예제 #1
0
void
tolocal(int argc, char *argv[])
{
	int i, len, tos;
	char *bp, *host, *src, *suser;

	for (i = 0; i < argc - 1; i++) {
		if (!(src = colon(argv[i]))) {		/* Local to local. */
			len = strlen(_PATH_CP) + strlen(argv[i]) +
			    strlen(argv[argc - 1]) + 20;
			if (!(bp = malloc(len)))
				err(1, "malloc");
			(void)snprintf(bp, len, "exec %s%s%s %s %s", _PATH_CP,
			    iamrecursive ? " -PR" : "", pflag ? " -p" : "",
			    argv[i], argv[argc - 1]);
			if (susystem(bp, userid))
				++errs;
			(void)free(bp);
			continue;
		}
		*src++ = 0;
		if (*src == 0)
			src = period;
		if ((host = strchr(argv[i], '@')) == NULL) {
			host = argv[i];
			suser = pwd->pw_name;
		} else {
			*host++ = 0;
			suser = argv[i];
			if (*suser == '\0')
				suser = pwd->pw_name;
			else if (!okname(suser)) {
				++errs;
				continue;
			}
		}
		len = strlen(src) + CMDNEEDS + 20;
		if ((bp = malloc(len)) == NULL)
			err(1, "malloc");
		(void)snprintf(bp, len, "%s -f %s", cmd, src);
		rem = rcmd_af(&host, port, pwd->pw_name, suser, bp, 0,
			    family);
		(void)free(bp);
		if (rem < 0) {
			++errs;
			continue;
		}
		(void)seteuid(userid);
		if (family == PF_INET) {
			tos = IPTOS_THROUGHPUT;
			if (setsockopt(rem, IPPROTO_IP, IP_TOS, &tos,
			    sizeof(int)) < 0)
				warn("TOS (ignored)");
		}
		sink(1, argv + argc - 1);
		(void)seteuid(0);
		(void)close(rem);
		rem = -1;
	}
}
예제 #2
0
파일: rcmd.c 프로젝트: andreiw/polaris
int rcmd(char **ahost, unsigned short rport, const char *locuser,
    const char *remuser, const char *cmd, int *fd2p)
{
	int rcmd_ret;

	rcmd_ret = rcmd_af(ahost, rport, locuser, remuser, cmd, fd2p,
	    AF_INET);
	return (rcmd_ret);
}
예제 #3
0
파일: rcp.c 프로젝트: lacombar/netbsd-alc
void
tolocal(int argc, char *argv[])
{
	int i;
	size_t len;
	char *bp, *host, *src, *suser;

	for (i = 0; i < argc - 1; i++) {
		if (!(src = colon(argv[i]))) {		/* Local to local. */
			len = strlen(_PATH_CP) + strlen(argv[i]) +
			    strlen(argv[argc - 1]) + 20;
			if (!(bp = malloc(len)))
				err(1, NULL);
			(void)snprintf(bp, len, "exec %s%s%s %s %s", _PATH_CP,
			    iamrecursive ? " -r" : "", pflag ? " -p" : "",
			    argv[i], argv[argc - 1]);
			if (susystem(bp))
				++errs;
			(void)free(bp);
			continue;
		}
		*src++ = 0;
		if (*src == 0)
			src = dot;
		if ((host = strchr(argv[i], '@')) == NULL) {
			host = argv[i];
			suser = pwname;
		} else {
			*host++ = 0;
			suser = argv[i];
			if (*suser == '\0')
				suser = pwname;
			else if (!okname(suser))
				continue;
		}
		host = unbracket(host);
		len = strlen(src) + CMDNEEDS + 20;
		if ((bp = malloc(len)) == NULL)
			err(1, NULL);
		(void)snprintf(bp, len, "%s -f %s", cmd, src);
		rem = 
			rcmd_af(&host, port, pwname, suser, bp, NULL, family);
		(void)free(bp);
		if (rem < 0) {
			++errs;
			continue;
		}
		sink(1, argv + argc - 1);
		(void)close(rem);
		rem = -1;
	}
}
예제 #4
0
/*
 * Run the remote command.  We aren't interested in any io, Only the
 * return code.
 */
static int
remote_command(char *command, char *host)
{
	struct passwd *pw;

	if ((pw = getpwuid(getuid())) != NULL) {
		int fd;

		if ((fd = rcmd_af(&host, htons(514), pw->pw_name, "root",
		    command, NULL, AF_INET6)) < 0)
			return (-1);
		(void) close(fd);
		return (0);
	} else
		return (-1);
}
예제 #5
0
void
toremote(char *targ, int argc, char *argv[])
{
	int i, tos;
	char *bp, *host, *src, *suser, *thost, *tuser;

	*targ++ = 0;
	if (*targ == 0)
		targ = period;

	if ((thost = strchr(argv[argc - 1], '@'))) {
		/* user@host */
		*thost++ = 0;
		tuser = argv[argc - 1];
		if (*tuser == '\0')
			tuser = NULL;
		else if (!okname(tuser))
			exit(1);
	} else {
		thost = argv[argc - 1];
		tuser = NULL;
	}

	for (i = 0; i < argc - 1; i++) {
		src = colon(argv[i]);
		if (src) {			/* remote to remote */
			*src++ = 0;
			if (*src == 0)
				src = period;
			host = strchr(argv[i], '@');
			if (host) {
				*host++ = 0;
				suser = argv[i];
				if (*suser == '\0')
					suser = pwd->pw_name;
				else if (!okname(suser)) {
					++errs;
					continue;
				}
				if (asprintf(&bp, 
				    "%s %s -l %s -n %s %s '%s%s%s:%s'",
				    _PATH_RSH, host, suser, cmd, src,
				    tuser ? tuser : "", tuser ? "@" : "",
				    thost, targ) == -1)
					err(1, "asprintf");
			} else
				if (asprintf(&bp,
				    "exec %s %s -n %s %s '%s%s%s:%s'",
				    _PATH_RSH, argv[i], cmd, src,
				    tuser ? tuser : "", tuser ? "@" : "",
				    thost, targ) == -1)
					err(1, "asprintf");
			(void)susystem(bp, userid);
			(void)free(bp);
		} else {			/* local to remote */
			if (rem == -1) {
				if (asprintf(&bp, "%s -t %s", cmd, targ)
					== -1)
					err(1, "asprintf");
				host = thost;
				rem = rcmd_af(&host, port,
				    pwd->pw_name,
				    tuser ? tuser : pwd->pw_name,
				    bp, 0, family);
				if (rem < 0)
					exit(1);
				if (family == PF_INET) {
					tos = IPTOS_THROUGHPUT;
					if (setsockopt(rem, IPPROTO_IP, IP_TOS,
					    &tos, sizeof(int)) < 0)
						warn("TOS (ignored)");
				}
				if (response() < 0)
					exit(1);
				(void)free(bp);
				(void)setuid(userid);
			}
			source(1, argv+i);
		}
	}
}
예제 #6
0
파일: rsh.c 프로젝트: CoryXie/opensolaris
/* VARARGS */
int
main(int argc, char **argv)
{
    int c, rem;
    char *cmd, *cp, **ap, buf[RSH_BUFSIZ], **argv0, *args, *args_no_x;
    char *host = NULL, *user = NULL;
    int cc;
    boolean_t asrsh = B_FALSE;
    struct passwd *pwd;
    boolean_t readfrom_rem;
    boolean_t readfrom_rfd2;
    int one = 1;
    int omask;
    boolean_t nflag = B_FALSE;
    char *krb_realm = NULL;
    krb5_flags authopts;
    krb5_error_code status;
    enum kcmd_proto kcmd_proto = KCMD_NEW_PROTOCOL;
    uid_t uid = getuid();

    c = (argc + 1) * sizeof (char *);
    if ((argv0 = malloc(c)) == NULL) {
        perror("malloc");
        return (EXIT_FAILURE);
    }
    (void) memcpy(argv0, argv, c);

    (void) setlocale(LC_ALL, "");

    (void) textdomain(TEXT_DOMAIN);

    /*
     * Determine command name used to invoke to rlogin(1). Users can
     * create links named by a host pointing to the binary and type
     * "hostname" to log into that host afterwards.
     */
    cmd = strrchr(argv[0], '/');
    cmd = (cmd != NULL) ? (cmd + 1) : argv[0];

    /*
     *	Add "remsh" as an alias for "rsh" (System III, V networking
     *	add-ons often used this name for the remote shell since rsh
     *	was already taken for the restricted shell).  Note that this
     *	usurps the ability to use "remsh" as the name of a host (by
     *	symlinking it to rsh), so we go one step farther:  if the
     *	file "/usr/bin/remsh" does not exist, we behave as if "remsh"
     *	is a host name.  If it does exist, we accept "remsh" as an
     *	"rsh" alias.
     */
    if (strcmp(cmd, "remsh") == 0) {
        struct stat sb;

        if (stat("/usr/bin/remsh", &sb) < 0)
            host = cmd;
    } else if (strcmp(cmd, "rsh") != 0) {
        host = cmd;
    }

    /* Handle legacy synopsis "rsh hostname options [command]". */
    if (host == NULL) {
        if (argc < 2)
            usage();
        if (*argv[1] != '-') {
            host = argv[1];
            argc--;
            argv[1] = argv[0];
            argv++;
            asrsh = B_TRUE;
        }
    }

    while ((c = getopt(argc, argv,
                       DEBUGOPTSTRING "8AFKLP:ade:fk:l:nwx")) != -1) {
        switch (c) {
#ifdef DEBUG
        case 'D':
            portnumber = htons(atoi(optarg));
            krb5auth_flag++;
            break;
#endif /* DEBUG */
        case 'F':
            if (fflag)
                usage_forward();
            Fflag = 1;
            krb5auth_flag++;
            fwdable_done = B_TRUE;
            break;
        case 'f':
            if (Fflag)
                usage_forward();
            fflag = 1;
            krb5auth_flag++;
            fwd_done = B_TRUE;
            break;
        case 'P':
            if (strcmp(optarg, "N") == 0)
                kcmd_proto = KCMD_NEW_PROTOCOL;
            else if (strcmp(optarg, "O") == 0)
                kcmd_proto = KCMD_OLD_PROTOCOL;
            else
                die(gettext("rsh: Only -PN or -PO "
                            "allowed.\n"));
            if (rcmdoption_done)
                die(gettext("rsh: Only one of -PN and -PO "
                            "allowed.\n"));
            rcmdoption_done = B_TRUE;
            krb5auth_flag++;
            break;
        case 'a':
            krb5auth_flag++;
            break;
        case 'K':
            no_krb5auth_flag++;
            break;
        case 'd':
            options |= SO_DEBUG;
            break;
        case 'k':
            krb_realm = optarg;
            krb5auth_flag++;
            break;
        case 'l':
            user = optarg;
            break;
        case 'n':
            if (!nflag) {
                if (close(STDIN_FILENO) < 0) {
                    perror("close");
                    return (EXIT_FAILURE);
                }
                /*
                 * "STDION_FILENO" defined to 0 by POSIX
                 * and hence the lowest file descriptor.
                 * So the open(2) below is guaranteed to
                 * reopen it because we closed it above.
                 */
                if (open("/dev/null", O_RDONLY) < 0) {
                    perror("open");
                    return (EXIT_FAILURE);
                }
                nflag = B_TRUE;
            }
            break;
        case 'x':
            encrypt_flag = 1;
            krb5auth_flag++;
            encrypt_done = B_TRUE;
            break;
        /*
         * Ignore the -L, -w, -e and -8 flags to allow aliases with
         * rlogin to work. Actually rlogin(1) doesn't understand
         * -w either but because "rsh -w hostname command" used
         * to work we still accept it.
         */
        case '8':
        case 'L':
        case 'e':
        case 'w':
        /*
         * On the lines of the -L, -w, -e and -8 options above, we
         * ignore the -A option too, in order to allow aliases with
         * rlogin to work.
         *
         * Mind you !, the -a option to trigger Kerberos authentication
         * in rsh, has a totally different usage in rlogin, its the
         * -A option (in rlogin) which needs to be used to talk
         * Kerberos.
         */
        case 'A':
            break;
        default:
            usage();
        }
    }

    argc -= optind;
    argv += optind;

    if (host == NULL) {
        if (argc == 0)
            usage();
        argc--;
        host = *argv++;
        asrsh = B_TRUE;
    }

    if (argc == 0) {
        (void) setreuid(uid, uid);
        if (nflag)
            usage();
        if (asrsh)
            *argv0 = "rlogin";
        (void) execv(rlogin_path, argv0);
        perror(rlogin_path);

        (void) fprintf(stderr, gettext("No local rlogin "
                                       "program found.\n"));
        return (EXIT_FAILURE);
    }

    if (__init_suid_priv(0, PRIV_NET_PRIVADDR, NULL) == -1) {
        (void) fprintf(stderr,
                       gettext("Insufficient privileges, "
                               "rsh must be set-uid root\n"));
        return (EXIT_FAILURE);
    }

    pwd = getpwuid(uid);
    if (pwd == NULL) {
        (void) fprintf(stderr, gettext("who are you?\n"));
        return (EXIT_FAILURE);
    }
    if (user == NULL)
        user = pwd->pw_name;

    /*
     * if the user disables krb5 on the cmdline (-K), then skip
     * all krb5 setup.
     *
     * if the user does not disable krb5 or enable krb5 on the
     * cmdline, check krb5.conf to see if it should be enabled.
     */

    if (no_krb5auth_flag) {
        krb5auth_flag = 0;
        Fflag = fflag = encrypt_flag = 0;
    } else if (!krb5auth_flag) {
        /* is autologin set in krb5.conf? */
        status = krb5_init_context(&bsd_context);
        /* don't sweat failure here */
        if (!status) {
            /*
             * note that the call to profile_get_options_boolean
             * with autologin_option can affect value of
             * krb5auth_flag
             */
            (void) profile_get_options_boolean(bsd_context->profile,
                                               appdef,
                                               autologin_option);
        }
    }

    if (krb5auth_flag) {
        if (!bsd_context) {
            status = krb5_init_context(&bsd_context);
            if (status) {
                com_err("rsh", status,
                        "while initializing krb5");
                return (EXIT_FAILURE);

            }
        }

        /*
         * Get our local realm to look up local realm options.
         */
        status = krb5_get_default_realm(bsd_context, &realmdef[1]);
        if (status) {
            com_err("rsh", status,
                    gettext("while getting default realm"));
            return (EXIT_FAILURE);
        }
        /*
         * Check the realms section in krb5.conf for encryption,
         * forward & forwardable info
         */
        profile_get_options_boolean(bsd_context->profile, realmdef,
                                    option);
        /*
         * Check the appdefaults section
         */
        profile_get_options_boolean(bsd_context->profile, appdef,
                                    option);
        profile_get_options_string(bsd_context->profile, appdef,
                                   rcmdversion);
        /*
         * Set the *_flag variables, if the corresponding *_done are
         * set to 1, because we dont want the config file values
         * overriding the command line options.
         */
        if (encrypt_done)
            encrypt_flag = 1;
        if (fwd_done) {
            fflag = 1;
            Fflag = 0;
        } else if (fwdable_done) {
            Fflag = 1;
            fflag = 0;
        }
        if (!rcmdoption_done && (rcmdproto != NULL)) {
            if (strncmp(rcmdproto, "rcmdv2", 6) == 0) {
                kcmd_proto = KCMD_NEW_PROTOCOL;
            } else if (strncmp(rcmdproto, "rcmdv1", 6) == 0) {
                kcmd_proto = KCMD_OLD_PROTOCOL;
            } else {
                (void) fprintf(stderr, gettext("Unrecognized "
                                               "KCMD protocol (%s)"), rcmdproto);
                return (EXIT_FAILURE);
            }
        }


        if (encrypt_flag && (!krb5_privacy_allowed())) {
            (void) fprintf(stderr, gettext("rsh: Encryption not "
                                           "supported.\n"));
            return (EXIT_FAILURE);
        }
    }

    /*
     * Connect with the service (shell/kshell) on the daemon side
     */
    if (portnumber == 0) {
        while (!init_service(krb5auth_flag)) {
            /*
             * Connecting to the 'kshell' service failed,
             * fallback to normal rsh; Reset all KRB5 flags
             * and connect to 'shell' service on the server
             */
            krb5auth_flag = 0;
            encrypt_flag = fflag = Fflag = 0;
        }
    }

    cc = encrypt_flag ? strlen(dash_x) : 0;
    for (ap = argv; *ap != NULL; ap++)
        cc += strlen(*ap) + 1;
    cp = args = malloc(cc);
    if (cp == NULL)
        perror("malloc");
    if (encrypt_flag) {
        int length;

        length = strlcpy(args, dash_x, cc);
        cp += length;
        cc -= length;
    }
    args_no_x = args;

    for (ap = argv; *ap != NULL; ap++) {
        int length;

        length = strlcpy(cp, *ap, cc);
        assert(length < cc);
        cp += length;
        cc -= length;
        if (ap[1] != NULL) {
            *cp++ = ' ';
            cc--;
        }
    }

    if (krb5auth_flag) {
        authopts = AP_OPTS_MUTUAL_REQUIRED;
        /*
         * Piggy-back forwarding flags on top of authopts;
         * they will be reset in kcmd
         */
        if (fflag || Fflag)
            authopts |= OPTS_FORWARD_CREDS;
        if (Fflag)
            authopts |= OPTS_FORWARDABLE_CREDS;

        status = kcmd(&rem, &host, portnumber,
                      pwd->pw_name, user,
                      args, &rfd2, "host", krb_realm,
                      bsd_context, &auth_context, &cred,
                      NULL,	/* No need for sequence number */
                      NULL,	/* No need for server seq # */
                      authopts,
                      1,	/* Always set anyport */
                      &kcmd_proto);
        if (status != 0) {
            /*
             * If new protocol requested, we dont fallback to
             * less secure ones.
             */
            if (kcmd_proto == KCMD_NEW_PROTOCOL) {
                (void) fprintf(stderr, gettext("rsh: kcmdv2 "
                                               "to host %s failed - %s\n"
                                               "Fallback to normal rsh denied."),
                               host, error_message(status));
                return (EXIT_FAILURE);
            }
            /* check NO_TKT_FILE or equivalent... */
            if (status != -1) {
                (void) fprintf(stderr,
                               gettext("rsh: kcmd to host %s failed - %s\n"
                                       "trying normal rsh...\n\n"),
                               host, error_message(status));
            } else {
                (void) fprintf(stderr,
                               gettext("trying normal rsh...\n"));
            }
            /*
             * kcmd() failed, so we now fallback to normal rsh,
             * after resetting the KRB5 flags and the 'args' array
             */
            krb5auth_flag = 0;
            encrypt_flag = fflag = Fflag = 0;
            args = args_no_x;
            (void) init_service(B_FALSE);
        } else {
            /*
             * Set up buffers for desread and deswrite.
             */
            desinbuf.data = des_inbuf;
            desoutbuf.data = des_outbuf;
            desinbuf.length = sizeof (des_inbuf);
            desoutbuf.length = sizeof (des_outbuf);

            session_key = &cred->keyblock;

            if (kcmd_proto == KCMD_NEW_PROTOCOL) {
                status = krb5_auth_con_getlocalsubkey(
                             bsd_context,
                             auth_context,
                             &session_key);
                if (status) {
                    com_err("rsh", status,
                            "determining subkey for session");
                    return (EXIT_FAILURE);
                }
                if (session_key == NULL) {
                    com_err("rsh", 0, "no subkey "
                            "negotiated for connection");
                    return (EXIT_FAILURE);
                }
            }

            eblock.crypto_entry = session_key->enctype;
            eblock.key = (krb5_keyblock *)session_key;

            init_encrypt(encrypt_flag, bsd_context, kcmd_proto,
                         &desinbuf, &desoutbuf, CLIENT, &eblock);
            if (encrypt_flag) {
                char *s = gettext("This rsh session is using "
                                  "encryption for all data transmissions.");
                (void) write(STDERR_FILENO, s, strlen(s));
                (void) write(STDERR_FILENO, "\r\n", 2);
            }
        }
    }

    /*
     * Don't merge this with the "if" statement above because
     * "krb5auth_flag" might be set to false inside it.
     */
    if (!krb5auth_flag) {
        rem = rcmd_af(&host, portnumber, pwd->pw_name, user, args,
                      &rfd2, AF_INET6);
        if (rem < 0)
            return (EXIT_FAILURE);
    }
    __priv_relinquish();

    if (rfd2 < 0) {
        (void) fprintf(stderr, gettext("rsh: can't establish "
                                       "stderr\n"));
        return (EXIT_FAILURE);
    }
    if (options & SO_DEBUG) {
        if (setsockopt(rem, SOL_SOCKET, SO_DEBUG, (char *)&one,
                       sizeof (one)) < 0)
            perror("rsh: setsockopt (stdin)");
        if (setsockopt(rfd2, SOL_SOCKET, SO_DEBUG, (char *)&one,
                       sizeof (one)) < 0)
            perror("rsh: setsockopt (stderr)");
    }
    omask = sigblock(mask(SIGINT)|mask(SIGQUIT)|mask(SIGTERM));

    if (sigdisp(SIGINT) != SIG_IGN)
        (void) sigset(SIGINT, sendsig);
    if (sigdisp(SIGQUIT) != SIG_IGN)
        (void) sigset(SIGQUIT, sendsig);
    if (sigdisp(SIGTERM) != SIG_IGN)
        (void) sigset(SIGTERM, sendsig);

    if (nflag) {
        (void) shutdown(rem, SHUT_WR);
    } else {
        child_pid = fork();
        if (child_pid < 0) {
            perror("rsh: fork");
            return (EXIT_FAILURE);
        }

        if (!encrypt_flag) {
            (void) ioctl(rfd2, FIONBIO, &one);
            (void) ioctl(rem, FIONBIO, &one);
        }

        if (child_pid == 0) {
            /* Child */
            fd_set remset;
            char *bp;
            int  wc;
            (void) close(rfd2);
reread:
            errno = 0;
            cc = read(0, buf, sizeof (buf));
            if (cc <= 0)
                goto done;
            bp = buf;
rewrite:
            FD_ZERO(&remset);
            FD_SET(rem, &remset);
            if (select(rem + 1, NULL, &remset, NULL, NULL) < 0) {
                if (errno != EINTR) {
                    perror("rsh: select");
                    return (EXIT_FAILURE);
                }
                goto rewrite;
            }
            if (!FD_ISSET(rem, &remset))
                goto rewrite;
            writeiv = B_FALSE;
            wc = desrshwrite(rem, bp, cc);
            if (wc < 0) {
                if (errno == EWOULDBLOCK)
                    goto rewrite;
                goto done;
            }
            cc -= wc;
            bp += wc;
            if (cc == 0)
                goto reread;
            goto rewrite;
done:
            (void) shutdown(rem, SHUT_WR);
            return (EXIT_SUCCESS);
        }
    }

#define	MAX(a, b)	(((a) > (b)) ? (a) : (b))

    sigsetmask(omask);
    readfrom_rem = B_TRUE;
    readfrom_rfd2 = B_TRUE;
    (void) sigset(SIGPIPE, sigpipehandler);
    do {
        fd_set readyset;

        FD_ZERO(&readyset);
        if (readfrom_rem)
            FD_SET(rem, &readyset);
        if (readfrom_rfd2)
            FD_SET(rfd2, &readyset);
        if (select(MAX(rem, rfd2) + 1, &readyset, NULL, NULL,
                   NULL) < 0) {
            if (errno != EINTR) {
                perror("rsh: select");
                return (EXIT_FAILURE);
            }
            continue;
        }
        if (FD_ISSET(rfd2, &readyset)) {
            errno = 0;
            readiv = B_TRUE;
            cc = desrshread(rfd2, buf, sizeof (buf));
            if (cc <= 0) {
                if (errno != EWOULDBLOCK)
                    readfrom_rfd2 = B_FALSE;
            } else {
                (void) write(STDERR_FILENO, buf, cc);
            }
        }
        if (FD_ISSET(rem, &readyset)) {
            errno = 0;
            readiv = B_FALSE;
            cc = desrshread(rem, buf, sizeof (buf));
            if (cc <= 0) {
                if (errno != EWOULDBLOCK)
                    readfrom_rem = B_FALSE;
            } else
                (void) write(STDOUT_FILENO, buf, cc);
        }
    } while (readfrom_rem || readfrom_rfd2);

    if (!nflag)
        (void) kill(child_pid, SIGKILL);
    return (EXIT_SUCCESS);
}
예제 #7
0
파일: rlogin.c 프로젝트: alhazred/onarm
int
main(int argc, char **argv)
{
	int c;
	char *cp, *cmd, *name = NULL;
	struct passwd *pwd;
	uid_t uid;
	int options = 0, oldmask;
	int on = 1;
	speed_t speed = 0;
	int getattr_ret;
	char *tmp;
	int sock;
	krb5_flags authopts;
	krb5_error_code status;
	enum kcmd_proto kcmd_proto = KCMD_NEW_PROTOCOL;

	(void) setlocale(LC_ALL, "");

#if !defined(TEXT_DOMAIN)
#define	TEXT_DOMAIN "SYS_TEST"
#endif
	(void) textdomain(TEXT_DOMAIN);

	if (__init_suid_priv(0, PRIV_NET_PRIVADDR, NULL) == -1) {
		(void) fprintf(stderr,
		    gettext("Insufficient privileges, "
			"rlogin must be set-uid root\n"));
		exit(1);
	}

	{
		int it;

		if ((getattr_ret = tcgetattr(STDIN_FILENO, &savetty)) < 0)
			perror("tcgetattr");
		it = ioctl(STDIN_FILENO, I_FIND, "ttcompat");
		if (it < 0) {
			perror("ioctl I_FIND ttcompat");
			return (EXIT_FAILURE);
		}
		if (it == 0) {
			if (ioctl(STDIN_FILENO, I_PUSH, "ttcompat") < 0) {
				perror("ioctl I_PUSH ttcompat");
				exit(EXIT_FAILURE);
			}
			ttcompat = B_TRUE;
		}
	}

	/*
	 * Determine command name used to invoke to rlogin(1). Users can
	 * create links named by a host pointing to the binary and type
	 * "hostname" to log into that host afterwards.
	 */
	cmd = strrchr(argv[0], '/');
	cmd = (cmd != NULL) ? (cmd + 1) : argv[0];

	if (strcmp(cmd, rlogin) == 0) {
		if (argc < 2)
			usage();
		if (*argv[1] != '-') {
			host = argv[1];
			argc--;
			argv[1] = argv[0];
			argv++;
		}
	} else {
		host = cmd;
	}

	while ((c = getopt(argc, argv,
	    DEBUGOPTSTRING "8AEFLP:ade:fk:l:x")) != -1) {
		switch (c) {
		case '8':
			eight = B_TRUE;
			break;
		case 'A':
			krb5auth_flag = B_TRUE;
			break;
#ifdef DEBUG
		case 'D':
			portnumber = htons(atoi(optarg));
			krb5auth_flag = B_TRUE;
			break;
#endif /* DEBUG */
		case 'E':
			nocmdchar = B_TRUE;
			break;
		case 'F':
			if (fflag)
				usage_forward();
			Fflag = 1;
			krb5auth_flag = B_TRUE;
			fwdable_done = B_TRUE;
			break;
		case 'f':
			if (Fflag)
				usage_forward();
			fflag = 1;
			krb5auth_flag = B_TRUE;
			fwd_done = B_TRUE;
			break;
		case 'L':
			litout = B_TRUE;
			break;
		case 'P':
			if (strcmp(optarg, "N") == 0)
				kcmd_proto = KCMD_NEW_PROTOCOL;
			else if (strcmp(optarg, "O") == 0)
				kcmd_proto = KCMD_OLD_PROTOCOL;
			else
				die(gettext("rlogin: Only -PN or -PO "
				    "allowed.\n"));
			if (rcmdoption_done)
				die(gettext("rlogin: Only one of -PN and -PO "
				    "allowed.\n"));
			rcmdoption_done = B_TRUE;
			krb5auth_flag = B_TRUE;
			break;
		case 'a':
		/*
		 * Force the remote host to prompt for a password by sending
		 * a NULL username. This option is mutually exclusive with
		 * the -A, -x, -f, -F, -k <realm> options.
		 */
			null_local_username = B_TRUE;
			break;
		case 'd':
			options |= SO_DEBUG;
			break;
		case 'e': {
			int c;

			cp = optarg;

			if ((c = *cp) != '\\') {
				cmdchar = c;
			} else {
				c = cp[1];
				if (c == '\0' || c == '\\') {
					cmdchar = '\\';
				} else if (c >= '0' && c <= '7') {
					long lc;

					lc = strtol(&cp[1], NULL, 8);
					if (lc < 0 || lc > 255)
						die(gettext("rlogin: octal "
						    "escape character %s too "
						    "large.\n"), cp);
					cmdchar = (char)lc;
				} else {
					die(gettext("rlogin: unrecognized "
					    "escape character option %s.\n"),
					    cp);
				}
			}
			break;
		}
		case 'k':
			krb_realm = optarg;
			krb5auth_flag = B_TRUE;
			break;
		case 'l':
			name = optarg;
			break;
		case 'x':
			encrypt_flag = 1;
			krb5auth_flag = B_TRUE;
			encrypt_done = B_TRUE;
			break;
		default:
			usage();
		}
	}

	argc -= optind;
	argv += optind;

	if (host == NULL) {
		if (argc == 0)
			usage();
		argc--;
		host = *argv++;
	}

	if (argc > 0)
		usage();

	pwd = getpwuid(uid = getuid());
	if (pwd == NULL) {
		(void) fprintf(stderr, gettext("getpwuid(): can not find "
			"password entry for user id %d."), uid);
		return (EXIT_FAILURE);
	}
	if (name == NULL)
		name = pwd->pw_name;

	/*
	 * If the `-a' option is issued on the cmd line, we reset all
	 * flags associated with other KRB5 specific options, since
	 * the -a option is mutually exclusive with the rest.
	 */
	if (null_local_username) {
		krb5auth_flag = B_FALSE;
		fflag = Fflag = encrypt_flag = 0;
		(void) fprintf(stderr, gettext("Note: The -a option nullifies "
					"all other Kerberos-specific\noptions "
					"you may have used.\n"));
	}

	if (krb5auth_flag) {
		status = krb5_init_context(&bsd_context);
		if (status) {
			com_err(rlogin, status, gettext("while initializing"
					" krb5"));
			return (EXIT_FAILURE);
		}
		/*
		 * Set up buffers for desread and deswrite.
		 */
		desinbuf.data = des_inbuf;
		desoutbuf.data = des_outbuf;
		desinbuf.length = sizeof (des_inbuf);
		desoutbuf.length = sizeof (des_outbuf);

		/*
		 * Get our local realm to look up local realm options.
		 */
		status = krb5_get_default_realm(bsd_context, &realmdef[1]);
		if (status) {
			com_err(rlogin, status,
				gettext("while getting default realm"));
			return (EXIT_FAILURE);
		}
		/*
		 * Check the realms section in krb5.conf for encryption,
		 * forward & forwardable info
		 */
		profile_get_options_boolean(bsd_context->profile, realmdef,
						option);
		/*
		 * Check the appdefaults section
		 */
		profile_get_options_boolean(bsd_context->profile, appdef,
						option);
		profile_get_options_string(bsd_context->profile, appdef,
						rcmdversion);

		/*
		 * Set the *_flag variables, if the corresponding *_done are
		 * set to 1, because we dont want the config file values
		 * overriding the command line options.
		 */
		if (encrypt_done)
			encrypt_flag = 1;
		if (fwd_done) {
			fflag = 1;
			Fflag = 0;
		} else if (fwdable_done) {
			Fflag = 1;
			fflag = 0;
		}
		if (!rcmdoption_done && (rcmdproto != NULL)) {
			if (strncmp(rcmdproto, "rcmdv2", 6) == 0) {
				kcmd_proto = KCMD_NEW_PROTOCOL;
			} else if (strncmp(rcmdproto, "rcmdv1", 6) == 0) {
				kcmd_proto = KCMD_OLD_PROTOCOL;
			} else {
				(void) fprintf(stderr, gettext("Unrecognized "
					"KCMD protocol (%s)"), rcmdproto);
				return (EXIT_FAILURE);
			}
		}

		if (encrypt_flag && (!krb5_privacy_allowed())) {
			(void) fprintf(stderr, gettext("rlogin: "******"Encryption not supported.\n"));
			return (EXIT_FAILURE);
		}
	}

	if (port_number == 0) {
		if (krb5auth_flag) {
			struct servent *sp;

			/*
			 * If the krb5auth_flag is set (via -A, -f, -F, -k) &
			 * if there is an entry in /etc/services for Kerberos
			 * login, attempt to login with Kerberos. If we fail
			 * at any step,  use the standard rlogin
			 */
			sp = getservbyname(encrypt_flag ?
			    "eklogin" : "klogin", "tcp");
			if (sp == NULL) {
				port_number = encrypt_flag ?
				    htons(2105) : htons(543);
			} else {
				port_number = sp->s_port;
			}
		} else {
			port_number = htons(IPPORT_LOGINSERVER);
		}
	}

	cp = getenv("TERM");
	if (cp) {
		(void) strncpy(term, cp, sizeof (term));
		term[sizeof (term) - 1] = '\0';
	}
	if (getattr_ret == 0) {
		speed = cfgetospeed(&savetty);
		/*
		 * "Be conservative in what we send" -- Only send baud rates
		 * which at least all 4.x BSD derivatives are known to handle
		 * correctly.
		 * NOTE:  This code assumes new termios speed values will
		 * be "higher" speeds.
		 */
		if (speed > B38400)
			speed = B38400;
	}

	/*
	 * Only put the terminal speed info in if we have room
	 * so we don't overflow the buffer, and only if we have
	 * a speed we recognize.
	 */
	if (speed > 0 && speed < sizeof (speeds)/sizeof (char *) &&
	    strlen(term) + strlen("/") + strlen(speeds[speed]) + 1 <
	    sizeof (term)) {
		(void) strcat(term, "/");
		(void) strcat(term, speeds[speed]);
	}
	(void) sigset(SIGPIPE, (sigdisp_t)lostpeer);
	/* will use SIGUSR1 for window size hack, so hold it off */
	oldmask = sigblock(sigmask(SIGURG) | sigmask(SIGUSR1));

	/*
	 * Determine if v4 literal address and if so store it to one
	 * side. This is to correct the undesired behaviour of rcmd_af
	 * which converts a passed in v4 literal address to a v4 mapped
	 * v6 literal address. If it was a v4 literal we then re-assign
	 * it to host.
	 */
	tmp = NULL;
	if (inet_addr(host) != (in_addr_t)-1)
		tmp = host;

	if (krb5auth_flag) {
		authopts = AP_OPTS_MUTUAL_REQUIRED;

		/* Piggy-back forwarding flags on top of authopts; */
		/* they will be reset in kcmd */
		if (fflag || Fflag)
			authopts |= OPTS_FORWARD_CREDS;
		if (Fflag)
			authopts |= OPTS_FORWARDABLE_CREDS;

		status = kcmd(&sock, &host, port_number,
			null_local_username ? "" : pwd->pw_name,
			name, term, NULL,
			"host", krb_realm, bsd_context, &auth_context,
			&cred,
			NULL,		/* No need for sequence number */
			NULL,		/* No need for server seq # */
			authopts,
			0,		/* Not any port # */
			&kcmd_proto);

		if (status != 0) {
			/*
			 * If new protocol requested, we dont fallback to
			 * less secure ones.
			 */
			if (kcmd_proto == KCMD_NEW_PROTOCOL) {
				(void) fprintf(stderr, gettext("rlogin: kcmdv2 "
					"to host %s failed - %s\n"
					"Fallback to normal rlogin denied."),
					host, error_message(status));
				return (EXIT_FAILURE);
			}
			if (status != -1) {
				(void) fprintf(stderr, gettext("rlogin: kcmd "
						"to host %s failed - %s,\n"
						"trying normal rlogin...\n\n"),
						host, error_message(status));
			} else {
				(void) fprintf(stderr,
					gettext("trying normal rlogin...\n"));
			}
			/*
			 * kcmd() failed, so we have to
			 * fallback to normal rlogin
			 */
			port_number = htons(IPPORT_LOGINSERVER);
			krb5auth_flag = B_FALSE;
			fflag = Fflag = encrypt_flag = 0;
			null_local_username = B_FALSE;
		} else {
			(void) fprintf(stderr,
			    gettext("connected with Kerberos V5\n"));

			/*
			 * Setup eblock for desread and deswrite.
			 */
			session_key = &cred->keyblock;

			if (kcmd_proto == KCMD_NEW_PROTOCOL) {
				status = krb5_auth_con_getlocalsubkey(
				    bsd_context,
				    auth_context,
				    &session_key);
				if (status) {
					com_err(rlogin, status,
					    "determining subkey for session");
					return (EXIT_FAILURE);
				}
				if (session_key == NULL) {
					com_err(rlogin, 0,
					    "no subkey negotiated for "
					    "connection");
					return (EXIT_FAILURE);
				}
			}

			eblock.crypto_entry = session_key->enctype;
			eblock.key = (krb5_keyblock *)session_key;

			init_encrypt(encrypt_flag, bsd_context, kcmd_proto,
			    &desinbuf, &desoutbuf, CLIENT, &eblock);

			rem = sock;
			if (rem < 0)
				pop(EXIT_FAILURE);
		}
	}

	/*
	 * Don't merge this with the "if" statement above because
	 * "krb5auth_flag" might be set to false inside it.
	 */
	if (!krb5auth_flag) {
		rem = rcmd_af(&host, port_number,
			null_local_username ? "" : pwd->pw_name,
			name, term, NULL, AF_INET6);
		if (rem < 0)
			pop(EXIT_FAILURE);
	}

	/* Never need our privilege again */
	__priv_relinquish();

	if (tmp != NULL)
		host = tmp;

	if (options & SO_DEBUG &&
	    setsockopt(rem, SOL_SOCKET, SO_DEBUG, (char *)&on,
			    sizeof (on)) < 0)
		perror("rlogin: setsockopt (SO_DEBUG)");

	{
		int bufsize = 8192;

		(void) setsockopt(rem, SOL_SOCKET, SO_RCVBUF, (char *)&bufsize,
			sizeof (int));
	}

	doit(oldmask);
	return (0);
}
예제 #8
0
int
main(int argc, char **argv)
{
	struct passwd const *pw;
	struct servent const *sp;
	long omask;
	int argoff, asrsh, ch, dflag, nflag, one, rem;
	pid_t pid = 0;
	uid_t uid;
	char *args, *host, *p, *user;
	int timeout = 0;

	argoff = asrsh = dflag = nflag = 0;
	one = 1;
	host = user = NULL;

	/* if called as something other than "rsh", use it as the host name */
	if ((p = strrchr(argv[0], '/')))
		++p;
	else
		p = argv[0];
	if (strcmp(p, "rsh"))
		host = p;
	else
		asrsh = 1;

	/* handle "rsh host flags" */
	if (!host && argc > 2 && argv[1][0] != '-') {
		host = argv[1];
		argoff = 1;
	}

#define	OPTIONS	"468Lde:l:nt:w"
	while ((ch = getopt(argc - argoff, argv + argoff, OPTIONS)) != -1)
		switch(ch) {
		case '4':
			family = PF_INET;
			break;

		case '6':
			family = PF_INET6;
			break;

		case 'L':	/* -8Lew are ignored to allow rlogin aliases */
		case 'e':
		case 'w':
		case '8':
			break;
		case 'd':
			dflag = 1;
			break;
		case 'l':
			user = optarg;
			break;
		case 'n':
			nflag = 1;
			break;
		case 't':
			timeout = atoi(optarg);
			break;
		case '?':
		default:
			usage();
		}
	optind += argoff;

	/* if haven't gotten a host yet, do so */
	if (!host && !(host = argv[optind++]))
		usage();

	/* if no further arguments, must have been called as rlogin. */
	if (!argv[optind]) {
		if (asrsh)
			*argv = rlogin;
		execv(_PATH_RLOGIN, argv);
		err(1, "can't exec %s", _PATH_RLOGIN);
	}

	argc -= optind;
	argv += optind;

	if (!(pw = getpwuid(uid = getuid())))
		errx(1, "unknown user id");
	if (!user)
		user = pw->pw_name;

	args = copyargs(argv);

	sp = NULL;
	if (sp == NULL)
		sp = getservbyname("shell", "tcp");
	if (sp == NULL)
		errx(1, "shell/tcp: unknown service");

	if (timeout) {
		signal(SIGALRM, connect_timeout);
		alarm(timeout);
	}
	rem = rcmd_af(&host, sp->s_port, pw->pw_name, user, args, &rfd2,
		      family);
	if (timeout) {
		signal(SIGALRM, SIG_DFL);
		alarm(0);
	}

	if (rem < 0)
		exit(1);

	if (rfd2 < 0)
		errx(1, "can't establish stderr");
	if (dflag) {
		if (setsockopt(rem, SOL_SOCKET, SO_DEBUG, &one,
		    sizeof(one)) < 0)
			warn("setsockopt");
		if (setsockopt(rfd2, SOL_SOCKET, SO_DEBUG, &one,
		    sizeof(one)) < 0)
			warn("setsockopt");
	}

	setuid(uid);
	omask = sigblock(sigmask(SIGINT)|sigmask(SIGQUIT)|sigmask(SIGTERM));
	if (signal(SIGINT, SIG_IGN) != SIG_IGN)
		signal(SIGINT, sendsig);
	if (signal(SIGQUIT, SIG_IGN) != SIG_IGN)
		signal(SIGQUIT, sendsig);
	if (signal(SIGTERM, SIG_IGN) != SIG_IGN)
		signal(SIGTERM, sendsig);

	if (!nflag) {
		pid = fork();
		if (pid < 0)
			err(1, "fork");
	}
	else
		shutdown(rem, SHUT_WR);

	ioctl(rfd2, FIONBIO, &one);
	ioctl(rem, FIONBIO, &one);

	talk(nflag, omask, pid, rem, timeout);

	if (!nflag)
		kill(pid, SIGKILL);
	exit(0);
}
예제 #9
0
int
rcmd(char **ahost, int rport, const char *locuser, const char *remuser,
     const char *cmd, int *fd2p)
{
	return rcmd_af(ahost, rport, locuser, remuser, cmd, fd2p, AF_INET);
}
예제 #10
0
파일: rlogin.c 프로젝트: JabirTech/Source
int
main(int argc, char *argv[])
{
	struct passwd *pw;
	struct servent *sp;
	struct termios tty;
	long omask;
	int argoff, ch, dflag, Dflag, one;
	uid_t uid;
	char *host, *localname, *p, *user, term[1024];
	speed_t ospeed;
	struct sockaddr_storage ss;
	socklen_t sslen;
	size_t len, len2;
	int i;

	argoff = dflag = Dflag = 0;
	one = 1;
	host = localname = user = NULL;

	if ((p = strrchr(argv[0], '/')))
		++p;
	else
		p = argv[0];

	if (strcmp(p, "rlogin"))
		host = p;

	/* handle "rlogin host flags" */
	if (!host && argc > 2 && argv[1][0] != '-') {
		host = argv[1];
		argoff = 1;
	}

#define	OPTIONS	"468DEde:i:l:"
	while ((ch = getopt(argc - argoff, argv + argoff, OPTIONS)) != -1)
		switch(ch) {
		case '4':
			family = PF_INET;
			break;

		case '6':
			family = PF_INET6;
			break;

		case '8':
			eight = 1;
			break;
		case 'D':
			Dflag = 1;
			break;
		case 'E':
			noescape = 1;
			break;
		case 'd':
			dflag = 1;
			break;
		case 'e':
			noescape = 0;
			escapechar = getescape(optarg);
			break;
		case 'i':
			if (getuid() != 0)
				errx(1, "-i user: permission denied");
			localname = optarg;
			break;
		case 'l':
			user = optarg;
			break;
		case '?':
		default:
			usage();
		}
	optind += argoff;

	/* if haven't gotten a host yet, do so */
	if (!host && !(host = argv[optind++]))
		usage();

	if (argv[optind])
		usage();

	if (!(pw = getpwuid(uid = getuid())))
		errx(1, "unknown user id");
	if (!user)
		user = pw->pw_name;
	if (!localname)
		localname = pw->pw_name;

	sp = NULL;
	sp = getservbyname("login", "tcp");
	if (sp == NULL)
		errx(1, "login/tcp: unknown service");

	if ((p = getenv("TERM")) != NULL)
		(void)strlcpy(term, p, sizeof(term));
	len = strlen(term);
	if (len < (sizeof(term) - 1) && tcgetattr(0, &tty) == 0) {
		/* start at 2 to include the / */
		for (ospeed = i = cfgetospeed(&tty), len2 = 2; i > 9; len2++)
			i /= 10;
		if (len + len2 < sizeof(term))
			(void)snprintf(term + len, len2 + 1, "/%d", ospeed);
	}

	(void)get_window_size(0, &winsize);

	(void)signal(SIGPIPE, lostpeer);
	/* will use SIGUSR1 for window size hack, so hold it off */
	omask = sigblock(sigmask(SIGURG) | sigmask(SIGUSR1));
	/*
	 * We set SIGURG and SIGUSR1 below so that an
	 * incoming signal will be held pending rather than being
	 * discarded. Note that these routines will be ready to get
	 * a signal by the time that they are unblocked below.
	 */
	(void)signal(SIGURG, copytochild);
	(void)signal(SIGUSR1, writeroob);

	rem = rcmd_af(&host, sp->s_port, localname, user, term, 0, family);

	if (rem < 0)
		exit(1);

	if (dflag &&
	    setsockopt(rem, SOL_SOCKET, SO_DEBUG, &one, sizeof(one)) < 0)
		warn("setsockopt");
	if (Dflag &&
	    setsockopt(rem, IPPROTO_TCP, TCP_NODELAY, &one, sizeof(one)) < 0)
		warn("setsockopt NODELAY (ignored)");

	sslen = sizeof(ss);
	one = IPTOS_LOWDELAY;
	if (getsockname(rem, (struct sockaddr *)&ss, &sslen) == 0 &&
	    ss.ss_family == AF_INET) {
		if (setsockopt(rem, IPPROTO_IP, IP_TOS, (char *)&one,
			       sizeof(int)) < 0)
			warn("setsockopt TOS (ignored)");
	} else
		if (ss.ss_family == AF_INET)
			warn("setsockopt getsockname failed");

	(void)setuid(uid);
	doit(omask);
	/*NOTREACHED*/
}
예제 #11
0
int
main(int argc, char *argv[])
{
	struct passwd *pw;
	struct servent *sp;
	struct sgttyb ttyb;
	long omask;
	int argoff, ch, dflag, Dflag, one, uid;
	char *host, *localname, *p, *user, term[1024];
#ifdef KERBEROS
	char *k;
#endif
	struct sockaddr_storage ss;
	int sslen;

	argoff = dflag = Dflag = 0;
	one = 1;
	host = localname = user = NULL;

	if ((p = strrchr(argv[0], '/')))
		++p;
	else
		p = argv[0];

	if (strcmp(p, "rlogin"))
		host = p;

	/* handle "rlogin host flags" */
	if (!host && argc > 2 && argv[1][0] != '-') {
		host = argv[1];
		argoff = 1;
	}

#ifdef KERBEROS
#define	OPTIONS	"468DEKLde:i:k:l:x"
#else
#define	OPTIONS	"468DEKLde:i:l:"
#endif
	while ((ch = getopt(argc - argoff, argv + argoff, OPTIONS)) != -1)
		switch(ch) {
		case '4':
			family = PF_INET;
			break;

		case '6':
			family = PF_INET6;
			break;

		case '8':
			eight = 1;
			break;
		case 'D':
			Dflag = 1;
			break;
		case 'E':
			noescape = 1;
			break;
		case 'K':
#ifdef KERBEROS
			use_kerberos = 0;
#endif
			break;
		case 'L':
			litout = 1;
			break;
		case 'd':
			dflag = 1;
			break;
		case 'e':
			noescape = 0;
			escapechar = getescape(optarg);
			break;
		case 'i':
			if (getuid() != 0)
				errx(1, "-i user: permission denied");
			localname = optarg;
			break;
#ifdef KERBEROS
		case 'k':
			dest_realm = dst_realm_buf;
			(void)strncpy(dest_realm, optarg, REALM_SZ);
			break;
#endif
		case 'l':
			user = optarg;
			break;
#ifdef CRYPT
#ifdef KERBEROS
		case 'x':
			doencrypt = 1;
			break;
#endif
#endif
		case '?':
		default:
			usage();
		}
	optind += argoff;

	/* if haven't gotten a host yet, do so */
	if (!host && !(host = argv[optind++]))
		usage();

	if (argv[optind])
		usage();

	if (!(pw = getpwuid(uid = getuid())))
		errx(1, "unknown user id");
	if (!user)
		user = pw->pw_name;
	if (!localname)
		localname = pw->pw_name;

	sp = NULL;
#ifdef KERBEROS
	k = auth_getval("auth_list");
	if (k && !strstr(k, "kerberos"))
	    use_kerberos = 0;
	if (use_kerberos) {
		sp = getservbyname((doencrypt ? "eklogin" : "klogin"), "tcp");
		if (sp == NULL) {
			use_kerberos = 0;
			warn("can't get entry for %s/tcp service",
			    doencrypt ? "eklogin" : "klogin");
		}
	}
#endif
	if (sp == NULL)
		sp = getservbyname("login", "tcp");
	if (sp == NULL)
		errx(1, "login/tcp: unknown service");

#define	MAX_TERM_LENGTH	(sizeof(term) - 1 - MAX_SPEED_LENGTH - 1)

	(void)strncpy(term, (p = getenv("TERM")) ? p : "network",
		      MAX_TERM_LENGTH);
	term[MAX_TERM_LENGTH] = '\0';
	if (ioctl(0, TIOCGETP, &ttyb) == 0) {
		(void)strcat(term, "/");
		(void)strcat(term, speeds[(int)ttyb.sg_ospeed]);
	}

	(void)get_window_size(0, &winsize);

	(void)signal(SIGPIPE, lostpeer);
	/* will use SIGUSR1 for window size hack, so hold it off */
	omask = sigblock(sigmask(SIGURG) | sigmask(SIGUSR1));
	/*
	 * We set SIGURG and SIGUSR1 below so that an
	 * incoming signal will be held pending rather than being
	 * discarded. Note that these routines will be ready to get
	 * a signal by the time that they are unblocked below.
	 */
	(void)signal(SIGURG, copytochild);
	(void)signal(SIGUSR1, writeroob);

#ifdef KERBEROS
	if (use_kerberos) {
		setuid(getuid());
		rem = KSUCCESS;
		errno = 0;
		if (dest_realm == NULL)
			dest_realm = krb_realmofhost(host);

#ifdef CRYPT
		if (doencrypt) {
			rem = krcmd_mutual(&host, sp->s_port, user, term, 0,
			    dest_realm, &cred, schedule);
			des_set_key(&cred.session, schedule);
		} else
#endif /* CRYPT */
			rem = krcmd(&host, sp->s_port, user, term, 0,
			    dest_realm);
		if (rem < 0) {
			int i;
			char **newargv;

			sp = getservbyname("login", "tcp");
			if (sp == NULL)
				errx(1, "unknown service login/tcp");
			if (errno == ECONNREFUSED)
				warn("remote host doesn't support Kerberos");
			if (errno == ENOENT)
				warn("can't provide Kerberos auth data");
			newargv = malloc((argc + 2) * sizeof(*newargv));
			if (newargv == NULL)
				err(1, "malloc");
			newargv[0] = argv[0];
			newargv[1] = "-K";
			for(i = 1; i < argc; ++i)
				newargv[i + 1] = argv[i];
			newargv[argc + 1] = NULL;
			execv(_PATH_RLOGIN, newargv);
		}
	} else {
#ifdef CRYPT
		if (doencrypt)
			errx(1, "the -x flag requires Kerberos authentication");
#endif /* CRYPT */
		rem = rcmd_af(&host, sp->s_port, localname, user, term, 0,
			      family);
	}
#else
	rem = rcmd_af(&host, sp->s_port, localname, user, term, 0, family);
#endif /* KERBEROS */

	if (rem < 0)
		exit(1);

	if (dflag &&
	    setsockopt(rem, SOL_SOCKET, SO_DEBUG, &one, sizeof(one)) < 0)
		warn("setsockopt");
	if (Dflag &&
	    setsockopt(rem, IPPROTO_TCP, TCP_NODELAY, &one, sizeof(one)) < 0)
		warn("setsockopt NODELAY (ignored)");

	sslen = sizeof(ss);
	one = IPTOS_LOWDELAY;
	if (getsockname(rem, (struct sockaddr *)&ss, &sslen) == 0 &&
	    ss.ss_family == AF_INET) {
		if (setsockopt(rem, IPPROTO_IP, IP_TOS, (char *)&one,
			       sizeof(int)) < 0)
			warn("setsockopt TOS (ignored)");
	} else
		if (ss.ss_family == AF_INET)
			warn("setsockopt getsockname failed");

	(void)setuid(uid);
	doit(omask);
	/*NOTREACHED*/
}
예제 #12
0
파일: rcp.c 프로젝트: lacombar/netbsd-alc
void
toremote(char *targ, int argc, char *argv[])
{
	int i;
	size_t len;
	char *bp, *host, *src, *suser, *thost, *tuser;

	*targ++ = 0;
	if (*targ == 0)
		targ = dot;

	if ((thost = strchr(argv[argc - 1], '@')) != NULL) {
		/* user@host */
		*thost++ = 0;
		tuser = argv[argc - 1];
		if (*tuser == '\0')
			tuser = NULL;
		else if (!okname(tuser))
			exit(1);
	} else {
		thost = argv[argc - 1];
		tuser = NULL;
	}
	thost = unbracket(thost);

	for (i = 0; i < argc - 1; i++) {
		src = colon(argv[i]);
		if (src) {			/* remote to remote */
			*src++ = 0;
			if (*src == 0)
				src = dot;
			host = strchr(argv[i], '@');
			len = strlen(_PATH_RSH) + strlen(argv[i]) +
			    strlen(src) + (tuser ? strlen(tuser) : 0) +
			    strlen(thost) + strlen(targ) + CMDNEEDS + 20;
			if (!(bp = malloc(len)))
				err(1, NULL);
			if (host) {
				*host++ = 0;
				host = unbracket(host);
				suser = argv[i];
				if (*suser == '\0')
					suser = pwname;
				else if (!okname(suser)) {
					(void)free(bp);
					continue;
				}
				(void)snprintf(bp, len,
				    "%s %s -l %s -n %s %s '%s%s%s:%s'",
				    _PATH_RSH, host, suser, cmd, src,
				    tuser ? tuser : "", tuser ? "@" : "",
				    thost, targ);
			} else {
				host = unbracket(argv[i]);
				(void)snprintf(bp, len,
				    "exec %s %s -n %s %s '%s%s%s:%s'",
				    _PATH_RSH, argv[i], cmd, src,
				    tuser ? tuser : "", tuser ? "@" : "",
				    thost, targ);
			}
			(void)susystem(bp);
			(void)free(bp);
		} else {			/* local to remote */
			if (rem == -1) {
				len = strlen(targ) + CMDNEEDS + 20;
				if (!(bp = malloc(len)))
					err(1, NULL);
				(void)snprintf(bp, len, "%s -t %s", cmd, targ);
				host = thost;
					rem = rcmd_af(&host, port, pwname,
					    tuser ? tuser : pwname,
					    bp, NULL, family);
				if (rem < 0)
					exit(1);
				if (response() < 0)
					exit(1);
				(void)free(bp);
			}
			source(1, argv+i);
		}
	}
}