--- /dev/null
+/*
+ * lib/crypto/os/localaddr.c
+ *
+ * Copyright 1990,1991 by the Massachusetts Institute of Technology.
+ * All Rights Reserved.
+ *
+ * Export of this software from the United States of America may
+ * require a specific license from the United States Government.
+ * It is the responsibility of any person or organization contemplating
+ * export to obtain such a license before exporting.
+ *
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of M.I.T. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission. M.I.T. makes no representations about the suitability of
+ * this software for any purpose. It is provided "as is" without express
+ * or implied warranty.
+ *
+ *
+ * Return the protocol addresses supported by this host.
+ *
+ * XNS support is untested, but "Should just work".
+ */
+
+
+#define NEED_SOCKETS
+#include "k5-int.h"
+
+#if !defined(HAVE_MACSOCK_H) && !defined(_MSDOS)
+
+/* needed for solaris, harmless elsewhere... */
+#define BSD_COMP
+#include <sys/ioctl.h>
+#include <sys/time.h>
+#include <errno.h>
+
+/*
+ * The SIOCGIF* ioctls require a socket.
+ * It doesn't matter *what* kind of socket they use, but it has to be
+ * a socket.
+ *
+ * Of course, you can't just ask the kernel for a socket of arbitrary
+ * type; you have to ask for one with a valid type.
+ *
+ */
+#ifdef KRB5_USE_INET
+
+#include <netinet/in.h>
+
+#ifndef USE_AF
+#define USE_AF AF_INET
+#define USE_TYPE SOCK_DGRAM
+#define USE_PROTO 0
+#endif
+
+#endif
+
+#ifdef KRB5_USE_NS
+
+#include <netns/ns.h>
+
+#ifndef USE_AF
+#define USE_AF AF_NS
+#define USE_TYPE SOCK_DGRAM
+#define USE_PROTO 0 /* guess */
+#endif
+
+#endif
+/*
+ * Add more address families here.
+ */
+
+extern int errno;
+
+/*
+ * Return all the protocol addresses of this host.
+ *
+ * We could kludge up something to return all addresses, assuming that
+ * they're valid kerberos protocol addresses, but we wouldn't know the
+ * real size of the sockaddr or know which part of it was actually the
+ * host part.
+ *
+ * This uses the SIOCGIFCONF, SIOCGIFFLAGS, and SIOCGIFADDR ioctl's.
+ */
+
+krb5_error_code INTERFACE
+krb5_crypto_os_localaddr(addr)
+ krb5_address ***addr;
+{
+ struct ifreq *ifr;
+ struct ifconf ifc;
+ int s, code, n, i;
+ char buf[1024];
+ krb5_address *addr_temp [ 1024/sizeof(struct ifreq) ];
+ int n_found;
+ int mem_err = 0;
+
+ ifc.ifc_len = sizeof(buf);
+ ifc.ifc_buf = buf;
+
+ s = socket (USE_AF, USE_TYPE, USE_PROTO);
+ if (s < 0)
+ return errno;
+
+ code = ioctl (s, SIOCGIFCONF, (char *)&ifc);
+ if (code < 0) {
+ int retval = errno;
+ closesocket (s);
+ return retval;
+ }
+ n = ifc.ifc_len / sizeof (struct ifreq);
+
+ for (n_found=0, i=0; i<n && ! mem_err; i++) {
+ krb5_address *address;
+ ifr = &ifc.ifc_req[i];
+
+ if (ioctl (s, SIOCGIFFLAGS, (char *)ifr) < 0)
+ continue;
+
+#ifdef IFF_LOOPBACK
+ if (ifr->ifr_flags & IFF_LOOPBACK)
+ continue;
+#endif
+
+ if (!(ifr->ifr_flags & IFF_UP))
+ /* interface is down; skip */
+ continue;
+
+ if (ioctl (s, SIOCGIFADDR, (char *)ifr) < 0)
+ /* can't get address */
+ continue;
+
+ /* ifr->ifr_addr has what we want! */
+ switch (ifr->ifr_addr.sa_family) {
+#ifdef KRB5_USE_INET
+ case AF_INET:
+ {
+ struct sockaddr_in *in =
+ (struct sockaddr_in *)&ifr->ifr_addr;
+
+ address = (krb5_address *)
+ malloc (sizeof(krb5_address));
+ if (address) {
+ address->addrtype = ADDRTYPE_INET;
+ address->length = sizeof(struct in_addr);
+ address->contents = (unsigned char *)malloc(address->length);
+ if (!address->contents) {
+ krb5_xfree(address);
+ address = 0;
+ mem_err++;
+ } else {
+ memcpy ((char *)address->contents,
+ (char *)&in->sin_addr,
+ address->length);
+ break;
+ }
+ } else mem_err++;
+ }
+#endif
+#ifdef KRB5_USE_NS
+ case AF_XNS:
+ {
+ struct sockaddr_ns *ns =
+ (struct sockaddr_ns *)&ifr->ifr_addr;
+ address = (krb5_address *)
+ malloc (sizeof (krb5_address) + sizeof (struct ns_addr));
+ if (address) {
+ address->addrtype = ADDRTYPE_XNS;
+
+ /* XXX should we perhaps use ns_host instead? */
+
+ address->length = sizeof(struct ns_addr);
+ address->contents = (unsigned char *)malloc(address->length);
+ if (!address->contents) {
+ krb5_xfree(address);
+ address = 0;
+ mem_err++;
+ } else {
+ memcpy ((char *)address->contents,
+ (char *)&ns->sns_addr,
+ address->length);
+ break;
+ }
+ } else mem_err++;
+ break;
+ }
+#endif
+ /*
+ * Add more address families here..
+ */
+ default:
+ continue;
+ }
+ if (address)
+ addr_temp[n_found++] = address;
+ address = 0;
+ }
+ close(s);
+
+ *addr = (krb5_address **)malloc (sizeof (krb5_address *) * (n_found+1));
+ if (*addr == 0)
+ mem_err++;
+
+ if (mem_err) {
+ for (i=0; i<n_found; i++) {
+ krb5_xfree(addr_temp[i]);
+ addr_temp[i] = 0;
+ }
+ return ENOMEM;
+ }
+
+ for (i=0; i<n_found; i++) {
+ (*addr)[i] = addr_temp[i];
+ }
+ (*addr)[n_found] = 0;
+ return 0;
+}
+
+#else /* Windows/Mac version */
+
+/* No ioctls in winsock so we just assume there is only one networking
+ * card per machine, so gethostent is good enough.
+ */
+
+krb5_error_code INTERFACE
+krb5_crypto_os_localaddr (krb5_address ***addr) {
+ char host[64]; /* Name of local machine */
+ struct hostent *hostrec;
+ int err;
+
+ *addr = calloc (2, sizeof (krb5_address *));
+ if (*addr == NULL)
+ return ENOMEM;
+
+#ifdef HAVE_MACSOCK_H
+ hostrec = getmyipaddr();
+#else /* HAVE_MACSOCK_H */
+ if (gethostname (host, sizeof(host))) {
+ err = WSAGetLastError();
+ return err;
+ }
+
+ hostrec = gethostbyname (host);
+ if (hostrec == NULL) {
+ err = WSAGetLastError();
+ return err;
+ }
+#endif /* HAVE_MACSOCK_H */
+
+ (*addr)[0] = calloc (1, sizeof(krb5_address));
+ if ((*addr)[0] == NULL) {
+ free (*addr);
+ return ENOMEM;
+ }
+ (*addr)[0]->addrtype = hostrec->h_addrtype;
+ (*addr)[0]->length = hostrec->h_length;
+ (*addr)[0]->contents = (unsigned char *)malloc((*addr)[0]->length);
+ if (!(*addr)[0]->contents) {
+ free((*addr)[0]);
+ free(*addr);
+ return ENOMEM;
+ } else {
+ memcpy ((*addr)[0]->contents,
+ hostrec->h_addr,
+ (*addr)[0]->length);
+ }
+ /* FIXME, deal with the case where gethostent returns multiple addrs */
+
+ return(0);
+}
+#endif
--- /dev/null
+/*
+ * lib/crypto/os/ustime.c
+ *
+ * Copyright 1990,1991 by the Massachusetts Institute of Technology.
+ * All Rights Reserved.
+ *
+ * Export of this software from the United States of America may
+ * require a specific license from the United States Government.
+ * It is the responsibility of any person or organization contemplating
+ * export to obtain such a license before exporting.
+ *
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of M.I.T. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission. M.I.T. makes no representations about the suitability of
+ * this software for any purpose. It is provided "as is" without express
+ * or implied warranty.
+ *
+ *
+ * krb5_mstimeofday for BSD 4.3
+ */
+
+#define NEED_SOCKETS
+#include "k5-int.h"
+
+#ifdef HAVE_MACSOCK_H
+/* We're a Macintosh -- do Mac time things. */
+
+/*
+ * This code is derived from kerberos/src/lib/des/mac_time.c from
+ * the Cygnus Support release of Kerberos V4:
+ *
+ * mac_time.c
+ * (Originally time_stuff.c)
+ * Copyright 1989 by the Massachusetts Institute of Technology.
+ * Macintosh ooperating system interface for Kerberos.
+ */
+
+#include "AddressXlation.h" /* for ip_addr, for #if 0'd net-time stuff */
+
+#include <script.h> /* Defines MachineLocation, used by getTimeZoneOffset */
+#include <ToolUtils.h> /* Defines BitTst(), called by getTimeZoneOffset() */
+#include <OSUtils.h> /* Defines GetDateTime */
+
+/* Mac Cincludes */
+#include <string.h>
+#include <stddef.h>
+
+ /*******************************
+ The Unix epoch is 1/1/70, the Mac epoch is 1/1/04.
+
+ 70 - 4 = 66 year differential
+
+ Thus the offset is:
+
+ (66 yrs) * (365 days/yr) * (24 hours/day) * (60 mins/hour) * (60 secs/min)
+ plus
+ (17 leap days) * (24 hours/day) * (60 mins/hour) * (60 secs/min)
+
+ Don't forget the offset from GMT.
+ *******************************/
+
+/* returns the offset in hours between the mac local time and the GMT */
+
+static
+unsigned krb5_int32
+getTimeZoneOffset()
+{
+ MachineLocation macLocation;
+ long gmtDelta;
+
+ macLocation.gmtFlags.gmtDelta=0L;
+ ReadLocation(&macLocation);
+ gmtDelta=macLocation.gmtFlags.gmtDelta & 0x00FFFFFF;
+ if (BitTst((void *)&gmtDelta,23L)) gmtDelta |= 0xFF000000;
+ gmtDelta /= 3600L;
+ return(gmtDelta);
+}
+
+static krb5_int32 last_sec = 0, last_usec = 0;
+
+/* Returns the GMT in seconds (and fake microseconds) using the Unix epoch */
+
+krb5_error_code INTERFACE
+krb5_crypto_us_timeofday(seconds, microseconds)
+ krb5_int32 *seconds, *microseconds;
+{
+ krb5_int32 sec, usec;
+ time_t the_time;
+
+ GetDateTime (&the_time);
+ sec = the_time -
+ ((66 * 365 * 24 * 60 * 60) +
+ (17 * 24 * 60 * 60) +
+ (getTimeZoneOffset() * 60 * 60));
+ usec = 0; /* Mac is too slow to count faster than once a second */
+
+ if ((sec == last_sec) && (usec == last_usec)) {
+ if (++last_usec >= 1000000) {
+ last_usec = 0;
+ last_sec++;
+ }
+ sec = last_sec;
+ usec = last_usec;
+ } else
+ last_sec = sec;
+ last_usec = usec;
+
+ *seconds = sec;
+ *microseconds = usec;
+ return 0;
+}
+
+#if 0
+
+int
+gettimeofdaynet (struct timeval *tp, struct timezone *tz)
+{
+ tp->tv_sec = gettimeofdaynet_no_offset();
+ return 0;
+}
+
+
+#define TIME_PORT 37
+#define TM_OFFSET 2208988800
+
+/*
+ *
+ * get_net_offset () -- Use UDP time protocol to figure out the
+ * offset between what the Mac thinks the time is an what
+ * the network thinks.
+ *
+ */
+int
+get_net_offset()
+{
+ time_t tv;
+ char buf[512],ts[256];
+ long *nettime;
+ int attempts, cc, time_port;
+ long unixtime;
+ char realm[REALM_SZ];
+ ip_addr fromaddr;
+ unsigned short fromport;
+ int result;
+
+ nettime = (long *)buf;
+ time_port = TIME_PORT;
+
+ cc = sizeof(buf);
+ result = hosts_send_recv(ts, 1, buf, &cc, "", time_port);
+ time (&tv);
+
+ if (result!=KSUCCESS || cc<4) {
+ net_offset = 0;
+ if (!result) result = 100;
+ return result;
+ }
+
+ unixtime = (long) ntohl(*nettime) - TM_OFFSET;
+
+ tv -= 66 * 365 * 24 * 60 * 60
+ + 17 * 60 * 60 * 24; /* Convert to unix time w/o offset */
+ net_offset = unixtime - tv;
+ net_got_offset = 1;
+
+ return 0;
+}
+
+#endif /* 0 */
+
+#else /* HAVE_MACSOCK_H */
+#ifndef _MSDOS
+/* We're a Unix machine -- do Unix time things. */
+
+extern int errno;
+
+static struct timeval last_tv = {0, 0};
+
+krb5_error_code INTERFACE
+krb5_crypto_us_timeofday(seconds, microseconds)
+ register krb5_int32 *seconds, *microseconds;
+{
+ struct timeval tv;
+
+ if (gettimeofday(&tv, (struct timezone *)0) == -1) {
+ /* failed, return errno */
+ return (krb5_error_code) errno;
+ }
+ if ((tv.tv_sec == last_tv.tv_sec) && (tv.tv_usec == last_tv.tv_usec)) {
+ if (++last_tv.tv_usec >= 1000000) {
+ last_tv.tv_usec = 0;
+ last_tv.tv_sec++;
+ }
+ tv = last_tv;
+ } else
+ last_tv = tv;
+
+ *seconds = tv.tv_sec;
+ *microseconds = tv.tv_usec;
+ return 0;
+}
+
+#else /* DOS version */
+/*
+ * Originally written by John Gilmore, Cygnus Support, May '94.
+ * Public Domain.
+ */
+
+#include <time.h>
+#include <sys/timeb.h>
+#include <dos.h>
+#include <string.h>
+
+/*
+ * Time handling. Translate Unix time calls into Kerberos internal
+ * procedure calls.
+ *
+ * Due to the fact that DOS time can be unreliable we have reverted
+ * to using the AT hardware clock and converting it to Unix time.
+ */
+
+static time_t win_gettime ();
+static long win_time_get_epoch(); /* Adjust for MSC 7.00 bug */
+
+krb5_error_code INTERFACE
+krb5_crypto_us_timeofday(seconds, microseconds)
+register krb5_int32 *seconds, *microseconds;
+{
+ krb5_int32 sec, usec;
+ static krb5_int32 last_sec = 0;
+ static krb5_int32 last_usec = 0;
+
+ sec = win_gettime (); /* Get the current time */
+ usec = 0; /* Can't do microseconds */
+
+ if (sec == last_sec) { /* Same as last time??? */
+ usec = ++last_usec; /* Yep, so do microseconds */
+ if (usec >= 1000000) {
+ ++sec;
+ usec = 0;
+ }
+ }
+ last_sec = sec; /* Remember for next time */
+ last_usec = usec;
+
+ *seconds = sec; /* Return the values */
+ *microseconds = usec;
+
+ return 0;
+}
+static time_t
+win_gettime () {
+ struct tm tm;
+ union _REGS inregs; /* For calling BIOS */
+ union _REGS outregs;
+ struct _timeb now;
+ time_t time;
+ long convert; /* MSC 7.00 bug work around */
+
+ _ftime(&now); /* Daylight savings time */
+
+ /* Get time from AT hardware clock INT 0x1A, AH=2 */
+ memset(&inregs, 0, sizeof(inregs));
+ inregs.h.ah = 2;
+ _int86(0x1a, &inregs, &outregs);
+
+ /* 0x13 = decimal 13, hence the decoding below */
+ tm.tm_sec = 10 * ((outregs.h.dh & 0xF0) >> 4) + (outregs.h.dh & 0x0F);
+ tm.tm_min = 10 * ((outregs.h.cl & 0xF0) >> 4) + (outregs.h.cl & 0x0F);
+ tm.tm_hour = 10 * ((outregs.h.ch & 0xF0) >> 4) + (outregs.h.ch & 0x0F);
+
+ /* Get date from AT hardware clock INT 0x1A, AH=4 */
+ memset(&inregs, 0, sizeof(inregs));
+ inregs.h.ah = 4;
+ _int86(0x1a, &inregs, &outregs);
+
+ tm.tm_mday = 10 * ((outregs.h.dl & 0xF0) >> 4) + (outregs.h.dl & 0x0F);
+ tm.tm_mon = 10 * ((outregs.h.dh & 0xF0) >> 4) + (outregs.h.dh & 0x0F) - 1;
+ tm.tm_year = 10 * ((outregs.h.cl & 0xF0) >> 4) + (outregs.h.cl & 0x0F);
+ tm.tm_year += 100 * ((10 * (outregs.h.ch & 0xF0) >> 4)
+ + (outregs.h.ch & 0x0F) - 19);
+
+ tm.tm_wday = 0;
+ tm.tm_yday = 0;
+ tm.tm_isdst = now.dstflag;
+
+ time = mktime(&tm);
+
+ convert = win_time_get_epoch();
+ return time + convert;
+
+}
+/*
+ * This routine figures out the current time epoch and returns the
+ * conversion factor. It exists because
+ * Microloss screwed the pooch on the time() and _ftime() calls in
+ * its release 7.0 libraries. They changed the epoch to Dec 31, 1899!
+ * Idiots... We try to cope.
+ */
+
+static struct tm jan_1_70 = {0, 0, 0, 1, 0, 70};
+static long epoch = 0;
+static int epoch_set = 0;
+
+long
+win_time_get_epoch()
+{
+
+ if (!epoch_set) {
+ epoch = 0 - mktime (&jan_1_70); /* Seconds til 1970 localtime */
+ epoch += _timezone; /* Seconds til 1970 GMT */
+ epoch_set = 1;
+ }
+ return epoch;
+}
+
+#endif /* MSDOS */
+#endif /* HAVE_MACSOCK_H */