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 (16 years, 8 months 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

# Content
1 /**
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 * Copyright © 2005 Atheme Development Group
10 * Rights to this code are as documented in doc/pod/license.pod.
11 *
12 * $Id: ircservices.C,v 1.6 2007-09-16 18:54:43 pippijn Exp $
13 */
14 /* Include file for high-level encryption routines.
15 *
16 * (C) 2003 Anope Team
17 * Contact us at info@anope.org
18 *
19 * Please read doc/poddoc/license.pod and README for further details.
20 *
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 #include <ermyth/crypto.h>
27 #include <util/md5.h>
28
29 static char const rcsid[] = "$Id: ircservices.C,v 1.6 2007-09-16 18:54:43 pippijn Exp $";
30
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 namespace crypto
47 {
48 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 #if ENCRYPT_MD5
59 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 #endif
84
85 return -1; /* unknown encryption algorithm */
86 }
87
88 #if 0 /* unused */
89 /* 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 #endif
96
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 #ifdef ENCRYPT_MD5
109 if (strcmp (buf, password) == 0)
110 #else
111 if (0)
112 #endif
113 return 1;
114 else
115 return 0;
116 }
117 } // 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>