X-Git-Url: https://git.subgeniuskitty.com/unix-history/.git/blobdiff_plain/9b9ae597599a0962e33d34948b933d380c2ee143..d43d1075666c90460941d74f5a568d29707cd540:/usr/src/usr.bin/tn3270/sys_curses/system.c?ds=inline diff --git a/usr/src/usr.bin/tn3270/sys_curses/system.c b/usr/src/usr.bin/tn3270/sys_curses/system.c index ef4394d0be..5ae20c0c53 100644 --- a/usr/src/usr.bin/tn3270/sys_curses/system.c +++ b/usr/src/usr.bin/tn3270/sys_curses/system.c @@ -1,4 +1,39 @@ +/* + * Copyright (c) 1988 Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms are permitted + * provided that the above copyright notice and this paragraph are + * duplicated in all such forms and that any documentation, + * advertising materials, and other materials related to such + * distribution and use acknowledge that the software was developed + * by the University of California, Berkeley. The name of the + * University may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#ifndef lint +static char sccsid[] = "@(#)system.c 4.1 (Berkeley) %G%"; +#endif /* not lint */ + #include + +#if defined(pyr) +#define fd_set fdset_t +#endif /* defined(pyr) */ + +#if !defined(sun) && !defined(pyr) +#include +#else /* !defined(sun) */ +#define IREAD 00400 +#define IWRITE 00200 +#endif /* !defined(sun) */ + +#include +#include #include #include #include @@ -12,13 +47,28 @@ extern int errno; #include #include "../general/general.h" -#include "../api/api.h" -#include "../apilib/api_exch.h" +#include "../ctlr/api.h" +#include "../api/api_exch.h" #include "../general/globals.h" +#ifndef FD_SETSIZE +/* + * The following is defined just in case someone should want to run + * this telnet on a 4.2 system. + * + */ + +#define FD_SET(n, p) ((p)->fds_bits[0] |= (1<<(n))) +#define FD_CLR(n, p) ((p)->fds_bits[0] &= ~(1<<(n))) +#define FD_ISSET(n, p) ((p)->fds_bits[0] & (1<<(n))) +#define FD_ZERO(p) ((p)->fds_bits[0] = 0) +#endif + static int shell_pid = 0; +static char key[50]; /* Actual key */ +static char *keyname; /* Name of file with key in it */ static char *ourENVlist[200]; /* Lots of room */ @@ -28,13 +78,15 @@ static int static enum { DEAD, UNCONNECTED, CONNECTED } state; +static long + storage_location; /* Address we have */ +static short + storage_length = 0; /* Length we have */ static int - storage_location, /* Address we have */ - storage_length = 0, /* Length we have */ storage_must_send = 0, /* Storage belongs on other side of wire */ storage_accessed = 0; /* The storage is accessed (so leave alone)! */ -static long storage[250]; +static long storage[1000]; static union REGS inputRegs; static struct SREGS inputSregs; @@ -60,20 +112,18 @@ nextstore() storage_length = 0; return -1; } - storage_length = ntohs(sd.length); - storage_location = ntohl(sd.location); + storage_length = sd.length; + storage_location = sd.location; if (storage_length > sizeof storage) { fprintf(stderr, "API client tried to send too much storage (%d).\n", storage_length); storage_length = 0; return -1; } - if (storage_length != 0) { - if (api_exch_intype(EXCH_TYPE_BYTES, storage_length, (char *)storage) - == -1) { - storage_length = 0; - return -1; - } + if (api_exch_intype(EXCH_TYPE_BYTES, storage_length, (char *)storage) + == -1) { + storage_length = 0; + return -1; } return 0; } @@ -86,10 +136,10 @@ char *message; struct storage_descriptor sd; int length = strlen(message); - if (api_exch_outcommand(EXCH_REJECTED) == -1) { + if (api_exch_outcommand(EXCH_CMD_REJECTED) == -1) { return -1; } - sd.length = htons(length); + sd.length = length; if (api_exch_outtype(EXCH_TYPE_STORE_DESC, sizeof sd, (char *)&sd) == -1) { return -1; } @@ -104,6 +154,12 @@ char *message; * doassociate() * * Negotiate with the other side and try to do something. + * + * Returns: + * + * -1: Error in processing + * 0: Invalid password entered + * 1: Association OK */ static int @@ -113,41 +169,15 @@ doassociate() char promptbuf[100], buffer[200]; - int length; - int was; struct storage_descriptor sd; + extern char *crypt(); - if ((pwent = getpwuid(geteuid())) == 0) { - return -1; - } - sprintf(promptbuf, "Enter password for user %s:", pwent->pw_name); - if (api_exch_outcommand(EXCH_SEND_AUTH) == -1) { - return -1; - } - sd.length = htons(strlen(promptbuf)); - if (api_exch_outtype(EXCH_TYPE_STORE_DESC, sizeof sd, (char *)&sd) == -1) { - return -1; - } - if (api_exch_outtype(EXCH_TYPE_BYTES, strlen(promptbuf), promptbuf) == -1) { - return -1; - } - sd.length = htons(strlen(pwent->pw_name)); - if (api_exch_outtype(EXCH_TYPE_STORE_DESC, sizeof sd, (char *)&sd) == -1) { - return -1; - } - if (api_exch_outtype(EXCH_TYPE_BYTES, - strlen(pwent->pw_name), pwent->pw_name) == -1) { - return -1; - } - if (api_exch_incommand(EXCH_AUTH) == -1) { - return -1; - } if (api_exch_intype(EXCH_TYPE_STORE_DESC, sizeof sd, (char *)&sd) == -1) { return -1; } - sd.length = ntohs(sd.length); + sd.length = sd.length; if (sd.length > sizeof buffer) { - doreject("Password entered was too long"); + doreject("(internal error) Authentication key too long"); return -1; } if (api_exch_intype(EXCH_TYPE_BYTES, sd.length, buffer) == -1) { @@ -155,30 +185,77 @@ doassociate() } buffer[sd.length] = 0; - /* Is this the correct password? */ - if (strlen(pwent->pw_name)) { - char *ptr; - int i; - - ptr = pwent->pw_name; - i = 0; - while (i < sd.length) { - buffer[i++] ^= *ptr++; - if (*ptr == 0) { - ptr = pwent->pw_name; - } + if (strcmp(buffer, key) != 0) { +#if (!defined(sun)) || defined(BSD) && (BSD >= 43) + extern uid_t geteuid(); +#endif /* (!defined(sun)) || defined(BSD) && (BSD >= 43) */ + + if ((pwent = getpwuid((int)geteuid())) == 0) { + return -1; } - } - if (strcmp(crypt(buffer, pwent->pw_passwd), pwent->pw_passwd) == 0) { - if (api_exch_outcommand(EXCH_ASSOCIATED) == -1) { + sprintf(promptbuf, "Enter password for user %s:", pwent->pw_name); + if (api_exch_outcommand(EXCH_CMD_SEND_AUTH) == -1) { + return -1; + } + sd.length = strlen(promptbuf); + if (api_exch_outtype(EXCH_TYPE_STORE_DESC, sizeof sd, (char *)&sd) + == -1) { + return -1; + } + if (api_exch_outtype(EXCH_TYPE_BYTES, strlen(promptbuf), promptbuf) + == -1) { + return -1; + } + sd.length = strlen(pwent->pw_name); + if (api_exch_outtype(EXCH_TYPE_STORE_DESC, sizeof sd, (char *)&sd) + == -1) { return -1; - } else { - return 1; } + if (api_exch_outtype(EXCH_TYPE_BYTES, + strlen(pwent->pw_name), pwent->pw_name) == -1) { + return -1; + } + if (api_exch_incommand(EXCH_CMD_AUTH) == -1) { + return -1; + } + if (api_exch_intype(EXCH_TYPE_STORE_DESC, sizeof sd, (char *)&sd) + == -1) { + return -1; + } + sd.length = sd.length; + if (sd.length > sizeof buffer) { + doreject("Password entered was too long"); + return -1; + } + if (api_exch_intype(EXCH_TYPE_BYTES, sd.length, buffer) == -1) { + return -1; + } + buffer[sd.length] = 0; + + /* Is this the correct password? */ + if (strlen(pwent->pw_name)) { + char *ptr; + int i; + + ptr = pwent->pw_name; + i = 0; + while (i < sd.length) { + buffer[i++] ^= *ptr++; + if (*ptr == 0) { + ptr = pwent->pw_name; + } + } + } + if (strcmp(crypt(buffer, pwent->pw_passwd), pwent->pw_passwd) != 0) { + doreject("Invalid password"); + sleep(10); /* Don't let us do too many of these */ + return 0; + } + } + if (api_exch_outcommand(EXCH_CMD_ASSOCIATED) == -1) { + return -1; } else { - doreject("Invalid password"); - sleep(10); /* Don't let us do too many of these */ - return 0; + return 1; } } @@ -186,12 +263,11 @@ doassociate() void freestorage() { - char buffer[40]; struct storage_descriptor sd; if (storage_accessed) { fprintf(stderr, "Internal error - attempt to free accessed storage.\n"); - fprintf(stderr, "(Enountered in file %s at line %s.)\n", + fprintf(stderr, "(Encountered in file %s at line %d.)\n", __FILE__, __LINE__); quit(); } @@ -199,75 +275,83 @@ freestorage() return; } storage_must_send = 0; - if (api_exch_outcommand(EXCH_HEREIS) == -1) { + if (api_exch_outcommand(EXCH_CMD_HEREIS) == -1) { kill_connection(); return; } - sd.length = htons(storage_length); - sd.location = htonl(storage_location); + sd.length = storage_length; + sd.location = storage_location; if (api_exch_outtype(EXCH_TYPE_STORE_DESC, sizeof sd, (char *)&sd) == -1) { kill_connection(); return; } - if (storage_length != 0) { - if (api_exch_outtype(EXCH_TYPE_BYTES, storage_length, (char *)storage) - == -1) { - kill_connection(); - return; - } + if (api_exch_outtype(EXCH_TYPE_BYTES, storage_length, (char *)storage) + == -1) { + kill_connection(); + return; } } static int -getstorage(address, length) +getstorage(address, length, copyin) +long + address; +int + length, + copyin; { struct storage_descriptor sd; - char buffer[40]; freestorage(); if (storage_accessed) { fprintf(stderr, "Internal error - attempt to get while storage accessed.\n"); - fprintf(stderr, "(Enountered in file %s at line %s.)\n", + fprintf(stderr, "(Encountered in file %s at line %d.)\n", __FILE__, __LINE__); quit(); } storage_must_send = 0; - if (api_exch_outcommand(EXCH_GIMME) == -1) { + if (api_exch_outcommand(EXCH_CMD_GIMME) == -1) { kill_connection(); return -1; } storage_location = address; storage_length = length; - sd.location = htonl(storage_location); - sd.length = htons(storage_length); - if (api_exch_outtype(EXCH_TYPE_STORE_DESC, sizeof sd, (char *)&sd) == -1) { - kill_connection(); - return -1; - } - if (api_exch_incommand(EXCH_HEREIS) == -1) { - fprintf(stderr, "Bad data from other side.\n"); - fprintf(stderr, "(Encountered at %s, %s.)\n", __FILE__, __LINE__); - return -1; - } - if (nextstore() == -1) { - kill_connection(); - return -1; + if (copyin) { + sd.location = (long)storage_location; + sd.length = storage_length; + if (api_exch_outtype(EXCH_TYPE_STORE_DESC, + sizeof sd, (char *)&sd) == -1) { + kill_connection(); + return -1; + } + if (api_exch_incommand(EXCH_CMD_HEREIS) == -1) { + fprintf(stderr, "Bad data from other side.\n"); + fprintf(stderr, "(Encountered at %s, %d.)\n", __FILE__, __LINE__); + return -1; + } + if (nextstore() == -1) { + kill_connection(); + return -1; + } } return 0; } +/*ARGSUSED*/ void movetous(local, es, di, length) char *local; -int +unsigned int es, di; int length; { + long where = SEG_OFF_BACK(es, di); + if (length > sizeof storage) { fprintf(stderr, "Internal API error - movetous() length too long.\n"); fprintf(stderr, "(detected in file %s, line %d)\n", __FILE__, __LINE__); @@ -275,13 +359,14 @@ int } else if (length == 0) { return; } - getstorage(di, length); - memcpy(local, storage+(di-storage_location), length); + getstorage(where, length, 1); + memcpy(local, (char *)(storage+((where-storage_location))), length); } +/*ARGSUSED*/ void movetothem(es, di, local, length) -int +unsigned int es, di; char @@ -289,6 +374,8 @@ char int length; { + long where = SEG_OFF_BACK(es, di); + if (length > sizeof storage) { fprintf(stderr, "Internal API error - movetothem() length too long.\n"); fprintf(stderr, "(detected in file %s, line %d)\n", __FILE__, __LINE__); @@ -299,43 +386,48 @@ int freestorage(); memcpy((char *)storage, local, length); storage_length = length; - storage_location = di; + storage_location = where; storage_must_send = 1; } char * -access_api(location, length) +access_api(location, length, copyin) +char * + location; int - location, - length; + length, + copyin; /* Do we need to copy in initially? */ { if (storage_accessed) { fprintf(stderr, "Internal error - storage accessed twice\n"); - fprintf(stderr, "(Encountered in file %s, line %s.)\n", + fprintf(stderr, "(Encountered in file %s, line %d.)\n", __FILE__, __LINE__); quit(); } else if (length != 0) { - storage_accessed = 1; freestorage(); - getstorage(location, length); + getstorage((long)location, length, copyin); + storage_accessed = 1; } return (char *) storage; } -unaccess_api(location, local, length) -int location; +/*ARGSUSED*/ +void +unaccess_api(location, local, length, copyout) +char *location; char *local; int length; +int copyout; { if (storage_accessed == 0) { fprintf(stderr, "Internal error - unnecessary unaccess_api call.\n"); - fprintf(stderr, "(Encountered in file %s, line %s.)\n", + fprintf(stderr, "(Encountered in file %s, line %d.)\n", __FILE__, __LINE__); quit(); } storage_accessed = 0; - storage_must_send = 1; /* Needs to go back */ + storage_must_send = copyout; /* if needs to go back */ } /* @@ -352,7 +444,8 @@ doconnect() FD_ZERO(&fdset); while (shell_active && (sock == -1)) { FD_SET(serversock, &fdset); - if ((i = select(serversock+1, &fdset, 0, 0, 0)) < 0) { + if ((i = select(serversock+1, &fdset, + (fd_set *)0, (fd_set *)0, (struct timeval *)0)) < 0) { if (errno = EINTR) { continue; } else { @@ -360,7 +453,7 @@ doconnect() return -1; } } else { - i = accept(serversock, 0, 0); + i = accept(serversock, (struct sockaddr *)0, (int *)0); if (i == -1) { perror("accepting API connection"); return -1; @@ -370,10 +463,13 @@ doconnect() } /* If the process has already exited, we may need to close */ if ((shell_active == 0) && (sock != -1)) { + extern void setcommandmode(); + (void) close(sock); sock = -1; setcommandmode(); /* In case child_died sneaked in */ } + return 0; } /* @@ -386,6 +482,8 @@ doconnect() int shell_continue() { + int i; + switch (state) { case DEAD: pause(); /* Nothing to do */ @@ -395,11 +493,11 @@ shell_continue() kill_connection(); return -1; } - if (api_exch_init(sock, "client") == -1) { + if (api_exch_init(sock, "server") == -1) { return -1; } while (state == UNCONNECTED) { - if (api_exch_incommand(EXCH_ASSOCIATE) == -1) { + if (api_exch_incommand(EXCH_CMD_ASSOCIATE) == -1) { kill_connection(); return -1; } else { @@ -416,29 +514,42 @@ shell_continue() } break; case CONNECTED: - if (api_exch_incommand(EXCH_REQUEST) == -1) { - kill_connection(); - } else if (api_exch_intype(EXCH_TYPE_REGS, sizeof inputRegs, - (char *)&inputRegs) == -1) { - kill_connection(); - } else if (api_exch_intype(EXCH_TYPE_SREGS, sizeof inputSregs, - (char *)&inputSregs) == -1) { - kill_connection(); - } else if (nextstore() == -1) { - kill_connection(); - } else { - handle_api(&inputRegs, &inputSregs); - freestorage(); /* Send any storage back */ - if (api_exch_outcommand(EXCH_REPLY) == -1) { + switch (i = api_exch_nextcommand()) { + case EXCH_CMD_REQUEST: + if (api_exch_intype(EXCH_TYPE_REGS, sizeof inputRegs, + (char *)&inputRegs) == -1) { kill_connection(); - } else if (api_exch_outtype(EXCH_TYPE_REGS, sizeof inputRegs, - (char *)&inputRegs) == -1) { + } else if (api_exch_intype(EXCH_TYPE_SREGS, sizeof inputSregs, + (char *)&inputSregs) == -1) { kill_connection(); - } else if (api_exch_outtype(EXCH_TYPE_SREGS, sizeof inputSregs, - (char *)&inputSregs) == -1) { + } else if (nextstore() == -1) { kill_connection(); + } else { + handle_api(&inputRegs, &inputSregs); + freestorage(); /* Send any storage back */ + if (api_exch_outcommand(EXCH_CMD_REPLY) == -1) { + kill_connection(); + } else if (api_exch_outtype(EXCH_TYPE_REGS, sizeof inputRegs, + (char *)&inputRegs) == -1) { + kill_connection(); + } else if (api_exch_outtype(EXCH_TYPE_SREGS, sizeof inputSregs, + (char *)&inputSregs) == -1) { + kill_connection(); + } + /* Done, and it all worked! */ + } + break; + case EXCH_CMD_DISASSOCIATE: + kill_connection(); + break; + default: + if (i != -1) { + fprintf(stderr, + "Looking for a REQUEST or DISASSOCIATE command\n"); + fprintf(stderr, "\treceived 0x%02x.\n", i); } - /* Done, and it all worked! */ + kill_connection(); + break; } } return shell_active; @@ -448,12 +559,14 @@ shell_continue() static int child_died() { - union wait *status; + union wait status; register int pid; - while ((pid = wait3(&status, WNOHANG, 0)) > 0) { + while ((pid = wait3(&status, WNOHANG, (struct rusage *)0)) > 0) { if (pid == shell_pid) { char inputbuffer[100]; + extern void setconnmode(); + extern void ConnectScreen(); shell_active = 0; if (sock != -1) { @@ -466,6 +579,7 @@ child_died() setconnmode(); ConnectScreen(); /* Turn screen on (if need be) */ (void) close(serversock); + (void) unlink(keyname); } } signal(SIGCHLD, child_died); @@ -488,8 +602,47 @@ char *argv[]; struct sockaddr_in server; char sockNAME[100]; static char **whereAPI = 0; + int fd; + struct timeval tv; + long ikey; + extern long random(); + extern char *mktemp(); + extern char *strcpy(); + + /* First, create verification file. */ + do { + keyname = mktemp("/tmp/apiXXXXXX"); + fd = open(keyname, O_RDWR|O_CREAT|O_EXCL, IREAD|IWRITE); + } while ((fd == -1) && (errno == EEXIST)); + + if (fd == -1) { + perror("open"); + return 0; + } + + /* Now, get seed for random */ + + if (gettimeofday(&tv, (struct timezone *)0) == -1) { + perror("gettimeofday"); + return 0; + } + srandom(tv.tv_usec); /* seed random number generator */ + do { + ikey = random(); + } while (ikey == 0); + sprintf(key, "%lu\n", (unsigned long) ikey); + if (write(fd, key, strlen(key)) != strlen(key)) { + perror("write"); + return 0; + } + key[strlen(key)-1] = 0; /* Get rid of newline */ + + if (close(fd) == -1) { + perror("close"); + return 0; + } - /* First, create the socket which will be connected to */ + /* Next, create the socket which will be connected to */ serversock = socket(AF_INET, SOCK_STREAM, 0); if (serversock < 0) { perror("opening API socket"); @@ -498,12 +651,12 @@ char *argv[]; server.sin_family = AF_INET; server.sin_addr.s_addr = INADDR_ANY; server.sin_port = 0; - if (bind(serversock, &server, sizeof server) < 0) { + if (bind(serversock, (struct sockaddr *)&server, sizeof server) < 0) { perror("binding API socket"); return 0; } length = sizeof server; - if (getsockname(serversock, &server, &length) < 0) { + if (getsockname(serversock, (struct sockaddr *)&server, &length) < 0) { perror("getting API socket name"); (void) close(serversock); } @@ -511,11 +664,12 @@ char *argv[]; /* Get name to advertise in address list */ strcpy(sockNAME, "API3270="); gethostname(sockNAME+strlen(sockNAME), sizeof sockNAME-strlen(sockNAME)); - if (strlen(sockNAME) > (sizeof sockNAME-10)) { + if (strlen(sockNAME) > (sizeof sockNAME-(10+strlen(keyname)))) { fprintf(stderr, "Local hostname too large; using 'localhost'.\n"); strcpy(sockNAME, "localhost"); } - sprintf(sockNAME+strlen(sockNAME), ":%d", ntohs(server.sin_port)); + sprintf(sockNAME+strlen(sockNAME), ":%u", ntohs(server.sin_port)); + sprintf(sockNAME+strlen(sockNAME), ":%s", keyname); if (whereAPI == 0) { char **ptr, **nextenv;