00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #if 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
00049 challenge = malloc (CRAM_MD5_CHALLENGE_LEN);
00050 if (challenge == NULL)
00051 return GSASL_MALLOC_ERROR;
00052
00053 cram_md5_challenge (challenge);
00054
00055 *mech_data = challenge;
00056
00057 return GSASL_OK;
00058 }
00059
00060 int
00061 _gsasl_cram_md5_server_step (Gsasl_session * sctx,
00062 void *mech_data,
00063 const char *input, size_t input_len,
00064 char **output, size_t * output_len)
00065 {
00066 char *challenge = mech_data;
00067 char hash[CRAM_MD5_DIGEST_LEN];
00068 const char *password;
00069 char *username = NULL;
00070 int res = GSASL_OK;
00071 char *normkey;
00072
00073 if (input_len == 0)
00074 {
00075 *output_len = strlen (challenge);
00076 *output = strdup (challenge);
00077
00078 return GSASL_NEEDS_MORE;
00079 }
00080
00081 if (input_len <= MD5LEN * 2)
00082 return GSASL_MECHANISM_PARSE_ERROR;
00083
00084 if (input[input_len - MD5LEN * 2 - 1] != ' ')
00085 return GSASL_MECHANISM_PARSE_ERROR;
00086
00087 username = calloc (1, input_len - MD5LEN * 2);
00088 if (username == NULL)
00089 return GSASL_MALLOC_ERROR;
00090
00091 memcpy (username, input, input_len - MD5LEN * 2 - 1);
00092
00093 gsasl_property_set (sctx, GSASL_AUTHID, username);
00094
00095 free (username);
00096
00097 password = gsasl_property_get (sctx, GSASL_PASSWORD);
00098 if (!password)
00099 return GSASL_NO_PASSWORD;
00100
00101
00102
00103 res = gsasl_saslprep (password, 0, &normkey, NULL);
00104 if (res != GSASL_OK)
00105 return res;
00106
00107 cram_md5_digest (challenge, strlen (challenge),
00108 normkey, strlen (normkey), hash);
00109
00110 free (normkey);
00111
00112 if (memcmp (&input[input_len - MD5LEN * 2], hash, 2 * MD5LEN) == 0)
00113 res = GSASL_OK;
00114 else
00115 res = GSASL_AUTHENTICATION_ERROR;
00116
00117 *output_len = 0;
00118 *output = NULL;
00119
00120 return res;
00121 }
00122
00123 void
00124 _gsasl_cram_md5_server_finish (Gsasl_session * sctx, void *mech_data)
00125 {
00126 char *challenge = mech_data;
00127
00128 if (challenge)
00129 free (challenge);
00130 }