* convt_tkt.c: Delete; it's not needed anymore
authorTom Yu <tlyu@mit.edu>
Tue, 12 Aug 1997 01:16:32 +0000 (01:16 +0000)
committerTom Yu <tlyu@mit.edu>
Tue, 12 Aug 1997 01:16:32 +0000 (01:16 +0000)
* test.c: Remove reference to krb524_convert_creds_addr, as that
doesn't exist anymore.

* conv_creds.c: Clean up substantially to be less convoluted.

* sendmsg.c: Fix to not do a full series of timeouts on each
server; loop over the whole list before increasing the timeout.

* configure.in: Update to use the new library build system to
build libkrb524.

* Makefile.in: Update to reflect changes in the library.  Also,
use the new library build system to build libkrb524.

git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@10167 dc483132-0cff-0310-8789-dd5450dbe970

src/krb524/ChangeLog
src/krb524/Makefile.in
src/krb524/configure.in
src/krb524/conv_creds.c
src/krb524/conv_tkt.c [deleted file]
src/krb524/sendmsg.c
src/krb524/test.c

index 092fb55ea55822b213acfee78213ec7f4f86814d..2d46bc210abec413c24f3c749cf8fe50d1729b34 100644 (file)
@@ -1,3 +1,21 @@
+Mon Aug 11 21:12:11 1997  Tom Yu  <tlyu@mit.edu>
+
+       * convt_tkt.c: Delete; it's not needed anymore.
+
+       * test.c: Remove reference to krb524_convert_creds_addr, as that
+       doesn't exist anymore.
+
+       * conv_creds.c: Clean up substantially to be less convoluted.
+
+       * sendmsg.c: Fix to not do a full series of timeouts on each
+       server; loop over the whole list before increasing the timeout.
+
+       * configure.in: Update to use the new library build system to
+       build libkrb524.
+
+       * Makefile.in: Update to reflect changes in the library.  Also,
+       use the new library build system to build libkrb524.
+
 Thu Aug  7 17:34:59 1997  Tom Yu  <tlyu@mit.edu>
 
        * cnv_tkt_skey.c:
index 802d956967b6d656e3d7ce823508307ac99e2fa9..05f991d4f5893d2866e8f03ec42e36f106fec300 100644 (file)
 # PERFORMANCE OF THIS SOFTWARE.
 # 
 
+LIB=krb524
+LIBMAJOR=1
+LIBMINOR=0
+RELDIR=../krb524
+STOBJLISTS=OBJS.ST
+
 CFLAGS = $(CCOPTS) -DUSE_MASTER  $(DEFS) $(LOCALINCLUDE)
 PROG_LIBPATH=-L$(TOPLIBD) $(KRB4_LIBPATH)
 PROG_RPATH=$(KRB5_LIBDIR)
-
-all::
-
 KRB524_DEPLIB  = libkrb524.a
 KRB524_LIB     = libkrb524.a
 
 LOCALINCLUDE= $(KRB4_INCLUDES) -I. -I$(srcdir)
 
 # Library sources
-SRCS   = conv_creds.c conv_princ.c conv_tkt.c cnv_tkt_skey.c \
+SRCS   = conv_creds.c conv_princ.c cnv_tkt_skey.c \
        encode.c misc.c globals.c sendmsg.c krb524_err.et
-OBJS   = conv_creds.o conv_princ.o conv_tkt.o cnv_tkt_skey.o \
+STLIBOBJS = conv_creds.o conv_princ.o cnv_tkt_skey.o \
        encode.o misc.o globals.o sendmsg.o krb524_err.o
 
 GENS   = krb524_err.c krb524_err.h
 
-all:: $(GENS) libkrb524.a krb524d krb524test k524init
+all:: $(GENS)
+all:: all-libs
 
-libkrb524.a: $(OBJS)
-       $(ARADD) $@ $(OBJS)
-       $(RANLIB) $@
+all:: krb524d krb524test k524init
 
 krb524test: libkrb524.a test.o $(KRB524_DEPLIB) $(KRB4COMPAT_DEPLIBS)
        $(CC_LINK) -o krb524test test.o $(KRB524_LIB) $(KRB4COMPAT_LIBS)
@@ -53,12 +55,10 @@ krb524d: krb524d.o $(KADMSRV_DEPLIBS) $(KRB524_DEPLIB) $(KRB4COMPAT_DEPLIBS)
 k524init: k524init.o  $(KRB524_DEPLIB) $(KRB4COMPAT_DEPLIBS)
        $(CC_LINK) -o k524init k524init.o $(KRB524_LIB) $(KRB4COMPAT_LIBS)
 
-install::
-       $(INSTALL_DATA) libkrb524.a $(DESTDIR)$(KRB5_LIBDIR)/libkrb524.a
-       $(RANLIB) $(DESTDIR)$(KRB5_LIBDIR)/libkrb524.a
+install:: install-libs
        $(INSTALL_PROGRAM) krb524d $(DESTDIR)$(SERVER_BINDIR)/krb524d
        $(INSTALL_PROGRAM) k524init $(DESTDIR)$(CLIENT_BINDIR)/krb524init
 
-clean::
-       $(RM) libkrb524.a $(OBJS) $(GENS) core *~ *.bak #*
+clean:: clean-libs clean-libobjs
+       $(RM) $(OBJS) $(GENS) core *~ *.bak #*
        $(RM) krb524test krb524d k524init test.o krb524d.o k524init.o
index bf967c1cf3d41d0f1b54ebd1bf1f5f02073c36d1..de61ccf6c29609db880b7cf22b5537fab5939558 100644 (file)
@@ -1,9 +1,7 @@
 AC_INIT(krb524d.c)
 CONFIG_RULES
-AC_PROG_ARCHIVE
-AC_PROG_ARCHIVE_ADD
-AC_PROG_RANLIB
-AC_PROG_INSTALL
+KRB5_BUILD_LIBRARY_STATIC
+KRB5_BUILD_LIBOBJS
 AC_PROG_AWK
 AC_CHECK_HEADERS(sys/select.h) dnl
 AC_TYPE_SIGNAL
index 1e30fa5cdf5d9139ee085f48a1c5746163edf248..7ae810e1352c058061dacac533f033ffa5827623 100644 (file)
 
 #include "krb524.h"
 
-int krb524_convert_creds_plain
+krb5_error_code krb524_convert_creds_plain
 KRB5_PROTOTYPE((krb5_context context, krb5_creds *v5creds, 
                   CREDENTIALS *v4creds));
 
+krb5_error_code krb524_sendto_kdc
+KRB5_PROTOTYPE((krb5_context context, const krb5_data *message,
+               krb5_data *realm, krb5_data *reply));
 
-int krb524_convert_creds_addr(context, v5creds, v4creds, saddr)
+krb5_error_code
+krb524_convert_creds_kdc(context, v5creds, v4creds)
      krb5_context context;
      krb5_creds *v5creds;
      CREDENTIALS *v4creds;
-     struct sockaddr *saddr;
 {
-     int ret;
+     krb5_error_code ret;
+     krb5_data reply;
+     char *p;
 
-     if ((ret = krb524_convert_creds_plain(context, v5creds, v4creds)))
-         return ret;
+     ret = krb524_convert_creds_plain(context, v5creds, v4creds);
+     if (ret)
+        return ret;
+
+     reply.data = NULL;
+     ret = krb524_sendto_kdc(context, &v5creds->ticket,
+                            &v5creds->server->realm, &reply);
+     if (ret)
+        return ret;
+
+     p = reply.data;
+     ret = ntohl(*((krb5_error_code *) p));
+     p += sizeof(krb5_error_code);
+     reply.length -= sizeof(krb5_error_code);
+     if (ret)
+        goto fail;
+
+     v4creds->kvno = ntohl(*((krb5_error_code *) p));
+     p += sizeof(int);
+     reply.length -= sizeof(int);
+     ret = decode_v4tkt(&v4creds->ticket_st, p, &reply.length);
 
-     return krb524_convert_tkt(v5creds->server, &v5creds->ticket,
-                              &v4creds->ticket_st,
-                              &v4creds->kvno,
-                              (struct sockaddr_in *) saddr);
+fail:
+     if (reply.data) 
+        free(reply.data);
+     reply.data = NULL;
+     return ret;
 }
 
-int krb524_convert_creds_kdc(context, v5creds, v4creds)
-     krb5_context context;
-     krb5_creds *v5creds;
-     CREDENTIALS *v4creds;
+#if 0
+int broken()
 {
-     struct sockaddr_in *addrs;
-     int ret, naddrs, i;
-
      if ((ret = krb5_locate_kdc(context, &v5creds->server->realm, &addrs,
                               &naddrs)))
          return ret;
@@ -92,8 +112,10 @@ int krb524_convert_creds_kdc(context, v5creds, v4creds)
      free(addrs);
      return ret;
 }
+#endif
 
-int krb524_convert_creds_plain(context, v5creds, v4creds)
+krb5_error_code
+krb524_convert_creds_plain(context, v5creds, v4creds)
      krb5_context context;
      krb5_creds *v5creds;
      CREDENTIALS *v4creds;
diff --git a/src/krb524/conv_tkt.c b/src/krb524/conv_tkt.c
deleted file mode 100644 (file)
index be0d055..0000000
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * Copyright 1994 by OpenVision Technologies, Inc.
- * 
- * Permission to use, copy, modify, distribute, and sell this software
- * and its documentation for any purpose is hereby granted without fee,
- * provided that the above copyright notice appears in all copies and
- * that both that copyright notice and this permission notice appear in
- * supporting documentation, and that the name of OpenVision not be used
- * in advertising or publicity pertaining to distribution of the software
- * without specific, written prior permission. OpenVision makes no
- * representations about the suitability of this software for any
- * purpose.  It is provided "as is" without express or implied warranty.
- * 
- * OPENVISION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
- * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
- * EVENT SHALL OPENVISION BE LIABLE FOR ANY SPECIAL, INDIRECT OR
- * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
- * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
- * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-#include <stdio.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <netdb.h>
-
-#include "krb5.h"
-#include <krb.h>
-#include "krb524.h"
-
-/*
- * krb524_convert_tkt.  Open a network connection to krb524d, send it
- * the V5 ticket, receive the V4 ticket in response.
- */
-int krb524_convert_tkt(server, v5tkt, v4tkt, kvno, saddr)
-     krb5_principal server;
-     krb5_data *v5tkt;
-     KTEXT_ST *v4tkt;
-     int *kvno;
-     struct sockaddr_in *saddr;
-{
-     char *p;
-     krb5_data reply;
-     struct servent *serv;
-     int ret, status;
-
-     reply.data = NULL;
-
-     if (saddr->sin_port == 0) {
-         serv = getservbyname(KRB524_SERVICE, "udp");
-         if (serv)
-              saddr->sin_port = serv->s_port;
-         else
-              saddr->sin_port = htons(KRB524_PORT);
-     }
-
-     if ((ret = krb524_send_message((struct sockaddr *) saddr, v5tkt, &reply)))
-         goto fail;
-     
-     p = reply.data;
-     status = ntohl(*((krb5_error_code *) p));
-     p += sizeof(krb5_error_code);
-     reply.length -= sizeof(krb5_error_code);
-     if (status) {
-         ret = status;
-         goto fail;
-     }
-     *kvno = ntohl(*((krb5_error_code *) p));
-     p += sizeof(int);
-     reply.length -= sizeof(int);
-     ret = decode_v4tkt(v4tkt, p, &reply.length);
-
-fail:
-     if (ret) {
-         if (reply.data) 
-              free(reply.data);
-         reply.data = NULL;
-         reply.length = 0;
-     }
-
-     return ret;
-}
-
index 4c7c8b748d8294de02f4ab1495ac13252dcbf554..5281359a9a082c3e16a888d124098c1cff5b9b40 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 1990,1991 by the Massachusetts Institute of Technology.
+ * Copyright 1990,1991,1997 by the Massachusetts Institute of Technology.
  * All Rights Reserved.
  *
  * Export of this software from the United States of America may
  * backoff retry algorithm.  This is based on krb5_sendto_kdc.
  */
 
-#include "krb5.h"
+/* Grab socket stuff.  This might want to go away later. */
+#define NEED_SOCKETS
+#define NEED_LOWLEVEL_IO
+#include "k5-int.h"
 
 #include <unistd.h>
 #include <stdlib.h>
 #include <string.h>
-#include <sys/types.h>
-#include <sys/socket.h>
+
 #include <sys/time.h>
-#include <netinet/in.h>
 
 #ifdef _AIX
 #include <sys/select.h>
 #include <krb.h>
 #include "krb524.h"
 
+/* Cheat and grab this internal function from lib/krb5/os. */
+krb5_error_code krb5_locate_kdc
+    PROTOTYPE((krb5_context, const krb5_data *,
+              struct sockaddr **, int *));
+
 /*
- * Send the formatted request 'message' to the host/port specified in
- * addr and return the response (if any) in 'reply'.
+ * krb524_sendto_kdc:
+ *
+ * A slightly modified version of krb5_sendto_kdc.
+ *
+ * send the formatted request 'message' to a KDC for realm 'realm' and
+ * return the response (if any) in 'reply'.
  *
  * If the message is sent and a response is received, 0 is returned,
  * otherwise an error code is returned.
@@ -55,103 +65,184 @@ extern int krb5_max_skdc_timeout;
 extern int krb5_skdc_timeout_shift;
 extern int krb5_skdc_timeout_1;
 
-int krb524_send_message
-       KRB5_PROTOTYPE((const struct sockaddr * addr, const krb5_data * message,
-                  krb5_data * reply));
-
-
-int krb524_send_message (addr, message, reply)
-     const struct sockaddr * addr;
-     const krb5_data * message;
-     krb5_data * reply;
+krb5_error_code
+krb524_sendto_kdc (context, message, realm, reply)
+    krb5_context context;
+    const krb5_data * message;
+    const krb5_data * realm;
+    krb5_data * reply;
 {
-    register int timeout;
-    int nready, received;
+    register int timeout, host, i;
+    struct sockaddr *addr;
+    int naddr;
+    struct servent *serv;
+    int sent, nready;
     krb5_error_code retval;
+    SOCKET *socklist;
     fd_set readable;
     struct timeval waitlen;
-    int s, cc;
-    
-    if ((reply->data = malloc(krb5_max_dgram_size)) == NULL)
+    int cc;
+
+    /*
+     * find KDC location(s) for realm
+     */
+
+    if (retval = krb5_locate_kdc (context, realm, &addr, &naddr))
+       return retval;
+    if (naddr == 0)
+       return KRB5_REALM_UNKNOWN;
+
+    socklist = (SOCKET *)malloc(naddr * sizeof(SOCKET));
+    if (socklist == NULL) {
+       free(addr);
        return ENOMEM;
-    reply->length = krb5_max_dgram_size;
+    }
+    for (i = 0; i < naddr; i++)
+       socklist[i] = INVALID_SOCKET;
 
-    /* XXX 4.2/4.3BSD has PF_xxx = AF_xxx, so the */
-    /* socket creation here will work properly... */
-    s = socket(addr->sa_family, SOCK_DGRAM, 0);
-    if (s == -1) {
-        retval = errno;
-        goto out;
+    /*
+     * Bash the ports numbers.
+     */
+    serv = getservbyname(KRB524_SERVICE, "udp");
+    for (i = 0; i < naddr; i++)
+       if (serv)
+           ((struct sockaddr_in *)&addr[i])->sin_port = serv->s_port;
+       else
+           ((struct sockaddr_in *)&addr[i])->sin_port = htons(KRB524_PORT);
+
+    if (!(reply->data = malloc(krb5_max_dgram_size))) {
+       free(addr);
+       free(socklist);
+       return ENOMEM;
     }
-    
+    reply->length = krb5_max_dgram_size;
+
+#if 0
     /*
-     * On BSD systems, a connected UDP socket will get connection
-     * refused and net unreachable errors while an unconnected socket
-     * will time out, so use connect, send, recv instead of sendto,
-     * recvfrom.  The connect here may return an error if the
-     * destination host is known to be unreachable.
+     * Not needed for Windows, since it's done by the DLL
+     * initialization. XXX What about for the Macintosh?
+     *
+     * See below for commented out SOCKET_CLEANUP()
      */
-    if (connect(s, (struct sockaddr *) addr, sizeof(struct sockaddr)) == -1) {
-        retval = errno;
-        goto out;
+    if (SOCKET_INITIALIZE()) {  /* PC needs this for some tcp/ip stacks */
+       free(addr);
+       free(socklist);
+       free(reply->data);
+        return SOCKET_ERRNO;
     }
-        
+#endif
+
     /*
-     * Send the message, and wait for a reply, using an exponential
-     * backoff.  Use the kdc timeout values, just for consistency.
+     * do exponential backoff.
      */
 
-    received = 0;
-    for (timeout = krb5_skdc_timeout_1;
-        timeout < krb5_max_skdc_timeout;
+    for (timeout = krb5_skdc_timeout_1; timeout < krb5_max_skdc_timeout;
         timeout <<= krb5_skdc_timeout_shift) {
-        
-        if (send(s, message->data, message->length, 0) != message->length) {
-             retval = errno;
-             goto out;
-        }
-        
-        waitlen.tv_usec = 0;
-        waitlen.tv_sec = timeout;
-        FD_ZERO(&readable);
-        FD_SET(s, &readable);
-        nready = select(1 + s, &readable, 0, 0, &waitlen);
-        if (nready < 0) {
-             retval = errno;
-             goto out;
-        } else if (nready == 1) {
-             if ((cc = recv(s, reply->data, reply->length, 0)) == -1) { 
-                  retval = errno;
-                  goto out;
-             }
-
-             /*
-              * We might consider here verifying that the reply came
-              * from the host specified, but that check can be fouled
-              * by some implementations of some network types which
-              * might show a loopback return address, for example, if
-              * the server is on the same host as the client.
-              *
-              * Besides, reply addresses can be spoofed, and we don't
-              * want to provide a false sense of security.
-              */
-             reply->length = cc;
-             retval = 0;
-             goto out;
-        }
-        /* else timeout, try again */
-    }
+       sent = 0;
+       for (host = 0; host < naddr; host++) {
+           /* send to the host, wait timeout seconds for a response,
+              then move on. */
+           /* cache some sockets for each host */
+           if (socklist[host] == INVALID_SOCKET) {
+               /* XXX 4.2/4.3BSD has PF_xxx = AF_xxx, so the socket
+                  creation here will work properly... */
+               /*
+                * From socket(2):
+                *
+                * The protocol specifies a particular protocol to be
+                * used with the socket.  Normally only a single
+                * protocol exists to support a particular socket type
+                * within a given protocol family.
+                */
+               socklist[host] = socket(addr[host].sa_family, SOCK_DGRAM, 0);
+               if (socklist[host] == INVALID_SOCKET)
+                   continue;           /* try other hosts */
+               /* have a socket to send/recv from */
+               /* On BSD systems, a connected UDP socket will get connection
+                  refused and net unreachable errors while an unconnected
+                  socket will time out, so use connect, send, recv instead of
+                  sendto, recvfrom.  The connect here may return an error if
+                  the destination host is known to be unreachable. */
+               if (connect(socklist[host],
+                           &addr[host], sizeof(addr[host])) == SOCKET_ERROR)
+                 continue;
+           }
+           if (send(socklist[host],
+                      message->data, message->length, 0) != message->length)
+             continue;
+       retry:
+           waitlen.tv_usec = 0;
+           waitlen.tv_sec = timeout;
+           FD_ZERO(&readable);
+           FD_SET(socklist[host], &readable);
+           if (nready = select(SOCKET_NFDS(socklist[host]),
+                               &readable,
+                               0,
+                               0,
+                               &waitlen)) {
+               if (nready == SOCKET_ERROR) {
+                   if (SOCKET_ERRNO == SOCKET_EINTR)
+                       goto retry;
+                   retval = SOCKET_ERRNO;
+                   goto out;
+               }
+               if ((cc = recv(socklist[host],
+                              reply->data, reply->length, 0)) == SOCKET_ERROR)
+                 {
+                   /* man page says error could be:
+                      EBADF: won't happen
+                      ENOTSOCK: it's a socket.
+                      EWOULDBLOCK: not marked non-blocking, and we selected.
+                      EINTR: could happen
+                      EFAULT: we allocated the reply packet.
+
+                      In addition, net related errors like ECONNREFUSED
+                      are possble (but undocumented).  Assume anything
+                      other than EINTR is a permanent error for the
+                      server (i.e. don't set sent = 1).
+                      */
 
-    /* If the loop exits normally, the max timeout expired without */
-    /* a reply having arrived.  */
-    retval = KRB524_NOTRESP;
+                   if (SOCKET_ERRNO == SOCKET_EINTR)
+                     sent = 1;
+                   continue;
+                 }
 
-out:
-    (void) close(s);
+               /* We might consider here verifying that the reply
+                  came from one of the KDC's listed for that address type,
+                  but that check can be fouled by some implementations of
+                  some network types which might show a loopback return
+                  address, for example, if the KDC is on the same host
+                  as the client. */
+
+               reply->length = cc;
+               retval = 0;
+               goto out;
+           } else if (nready == 0) {
+               /* timeout */
+               sent = 1;
+           }
+           /* not ready, go on to next server */
+       }
+       if (!sent) {
+           /* never were able to send to any servers; give up */
+           retval = KRB5_KDC_UNREACH;
+           break;
+       }
+    }
+    retval = KRB5_KDC_UNREACH;
+ out:
+    for (i = 0; i < naddr; i++)
+       if (socklist[i] != INVALID_SOCKET)
+           (void) closesocket (socklist[i]);
+#if 0
+    SOCKET_CLEANUP();                           /* Done with sockets for now */
+#endif
+    free(addr);
+    free(socklist);
     if (retval) {
-        free(reply->data);
-        reply->data = 0;
-        reply->length = 0;
+       free(reply->data);
+       reply->data = 0;
+       reply->length = 0;
     }
     return retval;
 }
index 50b1e55940d2680b8690b3abfb7e5b8f838dacb7..281c897e2443d1923bb0638e4b9645d72e7e95a2 100644 (file)
@@ -227,12 +227,14 @@ int main(argc, argv)
      while (argc) {
          if (strcmp(*argv, "-local") == 0)
               local++;
+#if 0
          else if (strcmp(*argv, "-remote") == 0) {
               argc--; argv++;
               if (!argc)
                    usage();
               remote = *argv;
          }
+#endif
          else
               break;
          argc--; argv++;
@@ -306,6 +308,7 @@ void do_remote(context, v5creds, server, key)
      printf("\nV5 credentials:\n");
      krb5_print_creds(context, v5creds, key);
 
+#if 0
      if (strcmp(server, "kdc") != 0) {
          hp = gethostbyname(server);
          if (hp == NULL) {
@@ -323,7 +326,9 @@ void do_remote(context, v5creds, server, key)
                       server);
               exit(1);
          }
-     } else {
+     } else
+#endif
+     {
          if ((ret = krb524_convert_creds_kdc(context, v5creds, &v4creds))) {
               com_err("test", ret, "converting credentials via kdc");
               exit(1);