📄 rlogind.c
字号:
rc = get_auth (infd, &ad->h, &ad->ap, &ad->enckey, err_msg, &ad->protocol, &cksumtype, &cksum, &cksumlen);#else rc = get_auth (infd, &ad->h, &ad->ap, NULL, err_msg, &ad->protocol, &cksumtype, &cksum, &cksumlen);#endif if (rc != SHISHI_OK) return rc;#ifdef ENCRYPTION /* init IV */ if (encrypt_io) { int i; char *iv; ad->ivtab[0] = &ad->iv1; ad->ivtab[1] = &ad->iv2; keytype = shishi_key_type (ad->enckey); keylen = shishi_cipher_blocksize (keytype); for (i = 0; i < 2; i++) { ad->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: ad->ivtab[i]->keyusage = SHISHI_KEYUSAGE_KCMD_DES; ad->ivtab[i]->iv = malloc (ad->ivtab[i]->ivlen); memset (ad->ivtab[i]->iv, i, ad->ivtab[i]->ivlen); ad->ivtab[i]->ctx = shishi_crypto (ad->h, ad->enckey, ad->ivtab[i]->keyusage, shishi_key_type (ad->enckey), ad->ivtab[i]->iv, ad->ivtab[i]->ivlen); break; case SHISHI_ARCFOUR_HMAC: case SHISHI_ARCFOUR_HMAC_EXP: ad->ivtab[i]->keyusage = SHISHI_KEYUSAGE_KCMD_DES + 6 - 4 * i; ad->ivtab[i]->ctx = shishi_crypto (ad->h, ad->enckey, ad->ivtab[i]->keyusage, shishi_key_type (ad->enckey), NULL, 0); break; default: ad->ivtab[i]->keyusage = SHISHI_KEYUSAGE_KCMD_DES + 6 - 4 * i; ad->ivtab[i]->iv = malloc (ad->ivtab[i]->ivlen); memset (ad->ivtab[i]->iv, 0, ad->ivtab[i]->ivlen); if (ad->protocol == 2) ad->ivtab[i]->ctx = shishi_crypto (ad->h, ad->enckey, ad->ivtab[i]->keyusage, shishi_key_type (ad->enckey), ad->ivtab[i]->iv, ad->ivtab[i]->ivlen); } } }#endif getstr (infd, &ad->lusername, NULL); getstr (infd, &ad->term, "TERM="); getstr (infd, &ad->rusername, NULL); rc = read (infd, &error, sizeof (int)); if ((rc != sizeof (int)) && rc) { free (pwd); free (cksum); return 1; } /* getpwnam crash !!!! pwd = getpwnam (ad->lusername); if (pwd == NULL) { *err_msg = "getpwnam failed"; syslog (LOG_ERR, "getpwnam failed: %m"); return 1; } syslog (LOG_INFO | LOG_AUTH, "%sKerberos V login from %s on %s\n", (pwd->pw_uid == 0) ? "ROOT " : "", ad->lusername, ad->hostname); */ free (pwd); syslog (LOG_INFO | LOG_AUTH, "Kerberos V login from %s on %s\n", ad->lusername, ad->hostname); /* verify checksum */ if (getsockname (infd, (struct sockaddr *) &sock, &socklen) < 0) { syslog (LOG_ERR, "Can't get sock name"); fatal (infd, "Can't get sockname", 1); } snprintf (cksumdata, 100, "%u:%s%s", ntohs (sock.sin_port), ad->term + 5, ad->lusername); rc = shishi_checksum (ad->h, ad->enckey, 0, cksumtype, cksumdata, strlen (cksumdata), &compcksum, &compcksumlen); free (cksum); if (rc != SHISHI_OK || compcksumlen != cksumlen || memcmp (compcksum, cksum, cksumlen) != 0) { /* err_msg crash ? */ /* *err_msg = "checksum verify failed"; */ syslog (LOG_ERR, "checksum verify failed: %s", shishi_error (ad->h)); free (compcksum); return 1; } free (compcksum); rc = shishi_authorized_p (ad->h, shishi_ap_tkt (ad->ap), ad->lusername); if (!rc) { syslog (LOG_ERR, "User is not authorized to log in as: %s", ad->lusername); shishi_ap_done (ad->ap); return 1; } shishi_ap_done (ad->ap); return SHISHI_OK;}#endif#endif#define BUFFER_SIZE 128voidgetstr (int infd, char **ptr, const char *prefix){ char c; char *buf; int pos; int size = BUFFER_SIZE; if (prefix) { int len = strlen (prefix); if (size < len + 1) size = len + 1; } buf = malloc (size); if (!buf) { syslog (LOG_ERR, "not enough memory"); exit (1); } pos = 0; if (prefix) { strcpy (buf, prefix); pos += strlen (buf); } do { if (read (infd, &c, 1) != 1) { syslog (LOG_ERR, "read error: %m"); exit (1); } if (pos == size) { size += BUFFER_SIZE; buf = realloc (buf, size); if (!buf) { syslog (LOG_ERR, "not enough memory"); exit (1); } } buf[pos++] = c; } while (c != 0); *ptr = buf;}#define pkcontrol(c) ((c)&(TIOCPKT_FLUSHWRITE|TIOCPKT_NOSTOP|TIOCPKT_DOSTOP))char magic[2] = { 0377, 0377 };char oobdata[] = { TIOCPKT_WINDOW }; /* May be modified by protocol/control */#ifdef SHISHIchar oobdata_new[] = { 0377, 0377, 'o', 'o', TIOCPKT_WINDOW };#endifvoidprotocol (int f, int p, struct auth_data *ap){ char fibuf[1024], *pbp = NULL, *fbp = NULL; int pcc = 0, fcc = 0; int cc, nfd, n; char cntl;#ifdef TIOCPKT int tiocpkt_on = 0;#endif /* * Must ignore SIGTTOU, otherwise we'll stop * when we try and set slave pty's window shape * (our controlling tty is the master pty). */ signal (SIGTTOU, SIG_IGN);#ifdef SHISHI if (kerberos && (ap->protocol == 2)) { ENC_WRITE (n, f, oobdata_new, 5, ap); } else#endif send (f, oobdata, 1, MSG_OOB); /* indicate new rlogin */ if (f > p) nfd = f + 1; else nfd = p + 1; if (nfd > FD_SETSIZE) { syslog (LOG_ERR, "select mask too small, increase FD_SETSIZE"); fatal (f, "internal error (select mask too small)", 0); } while (1) { fd_set ibits, obits, ebits, *omask; FD_ZERO (&ebits); FD_ZERO (&ibits); FD_ZERO (&obits); omask = (fd_set *) NULL; if (fcc) { FD_SET (p, &obits); omask = &obits; } else FD_SET (f, &ibits); if (pcc >= 0) { if (pcc) { FD_SET (f, &obits); omask = &obits; } else FD_SET (p, &ibits); } FD_SET (p, &ebits); if ((n = select (nfd, &ibits, omask, &ebits, 0)) < 0) { if (errno == EINTR) continue; fatal (f, "select", 1); } if (n == 0) { /* shouldn't happen... */ sleep (5); continue; } if (FD_ISSET (p, &ebits)) { cc = read (p, &cntl, 1); if (cc == 1 && pkcontrol (cntl)) { cntl |= oobdata[0]; send (f, &cntl, 1, MSG_OOB); if (cntl & TIOCPKT_FLUSHWRITE) { pcc = 0; FD_CLR (p, &ibits); } } } if (FD_ISSET (f, &ibits)) { ENC_READ (fcc, f, fibuf, sizeof (fibuf), ap); if (fcc < 0 && errno == EWOULDBLOCK) fcc = 0; else { register char *cp; int left; if (fcc <= 0) break; fbp = fibuf; for (cp = fibuf; cp < fibuf + fcc - 1; cp++) if (cp[0] == magic[0] && cp[1] == magic[1]) { int len; left = fcc - (cp - fibuf); len = control (p, cp, left); if (len) { left -= len; if (left > 0) memmove (cp, cp + len, left); fcc -= len; cp--; } } FD_SET (p, &obits); /* try write */ } } if (FD_ISSET (p, &obits) && fcc > 0) { cc = write (p, fbp, fcc); if (cc > 0) { fcc -= cc; fbp += cc; } } if (FD_ISSET (p, &ibits)) { char dbuf[1024 + 1]; pcc = read (p, dbuf, sizeof dbuf); pbp = dbuf; if (pcc < 0) { if (errno == EWOULDBLOCK) pcc = 0; else break; } else if (pcc == 0) { break; } else if (dbuf[0] == 0) { pbp++; pcc--; IF_NOT_ENCRYPT (FD_SET (f, &obits)); /* try write */ } else { if (pkcontrol (dbuf[0])) { dbuf[0] |= oobdata[0]; send (f, &dbuf[0], 1, MSG_OOB); } pcc = 0; } } if ((FD_ISSET (f, &obits)) && pcc > 0) { ENC_WRITE (cc, f, pbp, pcc, ap); if (cc < 0 && errno == EWOULDBLOCK) { /* * This happens when we try write after read * from p, but some old kernels balk at large * writes even when select returns true. */ if (!FD_ISSET (p, &ibits)) sleep (5); continue; } if (cc > 0) { pcc -= cc; pbp += cc; } } }}/* Handle a "control" request (signaled by magic being present) in the data stream. For now, we are only willing to handle window size changes. */intcontrol (int pty, char *cp, size_t n){ struct winsize w; if (n < 4 + sizeof (w) || cp[2] != 's' || cp[3] != 's') return (0); oobdata[0] &= ~TIOCPKT_WINDOW; /* we know he heard */ memmove (&w, cp + 4, sizeof w); w.ws_row = ntohs (w.ws_row); w.ws_col = ntohs (w.ws_col); w.ws_xpixel = ntohs (w.ws_xpixel); w.ws_ypixel = ntohs (w.ws_ypixel); ioctl (pty, TIOCSWINSZ, &w); return (4 + sizeof w);}RETSIGTYPEcleanup (int signo){ char *p; signo; p = line + sizeof (PATH_DEV) - 1;#ifdef UTMPX utmp_logout (p); chmod (line, 0644); chown (line, 0, 0);#else if (logout (p)) logwtmp (p, "", ""); chmod (line, 0666); chown (line, 0, 0); *p = 'p'; chmod (line, 0666); chown (line, 0, 0);#endif shutdown (netf, 2); exit (1);}intin_local_domain (char *hostname){ char *p = topdomain (hostname, local_dot_count); return p && strcasecmp (p, local_domain_name) == 0;}char *topdomain (char *name, int max_dots){ char *p; int dot_count = 0; for (p = name + strlen (name) - 1; p >= name; p--) { if (*p == '.' && ++dot_count == max_dots) return p + 1; } return name;}voidfatal (int f, const char *msg, int syserr){ int len; char buf[BUFSIZ], *bp = buf; /* * Prepend binary one to message if we haven't sent * the magic null as confirmation. */ if (!confirmed) *bp++ = '\01'; /* error indicator */ if (syserr) snprintf (bp, sizeof buf - (bp - buf), "rlogind: %s: %s.\r\n", msg, strerror (errno)); else snprintf (bp, sizeof buf - (bp - buf), "rlogind: %s.\r\n", msg); len = strlen (bp); write (f, buf, bp + len - buf); exit (1);}static const char usage_str[] = "usage: rlogind [options]\n" "\n" "Options are:\n" " -a, --verify-hostname Ask hostname for verification\n" " -d, --daemon Daemon mode\n" " -l, --no-rhosts Ignore .rhosts file\n" " -L, --local-domain=NAME Set local domain name\n" " -n, --no-keepalive Do not set SO_KEEPALIVE\n"#if defined(KERBEROS) || defined(SHISHI) " -k, --kerberos Use kerberos IV/V authentication\n"#ifdef ENCRYPTION " -x, --encrypt Use DES encryption\n"#endif /* ENCRYPTION */#endif /* KERBEROS */ " -D, --debug[=LEVEL] Set debug level\n" " -h, --help Display usage instructions\n" " -V, --version Display program version\n" " -o, --allow-root Allow uid == 0 to login, disable by default\n" " -p, --port PORT Listen on given port (valid only in daemon mode)\n" " -r, --reverse-required Require reverse resolving of a remote host IP\n";voidusage (){ printf ("%s\n" "Send bug reports to %s\n", usage_str, PACKAGE_BUGREPORT);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -