summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--accel-pptpd/cli/cli.c4
-rw-r--r--accel-pptpd/cli/show_sessions.c2
-rw-r--r--accel-pptpd/cli/tcp.c4
-rw-r--r--accel-pptpd/cli/telnet.c12
-rw-r--r--accel-pptpd/ctrl/pppoe/CMakeLists.txt7
-rw-r--r--accel-pptpd/ctrl/pppoe/pppoe.c61
-rw-r--r--accel-pptpd/ctrl/pppoe/pppoe.h6
-rw-r--r--accel-pptpd/ctrl/pppoe/tr101.c97
-rw-r--r--accel-pptpd/extra/chap-secrets.c41
-rw-r--r--accel-pptpd/extra/pppd_compat.c3
-rw-r--r--accel-pptpd/ppp/ipcp_opt_ipaddr.c6
-rw-r--r--accel-pptpd/radius/acct.c40
-rw-r--r--accel-pptpd/radius/auth.c54
-rw-r--r--accel-pptpd/radius/dict/dictionary1
-rw-r--r--accel-pptpd/radius/dm_coa.c2
-rw-r--r--accel-pptpd/radius/packet.c208
-rw-r--r--accel-pptpd/radius/radius.c12
-rw-r--r--accel-pptpd/radius/radius.h32
-rw-r--r--accel-pptpd/radius/radius_p.h2
-rw-r--r--accel-pptpd/radius/req.c58
-rw-r--r--accel-pptpd/triton/loader.c2
-rw-r--r--accel-pptpd/triton/md.c4
-rw-r--r--accel-pptpd/triton/timer.c4
-rw-r--r--rfc/TR-101.pdfbin0 -> 970534 bytes
24 files changed, 434 insertions, 228 deletions
diff --git a/accel-pptpd/cli/cli.c b/accel-pptpd/cli/cli.c
index 048809c1..ef168ded 100644
--- a/accel-pptpd/cli/cli.c
+++ b/accel-pptpd/cli/cli.c
@@ -181,7 +181,7 @@ int cli_process_cmd(struct cli_client_t *cln)
case CLI_CMD_EXIT:
cln->disconnect(cln);
case CLI_CMD_FAILED:
- return -1;
+ return 0;
case CLI_CMD_SYNTAX:
cli_send(cln, MSG_SYNTAX_ERROR);
return 0;
@@ -206,7 +206,7 @@ static void load_config(void)
_free(conf_cli_passwd);
opt = conf_get_opt("cli", "password");
if (opt)
- conf_cli_passwd = _strdup(conf_cli_passwd);
+ conf_cli_passwd = _strdup(opt);
else
conf_cli_passwd = NULL;
diff --git a/accel-pptpd/cli/show_sessions.c b/accel-pptpd/cli/show_sessions.c
index 5bdf64fe..f8fb3d00 100644
--- a/accel-pptpd/cli/show_sessions.c
+++ b/accel-pptpd/cli/show_sessions.c
@@ -14,7 +14,7 @@
#include "memdebug.h"
#define CELL_SIZE 128
-#define DEF_COLUMNS "ifname,username,ip,type,state,uptime"
+#define DEF_COLUMNS "ifname,username,calling-sid,ip,type,state,uptime"
struct column_t
{
diff --git a/accel-pptpd/cli/tcp.c b/accel-pptpd/cli/tcp.c
index 435752aa..260225f1 100644
--- a/accel-pptpd/cli/tcp.c
+++ b/accel-pptpd/cli/tcp.c
@@ -73,7 +73,7 @@ static void disconnect(struct tcp_client_t *cln)
static void cli_client_disconnect(struct cli_client_t *tcln)
{
struct tcp_client_t *cln = container_of(tcln, typeof(*cln), cli_client);
- disconnect(cln);
+ cln->disconnect = 1;
}
static void queue_buffer(struct tcp_client_t *cln, struct buffer_t *b)
@@ -184,7 +184,7 @@ static int cln_read(struct triton_md_handler_t *h)
drop:
disconnect(cln);
- return 0;
+ return -1;
}
static int cln_write(struct triton_md_handler_t *h)
diff --git a/accel-pptpd/cli/telnet.c b/accel-pptpd/cli/telnet.c
index a91418a9..0ea19fb1 100644
--- a/accel-pptpd/cli/telnet.c
+++ b/accel-pptpd/cli/telnet.c
@@ -120,7 +120,7 @@ static void disconnect(struct telnet_client_t *cln)
static void cli_client_disconnect(struct cli_client_t *tcln)
{
struct telnet_client_t *cln = container_of(tcln, typeof(*cln), cli_client);
- disconnect(cln);
+ cln->disconnect = 1;
}
static void queue_buffer(struct telnet_client_t *cln, struct buffer_t *b)
@@ -286,7 +286,7 @@ static int telnet_input_char(struct telnet_client_t *cln, uint8_t c)
if (strcmp((char *)cln->cmdline, conf_cli_passwd)) {
if (telnet_send(cln, MSG_AUTH_FAILED, sizeof(MSG_AUTH_FAILED)))
return -1;
- disconnect(cln);
+ cln->disconnect = 1;
return -1;
}
cln->auth = 1;
@@ -430,7 +430,7 @@ static int telnet_input_char(struct telnet_client_t *cln, uint8_t c)
}
return 0;
case 3:
- disconnect(cln);
+ cln->disconnect = 1;
return -1;
}
@@ -473,7 +473,7 @@ static int cln_read(struct triton_md_handler_t *h)
n = read(h->fd, recv_buf, RECV_BUF_SIZE);
if (n == 0) {
disconnect(cln);
- return 0;
+ return -1;
}
if (n < 0) {
if (errno != EAGAIN)
@@ -484,11 +484,11 @@ static int cln_read(struct triton_md_handler_t *h)
print_buf(cln->recv_buf + cln->recv_pos, n);*/
for (i = 0; i < n; i++) {
if (telnet_input_char(cln, recv_buf[i]))
- return -1;
+ break;
}
if (cln->disconnect) {
disconnect(cln);
- return 0;
+ return -1;
}
}
diff --git a/accel-pptpd/ctrl/pppoe/CMakeLists.txt b/accel-pptpd/ctrl/pppoe/CMakeLists.txt
index 5f5c5e4d..f047936e 100644
--- a/accel-pptpd/ctrl/pppoe/CMakeLists.txt
+++ b/accel-pptpd/ctrl/pppoe/CMakeLists.txt
@@ -1,12 +1,17 @@
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR})
-ADD_LIBRARY(pppoe SHARED
+SET(sources
pppoe.c
mac_filter.c
dpado.c
cli.c
)
+IF (RADIUS)
+SET(sources ${sources} tr101.c)
+ENDIF(RADIUS)
+
+ADD_LIBRARY(pppoe SHARED ${sources})
TARGET_LINK_LIBRARIES(pppoe crypto)
INSTALL(TARGETS pppoe LIBRARY DESTINATION lib/accel-pptp)
diff --git a/accel-pptpd/ctrl/pppoe/pppoe.c b/accel-pptpd/ctrl/pppoe/pppoe.c
index 2ec8bc26..3e6b0bf2 100644
--- a/accel-pptpd/ctrl/pppoe/pppoe.c
+++ b/accel-pptpd/ctrl/pppoe/pppoe.c
@@ -22,6 +22,10 @@
#include "mempool.h"
#include "cli.h"
+#ifdef RADIUS
+#include "radius.h"
+#endif
+
#include "pppoe.h"
#include "memdebug.h"
@@ -39,10 +43,14 @@ struct pppoe_conn_t
struct pppoe_tag *relay_sid;
struct pppoe_tag *host_uniq;
struct pppoe_tag *service_name;
+ struct pppoe_tag *tr101;
uint8_t cookie[COOKIE_LENGTH];
struct ppp_ctrl_t ctrl;
struct ppp_t ppp;
+#ifdef RADIUS
+ struct rad_plugin_t radius;
+#endif
};
struct delayed_pado_t
@@ -146,7 +154,29 @@ static void pppoe_conn_close(struct triton_context_t *ctx)
disconnect(conn);
}
-static struct pppoe_conn_t *allocate_channel(struct pppoe_serv_t *serv, const uint8_t *addr, const struct pppoe_tag *host_uniq, const struct pppoe_tag *relay_sid, const struct pppoe_tag *service_name, const uint8_t *cookie)
+#ifdef RADIUS
+static int pppoe_rad_send_access_request(struct rad_plugin_t *rad, struct rad_packet_t *pack)
+{
+ struct pppoe_conn_t *conn = container_of(rad, typeof(*conn), radius);
+
+ if (conn->tr101)
+ return tr101_send_access_request(conn->tr101, pack);
+
+ return 0;
+}
+
+static int pppoe_rad_send_accounting_request(struct rad_plugin_t *rad, struct rad_packet_t *pack)
+{
+ struct pppoe_conn_t *conn = container_of(rad, typeof(*conn), radius);
+
+ if (conn->tr101)
+ return tr101_send_accounting_request(conn->tr101, pack);
+
+ return 0;
+}
+#endif
+
+static struct pppoe_conn_t *allocate_channel(struct pppoe_serv_t *serv, const uint8_t *addr, const struct pppoe_tag *host_uniq, const struct pppoe_tag *relay_sid, const struct pppoe_tag *service_name, const struct pppoe_tag *tr101, const uint8_t *cookie)
{
struct pppoe_conn_t *conn;
int sid;
@@ -193,6 +223,11 @@ static struct pppoe_conn_t *allocate_channel(struct pppoe_serv_t *serv, const ui
memcpy(conn->relay_sid, relay_sid, sizeof(*relay_sid) + ntohs(relay_sid->tag_len));
}
+ if (tr101) {
+ conn->tr101 = _malloc(sizeof(*tr101) + ntohs(tr101->tag_len));
+ memcpy(conn->tr101, tr101, sizeof(*tr101) + ntohs(tr101->tag_len));
+ }
+
conn->service_name = _malloc(sizeof(*service_name) + ntohs(service_name->tag_len));
memcpy(conn->service_name, service_name, sizeof(*service_name) + ntohs(service_name->tag_len));
@@ -268,6 +303,14 @@ static void connect_channel(struct pppoe_conn_t *conn)
if (establish_ppp(&conn->ppp))
goto out_err_close;
+#ifdef RADIUS
+ if (conn->tr101) {
+ conn->radius.send_access_request = pppoe_rad_send_access_request;
+ conn->radius.send_accounting_request = pppoe_rad_send_accounting_request;
+ rad_register_plugin(&conn->ppp, &conn->radius);
+ }
+#endif
+
conn->ppp_started = 1;
dpado_check_next(__sync_add_and_fetch(&stat_active, 1));
@@ -367,7 +410,10 @@ static void print_packet(uint8_t *pack)
log_info2(">");
break;
case TAG_VENDOR_SPECIFIC:
- log_info2(" <Vendor-Specific>");
+ if (ntohs(tag->tag_len) < 4)
+ log_info2(" <Vendor-Specific invalid>");
+ else
+ log_info2(" <Vendor-Specific %x>", ntohl(*(uint32_t *)tag->tag_data));
break;
case TAG_RELAY_SESSION_ID:
log_info2(" <Relay-Session-Id");
@@ -740,8 +786,10 @@ static void pppoe_recv_PADR(struct pppoe_serv_t *serv, uint8_t *pack, int size)
struct pppoe_tag *relay_sid_tag = NULL;
struct pppoe_tag *ac_cookie_tag = NULL;
struct pppoe_tag *service_name_tag = NULL;
+ struct pppoe_tag *tr101_tag = NULL;
int n, service_match = 0;
struct pppoe_conn_t *conn;
+ int vendor_id;
if (ppp_shutdown)
return;
@@ -791,6 +839,13 @@ static void pppoe_recv_PADR(struct pppoe_serv_t *serv, uint8_t *pack, int size)
case TAG_RELAY_SESSION_ID:
relay_sid_tag = tag;
break;
+ case TAG_VENDOR_SPECIFIC:
+ if (ntohs(tag->tag_len) < 4)
+ continue;
+ vendor_id = ntohl(*(uint32_t *)tag->tag_data);
+ if (vendor_id == VENDOR_ADSL_FORUM)
+ tr101_tag = tag;
+ break;
}
}
@@ -828,7 +883,7 @@ static void pppoe_recv_PADR(struct pppoe_serv_t *serv, uint8_t *pack, int size)
if (conn)
return;
- conn = allocate_channel(serv, ethhdr->h_source, host_uniq_tag, relay_sid_tag, service_name_tag, (uint8_t *)ac_cookie_tag->tag_data);
+ conn = allocate_channel(serv, ethhdr->h_source, host_uniq_tag, relay_sid_tag, service_name_tag, tr101_tag, (uint8_t *)ac_cookie_tag->tag_data);
if (!conn)
pppoe_send_err(serv, ethhdr->h_source, host_uniq_tag, relay_sid_tag, CODE_PADS, TAG_AC_SYSTEM_ERROR);
else {
diff --git a/accel-pptpd/ctrl/pppoe/pppoe.h b/accel-pptpd/ctrl/pppoe/pppoe.h
index 323715d8..b0e665d7 100644
--- a/accel-pptpd/ctrl/pppoe/pppoe.h
+++ b/accel-pptpd/ctrl/pppoe/pppoe.h
@@ -41,6 +41,8 @@
#define MAX_PPPOE_PAYLOAD (ETH_DATA_LEN - PPPOE_OVERHEAD)
#define MAX_PPPOE_MTU (MAX_PPPOE_PAYLOAD - 2)
+#define VENDOR_ADSL_FORUM 0xde9
+
#define MAX_SID 65534
#define SECRET_LENGTH 16
#define COOKIE_LENGTH 24
@@ -102,5 +104,9 @@ void dpado_check_next(int conn_cnt);
void dpado_check_prev(int conn_cnt);
int dpado_parse(const char *str);
+struct rad_packet_t;
+int tr101_send_access_request(struct pppoe_tag *tr101, struct rad_packet_t *pack);
+int tr101_send_accounting_request(struct pppoe_tag *tr101, struct rad_packet_t *pack);
+
#endif
diff --git a/accel-pptpd/ctrl/pppoe/tr101.c b/accel-pptpd/ctrl/pppoe/tr101.c
new file mode 100644
index 00000000..cfb0fbcf
--- /dev/null
+++ b/accel-pptpd/ctrl/pppoe/tr101.c
@@ -0,0 +1,97 @@
+#include <string.h>
+#include <stdlib.h>
+#include <netinet/in.h>
+#include <net/ethernet.h>
+
+#include "triton.h"
+#include "ppp.h"
+#include "log.h"
+#include "radius.h"
+#include "memdebug.h"
+
+#include "pppoe.h"
+
+#define OPT_CIRCUIT_ID 0x01
+#define OPT_REMOTE_AGENT_ID 0x02
+#define OPT_ACTUAL_DATA_RATE_UP 0x81
+#define OPT_ACTUAL_DATA_RATE_DOWN 0x82
+#define OPT_MIN_DATA_RATE_UP 0x83
+#define OPT_MAX_DATA_RATE_DOWN 0x84
+
+static int tr101_send_request(struct pppoe_tag *tr101, struct rad_packet_t *pack, int type)
+{
+ uint8_t *ptr = (uint8_t *)tr101->tag_data + 4;
+ uint8_t *endptr = (uint8_t *)tr101->tag_data + ntohs(tr101->tag_len);
+ int id, len;
+ char str[64];
+
+ while (ptr < endptr) {
+ if (ptr + 2 > endptr)
+ goto inval;
+ id = *ptr++;
+ len = *ptr++;
+ if (ptr + len - 2 > endptr)
+ goto inval;
+ if (type && id > 0x80)
+ continue;
+ switch (id) {
+ case OPT_CIRCUIT_ID:
+ if (len - 2 > 63)
+ goto inval;
+ memcpy(str, ptr, len);
+ str[len - 2] = 0;
+ if (rad_packet_add_str(pack, "ADSL-Forum", "ADSL-Agent-Circuit-Id", str))
+ return -1;
+ break;
+ case OPT_REMOTE_AGENT_ID:
+ if (len - 2 > 63)
+ goto inval;
+ memcpy(str, ptr, len);
+ str[len - 2] = 0;
+ if (rad_packet_add_str(pack, "ADSL-Forum", "ADSL-Agent-Remote-Id", str))
+ return -1;
+ break;
+ case OPT_ACTUAL_DATA_RATE_UP:
+ if (len != 6)
+ goto inval;
+ if (rad_packet_add_int(pack, "ADSL-Forum", "Actual-Data-Rate-Upstream", ntohl(*(uint32_t *)ptr)))
+ return -1;
+ break;
+ case OPT_ACTUAL_DATA_RATE_DOWN:
+ if (len != 6)
+ goto inval;
+ if (rad_packet_add_int(pack, "ADSL-Forum", "Actual-Data-Rate-Downstream", ntohl(*(uint32_t *)ptr)))
+ return -1;
+ break;
+ case OPT_MIN_DATA_RATE_UP:
+ if (len != 6)
+ goto inval;
+ if (rad_packet_add_int(pack, "ADSL-Forum", "Minimum-Data-Rate-Upstream", ntohl(*(uint32_t *)ptr)))
+ return -1;
+ break;
+ case OPT_MAX_DATA_RATE_DOWN:
+ if (len != 6)
+ goto inval;
+ if (rad_packet_add_int(pack, "ADSL-Forum", "Maximum-Data-Rate-Upstream", ntohl(*(uint32_t *)ptr)))
+ return -1;
+ break;
+ }
+ ptr += len - 2;
+ }
+
+ return 0;
+
+inval:
+ log_ppp_warn("pppoe:tr101: invalid tag received\n");
+ return -1;
+}
+
+int tr101_send_access_request(struct pppoe_tag *tr101, struct rad_packet_t *pack)
+{
+ return tr101_send_request(tr101, pack, 1);
+}
+
+int tr101_send_accounting_request(struct pppoe_tag *tr101, struct rad_packet_t *pack)
+{
+ return tr101_send_request(tr101, pack, 0);
+}
diff --git a/accel-pptpd/extra/chap-secrets.c b/accel-pptpd/extra/chap-secrets.c
index 8983f90e..35503473 100644
--- a/accel-pptpd/extra/chap-secrets.c
+++ b/accel-pptpd/extra/chap-secrets.c
@@ -30,9 +30,28 @@ struct cs_pd_t
static char *skip_word(char *ptr)
{
- for(; *ptr; ptr++)
- if (*ptr == ' ' || *ptr == '\t' || *ptr == '\n')
+ char quote = 0;
+
+ if (*ptr == '\'' || *ptr == '"') {
+ quote = *ptr;
+ ptr++;
+ }
+
+ for(; *ptr; ptr++) {
+ if (quote) {
+ if (*ptr == '\n')
+ break;
+ if (*ptr == '\\' && ptr[1] && ptr[1] != '\n') {
+ memmove(ptr, ptr + 1, strlen(ptr));
+ continue;
+ }
+ if (*ptr == quote) {
+ *ptr = ' ';
+ break;
+ }
+ } else if (*ptr == ' ' || *ptr == '\t' || *ptr == '\n')
break;
+ }
return ptr;
}
static char *skip_space(char *ptr)
@@ -50,14 +69,17 @@ static int split(char *buf, char **ptr)
buf = skip_word(buf);
if (!*buf)
return i;
-
+
*buf = 0;
buf = skip_space(buf + 1);
if (!*buf)
return i;
- ptr[i] = buf;
+ if (*buf == '"' || *buf == '\'')
+ ptr[i] = buf + 1;
+ else
+ ptr[i] = buf;
}
buf = skip_word(buf);
@@ -95,11 +117,18 @@ static struct cs_pd_t *create_pd(struct ppp_t *ppp, const char *username)
}
while (fgets(buf, 4096, f)) {
+ if (buf[0] == '#')
+ continue;
n = split(buf, ptr);
if (n < 3)
continue;
- if (!strcmp(buf, username))
- goto found;
+ if (*buf == '\'' || *buf == '"') {
+ if (!strcmp(buf + 1, username))
+ goto found;
+ } else {
+ if (!strcmp(buf, username))
+ goto found;
+ }
}
out:
diff --git a/accel-pptpd/extra/pppd_compat.c b/accel-pptpd/extra/pppd_compat.c
index f6e85b02..f897dd68 100644
--- a/accel-pptpd/extra/pppd_compat.c
+++ b/accel-pptpd/extra/pppd_compat.c
@@ -476,8 +476,7 @@ static void fill_env(char **env, struct pppd_compat_pd_t *pd)
{
snprintf(env[0], 64, "PEERNAME=%s", pd->ppp->username);
- if (pd->ppp->stop_time) {
-
+ if (pd->ppp->stop_time && env[1]) {
snprintf(env[1], 24, "CONNECT_TIME=%lu", pd->ppp->stop_time - pd->ppp->start_time);
snprintf(env[2], 24, "BYTES_SENT=%u", pd->bytes_sent);
snprintf(env[3], 24, "BYTES_RCVD=%u", pd->bytes_rcvd);
diff --git a/accel-pptpd/ppp/ipcp_opt_ipaddr.c b/accel-pptpd/ppp/ipcp_opt_ipaddr.c
index 05120eb4..334f4256 100644
--- a/accel-pptpd/ppp/ipcp_opt_ipaddr.c
+++ b/accel-pptpd/ppp/ipcp_opt_ipaddr.c
@@ -63,14 +63,14 @@ static void ipaddr_free(struct ppp_ipcp_t *ipcp, struct ipcp_option_t *opt)
_free(ipaddr_opt);
}
-static int check_exists(in_addr_t addr)
+static int check_exists(struct ppp_t *self_ppp, in_addr_t addr)
{
struct ppp_t *ppp;
int r = 0;
pthread_rwlock_rdlock(&ppp_lock);
list_for_each_entry(ppp, &ppp_list, entry) {
- if (!ppp->terminating && ppp->peer_ipaddr == addr) {
+ if (!ppp->terminating && ppp->peer_ipaddr == addr && ppp != self_ppp) {
log_ppp_warn("ppp:ipcp: requested IP already assigned to %s\n", ppp->ifname);
r = 1;
break;
@@ -103,7 +103,7 @@ static int ipaddr_send_conf_req(struct ppp_ipcp_t *ipcp, struct ipcp_option_t *o
return -1;
}
- if (conf_check_exists && check_exists(ipaddr_opt->ip->peer_addr))
+ if (conf_check_exists && check_exists(ipcp->ppp, ipaddr_opt->ip->peer_addr))
return -1;
opt32->hdr.id=CI_ADDR;
diff --git a/accel-pptpd/radius/acct.c b/accel-pptpd/radius/acct.c
index 86dd0cd0..f2c0ebb4 100644
--- a/accel-pptpd/radius/acct.c
+++ b/accel-pptpd/radius/acct.c
@@ -58,13 +58,13 @@ static void req_set_stat(struct rad_req_t *req, struct ppp_t *ppp)
req->rpd->acct_output_gigawords++;
req->rpd->acct_output_octets = ifreq.stats.p.ppp_obytes;
- rad_packet_change_int(req->pack, "Acct-Input-Octets", ifreq.stats.p.ppp_ibytes);
- rad_packet_change_int(req->pack, "Acct-Output-Octets", ifreq.stats.p.ppp_obytes);
- rad_packet_change_int(req->pack, "Acct-Input-Packets", ifreq.stats.p.ppp_ipackets);
- rad_packet_change_int(req->pack, "Acct-Output-Packets", ifreq.stats.p.ppp_opackets);
- rad_packet_change_int(req->pack, "Acct-Input-Gigawords", req->rpd->acct_input_gigawords);
- rad_packet_change_int(req->pack, "Acct-Output-Gigawords", req->rpd->acct_output_gigawords);
- rad_packet_change_int(req->pack, "Acct-Session-Time", stop_time - ppp->start_time);
+ rad_packet_change_int(req->pack, NULL, "Acct-Input-Octets", ifreq.stats.p.ppp_ibytes);
+ rad_packet_change_int(req->pack, NULL, "Acct-Output-Octets", ifreq.stats.p.ppp_obytes);
+ rad_packet_change_int(req->pack, NULL, "Acct-Input-Packets", ifreq.stats.p.ppp_ipackets);
+ rad_packet_change_int(req->pack, NULL, "Acct-Output-Packets", ifreq.stats.p.ppp_opackets);
+ rad_packet_change_int(req->pack, NULL, "Acct-Input-Gigawords", req->rpd->acct_input_gigawords);
+ rad_packet_change_int(req->pack, NULL, "Acct-Output-Gigawords", req->rpd->acct_output_gigawords);
+ rad_packet_change_int(req->pack, NULL, "Acct-Session-Time", stop_time - ppp->start_time);
}
static int rad_acct_read(struct triton_md_handler_t *h)
@@ -135,7 +135,7 @@ static void rad_acct_timeout(struct triton_timer_t *t)
req->pack->id++;
- rad_packet_change_int(req->pack, "Acct-Delay-Time", dt);
+ rad_packet_change_int(req->pack, NULL, "Acct-Delay-Time", dt);
req_set_RA(req, conf_acct_secret);
rad_req_send(req, conf_interim_verbose);
}
@@ -154,8 +154,8 @@ static void rad_acct_interim_update(struct triton_timer_t *t)
time(&rpd->acct_timestamp);
rpd->acct_req->pack->id++;
- rad_packet_change_val(rpd->acct_req->pack, "Acct-Status-Type", "Interim-Update");
- rad_packet_change_int(rpd->acct_req->pack, "Acct-Delay-Time", 0);
+ rad_packet_change_val(rpd->acct_req->pack, NULL, "Acct-Status-Type", "Interim-Update");
+ rad_packet_change_int(rpd->acct_req->pack, NULL, "Acct-Delay-Time", 0);
req_set_RA(rpd->acct_req, conf_acct_secret);
rad_req_send(rpd->acct_req, conf_interim_verbose);
if (conf_acct_timeout) {
@@ -194,7 +194,7 @@ int rad_acct_start(struct radius_pd_t *rpd)
for (i = 0; i < conf_max_try; i++) {
time(&ts);
- rad_packet_change_int(rpd->acct_req->pack, "Acct-Delay-Time", ts - rpd->acct_timestamp);
+ rad_packet_change_int(rpd->acct_req->pack, NULL, "Acct-Delay-Time", ts - rpd->acct_timestamp);
if (req_set_RA(rpd->acct_req, conf_acct_secret))
goto out_err;
if (rad_req_send(rpd->acct_req, conf_verbose))
@@ -256,29 +256,29 @@ void rad_acct_stop(struct radius_pd_t *rpd)
switch (rpd->ppp->terminate_cause) {
case TERM_USER_REQUEST:
- rad_packet_add_val(rpd->acct_req->pack, "Acct-Terminate-Cause", "User-Request");
+ rad_packet_add_val(rpd->acct_req->pack, NULL, "Acct-Terminate-Cause", "User-Request");
break;
case TERM_SESSION_TIMEOUT:
- rad_packet_add_val(rpd->acct_req->pack, "Acct-Terminate-Cause", "Session-Timeout");
+ rad_packet_add_val(rpd->acct_req->pack, NULL, "Acct-Terminate-Cause", "Session-Timeout");
break;
case TERM_ADMIN_RESET:
- rad_packet_add_val(rpd->acct_req->pack, "Acct-Terminate-Cause", "Admin-Reset");
+ rad_packet_add_val(rpd->acct_req->pack, NULL, "Acct-Terminate-Cause", "Admin-Reset");
break;
case TERM_USER_ERROR:
case TERM_AUTH_ERROR:
- rad_packet_add_val(rpd->acct_req->pack, "Acct-Terminate-Cause", "User-Error");
+ rad_packet_add_val(rpd->acct_req->pack, NULL, "Acct-Terminate-Cause", "User-Error");
break;
case TERM_NAS_ERROR:
- rad_packet_add_val(rpd->acct_req->pack, "Acct-Terminate-Cause", "NAS-Error");
+ rad_packet_add_val(rpd->acct_req->pack, NULL, "Acct-Terminate-Cause", "NAS-Error");
break;
case TERM_NAS_REQUEST:
- rad_packet_add_val(rpd->acct_req->pack, "Acct-Terminate-Cause", "NAS-Request");
+ rad_packet_add_val(rpd->acct_req->pack, NULL, "Acct-Terminate-Cause", "NAS-Request");
break;
case TERM_NAS_REBOOT:
- rad_packet_add_val(rpd->acct_req->pack, "Acct-Terminate-Cause", "NAS-Reboot");
+ rad_packet_add_val(rpd->acct_req->pack, NULL, "Acct-Terminate-Cause", "NAS-Reboot");
break;
}
- rad_packet_change_val(rpd->acct_req->pack, "Acct-Status-Type", "Stop");
+ rad_packet_change_val(rpd->acct_req->pack, NULL, "Acct-Status-Type", "Stop");
req_set_stat(rpd->acct_req, rpd->ppp);
req_set_RA(rpd->acct_req, conf_acct_secret);
/// !!! rad_req_add_val(rpd->acct_req, "Acct-Terminate-Cause", "");
@@ -292,7 +292,7 @@ void rad_acct_stop(struct radius_pd_t *rpd)
for(i = 0; i < conf_max_try; i++) {
time(&ts);
- rad_packet_change_int(rpd->acct_req->pack, "Acct-Delay-Time", ts - rpd->acct_timestamp);
+ rad_packet_change_int(rpd->acct_req->pack, NULL, "Acct-Delay-Time", ts - rpd->acct_timestamp);
rpd->acct_req->pack->id++;
if (req_set_RA(rpd->acct_req, conf_acct_secret))
break;
diff --git a/accel-pptpd/radius/auth.c b/accel-pptpd/radius/auth.c
index 94a82698..244cb6e0 100644
--- a/accel-pptpd/radius/auth.c
+++ b/accel-pptpd/radius/auth.c
@@ -190,7 +190,7 @@ int rad_auth_pap(struct radius_pd_t *rpd, const char *username, va_list args)
if (!epasswd)
goto out;
- if (rad_packet_add_octets(req->pack, "User-Password", epasswd, epasswd_len)) {
+ if (rad_packet_add_octets(req->pack, NULL, "User-Password", epasswd, epasswd_len)) {
if (epasswd_len)
_free(epasswd);
goto out;
@@ -200,7 +200,7 @@ int rad_auth_pap(struct radius_pd_t *rpd, const char *username, va_list args)
_free(epasswd);
if (conf_sid_in_auth)
- if (rad_packet_add_str(req->pack, "Acct-Session-Id", rpd->ppp->sessionid, PPP_SESSIONID_LEN))
+ if (rad_packet_add_str(req->pack, NULL, "Acct-Session-Id", rpd->ppp->sessionid))
return -1;
r = rad_auth_send(req);
@@ -240,29 +240,29 @@ int rad_auth_chap_md5(struct radius_pd_t *rpd, const char *username, va_list arg
if (challenge_len == 16)
memcpy(rpd->auth_req->RA, challenge, 16);
else {
- if (rad_packet_add_octets(rpd->auth_req->pack, "CHAP-Challenge", challenge, challenge_len))
+ if (rad_packet_add_octets(rpd->auth_req->pack, NULL, "CHAP-Challenge", challenge, challenge_len))
goto out;
}
- if (rad_packet_add_octets(rpd->auth_req->pack, "CHAP-Password", chap_password, 17))
+ if (rad_packet_add_octets(rpd->auth_req->pack, NULL, "CHAP-Password", chap_password, 17))
goto out;
} else {
if (challenge_len == 16)
memcpy(rpd->auth_req->RA, challenge, 16);
else {
- if (rad_packet_change_octets(rpd->auth_req->pack, "CHAP-Challenge", challenge, challenge_len))
+ if (rad_packet_change_octets(rpd->auth_req->pack, NULL, "CHAP-Challenge", challenge, challenge_len))
goto out;
}
- if (rad_packet_change_octets(rpd->auth_req->pack, "CHAP-Password", chap_password, 17))
+ if (rad_packet_change_octets(rpd->auth_req->pack, NULL, "CHAP-Password", chap_password, 17))
goto out;
if (rpd->attr_state) {
- if (rad_packet_find_attr(rpd->auth_req->pack, "State")) {
- if (rad_packet_change_octets(rpd->auth_req->pack, "State", rpd->attr_state, rpd->attr_state_len))
+ if (rad_packet_find_attr(rpd->auth_req->pack, NULL, "State")) {
+ if (rad_packet_change_octets(rpd->auth_req->pack, NULL, "State", rpd->attr_state, rpd->attr_state_len))
goto out;
} else {
- if (rad_packet_add_octets(rpd->auth_req->pack, "State", rpd->attr_state, rpd->attr_state_len))
+ if (rad_packet_add_octets(rpd->auth_req->pack, NULL, "State", rpd->attr_state, rpd->attr_state_len))
goto out;
}
}
@@ -272,7 +272,7 @@ int rad_auth_chap_md5(struct radius_pd_t *rpd, const char *username, va_list arg
}
if (conf_sid_in_auth)
- if (rad_packet_add_str(rpd->auth_req->pack, "Acct-Session-Id", rpd->ppp->sessionid, PPP_SESSIONID_LEN))
+ if (rad_packet_add_str(rpd->auth_req->pack, NULL, "Acct-Session-Id", rpd->ppp->sessionid))
goto out;
r = rad_auth_send(rpd->auth_req);
@@ -358,24 +358,24 @@ int rad_auth_mschap_v1(struct radius_pd_t *rpd, const char *username, va_list ar
if (!rpd->auth_req)
return PWDB_DENIED;
- if (rad_packet_add_vendor_octets(rpd->auth_req->pack, "Microsoft", "MS-CHAP-Challenge", challenge, challenge_len))
+ if (rad_packet_add_octets(rpd->auth_req->pack, "Microsoft", "MS-CHAP-Challenge", challenge, challenge_len))
goto out;
- if (rad_packet_add_vendor_octets(rpd->auth_req->pack, "Microsoft", "MS-CHAP-Response", response, sizeof(response)))
+ if (rad_packet_add_octets(rpd->auth_req->pack, "Microsoft", "MS-CHAP-Response", response, sizeof(response)))
goto out;
} else {
- if (rad_packet_change_vendor_octets(rpd->auth_req->pack, "Microsoft", "MS-CHAP-Challenge", challenge, challenge_len))
+ if (rad_packet_change_octets(rpd->auth_req->pack, "Microsoft", "MS-CHAP-Challenge", challenge, challenge_len))
goto out;
- if (rad_packet_change_vendor_octets(rpd->auth_req->pack, "Microsoft", "MS-CHAP-Response", response, sizeof(response)))
+ if (rad_packet_change_octets(rpd->auth_req->pack, "Microsoft", "MS-CHAP-Response", response, sizeof(response)))
goto out;
if (rpd->attr_state) {
- if (rad_packet_find_attr(rpd->auth_req->pack, "State")) {
- if (rad_packet_change_octets(rpd->auth_req->pack, "State", rpd->attr_state, rpd->attr_state_len))
+ if (rad_packet_find_attr(rpd->auth_req->pack, NULL, "State")) {
+ if (rad_packet_change_octets(rpd->auth_req->pack, NULL, "State", rpd->attr_state, rpd->attr_state_len))
goto out;
} else {
- if (rad_packet_add_octets(rpd->auth_req->pack, "State", rpd->attr_state, rpd->attr_state_len))
+ if (rad_packet_add_octets(rpd->auth_req->pack, NULL, "State", rpd->attr_state, rpd->attr_state_len))
goto out;
}
}
@@ -385,7 +385,7 @@ int rad_auth_mschap_v1(struct radius_pd_t *rpd, const char *username, va_list ar
}
if (conf_sid_in_auth)
- if (rad_packet_add_str(rpd->auth_req->pack, "Acct-Session-Id", rpd->ppp->sessionid, PPP_SESSIONID_LEN))
+ if (rad_packet_add_str(rpd->auth_req->pack, NULL, "Acct-Session-Id", rpd->ppp->sessionid))
goto out;
r = rad_auth_send(rpd->auth_req);
@@ -433,24 +433,24 @@ int rad_auth_mschap_v2(struct radius_pd_t *rpd, const char *username, va_list ar
if (!rpd->auth_req)
return PWDB_DENIED;
- if (rad_packet_add_vendor_octets(rpd->auth_req->pack, "Microsoft", "MS-CHAP-Challenge", challenge, 16))
+ if (rad_packet_add_octets(rpd->auth_req->pack, "Microsoft", "MS-CHAP-Challenge", challenge, 16))
goto out;
- if (rad_packet_add_vendor_octets(rpd->auth_req->pack, "Microsoft", "MS-CHAP2-Response", mschap_response, sizeof(mschap_response)))
+ if (rad_packet_add_octets(rpd->auth_req->pack, "Microsoft", "MS-CHAP2-Response", mschap_response, sizeof(mschap_response)))
goto out;
} else {
- if (rad_packet_change_vendor_octets(rpd->auth_req->pack, "Microsoft", "MS-CHAP-Challenge", challenge, 16))
+ if (rad_packet_change_octets(rpd->auth_req->pack, "Microsoft", "MS-CHAP-Challenge", challenge, 16))
goto out;
- if (rad_packet_change_vendor_octets(rpd->auth_req->pack, "Microsoft", "MS-CHAP2-Response", mschap_response, sizeof(mschap_response)))
+ if (rad_packet_change_octets(rpd->auth_req->pack, "Microsoft", "MS-CHAP2-Response", mschap_response, sizeof(mschap_response)))
goto out;
if (rpd->attr_state) {
- if (rad_packet_find_attr(rpd->auth_req->pack, "State")) {
- if (rad_packet_change_octets(rpd->auth_req->pack, "State", rpd->attr_state, rpd->attr_state_len))
+ if (rad_packet_find_attr(rpd->auth_req->pack, NULL, "State")) {
+ if (rad_packet_change_octets(rpd->auth_req->pack, NULL, "State", rpd->attr_state, rpd->attr_state_len))
goto out;
} else {
- if (rad_packet_add_octets(rpd->auth_req->pack, "State", rpd->attr_state, rpd->attr_state_len))
+ if (rad_packet_add_octets(rpd->auth_req->pack, NULL, "State", rpd->attr_state, rpd->attr_state_len))
goto out;
}
}
@@ -460,12 +460,12 @@ int rad_auth_mschap_v2(struct radius_pd_t *rpd, const char *username, va_list ar
}
if (conf_sid_in_auth)
- if (rad_packet_add_str(rpd->auth_req->pack, "Acct-Session-Id", rpd->ppp->sessionid, PPP_SESSIONID_LEN))
+ if (rad_packet_add_str(rpd->auth_req->pack, NULL, "Acct-Session-Id", rpd->ppp->sessionid))
goto out;
r = rad_auth_send(rpd->auth_req);
if (r == PWDB_SUCCESS) {
- ra = rad_packet_find_vendor_attr(rpd->auth_req->reply, "Microsoft", "MS-CHAP2-Success");
+ ra = rad_packet_find_attr(rpd->auth_req->reply, "Microsoft", "MS-CHAP2-Success");
if (!ra) {
log_error("radius:auth:mschap-v2: 'MS-CHAP-Success' not found in radius response\n");
r = PWDB_DENIED;
diff --git a/accel-pptpd/radius/dict/dictionary b/accel-pptpd/radius/dict/dictionary
index 02006a63..27973105 100644
--- a/accel-pptpd/radius/dict/dictionary
+++ b/accel-pptpd/radius/dict/dictionary
@@ -70,6 +70,7 @@ $INCLUDE dictionary.rfc3576
$INCLUDE dictionary.rfc3580
$INCLUDE dictionary.rfc4072
$INCLUDE dictionary.rfc4372
+$INCLUDE dictionary.rfc4679
$INCLUDE dictionary.rfc5176
$INCLUDE dictionary.microsoft
diff --git a/accel-pptpd/radius/dm_coa.c b/accel-pptpd/radius/dm_coa.c
index baf51b51..366bb417 100644
--- a/accel-pptpd/radius/dm_coa.c
+++ b/accel-pptpd/radius/dm_coa.c
@@ -102,7 +102,7 @@ static int dm_coa_send_nak(int fd, struct rad_packet_t *req, struct sockaddr_in
reply->id = req->id;
if (err_code)
- rad_packet_add_int(reply, "Error-Cause", err_code);
+ rad_packet_add_int(reply, NULL, "Error-Cause", err_code);
if (rad_packet_build(reply, RA)) {
rad_packet_free(reply);
diff --git a/accel-pptpd/radius/packet.c b/accel-pptpd/radius/packet.c
index 08991ddd..4e24dedc 100644
--- a/accel-pptpd/radius/packet.c
+++ b/accel-pptpd/radius/packet.c
@@ -324,15 +324,25 @@ void rad_packet_print(struct rad_packet_t *pack, void (*print)(const char *fmt,
print("]\n");
}
-int rad_packet_add_int(struct rad_packet_t *pack, const char *name, int val)
+int __export rad_packet_add_int(struct rad_packet_t *pack, const char *vendor_name, const char *name, int val)
{
struct rad_attr_t *ra;
struct rad_dict_attr_t *attr;
+ struct rad_dict_vendor_t *vendor;
- if (pack->len + 2 + 4 >= REQ_LENGTH_MAX)
+ if (pack->len + (vendor_name ? 8 : 2) + 4 >= REQ_LENGTH_MAX)
return -1;
- attr = rad_dict_find_attr(name);
+ if (vendor_name) {
+ vendor = rad_dict_find_vendor_name(vendor_name);
+ if (!vendor)
+ return -1;
+ attr = rad_dict_find_vendor_attr(vendor, name);
+ } else {
+ vendor = NULL;
+ attr = rad_dict_find_attr(name);
+ }
+
if (!attr)
return -1;
@@ -341,20 +351,21 @@ int rad_packet_add_int(struct rad_packet_t *pack, const char *name, int val)
return -1;
memset(ra, 0, sizeof(*ra));
+ ra->vendor = vendor;
ra->attr = attr;
ra->len = 4;
ra->val.integer = val;
list_add_tail(&ra->entry, &pack->attrs);
- pack->len += 2 + 4;
+ pack->len += (vendor_name ? 8 : 2) + 4;
return 0;
}
-int rad_packet_change_int(struct rad_packet_t *pack, const char *name, int val)
+int __export rad_packet_change_int(struct rad_packet_t *pack, const char *vendor_name, const char *name, int val)
{
struct rad_attr_t *ra;
- ra = rad_packet_find_attr(pack, name);
+ ra = rad_packet_find_attr(pack, vendor_name, name);
if (!ra)
return -1;
@@ -363,15 +374,25 @@ int rad_packet_change_int(struct rad_packet_t *pack, const char *name, int val)
return 0;
}
-int rad_packet_add_octets(struct rad_packet_t *pack, const char *name, const uint8_t *val, int len)
+int __export rad_packet_add_octets(struct rad_packet_t *pack, const char *vendor_name, const char *name, const uint8_t *val, int len)
{
struct rad_attr_t *ra;
struct rad_dict_attr_t *attr;
+ struct rad_dict_vendor_t *vendor;
- if (pack->len + 2 + len >= REQ_LENGTH_MAX)
+ if (pack->len + (vendor_name ? 8 : 2) + len >= REQ_LENGTH_MAX)
return -1;
- attr = rad_dict_find_attr(name);
+ if (vendor_name) {
+ vendor = rad_dict_find_vendor_name(vendor_name);
+ if (!vendor)
+ return -1;
+ attr = rad_dict_find_vendor_attr(vendor, name);
+ } else {
+ vendor = NULL;
+ attr = rad_dict_find_attr(name);
+ }
+
if (!attr)
return -1;
@@ -382,6 +403,7 @@ int rad_packet_add_octets(struct rad_packet_t *pack, const char *name, const uin
}
memset(ra, 0, sizeof(*ra));
+ ra->vendor = vendor;
ra->attr = attr;
ra->len = len;
ra->val.octets = _malloc(len);
@@ -392,16 +414,16 @@ int rad_packet_add_octets(struct rad_packet_t *pack, const char *name, const uin
}
memcpy(ra->val.octets, val, len);
list_add_tail(&ra->entry, &pack->attrs);
- pack->len += 2 + len;
+ pack->len += (vendor_name ? 8 : 2) + len;
return 0;
}
-int rad_packet_change_octets(struct rad_packet_t *pack, const char *name, const uint8_t *val, int len)
+int __export rad_packet_change_octets(struct rad_packet_t *pack, const char *vendor_name, const char *name, const uint8_t *val, int len)
{
struct rad_attr_t *ra;
- ra = rad_packet_find_attr(pack, name);
+ ra = rad_packet_find_attr(pack, vendor_name, name);
if (!ra)
return -1;
@@ -425,15 +447,26 @@ int rad_packet_change_octets(struct rad_packet_t *pack, const char *name, const
}
-int rad_packet_add_str(struct rad_packet_t *pack, const char *name, const char *val, int len)
+int __export rad_packet_add_str(struct rad_packet_t *pack, const char *vendor_name, const char *name, const char *val)
{
struct rad_attr_t *ra;
struct rad_dict_attr_t *attr;
+ struct rad_dict_vendor_t *vendor;
+ int len = strlen(val);
- if (pack->len + 2 + len >= REQ_LENGTH_MAX)
+ if (pack->len + (vendor_name ? 8 : 2) + len >= REQ_LENGTH_MAX)
return -1;
- attr = rad_dict_find_attr(name);
+ if (vendor_name) {
+ vendor = rad_dict_find_vendor_name(vendor_name);
+ if (!vendor)
+ return -1;
+ attr = rad_dict_find_vendor_attr(vendor, name);
+ } else {
+ vendor = NULL;
+ attr = rad_dict_find_attr(name);
+ }
+
if (!attr)
return -1;
@@ -444,9 +477,10 @@ int rad_packet_add_str(struct rad_packet_t *pack, const char *name, const char *
}
memset(ra, 0, sizeof(*ra));
+ ra->vendor = vendor;
ra->attr = attr;
ra->len = len;
- ra->val.string = _malloc(len+1);
+ ra->val.string = _malloc(len + 1);
if (!ra->val.string) {
log_emerg("radius: out of memory\n");
_free(ra);
@@ -455,16 +489,16 @@ int rad_packet_add_str(struct rad_packet_t *pack, const char *name, const char *
memcpy(ra->val.string, val, len);
ra->val.string[len] = 0;
list_add_tail(&ra->entry, &pack->attrs);
- pack->len += 2 + len;
+ pack->len += (vendor_name ? 8 : 2) + len;
return 0;
}
-int rad_packet_change_str(struct rad_packet_t *pack, const char *name, const char *val, int len)
+int __export rad_packet_change_str(struct rad_packet_t *pack, const char *vendor_name, const char *name, const char *val, int len)
{
struct rad_attr_t *ra;
- ra = rad_packet_find_attr(pack, name);
+ ra = rad_packet_find_attr(pack, vendor_name, name);
if (!ra)
return -1;
@@ -488,19 +522,29 @@ int rad_packet_change_str(struct rad_packet_t *pack, const char *name, const cha
return 0;
}
-int rad_packet_add_val(struct rad_packet_t *pack, const char *name, const char *val)
+int __export rad_packet_add_val(struct rad_packet_t *pack, const char *vendor_name, const char *name, const char *val)
{
struct rad_attr_t *ra;
struct rad_dict_attr_t *attr;
struct rad_dict_value_t *v;
+ struct rad_dict_vendor_t *vendor;
- if (pack->len + 2 + 4 >= REQ_LENGTH_MAX)
+ if (pack->len + (vendor_name ? 8 : 2) + 4 >= REQ_LENGTH_MAX)
return -1;
- attr = rad_dict_find_attr(name);
+ if (vendor_name) {
+ vendor = rad_dict_find_vendor_name(vendor_name);
+ if (!vendor)
+ return -1;
+ attr = rad_dict_find_vendor_attr(vendor, name);
+ } else {
+ vendor = NULL;
+ attr = rad_dict_find_attr(name);
+ }
+
if (!attr)
return -1;
-
+
v = rad_dict_find_val_name(attr, val);
if (!v)
return -1;
@@ -510,21 +554,22 @@ int rad_packet_add_val(struct rad_packet_t *pack, const char *name, const char *
return -1;
memset(ra, 0, sizeof(*ra));
+ ra->vendor = vendor;
ra->attr = attr;
ra->len = 4;
ra->val = v->val;
list_add_tail(&ra->entry, &pack->attrs);
- pack->len += 2 + 4;
+ pack->len += (vendor_name ? 8 : 2) + 4;
return 0;
}
-int rad_packet_change_val(struct rad_packet_t *pack, const char *name, const char *val)
+int __export rad_packet_change_val(struct rad_packet_t *pack, const char *vendor_name, const char *name, const char *val)
{
struct rad_attr_t *ra;
struct rad_dict_value_t *v;
- ra = rad_packet_find_attr(pack, name);
+ ra = rad_packet_find_attr(pack, vendor_name, name);
if (!ra)
return -1;
@@ -537,19 +582,33 @@ int rad_packet_change_val(struct rad_packet_t *pack, const char *name, const cha
return 0;
}
-int rad_packet_add_ipaddr(struct rad_packet_t *pack, const char *name, in_addr_t ipaddr)
+int __export rad_packet_add_ipaddr(struct rad_packet_t *pack, const char *vendor_name, const char *name, in_addr_t ipaddr)
{
- return rad_packet_add_int(pack, name, ipaddr);
+ return rad_packet_add_int(pack, vendor_name, name, ipaddr);
}
-struct rad_attr_t *rad_packet_find_attr(struct rad_packet_t *pack, const char *name)
+struct rad_attr_t __export *rad_packet_find_attr(struct rad_packet_t *pack, const char *vendor_name, const char *name)
{
struct rad_attr_t *ra;
+ struct rad_dict_vendor_t *vendor;
- list_for_each_entry(ra, &pack->attrs, entry)
- if (!strcmp(ra->attr->name, name))
- return ra;
+ if (vendor_name) {
+ vendor = rad_dict_find_vendor_name(vendor_name);
+ if (!vendor)
+ return NULL;
+ } else
+ vendor = NULL;
+
+ list_for_each_entry(ra, &pack->attrs, entry) {
+ if (vendor && vendor != ra->vendor)
+ continue;
+
+ if (strcmp(ra->attr->name, name))
+ continue;
+
+ return ra;
+ }
return NULL;
}
@@ -578,91 +637,6 @@ int rad_packet_send(struct rad_packet_t *pack, int fd, struct sockaddr_in *addr)
return 0;
}
-int rad_packet_add_vendor_octets(struct rad_packet_t *pack, const char *vendor_name, const char *name, const uint8_t *val, int len)
-{
- struct rad_attr_t *ra;
- struct rad_dict_attr_t *attr;
- struct rad_dict_vendor_t *vendor;
-
- if (pack->len + 6 + 2 + len >= REQ_LENGTH_MAX)
- return -1;
-
- vendor = rad_dict_find_vendor_name(vendor_name);
- if (!vendor)
- return -1;
-
- attr = rad_dict_find_vendor_attr(vendor, name);
- if (!attr)
- return -1;
-
- ra = mempool_alloc(attr_pool);
- if (!ra) {
- log_emerg("radius: out of memory\n");
- return -1;
- }
-
- memset(ra, 0, sizeof(*ra));
- ra->vendor = vendor;
- ra->attr = attr;
- ra->len = len;
- ra->val.octets = _malloc(len);
- if (!ra->val.octets) {
- log_emerg("radius: out of memory\n");
- _free(ra);
- return -1;
- }
- memcpy(ra->val.octets, val, len);
- list_add_tail(&ra->entry, &pack->attrs);
- pack->len += 6 + 2 + len;
-
- return 0;
-}
-
-int rad_packet_change_vendor_octets(struct rad_packet_t *pack, const char *vendor_name, const char *name, const uint8_t *val, int len)
-{
- struct rad_attr_t *ra;
-
- ra = rad_packet_find_vendor_attr(pack, vendor_name, name);
- if (!ra)
- return -1;
-
- if (ra->len != len) {
- if (pack->len - ra->len + len >= REQ_LENGTH_MAX)
- return -1;
-
- ra->val.octets = _realloc(ra->val.octets, len);
- if (!ra->val.octets) {
- log_emerg("radius: out of memory\n");
- return -1;
- }
-
- pack->len += len - ra->len;
- ra->len = len;
- }
-
- memcpy(ra->val.octets, val, len);
-
- return 0;
-}
-
-struct rad_attr_t *rad_packet_find_vendor_attr(struct rad_packet_t *pack, const char *vendor_name, const char *name)
-{
- struct rad_attr_t *ra;
-
- list_for_each_entry(ra, &pack->attrs, entry) {
- if (!ra->vendor)
- continue;
- if (strcmp(ra->vendor->name, vendor_name))
- continue;
- if (strcmp(ra->attr->name, name))
- continue;
-
- return ra;
- }
-
- return NULL;
-}
-
static void __init init(void)
{
attr_pool = mempool_create(sizeof(struct rad_attr_t));
diff --git a/accel-pptpd/radius/radius.c b/accel-pptpd/radius/radius.c
index 8d0c8878..f081cf4f 100644
--- a/accel-pptpd/radius/radius.c
+++ b/accel-pptpd/radius/radius.c
@@ -173,6 +173,7 @@ static void ppp_starting(struct ppp_t *ppp)
rpd->pd.key = &pd_key;
rpd->ppp = ppp;
pthread_mutex_init(&rpd->lock, NULL);
+ INIT_LIST_HEAD(&rpd->plugin_list);
list_add_tail(&rpd->pd.entry, &ppp->pd_list);
pthread_rwlock_wrlock(&sessions_lock);
@@ -331,12 +332,23 @@ int rad_check_nas_pack(struct rad_packet_t *pack)
if (conf_nas_identifier && ident && strcmp(conf_nas_identifier, ident))
return -1;
+
if (conf_nas_ip_address && ipaddr && conf_nas_ip_address != ipaddr)
return -1;
return 0;
}
+void __export rad_register_plugin(struct ppp_t *ppp, struct rad_plugin_t *plugin)
+{
+ struct radius_pd_t *rpd = find_pd(ppp);
+
+ if (!rpd)
+ return;
+
+ list_add_tail(&plugin->entry, &rpd->plugin_list);
+}
+
static struct ipdb_t ipdb = {
.get = get_ip,
};
diff --git a/accel-pptpd/radius/radius.h b/accel-pptpd/radius/radius.h
index c42989e4..ad229d22 100644
--- a/accel-pptpd/radius/radius.h
+++ b/accel-pptpd/radius/radius.h
@@ -84,6 +84,17 @@ struct rad_packet_t
void *buf;
};
+struct rad_plugin_t
+{
+ struct list_head entry;
+ int (*send_access_request)(struct rad_plugin_t *, struct rad_packet_t *pack);
+ int (*send_accounting_request)(struct rad_plugin_t *, struct rad_packet_t *pack);
+};
+
+struct ppp_t;
+
+void rad_register_plugin(struct ppp_t *, struct rad_plugin_t *);
+
struct rad_dict_attr_t *rad_dict_find_attr(const char *name);
struct rad_dict_attr_t *rad_dict_find_attr_id(struct rad_dict_vendor_t *vendor, int type);
struct rad_dict_value_t *rad_dict_find_val_name(struct rad_dict_attr_t *, const char *name);
@@ -92,18 +103,15 @@ struct rad_dict_vendor_t *rad_dict_find_vendor_name(const char *name);
struct rad_dict_vendor_t *rad_dict_find_vendor_id(int id);
struct rad_dict_attr_t *rad_dict_find_vendor_attr(struct rad_dict_vendor_t *vendor, const char *name);
-struct rad_attr_t *rad_packet_find_attr(struct rad_packet_t *pack, const char *name);
-int rad_packet_add_int(struct rad_packet_t *pack, const char *name, int val);
-int rad_packet_add_val(struct rad_packet_t *pack, const char *name, const char *val);
-int rad_packet_add_str(struct rad_packet_t *pack, const char *name, const char *val, int len);
-int rad_packet_add_octets(struct rad_packet_t *pack, const char *name, const uint8_t *val, int len);
-int rad_packet_change_int(struct rad_packet_t *pack, const char *name, int val);
-int rad_packet_change_val(struct rad_packet_t *pack, const char *name, const char *val);
-int rad_packet_change_octets(struct rad_packet_t *pack, const char *name, const uint8_t *val, int len);
-int rad_packet_add_ipaddr(struct rad_packet_t *pack, const char *name, in_addr_t ipaddr);
-int rad_packet_add_vendor_octets(struct rad_packet_t *pack, const char *vendor_name, const char *name, const uint8_t *val, int len);
-int rad_packet_change_vendor_octets(struct rad_packet_t *pack, const char *vendor_name, const char *name, const uint8_t *val, int len);
-struct rad_attr_t *rad_packet_find_vendor_attr(struct rad_packet_t *pack, const char *vendor_name, const char *name);
+struct rad_attr_t *rad_packet_find_attr(struct rad_packet_t *pack, const char *vendor, const char *name);
+int rad_packet_add_int(struct rad_packet_t *pack, const char *vendor, const char *name, int val);
+int rad_packet_add_val(struct rad_packet_t *pack, const char *vendor, const char *name, const char *val);
+int rad_packet_add_str(struct rad_packet_t *pack, const char *vendor, const char *name, const char *val);
+int rad_packet_add_octets(struct rad_packet_t *pack, const char *vendor, const char *name, const uint8_t *val, int len);
+int rad_packet_change_int(struct rad_packet_t *pack, const char *vendor, const char *name, int val);
+int rad_packet_change_val(struct rad_packet_t *pack, const char *vendor, const char *name, const char *val);
+int rad_packet_change_octets(struct rad_packet_t *pack, const char *vendor, const char *name, const uint8_t *val, int len);
+int rad_packet_add_ipaddr(struct rad_packet_t *pack, const char *vendor, const char *name, in_addr_t ipaddr);
#endif
diff --git a/accel-pptpd/radius/radius_p.h b/accel-pptpd/radius/radius_p.h
index 2bd3ff84..9fd0b74c 100644
--- a/accel-pptpd/radius/radius_p.h
+++ b/accel-pptpd/radius/radius_p.h
@@ -38,6 +38,8 @@ struct radius_pd_t
uint8_t *attr_state;
int attr_state_len;
int termination_action;
+
+ struct list_head plugin_list;
};
struct rad_req_t
diff --git a/accel-pptpd/radius/req.c b/accel-pptpd/radius/req.c
index 94c10c3e..a384f236 100644
--- a/accel-pptpd/radius/req.c
+++ b/accel-pptpd/radius/req.c
@@ -21,6 +21,7 @@ static void rad_req_timeout(struct triton_timer_t *t);
struct rad_req_t *rad_req_alloc(struct radius_pd_t *rpd, int code, const char *username)
{
+ struct rad_plugin_t *plugin;
struct rad_req_t *req = _malloc(sizeof(*req));
if (!req)
@@ -48,32 +49,45 @@ struct rad_req_t *rad_req_alloc(struct radius_pd_t *rpd, int code, const char *u
if (!req->pack)
goto out_err;
- if (rad_packet_add_str(req->pack, "User-Name", username, strlen(username)))
+ if (rad_packet_add_str(req->pack, NULL, "User-Name", username))
goto out_err;
if (conf_nas_identifier)
- if (rad_packet_add_str(req->pack, "NAS-Identifier", conf_nas_identifier, strlen(conf_nas_identifier)))
+ if (rad_packet_add_str(req->pack, NULL, "NAS-Identifier", conf_nas_identifier))
goto out_err;
if (conf_nas_ip_address)
- if (rad_packet_add_ipaddr(req->pack, "NAS-IP-Address", conf_nas_ip_address))
+ if (rad_packet_add_ipaddr(req->pack, NULL, "NAS-IP-Address", conf_nas_ip_address))
goto out_err;
- if (rad_packet_add_int(req->pack, "NAS-Port", rpd->ppp->unit_idx))
+ if (rad_packet_add_int(req->pack, NULL, "NAS-Port", rpd->ppp->unit_idx))
goto out_err;
- if (rad_packet_add_val(req->pack, "NAS-Port-Type", "Virtual"))
+ if (rad_packet_add_val(req->pack, NULL, "NAS-Port-Type", "Virtual"))
goto out_err;
- if (rad_packet_add_val(req->pack, "Service-Type", "Framed-User"))
+ if (rad_packet_add_val(req->pack, NULL, "Service-Type", "Framed-User"))
goto out_err;
- if (rad_packet_add_val(req->pack, "Framed-Protocol", "PPP"))
+ if (rad_packet_add_val(req->pack, NULL, "Framed-Protocol", "PPP"))
goto out_err;
if (rpd->ppp->ctrl->calling_station_id)
- if (rad_packet_add_str(req->pack, "Calling-Station-Id", rpd->ppp->ctrl->calling_station_id, strlen(rpd->ppp->ctrl->calling_station_id)))
+ if (rad_packet_add_str(req->pack, NULL, "Calling-Station-Id", rpd->ppp->ctrl->calling_station_id))
goto out_err;
if (rpd->ppp->ctrl->called_station_id)
- if (rad_packet_add_str(req->pack, "Called-Station-Id", rpd->ppp->ctrl->called_station_id, strlen(rpd->ppp->ctrl->called_station_id)))
+ if (rad_packet_add_str(req->pack, NULL, "Called-Station-Id", rpd->ppp->ctrl->called_station_id))
goto out_err;
if (rpd->attr_class)
- if (rad_packet_add_octets(req->pack, "Class", rpd->attr_class, rpd->attr_class_len))
+ if (rad_packet_add_octets(req->pack, NULL, "Class", rpd->attr_class, rpd->attr_class_len))
goto out_err;
+ list_for_each_entry(plugin, &req->rpd->plugin_list, entry) {
+ switch (code) {
+ case CODE_ACCESS_REQUEST:
+ if (plugin->send_access_request && plugin->send_access_request(plugin, req->pack))
+ goto out_err;
+ break;
+ case CODE_ACCOUNTING_REQUEST:
+ if (plugin->send_accounting_request && plugin->send_accounting_request(plugin, req->pack))
+ goto out_err;
+ break;
+ }
+ }
+
return req;
out_err:
@@ -88,29 +102,29 @@ int rad_req_acct_fill(struct rad_req_t *req)
memset(req->RA, 0, sizeof(req->RA));
- if (rad_packet_add_val(req->pack, "Acct-Status-Type", "Start"))
+ if (rad_packet_add_val(req->pack, NULL, "Acct-Status-Type", "Start"))
return -1;
- if (rad_packet_add_val(req->pack, "Acct-Authentic", "RADIUS"))
+ if (rad_packet_add_val(req->pack, NULL, "Acct-Authentic", "RADIUS"))
return -1;
- if (rad_packet_add_str(req->pack, "Acct-Session-Id", req->rpd->ppp->sessionid, PPP_SESSIONID_LEN))
+ if (rad_packet_add_str(req->pack, NULL, "Acct-Session-Id", req->rpd->ppp->sessionid))
return -1;
- if (rad_packet_add_int(req->pack, "Acct-Session-Time", 0))
+ if (rad_packet_add_int(req->pack, NULL, "Acct-Session-Time", 0))
return -1;
- if (rad_packet_add_int(req->pack, "Acct-Input-Octets", 0))
+ if (rad_packet_add_int(req->pack, NULL, "Acct-Input-Octets", 0))
return -1;
- if (rad_packet_add_int(req->pack, "Acct-Output-Octets", 0))
+ if (rad_packet_add_int(req->pack, NULL, "Acct-Output-Octets", 0))
return -1;
- if (rad_packet_add_int(req->pack, "Acct-Input-Packets", 0))
+ if (rad_packet_add_int(req->pack, NULL, "Acct-Input-Packets", 0))
return -1;
- if (rad_packet_add_int(req->pack, "Acct-Output-Packets", 0))
+ if (rad_packet_add_int(req->pack, NULL, "Acct-Output-Packets", 0))
return -1;
- if (rad_packet_add_int(req->pack, "Acct-Input-Gigawords", 0))
+ if (rad_packet_add_int(req->pack, NULL, "Acct-Input-Gigawords", 0))
return -1;
- if (rad_packet_add_int(req->pack, "Acct-Output-Gigawords", 0))
+ if (rad_packet_add_int(req->pack, NULL, "Acct-Output-Gigawords", 0))
return -1;
- if (rad_packet_add_int(req->pack, "Acct-Delay-Time", 0))
+ if (rad_packet_add_int(req->pack, NULL, "Acct-Delay-Time", 0))
return -1;
- if (rad_packet_add_ipaddr(req->pack, "Framed-IP-Address", req->rpd->ppp->peer_ipaddr))
+ if (rad_packet_add_ipaddr(req->pack, NULL, "Framed-IP-Address", req->rpd->ppp->peer_ipaddr))
return -1;
return 0;
diff --git a/accel-pptpd/triton/loader.c b/accel-pptpd/triton/loader.c
index b6c1914e..2a2a2e2f 100644
--- a/accel-pptpd/triton/loader.c
+++ b/accel-pptpd/triton/loader.c
@@ -48,7 +48,7 @@ int load_modules(const char *name)
}
}
- if (!dlopen(fname, RTLD_NOW | RTLD_GLOBAL)) {
+ if (!dlopen(fname, RTLD_LAZY | RTLD_GLOBAL)) {
triton_log_error("loader: failed to load '%s': %s\n", opt->name, dlerror());
_free(fname);
return -1;
diff --git a/accel-pptpd/triton/md.c b/accel-pptpd/triton/md.c
index d8453896..84073d05 100644
--- a/accel-pptpd/triton/md.c
+++ b/accel-pptpd/triton/md.c
@@ -140,8 +140,10 @@ void __export triton_md_unregister_handler(struct triton_md_handler_t *ud)
spin_lock(&h->ctx->lock);
h->ud = NULL;
list_del(&h->entry);
- if (h->pending)
+ if (h->pending) {
list_del(&h->entry2);
+ __sync_sub_and_fetch(&triton_stat.md_handler_pending, 1);
+ }
spin_unlock(&h->ctx->lock);
sched_yield();
diff --git a/accel-pptpd/triton/timer.c b/accel-pptpd/triton/timer.c
index 4e37754c..7d117308 100644
--- a/accel-pptpd/triton/timer.c
+++ b/accel-pptpd/triton/timer.c
@@ -202,8 +202,10 @@ void __export triton_timer_del(struct triton_timer_t *ud)
spin_lock(&t->ctx->lock);
t->ud = NULL;
list_del(&t->entry);
- if (t->pending)
+ if (t->pending) {
list_del(&t->entry2);
+ __sync_sub_and_fetch(&triton_stat.timer_pending, 1);
+ }
spin_unlock(&t->ctx->lock);
sched_yield();
diff --git a/rfc/TR-101.pdf b/rfc/TR-101.pdf
new file mode 100644
index 00000000..38302020
--- /dev/null
+++ b/rfc/TR-101.pdf
Binary files differ