/*--------------------------------------------------------*/ /* login.c 08-aug-1997/bets */ /* postgres additions by pablo apr-1998 */ /*--------------------------------------------------------*/ #include #include #include #include #include #include #include #include #include "form.h" #include "page.h" #include "password.h" #include "login.h" #include /*----- utility routines ---------------------------------*/ /*--------------------------------------------------------*/ /* getcookie */ /*--------------------------------------------------------*/ char *getcookie( char *cooname ) { static char *atoken; char *allcooks; int len; if (( allcooks = getenv( "HTTP_COOKIE" )) == NULL ) { return NULL; } len = strlen( cooname ); atoken = strtok( allcooks," " ); while ( atoken != NULL ) { if (( strncmp( atoken, cooname,len ) == 0 ) && ( atoken[len] == '=' )) { return strtok( &atoken[len+1],"; " ); } atoken = strtok( NULL," " ); } return NULL; } /* end of getcookie() */ /*--------------------------------------------------------*/ /* init_err */ /* this routine redirects stderr output to the specified */ /* file (`logfile') */ /*--------------------------------------------------------*/ void init_err( char *logfile ) { time_t tim; char *p,*q; int fd; umask( 0 ); /* create logfile if nonexistant */ if (( fd = open( logfile,O_WRONLY|O_EXCL|O_CREAT,0666 )) >=0 ) { /* file was open, which means, it didn't exist (cause O_EXCL was set) */ close( fd ); } time( &tim ); /* if ( NULL == ( freopen( LOG_FILE,"a",stderr ))) {*/ if (( freopen( logfile,"a",stderr )) == NULL ) { exit( 999 ); } p = ctime( &tim ); for ( q=p; *q != '\0';q++ ) if ( *q == '\n' ) *q=' '; fprintf( stderr,"-- initializing -- %s %s (%d)\n", p,progname,(int)getpid() ); fflush( stderr ); } /* end of init_err() */ /*--------------------------------------------------------*/ /* space_replace */ /* this routine replaces blanks in string s with "_"'s. */ /* it also trims blanks from the end. */ /*--------------------------------------------------------*/ void space_replace( char *s ) { int i; for ( i=strlen(s)-1; i>=0; i-- ) { if ( s[i] != ' ' ) { break; } } s[i+1] = '\0'; for ( i=0; i\n",bgcolor ); } else { fprintf( stdout,"\n" ); } if ( fontnames != NULL ) { fprintf( stdout,"\n",fontnames ); } if ( strlen( heading ) > 0 ) fprintf( stdout,"

%s

\n", heading ); else fprintf( stdout,"
\n" ); form_begin( action ); } /* end of login_form_begin() */ /*--------------------------------------------------------*/ /* login_form_end */ /* this routine ends the form and the html page */ /*--------------------------------------------------------*/ void login_form_end() { form_end(); fprintf( stdout,"
\n" ); page_end(); } /* end of login_form_end() */ /*--------------------------------------------------------*/ /* login_form_user */ /* this routine prompts for user name on the login form */ /* the input will be of type text and will go into the */ /* environment variable called 'username' */ /*--------------------------------------------------------*/ void login_form_user( char *prompt, char *value, int size, char *new_button_label ) { fprintf( stdout,"

%s \n", prompt,size,value ); fprintf( stdout,"if you are new, enter a made-up name and then click here \n", new_button_label ); } /* end of login_form_user() */ /*--------------------------------------------------------*/ /* login_form_password */ /* this routine prompts for password on the login form */ /* the input will be of type password and will go into */ /* the environment variable called 'password' */ /*--------------------------------------------------------*/ void login_form_password( char *prompt, char *var, int size ) { fprintf( stdout,"

%s \n", prompt,var,size ); } /* end of login_form_password() */ /*--------------------------------------------------------*/ /* login_form_buttons */ /* this routine puts 2 buttons on the form: "Let's go!" */ /* and "help". the buttons are placed on the same line */ /* (horizontally) and centered. */ /*--------------------------------------------------------*/ void login_form_buttons() { fprintf( stdout,"

\n" ); fprintf( stdout,"

\n" ); fprintf( stdout,"\n" ); fprintf( stdout,"

\n" ); } /* end of login_form_buttons() */ /*--------------------------------------------------------*/ /* login_form_okay_button */ /*--------------------------------------------------------*/ void login_form_okay_button() { fprintf( stdout,"
\n" ); fprintf( stdout,"

\n" ); fprintf( stdout,"

\n" ); } /* end of login_form_okay_button() */ /*--------------------------------------------------------*/ /* login_form_get_option */ /*--------------------------------------------------------*/ void login_form_get_option( char **option ) { *option = form_getvar( "option" ); } /* end of login_form_get_option() */ /*----- login_form ---------------------------------------*/ /* */ /* +----- title ---------------------------------------+ */ /* | | */ /* | heading | */ /* | | */ /* | username_prompt: [username] [new_user_button] | */ /* | password_prompt: [password] | */ /* | | */ /* | [okay] [help] | */ /* | | */ /* +---------------------------------------------------+ */ /*--------------------------------------------------------*/ /* login_form_show */ /*--------------------------------------------------------*/ void login_form_show( char *title, char *bgcolor, char *fontnames, char *heading, char *action, char *username_prompt, char *username, int username_size, char *new_user_button, char *password_prompt, int password_size ){ login_form_begin( title,bgcolor,fontnames,heading,action ); login_form_user( username_prompt,username,username_size, new_user_button ); login_form_password( password_prompt,"password", password_size ); login_form_buttons(); fprintf( stdout,"" ); login_form_end(); } /* end of login_form_show() */ /*--------------------------------------------------------*/ /* login_form_get_input */ /*--------------------------------------------------------*/ void login_form_get_input( char **username, char **password, char **submit_button ) { *username = form_getvar( "username" ); if ( *username == NULL ) { page_error( "LoginException: username not found\n" ); exit( 0 ); } space_replace( *username ); *password = form_getvar( "password" ); if ( *password == NULL ) { page_error( "LoginException: password not found\n" ); exit( 0 ); } space_replace( *password ); if (( *submit_button = form_getvar( "START" )) == NULL ) if (( *submit_button = form_getvar( "HELP" )) == NULL ) if (( *submit_button = form_getvar( "NEW_USER" )) == NULL ) { page_error( "LoginException: submit button error\n" ); exit( 0 ); } } /* end of login_form_get_input() */ /*----- login_add_user_form ------------------------------*/ /* */ /* +----- title ---------------------------------------+ */ /* | | */ /* | add_user_heading [username]? | */ /* | | */ /* | | */ /* | | */ /* | | */ /* | [okay] | */ /* | | */ /* +---------------------------------------------------+ */ /*--------------------------------------------------------*/ /* login_add_user_form_show */ /*--------------------------------------------------------*/ void login_add_user_form_show( char *title, char *bgcolor, char *fontnames, char *add_user_heading, char *action, char *username, char *password ) { login_form_begin( title,bgcolor,fontnames,"",action ); fprintf( stdout,"

%s %s?

\n", add_user_heading,username ); fprintf( stdout,"", "username",username ); login_form_okay_button(); fprintf( stdout,"" ); fprintf( stdout,"","password",password ); login_form_end(); } /* end of login_add_user_form_show() */ /*--------------------------------------------------------*/ /* login_add_user_form_get_input */ /*--------------------------------------------------------*/ void login_add_user_form_get_input( char **username, char **password ) { *username = form_getvar( "username" ); if ( *username == NULL ) { page_error( "LoginException: username not found\n" ); exit( 0 ); } space_replace( *username ); *password = form_getvar( "password" ); space_replace( *password ); /* it's okay if password is null */ } /* end of login_form_add_user_get_input() */ /*----- login_new_password_form --------------------------*/ /* */ /* +----- title ---------------------------------------+ */ /* | | */ /* | new_password_heading [username] | */ /* | | */ /* | password_prompt: [password] | */ /* | verify_prompt : [verifypw] | */ /* | | */ /* | [okay] | */ /* | | */ /* +---------------------------------------------------+ */ /*--------------------------------------------------------*/ /* login_new_password_form_show() */ /*--------------------------------------------------------*/ void login_new_password_form_show( char *title, char *bgcolor, char *fontnames, char *new_password_heading, char *action, char *username, char *password, char *password_prompt, int password_size, char *verifypw_prompt ) { login_form_begin( title,bgcolor,fontnames,"",action ); fprintf( stdout,"

%s %s

\n", new_password_heading,username ); fprintf( stdout,"\n", "username",username ); if (( password == NULL ) || ( strlen( password ) == 0 )) { login_form_password( password_prompt,"password", password_size ); } login_form_password( verifypw_prompt,"verifypw", password_size ); login_form_okay_button(); fprintf( stdout,"" ); if (( password != NULL ) && ( strlen( password ) > 0 )) { fprintf( stdout,"","password",password ); } login_form_end(); } /* end of login_new_password_form_show() */ /*--------------------------------------------------------*/ /* login_new_password_form_get_input */ /*--------------------------------------------------------*/ void login_new_password_form_get_input( char **username, char **password, char **verifypw ) { *username = form_getvar( "username" ); if ( *username == NULL ) { page_error( "LoginException: username not found\n" ); exit( 0 ); } space_replace( *username ); *password = form_getvar( "password" ); if ( *password == NULL ) { page_error( "LoginException: password not found\n" ); exit( 0 ); } space_replace( *password ); *verifypw = form_getvar( "verifypw" ); if ( *verifypw == NULL ) { page_error( "LoginException: verifypw not found\n" ); exit( 0 ); } space_replace( *verifypw ); } /* end of login_new_password_form_get_input() */ /*----- main routine -------------------------------------*/ /*--------------------------------------------------------*/ /* login */ /* */ /* this routine is the toplevel login routine. it walks */ /* the user through the login process. initially, the */ /* login_form (above) is displayed. an old user will enter*/ /* a username/password and click on [okay]. in this case, */ /* this routine verifies that the username/password are */ /* not blank, looks up the username/password in the */ /* password database and returns the username if the */ /* password matches in the database. if any of these steps*/ /* fail, an error is output and the routine returns NULL. */ /* a new user will enter a username and click on */ /* [new_user_button]. the routine then prompts the user to*/ /* confirm that a new user will be added. then the */ /* login_add_user_form is displayed. the user confirms and*/ /* the routine enters the username and a blank password */ /* into the database (as a place holder). then the */ /* login_new_password_form is displayed. the user enters a*/ /* password (twice) and the routine enters the new */ /* password in the database in the record where the */ /* username place holder is. */ /* each time a new form is displayed, processing returns */ /* to the html browser and is subsequently returned here. */ /* */ /* return value: */ /* the routine returns the username of the user that has */ /* successfully completed the login process. if an */ /* unsucessful login occurred, then the routine returns */ /* NULL. */ /* */ /* arguments: */ /* sql_connection (input): PGconn (database pointer). */ /* a table called `passwords' must*/ /* exist with fields `user' and */ /* `password' (and user better be */ /* unique&indexed!) */ /* username_size (input): maximum length of username */ /* password_size (input): maximum length of password */ /* login_title (input) : title for login_form */ /* login_bgcolor (input): background color for html page */ /* if null, then default is used */ /* login_fontnames (input): font faces for html page */ /* if null, then default is used */ /* login_heading (input): heading for login_form */ /* login_url (input) : URL for the html browser to */ /* return to after exiting the */ /* form being displayed */ /* username_prompt (input): prompt for login_form */ /* password_prompt (input): prompt for login_form */ /* new_user_button (input): label for new_user_button */ /* add_user_title (input): title for login_add_user_form */ /* add_user_heading (input): heading for */ /* login_add_user_form; */ /* this should be something like */ /* "add user" or "add player" */ /* since the value of the username*/ /* will follow it on the form */ /* new_password_title (input): title for */ /* login_new_password_form */ /* new_password_heading (input): heading for */ /* login_new_password_form; */ /* this should be something like */ /* "enter password for user" or */ /* "enter password for player" */ /* since the value of the username*/ /* will follow it on the form */ /* verify_prompt (input): verify prompt for */ /* login_new_password_form */ /* error_no_username (input): error message to be */ /* displayed as the heading on */ /* redisplay of login_form when */ /* the username field is blank */ /* error_no_password (input): error message to be */ /* displayed as the heading on */ /* redisplay of LOGIN_FORM when */ /* the password field is blank */ /* error_incorrect_login (input): error message to be */ /* displayed as the heading on */ /* redisplay of login_form when */ /* the login is incorrect, */ /* i.e. the username and password */ /* don't match what is in the */ /* password database */ /* error_duplicate_user (input): error message to be */ /* displayed as the heading on */ /* redisplay of login_form when */ /* new username entered already */ /* exists in the database */ /*--------------------------------------------------------*/ char *login( PGconn *sql_connection, int username_size, int password_size, char *login_title, char *login_bgcolor, char *login_fontnames, char *login_heading, char *login_url, char *username_prompt, char *password_prompt, char *new_user_button, char *add_user_title, char *add_user_heading, char *new_password_title, char *new_password_heading, char *verify_password_prompt, char *error_no_username, char *error_no_password, char *error_incorrect_login, char *error_duplicate_user, void (*help_proc)( char *login_url ), char *cookiename ) { char *cookieval; char *coo_username; char *option, *username, *password, *the_password, *verifypw, *submit_button; /* get cookie */ if (( cookiename != NULL ) && (( cookieval = getcookie( cookiename )) != NULL )) { coo_username = cookieval; } else { coo_username = ""; } /* show form, if it hasn't been displayed yet */ if ( ! form_process() ) { login_form_show( login_title,login_bgcolor, login_fontnames, login_heading,login_url, username_prompt,coo_username, username_size,new_user_button, password_prompt,password_size ); return( NULL ); } /* get option: 0 = basic login; 1 = add new user; 2 = new password */ login_form_get_option( &option ); if ( option == NULL ) { option = (char *)malloc( 2 * sizeof( char )); strcpy( option,"0" ); } /* get data from form */ switch ( option[0] ) { case '0': /* basic login form */ login_form_get_input( &username,&password, &submit_button ); if ( ! strcmp( submit_button,"help" )) { (*help_proc)( login_url ); exit( 0 ); } break; case '1': /* add user form */ login_add_user_form_get_input( &username,&password ); break; case '2': /* new password form */ login_new_password_form_get_input( &username,&password, &verifypw ); break; } /* check for empty username: if username not entered, re-prompt user and show login form again */ if ( strlen( username ) == 0 ) { login_form_show( login_title,login_bgcolor, login_fontnames, error_no_username, login_url,username_prompt,"", username_size,new_user_button, password_prompt,password_size ); return( NULL ); } /* further processing */ switch ( option[0] ) { case '0': /* basic login form */ /* check for new player: either "new" button was pressed or username not found in database */ if (( ! strcmp( submit_button,new_user_button )) || (( the_password = pw_find( sql_connection,username, username_size )) == NULL )) { login_add_user_form_show( add_user_title, login_bgcolor, login_fontnames, add_user_heading, login_url,username, password ); return( NULL ); } /* check for empty database password, in case the "enter new user" process was aborted */ if (( strlen( the_password ) == 0 ) || ( ! strcmp( the_password," " ))) { login_new_password_form_show( new_password_title, login_bgcolor, login_fontnames, new_password_heading, login_url,username, password, password_prompt, password_size, verify_password_prompt ); return( NULL ); } /* check for empty password: if password not entered, re-prompt user and show login form again */ if ( strlen( password ) == 0 ) { login_form_show( login_title,login_bgcolor, login_fontnames, error_no_password, login_url,username_prompt,username, username_size,new_user_button, password_prompt,password_size ); return( NULL ); } /* check if database password matches password just entered: if not, re-prompt user and show login form again */ if ( ! password_okay( password,the_password )) { login_form_show( login_title,login_bgcolor, login_fontnames, error_incorrect_login, login_url,username_prompt,"", username_size,new_user_button, password_prompt,password_size ); return( NULL ); } /* username/password are okay, so all done! */ return( username ); break; case '1': /* add new user form */ /* first try to look up this user in the database to make sure the user isn't there */ if ( pw_insert( sql_connection,username,username_size, " " ) != 0 ) { /* user added */ page_error( "user name exists already; please choose a different one" ); } else { login_new_password_form_show( new_password_title, login_bgcolor, login_fontnames, new_password_heading, login_url,username, password, password_prompt, password_size, verify_password_prompt ); } return( NULL ); break; case '2': /* new password form */ /* check for empty password: if password not entered, re-prompt user and show login form again */ if (( strlen( password ) == 0 ) || ( strlen( verifypw ) == 0 )) { login_new_password_form_show( new_password_title, login_bgcolor, login_fontnames, error_incorrect_login, login_url,username, NULL, password_prompt, password_size, verify_password_prompt ); return( NULL ); } /* check if passwords match */ if ( strcmp( password,verifypw )) { login_new_password_form_show( new_password_title, login_bgcolor, login_fontnames, error_incorrect_login, login_url,username, NULL, password_prompt, password_size, verify_password_prompt ); return( NULL ); } /* encode password */ password = password_encode( password ); /* add user */ if ( pw_get( sql_connection,username,username_size, &the_password ) == 0 ) { /* successful */ if (( strlen( the_password ) == 0 ) || ( strcmp( the_password," " ))) { /* non-blank password in there -- someone else has this username */ login_form_show( login_title,login_bgcolor, login_fontnames, error_duplicate_user, login_url,username_prompt,"", username_size,new_user_button, password_prompt,password_size ); return( NULL ); } if ( pw_put( sql_connection,username,username_size, &password ) != 0 ) { page_error( PQerrorMessage(sql_connection) ); return( NULL ); } return( username ); } else { /* user not found or some other error, so just start again */ page_error( PQerrorMessage( sql_connection )); return( NULL ); } break; } } /* end of login() */