00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include <stdio.h>
00019 #include <string.h>
00020 #include <stdlib.h>
00021 #include <sys/time.h>
00022 #include <errno.h>
00023
00024 #define __USE_XOPEN
00025 #include <unistd.h>
00026
00027 #include <getopt.h>
00028
00029 #define FIRST_CHAR '!'
00030 #define LAST_CHAR '~'
00031 #define MAX_USER_NAME 256
00032 #define MAX_PASSWORD 8
00033 #define PASSWD_FILE_NAME "RIOpasswd"
00034
00035 #define ERROR_FILE_NOT_FOUND 1
00036 #define ERROR_PASSWORD_NOT_MATCH 2
00037 #define ERROR_NO_USERNAME 3
00038 #define ERROR_USER_ALREADY_EXISTS 4
00039 #define ERROR_STRING_TOO_LONG 5
00040
00041
00042 char PASSWD_FILE[ 256 ];
00043
00044
00045
00046 void Usage( char *program_name )
00047 {
00048 fprintf( stdout, "\nUsage:\n" );
00049 fprintf( stdout, " %s [ -d | directory] [ -h | --help | [-p | --password] <password> | [-u | --user] <username> | -v | --version |]\n", program_name );
00050 fprintf( stdout, "Where:\n" );
00051 fprintf( stdout, " [-d | --directory]: directory to save passwd file\n" );
00052 fprintf( stdout, " [-h | --help]: show this message\n" );
00053 fprintf( stdout, " [-p | --password] <password>: use <password> as user's password\n" );
00054 fprintf( stdout, " [-u | --user] <username>: use <username> as user's name\n" );
00055 fprintf( stdout, " [-v | --version]: show version\n" );
00056 fprintf( stdout, "\n" );
00057 }
00058
00059
00060
00061
00062
00063 void setSeed( void )
00064 {
00065 struct timeval time;
00066 unsigned int seed;
00067
00068 gettimeofday(&time, NULL);
00069 seed = time.tv_sec * time.tv_usec;
00070
00071 srand( seed );
00072 }
00073
00074
00075
00076
00077 int userFound( char *username )
00078 {
00079 char currentUser[MAX_USER_NAME];
00080 int status = 0;
00081 FILE *passwd_file;
00082
00083 passwd_file = fopen( PASSWD_FILE, "r" );
00084 if( passwd_file != NULL )
00085 {
00086 while( !feof( passwd_file ) )
00087 {
00088 if( fscanf( passwd_file, "%s %*s\n", currentUser ) != 1 )
00089 {
00090 fprintf( stderr, "Error when reading %s passwd file\n",
00091 PASSWD_FILE );
00092 exit( -1 );
00093
00094 }
00095
00096 if( strcmp( username, currentUser ) == 0 )
00097 {
00098 status = 1;
00099 break;
00100 }
00101 }
00102
00103 fclose( passwd_file );
00104 }
00105
00106 return status;
00107 }
00108
00109
00110
00111
00112 int createUser( char *username, char *password )
00113 {
00114 int status = 0;
00115 FILE *passwd_file;
00116
00117 passwd_file = fopen( PASSWD_FILE, "a" );
00118 if( passwd_file != NULL )
00119 {
00120 fprintf( passwd_file, "%s %s\n", username, password );
00121 fclose( passwd_file );
00122 }
00123 else
00124 {
00125 fprintf( stderr, "Error opening passwd file!\n" );
00126 status = ERROR_FILE_NOT_FOUND;
00127 }
00128
00129 return status;
00130 }
00131
00132
00133
00134
00135 int changeUserPasswd( char *username, char *password )
00136 {
00137 char currentUser[MAX_USER_NAME];
00138 char line[MAX_USER_NAME + MAX_PASSWORD + 1];
00139 FILE *passwd_file;
00140 int status = 0;
00141
00142 passwd_file = fopen( PASSWD_FILE, "r+" );
00143 if( passwd_file != NULL )
00144 {
00145 while( !feof( passwd_file ) )
00146 {
00147 if( fgets( line, MAX_USER_NAME + MAX_PASSWORD + 1,
00148 passwd_file ) == NULL )
00149 {
00150 fprintf( stderr, "Error when reading %s passwd file\n",
00151 PASSWD_FILE );
00152 }
00153 sscanf( line, "%s", currentUser );
00154
00155 if( strcmp( currentUser, username ) == 0 )
00156 {
00157 fseek( passwd_file, - strlen( line ), SEEK_CUR );
00158 fprintf( passwd_file, "%s %s\n", username, password );
00159
00160 break;
00161 }
00162 }
00163
00164 fclose( passwd_file );
00165 }
00166 else
00167 {
00168 fprintf( stderr, "Error opening passwd file!\n" );
00169 status = ERROR_FILE_NOT_FOUND;
00170 }
00171
00172 return status;
00173 }
00174
00175 int main( int argc, char **argv )
00176 {
00177 char username[MAX_USER_NAME];
00178 char password[MAX_PASSWORD + 1], password_check[MAX_PASSWORD + 1];
00179 char *buffer;
00180 char overwrite;
00181 char salt[3];
00182
00183
00184 char *dirname = NULL;
00185 int status = 0;
00186 int ask_username = 0;
00187 int ask_password = 0;
00188 char optch;
00189 int ind = -1;
00190
00191
00192 static char opts_short[] = "d:hp:u:v";
00193 static struct option opts_int[] =
00194 {
00195
00196
00197 {"directory" ,1,0,'d'},
00198 {"help" ,0,0,'h'},
00199 {"user" ,1,0,'u'},
00200 {"password" ,1,0,'p'},
00201 {"version" ,0,0,'v'},
00202 {0,0,0,0}
00203 };
00204
00205 while( ( optch = getopt_long( argc, argv, opts_short, opts_int,
00206 &ind ) ) != -1 )
00207 {
00208 switch( optch )
00209 {
00210 case 'u':
00211 if( strlen( optarg ) <= MAX_USER_NAME )
00212 {
00213 strcpy( username, optarg );
00214 ask_username = 1;
00215 }
00216 else
00217 {
00218 fprintf( stderr, "Username must be less than %d characters"
00219 " int\n", MAX_USER_NAME );
00220 return( ERROR_STRING_TOO_LONG );
00221 }
00222 break;
00223
00224 case 'p':
00225 if( strlen( optarg ) <= MAX_PASSWORD )
00226 {
00227 strcpy( password, optarg );
00228 ask_password = 1;
00229 }
00230 else
00231 {
00232 fprintf( stderr, "Password must be less than %d characters"
00233 " int\n", MAX_PASSWORD );
00234 return( ERROR_STRING_TOO_LONG );
00235 }
00236
00237 break;
00238
00239 case 'v':
00240 fprintf( stdout, "cryptPasswd version: %s\n", VERSION );
00241 return( 0 );
00242
00243 case 'h':
00244 default:
00245 Usage( argv[ 0 ] );
00246 return( 0 );
00247
00248 case 'd':
00249 dirname = optarg;
00250 break;
00251 }
00252 }
00253
00254
00255
00256 if( dirname == NULL)
00257 strcpy( PASSWD_FILE, PASSWD_FILE_NAME );
00258 else
00259 {
00260 strcpy( PASSWD_FILE, dirname );
00261 if( dirname[ strlen( dirname ) - 1 ] != '/')
00262 strcat( PASSWD_FILE, "/" );
00263 strcat( PASSWD_FILE, PASSWD_FILE_NAME );
00264 }
00265
00266
00267 if( ( access( PASSWD_FILE, R_OK | W_OK ) != 0 ) && ( errno == EACCES ) )
00268 {
00269 fprintf( stderr, "Access to %s file denied!\n", PASSWD_FILE );
00270 exit( -1 );
00271 }
00272
00273
00274 setSeed();
00275
00276
00277 if( ask_username == 0 )
00278 {
00279 fprintf( stdout, "Type user name or <Enter> to exit: " );
00280 if( fgets( username, MAX_USER_NAME , stdin ) == NULL )
00281 {
00282 fprintf( stderr, "Error when reading data from stdin\n" );
00283 exit( -1 );
00284 }
00285 username[ strlen( username ) - 1 ] = '\0';
00286 }
00287
00288
00289 if( strlen( username ) != 0 )
00290 {
00291
00292 if( userFound( username ) )
00293 {
00294 fprintf( stdout, "User %s already exists. Overwrite? (y|n) ",
00295 username );
00296 if( scanf( "%c", &overwrite ) != 1 )
00297 {
00298 fprintf( stderr, "Error when reading data from stdin\n" );
00299 exit( -1 );
00300 }
00301 if( overwrite == 'n' )
00302 {
00303 status = ERROR_USER_ALREADY_EXISTS;
00304 }
00305 }
00306
00307 if( status == 0 )
00308 {
00309
00310 if( ask_password == 0 )
00311 {
00312 fprintf( stdout, "Type password for user '%s': ", username );
00313 buffer = getpass( "" );
00314 if( strlen( buffer ) > MAX_PASSWORD )
00315 {
00316 fprintf( stderr, "Password must be less than %d characters"
00317 " int\n", MAX_PASSWORD + 1 );
00318 return( ERROR_STRING_TOO_LONG );
00319 }
00320
00321 strcpy( password, buffer );
00322
00323
00324 fprintf( stdout, "Retype user password: " );
00325 buffer = getpass( "" );
00326 if( strlen( buffer ) > MAX_PASSWORD )
00327 {
00328 fprintf( stderr, "Password must be less than %d characters"
00329 " int\n", MAX_PASSWORD + 1 );
00330 return( ERROR_STRING_TOO_LONG );
00331 }
00332 strcpy( password_check, buffer );
00333 }
00334
00335
00336 if( ( ask_password == 1 ) ||
00337 ( strcmp( password, password_check ) == 0 ) )
00338 {
00339 salt[0] = ( rand() % ( LAST_CHAR - FIRST_CHAR + 1 ) )
00340 + FIRST_CHAR;
00341 salt[1] = ( rand() % ( LAST_CHAR - FIRST_CHAR + 1 ) )
00342 + FIRST_CHAR;
00343 salt[2] = '\0';
00344
00345 if( overwrite == 'y' )
00346 status = changeUserPasswd( username,
00347 crypt( password, salt ) );
00348 else
00349 status = createUser( username, crypt( password, salt ) );
00350
00351 if( status == 0 )
00352 fprintf( stdout, "Username and crypted password were "
00353 "written to file %s.\n", PASSWD_FILE );
00354 }
00355
00356 else
00357 {
00358 if( overwrite == 'y' )
00359 {
00360 fprintf( stderr, "Passwords do not match. "
00361 "Password for user %s not changed.\n",
00362 username );
00363 }
00364 else
00365 {
00366 fprintf( stderr, "Passwords do not match. "
00367 "Password for user %s not created.\n",
00368 username );
00369 }
00370 status = ERROR_PASSWORD_NOT_MATCH;
00371 }
00372 }
00373 }
00374 else
00375 {
00376 status = ERROR_NO_USERNAME;
00377 }
00378
00379 return status;
00380 }