00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include "services.h"
00019
00020 static char *int_to_base64(long);
00021 static long base64_to_int(char *);
00022
00023 char *base64enc(long i)
00024 {
00025 if (i < 0)
00026 return ("0");
00027 return int_to_base64(i);
00028 }
00029
00030 long base64dec(char *b64)
00031 {
00032 if (b64)
00033 return base64_to_int(b64);
00034 else
00035 return 0;
00036 }
00037
00038
00039 static const char Base64[] =
00040 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
00041 static const char Pad64 = '=';
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106 int b64_encode(char *src, size_t srclength, char *target, size_t targsize)
00107 {
00108 size_t datalength = 0;
00109 unsigned char input[3];
00110 unsigned char output[4];
00111 size_t i;
00112
00113 while (2 < srclength) {
00114 input[0] = *src++;
00115 input[1] = *src++;
00116 input[2] = *src++;
00117 srclength -= 3;
00118
00119 output[0] = input[0] >> 2;
00120 output[1] = ((input[0] & 0x03) << 4) + (input[1] >> 4);
00121 output[2] = ((input[1] & 0x0f) << 2) + (input[2] >> 6);
00122 output[3] = input[2] & 0x3f;
00123
00124 if (datalength + 4 > targsize)
00125 return (-1);
00126 target[datalength++] = Base64[output[0]];
00127 target[datalength++] = Base64[output[1]];
00128 target[datalength++] = Base64[output[2]];
00129 target[datalength++] = Base64[output[3]];
00130 }
00131
00132
00133 if (0 != srclength) {
00134
00135 input[0] = input[1] = input[2] = '\0';
00136 for (i = 0; i < srclength; i++)
00137 input[i] = *src++;
00138
00139 output[0] = input[0] >> 2;
00140 output[1] = ((input[0] & 0x03) << 4) + (input[1] >> 4);
00141 output[2] = ((input[1] & 0x0f) << 2) + (input[2] >> 6);
00142
00143 if (datalength + 4 > targsize)
00144 return (-1);
00145 target[datalength++] = Base64[output[0]];
00146 target[datalength++] = Base64[output[1]];
00147 if (srclength == 1)
00148 target[datalength++] = Pad64;
00149 else
00150 target[datalength++] = Base64[output[2]];
00151 target[datalength++] = Pad64;
00152 }
00153 if (datalength >= targsize)
00154 return (-1);
00155 target[datalength] = '\0';
00156 return (datalength);
00157 }
00158
00159
00160
00161
00162
00163
00164
00165 int b64_decode(char *src, char *target, size_t targsize)
00166 {
00167 int tarindex, state, ch;
00168 char *pos;
00169
00170 state = 0;
00171 tarindex = 0;
00172
00173 while ((ch = *src++) != '\0') {
00174 if (isspace(ch))
00175 continue;
00176
00177 if (ch == Pad64)
00178 break;
00179
00180 pos = strchr(Base64, ch);
00181 if (pos == 0)
00182 return (-1);
00183
00184 switch (state) {
00185 case 0:
00186 if (target) {
00187 if ((size_t) tarindex >= targsize)
00188 return (-1);
00189 target[tarindex] = (pos - Base64) << 2;
00190 }
00191 state = 1;
00192 break;
00193 case 1:
00194 if (target) {
00195 if ((size_t) tarindex + 1 >= targsize)
00196 return (-1);
00197 target[tarindex] |= (pos - Base64) >> 4;
00198 target[tarindex + 1] = ((pos - Base64) & 0x0f)
00199 << 4;
00200 }
00201 tarindex++;
00202 state = 2;
00203 break;
00204 case 2:
00205 if (target) {
00206 if ((size_t) tarindex + 1 >= targsize)
00207 return (-1);
00208 target[tarindex] |= (pos - Base64) >> 2;
00209 target[tarindex + 1] = ((pos - Base64) & 0x03)
00210 << 6;
00211 }
00212 tarindex++;
00213 state = 3;
00214 break;
00215 case 3:
00216 if (target) {
00217 if ((size_t) tarindex >= targsize)
00218 return (-1);
00219 target[tarindex] |= (pos - Base64);
00220 }
00221 tarindex++;
00222 state = 0;
00223 break;
00224 default:
00225 abort();
00226 }
00227 }
00228
00229
00230
00231
00232
00233
00234 if (ch == Pad64) {
00235 ch = *src++;
00236 switch (state) {
00237 case 0:
00238 case 1:
00239 return (-1);
00240
00241 case 2:
00242
00243 for ((void) NULL; ch != '\0'; ch = *src++)
00244 if (!isspace(ch))
00245 break;
00246
00247 if (ch != Pad64)
00248 return (-1);
00249 ch = *src++;
00250
00251
00252
00253 case 3:
00254
00255
00256
00257
00258 for ((void) NULL; ch != '\0'; ch = *src++)
00259 if (!isspace(ch))
00260 return (-1);
00261
00262
00263
00264
00265
00266
00267
00268 if (target && target[tarindex] != 0)
00269 return (-1);
00270 }
00271 } else {
00272
00273
00274
00275
00276 if (state != 0)
00277 return (-1);
00278 }
00279
00280 return (tarindex);
00281 }
00282
00283 char *encode_ip(unsigned char *ip)
00284 {
00285 static char buf[25];
00286 unsigned char *cp;
00287 struct in_addr ia;
00288 char *s_ip;
00289
00290 if (!ip)
00291 return "*";
00292
00293 if (strchr((char *) ip, ':')) {
00294 return NULL;
00295 } else {
00296 s_ip = str_signed(ip);
00297 ia.s_addr = inet_addr(s_ip);
00298 cp = (unsigned char *) ia.s_addr;
00299 b64_encode((char *) &cp, sizeof(struct in_addr), buf, 25);
00300 }
00301 return buf;
00302 }
00303
00304 int decode_ip(char *buf)
00305 {
00306 int len = strlen(buf);
00307 char targ[25];
00308 struct in_addr ia;
00309
00310 b64_decode(buf, targ, 25);
00311 ia = *(struct in_addr *) targ;
00312 if (len == 24) {
00313 return 0;
00314 } else if (len == 8)
00315 return ia.s_addr;
00316 else
00317 return 0;
00318 }
00319
00320
00321
00322 char int6_to_base64_map[] = {
00323 '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D',
00324 'E', 'F',
00325 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T',
00326 'U', 'V',
00327 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j',
00328 'k', 'l',
00329 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
00330 '{', '}'
00331 };
00332
00333 char base64_to_int6_map[] = {
00334 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
00335 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
00336 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
00337 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1, -1, -1, -1, -1, -1,
00338 -1, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
00339 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, -1, -1, -1, -1, -1,
00340 -1, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50,
00341 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, -1, 63, -1, -1,
00342 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
00343 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
00344 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
00345 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
00346 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
00347 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
00348 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
00349 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
00350 };
00351
00352 static char *int_to_base64(long val)
00353 {
00354
00355
00356
00357 static char base64buf[8];
00358 long i = 7;
00359
00360 base64buf[i] = '\0';
00361
00362
00363
00364
00365
00366
00367 if (val > 2147483647L) {
00368 abort();
00369 }
00370
00371 do {
00372 base64buf[--i] = int6_to_base64_map[val & 63];
00373 }
00374 while (val >>= 6);
00375
00376 return base64buf + i;
00377 }
00378
00379 static long base64_to_int(char *b64)
00380 {
00381 int v = base64_to_int6_map[(unsigned char) *b64++];
00382
00383 if (!b64)
00384 return 0;
00385
00386 while (*b64) {
00387 v <<= 6;
00388 v += base64_to_int6_map[(unsigned char) *b64++];
00389 }
00390
00391 return v;
00392 }
00393
00394 long base64dects(char *ts)
00395 {
00396 char *token;
00397 long value;
00398
00399 if (!ts) {
00400 return 0;
00401 }
00402 token = myStrGetToken(ts, '!', 1);
00403
00404 if (!token) {
00405 return strtoul(ts, NULL, 10);
00406 }
00407 value = base64dec(token);
00408 Anope_Free(token);
00409 return value;
00410 }