/* * donkey --- Don't Key * An alternative for S/KEY's key program. * * Copyright (C) 1995 Kazuhiko Yamamoto * * This software conforms GNU GENERAL PUBLIC LICENSE Version 2. * * Author: Kazuhiko Yamamoto * Created: April 25, 1995 * Revised: October 4, 1995 * */ static char version_message[] = "donkey version 0.5 10/04/95 Kazuhiko Yamamoto"; #include "config.h" #include "donkey.h" #include "getopt.h" #include "md.h" /* * declaration of local functions */ private void usage PROTO((char *progname)); private void help PROTO((char *progname)); private void version PROTO((char *progname)); private char *stripname PROTO((char *filename)); private int btoa8 PROTO((char *out, char *in)); /* * global variables */ int MD = DefaultMD; struct option longopts [] = { {"number", 1, 0, 'n'}, {"init", 0, 0, 'i'}, {"help", 0, 0, 'h'}, {"version", 0, 0, 'v'}, {"function", 1, 0, 'f'}, {0, 0, 0, 0} }; char *help_message[] = { " -n num [-f func] Calculate one time passwords from (seq-num+1) to seq", " -i [-f func] Print /etc/skeykeys entry", 0 }; /* * definition of local functions */ private void usage(progname) char* progname; { fprintf(stderr, "usage:\t%s [-n num] [-f func] sequence seed\n\t%s -i\n", progname, progname); } private void help(progname) char *progname; { char **p = help_message; fprintf(stderr, "help: %s\n", progname); usage(progname); while (*p) fprintf(stderr, "%s\n", *p++); } private void version(progname) char *progname; { fprintf(stderr, "version of %s: %s\n", progname, version_message); } private char *stripname(filename) char *filename; { char *p; if ((p = strrchr(filename, FILESEP)) != NULL) filename = p + FILESEPLEN; return filename; } private int btoa8(out, in) char *out, *in; { int i; if(in == NULL || out == NULL) return -1; for(i=0; i < 8; i++){ sprintf(out, "%02x", *in++ & 0xff); out += 2; } return 0; } /* * main */ int main (argc, argv) int argc; char **argv; { int optc, arg_count, seq; char *progname = stripname(argv[0]); char key[8]; char passphrase1[PASS_PHRASE_MAX_LEN]; /* * default option values */ int n=1; int iflag=0; while((optc = getopt_long(argc, argv, "n:ihvf:", longopts, (int *)0)) != EOF) { switch (optc) { case 'n': if ((n = atoi(optarg)) < 0) { fprintf(stderr, "%s: count is wrong.\n", progname); exit(EXIT_FAILURE); } break; case 'i': iflag = 1; break; case 'h': help(progname); exit(EXIT_SUCCESS); break; case 'v': version(progname); exit(EXIT_SUCCESS); break; case 'f': if (strcmp(optarg, "md2") == 0) { MD = MD2; } else if (strcmp(optarg, "md4") == 0) { MD = MD4; } else if (strcmp(optarg, "md5") == 0) { MD = MD5; } else { fprintf(stderr, "%s: function is wrong.\n", progname); fprintf(stderr, "choice -- md2, md4 and md5\n"); exit(EXIT_FAILURE); } break; default: usage(progname); exit(EXIT_FAILURE); } } arg_count = argc - optind; if (iflag) { char passphrase2[PASS_PHRASE_MAX_LEN]; char defaultseed[SEED_LEN], seed[SEED_LEN]; char tbuf[27], seqbuf[BUFSIZ]; char *tstr; char key2[BUFSIZ]; char *defaultuser, user[BUFSIZ]; int seq, i, c; time_t now; struct tm *tm; if (arg_count != 0) { usage(progname); exit(EXIT_FAILURE); } /* * user name */ defaultuser = getpwuid(getuid())->pw_name; fprintf(stderr, "Enter login name [default %s]: ", defaultuser); for (i = 0; i < BUFSIZ - 1; i++) { c = getchar(); if (c == '\n') break; else if (c == EOF) break; else user[i] = (char) c; } user[i] = '\0'; if (user[0] == '\0') { strcpy(user, defaultuser); } /* * sequence */ fprintf(stderr, "Enter sequence 1 to 999 [default %d]: ", DEFAULT_SEQ); for (i = 0; i < BUFSIZ - 1; i++) { c = getchar(); if (c == '\n') break; else if (c == EOF) break; else seqbuf[i] = (char) c; } seqbuf[i] = '\0'; if (seqbuf[0] == '\0') { seq = DEFAULT_SEQ; } else { seq = atoi(seqbuf); if (seq < 1 || 999 < seq) { fprintf(stderr, "sequence must be 1 =< and <= 999\n"); exit(EXIT_FAILURE); } } /* * seed */ for (i=0; i < SEED_HOST_LEN; i++) defaultseed[i] = 'x'; #ifdef HAVE_UNAME { struct utsname sys; uname(&sys); strncpy(defaultseed, sys.nodename, SEED_HOST_LEN); } #elif defined(HAVE_GETHOSTNAME) gethostname(defaultseed, SEED_HOST_LEN + 1); #endif now = (time_t) time(NULL); sprintf(defaultseed + SEED_HOST_LEN, "%05ld", (long) (now % 100000)); fprintf(stderr, "Enter new seed [default %s]: ", defaultseed); for (i = 0; i < SEED_LEN - 1; i++) { c = getchar(); if (c == '\n') break; else if (c == EOF) break; else seed[i] = (char) c; } seed[i] = '\0'; if (seed[0] == '\0') { strcpy(seed, defaultseed); } /* * pass phrase */ fprintf(stderr, "Please choose passphrase between %d and %d characters.\n", PASS_PHRASE_MIN_LEN,PASS_PHRASE_MAX_LEN); passphrase("Enter passphrase : ", passphrase1, PASS_PHRASE_MAX_LEN, 1); passphrase("Re-enter passphrase : ", passphrase2, PASS_PHRASE_MAX_LEN, 0); if (strcmp(passphrase1, passphrase2) != 0) { fprintf(stderr, "No match, try again\n"); exit(EXIT_FAILURE); } /* * apply hash */ if (keycrunch(key, seed, passphrase1) == RET_ERROR) { fprintf(stderr, "keycrunch failed\n"); exit(EXIT_FAILURE); } for (i = 0; i < seq; i++) secure_hash(key); /* * The last time entry */ now = (time_t) time(NULL); #ifdef HAVE_STRFTIME tm = localtime(&now); strftime(tbuf, sizeof(tbuf), " %b %d,%Y %T", tm); tstr = tbuf; #else tstr = ctime(&now); { char m[16], d[16], y[16], t[16], w[16]; sscanf(tstr, "%s %s %s %s %s\n", w, m, d, t, y); sprintf(tstr, " %s %s,%s %s", m, d, y, t); } #endif /* HAVE_STRFTIME */ /* * print the result */ btoa8(key2, key); printf("%s %04d %-16s %s %-21s\n", user, seq, seed, key2, tstr); printf("%s\n", btoe(key)); exit(EXIT_SUCCESS); } /* * no iflag */ if (arg_count != 2) { usage(progname); exit(EXIT_FAILURE); } if ((seq = atoi(argv[optind])) < 0) { fprintf(stderr, "sequence is wrong.\n"); exit(EXIT_FAILURE); } if ( n < 1 || n > (seq + 1)) { fprintf(stderr, "%s: count should be in the range from 1 to (seq + 1)\n", progname); exit(EXIT_FAILURE); } passphrase("Enter passphrase : ", passphrase1, PASS_PHRASE_MAX_LEN, 0); if (keycrunch(key, argv[optind+1], passphrase1) == RET_ERROR) { fprintf(stderr, "keycrunch failed\n"); exit(EXIT_FAILURE); } if (n == 1) { int i; for (i = 0; i < seq; i++) secure_hash(key); printf("%s\n", btoe(key)); } else { int i; for (i = 0; i < (seq - n + 1); i++) secure_hash(key); for (; i < seq + 1; i++) { printf("%d: %-29s\n", i, btoe(key)); secure_hash(key); } } exit(EXIT_SUCCESS); }