diff options
author | Dan Winship <danw@src.gnome.org> | 2001-03-02 06:23:23 +0800 |
---|---|---|
committer | Dan Winship <danw@src.gnome.org> | 2001-03-02 06:23:23 +0800 |
commit | 61a496ffcad857b0dac176861206c4a98edc1620 (patch) | |
tree | 7c82b6f1f675b9baee5b06bd1b7406663e771b74 /camel/camel-sasl.c | |
parent | 63a09dc65bc9f54ec389cabb99c848ce56ef2fbc (diff) | |
download | gsoc2013-evolution-61a496ffcad857b0dac176861206c4a98edc1620.tar.gz gsoc2013-evolution-61a496ffcad857b0dac176861206c4a98edc1620.tar.zst gsoc2013-evolution-61a496ffcad857b0dac176861206c4a98edc1620.zip |
Take a GByteArray as input as well. Comment that you can pass %NULL for
* camel-sasl.c (camel_sasl_challenge): Take a GByteArray as input
as well. Comment that you can pass %NULL for @token to get the
initial auth data for mechanisms that are client-initiated.
(camel_sasl_challenge_base64): Convenience function for protocols
that use base64-encoded SASL.
(camel_sasl_authenticated): Implement this... (it was prototyped
already)
(camel_sasl_new): Function to take a service name, a mechanism
name, and a CamelService, and return a CamelSasl for it.
(camel_sasl_authtype, camel_sasl_authtype_list): Functions to
return CamelServiceAuthType information about SASL mechanisms, to
allow providers to deal with them generically.
* camel-sasl-anonymous.c, camel-sasl-plain.c: Update/simplify for
CamelSasl changes. Both of these are single-round
(client-initiated) mechanisms, so they don't need to keep state.
(camel_sasl_plain_new): Removed; use camel_sasl_new instead.
(Can't get rid of camel_sasl_anonymous_new though...)
* camel-sasl-cram-md5.c: Update/simplify for CamelSasl changes.
(camel_sasl_cram_md5_new): Removed; use camel_sasl_new instead.
(cram_md5_challenge): Use md5_get_digest where possible, and
various other minor simplifications. CRAM-MD5 only has a single
round, so there's no need to keep track of state. This code is now
tested (against Cyrus IMAPd) and known to work.
* camel-sasl-kerberos4.h: Update/simplify for CamelSasl changes.
Make only a single #ifdef HAVE_KRB4. Remove stuff from priv that
isn't needed between rounds.
(camel_sasl_kerberos4_new): Removed; use camel_sasl_new instead
(krb4_challenge): Fix up the logic I broke in my previous "at
least make it compile" fixes, update to match other changes, and
remove IMAP-isms that shouldn't be in the generic code. This still
isn't tested, because we're stuck behind a NAT right now...
svn path=/trunk/; revision=8462
Diffstat (limited to 'camel/camel-sasl.c')
-rw-r--r-- | camel/camel-sasl.c | 175 |
1 files changed, 164 insertions, 11 deletions
diff --git a/camel/camel-sasl.c b/camel/camel-sasl.c index a5aebe737c..1e7fc9108c 100644 --- a/camel/camel-sasl.c +++ b/camel/camel-sasl.c @@ -22,13 +22,19 @@ #include <config.h> #include "camel-sasl.h" +#include "camel-mime-utils.h" +#include "camel-service.h" + +#include "camel-sasl-cram-md5.h" +#include "camel-sasl-kerberos4.h" +#include "camel-sasl-plain.h" static CamelObjectClass *parent_class = NULL; /* Returns the class for a CamelSasl */ #define CS_CLASS(so) CAMEL_SASL_CLASS (CAMEL_OBJECT_GET_CLASS (so)) -static GByteArray *sasl_challenge (CamelSasl *sasl, const char *token, CamelException *ex); +static GByteArray *sasl_challenge (CamelSasl *sasl, GByteArray *token, CamelException *ex); static void camel_sasl_class_init (CamelSaslClass *camel_sasl_class) @@ -39,6 +45,13 @@ camel_sasl_class_init (CamelSaslClass *camel_sasl_class) camel_sasl_class->challenge = sasl_challenge; } +static void +camel_sasl_finalize (CamelSasl *sasl) +{ + g_free (sasl->service_name); + camel_object_unref (CAMEL_OBJECT (sasl->service)); +} + CamelType camel_sasl_get_type (void) { @@ -52,7 +65,7 @@ camel_sasl_get_type (void) (CamelObjectClassInitFunc) camel_sasl_class_init, NULL, NULL, - NULL ); + (CamelObjectFinalizeFunc) camel_sasl_finalize); } return type; @@ -60,7 +73,7 @@ camel_sasl_get_type (void) static GByteArray * -sasl_challenge (CamelSasl *sasl, const char *token, CamelException *ex) +sasl_challenge (CamelSasl *sasl, GByteArray *token, CamelException *ex) { g_warning ("sasl_challenge: Using default implementation!"); return NULL; @@ -68,20 +81,160 @@ sasl_challenge (CamelSasl *sasl, const char *token, CamelException *ex) /** * camel_sasl_challenge: - * @sasl: a sasl object - * @token: a token + * @sasl: a SASL object + * @token: a token, or %NULL * @ex: exception * - * Generate the next sasl challenge to send to the server. + * If @token is %NULL, generate the initial SASL message to send to + * the server. (This will be %NULL if the client doesn't initiate the + * exchange.) Otherwise, @token is a challenge from the server, and + * the return value is the response. * - * Return value: a string containing the base64 encoded sasl challenge - * or NULL on either an error or if the negotiation is complete. If an - * error has occured, @ex will also be set. + * Return value: The SASL response or %NULL. If an error occurred, @ex + * will also be set. **/ GByteArray * -camel_sasl_challenge (CamelSasl *sasl, const char *token, CamelException *ex) +camel_sasl_challenge (CamelSasl *sasl, GByteArray *token, CamelException *ex) { g_return_val_if_fail (CAMEL_IS_SASL (sasl), NULL); - + return CS_CLASS (sasl)->challenge (sasl, token, ex); } + +/** + * camel_sasl_challenge_base64: + * @sasl: a SASL object + * @token: a base64-encoded token + * @ex: exception + * + * As with camel_sasl_challenge(), but the challenge @token and the + * response are both base64-encoded. + * + * Return value: As with camel_sasl_challenge(), but base64-encoded. + **/ +char * +camel_sasl_challenge_base64 (CamelSasl *sasl, const char *token, CamelException *ex) +{ + GByteArray *token_binary, *ret_binary; + char *ret; + int len; + + g_return_val_if_fail (CAMEL_IS_SASL (sasl), NULL); + + if (token) { + token_binary = g_byte_array_new (); + len = strlen (token); + g_byte_array_append (token_binary, token, len); + token_binary->len = base64_decode_simple (token_binary->data, len); + } else + token_binary = NULL; + + ret_binary = camel_sasl_challenge (sasl, token_binary, ex); + if (token_binary) + g_byte_array_free (token_binary, TRUE); + if (!ret_binary) + return NULL; + + ret = base64_encode_simple (ret_binary->data, ret_binary->len); + g_byte_array_free (ret_binary, TRUE); + + return ret; +} + +/** + * camel_sasl_authenticated: + * @sasl: a SASL object + * + * Return value: whether or not @sasl has successfully authenticated + * the user. This will be %TRUE after it returns the last needed response. + * The caller must still pass that information on to the server and verify + * that it has accepted it. + **/ +gboolean +camel_sasl_authenticated (CamelSasl *sasl) +{ + return sasl->authenticated; +} + + +/** + * camel_sasl_new: + * @service_name: the SASL service name + * @mechanism: the SASL mechanism + * @service: the CamelService that will be using this SASL + * + * Return value: a new CamelSasl for the given @service_name, + * @mechanism, and @service, or %NULL if the mechanism is not + * supported. + **/ +CamelSasl * +camel_sasl_new (const char *service_name, const char *mechanism, CamelService *service) +{ + CamelSasl *sasl; + + g_return_val_if_fail (service_name != NULL, NULL); + g_return_val_if_fail (mechanism != NULL, NULL); + g_return_val_if_fail (CAMEL_IS_SERVICE (service), NULL); + + /* We don't do ANONYMOUS here, because it's a little bit weird. */ + + if (!strcmp (mechanism, "CRAM-MD5")) + sasl = (CamelSasl *)camel_object_new (CAMEL_SASL_CRAM_MD5_TYPE); +#ifdef HAVE_KRB4 + else if (!strcmp (mechanism, "KERBEROS_V4")) + sasl = (CamelSasl *)camel_object_new (CAMEL_SASL_KERBEROS4_TYPE); +#endif + else if (!strcmp (mechanism, "PLAIN")) + sasl = (CamelSasl *)camel_object_new (CAMEL_SASL_PLAIN_TYPE); + else + return NULL; + + sasl->service_name = g_strdup (service_name); + sasl->service = service; + camel_object_ref (CAMEL_OBJECT (service)); + + return sasl; +} + +/** + * camel_sasl_authtype_list: + * + * Return value: a GList of SASL-supported authtypes. The caller must + * free the list, but not the contents. + **/ +GList * +camel_sasl_authtype_list (void) +{ + GList *types = NULL; + + /* We don't do PLAIN here, because it's considered to be + * normal password authentication, just behind SSL. + */ + + types = g_list_prepend (types, &camel_sasl_cram_md5_authtype); +#ifdef HAVE_KRB4 + types = g_list_prepend (types, &camel_sasl_kerberos4_authtype); +#endif + + return types; +} + +/** + * camel_sasl_authtype: + * @mechanism: the SASL mechanism to get an authtype for + * + * Return value: a CamelServiceAuthType for the given mechanism, if + * it is supported. + **/ +CamelServiceAuthType * +camel_sasl_authtype (const char *mechanism) +{ + if (!strcmp (mechanism, "CRAM-MD5")) + return &camel_sasl_cram_md5_authtype; +#ifdef HAVE_KRB4 + else if (!strcmp (mechanism, "KERBEROS_V4")) + return &camel_sasl_kerberos4_authtype; +#endif + else + return NULL; +} |