home *** CD-ROM | disk | FTP | other *** search
- /* Subject: general purpose telnet server.
- This is a telnet bouncer that some people have expressed interest in.
- It's uses are utility and privacy related. It should compile easily on
- most OS's striaght out of it's wrapper as such.
-
- Mark
- mark@cairo.anu.edu.au
- */
- /* Name: ts2.c */
- /* Author: Hal-9000, Xanadude, Richard Stevens, Avalon, Mark */
- /* Distribution: Public */
- /* Copyright: Held by the respective contributors */
- /* Posted to USENET September '93 by Mark mark@cairo.anu.edu.au */
-
- /* This file was telserv.c, part of the Telnet Server package v. 1.0,
- written by "Hal-9000". Much of that package was developed by Richard
- Stephens and his thanks go to "Xanadude" for providing him with that
- section. Performance fix by Darren Reed. */
-
- /* Reworked to add concurrency, password checking and destination selection
- on the fly. - Mark 31st Aug 93
-
- Compiled and tested on:
- HPUX 9.01 9000/700 series NeXTStep 3.1 NeXT 68040
- OSx Pyramid 90x BSD universe SunOS 5.2 sun4c
- Ultrix 4.3 DEC RISC Linux 0.99.10 80486
-
- To compile, type "cc -O -s ts2.c -o ts2".
-
- MY_PASSWORD and SERV_TCP_PORT are all that is required to be altered. */
-
- #define MY_PASSWORD "bollox"
- #define SERV_TCP_PORT 9090 /* port I'll listen for connections on */
-
- #include <stdio.h>
- #include <sys/types.h>
- #include <sys/socket.h>
- #include <sys/time.h>
- #include <sys/resource.h>
- #include <sys/wait.h>
- #include <fcntl.h>
- #include <errno.h>
- #include <netinet/in.h>
- #include <netdb.h>
- #include <arpa/inet.h>
- #include <sys/ioctl.h>
-
- #define QLEN 5
-
- char sbuf[2048], cbuf[2048];
- extern int errno;
- extern char *sys_errlist[];
- void reaper();
- int main();
- void telcli();
-
- int main(argc, argv)
- int argc;
- char *argv[];
- {
- int srv_fd, rem_fd, rem_len, opt = 1;
- struct sockaddr_in rem_addr, srv_addr;
- #if !defined(SVR4) && !defined(POSIX) && !defined(linux) && !defined(__386BSD__) && !defined(hpux)
- union wait status;
- #else
- int status;
- #endif /* !defined(SVR4) */
-
- bzero((char *) &rem_addr, sizeof(rem_addr));
- bzero((char *) &srv_addr, sizeof(srv_addr));
- srv_addr.sin_family = AF_INET;
- srv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
- srv_addr.sin_port = htons(SERV_TCP_PORT);
- srv_fd = socket(PF_INET, SOCK_STREAM, 0);
- if (bind(srv_fd, (struct sockaddr *) &srv_addr, sizeof(srv_addr)) == -1) {
- perror("bind");
- exit(-1);
- }
- listen(srv_fd, QLEN);
- close(0); close(1); close(2);
- #ifdef TIOCNOTTY
- if ((rem_fd = open("/dev/tty", O_RDWR)) >= 0) {
- ioctl(rem_fd, TIOCNOTTY, (char *)0);
- close(rem_fd);
- }
- #endif
- if (fork()) exit(0);
- while (1) {
- rem_len = sizeof(rem_addr);
- rem_fd=accept(srv_fd, (struct sockaddr *) &rem_addr, &rem_len);
- if (rem_fd < 0) {
- if (errno == EINTR) continue;
- exit(-1);
- }
- switch(fork()) {
- case 0: /* child process */
- close(srv_fd); /* close original socket */
- telcli(rem_fd); /* process the request */
- close(rem_fd);
- exit(0);
- break;
- default:
- close(rem_fd); /* parent process */
- if (fork()) exit(0); /* let init worry about children */
- break;
- case -1:
- fprintf(stderr, "\n\rfork: %s\n\r", sys_errlist[errno]);
- break;
- }
- }
- }
-
- void telcli(source)
- int source;
- {
- int dest;
- int found;
- struct sockaddr_in sa;
- struct hostent *hp;
- struct servent *sp;
- char gethost[100];
- char getport[100];
- char string[100];
-
- bzero(gethost, 100);
- sprintf(string, "Password: ");
- write(source, string, strlen(string));
- read(source, gethost, 100);
- gethost[(strlen(gethost)-2)] = '\0'; /* kludge alert - kill the \r\n */
- if (strcmp(gethost, MY_PASSWORD) != 0) {
- sprintf(string, "Wrong password, got %s.\n", gethost);
- write(source, string, strlen(string));
- close(source);
- exit(0);
- }
- do {
- found = 0;
- bzero(gethost,100);
- sprintf(string, "Host: ");
- write(source, string, strlen(string));
- read(source, gethost, 100);
- gethost[(strlen(gethost)-2)] = '\0';
- hp = gethostbyname(gethost);
- if (hp) {
- found++;
- #if !defined(h_addr) /* In 4.3, this is a #define */
- #if defined(hpux) || defined(NeXT) || defined(ultrix) || defined(POSIX)
- memcpy((caddr_t)&sa.sin_addr, hp->h_addr_list[0], hp->h_length);
- #else
- bcopy(hp->h_addr_list[0], &sa.sin_addr, hp->h_length);
- #endif
- #else /* defined(h_addr) */
- #if defined(hpux) || defined(NeXT) || defined(ultrix) || defined(POSIX)
- memcpy((caddr_t)&sa.sin_addr, hp->h_addr, hp->h_length);
- #else
- bcopy(hp->h_addr, &sa.sin_addr, hp->h_length);
- #endif
- #endif /* defined(h_addr) */
- sprintf(string, "Found address for %s\n", hp->h_name);
- write(source, string, strlen(string));
- } else {
- if (inet_addr(gethost) == -1) {
- found = 0;
- sprintf(string, "Didnt find address for %s\n", gethost);
- write(source, string, strlen(string));
- } else {
- found++;
- sa.sin_addr.s_addr = inet_addr(gethost);
- }
- }
- } while (!found);
- sa.sin_family = AF_INET;
- sprintf(string, "Port: ");
- write(source, string, strlen(string));
- read(source, getport, 100);
- gethost[(strlen(getport)-2)] = '\0';
- sa.sin_port = htons((unsigned) atoi(getport));
- if (sa.sin_port == 0) {
- sp = getservbyname(getport, "tcp");
- if (sp)
- sa.sin_port = sp->s_port;
- else {
- sprintf(string, "%s: bad port number\n", getport);
- write(source, string, strlen(string));
- return;
- }
- }
- sprintf(string, "Trying %s...\n", (char *) inet_ntoa(sa.sin_addr));
- write(source, string, strlen(string));
- if ((dest = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
- perror("telcli: socket");
- exit(1);
- }
- connect(dest, (struct sockaddr *) &sa, sizeof(sa));
- sprintf(string, "Connected to %s port %d...\n", inet_ntoa(sa.sin_addr),
- ntohs(sa.sin_port));
- write(source, string, strlen(string));
- #ifdef FNDELAY
- fcntl(source,F_SETFL,fcntl(source,F_GETFL,0)|FNDELAY);
- fcntl(dest,F_SETFL,fcntl(dest,F_GETFL,0)|FNDELAY);
- #else
- fcntl(source,F_SETFL,O_NDELAY);
- fcntl(dest,F_SETFL,O_NDELAY);
- #endif
- communicate(dest,source);
- close(dest);
- exit(0);
- }
-
- communicate(sfd,cfd) {
- char *chead, *ctail, *shead, *stail;
- int num, nfd, spos, cpos;
- extern int errno;
- fd_set rd, wr;
-
- chead = ctail = cbuf;
- cpos = 0;
- shead = stail = sbuf;
- spos = 0;
- while (1) {
- FD_ZERO(&rd);
- FD_ZERO(&wr);
- if (spos < sizeof(sbuf)-1) FD_SET(sfd, &rd);
- if (ctail > chead) FD_SET(sfd, &wr);
- if (cpos < sizeof(cbuf)-1) FD_SET(cfd, &rd);
- if (stail > shead) FD_SET(cfd, &wr);
- nfd = select(256, &rd, &wr, 0, 0);
- if (nfd <= 0) continue;
- if (FD_ISSET(sfd, &rd)) {
- num=read(sfd,stail,sizeof(sbuf)-spos);
- if ((num==-1) && (errno != EWOULDBLOCK)) return;
- if (num==0) return;
- if (num>0) {
- spos += num;
- stail += num;
- if (!--nfd) continue;
- }
- }
- if (FD_ISSET(cfd, &rd)) {
- num=read(cfd,ctail,sizeof(cbuf)-cpos);
- if ((num==-1) && (errno != EWOULDBLOCK)) return;
- if (num==0) return;
- if (num>0) {
- cpos += num;
- ctail += num;
- if (!--nfd) continue;
- }
- }
- if (FD_ISSET(sfd, &wr)) {
- num=write(sfd,chead,ctail-chead);
- if ((num==-1) && (errno != EWOULDBLOCK)) return;
- if (num>0) {
- chead += num;
- if (chead == ctail) {
- chead = ctail = cbuf;
- cpos = 0;
- }
- if (!--nfd) continue;
- }
- }
- if (FD_ISSET(cfd, &wr)) {
- num=write(cfd,shead,stail-shead);
- if ((num==-1) && (errno != EWOULDBLOCK)) return;
- if (num>0) {
- shead += num;
- if (shead == stail) {
- shead = stail = sbuf;
- spos = 0;
- }
- if (!--nfd) continue;
- }
- }
- }
- }
-
-
-