summaryrefslogtreecommitdiff
path: root/accel-pptpd/radius/radius.c
diff options
context:
space:
mode:
Diffstat (limited to 'accel-pptpd/radius/radius.c')
-rw-r--r--accel-pptpd/radius/radius.c194
1 files changed, 25 insertions, 169 deletions
diff --git a/accel-pptpd/radius/radius.c b/accel-pptpd/radius/radius.c
index 89eb9fe..89491b3 100644
--- a/accel-pptpd/radius/radius.c
+++ b/accel-pptpd/radius/radius.c
@@ -5,8 +5,6 @@
#include <unistd.h>
#include <arpa/inet.h>
-#include <openssl/md5.h>
-
#include "log.h"
#include "ppp.h"
#include "pwdb.h"
@@ -35,173 +33,16 @@ char *conf_acct_server_secret;
static struct ppp_notified_t notified;
-static struct radius_pd_t *find_pd(struct ppp_t *ppp);
-
-static void proc_attrs(struct rad_req_t *req)
+void rad_proc_attrs(struct rad_req_t *req)
{
struct rad_req_attr_t *attr;
list_for_each_entry(attr, &req->reply->attrs, entry) {
- if (!strcmp(attr->attr->name, "Framed-IP-Address")) {
+ if (!strcmp(attr->attr->name, "Framed-IP-Address"))
req->rpd->ipaddr = attr->val.ipaddr;
- }
- }
-}
-
-static uint8_t* encrypt_password(const char *passwd, const char *secret, const uint8_t *RA, int *epasswd_len)
-{
- uint8_t *epasswd;
- int i, j, chunk_cnt;
- uint8_t b[16], c[16];
- MD5_CTX ctx;
-
- chunk_cnt = (strlen(passwd) - 1) / 16 + 1;
-
- epasswd = malloc(chunk_cnt * 16);
- if (!epasswd) {
- log_error("radius: out of memory\n");
- return NULL;
- }
-
- memset(epasswd, 0, chunk_cnt * 16);
- memcpy(epasswd, passwd, strlen(passwd));
- memcpy(c, RA, 16);
-
- for (i = 0; i < chunk_cnt; i++) {
- MD5_Init(&ctx);
- MD5_Update(&ctx, secret, strlen(secret));
- MD5_Update(&ctx, c, 16);
- MD5_Final(b, &ctx);
-
- for(j = 0; j < 16; j++)
- epasswd[i * 16 + j] ^= b[j];
-
- memcpy(c, epasswd + i * 16, 16);
- }
-
- *epasswd_len = chunk_cnt * 16;
- return epasswd;
-}
-
-static int check_pap(struct radius_pd_t *rpd, const char *username, va_list args)
-{
- struct rad_req_t *req;
- int i, r = PWDB_DENIED;
- //int id = va_arg(args, int);
- const char *passwd = va_arg(args, const char *);
- uint8_t *epasswd;
- int epasswd_len;
-
- 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;
-
- epasswd = encrypt_password(passwd, conf_auth_server_secret, req->RA, &epasswd_len);
- if (!epasswd)
- goto out;
-
- if (rad_req_add_str(req, "Password", (char*)epasswd, epasswd_len, 0)) {
- free(epasswd);
- goto out;
- }
-
- free(epasswd);
-
- 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_chap_md5(struct radius_pd_t *rpd, const char *username, va_list args)
-{
- 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;
+ else if (!strcmp(attr->attr->name, "Acct-Interim-Interval"))
+ req->rpd->acct_interim_interval = attr->val.integer;
}
-
- 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)
-{
- /*int id = va_arg(args, int);
- const uint8_t *challenge = va_arg(args, const uint8_t *);
- const uint8_t *lm_response = va_arg(args, const uint8_t *);
- const uint8_t *nt_response = va_arg(args, const uint8_t *);
- int flags = va_arg(args, int);*/
- return PWDB_DENIED;
-}
-
-static int check_mschap_v2(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 *);
- const uint8_t *peer_challenge = va_arg(args, const uint8_t *);
- const uint8_t *response = va_arg(args, const uint8_t *);
- int flags = va_arg(args, int);
- uint8_t *authenticator = va_arg(args, uint8_t *);*/
- return PWDB_DENIED;
}
static int check(struct pwdb_t *pwdb, struct ppp_t *ppp, const char *username, int type, va_list _args)
@@ -215,19 +56,19 @@ static int check(struct pwdb_t *pwdb, struct ppp_t *ppp, const char *username, i
switch(type) {
case PPP_PAP:
- r = check_pap(rpd, username, args);
+ r = rad_auth_pap(rpd, username, args);
break;
case PPP_CHAP:
chap_type = va_arg(args, int);
switch(chap_type) {
case CHAP_MD5:
- r = check_chap_md5(rpd, username, args);
+ r = rad_auth_chap_md5(rpd, username, args);
break;
case MSCHAP_V1:
- r = check_mschap_v1(rpd, username, args);
+ r = rad_auth_mschap_v1(rpd, username, args);
break;
case MSCHAP_V2:
- r = check_mschap_v2(rpd, username, args);
+ r = rad_auth_mschap_v2(rpd, username, args);
break;
}
break;
@@ -254,7 +95,7 @@ static int get_ip(struct ppp_t *ppp, in_addr_t *addr, in_addr_t *peer_addr)
return -1;
}
-static void ppp_started(struct ppp_notified_t *n, struct ppp_t *ppp)
+static void ppp_starting(struct ppp_notified_t *n, struct ppp_t *ppp)
{
struct radius_pd_t *pd = malloc(sizeof(*pd));
@@ -264,6 +105,19 @@ static void ppp_started(struct ppp_notified_t *n, struct ppp_t *ppp)
list_add_tail(&pd->pd.entry, &ppp->pd_list);
}
+static void ppp_started(struct ppp_notified_t *n, struct ppp_t *ppp)
+{
+ struct radius_pd_t *rpd = find_pd(ppp);
+
+ if (rad_acct_start(rpd))
+ ppp_terminate(rpd->ppp, 0);
+}
+static void ppp_finishing(struct ppp_notified_t *n, struct ppp_t *ppp)
+{
+ struct radius_pd_t *rpd = find_pd(ppp);
+
+ rad_acct_stop(rpd);
+}
static void ppp_finished(struct ppp_notified_t *n, struct ppp_t *ppp)
{
struct radius_pd_t *rpd = find_pd(ppp);
@@ -272,7 +126,7 @@ static void ppp_finished(struct ppp_notified_t *n, struct ppp_t *ppp)
free(rpd);
}
-static struct radius_pd_t *find_pd(struct ppp_t *ppp)
+struct radius_pd_t *find_pd(struct ppp_t *ppp)
{
struct ppp_pd_t *pd;
struct radius_pd_t *rpd;
@@ -297,7 +151,9 @@ static struct pwdb_t pwdb = {
};
static struct ppp_notified_t notified = {
+ .starting = ppp_starting,
.started = ppp_started,
+ .finishing = ppp_finishing,
.finished = ppp_finished,
};