From 0c039f4e1244f1ab974864d2020644a7e238b60e Mon Sep 17 00:00:00 2001 From: Stephan Bosch <stephan@rename-it.nl> Date: Sun, 30 Nov 2008 21:02:18 +0100 Subject: [PATCH] Enotify: further developed URI parsing. --- .../plugins/enotify/ext-enotify-limits.h | 2 +- src/lib-sieve/plugins/enotify/ntfy-mailto.c | 160 +++++++++++++++--- 2 files changed, 137 insertions(+), 25 deletions(-) diff --git a/src/lib-sieve/plugins/enotify/ext-enotify-limits.h b/src/lib-sieve/plugins/enotify/ext-enotify-limits.h index 214b229c3..84cac2665 100644 --- a/src/lib-sieve/plugins/enotify/ext-enotify-limits.h +++ b/src/lib-sieve/plugins/enotify/ext-enotify-limits.h @@ -4,6 +4,6 @@ #ifndef __EXT_ENOTIFY_LIMITS_H #define __EXT_ENOTIFY_LIMITS_H -#define EXT_ENOTIFY_MAX_SCHEME_LEN 32 +#define EXT_ENOTIFY_MAX_SCHEME_LEN 32 #endif /* __EXT_ENOTIFY_LIMITS_H */ diff --git a/src/lib-sieve/plugins/enotify/ntfy-mailto.c b/src/lib-sieve/plugins/enotify/ntfy-mailto.c index 54b8ed263..7ce3873b5 100644 --- a/src/lib-sieve/plugins/enotify/ntfy-mailto.c +++ b/src/lib-sieve/plugins/enotify/ntfy-mailto.c @@ -2,10 +2,14 @@ */ #include "lib.h" +#include "array.h" +#include "str.h" #include "ioloop.h" #include "str-sanitize.h" #include "message-date.h" +#include "rfc2822.h" + #include "sieve-common.h" #include "sieve-ast.h" #include "sieve-commands.h" @@ -15,9 +19,16 @@ #include "sieve-ext-enotify.h" +/* + * Configuration + */ + +#define NTFY_MAILTO_MAX_RECIPIENTS 4 + /* * Mailto notification method */ + static bool ntfy_mailto_validate_uri (struct sieve_validator *valdtr, struct sieve_ast_argument *arg, const char *uri_body); @@ -71,44 +82,156 @@ static bool _parse_hex_value(const char **in, char *out) *out |= value; (*in)++; - return TRUE; + return (*out != '\0'); } -static bool uri_extract_part -(const char **uri_p, char delim, string_t *part, const char **error_r) +static bool _uri_parse_recipients +(const char **uri_p, const char *const **recipients_r, const char **error_r) { + ARRAY_DEFINE(recipients, const char *); + string_t *to = t_str_new(128); + const char *recipient; const char *p = *uri_p; - while ( *p != '\0' && *p != delim ) { + if ( recipients_r != NULL ) + t_array_init(&recipients, NTFY_MAILTO_MAX_RECIPIENTS); + + while ( *p != '\0' && *p != '?' ) { if ( *p == '%' ) { + /* % encoded character */ char ch; p++; + /* Parse 2-digit hex value */ if ( !_parse_hex_value(&p, &ch) ) { *error_r = "invalid % encoding"; return FALSE; } + + /* Check for delimiter */ + if ( ch == ',' ) { + recipient = str_c(to); + + /* Verify recipient */ + + /* Add recipient to the list */ + if ( recipients_r != NULL ) { + recipient = t_strdup(recipient); + array_append(&recipients, &recipient, 1); + } - str_append_c(part, ch); + /* Reset for next recipient */ + str_truncate(to, 0); + } else { + /* Content character */ + str_append_c(to, ch); + } } else { - str_append_c(part, *p); + /* Content character */ + str_append_c(to, *p); p++; } + } + + /* Skip '?' */ + if ( *p != '\0' ) p++; + + recipient = str_c(to); + + /* Verify recipient */ + + // .... + + if ( recipients_r != NULL ) { + /* Add recipient to the list */ + recipient = t_strdup(recipient); + array_append(&recipients, &recipient, 1); + + /* Return recipients */ + (void)array_append_space(&recipients); + *recipients_r = array_idx(&recipients, 0); } - p++; *uri_p = p; return TRUE; } -static bool ntfy_mailto_parse_uri -(const char *uri_body, const char ***recipients_r, const char ***headers_r, +struct _header_field { + const char *name; + const char *body; +}; + +static bool _uri_parse_headers +(const char **uri_p, struct _header_field *const *headers_r, const char **error_r) { - string_t *to = t_str_new(128); - string_t *hfield = t_str_new(128); + ARRAY_DEFINE(headers, struct _header_field); + string_t *field = t_str_new(128); + const char *p = *uri_p; + + if ( headers_r != NULL ) + t_array_init(&headers, NTFY_MAILTO_MAX_RECIPIENTS); + + while ( *p != '\0' ) { + struct _header_field *hdrf; + + /* Parse field name */ + while ( *p != '\0' && *p != '=' ) { + char ch = *p; + p++; + + if ( ch == '%' ) { + /* Encoded, parse 2-digit hex value */ + if ( !_parse_hex_value(&p, &ch) ) { + *error_r = "invalid % encoding"; + return FALSE; + } + } + str_append_c(field, ch); + } + if ( *p != '\0' ) p++; + + if ( headers_r != NULL ) { + hdrf = array_append_space(&headers); + hdrf->name = t_strdup(str_c(field)); + } + + str_truncate(field, 0); + + /* Parse field body */ + while ( *p != '\0' && *p != '&' ) { + char ch = *p; + p++; + + if ( ch == '%' ) { + /* Encoded, parse 2-digit hex value */ + if ( !_parse_hex_value(&p, &ch) ) { + *error_r = "invalid % encoding"; + return FALSE; + } + } + str_append_c(field, ch); + } + if ( *p != '\0' ) p++; + + if ( headers_r != NULL ) { + hdrf->body = t_strdup(str_c(field)); + str_truncate(field, 0); + } + } + + /* Skip '&' */ + if ( *p != '\0' ) p++; + *uri_p = p; + return TRUE; +} + +static bool ntfy_mailto_parse_uri +(const char *uri_body, const char *const **recipients_r, + struct _header_field *const *headers_r, const char **error_r) +{ const char *p = uri_body; /* @@ -130,26 +253,15 @@ static bool ntfy_mailto_parse_uri /* First extract to-part by searching for '?' and decoding % items */ - if ( !uri_extract_part(&p, '?', to, error_r) ) + if ( !_uri_parse_recipients(&p, recipients_r, error_r) ) return FALSE; - /* Parse to part */ - - // .... - /* Extract hfield items */ while ( *p != '\0' ) { /* Extract hfield item by searching for '&' and decoding '%' items */ - if ( !uri_extract_part(&p, '&', hfield, error_r) ) + if ( !_uri_parse_headers(&p, headers_r, error_r) ) return FALSE; - - /* Add header to list */ - - // .... - - /* Reset for next header */ - str_truncate(hfield, 0); } return TRUE; -- GitLab