Changeset c121f89
- Timestamp:
- 2006-06-14T20:30:25Z (18 years ago)
- Branches:
- master
- Children:
- 5898ef8
- Parents:
- 85e9644
- Files:
-
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
Makefile
r85e9644 rc121f89 10 10 11 11 # Program variables 12 objects = account.o bitlbee.o conf.o crypting.o help.o ini.o ipc.o irc.o irc_commands.o log.o nick.o query.o root_commands.o set.o storage.o storage_text.o unix.o url.o user.o util.o12 objects = account.o bitlbee.o conf.o crypting.o help.o ini.o ipc.o irc.o irc_commands.o log.o nick.o query.o root_commands.o set.o storage.o storage_text.o storage_xml.o unix.o url.o user.o util.o 13 13 headers = account.h bitlbee.h commands.h conf.h config.h crypting.h help.h ini.h ipc.h irc.h log.h nick.h query.h set.h sock.h storage.h url.h user.h protocols/http_client.h protocols/md5.h protocols/nogaim.h protocols/proxy.h protocols/sha.h protocols/ssl_client.h 14 14 subdirs = protocols -
conf.c
r85e9644 rc121f89 55 55 conf->nofork = 0; 56 56 conf->verbose = 0; 57 conf->primary_storage = " text";57 conf->primary_storage = "xml"; 58 58 conf->runmode = RUNMODE_INETD; 59 59 conf->authmode = AUTHMODE_OPEN; -
root_commands.c
r85e9644 rc121f89 142 142 irc_umode_set( irc, "+R", 1 ); 143 143 break; 144 case STORAGE_OTHER_ERROR: 144 145 default: 145 irc_usermsg( irc, " Something very weird happened" );146 irc_usermsg( irc, "Unknown error while loading configuration" ); 146 147 break; 147 148 } -
storage.c
r85e9644 rc121f89 31 31 32 32 extern storage_t storage_text; 33 extern storage_t storage_xml; 33 34 34 static GList text_entry = { &storage_text, NULL, NULL }; 35 static GList *storage_backends = &text_entry; 35 static GList *storage_backends = NULL; 36 36 37 37 void register_storage_backend(storage_t *backend) … … 65 65 int i; 66 66 storage_t *storage; 67 67 68 register_storage_backend(&storage_text); 69 register_storage_backend(&storage_xml); 70 68 71 storage = storage_init_single(primary); 69 72 if (storage == NULL) -
storage.h
r85e9644 rc121f89 33 33 STORAGE_ALREADY_EXISTS, 34 34 STORAGE_OTHER_ERROR /* Error that isn't caused by user input, such as 35 36 35 a database that is unreachable. log() will be 36 used for the exact error message */ 37 37 } storage_status_t; 38 38 -
storage_xml.c
r85e9644 rc121f89 27 27 #include "bitlbee.h" 28 28 29 typedef enum 30 { 31 XML_PASS_CHECK_ONLY = -1, 32 XML_PASS_UNKNOWN = 0, 33 XML_PASS_OK 34 } xml_pass_st; 35 36 #define XML_PASS_ERRORMSG "Wrong username or password" 37 29 38 struct xml_parsedata 30 39 { … … 32 41 char *current_setting; 33 42 account_t *current_account; 43 char *given_nick; 44 char *given_pass; 45 xml_pass_st pass_st; 34 46 }; 35 47 … … 40 52 for( i = 0; attr_names[i]; i ++ ) 41 53 if( g_strcasecmp( attr_names[i], key ) == 0 ) 42 return attr_values[i];54 return (char*) attr_values[i]; 43 55 44 56 return NULL; 45 57 } 46 58 59 static void xml_destroy_xd( gpointer data ) 60 { 61 struct xml_parsedata *xd = data; 62 63 g_free( xd->given_nick ); 64 g_free( xd->given_pass ); 65 g_free( xd ); 66 } 67 47 68 static void xml_start_element( GMarkupParseContext *ctx, const gchar *element_name, const gchar **attr_names, const gchar **attr_values, gpointer data, GError **error ) 48 69 { 49 70 struct xml_parsedata *xd = data; 50 irc_t *irc = data->irc;71 irc_t *irc = xd->irc; 51 72 52 73 if( g_strcasecmp( element_name, "user" ) == 0 ) 53 74 { 54 75 char *nick = xml_attr( attr_names, attr_values, "nick" ); 55 56 if( nick && g_strcasecmp( nick, irc->nick ) == 0 ) 57 { 58 /* Okay! */ 59 } 76 char *pass = xml_attr( attr_names, attr_values, "password" ); 77 78 if( !nick || !pass ) 79 { 80 g_set_error( error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT, 81 "Missing attributes for %s element", element_name ); 82 } 83 else if( strcmp( nick, xd->given_nick ) == 0 && 84 strcmp( pass, xd->given_pass ) == 0 ) 85 { 86 if( xd->pass_st != XML_PASS_CHECK_ONLY ) 87 xd->pass_st = XML_PASS_OK; 88 } 89 else 90 { 91 g_set_error( error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT, 92 XML_PASS_ERRORMSG ); 93 } 94 } 95 else if( xd->pass_st < XML_PASS_OK ) 96 { 97 /* Let's not parse anything else if we only have to check 98 the password. */ 60 99 } 61 100 else if( g_strcasecmp( element_name, "account" ) == 0 ) 62 101 { 63 char *protocol, *handle, * password;102 char *protocol, *handle, *server, *password; 64 103 struct prpl *prpl = NULL; 65 104 66 105 handle = xml_attr( attr_names, attr_values, "handle" ); 67 106 password = xml_attr( attr_names, attr_values, "password" ); 107 server = xml_attr( attr_names, attr_values, "server" ); 68 108 69 109 protocol = xml_attr( attr_names, attr_values, "protocol" ); … … 71 111 prpl = find_protocol( protocol ); 72 112 73 if( handle && password && prpl ) 74 { 75 xd->current_account = account_add( irc, prpl, handle, password ) 113 if( !handle || !password ) 114 g_set_error( error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT, 115 "Missing attributes for %s element", element_name ); 116 else if( !prpl ) 117 g_set_error( error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT, 118 "Missing or unknown protocol %s element", element_name ); 119 else 120 { 121 xd->current_account = account_add( irc, prpl, handle, password ); 122 if( server ) 123 xd->current_account->server = g_strdup( server ); 76 124 } 77 125 } … … 80 128 if( xd->current_account == NULL ) 81 129 { 82 current_setting = xml_attr( attr_names, attr_values, "name" ); 130 char *setting; 131 132 if( xd->current_setting ) 133 { 134 g_free( xd->current_setting ); 135 xd->current_setting = NULL; 136 } 137 138 if( ( setting = xml_attr( attr_names, attr_values, "name" ) ) ) 139 xd->current_setting = g_strdup( setting ); 140 else 141 g_set_error( error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT, 142 "Missing attributes for %s element", element_name ); 83 143 } 84 144 } 85 145 else if( g_strcasecmp( element_name, "buddy" ) == 0 ) 86 146 { 87 } 88 else if( g_strcasecmp( element_name, "password" ) == 0 ) 89 { 147 char *handle, *nick; 148 149 handle = xml_attr( attr_names, attr_values, "handle" ); 150 nick = xml_attr( attr_names, attr_values, "nick" ); 151 152 if( xd->current_account && handle && nick ) 153 { 154 nick_set( irc, handle, xd->current_account->prpl, nick ); 155 } 156 else 157 { 158 g_set_error( error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT, 159 "Missing attributes for %s element", element_name ); 160 } 90 161 } 91 162 else 92 163 { 93 /* Return "unknown element" error. */ 164 g_set_error( error, G_MARKUP_ERROR, G_MARKUP_ERROR_UNKNOWN_ELEMENT, 165 "Unkown element: %s", element_name ); 94 166 } 95 167 } … … 102 174 { 103 175 struct xml_parsedata *xd = data; 104 irc_t *irc = data->irc; 105 106 if( xd->current_setting ) 107 { 108 set_setstr( irc, xd->current_setting, text ); 176 irc_t *irc = xd->irc; 177 178 if( xd->pass_st < XML_PASS_OK ) 179 { 180 /* Let's not parse anything else if we only have to check 181 the password. */ 182 } 183 else if( g_strcasecmp( g_markup_parse_context_get_element( ctx ), "setting" ) == 0 && 184 xd->current_setting && xd->current_account == NULL ) 185 { 186 set_setstr( irc, xd->current_setting, (char*) text ); 187 g_free( xd->current_setting ); 188 xd->current_setting = NULL; 109 189 } 110 190 } … … 131 211 } 132 212 133 static storage_status_t xml_load ( const char *my_nick, const char*password, irc_t *irc )213 static storage_status_t xml_load( const char *my_nick, const char *password, irc_t *irc ) 134 214 { 135 215 GMarkupParseContext *ctx; 136 137 ctx = g_markup_parse_context_new( parser, 0, xd, NULL ); 216 struct xml_parsedata *xd; 217 char *fn, buf[512]; 218 GError *gerr = NULL; 219 int fd, st; 220 138 221 if( irc->status >= USTATUS_IDENTIFIED ) 139 222 return( 1 ); 140 223 141 g_snprintf( s, 511, "%s%s%s", global.conf->configdir, my_nick, ".accounts" ); 142 fp = fopen( s, "r" ); 143 if( !fp ) return STORAGE_NO_SUCH_USER; 144 145 fscanf( fp, "%32[^\n]s", s ); 146 147 if (checkpass (password, s) != 0) 148 { 149 fclose( fp ); 150 return STORAGE_INVALID_PASSWORD; 151 } 152 153 /* Do this now. If the user runs with AuthMode = Registered, the 154 account command will not work otherwise. */ 224 xd = g_new0( struct xml_parsedata, 1 ); 225 xd->irc = irc; 226 xd->given_nick = g_strdup( my_nick ); 227 xd->given_pass = g_strdup( password ); 228 nick_lc( xd->given_nick ); 229 230 fn = g_strdup_printf( "%s%s%s", global.conf->configdir, xd->given_nick, ".xml" ); 231 if( ( fd = open( fn, O_RDONLY ) ) < 0 ) 232 { 233 xml_destroy_xd( xd ); 234 g_free( fn ); 235 return STORAGE_NO_SUCH_USER; 236 } 237 g_free( fn ); 238 239 ctx = g_markup_parse_context_new( &xml_parser, 0, xd, xml_destroy_xd ); 240 241 while( ( st = read( fd, buf, sizeof( buf ) ) ) > 0 ) 242 { 243 if( !g_markup_parse_context_parse( ctx, buf, st, &gerr ) || gerr ) 244 { 245 g_markup_parse_context_free( ctx ); 246 247 /* TODO: Display useful error msg */ 248 249 if( gerr && strcmp( gerr->message, XML_PASS_ERRORMSG ) == 0 ) 250 return STORAGE_INVALID_PASSWORD; 251 else 252 return STORAGE_OTHER_ERROR; 253 } 254 } 255 256 g_markup_parse_context_free( ctx ); 257 155 258 irc->status = USTATUS_IDENTIFIED; 156 259 157 while( fscanf( fp, "%511[^\n]s", s ) > 0 )158 {159 fgetc( fp );160 line = deobfucrypt( s, password );161 if (line == NULL) return STORAGE_OTHER_ERROR;162 root_command_string( irc, ru, line, 0 );163 g_free( line );164 }165 fclose( fp );166 167 g_snprintf( s, 511, "%s%s%s", global.conf->configdir, my_nick, ".nicks" );168 fp = fopen( s, "r" );169 if( !fp ) return STORAGE_NO_SUCH_USER;170 while( fscanf( fp, "%s %d %s", s, &proto, nick ) > 0 )171 {172 struct prpl *prpl;173 174 prpl = find_protocol_by_id(proto);175 176 if (!prpl)177 continue;178 179 http_decode( s );180 nick_set( irc, s, prpl, nick );181 }182 fclose( fp );183 184 260 if( set_getint( irc, "auto_connect" ) ) 185 261 { 186 strcpy( s, "account on" ); /* Can't do this directly because r_c_s alters the string */ 187 root_command_string( irc, ru, s, 0 ); 262 /* Can't do this directly because r_c_s alters the string */ 263 strcpy( buf, "account on" ); 264 root_command_string( irc, NULL, buf, 0 ); 188 265 } 189 266 … … 191 268 } 192 269 193 static storage_status_t text_save( irc_t *irc, int overwrite ) 194 { 195 char s[512]; 196 char path[512], new_path[512]; 197 char *line; 198 nick_t *n; 199 set_t *set; 200 mode_t ou = umask( 0077 ); 201 account_t *a; 202 FILE *fp; 203 char *hash; 204 205 if (!overwrite) { 270 static storage_status_t xml_save( irc_t *irc, int overwrite ) 271 { 272 /* if (!overwrite) { 206 273 g_snprintf( path, 511, "%s%s%s", global.conf->configdir, irc->nick, ".accounts" ); 207 274 if (access( path, F_OK ) != -1) … … 212 279 return STORAGE_ALREADY_EXISTS; 213 280 } 214 215 /*\ 216 * [SH] Nothing should be saved if no password is set, because the 217 * password is not set if it was wrong, or if one is not identified 218 * yet. This means that a malicious user could easily overwrite 219 * files owned by someone else: 220 * a Bad Thing, methinks 221 \*/ 222 223 /* [WVG] No? Really? */ 224 225 /*\ 226 * [SH] Okay, okay, it wasn't really Wilmer who said that, it was 227 * me. I just thought it was funny. 228 \*/ 229 230 hash = hashpass( irc->password ); 231 if( hash == NULL ) 232 { 233 irc_usermsg( irc, "Please register yourself if you want to save your settings." ); 234 return STORAGE_OTHER_ERROR; 235 } 236 237 g_snprintf( path, 511, "%s%s%s", global.conf->configdir, irc->nick, ".nicks~" ); 238 fp = fopen( path, "w" ); 239 if( !fp ) return STORAGE_OTHER_ERROR; 240 for( n = irc->nicks; n; n = n->next ) 241 { 242 strcpy( s, n->handle ); 243 s[169] = 0; /* Prevent any overflow (169 ~ 512 / 3) */ 244 http_encode( s ); 245 g_snprintf( s + strlen( s ), 510 - strlen( s ), " %d %s", find_protocol_id(n->proto->name), n->nick ); 246 if( fprintf( fp, "%s\n", s ) != strlen( s ) + 1 ) 247 { 248 irc_usermsg( irc, "fprintf() wrote too little. Disk full?" ); 249 fclose( fp ); 250 return STORAGE_OTHER_ERROR; 251 } 252 } 253 if( fclose( fp ) != 0 ) 254 { 255 irc_usermsg( irc, "fclose() reported an error. Disk full?" ); 256 return STORAGE_OTHER_ERROR; 257 } 258 259 g_snprintf( new_path, 512, "%s%s%s", global.conf->configdir, irc->nick, ".nicks" ); 260 if( unlink( new_path ) != 0 ) 261 { 262 if( errno != ENOENT ) 263 { 264 irc_usermsg( irc, "Error while removing old .nicks file" ); 265 return STORAGE_OTHER_ERROR; 266 } 267 } 268 if( rename( path, new_path ) != 0 ) 269 { 270 irc_usermsg( irc, "Error while renaming new .nicks file" ); 271 return STORAGE_OTHER_ERROR; 272 } 273 274 g_snprintf( path, 511, "%s%s%s", global.conf->configdir, irc->nick, ".accounts~" ); 275 fp = fopen( path, "w" ); 276 if( !fp ) return STORAGE_OTHER_ERROR; 277 if( fprintf( fp, "%s", hash ) != strlen( hash ) ) 278 { 279 irc_usermsg( irc, "fprintf() wrote too little. Disk full?" ); 280 fclose( fp ); 281 return STORAGE_OTHER_ERROR; 282 } 283 g_free( hash ); 284 285 for( a = irc->accounts; a; a = a->next ) 286 { 287 if( !strcmp(a->prpl->name, "oscar") ) 288 g_snprintf( s, sizeof( s ), "account add oscar \"%s\" \"%s\" %s", a->user, a->pass, a->server ); 289 else 290 g_snprintf( s, sizeof( s ), "account add %s \"%s\" \"%s\" \"%s\"", 291 a->prpl->name, a->user, a->pass, a->server ? a->server : "" ); 292 293 line = obfucrypt( s, irc->password ); 294 if( *line ) 295 { 296 if( fprintf( fp, "%s\n", line ) != strlen( line ) + 1 ) 297 { 298 irc_usermsg( irc, "fprintf() wrote too little. Disk full?" ); 299 fclose( fp ); 300 return STORAGE_OTHER_ERROR; 301 } 302 } 303 g_free( line ); 304 } 305 306 for( set = irc->set; set; set = set->next ) 307 { 308 if( set->value && set->def ) 309 { 310 g_snprintf( s, sizeof( s ), "set %s \"%s\"", set->key, set->value ); 311 line = obfucrypt( s, irc->password ); 312 if( *line ) 313 { 314 if( fprintf( fp, "%s\n", line ) != strlen( line ) + 1 ) 315 { 316 irc_usermsg( irc, "fprintf() wrote too little. Disk full?" ); 317 fclose( fp ); 318 return STORAGE_OTHER_ERROR; 319 } 320 } 321 g_free( line ); 322 } 323 } 324 325 if( strcmp( irc->mynick, ROOT_NICK ) != 0 ) 326 { 327 g_snprintf( s, sizeof( s ), "rename %s %s", ROOT_NICK, irc->mynick ); 328 line = obfucrypt( s, irc->password ); 329 if( *line ) 330 { 331 if( fprintf( fp, "%s\n", line ) != strlen( line ) + 1 ) 332 { 333 irc_usermsg( irc, "fprintf() wrote too little. Disk full?" ); 334 fclose( fp ); 335 return STORAGE_OTHER_ERROR; 336 } 337 } 338 g_free( line ); 339 } 340 if( fclose( fp ) != 0 ) 341 { 342 irc_usermsg( irc, "fclose() reported an error. Disk full?" ); 343 return STORAGE_OTHER_ERROR; 344 } 345 346 g_snprintf( new_path, 512, "%s%s%s", global.conf->configdir, irc->nick, ".accounts" ); 347 if( unlink( new_path ) != 0 ) 348 { 349 if( errno != ENOENT ) 350 { 351 irc_usermsg( irc, "Error while removing old .accounts file" ); 352 return STORAGE_OTHER_ERROR; 353 } 354 } 355 if( rename( path, new_path ) != 0 ) 356 { 357 irc_usermsg( irc, "Error while renaming new .accounts file" ); 358 return STORAGE_OTHER_ERROR; 359 } 360 361 umask( ou ); 362 363 return STORAGE_OK; 364 } 365 366 static storage_status_t text_check_pass( const char *nick, const char *password ) 367 { 368 char s[512]; 369 FILE *fp; 370 371 g_snprintf( s, 511, "%s%s%s", global.conf->configdir, nick, ".accounts" ); 372 fp = fopen( s, "r" ); 373 if (!fp) 374 return STORAGE_NO_SUCH_USER; 375 376 fscanf( fp, "%32[^\n]s", s ); 377 fclose( fp ); 378 379 if (checkpass( password, s) == -1) 380 return STORAGE_INVALID_PASSWORD; 381 382 return STORAGE_OK; 383 } 384 385 static storage_status_t text_remove( const char *nick, const char *password ) 386 { 387 char s[512]; 388 storage_status_t status; 389 390 status = text_check_pass( nick, password ); 391 if (status != STORAGE_OK) 392 return status; 393 394 g_snprintf( s, 511, "%s%s%s", global.conf->configdir, nick, ".accounts" ); 395 if (unlink( s ) == -1) 396 return STORAGE_OTHER_ERROR; 397 398 g_snprintf( s, 511, "%s%s%s", global.conf->configdir, nick, ".nicks" ); 399 if (unlink( s ) == -1) 400 return STORAGE_OTHER_ERROR; 401 281 */ 402 282 return STORAGE_OK; 403 283 } … … 406 286 .name = "xml", 407 287 .init = xml_init, 408 .check_pass = xml_check_pass,409 .remove = xml_remove,288 // .check_pass = xml_check_pass, 289 // .remove = xml_remove, 410 290 .load = xml_load, 411 291 .save = xml_save
Note: See TracChangeset
for help on using the changeset viewer.