source: storage_text.c @ fa29d093

Last change on this file since fa29d093 was 34337a7, checked in by Wilmer van der Gaast <wilmer@…>, at 2007-02-18T22:46:21Z

Fixed a possible issue with corrupted .nicks files in text_load().

  • Property mode set to 100644
File size: 4.8 KB
Line 
1  /********************************************************************\
2  * BitlBee -- An IRC to other IM-networks gateway                     *
3  *                                                                    *
4  * Copyright 2002-2004 Wilmer van der Gaast and others                *
5  \********************************************************************/
6
7/* Storage backend that uses the same file format as <=1.0 */
8
9/*
10  This program is free software; you can redistribute it and/or modify
11  it under the terms of the GNU General Public License as published by
12  the Free Software Foundation; either version 2 of the License, or
13  (at your option) any later version.
14
15  This program is distributed in the hope that it will be useful,
16  but WITHOUT ANY WARRANTY; without even the implied warranty of
17  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  GNU General Public License for more details.
19
20  You should have received a copy of the GNU General Public License with
21  the Debian GNU/Linux distribution in /usr/share/common-licenses/GPL;
22  if not, write to the Free Software Foundation, Inc., 59 Temple Place,
23  Suite 330, Boston, MA  02111-1307  USA
24*/
25
26#define BITLBEE_CORE
27#include "bitlbee.h"
28#include "crypting.h"
29
30static void text_init (void)
31{
32        if( access( global.conf->configdir, F_OK ) != 0 )
33                log_message( LOGLVL_WARNING, "The configuration directory %s does not exist. Configuration won't be saved.", global.conf->configdir );
34        else if( access( global.conf->configdir, R_OK ) != 0 || access( global.conf->configdir, W_OK ) != 0 )
35                log_message( LOGLVL_WARNING, "Permission problem: Can't read/write from/to %s.", global.conf->configdir );
36}
37
38static storage_status_t text_load ( const char *my_nick, const char* password, irc_t *irc )
39{
40        char s[512];
41        char *line;
42        int proto;
43        char nick[MAX_NICK_LENGTH+1];
44        FILE *fp;
45        user_t *ru = user_find( irc, ROOT_NICK );
46        account_t *acc, *acc_lookup[9];
47       
48        if( irc->status & USTATUS_IDENTIFIED )
49                return( 1 );
50       
51        g_snprintf( s, 511, "%s%s%s", global.conf->configdir, my_nick, ".accounts" );
52        fp = fopen( s, "r" );
53        if( !fp ) return STORAGE_NO_SUCH_USER;
54       
55        fscanf( fp, "%32[^\n]s", s );
56
57        if( checkpass( password, s ) != 0 )
58        {
59                fclose( fp );
60                return STORAGE_INVALID_PASSWORD;
61        }
62       
63        /* Do this now. If the user runs with AuthMode = Registered, the
64           account command will not work otherwise. */
65        irc->status |= USTATUS_IDENTIFIED;
66       
67        while( fscanf( fp, "%511[^\n]s", s ) > 0 )
68        {
69                fgetc( fp );
70                line = deobfucrypt( s, password );
71                if (line == NULL) return STORAGE_OTHER_ERROR;
72                root_command_string( irc, ru, line, 0 );
73                g_free( line );
74        }
75        fclose( fp );
76       
77        /* Build a list with the first listed account of every protocol
78           number. So if the user had nicks defined for a second account on
79           the same IM network, those nicks will be added to the wrong
80           account, and the user should rename those buddies again. But at
81           least from now on things will be saved properly. */
82        memset( acc_lookup, 0, sizeof( acc_lookup ) );
83        for( acc = irc->accounts; acc; acc = acc->next )
84        {
85                if( acc_lookup[0] == NULL && strcmp( acc->prpl->name, "oscar" ) == 0 )
86                        acc_lookup[0] = acc_lookup[1] = acc_lookup[3] = acc;
87                else if( acc_lookup[2] == NULL && strcmp( acc->prpl->name, "yahoo" ) == 0 )
88                        acc_lookup[2] = acc;
89                else if( acc_lookup[4] == NULL && strcmp( acc->prpl->name, "msn" ) == 0 )
90                        acc_lookup[4] = acc;
91                else if( acc_lookup[8] == NULL && strcmp( acc->prpl->name, "jabber" ) == 0 )
92                        acc_lookup[8] = acc;
93        }
94       
95        g_snprintf( s, 511, "%s%s%s", global.conf->configdir, my_nick, ".nicks" );
96        fp = fopen( s, "r" );
97        if( !fp ) return STORAGE_NO_SUCH_USER;
98        while( fscanf( fp, "%s %d %s", s, &proto, nick ) > 0 )
99        {
100                if( proto < 0 || proto > 8 || ( acc = acc_lookup[proto] ) == NULL )
101                        continue;
102               
103                http_decode( s );
104                nick_set( acc, s, nick );
105        }
106        fclose( fp );
107       
108        return STORAGE_OK;
109}
110
111static storage_status_t text_check_pass( const char *nick, const char *password )
112{
113        char s[512];
114        FILE *fp;
115       
116        g_snprintf( s, 511, "%s%s%s", global.conf->configdir, nick, ".accounts" );
117        fp = fopen( s, "r" );
118        if (!fp)
119                return STORAGE_NO_SUCH_USER;
120
121        fscanf( fp, "%32[^\n]s", s );
122        fclose( fp );
123
124        if (checkpass( password, s) == -1)
125                return STORAGE_INVALID_PASSWORD;
126
127        return STORAGE_OK;
128}
129
130static storage_status_t text_remove( const char *nick, const char *password )
131{
132        char s[512];
133        storage_status_t status;
134
135        status = text_check_pass( nick, password );
136        if (status != STORAGE_OK)
137                return status;
138
139        g_snprintf( s, 511, "%s%s%s", global.conf->configdir, nick, ".accounts" );
140        if (unlink( s ) == -1)
141                return STORAGE_OTHER_ERROR;
142       
143        g_snprintf( s, 511, "%s%s%s", global.conf->configdir, nick, ".nicks" );
144        if (unlink( s ) == -1)
145                return STORAGE_OTHER_ERROR;
146
147        return STORAGE_OK;
148}
149
150storage_t storage_text = {
151        .name = "text",
152        .init = text_init,
153        .check_pass = text_check_pass,
154        .remove = text_remove,
155        .load = text_load
156};
Note: See TracBrowser for help on using the repository browser.