]> eyrie.org Git - kerberos/sident.git/commitdiff
Huge code cleanup. Fix the coding style to be consistent everywhere,
authorRuss Allbery <rra@stanford.edu>
Mon, 14 Jun 2004 01:24:43 +0000 (01:24 +0000)
committerRuss Allbery <rra@stanford.edu>
Mon, 14 Jun 2004 01:24:43 +0000 (01:24 +0000)
untabify all of the source files, remove all trailing whitespace, and
make the code a bit cleaner.  Kill tons and tons of dead code and pieces
left over from pidentd that we never used.

Update the compatibility layer for the pidentd modules so that they really
can be used verbatim rather than requiring changes for things like
debug_flag.  Pull the sockaddr.h defines for IPv4 into pidentd.h so that
they don't have to be pasted into the Solaris kernel modules.  Delete the
old kvm code; pidentd no longer needs it, and the much simpler pkvm layer
can be used instead.

Include kerberosIV/krb.h instead of krb.h if it was found by configure.

Teach itest about the output format of Linux netstat and to use the euid
value in the kernel struct if the ruid value wasn't set.

14 files changed:
responder/Makefile.in
responder/error.h [deleted file]
responder/ident_auth.c
responder/ident_auth.h
responder/identd.c
responder/identd.h
responder/itest.c
responder/kernel/kvm.h [deleted file]
responder/kernel_helper.c
responder/kvm.c [deleted file]
responder/lifetime.c
responder/parse.c
responder/paths.h [deleted file]
responder/pidentd.h

index a25811fb51fbd804fda4d443f2d59a3fbae8064d..7cc0849b8b2c38243d03190be11e1318b6a2d799 100644 (file)
@@ -19,23 +19,19 @@ prefix              = @prefix@
 exec_prefix    = @exec_prefix@
 sbindir                = @sbindir@
 
-COBJS  = identd.o parse.o kernel.o kernel_helper.o kvm.o ident_auth.o \
-         tables.o gssapi.o @LIBOBJS@
+COBJS  = identd.o parse.o ident_auth.o tables.o gssapi.o @LIBOBJS@
+KOBJS  = kernel.o kernel_helper.o pkvm.o
 
 all: sidentd
 
-sidentd: $(COBJS) 
-       $(CC) $(LDFLAGS) -o sidentd $(COBJS) $(LIBS)
+sidentd: $(COBJS) $(KOBJS)
+       $(CC) $(LDFLAGS) -o sidentd $(COBJS) $(KOBJS) $(LIBS)
 
-kernel.o: kernel.c identd.h error.h kernel/kvm.h Makefile
+kernel.o: kernel.c pidentd.h pkvm.h Makefile
        $(CC) $(CPPFLAGS) $(CFLAGS) -c -o kernel.o kernel.c
 
-libkvm.a: kvm.o
-       @rm -f libkvm.a
-       ar cq libkvm.a kvm.o
-
-itest: itest.o kernel.o kvm.o
-       $(CC) $(LDFLAGS) -o itest itest.o kernel.o kernel_helper.o kvm.o $(LIBS)
+itest: itest.o $(KOBJS)
+       $(CC) $(LDFLAGS) -o itest itest.o $(KOBJS) $(LIBS)
 
 clean:
        rm -f sidentd core *.o kernel/*.o
@@ -49,18 +45,19 @@ depend:
 
 
 # DO NOT DELETE THIS LINE -- make depend depends on it.
-gssapi.o: gssapi.c identd.h $(top_srcdir)/include/sident.h \
- $(top_builddir)/config.h 
+gssapi.o: gssapi.c identd.h $(top_builddir)/config.h \
+  $(top_srcdir)/include/sident.h
 ident_auth.o: ident_auth.c $(top_builddir)/config.h identd.h \
- $(top_srcdir)/include/sident.h
-identd.o: identd.c error.h identd.h $(top_srcdir)/include/sident.h \
$(top_builddir)/config.h paths.h
-itest.o: itest.c identd.h $(top_srcdir)/include/sident.h \
$(top_builddir)/config.h error.h pidentd.h
 $(top_srcdir)/include/sident.h
+identd.o: identd.c identd.h $(top_builddir)/config.h \
 $(top_srcdir)/include/sident.h
+itest.o: itest.c identd.h $(top_builddir)/config.h \
 $(top_srcdir)/include/sident.h pidentd.h
 kernel.o: kernel.c $(top_builddir)/config.h pidentd.h
-kernel_helper.o: kernel_helper.c $(top_builddir)/config.h pidentd.h
-kvm.o: kvm.c $(top_builddir)/config.h
-parse.o: parse.c error.h identd.h $(top_srcdir)/include/sident.h \
- $(top_builddir)/config.h pidentd.h
+kernel_helper.o: kernel_helper.c $(top_builddir)/config.h identd.h \
+  $(top_srcdir)/include/sident.h pidentd.h
+lifetime.o: lifetime.c
+parse.o: parse.c identd.h $(top_builddir)/config.h \
+  $(top_srcdir)/include/sident.h pidentd.h
 pkvm.o: pkvm.c $(top_builddir)/config.h
 tables.o: tables.c
diff --git a/responder/error.h b/responder/error.h
deleted file mode 100644 (file)
index 6162e48..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-/** @file
- * Error handling macros.
- *
- * This program is in the public domain and may be used freely by anyone who
- * wants it.
- *
- * @date Last updated 1992-Aug-19
- * @author Peter Eriksson <pen@lysator.liu.se>
- *
- * $Id$
- */
-
-#ifndef ERROR_H
-#define ERROR_H 1
-
-#include <syslog.h>
-
-#define ERROR(fmt) \
-    ((syslog_flag ? (syslog(LOG_ERR, fmt),0) : 0), \
-     (debug_flag ? (fprintf(stderr, "%d , %d : ERROR : X-DBG : ", \
-                           lport, fport), \
-                   fprintf(stderr, fmt), perror(": "), 0) : \
-      (printf("%d , %d : ERROR : UNKNOWN-ERROR\r\n", lport, fport), 0)), \
-     fflush(stdout), fflush(stderr), exit(1), 0)
-
-
-#define ERROR1(fmt,v1) \
-    ((syslog_flag ? (syslog(LOG_ERR, fmt, v1),0) : 0), \
-     (debug_flag ? (fprintf(stderr, "%d , %d : ERROR : X-DBG : ", \
-                           lport, fport), \
-                   fprintf(stderr, fmt, v1), perror(": "), 0) : \
-      (printf("%d , %d : ERROR : UNKNOWN-ERROR\r\n", lport, fport), 0)), \
-     fflush(stdout), fflush(stderr), exit(1), 0)
-
-#define ERROR2(fmt,v1,v2) \
-    ((syslog_flag ? (syslog(LOG_ERR, fmt, v1, v2),0) : 0), \
-     (debug_flag ? (fprintf(stderr, "%d , %d : ERROR : X-DBG : ", \
-                           lport, fport), \
-                   fprintf(stderr, fmt, v1, v2), perror(": "), 0) : \
-      (printf("%d , %d : ERROR : UNKNOWN-ERROR\r\n", lport, fport), 0)), \
-     fflush(stdout), fflush(stderr), exit(1), 0)
-
-#endif /* ERROR_H */
index b2cabd94ae390f01d23008e4bafa993c9b6cf299..d01b4b4ea8c9a1ebbe99b991a0576bda8bab26a8 100644 (file)
@@ -5,6 +5,32 @@
  * @date 1996-08-28
  *
  * $Id$
+ *
+ * Much of this code was originally taken from acte_krb.c in the Cyrus IMAP
+ * distribution.  At the time, the copyright and license statement was as
+ * follows:
+ *
+ *      (C) Copyright 1994 by Carnegie Mellon University
+ *
+ *                      All Rights Reserved
+ *
+ * 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 appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Carnegie Mellon University not be used
+ * in advertising or publicity pertaining to distribution of the software
+ * without specific, written prior permission.  Carnegie Mellon University
+ * makes no representations about the suitability of this software for any
+ * purpose.  It is provided "as is" without express or implied warranty.
+ *
+ * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS,
+ * IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY 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 "config.h"
 #include <errno.h>
 #include <netdb.h>
 #include <netinet/in.h>
-#include <pwd.h> 
+#include <pwd.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include <sys/param.h>
-#include <sys/socket.h> 
+#include <sys/socket.h>
 #include <sys/stat.h>
 #include <sys/time.h>
 #include <sys/types.h>
 #include <syslog.h>
 
-#include <krb.h>
+#ifdef HAVE_KERBEROSIV_KRB_H
+# include <kerberosIV/krb.h>
+#else
+# include <krb.h>
+#endif
 
-#include "identd.h" 
+#include "identd.h"
 
 /* Exported definition of responder authentication mechanism */
-static int krb_responder_start(); 
-static int null_responder_start(); 
-static int krb_responder_auth(); 
-static int null_responder_auth(); 
-static void krb_free_state(); 
-static void null_free_state(); 
-static int trivial_responder_start(); 
+static int krb_responder_start();
+static int null_responder_start();
+static int krb_responder_auth();
+static int null_responder_auth();
+static void krb_free_state();
+static void null_free_state();
+static int trivial_responder_start();
 static int trivial_responder_auth();
 
 extern int do_out();
@@ -77,57 +107,58 @@ struct ident_responder_auth trivial_ident_auth = {
     null_free_state
 };
 
-
 #define IDENT_METHODS_COUNT 4
-/* TRIVIAL method must always be the last method */ 
-#define IDENT_TRIVIAL_METHOD (IDENT_METHODS_COUNT - 1 ) 
-struct ident_responder_auth *auth_methods[IDENT_METHODS_COUNT] = { &krb_ident_auth, 
-                                               &gssapi_ident_auth,
-                                               &otp_ident_auth,
-                                               &trivial_ident_auth
-}; 
-
-int 
-parse_auth(line,auth_struct)
-char *line;  
-struct ident_responder_auth **auth_struct ; 
-{ 
-  int rcode ;
-  int i ; 
-  char auth_method[128] ;
-  *auth_struct = NULL ; 
-  if ( line == NULL ) { 
-    *auth_struct = auth_methods[IDENT_TRIVIAL_METHOD] ; 
-    return IDENT_AUTH_OKAY ; 
-  }
-  /* Grok to the next , */ 
-
-  rcode = sscanf(line ," %32[^ \t\n\r,]",auth_method ); 
-  
-
-  for(i = 0 ; i < IDENT_METHODS_COUNT ; i++ ) { 
-    if ( strncmp(auth_method,auth_methods[i]->auth_method,
-                strlen(auth_methods[i]->auth_method)) == 0 ) {
-      *auth_struct = auth_methods[i] ; 
-      return(IDENT_AUTH_OKAY) ; 
-    }
-  }
-  return(IDENT_INVALID_REQ_INFO); 
-  
-  
-} 
 
+/* TRIVIAL method must always be the last method */
+#define IDENT_TRIVIAL_METHOD (IDENT_METHODS_COUNT - 1 )
 
-/* All the code from here to EOF is C&P from imclient.c in the imap.1.4
-libraries. 
-*/ 
+struct ident_responder_auth *auth_methods[IDENT_METHODS_COUNT] = {
+    &krb_ident_auth, &gssapi_ident_auth, &otp_ident_auth, &trivial_ident_auth
+};
 
-#define XX 127
-/*
- * Tables for encoding/decoding base64
+/** Given a line from a requester, find the requested auth type.
+ *
+ * If the line is NULL, assume the trivial (traditional) method.  Otherwise,
+ * find a case-sensitive match for the authentication method given in the
+ * table of acceptable authentication methods.  Set auth_struct to the struct
+ * for the one found.
+ *
+ * @param line The input from the requester.
+ * @param auth_struct Set to the struct corresponding to the desired method.
+ * @return An error code or #IDENT_AUTH_OKAY.
  */
+int
+parse_auth(char *line, struct ident_responder_auth **auth_struct)
+{
+    int i, rcode;
+    char auth_method[128];
+    const char *method;
+
+    *auth_struct = NULL;
+    if (line == NULL) {
+        *auth_struct = auth_methods[IDENT_TRIVIAL_METHOD];
+        return IDENT_AUTH_OKAY;
+    }
+
+    /* Parse the line to find the authentication method. */
+    rcode = sscanf(line, " %32[^ \t\n\r,]", auth_method);
+    if (rcode != 1)
+        return IDENT_INVALID_REQ_INFO;
+    for (i = 0; i < IDENT_METHODS_COUNT; i++) {
+        method = auth_methods[i]->auth_method;
+        if (strncmp(auth_method, method, strlen(method)) == 0) {
+            *auth_struct = auth_methods[i];
+            return IDENT_AUTH_OKAY;
+        }
+    }
+    return IDENT_INVALID_REQ_INFO;
+}
+
+
+/* Tables for encoding and decoding base64. */
 static const char basis_64[] =
-   "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+    "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+#define XX 127
 static const char index_64[256] = {
     XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX,
     XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX,
@@ -148,649 +179,577 @@ static const char index_64[256] = {
 };
 #define CHAR64(c)  (index_64[(unsigned char)(c)])
 
-/*
- * Decode in-place the base64 data in 'input'.  Returns the length
- * of the decoded data, or -1 if there was an error.
+/** Decode in-place a buffer encoded in base64.
+ *
+ * @param input The buffer containing base64 data to decode.
+ * @return Length of the decoded data, or -1 on error.
  */
-int 
-ident_decodebase64(input)
-char *input;
+int
+ident_decodebase64(char *input)
 {
     int len = 0;
     unsigned char *output = (unsigned char *)input;
     int c1, c2, c3, c4;
 
     while (*input) {
-       c1 = *input++;
-       if (CHAR64(c1) == XX) return -1;
-       c2 = *input++;
-       if (CHAR64(c2) == XX) return -1;
-       c3 = *input++;
-       if (c3 != '=' && CHAR64(c3) == XX) return -1; 
-       c4 = *input++;
-       if (c4 != '=' && CHAR64(c4) == XX) return -1;
-       *output++ = (CHAR64(c1) << 2) | (CHAR64(c2) >> 4);
-       ++len;
-       if (c3 == '=') break;
-       *output++ = ((CHAR64(c2) << 4) & 0xf0) | (CHAR64(c3) >> 2);
-       ++len;
-       if (c4 == '=') break;
-       *output++ = ((CHAR64(c3) << 6) & 0xc0) | CHAR64(c4);
-       ++len;
+        c1 = *input++;
+        if (CHAR64(c1) == XX)
+            return -1;
+        c2 = *input++;
+        if (CHAR64(c2) == XX)
+            return -1;
+        c3 = *input++;
+        if (c3 != '=' && CHAR64(c3) == XX)
+            return -1;
+        c4 = *input++;
+        if (c4 != '=' && CHAR64(c4) == XX)
+            return -1;
+        *output++ = (CHAR64(c1) << 2) | (CHAR64(c2) >> 4);
+        ++len;
+        if (c3 == '=')
+            break;
+        *output++ = ((CHAR64(c2) << 4) & 0xf0) | (CHAR64(c3) >> 2);
+        ++len;
+        if (c4 == '=')
+            break;
+        *output++ = ((CHAR64(c3) << 6) & 0xc0) | CHAR64(c4);
+        ++len;
     }
 
     return len;
 }
-       
 
-/*
- * Write to the string 'output' the base-64 encoded data
- * 'input', of (unencoded) length 'len'.
+/** Encode data into base64.
+ *
+ * The output buffer must be long enough to hold the encoded input.
+ *
+ * @param input Data to encode.
+ * @param output Buffer into which to write the encoded data.
+ * @param len The length of the input (not the size of the output buffer).
  */
-
 void
-ident_writebase64(input, output, len)
-char *input;
-char *output;
-int len;
+ident_writebase64(char *input, char *output, int len)
 {
     char buf[IDENT_BUFFER_SIZE];
-    char *outptr ; 
+    char *outptr;
     int buflen = 0;
     int c1, c2, c3;
-    outptr = output ; 
-    while (len) {
-       if (buflen >= sizeof(buf)-4) {
-           strncpy(outptr,buf,buflen);
-           buflen = 0;
-           outptr += buflen ; 
-       }
-       
-       c1 = (unsigned char)*input++;
-       buf[buflen++] = basis_64[c1>>2];
-
-       if (--len == 0) c2 = 0;
-       else c2 = (unsigned char)*input++;
-       buf[buflen++] = basis_64[((c1 & 0x3)<< 4) | ((c2 & 0xF0) >> 4)];
-
-       if (len == 0) {
-           buf[buflen++] = '=';
-           buf[buflen++] = '=';
-           break;
-       }
-
-       if (--len == 0) c3 = 0;
-       else c3 = (unsigned char)*input++;
-
-       buf[buflen++] = basis_64[((c2 & 0xF) << 2) | ((c3 & 0xC0) >>6)];
-       if (len == 0) {
-           buf[buflen++] = '=';
-           break;
-       }
-
-       --len;
-       buf[buflen++] = basis_64[c3 & 0x3F];
-    }
 
-    if (buflen >= sizeof(buf)-2) {
-       strncpy(outptr, buf, buflen);
-       outptr += buflen ; 
-       buflen = 0;
-    }
-    buf[buflen++] = '\0';
-    strcpy(outptr, buf);
-}
+    outptr = output;
+    while (len > 0) {
+        if (buflen >= sizeof(buf) - 4) {
+            strncpy(outptr, buf, buflen);
+            buflen = 0;
+            outptr += buflen;
+        }
 
-/* 
-**
-**     Kerberos auth routines
-**
-**
-*/ 
+        c1 = (unsigned char) *input++;
+        buf[buflen++] = basis_64[c1 >> 2];
 
+        if (--len == 0)
+            c2 = 0;
+        else
+            c2 = (unsigned char) *input++;
+        buf[buflen++] = basis_64[((c1 & 0x3) << 4) | ((c2 & 0xF0) >> 4)];
 
-/* acte_krb.c -- KERBEROS_V4 authentication routines for IMAP.
- *
- *     (C) Copyright 1994 by Carnegie Mellon University
- *
- *                      All Rights Reserved
- *
- * 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 appear in all copies
- * and that both that copyright notice and this permission notice
- * appear in supporting documentation, and that the name of Carnegie
- * Mellon University not be used in advertising or publicity
- * pertaining to distribution of the software without specific,
- * written prior permission.  Carnegie Mellon University makes no
- * representations about the suitability of this software for any
- * purpose.  It is provided "as is" without express or implied
- * warranty.
- *
- * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO
- * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY 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.
- *
- */
+        if (len == 0) {
+            buf[buflen++] = '=';
+            buf[buflen++] = '=';
+            break;
+        }
+
+        if (--len == 0)
+            c3 = 0;
+        else
+            c3 = (unsigned char) *input++;
+        buf[buflen++] = basis_64[((c2 & 0xF) << 2) | ((c3 & 0xC0) >> 6)];
+
+        if (len == 0) {
+            buf[buflen++] = '=';
+            break;
+        }
 
-extern char *lcase();
-extern char *krb_get_phost(), *krb_realmofhost();
+        --len;
+        buf[buflen++] = basis_64[c3 & 0x3F];
+    }
 
-/* Maximum number of bytes of overhead the protection mechanisms use */
-#define PROTECTION_OVERHEAD 31
+    if (buflen >= sizeof(buf) - 2) {
+        strncpy(outptr, buf, buflen);
+        outptr += buflen;
+        buflen = 0;
+    }
+    buf[buflen++] = '\0';
+    strcpy(outptr, buf);
+}
 
 /* Private state used by this mechanism */
 struct krb_state {
-    /* common */
-    char service[MAX_K_NAME_SZ+1];
+    char service[MAX_K_NAME_SZ + 1];
     int authstepno;
-    des_cblock session;        /* Our session key */
-    des_key_schedule schedule; /* Schedule for our session key */
+    des_cblock session;         /* Our session key */
+    des_key_schedule schedule;  /* Schedule for our session key */
     int32_t challenge;
-    char user[MAX_K_NAME_SZ+1];
-    int protallowed;
-    int maxbufsize;
-    struct sockaddr_in localaddr, remoteaddr;
-    long prot_time_sec;
-    char prot_time_5ms;
-    /* client */
+
+    /* Used by client. */
     char instance[INST_SZ];
     char realm[REALM_SZ];
-    /* server */
-    int (*authproc)();
-    AUTH_DAT kdata;
 };
 
-/*
- * Free the space used by an opaque state pointer
+/** Free the space used by the opaque mechanism state pointer.
+ *
+ * @param state Pointer to free.
  */
 static void
-krb_free_state(state)
-void *state;
+krb_free_state(void *state)
 {
-    memset((char *)state, 0, sizeof(struct krb_state));
-    free((char *) state);
+    memset(state, 0, sizeof(struct krb_state));
+    free(state);
 }
 
-static int krb_is_ticket(tf_name,auth_data)
-   char *tf_name; 
-   struct ident_auth_data *auth_data; 
+/** Check whether a file is a valid ticket for our user of interest.
+ *
+ * @param tf_name The name of the file to check.
+ * @param auth_data Data about the authentication we're attempting.
+ * @return Returns a Kerberos status code (KSUCCESS on success).
+ */
+static int
+krb_is_ticket(char *tf_name, struct ident_auth_data *auth_data)
 {
- struct stat stat_buf; 
- int code ; 
- char    pname[ANAME_SZ];
- char    pinst[INST_SZ];
- CREDENTIALS cred;
- time_t now;
-
- if (lstat(tf_name, &stat_buf) < 0) {
-       if ( debug_flag && syslog_flag ) { 
-        syslog(LOG_DEBUG,"lstat error %d on %s",errno,tf_name); 
-     }
-     switch (errno) {
-        case ENOENT:
-            return NO_TKT_FIL;
-        default:
-            return TKT_FIL_ACC;
-        }
- }
-
- /* Check ownership */ 
- if (stat_buf.st_uid != auth_data->uid ) { 
-     if ( debug_flag && syslog_flag ) { 
-        syslog(LOG_DEBUG,"UID mismatch %d : %d on %s",stat_buf.st_uid,auth_data->uid,tf_name); 
-     }
-   return TKT_FIL_ACC;
- }     
- /* Check file perms for 600 */ 
- if ( (stat_buf.st_mode & S_IRUSR) != S_IRUSR ) {   
-   if ( debug_flag && syslog_flag ) { 
-        syslog(LOG_DEBUG,"User can't read %s",tf_name); 
-     }
-
-   return TKT_FIL_ACC ; 
- }
-
- if ( 
-    ((stat_buf.st_mode & S_IRGRP) ==  S_IRGRP) ||
-    ((stat_buf.st_mode  & S_IWGRP) == S_IWGRP) ||
-    ((stat_buf.st_mode  & S_IROTH) ==  S_IROTH)||
-    ((stat_buf.st_mode  & S_IWOTH) ==  S_IWOTH) ) { 
-   
-   if (syslog_flag ) { 
-     syslog(LOG_ALERT,"Incorrect file permissons on %s : %o",tf_name,stat_buf.st_mode); 
-   }
- return TKT_FIL_ACC ; 
- }
- /* Okay now we should have a valid tkt file, let's look */ 
- /* Following src is C&P from klist.c in krb4. */ 
-
- /* Open ticket file */
- code =  tf_init(tf_name, R_TKT_FIL); 
- if ( code != KSUCCESS ) { 
-   tf_close() ; 
-  if ( debug_flag && syslog_flag ) { 
-        syslog(LOG_DEBUG,"tf_init failed %s",tf_name); 
-     }
-
-   return code ;
- }
- /* Get principal name and instance */
- if ((code = tf_get_pname(pname)) ||
-     (code  = tf_get_pinst(pinst))) {
-   tf_close () ; 
-   return code ; 
- }
-
- /* Ensure ticket is valid */
- now = time(NULL);
- while (tf_get_cred(&cred) == KSUCCESS) {
-   if (strcmp(cred.service,"krbtgt"))
-     continue;
-#ifdef SHORT_LIFETIME
-   cred.issue_date += ((unsigned char) cred.lifetime) * 5 * 60;
-#else
-   cred.issue_date = krb_life_to_time(cred.issue_date, cred.lifetime);
-#endif
-   if (now - cred.issue_date > 1 ) {
-     tf_close () ;
-     return KFAILURE ;
-   }
- }
- tf_close() ; 
- if ( syslog_flag ) { 
-   syslog(LOG_INFO,"Ticket file %s : %s.%s for %d",tf_name,pname,pinst,auth_data->uid ); 
- }
-          
- return KSUCCESS ; 
-}
+    struct stat stat_buf;
+    int code;
+    char pname[ANAME_SZ];
+    char pinst[INST_SZ];
+    CREDENTIALS cred;
+    time_t now;
+
+    /* Can we even stat the file? */
+    if (lstat(tf_name, &stat_buf) < 0) {
+        if (debug_flag && syslog_flag)
+            syslog(LOG_DEBUG, "lstat error %d on %s", errno, tf_name);
+        return (errno == ENOENT) ? NO_TKT_FIL : TKT_FIL_ACC;
+    }
 
+    /* Check ownership */
+    if (stat_buf.st_uid != auth_data->uid ) {
+        if (debug_flag && syslog_flag)
+            syslog(LOG_DEBUG, "UID mismatch %d : %d on %s", stat_buf.st_uid,
+                   auth_data->uid, tf_name);
+        return TKT_FIL_ACC;
+    }
 
-static int krb_find_ticket(tktstring,auth_data)
-     char *tktstring; 
-     struct ident_auth_data *auth_data; 
-{
-  int rcode ; 
-  char temp[MAXPATHLEN]; 
-  /* this is OS depedent */ 
-  DIR *temp_dir ; 
-  struct dirent *dp ; 
-
-  /* Need to set tkt file here */ 
-  /* This is cheating we need to dive kernel and get TKTFILE from ENV */        /* try krb4 standard */ 
-  sprintf(tktstring, "/tmp/tkt%d", auth_data->uid);
-
-  rcode = krb_is_ticket(tktstring,auth_data) ;  
-  if (rcode  == KSUCCESS ) {
-    return IDENT_AUTH_OKAY ; 
-  }
-
-  /* Now we will try grupping through /tmp for a "ticket file" */ 
-
-  temp_dir = opendir("/tmp") ; 
-
-  for (dp = readdir(temp_dir); dp != NULL; dp = readdir(temp_dir)){
-    if ( strncmp(dp->d_name, "tkt",strlen("tkt")) == 0 ) {
-      if (strlen(dp->d_name) >= MAXPATHLEN-6)
-       continue;
-      sprintf(temp,"/tmp/%s",dp->d_name); 
-      rcode = krb_is_ticket(temp,auth_data); 
-      if (rcode  == KSUCCESS ) {
-       strncpy(tktstring,temp,MAXPATHLEN-1); 
-       closedir(temp_dir);
-       return IDENT_AUTH_OKAY ; 
-      }
-      if (syslog_flag && debug_flag ){
-       syslog(LOG_DEBUG,"Rejected %s : %d",dp->d_name,rcode); 
-      }
-      
+    /* Check file perms for 600. */
+    if ((stat_buf.st_mode & S_IRUSR) != S_IRUSR) {
+        if (debug_flag && syslog_flag)
+            syslog(LOG_DEBUG, "User can't read %s", tf_name);
+        return TKT_FIL_ACC;
+    }
+    if (   ((stat_buf.st_mode & S_IRGRP) == S_IRGRP)
+        || ((stat_buf.st_mode & S_IWGRP) == S_IWGRP)
+        || ((stat_buf.st_mode & S_IROTH) == S_IROTH)
+        || ((stat_buf.st_mode & S_IWOTH) == S_IWOTH)) {
+        if (syslog_flag)
+            syslog(LOG_ALERT, "Incorrect file permissons on %s : %o",
+                   tf_name, stat_buf.st_mode);
+        return TKT_FIL_ACC ;
     }
-  }
-  closedir(temp_dir);
 
+    /* Okay now we should have a valid ticket file.  Let's look.  The
+       following was mostly taken directly from klist.c in Kerberos v4. */
 
-  return IDENT_USER_CANT_AUTH ; 
-}
+    /* Open ticket file */
+    code =  tf_init(tf_name, R_TKT_FIL);
+    if (code != KSUCCESS) {
+        tf_close();
+        if (debug_flag && syslog_flag)
+            syslog(LOG_DEBUG, "tf_init failed %s", tf_name);
+        return code;
+    }
 
+    /* Get principal name and instance. */
+    if ((code = tf_get_pname(pname)) || (code = tf_get_pinst(pinst))) {
+        tf_close();
+        return code;
+    }
 
+    /* Ensure ticket is valid. */
+    now = time(NULL);
+    while (tf_get_cred(&cred) == KSUCCESS) {
+        if (strcmp(cred.service, "krbtgt") != 0)
+            continue;
+        cred.issue_date = krb_life_to_time(cred.issue_date, cred.lifetime);
+        if (now - cred.issue_date > 1) {
+            tf_close();
+            return KFAILURE;
+        }
+    }
+    tf_close();
+    if (syslog_flag)
+        syslog(LOG_INFO, "Ticket file %s : %s.%s for %d", tf_name, pname,
+               pinst, auth_data->uid);
 
+    return KSUCCESS;
+}
 
+/** Find a valid ticket for the user in /tmp.
+ *
+ * @param tktstring Buffer that will hold the path to the ticket file.
+ * @param auth_data Data about the authentication we're attempting.
+ * @return An error code or #IDENT_AUTH_OKAY.
+ */
+static int
+krb_find_ticket(char *tktstring, struct ident_auth_data *auth_data)
+{
+    int rcode;
+    char temp[MAXPATHLEN];
+    DIR *temp_dir;
+    struct dirent *dp;
+
+    /* Ideally, we want to dive into the kernel and get TKTFILE from the
+       environment of the user's process.  Right now, we just cheat and look
+       in typical places.  Start by trying the K4 standard. */
+    sprintf(tktstring, "/tmp/tkt%d", auth_data->uid);
+    if (krb_is_ticket(tktstring, auth_data) == KSUCCESS)
+        return IDENT_AUTH_OKAY;
+
+    /* Now we will try grupping through /tmp for a ticket file. */
+    temp_dir = opendir("/tmp");
+    for (dp = readdir(temp_dir); dp != NULL; dp = readdir(temp_dir)) {
+        if (strncmp(dp->d_name, "tkt", strlen("tkt")) != 0)
+            continue;
+        if (strlen(dp->d_name) >= MAXPATHLEN - 6)
+            continue;
+        sprintf(temp, "/tmp/%s", dp->d_name);
+        rcode = krb_is_ticket(temp, auth_data);
+        if (rcode == KSUCCESS ) {
+            strncpy(tktstring, temp, MAXPATHLEN - 1);
+            closedir(temp_dir);
+            return IDENT_AUTH_OKAY;
+        }
+        if (syslog_flag && debug_flag)
+            syslog(LOG_DEBUG, "Rejected %s : %d", dp->d_name, rcode);
+    }
+    closedir(temp_dir);
+    return IDENT_USER_CANT_AUTH;
+}
 
-/*
- * Start the responder side of an authentication exchange.
+/** Start the responder side of an authentication exchange.
+ *
+ * This function doesn't send any data to the remote system.  It just makes
+ * sure that we have a ticket file for the user and obtains the needed service
+ * ticket that we'll use later on.
+ *
+ * @param auth_data Data about the authentication we're attempting.
+ * @return An error code or #IDENT_AUTH_OKAY.
  */
-static int krb_responder_start(auth_data)
-  struct ident_auth_data *auth_data ; 
+static int
+krb_responder_start(struct ident_auth_data *auth_data)
 {
     struct hostent *host_name;
     char *host;
     char instance[INST_SZ];
     char realm[REALM_SZ];
-    char tktstring[MAXPATHLEN]; 
+    char tktstring[MAXPATHLEN];
     KTEXT_ST authent;
     CREDENTIALS cr;
     struct krb_state *kstate;
     char *p;
 
-    kstate = ( struct krb_state *) malloc(sizeof(struct krb_state)) ; 
-    if ( kstate == NULL )
-      return IDENT_SYSTEM_ERROR ; 
-    if (  krb_find_ticket(&tktstring,auth_data) != IDENT_AUTH_OKAY ) {
-      return IDENT_USER_CANT_AUTH ; 
-    } 
+    kstate = malloc(sizeof(struct krb_state));
+    if (kstate == NULL)
+        return IDENT_SYSTEM_ERROR;
+    if (krb_find_ticket(tktstring, auth_data) != IDENT_AUTH_OKAY)
+        return IDENT_USER_CANT_AUTH;
     krb_set_tkt_string(tktstring);
 
-    /* Canonicalize hostname */
-    host_name = gethostbyaddr((char *) (auth_data->remote_addr), sizeof(struct in_addr), AF_INET);
-    if (!host_name) {
-       return IDENT_SYSTEM_ERROR;
-    }
+    /* Get the name of the remote host to determine the service ticket. */
+    host_name = gethostbyaddr((char *) auth_data->remote_addr,
+                              sizeof(struct in_addr), AF_INET);
+    if (host_name == NULL)
+        return IDENT_SYSTEM_ERROR;
     host = strdup(host_name->h_name);
     if (host == NULL)
         return IDENT_SYSTEM_ERROR;
-    
-    strncpy(instance, host_name->h_name, sizeof(instance)-1);
-    instance[sizeof(instance)-1] = '\0';
+
+    /* Form the name of the service ticket. */
+    strncpy(instance, host_name->h_name, sizeof(instance) - 1);
+    instance[sizeof(instance) - 1] = '\0';
     p = strchr(instance, '.');
     if (p != NULL)
         *p = '\0';
-    
-    p = instance ; 
-
-    while ( *p != '\0' ) { 
-      if ( isupper((int) *p) ) { 
-       *p = tolower((int) *p) ; 
-      }
-      p++ ; 
-    }
-  
-    strncpy(realm, krb_realmofhost(host),(REALM_SZ - 1));
+    for (p = instance; *p != '\0'; p++)
+        if (isupper((int) *p))
+            *p = tolower((int) *p);
+    strncpy(realm, krb_realmofhost(host), REALM_SZ - 1);
     free(host);
+    if (syslog_flag && debug_flag)
+        syslog(LOG_DEBUG, "Fetching ticket :%s.%s@%s:",
+               IDENT_AUTH_KRB_SERVICE, instance, realm);
 
-    if (syslog_flag && debug_flag ){
-       syslog(LOG_DEBUG,"Fetching ticket :%s.%s@%s:",
-              IDENT_AUTH_KRB_SERVICE,instance,realm); 
-    }  
-
-    /* Fetch imap.hostname service key */
-    (void) krb_mk_req(&authent,IDENT_AUTH_KRB_SERVICE , instance, realm, 0);
+    /* Fetch the service ticket and initialize our state information. */
+    krb_mk_req(&authent, IDENT_AUTH_KRB_SERVICE, instance, realm, 0);
     memset(&authent, 0, sizeof(authent));
-
-    if (krb_get_cred(IDENT_AUTH_KRB_SERVICE , instance, realm, &cr)) {
-       return IDENT_USER_CANT_AUTH;
-    }
-    
-    /* Do we need to know who we are ? */ 
-    /*     strcpy(kstate->user, user); */ 
-    
-    memset((char *)kstate, 0, sizeof(*kstate));
+    if (krb_get_cred(IDENT_AUTH_KRB_SERVICE, instance, realm, &cr))
+        return IDENT_USER_CANT_AUTH;
+    memset(kstate, 0, sizeof(*kstate));
     strcpy(kstate->service, IDENT_AUTH_KRB_SERVICE);
     kstate->authstepno = 0;
     memcpy(kstate->session, cr.session, sizeof(des_cblock));
     des_key_sched(kstate->session, kstate->schedule);
-
-
     strcpy(kstate->instance, instance);
     strcpy(kstate->realm, realm);
-
     memset(&cr, 0, sizeof(cr));
-    auth_data->auth_method_data = (void *)kstate;
-    return IDENT_AUTH_OKAY ; 
+    auth_data->auth_method_data = kstate;
+
+    return IDENT_AUTH_OKAY;
 }
 
-/*
- * Perform responder-side authentication protocol exchange
- * Returns IDENT_AUTH_OKAY if authentication can be complete after
- * sending our responder reply.
+/** Perform responder-side authentication protocol exchange.
+ *
+ * This function talks to the remote system, passing along the required
+ * Kerberos v4 SASL information.  It does mutual authentication if needed and
+ * then returns the status of the authentication.
+ *
+ * @param auth_data Data about the authentication we're attempting.
+ * @return An error code or #IDENT_AUTH_OKAY.
  */
-static int krb_responder_auth(auth_data)
-  struct ident_auth_data *auth_data ;
+static int
+krb_responder_auth(struct ident_auth_data *auth_data)
 {
     static KTEXT_ST authent;
-    struct krb_state *kstate = (struct krb_state *) auth_data->auth_method_data;
+    struct krb_state *kstate = auth_data->auth_method_data;
     char tmp[IDENT_BUFFER_SIZE];
-    char resp[IDENT_BUFFER_SIZE]; 
-    char output[IDENT_BUFFER_SIZE]; 
-    char *resp_ptr ; 
+    char resp[IDENT_BUFFER_SIZE];
+    char output[IDENT_BUFFER_SIZE];
+    char *resp_ptr ;
     char line[IDENT_BUFFER_SIZE];
-    char *line_ptr ; 
-    IDENT_INT16 i,j,k,resp_len, len , munch; 
-    int32_t challenge ; 
-    struct ident_auth_data auth_reply ; 
-    int code,rcode;
-    int timeout = IDENT_READ_TIMEOUT ; 
-    struct passwd *paswd_entry ;
-
-    while ( kstate->authstepno > -1 ) { 
-      switch (kstate->authstepno++) {
-      case 0:
-       /* Get challenge */ 
-       sscanf(auth_data->authenticate_data," KERBEROS_V4 , %[A-Za-z0-9+/=]",tmp ) ; 
-       rcode = ident_decodebase64(tmp); 
-       
-       /* Requester gave us challenge, respond with ticket+authenticator */
-       if (rcode < 4) {
-         kstate->authstepno = -1;
-         return IDENT_INVALID_REQ_INFO;
-       }
-       
-       kstate->challenge = ntohl(*(int *)tmp);
-
-       
-       code = krb_mk_req(&authent, kstate->service, kstate->instance,
-                         kstate->realm, kstate->challenge);
-       if (code) {
-         kstate->authstepno = -1;
-         return IDENT_AUTH_FAIL;
-       }
-       /* Now we need to formulate the response */ 
-       /* port, port : AUTHENTICATE : KERBEROS_V4, BASE64(htonl(authent.len)athent.dat htonl(identent.len)identent.dat) */ 
-       /* the ident dat looks like 
-       ** [16bit flag][resp port][req port][authid len][authid][pad] 
-       **  16 hton     16 hton    16 hton   16 hton     ???     pad to multiple of 8 
-       ** And then the whole thing is encrypted with the session key
-       */ 
-       
-       munch = sizeof(IDENT_INT16) ; 
-
-       /* memcpy(to,from,length ) */ 
-       k = htons(mutual_auth_flag) ; 
-       resp_ptr = resp ; 
-       memcpy(resp_ptr,&k,munch) ; 
-       
-
-
-       k = htons(auth_data->local_port) ; 
-       resp_ptr += munch ; 
-       memcpy(resp_ptr,&k,munch) ; 
-
-       k = htons(auth_data->remote_port) ; 
-       resp_ptr += munch ; 
-       memcpy(resp_ptr,&k,munch) ; 
-       
-
-       paswd_entry = getpwuid(auth_data->uid);
-       i = strlen(paswd_entry->pw_name); 
-
-       k = htons(i) ;
-       resp_ptr += munch ; 
-       memcpy(resp_ptr,&k,munch) ;
-       resp_ptr += munch ;
-
-       strcpy(resp_ptr,paswd_entry->pw_name);
-
-       k = sizeof(des_cblock) ; 
-       j = i%k; 
-       resp_ptr += i ; 
-
-       /* Pad to a multiple of sizeof(des_cblock)  */ 
-       bzero(resp_ptr,k-j) ; 
-       resp_len = 4*(munch)+i+k-j ;
-       
-       if ( syslog_flag && debug_flag ) { 
-         syslog(LOG_DEBUG,"Data: %4.4x:%4.4x:%4.4x:%4.4x:%s",
-                htons(mutual_auth_flag) ,
-                htons(auth_data->remote_port),
-                htons(auth_data->local_port),
-                htons(i),
-                paswd_entry->pw_name);
-         syslog(LOG_DEBUG,"Resp:%d:%4.4x:%4.4x:%4.4x:%4.4x:%s",munch,
-                *((IDENT_INT16*) resp),
-                *((IDENT_INT16*) &(resp[munch])),
-                *((IDENT_INT16*) &(resp[2*munch])),
-                *((IDENT_INT16*) &(resp[3*munch])),
-                &(resp[4*munch]));
-       }
-       des_pcbc_encrypt((des_cblock *) resp,(des_cblock *) output, resp_len ,kstate->schedule,&(kstate->session),1 ) ; 
-       
-       resp_ptr = tmp ; 
-        k = htons(authent.length); 
-       memcpy(resp,(char*)&k,(munch)); 
-       resp_ptr = &(resp[(munch)]); 
-       memcpy(resp_ptr,authent.dat,authent.length); 
-       resp_ptr = &(resp[(munch)+authent.length]); 
-       k = htons(resp_len); 
-       memcpy(resp_ptr,(char *)&k,(munch)); 
-       resp_ptr = &(resp[(munch)+authent.length+(munch)]);
-       memcpy(resp_ptr,output,resp_len); 
-       len = munch + authent.length + munch + resp_len ;
-       ident_writebase64(resp,tmp,len); 
-       sprintf(line," AUTHENTICATE : %s , %s ",auth_data->auth_struct->auth_method,tmp ); 
-       do_out(line,auth_data); 
-
-       if (mutual_auth_flag & MUTUAL_AUTH_BIT ) { 
-         return IDENT_AUTH_OKAY;
-       }
-       break;
-       
-      case 1:
-       /*
-        * Requester gave us mutual auth reply.
-        */
-       line[0] = '\0' ; 
-       
-       line_ptr = sfgets(line,IDENT_BUFFER_SIZE,auth_data->fp,timeout,auth_data);
-       if ( line_ptr == NULL ) {
-         do_error(IDENT_NO_MUTUAL_AUTH,auth_data); 
-       }
-       rcode = parse_auth_line(line,&auth_reply);
-       if( rcode != IDENT_AUTH_OKAY ) { 
-         do_error(rcode,&auth_reply) ; 
-       }
-       /* Check if the data is the same */ 
-       if (
-           ( auth_reply.local_port != auth_data->local_port ) || 
-           ( auth_reply.remote_port != auth_data->remote_port ) || 
-           ( strncmp(auth_reply.auth_struct->auth_method ,
-                     auth_data->auth_struct->auth_method , 
-                     strlen(auth_data->auth_struct->auth_method)) != 0 ) ) { 
-
-         if (debug_flag && syslog_flag)
-           syslog(LOG_DEBUG, "Auth reply does not match auth_data %d,%d : %d,%d", auth_reply.local_port,auth_reply.remote_port,auth_data->local_port,auth_data->remote_port );
-         do_error(IDENT_MUTUAL_AUTH_FAIL,auth_data); 
-       }
-       /* Get challenge */ 
-       sscanf(auth_reply.authenticate_data," KERBEROS_V4 , %[A-Za-z0-9+/=]",tmp ) ; 
-       rcode = ident_decodebase64(tmp); 
-
-       if (rcode < 4) {
-         kstate->authstepno = -1;
-         return IDENT_INVALID_RESP_INFO;
-       }
-       
-       des_ecb_encrypt((des_cblock *)tmp, (des_cblock *)tmp,
-                        kstate->schedule, 0);
-       memcpy(&challenge,tmp,sizeof(challenge)) ; 
-       challenge = ntohl(challenge); 
-       if (challenge != kstate->challenge + 1) {
-           /* Server failed to mutually authenticte */
-           kstate->authstepno = -1;
-       if (debug_flag && syslog_flag)
-         syslog(LOG_DEBUG, "Challenge failed:%d:%d",kstate->challenge,challenge);
-           return IDENT_MUTUAL_AUTH_FAIL;
-       }           
-       if (debug_flag && syslog_flag)
-         syslog(LOG_DEBUG, "Challenge succeeded:%d:%d",kstate->challenge,challenge);
-       
-       return IDENT_AUTH_OKAY;
-
-      default:
-       kstate->authstepno = -1;
-       return IDENT_SYSTEM_ERROR;
-      }
-    }
-    return 1;
-}
-
-
-/*
-** Does trivial (i.e. passwd file based auth)
-**
-*/
-static int trivial_responder_start( auth_data)
-struct ident_auth_data *auth_data; 
-{ 
+    char *line_ptr ;
+    IDENT_INT16 i, j, k, resp_len, len, munch;
+    int32_t challenge;
+    struct ident_auth_data auth_reply;
+    int code, rcode;
+    int timeout = IDENT_READ_TIMEOUT;
+    struct passwd *paswd_entry;
+
+    while (kstate->authstepno > -1) {
+        switch (kstate->authstepno++) {
+        case 0:
+            /* Get challenge. */
+            sscanf(auth_data->authenticate_data,
+                   " KERBEROS_V4 , %[A-Za-z0-9+/=]", tmp);
+            rcode = ident_decodebase64(tmp);
+
+            /* Requester gave us challenge, respond with ticket and
+               authenticator. */
+            if (rcode < 4) {
+                kstate->authstepno = -1;
+                return IDENT_INVALID_REQ_INFO;
+            }
+            memcpy(&kstate->challenge, tmp, sizeof(int32_t));
+            kstate->challenge = ntohl(kstate->challenge);
+            code = krb_mk_req(&authent, kstate->service, kstate->instance,
+                              kstate->realm, kstate->challenge);
+            if (code != 0) {
+                kstate->authstepno = -1;
+                return IDENT_AUTH_FAIL;
+            }
+
+            /* Now we need to formulate the response.  The response should
+               look like the following:
+
+                   <port>, <port> : AUTHENTICATE : KERBEROS_V4, <auth> <ident>
+
+               <auth> is the 32-bit length of the authenticator in network
+               byte order prepended to the authenticator and then encoded in
+               base64.  <ident> is the 32-bit length of the ident information
+               in network byte order prepended to the ident information and
+               then encoded in base64.
+
+               The ident information looks like:
+
+                   [flag][resp port][req port][authid len][authid][pad]
+                   <-16-><----16---><---16---><----16----><--??--><-?->
+
+               where padding is added to the end to pad the whole thing to a
+               multiple of eight.  The entire thing is then encrypted in the
+               session key from the authenticator.  All values above are in
+               network byte order. */
+            munch = sizeof(IDENT_INT16);
+            resp_ptr = resp;
+            k = htons(mutual_auth_flag);
+            memcpy(resp_ptr, &k, munch);
+            resp_ptr += munch;
+            k = htons(auth_data->local_port);
+            memcpy(resp_ptr, &k, munch);
+            resp_ptr += munch;
+            k = htons(auth_data->remote_port);
+            memcpy(resp_ptr, &k, munch);
+            resp_ptr += munch;
+            paswd_entry = getpwuid(auth_data->uid);
+            i = strlen(paswd_entry->pw_name);
+            k = htons(i);
+            memcpy(resp_ptr, &k, munch);
+            resp_ptr += munch;
+            strcpy(resp_ptr, paswd_entry->pw_name);
+            resp_ptr += i;
+            k = sizeof(des_cblock);
+            j = i % k;
+
+            /* Pad to a multiple of sizeof(des_cblock). */
+            memset(resp_ptr, 0, k - j);
+            resp_len = 4 * (munch) + i + k - j;
+
+            /* Log what we're doing for debugging purposes. */
+            if (syslog_flag && debug_flag) {
+                syslog(LOG_DEBUG, "Data: %4.4x:%4.4x:%4.4x:%4.4x:%s",
+                       htons(mutual_auth_flag),
+                       htons(auth_data->remote_port),
+                       htons(auth_data->local_port),
+                       htons(i), paswd_entry->pw_name);
+                syslog(LOG_DEBUG, "Resp: %d:%4.4x:%4.4x:%4.4x:%4.4x:%s",
+                       munch, *((IDENT_INT16 *) resp),
+                       *((IDENT_INT16 *) &(resp[munch])),
+                       *((IDENT_INT16 *) &(resp[2 * munch])),
+                       *((IDENT_INT16 *) &(resp[3 * munch])),
+                       &(resp[4 * munch]));
+            }
+
+            /* Encrypt the ident information. */
+            des_pcbc_encrypt((des_cblock *) resp, (des_cblock *) output,
+                             resp_len, kstate->schedule, &kstate->session, 1);
+
+            /* Now, build the authenticator and convert it to base64. */
+            k = htons(authent.length);
+            memcpy(resp, &k, munch);
+            resp_ptr = &resp[munch];
+            memcpy(resp_ptr, authent.dat, authent.length);
+            resp_ptr = &resp[munch + authent.length];
+            k = htons(resp_len);
+            memcpy(resp_ptr, &k, munch);
+            resp_ptr = &resp[munch + authent.length + munch];
+            memcpy(resp_ptr, output, resp_len);
+            len = munch + authent.length + munch + resp_len;
+            ident_writebase64(resp, tmp, len);
+
+            /* Send the output to the remote side.  If we're not doing mutual
+               authentication, we're done. */
+            sprintf(line, " AUTHENTICATE : %s , %s ",
+                    auth_data->auth_struct->auth_method, tmp);
+            do_out(line, auth_data);
+            if (mutual_auth_flag & MUTUAL_AUTH_BIT)
+                return IDENT_AUTH_OKAY;
+            break;
+
+        case 1:
+            /* Requester gave us mutual auth reply. */
+            line[0] = '\0';
+            line_ptr = sfgets(line, IDENT_BUFFER_SIZE, auth_data->fp,
+                              timeout, auth_data);
+            if (line_ptr == NULL)
+                do_error(IDENT_NO_MUTUAL_AUTH, auth_data);
+            rcode = parse_auth_line(line, &auth_reply);
+            if (rcode != IDENT_AUTH_OKAY)
+                do_error(rcode, &auth_reply);
+
+            /* Check if the data is the same */
+            if (   (auth_reply.local_port != auth_data->local_port)
+                || (auth_reply.remote_port != auth_data->remote_port)
+                || (strncmp(auth_reply.auth_struct->auth_method,
+                            "KERBEROS_V4", strlen("KERBEROS_V4")) != 0)) {
+                if (debug_flag && syslog_flag)
+                    syslog(LOG_DEBUG, "Auth reply does not match auth_data"
+                           " %d,%d : %d,%d", auth_reply.local_port,
+                           auth_reply.remote_port, auth_data->local_port,
+                           auth_data->remote_port);
+                do_error(IDENT_MUTUAL_AUTH_FAIL, auth_data);
+            }
+
+            /* Get challenge */
+            sscanf(auth_reply.authenticate_data,
+                   " KERBEROS_V4 , %[A-Za-z0-9+/=]", tmp);
+            rcode = ident_decodebase64(tmp);
+            if (rcode < 4) {
+                kstate->authstepno = -1;
+                return IDENT_INVALID_RESP_INFO;
+            }
+
+            /* Decrypt the challenge and check it. */
+            des_ecb_encrypt((des_cblock *) tmp, (des_cblock *) tmp,
+                            kstate->schedule, 0);
+            memcpy(&challenge, tmp, sizeof(challenge));
+            challenge = ntohl(challenge);
+            if (challenge != kstate->challenge + 1) {
+                kstate->authstepno = -1;
+                if (debug_flag && syslog_flag)
+                    syslog(LOG_DEBUG, "Challenge failed: %d:%d",
+                           kstate->challenge, challenge);
+                return IDENT_MUTUAL_AUTH_FAIL;
+            }
+            if (debug_flag && syslog_flag)
+                syslog(LOG_DEBUG, "Challenge succeeded: %d:%d",
+                       kstate->challenge, challenge);
+            return IDENT_AUTH_OKAY;
 
-  struct passwd *paswd_entry ; 
-  if ( allow_trivial ) { 
-    paswd_entry = getpwuid(auth_data->uid);
-    if (!paswd_entry || auth_data->uid != paswd_entry->pw_uid) { 
-      do_error(IDENT_NO_USER,auth_data);
-    }
-    auth_data->auth_method_data = (void *) paswd_entry ; 
-    return IDENT_AUTH_OKAY ; 
-  } else { 
-    do_error(IDENT_INVALID_REQ_INFO,auth_data);  
-  }
-  return 1;
-} 
-
-static int trivial_responder_auth( auth_data)
-struct ident_auth_data *auth_data; 
-{ 
-  struct passwd *pwd_entry ;
-  char tmp[IDENT_BUFFER_SIZE] ; 
-  if ( allow_trivial) { 
-    /* Do we want to do noident check here ? */ 
-    pwd_entry = ( struct passwd *) auth_data->auth_method_data;  
-    if ( ! uidonly_flag ) { 
-    sprintf(tmp," USERID : UNIX :%s ",
-             pwd_entry->pw_name);
-    } else { 
-      sprintf(tmp," USERID : UNIX :%d ",
-             auth_data->uid) ; 
+        default:
+            kstate->authstepno = -1;
+            return IDENT_SYSTEM_ERROR;
+        }
     }
-    do_out(tmp,auth_data); 
-    return IDENT_AUTH_OKAY ; 
-  } else { 
-    do_error(IDENT_INVALID_REQ_INFO,auth_data); 
-  }
-  return 1;
-} 
-
-
-
-
-
+    return IDENT_AUTH_FAIL;
+}
 
-static int  null_responder_start() { 
-  return IDENT_AUTH_NOT_SUPPORTED ; 
 
+/** Start traditional ident authentication.
+ *
+ * Does nothing except retrieve the password file entry for the user UID.
+ *
+ * @param auth_data Data about the authentication we're attempting.
+ * @return An error code or #IDENT_AUTH_OKAY.
+ */
+static int
+trivial_responder_start(struct ident_auth_data *auth_data)
+{
+    struct passwd *paswd_entry;
+
+    if (allow_trivial) {
+        paswd_entry = getpwuid(auth_data->uid);
+        if (!paswd_entry || auth_data->uid != paswd_entry->pw_uid)
+            do_error(IDENT_NO_USER, auth_data);
+        auth_data->auth_method_data = paswd_entry;
+        return IDENT_AUTH_OKAY;
+    } else
+        do_error(IDENT_INVALID_REQ_INFO, auth_data);
+    return IDENT_AUTH_FAIL;
 }
 
-static int     null_responder_auth() { 
+/** Send a traditional ident response.
+ *
+ * Implements traditional ident.  Sends either the username or the UID
+ * depending on our flags if trivial authentication is enabled.
+ *
+ * @param auth_data Data about the authentication we're attempting.
+ * @return An error code or #IDENT_AUTH_OKAY.
+ */
+static int
+trivial_responder_auth(struct ident_auth_data *auth_data)
+{
+    struct passwd *pwd_entry;
+    char tmp[IDENT_BUFFER_SIZE];
 
-  return IDENT_AUTH_NOT_SUPPORTED ; 
+    /* Do we want to do noident check here? */
+    if (allow_trivial) {
+        pwd_entry = auth_data->auth_method_data;
+        if (uidonly_flag)
+            sprintf(tmp, " USERID : UNIX :%d ", auth_data->uid);
+        else
+            sprintf(tmp, " USERID : UNIX :%s ", pwd_entry->pw_name);
+        do_out(tmp, auth_data);
+        return IDENT_AUTH_OKAY;
+    } else
+        do_error(IDENT_INVALID_REQ_INFO, auth_data);
+    return IDENT_AUTH_FAIL;
 }
 
-static void     null_free_state() {
-  return ; 
-}
+/* Null responder implementations, which always return an error. */
+static int null_responder_start(void) { return IDENT_AUTH_NOT_SUPPORTED; }
+static int null_responder_auth(void)  { return IDENT_AUTH_NOT_SUPPORTED; }
+static void null_free_state(void)     { return; }
index b8b33c542b790c0e4ac454dac7ee00c441480b56..703d5a1f9a6b1e89691543b8e98c381bcf0a6807 100644 (file)
@@ -1,56 +1,75 @@
+/** @file
+ * Defines for the Kerberos v4 authentication mechanism.
+ *
+ * The contents of this file mostly match similar things in the sident.h
+ * header file.  Some things from there should be moved here, and for the rest
+ * the S/Ident responder code should just include sident.h.
+ *
+ * @author Booker C. Bense <bbense@stanford.edu>
+ *
+ * $Id$
+ */
 
-#ifndef _IDENT_AUTH_H
-#define _IDENT_AUTH_H
+#ifndef IDENT_AUTH_H
+#define IDENT_AUTH_H 1
 
+/** Default delay for network reads. */
+#define IDENT_READ_TIMEOUT 60
+
+/** Buffer size sufficient to hold a complete request or response. */
 #define IDENT_BUFFER_SIZE 4096
 
+/** A 16-bit unsigned type. */
 #ifndef IDENT_INT16
-#define IDENT_INT16 unsigned short 
+# define IDENT_INT16 unsigned short
 #endif
-#define MUTUAL_AUTH_BIT 0x01 
-
-#ifdef TESTING 
-/* For testing , should be "ident" for real */ 
-#define IDENT_AUTH_KRB_SERVICE "rcmd" 
-#else 
-#define IDENT_AUTH_KRB_SERVICE "ident"
-#endif  
-#define IDENT_READ_TIMEOUT 60
 
-/* stolen from sendmail */ 
-#ifndef ARBPTR_T
-# define ARBPTR_T       void *
-#endif
+/** Bit to determine if mutual authentication is needed. */
+#define MUTUAL_AUTH_BIT 0x01
 
 
-/* 
- * 
- * Structs for ident authentication 
- * 
- */ 
+/** Internal structure storing data about a responder method.
+ *
+ * This struct has the same name but a different definition as a similar
+ * struct in sident.h.  In both cases, they're internal and really shouldn't
+ * be included in the public header file at all.  This part needs some work.
+ */
 struct ident_responder_auth {
-    char *auth_method;         /* Name of authentication mechanism */
-    int (*start)();            /* Start a responder->requester authentication */
-    int (*auth)();             /* Do an authentication protocol exchange */
-    void (*free_state)();      /* Free an authentication state */
+    char *auth_method;          /**< Name of authentication mechanism. */
+
+    /** Start a responder->requester authentication. */
+    char *(*start)(struct ident_auth_client_data *);
+
+    /** Do an authentication protocol exchange. */
+    int (*auth)(struct ident_auth_client_data *);
+
+    /** Free an authentication state structure. */
+    void (*free_state)(void *);
 };
 
+/** Internal structure containing responder information. */
 struct ident_auth_data {
-  FILE *fp ; /* input stream */ 
-  char *port_data ; /* points to port data part of auth_line */ 
-  char *cmd_data  ; /* points to "cmd" (i.e. AUTHENTICATE) part of line */ 
-  char *authenticate_data ; /* points to AUTHENTICATE part of line */ 
-  int uid; /* Uid of process */ 
-  int pid; /* Pid of process */ 
-  struct ident_responder_auth *auth_struct ; /* Pointer to auth_methods */ 
-  int local_port ; /* Local port of connection */ 
-  int remote_port ; /* Remote port of connection */ 
-  
-  struct in_addr *local_addr ; /* IP address local */  
-  struct in_addr *remote_addr ; /* IP address remote */ 
-  ARBPTR_T auth_method_data  ; /* Ptr to arbitrary struct needed for auth _method */ 
+    FILE *fp;                   /**< Input stream. */
+    char *port_data;            /**< Points to port data part of auth_line. */
+    char *cmd_data;             /**< Points to command part of line. */
+    char *authenticate_data;    /**< Points to AUTHENTICATE part of line. */
+    int uid;                    /**< UID of process. */
+    int pid;                    /**< PID of process. */
 
-};
+    /** Pointer to authentication methods. */
+    struct ident_responder_auth *auth_struct;
 
+    int local_port;             /**< Local port of connection. */
+    int remote_port;            /**< Remote port of connection. */
 
-#endif
+    /** Local IP address. */
+    struct in_addr *local_addr;
+
+    /** Remote IP address. */
+    struct in_addr *remote_addr;
+
+    /** Pointer to method-specific data used for authentication. */
+    void *auth_method_data;
+};
+
+#endif /* !IDENT_AUTH_H */
index 108e700ccf8ba099b2cf869ba881e83e8882f1a0..adce0e4b59cc0384619d53eb64bfce8ed84e863b 100644 (file)
  * $Id$
  */
 
-#include <ctype.h>
 #include <errno.h>
 #include <fcntl.h>
-#include <grp.h>
 #include <netdb.h>
-#include <pwd.h>
 #include <signal.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
-#include <sys/file.h>
-#include <sys/ioctl.h>
-#include <sys/param.h>
 #include <sys/socket.h>
-#include <sys/time.h>
 #include <sys/types.h>
-#include <sys/wait.h>
+#include <syslog.h>
 #include <unistd.h>
 
 /* BSDI needs <netinet/in.h> before <arpa/inet.h>. */
 # include <sys/select.h>
 #endif
 
-#include "error.h"
 #include "identd.h"
-#include "paths.h"
 
 int verbose_flag = 0;
 int debug_flag   = 0;
 int syslog_flag  = 0;
-int multi_flag   = 0;
 int unknown_flag = 0;
-int uidonly_flag = 0 ; 
-int users_can_nosident = ( 0 == 0 ) ;
-int allow_trivial = 0 ; 
-int mutual_auth_flag = 0 ; 
-int client_only_flag = 0 ; 
-
-int lport = 0;
-int fport = 0;
-
-static int syslog_facility = LOG_DAEMON;
-
-/*
-** The structure passing convention for GCC is incompatible with
-** Suns own C compiler, so we define our own inet_ntoa() function.
-** (This should only affect GCC version 1 I think, a well, this works
-** for version 2 also so why bother.. :-)
-*/
-#if defined(__GNUC__) && defined(__sparc__) && !defined(NeXT)
-
-#ifdef inet_ntoa
-#undef inet_ntoa
-#endif
-
-char *inet_ntoa(ad)
-    struct in_addr ad;
-{
-    unsigned long int s_ad;
-    int a, b, c, d;
-    static char addr[20];
-    
-    s_ad = ad.s_addr;
-    d = s_ad % 256;
-    s_ad /= 256;
-    c = s_ad % 256;
-    s_ad /= 256;
-    b = s_ad % 256;
-    a = s_ad / 256;
-    sprintf(addr, "%d.%d.%d.%d", a, b, c, d);
-    
-    return addr;
-}
-#endif
-
-static int comparemem(p1, p2, len)
-    unsigned char *p1;
-    unsigned char *p2;
-    int len;
-{
-    int c;
-
-    while (len-- > 0)
-       if ((c = (int) *p1++ - (int) *p2++) != 0)
-           return c;
-
-    return 0;
-}
-
-/*
-** Return the name of the connecting host, or the IP number as a string.
-*/
-char *gethost(addr)
-    struct in_addr *addr;
+int uidonly_flag = 0;
+int users_can_nosident = 1;
+int allow_trivial = 0;
+int mutual_auth_flag = 0;
+int client_only_flag = 0;
+
+/* Return the name of the connecting host, or the IP number as a string. */
+char *
+gethost(struct in_addr *addr)
 {
     int i;
     struct hostent *hp;
     char *hostname;
-  
-    hp = gethostbyaddr((char *) addr, sizeof(struct in_addr), AF_INET);
-    if (hp)
-    {
-       /* Found a IP -> Name match, now try the reverse for security reasons */
+
+    /* Make sure that forward and reverse DNS match to use a hostname. */
+    hp = gethostbyaddr((char *) addr, sizeof(*addr), AF_INET);
+    if (hp != NULL) {
         hostname = strdup(hp->h_name);
         if (hostname == NULL)
             return inet_ntoa(*addr);
-       hp = gethostbyname(hostname);
+        hp = gethostbyname(hostname);
         free(hostname);
-       if (hp)
-           for (i = 0; hp->h_addr_list[i]; i++)
-               if (comparemem(hp->h_addr_list[i],
-                              (unsigned char *) addr,
-                              sizeof(struct in_addr)) == 0)
-                   return hp->h_name;
-  }
-
-  return inet_ntoa(*addr);
-}
-
-
-char *clearmem(bp, len)
-    char *bp;
-    int len;
-{
-    char *cp;
-
-    cp = bp;
-    while (len-- > 0)
-       *cp++ = 0;
-    
-    return bp;
+        if (hp != NULL)
+            for (i = 0; hp->h_addr_list[i]; i++)
+                if (memcmp(hp->h_addr_list[i], addr, sizeof(*addr)) == 0)
+                    return hp->h_name;
+    }
+    return inet_ntoa(*addr);
 }
 
-
-/*
-** Main entry point into this daemon
-*/
-int main(argc,argv)
-    int argc;
-    char *argv[];
+/* Main entry point into this daemon. */
+int
+main(int argc, char *argv[])
 {
-    int i, len;
+    int len;
     struct sockaddr_in sin;
     struct in_addr laddr, faddr;
-
-    int opt_count = 0;         /* Count of option flags */
-  
-  
-    /*
-    ** Parse the command line arguments
-    */
-    for (i = 1; i < argc && argv[i][0] == '-'; i++) {
-       opt_count++;
-       switch (argv[i][1])
-       {
-         case 'l':    /* Use the Syslog daemon for logging */
-           syslog_flag++;
-           break;
-             
-         case 'n':
+    int option;
+
+    /* Parse options. */
+    opterr = 0;
+    while ((option = getopt(argc, argv, "CdeMNnlTVv")) != EOF) {
+        switch (option) {
+        case 'C':
+            client_only_flag++;
+            break;
+        case 'd':
+            debug_flag++;
+            break;
+        case 'e':
+            unknown_flag = 1;
+            break;
+        case 'l':
+            syslog_flag++;
+            break;
+        case 'M':
+            mutual_auth_flag++;
+            break;
+        case 'N':
+            users_can_nosident = 0;
+            break;
+        case 'n':
             uidonly_flag = 1;
             break;
-
-         case 'e':
-           unknown_flag = 1;
-           break;
-           
-         case 'V':    /* Give version of this daemon */
-           printf("[%s]\r\n", PACKAGE_STRING);
-           exit(0);
-           break;
-           
-         case 'v':    /* Be verbose */
-           verbose_flag++;
-           break;
-           
-         case 'd':    /* Enable debugging */
-           debug_flag++;
-           break;
-       
-         case 'N':    /* Disable users ".nosident" files */
-           users_can_nosident = ( 0 == 1 ) ;
-           break;
-         case 'M':      /* Turn off mutual auth */ 
-           mutual_auth_flag++ ; 
-           break ; 
-
-         case 'T':       /* Allow trivial auth */ 
-           allow_trivial++ ; 
-           break;
-         case 'C':         /* Turn on client only port checking */ 
-           client_only_flag++ ; 
-           break; 
-         default:
-           ERROR1("Bad option %s", argv[i]);
-           break;
-       }
+        case 'T':
+            allow_trivial++ ;
+            break;
+        case 'v':
+            verbose_flag++;
+            break;
+        case 'V':
+            printf("%s\n", PACKAGE_STRING);
+            exit(0);
+            break;
+        default:
+            fprintf(stderr, "sidentd: bad option -%c\n", optopt);
+            exit(1);
+            break;
+        }
+    }
+    argc -= optind;
+    if (argc > 0) {
+        fprintf(stderr, "sidentd: too many arguments\n");
+        exit(1);
     }
 
-    if (i < argc)
-       ERROR1("Too many arguments: ignored from %s", argv[i]);
-
-
-    /*
-    ** We used to call k_open here. But then the file descriptor
-    ** kd->fd open on /dev/kmem is shared by all child processes.
-    ** From the fork(2) man page:
-    **
-    ** o The child process has its own copy of the parent's descriptors.
-    **   These descriptors reference the same underlying objects.  For
-    **   instance, file pointers in file objects are shared between the
-    **   child and the parent so that an lseek(2) on a descriptor in the
-    **   child process can affect a subsequent read(2) or write(2) by
-    **   the parent.
-    **
-    ** Thus with concurrent (simultaneous) identd client processes,
-    ** they step on each other's toes when they use kvm_read.
-    ** 
-    ** Calling k_open here was a mistake for another reason too: we
-    ** did not yet honor -u and -g options. Presumably we are
-    ** running as root (unless the in.identd file is setuid), and
-    ** then we can open kmem regardless of -u and -g values.
-    ** 
-    ** 
-    ** Open the kernel memory device and read the nlist table
-    ** 
-    **     if (k_open() < 0)
-    **                 ERROR("main: k_open");
-    */
-
-    /*
-    ** Get foreign internet address
-    */
+    /* Get the remote Internet address.  If this fails, a user has tried to
+       start us from the command line or the network link died; either way,
+       the message won't reach the other end. */
     len = sizeof(sin);
-    if (getpeername(0, (struct sockaddr *) &sin, &len) == -1)
-    {
-       /*
-       ** A user has tried to start us from the command line or
-       ** the network link died, in which case this message won't
-       ** reach to other end anyway, so lets give the poor user some
-       ** errors.
-       */
-       perror("in.sidentd: getpeername()");
-       exit(1);
+    if (getpeername(0, (struct sockaddr *) &sin, &len) < 0) {
+        fprintf(stderr, "sidentd: getpeername failed: %s", strerror(errno));
+        exit(1);
     }
-    
     faddr = sin.sin_addr;
-    
-    
-    /*
-    ** Open the connection to the Syslog daemon if requested
-    */
+
+    /* If we're logging, open the connection to the syslog daemon. */
     if (syslog_flag)
-    {
-       openlog("sidentd", LOG_PID, syslog_facility);
-    }
-  
+        openlog("sidentd", LOG_PID, LOG_DAEMON);
 
-    /*
-    ** Get local internet address
-    */
+    /* Get the local Internet address.  If this fails, exit, since we have to
+       have it to check requests. */
     len = sizeof(sin);
-    if (getsockname(0, (struct sockaddr *) &sin, &len) == -1)
-    {
-       /*
-       ** We can just die here, because if this fails then the
-       ** network has died and we haven't got anyone to return
-       ** errors to.
-       */
-       exit(1);
+    if (getsockname(0, (struct sockaddr *) &sin, &len) == -1) {
+        fprintf(stderr, "sidentd: getsockname failed: %s", strerror(errno));
+        exit(1);
     }
     laddr = sin.sin_addr;
-    
 
-    /*
-    ** Get the local/foreign port pair from the luser
-    */
+    /* Parse the ident request. */
     parse(stdin, &laddr, &faddr);
-
-    /* Note : we should never return from parse */ 
     exit(0);
 }
index fed6b42d71cfa1ae07d390b8cf3161342cfcb5a5..1393a48dfcd5cd8cb0258f7eedd7f98be6fe5eb5 100644 (file)
  */
 
 #ifndef IDENTD_H
-#define IDENTD_H
+#define IDENTD_H 1
 
-extern char version[];
+#include <stdio.h> /* FILE */
+
+#include "config.h" 
+#include "sident.h" 
 
 extern int verbose_flag;
 extern int debug_flag;
 extern int syslog_flag;
-extern int multi_flag;
 extern int unknown_flag;
 extern int uidonly_flag; 
 extern int users_can_nosident;
-extern int crypto_flag;
 extern int allow_trivial; 
 extern int mutual_auth_flag; 
 extern int client_only_flag; 
 
-extern int lport;
-extern int fport;
-
-extern char *gethost();
-
-extern int k_open();
-extern int k_getuid();
-extern int parse();
-extern int parse_config();
-
-#include "sident.h" 
-
-#define MAX_PORT  65535
-#define VALID_PORT( _port_ ) ((_port_) > 1 && (_port_) < MAX_PORT )
-
-/* You may want to change this for whatever makes sense at your site. */ 
-
-#define SERVER_PORT( _port_) ((_port_) < 1024 && (_port_) != 6000 )
-
-#include "config.h" 
-
-/* lstat defines */ 
+extern char *gethost(struct in_addr *);
+extern int parse(FILE *, struct in_addr *laddr, struct in_addr *faddr);
 
-#ifndef S_IRUSR
-#define S_IRUSR  0000400 
-#endif
-#ifndef S_IRGRP
-#define S_IRGRP  0000040 
-#endif
-#ifndef S_IWGRP
-#define S_IWGRP  0000020 
-#endif
-#ifndef S_IROTH
-#define S_IROTH  0000004 
-#endif
-#ifndef S_IWOTH
-#define S_IWOTH  0000002 
-#endif
+/* Port checking.  You may want to adjust SERVER_PORT for whatever makes sense
+   at your site, in order to exclude other known server ports.  Note that
+   these macros evaluate the port number multiple times. */
+#define MAX_PORT        65535
+#define VALID_PORT(p)   ((p) > 1 && (p) < MAX_PORT)
+#define SERVER_PORT(p)  ((p) < 1024 || (p) == 6000)
 
 #endif /* !IDENTD_H */
index b362ad930f39dbd2b9ed7d901ab8a953451c3d6d..5110763312b5801ef0f3b972404e1dc4c0d0eb35 100644 (file)
  * It takes on stdin the output from "netstat -f inet -n | grep ESTAB" in
  * either Solaris 2.x (non-standard formats can easily be converted to this)
  *
- *     laddr.lport faddr.fport .....
+ *     laddr.lport faddr.fport .....
  *
  * or BSD 4.x (the defacto standard netstat output):
  *
- *     tcp <num> <num>  laddr.lport faddr.fport
+ *     tcp <num> <num>  laddr.lport faddr.fport
  *
- * format.
+ * format.  Optionally, the delimiter between the address and the port may be
+ * a colon instead.
  *
  * The output must be numeric, as non-numeric output is truncated when
  * hostnames get too long and ambiguous.  And we don't want netstat to first
  * convert numbers to names and then this program to convert names back to
  * numbers.
  *
- * @author Casper Dik (casper@fwi.uva.nl)
+ * @author Casper Dik <casper@fwi.uva.nl>
  *
  * $Id$
  */
 
-#include <ctype.h>
+#include <pwd.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include <sys/socket.h>
-#include <sys/time.h>
 #include <sys/types.h>
-#include <pwd.h>
+#include <syslog.h>
 
 /* BSDI needs <netinet/in.h> before <arpa/inet.h>. */
 #include <netinet/in.h>
 #include <arpa/inet.h>
 
 #include "identd.h"
-#include "error.h"
 #include "pidentd.h"
-#include "sident.h"
-
-static int syslog_facility = LOG_DAEMON;
-
-/*
- * To resolve external references that are usually resolved
- * from identd.c
- */
-char *path_unix = NULL;
-char *path_kmem = NULL;
-int lport = 0;
-int fport = 0;
 
+/* External references that are usually resolved from identd.c. */
 int debug_flag = 1;
 int syslog_flag = 1;
 
 int
-main()
+main(void)
 {
     char buf[500];
+    void *ka_ptr;
+    struct kernel *kinfo_ptr;
 
-    void *ka_ptr ; 
-    struct  kernel *kinfo_ptr ; 
-
-
-    /*
-    ** Open the connection to the Syslog daemon if requested
-    */
-    if (syslog_flag)
-    {
-       openlog("identd_test", LOG_PID, syslog_facility);
-    }
-
+    /* Some things just always syslog, so try to at least put a reasonable
+       program name on them.  This needs to be fixed. */
+    openlog("itest", LOG_PID, LOG_DAEMON);
 
+    /* Open the kernel. */
     if (ka_open(&ka_ptr) != 0) {
-       fprintf(stderr,"ka_open failed\n");
-       exit(1);
+        fprintf(stderr, "ka_open failed\n");
+        exit(1);
     }
-    while (fgets(buf,sizeof(buf),stdin)) {
-       char *loc, *rem, *tmp;
-       unsigned short lport, fport;
-       struct in_addr faddr, laddr;
-       int uid;
-       int pid;
-       char *cmd, *cmd_and_args;
-
-       struct passwd *pwd;
-       char buf2[sizeof(buf)];
-
-       strcpy(buf2,buf);
-
-       loc = strtok(buf, " \t");
-       if (strcmp(loc,"tcp") == 0) {
-           int i;
-           for (i = 0; i < 3; i++)
-               loc = strtok(NULL, " \t");
-       }
-       rem = strtok(NULL, " \t");
-       if (loc == NULL || rem == NULL) {
-           fprintf(stderr,"Malformed line: %s\n", buf2);
-           continue;
-       }
-       /* parse remote, local address */
-       tmp = strrchr(loc,'.');
-       if (tmp == NULL) {
-           fprintf(stderr,"Malformed line: %s\n", buf2);
-           continue;
-       }
-       *tmp++ ='\0';
-       laddr.s_addr = inet_addr(loc);
-       lport = atoi(tmp);
-
-       tmp = strrchr(rem,'.');
-       if (tmp == NULL) {
-           fprintf(stderr,"Malformed line: %s\n", buf2);
-           continue;
-       }
-       *tmp++ ='\0';
-       fport = atoi(tmp);
-       faddr.s_addr = inet_addr(rem);
-
-       uid = -1;
-
-       pid = 0;
-       cmd = "unknown";
-       cmd_and_args = "unknown";
-
-       /* convert this to ka_lookup */ 
 
-
-/*     if (k_getuid(&faddr, htons(fport), &laddr, htons(lport), &uid */
-
-/*             , &pid */
-/*             , &cmd */
-/*             , &cmd_and_args */
-
-/*             ) != 0) { */
-/*         fprintf(stderr,"*unknown*\t%s\t%d\t\t%s\t%d\n", loc, lport, rem, fport); */
-/*         continue; */
-/*     } */
-
-       
-  /* Fill up kernel info struct */ 
-
-    /*  struct kernel */
-    /*  { */
-    /*       Request parameters  */
-    /*      struct sockaddr_in local; */
-    /*      struct sockaddr_in remote; */
-    
-    /*      Result parameters */
-    /*      avail_t av; */
-    
-    /*      int status; */
-    /*      uid_t euid; */
-    /*      uid_t ruid; */
-    
-    /*      pid_t pid; */
-    /*      char *cmd; */
-    /*      char *argv; */
-    /*  }; */
-
-    kinfo_ptr = kernel_alloc() ; 
-
-
-    kinfo_ptr->local.sin_port = htons(lport) ; 
-    kinfo_ptr->remote.sin_port  = htons(fport) ;
-    memcpy(&(kinfo_ptr->local.sin_addr),&laddr,sizeof(struct in_addr)); 
-    memcpy(&(kinfo_ptr->remote.sin_addr),&faddr,sizeof(struct in_addr)); 
-    kinfo_ptr->local.sin_family = AF_INET ; 
-    kinfo_ptr->remote.sin_family = AF_INET ; 
-    /* k_getuid returns 0 on success, any non-zero on failure. */
-
-    
-    if  ( ka_lookup(ka_ptr,kinfo_ptr) <  0){ 
-      fprintf(stderr,"ka_lookup failed\n");
-      exit(1);
+    /* For each input string, parse it and then look it up in the kernel. */
+    while (fgets(buf, sizeof(buf), stdin) != NULL) {
+        char *loc, *rem, *tmp;
+        unsigned short lport, fport;
+        struct in_addr faddr, laddr;
+        int i;
+        struct passwd *pwd;
+        char buf2[sizeof(buf)];
+        uid_t uid;
+
+        strcpy(buf2, buf);
+
+        loc = strtok(buf, " \t");
+        if (strcmp(loc, "tcp") == 0)
+            for (i = 0; i < 3; i++)
+                loc = strtok(NULL, " \t");
+        rem = strtok(NULL, " \t");
+        if (loc == NULL || rem == NULL) {
+            fprintf(stderr,"Malformed line: %s\n", buf2);
+            continue;
+        }
+
+        /* Parse remote, local address. */
+        tmp = strrchr(loc, ':');
+        if (tmp == NULL)
+            tmp = strrchr(loc, '.');
+        if (tmp == NULL) {
+            fprintf(stderr,"Malformed line: %s\n", buf2);
+            continue;
+        }
+        *tmp++ = '\0';
+        laddr.s_addr = inet_addr(loc);
+        lport = atoi(tmp);
+        tmp = strrchr(rem, ':');
+        if (tmp == NULL)
+            tmp = strrchr(loc, '.');
+        if (tmp == NULL) {
+            fprintf(stderr,"Malformed line: %s\n", buf2);
+            continue;
+        }
+        *tmp++ = '\0';
+        fport = atoi(tmp);
+        faddr.s_addr = inet_addr(rem);
+
+        /* Flesh out the kernel lookup request. */
+        kinfo_ptr = kernel_alloc();
+        kinfo_ptr->local.sin_port = htons(lport);
+        kinfo_ptr->remote.sin_port = htons(fport);
+        memcpy(&kinfo_ptr->local.sin_addr, &laddr, sizeof(struct in_addr));
+        memcpy(&kinfo_ptr->remote.sin_addr, &faddr, sizeof(struct in_addr));
+        kinfo_ptr->local.sin_family = AF_INET;
+        kinfo_ptr->remote.sin_family = AF_INET;
+
+        /* Do the kernel lookup. */
+        if (ka_lookup(ka_ptr, kinfo_ptr) < 0) {
+            fprintf(stderr, "ka_lookup failed\n");
+            exit(1);
+        }
+        if (kinfo_ptr->status == 0) {
+            fprintf(stderr, "Connection not found\n");
+            continue;
+        }
+
+        /* Print out the results. */
+        uid = (kinfo_ptr->ruid == NO_UID) ? kinfo_ptr->euid : kinfo_ptr->ruid;
+        pwd = getpwuid(uid);
+        if (pwd != NULL)
+            printf("%-8.8s", pwd->pw_name);
+        else
+            printf("%-8.8d", kinfo_ptr->ruid);
+        printf(" \t%-13s\t%-4d\t%-13s\t%-4d\tPID=%d\tCMD=%s\tCMD+ARG=%s\n",
+               loc, lport, rem, fport, kinfo_ptr->pid, kinfo_ptr->cmd,
+               kinfo_ptr->argv);
     }
-       
-
-
-    pwd = getpwuid(kinfo_ptr->ruid);
-    if (pwd)
-      printf("%-8.8s", pwd->pw_name);
-    else
-      printf("%-8.8d", kinfo_ptr->ruid);
-
-    printf (" \t%-13s\t%-4d\t%-13s\t%-4d\tPID=%d\tCMD=%s\tCMD+ARG=%s\n", loc, lport, rem, fport, kinfo_ptr->pid, kinfo_ptr->cmd, kinfo_ptr->argv);
-
-    }
-
     return 0;
 }
diff --git a/responder/kernel/kvm.h b/responder/kernel/kvm.h
deleted file mode 100644 (file)
index 0c75b6f..0000000
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
-** kvm.h                    Header file for the kernel virtual memory access
-**                          routines
-**
-** This code is in the public domain and may be used freely by anyone
-** who wants to.
-**
-** Last update: 19 Oct 1992
-**
-** Author: Peter Eriksson <pen@lysator.liu.se>
-*/
-
-#ifndef __KVM_H__
-#define __KVM_H__
-
-typedef struct
-{
-  int fd;
-  char *namelist;
-#ifdef BSD43
-  int swap_fd;
-  int mem_fd;
-
-  int procidx;
-  int nproc;
-  struct pte *Usrptma;
-  struct pte *usrpt;
-  struct proc *proctab;
-#endif
-} kvm_t;
-
-
-extern kvm_t *kvm_open();
-extern int kvm_close();
-extern int kvm_nlist();
-extern int kvm_read();
-
-#ifdef BSD43
-extern struct user *kvm_getu();
-extern struct proc *kvm_getproc();
-extern struct proc *kvm_nextproc();
-extern int kvm_setproc();
-#endif
-
-#endif
index 65c4f037e43a537939b02531293898be1137aab3..e0886bf42e867f4e9279e4927759ec0604b48c7f 100644 (file)
@@ -4,12 +4,24 @@
  * This file provides the glue routines needed to use pidentd 3.0.* k_files
  * with the S/Ident responder code.
  *
+ * Most of the s_* functions are covered by the following license:
+ *
+ * Copyright (c) 1997-1999 Peter Eriksson <pen@lysator.liu.se>
+ *
+ * This program is free software; you can redistribute it and/or modify it as
+ * you wish - as long as you don't claim that you wrote it.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.
+ *
  * @author Booker C. Bense <bbense@stanford.edu>
+ * @author Peter Eriksson <pen@lysator.liu.se>
  *
  * $Id$
  */
 
-#include "config.h" 
+#include "config.h"
 
 #include <errno.h>
 #include <fcntl.h>
 #include <syslog.h>
 #include <unistd.h>
 
-#ifndef KERNEL_HELPER
-# define KERNEL_HELPER
-#endif 
-
-#include "pidentd.h"  
-
-
-/* osinfo_get is never actually used, since we don't use the
-** ka_init function in the k_files.  Its just to make the 
-** compiler happy. 
-*/ 
-
-char *osinfo_build = "the current os" ; 
-
-char * 
-osinfo_get( char *os_current) { 
-  
-  return NULL ; 
+#include "identd.h"
+#include "pidentd.h"
 
-} 
+/* Dummy variables that aren't used but that various kernel modules expect. */
+const char *osinfo_build = "the current os";
+int kernel_threads = 0;
+int kernel_buffers = 0;
+int kernel_attempts = 0;
 
+/* osinfo_get is never actually used, since we don't use the ka_init function
+   in the k_files.  Its just to make the compiler happy.  */
+char *osinfo_get(char *os_current) { return NULL; }
 
+/* Allocate the kernel struct that's used as an interface. */
 struct kernel *
 kernel_alloc(void)
 {
     struct kernel *kp;
-    
-    kp = (struct kernel *) s_malloc(sizeof(struct kernel));
-    
-    
+    kp = s_malloc(sizeof(struct kernel));
     kp->status = -1;
     kp->euid = NO_UID;
     kp->ruid = NO_UID;
-
     kp->pid = NO_PID;
     kp->cmd = NULL;
     kp->argv = NULL;
-    
     return kp;
 }
 
-
+/* Free the kernel struct. */
 void
 kernel_free(struct kernel *kp)
 {
     s_free(kp->cmd);
     s_free(kp->argv);
-    
-    s_free( kp);
+    s_free(kp);
 }
 
 
+/* The following functions are all copies or substitutes for the s_* functions
+   provided in pidentd, since they are used by the kernel modules. */
 
+/* abort replacement. */
+void s_abort(void) { abort(); }
 
-/*
-** safeio.c - Signal/Async safe wrapper functions
-**
-** Copyright (c) 1997-1999 Peter Eriksson <pen@lysator.liu.se>
-**
-** This program is free software; you can redistribute it and/or
-** modify it as you wish - as long as you don't claim that you wrote
-** it.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-*/
-
-extern int debug_flag ; 
-
-void
-s_abort(void)
-{
-
-    abort();
-}
-
-/*
-** A "safe" malloc, that always succeeds (or logs an
-** error to syslog and the abort()'s.
-**
-** The buffer returned is zeroed out.
-*/
+/* Safe malloc replacement that always succeeds (if it doesn't, it logs an
+   error message to syslog and then aborts.  The buffer is zeroed out before
+   it's returned, similar to calloc. */
 void *
 s_malloc(size_t size)
 {
     void *p;
 
-    p = (void *) malloc(size);
-    if (p == NULL)
-    {
-       if (debug_flag)
-           fprintf(stderr, "s_malloc(%lu) failed - aborting\n",
-                   (unsigned long) size);
-       
-       syslog(LOG_ERR, "malloc(%lu): %m", (unsigned long) size);
-       s_abort();
+    p = malloc(size);
+    if (p == NULL) {
+        if (debug_flag)
+            fprintf(stderr, "s_malloc(%lu) failed - aborting\n",
+                    (unsigned long) size);
+        syslog(LOG_ERR, "malloc(%lu): %m", (unsigned long) size);
+        s_abort();
     }
-
     memset(p, 0, size);
     return p;
 }
 
-
+/* Safe free replacement that doesn't call the system free if the pointer is
+   NULL (some system free implementations can't handle that). */
 void
 s_free(void *p)
 {
     if (p != NULL)
-       free(p);
+        free(p);
 }
 
-
+/* Safe strdup replacement. */
 char *
 s_strdup(const char *s)
 {
     char *ns;
     size_t len;
-    
-    
+
     if (s == NULL)
-       return NULL;
-
-    len = strlen(s)+1;
-    ns = (char *) malloc(len);
-    if (ns == NULL)
-    {
-       syslog(LOG_ERR, "strdup(): malloc(%lu): %m", (unsigned long) len);
-       s_abort();
+        return NULL;
+    len = strlen(s) + 1;
+    ns = malloc(len);
+    if (ns == NULL) {
+        syslog(LOG_ERR, "strdup(): malloc(%lu): %m", (unsigned long) len);
+        s_abort();
     }
-
     memcpy(ns, s, len);
     return ns;
 }
 
+#ifndef ENOSR
+# define ENOSR ENFILE
+#endif
+
+/* Safe s_open replacement that repeats the call to open on EINTR and logs a
+   warning on errors that indicate too many open files. */
 int
-s_open(const char *path,
-       int oflag,
-       ...)
+s_open(const char *path, int oflag, ...)
 {
     int s;
     mode_t mode = 0;
 
-    if (oflag & O_CREAT)
-    {
-       va_list ap;
+    if (oflag & O_CREAT) {
+        va_list ap;
 
-       va_start(ap, oflag);
-       /* FIXME: need to use widened form of mode_t here.  */
-       mode = va_arg(ap, int);
-       va_end(ap);
+        va_start(ap, oflag);
+        /* FIXME: need to use widened form of mode_t here. */
+        mode = va_arg(ap, int);
+        va_end(ap);
     }
 
-    while ((s = open(path, oflag, mode)) < 0 && errno == EINTR)
-       ;
-    
-    if (s < 0 && (errno == EMFILE
-                 || errno == ENFILE
-                 || errno == ENOMEM 
-#ifdef ENOSR
-                 || errno == ENOSR
-#endif
-                 ))
-    {
-       /* Too many open files */
-       
-       syslog(LOG_WARNING, "s_open(\"%s\", 0%o): %m", path, oflag);
-    }
-    
+    do {
+        s = open(path, oflag, mode);
+    } while (s < 0 && errno == EINTR);
+
+    /* Check for too many open files. */
+    if (s < 0 && (errno == EMFILE || errno == ENFILE || errno == ENOMEM
+                  || errno == ENOSR))
+        syslog(LOG_WARNING, "s_open(\"%s\", 0%o): %m", path, oflag);
     return s;
 }
 
-
-
-
+/* snprintf replacement that uses vsprintf if vsnprintf isn't available and
+   tries to detect a buffer overrun.  This can be replaced with a call to
+   vsnprintf once we have an snprintf replacement. */
 int
-s_snprintf(char *buf,
-          size_t bufsize,
-          const char *format,
-          ...)
+s_snprintf(char *buf, size_t bufsize, const char *format, ...)
 {
     va_list ap;
     int retcode;
 
+    if (bufsize < 1) {
+        syslog(LOG_ERR, "s_snprintf(..., %lu, ...): illegal bufsize",
+               (unsigned long) bufsize);
+        s_abort();
+    }
 
     va_start(ap, format);
-
-    if (bufsize < 1)
-    {
-        syslog(LOG_ERR, "s_snprintf(..., %d, ...): illegal bufsize",
-              bufsize);
-       s_abort();
-    }
-    
-    buf[bufsize-1] = '\0';
+    buf[bufsize - 1] = '\0';
 #ifdef HAVE_VSNPRINTF
     retcode = vsnprintf(buf, bufsize, format, ap);
 #else
     retcode = vsprintf(buf, format, ap);
 #endif
-       
-    if (retcode > 0 && (buf[bufsize-1] != '\0' ||
-                       retcode > bufsize-1))
-    {
-      syslog(LOG_ERR, "s_snprintf(..., %d, ...) = %d: buffer overrun\n",
-              bufsize, retcode);
-       
-       s_abort();
+    if (retcode > 0 && (buf[bufsize - 1] != '\0' || retcode > bufsize - 1)) {
+        syslog(LOG_ERR, "s_snprintf(..., %lu, ...) = %d: buffer overrun\n",
+               (unsigned long) bufsize, retcode);
+        s_abort();
     }
-
     va_end(ap);
-
     return retcode;
 }
diff --git a/responder/kvm.c b/responder/kvm.c
deleted file mode 100644 (file)
index b9f456f..0000000
+++ /dev/null
@@ -1,373 +0,0 @@
-/** @file
- * A set of functions for emulating kvm on operating systems without them.
- *
- * This code is in the public domain and may be used freely by anyone
- * who wants to.
- *
- * @date 1992-12-12
- * @author Peter Eriksson <pen@lysator.liu.se>
- *
- * $Id$
- */
-
-#include "config.h" 
-
-#ifndef NO_KVM
-#ifndef HAVE_LIBKVM
-
-#include <errno.h>
-#include <nlist.h>
-#include <stdio.h>
-#include <stdlib.h>
-
-#ifdef IRIX
-# include <sys/sbd.h>
-# ifdef IRIX6
-#  define K0_TO_PHYS(x)   (x) 
-#  define nlist nlist64
-# endif
-#endif
-
-#ifdef BSD43
-# include <sys/types.h>
-# include <sys/dir.h>
-# include <sys/param.h>
-# include <sys/vmmac.h>
-# include <sys/user.h>
-# ifdef DIRBLKSIZ
-#  undef DIRBLKSIZ
-# endif
-# include <sys/proc.h>
-# include <machine/pte.h>
-# include "paths.h"
-#endif
-#include "kernel/kvm.h"
-#include "paths.h"
-
-kvm_t *kvm_open(namelist, corefile, swapfile, flag, errstr)
-  char *namelist;
-  char *corefile;
-  char *swapfile;
-  int flag;
-  char *errstr;
-{
-  kvm_t *kd;
-
-  if (!namelist)
-    namelist = _PATH_UNIX;
-  if (!corefile)
-    corefile = _PATH_KMEM;
-  
-#ifdef BSD43
-  if (!swapfile)
-    swapfile = _PATH_SWAP;
-#endif
-  
-  kd = (kvm_t *) malloc(sizeof(kvm_t));
-  if (!kd)
-  {
-    if (errstr)
-      perror(errstr);
-    return NULL;
-  }
-
-  kd->namelist = (char *) malloc(strlen(namelist)+1);
-  if (!kd->namelist)
-  {
-    if (errstr)
-      perror(errstr);
-    return NULL;
-  }
-  
-  if ((kd->fd = open(corefile, flag)) < 0)
-  {
-    if (errstr)
-      perror(errstr);
-    free(kd->namelist);
-    free(kd);
-    return NULL;
-  }
-
-#ifdef BSD43
-  if ((kd->swap_fd = open(swapfile, flag)) < 0)
-  {
-    if (errstr)
-      perror(errstr);
-    close(kd->fd);
-    free(kd->namelist);
-    free(kd);
-    return NULL;
-  }
-
-  if ((kd->mem_fd = open(_PATH_MEM, flag)) < 0)
-  {
-    if (errstr)
-      perror(errstr);
-    close(kd->swap_fd);
-    close(kd->fd);
-    free(kd->namelist);
-    free(kd);
-    return NULL;
-  }
-#endif
-  
-  strcpy(kd->namelist, namelist);
-  return kd;
-}
-
-
-int kvm_close(kd)
-  kvm_t *kd;
-{
-  int code;
-  
-  code = close(kd->fd);
-#ifdef BSD43
-  close(kd->swap_fd);
-  close(kd->mem_fd);
-  if (kd->proctab)
-    free(kd->proctab);
-#endif
-  free(kd->namelist);
-  free(kd);
-
-  return code;
-}
-
-
-/*
-** Extract offsets to the symbols in the 'nl' list. Returns 0 if all found,
-** or else the number of variables that was not found.
-*/
-int kvm_nlist(kd, nl)
-  kvm_t *kd;
-  struct nlist *nl;
-{
-  int code;
-  int i;
-
-#ifdef IRIX6
-  code = nlist64(kd->namelist, nl);
-#else
-  code = nlist(kd->namelist, nl);
-#endif
-  if (code != 0)
-    return code;
-  
-  /*
-  ** Verify that we got all the needed variables. Needed because some
-  ** implementations of nlist() returns 0 although it didn't find all
-  ** variables.
-  */
-  if (code == 0)
-  {
-#if defined(__convex__) || defined(NeXT)
-    for (i = 0; nl[i].n_un.n_name && nl[i].n_un.n_name[0]; i++)
-#else  
-    for (i = 0; nl[i].n_name && nl[i].n_name[0]; i++)
-#endif
-#if defined(_AUX_SOURCE) || defined(_CRAY) || defined(sco) || defined(_SEQUENT_)
-      /* A/UX sets n_type to 0 if not compiled with -g. n_value will still
-      ** contain the (correct?) value (unless symbol unknown).
-      */
-      if( nl[i].n_value == 0)
-       code++;
-#else
-      if (nl[i].n_type == 0)
-       code++;
-#endif
-  }
-  
-  return code;
-}
-
-
-/*
-** Get a piece of the kernel memory
-*/
-static int readbuf(fd, addr, buf, len)
-  int fd;
-  long addr;
-  char *buf;
-  int len;
-{
-#ifdef IRIX
-  addr = K0_TO_PHYS(addr);
-#endif
-  errno = 0;
-#if defined(__alpha)
-  /*
-   * Let us be paranoid about return values.
-   * It should be like this on all implementations,
-   * but some may have broken lseek or read returns.
-   */
-  if (lseek(fd, addr, 0) != addr || errno != 0) return -1;
-  if (read(fd, buf, len) != len  || errno != 0) return -1;
-  return len;
-#else
-  if (lseek(fd, addr, 0) == -1 && errno != 0) return -1;
-  return read(fd, buf, len);
-#endif
-}
-
-int kvm_read(kd, addr, buf, len)
-  kvm_t *kd;
-  long addr;
-  char *buf;
-  int len;
-{
-  return readbuf(kd->fd, addr, buf, len);
-}
-
-
-#ifdef BSD43
-
-struct user *kvm_getu(kd, procp)
-  kvm_t *kd;
-  struct proc *procp;
-{
-  static union
-  {
-    struct user user;
-    char upages[UPAGES][NBPG];
-  } userb;
-
-  int ncl;
-  struct pte *pteaddr, apte;
-  struct pte arguutl[UPAGES+CLSIZE];
-  
-  
-  if ((procp->p_flag & SLOAD) == 0)
-  {
-    if(readbuf(kd->swap_fd,
-              dtob(procp->p_swaddr),
-              &userb.user, sizeof(struct user)) < 0)
-      return NULL;
-  }
-  else
-  {
-    /*
-    ** Sigh. I just *love* hard coded variable names in macros...
-    */
-    {
-      struct pte *usrpt = kd->usrpt;
-      
-      pteaddr = &kd->Usrptma[btokmx(procp->p_p0br) + procp->p_szpt - 1];
-      if (readbuf(kd->fd, pteaddr, &apte, sizeof(apte)) < 0)
-       return NULL;
-    }
-    
-    if (readbuf(kd->mem_fd,
-               ctob(apte.pg_pfnum+1)-(UPAGES+CLSIZE)*sizeof(struct pte),
-               arguutl, sizeof(arguutl)) < 0)
-      return NULL;
-
-    ncl = (sizeof(struct user) + NBPG*CLSIZE - 1) / (NBPG*CLSIZE);
-    while (--ncl >= 0)
-    {
-      int i;
-
-      
-      i = ncl * CLSIZE;
-      if(readbuf(kd->mem_fd,
-                ctob(arguutl[CLSIZE+i].pg_pfnum),
-                userb.upages[i], CLSIZE*NBPG) < 0)
-       return NULL;
-    }
-  }
-
-  return &userb.user;
-}
-
-
-
-struct proc *kvm_nextproc(kd)
-  kvm_t *kd;
-{
-  if (kd->proctab == NULL)
-    if (kvm_setproc(kd) < 0)
-      return NULL;
-
-  if (kd->procidx < kd->nproc)
-    return &kd->proctab[kd->procidx++];
-
-  return (struct proc *) NULL;
-}
-
-int kvm_setproc(kd)
-  kvm_t *kd;
-{
-  long procaddr;
-  
-  static struct nlist nl[] =
-  {
-#define N_PROC 0
-#define N_USRPTMA 1
-#define N_NPROC 2
-#define N_USRPT 3
-    { "_proc" },
-    { "_Usrptmap" },
-    { "_nproc" },
-    { "_usrpt" },
-    { "" }
-  };
-
-  if (kvm_nlist(kd, nl) != 0)
-    return -1;
-  
-  kd->Usrptma = (struct pte *) nl[N_USRPTMA].n_value;
-  kd->usrpt   = (struct pte *) nl[N_USRPT].n_value;
-  
-  if (readbuf(kd->fd, nl[N_NPROC].n_value, &kd->nproc, sizeof(kd->nproc)) < 0)
-    return -1;
-
-  if (readbuf(kd->fd, nl[N_PROC].n_value, &procaddr, sizeof(procaddr)) < 0)
-    return -1;
-  
-  if (kd->proctab)
-    free(kd->proctab);
-
-  kd->proctab = (struct proc *) calloc(kd->nproc, sizeof(struct proc));
-  if (!kd->proctab)
-    return -1;
-
-  if (readbuf(kd->fd,
-             procaddr,
-             kd->proctab,
-             kd->nproc*sizeof(struct proc)) < 0)
-    return -1;
-
-  kd->procidx = 0;
-
-  return 0;
-}
-
-
-struct proc *kvm_getproc(kd, pid)
-  kvm_t *kd;
-  int pid;
-{
-  struct proc *procp;
-
-
-  if (kvm_setproc(kd) < 0)
-    return NULL;
-
-  while ((procp = kvm_nextproc(kd)) && procp->p_pid != pid)
-    ;
-  
-  return procp;
-}
-
-#endif
-
-#else
-/* Just to make some compilers shut up! */
-int kvm_dummy()
-{
-    return 1;
-}
-#endif /* HAVE_LIBKVM */ 
-#endif /* NO_KVM */ 
index 1e4729316873fb0d14ac52537fad52592983b20c..c483d087e1b685d721a6145c5aa3e559f998ca63 100644 (file)
  */
 
 #include <time.h>
-#include <krb.h>
+
+#ifdef HAVE_KERBEROSIV_KRB_H
+# include <kerberosIV/krb.h>
+#else
+# include <krb.h>
+#endif
 
 /** The lifetime value indicating a ticket that never expires. */
 #define TKTLIFENOEXPIRE 0xFF
index 8177956c453915c688b7f4c41fcb09f6eed8383f..8d1d77e8ebc1b328dfee52d2c2ae4f2ceb9cafd3 100644 (file)
@@ -8,7 +8,6 @@
  * $Id$
  */
 
-#include <ctype.h>
 #include <errno.h>
 #include <pwd.h>
 #include <setjmp.h>
 #include <stdlib.h>
 #include <string.h>
 #include <sys/stat.h>
-#include <sys/time.h>
 #include <sys/types.h>
+#include <syslog.h>
 #include <unistd.h>
 
 /* BSDI needs <netinet/in.h> before <arpa/inet.h>. */
 #include <netinet/in.h>
 #include <arpa/inet.h>
 
-#include "error.h"
 #include "identd.h"
 #include "sident.h"
-#include "pidentd.h" 
+#include "pidentd.h"
+
+/* The number of times to retry a kernel lookup before failing. */
+#define MAX_RETRY 20
 
 extern int do_error();
 extern int parse_auth();
 
 
-/*
-** A small routine to check for the existance of the ".nosident"
-** file in a users home directory.
-*/
-static int check_nosident(uid_t uid)
+/* Check for the existence of a ".nosident" file in a user's home directory.
+   Return whether one was found. */
+static int
+check_nosident(uid_t uid)
 {
-  char *tmp_path,*homedir;
-  struct stat sbuf;
-  int rcode;
-  struct passwd *pw ; 
-
-  if ( users_can_nosident ) { 
-
-    pw = getpwuid(uid); 
-    
-    if ( pw == NULL ) 
-      return 0 ; 
+    char *tmp_path, *homedir;
+    struct stat sbuf;
+    int rcode;
+    struct passwd *pw;
+
+    if (users_can_nosident) {
+        pw = getpwuid(uid);
+        if (pw == NULL)
+            return 0;
+        homedir = pw->pw_dir;
+        if (homedir == NULL)
+            return 0;
+        tmp_path = malloc(strlen(homedir) + sizeof("/.nosident") + 1);
+        if (tmp_path == NULL)
+            return 0;
+        strcpy(tmp_path, homedir);
+        strcat(tmp_path, "/.nosident");
+        rcode = stat(tmp_path, &sbuf);
+        free(tmp_path);
+        return (rcode == 0);
+    } else
+        return 0;
+}
 
-    homedir = pw->pw_dir ; 
+/* Timeout handling for sfgets. */
+static jmp_buf context_read_timeout;
+static void
+readtimeout(int sig)
+{
+    longjmp(context_read_timeout, 1);
+}
 
-    if (!homedir)
-      return 0;
 
-    tmp_path = (char *) malloc(strlen(homedir) + sizeof("/.nosident") + 1);
-    if (!tmp_path)
-      return 0;
+/*
+**  An implementation of fgets that ignores EINTR interrupts and implements a
+**  timeout.  Takes a buffer, the size of the buffer, the file to read from,
+**  the timeout in seconds, and the authentication we're trying to perform
+**  (for error reporting).  Returns NULL on error and a pointer to the buffer
+**  otherwise.
+**
+**  This function needs to be rewritten to use select instead of setjmp and
+**  alarm.  Not only will that be easier to read, it will also be more
+**  reliable and understandable.
+*/
+char *
+sfgets(char *buf, int siz, FILE *fp, time_t timeout,
+       struct ident_auth_data *auth_data)
+{
+    char *p;
 
-    strcpy(tmp_path, homedir);
-    strcat(tmp_path, "/.nosident");
+    if (fp == NULL) {
+        buf[0] = '\0';
+        return NULL;
+    }
 
-    rcode = stat(tmp_path, &sbuf);
-    free(tmp_path);
+    /* Set the timeout. */
+    if (timeout != 0) {
+        if (signal(SIGALRM, readtimeout) == SIG_ERR)
+            do_error(IDENT_SYSTEM_ERROR, auth_data);
+        if (setjmp(context_read_timeout) != 0) {
+            syslog(LOG_NOTICE, "timeout waiting for input");
+            errno = 0;
+            buf[0] = '\0';
+            return NULL;
+        }
+        alarm(timeout);
+    }
 
-    return (rcode == 0);
-  } else { 
-    return ( 1 == 0 ) ; 
-  }
+    /* Try to read. */
+    p = NULL;
+    while (!feof(fp) && !ferror(fp)) {
+        errno = 0;
+        p = fgets(buf, siz, fp);
+        if (p != NULL || errno != EINTR)
+            break;
+        clearerr(fp);
+    }
+    alarm(0);
+    if (verbose_flag)
+        syslog(LOG_DEBUG, "In function sfgets :%d:%s:%s", siz, buf, p);
+    return buf;
 }
 
 
 /*
-**  Borrowed from Sendmail.8.8 
-**  SFGETS -- "safe" fgets -- times out and ignores random interrupts.
-**
-**     Parameters:
-**             buf -- place to put the input line.
-**             siz -- size of buf.
-**             fp -- file to read from.
-**             timeout -- the timeout before error occurs.
-**             during -- what we are trying to read (for error messages).
-**
-**     Returns:
-**             NULL on error (including timeout).  This will also leave
-**                     buf containing a null string.
-**             buf otherwise.
-**
-**     Side Effects:
-**             none.
+**  Parse an incoming line.  If it contains authentication information, run
+**  parse_auth to handle it.  Sets various things in the auth_data struct.
 */
-
-static jmp_buf CtxReadTimeout;
-static void    readtimeout();
-
-char *
-sfgets(buf, siz, fp, timeout,auth_data)
-       char *buf;
-       int siz;
-       FILE *fp;
-       time_t timeout;
-        struct ident_auth_data *auth_data ;
+int
+parse_auth_line(char *line, struct ident_auth_data *auth_data)
 {
+    char arg[33];
+    int rcode;
+    char *p;
 
-       register char *p;
-
-       if (fp == NULL)
-       {
-               buf[0] = '\0';
-               return NULL;
-       }
-
-       /* set the timeout */
-       if (timeout != 0)
-       {
-         if (signal(SIGALRM, readtimeout) == SIG_ERR) 
-                 do_error(IDENT_SYSTEM_ERROR,auth_data) ; 
-         if (setjmp(CtxReadTimeout) != 0)
-           {
-             syslog(LOG_NOTICE,
-                    "timeout waiting for input");
-             errno = 0;
-
-             buf[0] = '\0';
-             return (NULL);
-           }
-         alarm(timeout); 
-       }
-
-       /* try to read */
-       p = NULL;
-       while (!feof(fp) && !ferror(fp))
-       {
-               errno = 0;
-               p = fgets(buf, siz, fp);
-               if (p != NULL || errno != EINTR)
-                       break;
-               clearerr(fp);
-       }
-
-       /* clear the event if it has not sprung */
-
-       alarm(0); 
-
-       if (verbose_flag)
-         syslog(LOG_DEBUG, "In function sfgets :%d:%s:%s",siz,buf,p);
-
-       return (buf);
+    p = strtok(line, ": ");
+    if (verbose_flag)
+        syslog(LOG_DEBUG, "parse_auth_line: %s: port_data %s", line, p);
+    if (p != NULL)
+        auth_data->port_data = p;
+    else
+        return IDENT_INVALID_PORT;
+
+    p = strtok(NULL, ": ");
+    auth_data->cmd_data = p;
+
+    p = strtok(NULL, ": ");
+    auth_data->authenticate_data = p;
+
+    /* Parse the port data into numbers. */
+    rcode = sscanf(auth_data->port_data, " %d , %d ", &auth_data->local_port,
+                   &auth_data->remote_port);
+    if (rcode < 2)
+        return IDENT_INVALID_REQ_INFO;
+
+    /* If we have a command, parse it into a variable and then see if it's an
+       AUTHENTICATE commad.  If not, it's a trivial auth request. */
+    if (auth_data->cmd_data != NULL)
+        rcode = sscanf(auth_data->cmd_data, " %32s ", arg);
+    else
+        rcode = 0;
+    if (rcode > 0) {
+        if (strcmp(arg, "AUTHENTICATE") == 0
+            && auth_data->authenticate_data != NULL) {
+            if (verbose_flag)
+                syslog(LOG_DEBUG, "About to parse %s",
+                       auth_data->authenticate_data);
+            rcode = parse_auth(auth_data->authenticate_data,
+                               &auth_data->auth_struct);
+            return rcode;
+        } else
+            return IDENT_INVALID_REQ_INFO;
+    } else if (allow_trivial) {
+        rcode = parse_auth(NULL, &auth_data->auth_struct);
+        return rcode;
+    } else
+        return IDENT_UNKNOWN_ERROR;
 }
 
-static void
-readtimeout(sig_no)
-       int sig_no;
+
+/*
+**  Send a response back to the requester.  Takes the response and the
+**  auth_data struct (used to fill out the port details).  Always returns
+**  true.
+*/
+int
+do_out(char *string, struct ident_auth_data *auth_data)
 {
-       longjmp(CtxReadTimeout, 1);
+    printf(" %d , %d : %s\r\n", auth_data->local_port,
+           auth_data->remote_port, string);
+    if (verbose_flag)
+        syslog(LOG_DEBUG, " %d , %d : %s", auth_data->local_port,
+               auth_data->remote_port, string);
+    fflush(stdout);
+    return 1;
 }
 
+
 /*
-** Parse incoming lines 
+**  Return an error reply to the requester and log the error.  Takes the error
+**  code and the auth_data struct (used to fill out the port details).  Does
+**  not return; exit is called with the error code.
 **
+**  If the error code is above IDENT_INTERNAL_ERR, no reply is sent and the
+**  connection is just immediately closed.
 */
-int 
-parse_auth_line(line,auth_data) 
-char *line; 
-struct ident_auth_data *auth_data ;
-{ 
-  char arg[33] ;
-  int rcode ; 
-  char *p ; 
-  char delim[] = ":" ; 
-
-  p = strtok(line,delim); 
-  if (verbose_flag)
-    syslog(LOG_DEBUG, "In function parse_auth_line:%s:port_data %s",line,p);
-
-  if ( p != NULL ) { 
-    auth_data->port_data = p ; 
-  } else { 
-    return IDENT_INVALID_PORT ; 
-  }
-
-  p = strtok((char *) NULL,delim); 
-  auth_data->cmd_data = p ; 
-  
-  p = strtok((char *) NULL,delim); 
-  auth_data->authenticate_data = p ; 
-  
-  if ( auth_data->port_data != NULL ) { 
-    rcode = sscanf(auth_data->port_data, " %d , %d ", &(auth_data->local_port),
-                  &(auth_data->remote_port));
-  } else { 
-    return IDENT_INVALID_PORT ; 
-  }
-  if ( rcode > 0 ) { 
-    if (auth_data->cmd_data != NULL ) { 
-      rcode = sscanf(auth_data->cmd_data," %32s ",arg ) ;
+int
+do_error(int e_code, struct ident_auth_data *auth_data)
+{
+    char tmp[2048];
+    int show_code;
+
+    if (e_code < IDENT_INTERNAL_ERR) {
+        show_code = e_code;
+        if (unknown_flag)
+            if (e_code == IDENT_NO_USER || e_code == IDENT_INVALID_PORT)
+                show_code = IDENT_UNKNOWN_ERROR;
+        sprintf(tmp, " ERROR : %s ", ident_err_txt[show_code]);
+        do_out(tmp, auth_data);
+        if (syslog_flag)
+            syslog(LOG_INFO, "Error: %s", ident_err_txt[e_code]);
     } else {
-      rcode = 0 ; 
+        switch (e_code) {
+        case IDENT_NO_MUTUAL_AUTH:
+            if (syslog_flag)
+                syslog(LOG_INFO, "No mutual auth data");
+            break;
+        case IDENT_MUTUAL_AUTH_FAIL:
+            if (syslog_flag)
+                syslog(LOG_INFO, "Mutual auth failed");
+            break;
+        case IDENT_SYSTEM_ERROR:
+            if (syslog_flag)
+                syslog(LOG_INFO, "System error: %m");
+            break;
+        default:
+            if (syslog_flag)
+                syslog(LOG_INFO, "Unknown error code %d", e_code);
+            break;
+        }
     }
-    if ( rcode > 0 ) { 
-      if (( strncmp(arg,"AUTHENTICATE",strlen("AUTHENTICATE")) == 0)
-         && (auth_data->authenticate_data != NULL)  ) {
-        if (verbose_flag)
-          syslog(LOG_DEBUG, "About to parse %s", auth_data->authenticate_data);
-       rcode = parse_auth(auth_data->authenticate_data,&(auth_data->auth_struct)) ; 
-       return rcode ; 
-      } else { 
-       return IDENT_INVALID_REQ_INFO ; 
-      }
-    } else if ( allow_trivial   ) {
-       rcode =  parse_auth(NULL,&(auth_data->auth_struct)) ; 
-       return rcode ; 
-    } else { 
-      return IDENT_UNKNOWN_ERROR ;
-    } 
-  } else { 
-    return IDENT_SYSTEM_ERROR; 
-  }
-  
+    exit(e_code);
 }
-int 
-do_out(string , auth_data)
-char *string ; 
-struct ident_auth_data *auth_data ; 
-{
-  printf(" %d , %d : %s\r\n", auth_data->local_port,auth_data->remote_port,string); 
-  if (verbose_flag)
-    syslog(LOG_DEBUG," %d , %d : %s", auth_data->local_port,auth_data->remote_port,string );
-  
-   fflush(stdout); 
-   return 1;
-} 
-/* 
-** Handle ERROR codes 
+
+
+/*
+**  The core of the S/Ident daemon.  Parse the incoming request from the
+**  requester and take appropriate action.  This is also where we do the
+**  kernel query to flesh out the details of the request before passing them
+**  off to the handlers for the different authentication methods.
 **
+**  Takes the FILE of the remote connection, the local Internet address, and
+**  the remote Internet address (used in the kernel query).  Always returns 0;
+**  on error, this function will never return.
 */
-int 
-do_error(e_code,auth_data) 
-  int e_code ; 
-  struct ident_auth_data *auth_data ;
-{ 
-  char tmp[2048] ; 
-  int show_code ; 
-  if ( e_code < IDENT_INTERNAL_ERR ) { 
-    show_code = e_code ; 
-    if ( unknown_flag  )
-      if ( e_code == IDENT_NO_USER || e_code == IDENT_INVALID_PORT ) 
-       show_code = IDENT_UNKNOWN_ERROR ; 
-    sprintf(tmp," ERROR : %s ", ident_err_txt[show_code]);
-    do_out(tmp,auth_data); 
-
-    if ( syslog_flag)
-      syslog(LOG_INFO, "Error : %s", ident_err_txt[e_code]);
-      
-  } else { 
-    /* Need to syslog errors here */ 
-    switch(e_code) { 
-    case IDENT_NO_MUTUAL_AUTH: 
-      if ( syslog_flag) 
-       syslog(LOG_INFO, " No mutual auth data");
-      break;
-    case IDENT_MUTUAL_AUTH_FAIL: 
-      if ( syslog_flag)
-       syslog(LOG_INFO, " Mutual auth failed" );
-      break ;
-    case IDENT_SYSTEM_ERROR: 
-      if ( syslog_flag)
-       syslog(LOG_INFO, " System error" );
-      break ;
-
-    default:
-      if (syslog_flag)
-       syslog(LOG_INFO, " Unknown error code %d",e_code );
-      ; 
-    } 
-  } 
-  exit(e_code); 
-
-}  
-
-
-
-int parse(fp, laddr, faddr)
-  FILE *fp;
-  struct in_addr *laddr, *faddr;
+int
+parse(FILE *fp, struct in_addr *laddr, struct in_addr *faddr)
 {
-  int try, rcode;
-  int timeout = IDENT_READ_TIMEOUT ; 
-
-  struct ident_auth_data auth_data ; 
-  
-  struct in_addr laddr2;
-  struct in_addr faddr2;
-  int k_opened;
-  char line[2048]; 
-  char *line_ptr ; 
-  void *ka_ptr ; 
-  struct  kernel *kinfo_ptr ; 
-
-  k_opened = 0;
-
-  if (verbose_flag)
-    syslog(LOG_DEBUG, "In function parse()");
-
-  /*
-  ** Get the local/foreign port pair from the luser
-  */
-
-  if (verbose_flag)
-    syslog(LOG_DEBUG, "  Before sfgets()");
-
-  faddr2 = *faddr;
-  laddr2 = *laddr;
-  auth_data.local_addr = &laddr2;
-  auth_data.remote_addr = &faddr2; 
-  auth_data.fp = fp ; 
-
-  auth_data.local_port = auth_data.remote_port = 0;
-   
-  /* Read query from client */
-  line_ptr = line ;
-  line_ptr = sfgets(line,2048,fp,timeout,&auth_data); 
-  if (verbose_flag)
-    syslog(LOG_DEBUG, "After sfgets line_ptr:%s",line_ptr);
-
-  if ( line_ptr == NULL  ) { 
-    do_error(IDENT_SYSTEM_ERROR,&auth_data); 
-  } 
-  rcode = parse_auth_line(line_ptr,&auth_data); 
-  if ( rcode != IDENT_AUTH_OKAY ) { 
-    do_error(rcode,&auth_data); 
-  }
-
-
-  if (!( VALID_PORT(auth_data.local_port) &&  VALID_PORT(auth_data.remote_port))) { 
-    do_error(IDENT_INVALID_PORT,&auth_data); 
-  }
-    
-  if ( client_only_flag ) { 
-    if( SERVER_PORT(auth_data.local_port) ) { 
-      do_error(IDENT_NO_USER,&auth_data); 
-    }
-  }
-
-  if (syslog_flag) {
-    syslog(LOG_NOTICE, "from: %s ( %s ) for: %d, %d",
-          inet_ntoa(*faddr), gethost(faddr), auth_data.local_port, auth_data.remote_port);
-  }
-
-  if (verbose_flag)
-    syslog(LOG_DEBUG, "  After fscanf(), before k_open()");
-
-  if (! k_opened) {
-    /*
-    ** Open the kernel memory device and read the nlist table
-    ** 
-    ** Converted to use the ka_open routines from pidentd.3.0.x
-    */
-    if (ka_open(&ka_ptr) != 0) {
-      if (syslog_flag) 
-       syslog(LOG_ERR, "ka_open call failed");
-      do_error(IDENT_UNKNOWN_ERROR,auth_data);
-      
-    }
-    k_opened = 1;
-  }
-
-  if (verbose_flag)
-    syslog(LOG_DEBUG, "  After ka_open(), before ka_lookup()");
-
-  /*
-  ** Get the specific TCP connection and return the uid - user number.
-  */
+    int try, rcode;
+    int timeout = IDENT_READ_TIMEOUT;
+    struct ident_auth_data auth_data;
+    char line[2048];
+    char *line_ptr;
+    void *ka_ptr;
+    struct kernel *kinfo_ptr;
 
-#define MAX_RETRY 20
-  /*
-  ** Try to fetch the information MAX_RETRY times in case the
-  ** kernel changed beneath us and we missed or took a fault.
-  **
-  ** Why would we ever fail? Is not there a reliable way for the
-  ** kernel to identify its sockets? Cannot we use that interface?
-  **
-  ** Used to be 5 times, but often this is not enough on Alpha OSF.
-  */
-  /* #define SLEEP_BETWEEN_RETRIES 1 */
-  /*
-  ** If we failed in k_getuid, that is presumably because the OS was
-  ** busy creating or destroying processes. We may want to sleep for
-  ** a random time between retries, hoping for peace and quiet.
-  */
-
-  /* Fill up kernel info struct */ 
-
-  /*  struct kernel */
-  /*  { */
-  /*       Request parameters  */
-  /*      struct sockaddr_in local; */
-  /*      struct sockaddr_in remote; */
-    
-  /*      Result parameters */
-  /*      avail_t av; */
-    
-  /*      int status; */
-  /*      uid_t euid; */
-  /*      uid_t ruid; */
-    
-  /*      pid_t pid; */
-  /*      char *cmd; */
-  /*      char *argv; */
-  /*  }; */
-
-  kinfo_ptr = kernel_alloc() ; 
-
-  if ( kinfo_ptr == NULL ) { 
-    if (syslog_flag) 
-       syslog(LOG_ERR, "kernel_alloc call failed");
-    do_error(IDENT_UNKNOWN_ERROR,auth_data);
-  }
-
-  kinfo_ptr->local.sin_port = htons(auth_data.local_port) ; 
-  kinfo_ptr->remote.sin_port  = htons(auth_data.remote_port) ;
-  memcpy(&(kinfo_ptr->local.sin_addr),auth_data.local_addr,sizeof(struct in_addr)); 
-  memcpy(&(kinfo_ptr->remote.sin_addr),auth_data.remote_addr,sizeof(struct in_addr)); 
-  kinfo_ptr->local.sin_family = AF_INET ; 
-  kinfo_ptr->remote.sin_family = AF_INET ; 
-  /* ka_lookup returns 0 on not-found,1 on found, -1 on failure. */
-  kinfo_ptr->status = -1 ; 
-
-  for (try = 0;(try < MAX_RETRY && kinfo_ptr->status <  0); try++) {
-    kinfo_ptr->status =  ka_lookup(ka_ptr,kinfo_ptr) ; 
-      
-#ifdef SLEEP_BETWEEN_RETRIES
-    if (  kinfo_ptr->status <  0 ) {  
-      /* Seed the generator: auth_data.local_port should be unique (among other concurrent identd's) */
-      if (try < 1) srandom(auth_data.local_port);
-      /* This gives a max sleep of 0xffff = 65535 microsecs, about 32millisec average */
-      usleep(random()&0x00ffff);
-    }
-#endif
-  }
-  if (try >= MAX_RETRY) {
-    if (syslog_flag)   
-      syslog(LOG_INFO, "MAX_RETRY exceeded,Returned: %d , %d : NO-USER", auth_data.local_port, auth_data.remote_port);
-    do_error(IDENT_NO_USER,&auth_data); 
-  }
-
-  if (try > 1 && verbose_flag)
-    syslog(LOG_DEBUG, "ka_lookup retries: %d", try);
-
-  if (verbose_flag)
-    syslog(LOG_DEBUG, "  After ka_lookup(), before getpwuid() kinfo_ptr status = %d",kinfo_ptr->status);
-
-  if ( kinfo_ptr->status == 0 ) { 
-    do_error(IDENT_NO_USER,&auth_data); 
-  }
-
-  if (kinfo_ptr->ruid == NO_UID)
-    auth_data.uid = kinfo_ptr->euid;
-  else
-    auth_data.uid = kinfo_ptr->ruid;
-
-  if ( auth_data.uid > -1 ) { 
-      /* Setuid here ??? */ 
-
-      if ( setuid(auth_data.uid) != 0 ) { 
-         syslog(LOG_ALERT,"Setuid failed for uid:%d",auth_data.uid); 
-         do_error(IDENT_UNKNOWN_ERROR,&auth_data); 
-      }
-      /* Check for .nosident */ 
-      if( check_nosident(auth_data.uid) ) { 
-         syslog(LOG_DEBUG,"No ident requested by uid:%d",auth_data.uid) ; 
-         do_error(IDENT_HIDDEN_USER,&auth_data); 
-      } 
-  } else { 
+    if (verbose_flag)
+        syslog(LOG_DEBUG, "In function parse");
+    auth_data.local_addr = laddr;
+    auth_data.remote_addr = faddr;
+    auth_data.fp = fp;
+    auth_data.local_port = 0;
+    auth_data.remote_port = 0;
+
+    /* Read query from client and parse it. */
+    line_ptr = sfgets(line, 2048, fp, timeout, &auth_data);
+    if (verbose_flag)
+        syslog(LOG_DEBUG, "After sfgets line_ptr: %s", line_ptr);
+    if (line_ptr == NULL)
+        do_error(IDENT_SYSTEM_ERROR, &auth_data);
+    rcode = parse_auth_line(line_ptr, &auth_data);
+    if (rcode != IDENT_AUTH_OKAY)
+        do_error(rcode, &auth_data);
+
+    /* Validate the ports in the query. */
+    if (!VALID_PORT(auth_data.local_port)
+        || !VALID_PORT(auth_data.remote_port))
+        do_error(IDENT_INVALID_PORT,&auth_data);
+    if (client_only_flag)
+        if (SERVER_PORT(auth_data.local_port))
+            do_error(IDENT_NO_USER, &auth_data);
+
+    /* Log the query. */
     if (syslog_flag)
-      syslog(LOG_INFO, "INVALID uid %d",auth_data.uid);
-    do_error(IDENT_UNKNOWN_ERROR,&auth_data); 
-  }
+        syslog(LOG_NOTICE, "from: %s (%s), for: %d, %d",
+               inet_ntoa(*faddr), gethost(faddr), auth_data.local_port,
+               auth_data.remote_port);
 
-  if (syslog_flag)
-    syslog(LOG_INFO, "AUTHENTICATE with %s",auth_data.auth_struct->auth_method);
-
-  rcode = (*auth_data.auth_struct->start)(&auth_data);
-  if ( rcode != IDENT_AUTH_OKAY ) { 
+    /* Open the kernel and find the associated user. */
     if (verbose_flag)
-      syslog(LOG_DEBUG, "  Fail in auth_start");
-    do_error(rcode,&auth_data);
-  }
-
-  rcode = (*auth_data.auth_struct->auth)(&auth_data);
-  if ( rcode != IDENT_AUTH_OKAY ) { 
+        syslog(LOG_DEBUG, "After parsing, before k_open");
+    if (ka_open(&ka_ptr) != 0) {
+        if (syslog_flag)
+            syslog(LOG_ERR, "ka_open call failed");
+        do_error(IDENT_UNKNOWN_ERROR, &auth_data);
+    }
     if (verbose_flag)
-      syslog(LOG_DEBUG, " Fail in auth_auth");
-    do_error(rcode,&auth_data); 
-  }     
-  return 0;
+        syslog(LOG_DEBUG, "After ka_open, before ka_lookup");
+
+    /* Get the specific TCP connection and return the uid.
+
+       Try to fetch the information MAX_RETRY times in case the kernel changed
+       beneath us and we missed or took a fault.  Used to be 5 times, but
+       often this is not enough on Alpha OSF.
+
+       If we failed in ka_lookup, that is presumably because the OS was busy
+       creating or destroying processes.  We may want to sleep for a random
+       time between retries, hoping for peace and quiet, but we don't
+       currently. */
+    kinfo_ptr = kernel_alloc();
+    if (kinfo_ptr == NULL) {
+        if (syslog_flag)
+            syslog(LOG_ERR, "kernel_alloc call failed");
+        do_error(IDENT_UNKNOWN_ERROR, &auth_data);
+    }
+    kinfo_ptr->local.sin_port = htons(auth_data.local_port);
+    kinfo_ptr->remote.sin_port = htons(auth_data.remote_port);
+    memcpy(&kinfo_ptr->local.sin_addr, auth_data.local_addr,
+           sizeof(struct in_addr));
+    memcpy(&kinfo_ptr->remote.sin_addr, auth_data.remote_addr,
+           sizeof(struct in_addr));
+    kinfo_ptr->local.sin_family = AF_INET ;
+    kinfo_ptr->remote.sin_family = AF_INET ;
+    kinfo_ptr->status = -1;
+
+    /* status will be set to 0 on not found, 1 on found, and -1 on failure. */
+    for (try = 0; try < MAX_RETRY && kinfo_ptr->status < 0; try++)
+        kinfo_ptr->status = ka_lookup(ka_ptr, kinfo_ptr);
+    if (try >= MAX_RETRY) {
+        if (syslog_flag)
+            syslog(LOG_INFO,
+                   "MAX_RETRY exceeded, returned: %d , %d : NO-USER",
+                   auth_data.local_port, auth_data.remote_port);
+        do_error(IDENT_NO_USER, &auth_data);
+    }
+    if (try > 1 && verbose_flag)
+        syslog(LOG_DEBUG, "ka_lookup retries: %d", try);
+    if (verbose_flag)
+        syslog(LOG_DEBUG, "after ka_lookup, before getpwuid,"
+               " kinfo_ptr status = %d", kinfo_ptr->status);
+    if (kinfo_ptr->status == 0)
+        do_error(IDENT_NO_USER,&auth_data);
+
+    /* Try to use the real, not the effective, UID where possible. */
+    if (kinfo_ptr->ruid == NO_UID)
+        auth_data.uid = kinfo_ptr->euid;
+    else
+        auth_data.uid = kinfo_ptr->ruid;
+
+    /* If we found a valid UID, change users.  We can do everything from this
+       point forward as the user whose information is being looked up.  Check
+       for the user's .nosident file at this point as well. */
+    if (auth_data.uid > -1) {
+        if (setuid(auth_data.uid) != 0) {
+            syslog(LOG_ALERT, "setuid failed for uid %d", auth_data.uid);
+            do_error(IDENT_UNKNOWN_ERROR, &auth_data);
+        }
+        if (check_nosident(auth_data.uid)) {
+            syslog(LOG_DEBUG, "no ident requested by uid %d", auth_data.uid);
+            do_error(IDENT_HIDDEN_USER, &auth_data);
+        }
+    } else {
+        if (syslog_flag)
+            syslog(LOG_INFO, "invalid uid %d", auth_data.uid);
+        do_error(IDENT_UNKNOWN_ERROR, &auth_data);
+    }
+
+    /* We have a valid request.  Now do the real work. */
+    if (syslog_flag)
+        syslog(LOG_INFO, "AUTHENTICATE with %s",
+               auth_data.auth_struct->auth_method);
+    rcode = (*auth_data.auth_struct->start)(&auth_data);
+    if (rcode != IDENT_AUTH_OKAY) {
+        if (verbose_flag)
+            syslog(LOG_DEBUG, "fail in auth_start");
+        do_error(rcode, &auth_data);
+    }
+    rcode = (*auth_data.auth_struct->auth)(&auth_data);
+    if (rcode != IDENT_AUTH_OKAY) {
+        if (verbose_flag)
+            syslog(LOG_DEBUG, "fail in auth_auth");
+        do_error(rcode, &auth_data);
+    }
+    return 0;
 }
diff --git a/responder/paths.h b/responder/paths.h
deleted file mode 100644 (file)
index 47eba09..0000000
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
-** paths.h             Common path definitions for the in.identd daemon
-**
-** Last update: 11 Dec 1992
-**
-** Please send bug fixes/bug reports to: Peter Eriksson <pen@lysator.liu.se>
-*/
-
-#ifdef sequent
-#  define _PATH_UNIX "/dynix"
-#endif
-
-#if defined(MIPS) || defined(IRIX) || defined(sco) || defined(_SEQUENT_)
-#  define _PATH_UNIX "/unix"
-#endif
-
-#if defined(hpux) || defined(__hpux)
-#ifdef HPUX_10
-#  define _PATH_UNIX "/stand/vmunix"
-#else
-#  define _PATH_UNIX "/hp-ux"
-#endif
-#endif
-
-#ifdef SOLARIS
-#  define _PATH_UNIX "/dev/ksyms"
-#else
-#  if defined(SVR4) && !defined(_SEQUENT_)
-#    define _PATH_UNIX "/stand/unix"
-#  endif
-#endif
-
-#ifdef BSD43
-#  define _PATH_SWAP "/dev/drum"
-#  define _PATH_MEM  "/dev/mem"
-#endif
-
-#ifdef _AUX_SOURCE
-#  define _PATH_UNIX "/unix"
-#endif
-
-#ifdef _CRAY
-#  define _PATH_UNIX "/unicos"
-#  define _PATH_MEM  "/dev/mem"
-#endif
-
-#ifdef NeXT
-#  define _PATH_UNIX "/mach"
-#endif
-
-#ifdef __bsdi__
-#  define _PATH_UNIX "/bsd"
-#endif /* __bsdi__ */
-
-
-/*
- * Some defaults...
- */
-#ifndef _PATH_KMEM
-#  define _PATH_KMEM "/dev/kmem"
-#endif
-
-#ifndef _PATH_UNIX
-#  define _PATH_UNIX "/vmunix"
-#endif
-
-
-#ifndef PATH_CONFIG
-#  define PATH_CONFIG "/etc/identd.conf"
-#endif
-
-#ifndef PATH_DESKEY
-#  define PATH_DESKEY "/etc/identd.key"
-#endif
index 909f9174de62ad3b058c646bc5a8ddaa89e878d7..770239144f37e74c910e80358aade64ab8437ab5 100644 (file)
@@ -1,11 +1,11 @@
 /** @file
  * Provides necessary glue in order to use pidentd kernel files.
  *
- * This file provides the glue necessary to use pident3.* k_os files with
+ * This file provides the glue necessary to use pident 3.* k_os files with
  * S/Ident without any changes to the k_os files.
  *
  * $Id$
- */ 
+ */
 
 #ifndef PIDENTD_H
 #define PIDENTD_H
 #define NO_UID ((uid_t) -1)
 #define NO_PID ((pid_t) -1)
 
-#ifndef KERNEL_HELPER 
-extern char *osinfo_build ; 
-#endif
-
-char *osinfo_get( char *osinfo_current) ; 
-
-void *s_malloc( size_t size ) ; 
-void s_free( void *ptr) ; 
-
-char *s_strdup(const char *dup_string ) ; 
-
-struct kernel
-{
-    /* Request parameters */
+/* Taken from pidentd's sockaddr.h, the non-IPv6 case.  Eventually we'll have
+   to pull in the IPv6 pieces, but sident needs a bunch more work to support
+   IPv6.  These are used by the Solaris modules. */
+#define SGFAM(sag)      AF_INET
+#define SGSIZE(sag)     sizeof(struct in_addr)
+#define SGSOCKSIZE(sag) sizeof(struct sockaddr_in)
+#define SGPORT(sag)     ((sag).sin_port)
+#define SGADDRP(sag)    ((char *) &(sag).sin_addr)
+
+/* Only used by ka_init, which we don't call. */
+extern const char *osinfo_build;
+char *osinfo_get(char *osinfo_current);
+
+/* Various safe versions of regular functions used by the kernel modules. */
+void *s_malloc(size_t);
+void s_free(void *);
+char *s_strdup(const char *);
+int s_open(const char *, int, ...);
+int s_snprintf(char *, size_t, const char *, ...);
+
+/* Used as the interface to the kernel routines.  This matches the kernel
+   struct in pidentd 3.x except that we omit the av parameter, since none of
+   the kernel modules actually use it (it's a thread mutex). */
+struct kernel {
     struct sockaddr_in local;
     struct sockaddr_in remote;
 
     /* Result parameters */
-    
     int status;
     uid_t euid;
     uid_t ruid;
@@ -49,20 +58,22 @@ struct kernel
     char *argv;
 };
 
+/* Filled in by ka_init for some drivers.  We don't use them, but they have to
+   be here to compile the kernel modules. */
 extern int kernel_threads;
 extern int kernel_buffers;
 extern int kernel_attempts;
 
+/* The kernel modules use debug instead of debug_flag. */
+extern int debug_flag;
+#define debug debug_flag
+
+/* These interface functions we actually call in the sident code. */
 extern struct kernel *kernel_alloc(void);
 extern void kernel_free(struct kernel *kp);
 
-extern int kernel_init(void);
-extern void kernel_query(struct kernel *kp);
-
-
-/*
-** Operating system specific kernel access functions
-*/
+/* The kernel modules provide the following three functions.  We never call
+   ka_init, but we do use the other two. */
 extern int ka_init(void);
 extern int ka_open(void **misc);
 extern int ka_lookup(void *misc, struct kernel *kp);