Add OTP parity table. diff -urdpNX /usr/share/dontdiff -x Makefile dovecot.vanilla/src/lib-otp/otp-parity.c dovecot/src/lib-otp/otp-parity.c --- dovecot.vanilla/src/lib-otp/otp-parity.c 1970-01-01 03:00:00.000000000 +0300 +++ dovecot/src/lib-otp/otp-parity.c 2006-06-23 13:44:31.161891112 +0400 @@ -0,0 +1,29 @@ +/* + * OTP parity table. + * + * Copyright (c) 2006 Andrey Panin <pazke at donpac.ru> + * + * This software is released under the MIT license. + */ + +#include "lib.h" +#include "otp.h" + +const unsigned char parity_table[256] = { + 0, 1, 2, 3, 1, 2, 3, 0, 2, 3, 0, 1, 3, 0, 1, 2, + 1, 2, 3, 0, 2, 3, 0, 1, 3, 0, 1, 2, 0, 1, 2, 3, + 2, 3, 0, 1, 3, 0, 1, 2, 0, 1, 2, 3, 1, 2, 3, 0, + 3, 0, 1, 2, 0, 1, 2, 3, 1, 2, 3, 0, 2, 3, 0, 1, + 1, 2, 3, 0, 2, 3, 0, 1, 3, 0, 1, 2, 0, 1, 2, 3, + 2, 3, 0, 1, 3, 0, 1, 2, 0, 1, 2, 3, 1, 2, 3, 0, + 3, 0, 1, 2, 0, 1, 2, 3, 1, 2, 3, 0, 2, 3, 0, 1, + 0, 1, 2, 3, 1, 2, 3, 0, 2, 3, 0, 1, 3, 0, 1, 2, + 2, 3, 0, 1, 3, 0, 1, 2, 0, 1, 2, 3, 1, 2, 3, 0, + 3, 0, 1, 2, 0, 1, 2, 3, 1, 2, 3, 0, 2, 3, 0, 1, + 0, 1, 2, 3, 1, 2, 3, 0, 2, 3, 0, 1, 3, 0, 1, 2, + 1, 2, 3, 0, 2, 3, 0, 1, 3, 0, 1, 2, 0, 1, 2, 3, + 3, 0, 1, 2, 0, 1, 2, 3, 1, 2, 3, 0, 2, 3, 0, 1, + 0, 1, 2, 3, 1, 2, 3, 0, 2, 3, 0, 1, 3, 0, 1, 2, + 1, 2, 3, 0, 2, 3, 0, 1, 3, 0, 1, 2, 0, 1, 2, 3, + 2, 3, 0, 1, 3, 0, 1, 2, 0, 1, 2, 3, 1, 2, 3, 0, +}; diff -urdpNX /usr/share/dontdiff -x Makefile dovecot.vanilla/src/lib-otp/otp-parity.h dovecot/src/lib-otp/otp-parity.h --- dovecot.vanilla/src/lib-otp/otp-parity.h 1970-01-01 03:00:00.000000000 +0300 +++ dovecot/src/lib-otp/otp-parity.h 2006-06-23 13:44:31.161891112 +0400 @@ -0,0 +1,16 @@ +#ifndef __OTP_PARITY_H__ +#define __OTP_PARITY_H__ + +const unsigned char parity_table[256]; + +static inline unsigned int otp_parity(unsigned char *data) +{ + unsigned int i, parity = 0; + + for (i = 0; i < OTP_HASH_SIZE; i++) + parity += parity_table[*data++]; + + return parity & 3; +} + +#endif /* __OTP_PARITY_H__ */
Andrey Panin
2006-Jun-26 12:58 UTC
[Dovecot] [PATCH, RFC 4/13] OTP: extended response parser
Parser for OTP extended response as defined by RFC 2243. diff -urdpNX /usr/share/dontdiff -x Makefile dovecot.vanilla/src/lib-otp/otp-parse.c dovecot/src/lib-otp/otp-parse.c --- dovecot.vanilla/src/lib-otp/otp-parse.c 1970-01-01 03:00:00.000000000 +0300 +++ dovecot/src/lib-otp/otp-parse.c 2006-06-23 13:44:31.213883208 +0400 @@ -0,0 +1,254 @@ +/* + * OTP extended response parser. + * + * Copyright (c) 2006 Andrey Panin <pazke at donpac.ru> + * + * This software is released under the MIT license. + */ + +#include <stdlib.h> +#include <ctype.h> + +#include "lib.h" +#include "buffer.h" +#include "str.h" +#include "strfuncs.h" +#include "hex-binary.h" + +#include "otp.h" + + +#define IS_LWS(c) ((c) == ' ' || (c) == '\t') + +static inline const char *otp_skip_lws(const char *data) +{ + while (*data && IS_LWS(*data)) + data++; + return data; +} + +static inline int otp_check_tail(const char *data) +{ + data = otp_skip_lws(data); + + return *data != 0; +} + +int otp_read_hex(const char *data, const char **endptr, unsigned char *hash) +{ + string_t *str; + buffer_t *buf; + int i = 0; + + if (data == NULL) + return -1; + + str = t_str_new(18); + buf = buffer_create_data(unsafe_data_stack_pool, hash, OTP_HASH_SIZE); + + while (*data) { + char c = *data; + + if (isxdigit(c)) { + str_append_c(str, c); + if (++i == OTP_HASH_SIZE * 2) { + data++; + break; + } + } else if (!IS_LWS(c)) { + if (endptr) + *endptr = data; + return -1; + } + data++; + } + + if (endptr) + *endptr = data; + + if (i < OTP_HASH_SIZE * 2) + return -1; + + return hex_to_binary(str_c(str), buf); +} + +#define add_word() do { \ + tmp = otp_lookup_word(str_c(word)); \ + buffer_append(buf, &tmp, sizeof(tmp)); \ + count++; \ +} while (0) + +int otp_read_words(const char *data, const char **endptr, unsigned char *hash) +{ + int space = 0, len = 0, count = 0; + unsigned int parity = 0, bits[OTP_WORDS_NUMBER], tmp; + string_t *word; + buffer_t *buf; + + if (data == NULL) + return -1; + + word = t_str_new(8); + + data = otp_skip_lws(data); + + buf = buffer_create_data(pool_datastack_create(), bits, sizeof(bits)); + + for (; *data && (count < OTP_WORDS_NUMBER); data++) { + char c = *data; + + if (space) { + if (IS_LWS(c)) + continue; + else if (isalpha(c)) { + str_append_c(word, c); + space = 0; + len = 1; + continue; + } + } else { + if (isalpha(c)) { + if (len > OTP_MAX_WORD_LEN) { + count = 0; + break; + } + str_append_c(word, c); + continue; + } else if (IS_LWS(c)) { + add_word(); + str_truncate(word, 0); + space = 1; + continue; + } + } + break; + } + + if ((str_len(word) > 0) && (count == OTP_WORDS_NUMBER - 1)) + add_word(); + + if (endptr) + *endptr = data; + + if (count < OTP_WORDS_NUMBER) + return -1; + + hash[0] = bits[0] >> 3; + hash[1] = ((bits[0] & 7) << 5) | (bits[1] >> 6); + hash[2] = ((bits[1] & 0x3f) << 2) | (bits[2] >> 9); + hash[3] = (bits[2] >> 1) & 0xff; + hash[4] = ((bits[2] & 3) << 7) | (bits[3] >> 4); + hash[5] = ((bits[3] & 15) << 4) | (bits[4] >> 7); + hash[6] = ((bits[4] & 0x7f) << 1) | (bits[5] >> 10); + hash[7] = (bits[5] >> 2) & 0xff; + parity = bits[5] & 3; + + return otp_parity(hash) != parity; +} + +int otp_read_new_params(const char *data, const char **endptr, + struct otp_state *state) +{ + const char *p, *s; + int i = 0; + + s = p = data; + + while ((*p != 0) && !IS_LWS(*p)) p++; + if (*p == 0) + return -1; + + state->algo = digest_find(t_strdup_until(s, p++)); + if (state->algo < 0) + return -2; + + s = p; + state->seq = strtol(s, (char **) &p, 10); + if ((p == s) || !IS_LWS(*p)) + return -3; + p++; + + while (isalnum(*p) && (i < OTP_MAX_SEED_LEN)) + state->seed[i++] = tolower(*p++); + state->seed[i] = 0; + + *endptr = p; + return 0; +} + +int otp_parse_response(const char *data, unsigned char *hash, int hex) +{ + const char *end; + int ret = hex ? otp_read_hex(data, &end, hash) : + otp_read_words(data, &end, hash); + if (ret < 0) + return ret; + + return otp_check_tail(end); +} + +int otp_parse_init_response(const char *data, struct otp_state *new_state, + unsigned char *hash, int hex, const char **error) +{ + const char *end; + int ret = hex ? otp_read_hex(data, &end, hash) : + otp_read_words(data, &end, hash); + if (ret < 0) { + *error = "invalid current OTP"; + return ret; + } + + end = otp_skip_lws(end); + if (*end++ != ':') { + *error = "missing colon"; + return -1; + } + + ret = otp_read_new_params(end, &end, new_state); + if (ret < 0) { + *error = "invalid OTP parameters"; + return -1; + } + + end = otp_skip_lws(end); + if (*end++ != ':') { + *error = "missing colon"; + return -1; + } + + ret = hex ? otp_read_hex(end, &end, new_state->hash) : + otp_read_words(end, &end, new_state->hash); + if (ret < 0) { + *error = "invalid new OTP"; + return -1; + } + + if (otp_check_tail(end) != 0) { + *error = "trailing garbage found"; + return -1; + } + + return 0; +} + +int otp_parse_dbentry(const char *text, struct otp_state *state) +{ + const char *end; + int ret; + + ret = otp_read_new_params(text, &end, state); + if (ret != 0) + return ret; + + if (*end++ != ' ') + return -1; + + return otp_read_hex(end, NULL, state->hash); +} + +const char * otp_print_dbentry(const struct otp_state *state) +{ + return t_strdup_printf("%s %d %s %s", digest_name(state->algo), + state->seq, state->seed, + binary_to_hex(state->hash, 8)); +} diff -urdpNX /usr/share/dontdiff -x Makefile dovecot.vanilla/src/lib-otp/otp-parse.h dovecot/src/lib-otp/otp-parse.h --- dovecot.vanilla/src/lib-otp/otp-parse.h 1970-01-01 03:00:00.000000000 +0300 +++ dovecot/src/lib-otp/otp-parse.h 2006-06-23 13:44:31.213883208 +0400 @@ -0,0 +1,16 @@ +#ifndef __OTP_PARSE_H__ +#define __OTP_PARSE_H__ + +int otp_read_hex(const char *data, const char **endptr, unsigned char *hash); +int otp_read_words(const char *data, const char **endptr, unsigned char *hash); +int otp_read_new_params(const char *data, const char **endptr, + struct otp_state *state); + +int otp_parse_response(const char *data, unsigned char *hash, int hex); +int otp_parse_init_response(const char *data, struct otp_state *new_state, + unsigned char *hash, int hex, const char **error); + +int otp_parse_dbentry(const char *text, struct otp_state *state); +const char * otp_print_dbentry(const struct otp_state *state); + +#endif /* __OTP_PARSE_H__ */
Andrey Panin
2006-Jun-26 12:58 UTC
[Dovecot] [PATCH, RFC 5/13] OTP: add lib-otp to build process
Finally add lib-otp to the build process. diff -urdpNX /usr/share/dontdiff -x Makefile dovecot.vanilla/configure.in dovecot/configure.in --- dovecot.vanilla/configure.in 2006-06-23 13:42:22.158502608 +0400 +++ dovecot/configure.in 2006-06-23 13:44:31.276873632 +0400 @@ -1742,6 +1742,7 @@ src/lib-imap/Makefile src/lib-index/Makefile src/lib-mail/Makefile src/lib-ntlm/Makefile +src/lib-otp/Makefile src/lib-settings/Makefile src/lib-storage/Makefile src/lib-storage/index/Makefile diff -urdpNX /usr/share/dontdiff -x Makefile dovecot.vanilla/src/lib-otp/Makefile.am dovecot/src/lib-otp/Makefile.am --- dovecot.vanilla/src/lib-otp/Makefile.am 1970-01-01 03:00:00.000000000 +0300 +++ dovecot/src/lib-otp/Makefile.am 2006-06-23 13:44:31.276873632 +0400 @@ -0,0 +1,16 @@ +noinst_LIBRARIES = libotp.a + +AM_CPPFLAGS = \ + -I$(top_srcdir)/src/lib + +libotp_a_SOURCES = \ + otp-dictionary.c \ + otp-hash.c \ + otp-parity.c \ + otp-parse.c + +noinst_HEADERS = \ + otp-dictionary.h \ + otp-hash.h \ + otp-parity.h \ + otp-parse.h diff -urdpNX /usr/share/dontdiff -x Makefile dovecot.vanilla/src/lib-otp/otp.h dovecot/src/lib-otp/otp.h --- dovecot.vanilla/src/lib-otp/otp.h 1970-01-01 03:00:00.000000000 +0300 +++ dovecot/src/lib-otp/otp.h 2006-06-23 13:44:31.277873480 +0400 @@ -0,0 +1,22 @@ +#ifndef __OTP_H__ +#define __OTP_H__ + +#define OTP_MAX_SEED_LEN 16 +#define OTP_MAX_WORD_LEN 4 +#define OTP_WORDS_NUMBER 6 + +#define OTP_HASH_SIZE 8 + +struct otp_state { + int algo; + int seq; + unsigned char hash[OTP_HASH_SIZE]; + char seed[OTP_MAX_SEED_LEN + 1]; +}; + +#include "otp-hash.h" +#include "otp-dictionary.h" +#include "otp-parity.h" +#include "otp-parse.h" + +#endif /* __OTP_H__ */ diff -urdpNX /usr/share/dontdiff -x Makefile dovecot.vanilla/src/Makefile.am dovecot/src/Makefile.am --- dovecot.vanilla/src/Makefile.am 2006-06-23 13:42:22.126507472 +0400 +++ dovecot/src/Makefile.am 2006-06-23 13:44:31.277873480 +0400 @@ -11,6 +11,7 @@ SUBDIRS = \ lib-dict \ lib-sql \ lib-ntlm \ + lib-otp \ lib-settings \ lib-charset \ lib-mail \