]>
Commit | Line | Data |
---|---|---|
1 | /* | |
2 | nterface library functions | |
3 | Copyright (C) 2003-2004 Chris Porter. | |
4 | */ | |
5 | ||
6 | #include <stdio.h> | |
7 | #include <stdlib.h> | |
8 | #include <errno.h> | |
9 | #include <string.h> | |
10 | #include <limits.h> | |
11 | #include <sys/time.h> | |
12 | #include <stdarg.h> | |
13 | ||
14 | #include "../core/config.h" | |
15 | #include "../lib/irc_string.h" | |
16 | #include "../lib/sha2.h" | |
17 | #include "../lib/rijndael.h" | |
18 | ||
19 | #include "library.h" | |
20 | ||
21 | unsigned char hexlookup[256] = { | |
22 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |
23 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |
24 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |
25 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |
26 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x01, | |
27 | 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0xff, 0xff, | |
28 | 0xff, 0xff, 0xff, 0xff, 0xff, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, | |
29 | 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |
30 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |
31 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0a, 0x0b, 0x0c, | |
32 | 0x0d, 0x0e, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |
33 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |
34 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |
35 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |
36 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |
37 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |
38 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |
39 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |
40 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |
41 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |
42 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |
43 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |
44 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |
45 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |
46 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |
47 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff | |
48 | }; | |
49 | ||
50 | FILE *random_fd = NULL; | |
51 | ||
52 | int getcopyconfigitemint(char *section, char *key, int def, int *value) { | |
53 | char buf[50]; | |
54 | sstring *ini; | |
55 | int r; | |
56 | ||
57 | snprintf(buf, sizeof(buf), "%d", def); | |
58 | ini = getcopyconfigitem(section, key, buf, 15); | |
59 | ||
60 | if(!ini) | |
61 | return 0; | |
62 | ||
63 | r = protectedatoi(ini->content, value); | |
64 | freesstring(ini); | |
65 | if(!r) | |
66 | return 0; | |
67 | ||
68 | return 1; | |
69 | } | |
70 | ||
71 | int getcopyconfigitemintpositive(char *section, char *key, int def) { | |
72 | int value; | |
73 | if(!getcopyconfigitemint(section, key, def, &value)) | |
74 | return -1; | |
75 | ||
76 | if(value < 0) | |
77 | return -1; | |
78 | ||
79 | return value; | |
80 | } | |
81 | ||
82 | int positive_atoi(char *data) { | |
83 | int value; | |
84 | if(!protectedatoi(data, &value)) | |
85 | return -1; | |
86 | ||
87 | if(value < 0) | |
88 | return -1; | |
89 | ||
90 | return value; | |
91 | } | |
92 | ||
93 | char *challenge_response(char *challenge, char *password) { | |
94 | unsigned char buf[32]; | |
95 | static char output[sizeof(buf) * 2 + 1]; | |
96 | SHA256_CTX context; | |
97 | ||
98 | SHA256_Init(&context); | |
99 | SHA256_Update(&context, (unsigned char *)challenge, strlen(challenge)); | |
100 | SHA256_Update(&context, (unsigned char *)":", 1); | |
101 | SHA256_Update(&context, (unsigned char *)password, strlen(password)); | |
102 | SHA256_Final(buf, &context); | |
103 | ||
104 | SHA256_Init(&context); | |
105 | SHA256_Update(&context, (unsigned char *)buf, 32); | |
106 | SHA256_Final(buf, &context); | |
107 | ||
108 | ThirtyTwoByteHex(output, buf); | |
109 | ||
110 | return output; | |
111 | } | |
112 | ||
113 | int get_entropy(unsigned char *buf, int bytes) { | |
114 | if (!random_fd) { | |
115 | random_fd = fopen(RANDOM_LOCATION, "rb"); | |
116 | if(!random_fd) | |
117 | return 0; | |
118 | } | |
119 | ||
120 | fread(buf, 1, bytes, random_fd); | |
121 | ||
122 | return 1; | |
123 | } | |
124 | ||
125 | int generate_nonce(unsigned char *nonce, int nterfacer) { | |
126 | unsigned char entropy[20], output[32]; | |
127 | struct timeval tvv; | |
128 | SHA256_CTX c; | |
129 | ||
130 | if(!get_entropy(entropy, 20)) | |
131 | return 0; | |
132 | ||
133 | gettimeofday(&tvv, NULL); | |
134 | ||
135 | SHA256_Init(&c); | |
136 | SHA256_Update(&c, entropy, 20); | |
137 | SHA256_Update(&c, (unsigned char *)&tvv, sizeof(struct timeval)); | |
138 | SHA256_Final(output, &c); | |
139 | memcpy(nonce, output, 16); | |
140 | ||
141 | if(nterfacer) { | |
142 | nonce[7]&=128; | |
143 | } else { | |
144 | nonce[7]|=127; | |
145 | } | |
146 | ||
147 | return 1; | |
148 | } | |
149 | ||
150 | char *int_to_hex(unsigned char *input, char *buf, int len) { | |
151 | int i; | |
152 | for(i=0;i<len;i++) | |
153 | sprintf(buf + i * 2, "%.2x", input[i]); | |
154 | *(buf + len * 2) = '\0'; | |
155 | return buf; | |
156 | } | |
157 | ||
158 | int hex_to_int(char *input, unsigned char *buf, int buflen) { | |
159 | int i; | |
160 | for(i=0;i<buflen;i++) { | |
161 | if((0xff == hexlookup[(int)input[i * 2]]) || (0xff == hexlookup[(int)input[i * 2 + 1]])) { | |
162 | return 0; | |
163 | } else { | |
164 | buf[i] = (hexlookup[(int)input[i * 2]] << 4) | hexlookup[(int)input[i * 2 + 1]]; | |
165 | } | |
166 | } | |
167 | return 1; | |
168 | } | |
169 | ||
170 | char *request_error(int errn) { | |
171 | static char err[100]; | |
172 | ||
173 | err[0] = '\0'; | |
174 | switch (errn) { | |
175 | case RE_MEM_ERROR: | |
176 | snc(err, "Memory error"); | |
177 | break; | |
178 | case RE_SERVICE_NOT_FOUND: | |
179 | snc(err, "Service not found on this nterfaced instance"); | |
180 | break; | |
181 | case RE_REQUEST_REJECTED: | |
182 | snc(err, "Transport handler rejected request"); | |
183 | break; | |
184 | case RE_CONNECTION_CLOSED: | |
185 | snc(err, "Transport handler closed connection"); | |
186 | break; | |
187 | case RE_TRANSPORT_NOT_FOUND: | |
188 | snc(err, "Transport module not yet loaded for this service"); | |
189 | break; | |
190 | case RE_COMMAND_NOT_FOUND: | |
191 | snc(err, "Command not found on this service"); | |
192 | break; | |
193 | case RE_WRONG_ARG_COUNT: | |
194 | snc(err, "Wrong number of arguments for this command"); | |
195 | break; | |
196 | case RE_TOO_MANY_ARGS: | |
197 | snc(err, "Too many arguments supplied"); | |
198 | break; | |
199 | case RE_SERVICER_NOT_FOUND: | |
200 | snc(err, "Service not found on this nterfacer instance"); | |
201 | break; | |
202 | default: | |
203 | snc(err, "Unable to find error message"); | |
204 | } | |
205 | err[sizeof(err) - 1] = '\0'; | |
206 | ||
207 | return err; | |
208 | } | |
209 | ||
210 | rijndaelcbc *rijndaelcbc_init(unsigned char *key, int keybits, unsigned char *iv, int decrypt) { | |
211 | rijndaelcbc *ret = (rijndaelcbc *)ntmalloc(sizeof(rijndaelcbc) + RKLENGTH(keybits) * sizeof(unsigned long)); | |
212 | if(!ret) | |
213 | return NULL; | |
214 | ||
215 | ret->rk = (unsigned long *)(ret + 1); | |
216 | ||
217 | memcpy(ret->prevblock, iv, 16); | |
218 | ||
219 | if(decrypt) { | |
220 | ret->nrounds = rijndaelSetupDecrypt(ret->rk, key, keybits); | |
221 | } else { | |
222 | ret->nrounds = rijndaelSetupEncrypt(ret->rk, key, keybits); | |
223 | } | |
224 | return ret; | |
225 | } | |
226 | ||
227 | void rijndaelcbc_free(rijndaelcbc *c) { | |
228 | ntfree(c); | |
229 | } | |
230 | ||
231 | unsigned char *rijndaelcbc_encrypt(rijndaelcbc *c, unsigned char *ptblock) { | |
232 | int i; | |
233 | unsigned char *p = c->prevblock, *p2 = c->scratch; | |
234 | for(i=0;i<16;i++) | |
235 | *p2++ = *p++ ^ *ptblock++; | |
236 | ||
237 | rijndaelEncrypt(c->rk, c->nrounds, c->scratch, c->prevblock); | |
238 | return c->prevblock; | |
239 | } | |
240 | ||
241 | unsigned char *rijndaelcbc_decrypt(rijndaelcbc *c, unsigned char *ctblock) { | |
242 | int i; | |
243 | unsigned char *p = c->prevblock, *p2 = c->scratch; | |
244 | ||
245 | rijndaelDecrypt(c->rk, c->nrounds, ctblock, c->scratch); | |
246 | ||
247 | for(i=0;i<16;i++) | |
248 | *p2++^=*p++; | |
249 | ||
250 | memcpy(c->prevblock, ctblock, 16); | |
251 | return c->scratch; | |
252 | } |