diff --git a/usr.sbin/ppp/bundle.c b/usr.sbin/ppp/bundle.c index 047a4636fc0..0bb9c7d1638 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 @@ -41,11 +41,13 @@ #include #include #include +#include #include #include #include #include #include +#include #include #include @@ -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 655fc0a5042..a41e93b79a1 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 @@ -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 d687aa4140a..f45a388cd98 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 6a05653996d..1b7f6eeb767 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 429a01a06dc..65ccfc0e521 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 @@ -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);