+/*
+ * 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>
+
+#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 <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"
+#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 char key[50]; /* Actual key */
+static char *keyname; /* Name of file with key in it */
static char *ourENVlist[200]; /* Lots of room */
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)! */
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 (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;
}
* 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
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_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;
}
- 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) {
}
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;
- } 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 {
- doreject("Invalid password");
- sleep(10); /* Don't let us do too many of these */
- return 0;
+ return 1;
}
}
void
freestorage()
{
- char buffer[40];
struct storage_descriptor sd;
if (storage_accessed) {
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;
static int
getstorage(address, length, copyin)
+long
+ address;
int
- address,
length,
copyin;
{
struct storage_descriptor sd;
- char buffer[40];
freestorage();
if (storage_accessed) {
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();
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__);
} 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)
-int
+unsigned int
es,
di;
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__);
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)
+char *
+ location;
int
- location,
length,
copyin; /* Do we need to copy in initially? */
{
quit();
} else if (length != 0) {
freestorage();
- getstorage(location, length, copyin);
+ getstorage((long)location, length, copyin);
storage_accessed = 1;
}
return (char *) storage;
}
+/*ARGSUSED*/
+void
unaccess_api(location, local, length, copyout)
-int location;
+char *location;
char *local;
int length;
+int copyout;
{
if (storage_accessed == 0) {
fprintf(stderr, "Internal error - unnecessary unaccess_api call.\n");
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 {
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 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;
}
/*
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) {
setconnmode();
ConnectScreen(); /* Turn screen on (if need be) */
(void) close(serversock);
+ (void) unlink(keyname);
}
}
signal(SIGCHLD, child_died);
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");
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);
}
/* 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;