There is a bug in the code for getting AFS tokens in function
send_afs_tokens() in sshconnect1.c
Here is how the bug manifests itself:
If I have an AFS token that is still valid _and_ one that was valid but
is now expired then AFS token forwarding ignores both tokens instead
of forwarding the still valid one.
I can reproduce this problem on Red Hat Linux 7.2 systems with
OpenSSH-3.4p1 (and probably all older versions) compiled with
KTH-Krb4-1.1.1 (this is where the k_pioctl() function comes from; see
below). I am using OpenAFS-1.2.5. The same happens on Solaris 8
(OpenSSH-3.4p1, KTH-Krb4-1.1.1, IBM/Transarc ASF).
Here is the cause for the bug:
The problem is that k_pioctl() returns error code ENOTCONN for _all_
tokens it finds if there is an expired token present.
The loop has to continue in this case although the _data_ returned
by k_pioctl() is invalid. This invalidness can be checked by comparing
the length of the "ClearToken" component with the size of the
ClearToken
struct. In OpenSSH-3.4p1 this condition is checked in sshconnect1.c line
814. But it is wrong to "break" out of the loop because of this
condition.
Jumping to the next token is the correct behavior.
I have attached a (not nicely formatted) patch that fixes this problem.
-- Alf.
-----------------------------------------------------------------------
Alf Wachsmann | e-mail: alfw at slac.stanford.edu
SLAC Computing Service | Phone: +1-650-926-4802
2575 Sand Hill Road, M/S 97 | FAX: +1-650-926-3329
Menlo Park, CA 94025, USA | Office: Bldg. 50/323
-----------------------------------------------------------------------
http://www.slac.stanford.edu/~alfw (PGP)
-----------------------------------------------------------------------
-------------- next part --------------
--- sshconnect1.c.orig Fri Jun 28 13:25:51 2002
+++ sshconnect1.c Fri Jun 28 13:23:56 2002
@@ -797,7 +797,8 @@
parms.in_size = sizeof(i);
parms.out = buf;
parms.out_size = sizeof(buf);
- if (k_pioctl(0, VIOCGETTOK, &parms, 0) != 0)
+ k_pioctl(0, VIOCGETTOK, &parms, 0);
+ if(errno == EDOM)
break;
p = buf;
@@ -811,8 +812,7 @@
/* Get clear token. */
memcpy(&len, p, sizeof(len));
- if (len != sizeof(struct ClearToken))
- break;
+ if (len == sizeof(struct ClearToken)) {
p += sizeof(len);
memcpy(&ct, p, len);
p += len;
@@ -848,6 +848,7 @@
debug("AFS token for cell %s rejected.", server_cell);
else if (type != SSH_SMSG_SUCCESS)
packet_disconnect("Protocol error on AFS token response: %d",
type);
+ }
}
}