aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorKen Raeburn <raeburn@mit.edu>2000-06-30 00:16:21 +0000
committerKen Raeburn <raeburn@mit.edu>2000-06-30 00:16:21 +0000
commit5115426fe6ca5bd63cf8e3997fbaf8277792c024 (patch)
tree65d8c302c3ba8080437850651370eadad1632e22 /src
parent8165626f1caaaa60fcfd04472a07e8362f2447b8 (diff)
downloadkrb5-5115426fe6ca5bd63cf8e3997fbaf8277792c024.zip
krb5-5115426fe6ca5bd63cf8e3997fbaf8277792c024.tar.gz
krb5-5115426fe6ca5bd63cf8e3997fbaf8277792c024.tar.bz2
1.2-beta4 pullup
git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@12470 dc483132-0cff-0310-8789-dd5450dbe970
Diffstat (limited to 'src')
-rw-r--r--src/appl/bsd/ChangeLog141
-rw-r--r--src/appl/bsd/Makefile.in1
-rw-r--r--src/appl/bsd/configure.in11
-rw-r--r--src/appl/bsd/defines.h44
-rw-r--r--src/appl/bsd/kcmd.c197
-rw-r--r--src/appl/bsd/krcp.c131
-rw-r--r--src/appl/bsd/krlogin.c61
-rw-r--r--src/appl/bsd/krlogind.c81
-rw-r--r--src/appl/bsd/krsh.c57
-rw-r--r--src/appl/bsd/krshd.c71
-rw-r--r--src/appl/bsd/login.c83
-rw-r--r--src/appl/bsd/v4rcp.c24
-rw-r--r--src/appl/gssftp/ChangeLog5
-rw-r--r--src/appl/gssftp/configure.in2
-rw-r--r--src/appl/gssftp/ftp/ChangeLog17
-rw-r--r--src/appl/gssftp/ftp/cmds.c13
-rw-r--r--src/appl/gssftp/ftp/domacro.c18
-rw-r--r--src/appl/gssftp/ftp/ftp.c46
-rw-r--r--src/appl/gssftp/ftp/glob.c12
-rw-r--r--src/appl/gssftp/ftp/main.c3
-rw-r--r--src/appl/gssftp/ftp/secure.c5
-rw-r--r--src/appl/gssftp/ftpd/ChangeLog8
-rw-r--r--src/appl/gssftp/ftpd/ftpcmd.y2
-rw-r--r--src/appl/gssftp/ftpd/ftpd.c6
-rw-r--r--src/appl/telnet/libtelnet/ChangeLog19
-rw-r--r--src/appl/telnet/libtelnet/gettytab.c5
-rw-r--r--src/appl/telnet/libtelnet/kerberos.c4
-rw-r--r--src/appl/telnet/libtelnet/kerberos5.c33
-rw-r--r--src/appl/telnet/libtelnet/spx.c20
-rw-r--r--src/appl/telnet/telnet/ChangeLog15
-rw-r--r--src/appl/telnet/telnet/commands.c15
-rw-r--r--src/appl/telnet/telnet/externs.h2
-rw-r--r--src/appl/telnet/telnet/main.c3
-rw-r--r--src/appl/telnet/telnet/tn3270.c7
-rw-r--r--src/appl/telnet/telnet/utilities.c6
-rw-r--r--src/appl/telnet/telnetd/ChangeLog13
-rw-r--r--src/appl/telnet/telnetd/sys_term.c1
-rw-r--r--src/appl/telnet/telnetd/telnetd-ktd.c53
-rw-r--r--src/appl/telnet/telnetd/telnetd.c57
39 files changed, 971 insertions, 321 deletions
diff --git a/src/appl/bsd/ChangeLog b/src/appl/bsd/ChangeLog
index 9c87d98..0eac15d 100644
--- a/src/appl/bsd/ChangeLog
+++ b/src/appl/bsd/ChangeLog
@@ -1,3 +1,144 @@
+2000-06-19 Tom Yu <tlyu@mit.edu>
+
+ * krshd.c (recvauth): Call krb5_recvauth_version() rather than
+ calling krb5_recvauth() with arguments intended for
+ krb5_recvauth_version().
+
+ * kcmd.c: Conditionalize krb_sendauth prototype based on sense of
+ KRB5_KRB4_COMPAT.
+
+2000-06-15 Tom Yu <tlyu@mit.edu>
+
+ * login.c (try_convert524): Add use_ccache argument. Handle case
+ where we have gotten v5 creds via password being entered and don't
+ crash in that case, since previous code was assuming that v5 creds
+ were always being provided. Adapted from patch by Bob Basch.
+
+2000-06-10 Ken Raeburn <raeburn@mit.edu>
+
+ * krcp.c (main): Fix logic again, this time in the "success"
+ case. If there's a problem retrieving the new-protocol subkey,
+ print a message and exit, don't fall back.
+ * krsh.c (main): Ditto; don't look at enctype to try to guess
+ protocol version. Delete unused variable "similar".
+
+2000-06-09 Ken Raeburn <raeburn@mit.edu>
+
+ * krlogin.c (main): Rework fallback logic. Fall back to k4cmd
+ unless encryption and the new protocol were both requested.
+
+ * krsh.c (main): Rework fallback logic. Fall back to k4cmd if new
+ protocol wasn't requested.
+
+ * krcp.c (main): Revert setting of AP_OPTS_MUTUAL_REQUIRED
+ unconditionally, which was added by mistake with last set of
+ patches. If kcmd fails and the new protocol is requested, don't
+ fall back to v4.
+
+2000-05-31 Ken Raeburn <raeburn@mit.edu>
+
+ * Makefile.in (kcmd.o, krcp.o, krlogin.o, krlogind.o, krsh.o,
+ krshd.o): Depend on defines.h.
+ * krlogind.c: Include defines.h.
+ * krcp.c: Ditto.
+
+ * defines.h (enum kcmd_proto): New type.
+ (rcmd_stream_read, rcmd_stream_write, getport,
+ rcmd_stream_init_krb5): Add prototypes.
+
+ * kcmd.c (use_ivecs): New variable.
+ (encivec_i, encivec_o): Each is now an array of two elements.
+ (input, output, twrite, krb5_write_message, krb5_net_read,
+ krb5_net_write, krb_sendauth): Add prototypes.
+ (kcmd): New argument PROTONUMP points to enum kcmd_proto. If
+ value is KCMD_PROTOCOL_COMPAT_HACK, set it to KCMD_NEW_PROTOCOL or
+ KCMD_OLD_PROTOCOL depending on session key type. Use subkeys for
+ new protocol. Callers updated.
+ (normal_read, v5_des_read, v4_des_read, twrite, v5_des_write,
+ v4_des_write, rcmd_stream_write, rcmd_stream_read): Take
+ additional argument indicating whether the fd is for the secondary
+ channel; ignored except in some v5 cases. Callers updated.
+ (rcmd_stream_init_krb5): New argument, kcmd protocol version. Set
+ up ivecs for secondary channel in each direction with values 0x2
+ ior primary channel value. Callers updated.
+ (v5_des_read, v5_des_write): For new protocol, plaintext now has
+ its length prepended but not counted.
+
+ * krcp.c (main): Set kcmd protocol version based on command line,
+ not on encryption type. Default to COMPAT_HACK.
+ * krsh.c (main): Ditto.
+ * krlogin.c (main): Ditto.
+
+ * krlogind.c (recvauth): Use new krb5_compat_recvauth_version
+ routine. Determine client's kcmd protocol version and initialize
+ based on it.
+ * krshd.c (recvauth): Ditto.
+
+2000-05-19 Nalin Dahyabhai <nalin@redhat.com>
+ Ken Raeburn <raeburn@mit.edu>
+
+ * krcp.c (sink): bail if the target directory/file name is too long
+ * krlogind.c (recvauth, krb4 compat): truncate user name if the
+ principal's root would be too long to be valid
+ * v4rcp.c (sink): bail if the target directory/file name is too long
+
+2000-05-18 Tom Yu <tlyu@mit.edu>
+
+ * krshd.c: Shuffle inclusion of defines.h so that some krb5
+ structures are declared prior to the kcmd() prototype.
+
+2000-05-16 Ken Raeburn <raeburn@mit.edu>
+
+ * defines.h (kcmd): Add prototype.
+ * krcp.c (main): Add extra arg to a kcmd call I missed yesterday.
+
+2000-05-15 Ken Raeburn <raeburn@mit.edu>
+
+ * krcp.c (main): Fix some conditionalizations to make proper
+ indentation easier.
+
+ * kcmd.c (encivec_i, encivec_o): New variables replace old single
+ variable encivec.
+ (rcmd_stream_init_krb5): New argument am_client, used to
+ initialize both ivec values.
+ * krcp.c (main, answer_auth): Pass new argument.
+ * krlogin.c (main): Ditto.
+ * krlogind.c (recvauth): Ditto.
+ * krsh.c (main): Ditto.
+ * krshd.c (recvauth): Ditto.
+
+ * defines.h (OPTS_FORWARD_CREDS, OPTS_FORWARDABLE_CREDS): Change
+ numbers so they don't conflict with AP_OPTS_USE_SUBKEY.
+ * kcmd.c (kcmd): New argument authconp, used to return the auth
+ context to the caller if desired.
+ * krlogin.c (auth_context): New variable.
+ (main): Request a subkey from sendauth. Get the auth context from
+ kcmd so we can retrieve the subkey. If non-DES session key is
+ being used, pass the subkey to rcmd_stream_init_krb5 instead of
+ the session key; fail if no subkey is found and encryption is
+ required.
+ * krlogind.c (recvauth): If a non-DES session key is being used,
+ pass the client-provided subkey to rcmd_stream_init_krb5.
+ * krcp.c (main): Set up and use subkey as above.
+ * krsh.c (main): Set up and use subkey as above.
+ * krshd.c (recvauth): Accept and use subkey as above.
+
+2000-05-08 Ken Raeburn <raeburn@mit.edu>
+
+ * v4rcp.c (main, case 'k'): Make sure krb_realm is
+ null-terminated.
+
+2000-04-27 Nalin Dahyabhai <nalin@redhat.com>
+
+ * krlogin.c (main): Don't overflow buffer "term".
+ * krshd.c (doit): Don't overflow buffer "cmdbuf".
+ * login.c (afs_login): Don't overflow buffer "aklog_path".
+
+2000-03-24 Ken Raeburn <raeburn@mit.edu>
+
+ * configure.in: Check for alpha*-dec-osf* instead of
+ alpha-dec-osf*.
+
2000-03-15 Ken Raeburn <raeburn@mit.edu>
Mark D. Roth <roth@uiuc.edu>
diff --git a/src/appl/bsd/Makefile.in b/src/appl/bsd/Makefile.in
index eee13ca..93a6cba 100644
--- a/src/appl/bsd/Makefile.in
+++ b/src/appl/bsd/Makefile.in
@@ -90,3 +90,4 @@ install::
getdtablesize.o: $(srcdir)/getdtablesize.c
+kcmd.o krcp.o krlogin.o krlogind.o krsh.o krshd.o : defines.h
diff --git a/src/appl/bsd/configure.in b/src/appl/bsd/configure.in
index 6d31f48..cf65476 100644
--- a/src/appl/bsd/configure.in
+++ b/src/appl/bsd/configure.in
@@ -25,11 +25,12 @@ dnl Make our operating system-specific security checks and definitions for
dnl login.
dnl
case $krb5_cv_host in
-*-*-aix3*) # AIX has streams include files but not streams TTY
-# Moreover, strops.h trashes sys/ioctl.h
-krb5_cv_has_streams=no
-;;
-alpha-dec-osf*)
+*-*-aix3*)
+ # AIX has streams include files but not streams TTY
+ # Moreover, strops.h trashes sys/ioctl.h
+ krb5_cv_has_streams=no
+ ;;
+alpha*-dec-osf*)
AC_CHECK_LIB(security,setluid,
AC_DEFINE(HAVE_SETLUID)
LOGINLIBS="$LOGINLIBS -lsecurity"
diff --git a/src/appl/bsd/defines.h b/src/appl/bsd/defines.h
index fd9c3e1..6365d2c 100644
--- a/src/appl/bsd/defines.h
+++ b/src/appl/bsd/defines.h
@@ -1,3 +1,43 @@
-#define OPTS_FORWARD_CREDS 0x00000002
-#define OPTS_FORWARDABLE_CREDS 0x00000001
+#define OPTS_FORWARD_CREDS 0x00000020
+#define OPTS_FORWARDABLE_CREDS 0x00000010
#define RCMD_BUFSIZ 5120
+
+enum kcmd_proto {
+ /* Old protocol: DES encryption only. No subkeys. No protection
+ for cleartext length. No ivec supplied. OOB hacks used for
+ rlogin. Checksum may be omitted at connection startup. */
+ KCMD_OLD_PROTOCOL = 1,
+ /* New protocol: Any encryption scheme. Client-generated subkey
+ required. Prepend cleartext-length to cleartext data (but don't
+ include it in count). Starting ivec defined, chained. In-band
+ signalling. Checksum required. */
+ KCMD_NEW_PROTOCOL,
+ /* Hack: Get credentials, and use the old protocol iff the session
+ key type is single-DES. */
+ KCMD_PROTOCOL_COMPAT_HACK,
+ /* Using Kerberos version 4. */
+ KCMD_V4_PROTOCOL,
+ /* ??? */
+ KCMD_UNKNOWN_PROTOCOL
+};
+
+extern int kcmd (int *sock, char **ahost, int /* u_short */ rport,
+ char *locuser, char *remuser, char *cmd,
+ int *fd2p, char *service, char *realm,
+ krb5_creds **cred,
+ krb5_int32 *seqno, krb5_int32 *server_seqno,
+ struct sockaddr_in *laddr,
+ struct sockaddr_in *faddr,
+ krb5_auth_context *authconp,
+ krb5_flags authopts,
+ int anyport, int suppress_err,
+ enum kcmd_proto *protonum /* input and output */
+ );
+
+extern int rcmd_stream_read (int fd, char *buf, int len, int secondary);
+extern int rcmd_stream_write (int fd, char *buf, int len, int secondary);
+extern int getport (int *);
+
+extern void rcmd_stream_init_krb5 (krb5_keyblock *in_keyblock,
+ int encrypt_flag, int lencheck,
+ int am_client, enum kcmd_proto protonum);
diff --git a/src/appl/bsd/kcmd.c b/src/appl/bsd/kcmd.c
index 0e68f88..3e401cc 100644
--- a/src/appl/bsd/kcmd.c
+++ b/src/appl/bsd/kcmd.c
@@ -117,14 +117,18 @@ static char des_inbuf[2*RCMD_BUFSIZ]; /* needs to be > largest read size */
static char des_outpkt[2*RCMD_BUFSIZ+4]; /* needs to be > largest write size */
static krb5_data desinbuf;
static krb5_data desoutbuf;
-static krb5_data encivec;
+
+/* XXX Overloaded: use_ivecs!=0 -> new protocol, inband signalling, etc. */
+static int use_ivecs;
+static krb5_data encivec_i[2], encivec_o[2];
+
static krb5_keyblock *keyblock; /* key for encrypt/decrypt */
-static int (*input)();
-static int (*output)();
+static int (*input)(int, char *, int, int);
+static int (*output)(int, char *, int, int);
static char storage[2*RCMD_BUFSIZ]; /* storage for the decryption */
static int nstored = 0;
static char *store_ptr = storage;
-static int twrite();
+static int twrite(int, char *, int, int);
static int v5_des_read(), v5_des_write();
#ifdef KRB5_KRB4_COMPAT
static int v4_des_read(), v4_des_write();
@@ -133,8 +137,29 @@ static int right_justify;
#endif
static int do_lencheck;
+/* XXX: These should be internal to krb5 library, or declared in krb5.h. */
+extern krb5_error_code krb5_write_message (krb5_context, krb5_pointer,
+ krb5_data *);
+extern int krb5_net_read (krb5_context, int , char *, int);
+extern int krb5_net_write (krb5_context, int , const char *, int);
+/* XXX: And these should be declared in krb.h, or private. */
+#ifdef KRB5_KRB4_COMPAT
+extern int
+krb_sendauth(long options, int fd, KTEXT ticket,
+ char *service, char *inst, char *realm,
+ unsigned KRB4_32 checksum,
+ MSG_DAT *msg_data,
+ CREDENTIALS *cred,
+ Key_schedule schedule,
+ struct sockaddr_in *laddr,
+ struct sockaddr_in *faddr,
+ char *version);
+#endif
+
+int
kcmd(sock, ahost, rport, locuser, remuser, cmd, fd2p, service, realm,
- cred, seqno, server_seqno, laddr, faddr, authopts, anyport, suppress_err)
+ cred, seqno, server_seqno, laddr, faddr, authconp, authopts, anyport,
+ suppress_err, protonump)
int *sock;
char **ahost;
u_short rport;
@@ -142,15 +167,17 @@ kcmd(sock, ahost, rport, locuser, remuser, cmd, fd2p, service, realm,
int *fd2p;
char *service;
char *realm;
- krb5_creds **cred;
+ krb5_creds **cred; /* output only */
krb5_int32 *seqno;
krb5_int32 *server_seqno;
struct sockaddr_in *laddr, *faddr;
+ krb5_auth_context *authconp;
krb5_flags authopts;
int anyport;
int suppress_err; /* Don't print if authentication fails */
+ enum kcmd_proto *protonump;
{
- int i, s, timo = 1, pid;
+ int s, pid;
#ifdef POSIX_SIGNALS
sigset_t oldmask, urgmask;
#else
@@ -164,7 +191,6 @@ kcmd(sock, ahost, rport, locuser, remuser, cmd, fd2p, service, realm,
int rc;
char *host_save;
krb5_error_code status;
- krb5_error *err_ret;
krb5_ap_rep_enc_part *rep_ret;
krb5_error *error = 0;
int sin_len;
@@ -174,6 +200,8 @@ kcmd(sock, ahost, rport, locuser, remuser, cmd, fd2p, service, realm,
krb5_auth_context auth_context = NULL;
char *cksumbuf;
krb5_data cksumdat;
+ char *kcmd_version;
+ enum kcmd_proto protonum = *protonump;
if ((cksumbuf = malloc(strlen(cmd)+strlen(remuser)+64)) == 0 ) {
fprintf(stderr, "Unable to allocate memory for checksum buffer.\n");
@@ -361,12 +389,35 @@ kcmd(sock, ahost, rport, locuser, remuser, cmd, fd2p, service, realm,
KRB5_AUTH_CONTEXT_GENERATE_LOCAL_FULL_ADDR))
goto bad2;
- /* call Kerberos library routine to obtain an authenticator,
+ if (protonum == KCMD_PROTOCOL_COMPAT_HACK) {
+ krb5_boolean is_des;
+ status = krb5_c_enctype_compare (bsd_context, ENCTYPE_DES_CBC_CRC,
+ ret_cred->keyblock.enctype, &is_des);
+ if (status)
+ goto bad2;
+ protonum = is_des ? KCMD_OLD_PROTOCOL : KCMD_NEW_PROTOCOL;
+ }
+
+ switch (protonum) {
+ case KCMD_NEW_PROTOCOL:
+ authopts |= AP_OPTS_USE_SUBKEY;
+ kcmd_version = "KCMDV0.2";
+ break;
+ case KCMD_OLD_PROTOCOL:
+ kcmd_version = "KCMDV0.1";
+ break;
+ default:
+ status = EINVAL;
+ goto bad2;
+ }
+
+ /* Call Kerberos library routine to obtain an authenticator,
pass it over the socket to the server, and obtain mutual
- authentication. */
+ authentication. */
status = krb5_sendauth(bsd_context, &auth_context, (krb5_pointer) &s,
- "KCMDV0.1", ret_cred->client, ret_cred->server,
- authopts, &cksumdat, ret_cred, 0, &error, &rep_ret, NULL);
+ kcmd_version, ret_cred->client, ret_cred->server,
+ authopts, &cksumdat, ret_cred, 0,
+ &error, &rep_ret, NULL);
free(cksumbuf);
if (status) {
if (!suppress_err)
@@ -440,10 +491,13 @@ kcmd(sock, ahost, rport, locuser, remuser, cmd, fd2p, service, realm,
sigsetmask(oldmask);
#endif /* POSIX_SIGNALS */
*sock = s;
+ *protonump = protonum;
/* pass back credentials if wanted */
if (cred) krb5_copy_creds(bsd_context, ret_cred, cred);
krb5_free_creds(bsd_context, ret_cred);
+ if (authconp)
+ *authconp = auth_context;
return (0);
bad2:
@@ -464,6 +518,7 @@ kcmd(sock, ahost, rport, locuser, remuser, cmd, fd2p, service, realm,
#ifdef KRB5_KRB4_COMPAT
+int
k4cmd(sock, ahost, rport, locuser, remuser, cmd, fd2p, ticket, service, realm,
cred, schedule, msg_data, laddr, faddr, authopts, anyport)
int *sock;
@@ -701,7 +756,7 @@ reread:
#endif /* KRB5_KRB4_COMPAT */
-
+int
getport(alport)
int *alport;
{
@@ -733,16 +788,25 @@ getport(alport)
return -1;
}
+static int
+normal_read (int fd, char *buf, int len, int secondary)
+{
+ return read (fd, buf, len);
+}
+
void rcmd_stream_init_normal()
{
- input = read;
+ input = normal_read;
output = twrite;
}
-void rcmd_stream_init_krb5(in_keyblock, encrypt_flag, lencheck)
+void rcmd_stream_init_krb5(in_keyblock, encrypt_flag, lencheck, am_client,
+ protonum)
krb5_keyblock *in_keyblock;
int encrypt_flag;
int lencheck;
+ int am_client;
+ enum kcmd_proto protonum;
{
krb5_error_code status;
size_t blocksize;
@@ -760,33 +824,35 @@ void rcmd_stream_init_krb5(in_keyblock, encrypt_flag, lencheck)
input = v5_des_read;
output = v5_des_write;
- if (status = krb5_c_enctype_compare(bsd_context, ENCTYPE_DES_CBC_CRC,
- keyblock->enctype,
- &similar)) {
- /* XXX what do I do? */
- abort();
- }
-
- if (similar) {
- encivec.length = 0;
+ if (protonum == KCMD_OLD_PROTOCOL) {
+ use_ivecs = 0;
return;
}
+ use_ivecs = 1;
+
if (status = krb5_c_block_size(bsd_context, keyblock->enctype,
&blocksize)) {
/* XXX what do I do? */
abort();
}
- encivec.length = blocksize;
+ encivec_i[0].length = encivec_i[1].length = encivec_o[0].length
+ = encivec_o[1].length = blocksize;
- if ((encivec.data = malloc(encivec.length)) == NULL) {
+ if ((encivec_i[0].data = malloc(encivec_i[0].length * 4)) == NULL) {
/* XXX what do I do? */
abort();
}
+ encivec_i[1].data = encivec_i[0].data + encivec_i[0].length;
+ encivec_o[0].data = encivec_i[1].data + encivec_i[0].length;
+ encivec_o[1].data = encivec_o[0].data + encivec_i[0].length;
/* is there a better way to initialize this? */
- memset(encivec.data, '\0', blocksize);
+ memset(encivec_i[0].data, am_client, blocksize);
+ memset(encivec_o[0].data, 1 - am_client, blocksize);
+ memset(encivec_i[1].data, 2 | am_client, blocksize);
+ memset(encivec_o[1].data, 2 | (1 - am_client), blocksize);
}
#ifdef KRB5_KRB4_COMPAT
@@ -808,35 +874,39 @@ void rcmd_stream_init_krb4(session, encrypt_flag, lencheck, justify)
}
#endif
-int rcmd_stream_read(fd, buf, len)
+int rcmd_stream_read(fd, buf, len, sec)
int fd;
register char *buf;
int len;
+ int sec;
{
- return (*input)(fd, buf, len);
+ return (*input)(fd, buf, len, sec);
}
-int rcmd_stream_write(fd, buf, len)
+int rcmd_stream_write(fd, buf, len, sec)
int fd;
register char *buf;
int len;
+ int sec;
{
- return (*output)(fd, buf, len);
+ return (*output)(fd, buf, len, sec);
}
/* Because of rcp lossage, translate fd 0 to 1 when writing. */
-static int twrite(fd, buf, len)
+static int twrite(fd, buf, len, secondary)
int fd;
char *buf;
int len;
+ int secondary;
{
return write((fd == 0) ? 1 : fd, buf, len);
}
-static int v5_des_read(fd, buf, len)
+static int v5_des_read(fd, buf, len, secondary)
int fd;
char *buf;
int len;
+ int secondary;
{
int nreturned = 0;
size_t net_len,rd_len;
@@ -879,7 +949,8 @@ static int v5_des_read(fd, buf, len)
rd_len = (rd_len << 8) | c;
if (ret = krb5_c_encrypt_length(bsd_context, keyblock->enctype,
- rd_len, &net_len)) {
+ use_ivecs ? rd_len + 4 : rd_len,
+ &net_len)) {
errno = ret;
return(-1);
}
@@ -902,8 +973,8 @@ static int v5_des_read(fd, buf, len)
plain.data = storage;
/* decrypt info */
- if (krb5_c_decrypt(bsd_context, keyblock, KCMD_KEYUSAGE,
- encivec.length?&encivec:0,
+ if (ret = krb5_c_decrypt(bsd_context, keyblock, KCMD_KEYUSAGE,
+ use_ivecs ? encivec_i + secondary : 0,
&cipher, &plain)) {
/* probably out of sync */
errno = EIO;
@@ -911,6 +982,19 @@ static int v5_des_read(fd, buf, len)
}
store_ptr = storage;
nstored = rd_len;
+ if (use_ivecs) {
+ int rd_len2;
+ rd_len2 = storage[0] & 0xff;
+ rd_len2 <<= 8; rd_len2 |= storage[1] & 0xff;
+ rd_len2 <<= 8; rd_len2 |= storage[2] & 0xff;
+ rd_len2 <<= 8; rd_len2 |= storage[3] & 0xff;
+ if (rd_len2 != rd_len) {
+ /* cleartext length trashed? */
+ errno = EIO;
+ return -1;
+ }
+ store_ptr += 4;
+ }
if (nstored > len) {
memcpy(buf, store_ptr, len);
nreturned += len;
@@ -927,23 +1011,39 @@ static int v5_des_read(fd, buf, len)
-static int v5_des_write(fd, buf, len)
+static int v5_des_write(fd, buf, len, secondary)
int fd;
char *buf;
int len;
+ int secondary;
{
- unsigned char *len_buf = (unsigned char *) des_outpkt;
krb5_data plain;
krb5_enc_data cipher;
-
- plain.data = buf;
- plain.length = len;
+ char tmpbuf[2*RCMD_BUFSIZ+8];
+ unsigned char *len_buf = (unsigned char *) tmpbuf;
+
+ if (use_ivecs) {
+ unsigned char *lenbuf2 = (unsigned char *) tmpbuf;
+ if (len + 4 > sizeof(tmpbuf))
+ abort ();
+ lenbuf2[0] = (len & 0xff000000) >> 24;
+ lenbuf2[1] = (len & 0xff0000) >> 16;
+ lenbuf2[2] = (len & 0xff00) >> 8;
+ lenbuf2[3] = (len & 0xff);
+ memcpy (tmpbuf + 4, buf, len);
+
+ plain.data = tmpbuf;
+ plain.length = len + 4;
+ } else {
+ plain.data = buf;
+ plain.length = len;
+ }
cipher.ciphertext.length = sizeof(des_outpkt)-4;
cipher.ciphertext.data = desoutbuf.data;
if (krb5_c_encrypt(bsd_context, keyblock, KCMD_KEYUSAGE,
- encivec.length?&encivec:0,
+ use_ivecs ? encivec_o + secondary : 0,
&plain, &cipher)) {
errno = EIO;
return(-1);
@@ -951,6 +1051,7 @@ static int v5_des_write(fd, buf, len)
desoutbuf.length = cipher.ciphertext.length;
+ len_buf = (unsigned char *) des_outpkt;
len_buf[0] = (len & 0xff000000) >> 24;
len_buf[1] = (len & 0xff0000) >> 16;
len_buf[2] = (len & 0xff00) >> 8;
@@ -1032,11 +1133,11 @@ int len;
errno = EIO;
return(-1);
}
- (void) pcbc_encrypt(des_inbuf,
- storage,
+ (void) pcbc_encrypt((des_cblock *) des_inbuf,
+ (des_cblock *) storage,
(net_len < 8) ? 8 : net_len,
v4_schedule,
- v4_session,
+ &v4_session,
DECRYPT);
/*
* when the cleartext block is < 8 bytes, it is "right-justified"
@@ -1092,11 +1193,11 @@ int len;
/* this "right-justifies" the data in the buffer */
(void) memcpy(garbage_buf + 8 - len, buf, len);
}
- (void) pcbc_encrypt((len < 8) ? garbage_buf : buf,
- des_outpkt+4,
+ (void) pcbc_encrypt((des_cblock *) ((len < 8) ? garbage_buf : buf),
+ (des_cblock *) (des_outpkt+4),
(len < 8) ? 8 : len,
v4_schedule,
- v4_session,
+ &v4_session,
ENCRYPT);
/* tell the other end the real amount, but send an 8-byte padded
diff --git a/src/appl/bsd/krcp.c b/src/appl/bsd/krcp.c
index 9670145..7292e72 100644
--- a/src/appl/bsd/krcp.c
+++ b/src/appl/bsd/krcp.c
@@ -71,6 +71,8 @@ char copyright[] =
#include <k5-util.h>
#include <com_err.h>
+#include "defines.h"
+
#define RCP_BUFSIZ 4096
int sock;
@@ -131,7 +133,7 @@ void error KRB5_STDARG_P((char *fmt, ...));
void error KRB5_STDARG_P((char *, va_list));
#endif
-#define ga() (void) rcmd_stream_write(rem, "", 1)
+#define ga() (void) rcmd_stream_write(rem, "", 1, 0)
int main(argc, argv)
int argc;
@@ -153,6 +155,8 @@ int main(argc, argv)
krb5_error_code status;
int euid;
char **orig_argv = save_argv(argc, argv);
+ krb5_auth_context auth_context;
+ enum kcmd_proto kcmd_proto = KCMD_PROTOCOL_COMPAT_HACK;
status = krb5_init_context(&bsd_context);
if (status) {
@@ -224,6 +228,14 @@ int main(argc, argv)
}
strcpy(krb_config, *argv);
goto next_arg;
+ case 'P':
+ if (!strcmp (*argv, "O"))
+ kcmd_proto = KCMD_OLD_PROTOCOL;
+ else if (!strcmp (*argv, "N"))
+ kcmd_proto = KCMD_NEW_PROTOCOL;
+ else
+ usage ();
+ goto next_arg;
#endif /* KERBEROS */
/* The rest of these are not for users. */
case 'd':
@@ -376,20 +388,22 @@ int main(argc, argv)
suser = pwd->pw_name;
else if (!okname(suser))
continue;
+ (void) sprintf(buf,
#if defined(hpux) || defined(__hpux)
- (void) sprintf(buf, "remsh %s -l %s -n %s %s '%s%s%s:%s'",
+ "remsh %s -l %s -n %s %s '%s%s%s:%s'",
#else
- (void) sprintf(buf, "rsh %s -l %s -n %s %s '%s%s%s:%s'",
+ "rsh %s -l %s -n %s %s '%s%s%s:%s'",
#endif
host, suser, cmd, src,
tuser ? tuser : "",
tuser ? "@" : "",
thost, targ);
} else
+ (void) sprintf(buf,
#if defined(hpux) || defined(__hpux)
- (void) sprintf(buf, "remsh %s -n %s %s '%s%s%s:%s'",
+ "remsh %s -n %s %s '%s%s%s:%s'",
#else
- (void) sprintf(buf, "rsh %s -n %s %s '%s%s%s:%s'",
+ "rsh %s -n %s %s '%s%s%s:%s'",
#endif
argv[i], cmd, src,
tuser ? tuser : "",
@@ -397,7 +411,7 @@ int main(argc, argv)
thost, targ);
(void) susystem(buf);
} else { /* local to remote */
-krb5_creds *cred;
+ krb5_creds *cred;
if (rem == -1) {
(void) sprintf(buf, "%s -t %s",
cmd, targ);
@@ -418,10 +432,14 @@ krb5_creds *cred;
0, /* No server seq # */
&local,
&foreign,
- authopts,
+ &auth_context, authopts,
0, /* Not any port # */
- 0);
+ 0,
+ &kcmd_proto);
if (status) {
+ if (kcmd_proto == KCMD_NEW_PROTOCOL)
+ /* Don't fall back to less safe methods. */
+ exit (1);
#ifdef KRB5_KRB4_COMPAT
fprintf(stderr, "Trying krb4 rcp...\n");
if (strncmp(buf, "-x rcp", 6) == 0)
@@ -442,8 +460,29 @@ krb5_creds *cred;
try_normal(orig_argv);
#endif
}
- else
- rcmd_stream_init_krb5(&cred->keyblock, encryptflag, 0);
+ else {
+ krb5_boolean similar;
+ krb5_keyblock *key = &cred->keyblock;
+
+ if (status = krb5_c_enctype_compare(bsd_context,
+ ENCTYPE_DES_CBC_CRC,
+ cred->keyblock.enctype,
+ &similar))
+ try_normal(orig_argv); /* doesn't return */
+
+ if (!similar) {
+ status = krb5_auth_con_getlocalsubkey (bsd_context,
+ auth_context,
+ &key);
+ if ((status || !key) && encryptflag)
+ try_normal(orig_argv);
+ }
+ if (key == 0)
+ key = &cred->keyblock;
+
+ rcmd_stream_init_krb5(key, encryptflag, 0, 1,
+ kcmd_proto);
+ }
rem = sock;
#else
rem = rcmd(&host, port, pwd->pw_name,
@@ -521,10 +560,14 @@ krb5_creds *cred;
0, /* No server seq # */
(struct sockaddr_in *) 0,
&foreign,
- authopts,
+ &auth_context, authopts,
0, /* Not any port # */
- 0);
+ 0,
+ &kcmd_proto);
if (status) {
+ if (kcmd_proto == KCMD_NEW_PROTOCOL)
+ /* Don't fall back to less safe methods. */
+ exit (1);
#ifdef KRB5_KRB4_COMPAT
fprintf(stderr, "Trying krb4 rcp...\n");
if (strncmp(buf, "-x rcp", 6) == 0)
@@ -543,8 +586,27 @@ krb5_creds *cred;
#else
try_normal(orig_argv);
#endif
- } else
- rcmd_stream_init_krb5(&cred->keyblock, encryptflag, 0);
+ } else {
+ krb5_keyblock *key = &cred->keyblock;
+
+ if (kcmd_proto == KCMD_NEW_PROTOCOL) {
+ status = krb5_auth_con_getlocalsubkey (bsd_context,
+ auth_context,
+ &key);
+ if (status) {
+ com_err (argv[0], status,
+ "determining subkey for session");
+ exit (1);
+ }
+ if (!key) {
+ com_err (argv[0], 0,
+ "no subkey negotiated for connection");
+ exit (1);
+ }
+ }
+
+ rcmd_stream_init_krb5(key, encryptflag, 0, 1, kcmd_proto);
+ }
rem = sock;
euid = geteuid();
@@ -741,7 +803,7 @@ void source(argc, argv)
*/
(void) sprintf(buf, "T%ld 0 %ld 0\n",
stb.st_mtime, stb.st_atime);
- (void) rcmd_stream_write(rem, buf, strlen(buf));
+ (void) rcmd_stream_write(rem, buf, strlen(buf), 0);
if (response() < 0) {
(void) close(f);
continue;
@@ -749,7 +811,7 @@ void source(argc, argv)
}
(void) sprintf(buf, "C%04o %ld %s\n",
(int) stb.st_mode&07777, (long ) stb.st_size, last);
- (void) rcmd_stream_write(rem, buf, strlen(buf));
+ (void) rcmd_stream_write(rem, buf, strlen(buf), 0);
if (response() < 0) {
(void) close(f);
continue;
@@ -765,7 +827,7 @@ void source(argc, argv)
amt = stb.st_size - i;
if (readerr == 0 && read(f, bp->buf, amt) != amt)
readerr = errno;
- (void) rcmd_stream_write(rem, bp->buf, amt);
+ (void) rcmd_stream_write(rem, bp->buf, amt, 0);
}
(void) close(f);
if (readerr == 0)
@@ -810,14 +872,14 @@ void rsource(name, statp)
if (pflag) {
(void) sprintf(buf, "T%ld 0 %ld 0\n",
statp->st_mtime, statp->st_atime);
- (void) rcmd_stream_write(rem, buf, strlen(buf));
+ (void) rcmd_stream_write(rem, buf, strlen(buf), 0);
if (response() < 0) {
closedir(d);
return;
}
}
(void) sprintf(buf, "D%04o %d %s\n", statp->st_mode&07777, 0, last);
- (void) rcmd_stream_write(rem, buf, strlen(buf));
+ (void) rcmd_stream_write(rem, buf, strlen(buf), 0);
if (response() < 0) {
closedir(d);
return;
@@ -836,7 +898,7 @@ void rsource(name, statp)
source(1, bufv);
}
closedir(d);
- (void) rcmd_stream_write(rem, "E\n", 2);
+ (void) rcmd_stream_write(rem, "E\n", 2, 0);
(void) response();
}
@@ -845,7 +907,7 @@ void rsource(name, statp)
int response()
{
char resp, c, rbuf[RCP_BUFSIZ], *cp = rbuf;
- if (rcmd_stream_read(rem, &resp, 1) != 1)
+ if (rcmd_stream_read(rem, &resp, 1, 0) != 1)
lostconn();
switch (resp) {
@@ -858,7 +920,7 @@ int response()
case 1: /* error, followed by err msg */
case 2: /* fatal error, "" */
do {
- if (rcmd_stream_read(rem, &c, 1) != 1)
+ if (rcmd_stream_read(rem, &c, 1, 0) != 1)
lostconn();
*cp++ = c;
} while (cp < &rbuf[RCP_BUFSIZ] && c != '\n');
@@ -941,12 +1003,12 @@ void sink(argc, argv)
targisdir = 1;
for (first = 1; ; first = 0) {
cp = cmdbuf;
- if (rcmd_stream_read(rem, cp, 1) <= 0)
+ if (rcmd_stream_read(rem, cp, 1, 0) <= 0)
return;
if (*cp++ == '\n')
SCREWUP("unexpected '\\n'");
do {
- if (rcmd_stream_read(rem, cp, 1) != 1)
+ if (rcmd_stream_read(rem, cp, 1, 0) != 1)
SCREWUP("lost connection");
} while (*cp++ != '\n');
*cp = 0;
@@ -1012,11 +1074,17 @@ void sink(argc, argv)
size = size * 10 + (*cp++ - '0');
if (*cp++ != ' ')
SCREWUP("size not delimited");
- if (targisdir)
+ if (targisdir) {
+ if(strlen(targ) + strlen(cp) + 2 >= sizeof(nambuf))
+ SCREWUP("target name too long");
(void) sprintf(nambuf, "%s%s%s", targ,
*targ ? "/" : "", cp);
- else
- (void) strcpy(nambuf, targ);
+ } else {
+ if (strlen(targ) + 1 >= sizeof (nambuf))
+ SCREWUP("target name too long");
+ (void) strncpy(nambuf, targ, sizeof(nambuf) - 1);
+ }
+ nambuf[sizeof(nambuf) - 1] = '\0';
exists = stat(nambuf, &stb) == 0;
if (cmdbuf[0] == 'D') {
if (exists) {
@@ -1064,7 +1132,7 @@ void sink(argc, argv)
amt = size - i;
count += amt;
do {
- j = rcmd_stream_read(rem, cp, amt);
+ j = rcmd_stream_read(rem, cp, amt, 0);
if (j <= 0) {
if (j == 0)
error("rcp: dropped connection");
@@ -1159,7 +1227,7 @@ error(fmt, va_alist)
va_end(ap);
if (iamremote)
- (void) rcmd_stream_write(rem, buf, strlen(buf));
+ (void) rcmd_stream_write(rem, buf, strlen(buf), 0);
else
(void) write(2, buf+1, strlen(buf+1));
}
@@ -1170,7 +1238,7 @@ void usage()
{
#ifdef KERBEROS
fprintf(stderr,
- "Usage: \trcp [-p] [-x] [-k realm] f1 f2; or:\n\trcp [-r] [-p] [-x] [-k realm] f1 ... fn d2\n");
+ "Usage: \trcp [-PN | -PO] [-p] [-x] [-k realm] f1 f2; or:\n\trcp [-PN | -PO] [-r] [-p] [-x] [-k realm] f1 ... fn d2\n");
#else
fputs("usage: rcp [-p] f1 f2; or: rcp [-rp] f1 ... fn d2\n", stderr);
#endif
@@ -1315,7 +1383,8 @@ void
exit(1);
}
- rcmd_stream_init_krb5(&new_creds->keyblock, encryptflag, 0);
+ rcmd_stream_init_krb5(&new_creds->keyblock, encryptflag, 0, 0,
+ KCMD_OLD_PROTOCOL);
/* cleanup */
krb5_free_cred_contents(bsd_context, &creds);
diff --git a/src/appl/bsd/krlogin.c b/src/appl/bsd/krlogin.c
index da4a889..0039056 100644
--- a/src/appl/bsd/krlogin.c
+++ b/src/appl/bsd/krlogin.c
@@ -177,6 +177,7 @@ int fflag = 0, Fflag = 0;
krb5_creds *cred;
struct sockaddr_in local, foreign;
krb5_context bsd_context;
+krb5_auth_context auth_context;
#ifdef KRB5_KRB4_COMPAT
Key_schedule v4_schedule;
@@ -377,6 +378,7 @@ main(argc, argv)
#endif
#endif
int port, debug_port = 0;
+ enum kcmd_proto kcmd_proto = KCMD_PROTOCOL_COMPAT_HACK;
memset(&defaultservent, 0, sizeof(struct servent));
if (strrchr(argv[0], '/'))
@@ -502,6 +504,16 @@ main(argc, argv)
argv++, argc--;
goto another;
}
+ if (argc > 0 && !strcmp(*argv, "-PO")) {
+ kcmd_proto = KCMD_OLD_PROTOCOL;
+ argv++, argc--;
+ goto another;
+ }
+ if (argc > 0 && !strcmp(*argv, "-PN")) {
+ kcmd_proto = KCMD_NEW_PROTOCOL;
+ argv++, argc--;
+ goto another;
+ }
#endif /* KERBEROS */
if (host == 0)
goto usage;
@@ -559,7 +571,8 @@ main(argc, argv)
if (tcgetattr(0, &ttyb) == 0) {
int ospeed = cfgetospeed (&ttyb);
- (void) strcat(term, "/");
+ term[sizeof(term) - 1] = '\0';
+ (void) strncat(term, "/", sizeof(term) - 1 - strlen(term));
if (ospeed >= 50)
/* On some systems, ospeed is the baud rate itself,
not a table index. */
@@ -567,15 +580,16 @@ main(argc, argv)
else if (ospeed >= sizeof(speeds)/sizeof(char*))
/* Past end of table, but not high enough to
look like a real speed. */
- (void) strcat (term, speeds[sizeof(speeds)/sizeof(char*) - 1]);
+ (void) strncat (term, speeds[sizeof(speeds)/sizeof(char*) - 1], sizeof(term) - 1 - strlen(term));
else {
- (void) strcat(term, speeds[ospeed]);
+ (void) strncat(term, speeds[ospeed], sizeof(term) - 1 - strlen(term));
}
+ term[sizeof (term) - 1] = '\0';
}
#else
if (ioctl(0, TIOCGETP, &ttyb) == 0) {
- (void) strcat(term, "/");
- (void) strcat(term, speeds[ttyb.sg_ospeed]);
+ (void) strncat(term, "/", sizeof(term) - 1 - strlen(term));
+ (void) strncat(term, speeds[ttyb.sg_ospeed], sizeof(term) - 1 - strlen(term));
}
#endif
(void) get_window_size(0, &winsize);
@@ -631,10 +645,14 @@ main(argc, argv)
0, /* No need for sequence number */
0, /* No need for server seq # */
&local, &foreign,
- authopts,
+ &auth_context, authopts,
0, /* Not any port # */
- 0);
+ 0,
+ &kcmd_proto);
if (status) {
+ if (kcmd_proto == KCMD_NEW_PROTOCOL && encrypt_flag)
+ /* Don't fall back to something less secure. */
+ exit (1);
#ifdef KRB5_KRB4_COMPAT
fprintf(stderr, "Trying krb4 rlogin...\n");
status = k4cmd(&sock, &host, port,
@@ -650,19 +668,20 @@ main(argc, argv)
try_normal(orig_argv);
#endif
} else {
- krb5_boolean similar;
-
- rcmd_stream_init_krb5(&cred->keyblock, encrypt_flag, 1);
-
- if (status = krb5_c_enctype_compare(bsd_context, ENCTYPE_DES_CBC_CRC,
- cred->keyblock.enctype, &similar))
- try_normal(orig_argv); /* doesn't return */
+ krb5_keyblock *key = 0;
- if (!similar) {
+ if (kcmd_proto == KCMD_NEW_PROTOCOL) {
do_inband = 1;
- if (debug_port)
- fprintf(stderr, "DEBUG: setting do_inband\n");
+
+ status = krb5_auth_con_getlocalsubkey (bsd_context, auth_context,
+ &key);
+ if ((status || !key) && encrypt_flag)
+ try_normal(orig_argv);
}
+ if (key == 0)
+ key = &cred->keyblock;
+
+ rcmd_stream_init_krb5(key, encrypt_flag, 1, 1, kcmd_proto);
}
rem = sock;
@@ -1122,9 +1141,9 @@ writer()
#endif
if (c != cmdchar)
- (void) rcmd_stream_write(rem, &cmdchar, 1);
+ (void) rcmd_stream_write(rem, &cmdchar, 1, 0);
}
- if (rcmd_stream_write(rem, &c, 1) == 0) {
+ if (rcmd_stream_write(rem, &c, 1, 0) == 0) {
prf("line gone");
break;
}
@@ -1239,7 +1258,7 @@ sendwindow()
wp->ws_col = htons(winsize.ws_col);
wp->ws_xpixel = htons(winsize.ws_xpixel);
wp->ws_ypixel = htons(winsize.ws_ypixel);
- (void) rcmd_stream_write(rem, obuf, sizeof(obuf));
+ (void) rcmd_stream_write(rem, obuf, sizeof(obuf), 0);
}
@@ -1458,7 +1477,7 @@ fd_set readset, excset, writeset;
bufp += n;
}
if (FD_ISSET(rem, &readset)) {
- rcvcnt = rcmd_stream_read(rem, rcvbuf, sizeof (rcvbuf));
+ rcvcnt = rcmd_stream_read(rem, rcvbuf, sizeof (rcvbuf), 0);
if (rcvcnt == 0)
return (0);
if (rcvcnt < 0)
diff --git a/src/appl/bsd/krlogind.c b/src/appl/bsd/krlogind.c
index e37b84c..d274884 100644
--- a/src/appl/bsd/krlogind.c
+++ b/src/appl/bsd/krlogind.c
@@ -250,6 +250,7 @@ AUTH_DAT *v4_kdata;
Key_schedule v4_schedule;
#include "com_err.h"
+#include "defines.h"
#define SECURE_MESSAGE "This rlogin session is using DES encryption for all data transmissions.\r\n"
@@ -815,7 +816,7 @@ void doit(f, fromp)
stripdomain, always_ip,
&rhost_sane);
if (retval)
- fatalperror(2, "failed make_sane_hostname");
+ fatalperror(f, "failed make_sane_hostname");
if (passwd_req)
execl(login_program, "login", "-p", "-h", rhost_sane,
lusername, 0);
@@ -825,8 +826,9 @@ void doit(f, fromp)
#else /* USE_LOGIN_F */
execl(login_program, "login", "-r", rhost_sane, 0);
#endif /* USE_LOGIN_F */
-
- fatalperror(2, login_program);
+ syslog(LOG_ERR, "failed exec of %s: %s",
+ login_program, error_message(errno));
+ fatalperror(f, login_program);
/*NOTREACHED*/
} /* if (pid == 0) */
@@ -850,7 +852,7 @@ void doit(f, fromp)
#if defined(KERBEROS)
if (do_encrypt) {
- if (rcmd_stream_write(f, SECURE_MESSAGE, sizeof(SECURE_MESSAGE)) < 0){
+ if (rcmd_stream_write(f, SECURE_MESSAGE, sizeof(SECURE_MESSAGE), 0) < 0){
sprintf(buferror, "Cannot encrypt-write network.");
fatal(p,buferror);
}
@@ -918,11 +920,11 @@ int sendoob(fd, byte)
message[3] = 'o';
message[4] = *byte;
- cc = rcmd_stream_write(fd, message, sizeof(message));
+ cc = rcmd_stream_write(fd, message, sizeof(message), 0);
while (cc < 0 && ((errno == EWOULDBLOCK) || (errno == EAGAIN))) {
/* also shouldn't happen */
sleep(5);
- cc = rcmd_stream_write(fd, message, sizeof(message));
+ cc = rcmd_stream_write(fd, message, sizeof(message), 0);
}
} else {
send(fd, byte, 1, MSG_OOB);
@@ -1033,7 +1035,7 @@ void protocol(f, p)
}
#define pkcontrol(c) ((c)&(TIOCPKT_FLUSHWRITE|TIOCPKT_NOSTOP|TIOCPKT_DOSTOP))
if (FD_ISSET(f, &ibits)) {
- fcc = rcmd_stream_read(f, fibuf, sizeof (fibuf));
+ fcc = rcmd_stream_read(f, fibuf, sizeof (fibuf), 0);
if (fcc < 0 && ((errno == EWOULDBLOCK) || (errno == EAGAIN))) {
fcc = 0;
} else {
@@ -1121,7 +1123,7 @@ void protocol(f, p)
}
if (FD_ISSET(f, &obits) && pcc > 0) {
- cc = rcmd_stream_write(f, pbp, pcc);
+ cc = rcmd_stream_write(f, pbp, pcc, 0);
if (cc < 0 && ((errno == EWOULDBLOCK) || (errno == EAGAIN))) {
/* also shouldn't happen */
sleep(5);
@@ -1160,7 +1162,7 @@ void fatal(f, msg)
buf[0] = '\01'; /* error indicator */
(void) sprintf(buf + 1, "%s: %s.\r\n",progname, msg);
if ((f == netf) && (pid > 0))
- (void) rcmd_stream_write(f, buf, strlen(buf));
+ (void) rcmd_stream_write(f, buf, strlen(buf), 0);
else
(void) write(f, buf, strlen(buf));
syslog(LOG_ERR,"%s\n",msg);
@@ -1377,9 +1379,11 @@ recvauth(valid_checksum)
int len;
krb5_data inbuf;
char v4_instance[INST_SZ]; /* V4 Instance */
- char v4_version[9];
+ krb5_data version;
krb5_authenticator *authenticator;
krb5_rcache rcache;
+ enum kcmd_proto kcmd_proto;
+ krb5_keyblock *key;
*valid_checksum = 0;
len = sizeof(laddr);
@@ -1423,8 +1427,8 @@ recvauth(valid_checksum)
if (status) return status;
}
- if ((status = krb5_compat_recvauth(bsd_context, &auth_context, &netf,
- "KCMDV0.1",
+ if ((status = krb5_compat_recvauth_version(bsd_context, &auth_context,
+ &netf,
NULL, /* Specify daemon principal */
0, /* no flags */
keytab, /* normally NULL to use v5srvtab */
@@ -1438,8 +1442,8 @@ recvauth(valid_checksum)
&ticket, /* return ticket */
&auth_sys, /* which authentication system*/
- &v4_kdata, v4_schedule, v4_version))) {
-
+ &v4_kdata, v4_schedule,
+ &version))) {
if (auth_sys == KRB5_RECVAUTH_V5) {
/*
* clean up before exiting
@@ -1453,7 +1457,25 @@ recvauth(valid_checksum)
getstr(netf, lusername, sizeof (lusername), "locuser");
getstr(netf, term, sizeof(term), "Terminal type");
- if ((auth_sys == KRB5_RECVAUTH_V5) && !checksum_ignored) {
+
+ kcmd_proto = KCMD_UNKNOWN_PROTOCOL;
+ if (auth_sys == KRB5_RECVAUTH_V5) {
+ if (version.length != 9) {
+ fatal (netf, "bad application version length");
+ }
+ if (!memcmp (version.data, "KCMDV0.1", 9))
+ kcmd_proto = KCMD_OLD_PROTOCOL;
+ else if (!memcmp (version.data, "KCMDV0.2", 9))
+ kcmd_proto = KCMD_NEW_PROTOCOL;
+ }
+#ifdef KRB5_KRB4_COMPAT
+ if (auth_sys == KRB5_RECVAUTH_V4)
+ kcmd_proto = KCMD_V4_PROTOCOL;
+#endif
+
+ if ((auth_sys == KRB5_RECVAUTH_V5)
+ && !(checksum_ignored
+ && kcmd_proto == KCMD_OLD_PROTOCOL)) {
if ((status = krb5_auth_con_getauthenticator(bsd_context, auth_context,
&authenticator)))
@@ -1500,7 +1522,8 @@ recvauth(valid_checksum)
* Assume it to be the same as the first component of the
* principal's name.
*/
- strcpy(rusername, v4_kdata->pname);
+ strncpy(rusername, v4_kdata->pname, sizeof(rusername) - 1);
+ rusername[sizeof(rusername) - 1] = '\0';
status = krb5_425_conv_principal(bsd_context, v4_kdata->pname,
v4_kdata->pinst, v4_kdata->prealm,
@@ -1519,22 +1542,20 @@ recvauth(valid_checksum)
&client)))
return status;
- rcmd_stream_init_krb5(ticket->enc_part2->session, do_encrypt, 1);
-
- {
- krb5_boolean similar;
-
- if (status = krb5_c_enctype_compare(bsd_context, ENCTYPE_DES_CBC_CRC,
- ticket->enc_part2->session->enctype,
- &similar))
- return(status);
+ key = 0;
+ status = krb5_auth_con_getremotesubkey (bsd_context, auth_context, &key);
+ if (status)
+ fatal (netf, "Server can't get session subkey");
+ if (!key && do_encrypt && kcmd_proto == KCMD_NEW_PROTOCOL)
+ fatal (netf, "No session subkey sent");
+ if (key && kcmd_proto == KCMD_OLD_PROTOCOL)
+ fatal (netf, "Session subkey not permitted under old kcmd protocol");
+ if (key == 0)
+ key = ticket->enc_part2->session;
- if (!similar) {
- do_inband = 1;
- syslog(LOG_DEBUG, "setting do_inband");
- }
- }
+ rcmd_stream_init_krb5 (key, do_encrypt, 1, 0, kcmd_proto);
+ do_inband = (kcmd_proto == KCMD_NEW_PROTOCOL);
getstr(netf, rusername, sizeof(rusername), "remuser");
diff --git a/src/appl/bsd/krsh.c b/src/appl/bsd/krsh.c
index 9d602b2..c1741d8 100644
--- a/src/appl/bsd/krsh.c
+++ b/src/appl/bsd/krsh.c
@@ -93,8 +93,6 @@ krb5_sigtype sendsig();
#define UCB_RSH "/usr/ucb/rsh"
#endif
-
-
krb5_context bsd_context;
krb5_creds *cred;
@@ -137,7 +135,7 @@ main(argc, argv0)
struct servent *sp;
struct servent defaultservent;
struct sockaddr_in local, foreign;
- int suppress;
+ int suppress = 0;
#ifdef POSIX_SIGNALS
sigset_t omask, igmask;
@@ -148,6 +146,7 @@ main(argc, argv0)
#ifdef KERBEROS
krb5_flags authopts;
krb5_error_code status;
+ krb5_auth_context auth_context;
int fflag = 0, Fflag = 0;
#ifdef KRB5_KRB4_COMPAT
KTEXT_ST v4_ticket;
@@ -155,6 +154,7 @@ main(argc, argv0)
#endif
#endif /* KERBEROS */
int debug_port = 0;
+ enum kcmd_proto kcmd_proto = KCMD_PROTOCOL_COMPAT_HACK;
memset(&defaultservent, 0, sizeof(struct servent));
if (strrchr(argv[0], '/'))
@@ -239,6 +239,16 @@ main(argc, argv0)
argv++, argc--;
goto another;
}
+ if (argc > 0 && !strcmp(*argv, "-PO")) {
+ argv++, argc--;
+ kcmd_proto = KCMD_OLD_PROTOCOL;
+ goto another;
+ }
+ if (argc > 0 && !strcmp(*argv, "-PN")) {
+ argv++, argc--;
+ kcmd_proto = KCMD_NEW_PROTOCOL;
+ goto another;
+ }
#endif /* KERBEROS */
/*
* Ignore the -L, -w, -e and -8 flags to allow aliases with rlogin
@@ -367,10 +377,15 @@ main(argc, argv0)
0, /* No need for sequence number */
0, /* No need for server seq # */
&local, &foreign,
- authopts,
+ &auth_context, authopts,
1, /* Always set anyport, there is no need not to. --proven */
- suppress);
+ suppress,
+ &kcmd_proto);
if (status) {
+ /* If new protocol requested, don't fall back to less secure
+ ones. */
+ if (kcmd_proto == KCMD_NEW_PROTOCOL)
+ exit (1);
#ifdef KRB5_KRB4_COMPAT
/* No encrypted Kerberos 4 rsh. */
if (encrypt_flag)
@@ -391,8 +406,24 @@ main(argc, argv0)
#else
try_normal(argv0);
#endif
- } else
- rcmd_stream_init_krb5(&cred->keyblock, encrypt_flag, 0);
+ } else {
+ krb5_keyblock *key = &cred->keyblock;
+
+ if (kcmd_proto == KCMD_NEW_PROTOCOL) {
+ status = krb5_auth_con_getlocalsubkey (bsd_context, auth_context,
+ &key);
+ if (status) {
+ com_err (argv[0], status, "determining subkey for session");
+ exit (1);
+ }
+ if (!key) {
+ com_err (argv[0], 0, "no subkey negotiated for connection");
+ exit (1);
+ }
+ }
+
+ rcmd_stream_init_krb5(key, encrypt_flag, 0, 1, kcmd_proto);
+ }
#ifdef HAVE_ISATTY
if(encrypt_flag&&isatty(2)) {
@@ -489,7 +520,7 @@ main(argc, argv0)
}
if (FD_ISSET(rem, &rembits) == 0)
goto rewrite;
- wc = rcmd_stream_write(rem, bp, cc);
+ wc = rcmd_stream_write(rem, bp, cc, 0);
if (wc < 0) {
if ((errno == EWOULDBLOCK) || (errno == EAGAIN))
goto rewrite;
@@ -524,7 +555,7 @@ main(argc, argv0)
}
if (FD_ISSET(rfd2, &ready)) {
errno = 0;
- cc = rcmd_stream_read(rfd2, buf, sizeof buf);
+ cc = rcmd_stream_read(rfd2, buf, sizeof buf, 1);
if (cc <= 0) {
if ((errno != EWOULDBLOCK) && (errno != EAGAIN))
FD_CLR(rfd2, &readfrom);
@@ -533,7 +564,7 @@ main(argc, argv0)
}
if (FD_ISSET(rem, &ready)) {
errno = 0;
- cc = rcmd_stream_read(rem, buf, sizeof buf);
+ cc = rcmd_stream_read(rem, buf, sizeof buf, 0);
if (cc <= 0) {
if ((errno != EWOULDBLOCK) && (errno != EAGAIN))
FD_CLR(rem, &readfrom);
@@ -546,9 +577,9 @@ main(argc, argv0)
exit(0);
usage:
fprintf(stderr,
- "usage: \trsh host [ -l login ] [ -n ] [ -x ] [ -f / -F] command\n");
+ "usage: \trsh host [ -PN / -PO ] [ -l login ] [ -n ] [ -x ] [ -f / -F] command\n");
fprintf(stderr,
- "OR \trsh [ -l login ] [-n ] [ -x ] [ -f / -F ] host command\n");
+ "OR \trsh [ -PN / -PO ] [ -l login ] [-n ] [ -x ] [ -f / -F ] host command\n");
exit(1);
}
@@ -557,7 +588,7 @@ main(argc, argv0)
krb5_sigtype sendsig(signo)
char signo;
{
- (void) rcmd_stream_write(rfd2, &signo, 1);
+ (void) rcmd_stream_write(rfd2, &signo, 1, 1);
}
diff --git a/src/appl/bsd/krshd.c b/src/appl/bsd/krshd.c
index 3844087..c69729c 100644
--- a/src/appl/bsd/krshd.c
+++ b/src/appl/bsd/krshd.c
@@ -48,8 +48,8 @@ char copyright[] =
* or by the name of the daemon. If command-line arguments are present, they
* take priority. The options are:
* -k means trust krb4 or krb5
-* -5 means trust krb5
-* -4 means trust krb4 (using .klogin)
+ * -5 means trust krb5
+ * -4 means trust krb4 (using .klogin)
*
*/
@@ -73,9 +73,7 @@ char copyright[] =
#define SERVE_NON_KRB
#define LOG_REMOTE_REALM
#define LOG_CMD
-#include "defines.h"
-
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
@@ -162,6 +160,8 @@ char copyright[] =
Key_schedule v4_schedule;
#endif
+#include "defines.h"
+
#if HAVE_ARPA_NAMESER_H
#include <arpa/nameser.h>
#endif
@@ -1245,7 +1245,7 @@ if(port)
shutdown(s, 1+1);
FD_CLR(pv[0], &readfrom);
} else {
- (void) rcmd_stream_write(s, buf, cc);
+ (void) rcmd_stream_write(s, buf, cc, 1);
}
}
if (FD_ISSET(pw[0], &ready)) {
@@ -1256,12 +1256,12 @@ if(port)
shutdown(f, 1+1);
FD_CLR(pw[0], &readfrom);
} else {
- (void) rcmd_stream_write(f, buf, cc);
+ (void) rcmd_stream_write(f, buf, cc, 0);
}
}
if (port&&FD_ISSET(s, &ready)) {
/* read from the alternate channel, signal the child */
- if (rcmd_stream_read(s, &sig, 1) <= 0) {
+ if (rcmd_stream_read(s, &sig, 1, 1) <= 0) {
FD_CLR(s, &readfrom);
} else {
#ifdef POSIX_SIGNALS
@@ -1277,7 +1277,7 @@ if(port)
if (FD_ISSET(f, &ready)) {
/* read from the net, write to child stdin */
errno = 0;
- cc = rcmd_stream_read(f, buf, sizeof(buf));
+ cc = rcmd_stream_read(f, buf, sizeof(buf), 0);
if (cc <= 0) {
(void) close(px[1]);
FD_CLR(f, &readfrom);
@@ -1468,15 +1468,16 @@ if(port)
strcpy((char *) cmdbuf + offst, kprogdir);
cp = copy + 3 + offst;
+ cmdbuf[sizeof(cmdbuf) - 1] = '\0';
if (auth_sys == KRB5_RECVAUTH_V4) {
- strcat(cmdbuf, "/v4rcp");
+ strncat(cmdbuf, "/v4rcp", sizeof(cmdbuf) - 1 - strlen(cmdbuf));
} else {
- strcat(cmdbuf, "/rcp");
+ strncat(cmdbuf, "/rcp", sizeof(cmdbuf) - 1 - strlen(cmdbuf));
}
if (stat((char *)cmdbuf + offst, &s) >= 0)
- strcat(cmdbuf, cp);
+ strncat(cmdbuf, cp, sizeof(cmdbuf) - 1 - strlen(cmdbuf));
else
- strcpy(cmdbuf, copy);
+ strncpy(cmdbuf, copy, sizeof(cmdbuf) - 1 - strlen(cmdbuf));
free(copy);
}
#endif
@@ -1775,7 +1776,6 @@ recvauth(netf, peersin, valid_checksum)
krb5_data inbuf;
#ifdef KRB5_KRB4_COMPAT
char v4_instance[INST_SZ]; /* V4 Instance */
- char v4_version[9];
#endif
krb5_authenticator *authenticator;
krb5_ticket *ticket;
@@ -1783,6 +1783,8 @@ recvauth(netf, peersin, valid_checksum)
struct passwd *pwd;
uid_t uid;
gid_t gid;
+ enum kcmd_proto kcmd_proto;
+ krb5_data version;
*valid_checksum = 0;
len = sizeof(laddr);
@@ -1828,8 +1830,7 @@ recvauth(netf, peersin, valid_checksum)
}
#ifdef KRB5_KRB4_COMPAT
- status = krb5_compat_recvauth(bsd_context, &auth_context, &netf,
- "KCMDV0.1",
+ status = krb5_compat_recvauth_version(bsd_context, &auth_context, &netf,
NULL, /* Specify daemon principal */
0, /* no flags */
keytab, /* normally NULL to use v5srvtab */
@@ -1842,14 +1843,14 @@ recvauth(netf, peersin, valid_checksum)
&ticket, /* return ticket */
&auth_sys, /* which authentication system*/
- &v4_kdata, 0, v4_version);
+ &v4_kdata, 0, &version);
#else
- status = krb5_recvauth(bsd_context, &auth_context, &netf,
- "KCMDV0.1",
- NULL, /* daemon principal */
- 0, /* no flags */
- keytab, /* normally NULL to use v5srvtab */
- &ticket); /* return ticket */
+ status = krb5_recvauth_version(bsd_context, &auth_context, &netf,
+ NULL, /* daemon principal */
+ 0, /* no flags */
+ keytab, /* normally NULL to use v5srvtab */
+ &ticket, /* return ticket */
+ &version); /* application version string */
auth_sys = KRB5_RECVAUTH_V5;
#endif
@@ -1891,6 +1892,14 @@ recvauth(netf, peersin, valid_checksum)
/* Must be V5 */
+ kcmd_proto = KCMD_UNKNOWN_PROTOCOL;
+ if (version.length != 9)
+ fatal (netf, "bad application version length");
+ if (!memcmp (version.data, "KCMDV0.1", 9))
+ kcmd_proto = KCMD_OLD_PROTOCOL;
+ if (!memcmp (version.data, "KCMDV0.2", 9))
+ kcmd_proto = KCMD_NEW_PROTOCOL;
+
getstr(netf, remuser, sizeof(locuser), "remuser");
if ((status = krb5_unparse_name(bsd_context, ticket->enc_part2->client,
@@ -1939,7 +1948,21 @@ recvauth(netf, peersin, valid_checksum)
if (!strncmp(cmdbuf, "-x ", 3))
do_encrypt = 1;
- rcmd_stream_init_krb5(ticket->enc_part2->session, do_encrypt, 0);
+
+ {
+ krb5_keyblock *key;
+ status = krb5_auth_con_getremotesubkey (bsd_context, auth_context,
+ &key);
+ if (status)
+ fatal (netf, "Server can't get session subkey");
+ if (!key && do_encrypt && kcmd_proto == KCMD_NEW_PROTOCOL)
+ fatal (netf, "No session subkey sent");
+ if (key && kcmd_proto == KCMD_OLD_PROTOCOL)
+ fatal (netf, "Session subkey not allowed in old kcmd protocol");
+ if (key == 0)
+ key = ticket->enc_part2->session;
+ rcmd_stream_init_krb5 (key, do_encrypt, 0, 0, kcmd_proto);
+ }
/* Null out the "session" because kcmd.c references the session
* key here, and we do not want krb5_free_ticket() to destroy it. */
@@ -1990,7 +2013,7 @@ void fatal(f, msg)
buf[0] = '\01'; /* error indicator */
(void) sprintf(buf + 1, "%s: %s.\r\n",progname, msg);
if ((f == netf) && (pid > 0))
- (void) rcmd_stream_write(f, buf, strlen(buf));
+ (void) rcmd_stream_write(f, buf, strlen(buf), 0);
else
(void) write(f, buf, strlen(buf));
syslog(LOG_ERR,"%s\n",msg);
diff --git a/src/appl/bsd/login.c b/src/appl/bsd/login.c
index 40af3ce..af703b3 100644
--- a/src/appl/bsd/login.c
+++ b/src/appl/bsd/login.c
@@ -619,9 +619,10 @@ int have_v5_tickets (me)
#endif /* KRB5_GET_TICKETS */
#ifdef KRB4_CONVERT
-try_convert524 (kcontext, me)
- krb5_context kcontext;
- krb5_principal me;
+try_convert524(kcontext, me, use_ccache)
+ krb5_context kcontext;
+ krb5_principal me;
+ int use_ccache;
{
krb5_principal kpcserver;
krb5_error_code kpccode;
@@ -632,38 +633,45 @@ try_convert524 (kcontext, me)
/* or do this directly with krb524_convert_creds_kdc */
krb524_init_ets(kcontext);
- /* cc->ccache, already set up */
- /* client->me, already set up */
- if ((kpccode = krb5_build_principal(kcontext,
- &kpcserver,
- krb5_princ_realm(kcontext, me)->length,
- krb5_princ_realm(kcontext, me)->data,
- "krbtgt",
- krb5_princ_realm(kcontext, me)->data,
- NULL))) {
- com_err("login/v4", kpccode,
- "while creating service principal name");
- return 0;
- }
- memset((char *) &increds, 0, sizeof(increds));
- increds.client = me;
- increds.server = kpcserver;
- increds.times.endtime = 0;
- increds.keyblock.enctype = ENCTYPE_DES_CBC_CRC;
- if ((kpccode = krb5_get_credentials(kcontext, 0,
- ccache,
- &increds,
- &v5creds))) {
- com_err("login/v4", kpccode,
- "getting V5 credentials");
- return 0;
- }
- if ((kpccode = krb524_convert_creds_kdc(kcontext,
- v5creds,
- &v4creds))) {
- com_err("login/v4", kpccode,
- "converting to V4 credentials");
+ /* If we have forwarded v5 tickets, retrieve the credentials from
+ * the cache; otherwise, the v5 credentials are in my_creds.
+ */
+ if (use_ccache) {
+ /* cc->ccache, already set up */
+ /* client->me, already set up */
+ kpccode = krb5_build_principal(kcontext, &kpcserver,
+ krb5_princ_realm(kcontext, me)->length,
+ krb5_princ_realm(kcontext, me)->data,
+ "krbtgt",
+ krb5_princ_realm(kcontext, me)->data,
+ NULL);
+ if (kpccode) {
+ com_err("login/v4", kpccode,
+ "while creating service principal name");
+ return 0;
+ }
+
+ memset((char *) &increds, 0, sizeof(increds));
+ increds.client = me;
+ increds.server = kpcserver;
+ increds.times.endtime = 0;
+ increds.keyblock.enctype = ENCTYPE_DES_CBC_CRC;
+ kpccode = krb5_get_credentials(kcontext, 0, ccache,
+ &increds, &v5creds);
+ krb5_free_principal(kcontext, kpcserver);
+ increds.server = NULL;
+ if (kpccode) {
+ com_err("login/v4", kpccode, "getting V5 credentials");
+ return 0;
+ }
+
+ kpccode = krb524_convert_creds_kdc(kcontext, v5creds, &v4creds);
+ krb5_free_creds(kcontext, v5creds);
+ } else
+ kpccode = krb524_convert_creds_kdc(kcontext, &my_creds, &v4creds);
+ if (kpccode) {
+ com_err("login/v4", kpccode, "converting to V4 credentials");
return 0;
}
/* this is stolen from the v4 kinit */
@@ -913,8 +921,9 @@ afs_login ()
struct stat st;
/* construct the name */
/* get this from profile later */
- strcpy (aklog_path, KPROGDIR);
- strcat (aklog_path, "/aklog");
+ aklog_path[sizeof(aklog_path) - 1] = '\0';
+ strncpy (aklog_path, KPROGDIR, sizeof(aklog_path) - 1);
+ strncat (aklog_path, "/aklog", sizeof(aklog_path) - 1 - strlen(aklog_path));
/* only run it if we can find it */
if (stat (aklog_path, &st) == 0) {
system(aklog_path);
@@ -1448,7 +1457,7 @@ int main(argc, argv)
#if defined(KRB5_GET_TICKETS) && defined(KRB4_CONVERT)
if (login_krb4_convert && !got_v4_tickets) {
if (got_v5_tickets||forwarded_v5_tickets)
- try_convert524 (kcontext, me);
+ try_convert524(kcontext, me, forwarded_v5_tickets);
}
#endif
diff --git a/src/appl/bsd/v4rcp.c b/src/appl/bsd/v4rcp.c
index 36754de..3267783 100644
--- a/src/appl/bsd/v4rcp.c
+++ b/src/appl/bsd/v4rcp.c
@@ -208,7 +208,7 @@ int kstream_read(krem, buf, len)
/* decrypt it */
des_pcbc_encrypt ((des_cblock *)krem->retbuf,
(des_cblock *)krem->retbuf,
- sz, *krem->sched, *krem->ivec,
+ sz, *krem->sched, krem->ivec,
DECRYPT);
/* now retbuf has sz bytes, return len or x of them to the user */
@@ -265,7 +265,7 @@ int kstream_write(krem, buf, len)
abort ();
/* memset(outbuf+4+4, 0x42, BUFSIZ); */
st = des_pcbc_encrypt ((des_cblock *)buf, (des_cblock *)(krem->outbuf+4+4), outlen,
- *krem->sched, *krem->ivec, ENCRYPT);
+ *krem->sched, krem->ivec, ENCRYPT);
if (st) abort();
return write(krem->write_fd, krem->outbuf+4, 4+outlen);
@@ -400,6 +400,7 @@ int main(argc, argv)
if (argc == 0)
usage();
strncpy(krb_realm,*argv,REALM_SZ);
+ krb_realm[REALM_SZ-1] = 0;
sprintf(realmarg, " -k %s", krb_realm);
goto next_arg;
#endif /* KERBEROS */
@@ -782,11 +783,20 @@ void sink(argc, argv)
size = size * 10 + (*cp++ - '0');
if (*cp++ != ' ')
SCREWUP("size not delimited");
- if (targisdir)
- (void) sprintf(nambuf, "%s%s%s", targ,
- *targ ? "/" : "", cp);
- else
- (void) strcpy(nambuf, targ);
+ if (targisdir) {
+ if (strlen(targ) + strlen(cp) + 1 < sizeof(nambuf)) {
+ (void) sprintf(nambuf, "%s%s%s", targ,
+ *targ ? "/" : "", cp);
+ } else {
+ SCREWUP("target directory name too long");
+ }
+ } else {
+ if (strlen(targ) + 1 < sizeof(nambuf))
+ (void) strncpy(nambuf, targ, sizeof(nambuf)-1);
+ else
+ SCREWUP("target pathname too long");
+ }
+ nambuf[sizeof(nambuf)-1] = '\0';
exists = stat(nambuf, &stb) == 0;
if (cmdbuf[0] == 'D') {
if (exists) {
diff --git a/src/appl/gssftp/ChangeLog b/src/appl/gssftp/ChangeLog
index 7d41ff4..ed96d06 100644
--- a/src/appl/gssftp/ChangeLog
+++ b/src/appl/gssftp/ChangeLog
@@ -1,3 +1,8 @@
+2000-03-24 Ken Raeburn <raeburn@mit.edu>
+
+ * configure.in: Check for alpha*-dec-osf* instead of
+ alpha-dec-osf*.
+
1999-10-26 Wilfredo Sanchez <tritan@mit.edu>
* Makefile.in: Clean up usage of CFLAGS, CPPFLAGS, DEFS, DEFINES,
diff --git a/src/appl/gssftp/configure.in b/src/appl/gssftp/configure.in
index f0c2bff..349cc04 100644
--- a/src/appl/gssftp/configure.in
+++ b/src/appl/gssftp/configure.in
@@ -67,7 +67,7 @@ else
FTPD_LIBS="../../../krb524/libkrb524.a"
fi
case $krb5_cv_host in
-alpha-dec-osf*)
+alpha*-dec-osf*)
AC_CHECK_LIB(security,setluid,
AC_DEFINE(HAVE_SETLUID)
FTPD_LIBS="$FTPD_LIBS -lsecurity"
diff --git a/src/appl/gssftp/ftp/ChangeLog b/src/appl/gssftp/ftp/ChangeLog
index 22a29c3..a5d2265 100644
--- a/src/appl/gssftp/ftp/ChangeLog
+++ b/src/appl/gssftp/ftp/ChangeLog
@@ -1,3 +1,20 @@
+2000-05-11 Nalin Dahyabhai <nalin@redhat.com>
+
+ * domacro.c (domacro): Don't overflow "line2"
+ * ftp.c (getreply, krb4 compat): Bail if message data too big for buffer
+ (getreply, gssapi): Ditto.
+ (pswitch): Don't overflow "ntin", "ntout", "mapin", "mapout".
+ (do_auth, krb4 compat): Don't overflow "realm".
+
+2000-04-27 Nalin Dahyabhai <nalin@redhat.com>
+
+ * cmds.c (remglob): Don't overflow buffer "temp".
+ (shell): Don't overflow buffer "shellnam".
+ (quote1): "buf"
+ * glob.c (ftpglob): Fix boundary in buffer "agpath".
+ (expand): Don't overflow buffer pointed to by "gpath".
+ (execbrc): Don't overflow buffer "restbuf".
+
2000-02-18 Ken Raeburn <raeburn@mit.edu>
* cmds.c (mls): Declare some variables volatile to protect against
diff --git a/src/appl/gssftp/ftp/cmds.c b/src/appl/gssftp/ftp/cmds.c
index 2a8e775..0006e4f 100644
--- a/src/appl/gssftp/ftp/cmds.c
+++ b/src/appl/gssftp/ftp/cmds.c
@@ -1049,7 +1049,8 @@ remglob(argv,doswitch)
return (cp);
}
if (ftemp == NULL) {
- (void) strcpy(temp, _PATH_TMP);
+ (void) strncpy(temp, _PATH_TMP, sizeof(temp) - 1);
+ temp[sizeof(temp) - 1] = '\0';
(void) mktemp(temp);
oldverbose = verbose, verbose = 0;
oldhash = hash, hash = 0;
@@ -1510,7 +1511,8 @@ shell(argc, argv)
if (namep == NULL)
namep = shell;
(void) strcpy(shellnam,"-");
- (void) strcat(shellnam, ++namep);
+ (void) strncat(shellnam, ++namep, sizeof(shellnam) - 1 - strlen(shellnam));
+ shellnam[sizeof(shellnam) - 1] = '\0';
if (strcmp(namep, "sh") != 0)
shellnam[0] = '+';
if (debug) {
@@ -1702,13 +1704,14 @@ quote1(initial, argc, argv)
register int i, len;
char buf[FTP_BUFSIZ]; /* must be >= sizeof(line) */
- (void) strcpy(buf, initial);
+ (void) strncpy(buf, initial, sizeof(buf) - 1);
+ buf[sizeof(buf) - 1] = '\0';
if (argc > 1) {
len = strlen(buf);
- len += strlen(strcpy(&buf[len], argv[1]));
+ len += strlen(strncpy(&buf[len], argv[1], sizeof(buf) - 1 - len));
for (i = 2; i < argc; i++) {
buf[len++] = ' ';
- len += strlen(strcpy(&buf[len], argv[i]));
+ len += strlen(strncpy(&buf[len], argv[i], sizeof(buf) - 1 - len));
}
}
if (command(buf) == PRELIM) {
diff --git a/src/appl/gssftp/ftp/domacro.c b/src/appl/gssftp/ftp/domacro.c
index 9bc277b..ecfe9b4 100644
--- a/src/appl/gssftp/ftp/domacro.c
+++ b/src/appl/gssftp/ftp/domacro.c
@@ -71,7 +71,8 @@ domacro(argc, argv)
code = -1;
return;
}
- (void) strcpy(line2, line);
+ (void) strncpy(line2, line, sizeof(line2) - 1);
+ line2[sizeof(line2) - 1] = '\0';
TOP:
cp1 = macros[i].mac_start;
while (cp1 != macros[i].mac_end) {
@@ -92,7 +93,11 @@ TOP:
}
cp1--;
if (argc - 2 >= j) {
- (void) strcpy(cp2, argv[j+1]);
+ if(cp2 + strlen(argv[j+1]) - line < sizeof(line))
+ (void) strncpy(cp2, argv[j+1],
+ sizeof(line) - 1 -
+ (cp2 - line));
+ line[sizeof(line) - 1] = '\0';
cp2 += strlen(argv[j+1]);
}
break;
@@ -101,7 +106,11 @@ TOP:
loopflg = 1;
cp1++;
if (count < argc) {
- (void) strcpy(cp2, argv[count]);
+ if(cp2 + strlen(argv[j+1]) - line < sizeof(line))
+ (void) strncpy(cp2, argv[count],
+ sizeof(line) - 1 -
+ (cp2 - line));
+ line[sizeof(line) - 1] = '\0';
cp2 += strlen(argv[count]);
}
break;
@@ -138,7 +147,8 @@ TOP:
if (bell && c->c_bell) {
(void) putchar('\007');
}
- (void) strcpy(line, line2);
+ (void) strncpy(line, line2, sizeof(line) - 1);
+ line[sizeof(line) - 1] = '\0';
makeargv();
argc = margc;
argv = margv;
diff --git a/src/appl/gssftp/ftp/ftp.c b/src/appl/gssftp/ftp/ftp.c
index 11f583a..a00850d 100644
--- a/src/appl/gssftp/ftp/ftp.c
+++ b/src/appl/gssftp/ftp/ftp.c
@@ -680,9 +680,13 @@ getreply(expecteof)
n = '5';
} else {
if (debug) printf("%c:", safe ? 'S' : 'P');
- memcpy(ibuf, msg_data.app_data,
- msg_data.app_length);
- strcpy(&ibuf[msg_data.app_length], "\r\n");
+ if(msg_data.app_length < sizeof(ibuf) - 2) {
+ memcpy(ibuf, msg_data.app_data,
+ msg_data.app_length);
+ strcpy(&ibuf[msg_data.app_length], "\r\n");
+ } else {
+ printf("Message too long!");
+ }
continue;
}
#endif
@@ -703,9 +707,14 @@ getreply(expecteof)
"failed unsealing reply");
n = '5';
} else {
- memcpy(ibuf, msg_buf.value,
- msg_buf.length);
- strcpy(&ibuf[msg_buf.length], "\r\n");
+ if(msg_buf.length < sizeof(ibuf) - 2 - 1) {
+ memcpy(ibuf, msg_buf.value,
+ msg_buf.length);
+ strcpy(&ibuf[msg_buf.length], "\r\n");
+ } else {
+ user_gss_error(maj_stat, min_stat,
+ "reply was too long");
+ }
gss_release_buffer(&min_stat,&msg_buf);
continue;
}
@@ -1636,20 +1645,24 @@ pswitch(flag)
mcase = op->mcse;
ip->ntflg = ntflag;
ntflag = op->ntflg;
- (void) strncpy(ip->nti, ntin, 16);
+ (void) strncpy(ip->nti, ntin, sizeof(ip->nti) - 1);
(ip->nti)[strlen(ip->nti)] = '\0';
- (void) strcpy(ntin, op->nti);
- (void) strncpy(ip->nto, ntout, 16);
+ (void) strncpy(ntin, op->nti, sizeof(ntin) - 1);
+ ntin[sizeof(ntin) - 1] = '\0';
+ (void) strncpy(ip->nto, ntout, sizeof(ip->nto) - 1);
(ip->nto)[strlen(ip->nto)] = '\0';
- (void) strcpy(ntout, op->nto);
+ (void) strncpy(ntout, op->nto, sizeof(ntout) - 1);
+ ntout[sizeof(ntout) - 1] = '\0';
ip->mapflg = mapflag;
mapflag = op->mapflg;
(void) strncpy(ip->mi, mapin, MAXPATHLEN - 1);
(ip->mi)[strlen(ip->mi)] = '\0';
- (void) strcpy(mapin, op->mi);
+ (void) strncpy(mapin, op->mi, sizeof(mapin) - 1);
+ mapin[sizeof(mapin) - 1] = '\0';
(void) strncpy(ip->mo, mapout, MAXPATHLEN - 1);
(ip->mo)[strlen(ip->mo)] = '\0';
- (void) strcpy(mapout, op->mo);
+ (void) strncpy(mapout, op->mo, sizeof(mapout) - 1);
+ mapout[sizeof(mapout) - 1] = '\0';
ip->authtype = auth_type;
auth_type = op->authtype;
ip->clvl = clevel;
@@ -1846,7 +1859,8 @@ gunique(local)
fprintf(stderr, "local: %s: %s\n", local, strerror(errno));
return((char *) 0);
}
- (void) strcpy(new, local);
+ (void) strncpy(new, local, sizeof(new) - 3);
+ new[sizeof(new) - 1] = '\0';
cp = new + strlen(new);
*cp++ = '.';
while (!d) {
@@ -2054,9 +2068,11 @@ do_auth()
if (verbose)
printf("%s accepted as authentication type\n", "KERBEROS_V4");
- strcpy(inst, (char *) krb_get_phost(hostname));
+ strncpy(inst, (char *) krb_get_phost(hostname), sizeof(inst) - 1);
+ inst[sizeof(inst) - 1] = '\0';
if (realm[0] == '\0')
- strcpy(realm, (char *) krb_realmofhost(hostname));
+ strncpy(realm, (char *) krb_realmofhost(hostname), sizeof(realm) - 1);
+ realm[sizeof(realm) - 1] = '\0';
if ((kerror = krb_mk_req(&ticket, service = "ftp",
inst, realm, checksum))
&& (kerror != KDC_PR_UNKNOWN ||
diff --git a/src/appl/gssftp/ftp/glob.c b/src/appl/gssftp/ftp/glob.c
index f92ee5e..a5a6bf7 100644
--- a/src/appl/gssftp/ftp/glob.c
+++ b/src/appl/gssftp/ftp/glob.c
@@ -118,7 +118,7 @@ ftpglob(v)
globerr = 0;
gpath = agpath; gpathp = gpath; *gpathp = 0;
- lastgpathp = &gpath[sizeof agpath - 2];
+ lastgpathp = &gpath[sizeof(agpath) - 1];
ginit(agargv); globcnt = 0;
collect(v);
if (globcnt == 0 && (gflag&1)) {
@@ -198,7 +198,8 @@ expand(as)
globerr = "Unknown user name after ~";
(void) strcpy(gpath, gpath + 1);
} else
- (void) strcpy(gpath, home);
+ (void) strncpy(gpath, home, FTP_BUFSIZ - 1);
+ gpath[FTP_BUFSIZ - 1] = '\0';
gpathp = strend(gpath);
}
}
@@ -324,8 +325,9 @@ pend:
doit:
savec = *pm;
*pm = 0;
- (void) strcpy(lm, pl);
- (void) strcat(restbuf, pe + 1);
+ (void) strncpy(lm, pl, sizeof(restbuf) - 1 - (lm - restbuf));
+ restbuf[sizeof(restbuf) - 1] = '\0';
+ (void) strncat(restbuf, pe + 1, sizeof(restbuf) - 1 - strlen(restbuf));
*pm = savec;
if (s == 0) {
sgpathp = gpathp;
@@ -700,7 +702,7 @@ gethdir(home)
{
register struct passwd *pp = getpwnam(home);
- if (!pp || home + strlen(pp->pw_dir) >= lastgpathp)
+ if (!pp || ((home + strlen(pp->pw_dir)) >= lastgpathp))
return (1);
(void) strcpy(home, pp->pw_dir);
return (0);
diff --git a/src/appl/gssftp/ftp/main.c b/src/appl/gssftp/ftp/main.c
index 9c1e43a..6c7e1e9 100644
--- a/src/appl/gssftp/ftp/main.c
+++ b/src/appl/gssftp/ftp/main.c
@@ -193,7 +193,8 @@ main(argc, argv)
pw = getpwuid(getuid());
if (pw != NULL) {
home = homedir;
- (void) strcpy(home, pw->pw_dir);
+ (void) strncpy(home, pw->pw_dir, sizeof(homedir) - 1);
+ homedir[sizeof(homedir) - 1] = '\0';
}
if (argc > 0) {
if (setjmp(toplevel))
diff --git a/src/appl/gssftp/ftp/secure.c b/src/appl/gssftp/ftp/secure.c
index 48f57f9..e1f69b0 100644
--- a/src/appl/gssftp/ftp/secure.c
+++ b/src/appl/gssftp/ftp/secure.c
@@ -52,6 +52,11 @@ extern struct sockaddr_in myaddr;
extern int dlevel;
extern char *auth_type;
+/* Some libc's (GNU libc, at least) define MAX as a macro. Forget that. */
+#ifdef MAX
+#undef MAX
+#endif
+
#define MAX maxbuf
extern unsigned int maxbuf; /* maximum output buffer size */
extern unsigned char *ucbuf; /* cleartext buffer */
diff --git a/src/appl/gssftp/ftpd/ChangeLog b/src/appl/gssftp/ftpd/ChangeLog
index 388b4b2..70f2112 100644
--- a/src/appl/gssftp/ftpd/ChangeLog
+++ b/src/appl/gssftp/ftpd/ChangeLog
@@ -1,3 +1,11 @@
+2000-06-14 Tom Yu <tlyu@mit.edu>
+
+ * ftpcmd.y (nonguest): Return $1, not 1, if (!guest).
+
+2000-05-11 Nalin Dahyabhai <nalin@redhat.com>
+
+ * ftpd.c (gunique): Make sure that path stored in "new" isn't too long.
+
2000-02-18 Ken Raeburn <raeburn@mit.edu>
* ftpd.c (reply, lreply): Declare with format attribute under
diff --git a/src/appl/gssftp/ftpd/ftpcmd.y b/src/appl/gssftp/ftpd/ftpcmd.y
index acd1871..bc25219 100644
--- a/src/appl/gssftp/ftpd/ftpcmd.y
+++ b/src/appl/gssftp/ftpd/ftpcmd.y
@@ -865,7 +865,7 @@ nonguest: check_login
$$ = 0;
}
else
- $$ = 1;
+ $$ = $1;
}
;
%%
diff --git a/src/appl/gssftp/ftpd/ftpd.c b/src/appl/gssftp/ftpd/ftpd.c
index c7dfc8a..047be35 100644
--- a/src/appl/gssftp/ftpd/ftpd.c
+++ b/src/appl/gssftp/ftpd/ftpd.c
@@ -2123,7 +2123,8 @@ gunique(local)
}
if (cp)
*cp = '/';
- (void) strcpy(new, local);
+ (void) strncpy(new, local, sizeof(new) - 1);
+ new[sizeof(new) - 1] = '\0';
cp = new + strlen(new);
*cp++ = '.';
for (count = 1; count < 100; count++) {
@@ -2287,7 +2288,8 @@ char *data;
syslog(LOG_ERR, "Couldn't canonicalize local hostname");
return 0;
}
- strcpy(localname, hp->h_name);
+ strncpy(localname, hp->h_name, sizeof(localname) - 1);
+ localname[sizeof(localname) - 1] = '\0';
for (service = gss_services; *service; service++) {
sprintf(service_name, "%s@%s", *service, localname);
diff --git a/src/appl/telnet/libtelnet/ChangeLog b/src/appl/telnet/libtelnet/ChangeLog
index 03cb924..8b71835 100644
--- a/src/appl/telnet/libtelnet/ChangeLog
+++ b/src/appl/telnet/libtelnet/ChangeLog
@@ -1,3 +1,22 @@
+2000-05-11 Nalin Dahyabhai <nalin@redhat.com>
+
+ * gettytab.c (nchktc): Don't overflow tcname if tty type name is too
+ long
+ * kerberos.c (kerberos4_status): Make sure "UserNameRequested" is
+ always properly terminated.
+ * kerberos5.c (kerberos5_is): If bad principal name is too long to fit
+ in "errbuf", don't print it.
+ (kerberos5_status): Make sure "UserNameRequested" is always properly
+ terminated.
+ * spx.c (spx_status): Ditto.
+
+2000-04-28 Nalin Dahyabhai <nalin@redhat.com>
+
+ * kerberos5.c (kerberos5_is): Don't overflow buffer "errbuf".
+ * spx.c (spx_init, spx_send, spx_is): Don't overflow buffer
+ "targ_printable".
+ (spx_status): Don't overflow buffer "acl_file".
+
1999-10-26 Wilfredo Sanchez <tritan@mit.edu>
* Makefile.in: Clean up usage of CFLAGS, CPPFLAGS, DEFS, DEFINES,
diff --git a/src/appl/telnet/libtelnet/gettytab.c b/src/appl/telnet/libtelnet/gettytab.c
index f6ffb7c..aaad43a 100644
--- a/src/appl/telnet/libtelnet/gettytab.c
+++ b/src/appl/telnet/libtelnet/gettytab.c
@@ -98,9 +98,10 @@ nchktc()
/* p now points to beginning of last field */
if (p[0] != 't' || p[1] != 'c')
return(1);
- strcpy(tcname,p+3);
+ strncpy(tcname, p + 3, sizeof(tcname) - 1);
+ tcname[sizeof(tcname) - 1] = '\0';
q = tcname;
- while (q && *q != ':')
+ while (*q && *q != ':')
q++;
*q = 0;
if (++hopcount > MAXHOP) {
diff --git a/src/appl/telnet/libtelnet/kerberos.c b/src/appl/telnet/libtelnet/kerberos.c
index 734466e..eb657ae 100644
--- a/src/appl/telnet/libtelnet/kerberos.c
+++ b/src/appl/telnet/libtelnet/kerberos.c
@@ -602,7 +602,9 @@ kerberos4_status(ap, name, level)
return(level);
if (UserNameRequested && !kuserok(&adat, UserNameRequested)) {
- strcpy(name, UserNameRequested);
+ /* the name buffer comes from telnetd/telnetd{-ktd}.c */
+ strncpy(name, UserNameRequested, 255);
+ name[255] = '\0';
return(AUTH_VALID);
} else
return(AUTH_USER);
diff --git a/src/appl/telnet/libtelnet/kerberos5.c b/src/appl/telnet/libtelnet/kerberos5.c
index 6a62f36..b4c7398 100644
--- a/src/appl/telnet/libtelnet/kerberos5.c
+++ b/src/appl/telnet/libtelnet/kerberos5.c
@@ -423,7 +423,8 @@ kerberos5_is(ap, data, cnt)
NULL, keytabid, NULL, &ticket);
if (r) {
(void) strcpy(errbuf, "krb5_rd_req failed: ");
- (void) strcat(errbuf, error_message(r));
+ errbuf[sizeof(errbuf) - 1] = '\0';
+ (void) strncat(errbuf, error_message(r), sizeof(errbuf) - 1 - strlen(errbuf));
goto errout;
}
@@ -440,8 +441,12 @@ kerberos5_is(ap, data, cnt)
princ[krb5_princ_component(telnet_context,
ticket->server,0)->length] = '\0';
if (strcmp("host", princ)) {
- (void) sprintf(errbuf, "incorrect service name: \"%s\" != \"%s\"",
- princ, "host");
+ if(strlen(princ) < sizeof(errbuf) - 39) {
+ (void) sprintf(errbuf, "incorrect service name: \"%s\" != \"host\"",
+ princ);
+ } else {
+ (void) sprintf(errbuf, "incorrect service name: principal != \"host\"");
+ }
goto errout;
}
} else {
@@ -455,7 +460,8 @@ kerberos5_is(ap, data, cnt)
if (r) {
(void) strcpy(errbuf,
"krb5_auth_con_getauthenticator failed: ");
- (void) strcat(errbuf, error_message(r));
+ errbuf[sizeof(errbuf) - 1] = '\0';
+ (void) strncat(errbuf, error_message(r), sizeof(errbuf) - 1 - strlen(errbuf));
goto errout;
}
if ((ap->way & AUTH_ENCRYPT_MASK) == AUTH_ENCRYPT_ON &&
@@ -476,7 +482,8 @@ kerberos5_is(ap, data, cnt)
&key);
if (r) {
(void) strcpy(errbuf, "krb5_auth_con_getkey failed: ");
- (void) strcat(errbuf, error_message(r));
+ errbuf[sizeof(errbuf) - 1] = '\0';
+ (void) strncat(errbuf, error_message(r), sizeof(errbuf) - 1 - strlen(errbuf));
goto errout;
}
r = krb5_verify_checksum(telnet_context,
@@ -495,7 +502,8 @@ kerberos5_is(ap, data, cnt)
if (r) {
(void) strcpy(errbuf,
"checksum verification failed: ");
- (void) strcat(errbuf, error_message(r));
+ errbuf[sizeof(errbuf) - 1] = '\0';
+ (void) strncat(errbuf, error_message(r), sizeof(errbuf) - 1 - strlen(errbuf));
goto errout;
}
krb5_free_keyblock(telnet_context, key);
@@ -506,7 +514,8 @@ kerberos5_is(ap, data, cnt)
if ((r = krb5_mk_rep(telnet_context, auth_context,
&outbuf))) {
(void) strcpy(errbuf, "Make reply failed: ");
- (void) strcat(errbuf, error_message(r));
+ errbuf[sizeof(errbuf) - 1] = '\0';
+ (void) strncat(errbuf, error_message(r), sizeof(errbuf) - 1 - strlen(errbuf));
goto errout;
}
@@ -560,7 +569,8 @@ kerberos5_is(ap, data, cnt)
char errbuf[128];
(void) strcpy(errbuf, "Read forwarded creds failed: ");
- (void) strcat(errbuf, error_message(r));
+ errbuf[sizeof(errbuf) - 1] = '\0';
+ (void) strncat(errbuf, error_message(r), sizeof(errbuf) - 1 - strlen(errbuf));
Data(ap, KRB_FORWARD_REJECT, errbuf, -1);
if (auth_debug_mode)
printf(
@@ -586,7 +596,8 @@ kerberos5_is(ap, data, cnt)
char eerrbuf[329];
strcpy(eerrbuf, "telnetd: ");
- strcat(eerrbuf, errbuf);
+ eerrbuf[sizeof(eerrbuf) - 1] = '\0';
+ strncat(eerrbuf, errbuf, sizeof(eerrbuf) - 1 - strlen(eerrbuf));
Data(ap, KRB_REJECT, eerrbuf, -1);
}
if (auth_debug_mode)
@@ -706,7 +717,9 @@ kerberos5_status(ap, name, level)
krb5_kuserok(telnet_context, ticket->enc_part2->client,
UserNameRequested))
{
- strcpy(name, UserNameRequested);
+ /* the name buffer comes from telnetd/telnetd{-ktd}.c */
+ strncpy(name, UserNameRequested, 255);
+ name[255] = '\0';
return(AUTH_VALID);
} else
return(AUTH_USER);
diff --git a/src/appl/telnet/libtelnet/spx.c b/src/appl/telnet/libtelnet/spx.c
index f23490f..7285d0d 100644
--- a/src/appl/telnet/libtelnet/spx.c
+++ b/src/appl/telnet/libtelnet/spx.c
@@ -173,7 +173,8 @@ spx_init(ap, server)
str_data[3] = TELQUAL_REPLY;
gethostname(lhostname, sizeof(lhostname));
strcpy(targ_printable, "SERVICE:rcmd@");
- strcat(targ_printable, lhostname);
+ strncat(targ_printable, lhostname, sizeof(targ_printable) - 1 - 13);
+ targ_printable[sizeof(targ_printable) - 1] = '\0';
input_name_buffer.length = strlen(targ_printable);
input_name_buffer.value = targ_printable;
major_status = gss_import_name(&status,
@@ -216,7 +217,8 @@ spx_send(ap)
printf("[ Trying SPX ... ]\n");
strcpy(targ_printable, "SERVICE:rcmd@");
- strcat(targ_printable, RemoteHostName);
+ strncat(targ_printable, RemoteHostName, sizeof(targ_printable) - 1 - 13);
+ targ_printable[sizeof(targ_printable) - 1] = '\0';
input_name_buffer.length = strlen(targ_printable);
input_name_buffer.value = targ_printable;
@@ -324,7 +326,8 @@ spx_is(ap, data, cnt)
gethostname(lhostname, sizeof(lhostname));
strcpy(targ_printable, "SERVICE:rcmd@");
- strcat(targ_printable, lhostname);
+ strncat(targ_printable, lhostname, sizeof(targ_printable) - 1 - 13);
+ targ_printable[sizeof(targ_printable) - 1] = '\0';
input_name_buffer.length = strlen(targ_printable);
input_name_buffer.value = targ_printable;
@@ -479,7 +482,7 @@ spx_status(ap, name, level)
gss_buffer_desc fullname_buffer, acl_file_buffer;
gss_OID fullname_type;
- char acl_file[160], fullname[160];
+ char acl_file[MAXPATHLEN], fullname[160];
int major_status, status = 0;
struct passwd *pwd;
@@ -494,8 +497,9 @@ spx_status(ap, name, level)
return(AUTH_USER); /* not authenticated */
}
- strcpy(acl_file, pwd->pw_dir);
- strcat(acl_file, "/.sphinx");
+ acl_file[sizeof(acl_file) - 1] = '\0';
+ strncpy(acl_file, pwd->pw_dir, sizeof(acl_file) - 1);
+ strncat(acl_file, "/.sphinx", sizeof(acl_file) - 1 - strlen(acl_file));
acl_file_buffer.value = acl_file;
acl_file_buffer.length = strlen(acl_file);
@@ -511,7 +515,9 @@ spx_status(ap, name, level)
&acl_file_buffer);
if (major_status == GSS_S_COMPLETE) {
- strcpy(name, UserNameRequested);
+ /* the name buffer comes from telnetd/telnetd{-ktd}.c */
+ strncpy(name, UserNameRequested, 255);
+ name[255] = '\0';
return(AUTH_VALID);
} else {
return(AUTH_USER);
diff --git a/src/appl/telnet/telnet/ChangeLog b/src/appl/telnet/telnet/ChangeLog
index d8a341e..b8f209c 100644
--- a/src/appl/telnet/telnet/ChangeLog
+++ b/src/appl/telnet/telnet/ChangeLog
@@ -1,3 +1,18 @@
+2000-05-11 Nalin Dahyabhai <nalin@redhat.com>
+
+ * commands.c (makeargv): Don't overflow buffer "saveline".
+ (tn): Don't overflow buffer "_hostname".
+ (cmdrc): Don't overflow buffer "m1save".
+ * externs.h: Include the size of "tline", so that we can check for
+ overflows elsewhere.
+ * main.c(main, tn370): Don't overflow buffer "tline".
+ * utilities.c (SetNetTrace): Don't overflow buffer "NetTraceFile".
+
+2000-04-28 Nalin Dahyabhai <nalin@redhat.com>
+
+ * commands.c (cmdrc): Don't overflow buffer "rcbuf".
+ * tn3270.c (settranscom): Don't overflow buffer "transcom".
+
2000-02-24 Ezra Peisach <epeisach@mit.edu>
* configure.in: Remove dependency on libdes425 when krb4 support
diff --git a/src/appl/telnet/telnet/commands.c b/src/appl/telnet/telnet/commands.c
index 2c80b0b..8ffba2e 100644
--- a/src/appl/telnet/telnet/commands.c
+++ b/src/appl/telnet/telnet/commands.c
@@ -138,7 +138,9 @@ makeargv()
margc = 0;
cp = line;
if (*cp == '!') { /* Special case shell escape */
- strcpy(saveline, line); /* save for shell command */
+ strncpy(saveline, line, sizeof(saveline) - 1);
+ /* save for shell command */
+ saveline[sizeof(saveline) - 1] = '\0';
*argp++ = "!"; /* No room in string to get this */
margc++;
cp++;
@@ -2450,7 +2452,8 @@ tn(argc, argv)
if (temp & 0xffffffff != INADDR_NONE) {
sin.sin_addr.s_addr = temp;
sin.sin_family = AF_INET;
- (void) strcpy(_hostname, hostp);
+ (void) strncpy(_hostname, hostp, sizeof(_hostname) - 1);
+ _hostname[sizeof(_hostname) - 1] = '\0';
hostname = _hostname;
} else {
host = gethostbyname(hostp);
@@ -2855,16 +2858,18 @@ cmdrc(m1, m2)
if (skiprc)
return;
- strcpy(m1save, m1);
+ strncpy(m1save, m1, sizeof(m1save) - 1);
+ m1save[sizeof(m1save) - 1] = '\0';
m1 = m1save;
if (rcname == 0) {
rcname = getenv("HOME");
if (rcname)
- strcpy(rcbuf, rcname);
+ strncpy(rcbuf, rcname, sizeof(rcbuf) - 1);
else
rcbuf[0] = '\0';
- strcat(rcbuf, "/.telnetrc");
+ rcbuf[sizeof(rcbuf) - 1] = '\0';
+ strncat(rcbuf, "/.telnetrc", sizeof(rcbuf) - 1 - strlen(rcbuf));
rcname = rcbuf;
}
diff --git a/src/appl/telnet/telnet/externs.h b/src/appl/telnet/telnet/externs.h
index e993986..f35cded 100644
--- a/src/appl/telnet/telnet/externs.h
+++ b/src/appl/telnet/telnet/externs.h
@@ -486,7 +486,7 @@ extern char
*Ibackp, /* Oldest byte of 3270 data */
Ibuf[], /* 3270 buffer */
*Ifrontp, /* Where next 3270 byte goes */
- tline[],
+ tline[200],
*transcom; /* Transparent command */
extern int
diff --git a/src/appl/telnet/telnet/main.c b/src/appl/telnet/telnet/main.c
index da98ae6..7696857 100644
--- a/src/appl/telnet/telnet/main.c
+++ b/src/appl/telnet/telnet/main.c
@@ -274,7 +274,8 @@ main(argc, argv)
case 't':
#if defined(TN3270) && defined(unix)
transcom = tline;
- (void)strcpy(transcom, optarg);
+ (void)strncpy(transcom, optarg, sizeof(tline) - 1);
+ tline[sizeof(tline) - 1] = '\0';
#else
fprintf(stderr,
"%s: Warning: -t ignored, no TN3270 support.\n",
diff --git a/src/appl/telnet/telnet/tn3270.c b/src/appl/telnet/telnet/tn3270.c
index 77aedaf..c46ae7e 100644
--- a/src/appl/telnet/telnet/tn3270.c
+++ b/src/appl/telnet/telnet/tn3270.c
@@ -397,10 +397,11 @@ settranscom(argc, argv)
return 1;
}
transcom = tline;
- (void) strcpy(transcom, argv[1]);
+ (void) strncpy(transcom, argv[1], sizeof(tline) - 1);
+ tline[sizeof(tline) - 1] = '\0';
for (i = 2; i < argc; ++i) {
- (void) strcat(transcom, " ");
- (void) strcat(transcom, argv[i]);
+ (void) strncat(transcom, " ", sizeof(tline) - 1 - (transcom - tline));
+ (void) strncat(transcom, argv[i], sizeof(tline) - 1 - (transcom - tline));
}
return 1;
}
diff --git a/src/appl/telnet/telnet/utilities.c b/src/appl/telnet/telnet/utilities.c
index 19f503b..82ad841 100644
--- a/src/appl/telnet/telnet/utilities.c
+++ b/src/appl/telnet/telnet/utilities.c
@@ -113,13 +113,15 @@ SetNetTrace(file)
if (file && (strcmp(file, "-") != 0)) {
NetTrace = fopen(file, "w");
if (NetTrace) {
- strcpy((char *)NetTraceFile, file);
+ strncpy((char *)NetTraceFile, file, sizeof(NetTraceFile) - 1);
+ NetTraceFile[sizeof(NetTraceFile) - 1] = '\0';
return;
}
fprintf(stderr, "Cannot open %s.\n", file);
}
NetTrace = stdout;
- strcpy((char *)NetTraceFile, "(standard output)");
+ strncpy((char *)NetTraceFile, "(standard output)", sizeof(NetTraceFile) - 1);
+ NetTraceFile[sizeof(NetTraceFile) - 1] = '\0';
}
void
diff --git a/src/appl/telnet/telnetd/ChangeLog b/src/appl/telnet/telnetd/ChangeLog
index 800c9f8..ce2686f 100644
--- a/src/appl/telnet/telnetd/ChangeLog
+++ b/src/appl/telnet/telnetd/ChangeLog
@@ -1,3 +1,16 @@
+2000-06-29 Tom Yu <tlyu@mit.edu>
+
+ * telnetd.c (doit): Change test for "no authentication" as per
+ Jeffrey Altman's patch.
+
+2000-06-29 Nalin Dahyabhai <nalin@redhat.com>
+
+ * sys_term.c (start_login, Solaris): forcefully terminate "termbuf"
+ in case the "TERM" environment variable isn't.
+ * telnet-ktd.c (getterminaltype): Don't overflow buffers "first" and
+ "netobuf".
+ (recv_ayt): Forcibly terminate buffer "netobuf".
+
2000-05-31 Wilfredo Sanchez <tritan@mit.edu>
* configure.in, defs.h: Check for existance of <memory.h>.
diff --git a/src/appl/telnet/telnetd/sys_term.c b/src/appl/telnet/telnetd/sys_term.c
index ee8d53d..b79209d 100644
--- a/src/appl/telnet/telnetd/sys_term.c
+++ b/src/appl/telnet/telnetd/sys_term.c
@@ -1257,6 +1257,7 @@ start_login(host, autologin, name)
} else {
strcpy(termbuf, "TERM=");
strncat(termbuf, term, sizeof(termbuf) - 6);
+ termbuf[sizeof(termbuf) - 1] = '\0';
term = termbuf;
}
argv = addarg(argv, term);
diff --git a/src/appl/telnet/telnetd/telnetd-ktd.c b/src/appl/telnet/telnetd/telnetd-ktd.c
index 9ec608f..5936e3b 100644
--- a/src/appl/telnet/telnetd/telnetd-ktd.c
+++ b/src/appl/telnet/telnetd/telnetd-ktd.c
@@ -360,7 +360,7 @@ main(argc, argv)
}
(void) setsockopt(s, SOL_SOCKET, SO_REUSEADDR,
(char *)&on, sizeof(on));
- if (bind(s, (struct sockaddr *)&sin, sizeof sin) < 0) {
+ if (bind(s, (struct sockaddr *)&sin, sizeof(sin)) < 0) {
perror("bind");
exit(1);
}
@@ -368,7 +368,7 @@ main(argc, argv)
perror("listen");
exit(1);
}
- foo = sizeof sin;
+ foo = sizeof(sin);
ns = accept(s, (struct sockaddr *)&sin, &foo);
if (ns < 0) {
perror("accept");
@@ -548,25 +548,33 @@ getterminaltype(name)
if (his_state_is_will(TELOPT_TSPEED)) {
static char sbbuf[] = { IAC, SB, TELOPT_TSPEED, TELQUAL_SEND, IAC, SE };
- memcpy(nfrontp, sbbuf, sizeof sbbuf);
- nfrontp += sizeof sbbuf;
+ if(nfrontp - netobuf + sizeof(sbbuf) < sizeof(netobuf)) {
+ memcpy(nfrontp, sbbuf, sizeof(sbbuf));
+ nfrontp += sizeof(sbbuf);
+ }
}
if (his_state_is_will(TELOPT_XDISPLOC)) {
static char sbbuf[] = { IAC, SB, TELOPT_XDISPLOC, TELQUAL_SEND, IAC, SE };
- memcpy(nfrontp, sbbuf, sizeof sbbuf);
- nfrontp += sizeof sbbuf;
+ if(nfrontp - netobuf + sizeof(sbbuf) < sizeof(netobuf)) {
+ memcpy(nfrontp, sbbuf, sizeof(sbbuf));
+ nfrontp += sizeof(sbbuf);
+ }
}
if (his_state_is_will(TELOPT_ENVIRON)) {
static char sbbuf[] = { IAC, SB, TELOPT_ENVIRON, TELQUAL_SEND, IAC, SE };
- memcpy(nfrontp, sbbuf, sizeof sbbuf);
- nfrontp += sizeof sbbuf;
+ if(nfrontp - netobuf + sizeof(sbbuf) < sizeof(netobuf)) {
+ memcpy(nfrontp, sbbuf, sizeof(sbbuf));
+ nfrontp += sizeof(sbbuf);
+ }
}
if (his_state_is_will(TELOPT_TTYPE)) {
- memcpy(nfrontp, ttytype_sbbuf, sizeof ttytype_sbbuf);
- nfrontp += sizeof ttytype_sbbuf;
+ if(nfrontp - netobuf + sizeof(ttytype_sbbuf) < sizeof(netobuf)) {
+ memcpy(nfrontp, ttytype_sbbuf, sizeof(ttytype_sbbuf));
+ nfrontp += sizeof(ttytype_sbbuf);
+ }
}
if (his_state_is_will(TELOPT_TSPEED)) {
while (sequenceIs(tspeedsubopt, baseline))
@@ -591,12 +599,14 @@ getterminaltype(name)
* we have to just go with what we (might) have already gotten.
*/
if (his_state_is_will(TELOPT_TTYPE) && !terminaltypeok(terminaltype)) {
- (void) strncpy(first, terminaltype, sizeof(first));
+ (void) strncpy(first, terminaltype, sizeof(first) - 1);
+ first[sizeof(first) - 1] = '\0';
for(;;) {
/*
* Save the unknown name, and request the next name.
*/
- (void) strncpy(last, terminaltype, sizeof(last));
+ (void) strncpy(last, terminaltype, sizeof(last) - 1);
+ last[sizeof(last) - 1] = '\0';
_gettermname();
if (terminaltypeok(terminaltype))
break;
@@ -615,7 +625,8 @@ getterminaltype(name)
*/
_gettermname();
if (strncmp(first, terminaltype, sizeof(first)) != 0)
- (void) strncpy(terminaltype, first, sizeof(first));
+ (void) strncpy(terminaltype, first, sizeof(terminaltype) - 1);
+ terminaltype[sizeof(terminaltype) - 1] = '\0';
break;
}
}
@@ -635,8 +646,8 @@ _gettermname()
if (his_state_is_wont(TELOPT_TTYPE))
return;
settimer(baseline);
- memcpy(nfrontp, ttytype_sbbuf, sizeof ttytype_sbbuf);
- nfrontp += sizeof ttytype_sbbuf;
+ memcpy(nfrontp, ttytype_sbbuf, sizeof(ttytype_sbbuf));
+ nfrontp += sizeof(ttytype_sbbuf);
while (sequenceIs(ttypesubopt, baseline))
ttloop();
}
@@ -922,7 +933,7 @@ telnet(f, p, host)
#if defined(SO_OOBINLINE)
(void) setsockopt(net, SOL_SOCKET, SO_OOBINLINE,
- (char *)&on, sizeof on);
+ (char *)&on, sizeof(on));
#endif /* defined(SO_OOBINLINE) */
#ifdef SIGTSTP
@@ -989,8 +1000,10 @@ telnet(f, p, host)
HE = getstr("he", &cp);
HN = getstr("hn", &cp);
IM = getstr("im", &cp);
- if (HN && *HN)
- (void) strcpy(host_name, HN);
+ if (HN && *HN) {
+ (void) strncpy(host_name, HN, sizeof(host_name) - 1);
+ host_name[sizeof(host_name) - 1] = '\0';
+ }
if (IM == 0)
IM = "";
} else {
@@ -1426,8 +1439,10 @@ recv_ayt()
return;
}
#endif
- (void) strcpy(nfrontp, "\r\n[Yes]\r\n");
+ (void) strncpy(nfrontp, "\r\n[Yes]\r\n",
+ sizeof(netobuf) - 1 - (nfrontp - netobuf));
nfrontp += 9;
+ *nfrontp = '\0';
}
void
diff --git a/src/appl/telnet/telnetd/telnetd.c b/src/appl/telnet/telnetd/telnetd.c
index 7267469..f103488 100644
--- a/src/appl/telnet/telnetd/telnetd.c
+++ b/src/appl/telnet/telnetd/telnetd.c
@@ -522,7 +522,7 @@ main(argc, argv)
}
(void) setsockopt(s, SOL_SOCKET, SO_REUSEADDR,
(char *)&on, sizeof(on));
- if (bind(s, (struct sockaddr *)&sin, sizeof sin) < 0) {
+ if (bind(s, (struct sockaddr *)&sin, sizeof(sin)) < 0) {
perror("bind");
exit(1);
}
@@ -530,7 +530,7 @@ main(argc, argv)
perror("listen");
exit(1);
}
- foo = sizeof sin;
+ foo = sizeof(sin);
ns = accept(s, (struct sockaddr *)&sin, &foo);
if (ns < 0) {
perror("accept");
@@ -781,34 +781,49 @@ getterminaltype(name)
static unsigned char sb[] =
{ IAC, SB, TELOPT_TSPEED, TELQUAL_SEND, IAC, SE };
- memcpy(nfrontp, sb, sizeof sb);
- nfrontp += sizeof sb;
+ if(nfrontp - netobuf + sizeof(sb) < sizeof(netobuf)) {
+ memcpy(nfrontp, sb, sizeof(sb));
+ nfrontp += sizeof(sb);
+ *nfrontp = '\0';
+ }
}
if (his_state_is_will(TELOPT_XDISPLOC)) {
static unsigned char sb[] =
{ IAC, SB, TELOPT_XDISPLOC, TELQUAL_SEND, IAC, SE };
- memcpy(nfrontp, sb, sizeof sb);
- nfrontp += sizeof sb;
+ if(nfrontp - netobuf + sizeof(sb) < sizeof(netobuf)) {
+ memcpy(nfrontp, sb, sizeof(sb));
+ nfrontp += sizeof(sb);
+ *nfrontp = '\0';
+ }
}
if (his_state_is_will(TELOPT_NEW_ENVIRON)) {
static unsigned char sb[] =
{ IAC, SB, TELOPT_NEW_ENVIRON, TELQUAL_SEND, IAC, SE };
- memcpy(nfrontp, sb, sizeof sb);
- nfrontp += sizeof sb;
+ if(nfrontp - netobuf + sizeof(sb) < sizeof(netobuf)) {
+ memcpy(nfrontp, sb, sizeof(sb));
+ nfrontp += sizeof(sb);
+ *nfrontp = '\0';
+ }
}
else if (his_state_is_will(TELOPT_OLD_ENVIRON)) {
static unsigned char sb[] =
{ IAC, SB, TELOPT_OLD_ENVIRON, TELQUAL_SEND, IAC, SE };
- memcpy(nfrontp, sb, sizeof sb);
- nfrontp += sizeof sb;
+ if(nfrontp - netobuf + sizeof(sb) < sizeof(netobuf)) {
+ memcpy(nfrontp, sb, sizeof(sb));
+ nfrontp += sizeof(sb);
+ *nfrontp = '\0';
+ }
}
if (his_state_is_will(TELOPT_TTYPE)) {
- memcpy(nfrontp, ttytype_sbbuf, sizeof ttytype_sbbuf);
- nfrontp += sizeof ttytype_sbbuf;
+ if(nfrontp - netobuf + sizeof(ttytype_sbbuf) < sizeof(netobuf)) {
+ memcpy(nfrontp, ttytype_sbbuf, sizeof(ttytype_sbbuf));
+ nfrontp += sizeof(ttytype_sbbuf);
+ *nfrontp = '\0';
+ }
}
if (his_state_is_will(TELOPT_TSPEED)) {
while (sequenceIs(tspeedsubopt, baseline))
@@ -886,8 +901,11 @@ _gettermname()
if (his_state_is_wont(TELOPT_TTYPE))
return;
settimer(baseline);
- memcpy(nfrontp, ttytype_sbbuf, sizeof ttytype_sbbuf);
- nfrontp += sizeof ttytype_sbbuf;
+ if(nfrontp - netobuf + sizeof(ttytype_sbbuf)) {
+ memcpy(nfrontp, ttytype_sbbuf, sizeof(ttytype_sbbuf));
+ nfrontp += sizeof(ttytype_sbbuf);
+ *nfrontp = '\0';
+ }
while (sequenceIs(ttypesubopt, baseline))
ttloop();
}
@@ -1009,7 +1027,7 @@ pty_init();
setenv("TERM", *terminaltype ? terminaltype : "network", 1);
#if defined (AUTHENTICATION)
- if (user_name[0] == '\0') {
+ if (level < 0 && auth_level > 0) {
fatal (net, "No authentication provided");
exit (-1);
}
@@ -1205,7 +1223,7 @@ telnet(f, p, host)
#if defined(SO_OOBINLINE)
(void) setsockopt(net, SOL_SOCKET, SO_OOBINLINE,
- (char *)&on, sizeof on);
+ (char *)&on, sizeof(on));
#endif /* defined(SO_OOBINLINE) */
#ifdef SIGTSTP
@@ -1266,7 +1284,8 @@ telnet(f, p, host)
HN = getstr("hn", &cp);
IM = getstr("im", &cp);
if (HN && *HN)
- (void) strcpy(host_name, HN);
+ (void) strncpy(host_name, HN, sizeof(host_name) - 1);
+ host_name[sizeof(host_name) - 1] = '\0';
if (IM == 0)
IM = "";
} else {
@@ -1688,8 +1707,10 @@ recv_ayt()
return;
}
#endif
- (void) strcpy(nfrontp, "\r\n[Yes]\r\n");
+ (void) strncpy(nfrontp, "\r\n[Yes]\r\n",
+ sizeof(netobuf) - 1 - (nfrontp - netobuf));
nfrontp += 9;
+ *nfrontp = '\0';
}
void