ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/vendor/ircservices-5.1.24/encrypt.c
Revision: 3389
Committed: Fri Apr 25 14:12:15 2014 UTC (9 years, 11 months ago) by michael
Content type: text/x-csrc
File size: 9523 byte(s)
Log Message:
- Imported ircservices-5.1.24

File Contents

# Content
1 /* High-level encryption routines.
2 *
3 * IRC Services is copyright (c) 1996-2009 Andrew Church.
4 * E-mail: <achurch@achurch.org>
5 * Parts written by Andrew Kempe and others.
6 * This program is free but copyrighted software; see the file GPL.txt for
7 * details.
8 */
9
10 #include "services.h"
11 #include "modules.h"
12 #include "encrypt.h"
13
14 /*************************************************************************/
15
16 /* List of available ciphers. */
17 static CipherInfo *cipherlist;
18
19 /*************************************************************************/
20 /*************************************************************************/
21
22 /* Default (no encryption) routines. Used when no encryption is selected. */
23
24 /*************************************************************************/
25
26 /* encrypt(): Encrypt `src' of length `len' into `dest' of size `size'.
27 * Returns:
28 * 0 on success
29 * +N if the destination buffer is too small; N is the minimum size
30 * buffer required to hold the encrypted text
31 * -1 on other error
32 */
33
34 static int default_encrypt(const char *src, int len, char *dest, int size)
35 {
36 if (size < PASSMAX) {
37 return PASSMAX;
38 }
39 memset(dest, 0, size);
40 memcpy(dest, src, (len > size) ? size : len);
41 return 0;
42 }
43
44 /*************************************************************************/
45
46 /* Decrypt `src' into buffer `dest' of size `size'. Returns:
47 * 0 on success
48 * +N if the destination buffer is too small; N is the minimum size
49 * buffer required to hold the decrypted text
50 * -2 if the encryption algorithm does not allow decryption
51 * -1 on other error
52 */
53
54 static int default_decrypt(const char *src, char *dest, int size)
55 {
56 int passlen;
57 for (passlen = 0; passlen < PASSMAX; passlen++) {
58 if (!src[passlen]) {
59 break;
60 }
61 }
62 if (size < passlen+1) {
63 return passlen+1 - size;
64 }
65 memset(dest, 0, size);
66 memcpy(dest, src, passlen);
67 return 0;
68 }
69
70 /*************************************************************************/
71
72 /* Check an input password `plaintext' against a stored, encrypted password
73 * `password'. Return value is:
74 * 1 if the password matches
75 * 0 if the password does not match
76 * -1 if an error occurred while checking
77 */
78
79 static int default_check_password(const char *plaintext, const char *password)
80 {
81 if (strncmp(plaintext, password, PASSMAX) == 0) {
82 return 1;
83 } else {
84 return 0;
85 }
86 }
87
88 /*************************************************************************/
89 /*************************************************************************/
90
91 /* High-level password encryption routines. */
92
93 /*************************************************************************/
94
95 /* Allocate and return a new, empty Password structure. Always succeeds
96 * (smalloc() will throw a signal if memory cannot be allocated).
97 */
98
99 Password *new_password(void)
100 {
101 Password *password = smalloc(sizeof(*password));
102 init_password(password);
103 return password;
104 }
105
106 /*************************************************************************/
107
108 /* Initialize a preallocated Password structure. Identical in behavior to
109 * new_password(), except that the passed-in structure is used instead of
110 * allocating a new one, and the structure pointer is not returned.
111 */
112
113 void init_password(Password *password)
114 {
115 memset(password->password, 0, sizeof(password->password));
116 password->cipher = NULL;
117 }
118
119 /*************************************************************************/
120
121 /* Set the contents of a Password structure to the given values. If
122 * cipher is not NULL, a copy of it is made, so the original string may be
123 * disposed of after calling set_password().
124 */
125
126 void set_password(Password *password,
127 const char password_buffer[PASSMAX],
128 const char *cipher)
129 {
130 memcpy(password->password, password_buffer, PASSMAX);
131 if (cipher) {
132 password->cipher = sstrdup(cipher);
133 } else {
134 password->cipher = NULL;
135 }
136 }
137
138 /*************************************************************************/
139
140 /* Copy the contents of a Password structure to another Password structure.
141 * The destination password comes first, a la memcpy().
142 */
143
144 void copy_password(Password *to, const Password *from)
145 {
146 clear_password(to);
147 memcpy(to->password, from->password, sizeof(to->password));
148 if (from->cipher) {
149 to->cipher = sstrdup(from->cipher);
150 } else {
151 to->cipher = NULL;
152 }
153 }
154
155 /*************************************************************************/
156
157 /* Clear and free memory used by the contents of a Password structure,
158 * without freeing the structure itself. Similar to init_password(), but
159 * assumes that the contents of the Password structure are valid (in
160 * particular, assumes that password->cipher needs to be freed if it is
161 * not NULL).
162 */
163
164 void clear_password(Password *password)
165 {
166 memset(password->password, 0, sizeof(password->password));
167 free((char *)password->cipher);
168 password->cipher = NULL;
169 }
170
171 /*************************************************************************/
172
173 /* Free a Password structure allocated with new_password(). Does nothing
174 * if NULL is given.
175 */
176
177 void free_password(Password *password)
178 {
179 if (password) {
180 clear_password(password);
181 free(password);
182 }
183 }
184
185 /*************************************************************************/
186
187 /* Encrypt string `plaintext' of length `len', placing the result in
188 * `password'. Returns:
189 * 0 on success
190 * -2 if the encrypted password is too long to fit in the buffer
191 * -1 on other error
192 */
193
194 int encrypt_password(const char *plaintext, int len, Password *password)
195 {
196 encrypt_func_t low_encrypt = default_encrypt;
197 int res;
198
199 if (EncryptionType) {
200 CipherInfo *ci;
201 LIST_SEARCH(cipherlist, name, EncryptionType, strcmp, ci);
202 if (!ci) {
203 log("encrypt_password(): cipher `%s' not available!",
204 EncryptionType);
205 return -1;
206 }
207 low_encrypt = ci->encrypt;
208 }
209 clear_password(password);
210 res = (*low_encrypt)(plaintext, len, password->password,
211 sizeof(password->password));
212 if (res == 0) {
213 if (EncryptionType) {
214 password->cipher = strdup(EncryptionType);
215 if (!password->cipher) {
216 module_log_perror("strdup() failed in encrypt_password()");
217 clear_password(password);
218 return -1;
219 }
220 }
221 return 0;
222 } else {
223 clear_password(password);
224 if (res > 0) { /* buffer too small */
225 return -2;
226 } else {
227 return -1;
228 }
229 }
230 }
231
232 /*************************************************************************/
233
234 /* Decrypt `password' into buffer `dest' of length `size'. Returns:
235 * 0 on success
236 * +N if the destination buffer is too small; N is the minimum size
237 * buffer required to hold the decrypted password
238 * -2 if the encryption algorithm does not allow decryption
239 * -1 on other error
240 */
241
242 int decrypt_password(const Password *password, char *dest, int size)
243 {
244 decrypt_func_t low_decrypt = default_decrypt;
245
246 if (password->cipher) {
247 CipherInfo *ci;
248 LIST_SEARCH(cipherlist, name, password->cipher, strcmp, ci);
249 if (!ci) {
250 log("decrypt_password(): cipher `%s' not available!",
251 password->cipher);
252 return -1;
253 }
254 low_decrypt = ci->decrypt;
255 }
256 return (*low_decrypt)(password->password, dest, size);
257 }
258
259 /*************************************************************************/
260
261 /* Check an input password `plaintext' against a stored, encrypted password
262 * `password'. Return value is:
263 * 1 if the password matches
264 * 0 if the password does not match
265 * -1 if an error occurred while checking
266 */
267
268 int check_password(const char *plaintext, const Password *password)
269 {
270 check_password_func_t low_check_password = default_check_password;
271
272 if (password->cipher) {
273 CipherInfo *ci;
274 LIST_SEARCH(cipherlist, name, password->cipher, strcmp, ci);
275 if (!ci) {
276 log("check_password(): cipher `%s' not available!",
277 password->cipher);
278 return -1;
279 }
280 low_check_password = ci->check_password;
281 }
282 return (*low_check_password)(plaintext, password->password);
283 }
284
285 /*************************************************************************/
286 /*************************************************************************/
287
288 /* Cipher registration/unregistration. */
289
290 /*************************************************************************/
291
292 /* Register a new cipher. */
293
294 void register_cipher(CipherInfo *ci)
295 {
296 LIST_INSERT(ci, cipherlist);
297 }
298
299 /*************************************************************************/
300
301 /* Unregister a cipher. Does nothing if the cipher was not registered. */
302
303 void unregister_cipher(CipherInfo *ci)
304 {
305 CipherInfo *ci2;
306 LIST_FOREACH (ci2, cipherlist) {
307 if (ci2 == ci) {
308 LIST_REMOVE(ci, cipherlist);
309 break;
310 }
311 }
312 }
313
314 /*************************************************************************/
315
316 /*
317 * Local variables:
318 * c-file-style: "stroustrup"
319 * c-file-offsets: ((case-label . *) (statement-case-intro . *))
320 * indent-tabs-mode: nil
321 * End:
322 *
323 * vim: expandtab shiftwidth=4:
324 */