diff options
author | Patrick Monnerat <pm@datasphere.ch> | 2015-01-20 15:27:25 +0100 |
---|---|---|
committer | Patrick Monnerat <pm@datasphere.ch> | 2015-01-20 15:27:25 +0100 |
commit | e1ea18f90e93d50fc999c46c53685fbdd9508659 (patch) | |
tree | bd269f8ebae1d7f5fc1d127c73e7d194d6a9de6e /lib/curl_sasl.c | |
parent | 5f09cbcdbd0e0ac4e44a32d06122b5e58d575679 (diff) |
SASL: common URL option and auth capabilities decoders for all protocols
Diffstat (limited to 'lib/curl_sasl.c')
-rw-r--r-- | lib/curl_sasl.c | 103 |
1 files changed, 101 insertions, 2 deletions
diff --git a/lib/curl_sasl.c b/lib/curl_sasl.c index b944aa2df..7cb575b33 100644 --- a/lib/curl_sasl.c +++ b/lib/curl_sasl.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 2012 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 2012 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -41,6 +41,7 @@ #include "warnless.h" #include "curl_memory.h" #include "strtok.h" +#include "strequal.h" #include "rawstr.h" #include "non-ascii.h" /* included for Curl_convert_... prototypes */ @@ -73,6 +74,24 @@ return result; \ } + +/* Supported mechanisms */ +const struct { + const char * name; /* Name */ + size_t len; /* Name length */ + unsigned int bit; /* Flag bit */ +} mechtable[] = { + { "LOGIN", 5, SASL_MECH_LOGIN }, + { "PLAIN", 5, SASL_MECH_PLAIN }, + { "CRAM-MD5", 8, SASL_MECH_CRAM_MD5 }, + { "DIGEST-MD5", 10, SASL_MECH_DIGEST_MD5 }, + { "GSSAPI", 6, SASL_MECH_GSSAPI }, + { "EXTERNAL", 8, SASL_MECH_EXTERNAL }, + { "NTLM", 4, SASL_MECH_NTLM }, + { "XOAUTH2", 7, SASL_MECH_XOAUTH2 }, + { ZERO_NULL, 0, 0 } +}; + /* * Return 0 on success and then the buffers are filled in fine. * @@ -248,7 +267,7 @@ static CURLcode sasl_digest_get_qop_values(const char *options, int *value) * * Parameters: * - * serivce [in] - The service type such as www, smtp, pop or imap. + * service [in] - The service type such as www, smtp, pop or imap. * host [in] - The host name or realm. * * Returns a pointer to the newly allocated SPN. @@ -1180,3 +1199,83 @@ void Curl_sasl_cleanup(struct connectdata *conn, unsigned int authused) (void)authused; #endif } + +/* + * Curl_sasl_decode_mech() + * + * Convert an SASL mechanism name to a token. + * + * Parameters: + * + * ptr [in] - The mechanism string. + * maxlen [in] - Maximum mechanism string length. + * len [out] - If not NULL, effective name length. + * + * Return the SASL mechanism token or 0 if no match. + */ +unsigned int +Curl_sasl_decode_mech(const char *ptr, size_t maxlen, size_t *len) +{ + unsigned int i; + char c; + + for(i = 0; mechtable[i].name; i++) { + if(maxlen >= mechtable[i].len && + !memcmp(ptr, mechtable[i].name, mechtable[i].len)) { + if(len) + *len = mechtable[i].len; + if(maxlen == mechtable[i].len) + return mechtable[i].bit; + c = ptr[mechtable[i].len]; + if(!ISUPPER(c) && !ISDIGIT(c) && c != '-' && c != '_') + return mechtable[i].bit; + } + } + + return 0; +} + +/* + * Curl_sasl_parse_url_auth_option() + * + * Parse the URL login options. + */ +CURLcode Curl_sasl_parse_url_auth_option(struct SASL *sasl, + const char *value, size_t len) +{ + CURLcode result = CURLE_OK; + unsigned int mechbit; + size_t llen; + + if(!len) + return CURLE_URL_MALFORMAT; + + if(sasl->resetprefs) { + sasl->resetprefs = FALSE; + sasl->prefmech = SASL_AUTH_NONE; + } + + if(strnequal(value, "*", len)) + sasl->prefmech = SASL_AUTH_ANY; + else if((mechbit = Curl_sasl_decode_mech(value, len, &llen)) && + llen == len) + sasl->prefmech |= mechbit; + else + result = CURLE_URL_MALFORMAT; + + return result; +} + +/* + * Curl_sasl_init() + * + * Initializes an SASL structure. + */ +void Curl_sasl_init(struct SASL *sasl) +{ + sasl->authmechs = SASL_AUTH_NONE; /* No known authentication mechanism yet */ + sasl->prefmech = SASL_AUTH_ANY; /* Prefer all mechanisms */ + sasl->authused = SASL_AUTH_NONE; /* No the authentication mechanism used */ + sasl->resetprefs = TRUE; /* Reset prefmech upon AUTH parsing. */ + sasl->mutual_auth = FALSE; /* No mutual authentication (GSSAPI only) */ +} |