diff --git a/.cvsignore b/.cvsignore index e69de29..49cbbec 100644 --- a/.cvsignore +++ b/.cvsignore @@ -0,0 +1 @@ +pptp-1.6.0.tar.gz diff --git a/pptp-cvs20050331.patch b/pptp-cvs20050331.patch new file mode 100644 index 0000000..a77d4f7 --- /dev/null +++ b/pptp-cvs20050331.patch @@ -0,0 +1,423 @@ +diff -ur pptp-1.6.0/ChangeLog pptp-linux/ChangeLog +--- pptp-1.6.0/ChangeLog 2005-02-18 01:42:45.000000000 +0000 ++++ pptp-linux/ChangeLog 2005-03-31 16:52:04.000000000 +0100 +@@ -1,3 +1,32 @@ ++Thu Mar 31 17:41:17 2005 James Cameron ++ ++ * pptp_ctrl.c (pptp_dispatch): handle signals first, since there's ++ a possibility of premature return from the function. ++ ++ * pptp_callmgr.c (callmgr_main): terminate faster when peer closes ++ control connection. ++ ++Thu Mar 10 11:07:52 2005 James Cameron ++ ++ * pptp_ctrl.c (pptp_handle_timer): when we close connection due to ++ loss of echo replies, say so in the log. ++ Reported by: Jean Wolter. ++ ++ * pptp_ctrl.c: fix signal deadlock on kernel 2.6.x ++ Reported by: Jean Wolter. ++ ++ * util.c, util.h: adopt sigpipe implementation from pptpd. ++ ++ * pptp_ctrl.c (pptp_conn_open): use sigpipe implementation instead ++ of trying I/O in signal handler (which causes deadlocks). ++ ++ * pptp_ctrl.c (pptp_fd_set): include the sigpipe in the file ++ descriptor set. ++ ++ * pptp_ctrl.c (pptp_dispatch): detect queued signals via sigpipe. ++ ++ * pptp_ctrl.c (pptp_conn_destroy): close the sigpipe. ++ + Fri Feb 18 12:38:18 2005 James Cameron + + * pptp-1.6.0 released. +diff -ur pptp-1.6.0/NEWS pptp-linux/NEWS +--- pptp-1.6.0/NEWS 2005-02-18 01:42:45.000000000 +0000 ++++ pptp-linux/NEWS 2005-03-10 01:18:20.000000000 +0000 +@@ -1,3 +1,6 @@ ++- adopt sigpipe for use with SIGALRM on control connection [Wolter/Cameron] ++- properly report control connection echo reply loss [Wolter] ++ + Release 1.6.0: (18th February 2005) + + - fix double-free on stop control connection reply [Kivity] +@@ -101,4 +104,4 @@ + + - This is the first public release of the pptp-linux package. + +-$Id: NEWS,v 1.40 2005/02/18 00:32:19 quozl Exp $ ++$Id: NEWS,v 1.41 2005/03/10 01:18:20 quozl Exp $ +diff -ur pptp-1.6.0/pptp_callmgr.c pptp-linux/pptp_callmgr.c +--- pptp-1.6.0/pptp_callmgr.c 2005-02-18 01:42:45.000000000 +0000 ++++ pptp-linux/pptp_callmgr.c 2005-03-31 16:52:05.000000000 +0100 +@@ -2,7 +2,7 @@ + * Handles TCP port 1723 protocol. + * C. Scott Ananian + * +- * $Id: pptp_callmgr.c,v 1.18 2004/11/09 01:42:32 quozl Exp $ ++ * $Id: pptp_callmgr.c,v 1.20 2005/03/31 07:42:39 quozl Exp $ + */ + #include + #include +@@ -36,6 +36,7 @@ + sigjmp_buf callmgr_env; + + void callmgr_sighandler(int sig) { ++ /* TODO: according to signal(2), siglongjmp() is unsafe used here */ + siglongjmp (callmgr_env, 1); + } + +@@ -74,7 +75,7 @@ + case CALL_CLOSE_DONE: + /* don't need to do anything here, except make sure tables + * are sync'ed */ +- log("Closing connection"); ++ log("Closing connection (call state)"); + conninfo = pptp_conn_closure_get(conn); + lci = pptp_call_closure_get(conn, call); + assert(lci != NULL && conninfo != NULL); +@@ -227,7 +228,7 @@ + if (retval) { + struct local_callinfo *lci = + pptp_call_closure_get(conn, call); +- log("Closing connection"); ++ log("Closing connection (unhandled)"); + if(lci->pid[0] > 1) kill(lci->pid[0], SIGTERM); + if(lci->pid[1] > 1) kill(lci->pid[1], SIGTERM); + free(lci); +@@ -241,6 +242,7 @@ + } while (vector_size(call_list) > 0 || first); + shutdown: + { ++ int rc; + fd_set read_set, write_set; + struct timeval tv; + signal(SIGINT, callmgr_do_nothing); +@@ -250,7 +252,7 @@ + for (i = 0; i < vector_size(call_list); i++) { + PPTP_CALL *call = vector_get_Nth(call_list, i); + struct local_callinfo *lci = pptp_call_closure_get(conn, call); +- log("Closing connection"); ++ log("Closing connection (shutdown)"); + pptp_call_close(conn, call); + if(lci->pid[0] > 1) kill(lci->pid[0], SIGTERM); + if(lci->pid[1] > 1) kill(lci->pid[1], SIGTERM); +@@ -259,27 +261,34 @@ + FD_ZERO(&read_set); + FD_ZERO(&write_set); + pptp_fd_set(conn, &read_set, &write_set, &max_fd); +- pptp_dispatch(conn, &read_set, &write_set); +- /* wait for a respond, a timeout because there might not be one */ +- FD_ZERO(&read_set); +- FD_ZERO(&write_set); +- pptp_fd_set(conn, &read_set, &write_set, &max_fd); +- tv.tv_sec = 2; +- tv.tv_usec = 0; +- select(max_fd + 1, &read_set, &write_set, NULL, &tv); +- pptp_dispatch(conn, &read_set, &write_set); +- if (i > 0) sleep(2); +- /* no more open calls. Close the connection. */ +- pptp_conn_close(conn, PPTP_STOP_LOCAL_SHUTDOWN); +- /* wait for a respond, a timeout because there might not be one */ +- FD_ZERO(&read_set); +- FD_ZERO(&write_set); +- pptp_fd_set(conn, &read_set, &write_set, &max_fd); +- tv.tv_sec = 2; +- tv.tv_usec = 0; +- select(max_fd + 1, &read_set, &write_set, NULL, &tv); +- pptp_dispatch(conn, &read_set, &write_set); +- sleep(2); ++ tv.tv_sec = 0; ++ tv.tv_usec = 0; ++ select(max_fd + 1, &read_set, &write_set, NULL, &tv); ++ rc = pptp_dispatch(conn, &read_set, &write_set); ++ if (rc > 0) { ++ /* wait for a respond, a timeout because there might not be one */ ++ FD_ZERO(&read_set); ++ FD_ZERO(&write_set); ++ pptp_fd_set(conn, &read_set, &write_set, &max_fd); ++ tv.tv_sec = 2; ++ tv.tv_usec = 0; ++ select(max_fd + 1, &read_set, &write_set, NULL, &tv); ++ rc = pptp_dispatch(conn, &read_set, &write_set); ++ if (rc > 0) { ++ if (i > 0) sleep(2); ++ /* no more open calls. Close the connection. */ ++ pptp_conn_close(conn, PPTP_STOP_LOCAL_SHUTDOWN); ++ /* wait for a respond, a timeout because there might not be one */ ++ FD_ZERO(&read_set); ++ FD_ZERO(&write_set); ++ pptp_fd_set(conn, &read_set, &write_set, &max_fd); ++ tv.tv_sec = 2; ++ tv.tv_usec = 0; ++ select(max_fd + 1, &read_set, &write_set, NULL, &tv); ++ pptp_dispatch(conn, &read_set, &write_set); ++ if (rc > 0) sleep(2); ++ } ++ } + /* with extreme prejudice */ + pptp_conn_destroy(conn); + vector_destroy(call_list); +diff -ur pptp-1.6.0/pptp_ctrl.c pptp-linux/pptp_ctrl.c +--- pptp-1.6.0/pptp_ctrl.c 2005-02-18 01:42:45.000000000 +0000 ++++ pptp-linux/pptp_ctrl.c 2005-03-31 16:52:05.000000000 +0100 +@@ -1,7 +1,7 @@ + /* pptp_ctrl.c ... handle PPTP control connection. + * C. Scott Ananian + * +- * $Id: pptp_ctrl.c,v 1.29 2004/12/13 22:06:46 quozl Exp $ ++ * $Id: pptp_ctrl.c,v 1.31 2005/03/31 07:42:39 quozl Exp $ + */ + + #include +@@ -171,7 +171,7 @@ + + /* Local prototypes */ + static void pptp_reset_timer(void); +-static void pptp_handle_timer(int sig); ++static void pptp_handle_timer(); + /* Write/read as much as we can without blocking. */ + int pptp_write_some(PPTP_CONN * conn); + int pptp_read_some(PPTP_CONN * conn); +@@ -257,7 +257,6 @@ + /* Open new pptp_connection. Returns NULL on failure. */ + PPTP_CONN * pptp_conn_open(int inet_sock, int isclient, pptp_conn_cb callback) + { +- struct sigaction sigact; + PPTP_CONN *conn; + /* Allocate structure */ + if ((conn = malloc(sizeof(*conn))) == NULL) return NULL; +@@ -306,11 +305,9 @@ + } + /* Set up interval/keep-alive timer */ + /* First, register handler for SIGALRM */ +- sigact.sa_handler = pptp_handle_timer; +- sigemptyset(&sigact.sa_mask); +- sigact.sa_flags = SA_RESTART; ++ sigpipe_create(); ++ sigpipe_assign(SIGALRM); + global.conn = conn; +- sigaction(SIGALRM, &sigact, &global.old_sigaction); + /* Reset event timer */ + pptp_reset_timer(); + /* all done. */ +@@ -447,7 +444,7 @@ + pptp_call_destroy(conn, vector_get_Nth(conn->call, i)); + /* notify */ + if (conn->callback != NULL) conn->callback(conn, CONN_CLOSE_DONE); +- sigaction(SIGALRM, &global.old_sigaction, NULL); ++ sigpipe_close(); + close(conn->inet_sock); + /* deallocate */ + vector_destroy(conn->call); +@@ -467,6 +464,10 @@ + /* Always add fd to read_set. (always want something to read) */ + FD_SET(conn->inet_sock, read_set); + if (*max_fd < conn->inet_sock) *max_fd = conn->inet_sock; ++ /* Add signal pipe file descriptor to set */ ++ int sig_fd = sigpipe_fd(); ++ FD_SET(sig_fd, read_set); ++ if (*max_fd < sig_fd) *max_fd = sig_fd; + } + + /*** handle any pptp file descriptors set in fd_set, and clear them ***********/ +@@ -474,6 +475,11 @@ + { + int r = 0; + assert(conn && conn->call); ++ /* Check for signals */ ++ if (FD_ISSET(sigpipe_fd(), read_set)) { ++ if (sigpipe_read() == SIGALRM) pptp_handle_timer(); ++ FD_CLR(sigpipe_fd(), read_set); ++ } + /* Check write_set could be set. */ + if (FD_ISSET(conn->inet_sock, write_set)) { + FD_CLR(conn->inet_sock, write_set); +@@ -1026,7 +1032,7 @@ + + + /*** Handle keep-alive timer **************************************************/ +-static void pptp_handle_timer(int sig) ++static void pptp_handle_timer() + { + int i; + /* "Keep Alives and Timers, 1": check connection state */ +@@ -1038,16 +1044,15 @@ + pptp_conn_close(global.conn, PPTP_STOP_NONE); + } + /* "Keep Alives and Timers, 2": check echo status */ +- if (global.conn->ka_state == KA_OUTSTANDING) /*no response to keep-alive*/ +- pptp_conn_close(global.conn, PPTP_STOP_NONE); +- else { /* ka_state == NONE */ /* send keep-alive */ ++ if (global.conn->ka_state == KA_OUTSTANDING) { ++ /* no response to keep-alive */ ++ log ("closing control connection due to missing echo reply"); ++ pptp_conn_close(global.conn, PPTP_STOP_NONE); ++ } else { /* ka_state == NONE */ /* send keep-alive */ + struct pptp_echo_rqst rqst = { + PPTP_HEADER_CTRL(PPTP_ECHO_RQST), hton32(global.conn->ka_id) }; + pptp_send_ctrl_packet(global.conn, &rqst, sizeof(rqst)); + global.conn->ka_state = KA_OUTSTANDING; +- /* XXX FIXME: wake up ctrl thread -- or will the SIGALRM do that +- * automagically? XXX +- */ + } + /* check incoming/outgoing call states for !IDLE && !ESTABLISHED */ + for (i = 0; i < vector_size(global.conn->call); i++) { +diff -ur pptp-1.6.0/TODO pptp-linux/TODO +--- pptp-1.6.0/TODO 2005-02-18 01:42:45.000000000 +0000 ++++ pptp-linux/TODO 2005-03-10 01:18:20.000000000 +0000 +@@ -1,3 +1,12 @@ ++10th March 2005 ++ ++- call manager is not being reused as it was designed to be; if a ++tunnel is started within a minute of a tunnel being stopped, it does ++not succeed; symptom is LCP ConfReq's without any traffic from the ++server. ++ ++-- ++ + - finish --max-echo-wait + + 11th August 2004 +@@ -86,4 +95,4 @@ + already-existing gre-copy process in the same way it uses an + already-existing call manager. + +-$Id: TODO,v 1.21 2004/11/09 01:42:32 quozl Exp $ ++$Id: TODO,v 1.22 2005/03/10 01:18:20 quozl Exp $ +diff -ur pptp-1.6.0/util.c pptp-linux/util.c +--- pptp-1.6.0/util.c 2005-02-18 01:42:45.000000000 +0000 ++++ pptp-linux/util.c 2005-03-10 01:18:20.000000000 +0000 +@@ -1,7 +1,7 @@ + /* util.c ....... error message utilities. + * C. Scott Ananian + * +- * $Id: util.c,v 1.9 2004/11/09 23:26:15 quozl Exp $ ++ * $Id: util.c,v 1.10 2005/03/10 01:18:20 quozl Exp $ + */ + + #include +@@ -76,3 +76,83 @@ + if (file) fclose(file); + return ok; + } ++ ++/* signal to pipe delivery implementation */ ++#include ++#include ++#include ++#include ++ ++/* pipe private to process */ ++static int sigpipe[2]; ++ ++/* create a signal pipe, returns 0 for success, -1 with errno for failure */ ++int sigpipe_create() ++{ ++ int rc; ++ ++ rc = pipe(sigpipe); ++ if (rc < 0) return rc; ++ ++ fcntl(sigpipe[0], F_SETFD, FD_CLOEXEC); ++ fcntl(sigpipe[1], F_SETFD, FD_CLOEXEC); ++ ++#ifdef O_NONBLOCK ++#define FLAG_TO_SET O_NONBLOCK ++#else ++#ifdef SYSV ++#define FLAG_TO_SET O_NDELAY ++#else /* BSD */ ++#define FLAG_TO_SET FNDELAY ++#endif ++#endif ++ ++ rc = fcntl(sigpipe[1], F_GETFL); ++ if (rc != -1) ++ rc = fcntl(sigpipe[1], F_SETFL, rc | FLAG_TO_SET); ++ if (rc < 0) return rc; ++ return 0; ++#undef FLAG_TO_SET ++} ++ ++/* generic handler for signals, writes signal number to pipe */ ++void sigpipe_handler(int signum) ++{ ++ write(sigpipe[1], &signum, sizeof(signum)); ++ signal(signum, sigpipe_handler); ++} ++ ++/* assign a signal number to the pipe */ ++void sigpipe_assign(int signum) ++{ ++ sigset_t sigset; ++ struct sigaction sa; ++ ++ sigemptyset(&sigset); ++ sigaddset(&sigset, signum); ++ ++ memset(&sa, 0, sizeof(sa)); ++ sa.sa_handler = sigpipe_handler; ++ sigaction(signum, &sa, NULL); ++} ++ ++/* return the signal pipe read file descriptor for select(2) */ ++int sigpipe_fd() ++{ ++ return sigpipe[0]; ++} ++ ++/* read and return the pending signal from the pipe */ ++int sigpipe_read() ++{ ++ int signum; ++ read(sigpipe[0], &signum, sizeof(signum)); ++ return signum; ++} ++ ++void sigpipe_close() ++{ ++ close(sigpipe[0]); ++ close(sigpipe[1]); ++} ++ +diff -ur pptp-1.6.0/util.h pptp-linux/util.h +--- pptp-1.6.0/util.h 2005-02-18 01:42:45.000000000 +0000 ++++ pptp-linux/util.h 2005-03-10 01:18:20.000000000 +0000 +@@ -1,7 +1,7 @@ + /* util.h ....... error message utilities. + * C. Scott Ananian + * +- * $Id: util.h,v 1.5 2004/11/09 23:26:15 quozl Exp $ ++ * $Id: util.h,v 1.6 2005/03/10 01:18:20 quozl Exp $ + */ + + #ifndef INC_UTIL_H +@@ -32,4 +32,23 @@ + + int file2fd(const char *path, const char *mode, int fd); + ++/* signal to pipe delivery implementation */ ++ ++/* create a signal pipe, returns 0 for success, -1 with errno for failure */ ++int sigpipe_create(); ++ ++/* generic handler for signals, writes signal number to pipe */ ++void sigpipe_handler(int signum); ++ ++/* assign a signal number to the pipe */ ++void sigpipe_assign(int signum); ++ ++/* return the signal pipe read file descriptor for select(2) */ ++int sigpipe_fd(); ++ ++/* read and return the pending signal from the pipe */ ++int sigpipe_read(); ++ ++void sigpipe_close(); ++ + #endif /* INC_UTIL_H */ diff --git a/pptp.spec b/pptp.spec new file mode 100644 index 0000000..721cda9 --- /dev/null +++ b/pptp.spec @@ -0,0 +1,55 @@ +Name: pptp +Version: 1.6.0 +Release: 3%{?dist} +Summary: Point-to-Point Tunneling Protocol (PPTP) Client + +Group: Applications/Internet +License: GPL +URL: http://pptpclient.sourceforge.net/ +Source0: http://dl.sf.net/pptpclient/pptp-%{version}.tar.gz +Patch0: pptp-cvs20050331.patch +BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) + +Requires: ppp >= 2.4.2 + +%description +Client for the proprietary Microsoft Point-to-Point Tunneling +Protocol, PPTP. Allows connection to a PPTP based VPN as used +by employers and some cable and ADSL service providers. + +%prep +%setup -q +%patch0 -p1 + +%build +%{__make} %{?_smp_mflags} + +%install +%{__rm} -rf $RPM_BUILD_ROOT +%{__make} DESTDIR=$RPM_BUILD_ROOT install + +%clean +%{__rm} -rf $RPM_BUILD_ROOT + +%files +%defattr(-,root,root,-) +%doc AUTHORS COPYING DEVELOPERS NEWS README TODO USING +%doc ChangeLog Documentation/DESIGN.PPTP +%attr(755,root,root) %{_sbindir}/pptp +%{_mandir}/man8/pptp.8* +# /etc/ppp is hardcoded instead of using %{_sysconfdir}/ppp because the +# Fedora Core ppp package hardcodes the directory name +%config(noreplace) /etc/ppp/options.pptp + +%changelog +* Tue May 10 2005 Paul Howarth 1.6.0-3%{?dist} +- fix URL for SOURCE0 not to point to a specific sf.net mirror + +* Tue May 10 2005 Paul Howarth 1.6.0-2%{?dist} +- Weed out documentation useful only to developers +- Add dist tag +- Use full URL for SOURCE0 +- Fix permissions on %{_sbindir}/pptp + +* Fri May 6 2005 Paul Howarth 1.6.0-1 +- First build for Fedora Extras, based on upstream spec file diff --git a/sources b/sources index e69de29..74a12ee 100644 --- a/sources +++ b/sources @@ -0,0 +1 @@ +9a706327fb9827541d7c86d48ceb9631 pptp-1.6.0.tar.gz