X-Git-Url: http://git.chise.org/gitweb/?p=chise%2Fxemacs-chise.git.1;a=blobdiff_plain;f=lib-src%2Fgnuserv.c;h=27a98692d3e40d2835fa113b8f00bea566016816;hp=ddce69c2e0049828d65238990789d46c3cf2abfe;hb=6b1f1b2af579009e8a95f9c79f3cfe119f2f595d;hpb=a5f466de30a3e927ed1146b0c7e3870e71465c8f diff --git a/lib-src/gnuserv.c b/lib-src/gnuserv.c index ddce69c..27a9869 100644 --- a/lib-src/gnuserv.c +++ b/lib-src/gnuserv.c @@ -15,8 +15,8 @@ Please mail bugs and suggestions to the author at the above address. */ -/* HISTORY - * 11-Nov-1990 bristor@simba +/* HISTORY + * 11-Nov-1990 bristor@simba * Added EOT stuff. */ @@ -29,12 +29,11 @@ * ../etc/gnuserv.README relative to the directory containing this file) */ -#if 0 -static char rcsid [] = "!Header: gnuserv.c,v 2.1 95/02/16 11:58:27 arup alpha !"; -#endif - #include "gnuserv.h" +char gnuserv_version[] = "gnuserv version" GNUSERV_VERSION; + + #ifdef USE_LITOUT #ifdef linux #include @@ -73,7 +72,7 @@ main () #ifdef SYSV_IPC int ipc_qid = 0; /* ipc message queue id */ -int ipc_wpid = 0; /* watchdog task pid */ +pid_t ipc_wpid = 0; /* watchdog task pid */ /* @@ -84,7 +83,7 @@ void ipc_exit (int stat) { msgctl (ipc_qid,IPC_RMID,0); - + if (ipc_wpid != 0) kill (ipc_wpid, SIGKILL); @@ -102,7 +101,7 @@ ipc_handle_signal(int sig) } /* ipc_handle_signal */ -/* +/* ipc_spawn_watchdog -- spawn a watchdog task to clean up the message queue should the server process die. */ @@ -111,7 +110,7 @@ ipc_spawn_watchdog (void) { if ((ipc_wpid = fork ()) == 0) { /* child process */ - int ppid = getppid (); /* parent's process id */ + pid_t ppid = getppid (); /* parent's process id */ setpgrp(); /* gnu kills process group on exit */ @@ -190,7 +189,7 @@ handle_ipc_request (struct msgbuf *msgp) msgctl (ipc_qid, IPC_STAT, &msg_st); strncpy (buf, msgp->mtext, len); buf[len] = '\0'; /* terminate */ - + printf ("%d %s", ipc_qid, buf); fflush (stdout); @@ -210,7 +209,7 @@ handle_ipc_request (struct msgbuf *msgp) /* read in "n/m:" (n=client fd, m=message length) */ - while (offset < (GSERV_BUFSZ-1) && + while (offset < (GSERV_BUFSZ-1) && ((len = read (0, buf + offset, 1)) > 0) && buf[offset] != ':') { @@ -237,7 +236,7 @@ handle_ipc_request (struct msgbuf *msgp) exit (1); } - /* Send this string off, but only if we have enough space */ + /* Send this string off, but only if we have enough space */ if (GSERV_BUFSZ > total) { @@ -291,7 +290,7 @@ echo_request (int s) int len; printf("%d ",s); - + /* read until we get a newline or no characters */ while ((len = recv(s,buf,GSERV_BUFSZ-1,0)) > 0) { buf[len] = '\0'; @@ -309,7 +308,7 @@ echo_request (int s) fprintf(stderr,"%s: unable to recv\n",progname); exit(1); } /* if */ - + } /* echo_request */ @@ -323,11 +322,11 @@ handle_response (void) char buf[GSERV_BUFSZ+1]; int offset=0; int s; - int len; + int len = 0; int result_len; /* read in "n/m:" (n=client fd, m=message length) */ - while (offset < GSERV_BUFSZ && + while (offset < GSERV_BUFSZ && ((len = read(0,buf+offset,1)) > 0) && buf[offset] != ':') { offset += len; @@ -338,7 +337,7 @@ handle_response (void) fprintf(stderr,"%s: unable to read\n",progname); exit(1); } - + /* parse the response from emacs, getting client fd & result length */ buf[offset] = '\0'; sscanf(buf,"%d/%d", &s, &result_len); @@ -371,7 +370,7 @@ handle_response (void) /* send the newline */ buf[1] = '\0'; send_string(s,buf); - close(s); + close(s); } /* handle_response */ #endif /* INTERNET_DOMAIN_SOCKETS || UNIX_DOMAIN_SOCKETS */ @@ -379,7 +378,7 @@ handle_response (void) #ifdef INTERNET_DOMAIN_SOCKETS struct entry { - u_long host_addr; + unsigned long host_addr; struct entry *next; }; @@ -390,9 +389,9 @@ struct entry *permitted_hosts[TABLE_SIZE]; # include static Xauth *server_xauth = NULL; -#endif +#endif -static int +static int timed_read (int fd, char *buf, int max, int timeout, int one_line) { fd_set rmask; @@ -400,13 +399,13 @@ timed_read (int fd, char *buf, int max, int timeout, int one_line) char c = 0; int nbytes = 0; int r; - + tv.tv_sec = timeout; tv.tv_usec = 0; FD_ZERO(&rmask); FD_SET(fd, &rmask); - + do { r = select(fd + 1, &rmask, NULL, NULL, &tv); @@ -444,19 +443,19 @@ timed_read (int fd, char *buf, int max, int timeout, int one_line) return nbytes; } - - + + /* permitted -- return whether a given host is allowed to connect to the server. */ static int -permitted (u_long host_addr, int fd) +permitted (unsigned long host_addr, int fd) { int key; struct entry *entry; - char auth_protocol[128]; + char auth_protocol[128]; char buf[1024]; int auth_data_len; @@ -465,17 +464,17 @@ permitted (u_long host_addr, int fd) /* we are checking permission on a real connection */ /* Read auth protocol name */ - + if (timed_read(fd, auth_protocol, AUTH_NAMESZ, AUTH_TIMEOUT, 1) <= 0) return FALSE; if (strcmp (auth_protocol, DEFAUTH_NAME) && strcmp (auth_protocol, MCOOKIE_NAME)) { - printf ("authentication protocol (%s) from client is invalid...\n", + printf ("authentication protocol (%s) from client is invalid...\n", auth_protocol); printf ("... Was the client an old version of gnuclient/gnudoit?\004\n"); - + return FALSE; } @@ -491,19 +490,39 @@ permitted (u_long host_addr, int fd) auth_data_len = atoi(buf); + if (auth_data_len <= 0 || auth_data_len > sizeof(buf)) + { + return FALSE; + } + if (timed_read(fd, buf, auth_data_len, AUTH_TIMEOUT, 0) != auth_data_len) return FALSE; - + #ifdef AUTH_MAGIC_COOKIE - if (server_xauth && server_xauth->data && - !memcmp(buf, server_xauth->data, auth_data_len)) + if (server_xauth && server_xauth->data) { + /* Do a compare without comprising info about + the size of the cookie */ + int auth_data_pos; + int auth_mismatches = + ( auth_data_len ^ + server_xauth->data_length ); + + for(auth_data_pos=0; auth_data_pos < auth_data_len; ++auth_data_pos) + auth_mismatches |= + ( buf[auth_data_pos] ^ + server_xauth->data[auth_data_pos % server_xauth->data_length]); + + if (auth_mismatches == 0) return TRUE; + + for(;rand() % 1000;); } -#else + +#else printf ("client tried Xauth, but server is not compiled with Xauth\n"); #endif - + /* * auth failed, but allow this to fall through to the GNU_SECURE * protocol.... @@ -512,7 +531,7 @@ permitted (u_long host_addr, int fd) printf ("Xauth authentication failed, trying GNU_SECURE auth...\004\n"); } - + /* Other auth protocols go here, and should execute only if the * auth_protocol name matches. */ @@ -521,30 +540,30 @@ permitted (u_long host_addr, int fd) /* Now, try the old GNU_SECURE stuff... */ - + /* First find the hash key */ key = HASH(host_addr) % TABLE_SIZE; - + /* Now check the chain for that hash key */ for(entry=permitted_hosts[key]; entry != NULL; entry=entry->next) - if (host_addr == entry->host_addr) + if (host_addr == entry->host_addr) return(TRUE); - + return(FALSE); } /* permitted */ -/* +/* add_host -- add the given host to the list of permitted hosts, provided it isn't already there. -*/ +*/ static void -add_host (u_long host_addr) +add_host (unsigned long host_addr) { int key; struct entry *new_entry; - + if (!permitted(host_addr, -1)) { if ((new_entry = (struct entry *) malloc(sizeof(struct entry))) == NULL) { @@ -576,46 +595,51 @@ setup_table (void) FILE *host_file; char *file_name; char hostname[HOSTNAMSZ]; - u_int host_addr; + unsigned int host_addr; int i, hosts=0; - + int t; + /* Make sure every entry is null */ for (i=0; is_port; - + /* Create the listen socket. */ if ((ls = socket (AF_INET,SOCK_STREAM, 0)) == -1) { @@ -662,7 +686,7 @@ internet_init (void) fprintf(stderr,"%s: unable to create socket\n",progname); exit(1); } /* if */ - + /* Bind the listen address to the socket. */ if (bind(ls,(struct sockaddr *) &server,sizeof(struct sockaddr_in)) == -1) { @@ -672,7 +696,7 @@ internet_init (void) } /* if */ /* Initiate the listen on the socket so remote users - * can connect. + * can connect. */ if (listen(ls,20) == -1) { @@ -694,18 +718,18 @@ static void handle_internet_request (int ls) { int s; - size_t addrlen = sizeof(struct sockaddr_in); + socklen_t addrlen = sizeof (struct sockaddr_in); struct sockaddr_in peer; /* for peer socket address */ - memset((char *)&peer,0,sizeof(struct sockaddr_in)); + memset (&peer, '\0', sizeof (peer)); - if ((s = accept(ls,(struct sockaddr *)&peer, (void *) &addrlen)) == -1) + if ((s = accept(ls,(struct sockaddr *)&peer, &addrlen)) == -1) { perror(progname); fprintf(stderr,"%s: unable to accept\n",progname); exit(1); } /* if */ - + /* Check that access is allowed - if not return crud to the client */ if (!permitted(peer.sin_addr.s_addr, s)) { @@ -717,7 +741,7 @@ handle_internet_request (int ls) } /* if */ echo_request(s); - + } /* handle_internet_request */ #endif /* INTERNET_DOMAIN_SOCKETS */ @@ -732,7 +756,7 @@ unix_init (void) { int ls; /* socket descriptor */ struct sockaddr_un server; /* unix socket address */ - int bindlen; + socklen_t bindlen; if ((ls = socket(AF_UNIX,SOCK_STREAM, 0)) < 0) { @@ -772,7 +796,7 @@ unix_init (void) #else bindlen = strlen (server.sun_path) + sizeof (server.sun_family); #endif - + if (bind(ls,(struct sockaddr *)&server,bindlen) < 0) { perror(progname); @@ -791,7 +815,7 @@ unix_init (void) /* #### there are also better ways of dealing with this when sigvec() is present. */ #if defined (HAVE_SIGPROCMASK) - { + { sigset_t _mask; sigemptyset (&_mask); sigaddset (&_mask, SIGPIPE); @@ -814,19 +838,19 @@ static void handle_unix_request (int ls) { int s; - size_t len = sizeof(struct sockaddr_un); + socklen_t len = sizeof (struct sockaddr_un); struct sockaddr_un server; /* for unix socket address */ server.sun_family = AF_UNIX; - if ((s = accept(ls,(struct sockaddr *)&server, (void *)&len)) < 0) + if ((s = accept(ls,(struct sockaddr *)&server, &len)) < 0) { perror(progname); fprintf(stderr,"%s: unable to accept\n",progname); } /* if */ echo_request(s); - + } /* handle_unix_request */ #endif /* UNIX_DOMAIN_SOCKETS */ @@ -883,13 +907,13 @@ main (int argc, char *argv[]) FD_SET(uls, &rmask); if (ils >= 0) FD_SET(ils, &rmask); - - if (select(max2(fileno(stdin),max2(uls,ils)) + 1, &rmask, + + if (select(max2(fileno(stdin),max2(uls,ils)) + 1, &rmask, (fd_set *)NULL, (fd_set *)NULL, (struct timeval *)NULL) < 0) { perror(progname); fprintf(stderr,"%s: unable to select\n",progname); - exit(1); + return 1; } /* if */ #ifdef UNIX_DOMAIN_SOCKETS @@ -905,9 +929,7 @@ main (int argc, char *argv[]) if (FD_ISSET(fileno(stdin), &rmask)) /* from stdin (gnu process) */ handle_response(); #endif /* NOT SYSV_IPC */ - } /* while */ - - return 0; + } /* while (1) */ } /* main */ #endif /* SYSV_IPC || UNIX_DOMAIN_SOCKETS || INTERNET_DOMAIN_SOCKETS */