]> jfr.im git - irc/quakenet/newserv.git/blob - nterface/library.c
Add jupe support
[irc/quakenet/newserv.git] / nterface / library.c
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/sha1.h"
17 #include "../lib/helix.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 *challenge_random_fd = NULL;
51
52 unsigned char entropybuffer[CHALLENGE_ENTROPYLEN * CHALLENGE_ENTROPYBUF];
53 int entropy_remaining = 0;
54
55 int getcopyconfigitemint(char *section, char *key, int def, int *value) {
56 char buf[50];
57 sstring *ini;
58
59 snprintf(buf, sizeof(buf), "%d", def);
60 ini = getcopyconfigitem(section, key, buf, 6);
61
62 if(!ini)
63 return 0;
64
65 if(!protectedatoi(ini->content, value))
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[20];
95 static char output[sizeof(buf) * 2 + 1];
96 SHA1_CTX context;
97
98 SHA1Init(&context);
99 SHA1Update(&context, (unsigned char *)password, strlen(password));
100 SHA1Update(&context, (unsigned char *)" ", 1);
101 SHA1Update(&context, (unsigned char *)challenge, strlen(challenge));
102 SHA1Final(buf, &context);
103
104 TwentyByteHex(output, buf);
105
106 return output;
107 }
108
109 /* my entropy function from Q */
110 int get_challenge_entropy(unsigned char *data) {
111 if (!challenge_random_fd) {
112 challenge_random_fd = fopen(CHALLENGE_RANDOM_LOCATION, "rb");
113 if(!challenge_random_fd)
114 return 0;
115 }
116
117 if(!entropy_remaining) {
118 if(fread(entropybuffer, 1, sizeof(entropybuffer), challenge_random_fd) != sizeof(entropybuffer))
119 return 0;
120 entropy_remaining = CHALLENGE_ENTROPYBUF;
121 }
122
123 memcpy(data, entropybuffer + (CHALLENGE_ENTROPYBUF - entropy_remaining) * CHALLENGE_ENTROPYLEN, CHALLENGE_ENTROPYLEN);
124 entropy_remaining--;
125
126 return 1;
127 }
128
129 int generate_nonce(unsigned char *nonce, int nterfacer) {
130 unsigned char entropy[CHALLENGE_ENTROPYLEN];
131 struct timeval tvv;
132 if(!get_challenge_entropy(entropy))
133 return 0;
134
135 gettimeofday(&tvv, NULL);
136
137 memcpy(nonce, &tvv, sizeof(struct timeval));
138 memcpy(nonce + sizeof(struct timeval) - 2, entropy, NONCE_LEN - sizeof(struct timeval) + 2);
139
140 if(nterfacer) {
141 nonce[7]&=128;
142 } else {
143 nonce[7]|=127;
144 }
145
146 return 1;
147 }
148
149 char *get_random_hex(void) {
150 static char output[CHALLENGE_ENTROPYLEN * 2 + 1];
151 unsigned char stored[CHALLENGE_ENTROPYLEN];
152 if(get_challenge_entropy(stored)) {
153 TwentyByteHex(output, stored);
154 } else {
155 return NULL;
156 }
157 return output;
158 }
159
160 char *int_to_hex(unsigned char *input, char *buf, int len) {
161 int i;
162 for(i=0;i<len;i++)
163 sprintf(buf + i * 2, "%.2x", input[i]);
164 *(buf + len * 2) = '\0';
165 return buf;
166 }
167
168 int hex_to_int(char *input, unsigned char *buf, int buflen) {
169 int i;
170 for(i=0;i<buflen;i++) {
171 if((0xff == hexlookup[(int)input[i * 2]]) || (0xff == hexlookup[(int)input[i * 2 + 1]])) {
172 return 0;
173 } else {
174 buf[i] = (hexlookup[(int)input[i * 2]] << 4) | hexlookup[(int)input[i * 2 + 1]];
175 }
176 }
177 return 1;
178 }
179
180 char *request_error(int errn) {
181 static char err[100];
182
183 err[0] = '\0';
184 switch (errn) {
185 case RE_MEM_ERROR:
186 snc(err, "Memory error");
187 break;
188 case RE_SERVICE_NOT_FOUND:
189 snc(err, "Service not found on this nterfaced instance");
190 break;
191 case RE_REQUEST_REJECTED:
192 snc(err, "Transport handler rejected request");
193 break;
194 case RE_CONNECTION_CLOSED:
195 snc(err, "Transport handler closed connection");
196 break;
197 case RE_TRANSPORT_NOT_FOUND:
198 snc(err, "Transport module not yet loaded for this service");
199 break;
200 case RE_COMMAND_NOT_FOUND:
201 snc(err, "Command not found on this service");
202 break;
203 case RE_WRONG_ARG_COUNT:
204 snc(err, "Wrong number of arguments for this command");
205 break;
206 case RE_TOO_MANY_ARGS:
207 snc(err, "Too many arguments supplied");
208 break;
209 case RE_SERVICER_NOT_FOUND:
210 snc(err, "Service not found on this nterfacer instance");
211 break;
212 default:
213 snc(err, "Unable to find error message");
214 }
215 err[sizeof(err) - 1] = '\0';
216
217 return err;
218 }