Changes for pyramid from sbanner1@cheops (S. John Banner).
[unix-history] / usr / src / usr.bin / tn3270 / sys_curses / system.c
index 3b23182..a64e92f 100644 (file)
@@ -1,4 +1,43 @@
+/*
+ *     Copyright (c) 1984-1987 by the Regents of the
+ *     University of California and by Gregory Glenn Minshall.
+ *
+ *     Permission to use, copy, modify, and distribute these
+ *     programs and their documentation for any purpose and
+ *     without fee is hereby granted, provided that this
+ *     copyright and permission appear on all copies and
+ *     supporting documentation, the name of the Regents of
+ *     the University of California not be used in advertising
+ *     or publicity pertaining to distribution of the programs
+ *     without specific prior permission, and notice be given in
+ *     supporting documentation that copying and distribution is
+ *     by permission of the Regents of the University of California
+ *     and by Gregory Glenn Minshall.  Neither the Regents of the
+ *     University of California nor Gregory Glenn Minshall make
+ *     representations about the suitability of this software
+ *     for any purpose.  It is provided "as is" without
+ *     express or implied warranty.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)system.c   3.2 (Berkeley) %G%";
+#endif /* not lint */
+
 #include <sys/types.h>
 #include <sys/types.h>
+
+#if     defined(pyr)
+#define fd_set fdset_t
+#endif  /* defined(pyr) */
+
+#if    !defined(sun) && !defined(pyr)
+#include <sys/inode.h>
+#else  /* !defined(sun) */
+#define        IREAD   00400
+#define        IWRITE  00200
+#endif /* !defined(sun) */
+
+#include <sys/file.h>
+#include <sys/time.h>
 #include <sys/socket.h>
 #include <netinet/in.h>
 #include <sys/wait.h>
 #include <sys/socket.h>
 #include <netinet/in.h>
 #include <sys/wait.h>
@@ -12,13 +51,28 @@ extern int errno;
 #include <pwd.h>
 
 #include "../general/general.h"
 #include <pwd.h>
 
 #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"
 
 
 #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
+\f
 static int shell_pid = 0;
 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 */
 
 
 static char *ourENVlist[200];          /* Lots of room */
 
@@ -60,20 +114,18 @@ nextstore()
        storage_length = 0;
        return -1;
     }
        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 > 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;
 }
     }
     return 0;
 }
@@ -89,7 +141,7 @@ char *message;
     if (api_exch_outcommand(EXCH_CMD_REJECTED) == -1) {
        return -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;
     }
     if (api_exch_outtype(EXCH_TYPE_STORE_DESC, sizeof sd, (char *)&sd) == -1) {
        return -1;
     }
@@ -104,6 +156,12 @@ char       *message;
  * doassociate()
  *
  * Negotiate with the other side and try to do something.
  * 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
  */
 
 static int
@@ -117,37 +175,12 @@ doassociate()
     int was;
     struct storage_descriptor sd;
 
     int was;
     struct storage_descriptor sd;
 
-    if ((pwent = getpwuid(geteuid())) == 0) {
-       return -1;
-    }
-    sprintf(promptbuf, "Enter password for user %s:", pwent->pw_name);
-    if (api_exch_outcommand(EXCH_CMD_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_CMD_AUTH) == -1) {
-       return -1;
-    }
     if (api_exch_intype(EXCH_TYPE_STORE_DESC, sizeof sd, (char *)&sd) == -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) {
     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) {
        return -1;
     }
     if (api_exch_intype(EXCH_TYPE_BYTES, sd.length, buffer) == -1) {
@@ -155,30 +188,73 @@ doassociate()
     }
     buffer[sd.length] = 0;
 
     }
     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 ((pwent = getpwuid(geteuid())) == 0) {
+           return -1;
        }
        }
-    }
-    if (strcmp(crypt(buffer, pwent->pw_passwd), pwent->pw_passwd) == 0) {
-       if (api_exch_outcommand(EXCH_CMD_ASSOCIATED) == -1) {
+       sprintf(promptbuf, "Enter password for user %s:", pwent->pw_name);
+       if (api_exch_outcommand(EXCH_CMD_SEND_AUTH) == -1) {
            return -1;
            return -1;
-       } else {
-           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;
+       }
+       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 {
     } else {
-       doreject("Invalid password");
-       sleep(10);              /* Don't let us do too many of these */
-       return 0;
+       return 1;
     }
 }
 
     }
 }
 
@@ -203,24 +279,26 @@ freestorage()
        kill_connection();
        return;
     }
        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 (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
     }
 }
 
 
 static int
-getstorage(address, length)
+getstorage(address, length, copyin)
+int
+    address,
+    length,
+    copyin;
 {
     struct storage_descriptor sd;
     char buffer[40];
 {
     struct storage_descriptor sd;
     char buffer[40];
@@ -240,20 +318,23 @@ getstorage(address, length)
     }
     storage_location = address;
     storage_length = length;
     }
     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_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;
+    if (copyin) {
+       sd.location = 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;
 }
     }
     return 0;
 }
@@ -275,7 +356,7 @@ int
     } else if (length == 0) {
        return;
     }
     } else if (length == 0) {
        return;
     }
-    getstorage(di, length);
+    getstorage(di, length, 1);
     memcpy(local, storage+(di-storage_location), length);
 }
 
     memcpy(local, storage+(di-storage_location), length);
 }
 
@@ -305,10 +386,11 @@ int
 
 
 char *
 
 
 char *
-access_api(location, length)
+access_api(location, length, copyin)
 int
     location,
 int
     location,
-    length;
+    length,
+    copyin;                    /* Do we need to copy in initially? */
 {
     if (storage_accessed) {
        fprintf(stderr, "Internal error - storage accessed twice\n");
 {
     if (storage_accessed) {
        fprintf(stderr, "Internal error - storage accessed twice\n");
@@ -317,13 +399,13 @@ int
        quit();
     } else if (length != 0) {
        freestorage();
        quit();
     } else if (length != 0) {
        freestorage();
-       getstorage(location, length);
+       getstorage(location, length, copyin);
        storage_accessed = 1;
     }
     return (char *) storage;
 }
 
        storage_accessed = 1;
     }
     return (char *) storage;
 }
 
-unaccess_api(location, local, length)
+unaccess_api(location, local, length, copyout)
 int    location;
 char   *local;
 int    length;
 int    location;
 char   *local;
 int    length;
@@ -335,7 +417,7 @@ int length;
        quit();
     }
     storage_accessed = 0;
        quit();
     }
     storage_accessed = 0;
-    storage_must_send = 1;     /* Needs to go back */
+    storage_must_send = copyout;       /* if needs to go back */
 }
 
 /*
 }
 
 /*
@@ -481,6 +563,7 @@ child_died()
            setconnmode();
            ConnectScreen();    /* Turn screen on (if need be) */
            (void) close(serversock);
            setconnmode();
            ConnectScreen();    /* Turn screen on (if need be) */
            (void) close(serversock);
+           (void) unlink(keyname);
        }
     }
     signal(SIGCHLD, child_died);
        }
     }
     signal(SIGCHLD, child_died);
@@ -503,8 +586,46 @@ char       *argv[];
     struct sockaddr_in server;
     char sockNAME[100];
     static char **whereAPI = 0;
     struct sockaddr_in server;
     char sockNAME[100];
     static char **whereAPI = 0;
+    int fd;
+    struct timeval tv;
+    long ikey;
+    extern long random();
+    extern char *mktemp();
+
+    /* 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, 0) == -1) {
+       perror("gettimeofday");
+       return 0;
+    }
+    srandom(tv.tv_usec);               /* seed random number generator */
+    do {
+       ikey = random();
+    } while (ikey == 0);
+    sprintf(key, "%lu\n", 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");
     serversock = socket(AF_INET, SOCK_STREAM, 0);
     if (serversock < 0) {
        perror("opening API socket");
@@ -526,11 +647,12 @@ char      *argv[];
     /* Get name to advertise in address list */
     strcpy(sockNAME, "API3270=");
     gethostname(sockNAME+strlen(sockNAME), sizeof sockNAME-strlen(sockNAME));
     /* 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));
        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), ":%s", keyname);
 
     if (whereAPI == 0) {
        char **ptr, **nextenv;
 
     if (whereAPI == 0) {
        char **ptr, **nextenv;