diff options
author | brian <brian@FreeBSD.org> | 1998-05-25 02:22:38 +0000 |
---|---|---|
committer | brian <brian@FreeBSD.org> | 1998-05-25 02:22:38 +0000 |
commit | 02218556c6995f24069e2dc1ca9533572cd1c70e (patch) | |
tree | 8533006e9326a5a8d8e768c905871e42dd0b4cd0 /usr.sbin | |
parent | 631316592f05d5ef85d9d819cb08570b9b8cd481 (diff) | |
download | FreeBSD-src-02218556c6995f24069e2dc1ca9533572cd1c70e.zip FreeBSD-src-02218556c6995f24069e2dc1ca9533572cd1c70e.tar.gz |
o Don't try to transfer tty device descriptors as there's no way of
transferring session rights with them. Instead, create two
`/bin/cat' processes. A new child is spawned and disassociated from
the terminal and the parent, which continues with the rest of the ppp
process. Meanwhile, the parent spawns another child, and both the
parent and child exec the `/bin/cat' commands with the appropriate
descriptors. This way, the session is owned by the parent, and the
tty is held open.
o Close LCPs that have done a TLF and are now in ST_STOPPED before
calling Down. This prevents them from trying to come back up again
after the peer has shut them down (it seems a bit strange that the
rfc says that a Down in ST_STOPPED will cause a TLS etc).
o Don't try to set the physical link name pointer when we're receiving
and renaming a datalink. The physical hasn't been created yet, and as
it happens, the garbage physical pointer happens to be the value of another
physical - so we're pointing that other physical name at ourselves.
yeuck.
o Re-arrange the order of things in main (DoLoop()). We now handle
signals only after the select and not before the UpdateSet. It's
possible that either a signal (FSM timeout) or a descriptor_Read()
brings a link down, after which we'd better tidy up any dead direct
and 1off descriptors before calling UpdateSet() again.
o Mention when we detect a PPP packet when we see one before the link
is up (then start LCP as before).
Diffstat (limited to 'usr.sbin')
-rw-r--r-- | usr.sbin/ppp/bundle.c | 116 | ||||
-rw-r--r-- | usr.sbin/ppp/datalink.c | 12 | ||||
-rw-r--r-- | usr.sbin/ppp/main.c | 16 | ||||
-rw-r--r-- | usr.sbin/ppp/modem.c | 8 | ||||
-rw-r--r-- | usr.sbin/ppp/mp.c | 8 |
5 files changed, 128 insertions, 32 deletions
diff --git a/usr.sbin/ppp/bundle.c b/usr.sbin/ppp/bundle.c index 047a463..0bb9c7d 100644 --- a/usr.sbin/ppp/bundle.c +++ b/usr.sbin/ppp/bundle.c @@ -23,7 +23,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: bundle.c,v 1.5 1998/05/23 22:27:53 brian Exp $ + * $Id: bundle.c,v 1.6 1998/05/23 22:28:19 brian Exp $ */ #include <sys/types.h> @@ -41,11 +41,13 @@ #include <errno.h> #include <fcntl.h> #include <paths.h> +#include <signal.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/ioctl.h> #include <sys/uio.h> +#include <sys/wait.h> #include <termios.h> #include <unistd.h> @@ -1349,8 +1351,10 @@ bundle_ReceiveDatalink(struct bundle *bundle, int s, struct sockaddr_un *sun) niov = 1; iov[0].iov_len = strlen(Version) + 1; iov[0].iov_base = (char *)malloc(iov[0].iov_len); - if (datalink2iov(NULL, iov, &niov, sizeof iov / sizeof *iov) == -1) + if (datalink2iov(NULL, iov, &niov, sizeof iov / sizeof *iov) == -1) { + close(s); return; + } for (f = expect = 0; f < niov; f++) expect += iov[f].iov_len; @@ -1358,7 +1362,7 @@ bundle_ReceiveDatalink(struct bundle *bundle, int s, struct sockaddr_un *sun) /* Set up our message */ cmsg->cmsg_len = sizeof cmsgbuf; cmsg->cmsg_level = SOL_SOCKET; - cmsg->cmsg_type = SCM_RIGHTS; + cmsg->cmsg_type = 0; memset(&msg, '\0', sizeof msg); msg.msg_name = (caddr_t)sun; @@ -1378,13 +1382,22 @@ bundle_ReceiveDatalink(struct bundle *bundle, int s, struct sockaddr_un *sun) log_Printf(LogERROR, "Failed recvmsg: Got %d, not %d\n", f, expect); while (niov--) free(iov[niov].iov_base); + close(s); return; } - /* We've successfully received an open file descriptor through our socket */ - link_fd = *(int *)CMSG_DATA(cmsg); + write(s, "!", 1); /* ACK */ - write(s, "!",1 ); /* ACK */ + if (cmsg->cmsg_type == SCM_RIGHTS) { + /* We've successfully received an open file descriptor through our socket */ + log_Printf(LogDEBUG, "Receiving non-tty device\n"); + link_fd = *(int *)CMSG_DATA(cmsg); + } else { + /* It's a ``controlling'' tty device via CATPROG */ + log_Printf(LogDEBUG, "Receiving tty device\n"); + link_fd = dup(s); + fcntl(link_fd, F_SETFL, fcntl(link_fd, F_GETFL, 0) | O_NONBLOCK); + } if (strncmp(Version, iov[0].iov_base, iov[0].iov_len)) { log_Printf(LogWARN, "Cannot receive datalink, incorrect version" @@ -1405,6 +1418,7 @@ bundle_ReceiveDatalink(struct bundle *bundle, int s, struct sockaddr_un *sun) close(link_fd); free(iov[0].iov_base); + close(s); } void @@ -1429,18 +1443,30 @@ bundle_SendDatalink(struct datalink *dl, int s, struct sockaddr_un *sun) link_fd = datalink2iov(dl, iov, &niov, sizeof iov / sizeof *iov); if (link_fd != -1) { - cmsg->cmsg_len = sizeof cmsgbuf; - cmsg->cmsg_level = SOL_SOCKET; - cmsg->cmsg_type = SCM_RIGHTS; - *(int *)CMSG_DATA(cmsg) = link_fd; - memset(&msg, '\0', sizeof msg); + msg.msg_name = (caddr_t)sun; msg.msg_namelen = sizeof *sun; msg.msg_iov = iov; msg.msg_iovlen = niov; - msg.msg_control = cmsgbuf; - msg.msg_controllen = sizeof cmsgbuf; + + if (link_fd == STDIN_FILENO && isatty(link_fd)) { + /* + * We can't transfer this tty descriptor. If we do, then once the + * session leader exits, the descriptor becomes unusable by the + * other ppp process. Instead, we'll fork() two `/bin/cat' + * processes..... + */ + msg.msg_control = NULL; + msg.msg_controllen = 0; + } else { + cmsg->cmsg_len = sizeof cmsgbuf; + cmsg->cmsg_level = SOL_SOCKET; + cmsg->cmsg_type = SCM_RIGHTS; + *(int *)CMSG_DATA(cmsg) = link_fd; + msg.msg_control = cmsgbuf; + msg.msg_controllen = sizeof cmsgbuf; + } for (f = expect = 0; f < niov; f++) expect += iov[f].iov_len; @@ -1453,6 +1479,70 @@ bundle_SendDatalink(struct datalink *dl, int s, struct sockaddr_un *sun) log_Printf(LogERROR, "Failed sendmsg: %s\n", strerror(errno)); /* We must get the ACK before closing the descriptor ! */ read(s, &ack, 1); + + if (link_fd == STDIN_FILENO && isatty(link_fd)) { + /* We use `/bin/cat' to keep the tty session id */ + pid_t pid; + int status, len, fd; + char name[50], *tname; + + tname = ttyname(link_fd); + len = strlen(_PATH_DEV); + if (!strncmp(tname, _PATH_DEV, len)) + tname += len; + + log_Printf(LogPHASE, "%s: Using twin %s invocations\n", tname, CATPROG); + + switch ((pid = fork())) { + case -1: + log_Printf(LogERROR, "fork: %s\n", strerror(errno)); + break; + case 0: + if (fork()) /* Don't want to belong to the parent any more */ + exit(0); + setsid(); + log_Printf(LogPHASE, "%d: Continuing without controlling terminal\n", + (int)getpid()); + break; + default: + /* Parent does the execs .... */ + timer_TermService(); + waitpid(pid, &status, 0); + + fcntl(3, F_SETFD, 1); /* Set close-on-exec flag */ + fcntl(s, F_SETFL, fcntl(s, F_GETFL, 0) & ~O_NONBLOCK); + fcntl(link_fd, F_SETFL, fcntl(link_fd, F_GETFL, 0) & ~O_NONBLOCK); + s = fcntl(s, F_DUPFD, 3); + link_fd = fcntl(link_fd, F_DUPFD, 3); + dup2(open(_PATH_DEVNULL, O_WRONLY|O_APPEND), STDERR_FILENO); + + setuid(geteuid()); + + switch (fork()) { + case -1: + _exit(0); + break; + case 0: + dup2(link_fd, STDIN_FILENO); + dup2(s, STDOUT_FILENO); + snprintf(name, sizeof name, "%s <- %s", dl->name, tname); + break; + default: + dup2(s, STDIN_FILENO); + dup2(link_fd, STDOUT_FILENO); + snprintf(name, sizeof name, "%s -> %s", dl->name, tname); + break; + } + signal(SIGPIPE, SIG_DFL); + signal(SIGALRM, SIG_DFL); + for (fd = getdtablesize(); fd > 2; fd--) + close(fd); + execl(CATPROG, name, NULL); + _exit(0); + break; + } + } + close(s); close(link_fd); } diff --git a/usr.sbin/ppp/datalink.c b/usr.sbin/ppp/datalink.c index 655fc0a..a41e93b 100644 --- a/usr.sbin/ppp/datalink.c +++ b/usr.sbin/ppp/datalink.c @@ -23,7 +23,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: datalink.c,v 1.3 1998/05/23 13:38:06 brian Exp $ + * $Id: datalink.c,v 1.4 1998/05/23 22:24:33 brian Exp $ */ #include <sys/types.h> @@ -526,7 +526,9 @@ datalink_LayerFinish(void *v, struct fsm *fp) struct datalink *dl = (struct datalink *)v; if (fp->proto == PROTO_LCP) { - fsm_Down(fp); /* Bring us to INITIAL or STARTING */ + if (fp->state == ST_STOPPED) + fsm_Close(fp); /* back to CLOSED */ + fsm_Down(fp); /* Bring us to INITIAL or STARTING */ (*dl->parent->LayerFinish)(dl->parent->object, fp); datalink_ComeDown(dl, 0); } else if (fp->state == ST_CLOSED && fp->open_mode == OPEN_PASSIVE) @@ -761,6 +763,8 @@ datalink_Down(struct datalink *dl, int stay) case DATALINK_AUTH: case DATALINK_LCP: + if (dl->physical->link.lcp.fsm.state == ST_STOPPED) + fsm_Close(&dl->physical->link.lcp.fsm); /* back to CLOSED */ fsm_Down(&dl->physical->link.lcp.fsm); if (stay) fsm_Close(&dl->physical->link.lcp.fsm); @@ -965,7 +969,6 @@ iov2datalink(struct bundle *bundle, struct iovec *iov, int *niov, int maxiov, free(oname); } else { dl->name = strdup(dl->name); - dl->physical->link.name = dl->name; free(iov[*niov].iov_base); } (*niov)++; @@ -1076,7 +1079,8 @@ datalink_NextName(struct datalink *dl) n = sprintf(name, "%.*s-", dl->name[f] == '-' ? f : f + 1, dl->name); sprintf(name + n, "%d", atoi(dl->name + f + 1) + 1); oname = dl->name; - dl->physical->link.name = dl->name = name; + dl->name = name; + /* our physical link name isn't updated (it probably isn't created yet) */ return oname; } diff --git a/usr.sbin/ppp/main.c b/usr.sbin/ppp/main.c index d687aa4..f45a388 100644 --- a/usr.sbin/ppp/main.c +++ b/usr.sbin/ppp/main.c @@ -17,7 +17,7 @@ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. * - * $Id: main.c,v 1.123 1998/05/21 21:46:40 brian Exp $ + * $Id: main.c,v 1.124 1998/05/23 22:24:43 brian Exp $ * * TODO: */ @@ -476,8 +476,6 @@ DoLoop(struct bundle *bundle, struct prompt *prompt) FD_ZERO(&wfds); FD_ZERO(&efds); - sig_Handle(); - /* All our datalinks, the tun device and the MP socket */ descriptor_UpdateSet(&bundle->desc, &rfds, &wfds, &efds, &nfds); @@ -490,11 +488,7 @@ DoLoop(struct bundle *bundle, struct prompt *prompt) i = select(nfds, &rfds, &wfds, &efds, NULL); - if (i == 0) - continue; - else if (i < 0) { - if (errno == EINTR) - continue; + if (i < 0 && errno != EINTR) { log_Printf(LogERROR, "DoLoop: select(): %s\n", strerror(errno)); if (log_IsKept(LogTIMER)) { struct timeval t; @@ -532,6 +526,11 @@ DoLoop(struct bundle *bundle, struct prompt *prompt) break; } + sig_Handle(); + + if (i <= 0) + continue; + for (i = 0; i <= nfds; i++) if (FD_ISSET(i, &efds)) { log_Printf(LogALERT, "Exception detected on descriptor %d\n", i); @@ -549,6 +548,7 @@ DoLoop(struct bundle *bundle, struct prompt *prompt) if (descriptor_IsSet(&bundle->desc, &rfds)) descriptor_Read(&bundle->desc, bundle, &rfds); + } while (bundle_CleanDatalinks(bundle), !bundle_IsDead(bundle)); log_Printf(LogDEBUG, "DoLoop done.\n"); diff --git a/usr.sbin/ppp/modem.c b/usr.sbin/ppp/modem.c index 6a05653..1b7f6ee 100644 --- a/usr.sbin/ppp/modem.c +++ b/usr.sbin/ppp/modem.c @@ -17,7 +17,7 @@ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. * - * $Id: modem.c,v 1.82 1998/05/21 22:55:08 brian Exp $ + * $Id: modem.c,v 1.83 1998/05/23 22:24:44 brian Exp $ * * TODO: */ @@ -954,6 +954,8 @@ modem_DescriptorRead(struct descriptor *d, struct bundle *bundle, log_WritePrompts(p->dl, rbuff, cp - rbuff); log_WritePrompts(p->dl, "\r\n", 2); } + log_Printf(LogPHASE, "%s: PPP packet detected, coming up\n", + p->link.name); datalink_Up(p->dl, 0, 1); } else log_WritePrompts(p->dl, rbuff, n); @@ -1030,6 +1032,7 @@ iov2modem(struct datalink *dl, struct iovec *iov, int *niov, int maxiov, int fd) modem_StartTimer(dl->bundle, p); } /* Don't need to lock the device in -direct mode */ + /* XXX: What if it's not a -direct link ! */ return p; } @@ -1048,7 +1051,8 @@ modem2iov(struct physical *p, struct iovec *iov, int *niov, int maxiov) timer_Stop(&p->link.ccp.fsm.StoppedTimer); if (p->Timer.state != TIMER_STOPPED) { timer_Stop(&p->Timer); - p->Timer.state = TIMER_RUNNING; /* Special - see iov2modem() */ + if (!physical_IsATTY(p) || p->fd != STDIN_FILENO) + p->Timer.state = TIMER_RUNNING; /* Special - see iov2modem() */ } timer_Stop(&p->link.throughput.Timer); } diff --git a/usr.sbin/ppp/mp.c b/usr.sbin/ppp/mp.c index 429a01a..65ccfc0 100644 --- a/usr.sbin/ppp/mp.c +++ b/usr.sbin/ppp/mp.c @@ -23,7 +23,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: mp.c,v 1.4 1998/05/23 17:05:28 brian Exp $ + * $Id: mp.c,v 1.5 1998/05/23 22:24:46 brian Exp $ */ #include <sys/types.h> @@ -861,7 +861,6 @@ mpserver_UpdateSet(struct descriptor *d, fd_set *r, fd_set *w, fd_set *e, result -= datalink_RemoveFromSet(s->send.dl, r, w, e); bundle_SendDatalink(s->send.dl, s->fd, &s->socket); s->send.dl = NULL; - close(s->fd); s->fd = -1; } else /* Never read from a datalink that's on death row ! */ @@ -899,8 +898,8 @@ mpserver_Read(struct descriptor *d, struct bundle *bundle, const fd_set *fdset) if (in.sa_family == AF_LOCAL) bundle_ReceiveDatalink(bundle, fd, (struct sockaddr_un *)&in); - - close(fd); + else + close(fd); } static void @@ -994,7 +993,6 @@ mpserver_Close(struct mpserver *s) if (s->send.dl != NULL) { bundle_SendDatalink(s->send.dl, s->fd, &s->socket); s->send.dl = NULL; - close(s->fd); s->fd = -1; } else if (s->fd >= 0) { close(s->fd); |