1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155
|
/*
* Copyright (c) 2005 Atheme Development Group
* Rights to this code are as documented in doc/LICENSE.
*
* IRCServices's weird password encryption thingy, taken from Anope 1.6.3.
*
*/
/* Include file for high-level encryption routines.
*
* (C) 2003 Anope Team
* Contact us at info@anope.org
*
* Please read COPYING and README for furhter details.
*
* Based on the original code of Epona by Lara.
* Based on the original code of Services by Andy Church.
*
* $\Id: myencrypt.c 5 2004-03-29 01:29:50Z dane $
*
*/
#include "atheme.h"
/* necessary anope defines */
#define PASSMAX 32
#define ENCRYPT_MD5
/*************************************************************************/
/******** Our own high-level routines. ********/
#define XTOI(c) ((c)>9 ? (c)-'A'+10 : (c)-'0')
/* Result of this:
* c in [-128,9] => [-183,-46]
* c in [10,127] => [-38,79]
*/
/* Encrypt `src' of length `len' and store the result in `dest'. If the
* resulting string would be longer than `size', return -1 and leave `dest'
* unchanged; else return 0.
*/
static int myencrypt(const char *src, int len, char *dest, int size)
{
#ifdef ENCRYPT_MD5
md5_state_t context;
char digest[33];
char dest2[16];
int i;
if (size < 32)
return -1;
memset(&context, 0, sizeof(context));
memset(&digest, 0, sizeof(digest));
md5_init(&context);
md5_append(&context, (unsigned const char *) src, (size_t) len);
md5_finish(&context, (unsigned char *) digest);
for (i = 0; i < 32; i += 2)
dest2[i / 2] = XTOI(digest[i]) << 4 | XTOI(digest[i + 1]);
/* convert to hex, skipping last 8 bytes (constant) -- jilles */
strcpy(dest, "$ircservices$");
for (i = 0; i <= 7; i++)
sprintf(dest + 13 + 2 * i, "%02x", 255 & dest2[i]);
return 0;
#else
return -1; /* unknown encryption algorithm */
#endif
}
#if 0 /* unused */
/* Shortcut for encrypting a null-terminated string in place. */
static int encrypt_in_place(char *buf, int size)
{
return myencrypt(buf, strlen(buf), buf, size);
}
#endif
/* Compare a plaintext string against an encrypted password. Return 1 if
* they match, 0 if not, and -1 if something went wrong. */
static int check_password(const char *plaintext, const char *password)
{
char buf[BUFSIZE];
if (myencrypt(plaintext, strlen(plaintext), buf, sizeof(buf)) < 0)
return -1;
#ifdef ENCRYPT_MD5
if (strcmp(buf, password) == 0)
#else
if (0)
#endif
return 1;
else
return 0;
}
/*************************************************************************/
DECLARE_MODULE_V1
(
"crypto/ircservices", false, _modinit, _moddeinit,
PACKAGE_STRING,
"Jilles Tjoelker <jilles@stack.nl>"
);
static const char *ircservices_crypt_string(const char *key, const char *salt)
{
static char output[PASSMAX];
if (salt[0] == '$' && salt[1] == '1') /* this is a new pw XXX */
{
myencrypt(key, strlen(key), output, PASSMAX);
return output;
}
else
{
if (check_password(key, salt))
return salt;
else
{
output[0] = '\0';
return output;
}
}
}
static crypt_impl_t ircservices_crypt_impl = {
.id = "ircservices",
.crypt = &ircservices_crypt_string,
};
void _modinit(module_t *m)
{
crypt_register(&ircservices_crypt_impl);
}
void _moddeinit(module_unload_intent_t intent)
{
crypt_unregister(&ircservices_crypt_impl);
}
/* vim:cinoptions=>s,e0,n0,f0,{0,}0,^0,=s,ps,t0,c3,+s,(2s,us,)20,*30,gs,hs
* vim:ts=8
* vim:sw=8
* vim:noexpandtab
*/
|