📄 deslogind.c
字号:
/* * Copyright 1994 David A. Barrett. * * Remote login deaemon with authentication and data encryption of channel * * Revision History: * * 12-May-94: Fixed two malloc bugs in gendeskd.c and deslogind.c. * 14-Jun-94: * deslogind.c: Added -w option for login wrapper feature * -w option busted on HP-UX; wait for help. * Added RHOSTNAME environment variable. * utmp.c: added update of wtmp to writeut * log.c: ifdef'd return result from openlog * socket.c: errno.h inside #undef posix for ENOTSOCK (BSD/386) * tty.c: added control terminal setting for BSD/386 * changed "psignal" to "posignal" to avoid BSD name conflict * added changes for BSDI BSD/386 * changed include <ctype.h> before <stdlib.h> for BSD/386 * Thanks to Tom Markson <tom@twilight.com> for BSD/386 changes. * 24-Jan-95: Added WRITE_RETRY_TIME to txfr.c to fix linux lost connections * * Still to do: * Make the -w option work for HP-UX * Add '.' notation to hostname stuff on socket.c to allow IP addr to be used * figure out a way to run commands and pipelines: * it requires a way to make sure the pipes are flushed before exit * it may require detection of EOF across network * Add ip address to utmp entry for system V. fix in socket.c. * On hpux, can't reuse port numbers for a short while after exit. Why? * Check permissions on deslogin.users, and deslogin.log; issue warning. * Encrypt the log files too. * Catch all Coredump signals to prevent hostile user from signaling * us and examining the carcass for keys (deslogind, deslogingw). * How do you prevent a debugger from doing a ptrace(PT_ATTACH)? (cant!) * Compression (tricky because you must not impose delays) * Allow socket to be connected directly to resulting process * (won't happen because the parent is needed to encipher the data stream) * Figure out a way to improve protection from local users: * X11 server DISPLAY variable: * :0 still doesn't help because that creates a unix-domain socket: * named /usr/spool/sockets/X11/0 * * Deslogin: * Make sure that getPassphrase is not reading from unsecure device: * check $DISPLAY envt for 'local:' or ':' as prefix * check utmp to make sure not rlogin from somewhere else * permissions on Ctermid? Trojan Ctermid? * Protect against trojan of deslogin itself. * * Enhancements: * See rshd man page for internet socket login protocol. * Secondary socket for stderr ASCII port # '\0' terminated 0=none * upto 16 character server user name '\0' terminated * upto 16 character client user name '\0' terminated * command to execute limited by system's argument list * Server authenticates channel and sends a null byte to stderr sock * errors are sent with a '\1' as leading byte with mesage. * Notice that hpux rlogind man page describes a different protocol also. * Add passphrase command * * Inetd notes: * Umask and uid inherited from init and envt * Socket is available as stdin and stdout * * Notes: * I have set posignal so that SIGSTOP will not cause SIGCHLD. This allows * you to STOP a potential intruder in his tracks by sending SIGSTOP to * the process and then attach a debugger to it and examine what is going * on. * * Comments which Give a Section number and line number correspond to * quotes from IEEE Std 1003.1-1990 (ISO/IEC 9945-1: 1990). * (E.g. Sect5:10-12 means Section 5 lines 10 through 12 inclusive) */#define _POSIX_SOURCE/* * This is a mess. HP-UX ANSI C won't define pid_t in <sys/types.h> unless * _POSIX_SOURCE is defined. Other machines may refuse to define it. Pick * what's appropriate. <utmp.h> uses pid_t. On __SOLARIS__, <utmpx.h> * uses (struct timeval) which won't be defined unless !_POSIX_SOURCE. */#if defined(__SOLARIS__) /* { */#undef _POSIX_SOURCE /* allows struct timeval to be defined */#undef _POSIX_C_SOURCE#include <sys/types.h> /* gid_t pid_t uid_t clock_t */#include <time.h> /* time (also needed for "utmp.h") */#define _POSIX_SOURCE#define _POSIX_C_SOURCE#else /* } { */#include <sys/types.h> /* gid_t pid_t uid_t clock_t */#include <time.h> /* time (also needed for "utmp.h") */#endif /* } */#include <sys/times.h> /* struct tms */ /* mips fails to define prototype for times() unless */ /* __POSIX is defined. Strange. */#include <unistd.h> /* chdir close dup execve fork */ /* getlogin getpid getppid getpgrp */ /* setsid setgid setpgid setuid ctermid */ /* _SC_NGROUPS_MAX */#include <limits.h> /* NGROUPS_MAX */#include <ctype.h> /* must be before stdlib.h for BSDI's BSD 386 */#include <stdlib.h> /* atexit exit free malloc */#include <stdio.h> /* (fopen fclose fgets scanf printf etc.) */#include <string.h> /* memcmp memcpy memset */#include <errno.h>#include <sys/stat.h> /* umask flags */#include <fcntl.h>#include <termios.h>#include <signal.h>#include <pwd.h>#include <sys/wait.h> /* WNOHANG */#include "pty.h"#include "tty.h"#include "auth.h"#include "txfr.h"#include "socket.h"#include "log.h"#include "deslogin.h"#include "posignal.h"#include "utmp.h" /* setlogin */#include "group.h" /* getLoginGroups */#if defined(sun)#define BSD#endif#if defined(mips)#define BSD#endif/* * Begin customizable area */#if !defined(DEFAULT_UMASK) /* login user mask */#define DEFAULT_UMASK S_IWGRP|S_IWOTH#endif#if !defined(TTY_MODE) /* login permissions for controlling terminal */#define TTY_MODE (S_IRUSR|S_IWUSR|S_IWGRP|S_IWOTH)#endif#define TTY_RWANY (S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH)/* * These environment variables may be overwridden in the makefile */#if defined(BSD) /* sun dec mips */#if !defined(USERPATH)#define USERPATH ":/usr/ucb:/bin:/usr/bin"#endif#if !defined(SYSTEMPATH)#define SYSTEMPATH "/etc:/usr/ucb:/bin:/usr/bin"#endif#endif#if defined(hpux) /* hpux only */#define DEFAULT_MAIL "/usr/mail/"#endif#if !defined(USER_ENV) /* Additional envt variable to store userName */#define USER_ENV "USER" /* BSD (sun dec mips) xdm (not hpux) */#endif#if !defined(USERPATH)#define USERPATH ":/bin:/usr/bin"#endif#if !defined(SYSTEMPATH)#define SYSTEMPATH "/etc:/bin:/usr/bin"#endif#if !defined(DEFAULT_TERM)#define DEFAULT_TERM "network"#endif#if !defined(USER_FILE)#define USER_FILE "/usr/local/etc/deslogind.users"#endif#if !defined(NOLOGIN_FILE)#define NOLOGIN_FILE "/etc/nologin"#endif#if !defined(LOG_FILE)#define LOG_FILE "/usr/adm/deslogind.log"#endif/* * End of customizable area */#define PROGNAME_SIZE 255#define USERNAME_SIZE 17 /* assumption based on rshd man page */#define MAX_HOSTNAME 255extern int optind;extern char *optarg;#if defined(__STDC__) || defined(__cplusplus)extern int askTty(char *, char *, unsigned, int);#elseextern int askTty();#endifextern unsigned long defaultKey[64];static char ident[] = " @(#) deslogind.c version 1.32 03-Mar-95 Copyright 1995 by Dave Barrett(barrett@asgard.cs.Colorado.EDU)\n";static char RCSid[] = " @(#) deslogind.c $Revision: 1.13 $ $Date: 95/03/08 01:13:14 $\n";char mainProgName[PROGNAME_SIZE];char *progName, *argcName;int debug = 0;int verbose = 0;unsigned long inBytes = 0; /* for txfr */unsigned long outBytes = 0;struct termios oldmodes;char *defaultShell = "/bin/ksh";char *defaultArgv[] = { (char *) 0, /* substituted with arg0 variable later */ (char *) 0, /* if -w, then substitudet with loginArg1 */ (char *) 0, /* if -w, then remote host name */ (char *) 0};/* * Static data for -w option */char loginArg1[] = "-h";char loginProg[] = LOGIN_PROG;char loginCwd[] = "/";void setProgName() { pid_t pid = getpid(); /* can't fail */ sprintf(mainProgName, "%s[%lu]", argcName, (unsigned long) pid); progName = mainProgName;}void sigHandler(sig) int sig;{ switch (sig) { case SIGHUP: case SIGTERM: case SIGINT: log("%s: Terminated by signal %d\n", progName, sig); exit(1); /* make sure cleanup occurs on interrupt */ break; case SIGCHLD: /* child died */ if (debug) { log("%s: (main) SIGCHLD\n", progName); } break; default: break; }}char sname[PTY_NAMESIZE]; /* slave pty opened for shell control terminal */char userName[USERNAME_SIZE]; /* login name of user */char rhostName[MAX_HOSTNAME]; /* remote login host */int chldStat = 0;/* * Registered with atexit */void eraselogin(){ int res; res = setlogin(sname, userName, rhostName, &chldStat); if (res < 0) { log("%s: WARNING--eraselogin \"%s\" failed--%s\n", progName, sname, ERRMSG); } res = chmod(sname, TTY_RWANY); if (res < 0) { log("%s: WARNING--chmod \"%s\" to %o failed--%s\n", progName, sname, TTY_RWANY, ERRMSG); }}/* * Duplicate the given file descriptor to the given mode with error check. */int dupFd(fd, name, mode) int fd; char *name; mode_t mode;{ int newfd, res; newfd = dup(fd); if (newfd < 0) { log("%s: dup of fd %d (\"%s\") failed--%s\n", progName, fd, name, ERRMSG); exit(1); } res = fcntl(newfd, F_SETFL, mode); if (res < 0) { log("%s: fcntl of fd %d (\"%s\") failed--%s\n", progName, newfd, name, ERRMSG); exit(1); } return newfd;}/* * Memory allocation with error check and abort */void *allocate(size) register unsigned size;{ register void *res = (void *) malloc(size); if (res == (void *) 0) { log("%s: allocate of %u bytes failed\n", progName, size); exit(1); } return res;}/* * Create a copy of the input string. (0 if out of memory) */char *newString(chp) register char *chp;{ register unsigned len = 0; register char *res; if (chp != (char *) 0) { len = strlen(chp); } res = (char *) allocate(len+1); if (res != (char *) 0) { memcpy(res, chp, len); res[len] = '\0'; } return res;}void showEnv(prefix, envp) char *prefix; register char **envp;{ while (*envp != (char *) 0) { log("%s%s\n", prefix, *envp++); } log("\n");}/* * Add a new entry to the given environment. Return the new environment. * Set input ep to NULL to create initial invironment * Frees the old environment. * * If out of memory occurs, 0 is returned */char **updateEnv(ep, key, value) char **ep; char *key; char *value;{ register char **chpp = ep, **dstp = (char **) 0, **res; char *newEntry = (char *) 0; unsigned int envsize = 0, keylen = 0, vallen = 0; if (key != (char *) 0) { keylen = strlen(key); } if (ep != (char **) 0) { while (*chpp != (char *) 0) { if (keylen != 0 && strncmp(key, *chpp, keylen) == 0) { dstp = chpp; } chpp++; } envsize = chpp - ep; } if (keylen != 0 && value != (char *) 0) { vallen = strlen(value); newEntry = (char *) allocate(keylen+vallen+2); if (newEntry == (char *) 0) { return (char **) 0; } memcpy(newEntry, key, keylen); memcpy(newEntry + keylen, "=", 1); memcpy(newEntry + keylen + 1, value, vallen); newEntry[keylen + vallen + 1] = '\0'; } if (dstp != (char **) 0) { if (newEntry != (char *) 0) { /* replace the entry */ free(dstp);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -