Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #ifdef HAVE_CONFIG_H
00024 # include "config.h"
00025 #endif
00026
00027
00028 #include "cram-md5.h"
00029
00030
00031 #include <stdlib.h>
00032
00033
00034 #include <string.h>
00035
00036
00037 #include "challenge.h"
00038
00039
00040 #include "digest.h"
00041
00042 #define MD5LEN 16
00043
00044 int
00045 _gsasl_cram_md5_server_start (Gsasl_session * sctx, void **mech_data)
00046 {
00047 char *challenge;
00048 int rc;
00049
00050 challenge = malloc (CRAM_MD5_CHALLENGE_LEN);
00051 if (challenge == NULL)
00052 return GSASL_MALLOC_ERROR;
00053
00054 rc = cram_md5_challenge (challenge);
00055 if (rc)
00056 return GSASL_CRYPTO_ERROR;
00057
00058 *mech_data = challenge;
00059
00060 return GSASL_OK;
00061 }
00062
00063 int
00064 _gsasl_cram_md5_server_step (Gsasl_session * sctx,
00065 void *mech_data,
00066 const char *input, size_t input_len,
00067 char **output, size_t * output_len)
00068 {
00069 char *challenge = mech_data;
00070 char hash[CRAM_MD5_DIGEST_LEN];
00071 const char *password;
00072 char *username = NULL;
00073 int res = GSASL_OK;
00074 char *normkey;
00075
00076 if (input_len == 0)
00077 {
00078 *output_len = strlen (challenge);
00079 *output = strdup (challenge);
00080
00081 return GSASL_NEEDS_MORE;
00082 }
00083
00084 if (input_len <= MD5LEN * 2)
00085 return GSASL_MECHANISM_PARSE_ERROR;
00086
00087 if (input[input_len - MD5LEN * 2 - 1] != ' ')
00088 return GSASL_MECHANISM_PARSE_ERROR;
00089
00090 username = calloc (1, input_len - MD5LEN * 2);
00091 if (username == NULL)
00092 return GSASL_MALLOC_ERROR;
00093
00094 memcpy (username, input, input_len - MD5LEN * 2 - 1);
00095
00096 gsasl_property_set (sctx, GSASL_AUTHID, username);
00097
00098 free (username);
00099
00100 password = gsasl_property_get (sctx, GSASL_PASSWORD);
00101 if (!password)
00102 return GSASL_NO_PASSWORD;
00103
00104
00105
00106 res = gsasl_saslprep (password, 0, &normkey, NULL);
00107 if (res != GSASL_OK)
00108 return res;
00109
00110 cram_md5_digest (challenge, strlen (challenge),
00111 normkey, strlen (normkey), hash);
00112
00113 free (normkey);
00114
00115 if (memcmp (&input[input_len - MD5LEN * 2], hash, 2 * MD5LEN) == 0)
00116 res = GSASL_OK;
00117 else
00118 res = GSASL_AUTHENTICATION_ERROR;
00119
00120 *output_len = 0;
00121 *output = NULL;
00122
00123 return res;
00124 }
00125
00126 void
00127 _gsasl_cram_md5_server_finish (Gsasl_session * sctx, void *mech_data)
00128 {
00129 char *challenge = mech_data;
00130
00131 free (challenge);
00132 }