File: ircservices.c

package info (click to toggle)
atheme-services 7.2.12-2.1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 17,256 kB
  • sloc: ansic: 95,899; sh: 8,462; php: 5,032; perl: 3,327; makefile: 1,279; sed: 16; ruby: 15; python: 3
file content (155 lines) | stat: -rw-r--r-- 3,512 bytes parent folder | download | duplicates (6)
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
 */