diff options
Diffstat (limited to 'accel-pptpd/radius')
-rw-r--r-- | accel-pptpd/radius/CMakeLists.txt | 8 | ||||
-rw-r--r-- | accel-pptpd/radius/dict.c | 219 | ||||
-rw-r--r-- | accel-pptpd/radius/dictionary | 240 | ||||
-rw-r--r-- | accel-pptpd/radius/radius.c | 74 | ||||
-rw-r--r-- | accel-pptpd/radius/radius.h | 28 |
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 == ¬ified) { + 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(¬ified); +} + 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 + |