Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
128 changes: 100 additions & 28 deletions opendmarc/opendmarc-ar.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#include <ctype.h>
#include <assert.h>
#include <string.h>
#include <stdlib.h>
#ifdef ARTEST
# include <sysexits.h>
#endif /* ARTEST */
Expand Down Expand Up @@ -45,7 +46,7 @@
#define ARES_TOKENS ";=."
#define ARES_TOKENS2 "=."

#define ARES_MAXTOKENS 512
#define ARES_MAXTOKENS 1536

/* tables */
struct lookup
Expand Down Expand Up @@ -114,7 +115,7 @@ struct lookup ptypes[] =
** pointers available.
*/

static int
int
ares_tokenize(u_char *input, u_char *outbuf, size_t outbuflen,
u_char **tokens, int ntokens)
{
Expand Down Expand Up @@ -357,7 +358,7 @@ ares_xconvert(struct lookup *table, int code)
*/

int
ares_parse(u_char *hdr, struct authres *ar)
authres_parse(u_char *hdr, struct authres *ar, u_int *instance)
{
_Bool quoted;
int n;
Expand All @@ -366,8 +367,9 @@ ares_parse(u_char *hdr, struct authres *ar)
int r = 0;
int state;
int prevstate;
u_char tmp[MAXHEADER + 2];
u_char tmp[OPENDMARC_ARCARES_MAXHEADER_LEN + 2];
u_char *tokens[ARES_MAXTOKENS];
_Bool ignore_res;

assert(hdr != NULL);
assert(ar != NULL);
Expand All @@ -380,7 +382,7 @@ ares_parse(u_char *hdr, struct authres *ar)
return -1;

prevstate = -1;
state = 0;
state = (instance == NULL)?0:20;
n = 0;

quoted = FALSE;
Expand Down Expand Up @@ -452,11 +454,18 @@ ares_parse(u_char *hdr, struct authres *ar)
break;

case 3: /* method */
n++;
r = 0;
ignore_res = TRUE;
if (n < MAXARESULTS)
{
int method = ares_convert(methods, (char *) tokens[c]);
if (method != ARES_METHOD_UNKNOWN)
{
ar->ares_result[n++].result_method = method;
ignore_res = FALSE;
}
}

ar->ares_result[n - 1].result_method = ares_convert(methods,
(char *) tokens[c]);
r = 0;
prevstate = state;
state = 4;

Expand All @@ -473,8 +482,11 @@ ares_parse(u_char *hdr, struct authres *ar)
break;

case 5: /* result */
ar->ares_result[n - 1].result_result = ares_convert(aresults,
(char *) tokens[c]);
if (!ignore_res)
{
ar->ares_result[n - 1].result_result
= ares_convert(aresults, (char *) tokens[c]);
}
prevstate = state;
state = 6;

Expand All @@ -491,9 +503,12 @@ ares_parse(u_char *hdr, struct authres *ar)
break;

case 8:
strlcpy((char *) ar->ares_result[n - 1].result_reason,
(char *) tokens[c],
sizeof ar->ares_result[n - 1].result_reason);
if (!ignore_res)
{
strlcpy((char *) ar->ares_result[n - 1].result_reason,
(char *) tokens[c],
sizeof ar->ares_result[n - 1].result_reason);
}

prevstate = state;
state = 9;
Expand Down Expand Up @@ -532,9 +547,12 @@ ares_parse(u_char *hdr, struct authres *ar)
{
r--;

strlcat((char *) ar->ares_result[n - 1].result_value[r],
(char *) tokens[c],
sizeof ar->ares_result[n - 1].result_value[r]);
if (!ignore_res)
{
strlcat((char *) ar->ares_result[n - 1].result_value[r],
(char *) tokens[c],
sizeof ar->ares_result[n - 1].result_value[r]);
}

prevstate = state;
state = 13;
Expand All @@ -558,7 +576,10 @@ ares_parse(u_char *hdr, struct authres *ar)
if (x == ARES_PTYPE_UNKNOWN)
return -1;

ar->ares_result[n - 1].result_ptype[r] = x;
if (!ignore_res)
{
ar->ares_result[n - 1].result_ptype[r] = x;
}

prevstate = state;
state = 10;
Expand All @@ -577,9 +598,12 @@ ares_parse(u_char *hdr, struct authres *ar)
break;

case 11: /* property */
strlcpy((char *) ar->ares_result[n - 1].result_property[r],
(char *) tokens[c],
sizeof ar->ares_result[n - 1].result_property[r]);
if (!ignore_res)
{
strlcpy((char *) ar->ares_result[n - 1].result_property[r],
(char *) tokens[c],
sizeof ar->ares_result[n - 1].result_property[r]);
}

prevstate = state;
state = 12;
Expand All @@ -597,11 +621,14 @@ ares_parse(u_char *hdr, struct authres *ar)
break;

case 13: /* value */
strlcat((char *) ar->ares_result[n - 1].result_value[r],
(char *) tokens[c],
sizeof ar->ares_result[n - 1].result_value[r]);
r++;
ar->ares_result[n - 1].result_props = r;
if (!ignore_res)
{
strlcat((char *) ar->ares_result[n - 1].result_value[r - 1],
(char *) tokens[c],
sizeof ar->ares_result[n - 1].result_value[r - 1]);
ar->ares_result[n - 1].result_props = r;
}

prevstate = state;
if (c < ntoks - 1 && tokens[c + 1][1] == '\0')
Expand All @@ -619,6 +646,53 @@ ares_parse(u_char *hdr, struct authres *ar)
}

break;

case 20: /* start state of AAR; instance */
if (tokens[c][0] != 'i' ||
tokens[c][1] != '\0')
return -1;

prevstate = state;
state = 21;

break;

case 21: /* = */
if (tokens[c][0] != '=' ||
tokens[c][1] != '\0')
return -1;

prevstate = state;
state = 22;

break;

case 22: /* position */
if (!isascii(tokens[c][0]) ||
!isdigit(tokens[c][0]) ||
!(tokens[c][1] == '\0' ||
isascii(tokens[c][1]) &&
isdigit(tokens[c][1]) &&
tokens[c][2] == '\0'))
return -1;

*instance = (u_int)strtol(tokens[c], NULL, 10);

prevstate = state;
state = 23;

break;

case 23: /* ; */
if (tokens[c][0] != ';' ||
tokens[c][1] != '\0')
return -1;

prevstate = state;
state = 0;

break;

}
}

Expand All @@ -643,8 +717,6 @@ ares_parse(u_char *hdr, struct authres *ar)
** EX_USAGE or EX_OK
*/

# define NTOKENS 256

int
main(int argc, char **argv)
{
Expand All @@ -655,7 +727,7 @@ main(int argc, char **argv)
char *progname;
struct authres ar;
u_char buf[1024];
u_char *toks[NTOKENS];
u_char *toks[ARES_MAXTOKENS];

progname = (p = strrchr(argv[0], '/')) == NULL ? argv[0] : p + 1;

Expand Down
47 changes: 44 additions & 3 deletions opendmarc/opendmarc-ar.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,13 @@

/* limits */
#define AUTHRESHDRNAME "Authentication-Results"
#define MAXARESULTS 16
#define MAXARESULTS 32
#define MAXPROPS 16
#define MAXAVALUE 256

/* buffer to cache a single header */
#define OPENDMARC_ARCARES_MAXHEADER_LEN 4096

/* ARES_METHOD_T -- type for specifying an authentication method */
typedef int ares_method_t;

Expand Down Expand Up @@ -87,6 +90,42 @@ struct authres
struct result ares_result[MAXARESULTS];
};

/*
** ARES_TOKENIZE -- tokenize a string
**
** Parameters:
** input -- input string
** outbuf -- output buffer
** outbuflen -- number of bytes available at "outbuf"
** tokens -- array of token pointers
** ntokens -- number of token pointers available at "tokens"
**
** Return value:
** -1 -- not enough space at "outbuf" for tokenizing
** other -- number of tokens identified; may be greater than
** "ntokens" if there were more tokens found than there were
** pointers available.
*/
extern int ares_tokenize __P((u_char *input, u_char *outbuf, size_t outbuflen,
u_char **tokens, int ntokens));
/*
** AUTHRES_PARSE -- parse an Authentication-Results: or
** ARC-Authenticaion-Results:header, return a
** structure containing a parsed result
**
** Parameters:
** hdr -- NULL-terminated contents of an Authentication-Results:
** header field
** ar -- a pointer to a (struct authres) loaded by values after parsing
** instance -- a pointer to store instance ID for AAR header.
** If it is NULL, parse the header field as of AR.
** If it is not NULL, parse the header field as of AAR.
**
** Return value:
** 0 on success, -1 on failure.
*/
extern int authres_parse __P((u_char *hdr, struct authres *ar,
u_int *instance));
/*
** ARES_PARSE -- parse an Authentication-Results: header, return a
** structure containing a parsed result
Expand All @@ -100,6 +139,8 @@ struct authres
** 0 on success, -1 on failure.
*/

extern int ares_parse __P((u_char *hdr, struct authres *ar));

inline int ares_parse __P((u_char *hdr, struct authres *ar))
{
return authres_parse(hdr, ar, NULL);
}
#endif /* _OPENDMARC_AR_H_ */
Loading