]>
jfr.im git - irc/quakenet/snircd.git/blob - ircd/umkpasswd.c
2 * IRC - Internet Relay Chat, ircd/umkpasswd.c
3 * Copyright (C) 2002 hikari
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 1, or (at your option)
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 * $Id: umkpasswd.c,v 1.8 2005/05/11 04:15:04 entrope Exp $
29 /* #include <assert.h> -- Now using assert in ircd_log.h */
32 #include "ircd_alloc.h"
33 #include "ircd_log.h" /* for ircd's assert.h */
34 #include "ircd_string.h"
35 #include "umkpasswd.h"
39 /* crypto mech headers */
40 #include "ircd_crypt.h"
41 #include "ircd_crypt_smd5.h"
42 #include "ircd_crypt_native.h"
43 #include "ircd_crypt_plain.h"
45 /* bleah, evil globals */
46 umkpasswd_conf_t
* umkpasswd_conf
;
47 crypt_mechs_t
* crypt_mechs_root
;
51 void sendto_opmask_butone ( struct Client
* one
, unsigned int mask
,
52 const char * pattern
, ...)
54 /* only needed with memdebug, which also calls Debug() */
59 fprintf ( stderr
, "umkpasswd - Copyright (c) 2002 hikari \n " );
66 char * debughelp
= "[-d <level>] " ;
72 /*fprintf(stderr, "umkpasswd [-l] [[[-a]||[-u]] <username>] [-y <class>] %s[-c <file>] -m <mech> [password]\n\n", debughelp);*/
73 fprintf ( stderr
, "umkpasswd [-l] %s -m <mech> [password] \n\n " , debughelp
);
74 fprintf ( stderr
, " -l List mechanisms available. \n " );
76 fprintf ( stderr
, " -a <user> Add user to conf file. \n " );
77 fprintf ( stderr
, " -u <user> Update user's password field. \n " );
78 fprintf ( stderr
, " -y <class> Class to place oper in. \n " );
80 fprintf ( stderr
, " -m <mech> Mechanism to use [MANDATORY]. \n " );
82 fprintf ( stderr
, " -d <level> Debug level to run at. \n " );
85 fprintf(stderr, " -c <file> Conf file to use, default is DPATH/CPATH.\n\n");
90 /* our implementation of debug() */
91 void debug ( int level
, const char * form
, ...)
96 if ( level
<= ( umkpasswd_conf
-> debuglevel
))
99 vfprintf ( stderr
, form
, vl
);
100 fprintf ( stderr
, " \n " );
106 /* quick implementation of log_write() for assert() call */
107 void log_write ( enum LogSys subsys
, enum LogLevel severity
,
108 unsigned int flags
, const char * fmt
, ...)
112 vfprintf ( stderr
, fmt
, vl
);
113 fprintf ( stderr
, " \n " );
117 /* quick and dirty salt generator */
118 char * make_salt ( const char * salts
)
123 /* try and get around them running this time after time in quick succession */
125 srandom (( unsigned int ) time ( NULL
));
127 if (( tmp
= calloc ( 3 , sizeof ( char ))) != NULL
)
129 /* can't optimize this much more than just doing it twice */
130 n
= (( float )( strlen ( salts
))* random ()/( RAND_MAX
+ 1.0 ));
131 memcpy ( tmp
, ( salts
+ n
), 1 );
133 n
= (( float )( strlen ( salts
))* random ()/( RAND_MAX
+ 1.0 ));
134 memcpy (( tmp
+ 1 ), ( salts
+ n
), 1 );
136 Debug (( DEBUG_DEBUG
, "salts = %s " , salts
));
137 Debug (( DEBUG_DEBUG
, "strlen(salts) = %d " , strlen ( salts
)));
143 /* our implementation of ircd_crypt_register_mech() */
144 int ircd_crypt_register_mech ( crypt_mech_t
* mechanism
)
146 crypt_mechs_t
* crypt_mech
;
148 Debug (( DEBUG_INFO
, "ircd_crypt_register_mech: registering mechanism: %s " , mechanism
-> shortname
));
150 /* try to allocate some memory for the new mechanism */
151 if (( crypt_mech
= ( crypt_mechs_t
*) MyMalloc ( sizeof ( crypt_mechs_t
))) == NULL
)
153 /* aww poot, we couldn't get any memory, scream a little then back out */
154 Debug (( DEBUG_MALLOC
, "ircd_crypt_register_mech: could not allocate memory for %s " , mechanism
-> shortname
));
158 /* ok, we have memory, initialise it */
159 memset ( crypt_mech
, 0 , sizeof ( crypt_mechs_t
));
161 /* assign the data */
162 crypt_mech
-> mech
= mechanism
;
163 crypt_mech
-> next
= crypt_mech
-> prev
= NULL
;
165 /* first of all, is there anything there already? */
166 if ( crypt_mechs_root
-> next
== NULL
)
168 /* nope, just add ourself */
169 crypt_mechs_root
-> next
= crypt_mechs_root
-> prev
= crypt_mech
;
171 /* nice and simple, put ourself at the end */
172 crypt_mech
-> prev
= crypt_mechs_root
-> prev
;
173 crypt_mech
-> next
= NULL
;
174 crypt_mechs_root
-> prev
= crypt_mech
-> prev
-> next
= crypt_mech
;
178 Debug (( DEBUG_INFO
, "ircd_crypt_register_mech: registered mechanism: %s , crypt_function is at 0x %X ." , crypt_mech
-> mech
-> shortname
, & crypt_mech
-> mech
-> crypt_function
));
179 Debug (( DEBUG_INFO
, "ircd_crypt_register_mech: %s : %s " , crypt_mech
-> mech
-> shortname
, crypt_mech
-> mech
-> description
));
184 char * basename_into ( char * tmp
, char * target
)
186 unsigned int len
, ii
;
189 for ( ii
= len
; ii
> 0 ; )
190 if ( tmp
[-- ii
] == '/' )
193 return tmp
+ ii
+ ( tmp
[ ii
] == '/' );
194 else if ( tmp
[ ii
] != '/' )
201 if ( tmp
[-- ii
] == '/' )
205 for ( len
= 0 ; tmp
[ ii
] != '/' ; )
206 target
[ len
++] = tmp
[ ii
++];
217 unsigned char buffer
[ 1024 ], digest
[ 16 ];
219 if ( NULL
== ( file
= fopen ( tmp
, "r" )))
222 while (( len
= fread ( buffer
, 1 , 1024 , file
)))
223 MD5Update (& context
, buffer
, len
);
224 MD5Final ( digest
, & context
);
227 printf ( " %s : " , basename_into ( tmp
, ( char *) buffer
));
228 for ( len
= 0 ; len
< 16 ; len
++)
229 printf ( " %0 2x" , digest
[ len
]);
234 /* dump the loaded mechs list */
235 void show_mechs ( void )
237 crypt_mechs_t
* mechs
;
240 printf ( " \n Available mechanisms: \n " );
242 if ( crypt_mechs_root
== NULL
)
245 mechs
= crypt_mechs_root
-> next
;
252 printf ( " %s \t\t %s \n " , mechs
-> mech
-> mechname
, mechs
-> mech
-> description
);
258 /* load in the mech "modules" */
259 void load_mechs ( void )
261 /* we need these loaded by hand for now */
263 ircd_register_crypt_native ();
264 ircd_register_crypt_smd5 ();
265 ircd_register_crypt_plain (); /* yes I know it's slightly pointless */
270 crypt_mechs_t
* hunt_mech ( const char * mechname
)
274 assert ( NULL
!= mechname
);
276 if ( crypt_mechs_root
== NULL
)
279 mech
= crypt_mechs_root
-> next
;
286 if ( 0 == ( ircd_strcmp ( mech
-> mech
-> mechname
, mechname
)))
293 char * crypt_pass ( const char * pw
, const char * mech
)
295 crypt_mechs_t
* crypt_mech
;
296 char * salt
, * untagged
, * tagged
;
299 assert ( NULL
!= mech
);
301 Debug (( DEBUG_DEBUG
, "pw = %s \n " , pw
));
302 Debug (( DEBUG_DEBUG
, "mech = %s \n " , mech
));
304 if ( NULL
== ( crypt_mech
= hunt_mech ( mech
)))
306 printf ( "Unable to find mechanism %s \n " , mech
);
310 salt
= make_salt ( default_salts
);
312 untagged
= ( char *) CryptFunc ( crypt_mech
-> mech
)( pw
, salt
);
313 tagged
= ( char *) MyMalloc ( strlen ( untagged
)+ CryptTokSize ( crypt_mech
-> mech
)+ 1 );
314 memset ( tagged
, 0 , strlen ( untagged
)+ CryptTokSize ( crypt_mech
-> mech
)+ 1 );
315 strncpy ( tagged
, CryptTok ( crypt_mech
-> mech
), CryptTokSize ( crypt_mech
-> mech
));
316 strncpy ( tagged
+ CryptTokSize ( crypt_mech
-> mech
), untagged
, strlen ( untagged
));
321 char * parse_arguments ( int argc
, char ** argv
)
324 const char * options
= "a:d:lm:u:y:5:" ;
326 umkpasswd_conf
= ( umkpasswd_conf_t
*) MyMalloc ( sizeof ( umkpasswd_conf_t
));
328 umkpasswd_conf
-> flags
= 0 ;
329 umkpasswd_conf
-> debuglevel
= 0 ;
330 umkpasswd_conf
-> operclass
= 0 ;
331 umkpasswd_conf
-> user
= NULL
;
332 umkpasswd_conf
-> mech
= NULL
;
335 len
= strlen ( DPATH
) + strlen ( CPATH
) + 2 ;
336 umkpasswd_conf
-> conf
= ( char *) MyMalloc ( len
* sizeof ( char ));
337 memset ( umkpasswd_conf
-> conf
, 0 , len
* sizeof ( char ));
338 ircd_strncpy ( umkpasswd_conf
-> conf
, DPATH
, strlen ( DPATH
));
339 *(( umkpasswd_conf
-> conf
) + strlen ( DPATH
)) = '/' ;
340 ircd_strncpy (( umkpasswd_conf
-> conf
) + strlen ( DPATH
) + 1 , CPATH
, strlen ( CPATH
));
344 while (( EOF
!= ( c
= getopt ( argc
, argv
, options
))) && ! len
)
353 umkpasswd_conf
-> operclass
= atoi ( optarg
);
354 if ( umkpasswd_conf
-> operclass
< 0 )
355 umkpasswd_conf
-> operclass
= 0 ;
359 if ( umkpasswd_conf
-> flags
& ACT_ADDOPER
)
361 fprintf ( stderr
, "-a and -u are mutually exclusive. Use either or neither. \n " );
362 abort (); /* b0rk b0rk b0rk */
365 umkpasswd_conf
-> flags
|= ACT_UPDOPER
;
366 umkpasswd_conf
-> user
= optarg
;
370 umkpasswd_conf
-> mech
= optarg
;
380 umkpasswd_conf
-> debuglevel
= atoi ( optarg
);
381 if ( umkpasswd_conf
-> debuglevel
< 0 )
382 umkpasswd_conf
-> debuglevel
= 0 ;
386 umkpasswd_conf
-> conf
= optarg
;
390 if ( umkpasswd_conf
-> flags
& ACT_UPDOPER
)
392 fprintf ( stderr
, "-a and -u are mutually exclusive. Use either or neither. \n " );
393 abort (); /* b0rk b0rk b0rk */
396 umkpasswd_conf
-> flags
|= ACT_ADDOPER
;
397 umkpasswd_conf
-> user
= optarg
;
401 /* unknown option - spit out syntax and b0rk */
408 Debug (( DEBUG_DEBUG
, "flags = %d " , umkpasswd_conf
-> flags
));
409 Debug (( DEBUG_DEBUG
, "operclass = %d " , umkpasswd_conf
-> operclass
));
410 Debug (( DEBUG_DEBUG
, "debug = %d " , umkpasswd_conf
-> debuglevel
));
412 if ( NULL
!= umkpasswd_conf
-> mech
)
413 Debug (( DEBUG_DEBUG
, "mech = %s " , umkpasswd_conf
-> mech
));
415 Debug (( DEBUG_DEBUG
, "mech is unset" ));
417 if ( NULL
!= umkpasswd_conf
-> conf
)
418 Debug (( DEBUG_DEBUG
, "conf = %s " , umkpasswd_conf
-> conf
));
420 Debug (( DEBUG_DEBUG
, "conf is unset" ));
422 if ( NULL
!= umkpasswd_conf
-> user
)
423 Debug (( DEBUG_DEBUG
, "user = %s " , umkpasswd_conf
-> user
));
425 Debug (( DEBUG_DEBUG
, "user is unset" ));
427 /* anything left over should be password */
431 int main ( int argc
, char ** argv
)
433 char * pw
, * crypted_pw
;
435 crypt_mechs_root
= ( crypt_mechs_t
*) MyMalloc ( sizeof ( crypt_mechs_t
));
436 crypt_mechs_root
-> mech
= NULL
;
437 crypt_mechs_root
-> next
= crypt_mechs_root
-> prev
= NULL
;
445 pw
= parse_arguments ( argc
, argv
);
448 if ( NULL
== umkpasswd_conf
-> mech
)
450 fprintf ( stderr
, "No mechanism specified. \n " );
456 pw
= getpass ( "Password: " );
458 crypted_pw
= crypt_pass ( pw
, umkpasswd_conf
-> mech
);
460 printf ( "Crypted Pass: %s \n " , crypted_pw
);
461 memset ( pw
, 0 , strlen ( pw
));