📄 rlogin.c
字号:
ivtab[0] = &iv1; ivtab[1] = &iv2; for (i=0; i<2; i++) { ivtab[i]->ivlen = keylen; switch (keytype) { case SHISHI_DES_CBC_CRC: case SHISHI_DES_CBC_MD4: case SHISHI_DES_CBC_MD5: case SHISHI_DES_CBC_NONE: case SHISHI_DES3_CBC_HMAC_SHA1_KD: ivtab[i]->keyusage = SHISHI_KEYUSAGE_KCMD_DES; ivtab[i]->iv = malloc (ivtab[i]->ivlen); memset (ivtab[i]->iv, !i, ivtab[i]->ivlen); ivtab[i]->ctx = shishi_crypto (handle, key, ivtab[i]->keyusage, shishi_key_type (key), ivtab[i]->iv, ivtab[i]->ivlen); break; case SHISHI_ARCFOUR_HMAC: case SHISHI_ARCFOUR_HMAC_EXP: ivtab[i]->keyusage = SHISHI_KEYUSAGE_KCMD_DES + 2 + 4*i; ivtab[i]->ctx = shishi_crypto (handle, key, ivtab[i]->keyusage, shishi_key_type (key), NULL, 0); break; default : ivtab[i]->keyusage = SHISHI_KEYUSAGE_KCMD_DES + 2 + 4*i; ivtab[i]->iv = malloc (ivtab[i]->ivlen); memset (ivtab[i]->iv, 0, ivtab[i]->ivlen); ivtab[i]->ctx = shishi_crypto (handle, key, ivtab[i]->keyusage, shishi_key_type (key), ivtab[i]->iv, ivtab[i]->ivlen); } } } } else#else rem = krcmd_mutual (&host, sp->s_port, user, term, 0, dest_realm, &cred, schedule); else#endif#endif /* CRYPT */ rem = krcmd (#if defined (SHISHI) &handle, &host, sp->s_port, &user, term, 0, dest_realm);#else &host, sp->s_port, user, term, 0, dest_realm);#endif if (rem < 0) { use_kerberos = 0; sp = getservbyname ("login", "tcp"); if (sp == NULL) error (1, 0, "unknown service login/tcp."); if (errno == ECONNREFUSED) warning ("remote host doesn't support Kerberos"); if (errno == ENOENT) warning ("can't provide Kerberos auth data"); goto try_connect; } } else {# ifdef ENCRYPTION if (doencrypt) error (1, 0, "the -x flag requires Kerberos authentication.");#endif /* CRYPT */ if (!user) user = pw->pw_name; rem = rcmd (&host, sp->s_port, pw->pw_name, user, term, 0); }#else if (!user) user = pw->pw_name; rem = rcmd (&host, sp->s_port, pw->pw_name, user, term, 0);#endif /* KERBEROS */ if (rem < 0) exit (1); { int one = 1; if (dflag && setsockopt (rem, SOL_SOCKET, SO_DEBUG, (char *) &one, sizeof one) < 0) error (0, errno, "setsockopt DEBUG (ignored)"); }#if defined (IP_TOS) && defined (IPPROTO_IP) && defined (IPTOS_LOWDELAY) { int one = IPTOS_LOWDELAY; if (setsockopt (rem, IPPROTO_IP, IP_TOS, (char *)&one, sizeof (int)) < 0) error (0, errno, "setsockopt TOS (ignored)"); }#endif /* Now change to the real user ID. We have to be set-user-ID root to get the privileged port that rcmd () uses, however we now want to run as the real user who invoked us. */ seteuid (uid); setuid (uid); doit (&smask); /*NOTREACHED*/ return 0;}/* Some systems, like QNX/Neutrino , The constant B0, B50,.. maps straigth to the actual speed, 0, 50, ..., where on other system like GNU/Linux it maps to a const 0, 1, ... i.e the value are encoded. cfgetispeed(), according to posix should return a constant value reprensenting the Baud. So to be portable we have to the conversion ourselves. *//* Some values are not not define by POSIX. */#ifndef B7200#define B7200 B4800#endif#ifndef B14400#define B14400 B9600#endif#ifndef B19200# define B19200 B14400#endif#ifndef B28800#define B28800 B19200#endif#ifndef B38400# define B38400 B28800#endif#ifndef B57600#define B57600 B38400#endif#ifndef B76800#define B76800 B57600#endif#ifndef B115200#define B115200 B76800#endif#ifndef B230400#define B230400 B115200#endifstruct termspeeds{ unsigned int speed; unsigned int sym;} termspeeds[] ={ { 0, B0 }, { 50, B50 }, { 75, B75 }, { 110, B110 }, { 134, B134 }, { 150, B150 }, { 200, B200 }, { 300, B300 }, { 600, B600 }, { 1200, B1200 }, { 1800, B1800 }, { 2400, B2400 }, { 4800, B4800 }, { 7200, B7200 }, { 9600, B9600 }, { 14400, B14400 }, { 19200, B19200 }, { 28800, B28800 }, { 38400, B38400 }, { 57600, B57600 }, { 115200, B115200 }, { 230400, B230400 }, { -1, B230400 }};unsigned intspeed_translate (unsigned int sym){ unsigned int i; for (i = 0; i < (sizeof (termspeeds) / sizeof (*termspeeds)); i++) { if (termspeeds[i].sym == sym) return termspeeds[i].speed; } return 0;}/* Returns the terminal speed for the file descriptor FD, or SPEED_NOTATTY if FD is not associated with a terminal. */intspeed (int fd){ struct termios tt; if (tcgetattr (fd, &tt) == 0) { /* speed_t sp; */ unsigned int sp = cfgetispeed (&tt); return speed_translate (sp); } return SPEED_NOTATTY;}pid_t child;struct termios deftt;struct termios ixon_state;struct termios nott;voiddoit (sigset_t *smask){ int i; for (i = 0; i < NCCS; i++) nott.c_cc[i] = _POSIX_VDISABLE; tcgetattr(0, &deftt); nott.c_cc[VSTART] = deftt.c_cc[VSTART]; nott.c_cc[VSTOP] = deftt.c_cc[VSTOP]; setsig (SIGINT, SIG_IGN); setsignal (SIGHUP); setsignal (SIGQUIT); child = fork (); if (child == -1) { error (0, errno, "fork"); done (1); } if (child == 0) { mode (1); if (reader (smask) == 0) { /* If the reader () return 0, the socket to the server returned an EOF, meaning the client logged out of the remote system. This is the normal termination. */ msg ("connection closed."); exit (0); } /* If the reader () returns nonzero, the socket to the server returned an error. Somethingg went wrong. */ sleep (1); msg ("\007connection closed."); /* 007 == ASCII bell. */ exit (1); } /* * Parent process == writer. * * We may still own the socket, and may have a pending SIGURG (or might * receive one soon) that we really want to send to the reader. When * one of these comes in, the trap copytochild simply copies such * signals to the child. We can now unblock SIGURG and SIGUSR1 * that were set above. */ /* Reenables SIGURG and SIUSR1. */ sigprocmask (SIG_SETMASK, smask, (sigset_t *) 0); setsig (SIGCHLD, catch_child); writer (); /* If the write returns, it means the user entered "~." on the terminal. In this case we terminate and the server will eventually get an EOF on its end of the network connection. This should cause the server to log you out on the remote system. */ msg ("closed connection.");#ifdef SHISHI if (use_kerberos) { shishi_done (handle);#ifdef ENCRYPTION if (doencrypt) { shishi_key_done (key); shishi_crypto_close (iv1.ctx); shishi_crypto_close (iv2.ctx); free (iv1.iv); free (iv2.iv); }#endif }#endif done (0);}/* Enable a signal handler, unless the signal is already being ignored. This function is called before the fork (), for SIGHUP and SIGQUIT. *//* Trap a signal, unless it is being ignored. */voidsetsignal (int sig){ sig_t handler; sigset_t sigs; sigemptyset(&sigs); sigaddset(&sigs, sig); sigprocmask(SIG_BLOCK, &sigs, &sigs); handler = setsig (sig, exit); if (handler == SIG_IGN) setsig (sig, handler); sigprocmask(SIG_SETMASK, &sigs, (sigset_t *) 0);}/* This function is called by the parent: (1) at the end (user terminates the client end); (2) SIGCLD signal - the sigcld_parent () function. (3) SIGPPE signal - the connection has dropped. We send the child a SIGKILL signal, which it can't ignore, then wait for it to terminate. */voiddone (int status){ pid_t w; int wstatus; mode(0); if (child > 0) { /* make sure catch_child does not snap it up */ setsig (SIGCHLD, SIG_DFL); if (kill (child, SIGKILL) >= 0) while ((w = wait (&wstatus)) > 0 && w != child) continue; } exit (status);}int dosigwinch;/* * This is called when the reader process gets the out-of-band (urgent) * request to turn on the window-changing protocol. */RETSIGTYPEwriteroob (int signo ARG_UNUSED){ if (dosigwinch == 0) { sendwindow (); setsig (SIGWINCH, sigwinch); } dosigwinch = 1;}RETSIGTYPEcatch_child (int signo ARG_UNUSED){ int status; pid_t pid; for (;;) { pid = waitpid (-1, &status, WNOHANG | WUNTRACED); if (pid == 0) return; /* if the child (reader) dies, just quit */ if (pid < 0 || (pid == child && !WIFSTOPPED (status))) done (WEXITSTATUS (status) | WTERMSIG (status)); } /* NOTREACHED */}/* * writer: write to remote: 0 -> line. * ~. terminate * ~^Z suspend rlogin process. * ~<delayed-suspend char> suspend rlogin process, but leave reader alone. */voidwriter (){ register int bol, local, n; char c; bol = 1; /* beginning of line */ local = 0; for (;;) { n = read (STDIN_FILENO, &c, 1); if (n <= 0) { if (n < 0 && errno == EINTR) continue; break; } /* * If we're at the beginning of the line and recognize a * command character, then we echo locally. Otherwise, * characters are echo'd remotely. If the command character * is doubled, this acts as a force and local echo is * suppressed. */ if (bol) { bol = 0; if (!noescape && c == escapechar) { local = 1; continue; } } else if (local) { local = 0; if (c == '.' || c == deftt.c_cc[VEOF]) { echo (c); break; } if (c == deftt.c_cc[VSUSP]#ifdef VDSUSP || c == deftt.c_cc[VDSUSP]#endif ) { bol = 1; echo (c); stop (c); continue; } if (c != escapechar)#ifdef ENCRYPTION#ifdef KERBEROS if (doencrypt) des_write (rem, (char *)&escapechar, 1); else#elif defined(SHISHI) if (doencrypt) writeenc (handle, rem, (char *)&escapechar, 1, &wlen, &iv2, key, 2); else#endif#endif write (rem, &escapechar, 1); }#ifdef ENCRYPTION#ifdef KERBEROS if (doencrypt) { if (des_write (rem, &c, 1) == 0) { msg ("line gone"); break; } } else#elif defined(SHISHI) if (doencrypt) { writeenc (handle, rem, &c, 1, &wlen, &iv2, key, 2); if (wlen == 0) { msg ("line gone"); break; } } else#endif#endif if (write (rem, &c, 1) == 0) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -