summaryrefslogtreecommitdiff
path: root/accel-pptpd/radius
diff options
context:
space:
mode:
authorKozlov Dmitry <dima@server>2010-09-04 16:20:11 +0400
committerKozlov Dmitry <dima@server>2010-09-04 16:20:11 +0400
commitaf5a96e2d04056b065a36ecbd140a16d0685c7e6 (patch)
treef873b3c5c68a72d2df1785fdd0931bc57c91fd35 /accel-pptpd/radius
parente8aa3a1457295f70f8ccc9cd7f2f9073f01a5e2e (diff)
downloadaccel-ppp-af5a96e2d04056b065a36ecbd140a16d0685c7e6.tar.gz
accel-ppp-af5a96e2d04056b065a36ecbd140a16d0685c7e6.zip
started work on radius module
Diffstat (limited to 'accel-pptpd/radius')
-rw-r--r--accel-pptpd/radius/CMakeLists.txt8
-rw-r--r--accel-pptpd/radius/dict.c219
-rw-r--r--accel-pptpd/radius/dictionary240
-rw-r--r--accel-pptpd/radius/radius.c74
-rw-r--r--accel-pptpd/radius/radius.h28
5 files changed, 569 insertions, 0 deletions
diff --git a/accel-pptpd/radius/CMakeLists.txt b/accel-pptpd/radius/CMakeLists.txt
new file mode 100644
index 0000000..a53491f
--- /dev/null
+++ b/accel-pptpd/radius/CMakeLists.txt
@@ -0,0 +1,8 @@
+SET(target radius)
+SET(sources
+ radius.c
+ dict.c
+)
+
+ADD_LIBRARY(radius SHARED ${sources})
+
diff --git a/accel-pptpd/radius/dict.c b/accel-pptpd/radius/dict.c
new file mode 100644
index 0000000..62a25cf
--- /dev/null
+++ b/accel-pptpd/radius/dict.c
@@ -0,0 +1,219 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+
+#include "list.h"
+#include "radius.h"
+#include "log.h"
+
+
+struct dict_value_t
+{
+ struct list_head entry;
+ rad_value_t val;
+ const char *name;
+};
+
+struct dict_attr_t
+{
+ struct list_head entry;
+ const char *name;
+ int id;
+ int type;
+ rad_value_t val;
+ struct list_head values;
+};
+
+static char *skip_word(char *ptr)
+{
+ for(; *ptr; ptr++)
+ if (*ptr == ' ' || *ptr == '\t' || *ptr == '\n')
+ break;
+ return ptr;
+}
+static char *skip_space(char *ptr)
+{
+ for(; *ptr; ptr++)
+ if (*ptr != ' ' && *ptr != '\t')
+ break;
+ return ptr;
+}
+static int split(char *buf, char **ptr)
+{
+ int i;
+
+ for (i = 0; i < 3; i++) {
+ buf = skip_word(buf);
+ if (!*buf)
+ return -1;
+
+ *buf = 0;
+
+ buf = skip_space(buf + 1);
+ if (!*buf)
+ return -1;
+
+ ptr[i] = buf;
+ }
+
+ buf = skip_word(buf);
+ if (*buf == '\n')
+ *buf = 0;
+ else if (*buf)
+ return -1;
+
+ return 0;
+}
+
+struct dict_attr_t *find_attr(struct rad_dict_t *dict, const char *name)
+{
+ struct dict_attr_t *attr;
+
+ list_for_each_entry(attr, &dict->items, entry)
+ if (!strcmp(attr->name, name))
+ return attr;
+
+ return NULL;
+}
+
+#define BUF_SIZE 1024
+void *rad_load_dict(const char *fname)
+{
+ FILE *f;
+ char *buf, *ptr[3], *endptr;
+ int n = 0;
+ struct rad_dict_t *dict;
+ struct dict_attr_t *attr;
+ struct dict_value_t *val;
+
+ f = fopen(fname, "r");
+ if (!f) {
+ log_error("radius: open dictioanary '%s': %s\n", fname, strerror(errno));
+ return NULL;
+ }
+
+ buf = malloc(BUF_SIZE);
+ if (!buf) {
+ log_error("radius: out of memory\n");
+ fclose(f);
+ return NULL;
+ }
+
+ dict = malloc(sizeof(*dict));
+ if (!dict) {
+ log_error("radius: out of memory\n");
+ fclose(f);
+ free(buf);
+ return NULL;
+ }
+
+ INIT_LIST_HEAD(&dict->items);
+
+ while (fgets(buf, BUF_SIZE, f)) {
+ n++;
+ if (buf[0] == '#' || buf[0] == '\n' || buf[0] == 0)
+ continue;
+ if (split(buf, ptr)) {
+ log_error("radius:%s:%i: syntaxis error\n", fname, n);
+ goto out_err;
+ }
+ if (!strcmp(buf, "ATTRIBUTE")) {
+ attr = malloc(sizeof(*attr));
+ if (!attr) {
+ log_error("radius: out of memory\n");
+ goto out_err;
+ }
+ memset(attr, 0, sizeof(*attr));
+ INIT_LIST_HEAD(&attr->values);
+ list_add_tail(&attr->entry, &dict->items);
+ attr->name = strdup(ptr[0]);
+ attr->id = strtol(ptr[1], &endptr, 10);
+ if (*endptr != 0) {
+ log_error("radius:%s:%i: syntaxis error\n", fname, n);
+ goto out_err;
+ }
+ if (!strcmp(ptr[2], "integer"))
+ attr->type = ATTR_TYPE_INTEGER;
+ else if (!strcmp(ptr[2], "string"))
+ attr->type = ATTR_TYPE_STRING;
+ else if (!strcmp(ptr[2], "date"))
+ attr->type = ATTR_TYPE_DATE;
+ else if (!strcmp(ptr[2], "ipaddr"))
+ attr->type = ATTR_TYPE_IPADDR;
+ else {
+ log_error("radius:%s:%i: unknown attribute type\n", fname, n);
+ goto out_err;
+ }
+ } else if (!strcmp(buf, "VALUE")) {
+ attr = find_attr(dict, ptr[0]);
+ if (!attr) {
+ log_error("radius:%s:%i: unknown attribute\n", fname, n);
+ goto out_err;
+ }
+ val = malloc(sizeof(*val));
+ if (!val) {
+ log_error("radius: out of memory\n");
+ goto out_err;
+ }
+ memset(val, 0, sizeof(*val));
+ list_add_tail(&val->entry, &attr->values);
+ val->name = strdup(ptr[1]);
+ switch (attr->type) {
+ case ATTR_TYPE_INTEGER:
+ val->val.integer = strtol(ptr[2], &endptr, 10);
+ if (*endptr != 0) {
+ log_error("radius:%s:%i: syntaxis error\n", fname, n);
+ goto out_err;
+ }
+ break;
+ case ATTR_TYPE_STRING:
+ val->val.string = strdup(ptr[2]);
+ break;
+ case ATTR_TYPE_DATE:
+ log_warn("radius:%s:%i: VALUE of type 'date' is not implemented yet\n", fname, n);
+ break;
+ case ATTR_TYPE_IPADDR:
+ log_warn("radius:%s:%i: VALUE of type 'ipaddr' is not implemented yet\n", fname, n);
+ break;
+ }
+ } else {
+ log_error("radius:%s:%i: syntaxis error\n");
+ goto out_err;
+ }
+ }
+
+ free(buf);
+ fclose(f);
+
+ return dict;
+
+out_err:
+ rad_free_dict(dict);
+ free(buf);
+ fclose(f);
+ return NULL;
+}
+
+void rad_free_dict(struct rad_dict_t *dict)
+{
+ struct dict_attr_t *attr;
+ struct dict_value_t *val;
+
+ while (!list_empty(&dict->items)) {
+ attr = list_entry(dict->items.next, typeof(*attr), entry);
+ while (!list_empty(&attr->values)) {
+ val = list_entry(attr->values.next, typeof(*val), entry);
+ list_del(&val->entry);
+ free((char*)val->name);
+ if (attr->type == ATTR_TYPE_STRING)
+ free((char*)val->val.string);
+ free(val);
+ }
+ list_del(&attr->entry);
+ free((char*)attr->name);
+ free(attr);
+ }
+ free(dict);
+}
+
diff --git a/accel-pptpd/radius/dictionary b/accel-pptpd/radius/dictionary
new file mode 100644
index 0000000..caebe9d
--- /dev/null
+++ b/accel-pptpd/radius/dictionary
@@ -0,0 +1,240 @@
+#
+# Updated 97/06/13 to livingston-radius-2.01 miquels@cistron.nl
+#
+# This file contains dictionary translations for parsing
+# requests and generating responses. All transactions are
+# composed of Attribute/Value Pairs. The value of each attribute
+# is specified as one of 4 data types. Valid data types are:
+#
+# string - 0-253 octets
+# ipaddr - 4 octets in network byte order
+# integer - 32 bit value in big endian order (high byte first)
+# date - 32 bit value in big endian order - seconds since
+# 00:00:00 GMT, Jan. 1, 1970
+#
+# Enumerated values are stored in the user file with dictionary
+# VALUE translations for easy administration.
+#
+# Example:
+#
+# ATTRIBUTE VALUE
+# --------------- -----
+# Framed-Protocol = PPP
+# 7 = 1 (integer encoding)
+#
+
+#
+# Following are the proper new names. Use these.
+#
+ATTRIBUTE User-Name 1 string
+ATTRIBUTE Password 2 string
+ATTRIBUTE CHAP-Password 3 string
+ATTRIBUTE NAS-IP-Address 4 ipaddr
+ATTRIBUTE NAS-Port-Id 5 integer
+ATTRIBUTE Service-Type 6 integer
+ATTRIBUTE Framed-Protocol 7 integer
+ATTRIBUTE Framed-IP-Address 8 ipaddr
+ATTRIBUTE Framed-IP-Netmask 9 ipaddr
+ATTRIBUTE Framed-Routing 10 integer
+ATTRIBUTE Filter-Id 11 string
+ATTRIBUTE Framed-MTU 12 integer
+ATTRIBUTE Framed-Compression 13 integer
+ATTRIBUTE Login-IP-Host 14 ipaddr
+ATTRIBUTE Login-Service 15 integer
+ATTRIBUTE Login-TCP-Port 16 integer
+ATTRIBUTE Reply-Message 18 string
+ATTRIBUTE Callback-Number 19 string
+ATTRIBUTE Callback-Id 20 string
+ATTRIBUTE Framed-Route 22 string
+ATTRIBUTE Framed-IPX-Network 23 ipaddr
+ATTRIBUTE State 24 string
+ATTRIBUTE Class 25 string
+ATTRIBUTE Vendor-Specific 26 string
+ATTRIBUTE Session-Timeout 27 integer
+ATTRIBUTE Idle-Timeout 28 integer
+ATTRIBUTE Termination-Action 29 integer
+ATTRIBUTE Called-Station-Id 30 string
+ATTRIBUTE Calling-Station-Id 31 string
+ATTRIBUTE NAS-Identifier 32 string
+ATTRIBUTE Proxy-State 33 string
+ATTRIBUTE Login-LAT-Service 34 string
+ATTRIBUTE Login-LAT-Node 35 string
+ATTRIBUTE Login-LAT-Group 36 string
+ATTRIBUTE Framed-AppleTalk-Link 37 integer
+ATTRIBUTE Framed-AppleTalk-Network 38 integer
+ATTRIBUTE Framed-AppleTalk-Zone 39 string
+ATTRIBUTE Acct-Status-Type 40 integer
+ATTRIBUTE Acct-Delay-Time 41 integer
+ATTRIBUTE Acct-Input-Octets 42 integer
+ATTRIBUTE Acct-Output-Octets 43 integer
+ATTRIBUTE Acct-Session-Id 44 string
+ATTRIBUTE Acct-Authentic 45 integer
+ATTRIBUTE Acct-Session-Time 46 integer
+ATTRIBUTE Acct-Input-Packets 47 integer
+ATTRIBUTE Acct-Output-Packets 48 integer
+ATTRIBUTE Acct-Terminate-Cause 49 integer
+ATTRIBUTE Acct-Multi-Session-Id 50 string
+ATTRIBUTE Acct-Link-Count 51 integer
+ATTRIBUTE Event-Timestamp 55 integer
+ATTRIBUTE CHAP-Challenge 60 string
+ATTRIBUTE NAS-Port-Type 61 integer
+ATTRIBUTE Port-Limit 62 integer
+ATTRIBUTE Login-LAT-Port 63 integer
+ATTRIBUTE Connect-Info 77 string
+
+#
+# RFC3162 IPv6 attributes
+#
+ATTRIBUTE NAS-IPv6-Address 95 string
+ATTRIBUTE Framed-Interface-Id 96 string
+ATTRIBUTE Framed-IPv6-Prefix 97 string
+ATTRIBUTE Login-IPv6-Host 98 string
+ATTRIBUTE Framed-IPv6-Route 99 string
+ATTRIBUTE Framed-IPv6-Pool 100 string
+
+#
+# Experimental Non Protocol Attributes used by Cistron-Radiusd
+#
+ATTRIBUTE Huntgroup-Name 221 string
+ATTRIBUTE User-Category 1029 string
+ATTRIBUTE Group-Name 1030 string
+ATTRIBUTE Simultaneous-Use 1034 integer
+ATTRIBUTE Strip-User-Name 1035 integer
+ATTRIBUTE Fall-Through 1036 integer
+ATTRIBUTE Add-Port-To-IP-Address 1037 integer
+ATTRIBUTE Exec-Program 1038 string
+ATTRIBUTE Exec-Program-Wait 1039 string
+ATTRIBUTE Hint 1040 string
+
+#
+# Non-Protocol Attributes
+# These attributes are used internally by the server
+#
+ATTRIBUTE Expiration 21 date
+ATTRIBUTE Auth-Type 1000 integer
+ATTRIBUTE Menu 1001 string
+ATTRIBUTE Termination-Menu 1002 string
+ATTRIBUTE Prefix 1003 string
+ATTRIBUTE Suffix 1004 string
+ATTRIBUTE Group 1005 string
+ATTRIBUTE Crypt-Password 1006 string
+ATTRIBUTE Connect-Rate 1007 integer
+
+#
+# Integer Translations
+#
+
+# User Types
+
+VALUE Service-Type Login-User 1
+VALUE Service-Type Framed-User 2
+VALUE Service-Type Callback-Login-User 3
+VALUE Service-Type Callback-Framed-User 4
+VALUE Service-Type Outbound-User 5
+VALUE Service-Type Administrative-User 6
+VALUE Service-Type NAS-Prompt-User 7
+
+# Framed Protocols
+
+VALUE Framed-Protocol PPP 1
+VALUE Framed-Protocol SLIP 2
+
+# Framed Routing Values
+
+VALUE Framed-Routing None 0
+VALUE Framed-Routing Broadcast 1
+VALUE Framed-Routing Listen 2
+VALUE Framed-Routing Broadcast-Listen 3
+
+# Framed Compression Types
+
+VALUE Framed-Compression None 0
+VALUE Framed-Compression Van-Jacobson-TCP-IP 1
+
+# Login Services
+
+VALUE Login-Service Telnet 0
+VALUE Login-Service Rlogin 1
+VALUE Login-Service TCP-Clear 2
+VALUE Login-Service PortMaster 3
+
+# Status Types
+
+VALUE Acct-Status-Type Start 1
+VALUE Acct-Status-Type Stop 2
+VALUE Acct-Status-Type Alive 3
+VALUE Acct-Status-Type Accounting-On 7
+VALUE Acct-Status-Type Accounting-Off 8
+
+# Authentication Types
+
+VALUE Acct-Authentic RADIUS 1
+VALUE Acct-Authentic Local 2
+VALUE Acct-Authentic PowerLink128 100
+
+# Termination Options
+
+VALUE Termination-Action Default 0
+VALUE Termination-Action RADIUS-Request 1
+
+# NAS Port Types, available in 3.3.1 and later
+
+VALUE NAS-Port-Type Async 0
+VALUE NAS-Port-Type Sync 1
+VALUE NAS-Port-Type ISDN 2
+VALUE NAS-Port-Type ISDN-V120 3
+VALUE NAS-Port-Type ISDN-V110 4
+
+# Acct Terminate Causes, available in 3.3.2 and later
+
+VALUE Acct-Terminate-Cause User-Request 1
+VALUE Acct-Terminate-Cause Lost-Carrier 2
+VALUE Acct-Terminate-Cause Lost-Service 3
+VALUE Acct-Terminate-Cause Idle-Timeout 4
+VALUE Acct-Terminate-Cause Session-Timeout 5
+VALUE Acct-Terminate-Cause Admin-Reset 6
+VALUE Acct-Terminate-Cause Admin-Reboot 7
+VALUE Acct-Terminate-Cause Port-Error 8
+VALUE Acct-Terminate-Cause NAS-Error 9
+VALUE Acct-Terminate-Cause NAS-Request 10
+VALUE Acct-Terminate-Cause NAS-Reboot 11
+VALUE Acct-Terminate-Cause Port-Unneeded 12
+VALUE Acct-Terminate-Cause Port-Preempted 13
+VALUE Acct-Terminate-Cause Port-Suspended 14
+VALUE Acct-Terminate-Cause Service-Unavailable 15
+VALUE Acct-Terminate-Cause Callback 16
+VALUE Acct-Terminate-Cause User-Error 17
+VALUE Acct-Terminate-Cause Host-Request 18
+
+#
+# Non-Protocol Integer Translations
+#
+
+VALUE Auth-Type Local 0
+VALUE Auth-Type System 1
+VALUE Auth-Type SecurID 2
+VALUE Auth-Type Crypt-Local 3
+VALUE Auth-Type Reject 4
+
+#
+# Cistron extensions
+#
+VALUE Auth-Type Pam 253
+VALUE Auth-Type Accept 254
+
+#
+# Experimental Non-Protocol Integer Translations for Cistron-Radiusd
+#
+VALUE Fall-Through No 0
+VALUE Fall-Through Yes 1
+VALUE Add-Port-To-IP-Address No 0
+VALUE Add-Port-To-IP-Address Yes 1
+
+#
+# Configuration Values
+# uncomment these two lines to turn account expiration on
+#
+
+#VALUE Server-Config Password-Expiration 30
+#VALUE Server-Config Password-Warning 5
+
diff --git a/accel-pptpd/radius/radius.c b/accel-pptpd/radius/radius.c
new file mode 100644
index 0000000..10fef65
--- /dev/null
+++ b/accel-pptpd/radius/radius.c
@@ -0,0 +1,74 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "ppp.h"
+#include "pwdb.h"
+#include "radius.h"
+
+struct radius_pd_t
+{
+ struct ppp_pd_t pd;
+ struct ppp_t *ppp;
+};
+
+static struct ppp_notified_t notified;
+
+int cleartext_check(struct pwdb_t *pwdb, struct ppp_t *ppp, const char *username, const char *password)
+{
+ return PWDB_NO_IMPL;
+}
+int encrypted_check(struct pwdb_t *pwdb, struct ppp_t *ppp, const char *username, int type, va_list args)
+{
+ return PWDB_NO_IMPL;
+}
+
+
+static void ppp_started(struct ppp_notified_t *n, struct ppp_t *ppp)
+{
+ struct radius_pd_t *pd = malloc(sizeof(*pd));
+
+ memset(pd, 0, sizeof(*pd));
+ pd->pd.key = n;
+ pd->ppp = ppp;
+ list_add_tail(&pd->pd.entry, &ppp->pd_list);
+}
+
+static void ppp_finished(struct ppp_notified_t *n, struct ppp_t *ppp)
+{
+ struct ppp_pd_t *pd;
+ struct radius_pd_t *rpd;
+
+ list_for_each_entry(pd, &ppp->pd_list, entry) {
+ if (pd->key == &notified) {
+ rpd = container_of(pd, typeof(*rpd), pd);
+ list_del(&pd->entry);
+ free(rpd);
+ return;
+ }
+ }
+}
+
+struct pwdb_t pwdb = {
+ .cleartext_check = cleartext_check,
+ .encrypted_check = encrypted_check,
+};
+
+static struct ppp_notified_t notified = {
+ .started = ppp_started,
+ .finished = ppp_finished,
+};
+
+static void __init radius_init(void)
+{
+ char *dict = conf_get_opt("radius", "dictionary");
+ if (!dict) {
+ fprintf(stderr, "radius: dictionary not specified\n");
+ _exit(EXIT_FAILURE);
+ }
+ if (!rad_load_dict(dict))
+ _exit(EXIT_FAILURE);
+ ppp_register_notified(&notified);
+}
+
diff --git a/accel-pptpd/radius/radius.h b/accel-pptpd/radius/radius.h
new file mode 100644
index 0000000..aac1cd0
--- /dev/null
+++ b/accel-pptpd/radius/radius.h
@@ -0,0 +1,28 @@
+#ifndef __RADIUS_H
+#define __RADIUS_H
+
+#include <netinet/in.h>
+
+#define ATTR_TYPE_INTEGER 0
+#define ATTR_TYPE_STRING 1
+#define ATTR_TYPE_DATE 2
+#define ATTR_TYPE_IPADDR 3
+
+typedef union
+{
+ int integer;
+ const char *string;
+ time_t date;
+ in_addr_t ipaddr;
+} rad_value_t;
+
+struct rad_dict_t
+{
+ struct list_head items;
+};
+
+void *rad_load_dict(const char *fname);
+void rad_free_dict(struct rad_dict_t *dict);
+
+#endif
+