[comp.protocols.kerberos] Kerberos and two ethernet ports

jaw@castle.ed.ac.uk (Graeme Wood) (05/22/91)

I have recently attemted to put up kerberos on a Sequent S81.  The
source was the Bones distribution with Eric Young's DES library.

The source compiled ok, but when I run kinit and talked to our kerberos
server I get an authentication error:

sequent$ kinit
EUCS Project Fred (sequent)
Kerberos Initialization
Kerberos name: jaw
kinit: Password incorrect
sequent$

I believe that the problem is caused by the Sequent having two ethernet
ports and kerberos is seeing a request coming from the secondary enet
port with the IP address of the primary enet port in the authenticator 
and so rejects the request thinking that someone is trying to masquerade
as the host. 

Has anyone else seen this problem? Does anybody have any ideas as to
what could be happening and how I could fix it or work around it?

Graeme Wood
(Graeme.Wood@edinburgh.ac.uk)

davided@sco.COM (Dave Edmondson) (05/23/91)

jaw# I believe that the problem is caused by the Sequent having two
jaw# ethernet ports and kerberos is seeing a request coming from the
jaw# secondary enet port with the IP address of the primary enet port
jaw# in the authenticator and so rejects the request thinking that
jaw# someone is trying to masquerade as the host.
i have seen this problem too, and i recall that people at athena knew
about it.

jaw# Has anyone else seen this problem? Does anybody have any ideas as
jaw# to what could be happening and how I could fix it or work around
jaw# it?
three solutions suggest thenselves:
	1) get v5.  as i understand it (not read the v5 spec for quite
	a while) v5 will allow multiple addresses, and even multiple
	protocol families to be passed around in tickets.
	2) somewhere in libkrb (krb_rd_req springs to mind) is the
	place where the address check is performed.  you could add a
	reverse lookup here and check all of the hosts addresses
	against that which originated the packet.  the problem with
	this is that the name server is not a secure service, so it's
	reasonably easy to start spoofing.  the was a paper written
	about doing a secure nameserver, but i don't know if it ever
	got anywhere.
	3) fix your kernel.  somewhere in the code which emits ip
	packets is that part which inserts the correct ip address for
	the port from which the packet will travel.  it seems quite an
	easy change to make all packets be transmitted with the same
	address (ie the principal one).  i recall hearing that 4.4bsd
	does this.  this could introduce problems (inefficiencies
	really) when routing replies though.
last time i hit the problem, i went for solution 2, and just had to
cope with the occasional loss in security where multi-interface hosts
were concerned.

dave.
---
          Dave Edmondson, Santa Cruz Operation, davided@sco.com
  ``All those lines and circles, to me a mystery.'' -- Ten Thousand Maniacs

sjl@doc.imperial.ac.uk (Steve Lacey) (05/23/91)

Excerpts from kerberos: 22-May-91 Kerberos and two ethernet p.. Graeme
Wood@castle.ed.ac (847)


> I have recently attemted to put up kerberos on a Sequent S81.  The
> source was the Bones distribution with Eric Young's DES library.

> The source compiled ok, but when I run kinit and talked to our kerberos
> server I get an authentication error:

> sequent$ kinit
> EUCS Project Fred (sequent)
> Kerberos Initialization
> Kerberos name: jaw
> kinit: Password incorrect
> sequent$

> I believe that the problem is caused by the Sequent having two ethernet
> ports and kerberos is seeing a request coming from the secondary enet
> port with the IP address of the primary enet port in the authenticator 
> and so rejects the request thinking that someone is trying to masquerade
> as the host. 

> Has anyone else seen this problem? Does anybody have any ideas as to
> what could be happening and how I could fix it or work around it?

We had exactly the same problem. It is caused in krb_rd_req(),
basically, kerberos checks to see if the address the request was
received from is the same as that was put in the ticket. Now this is
liable to be the first in the list of addresses in the hostent. Problems
occur if the packet was sent out over a different interface. 

This can be cured by iterating over all addresses returned by
gethostbyaddr(), and is in fact what we do.

Of course, this can be spoofed by a fake hesiod server...

> Graeme Wood
> (Graeme.Wood@edinburgh.ac.uk)

Steve.
-----
Steve J Lacey, Systems Group.      (In my opinion, my opinions are just that.)
Department of Computing, Imperial College of Science, Technology and Medicine,
180 Queen's Gate, London SW7. Phone : 071 589 5111 x5085, Fax : 071 581 8024 
Email: sjl@doc.ic.ac.uk (sjl%uk.ac.ic.doc@nsfnet-relay.ac.uk), ..!ukc!icdoc!sjl

               Hold the MAYO & pass the COSMIC AWARENESS...

galina@watson.ibm.com_ (Galina Kofman) (05/23/91)

In  <10452@castle.ed.ac.uk>  jaw@castle.ed.ac.uk (Graeme Wood) writes:
>
> I have recently attemted to put up kerberos on a Sequent S81.  The
> source was the Bones distribution with Eric Young's DES library.
>
> The source compiled ok, but when I run kinit and talked to our kerberos
> server I get an authentication error:
>
> sequent$ kinit
> EUCS Project Fred (sequent)
> Kerberos Initialization
> Kerberos name: jaw
> kinit: Password incorrect
> sequent$
>
> I believe that the problem is caused by the Sequent having two ethernet
> ports and kerberos is seeing a request coming from the secondary enet
> port with the IP address of the primary enet port in the authenticator
> and so rejects the request thinking that someone is trying to masquerade
> as the host.
>
> Has anyone else seen this problem? Does anybody have any ideas as to
> what could be happening and how I could fix it or work around it?
>
> Graeme Wood
> (Graeme.Wood@edinburgh.ac.uk)

If you have multihomed host, you can specify the your particular ip address
by doing bind on your local socket.  This is what I have done to make the
code run on our multihomed host:

In send_to_kdc.c after the socket was obtained add:

    if ( loc_host_addr == 0 ) /* static u_long loc_host_addr = 0 initially */ {
        if ( (loc_host_addr = gethostid()) == 0) {
            if (krb_debug)
               fprintf(stderr, "%s: Gethostid error\n", prog);
            return(SKDC_CANT);
        }
    }
    local.sin_addr.s_addr = loc_host_addr;
    local.sin_family = AF_INET;
    if (bind(f, &local, S_AD_SZ, 0) < 0) /* struct sockaddr_in local */ {
        if (krb_debug)
               fprintf(stderr, "%s: Can't bind \n", prog);
        return(SKDC_CANT);

Similar code was added to kadm_cli_wrap.c, adm_serv.c, kerberos.c, etc


K5 supports multihomed hosts.

Galina Kofman.

viktor@shearson.com (Viktor Dukhovni) (05/25/91)

galina@watson.ibm.com (Galina Kofman)_ writes:

>In send_to_kdc.c after the socket was obtained add:

>    if ( loc_host_addr == 0 ) /* static u_long loc_host_addr = 0 initially */ {
>        if ( (loc_host_addr = gethostid()) == 0) {
				^^^^^^^
			This is not terribly likely to return
			an IP address.  On systems without a harware ID
			the default hostid may be based on the IP address,
			but these tend to also have sethostid(),  which
			may be used by the sysadmin to set any other value.


	To bind to the primary address one must

	char name[MAXHOSTNAMELEN];
	struct hostent *hp;
	gethostname(name,MAXHOSTNAMELEN);
	if ( (hp=gethostbyname(name)) == NULL ) {
		/* error */
		...
	}
	bcopy(hp->h_addr,&loc_host_addr,sizeof(loc_host_addr));
--
        Viktor Dukhovni <viktor@shearson.com>       : ARPA
                <...!uunet!shearson.com!viktor>     : UUCP
        388 Greenwich St., 11th floor, NY, NY 10013 : US-Post
                +1-(212)-464-3793                   : VOICE

oleg@watson.ibm.com (Oleg Vishnepolsky) (05/31/91)

In  <1991May24.210757.10215@shearson.com>  viktor@shearson.com (Viktor Dukhovni) writes:
> galina@watson.ibm.com (Galina Kofman)_ writes:
>
> >In send_to_kdc.c after the socket was obtained add:
>
> >    if ( loc_host_addr == 0 ) /* static u_long loc_host_addr = 0 initially */ {
> >        if ( (loc_host_addr = gethostid()) == 0) {
>                               ^^^^^^^
>                       This is not terribly likely to return
>                       an IP address.  On systems without a harware ID
>                       the default hostid may be based on the IP address,
>                       but these tend to also have sethostid(),  which
>                       may be used by the sysadmin to set any other value.
>
>
>       To bind to the primary address one must
>
>       char name[MAXHOSTNAMELEN];
>       struct hostent *hp;
>       gethostname(name,MAXHOSTNAMELEN);
>       if ( (hp=gethostbyname(name)) == NULL ) {
>               /* error */
>               ...
>       }
>       bcopy(hp->h_addr,&loc_host_addr,sizeof(loc_host_addr));
> --
>         Viktor Dukhovni <viktor@shearson.com>       : ARPA
>                 <...!uunet!shearson.com!viktor>     : UUCP
>         388 Greenwich St., 11th floor, NY, NY 10013 : US-Post
>                 +1-(212)-464-3793                   : VOICE

True on most UNIX systems. Not true on OS/2 and VM/CMS where Galina ported
KERBEROS to. gethostid() on these systems returns an IP address.
There gethostid() approach is more efficient since no need to resolve
a name is needed.

Oleg Vishnepolsky