#include #include #include #include #include "global.h" #include "manhat-lib/shared_util.h" #include "manhat-lib/shared_authenticate.h" #include "manhat-lib/shared_cs_util.h" #include "manhat-lib/shared_strtrm.h" #include "manhat-lib/shared_encrypt.h" #include "manhat-lib/shared_central_user.h" #include "manhat-lib/shared_add_util.h" #include "manhat-lib/shared_central_log.h" static void read_parameters (char *course, char *key, char *current, char *new_passwd, char *verify) { cs_get_optional_parameter ("crs", course, MAX_FILENAME); /* shared_cgi_util.c */ cs_get_required_parameter ("id", key, MAX_KEY); cs_get_required_parameter ("current", current, MAX_PASSWORD); cs_get_required_parameter ("new", new_passwd, MAX_PASSWORD); cs_get_required_parameter ("verify", verify, MAX_PASSWORD); } static void check_standalone_password (const char *plaintext_password, const CONFIG_STRUCT *conf, const SESSION *user) { char passwd_fname[MAX_PATH + 1]; FILE *fp; char line[200]; /* path to the individual's password file */ snprintf (passwd_fname, MAX_PATH + 1, "%s%s/%s/%s", conf->course_path, PEOPLE_DIR, user->username, PASSWORD_FNAME); fp = fopen (passwd_fname, "r"); if (!fp) cs_critical_error (ERR_PASSWD_OPEN_FAILED, ""); if (!fgets (line,200, fp)) cs_critical_error (ERR_PASSWD_OPEN_FAILED, ""); fclose(fp); strtrm(line); /* shared_util.c */ if(strcmp (line, encrypted_password(plaintext_password, user->username))) /* shared_encrypted.c */ cs_critical_error(ERR_INCORRECT_PASSWD_ENTERED,""); } static void check_central_password (const char *username, const char *plaintext_passwd) { char current_encrypted_password[MAX_ENCRYPTED_PASSWORD + 1]; get_central_user_password(username, current_encrypted_password); /* shared_encrypt.c */ if(strcmp(current_encrypted_password, encrypted_password(plaintext_passwd, username))) /* shared_encrypt.c */ cs_critical_error (ERR_INCORRECT_PASSWD_ENTERED, ""); } /* warning THIS MODIFIES all of the parameters !!! */ int contains_real_name(char *password, char *first, char *last) { char *ptr; for(ptr = password; *ptr; ptr++) *ptr = tolower(*ptr); for(ptr = first; *ptr; ptr++) *ptr = tolower(*ptr); for(ptr = last; *ptr; ptr++) *ptr = tolower(*ptr); return( strstr(password, first) || strstr(password, last) ); } static void check_validity (const char *current, const char *new_passwd, const char *verify, SESSION *user) { int len; char *ptr; char tmp_passwd[MAX_PASSWORD + 1]; char first[MAX_NAME + 1]; char last[MAX_NAME + 1]; char default_passwd[MAX_PASSWORD + 1]; char allowable_punctuation[]= "+=-$.^*"; /* a copy of new_passwd is made only to keep the compiler ** from complaining about discarding 'const' modifier from ** new_passwd when we later point ptr at it */ strncpy(tmp_passwd, new_passwd, MAX_PASSWORD+1); len = strlen (tmp_passwd); if ((len < 6) || (len > 15)) cs_critical_error (ERR_PASSWD_WRONG_LENGTH, ""); /* were the two new passwords typed in the same? */ if (strcmp (tmp_passwd, verify)) cs_critical_error (ERR_PASSWD_ENTERED_DIFFERENTLY, ""); /* don't allow them to use their current password */ if (!strcmp (current, tmp_passwd)) cs_critical_error (ERR_NEW_PASSWD_SAME_AS_OLD, ""); /* don't allow the password to be the same as the default ** password, as returned by derive_password() */ get_first_last_names(user->realname, first, last); /* shared_authenticate.c */ derive_password(user->username, first, last, user->id, default_passwd, MAX_PASSWORD + 1); if (!strcmp (new_passwd, default_passwd)) cs_critical_error (ERR_CANT_USE_DEFAULT_PASSWORD, ""); /* don't allow password to be same as username */ if (!strcmp (user->username, tmp_passwd)) cs_critical_error (ERR_PASSWD_AND_USERNAME_SAME, ""); /* don't allow password to be same their id number */ if (!strcmp (user->id, tmp_passwd)) cs_critical_error (ERR_PASSWD_AND_ID_SAME, ""); /* check for reasonable characters */ for (ptr = tmp_passwd; *ptr; ptr++) if (!isdigit (*ptr) && !isalpha (*ptr) && !strchr(allowable_punctuation,*ptr)) { cs_critical_error (ERR_PASSWD_HAS_INVALID_CHARS_X, tmp_passwd); } if(contains_real_name(tmp_passwd, first, last)) cs_critical_error(ERR_PASSWD_CONTAINS_YOUR_NAME, ""); /*** tmp_password is now lower cased, thanks to contains_real_name() call */ /* check some common bad passwords */ if(!strcmp(tmp_passwd,"manhattan") || !strcmp(tmp_passwd,"password") ) cs_critical_error(ERR_PASSWD_TOO_SIMPLE, ""); } static void change_password (const CONFIG_STRUCT *conf, const char *new_passwd, const SESSION *user, int standalone) { int success; if(standalone) success = write_password(user->username, new_passwd, conf->course_path); /* shared_encrypt.c */ else { success = write_central_password_file(user->username, new_passwd); /* shared_encrypt.c */ if(success) { cs_set_event_msg(); write_central_log(user->username, hdf_get_value(global_cgi->hdf, "log_event.change_password",""), "",0); } } if(!success) cs_critical_error(ERR_PASSWD_INTERNAL_ERROR, ""); } int main (void) { SESSION user; CONFIG_STRUCT conf; /* the configuration read from config file */ char course[MAX_PATH + 1]; /* from crs=? command line */ char key[MAX_KEY + 1]; /* from id=? command line */ char current[MAX_PASSWORD + 1], new_passwd[MAX_PASSWORD + 1], verify[MAX_PASSWORD + 1]; cs_cgi_init(); read_parameters (course, key, current, new_passwd, verify); if(*course) { read_configuration_file (course, &conf); /* shared_util.c */ validate_key (key, &user, &conf); /* shared_util.c */ if(conf.standalone) check_standalone_password(current, &conf, &user); else check_central_password(user.username,current); check_validity (current, new_passwd, verify, &user); change_password (&conf, new_passwd,&user,conf.standalone); printf ("Location: %s?crs=%s&id=%s\n\n", "main_menu", course, key); } else { validate_server_key(key,&user); /* shared_util.c */ check_central_password(user.username,current); check_validity (current, new_passwd, verify, &user); change_password (&conf, new_passwd, &user,0); printf ("Location: %s?id=%s&\n\n", "mymanhattan",key); } cs_cgi_destroy(); return 0; }