From: Marc Horowitz Date: Thu, 22 Oct 1998 06:44:11 +0000 (+0000) Subject: intermediate commit with inband protocol coded, but old-style OOB still running and... X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=1bb31f781ff62085bb35583873521791390d5e3f;p=thirdparty%2Fkrb5.git intermediate commit with inband protocol coded, but old-style OOB still running and working git-svn-id: svn://anonsvn.mit.edu/krb5/branches/marc-3des@10979 dc483132-0cff-0310-8789-dd5450dbe970 --- diff --git a/src/appl/bsd/krlogin.c b/src/appl/bsd/krlogin.c index 6471f2b00b..eb844b2971 100644 --- a/src/appl/bsd/krlogin.c +++ b/src/appl/bsd/krlogin.c @@ -180,6 +180,7 @@ char *getenv(); char *name; int rem = -1; /* Remote socket fd */ +int do_inband = 0; char cmdchar = '~'; int eight = 1; /* Default to 8 bit transmission */ int no_local_escape = 0; @@ -224,6 +225,7 @@ char *host=0; /* external, so it can be reached from confirm_death() */ krb5_sigtype sigwinch KRB5_PROTOTYPE((int)); +int server_message KRB5_PROTOTYPE((int)); void oob KRB5_PROTOTYPE((void)); krb5_sigtype lostpeer KRB5_PROTOTYPE((int)); #if __STDC__ @@ -1190,15 +1192,16 @@ int rcvcnt; int rcvstate; int ppid; +/* returns 1 if flush, 0 otherwise */ -void oob() +int server_message(mark) + int mark; { #ifndef POSIX_TERMIOS int out = FWRITE; #endif - int atmark, n; + int n; int rcvd = 0; - char waste[RLOGIN_BUFSIZ], mark; #ifdef POSIX_TERMIOS struct termios tty; #else @@ -1208,10 +1211,6 @@ void oob() struct sgttyb sb; #endif #endif - mark = 0; - - recv(rem, &mark, 1, MSG_OOB); - if (mark & TIOCPKT_WINDOW) { /* @@ -1270,28 +1269,62 @@ void oob() (void) ioctl(1, TCFLSH, 1); #endif #endif - for (;;) { - if (ioctl(rem, SIOCATMARK, &atmark) < 0) { - perror("ioctl"); - break; - } - if (atmark) - break; - n = read(rem, waste, sizeof (waste)); - printf("tossed %d bytes\n", n); - if (n <= 0) - break; -return; - } + return(1); } + + return(0); +} + +void oob() +{ + char mark; + char waste[RLOGIN_BUFSIZ]; + int atmark; + + mark = 0; - + recv(rem, &mark, 1, MSG_OOB); + + if (server_message(mark)) { + if (ioctl(rem, SIOCATMARK, &atmark) < 0) { + perror("ioctl"); + return; + } + if (!atmark) + read(rem, waste, sizeof (waste)); + } } +/* two control messages are defined: + + a double flag byte of 'o' indicates a one-byte message which is + identical to what was once carried out of band. + + a double flag byte of 'q' indicates a zero-byte message. This + message is interpreted as two \377 data bytes. This is just a + quote rule so that binary data from the server does not confuse the + client. */ +int control(cp, n) + unsigned char *cp; + int n; +{ + if ((n >= 5) && (cp[2] == 'o') && (cp[3] == 'o')) { + if (server_message(cp[4])) + return(-5); + return(5); + } else if ((n >= 4) && (cp[2] == 'q') && (cp[3] == 'q')) { + /* this is somewhat of a hack */ + cp[2] = '\377'; + cp[3] = '\377'; + return(2); + } + + return(0); +} /* - * reader: read from remote: line -> 1 + * reader: read from remote: line -> 1 */ reader(oldmask) #ifdef POSIX_SIGNALS @@ -1306,8 +1339,9 @@ reader(oldmask) int pid = -getpid(); #endif fd_set readset, excset, writeset; - int n, remaining; + int n, remaining, left; char *bufp = rcvbuf; + char *cp; #ifdef POSIX_SIGNALS struct sigaction sa; @@ -1334,24 +1368,23 @@ fd_set readset, excset, writeset; #endif /* POSIX_SIGNALS */ for (;;) { - if ((remaining = rcvcnt - (bufp - rcvbuf)) > 0) - { + if ((remaining = rcvcnt - (bufp - rcvbuf)) > 0) { FD_SET(1,&writeset); rcvstate = WRITING; FD_CLR(rem, &readset); + } else { + bufp = rcvbuf; + rcvcnt = 0; + rcvstate = READING; + FD_SET(rem,&readset); + FD_CLR(1,&writeset); } - else { - - bufp = rcvbuf; - rcvcnt = 0; - rcvstate = READING; - FD_SET(rem,&readset); - FD_CLR(1,&writeset); - } - FD_SET(rem,&excset); + if (!do_inband) + FD_SET(rem,&excset); if (select(rem+1, &readset, &writeset, &excset, 0) > 0 ) { - if (FD_ISSET(rem, &excset)) - oob(); + if (!do_inband) + if (FD_ISSET(rem, &excset)) + oob(); if (FD_ISSET(1,&writeset)) { n = write(1, bufp, remaining); if (n < 0) { @@ -1362,18 +1395,35 @@ fd_set readset, excset, writeset; bufp += n; } if (FD_ISSET(rem, &readset)) { - { - int x; - - if (!ioctl(rem, FIONREAD, &x)); - - } - rcvcnt = rcmd_stream_read(rem, rcvbuf, sizeof (rcvbuf)); if (rcvcnt == 0) return (0); if (rcvcnt < 0) goto error; + + if (do_inband) { + for (cp = rcvbuf; cp < rcvbuf+rcvcnt-1; cp++) { + if (cp[0] == '\377' && + cp[1] == '\377') { + left = (rcvbuf+rcvcnt) - cp; + n = control(cp, left); + if (n < 0) { + left -= (-n); + rcvcnt = 0; + /* flush before, and (-n) bytes */ + if (left > 0) + memmove(rcvbuf, cp+(-n), left); + cp = rcvbuf-1; + } else if (n) { + left -= n; + rcvcnt -= n; + if (left > 0) + memmove(cp, cp+n, left); + cp--; + } + } + } + } } } else error: diff --git a/src/appl/bsd/krlogind.c b/src/appl/bsd/krlogind.c index bd376ff098..16d044c6a4 100644 --- a/src/appl/bsd/krlogind.c +++ b/src/appl/bsd/krlogind.c @@ -266,6 +266,7 @@ char *krusername = 0; char term[64]; char rhost_name[128]; krb5_principal client; +int do_inband = 0; int reapchild(); char *progname; @@ -837,6 +838,31 @@ unsigned char oobdata[] = {TIOCPKT_WINDOW}; char oobdata[] = {0}; #endif +int sendoob(fd, byte) + int fd; + char *byte; +{ + char message[5]; + int cc; + + if (do_inband) { + message[0] = '\377'; + message[1] = '\377'; + message[2] = 'o'; + message[3] = 'o'; + message[4] = *byte; + + cc = rcmd_stream_write(fd, message, sizeof(message)); + while (cc < 0 && ((errno == EWOULDBLOCK) || (errno == EAGAIN))) { + /* also shouldn't happen */ + sleep(5); + cc = rcmd_stream_write(fd, message, sizeof(message)); + } + } else { + send(fd, byte, 1, MSG_OOB); + } +} + /* * Handle a "control" request (signaled by magic being present) * in the data stream. For now, we are only willing to handle @@ -880,7 +906,7 @@ int control(pty, cp, n) void protocol(f, p) int f, p; { - unsigned char pibuf[BUFSIZ], fibuf[BUFSIZ], *pbp, *fbp; + unsigned char pibuf[BUFSIZ], qpibuf[BUFSIZ*2], fibuf[BUFSIZ], *pbp, *fbp; register pcc = 0, fcc = 0; int cc; char cntl; @@ -915,7 +941,7 @@ void protocol(f, p) signal(SIGTTOU, SIG_IGN); #endif #ifdef TIOCSWINSZ - send(f, oobdata, 1, MSG_OOB); /* indicate new rlogin */ + sendoob(f, oobdata); #endif for (;;) { fd_set ibits, obits, ebits; @@ -933,7 +959,6 @@ void protocol(f, p) FD_SET(f, &obits); else FD_SET(p, &ibits); - FD_SET(p, &ebits); if (select(8*sizeof(ibits), &ibits, &obits, &ebits, 0) < 0) { if (errno == EINTR) @@ -941,43 +966,32 @@ void protocol(f, p) fatalperror(f, "select"); } #define pkcontrol(c) ((c)&(TIOCPKT_FLUSHWRITE|TIOCPKT_NOSTOP|TIOCPKT_DOSTOP)) - if (FD_ISSET(p, &ebits)) { - cc = read(p, &cntl, 1); - if (cc == 1 && pkcontrol(cntl)) { - cntl |= oobdata[0]; - send(f, &cntl, 1, MSG_OOB); - if (cntl & TIOCPKT_FLUSHWRITE) { - pcc = 0; - FD_CLR(p, &ibits); - } - } - } if (FD_ISSET(f, &ibits)) { fcc = rcmd_stream_read(f, fibuf, sizeof (fibuf)); - if (fcc < 0 && ((errno == EWOULDBLOCK) || (errno == EAGAIN))) - fcc = 0; - else { + if (fcc < 0 && ((errno == EWOULDBLOCK) || (errno == EAGAIN))) { + fcc = 0; + } else { register unsigned char *cp; int left, n; if (fcc <= 0) - break; + break; fbp = fibuf; - top: - for (cp = fibuf; cp < fibuf+fcc-1; cp++) - if (cp[0] == magic[0] && - cp[1] == magic[1]) { - left = fcc - (cp-fibuf); - n = control(p, cp, left); - if (n) { - left -= n; - if (left > 0) - memmove(cp, cp+n, left); - fcc -= n; - goto top; /* n^2 */ - } - } + for (cp = fibuf; cp < fibuf+fcc-1; cp++) { + if (cp[0] == magic[0] && + cp[1] == magic[1]) { + left = (fibuf+fcc) - cp; + n = control(p, cp, left); + if (n) { + left -= n; + fcc -= n; + if (left > 0) + memmove(cp, cp+n, left); + cp--; + } + } + } } } @@ -992,24 +1006,54 @@ void protocol(f, p) if (FD_ISSET(p, &ibits)) { pcc = read(p, pibuf, sizeof (pibuf)); pbp = pibuf; - if (pcc < 0 && ((errno == EWOULDBLOCK) || (errno == EAGAIN))) - pcc = 0; - else if (pcc <= 0) - break; + if (pcc < 0 && ((errno == EWOULDBLOCK) || (errno == EAGAIN))) { + pcc = 0; + } else if (pcc <= 0) { + break; + } #ifdef TIOCPKT else if (tiocpkt_on) { - if (pibuf[0] == 0) - pbp++, pcc--; - else { - if (pkcontrol(pibuf[0])) { - pibuf[0] |= oobdata[0]; - send(f, &pibuf[0], 1, MSG_OOB); - } - pcc = 0; - } + if (pibuf[0] == 0) { + pbp++, pcc--; + } else { + if (pkcontrol(pibuf[0])) { + pibuf[0] |= oobdata[0]; + sendoob(f, pibuf); + } + pcc = 0; + } } #endif + + /* quote any double-\377's if necessary */ + + if (do_inband) { + unsigned char *qpbp; + int qpcc, i; + + qpbp = qpibuf; + qpcc = 0; + + for (i=0; i 0) { cc = rcmd_stream_write(f, pbp, pcc); if (cc < 0 && ((errno == EWOULDBLOCK) || (errno == EAGAIN))) {