📄 gnuserv.c
字号:
/* -*-C-*- * Server code for handling requests from clients and forwarding them * on to the GNU Emacs process. * * This file is part of GNU Emacs. * * Copying is permitted under those conditions described by the GNU * General Public License. * * Copyright (C) 1989 Free Software Foundation, Inc. * * Author: Andy Norman (ange@hplb.hpl.hp.com), based on 'etc/server.c' * from the 18.52 GNU Emacs distribution. * * Please mail bugs and suggestions to the author at the above address. *//* HISTORY * 11-Nov-1990 bristor@simba * Added EOT stuff. *//* * This file incorporates new features added by Bob Weiner <weiner@mot.com>, * Darrell Kindred <dkindred@cmu.edu> and Arup Mukherjee <arup@cmu.edu>. * Please see the note at the end of the README file for details. * * (If gnuserv came bundled with your emacs, the README file is probably * ../etc/gnuserv.README relative to the directory containing this file) */#include <config.h>#include "libgtop-i18n.h"#include <glibtop.h>#include <glibtop/open.h>#include <glibtop/close.h>#include <glibtop/command.h>#include <glibtop/parameter.h>#include "server_config.h"#include <glibtop/gnuserv.h>#include <errno.h>#include <popt.h>#include "daemon.h"#ifdef AIX#include <sys/select.h>#endif#ifdef NEED_DECLARATION_PROGRAM_INVOCATION_NAMEextern char *program_invocation_name, *program_invocation_short_name;#endif#ifndef HAVE_PROGRAM_INVOCATION_SHORT_NAMEchar *program_invocation_short_name;#endif#ifndef HAVE_PROGRAM_INVOCATION_NAMEchar *program_invocation_name;#endifvoid handle_parent_connection (int s);void handle_slave_connection (int input, int output);#if !defined(INTERNET_DOMAIN_SOCKETS)#error "Internet Domain sockets are required"#endif#ifdef AUTH_MAGIC_COOKIE#include <X11/X.h>#include <X11/Xauth.h>static Xauth *server_xauth = NULL;#endif /* AUTH_MAGIC_COOKIE */int enable_debug = 0;int verbose_output = 0;static int no_daemon = 0;static int invoked_from_inetd = 0;static int changed_uid = 0;voidsyslog_message (int priority, char *format, ...){ va_list ap; char buffer [BUFSIZ]; va_start (ap, format); vsnprintf (buffer, BUFSIZ-1, format, ap); va_end (ap); syslog (priority, "%s", buffer);}voidsyslog_io_message (int priority, char *format, ...){ va_list ap; char buffer [BUFSIZ]; char buffer2 [BUFSIZ]; va_start (ap, format); vsnprintf (buffer, BUFSIZ-1, format, ap); va_end (ap); snprintf (buffer2, BUFSIZ-1, "%s: %s", buffer, strerror (errno)); syslog (priority, "%s", buffer2);}/* * timed_read - Read with timeout. */static inttimed_read (int fd, char *buf, int max, int timeout, int one_line){ fd_set rmask; struct timeval tv; /* = {timeout, 0}; */ 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); if (r > 0) { if (read (fd, &c, 1) == 1) { *buf++ = c; ++nbytes; } else { syslog_io_message (LOG_WARNING, "read error on socket"); return -1; } } else if (r == 0) { syslog_io_message (LOG_WARNING, "read timed out"); return -1; } else { syslog_io_message (LOG_WARNING, "error in select"); return -1; } } while ((nbytes < max) && !(one_line && (c == '\n'))); --buf; if (one_line && *buf == '\n') { *buf = 0; } return nbytes;}/* * permitted -- return whether a given host is allowed to connect to the server. */static intpermitted (u_long host_addr, int fd){ int i; char auth_protocol[128]; char buf[1024]; int auth_data_len; /* Read auth protocol name */ if (timed_read (fd, auth_protocol, AUTH_NAMESZ, AUTH_TIMEOUT, 1) <= 0) return FALSE; if (enable_debug) syslog_message (LOG_DEBUG, "Client sent authenticatin protocol '%s'.", auth_protocol); if (strcmp (auth_protocol, DEFAUTH_NAME) && strcmp (auth_protocol, MCOOKIE_NAME)) { syslog_message (LOG_WARNING, "Invalid authentication protocol " "'%s' from client", auth_protocol); return FALSE; } if (!strcmp (auth_protocol, MCOOKIE_NAME)) { /* * doing magic cookie auth */ if (timed_read (fd, buf, 10, AUTH_TIMEOUT, 1) <= 0) return FALSE; auth_data_len = atoi (buf); if (auth_data_len < 1 || auth_data_len > sizeof(buf)) { syslog_message(LOG_WARNING, "Invalid data length supplied by client"); return FALSE; } if (timed_read (fd, buf, auth_data_len, AUTH_TIMEOUT, 0) != auth_data_len) return FALSE;#ifdef AUTH_MAGIC_COOKIE if (!invoked_from_inetd && server_xauth && server_xauth->data && !memcmp (buf, server_xauth->data, auth_data_len)) { return TRUE; }#else syslog_message (LOG_WARNING, "Client tried Xauth, but server is " "not compiled with Xauth");#endif /* * auth failed, but allow this to fall through to the * GNU_SECURE protocol.... */ if (verbose_output) { if (changed_uid || invoked_from_inetd) syslog_message (LOG_WARNING, "Xauth authentication not allowed, " "trying GNU_SECURE ..."); else syslog_message (LOG_WARNING, "Xauth authentication failed, " "trying GNU_SECURE auth..."); } } /* Other auth protocols go here, and should execute only if * the * auth_protocol name matches. */ /* Now, try the old GNU_SECURE stuff... */ if (enable_debug) syslog_message (LOG_DEBUG, "Doing GNU_SECURE auth ..."); /* Now check the chain for that hash key */ for (i = 0; i < HOST_TABLE_ENTRIES; i++) { if (enable_debug) syslog_message (LOG_DEBUG, "Trying %lx - %lx", host_addr, permitted_hosts [i]); if (permitted_hosts [i] == 0L) return (FALSE); if (host_addr == permitted_hosts [i]) return (TRUE); } return (FALSE);}/* * setup_table -- initialise the table of hosts allowed to contact the server, * by reading from the file specified by the GNU_SECURE * environment variable * Put in the local machine, and, if a security file is specifed, * add each host that is named in the file. * Return the number of hosts added. */static intsetup_table (void){ char hostname [HOSTNAMSZ], screen [BUFSIZ]; long host_addr; int i, hosts = 0; /* Make sure every entry is null */ for (i = 0; i < HOST_TABLE_ENTRIES; i++) permitted_hosts [i] = 0; gethostname (hostname, HOSTNAMSZ); if ((host_addr = glibtop_internet_addr (hostname)) == -1) { syslog_io_message (LOG_ERR, "Can't resolve '%s'", hostname); exit (1); }#ifdef AUTH_MAGIC_COOKIE sprintf (screen, "%d", SERVER_PORT); server_xauth = XauGetAuthByAddr (FamilyInternet, sizeof (host_addr), (char *) &host_addr, strlen (screen), screen, strlen (MCOOKIE_X_NAME), MCOOKIE_X_NAME); hosts++;#endif /* AUTH_MAGIC_COOKIE */ /* Resolv host names from permitted_host_names []. */ for (i = 0; i < HOST_TABLE_ENTRIES; i++) { if (!permitted_host_names [i]) continue; if (enable_debug) syslog_message (LOG_DEBUG, "Resolving %s ...", permitted_host_names [i]); permitted_hosts [i] = glibtop_internet_addr (permitted_host_names [i]); if ((long) permitted_hosts [i] == -1) { syslog_io_message (LOG_ERR, "Can't resolve '%s'", permitted_host_names [i]); exit (1); } } if (enable_debug) for (i = 0; i < HOST_TABLE_ENTRIES; i++) syslog_message (LOG_DEBUG, "Host %s - %lx",
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -