From d352e8757c4817f687fcfaf265b69de5ce559095 Mon Sep 17 00:00:00 2001 From: taubert Date: Sat, 24 Jan 1998 08:31:02 +0000 Subject: [PATCH] Initial commit of rlogin utility --- usr.bin/rlogin/Makefile | 22 + usr.bin/rlogin/kcmd.c | 307 ++++++++++++ usr.bin/rlogin/krb.h | 38 ++ usr.bin/rlogin/krcmd.c | 158 ++++++ usr.bin/rlogin/rlogin.1 | 188 +++++++ usr.bin/rlogin/rlogin.c | 982 +++++++++++++++++++++++++++++++++++++ usr.bin/rlogin/rlogin.desc | 9 + usr.bin/rlogin/rlogin.rez | 31 ++ 8 files changed, 1735 insertions(+) create mode 100644 usr.bin/rlogin/Makefile create mode 100644 usr.bin/rlogin/kcmd.c create mode 100644 usr.bin/rlogin/krb.h create mode 100644 usr.bin/rlogin/krcmd.c create mode 100644 usr.bin/rlogin/rlogin.1 create mode 100644 usr.bin/rlogin/rlogin.c create mode 100644 usr.bin/rlogin/rlogin.desc create mode 100644 usr.bin/rlogin/rlogin.rez diff --git a/usr.bin/rlogin/Makefile b/usr.bin/rlogin/Makefile new file mode 100644 index 0000000..8c7c99e --- /dev/null +++ b/usr.bin/rlogin/Makefile @@ -0,0 +1,22 @@ +# @(#)Makefile 8.1 (Berkeley) 7/19/93 +# $Id: Makefile,v 1.1 1998/01/24 08:30:54 taubert Exp $ + +PROG= rlogin +SRCS= rlogin.c +LDADD= -lnetdb +OPTIMIZE=79 + +#.if exists(${DESTDIR}/usr/lib/libkrb.a) && (defined(MAKE_KERBEROS) \ +# || defined(MAKE_EBONES)) +#SRCS+= krcmd.c kcmd.c +#DPADD= ${LIBKRB} ${LIBDES} +#CFLAGS+=-DKERBEROS -DCRYPT +#LDADD= -lkrb -ldes +#DISTRIBUTION= krb +#.endif + +BINOWN= root +BINMODE=4555 +INSTALLFLAGS=-fschg + +.INCLUDE: /src/gno/prog.mk diff --git a/usr.bin/rlogin/kcmd.c b/usr.bin/rlogin/kcmd.c new file mode 100644 index 0000000..3f6a138 --- /dev/null +++ b/usr.bin/rlogin/kcmd.c @@ -0,0 +1,307 @@ +/* + * Copyright (c) 1983, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef lint +static char Xsccsid[] = "derived from @(#)rcmd.c 5.17 (Berkeley) 6/27/88"; +static char sccsid[] = "@(#)kcmd.c 8.2 (Berkeley) 8/19/93"; +#endif /* not lint */ + +#include +#include +#include +#include + +#include +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "krb.h" + +#ifndef MAXHOSTNAMELEN +#define MAXHOSTNAMELEN 64 +#endif + +#define START_PORT 5120 /* arbitrary */ + +int getport __P((int *)); + +int +kcmd(sock, ahost, rport, locuser, remuser, cmd, fd2p, ticket, service, realm, + cred, schedule, msg_data, laddr, faddr, authopts) + int *sock; + char **ahost; + u_short rport; + char *locuser, *remuser, *cmd; + int *fd2p; + KTEXT ticket; + char *service; + char *realm; + CREDENTIALS *cred; + Key_schedule schedule; + MSG_DAT *msg_data; + struct sockaddr_in *laddr, *faddr; + long authopts; +{ + int s, timo = 1, pid; + long oldmask; + struct sockaddr_in sin, from; + char c; +#ifdef ATHENA_COMPAT + int lport = IPPORT_RESERVED - 1; +#else + int lport = START_PORT; +#endif + struct hostent *hp; + int rc; + char *host_save; + int status; + + pid = getpid(); + hp = gethostbyname(*ahost); + if (hp == NULL) { + /* fprintf(stderr, "%s: unknown host\n", *ahost); */ + return (-1); + } + + host_save = malloc(strlen(hp->h_name) + 1); + strcpy(host_save, hp->h_name); + *ahost = host_save; + +#ifdef KERBEROS + /* If realm is null, look up from table */ + if (realm == NULL || realm[0] == '\0') + realm = krb_realmofhost(host_save); +#endif /* KERBEROS */ + + oldmask = sigblock(sigmask(SIGURG)); + for (;;) { + s = getport(&lport); + if (s < 0) { + if (errno == EAGAIN) + fprintf(stderr, + "kcmd(socket): All ports in use\n"); + else + perror("kcmd: socket"); + sigsetmask(oldmask); + return (-1); + } + fcntl(s, F_SETOWN, pid); + sin.sin_family = hp->h_addrtype; +#if defined(ultrix) || defined(sun) + bcopy(hp->h_addr, (caddr_t)&sin.sin_addr, hp->h_length); +#else + bcopy(hp->h_addr_list[0], (caddr_t)&sin.sin_addr, hp->h_length); +#endif + sin.sin_port = rport; + if (connect(s, (struct sockaddr *)&sin, sizeof(sin)) >= 0) + break; + (void) close(s); + if (errno == EADDRINUSE) { + lport--; + continue; + } + /* + * don't wait very long for Kerberos rcmd. + */ + if (errno == ECONNREFUSED && timo <= 4) { + /* sleep(timo); don't wait at all here */ + timo *= 2; + continue; + } +#if !(defined(ultrix) || defined(sun)) + if (hp->h_addr_list[1] != NULL) { + int oerrno = errno; + + fprintf(stderr, + "kcmd: connect to address %s: ", + inet_ntoa(sin.sin_addr)); + errno = oerrno; + perror(NULL); + hp->h_addr_list++; + bcopy(hp->h_addr_list[0], (caddr_t)&sin.sin_addr, + hp->h_length); + fprintf(stderr, "Trying %s...\n", + inet_ntoa(sin.sin_addr)); + continue; + } +#endif /* !(defined(ultrix) || defined(sun)) */ + if (errno != ECONNREFUSED) + perror(hp->h_name); + sigsetmask(oldmask); + return (-1); + } + lport--; + if (fd2p == 0) { + write(s, "", 1); + lport = 0; + } else { + char num[8]; + int s2 = getport(&lport), s3; + int len = sizeof(from); + + if (s2 < 0) { + status = -1; + goto bad; + } + listen(s2, 1); + (void) sprintf(num, "%d", lport); + if (write(s, num, strlen(num) + 1) != strlen(num) + 1) { + perror("kcmd(write): setting up stderr"); + (void) close(s2); + status = -1; + goto bad; + } + s3 = accept(s2, (struct sockaddr *)&from, &len); + (void) close(s2); + if (s3 < 0) { + perror("kcmd:accept"); + lport = 0; + status = -1; + goto bad; + } + *fd2p = s3; + from.sin_port = ntohs((u_short)from.sin_port); + if (from.sin_family != AF_INET || + from.sin_port >= IPPORT_RESERVED) { + fprintf(stderr, + "kcmd(socket): protocol failure in circuit setup.\n"); + status = -1; + goto bad2; + } + } + /* + * Kerberos-authenticated service. Don't have to send locuser, + * since its already in the ticket, and we'll extract it on + * the other side. + */ + /* (void) write(s, locuser, strlen(locuser)+1); */ + + /* set up the needed stuff for mutual auth, but only if necessary */ + if (authopts & KOPT_DO_MUTUAL) { + int sin_len; + *faddr = sin; + + sin_len = sizeof(struct sockaddr_in); + if (getsockname(s, (struct sockaddr *)laddr, &sin_len) < 0) { + perror("kcmd(getsockname)"); + status = -1; + goto bad2; + } + } +#ifdef KERBEROS + if ((status = krb_sendauth(authopts, s, ticket, service, *ahost, + realm, (unsigned long) getpid(), msg_data, + cred, schedule, + laddr, + faddr, + "KCMDV0.1")) != KSUCCESS) + goto bad2; +#endif /* KERBEROS */ + + (void) write(s, remuser, strlen(remuser)+1); + (void) write(s, cmd, strlen(cmd)+1); + + if ((rc = read(s, &c, 1)) != 1) { + if (rc == -1) + perror(*ahost); + else + fprintf(stderr,"kcmd: bad connection with remote host\n"); + status = -1; + goto bad2; + } + if (c != '\0') { + while (read(s, &c, 1) == 1) { + (void) write(2, &c, 1); + if (c == '\n') + break; + } + status = -1; + goto bad2; + } + sigsetmask(oldmask); + *sock = s; + return (KSUCCESS); +bad2: + if (lport) + (void) close(*fd2p); +bad: + (void) close(s); + sigsetmask(oldmask); + return (status); +} + +int +getport(alport) + int *alport; +{ + struct sockaddr_in sin; + int s; + + sin.sin_family = AF_INET; + sin.sin_addr.s_addr = INADDR_ANY; + s = socket(AF_INET, SOCK_STREAM, 0); + if (s < 0) + return (-1); + for (;;) { + sin.sin_port = htons((u_short)*alport); + if (bind(s, (struct sockaddr *)&sin, sizeof(sin)) >= 0) + return (s); + if (errno != EADDRINUSE) { + (void) close(s); + return (-1); + } + (*alport)--; +#ifdef ATHENA_COMPAT + if (*alport == IPPORT_RESERVED/2) { +#else + if (*alport == IPPORT_RESERVED) { +#endif + (void) close(s); + errno = EAGAIN; /* close */ + return (-1); + } + } +} diff --git a/usr.bin/rlogin/krb.h b/usr.bin/rlogin/krb.h new file mode 100644 index 0000000..07213f4 --- /dev/null +++ b/usr.bin/rlogin/krb.h @@ -0,0 +1,38 @@ +/*- + * Copyright (c) 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)krb.h 8.1 (Berkeley) 6/6/93 + */ + +int krcmd __P((char **, u_short, char *, char *, int *, char *)); +int krcmd_mutual __P((char **, u_short, char *, char *, int *, + char *, CREDENTIALS *, Key_schedule)); diff --git a/usr.bin/rlogin/krcmd.c b/usr.bin/rlogin/krcmd.c new file mode 100644 index 0000000..e485b2e --- /dev/null +++ b/usr.bin/rlogin/krcmd.c @@ -0,0 +1,158 @@ +/* + * Copyright (c) 1989, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef lint +static char sccsid[] = "@(#)krcmd.c 8.1 (Berkeley) 6/6/93"; +#endif /* not lint */ + +/* + * $Source: /nobackup/gdr/copy-of-cvs-from-tekarra/gno/usr.bin/rlogin/krcmd.c,v $ + * $Header: /mit/kerberos/ucb/mit/kcmd/RCS/krcmd.c,v 5.1 + * 89/07/25 15:38:44 kfall Exp Locker: kfall $ + * static char *rcsid_kcmd_c = + * "$Header: /mit/kerberos/ucb/mit/kcmd/RCS/krcmd.c,v 5.1 89/07/25 15:38:44 + * kfall Exp Locker: kfall $"; + */ + +#ifdef KERBEROS +#include +#ifdef CRYPT +#include +#endif + +#include + +#include +#include + +#include + +#define SERVICE_NAME "rcmd" + +int kcmd __P((int *, char **, u_short, char *, char *, char *, int *, + KTEXT, char *, char *, CREDENTIALS *, Key_schedule, MSG_DAT *, + struct sockaddr_in *, struct sockaddr_in *, long)); + +/* + * krcmd: simplified version of Athena's "kcmd" + * returns a socket attached to the destination, -1 or krb error on error + * if fd2p is non-NULL, another socket is filled in for it + */ + +int +krcmd(ahost, rport, remuser, cmd, fd2p, realm) + char **ahost; + u_short rport; + char *remuser, *cmd; + int *fd2p; + char *realm; +{ + int sock = -1, err = 0; + KTEXT_ST ticket; + long authopts = 0L; + + err = kcmd( + &sock, + ahost, + rport, + NULL, /* locuser not used */ + remuser, + cmd, + fd2p, + &ticket, + SERVICE_NAME, + realm, + (CREDENTIALS *) NULL, /* credentials not used */ + 0, /* key schedule not used */ + (MSG_DAT *) NULL, /* MSG_DAT not used */ + (struct sockaddr_in *) NULL, /* local addr not used */ + (struct sockaddr_in *) NULL, /* foreign addr not used */ + authopts + ); + + if (err > KSUCCESS && err < MAX_KRB_ERRORS) { + fprintf(stderr, "krcmd: %s\n", krb_err_txt[err]); + return(-1); + } + if (err < 0) + return(-1); + return(sock); +} + +#ifdef CRYPT +int +krcmd_mutual(ahost, rport, remuser, cmd, fd2p, realm, cred, sched) + char **ahost; + u_short rport; + char *remuser, *cmd; + int *fd2p; + char *realm; + CREDENTIALS *cred; + Key_schedule sched; +{ + int sock, err; + KTEXT_ST ticket; + MSG_DAT msg_dat; + struct sockaddr_in laddr, faddr; + long authopts = KOPT_DO_MUTUAL; + + err = kcmd( + &sock, + ahost, + rport, + NULL, /* locuser not used */ + remuser, + cmd, + fd2p, + &ticket, + SERVICE_NAME, + realm, + cred, /* filled in */ + sched, /* filled in */ + &msg_dat, /* filled in */ + &laddr, /* filled in */ + &faddr, /* filled in */ + authopts + ); + + if (err > KSUCCESS && err < MAX_KRB_ERRORS) { + fprintf(stderr, "krcmd_mutual: %s\n", krb_err_txt[err]); + return(-1); + } + + if (err < 0) + return (-1); + return(sock); +} +#endif /* CRYPT */ +#endif /* KERBEROS */ diff --git a/usr.bin/rlogin/rlogin.1 b/usr.bin/rlogin/rlogin.1 new file mode 100644 index 0000000..8f4453a --- /dev/null +++ b/usr.bin/rlogin/rlogin.1 @@ -0,0 +1,188 @@ +.\" Copyright (c) 1983, 1990, 1993 +.\" The Regents of the University of California. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" 3. All advertising materials mentioning features or use of this software +.\" must display the following acknowledgement: +.\" This product includes software developed by the University of +.\" California, Berkeley and its contributors. +.\" 4. Neither the name of the University nor the names of its contributors +.\" may be used to endorse or promote products derived from this software +.\" without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" @(#)rlogin.1 8.1 (Berkeley) 6/6/93 +.\" +.Dd June 6, 1993 +.Dt RLOGIN 1 +.Os BSD 4.2 +.Sh NAME +.Nm rlogin +.Nd remote login +.Sh SYNOPSIS +.Ar rlogin +.Op Fl 8DEKLdx +.Op Fl e Ar char +.Op Fl k Ar realm +.Op Fl l Ar username +.Ar host +.Sh DESCRIPTION +.Nm Rlogin +starts a terminal session on a remote host +.Ar host . +.Pp +.Nm Rlogin +first attempts to use the Kerberos authorization mechanism, described below. +If the remote host does not supporting Kerberos the standard Berkeley +.Pa rhosts +authorization mechanism is used. +The options are as follows: +.Bl -tag -width flag +.It Fl 8 +The +.Fl 8 +option allows an eight-bit input data path at all times; otherwise +parity bits are stripped except when the remote side's stop and start +characters are other than +^S/^Q . +.It Fl D +The +.Fl D +option sets the TCP_NODELAY socket option which can improve interactive response +at the expense of increased network load. +.It Fl E +The +.Fl E +option stops any character from being recognized as an escape character. +When used with the +.Fl 8 +option, this provides a completely transparent connection. +.It Fl K +The +.Fl K +option turns off all Kerberos authentication. +.It Fl L +The +.Fl L +option allows the rlogin session to be run in ``litout'' (see +.Xr tty 4 ) +mode. +.It Fl d +The +.Fl d +option turns on socket debugging (see +.Xr setsockopt 2 ) +on the TCP sockets used for communication with the remote host. +.It Fl e +The +.Fl e +option allows user specification of the escape character, which is +``~'' by default. +This specification may be as a literal character, or as an octal +value in the form \ennn. +.It Fl k +The +.FL k +option requests rlogin to obtain tickets for the remote host +in realm +.Ar realm +instead of the remote host's realm as determined by +.Xr krb_realmofhost 3 . +.It Fl x +The +.Fl x +option turns on +.Tn DES +encryption for all data passed via the +rlogin session. +This may impact response time and +.Tn CPU +utilization, but provides +increased security. +.El +.Pp +A line of the form ``.'' disconnects from the remote host. +Similarly, the line ``^Z'' will suspend the +.Nm rlogin +session, and ``'' suspends the +send portion of the rlogin, but allows output from the remote system. +By default, the tilde (``~'') character is the escape character, and +normally control-Y (``^Y'') is the delayed-suspend character. +.Pp +All echoing takes place at the remote site, so that (except for delays) +the +.Nm rlogin +is transparent. +Flow control via ^S/^Q and flushing of input and output on interrupts +are handled properly. +.Sh KERBEROS AUTHENTICATION +Each user may have a private authorization list in the file +.Pa .klogin +in their home directory. +Each line in this file should contain a Kerberos principal name of the +form +.Ar principal.instance@realm . +If the originating user is authenticated to one of the principals named +in +.Pa .klogin , +access is granted to the account. +The principal +.Ar accountname.@localrealm +is granted access if +there is no +.Pa .klogin +file. +Otherwise a login and password will be prompted for on the remote machine +as in +.Xr login 1 . +To avoid certain security problems, the +.Pa .klogin +file must be owned by +the remote user. +.Pp +If Kerberos authentication fails, a warning message is printed and the +standard Berkeley +.Nm rlogin +is used instead. +.Sh ENVIRONMENT +The following environment variable is utilized by +.Nm rlogin : +.Bl -tag -width TERM +.It Ev TERM +Determines the user's terminal type. +.El +.Sh SEE ALSO +.Xr rsh 1 , +.Xr kerberos 3 , +.Xr krb_sendauth 3 , +.Xr krb_realmofhost 3 +.Sh HISTORY +The +.Nm rlogin +command appeared in +.Bx 4.2 . +.Sh BUGS +.Nm Rlogin +will be replaced by +.Xr telnet 1 +in the near future. +.Pp +More of the environment should be propagated. diff --git a/usr.bin/rlogin/rlogin.c b/usr.bin/rlogin/rlogin.c new file mode 100644 index 0000000..7fcd20b --- /dev/null +++ b/usr.bin/rlogin/rlogin.c @@ -0,0 +1,982 @@ +/* + * Copyright (c) 1983, 1990, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef lint +static char copyright[] = +"@(#) Copyright (c) 1983, 1990, 1993\n\ + The Regents of the University of California. All rights reserved.\n"; +#endif /* not lint */ + +#ifndef lint +static char sccsid[] = "@(#)rlogin.c 8.1 (Berkeley) 6/6/93"; +#endif /* not lint */ + +/* + * rlogin - remote login + */ +#include +#include +#include +#ifndef __GNO__ +#include +#endif +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef __STDC__ +#include +#else +#include +#endif + +#ifdef KERBEROS +#include +#include + +#include "krb.h" + +CREDENTIALS cred; +Key_schedule schedule; +int use_kerberos = 1, doencrypt; +char dst_realm_buf[REALM_SZ], *dest_realm = NULL; +#endif + +#ifndef TIOCPKT_WINDOW +#define TIOCPKT_WINDOW 0x80 +#endif + +/* concession to Sun */ +#ifndef SIGUSR1 +#define SIGUSR1 30 +#endif + +int eight, litout, rem; + +int noescape; +u_char escapechar = '~'; + +char *speeds[] = { + "0", "50", "75", "110", "134", "150", "200", "300", "600", "1200", + "1800", "2400", "4800", "9600", "19200", "38400", "57600", "115200" +}; + +#ifdef OLDSUN +struct winsize { + unsigned short ws_row, ws_col; + unsigned short ws_xpixel, ws_ypixel; +}; +#else +#define get_window_size(fd, wp) ioctl(fd, TIOCGWINSZ, wp) +#endif +struct winsize winsize; + +void catch_child __P((int, int)); +void copytochild __P((int, int)); +__dead void doit __P((long)); +__dead void done __P((int)); +void echo __P((char)); +u_int getescape __P((char *)); +void lostpeer __P((int, int)); +void mode __P((int)); +void msg __P((char *)); +void oob __P((int, int)); +int reader __P((long)); +void sendwindow __P((void)); +void setsignal __P((int)); +void sigwinch __P((int, int)); +void stop __P((char)); +__dead void usage __P((void)); +void writer __P((void)); +void writeroob __P((int, int)); + +#ifdef KERBEROS +void warning __P((const char *, ...)); +#endif +#ifdef OLDSUN +int get_window_size __P((int, struct winsize *)); +#endif + +int +main(int argc, char **argv) +{ +extern char *optarg; +extern int optind; +struct passwd *pw; +struct servent *sp; +static struct sgttyb ttyb; +long omask; +int argoff, ch, dflag, Dflag, one, uid; +char *host, *p, *user; +static char term[1024]; + + argoff = dflag = Dflag = 0; + one = 1; + host = user = NULL; + + if (p = rindex(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 "8DEKLde:k:l:x" +#else +#define OPTIONS "8DEKLde:l:" +#endif + while ((ch = getopt(argc - argoff, argv + argoff, OPTIONS)) != EOF) + switch(ch) { + 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; +#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; + argc -= optind; + argv += optind; + + /* if haven't gotten a host yet, do so */ + if (!host && !(host = *argv++)) + usage(); + + if (*argv) + usage(); + + if (!(pw = getpwuid(uid = getuid()))) { + (void)fprintf(stderr, "rlogin: unknown user id.\n"); + exit(1); + } + if (!user) + user = pw->pw_name; + + sp = NULL; +#ifdef KERBEROS + if (use_kerberos) { + sp = getservbyname((doencrypt ? "eklogin" : "klogin"), "tcp"); + if (sp == NULL) { + use_kerberos = 0; + warning("can't get entry for %s/tcp service", + doencrypt ? "eklogin" : "klogin"); + } + } +#endif + if (sp == NULL) + sp = getservbyname("login", "tcp"); + if (sp == NULL) { + (void)fprintf(stderr, "rlogin: login/tcp: unknown service.\n"); + exit(1); + } + + (void)strcpy(term, (p = getenv("TERM")) ? p : "network"); + if (ioctl(STDIN_FILENO, TIOCGETP, &ttyb) == 0) { + (void)strcat(term, "/"); + (void)strcat(term, speeds[(int)ttyb.sg_ospeed]); + } + + (void)get_window_size(STDIN_FILENO, &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 +try_connect: + if (use_kerberos) { + struct hostent *hp; + + /* Fully qualify hostname (needed for krb_realmofhost). */ + hp = gethostbyname(host); + if (hp != NULL && !(host = strdup(hp->h_name))) { + (void)fprintf(stderr, "rlogin: %s\n", + strerror(ENOMEM)); + exit(1); + } + + 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) { + use_kerberos = 0; + sp = getservbyname("login", "tcp"); + if (sp == NULL) { + (void)fprintf(stderr, + "rlogin: unknown service login/tcp.\n"); + exit(1); + } + if (errno == ECONNREFUSED) + warning("remote host doesn't support Kerberos"); + if (errno == ENOENT) + warning("can't provide Kerberos auth data"); + goto try_connect; + } + } else { +#ifdef CRYPT + if (doencrypt) { + (void)fprintf(stderr, + "rlogin: the -x flag requires Kerberos authentication.\n"); + exit(1); + } +#endif /* CRYPT */ + rem = rcmd(&host, sp->s_port, pw->pw_name, user, term, 0); + } +#else + rem = rcmd(&host, sp->s_port, pw->pw_name, user, term, 0); +#endif /* KERBEROS */ + + if (rem < 0) + exit(1); + + if (dflag && + setsockopt(rem, SOL_SOCKET, SO_DEBUG, &one, sizeof(one)) < 0) + (void)fprintf(stderr, "rlogin: setsockopt: %s.\n", + strerror(errno)); + if (Dflag && + setsockopt(rem, IPPROTO_TCP, TCP_NODELAY, &one, sizeof(one)) < 0) + perror("rlogin: setsockopt NODELAY (ignored)"); + + one = IPTOS_LOWDELAY; + if (setsockopt(rem, IPPROTO_IP, IP_TOS, (char *)&one, sizeof(int)) < 0) + perror("rlogin: setsockopt TOS (ignored)"); + + (void)setuid(uid); + doit(omask); + /*NOTREACHED*/ +} + +int child, defflags, deflflags, tabflag; +char deferase, defkill; +struct tchars deftc; +struct ltchars defltc; +struct tchars notc = { -1, -1, -1, -1, -1, -1 }; +struct ltchars noltc = { -1, -1, -1, -1, -1, -1 }; + +#ifdef __ORCAC__ +#pragma databank 1 +#endif +void +doit_child(long omask) +{ + mode(1); + if (reader(omask) == 0) { + msg("connection closed."); + _exit(0); + } + sleep(1); + msg("\007connection closed."); + _exit(1); +} +#ifdef __ORCAC__ +#pragma databank 0 +#endif + +void +doit(long omask) +{ +static struct sgttyb sb; + + (void)ioctl(STDIN_FILENO, TIOCGETP, (char *)&sb); + defflags = sb.sg_flags; + tabflag = defflags & TBDELAY; + defflags &= ECHO | CRMOD; + deferase = sb.sg_erase; + defkill = sb.sg_kill; + (void)ioctl(STDIN_FILENO, TIOCLGET, &deflflags); + (void)ioctl(STDIN_FILENO, TIOCGETC, &deftc); + notc.t_startc = deftc.t_startc; + notc.t_stopc = deftc.t_stopc; + (void)ioctl(STDIN_FILENO, TIOCGLTC, &defltc); + (void)signal(SIGINT, SIG_IGN); + setsignal(SIGHUP); + setsignal(SIGQUIT); + child = fork2(doit_child, 1024, 0, "rlogin child", 2, omask); + if (child == -1) { + (void)fprintf(stderr, "rlogin: fork: %s.\n", strerror(errno)); + done(1); + } + + /* + * We may still own the socket, and may have a pending SIGURG (or might + * receive one soon) that we really want to send to the reader. When + * one of these comes in, the trap copytochild simply copies such + * signals to the child. We can now unblock SIGURG and SIGUSR1 + * that were set above. + */ + (void)sigsetmask(omask); + (void)signal(SIGCHLD, catch_child); + writer(); + msg("closed connection."); + done(0); +} + +/* trap a signal, unless it is being ignored. */ +void +setsignal(int sig) +{ +long omask = sigblock(sigmask(sig)); + + if (signal(sig, exit) == SIG_IGN) + (void)signal(sig, SIG_IGN); + (void)sigsetmask(omask); +} + +__dead void +done(int status) +{ +int w; +union wait wstatus; + + mode(0); + if (child > 0) { + /* make sure catch_child does not snap it up */ + (void)signal(SIGCHLD, SIG_DFL); + if (kill(child, SIGKILL) >= 0) + while ((w = wait(&wstatus)) > 0 && w != child); + } + exit(status); +} + +int dosigwinch; + +#ifdef __ORCAC__ +#pragma databank 1 +#endif +/* + * This is called when the reader process gets the out-of-band (urgent) + * request to turn on the window-changing protocol. + */ +void +writeroob(int signo, int code) +{ + if (dosigwinch == 0) { + sendwindow(); + (void)signal(SIGWINCH, sigwinch); + } + dosigwinch = 1; +} + +void +catch_child(int signo, int code) +{ +union wait status; +int pid; + + for (;;) { +#ifdef __GNO__ + pid = wait(&status); +#else + pid = wait3((int *)&status, WNOHANG|WUNTRACED, NULL); +#endif + if (pid == 0) + return; + /* if the child (reader) dies, just quit */ + if (pid < 0 || (pid == child && !WIFSTOPPED(status))) + done((int)(status.w_termsig | status.w_retcode)); + } + /* NOTREACHED */ +} +#ifdef __ORCAC__ +#pragma databank 0 +#endif + +/* + * writer: write to remote: 0 -> line. + * ~. terminate + * ~^Z suspend rlogin process. + * ~ suspend rlogin process, but leave reader alone. + */ +void +writer(void) +{ +register int bol, local, n; +char c; + + bol = 1; /* beginning of line */ + local = 0; + for (;;) { + n = read(STDIN_FILENO, &c, 1); + if (n <= 0) { + if (n < 0 && errno == EINTR) + continue; + break; + } + /* + * If we're at the beginning of the line and recognize a + * command character, then we echo locally. Otherwise, + * characters are echo'd remotely. If the command character + * is doubled, this acts as a force and local echo is + * suppressed. + */ + if (bol) { + bol = 0; + if (!noescape && c == escapechar) { + local = 1; + continue; + } + } else if (local) { + local = 0; + if (c == '.' || c == deftc.t_eofc) { + echo(c); + break; + } + if (c == defltc.t_suspc || c == defltc.t_dsuspc) { + bol = 1; + echo(c); + stop(c); + continue; + } + if (c != escapechar) +#ifdef CRYPT +#ifdef KERBEROS + if (doencrypt) + (void)des_write(rem, + (char *)&escapechar, 1); + else +#endif +#endif + (void)write(rem, &escapechar, 1); + } + +#ifdef CRYPT +#ifdef KERBEROS + if (doencrypt) { + if (des_write(rem, &c, 1) == 0) { + msg("line gone"); + break; + } + } else +#endif +#endif + if (write(rem, &c, 1) == 0) { + msg("line gone"); + break; + } + bol = c == defkill || c == deftc.t_eofc || + c == deftc.t_intrc || c == defltc.t_suspc || + c == '\r' || c == '\n'; + } +} + +void +#if __STDC__ +echo(register char c) +#else +echo(c) + register char c; +#endif +{ +register char *p; +char buf[8]; + + p = buf; + c &= 0177; + *p++ = escapechar; + if (c < ' ') { + *p++ = '^'; + *p++ = c + '@'; + } else if (c == 0177) { + *p++ = '^'; + *p++ = '?'; + } else + *p++ = c; + *p++ = '\r'; + *p++ = '\n'; + (void)write(STDOUT_FILENO, buf, p - buf); +} + +void +#if __STDC__ +stop(char cmdc) +#else +stop(cmdc) + char cmdc; +#endif +{ + mode(0); + (void)signal(SIGCHLD, SIG_IGN); + (void)kill(cmdc == defltc.t_suspc ? 0 : getpid(), SIGTSTP); + (void)signal(SIGCHLD, catch_child); + mode(1); + sigwinch(0, 0); /* check for size changes */ +} + +#ifdef __ORCAC__ +#pragma databank 1 +#endif +void +sigwinch(int signo, int code) +{ +static struct winsize ws; + +#ifdef __GNO__ +#define bcmp(__a, __b, __l) memcmp(__a, __b, __l) +#endif + if (dosigwinch && get_window_size(STDIN_FILENO, &ws) == 0 && + bcmp(&ws, &winsize, sizeof(ws))) { + winsize = ws; + sendwindow(); + } +} +#ifdef __ORCAC__ +#pragma databank 0 +#endif + +/* + * Send the window size to the server via the magic escape + */ +void +sendwindow(void) +{ +struct winsize *wp; +char obuf[4 + sizeof (struct winsize)]; + + wp = (struct winsize *)(obuf+4); + obuf[0] = 0377; + obuf[1] = 0377; + obuf[2] = 's'; + obuf[3] = 's'; + wp->ws_row = htons(winsize.ws_row); + wp->ws_col = htons(winsize.ws_col); + wp->ws_xpixel = htons(winsize.ws_xpixel); + wp->ws_ypixel = htons(winsize.ws_ypixel); + +#ifdef CRYPT +#ifdef KERBEROS + if(doencrypt) + (void)des_write(rem, obuf, sizeof(obuf)); + else +#endif +#endif + (void)write(rem, obuf, sizeof(obuf)); +} + +/* + * reader: read from remote: line -> 1 + */ +#define READING 1 +#define WRITING 2 + +jmp_buf rcvtop; +int ppid, rcvcnt, rcvstate; +char rcvbuf[8 * 1024]; + +#ifdef __ORCAC__ +#pragma databank 1 +#endif +void +oob(int signo, int code) +{ +static struct sgttyb sb; +int atmark, n, out, rcvd; +static char waste[BUFSIZ]; +char mark; + + out = O_RDWR; + rcvd = 0; + while (recv(rem, &mark, 1, MSG_OOB) < 0) { + switch (errno) { + case EWOULDBLOCK: + /* + * Urgent data not here yet. It may not be possible + * to send it yet if we are blocked for output and + * our input buffer is full. + */ + if (rcvcnt < sizeof(rcvbuf)) { + n = read(rem, rcvbuf + rcvcnt, + sizeof(rcvbuf) - rcvcnt); + if (n <= 0) + return; + rcvd += n; + } else { + n = read(rem, waste, sizeof(waste)); + if (n <= 0) + return; + } + continue; + default: + return; + } + } + if (mark & TIOCPKT_WINDOW) { + /* Let server know about window size changes */ + (void)kill(ppid, SIGUSR1); + } + if (!eight && (mark & TIOCPKT_NOSTOP)) { + (void)ioctl(STDIN_FILENO, TIOCGETP, (char *)&sb); + sb.sg_flags &= ~CBREAK; + sb.sg_flags |= RAW; + (void)ioctl(STDIN_FILENO, TIOCSETN, (char *)&sb); + notc.t_stopc = -1; + notc.t_startc = -1; + (void)ioctl(STDIN_FILENO, TIOCSETC, (char *)¬c); + } + if (!eight && (mark & TIOCPKT_DOSTOP)) { + (void)ioctl(STDIN_FILENO, TIOCGETP, (char *)&sb); + sb.sg_flags &= ~RAW; + sb.sg_flags |= CBREAK; + (void)ioctl(STDIN_FILENO, TIOCSETN, (char *)&sb); + notc.t_stopc = deftc.t_stopc; + notc.t_startc = deftc.t_startc; + (void)ioctl(STDIN_FILENO, TIOCSETC, (char *)¬c); + } + if (mark & TIOCPKT_FLUSHWRITE) { + (void)ioctl(STDOUT_FILENO, TIOCFLUSH, (char *)&out); + for (;;) { + if (ioctl(rem, SIOCATMARK, &atmark) < 0) { + (void)fprintf(stderr, "rlogin: ioctl: %s.\n", + strerror(errno)); + break; + } + if (atmark) + break; + n = read(rem, waste, sizeof (waste)); + if (n <= 0) + break; + } + /* + * Don't want any pending data to be output, so clear the recv + * buffer. If we were hanging on a write when interrupted, + * don't want it to restart. If we were reading, restart + * anyway. + */ + rcvcnt = 0; + longjmp(rcvtop, 1); + } + + /* oob does not do FLUSHREAD (alas!) */ + + /* + * If we filled the receive buffer while a read was pending, longjmp + * to the top to restart appropriately. Don't abort a pending write, + * however, or we won't know how much was written. + */ + if (rcvd && rcvstate == READING) + longjmp(rcvtop, 1); +} +#ifdef __ORCAC__ +#pragma databank 0 +#endif + +/* reader: read from remote: line -> 1 */ +int +reader(long omask) +{ +int pid, n, remaining; +char *bufp; + +#if BSD >= 43 || defined(SUNOS4) + pid = getpid(); /* modern systems use positives for pid */ +#else + pid = -getpid(); /* old broken systems use negatives */ +#endif + (void)signal(SIGTTOU, SIG_IGN); + (void)signal(SIGURG, oob); + ppid = getppid(); +#ifndef __GNO__ + (void)fcntl(rem, F_SETOWN, pid); +#endif + (void)setjmp(rcvtop); + (void)sigsetmask(omask); + bufp = rcvbuf; + for (;;) { + while ((remaining = rcvcnt - (bufp - rcvbuf)) > 0) { + rcvstate = WRITING; + n = write(STDOUT_FILENO, bufp, remaining); + if (n < 0) { + if (errno != EINTR) + return (-1); + continue; + } + bufp += n; + } + bufp = rcvbuf; + rcvcnt = 0; + rcvstate = READING; + +#ifdef CRYPT +#ifdef KERBEROS + if (doencrypt) + rcvcnt = des_read(rem, rcvbuf, sizeof(rcvbuf)); + else +#endif +#endif + rcvcnt = read(rem, rcvbuf, sizeof (rcvbuf)); + if (rcvcnt == 0) + return (0); + if (rcvcnt < 0) { + if (errno == EINTR) + continue; + (void)fprintf(stderr, "rlogin: read: %s.\n", + strerror(errno)); + return (-1); + } + } +} + +void +mode(int f) +{ +struct ltchars *ltc; +static struct sgttyb sb; +struct tchars *tc; +int lflags; + + (void)ioctl(STDIN_FILENO, TIOCGETP, (char *)&sb); + (void)ioctl(STDIN_FILENO, TIOCLGET, (char *)&lflags); + switch(f) { + case 0: + sb.sg_flags &= ~(CBREAK|RAW|TBDELAY); + sb.sg_flags |= defflags|tabflag; + tc = &deftc; + ltc = &defltc; + sb.sg_kill = defkill; + sb.sg_erase = deferase; + lflags = deflflags; + break; + case 1: + sb.sg_flags |= (eight ? RAW : CBREAK); + sb.sg_flags &= ~defflags; + /* preserve tab delays, but turn off XTABS */ + if ((sb.sg_flags & TBDELAY) == XTABS) + sb.sg_flags &= ~TBDELAY; + tc = ¬c; + ltc = &noltc; + sb.sg_kill = sb.sg_erase = -1; + if (litout) + lflags |= LLITOUT; + break; + default: + return; + } + (void)ioctl(STDIN_FILENO, TIOCSLTC, (char *)ltc); + (void)ioctl(STDIN_FILENO, TIOCSETC, (char *)tc); + (void)ioctl(STDIN_FILENO, TIOCSETN, (char *)&sb); + (void)ioctl(STDIN_FILENO, TIOCLSET, (char *)&lflags); +} + +#ifdef __ORCAC__ +#pragma databank 1 +#endif +void +lostpeer(int signo, int code) +{ + (void)signal(SIGPIPE, SIG_IGN); + msg("\007connection closed."); + done(1); +} + +/* copy SIGURGs to the child process. */ +void +copytochild(int signo, int code) +{ + (void)kill(child, SIGURG); +} +#ifdef __ORCAC__ +#pragma databank 0 +#endif + +void +msg(char *str) +{ + (void)fprintf(stderr, "rlogin: %s\r\n", str); +} + +#ifdef KERBEROS +/* VARARGS */ +void +#if __STDC__ +warning(const char *fmt, ...) +#else +warning(fmt, va_alist) + char *fmt; + va_dcl +#endif +{ + va_list ap; + + (void)fprintf(stderr, "rlogin: warning, using standard rlogin: "); +#ifdef __STDC__ + va_start(ap, fmt); +#else + va_start(ap); +#endif + vfprintf(stderr, fmt, ap); + va_end(ap); + (void)fprintf(stderr, ".\n"); +} +#endif + +__dead void +usage(void) +{ + (void)fprintf(stderr, + "usage: rlogin [ -%s]%s[-e char] [ -l username ] host\n", +#ifdef KERBEROS +#ifdef CRYPT + "8DEKLx", " [-k realm] "); +#else + "8DEKL", " [-k realm] "); +#endif +#else + "8DEL", " "); +#endif + exit(1); +} + +/* + * The following routine provides compatibility (such as it is) between older + * Suns and others. Suns have only a `ttysize', so we convert it to a winsize. + */ +#ifdef OLDSUN +int +get_window_size(fd, wp) + int fd; + struct winsize *wp; +{ + struct ttysize ts; + int error; + + if ((error = ioctl(STDIN_FILENO, TIOCGSIZE, &ts)) != 0) + return (error); + wp->ws_row = ts.ts_lines; + wp->ws_col = ts.ts_cols; + wp->ws_xpixel = 0; + wp->ws_ypixel = 0; + return (0); +} +#endif + +u_int +getescape(register char *p) +{ +long val; +int len; + + if ((len = strlen(p)) == 1) /* use any single char, including '\' */ + return ((u_int)*p); + /* otherwise, \nnn */ + if (*p == '\\' && len >= 2 && len <= 4) { + val = strtol(++p, NULL, 8); + for (;;) { + if (!*++p) + return ((u_int)val); + if (*p < '0' || *p > '8') + break; + } + } + msg("illegal option value -- e"); + usage(); + /* NOTREACHED */ +} + diff --git a/usr.bin/rlogin/rlogin.desc b/usr.bin/rlogin/rlogin.desc new file mode 100644 index 0000000..0bd8768 --- /dev/null +++ b/usr.bin/rlogin/rlogin.desc @@ -0,0 +1,9 @@ +Name: rlogin +Version: 1.0 (November 1997) +Shell: GNO & GS/TCP +Author: Derek Taubert (from FreeBSD 2.1.0 code) +Contact: taubert@geeks.org +Where: /usr/bin +FTP: ground.isca.uiowa.edu apple2.caltech.edu trenco.myrias.com + + Remote login. diff --git a/usr.bin/rlogin/rlogin.rez b/usr.bin/rlogin/rlogin.rez new file mode 100644 index 0000000..3136900 --- /dev/null +++ b/usr.bin/rlogin/rlogin.rez @@ -0,0 +1,31 @@ +/* + * Resources for rlogin version and comment + * + * $Id: rlogin.rez,v 1.1 1998/01/24 08:31:02 taubert Exp $ + */ +#define PROG "rlogin" +#define DESC "Remote login." + +#include "Types.rez" + +/* + * Version + */ +resource rVersion (1, purgeable3) { + { 1, 0, 0, /* Version 1.0.0 */ + release, /* development|alpha|beta|final|release */ + 0 }, /* non-final release number */ + verUS, /* Country */ + PROG, /* Program name */ + DESC " Released with GNO/ME and GS/TCP." +}; + + +/* + * Comment + */ +resource rComment (1, purgeable3) { + PROG " v1.0 (November 1997)\n" + "GNO utility: " DESC "\n" + "Ported from FreeBSD 2.1.0 code by Derek Taubert." +};