Release 4.1
[unix-history] / usr / src / usr.bin / tn3270 / sys_curses / system.c
index 7d0c954..5ae20c0 100644 (file)
@@ -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 <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,8 +47,8 @@ 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"
 
@@ -32,6 +67,8 @@ extern int errno;
 #endif
 \f
 static int shell_pid = 0;
 #endif
 \f
 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 */
 
@@ -41,9 +78,11 @@ static int
 
 static enum { DEAD, UNCONNECTED, CONNECTED } state;
 
 
 static enum { DEAD, UNCONNECTED, CONNECTED } state;
 
+static long
+    storage_location;          /* Address we have */
+static short
+    storage_length = 0;                /* Length we have */
 static int
 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)! */
 
     storage_must_send = 0,     /* Storage belongs on other side of wire */
     storage_accessed = 0;      /* The storage is accessed (so leave alone)! */
 
@@ -73,8 +112,8 @@ 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);
     if (storage_length > sizeof storage) {
        fprintf(stderr, "API client tried to send too much storage (%d).\n",
                storage_length);
@@ -100,7 +139,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;
     }
@@ -115,6 +154,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
@@ -124,41 +169,15 @@ doassociate()
     char
        promptbuf[100],
        buffer[200];
     char
        promptbuf[100],
        buffer[200];
-    int length;
-    int was;
     struct storage_descriptor sd;
     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_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) {
@@ -166,30 +185,77 @@ 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    (!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_CMD_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;
+       }
+       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;
            return -1;
-       } else {
-           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;
     }
 }
 
     }
 }
 
@@ -197,7 +263,6 @@ doassociate()
 void
 freestorage()
 {
 void
 freestorage()
 {
-    char buffer[40];
     struct storage_descriptor sd;
 
     if (storage_accessed) {
     struct storage_descriptor sd;
 
     if (storage_accessed) {
@@ -214,8 +279,8 @@ 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;
@@ -230,13 +295,13 @@ freestorage()
 
 static int
 getstorage(address, length, copyin)
 
 static int
 getstorage(address, length, copyin)
+long
+    address;
 int
 int
-    address,
     length,
     copyin;
 {
     struct storage_descriptor sd;
     length,
     copyin;
 {
     struct storage_descriptor sd;
-    char buffer[40];
 
     freestorage();
     if (storage_accessed) {
 
     freestorage();
     if (storage_accessed) {
@@ -254,8 +319,8 @@ int
     storage_location = address;
     storage_length = length;
     if (copyin) {
     storage_location = address;
     storage_length = length;
     if (copyin) {
-       sd.location = htonl(storage_location);
-       sd.length = htons(storage_length);
+       sd.location = (long)storage_location;
+       sd.length = storage_length;
        if (api_exch_outtype(EXCH_TYPE_STORE_DESC,
                                        sizeof sd, (char *)&sd) == -1) {
            kill_connection();
        if (api_exch_outtype(EXCH_TYPE_STORE_DESC,
                                        sizeof sd, (char *)&sd) == -1) {
            kill_connection();
@@ -274,16 +339,19 @@ int
     return 0;
 }
 
     return 0;
 }
 
+/*ARGSUSED*/
 void
 movetous(local, es, di, length)
 char
     *local;
 void
 movetous(local, es, di, length)
 char
     *local;
-int
+unsigned int
     es,
     di;
 int
     length;
 {
     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__);
     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__);
@@ -291,13 +359,14 @@ int
     } else if (length == 0) {
        return;
     }
     } else if (length == 0) {
        return;
     }
-    getstorage(di, length, 1);
-    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)
 void
 movetothem(es, di, local, length)
-int
+unsigned int
     es,
     di;
 char
     es,
     di;
 char
@@ -305,6 +374,8 @@ char
 int
     length;
 {
 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__);
     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__);
@@ -315,15 +386,16 @@ int
     freestorage();
     memcpy((char *)storage, local, length);
     storage_length = length;
     freestorage();
     memcpy((char *)storage, local, length);
     storage_length = length;
-    storage_location = di;
+    storage_location = where;
     storage_must_send = 1;
 }
 
 
 char *
 access_api(location, length, copyin)
     storage_must_send = 1;
 }
 
 
 char *
 access_api(location, length, copyin)
+char *
+    location;
 int
 int
-    location,
     length,
     copyin;                    /* Do we need to copy in initially? */
 {
     length,
     copyin;                    /* Do we need to copy in initially? */
 {
@@ -334,16 +406,19 @@ int
        quit();
     } else if (length != 0) {
        freestorage();
        quit();
     } else if (length != 0) {
        freestorage();
-       getstorage(location, length, copyin);
+       getstorage((long)location, length, copyin);
        storage_accessed = 1;
     }
     return (char *) storage;
 }
 
        storage_accessed = 1;
     }
     return (char *) storage;
 }
 
+/*ARGSUSED*/
+void
 unaccess_api(location, local, length, copyout)
 unaccess_api(location, local, length, copyout)
-int    location;
+char   *location;
 char   *local;
 int    length;
 char   *local;
 int    length;
+int    copyout;
 {
     if (storage_accessed == 0) {
        fprintf(stderr, "Internal error - unnecessary unaccess_api call.\n");
 {
     if (storage_accessed == 0) {
        fprintf(stderr, "Internal error - unnecessary unaccess_api call.\n");
@@ -369,7 +444,8 @@ doconnect()
     FD_ZERO(&fdset);
     while (shell_active && (sock == -1)) {
        FD_SET(serversock, &fdset);
     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 {
            if (errno = EINTR) {
                continue;
            } else {
@@ -377,7 +453,7 @@ doconnect()
                return -1;
            }
        } else {
                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;
            if (i == -1) {
                perror("accepting API connection");
                return -1;
@@ -387,10 +463,13 @@ doconnect()
     }
     /* If the process has already exited, we may need to close */
     if ((shell_active == 0) && (sock != -1)) {
     }
     /* 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 */
     }
        (void) close(sock);
        sock = -1;
        setcommandmode();       /* In case child_died sneaked in */
     }
+    return 0;
 }
 
 /*
 }
 
 /*
@@ -480,12 +559,14 @@ shell_continue()
 static int
 child_died()
 {
 static int
 child_died()
 {
-    union wait *status;
+    union wait status;
     register int pid;
 
     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];
        if (pid == shell_pid) {
            char inputbuffer[100];
+           extern void setconnmode();
+           extern void ConnectScreen();
 
            shell_active = 0;
            if (sock != -1) {
 
            shell_active = 0;
            if (sock != -1) {
@@ -498,6 +579,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);
@@ -520,8 +602,47 @@ 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();
+    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");
     serversock = socket(AF_INET, SOCK_STREAM, 0);
     if (serversock < 0) {
        perror("opening API socket");
@@ -530,12 +651,12 @@ char      *argv[];
     server.sin_family = AF_INET;
     server.sin_addr.s_addr = INADDR_ANY;
     server.sin_port = 0;
     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;
        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);
     }
        perror("getting API socket name");
        (void) close(serversock);
     }
@@ -543,11 +664,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");
     }
        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;
 
     if (whereAPI == 0) {
        char **ptr, **nextenv;