aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJorge Arellano Cid <jcid@dillo.org>2009-01-02 16:27:01 -0300
committerJorge Arellano Cid <jcid@dillo.org>2009-01-02 16:27:01 -0300
commitdfa816bd71ffe4cee9fad7ab69298b5a590bfde7 (patch)
treeb3a1c2a2c7ad0d408107d60fb5c73caa1205657d
parent5486bedf18450ae4de413c4174a0175948c95c3e (diff)
Refactored Auth_parse_auth_basic().
-rw-r--r--src/auth.c258
1 files changed, 145 insertions, 113 deletions
diff --git a/src/auth.c b/src/auth.c
index ad77b3b4..41388485 100644
--- a/src/auth.c
+++ b/src/auth.c
@@ -76,7 +76,7 @@ static AuthParse_t *Auth_parse_new()
static void Auth_parse_free(AuthParse_t *auth_parse)
{
if (auth_parse) {
- dFree((void *) auth_parse->realm);
+ dFree((void *)auth_parse->realm);
}
}
@@ -101,132 +101,163 @@ static int Auth_is_token_char(char c)
return (strchr(invalid, c) || iscntrl(c)) ? 0 : 1;
}
-static void Auth_parse_auth_basic(AuthParse_t *auth_parse, char *auth)
+/*
+ * Unquote the content of a quoted string.
+ * Return: newly allocated unquoted content.
+ *
+ * Arguments:
+ * quoted: pointer to the first char *after* the initial double quote.
+ * size: the number of chars in the result, *not* including a final '\0'.
+ *
+ * Preconditions:
+ * quoted points to a correctly quoted and escaped string.
+ * size is the number of characters in the quoted string, *after*
+ * removing escape characters.
+ *
+ */
+static const char *Auth_unquote_value(const char *quoted, int size)
{
- int token_value_pairs_found;
- char *realm = NULL;
- static const char realm_token[] = "realm";
-
- /* parse comma-separated token-value pairs */
- token_value_pairs_found = 0;
- while (1) {
- char *token, *value;
- int token_size, value_size;
-
- /* skip host and comma characters */
- while (*auth == ' ' || *auth == ',')
- auth++;
-
- /* end of string? */
- if (!*auth)
- goto end_parse;
-
- /* parse a token */
- token = auth;
- token_size = 0;
- while (Auth_is_token_char(*auth)) {
- auth++;
- token_size++;
- }
- if (token_size == 0) {
- MSG("auth.c: Auth_parse_auth_basic: "
- "missing Basic auth token\n");
- goto end_parse;
- }
+ char c, *value, *value_ptr;
+ value_ptr = value = dNew(char, size + 1);
+ while ((c = *quoted++) != '"')
+ *value_ptr++ = (c == '\\') ? *quoted++ : c;
+ *value_ptr = '\0';
+ return value;
+}
- /* skip space characters */
- while (*auth == ' ')
- auth++;
+/*
+ * Parse a quoted string. Save the result as the auth realm if required.
+ * Return: 1 if the parse succeeds, 0 otherwise.
+ */
+static int Auth_parse_quoted_string(AuthParse_t *auth_parse, int set_realm,
+ char **auth)
+{
+ char *value;
+ int size;
+
+ /* parse the '"' */
+ switch (*(*auth)++) {
+ case '"':
+ break;
+ case '\0':
+ case ',':
+ MSG("auth.c: missing Basic auth token value after '='\n");
+ return 0;
+ break;
+ default:
+ MSG("auth.c: garbage in Basic auth after '='\n");
+ return 0;
+ break;
+ }
- /* parse the '=' */
- switch (*auth++) {
- case '=':
+ /* parse the rest */
+ value = *auth;
+ size = 0;
+ while (1) {
+ switch (*(*auth)++) {
+ case '"':
+ if (set_realm) {
+ dFree((void *)auth_parse->realm);
+ auth_parse->realm = Auth_unquote_value(value, size);
+ auth_parse->ok = 1;
+ }
+ return 1;
break;
case '\0':
- case ',':
- MSG("auth.c: Auth_parse_auth_basic: "
- "missing Basic auth token value\n");
- goto end_parse;
+ MSG("auth.c: auth string ended inside quoted string value\n");
+ return 0;
break;
+ case '\\':
+ /* end of string? */
+ if (!*(*auth)++) {
+ MSG("auth.c: "
+ "auth string ended inside quoted string value "
+ "immediately after \\\n");
+ return 0;
+ }
+ /* fall through to the next case */
default:
- MSG("auth.c: Auth_parse_auth_basic: "
- "garbage after Basic auth token\n");
- goto end_parse;
+ size++;
break;
}
+ }
+}
+
+/*
+ * Parse a token-value pair.
+ * Return: 1 if the parse succeeds, 0 otherwise.
+ */
+static int Auth_parse_token_value(AuthParse_t *auth_parse, char **auth)
+{
+ char *token;
+ int token_size, set_realm;
+ static const char realm_token[] = "realm";
- /* skip space characters */
- while (*auth == ' ')
- auth++;
+ /* parse a token */
+ token = *auth;
+ token_size = 0;
+ while (Auth_is_token_char(**auth)) {
+ (*auth)++;
+ token_size++;
+ }
+ if (token_size == 0) {
+ MSG("auth.c: Auth_parse_token_value: "
+ "missing Basic auth token\n");
+ return 0;
+ }
- /* parse a quoted string */
+ /* skip space characters */
+ while (**auth == ' ')
+ (*auth)++;
+
+ /* parse the '=' */
+ switch (*(*auth)++) {
+ case '=':
+ break;
+ case '\0':
+ case ',':
+ MSG("auth.c: Auth_parse_token_value: "
+ "missing Basic auth token value\n");
+ return 0;
+ break;
+ default:
+ MSG("auth.c: Auth_parse_token_value: "
+ "garbage after Basic auth token\n");
+ return 0;
+ break;
+ }
- /* parse a '"' */
- switch (*auth++) {
- case '"':
- break;
- case '\0':
- case ',':
- MSG("auth.c: Auth_parse_auth_basic: "
- "missing Basic auth token value after '='\n");
- goto end_parse;
- break;
- default:
- MSG("auth.c: Auth_parse_auth_basic: "
- "garbage in Basic auth after '='\n");
- goto end_parse;
- break;
- }
+ /* skip space characters */
+ while (**auth == ' ')
+ (*auth)++;
- /* parse the rest of a quoted string */
- value = auth;
- value_size = 0;
- while (1) {
- switch (*auth++) {
- case '"':
- goto end_quoted_string;
- break;
- case '\0':
- MSG("auth.c: Auth_parse_auth_basic: "
- "auth string ended inside quoted string value\n");
- goto end_parse;
- break;
- case '\\':
- /* end of string? */
- if (!*auth++) {
- MSG("auth.c: Auth_parse_auth_basic: "
- "auth string ended inside quoted string value "
- "immediately after \\\n");
- goto end_parse;
- }
- /* fall through to the next case */
- default:
- value_size++;
- break;
- }
- } /* parse quoted string */
- end_quoted_string:
+ /* is this value the realm? */
+ set_realm =
+ auth_parse->realm == NULL &&
+ strncasecmp(realm_token,token,token_size) == 0 &&
+ strlen(realm_token) == token_size;
- token_value_pairs_found = 1;
+ return Auth_parse_quoted_string(auth_parse, set_realm, auth);
+}
- if (realm == NULL &&
- strncasecmp(realm_token,token,token_size) == 0 &&
- strlen(realm_token) == token_size) {
- /* unquote and save the value */
- char c, *value_ptr, *realm_ptr;
- realm = dNew(char, value_size + 1);
- value_ptr = value;
- realm_ptr = realm;
- while ((c = *value_ptr++) != '"')
- *realm_ptr++ = (c == '\\') ? *value_ptr++ : c;
- *realm_ptr = '\0';
- auth_parse->ok = 1;
- auth_parse->realm = realm;
- _MSG("auth.c: Auth_parse_auth_basic: realm: '%s'\n", realm);
- return;
- }
+static void Auth_parse_auth_basic(AuthParse_t *auth_parse, char **auth)
+{
+ int token_value_pairs_found;
+
+ /* parse comma-separated token-value pairs */
+ token_value_pairs_found = 0;
+ while (1) {
+ /* skip space and comma characters */
+ while (**auth == ' ' || **auth == ',')
+ (*auth)++;
+ /* end of string? */
+ if (!**auth)
+ break;
+ /* parse token-value pair */
+ if (!Auth_parse_token_value(auth_parse, auth))
+ break;
+ token_value_pairs_found = 1;
}
- end_parse:
if (!token_value_pairs_found) {
MSG("auth.c: Auth_parse_auth_basic: "
@@ -234,7 +265,7 @@ static void Auth_parse_auth_basic(AuthParse_t *auth_parse, char *auth)
return;
}
- if (!realm) {
+ if (!auth_parse->realm) {
MSG("auth.c: Auth_parse_auth_basic: "
"missing Basic auth realm\n");
return;
@@ -245,7 +276,8 @@ static void Auth_parse_auth(AuthParse_t *auth_parse, char *auth)
{
_MSG("auth.c: Auth_parse_auth: auth = '%s'\n", auth);
if (strncasecmp(auth, "Basic ", 6) == 0) {
- Auth_parse_auth_basic(auth_parse, auth + 6);
+ auth += 6;
+ Auth_parse_auth_basic(auth_parse, &auth);
} else {
MSG("auth.c: Auth_parse_auth: "
"unknown authorization scheme: auth = {%s}\n",