ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/cvsroot/ermyth/modules/crypto/ircservices.C
Revision: 1.6
Committed: Sun Sep 16 18:54:43 2007 UTC (19 years, 1 month ago) by pippijn
Content type: text/plain
Branch: MAIN
Changes since 1.5: +10 -5 lines
Log Message:
#defines to enum

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.6 * $Id: ircservices.C,v 1.5 2007-08-28 17:08:09 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    
28 pippijn 1.6 static char const rcsid[] = "$Id: ircservices.C,v 1.5 2007-08-28 17:08:09 pippijn Exp $";
29 pippijn 1.1
30     /* necessary anope defines */
31     #define PASSMAX 32
32     #define ENCRYPT_MD5 1
33    
34     /*************************************************************************/
35    
36     /******** Our own high-level routines. ********/
37    
38    
39     #define XTOI(c) ((c)>9 ? (c)-'A'+10 : (c)-'0')
40     /* Result of this:
41     * c in [-128,9] => [-183,-46]
42     * c in [10,127] => [-38,79]
43     */
44    
45 pippijn 1.5 namespace crypto
46 pippijn 1.1 {
47 pippijn 1.5 namespace impl
48     {
49     /**
50     * Encrypt `src' of length `len' and store the result in `dest'. If the
51     * resulting string would be longer than `size', return -1 and leave `dest'
52     * unchanged; else return 0.
53     */
54     static int
55     encrypt (char const * const src, int len, char *dest, int size)
56     {
57 pippijn 1.1 #if ENCRYPT_MD5
58 pippijn 1.5 MD5Context context;
59     char digest[33];
60     char dest2[16];
61     int i;
62    
63     if (size < 32)
64     return -1;
65    
66     memset (&context, 0, sizeof (context));
67     memset (&digest, 0, sizeof (digest));
68    
69     MD5Init (&context);
70     MD5Update (&context, (unsigned char const *) src, (size_t) len);
71     MD5Final ((unsigned char *) digest, &context);
72    
73     for (i = 0; i < 32; i += 2)
74     dest2[i / 2] = XTOI (digest[i]) << 4 | XTOI (digest[i + 1]);
75    
76     /* convert to hex, skipping last 8 bytes (constant) -- jilles */
77     strcpy (dest, "$ircservices$");
78     for (i = 0; i <= 7; i++)
79     sprintf (dest + 13 + 2 * i, "%02x", 255 & dest2[i]);
80     return 0;
81    
82 pippijn 1.1 #endif
83 pippijn 1.5
84     return -1; /* unknown encryption algorithm */
85     }
86    
87 pippijn 1.1 #if 0 /* unused */
88 pippijn 1.5 /* Shortcut for encrypting a null-terminated string in place. */
89     static int
90     encrypt_in_place (char *buf, int size)
91     {
92     return encrypt (buf, strlen (buf), buf, size);
93     }
94 pippijn 1.1 #endif
95 pippijn 1.5
96     /**
97     * Compare a plaintext string against an encrypted password. Return 1 if
98     * they match, 0 if not, and -1 if something went wrong.
99     */
100     static int
101     check_password (char const * const plaintext, char const * const password)
102     {
103     char buf[BUFSIZE];
104    
105     if (encrypt (plaintext, strlen (plaintext), buf, sizeof (buf)) < 0)
106     return -1;
107 pippijn 1.1 #ifdef ENCRYPT_MD5
108 pippijn 1.5 if (strcmp (buf, password) == 0)
109 pippijn 1.1 #else
110 pippijn 1.5 if (0)
111 pippijn 1.1 #endif
112 pippijn 1.5 return 1;
113     else
114     return 0;
115 pippijn 1.1 }
116 pippijn 1.5 } // namespace impl
117    
118     /*************************************************************************/
119    
120     struct ircservices : handler
121     {
122     virtual char const *crypt (char const * const key, char const * const salt);
123     };
124    
125     char const *
126     ircservices::crypt (char const * const key, char const * const salt)
127     {
128     static char output[PASSMAX];
129     if (salt[0] == '$' && salt[1] == '1') /* this is a new pw XXX */
130     {
131     impl::encrypt (key, strlen (key), output, PASSMAX);
132     return output;
133     }
134     else
135     {
136     if (impl::check_password (key, salt))
137     return salt;
138     else
139     return "";
140     }
141     }
142     } // namespace crypto
143    
144     #define FACREG_TYPE crypto::ircservices
145     #define FACREG_TYPE_NAME "ircservices"
146     #define FACREG_INTERFACE_TYPE crypto::handler
147     #include <ermyth/factory_reg.h>