/* Define to compile with Kerberos support. */
#undef HAVE_KRB4
+/* Define to compile with Kerberos v5 support. */
+#undef HAVE_KRB5
+
+/* Define to 1 if `enc_part2' is member of `krb5_ticket'. */
+#undef HAVE_KRB5_TICKET_ENC_PART2
+
+/* Define to 1 if `keyblock.enctype' is member of `krb5_creds'. */
+#undef HAVE_KRB5_CREDS_KEYBLOCK_ENCTYPE
+
+/* Define to 1 if you have the `krb5_c_make_checksum' function. */
+#undef HAVE_KRB5_C_MAKE_CHECKSUM
+
+/* Define to 1 if you have the `krb5_cc_set_default_name' function. */
+#undef HAVE_KRB5_CC_SET_DEFAULT_NAME
+
+/* Define to 1 if `krb5_auth_con_getauthenticator' takes a double pointer third arg. */
+#undef KRB5_AUTH_CON_GETAUTHENTICATOR_TAKES_DOUBLE_POINTER
+
+/* Define to 1 if you have the <krb5_err.h> header file. */
+#undef HAVE_KRB5_ERR_H
+
+/* Define to 1 if you have the `krb5_free_data' function. */
+#undef HAVE_KRB5_FREE_DATA
+
+/* Define to 1 if you have the <krb5/ss.h> header file. */
+#undef HAVE_KRB5_SS_H
+
+/* Define to 1 if you have the `krb_get_err_text' function. */
+#undef HAVE_KRB_GET_ERR_TEXT
+
+/* Define to 1 if you have the `krb_log' function. */
+#undef HAVE_KRB_LOG
+
/* Define to compile with ares support. */
#undef HAVE_ARES
AC_HEADER_SYS_WAIT
AC_CHECK_HEADERS(fcntl.h paths.h termios.h sgtty.h unistd.h malloc.h)
AC_CHECK_HEADERS(sys/filio.h sys/ioctl.h sys/time.h sys/file.h sys/utsname.h)
-AC_CHECK_HEADERS(sys/select.h sys/msgbuf.h sys/cdefs.h)
+AC_CHECK_HEADERS(sys/select.h sys/msgbuf.h sys/cdefs.h krb5_err.h)
if test "$no_x" != "yes"; then
XCLIENTS=xzwrite
AC_SUBST(SLIB)
ATHENA_KRB4
+ATHENA_KRB5
ATHENA_HESIOD
ATHENA_REGEXP
ATHENA_ARES
ATHENA_UTIL_COM_ERR
ATHENA_UTIL_SS
-LIBS="$KRB4_LIBS $HESIOD_LIBS $LIBS"
+LIBS="$KRB5_LIBS $KRB4_LIBS $HESIOD_LIBS $LIBS"
dnl Checks for library functions.
AC_PROG_GCC_TRADITIONAL
AC_FUNC_SETPGRP
AC_CHECK_FUNCS(putenv strchr memcpy memmove waitpid getlogin strerror random)
AC_CHECK_FUNCS(lrand48 gethostid getsid getpgid krb_get_err_text krb_log)
+AC_CHECK_FUNCS(krb5_free_data krb5_c_make_checksum krb5_cc_set_default_name)
+
+AC_MSG_CHECKING(for krb5_auth_con_getauthenticator taking double pointer)
+AC_CACHE_VAL(ac_cv_krb5_auth_con_getauthenticator_takes_double_pointer, [
+local_save_CPPFLAGS="$CPPFLAGS"
+CPPFLAGS="${CPPFLAGS} ${KRB5_INC_FLAGS}"
+AC_TRY_COMPILE(
+[#define socklen_t int
+#define ssize_t int
+#include <krb5.h>
+krb5_error_code
+krb5_auth_con_getauthenticator(krb5_context context,
+ krb5_auth_context auth_context,
+ krb5_authenticator *authenticator);],
+[krb5_error_code foo = krb5_auth_con_getauthenticator(0, 0, 0);],
+ac_cv_krb5_auth_con_getauthenticator_takes_double_pointer=no,
+ac_cv_krb5_auth_con_getauthenticator_takes_double_pointer=yes)
+])
+CPPFLAGS="${local_save_CPPFLAGS}"
+if test "$ac_cv_krb5_auth_con_getauthenticator_takes_double_pointer" = yes; then
+ AC_DEFINE(KRB5_AUTH_CON_GETAUTHENTICATOR_TAKES_DOUBLE_POINTER)dnl
+fi
+AC_MSG_RESULT($ac_cv_krb5_auth_con_getauthenticator_takes_double_pointer)
+
+AC_MSG_CHECKING(for enc_part2 in struct krb5_ticket)
+AC_CACHE_VAL(ac_cv_have_krb5_ticket_enc_part2, [
+local_save_CPPFLAGS="$CPPFLAGS"
+CPPFLAGS="${CPPFLAGS} ${KRB5_INC_FLAGS}"
+AC_TRY_COMPILE(
+[#include <krb5.h>], [krb5_ticket _tkt; _tkt.enc_part2;],
+ac_cv_have_krb5_ticket_enc_part2=yes,
+ac_cv_have_krb5_ticket_enc_part2=no)
+])
+CPPFLAGS="${local_save_CPPFLAGS}"
+if test "$ac_cv_have_krb5_ticket_enc_part2" = yes; then
+ AC_DEFINE(HAVE_KRB5_TICKET_ENC_PART2)dnl
+fi
+AC_MSG_RESULT($ac_cv_have_krb5_ticket_enc_part2)
+
+AC_MSG_CHECKING(for enctype in struct krb5_keyblock)
+AC_CACHE_VAL(ac_cv_have_krb5_creds_keyblock_enctype, [
+local_save_CPPFLAGS="$CPPFLAGS"
+CPPFLAGS="${CPPFLAGS} ${KRB5_INC_FLAGS}"
+AC_TRY_COMPILE(
+[#include <krb5.h>], [krb5_creds _creds; _creds.keyblock.enctype;],
+ac_cv_have_krb5_creds_keyblock_enctype=yes,
+ac_cv_have_krb5_creds_keyblock_enctype=no)
+])
+CPPFLAGS="${local_save_CPPFLAGS}"
+if test "$ac_cv_have_krb5_creds_keyblock_enctype" = yes; then
+ AC_DEFINE(HAVE_KRB5_CREDS_KEYBLOCK_ENCTYPE)dnl
+fi
+AC_MSG_RESULT($ac_cv_have_krb5_creds_keyblock_enctype)
AC_CONFIG_HEADER(h/config.h)
AC_OUTPUT(Makefile clients/Makefile clients/xzwrite/Makefile
/* h/config.h.in. Generated automatically from configure.in by autoheader. */
+/* Define to compile with Hesiod support. */
+#undef HAVE_HESIOD
-/* Define if the `getpgrp' function takes no argument. */
-#undef GETPGRP_VOID
+/* Define to compile with Kerberos support. */
+#undef HAVE_KRB4
-/* Define to `int' if <sys/types.h> doesn't define. */
-#undef gid_t
+/* Define to compile with Kerberos v5 support. */
+#undef HAVE_KRB5
-/* Define if you don't have vprintf but do have _doprnt. */
-#undef HAVE_DOPRNT
+/* Define to 1 if `enc_part2' is member of `krb5_ticket'. */
+#undef HAVE_KRB5_TICKET_ENC_PART2
-/* Define if you have <sys/wait.h> that is POSIX.1 compatible. */
-#undef HAVE_SYS_WAIT_H
+/* Define to 1 if `keyblock.enctype' is member of `krb5_creds'. */
+#undef HAVE_KRB5_CREDS_KEYBLOCK_ENCTYPE
-/* Define if you have the vprintf function. */
-#undef HAVE_VPRINTF
+/* Define to 1 if you have the `krb5_c_make_checksum' function. */
+#undef HAVE_KRB5_C_MAKE_CHECKSUM
-/* Define as the return type of signal handlers (int or void). */
-#undef RETSIGTYPE
+/* Define to 1 if you have the `krb5_cc_set_default_name' function. */
+#undef HAVE_KRB5_CC_SET_DEFAULT_NAME
-/* Define if the `setpgrp' function takes no argument. */
-#undef SETPGRP_VOID
+/* Define to 1 if `krb5_auth_con_getauthenticator' takes a double pointer third arg. */
+#undef KRB5_AUTH_CON_GETAUTHENTICATOR_TAKES_DOUBLE_POINTER
-/* Define if you have the ANSI C header files. */
-#undef STDC_HEADERS
+/* Define to 1 if you have the <krb5_err.h> header file. */
+#undef HAVE_KRB5_ERR_H
-/* Define to `int' if <sys/types.h> doesn't define. */
-#undef uid_t
+/* Define to 1 if you have the `krb5_free_data' function. */
+#undef HAVE_KRB5_FREE_DATA
-/* Define if the X Window System is missing or not being used. */
-#undef X_DISPLAY_MISSING
+/* Define to 1 if you have the <krb5/ss.h> header file. */
+#undef HAVE_KRB5_SS_H
-/* Define to compile with Hesiod support. */
-#undef HAVE_HESIOD
+/* Define to 1 if you have the `krb_get_err_text' function. */
+#undef HAVE_KRB_GET_ERR_TEXT
-/* Define to compile with Kerberos support. */
-#undef HAVE_KRB4
+/* Define to 1 if you have the `krb_log' function. */
+#undef HAVE_KRB_LOG
/* Define to compile with ares support. */
#undef HAVE_ARES
/* Define if you have the System Resource Controller library. */
#undef HAVE_SRC
+/* Define to "unsigned long" if your system headers don't. */
+#undef ulong
+
/* Define to a temporary directory on your system. */
#define FOUND_TMP "/var/tmp"
/* Define to the type of the host system. */
#define MACHINE_TYPE "unknown"
-/* The number of bytes in a int. */
-#undef SIZEOF_INT
+/* Define if `regcomp' exists and works. */
+#undef HAVE_REGCOMP
-/* The number of bytes in a long. */
-#undef SIZEOF_LONG
-/* The number of bytes in a short. */
-#undef SIZEOF_SHORT
+/* Define if the `getpgrp' function takes no argument. */
+#undef GETPGRP_VOID
+
+/* Define if you don't have `vprintf' but do have `_doprnt.' */
+#undef HAVE_DOPRNT
-/* Define if you have the gethostid function. */
+/* Define if you have the <fcntl.h> header file. */
+#undef HAVE_FCNTL_H
+
+/* Define if you have the `gethostid' function. */
#undef HAVE_GETHOSTID
-/* Define if you have the getlogin function. */
+/* Define if you have the `getlogin' function. */
#undef HAVE_GETLOGIN
-/* Define if you have the getpgid function. */
+/* Define if you have the `getpgid' function. */
#undef HAVE_GETPGID
-/* Define if you have the getsid function. */
+/* Define if you have the `getsid' function. */
#undef HAVE_GETSID
-/* Define if you have the krb_get_err_text function. */
+/* Define if you have the <inttypes.h> header file. */
+#undef HAVE_INTTYPES_H
+
+/* Define if you have the `krb5_cc_set_default_name' function. */
+#undef HAVE_KRB5_CC_SET_DEFAULT_NAME
+
+/* Define if `keyblock.enctype' is member of `krb5_creds'. */
+#undef HAVE_KRB5_CREDS_KEYBLOCK_ENCTYPE
+
+/* Define if you have the `krb5_c_make_checksum' function. */
+#undef HAVE_KRB5_C_MAKE_CHECKSUM
+
+/* Define if you have the <krb5_err.h> header file. */
+#undef HAVE_KRB5_ERR_H
+
+/* Define if you have the `krb5_free_data' function. */
+#undef HAVE_KRB5_FREE_DATA
+
+/* Define if `enc_part2' is member of `krb5_ticket'. */
+#undef HAVE_KRB5_TICKET_ENC_PART2
+
+/* Define if you have the `krb_get_err_text' function. */
#undef HAVE_KRB_GET_ERR_TEXT
-/* Define if you have the krb_log function. */
+/* Define if you have the `krb_log' function. */
#undef HAVE_KRB_LOG
-/* Define if you have the lrand48 function. */
+/* Define if you have the `44bsd' library (-l44bsd). */
+#undef HAVE_LIB44BSD
+
+/* Define if you have the `curses' library (-lcurses). */
+#undef HAVE_LIBCURSES
+
+/* Define if you have the `dl' library (-ldl). */
+#undef HAVE_LIBDL
+
+/* Define if you have the `gen' library (-lgen). */
+#undef HAVE_LIBGEN
+
+/* Define if you have the `nsl' library (-lnsl). */
+#undef HAVE_LIBNSL
+
+/* Define if you have the `readline' library (-lreadline). */
+#undef HAVE_LIBREADLINE
+
+/* Define if you have the `resolv' library (-lresolv). */
+#undef HAVE_LIBRESOLV
+
+/* Define if you have the `socket' library (-lsocket). */
+#undef HAVE_LIBSOCKET
+
+/* Define if you have the `w' library (-lw). */
+#undef HAVE_LIBW
+
+/* Define if you have the `lrand48' function. */
#undef HAVE_LRAND48
-/* Define if you have the memcpy function. */
+/* Define if you have the <malloc.h> header file. */
+#undef HAVE_MALLOC_H
+
+/* Define if you have the `memcpy' function. */
#undef HAVE_MEMCPY
-/* Define if you have the memmove function. */
+/* Define if you have the `memmove' function. */
#undef HAVE_MEMMOVE
-/* Define if you have the putenv function. */
+/* Define if you have the <memory.h> header file. */
+#undef HAVE_MEMORY_H
+
+/* Define if you have the <paths.h> header file. */
+#undef HAVE_PATHS_H
+
+/* Define if you have the `putenv' function. */
#undef HAVE_PUTENV
-/* Define if you have the random function. */
+/* Define if you have the `random' function. */
#undef HAVE_RANDOM
-/* Define if you have the strchr function. */
-#undef HAVE_STRCHR
-
-/* Define if you have the strerror function. */
-#undef HAVE_STRERROR
+/* Define if you have the <sgtty.h> header file. */
+#undef HAVE_SGTTY_H
-/* Define if you have the waitpid function. */
-#undef HAVE_WAITPID
+/* Define if you have the <stdlib.h> header file. */
+#undef HAVE_STDLIB_H
-/* Define if you have the <fcntl.h> header file. */
-#undef HAVE_FCNTL_H
+/* Define if you have the `strchr' function. */
+#undef HAVE_STRCHR
-/* Define if you have the <malloc.h> header file. */
-#undef HAVE_MALLOC_H
+/* Define if you have the `strerror' function. */
+#undef HAVE_STRERROR
-/* Define if you have the <paths.h> header file. */
-#undef HAVE_PATHS_H
+/* Define if you have the <strings.h> header file. */
+#undef HAVE_STRINGS_H
-/* Define if you have the <sgtty.h> header file. */
-#undef HAVE_SGTTY_H
+/* Define if you have the <string.h> header file. */
+#undef HAVE_STRING_H
-/* Define if you have the <sys/cdefs.h> header file. */
+/* Define if you have the <sys/cdefs.h> header file. */
#undef HAVE_SYS_CDEFS_H
-/* Define if you have the <sys/file.h> header file. */
+/* Define if you have the <sys/file.h> header file. */
#undef HAVE_SYS_FILE_H
-/* Define if you have the <sys/filio.h> header file. */
+/* Define if you have the <sys/filio.h> header file. */
#undef HAVE_SYS_FILIO_H
-/* Define if you have the <sys/ioctl.h> header file. */
+/* Define if you have the <sys/ioctl.h> header file. */
#undef HAVE_SYS_IOCTL_H
-/* Define if you have the <sys/msgbuf.h> header file. */
+/* Define if you have the <sys/msgbuf.h> header file. */
#undef HAVE_SYS_MSGBUF_H
-/* Define if you have the <sys/select.h> header file. */
+/* Define if you have the <sys/select.h> header file. */
#undef HAVE_SYS_SELECT_H
-/* Define if you have the <sys/time.h> header file. */
+/* Define if you have the <sys/time.h> header file. */
#undef HAVE_SYS_TIME_H
-/* Define if you have the <sys/utsname.h> header file. */
+/* Define if you have the <sys/utsname.h> header file. */
#undef HAVE_SYS_UTSNAME_H
-/* Define if you have the <termios.h> header file. */
+/* Define if you have <sys/wait.h> that is POSIX.1 compatible. */
+#undef HAVE_SYS_WAIT_H
+
+/* Define if you have the <termios.h> header file. */
#undef HAVE_TERMIOS_H
-/* Define if you have the <unistd.h> header file. */
+/* Define if you have the <unistd.h> header file. */
#undef HAVE_UNISTD_H
-/* Define if you have the 44bsd library (-l44bsd). */
-#undef HAVE_LIB44BSD
+/* Define if you have the `vprintf' function. */
+#undef HAVE_VPRINTF
-/* Define if you have the dl library (-ldl). */
-#undef HAVE_LIBDL
+/* Define if you have the `waitpid' function. */
+#undef HAVE_WAITPID
-/* Define if you have the gen library (-lgen). */
-#undef HAVE_LIBGEN
+/* Define as the return type of signal handlers (`int' or `void'). */
+#undef RETSIGTYPE
-/* Define if you have the nsl library (-lnsl). */
-#undef HAVE_LIBNSL
+/* Define if the `setpgrp' function takes no argument. */
+#undef SETPGRP_VOID
-/* Define if you have the resolv library (-lresolv). */
-#undef HAVE_LIBRESOLV
+/* The size of a `int', as computed by sizeof. */
+#undef SIZEOF_INT
-/* Define if you have the socket library (-lsocket). */
-#undef HAVE_LIBSOCKET
+/* The size of a `long', as computed by sizeof. */
+#undef SIZEOF_LONG
-/* Define if you have the w library (-lw). */
-#undef HAVE_LIBW
+/* The size of a `short', as computed by sizeof. */
+#undef SIZEOF_SHORT
+
+/* Define if you have the ANSI C header files. */
+#undef STDC_HEADERS
+
+/* Define if the X Window System is missing or not being used. */
+#undef X_DISPLAY_MISSING
+
+/* Define if `lex' declares `yytext' as a `char *' by default, not a `char[]'.
+ */
+#undef YYTEXT_POINTER
+
+/* Define to `int' if <sys/types.h> doesn't define. */
+#undef gid_t
+
+/* Define to `int' if <sys/types.h> doesn't define. */
+#undef uid_t
#include <krb_err.h>
#endif
+#ifdef HAVE_KRB5
+#include <krb5.h>
+#endif
+
#ifdef HAVE_HESIOD
#include <hesiod.h>
#endif
#define Z_NOTICETIMELIMIT 30 /* Time to wait for fragments */
#define Z_INITFILTERSIZE 30 /* Starting size of uid filter */
+#define Z_AUTHMODE_NONE 0 /* no authentication */
+#define Z_AUTHMODE_KRB4 1 /* authenticate using Kerberos V4 */
+#define Z_AUTHMODE_KRB5 2 /* authenticate using Kerberos V5 */
+
+#define Z_KEYUSAGE_CLT_CKSUM 1027 /* client->server notice checksum */
+#define Z_KEYUSAGE_SRV_CKSUM 1029 /* server->client notice checksum */
+
struct _Z_Hole {
struct _Z_Hole *next;
int first;
extern int __HM_set; /* 0 if dest addr set, 1 otherwise */
extern int __Zephyr_server; /* 0 if normal client, 1 if server or zhm */
+#ifdef HAVE_KRB5
+extern krb5_context Z_krb5_ctx;
+Code_t Z_krb5_lookup_cksumtype(krb5_enctype, krb5_cksumtype *);
+#endif
+
extern ZLocations_t *__locate_list;
extern int __locate_num;
extern int __locate_next;
#define SERVER_SVCNAME "zephyr-clt"
#define SERVER_SERVICE "zephyr"
#define SERVER_INSTANCE "zephyr"
+#define SERVER_KRB5_SERVICE "zephyr"
#define ZVERSIONHDR "ZEPH"
#define ZVERSIONMAJOR 0
char *z_multinotice;
ZUnique_Id_t z_multiuid;
ZChecksum_t z_checksum;
+ char *z_ascii_checksum;
int z_num_other_fields;
char *z_other_fields[Z_MAXOTHERFIELDS];
caddr_t z_message;
/* Defines for ZFormatNotice, et al. */
typedef Code_t (*Z_AuthProc) ZP((ZNotice_t*, char *, int, int *));
Code_t ZMakeAuthentication ZP((ZNotice_t*, char *,int, int*));
+Code_t ZMakeZcodeAuthentication ZP((ZNotice_t*, char *,int, int*));
+Code_t ZMakeZcodeRealmAuthentication ZP((ZNotice_t*, char *,int, int*, char*));
char *ZGetSender ZP((void));
char *ZGetVariable ZP((char *));
Code_t ZMakeAscii16 ZP((char *, int, unsigned int));
Code_t ZReceivePacket ZP((ZPacket_t, int*, struct sockaddr_in*));
Code_t ZCheckAuthentication ZP((ZNotice_t*, struct sockaddr_in*));
+Code_t ZCheckZcodeAuthentication ZP((ZNotice_t*, struct sockaddr_in*));
+Code_t ZCheckZcodeRealmAuthentication ZP((ZNotice_t*, struct sockaddr_in*, char *realm));
Code_t ZInitLocationInfo ZP((char *hostname, char *tty));
Code_t ZSetLocation ZP((char *exposure));
Code_t ZUnsetLocation ZP((void));
#define SRV_TIMEOUT 30
#define ZAUTH (ZMakeAuthentication)
+#define ZCAUTH (ZMakeZcodeAuthentication)
#define ZNOAUTH ((Z_AuthProc)0)
/* Packet strings */
ZOpenPort.o ZParseNot.o ZPeekIfNot.o ZPeekNot.o ZPeekPkt.o ZPending.o \
ZReadAscii.o ZRecvNot.o ZRecvPkt.o ZRetSubs.o ZSendList.o ZSendNot.o \
ZSendPkt.o ZSendRaw.o ZSendRLst.o ZSetDest.o ZSetFD.o ZSetSrv.o \
- ZSubs.o ZVariables.o ZWait4Not.o Zinternal.o
+ ZSubs.o ZVariables.o ZWait4Not.o Zinternal.o ZMakeZcode.o \
+ ZReadZcode.o ZCkZAut.o
LIBEXT=a
all: libzephyr.$(LIBEXT)
#include <internal.h>
+#if defined(HAVE_KRB5) && !HAVE_KRB5_FREE_DATA
+#define krb5_free_data(ctx, dat) free((dat)->data)
+#endif
+
/* Check authentication of the notice.
If it looks authentic but fails the Kerberos check, return -1.
If it looks authentic and passes the Kerberos check, return 1.
return (ZERR_NONE);
}
+
+Code_t ZNewFormatNotice(notice, buffer, ret_len, cert_routine)
+ register ZNotice_t *notice;
+ char **buffer;
+ int *ret_len;
+ Z_AuthProc cert_routine;
+{
+ char header[Z_MAXHEADERLEN];
+ int hdrlen;
+ Code_t retval;
+
+ if ((retval = Z_NewFormatHeader(notice, header, sizeof(header), &hdrlen,
+ cert_routine)) != ZERR_NONE)
+ return (retval);
+
+ *ret_len = hdrlen+notice->z_message_len;
+
+ /* Length can never be zero, don't have to worry about malloc(0). */
+ if (!(*buffer = (char *) malloc((unsigned)*ret_len)))
+ return (ENOMEM);
+
+ (void) memcpy(*buffer, header, hdrlen);
+ (void) memcpy(*buffer+hdrlen, notice->z_message, notice->z_message_len);
+
+ return (ZERR_NONE);
+}
return (ZERR_NONE);
}
+
+Code_t ZNewFormatSmallRawNotice(notice, buffer, ret_len)
+ ZNotice_t *notice;
+ ZPacket_t buffer;
+ int *ret_len;
+{
+ Code_t retval;
+ int hdrlen;
+
+ if ((retval = Z_AsciiFormatRawHeader(notice, buffer, Z_MAXHEADERLEN,
+ &hdrlen, NULL, NULL, NULL, NULL))
+ != ZERR_NONE)
+ return (retval);
+
+ *ret_len = hdrlen+notice->z_message_len;
+
+ if (*ret_len > Z_MAXPKTLEN)
+ return (ZERR_PKTLEN);
+
+ (void) memcpy(buffer+hdrlen, notice->z_message, notice->z_message_len);
+
+ return (ZERR_NONE);
+}
#ifdef HAVE_KRB4
#include <krb_err.h>
#endif
+#ifdef HAVE_KRB5_ERR_H
+#include <krb5_err.h>
+#endif
#ifndef INADDR_NONE
#define INADDR_NONE 0xffffffff
initialize_krb_error_table();
#endif
+#ifdef HAVE_KRB5
+ initialize_krb5_error_table();
+#endif
initialize_zeph_error_table();
__Q_Tail = NULL;
__Q_Head = NULL;
+#ifdef HAVE_KRB5
+ if ((code = krb5_init_context(&Z_krb5_ctx)))
+ return(code);
+#endif
+
/* if the application is a server, there might not be a zhm. The
code will fall back to something which might not be "right",
but this is is ok, since none of the servers call krb_rd_req. */
#include <krb_err.h>
#endif
+#if defined(HAVE_KRB5) && !HAVE_KRB5_FREE_DATA
+#define krb5_free_data(ctx, dat) free((dat)->data)
+#endif
+
Code_t ZResetAuthentication () {
return ZERR_NONE;
}
return (Z_FormatRawHeader(notice, buffer, buffer_len, len, NULL, NULL));
#endif
}
+
+Code_t ZMakeZcodeAuthentication(notice, buffer, buffer_len, phdr_len)
+ register ZNotice_t *notice;
+ char *buffer;
+ int buffer_len;
+ int *phdr_len;
+{
+ return ZMakeZcodeRealmAuthentication(notice, buffer, buffer_len, phdr_len,
+ __Zephyr_realm);
+}
+
+Code_t ZMakeZcodeRealmAuthentication(notice, buffer, buffer_len, phdr_len,
+ realm)
+ register ZNotice_t *notice;
+ char *buffer;
+ int buffer_len;
+ int *phdr_len;
+ char *realm;
+{
+#ifdef HAVE_KRB5
+ krb5_error_code result;
+ krb5_ccache ccache;
+ krb5_creds creds_in, *creds;
+ krb5_keyblock *keyblock;
+ krb5_enctype enctype;
+ krb5_cksumtype cksumtype;
+ krb5_auth_context authctx;
+ krb5_data *authent;
+ krb5_data cksumbuf;
+#if HAVE_KRB5_C_MAKE_CHECKSUM
+ krb5_checksum checksum;
+#else
+ krb5_crypto cryptctx;
+ Checksum checksum;
+ size_t xlen;
+#endif
+ char *svcinst, *x, *y;
+ char *cksum_start, *cstart, *cend, *asn1_data;
+ int plain_len; /* length of part not to be checksummed */
+ int cksum_len; /* length of part to be checksummed (incl cksum) */
+ int cksum0_len; /* length of part before checksum */
+ int cksum1_len; /* length of part after checksum */
+ int i, zcode_len, asn1_len;
+
+ /* Get a pointer to the default ccache. We don't need to free this. */
+ result = krb5_cc_default(Z_krb5_ctx, &ccache);
+ if (result)
+ return result;
+
+ /* GRRR. There's no allocator or constructor for krb5_creds */
+ /* GRRR. It would be nice if this API were documented at all */
+ memset(&creds_in, 0, sizeof(creds_in));
+
+ result = krb5_cc_get_principal(Z_krb5_ctx, ccache, &creds_in.client);
+ if (result) {
+ krb5_cc_close(Z_krb5_ctx, ccache);
+ return(result);
+ }
+
+ /* construct the service principal */
+ result = krb5_build_principal(Z_krb5_ctx, &creds_in.server,
+ strlen(realm),
+ realm,
+ SERVER_KRB5_SERVICE, SERVER_INSTANCE, 0);
+ if (result) {
+ krb5_free_cred_contents(Z_krb5_ctx, &creds_in); /* hope this is OK */
+ krb5_cc_close(Z_krb5_ctx, ccache);
+ return result;
+ }
+ /* HOLDING: creds_in.server, ccache */
+
+ /* look up or get the credentials we need */
+ result = krb5_get_credentials(Z_krb5_ctx, 0 /* flags */, ccache,
+ &creds_in, &creds);
+ krb5_cc_close(Z_krb5_ctx, ccache);
+ krb5_free_cred_contents(Z_krb5_ctx, &creds_in); /* hope this is OK */
+ if (result)
+ return result;
+ /* HOLDING: creds */
+
+ /* Figure out what checksum type to use */
+#if HAVE_KRB5_CREDS_KEYBLOCK_ENCTYPE
+ keyblock = &creds->keyblock;
+ enctype = keyblock->enctype;
+
+ result = Z_krb5_lookup_cksumtype(enctype, &cksumtype);
+ if (result) {
+ krb5_free_creds(Z_krb5_ctx, creds);
+ return result;
+ }
+#else
+ keyblock = &creds->session;
+ {
+ unsigned int len;
+ ENCTYPE *val;
+ int i = 0;
+
+ result = krb5_keytype_to_enctypes(Z_krb5_ctx, keyblock->keytype,
+ &len, &val);
+ if (result) {
+ krb5_free_creds(Z_krb5_ctx, creds);
+ return result;
+ }
+
+ do {
+ if (i == len) break;
+ result = Z_krb5_lookup_cksumtype(val[i], &cksumtype);
+ i++;
+ } while (result != 0);
+
+ if (result) {
+ krb5_free_creds(Z_krb5_ctx, creds);
+ return result;
+ }
+ enctype = val[i-1];
+ }
+#endif
+ /* HOLDING: creds */
+
+ /* Create the authenticator */
+ result = krb5_auth_con_init(Z_krb5_ctx, &authctx);
+ if (result) {
+ krb5_free_creds(Z_krb5_ctx, creds);
+ return (result);
+ }
+
+ authent = (krb5_data *)malloc(sizeof(krb5_data));
+
+ /* HOLDING: creds, authctx */
+ result = krb5_mk_req_extended(Z_krb5_ctx, &authctx, 0 /* options */,
+ 0 /* in_data */, creds, authent);
+ krb5_auth_con_free(Z_krb5_ctx, authctx);
+ if (result) {
+ krb5_free_creds(Z_krb5_ctx, creds);
+ return (result);
+ }
+ /* HOLDING: creds, authent */
+
+ /* Encode the authenticator */
+ notice->z_auth = 1;
+ notice->z_authent_len = authent->length;
+ zcode_len = authent->length * 2 + 2; /* 2x growth plus Z and null */
+ notice->z_ascii_authent = (char *)malloc(zcode_len);
+ if (!notice->z_ascii_authent) {
+ krb5_free_data(Z_krb5_ctx, authent);
+ krb5_free_creds(Z_krb5_ctx, creds);
+ return (ENOMEM);
+ }
+ /* HOLDING: creds, authent, notice->z_ascii_authent */
+ result = ZMakeZcode(notice->z_ascii_authent, zcode_len,
+ authent->data, authent->length);
+ krb5_free_data(Z_krb5_ctx, authent);
+ if (result) {
+ free(notice->z_ascii_authent);
+ krb5_free_creds(Z_krb5_ctx, creds);
+ return (result);
+ }
+ /* HOLDING: creds, notice->z_ascii_authent */
+
+ /* format the notice header, with a zero checksum */
+ result = Z_NewFormatRawHeader(notice, buffer, buffer_len, phdr_len,
+ &cksum_start, &cksum_len, &cstart, &cend);
+ free(notice->z_ascii_authent);
+ notice->z_authent_len = 0;
+ if (result) {
+ krb5_free_creds(Z_krb5_ctx, creds);
+ return (result);
+ }
+ /* HOLDING: creds */
+
+ /* Assemble the things to be checksummed */
+ plain_len = cksum_start - buffer;
+ cksum0_len = cstart - cksum_start;
+ cksum1_len = (cksum_start + cksum_len) - cend;
+ memset(&cksumbuf, 0, sizeof(cksumbuf));
+ cksumbuf.length = cksum0_len + cksum1_len + notice->z_message_len;
+ cksumbuf.data = malloc(cksumbuf.length);
+ if (!cksumbuf.data) {
+ krb5_free_creds(Z_krb5_ctx, creds);
+ return (ENOMEM);
+ }
+ /* HOLDING: creds, cksumbuf.data */
+ memcpy(cksumbuf.data, cksum_start, cksum0_len);
+ memcpy(cksumbuf.data + cksum0_len, cend, cksum1_len);
+ memcpy(cksumbuf.data + cksum0_len + cksum1_len,
+ notice->z_message, notice->z_message_len);
+
+#if HAVE_KRB5_C_MAKE_CHECKSUM
+ /* Create the checksum -- MIT crypto API */
+ result = krb5_c_make_checksum(Z_krb5_ctx, cksumtype,
+ keyblock, Z_KEYUSAGE_CLT_CKSUM,
+ &cksumbuf, &checksum);
+ krb5_free_creds(Z_krb5_ctx, creds);
+ if (result) {
+ free(cksumbuf.data);
+ return result;
+ }
+ /* HOLDING: cksumbuf.data, checksum */
+
+ asn1_data = checksum.contents;
+ asn1_len = checksum.length;
+#else
+ /* Create the checksum -- heimdal crypto API */
+ result = krb5_crypto_init(Z_krb5_ctx, keyblock, enctype, &cryptctx);
+ krb5_free_creds(Z_krb5_ctx, creds);
+ if (result) {
+ free(cksumbuf.data);
+ return result;
+ }
+ /* HOLDING: cksumbuf.data, cryptctx */
+ result = krb5_create_checksum(Z_krb5_ctx, cryptctx,
+ Z_KEYUSAGE_CLT_CKSUM, cksumtype,
+ cksumbuf.data, cksumbuf.length,
+ &checksum);
+ krb5_crypto_destroy(Z_krb5_ctx, cryptctx);
+ if (result) {
+ free(cksumbuf.data);
+ return result;
+ }
+ asn1_len = checksum.checksum.length;
+ asn1_data = checksum.checksum.data;
+ /* HOLDING: cksumbuf.data, checksum */
+#endif
+
+ /*
+ * OK.... we can zcode to a space starting at 'cstart',
+ * with a length of buffer_len - (plain_len + cksum_len).
+ * Then we tack on the end part, which is located at
+ * cksumbuf.data + cksum0_len and has length cksum1_len
+ */
+ result = ZMakeZcode(cstart, buffer_len - (plain_len + cksum_len),
+ asn1_data, asn1_len);
+ if (!result) {
+ zcode_len = strlen(cstart) + 1;
+ memcpy(cstart + zcode_len, cksumbuf.data + cksum0_len, cksum1_len);
+ *phdr_len -= cksum_len - (cksum0_len + cksum1_len);
+ *phdr_len += zcode_len;
+ }
+
+ /* free stuff up, and then return the result from the last call */
+
+ free(cksumbuf.data);
+#if HAVE_KRB5_C_MAKE_CHECKSUM
+ krb5_free_checksum_contents(Z_krb5_ctx, &checksum);
+#else
+ free_Checksum(&checksum);
+#endif
+ return (result);
+#endif /* HAVE_KRB5 */
+}
else
notice->z_default_format = "";
- if (ZReadAscii32(ptr, end-ptr, &temp) == ZERR_BADFIELD)
- BAD_PACKET;
- notice->z_checksum = temp;
- numfields--;
- ptr = next_field(ptr, end);
+ if (numfields && ptr < end) {
+ notice->z_ascii_checksum = ptr;
+
+#ifdef xZCODE_K4SUM
+ if (ZReadZcode32(ptr, end-ptr, &temp) == ZERR_BADFIELD)
+#else
+ if (ZReadAscii32(ptr, end-ptr, &temp) == ZERR_BADFIELD)
+#endif
+ notice->z_checksum = 0;
+ else
+ notice->z_checksum = temp;
+
+ numfields--;
+ ptr = next_field (ptr, end);
+ }
+ else
+ {
+ notice->z_ascii_checksum = "";
+ notice->z_checksum = 0;
+ }
if (numfields && ptr < end) {
notice->z_multinotice = ptr;
int __subscriptions_next;
int Z_discarded_packets = 0;
+#ifdef HAVE_KRB5
+/* This context is used throughout */
+krb5_context Z_krb5_ctx;
+
+static struct cksum_map_s {
+ krb5_enctype e;
+ krb5_cksumtype c;
+} cksum_map[] = {
+ /* per RFC1510 and draft-ietf-krb-wg-crypto-02.txt */
+ { ENCTYPE_NULL, CKSUMTYPE_RSA_MD5 },
+ { ENCTYPE_DES_CBC_CRC, CKSUMTYPE_RSA_MD5_DES },
+ { ENCTYPE_DES_CBC_MD4, CKSUMTYPE_RSA_MD4_DES },
+ { ENCTYPE_DES_CBC_MD5, CKSUMTYPE_RSA_MD5_DES },
+
+ /*
+ * The implementors hate us, and are inconsistent with names for
+ * most things defined after RFC1510. Note that des3-cbc-sha1
+ * and des3-cbc-sha1-kd are listed by number to avoid confusion
+ * caused by inconsistency between the names used in the specs
+ * and those used by implementations.
+ * -- jhutz, 30-Nov-2002
+ */
+
+ /* source lost in history (an expired internet-draft) */
+ { 5 /* des3-cbc-md5 */, 9 /* rsa-md5-des3 */ },
+ { 7 /* des3-cbc-sha1 */, 12 /* hmac-sha1-des3 */ },
+
+ /* per draft-ietf-krb-wg-crypto-02.txt */
+ { 16 /* des3-cbc-sha1-kd */, 12 /* hmac-sha1-des3-kd */ },
+
+ /* per draft-raeburn-krb-rijndael-krb-02.txt */
+ { 17 /* aes128-cts-hmac-sha1-96 */, 10 /* hmac-sha1-96-aes128 */ },
+ { 18 /* aes256-cts-hmac-sha1-96 */, 11 /* hmac-sha1-96-aes256 */ },
+
+ /* per draft-brezak-win2k-krb-rc4-hmac-04.txt */
+ { 23 /* rc4-hmac */, -138 /* hmac-md5 */ },
+ { 24 /* rc4-hmac-exp */, -138 /* hmac-md5 */ },
+};
+#define N_CKSUM_MAP (sizeof(cksum_map) / sizeof(struct cksum_map_s))
+
+Code_t Z_krb5_lookup_cksumtype(krb5_enctype e, krb5_cksumtype *c)
+{
+ int i;
+
+ for (i = 0; i < N_CKSUM_MAP; i++) {
+ if (cksum_map[i].e == e) {
+ *c = cksum_map[i].c;
+ return ZERR_NONE;
+ }
+ }
+ return KRB5_PROG_ETYPE_NOSUPP;
+}
+#endif /* HAVE_KRB5 */
+
#ifdef HAVE_KRB4
C_Block __Zephyr_session;
#endif
return Z_FormatAuthHeader(notice, buffer, buffer_len, len, cert_routine);
}
+Code_t Z_NewFormatHeader(notice, buffer, buffer_len, len, cert_routine)
+ ZNotice_t *notice;
+ char *buffer;
+ int buffer_len;
+ int *len;
+ Z_AuthProc cert_routine;
+{
+ Code_t retval;
+ static char version[BUFSIZ]; /* default init should be all \0 */
+ struct sockaddr_in name;
+ int namelen = sizeof(name);
+
+ if (!notice->z_sender)
+ notice->z_sender = ZGetSender();
+
+ if (notice->z_port == 0) {
+ if (ZGetFD() < 0) {
+ retval = ZOpenPort((u_short *)0);
+ if (retval != ZERR_NONE)
+ return (retval);
+ }
+ retval = getsockname(ZGetFD(), (struct sockaddr *) &name, &namelen);
+ if (retval != 0)
+ return (retval);
+ notice->z_port = name.sin_port;
+ }
+
+ notice->z_multinotice = "";
+
+ (void) gettimeofday(¬ice->z_uid.tv, (struct timezone *)0);
+ notice->z_uid.tv.tv_sec = htonl((u_long) notice->z_uid.tv.tv_sec);
+ notice->z_uid.tv.tv_usec = htonl((u_long) notice->z_uid.tv.tv_usec);
+
+ (void) memcpy(¬ice->z_uid.zuid_addr, &__My_addr, sizeof(__My_addr));
+
+ notice->z_multiuid = notice->z_uid;
+
+ if (!version[0])
+ (void) sprintf(version, "%s%d.%d", ZVERSIONHDR, ZVERSIONMAJOR,
+ ZVERSIONMINOR);
+ notice->z_version = version;
+
+ return Z_NewFormatAuthHeader(notice, buffer, buffer_len, len, cert_routine);
+}
+
Code_t Z_FormatAuthHeader(notice, buffer, buffer_len, len, cert_routine)
ZNotice_t *notice;
char *buffer;
return ((*cert_routine)(notice, buffer, buffer_len, len));
}
+Code_t Z_NewFormatAuthHeader(notice, buffer, buffer_len, len, cert_routine)
+ ZNotice_t *notice;
+ char *buffer;
+ int buffer_len;
+ int *len;
+ Z_AuthProc cert_routine;
+{
+ if (!cert_routine) {
+ notice->z_auth = 0;
+ notice->z_authent_len = 0;
+ notice->z_ascii_authent = "";
+ notice->z_checksum = 0;
+ return (Z_FormatRawHeader(notice, buffer, buffer_len,
+ len, NULL, NULL));
+ }
+
+ return ((*cert_routine)(notice, buffer, buffer_len, len));
+}
+
+Code_t Z_NewFormatRawHeader(notice, buffer, buffer_len, hdr_len,
+ cksum_start, cksum_len, cstart, cend)
+ ZNotice_t *notice;
+ char *buffer;
+ int buffer_len;
+ int *hdr_len;
+ char **cksum_start;
+ int *cksum_len;
+ char **cstart, **cend;
+{
+ return(Z_ZcodeFormatRawHeader(notice, buffer, buffer_len, hdr_len,
+ cksum_start, cksum_len, cstart, cend, 0));
+}
+
+Code_t Z_AsciiFormatRawHeader(notice, buffer, buffer_len, hdr_len,
+ cksum_start, cksum_len, cstart, cend)
+ ZNotice_t *notice;
+ char *buffer;
+ int buffer_len;
+ int *hdr_len;
+ char **cksum_start;
+ int *cksum_len;
+ char **cstart, **cend;
+{
+ return(Z_ZcodeFormatRawHeader(notice, buffer, buffer_len, hdr_len,
+ cksum_start, cksum_len, cstart, cend, 1));
+}
+
+Code_t Z_ZcodeFormatRawHeader(notice, buffer, buffer_len, hdr_len, cksum_start,
+ cksum_len, cstart, cend, cksumstyle)
+ ZNotice_t *notice;
+ char *buffer;
+ int buffer_len;
+ int *hdr_len;
+ char **cksum_start;
+ int *cksum_len;
+ char **cstart, **cend;
+ int cksumstyle;
+{
+ static char version_nogalaxy[BUFSIZ]; /* default init should be all \0 */
+ char newrecip[BUFSIZ];
+ char *ptr, *end;
+ int i;
+
+ if (!notice->z_class)
+ notice->z_class = "";
+
+ if (!notice->z_class_inst)
+ notice->z_class_inst = "";
+
+ if (!notice->z_opcode)
+ notice->z_opcode = "";
+
+ if (!notice->z_recipient)
+ notice->z_recipient = "";
+
+ if (!notice->z_default_format)
+ notice->z_default_format = "";
+
+ ptr = buffer;
+ end = buffer+buffer_len;
+
+ if (cksum_start)
+ *cksum_start = ptr;
+
+ (void) sprintf(version_nogalaxy, "%s%d.%d", ZVERSIONHDR,
+ ZVERSIONMAJOR, ZVERSIONMINOR);
+
+ notice->z_version = version_nogalaxy;
+
+ if (Z_AddField(&ptr, version_nogalaxy, end))
+ return (ZERR_HEADERLEN);
+
+ if (ZMakeAscii32(ptr, end-ptr,
+ Z_NUMFIELDS + notice->z_num_other_fields)
+ == ZERR_FIELDLEN)
+ return (ZERR_HEADERLEN);
+ ptr += strlen(ptr)+1;
+
+ if (ZMakeAscii32(ptr, end-ptr, notice->z_kind) == ZERR_FIELDLEN)
+ return (ZERR_HEADERLEN);
+ ptr += strlen(ptr)+1;
+
+ if (ZMakeAscii(ptr, end-ptr, (unsigned char *)¬ice->z_uid,
+ sizeof(ZUnique_Id_t)) == ZERR_FIELDLEN)
+ return (ZERR_HEADERLEN);
+ ptr += strlen(ptr)+1;
+
+ if (ZMakeAscii16(ptr, end-ptr, ntohs(notice->z_port)) == ZERR_FIELDLEN)
+ return (ZERR_HEADERLEN);
+ ptr += strlen(ptr)+1;
+
+ if (ZMakeAscii32(ptr, end-ptr, notice->z_auth) == ZERR_FIELDLEN)
+ return (ZERR_HEADERLEN);
+ ptr += strlen(ptr)+1;
+
+ if (ZMakeAscii32(ptr, end-ptr, notice->z_authent_len) == ZERR_FIELDLEN)
+ return (ZERR_HEADERLEN);
+ ptr += strlen(ptr)+1;
+
+ if (Z_AddField(&ptr, notice->z_ascii_authent, end))
+ return (ZERR_HEADERLEN);
+ if (Z_AddField(&ptr, notice->z_class, end))
+ return (ZERR_HEADERLEN);
+ if (Z_AddField(&ptr, notice->z_class_inst, end))
+ return (ZERR_HEADERLEN);
+ if (Z_AddField(&ptr, notice->z_opcode, end))
+ return (ZERR_HEADERLEN);
+ if (Z_AddField(&ptr, notice->z_sender, end))
+ return (ZERR_HEADERLEN);
+ if (strchr(notice->z_recipient, '@') || !*notice->z_recipient) {
+ if (Z_AddField(&ptr, notice->z_recipient, end))
+ return (ZERR_HEADERLEN);
+ }
+ else {
+ if (strlen(notice->z_recipient) + strlen(__Zephyr_realm) + 2 >
+ sizeof(newrecip))
+ return (ZERR_HEADERLEN);
+ (void) sprintf(newrecip, "%s@%s", notice->z_recipient, __Zephyr_realm);
+ if (Z_AddField(&ptr, newrecip, end))
+ return (ZERR_HEADERLEN);
+ }
+ if (Z_AddField(&ptr, notice->z_default_format, end))
+ return (ZERR_HEADERLEN);
+
+ /* copy back the end pointer location for crypto checksum */
+ if (cstart)
+ *cstart = ptr;
+ if (cksumstyle == 1) {
+ if (Z_AddField(&ptr, notice->z_ascii_checksum, end))
+ return (ZERR_HEADERLEN);
+ } else {
+#ifdef xZCODE_K4SUM
+ if (ZMakeZcode32(ptr, end-ptr, notice->z_checksum) == ZERR_FIELDLEN)
+ return ZERR_HEADERLEN;
+#else
+ if (ZMakeAscii32(ptr, end-ptr, notice->z_checksum) == ZERR_FIELDLEN)
+ return (ZERR_HEADERLEN);
+#endif
+ ptr += strlen(ptr)+1;
+ }
+ if (cend)
+ *cend = ptr;
+
+ if (Z_AddField(&ptr, notice->z_multinotice, end))
+ return (ZERR_HEADERLEN);
+
+ if (ZMakeAscii(ptr, end-ptr, (unsigned char *)¬ice->z_multiuid,
+ sizeof(ZUnique_Id_t)) == ZERR_FIELDLEN)
+ return (ZERR_HEADERLEN);
+ ptr += strlen(ptr)+1;
+
+ for (i=0;i<notice->z_num_other_fields;i++)
+ if (Z_AddField(&ptr, notice->z_other_fields[i], end))
+ return (ZERR_HEADERLEN);
+
+ if (cksum_len)
+ *cksum_len = ptr-*cksum_start;
+
+ *hdr_len = ptr-buffer;
+
+#if 0
+ {
+ printf("Z_FormatRawHeader output:\n");
+ for (i = 0; i < *hdr_len; i += 16) {
+ int i2;
+ printf("%03d:", i);
+ for (i2 = i; i2 < i+16 && i2 < *hdr_len; i2++)
+ printf(" %02x", buffer[i2] & 0xff);
+ for (; i2 < i+16; i2++)
+ printf(" ");
+ printf(" ");
+ for (i2 = i; i2 < i+16 && i2 < *hdr_len; i2++)
+ printf("%c",
+ ((buffer[i2] > 0 && buffer[i2] < 127 && isprint(buffer[i2]))
+ ? buffer[i2]
+ : '.'));
+ printf("\n");
+ }
+ }
+#endif
+
+ return (ZERR_NONE);
+}
+
Code_t Z_FormatRawHeader(notice, buffer, buffer_len, len, cstart, cend)
ZNotice_t *notice;
char *buffer;
LIBS=-lzephyr @LIBS@ -lcom_err
OBJS= zsrv_err.o access.o acl_files.o bdump.o class.o client.o common.o \
- dispatch.o kopt.o kstuff.o main.o server.o subscr.o timer.o uloc.o \
+ dispatch.o kstuff.o main.o server.o subscr.o timer.o uloc.o \
zstring.o realm.o version.o
all: zephyrd
static void shutdown_file_pointers __P((void));
static void cleanup __P((Server *server));
+#ifdef HAVE_KRB5
+static long ticket5_time;
+#define TKT5LIFETIME 8*60*60
+#define tkt5_lifetime(val) (val)
+#endif
+
#ifdef HAVE_KRB4
static long ticket_time;
krb_get_err_text(retval));
return 1;
}
+#if 0
s = (Sched *) check_key_sched_cache(serv_key);
if (s) {
serv_ksched = *s;
des_key_sched(serv_key, serv_ksched.s);
add_to_key_sched_cache(serv_key, &serv_ksched);
}
+#else
+ des_key_sched(serv_key, serv_ksched.s);
+#endif
#endif /* !NOENCRYPTION */
}
+#ifdef HAVE_KRB5
+ /* XXX */
+ if (ticket5_time < NOW - tkt5_lifetime(TKT5LIFETIME) + (15L * 60L)) {
+ krb5_keytab kt;
+ krb5_get_init_creds_opt opt;
+ krb5_creds cred;
+ krb5_principal principal;
+
+ memset(&cred, 0, sizeof(cred));
+
+ retval = krb5_build_principal(Z_krb5_ctx, &principal,
+ strlen(ZGetRealm()),
+ ZGetRealm(),
+ SERVER_KRB5_SERVICE, SERVER_INSTANCE,
+ 0);
+ if (retval) {
+ krb5_free_principal(Z_krb5_ctx, principal);
+ return(1);
+ }
+
+ krb5_get_init_creds_opt_init (&opt);
+ krb5_get_init_creds_opt_set_tkt_life (&opt, TKT5LIFETIME);
+
+ retval = krb5_kt_resolve(Z_krb5_ctx, keytab_file, &kt);
+ if (retval) return(1);
+
+ retval = krb5_get_init_creds_keytab (Z_krb5_ctx,
+ &cred,
+ principal,
+ kt,
+ 0,
+ NULL,
+ &opt);
+ krb5_free_principal(Z_krb5_ctx, principal);
+ krb5_kt_close(Z_krb5_ctx, kt);
+ if (retval) return(1);
+
+ retval = krb5_cc_initialize (Z_krb5_ctx, Z_krb5_ccache, cred.client);
+ if (retval) return(1);
+
+ retval = krb5_cc_store_cred (Z_krb5_ctx, Z_krb5_ccache, &cred);
+ if (retval) return(1);
+
+ ticket5_time = NOW;
+
+ krb5_free_cred_contents (Z_krb5_ctx, &cred);
+ }
+#endif
return(0);
}
#endif /* HAVE_KRB4 */
char *cp;
C_Block cblock;
#endif /* HAVE_KRB4 */
- Realm *realm = NULL;
+ ZRealm *realm = NULL;
#if 1
zdbug((LOG_DEBUG, "bdump recv loop"));
errno = 0;
cc = fread(buf, 1, len, f);
if (cc == 0)
+ {
+ if (feof(f))
+ return len2;
+ if (errno == 0)
+ errno = EIO;
return -1;
+ }
buf += cc;
len2 += cc;
len -= cc;
static Triplet *triplet_bucket[HASHSIZE]; /* the hash table of pointers */
static Code_t remove_client __P((Triplet *triplet, Client *client,
- Realm *realm));
+ ZRealm *realm));
static Code_t insert_client __P((Triplet *triplet, Client *client,
- Realm *realm));
+ ZRealm *realm));
static Triplet *triplet_alloc __P((String *classname, String *inst,
String *recipient));
static void free_triplet __P((Triplet *));
triplet_register(client, dest, realm)
Client *client;
Destination *dest;
- Realm *realm;
+ ZRealm *realm;
{
Triplet *triplet;
unsigned long hashval;
triplet_deregister(client, dest, realm)
Client *client;
Destination *dest;
- Realm *realm;
+ ZRealm *realm;
{
Triplet *triplet;
int retval;
insert_client(triplet, client, realm)
Triplet *triplet;
Client *client;
- Realm *realm;
+ ZRealm *realm;
{
Client **clientp, **newclients;
int new_size;
static Code_t remove_client(triplet, client, realm)
Triplet *triplet;
Client *client;
- Realm *realm;
+ ZRealm *realm;
{
Client **clientp;
int authentic; /* authentic flag */
Pending *pending; /* pending packet */
int from_server; /* packet is from another server */
- Realm *realm; /* foreign realm ptr */
+ ZRealm *realm; /* foreign realm ptr */
#ifdef DEBUG
static int first_time = 1;
#endif
} else {
if (realm = realm_which_realm(&input_sin)) {
authentic = ZCheckRealmAuthentication(&new_notice,
- &input_sin,
- realm->name);
+ &input_sin,
+ realm->name);
} else
authentic = ZCheckAuthentication(&new_notice, &input_sin);
}
}
}
+#if 0
if (whoisit.sin_port != hm_port && whoisit.sin_port != hm_srv_port &&
strcasecmp(new_notice.z_class, ZEPHYR_ADMIN_CLASS) != 0 &&
whoisit.sin_port != srv_addr.sin_port &&
ntohs(whoisit.sin_port));
return;
}
+#endif
message_notices.val++;
dispatch(&new_notice, authentic, &whoisit, from_server);
String *notice_class;
struct sockaddr_in who2;
int authflag;
- Realm *realm;
+ ZRealm *realm;
char *cp;
#ifdef DEBUG
char dbg_buf[BUFSIZ];
class = make_string(notice->z_class, 1);
if (realm_bound_for_realm(ZGetRealm(), notice->z_recipient)) {
- Realm *rlm;
+ ZRealm *rlm;
acl = class_get_acl(class);
if (acl != NULL) {
Client *client;
Code_t retval;
int wantdefs;
- Realm *realm;
+ ZRealm *realm;
struct sockaddr_in newwho;
/*
* krb_rd_req().
*/
+#if 0
int
krb_set_key(key,cvt)
char *key;
return ret;
#endif /* NOENCRYPTION */
}
-
+#endif
/*
* krb_rd_req() takes an AUTH_MSG_APPL_REQUEST or
KTEXT_ST req_id_st; /* Temp storage for authenticator */
KTEXT req_id = &req_id_st;
- char realm[REALM_SZ]; /* Realm of issuing kerberos */
+ char realm[REALM_SZ]; /* ZRealm of issuing kerberos */
Sched seskey_sched, *sched; /* Key sched for session key */
unsigned char skey[KKEY_SZ]; /* Session key from ticket */
char sname[SNAME_SZ]; /* Service name from ticket */
if (strcmp(ad->pinst,r_inst) != 0)
return RD_AP_INCON;
if (krb_ap_req_debug)
- krb_log("Realm: %s %s", ad->prealm, r_realm);
+ krb_log("ZRealm: %s %s", ad->prealm, r_realm);
if (strcmp(ad->prealm,r_realm) != 0)
return RD_AP_INCON;
struct sockaddr_in *from;
char *realm;
{
-#ifdef HAVE_KRB4
- int result;
- char rlmprincipal[ANAME_SZ+INST_SZ+REALM_SZ+4];
- char srcprincipal[ANAME_SZ+INST_SZ+REALM_SZ+4];
- KTEXT_ST authent, ticket;
- AUTH_DAT dat;
- ZChecksum_t checksum;
- CREDENTIALS cred;
- C_Block session_key;
+#ifdef HAVE_KRB5
+ char *authbuf;
+ char rlmprincipal[ANAME_SZ+INST_SZ+REALM_SZ+4+1024];
+ krb5_principal princ;
+ krb5_data packet;
+ krb5_ticket *tkt;
+ char *name;
+ krb5_error_code result;
+ krb5_principal server;
+ krb5_keytab keytabid = 0;
+ krb5_auth_context authctx;
+ krb5_keyblock *keyblock;
+ krb5_enctype enctype;
+ krb5_cksumtype cksumtype;
+ krb5_data cksumbuf;
+#if HAVE_KRB5_C_MAKE_CHECKSUM
+ krb5_checksum checksum;
+ krb5_boolean valid;
+#else
+ krb5_crypto cryptctx;
+ Checksum checksum;
+ size_t xlen;
+#endif
+ char *cksum0_base, *cksum1_base, *cksum2_base;
+ char *svcinst, *x, *y;
+ char *asn1_data, *key_data;
+ int asn1_len, key_len, cksum0_len, cksum1_len, cksum2_len;
+#ifdef KRB5_AUTH_CON_GETAUTHENTICATOR_TAKES_DOUBLE_POINTER
+ krb5_authenticator *authenticator;
+#define KRB5AUTHENT authenticator
+#else
+ krb5_authenticator authenticator;
+#define KRB5AUTHENT &authenticator
+#endif
+ int len;
if (!notice->z_auth)
return ZAUTH_NO;
if (notice->z_authent_len <= 0)
return ZAUTH_FAILED;
+ len = strlen(notice->z_ascii_authent)+1;
+ authbuf=malloc(len);
+
/* Read in the authentication data. */
- if (ZReadAscii(notice->z_ascii_authent,
- strlen(notice->z_ascii_authent)+1,
- (unsigned char *)authent.dat,
- notice->z_authent_len) == ZERR_BADFIELD) {
+ if (ZReadZcode(notice->z_ascii_authent,
+ authbuf,
+ len, &len) == ZERR_BADFIELD) {
return ZAUTH_FAILED;
}
- authent.length = notice->z_authent_len;
-
- /* Copy the ticket out of the authentication data. */
- if (krb_find_ticket(&authent, &ticket) != RD_AP_OK)
- return ZAUTH_FAILED;
- (void) sprintf(rlmprincipal, "%s.%s@%s", SERVER_SERVICE,
+ (void) sprintf(rlmprincipal, "%s/%s@%s", SERVER_SERVICE,
SERVER_INSTANCE, realm);
- /* Try to do a fast check against the cryptographic checksum. */
- if (find_session_key(&ticket, session_key, srcprincipal) >= 0) {
- if (strcmp(srcprincipal, rlmprincipal) != 0)
- return ZAUTH_FAILED;
- if (notice->z_time.tv_sec - NOW > CLOCK_SKEW)
- return ZAUTH_FAILED;
- checksum = compute_rlm_checksum(notice, session_key);
+ packet.length = len;
+ packet.data = authbuf;
- /* If checksum matches, packet is authentic. If not, we might
- * have an outdated session key, so keep going the slow way.
- */
- if (checksum == notice->z_checksum) {
- (void) memcpy((char *)__Zephyr_session, (char *)session_key,
- sizeof(C_Block)); /* For control_dispatch() */
- return ZAUTH_YES;
- }
-
- /* Try again. This way we can switch to the same checksums
- * that the rest of Zephyr uses at a future date, but for now
- * we need to be compatible */
- checksum = compute_checksum(notice, session_key);
- if (checksum == notice->z_checksum) {
- memcpy(__Zephyr_session, session_key, sizeof(C_Block));
- return ZAUTH_YES;
- }
+ result = krb5_kt_resolve(Z_krb5_ctx,
+ keytab_file, &keytabid);
+ if (result) {
+ free(authbuf);
+ return (result);
}
- /* We don't have the session key cached; do it the long way. */
- result = krb_rd_req(&authent, SERVER_SERVICE, SERVER_INSTANCE,
- from->sin_addr.s_addr, &dat, srvtab_file);
- if (result == RD_AP_OK) {
- sprintf(srcprincipal, "%s%s%s@%s", dat.pname, dat.pinst[0] ? "." : "",
- dat.pinst, dat.prealm);
- if (strcmp(rlmprincipal, srcprincipal))
- return ZAUTH_FAILED;
- } else {
- return ZAUTH_FAILED; /* didn't decode correctly */
+ /* HOLDING: authbuf, keytabid */
+ /* Create the auth context */
+ result = krb5_auth_con_init(Z_krb5_ctx, &authctx);
+ if (result) {
+ krb5_kt_close(Z_krb5_ctx, keytabid);
+ free(authbuf);
+ return (result);
}
- /* Check the cryptographic checksum. */
-#ifdef NOENCRYPTION
- checksum = 0;
+ /* HOLDING: authbuf, authctx */
+ result = krb5_build_principal(Z_krb5_ctx, &server, strlen(__Zephyr_realm),
+ __Zephyr_realm, SERVER_SERVICE,
+ SERVER_INSTANCE, NULL);
+ if (!result) {
+ result = krb5_rd_req(Z_krb5_ctx, &authctx, &packet, server,
+ keytabid, 0, &tkt);
+ krb5_free_principal(Z_krb5_ctx, server);
+ }
+ krb5_kt_close(Z_krb5_ctx, keytabid);
+
+ if (result) {
+ if (result == KRB5KRB_AP_ERR_REPEAT)
+ syslog(LOG_DEBUG, "k5 auth failed: %s", error_message(result));
+ else
+ syslog(LOG_WARNING,"k5 auth failed: %s", error_message(result));
+ free(authbuf);
+ krb5_auth_con_free(Z_krb5_ctx, authctx);
+ return ZAUTH_FAILED;
+ }
+
+ /* HOLDING: authbuf, authctx */
+#ifndef HAVE_KRB5_TICKET_ENC_PART2
+ if (tkt == 0 || tkt->client == 0) {
+ if (tkt) krb5_free_ticket(Z_krb5_ctx, tkt);
+ free(authbuf);
+ krb5_auth_con_free(Z_krb5_ctx, authctx);
+ return ZAUTH_FAILED;
+ }
+ princ = tkt->client;
#else
- checksum = compute_rlm_checksum(notice, dat.session);
-#endif
- if (checksum != notice->z_checksum) {
-#ifndef NOENCRYPTION
- checksum = compute_checksum(notice, dat.session);
- if (checksum != notice->z_checksum)
+ if (tkt == 0 || tkt->enc_part2 == 0) {
+ if (tkt) krb5_free_ticket(Z_krb5_ctx, tkt);
+ free(authbuf);
+ krb5_auth_con_free(Z_krb5_ctx, authctx);
+ return ZAUTH_FAILED;
+ }
+ princ = tkt->enc_part2->client;
#endif
+ if (princ == 0) {
+ krb5_free_ticket(Z_krb5_ctx, tkt);
+ free(authbuf);
+ krb5_auth_con_free(Z_krb5_ctx, authctx);
return ZAUTH_FAILED;
}
- /* Record the session key, expiry time, and source principal in the
- * hash table, so we can do a fast check next time. */
- add_session_key(&ticket, dat.session, srcprincipal,
- (time_t)(dat.time_sec + dat.life * 5 * 60));
+ /* HOLDING: authbuf, authctx, tkt */
+ result = krb5_unparse_name(Z_krb5_ctx, princ, &name);
+ if (result) {
+ syslog(LOG_WARNING, "k5 unparse_name failed: %s",
+ error_message(result));
+ free(authbuf);
+ krb5_auth_con_free(Z_krb5_ctx, authctx);
+ krb5_free_ticket(Z_krb5_ctx, tkt);
+ return ZAUTH_FAILED;
+ }
- return ZAUTH_YES;
+ krb5_free_ticket(Z_krb5_ctx, tkt);
-#else /* !HAVE_KRB4 */
+ /* HOLDING: authbuf, authctx, name */
+ if (strcmp(name, rlmprincipal)) {
+ syslog(LOG_WARNING, "k5 name mismatch: '%s' vs '%s'",
+ name, rlmprincipal);
+ krb5_auth_con_free(Z_krb5_ctx, authctx);
+ free(name);
+ free(authbuf);
+ return ZAUTH_FAILED;
+ }
+ free(name);
+ free(authbuf);
+
+ /* HOLDING: authctx */
+ /* Get an authenticator so we can get the keyblock */
+ result = krb5_auth_con_getauthenticator (Z_krb5_ctx, authctx,
+ &authenticator);
+ if(result) {
+ krb5_auth_con_free(Z_krb5_ctx, authctx);
+ return result;
+ }
+
+ /* HOLDING: authctx, authenticator */
+ result = krb5_auth_con_getkey(Z_krb5_ctx, authctx, &keyblock);
+ if (result) {
+ krb5_auth_con_free(Z_krb5_ctx, authctx);
+ krb5_free_authenticator(Z_krb5_ctx, KRB5AUTHENT);
+ return (ZAUTH_FAILED);
+ }
+
+ /* HOLDING: authctx, authenticator, keyblock */
+ /* Figure out what checksum type to use */
+#if HAVE_KRB5_CREDS_KEYBLOCK_ENCTYPE
+ key_data = keyblock->contents;
+ key_len = keyblock->length;
+ enctype = keyblock->enctype;
+ result = Z_krb5_lookup_cksumtype(enctype, &cksumtype);
+ if (result) {
+ krb5_free_keyblock(Z_krb5_ctx, keyblock);
+ krb5_auth_con_free(Z_krb5_ctx, authctx);
+ krb5_free_authenticator(Z_krb5_ctx, KRB5AUTHENT);
+ return (ZAUTH_FAILED);
+ }
+#else
+ key_data = keyblock->keyvalue.data;
+ key_len = keyblock->keyvalue.length;
+ {
+ unsigned int len;
+ ENCTYPE *val;
+ int i = 0;
+
+ result = krb5_keytype_to_enctypes(Z_krb5_ctx, keyblock->keytype,
+ &len, &val);
+ if (result) {
+ krb5_free_keyblock(Z_krb5_ctx, keyblock);
+ krb5_auth_con_free(Z_krb5_ctx, authctx);
+ krb5_free_authenticator(Z_krb5_ctx, KRB5AUTHENT);
+ return (ZAUTH_FAILED);
+ }
+
+ do {
+ if (i == len) break;
+ result = Z_krb5_lookup_cksumtype(val[i], &cksumtype);
+ i++;
+ } while (result != 0);
+
+ if (result) {
+ krb5_free_keyblock(Z_krb5_ctx, keyblock);
+ krb5_auth_con_free(Z_krb5_ctx, authctx);
+ krb5_free_authenticator(Z_krb5_ctx, KRB5AUTHENT);
+ return (ZAUTH_FAILED);
+ }
+ enctype = val[i-1];
+ }
+#endif
+ /* HOLDING: authctx, authenticator, keyblock */
+
+ /* Assemble the things to be checksummed */
+ /* first part is from start of packet through z_default_format:
+ * - z_version
+ * - z_num_other_fields
+ * - z_kind
+ * - z_uid
+ * - z_port
+ * - z_auth
+ * - z_authent_len
+ * - z_ascii_authent
+ * - z_class
+ * - z_class_inst
+ * - z_opcode
+ * - z_sender
+ * - z_recipient
+ * - z_default_format
+ */
+ cksum0_base = notice->z_packet;
+ x = notice->z_default_format;
+ cksum0_len = x + strlen(x) + 1 - cksum0_base;
+ /* second part is from z_multinotice through other fields:
+ * - z_multinotice
+ * - z_multiuid
+ * - z_other_fields[]
+ */
+ cksum1_base = notice->z_multinotice;
+ if (notice->z_num_other_fields)
+ x = notice->z_other_fields[notice->z_num_other_fields];
+ else
+ x = cksum1_base + strlen(cksum1_base) + 1; /* multiuid */
+ cksum1_len = x + strlen(x) + 1 - cksum1_base;
+
+ /* last part is the message body */
+ cksum2_base = notice->z_message;
+ cksum2_len = notice->z_message_len;
+
+ if ((!notice->z_ascii_checksum || *notice->z_ascii_checksum != 'Z') &&
+ key_len == 8 &&
+ (enctype == ENCTYPE_DES_CBC_CRC ||
+ enctype == ENCTYPE_DES_CBC_MD4 ||
+ enctype == ENCTYPE_DES_CBC_MD5)) {
+ /* try old-format checksum (covers cksum0 only) */
+
+ ZChecksum_t our_checksum;
+
+ our_checksum = des_quad_cksum(cksum0_base, NULL, cksum0_len, 0,
+ key_data);
+ if (our_checksum == notice->z_checksum) {
+ krb5_free_keyblock(Z_krb5_ctx, keyblock);
+ krb5_auth_con_free(Z_krb5_ctx, authctx);
+ krb5_free_authenticator(Z_krb5_ctx, KRB5AUTHENT);
+ return ZAUTH_YES;
+ }
+ }
+
+ /* HOLDING: authctx, authenticator */
+
+ cksumbuf.length = cksum0_len + cksum1_len + cksum2_len;
+ cksumbuf.data = malloc(cksumbuf.length);
+ if (!cksumbuf.data) {
+ krb5_free_keyblock(Z_krb5_ctx, keyblock);
+ krb5_auth_con_free(Z_krb5_ctx, authctx);
+ krb5_free_authenticator(Z_krb5_ctx, KRB5AUTHENT);
+ return ZAUTH_NO;
+ }
+ /* HOLDING: authctx, authenticator, cksumbuf.data */
+
+ memcpy(cksumbuf.data, cksum0_base, cksum0_len);
+ memcpy(cksumbuf.data + cksum0_len, cksum1_base, cksum1_len);
+ memcpy(cksumbuf.data + cksum0_len + cksum1_len,
+ cksum2_base, cksum2_len);
+
+ /* decode zcoded checksum */
+ /* The encoded form is always longer than the original */
+ asn1_len = strlen(notice->z_ascii_checksum) + 1;
+ asn1_data = malloc(asn1_len);
+ if (!asn1_data) {
+ krb5_free_keyblock(Z_krb5_ctx, keyblock);
+ krb5_auth_con_free(Z_krb5_ctx, authctx);
+ krb5_free_authenticator(Z_krb5_ctx, KRB5AUTHENT);
+ free(cksumbuf.data);
+ return ZAUTH_FAILED;
+ }
+ /* HOLDING: authctx, authenticator, cksumbuf.data, asn1_data */
+ result = ZReadZcode(notice->z_ascii_checksum,
+ asn1_data, asn1_len, &asn1_len);
+ if (result != ZERR_NONE) {
+ krb5_free_keyblock(Z_krb5_ctx, keyblock);
+ krb5_auth_con_free(Z_krb5_ctx, authctx);
+ krb5_free_authenticator(Z_krb5_ctx, KRB5AUTHENT);
+ free(asn1_data);
+ free(cksumbuf.data);
+ return ZAUTH_FAILED;
+ }
+ /* HOLDING: asn1_data, cksumbuf.data */
+
+#if HAVE_KRB5_C_MAKE_CHECKSUM
+ /* Verify the checksum -- MIT crypto API */
+ memset(&checksum, 0, sizeof(checksum));
+ checksum.length = asn1_len;
+ checksum.contents = asn1_data;
+ checksum.checksum_type = cksumtype;
+ result = krb5_c_verify_checksum(Z_krb5_ctx,
+ keyblock, Z_KEYUSAGE_SRV_CKSUM,
+ &cksumbuf, &checksum, &valid);
+ free(asn1_data);
+ krb5_auth_con_free(Z_krb5_ctx, authctx);
+ krb5_free_authenticator(Z_krb5_ctx, KRB5AUTHENT);
+ krb5_free_keyblock(Z_krb5_ctx, keyblock);
+ free(cksumbuf.data);
+ if (!result && valid)
+ return (ZAUTH_YES);
+ else
+ return (ZAUTH_FAILED);
+#else
+ /* Verify the checksum -- heimdal crypto API */
+ checksum.checksum.length = asn1_len;
+ checksum.checksum.data = asn1_data;
+ checksum.cksumtype = cksumtype;
+
+ /* HOLDING: authctx, authenticator, cksumbuf.data, asn1_data */
+
+ result = krb5_crypto_init(Z_krb5_ctx, keyblock, enctype, &cryptctx);
+ if (result) {
+ krb5_auth_con_free(Z_krb5_ctx, authctx);
+ krb5_free_authenticator(Z_krb5_ctx, KRB5AUTHENT);
+ krb5_free_keyblock(Z_krb5_ctx, keyblock);
+ free(asn1_data);
+ free(cksumbuf.data);
+ return result;
+ }
+ /* HOLDING: authctx, authenticator, cryptctx, cksumbuf.data, checksum */
+ result = krb5_verify_checksum(Z_krb5_ctx, cryptctx,
+ Z_KEYUSAGE_SRV_CKSUM,
+ cksumbuf.data, cksumbuf.length,
+ &checksum);
+ krb5_free_keyblock(Z_krb5_ctx, keyblock);
+ krb5_crypto_destroy(Z_krb5_ctx, cryptctx);
+ krb5_auth_con_free(Z_krb5_ctx, authctx);
+ krb5_free_authenticator(Z_krb5_ctx, KRB5AUTHENT);
+ free(asn1_data);
+ free(cksumbuf.data);
+ if (result)
+ return (ZAUTH_FAILED);
+ else
+ return (ZAUTH_YES);
+#endif
+#else
return (notice->z_auth) ? ZAUTH_YES : ZAUTH_NO;
#endif
}
+#undef KRB5AUTHENT
+
Code_t
ZCheckAuthentication(notice, from)
ZNotice_t *notice;
AUTH_DAT dat;
ZChecksum_t checksum;
C_Block session_key;
+ char instance[INST_SZ+1];
if (!notice->z_auth)
return ZAUTH_NO;
}
authent.length = notice->z_authent_len;
+#if 0
/* Copy the ticket out of the authentication data. */
if (krb_find_ticket(&authent, &ticket) != RD_AP_OK)
return ZAUTH_FAILED;
return ZAUTH_YES;
}
}
+#endif
+
+ strcpy(instance, SERVER_INSTANCE);
/* We don't have the session key cached; do it the long way. */
- result = krb_rd_req(&authent, SERVER_SERVICE, SERVER_INSTANCE,
+ result = krb_rd_req(&authent, SERVER_SERVICE, instance,
from->sin_addr.s_addr, &dat, srvtab_file);
if (result == RD_AP_OK) {
memcpy(__Zephyr_session, dat.session, sizeof(C_Block));
if (checksum != notice->z_checksum)
return ZAUTH_FAILED;
+#if 0
/* Record the session key, expiry time, and source principal in the
* hash table, so we can do a fast check next time. */
add_session_key(&ticket, dat.session, srcprincipal,
(time_t)(dat.time_sec + dat.life * 5 * 60));
+#endif
return ZAUTH_YES;
#endif
}
+
#ifdef HAVE_KRB4
static int hash_ticket(p, len)
char myname[MAXHOSTNAMELEN]; /* my host name */
char list_file[128];
+#ifdef HAVE_KRB5
+char keytab_file[128];
+static char tkt5_file[256];
+#endif
#ifdef HAVE_KRB4
char srvtab_file[128];
char my_realm[REALM_SZ];
struct in_addr my_addr;
char *bdump_version = "1.2";
+#ifdef HAVE_KRB5
+krb5_ccache Z_krb5_ccache;
+#endif
+
int
main(argc, argv)
int argc;
#ifdef HAVE_KRB4
sprintf(srvtab_file, "%s/zephyr/%s", SYSCONFDIR, ZEPHYR_SRVTAB);
sprintf(tkt_file, "%s/zephyr/%s", SYSCONFDIR, ZEPHYR_TKFILE);
+#endif
+#ifdef HAVE_KRB5
+ sprintf(keytab_file, "%s/zephyr/%s", SYSCONFDIR, ZEPHYR_KEYTAB);
+ sprintf(tkt5_file, "FILE:%s/zephyr/%s", SYSCONFDIR, ZEPHYR_TK5FILE);
#endif
sprintf(acl_dir, "%s/zephyr/%s", SYSCONFDIR, ZEPHYR_ACL_DIR);
sprintf(subs_file, "%s/zephyr/%s", SYSCONFDIR, DEFAULT_SUBS_FILE);
static int
initialize()
{
+ int zero = 0;
if (do_net_setup())
return(1);
ZSetServerState(1);
ZInitialize(); /* set up the library */
+#ifdef HAVE_KRB5
+ krb5_cc_resolve(Z_krb5_ctx, tkt5_file, &Z_krb5_ccache);
+#ifdef HAVE_KRB5_CC_SET_DEFAULT_NAME
+ krb5_cc_set_default_name(Z_krb5_ctx, tkt5_file);
+#else
+ {
+ /* Hack to make krb5_cc_default do something reasonable */
+ char *env=(char *)malloc(strlen(tkt5_file)+12);
+ if (!env) return(1);
+ sprintf(env, "KRB5CCNAME=%s", tkt5_file);
+ putenv(env);
+ }
+#endif
+#endif
#ifdef HAVE_KRB4
/* Override what Zinitialize set for ZGetRealm() */
if (*my_realm)
if (srv_socket < 0) {
syslog(LOG_ERR, "client_sock failed: %m");
return 1;
+ } else {
+#ifdef SO_BSDCOMPAT
+ int on = 1;
+
+ /* Prevent Linux from giving us socket errors we don't care about. */
+ setsockopt(srv_socket, SOL_SOCKET, SO_BSDCOMPAT, &on, sizeof(on));
+#endif
}
if (bind(srv_socket, (struct sockaddr *) &srv_addr,
sizeof(srv_addr)) < 0) {
{
int pid, i = 0;
int oerrno = errno;
- Realm *rlm;
+ ZRealm *rlm;
#ifdef _POSIX_VERSION
int waitb;
#else
Unacked *rlm_nacklist = NULL; /* not acked list for realm-realm
packets */
-Realm *otherrealms; /* points to an array of the known
+ZRealm *otherrealms; /* points to an array of the known
servers */
int nrealms = 0; /* number of other realms */
/*
* External Routines:
*
- * Realm *realm_which_realm(struct sockaddr_in *who)
+ * ZRealm *realm_which_realm(struct sockaddr_in *who)
* figures out if this packet came from another realm's server
*
- * Realm *realm_get_realm_by_pid(int pid)
+ * ZRealm *realm_get_realm_by_pid(int pid)
* figures out which realm a child handler was for
*
* void kill_realm_pids()
* int realm_sender_in_realm(char *realm, char *sender)
* figures out if sender is in realm
*
- * Realm *realm_get_realm_by_name(char *name)
+ * ZRealm *realm_get_realm_by_name(char *name)
* finds a realm struct from the realm array by name, tries expansion
*
* Code_t realm_dispatch(ZNotice_t *notice, int auth, struct sockaddr_in *who,
*
* Code_t realm_control_dispatch(ZNotice_t *notice, int auth,
* struct sockaddr_in *who, Server *server,
- * Realm *realm)
+ * ZRealm *realm)
* dispatches a foreign realm control message
*
* void realm_handoff(ZNotice_t *notice, int auth, struct sockaddr_in *who,
- * Realm *realm, int ack_to_sender)
+ * ZRealm *realm, int ack_to_sender)
* hands off a message to another realm
*
* void realm_dump_realms(File *fp)
* do a database dump of foreign realm info
*
*/
-static void realm_sendit __P((ZNotice_t *notice, struct sockaddr_in *who, int auth, Realm *realm, int ack_to_sender));
-static void realm_sendit_auth __P((ZNotice_t *notice, struct sockaddr_in *who, int auth, Realm *realm, int ack_to_sender));
+static void realm_sendit __P((ZNotice_t *notice, struct sockaddr_in *who, int auth, ZRealm *realm, int ack_to_sender));
+static Code_t realm_sendit_auth __P((ZNotice_t *notice, struct sockaddr_in *who, int auth, ZRealm *realm, int ack_to_sender));
static void rlm_ack __P((ZNotice_t *notice, Unacked *nacked));
static void rlm_nack_cancel __P((ZNotice_t *notice, struct sockaddr_in *who));
static void rlm_new_ticket __P(());
static void rlm_rexmit __P((void *arg));
-static Code_t realm_ulocate_dispatch __P((ZNotice_t *notice,int auth,struct sockaddr_in *who,Server *server,Realm *realm));
-static Code_t realm_new_server __P((struct sockaddr_in *, ZNotice_t *, Realm *));
-static Code_t realm_set_server __P((struct sockaddr_in *, Realm *));
+static Code_t realm_ulocate_dispatch __P((ZNotice_t *notice,int auth,struct sockaddr_in *who,Server *server,ZRealm *realm));
+static Code_t realm_new_server __P((struct sockaddr_in *, ZNotice_t *, ZRealm *));
+static Code_t realm_set_server __P((struct sockaddr_in *, ZRealm *));
#ifdef HAVE_KRB4
-static Code_t ticket_retrieve __P((Realm *realm));
+static Code_t ticket_retrieve __P((ZRealm *realm));
static int ticket_lookup __P((char *realm));
-static int ticket_expired __P((CREDENTIALS *cred));
#endif
static int
realm_get_idx_by_addr(realm, who)
- Realm *realm;
+ ZRealm *realm;
struct sockaddr_in *who;
{
struct sockaddr_in *addr;
realm_expand_realm(realmname)
char *realmname;
{
- Realm *realm;
+ ZRealm *realm;
int a;
/* First, look for an exact match (case insensitive) */
return(realmname);
}
-Realm *
+ZRealm *
realm_get_realm_by_pid(pid)
int pid;
{
- Realm *realm;
+ ZRealm *realm;
int a;
for (realm = otherrealms, a = 0; a < nrealms; a++, realm++)
void
kill_realm_pids()
{
- Realm *realm;
+ ZRealm *realm;
int a;
for (realm = otherrealms, a = 0; a < nrealms; a++, realm++)
return;
}
-Realmname *
+ZRealmname *
get_realm_lists(file)
char *file;
{
- Realmname *rlm_list, *rlm;
+ ZRealmname *rlm_list, *rlm;
int ii, nused, ntotal;
FILE *fp;
char buf[REALM_SZ + MAXHOSTNAMELEN + 1]; /* one for newline */
nused = 0;
if (!(fp = fopen(file, "r")))
- return((Realmname *)0);
+ return((ZRealmname *)0);
/* start with 16, realloc if necessary */
ntotal = 16;
- rlm_list = (Realmname *)malloc(ntotal * sizeof(Realmname));
+ rlm_list = (ZRealmname *)malloc(ntotal * sizeof(ZRealmname));
if (!rlm_list) {
syslog(LOG_CRIT, "get_realm_lists malloc");
abort();
/* new realm */
if (nused + 1 >= ntotal) {
/* make more space */
- rlm_list = (Realmname *)realloc((char *)rlm_list,
+ rlm_list = (ZRealmname *)realloc((char *)rlm_list,
(unsigned)ntotal * 2 *
- sizeof(Realmname));
+ sizeof(ZRealmname));
if (!rlm_list) {
syslog(LOG_CRIT, "get_realm_lists realloc");
abort();
}
}
if (nused + 1 >= ntotal) {
- rlm_list = (Realmname *)realloc((char *)rlm_list,
+ rlm_list = (ZRealmname *)realloc((char *)rlm_list,
(unsigned)(ntotal + 1) *
- sizeof(Realmname));
+ sizeof(ZRealmname));
if (!rlm_list) {
syslog(LOG_CRIT, "get_realm_lists realloc");
abort();
}
*rlm_list[nused].name = '\0';
+ fclose(fp);
return(rlm_list);
}
return 0;
}
-Realm *
+ZRealm *
realm_which_realm(who)
struct sockaddr_in *who;
{
- Realm *realm;
+ ZRealm *realm;
struct sockaddr_in *addr;
int a, b;
return 0;
}
-Realm *
+ZRealm *
realm_get_realm_by_name(name)
char *name;
{
int a;
- Realm *realm;
+ ZRealm *realm;
/* First, look for an exact match (case insensitive) */
for (realm = otherrealms, a = 0; a < nrealms; a++, realm++)
register ZNotice_t *notice;
struct sockaddr_in *who;
{
- register Realm *which = realm_which_realm(who);
+ register ZRealm *which = realm_which_realm(who);
register Unacked *nacked, *next;
ZPacket_t retval;
struct sockaddr_in *who;
Server *server;
{
- Realm *realm;
+ ZRealm *realm;
struct sockaddr_in newwho;
Code_t status = ZERR_NONE;
char rlm_recipient[REALM_SZ + 1];
realm_init()
{
Client *client;
- Realmname *rlmnames;
- Realm *rlm;
+ ZRealmname *rlmnames;
+ ZRealm *rlm;
int ii, jj, found;
struct in_addr *addresses;
struct hostent *hp;
for (nrealms = 0; *rlmnames[nrealms].name; nrealms++);
- otherrealms = (Realm *)malloc(nrealms * sizeof(Realm));
+ otherrealms = (ZRealm *)malloc(nrealms * sizeof(ZRealm));
if (!otherrealms) {
syslog(LOG_CRIT, "malloc failed in realm_init");
abort();
realm_deathgram(server)
Server *server;
{
- Realm *realm;
+ ZRealm *realm;
char rlm_recipient[REALM_SZ + 1];
int jj = 0;
}
#endif
- if ((retval = ZFormatNotice(&snotice, &pack, &packlen, ZAUTH))
+ if ((retval = ZFormatNotice(&snotice, &pack, &packlen, ZCAUTH))
!= ZERR_NONE)
{
syslog(LOG_WARNING, "rlm_deathgram format: %s",
realm_wakeup()
{
int jj, found = 0;
- Realm *realm;
+ ZRealm *realm;
char rlm_recipient[REALM_SZ + 1];
for (jj = 1; jj < nservers; jj++) { /* skip limbo server */
int auth;
struct sockaddr_in *who;
Server *server;
- Realm *realm;
+ ZRealm *realm;
{
register char *opcode = notice->z_opcode;
Code_t status;
int auth;
struct sockaddr_in *who;
Server *server;
- Realm *realm;
+ ZRealm *realm;
{
register char *opcode = notice->z_opcode;
Code_t status;
realm_new_server(sin, notice, realm)
struct sockaddr_in *sin;
ZNotice_t *notice;
- Realm *realm;
+ ZRealm *realm;
{
struct hostent *hp;
char suggested_server[MAXHOSTNAMELEN];
unsigned long addr;
- Realm *rlm;
+ ZRealm *rlm;
struct sockaddr_in sinaddr;
int srvidx;
static Code_t
realm_set_server(sin, realm)
struct sockaddr_in *sin;
- Realm *realm;
+ ZRealm *realm;
{
- Realm *rlm;
+ ZRealm *rlm;
rlm = realm_which_realm(sin);
/* Not exactly */
ZNotice_t *notice;
int auth;
struct sockaddr_in *who;
- Realm *realm;
+ ZRealm *realm;
int ack_to_sender;
{
#ifdef HAVE_KRB4
zdbug((LOG_DEBUG, "realm_sendit to realm %s auth %d", realm->name, auth));
/* valid ticket available now, send the message */
- realm_sendit_auth(notice, who, auth, realm, ack_to_sender);
+ retval = realm_sendit_auth(notice, who, auth, realm, ack_to_sender);
#else /* HAVE_KRB4 */
realm_sendit(notice, who, auth, realm, ack_to_sender);
#endif /* HAVE_KRB4 */
ZNotice_t *notice;
struct sockaddr_in *who;
int auth;
- Realm *realm;
+ ZRealm *realm;
int ack_to_sender;
{
caddr_t pack;
{
Unacked *nackpacket = (Unacked *) arg;
Code_t retval;
- register Realm *realm;
+ register ZRealm *realm;
int new_srv_idx;
zdbug((LOG_DEBUG,"rlm_rexmit"));
}
#ifdef HAVE_KRB4
-static void
+static Code_t
realm_sendit_auth(notice, who, auth, realm, ack_to_sender)
ZNotice_t *notice;
int auth;
struct sockaddr_in *who;
- Realm *realm;
+ ZRealm *realm;
int ack_to_sender;
{
char *buffer, *ptr;
Code_t retval;
Unacked *nacked;
char buf[1024], multi[64];
- CREDENTIALS cred;
- KTEXT_ST authent;
ZNotice_t partnotice, newnotice;
offset = 0;
- /* build an authent. first, make sure we have the ticket available */
- retval = krb_get_cred(SERVER_SERVICE, SERVER_INSTANCE, realm->name, &cred);
- if (retval != GC_OK) {
- syslog(LOG_WARNING, "rlm_sendit_auth get_cred: %s",
- error_message(retval+krb_err_base));
- return;
+ buffer = (char *) malloc(sizeof(ZPacket_t));
+ if (!buffer) {
+ syslog(LOG_ERR, "realm_sendit_auth malloc");
+ return ENOMEM; /* DON'T put on nack list */
}
- retval = krb_mk_req(&authent, SERVER_SERVICE, SERVER_INSTANCE,
- realm->name, 1);
- if (retval != MK_AP_OK) {
- syslog(LOG_WARNING, "rlm_sendit_auth mk_req: %s",
- error_message(retval+krb_err_base));
- return;
- }
+ buffer_len = sizeof(ZPacket_t);
- retval = ZMakeAscii(buf, sizeof(buf), authent.dat, authent.length);
+ newnotice = *notice;
+
+ hdrlen = 0;
+ retval = ZMakeZcodeRealmAuthentication(&newnotice, buffer, buffer_len,
+ &hdrlen, realm->name);
if (retval != ZERR_NONE) {
- syslog(LOG_WARNING, "rlm_sendit_auth mk_ascii: %s",
+ syslog(LOG_WARNING, "rlm_sendit_auth set addr: %s",
error_message(retval));
- return;
+ return (retval);
}
/* set the dest addr */
if (retval != ZERR_NONE) {
syslog(LOG_WARNING, "rlm_sendit_auth set addr: %s",
error_message(retval));
- return;
- }
-
- /* now format the notice, refragmenting if needed */
- newnotice = *notice;
- newnotice.z_auth = 1;
- newnotice.z_ascii_authent = buf;
- newnotice.z_authent_len = authent.length;
-
- buffer = (char *) malloc(sizeof(ZPacket_t));
- if (!buffer) {
- syslog(LOG_ERR, "realm_sendit_auth malloc");
- return; /* DON'T put on nack list */
- }
-
- buffer_len = sizeof(ZPacket_t);
-
- retval = Z_FormatRawHeader(&newnotice, buffer, buffer_len, &hdrlen, &ptr,
- NULL);
- if (retval != ZERR_NONE) {
- syslog(LOG_WARNING, "rlm_sendit_auth raw: %s", error_message(retval));
- free(buffer);
- return;
- }
-
-#ifdef NOENCRYPTION
- newnotice.z_checksum = 0;
-#else
- newnotice.z_checksum =
- (ZChecksum_t)des_quad_cksum(buffer, NULL, ptr - buffer, 0,
- cred.session);
-#endif
-
- retval = Z_FormatRawHeader(&newnotice, buffer, buffer_len, &hdrlen,
- NULL, NULL);
- if (retval != ZERR_NONE) {
- syslog(LOG_WARNING, "rlm_sendit_auth raw: %s", error_message(retval));
- free(buffer);
- return;
+ return (retval);
}
/* This is not terribly pretty, but it does do its job.
* but only the server uses it.
*/
- if ((newnotice.z_message_len+hdrlen > buffer_len) ||
- (newnotice.z_message_len+hdrlen > Z_MAXPKTLEN)) {
- /* Deallocate buffer, use a local one */
+ if ((notice->z_message_len+hdrlen > buffer_len) ||
+ (notice->z_message_len+hdrlen > Z_MAXPKTLEN)) {
+
+ /* Reallocate buffers inside the refragmenter */
free(buffer);
-
- partnotice = *notice;
- partnotice.z_auth = 1;
- partnotice.z_ascii_authent = buf;
- partnotice.z_authent_len = authent.length;
+ partnotice = *notice;
origoffset = 0;
origlen = notice->z_message_len;
syslog(LOG_ERR, "realm_sendit_auth malloc");
return; /* DON'T put on nack list */
}
-
- retval = Z_FormatRawHeader(&partnotice, buffer, buffer_len,
- &hdrlen, &ptr, NULL);
- if (retval != ZERR_NONE) {
- syslog(LOG_WARNING, "rlm_sendit_auth raw: %s",
- error_message(retval));
- free(buffer);
- return;
- }
-
-#ifdef NOENCRYPTION
- partnotice.z_checksum = 0;
-#else
- partnotice.z_checksum =
- (ZChecksum_t)des_quad_cksum(buffer, NULL, ptr - buffer, 0,
- cred.session);
-#endif
- retval = Z_FormatRawHeader(&partnotice, buffer, buffer_len,
- &hdrlen, NULL, NULL);
+ buffer_len = sizeof(ZPacket_t);
+
+ retval = ZMakeZcodeRealmAuthentication(&partnotice, buffer,
+ buffer_len, &hdrlen,
+ realm->name);
if (retval != ZERR_NONE) {
- syslog(LOG_WARNING, "rlm_sendit_auth raw: %s",
+ syslog(LOG_WARNING, "rlm_sendit_auth set addr: %s",
error_message(retval));
free(buffer);
- return;
+ return (retval);
}
ptr = buffer+hdrlen;
syslog(LOG_WARNING, "rlm_sendit_auth xmit: %s",
error_message(retval));
free(buffer);
- return;
+ return(retval);
}
if (!(nacked = (Unacked *)malloc(sizeof(Unacked)))) {
/* no space: just punt */
syslog(LOG_ERR, "rlm_sendit_auth nack malloc");
free(buffer);
- return;
+ return ENOMEM;
}
nacked->rexmits = 0;
if (!notice->z_message_len)
break;
}
-#if 0
- zdbug((LOG_DEBUG, "rlm_sendit_auth frag message sent"));
-#endif
- } else {
+ }
+ else {
/* This is easy, no further fragmentation needed */
ptr = buffer+hdrlen;
(void) memcpy(ptr, newnotice.z_message, newnotice.z_message_len);
- buffer_len = hdrlen+newnotice.z_message_len;
+ buffer_len = hdrlen+newnotice.z_message_len;
/* now send */
if ((retval = ZSendPacket(buffer, buffer_len, 0)) != ZERR_NONE) {
syslog(LOG_WARNING, "rlm_sendit_auth xmit: %s",
error_message(retval));
free(buffer);
- return;
+ return(retval);
}
-#if 0
- zdbug((LOG_DEBUG, "rlm_sendit_auth message sent"));
-#endif
/* now we've sent it, mark it as not ack'ed */
if (!(nacked = (Unacked *)malloc(sizeof(Unacked)))) {
/* no space: just punt */
syslog(LOG_ERR, "rlm_sendit_auth nack malloc");
free(buffer);
- return;
+ return 0;
}
nacked->rexmits = 0;
/* chain in */
LIST_INSERT(&rlm_nacklist, nacked);
}
- return;
-}
-
-static int
-ticket_expired(cred)
-CREDENTIALS *cred;
-{
-#ifdef HAVE_KRB_LIFE_TO_TIME
- return (krb_life_to_time(cred->issue_date, cred->lifetime) < NOW);
-#else /* HAVE_KRB_LIFE_TO_TIME */
- return (cred->issue_date + cred->lifetime*5*60 < NOW);
-#endif /* HAVE_KRB_LIFE_TO_TIME */
+ return 0;
}
static int
ticket_lookup(realm)
char *realm;
{
- CREDENTIALS cred;
- KTEXT_ST authent;
- int retval;
+ krb5_error_code result;
+ krb5_timestamp sec;
+ krb5_ccache ccache;
+ krb5_creds creds_in, *creds;
+
+ result = krb5_cc_default(Z_krb5_ctx, &ccache);
+ if (result)
+ return 0;
+
+ memset(&creds_in, 0, sizeof(creds_in));
+
+ result = krb5_cc_get_principal(Z_krb5_ctx, ccache, &creds_in.client);
+ if (result) {
+ krb5_cc_close(Z_krb5_ctx, ccache);
+ return 0;
+ }
+
+ result = krb5_build_principal(Z_krb5_ctx, &creds_in.server,
+ strlen(realm),
+ realm,
+ SERVER_KRB5_SERVICE, SERVER_INSTANCE, 0);
+ if (result) {
+ krb5_cc_close(Z_krb5_ctx, ccache);
+ return 0;
+ }
- retval = krb_get_cred(SERVER_SERVICE, SERVER_INSTANCE, realm, &cred);
- if (retval == GC_OK && !ticket_expired(&cred))
- /* good ticket */
- return(1);
+ result = krb5_get_credentials(Z_krb5_ctx, 0 /* flags */, ccache,
+ &creds_in, &creds);
+ krb5_cc_close(Z_krb5_ctx, ccache);
+ /* good ticket? */
+
+ krb5_timeofday (Z_krb5_ctx, &sec);
+ krb5_free_cred_contents(Z_krb5_ctx, &creds_in); /* hope this is OK */
+ if ((result == 0) && (sec < creds->times.endtime)) {
+ krb5_free_creds(Z_krb5_ctx, creds);
+ return (1);
+ }
+ if (!result) krb5_free_creds(Z_krb5_ctx, creds);
return (0);
}
static Code_t
ticket_retrieve(realm)
- Realm *realm;
+ ZRealm *realm;
{
- int pid, retval = 0;
- KTEXT_ST authent;
+ int pid;
+ krb5_ccache ccache;
+ krb5_error_code result;
+ krb5_auth_context authctx;
+ krb5_creds creds_in, *creds;
get_tgt();
if (realm->child_pid)
/* Right idea. Basically, we haven't gotten it yet */
- return KRBET_KDC_AUTH_EXP;
-
- /* For Putrify */
- memset(&authent.dat,0,MAX_KTXT_LEN);
- authent.mbz=0;
+ return KRB5KRB_AP_ERR_TKT_EXPIRED;
if (realm->have_tkt) {
- retval = krb_mk_req(&authent, SERVER_SERVICE, SERVER_INSTANCE,
- realm->name, 0);
- if (retval == KSUCCESS) {
- return retval;
+ /* Get a pointer to the default ccache. We don't need to free this. */
+ result = krb5_cc_default(Z_krb5_ctx, &ccache);
+
+ /* GRRR. There's no allocator or constructor for krb5_creds */
+ /* GRRR. It would be nice if this API were documented at all */
+ memset(&creds_in, 0, sizeof(creds_in));
+
+ if (!result)
+ result = krb5_cc_get_principal(Z_krb5_ctx, ccache, &creds_in.client);
+ /* construct the service principal */
+ if (!result)
+ result = krb5_build_principal(Z_krb5_ctx, &creds_in.server,
+ strlen(realm->name), realm->name,
+ SERVER_KRB5_SERVICE, SERVER_INSTANCE,
+ 0);
+
+ /* HOLDING: creds_in.server */
+
+ /* look up or get the credentials we need */
+ if (!result)
+ result = krb5_get_credentials(Z_krb5_ctx, 0 /* flags */, ccache,
+ &creds_in, &creds);
+ krb5_cc_close(Z_krb5_ctx, ccache);
+ krb5_free_cred_contents(Z_krb5_ctx, &creds_in); /* hope this is OK */
+ if (!result) {
+ krb5_free_creds(Z_krb5_ctx, creds);
+ return 0;
}
} else {
syslog(LOG_ERR, "tkt_rtrv: don't have ticket, but have no child");
#endif
#endif
+ syslog(LOG_INFO, "tkt_rtrv running for %s", realm->name);
while (1) {
- retval = krb_mk_req(&authent, SERVER_SERVICE, SERVER_INSTANCE,
- realm->name, 0);
- if (retval == KSUCCESS)
+ /* Get a pointer to the default ccache. We don't need to free this. */
+ result = krb5_cc_default(Z_krb5_ctx, &ccache);
+
+ /* GRRR. There's no allocator or constructor for krb5_creds */
+ /* GRRR. It would be nice if this API were documented at all */
+ memset(&creds_in, 0, sizeof(creds_in));
+
+ if (!result)
+ result = krb5_cc_get_principal(Z_krb5_ctx, ccache, &creds_in.client);
+ /* construct the service principal */
+ if (!result)
+ result = krb5_build_principal(Z_krb5_ctx, &creds_in.server,
+ strlen(realm->name), realm->name,
+ SERVER_KRB5_SERVICE, SERVER_INSTANCE,
+ 0);
+
+ /* HOLDING: creds_in.server */
+
+ /* look up or get the credentials we need */
+ if (!result)
+ result = krb5_get_credentials(Z_krb5_ctx, 0 /* flags */, ccache,
+ &creds_in, &creds);
+ krb5_cc_close(Z_krb5_ctx, ccache);
+ krb5_free_cred_contents(Z_krb5_ctx, &creds_in); /* hope this is OK */
+ if (!result) {
+ krb5_free_creds(Z_krb5_ctx, creds);
+ syslog(LOG_INFO, "tkt_rtrv succeeded for %s", realm->name);
exit(0);
+ }
/* Sleep a little while before retrying */
sleep(30);
realm->child_pid = pid;
realm->have_tkt = 0;
- syslog(LOG_WARNING, "tkt_rtrv: %s: %s", realm->name,
- krb_err_txt[retval]);
- return (retval+krb_err_base);
+ syslog(LOG_WARNING, "tkt_rtrv: %s: %d", realm->name,
+ result);
+ return (result);
}
}
#endif /* HAVE_KRB4 */
char **responses;
int num_resp;
char *vers, *pkts, *upt;
- Realm *realm;
+ ZRealm *realm;
int extrafields = 0;
#define NUM_FIXED 3 /* 3 fixed fields, plus server info */
syslog(LOG_CRIT, "srv_fwd malloc");
abort();
}
- retval = ZFormatSmallRawNotice(notice, pack, &packlen);
+ if (realm_which_realm(who)) {
+ retval = ZNewFormatSmallRawNotice(notice, pack, &packlen);
+ } else {
+ retval = ZFormatSmallRawNotice(notice, pack, &packlen);
+ }
if (retval != ZERR_NONE) {
syslog(LOG_WARNING, "srv_fwd format: %s", error_message(retval));
continue;
int *found));
static Destlist *subscr_copy_def_subs __P((char *person));
static Code_t subscr_realm_sendit __P((Client *who, Destlist *subs,
- ZNotice_t *notice, Realm *realm));
+ ZNotice_t *notice, ZRealm *realm));
static void subscr_unsub_realms __P((Destlist *newsubs));
static void subscr_unsub_sendit __P((Client *who, Destlist *subs,
- Realm *realm));
+ ZRealm *realm));
static int cl_match __P((Destlist*, Client *));
static int defaults_read = 0; /* set to 1 if the default subs
Code_t retval;
Acl *acl;
String *sender;
- Realm *realm = NULL;
+ ZRealm *realm = NULL;
if (!subs)
return ZERR_NONE; /* no subscr -> no error */
}
}
if (realm && !bdumping) {
- if (server && server == me_server) {
retval = subscr_realm_sendit(who, subs, notice, realm);
if (retval != ZERR_NONE) {
- free_subscriptions(subs);
- free_string(sender);
- return(retval);
- } else {
- /* free this one, will get from ADD */
free_subscription(subs);
- }
+ continue; /* the for loop */
} else {
/* Indicates we leaked traffic back to our realm */
+ free_subscription(subs); /* free this one, wil get from
+ ADD */
}
} else {
retval = triplet_register(who, &subs->dest, NULL);
struct sockaddr_in *sin;
ZNotice_t *notice;
{
- Realm *realm;
+ ZRealm *realm;
Client *who;
Destlist *cancel_subs, *subs, *cancel_next, *client_subs, *client_next;
Code_t retval;
subscr_realm_cancel(sin, notice, realm)
struct sockaddr_in *sin;
ZNotice_t *notice;
- Realm *realm;
+ ZRealm *realm;
{
Client *who;
Destlist *cancel_subs, *subs, *client_subs, *next, *next2;
{
Destlist *subs, *next;
Code_t retval;
- Realm *realm;
+ ZRealm *realm;
#if 0
zdbug((LOG_DEBUG,"subscr_cancel_client %s",
Client *who;
Destlist *subs;
ZNotice_t *notice;
- Realm *realm;
+ ZRealm *realm;
{
ZNotice_t snotice;
char *pack;
static Code_t
subscr_add_raw(client, realm, newsubs)
Client *client;
- Realm *realm;
+ ZRealm *realm;
Destlist *newsubs;
{
Destlist *subs, *subs2, *subs3, **head;
}
} else {
if (!realm) {
- Realm *remrealm =
+ ZRealm *remrealm =
realm_get_realm_by_name(subs->dest.recip->string + 1);
if (remrealm) {
Destlist *sub = (Destlist *) malloc(sizeof(Destlist));
/* Called from bdump_recv_loop to decapsulate realm subs */
Code_t
subscr_realm(realm, notice)
- Realm *realm;
+ ZRealm *realm;
ZNotice_t *notice;
{
Destlist *newsubs;
subscr_unsub_sendit(who, subs, realm)
Client *who;
Destlist *subs;
- Realm *realm;
+ ZRealm *realm;
{
ZNotice_t unotice;
Code_t retval;
/* Called from bump_send_loop by way of realm_send_realms */
Code_t
subscr_send_realm_subs(realm)
- Realm *realm;
+ ZRealm *realm;
{
int i = 0;
Destlist *subs, *next;
Code_t
subscr_realm_subs(realm)
- Realm *realm;
+ ZRealm *realm;
{
int i = 0;
Destlist *subs, *next;
ZNotice_t *notice;
struct sockaddr_in *who;
Server *server;
- Realm *realm;
+ ZRealm *realm;
Destlist *newsubs;
{
Destlist *subs, *subs2, *next;
found = 0;
for (subs = newsubs; subs; subs = next) {
- Realm *rlm;
+ ZRealm *rlm;
next=subs->next;
if (subs->dest.recip->string[0] != '\0') {
rlm = realm_which_realm(who);
ZNotice_t *notice;
struct sockaddr_in *who;
Server *server;
- Realm *realm;
+ ZRealm *realm;
{
Destlist *newsubs, *temp;
Acl *acl;
temp->dest.recip = make_string(rlm_recipient, 0);
}
- status = subscr_add_raw(client, (Realm *)0, newsubs);
+ status = subscr_add_raw(client, (ZRealm *)0, newsubs);
} else if (!strcmp(snotice.z_opcode, REALM_REQ_SUBSCRIBE)) {
zdbug((LOG_DEBUG, "subscr_foreign_user REQ %s/%s", tp0, tp1));
status = subscr_check_foreign_subs(notice, who, server, realm, newsubs);
static void free_loc __P((Location *loc));
static void ulogin_locate_forward __P((ZNotice_t *notice,
- struct sockaddr_in *who, Realm *realm));
+ struct sockaddr_in *who, ZRealm *realm));
static Location *locations = NULL; /* ptr to first in array */
static int num_locs = 0; /* number in array */
login_sendit(notice, auth, who, 1);
}
} else {
- syslog(LOG_ERR, "unknown ulog opcode %s", notice->z_opcode);
+ if (!strcmp(notice->z_opcode, LOGIN_USER_LOGIN))
+ zdbug((LOG_DEBUG, "ulog opcode from unknown foreign realm %s",
+ notice->z_opcode));
+ else
+ syslog(LOG_ERR, "unknown ulog opcode %s", notice->z_opcode);
if (server == me_server)
nack(notice, who);
return ZERR_NONE;
Server *server;
{
char *cp;
- Realm *realm;
+ ZRealm *realm;
if (!strcmp(notice->z_opcode, LOCATE_LOCATE)) {
/* we are talking to a current-rev client; send an ack */
ulogin_locate(notice, who, auth);
return ZERR_NONE;
} else {
- syslog(LOG_ERR, "unknown uloc opcode %s", notice->z_opcode);
+ syslog(LOG_ERR, "unknown uloc opcode %s", notice->z_opcode);
if (server == me_server)
nack(notice, who);
return ZERR_NONE;
ulogin_locate_forward(notice, who, realm)
ZNotice_t *notice;
struct sockaddr_in *who;
- Realm *realm;
+ ZRealm *realm;
{
ZNotice_t lnotice;
ulogin_realm_locate(notice, who, realm)
ZNotice_t *notice;
struct sockaddr_in *who;
- Realm *realm;
+ ZRealm *realm;
{
char **answer;
int found;
typedef struct _Destination Destination;
typedef struct _Destlist Destlist;
-typedef struct _Realm Realm;
-typedef struct _Realmname Realmname;
-typedef enum _Realm_state Realm_state;
+typedef struct _ZRealm ZRealm;
+typedef struct _ZRealmname ZRealmname;
+typedef enum _ZRealm_state ZRealm_state;
typedef struct _Client Client;
typedef struct _Triplet Triplet;
typedef enum _Server_state Server_state;
struct _Destlist *next, **prev_p;
};
-enum _Realm_state {
- REALM_UP, /* Realm is up */
- REALM_TARDY, /* Realm due for a hello XXX */
- REALM_DEAD, /* Realm is considered dead */
- REALM_STARTING /* Realm is between dead and up */
+enum _ZRealm_state {
+ REALM_UP, /* ZRealm is up */
+ REALM_TARDY, /* ZRealm due for a hello XXX */
+ REALM_DEAD, /* ZRealm is considered dead */
+ REALM_STARTING /* ZRealm is between dead and up */
};
-struct _Realm {
+struct _ZRealm {
char name[REALM_SZ];
int count;
struct sockaddr_in *addrs;
Client *client;
int child_pid;
int have_tkt;
- Realm_state state;
+ ZRealm_state state;
};
-struct _Realmname {
+struct _ZRealmname {
char name[REALM_SZ];
char **servers;
int nused;
String *principal; /* krb principal of user */
int last_send; /* Counter for last sent packet. */
time_t last_ack; /* Time of last received ack */
- Realm *realm;
+ ZRealm *realm;
struct _Client *next, **prev_p;
};
extern String *class_control, *class_admin, *class_hm;
extern String *class_ulogin, *class_ulocate;
int ZDest_eq __P((Destination *d1, Destination *d2));
-Code_t triplet_register __P((Client *client, Destination *dest, Realm *realm));
+Code_t triplet_register __P((Client *client, Destination *dest, ZRealm *realm));
Code_t triplet_deregister __P((Client *client, Destination *dest,
- Realm *realm));
+ ZRealm *realm));
Code_t class_restrict __P((char *class, Acl *acl));
Code_t class_setup_restricted __P((char *class, Acl *acl));
Client **triplet_lookup __P((Destination *dest));
struct sockaddr_in *who, Server *server));
/* found in subscr.c */
-Code_t subscr_foreign_user __P((ZNotice_t *, struct sockaddr_in *, Server *, Realm *));
+Code_t subscr_foreign_user __P((ZNotice_t *, struct sockaddr_in *, Server *, ZRealm *));
Code_t subscr_cancel __P((struct sockaddr_in *sin, ZNotice_t *notice));
Code_t subscr_subscribe __P((Client *who, ZNotice_t *notice, Server *server));
Code_t subscr_send_subs __P((Client *client));
/* found in realm.c */
int realm_sender_in_realm __P((char *realm, char *sender));
int realm_bound_for_realm __P((char *realm, char *recip));
-Realm *realm_which_realm __P((struct sockaddr_in *who));
-Realm *realm_get_realm_by_name __P((char *name));
-Realm *realm_get_realm_by_pid __P((int));
-void realm_handoff(ZNotice_t *, int, struct sockaddr_in *, Realm *, int);
+ZRealm *realm_which_realm __P((struct sockaddr_in *who));
+ZRealm *realm_get_realm_by_name __P((char *name));
+ZRealm *realm_get_realm_by_pid __P((int));
+void realm_handoff(ZNotice_t *, int, struct sockaddr_in *, ZRealm *, int);
char *realm_expand_realm(char *);
void realm_init __P((void));
-Code_t ZCheckRealmAuthentication __P((ZNotice_t *, struct sockaddr_in *,
+Code_t ZCheckZRealmAuthentication __P((ZNotice_t *, struct sockaddr_in *,
char *));
Code_t realm_control_dispatch __P((ZNotice_t *, int, struct sockaddr_in *,
- Server *, Realm *));
+ Server *, ZRealm *));
void realm_shutdown __P((void));
void realm_deathgram __P((Server *));
extern int zdebug;
extern char myname[]; /* domain name of this host */
extern char list_file[];
+#ifdef HAVE_KRB5
+extern char keytab_file[];
+extern krb5_ccache Z_krb5_ccache;
+#endif
#ifdef HAVE_KRB4
extern char srvtab_file[];
extern char my_realm[];
extern String *empty;
extern String *wildcard_instance;
-extern Realm *otherrealms;
+extern ZRealm *otherrealms;
extern int nrealms;
extern struct in_addr my_addr; /* my inet address */
#define SERVER_LIST_FILE "server.list"
#define REALM_LIST_FILE "realm.list"
+#ifdef HAVE_KRB5
+#define ZEPHYR_KEYTAB "krb5.keytab"
+#define ZEPHYR_TK5FILE "z5tkts"
+#endif
#ifdef HAVE_KRB4
#define ZEPHYR_SRVTAB "srvtab"
#define ZEPHYR_TKFILE "ztkts"
ec ZSRV_NOSUB,
"No such subscription"
ec ZSRV_NOCLASS,
- "Class unkown"
+ "Class unknown"
ec ZSRV_CLASSXISTS,
"Class already registered"
ec ZSRV_CLASSRESTRICTED,