You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

1270 lines
40 KiB

# --- SDE-COPYRIGHT-NOTE-BEGIN ---
# This copyright note is auto-generated by ./scripts/Create-CopyPatch.
#
# Filename: package/.../ppp/ppp-2.4.5-upstream-git-fixes-20110911.patch
# Copyright (C) 2011 The OpenSDE Project
#
# More information can be found in the files COPYING and README.
#
# This patch file is dual-licensed. It is available under the license the
# patched project is licensed under, as long as it is an OpenSource license
# as defined at http://www.opensource.org/ (e.g. BSD, X11) or under the terms
# of the GNU General Public License as published by the Free Software
# Foundation; either version 2 of the License, or (at your option) any later
# version.
# --- SDE-COPYRIGHT-NOTE-END ---
From e7537958aee79b3f653c601e903cb31d78fb7dcc Mon Sep 17 00:00:00 2001
From: Ludwig Nussel <ludwig.nussel@suse.de>
Date: Tue, 9 Feb 2010 17:32:15 +0100
Subject: [PATCH 1/9] Document +ipv6 and ipv6cp-accept-local
Signed-off-by: Ludwig Nussel <ludwig.nussel@suse.de>
Signed-off-by: Paul Mackerras <paulus@samba.org>
---
pppd/pppd.8 | 8 ++++++++
1 files changed, 8 insertions(+), 0 deletions(-)
diff --git ppp-2.4.5-release/pppd/pppd.8 ppp-2.4.5/pppd/pppd.8
index 8ea8200..b7adc77 100644
--- ppp-2.4.5-release/pppd/pppd.8
+++ ppp-2.4.5/pppd/pppd.8
@@ -193,6 +193,9 @@ will not accept a different value from the peer in the IPCP
negotiation, unless the \fIipcp\-accept\-local\fR and/or
\fIipcp\-accept\-remote\fR options are given, respectively.
.TP
+.B +ipv6
+Enable the IPv6CP and IPv6 protocols.
+.TP
.B ipv6 \fI<local_interface_identifier>\fR,\fI<remote_interface_identifier>
Set the local and/or remote 64-bit interface identifier. Either one may be
omitted. The identifier must be specified in standard ascii notation of
@@ -449,6 +452,11 @@ scripts. If this
option is given, the \fIstring\fR supplied is given as the 6th
parameter to those scripts.
.TP
+.B ipv6cp\-accept\-local
+With this option, pppd will accept the peer's idea of our local IPv6
+interface identifier, even if the local IPv6 interface identifier
+was specified in an option.
+.TP
.B ipv6cp\-max\-configure \fIn
Set the maximum number of IPv6CP configure-request transmissions to
\fIn\fR (default 10).
--
1.6.6.2
From 406215672cfadc03017341fe03802d1c7294b903 Mon Sep 17 00:00:00 2001
From: Ludwig Nussel <ludwig.nussel@suse.de>
Date: Tue, 9 Feb 2010 17:32:16 +0100
Subject: [PATCH 2/9] Install pppol2tp plugins with sane permissions
Signed-off-by: Ludwig Nussel <ludwig.nussel@suse.de>
Signed-off-by: Paul Mackerras <paulus@samba.org>
---
pppd/plugins/pppol2tp/Makefile.linux | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git ppp-2.4.5-release/pppd/plugins/pppol2tp/Makefile.linux ppp-2.4.5/pppd/plugins/pppol2tp/Makefile.linux
index 19eff67..ea3538e 100644
--- ppp-2.4.5-release/pppd/plugins/pppol2tp/Makefile.linux
+++ ppp-2.4.5/pppd/plugins/pppol2tp/Makefile.linux
@@ -20,7 +20,7 @@ all: $(PLUGINS)
install: all
$(INSTALL) -d -m 755 $(LIBDIR)
- $(INSTALL) -c -m 4550 $(PLUGINS) $(LIBDIR)
+ $(INSTALL) -c -m 755 $(PLUGINS) $(LIBDIR)
clean:
rm -f *.o *.so
--
1.6.6.2
From 3eb9e810cfa515543655659b72dde30c54fea0a5 Mon Sep 17 00:00:00 2001
From: Paul Mackerras <paulus@samba.org>
Date: Sun, 7 Mar 2010 15:21:38 +1100
Subject: [PATCH 3/9] pppd: Terminate correctly if lcp_lowerup delayed calling fsm_lowerup
Cameron Hutchison noticed that if pppd gets asked to terminate the
link in the period between when lcp_lowerup() is called and when
fsm_lowerup() is called from lcp_delayed_up() (i.e. when listen_time
is non-zero), pppd never exits.
The reason is that lcp_close() doesn't handle the delayed-up case
properly. Since the FSM is still in STOPPED state, we don't call
lcp_finished() and therefore never exit the main event loop.
This fixes it by handling the delayed-up case in lcp_close() as if
we had done the lowerup but the OPT_SILENT bit was set. We use the
silent case because we don't want to actually send a configure-request
at this point.
Signed-off-by: Paul Mackerras <paulus@samba.org>
---
pppd/lcp.c | 28 +++++++++++++++++++---------
1 files changed, 19 insertions(+), 9 deletions(-)
diff --git ppp-2.4.5-release/pppd/lcp.c ppp-2.4.5/pppd/lcp.c
index 5c77490..8ed2778 100644
--- ppp-2.4.5-release/pppd/lcp.c
+++ ppp-2.4.5/pppd/lcp.c
@@ -397,21 +397,29 @@ lcp_close(unit, reason)
char *reason;
{
fsm *f = &lcp_fsm[unit];
+ int oldstate;
if (phase != PHASE_DEAD && phase != PHASE_MASTER)
new_phase(PHASE_TERMINATE);
- if (f->state == STOPPED && f->flags & (OPT_PASSIVE|OPT_SILENT)) {
+
+ if (f->flags & DELAYED_UP) {
+ untimeout(lcp_delayed_up, f);
+ f->state = STOPPED;
+ }
+ oldstate = f->state;
+
+ fsm_close(f, reason);
+ if (oldstate == STOPPED && f->flags & (OPT_PASSIVE|OPT_SILENT|DELAYED_UP)) {
/*
* This action is not strictly according to the FSM in RFC1548,
* but it does mean that the program terminates if you do a
- * lcp_close() in passive/silent mode when a connection hasn't
- * been established.
+ * lcp_close() when a connection hasn't been established
+ * because we are in passive/silent mode or because we have
+ * delayed the fsm_lowerup() call and it hasn't happened yet.
*/
- f->state = CLOSED;
+ f->flags &= ~DELAYED_UP;
lcp_finished(f);
-
- } else
- fsm_close(f, reason);
+ }
}
@@ -453,9 +461,10 @@ lcp_lowerdown(unit)
{
fsm *f = &lcp_fsm[unit];
- if (f->flags & DELAYED_UP)
+ if (f->flags & DELAYED_UP) {
f->flags &= ~DELAYED_UP;
- else
+ untimeout(lcp_delayed_up, f);
+ } else
fsm_lowerdown(&lcp_fsm[unit]);
}
@@ -489,6 +498,7 @@ lcp_input(unit, p, len)
if (f->flags & DELAYED_UP) {
f->flags &= ~DELAYED_UP;
+ untimeout(lcp_delayed_up, f);
fsm_lowerup(f);
}
fsm_input(f, p, len);
--
1.6.6.2
From cab58617fd9d328029fffabc788020264b4fa91f Mon Sep 17 00:00:00 2001
From: Paul Mackerras <paulus@samba.org>
Date: Sun, 7 Mar 2010 16:54:00 +1100
Subject: [PATCH 4/9] rp_pppoe: Copy acName and pppd_pppoe_service after option parsing
At present, the access concentrator name (acName) and service name
(pppd_pppoe_service) are set by option parsing, but are used at the
point of PPPOEInitDevice(), which gets called when the ethernet
device name is seen. So if the rp_pppoe_service or rp_pppoe_ac
options appear after the device name, they are ignored.
This fixes it by using acName and pppd_pppoe_service in
PPPOEConnectDevice, which gets called after all options have been
parsed.
Signed-off-by: Paul Mackerras <paulus@samba.org>
---
pppd/plugins/rp-pppoe/plugin.c | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git ppp-2.4.5-release/pppd/plugins/rp-pppoe/plugin.c ppp-2.4.5/pppd/plugins/rp-pppoe/plugin.c
index e94494b..9bd6643 100644
--- ppp-2.4.5-release/pppd/plugins/rp-pppoe/plugin.c
+++ ppp-2.4.5/pppd/plugins/rp-pppoe/plugin.c
@@ -108,8 +108,6 @@ PPPOEInitDevice(void)
novm("PPPoE session data");
}
memset(conn, 0, sizeof(PPPoEConnection));
- conn->acName = acName;
- conn->serviceName = pppd_pppoe_service;
conn->ifName = devnam;
conn->discoverySocket = -1;
conn->sessionSocket = -1;
@@ -133,6 +131,8 @@ PPPOEConnectDevice(void)
{
struct sockaddr_pppox sp;
+ conn->acName = acName;
+ conn->serviceName = pppd_pppoe_service;
strlcpy(ppp_devnam, devnam, sizeof(ppp_devnam));
if (existingSession) {
unsigned int mac[ETH_ALEN];
--
1.6.6.2
From 2b6310fd24dba8e0fca8999916a162f0a1842a84 Mon Sep 17 00:00:00 2001
From: James Carlson <carlsonj@workingcode.com>
Date: Mon, 23 Aug 2010 09:59:56 -0400
Subject: [PATCH 5/9] Add set and reset options to control environment variables for scripts.
---
pppd/main.c | 111 +++++++++++++++++++++++++++++------
pppd/options.c | 179 +++++++++++++++++++++++++++++++++++++++++++++++++++++---
pppd/pppd.8 | 14 +++++
pppd/pppd.h | 27 +++++++--
pppd/utils.c | 7 +-
5 files changed, 302 insertions(+), 36 deletions(-)
diff --git ppp-2.4.5-release/pppd/main.c ppp-2.4.5/pppd/main.c
index 014d614..1b513ca 100644
--- ppp-2.4.5-release/pppd/main.c
+++ ppp-2.4.5/pppd/main.c
@@ -1615,6 +1615,52 @@ safe_fork(int infd, int outfd, int errfd)
return 0;
}
+static bool
+add_script_env(pos, newstring)
+ int pos;
+ char *newstring;
+{
+ if (pos + 1 >= s_env_nalloc) {
+ int new_n = pos + 17;
+ char **newenv = realloc(script_env, new_n * sizeof(char *));
+ if (newenv == NULL) {
+ free(newstring - 1);
+ return 0;
+ }
+ script_env = newenv;
+ s_env_nalloc = new_n;
+ }
+ script_env[pos] = newstring;
+ script_env[pos + 1] = NULL;
+ return 1;
+}
+
+static void
+remove_script_env(pos)
+ int pos;
+{
+ free(script_env[pos] - 1);
+ while ((script_env[pos] = script_env[pos + 1]) != NULL)
+ pos++;
+}
+
+/*
+ * update_system_environment - process the list of set/unset options
+ * and update the system environment.
+ */
+static void
+update_system_environment()
+{
+ struct userenv *uep;
+
+ for (uep = userenv_list; uep != NULL; uep = uep->ue_next) {
+ if (uep->ue_isset)
+ setenv(uep->ue_name, uep->ue_value, 1);
+ else
+ unsetenv(uep->ue_name);
+ }
+}
+
/*
* device_script - run a program to talk to the specified fds
* (e.g. to run the connector or disconnector script).
@@ -1670,6 +1716,7 @@ device_script(program, in, out, dont_wait)
fprintf(stderr, "pppd: setuid failed\n");
exit(1);
}
+ update_system_environment();
execl("/bin/sh", "sh", "-c", program, (char *)0);
perror("pppd: could not exec /bin/sh");
exit(99);
@@ -1678,6 +1725,44 @@ device_script(program, in, out, dont_wait)
/*
+ * update_script_environment - process the list of set/unset options
+ * and update the script environment. Note that we intentionally do
+ * not update the TDB. These changes are layered on top right before
+ * exec. It is not possible to use script_setenv() or
+ * script_unsetenv() safely after this routine is run.
+ */
+static void
+update_script_environment()
+{
+ struct userenv *uep;
+
+ for (uep = userenv_list; uep != NULL; uep = uep->ue_next) {
+ int i;
+ char *p, *newstring;
+ int nlen = strlen(uep->ue_name);
+
+ for (i = 0; (p = script_env[i]) != NULL; i++) {
+ if (strncmp(p, uep->ue_name, nlen) == 0 && p[nlen] == '=')
+ break;
+ }
+ if (uep->ue_isset) {
+ nlen += strlen(uep->ue_value) + 2;
+ newstring = malloc(nlen + 1);
+ if (newstring == NULL)
+ continue;
+ *newstring++ = 0;
+ slprintf(newstring, nlen, "%s=%s", uep->ue_name, uep->ue_value);
+ if (p != NULL)
+ script_env[i] = newstring;
+ else
+ add_script_env(i, newstring);
+ } else {
+ remove_script_env(i);
+ }
+ }
+}
+
+/*
* run_program - execute a program with given arguments,
* but don't wait for it unless wait is non-zero.
* If the program can't be executed, logs an error unless
@@ -1747,6 +1832,7 @@ run_program(prog, args, must_exist, done, arg, wait)
#endif
/* run the program */
+ update_script_environment();
execve(prog, args, script_env);
if (must_exist || errno != ENOENT) {
/* have to reopen the log, there's nowhere else
@@ -1967,25 +2053,16 @@ script_setenv(var, value, iskey)
} else {
/* no space allocated for script env. ptrs. yet */
i = 0;
- script_env = (char **) malloc(16 * sizeof(char *));
- if (script_env == 0)
+ script_env = malloc(16 * sizeof(char *));
+ if (script_env == 0) {
+ free(newstring - 1);
return;
+ }
s_env_nalloc = 16;
}
- /* reallocate script_env with more space if needed */
- if (i + 1 >= s_env_nalloc) {
- int new_n = i + 17;
- char **newenv = (char **) realloc((void *)script_env,
- new_n * sizeof(char *));
- if (newenv == 0)
- return;
- script_env = newenv;
- s_env_nalloc = new_n;
- }
-
- script_env[i] = newstring;
- script_env[i+1] = 0;
+ if (!add_script_env(i, newstring))
+ return;
#ifdef USE_TDB
if (pppdb != NULL) {
@@ -2016,9 +2093,7 @@ script_unsetenv(var)
if (p[-1] && pppdb != NULL)
delete_db_key(p);
#endif
- free(p-1);
- while ((script_env[i] = script_env[i+1]) != 0)
- ++i;
+ remove_script_env(i);
break;
}
}
diff --git ppp-2.4.5-release/pppd/options.c ppp-2.4.5/pppd/options.c
index 482eab9..434ab95 100644
--- ppp-2.4.5-release/pppd/options.c
+++ ppp-2.4.5/pppd/options.c
@@ -119,6 +119,7 @@ bool dump_options; /* print out option values */
bool dryrun; /* print out option values and exit */
char *domain; /* domain name set by domain option */
int child_wait = 5; /* # seconds to wait for children at exit */
+struct userenv *userenv_list; /* user environment variables */
#ifdef MAXOCTETS
unsigned int maxoctets = 0; /* default - no limit */
@@ -135,6 +136,7 @@ struct bpf_program pass_filter;/* Filter program for packets to pass */
struct bpf_program active_filter; /* Filter program for link-active pkts */
#endif
+static option_t *curopt; /* pointer to option being processed */
char *current_option; /* the name of the option being parsed */
int privileged_option; /* set iff the current option came from root */
char *option_source; /* string saying where the option came from */
@@ -167,6 +169,11 @@ static int setactivefilter __P((char **));
static int setmodir __P((char **));
#endif
+static int user_setenv __P((char **));
+static void user_setprint __P((option_t *, printer_func, void *));
+static int user_unsetenv __P((char **));
+static void user_unsetprint __P((option_t *, printer_func, void *));
+
static option_t *find_option __P((const char *name));
static int process_option __P((option_t *, char *, char **));
static int n_arguments __P((option_t *));
@@ -281,6 +288,13 @@ option_t general_options[] = {
"Number of seconds to wait for child processes at exit",
OPT_PRIO },
+ { "set", o_special, (void *)user_setenv,
+ "Set user environment variable",
+ OPT_A2PRINTER | OPT_NOPRINT, (void *)user_setprint },
+ { "unset", o_special, (void *)user_unsetenv,
+ "Unset user environment variable",
+ OPT_A2PRINTER | OPT_NOPRINT, (void *)user_unsetprint },
+
#ifdef HAVE_MULTILINK
{ "multilink", o_bool, &multilink,
"Enable multilink operation", OPT_PRIO | 1 },
@@ -768,6 +782,7 @@ process_option(opt, cmd, argv)
case o_special_noarg:
case o_special:
parser = (int (*) __P((char **))) opt->addr;
+ curopt = opt;
if (!(*parser)(argv))
return 0;
if (opt->flags & OPT_A2LIST) {
@@ -881,7 +896,7 @@ check_options()
static void
print_option(opt, mainopt, printer, arg)
option_t *opt, *mainopt;
- void (*printer) __P((void *, char *, ...));
+ printer_func printer;
void *arg;
{
int i, v;
@@ -944,11 +959,8 @@ print_option(opt, mainopt, printer, arg)
printer(arg, " ");
}
if (opt->flags & OPT_A2PRINTER) {
- void (*oprt) __P((option_t *,
- void ((*)__P((void *, char *, ...))),
- void *));
- oprt = (void (*) __P((option_t *,
- void ((*)__P((void *, char *, ...))),
+ void (*oprt) __P((option_t *, printer_func, void *));
+ oprt = (void (*) __P((option_t *, printer_func,
void *)))opt->addr2;
(*oprt)(opt, printer, arg);
} else if (opt->flags & OPT_A2STRVAL) {
@@ -986,7 +998,7 @@ print_option(opt, mainopt, printer, arg)
static void
print_option_list(opt, printer, arg)
option_t *opt;
- void (*printer) __P((void *, char *, ...));
+ printer_func printer;
void *arg;
{
while (opt->name != NULL) {
@@ -1004,7 +1016,7 @@ print_option_list(opt, printer, arg)
*/
void
print_options(printer, arg)
- void (*printer) __P((void *, char *, ...));
+ printer_func printer;
void *arg;
{
struct option_list *list;
@@ -1623,3 +1635,154 @@ loadplugin(argv)
return 0;
}
#endif /* PLUGIN */
+
+/*
+ * Set an environment variable specified by the user.
+ */
+static int
+user_setenv(argv)
+ char **argv;
+{
+ char *arg = argv[0];
+ char *eqp;
+ struct userenv *uep, **insp;
+
+ if ((eqp = strchr(arg, '=')) == NULL) {
+ option_error("missing = in name=value: %s", arg);
+ return 0;
+ }
+ if (eqp == arg) {
+ option_error("missing variable name: %s", arg);
+ return 0;
+ }
+ for (uep = userenv_list; uep != NULL; uep = uep->ue_next) {
+ int nlen = strlen(uep->ue_name);
+ if (nlen == (eqp - arg) &&
+ strncmp(arg, uep->ue_name, nlen) == 0)
+ break;
+ }
+ /* Ignore attempts by unprivileged users to override privileged sources */
+ if (uep != NULL && !privileged_option && uep->ue_priv)
+ return 1;
+ /* The name never changes, so allocate it with the structure */
+ if (uep == NULL) {
+ uep = malloc(sizeof (*uep) + (eqp-arg));
+ strncpy(uep->ue_name, arg, eqp-arg);
+ uep->ue_name[eqp-arg] = '\0';
+ uep->ue_next = NULL;
+ insp = &userenv_list;
+ while (*insp != NULL)
+ insp = &(*insp)->ue_next;
+ *insp = uep;
+ } else {
+ struct userenv *uep2;
+ for (uep2 = userenv_list; uep2 != NULL; uep2 = uep2->ue_next) {
+ if (uep2 != uep && !uep2->ue_isset)
+ break;
+ }
+ if (uep2 == NULL && !uep->ue_isset)
+ find_option("unset")->flags |= OPT_NOPRINT;
+ free(uep->ue_value);
+ }
+ uep->ue_isset = 1;
+ uep->ue_priv = privileged_option;
+ uep->ue_source = option_source;
+ uep->ue_value = strdup(eqp + 1);
+ curopt->flags &= ~OPT_NOPRINT;
+ return 1;
+}
+
+static void
+user_setprint(opt, printer, arg)
+ option_t *opt;
+ printer_func printer;
+ void *arg;
+{
+ struct userenv *uep, *uepnext;
+
+ uepnext = userenv_list;
+ while (uepnext != NULL && !uepnext->ue_isset)
+ uepnext = uepnext->ue_next;
+ while ((uep = uepnext) != NULL) {
+ uepnext = uep->ue_next;
+ while (uepnext != NULL && !uepnext->ue_isset)
+ uepnext = uepnext->ue_next;
+ (*printer)(arg, "%s=%s", uep->ue_name, uep->ue_value);
+ if (uepnext != NULL)
+ (*printer)(arg, "\t\t# (from %s)\n%s ", uep->ue_source, opt->name);
+ else
+ opt->source = uep->ue_source;
+ }
+}
+
+static int
+user_unsetenv(argv)
+ char **argv;
+{
+ struct userenv *uep, **insp;
+ char *arg = argv[0];
+
+ if (strchr(arg, '=') != NULL) {
+ option_error("unexpected = in name: %s", arg);
+ return 0;
+ }
+ if (arg == '\0') {
+ option_error("missing variable name for unset");
+ return 0;
+ }
+ for (uep = userenv_list; uep != NULL; uep = uep->ue_next) {
+ if (strcmp(arg, uep->ue_name) == 0)
+ break;
+ }
+ /* Ignore attempts by unprivileged users to override privileged sources */
+ if (uep != NULL && !privileged_option && uep->ue_priv)
+ return 1;
+ /* The name never changes, so allocate it with the structure */
+ if (uep == NULL) {
+ uep = malloc(sizeof (*uep) + strlen(arg));
+ strcpy(uep->ue_name, arg);
+ uep->ue_next = NULL;
+ insp = &userenv_list;
+ while (*insp != NULL)
+ insp = &(*insp)->ue_next;
+ *insp = uep;
+ } else {
+ struct userenv *uep2;
+ for (uep2 = userenv_list; uep2 != NULL; uep2 = uep2->ue_next) {
+ if (uep2 != uep && uep2->ue_isset)
+ break;
+ }
+ if (uep2 == NULL && uep->ue_isset)
+ find_option("set")->flags |= OPT_NOPRINT;
+ free(uep->ue_value);
+ }
+ uep->ue_isset = 0;
+ uep->ue_priv = privileged_option;
+ uep->ue_source = option_source;
+ uep->ue_value = NULL;
+ curopt->flags &= ~OPT_NOPRINT;
+ return 1;
+}
+
+static void
+user_unsetprint(opt, printer, arg)
+ option_t *opt;
+ printer_func printer;
+ void *arg;
+{
+ struct userenv *uep, *uepnext;
+
+ uepnext = userenv_list;
+ while (uepnext != NULL && uepnext->ue_isset)
+ uepnext = uepnext->ue_next;
+ while ((uep = uepnext) != NULL) {
+ uepnext = uep->ue_next;
+ while (uepnext != NULL && uepnext->ue_isset)
+ uepnext = uepnext->ue_next;
+ (*printer)(arg, "%s", uep->ue_name);
+ if (uepnext != NULL)
+ (*printer)(arg, "\t\t# (from %s)\n%s ", uep->ue_source, opt->name);
+ else
+ opt->source = uep->ue_source;
+ }
+}
diff --git ppp-2.4.5-release/pppd/pppd.8 ppp-2.4.5/pppd/pppd.8
index b7adc77..7ad24c5 100644
--- ppp-2.4.5-release/pppd/pppd.8
+++ ppp-2.4.5/pppd/pppd.8
@@ -1018,6 +1018,13 @@ Authentication Protocol] authentication.
Require the peer to authenticate itself using PAP [Password
Authentication Protocol] authentication.
.TP
+.B set \fIname\fR=\fIvalue
+Set an environment variable for scripts that are invoked by pppd.
+When set by a privileged source, the variable specified by \fIname\fR
+cannot be changed by options contained in an unprivileged source. See
+also the \fIunset\fR option and the environment described in
+\fISCRIPTS\fR.
+.TP
.B show\-password
When logging the contents of PAP packets, this option causes pppd to
show the password string in the log message.
@@ -1058,6 +1065,13 @@ under Linux and FreeBSD 2.2.8 and later.
Sets the ppp unit number (for a ppp0 or ppp1 etc interface name) for outbound
connections.
.TP
+.B unset \fIname
+Remove a variable from the environment variable for scripts that are
+invoked by pppd. When specified by a privileged source, the variable
+\fIname\fR cannot be set by options contained in an unprivileged
+source. See also the \fIset\fR option and the environment described
+in \fISCRIPTS\fR.
+.TP
.B updetach
With this option, pppd will detach from its controlling terminal once
it has successfully established the ppp connection (to the point where
diff --git ppp-2.4.5-release/pppd/pppd.h ppp-2.4.5/pppd/pppd.h
index cf9840a..936cc60 100644
--- ppp-2.4.5-release/pppd/pppd.h
+++ ppp-2.4.5/pppd/pppd.h
@@ -139,7 +139,7 @@ typedef struct {
#define OPT_INITONLY 0x4000000 /* option can only be set in init phase */
#define OPT_DEVEQUIV 0x8000000 /* equiv to device name */
#define OPT_DEVNAM (OPT_INITONLY | OPT_DEVEQUIV)
-#define OPT_A2PRINTER 0x10000000 /* *addr2 is a fn for printing option */
+#define OPT_A2PRINTER 0x10000000 /* *addr2 printer_func to print option */
#define OPT_A2STRVAL 0x20000000 /* *addr2 points to current string value */
#define OPT_NOPRINT 0x40000000 /* don't print this option at all */
@@ -199,6 +199,7 @@ struct epdisc {
#define EPD_PHONENUM 5
typedef void (*notify_func) __P((void *, int));
+typedef void (*printer_func) __P((void *, char *, ...));
struct notifier {
struct notifier *next;
@@ -406,8 +407,7 @@ struct protent {
/* Close the protocol */
void (*close) __P((int unit, char *reason));
/* Print a packet in readable form */
- int (*printpkt) __P((u_char *pkt, int len,
- void (*printer) __P((void *, char *, ...)),
+ int (*printpkt) __P((u_char *pkt, int len, printer_func printer,
void *arg));
/* Process a received data packet */
void (*datainput) __P((int unit, u_char *pkt, int len));
@@ -461,6 +461,21 @@ struct channel {
extern struct channel *the_channel;
/*
+ * This structure contains environment variables that are set or unset
+ * by the user.
+ */
+struct userenv {
+ struct userenv *ue_next;
+ char *ue_value; /* value (set only) */
+ bool ue_isset; /* 1 for set, 0 for unset */
+ bool ue_priv; /* from privileged source */
+ const char *ue_source; /* source name */
+ char ue_name[1]; /* variable name */
+};
+
+extern struct userenv *userenv_list;
+
+/*
* Prototypes.
*/
@@ -504,8 +519,8 @@ void tty_init __P((void));
/* Procedures exported from utils.c. */
void log_packet __P((u_char *, int, char *, int));
/* Format a packet and log it with syslog */
-void print_string __P((char *, int, void (*) (void *, char *, ...),
- void *)); /* Format a string for output */
+void print_string __P((char *, int, printer_func, void *));
+ /* Format a string for output */
int slprintf __P((char *, int, char *, ...)); /* sprintf++ */
int vslprintf __P((char *, int, char *, va_list)); /* vsprintf++ */
size_t strlcpy __P((char *, const char *, size_t)); /* safe strcpy */
@@ -691,7 +706,7 @@ void add_options __P((option_t *)); /* Add extra options */
void check_options __P((void)); /* check values after all options parsed */
int override_value __P((const char *, int, const char *));
/* override value if permitted by priority */
-void print_options __P((void (*) __P((void *, char *, ...)), void *));
+void print_options __P((printer_func, void *));
/* print out values of all options */
int parse_dotted_ip __P((char *, u_int32_t *));
diff --git ppp-2.4.5-release/pppd/utils.c ppp-2.4.5/pppd/utils.c
index 062b17e..5c9ba64 100644
--- ppp-2.4.5-release/pppd/utils.c
+++ ppp-2.4.5/pppd/utils.c
@@ -68,8 +68,7 @@ extern char *strerror();
static void logit __P((int, char *, va_list));
static void log_write __P((int, char *));
static void vslp_printer __P((void *, char *, ...));
-static void format_packet __P((u_char *, int, void (*) (void *, char *, ...),
- void *));
+static void format_packet __P((u_char *, int, printer_func, void *));
struct buffer_info {
char *ptr;
@@ -475,7 +474,7 @@ static void
format_packet(p, len, printer, arg)
u_char *p;
int len;
- void (*printer) __P((void *, char *, ...));
+ printer_func printer;
void *arg;
{
int i, n;
@@ -613,7 +612,7 @@ void
print_string(p, len, printer, arg)
char *p;
int len;
- void (*printer) __P((void *, char *, ...));
+ printer_func printer;
void *arg;
{
int c;
--
1.6.6.2
From 2b4ea140432eeba5a007c0d4e6236bd0e0c12ba4 Mon Sep 17 00:00:00 2001
From: James Carlson <carlsonj@workingcode.com>
Date: Mon, 23 Aug 2010 10:01:48 -0400
Subject: [PATCH 6/9] Nit: use _exit when exec fails and restrict values to 0-255 per POSIX.
---
pppd/main.c | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git ppp-2.4.5-release/pppd/main.c ppp-2.4.5/pppd/main.c
index 1b513ca..6e7378b 100644
--- ppp-2.4.5-release/pppd/main.c
+++ ppp-2.4.5/pppd/main.c
@@ -1719,7 +1719,7 @@ device_script(program, in, out, dont_wait)
update_system_environment();
execl("/bin/sh", "sh", "-c", program, (char *)0);
perror("pppd: could not exec /bin/sh");
- exit(99);
+ _exit(99);
/* NOTREACHED */
}
@@ -1841,7 +1841,7 @@ run_program(prog, args, must_exist, done, arg, wait)
syslog(LOG_ERR, "Can't execute %s: %m", prog);
closelog();
}
- _exit(-1);
+ _exit(99);
}
--
1.6.6.2
From 3089132cdf5b58dbdfc2daf08ec5c08eb47f8aca Mon Sep 17 00:00:00 2001
From: James Carlson <carlsonj@workingcode.com>
Date: Mon, 23 Aug 2010 10:03:07 -0400
Subject: [PATCH 7/9] Fix quote handling in configuration files to be more like shell quoting.
The specific case that confused a user was:
ROUTES="216.220.192.0/20 10.0.100.0/24"
which was interpreted as two separate words, merely because the first quote
mark was in the middle of a word.
---
pppd/options.c | 44 ++++++++++++++++++++++----------------------
1 files changed, 22 insertions(+), 22 deletions(-)
diff --git ppp-2.4.5-release/pppd/options.c ppp-2.4.5/pppd/options.c
index 434ab95..008b482 100644
--- ppp-2.4.5-release/pppd/options.c
+++ ppp-2.4.5/pppd/options.c
@@ -1146,6 +1146,7 @@ getword(f, word, newlinep, filename)
len = 0;
escape = 0;
comment = 0;
+ quoted = 0;
/*
* First skip white-space and comments.
@@ -1204,15 +1205,6 @@ getword(f, word, newlinep, filename)
}
/*
- * Save the delimiter for quoted strings.
- */
- if (!escape && (c == '"' || c == '\'')) {
- quoted = c;
- c = getc(f);
- } else
- quoted = 0;
-
- /*
* Process characters until the end of the word.
*/
while (c != EOF) {
@@ -1300,29 +1292,34 @@ getword(f, word, newlinep, filename)
if (!got)
c = getc(f);
continue;
-
}
/*
- * Not escaped: see if we've reached the end of the word.
+ * Backslash starts a new escape sequence.
*/
- if (quoted) {
- if (c == quoted)
- break;
- } else {
- if (isspace(c) || c == '#') {
- ungetc (c, f);
- break;
- }
+ if (c == '\\') {
+ escape = 1;
+ c = getc(f);
+ continue;
}
/*
- * Backslash starts an escape sequence.
+ * Not escaped: check for the start or end of a quoted
+ * section and see if we've reached the end of the word.
*/
- if (c == '\\') {
- escape = 1;
+ if (quoted) {
+ if (c == quoted) {
+ quoted = 0;
+ c = getc(f);
+ continue;
+ }
+ } else if (c == '"' || c == '\'') {
+ quoted = c;
c = getc(f);
continue;
+ } else if (isspace(c) || c == '#') {
+ ungetc (c, f);
+ break;
}
/*
@@ -1351,6 +1348,9 @@ getword(f, word, newlinep, filename)
*/
if (len == 0)
return 0;
+ if (quoted)
+ option_error("warning: quoted word runs to end of file (%.20s...)",
+ filename, word);
}
/*
--
1.6.6.2
From fd1dcdf758418f040da3ed801ab001b5e46854e7 Mon Sep 17 00:00:00 2001
From: Simon Arlott <simon.arlott.org.uk>
Date: Tue, 4 May 2010 20:06:06 +0100
Subject: [PATCH 8/9] rp-pppoe: allow MTU to be increased up to 1500
The ethernet data limit on rp-pppoe has been increased to 1508 to
allow an MTU of 1500 to be used. To prevent problems the interface
MTU is checked and used to lower the configured MTU/MRU.
If MIN(MTU/MRU) is > 1492, PPP-Max-Payload is added to PADI and
PADR. If PPP-Max-Payload is received in PADO or PADS, it will be
used to lower the configured MTU/MRU as required.
The MTU/MRU settings are stored and reloaded whenever a connection
is made, to allow for the peer or interface MTU/MRU to increase if
used with persist option.
Conforming to RFC4638, if no PPP-Max-Payload is received, the
negotiated MRU will be limited to 1492.
---
pppd/plugins/rp-pppoe/common.c | 5 ++-
pppd/plugins/rp-pppoe/discovery.c | 65 +++++++++++++++++++++++++++++++
pppd/plugins/rp-pppoe/plugin.c | 30 ++++++++++++++
pppd/plugins/rp-pppoe/pppoe-discovery.c | 2 +-
pppd/plugins/rp-pppoe/pppoe.h | 22 ++++++++--
5 files changed, 118 insertions(+), 6 deletions(-)
diff --git ppp-2.4.5-release/pppd/plugins/rp-pppoe/common.c ppp-2.4.5/pppd/plugins/rp-pppoe/common.c
index a49efe7..3b8e014 100644
--- ppp-2.4.5-release/pppd/plugins/rp-pppoe/common.c
+++ ppp-2.4.5/pppd/plugins/rp-pppoe/common.c
@@ -58,7 +58,7 @@ parsePacket(PPPoEPacket *packet, ParseFunc *func, void *extra)
}
/* Do some sanity checks on packet */
- if (len > ETH_DATA_LEN - 6) { /* 6-byte overhead for PPPoE header */
+ if (len > ETH_JUMBO_LEN - PPPOE_OVERHEAD) { /* 6-byte overhead for PPPoE header */
error("Invalid PPPoE packet length (%u)", len);
return -1;
}
@@ -246,6 +246,9 @@ void pppoe_printpkt(PPPoEPacket *packet,
case TAG_RELAY_SESSION_ID:
printer(arg, "relay-session-id");
break;
+ case TAG_PPP_MAX_PAYLOAD:
+ printer(arg, "PPP-max-payload");
+ break;
case TAG_SERVICE_NAME_ERROR:
printer(arg, "service-name-error");
text = 1;
diff --git ppp-2.4.5-release/pppd/plugins/rp-pppoe/discovery.c ppp-2.4.5/pppd/plugins/rp-pppoe/discovery.c
index 6e25ae7..a856490 100644
--- ppp-2.4.5-release/pppd/plugins/rp-pppoe/discovery.c
+++ ppp-2.4.5/pppd/plugins/rp-pppoe/discovery.c
@@ -14,6 +14,8 @@ static char const RCSID[] =
#define _GNU_SOURCE 1
#include "pppoe.h"
#include "pppd/pppd.h"
+#include "pppd/fsm.h"
+#include "pppd/lcp.h"
#include <string.h>
#include <stdlib.h>
@@ -110,6 +112,7 @@ parsePADOTags(UINT16_t type, UINT16_t len, unsigned char *data,
{
struct PacketCriteria *pc = (struct PacketCriteria *) extra;
PPPoEConnection *conn = pc->conn;
+ UINT16_t mru;
int i;
switch(type) {
@@ -140,6 +143,19 @@ parsePADOTags(UINT16_t type, UINT16_t len, unsigned char *data,
conn->relayId.length = htons(len);
memcpy(conn->relayId.payload, data, len);
break;
+ case TAG_PPP_MAX_PAYLOAD:
+ if (len == sizeof(mru)) {
+ memcpy(&mru, data, sizeof(mru));
+ mru = ntohs(mru);
+ if (mru >= ETH_PPPOE_MTU) {
+ if (lcp_allowoptions[0].mru > mru)
+ lcp_allowoptions[0].mru = mru;
+ if (lcp_wantoptions[0].mru > mru)
+ lcp_wantoptions[0].mru = mru;
+ conn->seenMaxPayload = 1;
+ }
+ }
+ break;
case TAG_SERVICE_NAME_ERROR:
error("PADO: Service-Name-Error: %.*s", (int) len, data);
conn->error = 1;
@@ -172,10 +188,24 @@ parsePADSTags(UINT16_t type, UINT16_t len, unsigned char *data,
void *extra)
{
PPPoEConnection *conn = (PPPoEConnection *) extra;
+ UINT16_t mru;
switch(type) {
case TAG_SERVICE_NAME:
dbglog("PADS: Service-Name: '%.*s'", (int) len, data);
break;
+ case TAG_PPP_MAX_PAYLOAD:
+ if (len == sizeof(mru)) {
+ memcpy(&mru, data, sizeof(mru));
+ mru = ntohs(mru);
+ if (mru >= ETH_PPPOE_MTU) {
+ if (lcp_allowoptions[0].mru > mru)
+ lcp_allowoptions[0].mru = mru;
+ if (lcp_wantoptions[0].mru > mru)
+ lcp_wantoptions[0].mru = mru;
+ conn->seenMaxPayload = 1;
+ }
+ }
+ break;
case TAG_SERVICE_NAME_ERROR:
error("PADS: Service-Name-Error: %.*s", (int) len, data);
conn->error = 1;
@@ -259,6 +289,19 @@ sendPADI(PPPoEConnection *conn)
plen += sizeof(pid) + TAG_HDR_SIZE;
}
+ /* Add our maximum MTU/MRU */
+ if (MIN(lcp_allowoptions[0].mru, lcp_wantoptions[0].mru) > ETH_PPPOE_MTU) {
+ PPPoETag maxPayload;
+ UINT16_t mru = htons(MIN(lcp_allowoptions[0].mru, lcp_wantoptions[0].mru));
+ maxPayload.type = htons(TAG_PPP_MAX_PAYLOAD);
+ maxPayload.length = htons(sizeof(mru));
+ memcpy(maxPayload.payload, &mru, sizeof(mru));
+ CHECK_ROOM(cursor, packet.payload, sizeof(mru) + TAG_HDR_SIZE);
+ memcpy(cursor, &maxPayload, sizeof(mru) + TAG_HDR_SIZE);
+ cursor += sizeof(mru) + TAG_HDR_SIZE;
+ plen += sizeof(mru) + TAG_HDR_SIZE;
+ }
+
packet.length = htons(plen);
sendPacket(conn, conn->discoverySocket, &packet, (int) (plen + HDR_SIZE));
@@ -289,6 +332,7 @@ waitForPADO(PPPoEConnection *conn, int timeout)
pc.serviceNameOK = (conn->serviceName) ? 0 : 1;
pc.seenACName = 0;
pc.seenServiceName = 0;
+ conn->seenMaxPayload = 0;
conn->error = 0;
do {
@@ -413,6 +457,19 @@ sendPADR(PPPoEConnection *conn)
plen += sizeof(pid) + TAG_HDR_SIZE;
}
+ /* Add our maximum MTU/MRU */
+ if (MIN(lcp_allowoptions[0].mru, lcp_wantoptions[0].mru) > ETH_PPPOE_MTU) {
+ PPPoETag maxPayload;
+ UINT16_t mru = htons(MIN(lcp_allowoptions[0].mru, lcp_wantoptions[0].mru));
+ maxPayload.type = htons(TAG_PPP_MAX_PAYLOAD);
+ maxPayload.length = htons(sizeof(mru));
+ memcpy(maxPayload.payload, &mru, sizeof(mru));
+ CHECK_ROOM(cursor, packet.payload, sizeof(mru) + TAG_HDR_SIZE);
+ memcpy(cursor, &maxPayload, sizeof(mru) + TAG_HDR_SIZE);
+ cursor += sizeof(mru) + TAG_HDR_SIZE;
+ plen += sizeof(mru) + TAG_HDR_SIZE;
+ }
+
/* Copy cookie and relay-ID if needed */
if (conn->cookie.type) {
CHECK_ROOM(cursor, packet.payload,
@@ -566,6 +623,14 @@ discovery(PPPoEConnection *conn)
timeout *= 2;
} while (conn->discoveryState == STATE_SENT_PADR);
+ if (!conn->seenMaxPayload) {
+ /* RFC 4638: MUST limit MTU/MRU to 1492 */
+ if (lcp_allowoptions[0].mru > ETH_PPPOE_MTU)
+ lcp_allowoptions[0].mru = ETH_PPPOE_MTU;
+ if (lcp_wantoptions[0].mru > ETH_PPPOE_MTU)
+ lcp_wantoptions[0].mru = ETH_PPPOE_MTU;
+ }
+
/* We're done. */
conn->discoveryState = STATE_SESSION;
return;
diff --git ppp-2.4.5-release/pppd/plugins/rp-pppoe/plugin.c ppp-2.4.5/pppd/plugins/rp-pppoe/plugin.c
index 9bd6643..97011aa 100644
--- ppp-2.4.5-release/pppd/plugins/rp-pppoe/plugin.c
+++ ppp-2.4.5/pppd/plugins/rp-pppoe/plugin.c
@@ -130,6 +130,31 @@ static int
PPPOEConnectDevice(void)
{
struct sockaddr_pppox sp;
+ struct ifreq ifr;
+ int s;
+
+ /* Restore configuration */
+ lcp_allowoptions[0].mru = conn->mtu;
+ lcp_wantoptions[0].mru = conn->mru;
+
+ /* Update maximum MRU */
+ s = socket(AF_INET, SOCK_DGRAM, 0);
+ if (s < 0) {
+ error("Can't get MTU for %s: %m", conn->ifName);
+ goto errout;
+ }
+ strncpy(ifr.ifr_name, conn->ifName, sizeof(ifr.ifr_name));
+ if (ioctl(s, SIOCGIFMTU, &ifr) < 0) {
+ error("Can't get MTU for %s: %m", conn->ifName);
+ close(s);
+ goto errout;
+ }
+ close(s);
+
+ if (lcp_allowoptions[0].mru > ifr.ifr_mtu - TOTAL_OVERHEAD)
+ lcp_allowoptions[0].mru = ifr.ifr_mtu - TOTAL_OVERHEAD;
+ if (lcp_wantoptions[0].mru > ifr.ifr_mtu - TOTAL_OVERHEAD)
+ lcp_wantoptions[0].mru = ifr.ifr_mtu - TOTAL_OVERHEAD;
conn->acName = acName;
conn->serviceName = pppd_pppoe_service;
@@ -163,6 +188,7 @@ PPPOEConnectDevice(void)
error("Failed to create PPPoE socket: %m");
goto errout;
}
+
sp.sa_family = AF_PPPOX;
sp.sa_protocol = PX_PROTO_OE;
sp.sa_addr.pppoe.sid = conn->session;
@@ -381,6 +407,10 @@ void pppoe_check_options(void)
if (lcp_wantoptions[0].mru > MAX_PPPOE_MTU)
lcp_wantoptions[0].mru = MAX_PPPOE_MTU;
+ /* Save configuration */
+ conn->mtu = lcp_allowoptions[0].mru;
+ conn->mru = lcp_wantoptions[0].mru;
+
ccp_allowoptions[0].deflate = 0;
ccp_wantoptions[0].deflate = 0;
diff --git ppp-2.4.5-release/pppd/plugins/rp-pppoe/pppoe-discovery.c ppp-2.4.5/pppd/plugins/rp-pppoe/pppoe-discovery.c
index 318f858..3d3bf4e 100644
--- ppp-2.4.5-release/pppd/plugins/rp-pppoe/pppoe-discovery.c
+++ ppp-2.4.5/pppd/plugins/rp-pppoe/pppoe-discovery.c
@@ -277,7 +277,7 @@ parsePacket(PPPoEPacket *packet, ParseFunc *func, void *extra)
}
/* Do some sanity checks on packet */
- if (len > ETH_DATA_LEN - 6) { /* 6-byte overhead for PPPoE header */
+ if (len > ETH_JUMBO_LEN - PPPOE_OVERHEAD) { /* 6-byte overhead for PPPoE header */
fprintf(stderr, "Invalid PPPoE packet length (%u)\n", len);
return -1;
}
diff --git ppp-2.4.5-release/pppd/plugins/rp-pppoe/pppoe.h ppp-2.4.5/pppd/plugins/rp-pppoe/pppoe.h
index 3dba439..9ab2eee 100644
--- ppp-2.4.5-release/pppd/plugins/rp-pppoe/pppoe.h
+++ ppp-2.4.5/pppd/plugins/rp-pppoe/pppoe.h
@@ -129,6 +129,7 @@ extern UINT16_t Eth_PPPOE_Session;
#define TAG_AC_COOKIE 0x0104
#define TAG_VENDOR_SPECIFIC 0x0105
#define TAG_RELAY_SESSION_ID 0x0110
+#define TAG_PPP_MAX_PAYLOAD 0x0120
#define TAG_SERVICE_NAME_ERROR 0x0201
#define TAG_AC_SYSTEM_ERROR 0x0202
#define TAG_GENERIC_ERROR 0x0203
@@ -167,6 +168,13 @@ extern UINT16_t Eth_PPPOE_Session;
#define IPV4ALEN 4
#define SMALLBUF 256
+/* There are other fixed-size buffers preventing
+ this from being increased to 16110. The buffer
+ sizes would need to be properly de-coupled from
+ the default MRU. For now, getting up to 1500 is
+ enough. */
+#define ETH_JUMBO_LEN 1508
+
/* A PPPoE Packet, including Ethernet headers */
typedef struct PPPoEPacketStruct {
struct ethhdr ethHdr; /* Ethernet header */
@@ -174,7 +182,7 @@ typedef struct PPPoEPacketStruct {
unsigned int code:8; /* PPPoE code */
unsigned int session:16; /* PPPoE session */
unsigned int length:16; /* Payload length */
- unsigned char payload[ETH_DATA_LEN]; /* A bit of room to spare */
+ unsigned char payload[ETH_JUMBO_LEN]; /* A bit of room to spare */
} PPPoEPacket;
#define PPPOE_VER(vt) ((vt) >> 4)
@@ -184,15 +192,18 @@ typedef struct PPPoEPacketStruct {
/* Header size of a PPPoE packet */
#define PPPOE_OVERHEAD 6 /* type, code, session, length */
#define HDR_SIZE (sizeof(struct ethhdr) + PPPOE_OVERHEAD)
-#define MAX_PPPOE_PAYLOAD (ETH_DATA_LEN - PPPOE_OVERHEAD)
-#define MAX_PPPOE_MTU (MAX_PPPOE_PAYLOAD - 2)
+#define MAX_PPPOE_PAYLOAD (ETH_JUMBO_LEN - PPPOE_OVERHEAD)
+#define PPP_OVERHEAD 2 /* protocol */
+#define MAX_PPPOE_MTU (MAX_PPPOE_PAYLOAD - PPP_OVERHEAD)
+#define TOTAL_OVERHEAD (PPPOE_OVERHEAD + PPP_OVERHEAD)
+#define ETH_PPPOE_MTU (ETH_DATA_LEN - TOTAL_OVERHEAD)
/* PPPoE Tag */
typedef struct PPPoETagStruct {
unsigned int type:16; /* tag type */
unsigned int length:16; /* Length of payload */
- unsigned char payload[ETH_DATA_LEN]; /* A LOT of room to spare */
+ unsigned char payload[ETH_JUMBO_LEN]; /* A LOT of room to spare */
} PPPoETag;
/* Header size of a PPPoE tag */
#define TAG_HDR_SIZE 4
@@ -233,6 +244,9 @@ typedef struct PPPoEConnectionStruct {
int error; /* Error packet received */
int debug; /* Set to log packets sent and received */
int discoveryTimeout; /* Timeout for discovery packets */
+ int seenMaxPayload;
+ int mtu; /* Stored MTU */
+ int mru; /* Stored MRU */
} PPPoEConnection;
/* Structure used to determine acceptable PADO or PADS packet */
--
1.6.6.2
From ae80bf833e48a6202f44a935a68083ae52ad3824 Mon Sep 17 00:00:00 2001
From: Ashok Rao <greatarbor@gmail.com>
Date: Sat, 11 Sep 2010 22:14:48 +1000
Subject: [PATCH 9/9] chat: Allow TIMEOUT value to come from environment variable
This allows the TIMEOUT value to be obtained from the environment
using the $ENVVAR syntax.
Signed-off-by: Paul Mackerras <paulus@samba.org>
---
chat/chat.c | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
diff --git ppp-2.4.5-release/chat/chat.c ppp-2.4.5/chat/chat.c
index 0b88c27..710dba9 100644
--- ppp-2.4.5-release/chat/chat.c
+++ ppp-2.4.5/chat/chat.c
@@ -1167,6 +1167,7 @@ register char *s;
if (timeout_next) {
timeout_next = 0;
+ s = clean(s, 0);
timeout = atoi(s);
if (timeout <= 0)
--
1.6.6.2