summaryrefslogtreecommitdiffstats
path: root/usr.sbin/npppd
diff options
context:
space:
mode:
authoryasuoka <yasuoka@openbsd.org>2012-09-18 13:14:08 +0000
committeryasuoka <yasuoka@openbsd.org>2012-09-18 13:14:08 +0000
commit821f7c5673b56ce7082633a67f8f8498f8f4faa2 (patch)
tree798092bb31b0c85298e91c7c3fc2cb5e2f6b4bd9 /usr.sbin/npppd
parentthis structure is not useful and ill-named. remove it. (diff)
downloadwireguard-openbsd-821f7c5673b56ce7082633a67f8f8498f8f4faa2.tar.xz
wireguard-openbsd-821f7c5673b56ce7082633a67f8f8498f8f4faa2.zip
New configuration syntax for npppd(8). `npppd.conf' will be based on
parse.y and `npppd-users' will be based on getcap(3). Add man pages. feedback from giovanni
Diffstat (limited to 'usr.sbin/npppd')
-rw-r--r--usr.sbin/npppd/HOWTO_PIPEX_NPPPD.txt154
-rw-r--r--usr.sbin/npppd/l2tp/l2tp.h60
-rw-r--r--usr.sbin/npppd/l2tp/l2tp_call.c13
-rw-r--r--usr.sbin/npppd/l2tp/l2tp_conf.h50
-rw-r--r--usr.sbin/npppd/l2tp/l2tp_ctrl.c69
-rw-r--r--usr.sbin/npppd/l2tp/l2tpd.c381
-rw-r--r--usr.sbin/npppd/npppd/Makefile36
-rw-r--r--usr.sbin/npppd/npppd/ccp.c18
-rw-r--r--usr.sbin/npppd/npppd/chap.c20
-rw-r--r--usr.sbin/npppd/npppd/ipcp.c19
-rw-r--r--usr.sbin/npppd/npppd/lcp.c96
-rw-r--r--usr.sbin/npppd/npppd/log.c158
-rw-r--r--usr.sbin/npppd/npppd/mppe.c103
-rw-r--r--usr.sbin/npppd/npppd/npppd-users.568
-rw-r--r--usr.sbin/npppd/npppd/npppd.8117
-rw-r--r--usr.sbin/npppd/npppd/npppd.c519
-rw-r--r--usr.sbin/npppd/npppd/npppd.conf.5642
-rw-r--r--usr.sbin/npppd/npppd/npppd.h297
-rw-r--r--usr.sbin/npppd/npppd/npppd_auth.c707
-rw-r--r--usr.sbin/npppd/npppd/npppd_auth.h18
-rw-r--r--usr.sbin/npppd/npppd/npppd_auth_local.h58
-rw-r--r--usr.sbin/npppd/npppd/npppd_config.c588
-rw-r--r--usr.sbin/npppd/npppd/npppd_ctl.c10
-rw-r--r--usr.sbin/npppd/npppd/npppd_defs.h28
-rw-r--r--usr.sbin/npppd/npppd/npppd_iface.c115
-rw-r--r--usr.sbin/npppd/npppd/npppd_iface.h28
-rw-r--r--usr.sbin/npppd/npppd/npppd_local.h100
-rw-r--r--usr.sbin/npppd/npppd/npppd_pool.c75
-rw-r--r--usr.sbin/npppd/npppd/npppd_radius.c8
-rw-r--r--usr.sbin/npppd/npppd/pap.c8
-rw-r--r--usr.sbin/npppd/npppd/parse.y1551
-rw-r--r--usr.sbin/npppd/npppd/ppp.c227
-rw-r--r--usr.sbin/npppd/npppd/ppp.h28
-rw-r--r--usr.sbin/npppd/npppd/privsep.c494
-rw-r--r--usr.sbin/npppd/npppd/privsep.h10
-rw-r--r--usr.sbin/npppd/npppd/radius_req.c14
-rw-r--r--usr.sbin/npppd/npppd/radius_req.h4
-rw-r--r--usr.sbin/npppd/pppoe/pppoe.h43
-rw-r--r--usr.sbin/npppd/pppoe/pppoe_conf.h46
-rw-r--r--usr.sbin/npppd/pppoe/pppoe_local.h6
-rw-r--r--usr.sbin/npppd/pppoe/pppoe_session.c8
-rw-r--r--usr.sbin/npppd/pppoe/pppoed.c150
-rw-r--r--usr.sbin/npppd/pptp/pptp.h40
-rw-r--r--usr.sbin/npppd/pptp/pptp_call.c12
-rw-r--r--usr.sbin/npppd/pptp/pptp_conf.h45
-rw-r--r--usr.sbin/npppd/pptp/pptp_ctrl.c14
-rw-r--r--usr.sbin/npppd/pptp/pptpd.c268
47 files changed, 4616 insertions, 2907 deletions
diff --git a/usr.sbin/npppd/HOWTO_PIPEX_NPPPD.txt b/usr.sbin/npppd/HOWTO_PIPEX_NPPPD.txt
deleted file mode 100644
index bef1f078873..00000000000
--- a/usr.sbin/npppd/HOWTO_PIPEX_NPPPD.txt
+++ /dev/null
@@ -1,154 +0,0 @@
-$Id: HOWTO_PIPEX_NPPPD.txt,v 1.8 2012/01/18 03:21:28 yasuoka Exp $
-
-How to test npppd and pipex
----------------------------
-
- client ------ server
- A.B.C.D
-
-on server
-
- 1. update your source tree
-
- 2. build and update kernel
-
- 3. build npppd
-
- % cd /usr/src/usr.sbin/npppd
- % make
- % sudo make install
-
- 4. install npppd.conf and npppd-users.csv to /etc/npppd/
- sample npppd.conf and npppd-user.csv attached below on this file.
-
- % sudo mkdir -m 0755 /etc/npppd
- % sudo cp npppd.conf /etc/npppd/
- % sudo cp npppd-users.csv /etc/npppd/
-
- 5. enable PIPEX and GRE by sysctl
-
- % sudo sysctl net.inet.gre.allow=1 (for PPTP)
- % sudo sysctl net.pipex.enable=1 (for PIPEX)
-
- 6. run npppd
-
- % sudo /usr/sbin/npppd -d
-
- NOTE:
-
- * Previous version required to create `_npppd' user and group, but
- now it uses '_ppp' instead. Delete `_npppd' if you created.
-
- % sudo userdel _npppd
- % sudo groupdel _npppd
-
- * Previous version has `npppdctl', but it was replaced by `npppctl'.
- So please remove `npppdctl' related files.
-
- % sudo rm /usr/sbin/npppdctl
- % sudo rm /usr/share/man/cat8/npppdctl.0
- % sudo rm /usr/share/man/man8/npppdctl.8
-
-
-on client
-
- 1. install 'pptp' from ports.
- 2. edit /etc/ppp/ppp.conf
- -------------------------------
- test_pptp:
- set device "!/usr/local/sbin/pptp --nolaunchpppd A.B.C.D"
- set authname test
- set authkey hogehoge
- set mppe 128 stateless
- disable protocomp
- deny protocomp
- disable ipv6cp
- -------------------------------
- modify "A.B.C.D" to actual IP address.
- 3. dial test_pptp
- % sudo ppp -ddial test_pptp
-
-
-How to test L2TP/IPsec
-----------------------
-
- 1. run isakmpd
- % sudo isakmpd -Kv
- 2. append below lines to /etc/ipsec.conf
- -------------------------------
- ike passive esp transport \
- proto udp from A.B.C.D to any port 1701 \
- main auth "hmac-sha" enc "3des" group modp1024 \
- quick auth "hmac-sha" enc "aes" \
- psk "secret"
- -------------------------------
- - change A.B.C.D to actual IP address
- - change "secret" to actual shared secret
-
- 3. exec ipsecctl to notice isakmpd
- % sudo ipsecctl -f /etc/ipsec.conf
-
- 4. connect from iPhone, MacOS or Windows
-
-
-[npppd.conf]
--------------------------------------------------------------------------------
-#
-# Simplest npppd.conf sample
-#
-# $Id: HOWTO_PIPEX_NPPPD.txt,v 1.8 2012/01/18 03:21:28 yasuoka Exp $
-
-interface_list: tun0
-interface.tun0.ip4addr: 10.0.0.1
-
-# IP address pool
-pool.dyna_pool: 10.0.0.0/25
-pool.pool: 10.0.0.128/25
-
-# Local file authentication
-auth.local.realm_list: local
-auth.local.realm.acctlist: /etc/npppd/npppd-users.csv
-realm.local.concentrate: tun0
-
-# RADIUS authentication / accounting
-#auth.radius.realm_list: radius
-#auth.radius.realm.server.address: 127.0.0.1:1812
-#auth.radius.realm.server.secret: hogehoge
-#auth.radius.realm.acct_server.address: 127.0.0.1:1813
-#auth.radius.realm.acct_server.secret: hogehoge
-#realm.radius.concentrate: tun0
-
-lcp.mru: 1400
-auth.method: mschapv2 chap
-#auth.method: mschapv2 chap pap
-#ipcp.dns_primary: 192.168.4.20
-#ipcp.dns_secondary: 192.168.6.20
-#ipcp.nbns_primary: 192.168.4.20
-#ipcp.nbns_secondary: 192.168.6.20
-#ipcp.assign_fixed: true
-#ipcp.assign_userselect: true
-
-pptpd.enabled: true
-pptpd.ip4_allow: 0.0.0.0/0
-#pptpd.listener_in: PPTP 192.168.0.1
-
-# L2TP daemon
-l2tpd.enabled: true
-l2tpd.ip4_allow: 0.0.0.0/0
-#l2tpd.listener_in: L2TP 192.168.0.1
-#l2tpd.purge_ipsec_sa: true
-l2tpd.require_ipsec: false
-
-# PPPoE daemon
-#pppoed.enabled: true
-#pppoed.interface: PPPoE vic0
-
-#pipex.enabled: false
--------------------------------------------------------------------------------
-
-[npppd-users.csv]
- - First line of the CSV is *IGNORED*. It is treated as a title line.
--------------------------------------------------------------------------------
-Username,Password,Framed-IP-Address,Framed-IP-Netmask,Description,Calling-Id
-user1,user1's secret,10.0.0.129,,memo for user1
--------------------------------------------------------------------------------
diff --git a/usr.sbin/npppd/l2tp/l2tp.h b/usr.sbin/npppd/l2tp/l2tp.h
index cc3c8b36a2f..f676273e687 100644
--- a/usr.sbin/npppd/l2tp/l2tp.h
+++ b/usr.sbin/npppd/l2tp/l2tp.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: l2tp.h,v 1.8 2012/05/08 13:18:37 yasuoka Exp $ */
+/* $OpenBSD: l2tp.h,v 1.9 2012/09/18 13:14:08 yasuoka Exp $ */
/*-
* Copyright (c) 2009 Internet Initiative Japan Inc.
@@ -30,7 +30,7 @@
/*@file
* header file for the L2TP module
*/
-/* $Id: l2tp.h,v 1.8 2012/05/08 13:18:37 yasuoka Exp $ */
+/* $Id: l2tp.h,v 1.9 2012/09/18 13:14:08 yasuoka Exp $ */
/************************************************************************
* Protocol Constants
@@ -213,8 +213,8 @@
/************************************************************************
* Implementation Specific Constants
************************************************************************/
+#include "l2tp_conf.h"
-#define L2TPD_BACKLOG 16
#define L2TPD_TUNNEL_HASH_SIZ 127
#define L2TPD_SND_BUFSIZ 2048
#define L2TPD_DEFAULT_SEND_WINSZ 4
@@ -223,7 +223,7 @@
#define L2TPD_CONFIG_BUFSIZ 65535
#define L2TP_CTRL_WINDOW_SIZE 8
#ifndef L2TPD_VENDOR_NAME
-#define L2TPD_VENDOR_NAME "IIJ"
+#define L2TPD_VENDOR_NAME ""
#endif
#define L2TPD_DEFAULT_UDP_PORT 1701
@@ -279,9 +279,13 @@
(((l2tpd)->state == L2TPD_STATE_SHUTTING_DOWN)? 1 : 0)
/** macro to retrieve a physical layer label from l2tp_ctrl */
-#define L2TP_CTRL_LISTENER_LABEL(ctrl) \
+#define L2TP_CTRL_LISTENER_TUN_NAME(ctrl) \
((l2tpd_listener *)slist_get(&(ctrl)->l2tpd->listener, \
- (ctrl)->listener_index))->phy_label
+ (ctrl)->listener_index))->tun_name
+
+#define L2TP_CTRL_CONF(ctrl) \
+ ((l2tpd_listener *)slist_get(&(ctrl)->l2tpd->listener, \
+ (ctrl)->listener_index))->conf
#define L2TP_CALL_DELAY_LIMIT 64
@@ -289,6 +293,8 @@
struct _l2tpd;
typedef struct _l2tpd_listener {
+ /* configuration */
+ struct l2tp_conf *conf;
/** event context */
struct event ev_sock;
/** L2TPD itself */
@@ -304,8 +310,8 @@ typedef struct _l2tpd_listener {
struct sockaddr_in sin4;
struct sockaddr_in6 sin6;
} bind;
- /** physical layer label */
- char phy_label[16];
+ /** tunnel name */
+ char tun_name[L2TP_NAME_LEN];
} l2tpd_listener;
/** datatype represents L2TP daemon */
@@ -323,24 +329,9 @@ typedef struct _l2tpd {
/** unique and free Session-ID list */
slist free_session_id_list;
- /** IPv4 network addresses allowed to connect */
- struct in_addr_range *ip4_allow;
-
- /** default hostname */
- char default_hostname[80];
-
- /** configuration */
- struct properties *config;
-
/** flags */
uint32_t
- require_ipsec:1,
- purge_ipsec_sa:1,
- ctrl_in_pktdump:1,
- ctrl_out_pktdump:1,
- data_in_pktdump:1,
- data_out_pktdump:1,
- phy_label_with_ifname:1;
+ purge_ipsec_sa:1;
} l2tpd;
/** datatype represents L2TP control connection */
@@ -374,8 +365,6 @@ typedef struct _l2tp_ctrl {
struct sockaddr_storage sock;
/** IPSEC NAT-T SA cookie */
void *sa_cookie;
- /** physical layer label (copied) */
- char phy_label[16];
/** list of L2TP calls */
slist call_list;
@@ -402,7 +391,6 @@ typedef struct _l2tp_ctrl {
/**
* delay between transition to idle state and sending HELLO in seconds.
- * invalid if less than or equal to zero.
*/
int hello_interval;
/** HELLO timeout */
@@ -412,8 +400,7 @@ typedef struct _l2tp_ctrl {
/** number of calls established */
int ncalls;
- int
- /** use sequence number in L2TP Data Message? */
+ int /** use sequence number in L2TP Data Message? */
data_use_seq:1,
/** waiting to acknowledge HELLO? */
hello_wait_ack:1;
@@ -479,19 +466,10 @@ l2tp_ctrl *l2tpd_get_ctrl (l2tpd *, u_int);
void l2tpd_add_ctrl (l2tpd *, l2tp_ctrl *);
void l2tpd_ctrl_finished_notify(l2tpd *);
void l2tpd_remove_ctrl (l2tpd *, u_int);
-int l2tpd_add_listener (l2tpd *, int, const char *, struct sockaddr *);
+int l2tpd_add_listener (l2tpd *, int, struct l2tp_conf *);
void l2tpd_log (l2tpd *, int, const char *, ...) __attribute__((__format__ (__printf__, 3, 4)));
-
-const char *l2tp_ctrl_config_str (l2tp_ctrl *, const char *);
-int l2tp_ctrl_config_int (l2tp_ctrl *, const char *, int);
-int l2tp_ctrl_config_str_equal (l2tp_ctrl *, const char *, const char *, int);
-int l2tp_ctrl_config_str_equali (l2tp_ctrl *, const char *, const char *, int);
-const char *l2tpd_config_str (l2tpd *, const char *);
-int l2tpd_config_int (l2tpd *, const char *, int);
-int l2tpd_config_str_equal (l2tpd *, const char *, const char *, int);
-int l2tpd_config_str_equali (l2tpd *, const char *, const char *, int);
-int l2tpd_reload(l2tpd *, struct properties *, const char *, int);
-void l2tpd_log_access_deny(l2tpd *, const char *, struct sockaddr *);
+int l2tpd_reload(l2tpd *, struct l2tp_confs *);
+void l2tpd_log_access_deny(l2tpd *, const char *, struct sockaddr *);
#ifdef __cplusplus
}
#endif
diff --git a/usr.sbin/npppd/l2tp/l2tp_call.c b/usr.sbin/npppd/l2tp/l2tp_call.c
index 990294709cc..562ca713840 100644
--- a/usr.sbin/npppd/l2tp/l2tp_call.c
+++ b/usr.sbin/npppd/l2tp/l2tp_call.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: l2tp_call.c,v 1.13 2012/07/13 15:11:14 yasuoka Exp $ */
+/* $OpenBSD: l2tp_call.c,v 1.14 2012/09/18 13:14:08 yasuoka Exp $ */
/*-
* Copyright (c) 2009 Internet Initiative Japan Inc.
@@ -25,7 +25,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
-/* $Id: l2tp_call.c,v 1.13 2012/07/13 15:11:14 yasuoka Exp $ */
+/* $Id: l2tp_call.c,v 1.14 2012/09/18 13:14:08 yasuoka Exp $ */
/**@file L2TP LNS call */
#include <sys/types.h>
#include <sys/param.h>
@@ -445,7 +445,7 @@ l2tp_call_send_data_packet(l2tp_call *_this, bytebuffer *buffer)
hdr->nr = htons(_this->rcv_nxt);
}
- if (_this->ctrl->l2tpd->data_out_pktdump != 0) {
+ if (L2TP_CTRL_CONF(_this->ctrl)->data_out_pktdump != 0) {
l2tpd_log(_this->ctrl->l2tpd, LOG_DEBUG,
"ctrl=%u call=%u L2TP Data output packet dump",
_this->ctrl->id, _this->id);
@@ -998,12 +998,12 @@ l2tp_call_bind_ppp(l2tp_call *_this, dialin_proxy_info *dpi)
_this->ppp = ppp;
- ppp->tunnel_type = PPP_TUNNEL_L2TP;
+ ppp->tunnel_type = NPPPD_TUNNEL_L2TP;
ppp->phy_context = _this;
ppp->send_packet = l2tp_call_ppp_output;
ppp->phy_close = l2tp_call_closed_by_ppp;
- strlcpy(ppp->phy_label, _this->ctrl->phy_label,
+ strlcpy(ppp->phy_label, L2TP_CTRL_LISTENER_TUN_NAME(_this->ctrl),
sizeof(ppp->phy_label));
L2TP_CALL_ASSERT(sizeof(ppp->phy_info) >= _this->ctrl->peer.ss_len);
memcpy(&ppp->phy_info, &_this->ctrl->peer,
@@ -1017,8 +1017,7 @@ l2tp_call_bind_ppp(l2tp_call *_this, dialin_proxy_info *dpi)
l2tp_call_log(_this, LOG_NOTICE, "logtype=PPPBind ppp=%d", ppp->id);
if (DIALIN_PROXY_IS_REQUESTED(dpi)) {
- if (!l2tp_ctrl_config_str_equal(_this->ctrl,
- "l2tp.accept_dialin", "true", 0)) {
+ if (!L2TP_CTRL_CONF(_this->ctrl)->accept_dialin) {
l2tp_call_log(_this, LOG_ERR,
"'accept_dialin' is 'false' in the setting.");
code = L2TP_CDN_RCODE_ERROR_CODE;
diff --git a/usr.sbin/npppd/l2tp/l2tp_conf.h b/usr.sbin/npppd/l2tp/l2tp_conf.h
new file mode 100644
index 00000000000..4306f993c31
--- /dev/null
+++ b/usr.sbin/npppd/l2tp/l2tp_conf.h
@@ -0,0 +1,50 @@
+/* $OpenBSD: l2tp_conf.h,v 1.1 2012/09/18 13:14:08 yasuoka Exp $ */
+
+/*
+ * Copyright (c) 2012 YASUOKA Masahiko <yasuoka@openbsd.org>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+#ifndef L2TP_CONF_H
+#define L2TP_CONF_H 1
+
+#include <sys/types.h>
+#include <sys/queue.h>
+#include <sys/socket.h>
+
+#include <stdbool.h>
+
+#define L2TP_NAME_LEN 16
+
+TAILQ_HEAD(l2tp_confs, l2tp_conf);
+
+struct l2tp_conf {
+ TAILQ_ENTRY(l2tp_conf) entry;
+ char name[L2TP_NAME_LEN];
+ char *hostname;
+ char *vendor_name;
+ struct sockaddr_storage address;
+ int hello_interval;
+ int hello_timeout;
+ bool data_use_seq;
+ bool require_ipsec;
+ bool accept_dialin;
+ bool lcp_renegotiation;
+ bool force_lcp_renegotiation;
+ bool ctrl_in_pktdump;
+ bool ctrl_out_pktdump;
+ bool data_in_pktdump;
+ bool data_out_pktdump;
+};
+
+#endif
diff --git a/usr.sbin/npppd/l2tp/l2tp_ctrl.c b/usr.sbin/npppd/l2tp/l2tp_ctrl.c
index a1f333e5fd5..1a980e51e27 100644
--- a/usr.sbin/npppd/l2tp/l2tp_ctrl.c
+++ b/usr.sbin/npppd/l2tp/l2tp_ctrl.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: l2tp_ctrl.c,v 1.12 2012/07/16 18:05:36 markus Exp $ */
+/* $OpenBSD: l2tp_ctrl.c,v 1.13 2012/09/18 13:14:08 yasuoka Exp $ */
/*-
* Copyright (c) 2009 Internet Initiative Japan Inc.
@@ -26,7 +26,7 @@
* SUCH DAMAGE.
*/
/**@file Control connection processing functions for L2TP LNS */
-/* $Id: l2tp_ctrl.c,v 1.12 2012/07/16 18:05:36 markus Exp $ */
+/* $Id: l2tp_ctrl.c,v 1.13 2012/09/18 13:14:08 yasuoka Exp $ */
#include <sys/types.h>
#include <sys/param.h>
#include <sys/time.h>
@@ -61,7 +61,6 @@
#include "l2tp_local.h"
#include "l2tp_subr.h"
#include "net_utils.h"
-#include "config_helper.h"
#include "version.h"
static int l2tp_ctrl_init (l2tp_ctrl *, l2tpd *, struct sockaddr *, struct sockaddr *, void *);
@@ -215,17 +214,11 @@ fail:
static void
l2tp_ctrl_reload(l2tp_ctrl *_this)
{
- int ival;
-
- _this->data_use_seq = l2tp_ctrl_config_str_equal(_this,
- "l2tp.data_use_seq", "true", 1);
-
- if ((ival = l2tp_ctrl_config_int(_this, "l2tp.hello_interval", 0))!= 0)
- _this->hello_interval = ival;
- if ((ival = l2tp_ctrl_config_int(_this, "l2tp.hello_timeout", 0)) != 0)
- _this->hello_timeout = ival;
-
- return;
+ _this->data_use_seq = L2TP_CTRL_CONF(_this)->data_use_seq;
+ if (L2TP_CTRL_CONF(_this)->hello_interval != 0)
+ _this->hello_interval = L2TP_CTRL_CONF(_this)->hello_interval;
+ if (L2TP_CTRL_CONF(_this)->hello_timeout != 0)
+ _this->hello_timeout = L2TP_CTRL_CONF(_this)->hello_timeout;
}
/*
@@ -332,7 +325,7 @@ cleanup:
break;
}
#if 0
- if (_this->l2tpd->purge_ipsec_sa != 0)
+ if (L2TP_CTRL_CONF(_this)e_ipsec_sa != 0)
l2tp_ctrl_purge_ipsec_sa(_this);
#endif
@@ -727,7 +720,6 @@ l2tp_ctrl_input(l2tpd *_this, int listener_index, struct sockaddr *peer,
char buf[L2TP_AVP_MAXSIZ], errmsg[256];
time_t curr_time;
u_char *pkt0;
- char ifname[IF_NAMESIZE], phy_label[256];
struct l2tp_header hdr;
char hbuf[NI_MAXHOST + NI_MAXSERV + 16];
@@ -826,43 +818,12 @@ l2tp_ctrl_input(l2tpd *_this, int listener_index, struct sockaddr *peer,
goto bad_packet;
}
- strlcpy(phy_label,
- ((l2tpd_listener *)slist_get(&_this->listener,
- listener_index))->phy_label, sizeof(phy_label));
- if (_this->phy_label_with_ifname != 0) {
- if (get_ifname_by_sockaddr(sock, ifname) == NULL) {
- if (errno != ENOENT)
- l2tp_ctrl_log(ctrl, LOG_ERR,
- "get_ifname_by_sockaddr() "
- "failed: %m");
- else
- l2tpd_log_access_deny(_this,
- "could not determine received "
- "interface", peer);
- goto fail;
- }
- if (l2tpd_config_str_equal(_this,
- config_key_prefix("l2tpd.interface", ifname),
- "accept", 0)){
- strlcat(phy_label, "%", sizeof(phy_label));
- strlcat(phy_label, ifname, sizeof(phy_label));
- } else if (l2tpd_config_str_equal(_this,
- config_key_prefix("l2tpd.interface", "any"),
- "accept", 0)){
- } else {
- /* the interface is not permited */
- snprintf(errmsg, sizeof(errmsg),
- "'%s' is not allowed by config.", ifname);
- l2tpd_log_access_deny(_this, errmsg, peer);
- goto fail;
- }
- }
-
if ((ctrl = l2tp_ctrl_create()) == NULL) {
l2tp_ctrl_log(ctrl, LOG_ERR,
"l2tp_ctrl_create() failed: %m");
goto fail;
}
+
if (l2tp_ctrl_init(ctrl, _this, peer, sock, nat_t_ctx) != 0) {
l2tp_ctrl_log(ctrl, LOG_ERR,
"l2tp_ctrl_start() failed: %m");
@@ -870,7 +831,6 @@ l2tp_ctrl_input(l2tpd *_this, int listener_index, struct sockaddr *peer,
}
ctrl->listener_index = listener_index;
- strlcpy(ctrl->phy_label, phy_label, sizeof(ctrl->phy_label));
l2tp_ctrl_reload(ctrl);
} else {
/*
@@ -1211,7 +1171,7 @@ l2tp_ctrl_send_packet(l2tp_ctrl *_this, int call_id, bytebuffer *bytebuf)
ntohs(hdr->ns), htons(hdr->nr),
_this->snd_nxt, _this->snd_una, _this->rcv_nxt));
- if (_this->l2tpd->ctrl_out_pktdump != 0) {
+ if (L2TP_CTRL_CONF(_this)->ctrl_out_pktdump != 0) {
l2tpd_log(_this->l2tpd, LOG_DEBUG,
"L2TP Control output packet dump");
show_hd(debug_get_debugfp(), bytebuffer_pointer(bytebuf),
@@ -1553,11 +1513,8 @@ l2tp_ctrl_send_SCCRP(l2tp_ctrl *_this)
memset(avp, 0, sizeof(*avp));
avp->is_mandatory = 1;
avp->attr_type = L2TP_AVP_TYPE_HOST_NAME;
-
- if ((val = l2tp_ctrl_config_str(_this, "l2tp.host_name")) == NULL)
- val = _this->l2tpd->default_hostname;
- if (val[0] == '\0')
- val = "G"; /* XXX magic word, why? ask yasuoka */
+ if ((val = L2TP_CTRL_CONF(_this)->hostname) == NULL)
+ val = "";
len = strlen(val);
memcpy(avp->attr_value, val, len);
bytebuf_add_avp(bytebuf, avp, len);
@@ -1592,7 +1549,7 @@ l2tp_ctrl_send_SCCRP(l2tp_ctrl *_this)
avp->is_mandatory = 1;
avp->attr_type = L2TP_AVP_TYPE_VENDOR_NAME;
- if ((val = l2tp_ctrl_config_str(_this, "l2tp.vendor_name")) == NULL)
+ if ((val = L2TP_CTRL_CONF(_this)->vendor_name) == NULL)
val = L2TPD_VENDOR_NAME;
len = strlen(val);
diff --git a/usr.sbin/npppd/l2tp/l2tpd.c b/usr.sbin/npppd/l2tp/l2tpd.c
index e5f739f8bc8..9a599fb0fe8 100644
--- a/usr.sbin/npppd/l2tp/l2tpd.c
+++ b/usr.sbin/npppd/l2tp/l2tpd.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: l2tpd.c,v 1.10 2012/07/16 18:05:36 markus Exp $ */
+/* $OpenBSD: l2tpd.c,v 1.11 2012/09/18 13:14:08 yasuoka Exp $ */
/*-
* Copyright (c) 2009 Internet Initiative Japan Inc.
@@ -26,15 +26,12 @@
* SUCH DAMAGE.
*/
/**@file L2TP(Layer Two Tunneling Protocol "L2TP") / RFC2661 */
-/* $Id: l2tpd.c,v 1.10 2012/07/16 18:05:36 markus Exp $ */
+/* $Id: l2tpd.c,v 1.11 2012/09/18 13:14:08 yasuoka Exp $ */
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <netinet/in.h>
#include <netinet/udp.h>
-#if 0
-#include <netinet6/ipsec.h>
-#endif
#include <stdlib.h>
#include <arpa/inet.h>
#include <stdio.h>
@@ -62,8 +59,6 @@
#include "l2tp_subr.h"
#include "l2tp_local.h"
#include "addr_range.h"
-#include "properties.h"
-#include "config_helper.h"
#include "net_utils.h"
#ifdef L2TPD_DEBUG
@@ -96,8 +91,6 @@ l2tpd_init(l2tpd *_this)
{
int i, off;
u_int id;
- struct sockaddr_in sin4;
- struct sockaddr_in6 sin6;
L2TPD_ASSERT(_this != NULL);
memset(_this, 0, sizeof(l2tpd));
@@ -105,20 +98,6 @@ l2tpd_init(l2tpd *_this)
slist_init(&_this->listener);
slist_init(&_this->free_session_id_list);
- memset(&sin4, 0, sizeof(sin4));
- sin4.sin_len = sizeof(sin4);
- sin4.sin_family = AF_INET;
- if (l2tpd_add_listener(_this, 0, L2TPD_DEFAULT_LAYER2_LABEL,
- (struct sockaddr *)&sin4) != 0) {
- return 1;
- }
- memset(&sin6, 0, sizeof(sin6));
- sin6.sin6_len = sizeof(sin6);
- sin6.sin6_family = AF_INET6;
- if (l2tpd_add_listener(_this, 1, L2TPD_DEFAULT_LAYER2_LABEL,
- (struct sockaddr *)&sin6) != 0) {
- return 1;
- }
_this->id = l2tpd_id_seq++;
if ((_this->ctrl_map = hash_create(short_cmp, short_hash,
@@ -146,9 +125,6 @@ l2tpd_init(l2tpd *_this)
return 1;
}
}
- _this->ip4_allow = NULL;
-
- _this->require_ipsec = 1;
_this->purge_ipsec_sa = 1;
_this->state = L2TPD_STATE_INIT;
@@ -159,12 +135,11 @@ l2tpd_init(l2tpd *_this)
* Add a {@link :l2tpd_listener} to the {@link ::l2tpd L2TP daemon}
* @param _this {@link ::l2tpd L2TP daemon}
* @param idx index of the lisnter
- * @param label physical layer label (ex. "L2TP")
+ * @param tun_name tunnel name (ex. "L2TP")
* @param bindaddr bind address
*/
int
-l2tpd_add_listener(l2tpd *_this, int idx, const char *label,
- struct sockaddr *bindaddr)
+l2tpd_add_listener(l2tpd *_this, int idx, struct l2tp_conf *conf)
{
l2tpd_listener *plistener, *plsnr;
@@ -192,8 +167,8 @@ l2tpd_add_listener(l2tpd *_this, int idx, const char *label,
goto fail;
}
memset(plistener, 0, sizeof(l2tpd_listener));
- L2TPD_ASSERT(sizeof(plistener->bind) >= bindaddr->sa_len);
- memcpy(&plistener->bind, bindaddr, bindaddr->sa_len);
+ L2TPD_ASSERT(sizeof(plistener->bind) >= conf->address.ss_len);
+ memcpy(&plistener->bind, &conf->address, conf->address.ss_len);
if (plistener->bind.sin6.sin6_port == 0)
plistener->bind.sin6.sin6_port = htons(L2TPD_DEFAULT_UDP_PORT);
@@ -201,7 +176,8 @@ l2tpd_add_listener(l2tpd *_this, int idx, const char *label,
plistener->sock = -1;
plistener->self = _this;
plistener->index = idx;
- strlcpy(plistener->phy_label, label, sizeof(plistener->phy_label));
+ plistener->conf = conf;
+ strlcpy(plistener->tun_name, conf->name, sizeof(plistener->tun_name));
if (slist_add(&_this->listener, plistener) == NULL) {
l2tpd_log(_this, LOG_ERR, "slist_add() failed in %s: %m",
@@ -229,9 +205,6 @@ l2tpd_uninit(l2tpd *_this)
_this->ctrl_map = NULL;
}
- if (_this->ip4_allow != NULL)
- in_addr_range_list_remove_all(&_this->ip4_allow);
-
slist_itr_first(&_this->listener);
while (slist_itr_has_next(&_this->listener)) {
plsnr = slist_itr_next(&_this->listener);
@@ -243,7 +216,6 @@ l2tpd_uninit(l2tpd *_this)
event_del(&_this->ev_timeout); /* just in case */
_this->state = L2TPD_STATE_STOPPED;
- _this->config = NULL;
}
/** assign the call to the l2tpd */
@@ -284,21 +256,22 @@ l2tpd_release_call(l2tpd *_this, l2tp_call *call)
slist_add(&_this->free_session_id_list, (void *)(uintptr_t)call->id);
}
-
/* start l2tpd listner */
static int
-l2tpd_listener_start(l2tpd_listener *_this, char *ipsec_policy_in,
- char *ipsec_policy_out)
+l2tpd_listener_start(l2tpd_listener *_this)
{
- int sock, ival;
l2tpd *_l2tpd;
- char hbuf[NI_MAXHOST + NI_MAXSERV + 16];
- sock = -1;
+ int af, lvl, opt, sock, ival;
+ char hbuf[NI_MAXHOST + NI_MAXSERV + 16];
+
_l2tpd = _this->self;
+ sock = -1;
+ af = _this->bind.sin6.sin6_family;
+ lvl = (af == AF_INET)? IPPROTO_IP : IPPROTO_IPV6;
- if (_this->phy_label[0] == '\0')
- strlcpy(_this->phy_label, L2TPD_DEFAULT_LAYER2_LABEL,
- sizeof(_this->phy_label));
+ if (_this->tun_name[0] == '\0')
+ strlcpy(_this->tun_name, L2TPD_DEFAULT_LAYER2_LABEL,
+ sizeof(_this->tun_name));
if ((sock = socket(_this->bind.sin6.sin6_family,
SOCK_DGRAM, IPPROTO_UDP)) < 0) {
l2tpd_log(_l2tpd, LOG_ERR,
@@ -342,16 +315,17 @@ l2tpd_listener_start(l2tpd_listener *_this, char *ipsec_policy_in,
goto fail;
}
#else
- if (_this->bind.sin6.sin6_family == AF_INET) {
- ival = 1;
- if (setsockopt(sock, IPPROTO_IP, IP_RECVDSTADDR, &ival,
- sizeof(ival)) != 0) {
- l2tpd_log(_l2tpd, LOG_ERR,
- "setsockopt(,,IP_RECVDSTADDR) failed in %s(): %m",
- __func__);
- goto fail;
- }
+ opt = (af == AF_INET)? IP_RECVDSTADDR : IPV6_RECVPKTINFO;
+ ival = 1;
+ if (setsockopt(sock, lvl, opt, &ival, sizeof(ival)) != 0) {
+ l2tpd_log(_l2tpd, LOG_ERR,
+ "setsockopt(,,IP{,V6}_RECVDSTADDR) failed in %s(): %m",
+ __func__);
+ goto fail;
+ }
+#endif
#ifdef USE_SA_COOKIE
+ if (af == AF_INET) {
ival = 1;
if (setsockopt(sock, IPPROTO_IP, IP_IPSECFLOWINFO, &ival,
sizeof(ival)) != 0) {
@@ -360,72 +334,67 @@ l2tpd_listener_start(l2tpd_listener *_this, char *ipsec_policy_in,
__func__);
goto fail;
}
-#endif
- } else {
- ival = 1;
- if (setsockopt(sock, IPPROTO_IPV6, IPV6_RECVPKTINFO, &ival,
- sizeof(ival)) != 0) {
- l2tpd_log(_l2tpd, LOG_ERR,
- "setsockopt(,,IPV6_PKTINFO) failed in %s(): %m",
- __func__);
- goto fail;
- }
}
#endif
- if (_this->bind.sin6.sin6_family == AF_INET) {
#ifdef IP_PIPEX
- ival = 1;
- if (setsockopt(sock, IPPROTO_IP, IP_PIPEX, &ival,
- sizeof(ival)) != 0)
- l2tpd_log(_l2tpd, LOG_WARNING,
- "%s(): setsockopt(IP_PIPEX) failed: %m", __func__);
+ opt = (af == AF_INET)? IP_PIPEX : IPV6_PIPEX;
+ ival = 1;
+ if (setsockopt(sock, lvl, opt, &ival, sizeof(ival)) != 0)
+ l2tpd_log(_l2tpd, LOG_WARNING,
+ "%s(): setsockopt(IP{,V6}_PIPEX) failed: %m", __func__);
#endif
+ if (_this->conf->require_ipsec) {
#ifdef IP_IPSEC_POLICY
- if (ipsec_policy_in != NULL &&
- setsockopt(sock, IPPROTO_IP, IP_IPSEC_POLICY,
- ipsec_policy_in, ipsec_get_policylen(ipsec_policy_in))
- < 0) {
+ caddr_t ipsec_policy_in, ipsec_policy_out;
+
+ opt = (af == AF_INET)? IP_IPSEC_POLICY : IPV6_IPSEC_POLICY;
+ /*
+ * Note: ipsec_set_policy() will assign the buffer for
+ * yacc parser stack, however it never free.
+ * it cause memory leak (-2000byte).
+ */
+ if ((ipsec_policy_in = ipsec_set_policy(L2TPD_IPSEC_POLICY_IN,
+ strlen(L2TPD_IPSEC_POLICY_IN))) == NULL) {
+ l2tpd_log(_l2tpd, LOG_ERR,
+ "ipsec_set_policy(L2TPD_IPSEC_POLICY_IN) failed "
+ "at %s(): %s: %m", __func__, ipsec_strerror());
+ } else if (setsockopt(sock, lvl, opt, ipsec_policy_in,
+ ipsec_get_policylen(ipsec_policy_in)) < 0) {
l2tpd_log(_l2tpd, LOG_WARNING,
"setsockopt(,,IP_IPSEC_POLICY(in)) failed "
"in %s(): %m", __func__);
}
+ if ((ipsec_policy_out = ipsec_set_policy(L2TPD_IPSEC_POLICY_OUT,
+ strlen(L2TPD_IPSEC_POLICY_OUT))) == NULL) {
+ l2tpd_log(_l2tpd, LOG_ERR,
+ "ipsec_set_policy(L2TPD_IPSEC_POLICY_OUT) failed "
+ "at %s(): %s: %m", __func__, ipsec_strerror());
+ }
if (ipsec_policy_out != NULL &&
- setsockopt(sock, IPPROTO_IP, IP_IPSEC_POLICY,
- ipsec_policy_out, ipsec_get_policylen(ipsec_policy_out))
- < 0) {
+ setsockopt(sock, lvl, opt, ipsec_policy_out,
+ ipsec_get_policylen(ipsec_policy_out)) < 0) {
l2tpd_log(_l2tpd, LOG_WARNING,
"setsockopt(,,IP_IPSEC_POLICY(out)) failed "
"in %s(): %m", __func__);
}
-#endif
- } else {
-#ifdef IPV6_PIPEX
- ival = 1;
- if (setsockopt(sock, IPPROTO_IPV6, IPV6_PIPEX, &ival,
- sizeof(ival)) != 0)
+ if (ipsec_policy_in != NULL)
+ free(ipsec_policy_in);
+ if (ipsec_policy_out != NULL)
+ free(ipsec_policy_out);
+#elif defined(IP_ESP_TRANS_LEVEL)
+ opt = (af == AF_INET)
+ ? IP_ESP_TRANS_LEVEL : IPV6_ESP_TRANS_LEVEL;
+ ival = IPSEC_LEVEL_REQUIRE;
+ if (setsockopt(sock, lvl, opt, &ival, sizeof(ival)) != 0) {
l2tpd_log(_l2tpd, LOG_WARNING,
- "%s(): setsockopt(IPV6_PIPEX) failed: %m",
- __func__);
-#endif
-#ifdef IPV6_IPSEC_POLICY
- if (ipsec_policy_in != NULL &&
- setsockopt(sock, IPPROTO_IPV6, IPV6_IPSEC_POLICY,
- ipsec_policy_in, ipsec_get_policylen(ipsec_policy_in))
- < 0) {
- l2tpd_log(_l2tpd, LOG_WARNING,
- "setsockopt(,,IPV6_IPSEC_POLICY(in)) failed "
- "in %s(): %m", __func__);
- }
- if (ipsec_policy_out != NULL &&
- setsockopt(sock, IPPROTO_IPV6, IPV6_IPSEC_POLICY,
- ipsec_policy_out, ipsec_get_policylen(ipsec_policy_out))
- < 0) {
- l2tpd_log(_l2tpd, LOG_WARNING,
- "setsockopt(,,IPV6_IPSEC_POLICY(out)) failed "
+ "setsockopt(,,IP{,V6}_ESP_TRANS_LEVEL(out)) failed "
"in %s(): %m", __func__);
}
+#else
+#error IP_IPSEC_POLICY or IP_ESP_TRANS_LEVEL must be usable.
#endif
}
+
_this->sock = sock;
event_set(&_this->ev_sock, _this->sock, EV_READ | EV_PERSIST,
@@ -434,7 +403,7 @@ l2tpd_listener_start(l2tpd_listener *_this, char *ipsec_policy_in,
l2tpd_log(_l2tpd, LOG_INFO, "Listening %s/udp (L2TP LNS) [%s]",
addrport_tostring((struct sockaddr *)&_this->bind,
- _this->bind.sin6.sin6_len, hbuf, sizeof(hbuf)), _this->phy_label);
+ _this->bind.sin6.sin6_len, hbuf, sizeof(hbuf)), _this->tun_name);
return 0;
fail:
@@ -449,12 +418,9 @@ int
l2tpd_start(l2tpd *_this)
{
int rval;
- caddr_t ipsec_policy_in, ipsec_policy_out;
l2tpd_listener *plsnr;
rval = 0;
- ipsec_policy_in = NULL;
- ipsec_policy_out = NULL;
L2TPD_ASSERT(_this->state == L2TPD_STATE_INIT);
if (_this->state != L2TPD_STATE_INIT) {
@@ -462,55 +428,17 @@ l2tpd_start(l2tpd *_this)
"state.");
return -1;
}
- if (_this->require_ipsec != 0) {
-#if 0
- /*
- * Note: ipsec_set_policy() will assign the buffer for
- * yacc parser stack, however it never free.
- * it cause memory leak (-2000byte).
- */
- if ((ipsec_policy_in = ipsec_set_policy(L2TPD_IPSEC_POLICY_IN,
- strlen(L2TPD_IPSEC_POLICY_IN))) == NULL) {
- l2tpd_log(_this, LOG_ERR,
- "ipsec_set_policy(L2TPD_IPSEC_POLICY_IN) failed "
- "at %s(): %s: %m", __func__, ipsec_strerror());
- goto fail;
- }
- if ((ipsec_policy_out = ipsec_set_policy(L2TPD_IPSEC_POLICY_OUT,
- strlen(L2TPD_IPSEC_POLICY_OUT))) == NULL) {
- l2tpd_log(_this, LOG_ERR,
- "ipsec_set_policy(L2TPD_IPSEC_POLICY_OUT) failed "
- "at %s(): %s: %m", __func__, ipsec_strerror());
- goto fail;
- }
-#endif
- }
slist_itr_first(&_this->listener);
while (slist_itr_has_next(&_this->listener)) {
plsnr = slist_itr_next(&_this->listener);
- rval |= l2tpd_listener_start(plsnr, ipsec_policy_in,
- ipsec_policy_out);
+ rval |= l2tpd_listener_start(plsnr);
}
- if (ipsec_policy_in != NULL)
- free(ipsec_policy_in);
- if (ipsec_policy_out != NULL)
- free(ipsec_policy_out);
-
if (rval == 0)
_this->state = L2TPD_STATE_RUNNING;
return rval;
-#if 0
-fail:
-#endif
- if (ipsec_policy_in != NULL)
- free(ipsec_policy_in);
- if (ipsec_policy_out != NULL)
- free(ipsec_policy_out);
-
- return 1;
}
/* stop l2tp lisnter */
@@ -619,138 +547,40 @@ l2tpd_stop(l2tpd *_this)
/*
* Configuration
*/
-#define CFG_KEY(p, s) config_key_prefix((p), (s))
-#define VAL_SEP " \t\r\n"
-
-CONFIG_FUNCTIONS(l2tpd_config, l2tpd, config);
-PREFIXED_CONFIG_FUNCTIONS(l2tp_ctrl_config, l2tp_ctrl, l2tpd->config,
- phy_label);
-
int
-l2tpd_reload(l2tpd *_this, struct properties *config, const char *name,
- int default_enabled)
+l2tpd_reload(l2tpd *_this, struct l2tp_confs *l2tp_conf)
{
- int i, do_start, aierr;
- const char *val;
- char *tok, *cp, buf[L2TPD_CONFIG_BUFSIZ], *label;
- struct addrinfo *ai;
-
- _this->config = config;
- do_start = 0;
- if (l2tpd_config_str_equal(_this, CFG_KEY(name, "enabled"), "true",
- default_enabled)) {
- /* care the case false-true flapping */
- if (l2tpd_is_shutting_down(_this))
- l2tpd_stop_immediatly(_this);
- if (l2tpd_is_stopped(_this))
- do_start = 1;
- } else {
- if (!l2tpd_is_stopped(_this))
- l2tpd_stop(_this);
- return 0;
- }
- if (do_start && l2tpd_init(_this) != 0)
- return 1;
- _this->config = config;
-
- /* default value */
- gethostname(_this->default_hostname, sizeof(_this->default_hostname));
-
- _this->ctrl_in_pktdump = l2tpd_config_str_equal(_this,
- "log.l2tp.ctrl.in.pktdump", "true", 0);
- _this->data_in_pktdump = l2tpd_config_str_equal(_this,
- "log.l2tp.data.in.pktdump", "true", 0);
- _this->ctrl_out_pktdump = l2tpd_config_str_equal(_this,
- "log.l2tp.ctrl.out.pktdump", "true", 0);
- _this->data_out_pktdump = l2tpd_config_str_equal(_this,
- "log.l2tp.data.out.pktdump", "true", 0);
- _this->phy_label_with_ifname = l2tpd_config_str_equal(_this,
- CFG_KEY(name, "label_with_ifname"), "true", 0);
-
- /* parse ip4_allow */
- in_addr_range_list_remove_all(&_this->ip4_allow);
- val = l2tpd_config_str(_this, CFG_KEY(name, "ip4_allow"));
- if (val != NULL) {
- if (strlen(val) >= sizeof(buf)) {
- l2tpd_log(_this, LOG_ERR, "configuration error at "
- "l2tpd.ip4_allow: too long");
- return 1;
- }
- strlcpy(buf, val, sizeof(buf));
- for (cp = buf; (tok = strsep(&cp, VAL_SEP)) != NULL;) {
- if (*tok == '\0')
- continue;
- if (in_addr_range_list_add(&_this->ip4_allow, tok)
- != 0) {
- l2tpd_log(_this, LOG_ERR,
- "configuration error at "
- "l2tpd.ip4_allow: %s", tok);
- return 1;
- }
- }
- }
+ int i;
+ struct l2tp_conf *conf;
+ l2tpd_listener *listener;
- if (do_start) {
- /*
- * in the case of 1) cold-booted and 2) pptpd.enable
- * toggled "false" to "true" do this, because we can
- * assume that all pptpd listner are initialized.
- */
- val = l2tpd_config_str(_this, CFG_KEY(name, "listener"));
- if (val != NULL) {
- if (strlen(val) >= sizeof(buf)) {
- l2tpd_log(_this, LOG_ERR,
- "configuration error at %s: too long",
- CFG_KEY(name, "listener"));
- return 1;
- }
- strlcpy(buf, val, sizeof(buf));
-
- label = NULL;
- /* it can accept multiple values with tab/space
- * separation */
- for (i = 0, cp = buf;
- (tok = strsep(&cp, VAL_SEP)) != NULL;) {
- if (*tok == '\0')
- continue;
- if (label == NULL) {
- label = tok;
- continue;
- }
- if ((aierr = addrport_parse(tok, IPPROTO_UDP,
- &ai)) != 0) {
- l2tpd_log(_this, LOG_ERR,
- "configuration error at "
- "l2tpd.listener: %s: %s", label,
- gai_strerror(aierr));
- label = NULL;
- return 1;
- }
- if (l2tpd_add_listener(_this, i, label,
- ai->ai_addr) != 0) {
- freeaddrinfo(ai);
- label = NULL;
+ if (slist_length(&_this->listener) > 0) {
+ /*
+ * TODO: add / remove / restart listener.
+ */
+ slist_itr_first(&_this->listener);
+ while (slist_itr_has_next(&_this->listener)) {
+ listener = slist_itr_next(&_this->listener);
+ TAILQ_FOREACH(conf, l2tp_conf, entry) {
+ if (strcmp(listener->tun_name,
+ conf->name) == 0) {
+ listener->conf = conf;
break;
}
- freeaddrinfo(ai);
- label = NULL;
- i++;
- }
- if (label != NULL) {
- l2tpd_log(_this, LOG_ERR, "configuration "
- "error at l2tpd.listener: %s", label);
- return 1;
}
}
- _this->purge_ipsec_sa = l2tpd_config_str_equal(_this,
- CFG_KEY(name, "purge_ipsec_sa"), "true", 1);
- _this->require_ipsec = l2tpd_config_str_equal(_this,
- CFG_KEY(name, "require_ipsec"), "true", 1);
- if (l2tpd_start(_this) != 0)
- return 1;
+ return 0;
}
+ if (l2tpd_init(_this) != 0)
+ return -1;
+ i = 0;
+ TAILQ_FOREACH(conf, l2tp_conf, entry)
+ l2tpd_add_listener(_this, i++, conf);
+ if (l2tpd_start(_this) != 0)
+ return -1;
+
return 0;
}
@@ -821,23 +651,12 @@ l2tpd_io_event(int fd, short evtype, void *ctx)
#else
nat_t = NULL;
#endif
- /*
- * XXX check source address when NAT-T
- */
- if (in_addr_range_list_includes(
- &_l2tpd->ip4_allow,
- &((struct sockaddr_in *)&peer)->sin_addr))
- l2tp_ctrl_input(_l2tpd, _this->index,
- (struct sockaddr *)&peer,
- (struct sockaddr *)&sock, nat_t,
- buf, sz);
- else
- l2tpd_log_access_deny(_l2tpd,
- "not allowed by acl.",
- (struct sockaddr *)&peer);
+ l2tp_ctrl_input(_l2tpd, _this->index,
+ (struct sockaddr *)&peer,
+ (struct sockaddr *)&sock, nat_t,
+ buf, sz);
break;
case AF_INET6:
- /* XXX source address restriction in IPv6? */
l2tp_ctrl_input(_l2tpd, _this->index,
(struct sockaddr *)&peer,
(struct sockaddr *)&sock, NULL,
diff --git a/usr.sbin/npppd/npppd/Makefile b/usr.sbin/npppd/npppd/Makefile
index 80e89f29b71..9ac946670eb 100644
--- a/usr.sbin/npppd/npppd/Makefile
+++ b/usr.sbin/npppd/npppd/Makefile
@@ -1,46 +1,42 @@
-# $OpenBSD: Makefile,v 1.12 2012/07/16 18:05:36 markus Exp $
+# $OpenBSD: Makefile,v 1.13 2012/09/18 13:14:08 yasuoka Exp $
NPPPD_COMMON_DIR= ${.CURDIR}/../common
PROG= npppd
-NOMAN= noman
-#MAN= npppd.8 npppd.conf.5 npppd-users.csv.5
+MAN= npppd.8 npppd.conf.5 npppd-users.5
CPPFLAGS+= -I${NPPPD_COMMON_DIR} -I${.CURDIR}
-SRCS= ccp.c chap.c chap_ms.c fsm.c ipcp.c lcp.c
-SRCS+= mppe.c pap.c ppp.c
+CPPFLAGS+= -I${.CURDIR}/../pptp -I${.CURDIR}/../l2tp -I${.CURDIR}/../pppoe
+SRCS= ccp.c chap.c chap_ms.c fsm.c ipcp.c lcp.c mppe.c pap.c ppp.c
SRCS+= npppd.c npppd_config.c npppd_subr.c npppd_auth.c npppd_iface.c
-SRCS+= config_helper.c slist.c hash.c properties.c bytebuf.c
-SRCS+= debugutil.c csvreader.c net_utils.c radish.c time_utils.c
-SRCS+= npppd_pool.c addr_range.c
-SRCS+= radius+.c radius_req.c npppd_radius.c
-SRCS+= recvfromto.c
-SRCS+= privsep.c
-#SRCS+= ipsec_util.c
-SRCS+= npppd_ctl.c
-
-CPPFLAGS+= -DUSE_NPPPD_PPTP -I${.CURDIR}/../pptp
+SRCS+= npppd_pool.c radius+.c radius_req.c npppd_radius.c npppd_ctl.c
+SRCS+= privsep.c parse.y log.c
+SRCS+= debugutil.c net_utils.c radish.c time_utils.c slist.c hash.c
+SRCS+= bytebuf.c addr_range.c recvfromto.c
+
+CPPFLAGS+= -DUSE_NPPPD_PPTP
SRCS+= pptp_call.c pptp_ctrl.c pptp_subr.c pptpd.c
.PATH: ${.CURDIR}/../pptp
-CPPFLAGS+= -DUSE_NPPPD_L2TP -I${.CURDIR}/../l2tp
+CPPFLAGS+= -DUSE_NPPPD_L2TP
SRCS+= l2tp_call.c l2tp_ctrl.c l2tp_subr.c l2tpd.c
.PATH: ${.CURDIR}/../l2tp
-CPPFLAGS+= -DUSE_NPPPD_PPPOE -I${.CURDIR}/../pppoe
+CPPFLAGS+= -DUSE_NPPPD_PPPOE
SRCS+= pppoe_session.c pppoed.c
.PATH: ${.CURDIR}/../pppoe
CPPFLAGS+= -D__COPYRIGHT\(x\)= -D__RCSID\(x\)=
-CPPFLAGS+= -DNPPPD_MAX_IFACE=8
+CPPFLAGS+= -DNPPPD_MAX_IFACE=8 -DNPPPD_MAX_POOL=8
CPPFLAGS+= -DUSE_NPPPD_MPPE
CPPFLAGS+= -DUSE_NPPPD_PIPEX
CPPFLAGS+= -DUSE_NPPPD_RADIUS
CPPFLAGS+= -DUSE_SA_COOKIE
+CPPFLAGS+= -DUSE_SA_COOKIE
CPPFLAGS+= -DGENERIC_USE -DRADISH
-LDADD+= -levent -lcrypto
-DPADD+= ${LIBEVENT} ${LIBCRYPTO}
+LDADD+= -levent -lcrypto -ly
+DPADD+= ${LIBEVENT} ${LIBCRYPTO} ${LIBY}
.ifdef DEBUG
CPPFLAGS+= -DDEBUG=1
diff --git a/usr.sbin/npppd/npppd/ccp.c b/usr.sbin/npppd/npppd/ccp.c
index 9cc4a532bc9..12bd39e62ff 100644
--- a/usr.sbin/npppd/npppd/ccp.c
+++ b/usr.sbin/npppd/npppd/ccp.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ccp.c,v 1.5 2012/05/08 13:15:11 yasuoka Exp $ */
+/* $OpenBSD: ccp.c,v 1.6 2012/09/18 13:14:08 yasuoka Exp $ */
/*-
* Copyright (c) 2009 Internet Initiative Japan Inc.
@@ -28,7 +28,7 @@
/**@file
* This file provides functions for CCP (Compression Control Protocol).
* MPPE is supported as a CCP option.
- * $Id: ccp.c,v 1.5 2012/05/08 13:15:11 yasuoka Exp $
+ * $Id: ccp.c,v 1.6 2012/09/18 13:14:08 yasuoka Exp $
*/
#include <sys/types.h>
#include <sys/socket.h>
@@ -87,6 +87,8 @@ static struct fsm_callbacks ccp_callbacks = {
void
ccp_init(ccp *_this, npppd_ppp *ppp)
{
+ struct tunnconf *conf;
+
memset(_this, 0, sizeof(ccp));
_this->ppp = ppp;
@@ -96,10 +98,14 @@ ccp_init(ccp *_this, npppd_ppp *ppp)
fsm_init(&_this->fsm);
- PPP_FSM_CONFIG(&_this->fsm, timeouttime, "ccp.timeout");
- PPP_FSM_CONFIG(&_this->fsm, maxconfreqtransmits,"ccp.max_configure");
- PPP_FSM_CONFIG(&_this->fsm, maxtermtransmits, "ccp.max_terminate");
- PPP_FSM_CONFIG(&_this->fsm, maxnakloops, "ccp.max_nak_loop");
+ conf = ppp_get_tunnconf(ppp);
+ PPP_FSM_CONFIG(&_this->fsm, timeouttime, conf->ccp_timeout);
+ PPP_FSM_CONFIG(&_this->fsm, maxconfreqtransmits,
+ conf->ccp_max_configure);
+ PPP_FSM_CONFIG(&_this->fsm, maxtermtransmits,
+ conf->ccp_max_terminate);
+ PPP_FSM_CONFIG(&_this->fsm, maxnakloops,
+ conf->ccp_max_nak_loop);
}
/** Request Command Interpreter */
diff --git a/usr.sbin/npppd/npppd/chap.c b/usr.sbin/npppd/npppd/chap.c
index f17fa53e229..9265a3559b4 100644
--- a/usr.sbin/npppd/npppd/chap.c
+++ b/usr.sbin/npppd/npppd/chap.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: chap.c,v 1.7 2012/05/08 13:18:37 yasuoka Exp $ */
+/* $OpenBSD: chap.c,v 1.8 2012/09/18 13:14:08 yasuoka Exp $ */
/*-
* Copyright (c) 2009 Internet Initiative Japan Inc.
@@ -36,7 +36,7 @@
* </ul></p>
*/
/* RFC 1994, 2433 */
-/* $Id: chap.c,v 1.7 2012/05/08 13:18:37 yasuoka Exp $ */
+/* $Id: chap.c,v 1.8 2012/09/18 13:14:08 yasuoka Exp $ */
#include <sys/types.h>
#include <sys/param.h>
#include <sys/socket.h>
@@ -129,7 +129,7 @@ static void chap_log (chap *, uint32_t, const char *, ...) __printflike(3
void
chap_init(chap *_this, npppd_ppp *ppp)
{
- const char *strval;
+ struct tunnconf *conf;
CHAP_ASSERT(ppp != NULL);
CHAP_ASSERT(_this != NULL);
@@ -137,10 +137,12 @@ chap_init(chap *_this, npppd_ppp *ppp)
memset(_this, 0, sizeof(chap));
_this->ppp = ppp;
- if ((strval = npppd_config_str(ppp->pppd, "chap.name")) == NULL)
+ conf = ppp_get_tunnconf(ppp);
+
+ if (conf->chap_name == NULL)
gethostname(_this->myname, sizeof(_this->myname));
else
- strlcpy(_this->myname, strval, sizeof(_this->myname));
+ strlcpy(_this->myname, conf->chap_name, sizeof(_this->myname));
_this->timerctx.ctx = _this;
_this->state = CHAP_STATE_INITIAL;
@@ -188,7 +190,7 @@ chap_start(chap *_this)
#ifdef USE_NPPPD_MPPE
/* The peer must use MS-CHAP-V2 as the type */
- if (MPPE_REQUIRED(_this->ppp) &&
+ if (MPPE_IS_REQUIRED(_this->ppp) &&
_this->type != PPP_AUTH_CHAP_MS_V2) {
chap_log(_this, LOG_ALERT,
"mppe is required but try to start chap "
@@ -508,7 +510,7 @@ chap_proxy_authen_prepare(chap *_this, dialin_proxy_info *dpi)
_this->pktid = dpi->auth_id;
#ifdef USE_NPPPD_MPPE
- if (MPPE_REQUIRED(_this->ppp) &&
+ if (MPPE_IS_REQUIRED(_this->ppp) &&
_this->type != PPP_AUTH_CHAP_MS_V2) {
chap_log(_this, LOG_ALERT,
"mppe is required but try to start chap "
@@ -760,8 +762,8 @@ chap_radius_authenticate(chap *_this, int id, char *username,
if ((radpkt = radius_new_request_packet(RADIUS_CODE_ACCESS_REQUEST))
== NULL)
goto fail;
- if (radius_prepare(rad_setting, _this, &radctx, chap_radius_response,
- _this->ppp->auth_timeout) != 0) {
+ if (radius_prepare(rad_setting, _this, &radctx, chap_radius_response)
+ != 0) {
radius_delete_packet(radpkt);
goto fail;
}
diff --git a/usr.sbin/npppd/npppd/ipcp.c b/usr.sbin/npppd/npppd/ipcp.c
index 94d2544f36a..a6b33dc34ca 100644
--- a/usr.sbin/npppd/npppd/ipcp.c
+++ b/usr.sbin/npppd/npppd/ipcp.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ipcp.c,v 1.4 2012/05/08 13:15:11 yasuoka Exp $ */
+/* $OpenBSD: ipcp.c,v 1.5 2012/09/18 13:14:08 yasuoka Exp $ */
/*-
* Copyright (c) 2009 Internet Initiative Japan Inc.
@@ -32,7 +32,7 @@
/*
* RFC 1332, 1877
*/
-/* $Id: ipcp.c,v 1.4 2012/05/08 13:15:11 yasuoka Exp $ */
+/* $Id: ipcp.c,v 1.5 2012/09/18 13:14:08 yasuoka Exp $ */
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/time.h>
@@ -105,6 +105,8 @@ static struct fsm_callbacks ipcp_callbacks = {
void
ipcp_init(ipcp *_this, npppd_ppp *ppp)
{
+ struct tunnconf *conf;
+
memset(_this, 0, sizeof(ipcp));
_this->ppp = ppp;
@@ -114,10 +116,15 @@ ipcp_init(ipcp *_this, npppd_ppp *ppp)
_this->fsm.callbacks = &ipcp_callbacks;
_this->fsm.protocol = PPP_PROTO_NCP | NCP_IPCP;
- PPP_FSM_CONFIG(&_this->fsm, timeouttime, "ipcp.timeout");
- PPP_FSM_CONFIG(&_this->fsm, maxconfreqtransmits,"ipcp.max_configure");
- PPP_FSM_CONFIG(&_this->fsm, maxtermtransmits, "ipcp.max_terminate");
- PPP_FSM_CONFIG(&_this->fsm, maxnakloops, "ipcp.max_nak_loop");
+
+ conf = ppp_get_tunnconf(ppp);
+ PPP_FSM_CONFIG(&_this->fsm, timeouttime, conf->ipcp_timeout);
+ PPP_FSM_CONFIG(&_this->fsm, maxconfreqtransmits,
+ conf->ipcp_max_configure);
+ PPP_FSM_CONFIG(&_this->fsm, maxtermtransmits,
+ conf->ipcp_max_terminate);
+ PPP_FSM_CONFIG(&_this->fsm, maxnakloops,
+ conf->ipcp_max_nak_loop);
}
static void
diff --git a/usr.sbin/npppd/npppd/lcp.c b/usr.sbin/npppd/npppd/lcp.c
index 278d94b3c0a..12bdd0220b5 100644
--- a/usr.sbin/npppd/npppd/lcp.c
+++ b/usr.sbin/npppd/npppd/lcp.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: lcp.c,v 1.7 2012/05/08 13:26:12 yasuoka Exp $ */
+/* $OpenBSD: lcp.c,v 1.8 2012/09/18 13:14:08 yasuoka Exp $ */
/*-
* Copyright (c) 2009 Internet Initiative Japan Inc.
@@ -25,7 +25,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
-/* $Id: lcp.c,v 1.7 2012/05/08 13:26:12 yasuoka Exp $ */
+/* $Id: lcp.c,v 1.8 2012/09/18 13:14:08 yasuoka Exp $ */
/**@file
* This file provides LCP related functions.
*<pre>
@@ -115,6 +115,8 @@ static struct fsm_callbacks lcp_callbacks = {
void
lcp_init(lcp *_this, npppd_ppp *ppp)
{
+ struct tunnconf *conf;
+
fsm_init(&_this->fsm);
_this->fsm.ppp = ppp;
@@ -127,19 +129,23 @@ lcp_init(lcp *_this, npppd_ppp *ppp)
_this->recv_reqs = 0;
_this->magic_number = ((0xffff & random()) << 16) | (0xffff & random());
- PPP_FSM_CONFIG(&_this->fsm, timeouttime, "lcp.timeout");
- PPP_FSM_CONFIG(&_this->fsm, maxconfreqtransmits,"lcp.max_configure");
- PPP_FSM_CONFIG(&_this->fsm, maxtermtransmits, "lcp.max_terminate");
- PPP_FSM_CONFIG(&_this->fsm, maxnakloops, "lcp.max_nak_loop");
+ conf = ppp_get_tunnconf(ppp);
+ PPP_FSM_CONFIG(&_this->fsm, timeouttime, conf->lcp_timeout);
+ PPP_FSM_CONFIG(&_this->fsm, maxconfreqtransmits,
+ conf->lcp_max_configure);
+ PPP_FSM_CONFIG(&_this->fsm, maxtermtransmits,
+ conf->lcp_max_terminate);
+ PPP_FSM_CONFIG(&_this->fsm, maxnakloops,
+ conf->lcp_max_nak_loop);
- /*
- * PPTP and L2TP are able to detect lost carrier, so LCP ECHO is off
- * by default.
- */
- _this->echo_interval = 0;
_this->echo_failures = 0;
- _this->echo_max_retries = 0;
-
+ if (!conf->lcp_keepalive)
+ _this->echo_interval = 0;
+ else {
+ _this->echo_interval = conf->lcp_keepalive_interval;
+ _this->echo_retry_interval = conf->lcp_keepalive_retry_interval;
+ _this->echo_max_retries = conf->lcp_keepalive_max_retries;
+ }
_this->auth_order[0] = -1;
}
@@ -1040,58 +1046,26 @@ lcp_ext(fsm *f, int code, int id, u_char *inp, int inlen)
static void
lcp_load_authconfig(fsm *f)
{
- int i, f_none;
- const char *val;
- lcp *_this;
+ int i;
+ lcp *_this;
+ struct tunnconf *conf;
- _this = &f->ppp->lcp;
i = 0;
- f_none = 0;
- if ((val = ppp_config_str(f->ppp, "auth.method")) != NULL) {
- char *authp0, *authp, authbuf[512];
-
- strlcpy(authbuf, val, sizeof(authbuf));
- authp0 = authbuf;
- while ((authp = strsep(&authp0, SPACE)) != NULL &&
- i < countof(_this->auth_order) - 1) {
- if (strcasecmp("none", authp) == 0) {
- f_none = 1;
- } else if (strcasecmp("PAP", authp) == 0) {
- _this->auth_order[i++] = PPP_AUTH_PAP;
- psm_opt_set_enabled(_this, pap, 1);
- } else if (strcasecmp("CHAP", authp) == 0 ||
- strcasecmp("MD5CHAP", authp) == 0) {
- _this->auth_order[i++] =
- PPP_AUTH_CHAP_MD5;
- psm_opt_set_enabled(_this, chap, 1);
- } else if (strcasecmp("CHAPMS", authp) == 0 ||
- strcasecmp("MSCHAP", authp) == 0) {
-#if 0 /* MS-CHAP is not supported. */
- _this->auth_order[i++] =
- PPP_AUTH_CHAP_MS;
- psm_opt_set_enabled(_this, chapms, 1);
-#endif
- } else if (strcasecmp("CHAPMSV2", authp) == 0 ||
- strcasecmp("MSCHAPV2", authp) == 0 ||
- strcasecmp("CHAPMS_V2", authp) == 0 ||
- strcasecmp("MSCHAP_V2", authp) == 0) {
- _this->auth_order[i++] = PPP_AUTH_CHAP_MS_V2;
- psm_opt_set_enabled(_this,chapms_v2, 1);
-#ifdef USE_NPPPD_EAP_RADIUS
- } else if (strcasecmp("EAP-RADIUS", authp) == 0) {
- _this->auth_order[i++] = PPP_AUTH_EAP;
- psm_opt_set_enabled(_this, eap, 1);
-#endif
- } else
- ppp_log(f->ppp, LOG_WARNING,
- "unknown auth protocol: %s", authp);
- }
+ _this = &f->ppp->lcp;
+ conf = ppp_get_tunnconf(f->ppp);
+ if ((conf->auth_methods & NPPPD_AUTH_METHODS_MSCHAPV2) != 0) {
+ _this->auth_order[i++] = PPP_AUTH_CHAP_MS_V2;
+ psm_opt_set_enabled(_this,chapms_v2, 1);
+ }
+ if ((conf->auth_methods & NPPPD_AUTH_METHODS_CHAP) != 0) {
+ _this->auth_order[i++] = PPP_AUTH_CHAP_MD5;
+ psm_opt_set_enabled(_this, chap, 1);
}
- if (f_none && i != 0) {
- ppp_log(f->ppp, LOG_WARNING, "auth protocol 'none' "
- "must be specified individually");
- f_none = 0;
+ if ((conf->auth_methods & NPPPD_AUTH_METHODS_PAP) != 0) {
+ _this->auth_order[i++] = PPP_AUTH_PAP;
+ psm_opt_set_enabled(_this, pap, 1);
}
+
_this->auth_order[i] = -1;
}
diff --git a/usr.sbin/npppd/npppd/log.c b/usr.sbin/npppd/npppd/log.c
new file mode 100644
index 00000000000..b0f67d6428d
--- /dev/null
+++ b/usr.sbin/npppd/npppd/log.c
@@ -0,0 +1,158 @@
+/* $OpenBSD: log.c,v 1.1 2012/09/18 13:14:08 yasuoka Exp $ */
+
+/*
+ * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
+ * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
+ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+
+#include <errno.h>
+#include <netdb.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <syslog.h>
+#include <time.h>
+
+#include "debugutil.h"
+#include "npppd.h"
+
+int debug;
+extern int debugsyslog;
+
+void logit(int, const char *, ...);
+
+void
+log_init(int n_debug)
+{
+ extern char *__progname;
+
+ debug = n_debug;
+
+ if (!debug)
+ openlog(__progname, LOG_PID | LOG_NDELAY, LOG_DAEMON);
+
+ tzset();
+}
+
+void
+logit(int pri, const char *fmt, ...)
+{
+ va_list ap;
+
+ va_start(ap, fmt);
+ vlog(pri, fmt, ap);
+ va_end(ap);
+}
+
+void
+vlog(int pri, const char *fmt, va_list ap)
+{
+ vlog_printf(pri, fmt, ap);
+}
+
+
+void
+log_warn(const char *emsg, ...)
+{
+ char *nfmt;
+ va_list ap;
+
+ /* best effort to even work in out of memory situations */
+ if (emsg == NULL)
+ logit(LOG_CRIT, "%s", strerror(errno));
+ else {
+ va_start(ap, emsg);
+
+ if (asprintf(&nfmt, "%s: %s", emsg, strerror(errno)) == -1) {
+ /* we tried it... */
+ vlog(LOG_CRIT, emsg, ap);
+ logit(LOG_CRIT, "%s", strerror(errno));
+ } else {
+ vlog(LOG_CRIT, nfmt, ap);
+ free(nfmt);
+ }
+ va_end(ap);
+ }
+}
+
+void
+log_warnx(const char *emsg, ...)
+{
+ va_list ap;
+
+ va_start(ap, emsg);
+ vlog(LOG_CRIT, emsg, ap);
+ va_end(ap);
+}
+
+void
+log_info(const char *emsg, ...)
+{
+ va_list ap;
+
+ va_start(ap, emsg);
+ vlog(LOG_INFO, emsg, ap);
+ va_end(ap);
+}
+
+void
+log_debug(const char *emsg, ...)
+{
+ va_list ap;
+
+ if (debug || debugsyslog) {
+ va_start(ap, emsg);
+ vlog(LOG_DEBUG, emsg, ap);
+ va_end(ap);
+ }
+}
+
+void
+fatal(const char *emsg)
+{
+ if (emsg == NULL)
+ logit(LOG_CRIT, "fatal: %s", strerror(errno));
+ else
+ if (errno)
+ logit(LOG_CRIT, "fatal: %s: %s",
+ emsg, strerror(errno));
+ else
+ logit(LOG_CRIT, "fatal: %s", emsg);
+
+ exit(1);
+}
+
+void
+fatalx(const char *emsg)
+{
+ errno = 0;
+ fatal(emsg);
+}
+
+const char *
+log_sockaddr(struct sockaddr *sa)
+{
+ static char buf[NI_MAXHOST];
+
+ if (getnameinfo(sa, SA_LEN(sa), buf, sizeof(buf), NULL, 0,
+ NI_NUMERICHOST))
+ return ("(unknown)");
+ else
+ return (buf);
+}
diff --git a/usr.sbin/npppd/npppd/mppe.c b/usr.sbin/npppd/npppd/mppe.c
index f02a6d26881..46994c174b0 100644
--- a/usr.sbin/npppd/npppd/mppe.c
+++ b/usr.sbin/npppd/npppd/mppe.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: mppe.c,v 1.7 2012/05/08 13:18:37 yasuoka Exp $ */
+/* $OpenBSD: mppe.c,v 1.8 2012/09/18 13:14:08 yasuoka Exp $ */
/*-
* Copyright (c) 2009 Internet Initiative Japan Inc.
@@ -25,7 +25,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
-/* $Id: mppe.c,v 1.7 2012/05/08 13:18:37 yasuoka Exp $ */
+/* $Id: mppe.c,v 1.8 2012/09/18 13:14:08 yasuoka Exp $ */
/**@file
*
* The implementation of MPPE(Microsoft Point-To-Point Encryption Protocol)
@@ -100,8 +100,7 @@ static void GetNewKeyFromSHA __P((u_char *, u_char *, int, u_char *));
void
mppe_init(mppe *_this, npppd_ppp *ppp)
{
- const char *sval;
- int ival;
+ struct tunnconf *conf;
MPPE_ASSERT(ppp != NULL);
MPPE_ASSERT(_this != NULL);
@@ -112,59 +111,35 @@ mppe_init(mppe *_this, npppd_ppp *ppp)
_this->mode_auto = 1;
_this->mode_stateless = 0;
- _this->keylen_auto = 1;
- _this->keylenbits = 128;
-
- _this->enabled = (ppp_config_str_equal(_this->ppp,
- "mppe.disabled", "true", 0) != 0)? 0 : 1;
+ conf = ppp_get_tunnconf(ppp);
+ _this->enabled = conf->mppe_yesno;
if (_this->enabled == 0)
goto mppe_config_done;
- _this->required = (ppp_config_str_equal(_this->ppp,
- "mppe.required", "true", 0) != 0)? 1 : 0;
+ _this->required = conf->mppe_required;
if (_this->required == 0)
goto mppe_config_done;
- sval = ppp_config_str(_this->ppp, "mppe.mode");
- if (sval != NULL) {
- if (strcmp(sval, "stateless") == 0) {
- _this->mode_auto = 0;
- _this->mode_stateless = 1;
- } else if (strcmp(sval, "stateful") == 0) {
- _this->mode_auto = 0;
- _this->mode_stateless = 0;
- } else if (strcmp(sval, "auto") == 0 ||
- strcmp(sval, "*") == 0) {
- /* no changes from default. */
- } else {
- mppe_log(_this, LOG_WARNING,
- "configuration \"mppe.mode\" has bad value");
- _this->mode_auto = 1;
- _this->mode_stateless = 0;
- }
- }
- if (ppp_config_str_equal(_this->ppp, "mppe.keylen", "auto", 0) ||
- ppp_config_str_equal(_this->ppp, "mppe.keylen", "*", 0)) {
- /* no changes from default. */
- } else {
- ival = ppp_config_int(_this->ppp, "mppe.keylen", -1);
- if (ival != -1) {
- switch (ival) {
- case 40:
- case 56:
- case 128:
- _this->keylenbits = ival;
- _this->keylen_auto = 0;
- break;
- default:
- mppe_log(_this, LOG_WARNING,
- "configuration \"mppe.keylen\" has bad "
- "value");
- }
- }
+ if (conf->mppe_keystate == (NPPPD_MPPE_STATEFUL|NPPPD_MPPE_STATELESS)) {
+ /* no need to change from default. */
+ } else if (conf->mppe_keystate == NPPPD_MPPE_STATELESS) {
+ _this->mode_auto = 0;
+ _this->mode_stateless = 1;
+ } else if (conf->mppe_keystate == NPPPD_MPPE_STATEFUL) {
+ _this->mode_auto = 0;
+ _this->mode_stateless = 0;
}
+
+ _this->keylenbits = 0;
+ if ((conf->mppe_keylen & NPPPD_MPPE_40BIT) != 0)
+ _this->keylenbits |= CCP_MPPE_NT_40bit;
+ if ((conf->mppe_keylen & NPPPD_MPPE_56BIT) != 0);
+ _this->keylenbits |= CCP_MPPE_NT_56bit;
+ if ((conf->mppe_keylen & NPPPD_MPPE_128BIT) != 0)
+ _this->keylenbits |= CCP_MPPE_NT_128bit;
+
mppe_config_done:
/* nothing */;
}
@@ -280,30 +255,16 @@ uint32_t
mppe_create_our_bits(mppe *_this, uint32_t peer_bits)
{
uint32_t our_bits;
+
/* default proposal */
- our_bits = CCP_MPPE_NT_128bit;
-
- if (_this->keylen_auto == 0) {
- switch (_this->keylenbits) {
- case 40:
- our_bits = CCP_MPPE_NT_40bit; break;
- case 56:
- our_bits = CCP_MPPE_NT_56bit; break;
- case 128:
- our_bits = CCP_MPPE_NT_128bit; break;
- }
- } else {
- /* auto */
- our_bits = CCP_MPPE_NT_128bit | CCP_MPPE_NT_56bit
- | CCP_MPPE_NT_40bit;
- if (peer_bits != 0) {
- if ((peer_bits & CCP_MPPE_NT_128bit) != 0)
- our_bits = CCP_MPPE_NT_128bit;
- else if ((peer_bits & CCP_MPPE_NT_56bit) != 0)
- our_bits = CCP_MPPE_NT_56bit;
- else if ((peer_bits & CCP_MPPE_NT_40bit) != 0)
- our_bits = CCP_MPPE_NT_40bit;
- }
+ our_bits = _this->keylenbits;
+ if (peer_bits != 0 && (peer_bits & our_bits) != 0) {
+ if ((peer_bits & CCP_MPPE_NT_128bit) != 0)
+ our_bits = CCP_MPPE_NT_128bit;
+ else if ((peer_bits & CCP_MPPE_NT_56bit) != 0)
+ our_bits = CCP_MPPE_NT_56bit;
+ else if ((peer_bits & CCP_MPPE_NT_40bit) != 0)
+ our_bits = CCP_MPPE_NT_40bit;
}
if (_this->mode_auto != 0) {
diff --git a/usr.sbin/npppd/npppd/npppd-users.5 b/usr.sbin/npppd/npppd/npppd-users.5
new file mode 100644
index 00000000000..ed17c4cc2f1
--- /dev/null
+++ b/usr.sbin/npppd/npppd/npppd-users.5
@@ -0,0 +1,68 @@
+.\" $OpenBSD: npppd-users.5,v 1.1 2012/09/18 13:14:08 yasuoka Exp $
+.\"
+.\" The following requests are required for all man pages.
+.\"
+.\" Remove `\&' from the line below.
+.Dd $Mdocdate: September 18 2012 $
+.Dt NPPPD-USERS 5
+.Os
+.Sh NAME
+.Nm npppd-users
+.Nd user database file
+.Sh SYNOPSIS
+.Nm /etc/npppd/npppd-users
+.Sh DESCRIPTION
+The
+.Nm
+file describes
+the various attributes of users.
+Refer to
+.Xr getcap 3
+for a description of the file layout.
+Each entry in the database is used to describe one user.
+The record name is the username.
+Following attributes can be specified:
+.Bl -column "framed-ip-network"
+.It Sy Name Ta Sy Description
+.It password Ta
+User's password
+.It framed-ip-address Ta
+IPv4 address to be assigned for the user.
+.It framed-ip-network Ta
+IPv4 netmask to be used for the user.
+.It calling-number Ta
+Calling phone number to check user's phone number.
+.El
+.\" The following requests should be uncommented and used where appropriate.
+.\" .Sh RETURN VALUES
+.\" For sections 2, 3, and 9 function return values only.
+.\" .Sh ENVIRONMENT
+.\" For sections 1, 6, 7 & 8 only.
+.\" .Sh FILES
+.\" .Sh EXIT STATUS
+.\" For sections 1, 6, & 8 only.
+.Pp
+.Sh EXAMPLES
+.Bd -literal
+taro:\\
+ :password=taro's password:\\
+ :framed-ip-address=192.168.0.101:
+
+hana:\\
+ :password=hana's password:\\
+ :framed-ip-address=192.168.0.102:
+.Ed
+.\" .Sh DIAGNOSTICS
+.\" For sections 1, 4, 6, 7, and 8 only.
+.\" .Sh ERRORS
+.\" For sections 2, 3, and 9 error and signal handling only.
+.Sh SEE ALSO
+.Xr npppd 8 ,
+.Xr npppd.conf 5 ,
+.Xr getcap 3
+.\" .Xr foobar 1
+.\" .Sh STANDARDS
+.\" .Sh HISTORY
+.\" .Sh AUTHORS
+.\" .Sh CAVEATS
+.\" .Sh BUGS
diff --git a/usr.sbin/npppd/npppd/npppd.8 b/usr.sbin/npppd/npppd/npppd.8
new file mode 100644
index 00000000000..9bf4d9020fc
--- /dev/null
+++ b/usr.sbin/npppd/npppd/npppd.8
@@ -0,0 +1,117 @@
+.\" $OpenBSD: npppd.8,v 1.1 2012/09/18 13:14:08 yasuoka Exp $
+.\"
+.\" Copyright (c) 2012 YASUOKA Masahiko <yasuoka@openbsd.org>
+.\"
+.\" Permission to use, copy, modify, and distribute this software for any
+.\" purpose with or without fee is hereby granted, provided that the above
+.\" copyright notice and this permission notice appear in all copies.
+.\"
+.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+.\" The following requests are required for all man pages.
+.\"
+.Dd $Mdocdate: September 18 2012 $
+.Dt NPPPD 8
+.Os
+.Sh NAME
+.Nm npppd
+.Nd New Point-to-Point Protocol daemon
+.Sh SYNOPSIS
+.Nm npppd
+.Op Fl hdn
+.Op Fl f Ar config_file
+.Sh DESCRIPTION
+The
+.Nm
+is a Point-to-Point Protocol and tunneling protocols daemon
+which does L2TP, PPTP and PPPoE servers.
+.Bl -tag -width Ds
+.It Fl d
+Do not daemonize.
+If this option is specified,
+.Nm
+will run in the foreground and log to
+.Em stderr .
+.It Fl f Ar file
+Specify an alternative configuration file.
+.It Fl n
+Configtest mode.
+Only check the configuration file for validity.
+.It Fl h
+Show the usage.
+.El
+.Pp
+Normally
+.Nm
+works with
+.Xr pipex 4
+to accelerate IP packet forwarding, but
+.Xr pipex 4
+is disabled by default. To enable it,
+set the
+.Va net.pipex.enable
+to `1' by
+.Xr sysctl 8
+or
+.Xr sysctl.conf 5 .
+.Pp
+When
+.Nm
+uses PPTP, receiving GRE packets is required, but it is disabled by default.
+To enable it, set the
+.Va net.inet.gre.allow
+to `1' by
+.Xr sysctl 8
+or
+.Xr sysctl.conf 5 .
+.\" The following requests should be uncommented and used where appropriate.
+.\" .Sh RETURN VALUES
+.\" For sections 2, 3, and 9 function return values only.
+.\" .Sh ENVIRONMENT
+.\" For sections 1, 6, 7 & 8 only.
+.Sh FILES
+.Bl -tag -width "/etc/npppd/npppd.conf" -compact
+.It Pa /etc/npppd/npppd.conf
+default
+.Xr npppd 8
+configuration file
+.El
+.\" .Sh EXIT STATUS
+.\" For sections 1, 6, & 8 only.
+.\" .Sh EXAMPLES
+.\" .Sh DIAGNOSTICS
+.\" For sections 1, 4, 6, 7, and 8 only.
+.\" .Sh ERRORS
+.\" For sections 2, 3, and 9 error and signal handling only.
+.Sh SEE ALSO
+.Xr npppctl 8 ,
+.Xr npppd.conf 5 ,
+.Xr pipex 4 ,
+.Xr tun 4 ,
+.Xr pppx 4 ,
+.Xr gre 4 ,
+.Xr sysctl 8 ,
+.Xr sysctl.conf 5
+.\" .Xr foobar 1
+.\" .Sh STANDARDS
+.Sh HISTORY
+The
+.Nm
+program first appeared in
+.Ox
+5.3.
+.Sh AUTHORS
+The
+.Nm
+program was written by Internet Initiative Japan Inc.
+.
+.\" .Sh CAVEATS
+.Sh BUGS
+If
+.Ic l2tp-require-ipsec
+yes to L2TP tunnel, all incoming packets will be dropped.
diff --git a/usr.sbin/npppd/npppd/npppd.c b/usr.sbin/npppd/npppd/npppd.c
index 9b34890f99f..b08ee3dddf5 100644
--- a/usr.sbin/npppd/npppd/npppd.c
+++ b/usr.sbin/npppd/npppd/npppd.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: npppd.c,v 1.20 2012/07/17 03:18:57 yasuoka Exp $ */
+/* $OpenBSD: npppd.c,v 1.21 2012/09/18 13:14:08 yasuoka Exp $ */
/*-
* Copyright (c) 2009 Internet Initiative Japan Inc.
@@ -29,7 +29,7 @@
* Next pppd(nppd). This file provides a npppd daemon process and operations
* for npppd instance.
* @author Yasuoka Masahiko
- * $Id: npppd.c,v 1.20 2012/07/17 03:18:57 yasuoka Exp $
+ * $Id: npppd.c,v 1.21 2012/09/18 13:14:08 yasuoka Exp $
*/
#include <sys/cdefs.h>
#include "version.h"
@@ -106,10 +106,10 @@ __COPYRIGHT(
static npppd s_npppd; /* singleton */
-static void npppd_reload0(npppd *);
+static void npppd_reload0 (npppd *);
+static void npppd_update_pool_reference (npppd *);
static int npppd_rd_walktree_delete(struct radish_head *);
static void usage (void);
-static void npppd_start (npppd *);
static void npppd_stop_really (npppd *);
static uint32_t str_hash(const void *, int);
static void npppd_on_sighup (int, short, void *);
@@ -145,28 +145,27 @@ static void pipex_periodic(npppd *);
* Daemon process
***********************************************************************/
int main (int, char *[]);
+int debugsyslog = 0; /* used by log.c */
int
main(int argc, char *argv[])
{
- int ch, stop_by_error, ll_adjust = 0, runasdaemon = 0;
- extern char *optarg;
- const char *npppd_conf0 = DEFAULT_NPPPD_CONF;
+ int ch, stop_by_error, runasdaemon = 1, nflag = 0;
+ extern char *optarg;
+ const char *npppd_conf0 = DEFAULT_NPPPD_CONF;
struct passwd *pw;
- while ((ch = getopt(argc, argv, "Dc:dhs")) != -1) {
+ while ((ch = getopt(argc, argv, "nf:dh")) != -1) {
switch (ch) {
- case 's':
- ll_adjust++;
+ case 'n':
+ nflag = 1;
break;
- case 'c':
+ case 'f':
npppd_conf0 = optarg;
break;
- case 'D':
- runasdaemon = 1;
- break;
case 'd':
debuglevel++;
+ runasdaemon = 0;
break;
case '?':
case 'h':
@@ -174,15 +173,26 @@ main(int argc, char *argv[])
exit(1);
}
}
+ argc -= optind;
+ argv += optind;
+ if (argc != 0) {
+ usage();
+ exit(1);
+ }
+ if (nflag) {
+ debuglevel++;
+ runasdaemon = 0;
+ }
+
+ /* for log.c */
+ log_init(debuglevel);
if (debuglevel > 0) {
+ /* for ../common/debugutil.c */
debug_set_debugfp(stderr);
debug_use_syslog(0);
- } else {
- debug_set_syslog_level_adjust(ll_adjust);
- openlog(NULL, LOG_PID, LOG_NPPPD);
- if (runasdaemon)
- daemon(0, 0);
}
+ if (runasdaemon)
+ daemon(0, 0);
/* check for root privileges */
if (geteuid())
@@ -194,6 +204,13 @@ main(int argc, char *argv[])
if (privsep_init() != 0)
err(1, "cannot drop privileges");
+ if (nflag) {
+ if (npppd_config_check(npppd_conf0) == 0) {
+ fprintf(stderr, "configuration OK\n");
+ exit(EXIT_SUCCESS);
+ }
+ exit(EXIT_FAILURE);
+ }
if (npppd_init(&s_npppd, npppd_conf0) != 0)
exit(EXIT_FAILURE);
@@ -221,15 +238,7 @@ main(int argc, char *argv[])
static void
usage()
{
- fprintf(stderr,
- "usage: npppd [-sDdh] [-c config_file]\n"
- "\t-d: increase debuglevel. Output log to standard error.\n"
- "\t-c: specify configuration file. default=\"%s\".\n"
- "\t-s: adjust syslog level to be silent.\n"
- "\t-D: run as a daemon.\n"
- "\t-h: show usage.\n"
- , DEFAULT_NPPPD_CONF
- );
+ fprintf(stderr, "usage: npppd [-hdn] [-f config_file]\n");
}
/** Returns the singleton npppd instance */
@@ -247,11 +256,8 @@ int
npppd_init(npppd *_this, const char *config_file)
{
int i, status = -1;
- char pidpath[MAXPATHLEN];
const char *pidpath0;
- const char *coredir;
FILE *pidfp = NULL;
- char cwd[MAXPATHLEN];
long seed;
memset(_this, 0, sizeof(npppd));
@@ -264,6 +270,7 @@ npppd_init(npppd *_this, const char *config_file)
pidpath0 = NULL;
_this->pid = getpid();
slist_init(&_this->realms);
+ npppd_conf_init(&_this->conf);
log_printf(LOG_NOTICE, "Starting npppd pid=%u version=%s",
_this->pid, VERSION);
@@ -305,24 +312,7 @@ npppd_init(npppd *_this, const char *config_file)
return -1;
}
- if ((pidpath0 = npppd_config_str(_this, "pidfile")) == NULL)
- pidpath0 = DEFAULT_NPPPD_PIDFILE;
-
- /* Runtime directory */
- if ((coredir = npppd_config_str(_this, "coredir")) == NULL) {
- /* diretory for pid file */
- strlcpy(pidpath, pidpath0, sizeof(pidpath));
- strlcpy(cwd, dirname(pidpath), sizeof(cwd));
- }
- else {
- /* directory for dumping core */
- strlcpy(cwd, coredir, sizeof(cwd));
- }
- if (chdir(cwd) != 0) {
- log_printf(LOG_ERR, "chdir(%s,) failed in %s(): %m", __func__,
- cwd);
- return -1;
- }
+ pidpath0 = DEFAULT_NPPPD_PIDFILE;
/* initialize event(3) */
event_init();
@@ -374,7 +364,12 @@ npppd_init(npppd *_this, const char *config_file)
npppd_ctl_init(&_this->ctl, _this, NPPPD_CTL_SOCK_PATH);
if ((status = npppd_ctl_start(&_this->ctl)) != 0)
return status;
- return npppd_modules_reload(_this);
+ if ((status = npppd_modules_reload(_this)) != 0)
+ return status;
+
+ npppd_update_pool_reference(_this);
+
+ return 0;
}
/** start the npppd */
@@ -445,8 +440,7 @@ npppd_stop_really(npppd *_this)
}
#endif
for (i = countof(_this->iface) - 1; i >= 0; i--) {
- if (_this->iface[i].initialized != 0)
- npppd_iface_fini(&_this->iface[i]);
+ npppd_iface_fini(&_this->iface[i]);
}
_this->finalized = 1;
}
@@ -476,8 +470,6 @@ npppd_fini(npppd *_this)
if (_this->iface[i].initialized != 0)
npppd_iface_fini(&_this->iface[i]);
}
- for (i = 0; i < countof(_this->iface_bind); i++)
- slist_fini(&_this->iface_bind[i].pools);
for (i = countof(_this->pool) - 1; i >= 0; i--) {
if (_this->pool[i].initialized != 0)
@@ -489,8 +481,7 @@ npppd_fini(npppd *_this)
signal_del(&_this->ev_sighup);
signal_del(&_this->ev_sigchld);
- if (_this->properties != NULL)
- properties_destroy(_this->properties);
+ npppd_conf_fini(&_this->conf);
slist_fini(&_this->realms);
@@ -660,38 +651,24 @@ npppd_get_user_framed_ip_address(npppd *_this, npppd_ppp *ppp,
}
NPPPD_ASSERT(ppp->realm != NULL);
- if (ppp->realm_framed_ip_address.s_addr != 0) {
-#if 1
-/*
- * FIXME: This fix is ad hok, it overwrites the ip address here if assigning
- * FIXME: IP address by RADIUS is prohibited. This will make a bug when a
- * FIXME: new authentication type is add. Fix this until then.
- */
- if ((ppp_ipcp(ppp)->ip_assign_flags & NPPPD_IP_ASSIGN_RADIUS)
- == 0) {
- ppp->realm_framed_ip_netmask.s_addr = 0;
- } else
-#endif
+ if (ppp->realm_framed_ip_address.s_addr != 0)
return &ppp->realm_framed_ip_address;
- }
- ppp->realm_framed_ip_netmask.s_addr = 0xffffffffL;
- if ((ppp_ipcp(ppp)->ip_assign_flags & NPPPD_IP_ASSIGN_FIXED) != 0) {
- /* assign by the authentication realm */
- if (npppd_auth_get_framed_ip(ppp->realm, username,
- &ppp->realm_framed_ip_address,
- &ppp->realm_framed_ip_netmask) != 0)
- ppp->realm_framed_ip_address.s_addr = 0;
- }
+ /* assign by the authentication realm */
+ if (npppd_auth_get_framed_ip(ppp->realm, username,
+ &ppp->realm_framed_ip_address,
+ &ppp->realm_framed_ip_netmask) != 0)
+ ppp->realm_framed_ip_address.s_addr = 0;
do_default:
/* Use USER_SELECT if the realm doesn't specify the ip address */
if (ppp->realm_framed_ip_address.s_addr == 0)
ppp->realm_framed_ip_address.s_addr = INADDR_USER_SELECT;
+
+
if (ppp->realm_framed_ip_address.s_addr == INADDR_USER_SELECT) {
/* Use NAS_SELECT if USER_SELECT is not allowed by the config */
- if ((ppp_ipcp(ppp)->ip_assign_flags &
- NPPPD_IP_ASSIGN_USER_SELECT) == 0)
+ if (!ppp_ipcp(ppp)->allow_user_select)
ppp->realm_framed_ip_address.s_addr = INADDR_NAS_SELECT;
}
NPPPD_DBG((LOG_DEBUG, "%s() = %s", __func__,
@@ -704,20 +681,18 @@ do_default:
int
npppd_check_calling_number(npppd *_this, npppd_ppp *ppp)
{
- int lnumber, rval, strict, loose;
- char number[NPPPD_PHONE_NUMBER_LEN + 1];
-
- strict = ppp_config_str_equal(ppp, "check_callnum", "strict", 0);
- loose = ppp_config_str_equal(ppp, "check_callnum", "loose", 0);
+ struct tunnconf *conf;
+ int lnumber, rval;
+ char number[NPPPD_PHONE_NUMBER_LEN + 1];
- if (strict || loose) {
+ conf = ppp_get_tunnconf(ppp);
+ if (conf->callnum_check != 0) {
lnumber = sizeof(number);
if ((rval = npppd_auth_get_calling_number(ppp->realm,
- ppp->username,
- number, &lnumber)) == 0)
+ ppp->username, number, &lnumber)) == 0)
return
(strcmp(number, ppp->calling_number) == 0)? 1 : 0;
- if (strict)
+ if ((conf->callnum_check & NPPPD_CALLNUM_CHECK_STRICT) != 0)
return 0;
}
@@ -817,7 +792,7 @@ npppd_check_user_max_session(npppd *_this, npppd_ppp *ppp)
slist *uppp;
/* user_max_session == 0 means unlimit */
- if (ppp_iface(ppp)->user_max_session == 0)
+ if (_this->user_max_session == 0)
return 1;
count = 0;
@@ -830,7 +805,7 @@ npppd_check_user_max_session(npppd *_this, npppd_ppp *ppp)
}
}
- return (count < ppp_iface(ppp)->user_max_session)? 1 : 0;
+ return (count < _this->user_max_session)? 1 : 0;
}
/***********************************************************************
@@ -976,7 +951,7 @@ npppd_ppp_pipex_enable(npppd *_this, npppd_ppp *ppp)
switch (ppp->tunnel_type) {
#ifdef USE_NPPPD_PPPOE
- case PPP_TUNNEL_PPPOE:
+ case NPPPD_TUNNEL_PPPOE:
{
struct sockaddr *sa;
struct ether_header *eh;
@@ -1003,7 +978,7 @@ npppd_ppp_pipex_enable(npppd *_this, npppd_ppp *ppp)
}
#endif
#ifdef USE_NPPPD_PPTP
- case PPP_TUNNEL_PPTP:
+ case NPPPD_TUNNEL_PPTP:
call = (pptp_call *)ppp->phy_context;
/* PPTP specific informations */
@@ -1029,7 +1004,7 @@ npppd_ppp_pipex_enable(npppd *_this, npppd_ppp *ppp)
break;
#endif
#ifdef USE_NPPPD_L2TP
- case PPP_TUNNEL_L2TP:
+ case NPPPD_TUNNEL_L2TP:
l2tp = (l2tp_call *)ppp->phy_context;
l2tpctrl = l2tp->ctrl;
@@ -1119,7 +1094,7 @@ npppd_ppp_pipex_disable(npppd *_this, npppd_ppp *ppp)
bzero(&req, sizeof(req));
switch(ppp->tunnel_type) {
#ifdef USE_NPPPD_PPPOE
- case PPP_TUNNEL_PPPOE:
+ case NPPPD_TUNNEL_PPPOE:
pppoe = (pppoe_session *)ppp->phy_context;
/* PPPoE specific informations */
@@ -1128,7 +1103,7 @@ npppd_ppp_pipex_disable(npppd *_this, npppd_ppp *ppp)
break;
#endif
#ifdef USE_NPPPD_PPTP
- case PPP_TUNNEL_PPTP:
+ case NPPPD_TUNNEL_PPTP:
call = (pptp_call *)ppp->phy_context;
/* PPTP specific informations */
@@ -1137,7 +1112,7 @@ npppd_ppp_pipex_disable(npppd *_this, npppd_ppp *ppp)
break;
#endif
#ifdef USE_NPPPD_L2TP
- case PPP_TUNNEL_L2TP:
+ case NPPPD_TUNNEL_L2TP:
l2tp = (l2tp_call *)ppp->phy_context;
/* L2TP specific context */
@@ -1185,7 +1160,7 @@ npppd_ppp_pipex_ip_disable(npppd *_this, npppd_ppp *ppp)
bzero(&req, sizeof(req));
switch(ppp->tunnel_type) {
#ifdef USE_NPPPD_PPPOE
- case PPP_TUNNEL_PPPOE:
+ case NPPPD_TUNNEL_PPPOE:
pppoe = (pppoe_session *)ppp->phy_context;
/* PPPoE specific informations */
@@ -1194,7 +1169,7 @@ npppd_ppp_pipex_ip_disable(npppd *_this, npppd_ppp *ppp)
break;
#endif
#ifdef USE_NPPPD_PPTP
- case PPP_TUNNEL_PPTP:
+ case NPPPD_TUNNEL_PPTP:
call = (pptp_call *)ppp->phy_context;
/* PPTP specific informations */
@@ -1203,7 +1178,7 @@ npppd_ppp_pipex_ip_disable(npppd *_this, npppd_ppp *ppp)
break;
#endif
#ifdef USE_NPPPD_L2TP
- case PPP_TUNNEL_L2TP:
+ case NPPPD_TUNNEL_L2TP:
l2tp = (l2tp_call *)ppp->phy_context;
/* L2TP specific context */
@@ -1222,11 +1197,11 @@ npppd_ppp_pipex_ip_disable(npppd *_this, npppd_ppp *ppp)
static void
pipex_periodic(npppd *_this)
{
- struct pipex_session_list_req req;
- npppd_ppp *ppp;
- int i, error;
- u_int ppp_id;
- slist dlist, users;
+ struct pipex_session_list_req req;
+ npppd_ppp *ppp;
+ int i, error;
+ u_int ppp_id;
+ slist dlist, users;
slist_init(&dlist);
slist_init(&users);
@@ -1296,6 +1271,7 @@ pipex_done:
int
npppd_prepare_ip(npppd *_this, npppd_ppp *ppp)
{
+
if (ppp_ipcp(ppp) == NULL)
return 1;
@@ -1307,15 +1283,10 @@ npppd_prepare_ip(npppd *_this, npppd_ppp *ppp)
ppp->ipcp.ip4_our = _this->iface[0].ip4addr;
else
return -1;
- if (ppp_ipcp(ppp)->dns_use_tunnel_end != 0) {
- ppp->ipcp.dns_pri = ppp->ipcp.ip4_our;
- ppp->ipcp.dns_sec.s_addr = INADDR_NONE;
- } else {
- ppp->ipcp.dns_pri = ppp_ipcp(ppp)->dns_pri;
- ppp->ipcp.dns_sec = ppp_ipcp(ppp)->dns_sec;
- }
- ppp->ipcp.nbns_pri = ppp_ipcp(ppp)->nbns_pri;
- ppp->ipcp.nbns_sec = ppp_ipcp(ppp)->nbns_sec;
+ ppp->ipcp.dns_pri = ppp_ipcp(ppp)->dns_servers[0];
+ ppp->ipcp.dns_sec = ppp_ipcp(ppp)->dns_servers[1];
+ ppp->ipcp.nbns_pri = ppp_ipcp(ppp)->nbns_servers[0];
+ ppp->ipcp.nbns_sec = ppp_ipcp(ppp)->nbns_servers[1];
return 0;
}
@@ -1494,7 +1465,7 @@ int
npppd_assign_ip_addr(npppd *_this, npppd_ppp *ppp, uint32_t req_ip4)
{
uint32_t ip4, ip4mask;
- int flag, dyna, rval, fallback_dyna;
+ int dyna, rval, fallback_dyna;
const char *reason = "out of the pool";
struct sockaddr_npppd *snp;
npppd_pool *pool;
@@ -1507,7 +1478,6 @@ npppd_assign_ip_addr(npppd *_this, npppd_ppp *ppp, uint32_t req_ip4)
ip4 = INADDR_ANY;
ip4mask = 0xffffffffL;
- flag = ppp_ipcp(ppp)->ip_assign_flags;
realm = ppp->realm;
dyna = 0;
fallback_dyna = 0;
@@ -1520,19 +1490,9 @@ npppd_assign_ip_addr(npppd *_this, npppd_ppp *ppp, uint32_t req_ip4)
dyna = 1;
} else {
NPPPD_ASSERT(realm != NULL);
- /* We cannot assign a fixed ip address without realm */
-
- if ((npppd_auth_get_type(realm) == NPPPD_AUTH_TYPE_RADIUS &&
- (flag & NPPPD_IP_ASSIGN_RADIUS) == 0 &&
- (flag & NPPPD_IP_ASSIGN_FIXED) == 0) ||
- (npppd_auth_get_type(realm) == NPPPD_AUTH_TYPE_LOCAL &&
- (flag & NPPPD_IP_ASSIGN_FIXED) == 0))
- dyna = 1;
- else {
- fallback_dyna = 1;
- req_ip4 = ntohl(ppp->realm_framed_ip_address.s_addr);
- ip4mask = ntohl(ppp->realm_framed_ip_netmask.s_addr);
- }
+ fallback_dyna = 1;
+ req_ip4 = ntohl(ppp->realm_framed_ip_address.s_addr);
+ ip4mask = ntohl(ppp->realm_framed_ip_netmask.s_addr);
}
if (!dyna) {
/*
@@ -1540,43 +1500,38 @@ npppd_assign_ip_addr(npppd *_this, npppd_ppp *ppp, uint32_t req_ip4)
* doesn't belong any address pool. Fallback to dynamic
* assignment.
*/
- for (slist_itr_first(ppp_pools(ppp));
- slist_itr_has_next(ppp_pools(ppp));){
- pool = slist_itr_next(ppp_pools(ppp));
- rval = npppd_pool_get_assignability(pool, req_ip4,
- ip4mask, &snp);
- switch (rval) {
- case ADDRESS_OK:
- if (snp->snp_type == SNP_POOL) {
- /*
- * Fixed address pool can be used
- * only if the realm specified to use
- * it.
- */
- if (ppp->realm_framed_ip_address
- .s_addr != INADDR_USER_SELECT)
- ip4 = req_ip4;
- break;
- }
- ppp->assign_dynapool = 1;
- ip4 = req_ip4;
- break;
- case ADDRESS_RESERVED:
- reason = "reserved";
- continue;
- case ADDRESS_OUT_OF_POOL:
- reason = "out of the pool";
- continue; /* try next */
- case ADDRESS_BUSY:
- fallback_dyna = 0;
- reason = "busy";
- break;
- default:
- case ADDRESS_INVALID:
- fallback_dyna = 0;
- reason = "invalid";
+ pool = ppp_pool(ppp);
+ rval = npppd_pool_get_assignability(pool, req_ip4, ip4mask,
+ &snp);
+ switch (rval) {
+ case ADDRESS_OK:
+ if (snp->snp_type == SNP_POOL) {
+ /*
+ * Fixed address pool can be used only if the
+ * realm specified to use it.
+ */
+ if (ppp->realm_framed_ip_address
+ .s_addr != INADDR_USER_SELECT)
+ ip4 = req_ip4;
break;
}
+ ppp->assign_dynapool = 1;
+ ip4 = req_ip4;
+ break;
+ case ADDRESS_RESERVED:
+ reason = "reserved";
+ break;
+ case ADDRESS_OUT_OF_POOL:
+ reason = "out of the pool";
+ break;
+ case ADDRESS_BUSY:
+ fallback_dyna = 0;
+ reason = "busy";
+ break;
+ default:
+ case ADDRESS_INVALID:
+ fallback_dyna = 0;
+ reason = "invalid";
break;
}
#define IP_4OCT(v) ((0xff000000 & (v)) >> 24), ((0x00ff0000 & (v)) >> 16),\
@@ -1590,19 +1545,13 @@ npppd_assign_ip_addr(npppd *_this, npppd_ppp *ppp, uint32_t req_ip4)
goto dyna_assign;
return 1;
}
- ppp->assigned_pool = pool;
ppp->ppp_framed_ip_address.s_addr = htonl(ip4);
ppp->ppp_framed_ip_netmask.s_addr = htonl(ip4mask);
} else {
dyna_assign:
- for (slist_itr_first(ppp_pools(ppp));
- slist_itr_has_next(ppp_pools(ppp));){
- pool = slist_itr_next(ppp_pools(ppp));
- ip4 = npppd_pool_get_dynamic(pool, ppp);
- if (ip4 != 0)
- break;
- }
+ pool = ppp_pool(ppp);
+ ip4 = npppd_pool_get_dynamic(pool, ppp);
if (ip4 == 0) {
ppp_log(ppp, LOG_NOTICE,
"No free address in the pool.");
@@ -1690,7 +1639,6 @@ npppd_set_radish(npppd *_this, void *radish_head)
slist_itr_remove(&rtlist0);
/* clear informations about old pool configuration */
- ppp->assigned_pool = NULL;
snp->snp_next = NULL;
delppp0 = 0;
@@ -1860,6 +1808,8 @@ rd2slist(struct radish_head *h, slist *list)
static void
npppd_reload0(npppd *_this)
{
+ int i;
+
npppd_reload_config(_this);
#ifdef USE_NPPPD_ARP
arp_set_strictintfnetwork(npppd_config_str_equali(_this, "arpd.strictintfnetwork", "true", ARPD_STRICTINTFNETWORK_DEFAULT));
@@ -1870,16 +1820,39 @@ npppd_reload0(npppd *_this)
#endif
npppd_modules_reload(_this);
npppd_ifaces_load_config(_this);
-#ifdef NPPPD_RESET_IP_ADDRESS
- {
- int i;
- for (i = 0; i < countof(_this->iface); i++) {
- if (_this->iface[i].initialized != 0)
- npppd_iface_reinit(&_this->iface[i]);
- }
- }
-#endif
+ npppd_update_pool_reference(_this);
npppd_auth_finalizer_periodic(_this);
+
+ for (i = 0; i < countof(_this->iface); i++) {
+ if (_this->iface[i].initialized != 0 &&
+ _this->iface[i].started == 0)
+ npppd_iface_start(&_this->iface[i]);
+ }
+}
+
+static void
+npppd_update_pool_reference(npppd *_this)
+{
+ int i, j;
+ /* update iface to pool reference */
+ for (i = 0; i < countof(_this->iface_pool); i++) {
+ _this->iface_pool[i] = NULL;
+ if (_this->iface[i].initialized == 0)
+ continue;
+ if (_this->iface[i].ipcpconf == NULL)
+ continue; /* no IPCP for this interface */
+
+ for (j = 0; j < countof(_this->pool); j++) {
+ if (_this->pool[j].initialized == 0)
+ continue;
+ if (strcmp(_this->iface[i].ipcpconf->name,
+ _this->pool[j].ipcp_name) == 0) {
+ /* found the ipcp that has the pool */
+ _this->iface_pool[i] = &_this->pool[j];
+ break;
+ }
+ }
+ }
}
/***********************************************************************
@@ -1966,10 +1939,10 @@ int
npppd_ppp_bind_realm(npppd *_this, npppd_ppp *ppp, const char *username, int
eap_required)
{
- int lsuffix, lprefix, lusername, lmax;
- const char *val;
- char *tok, *buf0, buf[NPPPD_CONFIG_BUFSIZ], buf1[MAX_USERNAME_LENGTH];
+ struct confbind *bind;
npppd_auth_base *realm = NULL, *realm0 = NULL, *realm1 = NULL;
+ char buf1[MAX_USERNAME_LENGTH];
+ int lsuffix, lprefix, lusername, lmax;
NPPPD_ASSERT(_this != NULL);
NPPPD_ASSERT(ppp != NULL);
@@ -1983,88 +1956,51 @@ npppd_ppp_bind_realm(npppd *_this, npppd_ppp *ppp, const char *username, int
lmax = -1;
realm = NULL;
- if ((val = ppp_config_str(ppp, "realm_list")) == NULL) {
-#ifndef NO_DEFAULT_REALM
- /*
- * If the realm is not a list, because of compatibility for
- * past versions, we try fallback from LOCAL to RADIUS.
- */
+ TAILQ_FOREACH(bind, &_this->conf.confbinds, entry) {
+ if (strcmp(bind->tunnconf->name, ppp->phy_label) != 0)
+ continue;
+
realm0 = NULL;
slist_itr_first(&_this->realms);
while (slist_itr_has_next(&_this->realms)) {
realm1 = slist_itr_next(&_this->realms);
if (!npppd_auth_is_usable(realm1))
continue;
- switch (npppd_auth_get_type(realm1)) {
- case NPPPD_AUTH_TYPE_LOCAL:
- if (npppd_auth_get_user_password(
- realm1, npppd_auth_username_for_auth(
- realm1, username, buf1),
- NULL, NULL) == 0) {
- realm = realm1;
- goto found;
- }
+ if (eap_required && !npppd_auth_is_eap_capable(realm1))
+ continue;
+ if (strcmp(npppd_auth_get_name(realm1),
+ bind->authconf->name) == 0) {
+ realm0 = realm1;
break;
-
- case NPPPD_AUTH_TYPE_RADIUS:
- realm = realm1;
- goto found;
}
}
-#else
- /* Nothing to do */
-#endif
- } else {
- strlcpy(buf, val, sizeof(buf));
- buf0 = buf;
- while ((tok = strsep(&buf0, " ,\t\r\n")) != NULL) {
- if (tok[0] == '\0')
- continue;
- realm0 = NULL;
- slist_itr_first(&_this->realms);
- while (slist_itr_has_next(&_this->realms)) {
- realm1 = slist_itr_next(&_this->realms);
- if (!npppd_auth_is_usable(realm1))
- continue;
- if (eap_required &&
- !npppd_auth_is_eap_capable(realm1))
- continue;
- if (strcmp(npppd_auth_get_label(realm1), tok)
- == 0) {
- realm0 = realm1;
- break;
- }
- }
- if (realm0 == NULL)
+ if (realm0 == NULL)
+ continue;
+
+ lsuffix = strlen(npppd_auth_get_suffix(realm0));
+ if (lsuffix > lmax &&
+ (lsuffix == 0 ||
+ (lsuffix < lusername && strcmp(username + lusername
+ - lsuffix, npppd_auth_get_suffix(realm0))
+ == 0))) {
+ /* check prefix */
+ lprefix = strlen(npppd_auth_get_prefix(realm0));
+ if (lprefix > 0 &&
+ strncmp(username, npppd_auth_get_prefix(realm0),
+ lprefix) != 0)
continue;
- lsuffix = strlen(npppd_auth_get_suffix(realm0));
- if (lsuffix > lmax &&
- (lsuffix == 0 || (lsuffix < lusername &&
- strcmp(username + lusername - lsuffix,
- npppd_auth_get_suffix(realm0)) == 0))) {
- /* check prefix */
- lprefix = strlen(npppd_auth_get_prefix(realm0));
- if (lprefix > 0 &&
- strncmp(username,
- npppd_auth_get_prefix(realm0),
- lprefix) != 0)
- continue;
- lmax = lsuffix;
- realm = realm0;
- }
+ lmax = lsuffix;
+ realm = realm0;
}
}
+
if (realm == NULL) {
log_printf(LOG_INFO, "user='%s' could not bind any realms",
username);
return 1;
}
-#ifndef NO_DEFAULT_REALM
-found:
-#endif
- NPPPD_DBG((LOG_DEBUG, "%s bind realm %s(%s)",
- username, npppd_auth_get_label(realm), npppd_auth_get_name(realm)));
+ NPPPD_DBG((LOG_DEBUG, "bind realm %s", npppd_auth_get_name(realm)));
if (npppd_auth_get_type(realm) == NPPPD_AUTH_TYPE_LOCAL)
/* hook the auto reload */
@@ -2144,62 +2080,46 @@ npppd_ppp_iface_is_ready(npppd *_this, npppd_ppp *ppp)
int
npppd_ppp_bind_iface(npppd *_this, npppd_ppp *ppp)
{
- int i, ifidx, ntotal_session;
- const char *ifname, *label;
- char buf[BUFSIZ];
- npppd_auth_base *realm;
+ int i, ifidx;
+ struct confbind *bind;
NPPPD_ASSERT(_this != NULL);
NPPPD_ASSERT(ppp != NULL);
if (ppp->ifidx >= 0)
return 0;
- if (ppp->peer_auth == 0) {
- strlcpy(buf, "no_auth.concentrate", sizeof(buf));
- } else {
- realm = (npppd_auth_base *)ppp->realm;
- strlcpy(buf, "realm.", sizeof(buf));
- NPPPD_ASSERT(ppp->realm != NULL);
- label = npppd_auth_get_label(realm);
- if (label[0] != '\0') {
- strlcat(buf, label, sizeof(buf));
- strlcat(buf, ".concentrate", sizeof(buf));
- } else
- strlcat(buf, "concentrate", sizeof(buf));
- }
-
- ifname = ppp_config_str(ppp, buf);
- if (ifname == NULL)
+
+ TAILQ_FOREACH(bind, &_this->conf.confbinds, entry) {
+ if (strcmp(bind->tunnconf->name, ppp->phy_label) != 0)
+ continue;
+ if (ppp->realm == NULL) {
+ if (bind->authconf == NULL)
+ break;
+ } else if (strcmp(bind->authconf->name,
+ npppd_auth_get_name(ppp->realm)) == 0)
+ break;
+ }
+ if (bind == NULL)
return 1;
/* Search a interface */
ifidx = -1;
- ntotal_session = 0;
for (i = 0; i < countof(_this->iface); i++) {
if (_this->iface[i].initialized == 0)
continue;
- ntotal_session += _this->iface[i].nsession;
- if (strcmp(_this->iface[i].ifname, ifname) == 0)
+ if (strcmp(_this->iface[i].ifname, bind->iface->name) == 0)
ifidx = i;
}
if (ifidx < 0)
return 1;
- if (ntotal_session >= _this->max_session) {
+ if (_this->max_session > 0 && _this->nsession++ >= _this->max_session) {
ppp_log(ppp, LOG_WARNING,
"Number of sessions reaches out of the limit=%d",
_this->max_session);
return 1;
}
- if (_this->iface[ifidx].nsession >= _this->iface[ifidx].max_session) {
- ppp_log(ppp, LOG_WARNING,
- "Number of sessions reaches out of the interface limit=%d",
- _this->iface[ifidx].max_session);
- return 1;
- }
-
ppp->ifidx = ifidx;
- ppp_iface(ppp)->nsession++;
return 0;
}
@@ -2208,9 +2128,7 @@ npppd_ppp_bind_iface(npppd *_this, npppd_ppp *ppp)
void
npppd_ppp_unbind_iface(npppd *_this, npppd_ppp *ppp)
{
- if (ppp->ifidx >= 0)
- ppp_iface(ppp)->nsession--;
-
+ _this->nsession--;
ppp->ifidx = -1;
}
@@ -2355,21 +2273,40 @@ seed_random(long *seed)
}
const char *
-npppd_ppp_tunnel_protocol_name(npppd *_this, npppd_ppp *ppp)
+npppd_tunnel_protocol_name(int tunn_protocol)
{
- switch (ppp->tunnel_type) {
- case PPP_TUNNEL_NONE:
+ switch (tunn_protocol) {
+ case NPPPD_TUNNEL_NONE:
return "None";
- case PPP_TUNNEL_L2TP:
+ case NPPPD_TUNNEL_L2TP:
return "L2TP";
- case PPP_TUNNEL_PPTP:
+ case NPPPD_TUNNEL_PPTP:
return "PPTP";
- case PPP_TUNNEL_PPPOE:
+ case NPPPD_TUNNEL_PPPOE:
return "PPPoE";
- case PPP_TUNNEL_SSTP:
+ case NPPPD_TUNNEL_SSTP:
return "SSTP";
}
- NPPPD_ASSERT(0);
return "Error";
}
+
+const char *
+npppd_ppp_tunnel_protocol_name(npppd *_this, npppd_ppp *ppp)
+{
+ return npppd_tunnel_protocol_name(ppp->tunnel_type);
+}
+
+struct tunnconf *
+npppd_get_tunnconf(npppd *_this, const char *name)
+{
+ struct tunnconf *conf;
+
+ TAILQ_FOREACH(conf, &_this->conf.tunnconfs, entry) {
+ if (strcmp(conf->name, name) == 0)
+ return conf;
+ }
+
+ return NULL;
+}
+
diff --git a/usr.sbin/npppd/npppd/npppd.conf.5 b/usr.sbin/npppd/npppd/npppd.conf.5
new file mode 100644
index 00000000000..29245694e20
--- /dev/null
+++ b/usr.sbin/npppd/npppd/npppd.conf.5
@@ -0,0 +1,642 @@
+.\" $OpenBSD: npppd.conf.5,v 1.1 2012/09/18 13:14:08 yasuoka Exp $
+.\"
+.\" Copyright (c) 2012 YASUOKA Masahiko <yasuoka@openbsd.org>
+.\"
+.\" Permission to use, copy, modify, and distribute this software for any
+.\" purpose with or without fee is hereby granted, provided that the above
+.\" copyright notice and this permission notice appear in all copies.
+.\"
+.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+.\"
+.\"
+.Dd $Mdocdate: September 18 2012 $
+.Dt NPPPD.CONF 5
+.Os
+.Sh NAME
+.Nm npppd.conf
+.Nd npppd configuration file
+.Sh DESCRIPTION
+.Nm
+is the configuration file for the PPP daemon,
+.Xr npppd 8 .
+.Sh SECTIONS
+.Nm
+is devided six sections:
+.Bl -tag -compact -width Authentications
+.It Sy Globals
+Global setting
+.It Sy Tunnels
+Tunnel setting describes the tunneling protocol and PPP settings.
+.It Sy IPCPs
+IPCP setting describes the Internet Protocol Configuration Protocol(IPCP)
+of PPP.
+.It Sy Interfaces
+Inteface setting
+.It Sy Authentications
+Authenticaton setting
+.It Sy Binds
+Bind the setting
+.El
+.Sh GLOBAL
+Global options are following:
+.Bl -tag -width Ds
+.It Ic set max-session Ar number
+Specify the maximum number of sessions.
+`0' means no limit. Default value is `0'.
+.It Ic set user-max-session Ar number
+Specify the maximum number of sessions for each user.
+`0' means no limit. Default value is `0'.
+.El
+.Sh TUNNEL
+.Pp
+The
+.Ic tunnel
+setting are described below:
+.Bd
+.Ic tunnel Ar name Ic protocol Ar protocol Ic { Ar options Ic }
+.Ed
+.Pp
+Specify
+.Ar name
+of this tunnel protocol setting.
+For
+.Ar protocol ,
+specify one of the following that this tunnel setting accepts from:
+.Pp
+.Bl -offset indent -compact -tag -width pppoe -indent
+.It Ic l2tp
+Layer Two Tunneling Protocol (RFC 2661)
+.It Ic pptp
+Point-to-Point Tunneling Protocol (RFC 2637)
+.It Ic pppoe
+PPP Over Ethernet (RFC 2516)
+.El
+.El
+.Pp
+Supported options are following:
+.Bl -tag -width Ds
+.It Ic listen on Ar address Op Ic port Ar port
+Specify IP address that this tunnel protocol listens on.
+Both IPv4 and IPv6 address can be used. If the port is ommited, the default
+port numbers are used.
+The default port number is 1723 for PPTP and 1701 for L2TP.
+Default value is `0.0.0.0'.
+This option can be specified if the tunnel protocol is not PPPoE.
+.It Ic listen on interface Ar interface-name
+Specify the interface name that this PPPoE tunnel listens on.
+The interface must be ethernet interface.
+This option can be specified if the tunnel protocol is PPPoE.
+.It Ic l2tp-hostname Ar string
+Specify a hostname that are used by L2TP.
+Default value is the value that is returned by
+.Xr gethostname 2 .
+This option can be specified if the tunnel protocol is L2TP.
+.It Ic l2tp-vendor-name Ar string
+Specify a vendor name that are used by L2TP.
+Default value is "" (empty string).
+This option can be specified if the tunnel protocol is L2TP.
+.It Ic l2tp-hello-interval Ar number
+Specify the interval time between L2TP hello request in seconds.
+The default value is `60'.
+This option can be specified if the tunnel protocol is L2TP.
+.It Ic l2tp-hello-timeout Ar number
+Specify the maximim time that
+.Nm
+waits L2TP hello response in seconds.
+The default value is `30'.
+This option can be specified if the tunnel protocol is L2TP.
+.It Ic l2tp-accept-dialin Ar yes | no
+If `yes' is specified,
+.Xr npppd 8
+accepts Proxy-LCP and Proxy-Authentication AVPs from LAC
+that is to do `compulsory tunneling mode'.
+The default is `no'.
+This option can be specified if the tunnel protocol is L2TP.
+.It Ic l2tp-lcp-renegotiation Ar yes | no
+If `yes' is specified,
+.Xr npppd 8
+will basically use the LCP that is received by Proxied-LCP AVPs,
+but when if the LCP is not acceptable
+.Xr npppd 8
+will negotiate LCP again.
+The default is `yes'.
+This option can be specified if the tunnel protocol is L2TP.
+.It Ic l2tp-force-lcp-renegotiation Ar yes | no
+If `yes' is specified,
+.Xr npppd 8
+will not use the LCP that is received by Proxied-LCP AVPs,
+it will negotiate LCP again.
+The default is `no'.
+This option can be specified if the tunnel protocol is L2TP.
+.It Ic l2tp-data-use-seq Ar yes | no
+Specify `yes' to use sequencling for L2TP Data comunication.
+The default is `yes'.
+This option can be specified if the tunnel protocol is L2TP.
+.It Ic l2tp-require-ipsec Ar yes | no
+Specify `yes' to refuse L2TP connections without IPsec encapsulation.
+The default is `no'.
+This option can be specified if the tunnel protocol is L2TP.
+.It Ic pptp-hostname Ar string
+Specify a hostname that are used by PPTP.
+Default value is the value that is returned by
+.Xr gethostname 2 .
+This option can be specified if the tunnel protocol is PPTP.
+.It Ic pptp-vendor-name Ar string
+Specify a vendor name that are used by PPTP.
+Default value is "" (empty string).
+This option can be specified if the tunnel protocol is PPTP.
+.It Ic pptp-echo-interval Ar number
+Specify the interval time between PPTP echo request in seconds.
+The default value is `60'.
+This option can be specified if the tunnel protocol is PPTP.
+.It Ic pptp-echo-timeout Ar number
+Specify the maximim time that
+.Nm
+waits PPTP echo reply in seconds.
+The default value is `60'.
+This option can be specified if the tunnel protocol is PPTP.
+.It Ic pppoe-service-name Ar string
+Specify a service name. The default is "" (empty string).
+This option can be specified if the tunnel protocol is PPPoE.
+.It Ic pppoe-accept-any-service Ar yes | no
+If `yes' is specified
+.Xr npppd 8
+accepts request from the clients that are accepting any service names
+Default value is `yes'.
+This option can be specified if the tunnel protocol is PPPoE.
+.It Ic pppoe-ac-name Ar string
+Specify the access concentrator(ac) name.
+The default value is created by the MAC Address
+of the listening interface.
+This option can be specified if the tunnel protocol is PPPoE.
+.It Ic mru Ar number
+Specified the MRU(Maximum Receive Unit) value.
+This value is used for LCP negotiation with the tunnel peer.
+The default value is `1360' for L2TP, `1400' for pptp and '1492' for PPPoE.
+.It Ic lcp-keepalive Ar yes | no
+Specify whether
+.Xr npppd 8
+uses LCP keep alive.
+The default value `no' for L2TP, `yes' for PPTP and PPPoE.
+.It Ic lcp-keepalive-interval Ar number
+Specify the interval time between LCP echo request in seconds.
+The default value is `300'.
+.It Ic lcp-keepalive-retry-interval Ar number
+Specify the interval time between retrying LCP echo request
+without receiving the echo reply from the peer.
+The value must be specified in seconds.
+The default value is `60'.
+.It Ic lcp-keepalive-max-retries Ar number
+Specify the maximum number of retrying LCP echo.
+If the peer doesn't respond and the number of retry reaches this value,
+.Xr npppd 8
+treats the link is dead and it closes the link.
+The default value is `3'.
+.It Ic lcp-timeout Ar number
+Specify the timeout value for LCP retransmission in seconds.
+Default value is `3'.
+.It Ic lcp-max-configure Ar number
+Specify the maximum number of LCP configure reqeuest transmission.
+Default value is `10'.
+.It Ic lcp-max-terminate Ar number
+Specify the maximum number of LCP terminate reqeuest transmission.
+Default value is `2'.
+.It Ic lcp-max-nak-loop Ar number
+Specify the maximum number of LCP configure NAK loops.
+Default value is `5'.
+.It Ic authentication-method Ar authentication-method ...
+Specify authentication methods.
+.Pp
+Following authentication methods can be used:
+.Bl -tag -width mschapv2 -compact -indent
+.It Ic pap
+Password Authentication Protocol
+.It Ic chap
+PPP Challenge Handshake Authentication Protocol (RFC 1994)
+.It Ic mschapv2
+Microsoft PPP CHAP Extensions, Version 2 (RFC 2749)
+.El
+.Pp
+`mschapv2' is used as the default for PPTP,
+`pap chap mschapv2' will be used as the default for other protocols.
+.It Ic ccp-timeout Ar number
+Specify the timeout value for CCP retransmission in seconds.
+Default value is `3'.
+.It Ic ccp-max-configure Ar number
+Specify the maximum number of CCP configure reqeuest transmission.
+Default value is `10'.
+.It Ic ccp-max-terminate Ar number
+Specify the maximum number of CCP terminate reqeuest transmission.
+Default value is `2'.
+.It Ic ccp-max-nak-loop Ar number
+Specify the maximum number of CCP configure NAK loops.
+Default value is `5'.
+.It Ic ipcp-timeout Ar number
+Specify the timeout value for IPCP retransmission in seconds.
+Default value is `3'.
+.It Ic ipcp-max-configure Ar number
+Specify the maximum number of IPCP configure reqeuest transmission.
+Default value is `10'.
+.It Ic ipcp-max-terminate Ar number
+Specify the maximum number of IPCP terminate reqeuest transmission.
+Default value is `2'.
+.It Ic ipcp-max-nak-loop Ar number
+Specify the maximum number of IPCP configure NAK loops.
+Default value is `5'.
+.It Ic mppe-key-length Ar key-length ...
+Specify key lengths that this configuration use.
+.Pp
+Following key lengths can be used:
+.Bl -tag -width 128 -compact -indent
+.It Ic 128
+128 bits encryption
+.It Ic 56
+56 bits encryption
+.It Ic 40
+40 bits encryption
+.El
+.It Ic mppe-key-state Ar mode ...
+Specify the key change modes that this configuration supports to.
+.Pp
+Following modes can be used:
+.Bl -tag -width stateless -compact -indent
+.It Ic stateful
+Stateful mode key changes
+.It Ic stateless
+Stateless mode key changes
+.El
+.It Ic idle-timeout Ar number
+Specify the timeout value for the idle timer in seconds.
+The idle timer disconnects the link if the link keeps idle for the time
+specified by this value.
+The link is treated as `idle' if the no data packet are sent or received.
+0 means disable the idle timer.
+Default value is `0'.
+.It Ic tcp-mss-adjust Ar yes | no
+If `yes' is specified,
+.Xr npppd 8
+adjusts TCP SYN packets so that the value of TCP MSS (maximum segment
+size) option is less than the value calculated from the link MTU.
+The default value is `no'.
+.It Ic ingress-filter Ar yes | no
+If `yes' is specified,
+.Xr npppd 8
+applies ingress filter for incoming packets.
+The ingress filter drops all packets that source address does not match to
+the address assigned by
+.Xr npppd 8
+for the link. Default value is `no'.
+.It Ic pipex Ar yes | no
+Specify whether
+.Xr npppd 8
+uses
+.Xr pipex 4 .
+Default is `yes'.
+.It Ic debug-dump-pktin Ar protocol ...
+If this option is specified,
+.Xr npppd 8
+dumps received packets which match the specified protocol.
+Following protocols can be specified:
+.Bl -tag -width mppe -compact -indent
+.It Ic ip
+Internet Protocol (IP)
+.It Ic lcp
+Link Configuration Protocol (LCP)
+.It Ic pap
+Password Authentication Protocol (PAP)
+.It Ic chap
+Challenge Handshake Authentication Protocol (CHAP)
+.\" .It Ic eap
+.\" Extended Authentication Protocol (EAP)
+.It Ic mppe
+Microsoft Point-to-Point Encryption (MPPE)
+.It Ic ccp
+Compression Control Protocol (CCP)
+.It Ic ipcp
+IP Configuration Protocol (IPCP)
+.El
+.It Ic debug-dump-pktout Ar protocol ...
+If this option is specified,
+.Xr npppd 8
+dumps sending packets which match the specified protocol.
+See
+.Ic debug-dump-pktin
+section for
+.Ar protocol .
+.It Ic l2tp-ctrl-in-pktdump Ar yes | no
+Specify whether
+.Xr npppd 8
+dumps received L2TP control packets for debug.
+Default is `no'.
+.It Ic l2tp-ctrl-out-pktdump Ar yes | no
+Specify whether
+.Xr npppd 8
+dumps sending L2TP control packets for debug.
+Default is `no'.
+.It Ic l2tp-data-in-pktdump Ar yes | no
+Specify whether
+.Xr npppd 8
+dumps received L2TP data packets for debug.
+Default is `no'.
+.It Ic l2tp-data-out-pktdump Ar yes | no
+Specify whether
+.Xr npppd 8
+dumps sending L2TP data packets for debug.
+Default is `no'.
+.It Ic pptp-ctrl-in-pktdump Ar yes | no
+Specify whether
+.Xr npppd 8
+dumps received PPTP control packets for debug.
+Default is `no'.
+.It Ic pptp-ctrl-out-pktdump Ar yes | no
+Specify whether
+.Xr npppd 8
+dumps sending PPTP control packets for debug.
+Default is `no'.
+.It Ic pptp-data-in-pktdump Ar yes | no
+Specify whether
+.Xr npppd 8
+dumps received PPTP data packets for debug.
+Default is `no'.
+.It Ic pptp-data-out-pktdump Ar yes | no
+Specify whether
+.Xr npppd 8
+dumps sending PPTP data packets for debug.
+Default is `no'.
+.It Ic pppoe-desc-in-pktdump Ar yes | no
+Specify whether
+.Xr npppd 8
+dumps received PPPoE discovery packets for debug.
+Default is `no'.
+.It Ic pppoe-desc-out-pktdump Ar yes | no
+Specify whether
+.Xr npppd 8
+dumps sending PPPoE discovery packets for debug.
+Default is `no'.
+.It Ic pppoe-session-in-pktdump Ar yes | no
+Specify whether
+.Xr npppd 8
+dumps received PPPoE session packets for debug.
+Default is `no'.
+.It Ic pppoe-session-out-pktdump Ar yes | no
+Specify whether
+.Xr npppd 8
+dumps sending PPPoE session packets for debug.
+Default is `no'.
+.El
+.Sh IPCP
+The
+.Ic icpp
+setting are described below:
+.Bd
+.Ic ipcp Ar name { Ar option ... Ic }
+.Ed
+.Pp
+Specify name of this
+.Ic ipcp
+setting.
+The maximum number of
+.Ic ipcp
+settings is 8.
+.Pp
+Supported options are following:
+.Bl -tag -width Ds
+.It Ic pool-address Ar address-range | address-mask Op Ic for Ar dynamic | static
+Specify the IP address space that is pooled for this IPCP setting.
+The address space can be specified by
+.Ar address-range
+(eg. 192.168.0.2-192.168.0.254)
+or
+.Ar address-mask
+(eg. 192.168.0.0/24) .
+.Ic for
+.Ar dynamic
+means the address space is reserved for dynamic allocation,
+.Ar static
+means the address space is reserved for static allocation. Default is
+.Ar dynamic .
+This option can be used in multiple times.
+.It Ic dns-servers Ar primary-server-address Op secondary-server-address
+Specify the DNS servers' IP address.
+.It Ic nbns-servers Ar primary-server-address Op secondary-server-address
+Specify the NetBIOS name servers' IP address.
+.It Ic allow-user-selected-address Ar yes | no
+Specify whether
+.Xr npppd 8
+is allowed to assign prior the address that is selected by the user.
+Default is `yes'.
+.El
+.Sh INTERFACE
+.Pp
+The
+.Ic interface
+setting is described below:
+.Bd
+.Ic interface Ar ifname Ic address Ar address Ic ipcp Ar ipcp
+.Ed
+.Pp
+Use
+.Xr tun 4
+or
+.Xr pppx 4
+and
+specify its name to
+.Ar ifname .
+.Ar address
+is the IP address of this interface, and it is noticed as the tunnel address
+to the tunnel peer.
+Specify the
+.Ic ipcp
+setting name that are used with this interface.
+The maximum number of
+.Ic interface
+settings is 8.
+.Sh AUTHENTICATION
+.Pp
+The
+.Ic authentication
+setting are described below:
+.Bd
+.Ic authentication Ar name Ic type Ar type { Ar option ... Ic }
+.Ed
+.Pp
+Specify
+.Ar name
+for this authentication setting.
+For
+.Ar type ,
+one of the following can be specified:
+.Pp
+.Bl -offset indent -compact -tag -width radius -indent
+.It Ic local
+authenticates by the local file.
+.It Ic radius
+authenticates by the remote RADIUS servers.
+.El
+.Pp
+Supported options are following:
+.Bl -tag -width Ds
+.It Ic username-suffix Ar string
+Specify the suffix of the username
+so that
+.Xr npppd 8
+selects this authentication setting only for a user who has the username
+that matches this suffix pattern.
+.It Ic username-prefix Ar string
+Specify the prefix of the username
+so that
+.Xr npppd 8
+selects this authentication setting only for a user who has the username
+that matches this prefix pattern.
+.\" .It Ic eap-capable Ar yes | no
+.\" Specify whether this authentcation server is able to use EAP.
+.\" Default is `yes'.
+.It Ic strip-nt-domain Ar yes | no
+Specify whether
+.Xr npppd 8
+remove the NT domain prefix like '\\\\NTDOMAIN\\' from the username
+before requesting the authentication server.
+Default is `no'.
+.It Ic strip-atmark-realm Ar yes | no
+Specify whether
+.Xr npppd 8
+remove the realm part that begins '@' (atmark)
+from the username before requesting the authentication server.
+Default is `no'.
+.It Ic users-file Ar string
+Specify the path for
+.Xr npppd-users 7
+that describes users' account information.
+The path must be under `/etc/npppd/', because
+.Xr npppd 8
+is restricted to access the files only in limited directories.
+.It Ic authentication-server { Ar radius-config Ic }
+This option describes the settings for RADIUS authentication server.
+This option can be used in RADIUS type only.
+.Bl -tag -width max-failovers -compact -indent
+.It Ic address Ar address Oo Ic port Ar port Oc Op Ic secret Ar secret
+Specify the IP address and port of RADIUS server to
+.Ar address
+and
+.Ar port ,
+and
+the shared secret to
+.Ar secret .
+.Ar secret
+must be less than 127 chars.
+Default port is 1812 for
+.Ic authentication-server,
+1813 for
+.Ic accouting-server .
+This option can be specified multiple times (max 16 times) in a
+.Ar radius-config .
+.It Ic timeout Ar number
+Specify the maximum time for waiting the response in seconds.
+Default is `9'.
+.It Ic max-tries Ar number
+Specify the maximum number of retransmission.
+Default is `3'.
+.It Ic max-failovers Ar number
+Specify the maximum number of failovers.
+Default is `1'.
+.El
+.It Ic accounting-server { Ar radius-config Ic }
+This option describes the settings for RADIUS accounting server.
+See
+.Ic authentication-server
+section for
+.Ar radius-config
+This option can be used in RADIUS type only.
+.El
+.Sh BIND
+.Pp
+.Ic bind
+describes a set of the
+.Ar tunnel
+setting,
+.Ar authentication
+setting and
+.Ar interface
+setting so that they are used together.
+.Bd
+.Ic bind Ic tunnel from Ar tunnel Ic authenticated by Ar authentication
+.Ic to Ar ifname
+.Ed
+.\" The following requests should be uncommented and used where appropriate.
+.\" .Sh RETURN VALUES
+.\" For sections 2, 3, and 9 function return values only.
+.\" .Sh ENVIRONMENT
+.\" For sections 1, 6, 7 & 8 only.
+.\" .Sh FILES
+.\" .Sh EXIT STATUS
+.\" For sections 1, 6, & 8 only.
+.Sh EXAMPLES
+.Pp
+Very simple configuration example is below:
+.Bd -literal -offset indent
+tunnel L2TP protocol l2tp
+tunnel PPTP protocol pptp
+ipcp IPCP {
+ pool-address 10.0.0.2-10.0.0.254
+ dns-servers 8.8.8.8
+}
+interface pppx0 address 10.0.0.1 ipcp IPCP
+authentication LOCAL type local {
+ users-file "/etc/npppd/npppd-users"
+}
+bind tunnel from L2TP authenticated by LOCAL to pppx0
+bind tunnel from PPTP authenticated by LOCAL to pppx0
+.Ed
+.Pp
+Simple configuration but has two authentication realms:
+.Bd -literal -offset indent
+tunnel L2TP protocol l2tp {
+ listen on 203.0.113.100
+}
+ipcp IPCP {
+ pool-address 10.0.0.2-10.0.0.254
+ dns-servers 8.8.8.8
+}
+interface tun0 address 10.0.0.1 ipcp IPCP
+interface tun1 address 10.0.0.1 ipcp IPCP
+authentication RADIUS type radius {
+ username-suffix "@example.com"
+ authentication-server {
+ address 192.168.0.1 secret "hogehoge"
+ }
+ accounting-server {
+ address 192.168.0.1 secret "hogehoge"
+ }
+}
+authentication LOCAL type local {
+ username-suffix "@local"
+ users-file "/etc/npppd/npppd-users"
+}
+bind tunnel from L2TP authenticated by RADIUS to tun0
+bind tunnel from L2TP authenticated by LOCAL to tun1
+.Ed
+.\" .Sh DIAGNOSTICS
+.\" For sections 1, 4, 6, 7, and 8 only.
+.\" .Sh ERRORS
+.\" For sections 2, 3, and 9 error and signal handling only.
+.Sh SEE ALSO
+.Xr npppctl 8 ,
+.Xr npppd 8 ,
+.Xr pipex 4 ,
+.Xr tun 4 ,
+.Xr pppx 4
+.\" .Sh STANDARDS
+.\" .Sh HISTORY
+.\" .Sh AUTHORS
+.\" .Sh CAVEATS
+.Sh BUGS
+Current version of
+.Xr npppd 8
+does not support adding or removing tunnel settings or changing its listener
+settings(listen address, port and l2tp-ipsec-require).
diff --git a/usr.sbin/npppd/npppd/npppd.h b/usr.sbin/npppd/npppd/npppd.h
index 4e1fb84838c..7db48afd1c1 100644
--- a/usr.sbin/npppd/npppd/npppd.h
+++ b/usr.sbin/npppd/npppd/npppd.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: npppd.h,v 1.9 2012/05/08 13:15:11 yasuoka Exp $ */
+/* $OpenBSD: npppd.h,v 1.10 2012/09/18 13:14:08 yasuoka Exp $ */
/*-
* Copyright (c) 2009 Internet Initiative Japan Inc.
@@ -28,28 +28,179 @@
#ifndef NPPPD_H
#define NPPPD_H 1
+
+#include <sys/param.h>
+#include <sys/queue.h>
+#include <sys/socket.h>
+#include <stdbool.h>
+#include <net/if.h>
+#include <net/if_dl.h>
+#include <netinet/in.h>
+#include <event.h>
+
+#include "slist.h"
+#include "addr_range.h"
+
+#include "l2tp_conf.h"
+#include "pptp_conf.h"
+#include "pppoe_conf.h"
+
#define NPPPD_USER "_ppp"
+#define NPPPD_GENERIC_NAME_LEN 32
-#ifndef NPPPD_DEFAULT_TUN_IFNAME
-#define NPPPD_DEFAULT_TUN_IFNAME "tun0"
-#endif
+/** Constants of tunnel type */
+#define NPPPD_TUNNEL_NONE 0 /** None Tunnel Type */
+#define NPPPD_TUNNEL_L2TP 1 /** L2TP Tunnel Type */
+#define NPPPD_TUNNEL_PPTP 2 /** PPTP Tunnel Type */
+#define NPPPD_TUNNEL_PPPOE 3 /** PPPoE Tunnel Type */
+#define NPPPD_TUNNEL_SSTP 4 /** SSTP Tunnel Type */
+
+#define NPPPD_AUTH_METHODS_PAP 0x0001
+#define NPPPD_AUTH_METHODS_CHAP 0x0002
+#define NPPPD_AUTH_METHODS_MSCHAPV2 0x0004
+
+#define NPPPD_MPPE_DISABLED 0x0000
+#define NPPPD_MPPE_ENABLED 0x0001
+#define NPPPD_MPPE_REQUIRED 0x0002
+
+#define NPPPD_MPPE_40BIT 0x0001
+#define NPPPD_MPPE_56BIT 0x0002
+#define NPPPD_MPPE_128BIT 0x0004
+
+#define NPPPD_MPPE_STATEFUL 0x0001
+#define NPPPD_MPPE_STATELESS 0x0002
+
+#define NPPPD_PROTO_BIT_IP 0x0001
+#define NPPPD_PROTO_BIT_LCP 0x0002
+#define NPPPD_PROTO_BIT_PAP 0x0004
+#define NPPPD_PROTO_BIT_CHAP 0x0008
+#define NPPPD_PROTO_BIT_EAP 0x0010
+#define NPPPD_PROTO_BIT_MPPE 0x0020
+#define NPPPD_PROTO_BIT_CCP 0x0040
+#define NPPPD_PROTO_BIT_IPCP 0x0080
+
+#define NPPPD_CALLNUM_CHECK_NONE 0
+#define NPPPD_CALLNUM_CHECK_STRICT 1
+#define NPPPD_CALLNUM_CHECK_LOOSE 2
+
+struct tunnconf {
+ TAILQ_ENTRY(tunnconf) entry;
+ const char *name;
+ int protocol;
+
+ union {
+ struct l2tp_conf l2tp;
+ struct pptp_conf pptp;
+ struct pppoe_conf pppoe;
+ } proto;
+
+ int lcp_timeout;
+ int lcp_max_configure;
+ int lcp_max_terminate;
+ int lcp_max_nak_loop;
+ int mru;
+ bool lcp_keepalive;
+ int lcp_keepalive_interval;
+ int lcp_keepalive_retry_interval;
+ int lcp_keepalive_max_retries;
+
+ u_int auth_methods;
+
+ int ipcp_timeout;
+ int ipcp_max_configure;
+ int ipcp_max_terminate;
+ int ipcp_max_nak_loop;
+ int ccp_timeout;
+ int ccp_max_configure;
+ int ccp_max_terminate;
+ int ccp_max_nak_loop;
+ char *chap_name;
+
+ bool mppe_yesno;
+ bool mppe_required;
+ u_int mppe_keylen;
+ u_int mppe_keystate;
+
+ int idle_timeout;
+ bool tcp_mss_adjust;
+ bool ingress_filter;
+ int callnum_check;
+ bool pipex;
-#define DEFAULT_RADIUS_AUTH_PORT 1812
-#define DEFAULT_RADIUS_ACCT_PORT 1813
-#define DEFAULT_RADIUS_TIMEOUT 9
-#define DEFAULT_RADIUS_MAX_TRIES 3
-#define DEFAULT_RADIUS_MAX_FAILOVERS 1
-#define DEFAULT_AUTH_TIMEOUT 30
+ u_int debug_dump_pktin;
+ u_int debug_dump_pktout;
+};
+
+struct radserver {
+ TAILQ_ENTRY(radserver) entry;
+ struct sockaddr_storage address;
+ char *secret;
+};
+
+struct radconf {
+ TAILQ_HEAD(radservers, radserver) servers;
+ int timeout;
+ int max_tries;
+ int max_failovers;
+};
+
+struct authconf {
+ TAILQ_ENTRY(authconf) entry;
+ char name[NPPPD_GENERIC_NAME_LEN];
+ int auth_type;
+ char *username_suffix;
+ char *username_prefix;
+ bool eap_capable;
+ bool strip_nt_domain;
+ bool strip_atmark_realm;
+ char users_file_path[MAXPATHLEN];
+ union {
+ struct {
+ struct radconf auth;
+ struct radconf acct;
+ } radius;
+ };
+};
+
+struct ipcpconf {
+ TAILQ_ENTRY(ipcpconf) entry;
+ char name[NPPPD_GENERIC_NAME_LEN];
+ bool dns_use_resolver;
+ struct in_addr dns_servers[2];
+ struct in_addr nbns_servers[2];
+ bool allow_user_select;
+ struct in_addr_range *dynamic_pool;
+ struct in_addr_range *static_pool;
+};
-/** assign fixed IP address */
-#define NPPPD_IP_ASSIGN_FIXED 0x0001
+struct iface {
+ TAILQ_ENTRY(iface) entry;
+ char name[IFNAMSIZ];
+ struct in_addr ip4addr;
+ struct ipcpconf *ipcpconf;
+ bool is_pppx;
+};
-/** accept IP address which is proposed by peer and assign it */
-#define NPPPD_IP_ASSIGN_USER_SELECT 0x0002
+struct confbind {
+ TAILQ_ENTRY(confbind) entry;
+ struct tunnconf *tunnconf;
+ struct authconf *authconf;
+ struct iface *iface;
+};
-/** use RADIUS Framed-IP-Address */
-#define NPPPD_IP_ASSIGN_RADIUS 0x0004
+struct npppd_conf {
+ int max_session;
+ int user_max_session;
+ TAILQ_HEAD(tunnconfs, tunnconf) tunnconfs;
+ TAILQ_HEAD(authconfs, authconf) authconfs;
+ TAILQ_HEAD(ipcpconfs, ipcpconf) ipcpconfs;
+ TAILQ_HEAD(ifaces, iface) ifaces;
+ TAILQ_HEAD(confbinds, confbind) confbinds;
+ struct l2tp_confs l2tp_confs;
+ struct pptp_confs pptp_confs;
+ struct pppoe_confs pppoe_confs;
+};
/** sockaddr_npppd */
struct sockaddr_npppd {
@@ -73,60 +224,66 @@ typedef struct _npppd npppd;
#include "ppp.h"
-#ifdef __cplusplus
-extern "C" {
-#endif
+#include <sys/cdefs.h>
+__BEGIN_DECLS
+npppd *npppd_get_npppd (void);
+int npppd_init (npppd *, const char *);
+void npppd_start (npppd *);
+void npppd_stop (npppd *);
+void npppd_fini (npppd *);
+int npppd_reset_routing_table (npppd *, int);
+int npppd_get_user_password (npppd *, npppd_ppp *, const char *, char *, int *);
+struct in_addr *npppd_get_user_framed_ip_address (npppd *, npppd_ppp *, const char *);
+int npppd_check_calling_number (npppd *, npppd_ppp *);
+npppd_ppp *npppd_get_ppp_by_ip (npppd *, struct in_addr);
+slist *npppd_get_ppp_by_user (npppd *, const char *);
+npppd_ppp *npppd_get_ppp_by_id (npppd *, u_int);
+int npppd_check_user_max_session (npppd *, npppd_ppp *);
+void npppd_network_output (npppd *, npppd_ppp *, int, u_char *, int);
+int npppd_ppp_pipex_enable (npppd *, npppd_ppp *);
+int npppd_ppp_pipex_disable (npppd *, npppd_ppp *);
+int npppd_prepare_ip (npppd *, npppd_ppp *);
+void npppd_release_ip (npppd *, npppd_ppp *);
+void npppd_set_ip_enabled (npppd *, npppd_ppp *, int);
+int npppd_assign_ip_addr (npppd *, npppd_ppp *, uint32_t);
+int npppd_set_radish (npppd *, void *);
+int npppd_get_all_users (npppd *, slist *);
+int npppd_ppp_bind_realm (npppd *, npppd_ppp *, const char *, int);
+int npppd_ppp_is_realm_local (npppd *, npppd_ppp *);
+int npppd_ppp_is_realm_radius (npppd *, npppd_ppp *);
+int npppd_ppp_is_realm_ready (npppd *, npppd_ppp *);
+const char *npppd_ppp_get_realm_name (npppd *, npppd_ppp *);
+const char *npppd_ppp_get_iface_name (npppd *, npppd_ppp *);
+int npppd_ppp_iface_is_ready (npppd *, npppd_ppp *);
+int npppd_ppp_bind_iface (npppd *, npppd_ppp *);
+void npppd_ppp_unbind_iface (npppd *, npppd_ppp *);
+void *npppd_get_radius_auth_setting (npppd *, npppd_ppp *);
+int sockaddr_npppd_match (void *, void *);
+const char *npppd_ppp_get_username_for_auth (npppd *, npppd_ppp *, const char *, char *);
+const char *npppd_ppp_tunnel_protocol_name (npppd *, npppd_ppp *);
+const char *npppd_tunnel_protocol_name (int);
+struct tunnconf *npppd_get_tunnconf (npppd *, const char *);
+int npppd_reload_config (npppd *);
+int npppd_modules_reload (npppd *);
+int npppd_ifaces_load_config (npppd *);
+
+int npppd_conf_parse (struct npppd_conf *, const char *);
+void npppd_conf_init (struct npppd_conf *);
+void npppd_conf_fini (struct npppd_conf *);
+int npppd_config_check (const char *);
+
+void log_init (int);
+void vlog (int, const char *, __va_list);
+void log_warn (const char *, ...);
+void log_warnx (const char *, ...);
+void log_info (const char *, ...);
+void log_debug (const char *, ...);
+void fatal (const char *);
+void fatalx (const char *);
+const char *log_sockaddr (struct sockaddr *);
+
+
+__END_DECLS
-npppd *npppd_get_npppd (void);
-int npppd_init (npppd *, const char *);
-void npppd_stop (npppd *);
-void npppd_fini (npppd *);
-int npppd_prepare_ip (npppd *, npppd_ppp *);
-void npppd_release_ip (npppd *, npppd_ppp *);
-int nppp_load_user_setting(npppd *, npppd_ppp *);
-void npppd_set_ip_enabled (npppd *, npppd_ppp *, int);
-int npppd_get_user_password (npppd *, npppd_ppp *, const char *, char *, int *);
-struct in_addr *npppd_get_user_framed_ip_address(npppd *, npppd_ppp *, const char *);
-int npppd_check_calling_number (npppd *, npppd_ppp *);
-void npppd_network_output (npppd *, npppd_ppp *, int, u_char *, int);
-void npppd_network_input (npppd *, uint8_t *, int);
-npppd_ppp *npppd_get_ppp_by_ip (npppd *, struct in_addr);
-slist *npppd_get_ppp_by_user (npppd *, const char *);
-int npppd_check_user_max_session(npppd *, npppd_ppp *);
-int npppd_get_all_users (npppd *, slist *);
-int npppd_set_radish (npppd *, void *);
-int npppd_ppp_iface_is_ready(npppd *, npppd_ppp *);
-int sockaddr_npppd_match(void *, void *);
-npppd_ppp *npppd_get_ppp_by_id(npppd *, u_int);
-
-const char *npppd_config_str (npppd *, const char *);
-int npppd_config_int (npppd *, const char *, int);
-int npppd_config_str_equal (npppd *, const char *, const char *, int);
-int npppd_config_str_equali (npppd *, const char *, const char *, int);
-int npppd_modules_reload (npppd *);
-int npppd_ifaces_load_config(npppd *);
-int npppd_reload_config (npppd *);
-int npppd_assign_ip_addr (npppd *, npppd_ppp *, uint32_t);
-void npppd_release_ip_addr (npppd *, npppd_ppp *);
-
-int npppd_ppp_bind_realm(npppd *, npppd_ppp *, const char *, int);
-int npppd_ppp_is_realm_local(npppd *, npppd_ppp *);
-int npppd_ppp_is_realm_radius(npppd *, npppd_ppp *);
-int npppd_ppp_is_realm_ready(npppd *, npppd_ppp *);
-const char *npppd_ppp_get_realm_name(npppd *, npppd_ppp *);
-int npppd_ppp_bind_iface(npppd *, npppd_ppp *);
-void npppd_ppp_unbind_iface(npppd *, npppd_ppp *);
-const char *npppd_ppp_get_iface_name(npppd *, npppd_ppp *);
-void * npppd_get_radius_auth_setting(npppd *, npppd_ppp *);
-const char *npppd_ppp_tunnel_protocol_name(npppd *, npppd_ppp *);
-
-void npppd_radius_auth_server_failure_notify(npppd *, npppd_ppp *, void *, const char *);
-int npppd_ppp_pipex_enable(npppd *, npppd_ppp *);
-int npppd_ppp_pipex_disable(npppd *, npppd_ppp *);
-const char *npppd_ppp_get_username_for_auth(npppd *, npppd_ppp *, const char *, char *);
-int npppd_reset_routing_table(npppd *, int);
-#ifdef __cplusplus
-}
-#endif
#endif
diff --git a/usr.sbin/npppd/npppd/npppd_auth.c b/usr.sbin/npppd/npppd/npppd_auth.c
index c06f3a7d3a1..b6d838c2de7 100644
--- a/usr.sbin/npppd/npppd/npppd_auth.c
+++ b/usr.sbin/npppd/npppd/npppd_auth.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: npppd_auth.c,v 1.9 2012/06/05 06:31:27 yasuoka Exp $ */
+/* $OpenBSD: npppd_auth.c,v 1.10 2012/09/18 13:14:08 yasuoka Exp $ */
/*-
* Copyright (c) 2009 Internet Initiative Japan Inc.
@@ -26,8 +26,7 @@
* SUCH DAMAGE.
*/
/**@file authentication realm */
-/* $Id: npppd_auth.c,v 1.9 2012/06/05 06:31:27 yasuoka Exp $ */
-/* I hope to write the source code in npppd-independent as possible. */
+/* $Id: npppd_auth.c,v 1.10 2012/09/18 13:14:08 yasuoka Exp $ */
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/socket.h>
@@ -45,24 +44,20 @@
#include <errno.h>
#include "debugutil.h"
-#include "hash.h"
#include "slist.h"
#include "npppd_local.h"
#include "npppd_auth.h"
-#include "config_helper.h"
#include "net_utils.h"
-#include "csvreader.h"
#include "npppd_auth_local.h"
-static const char *npppd_auth_default_label(npppd_auth_base *);
/**
* Create a npppd_auth_base object.
* @param auth_type the authentication type.
* specify {@link ::NPPPD_AUTH_TYPE_LOCAL} to authenticate by the local
* file, or specify {@link ::NPPPD_AUTH_TYPE_RADIUS} for RADIUS
* authentication.
- * @param label the configuration label
+ * @param name the configuration name
* @param _npppd the parent {@link ::npppd} object
* @see ::NPPPD_AUTH_TYPE_LOCAL
* @see ::NPPPD_AUTH_TYPE_RADIUS
@@ -70,21 +65,20 @@ static const char *npppd_auth_default_label(npppd_auth_base *);
* in case success otherwise NULL will be returned.
*/
npppd_auth_base *
-npppd_auth_create(int auth_type, const char *label, void *_npppd)
+npppd_auth_create(int auth_type, const char *name, void *_npppd)
{
npppd_auth_base *base;
- NPPPD_AUTH_ASSERT(label != NULL);
+ NPPPD_AUTH_ASSERT(name != NULL);
switch (auth_type) {
case NPPPD_AUTH_TYPE_LOCAL:
if ((base = malloc(sizeof(npppd_auth_local))) != NULL) {
memset(base, 0, sizeof(npppd_auth_local));
base->type = NPPPD_AUTH_TYPE_LOCAL;
- base->users_hash = NULL;
base->strip_nt_domain = 1;
base->strip_atmark_realm = 0;
- strlcpy(base->label, label, sizeof(base->label));
+ strlcpy(base->name, name, sizeof(base->name));
base->npppd = _npppd;
return base;
@@ -98,7 +92,7 @@ npppd_auth_create(int auth_type, const char *label, void *_npppd)
memset(base, 0, sizeof(npppd_auth_radius));
base->type = NPPPD_AUTH_TYPE_RADIUS;
base->strip_nt_domain = 0;
- strlcpy(base->label, label, sizeof(base->label));
+ strlcpy(base->name, name, sizeof(base->name));
base->npppd = _npppd;
if ((_this->rad_auth_setting =
radius_req_setting_create()) == NULL)
@@ -144,9 +138,6 @@ npppd_auth_dispose(npppd_auth_base *base)
base->disposing = 1;
- if (base->users_hash != NULL)
- hash_delete_all(base->users_hash, 1);
-
return;
}
@@ -158,11 +149,6 @@ npppd_auth_destroy(npppd_auth_base *base)
if (base->disposing == 0)
npppd_auth_dispose(base);
- if (base->users_hash != NULL) {
- hash_free(base->users_hash);
- base->users_hash = NULL;
- }
-
npppd_auth_base_log(base, LOG_INFO, "Finalized");
switch(base->type) {
@@ -194,56 +180,40 @@ npppd_auth_destroy(npppd_auth_base *base)
int
npppd_auth_reload(npppd_auth_base *base)
{
- const char *val;
-
- val = npppd_auth_config_str(base, "name");
- if (val == NULL)
- /* use the label if .name is not defined. */
- strlcpy(base->name, npppd_auth_default_label(base),
- sizeof(base->name));
- else
- strlcpy(base->name, val, sizeof(base->name));
-
- if ((val = npppd_auth_config_str(base, "pppsuffix")) != NULL)
- strlcpy(base->pppsuffix, val, sizeof(base->pppsuffix));
- else
- base->pppsuffix[0] = '\0';
-
- if ((val = npppd_auth_config_str(base, "pppprefix")) != NULL)
- strlcpy(base->pppprefix, val, sizeof(base->pppprefix));
- else
- base->pppprefix[0] = '\0';
-
- base->eap_capable =
- npppd_auth_config_str_equal(base, "eap_capable", "true", 1);
- base->strip_nt_domain =
- npppd_auth_config_str_equal(base, "strip_nt_domain", "true", 1);
- base->strip_atmark_realm =
- npppd_auth_config_str_equal(base, "strip_atmark_realm", "true", 0);
-
- base->has_acctlist = 0;
- base->acctlist_ready = 0;
+ struct authconf *auth;
+
+ TAILQ_FOREACH(auth, &base->npppd->conf.authconfs, entry) {
+ if (strcmp(auth->name, base->name) == 0)
+ break;
+ }
+ if (auth == NULL)
+ return 1;
+
+ base->pppprefix[0] = '\0';
+ base->pppsuffix[0] = '\0';
+ if (auth != NULL) {
+ if (auth->username_suffix != NULL)
+ strlcpy(base->pppsuffix, auth->username_suffix,
+ sizeof(base->pppsuffix));
+ if (auth->username_prefix != NULL)
+ strlcpy(base->pppprefix, auth->username_prefix,
+ sizeof(base->pppprefix));
+ base->eap_capable = auth->eap_capable;
+ base->strip_nt_domain = auth->strip_nt_domain;
+ base->strip_atmark_realm = auth->strip_atmark_realm;
+ }
+
+ base->has_users_file = 0;
base->radius_ready = 0;
- if ((val = npppd_auth_config_str(base, "acctlist")) != NULL) {
- strlcpy(base->acctlist_path, val, sizeof(base->acctlist_path));
- if (base->users_hash == NULL) {
- if ((base->users_hash = hash_create(
- (int (*)(const void *, const void *))strcmp,
- str_hash, 1021)) == NULL) {
- npppd_auth_base_log(base,
- LOG_WARNING, "hash_create() failed: %m.");
- goto fail;
- }
- }
- base->reloadable = NPPPD_DEFAULT_AUTH_LOCAL_RELOADABLE;
- base->has_acctlist = 1;
- if (npppd_auth_reload_acctlist(base) != 0)
- goto fail;
+ if (auth->users_file_path != NULL) {
+ strlcpy(base->users_file_path, auth->users_file_path,
+ sizeof(base->users_file_path));
+ base->has_users_file = 1;
} else {
if (base->type == NPPPD_AUTH_TYPE_LOCAL) {
npppd_auth_base_log(base,
- LOG_WARNING, "missing acctlist property.");
+ LOG_WARNING, "missing users_file property.");
goto fail;
}
}
@@ -251,7 +221,7 @@ npppd_auth_reload(npppd_auth_base *base)
switch (base->type) {
#ifdef USE_NPPPD_RADIUS
case NPPPD_AUTH_TYPE_RADIUS:
- if (npppd_auth_radius_reload(base) != 0)
+ if (npppd_auth_radius_reload(base, auth) != 0)
goto fail;
break;
#endif
@@ -262,8 +232,7 @@ npppd_auth_reload(npppd_auth_base *base)
fail:
base->initialized = 0;
- base->has_acctlist = 0;
- base->acctlist_ready = 0;
+ base->has_users_file = 0;
base->radius_ready = 0;
return 1;
@@ -287,35 +256,47 @@ int
npppd_auth_get_user_password(npppd_auth_base *base,
const char *username, char *password, int *plpassword)
{
- int sz, lpassword;
+ int retval, sz, lpassword;
npppd_auth_user *user;
NPPPD_AUTH_ASSERT(base != NULL);
NPPPD_AUTH_DBG((base, LOG_DEBUG, "%s(%s)", __func__, username));
- if (base->has_acctlist == 0 || base->acctlist_ready == 0)
- return -1;
-
- if (base->reloadable != 0)
- npppd_auth_reload_acctlist(base);
-
- if ((user = npppd_auth_find_user(base, username)) == NULL)
- return 1;
-
- if (password == NULL && plpassword == NULL)
- return 0;
- if (plpassword == NULL)
- return -1;
+ user = NULL;
+ retval = 0;
+ if (base->has_users_file == 0) {
+ retval = -1;
+ goto out;
+ }
+ if ((user = npppd_auth_get_user(base, username)) == NULL) {
+ retval = 1;
+ goto out;
+ }
+ if (password == NULL && plpassword == NULL) {
+ retval = 0;
+ goto out;
+ }
+ if (plpassword == NULL) {
+ retval = -1;
+ goto out;
+ }
lpassword = strlen(user->password) + 1;
sz = *plpassword;
*plpassword = lpassword;
- if (password == NULL)
- return 0;
- if (sz < lpassword)
- return 2;
-
+ if (password == NULL) {
+ retval = 0;
+ goto out;
+ }
+ if (sz < lpassword) {
+ retval = 2;
+ goto out;
+ }
strlcpy(password, user->password, sz);
- return 0;
+out:
+ if (user != NULL)
+ free(user);
+
+ return retval;
}
/**
@@ -340,10 +321,10 @@ npppd_auth_get_framed_ip(npppd_auth_base *base, const char *username,
NPPPD_AUTH_ASSERT(base != NULL);
NPPPD_AUTH_DBG((base, LOG_DEBUG, "%s(%s)", __func__, username));
- if (base->has_acctlist == 0 || base->acctlist_ready == 0)
+ if (base->has_users_file == 0)
return -1;
- if ((user = npppd_auth_find_user(base, username)) == NULL)
+ if ((user = npppd_auth_get_user(base, username)) == NULL)
return 1;
if (user->framed_ip_address.s_addr != 0) {
@@ -351,8 +332,10 @@ npppd_auth_get_framed_ip(npppd_auth_base *base, const char *username,
if (ip4netmask != NULL)
*ip4netmask = user->framed_ip_netmask;
+ free(user);
return 0;
}
+ free(user);
return 1;
}
@@ -374,27 +357,39 @@ int
npppd_auth_get_calling_number(npppd_auth_base *base, const char *username,
char *number, int *plnumber)
{
- int lcallnum, sz;
+ int retval, lcallnum, sz;
npppd_auth_user *user;
- if (base->has_acctlist == 0 || base->acctlist_ready == 0)
+ user = NULL;
+ retval = 0;
+ if (base->has_users_file == 0)
return -1;
- if ((user = npppd_auth_find_user(base, username)) == NULL)
+ if ((user = npppd_auth_get_user(base, username)) == NULL)
return 1;
- if (number == NULL && plnumber == NULL)
- return 0;
- if (plnumber == NULL)
- return -1;
+ if (number == NULL && plnumber == NULL) {
+ retval = 0;
+ goto out;
+ }
+ if (plnumber == NULL) {
+ retval = -1;
+ goto out;
+ }
lcallnum = strlen(user->calling_number) + 1;
sz = *plnumber;
*plnumber = lcallnum;
- if (sz < lcallnum)
- return 2;
+ if (sz < lcallnum) {
+ retval = 2;
+ goto out;
+ }
strlcpy(number, user->calling_number, sz);
- return 0;
+out:
+ if (user != NULL)
+ free(user);
+
+ return retval;
}
int
@@ -417,11 +412,11 @@ npppd_auth_is_ready(npppd_auth_base *base)
switch(base->type) {
case NPPPD_AUTH_TYPE_LOCAL:
- return (base->acctlist_ready != 0)? 1 : 0;
+ return (base->has_users_file)? 1 : 0;
/* NOTREACHED */
case NPPPD_AUTH_TYPE_RADIUS:
- return (base->acctlist_ready != 0 ||
+ return (base->has_users_file != 0 ||
base->radius_ready != 0)? 1 : 0;
/* NOTREACHED */
}
@@ -443,12 +438,6 @@ npppd_auth_is_eap_capable(npppd_auth_base *base)
}
const char *
-npppd_auth_get_label(npppd_auth_base *base)
-{
- return base->label;
-}
-
-const char *
npppd_auth_get_name(npppd_auth_base *base)
{
return base->name;
@@ -495,209 +484,13 @@ npppd_auth_username_for_auth(npppd_auth_base *base, const char *username,
/***********************************************************************
* Account list related functions
***********************************************************************/
-/** Reload the account list */
-static int
-npppd_auth_reload_acctlist(npppd_auth_base *base)
-{
- CSVREADER_STATUS status;
- int linno, ncols, usersz, nuser, eof, off;
- const char **cols, *passwd, *callnum;
- char line[8192];
- csvreader *csv;
- npppd_auth_user *user;
- struct in_addr ip4, ip4mask;
- slist users;
- FILE *file;
- struct stat st;
-
- if (base->acctlist_ready != 0 && lstat(base->acctlist_path, &st) == 0) {
- if (st.st_mtime == base->last_load)
- return 0;
- base->last_load = st.st_mtime;
- }
-
- slist_init(&users);
- csv = NULL;
- if ((file = priv_fopen(base->acctlist_path)) == NULL) {
- /* hash is empty if file is not found. */
- if (errno == ENOENT)
- hash_delete_all(base->users_hash, 1);
- npppd_auth_base_log(base,
- (errno == ENOENT)? LOG_DEBUG : LOG_ERR,
- "Open %s failed: %m", base->acctlist_path);
- return 0;
- }
- if ((csv = csvreader_create()) == NULL) {
- npppd_auth_base_log(base, LOG_ERR,
- "Loading a account list failed: csvreader_create(): %m");
- goto fail;
- }
-
- for (linno = 0, eof = 0; !eof;) {
- ip4.s_addr = 0;
- ip4mask.s_addr = 0xffffffffL;
- if (fgets(line, sizeof(line), file) != NULL) {
- int linelen;
-
- linelen = strlen(line);
- if (linelen <= 0) {
- npppd_auth_base_log(base, LOG_ERR,
- "Loading a account list failed: lineno=%d "
- "line too short", linno + 1);
- goto fail;
- }
- if (line[linelen - 1] != '\n' && !feof(file)) {
- npppd_auth_base_log(base, LOG_ERR,
- "Loading a account list failed: lineno=%d "
- "line too long", linno + 1);
- goto fail;
- }
-
- status = csvreader_parse(csv, line);
- } else {
- if (!feof(file)) {
- npppd_auth_base_log(base, LOG_ERR,
- "Loading a account list failed: %m");
- goto fail;
- }
- status = csvreader_parse_flush(csv);
- eof = 1;
- }
- if (status != CSVREADER_NO_ERROR) {
- if (status == CSVREADER_OUT_OF_MEMORY)
- npppd_auth_base_log(base, LOG_ERR,
- "Loading a account list failed: %m");
- else
- npppd_auth_base_log(base, LOG_ERR,
- "Loading a account list "
- "failed: lineno=%d parse error", linno);
- goto fail;
- }
- ncols = csvreader_get_number_of_column(csv);
- if ((cols = csvreader_get_column(csv)) == NULL)
- continue;
- linno++; /* count up here because line number is treated as CSV. */
- if (linno == 1) {
- /* skip a title line */
- continue;
- }
- if (ncols < 1) {
- npppd_auth_base_log(base, LOG_ERR,
- "account list lineno=%d has only %d fields.",
- linno, ncols);
- continue;
- }
- if (strlen(cols[0]) <= 0)
- continue; /* skip if the user-name is empty */
- if (ncols >= 3) {
- if (*cols[2] != '\0' && inet_aton(cols[2], &ip4) != 1) {
- npppd_auth_base_log(base, LOG_ERR,
- "account list lineno=%d parse error: "
- "invalid 'Framed-IP-Address' field: %s",
- linno, cols[2]);
- continue;
- }
- }
- if (ncols >= 4) {
- if ((*cols[3] != '\0' &&
- inet_aton(cols[3], &ip4mask) != 1) ||
- netmask2prefixlen(htonl(ip4mask.s_addr)) < 0) {
- npppd_auth_base_log(base, LOG_ERR,
- "account list lineno=%d parse error: "
- "invalid 'Framed-IP-Netmask' field: %s",
- linno, cols[3]);
- continue;
- }
- }
-
- passwd = "";
- if (cols[1] != NULL)
- passwd = cols[1];
- callnum = "";
- if (ncols >= 6 && cols[5] != NULL)
- callnum = cols[5];
-
- usersz = sizeof(npppd_auth_user);
- usersz += strlen(cols[0]) + 1;
- usersz += strlen(passwd) + 1;
- usersz += strlen(callnum) + 1;
- if ((user = malloc(usersz)) == NULL) {
- npppd_auth_base_log(base, LOG_ERR,
- "Loading a account list failed: %m");
- goto fail;
- }
- memset(user, 0, usersz);
-
- off = 0;
-
- user->username = user->space + off;
- off += strlcpy(user->username, cols[0], usersz - off);
- ++off;
-
- user->password = user->space + off;
- off += strlcpy(user->password, passwd, usersz - off);
- ++off;
-
- user->calling_number = user->space + off;
- strlcpy(user->calling_number, callnum, usersz - off);
-
- user->framed_ip_address = ip4;
- user->framed_ip_netmask = ip4mask;
-
- slist_add(&users, user);
- }
- hash_delete_all(base->users_hash, 1);
-
- nuser = 0;
- for (slist_itr_first(&users); slist_itr_has_next(&users);) {
- user = slist_itr_next(&users);
- if (hash_lookup(base->users_hash, user->username) != NULL) {
- npppd_auth_base_log(base, LOG_WARNING,
- "Record for user='%s' is redefined, the first "
- "record will be used.", user->username);
- free(user);
- goto next_user;
- }
- if (hash_insert(base->users_hash, user->username, user) != 0) {
- npppd_auth_base_log(base, LOG_ERR,
- "Loading a account list failed: hash_insert(): %m");
- goto fail;
- }
- nuser++;
-next_user:
- slist_itr_remove(&users);
- }
- slist_fini(&users);
- csvreader_destroy(csv);
-
- fclose(file);
- npppd_auth_base_log(base, LOG_INFO,
- "Loaded users from='%s' successfully. %d users",
- base->acctlist_path, nuser);
- base->acctlist_ready = 1;
-
- return 0;
-fail:
- fclose(file);
- if (csv != NULL)
- csvreader_destroy(csv);
- hash_delete_all(base->users_hash, 1);
- for (slist_itr_first(&users); slist_itr_has_next(&users);) {
- user = slist_itr_next(&users);
- free(user);
- }
- slist_fini(&users);
-
- return 1;
-}
-
static npppd_auth_user *
-npppd_auth_find_user(npppd_auth_base *base, const char *username)
+npppd_auth_get_user(npppd_auth_base *base, const char *username)
{
- int lsuffix, lusername;
- const char *un;
- char buf[MAX_USERNAME_LENGTH];
- hash_link *hl;
+ int lsuffix, lusername;
+ const char *un;
+ char buf[MAX_USERNAME_LENGTH];
+ npppd_auth_user *u;
un = username;
lsuffix = strlen(base->pppsuffix);
@@ -711,82 +504,86 @@ npppd_auth_find_user(npppd_auth_base *base, const char *username)
buf[lusername - lsuffix] = '\0';
un = buf;
}
+
+ if (priv_get_user_info(base->users_file_path, un, &u) == 0)
+ return u;
- if ((hl = hash_lookup(base->users_hash, un)) == NULL)
- return NULL;
-
- return hl->item;
+ return NULL;
}
#ifdef USE_NPPPD_RADIUS
/***********************************************************************
* RADIUS
***********************************************************************/
-
-static int
-radius_server_address_load(radius_req_setting *radius, int idx,
- const char *address, enum RADIUS_SERVER_TYPE type)
-{
- struct addrinfo *ai;
- struct sockaddr_in *sin4;
-
- memset(&radius->server[idx], 0, sizeof(radius->server[0]));
-
- if (addrport_parse(address, IPPROTO_TCP, &ai) !=0)
- return 1;
-
- switch (ai->ai_family) {
- default:
- freeaddrinfo(ai);
- return 1;
- case AF_INET:
- case AF_INET6:
- break;
- }
-
- sin4 = (struct sockaddr_in *)(ai->ai_addr);
- if (sin4->sin_port == 0)
- sin4->sin_port = htons((type == RADIUS_SERVER_TYPE_AUTH)
- ? DEFAULT_RADIUS_AUTH_PORT : DEFAULT_RADIUS_ACCT_PORT);
-
- memcpy(&radius->server[idx].peer, ai->ai_addr,
- MIN(sizeof(radius->server[idx].peer), ai->ai_addrlen));
-
- freeaddrinfo(ai);
- radius->server[idx].enabled = 1;
-
- return 0;
-}
-
-#define VAL_SEP " \t\r\n"
/** reload the configuration of RADIUS authentication realm */
static int
-npppd_auth_radius_reload(npppd_auth_base *base)
+npppd_auth_radius_reload(npppd_auth_base *base, struct authconf *auth)
{
- npppd_auth_radius *_this = (npppd_auth_radius *)base;
- int i, nauth, nacct;
-
- _this->rad_acct_setting->timeout = _this->rad_auth_setting->timeout =
- npppd_auth_config_int(base, "timeout", DEFAULT_RADIUS_TIMEOUT);
-
+ npppd_auth_radius *_this = (npppd_auth_radius *)base;
+ radius_req_setting *rad;
+ struct radserver *server;
+ int i, nauth, nacct;
+
+ _this->rad_auth_setting->timeout =
+ (auth->radius.auth.timeout == 0)
+ ? DEFAULT_RADIUS_TIMEOUT : auth->radius.auth.timeout;
+ _this->rad_acct_setting->timeout =
+ (auth->radius.acct.timeout == 0)
+ ? DEFAULT_RADIUS_TIMEOUT : auth->radius.acct.timeout;
+
+
+ _this->rad_auth_setting->max_tries =
+ (auth->radius.auth.max_tries == 0)
+ ? DEFAULT_RADIUS_MAX_TRIES : auth->radius.auth.max_tries;
_this->rad_acct_setting->max_tries =
- _this->rad_auth_setting->max_tries =
- npppd_auth_config_int(base, "max_tries",
- DEFAULT_RADIUS_MAX_TRIES);
+ (auth->radius.acct.max_tries == 0)
+ ? DEFAULT_RADIUS_MAX_TRIES : auth->radius.acct.max_tries;
+ _this->rad_auth_setting->max_failovers =
+ (auth->radius.auth.max_failovers == 0)
+ ? DEFAULT_RADIUS_MAX_FAILOVERS
+ : auth->radius.auth.max_failovers;
_this->rad_acct_setting->max_failovers =
- _this->rad_auth_setting->max_failovers =
- npppd_auth_config_int(base, "max_failovers",
- DEFAULT_RADIUS_MAX_FAILOVERS);
+ (auth->radius.acct.max_failovers == 0)
+ ? DEFAULT_RADIUS_MAX_FAILOVERS
+ : auth->radius.acct.max_failovers;
_this->rad_acct_setting->curr_server =
_this->rad_auth_setting->curr_server = 0;
- if ((nauth = radius_loadconfig(base, _this->rad_auth_setting,
- RADIUS_SERVER_TYPE_AUTH)) < 0)
- goto fail;
- if ((nacct = radius_loadconfig(base, _this->rad_acct_setting,
- RADIUS_SERVER_TYPE_ACCT)) < 0)
- goto fail;
+
+ /* load configs for authentication server */
+ rad = _this->rad_auth_setting;
+ for (i = 0; i < countof(rad->server); i++)
+ memset(&rad->server[i], 0, sizeof(rad->server[0]));
+ i = 0;
+ TAILQ_FOREACH(server, &auth->radius.auth.servers, entry) {
+ if (i >= countof(rad->server))
+ break;
+ memcpy(&rad->server[i].peer, &server->address,
+ server->address.ss_len);
+ strlcpy(rad->server[i].secret, server->secret,
+ sizeof(rad->server[i].secret));
+ rad->server[i].enabled = 1;
+ i++;
+ }
+ nauth = i;
+
+ /* load configs for accounting server */
+ rad = _this->rad_acct_setting;
+ for (i = 0; i < countof(rad->server); i++)
+ memset(&rad->server[i], 0, sizeof(rad->server[0]));
+ i = 0;
+ TAILQ_FOREACH(server, &auth->radius.acct.servers, entry) {
+ if (i >= countof(rad->server))
+ break;
+ memcpy(&rad->server[i].peer, &server->address,
+ server->address.ss_len);
+ strlcpy(rad->server[i].secret, server->secret,
+ sizeof(rad->server[i].secret));
+ rad->server[i].enabled = 1;
+ i++;
+ }
+ nacct = i;
for (i = 0; i < countof(_this->rad_auth_setting->server); i++) {
if (_this->rad_auth_setting->server[i].enabled)
@@ -795,102 +592,10 @@ npppd_auth_radius_reload(npppd_auth_base *base)
npppd_auth_base_log(&_this->nar_base, LOG_INFO,
"Loaded configuration. %d authentication server%s, %d accounting "
- "server%s. timeout=%dsec",
- nauth, (nauth > 1)? "s" : "", nacct, (nacct > 1)? "s" : "",
- _this->rad_auth_setting->timeout);
+ "server%s.",
+ nauth, (nauth > 1)? "s" : "", nacct, (nacct > 1)? "s" : "");
return 0;
-fail:
- npppd_auth_destroy(base);
-
- return 1;
-}
-
-static int
-radius_loadconfig(npppd_auth_base *base, radius_req_setting *radius,
- enum RADIUS_SERVER_TYPE srvtype)
-{
- npppd_auth_radius *_this = (npppd_auth_radius *)base;
- int i, n;
- const char *val;
- char *tok, *buf0, buf[NPPPD_CONFIG_BUFSIZ];
- char label[256];
- struct rad_cfglabel {
- const char *list;
- const char *address;
- const char *secret;
- const char *addressL;
- const char *secretL;
- } const rad_auth_cfglabel = {
- .list = "server_list",
- .address = "server.address",
- .secret = "server.secret",
- .addressL = "server.%s.address",
- .secretL = "server.%s.secret"
- }, rad_acct_cfglabel = {
- .list = "acct_server_list",
- .address = "acct_server.address",
- .secret = "acct_server.secret",
- .addressL = "acct_server.%s.address",
- .secretL = "acct_server.%s.secret"
- }, *cfglabel;
-
- if (srvtype == RADIUS_SERVER_TYPE_AUTH)
- cfglabel = &rad_auth_cfglabel;
- else
- cfglabel = &rad_acct_cfglabel;
-
- for (i = 0; i < countof(radius->server); i++)
- radius->server[i].enabled = 0;
-
- n = 0;
- if ((val = npppd_auth_config_str(base, cfglabel->list)) != NULL) {
- strlcpy(buf, val, sizeof(buf));
- buf0 = buf;
- while ((tok = strsep(&buf0, VAL_SEP)) != NULL) {
- if (tok[0] == '\0')
- continue;
- snprintf(label, sizeof(label), cfglabel->addressL,tok);
- if ((val = npppd_auth_config_str(base, label)) == NULL){
- npppd_auth_base_log(&_this->nar_base, LOG_INFO,
- "property %s is not found", label);
- goto fail;
- }
- if (radius_server_address_load(radius, n, val, srvtype)
- != 0) {
- npppd_auth_base_log(base, LOG_INFO,
- "parse error at %s", label);
- goto fail;
- }
- snprintf(label, sizeof(label), cfglabel->secretL, tok);
- if ((val = npppd_auth_config_str(base, label)) != NULL)
- strlcpy(radius->server[n].secret, val,
- sizeof(radius->server[n].secret));
- else
- radius->server[n].secret[0] = '\0';
- n++;
- }
- } else if ((val = npppd_auth_config_str(base, cfglabel->address))
- != NULL) {
- if (radius_server_address_load(radius, n, val, srvtype) != 0) {
- npppd_auth_base_log(base, LOG_INFO,
- "parse error at %s", label);
- goto fail;
- }
- if ((val = npppd_auth_config_str(base, cfglabel->secret))
- != NULL)
- strlcpy(radius->server[n].secret, val,
- sizeof(radius->server[n].secret));
- else
- radius->server[n].secret[0] = '\0';
- n++;
- }
- for (i = n; i < countof(radius->server); i++)
- memset(&radius->server[i], 0, sizeof(radius->server[0]));
-
- return n;
-fail:
- return -1;
}
/**
@@ -928,80 +633,10 @@ npppd_auth_base_log(npppd_auth_base *_this, int prio, const char *fmt, ...)
NPPPD_AUTH_ASSERT(_this != NULL);
va_start(ap, fmt);
- snprintf(logbuf, sizeof(logbuf), "realm name=%s(%s) %s",
- _this->name, (_this->label[0] == '\0')? "default" : _this->label,
- fmt);
+ snprintf(logbuf, sizeof(logbuf), "realm name=%s %s",
+ _this->name, fmt);
status = vlog_printf(prio, logbuf, ap);
va_end(ap);
return status;
}
-
-static uint32_t
-str_hash(const void *ptr, int sz)
-{
- u_int32_t hash = 0;
- int i, len;
- const char *str;
-
- str = ptr;
- len = strlen(str);
- for (i = 0; i < len; i++)
- hash = hash*0x1F + str[i];
- hash = (hash << 16) ^ (hash & 0xffff);
-
- return hash % sz;
-}
-
-static const char *
-npppd_auth_default_label(npppd_auth_base *base)
-{
- switch(base->type) {
- case NPPPD_AUTH_TYPE_LOCAL:
- return "local";
- case NPPPD_AUTH_TYPE_RADIUS:
- return "radius";
- }
- NPPPD_AUTH_ASSERT(0);
-
- return NULL;
-}
-
-static inline const char *
-npppd_auth_config_prefix(npppd_auth_base *base)
-{
- switch(base->type) {
- case NPPPD_AUTH_TYPE_LOCAL:
- return "auth.local.realm";
-
- case NPPPD_AUTH_TYPE_RADIUS:
- return "auth.radius.realm";
-
- }
- NPPPD_AUTH_ASSERT(0);
-
- return NULL;
-}
-
-static const char *
-npppd_auth_config_str(npppd_auth_base *base, const char *confKey)
-{
- return config_named_prefix_str(((npppd *)base->npppd)->properties,
- npppd_auth_config_prefix(base), base->label, confKey);
-}
-
-static int
-npppd_auth_config_int(npppd_auth_base *base, const char *confKey, int defVal)
-{
- return config_named_prefix_int(((npppd *)base->npppd)->properties,
- npppd_auth_config_prefix(base), base->label, confKey, defVal);
-}
-
-static int
-npppd_auth_config_str_equal(npppd_auth_base *base, const char *confKey,
- const char *confVal, int defVal)
-{
- return config_named_prefix_str_equal(((npppd *)base->npppd)->properties,
- npppd_auth_config_prefix(base), base->label, confKey, confVal,
- defVal);
-}
diff --git a/usr.sbin/npppd/npppd/npppd_auth.h b/usr.sbin/npppd/npppd/npppd_auth.h
index e0fe830d052..138674726cc 100644
--- a/usr.sbin/npppd/npppd/npppd_auth.h
+++ b/usr.sbin/npppd/npppd/npppd_auth.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: npppd_auth.h,v 1.5 2012/05/08 13:15:11 yasuoka Exp $ */
+/* $OpenBSD: npppd_auth.h,v 1.6 2012/09/18 13:14:08 yasuoka Exp $ */
/*-
* Copyright (c) 2009 Internet Initiative Japan Inc.
@@ -44,6 +44,21 @@ typedef struct _npppd_auth_base npppd_auth_base;
typedef struct _npppd_auth_radius npppd_auth_radius;
typedef struct _npppd_auth_local npppd_auth_local;
+/** the type of user account */
+typedef struct _npppd_auth_user {
+ /** username */
+ char *username;
+ /** password */
+ char *password;
+ /** Framed-IP-Address */
+ struct in_addr framed_ip_address;
+ /** Framed-IP-Netmask */
+ struct in_addr framed_ip_netmask;
+ /** Calling-Number */
+ char *calling_number;
+ /** field for space assignment */
+ char space[0];
+} npppd_auth_user;
#ifdef __cplusplus
extern "C" {
@@ -61,7 +76,6 @@ int npppd_auth_is_usable (npppd_auth_base *);
int npppd_auth_is_ready (npppd_auth_base *);
int npppd_auth_is_disposing (npppd_auth_base *);
int npppd_auth_is_eap_capable (npppd_auth_base *);
-const char *npppd_auth_get_label (npppd_auth_base *);
const char *npppd_auth_get_name (npppd_auth_base *);
const char *npppd_auth_get_suffix (npppd_auth_base *);
const char *npppd_auth_get_prefix (npppd_auth_base *);
diff --git a/usr.sbin/npppd/npppd/npppd_auth_local.h b/usr.sbin/npppd/npppd/npppd_auth_local.h
index c6f0daadfc6..d1947b77640 100644
--- a/usr.sbin/npppd/npppd/npppd_auth_local.h
+++ b/usr.sbin/npppd/npppd/npppd_auth_local.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: npppd_auth_local.h,v 1.5 2012/05/08 13:15:11 yasuoka Exp $ */
+/* $OpenBSD: npppd_auth_local.h,v 1.6 2012/09/18 13:14:08 yasuoka Exp $ */
/*-
* Copyright (c) 2009 Internet Initiative Japan Inc.
@@ -27,12 +27,10 @@
*/
struct _npppd_auth_base {
- /** name of label */
- char label[NPPPD_GENERIC_NAME_LEN];
/** name of realm */
char name[NPPPD_GENERIC_NAME_LEN];
/** reference indicated to parent npppd */
- void *npppd;
+ npppd *npppd;
/** type of authentication realm */
int type;
/** PPP suffix */
@@ -42,12 +40,8 @@ struct _npppd_auth_base {
uint32_t
/** whether initialized or not */
initialized:1,
- /** whether reloadable or not */
- reloadable:1,
/** in disposing */
disposing:1,
- /** Is the account list ready */
- acctlist_ready:1,
/** Is the radius configuration ready */
radius_ready:1,
/** whether EAP capable or not */
@@ -56,14 +50,12 @@ struct _npppd_auth_base {
strip_nt_domain:1,
/** whether force to strip after the '@' of PPP username or not */
strip_atmark_realm:1,
- /** has account-list */
- has_acctlist:1,
- reserved:24;
+ /** has users list */
+ has_users_file:1,
+ reserved:25;
- /** username => npppd_auth_user hash */
- hash_table *users_hash;
/** path name of account list */
- char acctlist_path[64];
+ char users_file_path[64];
/** last load time */
time_t last_load;
};
@@ -87,31 +79,8 @@ struct _npppd_auth_local {
npppd_auth_base nal_base;
};
-/** the type of user account */
-typedef struct _npppd_auth_user {
- /** username */
- char *username;
- /** password */
- char *password;
- /** Framed-IP-Address */
- struct in_addr framed_ip_address;
- /** Framed-IP-Netmask */
- struct in_addr framed_ip_netmask;
- /** Calling-Number */
- char *calling_number;
- /** field for space assignment */
- char space[0];
-} npppd_auth_user;
-
-static int npppd_auth_reload_acctlist (npppd_auth_base *);
-static npppd_auth_user *npppd_auth_find_user (npppd_auth_base *, const char *);
-static int npppd_auth_base_log (npppd_auth_base *, int, const char *, ...);
-static uint32_t str_hash (const void *, int);
-static const char * npppd_auth_default_label(npppd_auth_base *);
-static inline const char *npppd_auth_config_prefix (npppd_auth_base *);
-static const char *npppd_auth_config_str (npppd_auth_base *, const char *);
-static int npppd_auth_config_int (npppd_auth_base *, const char *, int) __unused;
-static int npppd_auth_config_str_equal (npppd_auth_base *, const char *, const char *, int);
+static npppd_auth_user *npppd_auth_get_user (npppd_auth_base *, const char *);
+static int npppd_auth_base_log (npppd_auth_base *, int, const char *, ...);
#ifdef USE_NPPPD_RADIUS
enum RADIUS_SERVER_TYPE {
@@ -119,9 +88,7 @@ enum RADIUS_SERVER_TYPE {
RADIUS_SERVER_TYPE_ACCT
};
-static int npppd_auth_radius_reload (npppd_auth_base *);
-static int radius_server_address_load (radius_req_setting *, int, const char *, enum RADIUS_SERVER_TYPE);
-static int radius_loadconfig(npppd_auth_base *, radius_req_setting *, enum RADIUS_SERVER_TYPE);
+static int npppd_auth_radius_reload (npppd_auth_base *, struct authconf *);
#endif
#ifdef NPPPD_AUTH_DEBUG
@@ -131,3 +98,10 @@ static int radius_loadconfig(npppd_auth_base *, radius_req_settin
#define NPPPD_AUTH_DBG(x)
#define NPPPD_AUTH_ASSERT(x)
#endif
+
+#define DEFAULT_RADIUS_AUTH_PORT 1812
+#define DEFAULT_RADIUS_ACCT_PORT 1813
+#define DEFAULT_RADIUS_TIMEOUT 9
+#define DEFAULT_RADIUS_MAX_TRIES 3
+#define DEFAULT_RADIUS_MAX_FAILOVERS 1
+
diff --git a/usr.sbin/npppd/npppd/npppd_config.c b/usr.sbin/npppd/npppd/npppd_config.c
index cc118285509..10cae9454e7 100644
--- a/usr.sbin/npppd/npppd/npppd_config.c
+++ b/usr.sbin/npppd/npppd/npppd_config.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: npppd_config.c,v 1.8 2012/05/08 13:15:11 yasuoka Exp $ */
+/* $OpenBSD: npppd_config.c,v 1.9 2012/09/18 13:14:08 yasuoka Exp $ */
/*-
* Copyright (c) 2009 Internet Initiative Japan Inc.
@@ -25,11 +25,10 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
-/* $Id: npppd_config.c,v 1.8 2012/05/08 13:15:11 yasuoka Exp $ */
+/* $Id: npppd_config.c,v 1.9 2012/09/18 13:14:08 yasuoka Exp $ */
/*@file
* This file provides functions which operates configuration and so on.
*/
-#include <sys/types.h>
#include <sys/param.h>
#include <sys/socket.h>
#include <netinet/in.h>
@@ -54,7 +53,6 @@
#include "npppd_ctl.h"
#include "npppd_auth.h"
#include "npppd_iface.h"
-#include "config_helper.h"
#include "radish.h"
#include "pathnames.h"
@@ -67,26 +65,18 @@
#define NPPPD_CONFIG_ASSERT(x)
#endif
+static int npppd_pool_load(npppd *);
+static int npppd_auth_realm_reload (npppd *);
+static npppd_auth_base *realm_list_remove (slist *, const char *);
-#define CFG_KEY(p, s) config_key_prefix((p), (s))
-#define VAL_SEP " \t\r\n"
-
-static void npppd_ipcp_config_load (npppd *);
-static void npppd_ipcp_config_load0 (npppd_ipcp_config *, const char *);
-static void npppd_debug_log_reload (npppd *);
-static int npppd_ip_addr_pool_load(npppd *);
-static int npppd_auth_realm_reload (npppd *);
-static void npppd_iface_binding_reload(npppd *, npppd_iface *, npppd_iface_binding *);
-static int realm_list_contains (slist *, const char *);
-static npppd_auth_base *realm_list_remove (slist *, const char *);
-
-CONFIG_FUNCTIONS(npppd_config, npppd, properties);
-PREFIXED_CONFIG_FUNCTIONS(ppp_config, npppd_ppp, pppd->properties, phy_label);
+int
+npppd_config_check(const char *path)
+{
+ struct npppd_conf conf;
-NAMED_PREFIX_CONFIG_DECL(npppd_ipcp_config, npppd_ipcp_config,
- npppd->properties, "ipcp", label);
-NAMED_PREFIX_CONFIG_FUNCTIONS(npppd_ipcp_config, npppd_ipcp_config,
- npppd->properties, "ipcp", label);
+ npppd_conf_init(&conf);
+ return npppd_conf_parse(&conf, path);
+}
/***********************************************************************
* Reading the configuration. This is the export function which
@@ -101,51 +91,18 @@ NAMED_PREFIX_CONFIG_FUNCTIONS(npppd_ipcp_config, npppd_ipcp_config,
int
npppd_reload_config(npppd *_this)
{
- int retval = -1;
- FILE *conffp = NULL;
- struct properties *proptmp = NULL;
+ int retval = -1;
+ struct npppd_conf conf;
- if ((conffp = priv_fopen(_this->config_file)) == NULL) {
- log_printf(LOG_ERR, "Load configuration from='%s' failed: %m",
- _this->config_file);
- retval = -1;
- goto fail;
- }
- if ((proptmp = properties_create(1061)) == NULL) {
- log_printf(LOG_ERR, "Load configuration from='%s' failed: %m",
- _this->config_file);
- retval = -1;
- goto fail;
- }
- if (properties_load(proptmp, conffp) != 0) {
- log_printf(LOG_ERR, "Load configuration from='%s' failed: %m",
+ npppd_conf_init(&conf);
+ if (npppd_conf_parse(&conf, _this->config_file) != 0) {
+ log_printf(LOG_ERR, "Load configuration from='%s' failed",
_this->config_file);
retval = -1;
goto fail;
}
- if (_this->properties != NULL) {
- /* swap */
- properties_remove_all(_this->properties);
- properties_put_all(_this->properties, proptmp);
- properties_destroy(proptmp);
- } else
- _this->properties = proptmp;
- proptmp = NULL;
-
- /* It is suitable for here as process sequence because of logging. */
- npppd_debug_log_reload(_this);
-
-#ifndef NO_DELAYED_RELOAD
- _this->delayed_reload = npppd_config_int(_this, "delayed_reload", 0);
- if (_this->delayed_reload < 0) {
- log_printf(LOG_WARNING, "Parse error at 'delayed_reload'");
- _this->delayed_reload = 0;
- }
-#endif
-
- _this->max_session = npppd_config_int(_this, "max_session",
- NPPPD_DEFAULT_MAX_PPP);
+ _this->conf = conf;
retval = 0;
log_printf(LOG_NOTICE, "Load configuration from='%s' successfully.",
@@ -153,10 +110,6 @@ npppd_reload_config(npppd *_this)
/* FALLTHROUGH */
fail:
- if (conffp != NULL)
- fclose(conffp);
- if (proptmp != NULL)
- properties_destroy(proptmp);
return retval;
}
@@ -165,29 +118,22 @@ fail:
int
npppd_modules_reload(npppd *_this)
{
- int i, rval;
+ int rval;
rval = 0;
- /* address pool */
- if (npppd_ip_addr_pool_load(_this) != 0)
+ if (npppd_pool_load(_this) != 0)
return -1;
- npppd_ipcp_config_load(_this);
-
npppd_auth_realm_reload(_this);
#ifdef USE_NPPPD_L2TP
- rval |= l2tpd_reload(&_this->l2tpd, _this->properties, "l2tpd", 1);
+ rval |= l2tpd_reload(&_this->l2tpd, &_this->conf.l2tp_confs);
#endif
#ifdef USE_NPPPD_PPTP
- rval |= pptpd_reload(&_this->pptpd, _this->properties, "pptpd",
- 1);
+ rval |= pptpd_reload(&_this->pptpd, &_this->conf.pptp_confs);
#endif
#ifdef USE_NPPPD_PPPOE
- rval |= pppoed_reload(&_this->pppoed, _this->properties, "pppoed", 0);
+ rval |= pppoed_reload(&_this->pppoed, &_this->conf.pppoe_confs);
#endif
- for (i = 0; i < countof(_this->iface_bind); i++)
- npppd_iface_binding_reload(_this, &_this->iface[i],
- &_this->iface_bind[i]);
return rval;
}
@@ -195,152 +141,14 @@ npppd_modules_reload(npppd *_this)
/***********************************************************************
* reload the configuration on each part
***********************************************************************/
-static void
-npppd_ipcp_config_load(npppd *_this)
-{
- int n;
- const char *val;
- char *tok, *buf0, buf[NPPPD_CONFIG_BUFSIZ];
-
- for (n = 0; n < countof(_this->ipcp_config); n++)
- memset(&_this->ipcp_config[n], 0, sizeof(npppd_ipcp_config));
- n = 0;
- if ((val = npppd_config_str(_this, "ipcp_list")) != NULL) {
- strlcpy(buf, val, sizeof(buf));
- buf0 = buf;
- while ((tok = strsep(&buf0, VAL_SEP)) != NULL) {
- if (tok[0] == '\0')
- continue;
- if (n >= countof(_this->ipcp_config)) {
- log_printf(LOG_WARNING,
- "number of the ipcp configuration reached "
- "limit=%d",
- (int)countof(_this->ipcp_config));
- break;
- }
- _this->ipcp_config[n].npppd = _this;
- npppd_ipcp_config_load0(&_this->ipcp_config[n], tok);
- n++;
- }
- } else {
- _this->ipcp_config[n].npppd = _this;
- npppd_ipcp_config_load0(&_this->ipcp_config[n++], NULL);
- }
-}
-
-/** load IPCP configuration */
-static void
-npppd_ipcp_config_load0(npppd_ipcp_config *_this, const char *label)
-{
- uint32_t ip_assign_flags;
- const char *val;
-
- if (label != NULL)
- strlcpy(_this->label, label, sizeof(_this->label));
- else
- memset(_this->label, 0, sizeof(_this->label));
-
- _this->initialized = 1;
-
- val = npppd_ipcp_config_str(_this, "name");
- if (val == NULL) {
- if (_this->label[0] == '\0')
- val = "default";
- else
- val = _this->label;
- }
- strlcpy(_this->name, val, sizeof(_this->name));
-
- /* IP address assignment policy */
- ip_assign_flags = 0;
- if (npppd_ipcp_config_str_equal(_this, "assign_userselect", "true", 1))
- ip_assign_flags |= NPPPD_IP_ASSIGN_USER_SELECT;
- else
- ip_assign_flags &= ~NPPPD_IP_ASSIGN_USER_SELECT;
-
- if (npppd_ipcp_config_str_equal(_this, "assign_fixed", "true", 1))
- ip_assign_flags |= NPPPD_IP_ASSIGN_FIXED;
- else
- ip_assign_flags &= ~NPPPD_IP_ASSIGN_FIXED;
-
- if (npppd_ipcp_config_str_equal(_this, "assign_radius", "true", 0))
- ip_assign_flags |= NPPPD_IP_ASSIGN_RADIUS;
- else
- ip_assign_flags &= ~NPPPD_IP_ASSIGN_RADIUS;
- _this->ip_assign_flags = ip_assign_flags;
-
-#define LOAD_IPADDR_SETTING(field, conf) \
- if ((val = npppd_ipcp_config_str(_this, conf)) == NULL || \
- strlen(val) <= 0) { \
- _this->field.s_addr = INADDR_NONE; \
- } else { \
- if (inet_aton(val, &_this->field) != 1) { \
- log_printf(LOG_ERR, "configuration error at " \
- conf ": parse error"); \
- } \
- _this->field = _this->field; \
- }
-
- _this->dns_use_tunnel_end = npppd_ipcp_config_str_equal(_this,
- "dns_use_tunnel_end", "true", 0);
- if (npppd_ipcp_config_str_equal(_this, "dns_use_resolver",
- "true", 0)) {
- if (load_resolv_conf(&_this->dns_pri, &_this->dns_sec) != 0)
- log_printf(LOG_ERR, "loading resolv.conf failed: %m");
- } else {
- LOAD_IPADDR_SETTING(dns_pri, "dns_primary");
- LOAD_IPADDR_SETTING(dns_sec, "dns_secondary");
- }
- LOAD_IPADDR_SETTING(nbns_pri, "nbns_primary");
- LOAD_IPADDR_SETTING(nbns_sec, "nbns_secondary");
-#undef LOAD_IPADDR_SETTING
-}
-
-/** reload the configuration for debug and the log file */
-static void
-npppd_debug_log_reload(npppd *_this)
-{
- int ival, oval;
- FILE *debugfp;
- const char *sval;
-
- if ((ival = npppd_config_int(_this, "debug.level", debuglevel)) ==
- debuglevel)
- return;
-
- /* change debug level */
- oval = debuglevel;
- debuglevel = ival;
- log_printf(LOG_NOTICE, "Debug level is changed %d => %d", oval, ival);
-
- debugfp = debug_get_debugfp();
- if (debugfp != stderr) {
- sval = npppd_config_str(_this, "debug.logpath");
- /* It is not foreground mode. */
- if (debugfp != NULL)
- fclose(debugfp);
- if (sval != NULL) {
- if ((debugfp = fopen(sval, "a+")) == NULL) {
- log_printf(LOG_ERR,
- "Failed to open logfile %s: %m", sval);
- } else {
- log_printf(LOG_INFO,
- "open logfile successfully %s", sval);
- debug_set_debugfp(debugfp);
- }
- }
- }
-}
-
/** load the configuration for IP address pool */
static int
-npppd_ip_addr_pool_load(npppd *_this)
+npppd_pool_load(npppd *_this)
{
int n, i, j;
- const char *val;
- char *tok, *buf0, buf[NPPPD_CONFIG_BUFSIZ];
- npppd_pool pool0[NPPPD_MAX_POOL];
+ npppd_pool pool0[NPPPD_MAX_IFACE];
struct radish_head *rd_curr, *rd_new;
+ struct ipcpconf *ipcp;
rd_curr = _this->rd;
rd_new = NULL;
@@ -354,36 +162,20 @@ npppd_ip_addr_pool_load(npppd *_this)
}
_this->rd = rd_new;
- /* load the configuration */
- if ((val = npppd_config_str(_this, "pool_list")) != NULL) {
- strlcpy(buf, val, sizeof(buf));
- buf0 = buf;
- while ((tok = strsep(&buf0, VAL_SEP)) != NULL) {
- if (tok[0] == '\0')
- continue;
- if (n >= countof(_this->pool)) {
- log_printf(LOG_WARNING,
- "number of the pool reached "
- "limit=%d",(int)countof(_this->pool));
- break;
- }
- if (npppd_pool_init(&pool0[n], _this, tok) != 0) {
- log_printf(LOG_WARNING, "Failed to initialize "
- "npppd_pool '%s': %m", tok);
- goto fail;
- }
- if (npppd_pool_reload(&pool0[n]) != 0)
- goto fail;
- n++;
+ TAILQ_FOREACH(ipcp, &_this->conf.ipcpconfs, entry) {
+ if (n >= countof(_this->pool)) {
+ log_printf(LOG_WARNING, "number of the pool reached "
+ "limit=%d",(int)countof(_this->pool));
+ break;
}
- } else {
- if (npppd_pool_init(&pool0[n], _this, "default") != 0) {
+ if (npppd_pool_init(&pool0[n], _this, ipcp->name) != 0) {
log_printf(LOG_WARNING, "Failed to initialize "
- "npppd_pool 'default': %m");
+ "npppd_pool '%s': %m", ipcp->name);
goto fail;
}
- if (npppd_pool_reload(&pool0[n++]) != 0)
+ if (npppd_pool_reload(&pool0[n]) != 0)
goto fail;
+ n++;
}
for (; n < countof(pool0); n++)
pool0[n].initialized = 0;
@@ -433,10 +225,9 @@ fail:
static int
npppd_auth_realm_reload(npppd *_this)
{
- int rval, ndef;
- const char *val;
- char buf[NPPPD_CONFIG_BUFSIZ * 2], *bufp, *tok;
- slist realms0, nrealms;
+ int rval;
+ slist realms0, nrealms;
+ struct authconf *auth;
npppd_auth_base *auth_base;
rval = 0;
@@ -449,115 +240,36 @@ npppd_auth_realm_reload(npppd *_this)
goto fail;
}
- ndef = 0;
- /* get the label of the local realm */
- if ((val = npppd_config_str(_this, "auth.local.realm_list")) != NULL) {
- ndef++;
- strlcpy(buf, val, sizeof(buf));
- bufp = buf;
- while ((tok = strsep(&bufp, VAL_SEP)) != NULL) {
- if (tok[0] == '\0')
- continue;
- if (realm_list_contains(&nrealms, tok)) {
- log_printf(LOG_WARNING,
- "label '%s' for auth.*.realm_list is not "
- "unique", tok);
- goto fail;
- }
- auth_base = realm_list_remove(&realms0, tok);
- if (auth_base != NULL &&
- npppd_auth_get_type(auth_base)
- != NPPPD_AUTH_TYPE_LOCAL) {
- /*
- * The type of authentication realm was changed in the
- * same label name.
- */
- slist_add(&realms0, auth_base);
- auth_base = NULL;
- }
- if (auth_base == NULL) {
- /* create newly */
- if ((auth_base = npppd_auth_create(
- NPPPD_AUTH_TYPE_LOCAL, tok, _this))
- == NULL) {
- log_printf(LOG_WARNING,
- "npppd_auth_create() failed in "
- "%s(): %m", __func__);
- goto fail;
- }
- }
- slist_add(&nrealms, auth_base);
- }
- }
-#ifdef USE_NPPPD_RADIUS
- /* get the label of the RADIUS realm */
- if ((val = npppd_config_str(_this, "auth.radius.realm_list")) != NULL) {
- ndef++;
- strlcpy(buf, val, sizeof(buf));
- bufp = buf;
- while ((tok = strsep(&bufp, VAL_SEP)) != NULL) {
- if (tok[0] == '\0')
- continue;
- if (realm_list_contains(&nrealms, tok)) {
- log_printf(LOG_WARNING,
- "label '%s' for auth.*.realm_list is not "
- "unique", tok);
- goto fail;
- }
- auth_base = realm_list_remove(&realms0, tok);
- if (auth_base != NULL &&
- npppd_auth_get_type(auth_base)
- != NPPPD_AUTH_TYPE_RADIUS) {
- /*
- * The type of authentication realm was changed in the
- * same label name.
- */
- slist_add(&realms0, auth_base);
- auth_base = NULL;
- }
- if (auth_base == NULL) {
- /* create newly */
- if ((auth_base = npppd_auth_create(
- NPPPD_AUTH_TYPE_RADIUS, tok, _this))
- == NULL) {
- log_printf(LOG_WARNING,
- "npppd_auth_create() failed in "
- "%s(): %m", __func__);
- goto fail;
- }
- }
- slist_add(&nrealms, auth_base);
+ TAILQ_FOREACH(auth, &_this->conf.authconfs, entry) {
+#ifndef USE_NPPPD_RADIUS
+ if (auth->auth_type == NPPPD_AUTH_TYPE_RADIUS) {
+ log_printf(LOG_WARNING, "radius support is not "
+ "enabled by compile time.");
+ continue;
}
- }
#endif
-#ifndef NO_DEFAULT_REALM
- if (ndef == 0) {
- /*
- * Compatibility for current implementation. Use default realm.
- */
- if (slist_length(&realms0) > 0) {
- slist_add_all(&nrealms, &realms0);
- slist_remove_all(&realms0);
- } else {
- if ((auth_base = npppd_auth_create(
- NPPPD_AUTH_TYPE_LOCAL, "", _this)) == NULL) {
- log_printf(LOG_WARNING,
- "malloc() failed in %s(): %m", __func__);
- goto fail;
- }
- slist_add(&nrealms, auth_base);
-#ifdef USE_NPPPD_RADIUS
- if ((auth_base = npppd_auth_create(
- NPPPD_AUTH_TYPE_RADIUS, "", _this)) == NULL) {
- log_printf(LOG_WARNING,
- "malloc() failed in %s(): %m", __func__);
+ auth_base = realm_list_remove(&realms0, auth->name);
+ if (auth_base != NULL &&
+ npppd_auth_get_type(auth_base) != auth->auth_type) {
+ /*
+ * The type of authentication has been changed in the
+ * same label name.
+ */
+ slist_add(&realms0, auth_base);
+ auth_base = NULL;
+ }
+
+ if (auth_base == NULL) {
+ /* create newly */
+ if ((auth_base = npppd_auth_create(auth->auth_type,
+ auth->name, _this)) == NULL) {
+ log_printf(LOG_WARNING, "npppd_auth_create() "
+ "failed in %s(): %m", __func__);
goto fail;
}
slist_add(&nrealms, auth_base);
-#endif
}
}
-#endif
if (slist_set_size(&_this->realms, slist_length(&nrealms)) != 0) {
log_printf(LOG_WARNING, "slist_set_size() failed in %s(): %m",
__func__);
@@ -598,22 +310,6 @@ fail:
return 1;
}
-static int
-realm_list_contains(slist *list0, const char *label)
-{
- npppd_auth_base *base;
-
- for (slist_itr_first(list0); slist_itr_has_next(list0); ) {
- base = slist_itr_next(list0);
- if (npppd_auth_is_disposing(base))
- continue;
- if (strcmp(npppd_auth_get_label(base), label) == 0)
- return 1;
- }
-
- return 0;
-}
-
static npppd_auth_base *
realm_list_remove(slist *list0, const char *label)
{
@@ -623,7 +319,7 @@ realm_list_remove(slist *list0, const char *label)
base = slist_itr_next(list0);
if (npppd_auth_is_disposing(base))
continue;
- if (strcmp(npppd_auth_get_label(base), label) == 0)
+ if (strcmp(npppd_auth_get_name(base), label) == 0)
return slist_itr_remove(list0);
}
@@ -634,140 +330,48 @@ realm_list_remove(slist *list0, const char *label)
int
npppd_ifaces_load_config(npppd *_this)
{
- int rval, n, nsession;
- const char *val;
- char *tok, *buf0, buf[BUFSIZ], buf1[128];
+ int i, n;
+ struct iface *iface;
+ npppd_iface *niface;
- rval = 0;
- n = 0;
- if ((val = npppd_config_str(_this, "interface_list")) != NULL) {
- strlcpy(buf, val, sizeof(buf));
- buf0 = buf;
- while ((tok = strsep(&buf0, VAL_SEP)) != NULL) {
- if (tok[0] == '\0')
- continue;
- if (n >= countof(_this->iface)) {
- log_printf(LOG_WARNING,
- "number of the interface reached "
- "limit=%d",(int)countof(_this->iface));
+ for (i = 0; i < countof(_this->iface); i++) {
+ if (_this->iface[i].initialized == 0)
+ continue;
+ TAILQ_FOREACH(iface, &_this->conf.ifaces, entry) {
+ if (strcmp(_this->iface[i].ifname, iface->name) == 0)
break;
- }
-
- strlcpy(buf1, "interface.", sizeof(buf1));
- strlcat(buf1, tok, sizeof(buf1));
-
- if (_this->iface[n].initialized != 0)
- nsession = _this->iface[n].nsession;
- else {
- int pppx;
-
- pppx = npppd_config_str_equal(_this,
- config_key_prefix(buf1, "pppx_mode"),
- "true", 0);
- npppd_iface_init(&_this->iface[n], tok, pppx);
- nsession = 0;
- }
-
- _this->iface[n].set_ip4addr = 0;
- if ((val = npppd_config_str(_this,
- config_key_prefix(buf1, "ip4addr"))) != NULL){
- if (inet_pton(AF_INET, val,
- &_this->iface[n].ip4addr) != 1) {
- log_printf(LOG_ERR,
- "configuration error at %s",
- config_key_prefix(buf1,
- "ip4addr"));
- return 1;
- }
- _this->iface[n].set_ip4addr = 1;
- }
-
- _this->iface[n].user_max_session = npppd_config_int(
- _this, config_key_prefix(buf1, "user_max_session"),
- NPPPD_DEFAULT_USER_MAX_PPP);
- _this->iface[n].max_session = npppd_config_int(_this,
- config_key_prefix(buf1, "max_session"),
- _this->max_session);
-
- _this->iface[n].nsession = nsession;
- _this->iface[n].npppd = _this;
- _this->iface[n].initialized = 1;
- n++;
}
- }
-
- return rval;
-}
-
-static void
-npppd_iface_binding_reload(npppd *_this, npppd_iface *iface,
- npppd_iface_binding *binding)
-{
- int i, using_default, had_ipcp;
- const char *val;
- char key[128], *tok, *buf0, buf[NPPPD_CONFIG_BUFSIZ];
-
- NPPPD_CONFIG_ASSERT(_this != NULL);
- NPPPD_CONFIG_ASSERT(iface != NULL);
- NPPPD_CONFIG_ASSERT(binding != NULL);
-
- had_ipcp = (binding->ipcp != NULL)? 1 : 0;
- slist_fini(&binding->pools);
- memset(binding, 0, sizeof(npppd_iface_binding));
- if (iface->initialized == 0)
- return;
-
-
- /* create the key */
- strlcpy(key, "interface.", sizeof(key));
- strlcat(key, iface->ifname, sizeof(key));
- strlcat(key, ".ipcp_configuration", sizeof(key));
-
- using_default = 0;
- if ((val = npppd_config_str(_this, key)) != NULL) {
- for (i = 0; i < countof(_this->ipcp_config); i++){
- if (_this->ipcp_config[i].initialized == 0)
- continue;
- if (strcmp(_this->ipcp_config[i].label, val) == 0) {
- binding->ipcp = &_this->ipcp_config[i];
- break;
- }
+ if (iface == NULL) {
+ npppd_iface_stop(&_this->iface[i]);
+ npppd_iface_fini(&_this->iface[i]);
}
- } else if (_this->ipcp_config[0].initialized != 0 &&
- _this->ipcp_config[0].label[0] == '\0') {
-#ifndef NO_DEFAULT_IPCP
- /* There is default IPCP configuration. */
- binding->ipcp = &_this->ipcp_config[0];
- using_default = 1;
-#else
- using_default = 0;
-#endif
- }
- slist_init(&binding->pools);
- if (binding->ipcp == NULL) {
- if (had_ipcp)
- log_printf(LOG_INFO, "%s has no ipcp", iface->ifname);
- return;
}
- if ((val = npppd_ipcp_config_str(binding->ipcp, "pool_list")) != NULL) {
- strlcpy(buf, val, sizeof(buf));
- buf0 = buf;
- while ((tok = strsep(&buf0, VAL_SEP)) != NULL) {
- if (tok[0] == '\0')
+ TAILQ_FOREACH(iface, &_this->conf.ifaces, entry) {
+ /* find the existing entry or first free entry */
+ niface = NULL;
+ for (i = 0; i < countof(_this->iface); i++) {
+ if (_this->iface[i].initialized == 0) {
+ if (niface == NULL)
+ niface = &_this->iface[i];
continue;
- for (i = 0; i < countof(_this->pool); i++) {
- if (_this->pool[i].initialized == 0)
- continue;
- if (strcmp(tok, _this->pool[i].label) != 0)
- continue;
- slist_add(&binding->pools, &_this->pool[i]);
+ }
+ if (strcmp(_this->iface[i].ifname, iface->name) == 0) {
+ niface = &_this->iface[i];
break;
}
}
- } else if (using_default) {
- if (_this->pool[0].initialized != 0)
- slist_add(&binding->pools, &_this->pool[0]);
+ if (niface == NULL) {
+ log_printf(LOG_WARNING,
+ "number of the interface reached limit=%d",
+ (int)countof(_this->iface));
+ break;
+ }
+ if (niface->initialized == 0)
+ npppd_iface_init(_this, niface, iface);
+ else
+ npppd_iface_reinit(niface, iface);
+ n++;
}
- log_printf(LOG_INFO, "%s is using ipcp=%s(%d pools).",
- iface->ifname, binding->ipcp->name, slist_length(&binding->pools));
+
+ return 0;
}
diff --git a/usr.sbin/npppd/npppd/npppd_ctl.c b/usr.sbin/npppd/npppd/npppd_ctl.c
index a190a02ac61..b99993e750d 100644
--- a/usr.sbin/npppd/npppd/npppd_ctl.c
+++ b/usr.sbin/npppd/npppd/npppd_ctl.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: npppd_ctl.c,v 1.9 2012/05/08 13:15:11 yasuoka Exp $ */
+/* $OpenBSD: npppd_ctl.c,v 1.10 2012/09/18 13:14:08 yasuoka Exp $ */
/*-
* Copyright (c) 2009 Internet Initiative Japan Inc.
@@ -30,7 +30,7 @@
* This file provides to open UNIX domain socket which located in
* /var/run/npppd_ctl and accept commmands from the npppdctl command.
*/
-/* $Id: npppd_ctl.c,v 1.9 2012/05/08 13:15:11 yasuoka Exp $ */
+/* $Id: npppd_ctl.c,v 1.10 2012/09/18 13:14:08 yasuoka Exp $ */
#include <sys/types.h>
#include <sys/param.h>
#include <sys/socket.h>
@@ -495,7 +495,7 @@ npppd_ppp_get_pipex_stat(struct npppd_who *_this, npppd_ppp *ppp)
memset(&req, 0, sizeof(req));
switch(ppp->tunnel_type) {
#ifdef USE_NPPPD_PPPOE
- case PPP_TUNNEL_PPPOE:
+ case NPPPD_TUNNEL_PPPOE:
pppoe = (pppoe_session *)ppp->phy_context;
/* PPPOE specific information */
@@ -504,7 +504,7 @@ npppd_ppp_get_pipex_stat(struct npppd_who *_this, npppd_ppp *ppp)
break;
#endif
#ifdef USE_NPPPD_PPTP
- case PPP_TUNNEL_PPTP:
+ case NPPPD_TUNNEL_PPTP:
call = (pptp_call *)ppp->phy_context;
/* PPTP specific information */
@@ -513,7 +513,7 @@ npppd_ppp_get_pipex_stat(struct npppd_who *_this, npppd_ppp *ppp)
break;
#endif
#ifdef USE_NPPPD_L2TP
- case PPP_TUNNEL_L2TP:
+ case NPPPD_TUNNEL_L2TP:
l2tp = (l2tp_call *)ppp->phy_context;
/* L2TP specific information */
diff --git a/usr.sbin/npppd/npppd/npppd_defs.h b/usr.sbin/npppd/npppd/npppd_defs.h
index a8553afa214..08a53c0f256 100644
--- a/usr.sbin/npppd/npppd/npppd_defs.h
+++ b/usr.sbin/npppd/npppd/npppd_defs.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: npppd_defs.h,v 1.7 2012/05/08 13:15:12 yasuoka Exp $ */
+/* $OpenBSD: npppd_defs.h,v 1.8 2012/09/18 13:14:08 yasuoka Exp $ */
/*-
* Copyright (c) 2009 Internet Initiative Japan Inc.
@@ -83,32 +83,6 @@
#define LOOPBACK_IFNAME "lo0"
#endif
-#ifndef NPPPD_DEFAULT_IP_ASSIGN_USER_SELECT
-#define NPPPD_DEFAULT_IP_ASSIGN_USER_SELECT 1
-#endif
-#ifndef NPPPD_DEFAULT_IP_ASSIGN_FIXED
-#define NPPPD_DEFAULT_IP_ASSIGN_FIXED 1
-#endif
-#ifndef NPPPD_DEFAULT_IP_ASSIGN_RADIUS
-#define NPPPD_DEFAULT_IP_ASSIGN_RADIUS 0
-#endif
-
-#ifndef DEFAULT_RTSOCK_EVENT_DELAY
-/**
- * delay time in seconds until npppd starts working when routing socket event
- * receive
- */
-#define DEFAULT_RTSOCK_EVENT_DELAY 5
-#endif
-#ifndef DEFAULT_RTSOCK_SEND_NPKTS
-/** numbers of packets to write to routing socket once */
-#define DEFAULT_RTSOCK_SEND_NPKTS 16
-#endif
-#ifndef DEFAULT_RTSOCK_SEND_WAIT_MILLISEC
-/** wait time in milliseconds to write to routing socket in-sequence */
-#define DEFAULT_RTSOCK_SEND_WAIT_MILLISEC 0
-#endif
-
#ifndef countof
#define countof(x) (sizeof(x) / sizeof((x)[0]))
#endif
diff --git a/usr.sbin/npppd/npppd/npppd_iface.c b/usr.sbin/npppd/npppd/npppd_iface.c
index 137ebc5cc06..fa19fbaaa59 100644
--- a/usr.sbin/npppd/npppd/npppd_iface.c
+++ b/usr.sbin/npppd/npppd/npppd_iface.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: npppd_iface.c,v 1.6 2012/05/08 13:15:12 yasuoka Exp $ */
+/* $OpenBSD: npppd_iface.c,v 1.7 2012/09/18 13:14:08 yasuoka Exp $ */
/*-
* Copyright (c) 2009 Internet Initiative Japan Inc.
@@ -25,7 +25,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
-/* $Id: npppd_iface.c,v 1.6 2012/05/08 13:15:12 yasuoka Exp $ */
+/* $Id: npppd_iface.c,v 1.7 2012/09/18 13:14:08 yasuoka Exp $ */
/**@file
* The interface of npppd and kernel.
* This is an implementation to use tun(4) or pppx(4).
@@ -35,12 +35,14 @@
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <sys/uio.h>
+#include <sys/sockio.h>
#include <netinet/in.h>
#include <netinet/in_systm.h>
#include <netinet/ip.h>
#include <arpa/inet.h>
#include <net/if_dl.h>
#include <net/if_tun.h>
+#include <net/if_types.h>
#include <fcntl.h>
@@ -100,15 +102,20 @@ static int npppd_iface_pipex_disable(npppd_iface *_this);
/** initialize npppd_iface */
void
-npppd_iface_init(npppd_iface *_this, const char *ifname, int pppx_mode)
+npppd_iface_init(npppd *npppd, npppd_iface *_this, struct iface *iface)
{
+
NPPPD_IFACE_ASSERT(_this != NULL);
memset(_this, 0, sizeof(npppd_iface));
+ _this->npppd = npppd;
+ strlcpy(_this->ifname, iface->name, sizeof(_this->ifname));
+ _this->using_pppx = iface->is_pppx;
+ _this->set_ip4addr = 1;
+ _this->ip4addr = iface->ip4addr;
+ _this->ipcpconf = iface->ipcpconf;
_this->devf = -1;
- strlcpy(_this->ifname, ifname, sizeof(_this->ifname));
-
- _this->using_pppx = pppx_mode;
+ _this->initialized = 1;
}
static int
@@ -135,35 +142,28 @@ npppd_iface_setup_ip(npppd_iface *_this)
strlcpy(ifra.ifra_name, _this->ifname, sizeof(ifra.ifra_name));
sin0 = (struct sockaddr_in *)&ifr.ifr_addr;
- if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
- npppd_iface_log(_this, LOG_ERR,
- "socket() failed in %s(): %m", __func__);
- goto fail;
- }
- if (ioctl(sock, SIOCGIFADDR, &ifr) != 0) {
+ if (priv_get_if_addr(_this->ifname, &assigned) != 0) {
if (errno != EADDRNOTAVAIL) {
npppd_iface_log(_this, LOG_ERR,
"get ip address failed: %m");
goto fail;
}
assigned.s_addr = 0;
- } else
- assigned = sin0->sin_addr;
+ }
if (assigned.s_addr != _this->ip4addr.s_addr)
changed = 1;
- memset(&ifr.ifr_ifru, 0, sizeof(ifr.ifr_ifru));
- if (ioctl(sock, SIOCGIFFLAGS, &ifr) != 0) {
+ if (priv_get_if_flags(_this->ifname, &if_flags) != 0) {
npppd_iface_log(_this, LOG_ERR,
"ioctl(,SIOCGIFFLAGS) failed: %m");
goto fail;
}
if_flags = ifr.ifr_flags;
-
if (_this->set_ip4addr != 0 && changed) {
do {
- if (ioctl(sock, SIOCDIFADDR, &ifr) != 0) {
+ struct in_addr dummy;
+ if (priv_delete_if_addr(_this->ifname) != 0) {
if (errno == EADDRNOTAVAIL)
break;
npppd_iface_log(_this, LOG_ERR,
@@ -171,7 +171,7 @@ npppd_iface_setup_ip(npppd_iface *_this)
_this->ifname);
goto fail;
}
- if (ioctl(sock, SIOCGIFADDR, &ifr) != 0) {
+ if (priv_get_if_addr(_this->ifname, &dummy) != 0) {
if (errno == EADDRNOTAVAIL)
break;
npppd_iface_log(_this, LOG_ERR,
@@ -181,34 +181,15 @@ npppd_iface_setup_ip(npppd_iface *_this)
}
} while (1);
-
/* ifconfig tun1 down */
- ifr.ifr_flags = if_flags & ~(IFF_UP | IFF_BROADCAST);
- if (ioctl(sock, SIOCSIFFLAGS, &ifr) != 0) {
+ if (priv_set_if_flags(_this->ifname,
+ if_flags & ~(IFF_UP | IFF_BROADCAST)) != 0) {
npppd_iface_log(_this, LOG_ERR,
"disabling %s failed: %m", _this->ifname);
goto fail;
}
-
- sin0 = (struct sockaddr_in *)&ifra.ifra_addr;
- sin0->sin_addr.s_addr = _this->ip4addr.s_addr;
- sin0->sin_family = AF_INET;
- sin0->sin_len = sizeof(struct sockaddr_in);
-
- sin0 = (struct sockaddr_in *)&ifra.ifra_mask;
- sin0->sin_addr.s_addr = 0xffffffffL;
- sin0->sin_family = AF_INET;
- sin0->sin_len = sizeof(struct sockaddr_in);
-
- sin0 = (struct sockaddr_in *)&ifra.ifra_broadaddr;
- sin0->sin_addr.s_addr = 0;
- sin0->sin_family = AF_INET;
- sin0->sin_len = sizeof(struct sockaddr_in);
-
- if (ioctl(sock, SIOCAIFADDR, &ifra) != 0 && errno != EEXIST) {
- /*
- * alias request, so EEXIST?
- */
+ if (priv_set_if_addr(_this->ifname, &_this->ip4addr) != 0 &&
+ errno != EEXIST) {
npppd_iface_log(_this, LOG_ERR,
"Cannot assign tun device ip address: %m");
goto fail;
@@ -220,7 +201,8 @@ npppd_iface_setup_ip(npppd_iface *_this)
if (npppd_iface_ip_is_ready(_this)) {
if (changed) {
/*
- * If there is a PPP session which was assigned interface IP address, disconnect it.
+ * If there is a PPP session which was assigned
+ * interface IP address, disconnect it.
*/
ppp = npppd_get_ppp_by_ip(_this->npppd, _this->ip4addr);
if (ppp != NULL) {
@@ -232,14 +214,15 @@ npppd_iface_setup_ip(npppd_iface *_this)
}
}
/* ifconfig tun1 up */
- ifr.ifr_flags = if_flags | IFF_UP | IFF_MULTICAST;
- if (ioctl(sock, SIOCSIFFLAGS, &ifr) != 0) {
+ if (priv_set_if_flags(_this->ifname,
+ if_flags | IFF_UP | IFF_MULTICAST) != 0) {
npppd_iface_log(_this, LOG_ERR,
"enabling %s failed: %m", _this->ifname);
goto fail;
}
/*
- * Add routing entry to communicate from host itself to _this->ip4addr.
+ * Add routing entry to communicate from host itself to
+ * _this->ip4addr.
*/
gw.s_addr = htonl(INADDR_LOOPBACK);
in_host_route_add(&_this->ip4addr, &gw, LOOPBACK_IFNAME, 0);
@@ -256,16 +239,18 @@ fail:
/** set tunnel end address */
int
-npppd_iface_reinit(npppd_iface *_this)
+npppd_iface_reinit(npppd_iface *_this, struct iface *iface)
{
int rval;
struct in_addr backup;
char buf0[128], buf1[128];
+ _this->ipcpconf = iface->ipcpconf;
+ backup = _this->ip4addr;
+ _this->ip4addr = iface->ip4addr;
+
if (_this->using_pppx)
return 0;
-
- backup = _this->ip4addr;
if ((rval = npppd_iface_setup_ip(_this)) != 0)
return rval;
@@ -287,14 +272,14 @@ npppd_iface_reinit(npppd_iface *_this)
int
npppd_iface_start(npppd_iface *_this)
{
- int x;
- char buf[MAXPATHLEN];
+ int x;
+ char buf[MAXPATHLEN];
NPPPD_IFACE_ASSERT(_this != NULL);
/* open device file */
snprintf(buf, sizeof(buf), "/dev/%s", _this->ifname);
- if ((_this->devf = open(buf, O_RDWR, 0600)) < 0) {
+ if ((_this->devf = priv_open(buf, O_RDWR, 0600)) < 0) {
npppd_iface_log(_this, LOG_ERR, "open(%s) failed: %m", buf);
goto fail;
}
@@ -310,8 +295,8 @@ npppd_iface_start(npppd_iface *_this)
x = IFF_BROADCAST;
if (ioctl(_this->devf, TUNSIFMODE, &x) != 0) {
npppd_iface_log(_this, LOG_ERR,
- "ioctl(TUNSIFMODE=IFF_BROADCAST) failed in %s(): %m",
- __func__);
+ "ioctl(TUNSIFMODE=IFF_BROADCAST) failed "
+ "in %s(): %m", __func__);
goto fail;
}
}
@@ -343,9 +328,10 @@ npppd_iface_start(npppd_iface *_this)
} else {
npppd_iface_log(_this, LOG_INFO, "Started ip4addr=%s",
(npppd_iface_ip_is_ready(_this))?
- inet_ntop(AF_INET, &_this->ip4addr, buf, sizeof(buf))
- : "(not assigned)");
+ inet_ntop(AF_INET, &_this->ip4addr, buf,
+ sizeof(buf)) : "(not assigned)");
}
+ _this->started = 1;
return 0;
fail:
@@ -362,8 +348,14 @@ fail:
void
npppd_iface_stop(npppd_iface *_this)
{
- NPPPD_IFACE_ASSERT(_this != NULL);
+ struct in_addr gw;
+ NPPPD_IFACE_ASSERT(_this != NULL);
+ if (_this->using_pppx == 0) {
+ priv_delete_if_addr(_this->ifname);
+ gw.s_addr = htonl(INADDR_LOOPBACK);
+ in_host_route_delete(&_this->ip4addr, &gw);
+ }
if (_this->devf >= 0) {
#ifdef USE_NPPPD_PIPEX
if (npppd_iface_pipex_disable(_this) != 0) {
@@ -377,7 +369,7 @@ npppd_iface_stop(npppd_iface *_this)
npppd_iface_log(_this, LOG_INFO, "Stopped");
}
_this->devf = -1;
- _this->initialized = 0;
+ _this->started = 0;
event_del(&_this->ev);
}
@@ -386,8 +378,7 @@ void
npppd_iface_fini(npppd_iface *_this)
{
NPPPD_IFACE_ASSERT(_this != NULL);
-
- npppd_iface_stop(_this);
+ _this->initialized = 0;
}
@@ -480,7 +471,7 @@ npppd_iface_network_input_delegate(struct radish *radish, void *args0)
/* output via MPPE if MPPE started */
mppe_pkt_output(&ppp->mppe, PPP_PROTO_IP, args->pktp,
args->lpktp);
- } else if (MPPE_REQUIRED(ppp)) {
+ } else if (MPPE_IS_REQUIRED(ppp)) {
/* in case MPPE not started but MPPE is mandatory, */
/* it is not necessary to log because of multicast. */
return 0;
@@ -541,7 +532,7 @@ npppd_iface_network_input_ipv4(npppd_iface *_this, u_char *pktp, int lpktp)
/* output via MPPE if MPPE started */
mppe_pkt_output(&ppp->mppe, PPP_PROTO_IP, pktp, lpktp);
return;
- } else if (MPPE_REQUIRED(ppp)) {
+ } else if (MPPE_IS_REQUIRED(ppp)) {
/* in case MPPE not started but MPPE is mandatory */
ppp_log(ppp, LOG_WARNING, "A packet received from network, "
"but MPPE is not started.");
diff --git a/usr.sbin/npppd/npppd/npppd_iface.h b/usr.sbin/npppd/npppd/npppd_iface.h
index 9ae21ce2e98..7a1b76f0496 100644
--- a/usr.sbin/npppd/npppd/npppd_iface.h
+++ b/usr.sbin/npppd/npppd/npppd_iface.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: npppd_iface.h,v 1.5 2012/05/08 13:15:12 yasuoka Exp $ */
+/* $OpenBSD: npppd_iface.h,v 1.6 2012/09/18 13:14:08 yasuoka Exp $ */
/*-
* Copyright (c) 2009 Internet Initiative Japan Inc.
@@ -25,8 +25,8 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
-#ifndef NPPPD_INTERFACE_H
-#define NPPPD_INTERFACE_H 1
+#ifndef NPPPD_IFACE_H
+#define NPPPD_IFACE_H 1
typedef struct _npppd_iface {
/** base of npppd structure */
@@ -41,13 +41,7 @@ typedef struct _npppd_iface {
/** for event(3) */
struct event ev;
- /** maximum PPP sessions per user */
- int user_max_session;
- /** maximum PPP sessions */
- int max_session;
-
- /** PPP sessions already connected */
- int nsession;
+ struct ipcpconf *ipcpconf;
int /**
* whether set IP address as npppd_iface's work or not.
@@ -56,20 +50,22 @@ typedef struct _npppd_iface {
set_ip4addr:1,
/** set if using pppx(4) rather than tun(4) */
using_pppx:1,
- /** initialized flag */
- initialized:1;
+ /** is initialized */
+ initialized:1,
+ /** is started */
+ started:1;
} npppd_iface;
/** whether interface IP address is usable or not */
-#define npppd_iface_ip_is_ready(int) \
- ((int)->initialized != 0 && (int)->ip4addr.s_addr != INADDR_ANY)
+#define npppd_iface_ip_is_ready(_iface) \
+ ((_iface)->initialized != 0 && (_iface)->ip4addr.s_addr != INADDR_ANY)
#ifdef __cplusplus
extern "C" {
#endif
-void npppd_iface_init (npppd_iface *, const char *, int);
-int npppd_iface_reinit (npppd_iface *);
+void npppd_iface_init (npppd *, npppd_iface *, struct iface *);
+int npppd_iface_reinit (npppd_iface *, struct iface *);
int npppd_iface_start (npppd_iface *);
void npppd_iface_stop (npppd_iface *);
void npppd_iface_fini (npppd_iface *);
diff --git a/usr.sbin/npppd/npppd/npppd_local.h b/usr.sbin/npppd/npppd/npppd_local.h
index 5a224da7a7a..366b22e082c 100644
--- a/usr.sbin/npppd/npppd/npppd_local.h
+++ b/usr.sbin/npppd/npppd/npppd_local.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: npppd_local.h,v 1.10 2012/05/08 13:18:37 yasuoka Exp $ */
+/* $OpenBSD: npppd_local.h,v 1.11 2012/09/18 13:14:08 yasuoka Exp $ */
/*-
* Copyright (c) 2009 Internet Initiative Japan Inc.
@@ -40,7 +40,6 @@
#include "slist.h"
#include "hash.h"
-#include "properties.h"
#include "debugutil.h"
#ifdef USE_NPPPD_RADIUS
@@ -67,8 +66,8 @@
#include "pppoe.h"
#endif
#include "npppd_auth.h"
-#include "npppd_iface.h"
#include "npppd.h"
+#include "npppd_iface.h"
#include "privsep.h"
@@ -93,10 +92,8 @@ typedef struct _npppd_ctl {
struct _npppd_pool {
/** base of npppd structure */
npppd *npppd;
- /** name of label */
- char label[NPPPD_GENERIC_NAME_LEN];
- /** name */
- char name[NPPPD_GENERIC_NAME_LEN];
+ /** ipcp name */
+ char ipcp_name[NPPPD_GENERIC_NAME_LEN];
/** size of sockaddr_npppd array */
int addrs_size;
/** pointer indicated to sockaddr_npppd array */
@@ -109,58 +106,6 @@ struct _npppd_pool {
running:1;
};
-/** structure of IPCP configuration */
-typedef struct _npppd_ipcp_config {
- /** name */
- char name[NPPPD_GENERIC_NAME_LEN];
- /** label (to associate with npppd structure) */
- char label[NPPPD_GENERIC_NAME_LEN];
- /** pointer indicated to parent npppd structure */
- npppd *npppd;
- /**
- * primary DNS server. INADDR_NONE if not inform peer this.
- * specified in network byte order.
- */
- struct in_addr dns_pri;
-
- /** secondary DNS server. INADDR_NONE if not inform peer this.
- * specified in network byte order.
- */
- struct in_addr dns_sec;
-
- /**
- * primary WINS server. INADDR_NONE if not inform peer this.
- * specified in network byte order.
- */
- struct in_addr nbns_pri;
-
- /**
- * secondary WINS server. INADDR_NONE if not inform peer this.
- * specified in network byte order.
- */
- struct in_addr nbns_sec;
-
- /**
- * bit flag which specifies the way of IP address assignment.
- * @see #NPPPD_IP_ASSIGN_FIXED
- * @see #NPPPD_IP_ASSIGN_USER_SELECT
- * @see #NPPPD_IP_ASSIGN_RADIUS
- */
- int ip_assign_flags;
-
- int /** whether use tunnel end point address as DNS server or not */
- dns_use_tunnel_end:1,
- /** whether initialized or not */
- initialized:1,
- reserved:30;
-} npppd_ipcp_config;
-
-/** structure which holds an interface of IPCP configuration and references of pool address */
-typedef struct _npppd_iface_binding {
- npppd_ipcp_config *ipcp;
- slist pools;
-} npppd_iface_binding;
-
/**
* npppd
*/
@@ -170,8 +115,8 @@ struct _npppd {
/** interface which concentrates PPP */
npppd_iface iface[NPPPD_MAX_IFACE];
- /** reference of interface of IPCP configuration and pool address */
- npppd_iface_binding iface_bind[NPPPD_MAX_IFACE];
+
+ npppd_pool *iface_pool[NPPPD_MAX_IFACE];
/** address pool */
npppd_pool pool[NPPPD_MAX_POOL];
@@ -179,9 +124,6 @@ struct _npppd {
/** radish pool which uses to manage allocated address */
struct radish_head *rd;
- /** IPCP configuration */
- npppd_ipcp_config ipcp_config[NPPPD_MAX_IPCP_CONFIG];
-
/** map of username to slist of npppd_ppp */
hash_table *map_user_ppp;
@@ -216,10 +158,7 @@ struct _npppd {
pppoed pppoed;
#endif
/** configuration file */
- struct properties * properties;
-
- /** user properties file */
- struct properties * users_props;
+ struct npppd_conf conf;
npppd_ctl ctl;
/** the time in seconds which process was started.*/
@@ -230,7 +169,8 @@ struct _npppd {
/** counter of reload configuration */
int16_t reloading_count;
- /** maximum PPP sessions */
+ int nsession;
+ int user_max_session;
int max_session;
u_int /** whether finalizing or not */
@@ -241,15 +181,9 @@ struct _npppd {
stop_by_error:1;
};
-#ifndef NPPPD_CONFIG_BUFSIZ
-#define NPPPD_CONFIG_BUFSIZ 65536 // 64K
-#endif
-#ifndef NPPPD_KEY_BUFSIZ
-#define NPPPD_KEY_BUFSIZ 512
-#endif
#define ppp_iface(ppp) (&(ppp)->pppd->iface[(ppp)->ifidx])
-#define ppp_ipcp(ppp) ((ppp)->pppd->iface_bind[(ppp)->ifidx].ipcp)
-#define ppp_pools(ppp) (&(ppp)->pppd->iface_bind[(ppp)->ifidx].pools)
+#define ppp_ipcp(ppp) ((ppp)->pppd->iface[(ppp)->ifidx].ipcpconf)
+#define ppp_pool(ppp) ((ppp)->pppd->iface_pool[(ppp)->ifidx])
#define SIN(sa) ((struct sockaddr_in *)(sa))
@@ -259,12 +193,18 @@ struct _npppd {
: (interval) + NPPPD_TIMER_TICK_IVAL \
- ((interval) % NPPPD_TIMER_TICK_IVAL))
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
void npppd_ctl_init (npppd_ctl *, npppd *, const char *);
int npppd_ctl_start (npppd_ctl *);
void npppd_ctl_stop (npppd_ctl *);
-#define sin46_port(x) (((x)->sa_family == AF_INET6) \
- ? ((struct sockaddr_in6 *)(x))->sin6_port \
- : ((struct sockaddr_in *)(x))->sin_port)
+#ifdef __cplusplus
+}
+#endif
#endif
diff --git a/usr.sbin/npppd/npppd/npppd_pool.c b/usr.sbin/npppd/npppd/npppd_pool.c
index c9f4160463c..1deb0aa1f8a 100644
--- a/usr.sbin/npppd/npppd/npppd_pool.c
+++ b/usr.sbin/npppd/npppd/npppd_pool.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: npppd_pool.c,v 1.6 2012/05/08 13:15:12 yasuoka Exp $ */
+/* $OpenBSD: npppd_pool.c,v 1.7 2012/09/18 13:14:08 yasuoka Exp $ */
/*-
* Copyright (c) 2009 Internet Initiative Japan Inc.
@@ -47,10 +47,8 @@
#include "slist.h"
#include "debugutil.h"
-#include "properties.h"
#include "addr_range.h"
#include "radish.h"
-#include "config_helper.h"
#include "npppd_local.h"
#include "npppd_pool.h"
#include "npppd_subr.h"
@@ -75,7 +73,6 @@
#define SHUFLLE_MARK 0xffffffffL
static int npppd_pool_log __P((npppd_pool *, int, const char *, ...)) __printflike(3, 4);
-static int in_addr_range_list_add_all (struct in_addr_range **, const char *);
static int is_valid_host_address (uint32_t);
static int npppd_pool_regist_radish(npppd_pool *, struct in_addr_range *,
struct sockaddr_npppd *, int );
@@ -90,7 +87,7 @@ npppd_pool_init(npppd_pool *_this, npppd *base, const char *name)
{
memset(_this, 0, sizeof(npppd_pool));
- strlcpy(_this->label, name, sizeof(_this->label));
+ strlcpy(_this->ipcp_name, name, sizeof(_this->ipcp_name));
_this->npppd = base;
slist_init(&_this->dyna_addrs);
@@ -106,12 +103,6 @@ npppd_pool_start(npppd_pool *_this)
return 0; /* nothing to do */
}
-/* expand config template */;
-NAMED_PREFIX_CONFIG_DECL(npppd_pool_config, npppd_pool, npppd->properties,
- "pool", label);
-NAMED_PREFIX_CONFIG_FUNCTIONS(npppd_pool_config, npppd_pool, npppd->properties,
- "pool", label);
-
/** Finalize npppd_poll. */
void
npppd_pool_uninit(npppd_pool *_this)
@@ -133,45 +124,21 @@ npppd_pool_reload(npppd_pool *_this)
int i, count, addrs_size;
struct sockaddr_npppd *addrs;
struct in_addr_range *pool, *dyna_pool, *range;
- const char *val, *val0;
char buf0[BUFSIZ], buf1[BUFSIZ];
+ struct ipcpconf *ipcp;
addrs = NULL;
pool = NULL;
dyna_pool = NULL;
buf0[0] = '\0';
- val = npppd_pool_config_str(_this, "name");
- if (val == NULL)
- val = _this->label;
- strlcpy(_this->name, val, sizeof(_this->name));
-
- /* dynamic address pool */
- val0 = NULL;
- val = npppd_pool_config_str(_this, "dyna_pool");
- if (val != NULL) {
- if (in_addr_range_list_add_all(&dyna_pool, val) != 0) {
- npppd_pool_log(_this, LOG_WARNING,
- "parse error at 'dyna_pool': %s", val);
- goto fail;
+ TAILQ_FOREACH(ipcp, &_this->npppd->conf.ipcpconfs, entry) {
+ if (strcmp(ipcp->name, _this->ipcp_name) == 0) {
+ dyna_pool = ipcp->dynamic_pool;
+ pool = ipcp->static_pool;
}
- val0 = val;
}
- /* static address pool */
- val = npppd_pool_config_str(_this, "pool");
- if (val != NULL) {
- if (in_addr_range_list_add_all(&pool, val) != 0) {
- npppd_pool_log(_this, LOG_WARNING,
- "parse error at 'pool': %s", val);
- goto fail;
- }
- if (val0 != NULL)
- /* Aggregate */
- in_addr_range_list_add_all(&pool, val0);
- }
-
- /* preparing to register address with RADISH. */
addrs_size = 0;
for (range = dyna_pool; range != NULL; range = range->next)
addrs_size++;
@@ -240,14 +207,9 @@ npppd_pool_reload(npppd_pool *_this)
free(_this->addrs);
_this->addrs = addrs;
_this->addrs_size = addrs_size;
- in_addr_range_list_remove_all(&pool);
- in_addr_range_list_remove_all(&dyna_pool);
return 0;
fail:
- in_addr_range_list_remove_all(&pool);
- in_addr_range_list_remove_all(&dyna_pool);
-
if (addrs != NULL)
free(addrs);
@@ -296,7 +258,7 @@ npppd_pool_regist_radish(npppd_pool *_this, struct in_addr_range *range,
npppd_pool_log(_this, LOG_WARNING,
"%d.%d.%d.%d/%d is already defined as '%s'(%s)",
A(range->addr), netmask2prefixlen(range->mask),
- npool0->name, (snp0->snp_type == SNP_POOL)
+ npool0->ipcp_name, (snp0->snp_type == SNP_POOL)
? "static" : "dynamic");
goto fail;
}
@@ -610,27 +572,10 @@ npppd_pool_log(npppd_pool *_this, int prio, const char *fmt, ...)
* so it can't NPPPD_POOL_ASSERT(_this != NULL).
*/
va_start(ap, fmt);
- snprintf(logbuf, sizeof(logbuf), "pool name=%s %s",
- (_this == NULL)? "null" : _this->name, fmt);
+ snprintf(logbuf, sizeof(logbuf), "ipcp=%s pool %s",
+ (_this == NULL)? "null" : _this->ipcp_name, fmt);
status = vlog_printf(prio, logbuf, ap);
va_end(ap);
return status;
}
-
-static int
-in_addr_range_list_add_all(struct in_addr_range **range, const char *str)
-{
- char *tok, *buf0, buf[NPPPD_CONFIG_BUFSIZ];
-
- strlcpy(buf, str, sizeof(buf));
- buf0 = buf;
-
- while ((tok = strsep(&buf0, " \r\n\t")) != NULL) {
- if (tok[0] == '\0')
- continue;
- if (in_addr_range_list_add(range, tok) != 0)
- return 1;
- }
- return 0;
-}
diff --git a/usr.sbin/npppd/npppd/npppd_radius.c b/usr.sbin/npppd/npppd/npppd_radius.c
index 02db2dd8fbc..a405862de9f 100644
--- a/usr.sbin/npppd/npppd/npppd_radius.c
+++ b/usr.sbin/npppd/npppd/npppd_radius.c
@@ -1,4 +1,4 @@
-/* $Id: npppd_radius.c,v 1.4 2012/06/05 06:31:27 yasuoka Exp $ */
+/* $Id: npppd_radius.c,v 1.5 2012/09/18 13:14:08 yasuoka Exp $ */
/*-
* Copyright (c) 2009 Internet Initiative Japan Inc.
* All rights reserved.
@@ -199,7 +199,7 @@ radius_acct_request(npppd *pppd, npppd_ppp *ppp, int stop)
goto fail;
if (radius_prepare(rad_setting, (void *)(uintptr_t)ppp->id, &radctx,
- npppd_ppp_radius_acct_reqcb, 0) != 0)
+ npppd_ppp_radius_acct_reqcb) != 0)
goto fail;
/* NAS Information */
@@ -222,13 +222,13 @@ radius_acct_request(npppd *pppd, npppd_ppp *ppp, int stop)
/* Tunnel Protocol Information */
switch (ppp->tunnel_type) {
- case PPP_TUNNEL_L2TP:
+ case NPPPD_TUNNEL_L2TP:
/* RFC 2868 3.1. Tunnel-Type */
ATTR_INT32(RADIUS_TYPE_TUNNEL_TYPE, RADIUS_TUNNEL_TYPE_L2TP);
if (l2tp_put_tunnel_attributes(radpkt, ppp->phy_context) != 0)
goto fail;
break;
- case PPP_TUNNEL_PPTP:
+ case NPPPD_TUNNEL_PPTP:
/* RFC 2868 3.1. Tunnel-Type */
ATTR_INT32(RADIUS_TYPE_TUNNEL_TYPE, RADIUS_TUNNEL_TYPE_PPTP);
if (pptp_put_tunnel_attributes(radpkt, ppp->phy_context) != 0)
diff --git a/usr.sbin/npppd/npppd/pap.c b/usr.sbin/npppd/npppd/pap.c
index aff752dd3d0..73eb31da384 100644
--- a/usr.sbin/npppd/npppd/pap.c
+++ b/usr.sbin/npppd/npppd/pap.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pap.c,v 1.6 2012/05/08 13:23:53 yasuoka Exp $ */
+/* $OpenBSD: pap.c,v 1.7 2012/09/18 13:14:08 yasuoka Exp $ */
/*-
* Copyright (c) 2009 Internet Initiative Japan Inc.
@@ -25,7 +25,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
-/* $Id: pap.c,v 1.6 2012/05/08 13:23:53 yasuoka Exp $ */
+/* $Id: pap.c,v 1.7 2012/09/18 13:14:08 yasuoka Exp $ */
/**@file
* This file provides Password Authentication Protocol (PAP) handlers.
* @author Yasuoka Masahiko
@@ -401,8 +401,8 @@ pap_radius_authenticate(pap *_this, const char *username, const char *password)
== NULL)
goto fail;
- if (radius_prepare(rad_setting, _this, &radctx,
- pap_radius_response, _this->ppp->auth_timeout) != 0) {
+ if (radius_prepare(rad_setting, _this, &radctx, pap_radius_response)
+ != 0) {
radius_delete_packet(radpkt);
goto fail;
}
diff --git a/usr.sbin/npppd/npppd/parse.y b/usr.sbin/npppd/npppd/parse.y
new file mode 100644
index 00000000000..cd2845da4f4
--- /dev/null
+++ b/usr.sbin/npppd/npppd/parse.y
@@ -0,0 +1,1551 @@
+/* $OpenBSD: parse.y,v 1.1 2012/09/18 13:14:08 yasuoka Exp $ */
+
+/*
+ * Copyright (c) 2002, 2003, 2004 Henning Brauer <henning@openbsd.org>
+ * Copyright (c) 2001 Markus Friedl. All rights reserved.
+ * Copyright (c) 2001 Daniel Hartmeier. All rights reserved.
+ * Copyright (c) 2001 Theo de Raadt. All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+%{
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/queue.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <net/if.h>
+
+#include <ctype.h>
+#include <errno.h>
+#include <limits.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <syslog.h>
+#include <netdb.h>
+#include <event.h>
+
+#include <stdbool.h>
+#include <stdarg.h>
+#include "npppd_auth.h"
+#include "slist.h"
+#include "npppd.h"
+#ifdef USE_NPPPD_RADIUS
+#include "radius_req.h"
+#endif
+#include "privsep.h"
+
+TAILQ_HEAD(files, file) files = TAILQ_HEAD_INITIALIZER(files);
+static struct file {
+ TAILQ_ENTRY(file) entry;
+ FILE *stream;
+ char *name;
+ int lineno;
+ int errors;
+} *file, *topfile;
+struct file *pushfile(const char *);
+int popfile(void);
+int yyparse(void);
+int yylex(void);
+int yyerror(const char *, ...);
+int kw_cmp(const void *, const void *);
+int lookup(char *);
+int lgetc(int);
+int lungetc(int);
+int findeol(void);
+
+static void tunnconf_init (struct tunnconf *, int);
+static void tunnconf_fini (struct tunnconf *);
+static struct tunnconf *tunnconf_find (const char *);
+static void authconf_init (struct authconf *);
+static void authconf_fini (struct authconf *);
+static void radconf_fini (struct radconf *);
+static struct authconf *authconf_find (const char *);
+static void ipcpconf_init (struct ipcpconf *);
+static void ipcpconf_fini (struct ipcpconf *);
+static struct ipcpconf *ipcpconf_find (const char *);
+struct iface *iface_find (const char *);
+
+struct npppd_conf *conf;
+struct ipcpconf *curr_ipcpconf;
+struct tunnconf *curr_tunnconf;
+struct authconf *curr_authconf;
+struct radconf *curr_radconf;
+
+typedef struct {
+ union {
+ int64_t number;
+ char *string;
+ struct sockaddr_storage address;
+ struct in_addr in4_addr;
+ bool yesno;
+ } v;
+ int lineno;
+} YYSTYPE;
+
+%}
+
+%token SET MAX_SESSION USER_MAX_SESSION
+%token TUNNEL LISTEN ON PROTOCOL
+%token MRU
+%token IP LCP PAP CHAP EAP MPPE CCP MSCHAPV2 STATEFUL STATELESS REQUIRED
+%token YES NO
+%token L2TP PPTP PPPOE L2TP_HOSTNAME L2TP_VENDOR_NAME L2TP_DATA_USE_SEQ
+%token L2TP_REQUIRE_IPSEC L2TP_LCP_RENEGOTIATION L2TP_FORCE_LCP_RENEGOTIATION
+%token L2TP_CTRL_IN_PKTDUMP L2TP_CTRL_OUT_PKTDUMP L2TP_DATA_IN_PKTDUMP
+%token L2TP_DATA_OUT_PKTDUMP PPTP_HOSTNAME
+%token PPTP_VENDOR_NAME PPTP_ECHO_INTERVAL PPTP_ECHO_TIMEOUT
+%token PPTP_CTRL_IN_PKTDUMP PPTP_CTRL_OUT_PKTDUMP PPTP_DATA_IN_PKTDUMP
+%token PPTP_DATA_OUT_PKTDUMP
+%token PPPOE_SERVICE_NAME PPPOE_ACCEPT_ANY_SERVICE PPPOE_AC_NAME
+%token PPPOE_DESC_IN_PKTDUMP PPPOE_DESC_OUT_PKTDUMP PPPOE_SESSION_IN_PKTDUMP
+%token PPPOE_SESSION_OUT_PKTDUMP
+%token LCP_TIMEOUT LCP_MAX_CONFIGURE LCP_MAX_TERMINATE LCP_MAX_NAK_LOOP
+%token LCP_KEEPALIVE LCP_KEEPALIVE_INTERVAL LCP_KEEPALIVE_RETRY_INTERVAL
+%token LCP_KEEPALIVE_MAX_RETRIES AUTHENTICATION_METHOD CHAP_NAME
+%token IPCP_TIMEOUT IPCP_MAX_CONFIGURE IPCP_MAX_TERMINATE IPCP_MAX_NAK_LOOP
+%token CCP_TIMEOUT CCP_MAX_CONFIGURE CCP_MAX_TERMINATE CCP_MAX_NAK_LOOP
+%token L2TP_HELLO_INTERVAL L2TP_HELLO_TIMEOUT L2TP_ACCEPT_DIALIN
+%token MPPE MPPE_KEY_LENGTH MPPE_KEY_STATE
+%token IDLE_TIMEOUT TCP_MSS_ADJUST INGRESS_FILTER CALLNUM_CHECK
+%token PIPEX DEBUG_DUMP_PKTIN DEBUG_DUMP_PKTOUT
+%token AUTHENTICATION TYPE LOCAL USERNAME_SUFFIX USERNAME_PREFIX EAP_CAPABLE
+%token STRIP_NT_DOMAIN STRIP_ATMARK_REALM USERS_FILE
+%token RADIUS AUTHENTICATION_SERVER ACCOUNTING_SERVER PORT
+%token X_TIMEOUT MAX_TRIES MAX_FAILOVERS SECRET
+%token POOL_ADDRESS DNS_SERVERS NBNS_SERVERS FOR STATIC DYNAMIC
+%token RESOLVER ALLOW_USER_SELECTED_ADDRESS
+%token INTERFACE ADDRESS IPCP
+%token BIND FROM AUTHENTICATED BY TO
+%token ERROR
+%token <v.string> STRING
+%token <v.number> NUMBER
+%type <v.yesno> yesno
+%type <v.address> address
+%type <v.address> addressport
+%type <v.number> optport
+%type <v.in4_addr> in4_addr
+%type <v.number> tunnelproto
+%type <v.number> mppeyesno
+%type <v.number> mppekeylen
+%type <v.number> mppekeylen_l
+%type <v.number> mppekeystate
+%type <v.number> mppekeystate_l
+%type <v.number> protobit
+%type <v.number> protobit_l
+%type <v.number> authtype
+%type <v.number> authmethod
+%type <v.number> authmethod_l
+%type <v.number> ipcppooltype
+
+%%
+
+grammar : /* empty */
+ | grammar '\n'
+ | grammar set '\n'
+ | grammar tunnel '\n'
+ | grammar authentication '\n'
+ | grammar ipcp '\n'
+ | grammar interface '\n'
+ | grammar bind '\n'
+ | grammar error '\n' { file->errors++; }
+ ;
+
+
+set : SET MAX_SESSION NUMBER { conf->max_session = $3; }
+ | SET USER_MAX_SESSION NUMBER { conf->user_max_session = $3; }
+ ;
+
+/*
+ * tunnel { }
+ */
+tunnel : TUNNEL STRING PROTOCOL tunnelproto {
+ struct tunnconf *n;
+
+ if (tunnconf_find($2) != NULL) {
+ yyerror("tunnel name = %s is already in use.",
+ $2);
+ free($2);
+ YYERROR;
+ }
+
+ if ((n = malloc(sizeof(struct tunnconf))) == NULL) {
+ yyerror("out of memory");
+ free($2);
+ YYERROR;
+ }
+ tunnconf_init(n, $4);
+ switch ($4) {
+ case NPPPD_TUNNEL_L2TP:
+ strlcpy(n->proto.l2tp.name, $2,
+ sizeof(n->proto.l2tp.name));
+ n->name = n->proto.l2tp.name;
+ break;
+ case NPPPD_TUNNEL_PPTP:
+ strlcpy(n->proto.pptp.name, $2,
+ sizeof(n->proto.pptp.name));
+ n->name = n->proto.pptp.name;
+ break;
+ case NPPPD_TUNNEL_PPPOE:
+ strlcpy(n->proto.pppoe.name, $2,
+ sizeof(n->proto.pppoe.name));
+ n->name = n->proto.pppoe.name;
+ break;
+ }
+ free($2);
+ n->protocol = $4;
+ curr_tunnconf = n;
+ } tunnopts {
+ TAILQ_INSERT_TAIL(&conf->tunnconfs, curr_tunnconf,
+ entry);
+ switch (curr_tunnconf->protocol) {
+#ifdef USE_NPPPD_L2TP
+ case NPPPD_TUNNEL_L2TP:
+ TAILQ_INSERT_TAIL(&conf->l2tp_confs,
+ &curr_tunnconf->proto.l2tp, entry);
+ break;
+#endif
+#ifdef USE_NPPPD_PPTP
+ case NPPPD_TUNNEL_PPTP:
+ TAILQ_INSERT_TAIL(&conf->pptp_confs,
+ &curr_tunnconf->proto.pptp, entry);
+ break;
+#endif
+#ifdef USE_NPPPD_PPPOE
+ case NPPPD_TUNNEL_PPPOE:
+ TAILQ_INSERT_TAIL(&conf->pppoe_confs,
+ &curr_tunnconf->proto.pppoe, entry);
+ break;
+#endif
+ default:
+ yyerror("%s is not enabled.",
+ npppd_tunnel_protocol_name(
+ curr_tunnconf->protocol));
+ tunnconf_fini(curr_tunnconf);
+ free(curr_tunnconf);
+ YYERROR;
+ }
+ curr_tunnconf = NULL;
+ }
+ ;
+
+
+tunnopts :
+ | '{' optnl tunnopt_l '}'
+ ;
+
+tunnopt_l : /* empty */
+ | tunnopt_l tunnopt nl
+ | tunnopt optnl
+ ;
+
+tunnopt : LISTEN ON addressport {
+ switch (curr_tunnconf->protocol) {
+ case NPPPD_TUNNEL_L2TP:
+ curr_tunnconf->proto.l2tp.address = $3;
+ break;
+ case NPPPD_TUNNEL_PPTP:
+ curr_tunnconf->proto.pptp.address = $3;
+ break;
+ default:
+ yyerror("listen on address is not supported "
+ "for specified protocol.\n");
+ YYERROR;
+ }
+ }
+ | LISTEN ON INTERFACE STRING {
+ switch (curr_tunnconf->protocol) {
+ case NPPPD_TUNNEL_PPPOE:
+ strlcpy(curr_tunnconf->proto.pppoe.if_name, $4,
+ sizeof(curr_tunnconf->proto.pppoe.if_name));
+ free($4);
+ break;
+ default:
+ free($4);
+ yyerror("listen on interface is not supported "
+ "for specified protocol.\n");
+ YYERROR;
+ }
+ }
+ | LCP_TIMEOUT NUMBER {
+ curr_tunnconf->lcp_timeout = $2;
+ }
+ | LCP_MAX_CONFIGURE NUMBER {
+ curr_tunnconf->lcp_max_configure = $2;
+ }
+ | LCP_MAX_TERMINATE NUMBER {
+ curr_tunnconf->lcp_max_terminate = $2;
+ }
+ | LCP_MAX_NAK_LOOP NUMBER {
+ curr_tunnconf->lcp_max_nak_loop = $2;
+ }
+ | MRU NUMBER {
+ curr_tunnconf->mru = $2;
+ }
+ | LCP_KEEPALIVE yesno {
+ curr_tunnconf->lcp_keepalive = $2;
+ }
+ | LCP_KEEPALIVE_INTERVAL NUMBER {
+ curr_tunnconf->lcp_keepalive_interval = $2;
+ }
+ | LCP_KEEPALIVE_RETRY_INTERVAL NUMBER {
+ curr_tunnconf->lcp_keepalive_retry_interval = $2;
+ }
+ | LCP_KEEPALIVE_MAX_RETRIES NUMBER {
+ curr_tunnconf->lcp_keepalive_max_retries = $2;
+ }
+ | AUTHENTICATION_METHOD authmethod_l {
+ curr_tunnconf->auth_methods = $2;
+ }
+ | CHAP_NAME STRING {
+ curr_tunnconf->chap_name = $2;
+ }
+ | IPCP_TIMEOUT NUMBER {
+ curr_tunnconf->ipcp_timeout = $2;
+ }
+ | IPCP_MAX_CONFIGURE NUMBER {
+ curr_tunnconf->ipcp_max_configure = $2;
+ }
+ | IPCP_MAX_TERMINATE NUMBER {
+ curr_tunnconf->ipcp_max_terminate = $2;
+ }
+ | IPCP_MAX_NAK_LOOP NUMBER {
+ curr_tunnconf->ipcp_max_nak_loop = $2;
+ }
+ | CCP_TIMEOUT NUMBER {
+ curr_tunnconf->ccp_timeout = $2;
+ }
+ | CCP_MAX_CONFIGURE NUMBER {
+ curr_tunnconf->ccp_max_configure = $2;
+ }
+ | CCP_MAX_TERMINATE NUMBER {
+ curr_tunnconf->ccp_max_terminate = $2;
+ }
+ | CCP_MAX_NAK_LOOP NUMBER {
+ curr_tunnconf->ccp_max_nak_loop = $2;
+ }
+ | L2TP_HOSTNAME STRING {
+ curr_tunnconf->proto.l2tp.hostname = $2;
+ }
+ | L2TP_VENDOR_NAME STRING {
+ curr_tunnconf->proto.l2tp.vendor_name = $2;
+ }
+ | L2TP_HELLO_INTERVAL NUMBER {
+ curr_tunnconf->proto.l2tp.hello_interval = $2;
+ }
+ | L2TP_HELLO_TIMEOUT NUMBER {
+ curr_tunnconf->proto.l2tp.hello_timeout = $2;
+ }
+ | L2TP_ACCEPT_DIALIN yesno {
+ curr_tunnconf->proto.l2tp.accept_dialin = $2;
+ }
+ | L2TP_DATA_USE_SEQ yesno {
+ curr_tunnconf->proto.l2tp.data_use_seq = $2;
+ }
+ | L2TP_REQUIRE_IPSEC yesno {
+ curr_tunnconf->proto.l2tp.require_ipsec = $2;
+ }
+ | L2TP_LCP_RENEGOTIATION yesno {
+ curr_tunnconf->proto.l2tp.lcp_renegotiation = $2;
+ }
+ | L2TP_FORCE_LCP_RENEGOTIATION yesno {
+ curr_tunnconf->proto.l2tp.force_lcp_renegotiation = $2;
+ }
+ | L2TP_CTRL_IN_PKTDUMP yesno {
+ curr_tunnconf->proto.l2tp.ctrl_in_pktdump = $2;
+ }
+ | L2TP_CTRL_OUT_PKTDUMP yesno {
+ curr_tunnconf->proto.l2tp.ctrl_out_pktdump = $2;
+ }
+ | L2TP_DATA_IN_PKTDUMP yesno {
+ curr_tunnconf->proto.l2tp.data_in_pktdump = $2;
+ }
+ | L2TP_DATA_OUT_PKTDUMP yesno {
+ curr_tunnconf->proto.l2tp.data_out_pktdump = $2;
+ }
+ | PPTP_HOSTNAME STRING {
+ curr_tunnconf->proto.pptp.hostname = $2;
+ }
+ | PPTP_VENDOR_NAME STRING {
+ curr_tunnconf->proto.pptp.vendor_name = $2;
+ }
+ | PPTP_ECHO_INTERVAL NUMBER {
+ curr_tunnconf->proto.pptp.echo_interval = $2;
+ }
+ | PPTP_ECHO_TIMEOUT NUMBER {
+ curr_tunnconf->proto.pptp.echo_timeout = $2;
+ }
+ | PPTP_CTRL_IN_PKTDUMP yesno {
+ curr_tunnconf->proto.pptp.ctrl_in_pktdump = $2;
+ }
+ | PPTP_CTRL_OUT_PKTDUMP yesno {
+ curr_tunnconf->proto.pptp.ctrl_out_pktdump = $2;
+ }
+ | PPTP_DATA_IN_PKTDUMP yesno {
+ curr_tunnconf->proto.pptp.data_in_pktdump = $2;
+ }
+ | PPTP_DATA_OUT_PKTDUMP yesno {
+ curr_tunnconf->proto.pptp.data_out_pktdump = $2;
+ }
+ | PPPOE_SERVICE_NAME STRING {
+ curr_tunnconf->proto.pppoe.service_name = $2;
+ }
+ | PPPOE_ACCEPT_ANY_SERVICE yesno {
+ curr_tunnconf->proto.pppoe.accept_any_service = $2;
+ }
+ | PPPOE_AC_NAME STRING {
+ curr_tunnconf->proto.pppoe.ac_name = $2;
+ }
+ | PPPOE_DESC_IN_PKTDUMP yesno {
+ curr_tunnconf->proto.pppoe.desc_in_pktdump = $2;
+ }
+ | PPPOE_DESC_OUT_PKTDUMP yesno {
+ curr_tunnconf->proto.pppoe.desc_out_pktdump = $2;
+ }
+ | PPPOE_SESSION_IN_PKTDUMP yesno {
+ curr_tunnconf->proto.pppoe.session_in_pktdump = $2;
+ }
+ | PPPOE_SESSION_OUT_PKTDUMP yesno {
+ curr_tunnconf->proto.pppoe.session_out_pktdump = $2;
+ }
+ | MPPE mppeyesno {
+ curr_tunnconf->mppe_yesno = $2;
+ }
+ | MPPE_KEY_LENGTH mppekeylen_l {
+ curr_tunnconf->mppe_keylen = $2;
+ }
+ | MPPE_KEY_STATE mppekeystate_l {
+ curr_tunnconf->mppe_keystate = $2;
+ }
+ | TCP_MSS_ADJUST yesno {
+ curr_tunnconf->tcp_mss_adjust = $2;
+ }
+ | IDLE_TIMEOUT NUMBER {
+ curr_tunnconf->idle_timeout = $2;
+ }
+ | INGRESS_FILTER yesno {
+ curr_tunnconf->ingress_filter = $2;
+ }
+ | CALLNUM_CHECK yesno {
+ curr_tunnconf->callnum_check = $2;
+ }
+ | PIPEX yesno {
+ curr_tunnconf->pipex = $2;
+ }
+ | DEBUG_DUMP_PKTIN protobit_l {
+ curr_tunnconf->debug_dump_pktin = $2;
+ }
+ | DEBUG_DUMP_PKTOUT protobit_l {
+ curr_tunnconf->debug_dump_pktout = $2;
+ }
+ ;
+
+tunnelproto : L2TP { $$ = NPPPD_TUNNEL_L2TP; }
+ | PPTP { $$ = NPPPD_TUNNEL_PPTP; }
+ | PPPOE { $$ = NPPPD_TUNNEL_PPPOE; }
+ ;
+
+mppeyesno : YES { $$ = NPPPD_MPPE_ENABLED; }
+ | NO { $$ = NPPPD_MPPE_DISABLED; }
+ | REQUIRED { $$ = NPPPD_MPPE_REQUIRED; }
+ ;
+
+address : STRING {
+ int retval;
+ struct addrinfo hint, *res;
+
+ memset(&hint, 0, sizeof(hint));
+ hint.ai_family = PF_UNSPEC;
+ hint.ai_socktype = SOCK_DGRAM; /* dummy */
+ hint.ai_flags = AI_NUMERICHOST;
+
+ if ((retval = getaddrinfo($1, NULL, &hint, &res))
+ != 0) {
+ yyerror("could not parse the address %s: %s",
+ $1, gai_strerror(retval));
+ free($1);
+ YYERROR;
+ }
+ free($1);
+
+ if (res->ai_family != AF_INET &&
+ res->ai_family != AF_INET6) {
+ yyerror("address family(%d) is not supported",
+ res->ai_family);
+ freeaddrinfo(res);
+ YYERROR;
+ }
+ memcpy(&($$), res->ai_addr, res->ai_addrlen);
+
+ freeaddrinfo(res);
+ }
+ ;
+
+addressport : address optport {
+ $$ = $1;
+ ((struct sockaddr_in *)&($$))->sin_port = htons($2);
+ }
+ ;
+
+in4_addr : STRING {
+ if (inet_aton($1, &($$)) != 1) {
+ yyerror("could not parse the address %s");
+ free($1);
+ YYERROR;
+ }
+ }
+ ;
+
+authmethod_l : authmethod { $$ = $1; }
+ | authmethod_l authmethod { $$ |= $2; }
+ ;
+
+authmethod : PAP { $$ = NPPPD_AUTH_METHODS_PAP; }
+ | CHAP { $$ = NPPPD_AUTH_METHODS_CHAP; }
+ | MSCHAPV2 {
+ $$ = NPPPD_AUTH_METHODS_MSCHAPV2;
+ }
+ ;
+
+mppekeylen_l : mppekeylen { $$ = $1; }
+ | mppekeylen_l mppekeylen { $$ |= $2; }
+ ;
+
+mppekeylen : NUMBER {
+ if ($1 == 40) $$ = NPPPD_MPPE_40BIT;
+ else if ($1 == 56) $$ = NPPPD_MPPE_56BIT;
+ else if ($1 == 128) $$ = NPPPD_MPPE_128BIT;
+ else {
+ yyerror("%d: unknown mppe key length", $$);
+ YYERROR;
+ }
+ }
+ ;
+
+mppekeystate_l : mppekeystate { $$ = $1; }
+ | mppekeystate_l mppekeystate { $$ |= $2; }
+ ;
+
+mppekeystate : STATEFUL { $$ = NPPPD_MPPE_STATEFUL; }
+ | STATELESS { $$ = NPPPD_MPPE_STATELESS; }
+ ;
+
+protobit_l : protobit { $$ = $1; }
+ | protobit_l protobit { $$ |= $2; }
+ ;
+
+protobit : IP { $$ = NPPPD_PROTO_BIT_IP; }
+ | LCP { $$ = NPPPD_PROTO_BIT_LCP; }
+ | PAP { $$ = NPPPD_PROTO_BIT_PAP; }
+ | CHAP { $$ = NPPPD_PROTO_BIT_CHAP; }
+ | EAP { $$ = NPPPD_PROTO_BIT_EAP; }
+ | MPPE { $$ = NPPPD_PROTO_BIT_MPPE; }
+ | CCP { $$ = NPPPD_PROTO_BIT_CCP; }
+ | IPCP { $$ = NPPPD_PROTO_BIT_IPCP; }
+ ;
+
+/*
+ * authentication { }
+ */
+authentication : AUTHENTICATION STRING TYPE authtype {
+ struct authconf *n;
+
+ if (authconf_find($2) != NULL) {
+ yyerror("authentication name %s is already in "
+ "use.", $2);
+ free($2);
+ YYERROR;
+ }
+ if ((n = malloc(sizeof(struct authconf))) == NULL) {
+ yyerror("out of memory");
+ free($2);
+ YYERROR;
+ }
+ authconf_init(n);
+ strlcpy(n->name, $2, sizeof(n->name));
+ free($2);
+ n->auth_type = $4;
+ if ($4 == NPPPD_AUTH_TYPE_RADIUS) {
+ TAILQ_INIT(&n->radius.auth.servers);
+ TAILQ_INIT(&n->radius.acct.servers);
+ }
+ curr_authconf = n;
+ } '{' optnl authopt_l '}' {
+ TAILQ_INSERT_TAIL(&conf->authconfs, curr_authconf,
+ entry);
+ curr_authconf = NULL;
+ }
+ ;
+
+authopt_l : /* empty */
+ | authopt_l authopt nl
+ | authopt optnl
+ ;
+
+authopt : USERNAME_SUFFIX STRING {
+ curr_authconf->username_suffix = $2;
+ }
+ | USERNAME_PREFIX STRING {
+ curr_authconf->username_prefix = $2;
+ }
+ | EAP_CAPABLE yesno {
+ curr_authconf->eap_capable = $2;
+ }
+ | STRIP_NT_DOMAIN yesno {
+ curr_authconf->eap_capable = $2;
+ }
+ | STRIP_ATMARK_REALM yesno {
+ curr_authconf->eap_capable = $2;
+ }
+ | USERS_FILE STRING {
+ strlcpy(curr_authconf->users_file_path, $2,
+ sizeof(curr_authconf->users_file_path));
+ free($2);
+ }
+ | AUTHENTICATION_SERVER {
+ if (curr_authconf->auth_type != NPPPD_AUTH_TYPE_RADIUS){
+ yyerror("`authentication-server' can not be "
+ "used for this type.");
+ YYERROR;
+ }
+ curr_radconf = &curr_authconf->radius.auth;
+ } '{' optnl radopt_l '}' {
+ curr_radconf = NULL;
+ }
+ | ACCOUNTING_SERVER {
+ if (curr_authconf->auth_type != NPPPD_AUTH_TYPE_RADIUS){
+ yyerror("`accounting-server' can not be used "
+ "for this type.");
+ YYERROR;
+ }
+ curr_radconf = &curr_authconf->radius.acct;
+ TAILQ_INIT(&curr_radconf->servers);
+ } '{' optnl radopt_l '}' {
+ curr_radconf = NULL;
+ }
+ ;
+
+optport : /* empty */ { $$ = 0; }
+ | PORT NUMBER { $$ = $2; }
+ ;
+
+authtype : LOCAL { $$ = NPPPD_AUTH_TYPE_LOCAL; }
+ | RADIUS { $$ = NPPPD_AUTH_TYPE_RADIUS; }
+ ;
+
+radopt_l :
+ | radopt_l radopt nl
+ | radopt optnl
+ ;
+
+radopt : ADDRESS address optport SECRET STRING {
+ int cnt;
+ struct radserver *n;
+
+ if (strlen($5) > MAX_RADIUS_SECRET - 1) {
+ yyerror("`secret' is too long. "
+ "use less than %d chars.",
+ MAX_RADIUS_SECRET - 1);
+ YYERROR;
+ }
+ cnt = 0;
+ TAILQ_FOREACH(n, &curr_radconf->servers, entry) {
+ cnt++;
+ }
+ if (cnt >= MAX_RADIUS_SERVERS) {
+ yyerror("too many radius servers. use less "
+ "than or equal to %d servers.",
+ MAX_RADIUS_SERVERS);
+ YYERROR;
+ }
+ if ((n = malloc(sizeof(struct radserver))) == NULL) {
+ yyerror("out of memory");
+ YYERROR;
+ }
+ n->address = $2;
+ ((struct sockaddr_in *)&n->address)->sin_port = $3;
+ n->secret = $5;
+ TAILQ_INSERT_TAIL(&curr_radconf->servers, n, entry);
+ }
+ | X_TIMEOUT NUMBER {
+ curr_radconf->timeout = $2;
+ }
+ | MAX_TRIES NUMBER {
+ curr_radconf->max_tries = $2;
+ }
+ | MAX_FAILOVERS NUMBER {
+ curr_radconf->max_failovers = $2;
+ }
+ ;
+/*
+ * ipcp { }
+ */
+ipcp : IPCP STRING {
+ int cnt;
+ struct ipcpconf *n;
+
+ cnt = 0;
+ /*
+ TAILQ_FOREACH(n, &conf->ipcpconfs, entry) {
+ cnt++;
+ }
+ if (cnt >= NPPPD_MAX_POOL) {
+ yyerror("too many `ipcp' settings. it must be "
+ "less than or euals to %d.",
+ NPPPD_MAX_POOL);
+ YYERROR;
+ }
+ */
+
+ if (ipcpconf_find($2) != NULL) {
+ yyerror("ipcp name %s is already in use.", $2);
+ free($2);
+ YYERROR;
+ }
+ if ((n = malloc(sizeof(struct ipcpconf))) == NULL) {
+ yyerror("out of memory");
+ free($2);
+ YYERROR;
+ }
+ ipcpconf_init(n);
+ strlcpy(n->name, $2, sizeof(n->name));
+ free($2);
+ curr_ipcpconf = n;
+ } '{' optnl ipcpopt_l '}' {
+ TAILQ_INSERT_TAIL(&conf->ipcpconfs, curr_ipcpconf,
+ entry);
+ curr_ipcpconf = NULL;
+ }
+ ;
+
+ipcpopt_l : /* empty */
+ | ipcpopt_l ipcpopt nl
+ | ipcpopt optnl
+ ;
+
+ipcpopt : POOL_ADDRESS STRING ipcppooltype {
+ if ($3 != 1) {
+ if (in_addr_range_list_add(
+ &curr_ipcpconf->dynamic_pool, $2) != 0) {
+ yyerror("out of memory");
+ free($2);
+ YYERROR;
+ }
+ }
+ if (in_addr_range_list_add(
+ &curr_ipcpconf->static_pool, $2) != 0) {
+ yyerror("out of memory");
+ free($2);
+ YYERROR;
+ }
+ free($2);
+ }
+ | DNS_SERVERS RESOLVER {
+ curr_ipcpconf->dns_use_resolver = true;
+ curr_ipcpconf->dns_servers[0].s_addr = 0;
+ curr_ipcpconf->dns_servers[1].s_addr = 0;
+ }
+ | DNS_SERVERS in4_addr in4_addr {
+ curr_ipcpconf->dns_use_resolver = false;
+ curr_ipcpconf->dns_servers[0] = $2;
+ curr_ipcpconf->dns_servers[1] = $3;
+ }
+ | DNS_SERVERS in4_addr {
+ curr_ipcpconf->dns_use_resolver = false;
+ curr_ipcpconf->dns_servers[0] = $2;
+ curr_ipcpconf->dns_servers[1].s_addr = 0;
+ }
+ | NBNS_SERVERS in4_addr in4_addr {
+ curr_ipcpconf->nbns_servers[0] = $2;
+ curr_ipcpconf->nbns_servers[1] = $3;
+ }
+ | NBNS_SERVERS in4_addr {
+ curr_ipcpconf->nbns_servers[0] = $2;
+ curr_ipcpconf->nbns_servers[1].s_addr = 0;
+ }
+ | ALLOW_USER_SELECTED_ADDRESS yesno {
+ curr_ipcpconf->allow_user_select = $2;
+ }
+ ;
+
+ipcppooltype : /* empty */ { $$ = 0; }
+ | FOR DYNAMIC { $$ = 0; }
+ | FOR STATIC { $$ = 1; }
+ ;
+
+
+/*
+ * interface
+ */
+interface : INTERFACE STRING ADDRESS in4_addr IPCP STRING {
+ int cnt;
+ struct iface *n;
+ struct ipcpconf *ipcp;
+
+ cnt = 0;
+ TAILQ_FOREACH(n, &conf->ifaces, entry) {
+ cnt++;
+ }
+ if (cnt >= NPPPD_MAX_IFACE) {
+ yyerror("too many interfaces. use less than "
+ "or equal to %d", NPPPD_MAX_IFACE);
+ YYERROR;
+ }
+
+ if ((ipcp = ipcpconf_find($6)) == NULL) {
+ yyerror("ipcp %s is not found", $6);
+ free($2);
+ YYERROR;
+ }
+ if (iface_find($2) != NULL) {
+ yyerror("interface %s is already in used.", $2);
+ free($2);
+ YYERROR;
+ }
+
+ if ((n = malloc(sizeof(struct iface))) == NULL) {
+ yyerror("out of memory");
+ free($2);
+ YYERROR;
+ }
+ strlcpy(n->name, $2, sizeof(n->name));
+ free($2);
+ n->ip4addr = $4;
+ if (strncmp(n->name, "pppx", 4) == 0)
+ n->is_pppx = true;
+
+ n->ipcpconf = ipcp;
+ TAILQ_INSERT_TAIL(&conf->ifaces, n, entry);
+ }
+ ;
+
+/*
+ * bind
+ */
+bind : BIND TUNNEL FROM STRING AUTHENTICATED BY STRING TO STRING {
+ struct authconf *auth;
+ struct tunnconf *tunn;
+ struct iface *iface;
+ struct confbind *n;
+
+ if ((tunn = tunnconf_find($4)) == NULL) {
+ yyerror("tunnel %s is not found", $4);
+ free($4);
+ free($7);
+ free($9);
+ YYERROR;
+ }
+ if ((auth = authconf_find($7)) == NULL) {
+ yyerror("authentication %s is not found", $7);
+ free($4);
+ free($7);
+ free($9);
+ YYERROR;
+ }
+ if ((iface = iface_find($9)) == NULL) {
+ yyerror("interface %s is not found", $9);
+ free($4);
+ free($7);
+ free($9);
+ YYERROR;
+ }
+ if ((n = malloc(sizeof(struct confbind))) == NULL) {
+ yyerror("out of memory");
+ free($4);
+ free($7);
+ free($9);
+ YYERROR;
+ }
+ n->tunnconf = tunn;
+ n->authconf = auth;
+ n->iface = iface;
+ TAILQ_INSERT_TAIL(&conf->confbinds, n, entry);
+ }
+ ;
+
+yesno : YES { $$ = true; }
+ | NO { $$ = false; }
+ ;
+
+optnl : '\n' optnl
+ |
+ ;
+
+nl : '\n' optnl
+ ;
+
+%%
+
+struct keywords {
+ const char *k_name;
+ int k_val;
+};
+
+int
+yyerror(const char *fmt, ...)
+{
+ va_list ap;
+ char *nfmt;
+
+ file->errors++;
+ va_start(ap, fmt);
+ if (asprintf(&nfmt, "%s:%d: %s", file->name, yylval.lineno, fmt) == -1)
+ fatalx("yyerror asprintf");
+ vlog(LOG_CRIT, nfmt, ap);
+ va_end(ap);
+ free(nfmt);
+ return (0);
+}
+
+int
+kw_cmp(const void *k, const void *e)
+{
+ return (strcmp(k, ((const struct keywords *)e)->k_name));
+}
+
+int
+lookup(char *s)
+{
+ /* this has to be sorted always */
+ static const struct keywords keywords[] = {
+ { "accounting-server", ACCOUNTING_SERVER},
+ { "address", ADDRESS},
+ { "allow-user-selected-address", ALLOW_USER_SELECTED_ADDRESS},
+ { "authenticated", AUTHENTICATED},
+ { "authentication", AUTHENTICATION},
+ { "authentication-method", AUTHENTICATION_METHOD},
+ { "authentication-server", AUTHENTICATION_SERVER},
+ { "bind", BIND},
+ { "by", BY},
+ { "callnum-check", CALLNUM_CHECK},
+ { "ccp", CCP},
+ { "ccp-max-configure", CCP_MAX_CONFIGURE},
+ { "ccp-max-nak-loop", CCP_MAX_NAK_LOOP},
+ { "ccp-max-terminate", CCP_MAX_TERMINATE},
+ { "ccp-timeout", CCP_TIMEOUT},
+ { "chap", CHAP},
+ { "chap-name", CHAP_NAME},
+ { "debug-dump-pktin", DEBUG_DUMP_PKTIN},
+ { "debug-dump-pktout", DEBUG_DUMP_PKTOUT},
+ { "dns-servers", DNS_SERVERS},
+ { "dynamic", DYNAMIC},
+ { "eap", EAP},
+ { "eap-capable", EAP_CAPABLE},
+ { "for", FOR},
+ { "from", FROM},
+ { "idle-timeout", IDLE_TIMEOUT},
+ { "ingress-filter", INGRESS_FILTER},
+ { "interface", INTERFACE},
+ { "ip", IP},
+ { "ipcp", IPCP},
+ { "ipcp-max-configure", IPCP_MAX_CONFIGURE},
+ { "ipcp-max-nak-loop", IPCP_MAX_NAK_LOOP},
+ { "ipcp-max-terminate", IPCP_MAX_TERMINATE},
+ { "ipcp-timeout", IPCP_TIMEOUT},
+ { "l2tp", L2TP},
+ { "l2tp-accept-dialin", L2TP_ACCEPT_DIALIN},
+ { "l2tp-ctrl-in-pktdump", L2TP_CTRL_IN_PKTDUMP},
+ { "l2tp-ctrl-out-pktdump", L2TP_CTRL_OUT_PKTDUMP},
+ { "l2tp-data-in-pktdump", L2TP_DATA_IN_PKTDUMP},
+ { "l2tp-data-out-pktdump", L2TP_DATA_OUT_PKTDUMP},
+ { "l2tp-data-use-seq", L2TP_DATA_USE_SEQ},
+ { "l2tp-force-lcp-renegotiation", L2TP_FORCE_LCP_RENEGOTIATION},
+ { "l2tp-hello-interval", L2TP_HELLO_INTERVAL},
+ { "l2tp-hello-timeout", L2TP_HELLO_TIMEOUT},
+ { "l2tp-hostname", L2TP_HOSTNAME},
+ { "l2tp-lcp-renegotiation", L2TP_LCP_RENEGOTIATION},
+ { "l2tp-require-ipsec", L2TP_REQUIRE_IPSEC},
+ { "l2tp-vendor-name", L2TP_VENDOR_NAME},
+ { "lcp", LCP},
+ { "lcp-keepalive", LCP_KEEPALIVE},
+ { "lcp-keepalive-interval", LCP_KEEPALIVE_INTERVAL},
+ { "lcp-keepalive-max-retries", LCP_KEEPALIVE_MAX_RETRIES },
+ { "lcp-keepalive-retry-interval", LCP_KEEPALIVE_RETRY_INTERVAL},
+ { "lcp-max-configure", LCP_MAX_CONFIGURE},
+ { "lcp-max-nak-loop", LCP_MAX_NAK_LOOP},
+ { "lcp-max-terminate", LCP_MAX_TERMINATE},
+ { "lcp-timeout", LCP_TIMEOUT},
+ { "listen", LISTEN},
+ { "local", LOCAL},
+ { "max-failovers", MAX_FAILOVERS},
+ { "max-session", MAX_SESSION},
+ { "max-tries", MAX_TRIES},
+ { "mppe", MPPE},
+ { "mppe", MPPE},
+ { "mppe-key-length", MPPE_KEY_LENGTH},
+ { "mppe-key-state", MPPE_KEY_STATE},
+ { "mru", MRU},
+ { "mschapv2", MSCHAPV2},
+ { "nbns-servers", NBNS_SERVERS},
+ { "no", NO},
+ { "on", ON},
+ { "pap", PAP},
+ { "pipex", PIPEX},
+ { "pool-address", POOL_ADDRESS},
+ { "port", PORT},
+ { "pppoe", PPPOE},
+ { "pppoe-ac-name", PPPOE_AC_NAME},
+ { "pppoe-accept-any-service", PPPOE_ACCEPT_ANY_SERVICE},
+ { "pppoe-desc-in-pktdump", PPPOE_DESC_IN_PKTDUMP},
+ { "pppoe-desc-out-pktdump", PPPOE_DESC_OUT_PKTDUMP},
+ { "pppoe-service-name", PPPOE_SERVICE_NAME},
+ { "pppoe-session-in-pktdump", PPPOE_SESSION_IN_PKTDUMP},
+ { "pppoe-session-out-pktdump", PPPOE_SESSION_OUT_PKTDUMP},
+ { "pptp", PPTP},
+ { "pptp-ctrl-in-pktdump", PPTP_CTRL_IN_PKTDUMP},
+ { "pptp-ctrl-out-pktdump", PPTP_CTRL_OUT_PKTDUMP},
+ { "pptp-data-in-pktdump", PPTP_DATA_IN_PKTDUMP},
+ { "pptp-data-out-pktdump", PPTP_DATA_OUT_PKTDUMP},
+ { "pptp-echo-interval", PPTP_ECHO_INTERVAL},
+ { "pptp-echo-timeout", PPTP_ECHO_TIMEOUT},
+ { "pptp-hostname", PPTP_HOSTNAME},
+ { "pptp-vendor-name", PPTP_VENDOR_NAME},
+ { "protocol", PROTOCOL},
+ { "radius", RADIUS},
+ { "required", REQUIRED},
+ { "resolver", RESOLVER},
+ { "secret", SECRET},
+ { "set", SET},
+ { "stateful", STATEFUL},
+ { "stateless", STATELESS},
+ { "static", STATIC},
+ { "strip-atmark-realm", STRIP_ATMARK_REALM},
+ { "strip-nt-domain", STRIP_NT_DOMAIN},
+ { "tcp-mss-adjust", TCP_MSS_ADJUST},
+ { "timeout", X_TIMEOUT},
+ { "to", TO},
+ { "tunnel", TUNNEL},
+ { "type", TYPE},
+ { "user-max-session", USER_MAX_SESSION},
+ { "username-prefix", USERNAME_PREFIX},
+ { "username-suffix", USERNAME_SUFFIX},
+ { "users-file", USERS_FILE},
+ { "yes", YES}
+ };
+ const struct keywords *p;
+
+ p = bsearch(s, keywords, sizeof(keywords)/sizeof(keywords[0]),
+ sizeof(keywords[0]), kw_cmp);
+
+ if (p)
+ return (p->k_val);
+ else
+ return (STRING);
+}
+
+#define MAXPUSHBACK 128
+
+char *parsebuf;
+int parseindex;
+char pushback_buffer[MAXPUSHBACK];
+int pushback_index = 0;
+
+int
+lgetc(int quotec)
+{
+ int c, next;
+
+ if (parsebuf) {
+ /* Read character from the parsebuffer instead of input. */
+ if (parseindex >= 0) {
+ c = parsebuf[parseindex++];
+ if (c != '\0')
+ return (c);
+ parsebuf = NULL;
+ } else
+ parseindex++;
+ }
+
+ if (pushback_index)
+ return (pushback_buffer[--pushback_index]);
+
+ if (quotec) {
+ if ((c = getc(file->stream)) == EOF) {
+ yyerror("reached end of file while parsing "
+ "quoted string");
+ if (file == topfile || popfile() == EOF)
+ return (EOF);
+ return (quotec);
+ }
+ return (c);
+ }
+
+ while ((c = getc(file->stream)) == '\\') {
+ next = getc(file->stream);
+ if (next != '\n') {
+ c = next;
+ break;
+ }
+ yylval.lineno = file->lineno;
+ file->lineno++;
+ }
+
+ while (c == EOF) {
+ if (file == topfile || popfile() == EOF)
+ return (EOF);
+ c = getc(file->stream);
+ }
+ return (c);
+}
+
+int
+lungetc(int c)
+{
+ if (c == EOF)
+ return (EOF);
+ if (parsebuf) {
+ parseindex--;
+ if (parseindex >= 0)
+ return (c);
+ }
+ if (pushback_index < MAXPUSHBACK-1)
+ return (pushback_buffer[pushback_index++] = c);
+ else
+ return (EOF);
+}
+
+int
+findeol(void)
+{
+ int c;
+
+ parsebuf = NULL;
+
+ /* skip to either EOF or the first real EOL */
+ while (1) {
+ if (pushback_index)
+ c = pushback_buffer[--pushback_index];
+ else
+ c = lgetc(0);
+ if (c == '\n') {
+ file->lineno++;
+ break;
+ }
+ if (c == EOF)
+ break;
+ }
+ return (ERROR);
+}
+
+int
+yylex(void)
+{
+ char buf[8096];
+ char *p;
+ int quotec, next, c;
+ int token;
+
+ p = buf;
+ while ((c = lgetc(0)) == ' ' || c == '\t')
+ ; /* nothing */
+
+ yylval.lineno = file->lineno;
+ if (c == '#')
+ while ((c = lgetc(0)) != '\n' && c != EOF)
+ ; /* nothing */
+
+ switch (c) {
+ case '\'':
+ case '"':
+ quotec = c;
+ while (1) {
+ if ((c = lgetc(quotec)) == EOF)
+ return (0);
+ if (c == '\n') {
+ file->lineno++;
+ continue;
+ } else if (c == '\\') {
+ if ((next = lgetc(quotec)) == EOF)
+ return (0);
+ if (next == quotec || c == ' ' || c == '\t')
+ c = next;
+ else if (next == '\n') {
+ file->lineno++;
+ continue;
+ } else
+ lungetc(next);
+ } else if (c == quotec) {
+ *p = '\0';
+ break;
+ }
+ if (p + 1 >= buf + sizeof(buf) - 1) {
+ yyerror("string too long");
+ return (findeol());
+ }
+ *p++ = (char)c;
+ }
+ yylval.v.string = strdup(buf);
+ if (yylval.v.string == NULL)
+ fatal("yylex: strdup");
+ return (STRING);
+ }
+
+#define allowed_to_end_number(x) \
+ (isspace(x) || x == ')' || x ==',' || x == '/' || x == '}' || x == '=')
+
+ if (c == '-' || isdigit(c)) {
+ do {
+ *p++ = c;
+ if ((unsigned)(p-buf) >= sizeof(buf)) {
+ yyerror("string too long");
+ return (findeol());
+ }
+ } while ((c = lgetc(0)) != EOF && isdigit(c));
+ lungetc(c);
+ if (p == buf + 1 && buf[0] == '-')
+ goto nodigits;
+ if (c == EOF || allowed_to_end_number(c)) {
+ const char *errstr = NULL;
+
+ *p = '\0';
+ yylval.v.number = strtonum(buf, LLONG_MIN,
+ LLONG_MAX, &errstr);
+ if (errstr) {
+ yyerror("\"%s\" invalid number: %s",
+ buf, errstr);
+ return (findeol());
+ }
+ return (NUMBER);
+ } else {
+nodigits:
+ while (p > buf + 1)
+ lungetc(*--p);
+ c = *--p;
+ if (c == '-')
+ return (c);
+ }
+ }
+
+#define allowed_in_string(x) \
+ (isalnum(x) || (ispunct(x) && x != '(' && x != ')' && \
+ x != '{' && x != '}' && x != '<' && x != '>' && \
+ x != '!' && x != '=' && x != '/' && x != '#' && \
+ x != ','))
+
+ if (isalnum(c) || c == ':' || c == '_' || c == '*') {
+ do {
+ *p++ = c;
+ if ((unsigned)(p-buf) >= sizeof(buf)) {
+ yyerror("string too long");
+ return (findeol());
+ }
+ } while ((c = lgetc(0)) != EOF && (allowed_in_string(c)));
+ lungetc(c);
+ *p = '\0';
+ if ((token = lookup(buf)) == STRING)
+ if ((yylval.v.string = strdup(buf)) == NULL)
+ fatal("yylex: strdup");
+ return (token);
+ }
+ if (c == '\n') {
+ yylval.lineno = file->lineno;
+ file->lineno++;
+ }
+ if (c == EOF)
+ return (0);
+ return (c);
+}
+
+struct file *
+pushfile(const char *name)
+{
+ struct file *nfile;
+
+ if ((nfile = calloc(1, sizeof(struct file))) == NULL) {
+ log_warn("malloc");
+ return (NULL);
+ }
+ if ((nfile->name = strdup(name)) == NULL) {
+ log_warn("malloc");
+ free(nfile);
+ return (NULL);
+ }
+#ifdef NO_PRIVSEP
+ if ((nfile->stream = fopen(nfile->name, "r")) == NULL) {
+#else
+ if ((nfile->stream = priv_fopen(nfile->name)) == NULL) {
+#endif
+ log_warn("%s", nfile->name);
+ free(nfile->name);
+ free(nfile);
+ return (NULL);
+ }
+ nfile->lineno = 1;
+ TAILQ_INSERT_TAIL(&files, nfile, entry);
+ return (nfile);
+}
+
+int
+popfile(void)
+{
+ struct file *prev;
+
+ if ((prev = TAILQ_PREV(file, files, entry)) != NULL)
+ prev->errors += file->errors;
+
+ TAILQ_REMOVE(&files, file, entry);
+ fclose(file->stream);
+ free(file->name);
+ free(file);
+ file = prev;
+ return (file ? 0 : EOF);
+}
+
+int
+npppd_conf_parse(struct npppd_conf *xconf, const char *filename)
+{
+ int errors = 0;
+
+ conf = xconf;
+
+ if ((file = pushfile(filename)) == NULL) {
+ return (-1);
+ }
+ topfile = file;
+
+ yyparse();
+ errors = file->errors;
+ popfile();
+
+ if (curr_tunnconf != NULL) {
+ tunnconf_fini(curr_tunnconf);
+ free(curr_tunnconf);
+ }
+ curr_tunnconf = NULL;
+ if (curr_authconf != NULL) {
+ authconf_fini(curr_authconf);
+ free(curr_authconf);
+ }
+ curr_authconf = NULL;
+ if (curr_ipcpconf != NULL) {
+ ipcpconf_fini(curr_ipcpconf);
+ free(curr_ipcpconf);
+ }
+ curr_ipcpconf = NULL;
+
+ if (errors)
+ npppd_conf_fini(xconf);
+
+ return (errors ? -1 : 0);
+}
+
+void
+npppd_conf_init(struct npppd_conf *xconf)
+{
+ memset(xconf, 0, sizeof(struct npppd_conf));
+ TAILQ_INIT(&xconf->tunnconfs);
+ TAILQ_INIT(&xconf->authconfs);
+ TAILQ_INIT(&xconf->ipcpconfs);
+ TAILQ_INIT(&xconf->ifaces);
+ TAILQ_INIT(&xconf->confbinds);
+ TAILQ_INIT(&xconf->l2tp_confs);
+ TAILQ_INIT(&xconf->pptp_confs);
+ TAILQ_INIT(&xconf->pppoe_confs);
+}
+
+void
+npppd_conf_fini(struct npppd_conf *xconf)
+{
+ struct tunnconf *tunn, *tunn0;
+ struct authconf *auth, *auth0;
+ struct ipcpconf *ipcp, *ipcp0;
+ struct iface *iface, *iface0;
+ struct confbind *confbind, *confbind0;
+
+ TAILQ_FOREACH_SAFE(tunn, &xconf->tunnconfs, entry, tunn0) {
+ tunnconf_fini(tunn);
+ }
+ if (curr_radconf != NULL) {
+ radconf_fini(curr_radconf);
+ curr_radconf = NULL;
+ }
+ TAILQ_FOREACH_SAFE(auth, &xconf->authconfs, entry, auth0) {
+ authconf_fini(auth);
+ }
+ TAILQ_FOREACH_SAFE(ipcp, &xconf->ipcpconfs, entry, ipcp0) {
+ ipcpconf_fini(ipcp);
+ }
+ TAILQ_FOREACH_SAFE(iface, &xconf->ifaces, entry, iface0) {
+ free(iface);
+ }
+ TAILQ_FOREACH_SAFE(confbind, &xconf->confbinds, entry, confbind0) {
+ free(confbind);
+ }
+ TAILQ_INIT(&xconf->l2tp_confs);
+ TAILQ_INIT(&xconf->pptp_confs);
+ TAILQ_INIT(&xconf->pppoe_confs);
+}
+
+void
+tunnconf_fini(struct tunnconf *tun)
+{
+ if (tun->chap_name != NULL)
+ free(tun->chap_name);
+ tun->chap_name = NULL;
+
+ switch (tun->protocol) {
+ case NPPPD_TUNNEL_L2TP:
+ if (tun->proto.l2tp.hostname != NULL)
+ free(tun->proto.l2tp.hostname);
+ tun->proto.l2tp.hostname = NULL;
+ if (tun->proto.l2tp.vendor_name != NULL)
+ free(tun->proto.l2tp.vendor_name);
+ tun->proto.l2tp.vendor_name = NULL;
+ break;
+ case NPPPD_TUNNEL_PPTP:
+ if (tun->proto.pptp.hostname != NULL)
+ free(tun->proto.pptp.hostname);
+ tun->proto.pptp.hostname = NULL;
+ if (tun->proto.pptp.vendor_name != NULL)
+ free(tun->proto.pptp.vendor_name);
+ tun->proto.pptp.vendor_name = NULL;
+ break;
+ case NPPPD_TUNNEL_PPPOE:
+ if (tun->proto.pppoe.service_name != NULL)
+ free(tun->proto.pppoe.service_name);
+ tun->proto.pppoe.service_name = NULL;
+ if (tun->proto.pppoe.ac_name != NULL)
+ free(tun->proto.pppoe.ac_name);
+ tun->proto.pppoe.ac_name = NULL;
+ break;
+ }
+}
+
+void
+tunnconf_init(struct tunnconf *tun, int protocol)
+{
+ extern struct tunnconf tunnconf_default_l2tp, tunnconf_default_pptp;
+ extern struct tunnconf tunnconf_default_pppoe;
+
+ switch (protocol) {
+ case NPPPD_TUNNEL_L2TP:
+ memcpy(tun, &tunnconf_default_l2tp, sizeof(struct tunnconf));
+ break;
+ case NPPPD_TUNNEL_PPTP:
+ memcpy(tun, &tunnconf_default_pptp, sizeof(struct tunnconf));
+ break;
+ case NPPPD_TUNNEL_PPPOE:
+ memcpy(tun, &tunnconf_default_pppoe, sizeof(struct tunnconf));
+ break;
+ }
+}
+
+struct tunnconf *
+tunnconf_find(const char *name)
+{
+ struct tunnconf *tunn;
+
+ TAILQ_FOREACH(tunn, &conf->tunnconfs, entry) {
+ if (strcmp(tunn->name, name) == 0)
+ return tunn;
+ }
+
+ return NULL;
+}
+
+void
+authconf_init(struct authconf *auth)
+{
+ memset(auth, 0, sizeof(struct authconf));
+ auth->eap_capable = true;
+ auth->strip_nt_domain = true;
+ auth->strip_atmark_realm = false;
+}
+
+void
+authconf_fini(struct authconf *auth)
+{
+ if (auth->username_suffix != NULL)
+ free(auth->username_suffix);
+ auth->username_suffix = NULL;
+
+ if (auth->username_prefix != NULL)
+ free(auth->username_prefix);
+ auth->username_prefix = NULL;
+
+ switch (auth->auth_type) {
+ case NPPPD_AUTH_TYPE_RADIUS:
+ radconf_fini(&auth->radius.auth);
+ radconf_fini(&auth->radius.acct);
+ break;
+ }
+}
+
+void
+radconf_fini(struct radconf *radconf)
+{
+ struct radserver *server, *server0;
+
+ TAILQ_FOREACH_SAFE(server, &radconf->servers, entry, server0) {
+ if (server->secret != NULL)
+ free(server->secret);
+ server->secret = NULL;
+ }
+}
+
+struct authconf *
+authconf_find(const char *name)
+{
+ struct authconf *auth;
+
+ TAILQ_FOREACH(auth, &conf->authconfs, entry) {
+ if (strcmp(auth->name, name) == 0)
+ return auth;
+ }
+
+ return NULL;
+}
+
+void
+ipcpconf_init(struct ipcpconf *ipcp)
+{
+ memset(ipcp, 0, sizeof(struct ipcpconf));
+}
+
+void
+ipcpconf_fini(struct ipcpconf *ipcp)
+{
+ if (ipcp->dynamic_pool != NULL)
+ in_addr_range_list_remove_all(&ipcp->dynamic_pool);
+ if (ipcp->static_pool != NULL)
+ in_addr_range_list_remove_all(&ipcp->static_pool);
+}
+
+struct ipcpconf *
+ipcpconf_find(const char *name)
+{
+ struct ipcpconf *ipcp;
+
+ TAILQ_FOREACH(ipcp, &conf->ipcpconfs, entry) {
+ if (strcmp(ipcp->name, name) == 0)
+ return ipcp;
+ }
+
+ return NULL;
+}
+
+struct iface *
+iface_find(const char *name)
+{
+ struct iface *iface;
+
+ TAILQ_FOREACH(iface, &conf->ifaces, entry) {
+ if (strcmp(iface->name, name) == 0)
+ return iface;
+ }
+
+ return NULL;
+}
diff --git a/usr.sbin/npppd/npppd/ppp.c b/usr.sbin/npppd/npppd/ppp.c
index 5ce30531174..4ffe1cb8c0e 100644
--- a/usr.sbin/npppd/npppd/ppp.c
+++ b/usr.sbin/npppd/npppd/ppp.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ppp.c,v 1.15 2012/09/07 10:47:42 yasuoka Exp $ */
+/* $OpenBSD: ppp.c,v 1.16 2012/09/18 13:14:08 yasuoka Exp $ */
/*-
* Copyright (c) 2009 Internet Initiative Japan Inc.
@@ -25,7 +25,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
-/* $Id: ppp.c,v 1.15 2012/09/07 10:47:42 yasuoka Exp $ */
+/* $Id: ppp.c,v 1.16 2012/09/18 13:14:08 yasuoka Exp $ */
/**@file
* This file provides PPP(Point-to-Point Protocol, RFC 1661) and
* {@link :: _npppd_ppp PPP instance} related functions.
@@ -79,13 +79,14 @@
static u_int ppp_seq = 0;
-static void ppp_stop0 __P((npppd_ppp *));
-static int ppp_recv_packet (npppd_ppp *, unsigned char *, int, int);
-static const char * ppp_peer_auth_string(npppd_ppp *);
-static void ppp_idle_timeout(int, short, void *);
+static void ppp_stop0 (npppd_ppp *);
+static int ppp_recv_packet (npppd_ppp *, unsigned char *, int, int);
+static const char *ppp_peer_auth_string (npppd_ppp *);
+static void ppp_idle_timeout (int, short, void *);
#ifdef USE_NPPPD_PIPEX
-static void ppp_on_network_pipex(npppd_ppp *);
+static void ppp_on_network_pipex(npppd_ppp *);
#endif
+static uint32_t ppp_proto_bit(int);
#define AUTH_IS_PAP(ppp) ((ppp)->peer_auth == PPP_AUTH_PAP)
#define AUTH_IS_CHAP(ppp) ((ppp)->peer_auth == PPP_AUTH_CHAP_MD5 ||\
@@ -129,6 +130,7 @@ ppp_create()
int
ppp_init(npppd *pppd, npppd_ppp *_this)
{
+ struct tunnconf *conf;
PPP_ASSERT(_this != NULL);
PPP_ASSERT(strlen(_this->phy_label) > 0);
@@ -142,7 +144,9 @@ ppp_init(npppd *pppd, npppd_ppp *_this)
lcp_init(&_this->lcp, _this);
- _this->mru = ppp_config_int(_this, "lcp.mru", DEFAULT_MRU);
+ conf = ppp_get_tunnconf(_this);
+ _this->mru = conf->mru;
+
if (_this->outpacket_buf == NULL) {
_this->outpacket_buf = malloc(_this->mru + 64);
if (_this->outpacket_buf == NULL){
@@ -151,19 +155,13 @@ ppp_init(npppd *pppd, npppd_ppp *_this)
return -1;
}
}
- _this->adjust_mss = ppp_config_str_equal(_this, "ip.adjust_mss", "true",
- 0);
+ _this->adjust_mss = (conf->tcp_mss_adjust)? 1 : 0;
+
#ifdef USE_NPPPD_PIPEX
- _this->use_pipex = ppp_config_str_equal(_this, "pipex.enabled", "true",
- 1);
+ _this->use_pipex = (conf->pipex)? 1 : 0;
#endif
/* load the logging configuration */
- _this->log_dump_in =
- ppp_config_str_equal(_this, "log.in.pktdump", "true", 0);
- _this->log_dump_out =
- ppp_config_str_equal(_this, "log.out.pktdump", "true", 0);
- _this->ingress_filter = ppp_config_str_equal(_this, "ingress_filter",
- "true", 0);
+ _this->ingress_filter = (conf->ingress_filter)? 1 : 0;
#ifdef USE_NPPPD_MPPE
mppe_init(&_this->mppe, _this);
@@ -174,19 +172,23 @@ ppp_init(npppd *pppd, npppd_ppp *_this)
chap_init(&_this->chap, _this);
/* load the idle timer configuration */
- _this->timeout_sec = ppp_config_int(_this, "idle_timeout", 0);
+ _this->timeout_sec = conf->idle_timeout;
+
if (!evtimer_initialized(&_this->idle_event))
evtimer_set(&_this->idle_event, ppp_idle_timeout, _this);
- _this->auth_timeout = ppp_config_int(_this, "auth.timeout",
- DEFAULT_AUTH_TIMEOUT);
-
- _this->lcp.echo_interval = ppp_config_int(_this,
- "lcp.echo_interval", DEFAULT_LCP_ECHO_INTERVAL);
- _this->lcp.echo_max_retries = ppp_config_int(_this,
- "lcp.echo_max_retries", DEFAULT_LCP_ECHO_MAX_RETRIES);
- _this->lcp.echo_retry_interval = ppp_config_int(_this,
- "lcp.echo_retry_interval", DEFAULT_LCP_ECHO_RETRY_INTERVAL);
+ if (conf->lcp_keepalive) {
+ _this->lcp.echo_interval = conf->lcp_keepalive_interval;
+ _this->lcp.echo_retry_interval =
+ conf->lcp_keepalive_retry_interval;
+ _this->lcp.echo_max_retries = conf->lcp_keepalive_max_retries;
+ } else {
+ _this->lcp.echo_interval = 0;
+ _this->lcp.echo_retry_interval = 0;
+ _this->lcp.echo_max_retries = 0;
+ }
+ _this->log_dump_in = (conf->debug_dump_pktin == 0)? 0 : 1;
+ _this->log_dump_out = (conf->debug_dump_pktout == 0)? 0 : 1;
return 0;
}
@@ -251,11 +253,13 @@ int
ppp_dialin_proxy_prepare(npppd_ppp *_this, dialin_proxy_info *dpi)
{
int renego_force, renego;
+ struct tunnconf *conf;
+
+ conf = ppp_get_tunnconf(_this);
+
+ renego = conf->proto.l2tp.lcp_renegotiation;
+ renego_force = conf->proto.l2tp.force_lcp_renegotiation;
- renego = (ppp_config_str_equal(_this,
- "l2tp.dialin.lcp_renegotiation", "disable", 0))? 0 : 1;
- renego_force = ppp_config_str_equal(_this,
- "l2tp.dialin.lcp_renegotiation", "force", 0);
if (renego_force)
renego = 1;
@@ -463,7 +467,7 @@ void
ppp_lcp_up(npppd_ppp *_this)
{
#ifdef USE_NPPPD_MPPE
- if (MPPE_REQUIRED(_this) && !MPPE_MUST_NEGO(_this)) {
+ if (MPPE_IS_REQUIRED(_this) && !MPPE_MUST_NEGO(_this)) {
ppp_log(_this, LOG_ERR, "MPPE is required, auth protocol must "
"be MS-CHAP-V2 or EAP");
ppp_stop(_this, "Encryption required");
@@ -806,11 +810,8 @@ ppp_recv_packet(npppd_ppp *_this, unsigned char *pkt, int lpkt, int flags)
return 1;
if (_this->log_dump_in != 0 && debug_get_debugfp() != NULL) {
- char buf[256];
-
- snprintf(buf, sizeof(buf), "log.%s.in.pktdump",
- proto_name(proto));
- if (ppp_config_str_equal(_this, buf, "true", 0) != 0) {
+ struct tunnconf *conf = ppp_get_tunnconf(_this);
+ if ((ppp_proto_bit(proto) & conf->debug_dump_pktin) != 0) {
ppp_log(_this, LOG_DEBUG,
"PPP input dump proto=%s(%d/%04x)",
proto_name(proto), proto, proto);
@@ -819,7 +820,7 @@ ppp_recv_packet(npppd_ppp *_this, unsigned char *pkt, int lpkt, int flags)
}
#ifdef USE_NPPPD_PIPEX
if (_this->pipex_enabled != 0 &&
- _this->tunnel_type == PPP_TUNNEL_PPPOE) {
+ _this->tunnel_type == NPPPD_TUNNEL_PPPOE) {
switch (proto) {
case PPP_PROTO_IP:
return 2; /* handled by PIPEX */
@@ -842,7 +843,7 @@ ppp_recv_packet(npppd_ppp *_this, unsigned char *pkt, int lpkt, int flags)
case PPP_PROTO_IP:
/* Checks for MPPE */
if ((flags & PPP_IO_FLAGS_MPPE_ENCRYPTED) == 0) {
- if (MPPE_REQUIRED(_this)) {
+ if (MPPE_IS_REQUIRED(_this)) {
/* MPPE is required but naked ip */
if (_this->logged_naked_ip == 0) {
@@ -1020,11 +1021,8 @@ ppp_output(npppd_ppp *_this, uint16_t proto, u_char code, u_char id,
memmove(outp, datap, ldata);
if (_this->log_dump_out != 0 && debug_get_debugfp() != NULL) {
- char buf[256];
-
- snprintf(buf, sizeof(buf), "log.%s.out.pktdump",
- proto_name(proto));
- if (ppp_config_str_equal(_this, buf, "true", 0) != 0) {
+ struct tunnconf *conf = ppp_get_tunnconf(_this);
+ if ((ppp_proto_bit(proto) & conf->debug_dump_pktout) != 0) {
ppp_log(_this, LOG_DEBUG,
"PPP output dump proto=%s(%d/%04x)",
proto_name(proto), proto, proto);
@@ -1135,9 +1133,9 @@ ppp_on_network_pipex(npppd_ppp *_this)
{
if (_this->use_pipex == 0)
return;
- if (_this->tunnel_type != PPP_TUNNEL_PPTP &&
- _this->tunnel_type != PPP_TUNNEL_PPPOE &&
- _this->tunnel_type != PPP_TUNNEL_L2TP)
+ if (_this->tunnel_type != NPPPD_TUNNEL_PPTP &&
+ _this->tunnel_type != NPPPD_TUNNEL_PPPOE &&
+ _this->tunnel_type != NPPPD_TUNNEL_L2TP)
return;
if (_this->pipex_started != 0)
@@ -1156,3 +1154,136 @@ ppp_on_network_pipex(npppd_ppp *_this)
/* else wait CCP or IPCP */
}
#endif
+
+static uint32_t
+ppp_proto_bit(int proto)
+{
+ switch (proto) {
+ case PPP_PROTO_IP: return NPPPD_PROTO_BIT_IP;
+ case PPP_PROTO_LCP: return NPPPD_PROTO_BIT_LCP;
+ case PPP_PROTO_PAP: return NPPPD_PROTO_BIT_PAP;
+ case PPP_PROTO_CHAP: return NPPPD_PROTO_BIT_CHAP;
+ case PPP_PROTO_EAP: return NPPPD_PROTO_BIT_EAP;
+ case PPP_PROTO_MPPE: return NPPPD_PROTO_BIT_MPPE;
+ case PPP_PROTO_NCP | NCP_CCP: return NPPPD_PROTO_BIT_CCP;
+ case PPP_PROTO_NCP | NCP_IPCP: return NPPPD_PROTO_BIT_IPCP;
+ }
+ return 0;
+}
+
+struct tunnconf tunnconf_default_l2tp = {
+ .mru = 1360,
+ .tcp_mss_adjust = false,
+ .pipex = true,
+ .ingress_filter = false,
+ .lcp_keepalive = false,
+ .lcp_keepalive_interval = DEFAULT_LCP_ECHO_INTERVAL,
+ .lcp_keepalive_retry_interval = DEFAULT_LCP_ECHO_RETRY_INTERVAL,
+ .lcp_keepalive_max_retries = DEFAULT_LCP_ECHO_MAX_RETRIES,
+ .auth_methods = NPPPD_AUTH_METHODS_CHAP | NPPPD_AUTH_METHODS_MSCHAPV2,
+ .mppe_yesno = true,
+ .mppe_required = false,
+ .mppe_keylen = NPPPD_MPPE_40BIT | NPPPD_MPPE_56BIT | NPPPD_MPPE_128BIT,
+ .mppe_keystate = NPPPD_MPPE_STATELESS | NPPPD_MPPE_STATEFUL,
+ .callnum_check = 0,
+ .proto = {
+ .l2tp = {
+ .hostname = NULL,
+ .vendor_name = NULL,
+ .address = {
+ .ss_family = AF_INET,
+ .ss_len = sizeof(struct sockaddr_in)
+ },
+ /* .hello_interval, */
+ /* .hello_timeout, */
+ .data_use_seq = true,
+ .require_ipsec = false,
+ /* .accept_dialin, */
+ .lcp_renegotiation = true,
+ .force_lcp_renegotiation = false,
+ /* .ctrl_in_pktdump, */
+ /* .ctrl_out_pktdump, */
+ /* .data_in_pktdump, */
+ /* .data_out_pktdump, */
+ }
+ }
+};
+struct tunnconf tunnconf_default_pptp = {
+ .mru = 1400,
+ .tcp_mss_adjust = false,
+ .pipex = true,
+ .ingress_filter = false,
+ .lcp_keepalive = true,
+ .lcp_keepalive_interval = DEFAULT_LCP_ECHO_INTERVAL,
+ .lcp_keepalive_retry_interval = DEFAULT_LCP_ECHO_RETRY_INTERVAL,
+ .lcp_keepalive_max_retries = DEFAULT_LCP_ECHO_MAX_RETRIES,
+ .auth_methods = NPPPD_AUTH_METHODS_CHAP | NPPPD_AUTH_METHODS_MSCHAPV2,
+ .mppe_yesno = true,
+ .mppe_required = true,
+ .mppe_keylen = NPPPD_MPPE_40BIT | NPPPD_MPPE_56BIT | NPPPD_MPPE_128BIT,
+ .mppe_keystate = NPPPD_MPPE_STATELESS | NPPPD_MPPE_STATEFUL,
+ .callnum_check = 0,
+ .proto = {
+ .pptp = {
+ .hostname = NULL,
+ .vendor_name = NULL,
+ .address = {
+ .ss_family = AF_INET,
+ .ss_len = sizeof(struct sockaddr_in)
+ },
+ /* .echo_interval, */
+ /* .echo_timeout, */
+ }
+ }
+};
+struct tunnconf tunnconf_default_pppoe = {
+ .mru = 1492,
+ .tcp_mss_adjust = false,
+ .pipex = true,
+ .ingress_filter = false,
+ .lcp_keepalive = true,
+ .lcp_keepalive_interval = DEFAULT_LCP_ECHO_INTERVAL,
+ .lcp_keepalive_retry_interval = DEFAULT_LCP_ECHO_RETRY_INTERVAL,
+ .lcp_keepalive_max_retries = DEFAULT_LCP_ECHO_MAX_RETRIES,
+ .auth_methods = NPPPD_AUTH_METHODS_CHAP | NPPPD_AUTH_METHODS_MSCHAPV2,
+ .mppe_yesno = true,
+ .mppe_required = false,
+ .mppe_keylen = NPPPD_MPPE_40BIT | NPPPD_MPPE_56BIT | NPPPD_MPPE_128BIT,
+ .mppe_keystate = NPPPD_MPPE_STATELESS | NPPPD_MPPE_STATEFUL,
+ .callnum_check = 0,
+ .proto = {
+ .pppoe = {
+ /* .service_name */
+ .accept_any_service = true,
+ /* .ac_name */
+ /* .desc_in_pktdump */
+ /* .desc_out_pktdump */
+ /* .session_in_pktdump */
+ /* .session_out_pktdump */
+ }
+ }
+};
+
+struct tunnconf *
+ppp_get_tunnconf(npppd_ppp *_this)
+{
+ struct tunnconf *conf;
+
+ conf = npppd_get_tunnconf(_this->pppd, _this->phy_label);
+ if (conf != NULL)
+ return conf;
+
+ switch (_this->tunnel_type) {
+ case NPPPD_TUNNEL_L2TP:
+ return &tunnconf_default_l2tp;
+ break;
+ case NPPPD_TUNNEL_PPTP:
+ return &tunnconf_default_pptp;
+ break;
+ case NPPPD_TUNNEL_PPPOE:
+ return &tunnconf_default_pppoe;
+ break;
+ }
+
+ return NULL;
+}
diff --git a/usr.sbin/npppd/npppd/ppp.h b/usr.sbin/npppd/npppd/ppp.h
index 24fd21730c3..3492df4937c 100644
--- a/usr.sbin/npppd/npppd/ppp.h
+++ b/usr.sbin/npppd/npppd/ppp.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: ppp.h,v 1.12 2012/09/07 10:47:42 yasuoka Exp $ */
+/* $OpenBSD: ppp.h,v 1.13 2012/09/18 13:14:08 yasuoka Exp $ */
/*-
* Copyright (c) 2009 Internet Initiative Japan Inc.
@@ -100,13 +100,6 @@
#define INADDR_USER_SELECT (htonl(0xFFFFFFFFL))
#define INADDR_NAS_SELECT (htonl(0xFFFFFFFEL))
-/** Constants of tunnel type */
-#define PPP_TUNNEL_NONE 0 /** None Tunnel Type */
-#define PPP_TUNNEL_L2TP 1 /** L2TP Tunnel Type */
-#define PPP_TUNNEL_PPTP 2 /** PPTP Tunnel Type */
-#define PPP_TUNNEL_PPPOE 3 /** PPPoE Tunnel Type */
-#define PPP_TUNNEL_SSTP 4 /** SSTP Tunnel Type */
-
/** Default LCP ECHO interval (sec) */
#define DEFAULT_LCP_ECHO_INTERVAL 300
@@ -427,9 +420,8 @@ typedef struct _mppe {
/* if 1 don't forward packet without MPPE */
required :1,
mode_auto :1,
- keylen_auto :1,
mode_stateless :1,
- reserved :11;
+ reserved :12;
uint16_t keylenbits;
mppe_rc4_t send, recv;
@@ -515,7 +507,6 @@ struct _npppd_ppp {
* </pre>
*/
uint16_t peer_auth;
- u_short auth_timeout;
#ifdef USE_NPPPD_MPPE
uint8_t mppe_started;
@@ -650,7 +641,7 @@ typedef struct _dialin_proxy_info {
((ppp)->peer_auth == PPP_AUTH_EAP)))
/** MPPE is required */
-#define MPPE_REQUIRED(ppp) \
+#define MPPE_IS_REQUIRED(ppp) \
(((ppp)->mppe.enabled != 0) && ((ppp)->mppe.required != 0))
/** MPPE is ready to use */
@@ -751,8 +742,12 @@ typedef struct _dialin_proxy_info {
#endif
#endif
-#define PPP_FSM_CONFIG(fsm, memb, confl) \
- (fsm)->memb = ppp_config_int((fsm)->ppp, confl, (fsm)->memb)
+#define PPP_FSM_CONFIG(_fsm, _memb, _val) \
+ do { \
+ (_fsm)->_memb = ((_val) == 0) \
+ ? (_fsm)->_memb : (_val); \
+ } while (0 /* CONSTCOND */)
+
#ifdef __cplusplus
extern "C" {
@@ -777,16 +772,13 @@ void ppp_ccp_opened (npppd_ppp *);
void ppp_ccp_stopped (npppd_ppp *);
inline void ppp_output (npppd_ppp *, uint16_t, u_char, u_char, u_char *, int);
u_char *ppp_packetbuf (npppd_ppp *, int);
-const char *ppp_config_str (npppd_ppp *, const char *);
-int ppp_config_int (npppd_ppp *, const char *, int);
-int ppp_config_str_equal (npppd_ppp *, const char *, const char *, int);
-int ppp_config_str_equali (npppd_ppp *, const char *, const char *, int);
int ppp_log (npppd_ppp *, int, const char *, ...) __printflike(3,4);
void ppp_reset_idle_timeout(npppd_ppp *);
#ifdef USE_NPPPD_RADIUS
void ppp_process_radius_framed_ip (npppd_ppp *, RADIUS_PACKET *);
int ppp_set_radius_attrs_for_authreq (npppd_ppp *, radius_req_setting *, RADIUS_PACKET *);
#endif
+struct tunnconf *ppp_get_tunnconf(npppd_ppp *);
void ccp_init (ccp *, npppd_ppp *);
void ipcp_init (ipcp *, npppd_ppp *);
diff --git a/usr.sbin/npppd/npppd/privsep.c b/usr.sbin/npppd/npppd/privsep.c
index cd10d3062dd..947aa8252d1 100644
--- a/usr.sbin/npppd/npppd/privsep.c
+++ b/usr.sbin/npppd/npppd/privsep.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: privsep.c,v 1.5 2012/05/08 13:15:12 yasuoka Exp $ */
+/* $OpenBSD: privsep.c,v 1.6 2012/09/18 13:14:08 yasuoka Exp $ */
/*
* Copyright (c) 2010 Yasuoka Masahiko <yasuoka@openbsd.org>
@@ -20,9 +20,12 @@
#include <sys/uio.h>
#include <sys/time.h>
#include <sys/un.h>
+#include <sys/ioctl.h>
#include <netinet/in.h>
#include <net/pfkeyv2.h>
+#include <net/if.h>
+#include <arpa/inet.h>
#include <stddef.h>
#include <stdio.h>
@@ -37,6 +40,9 @@
#include "pathnames.h"
#include "privsep.h"
+#include "npppd.h"
+#include "ppp.h"
+
#ifndef nitems
#define nitems(_a) (sizeof((_a)) / sizeof((_a)[0]))
#endif
@@ -46,7 +52,13 @@ enum PRIVSEP_CMD {
PRIVSEP_SOCKET,
PRIVSEP_BIND,
PRIVSEP_SENDTO,
- PRIVSEP_UNLINK
+ PRIVSEP_UNLINK,
+ PRIVSEP_GET_USER_INFO,
+ PRIVSEP_GET_IF_ADDR,
+ PRIVSEP_SET_IF_ADDR,
+ PRIVSEP_DEL_IF_ADDR,
+ PRIVSEP_GET_IF_FLAGS,
+ PRIVSEP_SET_IF_FLAGS
};
struct PRIVSEP_OPEN_ARG {
@@ -83,11 +95,66 @@ struct PRIVSEP_UNLINK_ARG {
char path[PATH_MAX];
};
+struct PRIVSEP_GET_USER_INFO_ARG {
+ enum PRIVSEP_CMD cmd;
+ char path[PATH_MAX];
+ char username[MAX_USERNAME_LENGTH];
+};
+
+struct PRIVSEP_GET_IF_ADDR_ARG {
+ enum PRIVSEP_CMD cmd;
+ char ifname[IFNAMSIZ];
+};
+
+struct PRIVSEP_GET_IF_ADDR_RESP {
+ int retval;
+ int rerrno;
+ struct in_addr addr;
+};
+
+struct PRIVSEP_SET_IF_ADDR_ARG {
+ enum PRIVSEP_CMD cmd;
+ char ifname[IFNAMSIZ];
+ struct in_addr addr;
+};
+
+struct PRIVSEP_DEL_IF_ADDR_ARG {
+ enum PRIVSEP_CMD cmd;
+ char ifname[IFNAMSIZ];
+};
+
+struct PRIVSEP_GET_IF_FLAGS_ARG {
+ enum PRIVSEP_CMD cmd;
+ char ifname[IFNAMSIZ];
+ int flags;
+};
+
+struct PRIVSEP_GET_IF_FLAGS_RESP {
+ int retval;
+ int rerrno;
+ int flags;
+};
+
+struct PRIVSEP_SET_IF_FLAGS_ARG {
+ enum PRIVSEP_CMD cmd;
+ char ifname[IFNAMSIZ];
+ int flags;
+};
+
struct PRIVSEP_COMMON_RESP {
int retval;
int rerrno;
};
+struct PRIVSEP_GET_USER_INFO_RESP {
+ int retval;
+ int rerrno;
+ char password[MAX_PASSWORD_LENGTH];
+ struct in_addr framed_ip_address;
+ struct in_addr framed_ip_netmask;
+ char calling_number[NPPPD_PHONE_NUMBER_LEN + 1];
+};
+
static void privsep_priv_main (int, int);
static void privsep_priv_on_sockio (int, short, void *);
static void privsep_priv_on_monpipeio (int, short, void *);
@@ -99,6 +166,12 @@ static int privsep_npppd_check_socket (struct PRIVSEP_SOCKET_ARG *);
static int privsep_npppd_check_bind (struct PRIVSEP_BIND_ARG *);
static int privsep_npppd_check_sendto (struct PRIVSEP_SENDTO_ARG *);
static int privsep_npppd_check_unlink (struct PRIVSEP_UNLINK_ARG *);
+static int privsep_npppd_check_get_user_info (struct PRIVSEP_GET_USER_INFO_ARG *);
+static int privsep_npppd_check_get_if_addr (struct PRIVSEP_GET_IF_ADDR_ARG *);
+static int privsep_npppd_check_set_if_addr (struct PRIVSEP_SET_IF_ADDR_ARG *);
+static int privsep_npppd_check_del_if_addr (struct PRIVSEP_DEL_IF_ADDR_ARG *);
+static int privsep_npppd_check_get_if_flags (struct PRIVSEP_GET_IF_FLAGS_ARG *);
+static int privsep_npppd_check_set_if_flags (struct PRIVSEP_SET_IF_FLAGS_ARG *);
static int privsep_sock = -1, privsep_monpipe = -1;;
static pid_t privsep_pid;
@@ -136,6 +209,7 @@ privsep_init(void)
_exit(0);
/* NOTREACHED */
}
+ setproctitle("main");
close(pairsock[0]);
close(monpipe[0]);
privsep_sock = pairsock[1];
@@ -330,6 +404,149 @@ priv_unlink(const char *path)
return privsep_common_resp();
}
+int
+priv_get_user_info(const char *path, const char *username,
+ npppd_auth_user **puser)
+{
+ int n, sz, retval;
+ char *cp;
+ struct PRIVSEP_GET_USER_INFO_ARG a;
+ struct PRIVSEP_GET_USER_INFO_RESP r;
+ npppd_auth_user *u;
+
+ a.cmd = PRIVSEP_GET_USER_INFO;
+ strlcpy(a.path, path, sizeof(a.path));
+ strlcpy(a.username, username, sizeof(a.username));
+ if ((retval = send(privsep_sock, &a, sizeof(a), 0)) < 0)
+ return retval;
+
+ if (recv(privsep_sock, &r, sizeof(r), 0) != sizeof(r))
+ return -1;
+ if (r.retval != 0) {
+ errno = r.rerrno;
+ return r.retval;
+ }
+
+ sz = strlen(username) + strlen(r.password) +
+ strlen(r.calling_number) + 3;
+
+ if ((u = malloc(offsetof(npppd_auth_user, space[sz]))) == NULL)
+ return -1;
+
+ cp = u->space;
+
+ u->username = cp;
+ n = strlcpy(cp, username, sz);
+ cp += ++n; sz -= n;
+
+ u->password = cp;
+ n = strlcpy(cp, r.password, sz);
+ cp += ++n; sz -= n;
+
+ u->calling_number = cp;
+ n = strlcpy(cp, r.calling_number, sz);
+ cp += ++n; sz -= n;
+
+ *puser = u;
+
+ return 0;
+}
+
+int
+priv_get_if_addr(const char *ifname, struct in_addr *addr)
+{
+ int retval;
+ struct PRIVSEP_GET_IF_ADDR_ARG a;
+ struct PRIVSEP_GET_IF_ADDR_RESP r;
+
+ a.cmd = PRIVSEP_GET_IF_ADDR;
+ strlcpy(a.ifname, ifname, sizeof(ifname));
+ if ((retval = send(privsep_sock, &a, sizeof(a), 0)) < 0)
+ return retval;
+ if ((retval = recv(privsep_sock, &r, sizeof(r), 0)) < 0) {
+ if (retval < 0)
+ return retval;
+ errno = EACCES;
+ return -1;
+ }
+
+ if (r.retval != -1)
+ *addr = r.addr;
+ else
+ errno = r.rerrno;
+
+ return 0;
+}
+
+int
+priv_delete_if_addr(const char *ifname)
+{
+ int retval;
+ struct PRIVSEP_DEL_IF_ADDR_ARG a;
+
+ a.cmd = PRIVSEP_DEL_IF_ADDR;
+ strlcpy(a.ifname, ifname, sizeof(ifname));
+ if ((retval = send(privsep_sock, &a, sizeof(a), 0)) < 0)
+ return retval;
+ retval = privsep_common_resp();
+
+ return retval;
+}
+
+int
+priv_set_if_addr(const char *ifname, struct in_addr *addr)
+{
+ int retval;
+ struct PRIVSEP_SET_IF_ADDR_ARG a;
+
+ a.cmd = PRIVSEP_SET_IF_ADDR;
+ strlcpy(a.ifname, ifname, sizeof(ifname));
+ a.addr = *addr;
+ if ((retval = send(privsep_sock, &a, sizeof(a), 0)) < 0)
+ return retval;
+
+ return privsep_common_resp();
+}
+
+int
+priv_get_if_flags(const char *ifname, int *pflags)
+{
+ int retval;
+ struct PRIVSEP_GET_IF_FLAGS_ARG a;
+ struct PRIVSEP_GET_IF_FLAGS_RESP r;
+
+ a.cmd = PRIVSEP_GET_IF_FLAGS;
+ strlcpy(a.ifname, ifname, sizeof(ifname));
+ if ((retval = send(privsep_sock, &a, sizeof(a), 0)) < 0)
+ return retval;
+ if ((retval = recv(privsep_sock, &r, sizeof(r), 0)) < 0) {
+ if (retval < 0)
+ return retval;
+ errno = EACCES;
+ return -1;
+ }
+ *pflags = r.flags;
+
+ if (r.retval != 0)
+ errno = r.rerrno;
+
+ return 0;
+}
+
+int
+priv_set_if_flags(const char *ifname, int flags)
+{
+ int retval;
+ struct PRIVSEP_SET_IF_FLAGS_ARG a;
+
+ a.cmd = PRIVSEP_SET_IF_FLAGS;
+ strlcpy(a.ifname, ifname, sizeof(ifname));
+ a.flags = flags;
+ if ((retval = send(privsep_sock, &a, sizeof(a), 0)) < 0)
+ return retval;
+ return privsep_common_resp();
+}
+
static int
privsep_recvfd(void)
{
@@ -506,6 +723,61 @@ privsep_priv_on_sockio(int sock, short evmask, void *ctx)
(void)send(sock, &r, sizeof(r), 0);
}
break;
+ case PRIVSEP_GET_USER_INFO: {
+ struct PRIVSEP_GET_USER_INFO_ARG *a;
+ struct PRIVSEP_GET_USER_INFO_RESP r;
+ int retval;
+ char *str, *buf, *db[2] = { NULL, NULL };
+
+ a = (struct PRIVSEP_GET_USER_INFO_ARG *)rbuf;
+ memset(&r, 0, sizeof(r));
+ db[0] = a->path;
+
+ if (privsep_npppd_check_get_user_info(a)) {
+ r.retval = -1;
+ r.rerrno = EACCES;
+ } else if ((retval = cgetent(&buf, db, a->username))
+ == 0) {
+ if ((retval = cgetstr(buf, "password", &str))
+ >= 0) {
+ if (strlcpy(r.password, str,
+ sizeof(r.password)) >=
+ sizeof(r.password))
+ goto on_broken_entry;
+ }
+ if ((retval = cgetstr(buf, "calling-number",
+ &str)) >= 0) {
+ if (strlcpy(r.calling_number, str,
+ sizeof(r.calling_number)) >=
+ sizeof(r.calling_number))
+ goto on_broken_entry;
+ }
+ if ((retval = cgetstr(buf, "framed-ip-address",
+ &str)) >= 0) {
+ if (inet_aton(str,
+ &r.framed_ip_address) != 1)
+ goto on_broken_entry;
+ }
+
+ if ((retval = cgetstr(buf, "framed-ip-netmask",
+ &str)) >= 0) {
+ if (inet_aton(str,
+ &r.framed_ip_netmask) != 1)
+ goto on_broken_entry;
+ }
+ cgetclose();
+ r.retval = 0;
+ } else if (retval == -1) {
+on_broken_entry:
+ r.retval = -1;
+ r.rerrno = ENOENT;
+ } else {
+ r.retval = retval;
+ r.rerrno = errno;
+ }
+ (void)send(sock, &r, sizeof(r), 0);
+ }
+ break;
case PRIVSEP_SENDTO: {
struct PRIVSEP_SENDTO_ARG *a;
struct PRIVSEP_COMMON_RESP r;
@@ -538,6 +810,158 @@ privsep_priv_on_sockio(int sock, short evmask, void *ctx)
(void)send(sock, &r, sizeof(r), 0);
}
break;
+ case PRIVSEP_GET_IF_ADDR: {
+ int s;
+ struct ifreq ifr;
+ struct PRIVSEP_GET_IF_ADDR_ARG *a;
+ struct PRIVSEP_GET_IF_ADDR_RESP r;
+
+ a = (struct PRIVSEP_GET_IF_ADDR_ARG *)rbuf;
+ if (privsep_npppd_check_get_if_addr(a)) {
+ r.rerrno = EACCES;
+ r.retval = -1;
+ } else {
+ memset(&ifr, 0, sizeof(ifr));
+ strlcpy(ifr.ifr_name, a->ifname,
+ sizeof(ifr.ifr_name));
+ if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0 ||
+ ioctl(s, SIOCGIFADDR, &ifr) != 0) {
+ r.retval = -1;
+ r.rerrno = errno;
+ } else
+ r.addr = ((struct sockaddr_in *)
+ &ifr.ifr_addr)->sin_addr;
+ if (s >= 0)
+ close(s);
+ }
+ (void)send(sock, &r, sizeof(r), 0);
+ }
+ break;
+ case PRIVSEP_SET_IF_ADDR: {
+ int s;
+ struct ifaliasreq ifra;
+ struct PRIVSEP_SET_IF_ADDR_ARG *a;
+ struct PRIVSEP_COMMON_RESP r;
+ struct sockaddr_in *sin4;
+
+ a = (struct PRIVSEP_SET_IF_ADDR_ARG *)rbuf;
+ if (privsep_npppd_check_set_if_addr(a)) {
+ r.rerrno = EACCES;
+ r.retval = -1;
+ } else {
+ memset(&ifra, 0, sizeof(ifra));
+ strlcpy(ifra.ifra_name, a->ifname,
+ sizeof(ifra.ifra_name));
+
+ sin4 = (struct sockaddr_in *)&ifra.ifra_addr;
+ sin4->sin_family = AF_INET;
+ sin4->sin_len = sizeof(struct sockaddr_in);
+ sin4->sin_addr = a->addr;
+
+ sin4 = (struct sockaddr_in *)&ifra.ifra_mask;
+ sin4->sin_family = AF_INET;
+ sin4->sin_len = sizeof(struct sockaddr_in);
+ sin4->sin_addr.s_addr = 0xffffffffUL;
+
+ sin4 =
+ (struct sockaddr_in *)&ifra.ifra_broadaddr;
+ sin4->sin_family = AF_INET;
+ sin4->sin_len = sizeof(struct sockaddr_in);
+ sin4->sin_addr.s_addr = 0;
+
+ if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0 ||
+ ioctl(s, SIOCAIFADDR, &ifra) != 0) {
+ r.retval = -1;
+ r.rerrno = errno;
+ } else
+ r.retval = 0;
+ if (s >= 0)
+ close(s);
+ }
+ (void)send(sock, &r, sizeof(r), 0);
+ }
+ break;
+ case PRIVSEP_DEL_IF_ADDR: {
+ int s;
+ struct ifreq ifr;
+ struct PRIVSEP_DEL_IF_ADDR_ARG *a;
+ struct PRIVSEP_COMMON_RESP r;
+
+ a = (struct PRIVSEP_DEL_IF_ADDR_ARG *)rbuf;
+ if (privsep_npppd_check_del_if_addr(a)) {
+ r.rerrno = EACCES;
+ r.retval = -1;
+ } else {
+ memset(&ifr, 0, sizeof(ifr));
+ strlcpy(ifr.ifr_name, a->ifname,
+ sizeof(ifr.ifr_name));
+ if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0 ||
+ ioctl(s, SIOCDIFADDR, &ifr) != 0) {
+ r.retval = -1;
+ r.rerrno = errno;
+ } else
+ r.retval = 0;
+ if (s >= 0)
+ close(s);
+ }
+ (void)send(sock, &r, sizeof(r), 0);
+ }
+ break;
+ case PRIVSEP_GET_IF_FLAGS: {
+ int s;
+ struct ifreq ifr;
+ struct PRIVSEP_GET_IF_FLAGS_ARG *a;
+ struct PRIVSEP_GET_IF_FLAGS_RESP r;
+
+ a = (struct PRIVSEP_GET_IF_FLAGS_ARG *)rbuf;
+ if (privsep_npppd_check_get_if_flags(a)) {
+ r.rerrno = EACCES;
+ r.retval = -1;
+ } else {
+ memset(&ifr, 0, sizeof(ifr));
+ strlcpy(ifr.ifr_name, a->ifname,
+ sizeof(ifr.ifr_name));
+ if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0 ||
+ ioctl(s, SIOCGIFFLAGS, &ifr) != 0) {
+ r.retval = -1;
+ r.rerrno = errno;
+ } else {
+ r.retval = 0;
+ r.flags = ifr.ifr_flags;
+ }
+ if (s >= 0)
+ close(s);
+ }
+ (void)send(sock, &r, sizeof(r), 0);
+ }
+ break;
+ case PRIVSEP_SET_IF_FLAGS: {
+ int s;
+ struct ifreq ifr;
+ struct PRIVSEP_SET_IF_FLAGS_ARG *a;
+ struct PRIVSEP_COMMON_RESP r;
+
+ a = (struct PRIVSEP_SET_IF_FLAGS_ARG *)rbuf;
+ if (privsep_npppd_check_set_if_flags(a)) {
+ r.rerrno = EACCES;
+ r.retval = -1;
+ } else {
+ memset(&ifr, 0, sizeof(ifr));
+ strlcpy(ifr.ifr_name, a->ifname,
+ sizeof(ifr.ifr_name));
+ ifr.ifr_flags = a->flags;
+ if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0 ||
+ ioctl(s, SIOCGIFFLAGS, &ifr) != 0) {
+ r.retval = -1;
+ r.rerrno = errno;
+ } else
+ r.retval = 0;
+ if (s >= 0)
+ close(s);
+ }
+ (void)send(sock, &r, sizeof(r), 0);
+ }
+ break;
}
}
}
@@ -601,7 +1025,9 @@ privsep_npppd_check_open(struct PRIVSEP_OPEN_ARG *arg)
} const allow_paths[] = {
{ NPPPD_DIR "/", 1, 1 },
{ "/dev/bpf", 1, 0 },
- { "/etc/resolv.conf", 0, 1 }
+ { "/etc/resolv.conf", 0, 1 },
+ { "/dev/tun", 1, 0 },
+ { "/dev/pppx", 1, 0 }
};
for (i = 0; i < nitems(allow_paths); i++) {
@@ -668,3 +1094,65 @@ privsep_npppd_check_unlink(struct PRIVSEP_UNLINK_ARG *arg)
return 1;
}
+
+static int
+privsep_npppd_check_get_user_info(struct PRIVSEP_GET_USER_INFO_ARG *arg)
+{
+ int l;
+
+ l = strlen(NPPPD_DIR "/");
+ if (strncmp(arg->path, NPPPD_DIR "/", l) == 0)
+ return 0;
+
+ return 1;
+}
+
+static int
+privsep_npppd_check_get_if_addr(struct PRIVSEP_GET_IF_ADDR_ARG *arg)
+{
+ if (strncmp(arg->ifname, "tun", 3) == 0 ||
+ strncmp(arg->ifname, "pppx", 4))
+ return 0;
+
+ return 1;
+}
+
+static int
+privsep_npppd_check_set_if_addr(struct PRIVSEP_SET_IF_ADDR_ARG *arg)
+{
+ if (strncmp(arg->ifname, "tun", 3) == 0 ||
+ strncmp(arg->ifname, "pppx", 4))
+ return 0;
+
+ return 1;
+}
+
+static int
+privsep_npppd_check_del_if_addr(struct PRIVSEP_DEL_IF_ADDR_ARG *arg)
+{
+ if (strncmp(arg->ifname, "tun", 3) == 0 ||
+ strncmp(arg->ifname, "pppx", 4))
+ return 0;
+
+ return 1;
+}
+
+static int
+privsep_npppd_check_get_if_flags(struct PRIVSEP_GET_IF_FLAGS_ARG *arg)
+{
+ if (strncmp(arg->ifname, "tun", 3) == 0 ||
+ strncmp(arg->ifname, "pppx", 4))
+ return 0;
+
+ return 1;
+}
+
+static int
+privsep_npppd_check_set_if_flags(struct PRIVSEP_SET_IF_FLAGS_ARG *arg)
+{
+ if (strncmp(arg->ifname, "tun", 3) == 0 ||
+ strncmp(arg->ifname, "pppx", 4))
+ return 0;
+
+ return 1;
+}
diff --git a/usr.sbin/npppd/npppd/privsep.h b/usr.sbin/npppd/npppd/privsep.h
index 0486dbef5c1..7b06ec5590e 100644
--- a/usr.sbin/npppd/npppd/privsep.h
+++ b/usr.sbin/npppd/npppd/privsep.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: privsep.h,v 1.4 2012/05/08 13:15:12 yasuoka Exp $ */
+/* $OpenBSD: privsep.h,v 1.5 2012/09/18 13:14:08 yasuoka Exp $ */
/*
* Copyright (c) 2010 Yasuoka Masahiko <yasuoka@openbsd.org>
@@ -20,6 +20,8 @@
#define PRIVSEP_BUFSIZE 4092
+#include "npppd_auth.h"
+
#ifdef __cplusplus
extern "C" {
#endif
@@ -34,6 +36,12 @@ int priv_socket (int, int, int);
int priv_open (const char *, int, mode_t);
int priv_send (int, const void *, int, int);
int priv_sendto (int, const void *, int, int, const struct sockaddr *, socklen_t);
+int priv_get_user_info(const char *, const char *, npppd_auth_user **);
+int priv_set_if_addr(const char *, struct in_addr *);
+int priv_get_if_addr(const char *, struct in_addr *);
+int priv_delete_if_addr(const char *);
+int priv_set_if_flags(const char *, int);
+int priv_get_if_flags(const char *, int *);
#ifdef __cplusplus
}
diff --git a/usr.sbin/npppd/npppd/radius_req.c b/usr.sbin/npppd/npppd/radius_req.c
index 98f9b84f6a2..162b32612b7 100644
--- a/usr.sbin/npppd/npppd/radius_req.c
+++ b/usr.sbin/npppd/npppd/radius_req.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: radius_req.c,v 1.5 2012/05/08 13:15:12 yasuoka Exp $ */
+/* $OpenBSD: radius_req.c,v 1.6 2012/09/18 13:14:08 yasuoka Exp $ */
/*-
* Copyright (c) 2009 Internet Initiative Japan Inc.
@@ -28,7 +28,7 @@
/**@file
* This file provides functions for RADIUS request using radius+.c and event(3).
* @author Yasuoka Masahiko
- * $Id: radius_req.c,v 1.5 2012/05/08 13:15:12 yasuoka Exp $
+ * $Id: radius_req.c,v 1.6 2012/09/18 13:14:08 yasuoka Exp $
*/
#include <sys/types.h>
#include <sys/param.h>
@@ -265,7 +265,7 @@ radius_prepare_socket(struct overlapped *lap)
*/
int
radius_prepare(radius_req_setting *setting, void *context,
- RADIUS_REQUEST_CTX *pctx, radius_response response_fn, int timeout)
+ RADIUS_REQUEST_CTX *pctx, radius_response response_fn)
{
struct overlapped *lap;
@@ -284,13 +284,7 @@ radius_prepare(radius_req_setting *setting, void *context,
lap->socket = -1;
lap->setting = setting;
- if (timeout != 0 &&
- (setting->max_tries == 0 ||
- timeout < setting->max_tries * setting->timeout))
- lap->max_tries = timeout / setting->timeout;
- else
- lap->max_tries = setting->max_tries;
-
+ lap->max_tries = setting->max_tries;
if (lap->max_tries <= 0)
lap->max_tries = 3; /* default max tries */
diff --git a/usr.sbin/npppd/npppd/radius_req.h b/usr.sbin/npppd/npppd/radius_req.h
index 6704c731db7..2b354979112 100644
--- a/usr.sbin/npppd/npppd/radius_req.h
+++ b/usr.sbin/npppd/npppd/radius_req.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: radius_req.h,v 1.5 2012/05/08 13:15:12 yasuoka Exp $ */
+/* $OpenBSD: radius_req.h,v 1.6 2012/09/18 13:14:08 yasuoka Exp $ */
/*-
* Copyright (c) 2009 Internet Initiative Japan Inc.
@@ -94,7 +94,7 @@ void radius_request (RADIUS_REQUEST_CTX, RADIUS_PACKET *);
int radius_prepare_nas_address (radius_req_setting *, RADIUS_PACKET *);
int radius_request_can_failover (RADIUS_REQUEST_CTX);
int radius_request_failover (RADIUS_REQUEST_CTX);
-int radius_prepare (radius_req_setting *, void *, RADIUS_REQUEST_CTX *, radius_response, int);
+int radius_prepare (radius_req_setting *, void *, RADIUS_REQUEST_CTX *, radius_response);
void radius_cancel_request (RADIUS_REQUEST_CTX);
const char *radius_get_server_secret (RADIUS_REQUEST_CTX);
struct sockaddr *radius_get_server_address (RADIUS_REQUEST_CTX);
diff --git a/usr.sbin/npppd/pppoe/pppoe.h b/usr.sbin/npppd/pppoe/pppoe.h
index d0c896dca0e..6c3c04e1f40 100644
--- a/usr.sbin/npppd/pppoe/pppoe.h
+++ b/usr.sbin/npppd/pppoe/pppoe.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: pppoe.h,v 1.4 2012/05/08 13:15:12 yasuoka Exp $ */
+/* $OpenBSD: pppoe.h,v 1.5 2012/09/18 13:14:08 yasuoka Exp $ */
/*-
* Copyright (c) 2009 Internet Initiative Japan Inc.
@@ -82,7 +82,9 @@ struct pppoe_tlv {
/*
* Constant variables and types for implementions
*/
-/** Default data link layer label */
+#include "pppoe_conf.h"
+
+/** Default data link layer */
#define PPPOED_DEFAULT_LAYER2_LABEL "PPPoE"
#define PPPOED_CONFIG_BUFSIZ 65535
@@ -118,7 +120,9 @@ typedef struct _pppoed_listener {
/** Listening interface name */
char listen_ifname[IF_NAMESIZE];
/** Label of physcal layer */
- char phy_label[PPPOED_PHY_LABEL_SIZE];
+ char tun_name[PPPOED_PHY_LABEL_SIZE];
+ /** Configuration */
+ struct pppoe_conf *conf;
} pppoed_listener;
/** PPPoE daemon type */
@@ -140,17 +144,10 @@ typedef struct _pppoed {
/** Next cookie number */
uint32_t acookie_next;
- /** Configuration {@link struct properties properties} */
- struct properties *config;
-
/** Flags */
uint32_t
- desc_in_pktdump:1,
- desc_out_pktdump:1,
- session_in_pktdump:1,
- session_out_pktdump:1,
listen_incomplete:1,
- reserved:27;
+ reserved:31;
} pppoed;
/** PPPoE session type */
@@ -196,26 +193,16 @@ int pppoe_session_recv_PADT (pppoe_session *, slist *);
void pppoe_session_input (pppoe_session *, u_char *, int);
void pppoe_session_disconnect (pppoe_session *);
-
int pppoed_add_listener (pppoed *, int, const char *, const char *);
int pppoed_reload_listeners(pppoed *);
-int pppoed_init (pppoed *);
-int pppoed_start (pppoed *);
-void pppoed_stop (pppoed *);
-void pppoed_uninit (pppoed *);
-void pppoed_pppoe_session_close_notify(pppoed *, pppoe_session *);
-const char * pppoed_tlv_value_string(struct pppoe_tlv *);
-int pppoed_reload(pppoed *, struct properties *, const char *, int);
-const char *pppoed_config_str (pppoed *, const char *);
-int pppoed_config_int (pppoed *, const char *, int);
-int pppoed_config_str_equal (pppoed *, const char *, const char *, int);
-int pppoed_config_str_equali (pppoed *, const char *, const char *, int);
-
-const char *pppoed_listener_config_str (pppoed_listener *, const char *);
-int pppoed_listener_config_int (pppoed_listener *, const char *, int);
-int pppoed_listener_config_str_equal (pppoed_listener *, const char *, const char *, int);
-int pppoed_listener_config_str_equali (pppoed_listener *, const char *, const char *, int);
+int pppoed_init (pppoed *);
+int pppoed_start (pppoed *);
+void pppoed_stop (pppoed *);
+void pppoed_uninit (pppoed *);
+void pppoed_pppoe_session_close_notify(pppoed *, pppoe_session *);
+const char *pppoed_tlv_value_string(struct pppoe_tlv *);
+int pppoed_reload(pppoed *, struct pppoe_confs *);
#ifdef __cplusplus
}
diff --git a/usr.sbin/npppd/pppoe/pppoe_conf.h b/usr.sbin/npppd/pppoe/pppoe_conf.h
new file mode 100644
index 00000000000..c6adccfbca1
--- /dev/null
+++ b/usr.sbin/npppd/pppoe/pppoe_conf.h
@@ -0,0 +1,46 @@
+/* $OpenBSD: pppoe_conf.h,v 1.1 2012/09/18 13:14:08 yasuoka Exp $ */
+
+/*
+ * Copyright (c) 2012 YASUOKA Masahiko <yasuoka@openbsd.org>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+#ifndef PPPOE_CONF_H
+#define PPPOE_CONF_H 1
+
+#include <sys/types.h>
+#include <sys/queue.h>
+#include <sys/socket.h>
+
+#include <stdbool.h>
+
+#define PPPOE_NAME_LEN 16
+
+TAILQ_HEAD(pppoe_confs, pppoe_conf);
+
+#include <net/if.h>
+
+struct pppoe_conf {
+ TAILQ_ENTRY(pppoe_conf) entry;
+ char name[PPPOE_NAME_LEN];
+ char if_name[IF_NAMESIZE];
+ char *service_name;
+ char *ac_name;
+ bool accept_any_service;
+ bool desc_in_pktdump;
+ bool desc_out_pktdump;
+ bool session_in_pktdump;
+ bool session_out_pktdump;
+};
+
+#endif
diff --git a/usr.sbin/npppd/pppoe/pppoe_local.h b/usr.sbin/npppd/pppoe/pppoe_local.h
index e741f46a3dc..94e213c2118 100644
--- a/usr.sbin/npppd/pppoe/pppoe_local.h
+++ b/usr.sbin/npppd/pppoe/pppoe_local.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: pppoe_local.h,v 1.4 2012/05/08 13:15:12 yasuoka Exp $ */
+/* $OpenBSD: pppoe_local.h,v 1.5 2012/09/18 13:14:08 yasuoka Exp $ */
/*-
* Copyright (c) 2009 Internet Initiative Japan Inc.
@@ -51,9 +51,9 @@
(session)->listener_index))->bpf
/** macro is to get the physical layer label by {@link pppoe_session} */
-#define PPPOE_SESSION_LISTENER_LABEL(session) \
+#define PPPOE_SESSION_LISTENER_TUN_NAME(session) \
((pppoed_listener *)slist_get(&(session)->pppoed->listener, \
- (session)->listener_index))->phy_label
+ (session)->listener_index))->tun_name
/** macro is to get the interface name by {@link pppoe_session} */
#define PPPOE_SESSION_LISTENER_IFNAME(session) \
((pppoed_listener *)slist_get(&(session)->pppoed->listener, \
diff --git a/usr.sbin/npppd/pppoe/pppoe_session.c b/usr.sbin/npppd/pppoe/pppoe_session.c
index 87842baf535..982bcf7d556 100644
--- a/usr.sbin/npppd/pppoe/pppoe_session.c
+++ b/usr.sbin/npppd/pppoe/pppoe_session.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pppoe_session.c,v 1.6 2012/05/08 13:15:12 yasuoka Exp $ */
+/* $OpenBSD: pppoe_session.c,v 1.7 2012/09/18 13:14:08 yasuoka Exp $ */
/*-
* Copyright (c) 2009 Internet Initiative Japan Inc.
@@ -28,7 +28,7 @@
/**@file
* Session management of PPPoE protocol
- * $Id: pppoe_session.c,v 1.6 2012/05/08 13:15:12 yasuoka Exp $
+ * $Id: pppoe_session.c,v 1.7 2012/09/18 13:14:08 yasuoka Exp $
*/
#include <sys/types.h>
@@ -494,12 +494,12 @@ pppoe_session_bind_ppp(pppoe_session *_this)
_this->ppp = ppp;
- ppp->tunnel_type = PPP_TUNNEL_PPPOE;
+ ppp->tunnel_type = NPPPD_TUNNEL_PPPOE;
ppp->phy_context = _this;
ppp->send_packet = pppoe_session_ppp_output;
ppp->phy_close = pppoe_session_close_by_ppp;
- strlcpy(ppp->phy_label, PPPOE_SESSION_LISTENER_LABEL(_this),
+ strlcpy(ppp->phy_label, PPPOE_SESSION_LISTENER_TUN_NAME(_this),
sizeof(ppp->phy_label));
memset(&sdl, 0, sizeof(sdl));
diff --git a/usr.sbin/npppd/pppoe/pppoed.c b/usr.sbin/npppd/pppoe/pppoed.c
index acf60fa8b3d..490a3bf9087 100644
--- a/usr.sbin/npppd/pppoe/pppoed.c
+++ b/usr.sbin/npppd/pppoe/pppoed.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pppoed.c,v 1.10 2012/05/08 13:18:37 yasuoka Exp $ */
+/* $OpenBSD: pppoed.c,v 1.11 2012/09/18 13:14:08 yasuoka Exp $ */
/*-
* Copyright (c) 2009 Internet Initiative Japan Inc.
@@ -28,7 +28,7 @@
/**@file
* This file provides the PPPoE(RFC2516) server(access concentrator)
* implementaion.
- * $Id: pppoed.c,v 1.10 2012/05/08 13:18:37 yasuoka Exp $
+ * $Id: pppoed.c,v 1.11 2012/09/18 13:14:08 yasuoka Exp $
*/
#include <sys/types.h>
#include <sys/param.h>
@@ -64,8 +64,6 @@
#include "slist.h"
#include "bytebuf.h"
#include "hash.h"
-#include "properties.h"
-#include "config_helper.h"
#include "privsep.h"
#include "pppoe.h"
@@ -329,7 +327,7 @@ pppoed_listener_start(pppoed_listener *_this, int restart)
pppoed_log(_pppoed, LOG_INFO, "Listening on %s (PPPoE) [%s] using=%s "
"address=%02x:%02x:%02x:%02x:%02x:%02x", _this->listen_ifname,
- _this->phy_label, buf, _this->ether_addr[0], _this->ether_addr[1],
+ _this->tun_name, buf, _this->ether_addr[0], _this->ether_addr[1],
_this->ether_addr[2], _this->ether_addr[3], _this->ether_addr[4],
_this->ether_addr[5]);
@@ -386,7 +384,7 @@ pppoed_listener_stop(pppoed_listener *_this)
close(_this->bpf);
pppoed_log(_pppoed, LOG_INFO, "Shutdown %s (PPPoE) [%s] "
"address=%02x:%02x:%02x:%02x:%02x:%02x",
- _this->listen_ifname, _this->phy_label,
+ _this->listen_ifname, _this->tun_name,
_this->ether_addr[0], _this->ether_addr[1],
_this->ether_addr[2], _this->ether_addr[3],
_this->ether_addr[4], _this->ether_addr[5]);
@@ -440,8 +438,6 @@ pppoed_uninit(pppoed *_this)
slist_fini(&_this->session_free_list);
/* listener themself has been released already */
slist_fini(&_this->listener);
-
- _this->config = NULL;
}
/* it called when the PPPoE session was closed */
@@ -465,127 +461,39 @@ pppoed_pppoe_session_close_notify(pppoed *_this, pppoe_session *session)
/*
* PPPoE Configuration
*/
-#define CFG_KEY(p, s) config_key_prefix((p), (s))
-#define VAL_SEP " \t\r\n"
-
-CONFIG_FUNCTIONS(pppoed_config, pppoed, config);
-PREFIXED_CONFIG_FUNCTIONS(pppoed_listener_config, pppoed_listener, self->config,
- phy_label);
-
/* reload configurations for the PPPoE daemon */
int
-pppoed_reload(pppoed *_this, struct properties *config, const char *name,
- int default_enabled)
+pppoed_reload(pppoed *_this, struct pppoe_confs *pppoe_conf)
{
- struct sockaddr_dl *sdl;
- int i, count, found;
- hash_link *hl;
- const char *val;
- char *tok, *cp, buf[PPPOED_CONFIG_BUFSIZ], *label;
- pppoed_listener *l;
- int do_start;
+ int i, count, do_start, found;
+ struct pppoe_conf *conf;
+ struct ifaddrs *ifa0;
+ slist rmlist, newlist;
struct {
- char ifname[IF_NAMESIZE];
- char label[PPPOED_PHY_LABEL_SIZE];
+ char ifname[IF_NAMESIZE];
+ char name[PPPOED_PHY_LABEL_SIZE];
} listeners[PPPOE_NLISTENER];
- struct ifaddrs *ifa0, *ifa;
- slist rmlist, newlist;
- pppoe_session *session;
+ pppoed_listener *l;
+ pppoe_session *session;
+ hash_link *hl;
do_start = 0;
-
- _this->config = config;
- if (pppoed_config_str_equal(_this, CFG_KEY(name, "enabled"), "true",
- default_enabled)) {
- /* avoid false->true flapping */
- if (pppoed_is_stopped(_this) || !pppoed_is_running(_this))
- do_start = 1;
- } else {
- if (!pppoed_is_stopped(_this))
- pppoed_stop(_this);
- return 0;
- }
-
- if (do_start) {
- if (pppoed_init(_this) != 0)
- return 1;
- _this->config = config;
- }
-
ifa0 = NULL;
slist_init(&rmlist);
slist_init(&newlist);
- _this->desc_in_pktdump = pppoed_config_str_equal(_this,
- "log.pppoe.desc.in.pktdump", "true", 0);
- _this->desc_out_pktdump = pppoed_config_str_equal(_this,
- "log.pppoe.desc.out.pktdump", "true", 0);
-
- _this->session_in_pktdump = pppoed_config_str_equal(_this,
- "log.pppoe.session.in.pktdump", "true", 0);
- _this->session_out_pktdump = pppoed_config_str_equal(_this,
- "log.pppoe.session.out.pktdump", "true", 0);
-
if (getifaddrs(&ifa0) != 0) {
pppoed_log(_this, LOG_ERR,
"getifaddrs() failed on %s(): %m", __func__);
goto fail;
}
count = 0;
- val = pppoed_config_str(_this, CFG_KEY(name, "interface"));
- if (val != NULL) {
- if (strlen(val) >= sizeof(buf)) {
- log_printf(LOG_ERR, "configuration error at "
- "%s: too long", CFG_KEY(name, "interface"));
- return 1;
- }
- strlcpy(buf, val, sizeof(buf));
-
- label = NULL;
- /* it accepts multiple entries with tab/space separation */
- for (i = 0, cp = buf;
- (tok = strsep(&cp, VAL_SEP)) != NULL;) {
- if (*tok == '\0')
- continue;
- if (label == NULL) {
- label = tok;
- continue;
- }
- PPPOED_ASSERT(count < countof(listeners));
- if (count >= countof(listeners)) {
- pppoed_log(_this, LOG_ERR,
- "Too many listeners");
- goto fail;
- }
- /* check the interface exist or not */
- found = 0;
- for (ifa = ifa0; ifa != NULL; ifa = ifa->ifa_next) {
- sdl = (struct sockaddr_dl *)ifa->ifa_addr;
- if (sdl->sdl_family == AF_LINK &&
- IFTYPE_IS_LAN(sdl->sdl_type) &&
- strcmp(ifa->ifa_name, tok) == 0) {
- found = 1;
- break;
- }
- }
- if (!found) {
- pppoed_log(_this, LOG_ERR,
- "interface %s is not found", tok);
- goto fail;
- }
- strlcpy(listeners[count].ifname, tok,
- sizeof(listeners[count].ifname));
- strlcpy(listeners[count].label, label,
- sizeof(listeners[count].label));
-
- label = NULL;
- count++;
- }
- if (label != NULL) {
- log_printf(LOG_ERR, "configuration error at %s: %s",
- CFG_KEY(name, "interface"), label);
- return 1;
- }
+ TAILQ_FOREACH(conf, pppoe_conf, entry) {
+ strlcpy(listeners[count].ifname, conf->if_name,
+ sizeof(listeners[count].ifname));
+ strlcpy(listeners[count].name, conf->name,
+ sizeof(listeners[count].name));
+ count++;
}
if (slist_add_all(&rmlist, &_this->listener) != 0)
@@ -609,8 +517,7 @@ pppoed_reload(pppoed *_this, struct properties *config, const char *name,
pppoed_listener_init(_this, l);
}
l->self = _this;
- strlcpy(l->phy_label, listeners[i].label,
- sizeof(l->phy_label));
+ strlcpy(l->tun_name, listeners[i].name, sizeof(l->tun_name));
strlcpy(l->listen_ifname, listeners[i].ifname,
sizeof(l->listen_ifname));
if (slist_add(&newlist, l) == NULL) {
@@ -959,8 +866,8 @@ static void
pppoed_recv_PADI(pppoed_listener *_this, uint8_t shost[ETHER_ADDR_LEN],
slist *tag_list)
{
- int len, accept_any_service_req;
- const char *val, *service_name, *ac_name;
+ int len;
+ const char *service_name, *ac_name;
u_char bufspace[2048];
u_char sn[2048], ac_name0[40];
struct pppoe_header pppoe;
@@ -978,11 +885,8 @@ pppoed_recv_PADI(pppoed_listener *_this, uint8_t shost[ETHER_ADDR_LEN],
tlv_service_name = NULL;
service_name = "";
- if ((val = pppoed_listener_config_str(_this, "pppoe.service_name"))
- != NULL)
- service_name = val;
- accept_any_service_req = pppoed_listener_config_str_equal(_this,
- "pppoe.accept_any_service_request", "true", 1);
+ if (_this->conf->service_name != NULL)
+ service_name = _this->conf->service_name;
for (slist_itr_first(tag_list); slist_itr_has_next(tag_list);) {
tlv0 = slist_itr_next(tag_list);
@@ -998,7 +902,7 @@ pppoed_recv_PADI(pppoed_listener *_this, uint8_t shost[ETHER_ADDR_LEN],
sn[len] = '\0';
if (strcmp(service_name, sn) == 0 ||
- (sn[0] == '\0' && accept_any_service_req))
+ (sn[0] == '\0' && _this->conf->accept_any_service))
tlv_service_name = tlv0;
}
}
@@ -1042,7 +946,7 @@ pppoed_recv_PADI(pppoed_listener *_this, uint8_t shost[ETHER_ADDR_LEN],
/*
* Tag - Access Concentrator Name
*/
- ac_name = pppoed_listener_config_str(_this, "pppoe.ac_name");
+ ac_name = _this->conf->ac_name;
if (ac_name == NULL) {
/*
* use the ethernet address as default AC-Name.
diff --git a/usr.sbin/npppd/pptp/pptp.h b/usr.sbin/npppd/pptp/pptp.h
index 00cdb88a188..9fc786c8d28 100644
--- a/usr.sbin/npppd/pptp/pptp.h
+++ b/usr.sbin/npppd/pptp/pptp.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: pptp.h,v 1.7 2012/05/08 13:15:12 yasuoka Exp $ */
+/* $OpenBSD: pptp.h,v 1.8 2012/09/18 13:14:08 yasuoka Exp $ */
/*-
* Copyright (c) 2009 Internet Initiative Japan Inc.
@@ -141,6 +141,8 @@
/*
* Constants of the NPPPD implementation
*/
+#include "pptp_conf.h"
+
/* pptpd status */
#define PPTPD_STATE_INIT 0
#define PPTPD_STATE_RUNNING 1
@@ -230,7 +232,8 @@ typedef struct _pptpd_listener {
int sock_gre; /* GRE socket */
struct sockaddr_in bind_sin; /* listing TCP address */
struct sockaddr_in bind_sin_gre; /* listing GRE address */
- char phy_label[16];
+ char tun_name[PPTP_NAME_LEN];
+ struct pptp_conf *conf;
} pptpd_listener;
typedef struct _pptpd {
@@ -240,20 +243,12 @@ typedef struct _pptpd {
struct event ev_timer; /* timer event context */
slist ctrl_list; /* list of PPTP controls */
- struct properties *config;
-
slist call_free_list; /* Free call lists */
hash_table *call_id_map; /* table to map between callid and call */
/* ipv4 networks that is permitted to connect */
- struct in_addr_range *ip4_allow;
uint32_t /* flags */
- initialized:1,
- ctrl_in_pktdump:1,
- ctrl_out_pktdump:1,
- data_in_pktdump:1,
- data_out_pktdump:1,
- phy_label_with_ifname:1;
+ initialized:1;
} pptpd;
#define pptp_ctrl_sock_gre(ctrl) \
@@ -261,16 +256,19 @@ typedef struct _pptpd {
(ctrl)->listener_index))->sock_gre
/* get listner's physical layer label from pptp_ctrl */
-#define PPTP_CTRL_LISTENER_LABEL(ctrl) \
+#define PPTP_CTRL_LISTENER_TUN_NAME(ctrl) \
((pptpd_listener *)slist_get(&(ctrl)->pptpd->listener,\
- (ctrl)->listener_index))->phy_label
+ (ctrl)->listener_index))->tun_name
+
+#define PPTP_CTRL_CONF(ctrl) \
+ ((pptpd_listener *)slist_get(&(ctrl)->pptpd->listener, \
+ (ctrl)->listener_index))->conf
typedef struct _pptp_ctrl {
pptpd *pptpd; /* parents */
uint16_t listener_index;
unsigned id;
int state;
- char phy_label[16];
int sock;
struct sockaddr_storage peer;
@@ -336,7 +334,7 @@ int pptpd_start (pptpd *);
void pptpd_stop (pptpd *);
void pptpd_stop_immediatly (pptpd *);
void pptpd_ctrl_finished_notify(pptpd *, pptp_ctrl *);
-int pptpd_add_listener(pptpd *, int, const char *, struct sockaddr *);
+int pptpd_add_listener(pptpd *, int, struct pptp_conf *);
pptp_ctrl *pptp_ctrl_create (void);
int pptp_ctrl_init (pptp_ctrl *);
@@ -353,17 +351,7 @@ void pptp_call_destroy (pptp_call *);
void pptp_call_input (pptp_call *, int, u_char *, int);
void pptp_call_gre_input (pptp_call *, uint32_t, uint32_t, int, u_char *, int);
void pptp_call_disconnect(pptp_call *, int, int, const char *);
-int pptpd_reload(pptpd *, struct properties *, const char *, int);
-
-/* config_helper */
-const char *pptpd_config_str (pptpd *, const char *);
-int pptpd_config_int (pptpd *, const char *, int);
-int pptpd_config_str_equal (pptpd *, const char *, const char *, int);
-int pptpd_config_str_equali (pptpd *, const char *, const char *, int);
-const char *pptp_ctrl_config_str (pptp_ctrl *, const char *);
-int pptp_ctrl_config_int (pptp_ctrl *, const char *, int);
-int pptp_ctrl_config_str_equal (pptp_ctrl *, const char *, const char *, int);
-int pptp_ctrl_config_str_equali (pptp_ctrl *, const char *, const char *, int);
+int pptpd_reload(pptpd *, struct pptp_confs *);
#ifdef __cplusplus
}
diff --git a/usr.sbin/npppd/pptp/pptp_call.c b/usr.sbin/npppd/pptp/pptp_call.c
index 49587359b66..a9ff1276cbb 100644
--- a/usr.sbin/npppd/pptp/pptp_call.c
+++ b/usr.sbin/npppd/pptp/pptp_call.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pptp_call.c,v 1.6 2012/05/08 13:15:12 yasuoka Exp $ */
+/* $OpenBSD: pptp_call.c,v 1.7 2012/09/18 13:14:08 yasuoka Exp $ */
/*-
* Copyright (c) 2009 Internet Initiative Japan Inc.
@@ -25,7 +25,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
-/* $Id: pptp_call.c,v 1.6 2012/05/08 13:15:12 yasuoka Exp $ */
+/* $Id: pptp_call.c,v 1.7 2012/09/18 13:14:08 yasuoka Exp $ */
/**@file PPTP Call */
/* currently it supports PAC mode only */
#include <sys/types.h>
@@ -624,7 +624,8 @@ pptp_call_gre_output(pptp_call *_this, int fseq, int fack, u_char *pkt,
default:
return 1;
}
- if (_this->ctrl->pptpd->data_out_pktdump != 0) {
+
+ if (PPTP_CTRL_CONF(_this->ctrl)->data_out_pktdump != 0) {
pptp_call_log(_this, LOG_DEBUG, "PPTP Data output packet dump");
show_hd(debug_get_debugfp(), buf, opkt - buf);
}
@@ -743,11 +744,12 @@ pptp_call_bind_ppp(pptp_call *_this)
_this->ppp = ppp;
ppp->phy_context = _this;
- ppp->tunnel_type = PPP_TUNNEL_PPTP;
+ ppp->tunnel_type = NPPPD_TUNNEL_PPTP;
ppp->send_packet = pptp_call_ppp_output;
ppp->phy_close = pptp_call_closed_by_ppp;
- strlcpy(ppp->phy_label, _this->ctrl->phy_label, sizeof(ppp->phy_label));
+ strlcpy(ppp->phy_label, PPTP_CTRL_LISTENER_TUN_NAME(_this->ctrl),
+ sizeof(ppp->phy_label));
PPTP_CALL_ASSERT(sizeof(ppp->phy_info) >= _this->ctrl->peer.ss_len);
memcpy(&ppp->phy_info, &_this->ctrl->peer,
diff --git a/usr.sbin/npppd/pptp/pptp_conf.h b/usr.sbin/npppd/pptp/pptp_conf.h
new file mode 100644
index 00000000000..c9c0d6af2b4
--- /dev/null
+++ b/usr.sbin/npppd/pptp/pptp_conf.h
@@ -0,0 +1,45 @@
+/* $OpenBSD: pptp_conf.h,v 1.1 2012/09/18 13:14:08 yasuoka Exp $ */
+
+/*
+ * Copyright (c) 2012 YASUOKA Masahiko <yasuoka@openbsd.org>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+#ifndef PPTP_CONF_H
+#define PPTP_CONF_H 1
+
+#include <sys/types.h>
+#include <sys/queue.h>
+#include <sys/socket.h>
+
+#include <stdbool.h>
+
+#define PPTP_NAME_LEN 16
+
+TAILQ_HEAD(pptp_confs, pptp_conf);
+
+struct pptp_conf {
+ TAILQ_ENTRY(pptp_conf) entry;
+ char name[PPTP_NAME_LEN];
+ char *hostname;
+ char *vendor_name;
+ int echo_interval;
+ int echo_timeout;
+ struct sockaddr_storage address;
+ bool ctrl_in_pktdump;
+ bool ctrl_out_pktdump;
+ bool data_in_pktdump;
+ bool data_out_pktdump;
+};
+
+#endif
diff --git a/usr.sbin/npppd/pptp/pptp_ctrl.c b/usr.sbin/npppd/pptp/pptp_ctrl.c
index 8c555faf96c..a983b5051a1 100644
--- a/usr.sbin/npppd/pptp/pptp_ctrl.c
+++ b/usr.sbin/npppd/pptp/pptp_ctrl.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pptp_ctrl.c,v 1.6 2012/05/08 13:18:37 yasuoka Exp $ */
+/* $OpenBSD: pptp_ctrl.c,v 1.7 2012/09/18 13:14:08 yasuoka Exp $ */
/*-
* Copyright (c) 2009 Internet Initiative Japan Inc.
@@ -29,7 +29,7 @@
* PPTP(RFC 2637) control connection implementation.
* currently it only support PAC part
*/
-/* $Id: pptp_ctrl.c,v 1.6 2012/05/08 13:18:37 yasuoka Exp $ */
+/* $Id: pptp_ctrl.c,v 1.7 2012/09/18 13:14:08 yasuoka Exp $ */
#include <sys/types.h>
#include <sys/param.h>
#include <sys/socket.h>
@@ -529,7 +529,7 @@ pptp_ctrl_output_flush(pptp_ctrl *_this)
bytebuffer_flip(_this->send_buf);
- if (_this->pptpd->ctrl_out_pktdump != 0) {
+ if (PPTP_CTRL_CONF(_this)->ctrl_out_pktdump != 0) {
pptp_ctrl_log(_this, LOG_DEBUG, "PPTP Control output packet");
show_hd(debug_get_debugfp(),
bytebuffer_pointer(_this->send_buf),
@@ -746,14 +746,14 @@ pptp_ctrl_send_SCCRP(pptp_ctrl *_this, int result, int error)
/* this implementation only support these strings up to
* 63 character */
/* host name */
- if ((val = pptp_ctrl_config_str(_this, "pptp.host_name")) == NULL)
+
+ if (PPTP_CTRL_CONF(_this)->hostname == NULL)
val = "";
strlcpy(scc->host_name, val, sizeof(scc->host_name));
/* vender name */
- if ((val = pptp_ctrl_config_str(_this, "pptp.vendor_name")) == NULL)
+ if (PPTP_CTRL_CONF(_this)->vendor_name == NULL)
val = PPTPD_DEFAULT_VENDOR_NAME;
-
strlcpy(scc->vendor_string, val, sizeof(scc->vendor_string));
pptp_ctrl_SCCRx_string(scc, logbuf, sizeof(logbuf));
@@ -919,7 +919,7 @@ pptp_ctrl_input(pptp_ctrl *_this, u_char *pkt, int lpkt)
_this->last_rcv_ctrl = curr_time;
- if (_this->pptpd->ctrl_in_pktdump != 0) {
+ if (PPTP_CTRL_CONF(_this)->ctrl_in_pktdump != 0) {
pptp_ctrl_log(_this, LOG_DEBUG,
"PPTP Control input packet dump: mestype=%s(%d)",
pptp_ctrl_mes_type_string(hdr->control_message_type),
diff --git a/usr.sbin/npppd/pptp/pptpd.c b/usr.sbin/npppd/pptp/pptpd.c
index cb5b86bf78f..e685a2cfd1a 100644
--- a/usr.sbin/npppd/pptp/pptpd.c
+++ b/usr.sbin/npppd/pptp/pptpd.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pptpd.c,v 1.10 2012/05/08 13:15:12 yasuoka Exp $ */
+/* $OpenBSD: pptpd.c,v 1.11 2012/09/18 13:14:08 yasuoka Exp $ */
/*-
* Copyright (c) 2009 Internet Initiative Japan Inc.
@@ -25,12 +25,12 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
-/* $Id: pptpd.c,v 1.10 2012/05/08 13:15:12 yasuoka Exp $ */
+/* $Id: pptpd.c,v 1.11 2012/09/18 13:14:08 yasuoka Exp $ */
/**@file
* This file provides a implementation of PPTP daemon. Currently it
* provides functions for PAC (PPTP Access Concentrator) only.
- * $Id: pptpd.c,v 1.10 2012/05/08 13:15:12 yasuoka Exp $
+ * $Id: pptpd.c,v 1.11 2012/09/18 13:14:08 yasuoka Exp $
*/
#include <sys/types.h>
#include <sys/param.h>
@@ -64,8 +64,6 @@
#include "hash.h"
#include "slist.h"
#include "addr_range.h"
-#include "properties.h"
-#include "config_helper.h"
#include "pptp.h"
#include "pptp_local.h"
@@ -99,23 +97,11 @@ int
pptpd_init(pptpd *_this)
{
int i, m;
- struct sockaddr_in sin0;
uint16_t call0, call[UINT16_MAX - 1];
memset(_this, 0, sizeof(pptpd));
_this->id = pptpd_seqno++;
- slist_init(&_this->listener);
- memset(&sin0, 0, sizeof(sin0));
- sin0.sin_len = sizeof(sin0);
- sin0.sin_family = AF_INET;
- if (pptpd_add_listener(_this, 0, PPTPD_DEFAULT_LAYER2_LABEL,
- (struct sockaddr *)&sin0) != 0) {
- return 1;
- }
-
- _this->ip4_allow = NULL;
-
slist_init(&_this->ctrl_list);
slist_init(&_this->call_free_list);
@@ -142,8 +128,7 @@ pptpd_init(pptpd *_this)
/* add a listner to pptpd daemon context */
int
-pptpd_add_listener(pptpd *_this, int idx, const char *label,
- struct sockaddr *bindaddr)
+pptpd_add_listener(pptpd *_this, int idx, struct pptp_conf *conf)
{
int inaddr_any;
pptpd_listener *plistener, *plstn;
@@ -174,9 +159,10 @@ pptpd_add_listener(pptpd *_this, int idx, const char *label,
}
memset(plistener, 0, sizeof(pptpd_listener));
- PPTPD_ASSERT(sizeof(plistener->bind_sin) >= bindaddr->sa_len);
- memcpy(&plistener->bind_sin, bindaddr, bindaddr->sa_len);
- memcpy(&plistener->bind_sin_gre, bindaddr, bindaddr->sa_len);
+ PPTPD_ASSERT(sizeof(plistener->bind_sin) >= conf->address.ss_len);
+ memcpy(&plistener->bind_sin, &conf->address, conf->address.ss_len);
+ memcpy(&plistener->bind_sin_gre, &conf->address,
+ conf->address.ss_len);
if (plistener->bind_sin.sin_port == 0)
plistener->bind_sin.sin_port = htons(PPTPD_DEFAULT_TCP_PORT);
@@ -205,7 +191,8 @@ pptpd_add_listener(pptpd *_this, int idx, const char *label,
plistener->sock_gre = -1;
plistener->self = _this;
plistener->index = idx;
- strlcpy(plistener->phy_label, label, sizeof(plistener->phy_label));
+ plistener->conf = conf;
+ strlcpy(plistener->tun_name, conf->name, sizeof(plistener->tun_name));
if (slist_add(&_this->listener, plistener) == NULL) {
pptpd_log(_this, LOG_ERR, "slist_add() failed in %s: %m",
@@ -236,13 +223,9 @@ pptpd_uninit(pptpd *_this)
free(plstn);
}
slist_fini(&_this->listener);
- if (_this->call_id_map != NULL) {
+ if (_this->call_id_map != NULL)
hash_free(_this->call_id_map);
- }
- if (_this->ip4_allow != NULL)
- in_addr_range_list_remove_all(&_this->ip4_allow);
_this->call_id_map = NULL;
- _this->config = NULL;
}
#define CALL_ID_KEY(call_id, listener_idx) \
@@ -309,9 +292,6 @@ pptpd_listener_start(pptpd_listener *_this)
memcpy(&bind_sin, &_this->bind_sin, sizeof(bind_sin));
memcpy(&bind_sin_gre, &_this->bind_sin_gre, sizeof(bind_sin_gre));
- if (_this->phy_label[0] == '\0')
- strlcpy(_this->phy_label, PPTPD_DEFAULT_LAYER2_LABEL,
- sizeof(_this->phy_label));
if ((sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) {
pptpd_log(_this->self, LOG_ERR, "socket() failed at %s(): %m",
__func__);
@@ -363,7 +343,7 @@ pptpd_listener_start(pptpd_listener *_this)
#endif
pptpd_log(_this->self, LOG_INFO, "Listening %s:%u/tcp (PPTP PAC) [%s]",
inet_ntoa(_this->bind_sin.sin_addr),
- ntohs(_this->bind_sin.sin_port), _this->phy_label);
+ ntohs(_this->bind_sin.sin_port), _this->tun_name);
/* GRE */
bind_sin_gre.sin_port = 0;
@@ -591,156 +571,46 @@ pptpd_stop(pptpd *_this)
/*
* PPTP Configuration
*/
-#define CFG_KEY(p, s) config_key_prefix((p), (s))
-#define VAL_SEP " \t\r\n"
-
-CONFIG_FUNCTIONS(pptpd_config, pptpd, config);
-PREFIXED_CONFIG_FUNCTIONS(pptp_ctrl_config, pptp_ctrl, pptpd->config,
- phy_label);
int
-pptpd_reload(pptpd *_this, struct properties *config, const char *name,
- int default_enabled)
+pptpd_reload(pptpd *_this, struct pptp_confs *pptp_conf)
{
- int i, do_start, aierr;
- const char *val;
- char *tok, *cp, buf[PPTPD_CONFIG_BUFSIZ], *label;
- struct addrinfo *ai;
-
- ASSERT(_this != NULL);
- ASSERT(config != NULL);
-
- _this->config = config;
- do_start = 0;
- if (pptpd_config_str_equal(_this, CFG_KEY(name, "enabled"), "true",
- default_enabled)) {
- /* avoid false-true flap */
- if (pptpd_is_shutting_down(_this))
- pptpd_stop_immediatly(_this);
- if (pptpd_is_stopped(_this))
- do_start = 1;
- } else {
- if (!pptpd_is_stopped(_this))
- pptpd_stop(_this);
- return 0;
- }
- if (do_start && pptpd_init(_this) != 0)
- return 1;
- /* set again as pptpd_init will reset it */
- _this->config = config;
-
- _this->ctrl_in_pktdump = pptpd_config_str_equal(_this,
- "log.pptp.ctrl.in.pktdump", "true", 0);
- _this->data_in_pktdump = pptpd_config_str_equal(_this,
- "log.pptp.data.in.pktdump", "true", 0);
- _this->ctrl_out_pktdump = pptpd_config_str_equal(_this,
- "log.pptp.ctrl.out.pktdump", "true", 0);
- _this->data_out_pktdump = pptpd_config_str_equal(_this,
- "log.pptp.data.out.pktdump", "true", 0);
- _this->phy_label_with_ifname = pptpd_config_str_equal(_this,
- CFG_KEY(name, "label_with_ifname"), "true", 0);
-
- /* parse ip4_allow */
- in_addr_range_list_remove_all(&_this->ip4_allow);
- val = pptpd_config_str(_this, CFG_KEY(name, "ip4_allow"));
- if (val != NULL) {
- if (strlen(val) >= sizeof(buf)) {
- log_printf(LOG_ERR, "configuration error at "
- "%s: too long", CFG_KEY(name, "ip4_allow"));
- return 1;
- }
- strlcpy(buf, val, sizeof(buf));
- for (cp = buf; (tok = strsep(&cp, VAL_SEP)) != NULL;) {
- if (*tok == '\0')
- continue;
- if (in_addr_range_list_add(&_this->ip4_allow, tok)
- != 0) {
- pptpd_log(_this, LOG_ERR,
- "configuration error at %s: %s",
- CFG_KEY(name, "ip4_allow"), tok);
- return 1;
- }
- }
- }
-
- if (do_start) {
- /* in the case of 1) cold-booted and 2) pptpd.enable
- * toggled "false" to "true" do this, because we can
- * assume that all pptpd listner are initialized. */
-
- val = pptpd_config_str(_this, CFG_KEY(name, "listener_in"));
- if (val != NULL) {
- if (strlen(val) >= sizeof(buf)) {
- pptpd_log(_this, LOG_ERR,
- "configuration error at "
- "%s: too long", CFG_KEY(name, "listener"));
- return 1;
- }
- strlcpy(buf, val, sizeof(buf));
-
- label = NULL;
- /* it can accept multple velues with tab/space
- * separation */
- for (i = 0, cp = buf;
- (tok = strsep(&cp, VAL_SEP)) != NULL;) {
- if (*tok == '\0')
- continue;
- if (label == NULL) {
- label = tok;
- continue;
- }
- if ((aierr = addrport_parse(tok, IPPROTO_TCP,
- &ai)) != 0) {
- pptpd_log(_this, LOG_ERR,
- "configuration error at "
- "%s: %s: %s",
- CFG_KEY(name, "listener_in"), tok,
- gai_strerror(aierr));
- return 1;
- }
- PPTPD_ASSERT(ai != NULL &&
- ai->ai_family == AF_INET);
- if (pptpd_add_listener(_this, i, label,
- ai->ai_addr) != 0) {
- freeaddrinfo(ai);
- label = NULL;
+ int i;
+ struct pptp_conf *conf;
+ pptpd_listener *listener;
+
+ if (slist_length(&_this->listener) > 0) {
+ /*
+ * TODO: add / remove / restart listener.
+ */
+ slist_itr_first(&_this->listener);
+ while (slist_itr_has_next(&_this->listener)) {
+ listener = slist_itr_next(&_this->listener);
+ TAILQ_FOREACH(conf, pptp_conf, entry) {
+ if (strcmp(listener->tun_name,
+ conf->name) == 0) {
+ listener->conf = conf;
break;
}
- freeaddrinfo(ai);
- label = NULL;
- i++;
- }
- if (label != NULL) {
- pptpd_log(_this, LOG_ERR,
- "configuration error at %s: %s",
- CFG_KEY(name, "listner_in"), label);
- return 1;
}
}
- if (pptpd_start(_this) != 0)
- return 1;
+
+ return 0;
}
+ if (pptpd_init(_this) != 0)
+ return -1;
+ i = 0;
+ TAILQ_FOREACH(conf, pptp_conf, entry)
+ pptpd_add_listener(_this, i++, conf);
+ if (pptpd_start(_this) != 0)
+ return -1;
+
return 0;
}
/*
* I/O functions
*/
-static void
-pptpd_log_access_deny(pptpd *_this, const char *reason, struct sockaddr *peer)
-{
- char hostbuf[NI_MAXHOST], servbuf[NI_MAXSERV];
-
- if (getnameinfo(peer, peer->sa_len, hostbuf, sizeof(hostbuf),
- servbuf, sizeof(servbuf), NI_NUMERICHOST | NI_NUMERICSERV) != 0) {
- pptpd_log(_this, LOG_ERR, "getnameinfo() failed at %s(): %m",
- __func__);
- return;
- }
- pptpd_log(_this, LOG_ALERT, "denied a connection from %s:%s/tcp: %s",
- hostbuf, servbuf, reason);
-}
-
/* I/O event handler of 1723/tcp */
static void
pptpd_io_event(int fd, short evmask, void *ctx)
@@ -783,27 +653,13 @@ pptpd_io_event(int fd, short evmask, void *ctx)
/* check peer */
switch (peer.ss_family) {
case AF_INET:
- if (!in_addr_range_list_includes(
- &_this->ip4_allow,
- &((struct sockaddr_in *)&peer)->sin_addr)) {
- reason = "not allowed by acl.";
- break;
- }
- goto accept;
+ pptp_ctrl_start_by_pptpd(_this, newsock,
+ listener->index, (struct sockaddr *)&peer);
+ break;
default:
reason = "address family is not supported.";
break;
}
- /* not permitted */
- pptpd_log_access_deny(_this, reason,
- (struct sockaddr *)&peer);
- close(newsock);
- continue;
- /* NOTREACHED */
-accept:
- /* permitted, can accepted */
- pptp_ctrl_start_by_pptpd(_this, newsock,
- listener->index, (struct sockaddr *)&peer);
}
}
}
@@ -874,7 +730,7 @@ pptpd_gre_input(pptpd_listener *listener, struct sockaddr *peer, u_char *pkt,
"getnameinfo() failed at %s(): %m", __func__);
goto fail;
}
- if (_this->data_in_pktdump != 0) {
+ if (listener->conf->data_in_pktdump != 0) {
pptpd_log(_this, LOG_DEBUG, "PPTP Data input packet dump");
show_hd(debug_get_debugfp(), pkt, lpkt);
}
@@ -976,10 +832,8 @@ static void
pptp_ctrl_start_by_pptpd(pptpd *_this, int sock, int listener_index,
struct sockaddr *peer)
{
- int ival;
pptp_ctrl *ctrl;
- socklen_t sslen;
- char ifname[IF_NAMESIZE], msgbuf[128];
+ socklen_t sslen;
ctrl = NULL;
if ((ctrl = pptp_ctrl_create()) == NULL)
@@ -1001,38 +855,10 @@ pptp_ctrl_start_by_pptpd(pptpd *_this, int sock, int listener_index,
goto fail;
}
- /* change with interface name, ex) "L2TP%em0.mru" */
- if (_this->phy_label_with_ifname != 0) {
- if (get_ifname_by_sockaddr((struct sockaddr *)&ctrl->our,
- ifname) == NULL) {
- pptpd_log_access_deny(_this,
- "could not get interface informations", peer);
- goto fail;
- }
- if (pptpd_config_str_equal(_this,
- config_key_prefix("pptpd.interface", ifname), "accept", 0)){
- snprintf(ctrl->phy_label, sizeof(ctrl->phy_label),
- "%s%%%s", PPTP_CTRL_LISTENER_LABEL(ctrl), ifname);
- } else if (pptpd_config_str_equal(_this,
- config_key_prefix("pptpd.interface", "any"), "accept", 0)){
- snprintf(ctrl->phy_label, sizeof(ctrl->phy_label),
- "%s", PPTP_CTRL_LISTENER_LABEL(ctrl));
- } else {
- /* the interface is not permitted */
- snprintf(msgbuf, sizeof(msgbuf),
- "'%s' is not allowed by config.", ifname);
- pptpd_log_access_deny(_this, msgbuf, peer);
- goto fail;
- }
- } else
- strlcpy(ctrl->phy_label, PPTP_CTRL_LISTENER_LABEL(ctrl),
- sizeof(ctrl->phy_label));
-
- if ((ival = pptp_ctrl_config_int(ctrl, "pptp.echo_interval", 0)) != 0)
- ctrl->echo_interval = ival;
-
- if ((ival = pptp_ctrl_config_int(ctrl, "pptp.echo_timeout", 0)) != 0)
- ctrl->echo_timeout = ival;
+ if (PPTP_CTRL_CONF(ctrl)->echo_interval != 0)
+ ctrl->echo_interval = PPTP_CTRL_CONF(ctrl)->echo_interval;
+ if (PPTP_CTRL_CONF(ctrl)->echo_timeout != 0)
+ ctrl->echo_timeout = PPTP_CTRL_CONF(ctrl)->echo_timeout;
if (pptp_ctrl_start(ctrl) != 0)
goto fail;