diff options
author | Sergey Poznyakoff <gray@gnu.org.ua> | 2020-02-26 15:48:20 +0200 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org.ua> | 2020-02-27 17:40:57 +0200 |
commit | 3b2d57c14f1ed207c79362b7136e3da4054ad817 (patch) | |
tree | 8f97331e65e3d6cc0d483fc0c3d11a2e668e33be /lib/base64.c | |
parent | a9a6567bac8ab7729c243b555e7fb3c4bb2c6e51 (diff) | |
download | ping903-3b2d57c14f1ed207c79362b7136e3da4054ad817.tar.gz ping903-3b2d57c14f1ed207c79362b7136e3da4054ad817.tar.bz2 |
Implememt client-side basic auth
* lib/Makefile.am: Add base64.c
* lib/base64.c: New file.
* lib/basicauth.c: Move base64 support to a separate source.
* lib/basicauth.h (base64_encode,base64_decode): New protos.
* src/strsplit.c: New file.
* src/Makefile.am (libping903_a_SOURCES): Add strsplit.c
* src/defs.h (CRED_FILE_NAME): New macro.
(ecalloc,strsplit,argcv_free): New proto.
* src/mem.c (ecalloc): New function.
* src/ping903.c (strsplit): Remove.
(cf_auth): Use modified strsplit.
* src/ping903q.c (http_query): Attempt to authenticate
if basic auth is required.
* examples/lib/LWP/Ping903.pm: New file.
* examples/dbload: Use LWP::Ping903
* examples/inspect: Likewise.
* examples/ipadd: Likewise.
* examples/ipdel: Likewise.
Diffstat (limited to 'lib/base64.c')
-rw-r--r-- | lib/base64.c | 85 |
1 files changed, 85 insertions, 0 deletions
diff --git a/lib/base64.c b/lib/base64.c new file mode 100644 index 0000000..ad07a5a --- /dev/null +++ b/lib/base64.c @@ -0,0 +1,85 @@ +#include <config.h> +#include <stdlib.h> +#include <errno.h> + +static char b64tab[] = + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + +int +base64_encode(const unsigned char *input, size_t input_len, + unsigned char **output, size_t *output_len) +{ + size_t olen = 4 * (input_len + 2) / 3 + 1; + unsigned char *out = malloc(olen); + + if (!out) + return -1; + *output = out; + while (input_len >= 3) { + *out++ = b64tab[input[0] >> 2]; + *out++ = b64tab[((input[0] << 4) & 0x30) | (input[1] >> 4)]; + *out++ = b64tab[((input[1] << 2) & 0x3c) | (input[2] >> 6)]; + *out++ = b64tab[input[2] & 0x3f]; + input_len -= 3; + input += 3; + } + + if (input_len > 0) { + unsigned char c = (input[0] << 4) & 0x30; + *out++ = b64tab[input[0] >> 2]; + if (input_len > 1) + c |= input[1] >> 4; + *out++ = b64tab[c]; + *out++ = (input_len < 2) ? + '=' : b64tab[(input[1] << 2) & 0x3c]; + *out++ = '='; + } + *output_len = out - *output; + *out = 0; + return 0; +} + +static int b64val[128] = { + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63, + 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1, + -1, 0, 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, -1, -1, -1, -1, -1, + -1, 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, -1, -1, -1, -1, -1 +}; + +int +base64_decode(const unsigned char *input, size_t input_len, + unsigned char *output, size_t output_len) +{ + unsigned char *out = output; +#define AC(c) do { if (output_len-- == 0) return -1; *out++ = (c); } while (0) + + if (!out) + return -1; + + do { + if (input[0] > 127 || b64val[input[0]] == -1 || + input[1] > 127 || b64val[input[1]] == -1 || + input[2] > 127 || + ((input[2] != '=') && (b64val[input[2]] == -1)) || + input[3] > 127 || + ((input[3] != '=') && (b64val[input[3]] == -1))) { + errno = EINVAL; + return -1; + } + AC((b64val[input[0]] << 2) | (b64val[input[1]] >> 4)); + if (input[2] != '=') { + AC(((b64val[input[1]] << 4) & 0xf0) | + (b64val[input[2]] >> 2)); + if (input[3] != '=') + AC(((b64val[input[2]] << 6) & 0xc0) | + b64val[input[3]]); + } + input += 4; + input_len -= 4; + } while (input_len > 0); + return out - output; +} |