#! /bin/sh # This is a shell archive. Remove anything before this line, then unpack # it by saving it into a file and typing "sh file". To overwrite existing # files, type "sh file -c". You can also feed this as standard input via # unshar, or by typing "sh 'README' <<'END_OF_FILE' X X S R I A L P O P -- POP over serial lines X (sccs info README 1.4 93/06/21) X X Author: Rudi van Houten X Ac.Comp.Centr.Utrecht (Netherlands) X With thanks to: X Steve Dorner X Scott Hannahs X Mogen Trab Damsgaard X X Version 1.0 11 dec '91 X Version 1.1 nov '92 (never released) X Version 1.2 8 jun '93 X Version 1.3 15 jun '93 X X The Macintosh POPmail client Eudora offers a possibility X to perform the POP and SMTP conversations over a serial X (dialup) connection. Therefore is needed a 'psuedo-account' X on a machine where Eudora can login. That account must have X permission to execute senndmail and popper, not only local X but also remote (via rsh) on all machines where a popserver X or smtpserver must be contacted. Eudora is secretive with X the password while showing its progress (if properly X configured), but nobody can prevent a curious Macontosh X owner from looking with ResEdit (or alike's). It can be a X security leak. X The same considerations apply to the IBM-PC client NUPop X that also can use serial tty-lines to acquire mail. X X This program srialpop is written to take care of these X trade off's. It must be used as the pseudo-account's X loginshell. The commands which are recognized by the X program are 'logout' and 'exit' (to finish the session X of course) and 'telnet ...' which performs X a TCP/IP connection with the indicated host/port. The X supplied portnumber is checked against a list of valid X portnumbers (now only POP and SMTP). X All other commands cause an exit with errormessage. X X So the pseudo-account doesn't need permissions to run X popper and sendmail, neither needed are permissions to X run rsh to another machine or let another machine rsh X in. And a diligent POPmail user who tries to login on X the psuedo-account will discover that there is no fun. X X The program is straightforward and rather simple, and X it is free. Yet I claim a copyright, with which I mean X that anybody who feels a need to change (parts of) this X program is under the obligation to document the changes X and the need thereof in the program distribution files. X Neither may this program be selled (as if anybody would X buy this gadget), or distributed for a fee that extends X a reasonable retribution for the 8k it occupies on disk X or other media (I don't ask money, why should you). X I have tested the program for some time now and found no X bugs/problems. That doeesn't mean of course there are not. X I offer this program free for everyone to use because I X think it can be useful and is less dangerous then the X shellscript originally suggested by Steve Dorner. But if X you stumble over an error I am in no way responsible for X the damage that can cause, however I don't expect disasters. X I should welcome (by email) any notification of changes, X corrections and enhancements in the form of the new program X source or a diff. X X At A.C.C.U. we rent POP mailboxes to users as a special cheap X service. The users who obtain that service can only use email X via the POP/SMTP mechanism. The owner of a POPmail account X can not do any work on the UNIX machine, only change his/her X password (their login shell is a script that consists of a X call to /bin/passwd), and they don't need a home directory. X Hence the service can be cheap. X X The passwd entry for pseudo-user srialpop is: X (splitted for layout reasons) X srialpop:passwd:uid:gid:POP dialup dummy account:\ X /home/srialpop:/home/srialpop/srialpop X X The passwd entry for a POPmail account: X popuser:passwd:uid:gid:POPmailuser:/home/srialpop:/usr/local/etc/chpw X X And the script /usr/local/etc/chpw used as their loginshell: X #!/bin/sh X exec /bin/passwd X X (Or place /bin/passwd as "loginshell" in /etc/passwd) X X Rudi van Houten X Ac.Comp.Centr.Utrecht X Budapestlaan 6 X 3584 CD Utrecht Netherlands X X ******************** X Known bugs: X X **NOTE for NUPop users ** X If srialpop is used the end-of-line indicator must be set X to "^M^J" in the "Options -> Serial" menu of NUPop. X **** X X There are some quirks with end-of-line definitions. X TCP/IP requires CR-LF (according to the RFC's), but I X never encountered a TCP/IP connection that was not satisfied X with only LF. X Someone reported that his system produced and accepted an X end-of-line consisting of LF-CR, I didn't save the mails and X forgot the details. X When using public datanet systems (as X.25 in Europe) there X can be a problem that X.25 considers CR as end-of-packet and X the LF that is sent thereafter by the UNIX-system or POP-client X is then considered as the start of a new packet, that never is X closed. When I will have some time to spare I will look at that, X but perhaps someone else will find a solution earlier (I expect X it can be solved by setting appropriate LF-CR translations in X srialpop and defining a single CR as end-of-line in Eudora/NUPop). X X X Program history: X 9 dec 91 original version, only installed at ACCU X The distribution contains one file 'srialpop.c' X 11 dec 91 some changes in IO-handling after Steve Dorner X viewed the program and made some sugeestions X - V1.0- X 18 aug 92 added port 105 for PH service X 20 Oct 92 changes for conditional compilation on Silicon X Graphics sent in by Scott Hannahs X X - V1.1- X 22 Nov 92 added a wait time before exit to satisfy the X Macintosh CTB Hayes Modem Tool. X added port 106 for password service X Introduce the use of a make to enable simple X definitions of symbols. X 14 dec 92 added exclusion of tab expansion X (Mogen Trab Damsgaard ) X - V1.2- X 8 June 93 now change the terminal settings for the whole X life of the program. Read the commands in blocks X of one character and do the echo from the program. X - V1.3- X 15 June 93 V1.2 did send the second character of CR-LF (or X LF-CR) line-end from the telnet command to the X connected server via the socket. This character X is now catched and thrown away. Some popservers X couldn't handle this, but I didn't see this X since popper did not have troubles. X XThis version of srialpop has been successfully tested on: XConvex OS 10.1 XDEC (Philips) P9070 ATT SYS V/68 R3V6 X XOn the next systems it compiles OK and seems to work when the Xtty-session is emulated on keyboard input via a telnet login, but Xit has NOT been actually tried out. XSGI IRIX System V.3 XSUN SPARC OS 4.1.3 END_OF_FILE if test 7010 -ne `wc -c <'README'`; then echo shar: \"'README'\" unpacked with wrong size! fi # end of 'README' fi if test -f 'Makefile' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'Makefile'\" else echo shar: Extracting \"'Makefile'\" \(1689 characters\) sed "s/^X//" >'Makefile' <<'END_OF_FILE' X# Version 1.1 Makefile 1.4 93/06/21 X# X# Makefile to compile and install srialpop X# the installation will place the program in the directory defined X# with symbol DEST, default the home directory of the user ${SRIALPOP}. X# Also a .hushlogin, .cshrc, .login and .profile are created there. X# The user ${SRIALPOP} is asumed to be configured to login with X# the program srialpop as "loginshell". X X#DEST= /home/srialpop XDEST= /usr/people/local/srialpop XSRIALPOP= srialpop XGROUP= mailusr X X# use this on Convexes and Suns: X#DEFS= X#LDFLAGS= X# use this on Silicon Graphics IRIX systems: XDEFS= -DSYSV -ansi XLDFLAGS= -lc_s -s X# use this on not above mentioned Unix System V (e.g. ULTRIX, SysV/68) X#DEFS= -DSYSV X#LDFLAGS= X X# On some systems it can be needed to enable or disable some X# tty-flags (e.g. X-on/X-off). This can be done by defining X# the symbol EXTRATTYFLAGS on the next line and writing code X# in routine extrattyflags situated in file srialpop.c just X# after the __STDC__ declarations. X# The code that is there now sets X-on/X-off, but will not X# be used since EXTRATTYFLAGS is not defined. X#CFLAGS= -O ${DEFS} -DEXTRATTYFLAGS XCFLAGS= -O ${DEFS} X Xsrialpop: srialpop.o X ${CC} $? ${LDFLAGS} -o $@ X Xinstall: srialpop X strip srialpop X mv srialpop ${DEST} X chgrp ${GROUP} ${DEST}/srialpop X chmod 511 ${DEST}/srialpop X touch ${DEST}/.hushlogin X echo "exit" > ${DEST}/.login X -ln ${DEST}/.login ${DEST}/.cshrc X -ln ${DEST}/.login ${DEST}/.profile X rm -f ${DEST}/.forward X chmod 644 ${DEST}/.hushlogin ${DEST}/.login X Xclean: X rm -f core srialpop *.o srialpop.shar X Xshar: srialpop.shar X shar README Makefile srialpop.c > srialpop.shar X Xsrialpop.shar: README Makefile srialpop.c END_OF_FILE if test 1689 -ne `wc -c <'Makefile'`; then echo shar: \"'Makefile'\" unpacked with wrong size! fi # end of 'Makefile' fi if test -f 'srialpop.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'srialpop.c'\" else echo shar: Extracting \"'srialpop.c'\" \(7122 characters\) sed "s/^X//" >'srialpop.c' <<'END_OF_FILE' X/* X X S R I A L P O P (POP over serial lines) X X Author: Rudi van Houten X Ac.Comp.Centr.Utrecht (Netherlands) X With thanks to: X Steve Dorner X Scott Hannahs X Mogen Trab Damsgaard X X see the file README for an introduction and hints for installation X X*/ Xstatic char sccsid[]= "@(#)srialpop.c 1.3"; X X#define LOGOUTGRACE 3 X/* X this is the time to wait (seconds) after a logout command before X actually breaking the connection X*/ X X#include X#include X#include X#include X#include X#include X#include X#include X#ifdef SYSV X#define bcopy(a,b,c) memcpy(b,a,c) X#include X#else X#include X#endif X#if __STDC__==1 X#include X#else X#include X#endif X X#define CRLF "\r\n" X X#define iBuflen 512 Xstatic char sBuf[iBuflen]; X Xstatic short iValidPort[]= X {25 /* SMTP */ X ,105 /* PH server */ X ,106 /* password server */ X ,109 /* POP2 */ X ,110 /* POP3 */ X }; X#define iValidPortsCount sizeof(iValidPort)/sizeof(short) X X#ifdef SYSV Xstatic struct termio sTermHold, sTermCurr; X#else Xstatic struct sgttyb sTermHold, sTermCurr; X#endif X X#if __STDC__==1 Xstatic void errorexit(char*, ... ); Xvoid main(void); X# ifdef EXTRATTYFLAGS Xstatic void extrattyflags(void); X# endif X#endif X X#ifdef EXTRATTYFLAGS Xstatic void extrattyflags() X{ X/* X * here code can be placed to add/clear extra flags in X * the tty discipline descriptions X * here is an example that Scott Hannahs used on SGI X */ XsTermCurr.c_iflag |= (IXON | IXOFF); Xreturn; X} /* void extrattyflags */ X#endif X X#if __STDC__==1 Xstatic void errorexit(char *sFormat, ...) X{ X#else Xstatic void errorexit(va_alist) va_dcl X{ X char *sFormat; X#endif X va_list ap; X fputs(CRLF,stderr); X#if __STDC__==1 X va_start(ap,sFormat); X#else X va_start(ap); X sFormat= va_arg(ap,char*); X#endif X vfprintf(stderr,sFormat,ap); X va_end(ap); X fputs(CRLF,stderr); X#ifdef SYSV X ioctl(0,TCSETAF,&sTermHold); X#else X ioctl(0,TIOCSETP,&sTermHold); X#endif X sleep(1); exit(1); X} /* errorexit */ X Xvoid main() X{ Xint iSock, iPort, iChild; Xregister int i, l; Xstruct in_addr sInAddr; Xstruct sockaddr_in sServer; Xstruct hostent *psHost, *gethostbyname(), *gethostbyaddr(); Xchar *psCommand, *psName, *psNumber; X X /* get stty structure sTermHold */ X#ifdef SYSV Xioctl(0,TCGETA,&sTermHold); X#else Xioctl(0,TIOCGETP,&sTermHold); X#endif Xbcopy(&sTermHold,&sTermCurr,sizeof(sTermCurr)); X /* and here prepare the line characteristics */ X#ifdef SYSV XsTermCurr.c_iflag &= ~(ICRNL | IXANY); XsTermCurr.c_oflag &= ~OPOST; XsTermCurr.c_lflag &= ~(ECHO | ICANON | ISIG ); XsTermCurr.c_cc[VMIN] = 1; XsTermCurr.c_cc[VTIME] = 0; X#else XsTermCurr.sg_flags &= ~(ECHO | CRMOD | XTABS); XsTermCurr.sg_flags |= CBREAK; X#endif X#ifdef EXTRATTYFLAGS Xextrattyflags(); X#endif X /* set line characteristics to NOECHO, NOCRLF etc. */ X#ifdef SYSV Xioctl(0,TCSETAF,&sTermCurr); X#else Xioctl(0,TIOCSETP,&sTermCurr); X#endif X X X/* this is the main loop, it reads the telnet or exit commandline */ Xfor (;;) X{ X write(1,"%",1); l= 0; X while(read(0,&sBuf[l],1) == 1 && sBuf[l] != '\n' && sBuf[l] != '\r') X { X write(1,&sBuf[l],1); X if (++l >= iBuflen) errorexit("Too long commandline",0); X } X if (sBuf[l] == '\n' || sBuf[l] == '\r') sBuf[l]= '\0'; else sBuf[++l]= '\0'; X if (l == 0) continue; X write(1,CRLF,2); X X if (strcmp(sBuf,"logout") == 0 X || strcmp(sBuf,"exit") == 0 X || strcmp(sBuf,"quit") == 0 X ) X break; /* finished, logout now */ X X /* next loop splits the commandline in its constituents */ X i= 0; psCommand= psName= psNumber= NULL; X while (i < l && psNumber == NULL) X { X while (isspace(sBuf[i])) i++; X if (i >= l) break; X if (psCommand == NULL) psCommand= &sBuf[i]; /* command found */ X else X if (psName == NULL) psName= &sBuf[i]; /* argument 1 */ X else psNumber= &sBuf[i]; /* argument 2 */ X do { i++; } while (!isspace(sBuf[i]) && i < l); X sBuf[i++]= '\0'; /* terminator after last argument */ X } X /* now we have a command (telnet) with two X arguments (1=host 2=portnumber) */ X X if (strcmp(psCommand,"telnet")) X errorexit("Sorry, don't know '%s'\n",psCommand); X /* telnet is the only known command */ X X if (psName == NULL || psNumber == NULL) X errorexit("Sorry, hostname or portnumber missing\n",0); X /* and both host and port are required */ X X if (l= strlen(psNumber)) X { X for (i= 0; i < l; i++) X if (!isdigit(psNumber[i])) X errorexit("Portnumber (%s) not numeric\n",psNumber); X iPort= atoi(psNumber); X } X else iPort= 0; X X /* check validity of portnumber */ X for (i=0; iPort != iValidPort[i]; i++) X if (i == iValidPortsCount) X errorexit("Sorry, %d is not a valid port\n",iPort); X X /* X (unsigned long)(-1) = 0xffffffff, returnvalue X from inet_addr() if illegal address passed through. X I assume then it is a domain name. X Thanks to Edwin Kremer (edwin@cs.ruu.nl) for the trick X */ X if ((sInAddr.s_addr= inet_addr(psName)) == 0xffffffff) X psHost= gethostbyname(psName); X else X psHost= gethostbyaddr((char*)&sInAddr,sizeof(struct in_addr),AF_INET); X if (psHost == 0) X errorexit("Cannot find server %s (host unknown)\n",psName); X X /* create socket */ X if ((iSock= socket(AF_INET,SOCK_STREAM,0)) < 0) X { perror("Cannot open IP socket"); exit(1); } X X /* fill socket structure .....*/ X sServer.sin_family= AF_INET; X bcopy(psHost->h_addr,&(sServer.sin_addr),psHost->h_length); X sServer.sin_port= htons(iPort); X X /*........and connect */ X if (connect(iSock,&sServer,sizeof(sServer)) < 0) X { perror("connecting stream socket"); exit(1); } X X /* now fork a child to copy stdin to socket */ X iChild= fork(); X if (iChild < 0) { perror("Cannot fork"); exit(1); } X if (iChild == 0) X { /* the child copies stdin to the socket */ X close(1); close(2); /* now close stdout and stderr */ X if (read(0,sBuf,1) == 1) X { X if (sBuf[0] != '\r' && sBuf[0] != '\n') write(iSock,sBuf,1); X while ((l= read(0,sBuf,iBuflen)) > 0) write(iSock,sBuf,l); X } X close(0); exit(0); X } /* if (iChild == 0) */ X /* no else part, child does exit X the parent copies the socket to stdout X */ X while ((l= read(iSock,sBuf,iBuflen)) > 0) write(1,sBuf,l); X close(iSock); X X kill(iChild,SIGTERM); /* superfluous */ X X} /* main loop */ X X /* reset line characteristics */ X#ifdef SYSV Xioctl(0,TCSETAF,&sTermHold); X#else Xioctl(0,TIOCSETP,&sTermHold); X#endif X Xsleep(LOGOUTGRACE); /* wait to satisfy Mac's Hayes Modem Tool */ Xclose(0); close(1); close(2); Xexit(0); X} /* main */ END_OF_FILE if test 7122 -ne `wc -c <'srialpop.c'`; then echo shar: \"'srialpop.c'\" unpacked with wrong size! fi # end of 'srialpop.c' fi echo shar: End of shell archive. exit 0