source: crypting.c @ cb91b72

Last change on this file since cb91b72 was 43e3368, checked in by Wilmer van der Gaast <wilmer@…>, at 2005-11-23T17:35:18Z

Little code cleanup in Jabber module, added support for Jabber headline messages.

  • Property mode set to 100644
File size: 5.7 KB
Line 
1  /********************************************************************\
2  * BitlBee -- An IRC to other IM-networks gateway                     *
3  *                                                                    *
4  * Copyright 2002-2004 Sjoerd Hemminga and others                     *
5  \********************************************************************/
6
7/* A little bit of encryption for the users' passwords                  */
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/* [WvG] This file can also be compiled into a stand-alone program
27   which can encode/decode BitlBee account files. The main() will be
28   included if CRYPTING_MAIN is defined. Or just do "make decode" and
29   the programs will be built. */
30
31#ifndef CRYPTING_MAIN
32#define BITLBEE_CORE
33#include "bitlbee.h"
34#include "irc.h"
35#include "md5.h"
36#include "crypting.h"
37#include <string.h>
38#include <stdio.h>
39#include <stdlib.h>
40
41#else
42
43typedef struct irc
44{
45        char *password;
46} irc_t;
47
48#define set_add( a, b, c, d )
49#define set_find( a, b ) NULL
50
51#include "md5.h"
52#include "crypting.h"
53#include <string.h>
54#include <stdio.h>
55#include <stdlib.h>
56
57#define irc_usermsg
58
59#endif
60
61/*\
62 * [SH] Do _not_ call this if it's not entirely sure that it will not cause
63 * harm to another users file, since this does not check the password for
64 * correctness.
65\*/
66
67/* USE WITH CAUTION!
68   Sets pass without checking */
69void setpassnc (irc_t *irc, char *pass) {
70        if (!set_find (irc, "password"))
71                set_add (irc, "password", NULL, passchange);
72       
73        if (irc->password) g_free (irc->password);
74       
75        if (pass) {
76                irc->password = g_strdup (pass);
77                irc_usermsg (irc, "Password successfully changed");
78        } else {
79                irc->password = NULL;
80        }
81}
82
83char *passchange (irc_t *irc, void *set, char *value) {
84        setpassnc (irc, value);
85        return (NULL);
86}
87
88int setpass (irc_t *irc, char *pass, char* md5sum) {
89        md5_state_t md5state;
90        md5_byte_t digest[16];
91        int i, j;
92        char digits[3];
93       
94        md5_init (&md5state);
95        md5_append (&md5state, (unsigned char *)pass, strlen (pass));
96        md5_finish (&md5state, digest);
97       
98        for (i = 0, j = 0; i < 16; i++, j += 2) {
99                /* Check password for correctness */
100                g_snprintf (digits, sizeof (digits), "%02x\n", digest[i]);
101               
102                if (digits[0] != md5sum[j]) return (-1);
103                if (digits[1] != md5sum[j + 1]) return (-1);
104        }
105       
106        /* If pass is correct, we end up here and we set the pass */
107        setpassnc (irc, pass);
108       
109        return (0);
110}
111
112char *hashpass (irc_t *irc) {
113        md5_state_t md5state;
114        md5_byte_t digest[16];
115        int i;
116        char digits[3];
117        char *rv;
118       
119        if (irc->password == NULL) return (NULL);
120       
121        rv = (char *)g_malloc (33);
122        memset (rv, 0, 33);
123       
124        md5_init (&md5state);
125        md5_append (&md5state, (unsigned char *)irc->password, strlen (irc->password));
126        md5_finish (&md5state, digest);
127       
128        for (i = 0; i < 16; i++) {
129                /* Build a hash of the pass */
130                g_snprintf (digits, sizeof (digits), "%02x", digest[i]);
131                strcat (rv, digits);
132        }
133       
134        return (rv);
135}
136
137char *obfucrypt (irc_t *irc, char *line) {
138        int i, j;
139        char *rv;
140       
141        if (irc->password == NULL) return (NULL);
142       
143        rv = (char *)g_malloc (strlen (line) + 1);
144        memset (rv, '\0', strlen (line) + 1);
145       
146        i = j = 0;
147        while (*line) {
148                /* Encrypt/obfuscate the line, using the password */
149                if (*(signed char*)line < 0) *line = - (*line);
150                if (((signed char*)irc->password)[i] < 0) irc->password[i] = - irc->password[i];
151               
152                rv[j] = *line + irc->password[i]; /* Overflow intended */
153               
154                line++;
155                if (!irc->password[++i]) i = 0;
156                j++;
157        }
158       
159        return (rv);
160}
161
162char *deobfucrypt (irc_t *irc, char *line) {
163        int i, j;
164        char *rv;
165       
166        if (irc->password == NULL) return (NULL);
167       
168        rv = (char *)g_malloc (strlen (line) + 1);
169        memset (rv, '\0', strlen (line) + 1);
170       
171        i = j = 0;
172        while (*line) {
173                /* Decrypt/deobfuscate the line, using the pass */
174                rv[j] = *line - irc->password[i]; /* Overflow intended */
175               
176                line++;
177                if (!irc->password[++i]) i = 0;
178                j++;
179        }
180       
181        return (rv);
182}
183
184#ifdef CRYPTING_MAIN
185
186/* A little main() function for people who want a stand-alone program to
187   encode/decode BitlCrypted files. */
188
189int main( int argc, char *argv[] )
190{
191        irc_t *irc = g_malloc( sizeof( irc_t ) );
192        char *hash, *action, line[256];
193        char* (*func)( irc_t *, char * );
194       
195        if( argc < 2 )
196        {
197                fprintf( stderr, "Usage: %s <password>\n\n"
198                                 "Reads from stdin, writes to stdout.\n"
199                                 "Call as \"encode\" to encode, \"decode\" to decode.\n", argv[0] );
200                return( 1 );
201        }
202       
203        memset( irc, 0, sizeof( irc_t ) );
204        irc->password = g_strdup( argv[1] );
205       
206        hash = hashpass( irc );
207        action = argv[0] + strlen( argv[0] ) - strlen( "encode" );
208       
209        if( strcmp( action, "encode" ) == 0 )
210        {
211                fwrite( hash, 32, 1, stdout );
212                func = obfucrypt;
213        }
214        else if( strcmp( action, "decode" ) == 0 )
215        {
216                char hash2[32];
217               
218                fread( hash2, 32, 1, stdin );
219                if( memcmp( hash, hash2, 32 ) != 0 )
220                {
221                        fprintf( stderr, "Passwords don't match. Can't decode.\n" );
222                        return( 1 );
223                }
224                func = deobfucrypt;
225        }
226        else
227        {
228                return( main( 0, NULL ) );
229        }
230       
231        while( fscanf( stdin, "%[^\n]255s", line ) > 0 )
232        {
233                char *out;
234               
235                /* Flush the newline */
236                fgetc( stdin );
237               
238                out = func( irc, line );
239                printf( "%s\n", out );
240                g_free( out );
241        }
242       
243        return( 0 );
244}
245
246#endif
Note: See TracBrowser for help on using the repository browser.