source: storage_text.c @ d8acfd3

Last change on this file since d8acfd3 was 3183c21, checked in by Wilmer van der Gaast <wilmer@…>, at 2008-09-06T22:59:32Z

Completely reviewed all uses of irc->password, irc_setpass() and
USTATUS_IDENTIFIED after another account overwriting vulnerability was
found by Tero Marttila.

  • Property mode set to 100644
File size: 4.5 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#ifdef _WIN32
30# define umask _umask
31# define mode_t int
32#endif
33
34#ifndef F_OK
35#define F_OK 0
36#endif
37
38static void text_init (void)
39{
40        /* Don't complain about the configuration directory anymore, leave it
41           up to the XML storage module, which uses the same directory for it
42           anyway. Nobody should be using just the text plugin anymore since
43           it's read only! */
44}
45
46static storage_status_t text_load( irc_t *irc, const char* password )
47{
48        char s[512];
49        char *line;
50        int proto;
51        char nick[MAX_NICK_LENGTH+1];
52        FILE *fp;
53        user_t *ru = user_find( irc, ROOT_NICK );
54        account_t *acc, *acc_lookup[9];
55       
56        g_snprintf( s, 511, "%s%s%s", global.conf->configdir, irc->nick, ".accounts" );
57        fp = fopen( s, "r" );
58        if( !fp ) return STORAGE_NO_SUCH_USER;
59       
60        fscanf( fp, "%32[^\n]s", s );
61
62        if( checkpass( password, s ) != 0 )
63        {
64                fclose( fp );
65                return STORAGE_INVALID_PASSWORD;
66        }
67       
68        while( fscanf( fp, "%511[^\n]s", s ) > 0 )
69        {
70                fgetc( fp );
71                line = deobfucrypt( s, password );
72                if (line == NULL) return STORAGE_OTHER_ERROR;
73                root_command_string( irc, ru, line, 0 );
74                g_free( line );
75        }
76        fclose( fp );
77       
78        /* Build a list with the first listed account of every protocol
79           number. So if the user had nicks defined for a second account on
80           the same IM network, those nicks will be added to the wrong
81           account, and the user should rename those buddies again. But at
82           least from now on things will be saved properly. */
83        memset( acc_lookup, 0, sizeof( acc_lookup ) );
84        for( acc = irc->accounts; acc; acc = acc->next )
85        {
86                if( acc_lookup[0] == NULL && strcmp( acc->prpl->name, "oscar" ) == 0 )
87                        acc_lookup[0] = acc_lookup[1] = acc_lookup[3] = acc;
88                else if( acc_lookup[2] == NULL && strcmp( acc->prpl->name, "yahoo" ) == 0 )
89                        acc_lookup[2] = acc;
90                else if( acc_lookup[4] == NULL && strcmp( acc->prpl->name, "msn" ) == 0 )
91                        acc_lookup[4] = acc;
92                else if( acc_lookup[8] == NULL && strcmp( acc->prpl->name, "jabber" ) == 0 )
93                        acc_lookup[8] = acc;
94        }
95       
96        g_snprintf( s, 511, "%s%s%s", global.conf->configdir, irc->nick, ".nicks" );
97        fp = fopen( s, "r" );
98        if( !fp ) return STORAGE_NO_SUCH_USER;
99        while( fscanf( fp, "%s %d %s", s, &proto, nick ) > 0 )
100        {
101                if( proto < 0 || proto > 8 || ( acc = acc_lookup[proto] ) == NULL )
102                        continue;
103               
104                http_decode( s );
105                nick_set( acc, s, nick );
106        }
107        fclose( fp );
108       
109        return STORAGE_OK;
110}
111
112static storage_status_t text_check_pass( const char *nick, const char *password )
113{
114        char s[512];
115        FILE *fp;
116       
117        g_snprintf( s, 511, "%s%s%s", global.conf->configdir, nick, ".accounts" );
118        fp = fopen( s, "r" );
119        if (!fp)
120                return STORAGE_NO_SUCH_USER;
121
122        fscanf( fp, "%32[^\n]s", s );
123        fclose( fp );
124
125        if (checkpass( password, s) == -1)
126                return STORAGE_INVALID_PASSWORD;
127
128        return STORAGE_OK;
129}
130
131static storage_status_t text_remove( const char *nick, const char *password )
132{
133        char s[512];
134        storage_status_t status;
135
136        status = text_check_pass( nick, password );
137        if (status != STORAGE_OK)
138                return status;
139
140        g_snprintf( s, 511, "%s%s%s", global.conf->configdir, nick, ".accounts" );
141        if (unlink( s ) == -1)
142                return STORAGE_OTHER_ERROR;
143       
144        g_snprintf( s, 511, "%s%s%s", global.conf->configdir, nick, ".nicks" );
145        if (unlink( s ) == -1)
146                return STORAGE_OTHER_ERROR;
147
148        return STORAGE_OK;
149}
150
151storage_t storage_text = {
152        .name = "text",
153        .init = text_init,
154        .check_pass = text_check_pass,
155        .remove = text_remove,
156        .load = text_load
157};
Note: See TracBrowser for help on using the repository browser.