36 RCSID(
"$Id: 649ed8daad0cf7d1900109628248ec83e2fb9303 $")
38 #include <freeradius-devel/radiusd.h>
39 #include <freeradius-devel/modules.h>
41 #include <freeradius-devel/md5.h>
45 #define VENDORPEC_SM 11406
46 #define SM_AUTHTYPE 101
47 #define SM_CHALLENGE 102
48 #define SM_RESPONSE 103
51 size_t challen,
char const *password)
57 fr_md5_update(&context, (uint8_t
const *) password, strlen(password));
62 static void calc_md5_digest(uint8_t *buffer, uint8_t
const *challenge,
size_t challen,
char const *password)
69 memset(buf, 0x36, 64);
70 for(i=0; i<64 && password[i]; i++) buf[i]^=password[i];
71 memcpy(buf+64, challenge, challen);
74 memset(buf, 0x5c, 64);
75 for(i=0; i<64 && password[i]; i++) buf[i]^=password[i];
82 static void calc_md4_digest(uint8_t *buffer, uint8_t
const *challenge,
size_t challen,
char const *password)
89 memset(buf, 0x36, 64);
90 for(i=0; i<64 && password[i]; i++) buf[i]^=password[i];
91 memcpy(buf+64, challenge, challen);
94 memset(buf, 0x5c, 64);
95 for(i=0; i<64 && password[i]; i++) buf[i]^=password[i];
103 size_t challen,
char const *password)
109 memset(buf, 0, 1024);
110 memset(buf, 0x36, 64);
111 for(i=0; i<64 && password[i]; i++) buf[i]^=password[i];
112 memcpy(buf+64, challenge, challen);
115 memset(buf, 0x5c, 64);
116 for(i=0; i<64 && password[i]; i++) buf[i]^=password[i];
126 VALUE_PAIR *authtype, *challenge, *response, *password;
131 AUTH(
"rlm_cram: Cleartext-Password is required for authentication");
136 AUTH(
"rlm_cram: Required attribute Sandy-Mail-Authtype missed");
141 AUTH(
"rlm_cram: Required attribute Sandy-Mail-Challenge missed");
146 AUTH(
"rlm_cram: Required attribute Sandy-Mail-Response missed");
149 switch (authtype->vp_integer){
151 if(challenge->vp_length < 5 || response->vp_length != 16) {
152 AUTH(
"rlm_cram: invalid MD5 challenge/response length");
155 calc_md5_digest(buffer, challenge->vp_octets, challenge->vp_length, password->vp_strvalue);
156 if(!memcmp(buffer, response->vp_octets, 16))
return RLM_MODULE_OK;
159 if(challenge->vp_length < 5 || response->vp_length != 16) {
160 AUTH(
"rlm_cram: invalid APOP challenge/response length");
163 calc_apop_digest(buffer, challenge->vp_octets, challenge->vp_length, password->vp_strvalue);
164 if(!memcmp(buffer, response->vp_octets, 16))
return RLM_MODULE_OK;
167 if(challenge->vp_length < 5 || response->vp_length != 16) {
168 AUTH(
"rlm_cram: invalid MD4 challenge/response length");
171 calc_md4_digest(buffer, challenge->vp_octets, challenge->vp_length, password->vp_strvalue);
172 if(!memcmp(buffer, response->vp_octets, 16))
return RLM_MODULE_OK;
175 if(challenge->vp_length < 5 || response->vp_length != 20) {
176 AUTH(
"rlm_cram: invalid MD4 challenge/response length");
179 calc_sha1_digest(buffer, challenge->vp_octets, challenge->vp_length, password->vp_strvalue);
180 if(!memcmp(buffer, response->vp_octets, 20))
return RLM_MODULE_OK;
183 AUTH(
"rlm_cram: unsupported Sandy-Mail-Authtype");
void fr_sha1_update(fr_sha1_ctx *context, uint8_t const *data, size_t len)
static void calc_md4_digest(uint8_t *buffer, uint8_t const *challenge, size_t challen, char const *password)
static void calc_apop_digest(uint8_t *buffer, uint8_t const *challenge, size_t challen, char const *password)
The module is OK, continue.
Metadata exported by the module.
#define RLM_TYPE_THREAD_SAFE
Module is threadsafe.
static void calc_md5_digest(uint8_t *buffer, uint8_t const *challenge, size_t challen, char const *password)
void fr_md5_init(FR_MD5_CTX *ctx)
Initialise a new MD5 context.
The module considers the request invalid.
static rlm_rcode_t mod_authenticate(void *instance, REQUEST *request) CC_HINT(nonnull)
void fr_md4_init(FR_MD4_CTX *ctx)
Initialise a new MD4 context.
void fr_sha1_init(fr_sha1_ctx *context)
void fr_md5_update(FR_MD5_CTX *ctx, uint8_t const *in, size_t inlen) CC_BOUNDED(__string__
void fr_md4_update(FR_MD4_CTX *ctx, uint8_t const *in, size_t inlen) CC_BOUNDED(__string__
void void fr_md4_final(uint8_t out[MD4_DIGEST_LENGTH], FR_MD4_CTX *ctx) CC_BOUNDED(__minbytes__
static void calc_sha1_digest(uint8_t *buffer, uint8_t const *challenge, size_t challen, char const *password)
Stores an attribute, a value and various bits of other data.
void fr_sha1_final(uint8_t digest[20], fr_sha1_ctx *context)
0 methods index for authenticate section.
enum rlm_rcodes rlm_rcode_t
Return codes indicating the result of the module call.
uint64_t magic
Used to validate module struct.
VALUE_PAIR * fr_pair_find_by_num(VALUE_PAIR *head, unsigned int vendor, unsigned int attr, int8_t tag)
Find the pair with the matching attribute.
void void fr_md5_final(uint8_t out[MD5_DIGEST_LENGTH], FR_MD5_CTX *ctx) CC_BOUNDED(__minbytes__
static rlm_rcode_t CC_HINT(nonnull)