/*
* OTP extended response parser.
*
* Copyright (c) 2006 Andrey Panin <pazke@donpac.ru>
*
* This software is released under the MIT license.
*/
#include "lib.h"
#include "buffer.h"
#include "str.h"
#include "strfuncs.h"
#include "hex-binary.h"
#include "otp.h"
#include <ctype.h>
{
data++;
return data;
}
{
return *data != 0;
}
{
unsigned int i = 0;
return -1;
while (*data != '\0') {
char c = *data;
if (i_isxdigit(c)) {
str_append_c(str, c);
if (++i == OTP_HASH_SIZE * 2) {
data++;
break;
}
} else if (!IS_LWS(c)) {
return -1;
}
data++;
}
if (i < OTP_HASH_SIZE * 2)
return -1;
}
#define add_word() do { \
count++; \
} while (0)
{
return -1;
char c = *data;
if (space) {
if (IS_LWS(c))
continue;
else if (i_isalpha(c)) {
str_append_c(word, c);
len = 1;
continue;
}
} else {
if (i_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);
continue;
}
}
break;
}
add_word();
if (count < OTP_WORDS_NUMBER)
return -1;
}
{
const char *p, *s;
unsigned int i = 0;
int algo;
s = p = data;
while ((*p != 0) && !IS_LWS(*p)) p++;
if (*p == 0)
return -1;
if (algo < 0)
return -2;
s = p;
return -3;
p++;
while (i_isalnum(*p) && (i < OTP_MAX_SEED_LEN))
*endptr = p;
return 0;
}
{
const char *end;
if (ret < 0)
return ret;
}
{
const char *end;
if (ret < 0) {
*error = "invalid current OTP";
return ret;
}
if (*end++ != ':') {
*error = "missing colon";
return -1;
}
if (ret < 0) {
*error = "invalid OTP parameters";
return -1;
}
if (*end++ != ':') {
*error = "missing colon";
return -1;
}
if (ret < 0) {
*error = "invalid new OTP";
return -1;
}
if (otp_check_tail(end)) {
*error = "trailing garbage found";
return -1;
}
return 0;
}
{
const char *end;
int ret;
if (ret != 0)
return ret;
if (*end++ != ' ')
return -1;
}
{
}