summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKozlov Dmitry <dima@server>2010-09-08 16:23:51 +0400
committerKozlov Dmitry <dima@server>2010-09-08 16:23:51 +0400
commit4dcca9422c5c001789b17c3266f3db8e0590568d (patch)
tree4d0f64de5b8c412dbd411978fb71c61a0762855b
parent4c6469a9fd820db713251a645ac2499782f796ed (diff)
downloadaccel-ppp-4dcca9422c5c001789b17c3266f3db8e0590568d.tar.gz
accel-ppp-4dcca9422c5c001789b17c3266f3db8e0590568d.zip
radius: implemented CHAP (md5) authorization
-rw-r--r--accel-pptpd/accel-pptpd.conf1
-rw-r--r--accel-pptpd/auth/auth_chap_md5.c58
-rw-r--r--accel-pptpd/radius/radius.c61
3 files changed, 92 insertions, 28 deletions
diff --git a/accel-pptpd/accel-pptpd.conf b/accel-pptpd/accel-pptpd.conf
index ece04f2f..1e3bc922 100644
--- a/accel-pptpd/accel-pptpd.conf
+++ b/accel-pptpd/accel-pptpd.conf
@@ -1,6 +1,7 @@
[modules]
./libpptp.so
./libauth_pap.so
+./libauth_chap_md5.so
./libradius.so
[core]
diff --git a/accel-pptpd/auth/auth_chap_md5.c b/accel-pptpd/auth/auth_chap_md5.c
index de2f4716..0bcec373 100644
--- a/accel-pptpd/auth/auth_chap_md5.c
+++ b/accel-pptpd/auth/auth_chap_md5.c
@@ -20,6 +20,8 @@
#define CHAP_SUCCESS 3
#define CHAP_FAILURE 4
+#define CHAP_MD5 5
+
#define VALUE_SIZE 16
#define MSG_FAILURE "Authentication failed"
@@ -128,13 +130,13 @@ static int chap_finish(struct ppp_t *ppp, struct auth_data_t *auth)
static int lcp_send_conf_req(struct ppp_t *ppp, struct auth_data_t *d, uint8_t *ptr)
{
- *ptr=5;
+ *ptr = CHAP_MD5;
return 1;
}
static int lcp_recv_conf_req(struct ppp_t *ppp, struct auth_data_t *d, uint8_t *ptr)
{
- if (*ptr==5)
+ if (*ptr == CHAP_MD5)
return LCP_OPT_ACK;
return LCP_OPT_NAK;
}
@@ -198,6 +200,7 @@ static void chap_recv_response(struct chap_auth_data_t *ad, struct chap_hdr_t *h
uint8_t md5[MD5_DIGEST_LENGTH];
char *passwd;
char *name;
+ int r;
struct chap_challenge_t *msg=(struct chap_challenge_t*)hdr;
log_debug("recv [CHAP Response id=%x <", msg->hdr.id);
@@ -221,34 +224,45 @@ static void chap_recv_response(struct chap_auth_data_t *ad, struct chap_hdr_t *h
}
name = strndup(msg->name,ntohs(msg->hdr.len)-sizeof(*msg)+2);
- passwd = pwdb_get_passwd(ad->ppp,name);
- if (!passwd)
- {
- free(name);
- log_debug("chap-md5: user not found\n");
- chap_send_failure(ad);
- return;
- }
- MD5_Init(&md5_ctx);
- MD5_Update(&md5_ctx,&msg->hdr.id,1);
- MD5_Update(&md5_ctx,passwd,strlen(passwd));
- MD5_Update(&md5_ctx,ad->val,VALUE_SIZE);
- MD5_Final(md5,&md5_ctx);
-
- if (memcmp(md5,msg->val,sizeof(md5)))
- {
- log_debug("chap-md5: challenge response mismatch\n");
+ r = pwdb_check(ad->ppp, name, PPP_CHAP, CHAP_MD5, ad->id, ad->val, VALUE_SIZE, msg->val);
+
+ if (r == PWDB_NO_IMPL) {
+ passwd = pwdb_get_passwd(ad->ppp,name);
+ if (!passwd)
+ {
+ free(name);
+ log_debug("chap-md5: user not found\n");
+ chap_send_failure(ad);
+ return;
+ }
+
+ MD5_Init(&md5_ctx);
+ MD5_Update(&md5_ctx,&msg->hdr.id,1);
+ MD5_Update(&md5_ctx,passwd,strlen(passwd));
+ MD5_Update(&md5_ctx,ad->val,VALUE_SIZE);
+ MD5_Final(md5,&md5_ctx);
+
+ if (memcmp(md5,msg->val,sizeof(md5)))
+ {
+ log_debug("chap-md5: challenge response mismatch\n");
+ chap_send_failure(ad);
+ auth_failed(ad->ppp);
+ }else
+ {
+ chap_send_success(ad);
+ auth_successed(ad->ppp);
+ }
+ free(passwd);
+ } else if (r == PWDB_DENIED) {
chap_send_failure(ad);
auth_failed(ad->ppp);
- }else
- {
+ } else {
chap_send_success(ad);
auth_successed(ad->ppp);
}
free(name);
- free(passwd);
}
static struct ppp_auth_handler_t chap=
diff --git a/accel-pptpd/radius/radius.c b/accel-pptpd/radius/radius.c
index a786dea5..89eb9fef 100644
--- a/accel-pptpd/radius/radius.c
+++ b/accel-pptpd/radius/radius.c
@@ -14,6 +14,10 @@
#include "radius.h"
+#define CHAP_MD5 5
+#define MSCHAP_V1 0x80
+#define MSCHAP_V2 0x81
+
int conf_max_try = 3;
int conf_timeout = 3;
char *conf_nas_identifier = "accel-pptpd";
@@ -129,9 +133,54 @@ out:
static int check_chap_md5(struct radius_pd_t *rpd, const char *username, va_list args)
{
- /*int id = va_arg(args, int);
- const uint8_t *challenge = va_arg(args, const uint8_t *);*/
- return PWDB_DENIED;
+ struct rad_req_t *req;
+ int i, r = PWDB_DENIED;
+ char chap_password[17];
+
+ int id = va_arg(args, int);
+ const uint8_t *challenge = va_arg(args, const uint8_t *);
+ int challenge_len = va_arg(args, int);
+ const uint8_t *response = va_arg(args, const uint8_t *);
+
+ chap_password[0] = id;
+ memcpy(chap_password + 1, response, 16);
+
+ req = rad_req_alloc(rpd, CODE_ACCESS_REQUEST, username);
+ if (!req)
+ return PWDB_DENIED;
+
+ req->server_name = conf_auth_server;
+ req->server_port = conf_auth_server_port;
+
+ if (challenge_len == 16)
+ memcpy(req->RA, challenge, 16);
+ else {
+ if (rad_req_add_str(req, "CHAP-Challenge", (char*)challenge, challenge_len, 0))
+ goto out;
+ }
+
+ if (rad_req_add_str(req, "CHAP-Password", chap_password, 17, 0))
+ goto out;
+
+ for(i = 0; i < conf_max_try; i++) {
+ if (rad_req_send(req))
+ goto out;
+
+ rad_req_wait(req, conf_timeout);
+
+ if (req->reply)
+ break;
+ }
+
+ if (req->reply && req->reply->code == CODE_ACCESS_ACCEPT) {
+ proc_attrs(req);
+ r = PWDB_SUCCESS;
+ }
+
+out:
+ rad_req_free(req);
+
+ return r;
}
static int check_mschap_v1(struct radius_pd_t *rpd, const char *username, va_list args)
@@ -171,13 +220,13 @@ static int check(struct pwdb_t *pwdb, struct ppp_t *ppp, const char *username, i
case PPP_CHAP:
chap_type = va_arg(args, int);
switch(chap_type) {
- case 0x05:
+ case CHAP_MD5:
r = check_chap_md5(rpd, username, args);
break;
- case 0x80:
+ case MSCHAP_V1:
r = check_mschap_v1(rpd, username, args);
break;
- case 0x81:
+ case MSCHAP_V2:
r = check_mschap_v2(rpd, username, args);
break;
}