ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/ermyth/modules/crypto/ircservices.C
Revision: 1.7
Committed: Sat Sep 22 14:27:27 2007 UTC (19 years ago) by pippijn
Content type: text/plain
Branch: MAIN
CVS Tags: HEAD
Changes since 1.6: +3 -2 lines
Log Message:
split up ermyth into ermyth-modules, libermyth (currently just ermyth-util) and ermyth-core

File Contents

# User Rev Content
1 pippijn 1.6 /**
2     * ircservices.C: IRCServices's weird password encryption thingy, taken from Anope 1.6.3.
3     *
4     * Copyright © 2007 Pippijn van Steenhoven / The Ermyth Team
5     * Rights to this code are as documented in COPYING.
6     *
7     *
8     * Portions of this file were derived from sources bearing the following license:
9 pippijn 1.5 * Copyright © 2005 Atheme Development Group
10 pippijn 1.2 * Rights to this code are as documented in doc/pod/license.pod.
11 pippijn 1.1 *
12 pippijn 1.7 * $Id: ircservices.C,v 1.6 2007-09-16 18:54:43 pippijn Exp $
13 pippijn 1.1 */
14     /* Include file for high-level encryption routines.
15     *
16     * (C) 2003 Anope Team
17     * Contact us at info@anope.org
18     *
19 pippijn 1.4 * Please read doc/poddoc/license.pod and README for further details.
20 pippijn 1.1 *
21     * Based on the original code of Epona by Lara.
22     * Based on the original code of Services by Andy Church.
23     */
24    
25     #include "atheme.h"
26 pippijn 1.5 #include <ermyth/crypto.h>
27 pippijn 1.7 #include <util/md5.h>
28 pippijn 1.5
29 pippijn 1.7 static char const rcsid[] = "$Id: ircservices.C,v 1.6 2007-09-16 18:54:43 pippijn Exp $";
30 pippijn 1.1
31     /* necessary anope defines */
32     #define PASSMAX 32
33     #define ENCRYPT_MD5 1
34    
35     /*************************************************************************/
36    
37     /******** Our own high-level routines. ********/
38    
39    
40     #define XTOI(c) ((c)>9 ? (c)-'A'+10 : (c)-'0')
41     /* Result of this:
42     * c in [-128,9] => [-183,-46]
43     * c in [10,127] => [-38,79]
44     */
45    
46 pippijn 1.5 namespace crypto
47 pippijn 1.1 {
48 pippijn 1.5 namespace impl
49     {
50     /**
51     * Encrypt `src' of length `len' and store the result in `dest'. If the
52     * resulting string would be longer than `size', return -1 and leave `dest'
53     * unchanged; else return 0.
54     */
55     static int
56     encrypt (char const * const src, int len, char *dest, int size)
57     {
58 pippijn 1.1 #if ENCRYPT_MD5
59 pippijn 1.5 MD5Context context;
60     char digest[33];
61     char dest2[16];
62     int i;
63    
64     if (size < 32)
65     return -1;
66    
67     memset (&context, 0, sizeof (context));
68     memset (&digest, 0, sizeof (digest));
69    
70     MD5Init (&context);
71     MD5Update (&context, (unsigned char const *) src, (size_t) len);
72     MD5Final ((unsigned char *) digest, &context);
73    
74     for (i = 0; i < 32; i += 2)
75     dest2[i / 2] = XTOI (digest[i]) << 4 | XTOI (digest[i + 1]);
76    
77     /* convert to hex, skipping last 8 bytes (constant) -- jilles */
78     strcpy (dest, "$ircservices$");
79     for (i = 0; i <= 7; i++)
80     sprintf (dest + 13 + 2 * i, "%02x", 255 & dest2[i]);
81     return 0;
82    
83 pippijn 1.1 #endif
84 pippijn 1.5
85     return -1; /* unknown encryption algorithm */
86     }
87    
88 pippijn 1.1 #if 0 /* unused */
89 pippijn 1.5 /* Shortcut for encrypting a null-terminated string in place. */
90     static int
91     encrypt_in_place (char *buf, int size)
92     {
93     return encrypt (buf, strlen (buf), buf, size);
94     }
95 pippijn 1.1 #endif
96 pippijn 1.5
97     /**
98     * Compare a plaintext string against an encrypted password. Return 1 if
99     * they match, 0 if not, and -1 if something went wrong.
100     */
101     static int
102     check_password (char const * const plaintext, char const * const password)
103     {
104     char buf[BUFSIZE];
105    
106     if (encrypt (plaintext, strlen (plaintext), buf, sizeof (buf)) < 0)
107     return -1;
108 pippijn 1.1 #ifdef ENCRYPT_MD5
109 pippijn 1.5 if (strcmp (buf, password) == 0)
110 pippijn 1.1 #else
111 pippijn 1.5 if (0)
112 pippijn 1.1 #endif
113 pippijn 1.5 return 1;
114     else
115     return 0;
116 pippijn 1.1 }
117 pippijn 1.5 } // namespace impl
118    
119     /*************************************************************************/
120    
121     struct ircservices : handler
122     {
123     virtual char const *crypt (char const * const key, char const * const salt);
124     };
125    
126     char const *
127     ircservices::crypt (char const * const key, char const * const salt)
128     {
129     static char output[PASSMAX];
130     if (salt[0] == '$' && salt[1] == '1') /* this is a new pw XXX */
131     {
132     impl::encrypt (key, strlen (key), output, PASSMAX);
133     return output;
134     }
135     else
136     {
137     if (impl::check_password (key, salt))
138     return salt;
139     else
140     return "";
141     }
142     }
143     } // namespace crypto
144    
145     #define FACREG_TYPE crypto::ircservices
146     #define FACREG_TYPE_NAME "ircservices"
147     #define FACREG_INTERFACE_TYPE crypto::handler
148     #include <ermyth/factory_reg.h>