/* File: makeUserPasswd.c * Author: Ed Griffiths (edgrif@sanger.ac.uk) * Copyright (c) J Thierry-Mieg and R Durbin, 1999 *------------------------------------------------------------------- * This file is part of the ACEDB genome database package, written by * Richard Durbin (Sanger Centre, UK) rd@sanger.ac.uk, and * Jean Thierry-Mieg (CRBM du CNRS, France) mieg@kaa.crbm.cnrs-mop.fr * * Description: Program to make an entry as it should appear in the * serverpasswd.wrm file. * Note that the output can be parsed to get the valid * entry, it will be the only non-blank line not beginning * with "//" * * Exported functions: none * HISTORY: * Last edited: Feb 3 10:09 2000 (edgrif) * Created: Wed Nov 17 14:07:06 1999 (edgrif) * CVS info: $Id: makeUserPasswd.c,v 1.2 2000/02/03 10:14:37 edgrif Exp $ *------------------------------------------------------------------- */ #include #include /* for non-echoing terminal code. */ #include /* for getting user input. */ #include #include #include enum {MD5_HASHLEN = 16, MD5_HEX_HASHLEN = ((MD5_HASHLEN * 2) + 1)} ; void usage(char *progname) ; char *getPasswd(void) ; char *convertMD5toHexStr(unsigned char digest[]) ; /* This program takes as input the userid, the program then prompts for the */ /* password, does some simple password checking and outputs to stdout a */ /* string in the form: */ /* userid: hash_string */ /* */ /* where hash_string is the MD5 hash of the userid and the pasword. */ /* */ int main(int argc, char **argv) { MD5_CTX Md5Ctx ; unsigned char digest[MD5_HASHLEN] ; char *hash ; if (argc != 2) usage(argv[0]) ; else { char *passwd ; /* Get passwd from user, call either succeeds or exits. */ passwd = getPasswd() ; /* Do the hash */ MD5Init(&Md5Ctx) ; MD5Update(&Md5Ctx, (unsigned char *)argv[1], strlen(argv[1])) ; MD5Update(&Md5Ctx, (unsigned char *)passwd, strlen(passwd)) ; MD5Final(digest, &Md5Ctx) ; /* Change the hash number into a hex string version. */ hash = convertMD5toHexStr(&digest[0]) ; messout("The following line is a valid entry for wspec/serverpasswd.wrm\n") ; printf("%s %s\n\n", argv[1], hash) ; } return 0 ; } void usage(char *progname) { printf("Run the program like this:\n" "\n" " %s userid\n" "\n" "the program then produces on stdout\n" "\n" " userid \n" "\n", progname) ; return ; } /* Both this and the following routine should really be common to this */ /* program and the server password stuff....they need to be incorporated... */ char *getPasswd(void) { struct termios term ; char *passwd = NULL ; char *passwd1, *passwd2 ; /* Get the terminal attributes to manipulate echo'ing. */ if (tcgetattr(fileno(stdin), &term) < 0) messcrash("Unable to get terminal attributes for input of password."); /* echo off... */ term.c_lflag &= ~(ECHO) ; if (tcsetattr(fileno(stdin), TCSADRAIN, &term) < 0) messcrash("Unable to set terminal attributes for input of password."); /* Get the passwd (twice). Note that newline after password is not echoed */ /* to terminal so we have to send one. */ passwd1 = readline("// Please enter passwd: ") ; printf("\n") ; passwd2 = readline("// Please re-enter passwd: ") ; printf("\n") ; /* echo on... */ term.c_lflag |= ECHO ; if (tcsetattr(fileno(stdin), TCSADRAIN, &term) < 0) messcrash("Unable to reset terminal attributes after input of password."); /* do some basic checking on the password. */ if (passwd1 == NULL /* can readline return NULL ? */ || (strcmp(passwd1, "") == 0) /* can't be empty string */ || (strlen(passwd1) < 6) /* must be at least 6 chars */ || (strstr(passwd1, " ") != NULL) /* no blanks */ || (strtok(passwd1, "abcdefghijklmnopqrstuvwxyz" "ABCDEFGHIJKLMNOPQRSTUVWXYZ" "0123456789") != NULL)) /* alphanumerics only. */ messExit("Password invalid, must be at least six chars with no blanks,\n" "only alphanumerics are allowed [a-z, A-Z, 0-9].") ; if (strcmp(passwd1, passwd2) != 0) /* must be reentered correctly. */ messExit("Password incorrectly re-entered.") ; passwd = passwd1 ; return passwd ; } /* This should be in a separate library really as it also exists in */ /* socketace.c */ char *convertMD5toHexStr(unsigned char digest[]) { char *digest_str ; int i ; char *hex_ptr ; digest_str = (char *)malloc(MD5_HEX_HASHLEN) ; for (i = 0, hex_ptr = digest_str ; i < MD5_HASHLEN ; i++, hex_ptr+=2) { sprintf(hex_ptr, "%02x", digest[i]) ; } return digest_str ; }