/* ** Copyright 1998 - 2006 Double Precision, Inc. ** See COPYING for distribution information. */ #if HAVE_CONFIG_H #include "config.h" #endif #include #if HAVE_SYS_STAT_H #include #endif #if HAVE_FCNTL_H #include #endif #if HAVE_UNISTD_H #include #endif #if TIME_WITH_SYS_TIME #include #include #else #if HAVE_SYS_TIME_H #include #else #include #endif #endif #if HAVE_MD5 #include "md5/md5.h" #endif #if HAVE_HMAC #include "libhmac/hmac.h" #endif #include #include #include #include #if HAVE_TERMIOS_H #include #endif #if HAVE_CRYPT_H #include #endif #if HAVE_CRYPT #if NEED_CRYPT_PROTOTYPE extern char *crypt(const char *, const char *); #endif #endif extern char userdb_hex64[]; #ifdef RANDOM extern void userdb_get_random(char *buf, unsigned n); #endif #if HAVE_MD5 char *userdb_mkmd5pw(const char *); #endif /* ** Where possible, we turn off echo when entering the password. ** We set up a signal handler to catch signals and restore the echo ** prior to exiting. */ #if HAVE_TERMIOS_H static struct termios tios; static int have_tios; static RETSIGTYPE sighandler(int signum) { if (write(1, "\n", 1) < 0) ; /* ignore gcc warning */ tcsetattr(0, TCSANOW, &tios); _exit(0); #if RETSIGTYPE != void return (0); #endif } #endif static void read_pw(char *buf) { int n, c; n=0; while ((c=getchar()) != EOF && c != '\n') if (n < BUFSIZ-1) buf[n++]=c; if (c == EOF && n == 0) exit(1); buf[n]=0; } int main(int argc, char **argv) { int n=1; int md5=0; char buf[BUFSIZ]; char salt[9]; #if HAVE_HMAC struct hmac_hashinfo *hmac=0; #endif while (n < argc) { if (strcmp(argv[n], "-md5") == 0) { md5=1; ++n; continue; } #if HAVE_HMAC if (strncmp(argv[n], "-hmac-", 6) == 0) { int i; for (i=0; hmac_list[i] && strcmp(hmac_list[i]->hh_name, argv[n]+6); i++) ; if (hmac_list[i]) { hmac=hmac_list[i]; ++n; continue; } } #endif fprintf(stderr, "%s: invalid argument.\n", argv[0]); exit(1); } /* Read the password */ #if HAVE_TERMIOS_H have_tios=0; if (tcgetattr(0, &tios) == 0) { struct termios tios2; char buf2[BUFSIZ]; have_tios=1; signal(SIGINT, sighandler); signal(SIGHUP, sighandler); tios2=tios; tios2.c_lflag &= ~ECHO; tcsetattr(0, TCSANOW, &tios2); for (;;) { if (write(2, "Password: ", 10) < 0) ; /* ignore gcc warning */ read_pw(buf); if (write(2, "\nReenter password: ", 19) < 0) ; /* ignore gcc warning */ read_pw(buf2); if (strcmp(buf, buf2) == 0) break; if (write(2, "\nPasswords don't match.\n\n", 25) < 0) ; /* ignore gcc warning */ } } else #endif read_pw(buf); #if HAVE_TERMIOS_H if (have_tios) { if (write(2, "\n", 1) < 0) ; /* ignore gcc warning */ tcsetattr(0, TCSANOW, &tios); signal(SIGINT, SIG_DFL); signal(SIGHUP, SIG_DFL); } #endif /* Set the password */ #if HAVE_HMAC if (hmac) { unsigned char *p=malloc(hmac->hh_L*2); unsigned i; if (!p) { perror("malloc"); exit(1); } hmac_hashkey(hmac, buf, strlen(buf), p, p+hmac->hh_L); for (i=0; ihh_L*2; i++) printf("%02x", (int)p[i]); printf("\n"); exit(0); } #endif #if HAVE_CRYPT #else md5=1; #endif #if HAVE_MD5 if (md5) { printf("%s\n", userdb_mkmd5pw(buf)); exit(0); } #endif #ifdef RANDOM userdb_get_random(salt, 2); salt[0]=userdb_hex64[salt[0] & 63]; salt[1]=userdb_hex64[salt[0] & 63]; #else { time_t t; int i; time(&t); t ^= getpid(); salt[0]=0; salt[1]=0; for (i=0; i<6; i++) { salt[0] <<= 1; salt[1] <<= 1; salt[0] |= (t & 1); t >>= 1; salt[1] |= (t & 1); t >>= 1; } salt[0]=userdb_hex64[(unsigned)salt[0]]; salt[1]=userdb_hex64[(unsigned)salt[1]]; } #endif #if HAVE_CRYPT printf("%s\n", crypt(buf, salt)); fflush(stdout); #endif return (0); }