The Kerberos V support may still fail on hosts with two or more
interfaces.
Regards
Markus
-------------- next part --------------
*** auth-krb5.c.orig Mon May 20 11:51:57 2002
--- auth-krb5.c Mon May 20 11:53:34 2002
***************
*** 38,43 ****
--- 38,44 ----
#include "servconf.h"
#include "uidswap.h"
#include "auth.h"
+ #include "canohost.h"
#ifdef KRB5
#include <krb5.h>
***************
*** 80,85 ****
--- 81,87 ----
krb5_data reply;
krb5_ticket *ticket;
int fd, ret;
+ char *localname;
ret = 0;
server = NULL;
***************
*** 108,114 ****
if (problem)
goto err;
! problem = krb5_sname_to_principal(authctxt->krb5_ctx, NULL, NULL ,
KRB5_NT_SRV_HST, &server);
if (problem)
goto err;
--- 110,118 ----
if (problem)
goto err;
! localname=get_local_hostname(fd);
!
! problem = krb5_sname_to_principal(authctxt->krb5_ctx, localname,
NULL ,
KRB5_NT_SRV_HST, &server);
if (problem)
goto err;
-------------- next part --------------
*** canohost.c.orig Mon May 20 11:54:18 2002
--- canohost.c Mon May 20 11:59:56 2002
***************
*** 22,27 ****
--- 22,100 ----
static void check_ip_options(int, char *);
/*
+ * Return the canonical name of the localhost of the socket. The
+ * caller should free the returned string with xfree.
+ */
+
+ const char *
+ get_local_hostname(int socket)
+ {
+ struct sockaddr_storage addr_6or4;
+ int i;
+ socklen_t addr_6or4_len;
+ char name[NI_MAXHOST], ntop[NI_MAXHOST];
+
+ /* Get local IP address*/
+ addr_6or4_len = sizeof(addr_6or4);
+ memset(&addr_6or4, 0, sizeof(addr_6or4));
+ if (getsockname(socket, (struct sockaddr *) &addr_6or4,
&addr_6or4_len) < 0) {
+ debug("getsockname failed: %.100s",
strerror(errno));
+ fatal_cleanup();
+ }
+ #ifdef IPV4_IN_IPV6
+ if (addr_6or4.ss_family == AF_INET6) {
+ struct sockaddr_in6 *addr6 = (struct sockaddr_in6
*)&addr_6or4;
+
+ /* Detect IPv4 in IPv6 mapped address and convert it to */
+ /* plain (AF_INET) IPv4 address */
+ if (IN6_IS_ADDR_V4MAPPED(&addr6->sin6_addr)) {
+ struct sockaddr_in *addr4 = (struct sockaddr_in
*)&addr_6or4;
+ struct in_addr addr;
+ u_int16_t port;
+
+ memcpy(&addr, ((char *)&addr6->sin6_addr) +
12, sizeof(addr));
+ port = addr6->sin6_port;
+
+ memset(&addr_6or4, 0, sizeof(addr_6or4));
+
+ addr4->sin_family = AF_INET;
+ memcpy(&addr4->sin_addr, &addr,
sizeof(addr));
+ addr4->sin_port = port;
+ }
+ }
+ #endif
+ if (addr_6or4.ss_family == AF_INET)
+ check_ip_options(socket, ntop);
+
+ if (getnameinfo((struct sockaddr *)&addr_6or4, addr_6or4_len,
ntop, sizeof(ntop),
+ NULL, 0, NI_NUMERICHOST) != 0)
+ fatal("get_local_hostname: getnameinfo NI_NUMERICHOST
failed");
+
+ debug3("Trying to resolve local address %.100s to hostname",
ntop);
+ /* Map the IP address to a host name. */
+ if (getnameinfo((struct sockaddr *)&addr_6or4, addr_6or4_len,
name, sizeof(name),
+ NULL, 0, NI_NAMEREQD) != 0) {
+ /* Host name not found. Use ip address. */
+ log("Could not resolve local address %.100s to
hostname", ntop);
+ return xstrdup(ntop);
+ }
+
+ /* Got host name. */
+ name[sizeof(name) - 1] = '\0';
+ /*
+ * Convert it to all lowercase (which is expected by the rest
+ * of this software).
+ */
+ for (i = 0; name[i]; i++)
+ if (isupper(name[i]))
+ name[i] = tolower(name[i]);
+
+ debug("Resolved local address %.100s to hostname %s",
ntop,name);
+
+ return xstrdup(name);
+ }
+
+ /*
* Return the canonical name of the host at the other end of the socket. The
* caller should free the returned string with xfree.
*/
-------------- next part --------------
*** canohost.h.orig Mon May 20 11:54:30 2002
--- canohost.h Mon May 20 11:56:19 2002
***************
*** 12,17 ****
--- 12,18 ----
* called by a name other than "ssh" or "Secure Shell".
*/
+ const char *get_local_hostname(int);
const char *get_canonical_hostname(int);
const char *get_remote_ipaddr(void);
const char *get_remote_name_or_ip(u_int, int);