/* password.c - password read/update helper functions.
 *
 * Copyright 2012 Ashwini Kumar <ak.ashwini@gmail.com>
 */

#include "toys.h"
#include <time.h>

// generate appropriate random salt string for given encryption algorithm.
int get_salt(char *salt, char *algo)
{
  struct {
    char *type, id, len;
  } al[] = {{"des", 0, 2}, {"md5", 1, 8}, {"sha256", 5, 16}, {"sha512", 6, 16}};
  int i;

  for (i = 0; i < ARRAY_LEN(al); i++) {
    if (!strcmp(algo, al[i].type)) {
      int len = al[i].len;
      char *s = salt;

      if (al[i].id) s += sprintf(s, "$%c$", '0'+al[i].id);

      // Read appropriate number of random bytes for salt
      i = xopen("/dev/urandom", O_RDONLY);
      xreadall(i, libbuf, ((len*6)+7)/8);
      close(i);

      // Grab 6 bit chunks and convert to characters in ./0-9a-zA-Z
      for (i=0; i<len; i++) {
        int bitpos = i*6, bits = bitpos/8;

        bits = ((libbuf[i]+(libbuf[i+1]<<8)) >> (bitpos&7)) & 0x3f;
        bits += 46;
        if (bits > 57) bits += 7;
        if (bits > 90) bits += 6;

        s[i] = bits;
      }
      salt[len] = 0;

      return s-salt;
    }
  }

  return -1;
}

// Reset terminal to known state, returning old state if old != NULL.
int set_terminal(int fd, int raw, struct termios *old)
{
  struct termios termio;

  if (!tcgetattr(fd, &termio) && old) *old = termio;

  // the following are the bits set for an xterm. Linux text mode TTYs by
  // default add two additional bits that only matter for serial processing
  // (turn serial line break into an interrupt, and XON/XOFF flow control)

  // Any key unblocks output, swap CR and NL on input
  termio.c_iflag = IXANY|ICRNL|INLCR;
  if (toys.which->flags & TOYFLAG_LOCALE) termio.c_iflag |= IUTF8;

  // Output appends CR to NL, does magic undocumented postprocessing
  termio.c_oflag = ONLCR|OPOST;

  // Leave serial port speed alone
  // termio.c_cflag = C_READ|CS8|EXTB;

  // Generate signals, input entire line at once, echo output
  // erase, line kill, escape control characters with ^
  // erase line char at a time
  // "extended" behavior: ctrl-V quotes next char, ctrl-R reprints unread chars,
  // ctrl-W erases word
  termio.c_lflag = ISIG|ICANON|ECHO|ECHOE|ECHOK|ECHOCTL|ECHOKE|IEXTEN;

  if (raw) cfmakeraw(&termio);

  return tcsetattr(fd, TCSANOW, &termio);
}

// Prompt with mesg, read password into buf, return 0 for success 1 for fail
int read_password(char *buf, int buflen, char *mesg)
{
  struct termios oldtermio;
  struct sigaction sa, oldsa;
  int i, ret = 1;

  // NOP signal handler to return from the read
  memset(&sa, 0, sizeof(sa));
  sa.sa_handler = generic_signal;
  sigaction(SIGINT, &sa, &oldsa);

  tcflush(0, TCIFLUSH);
  set_terminal(0, 1, &oldtermio);

  xprintf("%s", mesg);

  for (i=0; i < buflen-1; i++) {
    if ((ret = read(0, buf+i, 1)) < 0 || (!ret && !i)) {
      i = 0;
      ret = 1;

      break;
    } else if (!ret || buf[i] == '\n' || buf[i] == '\r') {
      ret = 0;

      break;
    } else if (buf[i] == 8 || buf[i] == 127) i -= i ? 2 : 1;
  }

  // Restore terminal/signal state, terminate string
  sigaction(SIGINT, &oldsa, NULL);
  tcsetattr(0, TCSANOW, &oldtermio);
  buf[i] = 0;
  xputc('\n');

  return ret;
}

static char *get_nextcolon(char *line, int cnt)
{
  while (cnt--) {
    if (!(line = strchr(line, ':'))) error_exit("Invalid Entry\n");
    line++; //jump past the colon
  }
  return line;
}

/*update_password is used by multiple utilities to update /etc/passwd,
 * /etc/shadow, /etc/group and /etc/gshadow files,
 * which are used as user, group databeses
 * entry can be
 * 1. encrypted password, when updating user password.
 * 2. complete entry for user details, when creating new user
 * 3. group members comma',' separated list, when adding user to group
 * 4. complete entry for group details, when creating new group
 * 5. entry = NULL, delete the named entry user/group
 */
int update_password(char *filename, char* username, char* entry)
{
  char *filenamesfx = NULL, *namesfx = NULL, *shadow = NULL,
       *sfx = NULL, *line = NULL;
  FILE *exfp, *newfp;
  int ret = -1, found = 0;
  struct flock lock;

  shadow = strstr(filename, "shadow");
  filenamesfx = xmprintf("%s+", filename);
  sfx = strchr(filenamesfx, '+');

  exfp = fopen(filename, "r+");
  if (!exfp) {
    perror_msg("Couldn't open file %s",filename);
    goto free_storage;
  }

  *sfx = '-';
  unlink(filenamesfx);
  ret = link(filename, filenamesfx);
  if (ret < 0) error_msg("can't create backup file");

  *sfx = '+';
  lock.l_type = F_WRLCK;
  lock.l_whence = SEEK_SET;
  lock.l_start = 0;
  lock.l_len = 0;

  ret = fcntl(fileno(exfp), F_SETLK, &lock);
  if (ret < 0) perror_msg("Couldn't lock file %s",filename);

  lock.l_type = F_UNLCK; //unlocking at a later stage

  newfp = fopen(filenamesfx, "w+");
  if (!newfp) {
    error_msg("couldn't open file for writing");
    ret = -1;
    fclose(exfp);
    goto free_storage;
  }

  ret = 0;
  namesfx = xmprintf("%s:",username);
  while ((line = get_line(fileno(exfp))) != NULL)
  {
    if (strncmp(line, namesfx, strlen(namesfx)))
      fprintf(newfp, "%s\n", line);
    else if (entry) {
      char *current_ptr = NULL;

      found = 1;
      if (!strcmp(toys.which->name, "passwd")) {
        fprintf(newfp, "%s%s:",namesfx, entry);
        current_ptr = get_nextcolon(line, 2); //past passwd
        if (shadow) {
          fprintf(newfp, "%u:",(unsigned)(time(NULL))/(24*60*60));
          current_ptr = get_nextcolon(current_ptr, 1);
          fprintf(newfp, "%s\n",current_ptr);
        } else fprintf(newfp, "%s\n",current_ptr);
      } else if (!strcmp(toys.which->name, "groupadd") ||
          !strcmp(toys.which->name, "addgroup") ||
          !strcmp(toys.which->name, "delgroup") ||
          !strcmp(toys.which->name, "groupdel")){
        current_ptr = get_nextcolon(line, 3); //past gid/admin list
        *current_ptr = '\0';
        fprintf(newfp, "%s", line);
        fprintf(newfp, "%s\n", entry);
      }
    }
    free(line);
  }
  free(namesfx);
  if (!found && entry) fprintf(newfp, "%s\n", entry);
  fcntl(fileno(exfp), F_SETLK, &lock);
  fclose(exfp);

  errno = 0;
  fflush(newfp);
  fsync(fileno(newfp));
  fclose(newfp);
  rename(filenamesfx, filename);
  if (errno) {
    perror_msg("File Writing/Saving failed: ");
    unlink(filenamesfx);
    ret = -1;
  }

free_storage:
  free(filenamesfx);
  return ret;
}
