rshd.c (51433) | rshd.c (56590) |
---|---|
1/*- 2 * Copyright (c) 1988, 1989, 1992, 1993, 1994 3 * The Regents of the University of California. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 28 unchanged lines hidden (view full) --- 37 The Regents of the University of California. All rights reserved.\n"; 38#endif /* not lint */ 39 40#ifndef lint 41#if 0 42static const char sccsid[] = "@(#)rshd.c 8.2 (Berkeley) 4/6/94"; 43#endif 44static const char rcsid[] = | 1/*- 2 * Copyright (c) 1988, 1989, 1992, 1993, 1994 3 * The Regents of the University of California. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 28 unchanged lines hidden (view full) --- 37 The Regents of the University of California. All rights reserved.\n"; 38#endif /* not lint */ 39 40#ifndef lint 41#if 0 42static const char sccsid[] = "@(#)rshd.c 8.2 (Berkeley) 4/6/94"; 43#endif 44static const char rcsid[] = |
45 "$FreeBSD: head/libexec/rshd/rshd.c 51433 1999-09-19 22:05:32Z markm $"; | 45 "$FreeBSD: head/libexec/rshd/rshd.c 56590 2000-01-25 14:52:10Z shin $"; |
46#endif /* not lint */ 47 48/* 49 * remote shell server: 50 * [port]\0 51 * remuser\0 52 * locuser\0 53 * command\0 --- 21 unchanged lines hidden (view full) --- 75#include <stdlib.h> 76#include <string.h> 77#include <syslog.h> 78#include <unistd.h> 79#ifdef LOGIN_CAP 80#include <login_cap.h> 81#endif 82 | 46#endif /* not lint */ 47 48/* 49 * remote shell server: 50 * [port]\0 51 * remuser\0 52 * locuser\0 53 * command\0 --- 21 unchanged lines hidden (view full) --- 75#include <stdlib.h> 76#include <string.h> 77#include <syslog.h> 78#include <unistd.h> 79#ifdef LOGIN_CAP 80#include <login_cap.h> 81#endif 82 |
83/* wrapper for KAME-special getnameinfo() */ 84#ifndef NI_WITHSCOPEID 85#define NI_WITHSCOPEID 0 86#endif 87 |
|
83int keepalive = 1; 84int log_success; /* If TRUE, log all successful accesses */ 85int sent_null; 86int no_delay; 87#ifdef CRYPT 88int doencrypt = 0; 89#endif 90 | 88int keepalive = 1; 89int log_success; /* If TRUE, log all successful accesses */ 90int sent_null; 91int no_delay; 92#ifdef CRYPT 93int doencrypt = 0; 94#endif 95 |
91void doit __P((struct sockaddr_in *)); | 96union sockunion { 97 struct sockinet { 98 u_char si_len; 99 u_char si_family; 100 u_short si_port; 101 } su_si; 102 struct sockaddr_in su_sin; 103 struct sockaddr_in6 su_sin6; 104}; 105#define su_len su_si.si_len 106#define su_family su_si.si_family 107#define su_port su_si.si_port 108 109void doit __P((union sockunion *)); |
92void error __P((const char *, ...)); 93void getstr __P((char *, int, char *)); 94int local_domain __P((char *)); 95char *topdomain __P((char *)); 96void usage __P((void)); 97 98#ifndef NO_PAM 99extern int auth_pam __P((char *)); --- 4 unchanged lines hidden (view full) --- 104int 105main(argc, argv) 106 int argc; 107 char *argv[]; 108{ 109 extern int __check_rhosts_file; 110 struct linger linger; 111 int ch, on = 1, fromlen; | 110void error __P((const char *, ...)); 111void getstr __P((char *, int, char *)); 112int local_domain __P((char *)); 113char *topdomain __P((char *)); 114void usage __P((void)); 115 116#ifndef NO_PAM 117extern int auth_pam __P((char *)); --- 4 unchanged lines hidden (view full) --- 122int 123main(argc, argv) 124 int argc; 125 char *argv[]; 126{ 127 extern int __check_rhosts_file; 128 struct linger linger; 129 int ch, on = 1, fromlen; |
112 struct sockaddr_in from; | 130 struct sockaddr_storage from; |
113 114 openlog("rshd", LOG_PID | LOG_ODELAY, LOG_DAEMON); 115 116 opterr = 0; 117 while ((ch = getopt(argc, argv, OPTIONS)) != -1) 118 switch (ch) { 119 case 'a': 120 /* ignored for compatability */ --- 43 unchanged lines hidden (view full) --- 164 linger.l_onoff = 1; 165 linger.l_linger = 60; /* XXX */ 166 if (setsockopt(0, SOL_SOCKET, SO_LINGER, (char *)&linger, 167 sizeof (linger)) < 0) 168 syslog(LOG_WARNING, "setsockopt (SO_LINGER): %m"); 169 if (no_delay && 170 setsockopt(0, IPPROTO_TCP, TCP_NODELAY, &on, sizeof(on)) < 0) 171 syslog(LOG_WARNING, "setsockopt (TCP_NODELAY): %m"); | 131 132 openlog("rshd", LOG_PID | LOG_ODELAY, LOG_DAEMON); 133 134 opterr = 0; 135 while ((ch = getopt(argc, argv, OPTIONS)) != -1) 136 switch (ch) { 137 case 'a': 138 /* ignored for compatability */ --- 43 unchanged lines hidden (view full) --- 182 linger.l_onoff = 1; 183 linger.l_linger = 60; /* XXX */ 184 if (setsockopt(0, SOL_SOCKET, SO_LINGER, (char *)&linger, 185 sizeof (linger)) < 0) 186 syslog(LOG_WARNING, "setsockopt (SO_LINGER): %m"); 187 if (no_delay && 188 setsockopt(0, IPPROTO_TCP, TCP_NODELAY, &on, sizeof(on)) < 0) 189 syslog(LOG_WARNING, "setsockopt (TCP_NODELAY): %m"); |
172 doit(&from); | 190 doit((union sockunion *)&from); |
173 /* NOTREACHED */ 174 return(0); 175} 176 177char username[20] = "USER="; 178char homedir[64] = "HOME="; 179char shell[64] = "SHELL="; 180char path[100] = "PATH="; 181char *envinit[] = 182 {homedir, shell, path, username, 0}; 183char **environ; 184 185void 186doit(fromp) | 191 /* NOTREACHED */ 192 return(0); 193} 194 195char username[20] = "USER="; 196char homedir[64] = "HOME="; 197char shell[64] = "SHELL="; 198char path[100] = "PATH="; 199char *envinit[] = 200 {homedir, shell, path, username, 0}; 201char **environ; 202 203void 204doit(fromp) |
187 struct sockaddr_in *fromp; | 205 union sockunion *fromp; |
188{ 189 extern char *__rcmd_errstr; /* syslog hook from libc/net/rcmd.c. */ 190 struct passwd *pwd; 191 u_short port; 192 fd_set ready, readfrom; 193 int cc, nfd, pv[2], pid, s; 194 int one = 1; 195 char *errorstr; 196 char *cp, sig, buf[BUFSIZ]; 197 char cmdbuf[NCARGS+1], locuser[16], remuser[16]; | 206{ 207 extern char *__rcmd_errstr; /* syslog hook from libc/net/rcmd.c. */ 208 struct passwd *pwd; 209 u_short port; 210 fd_set ready, readfrom; 211 int cc, nfd, pv[2], pid, s; 212 int one = 1; 213 char *errorstr; 214 char *cp, sig, buf[BUFSIZ]; 215 char cmdbuf[NCARGS+1], locuser[16], remuser[16]; |
198 char fromhost[MAXHOSTNAMELEN]; | 216 char fromhost[2 * MAXHOSTNAMELEN + 1]; 217 char numericname[INET6_ADDRSTRLEN]; 218 int af = fromp->su_family, err; |
199 int retval; 200#ifdef CRYPT 201 int rc; 202 int pv1[2], pv2[2]; 203#endif 204#ifdef LOGIN_CAP 205 login_cap_t *lc; 206#endif --- 4 unchanged lines hidden (view full) --- 211#ifdef DEBUG 212 { int t = open(_PATH_TTY, 2); 213 if (t >= 0) { 214 ioctl(t, TIOCNOTTY, (char *)0); 215 (void) close(t); 216 } 217 } 218#endif | 219 int retval; 220#ifdef CRYPT 221 int rc; 222 int pv1[2], pv2[2]; 223#endif 224#ifdef LOGIN_CAP 225 login_cap_t *lc; 226#endif --- 4 unchanged lines hidden (view full) --- 231#ifdef DEBUG 232 { int t = open(_PATH_TTY, 2); 233 if (t >= 0) { 234 ioctl(t, TIOCNOTTY, (char *)0); 235 (void) close(t); 236 } 237 } 238#endif |
219 fromp->sin_port = ntohs((u_short)fromp->sin_port); 220 if (fromp->sin_family != AF_INET) { 221 syslog(LOG_ERR, "malformed \"from\" address (af %d)", 222 fromp->sin_family); | 239 fromp->su_port = ntohs((u_short)fromp->su_port); 240 if (af != AF_INET 241#ifdef INET6 242 && af != AF_INET6 243#endif 244 ) { 245 syslog(LOG_ERR, "malformed \"from\" address (af %d)\n", af); |
223 exit(1); 224 } | 246 exit(1); 247 } |
248 err = getnameinfo((struct sockaddr *)fromp, fromp->su_len, numericname, 249 sizeof(numericname), NULL, 0, 250 NI_NUMERICHOST|NI_WITHSCOPEID); 251 /* XXX: do 'err' check */ |
|
225#ifdef IP_OPTIONS | 252#ifdef IP_OPTIONS |
226 { | 253 if (af == AF_INET) { |
227 u_char optbuf[BUFSIZ/3]; 228 int optsize = sizeof(optbuf), ipproto, i; 229 struct protoent *ip; 230 231 if ((ip = getprotobyname("ip")) != NULL) 232 ipproto = ip->p_proto; 233 else 234 ipproto = IPPROTO_IP; 235 if (!getsockopt(0, ipproto, IP_OPTIONS, (char *)optbuf, &optsize) && 236 optsize != 0) { 237 for (i = 0; i < optsize; ) { 238 u_char c = optbuf[i]; 239 if (c == IPOPT_LSRR || c == IPOPT_SSRR) { 240 syslog(LOG_NOTICE, 241 "connection refused from %s with IP option %s", | 254 u_char optbuf[BUFSIZ/3]; 255 int optsize = sizeof(optbuf), ipproto, i; 256 struct protoent *ip; 257 258 if ((ip = getprotobyname("ip")) != NULL) 259 ipproto = ip->p_proto; 260 else 261 ipproto = IPPROTO_IP; 262 if (!getsockopt(0, ipproto, IP_OPTIONS, (char *)optbuf, &optsize) && 263 optsize != 0) { 264 for (i = 0; i < optsize; ) { 265 u_char c = optbuf[i]; 266 if (c == IPOPT_LSRR || c == IPOPT_SSRR) { 267 syslog(LOG_NOTICE, 268 "connection refused from %s with IP option %s", |
242 inet_ntoa(fromp->sin_addr), | 269 numericname, |
243 c == IPOPT_LSRR ? "LSRR" : "SSRR"); 244 exit(1); 245 } 246 if (c == IPOPT_EOL) 247 break; 248 i += (c == IPOPT_NOP) ? 1 : optbuf[i+1]; 249 } 250 } 251 } 252#endif 253 | 270 c == IPOPT_LSRR ? "LSRR" : "SSRR"); 271 exit(1); 272 } 273 if (c == IPOPT_EOL) 274 break; 275 i += (c == IPOPT_NOP) ? 1 : optbuf[i+1]; 276 } 277 } 278 } 279#endif 280 |
254 if (fromp->sin_port >= IPPORT_RESERVED || 255 fromp->sin_port < IPPORT_RESERVED/2) { | 281 if (fromp->su_port >= IPPORT_RESERVED || 282 fromp->su_port < IPPORT_RESERVED/2) { |
256 syslog(LOG_NOTICE|LOG_AUTH, 257 "connection from %s on illegal port %u", | 283 syslog(LOG_NOTICE|LOG_AUTH, 284 "connection from %s on illegal port %u", |
258 inet_ntoa(fromp->sin_addr), 259 fromp->sin_port); | 285 numericname, 286 fromp->su_port); |
260 exit(1); 261 } 262 263 (void) alarm(60); 264 port = 0; 265 s = 0; /* not set or used if port == 0 */ 266 for (;;) { 267 char c; --- 6 unchanged lines hidden (view full) --- 274 if (c == 0) 275 break; 276 port = port * 10 + c - '0'; 277 } 278 279 (void) alarm(0); 280 if (port != 0) { 281 int lport = IPPORT_RESERVED - 1; | 287 exit(1); 288 } 289 290 (void) alarm(60); 291 port = 0; 292 s = 0; /* not set or used if port == 0 */ 293 for (;;) { 294 char c; --- 6 unchanged lines hidden (view full) --- 301 if (c == 0) 302 break; 303 port = port * 10 + c - '0'; 304 } 305 306 (void) alarm(0); 307 if (port != 0) { 308 int lport = IPPORT_RESERVED - 1; |
282 s = rresvport(&lport); | 309 s = rresvport_af(&lport, af); |
283 if (s < 0) { 284 syslog(LOG_ERR, "can't get stderr port: %m"); 285 exit(1); 286 } 287 if (port >= IPPORT_RESERVED || 288 port < IPPORT_RESERVED/2) { 289 syslog(LOG_NOTICE|LOG_AUTH, 290 "2nd socket from %s on unreserved port %u", | 310 if (s < 0) { 311 syslog(LOG_ERR, "can't get stderr port: %m"); 312 exit(1); 313 } 314 if (port >= IPPORT_RESERVED || 315 port < IPPORT_RESERVED/2) { 316 syslog(LOG_NOTICE|LOG_AUTH, 317 "2nd socket from %s on unreserved port %u", |
291 inet_ntoa(fromp->sin_addr), | 318 numericname, |
292 port); 293 exit(1); 294 } | 319 port); 320 exit(1); 321 } |
295 fromp->sin_port = htons(port); | 322 fromp->su_port = htons(port); |
296 if (connect(s, (struct sockaddr *)fromp, sizeof (*fromp)) < 0) { 297 syslog(LOG_INFO, "connect second port %d: %m", port); 298 exit(1); 299 } 300 } 301 302 errorstr = NULL; | 323 if (connect(s, (struct sockaddr *)fromp, sizeof (*fromp)) < 0) { 324 syslog(LOG_INFO, "connect second port %d: %m", port); 325 exit(1); 326 } 327 } 328 329 errorstr = NULL; |
303 realhostname(fromhost, sizeof(fromhost) - 1, &fromp->sin_addr); | 330 realhostname_sa(fromhost, sizeof(fromhost) - 1, 331 (struct sockaddr *)fromp, 332 fromp->su_len); |
304 fromhost[sizeof(fromhost) - 1] = '\0'; 305 306#ifdef CRYPT | 333 fromhost[sizeof(fromhost) - 1] = '\0'; 334 335#ifdef CRYPT |
307 if (doencrypt) { | 336 if (doencrypt && af == AF_INET) { |
308 struct sockaddr_in local_addr; 309 rc = sizeof(local_addr); 310 if (getsockname(0, (struct sockaddr *)&local_addr, 311 &rc) < 0) { 312 syslog(LOG_ERR, "getsockname: %m"); 313 error("rlogind: getsockname: %m"); 314 exit(1); 315 } --- 58 unchanged lines hidden (view full) --- 374 exit(1); 375 } 376 } 377#endif 378 379 if (errorstr || 380 (pwd->pw_expire && time(NULL) >= pwd->pw_expire) || 381 (pwd->pw_passwd != 0 && *pwd->pw_passwd != '\0' && | 337 struct sockaddr_in local_addr; 338 rc = sizeof(local_addr); 339 if (getsockname(0, (struct sockaddr *)&local_addr, 340 &rc) < 0) { 341 syslog(LOG_ERR, "getsockname: %m"); 342 error("rlogind: getsockname: %m"); 343 exit(1); 344 } --- 58 unchanged lines hidden (view full) --- 403 exit(1); 404 } 405 } 406#endif 407 408 if (errorstr || 409 (pwd->pw_expire && time(NULL) >= pwd->pw_expire) || 410 (pwd->pw_passwd != 0 && *pwd->pw_passwd != '\0' && |
382 iruserok(fromp->sin_addr.s_addr, pwd->pw_uid == 0, 383 remuser, locuser) < 0)) { | 411 iruserok_af( 412#ifdef INET6 413 (af == AF_INET6) 414 ? (void *)&fromp->su_sin6.sin6_addr : 415#endif 416 (void *)&fromp->su_sin.sin_addr, 417 pwd->pw_uid == 0, 418 remuser, locuser, af) < 0)) { |
384 if (__rcmd_errstr) 385 syslog(LOG_INFO|LOG_AUTH, 386 "%s@%s as %s: permission denied (%s). cmd='%.80s'", 387 remuser, fromhost, locuser, __rcmd_errstr, 388 cmdbuf); 389 else 390 syslog(LOG_INFO|LOG_AUTH, 391 "%s@%s as %s: permission denied. cmd='%.80s'", --- 5 unchanged lines hidden (view full) --- 397 exit(1); 398 } 399 400 if (pwd->pw_uid && !access(_PATH_NOLOGIN, F_OK)) { 401 error("Logins currently disabled.\n"); 402 exit(1); 403 } 404#ifdef LOGIN_CAP | 419 if (__rcmd_errstr) 420 syslog(LOG_INFO|LOG_AUTH, 421 "%s@%s as %s: permission denied (%s). cmd='%.80s'", 422 remuser, fromhost, locuser, __rcmd_errstr, 423 cmdbuf); 424 else 425 syslog(LOG_INFO|LOG_AUTH, 426 "%s@%s as %s: permission denied. cmd='%.80s'", --- 5 unchanged lines hidden (view full) --- 432 exit(1); 433 } 434 435 if (pwd->pw_uid && !access(_PATH_NOLOGIN, F_OK)) { 436 error("Logins currently disabled.\n"); 437 exit(1); 438 } 439#ifdef LOGIN_CAP |
405 if (lc != NULL) { | 440 if (lc != NULL && fromp->su_family == AF_INET) { /*XXX*/ |
406 char remote_ip[MAXHOSTNAMELEN]; 407 | 441 char remote_ip[MAXHOSTNAMELEN]; 442 |
408 strncpy(remote_ip, inet_ntoa(fromp->sin_addr), | 443 strncpy(remote_ip, numericname, |
409 sizeof(remote_ip) - 1); 410 remote_ip[sizeof(remote_ip) - 1] = 0; 411 if (!auth_hostok(lc, fromhost, remote_ip)) { 412 syslog(LOG_INFO|LOG_AUTH, 413 "%s@%s as %s: permission denied (%s). cmd='%.80s'", 414 remuser, fromhost, locuser, __rcmd_errstr, 415 cmdbuf); 416 error("Login incorrect.\n"); --- 310 unchanged lines hidden --- | 444 sizeof(remote_ip) - 1); 445 remote_ip[sizeof(remote_ip) - 1] = 0; 446 if (!auth_hostok(lc, fromhost, remote_ip)) { 447 syslog(LOG_INFO|LOG_AUTH, 448 "%s@%s as %s: permission denied (%s). cmd='%.80s'", 449 remuser, fromhost, locuser, __rcmd_errstr, 450 cmdbuf); 451 error("Login incorrect.\n"); --- 310 unchanged lines hidden --- |