/* password.c - password read/update helper functions. * * Copyright 2012 Ashwini Kumar * * TODO: cleanup */ #include "toys.h" #include // generate ID prefix and random salt 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 xgetrandom(libbuf, ((len*6)+7)/8, 0); // Grab 6 bit chunks and convert to characters in ./0-9a-zA-Z for (i=0; i> (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; } // 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, tty = tty_fd(), ret = 1; // NOP signal handler to return from the read. Use sigaction() instead // of xsignal() because we want to restore the old handler afterwards. memset(&sa, 0, sizeof(sa)); sa.sa_handler = generic_signal; sigaction(SIGINT, &sa, &oldsa); tcflush(tty, TCIFLUSH); xset_terminal(tty, 1, 0, &oldtermio); dprintf(tty, "%s", mesg); for (i = 0; i 0) { line[n-1] = 0; 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; }