1/*- 2 * Copyright (c) 1983, 1990, 1993, 1994 3 * The Regents of the University of California. All rights reserved.
| 1/*- 2 * Copyright (c) 1983, 1990, 1993, 1994 3 * The Regents of the University of California. All rights reserved.
|
| 4 * Copyright (c) 2002 Networks Associates Technology, Inc. 5 * All rights reserved.
|
4 *
| 6 *
|
| 7 * Portions of this software were developed for the FreeBSD Project by 8 * ThinkSec AS and NAI Labs, the Security Research Division of Network 9 * Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035 10 * ("CBOSS"), as part of the DARPA CHATS research program. 11 *
|
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 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 3. All advertising materials mentioning features or use of this software 14 * must display the following acknowledgement: 15 * This product includes software developed by the University of 16 * California, Berkeley and its contributors. 17 * 4. Neither the name of the University nor the names of its contributors 18 * may be used to endorse or promote products derived from this software 19 * without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * SUCH DAMAGE. 32 */ 33 34#ifndef lint 35static const char copyright[] = 36"@(#) Copyright (c) 1983, 1990, 1993, 1994\n\ 37 The Regents of the University of California. All rights reserved.\n"; 38#endif /* not lint */ 39 40#ifndef lint 41static const char sccsid[] = "From: @(#)rsh.c 8.3 (Berkeley) 4/6/94"; 42#endif /* not lint */ 43 44#include <sys/cdefs.h>
| 12 * Redistribution and use in source and binary forms, with or without 13 * modification, are permitted provided that the following conditions 14 * are met: 15 * 1. Redistributions of source code must retain the above copyright 16 * notice, this list of conditions and the following disclaimer. 17 * 2. Redistributions in binary form must reproduce the above copyright 18 * notice, this list of conditions and the following disclaimer in the 19 * documentation and/or other materials provided with the distribution. 20 * 3. All advertising materials mentioning features or use of this software 21 * must display the following acknowledgement: 22 * This product includes software developed by the University of 23 * California, Berkeley and its contributors. 24 * 4. Neither the name of the University nor the names of its contributors 25 * may be used to endorse or promote products derived from this software 26 * without specific prior written permission. 27 * 28 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 29 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 30 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 31 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 32 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 33 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 34 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 35 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 36 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 37 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 38 * SUCH DAMAGE. 39 */ 40 41#ifndef lint 42static const char copyright[] = 43"@(#) Copyright (c) 1983, 1990, 1993, 1994\n\ 44 The Regents of the University of California. All rights reserved.\n"; 45#endif /* not lint */ 46 47#ifndef lint 48static const char sccsid[] = "From: @(#)rsh.c 8.3 (Berkeley) 4/6/94"; 49#endif /* not lint */ 50 51#include <sys/cdefs.h>
|
45__FBSDID("$FreeBSD: head/usr.bin/rsh/rsh.c 93412 2002-03-30 08:51:21Z obrien $");
| 52__FBSDID("$FreeBSD: head/usr.bin/rsh/rsh.c 96196 2002-05-08 00:47:01Z des $");
|
46 47#include <sys/param.h> 48#include <sys/signal.h> 49#include <sys/socket.h> 50#include <sys/ioctl.h> 51#include <sys/file.h> 52#include <sys/time.h> 53 54#include <netinet/in.h> 55#include <netdb.h> 56 57#include <err.h> 58#include <errno.h> 59#include <libutil.h>
| 53 54#include <sys/param.h> 55#include <sys/signal.h> 56#include <sys/socket.h> 57#include <sys/ioctl.h> 58#include <sys/file.h> 59#include <sys/time.h> 60 61#include <netinet/in.h> 62#include <netdb.h> 63 64#include <err.h> 65#include <errno.h> 66#include <libutil.h>
|
| 67#include <paths.h>
|
60#include <pwd.h> 61#include <signal.h> 62#include <stdio.h> 63#include <stdlib.h> 64#include <string.h> 65#include <unistd.h> 66#include <err.h> 67
| 68#include <pwd.h> 69#include <signal.h> 70#include <stdio.h> 71#include <stdlib.h> 72#include <string.h> 73#include <unistd.h> 74#include <err.h> 75
|
68#include "pathnames.h" 69
| |
70#ifdef KERBEROS 71#include <openssl/des.h> 72#include <krb.h> 73#include "krb.h" 74 75CREDENTIALS cred; 76Key_schedule schedule; 77int use_kerberos = 1, doencrypt; 78char dst_realm_buf[REALM_SZ], *dest_realm; 79extern char *krb_realmofhost(); 80#endif 81 82/* 83 * rsh - remote shell 84 */ 85int rfd2; 86 87int family = PF_UNSPEC; 88char rlogin[] = "rlogin"; 89 90char *copyargs(char * const *); 91void sendsig(int); 92void talk(int, long, pid_t, int, int); 93void usage(void); 94 95int 96main(int argc, char *argv[]) 97{ 98 struct passwd const *pw; 99 struct servent const *sp; 100 long omask; 101 int argoff, asrsh, ch, dflag, nflag, one, rem; 102 pid_t pid = 0; 103 uid_t uid; 104 char *args, *host, *p, *user; 105 int timeout = 0; 106#ifdef KERBEROS 107 const char *k; 108#endif 109 110 argoff = asrsh = dflag = nflag = 0; 111 one = 1; 112 host = user = NULL; 113 114 /* if called as something other than "rsh", use it as the host name */ 115 if ((p = strrchr(argv[0], '/'))) 116 ++p; 117 else 118 p = argv[0]; 119 if (strcmp(p, "rsh")) 120 host = p; 121 else 122 asrsh = 1; 123 124 /* handle "rsh host flags" */ 125 if (!host && argc > 2 && argv[1][0] != '-') { 126 host = argv[1]; 127 argoff = 1; 128 } 129 130#ifdef KERBEROS 131#ifdef CRYPT 132#define OPTIONS "468KLde:k:l:nt:wx" 133#else 134#define OPTIONS "468KLde:k:l:nt:w" 135#endif 136#else 137#define OPTIONS "468KLde:l:nt:w" 138#endif 139 while ((ch = getopt(argc - argoff, argv + argoff, OPTIONS)) != -1) 140 switch(ch) { 141 case '4': 142 family = PF_INET; 143 break; 144 145 case '6': 146 family = PF_INET6; 147 break; 148 149 case 'K': 150#ifdef KERBEROS 151 use_kerberos = 0; 152#endif 153 break; 154 case 'L': /* -8Lew are ignored to allow rlogin aliases */ 155 case 'e': 156 case 'w': 157 case '8': 158 break; 159 case 'd': 160 dflag = 1; 161 break; 162 case 'l': 163 user = optarg; 164 break; 165#ifdef KERBEROS 166 case 'k': 167 dest_realm = dst_realm_buf; 168 strncpy(dest_realm, optarg, REALM_SZ); 169 break; 170#endif 171 case 'n': 172 nflag = 1; 173 break; 174#ifdef KERBEROS 175#ifdef CRYPT 176 case 'x': 177 doencrypt = 1; 178 break; 179#endif 180#endif 181 case 't': 182 timeout = atoi(optarg); 183 break; 184 case '?': 185 default: 186 usage(); 187 } 188 optind += argoff; 189 190 /* if haven't gotten a host yet, do so */ 191 if (!host && !(host = argv[optind++])) 192 usage(); 193 194 /* if no further arguments, must have been called as rlogin. */ 195 if (!argv[optind]) { 196 if (asrsh) 197 *argv = rlogin; 198 execv(_PATH_RLOGIN, argv); 199 err(1, "can't exec %s", _PATH_RLOGIN); 200 } 201 202 argc -= optind; 203 argv += optind; 204 205 if (!(pw = getpwuid(uid = getuid()))) 206 errx(1, "unknown user id"); 207 if (!user) 208 user = pw->pw_name; 209 210#ifdef KERBEROS 211#ifdef CRYPT 212 /* -x turns off -n */ 213 if (doencrypt) 214 nflag = 0; 215#endif 216#endif 217 218 args = copyargs(argv); 219 220 sp = NULL; 221#ifdef KERBEROS 222 k = auth_getval("auth_list"); 223 if (k && !strstr(k, "kerberos")) 224 use_kerberos = 0; 225 if (use_kerberos) { 226 sp = getservbyname((doencrypt ? "ekshell" : "kshell"), "tcp"); 227 if (sp == NULL) { 228 use_kerberos = 0; 229 warnx( 230 "warning, using standard rsh: can't get entry for %s/tcp service", 231 doencrypt ? "ekshell" : "kshell"); 232 } 233 } 234#endif 235 if (sp == NULL) 236 sp = getservbyname("shell", "tcp"); 237 if (sp == NULL) 238 errx(1, "shell/tcp: unknown service"); 239 240#ifdef KERBEROS 241try_connect: 242 if (use_kerberos) { 243 struct hostent *hp; 244 245 /* fully qualify hostname (needed for krb_realmofhost) */ 246 hp = gethostbyname(host); 247 if (hp != NULL && !(host = strdup(hp->h_name))) 248 err(1, NULL); 249 250 rem = KSUCCESS; 251 errno = 0; 252 if (dest_realm == NULL) 253 dest_realm = krb_realmofhost(host); 254 255#ifdef CRYPT 256 if (doencrypt) { 257 rem = krcmd_mutual(&host, sp->s_port, user, args, 258 &rfd2, dest_realm, &cred, schedule); 259 des_set_key(&cred.session, schedule); 260 } else 261#endif 262 rem = krcmd(&host, sp->s_port, user, args, &rfd2, 263 dest_realm); 264 if (rem < 0) { 265 use_kerberos = 0; 266 sp = getservbyname("shell", "tcp"); 267 if (sp == NULL) 268 errx(1, "shell/tcp: unknown service"); 269 if (errno == ECONNREFUSED) 270 warnx( 271 "warning, using standard rsh: remote host doesn't support Kerberos"); 272 if (errno == ENOENT) 273 warnx( 274 "warning, using standard rsh: can't provide Kerberos auth data"); 275 goto try_connect; 276 } 277 } else { 278 if (doencrypt) 279 errx(1, "the -x flag requires Kerberos authentication"); 280 rem = rcmd_af(&host, sp->s_port, pw->pw_name, user, args, 281 &rfd2, family); 282 } 283#else 284 rem = rcmd_af(&host, sp->s_port, pw->pw_name, user, args, &rfd2, 285 family); 286#endif 287 288 if (rem < 0) 289 exit(1); 290 291 if (rfd2 < 0) 292 errx(1, "can't establish stderr"); 293 if (dflag) { 294 if (setsockopt(rem, SOL_SOCKET, SO_DEBUG, &one, 295 sizeof(one)) < 0) 296 warn("setsockopt"); 297 if (setsockopt(rfd2, SOL_SOCKET, SO_DEBUG, &one, 298 sizeof(one)) < 0) 299 warn("setsockopt"); 300 } 301 302 (void)setuid(uid); 303 omask = sigblock(sigmask(SIGINT)|sigmask(SIGQUIT)|sigmask(SIGTERM)); 304 if (signal(SIGINT, SIG_IGN) != SIG_IGN) 305 (void)signal(SIGINT, sendsig); 306 if (signal(SIGQUIT, SIG_IGN) != SIG_IGN) 307 (void)signal(SIGQUIT, sendsig); 308 if (signal(SIGTERM, SIG_IGN) != SIG_IGN) 309 (void)signal(SIGTERM, sendsig); 310 311 if (!nflag) { 312 pid = fork(); 313 if (pid < 0) 314 err(1, "fork"); 315 }
| 76#ifdef KERBEROS 77#include <openssl/des.h> 78#include <krb.h> 79#include "krb.h" 80 81CREDENTIALS cred; 82Key_schedule schedule; 83int use_kerberos = 1, doencrypt; 84char dst_realm_buf[REALM_SZ], *dest_realm; 85extern char *krb_realmofhost(); 86#endif 87 88/* 89 * rsh - remote shell 90 */ 91int rfd2; 92 93int family = PF_UNSPEC; 94char rlogin[] = "rlogin"; 95 96char *copyargs(char * const *); 97void sendsig(int); 98void talk(int, long, pid_t, int, int); 99void usage(void); 100 101int 102main(int argc, char *argv[]) 103{ 104 struct passwd const *pw; 105 struct servent const *sp; 106 long omask; 107 int argoff, asrsh, ch, dflag, nflag, one, rem; 108 pid_t pid = 0; 109 uid_t uid; 110 char *args, *host, *p, *user; 111 int timeout = 0; 112#ifdef KERBEROS 113 const char *k; 114#endif 115 116 argoff = asrsh = dflag = nflag = 0; 117 one = 1; 118 host = user = NULL; 119 120 /* if called as something other than "rsh", use it as the host name */ 121 if ((p = strrchr(argv[0], '/'))) 122 ++p; 123 else 124 p = argv[0]; 125 if (strcmp(p, "rsh")) 126 host = p; 127 else 128 asrsh = 1; 129 130 /* handle "rsh host flags" */ 131 if (!host && argc > 2 && argv[1][0] != '-') { 132 host = argv[1]; 133 argoff = 1; 134 } 135 136#ifdef KERBEROS 137#ifdef CRYPT 138#define OPTIONS "468KLde:k:l:nt:wx" 139#else 140#define OPTIONS "468KLde:k:l:nt:w" 141#endif 142#else 143#define OPTIONS "468KLde:l:nt:w" 144#endif 145 while ((ch = getopt(argc - argoff, argv + argoff, OPTIONS)) != -1) 146 switch(ch) { 147 case '4': 148 family = PF_INET; 149 break; 150 151 case '6': 152 family = PF_INET6; 153 break; 154 155 case 'K': 156#ifdef KERBEROS 157 use_kerberos = 0; 158#endif 159 break; 160 case 'L': /* -8Lew are ignored to allow rlogin aliases */ 161 case 'e': 162 case 'w': 163 case '8': 164 break; 165 case 'd': 166 dflag = 1; 167 break; 168 case 'l': 169 user = optarg; 170 break; 171#ifdef KERBEROS 172 case 'k': 173 dest_realm = dst_realm_buf; 174 strncpy(dest_realm, optarg, REALM_SZ); 175 break; 176#endif 177 case 'n': 178 nflag = 1; 179 break; 180#ifdef KERBEROS 181#ifdef CRYPT 182 case 'x': 183 doencrypt = 1; 184 break; 185#endif 186#endif 187 case 't': 188 timeout = atoi(optarg); 189 break; 190 case '?': 191 default: 192 usage(); 193 } 194 optind += argoff; 195 196 /* if haven't gotten a host yet, do so */ 197 if (!host && !(host = argv[optind++])) 198 usage(); 199 200 /* if no further arguments, must have been called as rlogin. */ 201 if (!argv[optind]) { 202 if (asrsh) 203 *argv = rlogin; 204 execv(_PATH_RLOGIN, argv); 205 err(1, "can't exec %s", _PATH_RLOGIN); 206 } 207 208 argc -= optind; 209 argv += optind; 210 211 if (!(pw = getpwuid(uid = getuid()))) 212 errx(1, "unknown user id"); 213 if (!user) 214 user = pw->pw_name; 215 216#ifdef KERBEROS 217#ifdef CRYPT 218 /* -x turns off -n */ 219 if (doencrypt) 220 nflag = 0; 221#endif 222#endif 223 224 args = copyargs(argv); 225 226 sp = NULL; 227#ifdef KERBEROS 228 k = auth_getval("auth_list"); 229 if (k && !strstr(k, "kerberos")) 230 use_kerberos = 0; 231 if (use_kerberos) { 232 sp = getservbyname((doencrypt ? "ekshell" : "kshell"), "tcp"); 233 if (sp == NULL) { 234 use_kerberos = 0; 235 warnx( 236 "warning, using standard rsh: can't get entry for %s/tcp service", 237 doencrypt ? "ekshell" : "kshell"); 238 } 239 } 240#endif 241 if (sp == NULL) 242 sp = getservbyname("shell", "tcp"); 243 if (sp == NULL) 244 errx(1, "shell/tcp: unknown service"); 245 246#ifdef KERBEROS 247try_connect: 248 if (use_kerberos) { 249 struct hostent *hp; 250 251 /* fully qualify hostname (needed for krb_realmofhost) */ 252 hp = gethostbyname(host); 253 if (hp != NULL && !(host = strdup(hp->h_name))) 254 err(1, NULL); 255 256 rem = KSUCCESS; 257 errno = 0; 258 if (dest_realm == NULL) 259 dest_realm = krb_realmofhost(host); 260 261#ifdef CRYPT 262 if (doencrypt) { 263 rem = krcmd_mutual(&host, sp->s_port, user, args, 264 &rfd2, dest_realm, &cred, schedule); 265 des_set_key(&cred.session, schedule); 266 } else 267#endif 268 rem = krcmd(&host, sp->s_port, user, args, &rfd2, 269 dest_realm); 270 if (rem < 0) { 271 use_kerberos = 0; 272 sp = getservbyname("shell", "tcp"); 273 if (sp == NULL) 274 errx(1, "shell/tcp: unknown service"); 275 if (errno == ECONNREFUSED) 276 warnx( 277 "warning, using standard rsh: remote host doesn't support Kerberos"); 278 if (errno == ENOENT) 279 warnx( 280 "warning, using standard rsh: can't provide Kerberos auth data"); 281 goto try_connect; 282 } 283 } else { 284 if (doencrypt) 285 errx(1, "the -x flag requires Kerberos authentication"); 286 rem = rcmd_af(&host, sp->s_port, pw->pw_name, user, args, 287 &rfd2, family); 288 } 289#else 290 rem = rcmd_af(&host, sp->s_port, pw->pw_name, user, args, &rfd2, 291 family); 292#endif 293 294 if (rem < 0) 295 exit(1); 296 297 if (rfd2 < 0) 298 errx(1, "can't establish stderr"); 299 if (dflag) { 300 if (setsockopt(rem, SOL_SOCKET, SO_DEBUG, &one, 301 sizeof(one)) < 0) 302 warn("setsockopt"); 303 if (setsockopt(rfd2, SOL_SOCKET, SO_DEBUG, &one, 304 sizeof(one)) < 0) 305 warn("setsockopt"); 306 } 307 308 (void)setuid(uid); 309 omask = sigblock(sigmask(SIGINT)|sigmask(SIGQUIT)|sigmask(SIGTERM)); 310 if (signal(SIGINT, SIG_IGN) != SIG_IGN) 311 (void)signal(SIGINT, sendsig); 312 if (signal(SIGQUIT, SIG_IGN) != SIG_IGN) 313 (void)signal(SIGQUIT, sendsig); 314 if (signal(SIGTERM, SIG_IGN) != SIG_IGN) 315 (void)signal(SIGTERM, sendsig); 316 317 if (!nflag) { 318 pid = fork(); 319 if (pid < 0) 320 err(1, "fork"); 321 }
|
316 else
| 322 else
|
317 (void)shutdown(rem, 1); 318 319#ifdef KERBEROS 320#ifdef CRYPT 321 if (!doencrypt) 322#endif 323#endif 324 { 325 (void)ioctl(rfd2, FIONBIO, &one); 326 (void)ioctl(rem, FIONBIO, &one); 327 } 328 329 talk(nflag, omask, pid, rem, timeout); 330 331 if (!nflag) 332 (void)kill(pid, SIGKILL); 333 exit(0); 334} 335 336void 337talk(int nflag, long omask, pid_t pid, int rem, int timeout) 338{ 339 int cc, wc; 340 fd_set readfrom, ready, rembits; 341 char buf[BUFSIZ]; 342 const char *bp; 343 struct timeval tvtimeout; 344 int nfds, srval; 345 346 if (!nflag && pid == 0) { 347 (void)close(rfd2); 348 349reread: errno = 0; 350 if ((cc = read(0, buf, sizeof buf)) <= 0) 351 goto done; 352 bp = buf; 353 354rewrite: 355 FD_ZERO(&rembits); 356 FD_SET(rem, &rembits); 357 nfds = rem + 1; 358 if (select(nfds, 0, &rembits, 0, 0) < 0) { 359 if (errno != EINTR) 360 err(1, "select"); 361 goto rewrite; 362 } 363 if (!FD_ISSET(rem, &rembits)) 364 goto rewrite; 365#ifdef KERBEROS 366#ifdef CRYPT 367 if (doencrypt) 368 wc = des_enc_write(rem, bp, cc, schedule, &cred.session); 369 else 370#endif 371#endif 372 wc = write(rem, bp, cc); 373 if (wc < 0) { 374 if (errno == EWOULDBLOCK) 375 goto rewrite; 376 goto done; 377 } 378 bp += wc; 379 cc -= wc; 380 if (cc == 0) 381 goto reread; 382 goto rewrite; 383done: 384 (void)shutdown(rem, 1); 385 exit(0); 386 } 387 388 tvtimeout.tv_sec = timeout; 389 tvtimeout.tv_usec = 0; 390 391 (void)sigsetmask(omask); 392 FD_ZERO(&readfrom); 393 FD_SET(rfd2, &readfrom); 394 FD_SET(rem, &readfrom); 395 nfds = MAX(rfd2+1, rem+1); 396 do { 397 ready = readfrom; 398 if (timeout) { 399 srval = select(nfds, &ready, 0, 0, &tvtimeout); 400 } else { 401 srval = select(nfds, &ready, 0, 0, 0); 402 } 403 404 if (srval < 0) { 405 if (errno != EINTR) 406 err(1, "select"); 407 continue; 408 } 409 if (srval == 0) 410 errx(1, "timeout reached (%d seconds)\n", timeout); 411 if (FD_ISSET(rfd2, &ready)) { 412 errno = 0; 413#ifdef KERBEROS 414#ifdef CRYPT 415 if (doencrypt) 416 cc = des_enc_read(rfd2, buf, sizeof buf, schedule, &cred.session); 417 else 418#endif 419#endif 420 cc = read(rfd2, buf, sizeof buf); 421 if (cc <= 0) { 422 if (errno != EWOULDBLOCK) 423 FD_CLR(rfd2, &readfrom); 424 } else 425 (void)write(STDERR_FILENO, buf, cc); 426 } 427 if (FD_ISSET(rem, &ready)) { 428 errno = 0; 429#ifdef KERBEROS 430#ifdef CRYPT 431 if (doencrypt) 432 cc = des_enc_read(rem, buf, sizeof buf, schedule, &cred.session); 433 else 434#endif 435#endif 436 cc = read(rem, buf, sizeof buf); 437 if (cc <= 0) { 438 if (errno != EWOULDBLOCK) 439 FD_CLR(rem, &readfrom); 440 } else 441 (void)write(STDOUT_FILENO, buf, cc); 442 } 443 } while (FD_ISSET(rfd2, &readfrom) || FD_ISSET(rem, &readfrom)); 444} 445 446void 447sendsig(int sig) 448{ 449 char signo; 450 451 signo = sig; 452#ifdef KERBEROS 453#ifdef CRYPT 454 if (doencrypt) 455 (void)des_enc_write(rfd2, &signo, 1, schedule, &cred.session); 456 else 457#endif 458#endif 459 (void)write(rfd2, &signo, 1); 460} 461 462char * 463copyargs(char * const *argv) 464{ 465 int cc; 466 char *args, *p; 467 char * const *ap; 468 469 cc = 0; 470 for (ap = argv; *ap; ++ap) 471 cc += strlen(*ap) + 1; 472 if (!(args = malloc((u_int)cc))) 473 err(1, NULL); 474 for (p = args, ap = argv; *ap; ++ap) { 475 (void)strcpy(p, *ap); 476 for (p = strcpy(p, *ap); *p; ++p); 477 if (ap[1]) 478 *p++ = ' '; 479 } 480 return (args); 481} 482 483void 484usage(void) 485{ 486 487 (void)fprintf(stderr, 488 "usage: rsh [-46] [-ndK%s]%s[-l login] [-t timeout] host [command]\n", 489#ifdef KERBEROS 490#ifdef CRYPT 491 "x", " [-k realm] "); 492#else 493 "", " [-k realm] "); 494#endif 495#else 496 "", " "); 497#endif 498 exit(1); 499}
| 323 (void)shutdown(rem, 1); 324 325#ifdef KERBEROS 326#ifdef CRYPT 327 if (!doencrypt) 328#endif 329#endif 330 { 331 (void)ioctl(rfd2, FIONBIO, &one); 332 (void)ioctl(rem, FIONBIO, &one); 333 } 334 335 talk(nflag, omask, pid, rem, timeout); 336 337 if (!nflag) 338 (void)kill(pid, SIGKILL); 339 exit(0); 340} 341 342void 343talk(int nflag, long omask, pid_t pid, int rem, int timeout) 344{ 345 int cc, wc; 346 fd_set readfrom, ready, rembits; 347 char buf[BUFSIZ]; 348 const char *bp; 349 struct timeval tvtimeout; 350 int nfds, srval; 351 352 if (!nflag && pid == 0) { 353 (void)close(rfd2); 354 355reread: errno = 0; 356 if ((cc = read(0, buf, sizeof buf)) <= 0) 357 goto done; 358 bp = buf; 359 360rewrite: 361 FD_ZERO(&rembits); 362 FD_SET(rem, &rembits); 363 nfds = rem + 1; 364 if (select(nfds, 0, &rembits, 0, 0) < 0) { 365 if (errno != EINTR) 366 err(1, "select"); 367 goto rewrite; 368 } 369 if (!FD_ISSET(rem, &rembits)) 370 goto rewrite; 371#ifdef KERBEROS 372#ifdef CRYPT 373 if (doencrypt) 374 wc = des_enc_write(rem, bp, cc, schedule, &cred.session); 375 else 376#endif 377#endif 378 wc = write(rem, bp, cc); 379 if (wc < 0) { 380 if (errno == EWOULDBLOCK) 381 goto rewrite; 382 goto done; 383 } 384 bp += wc; 385 cc -= wc; 386 if (cc == 0) 387 goto reread; 388 goto rewrite; 389done: 390 (void)shutdown(rem, 1); 391 exit(0); 392 } 393 394 tvtimeout.tv_sec = timeout; 395 tvtimeout.tv_usec = 0; 396 397 (void)sigsetmask(omask); 398 FD_ZERO(&readfrom); 399 FD_SET(rfd2, &readfrom); 400 FD_SET(rem, &readfrom); 401 nfds = MAX(rfd2+1, rem+1); 402 do { 403 ready = readfrom; 404 if (timeout) { 405 srval = select(nfds, &ready, 0, 0, &tvtimeout); 406 } else { 407 srval = select(nfds, &ready, 0, 0, 0); 408 } 409 410 if (srval < 0) { 411 if (errno != EINTR) 412 err(1, "select"); 413 continue; 414 } 415 if (srval == 0) 416 errx(1, "timeout reached (%d seconds)\n", timeout); 417 if (FD_ISSET(rfd2, &ready)) { 418 errno = 0; 419#ifdef KERBEROS 420#ifdef CRYPT 421 if (doencrypt) 422 cc = des_enc_read(rfd2, buf, sizeof buf, schedule, &cred.session); 423 else 424#endif 425#endif 426 cc = read(rfd2, buf, sizeof buf); 427 if (cc <= 0) { 428 if (errno != EWOULDBLOCK) 429 FD_CLR(rfd2, &readfrom); 430 } else 431 (void)write(STDERR_FILENO, buf, cc); 432 } 433 if (FD_ISSET(rem, &ready)) { 434 errno = 0; 435#ifdef KERBEROS 436#ifdef CRYPT 437 if (doencrypt) 438 cc = des_enc_read(rem, buf, sizeof buf, schedule, &cred.session); 439 else 440#endif 441#endif 442 cc = read(rem, buf, sizeof buf); 443 if (cc <= 0) { 444 if (errno != EWOULDBLOCK) 445 FD_CLR(rem, &readfrom); 446 } else 447 (void)write(STDOUT_FILENO, buf, cc); 448 } 449 } while (FD_ISSET(rfd2, &readfrom) || FD_ISSET(rem, &readfrom)); 450} 451 452void 453sendsig(int sig) 454{ 455 char signo; 456 457 signo = sig; 458#ifdef KERBEROS 459#ifdef CRYPT 460 if (doencrypt) 461 (void)des_enc_write(rfd2, &signo, 1, schedule, &cred.session); 462 else 463#endif 464#endif 465 (void)write(rfd2, &signo, 1); 466} 467 468char * 469copyargs(char * const *argv) 470{ 471 int cc; 472 char *args, *p; 473 char * const *ap; 474 475 cc = 0; 476 for (ap = argv; *ap; ++ap) 477 cc += strlen(*ap) + 1; 478 if (!(args = malloc((u_int)cc))) 479 err(1, NULL); 480 for (p = args, ap = argv; *ap; ++ap) { 481 (void)strcpy(p, *ap); 482 for (p = strcpy(p, *ap); *p; ++p); 483 if (ap[1]) 484 *p++ = ' '; 485 } 486 return (args); 487} 488 489void 490usage(void) 491{ 492 493 (void)fprintf(stderr, 494 "usage: rsh [-46] [-ndK%s]%s[-l login] [-t timeout] host [command]\n", 495#ifdef KERBEROS 496#ifdef CRYPT 497 "x", " [-k realm] "); 498#else 499 "", " [-k realm] "); 500#endif 501#else 502 "", " "); 503#endif 504 exit(1); 505}
|
500
| |
| |