📄 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. * * 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#include <sys/types.h> /* gid_t pid_t uid_t clock_t */#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 */ /* _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.); ctermid */#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 <time.h> /* time asctime */#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 */#ifdef sun#define BSD#endif#ifdef mips#define BSD#endif/* * Begin customizable area */#ifndef DEFAULT_UMASK /* login user mask */#define DEFAULT_UMASK S_IWGRP|S_IWOTH#endif#ifndef 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 */#ifdef BSD /* sun dec mips */#ifndef USERPATH#define USERPATH ":/usr/ucb:/bin:/usr/bin"#endif#ifndef SYSTEMPATH#define SYSTEMPATH "/etc:/usr/ucb:/bin:/usr/bin"#endif#endif#ifdef hpux /* hpux only */#define DEFAULT_MAIL "/usr/mail/"#endif#ifndef USER_ENV /* Additional envt variable to store userName */#define USER_ENV "USER" /* BSD (sun dec mips) xdm (not hpux) */#endif#ifndef USERPATH#define USERPATH ":/bin:/usr/bin"#endif#ifndef SYSTEMPATH#define SYSTEMPATH "/etc:/bin:/usr/bin"#endif#ifndef DEFAULT_TERM#define DEFAULT_TERM "network"#endif#ifndef USER_FILE#define USER_FILE "/usr/local/etc/deslogind.users"#endif#ifndef NOLOGIN_FILE#define NOLOGIN_FILE "/etc/nologin"#endif#ifndef 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.10 16-Jun-94 Copyright 1994 by Dave Barrett(barrett@asgard.cs.Colorado.EDU)\n";static char RCSid[] = " @(#) deslogind.c $Revision: 1.10 $ $Date: 94/06/14 12:17:58 $\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 *//* * Registered with atexit */void eraselogin(){ int res; res = setlogin(sname, (char *) 0, (char *) 0); 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); *dstp = newEntry; return ep; } else { /* delete the entry */ *dstp = ep[envsize-1]; free(ep[envsize-1]); /* could cause problems */ ep[envsize-1] = (char *) 0; return ep; } } if (newEntry != (char *) 0) { envsize++; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -