Changeset 9df916f


Ignore:
Timestamp:
2005-12-09T20:48:45Z (14 years ago)
Author:
Jelmer Vernooij <jelmer@…>
Branches:
master
Children:
34759e6
Parents:
c2295f7 (diff), 87c24ba (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge my storage abstraction changes

Files:
3 added
12 edited

Legend:

Unmodified
Added
Removed
  • .bzrignore

    rc2295f7 r9df916f  
    88build-arch-stamp
    99tags
     10decode
     11encode
  • Makefile

    rc2295f7 r9df916f  
    1010
    1111# Program variables
    12 objects = account.o bitlbee.o commands.o conf.o crypting.o help.o ini.o irc.o log.o nick.o query.o set.o unix.o url.o user.o
     12objects = account.o bitlbee.o commands.o conf.o crypting.o help.o ini.o irc.o log.o nick.o query.o set.o unix.o url.o user.o storage_text.o storage.o
    1313subdirs = protocols
    1414
  • bitlbee.c

    rc2295f7 r9df916f  
    2727#include "bitlbee.h"
    2828#include "commands.h"
    29 #include "crypting.h"
    3029#include "protocols/nogaim.h"
    3130#include "help.h"
     
    244243}
    245244
    246 int bitlbee_load( irc_t *irc, const char* password )
    247 {
    248         char s[512];
    249         char *line;
    250         int proto;
    251         char nick[MAX_NICK_LENGTH+1];
    252         FILE *fp;
    253         user_t *ru = user_find( irc, ROOT_NICK );
    254        
    255         if( irc->status == USTATUS_IDENTIFIED )
    256                 return( 1 );
    257        
    258         g_snprintf( s, 511, "%s%s%s", global.conf->configdir, irc->nick, ".accounts" );
    259         fp = fopen( s, "r" );
    260         if( !fp ) return( 0 );
    261        
    262         fscanf( fp, "%32[^\n]s", s );
    263         if( setpass( irc, password, s ) < 0 )
    264         {
    265                 fclose( fp );
    266                 return( -1 );
    267         }
    268        
    269         /* Do this now. If the user runs with AuthMode = Registered, the
    270            account command will not work otherwise. */
    271         irc->status = USTATUS_IDENTIFIED;
    272        
    273         while( fscanf( fp, "%511[^\n]s", s ) > 0 )
    274         {
    275                 fgetc( fp );
    276                 line = deobfucrypt( irc, s );
    277                 root_command_string( irc, ru, line, 0 );
    278                 g_free( line );
    279         }
    280         fclose( fp );
    281        
    282         g_snprintf( s, 511, "%s%s%s", global.conf->configdir, irc->nick, ".nicks" );
    283         fp = fopen( s, "r" );
    284         if( !fp ) return( 0 );
    285         while( fscanf( fp, "%s %d %s", s, &proto, nick ) > 0 )
    286         {
    287                 http_decode( s );
    288                 nick_set( irc, s, proto, nick );
    289         }
    290         fclose( fp );
    291        
    292         if( set_getint( irc, "auto_connect" ) )
    293         {
    294                 strcpy( s, "account on" );      /* Can't do this directly because r_c_s alters the string */
    295                 root_command_string( irc, ru, s, 0 );
    296         }
    297        
    298         return( 1 );
    299 }
    300 
    301 int bitlbee_save( irc_t *irc )
    302 {
    303         char s[512];
    304         char path[512], new_path[512];
    305         char *line;
    306         nick_t *n;
    307         set_t *set;
    308         mode_t ou = umask( 0077 );
    309         account_t *a;
    310         FILE *fp;
    311         char *hash;
    312        
    313         /*\
    314          *  [SH] Nothing should be saved if no password is set, because the
    315          *  password is not set if it was wrong, or if one is not identified
    316          *  yet. This means that a malicious user could easily overwrite
    317          *  files owned by someone else:
    318          *  a Bad Thing, methinks
    319         \*/
    320 
    321         /* [WVG] No? Really? */
    322 
    323         /*\
    324          *  [SH] Okay, okay, it wasn't really Wilmer who said that, it was
    325          *  me. I just thought it was funny.
    326         \*/
    327        
    328         hash = hashpass( irc );
    329         if( hash == NULL )
    330         {
    331                 irc_usermsg( irc, "Please register yourself if you want to save your settings." );
    332                 return( 0 );
    333         }
    334        
    335         g_snprintf( path, 511, "%s%s%s", global.conf->configdir, irc->nick, ".nicks~" );
    336         fp = fopen( path, "w" );
    337         if( !fp ) return( 0 );
    338         for( n = irc->nicks; n; n = n->next )
    339         {
    340                 strcpy( s, n->handle );
    341                 s[169] = 0; /* Prevent any overflow (169 ~ 512 / 3) */
    342                 http_encode( s );
    343                 g_snprintf( s + strlen( s ), 510 - strlen( s ), " %d %s", n->proto, n->nick );
    344                 if( fprintf( fp, "%s\n", s ) != strlen( s ) + 1 )
    345                 {
    346                         irc_usermsg( irc, "fprintf() wrote too little. Disk full?" );
    347                         fclose( fp );
    348                         return( 0 );
    349                 }
    350         }
    351         if( fclose( fp ) != 0 )
    352         {
    353                 irc_usermsg( irc, "fclose() reported an error. Disk full?" );
    354                 return( 0 );
    355         }
    356  
    357         g_snprintf( new_path, 512, "%s%s%s", global.conf->configdir, irc->nick, ".nicks" );
    358         if( unlink( new_path ) != 0 )
    359         {
    360                 if( errno != ENOENT )
    361                 {
    362                         irc_usermsg( irc, "Error while removing old .nicks file" );
    363                         return( 0 );
    364                 }
    365         }
    366         if( rename( path, new_path ) != 0 )
    367         {
    368                 irc_usermsg( irc, "Error while renaming new .nicks file" );
    369                 return( 0 );
    370         }
    371        
    372         g_snprintf( path, 511, "%s%s%s", global.conf->configdir, irc->nick, ".accounts~" );
    373         fp = fopen( path, "w" );
    374         if( !fp ) return( 0 );
    375         if( fprintf( fp, "%s", hash ) != strlen( hash ) )
    376         {
    377                 irc_usermsg( irc, "fprintf() wrote too little. Disk full?" );
    378                 fclose( fp );
    379                 return( 0 );
    380         }
    381         g_free( hash );
    382 
    383         for( a = irc->accounts; a; a = a->next )
    384         {
    385                 if( a->protocol == PROTO_OSCAR || a->protocol == PROTO_ICQ || a->protocol == PROTO_TOC )
    386                         g_snprintf( s, sizeof( s ), "account add oscar \"%s\" \"%s\" %s", a->user, a->pass, a->server );
    387                 else
    388                         g_snprintf( s, sizeof( s ), "account add %s \"%s\" \"%s\" \"%s\"",
    389                                     proto_name[a->protocol], a->user, a->pass, a->server ? a->server : "" );
    390                
    391                 line = obfucrypt( irc, s );
    392                 if( *line )
    393                 {
    394                         if( fprintf( fp, "%s\n", line ) != strlen( line ) + 1 )
    395                         {
    396                                 irc_usermsg( irc, "fprintf() wrote too little. Disk full?" );
    397                                 fclose( fp );
    398                                 return( 0 );
    399                         }
    400                 }
    401                 g_free( line );
    402         }
    403        
    404         for( set = irc->set; set; set = set->next )
    405         {
    406                 if( set->value && set->def )
    407                 {
    408                         g_snprintf( s, sizeof( s ), "set %s \"%s\"", set->key, set->value );
    409                         line = obfucrypt( irc, s );
    410                         if( *line )
    411                         {
    412                                 if( fprintf( fp, "%s\n", line ) != strlen( line ) + 1 )
    413                                 {
    414                                         irc_usermsg( irc, "fprintf() wrote too little. Disk full?" );
    415                                         fclose( fp );
    416                                         return( 0 );
    417                                 }
    418                         }
    419                         g_free( line );
    420                 }
    421         }
    422        
    423         if( strcmp( irc->mynick, ROOT_NICK ) != 0 )
    424         {
    425                 g_snprintf( s, sizeof( s ), "rename %s %s", ROOT_NICK, irc->mynick );
    426                 line = obfucrypt( irc, s );
    427                 if( *line )
    428                 {
    429                         if( fprintf( fp, "%s\n", line ) != strlen( line ) + 1 )
    430                         {
    431                                 irc_usermsg( irc, "fprintf() wrote too little. Disk full?" );
    432                                 fclose( fp );
    433                                 return( 0 );
    434                         }
    435                 }
    436                 g_free( line );
    437         }
    438         if( fclose( fp ) != 0 )
    439         {
    440                 irc_usermsg( irc, "fclose() reported an error. Disk full?" );
    441                 return( 0 );
    442         }
    443        
    444         g_snprintf( new_path, 512, "%s%s%s", global.conf->configdir, irc->nick, ".accounts" );
    445         if( unlink( new_path ) != 0 )
    446         {
    447                 if( errno != ENOENT )
    448                 {
    449                         irc_usermsg( irc, "Error while removing old .accounts file" );
    450                         return( 0 );
    451                 }
    452         }
    453         if( rename( path, new_path ) != 0 )
    454         {
    455                 irc_usermsg( irc, "Error while renaming new .accounts file" );
    456                 return( 0 );
    457         }
    458        
    459         umask( ou );
    460        
    461         return( 1 );
    462 }
    463 
    464245void bitlbee_shutdown( gpointer data )
    465246{
  • bitlbee.h

    rc2295f7 r9df916f  
    100100
    101101#include "irc.h"
     102#include "storage.h"
    102103#include "set.h"
    103104#include "protocols/nogaim.h"
     
    115116        help_t *help;
    116117        conf_t *conf;
     118        storage_t *storage;
    117119        char *helpfile;
    118120        GMainLoop *loop;
     
    127129int root_command_string( irc_t *irc, user_t *u, char *command, int flags );
    128130int root_command( irc_t *irc, char *command[] );
    129 int bitlbee_load( irc_t *irc, const char *password );
    130 int bitlbee_save( irc_t *irc );
    131131void bitlbee_shutdown( gpointer data );
    132132double gettime( void );
  • commands.c

    rc2295f7 r9df916f  
    8686int cmd_identify( irc_t *irc, char **cmd )
    8787{
    88         int checkie = bitlbee_load( irc, cmd[1] );
    89        
    90         if( checkie == -1 )
    91         {
     88        storage_status_t status = global.storage->load( irc->nick, cmd[1], irc );
     89       
     90        switch (status) {
     91        case STORAGE_INVALID_PASSWORD:
    9292                irc_usermsg( irc, "Incorrect password" );
    93         }
    94         else if( checkie == 0 )
    95         {
     93                break;
     94        case STORAGE_NO_SUCH_USER:
    9695                irc_usermsg( irc, "The nick is (probably) not registered" );
    97         }
    98         else if( checkie == 1 )
    99         {
     96                break;
     97        case STORAGE_OK:
    10098                irc_usermsg( irc, "Password accepted" );
    101         }
    102         else
    103         {
     99                break;
     100        default:
    104101                irc_usermsg( irc, "Something very weird happened" );
     102                break;
    105103        }
    106104       
     
    110108int cmd_register( irc_t *irc, char **cmd )
    111109{
    112         int checkie;
    113         char path[512];
    114        
    115110        if( global.conf->authmode == AUTHMODE_REGISTERED )
    116111        {
     
    118113                return( 0 );
    119114        }
    120        
    121         g_snprintf( path, 511, "%s%s%s", global.conf->configdir, irc->nick, ".accounts" );
    122         checkie = access( path, F_OK );
    123        
    124         g_snprintf( path, 511, "%s%s%s", global.conf->configdir, irc->nick, ".nicks" );
    125         checkie += access( path, F_OK );
    126        
    127         if( checkie == -2 )
    128         {
    129                 setpassnc( irc, cmd[1] );
    130                 root_command_string( irc, user_find( irc, irc->mynick ), "save", 0 );
    131                 irc->status = USTATUS_IDENTIFIED;
    132         }
    133         else
    134         {
    135                 irc_usermsg( irc, "Nick is already registered" );
     115
     116        irc_setpass( irc, cmd[1] );
     117        switch( global.storage->save( irc, FALSE )) {
     118                case STORAGE_ALREADY_EXISTS:
     119                        irc_usermsg( irc, "Nick is already registered" );
     120                        break;
     121                       
     122                case STORAGE_OK:
     123                        irc->status = USTATUS_IDENTIFIED;
     124                        break;
     125
     126                default:
     127                        irc_usermsg( irc, "Error registering" );
     128                        break;
    136129        }
    137130       
     
    141134int cmd_drop( irc_t *irc, char **cmd )
    142135{
    143         char s[512];
    144         FILE *fp;
    145        
    146         g_snprintf( s, 511, "%s%s%s", global.conf->configdir, irc->nick, ".accounts" );
    147         fp = fopen( s, "r" );
    148         if( !fp )
    149         {
     136        storage_status_t status;
     137       
     138        status = global.storage->remove (irc->nick, cmd[1]);
     139        switch (status) {
     140        case STORAGE_NO_SUCH_USER:
    150141                irc_usermsg( irc, "That account does not exist" );
    151142                return( 0 );
    152         }
    153        
    154         fscanf( fp, "%32[^\n]s", s );
    155         fclose( fp );
    156         if( setpass( irc, cmd[1], s ) < 0 )
    157         {
    158                 irc_usermsg( irc, "Incorrect password" );
    159                 return( 0 );
    160         }
    161        
    162         g_snprintf( s, 511, "%s%s%s", global.conf->configdir, irc->nick, ".accounts" );
    163         unlink( s );
    164        
    165         g_snprintf( s, 511, "%s%s%s", global.conf->configdir, irc->nick, ".nicks" );
    166         unlink( s );
    167        
    168         setpassnc( irc, NULL );
    169         irc_usermsg( irc, "Files belonging to account `%s' removed", irc->nick );
    170        
    171         return( 0 );
     143        case STORAGE_INVALID_PASSWORD:
     144                irc_usermsg( irc, "Password invalid" );
     145                return( 0 );
     146        case STORAGE_OK:
     147                irc_setpass( irc, NULL );
     148                irc_usermsg( irc, "Account `%s' removed", irc->nick );
     149                return( 0 );
     150        default:
     151                irc_usermsg( irc, "Error: '%d'", status );
     152                return( 0 );
     153        }
    172154}
    173155
     
    634616int cmd_save( irc_t *irc, char **cmd )
    635617{
    636         if( bitlbee_save( irc ) )
     618        if( global.storage->save( irc, TRUE ) == STORAGE_OK )
    637619                irc_usermsg( irc, "Configuration saved" );
    638620        else
  • conf.c

    rc2295f7 r9df916f  
    5050        conf->nofork = 0;
    5151        conf->verbose = 0;
     52        conf->storage = "text";
    5253        conf->runmode = RUNMODE_INETD;
    5354        conf->authmode = AUTHMODE_OPEN;
     
    198199                                conf->motdfile = g_strdup( ini->value );
    199200                        }
     201                        else if( g_strcasecmp( ini->key, "storage" ) == 0 )
     202                        {
     203                                g_free( conf->storage );
     204                                conf->storage = g_strdup( ini->value );
     205                        }
    200206                        else if( g_strcasecmp( ini->key, "pinginterval" ) == 0 )
    201207                        {
  • conf.h

    rc2295f7 r9df916f  
    4242        char *configdir;
    4343        char *motdfile;
     44        char *storage;
    4445        int ping_interval;
    4546        int ping_timeout;
  • crypting.c

    rc2295f7 r9df916f  
    5252#include <stdlib.h>
    5353
    54 #define irc_usermsg
    55 
    5654#endif
    5755
     
    6260\*/
    6361
    64 /* USE WITH CAUTION!
    65    Sets pass without checking */
    66 void setpassnc (irc_t *irc, const char *pass)
    67 {
    68         if (irc->password) g_free (irc->password);
    69        
    70         if (pass) {
    71                 irc->password = g_strdup (pass);
    72                 irc_usermsg (irc, "Password successfully changed");
    73         } else {
    74                 irc->password = NULL;
    75         }
    76 }
    77 
    78 int setpass (irc_t *irc, const char *pass, const char* md5sum)
     62int checkpass (const char *pass, const char *md5sum)
    7963{
    8064        md5_state_t md5state;
     
    9478                if (digits[1] != md5sum[j + 1]) return (-1);
    9579        }
    96        
    97         /* If pass is correct, we end up here and we set the pass */
    98         setpassnc (irc, pass);
    99        
    100         return (0);
    101 }
     80
     81        return( 0 );
     82}
     83
    10284
    10385char *hashpass (irc_t *irc) {
  • crypting.h

    rc2295f7 r9df916f  
    2424*/
    2525
    26 void setpassnc (irc_t *irc, const char *pass); /* USE WITH CAUTION! */
    27 int setpass (irc_t *irc, const char *pass, const char* md5sum);
     26int checkpass (const char *password, const char *md5sum);
    2827char *hashpass (irc_t *irc);
    2928char *obfucrypt (irc_t *irc, char *line);
  • irc.c

    rc2295f7 r9df916f  
    3232GSList *irc_connection_list = NULL;
    3333
    34 char *passchange (irc_t *irc, void *set, char *value)
    35 {
    36         setpassnc (irc, value);
     34static char *passchange (irc_t *irc, void *set, char *value)
     35{
     36        irc_setpass (irc, value);
    3737        return (NULL);
    3838}
     
    161161       
    162162        if( irc->status >= USTATUS_IDENTIFIED && set_getint( irc, "save_on_quit" ) )
    163                 if( !bitlbee_save( irc ) )
     163                if( !global.storage->save( irc, TRUE ) )
    164164                        irc_usermsg( irc, "Error while saving settings!" );
    165165       
     
    266266        if( global.conf->runmode == RUNMODE_INETD )
    267267                g_main_quit( global.loop );
     268}
     269
     270/* USE WITH CAUTION!
     271   Sets pass without checking */
     272void irc_setpass (irc_t *irc, const char *pass)
     273{
     274        if (irc->password) g_free (irc->password);
     275       
     276        if (pass) {
     277                irc->password = g_strdup (pass);
     278                irc_usermsg (irc, "Password successfully changed");
     279        } else {
     280                irc->password = NULL;
     281        }
    268282}
    269283
  • irc.h

    rc2295f7 r9df916f  
    137137void irc_whois( irc_t *irc, char *nick );
    138138int irc_away( irc_t *irc, char *away );
     139void irc_setpass( irc_t *irc, const char *pass ); /* USE WITH CAUTION! */
    139140
    140141int irc_send( irc_t *irc, char *nick, char *s, int flags );
  • unix.c

    rc2295f7 r9df916f  
    5252       
    5353        global.helpfile = g_strdup( HELP_FILE );
    54        
     54
    5555        global.conf = conf_load( argc, argv );
    5656        if( global.conf == NULL )
    5757                return( 1 );
    58        
     58
     59
    5960        if( global.conf->runmode == RUNMODE_INETD )
    6061        {
     
    7071        if( i != 0 )
    7172                return( i );
     73
     74        global.storage = storage_init( global.conf->storage );
     75        if ( global.storage == NULL) {
     76                log_message( LOGLVL_ERROR, "No such storage backend '%s'", global.conf->storage );
     77                return( 1 );
     78        }
     79       
    7280       
    7381        /* Catch some signals to tell the user what's happening before quitting */
     
    8795        if( !getuid() || !geteuid() )
    8896                log_message( LOGLVL_WARNING, "BitlBee is running with root privileges. Why?" );
    89         if( access( global.conf->configdir, F_OK ) != 0 )
    90                 log_message( LOGLVL_WARNING, "The configuration directory %s does not exist. Configuration won't be saved.", CONFIG );
    91         else if( access( global.conf->configdir, R_OK ) != 0 || access( global.conf->configdir, W_OK ) != 0 )
    92                 log_message( LOGLVL_WARNING, "Permission problem: Can't read/write from/to %s.", global.conf->configdir );
    9397        if( help_init( &(global.help) ) == NULL )
    9498                log_message( LOGLVL_WARNING, "Error opening helpfile %s.", HELP_FILE );
Note: See TracChangeset for help on using the changeset viewer.