Skip Menu |
 

Download (untitled) / with headers
text/plain 9.6KiB
From schwim@whatmore.Stanford.EDU Wed May 20 20:51:59 1998
Received: from MIT.EDU (SOUTH-STATION-ANNEX.MIT.EDU [18.72.1.2]) by rt-11.MIT.EDU (8.7.5/8.7.3) with SMTP id UAA18772 for <bugs@RT-11.MIT.EDU>; Wed, 20 May 1998 20:51:54 -0400
Received: from whatmore.Stanford.EDU by MIT.EDU with SMTP
id AA21291; Wed, 20 May 98 20:51:46 EDT
Received: (from schwim@localhost)
by whatmore.Stanford.EDU (8.8.8/8.8.8) id RAA27759;
Wed, 20 May 1998 17:51:51 -0700 (PDT)
Message-Id: <199805210051.RAA27759@whatmore.Stanford.EDU>
Date: Wed, 20 May 1998 17:51:51 -0700 (PDT)
From: Larry Schwimmer <schwim@whatmore.Stanford.EDU>
To: krb5-bugs@MIT.EDU
Subject: PATCH: appl/bsd/kcmd.c

Show quoted text
>Number: 592
>Category: krb5-appl
>Synopsis: kcmd connection optimization, krb4 support
>Confidential: no
>Severity: non-critical
>Priority: medium
>Responsible: krb5-unassigned
>State: open
>Class: change-request
>Submitter-Id: unknown
>Arrival-Date: Wed May 20 20:52:00 EDT 1998
>Last-Modified: Fri Sep 14 11:45:15 EDT 2001
>Originator: Larry Schwimmer
>Organization:
Stanford University
Show quoted text
>Release: krb5-1.0.5
>Environment:
ALL
Show quoted text
>Description:

1) connection optimization

The appl/bsd clients which use kcmd are non-optimal in
failure. They first make a connection and then perform a sendauth
call. For cases when there is no ticket, it is a waste to initiate a
connection since the sendauth call will never succeed. The first part
of this patch moves the credential cache check before the connection
is created so that unnecessary connections are not made.

2) krb4 support

The second part of the patch adds k4cmd, which is based on the
krb4 kcmd with updates from the krb5 kcmd source. The purpose of this
code is to add krb4 fallback support to rsh and rlogin. We are in the
process of migrating to krb5 and having support for both krb4 and krb5
is a prerequisite for the transition.
Portions of the patches for krlogin.c and krsh.c that I will
be sending depend on this patch.

Show quoted text
>How-To-Repeat:
>Fix:

Patch below.

yours,
Larry Schwimmer
schwim@leland.stanford.edu
Leland Systems Group


--- appl/bsd/kcmd.c.orig Fri Feb 6 19:41:16 1998
+++ appl/bsd/kcmd.c Tue Apr 21 15:38:59 1998
@@ -156,6 +156,18 @@
krb5_princ_set_realm_length(bsd_context,get_cred->server,strlen(realm));
krb5_princ_set_realm_data(bsd_context,get_cred->server,strdup(realm));
}
+
+ if (status = krb5_cc_default(bsd_context, &cc)) {
+ krb5_free_creds(bsd_context, get_cred);
+ return status;
+ }
+
+ if (status = krb5_cc_get_principal(bsd_context, cc, &get_cred->client)) {
+ (void) krb5_cc_close(bsd_context, cc);
+ krb5_free_creds(bsd_context, get_cred);
+ return status;
+ }
+
#ifdef POSIX_SIGNALS
sigemptyset(&urgmask);
sigaddset(&urgmask, SIGURG);
@@ -267,14 +279,6 @@
goto bad2;
}

- if (status = krb5_cc_default(bsd_context, &cc))
- goto bad2;
-
- if (status = krb5_cc_get_principal(bsd_context, cc, &get_cred->client)) {
- (void) krb5_cc_close(bsd_context, cc);
- goto bad2;
- }
-
/* Get ticket from credentials cache or kdc */
status = krb5_get_credentials(bsd_context, 0, cc, get_cred, &ret_cred);
krb5_free_creds(bsd_context, get_cred);
@@ -448,3 +452,256 @@

#endif

+#ifdef KRB5_KRB4_COMPAT
+#include <kerberosIV/krb.h>
+#include <kerberosIV/kparse.h>
+
+k4cmd(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;
+KRB4_32 authopts;
+{
+ int s, timo = 1, pid;
+#ifdef POSIX_SIGNALS
+ sigset_t oldmask, urgmask;
+#else
+ long oldmask;
+#endif /* POSIX_SIGNALS */
+ struct sockaddr_in sin, from, local_laddr;
+ char c;
+ int lport = START_PORT;
+ struct hostent *hp;
+ int rc;
+ char *host_save;
+ int status;
+
+ pid = getpid();
+ hp = gethostbyname(*ahost);
+ if (hp == 0) {
+ fprintf(stderr, "%s: unknown host\n", *ahost);
+ return (-1);
+ }
+ if ((host_save = malloc(strlen(hp->h_name) + 1)) == NULL) {
+ fprintf(stderr,"k4cmd: no memory\n");
+ return -1;
+ }
+ strcpy(host_save, hp->h_name);
+
+ /* If realm is null, look up from table */
+ if ((realm == NULL) || (realm[0] == '\0')) {
+ realm = (char *)krb_realmofhost(host_save);
+ }
+
+ /* Avoid making a useless connection by first ensuring that
+ * a tgt exists. Unless it does, the sendauth will fail.
+ */
+ if (cred != (CREDENTIALS *)0) {
+ char lrealm[REALM_SZ];
+
+ if ((status = krb_get_tf_realm(TKT_FILE, lrealm)) != KSUCCESS)
+ return(status);
+
+ status = krb_get_cred("krbtgt",realm,lrealm,cred);
+
+ if (status != KSUCCESS &&
+ (strncmp(realm, lrealm, REALM_SZ)) == 0)
+ return status;
+ }
+#ifdef POSIX_SIGNALS
+ sigemptyset(&urgmask);
+ sigaddset(&urgmask,SIGURG);
+ sigprocmask(SIG_BLOCK,&urgmask,&oldmask);
+#else
+ oldmask = sigblock(sigmask(SIGURG));
+#endif /* POSIX_SIGNALS */
+ for (;;) {
+ s = getport(&lport);
+ if (s < 0) {
+ if (errno == EAGAIN)
+ fprintf(stderr, "socket: All ports in use\n");
+ else
+ perror("rcmd: socket");
+#ifdef POSIX_SIGNALS
+ sigprocmask(SIG_SETMASK,&oldmask,NULL);
+#else
+ sigsetmask(oldmask);
+#endif /* POSIX_SIGNALS */
+ return (-1);
+ }
+ sin.sin_family = hp->h_addrtype;
+ memcpy((caddr_t)&sin.sin_addr,hp->h_addr,sizeof(sin.sin_addr));
+ sin.sin_port = rport;
+ if (connect(s, (struct sockaddr *)&sin, sizeof (sin)) >= 0)
+ break;
+ (void) close(s);
+ if (errno == EADDRINUSE) {
+ lport--;
+ continue;
+ }
+#if !(defined(tek) || defined(ultrix) || defined(sun) || defined(SYSV))
+ if (hp->h_addr_list[1] != NULL) {
+ int oerrno = errno;
+
+ fprintf(stderr,
+ "connect to address %s: ", inet_ntoa(sin.sin_addr));
+ errno = oerrno;
+ perror(0);
+ hp->h_addr_list++;
+ memcpy((caddr_t)&sin.sin_addr, hp->h_addr_list[0],
+ sizeof(sin.sin_addr));
+ fprintf(stderr, "Trying %s...\n",
+ inet_ntoa(sin.sin_addr));
+ continue;
+ }
+#endif /* !(defined(ultrix) || defined(sun)) */
+ perror(hp->h_name);
+#ifdef POSIX_SIGNALS
+ sigprocmask(SIG_SETMASK,&oldmask,NULL);
+#else
+ sigsetmask(oldmask);
+#endif /* POSIX_SIGNALS */
+ 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("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("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,
+ "socket: protocol failure in circuit setup.\n");
+ 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); */
+
+ if (!laddr) laddr = &local_laddr;
+ if (!faddr) faddr = &sin;
+ else
+ memcpy(faddr,&sin,sizeof(sin));
+
+ /* 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("getsockname");
+ status = -1;
+ goto bad2;
+ }
+ }
+ if ((status = krb_sendauth(authopts, s, ticket, service, host_save,
+ realm, (unsigned KRB4_32) pid,
+ msg_data,
+ cred, schedule,
+ laddr,
+ faddr,
+ "KCMDV0.1")) != KSUCCESS) {
+ /* this part involves some very intimate knowledge of a
+ particular sendauth implementation to pry out the old bits.
+ This only catches the case of total failure -- but that's
+ the one where we get useful data from the remote end. If
+ we even get an authenticator back, then the problem gets
+ diagnosed locally anyhow. */
+ extern KRB4_32 __krb_sendauth_hidden_tkt_len;
+ char *old_data = (char*)&__krb_sendauth_hidden_tkt_len;
+ if ((status == KFAILURE) && (*old_data == 1)) {
+ write(2, old_data+1, 3);
+ *old_data = (-1);
+ }
+ if ((status == KFAILURE) && (*old_data == -1)) {
+ while (read(s, &c, 1) == 1) {
+ (void) write(2, &c, 1);
+ if (c == '\n')
+ break;
+ }
+ status = -1;
+ }
+ goto bad2;
+ }
+ (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(host_save);
+ } else {
+ fprintf(stderr,"rcmd: 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;
+ }
+#ifdef POSIX_SIGNALS
+ sigprocmask(SIG_SETMASK,&oldmask,NULL);
+#else
+ sigsetmask(oldmask);
+#endif /* POSIX_SIGNALS */
+ *sock = s;
+ return (KSUCCESS);
+ bad2:
+ if (lport)
+ (void) close(*fd2p);
+ bad:
+ (void) close(s);
+#ifdef POSIX_SIGNALS
+ sigprocmask(SIG_SETMASK,&oldmask,NULL);
+#else
+ sigsetmask(oldmask);
+#endif /* POSIX_SIGNALS */
+ return (status);
+}
+#endif /* KRB5_KRB4_COMPAT */
Show quoted text
>Audit-Trail:

Responsible-Changed-From-To: gnats-admin->krb5-unassigned
Responsible-Changed-By: raeburn
Responsible-Changed-When: Fri Sep 14 11:45:09 2001
Responsible-Changed-Why:

reformat/refile

Show quoted text
>Unformatted: