krb5-1.16/0000755000704600001450000000000013211554430012171 5ustar ghudsonlibuuidkrb5-1.16/README0000644000704600001450000003215513211554426013064 0ustar ghudsonlibuuid Kerberos Version 5, Release 1.16 Release Notes The MIT Kerberos Team Copyright and Other Notices --------------------------- Copyright (C) 1985-2017 by the Massachusetts Institute of Technology and its contributors. All rights reserved. Please see the file named NOTICE for additional notices. Documentation ------------- Unified documentation for Kerberos V5 is available in both HTML and PDF formats. The table of contents of the HTML format documentation is at doc/html/index.html, and the PDF format documentation is in the doc/pdf directory. Additionally, you may find copies of the HTML format documentation online at http://web.mit.edu/kerberos/krb5-latest/doc/ for the most recent supported release, or at http://web.mit.edu/kerberos/krb5-devel/doc/ for the release under development. More information about Kerberos may be found at http://web.mit.edu/kerberos/ and at the MIT Kerberos Consortium web site http://kerberos.org/ Building and Installing Kerberos 5 ---------------------------------- Build documentation is in doc/html/build/index.html or doc/pdf/build.pdf. The installation guide is in doc/html/admin/install.html or doc/pdf/install.pdf. If you are attempting to build under Windows, please see the src/windows/README file. Reporting Bugs -------------- Please report any problems/bugs/comments by sending email to krb5-bugs@mit.edu. You may view bug reports by visiting http://krbdev.mit.edu/rt/ and using the "Guest Login" button. Please note that the web interface to our bug database is read-only for guests, and the primary way to interact with our bug database is via email. DES transition -------------- The Data Encryption Standard (DES) is widely recognized as weak. The krb5-1.7 release contains measures to encourage sites to migrate away from using single-DES cryptosystems. Among these is a configuration variable that enables "weak" enctypes, which defaults to "false" beginning with krb5-1.8. Major changes in 1.16 (2017-12-05) ---------------------------------- Administrator experience: * The KDC can match PKINIT client certificates against the "pkinit_cert_match" string attribute on the client principal entry, using the same syntax as the existing "pkinit_cert_match" profile option. * The ktutil addent command supports the "-k 0" option to ignore the key version, and the "-s" option to use a non-default salt string. * kpropd supports a --pid-file option to write a pid file at startup, when it is run in standalone mode. * The "encrypted_challenge_indicator" realm option can be used to attach an authentication indicator to tickets obtained using FAST encrypted challenge pre-authentication. * Localization support can be disabled at build time with the --disable-nls configure option. Developer experience: * The kdcpolicy pluggable interface allows modules control whether tickets are issued by the KDC. * The kadm5_auth pluggable interface allows modules to control whether kadmind grants access to a kadmin request. * The certauth pluggable interface allows modules to control which PKINIT client certificates can authenticate to which client principals. * KDB modules can use the client and KDC interface IP addresses to determine whether to allow an AS request. * GSS applications can query the bit strength of a krb5 GSS context using the GSS_C_SEC_CONTEXT_SASL_SSF OID with gss_inquire_sec_context_by_oid(). * GSS applications can query the impersonator name of a krb5 GSS credential using the GSS_KRB5_GET_CRED_IMPERSONATOR OID with gss_inquire_cred_by_oid(). * kdcpreauth modules can query the KDC for the canonicalized requested client principal name, or match a principal name against the requested client principal name with canonicalization. Protocol evolution: * The client library will continue to try pre-authentication mechanisms after most failure conditions. * The KDC will issue trivially renewable tickets (where the renewable lifetime is equal to or less than the ticket lifetime) if requested by the client, to be friendlier to scripts. * The client library will use a random nonce for TGS requests instead of the current system time. * For the RC4 string-to-key or PAC operations, UTF-16 is supported (previously only UCS-2 was supported). * When matching PKINIT client certificates, UPN SANs will be matched correctly as UPNs, with canonicalization. User experience: * Dates after the year 2038 are accepted (provided that the platform time facilities support them), through the year 2106. * Automatic credential cache selection based on the client realm will take into account the fallback realm and the service hostname. * Referral and alternate cross-realm TGTs will not be cached, avoiding some scenarios where they can be added to the credential cache multiple times. * A German translation has been added. Code quality: * The build is warning-clean under clang with the configured warning options. * The automated test suite runs cleanly under AddressSanitizer. krb5-1.16 changes by ticket ID ------------------------------ 3349 Allow keytab entries to ignore the key version 7647 let ktutil support non-default salts 7877 Interleaved init_creds operations use same per-request preauth context 8352 Year 2038 fixes 8515 Add German translation 8517 Add KRB5_TRACE calls for DNS lookups 8518 Remove redeclaration of ttyname() in ksu 8526 Constify service and hostname in krb5_mk_req() 8527 Clean up memory handling in krb5_fwd_tgt_creds() 8528 Improve PKINIT UPN SAN matching 8529 Add OpenLDAP LDIF file for Kerberos schema 8533 Bug in src/tests/responder.c 8534 Add configure option to disable nls support 8537 Preauthentication should continue after failure 8539 Preauth tryagain should copy KDC cookie 8544 Wrong PKCS11 PIN can trigger PKINIT draft9 code 8548 Add OID to inquire GSS cred impersonator name 8549 Use fallback realm for GSSAPI ccache selection 8558 kvno memory leak (1.15.1) 8561 Add certauth pluggable interface 8562 Add the certauth dbmatch module 8568 Convert some pkiDebug messages to TRACE macros 8569 Add support to query the SSF of a GSS context 8570 Add the client_name() kdcpreauth callback 8571 Use the canonical client principal name for OTP 8572 Un-deprecate krb5_auth_con_initivector() 8575 Add FAST encrypted challenge auth indicator 8577 Replace UCS-2 conversions with UTF-16 8578 Add various bound checks 8579 duplicate caching of some cross-realm TGTs 8582 Use a random nonce in TGS requests 8583 Pass client address to DAL audit_as_req 8592 Parse all kadm5.acl fields at startup 8595 Pluggable interface for kadmin authorization 8597 acx_pthread.m4 needs to be updated 8602 Make ccache name work for klist/kdestroy -A 8603 Remove incomplete PKINIT OCSP support 8606 Add KDC policy pluggable interface 8607 kpropd should write a pidfile when started in standalone mode... 8608 Fix AIX build issues 8609 Renewed tickets can be marked renewable with no renewable endtime 8610 Don't set ctime in KDC error replies 8612 Bump bundled libverto for 0.3.0 release 8613 Add hostname-based ccselect module 8615 Abort client preauth on keyboard interrupt 8616 Fix default enctype order in docs 8617 PKINIT matching can crash for certs with long issuer and subject 8620 Length check when parsing GSS token encapsulation 8621 Expose context errors in pkinit_server_plugin_init 8623 Update features list for 1.16 8624 Update config.guess, config.sub Acknowledgements ---------------- Past Sponsors of the MIT Kerberos Consortium: Apple Carnegie Mellon University Centrify Corporation Columbia University Cornell University The Department of Defense of the United States of America (DoD) Fidelity Investments Google Iowa State University MIT Michigan State University Microsoft MITRE Corporation Morgan-Stanley The National Aeronautics and Space Administration of the United States of America (NASA) Network Appliance (NetApp) Nippon Telephone and Telegraph (NTT) US Government Office of the National Coordinator for Health Information Technology (ONC) Oracle Pennsylvania State University Red Hat Stanford University TeamF1, Inc. The University of Alaska The University of Michigan The University of Pennsylvania Past and present members of the Kerberos Team at MIT: Danilo Almeida Jeffrey Altman Justin Anderson Richard Basch Mitch Berger Jay Berkenbilt Andrew Boardman Bill Bryant Steve Buckley Joe Calzaretta John Carr Mark Colan Don Davis Sarah Day Alexandra Ellwood Carlos Garay Dan Geer Nancy Gilman Matt Hancher Thomas Hardjono Sam Hartman Paul Hill Marc Horowitz Eva Jacobus Miroslav Jurisic Barry Jaspan Benjamin Kaduk Geoffrey King Kevin Koch John Kohl HaoQi Li Jonathan Lin Peter Litwack Scott McGuire Steve Miller Kevin Mitchell Cliff Neuman Paul Park Ezra Peisach Chris Provenzano Ken Raeburn Jon Rochlis Jeff Schiller Jen Selby Robert Silk Bill Sommerfeld Jennifer Steiner Ralph Swick Brad Thompson Harry Tsai Zhanna Tsitkova Ted Ts'o Marshall Vale Taylor Yu The following external contributors have provided code, patches, bug reports, suggestions, and valuable resources: Ian Abbott Brandon Allbery Russell Allbery Brian Almeida Michael B Allen Heinz-Ado Arnolds Derek Atkins Mark Bannister David Bantz Alex Baule David Benjamin Thomas Bernard Adam Bernstein Arlene Berry Jeff Blaine Radoslav Bodo Sumit Bose Emmanuel Bouillon Isaac Boukris Philip Brown Samuel Cabrero Michael Calmer Andrea Campi Julien Chaffraix Ravi Channavajhala Srinivas Cheruku Leonardo Chiquitto Seemant Choudhary Howard Chu Andrea Cirulli Christopher D. Clausen Kevin Coffman Simon Cooper Sylvain Cortes Ian Crowther Arran Cudbard-Bell Jeff D'Angelo Nalin Dahyabhai Mark Davies Dennis Davis Alex Dehnert Mark Deneen Günther Deschner John Devitofranceschi Marc Dionne Roland Dowdeswell Dorian Ducournau Viktor Dukhovni Jason Edgecombe Mark Eichin Shawn M. Emery Douglas E. Engert Peter Eriksson Juha Erkkilä Gilles Espinasse Ronni Feldt Bill Fellows JC Ferguson Remi Ferrand Paul Fertser William Fiveash Jacques Florent Ákos Frohner Sebastian Galiano Marcus Granado Scott Grizzard Helmut Grohne Steve Grubb Philip Guenther Dominic Hargreaves Robbie Harwood John Hascall Jakob Haufe Matthieu Hautreux Jochen Hein Paul B. Henson Jeff Hodges Christopher Hogan Love Hörnquist Åstrand Ken Hornstein Henry B. Hotz Luke Howard Jakub Hrozek Shumon Huque Jeffrey Hutzelman Wyllys Ingersoll Holger Isenberg Spencer Jackson Diogenes S. Jesus Pavel Jindra Brian Johannesmeyer Joel Johnson Alexander Karaivanov Anders Kaseorg Bar Katz Zentaro Kavanagh Mubashir Kazia W. Trevor King Patrik Kis Martin Kittel Mikkel Kruse Reinhard Kugler Tomas Kuthan Pierre Labastie Chris Leick Volker Lendecke Jan iankko Lieskovsky Todd Lipcon Oliver Loch Kevin Longfellow Frank Lonigro Jon Looney Nuno Lopes Ryan Lynch Roland Mainz Andrei Maslennikov Michael Mattioli Nathaniel McCallum Greg McClement Cameron Meadors Alexey Melnikov Franklyn Mendez Markus Moeller Kyle Moffett Paul Moore Keiichi Mori Michael Morony Zbysek Mraz Edward Murrell Nikos Nikoleris Felipe Ortega Michael Osipov Andrej Ota Dmitri Pal Javier Palacios Tom Parker Ezra Peisach Zoran Pericic W. Michael Petullo Mark Phalan Brett Randall Jonathan Reams Jonathan Reed Robert Relyea Tony Reix Martin Rex Jason Rogers Matt Rogers Nate Rosenblum Solly Ross Mike Roszkowski Guillaume Rousse Joshua Schaeffer Andreas Schneider Tom Shaw Jim Shi Peter Shoults Richard Silverman Cel Skeggs Simo Sorce Michael Spang Michael Ströder Bjørn Tore Sund Joe Travaglini Tim Uglow Rathor Vipin Denis Vlasenko Jorgen Wahlsten Stef Walter Max (Weijun) Wang John Washington Stef Walter Xi Wang Kevin Wasserman Margaret Wasserman Marcus Watts Andreas Wiese Simon Wilkinson Nicolas Williams Ross Wilper Augustin Wolf David Woodhouse Tsu-Phong Wu Xu Qiang Neng Xue Zhaomo Yang Nickolai Zeldovich Hanz van Zijst Gertjan Zwartjes The above is not an exhaustive list; many others have contributed in various ways to the MIT Kerberos development effort over the years. Other acknowledgments (for bug reports and patches) are in the doc/CHANGES file. krb5-1.16/src/0000755000704600001450000000000013211554430012760 5ustar ghudsonlibuuidkrb5-1.16/src/aclocal.m40000644000704600001450000015456713211554426014647 0ustar ghudsonlibuuidAC_PREREQ(2.63) AC_COPYRIGHT([Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008, 2009 Massachusetts Institute of Technology. ]) dnl define([K5_TOPDIR],[.])dnl dnl AC_DEFUN(V5_SET_TOPDIR,[dnl ac_reltopdir="K5_TOPDIR" if test ! -r "$srcdir/K5_TOPDIR/aclocal.m4"; then AC_MSG_ERROR([Configure could not determine the relative topdir]) fi ac_topdir=$srcdir/$ac_reltopdir ac_config_fragdir=$ac_reltopdir/config # echo "Looking for $srcdir/$ac_config_fragdir" if test -d "$srcdir/$ac_config_fragdir"; then AC_CONFIG_AUX_DIR(K5_TOPDIR/config) else AC_MSG_ERROR([can not find config/ directory in $ac_reltopdir]) fi ])dnl dnl dnl Version info. dnl pushdef([x],esyscmd([sed -n 's/#define \([A-Z0-9_]*\)[ \t]*\(.*\)/\1=\2/p' < ]K5_TOPDIR/patchlevel.h)) define([PL_KRB5_MAJOR_RELEASE],regexp(x,[KRB5_MAJOR_RELEASE=\(.*\)],[\1])) ifelse(PL_KRB5_MAJOR_RELEASE,,[errprint([Can't determine KRB5_MAJOR_RELEASE value from patchlevel.h. ]) m4exit(1) dnl sometimes that does not work? builtin(m4exit,1)]) define([PL_KRB5_MINOR_RELEASE],regexp(x,[KRB5_MINOR_RELEASE=\(.*\)],[\1])) ifelse(PL_KRB5_MINOR_RELEASE,,[errprint([Can't determine KRB5_MINOR_RELEASE value from patchlevel.h. ]) m4exit(1) dnl sometimes that does not work? builtin(m4exit,1)]) define([PL_KRB5_PATCHLEVEL],regexp(x,[KRB5_PATCHLEVEL=\(.*\)],[\1])) ifelse(PL_KRB5_PATCHLEVEL,,[errprint([Can't determine KRB5_PATCHLEVEL value from patchlevel.h. ]) m4exit(1) dnl sometimes that does not work? builtin(m4exit,1)]) define([PL_KRB5_RELTAIL],regexp(x,[KRB5_RELTAIL="\(.*\)"],[\1])) dnl RELTAIL is allowed to not be defined. popdef([x]) define([K5_VERSION],PL_KRB5_MAJOR_RELEASE.PL_KRB5_MINOR_RELEASE[]ifelse(PL_KRB5_PATCHLEVEL,0,,.PL_KRB5_PATCHLEVEL)ifelse(PL_KRB5_RELTAIL,,,-PL_KRB5_RELTAIL)) define([K5_BUGADDR],krb5-bugs@mit.edu) define([K5_AC_INIT],[AC_INIT(Kerberos 5, K5_VERSION, K5_BUGADDR, krb5) AC_CONFIG_SRCDIR($1) build_dynobj=no]) dnl dnl drop in standard rules for all configure files -- CONFIG_RULES dnl AC_DEFUN(CONFIG_RULES,[dnl AC_REQUIRE([V5_SET_TOPDIR]) dnl EXTRA_FILES="" AC_SUBST(EXTRA_FILES) dnl Consider using AC_USE_SYSTEM_EXTENSIONS when we require autoconf dnl 2.59c or later, but be sure to test on Solaris first. AC_DEFINE([_GNU_SOURCE], 1, [Define to enable extensions in glibc]) AC_DEFINE([__STDC_WANT_LIB_EXT1__], 1, [Define to enable C11 extensions]) WITH_CC dnl AC_REQUIRE_CPP if test -z "$LD" ; then LD=$CC; fi AC_ARG_VAR(LD,[linker command [CC]]) AC_SUBST(LDFLAGS) dnl KRB5_AC_CHOOSE_ET dnl KRB5_AC_CHOOSE_SS dnl KRB5_AC_CHOOSE_DB dnl dnl allow stuff in tree to access deprecated stuff for now dnl AC_DEFINE([KRB5_DEPRECATED], 1, [Define only if building in-tree]) AC_C_CONST dnl WITH_NETLIB dnl WITH_HESIOD dnl KRB5_AC_MAINTAINER_MODE dnl AC_ARG_PROGRAM dnl dnl dnl This identifies the top of the source tree relative to the directory dnl in which the configure file lives. dnl CONFIG_RELTOPDIR=$ac_reltopdir AC_SUBST(CONFIG_RELTOPDIR) lib_frag=$srcdir/$ac_config_fragdir/lib.in AC_SUBST_FILE(lib_frag) libobj_frag=$srcdir/$ac_config_fragdir/libobj.in AC_SUBST_FILE(libobj_frag) libnover_frag=$srcdir/$ac_config_fragdir/libnover.in AC_SUBST_FILE(libnover_frag) libpriv_frag=$srcdir/$ac_config_fragdir/libpriv.in AC_SUBST_FILE(libpriv_frag) libnodeps_frag=$srcdir/$ac_config_fragdir/libnodeps.in AC_SUBST_FILE(libnodeps_frag) dnl KRB5_AC_PRAGMA_WEAK_REF WITH_LDAP KRB5_LIB_PARAMS KRB5_AC_INITFINI KRB5_AC_ENABLE_THREADS KRB5_AC_FIND_DLOPEN KRB5_AC_KEYRING_CCACHE KRB5_AC_PERSISTENT_KEYRING ])dnl dnl Maintainer mode, akin to what automake provides, 'cept we don't dnl want to use automake right now. AC_DEFUN([KRB5_AC_MAINTAINER_MODE], [AC_ARG_ENABLE([maintainer-mode], AC_HELP_STRING([--enable-maintainer-mode],[enable rebuilding of source files, Makefiles, etc]), USE_MAINTAINER_MODE=$enableval, USE_MAINTAINER_MODE=no) if test "$USE_MAINTAINER_MODE" = yes; then MAINTAINER_MODE_TRUE= MAINTAINER_MODE_FALSE='#' AC_MSG_NOTICE(enabling maintainer mode) else MAINTAINER_MODE_TRUE='#' MAINTAINER_MODE_FALSE= fi MAINT=$MAINTAINER_MODE_TRUE AC_SUBST(MAINTAINER_MODE_TRUE) AC_SUBST(MAINTAINER_MODE_FALSE) AC_SUBST(MAINT) ]) dnl AC_DEFUN([KRB5_AC_INITFINI],[ dnl Do we want initialization at load time? AC_ARG_ENABLE([delayed-initialization], AC_HELP_STRING([--disable-delayed-initialization],initialize library code when loaded @<:@delay until first use@:>@), , enable_delayed_initialization=yes) case "$enable_delayed_initialization" in yes) AC_DEFINE(DELAY_INITIALIZER,1,[Define if library initialization should be delayed until first use]) ;; no) ;; *) AC_MSG_ERROR(invalid option $enable_delayed_initialization for delayed-initialization) ;; esac dnl We always want finalization at unload time. dnl dnl Can we do things through gcc? KRB5_AC_GCC_ATTRS dnl How about with the linker? if test -z "$use_linker_init_option" ; then AC_MSG_ERROR(ran INITFINI before checking shlib.conf?) fi if test "$use_linker_init_option" = yes; then AC_DEFINE(USE_LINKER_INIT_OPTION,1,[Define if link-time options for library initialization will be used]) fi if test "$use_linker_fini_option" = yes; then AC_DEFINE(USE_LINKER_FINI_OPTION,1,[Define if link-time options for library finalization will be used]) fi ]) dnl find dlopen AC_DEFUN([KRB5_AC_FIND_DLOPEN],[ old_LIBS="$LIBS" DL_LIB= AC_SEARCH_LIBS(dlopen, dl, [ if test "$ac_cv_search_dlopen" != "none required"; then DL_LIB=$ac_cv_search_dlopen fi LIBS="$old_LIBS" AC_DEFINE(USE_DLOPEN,1,[Define if dlopen should be used])]) AC_SUBST(DL_LIB) ]) dnl Hack for now. AC_DEFUN([KRB5_AC_ENABLE_THREADS],[ AC_ARG_ENABLE([thread-support], AC_HELP_STRING([--disable-thread-support],don't enable thread support @<:@enabled@:>@), , enable_thread_support=yes) if test "$enable_thread_support" = yes ; then AC_MSG_NOTICE(enabling thread support) AC_DEFINE(ENABLE_THREADS,1,[Define if thread support enabled]) fi dnl Maybe this should be inside the conditional above? Doesn't cache.... if test "$enable_thread_support" = yes; then AX_PTHREAD(,[AC_MSG_ERROR([cannot determine options for enabling thread support; try --disable-thread-support])]) AC_MSG_NOTICE(PTHREAD_CC = $PTHREAD_CC) AC_MSG_NOTICE(PTHREAD_CFLAGS = $PTHREAD_CFLAGS) AC_MSG_NOTICE(PTHREAD_LIBS = $PTHREAD_LIBS) dnl Not really needed -- if pthread.h isn't found, ACX_PTHREAD will fail. dnl AC_CHECK_HEADERS(pthread.h) # AIX and Tru64 don't support weak references, and don't have # stub versions of the pthread code in libc. case "${host_os}" in aix* | osf*) # On these platforms, we'll always pull in the thread support. LIBS="$LIBS $PTHREAD_LIBS" CFLAGS="$CFLAGS $PTHREAD_CFLAGS" # We don't need to sometimes add the flags we've just folded in... PTHREAD_LIBS= PTHREAD_CFLAGS= ;; hpux*) # These are the flags that "gcc -pthread" adds. But we don't # want "-pthread" because that has link-time effects, and we # don't exclude CFLAGS when linking. *sigh* PTHREAD_CFLAGS="-D_REENTRANT -D_THREAD_SAFE -D_POSIX_C_SOURCE=199506L" ;; solaris2.[[1-9]]) # On Solaris 10 with gcc 3.4.3, the autoconf archive macro doesn't # get the right result. XXX What about Solaris 9 and earlier? if test "$GCC" = yes ; then PTHREAD_CFLAGS="-D_REENTRANT -pthreads" fi ;; solaris*) # On Solaris 10 with gcc 3.4.3, the autoconf archive macro doesn't # get the right result. if test "$GCC" = yes ; then PTHREAD_CFLAGS="-D_REENTRANT -pthreads" fi # On Solaris 10, the thread support is always available in libc. AC_DEFINE(NO_WEAK_PTHREADS,1,[Define if references to pthread routines should be non-weak.]) ;; esac THREAD_SUPPORT=1 else PTHREAD_CC="$CC" PTHREAD_CFLAGS="" PTHREAD_LIBS="" THREAD_SUPPORT=0 fi AC_SUBST(THREAD_SUPPORT) dnl We want to know where these routines live, so on systems with weak dnl reference support we can figure out whether or not the pthread library dnl has been linked in. dnl If we don't add any libraries for thread support, don't bother. AC_CHECK_FUNCS(pthread_once pthread_rwlock_init) old_CC="$CC" test "$PTHREAD_CC" != "" && test "$ac_cv_c_compiler_gnu" = no && CC=$PTHREAD_CC old_CFLAGS="$CFLAGS" # On Solaris, -pthreads is added to CFLAGS, no extra explicit libraries. CFLAGS="$CFLAGS $PTHREAD_CFLAGS" AC_SUBST(PTHREAD_CFLAGS) old_LIBS="$LIBS" LIBS="$PTHREAD_LIBS $LIBS" AC_MSG_NOTICE(rechecking with PTHREAD_... options) AC_CHECK_LIB(c, pthread_rwlock_init, [AC_DEFINE(HAVE_PTHREAD_RWLOCK_INIT_IN_THREAD_LIB,1,[Define if pthread_rwlock_init is provided in the thread library.])]) LIBS="$old_LIBS" CC="$old_CC" CFLAGS="$old_CFLAGS" ]) dnl This is somewhat gross and should go away when the build system dnl is revamped. -- tlyu dnl DECLARE_SYS_ERRLIST - check for sys_errlist in libc dnl AC_DEFUN([DECLARE_SYS_ERRLIST], [AC_CACHE_CHECK([for sys_errlist declaration], krb5_cv_decl_sys_errlist, [AC_TRY_COMPILE([#include #include ], [1+sys_nerr;], krb5_cv_decl_sys_errlist=yes, krb5_cv_decl_sys_errlist=no)]) # assume sys_nerr won't be declared w/o being in libc if test $krb5_cv_decl_sys_errlist = yes; then AC_DEFINE(SYS_ERRLIST_DECLARED,1,[Define if sys_errlist is defined in errno.h]) AC_DEFINE(HAVE_SYS_ERRLIST,1,[Define if sys_errlist in libc]) else # This means that sys_errlist is not declared in errno.h, but may still # be in libc. AC_CACHE_CHECK([for sys_errlist in libc], krb5_cv_var_sys_errlist, [AC_TRY_LINK([extern int sys_nerr;], [if (1+sys_nerr < 0) return 1;], krb5_cv_var_sys_errlist=yes, krb5_cv_var_sys_errlist=no;)]) if test $krb5_cv_var_sys_errlist = yes; then AC_DEFINE(HAVE_SYS_ERRLIST,1,[Define if sys_errlist in libc]) # Do this cruft for backwards compatibility for now. AC_DEFINE(NEED_SYS_ERRLIST,1,[Define if need to declare sys_errlist]) else AC_MSG_WARN([sys_errlist is neither in errno.h nor in libc]) fi fi]) dnl dnl check for sigmask/sigprocmask -- CHECK_SIGPROCMASK dnl AC_DEFUN(CHECK_SIGPROCMASK,[ AC_MSG_CHECKING([for use of sigprocmask]) AC_CACHE_VAL(krb5_cv_func_sigprocmask_use, [AC_TRY_LINK([#include ], [sigprocmask(SIG_SETMASK,0,0);], krb5_cv_func_sigprocmask_use=yes, AC_TRY_LINK([#include ], [sigmask(1);], krb5_cv_func_sigprocmask_use=no, krb5_cv_func_sigprocmask_use=yes))]) AC_MSG_RESULT($krb5_cv_func_sigprocmask_use) if test $krb5_cv_func_sigprocmask_use = yes; then AC_DEFINE(USE_SIGPROCMASK,1,[Define if sigprocmask should be used]) fi ])dnl dnl AC_DEFUN(AC_PROG_ARCHIVE, [AC_CHECK_PROG(ARCHIVE, ar, ar cqv, false)])dnl AC_DEFUN(AC_PROG_ARCHIVE_ADD, [AC_CHECK_PROG(ARADD, ar, ar cruv, false)])dnl dnl dnl check for -- CHECK_DIRENT dnl (may need to be more complex later) dnl AC_DEFUN(CHECK_DIRENT,[ AC_CHECK_HEADER(dirent.h,AC_DEFINE(USE_DIRENT_H,1,[Define if you have dirent.h functionality]))])dnl dnl dnl check if union wait is defined, or if WAIT_USES_INT -- CHECK_WAIT_TYPE dnl AC_DEFUN(CHECK_WAIT_TYPE,[ AC_MSG_CHECKING([if argument to wait is int *]) AC_CACHE_VAL(krb5_cv_struct_wait, dnl Test for prototype clash - if there is none - then assume int * works [AC_TRY_COMPILE([#include #include extern pid_t wait(int *);],[], krb5_cv_struct_wait=no,dnl dnl Else fallback on old stuff [AC_TRY_COMPILE( [#include ], [union wait i; #ifdef WEXITSTATUS WEXITSTATUS (i); #endif ], krb5_cv_struct_wait=yes, krb5_cv_struct_wait=no)])]) AC_MSG_RESULT($krb5_cv_struct_wait) if test $krb5_cv_struct_wait = no; then AC_DEFINE(WAIT_USES_INT,1,[Define if wait takes int as a argument]) fi ])dnl dnl dnl check for POSIX signal handling -- CHECK_SIGNALS dnl AC_DEFUN(CHECK_SIGNALS,[ AC_CHECK_FUNC(sigprocmask, AC_MSG_CHECKING(for sigset_t and POSIX_SIGNALS) AC_CACHE_VAL(krb5_cv_type_sigset_t, [AC_TRY_COMPILE( [#include ], [sigset_t x], krb5_cv_type_sigset_t=yes, krb5_cv_type_sigset_t=no)]) AC_MSG_RESULT($krb5_cv_type_sigset_t) if test $krb5_cv_type_sigset_t = yes; then AC_DEFINE(POSIX_SIGNALS,1,[Define if POSIX signal handling is used]) fi )])dnl dnl dnl check for signal type dnl dnl AC_RETSIGTYPE isn't quite right, but almost. AC_DEFUN(KRB5_SIGTYPE,[ AC_MSG_CHECKING([POSIX signal handlers]) AC_CACHE_VAL(krb5_cv_has_posix_signals, [AC_TRY_COMPILE( [#include #include #ifdef signal #undef signal #endif extern void (*signal ()) ();], [], krb5_cv_has_posix_signals=yes, krb5_cv_has_posix_signals=no)]) AC_MSG_RESULT($krb5_cv_has_posix_signals) if test $krb5_cv_has_posix_signals = yes; then stype=void AC_DEFINE(POSIX_SIGTYPE, 1, [Define if POSIX signal handlers are used]) else if test $ac_cv_type_signal = void; then stype=void else stype=int fi fi AC_DEFINE_UNQUOTED(krb5_sigtype, $stype, [Define krb5_sigtype to type of signal handler])dnl ])dnl dnl dnl check for POSIX setjmp/longjmp -- CHECK_SETJMP dnl AC_DEFUN(CHECK_SETJMP,[ AC_CHECK_FUNC(sigsetjmp, AC_MSG_CHECKING(for sigjmp_buf) AC_CACHE_VAL(krb5_cv_struct_sigjmp_buf, [AC_TRY_COMPILE( [#include ],[sigjmp_buf x], krb5_cv_struct_sigjmp_buf=yes,krb5_cv_struct_sigjmp_buf=no)]) AC_MSG_RESULT($krb5_cv_struct_sigjmp_buf) if test $krb5_cv_struct_sigjmp_buf = yes; then AC_DEFINE(POSIX_SETJMP,1,[Define if setjmp indicates POSIX interface]) fi )])dnl dnl dnl Check for IPv6 compile-time support. dnl AC_DEFUN(KRB5_AC_INET6,[ AC_CHECK_HEADERS(sys/types.h sys/socket.h netinet/in.h netdb.h) AC_CHECK_FUNCS(inet_ntop inet_pton getnameinfo) dnl getaddrinfo test needs netdb.h, for proper compilation on alpha dnl under OSF/1^H^H^H^H^HDigital^H^H^H^H^H^H^HTru64 UNIX, where it's dnl a macro AC_MSG_CHECKING(for getaddrinfo) AC_CACHE_VAL(ac_cv_func_getaddrinfo, [AC_TRY_LINK([#ifdef HAVE_NETDB_H #include #endif],[ struct addrinfo *ai; getaddrinfo("kerberos.mit.edu", "echo", 0, &ai); ], ac_cv_func_getaddrinfo=yes, ac_cv_func_getaddrinfo=no)]) AC_MSG_RESULT($ac_cv_func_getaddrinfo) if test $ac_cv_func_getaddrinfo = yes; then AC_DEFINE(HAVE_GETADDRINFO,1,[Define if you have the getaddrinfo function]) fi dnl AC_REQUIRE([KRB5_SOCKADDR_SA_LEN])dnl AC_MSG_CHECKING(for IPv6 compile-time support without -DINET6) AC_CACHE_VAL(krb5_cv_inet6,[ if test "$ac_cv_func_inet_ntop" != "yes" ; then krb5_cv_inet6=no else AC_TRY_COMPILE([ #ifdef HAVE_SYS_TYPES_H #include #endif #include #include #include ],[ struct sockaddr_in6 in; AF_INET6; IN6_IS_ADDR_LINKLOCAL (&in.sin6_addr); ],krb5_cv_inet6=yes,krb5_cv_inet6=no)]) fi AC_MSG_RESULT($krb5_cv_inet6) if test "$krb5_cv_inet6" = no && test "$ac_cv_func_inet_ntop" = yes; then AC_MSG_CHECKING(for IPv6 compile-time support with -DINET6) AC_CACHE_VAL(krb5_cv_inet6_with_dinet6,[ old_CC="$CC" CC="$CC -DINET6" AC_TRY_COMPILE([ #ifdef HAVE_SYS_TYPES_H #include #endif #include #include #include ],[ struct sockaddr_in6 in; AF_INET6; IN6_IS_ADDR_LINKLOCAL (&in.sin6_addr); ],krb5_cv_inet6_with_dinet6=yes,krb5_cv_inet6_with_dinet6=no) CC="$old_CC"]) AC_MSG_RESULT($krb5_cv_inet6_with_dinet6) fi if test $krb5_cv_inet6 = yes || test "$krb5_cv_inet6_with_dinet6" = yes; then if test "$krb5_cv_inet6_with_dinet6" = yes; then AC_DEFINE(INET6,1,[May need to be defined to enable IPv6 support, for example on IRIX]) fi fi ])dnl dnl AC_DEFUN(KRB5_AC_CHECK_FOR_CFLAGS,[ AC_BEFORE([$0],[AC_PROG_CC]) AC_BEFORE([$0],[AC_PROG_CXX]) krb5_ac_cflags_set=${CFLAGS+set} krb5_ac_cxxflags_set=${CXXFLAGS+set} krb5_ac_warn_cflags_set=${WARN_CFLAGS+set} krb5_ac_warn_cxxflags_set=${WARN_CXXFLAGS+set} ]) dnl AC_DEFUN(TRY_WARN_CC_FLAG_1,[dnl cachevar=`echo "krb5_cv_cc_flag_$1" | sed -e s/=/_eq_/g -e s/-/_dash_/g -e s/[[^a-zA-Z0-9_]]/_/g` AC_CACHE_CHECK([if C compiler supports $1], [$cachevar], [# first try without, then with AC_TRY_COMPILE([], 1;, [old_cflags="$CFLAGS" CFLAGS="$CFLAGS $cflags_warning_test_flags $1" AC_TRY_COMPILE([], 1;, eval $cachevar=yes, eval $cachevar=no) CFLAGS="$old_cflags"], [AC_MSG_ERROR(compiling simple test program with $CFLAGS failed)])]) if eval test '"${'$cachevar'}"' = yes; then WARN_CFLAGS="$WARN_CFLAGS $1" fi eval flag_supported='${'$cachevar'}' ])dnl dnl dnl Are additional flags needed to make unsupported warning options dnl get reported as errors? AC_DEFUN(CHECK_CC_WARNING_TEST_FLAGS,[dnl cflags_warning_test_flags= TRY_WARN_CC_FLAG_1(-Werror=unknown-warning-option) if test $flag_supported = yes; then cflags_warning_test_flags=-Werror=unknown-warning-option fi ])dnl dnl AC_DEFUN(TRY_WARN_CC_FLAG,[dnl AC_REQUIRE([CHECK_CC_WARNING_TEST_FLAGS])dnl TRY_WARN_CC_FLAG_1($1)dnl ])dnl dnl AC_DEFUN(WITH_CC,[dnl AC_REQUIRE([KRB5_AC_CHECK_FOR_CFLAGS])dnl AC_REQUIRE([AC_PROG_CC])dnl AC_REQUIRE([AC_PROG_CXX])dnl if test $ac_cv_c_compiler_gnu = yes ; then HAVE_GCC=yes else HAVE_GCC= fi AC_SUBST(HAVE_GCC) AC_CACHE_CHECK([for GNU linker], krb5_cv_prog_gnu_ld, [krb5_cv_prog_gnu_ld=no if test "$GCC" = yes; then if AC_TRY_COMMAND([$CC -Wl,-v 2>&1 dnl | grep "GNU ld" > /dev/null]); then krb5_cv_prog_gnu_ld=yes fi fi]) AC_ARG_WITH([size-optimizations], [ --with-size-optimizations enable a few optimizations to reduce code size possibly at some run-time cost], , withval=no) if test "$withval" = yes; then AC_DEFINE(CONFIG_SMALL,1,[Define to reduce code size even if it means more cpu usage]) fi # -Wno-long-long, if needed, for k5-platform.h without inttypes.h etc. extra_gcc_warn_opts="-Wall -Wcast-align -Wshadow" # -Wmissing-prototypes if test "$GCC" = yes ; then # Putting this here means we get -Os after -O2, which works. if test "$with_size_optimizations" = yes && test "x$krb5_ac_cflags_set" != xset; then AC_MSG_NOTICE(adding -Os optimization option) case "$CFLAGS" in "-g -O2") CFLAGS="-g -Os" ;; "-O2") CFLAGS="-Os" ;; *) CFLAGS="$CFLAGS -Os" ;; esac fi if test "x$krb5_ac_warn_cflags_set" = xset ; then AC_MSG_NOTICE(not adding extra gcc warning flags because WARN_CFLAGS was set) else AC_MSG_NOTICE(adding extra warning flags for gcc) WARN_CFLAGS="$WARN_CFLAGS $extra_gcc_warn_opts -Wmissing-prototypes" if test "`uname -s`" = Darwin ; then AC_MSG_NOTICE(skipping pedantic warnings on Darwin) elif test "`uname -s`" = Linux ; then AC_MSG_NOTICE(skipping pedantic warnings on Linux) else WARN_CFLAGS="$WARN_CFLAGS -pedantic" fi if test "$ac_cv_cxx_compiler_gnu" = yes; then if test "x$krb5_ac_warn_cxxflags_set" = xset ; then AC_MSG_NOTICE(not adding extra g++ warnings because WARN_CXXFLAGS was set) else AC_MSG_NOTICE(adding extra warning flags for g++) WARN_CXXFLAGS="$WARN_CXXFLAGS $extra_gcc_warn_opts" fi fi # Currently, G++ does not support -Wno-format-zero-length. TRY_WARN_CC_FLAG(-Wno-format-zero-length) # Other flags here may not be supported on some versions of # gcc that people want to use. for flag in overflow strict-overflow missing-format-attribute missing-prototypes return-type missing-braces parentheses switch unused-function unused-label unused-variable unused-value unknown-pragmas sign-compare newline-eof error=uninitialized no-maybe-uninitialized error=pointer-arith error=int-conversion error=incompatible-pointer-types error=discarded-qualifiers error=implicit-int ; do TRY_WARN_CC_FLAG(-W$flag) done # old-style-definition? generates many, many warnings # # Warnings that we'd like to turn into errors on versions of gcc # that support promoting only specific warnings to errors, but # we'll take as warnings on older compilers. (If such a warning # is added after the -Werror=foo feature, you can just put # error=foo in the above list, and skip the test for the # warning-only form.) At least in some versions, -Werror= doesn't # seem to make the conditions actual errors, but still issues # warnings; I guess we'll take what we can get. # # We're currently targeting C89+, not C99, so disallow some # constructs. for flag in declaration-after-statement ; do TRY_WARN_CC_FLAG(-Werror=$flag) if test "$flag_supported" = no; then TRY_WARN_CC_FLAG(-W$flag) fi done # We require function declarations now. # # In some compiler versions -- e.g., "gcc version 4.2.1 (Apple # Inc. build 5664)" -- the -Werror- option works, but the -Werror= # version doesn't cause implicitly declared functions to be # flagged as errors. If neither works, -Wall implies # -Wimplicit-function-declaration so don't bother. TRY_WARN_CC_FLAG(-Werror-implicit-function-declaration) if test "implicit-function-declaration_supported" = no; then TRY_WARN_CC_FLAG(-Werror=implicit-function-declaration) fi # fi if test "`uname -s`" = Darwin ; then # Someday this should be a feature test. # One current (Jaguar = OS 10.2) problem: # Archive library with foo.o undef sym X and bar.o common sym X, # if foo.o is pulled in at link time, bar.o may not be, causing # the linker to complain. # Dynamic library problems too? case "$CC $CFLAGS" in *-fcommon*) ;; # why someone would do this, I don't know *-fno-common*) ;; # okay, they're already doing the right thing *) AC_MSG_NOTICE(disabling the use of common storage on Darwin) CFLAGS="$CFLAGS -fno-common" ;; esac case "$LD $LDFLAGS" in *-Wl,-search_paths_first*) ;; *) LDFLAGS="${LDFLAGS} -Wl,-search_paths_first" ;; esac fi else if test "`uname -s`" = AIX ; then # Using AIX but not GCC, assume native compiler. # The native compiler appears not to give a nonzero exit # status for certain classes of errors, like missing arguments # in function calls. Let's try to fix that with -qhalt=e. case "$CC $CFLAGS" in *-qhalt=*) ;; *) CFLAGS="$CFLAGS -qhalt=e" AC_MSG_NOTICE(adding -qhalt=e for better error reporting) ;; esac # Also, the optimizer isn't turned on by default, which means # the static inline functions get left in random object files, # leading to references to pthread_mutex_lock from anything that # includes k5-int.h whether it uses threads or not. case "$CC $CFLAGS" in *-O*) ;; *) CFLAGS="$CFLAGS -O" AC_MSG_NOTICE(adding -O for inline thread-support function elimination) ;; esac fi if test "`uname -s`" = SunOS ; then # Using Solaris but not GCC, assume Sunsoft compiler. # We have some error-out-on-warning options available. # Sunsoft 12 compiler defaults to -xc99=all, it appears, so "inline" # works, but it also means that declaration-in-code warnings won't # be issued. # -v -fd -errwarn=E_DECLARATION_IN_CODE ... if test "x$krb5_ac_warn_cflags_set" = xset ; then AC_MSG_NOTICE(not adding extra warning flags because WARN_CFLAGS was set) else WARN_CFLAGS="-errtags=yes -errwarn=E_BAD_PTR_INT_COMBINATION,E_BAD_PTR_INT_COMB_ARG,E_PTR_TO_VOID_IN_ARITHMETIC,E_NO_IMPLICIT_DECL_ALLOWED,E_ATTRIBUTE_PARAM_UNDEFINED" fi if test "x$krb5_ac_warn_cxxflags_set" = xset ; then AC_MSG_NOTICE(not adding extra warning flags because WARN_CXXFLAGS was set) else WARN_CXXFLAGS="-errtags=yes +w +w2 -xport64" fi fi fi AC_SUBST(WARN_CFLAGS) AC_SUBST(WARN_CXXFLAGS) ])dnl dnl dnl dnl check for yylineno -- HAVE_YYLINENO dnl AC_DEFUN(HAVE_YYLINENO,[dnl AC_REQUIRE_CPP()AC_REQUIRE([AC_PROG_LEX])dnl AC_MSG_CHECKING([for yylineno declaration]) AC_CACHE_VAL(krb5_cv_type_yylineno, # some systems have yylineno, others don't... echo '%% %%' | ${LEX} -t > conftest.out if egrep yylineno conftest.out >/dev/null 2>&1; then krb5_cv_type_yylineno=yes else krb5_cv_type_yylineno=no fi rm -f conftest.out) AC_MSG_RESULT($krb5_cv_type_yylineno) if test $krb5_cv_type_yylineno = no; then AC_DEFINE(NO_YYLINENO, 1, [Define if lex produes code with yylineno]) fi ])dnl dnl dnl K5_GEN_MAKEFILE([dir, [frags]]) dnl AC_DEFUN(K5_GEN_MAKEFILE,[dnl ifelse($1, ,[_K5_GEN_MAKEFILE(.,$2)],[_K5_GEN_MAKEFILE($1,$2)]) ]) dnl dnl _K5_GEN_MAKEFILE(dir, [frags]) dnl dir must be present in this case dnl Note: Be careful in quoting. dnl The ac_foreach generates the list of fragments to include dnl or "" if $2 is empty AC_DEFUN(_K5_GEN_MAKEFILE,[dnl AC_CONFIG_FILES([$1/Makefile:$srcdir/]K5_TOPDIR[/config/pre.in:$1/Makefile.in:$1/deps:$srcdir/]K5_TOPDIR[/config/post.in]) ]) dnl dnl K5_GEN_FILE( ) dnl AC_DEFUN(K5_GEN_FILE,[AC_CONFIG_FILES($1)])dnl dnl dnl K5_AC_OUTPUT dnl Note: Adds the variables to config.status for individual dnl Makefile generation from config.status AC_DEFUN(K5_AC_OUTPUT,[AC_OUTPUT])dnl dnl dnl V5_AC_OUTPUT_MAKEFILE dnl AC_DEFUN(V5_AC_OUTPUT_MAKEFILE, [ifelse($1, , [_V5_AC_OUTPUT_MAKEFILE(.,$2)],[_V5_AC_OUTPUT_MAKEFILE($1,$2)])]) dnl define(_V5_AC_OUTPUT_MAKEFILE, [ifelse($2, , ,AC_CONFIG_FILES($2)) AC_FOREACH([DIR], [$1],dnl [AC_CONFIG_FILES(DIR[/Makefile:$srcdir/]K5_TOPDIR[/config/pre.in:]DIR[/Makefile.in:]DIR[/deps:$srcdir/]K5_TOPDIR[/config/post.in])]) K5_AC_OUTPUT])dnl dnl dnl dnl KRB5_SOCKADDR_SA_LEN: define HAVE_SA_LEN if sockaddr contains the sa_len dnl component dnl AC_DEFUN([KRB5_SOCKADDR_SA_LEN],[ dnl AC_CHECK_MEMBER(struct sockaddr.sa_len, AC_DEFINE(HAVE_SA_LEN,1,[Define if struct sockaddr contains sa_len]) ,,[#include #include ])]) dnl dnl WITH_NETLIB dnl dnl AC_DEFUN(WITH_NETLIB,[ AC_ARG_WITH([netlib], AC_HELP_STRING([--with-netlib=LIBS], use user defined resolver library), [ if test "$withval" = yes -o "$withval" = no ; then AC_MSG_RESULT("netlib will link with C library resolver only") else LIBS="$LIBS $withval" AC_MSG_RESULT("netlib will use \'$withval\'") fi ],dnl [AC_LIBRARY_NET] )])dnl dnl dnl AC_DEFUN(KRB5_AC_NEED_DAEMON, [ KRB5_NEED_PROTO([#ifdef HAVE_UNISTD_H #include #endif],daemon,1)])dnl dnl dnl KRB5_AC_NEED_LIBGEN --- check if libgen needs to be linked in for dnl compile/step dnl dnl AC_DEFUN(KRB5_AC_NEED_LIBGEN,[ AC_REQUIRE([AC_PROG_CC])dnl dnl dnl regcomp is present but non-functional on Solaris 2.4 dnl AC_MSG_CHECKING(for working regcomp) AC_CACHE_VAL(ac_cv_func_regcomp,[ AC_TRY_RUN([ #include #include regex_t x; regmatch_t m; int main() { return regcomp(&x,"pat.*",0) || regexec(&x,"pattern",1,&m,0); } ], ac_cv_func_regcomp=yes, ac_cv_func_regcomp=no, AC_MSG_ERROR([Cannot test regcomp when cross compiling]))]) AC_MSG_RESULT($ac_cv_func_regcomp) test $ac_cv_func_regcomp = yes && AC_DEFINE(HAVE_REGCOMP,1,[Define if regcomp exists and functions]) dnl dnl Check for the compile and step functions - only if regcomp is not available dnl if test $ac_cv_func_regcomp = no; then save_LIBS="$LIBS" LIBS=-lgen dnl this will fail if there's no compile/step in -lgen, or if there's dnl no -lgen. This is fine. AC_CHECK_FUNCS(compile step) LIBS="$save_LIBS" dnl dnl Set GEN_LIB if necessary dnl AC_CHECK_LIB(gen, compile, GEN_LIB=-lgen, GEN_LIB=) AC_SUBST(GEN_LIB) fi ]) dnl dnl KRB5_AC_REGEX_FUNCS --- check for different regular expression dnl support functions dnl AC_DEFUN(KRB5_AC_REGEX_FUNCS,[ AC_CHECK_FUNCS(re_comp re_exec regexec) AC_REQUIRE([KRB5_AC_NEED_LIBGEN])dnl ])dnl dnl dnl AC_KRB5_TCL_FIND_CONFIG (uses tcl_dir) dnl AC_DEFUN(AC_KRB5_TCL_FIND_CONFIG,[ AC_REQUIRE([KRB5_LIB_AUX])dnl AC_MSG_CHECKING(for tclConfig.sh) dnl On Debian, we might be given --with-tcl=/usr, or tclsh might dnl point us to /usr/lib/tcl8.4; either way, we need to find dnl /usr/lib/tcl8.4/tclConfig.sh. dnl On NetBSD, we might be given --with-tcl=/usr/pkg, or tclsh dnl might point us to /usr/pkg/lib/tcl8.4; we need to find dnl /usr/pkg/lib/tclConfig.sh. if test -r "$tcl_dir/lib/tclConfig.sh" ; then tcl_conf="$tcl_dir/lib/tclConfig.sh" elif test -r "$tcl_dir/tclConfig.sh" ; then tcl_conf="$tcl_dir/tclConfig.sh" elif test -r "$tcl_dir/../tclConfig.sh" ; then tcl_conf="$tcl_dir/../tclConfig.sh" else tcl_conf= lib="$tcl_dir/lib" changequote(<<,>>)dnl for d in "$lib" "$lib"/tcl7.[0-9] "$lib"/tcl8.[0-9] ; do if test -r "$d/tclConfig.sh" ; then tcl_conf="$tcl_conf $d/tclConfig.sh" fi done changequote([,])dnl fi if test -n "$tcl_conf" ; then AC_MSG_RESULT($tcl_conf) else AC_MSG_RESULT(not found) fi tcl_ok_conf= tcl_vers_maj= tcl_vers_min= old_CPPFLAGS=$CPPFLAGS old_LIBS=$LIBS old_LDFLAGS=$LDFLAGS if test -n "$tcl_conf" ; then for file in $tcl_conf ; do TCL_MAJOR_VERSION=x ; TCL_MINOR_VERSION=x AC_MSG_CHECKING(Tcl info in $file) . $file v=$TCL_MAJOR_VERSION.$TCL_MINOR_VERSION if test -z "$tcl_vers_maj" \ || test "$tcl_vers_maj" -lt "$TCL_MAJOR_VERSION" \ || test "$tcl_vers_maj" = "$TCL_MAJOR_VERSION" -a "$tcl_vers_min" -lt "$TCL_MINOR_VERSION" ; then for incdir in "$TCL_PREFIX/include/tcl$v" "$TCL_PREFIX/include" ; do if test -r "$incdir/tcl.h" -o -r "$incdir/tcl/tcl.h" ; then CPPFLAGS="$old_CPPFLAGS -I$incdir" break fi done LIBS="$old_LIBS `eval echo x $TCL_LIB_SPEC $TCL_LIBS | sed 's/^x//'`" LDFLAGS="$old_LDFLAGS $TCL_LD_FLAGS" AC_TRY_LINK( , [Tcl_CreateInterp ();], tcl_ok_conf=$file tcl_vers_maj=$TCL_MAJOR_VERSION tcl_vers_min=$TCL_MINOR_VERSION AC_MSG_RESULT($v - working), AC_MSG_RESULT($v - compilation failed) ) else AC_MSG_RESULT(older version $v) fi done fi CPPFLAGS=$old_CPPFLAGS LIBS=$old_LIBS LDFLAGS=$old_LDFLAGS tcl_header=no tcl_lib=no if test -n "$tcl_ok_conf" ; then . $tcl_ok_conf TCL_INCLUDES= for incdir in "$TCL_PREFIX/include/tcl$v" "$TCL_PREFIX/include" ; do if test -r "$incdir/tcl.h" -o -r "$incdir/tcl/tcl.h" ; then if test "$incdir" != "/usr/include" ; then TCL_INCLUDES=-I$incdir fi break fi done # Need eval because the first-level expansion could reference # variables like ${TCL_DBGX}. eval TCL_LIBS='"'$TCL_LIB_SPEC $TCL_LIBS $TCL_DL_LIBS'"' TCL_LIBPATH="-L$TCL_EXEC_PREFIX/lib" TCL_RPATH=":$TCL_EXEC_PREFIX/lib" if test "$DEPLIBEXT" != "$SHLIBEXT" && test -n "$RPATH_FLAG"; then TCL_MAYBE_RPATH='$(RPATH_FLAG)'"$TCL_EXEC_PREFIX/lib$RPATH_TAIL" else TCL_MAYBE_RPATH= fi CPPFLAGS="$old_CPPFLAGS $TCL_INCLUDES" AC_CHECK_HEADER(tcl.h,AC_DEFINE(HAVE_TCL_H,1,[Define if tcl.h is available]) tcl_header=yes) if test $tcl_header=no; then AC_CHECK_HEADER(tcl/tcl.h,AC_DEFINE(HAVE_TCL_TCL_H,1,[Define if tcl/tcl.h is available]) tcl_header=yes) fi CPPFLAGS="$old_CPPFLAGS" tcl_lib=yes else # If we read a tclConfig.sh file, it probably set this. TCL_LIBS= fi AC_SUBST(TCL_INCLUDES) AC_SUBST(TCL_LIBS) AC_SUBST(TCL_LIBPATH) AC_SUBST(TCL_RPATH) AC_SUBST(TCL_MAYBE_RPATH) ])dnl dnl dnl AC_KRB5_TCL_TRYOLD dnl attempt to use old search algorithm for locating tcl dnl AC_DEFUN(AC_KRB5_TCL_TRYOLD, [ AC_REQUIRE([KRB5_AC_FIND_DLOPEN]) AC_MSG_WARN([trying old tcl search code]) if test "$with_tcl" != yes -a "$with_tcl" != no; then TCL_INCLUDES=-I$with_tcl/include TCL_LIBPATH=-L$with_tcl/lib TCL_RPATH=:$with_tcl/lib fi if test "$with_tcl" != no ; then krb5_save_CPPFLAGS="$CPPFLAGS" krb5_save_LDFLAGS="$LDFLAGS" CPPFLAGS="$CPPFLAGS $TCL_INCLUDES" LDFLAGS="$LDFLAGS $TCL_LIBPATH" tcl_header=no AC_CHECK_HEADER(tcl.h,AC_DEFINE(HAVE_TCL_H,1,[Define if tcl.h found]) tcl_header=yes) if test $tcl_header=no; then AC_CHECK_HEADER(tcl/tcl.h,AC_DEFINE(HAVE_TCL_TCL_H,1,[Define if tcl/tcl.h found]) tcl_header=yes) fi if test $tcl_header = yes ; then tcl_lib=no if test $tcl_lib = no; then AC_CHECK_LIB(tcl8.0, Tcl_CreateCommand, TCL_LIBS="$TCL_LIBS -ltcl8.0 -lm $DL_LIB $LIBS" tcl_lib=yes,,-lm $DL_LIB) fi if test $tcl_lib = no; then AC_CHECK_LIB(tcl7.6, Tcl_CreateCommand, TCL_LIBS="$TCL_LIBS -ltcl7.6 -lm $DL_LIB $LIBS" tcl_lib=yes,,-lm $DL_LIB) fi if test $tcl_lib = no; then AC_CHECK_LIB(tcl7.5, Tcl_CreateCommand, TCL_LIBS="$TCL_LIBS -ltcl7.5 -lm $DL_LIB $LIBS" tcl_lib=yes,,-lm $DL_LIB) fi if test $tcl_lib = no ; then AC_CHECK_LIB(tcl, Tcl_CreateCommand, TCL_LIBS="$TCL_LIBS -ltcl -lm $DL_LIB $LIBS" tcl_lib=yes,,-lm $DL_LIB) fi if test $tcl_lib = no ; then AC_MSG_WARN("tcl.h found but not library") fi else AC_MSG_WARN(Could not find Tcl which is needed for the kadm5 tests) TCL_LIBS= fi CPPFLAGS="$krb5_save_CPPFLAGS" LDFLAGS="$krb5_save_LDFLAGS" AC_SUBST(TCL_INCLUDES) AC_SUBST(TCL_LIBS) AC_SUBST(TCL_LIBPATH) AC_SUBST(TCL_RPATH) else AC_MSG_RESULT("Not looking for Tcl library") fi ])dnl dnl dnl AC_KRB5_TCL - determine if the TCL library is present on system dnl AC_DEFUN(AC_KRB5_TCL,[ TCL_INCLUDES= TCL_LIBPATH= TCL_RPATH= TCL_LIBS= TCL_WITH= tcl_dir= AC_ARG_WITH(tcl, [ --with-tcl=path where Tcl resides], , with_tcl=try) if test "$with_tcl" = no ; then true elif test "$with_tcl" = yes -o "$with_tcl" = try ; then tcl_dir=/usr if test ! -r /usr/lib/tclConfig.sh; then cat >> conftest <<\EOF puts "tcl_dir=$tcl_library" EOF if tclsh conftest >conftest.out 2>/dev/null; then if grep tcl_dir= conftest.out >/dev/null 2>&1; then t=`sed s/tcl_dir=// conftest.out` tcl_dir=$t fi fi # tclsh ran script okay rm -f conftest conftest.out fi # no /usr/lib/tclConfig.sh else tcl_dir=$with_tcl fi if test "$with_tcl" != no ; then AC_KRB5_TCL_FIND_CONFIG if test $tcl_lib = no ; then if test "$with_tcl" != try ; then AC_KRB5_TCL_TRYOLD else AC_MSG_WARN(Could not find Tcl which is needed for some tests) fi fi fi # If "yes" or pathname, error out if not found. if test "$with_tcl" != no -a "$with_tcl" != try ; then if test "$tcl_header $tcl_lib" != "yes yes" ; then AC_MSG_ERROR(Could not find Tcl) fi fi ])dnl dnl dnl WITH_HESIOD dnl AC_DEFUN(WITH_HESIOD, [AC_ARG_WITH(hesiod, AC_HELP_STRING(--with-hesiod[=path], compile with hesiod support @<:@omitted@:>@), hesiod=$with_hesiod, with_hesiod=no) if test "$with_hesiod" != "no"; then HESIOD_DEFS=-DHESIOD AC_CHECK_LIB(resolv, res_send, res_lib=-lresolv) if test "$hesiod" != "yes"; then HESIOD_LIBS="-L${hesiod}/lib -lhesiod $res_lib" else HESIOD_LIBS="-lhesiod $res_lib" fi else HESIOD_DEFS= HESIOD_LIBS= fi AC_SUBST(HESIOD_DEFS) AC_SUBST(HESIOD_LIBS)]) dnl dnl KRB5_BUILD_LIBRARY dnl dnl Pull in the necessary stuff to create the libraries. AC_DEFUN(KRB5_BUILD_LIBRARY, [AC_REQUIRE([KRB5_LIB_AUX])dnl AC_REQUIRE([AC_PROG_LN_S])dnl AC_REQUIRE([AC_PROG_RANLIB])dnl AC_REQUIRE([AC_PROG_ARCHIVE])dnl AC_REQUIRE([AC_PROG_ARCHIVE_ADD])dnl AC_REQUIRE([AC_PROG_INSTALL])dnl AC_CHECK_PROG(AR, ar, ar, false) if test "$AR" = "false"; then AC_MSG_ERROR([ar not found in PATH]) fi AC_CHECK_PROG(PERL, perl, perl, false) if test "$ac_cv_prog_PERL" = "false"; then AC_MSG_ERROR(Perl is now required for Kerberos builds.) fi AC_SUBST(LIBLIST) AC_SUBST(LIBLINKS) AC_SUBST(PLUGIN) AC_SUBST(PLUGINLINK) AC_SUBST(PLUGININST) AC_SUBST(KDB5_PLUGIN_DEPLIBS) AC_SUBST(KDB5_PLUGIN_LIBS) AC_SUBST(MAKE_SHLIB_COMMAND) AC_SUBST(SHLIB_RPATH_FLAGS) AC_SUBST(SHLIB_EXPFLAGS) AC_SUBST(SHLIB_EXPORT_FILE_DEP) AC_SUBST(DYNOBJ_EXPDEPS) AC_SUBST(DYNOBJ_EXPFLAGS) AC_SUBST(INSTALL_SHLIB) AC_SUBST(STLIBEXT) AC_SUBST(SHLIBEXT) AC_SUBST(SHLIBVEXT) AC_SUBST(SHLIBSEXT) AC_SUBST(DEPLIBEXT) AC_SUBST(PFLIBEXT) AC_SUBST(LIBINSTLIST) AC_SUBST(DYNOBJEXT) AC_SUBST(MAKE_DYNOBJ_COMMAND) AC_SUBST(UNDEF_CHECK) ]) dnl dnl KRB5_BUILD_LIBOBJS dnl dnl Pull in the necessary stuff to build library objects. AC_DEFUN(KRB5_BUILD_LIBOBJS, [AC_REQUIRE([KRB5_LIB_AUX])dnl AC_SUBST(OBJLISTS) AC_SUBST(STOBJEXT) AC_SUBST(SHOBJEXT) AC_SUBST(PFOBJEXT) AC_SUBST(PICFLAGS) AC_SUBST(PROFFLAGS)]) dnl dnl KRB5_BUILD_PROGRAM dnl dnl Set variables to build a program. AC_DEFUN(KRB5_BUILD_PROGRAM, [AC_REQUIRE([KRB5_LIB_AUX])dnl AC_REQUIRE([KRB5_AC_NEED_LIBGEN])dnl AC_SUBST(CC_LINK) AC_SUBST(CXX_LINK) AC_SUBST(RPATH_FLAG) AC_SUBST(PROG_RPATH_FLAGS) AC_SUBST(DEPLIBEXT)]) dnl dnl KRB5_RUN_FLAGS dnl dnl Set up environment for running dynamic executables out of build tree AC_DEFUN(KRB5_RUN_FLAGS, [AC_REQUIRE([KRB5_LIB_AUX])dnl KRB5_RUN_ENV="$RUN_ENV" KRB5_RUN_VARS="$RUN_VARS" AC_SUBST(KRB5_RUN_ENV) AC_SUBST(KRB5_RUN_VARS)]) dnl dnl KRB5_LIB_AUX dnl dnl Parse configure options related to library building. AC_DEFUN(KRB5_LIB_AUX, [AC_REQUIRE([KRB5_LIB_PARAMS])dnl AC_ARG_ENABLE([static],,, [enable_static=no]) AC_ARG_ENABLE([shared],,, [enable_shared=yes]) if test "x$enable_static" = "x$enable_shared"; then AC_MSG_ERROR([--enable-static must be specified with --disable-shared]) fi AC_ARG_ENABLE([rpath], AC_HELP_STRING([--disable-rpath],[suppress run path flags in link lines]),, [enable_rpath=yes]) if test "x$enable_rpath" != xyes ; then # Unset the rpath flag values set by shlib.conf SHLIB_RPATH_FLAGS= RPATH_FLAG= PROG_RPATH_FLAGS= fi if test "$SHLIBEXT" = ".so-nobuild"; then AC_MSG_ERROR([Shared libraries are not yet supported on this platform.]) fi DEPLIBEXT=$SHLIBEXT if test "x$enable_static" = xyes; then AC_MSG_NOTICE([using static libraries]) LIBLIST='lib$(LIBBASE)$(STLIBEXT)' LIBLINKS='$(TOPLIBD)/lib$(LIBBASE)$(STLIBEXT)' PLUGIN='libkrb5_$(LIBBASE)$(STLIBEXT)' PLUGINLINK='$(TOPLIBD)/libkrb5_$(LIBBASE)$(STLIBEXT)' PLUGININST=install-static OBJLISTS=OBJS.ST LIBINSTLIST=install-static DEPLIBEXT=$STLIBEXT AC_DEFINE([STATIC_PLUGINS], 1, [Define for static plugin linkage]) KDB5_PLUGIN_DEPLIBS='$(TOPLIBD)/libkrb5_db2$(DEPLIBEXT)' KDB5_PLUGIN_LIBS='-lkrb5_db2' if test "x$OPENLDAP_PLUGIN" = xyes; then KDB5_PLUGIN_DEBLIBS=$KDB5_PLUGIN_DEPLIBS' $(TOPLIBD)/libkrb5_ldap$(DEPLIBEXT) $(TOPLIBD)/libkdb_ldap$(DEPLIBEXT)' KDB5_PLUGIN_LIBS=$KDB5_PLUGIN_LIBS' -lkrb5_kldap -lkdb_ldap $(LDAP_LIBS)' fi # kadm5srv_mit normally comes before kdb on the link line. Add it # again after the KDB plugins, since they depend on it for XDR stuff. KDB5_PLUGIN_DEPLIBS=$KDB5_PLUGIN_DEPLIBS' $(TOPLIBD)/libkadm5srv_mit$(DEPLIBEXT)' KDB5_PLUGIN_LIBS=$KDB5_PLUGIN_LIBS' -lkadm5srv_mit' # avoid duplicate rules generation for AIX and such SHLIBEXT=.so-nobuild SHLIBVEXT=.so.v-nobuild SHLIBSEXT=.so.s-nobuild else AC_MSG_NOTICE([using shared libraries]) # Clear some stuff in case of AIX, etc. if test "$STLIBEXT" = "$SHLIBEXT" ; then STLIBEXT=.a-nobuild fi case "$SHLIBSEXT" in .so.s-nobuild) LIBLIST='lib$(LIBBASE)$(SHLIBEXT)' LIBLINKS='$(TOPLIBD)/lib$(LIBBASE)$(SHLIBEXT) $(TOPLIBD)/lib$(LIBBASE)$(SHLIBVEXT)' LIBINSTLIST="install-shared" ;; *) LIBLIST='lib$(LIBBASE)$(SHLIBEXT) lib$(LIBBASE)$(SHLIBSEXT)' LIBLINKS='$(TOPLIBD)/lib$(LIBBASE)$(SHLIBEXT) $(TOPLIBD)/lib$(LIBBASE)$(SHLIBVEXT) $(TOPLIBD)/lib$(LIBBASE)$(SHLIBSEXT)' LIBINSTLIST="install-shlib-soname" ;; esac OBJLISTS="OBJS.SH" PLUGIN='$(LIBBASE)$(DYNOBJEXT)' PLUGINLINK='../$(PLUGIN)' PLUGININST=install-plugin KDB5_PLUGIN_DEPLIBS= KDB5_PLUGIN_LIBS= fi CC_LINK="$CC_LINK_SHARED" CXX_LINK="$CXX_LINK_SHARED" if test -z "$LIBLIST"; then AC_MSG_ERROR([must enable one of shared or static libraries]) fi # Check whether to build profiled libraries. AC_ARG_ENABLE([profiled], dnl [ --enable-profiled build profiled libraries @<:@disabled@:>@] , [if test "$enableval" = yes; then AC_MSG_ERROR([Sorry, profiled libraries do not work in this release.]) fi])]) dnl dnl KRB5_LIB_PARAMS dnl dnl Determine parameters related to libraries, e.g. various extensions. AC_DEFUN(KRB5_LIB_PARAMS, [AC_REQUIRE([AC_CANONICAL_HOST])dnl krb5_cv_host=$host AC_SUBST(krb5_cv_host) AC_REQUIRE([AC_PROG_CC])dnl AC_REQUIRE([V5_SET_TOPDIR])dnl . $ac_topdir/config/shlib.conf]) dnl dnl The following was written by jhawk@mit.edu dnl dnl AC_LIBRARY_NET: Id: net.m4,v 1.4 1997/10/25 20:49:53 jhawk Exp dnl dnl This test is for network applications that need socket() and dnl gethostbyname() -ish functions. Under Solaris, those applications need to dnl link with "-lsocket -lnsl". Under IRIX, they should *not* link with dnl "-lsocket" because libsocket.a breaks a number of things (for instance: dnl gethostbyname() under IRIX 5.2, and snoop sockets under most versions of dnl IRIX). dnl dnl Unfortunately, many application developers are not aware of this, and dnl mistakenly write tests that cause -lsocket to be used under IRIX. It is dnl also easy to write tests that cause -lnsl to be used under operating dnl systems where neither are necessary (or useful), such as SunOS 4.1.4, which dnl uses -lnsl for TLI. dnl dnl This test exists so that every application developer does not test this in dnl a different, and subtly broken fashion. dnl dnl It has been argued that this test should be broken up into two seperate dnl tests, one for the resolver libraries, and one for the libraries necessary dnl for using Sockets API. Unfortunately, the two are carefully intertwined and dnl allowing the autoconf user to use them independantly potentially results in dnl unfortunate ordering dependancies -- as such, such component macros would dnl have to carefully use indirection and be aware if the other components were dnl executed. Since other autoconf macros do not go to this trouble, and almost dnl no applications use sockets without the resolver, this complexity has not dnl been implemented. dnl dnl The check for libresolv is in case you are attempting to link statically dnl and happen to have a libresolv.a lying around (and no libnsl.a). dnl AC_DEFUN(AC_LIBRARY_NET, [ # Most operating systems have gethostbyname() in the default searched # libraries (i.e. libc): AC_CHECK_FUNC(gethostbyname, , [ # Some OSes (eg. Solaris) place it in libnsl: AC_CHECK_LIB(nsl, gethostbyname, , [ # Some strange OSes (SINIX) have it in libsocket: AC_CHECK_LIB(socket, gethostbyname, , [ # Unfortunately libsocket sometimes depends on libnsl. # AC_CHECK_LIB's API is essentially broken so the following # ugliness is necessary: AC_CHECK_LIB(socket, gethostbyname, LIBS="-lsocket -lnsl $LIBS", [AC_CHECK_LIB(resolv, gethostbyname, LIBS="-lresolv $LIBS" )], -lnsl) ]) ]) ]) AC_CHECK_FUNC(socket, , AC_CHECK_LIB(socket, socket, , AC_CHECK_LIB(socket, socket, LIBS="-lsocket -lnsl $LIBS", , -lnsl))) KRB5_AC_ENABLE_DNS if test "$enable_dns" = yes ; then # We assume that if libresolv exists we can link against it. # This may get us a gethostby* that doesn't respect nsswitch. AC_CHECK_LIB(resolv, main) _KRB5_AC_CHECK_RES_FUNCS(res_ninit res_nclose res_ndestroy res_nsearch dnl ns_initparse ns_name_uncompress dn_skipname res_search) if test $krb5_cv_func_res_nsearch = no \ && test $krb5_cv_func_res_search = no; then # Attempt to link with res_search(), in case it's not prototyped. AC_CHECK_FUNC(res_search, [AC_DEFINE(HAVE_RES_SEARCH, 1, [Define to 1 if you have the `res_search' function])], [AC_ERROR([cannot find res_nsearch or res_search])]) fi fi ]) AC_DEFUN([_KRB5_AC_CHECK_RES_FUNCS], [AC_FOREACH([AC_Func], [$1], [AH_TEMPLATE(AS_TR_CPP(HAVE_[]AC_Func), [Define to 1 if you have the `]AC_Func[' function.])])dnl for krb5_func in $1; do _KRB5_AC_CHECK_RES_FUNC($krb5_func) done ]) AC_DEFUN([_KRB5_AC_CHECK_RES_FUNC], [ # Solaris 9 prototypes ns_name_uncompress() in arpa/nameser.h, but # doesn't export it from libresolv.so, so we use extreme paranoia here # and check both for the declaration and that we can link against the # function. AC_CACHE_CHECK([for $1], [krb5_cv_func_$1], [AC_TRY_LINK( [#include #include #include @%:@include ], [/* * Use volatile, or else optimization can cause false positives. */ void (* volatile p)() = (void (*)())$1;], [AS_VAR_SET(krb5_cv_func_$1, yes)], [AS_VAR_SET(krb5_cv_func_$1, no)])]) AS_IF([test AS_VAR_GET(krb5_cv_func_$1) = yes], [AC_DEFINE_UNQUOTED(AS_TR_CPP([HAVE_$1]), 1, [Define to 1 if you have the `$1' function])])[]dnl ]) dnl dnl dnl KRB5_AC_ENABLE_DNS dnl AC_DEFUN(KRB5_AC_ENABLE_DNS, [ enable_dns=yes AC_ARG_ENABLE([dns-for-realm], [ --enable-dns-for-realm enable DNS lookups of Kerberos realm names], , [enable_dns_for_realm=no]) if test "$enable_dns_for_realm" = yes; then AC_DEFINE(KRB5_DNS_LOOKUP_REALM,1,[Define to enable DNS lookups of Kerberos realm names]) fi AC_DEFINE(KRB5_DNS_LOOKUP, 1,[Define for DNS support of locating realms and KDCs]) ]) dnl dnl dnl Check if we need the prototype for a function - we give it a bogus dnl prototype and if it complains - then a valid prototype exists on the dnl system. dnl dnl KRB5_NEED_PROTO(includes, function, [bypass]) dnl if $3 set, don't see if library defined. dnl Useful for case where we will define in libkrb5 the function if need be dnl but want to know if a prototype exists in either case on system. dnl AC_DEFUN([KRB5_NEED_PROTO], [ ifelse([$3], ,[if test "x$ac_cv_func_$2" = xyes; then]) AC_CACHE_CHECK([if $2 needs a prototype provided], krb5_cv_func_$2_noproto, AC_TRY_COMPILE([$1], [#undef $2 struct k5foo {int foo; } xx; extern int $2 (struct k5foo*); $2(&xx); ], krb5_cv_func_$2_noproto=yes,krb5_cv_func_$2_noproto=no)) if test $krb5_cv_func_$2_noproto = yes; then AC_DEFINE([NEED_]translit($2, [a-z], [A-Z])[_PROTO], 1, dnl [define if the system header files are missing prototype for $2()]) fi ifelse([$3], ,[fi]) ]) dnl dnl ============================================================= dnl Internal function for testing for getpeername prototype dnl AC_DEFUN([KRB5_GETPEERNAME_ARGS],[ AC_DEFINE([GETPEERNAME_ARG3_TYPE],GETSOCKNAME_ARG3_TYPE,[Type of getpeername second argument.]) ]) dnl dnl ============================================================= dnl Internal function for testing for getsockname arguments dnl AC_DEFUN([TRY_GETSOCK_INT],[ krb5_lib_var=`echo "$1 $2" | sed 'y% ./+-*%___p_p%'` AC_MSG_CHECKING([if getsockname() takes arguments $1 and $2]) AC_CACHE_VAL(krb5_cv_getsockname_proto_$krb5_lib_var, [ AC_TRY_COMPILE([#include #include extern int getsockname(int, $1, $2); ],,eval "krb5_cv_getsockname_proto_$krb5_lib_var=yes", eval "krb5_cv_getsockname_proto_$krb5_lib_var=no")]) if eval "test \"`echo '$krb5_cv_getsockname_proto_'$krb5_lib_var`\" = yes"; then AC_MSG_RESULT(yes) sock_set=yes; res1="$1"; res2="$2" else AC_MSG_RESULT(no) fi ]) dnl dnl Determines the types of the second and third arguments to getsockname(). dnl AC_DEFUN([KRB5_GETSOCKNAME_ARGS],[ sock_set=no for sock_arg1 in "struct sockaddr *" "void *" do for sock_arg2 in "size_t *" "int *" "socklen_t *" do if test $sock_set = no; then TRY_GETSOCK_INT($sock_arg1, $sock_arg2) fi done done if test "$sock_set" = no; then AC_MSG_NOTICE(assuming struct sockaddr and socklen_t for getsockname args) res1="struct sockaddr *" res2="socklen_t *" fi res1=`echo "$res1" | tr -d '*' | sed -e 's/ *$//'` res2=`echo "$res2" | tr -d '*' | sed -e 's/ *$//'` AC_DEFINE_UNQUOTED([GETSOCKNAME_ARG3_TYPE],$res2,[Type of pointer target for argument 3 to getsockname]) ]) dnl dnl AC_DEFUN([KRB5_AC_CHOOSE_ET],[ AC_ARG_WITH([system-et], AC_HELP_STRING(--with-system-et,use system compile_et and -lcom_err @<:@default: build and install a local version@:>@)) AC_MSG_CHECKING(which version of com_err to use) if test "x$with_system_et" = xyes ; then # This will be changed to "intlsys" if textdomain support is present. COM_ERR_VERSION=sys AC_MSG_RESULT(system) else COM_ERR_VERSION=k5 AC_MSG_RESULT(krb5) fi if test $COM_ERR_VERSION = sys; then # check for various functions we need AC_CHECK_LIB(com_err, add_error_table, :, AC_MSG_ERROR(cannot find add_error_table in com_err library)) AC_CHECK_LIB(com_err, remove_error_table, :, AC_MSG_ERROR(cannot find remove_error_table in com_err library)) # make sure compile_et provides "et_foo" name cat >> conf$$e.et </dev/null 2>&1 ; then true ; else AC_MSG_ERROR(execution failed) fi AC_TRY_COMPILE([#include "conf$$e.h" ],[ &et_foo_error_table; ],:, [AC_MSG_ERROR(cannot use et_foo_error_table)]) # Anything else we need to test for? rm -f conf$$e.c conf$$e.h krb5_cv_compile_et_useful=yes ]) AC_CACHE_CHECK(whether compile_et supports --textdomain, krb5_cv_compile_et_textdomain,[ krb5_cv_compile_et_textdomain=no if compile_et --textdomain=xyzw conf$$e.et >/dev/null 2>&1 ; then if grep -q xyzw conf$$e.c; then krb5_cv_compile_et_textdomain=yes fi fi rm -f conf$$e.c conf$$e.h ]) if test "$krb5_cv_compile_et_textdomain" = yes; then COM_ERR_VERSION=intlsys fi rm -f conf$$e.et fi AC_SUBST(COM_ERR_VERSION) if test "$COM_ERR_VERSION" = k5 -o "$COM_ERR_VERSION" = intlsys; then AC_DEFINE(HAVE_COM_ERR_INTL,1, [Define if com_err has compatible gettext support]) fi ]) AC_DEFUN([KRB5_AC_CHOOSE_SS],[ AC_ARG_WITH(system-ss, AC_HELP_STRING(--with-system-ss,use system -lss and mk_cmds @<:@private version@:>@)) AC_ARG_VAR(SS_LIB,[system libraries for 'ss' package [-lss]]) AC_MSG_CHECKING(which version of subsystem package to use) if test "x$with_system_ss" = xyes ; then SS_VERSION=sys AC_MSG_RESULT(system) # todo: check for various libraries we might need # in the meantime... test "x${SS_LIB+set}" = xset || SS_LIB=-lss old_LIBS="$LIBS" LIBS="$LIBS $SS_LIB" AC_CACHE_CHECK(whether system ss package works, krb5_cv_system_ss_okay,[ AC_TRY_RUN([ #include int main(int argc, char *argv[]) { if (argc == 42) { int i, err; i = ss_create_invocation("foo","foo","",0,&err); ss_listen(i); } return 0; }], krb5_cv_system_ss_okay=yes, AC_MSG_ERROR(cannot run test program), krb5_cv_system_ss_okay="assumed")]) LIBS="$old_LIBS" KRB5_NEED_PROTO([#include ],ss_execute_command,1) else SS_VERSION=k5 AC_MSG_RESULT(krb5) fi AC_SUBST(SS_LIB) AC_SUBST(SS_VERSION) ]) dnl AC_DEFUN([KRB5_AC_CHOOSE_DB],[ AC_ARG_WITH(system-db, AC_HELP_STRING(--with-system-db,use system Berkeley db @<:@private version@:>@)) AC_ARG_VAR(DB_HEADER,[header file for system Berkeley db package [db.h]]) AC_ARG_VAR(DB_LIB,[library for system Berkeley db package [-ldb]]) if test "x$with_system_db" = xyes ; then DB_VERSION=sys # TODO: Do we have specific routines we should check for? # How about known, easily recognizable bugs? # We want to use bt_rseq in some cases, but no other version but # ours has it right now. # # Okay, check the variables. test "x${DB_HEADER+set}" = xset || DB_HEADER=db.h test "x${DB_LIB+set}" = xset || DB_LIB=-ldb # if test "x${DB_HEADER}" = xdb.h ; then DB_HEADER_VERSION=sys else DB_HEADER_VERSION=redirect fi KDB5_DB_LIB="$DB_LIB" else DB_VERSION=k5 AC_DEFINE(HAVE_BT_RSEQ,1,[Define if bt_rseq is available, for recursive btree traversal.]) DB_HEADER=db.h DB_HEADER_VERSION=k5 # libdb gets sucked into libkdb KDB5_DB_LIB= # needed for a couple of things that need libdb for its own sake DB_LIB=-ldb fi AC_SUBST(DB_VERSION) AC_SUBST(DB_HEADER) AC_SUBST(DB_HEADER_VERSION) AC_SUBST(DB_LIB) AC_SUBST(KDB5_DB_LIB) ]) dnl dnl KRB5_AC_PRIOCNTL_HACK dnl dnl AC_DEFUN([KRB5_AC_PRIOCNTL_HACK], [AC_REQUIRE([AC_PROG_AWK])dnl AC_REQUIRE([AC_LANG_COMPILER_REQUIRE])dnl AC_CACHE_CHECK([whether to use priocntl hack], [krb5_cv_priocntl_hack], [case $krb5_cv_host in *-*-solaris2.9*) if test "$cross_compiling" = yes; then krb5_cv_priocntl_hack=yes else # Solaris patch 117171-11 (sparc) or 117172-11 (x86) # fixes the Solaris 9 bug where final pty output # gets lost on close. if showrev -p | $AWK 'BEGIN { e = 1 } /Patch: 11717[[12]]/ { x = index[]([$]2, "-"); if (substr[]([$]2, x + 1, length([$]2) - x) >= 11) { e = 0 } else { e = 1 } } END { exit e; }'; then krb5_cv_priocntl_hack=no else krb5_cv_priocntl_hack=yes fi fi ;; *) krb5_cv_priocntl_hack=no ;; esac]) if test "$krb5_cv_priocntl_hack" = yes; then PRIOCNTL_HACK=1 else PRIOCNTL_HACK=0 fi AC_SUBST(PRIOCNTL_HACK)]) dnl dnl dnl KRB5_AC_GCC_ATTRS AC_DEFUN([KRB5_AC_GCC_ATTRS], [AC_CACHE_CHECK([for constructor/destructor attribute support],krb5_cv_attr_constructor_destructor, [rm -f conftest.1 conftest.2 if test -r conftest.1 || test -r conftest.2 ; then AC_MSG_ERROR(write error in local file system?) fi true > conftest.1 true > conftest.2 if test -r conftest.1 && test -r conftest.2 ; then true ; else AC_MSG_ERROR(write error in local file system?) fi a=no b=no # blindly assume we have 'unlink'... AC_TRY_RUN([void foo1() __attribute__((constructor)); void foo1() { unlink("conftest.1"); } void foo2() __attribute__((destructor)); void foo2() { unlink("conftest.2"); } int main () { return 0; }], [test -r conftest.1 || a=yes test -r conftest.2 || b=yes], , AC_MSG_ERROR(Cannot test for constructor/destructor support when cross compiling)) case $krb5_cv_host in *-*-aix4.*) # Under AIX 4.3.3, at least, shared library destructor functions # appear to get executed in reverse link order (right to left), # so that a library's destructor function may run after that of # libraries it depends on, and may still have to access in the # destructor. # # That counts as "not working", for me, but it's a much more # complicated test case to set up. b=no ;; esac krb5_cv_attr_constructor_destructor="$a,$b" ]) # Okay, krb5_cv_... should be set now. case $krb5_cv_attr_constructor_destructor in yes,*) AC_DEFINE(CONSTRUCTOR_ATTR_WORKS,1,[Define if __attribute__((constructor)) works]) ;; esac case $krb5_cv_attr_constructor_destructor in *,yes) AC_DEFINE(DESTRUCTOR_ATTR_WORKS,1,[Define if __attribute__((destructor)) works]) ;; esac dnl End of attributes we care about right now. ]) dnl dnl dnl KRB5_AC_PRAGMA_WEAK_REF AC_DEFUN([KRB5_AC_PRAGMA_WEAK_REF], [AC_CACHE_CHECK([whether pragma weak references are supported], krb5_cv_pragma_weak_ref, [AC_TRY_LINK([#pragma weak flurbl extern int flurbl(void);],[if (&flurbl != 0) return flurbl();], krb5_cv_pragma_weak_ref=yes,krb5_cv_pragma_weak_ref=no)]) if test $krb5_cv_pragma_weak_ref = yes ; then AC_DEFINE(HAVE_PRAGMA_WEAK_REF,1,[Define if #pragma weak references work]) fi]) dnl dnl m4_include(config/ac-archive/ax_pthread.m4) m4_include(config/ac-archive/ax_recursive_eval.m4) dnl dnl dnl dnl --with-ldap=value dnl AC_DEFUN(WITH_LDAP,[ AC_ARG_WITH([ldap], [ --with-ldap compile OpenLDAP database backend module], [case "$withval" in OPENLDAP) with_ldap=yes ;; yes | no) ;; *) AC_MSG_ERROR(Invalid option value --with-ldap="$withval") ;; esac], with_ldap=no)dnl if test "$with_ldap" = yes; then AC_MSG_NOTICE(enabling OpenLDAP database backend module support) OPENLDAP_PLUGIN=yes fi ])dnl dnl dnl If libkeyutils exists (on Linux) include it and use keyring ccache AC_DEFUN(KRB5_AC_KEYRING_CCACHE,[ AC_CHECK_HEADERS([keyutils.h], AC_CHECK_LIB(keyutils, add_key, [dnl Pre-reqs were found AC_DEFINE(USE_KEYRING_CCACHE, 1, [Define if the keyring ccache should be enabled]) LIBS="-lkeyutils $LIBS" ])) ])dnl dnl dnl If libkeyutils supports persistent keyrings, use them AC_DEFUN(KRB5_AC_PERSISTENT_KEYRING,[ AC_CHECK_HEADERS([keyutils.h], AC_CHECK_LIB(keyutils, keyctl_get_persistent, [AC_DEFINE(HAVE_PERSISTENT_KEYRING, 1, [Define if persistent keyrings are supported]) ])) ])dnl dnl krb5-1.16/src/prototype/0000755000704600001450000000000013211554426015032 5ustar ghudsonlibuuidkrb5-1.16/src/prototype/prototype.c0000644000704600001450000000306613211554426017250 0ustar ghudsonlibuuid/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* prototype/prototype.c - <<< One-line description of file >>> */ /* * Copyright (C) 2017 by the Massachusetts Institute of Technology. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ /* * <<< Longer description of file >>> */ krb5-1.16/src/prototype/prototype.h0000644000704600001450000000324213211554426017251 0ustar ghudsonlibuuid/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* prototype/prototype.h - <<< One-line description of file >>> */ /* * Copyright (C) 2017 by the Massachusetts Institute of Technology. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ /* * <<< Longer description of file >>> */ #ifndef <<< include blocker>>>__ #define <<< include blocker>>>__ #endif /* __<<< include blocker>>>__ */ krb5-1.16/src/man/0000755000704600001450000000000013211554426013540 5ustar ghudsonlibuuidkrb5-1.16/src/man/kadmin.local.80000644000704600001450000000002213211554426016157 0ustar ghudsonlibuuid.so man1/kadmin.1 krb5-1.16/src/man/README0000644000704600001450000000034613211554426014423 0ustar ghudsonlibuuidThe manual page files in this directory are generated from reStructuredText format from doc/. Edits made here will not survive a run of "make rstman" from the doc directory, except for the files that implement "shadow manpages". krb5-1.16/src/man/sserver.man0000644000704600001450000001054713211554426015735 0ustar ghudsonlibuuid.\" Man page generated from reStructuredText. . .TH "SSERVER" "8" " " "1.16" "MIT Kerberos" .SH NAME sserver \- sample Kerberos version 5 server . .nr rst2man-indent-level 0 . .de1 rstReportMargin \\$1 \\n[an-margin] level \\n[rst2man-indent-level] level margin: \\n[rst2man-indent\\n[rst2man-indent-level]] - \\n[rst2man-indent0] \\n[rst2man-indent1] \\n[rst2man-indent2] .. .de1 INDENT .\" .rstReportMargin pre: . RS \\$1 . nr rst2man-indent\\n[rst2man-indent-level] \\n[an-margin] . nr rst2man-indent-level +1 .\" .rstReportMargin post: .. .de UNINDENT . RE .\" indent \\n[an-margin] .\" old: \\n[rst2man-indent\\n[rst2man-indent-level]] .nr rst2man-indent-level -1 .\" new: \\n[rst2man-indent\\n[rst2man-indent-level]] .in \\n[rst2man-indent\\n[rst2man-indent-level]]u .. .SH SYNOPSIS .sp \fBsserver\fP [ \fB\-p\fP \fIport\fP ] [ \fB\-S\fP \fIkeytab\fP ] [ \fIserver_port\fP ] .SH DESCRIPTION .sp sserver and \fIsclient(1)\fP are a simple demonstration client/server application. When sclient connects to sserver, it performs a Kerberos authentication, and then sserver returns to sclient the Kerberos principal which was used for the Kerberos authentication. It makes a good test that Kerberos has been successfully installed on a machine. .sp The service name used by sserver and sclient is sample. Hence, sserver will require that there be a keytab entry for the service \fBsample/hostname.domain.name@REALM.NAME\fP\&. This keytab is generated using the \fIkadmin(1)\fP program. The keytab file is usually installed as \fB@KTNAME@\fP\&. .sp The \fB\-S\fP option allows for a different keytab than the default. .sp sserver is normally invoked out of inetd(8), using a line in \fB/etc/inetd.conf\fP that looks like this: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C sample stream tcp nowait root /usr/local/sbin/sserver sserver .ft P .fi .UNINDENT .UNINDENT .sp Since \fBsample\fP is normally not a port defined in \fB/etc/services\fP, you will usually have to add a line to \fB/etc/services\fP which looks like this: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C sample 13135/tcp .ft P .fi .UNINDENT .UNINDENT .sp When using sclient, you will first have to have an entry in the Kerberos database, by using \fIkadmin(1)\fP, and then you have to get Kerberos tickets, by using \fIkinit(1)\fP\&. Also, if you are running the sclient program on a different host than the sserver it will be connecting to, be sure that both hosts have an entry in /etc/services for the sample tcp port, and that the same port number is in both files. .sp When you run sclient you should see something like this: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C sendauth succeeded, reply is: reply len 32, contents: You are nlgilman@JIMI.MIT.EDU .ft P .fi .UNINDENT .UNINDENT .SH COMMON ERROR MESSAGES .INDENT 0.0 .IP 1. 3 kinit returns the error: .INDENT 3.0 .INDENT 3.5 .sp .nf .ft C kinit: Client not found in Kerberos database while getting initial credentials .ft P .fi .UNINDENT .UNINDENT .sp This means that you didn\(aqt create an entry for your username in the Kerberos database. .IP 2. 3 sclient returns the error: .INDENT 3.0 .INDENT 3.5 .sp .nf .ft C unknown service sample/tcp; check /etc/services .ft P .fi .UNINDENT .UNINDENT .sp This means that you don\(aqt have an entry in /etc/services for the sample tcp port. .IP 3. 3 sclient returns the error: .INDENT 3.0 .INDENT 3.5 .sp .nf .ft C connect: Connection refused .ft P .fi .UNINDENT .UNINDENT .sp This probably means you didn\(aqt edit /etc/inetd.conf correctly, or you didn\(aqt restart inetd after editing inetd.conf. .IP 4. 3 sclient returns the error: .INDENT 3.0 .INDENT 3.5 .sp .nf .ft C sclient: Server not found in Kerberos database while using sendauth .ft P .fi .UNINDENT .UNINDENT .sp This means that the \fBsample/hostname@LOCAL.REALM\fP service was not defined in the Kerberos database; it should be created using \fIkadmin(1)\fP, and a keytab file needs to be generated to make the key for that service principal available for sclient. .IP 5. 3 sclient returns the error: .INDENT 3.0 .INDENT 3.5 .sp .nf .ft C sendauth rejected, error reply is: "No such file or directory" .ft P .fi .UNINDENT .UNINDENT .sp This probably means sserver couldn\(aqt find the keytab file. It was probably not installed in the proper directory. .UNINDENT .SH SEE ALSO .sp \fIsclient(1)\fP, services(5), inetd(8) .SH AUTHOR MIT .SH COPYRIGHT 1985-2017, MIT .\" Generated by docutils manpage writer. . krb5-1.16/src/man/kadmin.man0000644000704600001450000007743113211554426015514 0ustar ghudsonlibuuid.\" Man page generated from reStructuredText. . .TH "KADMIN" "1" " " "1.16" "MIT Kerberos" .SH NAME kadmin \- Kerberos V5 database administration program . .nr rst2man-indent-level 0 . .de1 rstReportMargin \\$1 \\n[an-margin] level \\n[rst2man-indent-level] level margin: \\n[rst2man-indent\\n[rst2man-indent-level]] - \\n[rst2man-indent0] \\n[rst2man-indent1] \\n[rst2man-indent2] .. .de1 INDENT .\" .rstReportMargin pre: . RS \\$1 . nr rst2man-indent\\n[rst2man-indent-level] \\n[an-margin] . nr rst2man-indent-level +1 .\" .rstReportMargin post: .. .de UNINDENT . RE .\" indent \\n[an-margin] .\" old: \\n[rst2man-indent\\n[rst2man-indent-level]] .nr rst2man-indent-level -1 .\" new: \\n[rst2man-indent\\n[rst2man-indent-level]] .in \\n[rst2man-indent\\n[rst2man-indent-level]]u .. .SH SYNOPSIS .sp \fBkadmin\fP [\fB\-O\fP|\fB\-N\fP] [\fB\-r\fP \fIrealm\fP] [\fB\-p\fP \fIprincipal\fP] [\fB\-q\fP \fIquery\fP] [[\fB\-c\fP \fIcache_name\fP]|[\fB\-k\fP [\fB\-t\fP \fIkeytab\fP]]|\fB\-n\fP] [\fB\-w\fP \fIpassword\fP] [\fB\-s\fP \fIadmin_server\fP[:\fIport\fP]] [command args...] .sp \fBkadmin.local\fP [\fB\-r\fP \fIrealm\fP] [\fB\-p\fP \fIprincipal\fP] [\fB\-q\fP \fIquery\fP] [\fB\-d\fP \fIdbname\fP] [\fB\-e\fP \fIenc\fP:\fIsalt\fP ...] [\fB\-m\fP] [\fB\-x\fP \fIdb_args\fP] [command args...] .SH DESCRIPTION .sp kadmin and kadmin.local are command\-line interfaces to the Kerberos V5 administration system. They provide nearly identical functionalities; the difference is that kadmin.local directly accesses the KDC database, while kadmin performs operations using \fIkadmind(8)\fP\&. Except as explicitly noted otherwise, this man page will use "kadmin" to refer to both versions. kadmin provides for the maintenance of Kerberos principals, password policies, and service key tables (keytabs). .sp The remote kadmin client uses Kerberos to authenticate to kadmind using the service principal \fBkadmin/ADMINHOST\fP (where \fIADMINHOST\fP is the fully\-qualified hostname of the admin server) or \fBkadmin/admin\fP\&. If the credentials cache contains a ticket for one of these principals, and the \fB\-c\fP credentials_cache option is specified, that ticket is used to authenticate to kadmind. Otherwise, the \fB\-p\fP and \fB\-k\fP options are used to specify the client Kerberos principal name used to authenticate. Once kadmin has determined the principal name, it requests a service ticket from the KDC, and uses that service ticket to authenticate to kadmind. .sp Since kadmin.local directly accesses the KDC database, it usually must be run directly on the master KDC with sufficient permissions to read the KDC database. If the KDC database uses the LDAP database module, kadmin.local can be run on any host which can access the LDAP server. .SH OPTIONS .INDENT 0.0 .TP .B \fB\-r\fP \fIrealm\fP Use \fIrealm\fP as the default database realm. .TP .B \fB\-p\fP \fIprincipal\fP Use \fIprincipal\fP to authenticate. Otherwise, kadmin will append \fB/admin\fP to the primary principal name of the default ccache, the value of the \fBUSER\fP environment variable, or the username as obtained with getpwuid, in order of preference. .TP .B \fB\-k\fP Use a keytab to decrypt the KDC response instead of prompting for a password. In this case, the default principal will be \fBhost/hostname\fP\&. If there is no keytab specified with the \fB\-t\fP option, then the default keytab will be used. .TP .B \fB\-t\fP \fIkeytab\fP Use \fIkeytab\fP to decrypt the KDC response. This can only be used with the \fB\-k\fP option. .TP .B \fB\-n\fP Requests anonymous processing. Two types of anonymous principals are supported. For fully anonymous Kerberos, configure PKINIT on the KDC and configure \fBpkinit_anchors\fP in the client\(aqs \fIkrb5.conf(5)\fP\&. Then use the \fB\-n\fP option with a principal of the form \fB@REALM\fP (an empty principal name followed by the at\-sign and a realm name). If permitted by the KDC, an anonymous ticket will be returned. A second form of anonymous tickets is supported; these realm\-exposed tickets hide the identity of the client but not the client\(aqs realm. For this mode, use \fBkinit \-n\fP with a normal principal name. If supported by the KDC, the principal (but not realm) will be replaced by the anonymous principal. As of release 1.8, the MIT Kerberos KDC only supports fully anonymous operation. .TP .B \fB\-c\fP \fIcredentials_cache\fP Use \fIcredentials_cache\fP as the credentials cache. The cache should contain a service ticket for the \fBkadmin/ADMINHOST\fP (where \fIADMINHOST\fP is the fully\-qualified hostname of the admin server) or \fBkadmin/admin\fP service; it can be acquired with the \fIkinit(1)\fP program. If this option is not specified, kadmin requests a new service ticket from the KDC, and stores it in its own temporary ccache. .TP .B \fB\-w\fP \fIpassword\fP Use \fIpassword\fP instead of prompting for one. Use this option with care, as it may expose the password to other users on the system via the process list. .TP .B \fB\-q\fP \fIquery\fP Perform the specified query and then exit. .TP .B \fB\-d\fP \fIdbname\fP Specifies the name of the KDC database. This option does not apply to the LDAP database module. .TP .B \fB\-s\fP \fIadmin_server\fP[:\fIport\fP] Specifies the admin server which kadmin should contact. .TP .B \fB\-m\fP If using kadmin.local, prompt for the database master password instead of reading it from a stash file. .TP .B \fB\-e\fP "\fIenc\fP:\fIsalt\fP ..." Sets the keysalt list to be used for any new keys created. See \fIKeysalt_lists\fP in \fIkdc.conf(5)\fP for a list of possible values. .TP .B \fB\-O\fP Force use of old AUTH_GSSAPI authentication flavor. .TP .B \fB\-N\fP Prevent fallback to AUTH_GSSAPI authentication flavor. .TP .B \fB\-x\fP \fIdb_args\fP Specifies the database specific arguments. See the next section for supported options. .UNINDENT .sp Starting with release 1.14, if any command\-line arguments remain after the options, they will be treated as a single query to be executed. This mode of operation is intended for scripts and behaves differently from the interactive mode in several respects: .INDENT 0.0 .IP \(bu 2 Query arguments are split by the shell, not by kadmin. .IP \(bu 2 Informational and warning messages are suppressed. Error messages and query output (e.g. for \fBget_principal\fP) will still be displayed. .IP \(bu 2 Confirmation prompts are disabled (as if \fB\-force\fP was given). Password prompts will still be issued as required. .IP \(bu 2 The exit status will be non\-zero if the query fails. .UNINDENT .sp The \fB\-q\fP option does not carry these behavior differences; the query will be processed as if it was entered interactively. The \fB\-q\fP option cannot be used in combination with a query in the remaining arguments. .SH DATABASE OPTIONS .sp Database options can be used to override database\-specific defaults. Supported options for the DB2 module are: .INDENT 0.0 .INDENT 3.5 .INDENT 0.0 .TP .B \fB\-x dbname=\fP*filename* Specifies the base filename of the DB2 database. .TP .B \fB\-x lockiter\fP Make iteration operations hold the lock for the duration of the entire operation, rather than temporarily releasing the lock while handling each principal. This is the default behavior, but this option exists to allow command line override of a [dbmodules] setting. First introduced in release 1.13. .TP .B \fB\-x unlockiter\fP Make iteration operations unlock the database for each principal, instead of holding the lock for the duration of the entire operation. First introduced in release 1.13. .UNINDENT .UNINDENT .UNINDENT .sp Supported options for the LDAP module are: .INDENT 0.0 .INDENT 3.5 .INDENT 0.0 .TP .B \fB\-x host=\fP\fIldapuri\fP Specifies the LDAP server to connect to by a LDAP URI. .TP .B \fB\-x binddn=\fP\fIbind_dn\fP Specifies the DN used to bind to the LDAP server. .TP .B \fB\-x bindpwd=\fP\fIpassword\fP Specifies the password or SASL secret used to bind to the LDAP server. Using this option may expose the password to other users on the system via the process list; to avoid this, instead stash the password using the \fBstashsrvpw\fP command of \fIkdb5_ldap_util(8)\fP\&. .TP .B \fB\-x sasl_mech=\fP\fImechanism\fP Specifies the SASL mechanism used to bind to the LDAP server. The bind DN is ignored if a SASL mechanism is used. New in release 1.13. .TP .B \fB\-x sasl_authcid=\fP\fIname\fP Specifies the authentication name used when binding to the LDAP server with a SASL mechanism, if the mechanism requires one. New in release 1.13. .TP .B \fB\-x sasl_authzid=\fP\fIname\fP Specifies the authorization name used when binding to the LDAP server with a SASL mechanism. New in release 1.13. .TP .B \fB\-x sasl_realm=\fP\fIrealm\fP Specifies the realm used when binding to the LDAP server with a SASL mechanism, if the mechanism uses one. New in release 1.13. .TP .B \fB\-x debug=\fP\fIlevel\fP sets the OpenLDAP client library debug level. \fIlevel\fP is an integer to be interpreted by the library. Debugging messages are printed to standard error. New in release 1.12. .UNINDENT .UNINDENT .UNINDENT .SH COMMANDS .sp When using the remote client, available commands may be restricted according to the privileges specified in the \fIkadm5.acl(5)\fP file on the admin server. .SS add_principal .INDENT 0.0 .INDENT 3.5 \fBadd_principal\fP [\fIoptions\fP] \fInewprinc\fP .UNINDENT .UNINDENT .sp Creates the principal \fInewprinc\fP, prompting twice for a password. If no password policy is specified with the \fB\-policy\fP option, and the policy named \fBdefault\fP is assigned to the principal if it exists. However, creating a policy named \fBdefault\fP will not automatically assign this policy to previously existing principals. This policy assignment can be suppressed with the \fB\-clearpolicy\fP option. .sp This command requires the \fBadd\fP privilege. .sp Aliases: \fBaddprinc\fP, \fBank\fP .sp Options: .INDENT 0.0 .TP .B \fB\-expire\fP \fIexpdate\fP (\fIgetdate\fP string) The expiration date of the principal. .TP .B \fB\-pwexpire\fP \fIpwexpdate\fP (\fIgetdate\fP string) The password expiration date. .TP .B \fB\-maxlife\fP \fImaxlife\fP (\fIduration\fP or \fIgetdate\fP string) The maximum ticket life for the principal. .TP .B \fB\-maxrenewlife\fP \fImaxrenewlife\fP (\fIduration\fP or \fIgetdate\fP string) The maximum renewable life of tickets for the principal. .TP .B \fB\-kvno\fP \fIkvno\fP The initial key version number. .TP .B \fB\-policy\fP \fIpolicy\fP The password policy used by this principal. If not specified, the policy \fBdefault\fP is used if it exists (unless \fB\-clearpolicy\fP is specified). .TP .B \fB\-clearpolicy\fP Prevents any policy from being assigned when \fB\-policy\fP is not specified. .TP .B {\-|+}\fBallow_postdated\fP \fB\-allow_postdated\fP prohibits this principal from obtaining postdated tickets. \fB+allow_postdated\fP clears this flag. .TP .B {\-|+}\fBallow_forwardable\fP \fB\-allow_forwardable\fP prohibits this principal from obtaining forwardable tickets. \fB+allow_forwardable\fP clears this flag. .TP .B {\-|+}\fBallow_renewable\fP \fB\-allow_renewable\fP prohibits this principal from obtaining renewable tickets. \fB+allow_renewable\fP clears this flag. .TP .B {\-|+}\fBallow_proxiable\fP \fB\-allow_proxiable\fP prohibits this principal from obtaining proxiable tickets. \fB+allow_proxiable\fP clears this flag. .TP .B {\-|+}\fBallow_dup_skey\fP \fB\-allow_dup_skey\fP disables user\-to\-user authentication for this principal by prohibiting this principal from obtaining a session key for another user. \fB+allow_dup_skey\fP clears this flag. .TP .B {\-|+}\fBrequires_preauth\fP \fB+requires_preauth\fP requires this principal to preauthenticate before being allowed to kinit. \fB\-requires_preauth\fP clears this flag. When \fB+requires_preauth\fP is set on a service principal, the KDC will only issue service tickets for that service principal if the client\(aqs initial authentication was performed using preauthentication. .TP .B {\-|+}\fBrequires_hwauth\fP \fB+requires_hwauth\fP requires this principal to preauthenticate using a hardware device before being allowed to kinit. \fB\-requires_hwauth\fP clears this flag. When \fB+requires_hwauth\fP is set on a service principal, the KDC will only issue service tickets for that service principal if the client\(aqs initial authentication was performed using a hardware device to preauthenticate. .TP .B {\-|+}\fBok_as_delegate\fP \fB+ok_as_delegate\fP sets the \fBokay as delegate\fP flag on tickets issued with this principal as the service. Clients may use this flag as a hint that credentials should be delegated when authenticating to the service. \fB\-ok_as_delegate\fP clears this flag. .TP .B {\-|+}\fBallow_svr\fP \fB\-allow_svr\fP prohibits the issuance of service tickets for this principal. \fB+allow_svr\fP clears this flag. .TP .B {\-|+}\fBallow_tgs_req\fP \fB\-allow_tgs_req\fP specifies that a Ticket\-Granting Service (TGS) request for a service ticket for this principal is not permitted. \fB+allow_tgs_req\fP clears this flag. .TP .B {\-|+}\fBallow_tix\fP \fB\-allow_tix\fP forbids the issuance of any tickets for this principal. \fB+allow_tix\fP clears this flag. .TP .B {\-|+}\fBneedchange\fP \fB+needchange\fP forces a password change on the next initial authentication to this principal. \fB\-needchange\fP clears this flag. .TP .B {\-|+}\fBpassword_changing_service\fP \fB+password_changing_service\fP marks this principal as a password change service principal. .TP .B {\-|+}\fBok_to_auth_as_delegate\fP \fB+ok_to_auth_as_delegate\fP allows this principal to acquire forwardable tickets to itself from arbitrary users, for use with constrained delegation. .TP .B {\-|+}\fBno_auth_data_required\fP \fB+no_auth_data_required\fP prevents PAC or AD\-SIGNEDPATH data from being added to service tickets for the principal. .TP .B {\-|+}\fBlockdown_keys\fP \fB+lockdown_keys\fP prevents keys for this principal from leaving the KDC via kadmind. The chpass and extract operations are denied for a principal with this attribute. The chrand operation is allowed, but will not return the new keys. The delete and rename operations are also denied if this attribute is set, in order to prevent a malicious administrator from replacing principals like krbtgt/* or kadmin/* with new principals without the attribute. This attribute can be set via the network protocol, but can only be removed using kadmin.local. .TP .B \fB\-randkey\fP Sets the key of the principal to a random value. .TP .B \fB\-nokey\fP Causes the principal to be created with no key. New in release 1.12. .TP .B \fB\-pw\fP \fIpassword\fP Sets the password of the principal to the specified string and does not prompt for a password. Note: using this option in a shell script may expose the password to other users on the system via the process list. .TP .B \fB\-e\fP \fIenc\fP:\fIsalt\fP,... Uses the specified keysalt list for setting the keys of the principal. See \fIKeysalt_lists\fP in \fIkdc.conf(5)\fP for a list of possible values. .TP .B \fB\-x\fP \fIdb_princ_args\fP Indicates database\-specific options. The options for the LDAP database module are: .INDENT 7.0 .TP .B \fB\-x dn=\fP\fIdn\fP Specifies the LDAP object that will contain the Kerberos principal being created. .TP .B \fB\-x linkdn=\fP\fIdn\fP Specifies the LDAP object to which the newly created Kerberos principal object will point. .TP .B \fB\-x containerdn=\fP\fIcontainer_dn\fP Specifies the container object under which the Kerberos principal is to be created. .TP .B \fB\-x tktpolicy=\fP\fIpolicy\fP Associates a ticket policy to the Kerberos principal. .UNINDENT .sp \fBNOTE:\fP .INDENT 7.0 .INDENT 3.5 .INDENT 0.0 .IP \(bu 2 The \fBcontainerdn\fP and \fBlinkdn\fP options cannot be specified with the \fBdn\fP option. .IP \(bu 2 If the \fIdn\fP or \fIcontainerdn\fP options are not specified while adding the principal, the principals are created under the principal container configured in the realm or the realm container. .IP \(bu 2 \fIdn\fP and \fIcontainerdn\fP should be within the subtrees or principal container configured in the realm. .UNINDENT .UNINDENT .UNINDENT .UNINDENT .sp Example: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C kadmin: addprinc jennifer WARNING: no policy specified for "jennifer@ATHENA.MIT.EDU"; defaulting to no policy. Enter password for principal jennifer@ATHENA.MIT.EDU: Re\-enter password for principal jennifer@ATHENA.MIT.EDU: Principal "jennifer@ATHENA.MIT.EDU" created. kadmin: .ft P .fi .UNINDENT .UNINDENT .SS modify_principal .INDENT 0.0 .INDENT 3.5 \fBmodify_principal\fP [\fIoptions\fP] \fIprincipal\fP .UNINDENT .UNINDENT .sp Modifies the specified principal, changing the fields as specified. The options to \fBadd_principal\fP also apply to this command, except for the \fB\-randkey\fP, \fB\-pw\fP, and \fB\-e\fP options. In addition, the option \fB\-clearpolicy\fP will clear the current policy of a principal. .sp This command requires the \fImodify\fP privilege. .sp Alias: \fBmodprinc\fP .sp Options (in addition to the \fBaddprinc\fP options): .INDENT 0.0 .TP .B \fB\-unlock\fP Unlocks a locked principal (one which has received too many failed authentication attempts without enough time between them according to its password policy) so that it can successfully authenticate. .UNINDENT .SS rename_principal .INDENT 0.0 .INDENT 3.5 \fBrename_principal\fP [\fB\-force\fP] \fIold_principal\fP \fInew_principal\fP .UNINDENT .UNINDENT .sp Renames the specified \fIold_principal\fP to \fInew_principal\fP\&. This command prompts for confirmation, unless the \fB\-force\fP option is given. .sp This command requires the \fBadd\fP and \fBdelete\fP privileges. .sp Alias: \fBrenprinc\fP .SS delete_principal .INDENT 0.0 .INDENT 3.5 \fBdelete_principal\fP [\fB\-force\fP] \fIprincipal\fP .UNINDENT .UNINDENT .sp Deletes the specified \fIprincipal\fP from the database. This command prompts for deletion, unless the \fB\-force\fP option is given. .sp This command requires the \fBdelete\fP privilege. .sp Alias: \fBdelprinc\fP .SS change_password .INDENT 0.0 .INDENT 3.5 \fBchange_password\fP [\fIoptions\fP] \fIprincipal\fP .UNINDENT .UNINDENT .sp Changes the password of \fIprincipal\fP\&. Prompts for a new password if neither \fB\-randkey\fP or \fB\-pw\fP is specified. .sp This command requires the \fBchangepw\fP privilege, or that the principal running the program is the same as the principal being changed. .sp Alias: \fBcpw\fP .sp The following options are available: .INDENT 0.0 .TP .B \fB\-randkey\fP Sets the key of the principal to a random value. .TP .B \fB\-pw\fP \fIpassword\fP Set the password to the specified string. Using this option in a script may expose the password to other users on the system via the process list. .TP .B \fB\-e\fP \fIenc\fP:\fIsalt\fP,... Uses the specified keysalt list for setting the keys of the principal. See \fIKeysalt_lists\fP in \fIkdc.conf(5)\fP for a list of possible values. .TP .B \fB\-keepold\fP Keeps the existing keys in the database. This flag is usually not necessary except perhaps for \fBkrbtgt\fP principals. .UNINDENT .sp Example: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C kadmin: cpw systest Enter password for principal systest@BLEEP.COM: Re\-enter password for principal systest@BLEEP.COM: Password for systest@BLEEP.COM changed. kadmin: .ft P .fi .UNINDENT .UNINDENT .SS purgekeys .INDENT 0.0 .INDENT 3.5 \fBpurgekeys\fP [\fB\-all\fP|\fB\-keepkvno\fP \fIoldest_kvno_to_keep\fP] \fIprincipal\fP .UNINDENT .UNINDENT .sp Purges previously retained old keys (e.g., from \fBchange_password \-keepold\fP) from \fIprincipal\fP\&. If \fB\-keepkvno\fP is specified, then only purges keys with kvnos lower than \fIoldest_kvno_to_keep\fP\&. If \fB\-all\fP is specified, then all keys are purged. The \fB\-all\fP option is new in release 1.12. .sp This command requires the \fBmodify\fP privilege. .SS get_principal .INDENT 0.0 .INDENT 3.5 \fBget_principal\fP [\fB\-terse\fP] \fIprincipal\fP .UNINDENT .UNINDENT .sp Gets the attributes of principal. With the \fB\-terse\fP option, outputs fields as quoted tab\-separated strings. .sp This command requires the \fBinquire\fP privilege, or that the principal running the the program to be the same as the one being listed. .sp Alias: \fBgetprinc\fP .sp Examples: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C kadmin: getprinc tlyu/admin Principal: tlyu/admin@BLEEP.COM Expiration date: [never] Last password change: Mon Aug 12 14:16:47 EDT 1996 Password expiration date: [none] Maximum ticket life: 0 days 10:00:00 Maximum renewable life: 7 days 00:00:00 Last modified: Mon Aug 12 14:16:47 EDT 1996 (bjaspan/admin@BLEEP.COM) Last successful authentication: [never] Last failed authentication: [never] Failed password attempts: 0 Number of keys: 2 Key: vno 1, des\-cbc\-crc Key: vno 1, des\-cbc\-crc:v4 Attributes: Policy: [none] kadmin: getprinc \-terse systest systest@BLEEP.COM 3 86400 604800 1 785926535 753241234 785900000 tlyu/admin@BLEEP.COM 786100034 0 0 kadmin: .ft P .fi .UNINDENT .UNINDENT .SS list_principals .INDENT 0.0 .INDENT 3.5 \fBlist_principals\fP [\fIexpression\fP] .UNINDENT .UNINDENT .sp Retrieves all or some principal names. \fIexpression\fP is a shell\-style glob expression that can contain the wild\-card characters \fB?\fP, \fB*\fP, and \fB[]\fP\&. All principal names matching the expression are printed. If no expression is provided, all principal names are printed. If the expression does not contain an \fB@\fP character, an \fB@\fP character followed by the local realm is appended to the expression. .sp This command requires the \fBlist\fP privilege. .sp Alias: \fBlistprincs\fP, \fBget_principals\fP, \fBget_princs\fP .sp Example: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C kadmin: listprincs test* test3@SECURE\-TEST.OV.COM test2@SECURE\-TEST.OV.COM test1@SECURE\-TEST.OV.COM testuser@SECURE\-TEST.OV.COM kadmin: .ft P .fi .UNINDENT .UNINDENT .SS get_strings .INDENT 0.0 .INDENT 3.5 \fBget_strings\fP \fIprincipal\fP .UNINDENT .UNINDENT .sp Displays string attributes on \fIprincipal\fP\&. .sp This command requires the \fBinquire\fP privilege. .sp Alias: \fBgetstr\fP .SS set_string .INDENT 0.0 .INDENT 3.5 \fBset_string\fP \fIprincipal\fP \fIname\fP \fIvalue\fP .UNINDENT .UNINDENT .sp Sets a string attribute on \fIprincipal\fP\&. String attributes are used to supply per\-principal configuration to the KDC and some KDC plugin modules. The following string attribute names are recognized by the KDC: .INDENT 0.0 .TP .B \fBrequire_auth\fP Specifies an authentication indicator which is required to authenticate to the principal as a service. Multiple indicators can be specified, separated by spaces; in this case any of the specified indicators will be accepted. (New in release 1.14.) .TP .B \fBsession_enctypes\fP Specifies the encryption types supported for session keys when the principal is authenticated to as a server. See \fIEncryption_types\fP in \fIkdc.conf(5)\fP for a list of the accepted values. .TP .B \fBotp\fP Enables One Time Passwords (OTP) preauthentication for a client \fIprincipal\fP\&. The \fIvalue\fP is a JSON string representing an array of objects, each having optional \fBtype\fP and \fBusername\fP fields. .TP .B \fBpkinit_cert_match\fP Specifies a matching expression that defines the certificate attributes required for the client certificate used by the principal during PKINIT authentication. The matching expression is in the same format as those used by the \fBpkinit_cert_match\fP option in \fIkrb5.conf(5)\fP\&. (New in release 1.16.) .UNINDENT .sp This command requires the \fBmodify\fP privilege. .sp Alias: \fBsetstr\fP .sp Example: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C set_string host/foo.mit.edu session_enctypes aes128\-cts set_string user@FOO.COM otp "[{""type"":""hotp"",""username"":""al""}]" .ft P .fi .UNINDENT .UNINDENT .SS del_string .INDENT 0.0 .INDENT 3.5 \fBdel_string\fP \fIprincipal\fP \fIkey\fP .UNINDENT .UNINDENT .sp Deletes a string attribute from \fIprincipal\fP\&. .sp This command requires the \fBdelete\fP privilege. .sp Alias: \fBdelstr\fP .SS add_policy .INDENT 0.0 .INDENT 3.5 \fBadd_policy\fP [\fIoptions\fP] \fIpolicy\fP .UNINDENT .UNINDENT .sp Adds a password policy named \fIpolicy\fP to the database. .sp This command requires the \fBadd\fP privilege. .sp Alias: \fBaddpol\fP .sp The following options are available: .INDENT 0.0 .TP .B \fB\-maxlife\fP \fItime\fP (\fIduration\fP or \fIgetdate\fP string) Sets the maximum lifetime of a password. .TP .B \fB\-minlife\fP \fItime\fP (\fIduration\fP or \fIgetdate\fP string) Sets the minimum lifetime of a password. .TP .B \fB\-minlength\fP \fIlength\fP Sets the minimum length of a password. .TP .B \fB\-minclasses\fP \fInumber\fP Sets the minimum number of character classes required in a password. The five character classes are lower case, upper case, numbers, punctuation, and whitespace/unprintable characters. .TP .B \fB\-history\fP \fInumber\fP Sets the number of past keys kept for a principal. This option is not supported with the LDAP KDC database module. .UNINDENT .INDENT 0.0 .TP .B \fB\-maxfailure\fP \fImaxnumber\fP Sets the number of authentication failures before the principal is locked. Authentication failures are only tracked for principals which require preauthentication. The counter of failed attempts resets to 0 after a successful attempt to authenticate. A \fImaxnumber\fP value of 0 (the default) disables lockout. .UNINDENT .INDENT 0.0 .TP .B \fB\-failurecountinterval\fP \fIfailuretime\fP (\fIduration\fP or \fIgetdate\fP string) Sets the allowable time between authentication failures. If an authentication failure happens after \fIfailuretime\fP has elapsed since the previous failure, the number of authentication failures is reset to 1. A \fIfailuretime\fP value of 0 (the default) means forever. .UNINDENT .INDENT 0.0 .TP .B \fB\-lockoutduration\fP \fIlockouttime\fP (\fIduration\fP or \fIgetdate\fP string) Sets the duration for which the principal is locked from authenticating if too many authentication failures occur without the specified failure count interval elapsing. A duration of 0 (the default) means the principal remains locked out until it is administratively unlocked with \fBmodprinc \-unlock\fP\&. .TP .B \fB\-allowedkeysalts\fP Specifies the key/salt tuples supported for long\-term keys when setting or changing a principal\(aqs password/keys. See \fIKeysalt_lists\fP in \fIkdc.conf(5)\fP for a list of the accepted values, but note that key/salt tuples must be separated with commas (\(aq,\(aq) only. To clear the allowed key/salt policy use a value of \(aq\-\(aq. .UNINDENT .sp Example: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C kadmin: add_policy \-maxlife "2 days" \-minlength 5 guests kadmin: .ft P .fi .UNINDENT .UNINDENT .SS modify_policy .INDENT 0.0 .INDENT 3.5 \fBmodify_policy\fP [\fIoptions\fP] \fIpolicy\fP .UNINDENT .UNINDENT .sp Modifies the password policy named \fIpolicy\fP\&. Options are as described for \fBadd_policy\fP\&. .sp This command requires the \fBmodify\fP privilege. .sp Alias: \fBmodpol\fP .SS delete_policy .INDENT 0.0 .INDENT 3.5 \fBdelete_policy\fP [\fB\-force\fP] \fIpolicy\fP .UNINDENT .UNINDENT .sp Deletes the password policy named \fIpolicy\fP\&. Prompts for confirmation before deletion. The command will fail if the policy is in use by any principals. .sp This command requires the \fBdelete\fP privilege. .sp Alias: \fBdelpol\fP .sp Example: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C kadmin: del_policy guests Are you sure you want to delete the policy "guests"? (yes/no): yes kadmin: .ft P .fi .UNINDENT .UNINDENT .SS get_policy .INDENT 0.0 .INDENT 3.5 \fBget_policy\fP [ \fB\-terse\fP ] \fIpolicy\fP .UNINDENT .UNINDENT .sp Displays the values of the password policy named \fIpolicy\fP\&. With the \fB\-terse\fP flag, outputs the fields as quoted strings separated by tabs. .sp This command requires the \fBinquire\fP privilege. .sp Alias: getpol .sp Examples: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C kadmin: get_policy admin Policy: admin Maximum password life: 180 days 00:00:00 Minimum password life: 00:00:00 Minimum password length: 6 Minimum number of password character classes: 2 Number of old keys kept: 5 Reference count: 17 kadmin: get_policy \-terse admin admin 15552000 0 6 2 5 17 kadmin: .ft P .fi .UNINDENT .UNINDENT .sp The "Reference count" is the number of principals using that policy. With the LDAP KDC database module, the reference count field is not meaningful. .SS list_policies .INDENT 0.0 .INDENT 3.5 \fBlist_policies\fP [\fIexpression\fP] .UNINDENT .UNINDENT .sp Retrieves all or some policy names. \fIexpression\fP is a shell\-style glob expression that can contain the wild\-card characters \fB?\fP, \fB*\fP, and \fB[]\fP\&. All policy names matching the expression are printed. If no expression is provided, all existing policy names are printed. .sp This command requires the \fBlist\fP privilege. .sp Aliases: \fBlistpols\fP, \fBget_policies\fP, \fBgetpols\fP\&. .sp Examples: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C kadmin: listpols test\-pol dict\-only once\-a\-min test\-pol\-nopw kadmin: listpols t* test\-pol test\-pol\-nopw kadmin: .ft P .fi .UNINDENT .UNINDENT .SS ktadd .INDENT 0.0 .INDENT 3.5 .nf \fBktadd\fP [options] \fIprincipal\fP \fBktadd\fP [options] \fB\-glob\fP \fIprinc\-exp\fP .fi .sp .UNINDENT .UNINDENT .sp Adds a \fIprincipal\fP, or all principals matching \fIprinc\-exp\fP, to a keytab file. Each principal\(aqs keys are randomized in the process. The rules for \fIprinc\-exp\fP are described in the \fBlist_principals\fP command. .sp This command requires the \fBinquire\fP and \fBchangepw\fP privileges. With the \fB\-glob\fP form, it also requires the \fBlist\fP privilege. .sp The options are: .INDENT 0.0 .TP .B \fB\-k[eytab]\fP \fIkeytab\fP Use \fIkeytab\fP as the keytab file. Otherwise, the default keytab is used. .TP .B \fB\-e\fP \fIenc\fP:\fIsalt\fP,... Uses the specified keysalt list for setting the new keys of the principal. See \fIKeysalt_lists\fP in \fIkdc.conf(5)\fP for a list of possible values. .TP .B \fB\-q\fP Display less verbose information. .TP .B \fB\-norandkey\fP Do not randomize the keys. The keys and their version numbers stay unchanged. This option cannot be specified in combination with the \fB\-e\fP option. .UNINDENT .sp An entry for each of the principal\(aqs unique encryption types is added, ignoring multiple keys with the same encryption type but different salt types. .sp Example: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C kadmin: ktadd \-k /tmp/foo\-new\-keytab host/foo.mit.edu Entry for principal host/foo.mit.edu@ATHENA.MIT.EDU with kvno 3, encryption type aes256\-cts\-hmac\-sha1\-96 added to keytab FILE:/tmp/foo\-new\-keytab kadmin: .ft P .fi .UNINDENT .UNINDENT .SS ktremove .INDENT 0.0 .INDENT 3.5 \fBktremove\fP [options] \fIprincipal\fP [\fIkvno\fP | \fIall\fP | \fIold\fP] .UNINDENT .UNINDENT .sp Removes entries for the specified \fIprincipal\fP from a keytab. Requires no permissions, since this does not require database access. .sp If the string "all" is specified, all entries for that principal are removed; if the string "old" is specified, all entries for that principal except those with the highest kvno are removed. Otherwise, the value specified is parsed as an integer, and all entries whose kvno match that integer are removed. .sp The options are: .INDENT 0.0 .TP .B \fB\-k[eytab]\fP \fIkeytab\fP Use \fIkeytab\fP as the keytab file. Otherwise, the default keytab is used. .TP .B \fB\-q\fP Display less verbose information. .UNINDENT .sp Example: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C kadmin: ktremove kadmin/admin all Entry for principal kadmin/admin with kvno 3 removed from keytab FILE:/etc/krb5.keytab kadmin: .ft P .fi .UNINDENT .UNINDENT .SS lock .sp Lock database exclusively. Use with extreme caution! This command only works with the DB2 KDC database module. .SS unlock .sp Release the exclusive database lock. .SS list_requests .sp Lists available for kadmin requests. .sp Aliases: \fBlr\fP, \fB?\fP .SS quit .sp Exit program. If the database was locked, the lock is released. .sp Aliases: \fBexit\fP, \fBq\fP .SH HISTORY .sp The kadmin program was originally written by Tom Yu at MIT, as an interface to the OpenVision Kerberos administration program. .SH SEE ALSO .sp \fIkpasswd(1)\fP, \fIkadmind(8)\fP .SH AUTHOR MIT .SH COPYRIGHT 1985-2017, MIT .\" Generated by docutils manpage writer. . krb5-1.16/src/man/k5login.man0000644000704600001450000000542513211554426015613 0ustar ghudsonlibuuid.\" Man page generated from reStructuredText. . .TH "K5LOGIN" "5" " " "1.16" "MIT Kerberos" .SH NAME k5login \- Kerberos V5 acl file for host access . .nr rst2man-indent-level 0 . .de1 rstReportMargin \\$1 \\n[an-margin] level \\n[rst2man-indent-level] level margin: \\n[rst2man-indent\\n[rst2man-indent-level]] - \\n[rst2man-indent0] \\n[rst2man-indent1] \\n[rst2man-indent2] .. .de1 INDENT .\" .rstReportMargin pre: . RS \\$1 . nr rst2man-indent\\n[rst2man-indent-level] \\n[an-margin] . nr rst2man-indent-level +1 .\" .rstReportMargin post: .. .de UNINDENT . RE .\" indent \\n[an-margin] .\" old: \\n[rst2man-indent\\n[rst2man-indent-level]] .nr rst2man-indent-level -1 .\" new: \\n[rst2man-indent\\n[rst2man-indent-level]] .in \\n[rst2man-indent\\n[rst2man-indent-level]]u .. .SH DESCRIPTION .sp The .k5login file, which resides in a user\(aqs home directory, contains a list of the Kerberos principals. Anyone with valid tickets for a principal in the file is allowed host access with the UID of the user in whose home directory the file resides. One common use is to place a .k5login file in root\(aqs home directory, thereby granting system administrators remote root access to the host via Kerberos. .SH EXAMPLES .sp Suppose the user \fBalice\fP had a .k5login file in her home directory containing just the following line: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C bob@FOOBAR.ORG .ft P .fi .UNINDENT .UNINDENT .sp This would allow \fBbob\fP to use Kerberos network applications, such as ssh(1), to access \fBalice\fP\(aqs account, using \fBbob\fP\(aqs Kerberos tickets. In a default configuration (with \fBk5login_authoritative\fP set to true in \fIkrb5.conf(5)\fP), this .k5login file would not let \fBalice\fP use those network applications to access her account, since she is not listed! With no .k5login file, or with \fBk5login_authoritative\fP set to false, a default rule would permit the principal \fBalice\fP in the machine\(aqs default realm to access the \fBalice\fP account. .sp Let us further suppose that \fBalice\fP is a system administrator. Alice and the other system administrators would have their principals in root\(aqs .k5login file on each host: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C alice@BLEEP.COM joeadmin/root@BLEEP.COM .ft P .fi .UNINDENT .UNINDENT .sp This would allow either system administrator to log in to these hosts using their Kerberos tickets instead of having to type the root password. Note that because \fBbob\fP retains the Kerberos tickets for his own principal, \fBbob@FOOBAR.ORG\fP, he would not have any of the privileges that require \fBalice\fP\(aqs tickets, such as root access to any of the site\(aqs hosts, or the ability to change \fBalice\fP\(aqs password. .SH SEE ALSO .sp kerberos(1) .SH AUTHOR MIT .SH COPYRIGHT 1985-2017, MIT .\" Generated by docutils manpage writer. . krb5-1.16/src/man/kpropd.man0000644000704600001450000001266513211554426015546 0ustar ghudsonlibuuid.\" Man page generated from reStructuredText. . .TH "KPROPD" "8" " " "1.16" "MIT Kerberos" .SH NAME kpropd \- Kerberos V5 slave KDC update server . .nr rst2man-indent-level 0 . .de1 rstReportMargin \\$1 \\n[an-margin] level \\n[rst2man-indent-level] level margin: \\n[rst2man-indent\\n[rst2man-indent-level]] - \\n[rst2man-indent0] \\n[rst2man-indent1] \\n[rst2man-indent2] .. .de1 INDENT .\" .rstReportMargin pre: . RS \\$1 . nr rst2man-indent\\n[rst2man-indent-level] \\n[an-margin] . nr rst2man-indent-level +1 .\" .rstReportMargin post: .. .de UNINDENT . RE .\" indent \\n[an-margin] .\" old: \\n[rst2man-indent\\n[rst2man-indent-level]] .nr rst2man-indent-level -1 .\" new: \\n[rst2man-indent\\n[rst2man-indent-level]] .in \\n[rst2man-indent\\n[rst2man-indent-level]]u .. .SH SYNOPSIS .sp \fBkpropd\fP [\fB\-r\fP \fIrealm\fP] [\fB\-A\fP \fIadmin_server\fP] [\fB\-a\fP \fIacl_file\fP] [\fB\-f\fP \fIslave_dumpfile\fP] [\fB\-F\fP \fIprincipal_database\fP] [\fB\-p\fP \fIkdb5_util_prog\fP] [\fB\-P\fP \fIport\fP] [\fB\-\-pid\-file\fP=\fIpid_file\fP] [\fB\-d\fP] [\fB\-t\fP] .SH DESCRIPTION .sp The \fIkpropd\fP command runs on the slave KDC server. It listens for update requests made by the \fIkprop(8)\fP program. If incremental propagation is enabled, it periodically requests incremental updates from the master KDC. .sp When the slave receives a kprop request from the master, kpropd accepts the dumped KDC database and places it in a file, and then runs \fIkdb5_util(8)\fP to load the dumped database into the active database which is used by \fIkrb5kdc(8)\fP\&. This allows the master Kerberos server to use \fIkprop(8)\fP to propagate its database to the slave servers. Upon a successful download of the KDC database file, the slave Kerberos server will have an up\-to\-date KDC database. .sp Where incremental propagation is not used, kpropd is commonly invoked out of inetd(8) as a nowait service. This is done by adding a line to the \fB/etc/inetd.conf\fP file which looks like this: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C kprop stream tcp nowait root /usr/local/sbin/kpropd kpropd .ft P .fi .UNINDENT .UNINDENT .sp kpropd can also run as a standalone daemon, backgrounding itself and waiting for connections on port 754 (or the port specified with the \fB\-P\fP option if given). Standalone mode is required for incremental propagation. Starting in release 1.11, kpropd automatically detects whether it was run from inetd and runs in standalone mode if it is not. Prior to release 1.11, the \fB\-S\fP option is required to run kpropd in standalone mode; this option is now accepted for backward compatibility but does nothing. .sp Incremental propagation may be enabled with the \fBiprop_enable\fP variable in \fIkdc.conf(5)\fP\&. If incremental propagation is enabled, the slave periodically polls the master KDC for updates, at an interval determined by the \fBiprop_slave_poll\fP variable. If the slave receives updates, kpropd updates its log file with any updates from the master. \fIkproplog(8)\fP can be used to view a summary of the update entry log on the slave KDC. If incremental propagation is enabled, the principal \fBkiprop/slavehostname@REALM\fP (where \fIslavehostname\fP is the name of the slave KDC host, and \fIREALM\fP is the name of the Kerberos realm) must be present in the slave\(aqs keytab file. .sp \fIkproplog(8)\fP can be used to force full replication when iprop is enabled. .SH OPTIONS .INDENT 0.0 .TP .B \fB\-r\fP \fIrealm\fP Specifies the realm of the master server. .TP .B \fB\-A\fP \fIadmin_server\fP Specifies the server to be contacted for incremental updates; by default, the master admin server is contacted. .TP .B \fB\-f\fP \fIfile\fP Specifies the filename where the dumped principal database file is to be stored; by default the dumped database file is \fB@LOCALSTATEDIR@\fP\fB/krb5kdc\fP\fB/from_master\fP\&. .TP .B \fB\-p\fP Allows the user to specify the pathname to the \fIkdb5_util(8)\fP program; by default the pathname used is \fB@SBINDIR@\fP\fB/kdb5_util\fP\&. .TP .B \fB\-d\fP Turn on debug mode. In this mode, kpropd will not detach itself from the current job and run in the background. Instead, it will run in the foreground and print out debugging messages during the database propagation. .TP .B \fB\-t\fP In standalone mode without incremental propagation, exit after one dump file is received. In incremental propagation mode, exit as soon as the database is up to date, or if the master returns an error. .TP .B \fB\-P\fP Allow for an alternate port number for kpropd to listen on. This is only useful in combination with the \fB\-S\fP option. .TP .B \fB\-a\fP \fIacl_file\fP Allows the user to specify the path to the kpropd.acl file; by default the path used is \fB@LOCALSTATEDIR@\fP\fB/krb5kdc\fP\fB/kpropd.acl\fP\&. .TP .B \fB\-\-pid\-file\fP=\fIpid_file\fP In standalone mode, write the process ID of the daemon into \fIpid_file\fP\&. .UNINDENT .SH ENVIRONMENT .sp kpropd uses the following environment variables: .INDENT 0.0 .IP \(bu 2 \fBKRB5_CONFIG\fP .IP \(bu 2 \fBKRB5_KDC_PROFILE\fP .UNINDENT .SH FILES .INDENT 0.0 .TP .B kpropd.acl Access file for kpropd; the default location is \fB/usr/local/var/krb5kdc/kpropd.acl\fP\&. Each entry is a line containing the principal of a host from which the local machine will allow Kerberos database propagation via \fIkprop(8)\fP\&. .UNINDENT .SH SEE ALSO .sp \fIkprop(8)\fP, \fIkdb5_util(8)\fP, \fIkrb5kdc(8)\fP, inetd(8) .SH AUTHOR MIT .SH COPYRIGHT 1985-2017, MIT .\" Generated by docutils manpage writer. . krb5-1.16/src/man/kproplog.man0000644000704600001450000000652213211554426016077 0ustar ghudsonlibuuid.\" Man page generated from reStructuredText. . .TH "KPROPLOG" "8" " " "1.16" "MIT Kerberos" .SH NAME kproplog \- display the contents of the Kerberos principal update log . .nr rst2man-indent-level 0 . .de1 rstReportMargin \\$1 \\n[an-margin] level \\n[rst2man-indent-level] level margin: \\n[rst2man-indent\\n[rst2man-indent-level]] - \\n[rst2man-indent0] \\n[rst2man-indent1] \\n[rst2man-indent2] .. .de1 INDENT .\" .rstReportMargin pre: . RS \\$1 . nr rst2man-indent\\n[rst2man-indent-level] \\n[an-margin] . nr rst2man-indent-level +1 .\" .rstReportMargin post: .. .de UNINDENT . RE .\" indent \\n[an-margin] .\" old: \\n[rst2man-indent\\n[rst2man-indent-level]] .nr rst2man-indent-level -1 .\" new: \\n[rst2man-indent\\n[rst2man-indent-level]] .in \\n[rst2man-indent\\n[rst2man-indent-level]]u .. .SH SYNOPSIS .sp \fBkproplog\fP [\fB\-h\fP] [\fB\-e\fP \fInum\fP] [\-v] \fBkproplog\fP [\-R] .SH DESCRIPTION .sp The kproplog command displays the contents of the KDC database update log to standard output. It can be used to keep track of incremental updates to the principal database. The update log file contains the update log maintained by the \fIkadmind(8)\fP process on the master KDC server and the \fIkpropd(8)\fP process on the slave KDC servers. When updates occur, they are logged to this file. Subsequently any KDC slave configured for incremental updates will request the current data from the master KDC and update their log file with any updates returned. .sp The kproplog command requires read access to the update log file. It will display update entries only for the KDC it runs on. .sp If no options are specified, kproplog displays a summary of the update log. If invoked on the master, kproplog also displays all of the update entries. If invoked on a slave KDC server, kproplog displays only a summary of the updates, which includes the serial number of the last update received and the associated time stamp of the last update. .SH OPTIONS .INDENT 0.0 .TP .B \fB\-R\fP Reset the update log. This forces full resynchronization. If used on a slave then that slave will request a full resync. If used on the master then all slaves will request full resyncs. .TP .B \fB\-h\fP Display a summary of the update log. This information includes the database version number, state of the database, the number of updates in the log, the time stamp of the first and last update, and the version number of the first and last update entry. .TP .B \fB\-e\fP \fInum\fP Display the last \fInum\fP update entries in the log. This is useful when debugging synchronization between KDC servers. .TP .B \fB\-v\fP Display individual attributes per update. An example of the output generated for one entry: .INDENT 7.0 .INDENT 3.5 .sp .nf .ft C Update Entry Update serial # : 4 Update operation : Add Update principal : test@EXAMPLE.COM Update size : 424 Update committed : True Update time stamp : Fri Feb 20 23:37:42 2004 Attributes changed : 6 Principal Key data Password last changed Modifying principal Modification time TL data .ft P .fi .UNINDENT .UNINDENT .UNINDENT .SH ENVIRONMENT .sp kproplog uses the following environment variables: .INDENT 0.0 .IP \(bu 2 \fBKRB5_KDC_PROFILE\fP .UNINDENT .SH SEE ALSO .sp \fIkpropd(8)\fP .SH AUTHOR MIT .SH COPYRIGHT 1985-2017, MIT .\" Generated by docutils manpage writer. . krb5-1.16/src/man/sclient.man0000644000704600001450000000225613211554426015703 0ustar ghudsonlibuuid.\" Man page generated from reStructuredText. . .TH "SCLIENT" "1" " " "1.16" "MIT Kerberos" .SH NAME sclient \- sample Kerberos version 5 client . .nr rst2man-indent-level 0 . .de1 rstReportMargin \\$1 \\n[an-margin] level \\n[rst2man-indent-level] level margin: \\n[rst2man-indent\\n[rst2man-indent-level]] - \\n[rst2man-indent0] \\n[rst2man-indent1] \\n[rst2man-indent2] .. .de1 INDENT .\" .rstReportMargin pre: . RS \\$1 . nr rst2man-indent\\n[rst2man-indent-level] \\n[an-margin] . nr rst2man-indent-level +1 .\" .rstReportMargin post: .. .de UNINDENT . RE .\" indent \\n[an-margin] .\" old: \\n[rst2man-indent\\n[rst2man-indent-level]] .nr rst2man-indent-level -1 .\" new: \\n[rst2man-indent\\n[rst2man-indent-level]] .in \\n[rst2man-indent\\n[rst2man-indent-level]]u .. .SH SYNOPSIS .sp \fBsclient\fP \fIremotehost\fP .SH DESCRIPTION .sp sclient is a sample application, primarily useful for testing purposes. It contacts a sample server \fIsserver(8)\fP and authenticates to it using Kerberos version 5 tickets, then displays the server\(aqs response. .SH SEE ALSO .sp \fIkinit(1)\fP, \fIsserver(8)\fP .SH AUTHOR MIT .SH COPYRIGHT 1985-2017, MIT .\" Generated by docutils manpage writer. . krb5-1.16/src/man/klist.man0000644000704600001450000001002013211554426015354 0ustar ghudsonlibuuid.\" Man page generated from reStructuredText. . .TH "KLIST" "1" " " "1.16" "MIT Kerberos" .SH NAME klist \- list cached Kerberos tickets . .nr rst2man-indent-level 0 . .de1 rstReportMargin \\$1 \\n[an-margin] level \\n[rst2man-indent-level] level margin: \\n[rst2man-indent\\n[rst2man-indent-level]] - \\n[rst2man-indent0] \\n[rst2man-indent1] \\n[rst2man-indent2] .. .de1 INDENT .\" .rstReportMargin pre: . RS \\$1 . nr rst2man-indent\\n[rst2man-indent-level] \\n[an-margin] . nr rst2man-indent-level +1 .\" .rstReportMargin post: .. .de UNINDENT . RE .\" indent \\n[an-margin] .\" old: \\n[rst2man-indent\\n[rst2man-indent-level]] .nr rst2man-indent-level -1 .\" new: \\n[rst2man-indent\\n[rst2man-indent-level]] .in \\n[rst2man-indent\\n[rst2man-indent-level]]u .. .SH SYNOPSIS .sp \fBklist\fP [\fB\-e\fP] [[\fB\-c\fP] [\fB\-l\fP] [\fB\-A\fP] [\fB\-f\fP] [\fB\-s\fP] [\fB\-a\fP [\fB\-n\fP]]] [\fB\-C\fP] [\fB\-k\fP [\fB\-t\fP] [\fB\-K\fP]] [\fB\-V\fP] [\fIcache_name\fP|\fIkeytab_name\fP] .SH DESCRIPTION .sp klist lists the Kerberos principal and Kerberos tickets held in a credentials cache, or the keys held in a keytab file. .SH OPTIONS .INDENT 0.0 .TP .B \fB\-e\fP Displays the encryption types of the session key and the ticket for each credential in the credential cache, or each key in the keytab file. .TP .B \fB\-l\fP If a cache collection is available, displays a table summarizing the caches present in the collection. .TP .B \fB\-A\fP If a cache collection is available, displays the contents of all of the caches in the collection. .TP .B \fB\-c\fP List tickets held in a credentials cache. This is the default if neither \fB\-c\fP nor \fB\-k\fP is specified. .TP .B \fB\-f\fP Shows the flags present in the credentials, using the following abbreviations: .INDENT 7.0 .INDENT 3.5 .sp .nf .ft C F Forwardable f forwarded P Proxiable p proxy D postDateable d postdated R Renewable I Initial i invalid H Hardware authenticated A preAuthenticated T Transit policy checked O Okay as delegate a anonymous .ft P .fi .UNINDENT .UNINDENT .TP .B \fB\-s\fP Causes klist to run silently (produce no output). klist will exit with status 1 if the credentials cache cannot be read or is expired, and with status 0 otherwise. .TP .B \fB\-a\fP Display list of addresses in credentials. .TP .B \fB\-n\fP Show numeric addresses instead of reverse\-resolving addresses. .TP .B \fB\-C\fP List configuration data that has been stored in the credentials cache when klist encounters it. By default, configuration data is not listed. .TP .B \fB\-k\fP List keys held in a keytab file. .TP .B \fB\-i\fP In combination with \fB\-k\fP, defaults to using the default client keytab instead of the default acceptor keytab, if no name is given. .TP .B \fB\-t\fP Display the time entry timestamps for each keytab entry in the keytab file. .TP .B \fB\-K\fP Display the value of the encryption key in each keytab entry in the keytab file. .TP .B \fB\-V\fP Display the Kerberos version number and exit. .UNINDENT .sp If \fIcache_name\fP or \fIkeytab_name\fP is not specified, klist will display the credentials in the default credentials cache or keytab file as appropriate. If the \fBKRB5CCNAME\fP environment variable is set, its value is used to locate the default ticket cache. .SH ENVIRONMENT .sp klist uses the following environment variable: .INDENT 0.0 .TP .B \fBKRB5CCNAME\fP Location of the default Kerberos 5 credentials (ticket) cache, in the form \fItype\fP:\fIresidual\fP\&. If no \fItype\fP prefix is present, the \fBFILE\fP type is assumed. The type of the default cache may determine the availability of a cache collection; for instance, a default cache of type \fBDIR\fP causes caches within the directory to be present in the collection. .UNINDENT .SH FILES .INDENT 0.0 .TP .B \fB@CCNAME@\fP Default location of Kerberos 5 credentials cache .TP .B \fB@KTNAME@\fP Default location for the local host\(aqs keytab file. .UNINDENT .SH SEE ALSO .sp \fIkinit(1)\fP, \fIkdestroy(1)\fP .SH AUTHOR MIT .SH COPYRIGHT 1985-2017, MIT .\" Generated by docutils manpage writer. . krb5-1.16/src/man/k5srvutil.man0000644000704600001450000000535213211554426016212 0ustar ghudsonlibuuid.\" Man page generated from reStructuredText. . .TH "K5SRVUTIL" "1" " " "1.16" "MIT Kerberos" .SH NAME k5srvutil \- host key table (keytab) manipulation utility . .nr rst2man-indent-level 0 . .de1 rstReportMargin \\$1 \\n[an-margin] level \\n[rst2man-indent-level] level margin: \\n[rst2man-indent\\n[rst2man-indent-level]] - \\n[rst2man-indent0] \\n[rst2man-indent1] \\n[rst2man-indent2] .. .de1 INDENT .\" .rstReportMargin pre: . RS \\$1 . nr rst2man-indent\\n[rst2man-indent-level] \\n[an-margin] . nr rst2man-indent-level +1 .\" .rstReportMargin post: .. .de UNINDENT . RE .\" indent \\n[an-margin] .\" old: \\n[rst2man-indent\\n[rst2man-indent-level]] .nr rst2man-indent-level -1 .\" new: \\n[rst2man-indent\\n[rst2man-indent-level]] .in \\n[rst2man-indent\\n[rst2man-indent-level]]u .. .SH SYNOPSIS .sp \fBk5srvutil\fP \fIoperation\fP [\fB\-i\fP] [\fB\-f\fP \fIfilename\fP] [\fB\-e\fP \fIkeysalts\fP] .SH DESCRIPTION .sp k5srvutil allows an administrator to list keys currently in a keytab, to obtain new keys for a principal currently in a keytab, or to delete non\-current keys from a keytab. .sp \fIoperation\fP must be one of the following: .INDENT 0.0 .TP .B \fBlist\fP Lists the keys in a keytab, showing version number and principal name. .TP .B \fBchange\fP Uses the kadmin protocol to update the keys in the Kerberos database to new randomly\-generated keys, and updates the keys in the keytab to match. If a key\(aqs version number doesn\(aqt match the version number stored in the Kerberos server\(aqs database, then the operation will fail. If the \fB\-i\fP flag is given, k5srvutil will prompt for confirmation before changing each key. If the \fB\-k\fP option is given, the old and new keys will be displayed. Ordinarily, keys will be generated with the default encryption types and key salts. This can be overridden with the \fB\-e\fP option. Old keys are retained in the keytab so that existing tickets continue to work, but \fBdelold\fP should be used after such tickets expire, to prevent attacks against the old keys. .TP .B \fBdelold\fP Deletes keys that are not the most recent version from the keytab. This operation should be used some time after a change operation to remove old keys, after existing tickets issued for the service have expired. If the \fB\-i\fP flag is given, then k5srvutil will prompt for confirmation for each principal. .TP .B \fBdelete\fP Deletes particular keys in the keytab, interactively prompting for each key. .UNINDENT .sp In all cases, the default keytab is used unless this is overridden by the \fB\-f\fP option. .sp k5srvutil uses the \fIkadmin(1)\fP program to edit the keytab in place. .SH SEE ALSO .sp \fIkadmin(1)\fP, \fIktutil(1)\fP .SH AUTHOR MIT .SH COPYRIGHT 1985-2017, MIT .\" Generated by docutils manpage writer. . krb5-1.16/src/man/kdestroy.man0000644000704600001450000000511013211554426016076 0ustar ghudsonlibuuid.\" Man page generated from reStructuredText. . .TH "KDESTROY" "1" " " "1.16" "MIT Kerberos" .SH NAME kdestroy \- destroy Kerberos tickets . .nr rst2man-indent-level 0 . .de1 rstReportMargin \\$1 \\n[an-margin] level \\n[rst2man-indent-level] level margin: \\n[rst2man-indent\\n[rst2man-indent-level]] - \\n[rst2man-indent0] \\n[rst2man-indent1] \\n[rst2man-indent2] .. .de1 INDENT .\" .rstReportMargin pre: . RS \\$1 . nr rst2man-indent\\n[rst2man-indent-level] \\n[an-margin] . nr rst2man-indent-level +1 .\" .rstReportMargin post: .. .de UNINDENT . RE .\" indent \\n[an-margin] .\" old: \\n[rst2man-indent\\n[rst2man-indent-level]] .nr rst2man-indent-level -1 .\" new: \\n[rst2man-indent\\n[rst2man-indent-level]] .in \\n[rst2man-indent\\n[rst2man-indent-level]]u .. .SH SYNOPSIS .sp \fBkdestroy\fP [\fB\-A\fP] [\fB\-q\fP] [\fB\-c\fP \fIcache_name\fP] .SH DESCRIPTION .sp The kdestroy utility destroys the user\(aqs active Kerberos authorization tickets by overwriting and deleting the credentials cache that contains them. If the credentials cache is not specified, the default credentials cache is destroyed. .SH OPTIONS .INDENT 0.0 .TP .B \fB\-A\fP Destroys all caches in the collection, if a cache collection is available. .TP .B \fB\-q\fP Run quietly. Normally kdestroy beeps if it fails to destroy the user\(aqs tickets. The \fB\-q\fP flag suppresses this behavior. .TP .B \fB\-c\fP \fIcache_name\fP Use \fIcache_name\fP as the credentials (ticket) cache name and location; if this option is not used, the default cache name and location are used. .sp The default credentials cache may vary between systems. If the \fBKRB5CCNAME\fP environment variable is set, its value is used to name the default ticket cache. .UNINDENT .SH NOTE .sp Most installations recommend that you place the kdestroy command in your .logout file, so that your tickets are destroyed automatically when you log out. .SH ENVIRONMENT .sp kdestroy uses the following environment variable: .INDENT 0.0 .TP .B \fBKRB5CCNAME\fP Location of the default Kerberos 5 credentials (ticket) cache, in the form \fItype\fP:\fIresidual\fP\&. If no \fItype\fP prefix is present, the \fBFILE\fP type is assumed. The type of the default cache may determine the availability of a cache collection; for instance, a default cache of type \fBDIR\fP causes caches within the directory to be present in the collection. .UNINDENT .SH FILES .INDENT 0.0 .TP .B \fB@CCNAME@\fP Default location of Kerberos 5 credentials cache .UNINDENT .SH SEE ALSO .sp \fIkinit(1)\fP, \fIklist(1)\fP .SH AUTHOR MIT .SH COPYRIGHT 1985-2017, MIT .\" Generated by docutils manpage writer. . krb5-1.16/src/man/kprop.man0000644000704600001450000000376513211554426015403 0ustar ghudsonlibuuid.\" Man page generated from reStructuredText. . .TH "KPROP" "8" " " "1.16" "MIT Kerberos" .SH NAME kprop \- propagate a Kerberos V5 principal database to a slave server . .nr rst2man-indent-level 0 . .de1 rstReportMargin \\$1 \\n[an-margin] level \\n[rst2man-indent-level] level margin: \\n[rst2man-indent\\n[rst2man-indent-level]] - \\n[rst2man-indent0] \\n[rst2man-indent1] \\n[rst2man-indent2] .. .de1 INDENT .\" .rstReportMargin pre: . RS \\$1 . nr rst2man-indent\\n[rst2man-indent-level] \\n[an-margin] . nr rst2man-indent-level +1 .\" .rstReportMargin post: .. .de UNINDENT . RE .\" indent \\n[an-margin] .\" old: \\n[rst2man-indent\\n[rst2man-indent-level]] .nr rst2man-indent-level -1 .\" new: \\n[rst2man-indent\\n[rst2man-indent-level]] .in \\n[rst2man-indent\\n[rst2man-indent-level]]u .. .SH SYNOPSIS .sp \fBkprop\fP [\fB\-r\fP \fIrealm\fP] [\fB\-f\fP \fIfile\fP] [\fB\-d\fP] [\fB\-P\fP \fIport\fP] [\fB\-s\fP \fIkeytab\fP] \fIslave_host\fP .SH DESCRIPTION .sp kprop is used to securely propagate a Kerberos V5 database dump file from the master Kerberos server to a slave Kerberos server, which is specified by \fIslave_host\fP\&. The dump file must be created by \fIkdb5_util(8)\fP\&. .SH OPTIONS .INDENT 0.0 .TP .B \fB\-r\fP \fIrealm\fP Specifies the realm of the master server. .TP .B \fB\-f\fP \fIfile\fP Specifies the filename where the dumped principal database file is to be found; by default the dumped database file is normally \fB@LOCALSTATEDIR@\fP\fB/krb5kdc\fP\fB/slave_datatrans\fP\&. .TP .B \fB\-P\fP \fIport\fP Specifies the port to use to contact the \fIkpropd(8)\fP server on the remote host. .TP .B \fB\-d\fP Prints debugging information. .TP .B \fB\-s\fP \fIkeytab\fP Specifies the location of the keytab file. .UNINDENT .SH ENVIRONMENT .sp \fIkprop\fP uses the following environment variable: .INDENT 0.0 .IP \(bu 2 \fBKRB5_CONFIG\fP .UNINDENT .SH SEE ALSO .sp \fIkpropd(8)\fP, \fIkdb5_util(8)\fP, \fIkrb5kdc(8)\fP .SH AUTHOR MIT .SH COPYRIGHT 1985-2017, MIT .\" Generated by docutils manpage writer. . krb5-1.16/src/man/krb5.conf.man0000644000704600001450000013730413211554426016034 0ustar ghudsonlibuuid.\" Man page generated from reStructuredText. . .TH "KRB5.CONF" "5" " " "1.16" "MIT Kerberos" .SH NAME krb5.conf \- Kerberos configuration file . .nr rst2man-indent-level 0 . .de1 rstReportMargin \\$1 \\n[an-margin] level \\n[rst2man-indent-level] level margin: \\n[rst2man-indent\\n[rst2man-indent-level]] - \\n[rst2man-indent0] \\n[rst2man-indent1] \\n[rst2man-indent2] .. .de1 INDENT .\" .rstReportMargin pre: . RS \\$1 . nr rst2man-indent\\n[rst2man-indent-level] \\n[an-margin] . nr rst2man-indent-level +1 .\" .rstReportMargin post: .. .de UNINDENT . RE .\" indent \\n[an-margin] .\" old: \\n[rst2man-indent\\n[rst2man-indent-level]] .nr rst2man-indent-level -1 .\" new: \\n[rst2man-indent\\n[rst2man-indent-level]] .in \\n[rst2man-indent\\n[rst2man-indent-level]]u .. .sp The krb5.conf file contains Kerberos configuration information, including the locations of KDCs and admin servers for the Kerberos realms of interest, defaults for the current realm and for Kerberos applications, and mappings of hostnames onto Kerberos realms. Normally, you should install your krb5.conf file in the directory \fB/etc\fP\&. You can override the default location by setting the environment variable \fBKRB5_CONFIG\fP\&. Multiple colon\-separated filenames may be specified in \fBKRB5_CONFIG\fP; all files which are present will be read. Starting in release 1.14, directory names can also be specified in \fBKRB5_CONFIG\fP; all files within the directory whose names consist solely of alphanumeric characters, dashes, or underscores will be read. .SH STRUCTURE .sp The krb5.conf file is set up in the style of a Windows INI file. Sections are headed by the section name, in square brackets. Each section may contain zero or more relations, of the form: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C foo = bar .ft P .fi .UNINDENT .UNINDENT .sp or: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C fubar = { foo = bar baz = quux } .ft P .fi .UNINDENT .UNINDENT .sp Placing a \(aq*\(aq at the end of a line indicates that this is the \fIfinal\fP value for the tag. This means that neither the remainder of this configuration file nor any other configuration file will be checked for any other values for this tag. .sp For example, if you have the following lines: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C foo = bar* foo = baz .ft P .fi .UNINDENT .UNINDENT .sp then the second value of \fBfoo\fP (\fBbaz\fP) would never be read. .sp The krb5.conf file can include other files using either of the following directives at the beginning of a line: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C include FILENAME includedir DIRNAME .ft P .fi .UNINDENT .UNINDENT .sp \fIFILENAME\fP or \fIDIRNAME\fP should be an absolute path. The named file or directory must exist and be readable. Including a directory includes all files within the directory whose names consist solely of alphanumeric characters, dashes, or underscores. Starting in release 1.15, files with names ending in ".conf" are also included, unless the name begins with ".". Included profile files are syntactically independent of their parents, so each included file must begin with a section header. .sp The krb5.conf file can specify that configuration should be obtained from a loadable module, rather than the file itself, using the following directive at the beginning of a line before any section headers: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C module MODULEPATH:RESIDUAL .ft P .fi .UNINDENT .UNINDENT .sp \fIMODULEPATH\fP may be relative to the library path of the krb5 installation, or it may be an absolute path. \fIRESIDUAL\fP is provided to the module at initialization time. If krb5.conf uses a module directive, \fIkdc.conf(5)\fP should also use one if it exists. .SH SECTIONS .sp The krb5.conf file may contain the following sections: .TS center; |l|l|. _ T{ \fI\%[libdefaults]\fP T} T{ Settings used by the Kerberos V5 library T} _ T{ \fI\%[realms]\fP T} T{ Realm\-specific contact information and settings T} _ T{ \fI\%[domain_realm]\fP T} T{ Maps server hostnames to Kerberos realms T} _ T{ \fI\%[capaths]\fP T} T{ Authentication paths for non\-hierarchical cross\-realm T} _ T{ \fI\%[appdefaults]\fP T} T{ Settings used by some Kerberos V5 applications T} _ T{ \fI\%[plugins]\fP T} T{ Controls plugin module registration T} _ .TE .sp Additionally, krb5.conf may include any of the relations described in \fIkdc.conf(5)\fP, but it is not a recommended practice. .SS [libdefaults] .sp The libdefaults section may contain any of the following relations: .INDENT 0.0 .TP .B \fBallow_weak_crypto\fP If this flag is set to false, then weak encryption types (as noted in \fIEncryption_types\fP in \fIkdc.conf(5)\fP) will be filtered out of the lists \fBdefault_tgs_enctypes\fP, \fBdefault_tkt_enctypes\fP, and \fBpermitted_enctypes\fP\&. The default value for this tag is false, which may cause authentication failures in existing Kerberos infrastructures that do not support strong crypto. Users in affected environments should set this tag to true until their infrastructure adopts stronger ciphers. .TP .B \fBap_req_checksum_type\fP An integer which specifies the type of AP\-REQ checksum to use in authenticators. This variable should be unset so the appropriate checksum for the encryption key in use will be used. This can be set if backward compatibility requires a specific checksum type. See the \fBkdc_req_checksum_type\fP configuration option for the possible values and their meanings. .TP .B \fBcanonicalize\fP If this flag is set to true, initial ticket requests to the KDC will request canonicalization of the client principal name, and answers with different client principals than the requested principal will be accepted. The default value is false. .TP .B \fBccache_type\fP This parameter determines the format of credential cache types created by \fIkinit(1)\fP or other programs. The default value is 4, which represents the most current format. Smaller values can be used for compatibility with very old implementations of Kerberos which interact with credential caches on the same host. .TP .B \fBclockskew\fP Sets the maximum allowable amount of clockskew in seconds that the library will tolerate before assuming that a Kerberos message is invalid. The default value is 300 seconds, or five minutes. .sp The clockskew setting is also used when evaluating ticket start and expiration times. For example, tickets that have reached their expiration time can still be used (and renewed if they are renewable tickets) if they have been expired for a shorter duration than the \fBclockskew\fP setting. .TP .B \fBdefault_ccache_name\fP This relation specifies the name of the default credential cache. The default is \fB@CCNAME@\fP\&. This relation is subject to parameter expansion (see below). New in release 1.11. .TP .B \fBdefault_client_keytab_name\fP This relation specifies the name of the default keytab for obtaining client credentials. The default is \fB@CKTNAME@\fP\&. This relation is subject to parameter expansion (see below). New in release 1.11. .TP .B \fBdefault_keytab_name\fP This relation specifies the default keytab name to be used by application servers such as sshd. The default is \fB@KTNAME@\fP\&. This relation is subject to parameter expansion (see below). .TP .B \fBdefault_realm\fP Identifies the default Kerberos realm for the client. Set its value to your Kerberos realm. If this value is not set, then a realm must be specified with every Kerberos principal when invoking programs such as \fIkinit(1)\fP\&. .TP .B \fBdefault_tgs_enctypes\fP Identifies the supported list of session key encryption types that the client should request when making a TGS\-REQ, in order of preference from highest to lowest. The list may be delimited with commas or whitespace. See \fIEncryption_types\fP in \fIkdc.conf(5)\fP for a list of the accepted values for this tag. The default value is \fBaes256\-cts\-hmac\-sha1\-96 aes128\-cts\-hmac\-sha1\-96 aes256\-cts\-hmac\-sha384\-192 aes128\-cts\-hmac\-sha256\-128 des3\-cbc\-sha1 arcfour\-hmac\-md5 camellia256\-cts\-cmac camellia128\-cts\-cmac des\-cbc\-crc des\-cbc\-md5 des\-cbc\-md4\fP, but single\-DES encryption types will be implicitly removed from this list if the value of \fBallow_weak_crypto\fP is false. .sp Do not set this unless required for specific backward compatibility purposes; stale values of this setting can prevent clients from taking advantage of new stronger enctypes when the libraries are upgraded. .TP .B \fBdefault_tkt_enctypes\fP Identifies the supported list of session key encryption types that the client should request when making an AS\-REQ, in order of preference from highest to lowest. The format is the same as for default_tgs_enctypes. The default value for this tag is \fBaes256\-cts\-hmac\-sha1\-96 aes128\-cts\-hmac\-sha1\-96 aes256\-cts\-hmac\-sha384\-192 aes128\-cts\-hmac\-sha256\-128 des3\-cbc\-sha1 arcfour\-hmac\-md5 camellia256\-cts\-cmac camellia128\-cts\-cmac des\-cbc\-crc des\-cbc\-md5 des\-cbc\-md4\fP, but single\-DES encryption types will be implicitly removed from this list if the value of \fBallow_weak_crypto\fP is false. .sp Do not set this unless required for specific backward compatibility purposes; stale values of this setting can prevent clients from taking advantage of new stronger enctypes when the libraries are upgraded. .TP .B \fBdns_canonicalize_hostname\fP Indicate whether name lookups will be used to canonicalize hostnames for use in service principal names. Setting this flag to false can improve security by reducing reliance on DNS, but means that short hostnames will not be canonicalized to fully\-qualified hostnames. The default value is true. .TP .B \fBdns_lookup_kdc\fP Indicate whether DNS SRV records should be used to locate the KDCs and other servers for a realm, if they are not listed in the krb5.conf information for the realm. (Note that the admin_server entry must be in the krb5.conf realm information in order to contact kadmind, because the DNS implementation for kadmin is incomplete.) .sp Enabling this option does open up a type of denial\-of\-service attack, if someone spoofs the DNS records and redirects you to another server. However, it\(aqs no worse than a denial of service, because that fake KDC will be unable to decode anything you send it (besides the initial ticket request, which has no encrypted data), and anything the fake KDC sends will not be trusted without verification using some secret that it won\(aqt know. .TP .B \fBdns_uri_lookup\fP Indicate whether DNS URI records should be used to locate the KDCs and other servers for a realm, if they are not listed in the krb5.conf information for the realm. SRV records are used as a fallback if no URI records were found. The default value is true. New in release 1.15. .TP .B \fBerr_fmt\fP This relation allows for custom error message formatting. If a value is set, error messages will be formatted by substituting a normal error message for %M and an error code for %C in the value. .TP .B \fBextra_addresses\fP This allows a computer to use multiple local addresses, in order to allow Kerberos to work in a network that uses NATs while still using address\-restricted tickets. The addresses should be in a comma\-separated list. This option has no effect if \fBnoaddresses\fP is true. .TP .B \fBforwardable\fP If this flag is true, initial tickets will be forwardable by default, if allowed by the KDC. The default value is false. .TP .B \fBignore_acceptor_hostname\fP When accepting GSSAPI or krb5 security contexts for host\-based service principals, ignore any hostname passed by the calling application, and allow clients to authenticate to any service principal in the keytab matching the service name and realm name (if given). This option can improve the administrative flexibility of server applications on multihomed hosts, but could compromise the security of virtual hosting environments. The default value is false. New in release 1.10. .TP .B \fBk5login_authoritative\fP If this flag is true, principals must be listed in a local user\(aqs k5login file to be granted login access, if a \fI\&.k5login(5)\fP file exists. If this flag is false, a principal may still be granted login access through other mechanisms even if a k5login file exists but does not list the principal. The default value is true. .TP .B \fBk5login_directory\fP If set, the library will look for a local user\(aqs k5login file within the named directory, with a filename corresponding to the local username. If not set, the library will look for k5login files in the user\(aqs home directory, with the filename .k5login. For security reasons, .k5login files must be owned by the local user or by root. .TP .B \fBkcm_mach_service\fP On macOS only, determines the name of the bootstrap service used to contact the KCM daemon for the KCM credential cache type. If the value is \fB\-\fP, Mach RPC will not be used to contact the KCM daemon. The default value is \fBorg.h5l.kcm\fP\&. .TP .B \fBkcm_socket\fP Determines the path to the Unix domain socket used to access the KCM daemon for the KCM credential cache type. If the value is \fB\-\fP, Unix domain sockets will not be used to contact the KCM daemon. The default value is \fB/var/run/.heim_org.h5l.kcm\-socket\fP\&. .TP .B \fBkdc_default_options\fP Default KDC options (Xored for multiple values) when requesting initial tickets. By default it is set to 0x00000010 (KDC_OPT_RENEWABLE_OK). .TP .B \fBkdc_timesync\fP Accepted values for this relation are 1 or 0. If it is nonzero, client machines will compute the difference between their time and the time returned by the KDC in the timestamps in the tickets and use this value to correct for an inaccurate system clock when requesting service tickets or authenticating to services. This corrective factor is only used by the Kerberos library; it is not used to change the system clock. The default value is 1. .TP .B \fBkdc_req_checksum_type\fP An integer which specifies the type of checksum to use for the KDC requests, for compatibility with very old KDC implementations. This value is only used for DES keys; other keys use the preferred checksum type for those keys. .sp The possible values and their meanings are as follows. .TS center; |l|l|. _ T{ 1 T} T{ CRC32 T} _ T{ 2 T} T{ RSA MD4 T} _ T{ 3 T} T{ RSA MD4 DES T} _ T{ 4 T} T{ DES CBC T} _ T{ 7 T} T{ RSA MD5 T} _ T{ 8 T} T{ RSA MD5 DES T} _ T{ 9 T} T{ NIST SHA T} _ T{ 12 T} T{ HMAC SHA1 DES3 T} _ T{ \-138 T} T{ Microsoft MD5 HMAC checksum type T} _ .TE .TP .B \fBnoaddresses\fP If this flag is true, requests for initial tickets will not be made with address restrictions set, allowing the tickets to be used across NATs. The default value is true. .TP .B \fBpermitted_enctypes\fP Identifies all encryption types that are permitted for use in session key encryption. The default value for this tag is \fBaes256\-cts\-hmac\-sha1\-96 aes128\-cts\-hmac\-sha1\-96 aes256\-cts\-hmac\-sha384\-192 aes128\-cts\-hmac\-sha256\-128 des3\-cbc\-sha1 arcfour\-hmac\-md5 camellia256\-cts\-cmac camellia128\-cts\-cmac des\-cbc\-crc des\-cbc\-md5 des\-cbc\-md4\fP, but single\-DES encryption types will be implicitly removed from this list if the value of \fBallow_weak_crypto\fP is false. .TP .B \fBplugin_base_dir\fP If set, determines the base directory where krb5 plugins are located. The default value is the \fBkrb5/plugins\fP subdirectory of the krb5 library directory. .TP .B \fBpreferred_preauth_types\fP This allows you to set the preferred preauthentication types which the client will attempt before others which may be advertised by a KDC. The default value for this setting is "17, 16, 15, 14", which forces libkrb5 to attempt to use PKINIT if it is supported. .TP .B \fBproxiable\fP If this flag is true, initial tickets will be proxiable by default, if allowed by the KDC. The default value is false. .TP .B \fBrdns\fP If this flag is true, reverse name lookup will be used in addition to forward name lookup to canonicalizing hostnames for use in service principal names. If \fBdns_canonicalize_hostname\fP is set to false, this flag has no effect. The default value is true. .TP .B \fBrealm_try_domains\fP Indicate whether a host\(aqs domain components should be used to determine the Kerberos realm of the host. The value of this variable is an integer: \-1 means not to search, 0 means to try the host\(aqs domain itself, 1 means to also try the domain\(aqs immediate parent, and so forth. The library\(aqs usual mechanism for locating Kerberos realms is used to determine whether a domain is a valid realm, which may involve consulting DNS if \fBdns_lookup_kdc\fP is set. The default is not to search domain components. .TP .B \fBrenew_lifetime\fP (\fIduration\fP string.) Sets the default renewable lifetime for initial ticket requests. The default value is 0. .TP .B \fBsafe_checksum_type\fP An integer which specifies the type of checksum to use for the KRB\-SAFE requests. By default it is set to 8 (RSA MD5 DES). For compatibility with applications linked against DCE version 1.1 or earlier Kerberos libraries, use a value of 3 to use the RSA MD4 DES instead. This field is ignored when its value is incompatible with the session key type. See the \fBkdc_req_checksum_type\fP configuration option for the possible values and their meanings. .TP .B \fBticket_lifetime\fP (\fIduration\fP string.) Sets the default lifetime for initial ticket requests. The default value is 1 day. .TP .B \fBudp_preference_limit\fP When sending a message to the KDC, the library will try using TCP before UDP if the size of the message is above \fBudp_preference_limit\fP\&. If the message is smaller than \fBudp_preference_limit\fP, then UDP will be tried before TCP. Regardless of the size, both protocols will be tried if the first attempt fails. .TP .B \fBverify_ap_req_nofail\fP If this flag is true, then an attempt to verify initial credentials will fail if the client machine does not have a keytab. The default value is false. .UNINDENT .SS [realms] .sp Each tag in the [realms] section of the file is the name of a Kerberos realm. The value of the tag is a subsection with relations that define the properties of that particular realm. For each realm, the following tags may be specified in the realm\(aqs subsection: .INDENT 0.0 .TP .B \fBadmin_server\fP Identifies the host where the administration server is running. Typically, this is the master Kerberos server. This tag must be given a value in order to communicate with the \fIkadmind(8)\fP server for the realm. .TP .B \fBauth_to_local\fP This tag allows you to set a general rule for mapping principal names to local user names. It will be used if there is not an explicit mapping for the principal name that is being translated. The possible values are: .INDENT 7.0 .TP .B \fBRULE:\fP\fIexp\fP The local name will be formulated from \fIexp\fP\&. .sp The format for \fIexp\fP is \fB[\fP\fIn\fP\fB:\fP\fIstring\fP\fB](\fP\fIregexp\fP\fB)s/\fP\fIpattern\fP\fB/\fP\fIreplacement\fP\fB/g\fP\&. The integer \fIn\fP indicates how many components the target principal should have. If this matches, then a string will be formed from \fIstring\fP, substituting the realm of the principal for \fB$0\fP and the \fIn\fP\(aqth component of the principal for \fB$n\fP (e.g., if the principal was \fBjohndoe/admin\fP then \fB[2:$2$1foo]\fP would result in the string \fBadminjohndoefoo\fP). If this string matches \fIregexp\fP, then the \fBs//[g]\fP substitution command will be run over the string. The optional \fBg\fP will cause the substitution to be global over the \fIstring\fP, instead of replacing only the first match in the \fIstring\fP\&. .TP .B \fBDEFAULT\fP The principal name will be used as the local user name. If the principal has more than one component or is not in the default realm, this rule is not applicable and the conversion will fail. .UNINDENT .sp For example: .INDENT 7.0 .INDENT 3.5 .sp .nf .ft C [realms] ATHENA.MIT.EDU = { auth_to_local = RULE:[2:$1](johndoe)s/^.*$/guest/ auth_to_local = RULE:[2:$1;$2](^.*;admin$)s/;admin$// auth_to_local = RULE:[2:$2](^.*;root)s/^.*$/root/ auto_to_local = DEFAULT } .ft P .fi .UNINDENT .UNINDENT .sp would result in any principal without \fBroot\fP or \fBadmin\fP as the second component to be translated with the default rule. A principal with a second component of \fBadmin\fP will become its first component. \fBroot\fP will be used as the local name for any principal with a second component of \fBroot\fP\&. The exception to these two rules are any principals \fBjohndoe/*\fP, which will always get the local name \fBguest\fP\&. .TP .B \fBauth_to_local_names\fP This subsection allows you to set explicit mappings from principal names to local user names. The tag is the mapping name, and the value is the corresponding local user name. .TP .B \fBdefault_domain\fP This tag specifies the domain used to expand hostnames when translating Kerberos 4 service principals to Kerberos 5 principals (for example, when converting \fBrcmd.hostname\fP to \fBhost/hostname.domain\fP). .TP .B \fBhttp_anchors\fP When KDCs and kpasswd servers are accessed through HTTPS proxies, this tag can be used to specify the location of the CA certificate which should be trusted to issue the certificate for a proxy server. If left unspecified, the system\-wide default set of CA certificates is used. .sp The syntax for values is similar to that of values for the \fBpkinit_anchors\fP tag: .sp \fBFILE:\fP \fIfilename\fP .sp \fIfilename\fP is assumed to be the name of an OpenSSL\-style ca\-bundle file. .sp \fBDIR:\fP \fIdirname\fP .sp \fIdirname\fP is assumed to be an directory which contains CA certificates. All files in the directory will be examined; if they contain certificates (in PEM format), they will be used. .sp \fBENV:\fP \fIenvvar\fP .sp \fIenvvar\fP specifies the name of an environment variable which has been set to a value conforming to one of the previous values. For example, \fBENV:X509_PROXY_CA\fP, where environment variable \fBX509_PROXY_CA\fP has been set to \fBFILE:/tmp/my_proxy.pem\fP\&. .TP .B \fBkdc\fP The name or address of a host running a KDC for that realm. An optional port number, separated from the hostname by a colon, may be included. If the name or address contains colons (for example, if it is an IPv6 address), enclose it in square brackets to distinguish the colon from a port separator. For your computer to be able to communicate with the KDC for each realm, this tag must be given a value in each realm subsection in the configuration file, or there must be DNS SRV records specifying the KDCs. .TP .B \fBkpasswd_server\fP Points to the server where all the password changes are performed. If there is no such entry, the port 464 on the \fBadmin_server\fP host will be tried. .TP .B \fBmaster_kdc\fP Identifies the master KDC(s). Currently, this tag is used in only one case: If an attempt to get credentials fails because of an invalid password, the client software will attempt to contact the master KDC, in case the user\(aqs password has just been changed, and the updated database has not been propagated to the slave servers yet. .TP .B \fBv4_instance_convert\fP This subsection allows the administrator to configure exceptions to the \fBdefault_domain\fP mapping rule. It contains V4 instances (the tag name) which should be translated to some specific hostname (the tag value) as the second component in a Kerberos V5 principal name. .TP .B \fBv4_realm\fP This relation is used by the krb524 library routines when converting a V5 principal name to a V4 principal name. It is used when the V4 realm name and the V5 realm name are not the same, but still share the same principal names and passwords. The tag value is the Kerberos V4 realm name. .UNINDENT .SS [domain_realm] .sp The [domain_realm] section provides a translation from a domain name or hostname to a Kerberos realm name. The tag name can be a host name or domain name, where domain names are indicated by a prefix of a period (\fB\&.\fP). The value of the relation is the Kerberos realm name for that particular host or domain. A host name relation implicitly provides the corresponding domain name relation, unless an explicit domain name relation is provided. The Kerberos realm may be identified either in the \fI\%realms\fP section or using DNS SRV records. Host names and domain names should be in lower case. For example: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C [domain_realm] crash.mit.edu = TEST.ATHENA.MIT.EDU .dev.mit.edu = TEST.ATHENA.MIT.EDU mit.edu = ATHENA.MIT.EDU .ft P .fi .UNINDENT .UNINDENT .sp maps the host with the name \fBcrash.mit.edu\fP into the \fBTEST.ATHENA.MIT.EDU\fP realm. The second entry maps all hosts under the domain \fBdev.mit.edu\fP into the \fBTEST.ATHENA.MIT.EDU\fP realm, but not the host with the name \fBdev.mit.edu\fP\&. That host is matched by the third entry, which maps the host \fBmit.edu\fP and all hosts under the domain \fBmit.edu\fP that do not match a preceding rule into the realm \fBATHENA.MIT.EDU\fP\&. .sp If no translation entry applies to a hostname used for a service principal for a service ticket request, the library will try to get a referral to the appropriate realm from the client realm\(aqs KDC. If that does not succeed, the host\(aqs realm is considered to be the hostname\(aqs domain portion converted to uppercase, unless the \fBrealm_try_domains\fP setting in [libdefaults] causes a different parent domain to be used. .SS [capaths] .sp In order to perform direct (non\-hierarchical) cross\-realm authentication, configuration is needed to determine the authentication paths between realms. .sp A client will use this section to find the authentication path between its realm and the realm of the server. The server will use this section to verify the authentication path used by the client, by checking the transited field of the received ticket. .sp There is a tag for each participating client realm, and each tag has subtags for each of the server realms. The value of the subtags is an intermediate realm which may participate in the cross\-realm authentication. The subtags may be repeated if there is more then one intermediate realm. A value of "." means that the two realms share keys directly, and no intermediate realms should be allowed to participate. .sp Only those entries which will be needed on the client or the server need to be present. A client needs a tag for its local realm with subtags for all the realms of servers it will need to authenticate to. A server needs a tag for each realm of the clients it will serve, with a subtag of the server realm. .sp For example, \fBANL.GOV\fP, \fBPNL.GOV\fP, and \fBNERSC.GOV\fP all wish to use the \fBES.NET\fP realm as an intermediate realm. ANL has a sub realm of \fBTEST.ANL.GOV\fP which will authenticate with \fBNERSC.GOV\fP but not \fBPNL.GOV\fP\&. The [capaths] section for \fBANL.GOV\fP systems would look like this: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C [capaths] ANL.GOV = { TEST.ANL.GOV = . PNL.GOV = ES.NET NERSC.GOV = ES.NET ES.NET = . } TEST.ANL.GOV = { ANL.GOV = . } PNL.GOV = { ANL.GOV = ES.NET } NERSC.GOV = { ANL.GOV = ES.NET } ES.NET = { ANL.GOV = . } .ft P .fi .UNINDENT .UNINDENT .sp The [capaths] section of the configuration file used on \fBNERSC.GOV\fP systems would look like this: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C [capaths] NERSC.GOV = { ANL.GOV = ES.NET TEST.ANL.GOV = ES.NET TEST.ANL.GOV = ANL.GOV PNL.GOV = ES.NET ES.NET = . } ANL.GOV = { NERSC.GOV = ES.NET } PNL.GOV = { NERSC.GOV = ES.NET } ES.NET = { NERSC.GOV = . } TEST.ANL.GOV = { NERSC.GOV = ANL.GOV NERSC.GOV = ES.NET } .ft P .fi .UNINDENT .UNINDENT .sp When a subtag is used more than once within a tag, clients will use the order of values to determine the path. The order of values is not important to servers. .SS [appdefaults] .sp Each tag in the [appdefaults] section names a Kerberos V5 application or an option that is used by some Kerberos V5 application[s]. The value of the tag defines the default behaviors for that application. .sp For example: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C [appdefaults] telnet = { ATHENA.MIT.EDU = { option1 = false } } telnet = { option1 = true option2 = true } ATHENA.MIT.EDU = { option2 = false } option2 = true .ft P .fi .UNINDENT .UNINDENT .sp The above four ways of specifying the value of an option are shown in order of decreasing precedence. In this example, if telnet is running in the realm EXAMPLE.COM, it should, by default, have option1 and option2 set to true. However, a telnet program in the realm \fBATHENA.MIT.EDU\fP should have \fBoption1\fP set to false and \fBoption2\fP set to true. Any other programs in ATHENA.MIT.EDU should have \fBoption2\fP set to false by default. Any programs running in other realms should have \fBoption2\fP set to true. .sp The list of specifiable options for each application may be found in that application\(aqs man pages. The application defaults specified here are overridden by those specified in the \fI\%realms\fP section. .SS [plugins] .INDENT 0.0 .INDENT 3.5 .INDENT 0.0 .IP \(bu 2 \fI\%pwqual\fP interface .IP \(bu 2 \fI\%kadm5_hook\fP interface .IP \(bu 2 \fI\%clpreauth\fP and \fI\%kdcpreauth\fP interfaces .UNINDENT .UNINDENT .UNINDENT .sp Tags in the [plugins] section can be used to register dynamic plugin modules and to turn modules on and off. Not every krb5 pluggable interface uses the [plugins] section; the ones that do are documented here. .sp New in release 1.9. .sp Each pluggable interface corresponds to a subsection of [plugins]. All subsections support the same tags: .INDENT 0.0 .TP .B \fBdisable\fP This tag may have multiple values. If there are values for this tag, then the named modules will be disabled for the pluggable interface. .TP .B \fBenable_only\fP This tag may have multiple values. If there are values for this tag, then only the named modules will be enabled for the pluggable interface. .TP .B \fBmodule\fP This tag may have multiple values. Each value is a string of the form \fBmodulename:pathname\fP, which causes the shared object located at \fIpathname\fP to be registered as a dynamic module named \fImodulename\fP for the pluggable interface. If \fIpathname\fP is not an absolute path, it will be treated as relative to the \fBplugin_base_dir\fP value from \fI\%[libdefaults]\fP\&. .UNINDENT .sp For pluggable interfaces where module order matters, modules registered with a \fBmodule\fP tag normally come first, in the order they are registered, followed by built\-in modules in the order they are documented below. If \fBenable_only\fP tags are used, then the order of those tags overrides the normal module order. .sp The following subsections are currently supported within the [plugins] section: .SS ccselect interface .sp The ccselect subsection controls modules for credential cache selection within a cache collection. In addition to any registered dynamic modules, the following built\-in modules exist (and may be disabled with the disable tag): .INDENT 0.0 .TP .B \fBk5identity\fP Uses a .k5identity file in the user\(aqs home directory to select a client principal .TP .B \fBrealm\fP Uses the service realm to guess an appropriate cache from the collection .TP .B \fBhostname\fP If the service principal is host\-based, uses the service hostname to guess an appropriate cache from the collection .UNINDENT .SS pwqual interface .sp The pwqual subsection controls modules for the password quality interface, which is used to reject weak passwords when passwords are changed. The following built\-in modules exist for this interface: .INDENT 0.0 .TP .B \fBdict\fP Checks against the realm dictionary file .TP .B \fBempty\fP Rejects empty passwords .TP .B \fBhesiod\fP Checks against user information stored in Hesiod (only if Kerberos was built with Hesiod support) .TP .B \fBprinc\fP Checks against components of the principal name .UNINDENT .SS kadm5_hook interface .sp The kadm5_hook interface provides plugins with information on principal creation, modification, password changes and deletion. This interface can be used to write a plugin to synchronize MIT Kerberos with another database such as Active Directory. No plugins are built in for this interface. .SS kadm5_auth interface .sp The kadm5_auth section (introduced in release 1.16) controls modules for the kadmin authorization interface, which determines whether a client principal is allowed to perform a kadmin operation. The following built\-in modules exist for this interface: .INDENT 0.0 .TP .B \fBacl\fP This module reads the \fIkadm5.acl(5)\fP file, and authorizes operations which are allowed according to the rules in the file. .TP .B \fBself\fP This module authorizes self\-service operations including password changes, creation of new random keys, fetching the client\(aqs principal record or string attributes, and fetching the policy record associated with the client principal. .UNINDENT .SS clpreauth and kdcpreauth interfaces .sp The clpreauth and kdcpreauth interfaces allow plugin modules to provide client and KDC preauthentication mechanisms. The following built\-in modules exist for these interfaces: .INDENT 0.0 .TP .B \fBpkinit\fP This module implements the PKINIT preauthentication mechanism. .TP .B \fBencrypted_challenge\fP This module implements the encrypted challenge FAST factor. .TP .B \fBencrypted_timestamp\fP This module implements the encrypted timestamp mechanism. .UNINDENT .SS hostrealm interface .sp The hostrealm section (introduced in release 1.12) controls modules for the host\-to\-realm interface, which affects the local mapping of hostnames to realm names and the choice of default realm. The following built\-in modules exist for this interface: .INDENT 0.0 .TP .B \fBprofile\fP This module consults the [domain_realm] section of the profile for authoritative host\-to\-realm mappings, and the \fBdefault_realm\fP variable for the default realm. .TP .B \fBdns\fP This module looks for DNS records for fallback host\-to\-realm mappings and the default realm. It only operates if the \fBdns_lookup_realm\fP variable is set to true. .TP .B \fBdomain\fP This module applies heuristics for fallback host\-to\-realm mappings. It implements the \fBrealm_try_domains\fP variable, and uses the uppercased parent domain of the hostname if that does not produce a result. .UNINDENT .SS localauth interface .sp The localauth section (introduced in release 1.12) controls modules for the local authorization interface, which affects the relationship between Kerberos principals and local system accounts. The following built\-in modules exist for this interface: .INDENT 0.0 .TP .B \fBdefault\fP This module implements the \fBDEFAULT\fP type for \fBauth_to_local\fP values. .TP .B \fBrule\fP This module implements the \fBRULE\fP type for \fBauth_to_local\fP values. .TP .B \fBnames\fP This module looks for an \fBauth_to_local_names\fP mapping for the principal name. .TP .B \fBauth_to_local\fP This module processes \fBauth_to_local\fP values in the default realm\(aqs section, and applies the default method if no \fBauth_to_local\fP values exist. .TP .B \fBk5login\fP This module authorizes a principal to a local account according to the account\(aqs \fI\&.k5login(5)\fP file. .TP .B \fBan2ln\fP This module authorizes a principal to a local account if the principal name maps to the local account name. .UNINDENT .SS certauth interface .sp The certauth section (introduced in release 1.16) controls modules for the certificate authorization interface, which determines whether a certificate is allowed to preauthenticate a user via PKINIT. The following built\-in modules exist for this interface: .INDENT 0.0 .TP .B \fBpkinit_san\fP This module authorizes the certificate if it contains a PKINIT Subject Alternative Name for the requested client principal, or a Microsoft UPN SAN matching the principal if \fBpkinit_allow_upn\fP is set to true for the realm. .TP .B \fBpkinit_eku\fP This module rejects the certificate if it does not contain an Extended Key Usage attribute consistent with the \fBpkinit_eku_checking\fP value for the realm. .TP .B \fBdbmatch\fP This module authorizes or rejects the certificate according to whether it matches the \fBpkinit_cert_match\fP string attribute on the client principal, if that attribute is present. .UNINDENT .SH PKINIT OPTIONS .sp \fBNOTE:\fP .INDENT 0.0 .INDENT 3.5 The following are PKINIT\-specific options. These values may be specified in [libdefaults] as global defaults, or within a realm\-specific subsection of [libdefaults], or may be specified as realm\-specific values in the [realms] section. A realm\-specific value overrides, not adds to, a generic [libdefaults] specification. The search order is: .UNINDENT .UNINDENT .INDENT 0.0 .IP 1. 3 realm\-specific subsection of [libdefaults]: .INDENT 3.0 .INDENT 3.5 .sp .nf .ft C [libdefaults] EXAMPLE.COM = { pkinit_anchors = FILE:/usr/local/example.com.crt } .ft P .fi .UNINDENT .UNINDENT .IP 2. 3 realm\-specific value in the [realms] section: .INDENT 3.0 .INDENT 3.5 .sp .nf .ft C [realms] OTHERREALM.ORG = { pkinit_anchors = FILE:/usr/local/otherrealm.org.crt } .ft P .fi .UNINDENT .UNINDENT .IP 3. 3 generic value in the [libdefaults] section: .INDENT 3.0 .INDENT 3.5 .sp .nf .ft C [libdefaults] pkinit_anchors = DIR:/usr/local/generic_trusted_cas/ .ft P .fi .UNINDENT .UNINDENT .UNINDENT .SS Specifying PKINIT identity information .sp The syntax for specifying Public Key identity, trust, and revocation information for PKINIT is as follows: .INDENT 0.0 .TP .B \fBFILE:\fP\fIfilename\fP[\fB,\fP\fIkeyfilename\fP] This option has context\-specific behavior. .sp In \fBpkinit_identity\fP or \fBpkinit_identities\fP, \fIfilename\fP specifies the name of a PEM\-format file containing the user\(aqs certificate. If \fIkeyfilename\fP is not specified, the user\(aqs private key is expected to be in \fIfilename\fP as well. Otherwise, \fIkeyfilename\fP is the name of the file containing the private key. .sp In \fBpkinit_anchors\fP or \fBpkinit_pool\fP, \fIfilename\fP is assumed to be the name of an OpenSSL\-style ca\-bundle file. .TP .B \fBDIR:\fP\fIdirname\fP This option has context\-specific behavior. .sp In \fBpkinit_identity\fP or \fBpkinit_identities\fP, \fIdirname\fP specifies a directory with files named \fB*.crt\fP and \fB*.key\fP where the first part of the file name is the same for matching pairs of certificate and private key files. When a file with a name ending with \fB\&.crt\fP is found, a matching file ending with \fB\&.key\fP is assumed to contain the private key. If no such file is found, then the certificate in the \fB\&.crt\fP is not used. .sp In \fBpkinit_anchors\fP or \fBpkinit_pool\fP, \fIdirname\fP is assumed to be an OpenSSL\-style hashed CA directory where each CA cert is stored in a file named \fBhash\-of\-ca\-cert.#\fP\&. This infrastructure is encouraged, but all files in the directory will be examined and if they contain certificates (in PEM format), they will be used. .sp In \fBpkinit_revoke\fP, \fIdirname\fP is assumed to be an OpenSSL\-style hashed CA directory where each revocation list is stored in a file named \fBhash\-of\-ca\-cert.r#\fP\&. This infrastructure is encouraged, but all files in the directory will be examined and if they contain a revocation list (in PEM format), they will be used. .TP .B \fBPKCS12:\fP\fIfilename\fP \fIfilename\fP is the name of a PKCS #12 format file, containing the user\(aqs certificate and private key. .TP .B \fBPKCS11:\fP[\fBmodule_name=\fP]\fImodname\fP[\fB:slotid=\fP\fIslot\-id\fP][\fB:token=\fP\fItoken\-label\fP][\fB:certid=\fP\fIcert\-id\fP][\fB:certlabel=\fP\fIcert\-label\fP] All keyword/values are optional. \fImodname\fP specifies the location of a library implementing PKCS #11. If a value is encountered with no keyword, it is assumed to be the \fImodname\fP\&. If no module\-name is specified, the default is \fBopensc\-pkcs11.so\fP\&. \fBslotid=\fP and/or \fBtoken=\fP may be specified to force the use of a particular smard card reader or token if there is more than one available. \fBcertid=\fP and/or \fBcertlabel=\fP may be specified to force the selection of a particular certificate on the device. See the \fBpkinit_cert_match\fP configuration option for more ways to select a particular certificate to use for PKINIT. .TP .B \fBENV:\fP\fIenvvar\fP \fIenvvar\fP specifies the name of an environment variable which has been set to a value conforming to one of the previous values. For example, \fBENV:X509_PROXY\fP, where environment variable \fBX509_PROXY\fP has been set to \fBFILE:/tmp/my_proxy.pem\fP\&. .UNINDENT .SS PKINIT krb5.conf options .INDENT 0.0 .TP .B \fBpkinit_anchors\fP Specifies the location of trusted anchor (root) certificates which the client trusts to sign KDC certificates. This option may be specified multiple times. These values from the config file are not used if the user specifies X509_anchors on the command line. .TP .B \fBpkinit_cert_match\fP Specifies matching rules that the client certificate must match before it is used to attempt PKINIT authentication. If a user has multiple certificates available (on a smart card, or via other media), there must be exactly one certificate chosen before attempting PKINIT authentication. This option may be specified multiple times. All the available certificates are checked against each rule in order until there is a match of exactly one certificate. .sp The Subject and Issuer comparison strings are the \fI\%RFC 2253\fP string representations from the certificate Subject DN and Issuer DN values. .sp The syntax of the matching rules is: .INDENT 7.0 .INDENT 3.5 [\fIrelation\-operator\fP]\fIcomponent\-rule\fP ... .UNINDENT .UNINDENT .sp where: .INDENT 7.0 .TP .B \fIrelation\-operator\fP can be either \fB&&\fP, meaning all component rules must match, or \fB||\fP, meaning only one component rule must match. The default is \fB&&\fP\&. .TP .B \fIcomponent\-rule\fP can be one of the following. Note that there is no punctuation or whitespace between component rules. .INDENT 7.0 .INDENT 3.5 .nf \fB\fP\fIregular\-expression\fP \fB\fP\fIregular\-expression\fP \fB\fP\fIregular\-expression\fP \fB\fP\fIextended\-key\-usage\-list\fP \fB\fP\fIkey\-usage\-list\fP .fi .sp .UNINDENT .UNINDENT .sp \fIextended\-key\-usage\-list\fP is a comma\-separated list of required Extended Key Usage values. All values in the list must be present in the certificate. Extended Key Usage values can be: .INDENT 7.0 .IP \(bu 2 pkinit .IP \(bu 2 msScLogin .IP \(bu 2 clientAuth .IP \(bu 2 emailProtection .UNINDENT .sp \fIkey\-usage\-list\fP is a comma\-separated list of required Key Usage values. All values in the list must be present in the certificate. Key Usage values can be: .INDENT 7.0 .IP \(bu 2 digitalSignature .IP \(bu 2 keyEncipherment .UNINDENT .UNINDENT .sp Examples: .INDENT 7.0 .INDENT 3.5 .sp .nf .ft C pkinit_cert_match = ||.*DoE.*.*@EXAMPLE.COM pkinit_cert_match = &&msScLogin,clientAuth.*DoE.* pkinit_cert_match = msScLogin,clientAuthdigitalSignature .ft P .fi .UNINDENT .UNINDENT .TP .B \fBpkinit_eku_checking\fP This option specifies what Extended Key Usage value the KDC certificate presented to the client must contain. (Note that if the KDC certificate has the pkinit SubjectAlternativeName encoded as the Kerberos TGS name, EKU checking is not necessary since the issuing CA has certified this as a KDC certificate.) The values recognized in the krb5.conf file are: .INDENT 7.0 .TP .B \fBkpKDC\fP This is the default value and specifies that the KDC must have the id\-pkinit\-KPKdc EKU as defined in \fI\%RFC 4556\fP\&. .TP .B \fBkpServerAuth\fP If \fBkpServerAuth\fP is specified, a KDC certificate with the id\-kp\-serverAuth EKU will be accepted. This key usage value is used in most commercially issued server certificates. .TP .B \fBnone\fP If \fBnone\fP is specified, then the KDC certificate will not be checked to verify it has an acceptable EKU. The use of this option is not recommended. .UNINDENT .TP .B \fBpkinit_dh_min_bits\fP Specifies the size of the Diffie\-Hellman key the client will attempt to use. The acceptable values are 1024, 2048, and 4096. The default is 2048. .TP .B \fBpkinit_identities\fP Specifies the location(s) to be used to find the user\(aqs X.509 identity information. This option may be specified multiple times. Each value is attempted in order until identity information is found and authentication is attempted. Note that these values are not used if the user specifies \fBX509_user_identity\fP on the command line. .TP .B \fBpkinit_kdc_hostname\fP The presense of this option indicates that the client is willing to accept a KDC certificate with a dNSName SAN (Subject Alternative Name) rather than requiring the id\-pkinit\-san as defined in \fI\%RFC 4556\fP\&. This option may be specified multiple times. Its value should contain the acceptable hostname for the KDC (as contained in its certificate). .TP .B \fBpkinit_pool\fP Specifies the location of intermediate certificates which may be used by the client to complete the trust chain between a KDC certificate and a trusted anchor. This option may be specified multiple times. .TP .B \fBpkinit_require_crl_checking\fP The default certificate verification process will always check the available revocation information to see if a certificate has been revoked. If a match is found for the certificate in a CRL, verification fails. If the certificate being verified is not listed in a CRL, or there is no CRL present for its issuing CA, and \fBpkinit_require_crl_checking\fP is false, then verification succeeds. .sp However, if \fBpkinit_require_crl_checking\fP is true and there is no CRL information available for the issuing CA, then verification fails. .sp \fBpkinit_require_crl_checking\fP should be set to true if the policy is such that up\-to\-date CRLs must be present for every CA. .TP .B \fBpkinit_revoke\fP Specifies the location of Certificate Revocation List (CRL) information to be used by the client when verifying the validity of the KDC certificate presented. This option may be specified multiple times. .UNINDENT .SH PARAMETER EXPANSION .sp Starting with release 1.11, several variables, such as \fBdefault_keytab_name\fP, allow parameters to be expanded. Valid parameters are: .INDENT 0.0 .INDENT 3.5 .TS center; |l|l|. _ T{ %{TEMP} T} T{ Temporary directory T} _ T{ %{uid} T} T{ Unix real UID or Windows SID T} _ T{ %{euid} T} T{ Unix effective user ID or Windows SID T} _ T{ %{USERID} T} T{ Same as %{uid} T} _ T{ %{null} T} T{ Empty string T} _ T{ %{LIBDIR} T} T{ Installation library directory T} _ T{ %{BINDIR} T} T{ Installation binary directory T} _ T{ %{SBINDIR} T} T{ Installation admin binary directory T} _ T{ %{username} T} T{ (Unix) Username of effective user ID T} _ T{ %{APPDATA} T} T{ (Windows) Roaming application data for current user T} _ T{ %{COMMON_APPDATA} T} T{ (Windows) Application data for all users T} _ T{ %{LOCAL_APPDATA} T} T{ (Windows) Local application data for current user T} _ T{ %{SYSTEM} T} T{ (Windows) Windows system folder T} _ T{ %{WINDOWS} T} T{ (Windows) Windows folder T} _ T{ %{USERCONFIG} T} T{ (Windows) Per\-user MIT krb5 config file directory T} _ T{ %{COMMONCONFIG} T} T{ (Windows) Common MIT krb5 config file directory T} _ .TE .UNINDENT .UNINDENT .SH SAMPLE KRB5.CONF FILE .sp Here is an example of a generic krb5.conf file: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C [libdefaults] default_realm = ATHENA.MIT.EDU dns_lookup_kdc = true dns_lookup_realm = false [realms] ATHENA.MIT.EDU = { kdc = kerberos.mit.edu kdc = kerberos\-1.mit.edu kdc = kerberos\-2.mit.edu admin_server = kerberos.mit.edu master_kdc = kerberos.mit.edu } EXAMPLE.COM = { kdc = kerberos.example.com kdc = kerberos\-1.example.com admin_server = kerberos.example.com } [domain_realm] mit.edu = ATHENA.MIT.EDU [capaths] ATHENA.MIT.EDU = { EXAMPLE.COM = . } EXAMPLE.COM = { ATHENA.MIT.EDU = . } .ft P .fi .UNINDENT .UNINDENT .SH FILES .sp \fB/etc/krb5.conf\fP .SH SEE ALSO .sp syslog(3) .SH AUTHOR MIT .SH COPYRIGHT 1985-2017, MIT .\" Generated by docutils manpage writer. . krb5-1.16/src/man/krb5-config.man0000644000704600001450000000645013211554426016350 0ustar ghudsonlibuuid.\" Man page generated from reStructuredText. . .TH "KRB5-CONFIG" "1" " " "1.16" "MIT Kerberos" .SH NAME krb5-config \- tool for linking against MIT Kerberos libraries . .nr rst2man-indent-level 0 . .de1 rstReportMargin \\$1 \\n[an-margin] level \\n[rst2man-indent-level] level margin: \\n[rst2man-indent\\n[rst2man-indent-level]] - \\n[rst2man-indent0] \\n[rst2man-indent1] \\n[rst2man-indent2] .. .de1 INDENT .\" .rstReportMargin pre: . RS \\$1 . nr rst2man-indent\\n[rst2man-indent-level] \\n[an-margin] . nr rst2man-indent-level +1 .\" .rstReportMargin post: .. .de UNINDENT . RE .\" indent \\n[an-margin] .\" old: \\n[rst2man-indent\\n[rst2man-indent-level]] .nr rst2man-indent-level -1 .\" new: \\n[rst2man-indent\\n[rst2man-indent-level]] .in \\n[rst2man-indent\\n[rst2man-indent-level]]u .. .SH SYNOPSIS .sp \fBkrb5\-config\fP [\fB\-\fP\fB\-help\fP | \fB\-\fP\fB\-all\fP | \fB\-\fP\fB\-version\fP | \fB\-\fP\fB\-vendor\fP | \fB\-\fP\fB\-prefix\fP | \fB\-\fP\fB\-exec\-prefix\fP | \fB\-\fP\fB\-defccname\fP | \fB\-\fP\fB\-defktname\fP | \fB\-\fP\fB\-defcktname\fP | \fB\-\fP\fB\-cflags\fP | \fB\-\fP\fB\-libs\fP [\fIlibraries\fP]] .SH DESCRIPTION .sp krb5\-config tells the application programmer what flags to use to compile and link programs against the installed Kerberos libraries. .SH OPTIONS .INDENT 0.0 .TP .B \fB\-\fP\fB\-help\fP prints a usage message. This is the default behavior when no options are specified. .TP .B \fB\-\fP\fB\-all\fP prints the version, vendor, prefix, and exec\-prefix. .TP .B \fB\-\fP\fB\-version\fP prints the version number of the Kerberos installation. .TP .B \fB\-\fP\fB\-vendor\fP prints the name of the vendor of the Kerberos installation. .TP .B \fB\-\fP\fB\-prefix\fP prints the prefix for which the Kerberos installation was built. .TP .B \fB\-\fP\fB\-exec\-prefix\fP prints the prefix for executables for which the Kerberos installation was built. .TP .B \fB\-\fP\fB\-defccname\fP prints the built\-in default credentials cache location. .TP .B \fB\-\fP\fB\-defktname\fP prints the built\-in default keytab location. .TP .B \fB\-\fP\fB\-defcktname\fP prints the built\-in default client (initiator) keytab location. .TP .B \fB\-\fP\fB\-cflags\fP prints the compilation flags used to build the Kerberos installation. .TP .B \fB\-\fP\fB\-libs\fP [\fIlibrary\fP] prints the compiler options needed to link against \fIlibrary\fP\&. Allowed values for \fIlibrary\fP are: .TS center; |l|l|. _ T{ krb5 T} T{ Kerberos 5 applications (default) T} _ T{ gssapi T} T{ GSSAPI applications with Kerberos 5 bindings T} _ T{ kadm\-client T} T{ Kadmin client T} _ T{ kadm\-server T} T{ Kadmin server T} _ T{ kdb T} T{ Applications that access the Kerberos database T} _ .TE .UNINDENT .SH EXAMPLES .sp krb5\-config is particularly useful for compiling against a Kerberos installation that was installed in a non\-standard location. For example, a Kerberos installation that is installed in \fB/opt/krb5/\fP but uses libraries in \fB/usr/local/lib/\fP for text localization would produce the following output: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C shell% krb5\-config \-\-libs krb5 \-L/opt/krb5/lib \-Wl,\-rpath \-Wl,/opt/krb5/lib \-L/usr/local/lib \-lkrb5 \-lk5crypto \-lcom_err .ft P .fi .UNINDENT .UNINDENT .SH SEE ALSO .sp kerberos(1), cc(1) .SH AUTHOR MIT .SH COPYRIGHT 1985-2017, MIT .\" Generated by docutils manpage writer. . krb5-1.16/src/man/krb5kdc.man0000644000704600001450000001156713211554426015574 0ustar ghudsonlibuuid.\" Man page generated from reStructuredText. . .TH "KRB5KDC" "8" " " "1.16" "MIT Kerberos" .SH NAME krb5kdc \- Kerberos V5 KDC . .nr rst2man-indent-level 0 . .de1 rstReportMargin \\$1 \\n[an-margin] level \\n[rst2man-indent-level] level margin: \\n[rst2man-indent\\n[rst2man-indent-level]] - \\n[rst2man-indent0] \\n[rst2man-indent1] \\n[rst2man-indent2] .. .de1 INDENT .\" .rstReportMargin pre: . RS \\$1 . nr rst2man-indent\\n[rst2man-indent-level] \\n[an-margin] . nr rst2man-indent-level +1 .\" .rstReportMargin post: .. .de UNINDENT . RE .\" indent \\n[an-margin] .\" old: \\n[rst2man-indent\\n[rst2man-indent-level]] .nr rst2man-indent-level -1 .\" new: \\n[rst2man-indent\\n[rst2man-indent-level]] .in \\n[rst2man-indent\\n[rst2man-indent-level]]u .. .SH SYNOPSIS .sp \fBkrb5kdc\fP [\fB\-x\fP \fIdb_args\fP] [\fB\-d\fP \fIdbname\fP] [\fB\-k\fP \fIkeytype\fP] [\fB\-M\fP \fImkeyname\fP] [\fB\-p\fP \fIportnum\fP] [\fB\-m\fP] [\fB\-r\fP \fIrealm\fP] [\fB\-n\fP] [\fB\-w\fP \fInumworkers\fP] [\fB\-P\fP \fIpid_file\fP] [\fB\-T\fP \fItime_offset\fP] .SH DESCRIPTION .sp krb5kdc is the Kerberos version 5 Authentication Service and Key Distribution Center (AS/KDC). .SH OPTIONS .sp The \fB\-r\fP \fIrealm\fP option specifies the realm for which the server should provide service. .sp The \fB\-d\fP \fIdbname\fP option specifies the name under which the principal database can be found. This option does not apply to the LDAP database. .sp The \fB\-k\fP \fIkeytype\fP option specifies the key type of the master key to be entered manually as a password when \fB\-m\fP is given; the default is \fBdes\-cbc\-crc\fP\&. .sp The \fB\-M\fP \fImkeyname\fP option specifies the principal name for the master key in the database (usually \fBK/M\fP in the KDC\(aqs realm). .sp The \fB\-m\fP option specifies that the master database password should be fetched from the keyboard rather than from a stash file. .sp The \fB\-n\fP option specifies that the KDC does not put itself in the background and does not disassociate itself from the terminal. In normal operation, you should always allow the KDC to place itself in the background. .sp The \fB\-P\fP \fIpid_file\fP option tells the KDC to write its PID into \fIpid_file\fP after it starts up. This can be used to identify whether the KDC is still running and to allow init scripts to stop the correct process. .sp The \fB\-p\fP \fIportnum\fP option specifies the default UDP port numbers which the KDC should listen on for Kerberos version 5 requests, as a comma\-separated list. This value overrides the UDP port numbers specified in the \fIkdcdefaults\fP section of \fIkdc.conf(5)\fP, but may be overridden by realm\-specific values. If no value is given from any source, the default port is 88. .sp The \fB\-w\fP \fInumworkers\fP option tells the KDC to fork \fInumworkers\fP processes to listen to the KDC ports and process requests in parallel. The top level KDC process (whose pid is recorded in the pid file if the \fB\-P\fP option is also given) acts as a supervisor. The supervisor will relay SIGHUP signals to the worker subprocesses, and will terminate the worker subprocess if the it is itself terminated or if any other worker process exits. .sp \fBNOTE:\fP .INDENT 0.0 .INDENT 3.5 On operating systems which do not have \fIpktinfo\fP support, using worker processes will prevent the KDC from listening for UDP packets on network interfaces created after the KDC starts. .UNINDENT .UNINDENT .sp The \fB\-x\fP \fIdb_args\fP option specifies database\-specific arguments. See \fIDatabase Options\fP in \fIkadmin(1)\fP for supported arguments. .sp The \fB\-T\fP \fIoffset\fP option specifies a time offset, in seconds, which the KDC will operate under. It is intended only for testing purposes. .SH EXAMPLE .sp The KDC may service requests for multiple realms (maximum 32 realms). The realms are listed on the command line. Per\-realm options that can be specified on the command line pertain for each realm that follows it and are superseded by subsequent definitions of the same option. .sp For example: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C krb5kdc \-p 2001 \-r REALM1 \-p 2002 \-r REALM2 \-r REALM3 .ft P .fi .UNINDENT .UNINDENT .sp specifies that the KDC listen on port 2001 for REALM1 and on port 2002 for REALM2 and REALM3. Additionally, per\-realm parameters may be specified in the \fIkdc.conf(5)\fP file. The location of this file may be specified by the \fBKRB5_KDC_PROFILE\fP environment variable. Per\-realm parameters specified in this file take precedence over options specified on the command line. See the \fIkdc.conf(5)\fP description for further details. .SH ENVIRONMENT .sp krb5kdc uses the following environment variables: .INDENT 0.0 .IP \(bu 2 \fBKRB5_CONFIG\fP .IP \(bu 2 \fBKRB5_KDC_PROFILE\fP .UNINDENT .SH SEE ALSO .sp \fIkdb5_util(8)\fP, \fIkdc.conf(5)\fP, \fIkrb5.conf(5)\fP, \fIkdb5_ldap_util(8)\fP .SH AUTHOR MIT .SH COPYRIGHT 1985-2017, MIT .\" Generated by docutils manpage writer. . krb5-1.16/src/man/deps0000644000704600001450000000003013211554426014407 0ustar ghudsonlibuuid# No dependencies here. krb5-1.16/src/man/dot.k5identity.50000644000704600001450000000002613211554426016502 0ustar ghudsonlibuuid.so man5/k5identity.5 krb5-1.16/src/man/kpasswd.man0000644000704600001450000000335613211554426015720 0ustar ghudsonlibuuid.\" Man page generated from reStructuredText. . .TH "KPASSWD" "1" " " "1.16" "MIT Kerberos" .SH NAME kpasswd \- change a user's Kerberos password . .nr rst2man-indent-level 0 . .de1 rstReportMargin \\$1 \\n[an-margin] level \\n[rst2man-indent-level] level margin: \\n[rst2man-indent\\n[rst2man-indent-level]] - \\n[rst2man-indent0] \\n[rst2man-indent1] \\n[rst2man-indent2] .. .de1 INDENT .\" .rstReportMargin pre: . RS \\$1 . nr rst2man-indent\\n[rst2man-indent-level] \\n[an-margin] . nr rst2man-indent-level +1 .\" .rstReportMargin post: .. .de UNINDENT . RE .\" indent \\n[an-margin] .\" old: \\n[rst2man-indent\\n[rst2man-indent-level]] .nr rst2man-indent-level -1 .\" new: \\n[rst2man-indent\\n[rst2man-indent-level]] .in \\n[rst2man-indent\\n[rst2man-indent-level]]u .. .SH SYNOPSIS .sp \fBkpasswd\fP [\fIprincipal\fP] .SH DESCRIPTION .sp The kpasswd command is used to change a Kerberos principal\(aqs password. kpasswd first prompts for the current Kerberos password, then prompts the user twice for the new password, and the password is changed. .sp If the principal is governed by a policy that specifies the length and/or number of character classes required in the new password, the new password must conform to the policy. (The five character classes are lower case, upper case, numbers, punctuation, and all other characters.) .SH OPTIONS .INDENT 0.0 .TP .B \fIprincipal\fP Change the password for the Kerberos principal principal. Otherwise, kpasswd uses the principal name from an existing ccache if there is one; if not, the principal is derived from the identity of the user invoking the kpasswd command. .UNINDENT .SH SEE ALSO .sp \fIkadmin(1)\fP, \fIkadmind(8)\fP .SH AUTHOR MIT .SH COPYRIGHT 1985-2017, MIT .\" Generated by docutils manpage writer. . krb5-1.16/src/man/kvno.man0000644000704600001450000000554613211554426015224 0ustar ghudsonlibuuid.\" Man page generated from reStructuredText. . .TH "KVNO" "1" " " "1.16" "MIT Kerberos" .SH NAME kvno \- print key version numbers of Kerberos principals . .nr rst2man-indent-level 0 . .de1 rstReportMargin \\$1 \\n[an-margin] level \\n[rst2man-indent-level] level margin: \\n[rst2man-indent\\n[rst2man-indent-level]] - \\n[rst2man-indent0] \\n[rst2man-indent1] \\n[rst2man-indent2] .. .de1 INDENT .\" .rstReportMargin pre: . RS \\$1 . nr rst2man-indent\\n[rst2man-indent-level] \\n[an-margin] . nr rst2man-indent-level +1 .\" .rstReportMargin post: .. .de UNINDENT . RE .\" indent \\n[an-margin] .\" old: \\n[rst2man-indent\\n[rst2man-indent-level]] .nr rst2man-indent-level -1 .\" new: \\n[rst2man-indent\\n[rst2man-indent-level]] .in \\n[rst2man-indent\\n[rst2man-indent-level]]u .. .SH SYNOPSIS .sp \fBkvno\fP [\fB\-c\fP \fIccache\fP] [\fB\-e\fP \fIetype\fP] [\fB\-q\fP] [\fB\-h\fP] [\fB\-P\fP] [\fB\-S\fP \fIsname\fP] [\fB\-U\fP \fIfor_user\fP] \fIservice1 service2\fP ... .SH DESCRIPTION .sp kvno acquires a service ticket for the specified Kerberos principals and prints out the key version numbers of each. .SH OPTIONS .INDENT 0.0 .TP .B \fB\-c\fP \fIccache\fP Specifies the name of a credentials cache to use (if not the default) .TP .B \fB\-e\fP \fIetype\fP Specifies the enctype which will be requested for the session key of all the services named on the command line. This is useful in certain backward compatibility situations. .TP .B \fB\-q\fP Suppress printing output when successful. If a service ticket cannot be obtained, an error message will still be printed and kvno will exit with nonzero status. .TP .B \fB\-h\fP Prints a usage statement and exits. .TP .B \fB\-P\fP Specifies that the \fIservice1 service2\fP ... arguments are to be treated as services for which credentials should be acquired using constrained delegation. This option is only valid when used in conjunction with protocol transition. .TP .B \fB\-S\fP \fIsname\fP Specifies that the \fIservice1 service2\fP ... arguments are interpreted as hostnames, and the service principals are to be constructed from those hostnames and the service name \fIsname\fP\&. The service hostnames will be canonicalized according to the usual rules for constructing service principals. .TP .B \fB\-U\fP \fIfor_user\fP Specifies that protocol transition (S4U2Self) is to be used to acquire a ticket on behalf of \fIfor_user\fP\&. If constrained delegation is not requested, the service name must match the credentials cache client principal. .UNINDENT .SH ENVIRONMENT .sp kvno uses the following environment variable: .INDENT 0.0 .TP .B \fBKRB5CCNAME\fP Location of the credentials (ticket) cache. .UNINDENT .SH FILES .INDENT 0.0 .TP .B \fB@CCNAME@\fP Default location of the credentials cache .UNINDENT .SH SEE ALSO .sp \fIkinit(1)\fP, \fIkdestroy(1)\fP .SH AUTHOR MIT .SH COPYRIGHT 1985-2017, MIT .\" Generated by docutils manpage writer. . krb5-1.16/src/man/kadm5.acl.man0000644000704600001450000001652613211554426016006 0ustar ghudsonlibuuid.\" Man page generated from reStructuredText. . .TH "KADM5.ACL" "5" " " "1.16" "MIT Kerberos" .SH NAME kadm5.acl \- Kerberos ACL file . .nr rst2man-indent-level 0 . .de1 rstReportMargin \\$1 \\n[an-margin] level \\n[rst2man-indent-level] level margin: \\n[rst2man-indent\\n[rst2man-indent-level]] - \\n[rst2man-indent0] \\n[rst2man-indent1] \\n[rst2man-indent2] .. .de1 INDENT .\" .rstReportMargin pre: . RS \\$1 . nr rst2man-indent\\n[rst2man-indent-level] \\n[an-margin] . nr rst2man-indent-level +1 .\" .rstReportMargin post: .. .de UNINDENT . RE .\" indent \\n[an-margin] .\" old: \\n[rst2man-indent\\n[rst2man-indent-level]] .nr rst2man-indent-level -1 .\" new: \\n[rst2man-indent\\n[rst2man-indent-level]] .in \\n[rst2man-indent\\n[rst2man-indent-level]]u .. .SH DESCRIPTION .sp The Kerberos \fIkadmind(8)\fP daemon uses an Access Control List (ACL) file to manage access rights to the Kerberos database. For operations that affect principals, the ACL file also controls which principals can operate on which other principals. .sp The default location of the Kerberos ACL file is \fB@LOCALSTATEDIR@\fP\fB/krb5kdc\fP\fB/kadm5.acl\fP unless this is overridden by the \fIacl_file\fP variable in \fIkdc.conf(5)\fP\&. .SH SYNTAX .sp Empty lines and lines starting with the sharp sign (\fB#\fP) are ignored. Lines containing ACL entries have the format: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C principal permissions [target_principal [restrictions] ] .ft P .fi .UNINDENT .UNINDENT .sp \fBNOTE:\fP .INDENT 0.0 .INDENT 3.5 Line order in the ACL file is important. The first matching entry will control access for an actor principal on a target principal. .UNINDENT .UNINDENT .INDENT 0.0 .TP .B \fIprincipal\fP (Partially or fully qualified Kerberos principal name.) Specifies the principal whose permissions are to be set. .sp Each component of the name may be wildcarded using the \fB*\fP character. .TP .B \fIpermissions\fP Specifies what operations may or may not be performed by a \fIprincipal\fP matching a particular entry. This is a string of one or more of the following list of characters or their upper\-case counterparts. If the character is \fIupper\-case\fP, then the operation is disallowed. If the character is \fIlower\-case\fP, then the operation is permitted. .TS center; |l|l|. _ T{ a T} T{ [Dis]allows the addition of principals or policies T} _ T{ c T} T{ [Dis]allows the changing of passwords for principals T} _ T{ d T} T{ [Dis]allows the deletion of principals or policies T} _ T{ e T} T{ [Dis]allows the extraction of principal keys T} _ T{ i T} T{ [Dis]allows inquiries about principals or policies T} _ T{ l T} T{ [Dis]allows the listing of all principals or policies T} _ T{ m T} T{ [Dis]allows the modification of principals or policies T} _ T{ p T} T{ [Dis]allows the propagation of the principal database (used in \fIincr_db_prop\fP) T} _ T{ s T} T{ [Dis]allows the explicit setting of the key for a principal T} _ T{ x T} T{ Short for admcilsp. All privileges (except \fBe\fP) T} _ T{ * T} T{ Same as x. T} _ .TE .UNINDENT .sp \fBNOTE:\fP .INDENT 0.0 .INDENT 3.5 The \fBextract\fP privilege is not included in the wildcard privilege; it must be explicitly assigned. This privilege allows the user to extract keys from the database, and must be handled with great care to avoid disclosure of important keys like those of the kadmin/* or krbtgt/* principals. The \fBlockdown_keys\fP principal attribute can be used to prevent key extraction from specific principals regardless of the granted privilege. .UNINDENT .UNINDENT .INDENT 0.0 .TP .B \fItarget_principal\fP (Optional. Partially or fully qualified Kerberos principal name.) Specifies the principal on which \fIpermissions\fP may be applied. Each component of the name may be wildcarded using the \fB*\fP character. .sp \fItarget_principal\fP can also include back\-references to \fIprincipal\fP, in which \fB*number\fP matches the corresponding wildcard in \fIprincipal\fP\&. .TP .B \fIrestrictions\fP (Optional) A string of flags. Allowed restrictions are: .INDENT 7.0 .INDENT 3.5 .INDENT 0.0 .TP .B {+|\-}\fIflagname\fP flag is forced to the indicated value. The permissible flags are the same as those for the \fBdefault_principal_flags\fP variable in \fIkdc.conf(5)\fP\&. .TP .B \fI\-clearpolicy\fP policy is forced to be empty. .TP .B \fI\-policy pol\fP policy is forced to be \fIpol\fP\&. .TP .B \-{\fIexpire, pwexpire, maxlife, maxrenewlife\fP} \fItime\fP (\fIgetdate\fP string) associated value will be forced to MIN(\fItime\fP, requested value). .UNINDENT .UNINDENT .UNINDENT .sp The above flags act as restrictions on any add or modify operation which is allowed due to that ACL line. .UNINDENT .sp \fBWARNING:\fP .INDENT 0.0 .INDENT 3.5 If the kadmind ACL file is modified, the kadmind daemon needs to be restarted for changes to take effect. .UNINDENT .UNINDENT .SH EXAMPLE .sp Here is an example of a kadm5.acl file: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C */admin@ATHENA.MIT.EDU * # line 1 joeadmin@ATHENA.MIT.EDU ADMCIL # line 2 joeadmin/*@ATHENA.MIT.EDU i */root@ATHENA.MIT.EDU # line 3 */root@ATHENA.MIT.EDU ci *1@ATHENA.MIT.EDU # line 4 */root@ATHENA.MIT.EDU l * # line 5 sms@ATHENA.MIT.EDU x * \-maxlife 9h \-postdateable # line 6 .ft P .fi .UNINDENT .UNINDENT .sp (line 1) Any principal in the \fBATHENA.MIT.EDU\fP realm with an \fBadmin\fP instance has all administrative privileges except extracting keys. .sp (lines 1\-3) The user \fBjoeadmin\fP has all permissions except extracting keys with his \fBadmin\fP instance, \fBjoeadmin/admin@ATHENA.MIT.EDU\fP (matches line 1). He has no permissions at all with his null instance, \fBjoeadmin@ATHENA.MIT.EDU\fP (matches line 2). His \fBroot\fP and other non\-\fBadmin\fP, non\-null instances (e.g., \fBextra\fP or \fBdbadmin\fP) have inquire permissions with any principal that has the instance \fBroot\fP (matches line 3). .sp (line 4) Any \fBroot\fP principal in \fBATHENA.MIT.EDU\fP can inquire or change the password of their null instance, but not any other null instance. (Here, \fB*1\fP denotes a back\-reference to the component matching the first wildcard in the actor principal.) .sp (line 5) Any \fBroot\fP principal in \fBATHENA.MIT.EDU\fP can generate the list of principals in the database, and the list of policies in the database. This line is separate from line 4, because list permission can only be granted globally, not to specific target principals. .sp (line 6) Finally, the Service Management System principal \fBsms@ATHENA.MIT.EDU\fP has all permissions except extracting keys, but any principal that it creates or modifies will not be able to get postdateable tickets or tickets with a life of longer than 9 hours. .SH MODULE BEHAVIOR .sp The ACL file can coexist with other authorization modules in release 1.16 and later, as configured in the \fIkadm5_auth\fP section of \fIkrb5.conf(5)\fP\&. The ACL file will positively authorize operations according to the rules above, but will never authoritatively deny an operation, so other modules can authorize operations in addition to those authorized by the ACL file. .sp To operate without an ACL file, set the \fIacl_file\fP variable in \fIkdc.conf(5)\fP to the empty string with \fBacl_file = ""\fP\&. .SH SEE ALSO .sp \fIkdc.conf(5)\fP, \fIkadmind(8)\fP .SH AUTHOR MIT .SH COPYRIGHT 1985-2017, MIT .\" Generated by docutils manpage writer. . krb5-1.16/src/man/dot.k5login.50000644000704600001450000000002313211554426015756 0ustar ghudsonlibuuid.so man5/k5login.5 krb5-1.16/src/man/ksu.man0000644000704600001450000004063413211554426015046 0ustar ghudsonlibuuid.\" Man page generated from reStructuredText. . .TH "KSU" "1" " " "1.16" "MIT Kerberos" .SH NAME ksu \- Kerberized super-user . .nr rst2man-indent-level 0 . .de1 rstReportMargin \\$1 \\n[an-margin] level \\n[rst2man-indent-level] level margin: \\n[rst2man-indent\\n[rst2man-indent-level]] - \\n[rst2man-indent0] \\n[rst2man-indent1] \\n[rst2man-indent2] .. .de1 INDENT .\" .rstReportMargin pre: . RS \\$1 . nr rst2man-indent\\n[rst2man-indent-level] \\n[an-margin] . nr rst2man-indent-level +1 .\" .rstReportMargin post: .. .de UNINDENT . RE .\" indent \\n[an-margin] .\" old: \\n[rst2man-indent\\n[rst2man-indent-level]] .nr rst2man-indent-level -1 .\" new: \\n[rst2man-indent\\n[rst2man-indent-level]] .in \\n[rst2man-indent\\n[rst2man-indent-level]]u .. .SH SYNOPSIS .sp \fBksu\fP [ \fItarget_user\fP ] [ \fB\-n\fP \fItarget_principal_name\fP ] [ \fB\-c\fP \fIsource_cache_name\fP ] [ \fB\-k\fP ] [ \fB\-r\fP time ] [ \fB\-pf\fP ] [ \fB\-l\fP \fIlifetime\fP ] [ \fB\-z | Z\fP ] [ \fB\-q\fP ] [ \fB\-e\fP \fIcommand\fP [ args ... ] ] [ \fB\-a\fP [ args ... ] ] .SH REQUIREMENTS .sp Must have Kerberos version 5 installed to compile ksu. Must have a Kerberos version 5 server running to use ksu. .SH DESCRIPTION .sp ksu is a Kerberized version of the su program that has two missions: one is to securely change the real and effective user ID to that of the target user, and the other is to create a new security context. .sp \fBNOTE:\fP .INDENT 0.0 .INDENT 3.5 For the sake of clarity, all references to and attributes of the user invoking the program will start with "source" (e.g., "source user", "source cache", etc.). .sp Likewise, all references to and attributes of the target account will start with "target". .UNINDENT .UNINDENT .SH AUTHENTICATION .sp To fulfill the first mission, ksu operates in two phases: authentication and authorization. Resolving the target principal name is the first step in authentication. The user can either specify his principal name with the \fB\-n\fP option (e.g., \fB\-n jqpublic@USC.EDU\fP) or a default principal name will be assigned using a heuristic described in the OPTIONS section (see \fB\-n\fP option). The target user name must be the first argument to ksu; if not specified root is the default. If \fB\&.\fP is specified then the target user will be the source user (e.g., \fBksu .\fP). If the source user is root or the target user is the source user, no authentication or authorization takes place. Otherwise, ksu looks for an appropriate Kerberos ticket in the source cache. .sp The ticket can either be for the end\-server or a ticket granting ticket (TGT) for the target principal\(aqs realm. If the ticket for the end\-server is already in the cache, it\(aqs decrypted and verified. If it\(aqs not in the cache but the TGT is, the TGT is used to obtain the ticket for the end\-server. The end\-server ticket is then verified. If neither ticket is in the cache, but ksu is compiled with the \fBGET_TGT_VIA_PASSWD\fP define, the user will be prompted for a Kerberos password which will then be used to get a TGT. If the user is logged in remotely and does not have a secure channel, the password may be exposed. If neither ticket is in the cache and \fBGET_TGT_VIA_PASSWD\fP is not defined, authentication fails. .SH AUTHORIZATION .sp This section describes authorization of the source user when ksu is invoked without the \fB\-e\fP option. For a description of the \fB\-e\fP option, see the OPTIONS section. .sp Upon successful authentication, ksu checks whether the target principal is authorized to access the target account. In the target user\(aqs home directory, ksu attempts to access two authorization files: \fI\&.k5login(5)\fP and .k5users. In the .k5login file each line contains the name of a principal that is authorized to access the account. .sp For example: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C jqpublic@USC.EDU jqpublic/secure@USC.EDU jqpublic/admin@USC.EDU .ft P .fi .UNINDENT .UNINDENT .sp The format of .k5users is the same, except the principal name may be followed by a list of commands that the principal is authorized to execute (see the \fB\-e\fP option in the OPTIONS section for details). .sp Thus if the target principal name is found in the .k5login file the source user is authorized to access the target account. Otherwise ksu looks in the .k5users file. If the target principal name is found without any trailing commands or followed only by \fB*\fP then the source user is authorized. If either .k5login or .k5users exist but an appropriate entry for the target principal does not exist then access is denied. If neither file exists then the principal will be granted access to the account according to the aname\->lname mapping rules. Otherwise, authorization fails. .SH EXECUTION OF THE TARGET SHELL .sp Upon successful authentication and authorization, ksu proceeds in a similar fashion to su. The environment is unmodified with the exception of USER, HOME and SHELL variables. If the target user is not root, USER gets set to the target user name. Otherwise USER remains unchanged. Both HOME and SHELL are set to the target login\(aqs default values. In addition, the environment variable \fBKRB5CCNAME\fP gets set to the name of the target cache. The real and effective user ID are changed to that of the target user. The target user\(aqs shell is then invoked (the shell name is specified in the password file). Upon termination of the shell, ksu deletes the target cache (unless ksu is invoked with the \fB\-k\fP option). This is implemented by first doing a fork and then an exec, instead of just exec, as done by su. .SH CREATING A NEW SECURITY CONTEXT .sp ksu can be used to create a new security context for the target program (either the target shell, or command specified via the \fB\-e\fP option). The target program inherits a set of credentials from the source user. By default, this set includes all of the credentials in the source cache plus any additional credentials obtained during authentication. The source user is able to limit the credentials in this set by using \fB\-z\fP or \fB\-Z\fP option. \fB\-z\fP restricts the copy of tickets from the source cache to the target cache to only the tickets where client == the target principal name. The \fB\-Z\fP option provides the target user with a fresh target cache (no creds in the cache). Note that for security reasons, when the source user is root and target user is non\-root, \fB\-z\fP option is the default mode of operation. .sp While no authentication takes place if the source user is root or is the same as the target user, additional tickets can still be obtained for the target cache. If \fB\-n\fP is specified and no credentials can be copied to the target cache, the source user is prompted for a Kerberos password (unless \fB\-Z\fP specified or \fBGET_TGT_VIA_PASSWD\fP is undefined). If successful, a TGT is obtained from the Kerberos server and stored in the target cache. Otherwise, if a password is not provided (user hit return) ksu continues in a normal mode of operation (the target cache will not contain the desired TGT). If the wrong password is typed in, ksu fails. .sp \fBNOTE:\fP .INDENT 0.0 .INDENT 3.5 During authentication, only the tickets that could be obtained without providing a password are cached in in the source cache. .UNINDENT .UNINDENT .SH OPTIONS .INDENT 0.0 .TP .B \fB\-n\fP \fItarget_principal_name\fP Specify a Kerberos target principal name. Used in authentication and authorization phases of ksu. .sp If ksu is invoked without \fB\-n\fP, a default principal name is assigned via the following heuristic: .INDENT 7.0 .IP \(bu 2 Case 1: source user is non\-root. .sp If the target user is the source user the default principal name is set to the default principal of the source cache. If the cache does not exist then the default principal name is set to \fBtarget_user@local_realm\fP\&. If the source and target users are different and neither \fB~target_user/.k5users\fP nor \fB~target_user/.k5login\fP exist then the default principal name is \fBtarget_user_login_name@local_realm\fP\&. Otherwise, starting with the first principal listed below, ksu checks if the principal is authorized to access the target account and whether there is a legitimate ticket for that principal in the source cache. If both conditions are met that principal becomes the default target principal, otherwise go to the next principal. .INDENT 2.0 .IP a. 3 default principal of the source cache .IP b. 3 target_user@local_realm .IP c. 3 source_user@local_realm .UNINDENT .sp If a\-c fails try any principal for which there is a ticket in the source cache and that is authorized to access the target account. If that fails select the first principal that is authorized to access the target account from the above list. If none are authorized and ksu is configured with \fBPRINC_LOOK_AHEAD\fP turned on, select the default principal as follows: .sp For each candidate in the above list, select an authorized principal that has the same realm name and first part of the principal name equal to the prefix of the candidate. For example if candidate a) is \fBjqpublic@ISI.EDU\fP and \fBjqpublic/secure@ISI.EDU\fP is authorized to access the target account then the default principal is set to \fBjqpublic/secure@ISI.EDU\fP\&. .IP \(bu 2 Case 2: source user is root. .sp If the target user is non\-root then the default principal name is \fBtarget_user@local_realm\fP\&. Else, if the source cache exists the default principal name is set to the default principal of the source cache. If the source cache does not exist, default principal name is set to \fBroot\e@local_realm\fP\&. .UNINDENT .UNINDENT .sp \fB\-c\fP \fIsource_cache_name\fP .INDENT 0.0 .INDENT 3.5 Specify source cache name (e.g., \fB\-c FILE:/tmp/my_cache\fP). If \fB\-c\fP option is not used then the name is obtained from \fBKRB5CCNAME\fP environment variable. If \fBKRB5CCNAME\fP is not defined the source cache name is set to \fBkrb5cc_\fP\&. The target cache name is automatically set to \fBkrb5cc_.(gen_sym())\fP, where gen_sym generates a new number such that the resulting cache does not already exist. For example: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C krb5cc_1984.2 .ft P .fi .UNINDENT .UNINDENT .UNINDENT .UNINDENT .INDENT 0.0 .TP .B \fB\-k\fP Do not delete the target cache upon termination of the target shell or a command (\fB\-e\fP command). Without \fB\-k\fP, ksu deletes the target cache. .TP .B \fB\-z\fP Restrict the copy of tickets from the source cache to the target cache to only the tickets where client == the target principal name. Use the \fB\-n\fP option if you want the tickets for other then the default principal. Note that the \fB\-z\fP option is mutually exclusive with the \fB\-Z\fP option. .TP .B \fB\-Z\fP Don\(aqt copy any tickets from the source cache to the target cache. Just create a fresh target cache, where the default principal name of the cache is initialized to the target principal name. Note that the \fB\-Z\fP option is mutually exclusive with the \fB\-z\fP option. .TP .B \fB\-q\fP Suppress the printing of status messages. .UNINDENT .sp Ticket granting ticket options: .INDENT 0.0 .TP .B \fB\-l\fP \fIlifetime\fP \fB\-r\fP \fItime\fP \fB\-pf\fP The ticket granting ticket options only apply to the case where there are no appropriate tickets in the cache to authenticate the source user. In this case if ksu is configured to prompt users for a Kerberos password (\fBGET_TGT_VIA_PASSWD\fP is defined), the ticket granting ticket options that are specified will be used when getting a ticket granting ticket from the Kerberos server. .TP .B \fB\-l\fP \fIlifetime\fP (\fIduration\fP string.) Specifies the lifetime to be requested for the ticket; if this option is not specified, the default ticket lifetime (12 hours) is used instead. .TP .B \fB\-r\fP \fItime\fP (\fIduration\fP string.) Specifies that the \fBrenewable\fP option should be requested for the ticket, and specifies the desired total lifetime of the ticket. .TP .B \fB\-p\fP specifies that the \fBproxiable\fP option should be requested for the ticket. .TP .B \fB\-f\fP option specifies that the \fBforwardable\fP option should be requested for the ticket. .TP .B \fB\-e\fP \fIcommand\fP [\fIargs\fP ...] ksu proceeds exactly the same as if it was invoked without the \fB\-e\fP option, except instead of executing the target shell, ksu executes the specified command. Example of usage: .INDENT 7.0 .INDENT 3.5 .sp .nf .ft C ksu bob \-e ls \-lag .ft P .fi .UNINDENT .UNINDENT .sp The authorization algorithm for \fB\-e\fP is as follows: .sp If the source user is root or source user == target user, no authorization takes place and the command is executed. If source user id != 0, and \fB~target_user/.k5users\fP file does not exist, authorization fails. Otherwise, \fB~target_user/.k5users\fP file must have an appropriate entry for target principal to get authorized. .sp The .k5users file format: .sp A single principal entry on each line that may be followed by a list of commands that the principal is authorized to execute. A principal name followed by a \fB*\fP means that the user is authorized to execute any command. Thus, in the following example: .INDENT 7.0 .INDENT 3.5 .sp .nf .ft C jqpublic@USC.EDU ls mail /local/kerberos/klist jqpublic/secure@USC.EDU * jqpublic/admin@USC.EDU .ft P .fi .UNINDENT .UNINDENT .sp \fBjqpublic@USC.EDU\fP is only authorized to execute \fBls\fP, \fBmail\fP and \fBklist\fP commands. \fBjqpublic/secure@USC.EDU\fP is authorized to execute any command. \fBjqpublic/admin@USC.EDU\fP is not authorized to execute any command. Note, that \fBjqpublic/admin@USC.EDU\fP is authorized to execute the target shell (regular ksu, without the \fB\-e\fP option) but \fBjqpublic@USC.EDU\fP is not. .sp The commands listed after the principal name must be either a full path names or just the program name. In the second case, \fBCMD_PATH\fP specifying the location of authorized programs must be defined at the compilation time of ksu. Which command gets executed? .sp If the source user is root or the target user is the source user or the user is authorized to execute any command (\fB*\fP entry) then command can be either a full or a relative path leading to the target program. Otherwise, the user must specify either a full path or just the program name. .TP .B \fB\-a\fP \fIargs\fP Specify arguments to be passed to the target shell. Note that all flags and parameters following \-a will be passed to the shell, thus all options intended for ksu must precede \fB\-a\fP\&. .sp The \fB\-a\fP option can be used to simulate the \fB\-e\fP option if used as follows: .INDENT 7.0 .INDENT 3.5 .sp .nf .ft C \-a \-c [command [arguments]]. .ft P .fi .UNINDENT .UNINDENT .sp \fB\-c\fP is interpreted by the c\-shell to execute the command. .UNINDENT .SH INSTALLATION INSTRUCTIONS .sp ksu can be compiled with the following four flags: .INDENT 0.0 .TP .B \fBGET_TGT_VIA_PASSWD\fP In case no appropriate tickets are found in the source cache, the user will be prompted for a Kerberos password. The password is then used to get a ticket granting ticket from the Kerberos server. The danger of configuring ksu with this macro is if the source user is logged in remotely and does not have a secure channel, the password may get exposed. .TP .B \fBPRINC_LOOK_AHEAD\fP During the resolution of the default principal name, \fBPRINC_LOOK_AHEAD\fP enables ksu to find principal names in the .k5users file as described in the OPTIONS section (see \fB\-n\fP option). .TP .B \fBCMD_PATH\fP Specifies a list of directories containing programs that users are authorized to execute (via .k5users file). .TP .B \fBHAVE_GETUSERSHELL\fP If the source user is non\-root, ksu insists that the target user\(aqs shell to be invoked is a "legal shell". \fIgetusershell(3)\fP is called to obtain the names of "legal shells". Note that the target user\(aqs shell is obtained from the passwd file. .UNINDENT .sp Sample configuration: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C KSU_OPTS = \-DGET_TGT_VIA_PASSWD \-DPRINC_LOOK_AHEAD \-DCMD_PATH=\(aq"/bin /usr/ucb /local/bin" .ft P .fi .UNINDENT .UNINDENT .sp ksu should be owned by root and have the set user id bit turned on. .sp ksu attempts to get a ticket for the end server just as Kerberized telnet and rlogin. Thus, there must be an entry for the server in the Kerberos database (e.g., \fBhost/nii.isi.edu@ISI.EDU\fP). The keytab file must be in an appropriate location. .SH SIDE EFFECTS .sp ksu deletes all expired tickets from the source cache. .SH AUTHOR OF KSU .sp GENNADY (ARI) MEDVINSKY .SH AUTHOR MIT .SH COPYRIGHT 1985-2017, MIT .\" Generated by docutils manpage writer. . krb5-1.16/src/man/kdb5_ldap_util.man0000644000704600001450000003170413211554426017124 0ustar ghudsonlibuuid.\" Man page generated from reStructuredText. . .TH "KDB5_LDAP_UTIL" "8" " " "1.16" "MIT Kerberos" .SH NAME kdb5_ldap_util \- Kerberos configuration utility . .nr rst2man-indent-level 0 . .de1 rstReportMargin \\$1 \\n[an-margin] level \\n[rst2man-indent-level] level margin: \\n[rst2man-indent\\n[rst2man-indent-level]] - \\n[rst2man-indent0] \\n[rst2man-indent1] \\n[rst2man-indent2] .. .de1 INDENT .\" .rstReportMargin pre: . RS \\$1 . nr rst2man-indent\\n[rst2man-indent-level] \\n[an-margin] . nr rst2man-indent-level +1 .\" .rstReportMargin post: .. .de UNINDENT . RE .\" indent \\n[an-margin] .\" old: \\n[rst2man-indent\\n[rst2man-indent-level]] .nr rst2man-indent-level -1 .\" new: \\n[rst2man-indent\\n[rst2man-indent-level]] .in \\n[rst2man-indent\\n[rst2man-indent-level]]u .. .SH SYNOPSIS .sp \fBkdb5_ldap_util\fP [\fB\-D\fP \fIuser_dn\fP [\fB\-w\fP \fIpasswd\fP]] [\fB\-H\fP \fIldapuri\fP] \fBcommand\fP [\fIcommand_options\fP] .SH DESCRIPTION .sp kdb5_ldap_util allows an administrator to manage realms, Kerberos services and ticket policies. .SH COMMAND-LINE OPTIONS .INDENT 0.0 .TP .B \fB\-D\fP \fIuser_dn\fP Specifies the Distinguished Name (DN) of the user who has sufficient rights to perform the operation on the LDAP server. .TP .B \fB\-w\fP \fIpasswd\fP Specifies the password of \fIuser_dn\fP\&. This option is not recommended. .TP .B \fB\-H\fP \fIldapuri\fP Specifies the URI of the LDAP server. It is recommended to use \fBldapi://\fP or \fBldaps://\fP to connect to the LDAP server. .UNINDENT .SH COMMANDS .SS create .INDENT 0.0 .INDENT 3.5 \fBcreate\fP [\fB\-subtrees\fP \fIsubtree_dn_list\fP] [\fB\-sscope\fP \fIsearch_scope\fP] [\fB\-containerref\fP \fIcontainer_reference_dn\fP] [\fB\-k\fP \fImkeytype\fP] [\fB\-kv\fP \fImkeyVNO\fP] [\fB\-m|\-P\fP \fIpassword\fP|\fB\-sf\fP \fIstashfilename\fP] [\fB\-s\fP] [\fB\-r\fP \fIrealm\fP] [\fB\-maxtktlife\fP \fImax_ticket_life\fP] [\fB\-maxrenewlife\fP \fImax_renewable_ticket_life\fP] [\fIticket_flags\fP] .UNINDENT .UNINDENT .sp Creates realm in directory. Options: .INDENT 0.0 .TP .B \fB\-subtrees\fP \fIsubtree_dn_list\fP Specifies the list of subtrees containing the principals of a realm. The list contains the DNs of the subtree objects separated by colon (\fB:\fP). .TP .B \fB\-sscope\fP \fIsearch_scope\fP Specifies the scope for searching the principals under the subtree. The possible values are 1 or one (one level), 2 or sub (subtrees). .TP .B \fB\-containerref\fP \fIcontainer_reference_dn\fP Specifies the DN of the container object in which the principals of a realm will be created. If the container reference is not configured for a realm, the principals will be created in the realm container. .TP .B \fB\-k\fP \fImkeytype\fP Specifies the key type of the master key in the database. The default is given by the \fBmaster_key_type\fP variable in \fIkdc.conf(5)\fP\&. .TP .B \fB\-kv\fP \fImkeyVNO\fP Specifies the version number of the master key in the database; the default is 1. Note that 0 is not allowed. .TP .B \fB\-m\fP Specifies that the master database password should be read from the TTY rather than fetched from a file on the disk. .TP .B \fB\-P\fP \fIpassword\fP Specifies the master database password. This option is not recommended. .TP .B \fB\-r\fP \fIrealm\fP Specifies the Kerberos realm of the database. .TP .B \fB\-sf\fP \fIstashfilename\fP Specifies the stash file of the master database password. .TP .B \fB\-s\fP Specifies that the stash file is to be created. .TP .B \fB\-maxtktlife\fP \fImax_ticket_life\fP (\fIgetdate\fP string) Specifies maximum ticket life for principals in this realm. .TP .B \fB\-maxrenewlife\fP \fImax_renewable_ticket_life\fP (\fIgetdate\fP string) Specifies maximum renewable life of tickets for principals in this realm. .TP .B \fIticket_flags\fP Specifies global ticket flags for the realm. Allowable flags are documented in the description of the \fBadd_principal\fP command in \fIkadmin(1)\fP\&. .UNINDENT .sp Example: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C kdb5_ldap_util \-D cn=admin,o=org \-H ldaps://ldap\-server1.mit.edu create \-subtrees o=org \-sscope SUB \-r ATHENA.MIT.EDU Password for "cn=admin,o=org": Initializing database for realm \(aqATHENA.MIT.EDU\(aq You will be prompted for the database Master Password. It is important that you NOT FORGET this password. Enter KDC database master key: Re\-enter KDC database master key to verify: .ft P .fi .UNINDENT .UNINDENT .SS modify .INDENT 0.0 .INDENT 3.5 \fBmodify\fP [\fB\-subtrees\fP \fIsubtree_dn_list\fP] [\fB\-sscope\fP \fIsearch_scope\fP] [\fB\-containerref\fP \fIcontainer_reference_dn\fP] [\fB\-r\fP \fIrealm\fP] [\fB\-maxtktlife\fP \fImax_ticket_life\fP] [\fB\-maxrenewlife\fP \fImax_renewable_ticket_life\fP] [\fIticket_flags\fP] .UNINDENT .UNINDENT .sp Modifies the attributes of a realm. Options: .INDENT 0.0 .TP .B \fB\-subtrees\fP \fIsubtree_dn_list\fP Specifies the list of subtrees containing the principals of a realm. The list contains the DNs of the subtree objects separated by colon (\fB:\fP). This list replaces the existing list. .TP .B \fB\-sscope\fP \fIsearch_scope\fP Specifies the scope for searching the principals under the subtrees. The possible values are 1 or one (one level), 2 or sub (subtrees). .TP .B \fB\-containerref\fP \fIcontainer_reference_dn\fP Specifies the DN of the container object in which the principals of a realm will be created. .TP .B \fB\-r\fP \fIrealm\fP Specifies the Kerberos realm of the database. .TP .B \fB\-maxtktlife\fP \fImax_ticket_life\fP (\fIgetdate\fP string) Specifies maximum ticket life for principals in this realm. .TP .B \fB\-maxrenewlife\fP \fImax_renewable_ticket_life\fP (\fIgetdate\fP string) Specifies maximum renewable life of tickets for principals in this realm. .TP .B \fIticket_flags\fP Specifies global ticket flags for the realm. Allowable flags are documented in the description of the \fBadd_principal\fP command in \fIkadmin(1)\fP\&. .UNINDENT .sp Example: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C shell% kdb5_ldap_util \-D cn=admin,o=org \-H ldaps://ldap\-server1.mit.edu modify +requires_preauth \-r ATHENA.MIT.EDU Password for "cn=admin,o=org": shell% .ft P .fi .UNINDENT .UNINDENT .SS view .INDENT 0.0 .INDENT 3.5 \fBview\fP [\fB\-r\fP \fIrealm\fP] .UNINDENT .UNINDENT .sp Displays the attributes of a realm. Options: .INDENT 0.0 .TP .B \fB\-r\fP \fIrealm\fP Specifies the Kerberos realm of the database. .UNINDENT .sp Example: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C kdb5_ldap_util \-D cn=admin,o=org \-H ldaps://ldap\-server1.mit.edu view \-r ATHENA.MIT.EDU Password for "cn=admin,o=org": Realm Name: ATHENA.MIT.EDU Subtree: ou=users,o=org Subtree: ou=servers,o=org SearchScope: ONE Maximum ticket life: 0 days 01:00:00 Maximum renewable life: 0 days 10:00:00 Ticket flags: DISALLOW_FORWARDABLE REQUIRES_PWCHANGE .ft P .fi .UNINDENT .UNINDENT .SS destroy .INDENT 0.0 .INDENT 3.5 \fBdestroy\fP [\fB\-f\fP] [\fB\-r\fP \fIrealm\fP] .UNINDENT .UNINDENT .sp Destroys an existing realm. Options: .INDENT 0.0 .TP .B \fB\-f\fP If specified, will not prompt the user for confirmation. .TP .B \fB\-r\fP \fIrealm\fP Specifies the Kerberos realm of the database. .UNINDENT .sp Example: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C shell% kdb5_ldap_util \-D cn=admin,o=org \-H ldaps://ldap\-server1.mit.edu destroy \-r ATHENA.MIT.EDU Password for "cn=admin,o=org": Deleting KDC database of \(aqATHENA.MIT.EDU\(aq, are you sure? (type \(aqyes\(aq to confirm)? yes OK, deleting database of \(aqATHENA.MIT.EDU\(aq... shell% .ft P .fi .UNINDENT .UNINDENT .SS list .INDENT 0.0 .INDENT 3.5 \fBlist\fP .UNINDENT .UNINDENT .sp Lists the name of realms. .sp Example: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C shell% kdb5_ldap_util \-D cn=admin,o=org \-H ldaps://ldap\-server1.mit.edu list Password for "cn=admin,o=org": ATHENA.MIT.EDU OPENLDAP.MIT.EDU MEDIA\-LAB.MIT.EDU shell% .ft P .fi .UNINDENT .UNINDENT .SS stashsrvpw .INDENT 0.0 .INDENT 3.5 \fBstashsrvpw\fP [\fB\-f\fP \fIfilename\fP] \fIname\fP .UNINDENT .UNINDENT .sp Allows an administrator to store the password for service object in a file so that KDC and Administration server can use it to authenticate to the LDAP server. Options: .INDENT 0.0 .TP .B \fB\-f\fP \fIfilename\fP Specifies the complete path of the service password file. By default, \fB/usr/local/var/service_passwd\fP is used. .TP .B \fIname\fP Specifies the name of the object whose password is to be stored. If \fIkrb5kdc(8)\fP or \fIkadmind(8)\fP are configured for simple binding, this should be the distinguished name it will use as given by the \fBldap_kdc_dn\fP or \fBldap_kadmind_dn\fP variable in \fIkdc.conf(5)\fP\&. If the KDC or kadmind is configured for SASL binding, this should be the authentication name it will use as given by the \fBldap_kdc_sasl_authcid\fP or \fBldap_kadmind_sasl_authcid\fP variable. .UNINDENT .sp Example: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C kdb5_ldap_util stashsrvpw \-f /home/andrew/conf_keyfile cn=service\-kdc,o=org Password for "cn=service\-kdc,o=org": Re\-enter password for "cn=service\-kdc,o=org": .ft P .fi .UNINDENT .UNINDENT .SS create_policy .INDENT 0.0 .INDENT 3.5 \fBcreate_policy\fP [\fB\-r\fP \fIrealm\fP] [\fB\-maxtktlife\fP \fImax_ticket_life\fP] [\fB\-maxrenewlife\fP \fImax_renewable_ticket_life\fP] [\fIticket_flags\fP] \fIpolicy_name\fP .UNINDENT .UNINDENT .sp Creates a ticket policy in the directory. Options: .INDENT 0.0 .TP .B \fB\-r\fP \fIrealm\fP Specifies the Kerberos realm of the database. .TP .B \fB\-maxtktlife\fP \fImax_ticket_life\fP (\fIgetdate\fP string) Specifies maximum ticket life for principals. .TP .B \fB\-maxrenewlife\fP \fImax_renewable_ticket_life\fP (\fIgetdate\fP string) Specifies maximum renewable life of tickets for principals. .TP .B \fIticket_flags\fP Specifies the ticket flags. If this option is not specified, by default, no restriction will be set by the policy. Allowable flags are documented in the description of the \fBadd_principal\fP command in \fIkadmin(1)\fP\&. .TP .B \fIpolicy_name\fP Specifies the name of the ticket policy. .UNINDENT .sp Example: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C kdb5_ldap_util \-D cn=admin,o=org \-H ldaps://ldap\-server1.mit.edu create_policy \-r ATHENA.MIT.EDU \-maxtktlife "1 day" \-maxrenewlife "1 week" \-allow_postdated +needchange \-allow_forwardable tktpolicy Password for "cn=admin,o=org": .ft P .fi .UNINDENT .UNINDENT .SS modify_policy .INDENT 0.0 .INDENT 3.5 \fBmodify_policy\fP [\fB\-r\fP \fIrealm\fP] [\fB\-maxtktlife\fP \fImax_ticket_life\fP] [\fB\-maxrenewlife\fP \fImax_renewable_ticket_life\fP] [\fIticket_flags\fP] \fIpolicy_name\fP .UNINDENT .UNINDENT .sp Modifies the attributes of a ticket policy. Options are same as for \fBcreate_policy\fP\&. .sp Example: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C kdb5_ldap_util \-D cn=admin,o=org \-H ldaps://ldap\-server1.mit.edu modify_policy \-r ATHENA.MIT.EDU \-maxtktlife "60 minutes" \-maxrenewlife "10 hours" +allow_postdated \-requires_preauth tktpolicy Password for "cn=admin,o=org": .ft P .fi .UNINDENT .UNINDENT .SS view_policy .INDENT 0.0 .INDENT 3.5 \fBview_policy\fP [\fB\-r\fP \fIrealm\fP] \fIpolicy_name\fP .UNINDENT .UNINDENT .sp Displays the attributes of a ticket policy. Options: .INDENT 0.0 .TP .B \fIpolicy_name\fP Specifies the name of the ticket policy. .UNINDENT .sp Example: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C kdb5_ldap_util \-D cn=admin,o=org \-H ldaps://ldap\-server1.mit.edu view_policy \-r ATHENA.MIT.EDU tktpolicy Password for "cn=admin,o=org": Ticket policy: tktpolicy Maximum ticket life: 0 days 01:00:00 Maximum renewable life: 0 days 10:00:00 Ticket flags: DISALLOW_FORWARDABLE REQUIRES_PWCHANGE .ft P .fi .UNINDENT .UNINDENT .SS destroy_policy .INDENT 0.0 .INDENT 3.5 \fBdestroy_policy\fP [\fB\-r\fP \fIrealm\fP] [\fB\-force\fP] \fIpolicy_name\fP .UNINDENT .UNINDENT .sp Destroys an existing ticket policy. Options: .INDENT 0.0 .TP .B \fB\-r\fP \fIrealm\fP Specifies the Kerberos realm of the database. .TP .B \fB\-force\fP Forces the deletion of the policy object. If not specified, the user will be prompted for confirmation before deleting the policy. .TP .B \fIpolicy_name\fP Specifies the name of the ticket policy. .UNINDENT .sp Example: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C kdb5_ldap_util \-D cn=admin,o=org \-H ldaps://ldap\-server1.mit.edu destroy_policy \-r ATHENA.MIT.EDU tktpolicy Password for "cn=admin,o=org": This will delete the policy object \(aqtktpolicy\(aq, are you sure? (type \(aqyes\(aq to confirm)? yes ** policy object \(aqtktpolicy\(aq deleted. .ft P .fi .UNINDENT .UNINDENT .SS list_policy .INDENT 0.0 .INDENT 3.5 \fBlist_policy\fP [\fB\-r\fP \fIrealm\fP] .UNINDENT .UNINDENT .sp Lists the ticket policies in realm if specified or in the default realm. Options: .INDENT 0.0 .TP .B \fB\-r\fP \fIrealm\fP Specifies the Kerberos realm of the database. .UNINDENT .sp Example: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C kdb5_ldap_util \-D cn=admin,o=org \-H ldaps://ldap\-server1.mit.edu list_policy \-r ATHENA.MIT.EDU Password for "cn=admin,o=org": tktpolicy tmppolicy userpolicy .ft P .fi .UNINDENT .UNINDENT .SH SEE ALSO .sp \fIkadmin(1)\fP .SH AUTHOR MIT .SH COPYRIGHT 1985-2017, MIT .\" Generated by docutils manpage writer. . krb5-1.16/src/man/kadmind.man0000644000704600001450000001221013211554426015640 0ustar ghudsonlibuuid.\" Man page generated from reStructuredText. . .TH "KADMIND" "8" " " "1.16" "MIT Kerberos" .SH NAME kadmind \- KADM5 administration server . .nr rst2man-indent-level 0 . .de1 rstReportMargin \\$1 \\n[an-margin] level \\n[rst2man-indent-level] level margin: \\n[rst2man-indent\\n[rst2man-indent-level]] - \\n[rst2man-indent0] \\n[rst2man-indent1] \\n[rst2man-indent2] .. .de1 INDENT .\" .rstReportMargin pre: . RS \\$1 . nr rst2man-indent\\n[rst2man-indent-level] \\n[an-margin] . nr rst2man-indent-level +1 .\" .rstReportMargin post: .. .de UNINDENT . RE .\" indent \\n[an-margin] .\" old: \\n[rst2man-indent\\n[rst2man-indent-level]] .nr rst2man-indent-level -1 .\" new: \\n[rst2man-indent\\n[rst2man-indent-level]] .in \\n[rst2man-indent\\n[rst2man-indent-level]]u .. .SH SYNOPSIS .sp \fBkadmind\fP [\fB\-x\fP \fIdb_args\fP] [\fB\-r\fP \fIrealm\fP] [\fB\-m\fP] [\fB\-nofork\fP] [\fB\-proponly\fP] [\fB\-port\fP \fIport\-number\fP] [\fB\-P\fP \fIpid_file\fP] [\fB\-p\fP \fIkdb5_util_path\fP] [\fB\-K\fP \fIkprop_path\fP] [\fB\-k\fP \fIkprop_port\fP] [\fB\-F\fP \fIdump_file\fP] .SH DESCRIPTION .sp kadmind starts the Kerberos administration server. kadmind typically runs on the master Kerberos server, which stores the KDC database. If the KDC database uses the LDAP module, the administration server and the KDC server need not run on the same machine. kadmind accepts remote requests from programs such as \fIkadmin(1)\fP and \fIkpasswd(1)\fP to administer the information in these database. .sp kadmind requires a number of configuration files to be set up in order for it to work: .INDENT 0.0 .TP .B \fIkdc.conf(5)\fP The KDC configuration file contains configuration information for the KDC and admin servers. kadmind uses settings in this file to locate the Kerberos database, and is also affected by the \fBacl_file\fP, \fBdict_file\fP, \fBkadmind_port\fP, and iprop\-related settings. .TP .B \fIkadm5.acl(5)\fP kadmind\(aqs ACL (access control list) tells it which principals are allowed to perform administration actions. The pathname to the ACL file can be specified with the \fBacl_file\fP \fIkdc.conf(5)\fP variable; by default, it is \fB@LOCALSTATEDIR@\fP\fB/krb5kdc\fP\fB/kadm5.acl\fP\&. .UNINDENT .sp After the server begins running, it puts itself in the background and disassociates itself from its controlling terminal. .sp kadmind can be configured for incremental database propagation. Incremental propagation allows slave KDC servers to receive principal and policy updates incrementally instead of receiving full dumps of the database. This facility can be enabled in the \fIkdc.conf(5)\fP file with the \fBiprop_enable\fP option. Incremental propagation requires the principal \fBkiprop/MASTER\e@REALM\fP (where MASTER is the master KDC\(aqs canonical host name, and REALM the realm name). In release 1.13, this principal is automatically created and registered into the datebase. .SH OPTIONS .INDENT 0.0 .TP .B \fB\-r\fP \fIrealm\fP specifies the realm that kadmind will serve; if it is not specified, the default realm of the host is used. .TP .B \fB\-m\fP causes the master database password to be fetched from the keyboard (before the server puts itself in the background, if not invoked with the \fB\-nofork\fP option) rather than from a file on disk. .TP .B \fB\-nofork\fP causes the server to remain in the foreground and remain associated to the terminal. In normal operation, you should allow the server to place itself in the background. .TP .B \fB\-proponly\fP causes the server to only listen and respond to Kerberos slave incremental propagation polling requests. This option can be used to set up a hierarchical propagation topology where a slave KDC provides incremental updates to other Kerberos slaves. .TP .B \fB\-port\fP \fIport\-number\fP specifies the port on which the administration server listens for connections. The default port is determined by the \fBkadmind_port\fP configuration variable in \fIkdc.conf(5)\fP\&. .TP .B \fB\-P\fP \fIpid_file\fP specifies the file to which the PID of kadmind process should be written after it starts up. This file can be used to identify whether kadmind is still running and to allow init scripts to stop the correct process. .TP .B \fB\-p\fP \fIkdb5_util_path\fP specifies the path to the kdb5_util command to use when dumping the KDB in response to full resync requests when iprop is enabled. .TP .B \fB\-K\fP \fIkprop_path\fP specifies the path to the kprop command to use to send full dumps to slaves in response to full resync requests. .TP .B \fB\-k\fP \fIkprop_port\fP specifies the port by which the kprop process that is spawned by kadmind connects to the slave kpropd, in order to transfer the dump file during an iprop full resync request. .TP .B \fB\-F\fP \fIdump_file\fP specifies the file path to be used for dumping the KDB in response to full resync requests when iprop is enabled. .TP .B \fB\-x\fP \fIdb_args\fP specifies database\-specific arguments. See \fIDatabase Options\fP in \fIkadmin(1)\fP for supported arguments. .UNINDENT .SH SEE ALSO .sp \fIkpasswd(1)\fP, \fIkadmin(1)\fP, \fIkdb5_util(8)\fP, \fIkdb5_ldap_util(8)\fP, \fIkadm5.acl(5)\fP .SH AUTHOR MIT .SH COPYRIGHT 1985-2017, MIT .\" Generated by docutils manpage writer. . krb5-1.16/src/man/kinit.man0000644000704600001450000002044413211554426015357 0ustar ghudsonlibuuid.\" Man page generated from reStructuredText. . .TH "KINIT" "1" " " "1.16" "MIT Kerberos" .SH NAME kinit \- obtain and cache Kerberos ticket-granting ticket . .nr rst2man-indent-level 0 . .de1 rstReportMargin \\$1 \\n[an-margin] level \\n[rst2man-indent-level] level margin: \\n[rst2man-indent\\n[rst2man-indent-level]] - \\n[rst2man-indent0] \\n[rst2man-indent1] \\n[rst2man-indent2] .. .de1 INDENT .\" .rstReportMargin pre: . RS \\$1 . nr rst2man-indent\\n[rst2man-indent-level] \\n[an-margin] . nr rst2man-indent-level +1 .\" .rstReportMargin post: .. .de UNINDENT . RE .\" indent \\n[an-margin] .\" old: \\n[rst2man-indent\\n[rst2man-indent-level]] .nr rst2man-indent-level -1 .\" new: \\n[rst2man-indent\\n[rst2man-indent-level]] .in \\n[rst2man-indent\\n[rst2man-indent-level]]u .. .SH SYNOPSIS .sp \fBkinit\fP [\fB\-V\fP] [\fB\-l\fP \fIlifetime\fP] [\fB\-s\fP \fIstart_time\fP] [\fB\-r\fP \fIrenewable_life\fP] [\fB\-p\fP | \-\fBP\fP] [\fB\-f\fP | \-\fBF\fP] [\fB\-a\fP] [\fB\-A\fP] [\fB\-C\fP] [\fB\-E\fP] [\fB\-v\fP] [\fB\-R\fP] [\fB\-k\fP [\-\fBt\fP \fIkeytab_file\fP]] [\fB\-c\fP \fIcache_name\fP] [\fB\-n\fP] [\fB\-S\fP \fIservice_name\fP] [\fB\-I\fP \fIinput_ccache\fP] [\fB\-T\fP \fIarmor_ccache\fP] [\fB\-X\fP \fIattribute\fP[=\fIvalue\fP]] [\fIprincipal\fP] .SH DESCRIPTION .sp kinit obtains and caches an initial ticket\-granting ticket for \fIprincipal\fP\&. If \fIprincipal\fP is absent, kinit chooses an appropriate principal name based on existing credential cache contents or the local username of the user invoking kinit. Some options modify the choice of principal name. .SH OPTIONS .INDENT 0.0 .TP .B \fB\-V\fP display verbose output. .TP .B \fB\-l\fP \fIlifetime\fP (\fIduration\fP string.) Requests a ticket with the lifetime \fIlifetime\fP\&. .sp For example, \fBkinit \-l 5:30\fP or \fBkinit \-l 5h30m\fP\&. .sp If the \fB\-l\fP option is not specified, the default ticket lifetime (configured by each site) is used. Specifying a ticket lifetime longer than the maximum ticket lifetime (configured by each site) will not override the configured maximum ticket lifetime. .TP .B \fB\-s\fP \fIstart_time\fP (\fIduration\fP string.) Requests a postdated ticket. Postdated tickets are issued with the \fBinvalid\fP flag set, and need to be resubmitted to the KDC for validation before use. .sp \fIstart_time\fP specifies the duration of the delay before the ticket can become valid. .TP .B \fB\-r\fP \fIrenewable_life\fP (\fIduration\fP string.) Requests renewable tickets, with a total lifetime of \fIrenewable_life\fP\&. .TP .B \fB\-f\fP requests forwardable tickets. .TP .B \fB\-F\fP requests non\-forwardable tickets. .TP .B \fB\-p\fP requests proxiable tickets. .TP .B \fB\-P\fP requests non\-proxiable tickets. .TP .B \fB\-a\fP requests tickets restricted to the host\(aqs local address[es]. .TP .B \fB\-A\fP requests tickets not restricted by address. .TP .B \fB\-C\fP requests canonicalization of the principal name, and allows the KDC to reply with a different client principal from the one requested. .TP .B \fB\-E\fP treats the principal name as an enterprise name (implies the \fB\-C\fP option). .TP .B \fB\-v\fP requests that the ticket\-granting ticket in the cache (with the \fBinvalid\fP flag set) be passed to the KDC for validation. If the ticket is within its requested time range, the cache is replaced with the validated ticket. .TP .B \fB\-R\fP requests renewal of the ticket\-granting ticket. Note that an expired ticket cannot be renewed, even if the ticket is still within its renewable life. .sp Note that renewable tickets that have expired as reported by \fIklist(1)\fP may sometimes be renewed using this option, because the KDC applies a grace period to account for client\-KDC clock skew. See \fIkrb5.conf(5)\fP \fBclockskew\fP setting. .TP .B \fB\-k\fP [\fB\-i\fP | \fB\-t\fP \fIkeytab_file\fP] requests a ticket, obtained from a key in the local host\(aqs keytab. The location of the keytab may be specified with the \fB\-t\fP \fIkeytab_file\fP option, or with the \fB\-i\fP option to specify the use of the default client keytab; otherwise the default keytab will be used. By default, a host ticket for the local host is requested, but any principal may be specified. On a KDC, the special keytab location \fBKDB:\fP can be used to indicate that kinit should open the KDC database and look up the key directly. This permits an administrator to obtain tickets as any principal that supports authentication based on the key. .TP .B \fB\-n\fP Requests anonymous processing. Two types of anonymous principals are supported. .sp For fully anonymous Kerberos, configure pkinit on the KDC and configure \fBpkinit_anchors\fP in the client\(aqs \fIkrb5.conf(5)\fP\&. Then use the \fB\-n\fP option with a principal of the form \fB@REALM\fP (an empty principal name followed by the at\-sign and a realm name). If permitted by the KDC, an anonymous ticket will be returned. .sp A second form of anonymous tickets is supported; these realm\-exposed tickets hide the identity of the client but not the client\(aqs realm. For this mode, use \fBkinit \-n\fP with a normal principal name. If supported by the KDC, the principal (but not realm) will be replaced by the anonymous principal. .sp As of release 1.8, the MIT Kerberos KDC only supports fully anonymous operation. .UNINDENT .sp \fB\-I\fP \fIinput_ccache\fP .INDENT 0.0 .INDENT 3.5 Specifies the name of a credentials cache that already contains a ticket. When obtaining that ticket, if information about how that ticket was obtained was also stored to the cache, that information will be used to affect how new credentials are obtained, including preselecting the same methods of authenticating to the KDC. .UNINDENT .UNINDENT .INDENT 0.0 .TP .B \fB\-T\fP \fIarmor_ccache\fP Specifies the name of a credentials cache that already contains a ticket. If supported by the KDC, this cache will be used to armor the request, preventing offline dictionary attacks and allowing the use of additional preauthentication mechanisms. Armoring also makes sure that the response from the KDC is not modified in transit. .TP .B \fB\-c\fP \fIcache_name\fP use \fIcache_name\fP as the Kerberos 5 credentials (ticket) cache location. If this option is not used, the default cache location is used. .sp The default cache location may vary between systems. If the \fBKRB5CCNAME\fP environment variable is set, its value is used to locate the default cache. If a principal name is specified and the type of the default cache supports a collection (such as the DIR type), an existing cache containing credentials for the principal is selected or a new one is created and becomes the new primary cache. Otherwise, any existing contents of the default cache are destroyed by kinit. .TP .B \fB\-S\fP \fIservice_name\fP specify an alternate service name to use when getting initial tickets. .TP .B \fB\-X\fP \fIattribute\fP[=\fIvalue\fP] specify a pre\-authentication \fIattribute\fP and \fIvalue\fP to be interpreted by pre\-authentication modules. The acceptable attribute and value values vary from module to module. This option may be specified multiple times to specify multiple attributes. If no value is specified, it is assumed to be "yes". .sp The following attributes are recognized by the PKINIT pre\-authentication mechanism: .INDENT 7.0 .TP .B \fBX509_user_identity\fP=\fIvalue\fP specify where to find user\(aqs X509 identity information .TP .B \fBX509_anchors\fP=\fIvalue\fP specify where to find trusted X509 anchor information .TP .B \fBflag_RSA_PROTOCOL\fP[\fB=yes\fP] specify use of RSA, rather than the default Diffie\-Hellman protocol .UNINDENT .UNINDENT .SH ENVIRONMENT .sp kinit uses the following environment variables: .INDENT 0.0 .TP .B \fBKRB5CCNAME\fP Location of the default Kerberos 5 credentials cache, in the form \fItype\fP:\fIresidual\fP\&. If no \fItype\fP prefix is present, the \fBFILE\fP type is assumed. The type of the default cache may determine the availability of a cache collection; for instance, a default cache of type \fBDIR\fP causes caches within the directory to be present in the collection. .UNINDENT .SH FILES .INDENT 0.0 .TP .B \fB@CCNAME@\fP default location of Kerberos 5 credentials cache .TP .B \fB@KTNAME@\fP default location for the local host\(aqs keytab. .UNINDENT .SH SEE ALSO .sp \fIklist(1)\fP, \fIkdestroy(1)\fP, kerberos(1) .SH AUTHOR MIT .SH COPYRIGHT 1985-2017, MIT .\" Generated by docutils manpage writer. . krb5-1.16/src/man/kdb5_util.man0000644000704600001450000004016013211554426016120 0ustar ghudsonlibuuid.\" Man page generated from reStructuredText. . .TH "KDB5_UTIL" "8" " " "1.16" "MIT Kerberos" .SH NAME kdb5_util \- Kerberos database maintenance utility . .nr rst2man-indent-level 0 . .de1 rstReportMargin \\$1 \\n[an-margin] level \\n[rst2man-indent-level] level margin: \\n[rst2man-indent\\n[rst2man-indent-level]] - \\n[rst2man-indent0] \\n[rst2man-indent1] \\n[rst2man-indent2] .. .de1 INDENT .\" .rstReportMargin pre: . RS \\$1 . nr rst2man-indent\\n[rst2man-indent-level] \\n[an-margin] . nr rst2man-indent-level +1 .\" .rstReportMargin post: .. .de UNINDENT . RE .\" indent \\n[an-margin] .\" old: \\n[rst2man-indent\\n[rst2man-indent-level]] .nr rst2man-indent-level -1 .\" new: \\n[rst2man-indent\\n[rst2man-indent-level]] .in \\n[rst2man-indent\\n[rst2man-indent-level]]u .. .SH SYNOPSIS .sp \fBkdb5_util\fP [\fB\-r\fP \fIrealm\fP] [\fB\-d\fP \fIdbname\fP] [\fB\-k\fP \fImkeytype\fP] [\fB\-M\fP \fImkeyname\fP] [\fB\-kv\fP \fImkeyVNO\fP] [\fB\-sf\fP \fIstashfilename\fP] [\fB\-m\fP] \fIcommand\fP [\fIcommand_options\fP] .SH DESCRIPTION .sp kdb5_util allows an administrator to perform maintenance procedures on the KDC database. Databases can be created, destroyed, and dumped to or loaded from ASCII files. kdb5_util can create a Kerberos master key stash file or perform live rollover of the master key. .sp When kdb5_util is run, it attempts to acquire the master key and open the database. However, execution continues regardless of whether or not kdb5_util successfully opens the database, because the database may not exist yet or the stash file may be corrupt. .sp Note that some KDC database modules may not support all kdb5_util commands. .SH COMMAND-LINE OPTIONS .INDENT 0.0 .TP .B \fB\-r\fP \fIrealm\fP specifies the Kerberos realm of the database. .TP .B \fB\-d\fP \fIdbname\fP specifies the name under which the principal database is stored; by default the database is that listed in \fIkdc.conf(5)\fP\&. The password policy database and lock files are also derived from this value. .TP .B \fB\-k\fP \fImkeytype\fP specifies the key type of the master key in the database. The default is given by the \fBmaster_key_type\fP variable in \fIkdc.conf(5)\fP\&. .TP .B \fB\-kv\fP \fImkeyVNO\fP Specifies the version number of the master key in the database; the default is 1. Note that 0 is not allowed. .TP .B \fB\-M\fP \fImkeyname\fP principal name for the master key in the database. If not specified, the name is determined by the \fBmaster_key_name\fP variable in \fIkdc.conf(5)\fP\&. .TP .B \fB\-m\fP specifies that the master database password should be read from the keyboard rather than fetched from a file on disk. .TP .B \fB\-sf\fP \fIstash_file\fP specifies the stash filename of the master database password. If not specified, the filename is determined by the \fBkey_stash_file\fP variable in \fIkdc.conf(5)\fP\&. .TP .B \fB\-P\fP \fIpassword\fP specifies the master database password. Using this option may expose the password to other users on the system via the process list. .UNINDENT .SH COMMANDS .SS create .INDENT 0.0 .INDENT 3.5 \fBcreate\fP [\fB\-s\fP] .UNINDENT .UNINDENT .sp Creates a new database. If the \fB\-s\fP option is specified, the stash file is also created. This command fails if the database already exists. If the command is successful, the database is opened just as if it had already existed when the program was first run. .SS destroy .INDENT 0.0 .INDENT 3.5 \fBdestroy\fP [\fB\-f\fP] .UNINDENT .UNINDENT .sp Destroys the database, first overwriting the disk sectors and then unlinking the files, after prompting the user for confirmation. With the \fB\-f\fP argument, does not prompt the user. .SS stash .INDENT 0.0 .INDENT 3.5 \fBstash\fP [\fB\-f\fP \fIkeyfile\fP] .UNINDENT .UNINDENT .sp Stores the master principal\(aqs keys in a stash file. The \fB\-f\fP argument can be used to override the \fIkeyfile\fP specified in \fIkdc.conf(5)\fP\&. .SS dump .INDENT 0.0 .INDENT 3.5 \fBdump\fP [\fB\-b7\fP|\fB\-ov\fP|\fB\-r13\fP] [\fB\-verbose\fP] [\fB\-mkey_convert\fP] [\fB\-new_mkey_file\fP \fImkey_file\fP] [\fB\-rev\fP] [\fB\-recurse\fP] [\fIfilename\fP [\fIprincipals\fP\&...]] .UNINDENT .UNINDENT .sp Dumps the current Kerberos and KADM5 database into an ASCII file. By default, the database is dumped in current format, "kdb5_util load_dump version 7". If filename is not specified, or is the string "\-", the dump is sent to standard output. Options: .INDENT 0.0 .TP .B \fB\-b7\fP causes the dump to be in the Kerberos 5 Beta 7 format ("kdb5_util load_dump version 4"). This was the dump format produced on releases prior to 1.2.2. .TP .B \fB\-ov\fP causes the dump to be in "ovsec_adm_export" format. .TP .B \fB\-r13\fP causes the dump to be in the Kerberos 5 1.3 format ("kdb5_util load_dump version 5"). This was the dump format produced on releases prior to 1.8. .TP .B \fB\-r18\fP causes the dump to be in the Kerberos 5 1.8 format ("kdb5_util load_dump version 6"). This was the dump format produced on releases prior to 1.11. .TP .B \fB\-verbose\fP causes the name of each principal and policy to be printed as it is dumped. .TP .B \fB\-mkey_convert\fP prompts for a new master key. This new master key will be used to re\-encrypt principal key data in the dumpfile. The principal keys themselves will not be changed. .TP .B \fB\-new_mkey_file\fP \fImkey_file\fP the filename of a stash file. The master key in this stash file will be used to re\-encrypt the key data in the dumpfile. The key data in the database will not be changed. .TP .B \fB\-rev\fP dumps in reverse order. This may recover principals that do not dump normally, in cases where database corruption has occurred. .TP .B \fB\-recurse\fP causes the dump to walk the database recursively (btree only). This may recover principals that do not dump normally, in cases where database corruption has occurred. In cases of such corruption, this option will probably retrieve more principals than the \fB\-rev\fP option will. .sp Changed in version 1.15: Release 1.15 restored the functionality of the \fB\-recurse\fP option. .sp Changed in version 1.5: The \fB\-recurse\fP option ceased working until release 1.15, doing a normal dump instead of a recursive traversal. .UNINDENT .SS load .INDENT 0.0 .INDENT 3.5 \fBload\fP [\fB\-b7\fP|\fB\-ov\fP|\fB\-r13\fP] [\fB\-hash\fP] [\fB\-verbose\fP] [\fB\-update\fP] \fIfilename\fP [\fIdbname\fP] .UNINDENT .UNINDENT .sp Loads a database dump from the named file into the named database. If no option is given to determine the format of the dump file, the format is detected automatically and handled as appropriate. Unless the \fB\-update\fP option is given, \fBload\fP creates a new database containing only the data in the dump file, overwriting the contents of any previously existing database. Note that when using the LDAP KDC database module, the \fB\-update\fP flag is required. .sp Options: .INDENT 0.0 .TP .B \fB\-b7\fP requires the database to be in the Kerberos 5 Beta 7 format ("kdb5_util load_dump version 4"). This was the dump format produced on releases prior to 1.2.2. .TP .B \fB\-ov\fP requires the database to be in "ovsec_adm_import" format. Must be used with the \fB\-update\fP option. .TP .B \fB\-r13\fP requires the database to be in Kerberos 5 1.3 format ("kdb5_util load_dump version 5"). This was the dump format produced on releases prior to 1.8. .TP .B \fB\-r18\fP requires the database to be in Kerberos 5 1.8 format ("kdb5_util load_dump version 6"). This was the dump format produced on releases prior to 1.11. .TP .B \fB\-hash\fP requires the database to be stored as a hash. If this option is not specified, the database will be stored as a btree. This option is not recommended, as databases stored in hash format are known to corrupt data and lose principals. .TP .B \fB\-verbose\fP causes the name of each principal and policy to be printed as it is dumped. .TP .B \fB\-update\fP records from the dump file are added to or updated in the existing database. Otherwise, a new database is created containing only what is in the dump file and the old one destroyed upon successful completion. .UNINDENT .sp If specified, \fIdbname\fP overrides the value specified on the command line or the default. .SS ark .INDENT 0.0 .INDENT 3.5 \fBark\fP [\fB\-e\fP \fIenc\fP:\fIsalt\fP,...] \fIprincipal\fP .UNINDENT .UNINDENT .sp Adds new random keys to \fIprincipal\fP at the next available key version number. Keys for the current highest key version number will be preserved. The \fB\-e\fP option specifies the list of encryption and salt types to be used for the new keys. .SS add_mkey .INDENT 0.0 .INDENT 3.5 \fBadd_mkey\fP [\fB\-e\fP \fIetype\fP] [\fB\-s\fP] .UNINDENT .UNINDENT .sp Adds a new master key to the master key principal, but does not mark it as active. Existing master keys will remain. The \fB\-e\fP option specifies the encryption type of the new master key; see \fIEncryption_types\fP in \fIkdc.conf(5)\fP for a list of possible values. The \fB\-s\fP option stashes the new master key in the stash file, which will be created if it doesn\(aqt already exist. .sp After a new master key is added, it should be propagated to slave servers via a manual or periodic invocation of \fIkprop(8)\fP\&. Then, the stash files on the slave servers should be updated with the kdb5_util \fBstash\fP command. Once those steps are complete, the key is ready to be marked active with the kdb5_util \fBuse_mkey\fP command. .SS use_mkey .INDENT 0.0 .INDENT 3.5 \fBuse_mkey\fP \fImkeyVNO\fP [\fItime\fP] .UNINDENT .UNINDENT .sp Sets the activation time of the master key specified by \fImkeyVNO\fP\&. Once a master key becomes active, it will be used to encrypt newly created principal keys. If no \fItime\fP argument is given, the current time is used, causing the specified master key version to become active immediately. The format for \fItime\fP is \fIgetdate\fP string. .sp After a new master key becomes active, the kdb5_util \fBupdate_princ_encryption\fP command can be used to update all principal keys to be encrypted in the new master key. .SS list_mkeys .INDENT 0.0 .INDENT 3.5 \fBlist_mkeys\fP .UNINDENT .UNINDENT .sp List all master keys, from most recent to earliest, in the master key principal. The output will show the kvno, enctype, and salt type for each mkey, similar to the output of \fIkadmin(1)\fP \fBgetprinc\fP\&. A \fB*\fP following an mkey denotes the currently active master key. .SS purge_mkeys .INDENT 0.0 .INDENT 3.5 \fBpurge_mkeys\fP [\fB\-f\fP] [\fB\-n\fP] [\fB\-v\fP] .UNINDENT .UNINDENT .sp Delete master keys from the master key principal that are not used to protect any principals. This command can be used to remove old master keys all principal keys are protected by a newer master key. .INDENT 0.0 .TP .B \fB\-f\fP does not prompt for confirmation. .TP .B \fB\-n\fP performs a dry run, showing master keys that would be purged, but not actually purging any keys. .TP .B \fB\-v\fP gives more verbose output. .UNINDENT .SS update_princ_encryption .INDENT 0.0 .INDENT 3.5 \fBupdate_princ_encryption\fP [\fB\-f\fP] [\fB\-n\fP] [\fB\-v\fP] [\fIprinc\-pattern\fP] .UNINDENT .UNINDENT .sp Update all principal records (or only those matching the \fIprinc\-pattern\fP glob pattern) to re\-encrypt the key data using the active database master key, if they are encrypted using a different version, and give a count at the end of the number of principals updated. If the \fB\-f\fP option is not given, ask for confirmation before starting to make changes. The \fB\-v\fP option causes each principal processed to be listed, with an indication as to whether it needed updating or not. The \fB\-n\fP option performs a dry run, only showing the actions which would have been taken. .SS tabdump .INDENT 0.0 .INDENT 3.5 \fBtabdump\fP [\fB\-H\fP] [\fB\-c\fP] [\fB\-e\fP] [\fB\-n\fP] [\fB\-o\fP \fIoutfile\fP] \fIdumptype\fP .UNINDENT .UNINDENT .sp Dump selected fields of the database in a tabular format suitable for reporting (e.g., using traditional Unix text processing tools) or importing into relational databases. The data format is tab\-separated (default), or optionally comma\-separated (CSV), with a fixed number of columns. The output begins with a header line containing field names, unless suppression is requested using the \fB\-H\fP option. .sp The \fIdumptype\fP parameter specifies the name of an output table (see below). .sp Options: .INDENT 0.0 .TP .B \fB\-H\fP suppress writing the field names in a header line .TP .B \fB\-c\fP use comma separated values (CSV) format, with minimal quoting, instead of the default tab\-separated (unquoted, unescaped) format .TP .B \fB\-e\fP write empty hexadecimal string fields as empty fields instead of as "\-1". .TP .B \fB\-n\fP produce numeric output for fields that normally have symbolic output, such as enctypes and flag names. Also requests output of time stamps as decimal POSIX time_t values. .TP .B \fB\-o\fP \fIoutfile\fP write the dump to the specified output file instead of to standard output .UNINDENT .sp Dump types: .INDENT 0.0 .TP .B \fBkeydata\fP principal encryption key information, including actual key data (which is still encrypted in the master key) .INDENT 7.0 .TP .B \fBname\fP principal name .TP .B \fBkeyindex\fP index of this key in the principal\(aqs key list .TP .B \fBkvno\fP key version number .TP .B \fBenctype\fP encryption type .TP .B \fBkey\fP key data as a hexadecimal string .TP .B \fBsalttype\fP salt type .TP .B \fBsalt\fP salt data as a hexadecimal string .UNINDENT .TP .B \fBkeyinfo\fP principal encryption key information (as in \fBkeydata\fP above), excluding actual key data .TP .B \fBprinc_flags\fP principal boolean attributes. Flag names print as hexadecimal numbers if the \fB\-n\fP option is specified, and all flag positions are printed regardless of whether or not they are set. If \fB\-n\fP is not specified, print all known flag names for each principal, but only print hexadecimal flag names if the corresponding flag is set. .INDENT 7.0 .TP .B \fBname\fP principal name .TP .B \fBflag\fP flag name .TP .B \fBvalue\fP boolean value (0 for clear, or 1 for set) .UNINDENT .TP .B \fBprinc_lockout\fP state information used for tracking repeated password failures .INDENT 7.0 .TP .B \fBname\fP principal name .TP .B \fBlast_success\fP time stamp of most recent successful authentication .TP .B \fBlast_failed\fP time stamp of most recent failed authentication .TP .B \fBfail_count\fP count of failed attempts .UNINDENT .TP .B \fBprinc_meta\fP principal metadata .INDENT 7.0 .TP .B \fBname\fP principal name .TP .B \fBmodby\fP name of last principal to modify this principal .TP .B \fBmodtime\fP timestamp of last modification .TP .B \fBlastpwd\fP timestamp of last password change .TP .B \fBpolicy\fP policy object name .TP .B \fBmkvno\fP key version number of the master key that encrypts this principal\(aqs key data .TP .B \fBhist_kvno\fP key version number of the history key that encrypts the key history data for this principal .UNINDENT .TP .B \fBprinc_stringattrs\fP string attributes (key/value pairs) .INDENT 7.0 .TP .B \fBname\fP principal name .TP .B \fBkey\fP attribute name .TP .B \fBvalue\fP attribute value .UNINDENT .TP .B \fBprinc_tktpolicy\fP per\-principal ticket policy data, including maximum ticket lifetimes .INDENT 7.0 .TP .B \fBname\fP principal name .TP .B \fBexpiration\fP principal expiration date .TP .B \fBpw_expiration\fP password expiration date .TP .B \fBmax_life\fP maximum ticket lifetime .TP .B \fBmax_renew_life\fP maximum renewable ticket lifetime .UNINDENT .UNINDENT .sp Examples: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C $ kdb5_util tabdump \-o keyinfo.txt keyinfo $ cat keyinfo.txt name keyindex kvno enctype salttype salt foo@EXAMPLE.COM 0 1 aes128\-cts\-hmac\-sha1\-96 normal \-1 bar@EXAMPLE.COM 0 1 aes128\-cts\-hmac\-sha1\-96 normal \-1 bar@EXAMPLE.COM 1 1 des\-cbc\-crc normal \-1 $ sqlite3 sqlite> .mode tabs sqlite> .import keyinfo.txt keyinfo sqlite> select * from keyinfo where enctype like \(aqdes\-cbc\-%\(aq; bar@EXAMPLE.COM 1 1 des\-cbc\-crc normal \-1 sqlite> .quit $ awk \-F\(aq\et\(aq \(aq$4 ~ /des\-cbc\-/ { print }\(aq keyinfo.txt bar@EXAMPLE.COM 1 1 des\-cbc\-crc normal \-1 .ft P .fi .UNINDENT .UNINDENT .SH SEE ALSO .sp \fIkadmin(1)\fP .SH AUTHOR MIT .SH COPYRIGHT 1985-2017, MIT .\" Generated by docutils manpage writer. . krb5-1.16/src/man/kswitch.man0000644000704600001450000000402513211554426015712 0ustar ghudsonlibuuid.\" Man page generated from reStructuredText. . .TH "KSWITCH" "1" " " "1.16" "MIT Kerberos" .SH NAME kswitch \- switch primary ticket cache . .nr rst2man-indent-level 0 . .de1 rstReportMargin \\$1 \\n[an-margin] level \\n[rst2man-indent-level] level margin: \\n[rst2man-indent\\n[rst2man-indent-level]] - \\n[rst2man-indent0] \\n[rst2man-indent1] \\n[rst2man-indent2] .. .de1 INDENT .\" .rstReportMargin pre: . RS \\$1 . nr rst2man-indent\\n[rst2man-indent-level] \\n[an-margin] . nr rst2man-indent-level +1 .\" .rstReportMargin post: .. .de UNINDENT . RE .\" indent \\n[an-margin] .\" old: \\n[rst2man-indent\\n[rst2man-indent-level]] .nr rst2man-indent-level -1 .\" new: \\n[rst2man-indent\\n[rst2man-indent-level]] .in \\n[rst2man-indent\\n[rst2man-indent-level]]u .. .SH SYNOPSIS .sp \fBkswitch\fP {\fB\-c\fP \fIcachename\fP|\fB\-p\fP \fIprincipal\fP} .SH DESCRIPTION .sp kswitch makes the specified credential cache the primary cache for the collection, if a cache collection is available. .SH OPTIONS .INDENT 0.0 .TP .B \fB\-c\fP \fIcachename\fP Directly specifies the credential cache to be made primary. .TP .B \fB\-p\fP \fIprincipal\fP Causes the cache collection to be searched for a cache containing credentials for \fIprincipal\fP\&. If one is found, that collection is made primary. .UNINDENT .SH ENVIRONMENT .sp kswitch uses the following environment variables: .INDENT 0.0 .TP .B \fBKRB5CCNAME\fP Location of the default Kerberos 5 credentials (ticket) cache, in the form \fItype\fP:\fIresidual\fP\&. If no \fItype\fP prefix is present, the \fBFILE\fP type is assumed. The type of the default cache may determine the availability of a cache collection; for instance, a default cache of type \fBDIR\fP causes caches within the directory to be present in the collection. .UNINDENT .SH FILES .INDENT 0.0 .TP .B \fB@CCNAME@\fP Default location of Kerberos 5 credentials cache .UNINDENT .SH SEE ALSO .sp \fIkinit(1)\fP, \fIkdestroy(1)\fP, \fIklist(1)\fP), kerberos(1) .SH AUTHOR MIT .SH COPYRIGHT 1985-2017, MIT .\" Generated by docutils manpage writer. . krb5-1.16/src/man/k5identity.man0000644000704600001450000000602113211554426016325 0ustar ghudsonlibuuid.\" Man page generated from reStructuredText. . .TH "K5IDENTITY" "5" " " "1.16" "MIT Kerberos" .SH NAME k5identity \- Kerberos V5 client principal selection rules . .nr rst2man-indent-level 0 . .de1 rstReportMargin \\$1 \\n[an-margin] level \\n[rst2man-indent-level] level margin: \\n[rst2man-indent\\n[rst2man-indent-level]] - \\n[rst2man-indent0] \\n[rst2man-indent1] \\n[rst2man-indent2] .. .de1 INDENT .\" .rstReportMargin pre: . RS \\$1 . nr rst2man-indent\\n[rst2man-indent-level] \\n[an-margin] . nr rst2man-indent-level +1 .\" .rstReportMargin post: .. .de UNINDENT . RE .\" indent \\n[an-margin] .\" old: \\n[rst2man-indent\\n[rst2man-indent-level]] .nr rst2man-indent-level -1 .\" new: \\n[rst2man-indent\\n[rst2man-indent-level]] .in \\n[rst2man-indent\\n[rst2man-indent-level]]u .. .SH DESCRIPTION .sp The .k5identity file, which resides in a user\(aqs home directory, contains a list of rules for selecting a client principals based on the server being accessed. These rules are used to choose a credential cache within the cache collection when possible. .sp Blank lines and lines beginning with \fB#\fP are ignored. Each line has the form: .INDENT 0.0 .INDENT 3.5 \fIprincipal\fP \fIfield\fP=\fIvalue\fP ... .UNINDENT .UNINDENT .sp If the server principal meets all of the field constraints, then principal is chosen as the client principal. The following fields are recognized: .INDENT 0.0 .TP .B \fBrealm\fP If the realm of the server principal is known, it is matched against \fIvalue\fP, which may be a pattern using shell wildcards. For host\-based server principals, the realm will generally only be known if there is a \fIdomain_realm\fP section in \fIkrb5.conf(5)\fP with a mapping for the hostname. .TP .B \fBservice\fP If the server principal is a host\-based principal, its service component is matched against \fIvalue\fP, which may be a pattern using shell wildcards. .TP .B \fBhost\fP If the server principal is a host\-based principal, its hostname component is converted to lower case and matched against \fIvalue\fP, which may be a pattern using shell wildcards. .sp If the server principal matches the constraints of multiple lines in the .k5identity file, the principal from the first matching line is used. If no line matches, credentials will be selected some other way, such as the realm heuristic or the current primary cache. .UNINDENT .SH EXAMPLE .sp The following example .k5identity file selects the client principal \fBalice@KRBTEST.COM\fP if the server principal is within that realm, the principal \fBalice/root@EXAMPLE.COM\fP if the server host is within a servers subdomain, and the principal \fBalice/mail@EXAMPLE.COM\fP when accessing the IMAP service on \fBmail.example.com\fP: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C alice@KRBTEST.COM realm=KRBTEST.COM alice/root@EXAMPLE.COM host=*.servers.example.com alice/mail@EXAMPLE.COM host=mail.example.com service=imap .ft P .fi .UNINDENT .UNINDENT .SH SEE ALSO .sp kerberos(1), \fIkrb5.conf(5)\fP .SH AUTHOR MIT .SH COPYRIGHT 1985-2017, MIT .\" Generated by docutils manpage writer. . krb5-1.16/src/man/Makefile.in0000644000704600001450000001371213211554426015611 0ustar ghudsonlibuuidmydir=man BUILDTOP=$(REL).. SPHINX_BUILD=sphinx-build GROFF=@GROFF@ GROFF_MAN=$(GROFF) -mtty-char -Tascii -mandoc -c localstatedir=@localstatedir@ runstatedir=@runstatedir@ sysconfdir=@sysconfdir@ DEFCCNAME=@DEFCCNAME@ DEFKTNAME=@DEFKTNAME@ DEFCKTNAME=@DEFCKTNAME@ MANSUBS=k5identity.sub k5login.sub k5srvutil.sub kadm5.acl.sub kadmin.sub \ kadmind.sub kdb5_ldap_util.sub kdb5_util.sub kdc.conf.sub \ kdestroy.sub kinit.sub klist.sub kpasswd.sub kprop.sub kpropd.sub \ kproplog.sub krb5.conf.sub krb5-config.sub krb5kdc.sub ksu.sub \ kswitch.sub ktutil.sub kvno.sub sclient.sub sserver.sub docsrc=$(top_srcdir)/../doc # Update checked-in man pages from RST sources in the top-level doc # directory. This can be done from an unconfigured tree with: # make -f Makefile.in top_srcdir=.. srcdir=. man # make -f Makefile.in clean # The sed command deletes some trailing whitespace that the docutils # manpage writer outputs near the end of its output files. man: $(docsrc)/version.py rm -rf rst_man $(SPHINX_BUILD) -q -t mansubs -b man $(docsrc) rst_man for f in rst_man/*.[0-9]; do \ name=`echo $$f | sed -e 's|^.*/\(.*\)\.[0-9]$$|\1|'`; \ sed -e '/^\.\\" $$/d' \ -e '/^\.\\"/s/reStructeredText/reStructuredText/' \ $$f > $(srcdir)/$$name.man; \ done $(docsrc)/version.py: $(top_srcdir)/patchlevel.h (cd $(BUILDTOP)/doc && make version.py) .SUFFIXES: .man .sub .man.sub: sed -e 's|@BINDIR@|$(CLIENT_BINDIR)|g' \ -e 's|@SBINDIR@|$(SERVER_BINDIR)|g' \ -e 's|@LIBDIR@|$(KRB5_LIBDIR)|g' \ -e 's|@LOCALSTATEDIR@|$(localstatedir)|g' \ -e 's|@RUNSTATEDIR@|$(runstatedir)|g' \ -e 's|@SYSCONFDIR@|$(sysconfdir)|g' \ -e 's|@CCNAME@|$(DEFCCNAME)|g' \ -e 's|@KTNAME@|$(DEFKTNAME)|g' \ -e 's|@CKTNAME@|$(DEFCKTNAME)|g' $? > $@ all: $(MANSUBS) clean: rm -rf $(MANSUBS) rst_man install: install-clientman install-fileman install-adminman install-serverman install-catman: install-clientcat install-filecat install-admincat install-servercat install-clientman: $(INSTALL_DATA) k5srvutil.sub $(DESTDIR)$(CLIENT_MANDIR)/k5srvutil.1 $(INSTALL_DATA) kadmin.sub $(DESTDIR)$(CLIENT_MANDIR)/kadmin.1 $(INSTALL_DATA) kdestroy.sub $(DESTDIR)$(CLIENT_MANDIR)/kdestroy.1 $(INSTALL_DATA) kinit.sub $(DESTDIR)$(CLIENT_MANDIR)/kinit.1 $(INSTALL_DATA) klist.sub $(DESTDIR)$(CLIENT_MANDIR)/klist.1 $(INSTALL_DATA) kpasswd.sub $(DESTDIR)$(CLIENT_MANDIR)/kpasswd.1 $(INSTALL_DATA) krb5-config.sub $(DESTDIR)$(CLIENT_MANDIR)/krb5-config.1 $(INSTALL_DATA) ksu.sub $(DESTDIR)$(CLIENT_MANDIR)/ksu.1 $(INSTALL_DATA) kswitch.sub $(DESTDIR)$(CLIENT_MANDIR)/kswitch.1 $(INSTALL_DATA) ktutil.sub $(DESTDIR)$(CLIENT_MANDIR)/ktutil.1 $(INSTALL_DATA) kvno.sub $(DESTDIR)$(CLIENT_MANDIR)/kvno.1 $(INSTALL_DATA) sclient.sub $(DESTDIR)$(CLIENT_MANDIR)/sclient.1 install-fileman: $(INSTALL_DATA) $(srcdir)/dot.k5identity.5 \ $(DESTDIR)$(FILE_MANDIR)/.k5identity.5 $(INSTALL_DATA) k5identity.sub $(DESTDIR)$(FILE_MANDIR)/k5identity.5 $(INSTALL_DATA) $(srcdir)/dot.k5login.5 \ $(DESTDIR)$(FILE_MANDIR)/.k5login.5 $(INSTALL_DATA) k5login.sub $(DESTDIR)$(FILE_MANDIR)/k5login.5 $(INSTALL_DATA) kadm5.acl.sub $(DESTDIR)$(FILE_MANDIR)/kadm5.acl.5 $(INSTALL_DATA) kdc.conf.sub $(DESTDIR)$(FILE_MANDIR)/kdc.conf.5 $(INSTALL_DATA) krb5.conf.sub $(DESTDIR)$(FILE_MANDIR)/krb5.conf.5 install-adminman: $(INSTALL_DATA) $(srcdir)/kadmin.local.8 \ $(DESTDIR)$(ADMIN_MANDIR)/kadmin.local.8 $(INSTALL_DATA) kdb5_ldap_util.sub \ $(DESTDIR)$(ADMIN_MANDIR)/kdb5_ldap_util.8 $(INSTALL_DATA) kdb5_util.sub $(DESTDIR)$(ADMIN_MANDIR)/kdb5_util.8 $(INSTALL_DATA) kprop.sub $(DESTDIR)$(ADMIN_MANDIR)/kprop.8 $(INSTALL_DATA) kproplog.sub $(DESTDIR)$(ADMIN_MANDIR)/kproplog.8 install-serverman: $(INSTALL_DATA) kadmind.sub $(DESTDIR)$(SERVER_MANDIR)/kadmind.8 $(INSTALL_DATA) kpropd.sub $(DESTDIR)$(SERVER_MANDIR)/kpropd.8 $(INSTALL_DATA) krb5kdc.sub $(DESTDIR)$(SERVER_MANDIR)/krb5kdc.8 $(INSTALL_DATA) sserver.sub $(DESTDIR)$(SERVER_MANDIR)/sserver.8 install-clientcat: $(GROFF_MAN) k5srvutil.sub > $(DESTDIR)$(CLIENT_CATDIR)/k5srvutil.1 $(GROFF_MAN) kadmin.sub > $(DESTDIR)$(CLIENT_CATDIR)/kadmin.1 $(GROFF_MAN) kdestroy.sub > $(DESTDIR)$(CLIENT_CATDIR)/kdestroy.1 $(GROFF_MAN) kinit.sub > $(DESTDIR)$(CLIENT_CATDIR)/kinit.1 $(GROFF_MAN) klist.sub > $(DESTDIR)$(CLIENT_CATDIR)/klist.1 $(GROFF_MAN) kpasswd.sub > $(DESTDIR)$(CLIENT_CATDIR)/kpasswd.1 $(GROFF_MAN) krb5-config.sub > $(DESTDIR)$(CLIENT_CATDIR)/krb5-config.1 $(GROFF_MAN) ksu.sub > $(DESTDIR)$(CLIENT_CATDIR)/ksu.1 $(GROFF_MAN) kswitch.sub > $(DESTDIR)$(CLIENT_CATDIR)/kswitch.1 $(GROFF_MAN) ktutil.sub > $(DESTDIR)$(CLIENT_CATDIR)/ktutil.1 $(GROFF_MAN) kvno.sub > $(DESTDIR)$(CLIENT_CATDIR)/kvno.1 $(GROFF_MAN) sclient.sub > $(DESTDIR)$(CLIENT_CATDIR)/sclient.1 install-filecat: $(GROFF_MAN) k5identity.sub > $(DESTDIR)$(FILE_CATDIR)/k5identity.5 ($(RM) $(DESTDIR)$(FILE_CATDIR)/.k5identity.5; \ $(LN_S) $(FILE_CATDIR)/k5identity.5 \ $(DESTDIR)$(FILE_CATDIR)/.k5identity.5) $(GROFF_MAN) k5login.sub > $(DESTDIR)$(FILE_CATDIR)/k5login.5 ($(RM) $(DESTDIR)$(FILE_CATDIR)/.k5login.5; \ $(LN_S) $(FILE_CATDIR)/k5login.5 \ $(DESTDIR)$(FILE_CATDIR)/.k5login.5) $(GROFF_MAN) kadm5.acl.sub > $(DESTDIR)$(FILE_CATDIR)/kadm5.acl.5 $(GROFF_MAN) kdc.conf.sub > $(DESTDIR)$(FILE_CATDIR)/kdc.conf.5 $(GROFF_MAN) krb5.conf.sub > $(DESTDIR)$(FILE_CATDIR)/krb5.conf.5 install-admincat: ($(RM) $(DESTDIR)$(ADMIN_CATDIR)/kadmin.local.8; \ $(LN_S) $(CLIENT_CATDIR)/kadmin.1 \ $(DESTDIR)$(ADMIN_CATDIR)/kadmin.local.8) $(GROFF_MAN) kdb5_ldap_util.sub > \ $(DESTDIR)$(ADMIN_CATDIR)/kdb5_ldap_util.8 $(GROFF_MAN) kdb5_util.sub > $(DESTDIR)$(ADMIN_CATDIR)/kdb5_util.8 $(GROFF_MAN) kprop.sub > $(DESTDIR)$(ADMIN_CATDIR)/kprop.8 $(GROFF_MAN) kproplog.sub > $(DESTDIR)$(ADMIN_CATDIR)/kproplog.8 install-servercat: $(GROFF_MAN) kadmind.sub > $(DESTDIR)$(SERVER_CATDIR)/kadmind.8 $(GROFF_MAN) kpropd.sub > $(DESTDIR)$(SERVER_CATDIR)/kpropd.8 $(GROFF_MAN) krb5kdc.sub > $(DESTDIR)$(SERVER_CATDIR)/krb5kdc.8 $(GROFF_MAN) sserver.sub > $(DESTDIR)$(SERVER_CATDIR)/sserver.8 krb5-1.16/src/man/kdc.conf.man0000644000704600001450000011445113211554426015730 0ustar ghudsonlibuuid.\" Man page generated from reStructuredText. . .TH "KDC.CONF" "5" " " "1.16" "MIT Kerberos" .SH NAME kdc.conf \- Kerberos V5 KDC configuration file . .nr rst2man-indent-level 0 . .de1 rstReportMargin \\$1 \\n[an-margin] level \\n[rst2man-indent-level] level margin: \\n[rst2man-indent\\n[rst2man-indent-level]] - \\n[rst2man-indent0] \\n[rst2man-indent1] \\n[rst2man-indent2] .. .de1 INDENT .\" .rstReportMargin pre: . RS \\$1 . nr rst2man-indent\\n[rst2man-indent-level] \\n[an-margin] . nr rst2man-indent-level +1 .\" .rstReportMargin post: .. .de UNINDENT . RE .\" indent \\n[an-margin] .\" old: \\n[rst2man-indent\\n[rst2man-indent-level]] .nr rst2man-indent-level -1 .\" new: \\n[rst2man-indent\\n[rst2man-indent-level]] .in \\n[rst2man-indent\\n[rst2man-indent-level]]u .. .sp The kdc.conf file supplements \fIkrb5.conf(5)\fP for programs which are typically only used on a KDC, such as the \fIkrb5kdc(8)\fP and \fIkadmind(8)\fP daemons and the \fIkdb5_util(8)\fP program. Relations documented here may also be specified in krb5.conf; for the KDC programs mentioned, krb5.conf and kdc.conf will be merged into a single configuration profile. .sp Normally, the kdc.conf file is found in the KDC state directory, \fB@LOCALSTATEDIR@\fP\fB/krb5kdc\fP\&. You can override the default location by setting the environment variable \fBKRB5_KDC_PROFILE\fP\&. .sp Please note that you need to restart the KDC daemon for any configuration changes to take effect. .SH STRUCTURE .sp The kdc.conf file is set up in the same format as the \fIkrb5.conf(5)\fP file. .SH SECTIONS .sp The kdc.conf file may contain the following sections: .TS center; |l|l|. _ T{ \fI\%[kdcdefaults]\fP T} T{ Default values for KDC behavior T} _ T{ \fI\%[realms]\fP T} T{ Realm\-specific database configuration and settings T} _ T{ \fI\%[dbdefaults]\fP T} T{ Default database settings T} _ T{ \fI\%[dbmodules]\fP T} T{ Per\-database settings T} _ T{ \fI\%[logging]\fP T} T{ Controls how Kerberos daemons perform logging T} _ .TE .SS [kdcdefaults] .sp With two exceptions, relations in the [kdcdefaults] section specify default values for realm variables, to be used if the [realms] subsection does not contain a relation for the tag. See the \fI\%[realms]\fP section for the definitions of these relations. .INDENT 0.0 .IP \(bu 2 \fBhost_based_services\fP .IP \(bu 2 \fBkdc_listen\fP .IP \(bu 2 \fBkdc_ports\fP .IP \(bu 2 \fBkdc_tcp_listen\fP .IP \(bu 2 \fBkdc_tcp_ports\fP .IP \(bu 2 \fBno_host_referral\fP .IP \(bu 2 \fBrestrict_anonymous_to_tgt\fP .UNINDENT .INDENT 0.0 .TP .B \fBkdc_max_dgram_reply_size\fP Specifies the maximum packet size that can be sent over UDP. The default value is 4096 bytes. .TP .B \fBkdc_tcp_listen_backlog\fP (Integer.) Set the size of the listen queue length for the KDC daemon. The value may be limited by OS settings. The default value is 5. .UNINDENT .SS [realms] .sp Each tag in the [realms] section is the name of a Kerberos realm. The value of the tag is a subsection where the relations define KDC parameters for that particular realm. The following example shows how to define one parameter for the ATHENA.MIT.EDU realm: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C [realms] ATHENA.MIT.EDU = { max_renewable_life = 7d 0h 0m 0s } .ft P .fi .UNINDENT .UNINDENT .sp The following tags may be specified in a [realms] subsection: .INDENT 0.0 .TP .B \fBacl_file\fP (String.) Location of the access control list file that \fIkadmind(8)\fP uses to determine which principals are allowed which permissions on the Kerberos database. To operate without an ACL file, set this relation to the empty string with \fBacl_file = ""\fP\&. The default value is \fB@LOCALSTATEDIR@\fP\fB/krb5kdc\fP\fB/kadm5.acl\fP\&. For more information on Kerberos ACL file see \fIkadm5.acl(5)\fP\&. .TP .B \fBdatabase_module\fP (String.) This relation indicates the name of the configuration section under \fI\%[dbmodules]\fP for database\-specific parameters used by the loadable database library. The default value is the realm name. If this configuration section does not exist, default values will be used for all database parameters. .TP .B \fBdatabase_name\fP (String, deprecated.) This relation specifies the location of the Kerberos database for this realm, if the DB2 module is being used and the \fI\%[dbmodules]\fP configuration section does not specify a database name. The default value is \fB@LOCALSTATEDIR@\fP\fB/krb5kdc\fP\fB/principal\fP\&. .TP .B \fBdefault_principal_expiration\fP (\fIabstime\fP string.) Specifies the default expiration date of principals created in this realm. The default value is 0, which means no expiration date. .TP .B \fBdefault_principal_flags\fP (Flag string.) Specifies the default attributes of principals created in this realm. The format for this string is a comma\-separated list of flags, with \(aq+\(aq before each flag that should be enabled and \(aq\-\(aq before each flag that should be disabled. The \fBpostdateable\fP, \fBforwardable\fP, \fBtgt\-based\fP, \fBrenewable\fP, \fBproxiable\fP, \fBdup\-skey\fP, \fBallow\-tickets\fP, and \fBservice\fP flags default to enabled. .sp There are a number of possible flags: .INDENT 7.0 .TP .B \fBallow\-tickets\fP Enabling this flag means that the KDC will issue tickets for this principal. Disabling this flag essentially deactivates the principal within this realm. .TP .B \fBdup\-skey\fP Enabling this flag allows the principal to obtain a session key for another user, permitting user\-to\-user authentication for this principal. .TP .B \fBforwardable\fP Enabling this flag allows the principal to obtain forwardable tickets. .TP .B \fBhwauth\fP If this flag is enabled, then the principal is required to preauthenticate using a hardware device before receiving any tickets. .TP .B \fBno\-auth\-data\-required\fP Enabling this flag prevents PAC or AD\-SIGNEDPATH data from being added to service tickets for the principal. .TP .B \fBok\-as\-delegate\fP If this flag is enabled, it hints the client that credentials can and should be delegated when authenticating to the service. .TP .B \fBok\-to\-auth\-as\-delegate\fP Enabling this flag allows the principal to use S4USelf tickets. .TP .B \fBpostdateable\fP Enabling this flag allows the principal to obtain postdateable tickets. .TP .B \fBpreauth\fP If this flag is enabled on a client principal, then that principal is required to preauthenticate to the KDC before receiving any tickets. On a service principal, enabling this flag means that service tickets for this principal will only be issued to clients with a TGT that has the preauthenticated bit set. .TP .B \fBproxiable\fP Enabling this flag allows the principal to obtain proxy tickets. .TP .B \fBpwchange\fP Enabling this flag forces a password change for this principal. .TP .B \fBpwservice\fP If this flag is enabled, it marks this principal as a password change service. This should only be used in special cases, for example, if a user\(aqs password has expired, then the user has to get tickets for that principal without going through the normal password authentication in order to be able to change the password. .TP .B \fBrenewable\fP Enabling this flag allows the principal to obtain renewable tickets. .TP .B \fBservice\fP Enabling this flag allows the the KDC to issue service tickets for this principal. .TP .B \fBtgt\-based\fP Enabling this flag allows a principal to obtain tickets based on a ticket\-granting\-ticket, rather than repeating the authentication process that was used to obtain the TGT. .UNINDENT .TP .B \fBdict_file\fP (String.) Location of the dictionary file containing strings that are not allowed as passwords. The file should contain one string per line, with no additional whitespace. If none is specified or if there is no policy assigned to the principal, no dictionary checks of passwords will be performed. .TP .B \fBencrypted_challenge_indicator\fP (String.) Specifies the authentication indicator value that the KDC asserts into tickets obtained using FAST encrypted challenge pre\-authentication. New in 1.16. .TP .B \fBhost_based_services\fP (Whitespace\- or comma\-separated list.) Lists services which will get host\-based referral processing even if the server principal is not marked as host\-based by the client. .TP .B \fBiprop_enable\fP (Boolean value.) Specifies whether incremental database propagation is enabled. The default value is false. .TP .B \fBiprop_master_ulogsize\fP (Integer.) Specifies the maximum number of log entries to be retained for incremental propagation. The default value is 1000. Prior to release 1.11, the maximum value was 2500. .TP .B \fBiprop_slave_poll\fP (Delta time string.) Specifies how often the slave KDC polls for new updates from the master. The default value is \fB2m\fP (that is, two minutes). .TP .B \fBiprop_listen\fP (Whitespace\- or comma\-separated list.) Specifies the iprop RPC listening addresses and/or ports for the \fIkadmind(8)\fP daemon. Each entry may be an interface address, a port number, or an address and port number separated by a colon. If the address contains colons, enclose it in square brackets. If no address is specified, the wildcard address is used. If kadmind fails to bind to any of the specified addresses, it will fail to start. The default (when \fBiprop_enable\fP is true) is to bind to the wildcard address at the port specified in \fBiprop_port\fP\&. New in release 1.15. .TP .B \fBiprop_port\fP (Port number.) Specifies the port number to be used for incremental propagation. When \fBiprop_enable\fP is true, this relation is required in the slave configuration file, and this relation or \fBiprop_listen\fP is required in the master configuration file, as there is no default port number. Port numbers specified in \fBiprop_listen\fP entries will override this port number for the \fIkadmind(8)\fP daemon. .TP .B \fBiprop_resync_timeout\fP (Delta time string.) Specifies the amount of time to wait for a full propagation to complete. This is optional in configuration files, and is used by slave KDCs only. The default value is 5 minutes (\fB5m\fP). New in release 1.11. .TP .B \fBiprop_logfile\fP (File name.) Specifies where the update log file for the realm database is to be stored. The default is to use the \fBdatabase_name\fP entry from the realms section of the krb5 config file, with \fB\&.ulog\fP appended. (NOTE: If \fBdatabase_name\fP isn\(aqt specified in the realms section, perhaps because the LDAP database back end is being used, or the file name is specified in the [dbmodules] section, then the hard\-coded default for \fBdatabase_name\fP is used. Determination of the \fBiprop_logfile\fP default value will not use values from the [dbmodules] section.) .TP .B \fBkadmind_listen\fP (Whitespace\- or comma\-separated list.) Specifies the kadmin RPC listening addresses and/or ports for the \fIkadmind(8)\fP daemon. Each entry may be an interface address, a port number, or an address and port number separated by a colon. If the address contains colons, enclose it in square brackets. If no address is specified, the wildcard address is used. If kadmind fails to bind to any of the specified addresses, it will fail to start. The default is to bind to the wildcard address at the port specified in \fBkadmind_port\fP, or the standard kadmin port (749). New in release 1.15. .TP .B \fBkadmind_port\fP (Port number.) Specifies the port on which the \fIkadmind(8)\fP daemon is to listen for this realm. Port numbers specified in \fBkadmind_listen\fP entries will override this port number. The assigned port for kadmind is 749, which is used by default. .TP .B \fBkey_stash_file\fP (String.) Specifies the location where the master key has been stored (via kdb5_util stash). The default is \fB@LOCALSTATEDIR@\fP\fB/krb5kdc\fP\fB/.k5.REALM\fP, where \fIREALM\fP is the Kerberos realm. .TP .B \fBkdc_listen\fP (Whitespace\- or comma\-separated list.) Specifies the UDP listening addresses and/or ports for the \fIkrb5kdc(8)\fP daemon. Each entry may be an interface address, a port number, or an address and port number separated by a colon. If the address contains colons, enclose it in square brackets. If no address is specified, the wildcard address is used. If no port is specified, the standard port (88) is used. If the KDC daemon fails to bind to any of the specified addresses, it will fail to start. The default is to bind to the wildcard address on the standard port. New in release 1.15. .TP .B \fBkdc_ports\fP (Whitespace\- or comma\-separated list, deprecated.) Prior to release 1.15, this relation lists the ports for the \fIkrb5kdc(8)\fP daemon to listen on for UDP requests. In release 1.15 and later, it has the same meaning as \fBkdc_listen\fP if that relation is not defined. .TP .B \fBkdc_tcp_listen\fP (Whitespace\- or comma\-separated list.) Specifies the TCP listening addresses and/or ports for the \fIkrb5kdc(8)\fP daemon. Each entry may be an interface address, a port number, or an address and port number separated by a colon. If the address contains colons, enclose it in square brackets. If no address is specified, the wildcard address is used. If no port is specified, the standard port (88) is used. To disable listening on TCP, set this relation to the empty string with \fBkdc_tcp_listen = ""\fP\&. If the KDC daemon fails to bind to any of the specified addresses, it will fail to start. The default is to bind to the wildcard address on the standard port. New in release 1.15. .TP .B \fBkdc_tcp_ports\fP (Whitespace\- or comma\-separated list, deprecated.) Prior to release 1.15, this relation lists the ports for the \fIkrb5kdc(8)\fP daemon to listen on for UDP requests. In release 1.15 and later, it has the same meaning as \fBkdc_tcp_listen\fP if that relation is not defined. .TP .B \fBkpasswd_listen\fP (Comma\-separated list.) Specifies the kpasswd listening addresses and/or ports for the \fIkadmind(8)\fP daemon. Each entry may be an interface address, a port number, or an address and port number separated by a colon. If the address contains colons, enclose it in square brackets. If no address is specified, the wildcard address is used. If kadmind fails to bind to any of the specified addresses, it will fail to start. The default is to bind to the wildcard address at the port specified in \fBkpasswd_port\fP, or the standard kpasswd port (464). New in release 1.15. .TP .B \fBkpasswd_port\fP (Port number.) Specifies the port on which the \fIkadmind(8)\fP daemon is to listen for password change requests for this realm. Port numbers specified in \fBkpasswd_listen\fP entries will override this port number. The assigned port for password change requests is 464, which is used by default. .TP .B \fBmaster_key_name\fP (String.) Specifies the name of the principal associated with the master key. The default is \fBK/M\fP\&. .TP .B \fBmaster_key_type\fP (Key type string.) Specifies the master key\(aqs key type. The default value for this is \fBaes256\-cts\-hmac\-sha1\-96\fP\&. For a list of all possible values, see \fI\%Encryption types\fP\&. .TP .B \fBmax_life\fP (\fIduration\fP string.) Specifies the maximum time period for which a ticket may be valid in this realm. The default value is 24 hours. .TP .B \fBmax_renewable_life\fP (\fIduration\fP string.) Specifies the maximum time period during which a valid ticket may be renewed in this realm. The default value is 0. .TP .B \fBno_host_referral\fP (Whitespace\- or comma\-separated list.) Lists services to block from getting host\-based referral processing, even if the client marks the server principal as host\-based or the service is also listed in \fBhost_based_services\fP\&. \fBno_host_referral = *\fP will disable referral processing altogether. .TP .B \fBdes_crc_session_supported\fP (Boolean value). If set to true, the KDC will assume that service principals support des\-cbc\-crc for session key enctype negotiation purposes. If \fBallow_weak_crypto\fP in \fIlibdefaults\fP is false, or if des\-cbc\-crc is not a permitted enctype, then this variable has no effect. Defaults to true. New in release 1.11. .TP .B \fBreject_bad_transit\fP (Boolean value.) If set to true, the KDC will check the list of transited realms for cross\-realm tickets against the transit path computed from the realm names and the capaths section of its \fIkrb5.conf(5)\fP file; if the path in the ticket to be issued contains any realms not in the computed path, the ticket will not be issued, and an error will be returned to the client instead. If this value is set to false, such tickets will be issued anyways, and it will be left up to the application server to validate the realm transit path. .sp If the disable\-transited\-check flag is set in the incoming request, this check is not performed at all. Having the \fBreject_bad_transit\fP option will cause such ticket requests to be rejected always. .sp This transit path checking and config file option currently apply only to TGS requests. .sp The default value is true. .TP .B \fBrestrict_anonymous_to_tgt\fP (Boolean value.) If set to true, the KDC will reject ticket requests from anonymous principals to service principals other than the realm\(aqs ticket\-granting service. This option allows anonymous PKINIT to be enabled for use as FAST armor tickets without allowing anonymous authentication to services. The default value is false. New in release 1.9. .TP .B \fBsupported_enctypes\fP (List of \fIkey\fP:\fIsalt\fP strings.) Specifies the default key/salt combinations of principals for this realm. Any principals created through \fIkadmin(1)\fP will have keys of these types. The default value for this tag is \fBaes256\-cts\-hmac\-sha1\-96:normal aes128\-cts\-hmac\-sha1\-96:normal des3\-cbc\-sha1:normal arcfour\-hmac\-md5:normal\fP\&. For lists of possible values, see \fI\%Keysalt lists\fP\&. .UNINDENT .SS [dbdefaults] .sp The [dbdefaults] section specifies default values for some database parameters, to be used if the [dbmodules] subsection does not contain a relation for the tag. See the \fI\%[dbmodules]\fP section for the definitions of these relations. .INDENT 0.0 .IP \(bu 2 \fBldap_kerberos_container_dn\fP .IP \(bu 2 \fBldap_kdc_dn\fP .IP \(bu 2 \fBldap_kdc_sasl_authcid\fP .IP \(bu 2 \fBldap_kdc_sasl_authzid\fP .IP \(bu 2 \fBldap_kdc_sasl_mech\fP .IP \(bu 2 \fBldap_kdc_sasl_realm\fP .IP \(bu 2 \fBldap_kadmind_dn\fP .IP \(bu 2 \fBldap_kadmind_sasl_authcid\fP .IP \(bu 2 \fBldap_kadmind_sasl_authzid\fP .IP \(bu 2 \fBldap_kadmind_sasl_mech\fP .IP \(bu 2 \fBldap_kadmind_sasl_realm\fP .IP \(bu 2 \fBldap_service_password_file\fP .IP \(bu 2 \fBldap_servers\fP .IP \(bu 2 \fBldap_conns_per_server\fP .UNINDENT .SS [dbmodules] .sp The [dbmodules] section contains parameters used by the KDC database library and database modules. Each tag in the [dbmodules] section is the name of a Kerberos realm or a section name specified by a realm\(aqs \fBdatabase_module\fP parameter. The following example shows how to define one database parameter for the ATHENA.MIT.EDU realm: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C [dbmodules] ATHENA.MIT.EDU = { disable_last_success = true } .ft P .fi .UNINDENT .UNINDENT .sp The following tags may be specified in a [dbmodules] subsection: .INDENT 0.0 .TP .B \fBdatabase_name\fP This DB2\-specific tag indicates the location of the database in the filesystem. The default is \fB@LOCALSTATEDIR@\fP\fB/krb5kdc\fP\fB/principal\fP\&. .TP .B \fBdb_library\fP This tag indicates the name of the loadable database module. The value should be \fBdb2\fP for the DB2 module and \fBkldap\fP for the LDAP module. .TP .B \fBdisable_last_success\fP If set to \fBtrue\fP, suppresses KDC updates to the "Last successful authentication" field of principal entries requiring preauthentication. Setting this flag may improve performance. (Principal entries which do not require preauthentication never update the "Last successful authentication" field.). First introduced in release 1.9. .TP .B \fBdisable_lockout\fP If set to \fBtrue\fP, suppresses KDC updates to the "Last failed authentication" and "Failed password attempts" fields of principal entries requiring preauthentication. Setting this flag may improve performance, but also disables account lockout. First introduced in release 1.9. .TP .B \fBldap_conns_per_server\fP This LDAP\-specific tag indicates the number of connections to be maintained per LDAP server. .TP .B \fBldap_kdc_dn\fP and \fBldap_kadmind_dn\fP These LDAP\-specific tags indicate the default DN for binding to the LDAP server. The \fIkrb5kdc(8)\fP daemon uses \fBldap_kdc_dn\fP, while the \fIkadmind(8)\fP daemon and other administrative programs use \fBldap_kadmind_dn\fP\&. The kadmind DN must have the rights to read and write the Kerberos data in the LDAP database. The KDC DN must have the same rights, unless \fBdisable_lockout\fP and \fBdisable_last_success\fP are true, in which case it only needs to have rights to read the Kerberos data. These tags are ignored if a SASL mechanism is set with \fBldap_kdc_sasl_mech\fP or \fBldap_kadmind_sasl_mech\fP\&. .TP .B \fBldap_kdc_sasl_mech\fP and \fBldap_kadmind_sasl_mech\fP These LDAP\-specific tags specify the SASL mechanism (such as \fBEXTERNAL\fP) to use when binding to the LDAP server. New in release 1.13. .TP .B \fBldap_kdc_sasl_authcid\fP and \fBldap_kadmind_sasl_authcid\fP These LDAP\-specific tags specify the SASL authentication identity to use when binding to the LDAP server. Not all SASL mechanisms require an authentication identity. If the SASL mechanism requires a secret (such as the password for \fBDIGEST\-MD5\fP), these tags also determine the name within the \fBldap_service_password_file\fP where the secret is stashed. New in release 1.13. .TP .B \fBldap_kdc_sasl_authzid\fP and \fBldap_kadmind_sasl_authzid\fP These LDAP\-specific tags specify the SASL authorization identity to use when binding to the LDAP server. In most circumstances they do not need to be specified. New in release 1.13. .TP .B \fBldap_kdc_sasl_realm\fP and \fBldap_kadmind_sasl_realm\fP These LDAP\-specific tags specify the SASL realm to use when binding to the LDAP server. In most circumstances they do not need to be set. New in release 1.13. .TP .B \fBldap_kerberos_container_dn\fP This LDAP\-specific tag indicates the DN of the container object where the realm objects will be located. .TP .B \fBldap_servers\fP This LDAP\-specific tag indicates the list of LDAP servers that the Kerberos servers can connect to. The list of LDAP servers is whitespace\-separated. The LDAP server is specified by a LDAP URI. It is recommended to use \fBldapi:\fP or \fBldaps:\fP URLs to connect to the LDAP server. .TP .B \fBldap_service_password_file\fP This LDAP\-specific tag indicates the file containing the stashed passwords (created by \fBkdb5_ldap_util stashsrvpw\fP) for the \fBldap_kdc_dn\fP and \fBldap_kadmind_dn\fP objects, or for the \fBldap_kdc_sasl_authcid\fP or \fBldap_kadmind_sasl_authcid\fP names for SASL authentication. This file must be kept secure. .TP .B \fBunlockiter\fP If set to \fBtrue\fP, this DB2\-specific tag causes iteration operations to release the database lock while processing each principal. Setting this flag to \fBtrue\fP can prevent extended blocking of KDC or kadmin operations when dumps of large databases are in progress. First introduced in release 1.13. .UNINDENT .sp The following tag may be specified directly in the [dbmodules] section to control where database modules are loaded from: .INDENT 0.0 .TP .B \fBdb_module_dir\fP This tag controls where the plugin system looks for database modules. The value should be an absolute path. .UNINDENT .SS [logging] .sp The [logging] section indicates how \fIkrb5kdc(8)\fP and \fIkadmind(8)\fP perform logging. It may contain the following relations: .INDENT 0.0 .TP .B \fBadmin_server\fP Specifies how \fIkadmind(8)\fP performs logging. .TP .B \fBkdc\fP Specifies how \fIkrb5kdc(8)\fP performs logging. .TP .B \fBdefault\fP Specifies how either daemon performs logging in the absence of relations specific to the daemon. .TP .B \fBdebug\fP (Boolean value.) Specifies whether debugging messages are included in log outputs other than SYSLOG. Debugging messages are always included in the system log output because syslog performs its own priority filtering. The default value is false. New in release 1.15. .UNINDENT .sp Logging specifications may have the following forms: .INDENT 0.0 .TP .B \fBFILE=\fP\fIfilename\fP or \fBFILE:\fP\fIfilename\fP This value causes the daemon\(aqs logging messages to go to the \fIfilename\fP\&. If the \fB=\fP form is used, the file is overwritten. If the \fB:\fP form is used, the file is appended to. .TP .B \fBSTDERR\fP This value causes the daemon\(aqs logging messages to go to its standard error stream. .TP .B \fBCONSOLE\fP This value causes the daemon\(aqs logging messages to go to the console, if the system supports it. .TP .B \fBDEVICE=\fP\fI\fP This causes the daemon\(aqs logging messages to go to the specified device. .TP .B \fBSYSLOG\fP[\fB:\fP\fIseverity\fP[\fB:\fP\fIfacility\fP]] This causes the daemon\(aqs logging messages to go to the system log. .sp The severity argument specifies the default severity of system log messages. This may be any of the following severities supported by the syslog(3) call, minus the \fBLOG_\fP prefix: \fBEMERG\fP, \fBALERT\fP, \fBCRIT\fP, \fBERR\fP, \fBWARNING\fP, \fBNOTICE\fP, \fBINFO\fP, and \fBDEBUG\fP\&. .sp The facility argument specifies the facility under which the messages are logged. This may be any of the following facilities supported by the syslog(3) call minus the LOG_ prefix: \fBKERN\fP, \fBUSER\fP, \fBMAIL\fP, \fBDAEMON\fP, \fBAUTH\fP, \fBLPR\fP, \fBNEWS\fP, \fBUUCP\fP, \fBCRON\fP, and \fBLOCAL0\fP through \fBLOCAL7\fP\&. .sp If no severity is specified, the default is \fBERR\fP\&. If no facility is specified, the default is \fBAUTH\fP\&. .UNINDENT .sp In the following example, the logging messages from the KDC will go to the console and to the system log under the facility LOG_DAEMON with default severity of LOG_INFO; and the logging messages from the administrative server will be appended to the file \fB/var/adm/kadmin.log\fP and sent to the device \fB/dev/tty04\fP\&. .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C [logging] kdc = CONSOLE kdc = SYSLOG:INFO:DAEMON admin_server = FILE:/var/adm/kadmin.log admin_server = DEVICE=/dev/tty04 .ft P .fi .UNINDENT .UNINDENT .SS [otp] .sp Each subsection of [otp] is the name of an OTP token type. The tags within the subsection define the configuration required to forward a One Time Password request to a RADIUS server. .sp For each token type, the following tags may be specified: .INDENT 0.0 .TP .B \fBserver\fP This is the server to send the RADIUS request to. It can be a hostname with optional port, an ip address with optional port, or a Unix domain socket address. The default is \fB@LOCALSTATEDIR@\fP\fB/krb5kdc\fP\fB/.socket\fP\&. .TP .B \fBsecret\fP This tag indicates a filename (which may be relative to \fB@LOCALSTATEDIR@\fP\fB/krb5kdc\fP) containing the secret used to encrypt the RADIUS packets. The secret should appear in the first line of the file by itself; leading and trailing whitespace on the line will be removed. If the value of \fBserver\fP is a Unix domain socket address, this tag is optional, and an empty secret will be used if it is not specified. Otherwise, this tag is required. .TP .B \fBtimeout\fP An integer which specifies the time in seconds during which the KDC should attempt to contact the RADIUS server. This tag is the total time across all retries and should be less than the time which an OTP value remains valid for. The default is 5 seconds. .TP .B \fBretries\fP This tag specifies the number of retries to make to the RADIUS server. The default is 3 retries (4 tries). .TP .B \fBstrip_realm\fP If this tag is \fBtrue\fP, the principal without the realm will be passed to the RADIUS server. Otherwise, the realm will be included. The default value is \fBtrue\fP\&. .TP .B \fBindicator\fP This tag specifies an authentication indicator to be included in the ticket if this token type is used to authenticate. This option may be specified multiple times. (New in release 1.14.) .UNINDENT .sp In the following example, requests are sent to a remote server via UDP: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C [otp] MyRemoteTokenType = { server = radius.mydomain.com:1812 secret = SEmfiajf42$ timeout = 15 retries = 5 strip_realm = true } .ft P .fi .UNINDENT .UNINDENT .sp An implicit default token type named \fBDEFAULT\fP is defined for when the per\-principal configuration does not specify a token type. Its configuration is shown below. You may override this token type to something applicable for your situation: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C [otp] DEFAULT = { strip_realm = false } .ft P .fi .UNINDENT .UNINDENT .SH PKINIT OPTIONS .sp \fBNOTE:\fP .INDENT 0.0 .INDENT 3.5 The following are pkinit\-specific options. These values may be specified in [kdcdefaults] as global defaults, or within a realm\-specific subsection of [realms]. Also note that a realm\-specific value over\-rides, does not add to, a generic [kdcdefaults] specification. The search order is: .UNINDENT .UNINDENT .INDENT 0.0 .IP 1. 3 realm\-specific subsection of [realms]: .INDENT 3.0 .INDENT 3.5 .sp .nf .ft C [realms] EXAMPLE.COM = { pkinit_anchors = FILE:/usr/local/example.com.crt } .ft P .fi .UNINDENT .UNINDENT .IP 2. 3 generic value in the [kdcdefaults] section: .INDENT 3.0 .INDENT 3.5 .sp .nf .ft C [kdcdefaults] pkinit_anchors = DIR:/usr/local/generic_trusted_cas/ .ft P .fi .UNINDENT .UNINDENT .UNINDENT .sp For information about the syntax of some of these options, see \fISpecifying PKINIT identity information\fP in \fIkrb5.conf(5)\fP\&. .INDENT 0.0 .TP .B \fBpkinit_anchors\fP Specifies the location of trusted anchor (root) certificates which the KDC trusts to sign client certificates. This option is required if pkinit is to be supported by the KDC. This option may be specified multiple times. .TP .B \fBpkinit_dh_min_bits\fP Specifies the minimum number of bits the KDC is willing to accept for a client\(aqs Diffie\-Hellman key. The default is 2048. .TP .B \fBpkinit_allow_upn\fP Specifies that the KDC is willing to accept client certificates with the Microsoft UserPrincipalName (UPN) Subject Alternative Name (SAN). This means the KDC accepts the binding of the UPN in the certificate to the Kerberos principal name. The default value is false. .sp Without this option, the KDC will only accept certificates with the id\-pkinit\-san as defined in \fI\%RFC 4556\fP\&. There is currently no option to disable SAN checking in the KDC. .TP .B \fBpkinit_eku_checking\fP This option specifies what Extended Key Usage (EKU) values the KDC is willing to accept in client certificates. The values recognized in the kdc.conf file are: .INDENT 7.0 .TP .B \fBkpClientAuth\fP This is the default value and specifies that client certificates must have the id\-pkinit\-KPClientAuth EKU as defined in \fI\%RFC 4556\fP\&. .TP .B \fBscLogin\fP If scLogin is specified, client certificates with the Microsoft Smart Card Login EKU (id\-ms\-kp\-sc\-logon) will be accepted. .TP .B \fBnone\fP If none is specified, then client certificates will not be checked to verify they have an acceptable EKU. The use of this option is not recommended. .UNINDENT .TP .B \fBpkinit_identity\fP Specifies the location of the KDC\(aqs X.509 identity information. This option is required if pkinit is to be supported by the KDC. .TP .B \fBpkinit_indicator\fP Specifies an authentication indicator to include in the ticket if pkinit is used to authenticate. This option may be specified multiple times. (New in release 1.14.) .TP .B \fBpkinit_pool\fP Specifies the location of intermediate certificates which may be used by the KDC to complete the trust chain between a client\(aqs certificate and a trusted anchor. This option may be specified multiple times. .TP .B \fBpkinit_revoke\fP Specifies the location of Certificate Revocation List (CRL) information to be used by the KDC when verifying the validity of client certificates. This option may be specified multiple times. .TP .B \fBpkinit_require_crl_checking\fP The default certificate verification process will always check the available revocation information to see if a certificate has been revoked. If a match is found for the certificate in a CRL, verification fails. If the certificate being verified is not listed in a CRL, or there is no CRL present for its issuing CA, and \fBpkinit_require_crl_checking\fP is false, then verification succeeds. .sp However, if \fBpkinit_require_crl_checking\fP is true and there is no CRL information available for the issuing CA, then verification fails. .sp \fBpkinit_require_crl_checking\fP should be set to true if the policy is such that up\-to\-date CRLs must be present for every CA. .UNINDENT .SH ENCRYPTION TYPES .sp Any tag in the configuration files which requires a list of encryption types can be set to some combination of the following strings. Encryption types marked as "weak" are available for compatibility but not recommended for use. .TS center; |l|l|. _ T{ des\-cbc\-crc T} T{ DES cbc mode with CRC\-32 (weak) T} _ T{ des\-cbc\-md4 T} T{ DES cbc mode with RSA\-MD4 (weak) T} _ T{ des\-cbc\-md5 T} T{ DES cbc mode with RSA\-MD5 (weak) T} _ T{ des\-cbc\-raw T} T{ DES cbc mode raw (weak) T} _ T{ des3\-cbc\-raw T} T{ Triple DES cbc mode raw (weak) T} _ T{ des3\-cbc\-sha1 des3\-hmac\-sha1 des3\-cbc\-sha1\-kd T} T{ Triple DES cbc mode with HMAC/sha1 T} _ T{ des\-hmac\-sha1 T} T{ DES with HMAC/sha1 (weak) T} _ T{ aes256\-cts\-hmac\-sha1\-96 aes256\-cts aes256\-sha1 T} T{ AES\-256 CTS mode with 96\-bit SHA\-1 HMAC T} _ T{ aes128\-cts\-hmac\-sha1\-96 aes128\-cts aes128\-sha1 T} T{ AES\-128 CTS mode with 96\-bit SHA\-1 HMAC T} _ T{ aes256\-cts\-hmac\-sha384\-192 aes256\-sha2 T} T{ AES\-256 CTS mode with 192\-bit SHA\-384 HMAC T} _ T{ aes128\-cts\-hmac\-sha256\-128 aes128\-sha2 T} T{ AES\-128 CTS mode with 128\-bit SHA\-256 HMAC T} _ T{ arcfour\-hmac rc4\-hmac arcfour\-hmac\-md5 T} T{ RC4 with HMAC/MD5 T} _ T{ arcfour\-hmac\-exp rc4\-hmac\-exp arcfour\-hmac\-md5\-exp T} T{ Exportable RC4 with HMAC/MD5 (weak) T} _ T{ camellia256\-cts\-cmac camellia256\-cts T} T{ Camellia\-256 CTS mode with CMAC T} _ T{ camellia128\-cts\-cmac camellia128\-cts T} T{ Camellia\-128 CTS mode with CMAC T} _ T{ des T} T{ The DES family: des\-cbc\-crc, des\-cbc\-md5, and des\-cbc\-md4 (weak) T} _ T{ des3 T} T{ The triple DES family: des3\-cbc\-sha1 T} _ T{ aes T} T{ The AES family: aes256\-cts\-hmac\-sha1\-96, aes128\-cts\-hmac\-sha1\-96, aes256\-cts\-hmac\-sha384\-192, and aes128\-cts\-hmac\-sha256\-128 T} _ T{ rc4 T} T{ The RC4 family: arcfour\-hmac T} _ T{ camellia T} T{ The Camellia family: camellia256\-cts\-cmac and camellia128\-cts\-cmac T} _ .TE .sp The string \fBDEFAULT\fP can be used to refer to the default set of types for the variable in question. Types or families can be removed from the current list by prefixing them with a minus sign ("\-"). Types or families can be prefixed with a plus sign ("+") for symmetry; it has the same meaning as just listing the type or family. For example, "\fBDEFAULT \-des\fP" would be the default set of encryption types with DES types removed, and "\fBdes3 DEFAULT\fP" would be the default set of encryption types with triple DES types moved to the front. .sp While \fBaes128\-cts\fP and \fBaes256\-cts\fP are supported for all Kerberos operations, they are not supported by very old versions of our GSSAPI implementation (krb5\-1.3.1 and earlier). Services running versions of krb5 without AES support must not be given keys of these encryption types in the KDC database. .sp The \fBaes128\-sha2\fP and \fBaes256\-sha2\fP encryption types are new in release 1.15. Services running versions of krb5 without support for these newer encryption types must not be given keys of these encryption types in the KDC database. .SH KEYSALT LISTS .sp Kerberos keys for users are usually derived from passwords. Kerberos commands and configuration parameters that affect generation of keys take lists of enctype\-salttype ("keysalt") pairs, known as \fIkeysalt lists\fP\&. Each keysalt pair is an enctype name followed by a salttype name, in the format \fIenc\fP:\fIsalt\fP\&. Individual keysalt list members are separated by comma (",") characters or space characters. For example: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C kadmin \-e aes256\-cts:normal,aes128\-cts:normal .ft P .fi .UNINDENT .UNINDENT .sp would start up kadmin so that by default it would generate password\-derived keys for the \fBaes256\-cts\fP and \fBaes128\-cts\fP encryption types, using a \fBnormal\fP salt. .sp To ensure that people who happen to pick the same password do not have the same key, Kerberos 5 incorporates more information into the key using something called a salt. The supported salt types are as follows: .TS center; |l|l|. _ T{ normal T} T{ default for Kerberos Version 5 T} _ T{ v4 T} T{ the only type used by Kerberos Version 4 (no salt) T} _ T{ norealm T} T{ same as the default, without using realm information T} _ T{ onlyrealm T} T{ uses only realm information as the salt T} _ T{ afs3 T} T{ AFS version 3, only used for compatibility with Kerberos 4 in AFS T} _ T{ special T} T{ generate a random salt T} _ .TE .SH SAMPLE KDC.CONF FILE .sp Here\(aqs an example of a kdc.conf file: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C [kdcdefaults] kdc_listen = 88 kdc_tcp_listen = 88 [realms] ATHENA.MIT.EDU = { kadmind_port = 749 max_life = 12h 0m 0s max_renewable_life = 7d 0h 0m 0s master_key_type = aes256\-cts\-hmac\-sha1\-96 supported_enctypes = aes256\-cts\-hmac\-sha1\-96:normal aes128\-cts\-hmac\-sha1\-96:normal database_module = openldap_ldapconf } [logging] kdc = FILE:/usr/local/var/krb5kdc/kdc.log admin_server = FILE:/usr/local/var/krb5kdc/kadmin.log [dbdefaults] ldap_kerberos_container_dn = cn=krbcontainer,dc=mit,dc=edu [dbmodules] openldap_ldapconf = { db_library = kldap disable_last_success = true ldap_kdc_dn = "cn=krbadmin,dc=mit,dc=edu" # this object needs to have read rights on # the realm container and principal subtrees ldap_kadmind_dn = "cn=krbadmin,dc=mit,dc=edu" # this object needs to have read and write rights on # the realm container and principal subtrees ldap_service_password_file = /etc/kerberos/service.keyfile ldap_servers = ldaps://kerberos.mit.edu ldap_conns_per_server = 5 } .ft P .fi .UNINDENT .UNINDENT .SH FILES .sp \fB@LOCALSTATEDIR@\fP\fB/krb5kdc\fP\fB/kdc.conf\fP .SH SEE ALSO .sp \fIkrb5.conf(5)\fP, \fIkrb5kdc(8)\fP, \fIkadm5.acl(5)\fP .SH AUTHOR MIT .SH COPYRIGHT 1985-2017, MIT .\" Generated by docutils manpage writer. . krb5-1.16/src/man/ktutil.man0000644000704600001450000000626713211554426015564 0ustar ghudsonlibuuid.\" Man page generated from reStructuredText. . .TH "KTUTIL" "1" " " "1.16" "MIT Kerberos" .SH NAME ktutil \- Kerberos keytab file maintenance utility . .nr rst2man-indent-level 0 . .de1 rstReportMargin \\$1 \\n[an-margin] level \\n[rst2man-indent-level] level margin: \\n[rst2man-indent\\n[rst2man-indent-level]] - \\n[rst2man-indent0] \\n[rst2man-indent1] \\n[rst2man-indent2] .. .de1 INDENT .\" .rstReportMargin pre: . RS \\$1 . nr rst2man-indent\\n[rst2man-indent-level] \\n[an-margin] . nr rst2man-indent-level +1 .\" .rstReportMargin post: .. .de UNINDENT . RE .\" indent \\n[an-margin] .\" old: \\n[rst2man-indent\\n[rst2man-indent-level]] .nr rst2man-indent-level -1 .\" new: \\n[rst2man-indent\\n[rst2man-indent-level]] .in \\n[rst2man-indent\\n[rst2man-indent-level]]u .. .SH SYNOPSIS .sp \fBktutil\fP .SH DESCRIPTION .sp The ktutil command invokes a command interface from which an administrator can read, write, or edit entries in a keytab or Kerberos V4 srvtab file. .SH COMMANDS .SS list .INDENT 0.0 .INDENT 3.5 \fBlist\fP .UNINDENT .UNINDENT .sp Displays the current keylist. .sp Alias: \fBl\fP .SS read_kt .INDENT 0.0 .INDENT 3.5 \fBread_kt\fP \fIkeytab\fP .UNINDENT .UNINDENT .sp Read the Kerberos V5 keytab file \fIkeytab\fP into the current keylist. .sp Alias: \fBrkt\fP .SS read_st .INDENT 0.0 .INDENT 3.5 \fBread_st\fP \fIsrvtab\fP .UNINDENT .UNINDENT .sp Read the Kerberos V4 srvtab file \fIsrvtab\fP into the current keylist. .sp Alias: \fBrst\fP .SS write_kt .INDENT 0.0 .INDENT 3.5 \fBwrite_kt\fP \fIkeytab\fP .UNINDENT .UNINDENT .sp Write the current keylist into the Kerberos V5 keytab file \fIkeytab\fP\&. .sp Alias: \fBwkt\fP .SS write_st .INDENT 0.0 .INDENT 3.5 \fBwrite_st\fP \fIsrvtab\fP .UNINDENT .UNINDENT .sp Write the current keylist into the Kerberos V4 srvtab file \fIsrvtab\fP\&. .sp Alias: \fBwst\fP .SS clear_list .INDENT 0.0 .INDENT 3.5 \fBclear_list\fP .UNINDENT .UNINDENT .sp Clear the current keylist. .sp Alias: \fBclear\fP .SS delete_entry .INDENT 0.0 .INDENT 3.5 \fBdelete_entry\fP \fIslot\fP .UNINDENT .UNINDENT .sp Delete the entry in slot number \fIslot\fP from the current keylist. .sp Alias: \fBdelent\fP .SS add_entry .INDENT 0.0 .INDENT 3.5 \fBadd_entry\fP {\fB\-key\fP|\fB\-password\fP} \fB\-p\fP \fIprincipal\fP \fB\-k\fP \fIkvno\fP \fB\-e\fP \fIenctype\fP [\fB\-s\fP \fIsalt\fP] .UNINDENT .UNINDENT .sp Add \fIprincipal\fP to keylist using key or password. .sp Alias: \fBaddent\fP .SS list_requests .INDENT 0.0 .INDENT 3.5 \fBlist_requests\fP .UNINDENT .UNINDENT .sp Displays a listing of available commands. .sp Aliases: \fBlr\fP, \fB?\fP .SS quit .INDENT 0.0 .INDENT 3.5 \fBquit\fP .UNINDENT .UNINDENT .sp Quits ktutil. .sp Aliases: \fBexit\fP, \fBq\fP .SH EXAMPLE .INDENT 0.0 .INDENT 3.5 .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C ktutil: add_entry \-password \-p alice@BLEEP.COM \-k 1 \-e aes128\-cts\-hmac\-sha1\-96 Password for alice@BLEEP.COM: ktutil: add_entry \-password \-p alice@BLEEP.COM \-k 1 \-e aes256\-cts\-hmac\-sha1\-96 Password for alice@BLEEP.COM: ktutil: write_kt keytab ktutil: .ft P .fi .UNINDENT .UNINDENT .UNINDENT .UNINDENT .SH SEE ALSO .sp \fIkadmin(1)\fP, \fIkdb5_util(8)\fP .SH AUTHOR MIT .SH COPYRIGHT 1985-2017, MIT .\" Generated by docutils manpage writer. . krb5-1.16/src/config/0000755000704600001450000000000013211554426014232 5ustar ghudsonlibuuidkrb5-1.16/src/config/win-pre.in0000644000704600001450000001456413211554426016155 0ustar ghudsonlibuuidWHAT=windows all: setup-msg outpre-dir all: all-$(WHAT) clean: clean-$(WHAT) install: install-$(WHAT) check: check-$(WHAT) all-windows: clean-windows:: install-windows: check-windows: all-windows: Makefile clean-windows:: Makefile # # Figure out the CPU # !if !defined(CPU) || "$(CPU)" == "" CPU=$(PROCESSOR_ARCHITECTURE) !endif # CPU !if "$(CPU)" == "" CPU=i386 !endif # Change x86 or X86 to i386 !if ( "$(CPU)" == "X86" ) || ( "$(CPU)" == "x86" ) CPU=i386 !endif # CPU == X86 !if ( "$(CPU)" != "i386" ) && ( "$(CPU)" != "ALPHA" ) && ( "$(CPU)" != "ALPHA64" ) && ( "$(CPU)" != "IA64" ) && ( "$(CPU)" != "AMD64" ) !error Must specify CPU environment variable ( CPU=i386, CPU=ALPHA, CPU=ALPHA64,CPU=IA64, CPU=AMD64) !endif # # End of figuring out CPU # !if "$(OS)" == "Windows_NT" DIRNUL= !else DIRNUL=\nul !endif # NOTE: ^ is an escape char for NMAKE. !ifdef NODEBUG OUTPRE_DBG=rel !else OUTPRE_DBG=dbg !endif OUTPRE1=obj OUTPRE2=$(OUTPRE1)\$(CPU) OUTPRE3=$(OUTPRE2)\$(OUTPRE_DBG) OUTPRE=$(OUTPRE3)^\ $(OUTPRE3)$(DIRNUL): -@if not exist $(OUTPRE1)$(DIRNUL) mkdir $(OUTPRE1) -@if not exist $(OUTPRE2)$(DIRNUL) mkdir $(OUTPRE2) -@if not exist $(OUTPRE3)$(DIRNUL) mkdir $(OUTPRE3) @if exist $(OUTPRE3)$(DIRNUL) echo Output going into $(OUTPRE3) @if not exist $(OUTPRE1)$(DIRNUL) echo The directory $(OUTPRE1) could not be created. @if exist $(OUTPRE1)$(DIRNUL) if not exist $(OUTPRE2)$(DIRNUL) echo The directory $(OUTPRE2) could not be created. @if exist $(OUTPRE2)$(DIRNUL) if not exist $(OUTPRE3)$(DIRNUL) echo The directory $(OUTPRE3) could not be created. clean-windows-dir: -@if exist $(OUTPRE3)$(DIRNUL) rmdir $(OUTPRE3) -@if exist $(OUTPRE2)$(DIRNUL) rmdir $(OUTPRE2) -@if exist $(OUTPRE1)$(DIRNUL) rmdir $(OUTPRE1) @if exist $(OUTPRE2)$(DIRNUL) echo The directory $(OUTPRE2) is not empty. @if not exist $(OUTPRE2)$(DIRNUL) if exist $(OUTPRE1)$(DIRNUL) echo The directory $(OUTPRE1) is not empty. # Directory syntax: # # begin absolute path ABS=^\ # begin relative path REL= # up-directory U=.. # path separator S=^\ # this is magic... should only be used for preceding a program invocation C=.^\ srcdir = . top_srcdir = $(srcdir)\$(BUILDTOP) DNS_LIB=$(BUILDTOP)\util\wshelper\$(OUTPRE)$(DLIB).lib DNS_INC=$(BUILDTOP)\windows\include !if defined(KRB5_NO_WSHELPER) DNSMSG=resolver !else DNSMSG=wshelper DNSFLAGS=-DWSHELPER=1 !endif !if !defined(DNS_INC) !message Must define DNS_INC to point to $(DNSMSG) includes dir! !error !endif !if !defined(DNS_LIB) !message Must define DNS_LIB to point to $(DNSMSG) library! !error !endif DNSLIBS=$(DNS_LIB) DNSFLAGS=-I$(DNS_INC) $(DNSFLAGS) -DKRB5_DNS_LOOKUP=1 !if defined(KRB5_USE_DNS_REALMS) DNSFLAGS=$(DNSFLAGS) -DKRB5_DNS_LOOKUP_REALM=1 !endif !if ("$(CPU)" == "i386") TIME_T_FLAGS=-D_USE_32BIT_TIME_T !endif !if defined (NODEBUG) KFWFLAGS=-DUSE_LEASH=1 !else KFWFLAGS=-DUSE_LEASH=1 -DDEBUG -D_CRTDBG_MAP_ALLOC !endif # # The name of the C compiler for the target # CC=cl PDB_OPTS=-Fd$(OUTPRE)\ -FD CPPFLAGS=-I$(top_srcdir)\include -I$(top_srcdir)\include\krb5 $(DNSFLAGS) -DWIN32_LEAN_AND_MEAN -DKRB5_DEPRECATED=1 -DKRB5_PRIVATE -D_CRT_SECURE_NO_DEPRECATE $(KFWFLAGS) $(TIME_T_FLAGS) CCOPTS=-nologo /EHsc /W3 $(PDB_OPTS) $(DLL_FILE_DEF) LOPTS=-nologo -incremental:no -manifest !if ("$(CPU)" == "IA64" ) || ("$(CPU)" == "AMD64" ) || ("$(CPU)" == "ALPHA64" ) ENTRYPOINT=_DllMainCRTStartup !else ENTRYPOINT=_DllMainCRTStartup@12 !endif CCLINKOPTION= SCLIB= DEBUGOPT=/Zi #if the compiler is vstudio 8, generate manifest !if exists("$(VCINSTALLDIR)\..\..\MICROSOFT VISUAL STUDIO 8") CCLINKOPTION = $(CCLINKOPTION) /MANIFEST _VC_MANIFEST_EMBED_EXE = if exist $*.exe.manifest mt.exe -manifest $*.exe.manifest -outputresource:$*.exe;1 _VC_MANIFEST_EMBED_DLL = if exist $*.dll.manifest mt.exe -manifest $*.dll.manifest -outputresource:$*.dll;2 !endif # /ZI gives better debug info in each object file (MSVC 6.0 or higher). # /Zi gives debug info in each object file. # /Gs Avoid stack probes (they don't seem to work anyway) # /Os optimize for space. FIXME: Do not use /Ox; it miscompiles the DES lib! # /Od disable optimization (for debugging) # /MD (Win32) thread safe, ML would be single threaded, don't build with ML # # CCOPTS was for DLL compiles # CCOPTS2 was for non-DLL compiles (EXEs, for example) # !ifdef NODEBUG !ifdef DEBUG_SYMBOL CCOPTS=$(DEBUGOPT) $(CCOPTS) LOPTS=$(LOPTS) -debug !endif CCOPTS=/Os /MD $(CCOPTS) LOPTS=$(LOPTS) !ifdef DEBUG_SYMBOL INSTALLDBGSYMS=copy !else INSTALLDBGSYMS=rem !endif !else CCOPTS=/Od $(DEBUGOPT) /MDd $(CCOPTS) LOPTS=$(LOPTS) -debug INSTALLDBGSYMS=copy !endif # XXX - NOTE: We should probably use DllMainCRTStartup DLL_LINKOPTS=$(LOPTS) -dll -entry:DllMain EXE_LINKOPTS=$(LOPTS) RM=$(BUILDTOP)\config\rm.bat LIBECHO=$(BUILDTOP)\util\windows\$(OUTPRE)libecho CP=copy/b nul:+ MV=ren LN=copy LIBCMD=lib AWK=rem RC = rc CVTRES = cvtres PERL=perl WCONFIG_EXE=$(BUILDTOP)\$(OUTPRE)wconfig.exe WCONFIG=$(WCONFIG_EXE:.exe=) $(WCONFIG_FLAGS) CLIB=$(BUILDTOP)\lib\$(OUTPRE)comerr32.lib PLIB=$(BUILDTOP)\lib\$(OUTPRE)xpprof32.lib KLIB=$(BUILDTOP)\lib\$(OUTPRE)krb5_32.lib K4LIB=$(BUILDTOP)\lib\$(OUTPRE)krb4_32.lib SLIB=$(BUILDTOP)\lib\$(OUTPRE)k5sprt32.lib GLIB=$(BUILDTOP)\lib\$(OUTPRE)gssapi32.lib DLIB=wshelp32 CCLIB=krbcc32 WLIB= !if ("$(CPU)" == "IA64" ) || ("$(CPU)" == "AMD64" ) || ("$(CPU)" == "ALPHA64" ) CLIB=$(BUILDTOP)\lib\$(OUTPRE)comerr64.lib PLIB=$(BUILDTOP)\lib\$(OUTPRE)xpprof64.lib KLIB=$(BUILDTOP)\lib\$(OUTPRE)krb5_64.lib K4LIB=$(BUILDTOP)\lib\$(OUTPRE)krb4_64.lib SLIB=$(BUILDTOP)\lib\$(OUTPRE)k5sprt64.lib GLIB=$(BUILDTOP)\lib\$(OUTPRE)gssapi64.lib DLIB=wshelp64 CCLIB=krbcc64 WLIB= !endif KRB4_INCLUDES=-I$(BUILDTOP)/include/kerberosIV COM_ERR_DEPS = $(BUILDTOP)/include/com_err.h RANLIB=rem OBJEXT=obj EXEEXT=.exe MFLAGS=$(MAKEFLAGS) !ifdef MIGNORE MAKE=-$(MAKE) !endif CRYPTO_IMPL = builtin PRNG_ALG = fortuna CFLAGS = $(CCOPTS) ALL_CFLAGS = $(DEFS) $(DEFINES) $(LOCALINCLUDES) $(CPPFLAGS) $(CFLAGS) C_RULE_STUFF=$(CC) $(ALL_CFLAGS) -Fo$(OUTPRE)\ -c C_RULE_PRINT=$(C_RULE_STUFF) C_RULE=$(C_RULE_STUFF) $< {}.rc{$(OUTPRE)}.res: $(RC) $(RCFLAGS) -fo $@ -r $< {}.c{$(OUTPRE)}.obj: @if "%DO_C_RULE_PRINT%"=="1" echo %C_RULE_PRINT% ... @set DO_C_RULE_PRINT= @$(C_RULE) {}.cxx{$(OUTPRE)}.obj: @if "%DO_C_RULE_PRINT%"=="1" echo %C_RULE_PRINT% ... @set DO_C_RULE_PRINT= @$(C_RULE) {}.cpp{$(OUTPRE)}.obj: @if "%DO_C_RULE_PRINT%"=="1" echo %C_RULE_PRINT% ... @set DO_C_RULE_PRINT= @$(C_RULE) # # End of Win32 pre-config lines (config/win-pre.in) # krb5-1.16/src/config/ren2long0000755000704600001450000000057313211554426015713 0ustar ghudsonlibuuid#!/bin/sh # # Shell script that changes names that have been truncated to 8.3 format # back to their original longer name. The awk script produces a script with # lines of the following format: # if [ -f ]; then echo ::mv ; mv ; fi # These lines then get executed in bin/sh. # find . -type f -print | gawk -f $0.awk | sh -x 2> /dev/null krb5-1.16/src/config/win-post.in0000644000704600001450000000634213211554426016347 0ustar ghudsonlibuuid# # Start of Win32 post-config lines (config/win-post.in) # setup-msg: @set C_RULE_PRINT= $(C_RULE_PRINT) @set DO_C_RULE_PRINT=1 !if defined(NO_OUTPRE) || defined(NO_OUTDIR) outpre-dir: !else outpre-dir: $(OUTPRE3)$(DIRNUL) !endif # # put all: first just in case no other rules occur here # all: # # Set the #define to indicate that we are compiling a DLL. We default to # compiling the Kerberos library # !if defined(DLL_EXP_TYPE) DLL_FILE_DEF=/D$(DLL_EXP_TYPE)_DLL_FILE !else DLL_FILE_DEF=/DKRB5_DLL_FILE !endif # Build the Makefile unless we are in the top-level #(where there is already an explicit rule). !if !defined(TOPLEVEL) Makefile: Makefile.in $(BUILDTOP)\config\win-pre.in $(BUILDTOP)\config\win-post.in $(WCONFIG) $(BUILDTOP)\config < Makefile.in > Makefile !endif # Recurse into subdirs if WINSUBDIRS or SUBDIRS is defined. Makefiles # can depend on all-recurse, clean-recurse, or check-recurse to perform # actions after recursion. !if defined(SUBDIRS) && !defined(WINSUBDIRS) WINSUBDIRS=$(SUBDIRS) !endif !ifdef WINSUBDIRS all-recurse: @for %d in ($(WINSUBDIRS)) do @(echo Making in $(mydir)\%d && \ pushd %d && $(MAKE) -$(MFLAGS) && popd) || exit 1 @echo Making in $(mydir) all-windows: all-recurse clean-recurse: @for %d in ($(WINSUBDIRS)) do @(echo Making clean in $(mydir)\%d && \ pushd %d && $(MAKE) -$(MFLAGS) clean && popd) || exit 1 @echo Making clean in $(mydir) clean-windows:: clean-recurse check-recurse: @for %d in ($(WINSUBDIRS)) do @(echo Making check in $(mydir)\%d && \ pushd %d && $(MAKE) -$(MFLAGS) check && popd) || exit 1 @echo Making check in $(mydir) check-windows: check-recurse !endif # WINSUBDIRS # Use 64-bit LIBNAME and OBJFILE on 64-bit platforms, if defined. !if ("$(CPU)" == "IA64") || ("$(CPU)" == "AMD64") || ("$(CPU)" == "ALPHA64") !if defined(WIN64LIBNAME) LIBNAME=$(WIN64LIBNAME) !endif !if defined(WIN64OBJFILE) OBJFILE=$(WIN64OBJFILE) !endif !endif # Build a library if LIBNAME is defined. !if defined(LIBNAME) !if !defined(OBJFILELIST) OBJFILELIST=@$(OBJFILE) !endif !if !defined(OBJFILEDEP) OBJFILEDEP=$(OBJFILE) !endif all-windows: $(LIBNAME) $(LIBNAME): $(OBJFILEDEP) $(LIBCMD) /out:$(LIBNAME) /nologo $(OBJFILELIST) !endif # LIBNAME # Build an object file list if OBJFILE is defined. !if defined(OBJFILE) all-windows: $(OBJFILE) !if defined(LIBOBJS) $(OBJFILE): $(LIBOBJS) if exist $(OBJFILE) del $(OBJFILE) !if defined(PREFIXDIR) $(LIBECHO) -p $(PREFIXDIR)\ $** > $(OBJFILE) !else $(LIBECHO) $** > $(OBJFILE) !endif # !PREFIXDIR !endif # LIBOBJS !endif # OBJFILE check: check-windows: clean-windows:: clean-windows-files clean-windows-dir # This needs to be in the post because we need RM to be defined in terms # of BUILDTOP clean-windows-files: !if "$(OUTPRE3)" == "" !error ASSERTION FAILURE: OUTPRE3 must be defined!!! !endif !if "$(OS)" == "Windows_NT" @if exist $(OUTPRE3)$(DIRNUL) rd /s/q $(OUTPRE3) !else @if exist $(OUTPRE3)$(DIRNUL) deltree /y $(OUTPRE3) !endif !if 0 $(RM) .\$(OUTPRE)*.obj .\$(OUTPRE)*.res $(RM) .\$(OUTPRE)*.exe .\$(OUTPRE)*.dll $(RM) .\$(OUTPRE)*.lib .\$(OUTPRE)*.pdb $(RM) .\$(OUTPRE)*.exp .\$(OUTPRE)*.map $(RM) .\$(OUTPRE)*.idb .\$(OUTPRE)*.ilk $(RM) .\$(OUTPRE)*.manifest !endif # Dependencies !if exist($(srcdir)/deps) !include $(srcdir)/deps !endif krb5-1.16/src/config/libobj.in0000644000704600001450000000166513211554426016033 0ustar ghudsonlibuuid### config/libobj.in # # Makefile fragment that builds object files for libraries. # # The following variables must be set in Makefile.in: # # STLIBOBJS list of .o objects; this must not contain variable # references. .SUFFIXES: .c .so .po .c.so: $(CC) $(PICFLAGS) -DSHARED $(ALL_CFLAGS) -c $< -o $*.so.o && $(MV) $*.so.o $*.so .c.po: $(CC) $(PROFFLAGS) $(ALL_CFLAGS) -c $< -o $*.po.o && $(MV) $*.po.o $*.po # rules to generate object file lists OBJS.ST: $(STLIBOBJS) Makefile @echo $(STLIBOBJS) > $@ : updated $@ OBJS.SH: $(SHLIBOBJS) Makefile @echo $(SHLIBOBJS) > $@ : updated $@ OBJS.PF: $(PFLIBOBJS) Makefile @echo $(PFLIBOBJS) > $@ : updated $@ all-libobjs: $(OBJLISTS) clean-libobjs: $(RM) OBJS.ST OBJS.SH OBJS.PF $(STLIBOBJS) $(SHLIBOBJS) $(PFLIBOBJS) Makefile: $(top_srcdir)/config/libobj.in config.status: $(top_srcdir)/config/shlib.conf # clean-unix:: clean-libobjs # all-unix: all-libobjs ### ### end config/libobj.in krb5-1.16/src/config/mkinstalldirs0000755000704600001450000000123713211554426017043 0ustar ghudsonlibuuid#! /bin/sh # mkinstalldirs --- make directory hierarchy # Author: Noah Friedman # Created: 1993-05-16 # Public domain # $Id$ errstatus=0 for file do set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'` shift pathcomp= for d do pathcomp="$pathcomp$d" case "$pathcomp" in -* ) pathcomp=./$pathcomp ;; esac if test ! -d "$pathcomp"; then echo "mkdir $pathcomp" mkdir "$pathcomp" || lasterr=$? if test ! -d "$pathcomp"; then errstatus=$lasterr fi fi pathcomp="$pathcomp/" done done exit $errstatus # mkinstalldirs ends here krb5-1.16/src/config/lib.in0000644000704600001450000001343113211554426015332 0ustar ghudsonlibuuid### config/lib.in # *** keep this in sync with libnover.in # # Makefile fragment that creates static, shared, and profiled libraries. # # The following variables must be set in the Makefile.in: # # LIBBASE library name without "lib" or extension # LIBMAJOR library major version # LIBMINOR library minor version # SHLIB_EXPDEPS list of libraries that this one has explicit # dependencies on, pref. in the form libfoo$(SHLIBEXT) # SHLIB_EXPLIBS list of libraries that this one has explicit # dependencies on, in "-lfoo" form. # RELDIR path to this directory relative to $(TOPLIBD) # # Makefile.in can also override the defaults for SHLIB_DIRS, # SHLIB_RDIRS, and STOBJLISTS from pre.in. LIBPREFIX=lib SHOBJLISTS=$(STOBJLISTS:.ST=.SH) PFOBJLISTS=$(STOBJLISTS:.ST=.PF) dummy-target-1 $(SUBDIROBJLISTS) $(SUBDIROBJLISTS:.ST=.SH) $(SUBDIROBJLISTS:.ST=.PF): all-recurse # Gets invoked as $(PARSE_OBJLISTS) list-of-OBJS.*-files PARSE_OBJLISTS= set -x && $(PERL) -p -e 'BEGIN { $$SIG{__WARN__} = sub {die @_} }; $$e=$$ARGV; $$e =~ s/OBJS\...$$//; s/^/ /; s/ $$//; s/ / $$e/g;' lib$(LIBBASE)$(STLIBEXT): $(STOBJLISTS) $(RM) $@ @echo "building static $(LIBBASE) library" set -x; objlist=`$(PARSE_OBJLISTS) $(STOBJLISTS)` && $(AR) cq $@ $$objlist $(RANLIB) $@ lib$(LIBBASE)$(SHLIBVEXT): $(SHOBJLISTS) $(SHLIB_EXPDEPS) $(SHLIB_EXPORT_FILE_DEP) $(RM) $@ @echo "building shared $(LIBBASE) library ($(LIBMAJOR).$(LIBMINOR))" set -x; objlist=`$(PARSE_OBJLISTS) $(SHOBJLISTS)` && $(MAKE_SHLIB_COMMAND) lib$(LIBBASE)$(SHLIBSEXT): lib$(LIBBASE)$(SHLIBVEXT) $(RM) $@ $(LN_S) lib$(LIBBASE)$(SHLIBVEXT) $@ lib$(LIBBASE)$(SHLIBEXT): lib$(LIBBASE)$(SHLIBVEXT) $(RM) $@ $(LN_S) lib$(LIBBASE)$(SHLIBVEXT) $@ binutils.versions: $(SHLIB_EXPORT_FILE) Makefile base=`echo "$(LIBBASE)" | sed -e 's/-/_/'`; \ echo > binutils.versions "$${base}_$(LIBMAJOR)_MIT {" sed >> binutils.versions < $(SHLIB_EXPORT_FILE) "s/$$/;/" echo >> binutils.versions "};" echo >> binutils.versions "HIDDEN { local: __*; _rest*; _save*; *; };" darwin.exports: $(SHLIB_EXPORT_FILE) Makefile sed > darwin-exports.tmp < $(SHLIB_EXPORT_FILE) "s/^/_/" $(MV) darwin-exports.tmp darwin.exports osf1.exports: $(SHLIB_EXPORT_FILE) Makefile $(RM) osf1.tmp osf1.exports sed "s/^/-exported_symbol /" < $(SHLIB_EXPORT_FILE) > osf1.tmp for f in . $(LIBINITFUNC); do \ if test "$$f" != "." ; then \ echo " -init $$f"__auxinit >> osf1.tmp; \ else :; fi; \ done a=""; \ for f in . $(LIBFINIFUNC); do \ if test "$$f" != "." ; then \ a="-fini $$f $$a"; \ else :; fi; \ done; echo " $$a" >> osf1.tmp mv -f osf1.tmp osf1.exports hpux.exports: $(SHLIB_EXPORT_FILE) Makefile $(RM) hpux.tmp hpux.exports sed "s/^/+e /" < $(SHLIB_EXPORT_FILE) > hpux.tmp a=""; \ for f in . $(LIBFINIFUNC); do \ if test "$$f" != .; then \ a="+I $${f}__auxfini $$a"; \ else :; fi; \ done; echo "$$a" >> hpux.tmp echo "+e errno" >> hpux.tmp base=`echo "$(LIBBASE)" | sed -e 's/-/_/'`; \ echo "+e _GLOBAL__FD_lib$${base}_$(LIBMAJOR)_$(LIBMINOR)" >> hpux.tmp; \ echo "+e _GLOBAL__FI_lib$${base}_$(LIBMAJOR)_$(LIBMINOR)" >> hpux.tmp mv -f hpux.tmp hpux.exports lib$(LIBBASE)$(PFLIBEXT): $(PFOBJLISTS) $(RM) $@ @echo "building profiled $(LIBBASE) library" set -x; objlist=`$(PARSE_OBJLISTS) $(PFOBJLISTS)` && $(AR) cq $@ $$objlist $(RANLIB) $@ $(TOPLIBD)/lib$(LIBBASE)$(STLIBEXT): lib$(LIBBASE)$(STLIBEXT) $(RM) $@ (cd $(TOPLIBD) && $(LN_S) $(RELDIR)/lib$(LIBBASE)$(STLIBEXT) .) $(TOPLIBD)/lib$(LIBBASE)$(SHLIBEXT): lib$(LIBBASE)$(SHLIBEXT) $(RM) $@ (cd $(TOPLIBD) && \ $(LN_S) lib$(LIBBASE)$(SHLIBVEXT) lib$(LIBBASE)$(SHLIBEXT)) $(TOPLIBD)/lib$(LIBBASE)$(SHLIBSEXT): lib$(LIBBASE)$(SHLIBSEXT) $(RM) $@ (cd $(TOPLIBD) && \ $(LN_S) lib$(LIBBASE)$(SHLIBVEXT) lib$(LIBBASE)$(SHLIBSEXT)) $(TOPLIBD)/lib$(LIBBASE)$(SHLIBVEXT): lib$(LIBBASE)$(SHLIBVEXT) $(RM) $@ (cd $(TOPLIBD) && $(LN_S) $(RELDIR)/lib$(LIBBASE)$(SHLIBVEXT) .) $(TOPLIBD)/lib$(LIBBASE)$(PFLIBEXT): lib$(LIBBASE)$(PFLIBEXT) $(RM) $@ (cd $(TOPLIBD) && $(LN_S) $(RELDIR)/lib$(LIBBASE)$(PFLIBEXT) .) all-libs: $(LIBLIST) all-liblinks: $(LIBLINKS) clean-libs: $(RM) lib$(LIBBASE)$(STLIBEXT) $(RM) lib$(LIBBASE)$(SHLIBVEXT) $(RM) lib$(LIBBASE)$(SHLIBSEXT) $(RM) lib$(LIBBASE)$(SHLIBEXT) $(RM) lib$(LIBBASE)$(PFLIBEXT) $(RM) binutils.versions osf1.exports darwin.exports hpux.exports clean-liblinks: $(RM) $(TOPLIBD)/lib$(LIBBASE)$(STLIBEXT) $(RM) $(TOPLIBD)/lib$(LIBBASE)$(SHLIBVEXT) $(RM) $(TOPLIBD)/lib$(LIBBASE)$(SHLIBSEXT) $(RM) $(TOPLIBD)/lib$(LIBBASE)$(SHLIBEXT) $(RM) $(TOPLIBD)/lib$(LIBBASE)$(PFLIBEXT) install-libs: $(LIBINSTLIST) install-static: $(RM) $(DESTDIR)$(KRB5_LIBDIR)/lib$(LIBBASE)$(STLIBEXT) $(INSTALL_DATA) lib$(LIBBASE)$(STLIBEXT) $(DESTDIR)$(KRB5_LIBDIR) $(RANLIB) $(DESTDIR)$(KRB5_LIBDIR)/lib$(LIBBASE)$(STLIBEXT) install-shared: $(RM) $(DESTDIR)$(KRB5_LIBDIR)/lib$(LIBBASE)$(SHLIBVEXT) $(RM) $(DESTDIR)$(KRB5_LIBDIR)/lib$(LIBBASE)$(SHLIBEXT) $(INSTALL_SHLIB) lib$(LIBBASE)$(SHLIBVEXT) $(DESTDIR)$(KRB5_LIBDIR) (cd $(DESTDIR)$(KRB5_LIBDIR) && $(LN_S) lib$(LIBBASE)$(SHLIBVEXT) \ lib$(LIBBASE)$(SHLIBEXT)) install-shlib-soname: install-shared $(RM) $(DESTDIR)$(KRB5_LIBDIR)/lib$(LIBBASE)$(SHLIBSEXT) (cd $(DESTDIR)$(KRB5_LIBDIR) && $(LN_S) lib$(LIBBASE)$(SHLIBVEXT) \ lib$(LIBBASE)$(SHLIBSEXT)) install-profiled: $(RM) $(DESTDIR)$(KRB5_LIBDIR)/lib$(LIBBASE)$(PFLIBEXT) $(INSTALL_DATA) lib$(LIBBASE)$(PFLIBEXT) $(DESTDIR)$(KRB5_LIBDIR) $(RANLIB) $(DESTDIR)$(KRB5_LIBDIR)/lib$(LIBBASE)$(PFLIBEXT) Makefile: $(top_srcdir)/config/lib.in $(BUILDTOP)/config.status: $(top_srcdir)/config/shlib.conf # Use the following if links need to be made to $(TOPLIBD): # all-unix: all-liblinks # install-unix: install-libs # clean-unix:: clean-liblinks clean-libs # Use the following if links need not be made: # all-unix: all-libs # install-unix: install-libs # clean-unix:: clean-libs ### ### end config/lib.in krb5-1.16/src/config/config.guess0000755000704600001450000012544713211554426016567 0ustar ghudsonlibuuid#! /bin/sh # Attempt to guess a canonical system name. # Copyright 1992-2017 Free Software Foundation, Inc. timestamp='2017-11-07' # This file is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # 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. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, see . # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that # program. This Exception is an additional permission under section 7 # of the GNU General Public License, version 3 ("GPLv3"). # # Originally written by Per Bothner; maintained since 2000 by Ben Elliston. # # You can get the latest version of this script from: # https://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess # # Please send patches to . me=`echo "$0" | sed -e 's,.*/,,'` usage="\ Usage: $0 [OPTION] Output the configuration name of the system \`$me' is run on. Options: -h, --help print this help, then exit -t, --time-stamp print date of last modification, then exit -v, --version print version number, then exit Report bugs and patches to ." version="\ GNU config.guess ($timestamp) Originally written by Per Bothner. Copyright 1992-2017 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." help=" Try \`$me --help' for more information." # Parse command line while test $# -gt 0 ; do case $1 in --time-stamp | --time* | -t ) echo "$timestamp" ; exit ;; --version | -v ) echo "$version" ; exit ;; --help | --h* | -h ) echo "$usage"; exit ;; -- ) # Stop option processing shift; break ;; - ) # Use stdin as input. break ;; -* ) echo "$me: invalid option $1$help" >&2 exit 1 ;; * ) break ;; esac done if test $# != 0; then echo "$me: too many arguments$help" >&2 exit 1 fi trap 'exit 1' 1 2 15 # CC_FOR_BUILD -- compiler used by this script. Note that the use of a # compiler to aid in system detection is discouraged as it requires # temporary files to be created and, as you can see below, it is a # headache to deal with in a portable fashion. # Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still # use `HOST_CC' if defined, but it is deprecated. # Portable tmp directory creation inspired by the Autoconf team. set_cc_for_build=' trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ; trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ; : ${TMPDIR=/tmp} ; { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } || { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } || { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ; dummy=$tmp/dummy ; tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ; case $CC_FOR_BUILD,$HOST_CC,$CC in ,,) echo "int x;" > $dummy.c ; for c in cc gcc c89 c99 ; do if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then CC_FOR_BUILD="$c"; break ; fi ; done ; if test x"$CC_FOR_BUILD" = x ; then CC_FOR_BUILD=no_compiler_found ; fi ;; ,,*) CC_FOR_BUILD=$CC ;; ,*,*) CC_FOR_BUILD=$HOST_CC ;; esac ; set_cc_for_build= ;' # This is needed to find uname on a Pyramid OSx when run in the BSD universe. # (ghazi@noc.rutgers.edu 1994-08-24) if (test -f /.attbin/uname) >/dev/null 2>&1 ; then PATH=$PATH:/.attbin ; export PATH fi UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown case "${UNAME_SYSTEM}" in Linux|GNU|GNU/*) # If the system lacks a compiler, then just pick glibc. # We could probably try harder. LIBC=gnu eval $set_cc_for_build cat <<-EOF > $dummy.c #include #if defined(__UCLIBC__) LIBC=uclibc #elif defined(__dietlibc__) LIBC=dietlibc #else LIBC=gnu #endif EOF eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC' | sed 's, ,,g'` ;; esac # Note: order is significant - the case branches are not exclusive. case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in *:NetBSD:*:*) # NetBSD (nbsd) targets should (where applicable) match one or # more of the tuples: *-*-netbsdelf*, *-*-netbsdaout*, # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently # switched to ELF, *-*-netbsd* would select the old # object file format. This provides both forward # compatibility and a consistent mechanism for selecting the # object file format. # # Note: NetBSD doesn't particularly care about the vendor # portion of the name. We always set it to "unknown". sysctl="sysctl -n hw.machine_arch" UNAME_MACHINE_ARCH=`(uname -p 2>/dev/null || \ /sbin/$sysctl 2>/dev/null || \ /usr/sbin/$sysctl 2>/dev/null || \ echo unknown)` case "${UNAME_MACHINE_ARCH}" in armeb) machine=armeb-unknown ;; arm*) machine=arm-unknown ;; sh3el) machine=shl-unknown ;; sh3eb) machine=sh-unknown ;; sh5el) machine=sh5le-unknown ;; earmv*) arch=`echo ${UNAME_MACHINE_ARCH} | sed -e 's,^e\(armv[0-9]\).*$,\1,'` endian=`echo ${UNAME_MACHINE_ARCH} | sed -ne 's,^.*\(eb\)$,\1,p'` machine=${arch}${endian}-unknown ;; *) machine=${UNAME_MACHINE_ARCH}-unknown ;; esac # The Operating System including object format, if it has switched # to ELF recently (or will in the future) and ABI. case "${UNAME_MACHINE_ARCH}" in earm*) os=netbsdelf ;; arm*|i386|m68k|ns32k|sh3*|sparc|vax) eval $set_cc_for_build if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ELF__ then # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). # Return netbsd for either. FIX? os=netbsd else os=netbsdelf fi ;; *) os=netbsd ;; esac # Determine ABI tags. case "${UNAME_MACHINE_ARCH}" in earm*) expr='s/^earmv[0-9]/-eabi/;s/eb$//' abi=`echo ${UNAME_MACHINE_ARCH} | sed -e "$expr"` ;; esac # The OS release # Debian GNU/NetBSD machines have a different userland, and # thus, need a distinct triplet. However, they do not need # kernel version information, so it can be replaced with a # suitable tag, in the style of linux-gnu. case "${UNAME_VERSION}" in Debian*) release='-gnu' ;; *) release=`echo ${UNAME_RELEASE} | sed -e 's/[-_].*//' | cut -d. -f1,2` ;; esac # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: # contains redundant information, the shorter form: # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. echo "${machine}-${os}${release}${abi}" exit ;; *:Bitrig:*:*) UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'` echo ${UNAME_MACHINE_ARCH}-unknown-bitrig${UNAME_RELEASE} exit ;; *:OpenBSD:*:*) UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE} exit ;; *:LibertyBSD:*:*) UNAME_MACHINE_ARCH=`arch | sed 's/^.*BSD\.//'` echo ${UNAME_MACHINE_ARCH}-unknown-libertybsd${UNAME_RELEASE} exit ;; *:MidnightBSD:*:*) echo ${UNAME_MACHINE}-unknown-midnightbsd${UNAME_RELEASE} exit ;; *:ekkoBSD:*:*) echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE} exit ;; *:SolidBSD:*:*) echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE} exit ;; macppc:MirBSD:*:*) echo powerpc-unknown-mirbsd${UNAME_RELEASE} exit ;; *:MirBSD:*:*) echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE} exit ;; *:Sortix:*:*) echo ${UNAME_MACHINE}-unknown-sortix exit ;; *:Redox:*:*) echo ${UNAME_MACHINE}-unknown-redox exit ;; alpha:OSF1:*:*) case $UNAME_RELEASE in *4.0) UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` ;; *5.*) UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'` ;; esac # According to Compaq, /usr/sbin/psrinfo has been available on # OSF/1 and Tru64 systems produced since 1995. I hope that # covers most systems running today. This code pipes the CPU # types through head -n 1, so we only detect the type of CPU 0. ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1` case "$ALPHA_CPU_TYPE" in "EV4 (21064)") UNAME_MACHINE=alpha ;; "EV4.5 (21064)") UNAME_MACHINE=alpha ;; "LCA4 (21066/21068)") UNAME_MACHINE=alpha ;; "EV5 (21164)") UNAME_MACHINE=alphaev5 ;; "EV5.6 (21164A)") UNAME_MACHINE=alphaev56 ;; "EV5.6 (21164PC)") UNAME_MACHINE=alphapca56 ;; "EV5.7 (21164PC)") UNAME_MACHINE=alphapca57 ;; "EV6 (21264)") UNAME_MACHINE=alphaev6 ;; "EV6.7 (21264A)") UNAME_MACHINE=alphaev67 ;; "EV6.8CB (21264C)") UNAME_MACHINE=alphaev68 ;; "EV6.8AL (21264B)") UNAME_MACHINE=alphaev68 ;; "EV6.8CX (21264D)") UNAME_MACHINE=alphaev68 ;; "EV6.9A (21264/EV69A)") UNAME_MACHINE=alphaev69 ;; "EV7 (21364)") UNAME_MACHINE=alphaev7 ;; "EV7.9 (21364A)") UNAME_MACHINE=alphaev79 ;; esac # A Pn.n version is a patched version. # A Vn.n version is a released version. # A Tn.n version is a released field test version. # A Xn.n version is an unreleased experimental baselevel. # 1.2 uses "1.2" for uname -r. echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz` # Reset EXIT trap before exiting to avoid spurious non-zero exit code. exitcode=$? trap '' 0 exit $exitcode ;; Amiga*:UNIX_System_V:4.0:*) echo m68k-unknown-sysv4 exit ;; *:[Aa]miga[Oo][Ss]:*:*) echo ${UNAME_MACHINE}-unknown-amigaos exit ;; *:[Mm]orph[Oo][Ss]:*:*) echo ${UNAME_MACHINE}-unknown-morphos exit ;; *:OS/390:*:*) echo i370-ibm-openedition exit ;; *:z/VM:*:*) echo s390-ibm-zvmoe exit ;; *:OS400:*:*) echo powerpc-ibm-os400 exit ;; arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) echo arm-acorn-riscix${UNAME_RELEASE} exit ;; arm*:riscos:*:*|arm*:RISCOS:*:*) echo arm-unknown-riscos exit ;; SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) echo hppa1.1-hitachi-hiuxmpp exit ;; Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. if test "`(/bin/universe) 2>/dev/null`" = att ; then echo pyramid-pyramid-sysv3 else echo pyramid-pyramid-bsd fi exit ;; NILE*:*:*:dcosx) echo pyramid-pyramid-svr4 exit ;; DRS?6000:unix:4.0:6*) echo sparc-icl-nx6 exit ;; DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*) case `/usr/bin/uname -p` in sparc) echo sparc-icl-nx7; exit ;; esac ;; s390x:SunOS:*:*) echo ${UNAME_MACHINE}-ibm-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; sun4H:SunOS:5.*:*) echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*) echo i386-pc-auroraux${UNAME_RELEASE} exit ;; i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*) eval $set_cc_for_build SUN_ARCH=i386 # If there is a compiler, see if it is configured for 64-bit objects. # Note that the Sun cc does not turn __LP64__ into 1 like gcc does. # This test works for both compilers. if [ "$CC_FOR_BUILD" != no_compiler_found ]; then if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \ (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ grep IS_64BIT_ARCH >/dev/null then SUN_ARCH=x86_64 fi fi echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; sun4*:SunOS:6*:*) # According to config.sub, this is the proper way to canonicalize # SunOS6. Hard to guess exactly what SunOS6 will be like, but # it's likely to be more like Solaris than SunOS4. echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; sun4*:SunOS:*:*) case "`/usr/bin/arch -k`" in Series*|S4*) UNAME_RELEASE=`uname -v` ;; esac # Japanese Language versions have a version number like `4.1.3-JL'. echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` exit ;; sun3*:SunOS:*:*) echo m68k-sun-sunos${UNAME_RELEASE} exit ;; sun*:*:4.2BSD:*) UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` test "x${UNAME_RELEASE}" = x && UNAME_RELEASE=3 case "`/bin/arch`" in sun3) echo m68k-sun-sunos${UNAME_RELEASE} ;; sun4) echo sparc-sun-sunos${UNAME_RELEASE} ;; esac exit ;; aushp:SunOS:*:*) echo sparc-auspex-sunos${UNAME_RELEASE} exit ;; # The situation for MiNT is a little confusing. The machine name # can be virtually everything (everything which is not # "atarist" or "atariste" at least should have a processor # > m68000). The system name ranges from "MiNT" over "FreeMiNT" # to the lowercase version "mint" (or "freemint"). Finally # the system name "TOS" denotes a system which is actually not # MiNT. But MiNT is downward compatible to TOS, so this should # be no problem. atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) echo m68k-atari-mint${UNAME_RELEASE} exit ;; atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) echo m68k-atari-mint${UNAME_RELEASE} exit ;; *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) echo m68k-atari-mint${UNAME_RELEASE} exit ;; milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) echo m68k-milan-mint${UNAME_RELEASE} exit ;; hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) echo m68k-hades-mint${UNAME_RELEASE} exit ;; *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) echo m68k-unknown-mint${UNAME_RELEASE} exit ;; m68k:machten:*:*) echo m68k-apple-machten${UNAME_RELEASE} exit ;; powerpc:machten:*:*) echo powerpc-apple-machten${UNAME_RELEASE} exit ;; RISC*:Mach:*:*) echo mips-dec-mach_bsd4.3 exit ;; RISC*:ULTRIX:*:*) echo mips-dec-ultrix${UNAME_RELEASE} exit ;; VAX*:ULTRIX*:*:*) echo vax-dec-ultrix${UNAME_RELEASE} exit ;; 2020:CLIX:*:* | 2430:CLIX:*:*) echo clipper-intergraph-clix${UNAME_RELEASE} exit ;; mips:*:*:UMIPS | mips:*:*:RISCos) eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #ifdef __cplusplus #include /* for printf() prototype */ int main (int argc, char *argv[]) { #else int main (argc, argv) int argc; char *argv[]; { #endif #if defined (host_mips) && defined (MIPSEB) #if defined (SYSTYPE_SYSV) printf ("mips-mips-riscos%ssysv\\n", argv[1]); exit (0); #endif #if defined (SYSTYPE_SVR4) printf ("mips-mips-riscos%ssvr4\\n", argv[1]); exit (0); #endif #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) printf ("mips-mips-riscos%sbsd\\n", argv[1]); exit (0); #endif #endif exit (-1); } EOF $CC_FOR_BUILD -o $dummy $dummy.c && dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` && SYSTEM_NAME=`$dummy $dummyarg` && { echo "$SYSTEM_NAME"; exit; } echo mips-mips-riscos${UNAME_RELEASE} exit ;; Motorola:PowerMAX_OS:*:*) echo powerpc-motorola-powermax exit ;; Motorola:*:4.3:PL8-*) echo powerpc-harris-powermax exit ;; Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*) echo powerpc-harris-powermax exit ;; Night_Hawk:Power_UNIX:*:*) echo powerpc-harris-powerunix exit ;; m88k:CX/UX:7*:*) echo m88k-harris-cxux7 exit ;; m88k:*:4*:R4*) echo m88k-motorola-sysv4 exit ;; m88k:*:3*:R3*) echo m88k-motorola-sysv3 exit ;; AViiON:dgux:*:*) # DG/UX returns AViiON for all architectures UNAME_PROCESSOR=`/usr/bin/uname -p` if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ] then if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ [ ${TARGET_BINARY_INTERFACE}x = x ] then echo m88k-dg-dgux${UNAME_RELEASE} else echo m88k-dg-dguxbcs${UNAME_RELEASE} fi else echo i586-dg-dgux${UNAME_RELEASE} fi exit ;; M88*:DolphinOS:*:*) # DolphinOS (SVR3) echo m88k-dolphin-sysv3 exit ;; M88*:*:R3*:*) # Delta 88k system running SVR3 echo m88k-motorola-sysv3 exit ;; XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) echo m88k-tektronix-sysv3 exit ;; Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) echo m68k-tektronix-bsd exit ;; *:IRIX*:*:*) echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` exit ;; ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id exit ;; # Note that: echo "'`uname -s`'" gives 'AIX ' i*86:AIX:*:*) echo i386-ibm-aix exit ;; ia64:AIX:*:*) if [ -x /usr/bin/oslevel ] ; then IBM_REV=`/usr/bin/oslevel` else IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} fi echo ${UNAME_MACHINE}-ibm-aix${IBM_REV} exit ;; *:AIX:2:3) if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #include main() { if (!__power_pc()) exit(1); puts("powerpc-ibm-aix3.2.5"); exit(0); } EOF if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` then echo "$SYSTEM_NAME" else echo rs6000-ibm-aix3.2.5 fi elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then echo rs6000-ibm-aix3.2.4 else echo rs6000-ibm-aix3.2 fi exit ;; *:AIX:*:[4567]) IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then IBM_ARCH=rs6000 else IBM_ARCH=powerpc fi if [ -x /usr/bin/lslpp ] ; then IBM_REV=`/usr/bin/lslpp -Lqc bos.rte.libc | awk -F: '{ print $3 }' | sed s/[0-9]*$/0/` else IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} fi echo ${IBM_ARCH}-ibm-aix${IBM_REV} exit ;; *:AIX:*:*) echo rs6000-ibm-aix exit ;; ibmrt:4.4BSD:*|romp-ibm:4.4BSD:*) echo romp-ibm-bsd4.4 exit ;; ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to exit ;; # report: romp-ibm BSD 4.3 *:BOSX:*:*) echo rs6000-bull-bosx exit ;; DPX/2?00:B.O.S.:*:*) echo m68k-bull-sysv3 exit ;; 9000/[34]??:4.3bsd:1.*:*) echo m68k-hp-bsd exit ;; hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) echo m68k-hp-bsd4.4 exit ;; 9000/[34678]??:HP-UX:*:*) HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` case "${UNAME_MACHINE}" in 9000/31?) HP_ARCH=m68000 ;; 9000/[34]??) HP_ARCH=m68k ;; 9000/[678][0-9][0-9]) if [ -x /usr/bin/getconf ]; then sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` case "${sc_cpu_version}" in 523) HP_ARCH=hppa1.0 ;; # CPU_PA_RISC1_0 528) HP_ARCH=hppa1.1 ;; # CPU_PA_RISC1_1 532) # CPU_PA_RISC2_0 case "${sc_kernel_bits}" in 32) HP_ARCH=hppa2.0n ;; 64) HP_ARCH=hppa2.0w ;; '') HP_ARCH=hppa2.0 ;; # HP-UX 10.20 esac ;; esac fi if [ "${HP_ARCH}" = "" ]; then eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #define _HPUX_SOURCE #include #include int main () { #if defined(_SC_KERNEL_BITS) long bits = sysconf(_SC_KERNEL_BITS); #endif long cpu = sysconf (_SC_CPU_VERSION); switch (cpu) { case CPU_PA_RISC1_0: puts ("hppa1.0"); break; case CPU_PA_RISC1_1: puts ("hppa1.1"); break; case CPU_PA_RISC2_0: #if defined(_SC_KERNEL_BITS) switch (bits) { case 64: puts ("hppa2.0w"); break; case 32: puts ("hppa2.0n"); break; default: puts ("hppa2.0"); break; } break; #else /* !defined(_SC_KERNEL_BITS) */ puts ("hppa2.0"); break; #endif default: puts ("hppa1.0"); break; } exit (0); } EOF (CCOPTS="" $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy` test -z "$HP_ARCH" && HP_ARCH=hppa fi ;; esac if [ ${HP_ARCH} = hppa2.0w ] then eval $set_cc_for_build # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler # generating 64-bit code. GNU and HP use different nomenclature: # # $ CC_FOR_BUILD=cc ./config.guess # => hppa2.0w-hp-hpux11.23 # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess # => hppa64-hp-hpux11.23 if echo __LP64__ | (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | grep -q __LP64__ then HP_ARCH=hppa2.0w else HP_ARCH=hppa64 fi fi echo ${HP_ARCH}-hp-hpux${HPUX_REV} exit ;; ia64:HP-UX:*:*) HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` echo ia64-hp-hpux${HPUX_REV} exit ;; 3050*:HI-UX:*:*) eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #include int main () { long cpu = sysconf (_SC_CPU_VERSION); /* The order matters, because CPU_IS_HP_MC68K erroneously returns true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct results, however. */ if (CPU_IS_PA_RISC (cpu)) { switch (cpu) { case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; default: puts ("hppa-hitachi-hiuxwe2"); break; } } else if (CPU_IS_HP_MC68K (cpu)) puts ("m68k-hitachi-hiuxwe2"); else puts ("unknown-hitachi-hiuxwe2"); exit (0); } EOF $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` && { echo "$SYSTEM_NAME"; exit; } echo unknown-hitachi-hiuxwe2 exit ;; 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:*) echo hppa1.1-hp-bsd exit ;; 9000/8??:4.3bsd:*:*) echo hppa1.0-hp-bsd exit ;; *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) echo hppa1.0-hp-mpeix exit ;; hp7??:OSF1:*:* | hp8?[79]:OSF1:*:*) echo hppa1.1-hp-osf exit ;; hp8??:OSF1:*:*) echo hppa1.0-hp-osf exit ;; i*86:OSF1:*:*) if [ -x /usr/sbin/sysversion ] ; then echo ${UNAME_MACHINE}-unknown-osf1mk else echo ${UNAME_MACHINE}-unknown-osf1 fi exit ;; parisc*:Lites*:*:*) echo hppa1.1-hp-lites exit ;; C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) echo c1-convex-bsd exit ;; C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) if getsysinfo -f scalar_acc then echo c32-convex-bsd else echo c2-convex-bsd fi exit ;; C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) echo c34-convex-bsd exit ;; C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) echo c38-convex-bsd exit ;; C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) echo c4-convex-bsd exit ;; CRAY*Y-MP:*:*:*) echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; CRAY*[A-Z]90:*:*:*) echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ -e 's/\.[^.]*$/.X/' exit ;; CRAY*TS:*:*:*) echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; CRAY*T3E:*:*:*) echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; CRAY*SV1:*:*:*) echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; *:UNICOS/mp:*:*) echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) FUJITSU_PROC=`uname -m | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz` FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'` FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" exit ;; 5000:UNIX_System_V:4.*:*) FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'` FUJITSU_REL=`echo ${UNAME_RELEASE} | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/ /_/'` echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" exit ;; i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} exit ;; sparc*:BSD/OS:*:*) echo sparc-unknown-bsdi${UNAME_RELEASE} exit ;; *:BSD/OS:*:*) echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} exit ;; *:FreeBSD:*:*) UNAME_PROCESSOR=`/usr/bin/uname -p` case ${UNAME_PROCESSOR} in amd64) UNAME_PROCESSOR=x86_64 ;; i386) UNAME_PROCESSOR=i586 ;; esac echo ${UNAME_PROCESSOR}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` exit ;; i*:CYGWIN*:*) echo ${UNAME_MACHINE}-pc-cygwin exit ;; *:MINGW64*:*) echo ${UNAME_MACHINE}-pc-mingw64 exit ;; *:MINGW*:*) echo ${UNAME_MACHINE}-pc-mingw32 exit ;; *:MSYS*:*) echo ${UNAME_MACHINE}-pc-msys exit ;; i*:PW*:*) echo ${UNAME_MACHINE}-pc-pw32 exit ;; *:Interix*:*) case ${UNAME_MACHINE} in x86) echo i586-pc-interix${UNAME_RELEASE} exit ;; authenticamd | genuineintel | EM64T) echo x86_64-unknown-interix${UNAME_RELEASE} exit ;; IA64) echo ia64-unknown-interix${UNAME_RELEASE} exit ;; esac ;; i*:UWIN*:*) echo ${UNAME_MACHINE}-pc-uwin exit ;; amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*) echo x86_64-unknown-cygwin exit ;; prep*:SunOS:5.*:*) echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; *:GNU:*:*) # the GNU system echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-${LIBC}`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` exit ;; *:GNU/*:*:*) # other systems with GNU libc and userland echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr "[:upper:]" "[:lower:]"``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-${LIBC} exit ;; i*86:Minix:*:*) echo ${UNAME_MACHINE}-pc-minix exit ;; aarch64:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; aarch64_be:Linux:*:*) UNAME_MACHINE=aarch64_be echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; alpha:Linux:*:*) case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in EV5) UNAME_MACHINE=alphaev5 ;; EV56) UNAME_MACHINE=alphaev56 ;; PCA56) UNAME_MACHINE=alphapca56 ;; PCA57) UNAME_MACHINE=alphapca56 ;; EV6) UNAME_MACHINE=alphaev6 ;; EV67) UNAME_MACHINE=alphaev67 ;; EV68*) UNAME_MACHINE=alphaev68 ;; esac objdump --private-headers /bin/sh | grep -q ld.so.1 if test "$?" = 0 ; then LIBC=gnulibc1 ; fi echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; arc:Linux:*:* | arceb:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; arm*:Linux:*:*) eval $set_cc_for_build if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ARM_EABI__ then echo ${UNAME_MACHINE}-unknown-linux-${LIBC} else if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ARM_PCS_VFP then echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabi else echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabihf fi fi exit ;; avr32*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; cris:Linux:*:*) echo ${UNAME_MACHINE}-axis-linux-${LIBC} exit ;; crisv32:Linux:*:*) echo ${UNAME_MACHINE}-axis-linux-${LIBC} exit ;; e2k:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; frv:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; hexagon:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; i*86:Linux:*:*) echo ${UNAME_MACHINE}-pc-linux-${LIBC} exit ;; ia64:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; k1om:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; m32r*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; m68*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; mips:Linux:*:* | mips64:Linux:*:*) eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #undef CPU #undef ${UNAME_MACHINE} #undef ${UNAME_MACHINE}el #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) CPU=${UNAME_MACHINE}el #else #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) CPU=${UNAME_MACHINE} #else CPU= #endif #endif EOF eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'` test x"${CPU}" != x && { echo "${CPU}-unknown-linux-${LIBC}"; exit; } ;; mips64el:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; openrisc*:Linux:*:*) echo or1k-unknown-linux-${LIBC} exit ;; or32:Linux:*:* | or1k*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; padre:Linux:*:*) echo sparc-unknown-linux-${LIBC} exit ;; parisc64:Linux:*:* | hppa64:Linux:*:*) echo hppa64-unknown-linux-${LIBC} exit ;; parisc:Linux:*:* | hppa:Linux:*:*) # Look for CPU level case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in PA7*) echo hppa1.1-unknown-linux-${LIBC} ;; PA8*) echo hppa2.0-unknown-linux-${LIBC} ;; *) echo hppa-unknown-linux-${LIBC} ;; esac exit ;; ppc64:Linux:*:*) echo powerpc64-unknown-linux-${LIBC} exit ;; ppc:Linux:*:*) echo powerpc-unknown-linux-${LIBC} exit ;; ppc64le:Linux:*:*) echo powerpc64le-unknown-linux-${LIBC} exit ;; ppcle:Linux:*:*) echo powerpcle-unknown-linux-${LIBC} exit ;; riscv32:Linux:*:* | riscv64:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; s390:Linux:*:* | s390x:Linux:*:*) echo ${UNAME_MACHINE}-ibm-linux-${LIBC} exit ;; sh64*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; sh*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; sparc:Linux:*:* | sparc64:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; tile*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; vax:Linux:*:*) echo ${UNAME_MACHINE}-dec-linux-${LIBC} exit ;; x86_64:Linux:*:*) echo ${UNAME_MACHINE}-pc-linux-${LIBC} exit ;; xtensa*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; i*86:DYNIX/ptx:4*:*) # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. # earlier versions are messed up and put the nodename in both # sysname and nodename. echo i386-sequent-sysv4 exit ;; i*86:UNIX_SV:4.2MP:2.*) # Unixware is an offshoot of SVR4, but it has its own version # number series starting with 2... # I am not positive that other SVR4 systems won't match this, # I just have to hope. -- rms. # Use sysv4.2uw... so that sysv4* matches it. echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} exit ;; i*86:OS/2:*:*) # If we were able to find `uname', then EMX Unix compatibility # is probably installed. echo ${UNAME_MACHINE}-pc-os2-emx exit ;; i*86:XTS-300:*:STOP) echo ${UNAME_MACHINE}-unknown-stop exit ;; i*86:atheos:*:*) echo ${UNAME_MACHINE}-unknown-atheos exit ;; i*86:syllable:*:*) echo ${UNAME_MACHINE}-pc-syllable exit ;; i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*) echo i386-unknown-lynxos${UNAME_RELEASE} exit ;; i*86:*DOS:*:*) echo ${UNAME_MACHINE}-pc-msdosdjgpp exit ;; i*86:*:4.*:*) UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'` if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL} else echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL} fi exit ;; i*86:*:5:[678]*) # UnixWare 7.x, OpenUNIX and OpenServer 6. case `/bin/uname -X | grep "^Machine"` in *486*) UNAME_MACHINE=i486 ;; *Pentium) UNAME_MACHINE=i586 ;; *Pent*|*Celeron) UNAME_MACHINE=i686 ;; esac echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} exit ;; i*86:*:3.2:*) if test -f /usr/options/cb.name; then UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')` (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \ && UNAME_MACHINE=i586 (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \ && UNAME_MACHINE=i686 (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ && UNAME_MACHINE=i686 echo ${UNAME_MACHINE}-pc-sco$UNAME_REL else echo ${UNAME_MACHINE}-pc-sysv32 fi exit ;; pc:*:*:*) # Left here for compatibility: # uname -m prints for DJGPP always 'pc', but it prints nothing about # the processor, so we play safe by assuming i586. # Note: whatever this is, it MUST be the same as what config.sub # prints for the "djgpp" host, or else GDB configure will decide that # this is a cross-build. echo i586-pc-msdosdjgpp exit ;; Intel:Mach:3*:*) echo i386-pc-mach3 exit ;; paragon:*:*:*) echo i860-intel-osf1 exit ;; i860:*:4.*:*) # i860-SVR4 if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 else # Add other i860-SVR4 vendors below as they are discovered. echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 fi exit ;; mini*:CTIX:SYS*5:*) # "miniframe" echo m68010-convergent-sysv exit ;; mc68k:UNIX:SYSTEM5:3.51m) echo m68k-convergent-sysv exit ;; M680?0:D-NIX:5.3:*) echo m68k-diab-dnix exit ;; M68*:*:R3V[5678]*:*) test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;; 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0) OS_REL='' test -r /etc/.relid \ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && { echo i486-ncr-sysv4.3${OS_REL}; exit; } /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && { echo i486-ncr-sysv4; exit; } ;; NCR*:*:4.2:* | MPRAS*:*:4.2:*) OS_REL='.3' test -r /etc/.relid \ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && { echo i486-ncr-sysv4.3${OS_REL}; exit; } /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ && { echo i586-ncr-sysv4.3${OS_REL}; exit; } /bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \ && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) echo m68k-unknown-lynxos${UNAME_RELEASE} exit ;; mc68030:UNIX_System_V:4.*:*) echo m68k-atari-sysv4 exit ;; TSUNAMI:LynxOS:2.*:*) echo sparc-unknown-lynxos${UNAME_RELEASE} exit ;; rs6000:LynxOS:2.*:*) echo rs6000-unknown-lynxos${UNAME_RELEASE} exit ;; PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*) echo powerpc-unknown-lynxos${UNAME_RELEASE} exit ;; SM[BE]S:UNIX_SV:*:*) echo mips-dde-sysv${UNAME_RELEASE} exit ;; RM*:ReliantUNIX-*:*:*) echo mips-sni-sysv4 exit ;; RM*:SINIX-*:*:*) echo mips-sni-sysv4 exit ;; *:SINIX-*:*:*) if uname -p 2>/dev/null >/dev/null ; then UNAME_MACHINE=`(uname -p) 2>/dev/null` echo ${UNAME_MACHINE}-sni-sysv4 else echo ns32k-sni-sysv fi exit ;; PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort # says echo i586-unisys-sysv4 exit ;; *:UNIX_System_V:4*:FTX*) # From Gerald Hewes . # How about differentiating between stratus architectures? -djm echo hppa1.1-stratus-sysv4 exit ;; *:*:*:FTX*) # From seanf@swdc.stratus.com. echo i860-stratus-sysv4 exit ;; i*86:VOS:*:*) # From Paul.Green@stratus.com. echo ${UNAME_MACHINE}-stratus-vos exit ;; *:VOS:*:*) # From Paul.Green@stratus.com. echo hppa1.1-stratus-vos exit ;; mc68*:A/UX:*:*) echo m68k-apple-aux${UNAME_RELEASE} exit ;; news*:NEWS-OS:6*:*) echo mips-sony-newsos6 exit ;; R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) if [ -d /usr/nec ]; then echo mips-nec-sysv${UNAME_RELEASE} else echo mips-unknown-sysv${UNAME_RELEASE} fi exit ;; BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. echo powerpc-be-beos exit ;; BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. echo powerpc-apple-beos exit ;; BePC:BeOS:*:*) # BeOS running on Intel PC compatible. echo i586-pc-beos exit ;; BePC:Haiku:*:*) # Haiku running on Intel PC compatible. echo i586-pc-haiku exit ;; x86_64:Haiku:*:*) echo x86_64-unknown-haiku exit ;; SX-4:SUPER-UX:*:*) echo sx4-nec-superux${UNAME_RELEASE} exit ;; SX-5:SUPER-UX:*:*) echo sx5-nec-superux${UNAME_RELEASE} exit ;; SX-6:SUPER-UX:*:*) echo sx6-nec-superux${UNAME_RELEASE} exit ;; SX-7:SUPER-UX:*:*) echo sx7-nec-superux${UNAME_RELEASE} exit ;; SX-8:SUPER-UX:*:*) echo sx8-nec-superux${UNAME_RELEASE} exit ;; SX-8R:SUPER-UX:*:*) echo sx8r-nec-superux${UNAME_RELEASE} exit ;; SX-ACE:SUPER-UX:*:*) echo sxace-nec-superux${UNAME_RELEASE} exit ;; Power*:Rhapsody:*:*) echo powerpc-apple-rhapsody${UNAME_RELEASE} exit ;; *:Rhapsody:*:*) echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} exit ;; *:Darwin:*:*) UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown eval $set_cc_for_build if test "$UNAME_PROCESSOR" = unknown ; then UNAME_PROCESSOR=powerpc fi if test `echo "$UNAME_RELEASE" | sed -e 's/\..*//'` -le 10 ; then if [ "$CC_FOR_BUILD" != no_compiler_found ]; then if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \ (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ grep IS_64BIT_ARCH >/dev/null then case $UNAME_PROCESSOR in i386) UNAME_PROCESSOR=x86_64 ;; powerpc) UNAME_PROCESSOR=powerpc64 ;; esac fi # On 10.4-10.6 one might compile for PowerPC via gcc -arch ppc if (echo '#ifdef __POWERPC__'; echo IS_PPC; echo '#endif') | \ (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ grep IS_PPC >/dev/null then UNAME_PROCESSOR=powerpc fi fi elif test "$UNAME_PROCESSOR" = i386 ; then # Avoid executing cc on OS X 10.9, as it ships with a stub # that puts up a graphical alert prompting to install # developer tools. Any system running Mac OS X 10.7 or # later (Darwin 11 and later) is required to have a 64-bit # processor. This is not true of the ARM version of Darwin # that Apple uses in portable devices. UNAME_PROCESSOR=x86_64 fi echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE} exit ;; *:procnto*:*:* | *:QNX:[0123456789]*:*) UNAME_PROCESSOR=`uname -p` if test "$UNAME_PROCESSOR" = x86; then UNAME_PROCESSOR=i386 UNAME_MACHINE=pc fi echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE} exit ;; *:QNX:*:4*) echo i386-pc-qnx exit ;; NEO-*:NONSTOP_KERNEL:*:*) echo neo-tandem-nsk${UNAME_RELEASE} exit ;; NSE-*:NONSTOP_KERNEL:*:*) echo nse-tandem-nsk${UNAME_RELEASE} exit ;; NSR-*:NONSTOP_KERNEL:*:*) echo nsr-tandem-nsk${UNAME_RELEASE} exit ;; NSX-*:NONSTOP_KERNEL:*:*) echo nsx-tandem-nsk${UNAME_RELEASE} exit ;; *:NonStop-UX:*:*) echo mips-compaq-nonstopux exit ;; BS2000:POSIX*:*:*) echo bs2000-siemens-sysv exit ;; DS/*:UNIX_System_V:*:*) echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} exit ;; *:Plan9:*:*) # "uname -m" is not consistent, so use $cputype instead. 386 # is converted to i386 for consistency with other x86 # operating systems. if test "$cputype" = 386; then UNAME_MACHINE=i386 else UNAME_MACHINE="$cputype" fi echo ${UNAME_MACHINE}-unknown-plan9 exit ;; *:TOPS-10:*:*) echo pdp10-unknown-tops10 exit ;; *:TENEX:*:*) echo pdp10-unknown-tenex exit ;; KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) echo pdp10-dec-tops20 exit ;; XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) echo pdp10-xkl-tops20 exit ;; *:TOPS-20:*:*) echo pdp10-unknown-tops20 exit ;; *:ITS:*:*) echo pdp10-unknown-its exit ;; SEI:*:*:SEIUX) echo mips-sei-seiux${UNAME_RELEASE} exit ;; *:DragonFly:*:*) echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` exit ;; *:*VMS:*:*) UNAME_MACHINE=`(uname -p) 2>/dev/null` case "${UNAME_MACHINE}" in A*) echo alpha-dec-vms ; exit ;; I*) echo ia64-dec-vms ; exit ;; V*) echo vax-dec-vms ; exit ;; esac ;; *:XENIX:*:SysV) echo i386-pc-xenix exit ;; i*86:skyos:*:*) echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE} | sed -e 's/ .*$//'` exit ;; i*86:rdos:*:*) echo ${UNAME_MACHINE}-pc-rdos exit ;; i*86:AROS:*:*) echo ${UNAME_MACHINE}-pc-aros exit ;; x86_64:VMkernel:*:*) echo ${UNAME_MACHINE}-unknown-esx exit ;; amd64:Isilon\ OneFS:*:*) echo x86_64-unknown-onefs exit ;; esac echo "$0: unable to guess system type" >&2 case "${UNAME_MACHINE}:${UNAME_SYSTEM}" in mips:Linux | mips64:Linux) # If we got here on MIPS GNU/Linux, output extra information. cat >&2 <&2 </dev/null || echo unknown` uname -r = `(uname -r) 2>/dev/null || echo unknown` uname -s = `(uname -s) 2>/dev/null || echo unknown` uname -v = `(uname -v) 2>/dev/null || echo unknown` /usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` /bin/uname -X = `(/bin/uname -X) 2>/dev/null` hostinfo = `(hostinfo) 2>/dev/null` /bin/universe = `(/bin/universe) 2>/dev/null` /usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` /bin/arch = `(/bin/arch) 2>/dev/null` /usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` /usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` UNAME_MACHINE = ${UNAME_MACHINE} UNAME_RELEASE = ${UNAME_RELEASE} UNAME_SYSTEM = ${UNAME_SYSTEM} UNAME_VERSION = ${UNAME_VERSION} EOF exit 1 # Local variables: # eval: (add-hook 'write-file-functions 'time-stamp) # time-stamp-start: "timestamp='" # time-stamp-format: "%:y-%02m-%02d" # time-stamp-end: "'" # End: krb5-1.16/src/config/shlib.conf0000644000704600001450000006014413211554426016207 0ustar ghudsonlibuuid# This shell script fragment should set a bunch of variables: # # CC_LINK_STATIC: How to link a program if we're only building static # libraries for krb5 (but may use other shared libs, and there may # be a shared krb5 lib already installed that we shouldn't use). # CC_LINK_SHARED: How to link a program if we're building shared # libraries. # CXX_LINK_STATIC, CXX_LINK_SHARED: Variants for C++. # STLIBEXT: Static library extension. # SHLIBEXT: Shared library extension. # SHLIBVEXT: Shared library extension, with major version. # SHLIBSEXT: Shared library extension, with full version. # (... finish documenting these ...) # # Set up some defaults. # STLIBEXT=.a # Default to being unable to build shared libraries. SHLIBEXT=.so-nobuild SHLIBVEXT=.so.v-nobuild SHLIBSEXT=.so.s-nobuild # Most systems support profiled libraries. PFLIBEXT=_p.a # Most systems install shared libs as mode 644, etc. while hpux wants 755 INSTALL_SHLIB='$(INSTALL_DATA)' # Most systems use the same objects for shared libraries and dynamically # loadable objects. DYNOBJEXT='$(SHLIBEXT)' MAKE_DYNOBJ_COMMAND='$(MAKE_SHLIB_COMMAND)' DYNOBJ_EXPDEPS='$(SHLIB_EXPDEPS)' DYNOBJ_EXPFLAGS='$(SHLIB_EXPFLAGS)' # use_linker_init_option=no use_linker_fini_option=no STOBJEXT=.o SHOBJEXT=.so PFOBJEXT=.po # Default for systems w/o shared libraries CC_LINK_STATIC='$(CC) $(PROG_LIBPATH) $(CFLAGS) $(LDFLAGS)' CXX_LINK_STATIC='$(CXX) $(PROG_LIBPATH) $(CXXFLAGS) $(LDFLAGS)' # SHLIB_EXPORT_FILE_DEP='$(SHLIB_EXPORT_FILE)' # This will do for most platforms, and we'll substitute for # LDCOMBINE, SHLIB_EXPFLAGS, and LDCOMBINE_TAIL below. MAKE_SHLIB_COMMAND=x INIT_FINI_PREP=: # Default to static or shared libraries? default_static=no default_shared=yes # Set up architecture-specific variables. case $krb5_cv_host in alpha*-dec-osf*) SHLIBVEXT='.so.$(LIBMAJOR).$(LIBMINOR)' SHLIBSEXT='.so.$(LIBMAJOR)' SHLIBEXT=.so # Alpha OSF/1 doesn't need separate PIC objects SHOBJEXT=.o INIT_FINI_PREP=initfini= LDCOMBINE='$(CC) $(CFLAGS) $(PTHREAD_CFLAGS) -shared -Wl,-expect_unresolved -Wl,\* -Wl,-update_registry -Wl,$(BUILDTOP)/so_locations -Wl,-soname -Wl,$(LIBPREFIX)$(LIBBASE)$(SHLIBSEXT) -Wl,-hidden -Wl,-input,osf1.exports $$initfini' SHLIB_EXPORT_FILE_DEP=osf1.exports use_linker_init_option=yes use_linker_fini_option=yes EXTRA_FILES="$EXTRA_FILES export" SHLIB_RPATH_FLAGS='-rpath $(SHLIB_RDIRS)' SHLIB_EXPFLAGS='$(SHLIB_RPATH_FLAGS) $(SHLIB_DIRS) $(SHLIB_EXPLIBS)' PROFFLAGS=-pg RPATH_FLAG='-Wl,-rpath -Wl,' PROG_RPATH_FLAGS='$(RPATH_FLAG)$(PROG_RPATH)' CC_LINK_SHARED='$(CC) $(PROG_LIBPATH) $(PROG_RPATH_FLAGS) $(CFLAGS) $(PTHREAD_CFLAGS) $(LDFLAGS)' CXX_LINK_SHARED='$(CXX) $(PROG_LIBPATH) $(PROG_RPATH_FLAGS) $(CXXFLAGS) $(PTHREAD_CFLAGS) $(LDFLAGS)' if test "$ac_cv_c_compiler_gnu" = yes \ && test "$krb5_cv_prog_gnu_ld" = yes; then # Really should check for gnu ld vs system ld, too. CC_LINK_STATIC='$(CC) $(PROG_LIBPATH) $(CFLAGS) $(PTHREAD_CFLAGS) $(LDFLAGS)' else # Need -oldstyle_liblookup to avoid picking up shared libs from # other builds. OSF/1 / Tru64 ld programs look through the entire # library path for shared libs prior to looking through the # entire library path for static libs. CC_LINK_STATIC='$(CC) $(PROG_LIBPATH) -Wl,-oldstyle_liblookup $(CFLAGS) $(PTHREAD_CFLAGS) $(LDFLAGS)' fi if test "$ac_cv_cxx_compiler_gnu" = yes \ && test "$krb5_cv_prog_gnu_ld" = yes; then # Really should check for gnu ld vs system ld, too. CXX_LINK_STATIC='$(CXX) $(PROG_LIBPATH) $(CXXFLAGS) $(PTHREAD_CFLAGS) $(LDFLAGS)' else # Need -oldstyle_liblookup to avoid picking up shared libs from # other builds. OSF/1 / Tru64 ld programs look through the entire # library path for shared libs prior to looking through the # entire library path for static libs. CXX_LINK_STATIC='$(CXX) $(PROG_LIBPATH) -Wl,-oldstyle_liblookup $(CXXFLAGS) $(PTHREAD_CFLAGS) $(LDFLAGS)' fi # _RLD_ROOT hack needed to repoint "root" directory for purposes # of searching for shared libs, since RPATHs take precedence over # LD_LIBRARY_PATH. RUN_ENV='LD_LIBRARY_PATH=`echo $(PROG_LIBPATH) | sed -e "s/-L//g" -e "s/ /:/g"`$${LD_LIBRARY_PATH+:$$LD_LIBRARY_PATH} _RLD_ROOT=$${_RLD_ROOT+$$_RLD_ROOT}$${_RLD_ROOT-/}' RUN_VARS='LD_LIBRARY_PATH _RLD_ROOT' ;; # Note: "-Wl,+s" when building executables enables the use of the # SHLIB_PATH environment variable for finding shared libraries # in non-standard directories. If a non-standard search-path for # shared libraries is compiled into the executable (using # -Wl,+b,$KRB5_SHLIBDIR), then the order of "-Wl,+b,..." and "-Wl,+s" # on the commandline of the linker will determine which path # (compiled-in or SHLIB_PATH) will be searched first. # # +I initproc routine gets called at load and unload time for # shl_load calls, but appears to never be called for link-time # specified libraries. # +e sym exports symbol and supposedly prevents other symbols # from being exported, according to the man page, but the # latter bit doesn't actually seem to work # -O +dpv should display any routines eliminated as unused, but -b # apparently turns that off *-*-hpux*) INSTALL_SHLIB='$(INSTALL)' case $host_cpu in hppa*) SHLIBEXT=.sl ;; ia64*) SHLIBEXT=.so ;; esac SHLIBVEXT='.$(LIBMAJOR).$(LIBMINOR)' SHLIBSEXT='.$(LIBMAJOR)' RPATH_FLAG='-Wl,+b,' if test "$ac_cv_c_compiler_gnu" = yes; then PICFLAGS=-fPIC SHLIB_RPATH_FLAGS='-Wl,+b,$(SHLIB_RDIRS)' SHLIB_EXPFLAGS='-Wl,+s $(SHLIB_RPATH_FLAGS) $(SHLIB_DIRS) $(SHLIB_EXPLIBS)' LDCOMBINE='gcc -fPIC -shared -Wl,+h,$(LIBPREFIX)$(LIBBASE)$(SHLIBSEXT) -Wl,-c,hpux.exports' else PICFLAGS=+z SHLIB_RPATH_FLAGS='+b $(SHLIB_RDIRS)' SHLIB_EXPFLAGS='$(SHLIB_RPATH_FLAGS) $(SHLIB_DIRS) $(SHLIB_EXPLIBS)' LDCOMBINE='ld -b +h $(LIBPREFIX)$(LIBBASE)$(SHLIBSEXT) -c hpux.exports' fi MAKE_SHLIB_COMMAND="${LDCOMBINE} -o \$@ \$\$objlist \$(LDFLAGS) \$(SHLIB_EXPFLAGS) ${LDCOMBINE_TAIL}" PROG_RPATH_FLAGS='$(RPATH_FLAG)$(PROG_RPATH)' CC_LINK_SHARED='$(CC) $(PROG_LIBPATH) $(PROG_RPATH_FLAGS) $(CFLAGS) $(LDFLAGS)' CC_LINK_STATIC='$(CC) $(PROG_LIBPATH) $(CFLAGS) $(LDFLAGS)' CXX_LINK_SHARED='$(CXX) $(PROG_LIBPATH) $(PROG_RPATH_FLAGS) $(CXXFLAGS) $(LDFLAGS)' CXX_LINK_STATIC='$(CXX) $(PROG_LIBPATH) $(CXXFLAGS) $(LDFLAGS)' RUN_ENV='SHLIB_PATH=`echo $(PROG_LIBPATH) | sed -e "s/-L//g" -e "s/ /:/g"`' RUN_VARS='SHLIB_PATH' SHLIB_EXPORT_FILE_DEP=hpux.exports # Do *not* set use_linker_init_option=yes here, because in the # case where the library is specified at program link time, the # initialization function appears not to get called, only for # shl_load. But for finalization functions, the shl_load case # is the one we care about. # # Not setting use_linker_init_option here should cause compilation # failures if the user tries to disable delayed initialization. use_linker_fini_option=yes ;; mips-sgi-irix6.3) # This is a Kludge; see below SHLIBVEXT='.so.$(LIBMAJOR).$(LIBMINOR)' SHLIBSEXT='.so.$(LIBMAJOR)' SHLIBEXT=.so SHOBJEXT=.o # Kludge follows: (gcc makes n32 object files but ld expects o32, so we reeducate ld) if test "$ac_cv_c_compiler_gnu" = yes; then LDCOMBINE='ld -n32 -shared -ignore_unresolved -update_registry $(BUILDTOP)/so_locations -soname $(LIBPREFIX)$(LIBBASE)$(SHLIBSEXT)' else LDCOMBINE='ld -shared -ignore_unresolved -update_registry $(BUILDTOP)/so_locations -soname $(LIBPREFIX)$(LIBBASE)$(SHLIBSEXT)' fi SHLIB_RPATH_FLAGS='-rpath $(SHLIB_RDIRS)' SHLIB_EXPFLAGS='$(SHLIB_RPATH_FLAGS) $(SHLIB_DIRS) $(SHLIB_EXPLIBS)' # no gprof for Irix... PROFFLAGS=-p RPATH_FLAG='-Wl,-rpath -Wl,' PROG_RPATH_FLAGS='$(RPATH_FLAG)$(PROG_RPATH)' CC_LINK_SHARED='$(CC) $(PROG_LIBPATH) $(PROG_RPATH_FLAGS) $(CFLAGS) $(LDFLAGS)' CC_LINK_STATIC='$(CC) $(PROG_LIBPATH) $(CFLAGS) $(LDFLAGS)' CXX_LINK_SHARED='$(CXX) $(PROG_LIBPATH) $(PROG_RPATH_FLAGS) $(CXXFLAGS) $(LDFLAGS)' CXX_LINK_STATIC='$(CXX) $(PROG_LIBPATH) $(CXXFLAGS) $(LDFLAGS)' # This grossness is necessary due to the presence of *three* # supported ABIs on Irix, and the precedence of the rpath over # LD_LIBRARY*_PATH. Like OSF/1, _RLD*_ROOT needs to be set to # work around this lossage. # # Set the N32 and 64 variables first because the unqualified # variables affect all three and can cause the sed command to fail. # # This loop is to reduce the clutter a slight bit. add='`echo $(PROG_LIBPATH) | sed -e "s/-L//g" -e "s/ /:/g"`' RUN_ENV= for i in N32 64 ''; do RUN_ENV="${RUN_ENV+$RUN_ENV }LD_LIBRARY${i}_PATH=$add\$\${LD_LIBRARY${i}_PATH+:\$\$LD_LIBRARY${i}_PATH}" RUN_ENV="${RUN_ENV} _RLD${i}_ROOT=\$\${_RLD${i}_ROOT+\$\${_RLD${i}_ROOT}}\$\${_RLD${i}_ROOT-/}" RUN_VARS="$RUN_VARS LD_LIBRARY${i}_PATH _RLD${i}_ROOT" done ;; mips-sgi-irix*) SHLIBVEXT='.so.$(LIBMAJOR).$(LIBMINOR)' SHLIBSEXT='.so.$(LIBMAJOR)' SHLIBEXT=.so SHOBJEXT=.o if test "$ac_cv_c_compiler_gnu" = yes; then LDCOMBINE_TAIL="" INIT_FINI_PREP="initfini=" else use_linker_init_option=yes use_linker_fini_option=yes INIT_FINI_PREP='initfini=; for f in . $(LIBINITFUNC); do if test $$f = .; then :; else initfini="$$initfini -Wl,-init,$${f}__auxinit"; fi; done; for f in . $(LIBFINIFUNC); do if test $$f = .; then :; else initfini="$$initfini -Wl,-fini,$${f}"; fi; done' LDCOMBINE_TAIL='-Wl,-exports_file -Wl,$(SHLIB_EXPORT_FILE)' fi opts='-Wl,-ignore_unresolved -Wl,-update_registry -Wl,$(BUILDTOP)/so_locations' if test "$ac_cv_c_compiler_gnu" = yes \ && test "$krb5_cv_prog_gnu_ld" = yes; then opts='' fi LDCOMBINE='$(CC) -shared '$opts' -Wl,-soname -Wl,$(LIBPREFIX)$(LIBBASE)$(SHLIBSEXT) $$initfini' SHLIB_RPATH_FLAGS='-rpath $(SHLIB_RDIRS)' SHLIB_EXPFLAGS='$(SHLIB_RPATH_FLAGS) $(SHLIB_DIRS) $(SHLIB_EXPLIBS)' # no gprof for Irix... PROFFLAGS=-p RPATH_FLAG='-Wl,-rpath -Wl,' PROG_RPATH_FLAGS='$(RPATH_FLAG)$(PROG_RPATH)' CC_LINK_SHARED='$(CC) $(PROG_LIBPATH) $(PROG_RPATH_FLAGS) $(CFLAGS) $(LDFLAGS)' CC_LINK_STATIC='$(CC) $(PROG_LIBPATH) $(CFLAGS) $(LDFLAGS)' CXX_LINK_SHARED='$(CXX) $(PROG_LIBPATH) $(PROG_RPATH_FLAGS) $(CXXFLAGS) $(LDFLAGS)' CXX_LINK_STATIC='$(CXX) $(PROG_LIBPATH) $(CXXFLAGS) $(LDFLAGS)' # This grossness is necessary due to the presence of *three* # supported ABIs on Irix, and the precedence of the rpath over # LD_LIBRARY*_PATH. Like OSF/1, _RLD*_ROOT needs to be set to # work around this lossage. # # Set the N32 and 64 variables first because the unqualified # variables affect all three and can cause the sed command to fail. # # This loop is to reduce the clutter a slight bit. add='`echo $(PROG_LIBPATH) | sed -e "s/-L//g" -e "s/ /:/g"`' RUN_ENV= for i in N32 64 ''; do RUN_ENV="${RUN_ENV+$RUN_ENV }LD_LIBRARY${i}_PATH=$add\$\${LD_LIBRARY${i}_PATH+:\$\$LD_LIBRARY${i}_PATH}" RUN_ENV="${RUN_ENV} _RLD${i}_ROOT=\$\${_RLD${i}_ROOT+\$\${_RLD${i}_ROOT}}\$\${_RLD${i}_ROOT-/}" RUN_VARS="$RUN_VARS LD_LIBRARY${i}_PATH _RLD${i}_ROOT" done ;; # untested... mips-sni-sysv4) if test "$ac_cv_c_compiler_gnu" = yes; then PICFLAGS=-fpic LDCOMBINE='$(CC) -G -Wl,-h -Wl,$(LIBPREFIX)$(LIBBASE)$(SHLIBSEXT)' else PICFLAGS=-Kpic LDCOMBINE='$(CC) -G -h $(LIBPREFIX)$(LIBBASE)$(SHLIBSEXT)' fi SHLIB_RPATH_FLAGS='-R$(SHLIB_RDIRS)' SHLIB_EXPFLAGS='$(SHLIB_RPATH_FLAGS) $(SHLIB_DIRS) $(SHLIB_EXPLIBS)' SHLIBEXT=.so SHLIBVEXT='.so.$(LIBMAJOR).$(LIBMINOR)' SHLIBSEXT='.so.$(LIBMAJOR)' RPATH_FLAG=-R PROG_RPATH_FLAGS='$(RPATH_FLAG)$(PROG_RPATH)' CC_LINK_SHARED='$(CC) $(PROG_LIBPATH) $(PROG_RPATH_FLAGS) $(CFLAGS) $(LDFLAGS)' CC_LINK_STATIC='$(CC) $(PROG_LIBPATH) $(CFLAGS) $(LDFLAGS)' CXX_LINK_SHARED='$(CXX) $(PROG_LIBPATH) $(PROG_RPATH_FLAGS) $(CXXFLAGS) $(LDFLAGS)' CXX_LINK_STATIC='$(CXX) $(PROG_LIBPATH) $(CXXFLAGS) $(LDFLAGS)' RUN_ENV='LD_LIBRARY_PATH=`echo $(PROG_LIBPATH) | sed -e "s/-L//g" -e "s/ /:/g"`' RUN_VARS='LD_LIBRARY_PATH' PROFFLAGS=-pg ;; mips-*-netbsd*) PICFLAGS=-fPIC SHLIBVEXT='.so.$(LIBMAJOR).$(LIBMINOR)' SHLIBSEXT='.so.$(LIBMAJOR)' SHLIBEXT=.so LDCOMBINE='ld -shared -soname $(LIBPREFIX)$(LIBBASE)$(SHLIBSEXT)' SHLIB_RPATH_FLAGS='-R$(SHLIB_RDIRS)' SHLIB_EXPFLAGS='$(SHLIB_RPATH_FLAGS) $(SHLIB_DIRS) $(SHLIB_EXPLIBS)' RPATH_FLAG='-Wl,-rpath -Wl,' PROG_RPATH_FLAGS='$(RPATH_FLAG)$(PROG_RPATH)' CC_LINK_SHARED='$(CC) $(PROG_LIBPATH) $(PROG_RPATH_FLAGS) $(CFLAGS) $(LDFLAGS)' CC_LINK_STATIC='$(CC) $(PROG_LIBPATH) $(CFLAGS) $(LDFLAGS)' CXX_LINK_SHARED='$(CXX) $(PROG_LIBPATH) $(PROG_RPATH_FLAGS) $(CXXFLAGS) $(LDFLAGS)' CXX_LINK_STATIC='$(CXX) $(PROG_LIBPATH) $(CXXFLAGS) $(LDFLAGS)' RUN_ENV='LD_LIBRARY_PATH=`echo $(PROG_LIBPATH) | sed -e "s/-L//g" -e "s/ /:/g"`' RUN_VARS='LD_LIBRARY_PATH' PROFFLAGS=-pg ;; *-*-netbsd*) PICFLAGS=-fPIC SHLIBVEXT='.so.$(LIBMAJOR).$(LIBMINOR)' SHLIBEXT=.so LDCOMBINE='$(CC) -shared' SHLIB_RPATH_FLAGS='-R$(SHLIB_RDIRS)' SHLIB_EXPFLAGS='$(SHLIB_RPATH_FLAGS) $(SHLIB_DIRS) $(SHLIB_EXPLIBS)' RPATH_FLAG=-R PROG_RPATH_FLAGS='$(RPATH_FLAG)$(PROG_RPATH)' CC_LINK_SHARED='$(CC) $(PROG_LIBPATH) $(PROG_RPATH_FLAGS) $(CFLAGS) $(LDFLAGS)' CC_LINK_STATIC='$(CC) $(PROG_LIBPATH) $(CFLAGS) $(LDFLAGS)' CXX_LINK_SHARED='$(CXX) $(PROG_LIBPATH) $(PROG_RPATH_FLAGS) $(CXXFLAGS) $(LDFLAGS)' CXX_LINK_STATIC='$(CXX) $(PROG_LIBPATH) $(CXXFLAGS) $(LDFLAGS)' RUN_ENV='LD_LIBRARY_PATH=`echo $(PROG_LIBPATH) | sed -e "s/-L//g" -e "s/ /:/g"`' RUN_VARS='LD_LIBRARY_PATH' PROFFLAGS=-pg ;; *-*-freebsd*) case $krb5_cv_host in sparc64-*) PICFLAGS=-fPIC ;; *) PICFLAGS=-fpic ;; esac SHLIBVEXT='.so.$(LIBMAJOR)' RPATH_FLAG='-Wl,--enable-new-dtags -Wl,-rpath -Wl,' PROG_RPATH_FLAGS='$(RPATH_FLAG)$(PROG_RPATH)' CC_LINK_SHARED='$(CC) $(PROG_LIBPATH) $(PROG_RPATH_FLAGS) $(CFLAGS) $(LDFLAGS)' CXX_LINK_SHARED='$(CXX) $(PROG_LIBPATH) $(PROG_RPATH_FLAGS) $(CXXFLAGS) $(LDFLAGS)' SHLIBEXT=.so LDCOMBINE='ld -Bshareable' SHLIB_RPATH_FLAGS='--enable-new-dtags -rpath $(SHLIB_RDIRS)' SHLIB_EXPFLAGS='$(SHLIB_RPATH_FLAGS) $(SHLIB_DIRS) $(SHLIB_EXPLIBS)' CC_LINK_STATIC='$(CC) $(PROG_LIBPATH) $(CFLAGS) $(LDFLAGS)' CXX_LINK_STATIC='$(CXX) $(PROG_LIBPATH) $(CXXFLAGS) $(LDFLAGS)' RUN_ENV='LD_LIBRARY_PATH=`echo $(PROG_LIBPATH) | sed -e "s/-L//g" -e "s/ /:/g"`' RUN_VARS='LD_LIBRARY_PATH' PROFFLAGS=-pg ;; *-*-openbsd*) PICFLAGS=-fpic SHLIBVEXT='.so.$(LIBMAJOR).$(LIBMINOR)' SHLIBEXT=.so LDCOMBINE='ld -Bshareable' SHLIB_RPATH_FLAGS='-R$(SHLIB_RDIRS)' SHLIB_EXPFLAGS='$(SHLIB_RPATH_FLAGS) $(SHLIB_DIRS) $(SHLIB_EXPLIBS)' RPATH_FLAG=-R PROG_RPATH_FLAGS='$(RPATH_FLAG)$(PROG_RPATH)' CC_LINK_SHARED='$(CC) $(PROG_LIBPATH) $(PROG_RPATH_FLAGS) $(CFLAGS) $(LDFLAGS)' CC_LINK_STATIC='$(CC) $(PROG_LIBPATH) $(CFLAGS) $(LDFLAGS)' CXX_LINK_SHARED='$(CXX) $(PROG_LIBPATH) $(PROG_RPATH_FLAGS) $(CXXFLAGS) $(LDFLAGS)' CXX_LINK_STATIC='$(CXX) $(PROG_LIBPATH) $(CXXFLAGS) $(LDFLAGS)' RUN_ENV='LD_LIBRARY_PATH=`echo $(PROG_LIBPATH) | sed -e "s/-L//g" -e "s/ /:/g"`' RUN_VARS='LD_LIBRARY_PATH' PROFFLAGS=-pg ;; *-*-darwin* | *-*-rhapsody*) SHLIBVEXT='.$(LIBMAJOR).$(LIBMINOR).dylib' SHLIBSEXT='.$(LIBMAJOR).dylib' SHLIB_EXPFLAGS='$(SHLIB_DIRS) $(SHLIB_EXPLIBS)' SHLIBEXT=.dylib DYNOBJEXT=.so SHLIB_EXPORT_FILE_DEP=darwin.exports LDCOMBINE='$(CC) -undefined error -dead_strip -dynamiclib -compatibility_version $(LIBMAJOR) -current_version $(LIBMAJOR).$(LIBMINOR) -install_name "$(KRB5_LIBDIR)/$(LIBPREFIX)$(LIBBASE)$(SHLIBVEXT)" -exported_symbols_list darwin.exports $(CFLAGS)' # The -dylib_file option tells the linker where to find indirect dependent # libraries, without adding them to the dependency list. We need this because # the direct dependent libraries contain the pathname where the indirect # dependent libraries will be installed (but haven't been yet). LDCOMBINE_TAIL="" for lib in libkrb5support.1.1.dylib libkadm5srv.5.1.dylib libkdb5.4.0.dylib; do LDCOMBINE_TAIL="$LDCOMBINE_TAIL -dylib_file \"\$(KRB5_LIBDIR)/$lib\":\$(TOPLIBD)/$lib" done MAKE_DYNOBJ_COMMAND='$(CC) -bundle $(CFLAGS) $(LDFLAGS) -o $@ $$objlist $(DYNOBJ_EXPFLAGS) $(LDFLAGS) -exported_symbols_list darwin.exports'" ${LDCOMBINE_TAIL}" CC_LINK_SHARED='$(CC) $(PROG_LIBPATH) -dynamic $(CFLAGS) $(LDFLAGS)' CC_LINK_STATIC='$(CC) $(PROG_LIBPATH) $(CFLAGS) $(LDFLAGS)' CXX_LINK_SHARED='$(CXX) $(PROG_LIBPATH) -dynamic $(CXXFLAGS) $(LDFLAGS)' CXX_LINK_STATIC='$(CXX) $(PROG_LIBPATH) $(CXXFLAGS) $(LDFLAGS)' RUN_ENV='DYLD_LIBRARY_PATH=`echo $(PROG_LIBPATH) | sed -e "s/-L//g" -e "s/ /:/g"`' RUN_VARS='DYLD_LIBRARY_PATH' ;; *-*-solaris*) if test "$ac_cv_c_compiler_gnu" = yes; then PICFLAGS=-fPIC LDCOMBINE='$(CC) $(CFLAGS) -shared -h $(LIBPREFIX)$(LIBBASE)$(SHLIBSEXT)' else PICFLAGS=-KPIC # Solaris cc doesn't default to stuffing the SONAME field... LDCOMBINE='$(CC) $(CFLAGS) -dy -G -z text -h $(LIBPREFIX)$(LIBBASE)$(SHLIBSEXT) $$initfini' # case $krb5_cv_host in *-*-solaris2.[1-7] | *-*-solaris2.[1-7].*) # Did Solaris 7 and earlier have a linker option for this? ;; *) INIT_FINI_PREP='initfini=; for f in . $(LIBINITFUNC); do if test $$f = .; then :; else initfini="$$initfini -Wl,-z,initarray=$${f}__auxinit"; fi; done; for f in . $(LIBFINIFUNC); do if test $$f = .; then :; else initfini="$$initfini -Wl,-z,finiarray=$$f"; fi; done' use_linker_init_option=yes use_linker_fini_option=yes ;; esac fi SHLIBVEXT='.so.$(LIBMAJOR).$(LIBMINOR)' SHLIBSEXT='.so.$(LIBMAJOR)' SHLIBEXT=.so SHLIB_RPATH_FLAGS='-R$(SHLIB_RDIRS)' SHLIB_EXPFLAGS='$(SHLIB_RPATH_FLAGS) $(SHLIB_DIRS) $(SHLIB_EXPLIBS)' PROFFLAGS=-pg RPATH_FLAG=-R PROG_RPATH_FLAGS='$(RPATH_FLAG)$(PROG_RPATH)' CC_LINK_SHARED='$(PURE) $(CC) $(PROG_LIBPATH) $(PROG_RPATH_FLAGS) $(CFLAGS) $(LDFLAGS)' CC_LINK_STATIC='$(PURE) $(CC) $(PROG_LIBPATH) $(CFLAGS) $(LDFLAGS)' CXX_LINK_SHARED='$(PURE) $(CXX) $(PROG_LIBPATH) $(PROG_RPATH_FLAGS) $(CXXFLAGS) $(LDFLAGS)' CXX_LINK_STATIC='$(PURE) $(CXX) $(PROG_LIBPATH) $(CXXFLAGS) $(LDFLAGS)' RUN_ENV='LD_LIBRARY_PATH=`echo $(PROG_LIBPATH) | sed -e "s/-L//g" -e "s/ /:/g"`' RUN_VARS='LD_LIBRARY_PATH' ;; *-*-linux* | *-*-gnu* | *-*-k*bsd*-gnu) PICFLAGS=-fPIC SHLIBVEXT='.so.$(LIBMAJOR).$(LIBMINOR)' SHLIBSEXT='.so.$(LIBMAJOR)' SHLIBEXT=.so # Linux ld doesn't default to stuffing the SONAME field... # Use objdump -x to examine the fields of the library # UNDEF_CHECK is suppressed by --enable-asan LDCOMBINE='$(CC) -shared -fPIC -Wl,-h,$(LIBPREFIX)$(LIBBASE)$(SHLIBSEXT) $(UNDEF_CHECK)' UNDEF_CHECK='-Wl,--no-undefined' # $(EXPORT_CHECK) runs export-check.pl when in maintainer mode. LDCOMBINE_TAIL='-Wl,--version-script binutils.versions $(EXPORT_CHECK)' SHLIB_EXPORT_FILE_DEP=binutils.versions RPATH_FLAG='-Wl,--enable-new-dtags -Wl,-rpath -Wl,' # For cases where we do have dependencies on other libraries # built in this tree... SHLIB_RPATH_FLAGS='$(RPATH_FLAG)$(SHLIB_RDIRS)' SHLIB_EXPFLAGS='$(SHLIB_RPATH_FLAGS) $(SHLIB_DIRS) $(SHLIB_EXPLIBS)' PROFFLAGS=-pg PROG_RPATH_FLAGS='$(RPATH_FLAG)$(PROG_RPATH)' CC_LINK_SHARED='$(CC) $(PROG_LIBPATH) $(PROG_RPATH_FLAGS) $(CFLAGS) $(LDFLAGS)' CC_LINK_STATIC='$(CC) $(PROG_LIBPATH) $(CFLAGS) $(LDFLAGS)' CXX_LINK_SHARED='$(CXX) $(PROG_LIBPATH) $(PROG_RPATH_FLAGS) $(CXXFLAGS) $(LDFLAGS)' CXX_LINK_STATIC='$(CXX) $(PROG_LIBPATH) $(CXXFLAGS) $(LDFLAGS)' RUN_ENV='LD_LIBRARY_PATH=`echo $(PROG_LIBPATH) | sed -e "s/-L//g" -e "s/ /:/g"`' RUN_VARS='LD_LIBRARY_PATH' ## old version: # Linux libc does weird stuff at shlib link time, must be # explicitly listed here. This also makes it get used even # for the libraries marked as not having any dependencies; while # that's not strictly correct, the resulting behavior -- not adding # extra -R directories -- is still what we want. #LDCOMBINE='ld -shared -h $(LIBPREFIX)$(LIBBASE)$(SHLIBSEXT)' #LDCOMBINE_TAIL="-lc" #SHLIB_EXPFLAGS='-R$(SHLIB_RDIRS) $(SHLIB_DIRS) $(SHLIB_EXPLIBS)' ;; *-*-bsdi4*) PICFLAGS=-fpic SHLIBVEXT='.so.$(LIBMAJOR)' SHLIBEXT=.so LDCOMBINE='ld -Bshareable' SHLIB_RPATH_FLAGS='-R$(SHLIB_RDIRS)' SHLIB_EXPFLAGS='$(SHLIB_RPATH_FLAGS) $(SHLIB_DIRS) $(SHLIB_EXPLIBS)' PROG_RPATH_FLAGS='-Wl,-rpath,$(PROG_RPATH)' CC_LINK_SHARED='$(CC) $(PROG_LIBPATH) $(PROG_RPATH_FLAGS)' CC_LINK_STATIC='$(CC) $(PROG_LIBPATH)' CXX_LINK_SHARED='$(CXX) $(PROG_LIBPATH) $(PROG_RPATH_FLAGS)' CXX_LINK_STATIC='$(CXX) $(PROG_LIBPATH)' RUN_ENV='LD_LIBRARY_PATH=`echo $(PROG_LIBPATH) | sed -e "s/-L//g" -e "s/ /:/g"`' RUN_VARS='LD_LIBRARY_PATH' PROFFLAGS=-pg ;; *-*-aix5*) SHLIBVEXT='.so.$(LIBMAJOR).$(LIBMINOR)' SHLIBEXT=.so # AIX doesn't need separate PIC objects SHOBJEXT=.o SHLIB_EXPFLAGS=' $(SHLIB_DIRS) $(SHLIB_EXPLIBS)' PROFFLAGS=-pg if test "$ac_cv_c_compiler_gnu" = "yes" ; then wl_prefix=-Wl, RPATH_FLAG='-Wl,-blibpath:' LDCOMBINE='$(CC) -shared -v -o $@ $$objlist -nostartfiles -Xlinker -bgcbypass:1 -Xlinker -bfilelist -Xlinker -bM:SRE -Xlinker -bE:$(SHLIB_EXPORT_FILE) -Xlinker -bernotok -Xlinker -brtl $(SHLIB_EXPFLAGS) $(LDFLAGS) -lc $$initfini' else wl_prefix= RPATH_FLAG=-blibpath: LDCOMBINE='/bin/ld -o $@ $$objlist -H512 -T512 -bnoentry -bgcbypass:1 -bnodelcsect -bfilelist -bM:SRE -bE:$(SHLIB_EXPORT_FILE) -bernotok -brtl $(SHLIB_EXPFLAGS) $(LDFLAGS) -lc $$initfini' fi # Assume initialization always delayed. INIT_FINI_PREP="wl=${wl_prefix}; "'i=1; initfini=; for f in . $(LIBFINIFUNC); do if test $$f != .; then initfini="$$initfini $${wl}-binitfini::$$f:$$i"; else :; fi; i=`expr $$i + 1`; done' use_linker_fini_option=yes MAKE_SHLIB_COMMAND="${INIT_FINI_PREP} && ${LDCOMBINE}" RPATH_TAIL=:/usr/lib:/lib PROG_RPATH_FLAGS='$(RPATH_FLAG)$(PROG_RPATH):'"$RPATH_TAIL" CC_LINK_SHARED='$(CC) $(PROG_LIBPATH) $(PROG_RPATH_FLAGS) $(CFLAGS) $(LDFLAGS)' CC_LINK_STATIC='$(CC) $(PROG_LIBPATH) $(CFLAGS) $(LDFLAGS)' CXX_LINK_SHARED='$(CXX) $(PROG_LIBPATH) $(PROG_RPATH_FLAGS) $(CXXFLAGS) $(LDFLAGS)' CXX_LINK_STATIC='$(CXX) $(PROG_LIBPATH) $(CXXFLAGS) $(LDFLAGS)' # $(PROG_RPATH) is here to handle things like a shared tcl library RUN_ENV='LIBPATH=`echo $(PROG_LIBPATH) | sed -e "s/-L//g" -e "s/ /:/g"`:$(PROG_RPATH):/usr/lib:/usr/local/lib' RUN_VARS='LIBPATH' ;; *-*-aix4.*) SHLIBVEXT='.a.$(LIBMAJOR).$(LIBMINOR)' SHLIBEXT=.a # AIX doesn't need separate PIC objects SHOBJEXT=.o SHLIB_EXPFLAGS=' $(SHLIB_DIRS) $(SHLIB_EXPLIBS)' PROFFLAGS=-pg # Dynamically loaded object can have whatever suffix, but don't # make archives like for shared libraries. DYNOBJEXT=.so # if test "$ac_cv_c_compiler_gnu" = "yes" ; then wl_prefix=-Wl, RPATH_FLAG='-Wl,-blibpath:' LDCOMBINE='$(CC) -shared -v -o shr.o.$(LIBMAJOR).$(LIBMINOR) $$objlist -nostartfiles -Xlinker -bgcbypass:1 -Xlinker -bfilelist -Xlinker -bM:SRE -Xlinker -bE:$(SHLIB_EXPORT_FILE) -Xlinker -bernotok $(SHLIB_EXPFLAGS) $(LDFLAGS) -lc $$initfini' LDCOMBINE_DYN='$(CC) -shared -v -o $@ $$objlist -nostartfiles -Xlinker -bgcbypass:1 -Xlinker -bfilelist -Xlinker -bM:SRE -Xlinker -bE:$(SHLIB_EXPORT_FILE) -Xlinker -bernotok $(SHLIB_EXPFLAGS) $(LDFLAGS) -lc $$initfini' else wl_prefix= RPATH_FLAG=-blibpath: LDCOMBINE='/bin/ld -o shr.o.$(LIBMAJOR).$(LIBMINOR) $$objlist -H512 -T512 -bnoentry -bgcbypass:1 -bnodelcsect -bfilelist -bM:SRE -bE:$(SHLIB_EXPORT_FILE) -bernotok $(SHLIB_EXPFLAGS) $(LDFLAGS) -lc $$initfini' LDCOMBINE_DYN='/bin/ld -o $@ $$objlist -H512 -T512 -bnoentry -bgcbypass:1 -bnodelcsect -bfilelist -bM:SRE -bE:$(SHLIB_EXPORT_FILE) -bernotok $(SHLIB_EXPFLAGS) $(LDFLAGS) -lc $$initfini' fi # Assume initialization always delayed. INIT_FINI_PREP="wl=${wl_prefix}; "'i=1; initfini=; for f in . $(LIBFINIFUNC); do if test $$f != .; then initfini="$$initfini $${wl}-binitfini::$$f:$$i"; else :; fi; i=`expr $$i + 1`; done' use_linker_fini_option=yes MAKE_SHLIB_COMMAND="${INIT_FINI_PREP} && ${LDCOMBINE}"' && ar cq $@ shr.o.$(LIBMAJOR).$(LIBMINOR) && chmod +x $@ && rm -f shr.o.$(LIBMAJOR).$(LIBMINOR)' MAKE_DYNOBJ_COMMAND="${INIT_FINI_PREP} && ${LDCOMBINE_DYN}" RPATH_TAIL=:/usr/lib:/lib PROG_RPATH_FLAGS='$(RPATH_FLAG)$(PROG_RPATH):'"$RPATH_TAIL" CC_LINK_SHARED='$(CC) $(PROG_LIBPATH) $(PROG_RPATH_FLAGS) $(CFLAGS) $(LDFLAGS)' CC_LINK_STATIC='$(CC) $(PROG_LIBPATH) $(CFLAGS) $(LDFLAGS)' CXX_LINK_SHARED='$(CXX) $(PROG_LIBPATH) $(PROG_RPATH_FLAGS) $(CXXFLAGS) $(LDFLAGS)' CXX_LINK_STATIC='$(CXX) $(PROG_LIBPATH) $(CXXFLAGS) $(LDFLAGS)' # $(PROG_RPATH) is here to handle things like a shared tcl library RUN_ENV='LIBPATH=`echo $(PROG_LIBPATH) | sed -e "s/-L//g" -e "s/ /:/g"`:$(PROG_RPATH):/usr/lib:/usr/local/lib' RUN_VARS='LIBPATH' ;; esac if test "${MAKE_SHLIB_COMMAND}" = "x" ; then if test "${INIT_FINI_PREP}" != ":"; then MAKE_SHLIB_COMMAND="${INIT_FINI_PREP} && ${LDCOMBINE} -o \$@ \$\$objlist \$(SHLIB_EXPFLAGS) \$(LDFLAGS) ${LDCOMBINE_TAIL}" else MAKE_SHLIB_COMMAND="${LDCOMBINE} -o \$@ \$\$objlist \$(SHLIB_EXPFLAGS) \$(LDFLAGS) ${LDCOMBINE_TAIL}" fi fi krb5-1.16/src/config/ac-archive/0000755000704600001450000000000013211554426016234 5ustar ghudsonlibuuidkrb5-1.16/src/config/ac-archive/README0000644000704600001450000000050213211554426017111 0ustar ghudsonlibuuid-*- text -*- These macros are taken from the autoconf archive at https://www.gnu.org/software/autoconf-archive/ . They are licensed under a modified version of the GNU General Public License as noted in the comments near the top of each file. ax_pthread.m4 serial 24 2017-02-06 ax_recursive_eval.m4 serial 1 2017-01-05 krb5-1.16/src/config/ac-archive/ax_recursive_eval.m40000644000704600001450000000455013211554426022210 0ustar ghudsonlibuuid# =========================================================================== # https://www.gnu.org/software/autoconf-archive/ax_recursive_eval.html # =========================================================================== # # SYNOPSIS # # AX_RECURSIVE_EVAL(VALUE, RESULT) # # DESCRIPTION # # Interpolate the VALUE in loop until it doesn't change, and set the # result to $RESULT. WARNING: It's easy to get an infinite loop with some # unsane input. # # LICENSE # # Copyright (c) 2008 Alexandre Duret-Lutz # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; either version 2 of the License, or (at your # option) any later version. # # 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. See the GNU General # Public License for more details. # # You should have received a copy of the GNU General Public License along # with this program. If not, see . # # As a special exception, the respective Autoconf Macro's copyright owner # gives unlimited permission to copy, distribute and modify the configure # scripts that are the output of Autoconf when processing the Macro. You # need not follow the terms of the GNU General Public License when using # or distributing such scripts, even though portions of the text of the # Macro appear in them. The GNU General Public License (GPL) does govern # all other use of the material that constitutes the Autoconf Macro. # # This special exception to the GPL applies to versions of the Autoconf # Macro released by the Autoconf Archive. When you make and distribute a # modified version of the Autoconf Macro, you may extend this special # exception to the GPL to apply to your modified version as well. #serial 1 AC_DEFUN([AX_RECURSIVE_EVAL], [_lcl_receval="$1" $2=`(test "x$prefix" = xNONE && prefix="$ac_default_prefix" test "x$exec_prefix" = xNONE && exec_prefix="${prefix}" _lcl_receval_old='' while test "[$]_lcl_receval_old" != "[$]_lcl_receval"; do _lcl_receval_old="[$]_lcl_receval" eval _lcl_receval="\"[$]_lcl_receval\"" done echo "[$]_lcl_receval")`]) krb5-1.16/src/config/ac-archive/ax_pthread.m40000644000704600001450000005052213211554426020621 0ustar ghudsonlibuuid# =========================================================================== # https://www.gnu.org/software/autoconf-archive/ax_pthread.html # =========================================================================== # # SYNOPSIS # # AX_PTHREAD([ACTION-IF-FOUND[, ACTION-IF-NOT-FOUND]]) # # DESCRIPTION # # This macro figures out how to build C programs using POSIX threads. It # sets the PTHREAD_LIBS output variable to the threads library and linker # flags, and the PTHREAD_CFLAGS output variable to any special C compiler # flags that are needed. (The user can also force certain compiler # flags/libs to be tested by setting these environment variables.) # # Also sets PTHREAD_CC to any special C compiler that is needed for # multi-threaded programs (defaults to the value of CC otherwise). (This # is necessary on AIX to use the special cc_r compiler alias.) # # NOTE: You are assumed to not only compile your program with these flags, # but also to link with them as well. For example, you might link with # $PTHREAD_CC $CFLAGS $PTHREAD_CFLAGS $LDFLAGS ... $PTHREAD_LIBS $LIBS # # If you are only building threaded programs, you may wish to use these # variables in your default LIBS, CFLAGS, and CC: # # LIBS="$PTHREAD_LIBS $LIBS" # CFLAGS="$CFLAGS $PTHREAD_CFLAGS" # CC="$PTHREAD_CC" # # In addition, if the PTHREAD_CREATE_JOINABLE thread-attribute constant # has a nonstandard name, this macro defines PTHREAD_CREATE_JOINABLE to # that name (e.g. PTHREAD_CREATE_UNDETACHED on AIX). # # Also HAVE_PTHREAD_PRIO_INHERIT is defined if pthread is found and the # PTHREAD_PRIO_INHERIT symbol is defined when compiling with # PTHREAD_CFLAGS. # # ACTION-IF-FOUND is a list of shell commands to run if a threads library # is found, and ACTION-IF-NOT-FOUND is a list of commands to run it if it # is not found. If ACTION-IF-FOUND is not specified, the default action # will define HAVE_PTHREAD. # # Please let the authors know if this macro fails on any platform, or if # you have any other suggestions or comments. This macro was based on work # by SGJ on autoconf scripts for FFTW (http://www.fftw.org/) (with help # from M. Frigo), as well as ac_pthread and hb_pthread macros posted by # Alejandro Forero Cuervo to the autoconf macro repository. We are also # grateful for the helpful feedback of numerous users. # # Updated for Autoconf 2.68 by Daniel Richard G. # # LICENSE # # Copyright (c) 2008 Steven G. Johnson # Copyright (c) 2011 Daniel Richard G. # # This program is free software: you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation, either version 3 of the License, or (at your # option) any later version. # # 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. See the GNU General # Public License for more details. # # You should have received a copy of the GNU General Public License along # with this program. If not, see . # # As a special exception, the respective Autoconf Macro's copyright owner # gives unlimited permission to copy, distribute and modify the configure # scripts that are the output of Autoconf when processing the Macro. You # need not follow the terms of the GNU General Public License when using # or distributing such scripts, even though portions of the text of the # Macro appear in them. The GNU General Public License (GPL) does govern # all other use of the material that constitutes the Autoconf Macro. # # This special exception to the GPL applies to versions of the Autoconf # Macro released by the Autoconf Archive. When you make and distribute a # modified version of the Autoconf Macro, you may extend this special # exception to the GPL to apply to your modified version as well. #serial 24 AU_ALIAS([ACX_PTHREAD], [AX_PTHREAD]) AC_DEFUN([AX_PTHREAD], [ AC_REQUIRE([AC_CANONICAL_HOST]) AC_REQUIRE([AC_PROG_CC]) AC_REQUIRE([AC_PROG_SED]) AC_LANG_PUSH([C]) ax_pthread_ok=no # We used to check for pthread.h first, but this fails if pthread.h # requires special compiler flags (e.g. on Tru64 or Sequent). # It gets checked for in the link test anyway. # First of all, check if the user has set any of the PTHREAD_LIBS, # etcetera environment variables, and if threads linking works using # them: if test "x$PTHREAD_CFLAGS$PTHREAD_LIBS" != "x"; then ax_pthread_save_CC="$CC" ax_pthread_save_CFLAGS="$CFLAGS" ax_pthread_save_LIBS="$LIBS" AS_IF([test "x$PTHREAD_CC" != "x"], [CC="$PTHREAD_CC"]) CFLAGS="$CFLAGS $PTHREAD_CFLAGS" LIBS="$PTHREAD_LIBS $LIBS" AC_MSG_CHECKING([for pthread_join using $CC $PTHREAD_CFLAGS $PTHREAD_LIBS]) AC_LINK_IFELSE([AC_LANG_CALL([], [pthread_join])], [ax_pthread_ok=yes]) AC_MSG_RESULT([$ax_pthread_ok]) if test "x$ax_pthread_ok" = "xno"; then PTHREAD_LIBS="" PTHREAD_CFLAGS="" fi CC="$ax_pthread_save_CC" CFLAGS="$ax_pthread_save_CFLAGS" LIBS="$ax_pthread_save_LIBS" fi # We must check for the threads library under a number of different # names; the ordering is very important because some systems # (e.g. DEC) have both -lpthread and -lpthreads, where one of the # libraries is broken (non-POSIX). # Create a list of thread flags to try. Items starting with a "-" are # C compiler flags, and other items are library names, except for "none" # which indicates that we try without any flags at all, and "pthread-config" # which is a program returning the flags for the Pth emulation library. ax_pthread_flags="pthreads none -Kthread -pthread -pthreads -mthreads pthread --thread-safe -mt pthread-config" # The ordering *is* (sometimes) important. Some notes on the # individual items follow: # pthreads: AIX (must check this before -lpthread) # none: in case threads are in libc; should be tried before -Kthread and # other compiler flags to prevent continual compiler warnings # -Kthread: Sequent (threads in libc, but -Kthread needed for pthread.h) # -pthread: Linux/gcc (kernel threads), BSD/gcc (userland threads), Tru64 # (Note: HP C rejects this with "bad form for `-t' option") # -pthreads: Solaris/gcc (Note: HP C also rejects) # -mt: Sun Workshop C (may only link SunOS threads [-lthread], but it # doesn't hurt to check since this sometimes defines pthreads and # -D_REENTRANT too), HP C (must be checked before -lpthread, which # is present but should not be used directly; and before -mthreads, # because the compiler interprets this as "-mt" + "-hreads") # -mthreads: Mingw32/gcc, Lynx/gcc # pthread: Linux, etcetera # --thread-safe: KAI C++ # pthread-config: use pthread-config program (for GNU Pth library) case $host_os in freebsd*) # -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able) # lthread: LinuxThreads port on FreeBSD (also preferred to -pthread) ax_pthread_flags="-kthread lthread $ax_pthread_flags" ;; hpux*) # From the cc(1) man page: "[-mt] Sets various -D flags to enable # multi-threading and also sets -lpthread." ax_pthread_flags="-mt -pthread pthread $ax_pthread_flags" ;; openedition*) # IBM z/OS requires a feature-test macro to be defined in order to # enable POSIX threads at all, so give the user a hint if this is # not set. (We don't define these ourselves, as they can affect # other portions of the system API in unpredictable ways.) AC_EGREP_CPP([AX_PTHREAD_ZOS_MISSING], [ # if !defined(_OPEN_THREADS) && !defined(_UNIX03_THREADS) AX_PTHREAD_ZOS_MISSING # endif ], [AC_MSG_WARN([IBM z/OS requires -D_OPEN_THREADS or -D_UNIX03_THREADS to enable pthreads support.])]) ;; solaris*) # On Solaris (at least, for some versions), libc contains stubbed # (non-functional) versions of the pthreads routines, so link-based # tests will erroneously succeed. (N.B.: The stubs are missing # pthread_cleanup_push, or rather a function called by this macro, # so we could check for that, but who knows whether they'll stub # that too in a future libc.) So we'll check first for the # standard Solaris way of linking pthreads (-mt -lpthread). ax_pthread_flags="-mt,pthread pthread $ax_pthread_flags" ;; esac # GCC generally uses -pthread, or -pthreads on some platforms (e.g. SPARC) AS_IF([test "x$GCC" = "xyes"], [ax_pthread_flags="-pthread -pthreads $ax_pthread_flags"]) # The presence of a feature test macro requesting re-entrant function # definitions is, on some systems, a strong hint that pthreads support is # correctly enabled case $host_os in darwin* | hpux* | linux* | osf* | solaris*) ax_pthread_check_macro="_REENTRANT" ;; aix*) ax_pthread_check_macro="_THREAD_SAFE" ;; *) ax_pthread_check_macro="--" ;; esac AS_IF([test "x$ax_pthread_check_macro" = "x--"], [ax_pthread_check_cond=0], [ax_pthread_check_cond="!defined($ax_pthread_check_macro)"]) # Are we compiling with Clang? AC_CACHE_CHECK([whether $CC is Clang], [ax_cv_PTHREAD_CLANG], [ax_cv_PTHREAD_CLANG=no # Note that Autoconf sets GCC=yes for Clang as well as GCC if test "x$GCC" = "xyes"; then AC_EGREP_CPP([AX_PTHREAD_CC_IS_CLANG], [/* Note: Clang 2.7 lacks __clang_[a-z]+__ */ # if defined(__clang__) && defined(__llvm__) AX_PTHREAD_CC_IS_CLANG # endif ], [ax_cv_PTHREAD_CLANG=yes]) fi ]) ax_pthread_clang="$ax_cv_PTHREAD_CLANG" ax_pthread_clang_warning=no # Clang needs special handling, because older versions handle the -pthread # option in a rather... idiosyncratic way if test "x$ax_pthread_clang" = "xyes"; then # Clang takes -pthread; it has never supported any other flag # (Note 1: This will need to be revisited if a system that Clang # supports has POSIX threads in a separate library. This tends not # to be the way of modern systems, but it's conceivable.) # (Note 2: On some systems, notably Darwin, -pthread is not needed # to get POSIX threads support; the API is always present and # active. We could reasonably leave PTHREAD_CFLAGS empty. But # -pthread does define _REENTRANT, and while the Darwin headers # ignore this macro, third-party headers might not.) PTHREAD_CFLAGS="-pthread" PTHREAD_LIBS= ax_pthread_ok=yes # However, older versions of Clang make a point of warning the user # that, in an invocation where only linking and no compilation is # taking place, the -pthread option has no effect ("argument unused # during compilation"). They expect -pthread to be passed in only # when source code is being compiled. # # Problem is, this is at odds with the way Automake and most other # C build frameworks function, which is that the same flags used in # compilation (CFLAGS) are also used in linking. Many systems # supported by AX_PTHREAD require exactly this for POSIX threads # support, and in fact it is often not straightforward to specify a # flag that is used only in the compilation phase and not in # linking. Such a scenario is extremely rare in practice. # # Even though use of the -pthread flag in linking would only print # a warning, this can be a nuisance for well-run software projects # that build with -Werror. So if the active version of Clang has # this misfeature, we search for an option to squash it. AC_CACHE_CHECK([whether Clang needs flag to prevent "argument unused" warning when linking with -pthread], [ax_cv_PTHREAD_CLANG_NO_WARN_FLAG], [ax_cv_PTHREAD_CLANG_NO_WARN_FLAG=unknown # Create an alternate version of $ac_link that compiles and # links in two steps (.c -> .o, .o -> exe) instead of one # (.c -> exe), because the warning occurs only in the second # step ax_pthread_save_ac_link="$ac_link" ax_pthread_sed='s/conftest\.\$ac_ext/conftest.$ac_objext/g' ax_pthread_link_step=`$as_echo "$ac_link" | sed "$ax_pthread_sed"` ax_pthread_2step_ac_link="($ac_compile) && (echo ==== >&5) && ($ax_pthread_link_step)" ax_pthread_save_CFLAGS="$CFLAGS" for ax_pthread_try in '' -Qunused-arguments -Wno-unused-command-line-argument unknown; do AS_IF([test "x$ax_pthread_try" = "xunknown"], [break]) CFLAGS="-Werror -Wunknown-warning-option $ax_pthread_try -pthread $ax_pthread_save_CFLAGS" ac_link="$ax_pthread_save_ac_link" AC_LINK_IFELSE([AC_LANG_SOURCE([[int main(void){return 0;}]])], [ac_link="$ax_pthread_2step_ac_link" AC_LINK_IFELSE([AC_LANG_SOURCE([[int main(void){return 0;}]])], [break]) ]) done ac_link="$ax_pthread_save_ac_link" CFLAGS="$ax_pthread_save_CFLAGS" AS_IF([test "x$ax_pthread_try" = "x"], [ax_pthread_try=no]) ax_cv_PTHREAD_CLANG_NO_WARN_FLAG="$ax_pthread_try" ]) case "$ax_cv_PTHREAD_CLANG_NO_WARN_FLAG" in no | unknown) ;; *) PTHREAD_CFLAGS="$ax_cv_PTHREAD_CLANG_NO_WARN_FLAG $PTHREAD_CFLAGS" ;; esac fi # $ax_pthread_clang = yes if test "x$ax_pthread_ok" = "xno"; then for ax_pthread_try_flag in $ax_pthread_flags; do case $ax_pthread_try_flag in none) AC_MSG_CHECKING([whether pthreads work without any flags]) ;; -mt,pthread) AC_MSG_CHECKING([whether pthreads work with -mt -lpthread]) PTHREAD_CFLAGS="-mt" PTHREAD_LIBS="-lpthread" ;; -*) AC_MSG_CHECKING([whether pthreads work with $ax_pthread_try_flag]) PTHREAD_CFLAGS="$ax_pthread_try_flag" ;; pthread-config) AC_CHECK_PROG([ax_pthread_config], [pthread-config], [yes], [no]) AS_IF([test "x$ax_pthread_config" = "xno"], [continue]) PTHREAD_CFLAGS="`pthread-config --cflags`" PTHREAD_LIBS="`pthread-config --ldflags` `pthread-config --libs`" ;; *) AC_MSG_CHECKING([for the pthreads library -l$ax_pthread_try_flag]) PTHREAD_LIBS="-l$ax_pthread_try_flag" ;; esac ax_pthread_save_CFLAGS="$CFLAGS" ax_pthread_save_LIBS="$LIBS" CFLAGS="$CFLAGS $PTHREAD_CFLAGS" LIBS="$PTHREAD_LIBS $LIBS" # Check for various functions. We must include pthread.h, # since some functions may be macros. (On the Sequent, we # need a special flag -Kthread to make this header compile.) # We check for pthread_join because it is in -lpthread on IRIX # while pthread_create is in libc. We check for pthread_attr_init # due to DEC craziness with -lpthreads. We check for # pthread_cleanup_push because it is one of the few pthread # functions on Solaris that doesn't have a non-functional libc stub. # We try pthread_create on general principles. AC_LINK_IFELSE([AC_LANG_PROGRAM([#include # if $ax_pthread_check_cond # error "$ax_pthread_check_macro must be defined" # endif static void routine(void *a) { a = 0; } static void *start_routine(void *a) { return a; }], [pthread_t th; pthread_attr_t attr; pthread_create(&th, 0, start_routine, 0); pthread_join(th, 0); pthread_attr_init(&attr); pthread_cleanup_push(routine, 0); pthread_cleanup_pop(0) /* ; */])], [ax_pthread_ok=yes], []) CFLAGS="$ax_pthread_save_CFLAGS" LIBS="$ax_pthread_save_LIBS" AC_MSG_RESULT([$ax_pthread_ok]) AS_IF([test "x$ax_pthread_ok" = "xyes"], [break]) PTHREAD_LIBS="" PTHREAD_CFLAGS="" done fi # Various other checks: if test "x$ax_pthread_ok" = "xyes"; then ax_pthread_save_CFLAGS="$CFLAGS" ax_pthread_save_LIBS="$LIBS" CFLAGS="$CFLAGS $PTHREAD_CFLAGS" LIBS="$PTHREAD_LIBS $LIBS" # Detect AIX lossage: JOINABLE attribute is called UNDETACHED. AC_CACHE_CHECK([for joinable pthread attribute], [ax_cv_PTHREAD_JOINABLE_ATTR], [ax_cv_PTHREAD_JOINABLE_ATTR=unknown for ax_pthread_attr in PTHREAD_CREATE_JOINABLE PTHREAD_CREATE_UNDETACHED; do AC_LINK_IFELSE([AC_LANG_PROGRAM([#include ], [int attr = $ax_pthread_attr; return attr /* ; */])], [ax_cv_PTHREAD_JOINABLE_ATTR=$ax_pthread_attr; break], []) done ]) AS_IF([test "x$ax_cv_PTHREAD_JOINABLE_ATTR" != "xunknown" && \ test "x$ax_cv_PTHREAD_JOINABLE_ATTR" != "xPTHREAD_CREATE_JOINABLE" && \ test "x$ax_pthread_joinable_attr_defined" != "xyes"], [AC_DEFINE_UNQUOTED([PTHREAD_CREATE_JOINABLE], [$ax_cv_PTHREAD_JOINABLE_ATTR], [Define to necessary symbol if this constant uses a non-standard name on your system.]) ax_pthread_joinable_attr_defined=yes ]) AC_CACHE_CHECK([whether more special flags are required for pthreads], [ax_cv_PTHREAD_SPECIAL_FLAGS], [ax_cv_PTHREAD_SPECIAL_FLAGS=no case $host_os in solaris*) ax_cv_PTHREAD_SPECIAL_FLAGS="-D_POSIX_PTHREAD_SEMANTICS" ;; esac ]) AS_IF([test "x$ax_cv_PTHREAD_SPECIAL_FLAGS" != "xno" && \ test "x$ax_pthread_special_flags_added" != "xyes"], [PTHREAD_CFLAGS="$ax_cv_PTHREAD_SPECIAL_FLAGS $PTHREAD_CFLAGS" ax_pthread_special_flags_added=yes]) AC_CACHE_CHECK([for PTHREAD_PRIO_INHERIT], [ax_cv_PTHREAD_PRIO_INHERIT], [AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include ]], [[int i = PTHREAD_PRIO_INHERIT;]])], [ax_cv_PTHREAD_PRIO_INHERIT=yes], [ax_cv_PTHREAD_PRIO_INHERIT=no]) ]) AS_IF([test "x$ax_cv_PTHREAD_PRIO_INHERIT" = "xyes" && \ test "x$ax_pthread_prio_inherit_defined" != "xyes"], [AC_DEFINE([HAVE_PTHREAD_PRIO_INHERIT], [1], [Have PTHREAD_PRIO_INHERIT.]) ax_pthread_prio_inherit_defined=yes ]) CFLAGS="$ax_pthread_save_CFLAGS" LIBS="$ax_pthread_save_LIBS" # More AIX lossage: compile with *_r variant if test "x$GCC" != "xyes"; then case $host_os in aix*) AS_CASE(["x/$CC"], [x*/c89|x*/c89_128|x*/c99|x*/c99_128|x*/cc|x*/cc128|x*/xlc|x*/xlc_v6|x*/xlc128|x*/xlc128_v6], [#handle absolute path differently from PATH based program lookup AS_CASE(["x$CC"], [x/*], [AS_IF([AS_EXECUTABLE_P([${CC}_r])],[PTHREAD_CC="${CC}_r"])], [AC_CHECK_PROGS([PTHREAD_CC],[${CC}_r],[$CC])])]) ;; esac fi fi test -n "$PTHREAD_CC" || PTHREAD_CC="$CC" AC_SUBST([PTHREAD_LIBS]) AC_SUBST([PTHREAD_CFLAGS]) AC_SUBST([PTHREAD_CC]) # Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND: if test "x$ax_pthread_ok" = "xyes"; then ifelse([$1],,[AC_DEFINE([HAVE_PTHREAD],[1],[Define if you have POSIX threads libraries and header files.])],[$1]) : else ax_pthread_ok=no $2 fi AC_LANG_POP ])dnl AX_PTHREAD krb5-1.16/src/config/rm.bat0000644000704600001450000000225513211554426015344 0ustar ghudsonlibuuid@echo off :loop if exist %1 del %1 shift if not %1.==. goto loop exit Rem Rem rm.bat Rem Rem Copyright 1995 by the Massachusetts Institute of Technology. Rem All Rights Reserved. Rem Rem Export of this software from the United States of America may Rem require a specific license from the United States Government. Rem It is the responsibility of any person or organization contemplating Rem export to obtain such a license before exporting. Rem Rem WITHIN THAT CONSTRAINT, permission to use, copy, modify, and Rem distribute this software and its documentation for any purpose and Rem without fee is hereby granted, provided that the above copyright Rem notice appear in all copies and that both that copyright notice and Rem this permission notice appear in supporting documentation, and that Rem the name of M.I.T. not be used in advertising or publicity pertaining Rem to distribution of the software without specific, written prior Rem permission. M.I.T. makes no representations about the suitability of Rem this software for any purpose. It is provided "as is" without express Rem or implied warranty. Rem Rem Rem Batch file to mimic the functionality of the Unix rm command Rem krb5-1.16/src/config/post.in0000644000704600001450000001744513211554426015562 0ustar ghudsonlibuuid############################################################ ## config/post.in ## # in case there is no default target (very unlikely) all: check-windows: ############################## # dependency generation # depend: depend-postrecurse depend-postrecurse: depend-recurse depend-recurse: depend-prerecurse depend-prerecurse: depend-postrecurse: depend-postrecurse: depend-update-makefile ALL_DEP_SRCS= $(SRCS) $(EXTRADEPSRCS) # be sure to check ALL_DEP_SRCS against *what it would be if SRCS and # EXTRADEPSRCS are both empty* $(BUILDTOP)/.depend-verify-srcdir: @if test "$(srcdir)" = "." ; then \ echo 1>&2 error: cannot build dependencies with srcdir=. ; \ echo 1>&2 "(can't distinguish generated files from source files)" ; \ echo 1>&2 "Run 'make distclean' and create a separate build dir" ; \ exit 1 ; \ elif test -f "$(top_srcdir)/include/autoconf.h"; then \ echo 1>&2 "error: generated headers found in source tree" ; \ echo 1>&2 "Run 'make distclean' in source tree first" ; \ exit 1 ; \ else \ if test -r $(BUILDTOP)/.depend-verify-srcdir; then :; \ else (set -x; touch $(BUILDTOP)/.depend-verify-srcdir); fi \ fi $(BUILDTOP)/.depend-verify-et: depend-verify-et-$(COM_ERR_VERSION) depend-verify-et-k5: @if test -r $(BUILDTOP)/.depend-verify-et; then :; \ else (set -x; touch $(BUILDTOP)/.depend-verify-et); fi depend-verify-et-sys depend-verify-et-intlsys: @echo 1>&2 error: cannot build dependencies using system et package @exit 1 $(BUILDTOP)/.depend-verify-ss: depend-verify-ss-$(SS_VERSION) depend-verify-ss-k5: @if test -r $(BUILDTOP)/.depend-verify-ss; then :; \ else (set -x; touch $(BUILDTOP)/.depend-verify-ss); fi depend-verify-ss-sys: @echo 1>&2 error: cannot build dependencies using system ss package @exit 1 $(BUILDTOP)/.depend-verify-verto: depend-verify-verto-$(VERTO_VERSION) depend-verify-verto-k5: @if test -r $(BUILDTOP)/.depend-verify-verto; then :; \ else (set -x; touch $(BUILDTOP)/.depend-verify-verto); fi depend-verify-verto-sys: @echo 1>&2 error: cannot build dependencies using system verto package @echo 1>&2 Please configure with --without-system-verto @exit 1 $(BUILDTOP)/.depend-verify-gcc: depend-verify-gcc-@HAVE_GCC@ depend-verify-gcc-yes: @if test -r $(BUILDTOP)/.depend-verify-gcc; then :; \ else (set -x; touch $(BUILDTOP)/.depend-verify-gcc); fi depend-verify-gcc-no: @echo 1>&2 error: The '"depend"' rules are written for gcc. @echo 1>&2 Please use gcc, or update the rules to handle your compiler. @exit 1 DEP_CFG_VERIFY = $(BUILDTOP)/.depend-verify-srcdir \ $(BUILDTOP)/.depend-verify-et $(BUILDTOP)/.depend-verify-ss \ $(BUILDTOP)/.depend-verify-verto DEP_VERIFY = $(DEP_CFG_VERIFY) $(BUILDTOP)/.depend-verify-gcc .d: $(ALL_DEP_SRCS) $(DEP_CFG_VERIFY) depend-dependencies if test "$(ALL_DEP_SRCS)" != " " ; then \ $(RM) .dtmp && $(MAKE) .dtmp && mv -f .dtmp .d ; \ else \ touch .d ; \ fi # These are dependencies of the depend target that do not get fed to # the compiler. Examples include generated header files. depend-dependencies: # .dtmp must *always* be out of date so that $? can be used to perform # VPATH searches on the sources. # # NOTE: This will fail when using Make programs whose VPATH support is # broken. .dtmp: $(ALL_DEP_SRCS) $(CC) -M -DDEPEND $(ALL_CFLAGS) $? > .dtmp # NOTE: This will also generate spurious $(OUTPRE) and $(OBJEXT) # references in rules for non-library objects in a directory where # library objects happen to be built. It's mostly harmless. .depend: .d $(top_srcdir)/util/depfix.pl perl $(top_srcdir)/util/depfix.pl '$(top_srcdir)' '$(mydir)' \ '$(srcdir)' '$(BUILDTOP)' '$(STLIBOBJS)' < .d > .depend # Temporarily keep the rule for removing the dependency line eater # until we're sure we've gotten everything converted and excised the # old stuff from Makefile.in files. depend-update-makefile: .depend depend-recurse if test "$(ALL_DEP_SRCS)" != " " ; then \ $(CP) .depend $(srcdir)/deps.new ; \ else \ echo "# No dependencies here." > $(srcdir)/deps.new ; \ fi $(top_srcdir)/config/move-if-changed $(srcdir)/deps.new $(srcdir)/deps sed -e '/^# +++ Dependency line eater +++/,$$d' \ < $(srcdir)/Makefile.in > $(srcdir)/Makefile.in.new $(top_srcdir)/config/move-if-changed $(srcdir)/Makefile.in.new \ $(srcdir)/Makefile.in DEPTARGETS = .depend .d .dtmp $(DEP_VERIFY) DEPTARGETS_CLEAN = .depend .d .dtmp $(DEPTARGETS_@srcdir@_@CONFIG_RELTOPDIR@) DEPTARGETS_@top_srcdir@_. = $(DEP_VERIFY) # Clear out dependencies. Should only be used temporarily, e.g., while # moving or renaming headers and then rebuilding dependencies. undepend: undepend-postrecurse undepend-recurse: undepend-postrecurse: undepend-recurse if test -n "$(SRCS)" ; then \ sed -e '/^# +++ Dependency line eater +++/,$$d' \ < $(srcdir)/Makefile.in \ > $(srcdir)/Makefile.in.new ;\ echo "# +++ Dependency line eater +++" >> $(srcdir)/Makefile.in.new ;\ echo "# (dependencies temporarily removed)" >> $(srcdir)/Makefile.in.new ;\ $(top_srcdir)/config/move-if-changed $(srcdir)/Makefile.in.new $(srcdir)/Makefile.in;\ else :; fi # # end dependency generation ############################## # Python tests check-unix: check-pytests-@HAVE_PYTHON@ # Makefile.in should add rules to check-pytests to execute Python tests. check-pytests-yes: check-pytests check-pytests-no: check-pytests: # cmocka tests check-unix: check-cmocka-@HAVE_CMOCKA@ check-cmocka-yes: check-cmocka check-cmocka-no: check-cmocka: clean: clean-$(WHAT) clean-unix:: $(RM) $(OBJS) $(DEPTARGETS_CLEAN) $(EXTRA_FILES) $(RM) et-[ch]-*.et et-[ch]-*.[ch] testlog testtrace -$(RM) -r testdir clean-windows:: $(RM) *.$(OBJEXT) $(RM) msvc.pdb *.err distclean: distclean-$(WHAT) distclean-normal-clean: $(MAKE) NORECURSE=true clean distclean-prerecurse: distclean-normal-clean distclean-nuke-configure-state: $(RM) config.log config.cache config.status Makefile distclean-postrecurse: distclean-nuke-configure-state Makefiles-prerecurse: Makefile # mydir = relative path from top to this Makefile Makefile: $(srcdir)/Makefile.in $(srcdir)/deps $(BUILDTOP)/config.status \ $(top_srcdir)/config/pre.in $(top_srcdir)/config/post.in (cd $(BUILDTOP) && $(SHELL) config.status $(mydir)/Makefile) $(BUILDTOP)/config.status: $(top_srcdir)/configure (cd $(BUILDTOP) && $(SHELL) config.status --recheck) $(top_srcdir)/configure: @MAINT@ \ $(top_srcdir)/configure.in \ $(top_srcdir)/patchlevel.h \ $(top_srcdir)/aclocal.m4 (cd $(top_srcdir) && \ $(AUTOCONF) -f --include=$(CONFIG_RELTOPDIR) $(AUTOCONFFLAGS)) RECURSE_TARGETS=all-recurse clean-recurse distclean-recurse install-recurse \ generate-files-mac-recurse \ check-recurse depend-recurse undepend-recurse \ Makefiles-recurse install-headers-recurse # MY_SUBDIRS overrides any setting of SUBDIRS generated by the # configure script that generated this Makefile. This is needed when # the configure script that produced this Makefile creates multiple # Makefiles in different directories; the setting of SUBDIRS will be # the same in each. # # LOCAL_SUBDIRS seems to account for the case where the configure # script doesn't call any other subsidiary configure scripts, but # generates multiple Makefiles. $(RECURSE_TARGETS): @case "`echo 'x$(MFLAGS)'|sed -e 's/^x//' -e 's/ --.*$$//'`" \ in *[ik]*) e="status=1" ;; *) e="exit 1";; esac; \ do_subdirs="$(SUBDIRS)" ; \ status=0; \ if test -n "$$do_subdirs" && test -z "$(NORECURSE)"; then \ for i in $$do_subdirs ; do \ if test -d $$i && test -r $$i/Makefile ; then \ case $$i in .);; *) \ target=`echo $@|sed s/-recurse//`; \ echo "making $$target in $(CURRENT_DIR)$$i..."; \ if (cd $$i ; $(MAKE) \ CURRENT_DIR=$(CURRENT_DIR)$$i/ $$target) then :; \ else eval $$e; fi; \ ;; \ esac; \ else \ echo "Skipping missing directory $(CURRENT_DIR)$$i" ; \ fi; \ done; \ else :; \ fi;\ exit $$status ## ## end of post.in ############################################################ krb5-1.16/src/config/libnover.in0000644000704600001450000001041113211554426016377 0ustar ghudsonlibuuid### config/libnover.in # *** keep this in sync with lib.in # # Makefile fragment that creates shared libraries sans version # info (plugin modules). # # The following variables must be set in the Makefile.in: # # LIBBASE library name without "lib" or extension # SHLIB_EXPDEPS list of libraries that this one has explicit # dependencies on, pref. in the form libfoo$(SHLIBEXT) # SHLIB_EXPLIBS list of libraries that this one has explicit # dependencies on, in "-lfoo" form. # RELDIR path to this directory relative to $(TOPLIBD) # # Makefile.in can also override the defaults for SHLIB_DIRS, # SHLIB_RDIRS, and STOBJLISTS from pre.in. LIBPREFIX= SHOBJLISTS=$(STOBJLISTS:.ST=.SH) PFOBJLISTS=$(STOBJLISTS:.ST=.PF) dummy-target-1 $(SUBDIROBJLISTS) $(SUBDIROBJLISTS:.ST=.SH) $(SUBDIROBJLISTS:.ST=.PF): all-recurse # Gets invoked as $(PARSE_OBJLISTS) list-of-OBJS.*-files PARSE_OBJLISTS= set -x && $(PERL) -p -e 'BEGIN { $$SIG{__WARN__} = sub {die @_} }; $$e=$$ARGV; $$e =~ s/OBJS\...$$//; s/^/ /; s/ $$//; s/ / $$e/g;' LIBINSTLIST=install-shared libkrb5_$(LIBBASE)$(STLIBEXT): $(STOBJLISTS) $(RM) $@ @echo "building static $(LIBBASE) library" set -x; objlist=`$(PARSE_OBJLISTS) $(STOBJLISTS)` && $(AR) cq $@ $$objlist $(RANLIB) $@ $(LIBBASE)$(DYNOBJEXT): $(SHOBJLISTS) $(DYNOBJ_EXPDEPS) $(SHLIB_EXPORT_FILE_DEP) $(RM) $@ @echo "building dynamic $(LIBBASE) object" set -x; objlist=`$(PARSE_OBJLISTS) $(SHOBJLISTS)` && $(MAKE_DYNOBJ_COMMAND) binutils.versions: $(SHLIB_EXPORT_FILE) Makefile echo > binutils.versions "HIDDEN { local: __*; _rest*; _save*; *; };" echo >> binutils.versions "$(LIBBASE)_$(LIBMAJOR)_MIT {" sed >> binutils.versions < $(SHLIB_EXPORT_FILE) "s/$$/;/" echo >> binutils.versions "};" osf1.exports: $(SHLIB_EXPORT_FILE) Makefile $(RM) osf1.tmp osf1.exports sed "s/^/-exported_symbol /" < $(SHLIB_EXPORT_FILE) > osf1.tmp for f in . $(LIBINITFUNC); do \ if test "$$f" != "." ; then \ echo " -init $$f"__auxinit >> osf1.tmp; \ else :; fi; \ done a=""; \ for f in . $(LIBFINIFUNC); do \ if test "$$f" != "." ; then \ a="-fini $$f $$a"; \ else :; fi; \ done; echo " $$a" >> osf1.tmp; \ mv -f osf1.tmp osf1.exports hpux.exports: $(SHLIB_EXPORT_FILE) Makefile $(RM) hpux.tmp hpux.exports sed "s/^/+e /" < $(SHLIB_EXPORT_FILE) > hpux.tmp a=""; \ for f in . $(LIBFINIFUNC); do \ if test "$$f" != .; then \ a="+I $${f}__auxfini $$a"; \ else :; fi; \ done; echo "$$a" >> hpux.tmp echo "+e errno" >> hpux.tmp mv -f hpux.tmp hpux.exports darwin.exports: $(SHLIB_EXPORT_FILE) Makefile $(RM) darwin.exports sed "s/^/_/" < $(SHLIB_EXPORT_FILE) > darwin.exports libkrb5_$(LIBBASE)$(PFLIBEXT): $(PFOBJLISTS) $(RM) $@ @echo "building profiled $(LIBBASE) library" set -x; objlist=`$(PARSE_OBJLISTS) $(PFOBJLISTS)` && $(AR) cq $@ $$objlist $(RANLIB) $@ # For static builds, we make a symlink in the main library directory, # allowing the plugin library to be a dependency of the core libraries # which use it. $(TOPLIBD)/libkrb5_$(LIBBASE)$(STLIBEXT): $(RM) $@ (cd $(TOPLIBD) && $(LN_S) $(RELDIR)/libkrb5_$(LIBBASE)$(STLIBEXT) .) # For shared builds, we make a symlink in the parent directory, allowing # tests to point plugin_base_dir at $(BUILDTOP)/plugins. ../$(LIBBASE)$(DYNOBJEXT): $(RM) $@ (cd .. && $(LN_S) `basename $(mydir)`/$(LIBBASE)$(DYNOBJEXT) .) all-liblinks: all-libs $(PLUGINLINK) all-libs: $(PLUGIN) clean-libs: $(RM) $(LIBBASE)$(DYNOBJEXT) $(RM) binutils.versions osf1.exports darwin.exports hpux.exports clean-liblinks: $(RM) $(PLUGINLINK) install-libs: $(PLUGININST) install-static: $(RM) $(DESTDIR)$(KRB5_LIBDIR)/libkrb5_$(LIBBASE)$(STLIBEXT) $(INSTALL_DATA) libkrb5_$(LIBBASE)$(STLIBEXT) $(DESTDIR)$(KRB5_LIBDIR) $(RANLIB) $(DESTDIR)$(KRB5_LIBDIR)/libkrb5_$(LIBBASE)$(STLIBEXT) install-plugin: $(RM) $(DESTDIR)$(MODULE_INSTALL_DIR)/$(LIBBASE)$(DYNOBJEXT) $(INSTALL_SHLIB) $(LIBBASE)$(DYNOBJEXT) $(DESTDIR)$(MODULE_INSTALL_DIR) Makefile: $(top_srcdir)/config/libnover.in $(BUILDTOP)/config.status: $(top_srcdir)/config/shlib.conf # Use the following if links need to be made to $(TOPLIBD): # all-unix: all-liblinks # install-unix: install-libs # clean-unix:: clean-liblinks clean-libs # Use the following if links need not be made: # all-unix: all-libs # install-unix: install-libs # clean-unix:: clean-libs ### ### end config/libnovers.in krb5-1.16/src/config/pre.in0000644000704600001450000004456013211554426015361 0ustar ghudsonlibuuid############################################################ ## config/pre.in ## common prefix for all Makefile.in in the Kerberos V5 tree. ## # These are set per-directory by autoconf 2.52 and 2.53: # srcdir=@srcdir@ # top_srcdir=@top_srcdir@ # but these are only set by autoconf 2.53, and thus not useful to us on # macOS yet (as of 10.2): # abs_srcdir=@abs_srcdir@ # abs_top_srcdir=@abs_top_srcdir@ # builddir=@builddir@ # abs_builddir=@abs_builddir@ # top_builddir=@top_builddir@ # abs_top_builddir=@abs_top_builddir@ # The "top" variables refer to the directory with the configure (or # config.status) script. WHAT = unix SHELL=/bin/sh all: all-$(WHAT) clean: clean-$(WHAT) distclean: distclean-$(WHAT) install: install-$(WHAT) check: check-$(WHAT) install-headers: install-headers-$(WHAT) ############################## # Recursion rule support # # The commands for the recursion targets live in config/post.in. # # General form of recursion rules: # # Each recursive target foo-unix has related targets: foo-prerecurse, # foo-recurse, and foo-postrecurse # # The foo-recurse rule is in post.in. It is what actually recursively # calls make. # # foo-recurse depends on foo-prerecurse, so any targets that must be # built before descending into subdirectories must be dependencies of # foo-prerecurse. # # foo-postrecurse depends on foo-recurse, but targets that must be # built after descending into subdirectories should be have # foo-recurse as dependencies in addition to being listed under # foo-postrecurse, to avoid ordering issues. # # The foo-prerecurse, foo-recurse, and foo-postrecurse rules are all # single-colon rules, to avoid nasty ordering problems with # double-colon rules. # # e.g. # all: includes foo # foo: # echo foo # includes: # echo bar # includes: # echo baz # # will result in "bar", "foo", "baz" on AIX, and possibly others. all-unix: all-postrecurse all-postrecurse: all-recurse all-recurse: all-prerecurse all-prerecurse: all-postrecurse: clean-unix:: clean-postrecurse clean-postrecurse: clean-recurse clean-recurse: clean-prerecurse clean-prerecurse: clean-postrecurse: distclean-unix: distclean-postrecurse distclean-postrecurse: distclean-recurse distclean-recurse: distclean-prerecurse distclean-prerecurse: distclean-postrecurse: install-unix: install-postrecurse install-postrecurse: install-recurse install-recurse: install-prerecurse install-prerecurse: install-postrecurse: install-headers-unix: install-headers-postrecurse install-headers-postrecurse: install-headers-recurse install-headers-recurse: install-headers-prerecurse install-headers-prerecurse: install-headers-postrecurse: check-unix: check-postrecurse check-postrecurse: check-recurse check-recurse: check-prerecurse check-prerecurse: check-postrecurse: Makefiles: Makefiles-postrecurse Makefiles-postrecurse: Makefiles-recurse Makefiles-recurse: Makefiles-prerecurse Makefiles-prerecurse: Makefiles-postrecurse: generate-files-mac: generate-files-mac-postrecurse generate-files-mac-postrecurse: generate-files-mac-recurse generate-files-mac-recurse: generate-files-mac-prerecurse generate-files-mac-prerecurse: # # end recursion rule support ############################## # Directory syntax: # # begin relative path REL= # this is magic... should only be used for preceding a program invocation C=./ # "/" for UNIX, "\" for Windows; *sigh* S=/ # srcdir = @srcdir@ top_srcdir = @top_srcdir@ VPATH = @srcdir@ CONFIG_RELTOPDIR = @CONFIG_RELTOPDIR@ # DEFS set by configure # DEFINES set by local Makefile.in # LOCALINCLUDES set by local Makefile.in # CPPFLAGS user override # CFLAGS user override but starts off set by configure # WARN_CFLAGS user override but starts off set by configure # PTHREAD_CFLAGS set by configure, not included in CFLAGS so that we # don't pull the pthreads library into shared libraries # ASAN_FLAGS set by configure when --enable-asan is used ALL_CFLAGS = $(DEFS) $(DEFINES) $(KRB_INCLUDES) $(LOCALINCLUDES) \ -DKRB5_DEPRECATED=1 \ -DKRB5_PRIVATE \ $(CPPFLAGS) $(CFLAGS) $(WARN_CFLAGS) $(PTHREAD_CFLAGS) $(ASAN_FLAGS) ALL_CXXFLAGS = $(DEFS) $(DEFINES) $(KRB_INCLUDES) $(LOCALINCLUDES) \ -DKRB5_DEPRECATED=1 \ -DKRB5_PRIVATE \ $(CPPFLAGS) $(CXXFLAGS) $(WARN_CXXFLAGS) $(PTHREAD_CFLAGS) \ $(ASAN_FLAGS) CFLAGS = @CFLAGS@ CXXFLAGS = @CXXFLAGS@ WARN_CFLAGS = @WARN_CFLAGS@ WARN_CXXFLAGS = @WARN_CXXFLAGS@ ASAN_FLAGS = @ASAN_FLAGS@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_LIBS = @PTHREAD_LIBS@ THREAD_LINKOPTS = $(PTHREAD_CFLAGS) $(PTHREAD_LIBS) CPPFLAGS = @CPPFLAGS@ DEFS = @DEFS@ CC = @CC@ CXX = @CXX@ LD = $(PURE) @LD@ KRB_INCLUDES = -I$(BUILDTOP)/include -I$(top_srcdir)/include LDFLAGS = @LDFLAGS@ LIBS = @LIBS@ INSTALL=@INSTALL@ INSTALL_STRIP= INSTALL_PROGRAM=@INSTALL_PROGRAM@ $(INSTALL_STRIP) INSTALL_SCRIPT=@INSTALL_PROGRAM@ INSTALL_DATA=@INSTALL_DATA@ INSTALL_SHLIB=@INSTALL_SHLIB@ INSTALL_SETUID=$(INSTALL) $(INSTALL_STRIP) -m 4755 -o root ## This is needed because autoconf will sometimes define @exec_prefix@ to be ## ${prefix}. prefix=@prefix@ INSTALL_PREFIX=$(prefix) INSTALL_EXEC_PREFIX=@exec_prefix@ exec_prefix=@exec_prefix@ datarootdir=@datarootdir@ datadir = @datadir@ EXAMPLEDIR = $(datadir)/examples/krb5 KRB5MANROOT = @mandir@ ADMIN_BINDIR = @sbindir@ SERVER_BINDIR = @sbindir@ CLIENT_BINDIR =@bindir@ PKGCONFIG_DIR = @libdir@/pkgconfig ADMIN_MANDIR = $(KRB5MANROOT)/man8 SERVER_MANDIR = $(KRB5MANROOT)/man8 CLIENT_MANDIR = $(KRB5MANROOT)/man1 FILE_MANDIR = $(KRB5MANROOT)/man5 ADMIN_CATDIR = $(KRB5MANROOT)/cat8 SERVER_CATDIR = $(KRB5MANROOT)/cat8 CLIENT_CATDIR = $(KRB5MANROOT)/cat1 FILE_CATDIR = $(KRB5MANROOT)/cat5 KRB5_LIBDIR = @libdir@ KRB5_INCDIR = @includedir@ MODULE_DIR = @libdir@/krb5/plugins KRB5_DB_MODULE_DIR = $(MODULE_DIR)/kdb KRB5_PA_MODULE_DIR = $(MODULE_DIR)/preauth KRB5_AD_MODULE_DIR = $(MODULE_DIR)/authdata KRB5_LIBKRB5_MODULE_DIR = $(MODULE_DIR)/libkrb5 KRB5_TLS_MODULE_DIR = $(MODULE_DIR)/tls KRB5_LOCALEDIR = @localedir@ GSS_MODULE_DIR = @libdir@/gss KRB5_INCSUBDIRS = \ $(KRB5_INCDIR)/kadm5 \ $(KRB5_INCDIR)/krb5 \ $(KRB5_INCDIR)/gssapi \ $(KRB5_INCDIR)/gssrpc # # Macros used by the KADM5 (OV-based) unit test system. # XXX check which of these are actually used! # SKIPTESTS = $(BUILDTOP)/skiptests TESTDIR = $(BUILDTOP)/kadmin/testing STESTDIR = $(top_srcdir)/kadmin/testing ENV_SETUP = $(TESTDIR)/scripts/env-setup.sh CLNTTCL = $(TESTDIR)/util/kadm5_clnt_tcl SRVTCL = $(TESTDIR)/util/kadm5_srv_tcl # Dejagnu variables. # We have to set the host with --host so that setup_xfail will work. # If we don't set it, then the host type used is "native", which # doesn't match "*-*-*". host=@krb5_cv_host@ DEJAFLAGS = --debug --srcdir $(srcdir) --host $(host) RUNTEST = runtest $(DEJAFLAGS) RUNPYTEST = PYTHONPATH=$(top_srcdir)/util VALGRIND="$(VALGRIND)" \ $(PYTHON) START_SERVERS = $(STESTDIR)/scripts/start_servers $(TEST_SERVER) $(TEST_PATH) START_SERVERS_LOCAL = $(STESTDIR)/scripts/start_servers_local STOP_SERVERS = $(STESTDIR)/scripts/stop_servers $(TEST_SERVER) $(TEST_PATH) STOP_SERVERS_LOCAL = $(STESTDIR)/scripts/stop_servers_local # # End of macros for the KADM5 unit test system. # transform = @program_transform_name@ RM = rm -f CP = cp MV = mv -f RANLIB = @RANLIB@ AWK = @AWK@ YACC = @YACC@ PERL = @PERL@ PYTHON = @PYTHON@ AUTOCONF = autoconf AUTOCONFFLAGS = AUTOHEADER = autoheader AUTOHEADERFLAGS = MOVEIFCHANGED = $(top_srcdir)/config/move-if-changed TOPLIBD = $(BUILDTOP)/lib OBJEXT = o EXEEXT = # # variables for libraries, for use in linking programs # -- this may want to get broken out into a separate frag later # # invocation is like: # prog: foo.o bar.o $(KRB5_BASE_DEPLIBS) # $(CC_LINK) -o $@ foo.o bar.o $(KRB5_BASE_LIBS) CC_LINK=@CC_LINK@ $(ASAN_FLAGS) CXX_LINK=@CXX_LINK@ $(ASAN_FLAGS) # Makefile.in files which build programs can override the list of # directories to look for dependent libraries in (in the form -Ldir1 # -Ldir2 ...) and also the list of rpath directories to search (in the # form dir1:dir2:...). PROG_LIBPATH=-L$(TOPLIBD) PROG_RPATH=$(KRB5_LIBDIR) # Library Makefile.in files can override this list of directories to # look for dependent libraries in (in the form -Ldir1 -Ldir2 ...) and # also the list of rpath directories to search (in the form # dir1:dir2:...) SHLIB_DIRS=-L$(TOPLIBD) SHLIB_RDIRS=$(KRB5_LIBDIR) # Multi-directory library Makefile.in files should override this list # of object files with the full list. STOBJLISTS=OBJS.ST # prefix (with no spaces after) for rpath flag to cc RPATH_FLAG=@RPATH_FLAG@ # link flags to add PROG_RPATH to the rpath PROG_RPATH_FLAGS=@PROG_RPATH_FLAGS@ # this gets set by configure to either $(STLIBEXT) or $(SHLIBEXT), # depending on whether we're building with shared libraries. DEPLIBEXT=@DEPLIBEXT@ KDB5_PLUGIN_DEPLIBS = @KDB5_PLUGIN_DEPLIBS@ KDB5_PLUGIN_LIBS = @KDB5_PLUGIN_LIBS@ KADMCLNT_DEPLIB = $(TOPLIBD)/libkadm5clnt_mit$(DEPLIBEXT) KADMSRV_DEPLIB = $(TOPLIBD)/libkadm5srv_mit$(DEPLIBEXT) KDB5_DEPLIB = $(TOPLIBD)/libkdb5$(DEPLIBEXT) GSSRPC_DEPLIB = $(TOPLIBD)/libgssrpc$(DEPLIBEXT) GSS_DEPLIB = $(TOPLIBD)/libgssapi_krb5$(DEPLIBEXT) KRB5_DEPLIB = $(TOPLIBD)/libkrb5$(DEPLIBEXT) CRYPTO_DEPLIB = $(TOPLIBD)/libk5crypto$(DEPLIBEXT) COM_ERR_DEPLIB = $(COM_ERR_DEPLIB-@COM_ERR_VERSION@) COM_ERR_DEPLIB-sys = # empty COM_ERR_DEPLIB-intlsys = # empty COM_ERR_DEPLIB-k5 = $(TOPLIBD)/libcom_err$(DEPLIBEXT) SUPPORT_LIBNAME=krb5support SUPPORT_DEPLIB = $(TOPLIBD)/lib$(SUPPORT_LIBNAME)$(DEPLIBEXT) # These are forced to use ".a" as an extension because they're never # built shared. SS_DEPLIB = $(SS_DEPLIB-@SS_VERSION@) SS_DEPLIB-k5 = $(TOPLIBD)/libss.a SS_DEPLIB-sys = APPUTILS_DEPLIB = $(TOPLIBD)/libapputils.a KRB5_BASE_DEPLIBS = $(KRB5_DEPLIB) $(CRYPTO_DEPLIB) $(COM_ERR_DEPLIB) $(SUPPORT_DEPLIB) KDB5_DEPLIBS = $(KDB5_DEPLIB) $(KDB5_PLUGIN_DEPLIBS) GSS_DEPLIBS = $(GSS_DEPLIB) GSSRPC_DEPLIBS = $(GSSRPC_DEPLIB) $(GSS_DEPLIBS) KADM_COMM_DEPLIBS = $(GSSRPC_DEPLIBS) $(KDB5_DEPLIBS) $(GSSRPC_DEPLIBS) KADMSRV_DEPLIBS = $(KADMSRV_DEPLIB) $(KDB5_DEPLIBS) $(KADM_COMM_DEPLIBS) KADMCLNT_DEPLIBS = $(KADMCLNT_DEPLIB) $(KADM_COMM_DEPLIBS) # Header file dependencies we might override. # See util/depfix.sed. # Also see depend-verify-* in post.in, which wants to confirm that we're using # the in-tree versions. COM_ERR_VERSION = @COM_ERR_VERSION@ COM_ERR_DEPS = $(COM_ERR_DEPS-@COM_ERR_VERSION@) COM_ERR_DEPS-sys = COM_ERR_DEPS-intlsys = COM_ERR_DEPS-k5 = $(BUILDTOP)/include/com_err.h SS_VERSION = @SS_VERSION@ SS_DEPS = $(SS_DEPS-@SS_VERSION@) SS_DEPS-sys = SS_DEPS-k5 = $(BUILDTOP)/include/ss/ss.h $(BUILDTOP)/include/ss/ss_err.h VERTO_VERSION = @VERTO_VERSION@ VERTO_DEPS = $(VERTO_DEPS-@VERTO_VERSION@) VERTO_DEPS-sys = VERTO_DEPS-k5 = $(BUILDTOP)/include/verto.h # LIBS gets substituted in... e.g. -lnsl -lsocket # GEN_LIB is -lgen if needed for regexp GEN_LIB = @GEN_LIB@ # Editline or readline flags and libraries. RL_CFLAGS = @RL_CFLAGS@ RL_LIBS = @RL_LIBS@ SS_LIB = $(SS_LIB-@SS_VERSION@) SS_LIB-sys = @SS_LIB@ SS_LIB-k5 = $(TOPLIBD)/libss.a $(RL_LIBS) KDB5_LIB = -lkdb5 $(KDB5_PLUGIN_LIBS) VERTO_DEPLIB = $(VERTO_DEPLIB-@VERTO_VERSION@) VERTO_DEPLIB-sys = # empty VERTO_DEPLIB-k5 = $(TOPLIBD)/libverto$(DEPLIBEXT) VERTO_CFLAGS = @VERTO_CFLAGS@ VERTO_LIBS = @VERTO_LIBS@ DL_LIB = @DL_LIB@ CMOCKA_LIBS = @CMOCKA_LIBS@ LDAP_LIBS = @LDAP_LIBS@ KRB5_LIB = -lkrb5 K5CRYPTO_LIB = -lk5crypto COM_ERR_LIB = -lcom_err GSS_KRB5_LIB = -lgssapi_krb5 SUPPORT_LIB = -l$(SUPPORT_LIBNAME) # HESIOD_LIBS is -lhesiod... HESIOD_LIBS = @HESIOD_LIBS@ KRB5_BASE_LIBS = $(KRB5_LIB) $(K5CRYPTO_LIB) $(COM_ERR_LIB) $(SUPPORT_LIB) $(GEN_LIB) $(LIBS) $(DL_LIB) KDB5_LIBS = $(KDB5_LIB) $(GSSRPC_LIBS) GSS_LIBS = $(GSS_KRB5_LIB) # needs fixing if ever used on macOS! GSSRPC_LIBS = -lgssrpc $(GSS_LIBS) KADM_COMM_LIBS = $(GSSRPC_LIBS) # need fixing if ever used on macOS! KADMSRV_LIBS = -lkadm5srv_mit $(HESIOD_LIBS) $(KDB5_LIBS) $(KADM_COMM_LIBS) KADMCLNT_LIBS = -lkadm5clnt_mit $(KADM_COMM_LIBS) # Misc stuff for linking server programs (and maybe some others, # eventually) but which we don't want to install. APPUTILS_LIB = -lapputils # So test programs can find their libraries without "make install", etc. RUN_SETUP=@KRB5_RUN_ENV@ RUN_VARS=@KRB5_RUN_VARS@ # Appropriate command prefix for most C test programs: use libraries # from the build tree, avoid referencing the installed krb5.conf and # message catalog, and use valgrind when asked. RUN_TEST=$(RUN_SETUP) KRB5_CONFIG=$(top_srcdir)/config-files/krb5.conf \ LC_ALL=C $(VALGRIND) # # variables for --with-tcl= TCL_LIBS = @TCL_LIBS@ TCL_LIBPATH = @TCL_LIBPATH@ TCL_RPATH = @TCL_RPATH@ TCL_MAYBE_RPATH = @TCL_MAYBE_RPATH@ TCL_INCLUDES = @TCL_INCLUDES@ # Crypto and PRNG back-end selections CRYPTO_IMPL = @CRYPTO_IMPL@ PRNG_ALG = @PRNG_ALG@ # TLS implementation selection TLS_IMPL = @TLS_IMPL@ TLS_IMPL_CFLAGS = @TLS_IMPL_CFLAGS@ TLS_IMPL_LIBS = @TLS_IMPL_LIBS@ # Whether we have the SASL header file for the LDAP KDB module HAVE_SASL = @HAVE_SASL@ # Whether we have libresolv 1.1.5 for URI discovery tests HAVE_RESOLV_WRAPPER = @HAVE_RESOLV_WRAPPER@ SIZEOF_TIME_T = @SIZEOF_TIME_T@ # error table rules # ### /* these are invoked as $(...) foo.et, which works, but could be better */ COMPILE_ET= $(COMPILE_ET-@COM_ERR_VERSION@) COMPILE_ET-sys= compile_et COMPILE_ET-intlsys= compile_et --textdomain mit-krb5 COMPILE_ET-k5= $(BUILDTOP)/util/et/compile_et -d $(top_srcdir)/util/et \ --textdomain mit-krb5 .SUFFIXES: .h .c .et .ct # These versions cause both .c and .h files to be generated at once. # But GNU make doesn't understand this, and parallel builds can trigger # both of them at once, causing them to stomp on each other. The versions # below only update one of the files, so compile_et has to get run twice, # but it won't break parallel builds. #.et.h: ; $(COMPILE_ET) $< #.et.c: ; $(COMPILE_ET) $< .et.h: $(RM) et-h-$*.et et-h-$*.c et-h-$*.h $(CP) $< et-h-$*.et $(COMPILE_ET) et-h-$*.et $(MV) et-h-$*.h $*.h $(RM) et-h-$*.et et-h-$*.c .et.c: $(RM) et-c-$*.et et-c-$*.c et-c-$*.h $(CP) $< et-c-$*.et $(COMPILE_ET) et-c-$*.et $(MV) et-c-$*.c $*.c $(RM) et-c-$*.et et-c-$*.h # rule to make object files # .SUFFIXES: .cpp .c .o .c.o: $(CC) $(ALL_CFLAGS) -c $< # Use .cpp because that's what autoconf uses in its test. # If the compiler doesn't accept a .cpp suffix here, it wouldn't # have accepted it when autoconf tested it. .cpp.o: $(CXX) $(ALL_CXXFLAGS) -c $< # ss command table rules # MAKE_COMMANDS= $(MAKE_COMMANDS-@SS_VERSION@) MAKE_COMMANDS-sys= mk_cmds MAKE_COMMANDS-k5= $(BUILDTOP)/util/ss/mk_cmds .ct.c: $(MAKE_COMMANDS) $< ## Parameters to be set by configure for use in lib.in: ## # # These settings are for building shared libraries only. Including # libpriv.in will override with values appropriate for static # libraries that we don't install. Some values will depend on whether # the platform supports major and minor version number extensions on # shared libraries, hence the FOO_@@ settings. LN_S=@LN_S@ AR=@AR@ # Set to "lib$(LIBBASE)$(STLIBEXT) lib$(LIBBASE)$(SHLIBEXT)" or some # subset thereof by configure; determines which types of libs get # built. LIBLIST=@LIBLIST@ # Set by configure; list of library symlinks to make to $(TOPLIBD) LIBLINKS=@LIBLINKS@ # Set by configure; name of plugin module to build (libfoo.a or foo.so) PLUGIN=@PLUGIN@ # Set by configure; symlink for plugin module for static plugin linking PLUGINLINK=@PLUGINLINK@ # Set by configure; list of install targets for libraries LIBINSTLIST=@LIBINSTLIST@ # Set by configure; install target PLUGININST=@PLUGININST@ # Some of these should really move to pre.in, since programs will need # it too. (e.g. stuff that has dependencies on the libraries) # usually .a STLIBEXT=@STLIBEXT@ # usually .so.$(LIBMAJOR).$(LIBMINOR) SHLIBVEXT=@SHLIBVEXT@ # usually .so.$(LIBMAJOR) (to allow for major-version compat) SHLIBSEXT=@SHLIBSEXT@ # usually .so SHLIBEXT=@SHLIBEXT@ # usually _p.a PFLIBEXT=@PFLIBEXT@ # DYNOBJEXT=@DYNOBJEXT@ MAKE_DYNOBJ_COMMAND=@MAKE_DYNOBJ_COMMAND@ DYNOBJ_EXPDEPS=@DYNOBJ_EXPDEPS@ DYNOBJ_EXPFLAGS=@DYNOBJ_EXPFLAGS@ # For some platforms, a flag which causes shared library creation to # check for undefined symbols. Suppressed when using --enable-asan. UNDEF_CHECK=@UNDEF_CHECK@ # File with symbol names to be exported, both functions and data, # currently not distinguished. SHLIB_EXPORT_FILE=$(srcdir)/$(LIBPREFIX)$(LIBBASE).exports # File that needs to be current for building the shared library, # usually SHLIB_EXPORT_FILE, but not always, if we have to convert # it to another, intermediate form for the linker. SHLIB_EXPORT_FILE_DEP=@SHLIB_EXPORT_FILE_DEP@ # Export file checker to run when building in maintainer mode on # Linux. This gets included in LDCOMBINE_TAIL. EXPORT_CHECK_CMD = && $(PERL) -w $(top_srcdir)/util/export-check.pl \ $(SHLIB_EXPORT_FILE) $@ EXPORT_CHECK = @MAINT@ $(EXPORT_CHECK_CMD) # Command to run to build a shared library. # In systems that require multiple commands, like AIX, it may need # to change to rearrange where the various parameters fit in. MAKE_SHLIB_COMMAND=@MAKE_SHLIB_COMMAND@ # run path flags for explicit libraries depending on this one, # e.g. "-R$(SHLIB_RPATH)" SHLIB_RPATH_FLAGS=@SHLIB_RPATH_FLAGS@ # flags for explicit libraries depending on this one, # e.g. "$(SHLIB_RPATH_FLAGS) $(SHLIB_SHLIB_DIRFLAGS) $(SHLIB_EXPLIBS)" SHLIB_EXPFLAGS=@SHLIB_EXPFLAGS@ ## Parameters to be set by configure for use in libobj.in: # Set to "OBJS.ST OBJS.SH OBJS.PF" or some subset thereof by # configure; determines which types of object files get built. OBJLISTS=@OBJLISTS@ # Note that $(LIBSRCS) *cannot* contain any variable references, or # the suffix substitution will break on some platforms! SHLIBOBJS=$(STLIBOBJS:.o=@SHOBJEXT@) PFLIBOBJS=$(STLIBOBJS:.o=@PFOBJEXT@) # # rules to make various types of object files # PICFLAGS=@PICFLAGS@ PROFFLAGS=@PROFFLAGS@ # platform-dependent temporary files that should get cleaned up EXTRA_FILES=@EXTRA_FILES@ VALGRIND= # Need absolute paths here because under kshd or ftpd we may run programs # while in other directories. VALGRIND_LOGDIR = `cd $(BUILDTOP)&&pwd` VALGRIND1 = valgrind --tool=memcheck --log-file=$(VALGRIND_LOGDIR)/vg.%p --trace-children=yes --leak-check=yes --suppressions=`cd $(top_srcdir)&&pwd`/util/valgrind-suppressions # Set OFFLINE=yes to disable tests that assume network connectivity. # (Specifically, this concerns the ability to fetch DNS data for # mit.edu, to verify that SRV queries are working.) Note that other # tests still assume that the local hostname can be resolved into # something that looks like an FQDN, with an IPv4 address. OFFLINE=no # Used when running Python tests. PYTESTFLAGS= ## ## end of pre.in ############################################################ krb5-1.16/src/config/libnodeps.in0000644000704600001450000000026313211554426016542 0ustar ghudsonlibuuid# Must override when there are no dependencies, because on some # platforms there's a prefix stuck in front of the library path that # we won't set (SHLIB_RDIRS). SHLIB_EXPFLAGS= krb5-1.16/src/config/config.sub0000755000704600001450000010752413211554426016226 0ustar ghudsonlibuuid#! /bin/sh # Configuration validation subroutine script. # Copyright 1992-2017 Free Software Foundation, Inc. timestamp='2017-11-23' # This file is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # 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. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, see . # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that # program. This Exception is an additional permission under section 7 # of the GNU General Public License, version 3 ("GPLv3"). # Please send patches to . # # Configuration subroutine to validate and canonicalize a configuration type. # Supply the specified configuration type as an argument. # If it is invalid, we print an error message on stderr and exit with code 1. # Otherwise, we print the canonical config type on stdout and succeed. # You can get the latest version of this script from: # https://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub # This file is supposed to be the same for all GNU packages # and recognize all the CPU types, system types and aliases # that are meaningful with *any* GNU software. # Each package is responsible for reporting which valid configurations # it does not support. The user should be able to distinguish # a failure to support a valid configuration from a meaningless # configuration. # The goal of this file is to map all the various variations of a given # machine specification into a single specification in the form: # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM # or in some cases, the newer four-part form: # CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM # It is wrong to echo any other type of specification. me=`echo "$0" | sed -e 's,.*/,,'` usage="\ Usage: $0 [OPTION] CPU-MFR-OPSYS or ALIAS Canonicalize a configuration name. Options: -h, --help print this help, then exit -t, --time-stamp print date of last modification, then exit -v, --version print version number, then exit Report bugs and patches to ." version="\ GNU config.sub ($timestamp) Copyright 1992-2017 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." help=" Try \`$me --help' for more information." # Parse command line while test $# -gt 0 ; do case $1 in --time-stamp | --time* | -t ) echo "$timestamp" ; exit ;; --version | -v ) echo "$version" ; exit ;; --help | --h* | -h ) echo "$usage"; exit ;; -- ) # Stop option processing shift; break ;; - ) # Use stdin as input. break ;; -* ) echo "$me: invalid option $1$help" exit 1 ;; *local*) # First pass through any local machine types. echo $1 exit ;; * ) break ;; esac done case $# in 0) echo "$me: missing argument$help" >&2 exit 1;; 1) ;; *) echo "$me: too many arguments$help" >&2 exit 1;; esac # Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). # Here we must recognize all the valid KERNEL-OS combinations. maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` case $maybe_os in nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \ linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \ knetbsd*-gnu* | netbsd*-gnu* | netbsd*-eabi* | \ kopensolaris*-gnu* | cloudabi*-eabi* | \ storm-chaos* | os2-emx* | rtmk-nova*) os=-$maybe_os basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` ;; android-linux) os=-linux-android basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`-unknown ;; *) basic_machine=`echo $1 | sed 's/-[^-]*$//'` if [ $basic_machine != $1 ] then os=`echo $1 | sed 's/.*-/-/'` else os=; fi ;; esac ### Let's recognize common machines as not being operating systems so ### that things like config.sub decstation-3100 work. We also ### recognize some manufacturers as not being operating systems, so we ### can provide default operating systems below. case $os in -sun*os*) # Prevent following clause from handling this invalid input. ;; -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \ -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \ -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ -apple | -axis | -knuth | -cray | -microblaze*) os= basic_machine=$1 ;; -bluegene*) os=-cnk ;; -sim | -cisco | -oki | -wec | -winbond) os= basic_machine=$1 ;; -scout) ;; -wrs) os=-vxworks basic_machine=$1 ;; -chorusos*) os=-chorusos basic_machine=$1 ;; -chorusrdb) os=-chorusrdb basic_machine=$1 ;; -hiux*) os=-hiuxwe2 ;; -sco6) os=-sco5v6 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco5) os=-sco3.2v5 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco4) os=-sco3.2v4 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco3.2.[4-9]*) os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco3.2v[4-9]*) # Don't forget version if it is 3.2v4 or newer. basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco5v6*) # Don't forget version if it is 3.2v4 or newer. basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco*) os=-sco3.2v2 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -udk*) basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -isc) os=-isc2.2 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -clix*) basic_machine=clipper-intergraph ;; -isc*) basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -lynx*178) os=-lynxos178 ;; -lynx*5) os=-lynxos5 ;; -lynx*) os=-lynxos ;; -ptx*) basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` ;; -psos*) os=-psos ;; -mint | -mint[0-9]*) basic_machine=m68k-atari os=-mint ;; esac # Decode aliases for certain CPU-COMPANY combinations. case $basic_machine in # Recognize the basic CPU types without company name. # Some are omitted here because they have special meanings below. 1750a | 580 \ | a29k \ | aarch64 | aarch64_be \ | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ | am33_2.0 \ | arc | arceb \ | arm | arm[bl]e | arme[lb] | armv[2-8] | armv[3-8][lb] | armv7[arm] \ | avr | avr32 \ | ba \ | be32 | be64 \ | bfin \ | c4x | c8051 | clipper \ | d10v | d30v | dlx | dsp16xx \ | e2k | epiphany \ | fido | fr30 | frv | ft32 \ | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ | hexagon \ | i370 | i860 | i960 | ia16 | ia64 \ | ip2k | iq2000 \ | k1om \ | le32 | le64 \ | lm32 \ | m32c | m32r | m32rle | m68000 | m68k | m88k \ | maxq | mb | microblaze | microblazeel | mcore | mep | metag \ | mips | mipsbe | mipseb | mipsel | mipsle \ | mips16 \ | mips64 | mips64el \ | mips64octeon | mips64octeonel \ | mips64orion | mips64orionel \ | mips64r5900 | mips64r5900el \ | mips64vr | mips64vrel \ | mips64vr4100 | mips64vr4100el \ | mips64vr4300 | mips64vr4300el \ | mips64vr5000 | mips64vr5000el \ | mips64vr5900 | mips64vr5900el \ | mipsisa32 | mipsisa32el \ | mipsisa32r2 | mipsisa32r2el \ | mipsisa32r6 | mipsisa32r6el \ | mipsisa64 | mipsisa64el \ | mipsisa64r2 | mipsisa64r2el \ | mipsisa64r6 | mipsisa64r6el \ | mipsisa64sb1 | mipsisa64sb1el \ | mipsisa64sr71k | mipsisa64sr71kel \ | mipsr5900 | mipsr5900el \ | mipstx39 | mipstx39el \ | mn10200 | mn10300 \ | moxie \ | mt \ | msp430 \ | nds32 | nds32le | nds32be \ | nios | nios2 | nios2eb | nios2el \ | ns16k | ns32k \ | open8 | or1k | or1knd | or32 \ | pdp10 | pdp11 | pj | pjl \ | powerpc | powerpc64 | powerpc64le | powerpcle \ | pru \ | pyramid \ | riscv32 | riscv64 \ | rl78 | rx \ | score \ | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[234]eb | sheb | shbe | shle | sh[1234]le | sh3ele \ | sh64 | sh64le \ | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \ | sparcv8 | sparcv9 | sparcv9b | sparcv9v \ | spu \ | tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \ | ubicom32 \ | v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \ | visium \ | wasm32 \ | x86 | xc16x | xstormy16 | xtensa \ | z8k | z80) basic_machine=$basic_machine-unknown ;; c54x) basic_machine=tic54x-unknown ;; c55x) basic_machine=tic55x-unknown ;; c6x) basic_machine=tic6x-unknown ;; leon|leon[3-9]) basic_machine=sparc-$basic_machine ;; m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | nvptx | picochip) basic_machine=$basic_machine-unknown os=-none ;; m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) ;; ms1) basic_machine=mt-unknown ;; strongarm | thumb | xscale) basic_machine=arm-unknown ;; xgate) basic_machine=$basic_machine-unknown os=-none ;; xscaleeb) basic_machine=armeb-unknown ;; xscaleel) basic_machine=armel-unknown ;; # We use `pc' rather than `unknown' # because (1) that's what they normally are, and # (2) the word "unknown" tends to confuse beginning users. i*86 | x86_64) basic_machine=$basic_machine-pc ;; # Object if more than one company name word. *-*-*) echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 exit 1 ;; # Recognize the basic CPU types with company name. 580-* \ | a29k-* \ | aarch64-* | aarch64_be-* \ | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ | alphapca5[67]-* | alpha64pca5[67]-* | arc-* | arceb-* \ | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ | avr-* | avr32-* \ | ba-* \ | be32-* | be64-* \ | bfin-* | bs2000-* \ | c[123]* | c30-* | [cjt]90-* | c4x-* \ | c8051-* | clipper-* | craynv-* | cydra-* \ | d10v-* | d30v-* | dlx-* \ | e2k-* | elxsi-* \ | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \ | h8300-* | h8500-* \ | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ | hexagon-* \ | i*86-* | i860-* | i960-* | ia16-* | ia64-* \ | ip2k-* | iq2000-* \ | k1om-* \ | le32-* | le64-* \ | lm32-* \ | m32c-* | m32r-* | m32rle-* \ | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ | m88110-* | m88k-* | maxq-* | mcore-* | metag-* \ | microblaze-* | microblazeel-* \ | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ | mips16-* \ | mips64-* | mips64el-* \ | mips64octeon-* | mips64octeonel-* \ | mips64orion-* | mips64orionel-* \ | mips64r5900-* | mips64r5900el-* \ | mips64vr-* | mips64vrel-* \ | mips64vr4100-* | mips64vr4100el-* \ | mips64vr4300-* | mips64vr4300el-* \ | mips64vr5000-* | mips64vr5000el-* \ | mips64vr5900-* | mips64vr5900el-* \ | mipsisa32-* | mipsisa32el-* \ | mipsisa32r2-* | mipsisa32r2el-* \ | mipsisa32r6-* | mipsisa32r6el-* \ | mipsisa64-* | mipsisa64el-* \ | mipsisa64r2-* | mipsisa64r2el-* \ | mipsisa64r6-* | mipsisa64r6el-* \ | mipsisa64sb1-* | mipsisa64sb1el-* \ | mipsisa64sr71k-* | mipsisa64sr71kel-* \ | mipsr5900-* | mipsr5900el-* \ | mipstx39-* | mipstx39el-* \ | mmix-* \ | mt-* \ | msp430-* \ | nds32-* | nds32le-* | nds32be-* \ | nios-* | nios2-* | nios2eb-* | nios2el-* \ | none-* | np1-* | ns16k-* | ns32k-* \ | open8-* \ | or1k*-* \ | orion-* \ | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \ | pru-* \ | pyramid-* \ | riscv32-* | riscv64-* \ | rl78-* | romp-* | rs6000-* | rx-* \ | sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \ | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \ | sparclite-* \ | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx*-* \ | tahoe-* \ | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \ | tile*-* \ | tron-* \ | ubicom32-* \ | v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \ | vax-* \ | visium-* \ | wasm32-* \ | we32k-* \ | x86-* | x86_64-* | xc16x-* | xps100-* \ | xstormy16-* | xtensa*-* \ | ymp-* \ | z8k-* | z80-*) ;; # Recognize the basic CPU types without company name, with glob match. xtensa*) basic_machine=$basic_machine-unknown ;; # Recognize the various machine names and aliases which stand # for a CPU type and a company and sometimes even an OS. 386bsd) basic_machine=i386-unknown os=-bsd ;; 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) basic_machine=m68000-att ;; 3b*) basic_machine=we32k-att ;; a29khif) basic_machine=a29k-amd os=-udi ;; abacus) basic_machine=abacus-unknown ;; adobe68k) basic_machine=m68010-adobe os=-scout ;; alliant | fx80) basic_machine=fx80-alliant ;; altos | altos3068) basic_machine=m68k-altos ;; am29k) basic_machine=a29k-none os=-bsd ;; amd64) basic_machine=x86_64-pc ;; amd64-*) basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'` ;; amdahl) basic_machine=580-amdahl os=-sysv ;; amiga | amiga-*) basic_machine=m68k-unknown ;; amigaos | amigados) basic_machine=m68k-unknown os=-amigaos ;; amigaunix | amix) basic_machine=m68k-unknown os=-sysv4 ;; apollo68) basic_machine=m68k-apollo os=-sysv ;; apollo68bsd) basic_machine=m68k-apollo os=-bsd ;; aros) basic_machine=i386-pc os=-aros ;; asmjs) basic_machine=asmjs-unknown ;; aux) basic_machine=m68k-apple os=-aux ;; balance) basic_machine=ns32k-sequent os=-dynix ;; blackfin) basic_machine=bfin-unknown os=-linux ;; blackfin-*) basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'` os=-linux ;; bluegene*) basic_machine=powerpc-ibm os=-cnk ;; c54x-*) basic_machine=tic54x-`echo $basic_machine | sed 's/^[^-]*-//'` ;; c55x-*) basic_machine=tic55x-`echo $basic_machine | sed 's/^[^-]*-//'` ;; c6x-*) basic_machine=tic6x-`echo $basic_machine | sed 's/^[^-]*-//'` ;; c90) basic_machine=c90-cray os=-unicos ;; cegcc) basic_machine=arm-unknown os=-cegcc ;; convex-c1) basic_machine=c1-convex os=-bsd ;; convex-c2) basic_machine=c2-convex os=-bsd ;; convex-c32) basic_machine=c32-convex os=-bsd ;; convex-c34) basic_machine=c34-convex os=-bsd ;; convex-c38) basic_machine=c38-convex os=-bsd ;; cray | j90) basic_machine=j90-cray os=-unicos ;; craynv) basic_machine=craynv-cray os=-unicosmp ;; cr16 | cr16-*) basic_machine=cr16-unknown os=-elf ;; crds | unos) basic_machine=m68k-crds ;; crisv32 | crisv32-* | etraxfs*) basic_machine=crisv32-axis ;; cris | cris-* | etrax*) basic_machine=cris-axis ;; crx) basic_machine=crx-unknown os=-elf ;; da30 | da30-*) basic_machine=m68k-da30 ;; decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) basic_machine=mips-dec ;; decsystem10* | dec10*) basic_machine=pdp10-dec os=-tops10 ;; decsystem20* | dec20*) basic_machine=pdp10-dec os=-tops20 ;; delta | 3300 | motorola-3300 | motorola-delta \ | 3300-motorola | delta-motorola) basic_machine=m68k-motorola ;; delta88) basic_machine=m88k-motorola os=-sysv3 ;; dicos) basic_machine=i686-pc os=-dicos ;; djgpp) basic_machine=i586-pc os=-msdosdjgpp ;; dpx20 | dpx20-*) basic_machine=rs6000-bull os=-bosx ;; dpx2*) basic_machine=m68k-bull os=-sysv3 ;; e500v[12]) basic_machine=powerpc-unknown os=$os"spe" ;; e500v[12]-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` os=$os"spe" ;; ebmon29k) basic_machine=a29k-amd os=-ebmon ;; elxsi) basic_machine=elxsi-elxsi os=-bsd ;; encore | umax | mmax) basic_machine=ns32k-encore ;; es1800 | OSE68k | ose68k | ose | OSE) basic_machine=m68k-ericsson os=-ose ;; fx2800) basic_machine=i860-alliant ;; genix) basic_machine=ns32k-ns ;; gmicro) basic_machine=tron-gmicro os=-sysv ;; go32) basic_machine=i386-pc os=-go32 ;; h3050r* | hiux*) basic_machine=hppa1.1-hitachi os=-hiuxwe2 ;; h8300hms) basic_machine=h8300-hitachi os=-hms ;; h8300xray) basic_machine=h8300-hitachi os=-xray ;; h8500hms) basic_machine=h8500-hitachi os=-hms ;; harris) basic_machine=m88k-harris os=-sysv3 ;; hp300-*) basic_machine=m68k-hp ;; hp300bsd) basic_machine=m68k-hp os=-bsd ;; hp300hpux) basic_machine=m68k-hp os=-hpux ;; hp3k9[0-9][0-9] | hp9[0-9][0-9]) basic_machine=hppa1.0-hp ;; hp9k2[0-9][0-9] | hp9k31[0-9]) basic_machine=m68000-hp ;; hp9k3[2-9][0-9]) basic_machine=m68k-hp ;; hp9k6[0-9][0-9] | hp6[0-9][0-9]) basic_machine=hppa1.0-hp ;; hp9k7[0-79][0-9] | hp7[0-79][0-9]) basic_machine=hppa1.1-hp ;; hp9k78[0-9] | hp78[0-9]) # FIXME: really hppa2.0-hp basic_machine=hppa1.1-hp ;; hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) # FIXME: really hppa2.0-hp basic_machine=hppa1.1-hp ;; hp9k8[0-9][13679] | hp8[0-9][13679]) basic_machine=hppa1.1-hp ;; hp9k8[0-9][0-9] | hp8[0-9][0-9]) basic_machine=hppa1.0-hp ;; hppa-next) os=-nextstep3 ;; hppaosf) basic_machine=hppa1.1-hp os=-osf ;; hppro) basic_machine=hppa1.1-hp os=-proelf ;; i370-ibm* | ibm*) basic_machine=i370-ibm ;; i*86v32) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv32 ;; i*86v4*) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv4 ;; i*86v) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv ;; i*86sol2) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-solaris2 ;; i386mach) basic_machine=i386-mach os=-mach ;; i386-vsta | vsta) basic_machine=i386-unknown os=-vsta ;; iris | iris4d) basic_machine=mips-sgi case $os in -irix*) ;; *) os=-irix4 ;; esac ;; isi68 | isi) basic_machine=m68k-isi os=-sysv ;; leon-*|leon[3-9]-*) basic_machine=sparc-`echo $basic_machine | sed 's/-.*//'` ;; m68knommu) basic_machine=m68k-unknown os=-linux ;; m68knommu-*) basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'` os=-linux ;; m88k-omron*) basic_machine=m88k-omron ;; magnum | m3230) basic_machine=mips-mips os=-sysv ;; merlin) basic_machine=ns32k-utek os=-sysv ;; microblaze*) basic_machine=microblaze-xilinx ;; mingw64) basic_machine=x86_64-pc os=-mingw64 ;; mingw32) basic_machine=i686-pc os=-mingw32 ;; mingw32ce) basic_machine=arm-unknown os=-mingw32ce ;; miniframe) basic_machine=m68000-convergent ;; *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*) basic_machine=m68k-atari os=-mint ;; mips3*-*) basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` ;; mips3*) basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown ;; monitor) basic_machine=m68k-rom68k os=-coff ;; morphos) basic_machine=powerpc-unknown os=-morphos ;; moxiebox) basic_machine=moxie-unknown os=-moxiebox ;; msdos) basic_machine=i386-pc os=-msdos ;; ms1-*) basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'` ;; msys) basic_machine=i686-pc os=-msys ;; mvs) basic_machine=i370-ibm os=-mvs ;; nacl) basic_machine=le32-unknown os=-nacl ;; ncr3000) basic_machine=i486-ncr os=-sysv4 ;; netbsd386) basic_machine=i386-unknown os=-netbsd ;; netwinder) basic_machine=armv4l-rebel os=-linux ;; news | news700 | news800 | news900) basic_machine=m68k-sony os=-newsos ;; news1000) basic_machine=m68030-sony os=-newsos ;; news-3600 | risc-news) basic_machine=mips-sony os=-newsos ;; necv70) basic_machine=v70-nec os=-sysv ;; next | m*-next) basic_machine=m68k-next case $os in -nextstep* ) ;; -ns2*) os=-nextstep2 ;; *) os=-nextstep3 ;; esac ;; nh3000) basic_machine=m68k-harris os=-cxux ;; nh[45]000) basic_machine=m88k-harris os=-cxux ;; nindy960) basic_machine=i960-intel os=-nindy ;; mon960) basic_machine=i960-intel os=-mon960 ;; nonstopux) basic_machine=mips-compaq os=-nonstopux ;; np1) basic_machine=np1-gould ;; neo-tandem) basic_machine=neo-tandem ;; nse-tandem) basic_machine=nse-tandem ;; nsr-tandem) basic_machine=nsr-tandem ;; nsx-tandem) basic_machine=nsx-tandem ;; op50n-* | op60c-*) basic_machine=hppa1.1-oki os=-proelf ;; openrisc | openrisc-*) basic_machine=or32-unknown ;; os400) basic_machine=powerpc-ibm os=-os400 ;; OSE68000 | ose68000) basic_machine=m68000-ericsson os=-ose ;; os68k) basic_machine=m68k-none os=-os68k ;; pa-hitachi) basic_machine=hppa1.1-hitachi os=-hiuxwe2 ;; paragon) basic_machine=i860-intel os=-osf ;; parisc) basic_machine=hppa-unknown os=-linux ;; parisc-*) basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'` os=-linux ;; pbd) basic_machine=sparc-tti ;; pbb) basic_machine=m68k-tti ;; pc532 | pc532-*) basic_machine=ns32k-pc532 ;; pc98) basic_machine=i386-pc ;; pc98-*) basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentium | p5 | k5 | k6 | nexgen | viac3) basic_machine=i586-pc ;; pentiumpro | p6 | 6x86 | athlon | athlon_*) basic_machine=i686-pc ;; pentiumii | pentium2 | pentiumiii | pentium3) basic_machine=i686-pc ;; pentium4) basic_machine=i786-pc ;; pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentiumpro-* | p6-* | 6x86-* | athlon-*) basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*) basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentium4-*) basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pn) basic_machine=pn-gould ;; power) basic_machine=power-ibm ;; ppc | ppcbe) basic_machine=powerpc-unknown ;; ppc-* | ppcbe-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ppcle | powerpclittle) basic_machine=powerpcle-unknown ;; ppcle-* | powerpclittle-*) basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ppc64) basic_machine=powerpc64-unknown ;; ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ppc64le | powerpc64little) basic_machine=powerpc64le-unknown ;; ppc64le-* | powerpc64little-*) basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ps2) basic_machine=i386-ibm ;; pw32) basic_machine=i586-unknown os=-pw32 ;; rdos | rdos64) basic_machine=x86_64-pc os=-rdos ;; rdos32) basic_machine=i386-pc os=-rdos ;; rom68k) basic_machine=m68k-rom68k os=-coff ;; rm[46]00) basic_machine=mips-siemens ;; rtpc | rtpc-*) basic_machine=romp-ibm ;; s390 | s390-*) basic_machine=s390-ibm ;; s390x | s390x-*) basic_machine=s390x-ibm ;; sa29200) basic_machine=a29k-amd os=-udi ;; sb1) basic_machine=mipsisa64sb1-unknown ;; sb1el) basic_machine=mipsisa64sb1el-unknown ;; sde) basic_machine=mipsisa32-sde os=-elf ;; sei) basic_machine=mips-sei os=-seiux ;; sequent) basic_machine=i386-sequent ;; sh) basic_machine=sh-hitachi os=-hms ;; sh5el) basic_machine=sh5le-unknown ;; sh64) basic_machine=sh64-unknown ;; sparclite-wrs | simso-wrs) basic_machine=sparclite-wrs os=-vxworks ;; sps7) basic_machine=m68k-bull os=-sysv2 ;; spur) basic_machine=spur-unknown ;; st2000) basic_machine=m68k-tandem ;; stratus) basic_machine=i860-stratus os=-sysv4 ;; strongarm-* | thumb-*) basic_machine=arm-`echo $basic_machine | sed 's/^[^-]*-//'` ;; sun2) basic_machine=m68000-sun ;; sun2os3) basic_machine=m68000-sun os=-sunos3 ;; sun2os4) basic_machine=m68000-sun os=-sunos4 ;; sun3os3) basic_machine=m68k-sun os=-sunos3 ;; sun3os4) basic_machine=m68k-sun os=-sunos4 ;; sun4os3) basic_machine=sparc-sun os=-sunos3 ;; sun4os4) basic_machine=sparc-sun os=-sunos4 ;; sun4sol2) basic_machine=sparc-sun os=-solaris2 ;; sun3 | sun3-*) basic_machine=m68k-sun ;; sun4) basic_machine=sparc-sun ;; sun386 | sun386i | roadrunner) basic_machine=i386-sun ;; sv1) basic_machine=sv1-cray os=-unicos ;; symmetry) basic_machine=i386-sequent os=-dynix ;; t3e) basic_machine=alphaev5-cray os=-unicos ;; t90) basic_machine=t90-cray os=-unicos ;; tile*) basic_machine=$basic_machine-unknown os=-linux-gnu ;; tx39) basic_machine=mipstx39-unknown ;; tx39el) basic_machine=mipstx39el-unknown ;; toad1) basic_machine=pdp10-xkl os=-tops20 ;; tower | tower-32) basic_machine=m68k-ncr ;; tpf) basic_machine=s390x-ibm os=-tpf ;; udi29k) basic_machine=a29k-amd os=-udi ;; ultra3) basic_machine=a29k-nyu os=-sym1 ;; v810 | necv810) basic_machine=v810-nec os=-none ;; vaxv) basic_machine=vax-dec os=-sysv ;; vms) basic_machine=vax-dec os=-vms ;; vpp*|vx|vx-*) basic_machine=f301-fujitsu ;; vxworks960) basic_machine=i960-wrs os=-vxworks ;; vxworks68) basic_machine=m68k-wrs os=-vxworks ;; vxworks29k) basic_machine=a29k-wrs os=-vxworks ;; wasm32) basic_machine=wasm32-unknown ;; w65*) basic_machine=w65-wdc os=-none ;; w89k-*) basic_machine=hppa1.1-winbond os=-proelf ;; x64) basic_machine=x86_64-pc ;; xbox) basic_machine=i686-pc os=-mingw32 ;; xps | xps100) basic_machine=xps100-honeywell ;; xscale-* | xscalee[bl]-*) basic_machine=`echo $basic_machine | sed 's/^xscale/arm/'` ;; ymp) basic_machine=ymp-cray os=-unicos ;; z8k-*-coff) basic_machine=z8k-unknown os=-sim ;; z80-*-coff) basic_machine=z80-unknown os=-sim ;; none) basic_machine=none-none os=-none ;; # Here we handle the default manufacturer of certain CPU types. It is in # some cases the only manufacturer, in others, it is the most popular. w89k) basic_machine=hppa1.1-winbond ;; op50n) basic_machine=hppa1.1-oki ;; op60c) basic_machine=hppa1.1-oki ;; romp) basic_machine=romp-ibm ;; mmix) basic_machine=mmix-knuth ;; rs6000) basic_machine=rs6000-ibm ;; vax) basic_machine=vax-dec ;; pdp10) # there are many clones, so DEC is not a safe bet basic_machine=pdp10-unknown ;; pdp11) basic_machine=pdp11-dec ;; we32k) basic_machine=we32k-att ;; sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele) basic_machine=sh-unknown ;; sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v) basic_machine=sparc-sun ;; cydra) basic_machine=cydra-cydrome ;; orion) basic_machine=orion-highlevel ;; orion105) basic_machine=clipper-highlevel ;; mac | mpw | mac-mpw) basic_machine=m68k-apple ;; pmac | pmac-mpw) basic_machine=powerpc-apple ;; *-unknown) # Make sure to match an already-canonicalized machine name. ;; *) echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 exit 1 ;; esac # Here we canonicalize certain aliases for manufacturers. case $basic_machine in *-digital*) basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` ;; *-commodore*) basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` ;; *) ;; esac # Decode manufacturer-specific aliases for certain operating systems. if [ x"$os" != x"" ] then case $os in # First match some system type aliases that might get confused # with valid system types. # -solaris* is a basic system type, with this one exception. -auroraux) os=-auroraux ;; -solaris1 | -solaris1.*) os=`echo $os | sed -e 's|solaris1|sunos4|'` ;; -solaris) os=-solaris2 ;; -svr4*) os=-sysv4 ;; -unixware*) os=-sysv4.2uw ;; -gnu/linux*) os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` ;; # Now accept the basic system types. # The portable systems comes first. # Each alternative MUST end in a * to match a version number. # -sysv* is not here because it comes later, after sysvr4. -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ | -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\ | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \ | -sym* | -kopensolaris* | -plan9* \ | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ | -aos* | -aros* | -cloudabi* | -sortix* \ | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \ | -bitrig* | -openbsd* | -solidbsd* | -libertybsd* \ | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \ | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ | -chorusos* | -chorusrdb* | -cegcc* | -glidix* \ | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ | -midipix* | -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \ | -linux-newlib* | -linux-musl* | -linux-uclibc* \ | -uxpv* | -beos* | -mpeix* | -udk* | -moxiebox* \ | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \ | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \ | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \ | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es* \ | -onefs* | -tirtos* | -phoenix* | -fuchsia* | -redox*) # Remember, each alternative MUST END IN *, to match a version number. ;; -qnx*) case $basic_machine in x86-* | i*86-*) ;; *) os=-nto$os ;; esac ;; -nto-qnx*) ;; -nto*) os=`echo $os | sed -e 's|nto|nto-qnx|'` ;; -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \ | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) ;; -mac*) os=`echo $os | sed -e 's|mac|macos|'` ;; -linux-dietlibc) os=-linux-dietlibc ;; -linux*) os=`echo $os | sed -e 's|linux|linux-gnu|'` ;; -sunos5*) os=`echo $os | sed -e 's|sunos5|solaris2|'` ;; -sunos6*) os=`echo $os | sed -e 's|sunos6|solaris3|'` ;; -opened*) os=-openedition ;; -os400*) os=-os400 ;; -wince*) os=-wince ;; -osfrose*) os=-osfrose ;; -osf*) os=-osf ;; -utek*) os=-bsd ;; -dynix*) os=-bsd ;; -acis*) os=-aos ;; -atheos*) os=-atheos ;; -syllable*) os=-syllable ;; -386bsd) os=-bsd ;; -ctix* | -uts*) os=-sysv ;; -nova*) os=-rtmk-nova ;; -ns2) os=-nextstep2 ;; -nsk*) os=-nsk ;; # Preserve the version number of sinix5. -sinix5.*) os=`echo $os | sed -e 's|sinix|sysv|'` ;; -sinix*) os=-sysv4 ;; -tpf*) os=-tpf ;; -triton*) os=-sysv3 ;; -oss*) os=-sysv3 ;; -svr4) os=-sysv4 ;; -svr3) os=-sysv3 ;; -sysvr4) os=-sysv4 ;; # This must come after -sysvr4. -sysv*) ;; -ose*) os=-ose ;; -es1800*) os=-ose ;; -xenix) os=-xenix ;; -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) os=-mint ;; -aros*) os=-aros ;; -zvmoe) os=-zvmoe ;; -dicos*) os=-dicos ;; -pikeos*) # Until real need of OS specific support for # particular features comes up, bare metal # configurations are quite functional. case $basic_machine in arm*) os=-eabi ;; *) os=-elf ;; esac ;; -nacl*) ;; -ios) ;; -none) ;; *) # Get rid of the `-' at the beginning of $os. os=`echo $os | sed 's/[^-]*-//'` echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2 exit 1 ;; esac else # Here we handle the default operating systems that come with various machines. # The value should be what the vendor currently ships out the door with their # machine or put another way, the most popular os provided with the machine. # Note that if you're going to try to match "-MANUFACTURER" here (say, # "-sun"), then you have to tell the case statement up towards the top # that MANUFACTURER isn't an operating system. Otherwise, code above # will signal an error saying that MANUFACTURER isn't an operating # system, and we'll never get to this point. case $basic_machine in score-*) os=-elf ;; spu-*) os=-elf ;; *-acorn) os=-riscix1.2 ;; arm*-rebel) os=-linux ;; arm*-semi) os=-aout ;; c4x-* | tic4x-*) os=-coff ;; c8051-*) os=-elf ;; hexagon-*) os=-elf ;; tic54x-*) os=-coff ;; tic55x-*) os=-coff ;; tic6x-*) os=-coff ;; # This must come before the *-dec entry. pdp10-*) os=-tops20 ;; pdp11-*) os=-none ;; *-dec | vax-*) os=-ultrix4.2 ;; m68*-apollo) os=-domain ;; i386-sun) os=-sunos4.0.2 ;; m68000-sun) os=-sunos3 ;; m68*-cisco) os=-aout ;; mep-*) os=-elf ;; mips*-cisco) os=-elf ;; mips*-*) os=-elf ;; or32-*) os=-coff ;; *-tti) # must be before sparc entry or we get the wrong os. os=-sysv3 ;; sparc-* | *-sun) os=-sunos4.1.1 ;; pru-*) os=-elf ;; *-be) os=-beos ;; *-haiku) os=-haiku ;; *-ibm) os=-aix ;; *-knuth) os=-mmixware ;; *-wec) os=-proelf ;; *-winbond) os=-proelf ;; *-oki) os=-proelf ;; *-hp) os=-hpux ;; *-hitachi) os=-hiux ;; i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) os=-sysv ;; *-cbm) os=-amigaos ;; *-dg) os=-dgux ;; *-dolphin) os=-sysv3 ;; m68k-ccur) os=-rtu ;; m88k-omron*) os=-luna ;; *-next) os=-nextstep ;; *-sequent) os=-ptx ;; *-crds) os=-unos ;; *-ns) os=-genix ;; i370-*) os=-mvs ;; *-next) os=-nextstep3 ;; *-gould) os=-sysv ;; *-highlevel) os=-bsd ;; *-encore) os=-bsd ;; *-sgi) os=-irix ;; *-siemens) os=-sysv4 ;; *-masscomp) os=-rtu ;; f30[01]-fujitsu | f700-fujitsu) os=-uxpv ;; *-rom68k) os=-coff ;; *-*bug) os=-coff ;; *-apple) os=-macos ;; *-atari*) os=-mint ;; *) os=-none ;; esac fi # Here we handle the case where we know the os, and the CPU type, but not the # manufacturer. We pick the logical manufacturer. vendor=unknown case $basic_machine in *-unknown) case $os in -riscix*) vendor=acorn ;; -sunos*) vendor=sun ;; -cnk*|-aix*) vendor=ibm ;; -beos*) vendor=be ;; -hpux*) vendor=hp ;; -mpeix*) vendor=hp ;; -hiux*) vendor=hitachi ;; -unos*) vendor=crds ;; -dgux*) vendor=dg ;; -luna*) vendor=omron ;; -genix*) vendor=ns ;; -mvs* | -opened*) vendor=ibm ;; -os400*) vendor=ibm ;; -ptx*) vendor=sequent ;; -tpf*) vendor=ibm ;; -vxsim* | -vxworks* | -windiss*) vendor=wrs ;; -aux*) vendor=apple ;; -hms*) vendor=hitachi ;; -mpw* | -macos*) vendor=apple ;; -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) vendor=atari ;; -vos*) vendor=stratus ;; esac basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` ;; esac echo $basic_machine$os exit # Local variables: # eval: (add-hook 'write-file-functions 'time-stamp) # time-stamp-start: "timestamp='" # time-stamp-format: "%:y-%02m-%02d" # time-stamp-end: "'" # End: krb5-1.16/src/config/ren2long.awk0000644000704600001450000000345513211554426016473 0ustar ghudsonlibuuid# # Awk script to convert filenames shortened down to 8.3 # back to their larger size. # # Works by looking at every filename and seeing if it's shortened # 8.3 version exists, and if so then mv the short name to the long # name. # # Usage: find . -type f -print | gawk -f ren2long.awk | sh -x [ 2> /dev/null ] # # Parse_path # # Takes the whole path and converts the basename part to 8.3. If it # changed in the process we emit a sh command to mv it if the shortened # name exists. # function parse_path(p,P2,N,NEW) { P2 = tolower(p) NEW = "" while(1) { N = index(P2,"/") # Go until all / are parsed if (N == 0) break NEW = NEW name83(substr(P2,1,N-1)) "/"; # More of the path P2 = substr(P2,N+1) } if (bad[P2] == 1) { print "echo skipping " p return } NEW = NEW name83(P2) # Append path and 8.3 name if (bad[P2] == 2) { print "if [ -f " NEW " ]; then echo ::rm " NEW " ; rm " NEW " ; fi" return } if (NEW != p) print "if [ -f " NEW " ]; then echo ::mv " NEW " " p " ; mv " NEW " " p " ; fi" } # # Name83 # # Converts the a single component part of a file name into 8.3 format # function name83(fname,P,B,E) { P = index(fname,"."); # Find the extension if (P == 0) { # No extension B = substr(fname,1,8); # Just truncate at 8 chars return B; } B = substr(fname, 1, P <= 8 ? P-1 : 8); # At most 8 chars in name E = substr(fname, P+1, 3) # And 3 in extension P = index(E, ".") # 2 dot problem if (P) E = substr(E, 1, P-1) B = B "." E # Put name together return B } BEGIN { bad["krb5-types-aux.h"] = 1 bad["autoconf.h.in"] = 1 bad["conv_tkt_skey.c"] = 1 ##bad["makefile"] = 2 -- windows have legitimate files with this name } { parse_path($1) # Do it } krb5-1.16/src/config/wconfig.pl0000755000704600001450000000374613211554426016240 0ustar ghudsonlibuuid#! perl $win_flag = "WIN32##"; @wflags = (); $mit_specific = 0; @ignore_list = ( "DOS#?#?" ); foreach $arg (@ARGV) { if ($arg =~ /^-/) { push @wflags, $arg; } if ("--mit" eq $arg) { $mit_specific = 1; } elsif ("--win16" eq $arg) { $win_flag = "WIN16##"; } elsif ("--win32" eq $arg) { $win_flag = "WIN32##"; } elsif ($arg =~ /^--enable-/) { my($a) = $arg . "##"; $a =~ s/^--enable-//; $a =~ tr/a-z/A-Z/; push @ignore_list, $a; } elsif ($arg =~ /^--ignore=/) { my($a) = $arg; $a =~ s/--ignore=//; push @ignore_list, $a; } elsif ($arg =~ /^-/) { print STDERR "Invalid option '$arg'\n"; exit 1; } else { if (! defined $dir) { $dir = $arg; } } } push @ignore_list, $win_flag; push @ignore_list, "MIT##" if $mit_specific; if ($#wflags >= 0) { printf "WCONFIG_FLAGS=%s\n", join (" ", @wflags); } # This has a couple variations from the old wconfig.c. # # The old script wouldn't treat the input strings as regular expressions. # This one does, and actually it builds one regexp, so the strict order of # checks done by wconfig.c no longer applies. # # And the old script would change "##DOS#" to "#", whereas this # version (with the regexp given above) will accept and discard 0, 1 # or 2 "#" marks. $sub = "sub do_subst { my (\$a) = shift; \$a =~ s/^##(" . join("|", @ignore_list) . ")//; return \$a; }"; #print STDERR $sub, "\n"; eval $sub; sub process { my $fh = shift; while (<$fh>) { if (/^@/) { # This branch isn't actually used as far as I can tell. print "\n"; next; } # Do we want to do any autoconf-style @FOO@ substitutions? # s/@MAINT@/#/g; # Are there any options we might want to set at configure time? print &do_subst($_); } } if (defined $dir) { open AUX, "<$dir/win-pre.in" || die "Couldn't open win-pre.in: $!\n"; &process(\*AUX); close AUX; } &process(\*STDIN); if (defined $dir) { open AUX, "<$dir/win-post.in" || die "Couldn't open win-post.in: $!\n"; &process(\*AUX); close AUX; } exit 0; krb5-1.16/src/config/install-sh0000755000704600001450000002017413211554426016242 0ustar ghudsonlibuuid#!/bin/sh # install - install a program, script, or datafile scriptversion=2003-09-24.23 # This originates from X11R5 (mit/util/scripts/install.sh), which was # later released in X11R6 (xc/config/util/install.sh) with the # following copyright and license. # # Copyright (C) 1994 X Consortium # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to # deal in the Software without restriction, including without limitation the # rights to use, copy, modify, merge, publish, distribute, sublicense, and/or # sell copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN # AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- # TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # # Except as contained in this notice, the name of the X Consortium shall not # be used in advertising or otherwise to promote the sale, use or other deal- # ings in this Software without prior written authorization from the X Consor- # tium. # # # FSF changes to this file are in the public domain. # # Calling this script install-sh is preferred over install.sh, to prevent # `make' implicit rules from creating a file called install from it # when there is no Makefile. # # This script is compatible with the BSD install script, but was written # from scratch. It can only install one file at a time, a restriction # shared with many OS's install programs. # set DOITPROG to echo to test this script # Don't use :- since 4.3BSD and earlier shells don't like it. doit="${DOITPROG-}" # put in absolute paths if you don't have them in your path; or use env. vars. mvprog="${MVPROG-mv}" cpprog="${CPPROG-cp}" chmodprog="${CHMODPROG-chmod}" chownprog="${CHOWNPROG-chown}" chgrpprog="${CHGRPPROG-chgrp}" stripprog="${STRIPPROG-strip}" rmprog="${RMPROG-rm}" mkdirprog="${MKDIRPROG-mkdir}" transformbasename= transform_arg= instcmd="$mvprog" chmodcmd="$chmodprog 0755" chowncmd= chgrpcmd= stripcmd= rmcmd="$rmprog -f" mvcmd="$mvprog" src= dst= dir_arg= usage="Usage: $0 [OPTION]... SRCFILE DSTFILE or: $0 -d DIR1 DIR2... In the first form, install SRCFILE to DSTFILE, removing SRCFILE by default. In the second, create the directory path DIR. Options: -b=TRANSFORMBASENAME -c copy source (using $cpprog) instead of moving (using $mvprog). -d create directories instead of installing files. -g GROUP $chgrp installed files to GROUP. -m MODE $chmod installed files to MODE. -o USER $chown installed files to USER. -s strip installed files (using $stripprog). -t=TRANSFORM --help display this help and exit. --version display version info and exit. Environment variables override the default commands: CHGRPPROG CHMODPROG CHOWNPROG CPPROG MKDIRPROG MVPROG RMPROG STRIPPROG " while test -n "$1"; do case $1 in -b=*) transformbasename=`echo $1 | sed 's/-b=//'` shift continue;; -c) instcmd=$cpprog shift continue;; -d) dir_arg=true shift continue;; -g) chgrpcmd="$chgrpprog $2" shift shift continue;; --help) echo "$usage"; exit 0;; -m) chmodcmd="$chmodprog $2" shift shift continue;; -o) chowncmd="$chownprog $2" shift shift continue;; -s) stripcmd=$stripprog shift continue;; -t=*) transformarg=`echo $1 | sed 's/-t=//'` shift continue;; --version) echo "$0 $scriptversion"; exit 0;; *) if test -z "$src"; then src=$1 else # this colon is to work around a 386BSD /bin/sh bug : dst=$1 fi shift continue;; esac done if test -z "$src"; then echo "$0: no input file specified." >&2 exit 1 fi # Protect names starting with `-'. case $src in -*) src=./$src ;; esac if test -n "$dir_arg"; then dst=$src src= if test -d "$dst"; then instcmd=: chmodcmd= else instcmd=$mkdirprog fi else # Waiting for this to be detected by the "$instcmd $src $dsttmp" command # might cause directories to be created, which would be especially bad # if $src (and thus $dsttmp) contains '*'. if test ! -f "$src" && test ! -d "$src"; then echo "$0: $src does not exist." >&2 exit 1 fi if test -z "$dst"; then echo "$0: no destination specified." >&2 exit 1 fi # Protect names starting with `-'. case $dst in -*) dst=./$dst ;; esac # If destination is a directory, append the input filename; won't work # if double slashes aren't ignored. if test -d "$dst"; then dst=$dst/`basename "$src"` fi fi # This sed command emulates the dirname command. dstdir=`echo "$dst" | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'` # Make sure that the destination directory exists. # Skip lots of stat calls in the usual case. if test ! -d "$dstdir"; then defaultIFS=' ' IFS="${IFS-$defaultIFS}" oIFS=$IFS # Some sh's can't handle IFS=/ for some reason. IFS='%' set - `echo "$dstdir" | sed -e 's@/@%@g' -e 's@^%@/@'` IFS=$oIFS pathcomp= while test $# -ne 0 ; do pathcomp=$pathcomp$1 shift test -d "$pathcomp" || $mkdirprog "$pathcomp" pathcomp=$pathcomp/ done fi if test -n "$dir_arg"; then $doit $instcmd "$dst" \ && { test -z "$chowncmd" || $doit $chowncmd "$dst"; } \ && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } \ && { test -z "$stripcmd" || $doit $stripcmd "$dst"; } \ && { test -z "$chmodcmd" || $doit $chmodcmd "$dst"; } else # If we're going to rename the final executable, determine the name now. if test -z "$transformarg"; then dstfile=`basename "$dst"` else dstfile=`basename "$dst" $transformbasename \ | sed $transformarg`$transformbasename fi # don't allow the sed command to completely eliminate the filename. test -z "$dstfile" && dstfile=`basename "$dst"` # Make a couple of temp file names in the proper directory. dsttmp=$dstdir/_inst.$$_ rmtmp=$dstdir/_rm.$$_ # Trap to clean up those temp files at exit. trap 'status=$?; rm -f "$dsttmp" "$rmtmp" && exit $status' 0 trap '(exit $?); exit' 1 2 13 15 # Move or copy the file name to the temp name $doit $instcmd "$src" "$dsttmp" && # and set any options; do chmod last to preserve setuid bits. # # If any of these fail, we abort the whole thing. If we want to # ignore errors from any of these, just make sure not to ignore # errors from the above "$doit $instcmd $src $dsttmp" command. # { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } \ && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } \ && { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } \ && { test -z "$chmodcmd" || $doit $chmodcmd "$dsttmp"; } && # Now remove or move aside any old file at destination location. We # try this two ways since rm can't unlink itself on some systems and # the destination file might be busy for other reasons. In this case, # the final cleanup might fail but the new file should still install # successfully. { if test -f "$dstdir/$dstfile"; then $doit $rmcmd -f "$dstdir/$dstfile" 2>/dev/null \ || $doit $mvcmd -f "$dstdir/$dstfile" "$rmtmp" 2>/dev/null \ || { echo "$0: cannot unlink or rename $dstdir/$dstfile" >&2 (exit 1); exit } else : fi } && # Now rename the file to the real destination. $doit $mvcmd "$dsttmp" "$dstdir/$dstfile" fi && # The final little trick to "correctly" pass the exit status to the exit trap. { (exit 0); exit } # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-end: "$" # End: krb5-1.16/src/config/move-if-changed0000755000704600001450000000057013211554426017113 0ustar ghudsonlibuuid#!/bin/sh # Move file 1 to file 2 if they don't already match. # Good for "make depend" for example, where it'd be nice to keep the # old datestamp. if [ $# != 2 ]; then echo 2>&1 usage: $0 newfile oldfilename exit 1 fi # if [ ! -r "$2" ]; then exec mv -f "$1" "$2" fi if cmp "$1" "$2" >/dev/null; then echo "$2 is unchanged" exec rm -f "$1" fi exec mv -f "$1" "$2" krb5-1.16/src/config/libpriv.in0000644000704600001450000000063713211554426016237 0ustar ghudsonlibuuid# Additional definitions for private libraries, which we build as archive # libraries (or equivalent) and do not install. # # The defaults (for installed shared libraries) are in pre.in. We # override them here, before lib.in uses them. LIBLIST=lib$(LIBBASE)$(STLIBEXT) LIBLINKS=$(TOPLIBD)/lib$(LIBBASE)$(STLIBEXT) OBJLISTS=OBJS.ST LIBINSTLIST= SHLIBEXT=.so-nobuild SHLIBVEXT=.so.v-nobuild SHLIBSEXT=.so.s-nobuild krb5-1.16/src/patchlevel.h0000644000704600001450000000453513211554426015274 0ustar ghudsonlibuuid/* patchlevel.h */ /* * Copyright (C) 2004-2006 by the Massachusetts Institute of Technology. * All rights reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ /* * This is the master file for version stamping purposes. The * checked-in version will contain the correct version information at * all times. Prior to an official release x.y.z, * KRB5_MAJOR_RELEASE=x, KRB5_MINOR_RELEASE=y, and KRB5_PATCHLEVEL=z. * KRB5_RELTAIL will reflect the release state. It will be * "prerelease" for unreleased code either on the trunk or on a * release branch. It will be undefined for a final release. * * Immediately following a final release, the release version numbers * will be incremented, and KRB5_RELTAIL will revert to "prerelease". * * KRB5_RELTAG contains the CVS tag name corresponding to the release. * KRB5_RELDATE identifies the date of the release. They should * normally be undefined for checked-in code. */ /* * ========== * IMPORTANT: * ========== * * If you are a vendor supplying modified code derived from MIT * Kerberos, you SHOULD update KRB5_RELTAIL to identify your * organization. */ #define KRB5_MAJOR_RELEASE 1 #define KRB5_MINOR_RELEASE 16 #define KRB5_PATCHLEVEL 0 /* #undef KRB5_RELTAIL */ #define KRB5_RELDATE "20171205" #define KRB5_RELTAG "krb5-1.16-final" krb5-1.16/src/tests/0000755000704600001450000000000013211554426014127 5ustar ghudsonlibuuidkrb5-1.16/src/tests/t_crossrealm.py0000755000704600001450000001361513211554426017207 0ustar ghudsonlibuuid#!/usr/bin/python # Copyright (C) 2011 by the Massachusetts Institute of Technology. # All rights reserved. # # Export of this software from the United States of America may # require a specific license from the United States Government. # It is the responsibility of any person or organization contemplating # export to obtain such a license before exporting. # # WITHIN THAT CONSTRAINT, permission to use, copy, modify, and # distribute this software and its documentation for any purpose and # without fee is hereby granted, provided that the above copyright # notice appear in all copies and that both that copyright notice and # this permission notice appear in supporting documentation, and that # the name of M.I.T. not be used in advertising or publicity pertaining # to distribution of the software without specific, written prior # permission. Furthermore if you modify this software you must label # your software as modified software and not distribute it in such a # fashion that it might be confused with the original M.I.T. software. # M.I.T. makes no representations about the suitability of # this software for any purpose. It is provided "as is" without express # or implied warranty. from k5test import * def test_kvno(r, princ, test, env=None): r.run([kvno, princ], env=env, expected_msg=princ) def stop(*realms): for r in realms: r.stop() # Verify that the princs appear as the service principals in the klist # output for the realm r, in order. def check_klist(r, princs): out = r.run([klist]) count = 0 seen_header = False for l in out.split('\n'): if l.startswith('Valid starting'): seen_header = True continue if not seen_header or l == '': continue if count >= len(princs): fail('too many entries in klist output') svcprinc = l.split()[4] if svcprinc != princs[count]: fail('saw service princ %s in klist output, expected %s' % (svcprinc, princs[count])) count += 1 if count != len(princs): fail('not enough entries in klist output') def tgt(r1, r2): return 'krbtgt/%s@%s' % (r1.realm, r2.realm) # Basic two-realm test with cross TGTs in both directions. r1, r2 = cross_realms(2) test_kvno(r1, r2.host_princ, 'basic r1->r2') check_klist(r1, (tgt(r1, r1), tgt(r2, r1), r2.host_princ)) test_kvno(r2, r1.host_princ, 'basic r2->r1') check_klist(r2, (tgt(r2, r2), tgt(r1, r2), r1.host_princ)) stop(r1, r2) # Test the KDC domain walk for hierarchically arranged realms. The # client in A.X will ask for a cross TGT to B.X, but A.X's KDC only # has a TGT for the intermediate realm X, so it will return that # instead. The client will use that to get a TGT for B.X. r1, r2, r3 = cross_realms(3, xtgts=((0,1), (1,2)), args=({'realm': 'A.X'}, {'realm': 'X'}, {'realm': 'B.X'})) test_kvno(r1, r3.host_princ, 'KDC domain walk') check_klist(r1, (tgt(r1, r1), r3.host_princ)) stop(r1, r2, r3) # Test client capaths. The client in A will ask for a cross TGT to D, # but A's KDC won't have it and won't know an intermediate to return. # The client will walk its A->D capaths to get TGTs for B, then C, # then D. The KDCs for C and D need capaths settings to avoid failing # transited checks, including a capaths for A->C. capaths = {'capaths': {'A': {'D': ['B', 'C'], 'C': 'B'}}} r1, r2, r3, r4 = cross_realms(4, xtgts=((0,1), (1,2), (2,3)), args=({'realm': 'A'}, {'realm': 'B'}, {'realm': 'C', 'krb5_conf': capaths}, {'realm': 'D', 'krb5_conf': capaths})) r1client = r1.special_env('client', False, krb5_conf=capaths) test_kvno(r1, r4.host_princ, 'client capaths', r1client) check_klist(r1, (tgt(r1, r1), tgt(r2, r1), tgt(r3, r2), tgt(r4, r3), r4.host_princ)) stop(r1, r2, r3, r4) # Test KDC capaths. The KDCs for A and B have appropriate capaths # settings to determine intermediate TGTs to return, but the client # has no idea. capaths = {'capaths': {'A': {'D': ['B', 'C'], 'C': 'B'}, 'B': {'D': 'C'}}} r1, r2, r3, r4 = cross_realms(4, xtgts=((0,1), (1,2), (2,3)), args=({'realm': 'A', 'krb5_conf': capaths}, {'realm': 'B', 'krb5_conf': capaths}, {'realm': 'C', 'krb5_conf': capaths}, {'realm': 'D', 'krb5_conf': capaths})) test_kvno(r1, r4.host_princ, 'KDC capaths') check_klist(r1, (tgt(r1, r1), tgt(r4, r3), r4.host_princ)) stop(r1, r2, r3, r4) # Test transited error. The KDC for C does not recognize B as an # intermediate realm for A->C, so it refuses to issue a service # ticket. capaths = {'capaths': {'A': {'C': 'B'}}} r1, r2, r3 = cross_realms(3, xtgts=((0,1), (1,2)), args=({'realm': 'A', 'krb5_conf': capaths}, {'realm': 'B'}, {'realm': 'C'})) r1.run([kvno, r3.host_princ], expected_code=1, expected_msg='KDC policy rejects request') check_klist(r1, (tgt(r1, r1), tgt(r3, r2))) stop(r1, r2, r3) # Test a different kind of transited error. The KDC for D does not # recognize B as an intermediate realm for A->C, so it refuses to # verify the krbtgt/C@B ticket in the TGS AP-REQ. capaths = {'capaths': {'A': {'D': ['B', 'C'], 'C': 'B'}, 'B': {'D': 'C'}}} r1, r2, r3, r4 = cross_realms(4, xtgts=((0,1), (1,2), (2,3)), args=({'realm': 'A', 'krb5_conf': capaths}, {'realm': 'B', 'krb5_conf': capaths}, {'realm': 'C', 'krb5_conf': capaths}, {'realm': 'D'})) r1.run([kvno, r4.host_princ], expected_code=1, expected_msg='Illegal cross-realm ticket') check_klist(r1, (tgt(r1, r1), tgt(r4, r3))) stop(r1, r2, r3, r4) success('Cross-realm tests') krb5-1.16/src/tests/t_sesskeynego.py0000755000704600001450000000670613211554426017377 0ustar ghudsonlibuuid#!/usr/bin/python from k5test import * import re # Run "kvno server" with a fresh set of client tickets, then check that the # enctypes in the service ticket match the expected values. etypes_re = re.compile(r'server@[^\n]+\n\tEtype \(skey, tkt\): ' '([^,]+), ([^\s]+)') def test_kvno(realm, expected_skey, expected_tkt): realm.kinit(realm.user_princ, password('user')) realm.run([kvno, 'server']) output = realm.run([klist, '-e']) m = etypes_re.search(output) if not m: fail('could not parse etypes from klist -e output') skey, tkt = m.groups() if skey != expected_skey: fail('got session key type %s, expected %s' % (skey, expected_skey)) if tkt != expected_tkt: fail('got ticket key type %s, expected %s' % (tkt, expected_tkt)) conf1 = {'libdefaults': {'default_tgs_enctypes': 'aes128-cts,aes256-cts'}} conf2 = {'libdefaults': {'default_tgs_enctypes': 'aes256-cts,aes128-cts'}} conf3 = {'libdefaults': { 'allow_weak_crypto': 'true', 'default_tkt_enctypes': 'aes128-cts', 'default_tgs_enctypes': 'rc4-hmac,aes128-cts,des-cbc-crc'}} conf4 = {'libdefaults': { 'allow_weak_crypto': 'true', 'default_tkt_enctypes': 'aes256-cts', 'default_tgs_enctypes': 'des-cbc-crc,rc4-hmac,aes256-cts'}, 'realms': {'$realm': {'des_crc_session_supported': 'false'}}} # Test with client request and session_enctypes preferring aes128, but # aes256 long-term key. realm = K5Realm(krb5_conf=conf1, create_host=False, get_creds=False) realm.run([kadminl, 'addprinc', '-randkey', '-e', 'aes256-cts', 'server']) realm.run([kadminl, 'setstr', 'server', 'session_enctypes', 'aes128-cts,aes256-cts']) test_kvno(realm, 'aes128-cts-hmac-sha1-96', 'aes256-cts-hmac-sha1-96') realm.stop() # Second go, almost same as first, but resulting session key must be aes256 # because of the difference in default_tgs_enctypes order. This tests that # session_enctypes doesn't change the order in which we negotiate. realm = K5Realm(krb5_conf=conf2, create_host=False, get_creds=False) realm.run([kadminl, 'addprinc', '-randkey', '-e', 'aes256-cts', 'server']) realm.run([kadminl, 'setstr', 'server', 'session_enctypes', 'aes128-cts,aes256-cts']) test_kvno(realm, 'aes256-cts-hmac-sha1-96', 'aes256-cts-hmac-sha1-96') realm.stop() # Next we use conf3 and try various things. realm = K5Realm(krb5_conf=conf3, create_host=False, get_creds=False) realm.run([kadminl, 'addprinc', '-randkey', '-e', 'aes256-cts:normal', 'server']) # 3a: Negotiate aes128 session key when principal only has aes256 long-term. realm.run([kadminl, 'setstr', 'server', 'session_enctypes', 'aes128-cts,aes256-cts']) test_kvno(realm, 'aes128-cts-hmac-sha1-96', 'aes256-cts-hmac-sha1-96') # 3b: Negotiate rc4-hmac session key when principal only has aes256 long-term. realm.run([kadminl, 'setstr', 'server', 'session_enctypes', 'rc4-hmac,aes128-cts,aes256-cts']) test_kvno(realm, 'arcfour-hmac', 'aes256-cts-hmac-sha1-96') # 3c: Test des-cbc-crc default assumption. realm.run([kadminl, 'delstr', 'server', 'session_enctypes']) test_kvno(realm, 'des-cbc-crc', 'aes256-cts-hmac-sha1-96') realm.stop() # Last go: test that we can disable the des-cbc-crc assumption realm = K5Realm(krb5_conf=conf4, get_creds=False) realm.run([kadminl, 'addprinc', '-randkey', '-e', 'aes256-cts', 'server']) test_kvno(realm, 'aes256-cts-hmac-sha1-96', 'aes256-cts-hmac-sha1-96') realm.stop() success('sesskeynego') krb5-1.16/src/tests/t_tabdump.py0000755000704600001450000000431713211554426016470 0ustar ghudsonlibuuid#!/usr/bin/python from k5test import * import csv import StringIO def tab_csv(s): io = StringIO.StringIO(s) return list(csv.DictReader(io, dialect=csv.excel_tab)) def getrows(dumptype): out = realm.run([kdb5_util, 'tabdump', dumptype]) return tab_csv(out) def checkkeys(rows, dumptype, names): if sorted(rows[0].keys()) != sorted(names): fail('tabdump %s field names' % dumptype) realm = K5Realm(start_kdc=False, get_creds=False) rows = getrows('keyinfo') checkkeys(rows, 'keyinfo', ["name", "keyindex", "kvno", "enctype", "salttype", "salt"]) userrows = [x for x in rows if x['name'].startswith('user@')] userrows.sort(key=lambda x: x['keyindex']) if (userrows[0]['enctype'] != 'aes256-cts-hmac-sha1-96' or userrows[1]['enctype'] != 'aes128-cts-hmac-sha1-96'): fail('tabdump keyinfo enctypes') success('tabdump keyinfo') rows = getrows('keydata') checkkeys(rows, 'keydata', ["name", "keyindex", "kvno", "enctype", "key", "salttype", "salt"]) rows = getrows('princ_flags') checkkeys(rows, 'princ_flags', ["name", "flag", "value"]) rows = getrows('princ_lockout') checkkeys(rows, 'princ_lockout', ["name", "last_success", "last_failed", "fail_count"]) realm.run([kadminl, 'addpol', '-history', '3', 'testpol']) realm.run([kadminl, 'modprinc', '-policy', 'testpol', 'user']) rows = getrows('princ_meta') checkkeys(rows, 'princ_meta', ["name", "modby", "modtime", "lastpwd", "policy", "mkvno", "hist_kvno"]) userrows = [x for x in rows if x['name'].startswith('user@')] if userrows[0]['policy'] != 'testpol': fail('tabdump princ_meta policy name') realm.run([kadminl, 'set_string', 'user', 'foo', 'bar']) rows = getrows('princ_stringattrs') checkkeys(rows, 'princ_stringattrs', ["name", "key", "value"]) userrows = [x for x in rows if x['name'].startswith('user@')] if (len(userrows) != 1 or userrows[0]['key'] != 'foo' or userrows[0]['value'] != 'bar'): fail('tabdump princ_stringattrs key/value') rows = getrows('princ_tktpolicy') checkkeys(rows, 'princ_tktpolicy', ["name", "expiration", "pw_expiration", "max_life", "max_renew_life"]) success('tabdump') krb5-1.16/src/tests/asn.1/0000755000704600001450000000000013211554426015047 5ustar ghudsonlibuuidkrb5-1.16/src/tests/asn.1/krb5_encode_test.c0000644000704600001450000007653513211554426020452 0ustar ghudsonlibuuid/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* tests/asn.1/krb5_encode_test.c */ /* * Copyright (C) 1994 by the Massachusetts Institute of Technology. * All rights reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #include "k5-int.h" #include "com_err.h" #include "utility.h" #include "ktest.h" #include "debug.h" extern int current_appl_type; krb5_context test_context; int error_count = 0; int do_trval = 0; int first_trval = 1; int trval2(); static void encoder_print_results(krb5_data *code, char *typestring, char *description) { char *code_string = NULL; int r, rlen; if (do_trval) { if (first_trval) first_trval = 0; else printf("\n"); printf("encode_krb5_%s%s:\n", typestring, description); r = trval2(stdout, code->data, code->length, 0, &rlen); printf("\n"); if (rlen < 0 || (unsigned int) rlen != code->length) { printf("Error: length mismatch: was %d, parsed %d\n", code->length, rlen); exit(1); } if (r != 0) { printf("Error: Return from trval2 is %d.\n", r); exit(1); } current_appl_type = -1; /* Reset type */ } else { asn1_krb5_data_unparse(code,&(code_string)); printf("encode_krb5_%s%s: %s\n", typestring, description, code_string); free(code_string); } ktest_destroy_data(&code); } static void PRS(argc, argv) int argc; char **argv; { extern char *optarg; int optchar; extern int print_types, print_krb5_types, print_id_and_len, print_constructed_length, print_skip_context, print_skip_tagnum, print_context_shortcut; while ((optchar = getopt(argc, argv, "tp:")) != -1) { switch(optchar) { case 't': do_trval = 1; break; case 'p': sample_principal_name = optarg; break; case '?': default: fprintf(stderr, "Usage: %s [-t] [-p principal]\n", argv[0]); exit(1); } } print_types = 1; print_krb5_types = 1; print_id_and_len = 0; print_constructed_length = 0; print_skip_context = 1; print_skip_tagnum = 1; print_context_shortcut = 1; } int main(argc, argv) int argc; char **argv; { krb5_data *code; krb5_error_code retval; PRS(argc, argv); retval = krb5_init_context(&test_context); if (retval) { com_err(argv[0], retval, "while initializing krb5"); exit(1); } init_access(argv[0]); #define encode_run(value,typestring,description,encoder) \ retval = encoder(&(value),&(code)); \ if (retval) { \ com_err("krb5_encode_test", retval,"while encoding %s", typestring); \ exit(1); \ } \ encoder_print_results(code, typestring, description); /****************************************************************/ /* encode_krb5_authenticator */ { krb5_authenticator authent; ktest_make_sample_authenticator(&authent); encode_run(authent, "authenticator", "", encode_krb5_authenticator); ktest_destroy_checksum(&(authent.checksum)); ktest_destroy_keyblock(&(authent.subkey)); authent.seq_number = 0; ktest_empty_authorization_data(authent.authorization_data); encode_run(authent, "authenticator", "(optionals empty)", encode_krb5_authenticator); ktest_destroy_authorization_data(&(authent.authorization_data)); encode_run(authent, "authenticator", "(optionals NULL)", encode_krb5_authenticator); ktest_empty_authenticator(&authent); } /****************************************************************/ /* encode_krb5_ticket */ { krb5_ticket tkt; ktest_make_sample_ticket(&tkt); encode_run(tkt, "ticket", "", encode_krb5_ticket); ktest_empty_ticket(&tkt); } /****************************************************************/ /* encode_krb5_encryption_key */ { krb5_keyblock keyblk; ktest_make_sample_keyblock(&keyblk); current_appl_type = 1005; encode_run(keyblk, "keyblock", "", encode_krb5_encryption_key); ktest_empty_keyblock(&keyblk); } /****************************************************************/ /* encode_krb5_enc_tkt_part */ { krb5_ticket tkt; memset(&tkt, 0, sizeof(krb5_ticket)); tkt.enc_part2 = ealloc(sizeof(krb5_enc_tkt_part)); ktest_make_sample_enc_tkt_part(tkt.enc_part2); encode_run(*tkt.enc_part2, "enc_tkt_part", "", encode_krb5_enc_tkt_part); tkt.enc_part2->times.starttime = 0; tkt.enc_part2->times.renew_till = 0; ktest_destroy_address(&(tkt.enc_part2->caddrs[1])); ktest_destroy_address(&(tkt.enc_part2->caddrs[0])); ktest_destroy_authdata(&(tkt.enc_part2->authorization_data[1])); ktest_destroy_authdata(&(tkt.enc_part2->authorization_data[0])); /* ISODE version fails on the empty caddrs field */ ktest_destroy_addresses(&(tkt.enc_part2->caddrs)); ktest_destroy_authorization_data(&(tkt.enc_part2->authorization_data)); encode_run(*tkt.enc_part2, "enc_tkt_part", "(optionals NULL)", encode_krb5_enc_tkt_part); ktest_empty_ticket(&tkt); } /****************************************************************/ /* encode_krb5_enc_kdc_rep_part */ { krb5_kdc_rep kdcr; memset(&kdcr, 0, sizeof(kdcr)); kdcr.enc_part2 = ealloc(sizeof(krb5_enc_kdc_rep_part)); ktest_make_sample_enc_kdc_rep_part(kdcr.enc_part2); encode_run(*kdcr.enc_part2, "enc_kdc_rep_part", "", encode_krb5_enc_kdc_rep_part); kdcr.enc_part2->key_exp = 0; kdcr.enc_part2->times.starttime = 0; kdcr.enc_part2->flags &= ~TKT_FLG_RENEWABLE; ktest_destroy_addresses(&(kdcr.enc_part2->caddrs)); encode_run(*kdcr.enc_part2, "enc_kdc_rep_part", "(optionals NULL)", encode_krb5_enc_kdc_rep_part); ktest_empty_kdc_rep(&kdcr); } /****************************************************************/ /* encode_krb5_as_rep */ { krb5_kdc_rep kdcr; ktest_make_sample_kdc_rep(&kdcr); /* kdcr.msg_type = KRB5_TGS_REP; test(encode_krb5_as_rep(&kdcr,&code) == KRB5_BADMSGTYPE, "encode_krb5_as_rep type check\n"); ktest_destroy_data(&code);*/ kdcr.msg_type = KRB5_AS_REP; encode_run(kdcr, "as_rep", "", encode_krb5_as_rep); ktest_destroy_pa_data_array(&(kdcr.padata)); encode_run(kdcr, "as_rep", "(optionals NULL)", encode_krb5_as_rep); ktest_empty_kdc_rep(&kdcr); } /****************************************************************/ /* encode_krb5_tgs_rep */ { krb5_kdc_rep kdcr; ktest_make_sample_kdc_rep(&kdcr); /* kdcr.msg_type = KRB5_AS_REP; test(encode_krb5_tgs_rep(&kdcr,&code) == KRB5_BADMSGTYPE, "encode_krb5_tgs_rep type check\n");*/ kdcr.msg_type = KRB5_TGS_REP; encode_run(kdcr, "tgs_rep", "", encode_krb5_tgs_rep); ktest_destroy_pa_data_array(&(kdcr.padata)); encode_run(kdcr, "tgs_rep", "(optionals NULL)", encode_krb5_tgs_rep); ktest_empty_kdc_rep(&kdcr); } /****************************************************************/ /* encode_krb5_ap_req */ { krb5_ap_req apreq; ktest_make_sample_ap_req(&apreq); encode_run(apreq, "ap_req", "", encode_krb5_ap_req); ktest_empty_ap_req(&apreq); } /****************************************************************/ /* encode_krb5_ap_rep */ { krb5_ap_rep aprep; ktest_make_sample_ap_rep(&aprep); encode_run(aprep, "ap_rep", "", encode_krb5_ap_rep); ktest_empty_ap_rep(&aprep); } /****************************************************************/ /* encode_krb5_ap_rep_enc_part */ { krb5_ap_rep_enc_part apenc; ktest_make_sample_ap_rep_enc_part(&apenc); encode_run(apenc, "ap_rep_enc_part", "", encode_krb5_ap_rep_enc_part); ktest_destroy_keyblock(&(apenc.subkey)); apenc.seq_number = 0; encode_run(apenc, "ap_rep_enc_part", "(optionals NULL)", encode_krb5_ap_rep_enc_part); ktest_empty_ap_rep_enc_part(&apenc); } /****************************************************************/ /* encode_krb5_as_req */ { krb5_kdc_req asreq; ktest_make_sample_kdc_req(&asreq); asreq.msg_type = KRB5_AS_REQ; asreq.kdc_options &= ~KDC_OPT_ENC_TKT_IN_SKEY; encode_run(asreq, "as_req", "", encode_krb5_as_req); ktest_destroy_pa_data_array(&(asreq.padata)); ktest_destroy_principal(&(asreq.client)); #ifndef ISODE_SUCKS ktest_destroy_principal(&(asreq.server)); #endif asreq.kdc_options |= KDC_OPT_ENC_TKT_IN_SKEY; asreq.from = 0; asreq.rtime = 0; ktest_destroy_addresses(&(asreq.addresses)); ktest_destroy_enc_data(&(asreq.authorization_data)); encode_run(asreq, "as_req", "(optionals NULL except second_ticket)", encode_krb5_as_req); ktest_destroy_sequence_of_ticket(&(asreq.second_ticket)); #ifndef ISODE_SUCKS ktest_make_sample_principal(&(asreq.server)); #endif asreq.kdc_options &= ~KDC_OPT_ENC_TKT_IN_SKEY; encode_run(asreq, "as_req", "(optionals NULL except server)", encode_krb5_as_req); ktest_empty_kdc_req(&asreq); } /****************************************************************/ /* encode_krb5_tgs_req */ { krb5_kdc_req tgsreq; ktest_make_sample_kdc_req(&tgsreq); tgsreq.msg_type = KRB5_TGS_REQ; tgsreq.kdc_options &= ~KDC_OPT_ENC_TKT_IN_SKEY; encode_run(tgsreq, "tgs_req", "", encode_krb5_tgs_req); ktest_destroy_pa_data_array(&(tgsreq.padata)); ktest_destroy_principal(&(tgsreq.client)); #ifndef ISODE_SUCKS ktest_destroy_principal(&(tgsreq.server)); #endif tgsreq.kdc_options |= KDC_OPT_ENC_TKT_IN_SKEY; tgsreq.from = 0; tgsreq.rtime = 0; ktest_destroy_addresses(&(tgsreq.addresses)); ktest_destroy_enc_data(&(tgsreq.authorization_data)); encode_run(tgsreq, "tgs_req", "(optionals NULL except second_ticket)", encode_krb5_tgs_req); ktest_destroy_sequence_of_ticket(&(tgsreq.second_ticket)); #ifndef ISODE_SUCKS ktest_make_sample_principal(&(tgsreq.server)); #endif tgsreq.kdc_options &= ~KDC_OPT_ENC_TKT_IN_SKEY; encode_run(tgsreq, "tgs_req", "(optionals NULL except server)", encode_krb5_tgs_req); ktest_empty_kdc_req(&tgsreq); } /****************************************************************/ /* encode_krb5_kdc_req_body */ { krb5_kdc_req kdcrb; memset(&kdcrb, 0, sizeof(kdcrb)); ktest_make_sample_kdc_req_body(&kdcrb); kdcrb.kdc_options &= ~KDC_OPT_ENC_TKT_IN_SKEY; current_appl_type = 1007; /* Force interpretation as kdc-req-body */ encode_run(kdcrb, "kdc_req_body", "", encode_krb5_kdc_req_body); ktest_destroy_principal(&(kdcrb.client)); #ifndef ISODE_SUCKS ktest_destroy_principal(&(kdcrb.server)); #endif kdcrb.kdc_options |= KDC_OPT_ENC_TKT_IN_SKEY; kdcrb.from = 0; kdcrb.rtime = 0; ktest_destroy_addresses(&(kdcrb.addresses)); ktest_destroy_enc_data(&(kdcrb.authorization_data)); current_appl_type = 1007; /* Force interpretation as kdc-req-body */ encode_run(kdcrb, "kdc_req_body", "(optionals NULL except second_ticket)", encode_krb5_kdc_req_body); ktest_destroy_sequence_of_ticket(&(kdcrb.second_ticket)); #ifndef ISODE_SUCKS ktest_make_sample_principal(&(kdcrb.server)); #endif kdcrb.kdc_options &= ~KDC_OPT_ENC_TKT_IN_SKEY; current_appl_type = 1007; /* Force interpretation as kdc-req-body */ encode_run(kdcrb, "kdc_req_body", "(optionals NULL except server)", encode_krb5_kdc_req_body); ktest_empty_kdc_req(&kdcrb); } /****************************************************************/ /* encode_krb5_safe */ { krb5_safe s; ktest_make_sample_safe(&s); encode_run(s, "safe", "", encode_krb5_safe); s.timestamp = 0; /* s.usec should be opted out by the timestamp */ s.seq_number = 0; ktest_destroy_address(&(s.r_address)); encode_run(s, "safe", "(optionals NULL)", encode_krb5_safe); ktest_empty_safe(&s); } /****************************************************************/ /* encode_krb5_priv */ { krb5_priv p; ktest_make_sample_priv(&p); encode_run(p, "priv", "", encode_krb5_priv); ktest_empty_priv(&p); } /****************************************************************/ /* encode_krb5_enc_priv_part */ { krb5_priv_enc_part ep; ktest_make_sample_priv_enc_part(&ep); encode_run(ep, "enc_priv_part", "", encode_krb5_enc_priv_part); ep.timestamp = 0; /* ep.usec should be opted out along with timestamp */ ep.seq_number = 0; ktest_destroy_address(&(ep.r_address)); encode_run(ep, "enc_priv_part", "(optionals NULL)", encode_krb5_enc_priv_part); ktest_empty_priv_enc_part(&ep); } /****************************************************************/ /* encode_krb5_cred */ { krb5_cred c; ktest_make_sample_cred(&c); encode_run(c, "cred", "", encode_krb5_cred); ktest_empty_cred(&c); } /****************************************************************/ /* encode_krb5_enc_cred_part */ { krb5_cred_enc_part cep; ktest_make_sample_cred_enc_part(&cep); encode_run(cep, "enc_cred_part", "", encode_krb5_enc_cred_part); ktest_destroy_principal(&(cep.ticket_info[0]->client)); ktest_destroy_principal(&(cep.ticket_info[0]->server)); cep.ticket_info[0]->flags = 0; cep.ticket_info[0]->times.authtime = 0; cep.ticket_info[0]->times.starttime = 0; cep.ticket_info[0]->times.endtime = 0; cep.ticket_info[0]->times.renew_till = 0; ktest_destroy_addresses(&(cep.ticket_info[0]->caddrs)); cep.nonce = 0; cep.timestamp = 0; ktest_destroy_address(&(cep.s_address)); ktest_destroy_address(&(cep.r_address)); encode_run(cep, "enc_cred_part", "(optionals NULL)", encode_krb5_enc_cred_part); ktest_empty_cred_enc_part(&cep); } /****************************************************************/ /* encode_krb5_error */ { krb5_error kerr; ktest_make_sample_error(&kerr); encode_run(kerr, "error", "", encode_krb5_error); kerr.ctime = 0; ktest_destroy_principal(&(kerr.client)); ktest_empty_data(&(kerr.text)); ktest_empty_data(&(kerr.e_data)); encode_run(kerr, "error", "(optionals NULL)", encode_krb5_error); ktest_empty_error(&kerr); } /****************************************************************/ /* encode_krb5_authdata */ { krb5_authdata **ad; ktest_make_sample_authorization_data(&ad); retval = encode_krb5_authdata(ad,&(code)); if (retval) { com_err("encoding authorization_data",retval,""); exit(1); } current_appl_type = 1004; /* Force type to be authdata */ encoder_print_results(code, "authorization_data", ""); ktest_destroy_authorization_data(&ad); } /****************************************************************/ /* encode_padata_sequence and encode_krb5_typed_data */ { krb5_pa_data **pa; ktest_make_sample_pa_data_array(&pa); encode_run(*pa, "padata_sequence", "", encode_krb5_padata_sequence); encode_run(*pa, "typed_data", "", encode_krb5_typed_data); ktest_destroy_pa_data_array(&pa); ktest_make_sample_empty_pa_data_array(&pa); encode_run(*pa, "padata_sequence", "(empty)", encode_krb5_padata_sequence); ktest_destroy_pa_data_array(&pa); } /****************************************************************/ /* encode_etype_info */ { krb5_etype_info_entry **info; ktest_make_sample_etype_info(&info); encode_run(*info, "etype_info", "", encode_krb5_etype_info); ktest_destroy_etype_info_entry(info[2]); info[2] = 0; ktest_destroy_etype_info_entry(info[1]); info[1] = 0; encode_run(*info, "etype_info", "(only 1)", encode_krb5_etype_info); ktest_destroy_etype_info_entry(info[0]); info[0] = 0; encode_run(*info, "etype_info", "(no info)", encode_krb5_etype_info); ktest_destroy_etype_info(info); } /* encode_etype_info2 */ { krb5_etype_info_entry **info; ktest_make_sample_etype_info2(&info); encode_run(*info, "etype_info2", "", encode_krb5_etype_info2); ktest_destroy_etype_info_entry(info[2]); info[2] = 0; ktest_destroy_etype_info_entry(info[1]); info[1] = 0; encode_run(*info, "etype_info2", "(only 1)", encode_krb5_etype_info2); /* etype_info2 sequences aren't allowed to be empty. */ ktest_destroy_etype_info(info); } /****************************************************************/ /* encode_pa_enc_ts */ { krb5_pa_enc_ts pa_enc; ktest_make_sample_pa_enc_ts(&pa_enc); encode_run(pa_enc, "pa_enc_ts", "", encode_krb5_pa_enc_ts); pa_enc.pausec = 0; encode_run(pa_enc, "pa_enc_ts (no usec)", "", encode_krb5_pa_enc_ts); } /****************************************************************/ /* encode_enc_data */ { krb5_enc_data enc_data; ktest_make_sample_enc_data(&enc_data); current_appl_type = 1001; encode_run(enc_data, "enc_data", "", encode_krb5_enc_data); enc_data.kvno = 0xFF000000; current_appl_type = 1001; encode_run(enc_data, "enc_data", "(MSB-set kvno)", encode_krb5_enc_data); enc_data.kvno = 0xFFFFFFFF; current_appl_type = 1001; encode_run(enc_data, "enc_data", "(kvno=-1)", encode_krb5_enc_data); ktest_destroy_enc_data(&enc_data); } /****************************************************************/ /* encode_krb5_sam_challenge_2 */ { krb5_sam_challenge_2 sam_ch2; ktest_make_sample_sam_challenge_2(&sam_ch2); encode_run(sam_ch2, "sam_challenge_2", "", encode_krb5_sam_challenge_2); ktest_empty_sam_challenge_2(&sam_ch2); } /****************************************************************/ /* encode_krb5_sam_challenge_2_body */ { krb5_sam_challenge_2_body body; ktest_make_sample_sam_challenge_2_body(&body); encode_run(body, "sam_challenge_2_body", "", encode_krb5_sam_challenge_2_body); ktest_empty_sam_challenge_2_body(&body); } /****************************************************************/ /* encode_krb5_sam_response_2 */ { krb5_sam_response_2 sam_ch2; ktest_make_sample_sam_response_2(&sam_ch2); encode_run(sam_ch2, "sam_response_2", "", encode_krb5_sam_response_2); ktest_empty_sam_response_2(&sam_ch2); } /****************************************************************/ /* encode_krb5_sam_response_enc_2 */ { krb5_enc_sam_response_enc_2 sam_ch2; ktest_make_sample_enc_sam_response_enc_2(&sam_ch2); encode_run(sam_ch2, "enc_sam_response_enc_2", "", encode_krb5_enc_sam_response_enc_2); ktest_empty_enc_sam_response_enc_2(&sam_ch2); } /****************************************************************/ /* encode_krb5_pa_for_user */ { krb5_pa_for_user s4u; ktest_make_sample_pa_for_user(&s4u); encode_run(s4u, "pa_for_user", "", encode_krb5_pa_for_user); ktest_empty_pa_for_user(&s4u); } /****************************************************************/ /* encode_krb5_pa_s4u_x509_user */ { krb5_pa_s4u_x509_user s4u; ktest_make_sample_pa_s4u_x509_user(&s4u); encode_run(s4u, "pa_s4u_x509_user", "", encode_krb5_pa_s4u_x509_user); ktest_empty_pa_s4u_x509_user(&s4u); } /****************************************************************/ /* encode_krb5_ad_kdcissued */ { krb5_ad_kdcissued kdci; ktest_make_sample_ad_kdcissued(&kdci); encode_run(kdci, "ad_kdcissued", "", encode_krb5_ad_kdcissued); ktest_empty_ad_kdcissued(&kdci); } /****************************************************************/ /* encode_krb5_ad_signedpath_data */ { krb5_ad_signedpath_data spd; ktest_make_sample_ad_signedpath_data(&spd); encode_run(spd, "ad_signedpath_data", "", encode_krb5_ad_signedpath_data); ktest_empty_ad_signedpath_data(&spd); } /****************************************************************/ /* encode_krb5_ad_signedpath */ { krb5_ad_signedpath sp; ktest_make_sample_ad_signedpath(&sp); encode_run(sp, "ad_signedpath", "", encode_krb5_ad_signedpath); ktest_empty_ad_signedpath(&sp); } /****************************************************************/ /* encode_krb5_iakerb_header */ { krb5_iakerb_header ih; ktest_make_sample_iakerb_header(&ih); encode_run(ih, "iakerb_header", "", encode_krb5_iakerb_header); ktest_empty_iakerb_header(&ih); } /****************************************************************/ /* encode_krb5_iakerb_finished */ { krb5_iakerb_finished ih; ktest_make_sample_iakerb_finished(&ih); encode_run(ih, "iakerb_finished", "", encode_krb5_iakerb_finished); ktest_empty_iakerb_finished(&ih); } /****************************************************************/ /* encode_krb5_fast_response */ { krb5_fast_response fr; ktest_make_sample_fast_response(&fr); encode_run(fr, "fast_response", "", encode_krb5_fast_response); ktest_empty_fast_response(&fr); } /****************************************************************/ /* encode_krb5_pa_fx_fast_reply */ { krb5_enc_data enc_data; ktest_make_sample_enc_data(&enc_data); encode_run(enc_data, "pa_fx_fast_reply", "", encode_krb5_pa_fx_fast_reply); ktest_destroy_enc_data(&enc_data); } /****************************************************************/ /* encode_krb5_otp_tokeninfo */ { krb5_otp_tokeninfo ti; ktest_make_minimal_otp_tokeninfo(&ti); encode_run(ti, "otp_tokeninfo", "(optionals NULL)", encode_krb5_otp_tokeninfo); ktest_empty_otp_tokeninfo(&ti); ktest_make_maximal_otp_tokeninfo(&ti); encode_run(ti, "otp_tokeninfo", "", encode_krb5_otp_tokeninfo); ktest_empty_otp_tokeninfo(&ti); } /****************************************************************/ /* encode_krb5_pa_otp_challenge */ { krb5_pa_otp_challenge ch; ktest_make_minimal_pa_otp_challenge(&ch); encode_run(ch, "pa_otp_challenge", "(optionals NULL)", encode_krb5_pa_otp_challenge); ktest_empty_pa_otp_challenge(&ch); ktest_make_maximal_pa_otp_challenge(&ch); encode_run(ch, "pa_otp_challenge", "", encode_krb5_pa_otp_challenge); ktest_empty_pa_otp_challenge(&ch); } /****************************************************************/ /* encode_krb5_pa_otp_req */ { krb5_pa_otp_req req; ktest_make_minimal_pa_otp_req(&req); encode_run(req, "pa_otp_req", "(optionals NULL)", encode_krb5_pa_otp_req); ktest_empty_pa_otp_req(&req); ktest_make_maximal_pa_otp_req(&req); encode_run(req, "pa_otp_req", "", encode_krb5_pa_otp_req); ktest_empty_pa_otp_req(&req); } /****************************************************************/ /* encode_krb5_pa_otp_enc_request */ { krb5_data d; ktest_make_sample_data(&d); encode_run(d, "pa_otp_enc_req", "", encode_krb5_pa_otp_enc_req); ktest_empty_data(&d); } /****************************************************************/ /* encode_krb5_kkdcp_message */ { krb5_kkdcp_message info; ktest_make_sample_kkdcp_message(&info); encode_run(info, "kkdcp_message", "", encode_krb5_kkdcp_message); ktest_empty_kkdcp_message(&info); } /* encode_krb5_cammac */ { krb5_cammac req; ktest_make_minimal_cammac(&req); encode_run(req, "cammac", "(optionals NULL)", encode_krb5_cammac); ktest_empty_cammac(&req); ktest_make_maximal_cammac(&req); encode_run(req, "cammac", "", encode_krb5_cammac); ktest_empty_cammac(&req); } /****************************************************************/ /* encode_krb5_secure_cookie */ { krb5_secure_cookie cookie; ktest_make_sample_secure_cookie(&cookie); encode_run(cookie, "secure_cookie", "", encode_krb5_secure_cookie); ktest_empty_secure_cookie(&cookie); } #ifndef DISABLE_PKINIT /****************************************************************/ /* encode_krb5_pa_pk_as_req */ { krb5_pa_pk_as_req req; ktest_make_sample_pa_pk_as_req(&req); encode_run(req, "pa_pk_as_req", "", acc.encode_krb5_pa_pk_as_req); ktest_empty_pa_pk_as_req(&req); } /****************************************************************/ /* encode_krb5_pa_pk_as_req_draft9 */ { krb5_pa_pk_as_req_draft9 req; ktest_make_sample_pa_pk_as_req_draft9(&req); encode_run(req, "pa_pk_as_req_draft9", "", acc.encode_krb5_pa_pk_as_req_draft9); ktest_empty_pa_pk_as_req_draft9(&req); } /****************************************************************/ /* encode_krb5_pa_pk_as_rep */ { krb5_pa_pk_as_rep rep; ktest_make_sample_pa_pk_as_rep_dhInfo(&rep); encode_run(rep, "pa_pk_as_rep", "(dhInfo)", acc.encode_krb5_pa_pk_as_rep); ktest_empty_pa_pk_as_rep(&rep); ktest_make_sample_pa_pk_as_rep_encKeyPack(&rep); encode_run(rep, "pa_pk_as_rep", "(encKeyPack)", acc.encode_krb5_pa_pk_as_rep); ktest_empty_pa_pk_as_rep(&rep); } /****************************************************************/ /* encode_krb5_pa_pk_as_rep_draft9 */ { krb5_pa_pk_as_rep_draft9 rep; ktest_make_sample_pa_pk_as_rep_draft9_dhSignedData(&rep); encode_run(rep, "pa_pk_as_rep_draft9", "(dhSignedData)", acc.encode_krb5_pa_pk_as_rep_draft9); ktest_empty_pa_pk_as_rep_draft9(&rep); ktest_make_sample_pa_pk_as_rep_draft9_encKeyPack(&rep); encode_run(rep, "pa_pk_as_rep_draft9", "(encKeyPack)", acc.encode_krb5_pa_pk_as_rep_draft9); ktest_empty_pa_pk_as_rep_draft9(&rep); } /****************************************************************/ /* encode_krb5_auth_pack */ { krb5_auth_pack pack; ktest_make_sample_auth_pack(&pack); encode_run(pack, "auth_pack", "", acc.encode_krb5_auth_pack); ktest_empty_auth_pack(&pack); } /****************************************************************/ /* encode_krb5_auth_pack_draft9_draft9 */ { krb5_auth_pack_draft9 pack; ktest_make_sample_auth_pack_draft9(&pack); encode_run(pack, "auth_pack_draft9", "", acc.encode_krb5_auth_pack_draft9); ktest_empty_auth_pack_draft9(&pack); } /****************************************************************/ /* encode_krb5_kdc_dh_key_info */ { krb5_kdc_dh_key_info ki; ktest_make_sample_kdc_dh_key_info(&ki); encode_run(ki, "kdc_dh_key_info", "", acc.encode_krb5_kdc_dh_key_info); ktest_empty_kdc_dh_key_info(&ki); } /****************************************************************/ /* encode_krb5_reply_key_pack */ { krb5_reply_key_pack pack; ktest_make_sample_reply_key_pack(&pack); encode_run(pack, "reply_key_pack", "", acc.encode_krb5_reply_key_pack); ktest_empty_reply_key_pack(&pack); } /****************************************************************/ /* encode_krb5_reply_key_pack_draft9 */ { krb5_reply_key_pack_draft9 pack; ktest_make_sample_reply_key_pack_draft9(&pack); encode_run(pack, "reply_key_pack_draft9", "", acc.encode_krb5_reply_key_pack_draft9); ktest_empty_reply_key_pack_draft9(&pack); } /****************************************************************/ /* encode_krb5_sp80056a_other_info */ { krb5_sp80056a_other_info info; ktest_make_sample_sp80056a_other_info(&info); encode_run(info, "sp80056a_other_info", "", encode_krb5_sp80056a_other_info); ktest_empty_sp80056a_other_info(&info); } /****************************************************************/ /* encode_krb5_pkinit_supp_pub_info */ { krb5_pkinit_supp_pub_info info; ktest_make_sample_pkinit_supp_pub_info(&info); encode_run(info, "pkinit_supp_pub_info", "", encode_krb5_pkinit_supp_pub_info); ktest_empty_pkinit_supp_pub_info(&info); } #endif /* not DISABLE_PKINIT */ #ifdef ENABLE_LDAP { ldap_seqof_key_data skd; ktest_make_sample_ldap_seqof_key_data(&skd); encode_run(skd, "ldap_seqof_key_data", "", acc.asn1_ldap_encode_sequence_of_keys); ktest_empty_ldap_seqof_key_data(test_context, &skd); } #endif krb5_free_context(test_context); exit(error_count); return(error_count); } krb5-1.16/src/tests/asn.1/make-vectors.c0000644000704600001450000002516313211554426017622 0ustar ghudsonlibuuid/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* tests/asn.1/make-vectors.c - Generate ASN.1 test vectors using asn1c */ /* * Copyright (C) 2011 by the Massachusetts Institute of Technology. * All rights reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ /* * This program generates test vectors using asn1c, to be included in other * test programs which exercise the krb5 ASN.1 encoder and decoder functions. * It is intended to be used via "make test-vectors". Currently, test vectors * are only generated for a subset of newer ASN.1 objects. */ #include #include #include #include #include #include #include #include #include static unsigned char buf[8192]; static size_t buf_pos; /* PrincipalName and KRB5PrincipalName */ static KerberosString_t comp_1 = { "hftsai", 6 }; static KerberosString_t comp_2 = { "extra", 5 }; static KerberosString_t *comps[] = { &comp_1, &comp_2 }; static PrincipalName_t princ = { 1, { comps, 2, 2 } }; static KRB5PrincipalName_t krb5princ = { { "ATHENA.MIT.EDU", 14 }, { 1, { comps, 2, 2 } } }; /* OtherInfo */ static unsigned int krb5_arcs[] = { 1, 2, 840, 113554, 1, 2, 2 }; static OCTET_STRING_t krb5data_ostring = { "krb5data", 8 }; static OtherInfo_t other_info = { { 0 }, { 0 }, { 0 }, /* Initialized in main() */ &krb5data_ostring, NULL }; /* PkinitSuppPubInfo */ static PkinitSuppPubInfo_t supp_pub_info = { 1, { "krb5data", 8 }, { "krb5data", 8 } }; /* Minimal OTP-TOKENINFO */ static OTP_TOKENINFO_t token_info_1 = { { "\0\0\0\0", 4, 0 } }; /* Maximal OTP-TOKENINFO */ static UTF8String_t vendor = { "Examplecorp", 11 }; static OCTET_STRING_t challenge = { "hark!", 5 }; static Int32_t otp_length = 10; static OTPFormat_t otp_format; /* Initialized to 2 in main(). */ static OCTET_STRING_t token_id = { "yourtoken", 9 }; static AnyURI_t otp_alg = { "urn:ietf:params:xml:ns:keyprov:pskc:hotp", 40 }; static unsigned int sha256_arcs[] = { 2, 16, 840, 1, 101, 3, 4, 2, 1 }; static unsigned int sha1_arcs[] = { 1, 3, 14, 3, 2, 26 }; static AlgorithmIdentifier_t alg_sha256, alg_sha1; /* Initialized in main(). */ static AlgorithmIdentifier_t *algs[] = { &alg_sha256, &alg_sha1 }; static struct supportedHashAlg hash_algs = { algs, 2, 2 }; static Int32_t iter_count = 1000; /* Flags are nextOTP | combine | collect-pin | must-encrypt-nonce | * separate-pin-required | check-digit */ static OTP_TOKENINFO_t token_info_2 = { { "\x77\0\0\0", 4, 0 }, &vendor, &challenge, &otp_length, &otp_format, &token_id, &otp_alg, &hash_algs, &iter_count }; /* Minimal PA-OTP-CHALLENGE */ static OTP_TOKENINFO_t *tinfo_1[] = { &token_info_1 }; static PA_OTP_CHALLENGE_t challenge_1 = { { "minnonce", 8 }, NULL, { { tinfo_1, 1, 1 } } }; /* Maximal PA-OTP-CHALLENGE */ static OTP_TOKENINFO_t *tinfo_2[] = { &token_info_1, &token_info_2 }; static UTF8String_t service = { "testservice", 11 }; static KerberosString_t salt = { "keysalt", 7 }; static OCTET_STRING_t s2kparams = { "1234", 4 }; static PA_OTP_CHALLENGE_t challenge_2 = { { "maxnonce", 8 }, &service, { { tinfo_2, 2, 2 } }, &salt, &s2kparams }; /* Minimal PA-OTP-REQUEST */ static UInt32_t kvno = 5; static PA_OTP_REQUEST_t request_1 = { { "\0\0\0\0", 4, 0 }, NULL, { 0, &kvno, { "krbASN.1 test message", 21 } } }; /* Maximal PA-OTP-REQUEST */ /* Flags are nextOTP | combine */ static OCTET_STRING_t nonce = { "nonce", 5 }; static OCTET_STRING_t otp_value = { "frogs", 5 }; static UTF8String_t otp_pin = { "myfirstpin", 10 }; /* Corresponds to Unix time 771228197 */ static KerberosTime_t otp_time = { "19940610060317Z", 15 }; static OCTET_STRING_t counter = { "346", 3 }; static PA_OTP_REQUEST_t request_2 = { { "\x60\0\0\0", 4, 0 }, &nonce, { 0, &kvno, { "krbASN.1 test message", 21 } }, &alg_sha256, &iter_count, &otp_value, &otp_pin, &challenge, &otp_time, &counter, &otp_format, &token_id, &otp_alg, &vendor }; /* PA-OTP-ENC-REQUEST */ static PA_OTP_ENC_REQUEST_t enc_request = { { "krb5data", 8 } }; /* * There is no ASN.1 name for a single authorization data element, so asn1c * declares it as "struct Member" in an inner scope. This structure must be * laid out identically to that one. */ struct ad_element { Int32_t ad_type; OCTET_STRING_t ad_data; asn_struct_ctx_t _asn_ctx; }; /* Authorization data elements and lists, for use in CAMMAC */ static struct ad_element ad_1 = { 1, { "ad1", 3 } }; static struct ad_element ad_2 = { 2, { "ad2", 3 } }; static struct ad_element *adlist_1[] = { &ad_1 }; static struct ad_element *adlist_2[] = { &ad_1, &ad_2 }; /* Minimal Verifier */ static Verifier_t verifier_1 = { Verifier_PR_mac, { { NULL, NULL, NULL, { 1, { "cksum1", 6 } } } } }; /* Maximal Verifier */ static Int32_t enctype = 16; static Verifier_t verifier_2 = { Verifier_PR_mac, { { &princ, &kvno, &enctype, { 1, { "cksum2", 6 } } } } }; /* Minimal CAMMAC */ static AD_CAMMAC_t cammac_1 = { { { (void *)adlist_1, 1, 1 } }, NULL, NULL, NULL }; /* Maximal CAMMAC */ static Verifier_MAC_t vmac_1 = { &princ, &kvno, &enctype, { 1, { "cksumkdc", 8 } } }; static Verifier_MAC_t vmac_2 = { &princ, &kvno, &enctype, { 1, { "cksumsvc", 8 } } }; static Verifier_t *verifiers[] = { &verifier_1, &verifier_2 }; static struct other_verifiers overfs = { { verifiers, 2, 2 } }; static AD_CAMMAC_t cammac_2 = { { { (void *)adlist_2, 2, 2 } }, &vmac_1, &vmac_2, &overfs }; static int consume(const void *data, size_t size, void *dummy) { memcpy(buf + buf_pos, data, size); buf_pos += size; return 0; } /* Display a C string literal representing the contents of buf, and * reinitialize buf_pos for the next encoding operation. */ static void printbuf(void) { size_t i; for (i = 0; i < buf_pos; i++) { printf("%02X", buf[i]); if (i + 1 < buf_pos) printf(" "); } buf_pos = 0; } int main() { /* Initialize values which can't use static initializers. */ asn_long2INTEGER(&otp_format, 2); /* Alphanumeric */ OBJECT_IDENTIFIER_set_arcs(&alg_sha256.algorithm, sha256_arcs, sizeof(*sha256_arcs), sizeof(sha256_arcs) / sizeof(*sha256_arcs)); OBJECT_IDENTIFIER_set_arcs(&alg_sha1.algorithm, sha1_arcs, sizeof(*sha1_arcs), sizeof(sha1_arcs) / sizeof(*sha1_arcs)); OBJECT_IDENTIFIER_set_arcs(&other_info.algorithmID.algorithm, krb5_arcs, sizeof(*krb5_arcs), sizeof(krb5_arcs) / sizeof(*krb5_arcs)); printf("PrincipalName:\n"); der_encode(&asn_DEF_PrincipalName, &princ, consume, NULL); printbuf(); /* Print this encoding and also use it to initialize two fields of * other_info. */ printf("\nKRB5PrincipalName:\n"); der_encode(&asn_DEF_KRB5PrincipalName, &krb5princ, consume, NULL); OCTET_STRING_fromBuf(&other_info.partyUInfo, buf, buf_pos); OCTET_STRING_fromBuf(&other_info.partyVInfo, buf, buf_pos); printbuf(); printf("\nOtherInfo:\n"); der_encode(&asn_DEF_OtherInfo, &other_info, consume, NULL); printbuf(); free(other_info.partyUInfo.buf); free(other_info.partyVInfo.buf); printf("\nPkinitSuppPubInfo:\n"); der_encode(&asn_DEF_PkinitSuppPubInfo, &supp_pub_info, consume, NULL); printbuf(); printf("\nMinimal OTP-TOKEN-INFO:\n"); der_encode(&asn_DEF_OTP_TOKENINFO, &token_info_1, consume, NULL); printbuf(); printf("\nMaximal OTP-TOKEN-INFO:\n"); der_encode(&asn_DEF_OTP_TOKENINFO, &token_info_2, consume, NULL); printbuf(); printf("\nMinimal PA-OTP-CHALLENGE:\n"); der_encode(&asn_DEF_PA_OTP_CHALLENGE, &challenge_1, consume, NULL); printbuf(); printf("\nMaximal PA-OTP-CHALLENGE:\n"); der_encode(&asn_DEF_PA_OTP_CHALLENGE, &challenge_2, consume, NULL); printbuf(); printf("\nMinimal PA-OTP-REQUEST:\n"); der_encode(&asn_DEF_PA_OTP_REQUEST, &request_1, consume, NULL); printbuf(); printf("\nMaximal PA-OTP-REQUEST:\n"); der_encode(&asn_DEF_PA_OTP_REQUEST, &request_2, consume, NULL); printbuf(); printf("\nPA-OTP-ENC-REQUEST:\n"); der_encode(&asn_DEF_PA_OTP_ENC_REQUEST, &enc_request, consume, NULL); printbuf(); printf("\nMinimal Verifier:\n"); der_encode(&asn_DEF_Verifier, &verifier_1, consume, NULL); printbuf(); printf("\nMaximal Verifier:\n"); der_encode(&asn_DEF_Verifier, &verifier_2, consume, NULL); printbuf(); printf("\nMinimal AD-CAMMAC:\n"); der_encode(&asn_DEF_AD_CAMMAC, &cammac_1, consume, NULL); printbuf(); printf("\nMaximal AD-CAMMAC:\n"); der_encode(&asn_DEF_AD_CAMMAC, &cammac_2, consume, NULL); printbuf(); printf("\n"); return 0; } krb5-1.16/src/tests/asn.1/README0000644000704600001450000000243613211554426015734 0ustar ghudsonlibuuidkrb5_encode_test runs through all the functions declared in src/include/krb5/asn.1/krb5_encode.h. It passes various sample inputs to each function and prints the result to standard output. This output should match the contents of the file "reference_encode.out". Each function is first run with a relatively simple, contrived sample structure. Then if the structure has any optional parts, these parts are cleared and another run is made. Some structures (namely, those containing a krb5_kdc_req_body) have a third run, due to the fact that two of the kdc_req_body's optional fields have mutually exclusive conditions under which they may be omitted. krb5_decode_test runs through all the functions declared in src/include/krb5/asn.1/krb5_decode.h. It has the encodings in reference_encode.out hard-coded into itself. It sets up the krb5 structures the same way krb5_encode_test does, then passes its hard-coded encoding strings through the krb5 decoders. The outputs of these functions are compared to the previously set-up structures in memory, and the results are reported to standard output. If every line comes out prefixed by "OK: ", then the decoders are working properly. If any decoder produces an anomalous output, then its output line will be prefixed by "ERROR: " krb5-1.16/src/tests/asn.1/utility.c0000644000704600001450000001012113211554426016711 0ustar ghudsonlibuuid/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* tests/asn.1/utility.c */ /* * Copyright (C) 1994 by the Massachusetts Institute of Technology. * All rights reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #include "utility.h" #include "krb5.h" #include #include #include krb5int_access acc; char hexchar (const unsigned int digit); void * ealloc(size_t size) { void *ptr = calloc(1, size); if (ptr == NULL) abort(); return ptr; } char * estrdup(const char *str) { char *newstr = strdup(str); if (newstr == NULL) abort(); return newstr; } void asn1_krb5_data_unparse(const krb5_data *code, char **s) { if (*s != NULL) free(*s); if (code==NULL) { *s = estrdup(""); } else if (code->data == NULL || ((int) code->length) <= 0) { *s = estrdup(""); } else { unsigned int i; *s = ealloc(3 * code->length); for (i = 0; i < code->length; i++) { (*s)[3*i] = hexchar((unsigned char) (((code->data)[i]&0xF0)>>4)); (*s)[3*i+1] = hexchar((unsigned char) ((code->data)[i]&0x0F)); (*s)[3*i+2] = ' '; } (*s)[3*(code->length)-1] = '\0'; } } char hexchar(const unsigned int digit) { if (digit<=9) return '0'+digit; else if (digit<=15) return 'A'+digit-10; else return 'X'; } void krb5_data_parse(krb5_data *d, const char *s) { d->length = strlen(s); d->data = ealloc(d->length); memcpy(d->data, s, d->length); } asn1_error_code krb5_data_hex_parse(krb5_data *d, const char *s) { int lo; long v; const char *cp; char *dp; char buf[2]; d->data = ealloc(strlen(s) / 2 + 1); d->length = 0; buf[1] = '\0'; for (lo = 0, dp = d->data, cp = s; *cp; cp++) { if (*cp < 0) return ASN1_PARSE_ERROR; else if (isspace((unsigned char) *cp)) continue; else if (isxdigit((unsigned char) *cp)) { buf[0] = *cp; v = strtol(buf, NULL, 16); } else return ASN1_PARSE_ERROR; if (lo) { *dp++ |= v; lo = 0; } else { *dp = v << 4; lo = 1; } } d->length = dp - d->data; return 0; } #if 0 void asn1buf_print(const asn1buf *buf) { asn1buf bufcopy; char *s=NULL; int length; int i; bufcopy.base = bufcopy.next = buf->next; bufcopy.bound = buf->bound; length = asn1buf_len(&bufcopy); s = calloc(3*length, sizeof(char)); if (s == NULL) return; for (i=0; i>4); s[3*i+1] = hexchar((bufcopy.base)[i]&0x0F); s[3*i+2] = ' '; } s[3*length-1] = '\0'; printf("%s\n",s); free(s); } #endif void init_access(const char *progname) { krb5_error_code ret; ret = krb5int_accessor(&acc, KRB5INT_ACCESS_VERSION); if (ret) { com_err(progname, ret, "while initializing accessor"); exit(1); } } krb5-1.16/src/tests/asn.1/krb5.asn10000644000704600001450000003156613211554426016511 0ustar ghudsonlibuuidKerberosV5Spec2 { iso(1) identified-organization(3) dod(6) internet(1) security(5) kerberosV5(2) modules(4) krb5spec2(2) } DEFINITIONS EXPLICIT TAGS ::= BEGIN -- OID arc for KerberosV5 -- -- This OID may be used to identify Kerberos protocol messages -- encapsulated in other protocols. -- -- This OID also designates the OID arc for KerberosV5-related OIDs. -- -- NOTE: RFC 1510 had an incorrect value (5) for "dod" in its OID. id-krb5 OBJECT IDENTIFIER ::= { iso(1) identified-organization(3) dod(6) internet(1) security(5) kerberosV5(2) } Int32 ::= INTEGER (-2147483648..2147483647) -- signed values representable in 32 bits UInt32 ::= INTEGER (0..4294967295) -- unsigned 32 bit values Microseconds ::= INTEGER (0..999999) -- microseconds KerberosString ::= GeneralString -- (IA5String) Realm ::= KerberosString PrincipalName ::= SEQUENCE { name-type [0] Int32, name-string [1] SEQUENCE OF KerberosString } KerberosTime ::= GeneralizedTime -- with no fractional seconds HostAddress ::= SEQUENCE { addr-type [0] Int32, address [1] OCTET STRING } -- NOTE: HostAddresses is always used as an OPTIONAL field and -- should not be empty. HostAddresses -- NOTE: subtly different from rfc1510, -- but has a value mapping and encodes the same ::= SEQUENCE OF HostAddress -- NOTE: AuthorizationData is always used as an OPTIONAL field and -- should not be empty. AuthorizationData ::= SEQUENCE OF SEQUENCE { ad-type [0] Int32, ad-data [1] OCTET STRING } PA-DATA ::= SEQUENCE { -- NOTE: first tag is [1], not [0] padata-type [1] Int32, padata-value [2] OCTET STRING -- might be encoded AP-REQ } KerberosFlags ::= BIT STRING (SIZE (32..MAX)) -- minimum number of bits shall be sent, -- but no fewer than 32 EncryptedData ::= SEQUENCE { etype [0] Int32 -- EncryptionType --, kvno [1] UInt32 OPTIONAL, cipher [2] OCTET STRING -- ciphertext } EncryptionKey ::= SEQUENCE { keytype [0] Int32 -- actually encryption type --, keyvalue [1] OCTET STRING } Checksum ::= SEQUENCE { cksumtype [0] Int32, checksum [1] OCTET STRING } Ticket ::= [APPLICATION 1] SEQUENCE { tkt-vno [0] INTEGER (5), realm [1] Realm, sname [2] PrincipalName, enc-part [3] EncryptedData -- EncTicketPart } -- Encrypted part of ticket EncTicketPart ::= [APPLICATION 3] SEQUENCE { flags [0] TicketFlags, key [1] EncryptionKey, crealm [2] Realm, cname [3] PrincipalName, transited [4] TransitedEncoding, authtime [5] KerberosTime, starttime [6] KerberosTime OPTIONAL, endtime [7] KerberosTime, renew-till [8] KerberosTime OPTIONAL, caddr [9] HostAddresses OPTIONAL, authorization-data [10] AuthorizationData OPTIONAL } -- encoded Transited field TransitedEncoding ::= SEQUENCE { tr-type [0] Int32 -- must be registered --, contents [1] OCTET STRING } TicketFlags ::= KerberosFlags -- reserved(0), -- forwardable(1), -- forwarded(2), -- proxiable(3), -- proxy(4), -- may-postdate(5), -- postdated(6), -- invalid(7), -- renewable(8), -- initial(9), -- pre-authent(10), -- hw-authent(11), -- the following are new since 1510 -- transited-policy-checked(12), -- ok-as-delegate(13) AS-REQ ::= [APPLICATION 10] KDC-REQ TGS-REQ ::= [APPLICATION 12] KDC-REQ KDC-REQ ::= SEQUENCE { -- NOTE: first tag is [1], not [0] pvno [1] INTEGER (5) , msg-type [2] INTEGER (10 -- AS -- | 12 -- TGS --), padata [3] SEQUENCE OF PA-DATA OPTIONAL -- NOTE: not empty --, req-body [4] KDC-REQ-BODY } KDC-REQ-BODY ::= SEQUENCE { kdc-options [0] KDCOptions, cname [1] PrincipalName OPTIONAL -- Used only in AS-REQ --, realm [2] Realm -- Server's realm -- Also client's in AS-REQ --, sname [3] PrincipalName OPTIONAL, from [4] KerberosTime OPTIONAL, till [5] KerberosTime, rtime [6] KerberosTime OPTIONAL, nonce [7] UInt32, etype [8] SEQUENCE OF Int32 -- EncryptionType -- in preference order --, addresses [9] HostAddresses OPTIONAL, enc-authorization-data [10] EncryptedData OPTIONAL -- AuthorizationData --, additional-tickets [11] SEQUENCE OF Ticket OPTIONAL -- NOTE: not empty } KDCOptions ::= KerberosFlags -- reserved(0), -- forwardable(1), -- forwarded(2), -- proxiable(3), -- proxy(4), -- allow-postdate(5), -- postdated(6), -- unused7(7), -- renewable(8), -- unused9(9), -- unused10(10), -- opt-hardware-auth(11), -- unused12(12), -- unused13(13), -- 15 is reserved for canonicalize -- unused15(15), -- 26 was unused in 1510 -- disable-transited-check(26), -- -- renewable-ok(27), -- enc-tkt-in-skey(28), -- renew(30), -- validate(31) AS-REP ::= [APPLICATION 11] KDC-REP TGS-REP ::= [APPLICATION 13] KDC-REP KDC-REP ::= SEQUENCE { pvno [0] INTEGER (5), msg-type [1] INTEGER (11 -- AS -- | 13 -- TGS --), padata [2] SEQUENCE OF PA-DATA OPTIONAL -- NOTE: not empty --, crealm [3] Realm, cname [4] PrincipalName, ticket [5] Ticket, enc-part [6] EncryptedData -- EncASRepPart or EncTGSRepPart, -- as appropriate } EncASRepPart ::= [APPLICATION 25] EncKDCRepPart EncTGSRepPart ::= [APPLICATION 26] EncKDCRepPart EncKDCRepPart ::= SEQUENCE { key [0] EncryptionKey, last-req [1] LastReq, nonce [2] UInt32, key-expiration [3] KerberosTime OPTIONAL, flags [4] TicketFlags, authtime [5] KerberosTime, starttime [6] KerberosTime OPTIONAL, endtime [7] KerberosTime, renew-till [8] KerberosTime OPTIONAL, srealm [9] Realm, sname [10] PrincipalName, caddr [11] HostAddresses OPTIONAL } LastReq ::= SEQUENCE OF SEQUENCE { lr-type [0] Int32, lr-value [1] KerberosTime } AP-REQ ::= [APPLICATION 14] SEQUENCE { pvno [0] INTEGER (5), msg-type [1] INTEGER (14), ap-options [2] APOptions, ticket [3] Ticket, authenticator [4] EncryptedData -- Authenticator } APOptions ::= KerberosFlags -- reserved(0), -- use-session-key(1), -- mutual-required(2) -- Unencrypted authenticator Authenticator ::= [APPLICATION 2] SEQUENCE { authenticator-vno [0] INTEGER (5), crealm [1] Realm, cname [2] PrincipalName, cksum [3] Checksum OPTIONAL, cusec [4] Microseconds, ctime [5] KerberosTime, subkey [6] EncryptionKey OPTIONAL, seq-number [7] UInt32 OPTIONAL, authorization-data [8] AuthorizationData OPTIONAL } AP-REP ::= [APPLICATION 15] SEQUENCE { pvno [0] INTEGER (5), msg-type [1] INTEGER (15), enc-part [2] EncryptedData -- EncAPRepPart } EncAPRepPart ::= [APPLICATION 27] SEQUENCE { ctime [0] KerberosTime, cusec [1] Microseconds, subkey [2] EncryptionKey OPTIONAL, seq-number [3] UInt32 OPTIONAL } KRB-SAFE ::= [APPLICATION 20] SEQUENCE { pvno [0] INTEGER (5), msg-type [1] INTEGER (20), safe-body [2] KRB-SAFE-BODY, cksum [3] Checksum } KRB-SAFE-BODY ::= SEQUENCE { user-data [0] OCTET STRING, timestamp [1] KerberosTime OPTIONAL, usec [2] Microseconds OPTIONAL, seq-number [3] UInt32 OPTIONAL, s-address [4] HostAddress, r-address [5] HostAddress OPTIONAL } KRB-PRIV ::= [APPLICATION 21] SEQUENCE { pvno [0] INTEGER (5), msg-type [1] INTEGER (21), -- NOTE: there is no [2] tag enc-part [3] EncryptedData -- EncKrbPrivPart } EncKrbPrivPart ::= [APPLICATION 28] SEQUENCE { user-data [0] OCTET STRING, timestamp [1] KerberosTime OPTIONAL, usec [2] Microseconds OPTIONAL, seq-number [3] UInt32 OPTIONAL, s-address [4] HostAddress -- sender's addr --, r-address [5] HostAddress OPTIONAL -- recip's addr } KRB-CRED ::= [APPLICATION 22] SEQUENCE { pvno [0] INTEGER (5), msg-type [1] INTEGER (22), tickets [2] SEQUENCE OF Ticket, enc-part [3] EncryptedData -- EncKrbCredPart } EncKrbCredPart ::= [APPLICATION 29] SEQUENCE { ticket-info [0] SEQUENCE OF KrbCredInfo, nonce [1] UInt32 OPTIONAL, timestamp [2] KerberosTime OPTIONAL, usec [3] Microseconds OPTIONAL, s-address [4] HostAddress OPTIONAL, r-address [5] HostAddress OPTIONAL } KrbCredInfo ::= SEQUENCE { key [0] EncryptionKey, prealm [1] Realm OPTIONAL, pname [2] PrincipalName OPTIONAL, flags [3] TicketFlags OPTIONAL, authtime [4] KerberosTime OPTIONAL, starttime [5] KerberosTime OPTIONAL, endtime [6] KerberosTime OPTIONAL, renew-till [7] KerberosTime OPTIONAL, srealm [8] Realm OPTIONAL, sname [9] PrincipalName OPTIONAL, caddr [10] HostAddresses OPTIONAL } KRB-ERROR ::= [APPLICATION 30] SEQUENCE { pvno [0] INTEGER (5), msg-type [1] INTEGER (30), ctime [2] KerberosTime OPTIONAL, cusec [3] Microseconds OPTIONAL, stime [4] KerberosTime, susec [5] Microseconds, error-code [6] Int32, crealm [7] Realm OPTIONAL, cname [8] PrincipalName OPTIONAL, realm [9] Realm -- service realm --, sname [10] PrincipalName -- service name --, e-text [11] KerberosString OPTIONAL, e-data [12] OCTET STRING OPTIONAL } METHOD-DATA ::= SEQUENCE OF PA-DATA TYPED-DATA ::= SEQUENCE SIZE (1..MAX) OF SEQUENCE { data-type [0] Int32, data-value [1] OCTET STRING OPTIONAL } -- preauth stuff follows PA-ENC-TIMESTAMP ::= EncryptedData -- PA-ENC-TS-ENC PA-ENC-TS-ENC ::= SEQUENCE { patimestamp [0] KerberosTime -- client's time --, pausec [1] Microseconds OPTIONAL } ETYPE-INFO-ENTRY ::= SEQUENCE { etype [0] Int32, salt [1] OCTET STRING OPTIONAL } ETYPE-INFO ::= SEQUENCE OF ETYPE-INFO-ENTRY ETYPE-INFO2-ENTRY ::= SEQUENCE { etype [0] Int32, salt [1] KerberosString OPTIONAL, s2kparams [2] OCTET STRING OPTIONAL } ETYPE-INFO2 ::= SEQUENCE SIZE (1..MAX) OF ETYPE-INFO2-ENTRY AD-IF-RELEVANT ::= AuthorizationData AD-KDCIssued ::= SEQUENCE { ad-checksum [0] Checksum, i-realm [1] Realm OPTIONAL, i-sname [2] PrincipalName OPTIONAL, elements [3] AuthorizationData } AD-AND-OR ::= SEQUENCE { condition-count [0] Int32, elements [1] AuthorizationData } AD-MANDATORY-FOR-KDC ::= AuthorizationData END krb5-1.16/src/tests/asn.1/ktest.h0000644000704600001450000002417113211554426016357 0ustar ghudsonlibuuid/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* tests/asn.1/ktest.h */ /* * Copyright (C) 1994 by the Massachusetts Institute of Technology. * All rights reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #ifndef __KTEST_H__ #define __KTEST_H__ #include "k5-int.h" #include "kdb.h" #define SAMPLE_USEC 123456 #define SAMPLE_TIME 771228197 /* Fri Jun 10 6:03:17 GMT 1994 */ #define SAMPLE_SEQ_NUMBER 17 #define SAMPLE_NONCE 42 #define SAMPLE_FLAGS 0xFEDCBA98 #define SAMPLE_ERROR 0x3C; void ktest_make_sample_data(krb5_data *d); void ktest_make_sample_authenticator(krb5_authenticator *a); void ktest_make_sample_principal(krb5_principal *p); void ktest_make_sample_checksum(krb5_checksum *cs); void ktest_make_sample_keyblock(krb5_keyblock *kb); void ktest_make_sample_ticket(krb5_ticket *tkt); void ktest_make_sample_enc_data(krb5_enc_data *ed); void ktest_make_sample_enc_tkt_part(krb5_enc_tkt_part *etp); void ktest_make_sample_transited(krb5_transited *t); void ktest_make_sample_ticket_times(krb5_ticket_times *tt); void ktest_make_sample_addresses(krb5_address ***caddrs); void ktest_make_sample_address(krb5_address *a); void ktest_make_sample_authorization_data(krb5_authdata ***ad); void ktest_make_sample_authdata(krb5_authdata *ad); void ktest_make_sample_enc_kdc_rep_part(krb5_enc_kdc_rep_part *ekr); void ktest_make_sample_kdc_req(krb5_kdc_req *kr); void ktest_make_sample_last_req(krb5_last_req_entry ***lr); void ktest_make_sample_last_req_entry(krb5_last_req_entry **lre); void ktest_make_sample_kdc_rep(krb5_kdc_rep *kdcr); void ktest_make_sample_pa_data_array(krb5_pa_data ***pad); void ktest_make_sample_empty_pa_data_array(krb5_pa_data ***pad); void ktest_make_sample_pa_data(krb5_pa_data *pad); void ktest_make_sample_ap_req(krb5_ap_req *ar); void ktest_make_sample_ap_rep(krb5_ap_rep *ar); void ktest_make_sample_ap_rep_enc_part(krb5_ap_rep_enc_part *arep); void ktest_make_sample_kdc_req_body(krb5_kdc_req *krb); void ktest_make_sample_safe(krb5_safe *s); void ktest_make_sample_priv(krb5_priv *p); void ktest_make_sample_priv_enc_part(krb5_priv_enc_part *pep); void ktest_make_sample_cred(krb5_cred *c); void ktest_make_sample_cred_enc_part(krb5_cred_enc_part *cep); void ktest_make_sample_sequence_of_ticket(krb5_ticket ***sot); void ktest_make_sample_error(krb5_error *kerr); void ktest_make_sequence_of_cred_info(krb5_cred_info ***soci); void ktest_make_sample_cred_info(krb5_cred_info *ci); void ktest_make_sample_etype_info(krb5_etype_info_entry ***p); void ktest_make_sample_etype_info2(krb5_etype_info_entry ***p); void ktest_make_sample_pa_enc_ts(krb5_pa_enc_ts *am); void ktest_make_sample_sam_challenge_2(krb5_sam_challenge_2 *p); void ktest_make_sample_sam_challenge_2_body(krb5_sam_challenge_2_body *p); void ktest_make_sample_sam_response_2(krb5_sam_response_2 *p); void ktest_make_sample_enc_sam_response_enc_2(krb5_enc_sam_response_enc_2 *p); void ktest_make_sample_pa_for_user(krb5_pa_for_user *p); void ktest_make_sample_pa_s4u_x509_user(krb5_pa_s4u_x509_user *p); void ktest_make_sample_ad_kdcissued(krb5_ad_kdcissued *p); void ktest_make_sample_ad_signedpath_data(krb5_ad_signedpath_data *p); void ktest_make_sample_ad_signedpath(krb5_ad_signedpath *p); void ktest_make_sample_iakerb_header(krb5_iakerb_header *p); void ktest_make_sample_iakerb_finished(krb5_iakerb_finished *p); void ktest_make_sample_fast_response(krb5_fast_response *p); void ktest_make_sha256_alg(krb5_algorithm_identifier *p); void ktest_make_sha1_alg(krb5_algorithm_identifier *p); void ktest_make_minimal_otp_tokeninfo(krb5_otp_tokeninfo *p); void ktest_make_maximal_otp_tokeninfo(krb5_otp_tokeninfo *p); void ktest_make_minimal_pa_otp_challenge(krb5_pa_otp_challenge *p); void ktest_make_maximal_pa_otp_challenge(krb5_pa_otp_challenge *p); void ktest_make_minimal_pa_otp_req(krb5_pa_otp_req *p); void ktest_make_maximal_pa_otp_req(krb5_pa_otp_req *p); #ifndef DISABLE_PKINIT void ktest_make_sample_pa_pk_as_req(krb5_pa_pk_as_req *p); void ktest_make_sample_pa_pk_as_req_draft9(krb5_pa_pk_as_req_draft9 *p); void ktest_make_sample_pa_pk_as_rep_dhInfo(krb5_pa_pk_as_rep *p); void ktest_make_sample_pa_pk_as_rep_encKeyPack(krb5_pa_pk_as_rep *p); void ktest_make_sample_pa_pk_as_rep_draft9_dhSignedData( krb5_pa_pk_as_rep_draft9 *p); void ktest_make_sample_pa_pk_as_rep_draft9_encKeyPack( krb5_pa_pk_as_rep_draft9 *p); void ktest_make_sample_auth_pack(krb5_auth_pack *p); void ktest_make_sample_auth_pack_draft9(krb5_auth_pack_draft9 *p); void ktest_make_sample_kdc_dh_key_info(krb5_kdc_dh_key_info *p); void ktest_make_sample_reply_key_pack(krb5_reply_key_pack *p); void ktest_make_sample_reply_key_pack_draft9(krb5_reply_key_pack_draft9 *p); void ktest_make_sample_sp80056a_other_info(krb5_sp80056a_other_info *p); void ktest_make_sample_pkinit_supp_pub_info(krb5_pkinit_supp_pub_info *p); #endif #ifdef ENABLE_LDAP void ktest_make_sample_ldap_seqof_key_data(ldap_seqof_key_data *p); #endif void ktest_make_sample_kkdcp_message(krb5_kkdcp_message *p); void ktest_make_minimal_cammac(krb5_cammac *p); void ktest_make_maximal_cammac(krb5_cammac *p); void ktest_make_sample_secure_cookie(krb5_secure_cookie *p); /*----------------------------------------------------------------------*/ void ktest_empty_authorization_data(krb5_authdata **ad); void ktest_destroy_authorization_data(krb5_authdata ***ad); void ktest_destroy_authorization_data(krb5_authdata ***ad); void ktest_empty_addresses(krb5_address **a); void ktest_destroy_addresses(krb5_address ***a); void ktest_destroy_address(krb5_address **a); void ktest_empty_pa_data_array(krb5_pa_data **pad); void ktest_destroy_pa_data_array(krb5_pa_data ***pad); void ktest_destroy_pa_data(krb5_pa_data **pad); void ktest_destroy_data(krb5_data **d); void ktest_empty_data(krb5_data *d); void ktest_destroy_principal(krb5_principal *p); void ktest_destroy_checksum(krb5_checksum **cs); void ktest_empty_keyblock(krb5_keyblock *kb); void ktest_destroy_keyblock(krb5_keyblock **kb); void ktest_destroy_authdata(krb5_authdata **ad); void ktest_destroy_sequence_of_integer(long **soi); void ktest_destroy_sequence_of_ticket(krb5_ticket ***sot); void ktest_destroy_ticket(krb5_ticket **tkt); void ktest_empty_ticket(krb5_ticket *tkt); void ktest_destroy_enc_data(krb5_enc_data *ed); void ktest_empty_error(krb5_error *kerr); void ktest_destroy_etype_info_entry(krb5_etype_info_entry *i); void ktest_destroy_etype_info(krb5_etype_info_entry **info); void ktest_empty_kdc_req(krb5_kdc_req *kr); void ktest_empty_kdc_rep(krb5_kdc_rep *kr); void ktest_empty_authenticator(krb5_authenticator *a); void ktest_empty_enc_tkt_part(krb5_enc_tkt_part *etp); void ktest_destroy_enc_tkt_part(krb5_enc_tkt_part **etp); void ktest_empty_enc_kdc_rep_part(krb5_enc_kdc_rep_part *ekr); void ktest_destroy_transited(krb5_transited *t); void ktest_empty_ap_rep(krb5_ap_rep *ar); void ktest_empty_ap_req(krb5_ap_req *ar); void ktest_empty_cred_enc_part(krb5_cred_enc_part *cep); void ktest_destroy_cred_info(krb5_cred_info **ci); void ktest_destroy_sequence_of_cred_info(krb5_cred_info ***soci); void ktest_empty_safe(krb5_safe *s); void ktest_empty_priv(krb5_priv *p); void ktest_empty_priv_enc_part(krb5_priv_enc_part *pep); void ktest_empty_cred(krb5_cred *c); void ktest_destroy_last_req(krb5_last_req_entry ***lr); void ktest_empty_ap_rep_enc_part(krb5_ap_rep_enc_part *arep); void ktest_empty_sam_challenge_2(krb5_sam_challenge_2 *p); void ktest_empty_sam_challenge_2_body(krb5_sam_challenge_2_body *p); void ktest_empty_sam_response_2(krb5_sam_response_2 *p); void ktest_empty_enc_sam_response_enc_2(krb5_enc_sam_response_enc_2 *p); void ktest_empty_pa_for_user(krb5_pa_for_user *p); void ktest_empty_pa_s4u_x509_user(krb5_pa_s4u_x509_user *p); void ktest_empty_ad_kdcissued(krb5_ad_kdcissued *p); void ktest_empty_ad_signedpath_data(krb5_ad_signedpath_data *p); void ktest_empty_ad_signedpath(krb5_ad_signedpath *p); void ktest_empty_iakerb_header(krb5_iakerb_header *p); void ktest_empty_iakerb_finished(krb5_iakerb_finished *p); void ktest_empty_fast_response(krb5_fast_response *p); void ktest_empty_otp_tokeninfo(krb5_otp_tokeninfo *p); void ktest_empty_pa_otp_challenge(krb5_pa_otp_challenge *p); void ktest_empty_pa_otp_req(krb5_pa_otp_req *p); #ifndef DISABLE_PKINIT void ktest_empty_pa_pk_as_req(krb5_pa_pk_as_req *p); void ktest_empty_pa_pk_as_req_draft9(krb5_pa_pk_as_req_draft9 *p); void ktest_empty_pa_pk_as_rep(krb5_pa_pk_as_rep *p); void ktest_empty_pa_pk_as_rep_draft9(krb5_pa_pk_as_rep_draft9 *p); void ktest_empty_auth_pack(krb5_auth_pack *p); void ktest_empty_auth_pack_draft9(krb5_auth_pack_draft9 *p); void ktest_empty_kdc_dh_key_info(krb5_kdc_dh_key_info *p); void ktest_empty_reply_key_pack(krb5_reply_key_pack *p); void ktest_empty_reply_key_pack_draft9(krb5_reply_key_pack_draft9 *p); void ktest_empty_sp80056a_other_info(krb5_sp80056a_other_info *p); void ktest_empty_pkinit_supp_pub_info(krb5_pkinit_supp_pub_info *p); #endif #ifdef ENABLE_LDAP void ktest_empty_ldap_seqof_key_data(krb5_context, ldap_seqof_key_data *p); #endif void ktest_empty_kkdcp_message(krb5_kkdcp_message *p); void ktest_empty_cammac(krb5_cammac *p); void ktest_empty_secure_cookie(krb5_secure_cookie *p); extern krb5_context test_context; extern char *sample_principal_name; #endif krb5-1.16/src/tests/asn.1/reference_encode.out0000644000704600001450000007504013211554426021061 0ustar ghudsonlibuuidencode_krb5_authenticator: 62 81 A1 30 81 9E A0 03 02 01 05 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A3 0F 30 0D A0 03 02 01 01 A1 06 04 04 31 32 33 34 A4 05 02 03 01 E2 40 A5 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A6 13 30 11 A0 03 02 01 01 A1 0A 04 08 31 32 33 34 35 36 37 38 A7 03 02 01 11 A8 24 30 22 30 0F A0 03 02 01 01 A1 08 04 06 66 6F 6F 62 61 72 30 0F A0 03 02 01 01 A1 08 04 06 66 6F 6F 62 61 72 encode_krb5_authenticator(optionals empty): 62 4F 30 4D A0 03 02 01 05 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A4 05 02 03 01 E2 40 A5 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A encode_krb5_authenticator(optionals NULL): 62 4F 30 4D A0 03 02 01 05 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A4 05 02 03 01 E2 40 A5 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A encode_krb5_ticket: 61 5C 30 5A A0 03 02 01 05 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A3 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65 encode_krb5_keyblock: 30 11 A0 03 02 01 01 A1 0A 04 08 31 32 33 34 35 36 37 38 encode_krb5_enc_tkt_part: 63 82 01 14 30 82 01 10 A0 07 03 05 00 FE DC BA 98 A1 13 30 11 A0 03 02 01 01 A1 0A 04 08 31 32 33 34 35 36 37 38 A2 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A3 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A4 2E 30 2C A0 03 02 01 01 A1 25 04 23 45 44 55 2C 4D 49 54 2E 2C 41 54 48 45 4E 41 2E 2C 57 41 53 48 49 4E 47 54 4F 4E 2E 45 44 55 2C 43 53 2E A5 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A6 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A7 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A8 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A9 20 30 1E 30 0D A0 03 02 01 02 A1 06 04 04 12 D0 00 23 30 0D A0 03 02 01 02 A1 06 04 04 12 D0 00 23 AA 24 30 22 30 0F A0 03 02 01 01 A1 08 04 06 66 6F 6F 62 61 72 30 0F A0 03 02 01 01 A1 08 04 06 66 6F 6F 62 61 72 encode_krb5_enc_tkt_part(optionals NULL): 63 81 A5 30 81 A2 A0 07 03 05 00 FE DC BA 98 A1 13 30 11 A0 03 02 01 01 A1 0A 04 08 31 32 33 34 35 36 37 38 A2 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A3 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A4 2E 30 2C A0 03 02 01 01 A1 25 04 23 45 44 55 2C 4D 49 54 2E 2C 41 54 48 45 4E 41 2E 2C 57 41 53 48 49 4E 47 54 4F 4E 2E 45 44 55 2C 43 53 2E A5 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A7 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A encode_krb5_enc_kdc_rep_part: 7A 82 01 0E 30 82 01 0A A0 13 30 11 A0 03 02 01 01 A1 0A 04 08 31 32 33 34 35 36 37 38 A1 36 30 34 30 18 A0 03 02 01 FB A1 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A 30 18 A0 03 02 01 FB A1 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A2 03 02 01 2A A3 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A4 07 03 05 00 FE DC BA 98 A5 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A6 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A7 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A8 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A9 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 AA 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 AB 20 30 1E 30 0D A0 03 02 01 02 A1 06 04 04 12 D0 00 23 30 0D A0 03 02 01 02 A1 06 04 04 12 D0 00 23 encode_krb5_enc_kdc_rep_part(optionals NULL): 7A 81 B2 30 81 AF A0 13 30 11 A0 03 02 01 01 A1 0A 04 08 31 32 33 34 35 36 37 38 A1 36 30 34 30 18 A0 03 02 01 FB A1 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A 30 18 A0 03 02 01 FB A1 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A2 03 02 01 2A A4 07 03 05 00 FE 5C BA 98 A5 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A7 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A9 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 AA 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 encode_krb5_as_rep: 6B 81 EA 30 81 E7 A0 03 02 01 05 A1 03 02 01 0B A2 26 30 24 30 10 A1 03 02 01 0D A2 09 04 07 70 61 2D 64 61 74 61 30 10 A1 03 02 01 0D A2 09 04 07 70 61 2D 64 61 74 61 A3 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A4 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A5 5E 61 5C 30 5A A0 03 02 01 05 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A3 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65 A6 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65 encode_krb5_as_rep(optionals NULL): 6B 81 C2 30 81 BF A0 03 02 01 05 A1 03 02 01 0B A3 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A4 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A5 5E 61 5C 30 5A A0 03 02 01 05 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A3 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65 A6 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65 encode_krb5_tgs_rep: 6D 81 EA 30 81 E7 A0 03 02 01 05 A1 03 02 01 0D A2 26 30 24 30 10 A1 03 02 01 0D A2 09 04 07 70 61 2D 64 61 74 61 30 10 A1 03 02 01 0D A2 09 04 07 70 61 2D 64 61 74 61 A3 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A4 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A5 5E 61 5C 30 5A A0 03 02 01 05 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A3 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65 A6 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65 encode_krb5_tgs_rep(optionals NULL): 6D 81 C2 30 81 BF A0 03 02 01 05 A1 03 02 01 0D A3 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A4 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A5 5E 61 5C 30 5A A0 03 02 01 05 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A3 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65 A6 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65 encode_krb5_ap_req: 6E 81 9D 30 81 9A A0 03 02 01 05 A1 03 02 01 0E A2 07 03 05 00 FE DC BA 98 A3 5E 61 5C 30 5A A0 03 02 01 05 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A3 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65 A4 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65 encode_krb5_ap_rep: 6F 33 30 31 A0 03 02 01 05 A1 03 02 01 0F A2 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65 encode_krb5_ap_rep_enc_part: 7B 36 30 34 A0 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A1 05 02 03 01 E2 40 A2 13 30 11 A0 03 02 01 01 A1 0A 04 08 31 32 33 34 35 36 37 38 A3 03 02 01 11 encode_krb5_ap_rep_enc_part(optionals NULL): 7B 1C 30 1A A0 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A1 05 02 03 01 E2 40 encode_krb5_as_req: 6A 82 01 E4 30 82 01 E0 A1 03 02 01 05 A2 03 02 01 0A A3 26 30 24 30 10 A1 03 02 01 0D A2 09 04 07 70 61 2D 64 61 74 61 30 10 A1 03 02 01 0D A2 09 04 07 70 61 2D 64 61 74 61 A4 82 01 AA 30 82 01 A6 A0 07 03 05 00 FE DC BA 90 A1 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A2 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A3 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A4 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A5 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A6 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A7 03 02 01 2A A8 08 30 06 02 01 00 02 01 01 A9 20 30 1E 30 0D A0 03 02 01 02 A1 06 04 04 12 D0 00 23 30 0D A0 03 02 01 02 A1 06 04 04 12 D0 00 23 AA 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65 AB 81 BF 30 81 BC 61 5C 30 5A A0 03 02 01 05 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A3 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65 61 5C 30 5A A0 03 02 01 05 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A3 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65 encode_krb5_as_req(optionals NULL except second_ticket): 6A 82 01 14 30 82 01 10 A1 03 02 01 05 A2 03 02 01 0A A4 82 01 02 30 81 FF A0 07 03 05 00 FE DC BA 98 A2 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A5 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A7 03 02 01 2A A8 08 30 06 02 01 00 02 01 01 AB 81 BF 30 81 BC 61 5C 30 5A A0 03 02 01 05 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A3 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65 61 5C 30 5A A0 03 02 01 05 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A3 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65 encode_krb5_as_req(optionals NULL except server): 6A 69 30 67 A1 03 02 01 05 A2 03 02 01 0A A4 5B 30 59 A0 07 03 05 00 FE DC BA 90 A2 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A3 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A5 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A7 03 02 01 2A A8 08 30 06 02 01 00 02 01 01 encode_krb5_tgs_req: 6C 82 01 E4 30 82 01 E0 A1 03 02 01 05 A2 03 02 01 0C A3 26 30 24 30 10 A1 03 02 01 0D A2 09 04 07 70 61 2D 64 61 74 61 30 10 A1 03 02 01 0D A2 09 04 07 70 61 2D 64 61 74 61 A4 82 01 AA 30 82 01 A6 A0 07 03 05 00 FE DC BA 90 A1 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A2 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A3 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A4 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A5 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A6 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A7 03 02 01 2A A8 08 30 06 02 01 00 02 01 01 A9 20 30 1E 30 0D A0 03 02 01 02 A1 06 04 04 12 D0 00 23 30 0D A0 03 02 01 02 A1 06 04 04 12 D0 00 23 AA 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65 AB 81 BF 30 81 BC 61 5C 30 5A A0 03 02 01 05 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A3 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65 61 5C 30 5A A0 03 02 01 05 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A3 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65 encode_krb5_tgs_req(optionals NULL except second_ticket): 6C 82 01 14 30 82 01 10 A1 03 02 01 05 A2 03 02 01 0C A4 82 01 02 30 81 FF A0 07 03 05 00 FE DC BA 98 A2 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A5 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A7 03 02 01 2A A8 08 30 06 02 01 00 02 01 01 AB 81 BF 30 81 BC 61 5C 30 5A A0 03 02 01 05 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A3 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65 61 5C 30 5A A0 03 02 01 05 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A3 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65 encode_krb5_tgs_req(optionals NULL except server): 6C 69 30 67 A1 03 02 01 05 A2 03 02 01 0C A4 5B 30 59 A0 07 03 05 00 FE DC BA 90 A2 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A3 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A5 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A7 03 02 01 2A A8 08 30 06 02 01 00 02 01 01 encode_krb5_kdc_req_body: 30 82 01 A6 A0 07 03 05 00 FE DC BA 90 A1 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A2 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A3 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A4 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A5 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A6 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A7 03 02 01 2A A8 08 30 06 02 01 00 02 01 01 A9 20 30 1E 30 0D A0 03 02 01 02 A1 06 04 04 12 D0 00 23 30 0D A0 03 02 01 02 A1 06 04 04 12 D0 00 23 AA 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65 AB 81 BF 30 81 BC 61 5C 30 5A A0 03 02 01 05 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A3 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65 61 5C 30 5A A0 03 02 01 05 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A3 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65 encode_krb5_kdc_req_body(optionals NULL except second_ticket): 30 81 FF A0 07 03 05 00 FE DC BA 98 A2 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A5 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A7 03 02 01 2A A8 08 30 06 02 01 00 02 01 01 AB 81 BF 30 81 BC 61 5C 30 5A A0 03 02 01 05 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A3 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65 61 5C 30 5A A0 03 02 01 05 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A3 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65 encode_krb5_kdc_req_body(optionals NULL except server): 30 59 A0 07 03 05 00 FE DC BA 90 A2 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A3 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A5 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A7 03 02 01 2A A8 08 30 06 02 01 00 02 01 01 encode_krb5_safe: 74 6E 30 6C A0 03 02 01 05 A1 03 02 01 14 A2 4F 30 4D A0 0A 04 08 6B 72 62 35 64 61 74 61 A1 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A2 05 02 03 01 E2 40 A3 03 02 01 11 A4 0F 30 0D A0 03 02 01 02 A1 06 04 04 12 D0 00 23 A5 0F 30 0D A0 03 02 01 02 A1 06 04 04 12 D0 00 23 A3 0F 30 0D A0 03 02 01 01 A1 06 04 04 31 32 33 34 encode_krb5_safe(optionals NULL): 74 3E 30 3C A0 03 02 01 05 A1 03 02 01 14 A2 1F 30 1D A0 0A 04 08 6B 72 62 35 64 61 74 61 A4 0F 30 0D A0 03 02 01 02 A1 06 04 04 12 D0 00 23 A3 0F 30 0D A0 03 02 01 01 A1 06 04 04 31 32 33 34 encode_krb5_priv: 75 33 30 31 A0 03 02 01 05 A1 03 02 01 15 A3 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65 encode_krb5_enc_priv_part: 7C 4F 30 4D A0 0A 04 08 6B 72 62 35 64 61 74 61 A1 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A2 05 02 03 01 E2 40 A3 03 02 01 11 A4 0F 30 0D A0 03 02 01 02 A1 06 04 04 12 D0 00 23 A5 0F 30 0D A0 03 02 01 02 A1 06 04 04 12 D0 00 23 encode_krb5_enc_priv_part(optionals NULL): 7C 1F 30 1D A0 0A 04 08 6B 72 62 35 64 61 74 61 A4 0F 30 0D A0 03 02 01 02 A1 06 04 04 12 D0 00 23 encode_krb5_cred: 76 81 F6 30 81 F3 A0 03 02 01 05 A1 03 02 01 16 A2 81 BF 30 81 BC 61 5C 30 5A A0 03 02 01 05 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A3 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65 61 5C 30 5A A0 03 02 01 05 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A3 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65 A3 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65 encode_krb5_enc_cred_part: 7D 82 02 23 30 82 02 1F A0 82 01 DA 30 82 01 D6 30 81 E8 A0 13 30 11 A0 03 02 01 01 A1 0A 04 08 31 32 33 34 35 36 37 38 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A3 07 03 05 00 FE DC BA 98 A4 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A5 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A6 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A7 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A8 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A9 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 AA 20 30 1E 30 0D A0 03 02 01 02 A1 06 04 04 12 D0 00 23 30 0D A0 03 02 01 02 A1 06 04 04 12 D0 00 23 30 81 E8 A0 13 30 11 A0 03 02 01 01 A1 0A 04 08 31 32 33 34 35 36 37 38 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A3 07 03 05 00 FE DC BA 98 A4 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A5 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A6 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A7 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A8 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A9 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 AA 20 30 1E 30 0D A0 03 02 01 02 A1 06 04 04 12 D0 00 23 30 0D A0 03 02 01 02 A1 06 04 04 12 D0 00 23 A1 03 02 01 2A A2 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A3 05 02 03 01 E2 40 A4 0F 30 0D A0 03 02 01 02 A1 06 04 04 12 D0 00 23 A5 0F 30 0D A0 03 02 01 02 A1 06 04 04 12 D0 00 23 encode_krb5_enc_cred_part(optionals NULL): 7D 82 01 0E 30 82 01 0A A0 82 01 06 30 82 01 02 30 15 A0 13 30 11 A0 03 02 01 01 A1 0A 04 08 31 32 33 34 35 36 37 38 30 81 E8 A0 13 30 11 A0 03 02 01 01 A1 0A 04 08 31 32 33 34 35 36 37 38 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A3 07 03 05 00 FE DC BA 98 A4 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A5 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A6 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A7 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A8 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A9 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 AA 20 30 1E 30 0D A0 03 02 01 02 A1 06 04 04 12 D0 00 23 30 0D A0 03 02 01 02 A1 06 04 04 12 D0 00 23 encode_krb5_error: 7E 81 BA 30 81 B7 A0 03 02 01 05 A1 03 02 01 1E A2 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A3 05 02 03 01 E2 40 A4 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A5 05 02 03 01 E2 40 A6 03 02 01 3C A7 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A8 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A9 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 AA 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 AB 0A 1B 08 6B 72 62 35 64 61 74 61 AC 0A 04 08 6B 72 62 35 64 61 74 61 encode_krb5_error(optionals NULL): 7E 60 30 5E A0 03 02 01 05 A1 03 02 01 1E A3 05 02 03 01 E2 40 A4 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A5 05 02 03 01 E2 40 A6 03 02 01 3C A9 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 AA 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 encode_krb5_authorization_data: 30 22 30 0F A0 03 02 01 01 A1 08 04 06 66 6F 6F 62 61 72 30 0F A0 03 02 01 01 A1 08 04 06 66 6F 6F 62 61 72 encode_krb5_padata_sequence: 30 24 30 10 A1 03 02 01 0D A2 09 04 07 70 61 2D 64 61 74 61 30 10 A1 03 02 01 0D A2 09 04 07 70 61 2D 64 61 74 61 encode_krb5_typed_data: 30 24 30 10 A0 03 02 01 0D A1 09 04 07 70 61 2D 64 61 74 61 30 10 A0 03 02 01 0D A1 09 04 07 70 61 2D 64 61 74 61 encode_krb5_padata_sequence(empty): 30 00 encode_krb5_etype_info: 30 33 30 14 A0 03 02 01 00 A1 0D 04 0B 4D 6F 72 74 6F 6E 27 73 20 23 30 30 05 A0 03 02 01 01 30 14 A0 03 02 01 02 A1 0D 04 0B 4D 6F 72 74 6F 6E 27 73 20 23 32 encode_krb5_etype_info(only 1): 30 16 30 14 A0 03 02 01 00 A1 0D 04 0B 4D 6F 72 74 6F 6E 27 73 20 23 30 encode_krb5_etype_info(no info): 30 00 encode_krb5_etype_info2: 30 51 30 1E A0 03 02 01 00 A1 0D 1B 0B 4D 6F 72 74 6F 6E 27 73 20 23 30 A2 08 04 06 73 32 6B 3A 20 30 30 0F A0 03 02 01 01 A2 08 04 06 73 32 6B 3A 20 31 30 1E A0 03 02 01 02 A1 0D 1B 0B 4D 6F 72 74 6F 6E 27 73 20 23 32 A2 08 04 06 73 32 6B 3A 20 32 encode_krb5_etype_info2(only 1): 30 20 30 1E A0 03 02 01 00 A1 0D 1B 0B 4D 6F 72 74 6F 6E 27 73 20 23 30 A2 08 04 06 73 32 6B 3A 20 30 encode_krb5_pa_enc_ts: 30 1A A0 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A1 05 02 03 01 E2 40 encode_krb5_pa_enc_ts (no usec): 30 13 A0 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A encode_krb5_enc_data: 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65 encode_krb5_enc_data(MSB-set kvno): 30 26 A0 03 02 01 00 A1 06 02 04 FF 00 00 00 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65 encode_krb5_enc_data(kvno=-1): 30 23 A0 03 02 01 00 A1 03 02 01 FF A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65 encode_krb5_sam_challenge_2: 30 22 A0 0D 30 0B 04 09 63 68 61 6C 6C 65 6E 67 65 A1 11 30 0F 30 0D A0 03 02 01 01 A1 06 04 04 31 32 33 34 encode_krb5_sam_challenge_2_body: 30 64 A0 03 02 01 2A A1 07 03 05 00 80 00 00 00 A2 0B 04 09 74 79 70 65 20 6E 61 6D 65 A4 11 04 0F 63 68 61 6C 6C 65 6E 67 65 20 6C 61 62 65 6C A5 10 04 0E 63 68 61 6C 6C 65 6E 67 65 20 69 70 73 65 A6 16 04 14 72 65 73 70 6F 6E 73 65 5F 70 72 6F 6D 70 74 20 69 70 73 65 A8 05 02 03 54 32 10 A9 03 02 01 01 encode_krb5_sam_response_2: 30 42 A0 03 02 01 2B A1 07 03 05 00 80 00 00 00 A2 0C 04 0A 74 72 61 63 6B 20 64 61 74 61 A3 1D 30 1B A0 03 02 01 01 A1 04 02 02 0D 36 A2 0E 04 0C 6E 6F 6E 63 65 20 6F 72 20 73 61 64 A4 05 02 03 54 32 10 encode_krb5_enc_sam_response_enc_2: 30 1F A0 03 02 01 58 A1 18 04 16 65 6E 63 5F 73 61 6D 5F 72 65 73 70 6F 6E 73 65 5F 65 6E 63 5F 32 encode_krb5_pa_for_user: 30 4B A0 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 0F 30 0D A0 03 02 01 01 A1 06 04 04 31 32 33 34 A3 0A 1B 08 6B 72 62 35 64 61 74 61 encode_krb5_pa_s4u_x509_user: 30 68 A0 55 30 53 A0 06 02 04 00 CA 14 9A A1 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A2 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A3 12 04 10 70 61 5F 73 34 75 5F 78 35 30 39 5F 75 73 65 72 A4 07 03 05 00 80 00 00 00 A1 0F 30 0D A0 03 02 01 01 A1 06 04 04 31 32 33 34 encode_krb5_ad_kdcissued: 30 65 A0 0F 30 0D A0 03 02 01 01 A1 06 04 04 31 32 33 34 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A3 24 30 22 30 0F A0 03 02 01 01 A1 08 04 06 66 6F 6F 62 61 72 30 0F A0 03 02 01 01 A1 08 04 06 66 6F 6F 62 61 72 encode_krb5_ad_signedpath_data: 30 81 C7 A0 30 30 2E A0 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A1 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A2 32 30 30 30 2E A0 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A3 26 30 24 30 10 A1 03 02 01 0D A2 09 04 07 70 61 2D 64 61 74 61 30 10 A1 03 02 01 0D A2 09 04 07 70 61 2D 64 61 74 61 A4 24 30 22 30 0F A0 03 02 01 01 A1 08 04 06 66 6F 6F 62 61 72 30 0F A0 03 02 01 01 A1 08 04 06 66 6F 6F 62 61 72 encode_krb5_ad_signedpath: 30 3E A0 03 02 01 01 A1 0F 30 0D A0 03 02 01 01 A1 06 04 04 31 32 33 34 A3 26 30 24 30 10 A1 03 02 01 0D A2 09 04 07 70 61 2D 64 61 74 61 30 10 A1 03 02 01 0D A2 09 04 07 70 61 2D 64 61 74 61 encode_krb5_iakerb_header: 30 18 A1 0A 04 08 6B 72 62 35 64 61 74 61 A2 0A 04 08 6B 72 62 35 64 61 74 61 encode_krb5_iakerb_finished: 30 11 A1 0F 30 0D A0 03 02 01 01 A1 06 04 04 31 32 33 34 encode_krb5_fast_response: 30 81 9F A0 26 30 24 30 10 A1 03 02 01 0D A2 09 04 07 70 61 2D 64 61 74 61 30 10 A1 03 02 01 0D A2 09 04 07 70 61 2D 64 61 74 61 A1 13 30 11 A0 03 02 01 01 A1 0A 04 08 31 32 33 34 35 36 37 38 A2 5B 30 59 A0 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A1 05 02 03 01 E2 40 A2 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A3 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A4 0F 30 0D A0 03 02 01 01 A1 06 04 04 31 32 33 34 A3 03 02 01 2A encode_krb5_pa_fx_fast_reply: A0 29 30 27 A0 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65 encode_krb5_otp_tokeninfo(optionals NULL): 30 07 80 05 00 00 00 00 00 encode_krb5_otp_tokeninfo: 30 72 80 05 00 77 00 00 00 81 0B 45 78 61 6D 70 6C 65 63 6F 72 70 82 05 68 61 72 6B 21 83 01 0A 84 01 02 85 09 79 6F 75 72 74 6F 6B 65 6E 86 28 75 72 6E 3A 69 65 74 66 3A 70 61 72 61 6D 73 3A 78 6D 6C 3A 6E 73 3A 6B 65 79 70 72 6F 76 3A 70 73 6B 63 3A 68 6F 74 70 A7 16 30 0B 06 09 60 86 48 01 65 03 04 02 01 30 07 06 05 2B 0E 03 02 1A 88 02 03 E8 encode_krb5_pa_otp_challenge(optionals NULL): 30 15 80 08 6D 69 6E 6E 6F 6E 63 65 A2 09 30 07 80 05 00 00 00 00 00 encode_krb5_pa_otp_challenge: 30 81 A5 80 08 6D 61 78 6E 6F 6E 63 65 81 0B 74 65 73 74 73 65 72 76 69 63 65 A2 7D 30 07 80 05 00 00 00 00 00 30 72 80 05 00 77 00 00 00 81 0B 45 78 61 6D 70 6C 65 63 6F 72 70 82 05 68 61 72 6B 21 83 01 0A 84 01 02 85 09 79 6F 75 72 74 6F 6B 65 6E 86 28 75 72 6E 3A 69 65 74 66 3A 70 61 72 61 6D 73 3A 78 6D 6C 3A 6E 73 3A 6B 65 79 70 72 6F 76 3A 70 73 6B 63 3A 68 6F 74 70 A7 16 30 0B 06 09 60 86 48 01 65 03 04 02 01 30 07 06 05 2B 0E 03 02 1A 88 02 03 E8 83 07 6B 65 79 73 61 6C 74 84 04 31 32 33 34 encode_krb5_pa_otp_req(optionals NULL): 30 2C 80 05 00 00 00 00 00 A2 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65 encode_krb5_pa_otp_req: 30 81 B9 80 05 00 60 00 00 00 81 05 6E 6F 6E 63 65 A2 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65 A3 0B 06 09 60 86 48 01 65 03 04 02 01 84 02 03 E8 85 05 66 72 6F 67 73 86 0A 6D 79 66 69 72 73 74 70 69 6E 87 05 68 61 72 6B 21 88 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A 89 03 33 34 36 8A 01 02 8B 09 79 6F 75 72 74 6F 6B 65 6E 8C 28 75 72 6E 3A 69 65 74 66 3A 70 61 72 61 6D 73 3A 78 6D 6C 3A 6E 73 3A 6B 65 79 70 72 6F 76 3A 70 73 6B 63 3A 68 6F 74 70 8D 0B 45 78 61 6D 70 6C 65 63 6F 72 70 encode_krb5_pa_otp_enc_req: 30 0A 80 08 6B 72 62 35 64 61 74 61 encode_krb5_kkdcp_message: 30 82 01 FC A0 82 01 EC 04 82 01 E8 6A 82 01 E4 30 82 01 E0 A1 03 02 01 05 A2 03 02 01 0A A3 26 30 24 30 10 A1 03 02 01 0D A2 09 04 07 70 61 2D 64 61 74 61 30 10 A1 03 02 01 0D A2 09 04 07 70 61 2D 64 61 74 61 A4 82 01 AA 30 82 01 A6 A0 07 03 05 00 FE DC BA 98 A1 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A2 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A3 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A4 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A5 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A6 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A7 03 02 01 2A A8 08 30 06 02 01 00 02 01 01 A9 20 30 1E 30 0D A0 03 02 01 02 A1 06 04 04 12 D0 00 23 30 0D A0 03 02 01 02 A1 06 04 04 12 D0 00 23 AA 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65 AB 81 BF 30 81 BC 61 5C 30 5A A0 03 02 01 05 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A3 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65 61 5C 30 5A A0 03 02 01 05 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A3 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65 A1 0A 1B 08 6B 72 62 35 64 61 74 61 encode_krb5_cammac(optionals NULL): 30 12 A0 10 30 0E 30 0C A0 03 02 01 01 A1 05 04 03 61 64 31 encode_krb5_cammac: 30 81 F2 A0 1E 30 1C 30 0C A0 03 02 01 01 A1 05 04 03 61 64 31 30 0C A0 03 02 01 02 A1 05 04 03 61 64 32 A1 3D 30 3B A0 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A1 03 02 01 05 A2 03 02 01 10 A3 13 30 11 A0 03 02 01 01 A1 0A 04 08 63 6B 73 75 6D 6B 64 63 A2 3D 30 3B A0 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A1 03 02 01 05 A2 03 02 01 10 A3 13 30 11 A0 03 02 01 01 A1 0A 04 08 63 6B 73 75 6D 73 76 63 A3 52 30 50 30 13 A3 11 30 0F A0 03 02 01 01 A1 08 04 06 63 6B 73 75 6D 31 30 39 A0 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A1 03 02 01 05 A2 03 02 01 10 A3 11 30 0F A0 03 02 01 01 A1 08 04 06 63 6B 73 75 6D 32 encode_krb5_secure_cookie: 30 2C 02 04 2D F8 02 25 30 24 30 10 A1 03 02 01 0D A2 09 04 07 70 61 2D 64 61 74 61 30 10 A1 03 02 01 0D A2 09 04 07 70 61 2D 64 61 74 61 krb5-1.16/src/tests/asn.1/pkinit_encode.out0000644000704600001450000000471413211554426020421 0ustar ghudsonlibuuidencode_krb5_pa_pk_as_req: 30 38 80 08 6B 72 62 35 64 61 74 61 A1 22 30 20 30 1E 80 08 6B 72 62 35 64 61 74 61 81 08 6B 72 62 35 64 61 74 61 82 08 6B 72 62 35 64 61 74 61 82 08 6B 72 62 35 64 61 74 61 encode_krb5_pa_pk_as_req_draft9: 30 14 80 08 6B 72 62 35 64 61 74 61 82 08 6B 72 62 35 64 61 74 61 encode_krb5_pa_pk_as_rep(dhInfo): A0 28 30 26 80 08 6B 72 62 35 64 61 74 61 A1 0A 04 08 6B 72 62 35 64 61 74 61 A2 0E 30 0C A0 0A 06 08 6B 72 62 35 64 61 74 61 encode_krb5_pa_pk_as_rep(encKeyPack): 81 08 6B 72 62 35 64 61 74 61 encode_krb5_pa_pk_as_rep_draft9(dhSignedData): 80 08 6B 72 62 35 64 61 74 61 encode_krb5_pa_pk_as_rep_draft9(encKeyPack): 81 08 6B 72 62 35 64 61 74 61 encode_krb5_auth_pack: 30 81 93 A0 29 30 27 A0 05 02 03 01 E2 40 A1 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A2 03 02 01 2A A3 06 04 04 31 32 33 34 A1 22 30 20 30 13 06 09 2A 86 48 86 F7 12 01 02 02 04 06 70 61 72 61 6D 73 03 09 00 6B 72 62 35 64 61 74 61 A2 24 30 22 30 13 06 09 2A 86 48 86 F7 12 01 02 02 04 06 70 61 72 61 6D 73 30 0B 06 09 2A 86 48 86 F7 12 01 02 02 A3 0A 04 08 6B 72 62 35 64 61 74 61 A4 10 30 0E 30 0C A0 0A 06 08 6B 72 62 35 64 61 74 61 encode_krb5_auth_pack_draft9: 30 75 A0 4F 30 4D A0 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 05 02 03 01 E2 40 A3 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A4 03 02 01 2A A1 22 30 20 30 13 06 09 2A 86 48 86 F7 12 01 02 02 04 06 70 61 72 61 6D 73 03 09 00 6B 72 62 35 64 61 74 61 encode_krb5_kdc_dh_key_info: 30 25 A0 0B 03 09 00 6B 72 62 35 64 61 74 61 A1 03 02 01 2A A2 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A encode_krb5_reply_key_pack: 30 26 A0 13 30 11 A0 03 02 01 01 A1 0A 04 08 31 32 33 34 35 36 37 38 A1 0F 30 0D A0 03 02 01 01 A1 06 04 04 31 32 33 34 encode_krb5_reply_key_pack_draft9: 30 1A A0 13 30 11 A0 03 02 01 01 A1 0A 04 08 31 32 33 34 35 36 37 38 A1 03 02 01 2A encode_krb5_sp80056a_other_info: 30 81 81 30 0B 06 09 2A 86 48 86 F7 12 01 02 02 A0 32 04 30 30 2E A0 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A1 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A1 32 04 30 30 2E A0 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A1 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A2 0A 04 08 6B 72 62 35 64 61 74 61 encode_krb5_pkinit_supp_pub_info: 30 1D A0 03 02 01 01 A1 0A 04 08 6B 72 62 35 64 61 74 61 A2 0A 04 08 6B 72 62 35 64 61 74 61 krb5-1.16/src/tests/asn.1/ktest.c0000644000704600001450000013420513211554426016352 0ustar ghudsonlibuuid/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* tests/asn.1/ktest.c */ /* * Copyright (C) 1994 by the Massachusetts Institute of Technology. * All rights reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #include "ktest.h" #include "utility.h" #include char *sample_principal_name = "hftsai/extra@ATHENA.MIT.EDU"; void ktest_make_sample_authenticator(krb5_authenticator *a) { ktest_make_sample_principal(&a->client); a->checksum = ealloc(sizeof(krb5_checksum)); ktest_make_sample_checksum(a->checksum); a->cusec = SAMPLE_USEC; a->ctime = SAMPLE_TIME; a->subkey = ealloc(sizeof(krb5_keyblock)); ktest_make_sample_keyblock(a->subkey); a->seq_number = SAMPLE_SEQ_NUMBER; ktest_make_sample_authorization_data(&a->authorization_data); } void ktest_make_sample_principal(krb5_principal *p) { if (krb5_parse_name(test_context, sample_principal_name, p)) abort(); } void ktest_make_sample_checksum(krb5_checksum *cs) { cs->checksum_type = 1; cs->length = 4; cs->contents = ealloc(4); memcpy(cs->contents,"1234",4); } void ktest_make_sample_keyblock(krb5_keyblock *kb) { kb->magic = KV5M_KEYBLOCK; kb->enctype = 1; kb->length = 8; kb->contents = ealloc(8); memcpy(kb->contents,"12345678",8); } void ktest_make_sample_ticket(krb5_ticket *tkt) { ktest_make_sample_principal(&tkt->server); ktest_make_sample_enc_data(&tkt->enc_part); tkt->enc_part2 = NULL; } void ktest_make_sample_enc_data(krb5_enc_data *ed) { ed->kvno = 5; ed->enctype = 0; krb5_data_parse(&ed->ciphertext, "krbASN.1 test message"); } void ktest_make_sample_enc_tkt_part(krb5_enc_tkt_part *etp) { etp->flags = SAMPLE_FLAGS; etp->session = ealloc(sizeof(krb5_keyblock)); ktest_make_sample_keyblock(etp->session); ktest_make_sample_principal(&etp->client); ktest_make_sample_transited(&etp->transited); ktest_make_sample_ticket_times(&etp->times); ktest_make_sample_addresses(&etp->caddrs); ktest_make_sample_authorization_data(&etp->authorization_data); } void ktest_make_sample_addresses(krb5_address ***caddrs) { int i; *caddrs = ealloc(3 * sizeof(krb5_address *)); for (i = 0; i < 2; i++) { (*caddrs)[i] = ealloc(sizeof(krb5_address)); ktest_make_sample_address((*caddrs)[i]); } (*caddrs)[2] = NULL; } void ktest_make_sample_authorization_data(krb5_authdata ***ad) { int i; *ad = ealloc(3 * sizeof(krb5_authdata *)); for (i = 0; i <= 1; i++) { (*ad)[i] = ealloc(sizeof(krb5_authdata)); ktest_make_sample_authdata((*ad)[i]); } (*ad)[2] = NULL; } void ktest_make_sample_transited(krb5_transited *t) { t->tr_type = 1; krb5_data_parse(&t->tr_contents, "EDU,MIT.,ATHENA.,WASHINGTON.EDU,CS."); } void ktest_make_sample_ticket_times(krb5_ticket_times *tt) { tt->authtime = SAMPLE_TIME; tt->starttime = SAMPLE_TIME; tt->endtime = SAMPLE_TIME; tt->renew_till = SAMPLE_TIME; } void ktest_make_sample_address(krb5_address *a) { a->addrtype = ADDRTYPE_INET; a->length = 4; a->contents = ealloc(4 * sizeof(krb5_octet)); a->contents[0] = 18; a->contents[1] = 208; a->contents[2] = 0; a->contents[3] = 35; } void ktest_make_sample_authdata(krb5_authdata *ad) { ad->ad_type = 1; ad->length = 6; ad->contents = ealloc(6 * sizeof(krb5_octet)); memcpy(ad->contents, "foobar", 6); } void ktest_make_sample_enc_kdc_rep_part(krb5_enc_kdc_rep_part *ekr) { ekr->session = ealloc(sizeof(krb5_keyblock)); ktest_make_sample_keyblock(ekr->session); ktest_make_sample_last_req(&ekr->last_req); ekr->nonce = SAMPLE_NONCE; ekr->key_exp = SAMPLE_TIME; ekr->flags = SAMPLE_FLAGS; ekr->times.authtime = SAMPLE_TIME; ekr->times.starttime = SAMPLE_TIME; ekr->times.endtime = SAMPLE_TIME; ekr->times.renew_till = SAMPLE_TIME; ktest_make_sample_principal(&ekr->server); ktest_make_sample_addresses(&ekr->caddrs); } void ktest_make_sample_last_req(krb5_last_req_entry ***lr) { int i; *lr = ealloc(3 * sizeof(krb5_last_req_entry *)); for (i = 0; i <= 1; i++) ktest_make_sample_last_req_entry(&(*lr)[i]); (*lr)[2] = NULL; } void ktest_make_sample_last_req_entry(krb5_last_req_entry **lre) { *lre = ealloc(sizeof(krb5_last_req_entry)); (*lre)->lr_type = -5; (*lre)->value = SAMPLE_TIME; } void ktest_make_sample_kdc_rep(krb5_kdc_rep *kdcr) { ktest_make_sample_pa_data_array(&kdcr->padata); ktest_make_sample_principal(&kdcr->client); kdcr->ticket = ealloc(sizeof(krb5_ticket)); ktest_make_sample_ticket(kdcr->ticket); ktest_make_sample_enc_data(&kdcr->enc_part); kdcr->enc_part2 = NULL; } void ktest_make_sample_pa_data_array(krb5_pa_data ***pad) { int i; *pad = ealloc(3 * sizeof(krb5_pa_data *)); for (i = 0; i <= 1; i++) { (*pad)[i] = ealloc(sizeof(krb5_pa_data)); ktest_make_sample_pa_data((*pad)[i]); } (*pad)[2] = NULL; } void ktest_make_sample_empty_pa_data_array(krb5_pa_data ***pad) { *pad = ealloc(sizeof(krb5_pa_data *)); (*pad)[0] = NULL; } void ktest_make_sample_pa_data(krb5_pa_data *pad) { pad->pa_type = 13; pad->length = 7; pad->contents = ealloc(7); memcpy(pad->contents, "pa-data", 7); } void ktest_make_sample_ap_req(krb5_ap_req *ar) { ar->ap_options = SAMPLE_FLAGS; ar->ticket = ealloc(sizeof(krb5_ticket)); ktest_make_sample_ticket(ar->ticket); ktest_make_sample_enc_data(&(ar->authenticator)); } void ktest_make_sample_ap_rep(krb5_ap_rep *ar) { ktest_make_sample_enc_data(&ar->enc_part); } void ktest_make_sample_ap_rep_enc_part(krb5_ap_rep_enc_part *arep) { arep->ctime = SAMPLE_TIME; arep->cusec = SAMPLE_USEC; arep->subkey = ealloc(sizeof(krb5_keyblock)); ktest_make_sample_keyblock(arep->subkey); arep->seq_number = SAMPLE_SEQ_NUMBER; } void ktest_make_sample_kdc_req(krb5_kdc_req *kr) { /* msg_type is left up to the calling procedure */ ktest_make_sample_pa_data_array(&kr->padata); kr->kdc_options = SAMPLE_FLAGS; ktest_make_sample_principal(&(kr->client)); ktest_make_sample_principal(&(kr->server)); kr->from = SAMPLE_TIME; kr->till = SAMPLE_TIME; kr->rtime = SAMPLE_TIME; kr->nonce = SAMPLE_NONCE; kr->nktypes = 2; kr->ktype = ealloc(2 * sizeof(krb5_enctype)); kr->ktype[0] = 0; kr->ktype[1] = 1; ktest_make_sample_addresses(&kr->addresses); ktest_make_sample_enc_data(&kr->authorization_data); ktest_make_sample_authorization_data(&kr->unenc_authdata); ktest_make_sample_sequence_of_ticket(&kr->second_ticket); } void ktest_make_sample_kdc_req_body(krb5_kdc_req *krb) { krb->kdc_options = SAMPLE_FLAGS; ktest_make_sample_principal(&krb->client); ktest_make_sample_principal(&krb->server); krb->from = SAMPLE_TIME; krb->till = SAMPLE_TIME; krb->rtime = SAMPLE_TIME; krb->nonce = SAMPLE_NONCE; krb->nktypes = 2; krb->ktype = (krb5_enctype*)calloc(2,sizeof(krb5_enctype)); krb->ktype[0] = 0; krb->ktype[1] = 1; ktest_make_sample_addresses(&krb->addresses); ktest_make_sample_enc_data(&krb->authorization_data); ktest_make_sample_authorization_data(&krb->unenc_authdata); ktest_make_sample_sequence_of_ticket(&krb->second_ticket); } void ktest_make_sample_safe(krb5_safe *s) { ktest_make_sample_data(&s->user_data); s->timestamp = SAMPLE_TIME; s->usec = SAMPLE_USEC; s->seq_number = SAMPLE_SEQ_NUMBER; s->s_address = ealloc(sizeof(krb5_address)); ktest_make_sample_address(s->s_address); s->r_address = ealloc(sizeof(krb5_address)); ktest_make_sample_address(s->r_address); s->checksum = ealloc(sizeof(krb5_checksum)); ktest_make_sample_checksum(s->checksum); } void ktest_make_sample_priv(krb5_priv *p) { ktest_make_sample_enc_data(&p->enc_part); } void ktest_make_sample_priv_enc_part(krb5_priv_enc_part *pep) { ktest_make_sample_data(&(pep->user_data)); pep->timestamp = SAMPLE_TIME; pep->usec = SAMPLE_USEC; pep->seq_number = SAMPLE_SEQ_NUMBER; pep->s_address = ealloc(sizeof(krb5_address)); ktest_make_sample_address(pep->s_address); pep->r_address = ealloc(sizeof(krb5_address)); ktest_make_sample_address(pep->r_address); } void ktest_make_sample_cred(krb5_cred *c) { ktest_make_sample_sequence_of_ticket(&c->tickets); ktest_make_sample_enc_data(&c->enc_part); } void ktest_make_sample_sequence_of_ticket(krb5_ticket ***sot) { int i; *sot = ealloc(3 * sizeof(krb5_ticket *)); for (i = 0; i < 2; i++) { (*sot)[i] = ealloc(sizeof(krb5_ticket)); ktest_make_sample_ticket((*sot)[i]); } (*sot)[2] = NULL; } void ktest_make_sample_cred_enc_part(krb5_cred_enc_part *cep) { cep->nonce = SAMPLE_NONCE; cep->timestamp = SAMPLE_TIME; cep->usec = SAMPLE_USEC; cep->s_address = ealloc(sizeof(krb5_address)); ktest_make_sample_address(cep->s_address); cep->r_address = ealloc(sizeof(krb5_address)); ktest_make_sample_address(cep->r_address); ktest_make_sequence_of_cred_info(&cep->ticket_info); } void ktest_make_sequence_of_cred_info(krb5_cred_info ***soci) { int i; *soci = ealloc(3 * sizeof(krb5_cred_info *)); for (i = 0; i < 2; i++) { (*soci)[i] = ealloc(sizeof(krb5_cred_info)); ktest_make_sample_cred_info((*soci)[i]); } (*soci)[2] = NULL; } void ktest_make_sample_cred_info(krb5_cred_info *ci) { ci->session = ealloc(sizeof(krb5_keyblock)); ktest_make_sample_keyblock(ci->session); ktest_make_sample_principal(&ci->client); ktest_make_sample_principal(&ci->server); ci->flags = SAMPLE_FLAGS; ci->times.authtime = SAMPLE_TIME; ci->times.starttime = SAMPLE_TIME; ci->times.endtime = SAMPLE_TIME; ci->times.renew_till = SAMPLE_TIME; ktest_make_sample_addresses(&ci->caddrs); } void ktest_make_sample_error(krb5_error *kerr) { kerr->ctime = SAMPLE_TIME; kerr->cusec = SAMPLE_USEC; kerr->susec = SAMPLE_USEC; kerr->stime = SAMPLE_TIME; kerr->error = SAMPLE_ERROR; ktest_make_sample_principal(&kerr->client); ktest_make_sample_principal(&kerr->server); ktest_make_sample_data(&kerr->text); ktest_make_sample_data(&kerr->e_data); } void ktest_make_sample_data(krb5_data *d) { krb5_data_parse(d, "krb5data"); } void ktest_make_sample_etype_info(krb5_etype_info_entry ***p) { krb5_etype_info_entry **info; int i, len; char *str; info = ealloc(4 * sizeof(krb5_etype_info_entry *)); for (i = 0; i < 3; i++) { info[i] = ealloc(sizeof(krb5_etype_info_entry)); info[i]->etype = i; len = asprintf(&str, "Morton's #%d", i); if (len < 0) abort(); info[i]->salt = (krb5_octet *)str; info[i]->length = len; info[i]->s2kparams.data = NULL; info[i]->s2kparams.length = 0; info[i]->magic = KV5M_ETYPE_INFO_ENTRY; } free(info[1]->salt); info[1]->length = KRB5_ETYPE_NO_SALT; info[1]->salt = 0; *p = info; } void ktest_make_sample_etype_info2(krb5_etype_info_entry ***p) { krb5_etype_info_entry **info; int i, len; char *str; info = ealloc(4 * sizeof(krb5_etype_info_entry *)); for (i = 0; i < 3; i++) { info[i] = ealloc(sizeof(krb5_etype_info_entry)); info[i]->etype = i; len = asprintf(&str, "Morton's #%d", i); if (len < 0) abort(); info[i]->salt = (krb5_octet *)str; info[i]->length = (unsigned int)len; len = asprintf(&info[i]->s2kparams.data, "s2k: %d", i); if (len < 0) abort(); info[i]->s2kparams.length = (unsigned int) len; info[i]->magic = KV5M_ETYPE_INFO_ENTRY; } free(info[1]->salt); info[1]->length = KRB5_ETYPE_NO_SALT; info[1]->salt = 0; *p = info; } void ktest_make_sample_pa_enc_ts(krb5_pa_enc_ts *pa_enc) { pa_enc->patimestamp = SAMPLE_TIME; pa_enc->pausec = SAMPLE_USEC; } void ktest_make_sample_sam_challenge_2(krb5_sam_challenge_2 *p) { /* Need a valid DER sequence encoding here; this one contains the OCTET * STRING "challenge". */ krb5_data_parse(&p->sam_challenge_2_body, "\x30\x0B\x04\x09" "challenge"); p->sam_cksum = ealloc(2 * sizeof(krb5_checksum *)); p->sam_cksum[0] = ealloc(sizeof(krb5_checksum)); ktest_make_sample_checksum(p->sam_cksum[0]); p->sam_cksum[1] = NULL; } void ktest_make_sample_sam_challenge_2_body(krb5_sam_challenge_2_body *p) { p->sam_type = 42; p->sam_flags = KRB5_SAM_USE_SAD_AS_KEY; krb5_data_parse(&p->sam_type_name, "type name"); p->sam_track_id = empty_data(); krb5_data_parse(&p->sam_challenge_label, "challenge label"); krb5_data_parse(&p->sam_challenge, "challenge ipse"); krb5_data_parse(&p->sam_response_prompt, "response_prompt ipse"); p->sam_pk_for_sad = empty_data(); p->sam_nonce = 0x543210; p->sam_etype = ENCTYPE_DES_CBC_CRC; } void ktest_make_sample_sam_response_2(krb5_sam_response_2 *p) { p->magic = KV5M_SAM_RESPONSE; p->sam_type = 43; /* information */ p->sam_flags = KRB5_SAM_USE_SAD_AS_KEY; /* KRB5_SAM_* values */ krb5_data_parse(&p->sam_track_id, "track data"); krb5_data_parse(&p->sam_enc_nonce_or_sad.ciphertext, "nonce or sad"); p->sam_enc_nonce_or_sad.enctype = ENCTYPE_DES_CBC_CRC; p->sam_enc_nonce_or_sad.kvno = 3382; p->sam_nonce = 0x543210; } void ktest_make_sample_enc_sam_response_enc_2(krb5_enc_sam_response_enc_2 *p) { p->magic = 83; p->sam_nonce = 88; krb5_data_parse(&p->sam_sad, "enc_sam_response_enc_2"); } void ktest_make_sample_pa_for_user(krb5_pa_for_user *p) { ktest_make_sample_principal(&p->user); ktest_make_sample_checksum(&p->cksum); ktest_make_sample_data(&p->auth_package); } void ktest_make_sample_pa_s4u_x509_user(krb5_pa_s4u_x509_user *p) { krb5_s4u_userid *u = &p->user_id; u->nonce = 13243546; ktest_make_sample_principal(&u->user); krb5_data_parse(&u->subject_cert, "pa_s4u_x509_user"); u->options = 0x80000000; ktest_make_sample_checksum(&p->cksum); } void ktest_make_sample_ad_kdcissued(krb5_ad_kdcissued *p) { ktest_make_sample_checksum(&p->ad_checksum); ktest_make_sample_principal(&p->i_principal); ktest_make_sample_authorization_data(&p->elements); } void ktest_make_sample_ad_signedpath_data(krb5_ad_signedpath_data *p) { ktest_make_sample_principal(&p->client); p->authtime = SAMPLE_TIME; p->delegated = ealloc(2 * sizeof(krb5_principal)); ktest_make_sample_principal(&p->delegated[0]); p->delegated[1] = NULL; ktest_make_sample_authorization_data(&p->authorization_data); ktest_make_sample_pa_data_array(&p->method_data); } void ktest_make_sample_ad_signedpath(krb5_ad_signedpath *p) { p->enctype = 1; ktest_make_sample_checksum(&p->checksum); p->delegated = ealloc(2 * sizeof(krb5_principal)); p->delegated[1] = NULL; ktest_make_sample_pa_data_array(&p->method_data); } void ktest_make_sample_iakerb_header(krb5_iakerb_header *ih) { ktest_make_sample_data(&(ih->target_realm)); ih->cookie = ealloc(sizeof(krb5_data)); ktest_make_sample_data(ih->cookie); } void ktest_make_sample_iakerb_finished(krb5_iakerb_finished *ih) { ktest_make_sample_checksum(&ih->checksum); } static void ktest_make_sample_fast_finished(krb5_fast_finished *p) { p->timestamp = SAMPLE_TIME; p->usec = SAMPLE_USEC; ktest_make_sample_principal(&p->client); ktest_make_sample_checksum(&p->ticket_checksum); } void ktest_make_sample_fast_response(krb5_fast_response *p) { ktest_make_sample_pa_data_array(&p->padata); p->strengthen_key = ealloc(sizeof(krb5_keyblock)); ktest_make_sample_keyblock(p->strengthen_key); p->finished = ealloc(sizeof(krb5_fast_finished)); ktest_make_sample_fast_finished(p->finished); p->nonce = SAMPLE_NONCE; } void ktest_make_sha256_alg(krb5_algorithm_identifier *p) { /* { 2 16 840 1 101 3 4 2 1 } */ krb5_data_parse(&p->algorithm, "\x60\x86\x48\x01\x65\x03\x04\x02\x01"); p->parameters = empty_data(); } void ktest_make_sha1_alg(krb5_algorithm_identifier *p) { /* { 1 3 14 3 2 26 } */ krb5_data_parse(&p->algorithm, "\x2b\x0e\x03\x02\x1a"); p->parameters = empty_data(); } void ktest_make_minimal_otp_tokeninfo(krb5_otp_tokeninfo *p) { memset(p, 0, sizeof(*p)); p->length = p->format = p->iteration_count = -1; } void ktest_make_maximal_otp_tokeninfo(krb5_otp_tokeninfo *p) { p->flags = KRB5_OTP_FLAG_NEXTOTP | KRB5_OTP_FLAG_COMBINE | KRB5_OTP_FLAG_COLLECT_PIN | KRB5_OTP_FLAG_ENCRYPT_NONCE | KRB5_OTP_FLAG_SEPARATE_PIN | KRB5_OTP_FLAG_CHECK_DIGIT; krb5_data_parse(&p->vendor, "Examplecorp"); krb5_data_parse(&p->challenge, "hark!"); p->length = 10; p->format = 2; krb5_data_parse(&p->token_id, "yourtoken"); krb5_data_parse(&p->alg_id, "urn:ietf:params:xml:ns:keyprov:pskc:hotp"); p->supported_hash_alg = ealloc(3 * sizeof(*p->supported_hash_alg)); p->supported_hash_alg[0] = ealloc(sizeof(*p->supported_hash_alg[0])); ktest_make_sha256_alg(p->supported_hash_alg[0]); p->supported_hash_alg[1] = ealloc(sizeof(*p->supported_hash_alg[1])); ktest_make_sha1_alg(p->supported_hash_alg[1]); p->supported_hash_alg[2] = NULL; p->iteration_count = 1000; } void ktest_make_minimal_pa_otp_challenge(krb5_pa_otp_challenge *p) { memset(p, 0, sizeof(*p)); krb5_data_parse(&p->nonce, "minnonce"); p->tokeninfo = ealloc(2 * sizeof(*p->tokeninfo)); p->tokeninfo[0] = ealloc(sizeof(*p->tokeninfo[0])); ktest_make_minimal_otp_tokeninfo(p->tokeninfo[0]); p->tokeninfo[1] = NULL; } void ktest_make_maximal_pa_otp_challenge(krb5_pa_otp_challenge *p) { krb5_data_parse(&p->nonce, "maxnonce"); krb5_data_parse(&p->service, "testservice"); p->tokeninfo = ealloc(3 * sizeof(*p->tokeninfo)); p->tokeninfo[0] = ealloc(sizeof(*p->tokeninfo[0])); ktest_make_minimal_otp_tokeninfo(p->tokeninfo[0]); p->tokeninfo[1] = ealloc(sizeof(*p->tokeninfo[1])); ktest_make_maximal_otp_tokeninfo(p->tokeninfo[1]); p->tokeninfo[2] = NULL; krb5_data_parse(&p->salt, "keysalt"); krb5_data_parse(&p->s2kparams, "1234"); } void ktest_make_minimal_pa_otp_req(krb5_pa_otp_req *p) { memset(p, 0, sizeof(*p)); p->iteration_count = -1; p->format = -1; ktest_make_sample_enc_data(&p->enc_data); } void ktest_make_maximal_pa_otp_req(krb5_pa_otp_req *p) { p->flags = KRB5_OTP_FLAG_NEXTOTP | KRB5_OTP_FLAG_COMBINE; krb5_data_parse(&p->nonce, "nonce"); ktest_make_sample_enc_data(&p->enc_data); p->hash_alg = ealloc(sizeof(*p->hash_alg)); ktest_make_sha256_alg(p->hash_alg); p->iteration_count = 1000; krb5_data_parse(&p->otp_value, "frogs"); krb5_data_parse(&p->pin, "myfirstpin"); krb5_data_parse(&p->challenge, "hark!"); p->time = SAMPLE_TIME; krb5_data_parse(&p->counter, "346"); p->format = 2; krb5_data_parse(&p->token_id, "yourtoken"); krb5_data_parse(&p->alg_id, "urn:ietf:params:xml:ns:keyprov:pskc:hotp"); krb5_data_parse(&p->vendor, "Examplecorp"); } #ifndef DISABLE_PKINIT static void ktest_make_sample_pk_authenticator(krb5_pk_authenticator *p) { p->cusec = SAMPLE_USEC; p->ctime = SAMPLE_TIME; p->nonce = SAMPLE_NONCE; ktest_make_sample_checksum(&p->paChecksum); /* We don't encode the checksum type, only the contents. */ p->paChecksum.checksum_type = 0; } static void ktest_make_sample_pk_authenticator_draft9(krb5_pk_authenticator_draft9 *p) { ktest_make_sample_principal(&p->kdcName); p->cusec = SAMPLE_USEC; p->ctime = SAMPLE_TIME; p->nonce = SAMPLE_NONCE; } static void ktest_make_sample_oid(krb5_data *p) { krb5_data_parse(p, "\052\206\110\206\367\022\001\002\002"); } static void ktest_make_sample_algorithm_identifier(krb5_algorithm_identifier *p) { ktest_make_sample_oid(&p->algorithm); /* Need a valid DER encoding here; this is the OCTET STRING "params". */ krb5_data_parse(&p->parameters, "\x04\x06" "params"); } static void ktest_make_sample_algorithm_identifier_no_params(krb5_algorithm_identifier *p) { ktest_make_sample_oid(&p->algorithm); p->parameters = empty_data(); } static void ktest_make_sample_subject_pk_info(krb5_subject_pk_info *p) { ktest_make_sample_algorithm_identifier(&p->algorithm); ktest_make_sample_data(&p->subjectPublicKey); } static void ktest_make_sample_external_principal_identifier( krb5_external_principal_identifier *p) { ktest_make_sample_data(&p->subjectName); ktest_make_sample_data(&p->issuerAndSerialNumber); ktest_make_sample_data(&p->subjectKeyIdentifier); } void ktest_make_sample_pa_pk_as_req(krb5_pa_pk_as_req *p) { ktest_make_sample_data(&p->signedAuthPack); p->trustedCertifiers = ealloc(2 * sizeof(krb5_external_principal_identifier *)); p->trustedCertifiers[0] = ealloc(sizeof(krb5_external_principal_identifier)); ktest_make_sample_external_principal_identifier(p->trustedCertifiers[0]); p->trustedCertifiers[1] = NULL; ktest_make_sample_data(&p->kdcPkId); } void ktest_make_sample_pa_pk_as_req_draft9(krb5_pa_pk_as_req_draft9 *p) { ktest_make_sample_data(&p->signedAuthPack); ktest_make_sample_data(&p->kdcCert); } static void ktest_make_sample_dh_rep_info(krb5_dh_rep_info *p) { ktest_make_sample_data(&p->dhSignedData); ktest_make_sample_data(&p->serverDHNonce); p->kdfID = ealloc(sizeof(krb5_data)); ktest_make_sample_data(p->kdfID); } void ktest_make_sample_pa_pk_as_rep_dhInfo(krb5_pa_pk_as_rep *p) { p->choice = choice_pa_pk_as_rep_dhInfo; ktest_make_sample_dh_rep_info(&p->u.dh_Info); } void ktest_make_sample_pa_pk_as_rep_encKeyPack(krb5_pa_pk_as_rep *p) { p->choice = choice_pa_pk_as_rep_encKeyPack; ktest_make_sample_data(&p->u.encKeyPack); } void ktest_make_sample_pa_pk_as_rep_draft9_dhSignedData(krb5_pa_pk_as_rep_draft9 *p) { p->choice = choice_pa_pk_as_rep_draft9_dhSignedData; ktest_make_sample_data(&p->u.dhSignedData); } void ktest_make_sample_pa_pk_as_rep_draft9_encKeyPack(krb5_pa_pk_as_rep_draft9 *p) { p->choice = choice_pa_pk_as_rep_draft9_encKeyPack; ktest_make_sample_data(&p->u.encKeyPack); } void ktest_make_sample_auth_pack(krb5_auth_pack *p) { ktest_make_sample_pk_authenticator(&p->pkAuthenticator); p->clientPublicValue = ealloc(sizeof(krb5_subject_pk_info)); ktest_make_sample_subject_pk_info(p->clientPublicValue); p->supportedCMSTypes = ealloc(3 * sizeof(krb5_algorithm_identifier *)); p->supportedCMSTypes[0] = ealloc(sizeof(krb5_algorithm_identifier)); ktest_make_sample_algorithm_identifier(p->supportedCMSTypes[0]); p->supportedCMSTypes[1] = ealloc(sizeof(krb5_algorithm_identifier)); ktest_make_sample_algorithm_identifier_no_params(p->supportedCMSTypes[1]); p->supportedCMSTypes[2] = NULL; ktest_make_sample_data(&p->clientDHNonce); p->supportedKDFs = ealloc(2 * sizeof(krb5_data *)); p->supportedKDFs[0] = ealloc(sizeof(krb5_data)); ktest_make_sample_data(p->supportedKDFs[0]); p->supportedKDFs[1] = NULL; } void ktest_make_sample_auth_pack_draft9(krb5_auth_pack_draft9 *p) { ktest_make_sample_pk_authenticator_draft9(&p->pkAuthenticator); p->clientPublicValue = ealloc(sizeof(krb5_subject_pk_info)); ktest_make_sample_subject_pk_info(p->clientPublicValue); } void ktest_make_sample_kdc_dh_key_info(krb5_kdc_dh_key_info *p) { ktest_make_sample_data(&p->subjectPublicKey); p->nonce = SAMPLE_NONCE; p->dhKeyExpiration = SAMPLE_TIME; } void ktest_make_sample_reply_key_pack(krb5_reply_key_pack *p) { ktest_make_sample_keyblock(&p->replyKey); ktest_make_sample_checksum(&p->asChecksum); } void ktest_make_sample_reply_key_pack_draft9(krb5_reply_key_pack_draft9 *p) { ktest_make_sample_keyblock(&p->replyKey); p->nonce = SAMPLE_NONCE; } void ktest_make_sample_sp80056a_other_info(krb5_sp80056a_other_info *p) { ktest_make_sample_algorithm_identifier_no_params(&p->algorithm_identifier); ktest_make_sample_principal(&p->party_u_info); ktest_make_sample_principal(&p->party_v_info); ktest_make_sample_data(&p->supp_pub_info); } void ktest_make_sample_pkinit_supp_pub_info(krb5_pkinit_supp_pub_info *p) { p->enctype = ENCTYPE_DES_CBC_CRC; ktest_make_sample_data(&p->as_req); ktest_make_sample_data(&p->pk_as_rep); } #endif /* not DISABLE_PKINIT */ #ifdef ENABLE_LDAP static void ktest_make_sample_key_data(krb5_key_data *p, int i) { char *str; int len; len = asprintf(&str, "key%d", i); if (len < 0) abort(); p->key_data_ver = 2; p->key_data_type[0] = 2; p->key_data_length[0] = (unsigned int) len; p->key_data_contents[0] = (krb5_octet *)str; len = asprintf(&str, "salt%d", i); if (len < 0) abort(); p->key_data_type[1] = i; p->key_data_length[1] = (unsigned int) len; p->key_data_contents[1] = (krb5_octet *)str; } void ktest_make_sample_ldap_seqof_key_data(ldap_seqof_key_data *p) { int i; p->mkvno = 14; p->n_key_data = 3; p->key_data = calloc(3,sizeof(krb5_key_data)); p->kvno = 42; for (i = 0; i < 3; i++) ktest_make_sample_key_data(&p->key_data[i], i); } #endif void ktest_make_sample_kkdcp_message(krb5_kkdcp_message *p) { krb5_kdc_req req; krb5_data *message; ktest_make_sample_kdc_req(&req); req.msg_type = KRB5_AS_REQ; encode_krb5_as_req(&req, &message); p->kerb_message = *message; free(message); ktest_empty_kdc_req(&req); ktest_make_sample_data(&(p->target_domain)); p->dclocator_hint = 0; } static krb5_authdata * make_ad_element(krb5_authdatatype ad_type, const char *str) { krb5_authdata *ad; ad = ealloc(sizeof(*ad)); ad->ad_type = ad_type; ad->length = strlen(str); ad->contents = ealloc(ad->length); memcpy(ad->contents, str, ad->length); return ad; } static krb5_verifier_mac * make_vmac(krb5_boolean include_princ, krb5_kvno kvno, krb5_enctype enctype, const char *cksumstr) { krb5_verifier_mac *vmac; vmac = ealloc(sizeof(*vmac)); if (include_princ) { ktest_make_sample_principal(&vmac->princ); (void)krb5_set_principal_realm(NULL, vmac->princ, ""); } else { vmac->princ = NULL; } vmac->kvno = kvno; vmac->enctype = enctype; vmac->checksum.checksum_type = 1; vmac->checksum.length = strlen(cksumstr); vmac->checksum.contents = ealloc(vmac->checksum.length); memcpy(vmac->checksum.contents, cksumstr, vmac->checksum.length); return vmac; } void ktest_make_minimal_cammac(krb5_cammac *p) { memset(p, 0, sizeof(*p)); p->elements = ealloc(2 * sizeof(*p->elements)); p->elements[0] = make_ad_element(1, "ad1"); p->elements[1] = NULL; } void ktest_make_maximal_cammac(krb5_cammac *p) { p->elements = ealloc(3 * sizeof(*p->elements)); p->elements[0] = make_ad_element(1, "ad1"); p->elements[1] = make_ad_element(2, "ad2"); p->elements[2] = NULL; p->kdc_verifier = make_vmac(TRUE, 5, 16, "cksumkdc"); p->svc_verifier = make_vmac(TRUE, 5, 16, "cksumsvc"); p->other_verifiers = ealloc(3 * sizeof(*p->other_verifiers)); p->other_verifiers[0] = make_vmac(FALSE, 0, 0, "cksum1"); p->other_verifiers[1] = make_vmac(TRUE, 5, 16, "cksum2"); p->other_verifiers[2] = NULL; } void ktest_make_sample_secure_cookie(krb5_secure_cookie *p) { ktest_make_sample_pa_data_array(&p->data); p->time = SAMPLE_TIME; } /****************************************************************/ /* destructors */ void ktest_destroy_data(krb5_data **d) { if (*d != NULL) { free((*d)->data); free(*d); *d = NULL; } } void ktest_empty_data(krb5_data *d) { if (d->data != NULL) { free(d->data); d->data = NULL; d->length = 0; } } static void ktest_empty_checksum(krb5_checksum *cs) { free(cs->contents); cs->contents = NULL; } void ktest_destroy_checksum(krb5_checksum **cs) { if (*cs != NULL) { free((*cs)->contents); free(*cs); *cs = NULL; } } void ktest_empty_keyblock(krb5_keyblock *kb) { if (kb != NULL) { if (kb->contents) { free(kb->contents); kb->contents = NULL; } } } void ktest_destroy_keyblock(krb5_keyblock **kb) { if (*kb != NULL) { free((*kb)->contents); free(*kb); *kb = NULL; } } void ktest_empty_authorization_data(krb5_authdata **ad) { int i; if (*ad != NULL) { for (i=0; ad[i] != NULL; i++) ktest_destroy_authdata(&ad[i]); } } void ktest_destroy_authorization_data(krb5_authdata ***ad) { ktest_empty_authorization_data(*ad); free(*ad); *ad = NULL; } void ktest_destroy_authdata(krb5_authdata **ad) { if (*ad != NULL) { free((*ad)->contents); free(*ad); *ad = NULL; } } void ktest_empty_pa_data_array(krb5_pa_data **pad) { int i; for (i=0; pad[i] != NULL; i++) ktest_destroy_pa_data(&pad[i]); } void ktest_destroy_pa_data_array(krb5_pa_data ***pad) { ktest_empty_pa_data_array(*pad); free(*pad); *pad = NULL; } void ktest_destroy_pa_data(krb5_pa_data **pad) { if (*pad != NULL) { free((*pad)->contents); free(*pad); *pad = NULL; } } void ktest_destroy_address(krb5_address **a) { if (*a != NULL) { free((*a)->contents); free(*a); *a = NULL; } } void ktest_empty_addresses(krb5_address **a) { int i; for (i=0; a[i] != NULL; i++) ktest_destroy_address(&a[i]); } void ktest_destroy_addresses(krb5_address ***a) { ktest_empty_addresses(*a); free(*a); *a = NULL; } void ktest_destroy_principal(krb5_principal *p) { int i; if (*p == NULL) return; for (i=0; i<(*p)->length; i++) ktest_empty_data(&(*p)->data[i]); ktest_empty_data(&(*p)->realm); free((*p)->data); free(*p); *p = NULL; } void ktest_destroy_sequence_of_integer(long **soi) { free(*soi); *soi = NULL; } void ktest_destroy_sequence_of_ticket(krb5_ticket ***sot) { int i; for (i=0; (*sot)[i] != NULL; i++) ktest_destroy_ticket(&(*sot)[i]); free(*sot); *sot = NULL; } void ktest_destroy_ticket(krb5_ticket **tkt) { ktest_destroy_principal(&(*tkt)->server); ktest_destroy_enc_data(&(*tkt)->enc_part); /* ktest_empty_enc_tkt_part(((*tkt)->enc_part2));*/ free(*tkt); *tkt = NULL; } void ktest_empty_ticket(krb5_ticket *tkt) { if (tkt->server) ktest_destroy_principal(&tkt->server); ktest_destroy_enc_data(&tkt->enc_part); if (tkt->enc_part2) ktest_destroy_enc_tkt_part(&tkt->enc_part2); } void ktest_destroy_enc_data(krb5_enc_data *ed) { ktest_empty_data(&ed->ciphertext); ed->kvno = 0; } void ktest_destroy_etype_info_entry(krb5_etype_info_entry *i) { if (i->salt) free(i->salt); ktest_empty_data(&i->s2kparams); free(i); } void ktest_destroy_etype_info(krb5_etype_info_entry **info) { int i; for (i = 0; info[i] != NULL; i++) ktest_destroy_etype_info_entry(info[i]); free(info); } void ktest_empty_kdc_req(krb5_kdc_req *kr) { if (kr->padata) ktest_destroy_pa_data_array(&kr->padata); if (kr->client) ktest_destroy_principal(&kr->client); if (kr->server) ktest_destroy_principal(&kr->server); free(kr->ktype); if (kr->addresses) ktest_destroy_addresses(&kr->addresses); ktest_destroy_enc_data(&kr->authorization_data); if (kr->unenc_authdata) ktest_destroy_authorization_data(&kr->unenc_authdata); if (kr->second_ticket) ktest_destroy_sequence_of_ticket(&kr->second_ticket); } void ktest_empty_kdc_rep(krb5_kdc_rep *kr) { if (kr->padata) ktest_destroy_pa_data_array(&kr->padata); if (kr->client) ktest_destroy_principal(&kr->client); if (kr->ticket) ktest_destroy_ticket(&kr->ticket); ktest_destroy_enc_data(&kr->enc_part); if (kr->enc_part2) { ktest_empty_enc_kdc_rep_part(kr->enc_part2); free(kr->enc_part2); kr->enc_part2 = NULL; } } void ktest_empty_authenticator(krb5_authenticator *a) { if (a->client) ktest_destroy_principal(&a->client); if (a->checksum) ktest_destroy_checksum(&a->checksum); if (a->subkey) ktest_destroy_keyblock(&a->subkey); if (a->authorization_data) ktest_destroy_authorization_data(&a->authorization_data); } void ktest_empty_enc_tkt_part(krb5_enc_tkt_part *etp) { if (etp->session) ktest_destroy_keyblock(&etp->session); if (etp->client) ktest_destroy_principal(&etp->client); if (etp->caddrs) ktest_destroy_addresses(&etp->caddrs); if (etp->authorization_data) ktest_destroy_authorization_data(&etp->authorization_data); ktest_destroy_transited(&etp->transited); } void ktest_destroy_enc_tkt_part(krb5_enc_tkt_part **etp) { if (*etp) { ktest_empty_enc_tkt_part(*etp); free(*etp); *etp = NULL; } } void ktest_empty_enc_kdc_rep_part(krb5_enc_kdc_rep_part *ekr) { if (ekr->session) ktest_destroy_keyblock(&ekr->session); if (ekr->server) ktest_destroy_principal(&ekr->server); if (ekr->caddrs) ktest_destroy_addresses(&ekr->caddrs); ktest_destroy_last_req(&ekr->last_req); } void ktest_destroy_transited(krb5_transited *t) { if (t->tr_contents.data) ktest_empty_data(&t->tr_contents); } void ktest_empty_ap_rep(krb5_ap_rep *ar) { ktest_destroy_enc_data(&ar->enc_part); } void ktest_empty_ap_req(krb5_ap_req *ar) { if (ar->ticket) ktest_destroy_ticket(&ar->ticket); ktest_destroy_enc_data(&ar->authenticator); } void ktest_empty_cred_enc_part(krb5_cred_enc_part *cep) { if (cep->s_address) ktest_destroy_address(&cep->s_address); if (cep->r_address) ktest_destroy_address(&cep->r_address); if (cep->ticket_info) ktest_destroy_sequence_of_cred_info(&cep->ticket_info); } void ktest_destroy_cred_info(krb5_cred_info **ci) { if ((*ci)->session) ktest_destroy_keyblock(&(*ci)->session); if ((*ci)->client) ktest_destroy_principal(&(*ci)->client); if ((*ci)->server) ktest_destroy_principal(&(*ci)->server); if ((*ci)->caddrs) ktest_destroy_addresses(&(*ci)->caddrs); free(*ci); *ci = NULL; } void ktest_destroy_sequence_of_cred_info(krb5_cred_info ***soci) { int i; for (i = 0; (*soci)[i] != NULL; i++) ktest_destroy_cred_info(&(*soci)[i]); free(*soci); *soci = NULL; } void ktest_empty_safe(krb5_safe *s) { ktest_empty_data(&s->user_data); ktest_destroy_address(&s->s_address); ktest_destroy_address(&s->r_address); ktest_destroy_checksum(&s->checksum); } void ktest_empty_priv_enc_part(krb5_priv_enc_part *pep) { ktest_empty_data(&pep->user_data); ktest_destroy_address(&pep->s_address); ktest_destroy_address(&pep->r_address); } void ktest_empty_priv(krb5_priv *p) { ktest_destroy_enc_data(&p->enc_part); } void ktest_empty_cred(krb5_cred *c) { ktest_destroy_sequence_of_ticket(&c->tickets); ktest_destroy_enc_data(&c->enc_part); /* enc_part2 */ } void ktest_destroy_last_req(krb5_last_req_entry ***lr) { int i; if (*lr) { for (i=0; (*lr)[i] != NULL; i++) free((*lr)[i]); free(*lr); } } void ktest_empty_error(krb5_error *kerr) { if (kerr->client) ktest_destroy_principal(&kerr->client); if (kerr->server) ktest_destroy_principal(&kerr->server); ktest_empty_data(&kerr->text); ktest_empty_data(&kerr->e_data); } void ktest_empty_ap_rep_enc_part(krb5_ap_rep_enc_part *arep) { ktest_destroy_keyblock(&(arep)->subkey); } void ktest_empty_sam_challenge_2(krb5_sam_challenge_2 *p) { krb5_checksum **ck; ktest_empty_data(&p->sam_challenge_2_body); if (p->sam_cksum != NULL) { for (ck = p->sam_cksum; *ck != NULL; ck++) ktest_destroy_checksum(ck); free(p->sam_cksum); p->sam_cksum = NULL; } } void ktest_empty_sam_challenge_2_body(krb5_sam_challenge_2_body *p) { ktest_empty_data(&p->sam_type_name); ktest_empty_data(&p->sam_track_id); ktest_empty_data(&p->sam_challenge_label); ktest_empty_data(&p->sam_challenge); ktest_empty_data(&p->sam_response_prompt); ktest_empty_data(&p->sam_pk_for_sad); } void ktest_empty_sam_response_2(krb5_sam_response_2 *p) { ktest_empty_data(&p->sam_track_id); ktest_empty_data(&p->sam_enc_nonce_or_sad.ciphertext); } void ktest_empty_enc_sam_response_enc_2(krb5_enc_sam_response_enc_2 *p) { ktest_empty_data(&p->sam_sad); } void ktest_empty_pa_for_user(krb5_pa_for_user *p) { ktest_destroy_principal(&p->user); ktest_empty_checksum(&p->cksum); ktest_empty_data(&p->auth_package); } void ktest_empty_pa_s4u_x509_user(krb5_pa_s4u_x509_user *p) { ktest_destroy_principal(&p->user_id.user); ktest_empty_data(&p->user_id.subject_cert); free(p->cksum.contents); } void ktest_empty_ad_kdcissued(krb5_ad_kdcissued *p) { free(p->ad_checksum.contents); ktest_destroy_principal(&p->i_principal); ktest_destroy_authorization_data(&p->elements); } void ktest_empty_ad_signedpath_data(krb5_ad_signedpath_data *p) { int i; ktest_destroy_principal(&p->client); if (p->delegated != NULL) { for (i = 0; p->delegated[i] != NULL; i++) { krb5_principal princ = p->delegated[i]; ktest_destroy_principal(&princ); } free(p->delegated); } ktest_destroy_pa_data_array(&p->method_data); ktest_destroy_authorization_data(&p->authorization_data); } void ktest_empty_ad_signedpath(krb5_ad_signedpath *p) { int i; free(p->checksum.contents); if (p->delegated != NULL) { for (i = 0; p->delegated[i] != NULL; i++) { krb5_principal princ = p->delegated[i]; ktest_destroy_principal(&princ); } free(p->delegated); } ktest_destroy_pa_data_array(&p->method_data); } void ktest_empty_iakerb_header(krb5_iakerb_header *p) { krb5_free_data_contents(NULL, &p->target_realm); krb5_free_data(NULL, p->cookie); } void ktest_empty_iakerb_finished(krb5_iakerb_finished *p) { krb5_free_checksum_contents(NULL, &p->checksum); } static void ktest_empty_fast_finished(krb5_fast_finished *p) { ktest_destroy_principal(&p->client); ktest_empty_checksum(&p->ticket_checksum); } void ktest_empty_fast_response(krb5_fast_response *p) { ktest_destroy_pa_data_array(&p->padata); ktest_destroy_keyblock(&p->strengthen_key); if (p->finished != NULL) { ktest_empty_fast_finished(p->finished); free(p->finished); p->finished = NULL; } } static void ktest_empty_algorithm_identifier(krb5_algorithm_identifier *p) { ktest_empty_data(&p->algorithm); ktest_empty_data(&p->parameters); } void ktest_empty_otp_tokeninfo(krb5_otp_tokeninfo *p) { krb5_algorithm_identifier **alg; p->flags = 0; krb5_free_data_contents(NULL, &p->vendor); krb5_free_data_contents(NULL, &p->challenge); krb5_free_data_contents(NULL, &p->token_id); krb5_free_data_contents(NULL, &p->alg_id); for (alg = p->supported_hash_alg; alg != NULL && *alg != NULL; alg++) { ktest_empty_algorithm_identifier(*alg); free(*alg); } free(p->supported_hash_alg); p->supported_hash_alg = NULL; p->length = p->format = p->iteration_count = -1; } void ktest_empty_pa_otp_challenge(krb5_pa_otp_challenge *p) { krb5_otp_tokeninfo **ti; krb5_free_data_contents(NULL, &p->nonce); krb5_free_data_contents(NULL, &p->service); for (ti = p->tokeninfo; *ti != NULL; ti++) { ktest_empty_otp_tokeninfo(*ti); free(*ti); } free(p->tokeninfo); p->tokeninfo = NULL; krb5_free_data_contents(NULL, &p->salt); krb5_free_data_contents(NULL, &p->s2kparams); } void ktest_empty_pa_otp_req(krb5_pa_otp_req *p) { p->flags = 0; krb5_free_data_contents(NULL, &p->nonce); ktest_destroy_enc_data(&p->enc_data); if (p->hash_alg != NULL) ktest_empty_algorithm_identifier(p->hash_alg); free(p->hash_alg); p->hash_alg = NULL; p->iteration_count = -1; krb5_free_data_contents(NULL, &p->otp_value); krb5_free_data_contents(NULL, &p->pin); krb5_free_data_contents(NULL, &p->challenge); p->time = 0; krb5_free_data_contents(NULL, &p->counter); p->format = -1; krb5_free_data_contents(NULL, &p->token_id); krb5_free_data_contents(NULL, &p->alg_id); krb5_free_data_contents(NULL, &p->vendor); } #ifndef DISABLE_PKINIT static void ktest_empty_pk_authenticator(krb5_pk_authenticator *p) { ktest_empty_checksum(&p->paChecksum); p->paChecksum.contents = NULL; } static void ktest_empty_pk_authenticator_draft9(krb5_pk_authenticator_draft9 *p) { ktest_destroy_principal(&p->kdcName); } static void ktest_empty_subject_pk_info(krb5_subject_pk_info *p) { ktest_empty_algorithm_identifier(&p->algorithm); ktest_empty_data(&p->subjectPublicKey); } static void ktest_empty_external_principal_identifier( krb5_external_principal_identifier *p) { ktest_empty_data(&p->subjectName); ktest_empty_data(&p->issuerAndSerialNumber); ktest_empty_data(&p->subjectKeyIdentifier); } void ktest_empty_pa_pk_as_req(krb5_pa_pk_as_req *p) { krb5_external_principal_identifier **pi; ktest_empty_data(&p->signedAuthPack); for (pi = p->trustedCertifiers; *pi != NULL; pi++) { ktest_empty_external_principal_identifier(*pi); free(*pi); } free(p->trustedCertifiers); p->trustedCertifiers = NULL; ktest_empty_data(&p->kdcPkId); } void ktest_empty_pa_pk_as_req_draft9(krb5_pa_pk_as_req_draft9 *p) { ktest_empty_data(&p->signedAuthPack); ktest_empty_data(&p->kdcCert); } static void ktest_empty_dh_rep_info(krb5_dh_rep_info *p) { ktest_empty_data(&p->dhSignedData); ktest_empty_data(&p->serverDHNonce); ktest_destroy_data(&p->kdfID); } void ktest_empty_pa_pk_as_rep(krb5_pa_pk_as_rep *p) { if (p->choice == choice_pa_pk_as_rep_dhInfo) ktest_empty_dh_rep_info(&p->u.dh_Info); else if (p->choice == choice_pa_pk_as_rep_encKeyPack) ktest_empty_data(&p->u.encKeyPack); p->choice = choice_pa_pk_as_rep_UNKNOWN; } void ktest_empty_pa_pk_as_rep_draft9(krb5_pa_pk_as_rep_draft9 *p) { if (p->choice == choice_pa_pk_as_rep_draft9_dhSignedData) ktest_empty_data(&p->u.dhSignedData); else if (p->choice == choice_pa_pk_as_rep_draft9_encKeyPack) ktest_empty_data(&p->u.encKeyPack); p->choice = choice_pa_pk_as_rep_draft9_UNKNOWN; } void ktest_empty_auth_pack(krb5_auth_pack *p) { krb5_algorithm_identifier **ai; krb5_data **d; ktest_empty_pk_authenticator(&p->pkAuthenticator); if (p->clientPublicValue != NULL) { ktest_empty_subject_pk_info(p->clientPublicValue); free(p->clientPublicValue); p->clientPublicValue = NULL; } if (p->supportedCMSTypes != NULL) { for (ai = p->supportedCMSTypes; *ai != NULL; ai++) { ktest_empty_algorithm_identifier(*ai); free(*ai); } free(p->supportedCMSTypes); p->supportedCMSTypes = NULL; } ktest_empty_data(&p->clientDHNonce); if (p->supportedKDFs != NULL) { for (d = p->supportedKDFs; *d != NULL; d++) { ktest_empty_data(*d); free(*d); } free(p->supportedKDFs); p->supportedKDFs = NULL; } } void ktest_empty_auth_pack_draft9(krb5_auth_pack_draft9 *p) { ktest_empty_pk_authenticator_draft9(&p->pkAuthenticator); if (p->clientPublicValue != NULL) { ktest_empty_subject_pk_info(p->clientPublicValue); free(p->clientPublicValue); p->clientPublicValue = NULL; } } void ktest_empty_kdc_dh_key_info(krb5_kdc_dh_key_info *p) { ktest_empty_data(&p->subjectPublicKey); } void ktest_empty_reply_key_pack(krb5_reply_key_pack *p) { ktest_empty_keyblock(&p->replyKey); ktest_empty_checksum(&p->asChecksum); } void ktest_empty_reply_key_pack_draft9(krb5_reply_key_pack_draft9 *p) { ktest_empty_keyblock(&p->replyKey); } void ktest_empty_sp80056a_other_info(krb5_sp80056a_other_info *p) { ktest_empty_algorithm_identifier(&p->algorithm_identifier); ktest_destroy_principal(&p->party_u_info); ktest_destroy_principal(&p->party_v_info); ktest_empty_data(&p->supp_pub_info); } void ktest_empty_pkinit_supp_pub_info(krb5_pkinit_supp_pub_info *p) { ktest_empty_data(&p->as_req); ktest_empty_data(&p->pk_as_rep); } #endif /* not DISABLE_PKINIT */ #ifdef ENABLE_LDAP void ktest_empty_ldap_seqof_key_data(krb5_context ctx, ldap_seqof_key_data *p) { int i; for (i = 0; i < p->n_key_data; i++) { free(p->key_data[i].key_data_contents[0]); free(p->key_data[i].key_data_contents[1]); } free(p->key_data); } #endif void ktest_empty_kkdcp_message(krb5_kkdcp_message *p) { ktest_empty_data(&p->kerb_message); ktest_empty_data(&p->target_domain); p->dclocator_hint = -1; } static void destroy_verifier_mac(krb5_verifier_mac **vmac) { if (*vmac == NULL) return; ktest_destroy_principal(&(*vmac)->princ); ktest_empty_checksum(&(*vmac)->checksum); free(*vmac); *vmac = NULL; } void ktest_empty_cammac(krb5_cammac *p) { krb5_verifier_mac **vmacp; ktest_destroy_authorization_data(&p->elements); destroy_verifier_mac(&p->kdc_verifier); destroy_verifier_mac(&p->svc_verifier); for (vmacp = p->other_verifiers; vmacp != NULL && *vmacp != NULL; vmacp++) destroy_verifier_mac(vmacp); free(p->other_verifiers); p->other_verifiers = NULL; } void ktest_empty_secure_cookie(krb5_secure_cookie *p) { ktest_empty_pa_data_array(p->data); } krb5-1.16/src/tests/asn.1/pkinit_trval.out0000644000704600001450000001100713211554426020305 0ustar ghudsonlibuuid encode_krb5_pa_pk_as_req: [Sequence/Sequence Of] . [0] <8> 6b 72 62 35 64 61 74 61 krb5data . [1] [Sequence/Sequence Of] . . [Sequence/Sequence Of] . . . [0] <8> 6b 72 62 35 64 61 74 61 krb5data . . . [1] <8> 6b 72 62 35 64 61 74 61 krb5data . . . [2] <8> 6b 72 62 35 64 61 74 61 krb5data . [2] <8> 6b 72 62 35 64 61 74 61 krb5data encode_krb5_pa_pk_as_req_draft9: [Sequence/Sequence Of] . [0] <8> 6b 72 62 35 64 61 74 61 krb5data . [2] <8> 6b 72 62 35 64 61 74 61 krb5data encode_krb5_pa_pk_as_rep(dhInfo): [CONT 0] . [Sequence/Sequence Of] . . [0] <8> 6b 72 62 35 64 61 74 61 krb5data . . [1] [Octet String] "krb5data" . . [2] [Sequence/Sequence Of] . . . [0] [Object Identifier] <8> 6b 72 62 35 64 61 74 61 krb5data encode_krb5_pa_pk_as_rep(encKeyPack): [CONT 1] <8> 6b 72 62 35 64 61 74 61 krb5data encode_krb5_pa_pk_as_rep_draft9(dhSignedData): [CONT 0] <8> 6b 72 62 35 64 61 74 61 krb5data encode_krb5_pa_pk_as_rep_draft9(encKeyPack): [CONT 1] <8> 6b 72 62 35 64 61 74 61 krb5data encode_krb5_auth_pack: [Sequence/Sequence Of] . [0] [Sequence/Sequence Of] . . [0] [Integer] 123456 . . [1] [Generalized Time] "19940610060317Z" . . [2] [Integer] 42 . . [3] [Octet String] "1234" . [1] [Sequence/Sequence Of] . . [Sequence/Sequence Of] . . . [Object Identifier] <9> 2a 86 48 86 f7 12 01 02 02 *.H...... . . . [Octet String] "params" . . [Bit String] <9> 00 6b 72 62 35 64 61 74 61 .krb5data . [2] [Sequence/Sequence Of] . . [Sequence/Sequence Of] . . . [Object Identifier] <9> 2a 86 48 86 f7 12 01 02 02 *.H...... . . . [Octet String] "params" . . [Sequence/Sequence Of] . . . [Object Identifier] <9> 2a 86 48 86 f7 12 01 02 02 *.H...... . [3] [Octet String] "krb5data" . [4] [Sequence/Sequence Of] . . [Sequence/Sequence Of] . . . [0] [Object Identifier] <8> 6b 72 62 35 64 61 74 61 krb5data encode_krb5_auth_pack_draft9: [Sequence/Sequence Of] . [0] [Sequence/Sequence Of] . . [0] [Sequence/Sequence Of] . . . [0] [Integer] 1 . . . [1] [Sequence/Sequence Of] . . . . [General string] "hftsai" . . . . [General string] "extra" . . [1] [General string] "ATHENA.MIT.EDU" . . [2] [Integer] 123456 . . [3] [Generalized Time] "19940610060317Z" . . [4] [Integer] 42 . [1] [Sequence/Sequence Of] . . [Sequence/Sequence Of] . . . [Object Identifier] <9> 2a 86 48 86 f7 12 01 02 02 *.H...... . . . [Octet String] "params" . . [Bit String] <9> 00 6b 72 62 35 64 61 74 61 .krb5data encode_krb5_kdc_dh_key_info: [Sequence/Sequence Of] . [0] [Bit String] <9> 00 6b 72 62 35 64 61 74 61 .krb5data . [1] [Integer] 42 . [2] [Generalized Time] "19940610060317Z" encode_krb5_reply_key_pack: [Sequence/Sequence Of] . [0] [Sequence/Sequence Of] . . [0] [Integer] 1 . . [1] [Octet String] "12345678" . [1] [Sequence/Sequence Of] . . [0] [Integer] 1 . . [1] [Octet String] "1234" encode_krb5_reply_key_pack_draft9: [Sequence/Sequence Of] . [0] [Sequence/Sequence Of] . . [0] [Integer] 1 . . [1] [Octet String] "12345678" . [1] [Integer] 42 encode_krb5_sp80056a_other_info: [Sequence/Sequence Of] . [Sequence/Sequence Of] . . [Object Identifier] <9> 2a 86 48 86 f7 12 01 02 02 *.H...... . [0] [Octet String] <48> 30 2e a0 10 1b 0e 41 54 48 45 4e 41 2e 4d 49 54 0.....ATHENA.MIT 2e 45 44 55 a1 1a 30 18 a0 03 02 01 01 a1 11 30 .EDU..0........0 0f 1b 06 68 66 74 73 61 69 1b 05 65 78 74 72 61 ...hftsai..extra . [1] [Octet String] <48> 30 2e a0 10 1b 0e 41 54 48 45 4e 41 2e 4d 49 54 0.....ATHENA.MIT 2e 45 44 55 a1 1a 30 18 a0 03 02 01 01 a1 11 30 .EDU..0........0 0f 1b 06 68 66 74 73 61 69 1b 05 65 78 74 72 61 ...hftsai..extra . [2] [Octet String] "krb5data" encode_krb5_pkinit_supp_pub_info: [Sequence/Sequence Of] . [0] [Integer] 1 . [1] [Octet String] "krb5data" . [2] [Octet String] "krb5data" krb5-1.16/src/tests/asn.1/cammac.asn10000644000704600001450000000164113211554426017056 0ustar ghudsonlibuuidKerberosV5CAMMAC DEFINITIONS EXPLICIT TAGS ::= BEGIN IMPORTS AuthorizationData, PrincipalName, Checksum, UInt32, Int32 FROM KerberosV5Spec2 { iso(1) identified-organization(3) dod(6) internet(1) security(5) kerberosV5(2) modules(4) krb5spec2(2) }; -- as defined in RFC 4120. AD-CAMMAC ::= SEQUENCE { elements [0] AuthorizationData, kdc-verifier [1] Verifier-MAC OPTIONAL, svc-verifier [2] Verifier-MAC OPTIONAL, other-verifiers [3] SEQUENCE (SIZE (1..MAX)) OF Verifier OPTIONAL } Verifier ::= CHOICE { mac Verifier-MAC, ... } Verifier-MAC ::= SEQUENCE { identifier [0] PrincipalName OPTIONAL, kvno [1] UInt32 OPTIONAL, enctype [2] Int32 OPTIONAL, mac [3] Checksum } END krb5-1.16/src/tests/asn.1/krb5_decode_leak.c0000644000704600001450000006167313211554426020372 0ustar ghudsonlibuuid/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* tests/asn.1/krb5_decode_leak.c */ /* * Copyright (C) 2009 by the Massachusetts Institute of Technology. * All rights reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ /* * This program is intended to help detect memory leaks in the ASN.1 * decoder functions by exercising their failure paths. The setup * code for the test cases is copied from krb5_encode_test.c. * * This code does not actually detect leaks by itself; it must be run * through a leak-detection tool such as valgrind to do so. Simply * running the program will exercise a bunch of ASN.1 encoder and * decoder code paths but won't validate the results. */ #include "k5-int.h" #include "com_err.h" #include "utility.h" #include "ktest.h" #include "debug.h" krb5_context test_context; /* * Contrary to our usual convention, krb5_free_cred_enc_part is a * contents-only free function (and is assumed to be by mk_cred and * rd_cred) and we have no whole-structure free function for that data * type. So create one here. */ static void free_cred_enc_part_whole(krb5_context ctx, krb5_cred_enc_part *val) { krb5_free_cred_enc_part(ctx, val); free(val); } int main(int argc, char **argv) { krb5_data *code; krb5_error_code retval; unsigned int i; retval = krb5_init_context(&test_context); if (retval) { com_err(argv[0], retval, "while initializing krb5"); exit(1); } init_access(argv[0]); #define encode_run(value,type,typestring,description,encoder) /* * Encode a value. Then attempt to trigger most failure paths of * the decoder function by passing in corrupt encodings, which we * generate by perturbing each byte of the encoding in turn. Some * of the perturbed encodings are expected to decode successfully, * so we need a free function to discard successful results. Make * sure to define a pointer named "tmp" of the correct type in the * enclosing block. */ #define leak_test(value, encoder, decoder, freefn) \ retval = encoder(&(value),&(code)); \ if (retval) { \ com_err("krb5_decode_leak", retval, "while encoding"); \ exit(1); \ } \ for (i = 0; i < code->length; i++) { \ code->data[i] = (char)~((unsigned char)code->data[i]); \ retval = decoder(code, &tmp); \ code->data[i] = (char)~((unsigned char)code->data[i]); \ if (retval == 0) \ freefn(test_context, tmp); \ } \ krb5_free_data(test_context, code); /****************************************************************/ /* encode_krb5_authenticator */ { krb5_authenticator authent, *tmp; ktest_make_sample_authenticator(&authent); leak_test(authent, encode_krb5_authenticator, decode_krb5_authenticator, krb5_free_authenticator); ktest_destroy_checksum(&(authent.checksum)); ktest_destroy_keyblock(&(authent.subkey)); authent.seq_number = 0; ktest_empty_authorization_data(authent.authorization_data); leak_test(authent, encode_krb5_authenticator, decode_krb5_authenticator, krb5_free_authenticator); ktest_destroy_authorization_data(&(authent.authorization_data)); leak_test(authent, encode_krb5_authenticator, decode_krb5_authenticator, krb5_free_authenticator); ktest_empty_authenticator(&authent); } /****************************************************************/ /* encode_krb5_ticket */ { krb5_ticket tkt, *tmp; ktest_make_sample_ticket(&tkt); leak_test(tkt, encode_krb5_ticket, decode_krb5_ticket, krb5_free_ticket); ktest_empty_ticket(&tkt); } /****************************************************************/ /* encode_krb5_encryption_key */ { krb5_keyblock keyblk, *tmp; ktest_make_sample_keyblock(&keyblk); leak_test(keyblk, encode_krb5_encryption_key, decode_krb5_encryption_key, krb5_free_keyblock); ktest_empty_keyblock(&keyblk); } /****************************************************************/ /* encode_krb5_enc_tkt_part */ { krb5_ticket tkt; krb5_enc_tkt_part *tmp; memset(&tkt, 0, sizeof(krb5_ticket)); tkt.enc_part2 = ealloc(sizeof(krb5_enc_tkt_part)); ktest_make_sample_enc_tkt_part(tkt.enc_part2); leak_test(*(tkt.enc_part2), encode_krb5_enc_tkt_part, decode_krb5_enc_tkt_part, krb5_free_enc_tkt_part); tkt.enc_part2->times.starttime = 0; tkt.enc_part2->times.renew_till = 0; ktest_destroy_address(&(tkt.enc_part2->caddrs[1])); ktest_destroy_address(&(tkt.enc_part2->caddrs[0])); ktest_destroy_authdata(&(tkt.enc_part2->authorization_data[1])); ktest_destroy_authdata(&(tkt.enc_part2->authorization_data[0])); /* ISODE version fails on the empty caddrs field */ ktest_destroy_addresses(&(tkt.enc_part2->caddrs)); ktest_destroy_authorization_data(&(tkt.enc_part2->authorization_data)); leak_test(*(tkt.enc_part2), encode_krb5_enc_tkt_part, decode_krb5_enc_tkt_part, krb5_free_enc_tkt_part); ktest_empty_ticket(&tkt); } /****************************************************************/ /* encode_krb5_enc_kdc_rep_part */ { krb5_kdc_rep kdcr; krb5_enc_kdc_rep_part *tmp; memset(&kdcr, 0, sizeof(kdcr)); kdcr.enc_part2 = ealloc(sizeof(krb5_enc_kdc_rep_part)); ktest_make_sample_enc_kdc_rep_part(kdcr.enc_part2); leak_test(*(kdcr.enc_part2), encode_krb5_enc_kdc_rep_part, decode_krb5_enc_kdc_rep_part, krb5_free_enc_kdc_rep_part); kdcr.enc_part2->key_exp = 0; kdcr.enc_part2->times.starttime = 0; kdcr.enc_part2->flags &= ~TKT_FLG_RENEWABLE; ktest_destroy_addresses(&(kdcr.enc_part2->caddrs)); leak_test(*(kdcr.enc_part2), encode_krb5_enc_kdc_rep_part, decode_krb5_enc_kdc_rep_part, krb5_free_enc_kdc_rep_part); ktest_empty_kdc_rep(&kdcr); } /****************************************************************/ /* encode_krb5_as_rep */ { krb5_kdc_rep kdcr, *tmp; ktest_make_sample_kdc_rep(&kdcr); kdcr.msg_type = KRB5_AS_REP; leak_test(kdcr, encode_krb5_as_rep, decode_krb5_as_rep, krb5_free_kdc_rep); ktest_destroy_pa_data_array(&(kdcr.padata)); leak_test(kdcr, encode_krb5_as_rep, decode_krb5_as_rep, krb5_free_kdc_rep); ktest_empty_kdc_rep(&kdcr); } /****************************************************************/ /* encode_krb5_tgs_rep */ { krb5_kdc_rep kdcr, *tmp; ktest_make_sample_kdc_rep(&kdcr); kdcr.msg_type = KRB5_TGS_REP; leak_test(kdcr, encode_krb5_tgs_rep, decode_krb5_tgs_rep, krb5_free_kdc_rep); ktest_destroy_pa_data_array(&(kdcr.padata)); leak_test(kdcr, encode_krb5_tgs_rep, decode_krb5_tgs_rep, krb5_free_kdc_rep); ktest_empty_kdc_rep(&kdcr); } /****************************************************************/ /* encode_krb5_ap_req */ { krb5_ap_req apreq, *tmp; ktest_make_sample_ap_req(&apreq); leak_test(apreq, encode_krb5_ap_req, decode_krb5_ap_req, krb5_free_ap_req); ktest_empty_ap_req(&apreq); } /****************************************************************/ /* encode_krb5_ap_rep */ { krb5_ap_rep aprep, *tmp; ktest_make_sample_ap_rep(&aprep); leak_test(aprep, encode_krb5_ap_rep, decode_krb5_ap_rep, krb5_free_ap_rep); ktest_empty_ap_rep(&aprep); } /****************************************************************/ /* encode_krb5_ap_rep_enc_part */ { krb5_ap_rep_enc_part apenc, *tmp; ktest_make_sample_ap_rep_enc_part(&apenc); leak_test(apenc, encode_krb5_ap_rep_enc_part, decode_krb5_ap_rep_enc_part, krb5_free_ap_rep_enc_part); ktest_destroy_keyblock(&(apenc.subkey)); apenc.seq_number = 0; leak_test(apenc, encode_krb5_ap_rep_enc_part, decode_krb5_ap_rep_enc_part, krb5_free_ap_rep_enc_part); ktest_empty_ap_rep_enc_part(&apenc); } /****************************************************************/ /* encode_krb5_as_req */ { krb5_kdc_req asreq, *tmp; ktest_make_sample_kdc_req(&asreq); asreq.msg_type = KRB5_AS_REQ; asreq.kdc_options &= ~KDC_OPT_ENC_TKT_IN_SKEY; leak_test(asreq, encode_krb5_as_req, decode_krb5_as_req, krb5_free_kdc_req); ktest_destroy_pa_data_array(&(asreq.padata)); ktest_destroy_principal(&(asreq.client)); #ifndef ISODE_SUCKS ktest_destroy_principal(&(asreq.server)); #endif asreq.kdc_options |= KDC_OPT_ENC_TKT_IN_SKEY; asreq.from = 0; asreq.rtime = 0; ktest_destroy_addresses(&(asreq.addresses)); ktest_destroy_enc_data(&(asreq.authorization_data)); leak_test(asreq, encode_krb5_as_req, decode_krb5_as_req, krb5_free_kdc_req); ktest_destroy_sequence_of_ticket(&(asreq.second_ticket)); #ifndef ISODE_SUCKS ktest_make_sample_principal(&(asreq.server)); #endif asreq.kdc_options &= ~KDC_OPT_ENC_TKT_IN_SKEY; leak_test(asreq, encode_krb5_as_req, decode_krb5_as_req, krb5_free_kdc_req); ktest_empty_kdc_req(&asreq); } /****************************************************************/ /* encode_krb5_tgs_req */ { krb5_kdc_req tgsreq, *tmp; ktest_make_sample_kdc_req(&tgsreq); tgsreq.msg_type = KRB5_TGS_REQ; tgsreq.kdc_options &= ~KDC_OPT_ENC_TKT_IN_SKEY; leak_test(tgsreq, encode_krb5_tgs_req, decode_krb5_tgs_req, krb5_free_kdc_req); ktest_destroy_pa_data_array(&(tgsreq.padata)); ktest_destroy_principal(&(tgsreq.client)); #ifndef ISODE_SUCKS ktest_destroy_principal(&(tgsreq.server)); #endif tgsreq.kdc_options |= KDC_OPT_ENC_TKT_IN_SKEY; tgsreq.from = 0; tgsreq.rtime = 0; ktest_destroy_addresses(&(tgsreq.addresses)); ktest_destroy_enc_data(&(tgsreq.authorization_data)); leak_test(tgsreq, encode_krb5_tgs_req, decode_krb5_tgs_req, krb5_free_kdc_req); ktest_destroy_sequence_of_ticket(&(tgsreq.second_ticket)); #ifndef ISODE_SUCKS ktest_make_sample_principal(&(tgsreq.server)); #endif tgsreq.kdc_options &= ~KDC_OPT_ENC_TKT_IN_SKEY; leak_test(tgsreq, encode_krb5_tgs_req, decode_krb5_tgs_req, krb5_free_kdc_req); ktest_empty_kdc_req(&tgsreq); } /****************************************************************/ /* encode_krb5_kdc_req_body */ { krb5_kdc_req kdcrb, *tmp; memset(&kdcrb, 0, sizeof(kdcrb)); ktest_make_sample_kdc_req_body(&kdcrb); kdcrb.kdc_options &= ~KDC_OPT_ENC_TKT_IN_SKEY; leak_test(kdcrb, encode_krb5_kdc_req_body, decode_krb5_kdc_req_body, krb5_free_kdc_req); ktest_destroy_principal(&(kdcrb.client)); #ifndef ISODE_SUCKS ktest_destroy_principal(&(kdcrb.server)); #endif kdcrb.kdc_options |= KDC_OPT_ENC_TKT_IN_SKEY; kdcrb.from = 0; kdcrb.rtime = 0; ktest_destroy_addresses(&(kdcrb.addresses)); ktest_destroy_enc_data(&(kdcrb.authorization_data)); leak_test(kdcrb, encode_krb5_kdc_req_body, decode_krb5_kdc_req_body, krb5_free_kdc_req); ktest_destroy_sequence_of_ticket(&(kdcrb.second_ticket)); #ifndef ISODE_SUCKS ktest_make_sample_principal(&(kdcrb.server)); #endif kdcrb.kdc_options &= ~KDC_OPT_ENC_TKT_IN_SKEY; leak_test(kdcrb, encode_krb5_kdc_req_body, decode_krb5_kdc_req_body, krb5_free_kdc_req); ktest_empty_kdc_req(&kdcrb); } /****************************************************************/ /* encode_krb5_safe */ { krb5_safe s, *tmp; ktest_make_sample_safe(&s); leak_test(s, encode_krb5_safe, decode_krb5_safe, krb5_free_safe); s.timestamp = 0; /* s.usec should be opted out by the timestamp */ s.seq_number = 0; ktest_destroy_address(&(s.r_address)); leak_test(s, encode_krb5_safe, decode_krb5_safe, krb5_free_safe); ktest_empty_safe(&s); } /****************************************************************/ /* encode_krb5_priv */ { krb5_priv p, *tmp; ktest_make_sample_priv(&p); leak_test(p, encode_krb5_priv, decode_krb5_priv, krb5_free_priv); ktest_empty_priv(&p); } /****************************************************************/ /* encode_krb5_enc_priv_part */ { krb5_priv_enc_part ep, *tmp; ktest_make_sample_priv_enc_part(&ep); leak_test(ep, encode_krb5_enc_priv_part, decode_krb5_enc_priv_part, krb5_free_priv_enc_part); ep.timestamp = 0; /* ep.usec should be opted out along with timestamp */ ep.seq_number = 0; ktest_destroy_address(&(ep.r_address)); leak_test(ep, encode_krb5_enc_priv_part, decode_krb5_enc_priv_part, krb5_free_priv_enc_part); ktest_empty_priv_enc_part(&ep); } /****************************************************************/ /* encode_krb5_cred */ { krb5_cred c, *tmp; ktest_make_sample_cred(&c); leak_test(c, encode_krb5_cred, decode_krb5_cred, krb5_free_cred); ktest_empty_cred(&c); } /****************************************************************/ /* encode_krb5_enc_cred_part */ { krb5_cred_enc_part cep, *tmp; ktest_make_sample_cred_enc_part(&cep); leak_test(cep, encode_krb5_enc_cred_part, decode_krb5_enc_cred_part, free_cred_enc_part_whole); ktest_destroy_principal(&(cep.ticket_info[0]->client)); ktest_destroy_principal(&(cep.ticket_info[0]->server)); cep.ticket_info[0]->flags = 0; cep.ticket_info[0]->times.authtime = 0; cep.ticket_info[0]->times.starttime = 0; cep.ticket_info[0]->times.endtime = 0; cep.ticket_info[0]->times.renew_till = 0; ktest_destroy_addresses(&(cep.ticket_info[0]->caddrs)); cep.nonce = 0; cep.timestamp = 0; ktest_destroy_address(&(cep.s_address)); ktest_destroy_address(&(cep.r_address)); leak_test(cep, encode_krb5_enc_cred_part, decode_krb5_enc_cred_part, free_cred_enc_part_whole); ktest_empty_cred_enc_part(&cep); } /****************************************************************/ /* encode_krb5_error */ { krb5_error kerr, *tmp; ktest_make_sample_error(&kerr); leak_test(kerr, encode_krb5_error, decode_krb5_error, krb5_free_error); kerr.ctime = 0; ktest_destroy_principal(&(kerr.client)); ktest_empty_data(&(kerr.text)); ktest_empty_data(&(kerr.e_data)); leak_test(kerr, encode_krb5_error, decode_krb5_error, krb5_free_error); ktest_empty_error(&kerr); } /****************************************************************/ /* encode_krb5_authdata */ { krb5_authdata **ad, **tmp; ktest_make_sample_authorization_data(&ad); leak_test(*ad, encode_krb5_authdata, decode_krb5_authdata, krb5_free_authdata); ktest_destroy_authorization_data(&ad); } /****************************************************************/ /* encode_padata_sequence and encode_typed_data */ { krb5_pa_data **pa, **tmp; ktest_make_sample_pa_data_array(&pa); leak_test(*pa, encode_krb5_padata_sequence, decode_krb5_padata_sequence, krb5_free_pa_data); leak_test(*pa, encode_krb5_typed_data, decode_krb5_typed_data, krb5_free_pa_data); ktest_destroy_pa_data_array(&pa); } /****************************************************************/ /* encode_padata_sequence (empty) */ { krb5_pa_data **pa, **tmp; ktest_make_sample_empty_pa_data_array(&pa); leak_test(*pa, encode_krb5_padata_sequence, decode_krb5_padata_sequence, krb5_free_pa_data); ktest_destroy_pa_data_array(&pa); } /****************************************************************/ /* encode_etype_info */ { krb5_etype_info_entry **info, **tmp; ktest_make_sample_etype_info(&info); leak_test(*info, encode_krb5_etype_info, decode_krb5_etype_info, krb5_free_etype_info); ktest_destroy_etype_info_entry(info[2]); info[2] = 0; ktest_destroy_etype_info_entry(info[1]); info[1] = 0; leak_test(*info, encode_krb5_etype_info, decode_krb5_etype_info, krb5_free_etype_info); ktest_destroy_etype_info_entry(info[0]); info[0] = 0; leak_test(*info, encode_krb5_etype_info, decode_krb5_etype_info, krb5_free_etype_info); ktest_destroy_etype_info(info); } /* encode_etype_info 2*/ { krb5_etype_info_entry **info, **tmp; ktest_make_sample_etype_info2(&info); leak_test(*info, encode_krb5_etype_info2, decode_krb5_etype_info2, krb5_free_etype_info); ktest_destroy_etype_info_entry(info[2]); info[2] = 0; ktest_destroy_etype_info_entry(info[1]); info[1] = 0; leak_test(*info, encode_krb5_etype_info2, decode_krb5_etype_info2, krb5_free_etype_info); ktest_destroy_etype_info(info); } /****************************************************************/ /* encode_pa_enc_ts */ { krb5_pa_enc_ts pa_enc, *tmp; ktest_make_sample_pa_enc_ts(&pa_enc); leak_test(pa_enc, encode_krb5_pa_enc_ts, decode_krb5_pa_enc_ts, krb5_free_pa_enc_ts); pa_enc.pausec = 0; leak_test(pa_enc, encode_krb5_pa_enc_ts, decode_krb5_pa_enc_ts, krb5_free_pa_enc_ts); } /****************************************************************/ /* encode_enc_data */ { krb5_enc_data enc_data, *tmp; ktest_make_sample_enc_data(&enc_data); leak_test(enc_data, encode_krb5_enc_data, decode_krb5_enc_data, krb5_free_enc_data); ktest_destroy_enc_data(&enc_data); } /****************************************************************/ /* encode_krb5_sam_challenge_2 */ { krb5_sam_challenge_2 sam_ch2, *tmp; ktest_make_sample_sam_challenge_2(&sam_ch2); leak_test(sam_ch2, encode_krb5_sam_challenge_2, decode_krb5_sam_challenge_2, krb5_free_sam_challenge_2); ktest_empty_sam_challenge_2(&sam_ch2); } /****************************************************************/ /* encode_krb5_sam_challenge_2 */ { krb5_sam_challenge_2_body body, *tmp; ktest_make_sample_sam_challenge_2_body(&body); leak_test(body, encode_krb5_sam_challenge_2_body, decode_krb5_sam_challenge_2_body, krb5_free_sam_challenge_2_body); ktest_empty_sam_challenge_2_body(&body); } /****************************************************************/ /* encode_krb5_sam_response_2 */ { krb5_sam_response_2 sam_ch2, *tmp; ktest_make_sample_sam_response_2(&sam_ch2); leak_test(sam_ch2, encode_krb5_sam_response_2, decode_krb5_sam_response_2, krb5_free_sam_response_2); ktest_empty_sam_response_2(&sam_ch2); } /****************************************************************/ /* encode_krb5_sam_response_enc_2 */ { krb5_enc_sam_response_enc_2 sam_ch2, *tmp; ktest_make_sample_enc_sam_response_enc_2(&sam_ch2); leak_test(sam_ch2, encode_krb5_enc_sam_response_enc_2, decode_krb5_enc_sam_response_enc_2, krb5_free_enc_sam_response_enc_2); ktest_empty_enc_sam_response_enc_2(&sam_ch2); } /****************************************************************/ /* encode_krb5_pa_for_user */ { krb5_pa_for_user foru, *tmp; ktest_make_sample_pa_for_user(&foru); leak_test(foru, encode_krb5_pa_for_user, decode_krb5_pa_for_user, krb5_free_pa_for_user); ktest_empty_pa_for_user(&foru); } /****************************************************************/ /* encode_krb5_pa_s4u_x509_user */ { krb5_pa_s4u_x509_user s4u, *tmp; ktest_make_sample_pa_s4u_x509_user(&s4u); leak_test(s4u, encode_krb5_pa_s4u_x509_user, decode_krb5_pa_s4u_x509_user, krb5_free_pa_s4u_x509_user); ktest_empty_pa_s4u_x509_user(&s4u); } /****************************************************************/ /* encode_krb5_ad_kdcissued */ { krb5_ad_kdcissued kdci, *tmp; ktest_make_sample_ad_kdcissued(&kdci); leak_test(kdci, encode_krb5_ad_kdcissued, decode_krb5_ad_kdcissued, krb5_free_ad_kdcissued); ktest_empty_ad_kdcissued(&kdci); } #if 0 /****************************************************************/ /* encode_krb5_ad_signedpath_data */ { krb5_ad_signedpath_data spd, *tmp; ktest_make_sample_ad_signedpath_data(&spd); leak_test(spd, encode_krb5_ad_signedpath_data, decode_krb5_ad_signedpath_data, NULL); ktest_empty_ad_signedpath_data(&spd); } #endif /****************************************************************/ /* encode_krb5_ad_signedpath */ { krb5_ad_signedpath sp, *tmp; ktest_make_sample_ad_signedpath(&sp); leak_test(sp, encode_krb5_ad_signedpath, decode_krb5_ad_signedpath, krb5_free_ad_signedpath); ktest_empty_ad_signedpath(&sp); } /****************************************************************/ /* encode_krb5_iakerb_header */ { krb5_iakerb_header ih, *tmp; ktest_make_sample_iakerb_header(&ih); leak_test(ih, encode_krb5_iakerb_header, decode_krb5_iakerb_header, krb5_free_iakerb_header); ktest_empty_iakerb_header(&ih); } /****************************************************************/ /* encode_krb5_iakerb_finished */ { krb5_iakerb_finished ih, *tmp; ktest_make_sample_iakerb_finished(&ih); leak_test(ih, encode_krb5_iakerb_finished, decode_krb5_iakerb_finished, krb5_free_iakerb_finished); ktest_empty_iakerb_finished(&ih); } /****************************************************************/ /* encode_krb5_fast_response */ { krb5_fast_response fr, *tmp; ktest_make_sample_fast_response(&fr); leak_test(fr, encode_krb5_fast_response, decode_krb5_fast_response, krb5_free_fast_response); ktest_empty_fast_response(&fr); } /****************************************************************/ /* encode_krb5_pa_fx_fast_reply */ { krb5_enc_data enc, *tmp; ktest_make_sample_enc_data(&enc); leak_test(enc, encode_krb5_pa_fx_fast_reply, decode_krb5_pa_fx_fast_reply, krb5_free_enc_data); ktest_destroy_enc_data(&enc); } krb5_free_context(test_context); return 0; } krb5-1.16/src/tests/asn.1/pkix.asn10000644000704600001450000005536413211554426016623 0ustar ghudsonlibuuidPKIX1Explicit88 { iso(1) identified-organization(3) dod(6) internet(1) security(5) mechanisms(5) pkix(7) id-mod(0) id-pkix1-explicit(18) } DEFINITIONS EXPLICIT TAGS ::= BEGIN -- EXPORTS ALL -- -- IMPORTS NONE -- -- UNIVERSAL Types defined in 1993 and 1998 ASN.1 -- and required by this specification -- (Commented out for krb5 source tree) -- UniversalString ::= [UNIVERSAL 28] IMPLICIT OCTET STRING -- UniversalString is defined in ASN.1:1993 -- BMPString ::= [UNIVERSAL 30] IMPLICIT OCTET STRING -- BMPString is the subtype of UniversalString and models -- the Basic Multilingual Plane of ISO/IEC 10646 --UTF8String ::= [UNIVERSAL 12] IMPLICIT OCTET STRING -- The content of this type conforms to RFC 3629. -- PKIX specific OIDs id-pkix OBJECT IDENTIFIER ::= { iso(1) identified-organization(3) dod(6) internet(1) security(5) mechanisms(5) pkix(7) } -- PKIX arcs id-pe OBJECT IDENTIFIER ::= { id-pkix 1 } -- arc for private certificate extensions id-qt OBJECT IDENTIFIER ::= { id-pkix 2 } -- arc for policy qualifier types id-kp OBJECT IDENTIFIER ::= { id-pkix 3 } -- arc for extended key purpose OIDS id-ad OBJECT IDENTIFIER ::= { id-pkix 48 } -- arc for access descriptors -- policyQualifierIds for Internet policy qualifiers id-qt-cps OBJECT IDENTIFIER ::= { id-qt 1 } -- OID for CPS qualifier id-qt-unotice OBJECT IDENTIFIER ::= { id-qt 2 } -- OID for user notice qualifier -- access descriptor definitions id-ad-ocsp OBJECT IDENTIFIER ::= { id-ad 1 } id-ad-caIssuers OBJECT IDENTIFIER ::= { id-ad 2 } id-ad-timeStamping OBJECT IDENTIFIER ::= { id-ad 3 } id-ad-caRepository OBJECT IDENTIFIER ::= { id-ad 5 } -- attribute data types Attribute ::= SEQUENCE { type AttributeType, values SET OF AttributeValue } -- at least one value is required AttributeType ::= OBJECT IDENTIFIER AttributeValue ::= ANY -- DEFINED BY AttributeType AttributeTypeAndValue ::= SEQUENCE { type AttributeType, value AttributeValue } -- suggested naming attributes: Definition of the following -- information object set may be augmented to meet local -- requirements. Note that deleting members of the set may -- prevent interoperability with conforming implementations. -- presented in pairs: the AttributeType followed by the -- type definition for the corresponding AttributeValue -- Arc for standard naming attributes id-at OBJECT IDENTIFIER ::= { joint-iso-ccitt(2) ds(5) 4 } -- Naming attributes of type X520name id-at-name AttributeType ::= { id-at 41 } id-at-surname AttributeType ::= { id-at 4 } id-at-givenName AttributeType ::= { id-at 42 } id-at-initials AttributeType ::= { id-at 43 } id-at-generationQualifier AttributeType ::= { id-at 44 } -- Naming attributes of type X520Name: -- X520name ::= DirectoryString (SIZE (1..ub-name)) -- -- Expanded to avoid parameterized type: X520name ::= CHOICE { teletexString TeletexString (SIZE (1..ub-name)), printableString PrintableString (SIZE (1..ub-name)), universalString UniversalString (SIZE (1..ub-name)), utf8String UTF8String (SIZE (1..ub-name)), bmpString BMPString (SIZE (1..ub-name)) } -- Naming attributes of type X520CommonName id-at-commonName AttributeType ::= { id-at 3 } -- Naming attributes of type X520CommonName: -- X520CommonName ::= DirectoryName (SIZE (1..ub-common-name)) -- -- Expanded to avoid parameterized type: X520CommonName ::= CHOICE { teletexString TeletexString (SIZE (1..ub-common-name)), printableString PrintableString (SIZE (1..ub-common-name)), universalString UniversalString (SIZE (1..ub-common-name)), utf8String UTF8String (SIZE (1..ub-common-name)), bmpString BMPString (SIZE (1..ub-common-name)) } -- Naming attributes of type X520LocalityName id-at-localityName AttributeType ::= { id-at 7 } -- Naming attributes of type X520LocalityName: -- X520LocalityName ::= DirectoryName (SIZE (1..ub-locality-name)) -- -- Expanded to avoid parameterized type: X520LocalityName ::= CHOICE { teletexString TeletexString (SIZE (1..ub-locality-name)), printableString PrintableString (SIZE (1..ub-locality-name)), universalString UniversalString (SIZE (1..ub-locality-name)), utf8String UTF8String (SIZE (1..ub-locality-name)), bmpString BMPString (SIZE (1..ub-locality-name)) } -- Naming attributes of type X520StateOrProvinceName id-at-stateOrProvinceName AttributeType ::= { id-at 8 } -- Naming attributes of type X520StateOrProvinceName: -- X520StateOrProvinceName ::= DirectoryName (SIZE (1..ub-state-name)) -- -- Expanded to avoid parameterized type: X520StateOrProvinceName ::= CHOICE { teletexString TeletexString (SIZE (1..ub-state-name)), printableString PrintableString (SIZE (1..ub-state-name)), universalString UniversalString (SIZE (1..ub-state-name)), utf8String UTF8String (SIZE (1..ub-state-name)), bmpString BMPString (SIZE (1..ub-state-name)) } -- Naming attributes of type X520OrganizationName id-at-organizationName AttributeType ::= { id-at 10 } -- Naming attributes of type X520OrganizationName: -- X520OrganizationName ::= -- DirectoryName (SIZE (1..ub-organization-name)) -- -- Expanded to avoid parameterized type: X520OrganizationName ::= CHOICE { teletexString TeletexString (SIZE (1..ub-organization-name)), printableString PrintableString (SIZE (1..ub-organization-name)), universalString UniversalString (SIZE (1..ub-organization-name)), utf8String UTF8String (SIZE (1..ub-organization-name)), bmpString BMPString (SIZE (1..ub-organization-name)) } -- Naming attributes of type X520OrganizationalUnitName id-at-organizationalUnitName AttributeType ::= { id-at 11 } -- Naming attributes of type X520OrganizationalUnitName: -- X520OrganizationalUnitName ::= -- DirectoryName (SIZE (1..ub-organizational-unit-name)) -- -- Expanded to avoid parameterized type: X520OrganizationalUnitName ::= CHOICE { teletexString TeletexString (SIZE (1..ub-organizational-unit-name)), printableString PrintableString (SIZE (1..ub-organizational-unit-name)), universalString UniversalString (SIZE (1..ub-organizational-unit-name)), utf8String UTF8String (SIZE (1..ub-organizational-unit-name)), bmpString BMPString (SIZE (1..ub-organizational-unit-name)) } -- Naming attributes of type X520Title id-at-title AttributeType ::= { id-at 12 } -- Naming attributes of type X520Title: -- X520Title ::= DirectoryName (SIZE (1..ub-title)) -- -- Expanded to avoid parameterized type: X520Title ::= CHOICE { teletexString TeletexString (SIZE (1..ub-title)), printableString PrintableString (SIZE (1..ub-title)), universalString UniversalString (SIZE (1..ub-title)), utf8String UTF8String (SIZE (1..ub-title)), bmpString BMPString (SIZE (1..ub-title)) } -- Naming attributes of type X520dnQualifier id-at-dnQualifier AttributeType ::= { id-at 46 } X520dnQualifier ::= PrintableString -- Naming attributes of type X520countryName (digraph from IS 3166) id-at-countryName AttributeType ::= { id-at 6 } X520countryName ::= PrintableString (SIZE (2)) -- Naming attributes of type X520SerialNumber id-at-serialNumber AttributeType ::= { id-at 5 } X520SerialNumber ::= PrintableString (SIZE (1..ub-serial-number)) -- Naming attributes of type X520Pseudonym id-at-pseudonym AttributeType ::= { id-at 65 } -- Naming attributes of type X520Pseudonym: -- X520Pseudonym ::= DirectoryName (SIZE (1..ub-pseudonym)) -- -- Expanded to avoid parameterized type: X520Pseudonym ::= CHOICE { teletexString TeletexString (SIZE (1..ub-pseudonym)), printableString PrintableString (SIZE (1..ub-pseudonym)), universalString UniversalString (SIZE (1..ub-pseudonym)), utf8String UTF8String (SIZE (1..ub-pseudonym)), bmpString BMPString (SIZE (1..ub-pseudonym)) } -- Naming attributes of type DomainComponent (from RFC 4519) id-domainComponent AttributeType ::= { 0 9 2342 19200300 100 1 25 } DomainComponent ::= IA5String -- Legacy attributes pkcs-9 OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) 9 } id-emailAddress AttributeType ::= { pkcs-9 1 } EmailAddress ::= IA5String (SIZE (1..ub-emailaddress-length)) -- naming data types -- Name ::= CHOICE { -- only one possibility for now -- rdnSequence RDNSequence } RDNSequence ::= SEQUENCE OF RelativeDistinguishedName DistinguishedName ::= RDNSequence RelativeDistinguishedName ::= SET SIZE (1..MAX) OF AttributeTypeAndValue -- Directory string type -- DirectoryString ::= CHOICE { teletexString TeletexString (SIZE (1..MAX)), printableString PrintableString (SIZE (1..MAX)), universalString UniversalString (SIZE (1..MAX)), utf8String UTF8String (SIZE (1..MAX)), bmpString BMPString (SIZE (1..MAX)) } -- certificate and CRL specific structures begin here Certificate ::= SEQUENCE { tbsCertificate TBSCertificate, signatureAlgorithm AlgorithmIdentifier, signature BIT STRING } TBSCertificate ::= SEQUENCE { version [0] Version DEFAULT v1, serialNumber CertificateSerialNumber, signature AlgorithmIdentifier, issuer Name, validity Validity, subject Name, subjectPublicKeyInfo SubjectPublicKeyInfo, issuerUniqueID [1] IMPLICIT UniqueIdentifier OPTIONAL, -- If present, version MUST be v2 or v3 subjectUniqueID [2] IMPLICIT UniqueIdentifier OPTIONAL, -- If present, version MUST be v2 or v3 extensions [3] Extensions OPTIONAL -- If present, version MUST be v3 -- } Version ::= INTEGER { v1(0), v2(1), v3(2) } CertificateSerialNumber ::= INTEGER Validity ::= SEQUENCE { notBefore Time, notAfter Time } Time ::= CHOICE { utcTime UTCTime, generalTime GeneralizedTime } UniqueIdentifier ::= BIT STRING SubjectPublicKeyInfo ::= SEQUENCE { algorithm AlgorithmIdentifier, subjectPublicKey BIT STRING } Extensions ::= SEQUENCE SIZE (1..MAX) OF Extension Extension ::= SEQUENCE { extnID OBJECT IDENTIFIER, critical BOOLEAN DEFAULT FALSE, extnValue OCTET STRING -- contains the DER encoding of an ASN.1 value -- corresponding to the extension type identified -- by extnID } -- CRL structures CertificateList ::= SEQUENCE { tbsCertList TBSCertList, signatureAlgorithm AlgorithmIdentifier, signature BIT STRING } TBSCertList ::= SEQUENCE { version Version OPTIONAL, -- if present, MUST be v2 signature AlgorithmIdentifier, issuer Name, thisUpdate Time, nextUpdate Time OPTIONAL, revokedCertificates SEQUENCE OF SEQUENCE { userCertificate CertificateSerialNumber, revocationDate Time, crlEntryExtensions Extensions OPTIONAL -- if present, version MUST be v2 } OPTIONAL, crlExtensions [0] Extensions OPTIONAL } -- if present, version MUST be v2 -- Version, Time, CertificateSerialNumber, and Extensions were -- defined earlier for use in the certificate structure AlgorithmIdentifier ::= SEQUENCE { algorithm OBJECT IDENTIFIER, parameters ANY DEFINED BY algorithm OPTIONAL } -- contains a value of the type -- registered for use with the -- algorithm object identifier value -- X.400 address syntax starts here ORAddress ::= SEQUENCE { built-in-standard-attributes BuiltInStandardAttributes, built-in-domain-defined-attributes BuiltInDomainDefinedAttributes OPTIONAL, -- see also teletex-domain-defined-attributes extension-attributes ExtensionAttributes OPTIONAL } -- Built-in Standard Attributes BuiltInStandardAttributes ::= SEQUENCE { country-name CountryName OPTIONAL, administration-domain-name AdministrationDomainName OPTIONAL, network-address [0] IMPLICIT NetworkAddress OPTIONAL, -- see also extended-network-address terminal-identifier [1] IMPLICIT TerminalIdentifier OPTIONAL, private-domain-name [2] PrivateDomainName OPTIONAL, organization-name [3] IMPLICIT OrganizationName OPTIONAL, -- see also teletex-organization-name numeric-user-identifier [4] IMPLICIT NumericUserIdentifier OPTIONAL, personal-name [5] IMPLICIT PersonalName OPTIONAL, -- see also teletex-personal-name organizational-unit-names [6] IMPLICIT OrganizationalUnitNames OPTIONAL } -- see also teletex-organizational-unit-names CountryName ::= [APPLICATION 1] CHOICE { x121-dcc-code NumericString (SIZE (ub-country-name-numeric-length)), iso-3166-alpha2-code PrintableString (SIZE (ub-country-name-alpha-length)) } AdministrationDomainName ::= [APPLICATION 2] CHOICE { numeric NumericString (SIZE (0..ub-domain-name-length)), printable PrintableString (SIZE (0..ub-domain-name-length)) } NetworkAddress ::= X121Address -- see also extended-network-address X121Address ::= NumericString (SIZE (1..ub-x121-address-length)) TerminalIdentifier ::= PrintableString (SIZE (1..ub-terminal-id-length)) PrivateDomainName ::= CHOICE { numeric NumericString (SIZE (1..ub-domain-name-length)), printable PrintableString (SIZE (1..ub-domain-name-length)) } OrganizationName ::= PrintableString (SIZE (1..ub-organization-name-length)) -- see also teletex-organization-name NumericUserIdentifier ::= NumericString (SIZE (1..ub-numeric-user-id-length)) PersonalName ::= SET { surname [0] IMPLICIT PrintableString (SIZE (1..ub-surname-length)), given-name [1] IMPLICIT PrintableString (SIZE (1..ub-given-name-length)) OPTIONAL, initials [2] IMPLICIT PrintableString (SIZE (1..ub-initials-length)) OPTIONAL, generation-qualifier [3] IMPLICIT PrintableString (SIZE (1..ub-generation-qualifier-length)) OPTIONAL } -- see also teletex-personal-name OrganizationalUnitNames ::= SEQUENCE SIZE (1..ub-organizational-units) OF OrganizationalUnitName -- see also teletex-organizational-unit-names OrganizationalUnitName ::= PrintableString (SIZE (1..ub-organizational-unit-name-length)) -- Built-in Domain-defined Attributes BuiltInDomainDefinedAttributes ::= SEQUENCE SIZE (1..ub-domain-defined-attributes) OF BuiltInDomainDefinedAttribute BuiltInDomainDefinedAttribute ::= SEQUENCE { type PrintableString (SIZE (1..ub-domain-defined-attribute-type-length)), value PrintableString (SIZE (1..ub-domain-defined-attribute-value-length)) } -- Extension Attributes ExtensionAttributes ::= SET SIZE (1..ub-extension-attributes) OF ExtensionAttribute ExtensionAttribute ::= SEQUENCE { extension-attribute-type [0] IMPLICIT INTEGER (0..ub-extension-attributes), extension-attribute-value [1] ANY DEFINED BY extension-attribute-type } -- Extension types and attribute values common-name INTEGER ::= 1 CommonName ::= PrintableString (SIZE (1..ub-common-name-length)) teletex-common-name INTEGER ::= 2 TeletexCommonName ::= TeletexString (SIZE (1..ub-common-name-length)) teletex-organization-name INTEGER ::= 3 TeletexOrganizationName ::= TeletexString (SIZE (1..ub-organization-name-length)) teletex-personal-name INTEGER ::= 4 TeletexPersonalName ::= SET { surname [0] IMPLICIT TeletexString (SIZE (1..ub-surname-length)), given-name [1] IMPLICIT TeletexString (SIZE (1..ub-given-name-length)) OPTIONAL, initials [2] IMPLICIT TeletexString (SIZE (1..ub-initials-length)) OPTIONAL, generation-qualifier [3] IMPLICIT TeletexString (SIZE (1..ub-generation-qualifier-length)) OPTIONAL } teletex-organizational-unit-names INTEGER ::= 5 TeletexOrganizationalUnitNames ::= SEQUENCE SIZE (1..ub-organizational-units) OF TeletexOrganizationalUnitName TeletexOrganizationalUnitName ::= TeletexString (SIZE (1..ub-organizational-unit-name-length)) pds-name INTEGER ::= 7 PDSName ::= PrintableString (SIZE (1..ub-pds-name-length)) physical-delivery-country-name INTEGER ::= 8 PhysicalDeliveryCountryName ::= CHOICE { x121-dcc-code NumericString (SIZE (ub-country-name-numeric-length)), iso-3166-alpha2-code PrintableString (SIZE (ub-country-name-alpha-length)) } postal-code INTEGER ::= 9 PostalCode ::= CHOICE { numeric-code NumericString (SIZE (1..ub-postal-code-length)), printable-code PrintableString (SIZE (1..ub-postal-code-length)) } physical-delivery-office-name INTEGER ::= 10 PhysicalDeliveryOfficeName ::= PDSParameter physical-delivery-office-number INTEGER ::= 11 PhysicalDeliveryOfficeNumber ::= PDSParameter extension-OR-address-components INTEGER ::= 12 ExtensionORAddressComponents ::= PDSParameter physical-delivery-personal-name INTEGER ::= 13 PhysicalDeliveryPersonalName ::= PDSParameter physical-delivery-organization-name INTEGER ::= 14 PhysicalDeliveryOrganizationName ::= PDSParameter extension-physical-delivery-address-components INTEGER ::= 15 ExtensionPhysicalDeliveryAddressComponents ::= PDSParameter unformatted-postal-address INTEGER ::= 16 UnformattedPostalAddress ::= SET { printable-address SEQUENCE SIZE (1..ub-pds-physical-address-lines) OF PrintableString (SIZE (1..ub-pds-parameter-length)) OPTIONAL, teletex-string TeletexString (SIZE (1..ub-unformatted-address-length)) OPTIONAL } street-address INTEGER ::= 17 StreetAddress ::= PDSParameter post-office-box-address INTEGER ::= 18 PostOfficeBoxAddress ::= PDSParameter poste-restante-address INTEGER ::= 19 PosteRestanteAddress ::= PDSParameter unique-postal-name INTEGER ::= 20 UniquePostalName ::= PDSParameter local-postal-attributes INTEGER ::= 21 LocalPostalAttributes ::= PDSParameter PDSParameter ::= SET { printable-string PrintableString (SIZE(1..ub-pds-parameter-length)) OPTIONAL, teletex-string TeletexString (SIZE(1..ub-pds-parameter-length)) OPTIONAL } extended-network-address INTEGER ::= 22 ExtendedNetworkAddress ::= CHOICE { e163-4-address SEQUENCE { number [0] IMPLICIT NumericString (SIZE (1..ub-e163-4-number-length)), sub-address [1] IMPLICIT NumericString (SIZE (1..ub-e163-4-sub-address-length)) OPTIONAL }, psap-address [0] IMPLICIT PresentationAddress } PresentationAddress ::= SEQUENCE { pSelector [0] EXPLICIT OCTET STRING OPTIONAL, sSelector [1] EXPLICIT OCTET STRING OPTIONAL, tSelector [2] EXPLICIT OCTET STRING OPTIONAL, nAddresses [3] EXPLICIT SET SIZE (1..MAX) OF OCTET STRING } terminal-type INTEGER ::= 23 TerminalType ::= INTEGER { telex (3), teletex (4), g3-facsimile (5), g4-facsimile (6), ia5-terminal (7), videotex (8) } (0..ub-integer-options) -- Extension Domain-defined Attributes teletex-domain-defined-attributes INTEGER ::= 6 TeletexDomainDefinedAttributes ::= SEQUENCE SIZE (1..ub-domain-defined-attributes) OF TeletexDomainDefinedAttribute TeletexDomainDefinedAttribute ::= SEQUENCE { type TeletexString (SIZE (1..ub-domain-defined-attribute-type-length)), value TeletexString (SIZE (1..ub-domain-defined-attribute-value-length)) } -- specifications of Upper Bounds MUST be regarded as mandatory -- from Annex B of ITU-T X.411 Reference Definition of MTS Parameter -- Upper Bounds -- Upper Bounds ub-name INTEGER ::= 32768 ub-common-name INTEGER ::= 64 ub-locality-name INTEGER ::= 128 ub-state-name INTEGER ::= 128 ub-organization-name INTEGER ::= 64 ub-organizational-unit-name INTEGER ::= 64 ub-title INTEGER ::= 64 ub-serial-number INTEGER ::= 64 ub-match INTEGER ::= 128 ub-emailaddress-length INTEGER ::= 255 ub-common-name-length INTEGER ::= 64 ub-country-name-alpha-length INTEGER ::= 2 ub-country-name-numeric-length INTEGER ::= 3 ub-domain-defined-attributes INTEGER ::= 4 ub-domain-defined-attribute-type-length INTEGER ::= 8 ub-domain-defined-attribute-value-length INTEGER ::= 128 ub-domain-name-length INTEGER ::= 16 ub-extension-attributes INTEGER ::= 256 ub-e163-4-number-length INTEGER ::= 15 ub-e163-4-sub-address-length INTEGER ::= 40 ub-generation-qualifier-length INTEGER ::= 3 ub-given-name-length INTEGER ::= 16 ub-initials-length INTEGER ::= 5 ub-integer-options INTEGER ::= 256 ub-numeric-user-id-length INTEGER ::= 32 ub-organization-name-length INTEGER ::= 64 ub-organizational-unit-name-length INTEGER ::= 32 ub-organizational-units INTEGER ::= 4 ub-pds-name-length INTEGER ::= 16 ub-pds-parameter-length INTEGER ::= 30 ub-pds-physical-address-lines INTEGER ::= 6 ub-postal-code-length INTEGER ::= 16 ub-pseudonym INTEGER ::= 128 ub-surname-length INTEGER ::= 40 ub-terminal-id-length INTEGER ::= 24 ub-unformatted-address-length INTEGER ::= 180 ub-x121-address-length INTEGER ::= 16 -- Note - upper bounds on string types, such as TeletexString, are -- measured in characters. Excepting PrintableString or IA5String, a -- significantly greater number of octets will be required to hold -- such a value. As a minimum, 16 octets, or twice the specified -- upper bound, whichever is the larger, should be allowed for -- TeletexString. For UTF8String or UniversalString at least four -- times the upper bound should be allowed. END krb5-1.16/src/tests/asn.1/trval_reference.out0000644000704600001450000015526013211554426020757 0ustar ghudsonlibuuidencode_krb5_authenticator: [Krb5 Authenticator] . [Sequence/Sequence Of] . . [authenticator-vno] [Integer] 5 . . [crealm] [General string] "ATHENA.MIT.EDU" . . [cname] [Sequence/Sequence Of] . . . [name-type] [Integer] 1 . . . [name-string] [Sequence/Sequence Of] . . . . [General string] "hftsai" . . . . [General string] "extra" . . [cksum] [Sequence/Sequence Of] . . . [cksumtype] [Integer] 1 . . . [checksum] [Octet String] "1234" . . [cusec] [Integer] 123456 . . [ctime] [Generalized Time] "19940610060317Z" . . [subkey] [Sequence/Sequence Of] . . . [keytype] [Integer] 1 . . . [keyvalue] [Octet String] "12345678" . . [seq-number] [Integer] 17 . . [authorization-data] [Sequence/Sequence Of] . . . [Sequence/Sequence Of] . . . . [ad-type] [Integer] 1 . . . . [ad-data] [Octet String] "foobar" . . . [Sequence/Sequence Of] . . . . [ad-type] [Integer] 1 . . . . [ad-data] [Octet String] "foobar" encode_krb5_authenticator(optionals empty): [Krb5 Authenticator] . [Sequence/Sequence Of] . . [authenticator-vno] [Integer] 5 . . [crealm] [General string] "ATHENA.MIT.EDU" . . [cname] [Sequence/Sequence Of] . . . [name-type] [Integer] 1 . . . [name-string] [Sequence/Sequence Of] . . . . [General string] "hftsai" . . . . [General string] "extra" . . [cusec] [Integer] 123456 . . [ctime] [Generalized Time] "19940610060317Z" encode_krb5_authenticator(optionals NULL): [Krb5 Authenticator] . [Sequence/Sequence Of] . . [authenticator-vno] [Integer] 5 . . [crealm] [General string] "ATHENA.MIT.EDU" . . [cname] [Sequence/Sequence Of] . . . [name-type] [Integer] 1 . . . [name-string] [Sequence/Sequence Of] . . . . [General string] "hftsai" . . . . [General string] "extra" . . [cusec] [Integer] 123456 . . [ctime] [Generalized Time] "19940610060317Z" encode_krb5_ticket: [Krb5 Ticket] . [Sequence/Sequence Of] . . [tkt-vno] [Integer] 5 . . [realm] [General string] "ATHENA.MIT.EDU" . . [sname] [Sequence/Sequence Of] . . . [name-type] [Integer] 1 . . . [name-string] [Sequence/Sequence Of] . . . . [General string] "hftsai" . . . . [General string] "extra" . . [tkt-enc-part] [Sequence/Sequence Of] . . . [etype] [Integer] 0 . . . [kvno] [Integer] 5 . . . [cipher] [Octet String] "krbASN.1 test message" encode_krb5_keyblock: [Sequence/Sequence Of] . [keytype] [Integer] 1 . [keyvalue] [Octet String] "12345678" encode_krb5_enc_tkt_part: [Krb5 Encrypted ticket part] . [Sequence/Sequence Of] . . [flags] [Bit String] 0xfedcba98 . . [key] [Sequence/Sequence Of] . . . [keytype] [Integer] 1 . . . [keyvalue] [Octet String] "12345678" . . [crealm] [General string] "ATHENA.MIT.EDU" . . [cname] [Sequence/Sequence Of] . . . [name-type] [Integer] 1 . . . [name-string] [Sequence/Sequence Of] . . . . [General string] "hftsai" . . . . [General string] "extra" . . [transited] [Sequence/Sequence Of] . . . [flags] [Integer] 1 . . . [key] [Octet String] "EDU,MIT.,ATHENA.,WASHINGTON.EDU,CS." . . [authtime] [Generalized Time] "19940610060317Z" . . [starttime] [Generalized Time] "19940610060317Z" . . [endtime] [Generalized Time] "19940610060317Z" . . [renew-till] [Generalized Time] "19940610060317Z" . . [caddr] [Sequence/Sequence Of] . . . [Sequence/Sequence Of] . . . . [addr-type] [Integer] 2 . . . . [address] [Octet String] <4> 12 d0 00 23 ...# . . . [Sequence/Sequence Of] . . . . [addr-type] [Integer] 2 . . . . [address] [Octet String] <4> 12 d0 00 23 ...# . . [authorization-data] [Sequence/Sequence Of] . . . [Sequence/Sequence Of] . . . . [ad-type] [Integer] 1 . . . . [ad-data] [Octet String] "foobar" . . . [Sequence/Sequence Of] . . . . [ad-type] [Integer] 1 . . . . [ad-data] [Octet String] "foobar" encode_krb5_enc_tkt_part(optionals NULL): [Krb5 Encrypted ticket part] . [Sequence/Sequence Of] . . [flags] [Bit String] 0xfedcba98 . . [key] [Sequence/Sequence Of] . . . [keytype] [Integer] 1 . . . [keyvalue] [Octet String] "12345678" . . [crealm] [General string] "ATHENA.MIT.EDU" . . [cname] [Sequence/Sequence Of] . . . [name-type] [Integer] 1 . . . [name-string] [Sequence/Sequence Of] . . . . [General string] "hftsai" . . . . [General string] "extra" . . [transited] [Sequence/Sequence Of] . . . [flags] [Integer] 1 . . . [key] [Octet String] "EDU,MIT.,ATHENA.,WASHINGTON.EDU,CS." . . [authtime] [Generalized Time] "19940610060317Z" . . [endtime] [Generalized Time] "19940610060317Z" encode_krb5_enc_kdc_rep_part: [Krb5 Encrypted TGS-REP part] . [Sequence/Sequence Of] . . [key] [Sequence/Sequence Of] . . . [keytype] [Integer] 1 . . . [keyvalue] [Octet String] "12345678" . . [last-req] [Sequence/Sequence Of] . . . [Sequence/Sequence Of] . . . . [lr-type] [Integer] -5 . . . . [lr-value] [Generalized Time] "19940610060317Z" . . . [Sequence/Sequence Of] . . . . [lr-type] [Integer] -5 . . . . [lr-value] [Generalized Time] "19940610060317Z" . . [nonce] [Integer] 42 . . [key-expiration] [Generalized Time] "19940610060317Z" . . [flags] [Bit String] 0xfedcba98 . . [authtime] [Generalized Time] "19940610060317Z" . . [starttime] [Generalized Time] "19940610060317Z" . . [enddtime] [Generalized Time] "19940610060317Z" . . [renew-till] [Generalized Time] "19940610060317Z" . . [srealm] [General string] "ATHENA.MIT.EDU" . . [sname] [Sequence/Sequence Of] . . . [name-type] [Integer] 1 . . . [name-string] [Sequence/Sequence Of] . . . . [General string] "hftsai" . . . . [General string] "extra" . . [caddr] [Sequence/Sequence Of] . . . [Sequence/Sequence Of] . . . . [addr-type] [Integer] 2 . . . . [address] [Octet String] <4> 12 d0 00 23 ...# . . . [Sequence/Sequence Of] . . . . [addr-type] [Integer] 2 . . . . [address] [Octet String] <4> 12 d0 00 23 ...# encode_krb5_enc_kdc_rep_part(optionals NULL): [Krb5 Encrypted TGS-REP part] . [Sequence/Sequence Of] . . [key] [Sequence/Sequence Of] . . . [keytype] [Integer] 1 . . . [keyvalue] [Octet String] "12345678" . . [last-req] [Sequence/Sequence Of] . . . [Sequence/Sequence Of] . . . . [lr-type] [Integer] -5 . . . . [lr-value] [Generalized Time] "19940610060317Z" . . . [Sequence/Sequence Of] . . . . [lr-type] [Integer] -5 . . . . [lr-value] [Generalized Time] "19940610060317Z" . . [nonce] [Integer] 42 . . [flags] [Bit String] 0xfe5cba98 . . [authtime] [Generalized Time] "19940610060317Z" . . [enddtime] [Generalized Time] "19940610060317Z" . . [srealm] [General string] "ATHENA.MIT.EDU" . . [sname] [Sequence/Sequence Of] . . . [name-type] [Integer] 1 . . . [name-string] [Sequence/Sequence Of] . . . . [General string] "hftsai" . . . . [General string] "extra" encode_krb5_as_rep: [Krb5 AS-REP packet] . [Sequence/Sequence Of] . . [pvno] [Integer] 5 . . [msg-type] [Integer] 11 . . [padata] [Sequence/Sequence Of] . . . [Sequence/Sequence Of] . . . . [padata-type] [Integer] 13 . . . . [pa-data] [Octet String] "pa-data" . . . [Sequence/Sequence Of] . . . . [padata-type] [Integer] 13 . . . . [pa-data] [Octet String] "pa-data" . . [crealm] [General string] "ATHENA.MIT.EDU" . . [cname] [Sequence/Sequence Of] . . . [name-type] [Integer] 1 . . . [name-string] [Sequence/Sequence Of] . . . . [General string] "hftsai" . . . . [General string] "extra" . . [ticket] [Krb5 Ticket] . . . [Sequence/Sequence Of] . . . . [tkt-vno] [Integer] 5 . . . . [realm] [General string] "ATHENA.MIT.EDU" . . . . [sname] [Sequence/Sequence Of] . . . . . [name-type] [Integer] 1 . . . . . [name-string] [Sequence/Sequence Of] . . . . . . [General string] "hftsai" . . . . . . [General string] "extra" . . . . [tkt-enc-part] [Sequence/Sequence Of] . . . . . [etype] [Integer] 0 . . . . . [kvno] [Integer] 5 . . . . . [cipher] [Octet String] "krbASN.1 test message" . . [enc-part] [Sequence/Sequence Of] . . . [etype] [Integer] 0 . . . [kvno] [Integer] 5 . . . [cipher] [Octet String] "krbASN.1 test message" encode_krb5_as_rep(optionals NULL): [Krb5 AS-REP packet] . [Sequence/Sequence Of] . . [pvno] [Integer] 5 . . [msg-type] [Integer] 11 . . [crealm] [General string] "ATHENA.MIT.EDU" . . [cname] [Sequence/Sequence Of] . . . [name-type] [Integer] 1 . . . [name-string] [Sequence/Sequence Of] . . . . [General string] "hftsai" . . . . [General string] "extra" . . [ticket] [Krb5 Ticket] . . . [Sequence/Sequence Of] . . . . [tkt-vno] [Integer] 5 . . . . [realm] [General string] "ATHENA.MIT.EDU" . . . . [sname] [Sequence/Sequence Of] . . . . . [name-type] [Integer] 1 . . . . . [name-string] [Sequence/Sequence Of] . . . . . . [General string] "hftsai" . . . . . . [General string] "extra" . . . . [tkt-enc-part] [Sequence/Sequence Of] . . . . . [etype] [Integer] 0 . . . . . [kvno] [Integer] 5 . . . . . [cipher] [Octet String] "krbASN.1 test message" . . [enc-part] [Sequence/Sequence Of] . . . [etype] [Integer] 0 . . . [kvno] [Integer] 5 . . . [cipher] [Octet String] "krbASN.1 test message" encode_krb5_tgs_rep: [Krb5 TGS-REP packet] . [Sequence/Sequence Of] . . [pvno] [Integer] 5 . . [msg-type] [Integer] 13 . . [padata] [Sequence/Sequence Of] . . . [Sequence/Sequence Of] . . . . [padata-type] [Integer] 13 . . . . [pa-data] [Octet String] "pa-data" . . . [Sequence/Sequence Of] . . . . [padata-type] [Integer] 13 . . . . [pa-data] [Octet String] "pa-data" . . [crealm] [General string] "ATHENA.MIT.EDU" . . [cname] [Sequence/Sequence Of] . . . [name-type] [Integer] 1 . . . [name-string] [Sequence/Sequence Of] . . . . [General string] "hftsai" . . . . [General string] "extra" . . [ticket] [Krb5 Ticket] . . . [Sequence/Sequence Of] . . . . [tkt-vno] [Integer] 5 . . . . [realm] [General string] "ATHENA.MIT.EDU" . . . . [sname] [Sequence/Sequence Of] . . . . . [name-type] [Integer] 1 . . . . . [name-string] [Sequence/Sequence Of] . . . . . . [General string] "hftsai" . . . . . . [General string] "extra" . . . . [tkt-enc-part] [Sequence/Sequence Of] . . . . . [etype] [Integer] 0 . . . . . [kvno] [Integer] 5 . . . . . [cipher] [Octet String] "krbASN.1 test message" . . [enc-part] [Sequence/Sequence Of] . . . [etype] [Integer] 0 . . . [kvno] [Integer] 5 . . . [cipher] [Octet String] "krbASN.1 test message" encode_krb5_tgs_rep(optionals NULL): [Krb5 TGS-REP packet] . [Sequence/Sequence Of] . . [pvno] [Integer] 5 . . [msg-type] [Integer] 13 . . [crealm] [General string] "ATHENA.MIT.EDU" . . [cname] [Sequence/Sequence Of] . . . [name-type] [Integer] 1 . . . [name-string] [Sequence/Sequence Of] . . . . [General string] "hftsai" . . . . [General string] "extra" . . [ticket] [Krb5 Ticket] . . . [Sequence/Sequence Of] . . . . [tkt-vno] [Integer] 5 . . . . [realm] [General string] "ATHENA.MIT.EDU" . . . . [sname] [Sequence/Sequence Of] . . . . . [name-type] [Integer] 1 . . . . . [name-string] [Sequence/Sequence Of] . . . . . . [General string] "hftsai" . . . . . . [General string] "extra" . . . . [tkt-enc-part] [Sequence/Sequence Of] . . . . . [etype] [Integer] 0 . . . . . [kvno] [Integer] 5 . . . . . [cipher] [Octet String] "krbASN.1 test message" . . [enc-part] [Sequence/Sequence Of] . . . [etype] [Integer] 0 . . . [kvno] [Integer] 5 . . . [cipher] [Octet String] "krbASN.1 test message" encode_krb5_ap_req: [Krb5 AP-REQ packet] . [Sequence/Sequence Of] . . [pvno] [Integer] 5 . . [msg-type] [Integer] 14 . . [ap-options] [Bit String] 0xfedcba98 . . [ticket] [Krb5 Ticket] . . . [Sequence/Sequence Of] . . . . [tkt-vno] [Integer] 5 . . . . [realm] [General string] "ATHENA.MIT.EDU" . . . . [sname] [Sequence/Sequence Of] . . . . . [name-type] [Integer] 1 . . . . . [name-string] [Sequence/Sequence Of] . . . . . . [General string] "hftsai" . . . . . . [General string] "extra" . . . . [tkt-enc-part] [Sequence/Sequence Of] . . . . . [etype] [Integer] 0 . . . . . [kvno] [Integer] 5 . . . . . [cipher] [Octet String] "krbASN.1 test message" . . [authenticator] [Sequence/Sequence Of] . . . [etype] [Integer] 0 . . . [kvno] [Integer] 5 . . . [cipher] [Octet String] "krbASN.1 test message" encode_krb5_ap_rep: [Krb5 AP-REP packet] . [Sequence/Sequence Of] . . [pvno] [Integer] 5 . . [msg-type] [Integer] 15 . . [enc-part] [Sequence/Sequence Of] . . . [etype] [Integer] 0 . . . [kvno] [Integer] 5 . . . [cipher] [Octet String] "krbASN.1 test message" encode_krb5_ap_rep_enc_part: [Krb5 Encrypted AP-REP part] . [Sequence/Sequence Of] . . [ctime] [Generalized Time] "19940610060317Z" . . [cusec] [Integer] 123456 . . [subkey] [Sequence/Sequence Of] . . . [keytype] [Integer] 1 . . . [keyvalue] [Octet String] "12345678" . . [seq-number] [Integer] 17 encode_krb5_ap_rep_enc_part(optionals NULL): [Krb5 Encrypted AP-REP part] . [Sequence/Sequence Of] . . [ctime] [Generalized Time] "19940610060317Z" . . [cusec] [Integer] 123456 encode_krb5_as_req: [Krb5 AS-REQ packet] . [Sequence/Sequence Of] . . [pvno] [Integer] 5 . . [msg-type] [Integer] 10 . . [padata] [Sequence/Sequence Of] . . . [Sequence/Sequence Of] . . . . [padata-type] [Integer] 13 . . . . [pa-data] [Octet String] "pa-data" . . . [Sequence/Sequence Of] . . . . [padata-type] [Integer] 13 . . . . [pa-data] [Octet String] "pa-data" . . [req-body] [Sequence/Sequence Of] . . . [kdc-options] [Bit String] 0xfedcba90 . . . [cname] [Sequence/Sequence Of] . . . . [name-type] [Integer] 1 . . . . [name-string] [Sequence/Sequence Of] . . . . . [General string] "hftsai" . . . . . [General string] "extra" . . . [realm] [General string] "ATHENA.MIT.EDU" . . . [sname] [Sequence/Sequence Of] . . . . [name-type] [Integer] 1 . . . . [name-string] [Sequence/Sequence Of] . . . . . [General string] "hftsai" . . . . . [General string] "extra" . . . [from] [Generalized Time] "19940610060317Z" . . . [till] [Generalized Time] "19940610060317Z" . . . [rtime] [Generalized Time] "19940610060317Z" . . . [nonce] [Integer] 42 . . . [etype] [Sequence/Sequence Of] . . . . [Integer] 0 . . . . [Integer] 1 . . . [addresses] [Sequence/Sequence Of] . . . . [Sequence/Sequence Of] . . . . . [addr-type] [Integer] 2 . . . . . [address] [Octet String] <4> 12 d0 00 23 ...# . . . . [Sequence/Sequence Of] . . . . . [addr-type] [Integer] 2 . . . . . [address] [Octet String] <4> 12 d0 00 23 ...# . . . [enc-authorization-data] [Sequence/Sequence Of] . . . . [etype] [Integer] 0 . . . . [kvno] [Integer] 5 . . . . [cipher] [Octet String] "krbASN.1 test message" . . . [additional-tickets] [Sequence/Sequence Of] . . . . [Krb5 Ticket] . . . . . [Sequence/Sequence Of] . . . . . . [tkt-vno] [Integer] 5 . . . . . . [realm] [General string] "ATHENA.MIT.EDU" . . . . . . [sname] [Sequence/Sequence Of] . . . . . . . [name-type] [Integer] 1 . . . . . . . [name-string] [Sequence/Sequence Of] . . . . . . . . [General string] "hftsai" . . . . . . . . [General string] "extra" . . . . . . [tkt-enc-part] [Sequence/Sequence Of] . . . . . . . [etype] [Integer] 0 . . . . . . . [kvno] [Integer] 5 . . . . . . . [cipher] [Octet String] "krbASN.1 test message" . . . . [Krb5 Ticket] . . . . . [Sequence/Sequence Of] . . . . . . [tkt-vno] [Integer] 5 . . . . . . [realm] [General string] "ATHENA.MIT.EDU" . . . . . . [sname] [Sequence/Sequence Of] . . . . . . . [name-type] [Integer] 1 . . . . . . . [name-string] [Sequence/Sequence Of] . . . . . . . . [General string] "hftsai" . . . . . . . . [General string] "extra" . . . . . . [tkt-enc-part] [Sequence/Sequence Of] . . . . . . . [etype] [Integer] 0 . . . . . . . [kvno] [Integer] 5 . . . . . . . [cipher] [Octet String] "krbASN.1 test message" encode_krb5_as_req(optionals NULL except second_ticket): [Krb5 AS-REQ packet] . [Sequence/Sequence Of] . . [pvno] [Integer] 5 . . [msg-type] [Integer] 10 . . [req-body] [Sequence/Sequence Of] . . . [kdc-options] [Bit String] 0xfedcba98 . . . [realm] [General string] "ATHENA.MIT.EDU" . . . [till] [Generalized Time] "19940610060317Z" . . . [nonce] [Integer] 42 . . . [etype] [Sequence/Sequence Of] . . . . [Integer] 0 . . . . [Integer] 1 . . . [additional-tickets] [Sequence/Sequence Of] . . . . [Krb5 Ticket] . . . . . [Sequence/Sequence Of] . . . . . . [tkt-vno] [Integer] 5 . . . . . . [realm] [General string] "ATHENA.MIT.EDU" . . . . . . [sname] [Sequence/Sequence Of] . . . . . . . [name-type] [Integer] 1 . . . . . . . [name-string] [Sequence/Sequence Of] . . . . . . . . [General string] "hftsai" . . . . . . . . [General string] "extra" . . . . . . [tkt-enc-part] [Sequence/Sequence Of] . . . . . . . [etype] [Integer] 0 . . . . . . . [kvno] [Integer] 5 . . . . . . . [cipher] [Octet String] "krbASN.1 test message" . . . . [Krb5 Ticket] . . . . . [Sequence/Sequence Of] . . . . . . [tkt-vno] [Integer] 5 . . . . . . [realm] [General string] "ATHENA.MIT.EDU" . . . . . . [sname] [Sequence/Sequence Of] . . . . . . . [name-type] [Integer] 1 . . . . . . . [name-string] [Sequence/Sequence Of] . . . . . . . . [General string] "hftsai" . . . . . . . . [General string] "extra" . . . . . . [tkt-enc-part] [Sequence/Sequence Of] . . . . . . . [etype] [Integer] 0 . . . . . . . [kvno] [Integer] 5 . . . . . . . [cipher] [Octet String] "krbASN.1 test message" encode_krb5_as_req(optionals NULL except server): [Krb5 AS-REQ packet] . [Sequence/Sequence Of] . . [pvno] [Integer] 5 . . [msg-type] [Integer] 10 . . [req-body] [Sequence/Sequence Of] . . . [kdc-options] [Bit String] 0xfedcba90 . . . [realm] [General string] "ATHENA.MIT.EDU" . . . [sname] [Sequence/Sequence Of] . . . . [name-type] [Integer] 1 . . . . [name-string] [Sequence/Sequence Of] . . . . . [General string] "hftsai" . . . . . [General string] "extra" . . . [till] [Generalized Time] "19940610060317Z" . . . [nonce] [Integer] 42 . . . [etype] [Sequence/Sequence Of] . . . . [Integer] 0 . . . . [Integer] 1 encode_krb5_tgs_req: [Krb5 TGS-REQ packet] . [Sequence/Sequence Of] . . [pvno] [Integer] 5 . . [msg-type] [Integer] 12 . . [padata] [Sequence/Sequence Of] . . . [Sequence/Sequence Of] . . . . [padata-type] [Integer] 13 . . . . [pa-data] [Octet String] "pa-data" . . . [Sequence/Sequence Of] . . . . [padata-type] [Integer] 13 . . . . [pa-data] [Octet String] "pa-data" . . [req-body] [Sequence/Sequence Of] . . . [kdc-options] [Bit String] 0xfedcba90 . . . [cname] [Sequence/Sequence Of] . . . . [name-type] [Integer] 1 . . . . [name-string] [Sequence/Sequence Of] . . . . . [General string] "hftsai" . . . . . [General string] "extra" . . . [realm] [General string] "ATHENA.MIT.EDU" . . . [sname] [Sequence/Sequence Of] . . . . [name-type] [Integer] 1 . . . . [name-string] [Sequence/Sequence Of] . . . . . [General string] "hftsai" . . . . . [General string] "extra" . . . [from] [Generalized Time] "19940610060317Z" . . . [till] [Generalized Time] "19940610060317Z" . . . [rtime] [Generalized Time] "19940610060317Z" . . . [nonce] [Integer] 42 . . . [etype] [Sequence/Sequence Of] . . . . [Integer] 0 . . . . [Integer] 1 . . . [addresses] [Sequence/Sequence Of] . . . . [Sequence/Sequence Of] . . . . . [addr-type] [Integer] 2 . . . . . [address] [Octet String] <4> 12 d0 00 23 ...# . . . . [Sequence/Sequence Of] . . . . . [addr-type] [Integer] 2 . . . . . [address] [Octet String] <4> 12 d0 00 23 ...# . . . [enc-authorization-data] [Sequence/Sequence Of] . . . . [etype] [Integer] 0 . . . . [kvno] [Integer] 5 . . . . [cipher] [Octet String] "krbASN.1 test message" . . . [additional-tickets] [Sequence/Sequence Of] . . . . [Krb5 Ticket] . . . . . [Sequence/Sequence Of] . . . . . . [tkt-vno] [Integer] 5 . . . . . . [realm] [General string] "ATHENA.MIT.EDU" . . . . . . [sname] [Sequence/Sequence Of] . . . . . . . [name-type] [Integer] 1 . . . . . . . [name-string] [Sequence/Sequence Of] . . . . . . . . [General string] "hftsai" . . . . . . . . [General string] "extra" . . . . . . [tkt-enc-part] [Sequence/Sequence Of] . . . . . . . [etype] [Integer] 0 . . . . . . . [kvno] [Integer] 5 . . . . . . . [cipher] [Octet String] "krbASN.1 test message" . . . . [Krb5 Ticket] . . . . . [Sequence/Sequence Of] . . . . . . [tkt-vno] [Integer] 5 . . . . . . [realm] [General string] "ATHENA.MIT.EDU" . . . . . . [sname] [Sequence/Sequence Of] . . . . . . . [name-type] [Integer] 1 . . . . . . . [name-string] [Sequence/Sequence Of] . . . . . . . . [General string] "hftsai" . . . . . . . . [General string] "extra" . . . . . . [tkt-enc-part] [Sequence/Sequence Of] . . . . . . . [etype] [Integer] 0 . . . . . . . [kvno] [Integer] 5 . . . . . . . [cipher] [Octet String] "krbASN.1 test message" encode_krb5_tgs_req(optionals NULL except second_ticket): [Krb5 TGS-REQ packet] . [Sequence/Sequence Of] . . [pvno] [Integer] 5 . . [msg-type] [Integer] 12 . . [req-body] [Sequence/Sequence Of] . . . [kdc-options] [Bit String] 0xfedcba98 . . . [realm] [General string] "ATHENA.MIT.EDU" . . . [till] [Generalized Time] "19940610060317Z" . . . [nonce] [Integer] 42 . . . [etype] [Sequence/Sequence Of] . . . . [Integer] 0 . . . . [Integer] 1 . . . [additional-tickets] [Sequence/Sequence Of] . . . . [Krb5 Ticket] . . . . . [Sequence/Sequence Of] . . . . . . [tkt-vno] [Integer] 5 . . . . . . [realm] [General string] "ATHENA.MIT.EDU" . . . . . . [sname] [Sequence/Sequence Of] . . . . . . . [name-type] [Integer] 1 . . . . . . . [name-string] [Sequence/Sequence Of] . . . . . . . . [General string] "hftsai" . . . . . . . . [General string] "extra" . . . . . . [tkt-enc-part] [Sequence/Sequence Of] . . . . . . . [etype] [Integer] 0 . . . . . . . [kvno] [Integer] 5 . . . . . . . [cipher] [Octet String] "krbASN.1 test message" . . . . [Krb5 Ticket] . . . . . [Sequence/Sequence Of] . . . . . . [tkt-vno] [Integer] 5 . . . . . . [realm] [General string] "ATHENA.MIT.EDU" . . . . . . [sname] [Sequence/Sequence Of] . . . . . . . [name-type] [Integer] 1 . . . . . . . [name-string] [Sequence/Sequence Of] . . . . . . . . [General string] "hftsai" . . . . . . . . [General string] "extra" . . . . . . [tkt-enc-part] [Sequence/Sequence Of] . . . . . . . [etype] [Integer] 0 . . . . . . . [kvno] [Integer] 5 . . . . . . . [cipher] [Octet String] "krbASN.1 test message" encode_krb5_tgs_req(optionals NULL except server): [Krb5 TGS-REQ packet] . [Sequence/Sequence Of] . . [pvno] [Integer] 5 . . [msg-type] [Integer] 12 . . [req-body] [Sequence/Sequence Of] . . . [kdc-options] [Bit String] 0xfedcba90 . . . [realm] [General string] "ATHENA.MIT.EDU" . . . [sname] [Sequence/Sequence Of] . . . . [name-type] [Integer] 1 . . . . [name-string] [Sequence/Sequence Of] . . . . . [General string] "hftsai" . . . . . [General string] "extra" . . . [till] [Generalized Time] "19940610060317Z" . . . [nonce] [Integer] 42 . . . [etype] [Sequence/Sequence Of] . . . . [Integer] 0 . . . . [Integer] 1 encode_krb5_kdc_req_body: [Sequence/Sequence Of] . [kdc-options] [Bit String] 0xfedcba90 . [cname] [Sequence/Sequence Of] . . [name-type] [Integer] 1 . . [name-string] [Sequence/Sequence Of] . . . [General string] "hftsai" . . . [General string] "extra" . [realm] [General string] "ATHENA.MIT.EDU" . [sname] [Sequence/Sequence Of] . . [name-type] [Integer] 1 . . [name-string] [Sequence/Sequence Of] . . . [General string] "hftsai" . . . [General string] "extra" . [from] [Generalized Time] "19940610060317Z" . [till] [Generalized Time] "19940610060317Z" . [rtime] [Generalized Time] "19940610060317Z" . [nonce] [Integer] 42 . [etype] [Sequence/Sequence Of] . . [Integer] 0 . . [Integer] 1 . [addresses] [Sequence/Sequence Of] . . [Sequence/Sequence Of] . . . [addr-type] [Integer] 2 . . . [address] [Octet String] <4> 12 d0 00 23 ...# . . [Sequence/Sequence Of] . . . [addr-type] [Integer] 2 . . . [address] [Octet String] <4> 12 d0 00 23 ...# . [enc-authorization-data] [Sequence/Sequence Of] . . [etype] [Integer] 0 . . [kvno] [Integer] 5 . . [cipher] [Octet String] "krbASN.1 test message" . [additional-tickets] [Sequence/Sequence Of] . . [Krb5 Ticket] . . . [Sequence/Sequence Of] . . . . [tkt-vno] [Integer] 5 . . . . [realm] [General string] "ATHENA.MIT.EDU" . . . . [sname] [Sequence/Sequence Of] . . . . . [name-type] [Integer] 1 . . . . . [name-string] [Sequence/Sequence Of] . . . . . . [General string] "hftsai" . . . . . . [General string] "extra" . . . . [tkt-enc-part] [Sequence/Sequence Of] . . . . . [etype] [Integer] 0 . . . . . [kvno] [Integer] 5 . . . . . [cipher] [Octet String] "krbASN.1 test message" . . [Krb5 Ticket] . . . [Sequence/Sequence Of] . . . . [tkt-vno] [Integer] 5 . . . . [realm] [General string] "ATHENA.MIT.EDU" . . . . [sname] [Sequence/Sequence Of] . . . . . [name-type] [Integer] 1 . . . . . [name-string] [Sequence/Sequence Of] . . . . . . [General string] "hftsai" . . . . . . [General string] "extra" . . . . [tkt-enc-part] [Sequence/Sequence Of] . . . . . [etype] [Integer] 0 . . . . . [kvno] [Integer] 5 . . . . . [cipher] [Octet String] "krbASN.1 test message" encode_krb5_kdc_req_body(optionals NULL except second_ticket): [Sequence/Sequence Of] . [kdc-options] [Bit String] 0xfedcba98 . [realm] [General string] "ATHENA.MIT.EDU" . [till] [Generalized Time] "19940610060317Z" . [nonce] [Integer] 42 . [etype] [Sequence/Sequence Of] . . [Integer] 0 . . [Integer] 1 . [additional-tickets] [Sequence/Sequence Of] . . [Krb5 Ticket] . . . [Sequence/Sequence Of] . . . . [tkt-vno] [Integer] 5 . . . . [realm] [General string] "ATHENA.MIT.EDU" . . . . [sname] [Sequence/Sequence Of] . . . . . [name-type] [Integer] 1 . . . . . [name-string] [Sequence/Sequence Of] . . . . . . [General string] "hftsai" . . . . . . [General string] "extra" . . . . [tkt-enc-part] [Sequence/Sequence Of] . . . . . [etype] [Integer] 0 . . . . . [kvno] [Integer] 5 . . . . . [cipher] [Octet String] "krbASN.1 test message" . . [Krb5 Ticket] . . . [Sequence/Sequence Of] . . . . [tkt-vno] [Integer] 5 . . . . [realm] [General string] "ATHENA.MIT.EDU" . . . . [sname] [Sequence/Sequence Of] . . . . . [name-type] [Integer] 1 . . . . . [name-string] [Sequence/Sequence Of] . . . . . . [General string] "hftsai" . . . . . . [General string] "extra" . . . . [tkt-enc-part] [Sequence/Sequence Of] . . . . . [etype] [Integer] 0 . . . . . [kvno] [Integer] 5 . . . . . [cipher] [Octet String] "krbASN.1 test message" encode_krb5_kdc_req_body(optionals NULL except server): [Sequence/Sequence Of] . [kdc-options] [Bit String] 0xfedcba90 . [realm] [General string] "ATHENA.MIT.EDU" . [sname] [Sequence/Sequence Of] . . [name-type] [Integer] 1 . . [name-string] [Sequence/Sequence Of] . . . [General string] "hftsai" . . . [General string] "extra" . [till] [Generalized Time] "19940610060317Z" . [nonce] [Integer] 42 . [etype] [Sequence/Sequence Of] . . [Integer] 0 . . [Integer] 1 encode_krb5_safe: [Krb5 SAFE packet] . [Sequence/Sequence Of] . . [pvno] [Integer] 5 . . [msg-type] [Integer] 20 . . [safe-body] [Sequence/Sequence Of] . . . [user-data] [Octet String] "krb5data" . . . [timestamp] [Generalized Time] "19940610060317Z" . . . [usec] [Integer] 123456 . . . [seq-number] [Integer] 17 . . . [s-address] [Sequence/Sequence Of] . . . . [addr-type] [Integer] 2 . . . . [address] [Octet String] <4> 12 d0 00 23 ...# . . . [r-address] [Sequence/Sequence Of] . . . . [addr-type] [Integer] 2 . . . . [address] [Octet String] <4> 12 d0 00 23 ...# . . [cksum] [Sequence/Sequence Of] . . . [cksumtype] [Integer] 1 . . . [checksum] [Octet String] "1234" encode_krb5_safe(optionals NULL): [Krb5 SAFE packet] . [Sequence/Sequence Of] . . [pvno] [Integer] 5 . . [msg-type] [Integer] 20 . . [safe-body] [Sequence/Sequence Of] . . . [user-data] [Octet String] "krb5data" . . . [s-address] [Sequence/Sequence Of] . . . . [addr-type] [Integer] 2 . . . . [address] [Octet String] <4> 12 d0 00 23 ...# . . [cksum] [Sequence/Sequence Of] . . . [cksumtype] [Integer] 1 . . . [checksum] [Octet String] "1234" encode_krb5_priv: [Krb5 PRIV packet] . [Sequence/Sequence Of] . . [pvno] [Integer] 5 . . [msg-type] [Integer] 21 . . [3] [Sequence/Sequence Of] . . . [pvno] [Integer] 0 . . . [msg-type] [Integer] 5 . . . [enc-part] [Octet String] "krbASN.1 test message" encode_krb5_enc_priv_part: [Krb5 Encrypted PRIV part] . [Sequence/Sequence Of] . . [user-data] [Octet String] "krb5data" . . [timestamp] [Generalized Time] "19940610060317Z" . . [usec] [Integer] 123456 . . [seq-number] [Integer] 17 . . [s-address] [Sequence/Sequence Of] . . . [addr-type] [Integer] 2 . . . [address] [Octet String] <4> 12 d0 00 23 ...# . . [r-address] [Sequence/Sequence Of] . . . [addr-type] [Integer] 2 . . . [address] [Octet String] <4> 12 d0 00 23 ...# encode_krb5_enc_priv_part(optionals NULL): [Krb5 Encrypted PRIV part] . [Sequence/Sequence Of] . . [user-data] [Octet String] "krb5data" . . [s-address] [Sequence/Sequence Of] . . . [addr-type] [Integer] 2 . . . [address] [Octet String] <4> 12 d0 00 23 ...# encode_krb5_cred: [Krb5 CRED packet] . [Sequence/Sequence Of] . . [pvno] [Integer] 5 . . [msg-type] [Integer] 22 . . [tickets] [Sequence/Sequence Of] . . . [Krb5 Ticket] . . . . [Sequence/Sequence Of] . . . . . [tkt-vno] [Integer] 5 . . . . . [realm] [General string] "ATHENA.MIT.EDU" . . . . . [sname] [Sequence/Sequence Of] . . . . . . [name-type] [Integer] 1 . . . . . . [name-string] [Sequence/Sequence Of] . . . . . . . [General string] "hftsai" . . . . . . . [General string] "extra" . . . . . [tkt-enc-part] [Sequence/Sequence Of] . . . . . . [etype] [Integer] 0 . . . . . . [kvno] [Integer] 5 . . . . . . [cipher] [Octet String] "krbASN.1 test message" . . . [Krb5 Ticket] . . . . [Sequence/Sequence Of] . . . . . [tkt-vno] [Integer] 5 . . . . . [realm] [General string] "ATHENA.MIT.EDU" . . . . . [sname] [Sequence/Sequence Of] . . . . . . [name-type] [Integer] 1 . . . . . . [name-string] [Sequence/Sequence Of] . . . . . . . [General string] "hftsai" . . . . . . . [General string] "extra" . . . . . [tkt-enc-part] [Sequence/Sequence Of] . . . . . . [etype] [Integer] 0 . . . . . . [kvno] [Integer] 5 . . . . . . [cipher] [Octet String] "krbASN.1 test message" . . [enc-part] [Sequence/Sequence Of] . . . [etype] [Integer] 0 . . . [kvno] [Integer] 5 . . . [cipher] [Octet String] "krbASN.1 test message" encode_krb5_enc_cred_part: [Krb5 Encrypted CRED part] . [Sequence/Sequence Of] . . [ticket-info] [Sequence/Sequence Of] . . . [Sequence/Sequence Of] . . . . [key] [Sequence/Sequence Of] . . . . . [keytype] [Integer] 1 . . . . . [keyvalue] [Octet String] "12345678" . . . . [prealm] [General string] "ATHENA.MIT.EDU" . . . . [pname] [Sequence/Sequence Of] . . . . . [name-type] [Integer] 1 . . . . . [name-string] [Sequence/Sequence Of] . . . . . . [General string] "hftsai" . . . . . . [General string] "extra" . . . . [flags] [Bit String] 0xfedcba98 . . . . [authtime] [Generalized Time] "19940610060317Z" . . . . [startime] [Generalized Time] "19940610060317Z" . . . . [endtime] [Generalized Time] "19940610060317Z" . . . . [renew-till] [Generalized Time] "19940610060317Z" . . . . [srealm] [General string] "ATHENA.MIT.EDU" . . . . [sname] [Sequence/Sequence Of] . . . . . [name-type] [Integer] 1 . . . . . [name-string] [Sequence/Sequence Of] . . . . . . [General string] "hftsai" . . . . . . [General string] "extra" . . . . [caddr] [Sequence/Sequence Of] . . . . . [Sequence/Sequence Of] . . . . . . [addr-type] [Integer] 2 . . . . . . [address] [Octet String] <4> 12 d0 00 23 ...# . . . . . [Sequence/Sequence Of] . . . . . . [addr-type] [Integer] 2 . . . . . . [address] [Octet String] <4> 12 d0 00 23 ...# . . . [Sequence/Sequence Of] . . . . [key] [Sequence/Sequence Of] . . . . . [keytype] [Integer] 1 . . . . . [keyvalue] [Octet String] "12345678" . . . . [prealm] [General string] "ATHENA.MIT.EDU" . . . . [pname] [Sequence/Sequence Of] . . . . . [name-type] [Integer] 1 . . . . . [name-string] [Sequence/Sequence Of] . . . . . . [General string] "hftsai" . . . . . . [General string] "extra" . . . . [flags] [Bit String] 0xfedcba98 . . . . [authtime] [Generalized Time] "19940610060317Z" . . . . [startime] [Generalized Time] "19940610060317Z" . . . . [endtime] [Generalized Time] "19940610060317Z" . . . . [renew-till] [Generalized Time] "19940610060317Z" . . . . [srealm] [General string] "ATHENA.MIT.EDU" . . . . [sname] [Sequence/Sequence Of] . . . . . [name-type] [Integer] 1 . . . . . [name-string] [Sequence/Sequence Of] . . . . . . [General string] "hftsai" . . . . . . [General string] "extra" . . . . [caddr] [Sequence/Sequence Of] . . . . . [Sequence/Sequence Of] . . . . . . [addr-type] [Integer] 2 . . . . . . [address] [Octet String] <4> 12 d0 00 23 ...# . . . . . [Sequence/Sequence Of] . . . . . . [addr-type] [Integer] 2 . . . . . . [address] [Octet String] <4> 12 d0 00 23 ...# . . [nonce] [Integer] 42 . . [timestamp] [Generalized Time] "19940610060317Z" . . [usec] [Integer] 123456 . . [s-address] [Sequence/Sequence Of] . . . [addr-type] [Integer] 2 . . . [address] [Octet String] <4> 12 d0 00 23 ...# . . [r-address] [Sequence/Sequence Of] . . . [addr-type] [Integer] 2 . . . [address] [Octet String] <4> 12 d0 00 23 ...# encode_krb5_enc_cred_part(optionals NULL): [Krb5 Encrypted CRED part] . [Sequence/Sequence Of] . . [ticket-info] [Sequence/Sequence Of] . . . [Sequence/Sequence Of] . . . . [key] [Sequence/Sequence Of] . . . . . [keytype] [Integer] 1 . . . . . [keyvalue] [Octet String] "12345678" . . . [Sequence/Sequence Of] . . . . [key] [Sequence/Sequence Of] . . . . . [keytype] [Integer] 1 . . . . . [keyvalue] [Octet String] "12345678" . . . . [prealm] [General string] "ATHENA.MIT.EDU" . . . . [pname] [Sequence/Sequence Of] . . . . . [name-type] [Integer] 1 . . . . . [name-string] [Sequence/Sequence Of] . . . . . . [General string] "hftsai" . . . . . . [General string] "extra" . . . . [flags] [Bit String] 0xfedcba98 . . . . [authtime] [Generalized Time] "19940610060317Z" . . . . [startime] [Generalized Time] "19940610060317Z" . . . . [endtime] [Generalized Time] "19940610060317Z" . . . . [renew-till] [Generalized Time] "19940610060317Z" . . . . [srealm] [General string] "ATHENA.MIT.EDU" . . . . [sname] [Sequence/Sequence Of] . . . . . [name-type] [Integer] 1 . . . . . [name-string] [Sequence/Sequence Of] . . . . . . [General string] "hftsai" . . . . . . [General string] "extra" . . . . [caddr] [Sequence/Sequence Of] . . . . . [Sequence/Sequence Of] . . . . . . [addr-type] [Integer] 2 . . . . . . [address] [Octet String] <4> 12 d0 00 23 ...# . . . . . [Sequence/Sequence Of] . . . . . . [addr-type] [Integer] 2 . . . . . . [address] [Octet String] <4> 12 d0 00 23 ...# encode_krb5_error: [Krb5 ERROR packet] . [Sequence/Sequence Of] . . [pvno] [Integer] 5 . . [msg-type] [Integer] 30 . . [ctime] [Generalized Time] "19940610060317Z" . . [cusec] [Integer] 123456 . . [stime] [Generalized Time] "19940610060317Z" . . [susec] [Integer] 123456 . . [error-code] [Integer] 60 . . [crealm] [General string] "ATHENA.MIT.EDU" . . [cname] [Sequence/Sequence Of] . . . [name-type] [Integer] 1 . . . [name-string] [Sequence/Sequence Of] . . . . [General string] "hftsai" . . . . [General string] "extra" . . [realm] [General string] "ATHENA.MIT.EDU" . . [sname] [Sequence/Sequence Of] . . . [name-type] [Integer] 1 . . . [name-string] [Sequence/Sequence Of] . . . . [General string] "hftsai" . . . . [General string] "extra" . . [e-text] [General string] "krb5data" . . [e-data] [Octet String] "krb5data" encode_krb5_error(optionals NULL): [Krb5 ERROR packet] . [Sequence/Sequence Of] . . [pvno] [Integer] 5 . . [msg-type] [Integer] 30 . . [cusec] [Integer] 123456 . . [stime] [Generalized Time] "19940610060317Z" . . [susec] [Integer] 123456 . . [error-code] [Integer] 60 . . [realm] [General string] "ATHENA.MIT.EDU" . . [sname] [Sequence/Sequence Of] . . . [name-type] [Integer] 1 . . . [name-string] [Sequence/Sequence Of] . . . . [General string] "hftsai" . . . . [General string] "extra" encode_krb5_authorization_data: [Sequence/Sequence Of] . [Sequence/Sequence Of] . . [ad-type] [Integer] 1 . . [ad-data] [Octet String] "foobar" . [Sequence/Sequence Of] . . [ad-type] [Integer] 1 . . [ad-data] [Octet String] "foobar" encode_krb5_padata_sequence: [Sequence/Sequence Of] . [Sequence/Sequence Of] . . [1] [Integer] 13 . . [2] [Octet String] "pa-data" . [Sequence/Sequence Of] . . [1] [Integer] 13 . . [2] [Octet String] "pa-data" encode_krb5_typed_data: [Sequence/Sequence Of] . [Sequence/Sequence Of] . . [0] [Integer] 13 . . [1] [Octet String] "pa-data" . [Sequence/Sequence Of] . . [0] [Integer] 13 . . [1] [Octet String] "pa-data" encode_krb5_padata_sequence(empty): [Sequence/Sequence Of] encode_krb5_etype_info: [Sequence/Sequence Of] . [Sequence/Sequence Of] . . [0] [Integer] 0 . . [1] [Octet String] "Morton's #0" . [Sequence/Sequence Of] . . [0] [Integer] 1 . [Sequence/Sequence Of] . . [0] [Integer] 2 . . [1] [Octet String] "Morton's #2" encode_krb5_etype_info(only 1): [Sequence/Sequence Of] . [Sequence/Sequence Of] . . [0] [Integer] 0 . . [1] [Octet String] "Morton's #0" encode_krb5_etype_info(no info): [Sequence/Sequence Of] encode_krb5_etype_info2: [Sequence/Sequence Of] . [Sequence/Sequence Of] . . [0] [Integer] 0 . . [1] [General string] "Morton's #0" . . [2] [Octet String] "s2k: 0" . [Sequence/Sequence Of] . . [0] [Integer] 1 . . [2] [Octet String] "s2k: 1" . [Sequence/Sequence Of] . . [0] [Integer] 2 . . [1] [General string] "Morton's #2" . . [2] [Octet String] "s2k: 2" encode_krb5_etype_info2(only 1): [Sequence/Sequence Of] . [Sequence/Sequence Of] . . [0] [Integer] 0 . . [1] [General string] "Morton's #0" . . [2] [Octet String] "s2k: 0" encode_krb5_pa_enc_ts: [Sequence/Sequence Of] . [0] [Generalized Time] "19940610060317Z" . [1] [Integer] 123456 encode_krb5_pa_enc_ts (no usec): [Sequence/Sequence Of] . [0] [Generalized Time] "19940610060317Z" encode_krb5_enc_data: [Sequence/Sequence Of] . [etype] [Integer] 0 . [kvno] [Integer] 5 . [cipher] [Octet String] "krbASN.1 test message" encode_krb5_enc_data(MSB-set kvno): [Sequence/Sequence Of] . [etype] [Integer] 0 . [kvno] [Integer] -16777216 . [cipher] [Octet String] "krbASN.1 test message" encode_krb5_enc_data(kvno=-1): [Sequence/Sequence Of] . [etype] [Integer] 0 . [kvno] [Integer] -1 . [cipher] [Octet String] "krbASN.1 test message" encode_krb5_sam_challenge_2: [Sequence/Sequence Of] . [0] [Sequence/Sequence Of] . . [Octet String] "challenge" . [1] [Sequence/Sequence Of] . . [Sequence/Sequence Of] . . . [0] [Integer] 1 . . . [1] [Octet String] "1234" encode_krb5_sam_challenge_2_body: [Sequence/Sequence Of] . [0] [Integer] 42 . [1] [Bit String] 0x80000000 . [2] [Octet String] "type name" . [4] [Octet String] "challenge label" . [5] [Octet String] "challenge ipse" . [6] [Octet String] "response_prompt ipse" . [8] [Integer] 5517840 . [9] [Integer] 1 encode_krb5_sam_response_2: [Sequence/Sequence Of] . [0] [Integer] 43 . [1] [Bit String] 0x80000000 . [2] [Octet String] "track data" . [3] [Sequence/Sequence Of] . . [0] [Integer] 1 . . [1] [Integer] 3382 . . [2] [Octet String] "nonce or sad" . [4] [Integer] 5517840 encode_krb5_enc_sam_response_enc_2: [Sequence/Sequence Of] . [0] [Integer] 88 . [1] [Octet String] "enc_sam_response_enc_2" encode_krb5_pa_for_user: [Sequence/Sequence Of] . [0] [Sequence/Sequence Of] . . [0] [Integer] 1 . . [1] [Sequence/Sequence Of] . . . [General string] "hftsai" . . . [General string] "extra" . [1] [General string] "ATHENA.MIT.EDU" . [2] [Sequence/Sequence Of] . . [0] [Integer] 1 . . [1] [Octet String] "1234" . [3] [General string] "krb5data" encode_krb5_pa_s4u_x509_user: [Sequence/Sequence Of] . [0] [Sequence/Sequence Of] . . [0] [Integer] 13243546 . . [1] [Sequence/Sequence Of] . . . [0] [Integer] 1 . . . [1] [Sequence/Sequence Of] . . . . [General string] "hftsai" . . . . [General string] "extra" . . [2] [General string] "ATHENA.MIT.EDU" . . [3] [Octet String] "pa_s4u_x509_user" . . [4] [Bit String] 0x80000000 . [1] [Sequence/Sequence Of] . . [0] [Integer] 1 . . [1] [Octet String] "1234" encode_krb5_ad_kdcissued: [Sequence/Sequence Of] . [0] [Sequence/Sequence Of] . . [0] [Integer] 1 . . [1] [Octet String] "1234" . [1] [General string] "ATHENA.MIT.EDU" . [2] [Sequence/Sequence Of] . . [0] [Integer] 1 . . [1] [Sequence/Sequence Of] . . . [General string] "hftsai" . . . [General string] "extra" . [3] [Sequence/Sequence Of] . . [Sequence/Sequence Of] . . . [0] [Integer] 1 . . . [1] [Octet String] "foobar" . . [Sequence/Sequence Of] . . . [0] [Integer] 1 . . . [1] [Octet String] "foobar" encode_krb5_ad_signedpath_data: [Sequence/Sequence Of] . [0] [Sequence/Sequence Of] . . [0] [Sequence/Sequence Of] . . . [0] [Integer] 1 . . . [1] [Sequence/Sequence Of] . . . . [General string] "hftsai" . . . . [General string] "extra" . . [1] [General string] "ATHENA.MIT.EDU" . [1] [Generalized Time] "19940610060317Z" . [2] [Sequence/Sequence Of] . . [Sequence/Sequence Of] . . . [0] [Sequence/Sequence Of] . . . . [0] [Integer] 1 . . . . [1] [Sequence/Sequence Of] . . . . . [General string] "hftsai" . . . . . [General string] "extra" . . . [1] [General string] "ATHENA.MIT.EDU" . [3] [Sequence/Sequence Of] . . [Sequence/Sequence Of] . . . [1] [Integer] 13 . . . [2] [Octet String] "pa-data" . . [Sequence/Sequence Of] . . . [1] [Integer] 13 . . . [2] [Octet String] "pa-data" . [4] [Sequence/Sequence Of] . . [Sequence/Sequence Of] . . . [0] [Integer] 1 . . . [1] [Octet String] "foobar" . . [Sequence/Sequence Of] . . . [0] [Integer] 1 . . . [1] [Octet String] "foobar" encode_krb5_ad_signedpath: [Sequence/Sequence Of] . [0] [Integer] 1 . [1] [Sequence/Sequence Of] . . [0] [Integer] 1 . . [1] [Octet String] "1234" . [3] [Sequence/Sequence Of] . . [Sequence/Sequence Of] . . . [1] [Integer] 13 . . . [2] [Octet String] "pa-data" . . [Sequence/Sequence Of] . . . [1] [Integer] 13 . . . [2] [Octet String] "pa-data" encode_krb5_iakerb_header: [Sequence/Sequence Of] . [1] [Octet String] "krb5data" . [2] [Octet String] "krb5data" encode_krb5_iakerb_finished: [Sequence/Sequence Of] . [1] [Sequence/Sequence Of] . . [0] [Integer] 1 . . [1] [Octet String] "1234" encode_krb5_fast_response: [Sequence/Sequence Of] . [0] [Sequence/Sequence Of] . . [Sequence/Sequence Of] . . . [1] [Integer] 13 . . . [2] [Octet String] "pa-data" . . [Sequence/Sequence Of] . . . [1] [Integer] 13 . . . [2] [Octet String] "pa-data" . [1] [Sequence/Sequence Of] . . [0] [Integer] 1 . . [1] [Octet String] "12345678" . [2] [Sequence/Sequence Of] . . [0] [Generalized Time] "19940610060317Z" . . [1] [Integer] 123456 . . [2] [General string] "ATHENA.MIT.EDU" . . [3] [Sequence/Sequence Of] . . . [0] [Integer] 1 . . . [1] [Sequence/Sequence Of] . . . . [General string] "hftsai" . . . . [General string] "extra" . . [4] [Sequence/Sequence Of] . . . [0] [Integer] 1 . . . [1] [Octet String] "1234" . [3] [Integer] 42 encode_krb5_pa_fx_fast_reply: [CONT 0] . [Sequence/Sequence Of] . . [0] [Sequence/Sequence Of] . . . [0] [Integer] 0 . . . [1] [Integer] 5 . . . [2] [Octet String] "krbASN.1 test message" encode_krb5_otp_tokeninfo(optionals NULL): [Sequence/Sequence Of] . [0] <5> 00 00 00 00 00 ..... encode_krb5_otp_tokeninfo: [Sequence/Sequence Of] . [0] <5> 00 77 00 00 00 .w... . [1] <11> 45 78 61 6d 70 6c 65 63 6f 72 70 Examplecorp . [2] <5> 68 61 72 6b 21 hark! . [3] 0x0 (10 unused bits) . [4] <1> 02 . . [5] <9> 79 6f 75 72 74 6f 6b 65 6e yourtoken . [6] <40> 75 72 6e 3a 69 65 74 66 3a 70 61 72 61 6d 73 3a urn:ietf:params: 78 6d 6c 3a 6e 73 3a 6b 65 79 70 72 6f 76 3a 70 xml:ns:keyprov:p 73 6b 63 3a 68 6f 74 70 skc:hotp . [7] [Sequence/Sequence Of] . . [Object Identifier] <9> 60 86 48 01 65 03 04 02 01 `.H.e.... . [Sequence/Sequence Of] . . [Object Identifier] <5> 2b 0e 03 02 1a +.... . [8] <2> 03 e8 .. encode_krb5_pa_otp_challenge(optionals NULL): [Sequence/Sequence Of] . [0] <8> 6d 69 6e 6e 6f 6e 63 65 minnonce . [2] [Sequence/Sequence Of] . . [0] <5> 00 00 00 00 00 ..... encode_krb5_pa_otp_challenge: [Sequence/Sequence Of] . [0] <8> 6d 61 78 6e 6f 6e 63 65 maxnonce . [1] <11> 74 65 73 74 73 65 72 76 69 63 65 testservice . [2] [Sequence/Sequence Of] . . [0] <5> 00 00 00 00 00 ..... . [Sequence/Sequence Of] . . [0] <5> 00 77 00 00 00 .w... . . [1] <11> 45 78 61 6d 70 6c 65 63 6f 72 70 Examplecorp . . [2] <5> 68 61 72 6b 21 hark! . . [3] 0x0 (10 unused bits) . . [4] <1> 02 . . . [5] <9> 79 6f 75 72 74 6f 6b 65 6e yourtoken . . [6] <40> 75 72 6e 3a 69 65 74 66 3a 70 61 72 61 6d 73 urn:ietf:params 3a 78 6d 6c 3a 6e 73 3a 6b 65 79 70 72 6f 76 :xml:ns:keyprov 3a 70 73 6b 63 3a 68 6f 74 70 :pskc:hotp . . [7] [Sequence/Sequence Of] . . . [Object Identifier] <9> 60 86 48 01 65 03 04 02 01 `.H.e.... . . [Sequence/Sequence Of] . . . [Object Identifier] <5> 2b 0e 03 02 1a +.... . . [8] <2> 03 e8 .. . [3] <7> 6b 65 79 73 61 6c 74 keysalt . [4] "1234" encode_krb5_pa_otp_req(optionals NULL): [Sequence/Sequence Of] . [0] <5> 00 00 00 00 00 ..... . [2] [0] [Integer] 0 . [1] [Integer] 5 . [2] [Octet String] "krbASN.1 test message" encode_krb5_pa_otp_req: [Sequence/Sequence Of] . [0] <5> 00 60 00 00 00 .`... . [1] <5> 6e 6f 6e 63 65 nonce . [2] [0] [Integer] 0 . [1] [Integer] 5 . [2] [Octet String] "krbASN.1 test message" . [3] [Object Identifier] <9> 60 86 48 01 65 03 04 02 01 `.H.e.... . [4] <2> 03 e8 .. . [5] <5> 66 72 6f 67 73 frogs . [6] <10> 6d 79 66 69 72 73 74 70 69 6e myfirstpin . [7] <5> 68 61 72 6b 21 hark! . [8] <15> 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5a 19940610060317Z . [9] <3> 33 34 36 346 . [10] <1> 02 . . [11] <9> 79 6f 75 72 74 6f 6b 65 6e yourtoken . [12] <40> 75 72 6e 3a 69 65 74 66 3a 70 61 72 61 6d 73 3a urn:ietf:params: 78 6d 6c 3a 6e 73 3a 6b 65 79 70 72 6f 76 3a 70 xml:ns:keyprov:p 73 6b 63 3a 68 6f 74 70 skc:hotp . [13] <11> 45 78 61 6d 70 6c 65 63 6f 72 70 Examplecorp encode_krb5_pa_otp_enc_req: [Sequence/Sequence Of] . [0] <8> 6b 72 62 35 64 61 74 61 krb5data encode_krb5_kkdcp_message: [Sequence/Sequence Of] . [0] [Octet String] <488> 6a 82 01 e4 30 82 01 e0 a1 03 02 01 05 a2 03 02 j...0........... 01 0a a3 26 30 24 30 10 a1 03 02 01 0d a2 09 04 ...&0$0......... 07 70 61 2d 64 61 74 61 30 10 a1 03 02 01 0d a2 .pa-data0....... 09 04 07 70 61 2d 64 61 74 61 a4 82 01 aa 30 82 ...pa-data....0. 01 a6 a0 07 03 05 00 fe dc ba 98 a1 1a 30 18 a0 .............0.. 03 02 01 01 a1 11 30 0f 1b 06 68 66 74 73 61 69 ......0...hftsai 1b 05 65 78 74 72 61 a2 10 1b 0e 41 54 48 45 4e ..extra....ATHEN 41 2e 4d 49 54 2e 45 44 55 a3 1a 30 18 a0 03 02 A.MIT.EDU..0.... 01 01 a1 11 30 0f 1b 06 68 66 74 73 61 69 1b 05 ....0...hftsai.. 65 78 74 72 61 a4 11 18 0f 31 39 39 34 30 36 31 extra....1994061 30 30 36 30 33 31 37 5a a5 11 18 0f 31 39 39 34 0060317Z....1994 30 36 31 30 30 36 30 33 31 37 5a a6 11 18 0f 31 0610060317Z....1 39 39 34 30 36 31 30 30 36 30 33 31 37 5a a7 03 9940610060317Z.. 02 01 2a a8 08 30 06 02 01 00 02 01 01 a9 20 30 ..*..0........ 0 1e 30 0d a0 03 02 01 02 a1 06 04 04 12 d0 00 23 .0.............# 30 0d a0 03 02 01 02 a1 06 04 04 12 d0 00 23 aa 0.............#. 25 30 23 a0 03 02 01 00 a1 03 02 01 05 a2 17 04 %0#............. 15 6b 72 62 41 53 4e 2e 31 20 74 65 73 74 20 6d .krbASN.1 test m 65 73 73 61 67 65 ab 81 bf 30 81 bc 61 5c 30 5a essage...0..a\0Z a0 03 02 01 05 a1 10 1b 0e 41 54 48 45 4e 41 2e .........ATHENA. 4d 49 54 2e 45 44 55 a2 1a 30 18 a0 03 02 01 01 MIT.EDU..0...... a1 11 30 0f 1b 06 68 66 74 73 61 69 1b 05 65 78 ..0...hftsai..ex 74 72 61 a3 25 30 23 a0 03 02 01 00 a1 03 02 01 tra.%0#......... 05 a2 17 04 15 6b 72 62 41 53 4e 2e 31 20 74 65 .....krbASN.1 te 73 74 20 6d 65 73 73 61 67 65 61 5c 30 5a a0 03 st messagea\0Z.. 02 01 05 a1 10 1b 0e 41 54 48 45 4e 41 2e 4d 49 .......ATHENA.MI 54 2e 45 44 55 a2 1a 30 18 a0 03 02 01 01 a1 11 T.EDU..0........ 30 0f 1b 06 68 66 74 73 61 69 1b 05 65 78 74 72 0...hftsai..extr 61 a3 25 30 23 a0 03 02 01 00 a1 03 02 01 05 a2 a.%0#........... 17 04 15 6b 72 62 41 53 4e 2e 31 20 74 65 73 74 ...krbASN.1 test 20 6d 65 73 73 61 67 65 message . [1] [General string] "krb5data" encode_krb5_cammac(optionals NULL): [Sequence/Sequence Of] . [0] [Sequence/Sequence Of] . . [Sequence/Sequence Of] . . . [0] [Integer] 1 . . . [1] [Octet String] "ad1" encode_krb5_cammac: [Sequence/Sequence Of] . [0] [Sequence/Sequence Of] . . [Sequence/Sequence Of] . . . [0] [Integer] 1 . . . [1] [Octet String] "ad1" . . [Sequence/Sequence Of] . . . [0] [Integer] 2 . . . [1] [Octet String] "ad2" . [1] [Sequence/Sequence Of] . . [0] [Sequence/Sequence Of] . . . [0] [Integer] 1 . . . [1] [Sequence/Sequence Of] . . . . [General string] "hftsai" . . . . [General string] "extra" . . [1] [Integer] 5 . . [2] [Integer] 16 . . [3] [Sequence/Sequence Of] . . . [0] [Integer] 1 . . . [1] [Octet String] "cksumkdc" . [2] [Sequence/Sequence Of] . . [0] [Sequence/Sequence Of] . . . [0] [Integer] 1 . . . [1] [Sequence/Sequence Of] . . . . [General string] "hftsai" . . . . [General string] "extra" . . [1] [Integer] 5 . . [2] [Integer] 16 . . [3] [Sequence/Sequence Of] . . . [0] [Integer] 1 . . . [1] [Octet String] "cksumsvc" . [3] [Sequence/Sequence Of] . . [Sequence/Sequence Of] . . . [3] [Sequence/Sequence Of] . . . . [0] [Integer] 1 . . . . [1] [Octet String] "cksum1" . . [Sequence/Sequence Of] . . . [0] [Sequence/Sequence Of] . . . . [0] [Integer] 1 . . . . [1] [Sequence/Sequence Of] . . . . . [General string] "hftsai" . . . . . [General string] "extra" . . . [1] [Integer] 5 . . . [2] [Integer] 16 . . . [3] [Sequence/Sequence Of] . . . . [0] [Integer] 1 . . . . [1] [Octet String] "cksum2" encode_krb5_secure_cookie: [Sequence/Sequence Of] . [Integer] 771228197 . [Sequence/Sequence Of] . . [Sequence/Sequence Of] . . . [1] [Integer] 13 . . . [2] [Octet String] "pa-data" . . [Sequence/Sequence Of] . . . [1] [Integer] 13 . . . [2] [Octet String] "pa-data" krb5-1.16/src/tests/asn.1/ktest_equal.c0000644000704600001450000010060413211554426017535 0ustar ghudsonlibuuid/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* tests/asn.1/ktest_equal.c */ /* * Copyright (C) 1994 by the Massachusetts Institute of Technology. * All rights reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #include #include #include "ktest_equal.h" #define FALSE 0 #define TRUE 1 #define struct_equal(field,comparator) \ comparator(&(ref->field),&(var->field)) #define ptr_equal(field,comparator) \ comparator(ref->field,var->field) #define scalar_equal(field) \ ((ref->field) == (var->field)) #define len_equal(length,field,comparator) \ ((ref->length == var->length) && \ comparator(ref->length,ref->field,var->field)) int ktest_equal_authenticator(krb5_authenticator *ref, krb5_authenticator *var) { int p = TRUE; if (ref == var) return TRUE; else if (ref == NULL || var == NULL) return FALSE; p = p && ptr_equal(client,ktest_equal_principal_data); p = p && ptr_equal(checksum,ktest_equal_checksum); p = p && scalar_equal(cusec); p = p && scalar_equal(ctime); p = p && ptr_equal(subkey,ktest_equal_keyblock); p = p && scalar_equal(seq_number); p = p && ptr_equal(authorization_data,ktest_equal_authorization_data); return p; } int ktest_equal_principal_data(krb5_principal_data *ref, krb5_principal_data *var) { if (ref == var) return TRUE; else if (ref == NULL || var == NULL) return FALSE; return(struct_equal(realm,ktest_equal_data) && len_equal(length,data,ktest_equal_array_of_data) && scalar_equal(type)); } int ktest_equal_authdata(krb5_authdata *ref, krb5_authdata *var) { if (ref == var) return TRUE; else if (ref == NULL || var == NULL) return FALSE; return(scalar_equal(ad_type) && len_equal(length,contents,ktest_equal_array_of_octet)); } int ktest_equal_checksum(krb5_checksum *ref, krb5_checksum *var) { if (ref == var) return TRUE; else if (ref == NULL || var == NULL) return FALSE; return(scalar_equal(checksum_type) && len_equal(length,contents,ktest_equal_array_of_octet)); } int ktest_equal_keyblock(krb5_keyblock *ref, krb5_keyblock *var) { if (ref == var) return TRUE; else if (ref == NULL || var == NULL) return FALSE; return(scalar_equal(enctype) && len_equal(length,contents,ktest_equal_array_of_octet)); } int ktest_equal_data(krb5_data *ref, krb5_data *var) { if (ref == var) return TRUE; else if (ref == NULL || var == NULL) return FALSE; return(len_equal(length,data,ktest_equal_array_of_char)); } int ktest_equal_ticket(krb5_ticket *ref, krb5_ticket *var) { int p = TRUE; if (ref == var) return TRUE; else if (ref == NULL || var == NULL) return FALSE; p = p && ptr_equal(server,ktest_equal_principal_data); p = p && struct_equal(enc_part,ktest_equal_enc_data); /* enc_part2 is irrelevant, as far as the ASN.1 code is concerned */ return p; } int ktest_equal_enc_data(krb5_enc_data *ref, krb5_enc_data *var) { int p = TRUE; if (ref == var) return TRUE; else if (ref == NULL || var == NULL) return FALSE; p = p && scalar_equal(enctype); p = p && scalar_equal(kvno); p = p && struct_equal(ciphertext,ktest_equal_data); return p; } int ktest_equal_encryption_key(krb5_keyblock *ref, krb5_keyblock *var) { int p = TRUE; if (ref == var) return TRUE; else if (ref == NULL || var == NULL) return FALSE; p = p && scalar_equal(enctype); p = p && len_equal(length,contents,ktest_equal_array_of_octet); return p; } int ktest_equal_enc_tkt_part(krb5_enc_tkt_part *ref, krb5_enc_tkt_part *var) { int p = TRUE; if (ref == var) return TRUE; else if (ref == NULL || var == NULL) return FALSE; p = p && scalar_equal(flags); p = p && ptr_equal(session,ktest_equal_encryption_key); p = p && ptr_equal(client,ktest_equal_principal_data); p = p && struct_equal(transited,ktest_equal_transited); p = p && struct_equal(times,ktest_equal_ticket_times); p = p && ptr_equal(caddrs,ktest_equal_addresses); p = p && ptr_equal(authorization_data,ktest_equal_authorization_data); return p; } int ktest_equal_transited(krb5_transited *ref, krb5_transited *var) { int p = TRUE; if (ref == var) return TRUE; else if (ref == NULL || var == NULL) return FALSE; p = p && scalar_equal(tr_type); p = p && struct_equal(tr_contents,ktest_equal_data); return p; } int ktest_equal_ticket_times(krb5_ticket_times *ref, krb5_ticket_times *var) { int p = TRUE; if (ref == var) return TRUE; else if (ref == NULL || var == NULL) return FALSE; p = p && scalar_equal(authtime); p = p && scalar_equal(starttime); p = p && scalar_equal(endtime); p = p && scalar_equal(renew_till); return p; } int ktest_equal_address(krb5_address *ref, krb5_address *var) { int p = TRUE; if (ref == var) return TRUE; else if (ref == NULL || var == NULL) return FALSE; p = p && scalar_equal(addrtype); p = p && len_equal(length,contents,ktest_equal_array_of_octet); return p; } int ktest_equal_enc_kdc_rep_part(krb5_enc_kdc_rep_part *ref, krb5_enc_kdc_rep_part *var) { int p = TRUE; if (ref == var) return TRUE; else if (ref == NULL || var == NULL) return FALSE; p = p && ptr_equal(session,ktest_equal_keyblock); p = p && ptr_equal(last_req,ktest_equal_last_req); p = p && scalar_equal(nonce); p = p && scalar_equal(key_exp); p = p && scalar_equal(flags); p = p && struct_equal(times,ktest_equal_ticket_times); p = p && ptr_equal(server,ktest_equal_principal_data); p = p && ptr_equal(caddrs,ktest_equal_addresses); return p; } int ktest_equal_priv(krb5_priv *ref, krb5_priv *var) { int p = TRUE; if (ref == var) return TRUE; else if (ref == NULL || var == NULL) return FALSE; p = p && struct_equal(enc_part,ktest_equal_enc_data); return p; } int ktest_equal_cred(krb5_cred *ref, krb5_cred *var) { int p = TRUE; if (ref == var) return TRUE; else if (ref == NULL || var == NULL) return FALSE; p = p && ptr_equal(tickets,ktest_equal_sequence_of_ticket); p = p && struct_equal(enc_part,ktest_equal_enc_data); return p; } int ktest_equal_error(krb5_error *ref, krb5_error *var) { int p = TRUE; if (ref == var) return TRUE; else if (ref == NULL || var == NULL) return FALSE; p = p && scalar_equal(ctime); p = p && scalar_equal(cusec); p = p && scalar_equal(susec); p = p && scalar_equal(stime); p = p && scalar_equal(error); p = p && ptr_equal(client,ktest_equal_principal_data); p = p && ptr_equal(server,ktest_equal_principal_data); p = p && struct_equal(text,ktest_equal_data); p = p && struct_equal(e_data,ktest_equal_data); return p; } int ktest_equal_ap_req(krb5_ap_req *ref, krb5_ap_req *var) { int p = TRUE; if (ref == var) return TRUE; else if (ref == NULL || var == NULL) return FALSE; p = p && scalar_equal(ap_options); p = p && ptr_equal(ticket,ktest_equal_ticket); p = p && struct_equal(authenticator,ktest_equal_enc_data); return p; } int ktest_equal_ap_rep(krb5_ap_rep *ref, krb5_ap_rep *var) { int p = TRUE; if (ref == var) return TRUE; else if (ref == NULL || var == NULL) return FALSE; p = p && struct_equal(enc_part,ktest_equal_enc_data); return p; } int ktest_equal_ap_rep_enc_part(krb5_ap_rep_enc_part *ref, krb5_ap_rep_enc_part *var) { int p = TRUE; if (ref == var) return TRUE; else if (ref == NULL || var == NULL) return FALSE; p = p && scalar_equal(ctime); p = p && scalar_equal(cusec); p = p && ptr_equal(subkey,ktest_equal_encryption_key); p = p && scalar_equal(seq_number); return p; } int ktest_equal_safe(krb5_safe *ref, krb5_safe *var) { int p = TRUE; if (ref == var) return TRUE; else if (ref == NULL || var == NULL) return FALSE; p = p && struct_equal(user_data,ktest_equal_data); p = p && scalar_equal(timestamp); p = p && scalar_equal(usec); p = p && scalar_equal(seq_number); p = p && ptr_equal(s_address,ktest_equal_address); p = p && ptr_equal(r_address,ktest_equal_address); p = p && ptr_equal(checksum,ktest_equal_checksum); return p; } int ktest_equal_enc_cred_part(krb5_cred_enc_part *ref, krb5_cred_enc_part *var) { int p = TRUE; if (ref == var) return TRUE; else if (ref == NULL || var == NULL) return FALSE; p = p && scalar_equal(nonce); p = p && scalar_equal(timestamp); p = p && scalar_equal(usec); p = p && ptr_equal(s_address,ktest_equal_address); p = p && ptr_equal(r_address,ktest_equal_address); p = p && ptr_equal(ticket_info,ktest_equal_sequence_of_cred_info); return p; } int ktest_equal_enc_priv_part(krb5_priv_enc_part *ref, krb5_priv_enc_part *var) { int p = TRUE; if (ref == var) return TRUE; else if (ref == NULL || var == NULL) return FALSE; p = p && struct_equal(user_data,ktest_equal_data); p = p && scalar_equal(timestamp); p = p && scalar_equal(usec); p = p && scalar_equal(seq_number); p = p && ptr_equal(s_address,ktest_equal_address); p = p && ptr_equal(r_address,ktest_equal_address); return p; } int ktest_equal_as_rep(krb5_kdc_rep *ref, krb5_kdc_rep *var) { int p = TRUE; if (ref == var) return TRUE; else if (ref == NULL || var == NULL) return FALSE; p = p && scalar_equal(msg_type); p = p && ptr_equal(padata,ktest_equal_sequence_of_pa_data); p = p && ptr_equal(client,ktest_equal_principal_data); p = p && ptr_equal(ticket,ktest_equal_ticket); p = p && struct_equal(enc_part,ktest_equal_enc_data); p = p && ptr_equal(enc_part2,ktest_equal_enc_kdc_rep_part); return p; } int ktest_equal_tgs_rep(krb5_kdc_rep *ref, krb5_kdc_rep *var) { return ktest_equal_as_rep(ref,var); } int ktest_equal_as_req(krb5_kdc_req *ref, krb5_kdc_req *var) { int p = TRUE; if (ref == var) return TRUE; else if (ref == NULL || var == NULL) return FALSE; p = p && scalar_equal(msg_type); p = p && ptr_equal(padata,ktest_equal_sequence_of_pa_data); p = p && scalar_equal(kdc_options); p = p && ptr_equal(client,ktest_equal_principal_data); p = p && ptr_equal(server,ktest_equal_principal_data); p = p && scalar_equal(from); p = p && scalar_equal(till); p = p && scalar_equal(rtime); p = p && scalar_equal(nonce); p = p && len_equal(nktypes,ktype,ktest_equal_array_of_enctype); p = p && ptr_equal(addresses,ktest_equal_addresses); p = p && struct_equal(authorization_data,ktest_equal_enc_data); /* This field isn't actually in the ASN.1 encoding. */ /* p = p && ptr_equal(unenc_authdata,ktest_equal_authorization_data); */ return p; } int ktest_equal_tgs_req(krb5_kdc_req *ref, krb5_kdc_req *var) { return ktest_equal_as_req(ref,var); } int ktest_equal_kdc_req_body(krb5_kdc_req *ref, krb5_kdc_req *var) { int p = TRUE; if (ref == var) return TRUE; else if (ref == NULL || var == NULL) return FALSE; p = p && scalar_equal(kdc_options); p = p && ptr_equal(client,ktest_equal_principal_data); p = p && ptr_equal(server,ktest_equal_principal_data); p = p && scalar_equal(from); p = p && scalar_equal(till); p = p && scalar_equal(rtime); p = p && scalar_equal(nonce); p = p && len_equal(nktypes,ktype,ktest_equal_array_of_enctype); p = p && ptr_equal(addresses,ktest_equal_addresses); p = p && struct_equal(authorization_data,ktest_equal_enc_data); /* This isn't part of the ASN.1 encoding. */ /* p = p && ptr_equal(unenc_authdata,ktest_equal_authorization_data); */ return p; } int ktest_equal_last_req_entry(krb5_last_req_entry *ref, krb5_last_req_entry *var) { int p = TRUE; if (ref == var) return TRUE; else if (ref == NULL || var == NULL) return FALSE; p = p && scalar_equal(lr_type); p = p && scalar_equal(value); return p; } int ktest_equal_pa_data(krb5_pa_data *ref, krb5_pa_data *var) { int p = TRUE; if (ref == var) return TRUE; else if (ref == NULL || var == NULL) return FALSE; p = p && scalar_equal(pa_type); p = p && len_equal(length,contents,ktest_equal_array_of_octet); return p; } int ktest_equal_cred_info(krb5_cred_info *ref, krb5_cred_info *var) { int p = TRUE; if (ref == var) return TRUE; else if (ref == NULL || var == NULL) return FALSE; p = p && ptr_equal(session,ktest_equal_keyblock); p = p && ptr_equal(client,ktest_equal_principal_data); p = p && ptr_equal(server,ktest_equal_principal_data); p = p && scalar_equal(flags); p = p && struct_equal(times,ktest_equal_ticket_times); p = p && ptr_equal(caddrs,ktest_equal_addresses); return p; } int ktest_equal_krb5_etype_info_entry(krb5_etype_info_entry *ref, krb5_etype_info_entry *var) { if (ref->etype != var->etype) return FALSE; if (ref->length != var->length) return FALSE; if (ref->length > 0 && ref->length != KRB5_ETYPE_NO_SALT) if (memcmp(ref->salt, var->salt, ref->length) != 0) return FALSE; return TRUE; } int ktest_equal_krb5_pa_enc_ts(krb5_pa_enc_ts *ref, krb5_pa_enc_ts *var) { int p = TRUE; if (ref == var) return TRUE; else if (ref == NULL || var == NULL) return FALSE; p = p && scalar_equal(patimestamp); p = p && scalar_equal(pausec); return p; } #define equal_str(f) struct_equal(f,ktest_equal_data) int ktest_equal_sam_challenge_2_body(krb5_sam_challenge_2_body *ref, krb5_sam_challenge_2_body *var) { int p = TRUE; if (ref == var) return TRUE; else if (ref == NULL || var == NULL) return FALSE; p = p && scalar_equal(sam_type); p = p && scalar_equal(sam_flags); p = p && equal_str(sam_type_name); p = p && equal_str(sam_track_id); p = p && equal_str(sam_challenge_label); p = p && equal_str(sam_challenge); p = p && equal_str(sam_response_prompt); p = p && equal_str(sam_pk_for_sad); p = p && scalar_equal(sam_nonce); p = p && scalar_equal(sam_etype); return p; } int ktest_equal_sam_challenge_2(krb5_sam_challenge_2 *ref, krb5_sam_challenge_2 *var) { int p = TRUE; if (ref == var) return TRUE; else if (ref == NULL || var == NULL) return FALSE; p = p && equal_str(sam_challenge_2_body); p = p && ptr_equal(sam_cksum,ktest_equal_sequence_of_checksum); return p; } int ktest_equal_pa_for_user(krb5_pa_for_user *ref, krb5_pa_for_user *var) { int p = TRUE; if (ref == var) return TRUE; else if (ref == NULL || var == NULL) return FALSE; p = p && ptr_equal(user, ktest_equal_principal_data); p = p && struct_equal(cksum, ktest_equal_checksum); p = p && equal_str(auth_package); return p; } int ktest_equal_pa_s4u_x509_user(krb5_pa_s4u_x509_user *ref, krb5_pa_s4u_x509_user *var) { int p = TRUE; if (ref == var) return TRUE; else if (ref == NULL || var == NULL) return FALSE; p = p && scalar_equal(user_id.nonce); p = p && ptr_equal(user_id.user,ktest_equal_principal_data); p = p && struct_equal(user_id.subject_cert,ktest_equal_data); p = p && scalar_equal(user_id.options); p = p && struct_equal(cksum,ktest_equal_checksum); return p; } int ktest_equal_ad_kdcissued(krb5_ad_kdcissued *ref, krb5_ad_kdcissued *var) { int p = TRUE; if (ref == var) return TRUE; else if (ref == NULL || var == NULL) return FALSE; p = p && struct_equal(ad_checksum,ktest_equal_checksum); p = p && ptr_equal(i_principal,ktest_equal_principal_data); p = p && ptr_equal(elements,ktest_equal_authorization_data); return p; } int ktest_equal_ad_signedpath_data(krb5_ad_signedpath_data *ref, krb5_ad_signedpath_data *var) { int p = TRUE; if (ref == var) return TRUE; else if (ref == NULL || var == NULL) return FALSE; p = p && ptr_equal(client,ktest_equal_principal_data); p = p && scalar_equal(authtime); p = p && ptr_equal(delegated,ktest_equal_sequence_of_principal); p = p && ptr_equal(method_data,ktest_equal_sequence_of_pa_data); p = p && ptr_equal(authorization_data,ktest_equal_authorization_data); return p; } int ktest_equal_ad_signedpath(krb5_ad_signedpath *ref, krb5_ad_signedpath *var) { int p = TRUE; if (ref == var) return TRUE; else if (ref == NULL || var == NULL) return FALSE; p = p && scalar_equal(enctype); p = p && struct_equal(checksum,ktest_equal_checksum); p = p && ptr_equal(delegated,ktest_equal_sequence_of_principal); p = p && ptr_equal(method_data,ktest_equal_sequence_of_pa_data); return p; } int ktest_equal_iakerb_header(krb5_iakerb_header *ref, krb5_iakerb_header *var) { int p = TRUE; if (ref == var) return TRUE; else if (ref == NULL || var == NULL) return FALSE; p = p && struct_equal(target_realm,ktest_equal_data); p = p && ptr_equal(cookie,ktest_equal_data); return p; } int ktest_equal_iakerb_finished(krb5_iakerb_finished *ref, krb5_iakerb_finished *var) { int p = TRUE; if (ref == var) return TRUE; else if (ref == NULL || var == NULL) return FALSE; p = p && struct_equal(checksum,ktest_equal_checksum); return p; } static int ktest_equal_fast_finished(krb5_fast_finished *ref, krb5_fast_finished *var) { int p = TRUE; if (ref == var) return TRUE; else if (ref == NULL || var == NULL) return FALSE; p = p && scalar_equal(timestamp); p = p && scalar_equal(usec); p = p && ptr_equal(client, ktest_equal_principal_data); p = p && struct_equal(ticket_checksum, ktest_equal_checksum); return p; } int ktest_equal_fast_response(krb5_fast_response *ref, krb5_fast_response *var) { int p = TRUE; if (ref == var) return TRUE; else if (ref == NULL || var == NULL) return FALSE; p = p && ptr_equal(padata, ktest_equal_sequence_of_pa_data); p = p && ptr_equal(strengthen_key, ktest_equal_keyblock); p = p && ptr_equal(finished, ktest_equal_fast_finished); p = p && scalar_equal(nonce); return p; } static int ktest_equal_algorithm_identifier(krb5_algorithm_identifier *ref, krb5_algorithm_identifier *var) { int p = TRUE; if (ref == var) return TRUE; else if (ref == NULL || var == NULL) return FALSE; p = p && equal_str(algorithm); p = p && equal_str(parameters); return p; } int ktest_equal_otp_tokeninfo(krb5_otp_tokeninfo *ref, krb5_otp_tokeninfo *var) { int p = TRUE; if (ref == var) return TRUE; else if (ref == NULL || var == NULL) return FALSE; p = p && scalar_equal(flags); p = p && equal_str(vendor); p = p && equal_str(challenge); p = p && scalar_equal(length); p = p && scalar_equal(format); p = p && equal_str(token_id); p = p && equal_str(alg_id); p = p && ptr_equal(supported_hash_alg, ktest_equal_sequence_of_algorithm_identifier); p = p && scalar_equal(iteration_count); return p; } int ktest_equal_pa_otp_challenge(krb5_pa_otp_challenge *ref, krb5_pa_otp_challenge *var) { int p = TRUE; if (ref == var) return TRUE; else if (ref == NULL || var == NULL) return FALSE; p = p && equal_str(nonce); p = p && equal_str(service); p = p && ptr_equal(tokeninfo, ktest_equal_sequence_of_otp_tokeninfo); p = p && equal_str(salt); p = p && equal_str(s2kparams); return p; } int ktest_equal_pa_otp_req(krb5_pa_otp_req *ref, krb5_pa_otp_req *var) { int p = TRUE; if (ref == var) return TRUE; else if (ref == NULL || var == NULL) return FALSE; p = p && scalar_equal(flags); p = p && equal_str(nonce); p = p && struct_equal(enc_data, ktest_equal_enc_data); p = p && ptr_equal(hash_alg, ktest_equal_algorithm_identifier); p = p && scalar_equal(iteration_count); p = p && equal_str(otp_value); p = p && equal_str(pin); p = p && equal_str(challenge); p = p && scalar_equal(time); p = p && equal_str(counter); p = p && scalar_equal(format); p = p && equal_str(token_id); p = p && equal_str(alg_id); p = p && equal_str(vendor); return p; } #ifdef ENABLE_LDAP static int equal_key_data(krb5_key_data *ref, krb5_key_data *var) { int p = TRUE; if (ref == var) return TRUE; else if (ref == NULL || var == NULL) return FALSE; p = p && scalar_equal(key_data_type[0]); p = p && scalar_equal(key_data_type[1]); p = p && len_equal(key_data_length[0],key_data_contents[0], ktest_equal_array_of_octet); p = p && len_equal(key_data_length[1],key_data_contents[1], ktest_equal_array_of_octet); return p; } static int equal_key_data_array(int n, krb5_key_data *ref, krb5_key_data *val) { int i, p = TRUE; for (i = 0; i < n; i++) { p = p && equal_key_data(ref+i, val+i); } return p; } int ktest_equal_ldap_sequence_of_keys(ldap_seqof_key_data *ref, ldap_seqof_key_data *var) { int p = TRUE; if (ref == var) return TRUE; else if (ref == NULL || var == NULL) return FALSE; p = p && scalar_equal(mkvno); p = p && scalar_equal(kvno); p = p && len_equal(n_key_data,key_data,equal_key_data_array); return p; } #endif /**** arrays ****************************************************************/ int ktest_equal_array_of_data(int length, krb5_data *ref, krb5_data *var) { int i,p = TRUE; if (length == 0 || ref == var) return TRUE; else if (ref == NULL || var == NULL) return FALSE; for (i=0; i<(length); i++) { p = p && ktest_equal_data(&(ref[i]),&(var[i])); } return p; } int ktest_equal_array_of_octet(unsigned int length, krb5_octet *ref, krb5_octet *var) { unsigned int i, p = TRUE; if (length == 0 || ref == var) return TRUE; else if (ref == NULL || var == NULL) return FALSE; for (i=0; ichoice != var->choice) return FALSE; if (ref->choice == choice_pa_pk_as_rep_dhInfo) p = p && struct_equal(u.dh_Info, ktest_equal_dh_rep_info); else if (ref->choice == choice_pa_pk_as_rep_encKeyPack) p = p && equal_str(u.encKeyPack); return p; } static int ktest_equal_sequence_of_data(krb5_data **ref, krb5_data **var) { array_compare(ktest_equal_data); } int ktest_equal_auth_pack(krb5_auth_pack *ref, krb5_auth_pack *var) { int p = TRUE; if (ref == var) return TRUE; else if (ref == NULL || var == NULL) return FALSE; p = p && struct_equal(pkAuthenticator, ktest_equal_pk_authenticator); p = p && ptr_equal(clientPublicValue, ktest_equal_subject_pk_info); p = p && ptr_equal(supportedCMSTypes, ktest_equal_sequence_of_algorithm_identifier); p = p && equal_str(clientDHNonce); p = p && ptr_equal(supportedKDFs, ktest_equal_sequence_of_data); return p; } int ktest_equal_auth_pack_draft9(krb5_auth_pack_draft9 *ref, krb5_auth_pack_draft9 *var) { int p = TRUE; if (ref == var) return TRUE; else if (ref == NULL || var == NULL) return FALSE; p = p && struct_equal(pkAuthenticator, ktest_equal_pk_authenticator_draft9); p = p && ptr_equal(clientPublicValue, ktest_equal_subject_pk_info); return p; } int ktest_equal_kdc_dh_key_info(krb5_kdc_dh_key_info *ref, krb5_kdc_dh_key_info *var) { int p = TRUE; if (ref == var) return TRUE; else if (ref == NULL || var == NULL) return FALSE; p = p && equal_str(subjectPublicKey); p = p && scalar_equal(nonce); p = p && scalar_equal(dhKeyExpiration); return p; } int ktest_equal_reply_key_pack(krb5_reply_key_pack *ref, krb5_reply_key_pack *var) { int p = TRUE; if (ref == var) return TRUE; else if (ref == NULL || var == NULL) return FALSE; p = p && struct_equal(replyKey, ktest_equal_keyblock); p = p && struct_equal(asChecksum, ktest_equal_checksum); return p; } int ktest_equal_reply_key_pack_draft9(krb5_reply_key_pack_draft9 *ref, krb5_reply_key_pack_draft9 *var) { int p = TRUE; if (ref == var) return TRUE; else if (ref == NULL || var == NULL) return FALSE; p = p && struct_equal(replyKey, ktest_equal_keyblock); p = p && scalar_equal(nonce); return p; } #endif /* not DISABLE_PKINIT */ int ktest_equal_kkdcp_message(krb5_kkdcp_message *ref, krb5_kkdcp_message *var) { int p = TRUE; if (ref == var) return TRUE; else if (ref == NULL || var == NULL) return FALSE; p = p && data_eq(ref->kerb_message, var->kerb_message); p = p && data_eq(ref->target_domain, var->target_domain); p = p && (ref->dclocator_hint == var->dclocator_hint); return p; } static int vmac_eq(krb5_verifier_mac *ref, krb5_verifier_mac *var) { int p = TRUE; if (ref == var) return TRUE; else if (ref == NULL || var == NULL) return FALSE; p = p && ptr_equal(princ, ktest_equal_principal_data); p = p && scalar_equal(kvno); p = p && scalar_equal(enctype); p = p && struct_equal(checksum, ktest_equal_checksum); return p; } static int vmac_list_eq(krb5_verifier_mac **ref, krb5_verifier_mac **var) { array_compare(vmac_eq); } int ktest_equal_cammac(krb5_cammac *ref, krb5_cammac *var) { int p = TRUE; if (ref == var) return TRUE; else if (ref == NULL || var == NULL) return FALSE; p = p && ptr_equal(elements, ktest_equal_authorization_data); p = p && ptr_equal(kdc_verifier, vmac_eq); p = p && ptr_equal(svc_verifier, vmac_eq); p = p && ptr_equal(other_verifiers, vmac_list_eq); return p; } int ktest_equal_secure_cookie(krb5_secure_cookie *ref, krb5_secure_cookie *var) { int p = TRUE; if (ref == var) return TRUE; else if (ref == NULL || var == NULL) return FALSE; p = p && ktest_equal_sequence_of_pa_data(ref->data, var->data); p = p && ref->time == ref->time; return p; } krb5-1.16/src/tests/asn.1/pkinit-agility.asn10000644000704600001450000000711513211554426020575 0ustar ghudsonlibuuidKerberosV5-PK-INIT-Agility-SPEC { iso(1) identified-organization(3) dod(6) internet(1) security(5) kerberosV5(2) modules(4) pkinit(5) agility (1) } DEFINITIONS EXPLICIT TAGS ::= BEGIN IMPORTS AlgorithmIdentifier, SubjectPublicKeyInfo FROM PKIX1Explicit88 { iso (1) identified-organization (3) dod (6) internet (1) security (5) mechanisms (5) pkix (7) id-mod (0) id-pkix1-explicit (18) } -- As defined in RFC 3280. Ticket, Int32, Realm, EncryptionKey, Checksum FROM KerberosV5Spec2 { iso(1) identified-organization(3) dod(6) internet(1) security(5) kerberosV5(2) modules(4) krb5spec2(2) } -- as defined in RFC 4120. PKAuthenticator, DHNonce FROM KerberosV5-PK-INIT-SPEC { iso(1) identified-organization(3) dod(6) internet(1) security(5) kerberosV5(2) modules(4) pkinit(5) }; -- as defined in RFC 4556. TD-CMS-DIGEST-ALGORITHMS-DATA ::= SEQUENCE OF AlgorithmIdentifier -- Contains the list of CMS algorithm [RFC3852] -- identifiers that identify the digest algorithms -- acceptable by the KDC for signing CMS data in -- the order of decreasing preference. TD-CERT-DIGEST-ALGORITHMS-DATA ::= SEQUENCE { allowedAlgorithms [0] SEQUENCE OF AlgorithmIdentifier, -- Contains the list of CMS algorithm [RFC3852] -- identifiers that identify the digest algorithms -- that are used by the CA to sign the client's -- X.509 certificate and acceptable by the KDC in -- the process of validating the client's X.509 -- certificate, in the order of decreasing -- preference. rejectedAlgorithm [1] AlgorithmIdentifier OPTIONAL, -- This identifies the digest algorithm that was -- used to sign the client's X.509 certificate and -- has been rejected by the KDC in the process of -- validating the client's X.509 certificate -- [RFC3280]. ... } OtherInfo ::= SEQUENCE { algorithmID AlgorithmIdentifier, partyUInfo [0] OCTET STRING, partyVInfo [1] OCTET STRING, suppPubInfo [2] OCTET STRING OPTIONAL, suppPrivInfo [3] OCTET STRING OPTIONAL } PkinitSuppPubInfo ::= SEQUENCE { enctype [0] Int32, -- The enctype of the AS reply key. as-REQ [1] OCTET STRING, -- This contains the AS-REQ in the request. pk-as-rep [2] OCTET STRING, -- Contains the DER encoding of the type -- PA-PK-AS-REP [RFC4556] in the KDC reply. ... } -- Renamed from AuthPack to allow asn1c to process this and pkinit.asn1 AuthPack2 ::= SEQUENCE { pkAuthenticator [0] PKAuthenticator, clientPublicValue [1] SubjectPublicKeyInfo OPTIONAL, supportedCMSTypes [2] SEQUENCE OF AlgorithmIdentifier OPTIONAL, clientDHNonce [3] DHNonce OPTIONAL, ..., supportedKDFs [4] SEQUENCE OF KDFAlgorithmId OPTIONAL, -- Contains an unordered set of KDFs supported by the -- client. ... } KDFAlgorithmId ::= SEQUENCE { kdf-id [0] OBJECT IDENTIFIER, -- The object identifier of the KDF ... } -- Renamed from DHRepInfo to allow asn1c to process this and pkinit.asn1 DHRepInfo2 ::= SEQUENCE { dhSignedData [0] IMPLICIT OCTET STRING, serverDHNonce [1] DHNonce OPTIONAL, ..., kdf [2] KDFAlgorithmId OPTIONAL, -- The KDF picked by the KDC. ... } END krb5-1.16/src/tests/asn.1/debug.h0000644000704600001450000000333513211554426016312 0ustar ghudsonlibuuid/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* tests/asn.1/debug.h */ /* * Copyright (C) 1994 by the Massachusetts Institute of Technology. * All rights reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #ifndef __DEBUG_H__ #define __DEBUG_H__ /* assert utility macro for test programs: If the predicate (pred) is true, then OK: is printed. Otherwise, ERROR: is printed. message should be a printf format string. */ #include #define test(pred,message) \ if(pred) printf("OK: "); \ else { printf("ERROR: "); error_count++; } \ printf(message); #endif krb5-1.16/src/tests/asn.1/utility.h0000644000704600001450000000501313211554426016722 0ustar ghudsonlibuuid/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* tests/asn.1/utility.h */ /* * Copyright (C) 1994 by the Massachusetts Institute of Technology. * All rights reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #ifndef __UTILITY_H__ #define __UTILITY_H__ #include "k5-int.h" #include "krbasn1.h" #include "asn1buf.h" /* Aborts on failure. ealloc returns zero-filled memory. */ void *ealloc(size_t size); char *estrdup(const char *str); void asn1_krb5_data_unparse(const krb5_data *code, char **s); /* modifies *s; effects Instantiates *s with a string representation of the series of hex octets in *code. (e.g. "02 02 00 7F") If code==NULL, the string rep is "". If code is empty (it contains no data or has length <= 0), the string rep is "". If *s is non-NULL, then its currently-allocated storage will be freed prior to the instantiation. Returns ENOMEM or the string rep cannot be created. */ void krb5_data_parse(krb5_data *d, const char *s); /* effects Parses character string *s into krb5_data *d. */ asn1_error_code krb5_data_hex_parse(krb5_data *d, const char *s); /* requires *s is the string representation of a sequence of hexadecimal octets. (e.g. "02 01 00") effects Parses *s into krb5_data *d. */ void asn1buf_print(const asn1buf *buf); extern krb5int_access acc; extern void init_access(const char *progname); #endif krb5-1.16/src/tests/asn.1/deps0000644000704600001450000001200013211554426015716 0ustar ghudsonlibuuid# # Generated makefile dependencies follow. # $(OUTPRE)krb5_encode_test.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(srcdir)/../../lib/krb5/asn.1/asn1buf.h \ $(srcdir)/../../lib/krb5/asn.1/krbasn1.h $(top_srcdir)/include/k5-buf.h \ $(top_srcdir)/include/k5-err.h $(top_srcdir)/include/k5-gmt_mktime.h \ $(top_srcdir)/include/k5-int-pkinit.h $(top_srcdir)/include/k5-int.h \ $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-plugin.h \ $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/k5-trace.h \ $(top_srcdir)/include/kdb.h $(top_srcdir)/include/krb5.h \ $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/plugin.h \ $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \ debug.h krb5_encode_test.c ktest.h utility.h $(OUTPRE)krb5_decode_test.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(srcdir)/../../lib/krb5/asn.1/asn1buf.h \ $(srcdir)/../../lib/krb5/asn.1/krbasn1.h $(top_srcdir)/include/k5-buf.h \ $(top_srcdir)/include/k5-err.h $(top_srcdir)/include/k5-gmt_mktime.h \ $(top_srcdir)/include/k5-int-pkinit.h $(top_srcdir)/include/k5-int.h \ $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-plugin.h \ $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/k5-trace.h \ $(top_srcdir)/include/kdb.h $(top_srcdir)/include/krb5.h \ $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/plugin.h \ $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \ debug.h krb5_decode_test.c ktest.h ktest_equal.h utility.h $(OUTPRE)krb5_decode_leak.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(srcdir)/../../lib/krb5/asn.1/asn1buf.h \ $(srcdir)/../../lib/krb5/asn.1/krbasn1.h $(top_srcdir)/include/k5-buf.h \ $(top_srcdir)/include/k5-err.h $(top_srcdir)/include/k5-gmt_mktime.h \ $(top_srcdir)/include/k5-int-pkinit.h $(top_srcdir)/include/k5-int.h \ $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-plugin.h \ $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/k5-trace.h \ $(top_srcdir)/include/kdb.h $(top_srcdir)/include/krb5.h \ $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/plugin.h \ $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \ debug.h krb5_decode_leak.c ktest.h utility.h $(OUTPRE)ktest.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(srcdir)/../../lib/krb5/asn.1/asn1buf.h \ $(srcdir)/../../lib/krb5/asn.1/krbasn1.h $(top_srcdir)/include/k5-buf.h \ $(top_srcdir)/include/k5-err.h $(top_srcdir)/include/k5-gmt_mktime.h \ $(top_srcdir)/include/k5-int-pkinit.h $(top_srcdir)/include/k5-int.h \ $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-plugin.h \ $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/k5-trace.h \ $(top_srcdir)/include/kdb.h $(top_srcdir)/include/krb5.h \ $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/plugin.h \ $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \ ktest.c ktest.h utility.h $(OUTPRE)ktest_equal.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h \ $(top_srcdir)/include/k5-err.h $(top_srcdir)/include/k5-gmt_mktime.h \ $(top_srcdir)/include/k5-int-pkinit.h $(top_srcdir)/include/k5-int.h \ $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-plugin.h \ $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/k5-trace.h \ $(top_srcdir)/include/kdb.h $(top_srcdir)/include/krb5.h \ $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/plugin.h \ $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \ ktest_equal.c ktest_equal.h $(OUTPRE)utility.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(srcdir)/../../lib/krb5/asn.1/asn1buf.h \ $(srcdir)/../../lib/krb5/asn.1/krbasn1.h $(top_srcdir)/include/k5-buf.h \ $(top_srcdir)/include/k5-err.h $(top_srcdir)/include/k5-gmt_mktime.h \ $(top_srcdir)/include/k5-int-pkinit.h $(top_srcdir)/include/k5-int.h \ $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-plugin.h \ $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/k5-trace.h \ $(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/authdata_plugin.h \ $(top_srcdir)/include/krb5/plugin.h $(top_srcdir)/include/port-sockets.h \ $(top_srcdir)/include/socket-utils.h utility.c utility.h $(OUTPRE)trval.$(OBJEXT): trval.c $(OUTPRE)t_trval.$(OBJEXT): t_trval.c trval.c krb5-1.16/src/tests/asn.1/ldap_trval.out0000644000704600001450000000154413211554426017734 0ustar ghudsonlibuuid encode_krb5_ldap_seqof_key_data: [Sequence/Sequence Of] . [0] [Integer] 1 . [1] [Integer] 1 . [2] [Integer] 42 . [3] [Integer] 14 . [4] [Sequence/Sequence Of] . . [Sequence/Sequence Of] . . . [0] [Sequence/Sequence Of] . . . . [0] [Integer] 0 . . . . [1] [Octet String] "salt0" . . . [1] [Sequence/Sequence Of] . . . . [0] [Integer] 2 . . . . [1] [Octet String] "key0" . . [Sequence/Sequence Of] . . . [0] [Sequence/Sequence Of] . . . . [0] [Integer] 1 . . . . [1] [Octet String] "salt1" . . . [1] [Sequence/Sequence Of] . . . . [0] [Integer] 2 . . . . [1] [Octet String] "key1" . . [Sequence/Sequence Of] . . . [0] [Sequence/Sequence Of] . . . . [0] [Integer] 2 . . . . [1] [Octet String] "salt2" . . . [1] [Sequence/Sequence Of] . . . . [0] [Integer] 2 . . . . [1] [Octet String] "key2" krb5-1.16/src/tests/asn.1/pkinit.asn10000644000704600001450000002510213211554426017131 0ustar ghudsonlibuuidKerberosV5-PK-INIT-SPEC { iso(1) identified-organization(3) dod(6) internet(1) security(5) kerberosV5(2) modules(4) pkinit(5) } DEFINITIONS EXPLICIT TAGS ::= BEGIN IMPORTS SubjectPublicKeyInfo, AlgorithmIdentifier FROM PKIX1Explicit88 { iso (1) identified-organization (3) dod (6) internet (1) security (5) mechanisms (5) pkix (7) id-mod (0) id-pkix1-explicit (18) } -- As defined in RFC 3280. KerberosTime, PrincipalName, Realm, EncryptionKey, Checksum FROM KerberosV5Spec2 { iso(1) identified-organization(3) dod(6) internet(1) security(5) kerberosV5(2) modules(4) krb5spec2(2) }; -- as defined in RFC 4120. id-pkinit OBJECT IDENTIFIER ::= { iso(1) identified-organization(3) dod(6) internet(1) security(5) kerberosv5(2) pkinit (3) } id-pkinit-authData OBJECT IDENTIFIER ::= { id-pkinit 1 } id-pkinit-DHKeyData OBJECT IDENTIFIER ::= { id-pkinit 2 } id-pkinit-rkeyData OBJECT IDENTIFIER ::= { id-pkinit 3 } id-pkinit-KPClientAuth OBJECT IDENTIFIER ::= { id-pkinit 4 } id-pkinit-KPKdc OBJECT IDENTIFIER ::= { id-pkinit 5 } id-pkinit-san OBJECT IDENTIFIER ::= { iso(1) org(3) dod(6) internet(1) security(5) kerberosv5(2) x509SanAN (2) } pa-pk-as-req INTEGER ::= 16 pa-pk-as-rep INTEGER ::= 17 ad-initial-verified-cas INTEGER ::= 9 td-trusted-certifiers INTEGER ::= 104 td-invalid-certificates INTEGER ::= 105 td-dh-parameters INTEGER ::= 109 PA-PK-AS-REQ ::= SEQUENCE { signedAuthPack [0] IMPLICIT OCTET STRING, -- Contains a CMS type ContentInfo encoded -- according to [RFC3852]. -- The contentType field of the type ContentInfo -- is id-signedData (1.2.840.113549.1.7.2), -- and the content field is a SignedData. -- The eContentType field for the type SignedData is -- id-pkinit-authData (1.3.6.1.5.2.3.1), and the -- eContent field contains the DER encoding of the -- type AuthPack. -- AuthPack is defined below. trustedCertifiers [1] SEQUENCE OF ExternalPrincipalIdentifier OPTIONAL, -- Contains a list of CAs, trusted by the client, -- that can be used to certify the KDC. -- Each ExternalPrincipalIdentifier identifies a CA -- or a CA certificate (thereby its public key). -- The information contained in the -- trustedCertifiers SHOULD be used by the KDC as -- hints to guide its selection of an appropriate -- certificate chain to return to the client. kdcPkId [2] IMPLICIT OCTET STRING OPTIONAL, -- Contains a CMS type SignerIdentifier encoded -- according to [RFC3852]. -- Identifies, if present, a particular KDC -- public key that the client already has. ... } DHNonce ::= OCTET STRING ExternalPrincipalIdentifier ::= SEQUENCE { subjectName [0] IMPLICIT OCTET STRING OPTIONAL, -- Contains a PKIX type Name encoded according to -- [RFC3280]. -- Identifies the certificate subject by the -- distinguished subject name. -- REQUIRED when there is a distinguished subject -- name present in the certificate. issuerAndSerialNumber [1] IMPLICIT OCTET STRING OPTIONAL, -- Contains a CMS type IssuerAndSerialNumber encoded -- according to [RFC3852]. -- Identifies a certificate of the subject. -- REQUIRED for TD-INVALID-CERTIFICATES and -- TD-TRUSTED-CERTIFIERS. subjectKeyIdentifier [2] IMPLICIT OCTET STRING OPTIONAL, -- Identifies the subject's public key by a key -- identifier. When an X.509 certificate is -- referenced, this key identifier matches the X.509 -- subjectKeyIdentifier extension value. When other -- certificate formats are referenced, the documents -- that specify the certificate format and their use -- with the CMS must include details on matching the -- key identifier to the appropriate certificate -- field. -- RECOMMENDED for TD-TRUSTED-CERTIFIERS. ... } AuthPack ::= SEQUENCE { pkAuthenticator [0] PKAuthenticator, clientPublicValue [1] SubjectPublicKeyInfo OPTIONAL, -- Type SubjectPublicKeyInfo is defined in -- [RFC3280]. -- Specifies Diffie-Hellman domain parameters -- and the client's public key value [IEEE1363]. -- The DH public key value is encoded as a BIT -- STRING according to [RFC3279]. -- This field is present only if the client wishes -- to use the Diffie-Hellman key agreement method. supportedCMSTypes [2] SEQUENCE OF AlgorithmIdentifier OPTIONAL, -- Type AlgorithmIdentifier is defined in -- [RFC3280]. -- List of CMS algorithm [RFC3370] identifiers -- that identify key transport algorithms, or -- content encryption algorithms, or signature -- algorithms supported by the client in order of -- (decreasing) preference. clientDHNonce [3] DHNonce OPTIONAL, -- Present only if the client indicates that it -- wishes to reuse DH keys or to allow the KDC to -- do so. ... } PKAuthenticator ::= SEQUENCE { cusec [0] INTEGER (0..999999), ctime [1] KerberosTime, -- cusec and ctime are used as in [RFC4120], for -- replay prevention. nonce [2] INTEGER (0..4294967295), -- Chosen randomly; this nonce does not need to -- match with the nonce in the KDC-REQ-BODY. paChecksum [3] OCTET STRING OPTIONAL, -- MUST be present. -- Contains the SHA1 checksum, performed over -- KDC-REQ-BODY. ... } TD-TRUSTED-CERTIFIERS ::= SEQUENCE OF ExternalPrincipalIdentifier -- Identifies a list of CAs trusted by the KDC. -- Each ExternalPrincipalIdentifier identifies a CA -- or a CA certificate (thereby its public key). TD-INVALID-CERTIFICATES ::= SEQUENCE OF ExternalPrincipalIdentifier -- Each ExternalPrincipalIdentifier identifies a -- certificate (sent by the client) with an invalid -- signature. KRB5PrincipalName ::= SEQUENCE { realm [0] Realm, principalName [1] PrincipalName } AD-INITIAL-VERIFIED-CAS ::= SEQUENCE OF ExternalPrincipalIdentifier -- Identifies the certification path based on which -- the client certificate was validated. -- Each ExternalPrincipalIdentifier identifies a CA -- or a CA certificate (thereby its public key). PA-PK-AS-REP ::= CHOICE { dhInfo [0] DHRepInfo, -- Selected when Diffie-Hellman key exchange is -- used. encKeyPack [1] IMPLICIT OCTET STRING, -- Selected when public key encryption is used. -- Contains a CMS type ContentInfo encoded -- according to [RFC3852]. -- The contentType field of the type ContentInfo is -- id-envelopedData (1.2.840.113549.1.7.3). -- The content field is an EnvelopedData. -- The contentType field for the type EnvelopedData -- is id-signedData (1.2.840.113549.1.7.2). -- The eContentType field for the inner type -- SignedData (when unencrypted) is -- id-pkinit-rkeyData (1.3.6.1.5.2.3.3) and the -- eContent field contains the DER encoding of the -- type ReplyKeyPack. -- ReplyKeyPack is defined below. ... } DHRepInfo ::= SEQUENCE { dhSignedData [0] IMPLICIT OCTET STRING, -- Contains a CMS type ContentInfo encoded according -- to [RFC3852]. -- The contentType field of the type ContentInfo is -- id-signedData (1.2.840.113549.1.7.2), and the -- content field is a SignedData. -- The eContentType field for the type SignedData is -- id-pkinit-DHKeyData (1.3.6.1.5.2.3.2), and the -- eContent field contains the DER encoding of the -- type KDCDHKeyInfo. -- KDCDHKeyInfo is defined below. serverDHNonce [1] DHNonce OPTIONAL, -- Present if and only if dhKeyExpiration is -- present. ... } KDCDHKeyInfo ::= SEQUENCE { subjectPublicKey [0] BIT STRING, -- The KDC's DH public key. -- The DH public key value is encoded as a BIT -- STRING according to [RFC3279]. nonce [1] INTEGER (0..4294967295), -- Contains the nonce in the pkAuthenticator field -- in the request if the DH keys are NOT reused, -- 0 otherwise. dhKeyExpiration [2] KerberosTime OPTIONAL, -- Expiration time for KDC's key pair, -- present if and only if the DH keys are reused. -- If present, the KDC's DH public key MUST not be -- used past the point of this expiration time. -- If this field is omitted then the serverDHNonce -- field MUST also be omitted. ... } ReplyKeyPack ::= SEQUENCE { replyKey [0] EncryptionKey, -- Contains the session key used to encrypt the -- enc-part field in the AS-REP, i.e., the -- AS reply key. asChecksum [1] Checksum, -- Contains the checksum of the AS-REQ -- corresponding to the containing AS-REP. -- The checksum is performed over the type AS-REQ. -- The protocol key [RFC3961] of the checksum is the -- replyKey and the key usage number is 6. -- If the replyKey's enctype is "newer" [RFC4120] -- [RFC4121], the checksum is the required -- checksum operation [RFC3961] for that enctype. -- The client MUST verify this checksum upon receipt -- of the AS-REP. ... } TD-DH-PARAMETERS ::= SEQUENCE OF AlgorithmIdentifier -- Each AlgorithmIdentifier specifies a set of -- Diffie-Hellman domain parameters [IEEE1363]. -- This list is in decreasing preference order. END krb5-1.16/src/tests/asn.1/trval.c0000644000704600001450000005017413211554426016352 0ustar ghudsonlibuuid/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* * Copyright (C) 1992,1993 Trusted Information Systems, Inc. * * Permission to include this software in the Kerberos V5 distribution * was graciously provided by Trusted Information Systems. * * Trusted Information Systems makes no representation about the * suitability of this software for any purpose. It is provided * "as is" without express or implied warranty. */ /* * Copyright (C) 1994 Massachusetts Institute of Technology * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ /***************************************************************************** * trval.c.c *****************************************************************************/ #include #include #include #include #include #define OK 0 #define NOTOK (-1) /* IDENTIFIER OCTET = TAG CLASS | FORM OF ENCODING | TAG NUMBER */ /* TAG CLASSES */ #define ID_CLASS 0xc0 /* bits 8 and 7 */ #define CLASS_UNIV 0x00 /* 0 = universal */ #define CLASS_APPL 0x40 /* 1 = application */ #define CLASS_CONT 0x80 /* 2 = context-specific */ #define CLASS_PRIV 0xc0 /* 3 = private */ /* FORM OF ENCODING */ #define ID_FORM 0x20 /* bit 6 */ #define FORM_PRIM 0x00 /* 0 = primitive */ #define FORM_CONS 0x20 /* 1 = constructed */ /* TAG NUMBERS */ #define ID_TAG 0x1f /* bits 5-1 */ #define PRIM_BOOL 0x01 /* Boolean */ #define PRIM_INT 0x02 /* Integer */ #define PRIM_BITS 0x03 /* Bit String */ #define PRIM_OCTS 0x04 /* Octet String */ #define PRIM_NULL 0x05 /* Null */ #define PRIM_OID 0x06 /* Object Identifier */ #define PRIM_ODE 0x07 /* Object Descriptor */ #define CONS_EXTN 0x08 /* External */ #define PRIM_REAL 0x09 /* Real */ #define PRIM_ENUM 0x0a /* Enumerated type */ #define PRIM_ENCR 0x0b /* Encrypted */ #define CONS_SEQ 0x10 /* SEQUENCE/SEQUENCE OF */ #define CONS_SET 0x11 /* SET/SET OF */ #define DEFN_NUMS 0x12 /* Numeric String */ #define DEFN_PRTS 0x13 /* Printable String */ #define DEFN_T61S 0x14 /* T.61 String */ #define DEFN_VTXS 0x15 /* Videotex String */ #define DEFN_IA5S 0x16 /* IA5 String */ #define DEFN_UTCT 0x17 /* UTCTime */ #define DEFN_GENT 0x18 /* Generalized Time */ #define DEFN_GFXS 0x19 /* Graphics string (ISO2375) */ #define DEFN_VISS 0x1a /* Visible string */ #define DEFN_GENS 0x1b /* General string */ #define DEFN_CHRS 0x1c /* Character string */ #define LEN_XTND 0x80 /* long or indefinite form */ #define LEN_SMAX 127 /* largest short form */ #define LEN_MASK 0x7f /* mask to get number of bytes in length */ #define LEN_INDF (-1) /* indefinite length */ #define KRB5 /* Do krb5 application types */ int print_types = 0; int print_id_and_len = 1; int print_constructed_length = 1; int print_primitive_length = 1; int print_skip_context = 0; int print_skip_tagnum = 1; int print_context_shortcut = 0; int do_hex = 0; #ifdef KRB5 int print_krb5_types = 0; #endif int current_appl_type = -1; int decode_len (FILE *, unsigned char *, int); int do_prim (FILE *, int, unsigned char *, int, int); int do_cons (FILE *, unsigned char *, int, int, int *); int do_prim_bitstring (FILE *, int, unsigned char *, int, int); int do_prim_int (FILE *, int, unsigned char *, int, int); int do_prim_string (FILE *, int, unsigned char *, int, int); void print_tag_type (FILE *, int, int); int trval (FILE *, FILE *); int trval2 (FILE *, unsigned char *, int, int, int *); /****************************************************************************/ static int convert_nibble(int ch) { if (isdigit(ch)) return (ch - '0'); if (ch >= 'a' && ch <= 'f') return (ch - 'a' + 10); if (ch >= 'A' && ch <= 'F') return (ch - 'A' + 10); return -1; } int trval(fin, fout) FILE *fin; FILE *fout; { unsigned char *p; unsigned int maxlen; int len; int cc, cc2, n1, n2; int r; int rlen; maxlen = BUFSIZ; p = (unsigned char *)malloc(maxlen); len = 0; while ((cc = fgetc(fin)) != EOF) { if ((unsigned int) len == maxlen) { maxlen += BUFSIZ; p = (unsigned char *)realloc(p, maxlen); } if (do_hex) { if (cc == ' ' || cc == '\n' || cc == '\t') continue; cc2 = fgetc(fin); if (cc2 == EOF) break; n1 = convert_nibble(cc); n2 = convert_nibble(cc2); cc = (n1 << 4) + n2; } p[len++] = cc; } fprintf(fout, "<%d>", len); r = trval2(fout, p, len, 0, &rlen); fprintf(fout, "\n"); (void) free(p); return(r); } int trval2(fp, enc, len, lev, rlen) FILE *fp; unsigned char *enc; int len; int lev; int *rlen; { int l, eid, elen, xlen, r, rlen2 = 0; int rlen_ext = 0; r = OK; *rlen = -1; if (len < 2) { fprintf(fp, "missing id and length octets (%d)\n", len); return(NOTOK); } fprintf(fp, "\n"); for (l=0; l len - 2) { fprintf(fp, "extended length too long (%d > %d - 2)\n", xlen, len); return(NOTOK); } elen = decode_len(fp, enc+2, xlen); } if (elen > len - 2 - xlen) { fprintf(fp, "length too long (%d > %d - 2 - %d)\n", elen, len, xlen); return(NOTOK); } print_tag_type(fp, eid, lev); if (print_context_shortcut && (eid & ID_CLASS) == CLASS_CONT && (eid & ID_FORM) == FORM_CONS && lev > 0) { rlen_ext += 2 + xlen; enc += 2 + xlen; fprintf(fp, " "); goto context_restart; } switch(eid & ID_FORM) { case FORM_PRIM: r = do_prim(fp, eid & ID_TAG, enc+2+xlen, elen, lev+1); *rlen = 2 + xlen + elen + rlen_ext; break; case FORM_CONS: if (print_constructed_length) { fprintf(fp, " constr"); fprintf(fp, " <%d>", elen); } r = do_cons(fp, enc+2+xlen, elen, lev+1, &rlen2); *rlen = 2 + xlen + rlen2 + rlen_ext; break; } return(r); } int decode_len(fp, enc, len) FILE *fp; unsigned char *enc; int len; { int rlen; int i; if (print_id_and_len) fprintf(fp, "%02x ", enc[0]); rlen = enc[0]; for (i=1; i 5) return 0; for (i=1; i < len; i++) { num = num << 8; num += enc[i]; } fprintf(fp, " 0x%lx", num); if (enc[0]) fprintf(fp, " (%d unused bits)", enc[0]); return 1; } /* * This is the printing function for integers */ int do_prim_int(fp, tag, enc, len, lev) FILE *fp; int tag; unsigned char *enc; int len; int lev; { int i; long num = 0; if (tag != PRIM_INT || len > 4) return 0; if (enc[0] & 0x80) num = -1; for (i=0; i < len; i++) { num = num << 8; num += enc[i]; } fprintf(fp, " %ld", num); return 1; } /* * This is the printing function which we use if it's a string or * other other type which is best printed as a string */ int do_prim_string(fp, tag, enc, len, lev) FILE *fp; int tag; unsigned char *enc; int len; int lev; { int i; /* * Only try this printing function with "reasonable" types */ if ((tag < DEFN_NUMS) && (tag != PRIM_OCTS)) return 0; for (i=0; i < len; i++) if (!isprint(enc[i])) return 0; fprintf(fp, " \"%.*s\"", len, enc); return 1; } int do_prim(fp, tag, enc, len, lev) FILE *fp; int tag; unsigned char *enc; int len; int lev; { int n; int i; int j; int width; if (do_prim_string(fp, tag, enc, len, lev)) return OK; if (do_prim_int(fp, tag, enc, len, lev)) return OK; if (do_prim_bitstring(fp, tag, enc, len, lev)) return OK; if (print_primitive_length) fprintf(fp, " <%d>", len); width = (80 - (lev * 3) - 8) / 4; for (n = 0; n < len; n++) { if ((n % width) == 0) { fprintf(fp, "\n"); for (i=0; ik1 > 0; ent++) { if ((ent->k1 == key1) && (ent->k2 == key2)) { if (ent->new_appl) current_appl_type = ent->new_appl; return ent->str; } } return 0; } struct typestring_table univ_types[] = { { PRIM_BOOL, -1, "Boolean"}, { PRIM_INT, -1, "Integer"}, { PRIM_BITS, -1, "Bit String"}, { PRIM_OCTS, -1, "Octet String"}, { PRIM_NULL, -1, "Null"}, { PRIM_OID, -1, "Object Identifier"}, { PRIM_ODE, -1, "Object Descriptor"}, { CONS_EXTN, -1, "External"}, { PRIM_REAL, -1, "Real"}, { PRIM_ENUM, -1, "Enumerated type"}, { PRIM_ENCR, -1, "Encrypted"}, { CONS_SEQ, -1, "Sequence/Sequence Of"}, { CONS_SET, -1, "Set/Set Of"}, { DEFN_NUMS, -1, "Numeric String"}, { DEFN_PRTS, -1, "Printable String"}, { DEFN_T61S, -1, "T.61 String"}, { DEFN_VTXS, -1, "Videotex String"}, { DEFN_IA5S, -1, "IA5 String"}, { DEFN_UTCT, -1, "UTCTime"}, { DEFN_GENT, -1, "Generalized Time"}, { DEFN_GFXS, -1, "Graphics string (ISO2375)"}, { DEFN_VISS, -1, "Visible string"}, { DEFN_GENS, -1, "General string"}, { DEFN_CHRS, -1, "Character string"}, { -1, -1, 0} }; #ifdef KRB5 struct typestring_table krb5_types[] = { { 1, -1, "Krb5 Ticket"}, { 2, -1, "Krb5 Authenticator"}, { 3, -1, "Krb5 Encrypted ticket part"}, { 10, -1, "Krb5 AS-REQ packet"}, { 11, -1, "Krb5 AS-REP packet"}, { 12, -1, "Krb5 TGS-REQ packet"}, { 13, -1, "Krb5 TGS-REP packet"}, { 14, -1, "Krb5 AP-REQ packet"}, { 15, -1, "Krb5 AP-REP packet"}, { 20, -1, "Krb5 SAFE packet"}, { 21, -1, "Krb5 PRIV packet"}, { 22, -1, "Krb5 CRED packet"}, { 30, -1, "Krb5 ERROR packet"}, { 25, -1, "Krb5 Encrypted AS-REP part"}, { 26, -1, "Krb5 Encrypted TGS-REP part"}, { 27, -1, "Krb5 Encrypted AP-REP part"}, { 28, -1, "Krb5 Encrypted PRIV part"}, { 29, -1, "Krb5 Encrypted CRED part"}, { -1, -1, 0} }; struct typestring_table krb5_fields[] = { { 1000, 0, "name-type"}, /* PrincipalName */ { 1000, 1, "name-string"}, { 1001, 0, "etype"}, /* Encrypted data */ { 1001, 1, "kvno"}, { 1001, 2, "cipher"}, { 1002, 0, "addr-type"}, /* HostAddress */ { 1002, 1, "address"}, { 1003, 0, "addr-type"}, /* HostAddresses */ { 1003, 1, "address"}, { 1004, 0, "ad-type"}, /* AuthorizationData */ { 1004, 1, "ad-data"}, { 1005, 0, "keytype"}, /* EncryptionKey */ { 1005, 1, "keyvalue"}, { 1006, 0, "cksumtype"}, /* Checksum */ { 1006, 1, "checksum"}, { 1007, 0, "kdc-options"}, /* KDC-REQ-BODY */ { 1007, 1, "cname", 1000}, { 1007, 2, "realm"}, { 1007, 3, "sname", 1000}, { 1007, 4, "from"}, { 1007, 5, "till"}, { 1007, 6, "rtime"}, { 1007, 7, "nonce"}, { 1007, 8, "etype"}, { 1007, 9, "addresses", 1003}, { 1007, 10, "enc-authorization-data", 1001}, { 1007, 11, "additional-tickets"}, { 1008, 1, "padata-type"}, /* PA-DATA */ { 1008, 2, "pa-data"}, { 1009, 0, "user-data"}, /* KRB-SAFE-BODY */ { 1009, 1, "timestamp"}, { 1009, 2, "usec"}, { 1009, 3, "seq-number"}, { 1009, 4, "s-address", 1002}, { 1009, 5, "r-address", 1002}, { 1010, 0, "lr-type"}, /* LastReq */ { 1010, 1, "lr-value"}, { 1011, 0, "key", 1005}, /* KRB-CRED-INFO */ { 1011, 1, "prealm"}, { 1011, 2, "pname", 1000}, { 1011, 3, "flags"}, { 1011, 4, "authtime"}, { 1011, 5, "startime"}, { 1011, 6, "endtime"}, { 1011, 7, "renew-till"}, { 1011, 8, "srealm"}, { 1011, 9, "sname", 1000}, { 1011, 10, "caddr", 1002}, { 1, 0, "tkt-vno"}, /* Ticket */ { 1, 1, "realm"}, { 1, 2, "sname", 1000}, { 1, 3, "tkt-enc-part", 1001}, { 2, 0, "authenticator-vno"}, /* Authenticator */ { 2, 1, "crealm"}, { 2, 2, "cname", 1000}, { 2, 3, "cksum", 1006}, { 2, 4, "cusec"}, { 2, 5, "ctime"}, { 2, 6, "subkey", 1005}, { 2, 7, "seq-number"}, { 2, 8, "authorization-data", 1004}, { 3, 0, "flags"}, /* EncTicketPart */ { 3, 1, "key", 1005}, { 3, 2, "crealm"}, { 3, 3, "cname", 1000}, { 3, 4, "transited"}, { 3, 5, "authtime"}, { 3, 6, "starttime"}, { 3, 7, "endtime"}, { 3, 8, "renew-till"}, { 3, 9, "caddr", 1003}, { 3, 10, "authorization-data", 1004}, { 10, 1, "pvno"}, /* AS-REQ */ { 10, 2, "msg-type"}, { 10, 3, "padata", 1008}, { 10, 4, "req-body", 1007}, { 11, 0, "pvno"}, /* AS-REP */ { 11, 1, "msg-type"}, { 11, 2, "padata", 1008}, { 11, 3, "crealm"}, { 11, 4, "cname", 1000}, { 11, 5, "ticket"}, { 11, 6, "enc-part", 1001}, { 12, 1, "pvno"}, /* TGS-REQ */ { 12, 2, "msg-type"}, { 12, 3, "padata", 1008}, { 12, 4, "req-body", 1007}, { 13, 0, "pvno"}, /* TGS-REP */ { 13, 1, "msg-type"}, { 13, 2, "padata", 1008}, { 13, 3, "crealm"}, { 13, 4, "cname", 1000}, { 13, 5, "ticket"}, { 13, 6, "enc-part", 1001}, { 14, 0, "pvno"}, /* AP-REQ */ { 14, 1, "msg-type"}, { 14, 2, "ap-options"}, { 14, 3, "ticket"}, { 14, 4, "authenticator", 1001}, { 15, 0, "pvno"}, /* AP-REP */ { 15, 1, "msg-type"}, { 15, 2, "enc-part", 1001}, { 20, 0, "pvno"}, /* KRB-SAFE */ { 20, 1, "msg-type"}, { 20, 2, "safe-body", 1009}, { 20, 3, "cksum", 1006}, { 21, 0, "pvno"}, /* KRB-PRIV */ { 21, 1, "msg-type"}, { 21, 2, "enc-part", 1001}, { 22, 0, "pvno"}, /* KRB-CRED */ { 22, 1, "msg-type"}, { 22, 2, "tickets"}, { 22, 3, "enc-part", 1001}, { 25, 0, "key", 1005}, /* EncASRepPart */ { 25, 1, "last-req", 1010}, { 25, 2, "nonce"}, { 25, 3, "key-expiration"}, { 25, 4, "flags"}, { 25, 5, "authtime"}, { 25, 6, "starttime"}, { 25, 7, "enddtime"}, { 25, 8, "renew-till"}, { 25, 9, "srealm"}, { 25, 10, "sname", 1000}, { 25, 11, "caddr", 1003}, { 26, 0, "key", 1005}, /* EncTGSRepPart */ { 26, 1, "last-req", 1010}, { 26, 2, "nonce"}, { 26, 3, "key-expiration"}, { 26, 4, "flags"}, { 26, 5, "authtime"}, { 26, 6, "starttime"}, { 26, 7, "enddtime"}, { 26, 8, "renew-till"}, { 26, 9, "srealm"}, { 26, 10, "sname", 1000}, { 26, 11, "caddr", 1003}, { 27, 0, "ctime"}, /* EncApRepPart */ { 27, 1, "cusec"}, { 27, 2, "subkey", 1005}, { 27, 3, "seq-number"}, { 28, 0, "user-data"}, /* EncKrbPrivPart */ { 28, 1, "timestamp"}, { 28, 2, "usec"}, { 28, 3, "seq-number"}, { 28, 4, "s-address", 1002}, { 28, 5, "r-address", 1002}, { 29, 0, "ticket-info", 1011}, /* EncKrbCredPart */ { 29, 1, "nonce"}, { 29, 2, "timestamp"}, { 29, 3, "usec"}, { 29, 4, "s-address", 1002}, { 29, 5, "r-address", 1002}, { 30, 0, "pvno"}, /* KRB-ERROR */ { 30, 1, "msg-type"}, { 30, 2, "ctime"}, { 30, 3, "cusec"}, { 30, 4, "stime"}, { 30, 5, "susec"}, { 30, 6, "error-code"}, { 30, 7, "crealm"}, { 30, 8, "cname", 1000}, { 30, 9, "realm"}, { 30, 10, "sname", 1000}, { 30, 11, "e-text"}, { 30, 12, "e-data"}, { -1, -1, 0} }; #endif void print_tag_type(fp, eid, lev) FILE *fp; int eid; int lev; { int tag = eid & ID_TAG; int do_space = 1; char *str; fprintf(fp, "["); switch(eid & ID_CLASS) { case CLASS_UNIV: if (print_types && print_skip_tagnum) do_space = 0; else fprintf(fp, "UNIV %d", tag); break; case CLASS_APPL: current_appl_type = tag; #ifdef KRB5 if (print_krb5_types) { str = lookup_typestring(krb5_types, tag, -1); if (str) { fputs(str, fp); break; } } #endif fprintf(fp, "APPL %d", tag); break; case CLASS_CONT: #ifdef KRB5 if (print_krb5_types && current_appl_type) { str = lookup_typestring(krb5_fields, current_appl_type, tag); if (str) { fputs(str, fp); break; } } #endif if (print_skip_context && lev) fprintf(fp, "%d", tag); else fprintf(fp, "CONT %d", tag); break; case CLASS_PRIV: fprintf(fp, "PRIV %d", tag); break; } if (print_types && ((eid & ID_CLASS) == CLASS_UNIV)) { if (do_space) fputs(" ", fp); str = lookup_typestring(univ_types, eid & ID_TAG, -1); if (str) fputs(str, fp); else fprintf(fp, "UNIV %d???", eid & ID_TAG); } fprintf(fp, "]"); } /*****************************************************************************/ krb5-1.16/src/tests/asn.1/ldap_encode.out0000644000704600001450000000067713211554426020047 0ustar ghudsonlibuuidencode_krb5_ldap_seqof_key_data: 30 81 87 A0 03 02 01 01 A1 03 02 01 01 A2 03 02 01 2A A3 03 02 01 0E A4 71 30 6F 30 23 A0 10 30 0E A0 03 02 01 00 A1 07 04 05 73 61 6C 74 30 A1 0F 30 0D A0 03 02 01 02 A1 06 04 04 6B 65 79 30 30 23 A0 10 30 0E A0 03 02 01 01 A1 07 04 05 73 61 6C 74 31 A1 0F 30 0D A0 03 02 01 02 A1 06 04 04 6B 65 79 31 30 23 A0 10 30 0E A0 03 02 01 02 A1 07 04 05 73 61 6C 74 32 A1 0F 30 0D A0 03 02 01 02 A1 06 04 04 6B 65 79 32 krb5-1.16/src/tests/asn.1/otp.asn10000644000704600001450000000775713211554426016455 0ustar ghudsonlibuuid OTPKerberos DEFINITIONS IMPLICIT TAGS ::= BEGIN IMPORTS KerberosTime, KerberosFlags, EncryptionKey, Int32, EncryptedData, LastReq, KerberosString FROM KerberosV5Spec2 {iso(1) identified-organization(3) dod(6) internet(1) security(5) kerberosV5(2) modules(4) krb5spec2(2)} -- as defined in RFC 4120. AlgorithmIdentifier FROM PKIX1Explicit88 { iso (1) identified-organization (3) dod (6) internet (1) security (5) mechanisms (5) pkix (7) id-mod (0) id-pkix1-explicit (18) }; -- As defined in RFC 5280. PA-OTP-CHALLENGE ::= SEQUENCE { nonce [0] OCTET STRING, otp-service [1] UTF8String OPTIONAL, otp-tokenInfo [2] SEQUENCE (SIZE(1..MAX)) OF OTP-TOKENINFO, salt [3] KerberosString OPTIONAL, s2kparams [4] OCTET STRING OPTIONAL, ... } OTP-TOKENINFO ::= SEQUENCE { flags [0] OTPFlags, otp-vendor [1] UTF8String OPTIONAL, otp-challenge [2] OCTET STRING (SIZE(1..MAX)) OPTIONAL, otp-length [3] Int32 OPTIONAL, otp-format [4] OTPFormat OPTIONAL, otp-tokenID [5] OCTET STRING OPTIONAL, otp-algID [6] AnyURI OPTIONAL, supportedHashAlg [7] SEQUENCE OF AlgorithmIdentifier OPTIONAL, iterationCount [8] Int32 OPTIONAL, ... } OTPFormat ::= INTEGER { decimal(0), hexadecimal(1), alphanumeric(2), binary(3), base64(4) } OTPFlags ::= KerberosFlags -- reserved(0), -- nextOTP(1), -- combine(2), -- collect-pin(3), -- do-not-collect-pin(4), -- must-encrypt-nonce (5), -- separate-pin-required (6), -- check-digit (7) PA-OTP-REQUEST ::= SEQUENCE { flags [0] OTPFlags, nonce [1] OCTET STRING OPTIONAL, encData [2] EncryptedData, -- PA-OTP-ENC-REQUEST or PA-ENC-TS-ENC -- Key usage of KEY_USAGE_OTP_REQUEST hashAlg [3] AlgorithmIdentifier OPTIONAL, iterationCount [4] Int32 OPTIONAL, otp-value [5] OCTET STRING OPTIONAL, otp-pin [6] UTF8String OPTIONAL, otp-challenge [7] OCTET STRING (SIZE(1..MAX)) OPTIONAL, otp-time [8] KerberosTime OPTIONAL, otp-counter [9] OCTET STRING OPTIONAL, otp-format [10] OTPFormat OPTIONAL, otp-tokenID [11] OCTET STRING OPTIONAL, otp-algID [12] AnyURI OPTIONAL, otp-vendor [13] UTF8String OPTIONAL, ... } PA-OTP-ENC-REQUEST ::= SEQUENCE { nonce [0] OCTET STRING, ... } PA-OTP-PIN-CHANGE ::= SEQUENCE { flags [0] PinFlags, pin [1] UTF8String OPTIONAL, minLength [2] INTEGER OPTIONAL, maxLength [3] INTEGER OPTIONAL, last-req [4] LastReq OPTIONAL, format [5] OTPFormat OPTIONAL, ... } PinFlags ::= KerberosFlags -- reserved(0), -- systemSetPin(1), -- mandatory(2) AnyURI ::= UTF8String (CONSTRAINED BY { -- MUST be a valid URI in accordance with IETF RFC 2396 }) END krb5-1.16/src/tests/asn.1/ktest_equal.h0000644000704600001450000001602413211554426017544 0ustar ghudsonlibuuid/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* tests/asn.1/ktest_equal.h */ /* * Copyright (C) 1994 by the Massachusetts Institute of Technology. * All rights reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #ifndef __KTEST_EQUAL_H__ #define __KTEST_EQUAL_H__ #include "k5-int.h" #include "kdb.h" /* int ktest_equal_structure(krb5_structure *ref, *var) */ /* effects Returns true (non-zero) if ref and var are semantically equivalent (i.e. have the same values, but aren't necessarily the same object). Returns false (zero) if ref and var differ. */ #define generic(funcname,type)\ int funcname (type *ref, type *var) #define len_array(funcname,type)\ int funcname (int length, type *ref, type *var) #define len_unsigned_array(funcname,type)\ int funcname (unsigned int length, type *ref, type *var) generic(ktest_equal_authenticator,krb5_authenticator); generic(ktest_equal_principal_data,krb5_principal_data); generic(ktest_equal_checksum,krb5_checksum); generic(ktest_equal_keyblock,krb5_keyblock); generic(ktest_equal_data,krb5_data); generic(ktest_equal_authdata,krb5_authdata); generic(ktest_equal_ticket,krb5_ticket); generic(ktest_equal_enc_tkt_part,krb5_enc_tkt_part); generic(ktest_equal_transited,krb5_transited); generic(ktest_equal_ticket_times,krb5_ticket_times); generic(ktest_equal_address,krb5_address); generic(ktest_equal_enc_data,krb5_enc_data); generic(ktest_equal_enc_kdc_rep_part,krb5_enc_kdc_rep_part); generic(ktest_equal_priv,krb5_priv); generic(ktest_equal_cred,krb5_cred); generic(ktest_equal_error,krb5_error); generic(ktest_equal_ap_req,krb5_ap_req); generic(ktest_equal_ap_rep,krb5_ap_rep); generic(ktest_equal_ap_rep_enc_part,krb5_ap_rep_enc_part); generic(ktest_equal_safe,krb5_safe); generic(ktest_equal_last_req_entry,krb5_last_req_entry); generic(ktest_equal_pa_data,krb5_pa_data); generic(ktest_equal_cred_info,krb5_cred_info); generic(ktest_equal_enc_cred_part,krb5_cred_enc_part); generic(ktest_equal_enc_priv_part,krb5_priv_enc_part); generic(ktest_equal_as_rep,krb5_kdc_rep); generic(ktest_equal_tgs_rep,krb5_kdc_rep); generic(ktest_equal_as_req,krb5_kdc_req); generic(ktest_equal_tgs_req,krb5_kdc_req); generic(ktest_equal_kdc_req_body,krb5_kdc_req); generic(ktest_equal_encryption_key,krb5_keyblock); generic(ktest_equal_krb5_pa_enc_ts,krb5_pa_enc_ts); generic(ktest_equal_sam_challenge_2,krb5_sam_challenge_2); generic(ktest_equal_sam_challenge_2_body,krb5_sam_challenge_2_body); int ktest_equal_last_req(krb5_last_req_entry **ref, krb5_last_req_entry **var); int ktest_equal_sequence_of_ticket(krb5_ticket **ref, krb5_ticket **var); int ktest_equal_sequence_of_pa_data(krb5_pa_data **ref, krb5_pa_data **var); int ktest_equal_sequence_of_cred_info(krb5_cred_info **ref, krb5_cred_info **var); int ktest_equal_sequence_of_principal(krb5_principal *ref, krb5_principal *var); int ktest_equal_sequence_of_checksum(krb5_checksum **ref, krb5_checksum **var); int ktest_equal_sequence_of_algorithm_identifier(krb5_algorithm_identifier **ref, krb5_algorithm_identifier **var); int ktest_equal_sequence_of_otp_tokeninfo(krb5_otp_tokeninfo **ref, krb5_otp_tokeninfo **var); len_array(ktest_equal_array_of_enctype,krb5_enctype); len_array(ktest_equal_array_of_data,krb5_data); len_unsigned_array(ktest_equal_array_of_octet,krb5_octet); int ktest_equal_authorization_data(krb5_authdata **ref, krb5_authdata **var); int ktest_equal_addresses(krb5_address **ref, krb5_address **var); int ktest_equal_array_of_char(const unsigned int length, char *ref, char *var); int ktest_equal_etype_info(krb5_etype_info_entry **ref, krb5_etype_info_entry **var); int ktest_equal_krb5_etype_info_entry(krb5_etype_info_entry *ref, krb5_etype_info_entry *var); int ktest_equal_pa_for_user(krb5_pa_for_user *ref, krb5_pa_for_user *var); int ktest_equal_pa_s4u_x509_user(krb5_pa_s4u_x509_user *ref, krb5_pa_s4u_x509_user *var); int ktest_equal_ad_kdcissued(krb5_ad_kdcissued *ref, krb5_ad_kdcissued *var); int ktest_equal_ad_signedpath_data(krb5_ad_signedpath_data *ref, krb5_ad_signedpath_data *var); int ktest_equal_ad_signedpath(krb5_ad_signedpath *ref, krb5_ad_signedpath *var); int ktest_equal_iakerb_header(krb5_iakerb_header *ref, krb5_iakerb_header *var); int ktest_equal_iakerb_finished(krb5_iakerb_finished *ref, krb5_iakerb_finished *var); int ktest_equal_fast_response(krb5_fast_response *ref, krb5_fast_response *var); int ktest_equal_otp_tokeninfo(krb5_otp_tokeninfo *ref, krb5_otp_tokeninfo *var); int ktest_equal_pa_otp_challenge(krb5_pa_otp_challenge *ref, krb5_pa_otp_challenge *var); int ktest_equal_pa_otp_req(krb5_pa_otp_req *ref, krb5_pa_otp_req *var); int ktest_equal_ldap_sequence_of_keys(ldap_seqof_key_data *ref, ldap_seqof_key_data *var); #ifndef DISABLE_PKINIT generic(ktest_equal_pa_pk_as_req, krb5_pa_pk_as_req); generic(ktest_equal_pa_pk_as_req_draft9, krb5_pa_pk_as_req_draft9); generic(ktest_equal_pa_pk_as_rep, krb5_pa_pk_as_rep); generic(ktest_equal_auth_pack, krb5_auth_pack); generic(ktest_equal_auth_pack_draft9, krb5_auth_pack_draft9); generic(ktest_equal_kdc_dh_key_info, krb5_kdc_dh_key_info); generic(ktest_equal_reply_key_pack, krb5_reply_key_pack); generic(ktest_equal_reply_key_pack_draft9, krb5_reply_key_pack_draft9); #endif /* not DISABLE_PKINIT */ int ktest_equal_kkdcp_message(krb5_kkdcp_message *ref, krb5_kkdcp_message *var); int ktest_equal_cammac(krb5_cammac *ref, krb5_cammac *var); int ktest_equal_secure_cookie(krb5_secure_cookie *ref, krb5_secure_cookie *var); #endif krb5-1.16/src/tests/asn.1/Makefile.in0000644000704600001450000000641213211554426017117 0ustar ghudsonlibuuidmydir=tests$(S)asn.1 BUILDTOP=$(REL)..$(S).. LDAP=@LDAP@ SRCS= $(srcdir)/krb5_encode_test.c $(srcdir)/krb5_decode_test.c \ $(srcdir)/krb5_decode_leak.c $(srcdir)/ktest.c \ $(srcdir)/ktest_equal.c $(srcdir)/utility.c \ $(srcdir)/trval.c $(srcdir)/t_trval.c ASN1SRCS= $(srcdir)/krb5.asn1 $(srcdir)/pkix.asn1 $(srcdir)/otp.asn1 \ $(srcdir)/pkinit.asn1 $(srcdir)/pkinit-agility.asn1 \ $(srcdir)/cammac.asn1 all: krb5_encode_test krb5_decode_test krb5_decode_leak t_trval LOCALINCLUDES = -I$(srcdir)/../../lib/krb5/asn.1 ENCOBJS = krb5_encode_test.o ktest.o ktest_equal.o utility.o trval.o krb5_encode_test: $(ENCOBJS) $(KRB5_BASE_DEPLIBS) $(CC_LINK) -o krb5_encode_test $(ENCOBJS) $(KRB5_BASE_LIBS) DECOBJS = krb5_decode_test.o ktest.o ktest_equal.o utility.o krb5_decode_test: $(DECOBJS) $(KRB5_BASE_DEPLIBS) $(CC_LINK) -o krb5_decode_test $(DECOBJS) $(KRB5_BASE_LIBS) LEAKOBJS = krb5_decode_leak.o ktest.o ktest_equal.o utility.o krb5_decode_leak: $(LEAKOBJS) $(KRB5_BASE_DEPLIBS) $(CC_LINK) -o krb5_decode_leak $(LEAKOBJS) $(KRB5_BASE_LIBS) t_trval: t_trval.o $(CC) -o t_trval $(ALL_CFLAGS) t_trval.o check: check-encode check-encode-trval check-decode check-leak # Does not actually test for leaks unless using valgrind or a similar # tool, but does exercise a bunch of code. check-leak: krb5_decode_leak $(RUN_TEST) ./krb5_decode_leak check-decode: krb5_decode_test $(RUN_TEST) ./krb5_decode_test PKINIT_ENCODE_OUT=$(PKINIT_ENCODE_OUT-@PKINIT@) PKINIT_ENCODE_OUT-yes=$(srcdir)/pkinit_encode.out PKINIT_ENCODE_OUT-no= LDAP_ENCODE_OUT=$(LDAP_ENCODE_OUT-@LDAP@) LDAP_ENCODE_OUT-yes=$(srcdir)/ldap_encode.out LDAP_ENCODE_OUT-no= expected_encode.out: reference_encode.out pkinit_encode.out ldap_encode.out cat $(srcdir)/reference_encode.out $(PKINIT_ENCODE_OUT) \ $(LDAP_ENCODE_OUT) > $@ PKINIT_TRVAL_OUT=$(PKINIT_TRVAL_OUT-@PKINIT@) PKINIT_TRVAL_OUT-yes=$(srcdir)/pkinit_trval.out PKINIT_TRVAL_OUT-no= LDAP_TRVAL_OUT=$(LDAP_TRVAL_OUT-@LDAP@) LDAP_TRVAL_OUT-yes=$(srcdir)/ldap_trval.out LDAP_TRVAL_OUT-no= expected_trval.out: trval_reference.out pkinit_trval.out ldap_trval.out cat $(srcdir)/trval_reference.out $(PKINIT_TRVAL_OUT) \ $(LDAP_TRVAL_OUT) > $@ check-encode: krb5_encode_test expected_encode.out $(RUN_TEST) ./krb5_encode_test > test.out cmp test.out expected_encode.out check-encode-trval: krb5_encode_test expected_trval.out $(RUN_TEST) ./krb5_encode_test -t > trval.out cmp trval.out expected_trval.out # This target uses asn1c to generate encodings of sample objects, to # help ensure that our implementation is correct. asn1c must be in the # path for this to work. test-vectors: $(RM) -r vectors mkdir vectors cp $(ASN1SRCS) $(srcdir)/make-vectors.c vectors (cd vectors && asn1c *.asn1 && rm converter-sample.c) (cd vectors && $(CC) -I. -w *.c -o make-vectors) (cd vectors && ./make-vectors) install: clean: rm -f *~ *.o krb5_encode_test krb5_decode_test krb5_decode_leak test.out trval t_trval expected_encode.out expected_trval.out trval.out ################ Dependencies ################ krb5_decode_test.o: ktest.h utility.h ktest_equal.h debug.h krb5_encode_test.o: utility.h ktest.h debug.h trval.o: trval.c ktest.o: ktest.h utility.h ktest_equal.o: ktest_equal.h #utility.o: utility.h #utility.h: krbasn1.h asn1buf.h ############################################## krb5-1.16/src/tests/asn.1/t_trval.c0000644000704600001450000000705413211554426016674 0ustar ghudsonlibuuid/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* * Copyright (C) 1992,1993 Trusted Information Systems, Inc. * * Permission to include this software in the Kerberos V5 distribution * was graciously provided by Trusted Information Systems. * * Trusted Information Systems makes no representation about the * suitability of this software for any purpose. It is provided * "as is" without express or implied warranty. * * Copyright (C) 1994 Massachusetts Institute of Technology * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ /* Split out from "#ifdef STANDALONE" code previously in trval.c, so that trval.o could be linked into other tests too without the -DSTANDALONE code. */ #include "trval.c" static void usage() { fprintf(stderr, "Usage: trval [--types] [--krb5] [--krb5decode] [--hex] [-notypebytes] [file]\n"); exit(1); } /* * Returns true if the option was selected. Allow "-option" and * "--option" syntax, since we used to accept only "-option" */ static int check_option(word, option) char *word; char *option; { if (word[0] != '-') return 0; if (word[1] == '-') word++; if (strcmp(word+1, option)) return 0; return 1; } int main(argc, argv) int argc; char **argv; { int optflg = 1; FILE *fp; int r = 0; while (--argc > 0) { argv++; if (optflg && *(argv)[0] == '-') { if (check_option(*argv, "help")) usage(); else if (check_option(*argv, "types")) print_types = 1; else if (check_option(*argv, "notypes")) print_types = 0; else if (check_option(*argv, "krb5")) print_krb5_types = 1; else if (check_option(*argv, "hex")) do_hex = 1; else if (check_option(*argv, "notypebytes")) print_id_and_len = 0; else if (check_option(*argv, "krb5decode")) { print_id_and_len = 0; print_krb5_types = 1; print_types = 1; } else { fprintf(stderr,"trval: unknown option: %s\n", *argv); usage(); } } else { optflg = 0; if ((fp = fopen(*argv,"r")) == NULL) { fprintf(stderr,"trval: unable to open %s\n", *argv); continue; } r = trval(fp, stdout); fclose(fp); } } if (optflg) r = trval(stdin, stdout); exit(r); } krb5-1.16/src/tests/asn.1/krb5_decode_test.c0000644000704600001450000025457313211554426020440 0ustar ghudsonlibuuid/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* tests/asn.1/krb5_decode_test.c */ /* * Copyright (C) 1994 by the Massachusetts Institute of Technology. * All rights reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #include "k5-int.h" #include "ktest.h" #include "com_err.h" #include "utility.h" #include "ktest_equal.h" #include "debug.h" #include krb5_context test_context; int error_count = 0; void krb5_ktest_free_enc_data(krb5_context context, krb5_enc_data *val); #ifndef DISABLE_PKINIT static int equal_principal(krb5_principal *ref, krb5_principal var); static void ktest_free_auth_pack(krb5_context context, krb5_auth_pack *val); static void ktest_free_auth_pack_draft9(krb5_context context, krb5_auth_pack_draft9 *val); static void ktest_free_kdc_dh_key_info(krb5_context context, krb5_kdc_dh_key_info *val); static void ktest_free_pa_pk_as_req(krb5_context context, krb5_pa_pk_as_req *val); static void ktest_free_pa_pk_as_rep(krb5_context context, krb5_pa_pk_as_rep *val); static void ktest_free_reply_key_pack(krb5_context context, krb5_reply_key_pack *val); static void ktest_free_reply_key_pack_draft9(krb5_context context, krb5_reply_key_pack_draft9 *val); #endif static void ktest_free_kkdcp_message(krb5_context context, krb5_kkdcp_message *val); int main(argc, argv) int argc; char **argv; { krb5_data code; krb5_error_code retval; retval = krb5_init_context(&test_context); if (retval) { com_err(argv[0], retval, "while initializing krb5"); exit(1); } init_access(argv[0]); #define setup(type,constructor) \ type ref, *var; \ constructor(&ref); \ #define decode_run(typestring,description,encoding,decoder,comparator,cleanup) \ retval = krb5_data_hex_parse(&code,encoding); \ if (retval) { \ com_err("krb5_decode_test", retval, "while parsing %s", typestring); \ exit(1); \ } \ retval = decoder(&code,&var); \ if (retval) { \ com_err("krb5_decode_test", retval, "while decoding %s", typestring); \ error_count++; \ } \ test(comparator(&ref,var),typestring); \ printf("%s\n",description); \ krb5_free_data_contents(test_context, &code); \ cleanup(test_context, var); /****************************************************************/ /* decode_krb5_authenticator */ { setup(krb5_authenticator,ktest_make_sample_authenticator); decode_run("authenticator","","62 81 A1 30 81 9E A0 03 02 01 05 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A3 0F 30 0D A0 03 02 01 01 A1 06 04 04 31 32 33 34 A4 05 02 03 01 E2 40 A5 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A6 13 30 11 A0 03 02 01 01 A1 0A 04 08 31 32 33 34 35 36 37 38 A7 03 02 01 11 A8 24 30 22 30 0F A0 03 02 01 01 A1 08 04 06 66 6F 6F 62 61 72 30 0F A0 03 02 01 01 A1 08 04 06 66 6F 6F 62 61 72",decode_krb5_authenticator,ktest_equal_authenticator,krb5_free_authenticator); ref.seq_number = 0xffffff80; decode_run("authenticator","(80 -> seq-number 0xffffff80)", "62 81 A1 30 81 9E" " A0 03 02 01 05" " A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55" " A2 1A 30 18" " A0 03 02 01 01" " A1 11 30 0F" " 1B 06 68 66 74 73 61 69" " 1B 05 65 78 74 72 61" " A3 0F 30 0D" " A0 03 02 01 01" " A1 06 04 04 31 32 33 34" " A4 05 02 03 01 E2 40" " A5 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A" " A6 13 30 11" " A0 03 02 01 01" " A1 0A 04 08 31 32 33 34 35 36 37 38" " A7 03 02 01 80" " A8 24 30 22" " 30 0F" " A0 03 02 01 01" " A1 08 04 06 66 6F 6F 62 61 72" " 30 0F" " A0 03 02 01 01" " A1 08 04 06 66 6F 6F 62 61 72" ,decode_krb5_authenticator,ktest_equal_authenticator,krb5_free_authenticator); ref.seq_number = 0xffffffff; decode_run("authenticator","(FF -> seq-number 0xffffffff)", "62 81 A1 30 81 9E" " A0 03 02 01 05" " A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55" " A2 1A 30 18" " A0 03 02 01 01" " A1 11 30 0F" " 1B 06 68 66 74 73 61 69" " 1B 05 65 78 74 72 61" " A3 0F 30 0D" " A0 03 02 01 01" " A1 06 04 04 31 32 33 34" " A4 05 02 03 01 E2 40" " A5 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A" " A6 13 30 11" " A0 03 02 01 01" " A1 0A 04 08 31 32 33 34 35 36 37 38" " A7 03 02 01 FF" " A8 24 30 22" " 30 0F" " A0 03 02 01 01" " A1 08 04 06 66 6F 6F 62 61 72" " 30 0F" " A0 03 02 01 01" " A1 08 04 06 66 6F 6F 62 61 72" ,decode_krb5_authenticator,ktest_equal_authenticator,krb5_free_authenticator); ref.seq_number = 0xff; decode_run("authenticator","(00FF -> seq-number 0xff)", "62 81 A2 30 81 9F" " A0 03 02 01 05" " A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55" " A2 1A 30 18" " A0 03 02 01 01" " A1 11 30 0F" " 1B 06 68 66 74 73 61 69" " 1B 05 65 78 74 72 61" " A3 0F 30 0D" " A0 03 02 01 01" " A1 06 04 04 31 32 33 34" " A4 05 02 03 01 E2 40" " A5 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A" " A6 13 30 11" " A0 03 02 01 01" " A1 0A 04 08 31 32 33 34 35 36 37 38" " A7 04 02 02 00 FF" " A8 24 30 22" " 30 0F" " A0 03 02 01 01" " A1 08 04 06 66 6F 6F 62 61 72" " 30 0F" " A0 03 02 01 01" " A1 08 04 06 66 6F 6F 62 61 72" ,decode_krb5_authenticator,ktest_equal_authenticator,krb5_free_authenticator); ref.seq_number = 0xffffffff; decode_run("authenticator","(00FFFFFFFF -> seq-number 0xffffffff)", "62 81 A5 30 81 A2" " A0 03 02 01 05" " A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55" " A2 1A 30 18" " A0 03 02 01 01" " A1 11 30 0F" " 1B 06 68 66 74 73 61 69" " 1B 05 65 78 74 72 61" " A3 0F 30 0D" " A0 03 02 01 01" " A1 06 04 04 31 32 33 34" " A4 05 02 03 01 E2 40" " A5 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A" " A6 13 30 11" " A0 03 02 01 01" " A1 0A 04 08 31 32 33 34 35 36 37 38" " A7 07 02 05 00 FF FF FF FF" " A8 24 30 22" " 30 0F" " A0 03 02 01 01" " A1 08 04 06 66 6F 6F 62 61 72" " 30 0F" " A0 03 02 01 01" " A1 08 04 06 66 6F 6F 62 61 72" ,decode_krb5_authenticator,ktest_equal_authenticator,krb5_free_authenticator); ref.seq_number = 0x7fffffff; decode_run("authenticator","(7FFFFFFF -> seq-number 0x7fffffff)", "62 81 A4 30 81 A1" " A0 03 02 01 05" " A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55" " A2 1A 30 18" " A0 03 02 01 01" " A1 11 30 0F" " 1B 06 68 66 74 73 61 69" " 1B 05 65 78 74 72 61" " A3 0F 30 0D" " A0 03 02 01 01" " A1 06 04 04 31 32 33 34" " A4 05 02 03 01 E2 40" " A5 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A" " A6 13 30 11" " A0 03 02 01 01" " A1 0A 04 08 31 32 33 34 35 36 37 38" " A7 06 02 04 7F FF FF FF" " A8 24 30 22" " 30 0F" " A0 03 02 01 01" " A1 08 04 06 66 6F 6F 62 61 72" " 30 0F" " A0 03 02 01 01" " A1 08 04 06 66 6F 6F 62 61 72" ,decode_krb5_authenticator,ktest_equal_authenticator,krb5_free_authenticator); ref.seq_number = 0xffffffff; decode_run("authenticator","(FFFFFFFF -> seq-number 0xffffffff)", "62 81 A4 30 81 A1" " A0 03 02 01 05" " A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55" " A2 1A 30 18" " A0 03 02 01 01" " A1 11 30 0F" " 1B 06 68 66 74 73 61 69" " 1B 05 65 78 74 72 61" " A3 0F 30 0D" " A0 03 02 01 01" " A1 06 04 04 31 32 33 34" " A4 05 02 03 01 E2 40" " A5 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A" " A6 13 30 11" " A0 03 02 01 01" " A1 0A 04 08 31 32 33 34 35 36 37 38" " A7 06 02 04 FF FF FF FF" " A8 24 30 22" " 30 0F" " A0 03 02 01 01" " A1 08 04 06 66 6F 6F 62 61 72" " 30 0F" " A0 03 02 01 01" " A1 08 04 06 66 6F 6F 62 61 72" ,decode_krb5_authenticator,ktest_equal_authenticator,krb5_free_authenticator); ktest_destroy_checksum(&(ref.checksum)); ktest_destroy_keyblock(&(ref.subkey)); ref.seq_number = 0; ktest_empty_authorization_data(ref.authorization_data); decode_run("authenticator","(optionals empty)","62 4F 30 4D A0 03 02 01 05 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A4 05 02 03 01 E2 40 A5 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A",decode_krb5_authenticator,ktest_equal_authenticator,krb5_free_authenticator); ktest_destroy_authorization_data(&(ref.authorization_data)); decode_run("authenticator","(optionals NULL)","62 4F 30 4D A0 03 02 01 05 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A4 05 02 03 01 E2 40 A5 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A",decode_krb5_authenticator,ktest_equal_authenticator,krb5_free_authenticator); ktest_empty_authenticator(&ref); } /****************************************************************/ /* decode_krb5_ticket */ { setup(krb5_ticket,ktest_make_sample_ticket); decode_run("ticket","","61 5C 30 5A A0 03 02 01 05 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A3 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65",decode_krb5_ticket,ktest_equal_ticket,krb5_free_ticket); decode_run("ticket","(+ trailing [4] INTEGER","61 61 30 5F A0 03 02 01 05 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A3 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65 A4 03 02 01 01",decode_krb5_ticket,ktest_equal_ticket,krb5_free_ticket); /* "61 80 30 80 " " A0 03 02 01 05 " " A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 " " A2 80 30 80 " " A0 03 02 01 01 " " A1 80 30 80 " " 1B 06 68 66 74 73 61 69 " " 1B 05 65 78 74 72 61 " " 00 00 00 00 " " 00 00 00 00 " " A3 80 30 80 " " A0 03 02 01 00 " " A1 03 02 01 05 " " A2 17 04 15 6B 72 62 41 53 4E 2E 31 " " 20 74 65 73 74 20 6D 65 73 73 61 67 65 " " 00 00 00 00" "00 00 00 00" */ decode_run("ticket","(indefinite lengths)", "61 80 30 80 A0 03 02 01 05 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 80 30 80 A0 03 02 01 01 A1 80 30 80 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 00 00 00 00 00 00 00 00 A3 80 30 80 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65 00 00 00 00 00 00 00 00" ,decode_krb5_ticket,ktest_equal_ticket,krb5_free_ticket); /* "61 80 30 80 " " A0 03 02 01 05 " " A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 " " A2 80 30 80 " " A0 03 02 01 01 " " A1 80 30 80 " " 1B 06 68 66 74 73 61 69 " " 1B 05 65 78 74 72 61 " " 00 00 00 00 " " 00 00 00 00 " " A3 80 30 80 " " A0 03 02 01 00 " " A1 03 02 01 05 " " A2 17 04 15 6B 72 62 41 53 4E 2E 31 " " 20 74 65 73 74 20 6D 65 73 73 61 67 65 " " 00 00 00 00" " A4 03 02 01 01 " "00 00 00 00" */ decode_run("ticket","(indefinite lengths + trailing [4] INTEGER)", "61 80 30 80 A0 03 02 01 05 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 80 30 80 A0 03 02 01 01 A1 80 30 80 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 00 00 00 00 00 00 00 00 A3 80 30 80 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65 00 00 00 00 A4 03 02 01 01 00 00 00 00",decode_krb5_ticket,ktest_equal_ticket,krb5_free_ticket); ktest_empty_ticket(&ref); } /****************************************************************/ /* decode_krb5_encryption_key */ { setup(krb5_keyblock,ktest_make_sample_keyblock); decode_run("encryption_key","","30 11 A0 03 02 01 01 A1 0A 04 08 31 32 33 34 35 36 37 38",decode_krb5_encryption_key,ktest_equal_encryption_key,krb5_free_keyblock); decode_run("encryption_key","(+ trailing [2] INTEGER)","30 16 A0 03 02 01 01 A1 0A 04 08 31 32 33 34 35 36 37 38 A2 03 02 01 01",decode_krb5_encryption_key,ktest_equal_encryption_key,krb5_free_keyblock); decode_run("encryption_key","(+ trailing [2] SEQUENCE {[0] INTEGER})","30 1A A0 03 02 01 01 A1 0A 04 08 31 32 33 34 35 36 37 38 A2 07 30 05 A0 03 02 01 01",decode_krb5_encryption_key,ktest_equal_encryption_key,krb5_free_keyblock); decode_run("encryption_key","(indefinite lengths)","30 80 A0 03 02 01 01 A1 0A 04 08 31 32 33 34 35 36 37 38 00 00",decode_krb5_encryption_key,ktest_equal_encryption_key,krb5_free_keyblock); decode_run("encryption_key","(indefinite lengths + trailing [2] INTEGER)","30 80 A0 03 02 01 01 A1 0A 04 08 31 32 33 34 35 36 37 38 A2 03 02 01 01 00 00",decode_krb5_encryption_key,ktest_equal_encryption_key,krb5_free_keyblock); decode_run("encryption_key","(indefinite lengths + trailing [2] SEQUENCE {[0] INTEGER})","30 80 A0 03 02 01 01 A1 0A 04 08 31 32 33 34 35 36 37 38 A2 80 30 80 A0 03 02 01 01 00 00 00 00 00 00",decode_krb5_encryption_key,ktest_equal_encryption_key,krb5_free_keyblock); decode_run("encryption_key","(indefinite lengths + trailing SEQUENCE {[0] INTEGER})","30 80 A0 03 02 01 01 A1 0A 04 08 31 32 33 34 35 36 37 38 30 80 A0 03 02 01 01 00 00 00 00",decode_krb5_encryption_key,ktest_equal_encryption_key,krb5_free_keyblock); ref.enctype = -1; decode_run("encryption_key","(enctype = -1)","30 11 A0 03 02 01 FF A1 0A 04 08 31 32 33 34 35 36 37 38",decode_krb5_encryption_key,ktest_equal_encryption_key,krb5_free_keyblock); ref.enctype = -255; decode_run("encryption_key","(enctype = -255)","30 12 A0 04 02 02 FF 01 A1 0A 04 08 31 32 33 34 35 36 37 38",decode_krb5_encryption_key,ktest_equal_encryption_key,krb5_free_keyblock); ref.enctype = 255; decode_run("encryption_key","(enctype = 255)","30 12 A0 04 02 02 00 FF A1 0A 04 08 31 32 33 34 35 36 37 38",decode_krb5_encryption_key,ktest_equal_encryption_key,krb5_free_keyblock); ref.enctype = -2147483648U; decode_run("encryption_key","(enctype = -2147483648)","30 14 A0 06 02 04 80 00 00 00 A1 0A 04 08 31 32 33 34 35 36 37 38",decode_krb5_encryption_key,ktest_equal_encryption_key,krb5_free_keyblock); ref.enctype = 2147483647; decode_run("encryption_key","(enctype = 2147483647)","30 14 A0 06 02 04 7F FF FF FF A1 0A 04 08 31 32 33 34 35 36 37 38",decode_krb5_encryption_key,ktest_equal_encryption_key,krb5_free_keyblock); ktest_empty_keyblock(&ref); } /****************************************************************/ /* decode_krb5_enc_tkt_part */ { setup(krb5_enc_tkt_part,ktest_make_sample_enc_tkt_part); decode_run("enc_tkt_part","","63 82 01 14 30 82 01 10 A0 07 03 05 00 FE DC BA 98 A1 13 30 11 A0 03 02 01 01 A1 0A 04 08 31 32 33 34 35 36 37 38 A2 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A3 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A4 2E 30 2C A0 03 02 01 01 A1 25 04 23 45 44 55 2C 4D 49 54 2E 2C 41 54 48 45 4E 41 2E 2C 57 41 53 48 49 4E 47 54 4F 4E 2E 45 44 55 2C 43 53 2E A5 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A6 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A7 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A8 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A9 20 30 1E 30 0D A0 03 02 01 02 A1 06 04 04 12 D0 00 23 30 0D A0 03 02 01 02 A1 06 04 04 12 D0 00 23 AA 24 30 22 30 0F A0 03 02 01 01 A1 08 04 06 66 6F 6F 62 61 72 30 0F A0 03 02 01 01 A1 08 04 06 66 6F 6F 62 61 72",decode_krb5_enc_tkt_part,ktest_equal_enc_tkt_part,krb5_free_enc_tkt_part); ref.times.starttime = 0; ref.times.renew_till = 0; ktest_destroy_address(&(ref.caddrs[1])); ktest_destroy_address(&(ref.caddrs[0])); ktest_destroy_authdata(&(ref.authorization_data[1])); ktest_destroy_authdata(&(ref.authorization_data[0])); /* ISODE version fails on the empty caddrs field */ ktest_destroy_addresses(&(ref.caddrs)); ktest_destroy_authorization_data(&(ref.authorization_data)); decode_run("enc_tkt_part","(optionals NULL)","63 81 A5 30 81 A2 A0 07 03 05 00 FE DC BA 98 A1 13 30 11 A0 03 02 01 01 A1 0A 04 08 31 32 33 34 35 36 37 38 A2 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A3 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A4 2E 30 2C A0 03 02 01 01 A1 25 04 23 45 44 55 2C 4D 49 54 2E 2C 41 54 48 45 4E 41 2E 2C 57 41 53 48 49 4E 47 54 4F 4E 2E 45 44 55 2C 43 53 2E A5 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A7 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A",decode_krb5_enc_tkt_part,ktest_equal_enc_tkt_part, krb5_free_enc_tkt_part); decode_run("enc_tkt_part","(optionals NULL + bitstring enlarged to 38 bits)","63 81 A6 30 81 A3 A0 08 03 06 02 FE DC BA 98 DC A1 13 30 11 A0 03 02 01 01 A1 0A 04 08 31 32 33 34 35 36 37 38 A2 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A3 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A4 2E 30 2C A0 03 02 01 01 A1 25 04 23 45 44 55 2C 4D 49 54 2E 2C 41 54 48 45 4E 41 2E 2C 57 41 53 48 49 4E 47 54 4F 4E 2E 45 44 55 2C 43 53 2E A5 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A7 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A",decode_krb5_enc_tkt_part,ktest_equal_enc_tkt_part,krb5_free_enc_tkt_part); decode_run("enc_tkt_part","(optionals NULL + bitstring enlarged to 40 bits)","63 81 A6 30 81 A3 A0 08 03 06 00 FE DC BA 98 DE A1 13 30 11 A0 03 02 01 01 A1 0A 04 08 31 32 33 34 35 36 37 38 A2 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A3 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A4 2E 30 2C A0 03 02 01 01 A1 25 04 23 45 44 55 2C 4D 49 54 2E 2C 41 54 48 45 4E 41 2E 2C 57 41 53 48 49 4E 47 54 4F 4E 2E 45 44 55 2C 43 53 2E A5 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A7 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A",decode_krb5_enc_tkt_part,ktest_equal_enc_tkt_part,krb5_free_enc_tkt_part); decode_run("enc_tkt_part","(optionals NULL + bitstring reduced to 29 bits)","63 81 A5 30 81 A2 A0 07 03 05 03 FE DC BA 98 A1 13 30 11 A0 03 02 01 01 A1 0A 04 08 31 32 33 34 35 36 37 38 A2 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A3 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A4 2E 30 2C A0 03 02 01 01 A1 25 04 23 45 44 55 2C 4D 49 54 2E 2C 41 54 48 45 4E 41 2E 2C 57 41 53 48 49 4E 47 54 4F 4E 2E 45 44 55 2C 43 53 2E A5 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A7 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A",decode_krb5_enc_tkt_part,ktest_equal_enc_tkt_part,krb5_free_enc_tkt_part); ref.flags &= 0xFFFFFF00; decode_run("enc_tkt_part","(optionals NULL + bitstring reduced to 24 bits)","63 81 A4 30 81 A1 A0 06 03 04 00 FE DC BA A1 13 30 11 A0 03 02 01 01 A1 0A 04 08 31 32 33 34 35 36 37 38 A2 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A3 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A4 2E 30 2C A0 03 02 01 01 A1 25 04 23 45 44 55 2C 4D 49 54 2E 2C 41 54 48 45 4E 41 2E 2C 57 41 53 48 49 4E 47 54 4F 4E 2E 45 44 55 2C 43 53 2E A5 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A7 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A",decode_krb5_enc_tkt_part,ktest_equal_enc_tkt_part,krb5_free_enc_tkt_part); ktest_empty_enc_tkt_part(&ref); } /****************************************************************/ /* decode_krb5_enc_kdc_rep_part */ { setup(krb5_enc_kdc_rep_part,ktest_make_sample_enc_kdc_rep_part); #ifdef KRB5_GENEROUS_LR_TYPE decode_run("enc_kdc_rep_part","(compat_lr_type)","7A 82 01 10 30 82 01 0C A0 13 30 11 A0 03 02 01 01 A1 0A 04 08 31 32 33 34 35 36 37 38 A1 38 30 36 30 19 A0 04 02 02 00 FB A1 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A 30 19 A0 04 02 02 00 FB A1 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A2 03 02 01 2A A3 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A4 07 03 05 00 FE DC BA 98 A5 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A6 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A7 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A8 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A9 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 AA 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 AB 20 30 1E 30 0D A0 03 02 01 02 A1 06 04 04 12 D0 00 23 30 0D A0 03 02 01 02 A1 06 04 04 12 D0 00 23",decode_krb5_enc_kdc_rep_part,ktest_equal_enc_kdc_rep_part,krb5_free_enc_kdc_rep_part); #endif decode_run("enc_kdc_rep_part","","7A 82 01 0E 30 82 01 0A A0 13 30 11 A0 03 02 01 01 A1 0A 04 08 31 32 33 34 35 36 37 38 A1 36 30 34 30 18 A0 03 02 01 FB A1 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A 30 18 A0 03 02 01 FB A1 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A2 03 02 01 2A A3 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A4 07 03 05 00 FE DC BA 98 A5 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A6 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A7 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A8 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A9 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 AA 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 AB 20 30 1E 30 0D A0 03 02 01 02 A1 06 04 04 12 D0 00 23 30 0D A0 03 02 01 02 A1 06 04 04 12 D0 00 23",decode_krb5_enc_kdc_rep_part,ktest_equal_enc_kdc_rep_part,krb5_free_enc_kdc_rep_part); ref.key_exp = 0; /* ref.times.starttime = 0;*/ ref.times.starttime = ref.times.authtime; ref.times.renew_till = 0; ref.flags &= ~TKT_FLG_RENEWABLE; ktest_destroy_addresses(&(ref.caddrs)); #ifdef KRB5_GENEROUS_LR_TYPE decode_run("enc_kdc_rep_part","(optionals NULL)(compat lr_type)","7A 81 B4 30 81 B1 A0 13 30 11 A0 03 02 01 01 A1 0A 04 08 31 32 33 34 35 36 37 38 A1 38 30 36 30 19 A0 04 02 02 00 FB A1 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A 30 19 A0 04 02 02 00 FB A1 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A2 03 02 01 2A A4 07 03 05 00 FE 5C BA 98 A5 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A7 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A9 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 AA 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61",decode_krb5_enc_kdc_rep_part,ktest_equal_enc_kdc_rep_part,krb5_free_enc_kdc_rep_part); #endif decode_run("enc_kdc_rep_part","(optionals NULL)","7A 81 B2 30 81 AF A0 13 30 11 A0 03 02 01 01 A1 0A 04 08 31 32 33 34 35 36 37 38 A1 36 30 34 30 18 A0 03 02 01 FB A1 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A 30 18 A0 03 02 01 FB A1 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A2 03 02 01 2A A4 07 03 05 00 FE 5C BA 98 A5 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A7 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A9 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 AA 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61",decode_krb5_enc_kdc_rep_part,ktest_equal_enc_kdc_rep_part,krb5_free_enc_kdc_rep_part); ktest_empty_enc_kdc_rep_part(&ref); } /****************************************************************/ /* decode_krb5_as_rep */ { setup(krb5_kdc_rep,ktest_make_sample_kdc_rep); ref.msg_type = KRB5_AS_REP; decode_run("as_rep","","6B 81 EA 30 81 E7 A0 03 02 01 05 A1 03 02 01 0B A2 26 30 24 30 10 A1 03 02 01 0D A2 09 04 07 70 61 2D 64 61 74 61 30 10 A1 03 02 01 0D A2 09 04 07 70 61 2D 64 61 74 61 A3 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A4 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A5 5E 61 5C 30 5A A0 03 02 01 05 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A3 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65 A6 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65",decode_krb5_as_rep,ktest_equal_as_rep,krb5_free_kdc_rep); /* 6B 80 30 80 A0 03 02 01 05 A1 03 02 01 0B A2 80 30 80 30 80 A1 03 02 01 0D A2 09 04 07 70 61 2D 64 61 74 61 00 00 30 80 A1 03 02 01 0D A2 09 04 07 70 61 2D 64 61 74 61 00 00 00 00 00 00 A3 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A4 80 30 80 A0 03 02 01 01 A1 80 30 80 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 00 00 00 00 00 00 00 00 A5 80 61 80 30 80 A0 03 02 01 05 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 80 30 80 A0 03 02 01 01 A1 80 30 80 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 00 00 00 00 00 00 00 00 A3 80 30 80 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65 00 00 00 00 00 00 00 00 00 00 A6 80 30 80 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65 00 00 00 00 00 00 00 00 */ decode_run("as_rep","(indefinite lengths)","6B 80 30 80 A0 03 02 01 05 A1 03 02 01 0B A2 80 30 80 30 80 A1 03 02 01 0D A2 09 04 07 70 61 2D 64 61 74 61 00 00 30 80 A1 03 02 01 0D A2 09 04 07 70 61 2D 64 61 74 61 00 00 00 00 00 00 A3 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A4 80 30 80 A0 03 02 01 01 A1 80 30 80 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 00 00 00 00 00 00 00 00 A5 80 61 80 30 80 A0 03 02 01 05 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 80 30 80 A0 03 02 01 01 A1 80 30 80 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 00 00 00 00 00 00 00 00 A3 80 30 80 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65 00 00 00 00 00 00 00 00 00 00 A6 80 30 80 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65 00 00 00 00 00 00 00 00",decode_krb5_as_rep,ktest_equal_as_rep,krb5_free_kdc_rep); ktest_destroy_pa_data_array(&(ref.padata)); decode_run("as_rep","(optionals NULL)","6B 81 C2 30 81 BF A0 03 02 01 05 A1 03 02 01 0B A3 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A4 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A5 5E 61 5C 30 5A A0 03 02 01 05 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A3 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65 A6 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65",decode_krb5_as_rep,ktest_equal_as_rep,krb5_free_kdc_rep); ktest_empty_kdc_rep(&ref); } /****************************************************************/ /* decode_krb5_tgs_rep */ { setup(krb5_kdc_rep,ktest_make_sample_kdc_rep); ref.msg_type = KRB5_TGS_REP; decode_run("tgs_rep","","6D 81 EA 30 81 E7 A0 03 02 01 05 A1 03 02 01 0D A2 26 30 24 30 10 A1 03 02 01 0D A2 09 04 07 70 61 2D 64 61 74 61 30 10 A1 03 02 01 0D A2 09 04 07 70 61 2D 64 61 74 61 A3 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A4 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A5 5E 61 5C 30 5A A0 03 02 01 05 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A3 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65 A6 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65",decode_krb5_tgs_rep,ktest_equal_tgs_rep,krb5_free_kdc_rep); ktest_destroy_pa_data_array(&(ref.padata)); decode_run("tgs_rep","(optionals NULL)","6D 81 C2 30 81 BF A0 03 02 01 05 A1 03 02 01 0D A3 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A4 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A5 5E 61 5C 30 5A A0 03 02 01 05 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A3 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65 A6 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65",decode_krb5_tgs_rep,ktest_equal_tgs_rep,krb5_free_kdc_rep); ktest_empty_kdc_rep(&ref); } /****************************************************************/ /* decode_krb5_ap_req */ { setup(krb5_ap_req,ktest_make_sample_ap_req); decode_run("ap_req","","6E 81 9D 30 81 9A A0 03 02 01 05 A1 03 02 01 0E A2 07 03 05 00 FE DC BA 98 A3 5E 61 5C 30 5A A0 03 02 01 05 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A3 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65 A4 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65",decode_krb5_ap_req,ktest_equal_ap_req,krb5_free_ap_req); ktest_empty_ap_req(&ref); } /****************************************************************/ /* decode_krb5_ap_rep */ { setup(krb5_ap_rep,ktest_make_sample_ap_rep); decode_run("ap_rep","","6F 33 30 31 A0 03 02 01 05 A1 03 02 01 0F A2 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65",decode_krb5_ap_rep,ktest_equal_ap_rep,krb5_free_ap_rep); ktest_empty_ap_rep(&ref); } /****************************************************************/ /* decode_krb5_ap_rep_enc_part */ { setup(krb5_ap_rep_enc_part,ktest_make_sample_ap_rep_enc_part); decode_run("ap_rep_enc_part","","7B 36 30 34 A0 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A1 05 02 03 01 E2 40 A2 13 30 11 A0 03 02 01 01 A1 0A 04 08 31 32 33 34 35 36 37 38 A3 03 02 01 11",decode_krb5_ap_rep_enc_part,ktest_equal_ap_rep_enc_part,krb5_free_ap_rep_enc_part); ktest_destroy_keyblock(&(ref.subkey)); ref.seq_number = 0; decode_run("ap_rep_enc_part","(optionals NULL)","7B 1C 30 1A A0 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A1 05 02 03 01 E2 40",decode_krb5_ap_rep_enc_part,ktest_equal_ap_rep_enc_part,krb5_free_ap_rep_enc_part); retval = krb5_data_hex_parse(&code, "7B 06 30 04 A0 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A1 05 02 03 01 E2 40"); if (retval) { com_err("krb5_decode_test", retval, "while parsing"); exit(1); } retval = decode_krb5_ap_rep_enc_part(&code, &var); if (retval != ASN1_OVERRUN) { printf("ERROR: "); error_count++; } else { printf("OK: "); } printf("ap_rep_enc_part(optionals NULL + expect ASN1_OVERRUN for inconsistent length of timestamp)\n"); krb5_free_data_contents(test_context, &code); krb5_free_ap_rep_enc_part(test_context, var); ktest_empty_ap_rep_enc_part(&ref); } /****************************************************************/ /* decode_krb5_as_req */ { setup(krb5_kdc_req,ktest_make_sample_kdc_req); ref.msg_type = KRB5_AS_REQ; ref.kdc_options &= ~KDC_OPT_ENC_TKT_IN_SKEY; decode_run("as_req","","6A 82 01 E4 30 82 01 E0 A1 03 02 01 05 A2 03 02 01 0A A3 26 30 24 30 10 A1 03 02 01 0D A2 09 04 07 70 61 2D 64 61 74 61 30 10 A1 03 02 01 0D A2 09 04 07 70 61 2D 64 61 74 61 A4 82 01 AA 30 82 01 A6 A0 07 03 05 00 FE DC BA 90 A1 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A2 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A3 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A4 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A5 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A6 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A7 03 02 01 2A A8 08 30 06 02 01 00 02 01 01 A9 20 30 1E 30 0D A0 03 02 01 02 A1 06 04 04 12 D0 00 23 30 0D A0 03 02 01 02 A1 06 04 04 12 D0 00 23 AA 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65 AB 81 BF 30 81 BC 61 5C 30 5A A0 03 02 01 05 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A3 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65 61 5C 30 5A A0 03 02 01 05 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A3 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65",decode_krb5_as_req,ktest_equal_as_req,krb5_free_kdc_req); ktest_destroy_pa_data_array(&(ref.padata)); ktest_destroy_principal(&(ref.client)); #ifndef ISODE_SUCKS ktest_destroy_principal(&(ref.server)); #endif ref.kdc_options |= KDC_OPT_ENC_TKT_IN_SKEY; ref.from = 0; ref.rtime = 0; ktest_destroy_addresses(&(ref.addresses)); ktest_destroy_enc_data(&(ref.authorization_data)); decode_run("as_req","(optionals NULL except second_ticket)","6A 82 01 14 30 82 01 10 A1 03 02 01 05 A2 03 02 01 0A A4 82 01 02 30 81 FF A0 07 03 05 00 FE DC BA 98 A2 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A5 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A7 03 02 01 2A A8 08 30 06 02 01 00 02 01 01 AB 81 BF 30 81 BC 61 5C 30 5A A0 03 02 01 05 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A3 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65 61 5C 30 5A A0 03 02 01 05 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A3 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65",decode_krb5_as_req,ktest_equal_as_req,krb5_free_kdc_req); ktest_destroy_sequence_of_ticket(&(ref.second_ticket)); #ifndef ISODE_SUCKS ktest_make_sample_principal(&(ref.server)); #endif ref.kdc_options &= ~KDC_OPT_ENC_TKT_IN_SKEY; decode_run("as_req","(optionals NULL except server)","6A 69 30 67 A1 03 02 01 05 A2 03 02 01 0A A4 5B 30 59 A0 07 03 05 00 FE DC BA 90 A2 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A3 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A5 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A7 03 02 01 2A A8 08 30 06 02 01 00 02 01 01",decode_krb5_as_req,ktest_equal_as_req,krb5_free_kdc_req); ktest_empty_kdc_req(&ref); } /****************************************************************/ /* decode_krb5_tgs_req */ { setup(krb5_kdc_req,ktest_make_sample_kdc_req); ref.msg_type = KRB5_TGS_REQ; ref.kdc_options &= ~KDC_OPT_ENC_TKT_IN_SKEY; decode_run("tgs_req","","6C 82 01 E4 30 82 01 E0 A1 03 02 01 05 A2 03 02 01 0C A3 26 30 24 30 10 A1 03 02 01 0D A2 09 04 07 70 61 2D 64 61 74 61 30 10 A1 03 02 01 0D A2 09 04 07 70 61 2D 64 61 74 61 A4 82 01 AA 30 82 01 A6 A0 07 03 05 00 FE DC BA 90 A1 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A2 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A3 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A4 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A5 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A6 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A7 03 02 01 2A A8 08 30 06 02 01 00 02 01 01 A9 20 30 1E 30 0D A0 03 02 01 02 A1 06 04 04 12 D0 00 23 30 0D A0 03 02 01 02 A1 06 04 04 12 D0 00 23 AA 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65 AB 81 BF 30 81 BC 61 5C 30 5A A0 03 02 01 05 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A3 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65 61 5C 30 5A A0 03 02 01 05 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A3 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65",decode_krb5_tgs_req,ktest_equal_tgs_req,krb5_free_kdc_req); ktest_destroy_pa_data_array(&(ref.padata)); ktest_destroy_principal(&(ref.client)); #ifndef ISODE_SUCKS ktest_destroy_principal(&(ref.server)); #endif ref.kdc_options |= KDC_OPT_ENC_TKT_IN_SKEY; ref.from = 0; ref.rtime = 0; ktest_destroy_addresses(&(ref.addresses)); ktest_destroy_enc_data(&(ref.authorization_data)); decode_run("tgs_req","(optionals NULL except second_ticket)","6C 82 01 14 30 82 01 10 A1 03 02 01 05 A2 03 02 01 0C A4 82 01 02 30 81 FF A0 07 03 05 00 FE DC BA 98 A2 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A5 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A7 03 02 01 2A A8 08 30 06 02 01 00 02 01 01 AB 81 BF 30 81 BC 61 5C 30 5A A0 03 02 01 05 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A3 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65 61 5C 30 5A A0 03 02 01 05 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A3 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65",decode_krb5_tgs_req,ktest_equal_tgs_req,krb5_free_kdc_req); ktest_destroy_sequence_of_ticket(&(ref.second_ticket)); #ifndef ISODE_SUCKS ktest_make_sample_principal(&(ref.server)); #endif ref.kdc_options &= ~KDC_OPT_ENC_TKT_IN_SKEY; decode_run("tgs_req","(optionals NULL except server)","6C 69 30 67 A1 03 02 01 05 A2 03 02 01 0C A4 5B 30 59 A0 07 03 05 00 FE DC BA 90 A2 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A3 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A5 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A7 03 02 01 2A A8 08 30 06 02 01 00 02 01 01",decode_krb5_tgs_req,ktest_equal_tgs_req,krb5_free_kdc_req); ktest_empty_kdc_req(&ref); } /****************************************************************/ /* decode_krb5_kdc_req_body */ { krb5_kdc_req ref, *var; memset(&ref, 0, sizeof(krb5_kdc_req)); ktest_make_sample_kdc_req_body(&ref); ref.kdc_options &= ~KDC_OPT_ENC_TKT_IN_SKEY; decode_run("kdc_req_body","","30 82 01 A6 A0 07 03 05 00 FE DC BA 90 A1 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A2 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A3 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A4 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A5 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A6 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A7 03 02 01 2A A8 08 30 06 02 01 00 02 01 01 A9 20 30 1E 30 0D A0 03 02 01 02 A1 06 04 04 12 D0 00 23 30 0D A0 03 02 01 02 A1 06 04 04 12 D0 00 23 AA 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65 AB 81 BF 30 81 BC 61 5C 30 5A A0 03 02 01 05 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A3 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65 61 5C 30 5A A0 03 02 01 05 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A3 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65",decode_krb5_kdc_req_body,ktest_equal_kdc_req_body,krb5_free_kdc_req); ktest_destroy_principal(&(ref.client)); #ifndef ISODE_SUCKS ktest_destroy_principal(&(ref.server)); #endif ref.kdc_options |= KDC_OPT_ENC_TKT_IN_SKEY; ref.from = 0; ref.rtime = 0; ktest_destroy_addresses(&(ref.addresses)); ktest_destroy_enc_data(&(ref.authorization_data)); decode_run("kdc_req_body","(optionals NULL except second_ticket)","30 81 FF A0 07 03 05 00 FE DC BA 98 A2 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A5 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A7 03 02 01 2A A8 08 30 06 02 01 00 02 01 01 AB 81 BF 30 81 BC 61 5C 30 5A A0 03 02 01 05 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A3 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65 61 5C 30 5A A0 03 02 01 05 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A3 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65",decode_krb5_kdc_req_body,ktest_equal_kdc_req_body,krb5_free_kdc_req); ktest_destroy_sequence_of_ticket(&(ref.second_ticket)); #ifndef ISODE_SUCKS ktest_make_sample_principal(&(ref.server)); #endif ref.kdc_options &= ~KDC_OPT_ENC_TKT_IN_SKEY; decode_run("kdc_req_body","(optionals NULL except server)","30 59 A0 07 03 05 00 FE DC BA 90 A2 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A3 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A5 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A7 03 02 01 2A A8 08 30 06 02 01 00 02 01 01",decode_krb5_kdc_req_body,ktest_equal_kdc_req_body,krb5_free_kdc_req); ref.nktypes = 0; free(ref.ktype); ref.ktype = NULL; decode_run("kdc_req_body","(optionals NULL except server; zero-length etypes)","30 53 A0 07 03 05 00 FE DC BA 90 A2 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A3 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A5 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A7 03 02 01 2A A8 02 30 00",decode_krb5_kdc_req_body,ktest_equal_kdc_req_body,krb5_free_kdc_req); ktest_empty_kdc_req(&ref); } /****************************************************************/ /* decode_krb5_safe */ { setup(krb5_safe,ktest_make_sample_safe); decode_run("safe","","74 6E 30 6C A0 03 02 01 05 A1 03 02 01 14 A2 4F 30 4D A0 0A 04 08 6B 72 62 35 64 61 74 61 A1 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A2 05 02 03 01 E2 40 A3 03 02 01 11 A4 0F 30 0D A0 03 02 01 02 A1 06 04 04 12 D0 00 23 A5 0F 30 0D A0 03 02 01 02 A1 06 04 04 12 D0 00 23 A3 0F 30 0D A0 03 02 01 01 A1 06 04 04 31 32 33 34",decode_krb5_safe,ktest_equal_safe,krb5_free_safe); ref.timestamp = 0; ref.usec = 0; ref.seq_number = 0; ktest_destroy_address(&(ref.r_address)); decode_run("safe","(optionals NULL)","74 3E 30 3C A0 03 02 01 05 A1 03 02 01 14 A2 1F 30 1D A0 0A 04 08 6B 72 62 35 64 61 74 61 A4 0F 30 0D A0 03 02 01 02 A1 06 04 04 12 D0 00 23 A3 0F 30 0D A0 03 02 01 01 A1 06 04 04 31 32 33 34",decode_krb5_safe,ktest_equal_safe,krb5_free_safe); ktest_empty_safe(&ref); } /****************************************************************/ /* decode_krb5_priv */ { setup(krb5_priv,ktest_make_sample_priv); decode_run("priv","","75 33 30 31 A0 03 02 01 05 A1 03 02 01 15 A3 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65",decode_krb5_priv,ktest_equal_priv,krb5_free_priv); ktest_empty_priv(&ref); } /****************************************************************/ /* decode_krb5_enc_priv_part */ { setup(krb5_priv_enc_part,ktest_make_sample_priv_enc_part); decode_run("enc_priv_part","","7C 4F 30 4D A0 0A 04 08 6B 72 62 35 64 61 74 61 A1 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A2 05 02 03 01 E2 40 A3 03 02 01 11 A4 0F 30 0D A0 03 02 01 02 A1 06 04 04 12 D0 00 23 A5 0F 30 0D A0 03 02 01 02 A1 06 04 04 12 D0 00 23",decode_krb5_enc_priv_part,ktest_equal_enc_priv_part,krb5_free_priv_enc_part); ref.timestamp = 0; ref.usec = 0; ref.seq_number = 0; ktest_destroy_address(&(ref.r_address)); decode_run("enc_priv_part","(optionals NULL)","7C 1F 30 1D A0 0A 04 08 6B 72 62 35 64 61 74 61 A4 0F 30 0D A0 03 02 01 02 A1 06 04 04 12 D0 00 23",decode_krb5_enc_priv_part,ktest_equal_enc_priv_part,krb5_free_priv_enc_part); ktest_empty_priv_enc_part(&ref); } /****************************************************************/ /* decode_krb5_cred */ { setup(krb5_cred,ktest_make_sample_cred); decode_run("cred","","76 81 F6 30 81 F3 A0 03 02 01 05 A1 03 02 01 16 A2 81 BF 30 81 BC 61 5C 30 5A A0 03 02 01 05 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A3 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65 61 5C 30 5A A0 03 02 01 05 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A3 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65 A3 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65",decode_krb5_cred,ktest_equal_cred,krb5_free_cred); ktest_empty_cred(&ref); } /****************************************************************/ /* decode_krb5_enc_cred_part */ { setup(krb5_cred_enc_part,ktest_make_sample_cred_enc_part); decode_run("enc_cred_part","","7D 82 02 23 30 82 02 1F A0 82 01 DA 30 82 01 D6 30 81 E8 A0 13 30 11 A0 03 02 01 01 A1 0A 04 08 31 32 33 34 35 36 37 38 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A3 07 03 05 00 FE DC BA 98 A4 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A5 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A6 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A7 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A8 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A9 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 AA 20 30 1E 30 0D A0 03 02 01 02 A1 06 04 04 12 D0 00 23 30 0D A0 03 02 01 02 A1 06 04 04 12 D0 00 23 30 81 E8 A0 13 30 11 A0 03 02 01 01 A1 0A 04 08 31 32 33 34 35 36 37 38 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A3 07 03 05 00 FE DC BA 98 A4 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A5 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A6 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A7 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A8 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A9 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 AA 20 30 1E 30 0D A0 03 02 01 02 A1 06 04 04 12 D0 00 23 30 0D A0 03 02 01 02 A1 06 04 04 12 D0 00 23 A1 03 02 01 2A A2 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A3 05 02 03 01 E2 40 A4 0F 30 0D A0 03 02 01 02 A1 06 04 04 12 D0 00 23 A5 0F 30 0D A0 03 02 01 02 A1 06 04 04 12 D0 00 23",decode_krb5_enc_cred_part,ktest_equal_enc_cred_part,krb5_free_cred_enc_part); /* free_cred_enc_part does not free the pointer */ free(var); ktest_destroy_principal(&(ref.ticket_info[0]->client)); ktest_destroy_principal(&(ref.ticket_info[0]->server)); ref.ticket_info[0]->flags = 0; ref.ticket_info[0]->times.authtime = 0; ref.ticket_info[0]->times.starttime = 0; ref.ticket_info[0]->times.endtime = 0; ref.ticket_info[0]->times.renew_till = 0; ktest_destroy_addresses(&(ref.ticket_info[0]->caddrs)); ref.nonce = 0; ref.timestamp = 0; ref.usec = 0; ktest_destroy_address(&(ref.s_address)); ktest_destroy_address(&(ref.r_address)); decode_run("enc_cred_part","(optionals NULL)","7D 82 01 0E 30 82 01 0A A0 82 01 06 30 82 01 02 30 15 A0 13 30 11 A0 03 02 01 01 A1 0A 04 08 31 32 33 34 35 36 37 38 30 81 E8 A0 13 30 11 A0 03 02 01 01 A1 0A 04 08 31 32 33 34 35 36 37 38 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A3 07 03 05 00 FE DC BA 98 A4 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A5 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A6 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A7 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A8 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A9 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 AA 20 30 1E 30 0D A0 03 02 01 02 A1 06 04 04 12 D0 00 23 30 0D A0 03 02 01 02 A1 06 04 04 12 D0 00 23",decode_krb5_enc_cred_part,ktest_equal_enc_cred_part,krb5_free_cred_enc_part); /* free_cred_enc_part does not free the pointer */ free(var); ktest_empty_cred_enc_part(&ref); } /****************************************************************/ /* decode_krb5_error */ { setup(krb5_error,ktest_make_sample_error); decode_run("error","","7E 81 BA 30 81 B7 A0 03 02 01 05 A1 03 02 01 1E A2 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A3 05 02 03 01 E2 40 A4 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A5 05 02 03 01 E2 40 A6 03 02 01 3C A7 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A8 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A9 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 AA 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 AB 0A 1B 08 6B 72 62 35 64 61 74 61 AC 0A 04 08 6B 72 62 35 64 61 74 61",decode_krb5_error,ktest_equal_error,krb5_free_error); ref.ctime = 0; ktest_destroy_principal(&(ref.client)); ktest_empty_data(&(ref.text)); ktest_empty_data(&(ref.e_data)); decode_run("error","(optionals NULL)","7E 60 30 5E A0 03 02 01 05 A1 03 02 01 1E A3 05 02 03 01 E2 40 A4 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A5 05 02 03 01 E2 40 A6 03 02 01 3C A9 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 AA 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61",decode_krb5_error,ktest_equal_error,krb5_free_error); ktest_empty_error(&ref); } /****************************************************************/ /* decode_krb5_authdata and krb5int_get_authdata_containee_types */ { krb5_authdata **ref, **var, tmp; unsigned int count; krb5_authdatatype *types = NULL; ktest_make_sample_authorization_data(&ref); retval = krb5_data_hex_parse(&code,"30 22 30 0F A0 03 02 01 01 A1 08 04 06 66 6F 6F 62 61 72 30 0F A0 03 02 01 01 A1 08 04 06 66 6F 6F 62 61 72"); if (retval) { com_err("parsing authorization_data",retval,""); exit(1); } retval = decode_krb5_authdata(&code,&var); if (retval) com_err("decoding authorization_data",retval,""); test(ktest_equal_authorization_data(ref,var),"authorization_data\n"); tmp.length = code.length; tmp.contents = (krb5_octet *)code.data; retval = krb5int_get_authdata_containee_types(test_context, &tmp, &count, &types); if (retval) com_err("reading authdata types",retval,""); test(count == 2 && types[0] == 1 && types[1] == 1, "authorization_data(types only)\n"); free(types); krb5_free_data_contents(test_context, &code); krb5_free_authdata(test_context, var); ktest_destroy_authorization_data(&ref); } /****************************************************************/ /* decode_krb5_padata_sequence and decode_krb5_typed_data */ { krb5_pa_data **ref, **var; ktest_make_sample_pa_data_array(&ref); retval = krb5_data_hex_parse(&code,"30 24 30 10 A1 03 02 01 0D A2 09 04 07 70 61 2D 64 61 74 61 30 10 A1 03 02 01 0D A2 09 04 07 70 61 2D 64 61 74 61"); if (retval) { com_err("parsing padata_sequence",retval,""); exit(1); } retval = decode_krb5_padata_sequence(&code,&var); if (retval) com_err("decoding padata_sequence",retval,""); test(ktest_equal_sequence_of_pa_data(ref,var),"pa_data\n"); krb5_free_pa_data(test_context, var); krb5_free_data_contents(test_context, &code); retval = krb5_data_hex_parse(&code,"30 24 30 10 A0 03 02 01 0D A1 09 04 07 70 61 2D 64 61 74 61 30 10 A0 03 02 01 0D A1 09 04 07 70 61 2D 64 61 74 61"); if (retval) { com_err("parsing padata_sequence",retval,""); exit(1); } retval = decode_krb5_typed_data(&code,&var); if (retval) com_err("decoding typed_data",retval,""); test(ktest_equal_sequence_of_pa_data(ref,var),"typed_data\n"); krb5_free_pa_data(test_context, var); krb5_free_data_contents(test_context, &code); ktest_destroy_pa_data_array(&ref); } /****************************************************************/ /* decode_krb5_padata_sequence (empty) */ { krb5_pa_data **ref, **var; ktest_make_sample_empty_pa_data_array(&ref); retval = krb5_data_hex_parse(&code,"30 00"); if (retval) { com_err("parsing padata_sequence (empty)",retval,""); exit(1); } retval = decode_krb5_padata_sequence(&code,&var); if (retval) com_err("decoding padata_sequence (empty)",retval,""); test(ktest_equal_sequence_of_pa_data(ref,var),"pa_data (empty)\n"); krb5_free_pa_data(test_context, var); krb5_free_data_contents(test_context, &code); ktest_destroy_pa_data_array(&ref); } /****************************************************************/ /* decode_etype_info */ { krb5_etype_info ref, var; ktest_make_sample_etype_info(&ref); retval = krb5_data_hex_parse(&code,"30 33 30 14 A0 03 02 01 00 A1 0D 04 0B 4D 6F 72 74 6F 6E 27 73 20 23 30 30 05 A0 03 02 01 01 30 14 A0 03 02 01 02 A1 0D 04 0B 4D 6F 72 74 6F 6E 27 73 20 23 32"); if (retval) { com_err("krb5_decode_test", retval, "while parsing etype_info"); exit(1); } retval = decode_krb5_etype_info(&code,&var); if (retval) { com_err("krb5_decode_test", retval, "while decoding etype_info"); } test(ktest_equal_etype_info(ref,var),"etype_info\n"); ktest_destroy_etype_info(var); ktest_destroy_etype_info_entry(ref[2]); ref[2] = 0; ktest_destroy_etype_info_entry(ref[1]); ref[1] = 0; krb5_free_data_contents(test_context, &code); retval = krb5_data_hex_parse(&code,"30 16 30 14 A0 03 02 01 00 A1 0D 04 0B 4D 6F 72 74 6F 6E 27 73 20 23 30"); if (retval) { com_err("krb5_decode_test", retval, "while parsing etype_info (only one)"); exit(1); } retval = decode_krb5_etype_info(&code,&var); if (retval) { com_err("krb5_decode_test", retval, "while decoding etype_info (only one)"); } test(ktest_equal_etype_info(ref,var),"etype_info (only one)\n"); ktest_destroy_etype_info(var); ktest_destroy_etype_info_entry(ref[0]); ref[0] = 0; krb5_free_data_contents(test_context, &code); retval = krb5_data_hex_parse(&code,"30 00"); if (retval) { com_err("krb5_decode_test", retval, "while parsing etype_info (no info)"); exit(1); } retval = decode_krb5_etype_info(&code,&var); if (retval) { com_err("krb5_decode_test", retval, "while decoding etype_info (no info)"); } test(ktest_equal_etype_info(ref,var),"etype_info (no info)\n"); krb5_free_data_contents(test_context, &code); ktest_destroy_etype_info(var); ktest_destroy_etype_info(ref); } /****************************************************************/ /* decode_etype_info2 */ { krb5_etype_info ref, var; ktest_make_sample_etype_info2(&ref); retval = krb5_data_hex_parse(&code,"30 51 30 1E A0 03 02 01 00 A1 0D 1B 0B 4D 6F 72 74 6F 6E 27 73 20 23 30 A2 08 04 06 73 32 6B 3A 20 30 30 0F A0 03 02 01 01 A2 08 04 06 73 32 6B 3A 20 31 30 1E A0 03 02 01 02 A1 0D 1B 0B 4D 6F 72 74 6F 6E 27 73 20 23 32 A2 08 04 06 73 32 6B 3A 20 32"); if (retval) { com_err("krb5_decode_test", retval, "while parsing etype_info2"); exit(1); } retval = decode_krb5_etype_info2(&code,&var); if (retval) { com_err("krb5_decode_test", retval, "while decoding etype_info2"); } test(ktest_equal_etype_info(ref,var),"etype_info2\n"); ktest_destroy_etype_info(var); ktest_destroy_etype_info_entry(ref[2]); ref[2] = 0; ktest_destroy_etype_info_entry(ref[1]); ref[1] = 0; krb5_free_data_contents(test_context, &code); retval = krb5_data_hex_parse(&code,"30 20 30 1E A0 03 02 01 00 A1 0D 1B 0B 4D 6F 72 74 6F 6E 27 73 20 23 30 A2 08 04 06 73 32 6B 3A 20 30"); if (retval) { com_err("krb5_decode_test", retval, "while parsing etype_info2 (only one)"); exit(1); } retval = decode_krb5_etype_info2(&code,&var); if (retval) { com_err("krb5_decode_test", retval, "while decoding etype_info2 (only one)"); } test(ktest_equal_etype_info(ref,var),"etype_info2 (only one)\n"); krb5_free_data_contents(test_context, &code); ktest_destroy_etype_info(var); ktest_destroy_etype_info(ref); } /****************************************************************/ /* decode_pa_enc_ts */ { setup(krb5_pa_enc_ts,ktest_make_sample_pa_enc_ts); decode_run("pa_enc_ts","","30 1A A0 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A1 05 02 03 01 E2 40",decode_krb5_pa_enc_ts,ktest_equal_krb5_pa_enc_ts,krb5_free_pa_enc_ts); ref.pausec = 0; decode_run("pa_enc_ts (no usec)","","30 13 A0 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A",decode_krb5_pa_enc_ts,ktest_equal_krb5_pa_enc_ts,krb5_free_pa_enc_ts); } /****************************************************************/ /* decode_enc_data */ { setup(krb5_enc_data,ktest_make_sample_enc_data); decode_run("enc_data","","30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65",decode_krb5_enc_data,ktest_equal_enc_data,krb5_ktest_free_enc_data); ref.kvno = 0xFF000000; decode_run("enc_data","(MSB-set kvno)","30 26 A0 03 02 01 00 A1 06 02 04 FF 00 00 00 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65",decode_krb5_enc_data,ktest_equal_enc_data,krb5_ktest_free_enc_data); ref.kvno = 0xFFFFFFFF; decode_run("enc_data","(kvno=-1)","30 23 A0 03 02 01 00 A1 03 02 01 FF A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65",decode_krb5_enc_data,ktest_equal_enc_data,krb5_ktest_free_enc_data); ktest_destroy_enc_data(&ref); } /****************************************************************/ /* decode_sam_challenge_2 */ { setup(krb5_sam_challenge_2,ktest_make_sample_sam_challenge_2); decode_run("sam_challenge_2","","30 22 A0 0D 30 0B 04 09 63 68 61 6C 6C 65 6E 67 65 A1 11 30 0F 30 0D A0 03 02 01 01 A1 06 04 04 31 32 33 34",decode_krb5_sam_challenge_2,ktest_equal_sam_challenge_2,krb5_free_sam_challenge_2); ktest_empty_sam_challenge_2(&ref); } /****************************************************************/ /* decode_sam_challenge_2_body */ { setup(krb5_sam_challenge_2_body,ktest_make_sample_sam_challenge_2_body); decode_run("sam_challenge_2_body","","30 64 A0 03 02 01 2A A1 07 03 05 00 80 00 00 00 A2 0B 04 09 74 79 70 65 20 6E 61 6D 65 A4 11 04 0F 63 68 61 6C 6C 65 6E 67 65 20 6C 61 62 65 6C A5 10 04 0E 63 68 61 6C 6C 65 6E 67 65 20 69 70 73 65 A6 16 04 14 72 65 73 70 6F 6E 73 65 5F 70 72 6F 6D 70 74 20 69 70 73 65 A8 05 02 03 54 32 10 A9 03 02 01 01",decode_krb5_sam_challenge_2_body,ktest_equal_sam_challenge_2_body,krb5_free_sam_challenge_2_body); ktest_empty_sam_challenge_2_body(&ref); } /****************************************************************/ /* decode_pa_for_user */ { setup(krb5_pa_for_user,ktest_make_sample_pa_for_user); decode_run("pa_for_user","","30 4B A0 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 0F 30 0D A0 03 02 01 01 A1 06 04 04 31 32 33 34 A3 0A 1B 08 6B 72 62 35 64 61 74 61",decode_krb5_pa_for_user,ktest_equal_pa_for_user,krb5_free_pa_for_user); ktest_empty_pa_for_user(&ref); } /****************************************************************/ /* decode_pa_s4u_x509_user */ { setup(krb5_pa_s4u_x509_user,ktest_make_sample_pa_s4u_x509_user); decode_run("pa_s4u_x509_user","","30 68 A0 55 30 53 A0 06 02 04 00 CA 14 9A A1 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A2 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A3 12 04 10 70 61 5F 73 34 75 5F 78 35 30 39 5F 75 73 65 72 A4 07 03 05 00 80 00 00 00 A1 0F 30 0D A0 03 02 01 01 A1 06 04 04 31 32 33 34",decode_krb5_pa_s4u_x509_user,ktest_equal_pa_s4u_x509_user,krb5_free_pa_s4u_x509_user); ktest_empty_pa_s4u_x509_user(&ref); } /****************************************************************/ /* decode_pa_pac_req */ { /* This type has no encoder and is very simple. Test two * hand-generated encodings. */ krb5_pa_pac_req *req1 = NULL, *req2 = NULL; code = make_data("\x30\x05\xA0\x03\x01\x01\x00", 7); retval = decode_krb5_pa_pac_req(&code, &req1); if (retval) { com_err(argv[0], retval, "while decoding PA-PAC-REQ"); exit(1); } code = make_data("\x30\x05\xA0\x03\x01\x01\xFF", 7); retval = decode_krb5_pa_pac_req(&code, &req2); if (retval) { com_err(argv[0], retval, "while decoding PA-PAC-REQ"); exit(1); } if (req1->include_pac != 0 || req2->include_pac != 1) { printf("ERROR: "); error_count++; } else { printf("OK: "); } printf("pa_pac_rec\n"); free(req1); free(req2); } /****************************************************************/ /* decode_ad_kdcissued */ { setup(krb5_ad_kdcissued,ktest_make_sample_ad_kdcissued); decode_run("ad_kdcissued","","30 65 A0 0F 30 0D A0 03 02 01 01 A1 06 04 04 31 32 33 34 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A3 24 30 22 30 0F A0 03 02 01 01 A1 08 04 06 66 6F 6F 62 61 72 30 0F A0 03 02 01 01 A1 08 04 06 66 6F 6F 62 61 72",decode_krb5_ad_kdcissued,ktest_equal_ad_kdcissued,krb5_free_ad_kdcissued); ktest_empty_ad_kdcissued(&ref); } /****************************************************************/ /* decode_ad_signedpath */ { setup(krb5_ad_signedpath,ktest_make_sample_ad_signedpath); decode_run("ad_signedpath","","30 3E A0 03 02 01 01 A1 0F 30 0D A0 03 02 01 01 A1 06 04 04 31 32 33 34 A3 26 30 24 30 10 A1 03 02 01 0D A2 09 04 07 70 61 2D 64 61 74 61 30 10 A1 03 02 01 0D A2 09 04 07 70 61 2D 64 61 74 61",decode_krb5_ad_signedpath,ktest_equal_ad_signedpath,krb5_free_ad_signedpath); ktest_empty_ad_signedpath(&ref); } /****************************************************************/ /* decode_iakerb_header */ { setup(krb5_iakerb_header,ktest_make_sample_iakerb_header); decode_run("iakerb_header","","30 18 A1 0A 04 08 6B 72 62 35 64 61 74 61 A2 0A 04 08 6B 72 62 35 64 61 74 61",decode_krb5_iakerb_header,ktest_equal_iakerb_header,krb5_free_iakerb_header); ktest_empty_iakerb_header(&ref); } /****************************************************************/ /* decode_iakerb_finished */ { setup(krb5_iakerb_finished,ktest_make_sample_iakerb_finished); decode_run("iakerb_finished","","30 11 A1 0F 30 0D A0 03 02 01 01 A1 06 04 04 31 32 33 34",decode_krb5_iakerb_finished,ktest_equal_iakerb_finished,krb5_free_iakerb_finished); ktest_empty_iakerb_finished(&ref); } /****************************************************************/ /* decode_fast_response */ { setup(krb5_fast_response,ktest_make_sample_fast_response); decode_run("fast_response","","30 81 9F A0 26 30 24 30 10 A1 03 02 01 0D A2 09 04 07 70 61 2D 64 61 74 61 30 10 A1 03 02 01 0D A2 09 04 07 70 61 2D 64 61 74 61 A1 13 30 11 A0 03 02 01 01 A1 0A 04 08 31 32 33 34 35 36 37 38 A2 5B 30 59 A0 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A1 05 02 03 01 E2 40 A2 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A3 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A4 0F 30 0D A0 03 02 01 01 A1 06 04 04 31 32 33 34 A3 03 02 01 2A",decode_krb5_fast_response,ktest_equal_fast_response,krb5_free_fast_response); ktest_empty_fast_response(&ref); } /****************************************************************/ /* decode_pa_fx_fast_reply */ { setup(krb5_enc_data,ktest_make_sample_enc_data); decode_run("pa_fx_fast_reply","","A0 29 30 27 A0 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65",decode_krb5_pa_fx_fast_reply,ktest_equal_enc_data,krb5_free_enc_data); ktest_destroy_enc_data(&ref); } /****************************************************************/ /* decode_krb5_otp_tokeninfo */ { setup(krb5_otp_tokeninfo,ktest_make_minimal_otp_tokeninfo); decode_run("otp_tokeninfo","(optionals NULL)","30 07 80 05 00 00 00 00 00",decode_krb5_otp_tokeninfo,ktest_equal_otp_tokeninfo,k5_free_otp_tokeninfo); ktest_empty_otp_tokeninfo(&ref); } { setup(krb5_otp_tokeninfo,ktest_make_maximal_otp_tokeninfo); decode_run("otp_tokeninfo","","30 72 80 05 00 77 00 00 00 81 0B 45 78 61 6D 70 6C 65 63 6F 72 70 82 05 68 61 72 6B 21 83 01 0A 84 01 02 85 09 79 6F 75 72 74 6F 6B 65 6E 86 28 75 72 6E 3A 69 65 74 66 3A 70 61 72 61 6D 73 3A 78 6D 6C 3A 6E 73 3A 6B 65 79 70 72 6F 76 3A 70 73 6B 63 3A 68 6F 74 70 A7 16 30 0B 06 09 60 86 48 01 65 03 04 02 01 30 07 06 05 2B 0E 03 02 1A 88 02 03 E8",decode_krb5_otp_tokeninfo,ktest_equal_otp_tokeninfo,k5_free_otp_tokeninfo); ktest_empty_otp_tokeninfo(&ref); } /****************************************************************/ /* decode_krb5_pa_otp_challenge */ { setup(krb5_pa_otp_challenge,ktest_make_minimal_pa_otp_challenge); decode_run("pa_otp_challenge","(optionals NULL)","30 15 80 08 6D 69 6E 6E 6F 6E 63 65 A2 09 30 07 80 05 00 00 00 00 00",decode_krb5_pa_otp_challenge,ktest_equal_pa_otp_challenge,k5_free_pa_otp_challenge); ktest_empty_pa_otp_challenge(&ref); } { setup(krb5_pa_otp_challenge,ktest_make_maximal_pa_otp_challenge); decode_run("pa_otp_challenge","","30 81 A5 80 08 6D 61 78 6E 6F 6E 63 65 81 0B 74 65 73 74 73 65 72 76 69 63 65 A2 7D 30 07 80 05 00 00 00 00 00 30 72 80 05 00 77 00 00 00 81 0B 45 78 61 6D 70 6C 65 63 6F 72 70 82 05 68 61 72 6B 21 83 01 0A 84 01 02 85 09 79 6F 75 72 74 6F 6B 65 6E 86 28 75 72 6E 3A 69 65 74 66 3A 70 61 72 61 6D 73 3A 78 6D 6C 3A 6E 73 3A 6B 65 79 70 72 6F 76 3A 70 73 6B 63 3A 68 6F 74 70 A7 16 30 0B 06 09 60 86 48 01 65 03 04 02 01 30 07 06 05 2B 0E 03 02 1A 88 02 03 E8 83 07 6B 65 79 73 61 6C 74 84 04 31 32 33 34",decode_krb5_pa_otp_challenge,ktest_equal_pa_otp_challenge,k5_free_pa_otp_challenge); ktest_empty_pa_otp_challenge(&ref); } /****************************************************************/ /* decode_krb5_pa_otp_req */ { setup(krb5_pa_otp_req,ktest_make_minimal_pa_otp_req); decode_run("pa_otp_req","(optionals NULL)","30 2C 80 05 00 00 00 00 00 A2 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65",decode_krb5_pa_otp_req,ktest_equal_pa_otp_req,k5_free_pa_otp_req); ktest_empty_pa_otp_req(&ref); } { setup(krb5_pa_otp_req,ktest_make_maximal_pa_otp_req); decode_run("pa_otp_req","","30 81 B9 80 05 00 60 00 00 00 81 05 6E 6F 6E 63 65 A2 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65 A3 0B 06 09 60 86 48 01 65 03 04 02 01 84 02 03 E8 85 05 66 72 6F 67 73 86 0A 6D 79 66 69 72 73 74 70 69 6E 87 05 68 61 72 6B 21 88 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A 89 03 33 34 36 8A 01 02 8B 09 79 6F 75 72 74 6F 6B 65 6E 8C 28 75 72 6E 3A 69 65 74 66 3A 70 61 72 61 6D 73 3A 78 6D 6C 3A 6E 73 3A 6B 65 79 70 72 6F 76 3A 70 73 6B 63 3A 68 6F 74 70 8D 0B 45 78 61 6D 70 6C 65 63 6F 72 70",decode_krb5_pa_otp_req,ktest_equal_pa_otp_req,k5_free_pa_otp_req); ktest_empty_pa_otp_req(&ref); } /****************************************************************/ /* decode_krb5_pa_otp_enc_req */ { setup(krb5_data,ktest_make_sample_data); decode_run("pa_otp_enc_req","","30 0A 80 08 6B 72 62 35 64 61 74 61",decode_krb5_pa_otp_enc_req,ktest_equal_data,krb5_free_data); ktest_empty_data(&ref); } /****************************************************************/ /* decode_krb5_kkdcp_message */ { setup(krb5_kkdcp_message,ktest_make_sample_kkdcp_message); decode_run("kkdcp_message","","30 82 01 FC A0 82 01 EC 04 82 01 E8 6A 82 01 E4 30 82 01 E0 A1 03 02 01 05 A2 03 02 01 0A A3 26 30 24 30 10 A1 03 02 01 0D A2 09 04 07 70 61 2D 64 61 74 61 30 10 A1 03 02 01 0D A2 09 04 07 70 61 2D 64 61 74 61 A4 82 01 AA 30 82 01 A6 A0 07 03 05 00 FE DC BA 98 A1 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A2 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A3 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A4 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A5 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A6 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A7 03 02 01 2A A8 08 30 06 02 01 00 02 01 01 A9 20 30 1E 30 0D A0 03 02 01 02 A1 06 04 04 12 D0 00 23 30 0D A0 03 02 01 02 A1 06 04 04 12 D0 00 23 AA 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65 AB 81 BF 30 81 BC 61 5C 30 5A A0 03 02 01 05 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A3 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65 61 5C 30 5A A0 03 02 01 05 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A3 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65 A1 0A 1B 08 6B 72 62 35 64 61 74 61",decode_krb5_kkdcp_message,ktest_equal_kkdcp_message,ktest_free_kkdcp_message); ktest_empty_kkdcp_message(&ref); } /****************************************************************/ /* decode_krb5_cammac */ { setup(krb5_cammac,ktest_make_minimal_cammac); decode_run("cammac","(optionals NULL)","30 12 A0 10 30 0E 30 0C A0 03 02 01 01 A1 05 04 03 61 64 31",decode_krb5_cammac,ktest_equal_cammac,k5_free_cammac); ktest_empty_cammac(&ref); } { setup(krb5_cammac,ktest_make_maximal_cammac); decode_run("cammac","","30 81 F2 A0 1E 30 1C 30 0C A0 03 02 01 01 A1 05 04 03 61 64 31 30 0C A0 03 02 01 02 A1 05 04 03 61 64 32 A1 3D 30 3B A0 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A1 03 02 01 05 A2 03 02 01 10 A3 13 30 11 A0 03 02 01 01 A1 0A 04 08 63 6B 73 75 6D 6B 64 63 A2 3D 30 3B A0 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A1 03 02 01 05 A2 03 02 01 10 A3 13 30 11 A0 03 02 01 01 A1 0A 04 08 63 6B 73 75 6D 73 76 63 A3 52 30 50 30 13 A3 11 30 0F A0 03 02 01 01 A1 08 04 06 63 6B 73 75 6D 31 30 39 A0 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A1 03 02 01 05 A2 03 02 01 10 A3 11 30 0F A0 03 02 01 01 A1 08 04 06 63 6B 73 75 6D 32",decode_krb5_cammac,ktest_equal_cammac,k5_free_cammac); ktest_empty_cammac(&ref); } /****************************************************************/ /* decode_krb5_secure_cookie */ { setup(krb5_secure_cookie,ktest_make_sample_secure_cookie); decode_run("secure_cookie","","30 2C 02 04 2D F8 02 25 30 24 30 10 A1 03 02 01 0D A2 09 04 07 70 61 2D 64 61 74 61 30 10 A1 03 02 01 0D A2 09 04 07 70 61 2D 64 61 74 61",decode_krb5_secure_cookie,ktest_equal_secure_cookie,k5_free_secure_cookie); ktest_empty_secure_cookie(&ref); } #ifndef DISABLE_PKINIT /****************************************************************/ /* decode_krb5_pa_pk_as_req */ { setup(krb5_pa_pk_as_req,ktest_make_sample_pa_pk_as_req); decode_run("krb5_pa_pk_as_req","","30 38 80 08 6B 72 62 35 64 61 74 61 A1 22 30 20 30 1E 80 08 6B 72 62 35 64 61 74 61 81 08 6B 72 62 35 64 61 74 61 82 08 6B 72 62 35 64 61 74 61 82 08 6B 72 62 35 64 61 74 61", acc.decode_krb5_pa_pk_as_req, ktest_equal_pa_pk_as_req,ktest_free_pa_pk_as_req); ktest_empty_pa_pk_as_req(&ref); } /****************************************************************/ /* decode_krb5_pa_pk_as_rep */ { setup(krb5_pa_pk_as_rep,ktest_make_sample_pa_pk_as_rep_dhInfo); decode_run("krb5_pa_pk_as_rep","(dhInfo)","A0 28 30 26 80 08 6B 72 62 35 64 61 74 61 A1 0A 04 08 6B 72 62 35 64 61 74 61 A2 0E 30 0C A0 0A 06 08 6B 72 62 35 64 61 74 61", acc.decode_krb5_pa_pk_as_rep, ktest_equal_pa_pk_as_rep,ktest_free_pa_pk_as_rep); ktest_empty_pa_pk_as_rep(&ref); } { setup(krb5_pa_pk_as_rep,ktest_make_sample_pa_pk_as_rep_encKeyPack); decode_run("krb5_pa_pk_as_rep","(encKeyPack)","81 08 6B 72 62 35 64 61 74 61", acc.decode_krb5_pa_pk_as_rep, ktest_equal_pa_pk_as_rep,ktest_free_pa_pk_as_rep); ktest_empty_pa_pk_as_rep(&ref); } /****************************************************************/ /* decode_krb5_auth_pack */ { setup(krb5_auth_pack,ktest_make_sample_auth_pack); decode_run("krb5_auth_pack","","30 81 93 A0 29 30 27 A0 05 02 03 01 E2 40 A1 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A2 03 02 01 2A A3 06 04 04 31 32 33 34 A1 22 30 20 30 13 06 09 2A 86 48 86 F7 12 01 02 02 04 06 70 61 72 61 6D 73 03 09 00 6B 72 62 35 64 61 74 61 A2 24 30 22 30 13 06 09 2A 86 48 86 F7 12 01 02 02 04 06 70 61 72 61 6D 73 30 0B 06 09 2A 86 48 86 F7 12 01 02 02 A3 0A 04 08 6B 72 62 35 64 61 74 61 A4 10 30 0E 30 0C A0 0A 06 08 6B 72 62 35 64 61 74 61", acc.decode_krb5_auth_pack, ktest_equal_auth_pack,ktest_free_auth_pack); ktest_empty_auth_pack(&ref); } /****************************************************************/ /* decode_krb5_auth_pack_draft9 */ { setup(krb5_auth_pack_draft9,ktest_make_sample_auth_pack_draft9); decode_run("krb5_auth_pack_draft9","","30 75 A0 4F 30 4D A0 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 05 02 03 01 E2 40 A3 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A4 03 02 01 2A A1 22 30 20 30 13 06 09 2A 86 48 86 F7 12 01 02 02 04 06 70 61 72 61 6D 73 03 09 00 6B 72 62 35 64 61 74 61", acc.decode_krb5_auth_pack_draft9, ktest_equal_auth_pack_draft9,ktest_free_auth_pack_draft9); ktest_empty_auth_pack_draft9(&ref); } /****************************************************************/ /* decode_krb5_kdc_dh_key_info */ { setup(krb5_kdc_dh_key_info,ktest_make_sample_kdc_dh_key_info); decode_run("krb5_kdc_dh_key_info","","30 25 A0 0B 03 09 00 6B 72 62 35 64 61 74 61 A1 03 02 01 2A A2 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A", acc.decode_krb5_kdc_dh_key_info, ktest_equal_kdc_dh_key_info,ktest_free_kdc_dh_key_info); ktest_empty_kdc_dh_key_info(&ref); } /****************************************************************/ /* decode_krb5_reply_key_pack */ { setup(krb5_reply_key_pack,ktest_make_sample_reply_key_pack); decode_run("krb5_reply_key_pack","","30 26 A0 13 30 11 A0 03 02 01 01 A1 0A 04 08 31 32 33 34 35 36 37 38 A1 0F 30 0D A0 03 02 01 01 A1 06 04 04 31 32 33 34", acc.decode_krb5_reply_key_pack, ktest_equal_reply_key_pack,ktest_free_reply_key_pack); ktest_empty_reply_key_pack(&ref); } /****************************************************************/ /* decode_krb5_reply_key_pack_draft9 */ { setup(krb5_reply_key_pack_draft9,ktest_make_sample_reply_key_pack_draft9); decode_run("krb5_reply_key_pack_draft9","","30 1A A0 13 30 11 A0 03 02 01 01 A1 0A 04 08 31 32 33 34 35 36 37 38 A1 03 02 01 2A", acc.decode_krb5_reply_key_pack_draft9, ktest_equal_reply_key_pack_draft9,ktest_free_reply_key_pack_draft9); ktest_empty_reply_key_pack_draft9(&ref); } /****************************************************************/ /* decode_krb5_principal_name */ /* We have no encoder for this type (KerberosName from RFC 4556); the * encoding is hand-generated. */ { krb5_principal ref, var; ktest_make_sample_principal(&ref); decode_run("krb5_principal_name","","30 2E A0 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A1 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61", acc.decode_krb5_principal_name,equal_principal,krb5_free_principal); } #endif /* not DISABLE_PKINIT */ #ifdef ENABLE_LDAP /* ldap sequence_of_keys */ { setup(ldap_seqof_key_data,ktest_make_sample_ldap_seqof_key_data); decode_run("ldap_seqof_key_data","","30 81 87 A0 03 02 01 01 A1 03 02 01 01 A2 03 02 01 2A A3 03 02 01 0E A4 71 30 6F 30 23 A0 10 30 0E A0 03 02 01 00 A1 07 04 05 73 61 6C 74 30 A1 0F 30 0D A0 03 02 01 02 A1 06 04 04 6B 65 79 30 30 23 A0 10 30 0E A0 03 02 01 01 A1 07 04 05 73 61 6C 74 31 A1 0F 30 0D A0 03 02 01 02 A1 06 04 04 6B 65 79 31 30 23 A0 10 30 0E A0 03 02 01 02 A1 07 04 05 73 61 6C 74 32 A1 0F 30 0D A0 03 02 01 02 A1 06 04 04 6B 65 79 32",acc.asn1_ldap_decode_sequence_of_keys,ktest_equal_ldap_sequence_of_keys,ktest_empty_ldap_seqof_key_data); ktest_empty_ldap_seqof_key_data(test_context, &ref); } #endif krb5_free_context(test_context); exit(error_count); return(error_count); } void krb5_ktest_free_enc_data(krb5_context context, krb5_enc_data *val) { if (val) { krb5_free_data_contents(context, &(val->ciphertext)); free(val); } } #ifndef DISABLE_PKINIT /* Glue function to make ktest_equal_principal_data look like what decode_run * expects. */ static int equal_principal(krb5_principal *ref, krb5_principal var) { return ktest_equal_principal_data(*ref, var); } static void ktest_free_auth_pack(krb5_context context, krb5_auth_pack *val) { if (val) ktest_empty_auth_pack(val); free(val); } static void ktest_free_auth_pack_draft9(krb5_context context, krb5_auth_pack_draft9 *val) { if (val) ktest_empty_auth_pack_draft9(val); free(val); } static void ktest_free_kdc_dh_key_info(krb5_context context, krb5_kdc_dh_key_info *val) { if (val) ktest_empty_kdc_dh_key_info(val); free(val); } static void ktest_free_pa_pk_as_req(krb5_context context, krb5_pa_pk_as_req *val) { if (val) ktest_empty_pa_pk_as_req(val); free(val); } static void ktest_free_pa_pk_as_rep(krb5_context context, krb5_pa_pk_as_rep *val) { if (val) ktest_empty_pa_pk_as_rep(val); free(val); } static void ktest_free_reply_key_pack(krb5_context context, krb5_reply_key_pack *val) { if (val) ktest_empty_reply_key_pack(val); free(val); } static void ktest_free_reply_key_pack_draft9(krb5_context context, krb5_reply_key_pack_draft9 *val) { if (val) ktest_empty_reply_key_pack_draft9(val); free(val); } #endif /* not DISABLE_PKINIT */ static void ktest_free_kkdcp_message(krb5_context context, krb5_kkdcp_message *val) { if (val) ktest_empty_kkdcp_message(val); free(val); } krb5-1.16/src/tests/t_audit.py0000755000704600001450000000205313211554426016135 0ustar ghudsonlibuuid#!/usr/bin/python from k5test import * conf = {'plugins': {'audit': { 'module': 'test:$plugins/audit/test/k5audit_test.so'}}} realm = K5Realm(krb5_conf=conf, get_creds=False) realm.addprinc('target') realm.run([kadminl, 'modprinc', '+ok_to_auth_as_delegate', realm.host_princ]) # Make normal AS and TGS requests so they will be audited. realm.kinit(realm.host_princ, flags=['-k', '-f']) realm.run([kvno, 'target']) # Make S4U2Self and S4U2Proxy requests so they will be audited. The # S4U2Proxy request is expected to fail. realm.run([kvno, '-k', realm.keytab, '-U', 'user', '-P', 'target'], expected_code=1, expected_msg='NOT_ALLOWED_TO_DELEGATE') # Make a U2U request so it will be audited. uuserver = os.path.join(buildtop, 'appl', 'user_user', 'uuserver') uuclient = os.path.join(buildtop, 'appl', 'user_user', 'uuclient') port_arg = str(realm.server_port()) realm.start_server([uuserver, port_arg], 'Server started') realm.run([uuclient, hostname, 'testing message', port_arg], expected_msg='Hello') success('Audit tests') krb5-1.16/src/tests/t_keydata.py0000755000704600001450000000370613211554426016457 0ustar ghudsonlibuuid#!/usr/bin/python from k5test import * realm = K5Realm(create_user=False, create_host=False) # Create a principal with no keys. realm.run([kadminl, 'addprinc', '-nokey', 'user']) realm.run([kadminl, 'getprinc', 'user'], expected_msg='Number of keys: 0') # Change its password and check the resulting kvno. realm.run([kadminl, 'cpw', '-pw', 'password', 'user']) realm.run([kadminl, 'getprinc', 'user'], expected_msg='vno 1') # Delete all of its keys. realm.run([kadminl, 'purgekeys', '-all', 'user']) realm.run([kadminl, 'getprinc', 'user'], expected_msg='Number of keys: 0') # Randomize its keys and check the resulting kvno. realm.run([kadminl, 'cpw', '-randkey', 'user']) realm.run([kadminl, 'getprinc', 'user'], expected_msg='vno 1') # Return true if patype appears to have been received in a hint list # from a KDC error message, based on the trace file fname. def preauth_type_received(fname, patype): f = open(fname, 'r') found = False for line in f: if 'Processing preauth types:' in line: ind = line.find('types:') patypes = line[ind + 6:].strip().split(', ') if str(patype) in patypes: found = True f.close() return found # Make sure the KDC doesn't offer encrypted timestamp for a principal # with no keys. tracefile = os.path.join(realm.testdir, 'trace') realm.run([kadminl, 'purgekeys', '-all', 'user']) realm.run([kadminl, 'modprinc', '+requires_preauth', 'user']) realm.run(['env', 'KRB5_TRACE=' + tracefile, kinit, 'user'], expected_code=1) if preauth_type_received(tracefile, 2): fail('encrypted timestamp') # Make sure it doesn't offer encrypted challenge either. realm.run([kadminl, 'addprinc', '-pw', 'fast', 'armor']) realm.kinit('armor', 'fast') os.remove(tracefile) realm.run(['env', 'KRB5_TRACE=' + tracefile, kinit, '-T', realm.ccache, 'user'], expected_code=1) if preauth_type_received(tracefile, 138): fail('encrypted challenge') success('Key data tests') krb5-1.16/src/tests/gssapi/0000755000704600001450000000000013211554426015415 5ustar ghudsonlibuuidkrb5-1.16/src/tests/gssapi/t_enctypes.c0000644000704600001450000001744713211554426017753 0ustar ghudsonlibuuid/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* tests/gssapi/t_enctypes.c - gss_krb5_set_allowable_enctypes test */ /* * Copyright (C) 2013 by the Massachusetts Institute of Technology. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "k5-int.h" #include "common.h" #include "gssapi_ext.h" /* * This test program establishes contexts with the krb5 mech, the default * initiator name, a specified target name, and the default acceptor name. * Before the exchange, gss_set_allowable_enctypes is called for the initiator * and the acceptor cred if requested. If the exchange is successful, the * resulting contexts are exported with gss_krb5_export_lucid_sec_context, * checked for mismatches, and the GSS protocol and keys are displayed. Exits * with status 0 if all operations are successful, or 1 if not. * * Usage: ./t_enctypes [-i initenctypes] [-a accenctypes] targetname */ static void usage() { errout("Usage: t_enctypes [-i initenctypes] [-a accenctypes] " "targetname"); } /* Error out if ikey is not the same as akey. */ static void check_key_match(gss_krb5_lucid_key_t *ikey, gss_krb5_lucid_key_t *akey) { if (ikey->type != akey->type || ikey->length != akey->length || memcmp(ikey->data, akey->data, ikey->length) != 0) errout("Initiator and acceptor keys do not match"); } /* Display the name of enctype. */ static void display_enctype(krb5_enctype enctype) { char ename[128]; if (krb5_enctype_to_name(enctype, FALSE, ename, sizeof(ename)) == 0) fputs(ename, stdout); else fputs("(unknown)", stdout); } int main(int argc, char *argv[]) { krb5_error_code ret; krb5_context kctx = NULL; krb5_enctype *ienc = NULL, *aenc = NULL, zero = 0; OM_uint32 minor, major, flags; gss_name_t tname; gss_cred_id_t icred = GSS_C_NO_CREDENTIAL, acred = GSS_C_NO_CREDENTIAL; gss_ctx_id_t ictx, actx; gss_krb5_lucid_context_v1_t *ilucid, *alucid; gss_krb5_rfc1964_keydata_t *i1964, *a1964; gss_krb5_cfx_keydata_t *icfx, *acfx; gss_buffer_set_t bufset = GSS_C_NO_BUFFER_SET; gss_OID ssf_oid = GSS_C_SEC_CONTEXT_SASL_SSF; unsigned int ssf; size_t count; void *lptr; int c; ret = krb5_init_context(&kctx); check_k5err(kctx, "krb5_init_context", ret); /* Parse arguments. */ while ((c = getopt(argc, argv, "i:a:")) != -1) { switch (c) { case 'i': ret = krb5int_parse_enctype_list(kctx, "", optarg, &zero, &ienc); check_k5err(kctx, "krb5_parse_enctype_list(initiator)", ret); break; case 'a': ret = krb5int_parse_enctype_list(kctx, "", optarg, &zero, &aenc); check_k5err(kctx, "krb5_parse_enctype_list(acceptor)", ret); break; default: usage(); } } argc -= optind; argv += optind; if (argc != 1) usage(); tname = import_name(*argv); if (ienc != NULL) { major = gss_acquire_cred(&minor, GSS_C_NO_NAME, GSS_C_INDEFINITE, &mechset_krb5, GSS_C_INITIATE, &icred, NULL, NULL); check_gsserr("gss_acquire_cred(initiator)", major, minor); for (count = 0; ienc[count]; count++); major = gss_krb5_set_allowable_enctypes(&minor, icred, count, ienc); check_gsserr("gss_krb5_set_allowable_enctypes(init)", major, minor); } if (aenc != NULL) { major = gss_acquire_cred(&minor, GSS_C_NO_NAME, GSS_C_INDEFINITE, &mechset_krb5, GSS_C_ACCEPT, &acred, NULL, NULL); check_gsserr("gss_acquire_cred(acceptor)", major, minor); for (count = 0; aenc[count]; count++); major = gss_krb5_set_allowable_enctypes(&minor, acred, count, aenc); check_gsserr("gss_krb5_set_allowable_enctypes(acc)", major, minor); } flags = GSS_C_REPLAY_FLAG | GSS_C_SEQUENCE_FLAG | GSS_C_MUTUAL_FLAG; establish_contexts(&mech_krb5, icred, acred, tname, flags, &ictx, &actx, NULL, NULL, NULL); /* Query the SSF value and range-check the result. */ major = gss_inquire_sec_context_by_oid(&minor, ictx, ssf_oid, &bufset); check_gsserr("gss_inquire_sec_context_by_oid(ssf)", major, minor); if (bufset->elements[0].length != 4) errout("SSF buffer has unexpected length"); ssf = load_32_be(bufset->elements[0].value); if (ssf < 56 || ssf > 256) errout("SSF value not within acceptable range (56-256)"); (void)gss_release_buffer_set(&minor, &bufset); /* Export to lucid contexts. */ major = gss_krb5_export_lucid_sec_context(&minor, &ictx, 1, &lptr); check_gsserr("gss_export_lucid_sec_context(initiator)", major, minor); ilucid = lptr; major = gss_krb5_export_lucid_sec_context(&minor, &actx, 1, &lptr); check_gsserr("gss_export_lucid_sec_context(acceptor)", major, minor); alucid = lptr; /* Grab the session keys and make sure they match. */ if (ilucid->protocol != alucid->protocol) errout("Initiator/acceptor protocol mismatch"); if (ilucid->protocol) { icfx = &ilucid->cfx_kd; acfx = &alucid->cfx_kd; if (icfx->have_acceptor_subkey != acfx->have_acceptor_subkey) errout("Initiator/acceptor have_acceptor_subkey mismatch"); check_key_match(&icfx->ctx_key, &acfx->ctx_key); if (icfx->have_acceptor_subkey) check_key_match(&icfx->acceptor_subkey, &acfx->acceptor_subkey); fputs("cfx ", stdout); display_enctype(icfx->ctx_key.type); if (icfx->have_acceptor_subkey) { fputs(" ", stdout); display_enctype(icfx->acceptor_subkey.type); } fputs("\n", stdout); } else { i1964 = &ilucid->rfc1964_kd; a1964 = &alucid->rfc1964_kd; if (i1964->sign_alg != a1964->sign_alg || i1964->seal_alg != a1964->seal_alg) errout("Initiator/acceptor sign or seal alg mismatch"); check_key_match(&i1964->ctx_key, &a1964->ctx_key); fputs("rfc1964 ", stdout); display_enctype(i1964->ctx_key.type); fputs("\n", stdout); } krb5_free_context(kctx); free(ienc); free(aenc); (void)gss_release_name(&minor, &tname); (void)gss_release_cred(&minor, &icred); (void)gss_release_cred(&minor, &acred); (void)gss_delete_sec_context(&minor, &ictx, NULL); (void)gss_delete_sec_context(&minor, &actx, NULL); (void)gss_krb5_free_lucid_sec_context(&minor, ilucid); (void)gss_krb5_free_lucid_sec_context(&minor, alucid); return 0; } krb5-1.16/src/tests/gssapi/t_enctypes.py0000755000704600001450000001431613211554426020154 0ustar ghudsonlibuuid#!/usr/bin/python from k5test import * # Define some convenience abbreviations for enctypes we will see in # test program output. For background, aes256 and aes128 are "CFX # enctypes", meaning that they imply support for RFC 4121, while des3 # and rc4 are not. DES3 keys will appear as 'des3-cbc-raw' in # t_enctypes output because that's how GSSAPI does raw triple-DES # encryption without the RFC3961 framing. aes256 = 'aes256-cts-hmac-sha1-96' aes128 = 'aes128-cts-hmac-sha1-96' des3 = 'des3-cbc-sha1' des3raw = 'des3-cbc-raw' rc4 = 'arcfour-hmac' # These tests make assumptions about the default enctype lists, so set # them explicitly rather than relying on the library defaults. enctypes='aes des3 rc4' supp='aes256-cts:normal aes128-cts:normal des3-cbc-sha1:normal rc4-hmac:normal' conf = {'libdefaults': { 'default_tgs_enctypes': enctypes, 'default_tkt_enctypes': enctypes, 'permitted_enctypes': enctypes}, 'realms': {'$realm': {'supported_enctypes': supp}}} realm = K5Realm(krb5_conf=conf) shutil.copyfile(realm.ccache, os.path.join(realm.testdir, 'save')) # Return an argument list for running t_enctypes with optional initiator # and acceptor enctype lists. def cmdline(ienc, aenc): iflags = ienc and ['-i', ienc] or [] aflags = aenc and ['-a', aenc] or [] return ['./t_enctypes'] + iflags + aflags + ['p:' + realm.host_princ] # Run t_enctypes with optional initiator and acceptor enctype lists, # and check that it succeeds with the expected output. Also check # that the ticket we got has the expected encryption key and session # key. def test(msg, ienc, aenc, tktenc='', tktsession='', proto='', isubkey='', asubkey=None): shutil.copyfile(os.path.join(realm.testdir, 'save'), realm.ccache) # Run the test program and check its output. out = realm.run(cmdline(ienc, aenc)).split() if out[0] != proto or out[1] != isubkey: fail(msg) if asubkey is not None and (len(out) < 3 or out[2] != asubkey): fail(msg) lines = realm.run([klist, '-e']).splitlines() for ind, line in enumerate(lines): if realm.host_princ in line: if lines[ind + 1].strip() != ('Etype (skey, tkt): %s, %s' % (tktsession, tktenc)): fail(msg) break # Run t_enctypes with optional initiator and acceptor enctype lists, # and check that it fails with the expected error message. def test_err(msg, ienc, aenc, expected_err): shutil.copyfile(os.path.join(realm.testdir, 'save'), realm.ccache) realm.run(cmdline(ienc, aenc), expected_code=1, expected_msg=expected_err) # By default, all of the key enctypes should be aes256. test('noargs', None, None, tktenc=aes256, tktsession=aes256, proto='cfx', isubkey=aes256, asubkey=aes256) # When the initiator constrains the permitted session enctypes to # aes128, the ticket encryption key should remain aes256. The client # initiator will not send an RFC 4537 upgrade list because it sees no # other permitted enctypes, so the acceptor subkey will not be # upgraded from aes128. test('init aes128', 'aes128-cts', None, tktenc=aes256, tktsession=aes128, proto='cfx', isubkey=aes128, asubkey=aes128) # If the initiator and acceptor both constrain the permitted session # enctypes to aes128, we should see the same keys as above. This # tests that the acceptor does not mistakenly contrain the ticket # encryption key. test('both aes128', 'aes128-cts', 'aes128-cts', tktenc=aes256, tktsession=aes128, proto='cfx', isubkey=aes128, asubkey=aes128) # If only the acceptor constrains the permitted session enctypes to # aes128, subkey negotiation fails because the acceptor considers the # aes256 session key to be non-permitted. test_err('acc aes128', None, 'aes128-cts', 'Encryption type not permitted') # If the initiator constrains the permitted session enctypes to des3, # no acceptor subkey will be generated because we can't upgrade to a # CFX enctype. test('init des3', 'des3', None, tktenc=aes256, tktsession=des3, proto='rfc1964', isubkey=des3raw, asubkey=None) # Force the ticket session key to be rc4, so we can test some subkey # upgrade cases. The ticket encryption key remains aes256. realm.run([kadminl, 'setstr', realm.host_princ, 'session_enctypes', 'rc4']) # With no arguments, the initiator should send an upgrade list of # [aes256 aes128 des3] and the acceptor should upgrade to an aes256 # subkey. test('upgrade noargs', None, None, tktenc=aes256, tktsession=rc4, proto='cfx', isubkey=rc4, asubkey=aes256) # If the initiator won't permit rc4 as a session key, it won't be able # to get a ticket. test_err('upgrade init aes', 'aes', None, 'no support for encryption type') # If the initiator permits rc4 but prefers aes128, it will send an # upgrade list of [aes128] and the acceptor will upgrade to aes128. test('upgrade init aes128+rc4', 'aes128-cts rc4', None, tktenc=aes256, tktsession=rc4, proto='cfx', isubkey=rc4, asubkey=aes128) # If the initiator permits rc4 but prefers des3, it will send an # upgrade list of [des3], but the acceptor won't generate a subkey # because des3 isn't a CFX enctype. test('upgrade init des3+rc4', 'des3 rc4', None, tktenc=aes256, tktsession=rc4, proto='rfc1964', isubkey=rc4, asubkey=None) # If the acceptor permits only aes128, subkey negotiation will fail # because the ticket session key and initiator subkey are # non-permitted. (This is unfortunate if the acceptor's restriction # is only for the sake of the kernel, since we could upgrade to an # aes128 subkey, but it's the current semantics.) test_err('upgrade acc aes128', None, 'aes128-cts', 'Encryption type ArcFour with HMAC/md5 not permitted') # If the acceptor permits rc4 but prefers aes128, it will negotiate an # upgrade to aes128. test('upgrade acc aes128 rc4', None, 'aes128-cts rc4', tktenc=aes256, tktsession=rc4, proto='cfx', isubkey=rc4, asubkey=aes128) # In this test, the initiator and acceptor each prefer an AES enctype # to rc4, but they can't agree on which one, so no subkey is # generated. test('upgrade mismatch', 'aes128-cts rc4', 'aes256-cts rc4', tktenc=aes256, tktsession=rc4, proto='rfc1964', isubkey=rc4, asubkey=None) success('gss_krb5_set_allowable_enctypes tests') krb5-1.16/src/tests/gssapi/t_pcontok.c0000644000704600001450000001626713211554426017575 0ustar ghudsonlibuuid/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* tests/gssapi/t_pcontok.c - gss_process_context_token tests */ /* * Copyright (C) 2014 by the Massachusetts Institute of Technology. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ /* * This test program exercises krb5 gss_process_context_token. It first * establishes a context to a named target. Then, if the resulting context * uses RFC 1964, it creates a context deletion token from the acceptor to the * initiator and passes it to the initiator using gss_process_context_token. * If the established context uses RFC 4121, this program feeds a made-up * context token to gss_process_context_token and checks for the expected * error. */ #include "k5-int.h" #include "common.h" #define SGN_ALG_DES_MAC_MD5 0x00 #define SGN_ALG_HMAC_SHA1_DES3_KD 0x04 #define SGN_ALG_HMAC_MD5 0x11 /* * Create a valid RFC 1964 context deletion token using the information in * * lctx. We must do this by hand since we no longer create context deletion * tokens from gss_delete_sec_context. */ static void make_delete_token(gss_krb5_lucid_context_v1_t *lctx, gss_buffer_desc *out) { krb5_error_code ret; krb5_context context; krb5_keyblock seqkb; krb5_key seq; krb5_checksum cksum; krb5_cksumtype cktype; krb5_keyusage ckusage; krb5_crypto_iov iov; krb5_data d; size_t cksize, tlen; unsigned char *token, *ptr, iv[8]; gss_krb5_lucid_key_t *lkey = &lctx->rfc1964_kd.ctx_key; int signalg = lctx->rfc1964_kd.sign_alg; ret = krb5_init_context(&context); check_k5err(context, "krb5_init_context", ret); seqkb.enctype = lkey->type; seqkb.length = lkey->length; seqkb.contents = lkey->data; ret = krb5_k_create_key(context, &seqkb, &seq); check_k5err(context, "krb5_k_create_key", ret); if (signalg == SGN_ALG_DES_MAC_MD5) { cktype = CKSUMTYPE_RSA_MD5; cksize = 8; ckusage = 0; } else if (signalg == SGN_ALG_HMAC_SHA1_DES3_KD) { cktype = CKSUMTYPE_HMAC_SHA1_DES3; cksize = 20; ckusage = 23; } else if (signalg == SGN_ALG_HMAC_MD5) { cktype = CKSUMTYPE_HMAC_MD5_ARCFOUR; cksize = 8; ckusage = 15; } else { abort(); } tlen = 20 + mech_krb5.length + cksize; token = malloc(tlen); assert(token != NULL); /* Create the ASN.1 wrapper (4 + mech_krb5.length bytes). Assume the ASN.1 * lengths fit in one byte since deletion tokens are short. */ ptr = token; *ptr++ = 0x60; *ptr++ = tlen - 2; *ptr++ = 0x06; *ptr++ = mech_krb5.length; memcpy(ptr, mech_krb5.elements, mech_krb5.length); ptr += mech_krb5.length; /* Create the RFC 1964 token header (8 bytes). */ *ptr++ = 0x01; *ptr++ = 0x02; store_16_le(signalg, ptr); ptr += 2; *ptr++ = 0xFF; *ptr++ = 0xFF; *ptr++ = 0xFF; *ptr++ = 0xFF; /* Create the checksum (cksize bytes at offset 8 from the header). */ d = make_data(ptr - 8, 8); ret = krb5_k_make_checksum(context, cktype, seq, ckusage, &d, &cksum); check_k5err(context, "krb5_k_make_checksum", ret); if (signalg == SGN_ALG_DES_MAC_MD5) { iov.flags = KRB5_CRYPTO_TYPE_DATA; iov.data = make_data(cksum.contents, 16); ret = krb5_k_encrypt_iov(context, seq, 0, NULL, &iov, 1); memcpy(ptr + 8, cksum.contents + 8, 8); } else { memcpy(ptr + 8, cksum.contents, cksize); } /* Create the sequence number (8 bytes). */ iov.flags = KRB5_CRYPTO_TYPE_DATA; iov.data = make_data(ptr, 8); ptr[4] = ptr[5] = ptr[6] = ptr[7] = lctx->initiate ? 0 : 0xFF; memcpy(iv, ptr + 8, 8); d = make_data(iv, 8); if (signalg == SGN_ALG_HMAC_MD5) { store_32_be(lctx->send_seq, ptr); ret = krb5int_arcfour_gsscrypt(&seq->keyblock, 0, &d, &iov, 1); check_k5err(context, "krb5int_arcfour_gsscrypt(seq)", ret); } else { store_32_le(lctx->send_seq, ptr); ret = krb5_k_encrypt_iov(context, seq, 24, &d, &iov, 1); check_k5err(context, "krb5_k_encrypt_iov(seq)", ret); } krb5_free_checksum_contents(context, &cksum); krb5_k_free_key(context, seq); krb5_free_context(context); out->length = tlen; out->value = token; } int main(int argc, char *argv[]) { OM_uint32 minor, major, flags; gss_name_t tname; gss_buffer_desc token, in = GSS_C_EMPTY_BUFFER, out; gss_ctx_id_t ictx, actx; gss_krb5_lucid_context_v1_t *lctx; void *lptr; assert(argc == 2); tname = import_name(argv[1]); flags = GSS_C_REPLAY_FLAG | GSS_C_SEQUENCE_FLAG; establish_contexts(&mech_krb5, GSS_C_NO_CREDENTIAL, GSS_C_NO_CREDENTIAL, tname, flags, &ictx, &actx, NULL, NULL, NULL); /* Export the acceptor context to a lucid context so we can look inside. */ major = gss_krb5_export_lucid_sec_context(&minor, &actx, 1, &lptr); check_gsserr("gss_export_lucid_sec_context", major, minor); lctx = lptr; if (!lctx->protocol) { /* Make an RFC 1964 context deletion token and pass it to * gss_process_context_token. */ make_delete_token(lctx, &token); major = gss_process_context_token(&minor, ictx, &token); free(token.value); check_gsserr("gss_process_context_token", major, minor); /* Check for the appropriate major code from gss_wrap. */ major = gss_wrap(&minor, ictx, 1, GSS_C_QOP_DEFAULT, &in, NULL, &out); assert(major == GSS_S_NO_CONTEXT); } else { /* RFC 4121 defines no context deletion token, so try passing something * arbitrary and check for the appropriate major code. */ token.value = "abcd"; token.length = 4; major = gss_process_context_token(&minor, ictx, &token); assert(major == GSS_S_DEFECTIVE_TOKEN); } (void)gss_release_name(&minor, &tname); (void)gss_delete_sec_context(&minor, &ictx, NULL); (void)gss_krb5_free_lucid_sec_context(&minor, lptr); return 0; } krb5-1.16/src/tests/gssapi/t_credstore.c0000644000704600001450000001177513211554426020111 0ustar ghudsonlibuuid/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* * Copyright 2011 Red Hat, Inc. * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation files * (the "Software"), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, * publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ #include #include #include #include "common.h" static void usage(void) { fprintf(stderr, "Usage: t_credstore [-sabi] principal [{key value} ...]\n"); exit(1); } int main(int argc, char *argv[]) { OM_uint32 minor, major; gss_key_value_set_desc store; gss_name_t name; gss_cred_usage_t cred_usage = GSS_C_BOTH; gss_OID_set mechs = GSS_C_NO_OID_SET; gss_cred_id_t cred = GSS_C_NO_CREDENTIAL; gss_ctx_id_t ictx = GSS_C_NO_CONTEXT, actx = GSS_C_NO_CONTEXT; gss_buffer_desc itok, atok; krb5_boolean store_creds = FALSE, replay = FALSE; char opt; /* Parse options. */ for (argv++; *argv != NULL && **argv == '-'; argv++) { opt = (*argv)[1]; if (opt == 's') store_creds = TRUE; else if (opt == 'r') replay = TRUE; else if (opt == 'a') cred_usage = GSS_C_ACCEPT; else if (opt == 'b') cred_usage = GSS_C_BOTH; else if (opt == 'i') cred_usage = GSS_C_INITIATE; else usage(); } /* Get the principal name. */ if (*argv == NULL) usage(); name = import_name(*argv++); /* Put any remaining arguments into the store. */ store.elements = calloc(argc, sizeof(struct gss_key_value_element_struct)); if (!store.elements) errout("OOM"); store.count = 0; while (*argv != NULL) { if (*(argv + 1) == NULL) usage(); store.elements[store.count].key = *argv; store.elements[store.count].value = *(argv + 1); store.count++; argv += 2; } if (store_creds) { /* Acquire default creds and try to store them in the cred store. */ major = gss_acquire_cred(&minor, GSS_C_NO_NAME, 0, GSS_C_NO_OID_SET, GSS_C_INITIATE, &cred, NULL, NULL); check_gsserr("gss_acquire_cred", major, minor); major = gss_store_cred_into(&minor, cred, GSS_C_INITIATE, GSS_C_NO_OID, 1, 0, &store, NULL, NULL); check_gsserr("gss_store_cred_into", major, minor); gss_release_cred(&minor, &cred); } /* Try to acquire creds from store. */ major = gss_acquire_cred_from(&minor, name, 0, mechs, cred_usage, &store, &cred, NULL, NULL); check_gsserr("gss_acquire_cred_from", major, minor); if (replay) { /* Induce a replay using cred as the acceptor cred, to test the replay * cache indicated by the store. */ major = gss_init_sec_context(&minor, GSS_C_NO_CREDENTIAL, &ictx, name, &mech_krb5, 0, GSS_C_INDEFINITE, GSS_C_NO_CHANNEL_BINDINGS, GSS_C_NO_BUFFER, NULL, &itok, NULL, NULL); check_gsserr("gss_init_sec_context", major, minor); (void)gss_delete_sec_context(&minor, &ictx, NULL); major = gss_accept_sec_context(&minor, &actx, cred, &itok, GSS_C_NO_CHANNEL_BINDINGS, NULL, NULL, &atok, NULL, NULL, NULL); check_gsserr("gss_accept_sec_context(1)", major, minor); (void)gss_release_buffer(&minor, &atok); (void)gss_delete_sec_context(&minor, &actx, NULL); major = gss_accept_sec_context(&minor, &actx, cred, &itok, GSS_C_NO_CHANNEL_BINDINGS, NULL, NULL, &atok, NULL, NULL, NULL); check_gsserr("gss_accept_sec_context(2)", major, minor); (void)gss_release_buffer(&minor, &itok); (void)gss_release_buffer(&minor, &atok); (void)gss_delete_sec_context(&minor, &actx, NULL); } gss_release_name(&minor, &name); gss_release_cred(&minor, &cred); free(store.elements); return 0; } krb5-1.16/src/tests/gssapi/t_spnego.c0000644000704600001450000002717413211554426017412 0ustar ghudsonlibuuid/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* * Copyright 2010 by the Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. * */ #include #include #include #include #include "common.h" static gss_OID_desc mech_krb5_wrong = { 9, "\052\206\110\202\367\022\001\002\002" }; gss_OID_set_desc mechset_krb5_wrong = { 1, &mech_krb5_wrong }; /* * Test program for SPNEGO and gss_set_neg_mechs * * Example usage: * * kinit testuser * ./t_spnego host/test.host@REALM testhost.keytab */ /* Replace *tok and *len with the concatenation of prefix and *tok. */ static void prepend(const void *prefix, size_t plen, uint8_t **tok, size_t *len) { uint8_t *newtok; newtok = malloc(plen + *len); assert(newtok != NULL); memcpy(newtok, prefix, plen); memcpy(newtok + plen, *tok, *len); free(*tok); *tok = newtok; *len = plen + *len; } /* Replace *tok and *len with *tok wrapped in a DER tag with the given tag * byte. *len must be less than 2^16. */ static void der_wrap(uint8_t tag, uint8_t **tok, size_t *len) { char lenbuf[3]; uint8_t *wrapped; size_t llen; if (*len < 128) { lenbuf[0] = *len; llen = 1; } else if (*len < 256) { lenbuf[0] = 0x81; lenbuf[1] = *len; llen = 2; } else { assert(*len >> 16 == 0); lenbuf[0] = 0x82; lenbuf[1] = *len >> 8; lenbuf[2] = *len & 0xFF; llen = 3; } wrapped = malloc(1 + llen + *len); assert(wrapped != NULL); *wrapped = tag; memcpy(wrapped + 1, lenbuf, llen); memcpy(wrapped + 1 + llen, *tok, *len); free(*tok); *tok = wrapped; *len = 1 + llen + *len; } /* * Create a SPNEGO initiator token for the erroneous Microsoft krb5 mech OID, * wrapping a krb5 token ktok. The token should look like: * * 60 (GSS framing sequence) * 06 06 2B 06 01 05 05 02 (SPNEGO OID) * A0 (NegotiationToken choice 0, negTokenInit) * 30 (sequence) * A0 0D (context tag 0, mechTypes) * 30 0B (sequence of) * 06 09 2A 86 48 82 F7 12 01 02 02 (wrong krb5 OID) * A2 (context tag 2, mechToken) * 04 (octet string) * */ static void create_mskrb5_spnego_token(gss_buffer_t ktok, gss_buffer_desc *tok_out) { uint8_t *tok; size_t len; len = ktok->length; tok = malloc(len); assert(tok != NULL); memcpy(tok, ktok->value, len); /* Wrap the krb5 token in OCTET STRING and [2] tags. */ der_wrap(0x04, &tok, &len); der_wrap(0xA2, &tok, &len); /* Prepend the wrong krb5 OID inside OBJECT IDENTIFIER and [0] tags. */ prepend("\xA0\x0D\x30\x0B\x06\x09\x2A\x86\x48\x82\xF7\x12\x01\x02\x02", 15, &tok, &len); /* Wrap the previous two things in SEQUENCE and [0] tags. */ der_wrap(0x30, &tok, &len); der_wrap(0xA0, &tok, &len); /* Prepend the SPNEGO OID in an OBJECT IDENTIFIER tag. */ prepend("\x06\x06\x2B\x06\x01\x05\x05\x02", 8, &tok, &len); /* Wrap the whole thing in an [APPLICATION 0] tag. */ der_wrap(0x60, &tok, &len); tok_out->value = tok; tok_out->length = len; } /* * Test that the SPNEGO acceptor code accepts and properly reflects back the * erroneous Microsoft mech OID in the supportedMech field of the NegTokenResp * message. Use acred as the verifier cred handle. */ static void test_mskrb_oid(gss_name_t tname, gss_cred_id_t acred) { OM_uint32 major, minor; gss_ctx_id_t ictx = GSS_C_NO_CONTEXT, actx = GSS_C_NO_CONTEXT; gss_buffer_desc atok = GSS_C_EMPTY_BUFFER, ktok = GSS_C_EMPTY_BUFFER, stok; const unsigned char *atok_oid; /* * Our SPNEGO mech no longer acquires creds for the wrong mech OID, so we * have to construct a SPNEGO token ourselves. */ major = gss_init_sec_context(&minor, GSS_C_NO_CREDENTIAL, &ictx, tname, &mech_krb5, 0, GSS_C_INDEFINITE, GSS_C_NO_CHANNEL_BINDINGS, &atok, NULL, &ktok, NULL, NULL); check_gsserr("gss_init_sec_context(mskrb)", major, minor); assert(major == GSS_S_COMPLETE); create_mskrb5_spnego_token(&ktok, &stok); /* * Look directly at the DER encoding of the response token. Since we * didn't request mutual authentication, the SPNEGO reply will contain no * underlying mech token; therefore, the encoding of the correct * NegotiationToken response is completely predictable: * * A1 14 (choice 1, length 20, meaning negTokenResp) * 30 12 (sequence, length 18) * A0 03 (context tag 0, length 3) * 0A 01 00 (enumerated value 0, meaning accept-completed) * A1 0B (context tag 1, length 11) * 06 09 (object identifier, length 9) * 2A 86 48 82 F7 12 01 02 02 (the erroneous krb5 OID) * * So we can just compare the length to 22 and the nine bytes at offset 13 * to the expected OID. */ major = gss_accept_sec_context(&minor, &actx, acred, &stok, GSS_C_NO_CHANNEL_BINDINGS, NULL, NULL, &atok, NULL, NULL, NULL); check_gsserr("gss_accept_sec_context(mskrb)", major, minor); assert(atok.length == 22); atok_oid = (unsigned char *)atok.value + 13; assert(memcmp(atok_oid, mech_krb5_wrong.elements, 9) == 0); (void)gss_delete_sec_context(&minor, &ictx, NULL); (void)gss_delete_sec_context(&minor, &actx, NULL); (void)gss_release_buffer(&minor, &ktok); (void)gss_release_buffer(&minor, &atok); free(stok.value); } /* Check that we return a compatibility NegTokenInit2 message containing * NegHints for an empty initiator token. */ static void test_neghints() { OM_uint32 major, minor; gss_buffer_desc itok = GSS_C_EMPTY_BUFFER, atok; gss_ctx_id_t actx = GSS_C_NO_CONTEXT; const char *expected = /* RFC 2743 token framing: [APPLICATION 0] IMPLICIT SEQUENCE followed * by OBJECT IDENTIFIER and the SPNEGO OID */ "\x60\x47\x06\x06" "\x2B\x06\x01\x05\x05\x02" /* [0] SEQUENCE for the NegotiationToken negtokenInit choice */ "\xA0\x3D\x30\x3B" /* [0] MechTypeList containing the krb5 OID */ "\xA0\x0D\x30\x0B\x06\x09" "\x2A\x86\x48\x86\xF7\x12\x01\x02\x02" /* [3] NegHints containing [0] GeneralString containing the dummy * hintName string defined in [MS-SPNG] */ "\xA3\x2A\x30\x28\xA0\x26\x1B\x24" "not_defined_in_RFC4178@please_ignore"; /* Produce a hint token. */ major = gss_accept_sec_context(&minor, &actx, GSS_C_NO_CREDENTIAL, &itok, GSS_C_NO_CHANNEL_BINDINGS, NULL, NULL, &atok, NULL, NULL, NULL); check_gsserr("gss_accept_sec_context(neghints)", major, minor); /* Verify it against the expected contents, which are fixed as long as we * only list the krb5 mech in the token. */ assert(atok.length == strlen(expected)); assert(memcmp(atok.value, expected, atok.length) == 0); (void)gss_release_buffer(&minor, &atok); (void)gss_delete_sec_context(&minor, &actx, NULL); } int main(int argc, char *argv[]) { OM_uint32 minor, major, flags; gss_cred_id_t verifier_cred_handle = GSS_C_NO_CREDENTIAL; gss_cred_id_t initiator_cred_handle = GSS_C_NO_CREDENTIAL; gss_OID_set actual_mechs = GSS_C_NO_OID_SET; gss_ctx_id_t initiator_context, acceptor_context; gss_name_t target_name, source_name = GSS_C_NO_NAME; gss_OID mech = GSS_C_NO_OID; gss_OID_desc pref_oids[2]; gss_OID_set_desc pref_mechs; if (argc < 2 || argc > 3) { fprintf(stderr, "Usage: %s target_name [keytab]\n", argv[0]); exit(1); } target_name = import_name(argv[1]); if (argc >= 3) { major = krb5_gss_register_acceptor_identity(argv[2]); check_gsserr("krb5_gss_register_acceptor_identity", major, 0); } /* Get default initiator cred. */ major = gss_acquire_cred(&minor, GSS_C_NO_NAME, GSS_C_INDEFINITE, &mechset_spnego, GSS_C_INITIATE, &initiator_cred_handle, NULL, NULL); check_gsserr("gss_acquire_cred(initiator)", major, minor); /* * The following test is designed to exercise SPNEGO reselection on the * client and server. Unfortunately, it no longer does so after tickets * #8217 and #8021, since SPNEGO now only acquires a single krb5 cred and * there is no way to expand the underlying creds with gss_set_neg_mechs(). * To fix this we need gss_acquire_cred_with_cred() or some other way to * turn a cred with a specifically requested mech set into a SPNEGO cred. */ /* Make the initiator prefer IAKERB and offer krb5 as an alternative. */ pref_oids[0] = mech_iakerb; pref_oids[1] = mech_krb5; pref_mechs.count = 2; pref_mechs.elements = pref_oids; major = gss_set_neg_mechs(&minor, initiator_cred_handle, &pref_mechs); check_gsserr("gss_set_neg_mechs(initiator)", major, minor); /* Get default acceptor cred. */ major = gss_acquire_cred(&minor, GSS_C_NO_NAME, GSS_C_INDEFINITE, &mechset_spnego, GSS_C_ACCEPT, &verifier_cred_handle, &actual_mechs, NULL); check_gsserr("gss_acquire_cred(acceptor)", major, minor); /* Restrict the acceptor to krb5 (which will force a reselection). */ major = gss_set_neg_mechs(&minor, verifier_cred_handle, &mechset_krb5); check_gsserr("gss_set_neg_mechs(acceptor)", major, minor); flags = GSS_C_REPLAY_FLAG | GSS_C_SEQUENCE_FLAG; establish_contexts(&mech_spnego, initiator_cred_handle, verifier_cred_handle, target_name, flags, &initiator_context, &acceptor_context, &source_name, &mech, NULL); display_canon_name("Source name", source_name, &mech_krb5); display_oid("Source mech", mech); /* Test acceptance of the erroneous Microsoft krb5 OID, with and without an * acceptor cred. */ test_mskrb_oid(target_name, verifier_cred_handle); test_mskrb_oid(target_name, GSS_C_NO_CREDENTIAL); test_neghints(); (void)gss_delete_sec_context(&minor, &initiator_context, NULL); (void)gss_delete_sec_context(&minor, &acceptor_context, NULL); (void)gss_release_name(&minor, &source_name); (void)gss_release_name(&minor, &target_name); (void)gss_release_cred(&minor, &initiator_cred_handle); (void)gss_release_cred(&minor, &verifier_cred_handle); (void)gss_release_oid_set(&minor, &actual_mechs); return 0; } krb5-1.16/src/tests/gssapi/t_lifetime.c0000644000704600001450000001366413211554426017714 0ustar ghudsonlibuuid/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* tests/gssapi/t_lifetime.c - display cred and context lifetimes */ /* * Copyright (C) 2017 by the Massachusetts Institute of Technology. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #include #include #include #include "common.h" /* * Using the default credential, exercise the GSS functions which accept or * produce lifetimes. Display the following results, one per line, as ASCII * integers or the string "indefinite": * * initiator cred lifetime according to gss_acquire_cred() * initiator cred lifetime according to gss_inquire_cred() * acceptor cred lifetime according to gss_acquire_cred() * acceptor cred lifetime according to gss_inquire_cred() * initiator context lifetime according to gss_init_sec_context() * initiator context lifetime according to gss_inquire_context() * initiator context lifetime according to gss_context_time() * acceptor context lifetime according to gss_init_sec_context() * acceptor context lifetime according to gss_inquire_context() * acceptor context lifetime according to gss_context_time() */ static void display_time(OM_uint32 tval) { if (tval == GSS_C_INDEFINITE) puts("indefinite"); else printf("%u\n", (unsigned int)tval); } int main(int argc, char *argv[]) { OM_uint32 minor, major; gss_cred_id_t icred, acred; gss_name_t tname; gss_ctx_id_t ictx = GSS_C_NO_CONTEXT, actx = GSS_C_NO_CONTEXT; gss_buffer_desc itok = GSS_C_EMPTY_BUFFER, atok = GSS_C_EMPTY_BUFFER; OM_uint32 time_req = GSS_C_INDEFINITE, time_rec; if (argc < 2 || argc > 3) { fprintf(stderr, "Usage: %s targetname [time_req]\n", argv[0]); return 1; } tname = import_name(argv[1]); if (argc >= 3) time_req = atoll(argv[2]); /* Get initiator cred and display its lifetime according to * gss_acquire_cred and gss_inquire_cred. */ major = gss_acquire_cred(&minor, GSS_C_NO_NAME, time_req, &mechset_krb5, GSS_C_INITIATE, &icred, NULL, &time_rec); check_gsserr("gss_acquire_cred(initiate)", major, minor); display_time(time_rec); major = gss_inquire_cred(&minor, icred, NULL, &time_rec, NULL, NULL); check_gsserr("gss_inquire_cred(initiate)", major, minor); display_time(time_rec); /* Get acceptor cred and display its lifetime according to gss_acquire_cred * and gss_inquire_cred. */ major = gss_acquire_cred(&minor, GSS_C_NO_NAME, time_req, &mechset_krb5, GSS_C_ACCEPT, &acred, NULL, &time_rec); check_gsserr("gss_acquire_cred(accept)", major, minor); display_time(time_rec); major = gss_inquire_cred(&minor, acred, NULL, &time_rec, NULL, NULL); check_gsserr("gss_inquire_cred(accept)", major, minor); display_time(time_rec); /* Make an initiator context and display its lifetime according to * gss_init_sec_context, gss_inquire_context, and gss_context_time. */ major = gss_init_sec_context(&minor, icred, &ictx, tname, &mech_krb5, 0, time_req, GSS_C_NO_CHANNEL_BINDINGS, &atok, NULL, &itok, NULL, &time_rec); check_gsserr("gss_init_sec_context", major, minor); assert(major == GSS_S_COMPLETE); display_time(time_rec); major = gss_inquire_context(&minor, ictx, NULL, NULL, &time_rec, NULL, NULL, NULL, NULL); check_gsserr("gss_inquire_context(initiate)", major, minor); display_time(time_rec); major = gss_context_time(&minor, ictx, &time_rec); check_gsserr("gss_context_time(initiate)", major, minor); display_time(time_rec); major = gss_accept_sec_context(&minor, &actx, acred, &itok, GSS_C_NO_CHANNEL_BINDINGS, NULL, NULL, &atok, NULL, &time_rec, NULL); check_gsserr("gss_accept_sec_context", major, minor); assert(major == GSS_S_COMPLETE); display_time(time_rec); major = gss_inquire_context(&minor, actx, NULL, NULL, &time_rec, NULL, NULL, NULL, NULL); check_gsserr("gss_inquire_context(accept)", major, minor); display_time(time_rec); major = gss_context_time(&minor, actx, &time_rec); check_gsserr("gss_context_time(accept)", major, minor); display_time(time_rec); (void)gss_release_buffer(&minor, &itok); (void)gss_release_buffer(&minor, &atok); (void)gss_release_name(&minor, &tname); (void)gss_release_cred(&minor, &icred); (void)gss_release_cred(&minor, &acred); (void)gss_delete_sec_context(&minor, &ictx, NULL); (void)gss_delete_sec_context(&minor, &actx, NULL); return 0; } krb5-1.16/src/tests/gssapi/t_inq_cred.c0000644000704600001450000000777113211554426017704 0ustar ghudsonlibuuid/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* tests/gssapi/t_inq_cred.c - Test program for gss_inquire_cred behavior */ /* * Copyright 2012 by the Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ /* * Test program for gss_inquire_cred, intended to be run from a Python test * script. Acquires credentials, inquires them, and prints the resulting name * and lifetime. * * Usage: ./t_inq_cred [-k|-s] [-a|-b|-i] [initiatorname] * * By default no mechanism is specified when acquiring credentials; -k * indicates the krb5 mech and -s indicates SPNEGO. By default or with -i, * initiator credentials are acquired; -a indicates acceptor credentials and -b * indicates credentials of both types. The credential is acquired with no * name by default; a krb5 principal name or host-based name (prefixed with * "gss:") may be supplied as an argument. */ #include #include #include #include "common.h" static void usage(void) { fprintf(stderr, "Usage: t_inq_cred [-k|-s] [-a|-b|-i] [princ|gss:service@host]\n"); exit(1); } int main(int argc, char *argv[]) { OM_uint32 minor, major, lifetime; gss_cred_usage_t cred_usage = GSS_C_INITIATE; gss_OID_set mechs = GSS_C_NO_OID_SET; gss_cred_id_t cred = GSS_C_NO_CREDENTIAL; gss_name_t name = GSS_C_NO_NAME; gss_buffer_desc buf; const char *name_arg = NULL; char opt; while (argc > 1 && argv[1][0] == '-') { opt = argv[1][1]; argc--, argv++; if (opt == 'a') cred_usage = GSS_C_ACCEPT; else if (opt == 'b') cred_usage = GSS_C_BOTH; else if (opt == 'i') cred_usage = GSS_C_INITIATE; else if (opt == 'k') mechs = &mechset_krb5; else if (opt == 's') mechs = &mechset_spnego; else usage(); } if (argc > 2) usage(); if (argc > 1) name_arg = argv[1]; /* Import the name, if given. */ if (name_arg != NULL) name = import_name(name_arg); /* Acquire a credential. */ major = gss_acquire_cred(&minor, name, GSS_C_INDEFINITE, mechs, cred_usage, &cred, NULL, NULL); check_gsserr("gss_acquire_cred", major, minor); /* Inquire about the credential. */ (void)gss_release_name(&minor, &name); major = gss_inquire_cred(&minor, cred, &name, &lifetime, NULL, NULL); check_gsserr("gss_inquire_cred", major, minor); /* Get a display form of the name. */ buf.value = NULL; buf.length = 0; major = gss_display_name(&minor, name, &buf, NULL); check_gsserr("gss_display_name", major, minor); printf("name: %.*s\n", (int)buf.length, (char *)buf.value); printf("lifetime: %d\n", (int)lifetime); (void)gss_release_cred(&minor, &cred); (void)gss_release_name(&minor, &name); (void)gss_release_buffer(&minor, &buf); return 0; } krb5-1.16/src/tests/gssapi/t_export_cred.c0000644000704600001450000001070413211554426020424 0ustar ghudsonlibuuid/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* * Copyright 2011 by the Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #include #include #include "common.h" /* Display a usage error message and exit. */ static void usage(void) { fprintf(stderr, "Usage: t_export_cred [-k|-s] [-i initiatorname] " "[-a acceptorname] targetname\n"); exit(1); } int main(int argc, char *argv[]) { OM_uint32 major, minor, flags; gss_name_t initiator_name = GSS_C_NO_NAME, acceptor_name = GSS_C_NO_NAME; gss_name_t target_name; gss_cred_id_t initiator_cred, acceptor_cred, delegated_cred; gss_ctx_id_t initiator_context = GSS_C_NO_CONTEXT; gss_ctx_id_t acceptor_context = GSS_C_NO_CONTEXT; gss_OID mech = GSS_C_NO_OID; gss_OID_set mechs = GSS_C_NO_OID_SET; char optchar; /* Parse arguments. */ argv++; while (*argv != NULL && **argv == '-') { optchar = (*argv)[1]; argv++; if (optchar == 'i') { if (*argv == NULL) usage(); initiator_name = import_name(*argv++); } else if (optchar == 'a') { if (*argv == NULL) usage(); acceptor_name = import_name(*argv++); } else if (optchar == 'k') { mech = &mech_krb5; mechs = &mechset_krb5; } else if (optchar == 's') { mech = &mech_spnego; mechs = &mechset_spnego; } else { usage(); } } if (*argv == NULL || *(argv + 1) != NULL) usage(); target_name = import_name(argv[0]); /* Get initiator cred and export/import it. */ major = gss_acquire_cred(&minor, initiator_name, GSS_C_INDEFINITE, mechs, GSS_C_INITIATE, &initiator_cred, NULL, NULL); check_gsserr("gss_acquire_cred(initiator)", major, minor); export_import_cred(&initiator_cred); /* Get acceptor cred and export/import it. */ major = gss_acquire_cred(&minor, acceptor_name, GSS_C_INDEFINITE, mechs, GSS_C_ACCEPT, &acceptor_cred, NULL, NULL); check_gsserr("gss_acquire_cred(acceptor)", major, minor); export_import_cred(&acceptor_cred); /* Initiate and accept a security context (one-token exchange only), * delegating credentials. */ flags = GSS_C_REPLAY_FLAG | GSS_C_SEQUENCE_FLAG | GSS_C_CONF_FLAG | GSS_C_INTEG_FLAG | GSS_C_DELEG_FLAG; establish_contexts(mech, initiator_cred, acceptor_cred, target_name, flags, &initiator_context, &acceptor_context, NULL, NULL, &delegated_cred); /* Import, release, export, and store delegated creds */ export_import_cred(&delegated_cred); major = gss_store_cred(&minor, delegated_cred, GSS_C_INITIATE, GSS_C_NULL_OID, 1, 1, NULL, NULL); check_gsserr("gss_store_cred", major, minor); (void)gss_release_name(&minor, &initiator_name); (void)gss_release_name(&minor, &acceptor_name); (void)gss_release_name(&minor, &target_name); (void)gss_release_cred(&minor, &initiator_cred); (void)gss_release_cred(&minor, &acceptor_cred); (void)gss_release_cred(&minor, &delegated_cred); (void)gss_delete_sec_context(&minor, &initiator_context, NULL); (void)gss_delete_sec_context(&minor, &acceptor_context, NULL); return 0; } krb5-1.16/src/tests/gssapi/t_gssapi.py0000755000704600001450000002362013211554426017606 0ustar ghudsonlibuuid#!/usr/bin/python from k5test import * # Test krb5 negotiation under SPNEGO for all enctype configurations. Also # test IOV wrap/unwrap with and without SPNEGO. for realm in multipass_realms(): realm.run(['./t_spnego','p:' + realm.host_princ, realm.keytab]) realm.run(['./t_iov', 'p:' + realm.host_princ]) realm.run(['./t_iov', '-s', 'p:' + realm.host_princ]) realm.run(['./t_pcontok', 'p:' + realm.host_princ]) ### Test acceptor name behavior. realm = K5Realm() # Create some host-based principals and put most of them into the # keytab. Rename one principal so that the keytab name matches the # key but not the client name. realm.run([kadminl, 'addprinc', '-randkey', 'service1/abraham']) realm.run([kadminl, 'addprinc', '-randkey', 'service1/barack']) realm.run([kadminl, 'addprinc', '-randkey', 'service2/calvin']) realm.run([kadminl, 'addprinc', '-randkey', 'service2/dwight']) realm.run([kadminl, 'addprinc', '-randkey', 'host/-nomatch-']) realm.run([kadminl, 'xst', 'service1/abraham']) realm.run([kadminl, 'xst', 'service1/barack']) realm.run([kadminl, 'xst', 'service2/calvin']) realm.run([kadminl, 'renprinc', 'service1/abraham', 'service1/andrew']) # Test with no acceptor name, including client/keytab principal # mismatch (non-fatal) and missing keytab entry (fatal). realm.run(['./t_accname', 'p:service1/andrew'], expected_msg='service1/abraham') realm.run(['./t_accname', 'p:service1/barack'], expected_msg='service1/barack') realm.run(['./t_accname', 'p:service2/calvin'], expected_msg='service2/calvin') realm.run(['./t_accname', 'p:service2/dwight'], expected_code=1, expected_msg=' not found in keytab') # Test with acceptor name containing service only, including # client/keytab hostname mismatch (non-fatal) and service name # mismatch (fatal). realm.run(['./t_accname', 'p:service1/andrew', 'h:service1'], expected_msg='service1/abraham') realm.run(['./t_accname', 'p:service1/andrew', 'h:service2'], expected_code=1, expected_msg=' not found in keytab') realm.run(['./t_accname', 'p:service2/calvin', 'h:service2'], expected_msg='service2/calvin') realm.run(['./t_accname', 'p:service2/calvin', 'h:service1'], expected_code=1, expected_msg=' found in keytab but does not match server principal') # Test with acceptor name containing service and host. Use the # client's un-canonicalized hostname as acceptor input to mirror what # many servers do. realm.run(['./t_accname', 'p:' + realm.host_princ, 'h:host@%s' % socket.gethostname()], expected_msg=realm.host_princ) realm.run(['./t_accname', 'p:host/-nomatch-', 'h:host@%s' % socket.gethostname()], expected_code=1, expected_msg=' not found in keytab') # Test krb5_gss_import_cred. realm.run(['./t_imp_cred', 'p:service1/barack']) realm.run(['./t_imp_cred', 'p:service1/barack', 'service1/barack']) realm.run(['./t_imp_cred', 'p:service1/andrew', 'service1/abraham']) realm.run(['./t_imp_cred', 'p:service2/dwight'], expected_code=1, expected_msg=' not found in keytab') # Test credential store extension. tmpccname = 'FILE:' + os.path.join(realm.testdir, 'def_cache') realm.env['KRB5CCNAME'] = tmpccname storagecache = 'FILE:' + os.path.join(realm.testdir, 'user_store') servicekeytab = os.path.join(realm.testdir, 'kt') service_cs = 'service/cs@%s' % realm.realm realm.addprinc(service_cs) realm.extract_keytab(service_cs, servicekeytab) realm.kinit(service_cs, None, ['-k', '-t', servicekeytab]) realm.run(['./t_credstore', '-s', 'p:' + service_cs, 'ccache', storagecache, 'keytab', servicekeytab]) # Test rcache feature of cred stores. t_credstore -r should produce a # replay error normally, but not with rcache set to "none:". output = realm.run(['./t_credstore', '-r', '-a', 'p:' + realm.host_princ], expected_code=1) if 'gss_accept_sec_context(2): Request is a replay' not in output: fail('Expected replay error not seen in t_credstore output') realm.run(['./t_credstore', '-r', '-a', 'p:' + realm.host_princ, 'rcache', 'none:']) # Verify that we can't acquire acceptor creds without a keytab. os.remove(realm.keytab) output = realm.run(['./t_accname', 'p:abc'], expected_code=1) if ('gss_acquire_cred: Keytab' not in output or 'nonexistent or empty' not in output): fail('Expected error message not seen for nonexistent keytab') realm.stop() # Re-run the last acceptor name test with ignore_acceptor_hostname set # and the principal for the mismatching hostname in the keytab. ignore_conf = {'libdefaults': {'ignore_acceptor_hostname': 'true'}} realm = K5Realm(krb5_conf=ignore_conf) realm.run([kadminl, 'addprinc', '-randkey', 'host/-nomatch-']) realm.run([kadminl, 'xst', 'host/-nomatch-']) realm.run(['./t_accname', 'p:host/-nomatch-', 'h:host@%s' % socket.gethostname()], expected_msg='host/-nomatch-') realm.stop() # Make sure a GSSAPI acceptor can handle cross-realm tickets with a # transited field. (Regression test for #7639.) r1, r2, r3 = cross_realms(3, xtgts=((0,1), (1,2)), create_user=False, create_host=False, args=[{'realm': 'A.X', 'create_user': True}, {'realm': 'X'}, {'realm': 'B.X', 'create_host': True}]) os.rename(r3.keytab, r1.keytab) r1.run(['./t_accname', 'p:' + r3.host_princ, 'h:host']) r1.stop() r2.stop() r3.stop() ### Test gss_inquire_cred behavior. realm = K5Realm() # Test deferred resolution of the default ccache for initiator creds. realm.run(['./t_inq_cred'], expected_msg=realm.user_princ) realm.run(['./t_inq_cred', '-k'], expected_msg=realm.user_princ) realm.run(['./t_inq_cred', '-s'], expected_msg=realm.user_princ) # Test picking a name from the keytab for acceptor creds. realm.run(['./t_inq_cred', '-a'], expected_msg=realm.host_princ) realm.run(['./t_inq_cred', '-k', '-a'], expected_msg=realm.host_princ) realm.run(['./t_inq_cred', '-s', '-a'], expected_msg=realm.host_princ) # Test client keytab initiation (non-deferred) with a specified name. realm.extract_keytab(realm.user_princ, realm.client_keytab) os.remove(realm.ccache) realm.run(['./t_inq_cred', '-k'], expected_msg=realm.user_princ) # Test deferred client keytab initiation and GSS_C_BOTH cred usage. os.remove(realm.client_keytab) os.remove(realm.ccache) shutil.copyfile(realm.keytab, realm.client_keytab) realm.run(['./t_inq_cred', '-k', '-b'], expected_msg=realm.host_princ) # Test gss_export_name behavior. out = realm.run(['./t_export_name', 'u:x']) if out != '0401000B06092A864886F7120102020000000D78404B5242544553542E434F4D\n': fail('Unexpected output from t_export_name (krb5 username)') output = realm.run(['./t_export_name', '-s', 'u:xyz']) if output != '0401000806062B06010505020000000378797A\n': fail('Unexpected output from t_export_name (SPNEGO username)') output = realm.run(['./t_export_name', 'p:a@b']) if output != '0401000B06092A864886F71201020200000003614062\n': fail('Unexpected output from t_export_name (krb5 principal)') output = realm.run(['./t_export_name', '-s', 'p:a@b']) if output != '0401000806062B060105050200000003614062\n': fail('Unexpected output from t_export_name (SPNEGO krb5 principal)') # Test that composite-export tokens can be imported. output = realm.run(['./t_export_name', '-c', 'p:a@b']) if (output != '0402000B06092A864886F7120102020000000361406200000000\n'): fail('Unexpected output from t_export_name (using COMPOSITE_EXPORT)') # Test gss_inquire_mechs_for_name behavior. krb5_mech = '{ 1 2 840 113554 1 2 2 }' spnego_mech = '{ 1 3 6 1 5 5 2 }' out = realm.run(['./t_inq_mechs_name', 'p:a@b']) if krb5_mech not in out: fail('t_inq_mechs_name (principal)') out = realm.run(['./t_inq_mechs_name', 'u:x']) if krb5_mech not in out or spnego_mech not in out: fail('t_inq_mecs_name (user)') out = realm.run(['./t_inq_mechs_name', 'h:host']) if krb5_mech not in out or spnego_mech not in out: fail('t_inq_mecs_name (hostbased)') # Test that accept_sec_context can produce an error token and # init_sec_context can interpret it. realm.run(['./t_err', 'p:' + realm.host_princ]) # Test the GSS_KRB5_CRED_NO_CI_FLAGS_X cred option. realm.run(['./t_ciflags', 'p:' + realm.host_princ]) # Test that inquire_context works properly, even on incomplete # contexts. realm.run(['./t_inq_ctx', 'user', password('user'), 'p:%s' % realm.host_princ]) if runenv.sizeof_time_t <= 4: skip_rest('y2038 GSSAPI tests', 'platform has 32-bit time_t') # Test lifetime results, using a realm with a large maximum lifetime # so that we can test ticket end dates after y2038. realm.stop() conf = {'realms': {'$realm': {'max_life': '9000d'}}} realm = K5Realm(kdc_conf=conf, get_creds=False) # Check a lifetime string result against an expected number value (or None). # Allow some variance due to time elapsed during the tests. def check_lifetime(msg, val, expected): if expected is None and val != 'indefinite': fail('%s: expected indefinite, got %s' % (msg, val)) if expected is not None and val == 'indefinite': fail('%s: expected %d, got indefinite' % (msg, expected)) if expected is not None and abs(int(val) - expected) > 100: fail('%s: expected %d, got %s' % (msg, expected, val)) realm.kinit(realm.user_princ, password('user'), flags=['-l', '8500d']) out = realm.run(['./t_lifetime', 'p:' + realm.host_princ, str(8000 * 86400)]) ln = out.split('\n') check_lifetime('icred gss_acquire_cred', ln[0], 8500 * 86400) check_lifetime('icred gss_inquire_cred', ln[1], 8500 * 86400) check_lifetime('acred gss_acquire_cred', ln[2], None) check_lifetime('acred gss_inquire_cred', ln[3], None) check_lifetime('ictx gss_init_sec_context', ln[4], 8000 * 86400) check_lifetime('ictx gss_inquire_context', ln[5], 8000 * 86400) check_lifetime('ictx gss_context_time', ln[6], 8000 * 86400) check_lifetime('actx gss_accept_sec_context', ln[7], 8000 * 86400 + 300) check_lifetime('actx gss_inquire_context', ln[8], 8000 * 86400 + 300) check_lifetime('actx gss_context_time', ln[9], 8000 * 86400 + 300) success('GSSAPI tests') krb5-1.16/src/tests/gssapi/t_s4u.c0000644000704600001450000003107513211554426016625 0ustar ghudsonlibuuid/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* * Copyright 2009 by the Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ /* * Test program for protocol transition (S4U2Self) and constrained delegation * (S4U2Proxy) * * Note: because of name canonicalization, the following tips may help * when configuring with Active Directory: * * - Create a computer account FOO$ * - Set the UPN to host/foo.domain (no suffix); this is necessary to * be able to send an AS-REQ as this principal, otherwise you would * need to use the canonical name (FOO$), which will cause principal * comparison errors in gss_accept_sec_context(). * - Add a SPN of host/foo.domain * - Configure the computer account to support constrained delegation with * protocol transition (Trust this computer for delegation to specified * services only / Use any authentication protocol) * - Add host/foo.domain to the keytab (possibly easiest to do this * with ktadd) * * For S4U2Proxy to work the TGT must be forwardable too. * * Usage eg: * * kinit -k -t test.keytab -f 'host/test.win.mit.edu@WIN.MIT.EDU' * ./t_s4u p:delegtest@WIN.MIT.EDU p:HOST/WIN-EQ7E4AA2WR8.win.mit.edu@WIN.MIT.EDU test.keytab */ #include #include #include #include "common.h" static int use_spnego = 0; static void test_greet_authz_data(gss_name_t *name) { OM_uint32 major, minor; gss_buffer_desc attr; gss_buffer_desc value; gss_name_t canon; major = gss_canonicalize_name(&minor, *name, &mech_krb5, &canon); check_gsserr("gss_canonicalize_name", major, minor); attr.value = "greet:greeting"; attr.length = strlen((char *)attr.value); value.value = "Hello, acceptor world!"; value.length = strlen((char *)value.value); major = gss_set_name_attribute(&minor, canon, 1, &attr, &value); if (major == GSS_S_UNAVAILABLE) { (void)gss_release_name(&minor, &canon); return; } check_gsserr("gss_set_name_attribute", major, minor); gss_release_name(&minor, name); *name = canon; } static void init_accept_sec_context(gss_cred_id_t claimant_cred_handle, gss_cred_id_t verifier_cred_handle, gss_cred_id_t *deleg_cred_handle) { OM_uint32 major, minor, flags; gss_name_t source_name = GSS_C_NO_NAME, target_name = GSS_C_NO_NAME; gss_ctx_id_t initiator_context, acceptor_context; gss_OID mech = GSS_C_NO_OID; *deleg_cred_handle = GSS_C_NO_CREDENTIAL; major = gss_inquire_cred(&minor, verifier_cred_handle, &target_name, NULL, NULL, NULL); check_gsserr("gss_inquire_cred", major, minor); display_canon_name("Target name", target_name, &mech_krb5); mech = use_spnego ? &mech_spnego : &mech_krb5; display_oid("Target mech", mech); flags = GSS_C_REPLAY_FLAG | GSS_C_SEQUENCE_FLAG; establish_contexts(mech, claimant_cred_handle, verifier_cred_handle, target_name, flags, &initiator_context, &acceptor_context, &source_name, &mech, deleg_cred_handle); display_canon_name("Source name", source_name, &mech_krb5); display_oid("Source mech", mech); enumerate_attributes(source_name, 1); (void)gss_release_name(&minor, &source_name); (void)gss_release_name(&minor, &target_name); (void)gss_delete_sec_context(&minor, &initiator_context, NULL); (void)gss_delete_sec_context(&minor, &acceptor_context, NULL); } static void check_ticket_count(gss_cred_id_t cred, int expected) { krb5_error_code ret; krb5_context context = NULL; krb5_creds kcred; krb5_cc_cursor cur; krb5_ccache ccache; int count = 0; gss_key_value_set_desc store; gss_key_value_element_desc elem; OM_uint32 major, minor; const char *ccname = "MEMORY:count"; store.count = 1; store.elements = &elem; elem.key = "ccache"; elem.value = ccname; major = gss_store_cred_into(&minor, cred, GSS_C_INITIATE, &mech_krb5, 1, 0, &store, NULL, NULL); check_gsserr("gss_store_cred_into", major, minor); ret = krb5_init_context(&context); check_k5err(context, "krb5_init_context", ret); ret = krb5_cc_resolve(context, ccname, &ccache); check_k5err(context, "krb5_cc_resolve", ret); ret = krb5_cc_start_seq_get(context, ccache, &cur); check_k5err(context, "krb5_cc_start_seq_get", ret); while (!krb5_cc_next_cred(context, ccache, &cur, &kcred)) { if (!krb5_is_config_principal(context, kcred.server)) count++; krb5_free_cred_contents(context, &kcred); } ret = krb5_cc_end_seq_get(context, ccache, &cur); check_k5err(context, "krb5_cc_end_seq_get", ret); if (expected != count) { printf("Expected %d tickets but got %d\n", expected, count); exit(1); } krb5_cc_destroy(context, ccache); krb5_free_context(context); } static void constrained_delegate(gss_OID_set desired_mechs, gss_name_t target, gss_cred_id_t delegated_cred_handle, gss_cred_id_t verifier_cred_handle) { OM_uint32 major, minor; gss_ctx_id_t initiator_context = GSS_C_NO_CONTEXT; gss_name_t cred_name = GSS_C_NO_NAME; OM_uint32 time_rec, lifetime; gss_cred_usage_t usage; gss_buffer_desc token; gss_OID_set mechs; printf("Constrained delegation tests follow\n"); printf("-----------------------------------\n\n"); if (gss_inquire_cred(&minor, verifier_cred_handle, &cred_name, &lifetime, &usage, NULL) == GSS_S_COMPLETE) { display_canon_name("Proxy name", cred_name, &mech_krb5); (void)gss_release_name(&minor, &cred_name); } display_canon_name("Target name", target, &mech_krb5); if (gss_inquire_cred(&minor, delegated_cred_handle, &cred_name, &lifetime, &usage, &mechs) == GSS_S_COMPLETE) { display_canon_name("Delegated name", cred_name, &mech_krb5); display_oid("Delegated mech", &mechs->elements[0]); (void)gss_release_name(&minor, &cred_name); } printf("\n"); major = gss_init_sec_context(&minor, delegated_cred_handle, &initiator_context, target, mechs ? &mechs->elements[0] : &mech_krb5, GSS_C_REPLAY_FLAG | GSS_C_SEQUENCE_FLAG, GSS_C_INDEFINITE, GSS_C_NO_CHANNEL_BINDINGS, GSS_C_NO_BUFFER, NULL, &token, NULL, &time_rec); check_gsserr("gss_init_sec_context", major, minor); (void)gss_release_buffer(&minor, &token); (void)gss_delete_sec_context(&minor, &initiator_context, NULL); /* Ensure a second call does not acquire new ticket. */ major = gss_init_sec_context(&minor, delegated_cred_handle, &initiator_context, target, mechs ? &mechs->elements[0] : &mech_krb5, GSS_C_REPLAY_FLAG | GSS_C_SEQUENCE_FLAG, GSS_C_INDEFINITE, GSS_C_NO_CHANNEL_BINDINGS, GSS_C_NO_BUFFER, NULL, &token, NULL, &time_rec); check_gsserr("gss_init_sec_context", major, minor); (void)gss_release_buffer(&minor, &token); (void)gss_delete_sec_context(&minor, &initiator_context, NULL); (void)gss_release_oid_set(&minor, &mechs); /* We expect three tickets: our TGT, the evidence ticket, and the ticket to * the target service. */ check_ticket_count(delegated_cred_handle, 3); } int main(int argc, char *argv[]) { OM_uint32 minor, major; gss_cred_id_t impersonator_cred_handle = GSS_C_NO_CREDENTIAL; gss_cred_id_t user_cred_handle = GSS_C_NO_CREDENTIAL; gss_cred_id_t delegated_cred_handle = GSS_C_NO_CREDENTIAL; gss_name_t user = GSS_C_NO_NAME, target = GSS_C_NO_NAME; gss_OID_set mechs; gss_buffer_set_t bufset = GSS_C_NO_BUFFER_SET; if (argc < 2 || argc > 5) { fprintf(stderr, "Usage: %s [--spnego] [user] " "[proxy-target] [keytab]\n", argv[0]); fprintf(stderr, " proxy-target and keytab are optional\n"); exit(1); } if (strcmp(argv[1], "--spnego") == 0) { use_spnego++; argc--; argv++; } user = import_name(argv[1]); if (argc > 2 && strcmp(argv[2], "-")) target = import_name(argv[2]); if (argc > 3) { major = krb5_gss_register_acceptor_identity(argv[3]); check_gsserr("krb5_gss_register_acceptor_identity", major, 0); } /* Get default cred. */ mechs = use_spnego ? &mechset_spnego : &mechset_krb5; major = gss_acquire_cred(&minor, GSS_C_NO_NAME, GSS_C_INDEFINITE, mechs, GSS_C_BOTH, &impersonator_cred_handle, NULL, NULL); check_gsserr("gss_acquire_cred", major, minor); printf("Protocol transition tests follow\n"); printf("-----------------------------------\n\n"); test_greet_authz_data(&user); /* Get S4U2Self cred. */ major = gss_acquire_cred_impersonate_name(&minor, impersonator_cred_handle, user, GSS_C_INDEFINITE, mechs, GSS_C_INITIATE, &user_cred_handle, NULL, NULL); check_gsserr("gss_acquire_cred_impersonate_name", major, minor); init_accept_sec_context(user_cred_handle, impersonator_cred_handle, &delegated_cred_handle); printf("\n"); if (target != GSS_C_NO_NAME && delegated_cred_handle != GSS_C_NO_CREDENTIAL) { constrained_delegate(mechs, target, delegated_cred_handle, impersonator_cred_handle); } else if (target != GSS_C_NO_NAME) { fprintf(stderr, "Warning: no delegated cred handle returned\n\n"); fprintf(stderr, "Verify:\n\n"); fprintf(stderr, " - The TGT for the impersonating service is " "forwardable\n"); fprintf(stderr, " - The T2A4D flag set on the impersonating service's " "UAC\n"); fprintf(stderr, " - The user is not marked sensitive and cannot be " "delegated\n"); fprintf(stderr, "\n"); } if (delegated_cred_handle != GSS_C_NO_CREDENTIAL) { /* Inquire impersonator status. */ major = gss_inquire_cred_by_oid(&minor, user_cred_handle, GSS_KRB5_GET_CRED_IMPERSONATOR, &bufset); check_gsserr("gss_inquire_cred_by_oid", major, minor); if (bufset->count == 0) errout("gss_inquire_cred_by_oid(user) returned NO impersonator"); (void)gss_release_buffer_set(&minor, &bufset); major = gss_inquire_cred_by_oid(&minor, impersonator_cred_handle, GSS_KRB5_GET_CRED_IMPERSONATOR, &bufset); check_gsserr("gss_inquire_cred_by_oid", major, minor); if (bufset->count != 0) errout("gss_inquire_cred_by_oid(svc) returned an impersonator"); (void)gss_release_buffer_set(&minor, &bufset); } (void)gss_release_name(&minor, &user); (void)gss_release_name(&minor, &target); (void)gss_release_cred(&minor, &delegated_cred_handle); (void)gss_release_cred(&minor, &impersonator_cred_handle); (void)gss_release_cred(&minor, &user_cred_handle); return 0; } krb5-1.16/src/tests/gssapi/t_export_name.c0000644000704600001450000001010113211554426020416 0ustar ghudsonlibuuid/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* tests/gssapi/t_export_name.c - Test program for gss_export_name behavior */ /* * Copyright 2012 by the Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ /* * Test program for gss_export_name, intended to be run from a Python test * script. Imports a name, canonicalizes it to a mech, exports it, * re-imports/exports it to compare results, and then prints the hex form of * the exported name followed by a newline. * * Usage: ./t_export_name [-k|-s] user:username|krb5:princ|host:service@host * * The name is imported as a username, krb5 principal, or hostbased name. * By default or with -k, the name is canonicalized to the krb5 mech; -s * indicates SPNEGO instead. */ #include #include #include #include "common.h" static void usage(void) { fprintf(stderr, "Usage: t_export_name [-k|-s] name\n"); exit(1); } int main(int argc, char *argv[]) { OM_uint32 minor, major; gss_OID mech = (gss_OID)gss_mech_krb5; gss_name_t name, mechname, impname; gss_buffer_desc buf, buf2; krb5_boolean use_composite = FALSE; gss_OID ntype; const char *name_arg; char opt; /* Parse arguments. */ while (argc > 1 && argv[1][0] == '-') { opt = argv[1][1]; argc--, argv++; if (opt == 'k') mech = &mech_krb5; else if (opt == 's') mech = &mech_spnego; else if (opt == 'c') use_composite = TRUE; else usage(); } if (argc != 2) usage(); name_arg = argv[1]; /* Import the name. */ name = import_name(name_arg); /* Canonicalize and export the name. */ major = gss_canonicalize_name(&minor, name, mech, &mechname); check_gsserr("gss_canonicalize_name", major, minor); if (use_composite) major = gss_export_name_composite(&minor, mechname, &buf); else major = gss_export_name(&minor, mechname, &buf); check_gsserr("gss_export_name", major, minor); /* Import and re-export the name, and compare the results. */ ntype = use_composite ? GSS_C_NT_COMPOSITE_EXPORT : GSS_C_NT_EXPORT_NAME; major = gss_import_name(&minor, &buf, ntype, &impname); check_gsserr("gss_import_name", major, minor); if (use_composite) major = gss_export_name_composite(&minor, impname, &buf2); else major = gss_export_name(&minor, impname, &buf2); check_gsserr("gss_export_name", major, minor); if (buf.length != buf2.length || memcmp(buf.value, buf2.value, buf.length) != 0) { fprintf(stderr, "Mismatched results:\n"); print_hex(stderr, &buf); print_hex(stderr, &buf2); return 1; } print_hex(stdout, &buf); (void)gss_release_name(&minor, &name); (void)gss_release_name(&minor, &mechname); (void)gss_release_name(&minor, &impname); (void)gss_release_buffer(&minor, &buf); (void)gss_release_buffer(&minor, &buf2); return 0; } krb5-1.16/src/tests/gssapi/t_prf.c0000644000704600001450000002004213211554426016671 0ustar ghudsonlibuuid/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* * Copyright 2014 by the Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #include "k5-int.h" #include "common.h" #include "mglueP.h" #include "gssapiP_krb5.h" static const char inputstr[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" "abcdefghijklmnopqrstuvwxyz123456789"; /* For each test, out1 corresponds to key1 with an empty input, and out2 * corresponds to key2 with the above 61-byte input string. */ static struct { krb5_enctype enctype; const char *key1; const char *out1; const char *key2; const char *out2; } tests[] = { { ENCTYPE_DES_CBC_CRC, "E607FE9DABB57AE0", "803C4121379FC4B87CE413B67707C4632EBED2C6D6B7" "2A55E878836E35E21600D915D590DED5B6D77BB30A1F", "54758316B6257A75", "279E4105F7ADC9BD6EF28ABE31D89B442FE0058388BA" "33264ACB5729562DC637950F6BD144B654BE7700B2D6" }, { ENCTYPE_DES3_CBC_SHA1, "70378A19CD64134580C27C0115D6B34A1CF2FEECEF9886A2", "9F8D127C520BB826BFF3E0FE5EF352389C17E0C073D9" "AC4A333D644D21BA3EF24F4A886D143F85AC9F6377FB", "3452A167DF1094BA1089E0A20E9E51ABEF1525922558B69E", "6BF24FABC858F8DD9752E4FCD331BB831F238B5BE190" "4EEA42E38F7A60C588F075C5C96A67E7F8B7BD0AECF4" }, { ENCTYPE_ARCFOUR_HMAC, "3BB3AE288C12B3B9D06B208A4151B3B6", "9AEA11A3BCF3C53F1F91F5A0BA2132E2501ADF5F3C28" "3C8A983AB88757CE865A22132D6100EAD63E9E291AFA", "6DB7B33A01BD2B72F7655CB7B3D5FA0B", "CDA9A544869FC84873B692663A82AFDA101C8611498B" "A46138B01E927C9B95EEC953B562807434037837DDDF" }, { ENCTYPE_AES128_CTS_HMAC_SHA1_96, "6C742096EB896230312B73972FA28B5D", "94208D982FC1BB7778128BDD77904420B45C9DA699F3" "117BCE66E39602128EF0296611A6D191A5828530F20F", "FA61138C109D834A477D24C7311BE6DA", "0FAEDF0F842CC834FEE750487E1B622739286B975FE5" "B7F45AB053143C75CA0DF5D3D4BBB80F6A616C7C9027" }, { ENCTYPE_AES256_CTS_HMAC_SHA1_96, "08FCDAFD5832611B73BA7B497FEBFF8C954B4B58031CAD9B977C3B8C25192FD6", "E627EFC14EF5B6D629F830C7109DEA0D3D7D36E8CD57" "A1F301C5452494A1928F05AFFBEE3360232209D3BE0D", "F5B68B7823D8944F33F41541B4E4D38C9B2934F8D16334A796645B066152B4BE", "112F2B2D878590653CCC7DE278E9F0AA46FA5A380B62" "59F774CB7C134FCD37F61A50FD0D9F89BF8FE1A6B593" }, { ENCTYPE_CAMELLIA128_CTS_CMAC, "866E0466A178279A32AC0BDA92B72AEB", "97FBB354BF341C3A160DCC86A7A910FDA824601DF677" "68797BACEEBF5D250AE929DEC9760772084267F50A54", "D4893FD37DA1A211E12DD1E03E0F03B7", "1DEE2FF126CA563A2A2326B9DD3F0095013257414C83" "FAD4398901013D55F367C82681186B7B2FE62F746BA4" }, { ENCTYPE_CAMELLIA256_CTS_CMAC, "203071B1AE77BD3D6FCE70174AF95C225B1CED46B35CF52B6479EFEB47E6B063", "9B30020634C10FDA28420CEE7B96B70A90A771CED43A" "D8346554163E5949CBAE2FB8EF36AFB6B32CE75116A0", "A171AD582C1AFBBAD52ABD622EE6B6A14D19BF95C6914B2BA40FFD99A88EC660", "A47CBB6E104DCC77E4DB48A7A474B977F2FB6A7A1AB6" "52317D50508AE72B7BE2E4E4BA24164E029CBACF786B" }, { ENCTYPE_AES128_CTS_HMAC_SHA256_128, "089BCA48B105EA6EA77CA5D2F39DC5E7", "ED1736209B7C59C9F6A3AE8CCC8A7C97ADFDD11688AD" "F304F2F74252CBACD311A2D9253211FDA49745CE4F62", "3705D96080C17728A0E800EAB6E0D23C", "2BB41B183D76D8D5B30CBB049A7EFE9F350EFA058DC2" "C4D868308D354A7B199BE6FD1F22B53C038BC6036581" }, { ENCTYPE_AES256_CTS_HMAC_SHA384_192, "45BD806DBF6A833A9CFFC1C94589A222367A79BC21C413718906E9F578A78467", "1C613AE8B77A3B4D783F3DCE6C9178FC025E87F48A44" "784A69CB5FC697FE266A6141905067EF78566D309085", "6D404D37FAF79F9DF0D33568D320669800EB4836472EA8A026D16B7182460C52", "D15944B0A44508D1E61213F6455F292A02298F870C01" "A3F74AD0345A4A6651EBE101976E933F32D44F0B5947" }, }; /* Decode hexstr into out. No length checking. */ static size_t fromhex(const char *hexstr, unsigned char *out) { const char *p; size_t count; for (p = hexstr, count = 0; *p != '\0'; p += 2, count++) sscanf(p, "%2hhx", &out[count]); return count; } int main(int argc, char *argv[]) { OM_uint32 minor, major; gss_ctx_id_t context; gss_union_ctx_id_desc uctx; krb5_gss_ctx_id_rec kgctx; krb5_key k1, k2; krb5_keyblock kb1, kb2; gss_buffer_desc in, out; unsigned char k1buf[32], k2buf[32], outbuf[44]; size_t i; /* * Fake up just enough of a krb5 GSS context to make gss_pseudo_random * work, with chosen subkeys and acceptor subkeys. If we implement * gss_import_lucid_sec_context, we can rewrite this to use public * interfaces and stop using private headers and internal knowledge of the * implementation. */ context = (gss_ctx_id_t)&uctx; memset(&uctx, 0, sizeof(uctx)); uctx.mech_type = &mech_krb5; uctx.internal_ctx_id = (gss_ctx_id_t)&kgctx; memset(&kgctx, 0, sizeof(kgctx)); kgctx.k5_context = NULL; kgctx.established = 1; kgctx.have_acceptor_subkey = 1; kb1.contents = k1buf; kb2.contents = k2buf; for (i = 0; i < sizeof(tests) / sizeof(*tests); i++) { /* Set up the keys for this test. */ kb1.enctype = tests[i].enctype; kb1.length = fromhex(tests[i].key1, k1buf); check_k5err(NULL, "create_key", krb5_k_create_key(NULL, &kb1, &k1)); kgctx.subkey = k1; kb2.enctype = tests[i].enctype; kb2.length = fromhex(tests[i].key2, k2buf); check_k5err(NULL, "create_key", krb5_k_create_key(NULL, &kb2, &k2)); kgctx.acceptor_subkey = k2; /* Generate a PRF value with the subkey and an empty input, and compare * it to the first expected output. */ in.length = 0; in.value = NULL; major = gss_pseudo_random(&minor, context, GSS_C_PRF_KEY_PARTIAL, &in, 44, &out); check_gsserr("gss_pseudo_random", major, minor); (void)fromhex(tests[i].out1, outbuf); assert(out.length == 44 && memcmp(out.value, outbuf, 44) == 0); (void)gss_release_buffer(&minor, &out); /* Generate a PRF value with the acceptor subkey and the 61-byte input * string, and compare it to the second expected output. */ in.length = strlen(inputstr); in.value = (char *)inputstr; major = gss_pseudo_random(&minor, context, GSS_C_PRF_KEY_FULL, &in, 44, &out); check_gsserr("gss_pseudo_random", major, minor); (void)fromhex(tests[i].out2, outbuf); assert(out.length == 44 && memcmp(out.value, outbuf, 44) == 0); (void)gss_release_buffer(&minor, &out); /* Also check that generating zero bytes of output works. */ major = gss_pseudo_random(&minor, context, GSS_C_PRF_KEY_FULL, &in, 0, &out); check_gsserr("gss_pseudo_random", major, minor); assert(out.length == 0); (void)gss_release_buffer(&minor, &out); krb5_k_free_key(NULL, k1); krb5_k_free_key(NULL, k2); } return 0; } krb5-1.16/src/tests/gssapi/t_s4u2proxy_krb5.c0000644000704600001450000001571713211554426020741 0ustar ghudsonlibuuid/* -*- mode: c; indent-tabs-mode: nil -*- */ /* tests/gssapi/t_s4u2proxy_deleg.c - Test S4U2Proxy after krb5 auth */ /* * Copyright 2011 by the Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #include #include #include #include "common.h" /* * Usage: ./t_s4u2proxy_krb5 [--spnego] client_cache storage_cache * [accname|-] service1 service2 * * This program performs a regular Kerberos or SPNEGO authentication from the * default principal of client_cache to service1. If that authentication * yields delegated credentials, the program stores those credentials in * sorage_ccache and uses that cache to perform a second authentication to * service2 using S4U2Proxy. * * The default keytab must contain keys for service1 and service2. The default * ccache must contain a TGT for service1. This program assumes that krb5 or * SPNEGO authentication requires only one token exchange. */ int main(int argc, char *argv[]) { const char *client_ccname, *storage_ccname, *accname, *service1, *service2; krb5_context context = NULL; krb5_error_code ret; krb5_boolean use_spnego = FALSE; krb5_ccache storage_ccache = NULL; krb5_principal client_princ = NULL; OM_uint32 minor, major, flags; gss_buffer_desc buf = GSS_C_EMPTY_BUFFER; gss_OID mech; gss_OID_set mechs; gss_name_t acceptor_name = GSS_C_NO_NAME, client_name = GSS_C_NO_NAME; gss_name_t service1_name = GSS_C_NO_NAME, service2_name = GSS_C_NO_NAME; gss_cred_id_t service1_cred = GSS_C_NO_CREDENTIAL; gss_cred_id_t deleg_cred = GSS_C_NO_CREDENTIAL; gss_ctx_id_t initiator_context, acceptor_context; /* Parse arguments. */ if (argc >= 2 && strcmp(argv[1], "--spnego") == 0) { use_spnego = TRUE; argc--; argv++; } if (argc != 6) { fprintf(stderr, "./t_s4u2proxy_krb5 [--spnego] client_ccache " "storage_ccache [accname|-] service1 service2\n"); return 1; } client_ccname = argv[1]; storage_ccname = argv[2]; accname = argv[3]; service1 = argv[4]; service2 = argv[5]; mech = use_spnego ? &mech_spnego : &mech_krb5; mechs = use_spnego ? &mechset_spnego : &mechset_krb5; ret = krb5_init_context(&context); check_k5err(context, "krb5_init_context", ret); /* Get GSS_C_BOTH acceptor credentials, using the default ccache. */ acceptor_name = GSS_C_NO_NAME; if (strcmp(accname, "-") != 0) acceptor_name = import_name(service1); major = gss_acquire_cred(&minor, acceptor_name, GSS_C_INDEFINITE, mechs, GSS_C_BOTH, &service1_cred, NULL, NULL); check_gsserr("gss_acquire_cred(service1)", major, minor); /* Establish contexts using the client ccache. */ service1_name = import_name(service1); major = gss_krb5_ccache_name(&minor, client_ccname, NULL); check_gsserr("gss_krb5_ccache_name(1)", major, minor); flags = GSS_C_REPLAY_FLAG | GSS_C_SEQUENCE_FLAG; establish_contexts(mech, GSS_C_NO_CREDENTIAL, service1_cred, service1_name, flags, &initiator_context, &acceptor_context, &client_name, NULL, &deleg_cred); /* Display and remember the client principal. */ major = gss_display_name(&minor, client_name, &buf, NULL); check_gsserr("gss_display_name(1)", major, minor); printf("auth1: %.*s\n", (int)buf.length, (char *)buf.value); /* Assumes buffer is null-terminated, which in our implementation it is. */ ret = krb5_parse_name(context, buf.value, &client_princ); check_k5err(context, "krb5_parse_name", ret); (void)gss_release_buffer(&minor, &buf); if (deleg_cred == GSS_C_NO_CREDENTIAL) { printf("no credential delegated.\n"); goto cleanup; } /* Take the opportunity to test cred export/import on the synthesized * S4U2Proxy delegated cred. */ export_import_cred(&deleg_cred); /* Store the delegated credentials. */ ret = krb5_cc_resolve(context, storage_ccname, &storage_ccache); check_k5err(context, "krb5_cc_resolve", ret); ret = krb5_cc_initialize(context, storage_ccache, client_princ); check_k5err(context, "krb5_cc_initialize", ret); major = gss_krb5_copy_ccache(&minor, deleg_cred, storage_ccache); check_gsserr("gss_krb5_copy_ccache", major, minor); ret = krb5_cc_close(context, storage_ccache); check_k5err(context, "krb5_cc_close", ret); (void)gss_delete_sec_context(&minor, &initiator_context, GSS_C_NO_BUFFER); (void)gss_delete_sec_context(&minor, &acceptor_context, GSS_C_NO_BUFFER); (void)gss_release_name(&minor, &client_name); (void)gss_release_cred(&minor, &deleg_cred); /* Establish contexts using the storage ccache. */ service2_name = import_name(service2); major = gss_krb5_ccache_name(&minor, storage_ccname, NULL); check_gsserr("gss_krb5_ccache_name(2)", major, minor); establish_contexts(mech, GSS_C_NO_CREDENTIAL, GSS_C_NO_CREDENTIAL, service2_name, flags, &initiator_context, &acceptor_context, &client_name, NULL, &deleg_cred); major = gss_display_name(&minor, client_name, &buf, NULL); check_gsserr("gss_display_name(2)", major, minor); printf("auth2: %.*s\n", (int)buf.length, (char *)buf.value); (void)gss_release_buffer(&minor, &buf); cleanup: (void)gss_release_name(&minor, &acceptor_name); (void)gss_release_name(&minor, &client_name); (void)gss_release_name(&minor, &service1_name); (void)gss_release_name(&minor, &service2_name); (void)gss_release_cred(&minor, &service1_cred); (void)gss_release_cred(&minor, &deleg_cred); (void)gss_delete_sec_context(&minor, &initiator_context, GSS_C_NO_BUFFER); (void)gss_delete_sec_context(&minor, &acceptor_context, GSS_C_NO_BUFFER); krb5_free_principal(context, client_princ); krb5_free_context(context); return 0; } krb5-1.16/src/tests/gssapi/ccinit.c0000644000704600001450000000466113211554426017041 0ustar ghudsonlibuuid/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* tests/gssapi/ccinit.c - Initialize an empty ccache */ /* * Copyright (C) 2012 by the Massachusetts Institute of Technology. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ /* * This program initializes a ccache without attempting to get credentials in * it. It is used to test some finer points of gss_acquire_cred behavior. */ #include "k5-int.h" static void check(krb5_error_code code) { if (code != 0) { com_err("ccinit", code, NULL); abort(); } } int main(int argc, char **argv) { const char *ccname, *princname; krb5_context context; krb5_principal princ; krb5_ccache ccache; if (argc != 3) { fprintf(stderr, "Usage: %s ccname princname\n", argv[0]); return 1; } ccname = argv[1]; princname = argv[2]; check(krb5_init_context(&context)); check(krb5_parse_name(context, princname, &princ)); check(krb5_cc_resolve(context, ccname, &ccache)); check(krb5_cc_initialize(context, ccache, princ)); krb5_cc_close(context, ccache); krb5_free_principal(context, princ); krb5_free_context(context); return 0; } krb5-1.16/src/tests/gssapi/t_saslname.c0000644000704600001450000001472013211554426017713 0ustar ghudsonlibuuid/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* * Copyright 2009 by the Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #include #include #include #include "common.h" static void dump_known_mech_attrs(gss_OID mech) { OM_uint32 major, minor; gss_OID_set mech_attrs = GSS_C_NO_OID_SET; gss_OID_set known_attrs = GSS_C_NO_OID_SET; size_t i; major = gss_inquire_attrs_for_mech(&minor, mech, &mech_attrs, &known_attrs); check_gsserr("gss_inquire_attrs_for_mech", major, minor); printf("Known attributes\n"); printf("----------------\n"); for (i = 0; i < known_attrs->count; i++) { gss_buffer_desc name = GSS_C_EMPTY_BUFFER; gss_buffer_desc short_desc = GSS_C_EMPTY_BUFFER; gss_buffer_desc long_desc = GSS_C_EMPTY_BUFFER; major = gss_display_mech_attr(&minor, &known_attrs->elements[i], &name, &short_desc, &long_desc); check_gsserr("gss_display_mech_attr", major, minor); printf("%.*s (%.*s): %.*s\n", (int)short_desc.length, (char *)short_desc.value, (int)name.length, (char *)name.value, (int)long_desc.length, (char *)long_desc.value); (void)gss_release_buffer(&minor, &name); (void)gss_release_buffer(&minor, &short_desc); (void)gss_release_buffer(&minor, &long_desc); } printf("\n"); (void)gss_release_oid_set(&minor, &mech_attrs); (void)gss_release_oid_set(&minor, &known_attrs); } static void dump_mech_attrs(gss_OID mech) { OM_uint32 major, minor; gss_OID_set mech_attrs = GSS_C_NO_OID_SET; gss_OID_set known_attrs = GSS_C_NO_OID_SET; size_t i; major = gss_inquire_attrs_for_mech(&minor, mech, &mech_attrs, &known_attrs); check_gsserr("gss_inquire_attrs_for_mech", major, minor); printf("Mech attrs: "); for (i = 0; i < mech_attrs->count; i++) { gss_buffer_desc name = GSS_C_EMPTY_BUFFER; gss_buffer_desc short_desc = GSS_C_EMPTY_BUFFER; gss_buffer_desc long_desc = GSS_C_EMPTY_BUFFER; major = gss_display_mech_attr(&minor, &mech_attrs->elements[i], &name, &short_desc, &long_desc); check_gsserr("gss_display_mech_attr", major, minor); printf("%.*s ", (int)name.length, (char *)name.value); (void)gss_release_buffer(&minor, &name); (void)gss_release_buffer(&minor, &short_desc); (void)gss_release_buffer(&minor, &long_desc); } printf("\n"); (void)gss_release_oid_set(&minor, &mech_attrs); (void)gss_release_oid_set(&minor, &known_attrs); } int main(int argc, char *argv[]) { gss_OID_set mechs; OM_uint32 major, minor; size_t i; major = gss_indicate_mechs(&minor, &mechs); check_gsserr("gss_indicate_mechs", major, minor); if (mechs->count > 0) dump_known_mech_attrs(mechs->elements); for (i = 0; i < mechs->count; i++) { gss_buffer_desc oidstr = GSS_C_EMPTY_BUFFER; gss_buffer_desc sasl_mech_name = GSS_C_EMPTY_BUFFER; gss_buffer_desc mech_name = GSS_C_EMPTY_BUFFER; gss_buffer_desc mech_description = GSS_C_EMPTY_BUFFER; gss_OID oid = GSS_C_NO_OID; major = gss_oid_to_str(&minor, &mechs->elements[i], &oidstr); if (GSS_ERROR(major)) continue; major = gss_inquire_saslname_for_mech(&minor, &mechs->elements[i], &sasl_mech_name, &mech_name, &mech_description); if (GSS_ERROR(major)) { gss_release_buffer(&minor, &oidstr); continue; } printf("-------------------------------------------------------------" "-----------------\n"); printf("OID : %.*s\n", (int)oidstr.length, (char *)oidstr.value); printf("SASL mech : %.*s\n", (int)sasl_mech_name.length, (char *)sasl_mech_name.value); printf("Mech name : %.*s\n", (int)mech_name.length, (char *)mech_name.value); printf("Mech desc : %.*s\n", (int)mech_description.length, (char *)mech_description.value); dump_mech_attrs(&mechs->elements[i]); printf("-------------------------------------------------------------" "-----------------\n"); major = gss_inquire_mech_for_saslname(&minor, &sasl_mech_name, &oid); check_gsserr("gss_inquire_mech_for_saslname", major, minor); if (oid == GSS_C_NO_OID || (oid->length != mechs->elements[i].length && memcmp(oid->elements, mechs->elements[i].elements, oid->length) != 0)) { (void)gss_release_buffer(&minor, &oidstr); (void)gss_oid_to_str(&minor, oid, &oidstr); fprintf(stderr, "Got different OID %.*s for mechanism %.*s\n", (int)oidstr.length, (char *)oidstr.value, (int)sasl_mech_name.length, (char *)sasl_mech_name.value); } (void)gss_release_buffer(&minor, &oidstr); (void)gss_release_buffer(&minor, &sasl_mech_name); (void)gss_release_buffer(&minor, &mech_name); (void)gss_release_buffer(&minor, &mech_description); } (void)gss_release_oid_set(&minor, &mechs); return 0; } krb5-1.16/src/tests/gssapi/t_ccselect.c0000644000704600001450000000727113211554426017700 0ustar ghudsonlibuuid/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* tests/gssapi/t_ccselect.c - Test program for GSSAPI cred selection */ /* * Copyright 2011 by the Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #include #include #include #include "common.h" /* * Test program for client credential selection, intended to be run from a * Python test script. Establishes contexts with an optionally specified * initiator name, a specified target name, and the default acceptor cred. If * the exchange is successful, prints the initiator name as seen by the * acceptor. If any call is unsuccessful, displays an error message. Exits * with status 0 if all operations are successful, or 1 if not. * * Usage: ./t_ccselect targetname [initiatorname|-] */ int main(int argc, char *argv[]) { OM_uint32 minor, major, flags; gss_cred_id_t initiator_cred = GSS_C_NO_CREDENTIAL; gss_name_t target_name, initiator_name = GSS_C_NO_NAME; gss_name_t real_initiator_name; gss_buffer_desc namebuf; gss_ctx_id_t initiator_context, acceptor_context; if (argc < 2 || argc > 3) { fprintf(stderr, "Usage: %s targetname [initiatorname|-]\n", argv[0]); return 1; } target_name = import_name(argv[1]); if (argc >= 3) { /* Get initiator cred. */ if (strcmp(argv[2], "-") != 0) initiator_name = import_name(argv[2]); major = gss_acquire_cred(&minor, initiator_name, GSS_C_INDEFINITE, GSS_C_NO_OID_SET, GSS_C_INITIATE, &initiator_cred, NULL, NULL); check_gsserr("gss_acquire_cred", major, minor); } flags = GSS_C_REPLAY_FLAG | GSS_C_SEQUENCE_FLAG; establish_contexts(&mech_krb5, initiator_cred, GSS_C_NO_CREDENTIAL, target_name, flags, &initiator_context, &acceptor_context, &real_initiator_name, NULL, NULL); namebuf.value = NULL; namebuf.length = 0; major = gss_display_name(&minor, real_initiator_name, &namebuf, NULL); check_gsserr("gss_display_name(initiator)", major, minor); printf("%.*s\n", (int)namebuf.length, (char *)namebuf.value); (void)gss_release_name(&minor, &target_name); (void)gss_release_name(&minor, &initiator_name); (void)gss_release_name(&minor, &real_initiator_name); (void)gss_release_cred(&minor, &initiator_cred); (void)gss_delete_sec_context(&minor, &initiator_context, NULL); (void)gss_delete_sec_context(&minor, &acceptor_context, NULL); (void)gss_release_buffer(&minor, &namebuf); return 0; } krb5-1.16/src/tests/gssapi/t_inq_mechs_name.c0000644000704600001450000000450613211554426021057 0ustar ghudsonlibuuid/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* tests/gssapi/t_inq_mechs_name.c - Exercise gss_inquire_mechs_for_name */ /* * Copyright (C) 2012 by the Massachusetts Institute of Technology. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ /* * Test program to exercise gss_inquire_mechs_for_name by importing a name and * reporting the mech OIDs which are reported as being able to process it. * * Usage: ./t_inq_mechs_name name */ #include #include "common.h" int main(int argc, char *argv[]) { OM_uint32 minor, major; gss_name_t name; gss_OID_set mechs; size_t i; if (argc != 2) { fprintf(stderr, "Usage: t_inq_mechs_for_name name\n"); return 1; } name = import_name(argv[1]); major = gss_inquire_mechs_for_name(&minor, name, &mechs); check_gsserr("gss_inquire_mechs_for_name", major, minor); for (i = 0; i < mechs->count; i++) display_oid(NULL, &mechs->elements[i]); (void)gss_release_oid_set(&minor, &mechs); (void)gss_release_name(&minor, &name); return 0; } krb5-1.16/src/tests/gssapi/t_iov.c0000644000704600001450000005355613211554426016717 0ustar ghudsonlibuuid/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* tests/gssapi/t_iov.c - Test program for IOV functions */ /* * Copyright (C) 2013 by the Massachusetts Institute of Technology. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #include #include #include #include #include "common.h" /* Concatenate iov (except for sign-only buffers) into a contiguous token. */ static void concat_iov(gss_iov_buffer_desc *iov, size_t iovlen, char **buf_out, size_t *len_out) { size_t len, i; char *buf; /* Concatenate the result into a contiguous buffer. */ len = 0; for (i = 0; i < iovlen; i++) { if (GSS_IOV_BUFFER_TYPE(iov[i].type) != GSS_IOV_BUFFER_TYPE_SIGN_ONLY) len += iov[i].buffer.length; } buf = malloc(len); if (buf == NULL) errout("malloc failed"); len = 0; for (i = 0; i < iovlen; i++) { if (GSS_IOV_BUFFER_TYPE(iov[i].type) == GSS_IOV_BUFFER_TYPE_SIGN_ONLY) continue; memcpy(buf + len, iov[i].buffer.value, iov[i].buffer.length); len += iov[i].buffer.length; } *buf_out = buf; *len_out = len; } static void check_encrypted(const char *msg, int conf, const char *buf, const char *plain) { int same = memcmp(buf, plain, strlen(plain)) == 0; if ((conf && same) || (!conf && !same)) errout(msg); } /* * Wrap str in standard form (HEADER | DATA | PADDING | TRAILER) using the * caller-provided array iov, which must have space for four elements. Library * allocation will be used for the header/padding/trailer buffers, so the * caller must check and free them. */ static void wrap_std(gss_ctx_id_t ctx, char *str, gss_iov_buffer_desc *iov, int conf) { OM_uint32 minor, major; int oconf; /* Lay out iov array. */ iov[0].type = GSS_IOV_BUFFER_TYPE_HEADER | GSS_IOV_BUFFER_FLAG_ALLOCATE; iov[1].type = GSS_IOV_BUFFER_TYPE_DATA; iov[1].buffer.value = str; iov[1].buffer.length = strlen(str); iov[2].type = GSS_IOV_BUFFER_TYPE_PADDING | GSS_IOV_BUFFER_FLAG_ALLOCATE; iov[3].type = GSS_IOV_BUFFER_TYPE_TRAILER | GSS_IOV_BUFFER_FLAG_ALLOCATE; /* Wrap. This will allocate header/padding/trailer buffers as necessary * and encrypt str in place. */ major = gss_wrap_iov(&minor, ctx, conf, GSS_C_QOP_DEFAULT, &oconf, iov, 4); check_gsserr("gss_wrap_iov(std)", major, minor); if (oconf != conf) errout("gss_wrap_iov(std) conf"); } /* Create standard tokens using gss_wrap_iov and ctx1, and make sure we can * unwrap them using ctx2 in all of the supported ways. */ static void test_standard_wrap(gss_ctx_id_t ctx1, gss_ctx_id_t ctx2, int conf) { OM_uint32 major, minor; gss_iov_buffer_desc iov[4], stiov[2]; gss_qop_t qop; gss_buffer_desc input, output; const char *string1 = "The swift brown fox jumped over the lazy dog."; const char *string2 = "Now is the time!"; const char *string3 = "x"; const char *string4 = "!@#"; char data[1024], *fulltoken; size_t len; int oconf; ptrdiff_t offset; /* Wrap a standard token and unwrap it using the iov array. */ memcpy(data, string1, strlen(string1) + 1); wrap_std(ctx1, data, iov, conf); check_encrypted("gss_wrap_iov(std1) encryption", conf, data, string1); major = gss_unwrap_iov(&minor, ctx2, &oconf, &qop, iov, 4); check_gsserr("gss_unwrap_iov(std1)", major, minor); if (oconf != conf || qop != GSS_C_QOP_DEFAULT) errout("gss_unwrap_iov(std1) conf/qop"); if (iov[1].buffer.value != data || iov[1].buffer.length != strlen(string1)) errout("gss_unwrap_iov(std1) data buffer"); if (memcmp(data, string1, iov[1].buffer.length) != 0) errout("gss_unwrap_iov(std1) decryption"); (void)gss_release_iov_buffer(&minor, iov, 4); /* Wrap a standard token and unwrap it using gss_unwrap(). */ memcpy(data, string2, strlen(string2) + 1); wrap_std(ctx1, data, iov, conf); concat_iov(iov, 4, &fulltoken, &len); input.value = fulltoken; input.length = len; major = gss_unwrap(&minor, ctx2, &input, &output, &oconf, &qop); check_gsserr("gss_unwrap(std2)", major, minor); if (oconf != conf || qop != GSS_C_QOP_DEFAULT) errout("gss_unwrap(std2) conf/qop"); if (output.length != strlen(string2) || memcmp(output.value, string2, output.length) != 0) errout("gss_unwrap(std2) decryption"); (void)gss_release_buffer(&minor, &output); (void)gss_release_iov_buffer(&minor, iov, 4); free(fulltoken); /* Wrap a standard token and unwrap it using a stream buffer. */ memcpy(data, string3, strlen(string3) + 1); wrap_std(ctx1, data, iov, conf); concat_iov(iov, 4, &fulltoken, &len); stiov[0].type = GSS_IOV_BUFFER_TYPE_STREAM; stiov[0].buffer.value = fulltoken; stiov[0].buffer.length = len; stiov[1].type = GSS_IOV_BUFFER_TYPE_DATA; major = gss_unwrap_iov(&minor, ctx2, &oconf, &qop, stiov, 2); check_gsserr("gss_unwrap_iov(std3)", major, minor); if (oconf != conf || qop != GSS_C_QOP_DEFAULT) errout("gss_unwrap_iov(std3) conf/qop"); if (stiov[1].buffer.length != strlen(string3) || memcmp(stiov[1].buffer.value, string3, strlen(string3)) != 0) errout("gss_unwrap_iov(std3) decryption"); offset = (char *)stiov[1].buffer.value - fulltoken; if (offset < 0 || (size_t)offset > len) errout("gss_unwrap_iov(std3) offset"); (void)gss_release_iov_buffer(&minor, iov, 4); free(fulltoken); /* Wrap a token using gss_wrap and unwrap it using a stream buffer with * allocation and copying. */ input.value = (char *)string4; input.length = strlen(string4); major = gss_wrap(&minor, ctx1, conf, GSS_C_QOP_DEFAULT, &input, &oconf, &output); check_gsserr("gss_wrap(std4)", major, minor); if (oconf != conf) errout("gss_wrap(std4) conf"); stiov[0].type = GSS_IOV_BUFFER_TYPE_STREAM; stiov[0].buffer = output; stiov[1].type = GSS_IOV_BUFFER_TYPE_DATA | GSS_IOV_BUFFER_FLAG_ALLOCATE; major = gss_unwrap_iov(&minor, ctx2, &oconf, &qop, stiov, 2); check_gsserr("gss_unwrap_iov(std4)", major, minor); if (!(GSS_IOV_BUFFER_FLAGS(stiov[1].type) & GSS_IOV_BUFFER_FLAG_ALLOCATED)) errout("gss_unwrap_iov(std4) allocated"); if (oconf != conf || qop != GSS_C_QOP_DEFAULT) errout("gss_unwrap_iov(std4) conf/qop"); if (stiov[1].buffer.length != strlen(string4) || memcmp(stiov[1].buffer.value, string4, strlen(string4)) != 0) errout("gss_unwrap_iov(std4) decryption"); (void)gss_release_buffer(&minor, &output); (void)gss_release_iov_buffer(&minor, stiov, 2); } /* * Wrap an AEAD token (HEADER | SIGN_ONLY | DATA | PADDING | TRAILER) using the * caller-provided array iov, which must have space for five elements, and the * caller-provided buffer data, which must be big enough to handle the test * inputs. Library allocation will not be used. */ static void wrap_aead(gss_ctx_id_t ctx, const char *sign, const char *wrap, gss_iov_buffer_desc *iov, char *data, int conf) { OM_uint32 major, minor; int oconf; char *ptr; /* Lay out iov array. */ iov[0].type = GSS_IOV_BUFFER_TYPE_HEADER; iov[1].type = GSS_IOV_BUFFER_TYPE_SIGN_ONLY; iov[1].buffer.value = (char *)sign; iov[1].buffer.length = strlen(sign); iov[2].type = GSS_IOV_BUFFER_TYPE_DATA; iov[2].buffer.value = (char *)wrap; iov[2].buffer.length = strlen(wrap); iov[3].type = GSS_IOV_BUFFER_TYPE_PADDING; iov[4].type = GSS_IOV_BUFFER_TYPE_TRAILER; /* Get header/padding/trailer lengths. */ major = gss_wrap_iov_length(&minor, ctx, conf, GSS_C_QOP_DEFAULT, &oconf, iov, 5); check_gsserr("gss_wrap_iov_length(aead)", major, minor); if (oconf != conf) errout("gss_wrap_iov_length(aead) conf"); if (iov[1].buffer.value != sign || iov[1].buffer.length != strlen(sign)) errout("gss_wrap_iov_length(aead) sign-only buffer"); if (iov[2].buffer.value != wrap || iov[2].buffer.length != strlen(wrap)) errout("gss_wrap_iov_length(aead) data buffer"); /* Set iov buffer pointers using returned lengths. */ iov[0].buffer.value = data; ptr = data + iov[0].buffer.length; memcpy(ptr, wrap, strlen(wrap)); iov[2].buffer.value = ptr; ptr += iov[2].buffer.length; iov[3].buffer.value = ptr; ptr += iov[3].buffer.length; iov[4].buffer.value = ptr; /* Wrap the AEAD token. */ major = gss_wrap_iov(&minor, ctx, conf, GSS_C_QOP_DEFAULT, &oconf, iov, 5); check_gsserr("gss_wrap_iov(aead)", major, minor); if (oconf != conf) errout("gss_wrap_iov(aead) conf"); if (iov[1].buffer.value != sign || iov[1].buffer.length != strlen(sign)) errout("gss_wrap_iov(aead) sign-only buffer"); if (iov[2].buffer.length != strlen(wrap)) errout("gss_wrap_iov(aead) data buffer"); check_encrypted("gss_wrap_iov(aead) encryption", conf, iov[2].buffer.value, wrap); } /* Create AEAD tokens using gss_wrap_iov and ctx1, and make sure we can unwrap * them using ctx2 in all of the supported ways. */ static void test_aead(gss_ctx_id_t ctx1, gss_ctx_id_t ctx2, int conf) { OM_uint32 major, minor; gss_iov_buffer_desc iov[5], stiov[3]; gss_qop_t qop; gss_buffer_desc input, assoc, output; const char *sign = "This data is only signed."; const char *wrap = "This data is wrapped in-place."; char data[1024], *fulltoken; size_t len; int oconf; ptrdiff_t offset; /* Wrap an AEAD token and unwrap it using the IOV array. */ wrap_aead(ctx1, sign, wrap, iov, data, conf); major = gss_unwrap_iov(&minor, ctx2, &oconf, &qop, iov, 5); check_gsserr("gss_unwrap_iov(aead1)", major, minor); if (oconf != conf || qop != GSS_C_QOP_DEFAULT) errout("gss_unwrap_iov(aead1) conf/qop"); if (iov[1].buffer.value != sign || iov[1].buffer.length != strlen(sign)) errout("gss_unwrap_iov(aead1) sign-only buffer"); if (iov[2].buffer.length != strlen(wrap) || memcmp(iov[2].buffer.value, wrap, iov[2].buffer.length) != 0) errout("gss_unwrap_iov(aead1) decryption"); /* Wrap an AEAD token and unwrap it using gss_unwrap_aead. */ wrap_aead(ctx1, sign, wrap, iov, data, conf); concat_iov(iov, 5, &fulltoken, &len); input.value = fulltoken; input.length = len; assoc.value = (char *)sign; assoc.length = strlen(sign); major = gss_unwrap_aead(&minor, ctx2, &input, &assoc, &output, &oconf, &qop); check_gsserr("gss_unwrap_aead(aead2)", major, minor); if (output.length != strlen(wrap) || memcmp(output.value, wrap, output.length) != 0) errout("gss_unwrap_aead(aead2) decryption"); free(fulltoken); (void)gss_release_buffer(&minor, &output); /* Wrap an AEAD token and unwrap it using a stream buffer. */ wrap_aead(ctx1, sign, wrap, iov, data, conf); concat_iov(iov, 5, &fulltoken, &len); stiov[0].type = GSS_IOV_BUFFER_TYPE_STREAM; stiov[0].buffer.value = fulltoken; stiov[0].buffer.length = len; stiov[1].type = GSS_IOV_BUFFER_TYPE_SIGN_ONLY; stiov[1].buffer.value = (char *)sign; stiov[1].buffer.length = strlen(sign); stiov[2].type = GSS_IOV_BUFFER_TYPE_DATA; major = gss_unwrap_iov(&minor, ctx2, &oconf, &qop, stiov, 3); check_gsserr("gss_unwrap_iov(aead3)", major, minor); if (oconf != conf || qop != GSS_C_QOP_DEFAULT) errout("gss_unwrap_iov(aead3) conf/qop"); if (stiov[2].buffer.length != strlen(wrap) || memcmp(stiov[2].buffer.value, wrap, strlen(wrap)) != 0) errout("gss_unwrap_iov(aead3) decryption"); offset = (char *)stiov[2].buffer.value - fulltoken; if (offset < 0 || (size_t)offset > len) errout("gss_unwrap_iov(aead3) offset"); free(fulltoken); (void)gss_release_iov_buffer(&minor, iov, 4); /* Wrap a token using gss_wrap_aead and unwrap it using a stream buffer * with allocation and copying. */ input.value = (char *)wrap; input.length = strlen(wrap); assoc.value = (char *)sign; assoc.length = strlen(sign); major = gss_wrap_aead(&minor, ctx1, conf, GSS_C_QOP_DEFAULT, &assoc, &input, &oconf, &output); check_gsserr("gss_wrap_aead(aead4)", major, minor); if (oconf != conf) errout("gss_wrap(aead4) conf"); stiov[0].type = GSS_IOV_BUFFER_TYPE_STREAM; stiov[0].buffer = output; stiov[1].type = GSS_IOV_BUFFER_TYPE_SIGN_ONLY; stiov[1].buffer = assoc; stiov[2].type = GSS_IOV_BUFFER_TYPE_DATA | GSS_IOV_BUFFER_FLAG_ALLOCATE; major = gss_unwrap_iov(&minor, ctx2, &oconf, &qop, stiov, 3); check_gsserr("gss_unwrap_iov(aead4)", major, minor); if (!(GSS_IOV_BUFFER_FLAGS(stiov[2].type) & GSS_IOV_BUFFER_FLAG_ALLOCATED)) errout("gss_unwrap_iov(aead4) allocated"); if (oconf != conf || qop != GSS_C_QOP_DEFAULT) errout("gss_unwrap_iov(aead4) conf/qop"); if (stiov[2].buffer.length != strlen(wrap) || memcmp(stiov[2].buffer.value, wrap, strlen(wrap)) != 0) errout("gss_unwrap_iov(aead4) decryption"); (void)gss_release_buffer(&minor, &output); (void)gss_release_iov_buffer(&minor, stiov, 3); } /* * Get a MIC for sign1, sign2, and sign3 using the caller-provided array iov, * which must have space for four elements, and the caller-provided buffer * data, which must be big enough for the MIC. If data is NULL, the library * will be asked to allocate the MIC buffer. The MIC will be located in * iov[3].buffer. */ static void mic(gss_ctx_id_t ctx, const char *sign1, const char *sign2, const char *sign3, gss_iov_buffer_desc *iov, char *data) { OM_uint32 minor, major; krb5_boolean allocated; /* Lay out iov array. */ iov[0].type = GSS_IOV_BUFFER_TYPE_DATA; iov[0].buffer.value = (char *)sign1; iov[0].buffer.length = strlen(sign1); iov[1].type = GSS_IOV_BUFFER_TYPE_SIGN_ONLY; iov[1].buffer.value = (char *)sign2; iov[1].buffer.length = strlen(sign2); iov[2].type = GSS_IOV_BUFFER_TYPE_SIGN_ONLY; iov[2].buffer.value = (char *)sign3; iov[2].buffer.length = strlen(sign3); iov[3].type = GSS_IOV_BUFFER_TYPE_MIC_TOKEN; if (data == NULL) { /* Ask the library to allocate the MIC buffer. */ iov[3].type |= GSS_IOV_BUFFER_FLAG_ALLOCATE; } else { /* Get the MIC length and use the caller-provided buffer. */ major = gss_get_mic_iov_length(&minor, ctx, GSS_C_QOP_DEFAULT, iov, 4); check_gsserr("gss_get_mic_iov_length", major, minor); iov[3].buffer.value = data; } major = gss_get_mic_iov(&minor, ctx, GSS_C_QOP_DEFAULT, iov, 4); check_gsserr("gss_get_mic_iov", major, minor); allocated = (GSS_IOV_BUFFER_FLAGS(iov[3].type) & GSS_IOV_BUFFER_FLAG_ALLOCATED) != 0; if (allocated != (data == NULL)) errout("gss_get_mic_iov allocated"); } static void test_mic(gss_ctx_id_t ctx1, gss_ctx_id_t ctx2) { OM_uint32 major, minor; gss_iov_buffer_desc iov[4]; gss_qop_t qop; gss_buffer_desc concatbuf, micbuf; const char *sign1 = "Data and sign-only "; const char *sign2 = "buffers are treated "; const char *sign3 = "equally by gss_get_mic_iov"; char concat[1024], data[1024]; (void)snprintf(concat, sizeof(concat), "%s%s%s", sign1, sign2, sign3); concatbuf.value = concat; concatbuf.length = strlen(concat); /* MIC with a caller-provided buffer and verify with the IOV array. */ mic(ctx1, sign1, sign2, sign3, iov, data); major = gss_verify_mic_iov(&minor, ctx2, &qop, iov, 4); check_gsserr("gss_verify_mic_iov(mic1)", major, minor); if (qop != GSS_C_QOP_DEFAULT) errout("gss_verify_mic_iov(mic1) qop"); /* MIC with an allocated buffer and verify with gss_verify_mic. */ mic(ctx1, sign1, sign2, sign3, iov, NULL); major = gss_verify_mic(&minor, ctx2, &concatbuf, &iov[3].buffer, &qop); check_gsserr("gss_verify_mic(mic2)", major, minor); if (qop != GSS_C_QOP_DEFAULT) errout("gss_verify_mic(mic2) qop"); (void)gss_release_iov_buffer(&minor, iov, 4); /* MIC with gss_c_get_mic and verify using the IOV array (which is still * mostly set up from the last call to mic(). */ major = gss_get_mic(&minor, ctx1, GSS_C_QOP_DEFAULT, &concatbuf, &micbuf); check_gsserr("gss_get_mic(mic3)", major, minor); iov[3].buffer = micbuf; major = gss_verify_mic_iov(&minor, ctx2, &qop, iov, 4); check_gsserr("gss_verify_mic_iov(mic3)", major, minor); if (qop != GSS_C_QOP_DEFAULT) errout("gss_verify_mic_iov(mic3) qop"); (void)gss_release_buffer(&minor, &micbuf); } /* Create a DCE-style token and make sure we can unwrap it. */ static void test_dce(gss_ctx_id_t ctx1, gss_ctx_id_t ctx2, int conf) { OM_uint32 major, minor; gss_iov_buffer_desc iov[4]; gss_qop_t qop; const char *sign1 = "First data to be signed"; const char *sign2 = "Second data to be signed"; const char *wrap = "This data must align to 16 bytes"; int oconf; char data[1024]; /* Wrap a SIGN_ONLY_1 | DATA | SIGN_ONLY_2 | HEADER token. */ memcpy(data, wrap, strlen(wrap) + 1); iov[0].type = GSS_IOV_BUFFER_TYPE_SIGN_ONLY; iov[0].buffer.value = (char *)sign1; iov[0].buffer.length = strlen(sign1); iov[1].type = GSS_IOV_BUFFER_TYPE_DATA; iov[1].buffer.value = data; iov[1].buffer.length = strlen(wrap); iov[2].type = GSS_IOV_BUFFER_TYPE_SIGN_ONLY; iov[2].buffer.value = (char *)sign2; iov[2].buffer.length = strlen(sign2); iov[3].type = GSS_IOV_BUFFER_TYPE_HEADER | GSS_IOV_BUFFER_FLAG_ALLOCATE; major = gss_wrap_iov(&minor, ctx1, conf, GSS_C_QOP_DEFAULT, &oconf, iov, 4); check_gsserr("gss_wrap_iov(dce)", major, minor); if (oconf != conf) errout("gss_wrap_iov(dce) conf"); if (iov[0].buffer.value != sign1 || iov[0].buffer.length != strlen(sign1)) errout("gss_wrap_iov(dce) sign1 buffer"); if (iov[1].buffer.value != data || iov[1].buffer.length != strlen(wrap)) errout("gss_wrap_iov(dce) data buffer"); if (iov[2].buffer.value != sign2 || iov[2].buffer.length != strlen(sign2)) errout("gss_wrap_iov(dce) sign2 buffer"); check_encrypted("gss_wrap_iov(dce) encryption", conf, data, wrap); /* Make sure we can unwrap it. */ major = gss_unwrap_iov(&minor, ctx2, &oconf, &qop, iov, 4); check_gsserr("gss_unwrap_iov(std1)", major, minor); if (oconf != conf || qop != GSS_C_QOP_DEFAULT) errout("gss_unwrap_iov(std1) conf/qop"); if (iov[0].buffer.value != sign1 || iov[0].buffer.length != strlen(sign1)) errout("gss_unwrap_iov(dce) sign1 buffer"); if (iov[1].buffer.value != data || iov[1].buffer.length != strlen(wrap)) errout("gss_unwrap_iov(dce) data buffer"); if (iov[2].buffer.value != sign2 || iov[2].buffer.length != strlen(sign2)) errout("gss_unwrap_iov(dce) sign2 buffer"); if (memcmp(data, wrap, iov[1].buffer.length) != 0) errout("gss_unwrap_iov(dce) decryption"); (void)gss_release_iov_buffer(&minor, iov, 4); } int main(int argc, char *argv[]) { OM_uint32 minor, flags; gss_OID mech = &mech_krb5; gss_name_t tname; gss_ctx_id_t ictx, actx; /* Parse arguments. */ argv++; if (*argv != NULL && strcmp(*argv, "-s") == 0) { mech = &mech_spnego; argv++; } if (*argv == NULL || *(argv + 1) != NULL) errout("Usage: t_iov [-s] targetname"); tname = import_name(*argv); flags = GSS_C_REPLAY_FLAG | GSS_C_SEQUENCE_FLAG | GSS_C_MUTUAL_FLAG; establish_contexts(mech, GSS_C_NO_CREDENTIAL, GSS_C_NO_CREDENTIAL, tname, flags, &ictx, &actx, NULL, NULL, NULL); /* Test standard token wrapping and unwrapping in both directions, with and * without confidentiality. */ test_standard_wrap(ictx, actx, 0); test_standard_wrap(ictx, actx, 1); test_standard_wrap(actx, ictx, 0); test_standard_wrap(actx, ictx, 1); /* Test AEAD wrapping. */ test_aead(ictx, actx, 0); test_aead(ictx, actx, 1); test_aead(actx, ictx, 0); test_aead(actx, ictx, 1); /* Test MIC tokens. */ test_mic(ictx, actx); test_mic(actx, ictx); /* Test DCE wrapping with DCE-style contexts. */ (void)gss_delete_sec_context(&minor, &ictx, NULL); (void)gss_delete_sec_context(&minor, &actx, NULL); flags = GSS_C_REPLAY_FLAG | GSS_C_SEQUENCE_FLAG | GSS_C_DCE_STYLE; establish_contexts(mech, GSS_C_NO_CREDENTIAL, GSS_C_NO_CREDENTIAL, tname, flags, &ictx, &actx, NULL, NULL, NULL); test_dce(ictx, actx, 0); test_dce(ictx, actx, 1); test_dce(actx, ictx, 0); test_dce(actx, ictx, 1); (void)gss_release_name(&minor, &tname); (void)gss_delete_sec_context(&minor, &ictx, NULL); (void)gss_delete_sec_context(&minor, &actx, NULL); return 0; } krb5-1.16/src/tests/gssapi/t_srcattrs.c0000644000704600001450000000454613211554426017762 0ustar ghudsonlibuuid/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* src/tests/gssapi/t_accname_authind.c - test harness for auth indicators */ /* * Copyright (C) 2016 by Red Hat, Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #include #include #include "common.h" /* Establish a context to the given target name and enumerate the attributes of * the source name. */ int main(int argc, char *argv[]) { OM_uint32 minor, flags; gss_name_t tname, sname; gss_ctx_id_t ictx, actx; if (argc != 2) { fprintf(stderr, "Usage: %s targetname\n", argv[0]); return 1; } tname = import_name(argv[1]); flags = GSS_C_REPLAY_FLAG | GSS_C_SEQUENCE_FLAG; establish_contexts(&mech_krb5, GSS_C_NO_CREDENTIAL, GSS_C_NO_CREDENTIAL, tname, flags, &ictx, &actx, &sname, NULL, NULL); enumerate_attributes(sname, 1); (void)gss_release_name(&minor, &tname); (void)gss_release_name(&minor, &sname); (void)gss_delete_sec_context(&minor, &ictx, NULL); (void)gss_delete_sec_context(&minor, &actx, NULL); return 0; } krb5-1.16/src/tests/gssapi/common.c0000644000704600001450000002051213211554426017051 0ustar ghudsonlibuuid/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* tests/gssapi/common.c - Common utility functions for GSSAPI test programs */ /* * Copyright (C) 2012 by the Massachusetts Institute of Technology. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #include #include #include "common.h" gss_OID_desc mech_krb5 = { 9, "\052\206\110\206\367\022\001\002\002" }; gss_OID_desc mech_spnego = { 6, "\053\006\001\005\005\002" }; gss_OID_desc mech_iakerb = { 6, "\053\006\001\005\002\005" }; gss_OID_set_desc mechset_krb5 = { 1, &mech_krb5 }; gss_OID_set_desc mechset_spnego = { 1, &mech_spnego }; gss_OID_set_desc mechset_iakerb = { 1, &mech_iakerb }; static void display_status(const char *msg, OM_uint32 code, int type) { OM_uint32 min_stat, msg_ctx = 0; gss_buffer_desc buf; do { (void)gss_display_status(&min_stat, code, type, GSS_C_NULL_OID, &msg_ctx, &buf); fprintf(stderr, "%s: %.*s\n", msg, (int)buf.length, (char *)buf.value); (void)gss_release_buffer(&min_stat, &buf); } while (msg_ctx != 0); } void check_gsserr(const char *msg, OM_uint32 major, OM_uint32 minor) { if (GSS_ERROR(major)) { display_status(msg, major, GSS_C_GSS_CODE); display_status(msg, minor, GSS_C_MECH_CODE); exit(1); } } void check_k5err(krb5_context context, const char *msg, krb5_error_code code) { const char *errmsg; if (code) { errmsg = krb5_get_error_message(context, code); printf("%s: %s\n", msg, errmsg); krb5_free_error_message(context, errmsg); exit(1); } } void errout(const char *msg) { fprintf(stderr, "%s\n", msg); exit(1); } gss_name_t import_name(const char *str) { OM_uint32 major, minor; gss_name_t name; gss_buffer_desc buf; gss_OID nametype = NULL; if (*str == 'u') nametype = GSS_C_NT_USER_NAME; else if (*str == 'p') nametype = (gss_OID)GSS_KRB5_NT_PRINCIPAL_NAME; else if (*str == 'h') nametype = GSS_C_NT_HOSTBASED_SERVICE; if (nametype == NULL || str[1] != ':') errout("names must begin with u: or p: or h:"); buf.value = (char *)str + 2; buf.length = strlen(str) - 2; major = gss_import_name(&minor, &buf, nametype, &name); check_gsserr("gss_import_name", major, minor); return name; } void establish_contexts(gss_OID imech, gss_cred_id_t icred, gss_cred_id_t acred, gss_name_t tname, OM_uint32 flags, gss_ctx_id_t *ictx, gss_ctx_id_t *actx, gss_name_t *src_name, gss_OID *amech, gss_cred_id_t *deleg_cred) { OM_uint32 minor, imaj, amaj; gss_buffer_desc itok, atok; *ictx = *actx = GSS_C_NO_CONTEXT; imaj = amaj = GSS_S_CONTINUE_NEEDED; itok.value = atok.value = NULL; itok.length = atok.length = 0; for (;;) { (void)gss_release_buffer(&minor, &itok); imaj = gss_init_sec_context(&minor, icred, ictx, tname, imech, flags, GSS_C_INDEFINITE, GSS_C_NO_CHANNEL_BINDINGS, &atok, NULL, &itok, NULL, NULL); check_gsserr("gss_init_sec_context", imaj, minor); if (amaj == GSS_S_COMPLETE) break; (void)gss_release_buffer(&minor, &atok); amaj = gss_accept_sec_context(&minor, actx, acred, &itok, GSS_C_NO_CHANNEL_BINDINGS, src_name, amech, &atok, NULL, NULL, deleg_cred); check_gsserr("gss_accept_sec_context", amaj, minor); (void)gss_release_buffer(&minor, &itok); if (imaj == GSS_S_COMPLETE) break; } if (imaj != GSS_S_COMPLETE || amaj != GSS_S_COMPLETE) errout("One side wants to continue after the other is done"); (void)gss_release_buffer(&minor, &itok); (void)gss_release_buffer(&minor, &atok); } void export_import_cred(gss_cred_id_t *cred) { OM_uint32 major, minor; gss_buffer_desc buf; major = gss_export_cred(&minor, *cred, &buf); check_gsserr("gss_export_cred", major, minor); (void)gss_release_cred(&minor, cred); major = gss_import_cred(&minor, &buf, cred); check_gsserr("gss_import_cred", major, minor); (void)gss_release_buffer(&minor, &buf); } void display_canon_name(const char *tag, gss_name_t name, gss_OID mech) { gss_name_t canon; OM_uint32 major, minor; gss_buffer_desc buf; major = gss_canonicalize_name(&minor, name, mech, &canon); check_gsserr("gss_canonicalize_name", major, minor); major = gss_display_name(&minor, canon, &buf, NULL); check_gsserr("gss_display_name", major, minor); printf("%s:\t%.*s\n", tag, (int)buf.length, (char *)buf.value); (void)gss_release_name(&minor, &canon); (void)gss_release_buffer(&minor, &buf); } void display_oid(const char *tag, gss_OID oid) { OM_uint32 major, minor; gss_buffer_desc buf; major = gss_oid_to_str(&minor, oid, &buf); check_gsserr("gss_oid_to_str", major, minor); if (tag != NULL) printf("%s:\t", tag); printf("%.*s\n", (int)buf.length, (char *)buf.value); (void)gss_release_buffer(&minor, &buf); } static void dump_attribute(gss_name_t name, gss_buffer_t attribute, int noisy) { OM_uint32 major, minor; gss_buffer_desc value; gss_buffer_desc display_value; int authenticated = 0; int complete = 0; int more = -1; unsigned int i; while (more != 0) { value.value = NULL; display_value.value = NULL; major = gss_get_name_attribute(&minor, name, attribute, &authenticated, &complete, &value, &display_value, &more); check_gsserr("gss_get_name_attribute", major, minor); printf("Attribute %.*s %s %s\n\n%.*s\n", (int)attribute->length, (char *)attribute->value, authenticated ? "Authenticated" : "", complete ? "Complete" : "", (int)display_value.length, (char *)display_value.value); if (noisy) { for (i = 0; i < value.length; i++) { if ((i % 32) == 0) printf("\n"); printf("%02x", ((char *)value.value)[i] & 0xFF); } printf("\n\n"); } (void)gss_release_buffer(&minor, &value); (void)gss_release_buffer(&minor, &display_value); } } void enumerate_attributes(gss_name_t name, int noisy) { OM_uint32 major, minor; int is_mechname; gss_buffer_set_t attrs = GSS_C_NO_BUFFER_SET; size_t i; major = gss_inquire_name(&minor, name, &is_mechname, NULL, &attrs); check_gsserr("gss_inquire_name", major, minor); if (attrs != GSS_C_NO_BUFFER_SET) { for (i = 0; i < attrs->count; i++) dump_attribute(name, &attrs->elements[i], noisy); } (void)gss_release_buffer_set(&minor, &attrs); } void print_hex(FILE *fp, gss_buffer_t buf) { size_t i; const unsigned char *bytes = buf->value; for (i = 0; i < buf->length; i++) printf("%02X", bytes[i]); printf("\n"); } krb5-1.16/src/tests/gssapi/t_client_keytab.py0000755000704600001450000001144013211554426021132 0ustar ghudsonlibuuid#!/usr/bin/python from k5test import * # Set up a basic realm and a client keytab containing two user principals. # Point HOME at realm.testdir for tests using .k5identity. realm = K5Realm(get_creds=False) bob = 'bob@' + realm.realm phost = 'p:' + realm.host_princ puser = 'p:' + realm.user_princ pbob = 'p:' + bob gssserver = 'h:host@' + hostname realm.env['HOME'] = realm.testdir realm.addprinc(bob, password('bob')) realm.extract_keytab(realm.user_princ, realm.client_keytab) realm.extract_keytab(bob, realm.client_keytab) # Test 1: no name/cache specified, pick first principal from client keytab realm.run(['./t_ccselect', phost], expected_msg=realm.user_princ) realm.run([kdestroy]) # Test 2: no name/cache specified, pick principal from k5identity k5idname = os.path.join(realm.testdir, '.k5identity') k5id = open(k5idname, 'w') k5id.write('%s service=host host=%s\n' % (bob, hostname)) k5id.close() realm.run(['./t_ccselect', gssserver], expected_msg=bob) os.remove(k5idname) realm.run([kdestroy]) # Test 3: no name/cache specified, default ccache has name but no creds realm.run(['./ccinit', realm.ccache, bob]) realm.run(['./t_ccselect', phost], expected_msg=bob) # Leave tickets for next test. # Test 4: name specified, non-collectable default cache doesn't match msg = 'Principal in credential cache does not match desired name' realm.run(['./t_ccselect', phost, puser], expected_code=1, expected_msg=msg) realm.run([kdestroy]) # Test 5: name specified, nonexistent default cache realm.run(['./t_ccselect', phost, pbob], expected_msg=bob) # Leave tickets for next test. # Test 6: name specified, matches default cache, time to refresh realm.run(['./ccrefresh', realm.ccache, '1']) realm.run(['./t_ccselect', phost, pbob], expected_msg=bob) out = realm.run(['./ccrefresh', realm.ccache]) if int(out) < 1000: fail('Credentials apparently not refreshed') realm.run([kdestroy]) # Test 7: empty ccache specified, pick first principal from client keytab realm.run(['./t_imp_cred', phost]) realm.klist(realm.user_princ) realm.run([kdestroy]) # Test 8: ccache specified with name but no creds; name not in client keytab realm.run(['./ccinit', realm.ccache, realm.host_princ]) realm.run(['./t_imp_cred', phost], expected_code=1, expected_msg='Credential cache is empty') realm.run([kdestroy]) # Test 9: ccache specified with name but no creds; name in client keytab realm.run(['./ccinit', realm.ccache, bob]) realm.run(['./t_imp_cred', phost]) realm.klist(bob) # Leave tickets for next test. # Test 10: ccache specified with creds, time to refresh realm.run(['./ccrefresh', realm.ccache, '1']) realm.run(['./t_imp_cred', phost]) realm.klist(bob) out = realm.run(['./ccrefresh', realm.ccache]) if int(out) < 1000: fail('Credentials apparently not refreshed') realm.run([kdestroy]) # Test 11: gss_import_cred_from with client_keytab value store_keytab = os.path.join(realm.testdir, 'store_keytab') os.rename(realm.client_keytab, store_keytab) realm.run(['./t_credstore', '-i', 'p:' + realm.user_princ, 'client_keytab', store_keytab]) realm.klist(realm.user_princ) os.rename(store_keytab, realm.client_keytab) # Use a cache collection for the remaining tests. ccdir = os.path.join(realm.testdir, 'cc') ccname = 'DIR:' + ccdir os.mkdir(ccdir) realm.env['KRB5CCNAME'] = ccname # Test 12: name specified, matching cache in collection with no creds bobcache = os.path.join(ccdir, 'tktbob') realm.run(['./ccinit', bobcache, bob]) realm.run(['./t_ccselect', phost, pbob], expected_msg=bob) # Leave tickets for next test. # Test 13: name specified, matching cache in collection, time to refresh realm.run(['./ccrefresh', bobcache, '1']) realm.run(['./t_ccselect', phost, pbob], expected_msg=bob) out = realm.run(['./ccrefresh', bobcache]) if int(out) < 1000: fail('Credentials apparently not refreshed') realm.run([kdestroy, '-A']) # Test 14: name specified, collection has default for different principal realm.kinit(realm.user_princ, password('user')) realm.run(['./t_ccselect', phost, pbob], expected_msg=bob) msg = 'Default principal: %s\n' % realm.user_princ realm.run([klist], expected_msg=msg) realm.run([kdestroy, '-A']) # Test 15: name specified, collection has no default cache realm.run(['./t_ccselect', phost, pbob], expected_msg=bob) # Make sure the tickets we acquired didn't become the default realm.run([klist], expected_code=1, expected_msg='No credentials cache found') realm.run([kdestroy, '-A']) # Test 16: default client keytab cannot be resolved, but valid # credentials exist in ccache. conf = {'libdefaults': {'default_client_keytab_name': '%{'}} bad_cktname = realm.special_env('bad_cktname', False, krb5_conf=conf) del bad_cktname['KRB5_CLIENT_KTNAME'] realm.kinit(realm.user_princ, password('user')) realm.run(['./t_ccselect', phost], env=bad_cktname, expected_msg=realm.user_princ) success('Client keytab tests') krb5-1.16/src/tests/gssapi/t_namingexts.c0000644000704600001450000001657013211554426020272 0ustar ghudsonlibuuid/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* * Copyright 2009 by the Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #include #include #include #include "common.h" static int use_spnego = 0; static void display_name(const char *tag, gss_name_t name) { OM_uint32 major, minor; gss_buffer_desc buf; major = gss_display_name(&minor, name, &buf, NULL); check_gsserr("gss_display_name", major, minor); printf("%s:\t%.*s\n", tag, (int)buf.length, (char *)buf.value); (void)gss_release_buffer(&minor, &buf); } static void test_export_import_name(gss_name_t name) { OM_uint32 major, minor; gss_buffer_desc exported_name = GSS_C_EMPTY_BUFFER; gss_name_t imported_name = GSS_C_NO_NAME; gss_name_t imported_name_comp = GSS_C_NO_NAME; unsigned int i; major = gss_export_name_composite(&minor, name, &exported_name); check_gsserr("gss_export_name_composite", major, minor); printf("Exported name:\n"); for (i = 0; i < exported_name.length; i++) { if ((i % 32) == 0) printf("\n"); printf("%02x", ((char *)exported_name.value)[i] & 0xFF); } printf("\n"); major = gss_import_name(&minor, &exported_name, GSS_C_NT_EXPORT_NAME, &imported_name); check_gsserr("gss_import_name", major, minor); major = gss_import_name(&minor, &exported_name, GSS_C_NT_COMPOSITE_EXPORT, &imported_name_comp); check_gsserr("gss_import_name", major, minor); (void)gss_release_buffer(&minor, &exported_name); printf("\n"); display_canon_name("Re-imported name", imported_name, &mech_krb5); printf("Re-imported attributes:\n\n"); enumerate_attributes(imported_name, 0); display_name("Re-imported (as composite) name", imported_name_comp); printf("Re-imported (as composite) attributes:\n\n"); enumerate_attributes(imported_name_comp, 0); (void)gss_release_name(&minor, &imported_name); (void)gss_release_name(&minor, &imported_name_comp); } static void test_greet_authz_data(gss_name_t name) { OM_uint32 major, minor; gss_buffer_desc attr; gss_buffer_desc value; attr.value = "urn:greet:greeting"; attr.length = strlen((char *)attr.value); major = gss_delete_name_attribute(&minor, name, &attr); if (major == GSS_S_UNAVAILABLE) { fprintf(stderr, "Warning: greet_client plugin not installed\n"); exit(1); } check_gsserr("gss_delete_name_attribute", major, minor); value.value = "Hello, acceptor world!"; value.length = strlen((char *)value.value); major = gss_set_name_attribute(&minor, name, 1, &attr, &value); if (major == GSS_S_UNAVAILABLE) return; check_gsserr("gss_set_name_attribute", major, minor); } static void test_map_name_to_any(gss_name_t name) { OM_uint32 major, minor; gss_buffer_desc type_id; krb5_pac pac; krb5_context context = NULL; krb5_error_code ret; size_t len, i; krb5_ui_4 *types; type_id.value = "mspac"; type_id.length = strlen((char *)type_id.value); major = gss_map_name_to_any(&minor, name, 1, &type_id, (gss_any_t *)&pac); if (major == GSS_S_UNAVAILABLE) return; check_gsserr("gss_map_name_to_any", major, minor); ret = krb5_init_context(&context); check_k5err(context, "krb5_init_context", ret); if (krb5_pac_get_types(context, pac, &len, &types) == 0) { printf("PAC buffer types:"); for (i = 0; i < len; i++) printf(" %d", types[i]); printf("\n"); free(types); } (void)gss_release_any_name_mapping(&minor, name, &type_id, (gss_any_t *)&pac); } static void init_accept_sec_context(gss_cred_id_t verifier_cred_handle) { OM_uint32 major, minor, flags; gss_name_t source_name = GSS_C_NO_NAME, target_name = GSS_C_NO_NAME; gss_ctx_id_t initiator_context, acceptor_context; gss_OID mech = use_spnego ? &mech_spnego : &mech_krb5; major = gss_inquire_cred(&minor, verifier_cred_handle, &target_name, NULL, NULL, NULL); check_gsserr("gss_inquire_cred", major, minor); display_canon_name("Target name", target_name, &mech_krb5); flags = GSS_C_REPLAY_FLAG | GSS_C_SEQUENCE_FLAG; establish_contexts(mech, verifier_cred_handle, verifier_cred_handle, target_name, flags, &initiator_context, &acceptor_context, &source_name, NULL, NULL); display_canon_name("Source name", source_name, &mech_krb5); enumerate_attributes(source_name, 1); test_export_import_name(source_name); test_map_name_to_any(source_name); (void)gss_release_name(&minor, &source_name); (void)gss_release_name(&minor, &target_name); (void)gss_delete_sec_context(&minor, &initiator_context, NULL); (void)gss_delete_sec_context(&minor, &acceptor_context, NULL); } int main(int argc, char *argv[]) { OM_uint32 minor, major; gss_cred_id_t cred_handle = GSS_C_NO_CREDENTIAL; gss_OID_set mechs, actual_mechs = GSS_C_NO_OID_SET; gss_name_t tmp_name, name; if (argc > 1 && strcmp(argv[1], "--spnego") == 0) { use_spnego++; argc--; argv++; } if (argc < 2) { fprintf(stderr, "Usage: %s [--spnego] principal [keytab]\n", argv[0]); exit(1); } tmp_name = import_name(argv[1]); major = gss_canonicalize_name(&minor, tmp_name, &mech_krb5, &name); check_gsserr("gss_canonicalze_name", major, minor); (void)gss_release_name(&minor, &tmp_name); test_greet_authz_data(name); if (argc >= 3) { major = krb5_gss_register_acceptor_identity(argv[2]); check_gsserr("krb5_gss_register_acceptor_identity", major, minor); } mechs = use_spnego ? &mechset_spnego : &mechset_krb5; /* get default cred */ major = gss_acquire_cred(&minor, name, GSS_C_INDEFINITE, mechs, GSS_C_BOTH, &cred_handle, &actual_mechs, NULL); check_gsserr("gss_acquire_cred", major, minor); (void)gss_release_oid_set(&minor, &actual_mechs); init_accept_sec_context(cred_handle); printf("\n"); (void)gss_release_cred(&minor, &cred_handle); (void)gss_release_oid_set(&minor, &actual_mechs); (void)gss_release_name(&minor, &name); return 0; } krb5-1.16/src/tests/gssapi/t_accname.c0000644000704600001450000000743613211554426017505 0ustar ghudsonlibuuid/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* * Copyright 2011 by the Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #include #include #include "common.h" /* * Test program for acceptor names, intended to be run from a Python test * script. Establishes contexts with the default initiator name, a specified * principal name as target name, and a specified host-based name as acceptor * name (or GSS_C_NO_NAME if no acceptor name is given). If the exchange is * successful, queries the context for the acceptor name and prints it. If any * call is unsuccessful, displays an error message. Exits with status 0 if all * operations are successful, or 1 if not. * * Usage: ./t_accname targetname [acceptorname] */ int main(int argc, char *argv[]) { OM_uint32 minor, major, flags; gss_cred_id_t acceptor_cred; gss_name_t target_name, acceptor_name = GSS_C_NO_NAME, real_acceptor_name; gss_buffer_desc namebuf; gss_ctx_id_t initiator_context, acceptor_context; if (argc < 2 || argc > 3) { fprintf(stderr, "Usage: %s targetname [acceptorname]\n", argv[0]); return 1; } /* Import target and acceptor names. */ target_name = import_name(argv[1]); if (argc >= 3) acceptor_name = import_name(argv[2]); /* Get acceptor cred. */ major = gss_acquire_cred(&minor, acceptor_name, GSS_C_INDEFINITE, GSS_C_NO_OID_SET, GSS_C_ACCEPT, &acceptor_cred, NULL, NULL); check_gsserr("gss_acquire_cred", major, minor); flags = GSS_C_REPLAY_FLAG | GSS_C_SEQUENCE_FLAG; establish_contexts(&mech_krb5, GSS_C_NO_CREDENTIAL, acceptor_cred, target_name, flags, &initiator_context, &acceptor_context, NULL, NULL, NULL); major = gss_inquire_context(&minor, acceptor_context, NULL, &real_acceptor_name, NULL, NULL, NULL, NULL, NULL); check_gsserr("gss_inquire_context", major, minor); namebuf.value = NULL; namebuf.length = 0; major = gss_display_name(&minor, real_acceptor_name, &namebuf, NULL); check_gsserr("gss_display_name", major, minor); printf("%.*s\n", (int)namebuf.length, (char *)namebuf.value); (void)gss_release_name(&minor, &target_name); (void)gss_release_name(&minor, &acceptor_name); (void)gss_release_name(&minor, &real_acceptor_name); (void)gss_release_cred(&minor, &acceptor_cred); (void)gss_delete_sec_context(&minor, &initiator_context, NULL); (void)gss_delete_sec_context(&minor, &acceptor_context, NULL); (void)gss_release_buffer(&minor, &namebuf); return 0; } krb5-1.16/src/tests/gssapi/t_authind.py0000644000704600001450000000443513211554426017754 0ustar ghudsonlibuuid#!/usr/bin/python from k5test import * # Test authentication indicators. Load the test preauth module so we # can control the indicators asserted. testpreauth = os.path.join(buildtop, 'plugins', 'preauth', 'test', 'test.so') conf = {'plugins': {'kdcpreauth': {'module': 'test:' + testpreauth}, 'clpreauth': {'module': 'test:' + testpreauth}}} realm = K5Realm(krb5_conf=conf) realm.run([kadminl, 'addprinc', '-randkey', 'service/1']) realm.run([kadminl, 'addprinc', '-randkey', 'service/2']) realm.run([kadminl, 'modprinc', '+requires_preauth', realm.user_princ]) realm.run([kadminl, 'setstr', 'service/1', 'require_auth', 'superstrong']) realm.run([kadminl, 'setstr', 'service/2', 'require_auth', 'one two']) realm.run([kadminl, 'xst', 'service/1']) realm.run([kadminl, 'xst', 'service/2']) realm.kinit(realm.user_princ, password('user'), ['-X', 'indicators=superstrong']) out = realm.run(['./t_srcattrs', 'p:service/1']) if ('Attribute auth-indicators Authenticated Complete') not in out: fail('Expected attribute type data not seen') # UTF8 "superstrong" if '73757065727374726f6e67' not in out: fail('Expected auth indicator not seen in name attributes') msg = 'gss_init_sec_context: KDC policy rejects request' realm.run(['./t_srcattrs', 'p:service/2'], expected_code=1, expected_msg=msg) realm.kinit(realm.user_princ, password('user'), ['-X', 'indicators=one two']) out = realm.run(['./t_srcattrs', 'p:service/2']) # Hexademical "one" and "two" if '6f6e65' not in out or '74776f' not in out: fail('Expected auth indicator not seen in name attributes') realm.stop() # Test the FAST encrypted challenge auth indicator. kdcconf = {'realms': {'$realm': {'encrypted_challenge_indicator': 'fast'}}} realm = K5Realm(kdc_conf=kdcconf) realm.run([kadminl, 'modprinc', '+requires_preauth', realm.user_princ]) realm.run([kadminl, 'xst', realm.host_princ]) realm.kinit(realm.user_princ, password('user')) realm.kinit(realm.user_princ, password('user'), ['-T', realm.ccache]) out = realm.run(['./t_srcattrs', 'p:' + realm.host_princ]) if ('Attribute auth-indicators Authenticated Complete') not in out: fail('Expected attribute type not seen') if '66617374' not in out: fail('Expected auth indicator not seen in name attributes') realm.stop() success('GSSAPI auth indicator tests') krb5-1.16/src/tests/gssapi/t_imp_name.c0000644000704600001450000000420113211554426017666 0ustar ghudsonlibuuid/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* * Copyright 1996, Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ /* * Simple test program for testing how GSSAPI import name works. (May * be made into a more full-fledged test program later.) */ #include #include "common.h" int main(int argc, char **argv) { const char *name = "host@dcl.mit.edu"; OM_uint32 major, minor; gss_name_t gss_name; gss_buffer_desc buf; gss_OID name_oid; gss_name = import_name(name); major = gss_display_name(&minor, gss_name, &buf, &name_oid); check_gsserr("gss_display_name", major, minor); printf("name is: %.*s\n", (int)buf.length, (char *)buf.value); (void)gss_release_buffer(&minor, &buf); major = gss_oid_to_str(&minor, name_oid, &buf); check_gsserr("gss_oid_to_str", major, minor); printf("name type is: %.*s\n", (int)buf.length, (char *)buf.value); (void)gss_release_buffer(&minor, &buf); (void)gss_release_name(&minor, &gss_name); return 0; } krb5-1.16/src/tests/gssapi/ccrefresh.c0000644000704600001450000000524613211554426017534 0ustar ghudsonlibuuid/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* tests/gssapi/ccrefresh.c - Get or set refresh time on a ccache */ /* * Copyright (C) 2012 by the Massachusetts Institute of Technology. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ /* * This program sets the refresh time of an existing ccache to 1, forcing a * refresh. */ #include "k5-int.h" static void check(krb5_error_code code) { if (code != 0) { com_err("ccrefresh", code, NULL); abort(); } } int main(int argc, char **argv) { const char *ccname, *value = NULL; krb5_context context; krb5_ccache ccache; krb5_data d; if (argc != 2 && argc != 3) { fprintf(stderr, "Usage: %s ccname [value]\n", argv[0]); return 1; } ccname = argv[1]; if (argc == 3) value = argv[2]; check(krb5_init_context(&context)); check(krb5_cc_resolve(context, ccname, &ccache)); if (value != NULL) { d = string2data((char *)value); check(krb5_cc_set_config(context, ccache, NULL, KRB5_CC_CONF_REFRESH_TIME, &d)); } else { check(krb5_cc_get_config(context, ccache, NULL, KRB5_CC_CONF_REFRESH_TIME, &d)); printf("%.*s\n", (int)d.length, d.data); krb5_free_data_contents(context, &d); } krb5_cc_close(context, ccache); krb5_free_context(context); return 0; } krb5-1.16/src/tests/gssapi/deps0000644000704600001450000002720613211554426016302 0ustar ghudsonlibuuid# # Generated makefile dependencies follow. # $(OUTPRE)ccinit.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h \ $(top_srcdir)/include/k5-err.h $(top_srcdir)/include/k5-gmt_mktime.h \ $(top_srcdir)/include/k5-int-pkinit.h $(top_srcdir)/include/k5-int.h \ $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-plugin.h \ $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/k5-trace.h \ $(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/authdata_plugin.h \ $(top_srcdir)/include/krb5/plugin.h $(top_srcdir)/include/port-sockets.h \ $(top_srcdir)/include/socket-utils.h ccinit.c $(OUTPRE)ccrefresh.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h \ $(top_srcdir)/include/k5-err.h $(top_srcdir)/include/k5-gmt_mktime.h \ $(top_srcdir)/include/k5-int-pkinit.h $(top_srcdir)/include/k5-int.h \ $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-plugin.h \ $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/k5-trace.h \ $(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/authdata_plugin.h \ $(top_srcdir)/include/krb5/plugin.h $(top_srcdir)/include/port-sockets.h \ $(top_srcdir)/include/socket-utils.h ccrefresh.c $(OUTPRE)common.$(OBJEXT): $(BUILDTOP)/include/gssapi/gssapi.h \ $(BUILDTOP)/include/gssapi/gssapi_ext.h $(BUILDTOP)/include/gssapi/gssapi_krb5.h \ $(BUILDTOP)/include/krb5/krb5.h $(COM_ERR_DEPS) $(top_srcdir)/include/krb5.h \ common.c common.h $(OUTPRE)t_accname.$(OBJEXT): $(BUILDTOP)/include/gssapi/gssapi.h \ $(BUILDTOP)/include/gssapi/gssapi_ext.h $(BUILDTOP)/include/gssapi/gssapi_krb5.h \ $(BUILDTOP)/include/krb5/krb5.h $(COM_ERR_DEPS) $(top_srcdir)/include/krb5.h \ common.h t_accname.c $(OUTPRE)t_ccselect.$(OBJEXT): $(BUILDTOP)/include/gssapi/gssapi.h \ $(BUILDTOP)/include/gssapi/gssapi_ext.h $(BUILDTOP)/include/gssapi/gssapi_krb5.h \ $(BUILDTOP)/include/krb5/krb5.h $(COM_ERR_DEPS) $(top_srcdir)/include/krb5.h \ common.h t_ccselect.c $(OUTPRE)t_ciflags.$(OBJEXT): $(BUILDTOP)/include/gssapi/gssapi.h \ $(BUILDTOP)/include/gssapi/gssapi_ext.h $(BUILDTOP)/include/gssapi/gssapi_krb5.h \ $(BUILDTOP)/include/krb5/krb5.h $(COM_ERR_DEPS) $(top_srcdir)/include/krb5.h \ common.h t_ciflags.c $(OUTPRE)t_credstore.$(OBJEXT): $(BUILDTOP)/include/gssapi/gssapi.h \ $(BUILDTOP)/include/gssapi/gssapi_ext.h $(BUILDTOP)/include/gssapi/gssapi_krb5.h \ $(BUILDTOP)/include/krb5/krb5.h $(COM_ERR_DEPS) $(top_srcdir)/include/krb5.h \ common.h t_credstore.c $(OUTPRE)t_enctypes.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/gssapi/gssapi.h $(BUILDTOP)/include/gssapi/gssapi_ext.h \ $(BUILDTOP)/include/gssapi/gssapi_krb5.h $(BUILDTOP)/include/krb5/krb5.h \ $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ $(COM_ERR_DEPS) $(srcdir)/../../lib/gssapi/generic/gssapi_ext.h \ $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \ $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-int-pkinit.h \ $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \ $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \ $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/krb5.h \ $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/plugin.h \ $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \ common.h t_enctypes.c $(OUTPRE)t_err.$(OBJEXT): $(BUILDTOP)/include/gssapi/gssapi.h \ $(BUILDTOP)/include/gssapi/gssapi_ext.h $(BUILDTOP)/include/gssapi/gssapi_krb5.h \ $(BUILDTOP)/include/krb5/krb5.h $(COM_ERR_DEPS) $(top_srcdir)/include/krb5.h \ common.h t_err.c $(OUTPRE)t_export_cred.$(OBJEXT): $(BUILDTOP)/include/gssapi/gssapi.h \ $(BUILDTOP)/include/gssapi/gssapi_ext.h $(BUILDTOP)/include/gssapi/gssapi_krb5.h \ $(BUILDTOP)/include/krb5/krb5.h $(COM_ERR_DEPS) $(top_srcdir)/include/krb5.h \ common.h t_export_cred.c $(OUTPRE)t_export_name.$(OBJEXT): $(BUILDTOP)/include/gssapi/gssapi.h \ $(BUILDTOP)/include/gssapi/gssapi_ext.h $(BUILDTOP)/include/gssapi/gssapi_krb5.h \ $(BUILDTOP)/include/krb5/krb5.h $(COM_ERR_DEPS) $(top_srcdir)/include/krb5.h \ common.h t_export_name.c $(OUTPRE)t_gssexts.$(OBJEXT): $(BUILDTOP)/include/gssapi/gssapi.h \ $(BUILDTOP)/include/gssapi/gssapi_ext.h $(BUILDTOP)/include/gssapi/gssapi_krb5.h \ $(BUILDTOP)/include/krb5/krb5.h $(COM_ERR_DEPS) $(top_srcdir)/include/krb5.h \ common.h t_gssexts.c $(OUTPRE)t_imp_cred.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/gssapi/gssapi.h $(BUILDTOP)/include/gssapi/gssapi_ext.h \ $(BUILDTOP)/include/gssapi/gssapi_krb5.h $(BUILDTOP)/include/krb5/krb5.h \ $(COM_ERR_DEPS) $(top_srcdir)/include/k5-platform.h \ $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/krb5.h \ common.h t_imp_cred.c $(OUTPRE)t_imp_name.$(OBJEXT): $(BUILDTOP)/include/gssapi/gssapi.h \ $(BUILDTOP)/include/gssapi/gssapi_ext.h $(BUILDTOP)/include/gssapi/gssapi_krb5.h \ $(BUILDTOP)/include/krb5/krb5.h $(COM_ERR_DEPS) $(top_srcdir)/include/krb5.h \ common.h t_imp_name.c $(OUTPRE)t_invalid.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/gssapi/gssapi.h $(BUILDTOP)/include/gssapi/gssapi_alloc.h \ $(BUILDTOP)/include/gssapi/gssapi_ext.h $(BUILDTOP)/include/gssapi/gssapi_krb5.h \ $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ $(BUILDTOP)/include/profile.h $(BUILDTOP)/lib/gssapi/generic/gssapi_err_generic.h \ $(BUILDTOP)/lib/gssapi/krb5/gssapi_err_krb5.h $(COM_ERR_DEPS) \ $(srcdir)/../../lib/gssapi/generic/gssapiP_generic.h \ $(srcdir)/../../lib/gssapi/generic/gssapi_ext.h $(srcdir)/../../lib/gssapi/generic/gssapi_generic.h \ $(srcdir)/../../lib/gssapi/krb5/gssapiP_krb5.h $(srcdir)/../../lib/gssapi/krb5/gssapi_krb5.h \ $(srcdir)/../../lib/gssapi/mechglue/mechglue.h $(srcdir)/../../lib/gssapi/mechglue/mglueP.h \ $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \ $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-int-pkinit.h \ $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \ $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \ $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/krb5.h \ $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/plugin.h \ $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \ common.h t_invalid.c $(OUTPRE)t_inq_cred.$(OBJEXT): $(BUILDTOP)/include/gssapi/gssapi.h \ $(BUILDTOP)/include/gssapi/gssapi_ext.h $(BUILDTOP)/include/gssapi/gssapi_krb5.h \ $(BUILDTOP)/include/krb5/krb5.h $(COM_ERR_DEPS) $(top_srcdir)/include/krb5.h \ common.h t_inq_cred.c $(OUTPRE)t_inq_ctx.$(OBJEXT): $(BUILDTOP)/include/gssapi/gssapi.h \ $(BUILDTOP)/include/gssapi/gssapi_ext.h $(BUILDTOP)/include/gssapi/gssapi_krb5.h \ $(BUILDTOP)/include/krb5/krb5.h $(COM_ERR_DEPS) $(top_srcdir)/include/krb5.h \ common.h t_inq_ctx.c $(OUTPRE)t_inq_mechs_name.$(OBJEXT): $(BUILDTOP)/include/gssapi/gssapi.h \ $(BUILDTOP)/include/gssapi/gssapi_ext.h $(BUILDTOP)/include/gssapi/gssapi_krb5.h \ $(BUILDTOP)/include/krb5/krb5.h $(COM_ERR_DEPS) $(top_srcdir)/include/krb5.h \ common.h t_inq_mechs_name.c $(OUTPRE)t_iov.$(OBJEXT): $(BUILDTOP)/include/gssapi/gssapi.h \ $(BUILDTOP)/include/gssapi/gssapi_ext.h $(BUILDTOP)/include/gssapi/gssapi_krb5.h \ $(BUILDTOP)/include/krb5/krb5.h $(COM_ERR_DEPS) $(top_srcdir)/include/krb5.h \ common.h t_iov.c $(OUTPRE)t_lifetime.$(OBJEXT): $(BUILDTOP)/include/gssapi/gssapi.h \ $(BUILDTOP)/include/gssapi/gssapi_ext.h $(BUILDTOP)/include/gssapi/gssapi_krb5.h \ $(BUILDTOP)/include/krb5/krb5.h $(COM_ERR_DEPS) $(top_srcdir)/include/krb5.h \ common.h t_lifetime.c $(OUTPRE)t_namingexts.$(OBJEXT): $(BUILDTOP)/include/gssapi/gssapi.h \ $(BUILDTOP)/include/gssapi/gssapi_ext.h $(BUILDTOP)/include/gssapi/gssapi_krb5.h \ $(BUILDTOP)/include/krb5/krb5.h $(COM_ERR_DEPS) $(top_srcdir)/include/krb5.h \ common.h t_namingexts.c $(OUTPRE)t_oid.$(OBJEXT): $(BUILDTOP)/include/gssapi/gssapi.h \ $(BUILDTOP)/include/gssapi/gssapi_ext.h $(BUILDTOP)/include/gssapi/gssapi_krb5.h \ $(BUILDTOP)/include/krb5/krb5.h $(COM_ERR_DEPS) $(top_srcdir)/include/krb5.h \ common.h t_oid.c $(OUTPRE)t_pcontok.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/gssapi/gssapi.h $(BUILDTOP)/include/gssapi/gssapi_ext.h \ $(BUILDTOP)/include/gssapi/gssapi_krb5.h $(BUILDTOP)/include/krb5/krb5.h \ $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \ $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-int-pkinit.h \ $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \ $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \ $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/krb5.h \ $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/plugin.h \ $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \ common.h t_pcontok.c $(OUTPRE)t_prf.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/gssapi/gssapi.h $(BUILDTOP)/include/gssapi/gssapi_alloc.h \ $(BUILDTOP)/include/gssapi/gssapi_ext.h $(BUILDTOP)/include/gssapi/gssapi_krb5.h \ $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ $(BUILDTOP)/include/profile.h $(BUILDTOP)/lib/gssapi/generic/gssapi_err_generic.h \ $(BUILDTOP)/lib/gssapi/krb5/gssapi_err_krb5.h $(COM_ERR_DEPS) \ $(srcdir)/../../lib/gssapi/generic/gssapiP_generic.h \ $(srcdir)/../../lib/gssapi/generic/gssapi_ext.h $(srcdir)/../../lib/gssapi/generic/gssapi_generic.h \ $(srcdir)/../../lib/gssapi/krb5/gssapiP_krb5.h $(srcdir)/../../lib/gssapi/krb5/gssapi_krb5.h \ $(srcdir)/../../lib/gssapi/mechglue/mechglue.h $(srcdir)/../../lib/gssapi/mechglue/mglueP.h \ $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \ $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-int-pkinit.h \ $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \ $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \ $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/krb5.h \ $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/plugin.h \ $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \ common.h t_prf.c $(OUTPRE)t_s4u.$(OBJEXT): $(BUILDTOP)/include/gssapi/gssapi.h \ $(BUILDTOP)/include/gssapi/gssapi_ext.h $(BUILDTOP)/include/gssapi/gssapi_krb5.h \ $(BUILDTOP)/include/krb5/krb5.h $(COM_ERR_DEPS) $(top_srcdir)/include/krb5.h \ common.h t_s4u.c $(OUTPRE)t_s4u2proxy_krb5.$(OBJEXT): $(BUILDTOP)/include/gssapi/gssapi.h \ $(BUILDTOP)/include/gssapi/gssapi_ext.h $(BUILDTOP)/include/gssapi/gssapi_krb5.h \ $(BUILDTOP)/include/krb5/krb5.h $(COM_ERR_DEPS) $(top_srcdir)/include/krb5.h \ common.h t_s4u2proxy_krb5.c $(OUTPRE)t_saslname.$(OBJEXT): $(BUILDTOP)/include/gssapi/gssapi.h \ $(BUILDTOP)/include/gssapi/gssapi_ext.h $(BUILDTOP)/include/gssapi/gssapi_krb5.h \ $(BUILDTOP)/include/krb5/krb5.h $(COM_ERR_DEPS) $(top_srcdir)/include/krb5.h \ common.h t_saslname.c $(OUTPRE)t_spnego.$(OBJEXT): $(BUILDTOP)/include/gssapi/gssapi.h \ $(BUILDTOP)/include/gssapi/gssapi_ext.h $(BUILDTOP)/include/gssapi/gssapi_krb5.h \ $(BUILDTOP)/include/krb5/krb5.h $(COM_ERR_DEPS) $(top_srcdir)/include/krb5.h \ common.h t_spnego.c $(OUTPRE)t_srcattrs.$(OBJEXT): $(BUILDTOP)/include/gssapi/gssapi.h \ $(BUILDTOP)/include/gssapi/gssapi_ext.h $(BUILDTOP)/include/gssapi/gssapi_krb5.h \ $(BUILDTOP)/include/krb5/krb5.h $(COM_ERR_DEPS) $(top_srcdir)/include/krb5.h \ common.h t_srcattrs.c krb5-1.16/src/tests/gssapi/t_export_cred.py0000755000704600001450000000327413211554426020641 0ustar ghudsonlibuuid#!/usr/bin/python from k5test import * # Test gss_export_cred and gss_import_cred for initiator creds, # acceptor creds, and traditional delegated creds. t_s4u.py tests # exporting and importing a synthesized S4U2Proxy delegated # credential. # Make up a filename to hold user's initial credentials. def ccache_savefile(realm): return os.path.join(realm.testdir, 'ccache.copy') # Move user's initial credentials into the save file. def ccache_save(realm): os.rename(realm.ccache, ccache_savefile(realm)) # Copy user's initial credentials from the save file into the ccache. def ccache_restore(realm): shutil.copyfile(ccache_savefile(realm), realm.ccache) # Run t_export_cred with the saved ccache and verify that it stores a # forwarded cred into the default ccache. def check(realm, args): ccache_restore(realm) realm.run(['./t_export_cred'] + args) realm.run([klist, '-f'], expected_msg='Flags: Ff') # Check a given set of arguments with no specified mech and with krb5 # and SPNEGO as the specified mech. def check_mechs(realm, args): check(realm, args) check(realm, ['-k'] + args) check(realm, ['-s'] + args) # Make a realm, get forwardable tickets, and save a copy for each test. realm = K5Realm(get_creds=False) realm.kinit(realm.user_princ, password('user'), ['-f']) ccache_save(realm) # Test with default initiator and acceptor cred. tname = 'p:' + realm.host_princ check_mechs(realm, [tname]) # Test with principal-named initiator and acceptor cred. iname = 'p:' + realm.user_princ check_mechs(realm, ['-i', iname, '-a', tname, tname]) # Test with host-based acceptor cred. check_mechs(realm, ['-a', 'h:host', tname]) success('gss_export_cred/gss_import_cred tests') krb5-1.16/src/tests/gssapi/t_invalid.c0000644000704600001450000003703313211554426017540 0ustar ghudsonlibuuid/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* tests/gssapi/t_invalid.c - Invalid message token regression tests */ /* * Copyright (C) 2014 by the Massachusetts Institute of Technology. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ /* * This file contains regression tests for some GSSAPI invalid token * vulnerabilities. * * 1. A pre-CFX wrap or MIC token processed with a CFX-only context causes a * null pointer dereference. (The token must use SEAL_ALG_NONE or it will * be rejected.) * * 2. A pre-CFX wrap or MIC token with fewer than 24 bytes after the ASN.1 * header causes an input buffer overrun, usually leading to either a segv * or a GSS_S_DEFECTIVE_TOKEN error due to garbage algorithm, filler, or * sequence number values. * * 3. A pre-CFX wrap token with fewer than 16 + cksumlen bytes after the ASN.1 * header causes an integer underflow when computing the ciphertext length, * leading to an allocation error on 32-bit platforms or a segv on 64-bit * platforms. A pre-CFX MIC token of this size causes an input buffer * overrun when comparing the checksum, perhaps leading to a segv. * * 4. A pre-CFX wrap token with fewer than conflen + padlen bytes in the * ciphertext (where padlen is the last byte of the decrypted ciphertext) * causes an integer underflow when computing the original message length, * leading to an allocation error. * * 5. In the mechglue, truncated encapsulation in the initial context token can * cause input buffer overruns in gss_accept_sec_context(). * * Vulnerabilities #1 and #2 also apply to IOV unwrap, although tokens with * fewer than 16 bytes after the ASN.1 header will be rejected. * Vulnerabilities #2 and #5 can only be robustly detected using a * memory-checking environment such as valgrind. */ #include "k5-int.h" #include "common.h" #include "mglueP.h" #include "gssapiP_krb5.h" /* * The following samples contain context parameters and otherwise valid seal * tokens where the plain text is padded with byte value 100 instead of the * proper value 1. */ struct test { krb5_enctype enctype; krb5_enctype encseq_enctype; int sealalg; int signalg; size_t cksum_size; size_t keylen; const char *keydata; size_t toklen; const char *token; } tests[] = { { ENCTYPE_DES_CBC_CRC, ENCTYPE_DES_CBC_RAW, SEAL_ALG_DES, SGN_ALG_DES_MAC_MD5, 8, 8, "\x26\xEC\xBA\xB6\xFE\xBA\x91\xCE", 53, "\x60\x33\x06\x09\x2A\x86\x48\x86\xF7\x12\x01\x02\x02\x02\x01\x00" "\x00\x00\x00\xFF\xFF\xF0\x0B\x90\x7B\xC4\xFC\xEB\xF4\x84\x9C\x5A" "\xA8\x56\x41\x3E\xE1\x62\xEE\x38\xD1\x34\x9A\xE3\xFB\xC9\xFD\x0A" "\xDC\x83\xE1\x4A\xE4" }, { ENCTYPE_DES3_CBC_SHA1, ENCTYPE_DES3_CBC_RAW, SEAL_ALG_DES3KD, SGN_ALG_HMAC_SHA1_DES3_KD, 20, 24, "\x4F\xEA\x19\x19\x5E\x0E\x10\xDF\x3D\x29\xB5\x13\x8F\x01\xC7\xA7" "\x92\x3D\x38\xF7\x26\x73\x0D\x6D", 65, "\x60\x3F\x06\x09\x2A\x86\x48\x86\xF7\x12\x01\x02\x02\x02\x01\x04" "\x00\x02\x00\xFF\xFF\xEB\xF3\x9A\x89\x24\x57\xB8\x63\x95\x25\xE8" "\x6E\x8E\x79\xE6\x2E\xCA\xD3\xFF\x57\x9F\x8C\xAB\xEF\xDD\x28\x10" "\x2F\x93\x21\x2E\xF2\x52\xB6\x6F\xA8\xBB\x8A\x6D\xAA\x6F\xB7\xF4\xD4" }, { ENCTYPE_ARCFOUR_HMAC, ENCTYPE_ARCFOUR_HMAC, SEAL_ALG_MICROSOFT_RC4, SGN_ALG_HMAC_MD5, 8, 16, "\x66\x64\x41\x64\x55\x78\x21\xD0\xD0\xFD\x05\x6A\xFF\x6F\xE8\x09", 53, "\x60\x33\x06\x09\x2A\x86\x48\x86\xF7\x12\x01\x02\x02\x02\x01\x11" "\x00\x10\x00\xFF\xFF\x35\xD4\x79\xF3\x8C\x47\x8F\x6E\x23\x6F\x3E" "\xCC\x5E\x57\x5C\x6A\x89\xF0\xA2\x03\x4F\x0B\x51\x11\xEE\x89\x7E" "\xD6\xF6\xB5\xD6\x51" } }; /* Fake up enough of a CFX GSS context for gss_unwrap, using an AES key. */ static gss_ctx_id_t make_fake_cfx_context() { gss_union_ctx_id_t uctx; krb5_gss_ctx_id_t kgctx; krb5_keyblock kb; kgctx = calloc(1, sizeof(*kgctx)); if (kgctx == NULL) abort(); kgctx->established = 1; kgctx->proto = 1; if (g_seqstate_init(&kgctx->seqstate, 0, 0, 0, 0) != 0) abort(); kgctx->mech_used = &mech_krb5; kgctx->sealalg = -1; kgctx->signalg = -1; kb.enctype = ENCTYPE_AES128_CTS_HMAC_SHA1_96; kb.length = 16; kb.contents = (unsigned char *)"1234567887654321"; if (krb5_k_create_key(NULL, &kb, &kgctx->subkey) != 0) abort(); uctx = calloc(1, sizeof(*uctx)); if (uctx == NULL) abort(); uctx->mech_type = &mech_krb5; uctx->internal_ctx_id = (gss_ctx_id_t)kgctx; return (gss_ctx_id_t)uctx; } /* Fake up enough of a GSS context for gss_unwrap, using keys from test. */ static gss_ctx_id_t make_fake_context(const struct test *test) { gss_union_ctx_id_t uctx; krb5_gss_ctx_id_t kgctx; krb5_keyblock kb; unsigned char encbuf[8]; size_t i; kgctx = calloc(1, sizeof(*kgctx)); if (kgctx == NULL) abort(); kgctx->established = 1; if (g_seqstate_init(&kgctx->seqstate, 0, 0, 0, 0) != 0) abort(); kgctx->mech_used = &mech_krb5; kgctx->sealalg = test->sealalg; kgctx->signalg = test->signalg; kgctx->cksum_size = test->cksum_size; kb.enctype = test->enctype; kb.length = test->keylen; kb.contents = (unsigned char *)test->keydata; if (krb5_k_create_key(NULL, &kb, &kgctx->subkey) != 0) abort(); kb.enctype = test->encseq_enctype; if (krb5_k_create_key(NULL, &kb, &kgctx->seq) != 0) abort(); if (kb.enctype == ENCTYPE_DES_CBC_RAW) { for (i = 0; i < 8; i++) encbuf[i] = kb.contents[i] ^ 0xF0; kb.contents = encbuf; } if (krb5_k_create_key(NULL, &kb, &kgctx->enc) != 0) abort(); uctx = calloc(1, sizeof(*uctx)); if (uctx == NULL) abort(); uctx->mech_type = &mech_krb5; uctx->internal_ctx_id = (gss_ctx_id_t)kgctx; return (gss_ctx_id_t)uctx; } /* Free a context created by make_fake_context. */ static void free_fake_context(gss_ctx_id_t ctx) { gss_union_ctx_id_t uctx = (gss_union_ctx_id_t)ctx; krb5_gss_ctx_id_t kgctx = (krb5_gss_ctx_id_t)uctx->internal_ctx_id; free(kgctx->seqstate); krb5_k_free_key(NULL, kgctx->subkey); krb5_k_free_key(NULL, kgctx->seq); krb5_k_free_key(NULL, kgctx->enc); free(kgctx); free(uctx); } /* Prefix a token (starting at the two-byte ID) with an ASN.1 header and return * it in an allocated block to facilitate checking by valgrind or similar. */ static void make_token(unsigned char *token, size_t len, gss_buffer_t out) { char *wrapped; assert(mech_krb5.length == 9); assert(len + 11 < 128); wrapped = malloc(len + 13); if (wrapped == NULL) abort(); wrapped[0] = 0x60; wrapped[1] = len + 11; wrapped[2] = 0x06; wrapped[3] = 9; memcpy(wrapped + 4, mech_krb5.elements, 9); memcpy(wrapped + 13, token, len); out->length = len + 13; out->value = wrapped; } /* Unwrap a superficially valid RFC 1964 token with a CFX-only context, with * regular and IOV unwrap. */ static void test_bogus_1964_token(gss_ctx_id_t ctx) { OM_uint32 minor, major; unsigned char tokbuf[128]; gss_buffer_desc in, out; gss_iov_buffer_desc iov; store_16_be(KG_TOK_SIGN_MSG, tokbuf); store_16_le(SGN_ALG_DES_MAC_MD5, tokbuf + 2); store_16_le(SEAL_ALG_NONE, tokbuf + 4); store_16_le(0xFFFF, tokbuf + 6); memset(tokbuf + 8, 0, 16); make_token(tokbuf, 24, &in); major = gss_unwrap(&minor, ctx, &in, &out, NULL, NULL); if (major != GSS_S_DEFECTIVE_TOKEN) abort(); (void)gss_release_buffer(&minor, &out); iov.type = GSS_IOV_BUFFER_TYPE_HEADER; iov.buffer = in; major = gss_unwrap_iov(&minor, ctx, NULL, NULL, &iov, 1); if (major != GSS_S_DEFECTIVE_TOKEN) abort(); free(in.value); } /* Process wrap and MIC tokens with incomplete headers. */ static void test_short_header(gss_ctx_id_t ctx) { OM_uint32 minor, major; unsigned char tokbuf[128]; gss_buffer_desc in, out, empty = GSS_C_EMPTY_BUFFER; /* Seal token, 2-24 bytes */ store_16_be(KG_TOK_SEAL_MSG, tokbuf); make_token(tokbuf, 2, &in); major = gss_unwrap(&minor, ctx, &in, &out, NULL, NULL); if (major != GSS_S_DEFECTIVE_TOKEN) abort(); free(in.value); (void)gss_release_buffer(&minor, &out); /* Sign token, 2-24 bytes */ store_16_be(KG_TOK_SIGN_MSG, tokbuf); make_token(tokbuf, 2, &in); major = gss_unwrap(&minor, ctx, &in, &out, NULL, NULL); if (major != GSS_S_DEFECTIVE_TOKEN) abort(); free(in.value); (void)gss_release_buffer(&minor, &out); /* MIC token, 2-24 bytes */ store_16_be(KG_TOK_MIC_MSG, tokbuf); make_token(tokbuf, 2, &in); major = gss_verify_mic(&minor, ctx, &empty, &in, NULL); if (major != GSS_S_DEFECTIVE_TOKEN) abort(); free(in.value); } /* Process wrap and MIC tokens with incomplete headers. */ static void test_short_header_iov(gss_ctx_id_t ctx, const struct test *test) { OM_uint32 minor, major; unsigned char tokbuf[128]; gss_iov_buffer_desc iov; /* IOV seal token, 16-23 bytes */ store_16_be(KG_TOK_SEAL_MSG, tokbuf); store_16_le(test->signalg, tokbuf + 2); store_16_le(test->sealalg, tokbuf + 4); store_16_be(0xFFFF, tokbuf + 6); memset(tokbuf + 8, 0, 8); iov.type = GSS_IOV_BUFFER_TYPE_HEADER; make_token(tokbuf, 16, &iov.buffer); major = gss_unwrap_iov(&minor, ctx, NULL, NULL, &iov, 1); if (major != GSS_S_DEFECTIVE_TOKEN) abort(); free(iov.buffer.value); /* IOV sign token, 16-23 bytes */ store_16_be(KG_TOK_SIGN_MSG, tokbuf); store_16_le(test->signalg, tokbuf + 2); store_16_le(SEAL_ALG_NONE, tokbuf + 4); store_16_le(0xFFFF, tokbuf + 6); memset(tokbuf + 8, 0, 8); iov.type = GSS_IOV_BUFFER_TYPE_HEADER; make_token(tokbuf, 16, &iov.buffer); major = gss_unwrap_iov(&minor, ctx, NULL, NULL, &iov, 1); if (major != GSS_S_DEFECTIVE_TOKEN) abort(); free(iov.buffer.value); /* IOV MIC token, 16-23 bytes */ store_16_be(KG_TOK_MIC_MSG, tokbuf); store_16_be(test->signalg, tokbuf + 2); store_16_le(SEAL_ALG_NONE, tokbuf + 4); store_16_le(0xFFFF, tokbuf + 6); memset(tokbuf + 8, 0, 8); iov.type = GSS_IOV_BUFFER_TYPE_MIC_TOKEN; make_token(tokbuf, 16, &iov.buffer); major = gss_verify_mic_iov(&minor, ctx, NULL, &iov, 1); if (major != GSS_S_DEFECTIVE_TOKEN) abort(); free(iov.buffer.value); } /* Process wrap and MIC tokens with incomplete checksums. */ static void test_short_checksum(gss_ctx_id_t ctx, const struct test *test) { OM_uint32 minor, major; unsigned char tokbuf[128]; gss_buffer_desc in, out, empty = GSS_C_EMPTY_BUFFER; /* Can only do this with the DES3 checksum, as we can't easily get past * retrieving the sequence number when the checksum is only eight bytes. */ if (test->cksum_size <= 8) return; /* Seal token, fewer than 16 + cksum_size bytes. Use the token from the * test data to get a valid sequence number. */ make_token((unsigned char *)test->token + 13, 24, &in); major = gss_unwrap(&minor, ctx, &in, &out, NULL, NULL); if (major != GSS_S_DEFECTIVE_TOKEN) abort(); free(in.value); (void)gss_release_buffer(&minor, &out); /* Sign token, fewer than 16 + cksum_size bytes. */ memcpy(tokbuf, test->token + 13, 24); store_16_be(KG_TOK_SIGN_MSG, tokbuf); store_16_le(SEAL_ALG_NONE, tokbuf + 4); make_token(tokbuf, 24, &in); major = gss_unwrap(&minor, ctx, &in, &out, NULL, NULL); if (major != GSS_S_DEFECTIVE_TOKEN) abort(); free(in.value); (void)gss_release_buffer(&minor, &out); /* MIC token, fewer than 16 + cksum_size bytes. */ memcpy(tokbuf, test->token + 13, 24); store_16_be(KG_TOK_MIC_MSG, tokbuf); store_16_le(SEAL_ALG_NONE, tokbuf + 4); make_token(tokbuf, 24, &in); major = gss_verify_mic(&minor, ctx, &empty, &in, NULL); if (major != GSS_S_DEFECTIVE_TOKEN) abort(); free(in.value); } /* Unwrap a token with a bogus padding byte in the decrypted ciphertext. */ static void test_bad_pad(gss_ctx_id_t ctx, const struct test *test) { OM_uint32 minor, major; gss_buffer_desc in, out; in.length = test->toklen; in.value = (char *)test->token; major = gss_unwrap(&minor, ctx, &in, &out, NULL, NULL); if (major != GSS_S_BAD_SIG) abort(); (void)gss_release_buffer(&minor, &out); } static void try_accept(void *value, size_t len) { OM_uint32 minor; gss_buffer_desc in, out; gss_ctx_id_t ctx = GSS_C_NO_CONTEXT; /* Copy the provided value to make input overruns more obvious. */ in.value = malloc(len); if (in.value == NULL) abort(); memcpy(in.value, value, len); in.length = len; (void)gss_accept_sec_context(&minor, &ctx, GSS_C_NO_CREDENTIAL, &in, GSS_C_NO_CHANNEL_BINDINGS, NULL, NULL, &out, NULL, NULL, NULL); gss_release_buffer(&minor, &out); gss_delete_sec_context(&minor, &ctx, GSS_C_NO_BUFFER); free(in.value); } /* Accept contexts using superficially valid but truncated encapsulations. */ static void test_short_encapsulation() { /* Include just the initial application tag, to see if we overrun reading * the sequence length. */ try_accept("\x60", 1); /* Indicate four additional sequence length bytes, to see if we overrun * reading them (or skipping them and reading the next byte). */ try_accept("\x60\x84", 2); /* Include an object identifier tag but no length, to see if we overrun * reading the length. */ try_accept("\x60\x40\x06", 3); /* Include an object identifier tag with a length matching the krb5 mech, * but no OID bytes, to see if we overrun comparing against mechs. */ try_accept("\x60\x40\x06\x09", 4); } int main(int argc, char **argv) { gss_ctx_id_t ctx; size_t i; ctx = make_fake_cfx_context(); test_bogus_1964_token(ctx); free_fake_context(ctx); for (i = 0; i < sizeof(tests) / sizeof(*tests); i++) { ctx = make_fake_context(&tests[i]); test_short_header(ctx); test_short_header_iov(ctx, &tests[i]); test_short_checksum(ctx, &tests[i]); test_bad_pad(ctx, &tests[i]); free_fake_context(ctx); } test_short_encapsulation(); return 0; } krb5-1.16/src/tests/gssapi/t_err.c0000644000704600001450000001147413211554426016703 0ustar ghudsonlibuuid/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* tests/gssapi/t_err.c - Test accept_sec_context error generation */ /* * Copyright (C) 2013 by the Massachusetts Institute of Technology. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ /* * This test program verifies that the krb5 gss_accept_sec_context can produce * error tokens and that gss_init_sec_context can interpret them. */ #include #include #include #include #include "common.h" static void check_replay_error(const char *msg, OM_uint32 major, OM_uint32 minor) { OM_uint32 tmpmin, msg_ctx = 0; const char *replay = "Request is a replay"; gss_buffer_desc m; if (major != GSS_S_FAILURE) { fprintf(stderr, "%s: expected major code GSS_S_FAILURE\n", msg); check_gsserr(msg, major, minor); exit(1); } (void)gss_display_status(&tmpmin, minor, GSS_C_MECH_CODE, GSS_C_NULL_OID, &msg_ctx, &m); if (m.length != strlen(replay) || memcmp(m.value, replay, m.length) != 0) { fprintf(stderr, "%s: expected replay error; got %.*s\n", msg, (int)m.length, (char *)m.value); exit(1); } (void)gss_release_buffer(&tmpmin, &m); } int main(int argc, char *argv[]) { OM_uint32 minor, major, flags; gss_OID mech = &mech_krb5; gss_name_t tname; gss_buffer_desc itok, atok; gss_ctx_id_t ictx = GSS_C_NO_CONTEXT, actx = GSS_C_NO_CONTEXT; if (argc != 2) { fprintf(stderr, "Usage: %s targetname\n", argv[0]); return 1; } tname = import_name(argv[1]); /* Get the initial context token. */ flags = GSS_C_REPLAY_FLAG | GSS_C_SEQUENCE_FLAG | GSS_C_MUTUAL_FLAG; major = gss_init_sec_context(&minor, GSS_C_NO_CREDENTIAL, &ictx, tname, mech, flags, GSS_C_INDEFINITE, GSS_C_NO_CHANNEL_BINDINGS, GSS_C_NO_BUFFER, NULL, &itok, NULL, NULL); check_gsserr("gss_init_sec_context(1)", major, minor); assert(major == GSS_S_CONTINUE_NEEDED); /* Process this token into an acceptor context, then discard it. */ major = gss_accept_sec_context(&minor, &actx, GSS_C_NO_CREDENTIAL, &itok, GSS_C_NO_CHANNEL_BINDINGS, NULL, NULL, &atok, NULL, NULL, NULL); check_gsserr("gss_accept_sec_context(1)", major, minor); (void)gss_release_buffer(&minor, &atok); (void)gss_delete_sec_context(&minor, &actx, NULL); /* Process the same token again, producing a replay error. */ major = gss_accept_sec_context(&minor, &actx, GSS_C_NO_CREDENTIAL, &itok, GSS_C_NO_CHANNEL_BINDINGS, NULL, NULL, &atok, NULL, NULL, NULL); check_replay_error("gss_accept_sec_context(2)", major, minor); assert(atok.length != 0); /* Send the error token back the initiator. */ (void)gss_release_buffer(&minor, &itok); major = gss_init_sec_context(&minor, GSS_C_NO_CREDENTIAL, &ictx, tname, mech, flags, GSS_C_INDEFINITE, GSS_C_NO_CHANNEL_BINDINGS, &atok, NULL, &itok, NULL, NULL); check_replay_error("gss_init_sec_context(2)", major, minor); (void)gss_release_name(&minor, &tname); (void)gss_release_buffer(&minor, &itok); (void)gss_release_buffer(&minor, &atok); (void)gss_delete_sec_context(&minor, &ictx, NULL); (void)gss_delete_sec_context(&minor, &actx, NULL); return 0; } krb5-1.16/src/tests/gssapi/t_inq_ctx.c0000644000704600001450000002223013211554426017550 0ustar ghudsonlibuuid/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* * Copyright 2015 Red Hat, Inc. * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation files * (the "Software"), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, * publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ #include #include #include #include #include "common.h" /* * Test program for inquiring about a security context, intented to be run from * a Python test script. Partially establishes a context to test inquiring * about an incomplete context, and then establishes full contexts and inquires * them. Exits with status 0 if all operations are successful, or 1 if not. * * Usage: ./t_inq_ctx target_name */ static void check_inq_context(gss_ctx_id_t context, int incomplete, gss_OID expected_mech, OM_uint32 expected_flags, int expected_locally_init) { OM_uint32 major, minor; gss_name_t out_init_name, out_accept_name; OM_uint32 out_lifetime; gss_OID out_mech_type; OM_uint32 out_flags; int out_locally_init; int out_open; major = gss_inquire_context(&minor, context, &out_init_name, &out_accept_name, &out_lifetime, &out_mech_type, &out_flags, &out_locally_init, &out_open); check_gsserr("gss_inquire_context", major, minor); assert(gss_oid_equal(out_mech_type, expected_mech)); assert(out_flags == expected_flags); assert(out_locally_init == expected_locally_init); if (incomplete) { assert(!out_open); assert(out_lifetime == 0); assert(out_init_name == GSS_C_NO_NAME); assert(out_accept_name == GSS_C_NO_NAME); } else { assert(out_open); assert(out_lifetime > 0); assert(out_init_name != GSS_C_NO_NAME); assert(out_accept_name != GSS_C_NO_NAME); } (void)gss_release_name(&minor, &out_accept_name); (void)gss_release_name(&minor, &out_init_name); } /* Call gss_init_sec_context() once to create an initiator context (which will * be partial if flags includes GSS_C_MUTUAL_FLAG and the mech is krb5). */ static void start_init_context(gss_OID mech, gss_cred_id_t cred, gss_name_t tname, OM_uint32 flags, gss_ctx_id_t *ctx) { OM_uint32 major, minor; gss_buffer_desc itok = GSS_C_EMPTY_BUFFER; *ctx = GSS_C_NO_CONTEXT; major = gss_init_sec_context(&minor, cred, ctx, tname, mech, flags, GSS_C_INDEFINITE, GSS_C_NO_CHANNEL_BINDINGS, NULL, NULL, &itok, NULL, NULL); check_gsserr("gss_init_sec_context", major, minor); (void)gss_release_buffer(&minor, &itok); } /* Call gss_init_sec_context() and gss_accept_sec_context() once to create an * acceptor context. */ static void start_accept_context(gss_OID mech, gss_cred_id_t icred, gss_cred_id_t acred, gss_name_t tname, OM_uint32 flags, gss_ctx_id_t *ctx) { OM_uint32 major, minor; gss_ctx_id_t ictx = GSS_C_NO_CONTEXT; gss_buffer_desc itok = GSS_C_EMPTY_BUFFER, atok = GSS_C_EMPTY_BUFFER; major = gss_init_sec_context(&minor, icred, &ictx, tname, mech, flags, GSS_C_INDEFINITE, GSS_C_NO_CHANNEL_BINDINGS, NULL, NULL, &itok, NULL, NULL); check_gsserr("gss_init_sec_context", major, minor); *ctx = GSS_C_NO_CONTEXT; major = gss_accept_sec_context(&minor, ctx, acred, &itok, GSS_C_NO_CHANNEL_BINDINGS, NULL, NULL, &atok, NULL, NULL, NULL); check_gsserr("gss_accept_sec_context", major, minor); (void)gss_release_buffer(&minor, &itok); (void)gss_release_buffer(&minor, &atok); (void)gss_delete_sec_context(&minor, &ictx, NULL); } static void partial_iakerb_acceptor(const char *username, const char *password, gss_name_t tname, OM_uint32 flags, gss_ctx_id_t *ctx) { OM_uint32 major, minor; gss_name_t name; gss_buffer_desc ubuf, pwbuf; gss_OID_set_desc mechlist; gss_cred_id_t icred, acred; mechlist.count = 1; mechlist.elements = &mech_iakerb; /* Import the username. */ ubuf.value = (void *)username; ubuf.length = strlen(username); major = gss_import_name(&minor, &ubuf, GSS_C_NT_USER_NAME, &name); check_gsserr("gss_import_name", major, minor); /* Create an IAKERB initiator cred with the username and password. */ pwbuf.value = (void *)password; pwbuf.length = strlen(password); major = gss_acquire_cred_with_password(&minor, name, &pwbuf, 0, &mechlist, GSS_C_INITIATE, &icred, NULL, NULL); check_gsserr("gss_acquire_cred_with_password", major, minor); /* Create an acceptor cred with support for IAKERB. */ major = gss_acquire_cred(&minor, GSS_C_NO_NAME, GSS_C_INDEFINITE, &mechlist, GSS_C_ACCEPT, &acred, NULL, NULL); check_gsserr("gss_acquire_cred", major, minor); /* Begin context establishment to get a partial acceptor context. */ start_accept_context(&mech_iakerb, icred, acred, tname, flags, ctx); (void)gss_release_name(&minor, &name); (void)gss_release_cred(&minor, &icred); (void)gss_release_cred(&minor, &acred); } /* Create a partially established SPNEGO acceptor. */ static void partial_spnego_acceptor(gss_name_t tname, gss_ctx_id_t *ctx) { OM_uint32 major, minor; gss_buffer_desc itok = GSS_C_EMPTY_BUFFER, atok; /* * We could construct a fixed SPNEGO initiator token which forces a * renegotiation, but a simpler approach is to pass an empty token to * gss_accept_sec_context(), taking advantage of our compatibility support * for SPNEGO NegHints. */ *ctx = GSS_C_NO_CONTEXT; major = gss_accept_sec_context(&minor, ctx, GSS_C_NO_CREDENTIAL, &itok, GSS_C_NO_CHANNEL_BINDINGS, NULL, NULL, &atok, NULL, NULL, NULL); check_gsserr("gss_accept_sec_context(neghints)", major, minor); (void)gss_release_buffer(&minor, &atok); } int main(int argc, char *argv[]) { OM_uint32 minor, flags, dce_flags; gss_name_t tname; gss_ctx_id_t ictx, actx; const char *username, *password; if (argc != 4) { fprintf(stderr, "Usage: %s username password targetname\n", argv[0]); return 1; } username = argv[1]; password = argv[2]; tname = import_name(argv[3]); flags = GSS_C_SEQUENCE_FLAG | GSS_C_MUTUAL_FLAG | GSS_C_CONF_FLAG | GSS_C_INTEG_FLAG; start_init_context(&mech_krb5, GSS_C_NO_CREDENTIAL, tname, flags, &ictx); check_inq_context(ictx, 1, &mech_krb5, flags | GSS_C_TRANS_FLAG, 1); (void)gss_delete_sec_context(&minor, &ictx, NULL); start_init_context(&mech_iakerb, GSS_C_NO_CREDENTIAL, tname, flags, &ictx); check_inq_context(ictx, 1, &mech_iakerb, flags, 1); (void)gss_delete_sec_context(&minor, &ictx, NULL); start_init_context(&mech_spnego, GSS_C_NO_CREDENTIAL, tname, flags, &ictx); check_inq_context(ictx, 1, &mech_spnego, flags, 1); (void)gss_delete_sec_context(&minor, &ictx, NULL); dce_flags = flags | GSS_C_DCE_STYLE; start_accept_context(&mech_krb5, GSS_C_NO_CREDENTIAL, GSS_C_NO_CREDENTIAL, tname, dce_flags, &actx); check_inq_context(actx, 1, &mech_krb5, dce_flags | GSS_C_TRANS_FLAG, 0); (void)gss_delete_sec_context(&minor, &actx, NULL); partial_iakerb_acceptor(username, password, tname, flags, &actx); check_inq_context(actx, 1, &mech_iakerb, 0, 0); (void)gss_delete_sec_context(&minor, &actx, NULL); partial_spnego_acceptor(tname, &actx); check_inq_context(actx, 1, &mech_spnego, 0, 0); (void)gss_delete_sec_context(&minor, &actx, NULL); establish_contexts(&mech_krb5, GSS_C_NO_CREDENTIAL, GSS_C_NO_CREDENTIAL, tname, flags, &ictx, &actx, NULL, NULL, NULL); check_inq_context(ictx, 0, &mech_krb5, flags | GSS_C_TRANS_FLAG, 1); check_inq_context(actx, 0, &mech_krb5, flags | GSS_C_TRANS_FLAG | GSS_C_PROT_READY_FLAG, 0); (void)gss_delete_sec_context(&minor, &ictx, NULL); (void)gss_delete_sec_context(&minor, &actx, NULL); (void)gss_release_name(&minor, &tname); return 0; } krb5-1.16/src/tests/gssapi/t_imp_cred.c0000644000704600001450000000773413211554426017701 0ustar ghudsonlibuuid/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* tests/gssapi/t_imp_cred.c - krb5_gss_import_cred test harness */ /* * Copyright 2011 by the Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ /* * Test program for krb5_gss_import_cred, intended to be run from a Python test * script. Creates an initiator credential for the default ccache and an * acceptor principal for the default keytab (possibly using a specified keytab * principal), and performs a one-token context exchange using a specified * target principal. If the exchange is successful, queries the context for * the acceptor name and prints it. If any call is unsuccessful, displays an * error message. Exits with status 0 if all operations are successful, or 1 * if not. * * Usage: ./t_imp_cred target-princ [keytab-princ] */ #include "k5-platform.h" #include #include "common.h" int main(int argc, char *argv[]) { OM_uint32 minor, major, flags; gss_cred_id_t initiator_cred, acceptor_cred; gss_ctx_id_t initiator_context, acceptor_context; gss_name_t target_name; krb5_context context = NULL; krb5_ccache cc; krb5_keytab kt; krb5_principal princ = NULL; krb5_error_code ret; if (argc < 2 || argc > 3) { fprintf(stderr, "Usage: %s targetname [acceptorprinc]\n", argv[0]); return 1; } /* Import the target name. */ target_name = import_name(argv[1]); /* Acquire the krb5 objects we need. */ ret = krb5_init_context(&context); check_k5err(context, "krb5_init_context", ret); ret = krb5_cc_default(context, &cc); check_k5err(context, "krb5_cc_default", ret); ret = krb5_kt_default(context, &kt); check_k5err(context, "krb5_kt_default", ret); if (argc >= 3) { ret = krb5_parse_name(context, argv[2], &princ); check_k5err(context, "krb5_parse_name", ret); } /* Get initiator cred. */ major = gss_krb5_import_cred(&minor, cc, NULL, NULL, &initiator_cred); check_gsserr("gss_krb5_import_cred (initiator)", major, minor); /* Get acceptor cred. */ major = gss_krb5_import_cred(&minor, NULL, princ, kt, &acceptor_cred); check_gsserr("gss_krb5_import_cred (acceptor)", major, minor); flags = GSS_C_REPLAY_FLAG | GSS_C_SEQUENCE_FLAG; establish_contexts(&mech_krb5, initiator_cred, acceptor_cred, target_name, flags, &initiator_context, &acceptor_context, NULL, NULL, NULL); krb5_cc_close(context, cc); krb5_kt_close(context, kt); krb5_free_principal(context, princ); krb5_free_context(context); (void)gss_release_name(&minor, &target_name); (void)gss_release_cred(&minor, &initiator_cred); (void)gss_release_cred(&minor, &acceptor_cred); (void)gss_delete_sec_context(&minor, &initiator_context, NULL); (void)gss_delete_sec_context(&minor, &acceptor_context, NULL); return 0; } krb5-1.16/src/tests/gssapi/t_s4u.py0000755000704600001450000001532013211554426017031 0ustar ghudsonlibuuid#!/usr/bin/python from k5test import * realm = K5Realm(create_host=False, get_creds=False) usercache = 'FILE:' + os.path.join(realm.testdir, 'usercache') storagecache = 'FILE:' + os.path.join(realm.testdir, 'save') # Create two service principals with keys in the default keytab. service1 = 'service/1@%s' % realm.realm realm.addprinc(service1) realm.extract_keytab(service1, realm.keytab) service2 = 'service/2@%s' % realm.realm realm.addprinc(service2) realm.extract_keytab(service2, realm.keytab) puser = 'p:' + realm.user_princ pservice1 = 'p:' + service1 pservice2 = 'p:' + service2 # Get forwardable creds for service1 in the default cache. realm.kinit(service1, None, ['-f', '-k']) # Try krb5 -> S4U2Proxy with forwardable user creds. This should fail # at the S4U2Proxy step since the DB2 back end currently has no # support for allowing it. realm.kinit(realm.user_princ, password('user'), ['-f', '-c', usercache]) output = realm.run(['./t_s4u2proxy_krb5', usercache, storagecache, '-', pservice1, pservice2], expected_code=1) if ('auth1: ' + realm.user_princ not in output or 'NOT_ALLOWED_TO_DELEGATE' not in output): fail('krb5 -> s4u2proxy') # Again with SPNEGO. output = realm.run(['./t_s4u2proxy_krb5', '--spnego', usercache, storagecache, '-', pservice1, pservice2], expected_code=1) if ('auth1: ' + realm.user_princ not in output or 'NOT_ALLOWED_TO_DELEGATE' not in output): fail('krb5 -> s4u2proxy (SPNEGO)') # Try krb5 -> S4U2Proxy without forwardable user creds. This should # result in no delegated credential being created by # accept_sec_context. realm.kinit(realm.user_princ, password('user'), ['-c', usercache]) realm.run(['./t_s4u2proxy_krb5', usercache, storagecache, pservice1, pservice1, pservice2], expected_msg='no credential delegated') # Try S4U2Self. Ask for an S4U2Proxy step; this won't happen because # service/1 isn't allowed to get a forwardable S4U2Self ticket. output = realm.run(['./t_s4u', puser, pservice2]) if ('Warning: no delegated cred handle' not in output or 'Source name:\t' + realm.user_princ not in output): fail('s4u2self') output = realm.run(['./t_s4u', '--spnego', puser, pservice2]) if ('Warning: no delegated cred handle' not in output or 'Source name:\t' + realm.user_princ not in output): fail('s4u2self (SPNEGO)') # Correct that problem and try again. As above, the S4U2Proxy step # won't actually succeed since we don't support that in DB2. realm.run([kadminl, 'modprinc', '+ok_to_auth_as_delegate', service1]) realm.run(['./t_s4u', puser, pservice2], expected_code=1, expected_msg='NOT_ALLOWED_TO_DELEGATE') # Again with SPNEGO. This uses SPNEGO for the initial authentication, # but still uses krb5 for S4U2Proxy--the delegated cred is returned as # a krb5 cred, not a SPNEGO cred, and t_s4u uses the delegated cred # directly rather than saving and reacquiring it. realm.run(['./t_s4u', '--spnego', puser, pservice2], expected_code=1, expected_msg='NOT_ALLOWED_TO_DELEGATE') realm.stop() # Set up a realm using the test KDB module so that we can do # successful S4U2Proxy delegations. testprincs = {'krbtgt/KRBTEST.COM': {'keys': 'aes128-cts'}, 'user': {'keys': 'aes128-cts'}, 'service/1': {'flags': '+ok-to-auth-as-delegate', 'keys': 'aes128-cts'}, 'service/2': {'keys': 'aes128-cts'}} conf = {'realms': {'$realm': {'database_module': 'test'}}, 'dbmodules': {'test': {'db_library': 'test', 'princs': testprincs, 'delegation': {'service/1': 'service/2'}}}} realm = K5Realm(create_kdb=False, kdc_conf=conf) userkeytab = 'FILE:' + os.path.join(realm.testdir, 'userkeytab') realm.extract_keytab(realm.user_princ, userkeytab) realm.extract_keytab(service1, realm.keytab) realm.extract_keytab(service2, realm.keytab) realm.start_kdc() # Get forwardable creds for service1 in the default cache. realm.kinit(service1, None, ['-f', '-k']) # Successful krb5 -> S4U2Proxy, with krb5 and SPNEGO mechs. realm.kinit(realm.user_princ, None, ['-f', '-k', '-c', usercache, '-t', userkeytab]) out = realm.run(['./t_s4u2proxy_krb5', usercache, storagecache, '-', pservice1, pservice2]) if 'auth1: user@' not in out or 'auth2: user@' not in out: fail('krb5 -> s4u2proxy') out = realm.run(['./t_s4u2proxy_krb5', '--spnego', usercache, storagecache, '-', pservice1, pservice2]) if 'auth1: user@' not in out or 'auth2: user@' not in out: fail('krb5 -> s4u2proxy') # Successful S4U2Self -> S4U2Proxy. out = realm.run(['./t_s4u', puser, pservice2]) # Regression test for #8139: get a user ticket directly for service1 and # try krb5 -> S4U2Proxy. realm.kinit(realm.user_princ, None, ['-f', '-k', '-c', usercache, '-t', userkeytab, '-S', service1]) out = realm.run(['./t_s4u2proxy_krb5', usercache, storagecache, '-', pservice1, pservice2]) if 'auth1: user@' not in out or 'auth2: user@' not in out: fail('krb5 -> s4u2proxy') # Simulate a krbtgt rollover and verify that the user ticket can still # be validated. realm.stop_kdc() newtgt_keys = ['2 aes128-cts', '1 aes128-cts'] newtgt_princs = {'krbtgt/KRBTEST.COM': {'keys': newtgt_keys}} newtgt_conf = {'dbmodules': {'test': {'princs': newtgt_princs}}} newtgt_env = realm.special_env('newtgt', True, kdc_conf=newtgt_conf) realm.start_kdc(env=newtgt_env) out = realm.run(['./t_s4u2proxy_krb5', usercache, storagecache, '-', pservice1, pservice2]) if 'auth1: user@' not in out or 'auth2: user@' not in out: fail('krb5 -> s4u2proxy') # Get a user ticket after the krbtgt rollover and verify that # S4U2Proxy delegation works (also a #8139 regression test). realm.kinit(realm.user_princ, None, ['-f', '-k', '-c', usercache, '-t', userkeytab]) out = realm.run(['./t_s4u2proxy_krb5', usercache, storagecache, '-', pservice1, pservice2]) if 'auth1: user@' not in out or 'auth2: user@' not in out: fail('krb5 -> s4u2proxy') realm.stop() # Exercise cross-realm S4U2Self. The query in the foreign realm will # fail, but we can check that the right server principal was used. r1, r2 = cross_realms(2, create_user=False) r1.run([kinit, '-k', r1.host_princ]) r1.run(['./t_s4u', 'p:' + r2.host_princ], expected_code=1, expected_msg='Server not found in Kerberos database') r1.stop() r2.stop() with open(os.path.join(r2.testdir, 'kdc.log')) as f: kdclog = f.read() exp_princ = r1.host_princ.replace('/', '\\/').replace('@', '\\@') if ('for %s@%s, Server not found' % (exp_princ, r2.realm)) not in kdclog: fail('cross-realm s4u2self (kdc log)') success('S4U test cases') krb5-1.16/src/tests/gssapi/t_ccselect.py0000755000704600001450000001473313211554426020112 0ustar ghudsonlibuuid#!/usr/bin/python # Copyright (C) 2011 by the Massachusetts Institute of Technology. # All rights reserved. # Export of this software from the United States of America may # require a specific license from the United States Government. # It is the responsibility of any person or organization contemplating # export to obtain such a license before exporting. # # WITHIN THAT CONSTRAINT, permission to use, copy, modify, and # distribute this software and its documentation for any purpose and # without fee is hereby granted, provided that the above copyright # notice appear in all copies and that both that copyright notice and # this permission notice appear in supporting documentation, and that # the name of M.I.T. not be used in advertising or publicity pertaining # to distribution of the software without specific, written prior # permission. Furthermore if you modify this software you must label # your software as modified software and not distribute it in such a # fashion that it might be confused with the original M.I.T. software. # M.I.T. makes no representations about the suitability of # this software for any purpose. It is provided "as is" without express # or implied warranty. from k5test import * # Create two independent realms (no cross-realm TGTs). r1 = K5Realm(create_user=False) r2 = K5Realm(create_user=False, realm='KRBTEST2.COM', portbase=62000, testdir=os.path.join(r1.testdir, 'r2')) host1 = 'p:' + r1.host_princ host2 = 'p:' + r2.host_princ foo = 'foo.krbtest.com' foo2 = 'foo.krbtest2.com' foobar = "foo.bar.krbtest.com" # These strings specify the target as a GSS name. The resulting # principal will have the host-based type, with the referral realm # (since k5test realms have no domain-realm mapping by default). # krb5_cc_select() will use the fallback realm, which is either the # uppercased parent domain, or the default realm if the hostname is a # single component. gssserver = 'h:host@' + foo gssserver2 = 'h:host@' + foo2 gssserver_bar = 'h:host@' + foobar gsslocal = 'h:host@localhost' # refserver specifies the target as a principal in the referral realm. # The principal won't be treated as a host principal by the # .k5identity rules since it has unknown type. refserver = 'p:host/' + hostname + '@' # Verify that we can't get initiator creds with no credentials in the # collection. r1.run(['./t_ccselect', host1, '-'], expected_code=1, expected_msg='No Kerberos credentials available') # Make a directory collection and use it for client commands in both realms. ccdir = os.path.join(r1.testdir, 'cc') ccname = 'DIR:' + ccdir r1.env['KRB5CCNAME'] = ccname r2.env['KRB5CCNAME'] = ccname # Use .k5identity from testdir and not from the tester's homedir. r1.env['HOME'] = r1.testdir r2.env['HOME'] = r1.testdir # Create two users in r1 and one in r2. alice='alice@KRBTEST.COM' bob='bob@KRBTEST.COM' zaphod='zaphod@KRBTEST2.COM' r1.addprinc(alice, password('alice')) r1.addprinc(bob, password('bob')) r2.addprinc(zaphod, password('zaphod')) # Create host principals and keytabs for fallback realm tests. r1.addprinc('host/localhost') r2.addprinc('host/localhost') r1.addprinc('host/' + foo) r2.addprinc('host/' + foo2) r1.addprinc('host/' + foobar) r1.extract_keytab('host/localhost', r1.keytab) r2.extract_keytab('host/localhost', r2.keytab) r1.extract_keytab('host/' + foo, r1.keytab) r2.extract_keytab('host/' + foo2, r2.keytab) r1.extract_keytab('host/' + foobar, r1.keytab) # Get tickets for one user in each realm (zaphod will be primary). r1.kinit(alice, password('alice')) r2.kinit(zaphod, password('zaphod')) # Check that we can find a cache for a specified client principal. output = r1.run(['./t_ccselect', host1, 'p:' + alice]) if output != (alice + '\n'): fail('alice not chosen when specified') output = r2.run(['./t_ccselect', host2, 'p:' + zaphod]) if output != (zaphod + '\n'): fail('zaphod not chosen when specified') # Check that we can guess a cache based on the service realm. output = r1.run(['./t_ccselect', host1]) if output != (alice + '\n'): fail('alice not chosen as default initiator cred for server in r1') output = r1.run(['./t_ccselect', host1, '-']) if output != (alice + '\n'): fail('alice not chosen as default initiator name for server in r1') output = r2.run(['./t_ccselect', host2]) if output != (zaphod + '\n'): fail('zaphod not chosen as default initiator cred for server in r1') output = r2.run(['./t_ccselect', host2, '-']) if output != (zaphod + '\n'): fail('zaphod not chosen as default initiator name for server in r1') # Check that primary cache is used if server realm is unknown. output = r2.run(['./t_ccselect', refserver]) if output != (zaphod + '\n'): fail('zaphod not chosen via primary cache for unknown server realm') r1.run(['./t_ccselect', gssserver2], expected_code=1) # Check ccache selection using a fallback realm. output = r1.run(['./t_ccselect', gssserver]) if output != (alice + '\n'): fail('alice not chosen via parent domain fallback') output = r2.run(['./t_ccselect', gssserver2]) if output != (zaphod + '\n'): fail('zaphod not chosen via parent domain fallback') # Check ccache selection using a fallback realm (default realm). output = r1.run(['./t_ccselect', gsslocal]) if output != (alice + '\n'): fail('alice not chosen via default realm fallback') output = r2.run(['./t_ccselect', gsslocal]) if output != (zaphod + '\n'): fail('zaphod not chosen via default realm fallback') # Check that realm ccselect fallback works correctly r1.run(['./t_ccselect', gssserver_bar], expected_msg=alice) r2.kinit(zaphod, password('zaphod')) r1.run(['./t_ccselect', gssserver_bar], expected_msg=alice) # Get a second cred in r1 (bob will be primary). r1.kinit(bob, password('bob')) # Try some cache selections using .k5identity. k5id = open(os.path.join(r1.testdir, '.k5identity'), 'w') k5id.write('%s realm=%s\n' % (alice, r1.realm)) k5id.write('%s service=ho*t host=localhost\n' % zaphod) k5id.write('noprinc service=bogus') k5id.close() output = r1.run(['./t_ccselect', host1]) if output != (alice + '\n'): fail('alice not chosen via .k5identity realm line.') output = r2.run(['./t_ccselect', gsslocal]) if output != (zaphod + '\n'): fail('zaphod not chosen via .k5identity service/host line.') output = r1.run(['./t_ccselect', refserver]) if output != (bob + '\n'): fail('bob not chosen via primary cache when no .k5identity line matches.') r1.run(['./t_ccselect', 'h:bogus@' + foo2], expected_code=1, expected_msg="Can't find client principal noprinc") success('GSSAPI credential selection tests') krb5-1.16/src/tests/gssapi/Makefile.in0000644000704600001450000001207513211554426017467 0ustar ghudsonlibuuidmydir=tests$(S)gssapi BUILDTOP=$(REL)..$(S).. DEFINES = -DUSE_AUTOCONF_H # For t_prf.c LOCALINCLUDES = -I$(srcdir)/../../lib/gssapi/mechglue \ -I$(srcdir)/../../lib/gssapi/krb5 \ -I$(srcdir)/../../lib/gssapi/generic -I../../lib/gssapi/krb5 \ -I../../lib/gssapi/generic SRCS= $(srcdir)/ccinit.c $(srcdir)/ccrefresh.c $(srcdir)/common.c \ $(srcdir)/t_accname.c $(srcdir)/t_ccselect.c $(srcdir)/t_ciflags.c \ $(srcdir)/t_credstore.c $(srcdir)/t_enctypes.c $(srcdir)/t_err.c \ $(srcdir)/t_export_cred.c $(srcdir)/t_export_name.c \ $(srcdir)/t_gssexts.c $(srcdir)/t_imp_cred.c $(srcdir)/t_imp_name.c \ $(srcdir)/t_invalid.c $(srcdir)/t_inq_cred.c $(srcdir)/t_inq_ctx.c \ $(srcdir)/t_inq_mechs_name.c $(srcdir)/t_iov.c \ $(srcdir)/t_lifetime.c $(srcdir)/t_namingexts.c $(srcdir)/t_oid.c \ $(srcdir)/t_pcontok.c $(srcdir)/t_prf.c $(srcdir)/t_s4u.c \ $(srcdir)/t_s4u2proxy_krb5.c $(srcdir)/t_saslname.c \ $(srcdir)/t_spnego.c $(srcdir)/t_srcattrs.c OBJS= ccinit.o ccrefresh.o common.o t_accname.o t_ccselect.o t_ciflags.o \ t_credstore.o t_enctypes.o t_err.o t_export_cred.o t_export_name.o \ t_gssexts.o t_imp_cred.o t_imp_name.o t_invalid.o t_inq_cred.o \ t_inq_ctx.o t_inq_mechs_name.o t_iov.o t_lifetime.o t_namingexts.o \ t_oid.o t_pcontok.o t_prf.o t_s4u.o t_s4u2proxy_krb5.o t_saslname.o \ t_spnego.o t_srcattrs.o COMMON_DEPS= common.o $(GSS_DEPLIBS) $(KRB5_BASE_DEPLIBS) COMMON_LIBS= common.o $(GSS_LIBS) $(KRB5_BASE_LIBS) all: ccinit ccrefresh t_accname t_ccselect t_ciflags t_credstore t_enctypes \ t_err t_export_cred t_export_name t_gssexts t_imp_cred t_imp_name \ t_invalid t_inq_cred t_inq_ctx t_inq_mechs_name t_iov t_lifetime \ t_namingexts t_oid t_pcontok t_prf t_s4u t_s4u2proxy_krb5 t_saslname \ t_spnego t_srcattrs check-unix: t_oid $(RUN_TEST) ./t_invalid $(RUN_TEST) ./t_oid $(RUN_TEST) ./t_prf check-pytests: ccinit ccrefresh t_accname t_ccselect t_ciflags t_credstore \ t_enctypes t_err t_export_cred t_export_name t_imp_cred t_inq_cred \ t_inq_ctx t_inq_mechs_name t_iov t_lifetime t_pcontok t_s4u \ t_s4u2proxy_krb5 t_spnego t_srcattrs $(RUNPYTEST) $(srcdir)/t_gssapi.py $(PYTESTFLAGS) $(RUNPYTEST) $(srcdir)/t_ccselect.py $(PYTESTFLAGS) $(RUNPYTEST) $(srcdir)/t_client_keytab.py $(PYTESTFLAGS) $(RUNPYTEST) $(srcdir)/t_enctypes.py $(PYTESTFLAGS) $(RUNPYTEST) $(srcdir)/t_export_cred.py $(PYTESTFLAGS) $(RUNPYTEST) $(srcdir)/t_s4u.py $(PYTESTFLAGS) $(RUNPYTEST) $(srcdir)/t_authind.py $(PYTESTFLAGS) ccinit: ccinit.o $(KRB5_BASE_DEPLIBS) $(CC_LINK) -o ccinit ccinit.o $(KRB5_BASE_LIBS) ccrefresh: ccrefresh.o $(KRB5_BASE_DEPLIBS) $(CC_LINK) -o ccrefresh ccrefresh.o $(KRB5_BASE_LIBS) t_accname: t_accname.o $(COMMON_DEPS) $(CC_LINK) -o $@ t_accname.o $(COMMON_LIBS) t_ccselect: t_ccselect.o $(COMMON_DEPS) $(CC_LINK) -o $@ t_ccselect.o $(COMMON_LIBS) t_ciflags: t_ciflags.o $(COMMON_DEPS) $(CC_LINK) -o $@ t_ciflags.o $(COMMON_LIBS) t_credstore: t_credstore.o $(COMMON_DEPS) $(CC_LINK) -o $@ t_credstore.o $(COMMON_LIBS) t_enctypes: t_enctypes.o $(COMMON_DEPS) $(CC_LINK) -o $@ t_enctypes.o $(COMMON_LIBS) t_err: t_err.o $(COMMON_DEPS) $(CC_LINK) -o $@ t_err.o $(COMMON_LIBS) t_export_cred: t_export_cred.o $(COMMON_DEPS) $(CC_LINK) -o $@ t_export_cred.o $(COMMON_LIBS) t_export_name: t_export_name.o $(COMMON_DEPS) $(CC_LINK) -o $@ t_export_name.o $(COMMON_LIBS) t_gssexts: t_gssexts.o $(COMMON_DEPS) $(CC_LINK) -o $@ t_gssexts.o $(COMMON_LIBS) t_imp_cred: t_imp_cred.o $(COMMON_DEPS) $(CC_LINK) -o $@ t_imp_cred.o $(COMMON_LIBS) t_imp_name: t_imp_name.o $(COMMON_DEPS) $(CC_LINK) -o $@ t_imp_name.o $(COMMON_LIBS) t_invalid: t_invalid.o $(COMMON_DEPS) $(CC_LINK) -o $@ t_invalid.o $(COMMON_LIBS) t_inq_cred: t_inq_cred.o $(COMMON_DEPS) $(CC_LINK) -o $@ t_inq_cred.o $(COMMON_LIBS) t_inq_ctx: t_inq_ctx.o $(COMMON_DEPS) $(CC_LINK) -o $@ t_inq_ctx.o $(COMMON_LIBS) t_inq_mechs_name: t_inq_mechs_name.o $(COMMON_DEPS) $(CC_LINK) -o $@ t_inq_mechs_name.o $(COMMON_LIBS) t_iov: t_iov.o $(COMMON_DEPS) $(CC_LINK) -o $@ t_iov.o $(COMMON_LIBS) t_lifetime: t_lifetime.o $(COMMON_DEPS) $(CC_LINK) -o $@ t_lifetime.o $(COMMON_LIBS) t_namingexts: t_namingexts.o $(COMMON_DEPS) $(CC_LINK) -o $@ t_namingexts.o $(COMMON_LIBS) t_pcontok: t_pcontok.o $(COMMON_DEPS) $(CC_LINK) -o $@ t_pcontok.o $(COMMON_LIBS) t_oid: t_oid.o $(COMMON_DEPS) $(CC_LINK) -o $@ t_oid.o $(COMMON_LIBS) t_prf: t_prf.o $(COMMON_DEPS) $(CC_LINK) -o $@ t_prf.o $(COMMON_LIBS) t_s4u: t_s4u.o $(COMMON_DEPS) $(CC_LINK) -o $@ t_s4u.o $(COMMON_LIBS) t_s4u2proxy_krb5: t_s4u2proxy_krb5.o $(COMMON_DEPS) $(CC_LINK) -o $@ t_s4u2proxy_krb5.o $(COMMON_LIBS) t_saslname: t_saslname.o $(COMMON_DEPS) $(CC_LINK) -o $@ t_saslname.o $(COMMON_LIBS) t_spnego: t_spnego.o $(COMMON_DEPS) $(CC_LINK) -o $@ t_spnego.o $(COMMON_LIBS) t_srcattrs: t_srcattrs.o $(COMMON_DEPS) $(CC_LINK) -o $@ t_srcattrs.o $(COMMON_LIBS) clean: $(RM) ccinit ccrefresh t_accname t_ccselect t_ciflags t_credstore $(RM) t_enctypes t_err t_export_cred t_export_name t_gssexts t_imp_cred $(RM) t_imp_name t_invalid t_inq_cred t_inq_ctx t_inq_mechs_name t_iov $(RM) t_lifetime t_namingexts t_oid t_pcontok t_prf t_s4u $(RM) t_s4u2proxy_krb5 t_saslname t_spnego t_srcattrs krb5-1.16/src/tests/gssapi/t_oid.c0000644000704600001450000002014013211554426016654 0ustar ghudsonlibuuid/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* tests/gssapi/t_oid.c - Test OID manipulation functions */ /* * Copyright (C) 2012 by the Massachusetts Institute of Technology. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #include #include #include #include "common.h" static struct { char *canonical; char *variant; gss_OID_desc oid; } tests[] = { /* GSS_C_NT_USER_NAME */ { "{ 1 2 840 113554 1 2 1 1 }", "1.2.840.113554.1.2.1.1", { 10, "\x2A\x86\x48\x86\xF7\x12\x01\x02\x01\x01" } }, /* GSS_C_NT_MACHINE_UID_NAME */ { "{ 1 2 840 113554 1 2 1 2 }", "1 2 840 113554 1 2 1 2", { 10, "\x2A\x86\x48\x86\xF7\x12\x01\x02\x01\x02" } }, /* GSS_C_NT_STRING_UID_NAME */ { "{ 1 2 840 113554 1 2 1 3 }", "{1 2 840 113554 1 2 1 3}", { 10, "\x2A\x86\x48\x86\xF7\x12\x01\x02\x01\x03" } }, /* GSS_C_NT_HOSTBASED_SERVICE_X */ { "{ 1 3 6 1 5 6 2 }", "{ 1 3 6 1 5 6 2 }", { 6, "\x2B\x06\x01\x05\x06\x02" } }, /* GSS_C_NT_ANONYMOUS */ { "{ 1 3 6 1 5 6 3 }", "{ 01 03 06 01 05 06 03 }", { 6, "\x2B\x06\x01\x05\x06\x03" } }, /* GSS_KRB5_NT_PRINCIPAL_NAME */ { "{ 1 2 840 113554 1 2 2 1 }", " {01 2 840 113554 1 2 2 1 } ", { 10, "\x2A\x86\x48\x86\xF7\x12\x01\x02\x02\x01" } }, /* gss_krb5_nt_principal */ { "{ 1 2 840 113554 1 2 2 2 }", "{1.2.840.113554.1.2.2.2}", { 10, "\x2A\x86\x48\x86\xF7\x12\x01\x02\x02\x02" } }, /* gss_mech_krb5 */ { "{ 1 2 840 113554 1 2 2 }", "{ 1.2.840.113554.1.2.2 }", { 9, "\x2A\x86\x48\x86\xF7\x12\x01\x02\x02" } }, /* gss_mech_krb5_old */ { "{ 1 3 5 1 5 2 }", "001 . 003 . 005 . 001 . 005 . 002", { 5, "\x2B\x05\x01\x05\x02" } }, /* gss_mech_krb5_wrong */ { "{ 1 2 840 48018 1 2 2 }", "1.2.840.48018.1.2.2 trailing garbage", { 9, "\x2A\x86\x48\x82\xF7\x12\x01\x02\x02" } }, /* gss_mech_iakerb */ { "{ 1 3 6 1 5 2 5 }", "{ 1 3 6 1 5 2 5 } trailing garbage", { 6, "\x2B\x06\x01\x05\x02\x05" } }, /* SPNEGO */ { "{ 1 3 6 1 5 5 2 }", "{1 3 6 1 5 5 2} trailing garbage", { 6, "\x2B\x06\x01\x05\x05\x02" } }, /* Edge cases for the first two arcs */ { "{ 0 0 }", NULL, { 1, "\x00" } }, { "{ 0 39 }", NULL, { 1, "\x27" } }, { "{ 1 0 }", NULL, { 1, "\x28" } }, { "{ 1 39 }", NULL, { 1, "\x4F" } }, { "{ 2 0 }", NULL, { 1, "\x50" } }, { "{ 2 40 }", NULL, { 1, "\x78" } }, { "{ 2 47 }", NULL, { 1, "\x7F" } }, { "{ 2 48 }", NULL, { 2, "\x81\x00" } }, { "{ 2 16304 }", NULL, { 3, "\x81\x80\x00" } }, /* Zero-valued arcs */ { "{ 0 0 0 }", NULL, { 2, "\x00\x00" } }, { "{ 0 0 1 0 }", NULL, { 3, "\x00\x01\x00" } }, { "{ 0 0 128 0 }", NULL, { 4, "\x00\x81\x00\x00 " } }, { "{ 0 0 0 1 }", NULL, { 3, "\x00\x00\x01" } }, { "{ 0 0 128 0 1 0 128 }", NULL, { 8, "\x00\x81\x00\x00\x01\x00\x81\x00 " } } }; static char *invalid_strings[] = { "", "{}", "{", "}", " ", " { } ", "x", "+1 1", "-1.1", "1.+0", "+0.1", "{ 1 garbage }", "{ 1 }", "{ 0 40 }", "{ 1 40 }", "{ 1 128 }", "{ 1 1", "{ 1 2 3 4 +5 }", "{ 1.2.-3.4.5 }" }; static int oid_equal(gss_OID o1, gss_OID o2) { return o1->length == o2->length && memcmp(o1->elements, o2->elements, o1->length) == 0; } int main() { size_t i; OM_uint32 major, minor; gss_buffer_desc buf; gss_OID oid; gss_OID_set set; int status = 0, present; for (i = 0; i < sizeof(tests) / sizeof(*tests); i++) { /* Check that this test's OID converts to its canonical string form. */ major = gss_oid_to_str(&minor, &tests[i].oid, &buf); check_gsserr("gss_oid_to_str", major, minor); if (buf.length != strlen(tests[i].canonical) + 1 || memcmp(buf.value, tests[i].canonical, buf.length) != 0) { status = 1; printf("test %d: OID converts to %.*s, wanted %s\n", (int)i, (int)buf.length, (char *)buf.value, tests[i].canonical); } (void)gss_release_buffer(&minor, &buf); /* Check that this test's canonical string form converts to its OID. */ buf.value = tests[i].canonical; buf.length = strlen(tests[i].canonical); major = gss_str_to_oid(&minor, &buf, &oid); check_gsserr("gss_str_to_oid", major, minor); if (!oid_equal(oid, &tests[i].oid)) { status = 1; printf("test %d: %s converts to wrong OID\n", (int)i, tests[i].canonical); display_oid("wanted", &tests[i].oid); display_oid("actual", oid); } (void)gss_release_oid(&minor, &oid); /* Check that this test's variant string form converts to its OID. */ if (tests[i].variant == NULL) continue; buf.value = tests[i].variant; buf.length = strlen(tests[i].variant); major = gss_str_to_oid(&minor, &buf, &oid); check_gsserr("gss_str_to_oid", major, minor); if (!oid_equal(oid, &tests[i].oid)) { status = 1; printf("test %d: %s converts to wrong OID\n", (int)i, tests[i].variant); display_oid("wanted", &tests[i].oid); display_oid("actual", oid); } (void)gss_release_oid(&minor, &oid); } for (i = 0; i < sizeof(invalid_strings) / sizeof(*invalid_strings); i++) { buf.value = invalid_strings[i]; buf.length = strlen(invalid_strings[i]); major = gss_str_to_oid(&minor, &buf, &oid); if (major == GSS_S_COMPLETE) { status = 1; printf("invalid %d: %s converted when it should not have\n", (int)i, invalid_strings[i]); (void)gss_release_oid(&minor, &oid); } } major = gss_create_empty_oid_set(&minor, &set); check_gsserr("gss_create_empty_oid_set", major, minor); for (i = 0; i < sizeof(tests) / sizeof(*tests); i++) { major = gss_add_oid_set_member(&minor, &tests[i].oid, &set); check_gsserr("gss_add_oid_set_member", major, minor); } if (set->count != i) { status = 1; printf("oid set has wrong size: wanted %d, actual %d\n", (int)i, (int)set->count); } for (i = 0; i < set->count; i++) { if (!oid_equal(&set->elements[i], &tests[i].oid)) { status = 1; printf("oid set has wrong element %d\n", (int)i); display_oid("wanted", &tests[i].oid); display_oid("actual", &set->elements[i]); } major = gss_test_oid_set_member(&minor, &tests[i].oid, set, &present); check_gsserr("gss_test_oid_set_member", major, minor); if (!present) { status = 1; printf("oid set does not contain OID %d\n", (int)i); display_oid("wanted", &tests[i].oid); } } (void)gss_release_oid_set(&minor, &set); return status; } krb5-1.16/src/tests/gssapi/t_gssexts.c0000644000704600001450000002203713211554426017610 0ustar ghudsonlibuuid/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* * Copyright 2009 by the Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #include #include #include #include "common.h" /* * Test program for protocol transition (S4U2Self) and constrained delegation * (S4U2Proxy) * * Note: because of name canonicalization, the following tips may help * when configuring with Active Directory: * * - Create a computer account FOO$ * - Set the UPN to host/foo.domain (no suffix); this is necessary to * be able to send an AS-REQ as this principal, otherwise you would * need to use the canonical name (FOO$), which will cause principal * comparison errors in gss_accept_sec_context(). * - Add a SPN of host/foo.domain * - Configure the computer account to support constrained delegation with * protocol transition (Trust this computer for delegation to specified * services only / Use any authentication protocol) * - Add host/foo.domain to the keytab (possibly easiest to do this * with ktadd) * * For S4U2Proxy to work the TGT must be forwardable too. * * Usage eg: * * kinit -k -t test.keytab -f 'host/test.win.mit.edu@WIN.MIT.EDU' * ./t_s4u p:delegtest@WIN.MIT.EDU p:HOST/WIN-EQ7E4AA2WR8.win.mit.edu@WIN.MIT.EDU test.keytab */ static int use_spnego = 0; static void test_prf(gss_ctx_id_t initiatorContext, gss_ctx_id_t acceptorContext, int flags) { gss_buffer_desc constant; OM_uint32 major, minor; unsigned int i; gss_buffer_desc initiatorPrf; gss_buffer_desc acceptorPrf; constant.value = "gss prf test"; constant.length = strlen((char *)constant.value); initiatorPrf.value = NULL; acceptorPrf.value = NULL; major = gss_pseudo_random(&minor, initiatorContext, flags, &constant, 19, &initiatorPrf); check_gsserr("gss_pseudo_random", major, minor); printf("%s\n", flags == GSS_C_PRF_KEY_FULL ? "PRF_KEY_FULL" : "PRF_KEY_PARTIAL"); printf("Initiator PRF: "); for (i = 0; i < initiatorPrf.length; i++) printf("%02x ", ((char *)initiatorPrf.value)[i] & 0xFF); printf("\n"); major = gss_pseudo_random(&minor, acceptorContext, flags, &constant, 19, &acceptorPrf); check_gsserr("gss_pseudo_random", major, minor); printf("Acceptor PRF: "); for (i = 0; i < acceptorPrf.length; i++) printf("%02x ", ((char *)acceptorPrf.value)[i] & 0xFF); printf("\n"); if (acceptorPrf.length != initiatorPrf.length || memcmp(acceptorPrf.value, initiatorPrf.value, initiatorPrf.length)) { fprintf(stderr, "Initiator and acceptor PRF output does not match\n"); exit(1); } (void)gss_release_buffer(&minor, &initiatorPrf); (void)gss_release_buffer(&minor, &acceptorPrf); } static void init_accept_sec_context(gss_cred_id_t claimant_cred_handle, gss_cred_id_t verifier_cred_handle, gss_cred_id_t *deleg_cred_handle) { OM_uint32 major, minor, flags; gss_name_t source_name = GSS_C_NO_NAME, target_name = GSS_C_NO_NAME; gss_ctx_id_t initiator_context, acceptor_context; gss_OID mech; *deleg_cred_handle = GSS_C_NO_CREDENTIAL; major = gss_inquire_cred(&minor, verifier_cred_handle, &target_name, NULL, NULL, NULL); check_gsserr("gss_inquire_cred", major, minor); display_canon_name("Target name", target_name, &mech_krb5); mech = use_spnego ? &mech_spnego : &mech_krb5; display_oid("Target mech", mech); flags = GSS_C_REPLAY_FLAG | GSS_C_SEQUENCE_FLAG; establish_contexts(mech, claimant_cred_handle, verifier_cred_handle, target_name, flags, &initiator_context, &acceptor_context, &source_name, NULL, deleg_cred_handle); test_prf(initiator_context, acceptor_context, GSS_C_PRF_KEY_FULL); test_prf(initiator_context, acceptor_context, GSS_C_PRF_KEY_PARTIAL); (void)gss_release_name(&minor, &source_name); (void)gss_delete_sec_context(&minor, &acceptor_context, NULL); (void)gss_delete_sec_context(&minor, &initiator_context, NULL); } static void get_default_cred(const char *keytab_name, gss_OID_set mechs, gss_cred_id_t *impersonator_cred_handle) { OM_uint32 major = GSS_S_FAILURE, minor; krb5_error_code ret; krb5_context context = NULL; krb5_keytab keytab = NULL; krb5_principal keytab_principal = NULL; krb5_ccache ccache = NULL; if (keytab_name != NULL) { ret = krb5_init_context(&context); check_k5err(context, "krb5_init_context", ret); ret = krb5_kt_resolve(context, keytab_name, &keytab); check_k5err(context, "krb5_kt_resolve", ret); ret = krb5_cc_default(context, &ccache); check_k5err(context, "krb5_cc_default", ret); ret = krb5_cc_get_principal(context, ccache, &keytab_principal); check_k5err(context, "krb5_cc_get_principal", ret); major = gss_krb5_import_cred(&minor, ccache, keytab_principal, keytab, impersonator_cred_handle); check_gsserr("gss_krb5_import_cred", major, minor); krb5_free_principal(context, keytab_principal); krb5_cc_close(context, ccache); krb5_kt_close(context, keytab); krb5_free_context(context); } else { major = gss_acquire_cred(&minor, GSS_C_NO_NAME, GSS_C_INDEFINITE, mechs, GSS_C_BOTH, impersonator_cred_handle, NULL, NULL); check_gsserr("gss_acquire_cred", major, minor); } } int main(int argc, char *argv[]) { OM_uint32 minor, major; gss_cred_id_t impersonator_cred_handle = GSS_C_NO_CREDENTIAL; gss_cred_id_t user_cred_handle = GSS_C_NO_CREDENTIAL; gss_cred_id_t delegated_cred_handle = GSS_C_NO_CREDENTIAL; gss_name_t user = GSS_C_NO_NAME, target = GSS_C_NO_NAME; gss_OID_set mechs, actual_mechs = GSS_C_NO_OID_SET; uid_t uid; if (argc < 2 || argc > 5) { fprintf(stderr, "Usage: %s [--spnego] [user] " "[proxy-target] [keytab]\n", argv[0]); fprintf(stderr, " proxy-target and keytab are optional\n"); exit(1); } if (strcmp(argv[1], "--spnego") == 0) { use_spnego++; argc--; argv++; } user = import_name(argv[1]); major = gss_pname_to_uid(&minor, user, NULL, &uid); check_gsserr("gss_pname_to_uid(user)", major, minor); if (argc > 2 && strcmp(argv[2], "-") != 0) target = import_name(argv[2]); mechs = use_spnego ? &mechset_spnego : &mechset_krb5; get_default_cred((argc > 3) ? argv[3] : NULL, mechs, &impersonator_cred_handle); printf("Protocol transition tests follow\n"); printf("-----------------------------------\n\n"); /* get S4U2Self cred */ major = gss_acquire_cred_impersonate_name(&minor, impersonator_cred_handle, user, GSS_C_INDEFINITE, mechs, GSS_C_INITIATE, &user_cred_handle, &actual_mechs, NULL); check_gsserr("gss_acquire_cred_impersonate_name", major, minor); /* Try to store it in default ccache */ major = gss_store_cred(&minor, user_cred_handle, GSS_C_INITIATE, &mechs->elements[0], 1, 1, NULL, NULL); check_gsserr("gss_store_cred", major, minor); init_accept_sec_context(user_cred_handle, impersonator_cred_handle, &delegated_cred_handle); printf("\n"); (void)gss_release_name(&minor, &user); (void)gss_release_name(&minor, &target); (void)gss_release_cred(&minor, &delegated_cred_handle); (void)gss_release_cred(&minor, &impersonator_cred_handle); (void)gss_release_cred(&minor, &user_cred_handle); (void)gss_release_oid_set(&minor, &actual_mechs); return 0; } krb5-1.16/src/tests/gssapi/common.h0000644000704600001450000000662013211554426017062 0ustar ghudsonlibuuid/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* tests/gssapi/common.h - Declarations for GSSAPI test utility functions */ /* * Copyright (C) 2012 by the Massachusetts Institute of Technology. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef COMMON_H #define COMMON_H #include extern gss_OID_desc mech_krb5; extern gss_OID_desc mech_spnego; extern gss_OID_desc mech_iakerb; extern gss_OID_set_desc mechset_krb5; extern gss_OID_set_desc mechset_spnego; extern gss_OID_set_desc mechset_iakerb; /* Display an error message (containing msg) and exit if major is an error. */ void check_gsserr(const char *msg, OM_uint32 major, OM_uint32 minor); /* Display an error message (containing msg) and exit if code is an error. */ void check_k5err(krb5_context context, const char *msg, krb5_error_code code); /* Display an error message containing msg and exit. */ void errout(const char *msg); /* Import a GSSAPI name based on a string of the form 'u:username', * 'p:principalname', or 'h:host@service' (or just 'h:service'). */ gss_name_t import_name(const char *str); /* Establish contexts using gss_init_sec_context and gss_accept_sec_context. */ void establish_contexts(gss_OID imech, gss_cred_id_t icred, gss_cred_id_t acred, gss_name_t tname, OM_uint32 flags, gss_ctx_id_t *ictx, gss_ctx_id_t *actx, gss_name_t *src_name, gss_OID *amech, gss_cred_id_t *deleg_cred); /* Export *cred to a token, then release *cred and replace it by re-importing * the token. */ void export_import_cred(gss_cred_id_t *cred); /* Display name as canonicalized to mech, preceded by tag. */ void display_canon_name(const char *tag, gss_name_t name, gss_OID mech); /* Display oid in printable form, preceded by tag (if not NULL). */ void display_oid(const char *tag, gss_OID oid); /* Display attributes of name, including hex value if noisy is true. */ void enumerate_attributes(gss_name_t name, int noisy); /* Display the contents of buf to fp in hex, followed by a newline. */ void print_hex(FILE *fp, gss_buffer_t buf); #endif /* COMMON_H */ krb5-1.16/src/tests/gssapi/t_ciflags.c0000644000704600001450000001207413211554426017520 0ustar ghudsonlibuuid/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* tests/gssapi/t_ciflags.c - GSS_KRB5_CRED_NO_CI_FLAGS_X tests */ /* * Copyright (C) 2015 by the Massachusetts Institute of Technology. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #include #include #include #include "common.h" static void flagtest(gss_OID mech, gss_cred_id_t icred, gss_name_t tname, OM_uint32 inflags, OM_uint32 expflags) { gss_ctx_id_t ictx, actx; OM_uint32 major, minor, flags; establish_contexts(mech, icred, GSS_C_NO_CREDENTIAL, tname, inflags, &ictx, &actx, NULL, NULL, NULL); major = gss_inquire_context(&minor, actx, NULL, NULL, NULL, NULL, &flags, NULL, NULL); check_gsserr("gss_inquire_context", major, minor); assert(flags == expflags); (void)gss_delete_sec_context(&minor, &ictx, NULL); (void)gss_delete_sec_context(&minor, &actx, NULL); } int main(int argc, char *argv[]) { OM_uint32 minor, major; gss_cred_id_t icred; gss_name_t tname; gss_buffer_desc empty_buffer = GSS_C_EMPTY_BUFFER; if (argc != 2) { fprintf(stderr, "Usage: %s targetname\n", argv[0]); return 1; } tname = import_name(argv[1]); /* With no flags, the initiator asserts conf, integ, trans */ flagtest(&mech_krb5, GSS_C_NO_CREDENTIAL, tname, 0, GSS_C_CONF_FLAG | GSS_C_INTEG_FLAG | GSS_C_TRANS_FLAG); flagtest(&mech_spnego, GSS_C_NO_CREDENTIAL, tname, 0, GSS_C_CONF_FLAG | GSS_C_INTEG_FLAG | GSS_C_TRANS_FLAG); /* The initiator also asserts most flags specified by the caller. */ flagtest(&mech_krb5, GSS_C_NO_CREDENTIAL, tname, GSS_C_SEQUENCE_FLAG, GSS_C_CONF_FLAG | GSS_C_INTEG_FLAG | GSS_C_TRANS_FLAG | GSS_C_SEQUENCE_FLAG); flagtest(&mech_spnego, GSS_C_NO_CREDENTIAL, tname, GSS_C_SEQUENCE_FLAG, GSS_C_CONF_FLAG | GSS_C_INTEG_FLAG | GSS_C_TRANS_FLAG | GSS_C_SEQUENCE_FLAG); /* Get a normal initiator cred and re-test with no flags. */ major = gss_acquire_cred(&minor, GSS_C_NO_NAME, GSS_C_INDEFINITE, GSS_C_NO_OID_SET, GSS_C_INITIATE, &icred, NULL, NULL); check_gsserr("gss_acquire_cred", major, minor); flagtest(&mech_krb5, icred, tname, 0, GSS_C_CONF_FLAG | GSS_C_INTEG_FLAG | GSS_C_TRANS_FLAG); flagtest(&mech_spnego, icred, tname, 0, GSS_C_CONF_FLAG | GSS_C_INTEG_FLAG | GSS_C_TRANS_FLAG); /* Suppress confidentiality and integrity flags on the initiator cred and * check that they are suppressed, but can still be asserted explicitly. */ major = gss_set_cred_option(&minor, &icred, (gss_OID)GSS_KRB5_CRED_NO_CI_FLAGS_X, &empty_buffer); check_gsserr("gss_set_cred_option", major, minor); flagtest(&mech_krb5, icred, tname, 0, GSS_C_TRANS_FLAG); flagtest(&mech_krb5, icred, tname, GSS_C_CONF_FLAG, GSS_C_CONF_FLAG | GSS_C_TRANS_FLAG); flagtest(&mech_krb5, icred, tname, GSS_C_INTEG_FLAG, GSS_C_INTEG_FLAG | GSS_C_TRANS_FLAG); flagtest(&mech_krb5, icred, tname, GSS_C_CONF_FLAG | GSS_C_INTEG_FLAG, GSS_C_CONF_FLAG | GSS_C_INTEG_FLAG | GSS_C_TRANS_FLAG); flagtest(&mech_spnego, icred, tname, 0, GSS_C_TRANS_FLAG); flagtest(&mech_spnego, icred, tname, GSS_C_INTEG_FLAG, GSS_C_INTEG_FLAG | GSS_C_TRANS_FLAG); flagtest(&mech_spnego, icred, tname, GSS_C_CONF_FLAG, GSS_C_CONF_FLAG | GSS_C_TRANS_FLAG); flagtest(&mech_spnego, icred, tname, GSS_C_CONF_FLAG | GSS_C_INTEG_FLAG, GSS_C_CONF_FLAG | GSS_C_INTEG_FLAG | GSS_C_TRANS_FLAG); (void)gss_release_name(&minor, &tname); (void)gss_release_cred(&minor, &icred); return 0; } krb5-1.16/src/tests/dumpfiles/0000755000704600001450000000000013211554426016117 5ustar ghudsonlibuuidkrb5-1.16/src/tests/dumpfiles/dump.r130000644000704600001450000001204313211554426017413 0ustar ghudsonlibuuidkdb5_util load_dump version 5 princ 38 15 3 1 0 K/M@KRBTEST.COM 64 86400 0 0 0 0 0 0 8 2 0100 9 8 0100010000000000 2 28 b93e105164625f6372656174696f6e404b5242544553542e434f4d00 1 1 18 62 2000408c027c250e8cc3b81476414f2214d57c1ce38891e29792e87258247c73547df4d5756266931dd6686b62270e656895a31ec66bfe913b4f15226227 -1; princ 38 36 4 4 0 host/equal-rites.mit.edu@KRBTEST.COM 0 86400 0 0 0 0 0 0 3 24 12345c010000000000000000000000000000000200000000 2 30 b93e105167687564736f6e2f61646d696e404b5242544553542e434f4d00 8 2 0100 1 4 b93e1051 1 1 18 62 20009b7f9e9edd44559c5ffb2b52beb92e57586f9bdf59ae0be7010ffa8b628928bebc7d6015211977bc34325be853e5f1eb5826ce75575414bc2696bc16 1 1 17 46 10001bfaf4d8ddd6e8767194a190e9dec2617dbc90883db767fa464325b76b97ea98f3b61c4d4234ff9aee6314a4 1 1 16 54 18008291ce8c2ccde958c2739e93ce499b088b1b8c304bce95097bd6c1bd92c3c9f64e92950767f7806d890b386ba586fdb7f8433f1c 1 1 23 46 1000a460520a9e39b1539e703a51793967247999a9a0bb7c59a61ca2b5e64a58c3b9cf8217daeddd71caae9d7fbb -1; princ 38 24 4 4 0 kadmin/admin@KRBTEST.COM 4 10800 0 0 0 0 0 0 3 24 12345c010000000000000000000000000000000200000000 2 26 b93e10516b6462355f7574696c404b5242544553542e434f4d00 8 2 0100 1 4 b93e1051 1 1 18 62 20005ea70b11f3337975c5463baedc68b234cadf72f89828d98e3c16cb8640bba7c5ed48a4bcf7649a73a9a410e96234924bfacd4bb38f08982db02c5c5b 1 1 17 46 10001b678f8b9bb6913397202c259702c1941fd5d2892f42349a92ca908de248cd041465bb3d16d27efce1f63e30 1 1 16 54 18009ed81fe14b19549918acad7b1158b86f5971ab3bd77b2359c29147af35730167210157e510dda65f691c312ac398850d7e228c40 1 1 23 46 10001d15a249bbea104208ae0b3d83337d4c06f6edef6a6ac60ec3df7b52aeeeb388c7233a9b1e3de646949ed540 -1; princ 38 27 4 4 0 kadmin/changepw@KRBTEST.COM 8196 300 0 0 0 0 0 0 3 24 12345c010000000000000000000000000000000200000000 2 26 b93e10516b6462355f7574696c404b5242544553542e434f4d00 8 2 0100 1 4 b93e1051 1 1 18 62 200015daf7bc8073eae166b03231330b81b78cfd6021d3dcf3700862dc98725c5bb549a72aa2ae8eef37dc2db5acc59cc62600f72052c6238ef216dd24a5 1 1 17 46 1000c1e176f253d6292fe4e34b2edfbdd5ff81ff3e17b38c2a674bd738d20fc40a4ed38a02351f4a9872123fb865 1 1 16 54 18008bf3418871e7d117af489798fbbcc031c534e095b4e4ed6cb110c7d87a91e5fb6c080c77616618db80ed37589fcc0ca8328406ef 1 1 23 46 10007a522025d2e7126dc48d76218e9efb3ff4326a3b5969be0deac108657a9d23c7827ec39b828fd43e51ea114b -1; princ 38 38 4 4 0 kadmin/equal-rites.mit.edu@KRBTEST.COM 4 10800 0 0 0 0 0 0 3 24 12345c010000000000000000000000000000000200000000 2 26 b93e10516b6462355f7574696c404b5242544553542e434f4d00 8 2 0100 1 4 b93e1051 1 1 18 62 200045a2e5b79c5787bfc68700d3abc0034cc91d48f10636c35e1a571c41c4e6892caceeda8808bfa46aa4050a6d33d99cb64d237f645af6741e90c723ff 1 1 17 46 100073b99fecd81b4fe113b10852065c15e75ed7d256d2d242b3cca57317c28c7fece4bda797f116309ea5bc2eb1 1 1 16 54 1800bd05672170b5d04cb62394498988f3844b744a0793ac435d044e67ed0ee50d20c408b30cec599c169378b0ad2a4967f42aef38e5 1 1 23 46 1000a1a515e0fe322980f319752bf85dd405ca2bdda148009654584b70f50d38c532df1c2d0a3c56f9758775b007 -1; princ 38 30 1 4 0 krbtgt/KRBTEST.COM@KRBTEST.COM 0 86400 0 0 0 0 0 0 2 28 b93e105164625f6372656174696f6e404b5242544553542e434f4d00 1 1 18 62 2000582c9aaf26c4a0abf13600baf37718c91e15dca02385e346cf5d2730d28b2302677f23d02791299548b45e1ced0b05cd30062617bff7532885d7889c 1 1 17 46 1000122eb47263d7837771ebbf7ad82163cc2ea7674a417944c0cbf186522fc0e74a73affd4a42fb9fda287be4f8 1 1 16 54 18008cd8064aea468f13f36ae13ecd4f993d87ef6bafcb2dc5101ad903200ffe3d5c265b2f0c71a6c07ec60d259b6862825cc77a70b2 1 1 23 46 10001699ad0304644456106328fbd733bd5c524f20d4b5d8b8e370eff196803b5990ee7e9eb4b6c2214cf327f59b -1; princ 38 18 4 0 0 nokeys@KRBTEST.COM 0 86400 0 0 0 0 0 0 3 24 12345c010000000000000000000000000000000200000000 2 27 d931dc51757365722f61646d696e404b5242544553542e434f4d00 8 2 0100 1 4 d931dc51 -1; princ 38 22 4 4 0 user/admin@KRBTEST.COM 0 86400 0 0 0 0 0 0 3 24 12345c010000000000000000000000000000000200000000 2 30 b93e105167687564736f6e2f61646d696e404b5242544553542e434f4d00 8 2 0100 1 4 b93e1051 1 1 18 62 20002db4cd2b0824c44a17cdbb2d180a1ec9956db35d74741826ed0d77eaef9abdb20c481d5ab9f511d5a3e6b8def443382f03d247568d81529e5dd17fae 1 1 17 46 100011d7cc3627468d565d398cffd735a3cc9d3705cd9846cede198c7d07f4e8209cd9192bc6c5f127169c00f373 1 1 16 54 18002bd9dc3388c90055844b3b4c5c2a814d73758f226d44d7dc5e35ef3b65e7d80cd604a4ef2a5769106818c3d813956bbad1813cb2 1 1 23 46 1000409681c3ff356fb7d28a9f71957c3465ea42ec4eee5019a662f7d367042527b76ae783cfbd0dccbd7529d090 -1; princ 38 16 4 4 0 user@KRBTEST.COM 0 86400 0 0 0 0 0 0 3 32 12345c010000000874657374706f6c0000000800000000000000000200000000 2 27 d73e1051757365722f61646d696e404b5242544553542e434f4d00 8 2 0100 1 4 b93e1051 1 1 18 62 2000aec451aae295389f92d177e61b5154941386c70d75d382393e556dfa61bd77d112a777420a99030b56649d366bba83a5c40aa17fa4522222d2e78e10 1 1 17 46 10009c8ab7b3f89ccf3ca3ad98352a461b7f4f1b0c495605117591d9ad52ba4da0adef7a902126973ed2bdc3ffbf 1 1 16 54 18002b87a46d6c4de954a316b5ce28a99886f2abb6b0307190e577b81171dfb7a067139835be8625bc36b0edaaed357609107d85d335 1 1 23 46 1000c01fcdb3050a2270f82dbafbe4c1adc868377bf7133ee7a1bcaf85817abe541beb8008b91c54b99e93d2e0f5 -1; policy testpol 0 0 1 3 1 0 krb5-1.16/src/tests/dumpfiles/dump0000644000704600001450000001206313211554426017011 0ustar ghudsonlibuuidkdb5_util load_dump version 7 princ 38 15 3 1 0 K/M@KRBTEST.COM 64 86400 0 0 0 0 0 0 8 2 0100 9 8 0100010000000000 2 28 b93e105164625f6372656174696f6e404b5242544553542e434f4d00 1 1 18 62 2000408c027c250e8cc3b81476414f2214d57c1ce38891e29792e87258247c73547df4d5756266931dd6686b62270e656895a31ec66bfe913b4f15226227 -1; princ 38 36 4 4 0 host/equal-rites.mit.edu@KRBTEST.COM 0 86400 0 0 0 0 0 0 3 24 12345c010000000000000000000000000000000200000000 2 30 b93e105167687564736f6e2f61646d696e404b5242544553542e434f4d00 8 2 0100 1 4 b93e1051 1 1 18 62 20009b7f9e9edd44559c5ffb2b52beb92e57586f9bdf59ae0be7010ffa8b628928bebc7d6015211977bc34325be853e5f1eb5826ce75575414bc2696bc16 1 1 17 46 10001bfaf4d8ddd6e8767194a190e9dec2617dbc90883db767fa464325b76b97ea98f3b61c4d4234ff9aee6314a4 1 1 16 54 18008291ce8c2ccde958c2739e93ce499b088b1b8c304bce95097bd6c1bd92c3c9f64e92950767f7806d890b386ba586fdb7f8433f1c 1 1 23 46 1000a460520a9e39b1539e703a51793967247999a9a0bb7c59a61ca2b5e64a58c3b9cf8217daeddd71caae9d7fbb -1; princ 38 24 4 4 0 kadmin/admin@KRBTEST.COM 4 10800 0 0 0 0 0 0 3 24 12345c010000000000000000000000000000000200000000 2 26 b93e10516b6462355f7574696c404b5242544553542e434f4d00 8 2 0100 1 4 b93e1051 1 1 18 62 20005ea70b11f3337975c5463baedc68b234cadf72f89828d98e3c16cb8640bba7c5ed48a4bcf7649a73a9a410e96234924bfacd4bb38f08982db02c5c5b 1 1 17 46 10001b678f8b9bb6913397202c259702c1941fd5d2892f42349a92ca908de248cd041465bb3d16d27efce1f63e30 1 1 16 54 18009ed81fe14b19549918acad7b1158b86f5971ab3bd77b2359c29147af35730167210157e510dda65f691c312ac398850d7e228c40 1 1 23 46 10001d15a249bbea104208ae0b3d83337d4c06f6edef6a6ac60ec3df7b52aeeeb388c7233a9b1e3de646949ed540 -1; princ 38 27 4 4 0 kadmin/changepw@KRBTEST.COM 8196 300 0 0 0 0 0 0 3 24 12345c010000000000000000000000000000000200000000 2 26 b93e10516b6462355f7574696c404b5242544553542e434f4d00 8 2 0100 1 4 b93e1051 1 1 18 62 200015daf7bc8073eae166b03231330b81b78cfd6021d3dcf3700862dc98725c5bb549a72aa2ae8eef37dc2db5acc59cc62600f72052c6238ef216dd24a5 1 1 17 46 1000c1e176f253d6292fe4e34b2edfbdd5ff81ff3e17b38c2a674bd738d20fc40a4ed38a02351f4a9872123fb865 1 1 16 54 18008bf3418871e7d117af489798fbbcc031c534e095b4e4ed6cb110c7d87a91e5fb6c080c77616618db80ed37589fcc0ca8328406ef 1 1 23 46 10007a522025d2e7126dc48d76218e9efb3ff4326a3b5969be0deac108657a9d23c7827ec39b828fd43e51ea114b -1; princ 38 38 4 4 0 kadmin/equal-rites.mit.edu@KRBTEST.COM 4 10800 0 0 0 0 0 0 3 24 12345c010000000000000000000000000000000200000000 2 26 b93e10516b6462355f7574696c404b5242544553542e434f4d00 8 2 0100 1 4 b93e1051 1 1 18 62 200045a2e5b79c5787bfc68700d3abc0034cc91d48f10636c35e1a571c41c4e6892caceeda8808bfa46aa4050a6d33d99cb64d237f645af6741e90c723ff 1 1 17 46 100073b99fecd81b4fe113b10852065c15e75ed7d256d2d242b3cca57317c28c7fece4bda797f116309ea5bc2eb1 1 1 16 54 1800bd05672170b5d04cb62394498988f3844b744a0793ac435d044e67ed0ee50d20c408b30cec599c169378b0ad2a4967f42aef38e5 1 1 23 46 1000a1a515e0fe322980f319752bf85dd405ca2bdda148009654584b70f50d38c532df1c2d0a3c56f9758775b007 -1; princ 38 30 1 4 0 krbtgt/KRBTEST.COM@KRBTEST.COM 0 86400 0 0 0 0 0 0 2 28 b93e105164625f6372656174696f6e404b5242544553542e434f4d00 1 1 18 62 2000582c9aaf26c4a0abf13600baf37718c91e15dca02385e346cf5d2730d28b2302677f23d02791299548b45e1ced0b05cd30062617bff7532885d7889c 1 1 17 46 1000122eb47263d7837771ebbf7ad82163cc2ea7674a417944c0cbf186522fc0e74a73affd4a42fb9fda287be4f8 1 1 16 54 18008cd8064aea468f13f36ae13ecd4f993d87ef6bafcb2dc5101ad903200ffe3d5c265b2f0c71a6c07ec60d259b6862825cc77a70b2 1 1 23 46 10001699ad0304644456106328fbd733bd5c524f20d4b5d8b8e370eff196803b5990ee7e9eb4b6c2214cf327f59b -1; princ 38 18 4 0 0 nokeys@KRBTEST.COM 0 86400 0 0 0 0 0 0 3 24 12345c010000000000000000000000000000000200000000 2 27 d931dc51757365722f61646d696e404b5242544553542e434f4d00 8 2 0100 1 4 d931dc51 -1; princ 38 22 4 4 0 user/admin@KRBTEST.COM 0 86400 0 0 0 0 0 0 3 24 12345c010000000000000000000000000000000200000000 2 30 b93e105167687564736f6e2f61646d696e404b5242544553542e434f4d00 8 2 0100 1 4 b93e1051 1 1 18 62 20002db4cd2b0824c44a17cdbb2d180a1ec9956db35d74741826ed0d77eaef9abdb20c481d5ab9f511d5a3e6b8def443382f03d247568d81529e5dd17fae 1 1 17 46 100011d7cc3627468d565d398cffd735a3cc9d3705cd9846cede198c7d07f4e8209cd9192bc6c5f127169c00f373 1 1 16 54 18002bd9dc3388c90055844b3b4c5c2a814d73758f226d44d7dc5e35ef3b65e7d80cd604a4ef2a5769106818c3d813956bbad1813cb2 1 1 23 46 1000409681c3ff356fb7d28a9f71957c3465ea42ec4eee5019a662f7d367042527b76ae783cfbd0dccbd7529d090 -1; princ 38 16 4 4 0 user@KRBTEST.COM 0 86400 0 0 0 0 0 0 3 32 12345c010000000874657374706f6c0000000800000000000000000200000000 2 27 d73e1051757365722f61646d696e404b5242544553542e434f4d00 8 2 0100 1 4 b93e1051 1 1 18 62 2000aec451aae295389f92d177e61b5154941386c70d75d382393e556dfa61bd77d112a777420a99030b56649d366bba83a5c40aa17fa4522222d2e78e10 1 1 17 46 10009c8ab7b3f89ccf3ca3ad98352a461b7f4f1b0c495605117591d9ad52ba4da0adef7a902126973ed2bdc3ffbf 1 1 16 54 18002b87a46d6c4de954a316b5ce28a99886f2abb6b0307190e577b81171dfb7a067139835be8625bc36b0edaaed357609107d85d335 1 1 23 46 1000c01fcdb3050a2270f82dbafbe4c1adc868377bf7133ee7a1bcaf85817abe541beb8008b91c54b99e93d2e0f5 -1; policy testpol 0 0 1 3 1 0 0 0 0 0 0 0 - 0 krb5-1.16/src/tests/dumpfiles/dump.ov0000644000704600001450000000053413211554426017434 0ustar ghudsonlibuuidOpenV*Secure V1.0 princ host/equal-rites.mit.edu@KRBTEST.COM 0 0 0 2 princ kadmin/admin@KRBTEST.COM 0 0 0 2 princ kadmin/changepw@KRBTEST.COM 0 0 0 2 princ kadmin/equal-rites.mit.edu@KRBTEST.COM 0 0 0 2 princ nokeys@KRBTEST.COM 0 0 0 2 princ user/admin@KRBTEST.COM 0 0 0 2 princ user@KRBTEST.COM testpol 800 0 0 2 policy testpol 0 0 1 3 1 0 krb5-1.16/src/tests/dumpfiles/dump.160000644000704600001450000000415713211554426017243 0ustar ghudsonlibuuidkdb5_util load_dump version 5 princ 38 15 1 1 0 K/M@KRBTEST.COM 64 36000 604800 0 0 0 0 0 2 28 18de675264625f6372656174696f6e404b5242544553542e434f4d00 1 1 16 54 180001361a6c58b3a273e484574c6c5739fb114ffe7d2298e767b545f332e3bda573021c97728028e7ec4942708f23f4445d4419f4ad -1; princ 38 24 3 2 0 kadmin/admin@KRBTEST.COM 4 10800 604800 0 0 0 0 0 3 24 12345c010000000000000000000000000000000200000000 2 26 18de67526b6462355f7574696c404b5242544553542e434f4d00 1 4 18de6752 1 2 16 54 1800555ff1892cdb7dd7c62b659f9659981205ebb4f9fd4446e5243f58dfc0b99a4f096080d435702e052793a90c66aea062c8b8964e 1 2 1 38 0800ca62598d281381a22fc6d5bdf25653002b6afeb8f24af6ea01c9301359527304a08bb8f5 -1; princ 38 27 3 2 0 kadmin/changepw@KRBTEST.COM 8196 300 604800 0 0 0 0 0 3 24 12345c010000000000000000000000000000000200000000 2 26 18de67526b6462355f7574696c404b5242544553542e434f4d00 1 4 18de6752 1 2 16 54 1800237a5df1fc3295e08ba18986f51f553c2d0dfff3fb8e17d19ac7777a1cd516713e5496521ba362261ab61c063090705ecf7bca01 1 2 1 38 0800685d1f82188b712b2947b63a259269b1fe53bf383bb05cdc802e2cb9d680631e512af4d4 -1; princ 38 38 3 2 0 kadmin/equal-rites.mit.edu@KRBTEST.COM 4 10800 604800 0 0 0 0 0 3 24 12345c010000000000000000000000000000000200000000 2 26 18de67526b6462355f7574696c404b5242544553542e434f4d00 1 4 18de6752 1 2 16 54 1800ed9ad2e91940a41abc9b05d7dfb736c353e3ff18272b1d3bc31e5ebc3204e15d5fd9c3caa0c57be4736831b6f03c1741d5423ff1 1 2 1 38 0800eb82c30aa8e1f5a10f0f099372e2ff3385cb5437b41abee02491673cf45c79b2c4466364 -1; princ 38 26 3 1 0 kadmin/history@KRBTEST.COM 0 64 604800 0 0 0 0 0 3 24 12345c010000000000000000000000000000000200000000 2 26 18de67526b6462355f7574696c404b5242544553542e434f4d00 1 4 18de6752 1 2 16 54 180070b4f132c63aa7d8b91f1323daa8d59bf2e04663b9b8931bcbe9a953c4fab6dda7c820db0cf9922af5ebfb7bd09101849e81f054 -1; princ 38 30 1 2 0 krbtgt/KRBTEST.COM@KRBTEST.COM 0 36000 604800 0 0 0 0 0 2 28 18de675264625f6372656174696f6e404b5242544553542e434f4d00 1 1 16 54 1800010572e45515fc5ee028a59a48bc86896ab5014c265304b2340d37a46c0185312e475e9245e70df0f6874c9348a2ca4389c7168f 1 1 1 38 0800d8b88190a5e7f49cdca68c0e018bafd971f1606f9af2f2e3d9e31c69071556896443ade2 -1; krb5-1.16/src/tests/dumpfiles/dump.b70000644000704600001450000001123113211554426017314 0ustar ghudsonlibuuidkdb5_util load_dump version 4 princ 38 15 3 1 0 K/M@KRBTEST.COM 64 86400 0 0 0 0 0 0 8 2 0100 9 8 0100010000000000 2 28 b93e105164625f6372656174696f6e404b5242544553542e434f4d00 1 1 18 62 2000408c027c250e8cc3b81476414f2214d57c1ce38891e29792e87258247c73547df4d5756266931dd6686b62270e656895a31ec66bfe913b4f15226227 -1; princ 38 36 3 4 0 host/equal-rites.mit.edu@KRBTEST.COM 0 86400 0 0 0 0 0 0 2 30 b93e105167687564736f6e2f61646d696e404b5242544553542e434f4d00 8 2 0100 1 4 b93e1051 1 1 18 62 20009b7f9e9edd44559c5ffb2b52beb92e57586f9bdf59ae0be7010ffa8b628928bebc7d6015211977bc34325be853e5f1eb5826ce75575414bc2696bc16 1 1 17 46 10001bfaf4d8ddd6e8767194a190e9dec2617dbc90883db767fa464325b76b97ea98f3b61c4d4234ff9aee6314a4 1 1 16 54 18008291ce8c2ccde958c2739e93ce499b088b1b8c304bce95097bd6c1bd92c3c9f64e92950767f7806d890b386ba586fdb7f8433f1c 1 1 23 46 1000a460520a9e39b1539e703a51793967247999a9a0bb7c59a61ca2b5e64a58c3b9cf8217daeddd71caae9d7fbb -1; princ 38 24 3 4 0 kadmin/admin@KRBTEST.COM 4 10800 0 0 0 0 0 0 2 26 b93e10516b6462355f7574696c404b5242544553542e434f4d00 8 2 0100 1 4 b93e1051 1 1 18 62 20005ea70b11f3337975c5463baedc68b234cadf72f89828d98e3c16cb8640bba7c5ed48a4bcf7649a73a9a410e96234924bfacd4bb38f08982db02c5c5b 1 1 17 46 10001b678f8b9bb6913397202c259702c1941fd5d2892f42349a92ca908de248cd041465bb3d16d27efce1f63e30 1 1 16 54 18009ed81fe14b19549918acad7b1158b86f5971ab3bd77b2359c29147af35730167210157e510dda65f691c312ac398850d7e228c40 1 1 23 46 10001d15a249bbea104208ae0b3d83337d4c06f6edef6a6ac60ec3df7b52aeeeb388c7233a9b1e3de646949ed540 -1; princ 38 27 3 4 0 kadmin/changepw@KRBTEST.COM 8196 300 0 0 0 0 0 0 2 26 b93e10516b6462355f7574696c404b5242544553542e434f4d00 8 2 0100 1 4 b93e1051 1 1 18 62 200015daf7bc8073eae166b03231330b81b78cfd6021d3dcf3700862dc98725c5bb549a72aa2ae8eef37dc2db5acc59cc62600f72052c6238ef216dd24a5 1 1 17 46 1000c1e176f253d6292fe4e34b2edfbdd5ff81ff3e17b38c2a674bd738d20fc40a4ed38a02351f4a9872123fb865 1 1 16 54 18008bf3418871e7d117af489798fbbcc031c534e095b4e4ed6cb110c7d87a91e5fb6c080c77616618db80ed37589fcc0ca8328406ef 1 1 23 46 10007a522025d2e7126dc48d76218e9efb3ff4326a3b5969be0deac108657a9d23c7827ec39b828fd43e51ea114b -1; princ 38 38 3 4 0 kadmin/equal-rites.mit.edu@KRBTEST.COM 4 10800 0 0 0 0 0 0 2 26 b93e10516b6462355f7574696c404b5242544553542e434f4d00 8 2 0100 1 4 b93e1051 1 1 18 62 200045a2e5b79c5787bfc68700d3abc0034cc91d48f10636c35e1a571c41c4e6892caceeda8808bfa46aa4050a6d33d99cb64d237f645af6741e90c723ff 1 1 17 46 100073b99fecd81b4fe113b10852065c15e75ed7d256d2d242b3cca57317c28c7fece4bda797f116309ea5bc2eb1 1 1 16 54 1800bd05672170b5d04cb62394498988f3844b744a0793ac435d044e67ed0ee50d20c408b30cec599c169378b0ad2a4967f42aef38e5 1 1 23 46 1000a1a515e0fe322980f319752bf85dd405ca2bdda148009654584b70f50d38c532df1c2d0a3c56f9758775b007 -1; princ 38 30 1 4 0 krbtgt/KRBTEST.COM@KRBTEST.COM 0 86400 0 0 0 0 0 0 2 28 b93e105164625f6372656174696f6e404b5242544553542e434f4d00 1 1 18 62 2000582c9aaf26c4a0abf13600baf37718c91e15dca02385e346cf5d2730d28b2302677f23d02791299548b45e1ced0b05cd30062617bff7532885d7889c 1 1 17 46 1000122eb47263d7837771ebbf7ad82163cc2ea7674a417944c0cbf186522fc0e74a73affd4a42fb9fda287be4f8 1 1 16 54 18008cd8064aea468f13f36ae13ecd4f993d87ef6bafcb2dc5101ad903200ffe3d5c265b2f0c71a6c07ec60d259b6862825cc77a70b2 1 1 23 46 10001699ad0304644456106328fbd733bd5c524f20d4b5d8b8e370eff196803b5990ee7e9eb4b6c2214cf327f59b -1; princ 38 18 3 0 0 nokeys@KRBTEST.COM 0 86400 0 0 0 0 0 0 2 27 d931dc51757365722f61646d696e404b5242544553542e434f4d00 8 2 0100 1 4 d931dc51 -1; princ 38 22 3 4 0 user/admin@KRBTEST.COM 0 86400 0 0 0 0 0 0 2 30 b93e105167687564736f6e2f61646d696e404b5242544553542e434f4d00 8 2 0100 1 4 b93e1051 1 1 18 62 20002db4cd2b0824c44a17cdbb2d180a1ec9956db35d74741826ed0d77eaef9abdb20c481d5ab9f511d5a3e6b8def443382f03d247568d81529e5dd17fae 1 1 17 46 100011d7cc3627468d565d398cffd735a3cc9d3705cd9846cede198c7d07f4e8209cd9192bc6c5f127169c00f373 1 1 16 54 18002bd9dc3388c90055844b3b4c5c2a814d73758f226d44d7dc5e35ef3b65e7d80cd604a4ef2a5769106818c3d813956bbad1813cb2 1 1 23 46 1000409681c3ff356fb7d28a9f71957c3465ea42ec4eee5019a662f7d367042527b76ae783cfbd0dccbd7529d090 -1; princ 38 16 3 4 0 user@KRBTEST.COM 0 86400 0 0 0 0 0 0 2 27 d73e1051757365722f61646d696e404b5242544553542e434f4d00 8 2 0100 1 4 b93e1051 1 1 18 62 2000aec451aae295389f92d177e61b5154941386c70d75d382393e556dfa61bd77d112a777420a99030b56649d366bba83a5c40aa17fa4522222d2e78e10 1 1 17 46 10009c8ab7b3f89ccf3ca3ad98352a461b7f4f1b0c495605117591d9ad52ba4da0adef7a902126973ed2bdc3ffbf 1 1 16 54 18002b87a46d6c4de954a316b5ce28a99886f2abb6b0307190e577b81171dfb7a067139835be8625bc36b0edaaed357609107d85d335 1 1 23 46 1000c01fcdb3050a2270f82dbafbe4c1adc868377bf7133ee7a1bcaf85817abe541beb8008b91c54b99e93d2e0f5 -1; policy testpol 0 0 1 3 1 0 krb5-1.16/src/tests/dumpfiles/dump.r180000644000704600001450000001205113211554426017417 0ustar ghudsonlibuuidkdb5_util load_dump version 6 princ 38 15 3 1 0 K/M@KRBTEST.COM 64 86400 0 0 0 0 0 0 8 2 0100 9 8 0100010000000000 2 28 b93e105164625f6372656174696f6e404b5242544553542e434f4d00 1 1 18 62 2000408c027c250e8cc3b81476414f2214d57c1ce38891e29792e87258247c73547df4d5756266931dd6686b62270e656895a31ec66bfe913b4f15226227 -1; princ 38 36 4 4 0 host/equal-rites.mit.edu@KRBTEST.COM 0 86400 0 0 0 0 0 0 3 24 12345c010000000000000000000000000000000200000000 2 30 b93e105167687564736f6e2f61646d696e404b5242544553542e434f4d00 8 2 0100 1 4 b93e1051 1 1 18 62 20009b7f9e9edd44559c5ffb2b52beb92e57586f9bdf59ae0be7010ffa8b628928bebc7d6015211977bc34325be853e5f1eb5826ce75575414bc2696bc16 1 1 17 46 10001bfaf4d8ddd6e8767194a190e9dec2617dbc90883db767fa464325b76b97ea98f3b61c4d4234ff9aee6314a4 1 1 16 54 18008291ce8c2ccde958c2739e93ce499b088b1b8c304bce95097bd6c1bd92c3c9f64e92950767f7806d890b386ba586fdb7f8433f1c 1 1 23 46 1000a460520a9e39b1539e703a51793967247999a9a0bb7c59a61ca2b5e64a58c3b9cf8217daeddd71caae9d7fbb -1; princ 38 24 4 4 0 kadmin/admin@KRBTEST.COM 4 10800 0 0 0 0 0 0 3 24 12345c010000000000000000000000000000000200000000 2 26 b93e10516b6462355f7574696c404b5242544553542e434f4d00 8 2 0100 1 4 b93e1051 1 1 18 62 20005ea70b11f3337975c5463baedc68b234cadf72f89828d98e3c16cb8640bba7c5ed48a4bcf7649a73a9a410e96234924bfacd4bb38f08982db02c5c5b 1 1 17 46 10001b678f8b9bb6913397202c259702c1941fd5d2892f42349a92ca908de248cd041465bb3d16d27efce1f63e30 1 1 16 54 18009ed81fe14b19549918acad7b1158b86f5971ab3bd77b2359c29147af35730167210157e510dda65f691c312ac398850d7e228c40 1 1 23 46 10001d15a249bbea104208ae0b3d83337d4c06f6edef6a6ac60ec3df7b52aeeeb388c7233a9b1e3de646949ed540 -1; princ 38 27 4 4 0 kadmin/changepw@KRBTEST.COM 8196 300 0 0 0 0 0 0 3 24 12345c010000000000000000000000000000000200000000 2 26 b93e10516b6462355f7574696c404b5242544553542e434f4d00 8 2 0100 1 4 b93e1051 1 1 18 62 200015daf7bc8073eae166b03231330b81b78cfd6021d3dcf3700862dc98725c5bb549a72aa2ae8eef37dc2db5acc59cc62600f72052c6238ef216dd24a5 1 1 17 46 1000c1e176f253d6292fe4e34b2edfbdd5ff81ff3e17b38c2a674bd738d20fc40a4ed38a02351f4a9872123fb865 1 1 16 54 18008bf3418871e7d117af489798fbbcc031c534e095b4e4ed6cb110c7d87a91e5fb6c080c77616618db80ed37589fcc0ca8328406ef 1 1 23 46 10007a522025d2e7126dc48d76218e9efb3ff4326a3b5969be0deac108657a9d23c7827ec39b828fd43e51ea114b -1; princ 38 38 4 4 0 kadmin/equal-rites.mit.edu@KRBTEST.COM 4 10800 0 0 0 0 0 0 3 24 12345c010000000000000000000000000000000200000000 2 26 b93e10516b6462355f7574696c404b5242544553542e434f4d00 8 2 0100 1 4 b93e1051 1 1 18 62 200045a2e5b79c5787bfc68700d3abc0034cc91d48f10636c35e1a571c41c4e6892caceeda8808bfa46aa4050a6d33d99cb64d237f645af6741e90c723ff 1 1 17 46 100073b99fecd81b4fe113b10852065c15e75ed7d256d2d242b3cca57317c28c7fece4bda797f116309ea5bc2eb1 1 1 16 54 1800bd05672170b5d04cb62394498988f3844b744a0793ac435d044e67ed0ee50d20c408b30cec599c169378b0ad2a4967f42aef38e5 1 1 23 46 1000a1a515e0fe322980f319752bf85dd405ca2bdda148009654584b70f50d38c532df1c2d0a3c56f9758775b007 -1; princ 38 30 1 4 0 krbtgt/KRBTEST.COM@KRBTEST.COM 0 86400 0 0 0 0 0 0 2 28 b93e105164625f6372656174696f6e404b5242544553542e434f4d00 1 1 18 62 2000582c9aaf26c4a0abf13600baf37718c91e15dca02385e346cf5d2730d28b2302677f23d02791299548b45e1ced0b05cd30062617bff7532885d7889c 1 1 17 46 1000122eb47263d7837771ebbf7ad82163cc2ea7674a417944c0cbf186522fc0e74a73affd4a42fb9fda287be4f8 1 1 16 54 18008cd8064aea468f13f36ae13ecd4f993d87ef6bafcb2dc5101ad903200ffe3d5c265b2f0c71a6c07ec60d259b6862825cc77a70b2 1 1 23 46 10001699ad0304644456106328fbd733bd5c524f20d4b5d8b8e370eff196803b5990ee7e9eb4b6c2214cf327f59b -1; princ 38 18 4 0 0 nokeys@KRBTEST.COM 0 86400 0 0 0 0 0 0 3 24 12345c010000000000000000000000000000000200000000 2 27 d931dc51757365722f61646d696e404b5242544553542e434f4d00 8 2 0100 1 4 d931dc51 -1; princ 38 22 4 4 0 user/admin@KRBTEST.COM 0 86400 0 0 0 0 0 0 3 24 12345c010000000000000000000000000000000200000000 2 30 b93e105167687564736f6e2f61646d696e404b5242544553542e434f4d00 8 2 0100 1 4 b93e1051 1 1 18 62 20002db4cd2b0824c44a17cdbb2d180a1ec9956db35d74741826ed0d77eaef9abdb20c481d5ab9f511d5a3e6b8def443382f03d247568d81529e5dd17fae 1 1 17 46 100011d7cc3627468d565d398cffd735a3cc9d3705cd9846cede198c7d07f4e8209cd9192bc6c5f127169c00f373 1 1 16 54 18002bd9dc3388c90055844b3b4c5c2a814d73758f226d44d7dc5e35ef3b65e7d80cd604a4ef2a5769106818c3d813956bbad1813cb2 1 1 23 46 1000409681c3ff356fb7d28a9f71957c3465ea42ec4eee5019a662f7d367042527b76ae783cfbd0dccbd7529d090 -1; princ 38 16 4 4 0 user@KRBTEST.COM 0 86400 0 0 0 0 0 0 3 32 12345c010000000874657374706f6c0000000800000000000000000200000000 2 27 d73e1051757365722f61646d696e404b5242544553542e434f4d00 8 2 0100 1 4 b93e1051 1 1 18 62 2000aec451aae295389f92d177e61b5154941386c70d75d382393e556dfa61bd77d112a777420a99030b56649d366bba83a5c40aa17fa4522222d2e78e10 1 1 17 46 10009c8ab7b3f89ccf3ca3ad98352a461b7f4f1b0c495605117591d9ad52ba4da0adef7a902126973ed2bdc3ffbf 1 1 16 54 18002b87a46d6c4de954a316b5ce28a99886f2abb6b0307190e577b81171dfb7a067139835be8625bc36b0edaaed357609107d85d335 1 1 23 46 1000c01fcdb3050a2270f82dbafbe4c1adc868377bf7133ee7a1bcaf85817abe541beb8008b91c54b99e93d2e0f5 -1; policy testpol 0 0 1 3 1 0 0 0 0 krb5-1.16/src/tests/t_localauth.py0000755000704600001450000001525613211554426017014 0ustar ghudsonlibuuid#!/usr/bin/python from k5test import * # Unfortunately, we can't reliably test the k5login module. We can control # the directory where k5login files are read, but we can't suppress the UID # validity check, which might fail in some filesystems for a .k5login file # we create. conf = {'plugins': {'localauth': { 'disable': 'k5login'}}} realm = K5Realm(create_kdb=False, krb5_conf=conf) def test_an2ln(env, aname, result, msg): out = realm.run(['./localauth', aname], env=env) if out != result + '\n': fail(msg) def test_an2ln_err(env, aname, err, msg): realm.run(['./localauth', aname], env=env, expected_code=1, expected_msg=err) def test_userok(env, aname, lname, ok, msg): out = realm.run(['./localauth', aname, lname], env=env) if ((ok and out != 'yes\n') or (not ok and out != 'no\n')): fail(msg) # The default an2ln method works only in the default realm, and works # for a single-component principal or a two-component principal where # the second component is the default realm. test_an2ln(None, 'user@KRBTEST.COM', 'user', 'default rule 1') test_an2ln(None, 'user/KRBTEST.COM@KRBTEST.COM', 'user', 'default rule 2') test_an2ln_err(None, 'user/KRBTEST.COM/x@KRBTEST.COM', 'No translation', 'default rule (3)') test_an2ln_err(None, 'user/X@KRBTEST.COM', 'No translation', 'default rule comp mismatch') test_an2ln_err(None, 'user@X', 'No translation', 'default rule realm mismatch') # auth_to_local_names matches ignore the realm but are case-sensitive. conf_names1 = {'realms': {'$realm': {'auth_to_local_names': {'user': 'abcd'}}}} names1 = realm.special_env('names1', False, conf_names1) test_an2ln(names1, 'user@KRBTEST.COM', 'abcd', 'auth_to_local_names match') test_an2ln(names1, 'user@X', 'abcd', 'auth_to_local_names out-of-realm match') test_an2ln(names1, 'x@KRBTEST.COM', 'x', 'auth_to_local_names mismatch') test_an2ln(names1, 'User@KRBTEST.COM', 'User', 'auth_to_local_names case') # auth_to_local_names values must be in the default realm's section. conf_names2 = {'realms': {'X': {'auth_to_local_names': {'user': 'abcd'}}}} names2 = realm.special_env('names2', False, conf_names2) test_an2ln_err(names2, 'user@X', 'No translation', 'auth_to_local_names section mismatch') # Return a realm environment containing an auth_to_local value (or list). def a2l_realm(name, values): conf = {'realms': {'$realm': {'auth_to_local': values}}} return realm.special_env(name, False, conf) # Test explicit use of default method. auth1 = a2l_realm('auth1', 'DEFAULT') test_an2ln(auth1, 'user@KRBTEST.COM', 'user', 'default rule') # Test some invalid auth_to_local values. auth2 = a2l_realm('auth2', 'RULE') test_an2ln_err(auth2, 'user@X', 'Improper format', 'null rule') auth3 = a2l_realm('auth3', 'UNRECOGNIZED:stuff') test_an2ln_err(auth3, 'user@X', 'Improper format', 'null rule') # An empty rule has the default selection string (unparsed principal # without realm) and no match or substitutions. rule1 = a2l_realm('rule1', 'RULE:') test_an2ln(rule1, 'user@KRBTEST.COM', 'user', 'empty rule') test_an2ln(rule1, 'user@X', 'user', 'empty rule (foreign realm)') test_an2ln(rule1, 'a/b/c@X', 'a/b/c', 'empty rule (multi-component)') # Test explicit selection string. Also test that the default method # is suppressed when auth_to_local values are present. rule2 = a2l_realm('rule2', 'RULE:[2:$$0.$$2.$$1]') test_an2ln(rule2, 'aaron/burr@REALM', 'REALM.burr.aaron', 'selection string') test_an2ln_err(rule2, 'user@KRBTEST.COM', 'No translation', 'suppress default') # Test match string. rule3 = a2l_realm('rule3', 'RULE:(.*tail)') test_an2ln(rule3, 'withtail@X', 'withtail', 'rule match 1') test_an2ln(rule3, 'x/withtail@X', 'x/withtail', 'rule match 2') test_an2ln_err(rule3, 'tails@X', 'No translation', 'rule anchor mismatch') # Test substitutions. rule4 = a2l_realm('rule4', 'RULE:s/birds/bees/') test_an2ln(rule4, 'thebirdsbirdsbirds@X', 'thebeesbirdsbirds', 'subst 1') rule5 = a2l_realm('rule4', 'RULE:s/birds/bees/g s/bees/birds/') test_an2ln(rule4, 'the/birdsbirdsbirds@x', 'the/birdsbeesbees', 'subst 2') # Test a bunch of auth_to_local values and rule features in combination. combo = a2l_realm('combo', ['RULE:[1:$$1-$$0](fred.*)s/-/ /g', 'DEFAULT', 'RULE:[3:$$1](z.*z)']) test_an2ln(combo, 'fred@X', 'fred X', 'combo 1') test_an2ln(combo, 'fred-too@X', 'fred too X', 'combo 2') test_an2ln(combo, 'fred@KRBTEST.COM', 'fred KRBTEST.COM', 'combo 3') test_an2ln(combo, 'user@KRBTEST.COM', 'user', 'combo 4') test_an2ln(combo, 'zazz/b/c@X', 'zazz', 'combo 5') test_an2ln_err(combo, 'a/b@KRBTEST.COM', 'No translation', 'combo 6') # Test the an2ln userok method with the combo environment. test_userok(combo, 'fred@X', 'fred X', True, 'combo userok 1') test_userok(combo, 'user@KRBTEST.COM', 'user', True, 'combo userok 2') test_userok(combo, 'user@KRBTEST.COM', 'X', False, 'combo userok 3') test_userok(combo, 'a/b@KRBTEST.COM', 'a/b', False, 'combo userok 4') # Register the two test modules and set up some auth_to_local and # auth_to_local_names entries. modpath = os.path.join(buildtop, 'plugins', 'localauth', 'test', 'localauth_test.so') conf = {'plugins': {'localauth': { 'module': [ 'test1:' + modpath, 'test2:' + modpath]}}, 'realms': {'$realm': {'auth_to_local': [ 'RULE:(test/rulefirst)s/.*/rule/', 'TYPEA', 'DEFAULT', 'TYPEB:resid']}, 'auth_to_local_names': {'test/a/b': 'name'}}} mod = realm.special_env('mod', False, conf) # test1's untyped an2ln method should come before the names method, mapping # test/a/b@X to its realm name (superceding auth_to_local_names). test_an2ln(mod, 'test/a/b@X', 'X', 'mod untyped an2ln') # Match the auth_to_local values in order. test2's TYPEA should map # test/notrule to its second component, and its TYPEB should map # anything which gets there to the residual string. test_an2ln(mod, 'test/rulefirst@X', 'rule', 'mod auth_to_local 1') test_an2ln(mod, 'test/notrule', 'notrule', 'mod auth_to_local 2') test_an2ln(mod, 'user@KRBTEST.COM', 'user', 'mod auth_to_local 3') test_an2ln(mod, 'xyz@X', 'resid', 'mod auth_to_local 4') # test2's userok module should succeed when the number of components # is equal to the length of the local name, should pass if the first # component is 'pass', and should reject otherwise. test_userok(mod, 'a/b/c/d@X', 'four', True, 'mod userok 1') test_userok(mod, 'x/y/z@X', 'four', False, 'mod userok 2') test_userok(mod, 'pass@KRBTEST.COM', 'pass', True, 'mod userok 3') test_userok(mod, 'user@KRBTEST.COM', 'user', False, 'mod userok 4') success('krb5_kuserok and krb5_aname_to_localname tests') krb5-1.16/src/tests/t_kadm5_auth.py0000644000704600001450000000740113211554426017050 0ustar ghudsonlibuuid#!/usr/bin/python from k5test import * # Create a realm with the welcomer and bouncer kadm5_auth test modules # in place of the builtin modules. modpath = os.path.join(buildtop, 'plugins', 'kadm5_auth', 'test', 'kadm5_auth_test.so') conf = {'plugins': {'kadm5_auth': {'module': ['welcomer:' + modpath, 'bouncer:' + modpath], 'enable_only': ['welcomer', 'bouncer']}}} realm = K5Realm(krb5_conf=conf, create_host=False) realm.start_kadmind() realm.prep_kadmin() # addprinc: welcomer accepts with policy VIP, bouncer denies maxlife. realm.run_kadmin(['addprinc', '-randkey', 'princ'], expected_code=1) realm.run_kadmin(['addprinc', '-randkey', '-policy', 'VIP', 'princ']) realm.run_kadmin(['addprinc', '-randkey', '-policy', 'VIP', '-maxlife', '3', 'princ'], expected_code=1) # modprinc: welcomer accepts with only maxrenewlife, bouncer denies # with even-component target principal. realm.run_kadmin(['modprinc', '-maxlife', '3', 'princ'], expected_code=1) realm.run_kadmin(['modprinc', '-maxrenewlife', '3', 'princ']) realm.run_kadmin(['modprinc', '-maxrenewlife', '3', 'user/admin'], expected_code=1) # setstr: welcomer accepts with key 'note', bouncer denies with value # length > 10. realm.run_kadmin(['setstr', 'princ', 'somekey', 'someval'], expected_code=1) realm.run_kadmin(['setstr', 'princ', 'note', 'abc']) realm.run_kadmin(['setstr', 'princ', 'note', 'abcdefghijkl'], expected_code=1) # delprinc: welcomer accepts with target principal beginning with 'd', # bouncer denies with "nodelete" string attribute. realm.run_kadmin(['delprinc', 'user'], expected_code=1) realm.run([kadminl, 'addprinc', '-randkey', 'deltest']) realm.run_kadmin(['delprinc', 'deltest']) realm.run([kadminl, 'addprinc', '-randkey', 'deltest']) realm.run([kadminl, 'setstr', 'deltest', 'nodelete', 'yes']) realm.run_kadmin(['delprinc', 'deltest'], expected_code=1) # renprinc: welcomer accepts with same-length first components, bouncer # refuses with source principal beginning with 'a'. realm.run_kadmin(['renprinc', 'princ', 'xyz'], expected_code=1) realm.run_kadmin(['renprinc', 'princ', 'abcde']) realm.run_kadmin(['renprinc', 'abcde', 'fghij'], expected_code=1) # addpol: welcomer accepts with minlength 3, bouncer denies with name # length <= 3. realm.run_kadmin(['addpol', 'testpol'], expected_code=1) realm.run_kadmin(['addpol', '-minlength', '3', 'testpol']) realm.run_kadmin(['addpol', '-minlength', '3', 'abc'], expected_code=1) # modpol: welcomer accepts changes to minlife, bouncer denies with # minlife > 10. realm.run_kadmin(['modpol', '-minlength', '4', 'testpol'], expected_code=1) realm.run_kadmin(['modpol', '-minlife', '8', 'testpol']) realm.run_kadmin(['modpol', '-minlife', '11', 'testpol'], expected_code=1) # getpol: welcomer accepts if policy and client policy have same length, # bouncer denies if policy name begins with 'x'. realm.run([kadminl, 'addpol', 'aaaa']) realm.run([kadminl, 'addpol', 'bbbb']) realm.run([kadminl, 'addpol', 'xxxx']) realm.run([kadminl, 'modprinc', '-policy', 'aaaa', 'user/admin']) realm.run_kadmin(['getpol', 'testpol'], expected_code=1) realm.run_kadmin(['getpol', 'bbbb']) realm.run_kadmin(['getpol', 'xxxx'], expected_code=1) # end: welcomer counts operations using "ends" string attribute on # "opcount" principal. kadmind is dumb and invokes the end method for # every RPC operation including init, so we expect four calls to the # end operation. realm.run([kadminl, 'addprinc', '-nokey', 'opcount']) realm.run([kadminl, 'setstr', 'opcount', 'ends', '0']) realm.run_kadmin(['getprinc', 'user']) realm.run_kadmin(['getpol', 'bbbb']) realm.run([kadminl, 'getstrs', 'opcount'], expected_msg='ends: 4') success('kadm5_auth pluggable interface tests') krb5-1.16/src/tests/t_iprop.py0000755000704600001450000004653513211554426016175 0ustar ghudsonlibuuid#!/usr/bin/python import os import re from k5test import * # Read lines from kpropd output until we are synchronized. Error if # full_expected is true and we didn't see a full propagation or vice # versa. def wait_for_prop(kpropd, full_expected, expected_old, expected_new): output('*** Waiting for sync from kpropd\n') full_seen = sleep_seen = False old_sno = new_sno = -1 while True: line = kpropd.stdout.readline() if line == '': fail('kpropd process exited unexpectedly') output('kpropd: ' + line) m = re.match(r'Calling iprop_get_updates_1 \(sno=(\d+) ', line) if m: if not full_seen: old_sno = int(m.group(1)) # Also record this as the new sno, in case we get back # UPDATE_NIL. new_sno = int(m.group(1)) m = re.match(r'Got incremental updates \(sno=(\d+) ', line) if m: new_sno = int(m.group(1)) if 'KDC is synchronized' in line or 'Incremental updates:' in line: break # After a full resync request, these lines could appear in # either order. if 'Waiting for' in line: sleep_seen = True if 'load process for full propagation completed' in line: full_seen = True # Detect some failure conditions. if 'Still waiting for full resync' in line: fail('kadmind gave consecutive full resyncs') if 'Rejected connection' in line: fail('kpropd rejected kprop connection') if 'get updates failed' in line: fail('iprop_get_updates failed') if 'permission denied' in line: fail('kadmind denied update') if 'error from master' in line or 'error returned from master' in line: fail('kadmind reported error') if 'invalid return' in line: fail('kadmind returned invalid result') if full_expected and not full_seen: fail('Expected full dump but saw only incremental') if full_seen and not full_expected: fail('Expected incremental prop but saw full dump') if old_sno != expected_old: fail('Expected old serial %d from kpropd sync' % expected_old) if new_sno != expected_new: fail('Expected new serial %d from kpropd sync' % expected_new) # Wait until kpropd is sleeping before continuing, to avoid races. # (This is imperfect since there's there is a short window between # the fprintf and the sleep; kpropd will need design changes to # fix that.) while True: line = kpropd.stdout.readline() output('kpropd: ' + line) if 'Waiting for' in line: break output('*** Sync complete\n') # Verify the output of kproplog against the expected number of # entries, first and last serial number, and a list of principal names # for the update entrires. def check_ulog(num, first, last, entries, env=None): out = realm.run([kproplog], env=env) if 'Number of entries : ' + str(num) + '\n' not in out: fail('Expected %d entries' % num) if last: firststr = first and str(first) or 'None' if 'First serial # : ' + firststr + '\n' not in out: fail('Expected first serial number %d' % first) laststr = last and str(last) or 'None' if 'Last serial # : ' + laststr + '\n' not in out: fail('Expected last serial number %d' % last) assert(len(entries) == num) ser = first - 1 entindex = 0 for line in out.splitlines(): m = re.match(r'\tUpdate serial # : (\d+)$', line) if m: ser = ser + 1 if m.group(1) != str(ser): fail('Expected serial number %d in update entry' % ser) m = re.match(r'\tUpdate principal : (.*)$', line) if m: eprinc = entries[ser - first] if eprinc == None: fail('Expected dummy update entry %d' % ser) elif m.group(1) != eprinc: fail('Expected princ %s in update entry %d' % (eprinc, ser)) if line == '\tDummy entry': eprinc = entries[ser - first] if eprinc != None: fail('Expected princ %s in update entry %d' % (eprinc, ser)) # slave1 will receive updates from master, and slave2 will receive # updates from slave1. Because of the awkward way iprop and kprop # port configuration currently works, we need separate config files # for the slave and master sides of slave1, but they use the same DB # and ulog file. conf = {'realms': {'$realm': {'iprop_enable': 'true', 'iprop_logfile': '$testdir/db.ulog'}}} conf_slave1 = {'realms': {'$realm': {'iprop_slave_poll': '600', 'iprop_logfile': '$testdir/ulog.slave1'}}, 'dbmodules': {'db': {'database_name': '$testdir/db.slave1'}}} conf_slave1m = {'realms': {'$realm': {'iprop_logfile': '$testdir/ulog.slave1', 'iprop_port': '$port8'}}, 'dbmodules': {'db': {'database_name': '$testdir/db.slave1'}}} conf_slave2 = {'realms': {'$realm': {'iprop_slave_poll': '600', 'iprop_logfile': '$testdir/ulog.slave2', 'iprop_port': '$port8'}}, 'dbmodules': {'db': {'database_name': '$testdir/db.slave2'}}} conf_foo = {'libdefaults': {'default_realm': 'FOO'}, 'domain_realm': {hostname: 'FOO'}} realm = K5Realm(kdc_conf=conf, create_user=False, start_kadmind=True) slave1 = realm.special_env('slave1', True, kdc_conf=conf_slave1) slave1m = realm.special_env('slave1m', True, krb5_conf=conf_foo, kdc_conf=conf_slave1m) slave2 = realm.special_env('slave2', True, kdc_conf=conf_slave2) # A default_realm and domain_realm that do not match the KDC's realm. # The FOO realm iprop_logfile setting is needed to run kproplog during # a slave3 test, since kproplog has no realm option. conf_slave3 = {'realms': {'$realm': {'iprop_slave_poll': '600', 'iprop_logfile': '$testdir/ulog.slave3', 'iprop_port': '$port8'}, 'FOO': {'iprop_logfile': '$testdir/ulog.slave3'}}, 'dbmodules': {'db': {'database_name': '$testdir/db.slave3'}}} slave3 = realm.special_env('slave3', True, krb5_conf=conf_foo, kdc_conf=conf_slave3) # A default realm and a domain realm map that differ. krb5_conf_slave4 = {'domain_realm': {hostname: 'FOO'}} conf_slave4 = {'realms': {'$realm': {'iprop_slave_poll': '600', 'iprop_logfile': '$testdir/ulog.slave4', 'iprop_port': '$port8'}}, 'dbmodules': {'db': {'database_name': '$testdir/db.slave4'}}} slave4 = realm.special_env('slave4', True, krb5_conf=krb5_conf_slave4, kdc_conf=conf_slave4) # Define some principal names. pr3 is long enough to cause internal # reallocs, but not long enough to grow the basic ulog entry size. pr1 = 'wakawaka@' + realm.realm pr2 = 'w@' + realm.realm c = 'chocolate-flavored-school-bus' cs = c + '/' pr3 = (cs + cs + cs + cs + cs + cs + cs + cs + cs + cs + cs + cs + c + '@' + realm.realm) # Create the kpropd ACL file. acl_file = os.path.join(realm.testdir, 'kpropd-acl') acl = open(acl_file, 'w') acl.write(realm.host_princ + '\n') acl.close() ulog = os.path.join(realm.testdir, 'db.ulog') if not os.path.exists(ulog): fail('update log not created: ' + ulog) # Create the principal used to authenticate kpropd to kadmind. kiprop_princ = 'kiprop/' + hostname realm.extract_keytab(kiprop_princ, realm.keytab) # Create the initial slave databases. dumpfile = os.path.join(realm.testdir, 'dump') realm.run([kdb5_util, 'dump', dumpfile]) realm.run([kdb5_util, 'load', dumpfile], slave1) realm.run([kdb5_util, 'load', dumpfile], slave2) realm.run([kdb5_util, '-r', realm.realm, 'load', dumpfile], slave3) realm.run([kdb5_util, 'load', dumpfile], slave4) # Reinitialize the master ulog so we know exactly what to expect in # it. realm.run([kproplog, '-R']) check_ulog(1, 1, 1, [None]) # Make some changes to the master DB. realm.addprinc(pr1) realm.addprinc(pr3) realm.addprinc(pr2) realm.run([kadminl, 'modprinc', '-allow_tix', pr2]) realm.run([kadminl, 'modprinc', '+allow_tix', pr2]) check_ulog(6, 1, 6, [None, pr1, pr3, pr2, pr2, pr2]) # Start kpropd for slave1 and get a full dump from master. kpropd1 = realm.start_kpropd(slave1, ['-d']) wait_for_prop(kpropd1, True, 1, 6) out = realm.run([kadminl, 'listprincs'], env=slave1) if pr1 not in out or pr2 not in out or pr3 not in out: fail('slave1 does not have all principals from master') check_ulog(1, 6, 6, [None], slave1) # Make a change and check that it propagates incrementally. realm.run([kadminl, 'modprinc', '-allow_tix', pr2]) check_ulog(7, 1, 7, [None, pr1, pr3, pr2, pr2, pr2, pr2]) kpropd1.send_signal(signal.SIGUSR1) wait_for_prop(kpropd1, False, 6, 7) check_ulog(2, 6, 7, [None, pr2], slave1) realm.run([kadminl, 'getprinc', pr2], env=slave1, expected_msg='Attributes: DISALLOW_ALL_TIX') # Start kadmind -proponly for slave1. (Use the slave1m environment # which defines iprop_port to $port8.) slave1_out_dump_path = os.path.join(realm.testdir, 'dump.slave1.out') slave2_in_dump_path = os.path.join(realm.testdir, 'dump.slave2.in') slave2_kprop_port = str(realm.portbase + 9) realm.start_server([kadmind, '-r', realm.realm, '-nofork', '-proponly', '-W', '-p', kdb5_util, '-K', kprop, '-k', slave2_kprop_port, '-F', slave1_out_dump_path], 'starting...', slave1m) # Test similar default_realm and domain_realm map settings with -r realm. slave3_in_dump_path = os.path.join(realm.testdir, 'dump.slave3.in') kpropd3 = realm.start_server([kpropd, '-d', '-D', '-r', realm.realm, '-P', slave2_kprop_port, '-f', slave3_in_dump_path, '-p', kdb5_util, '-a', acl_file, '-A', hostname], 'ready', slave3) wait_for_prop(kpropd3, True, 1, 7) out = realm.run([kadminl, '-r', realm.realm, 'listprincs'], env=slave3) if pr1 not in out or pr2 not in out or pr3 not in out: fail('slave3 does not have all principals from slave1') check_ulog(1, 7, 7, [None], env=slave3) # Test an incremental propagation for the kpropd -r case. realm.run([kadminl, 'modprinc', '-maxlife', '20 minutes', pr1]) check_ulog(8, 1, 8, [None, pr1, pr3, pr2, pr2, pr2, pr2, pr1]) kpropd1.send_signal(signal.SIGUSR1) wait_for_prop(kpropd1, False, 7, 8) check_ulog(3, 6, 8, [None, pr2, pr1], slave1) realm.run([kadminl, 'getprinc', pr1], env=slave1, expected_msg='Maximum ticket life: 0 days 00:20:00') kpropd3.send_signal(signal.SIGUSR1) wait_for_prop(kpropd3, False, 7, 8) check_ulog(2, 7, 8, [None, pr1], slave3) realm.run([kadminl, '-r', realm.realm, 'getprinc', pr1], env=slave3, expected_msg='Maximum ticket life: 0 days 00:20:00') stop_daemon(kpropd3) # Test dissimilar default_realm and domain_realm map settings (no -r realm). slave4_in_dump_path = os.path.join(realm.testdir, 'dump.slave4.in') kpropd4 = realm.start_server([kpropd, '-d', '-D', '-P', slave2_kprop_port, '-f', slave4_in_dump_path, '-p', kdb5_util, '-a', acl_file, '-A', hostname], 'ready', slave4) wait_for_prop(kpropd4, True, 1, 8) out = realm.run([kadminl, 'listprincs'], env=slave4) if pr1 not in out or pr2 not in out or pr3 not in out: fail('slave4 does not have all principals from slave1') stop_daemon(kpropd4) # Start kpropd for slave2. The -A option isn't needed since we're # talking to the same host as master (we specify it anyway to exercise # the code), but slave2 defines iprop_port to $port8 so it will talk # to slave1. Get a full dump from slave1. kpropd2 = realm.start_server([kpropd, '-d', '-D', '-P', slave2_kprop_port, '-f', slave2_in_dump_path, '-p', kdb5_util, '-a', acl_file, '-A', hostname], 'ready', slave2) wait_for_prop(kpropd2, True, 1, 8) check_ulog(2, 7, 8, [None, pr1], slave2) out = realm.run([kadminl, 'listprincs'], env=slave1) if pr1 not in out or pr2 not in out or pr3 not in out: fail('slave2 does not have all principals from slave1') # Make another change and check that it propagates incrementally to # both slaves. realm.run([kadminl, 'modprinc', '-maxrenewlife', '22 hours', pr1]) check_ulog(9, 1, 9, [None, pr1, pr3, pr2, pr2, pr2, pr2, pr1, pr1]) kpropd1.send_signal(signal.SIGUSR1) wait_for_prop(kpropd1, False, 8, 9) check_ulog(4, 6, 9, [None, pr2, pr1, pr1], slave1) realm.run([kadminl, 'getprinc', pr1], env=slave1, expected_msg='Maximum renewable life: 0 days 22:00:00\n') kpropd2.send_signal(signal.SIGUSR1) wait_for_prop(kpropd2, False, 8, 9) check_ulog(3, 7, 9, [None, pr1, pr1], slave2) realm.run([kadminl, 'getprinc', pr1], env=slave2, expected_msg='Maximum renewable life: 0 days 22:00:00\n') # Reset the ulog on slave1 to force a full resync from master. The # resync will use the old dump file and then propagate changes. # slave2 should still be in sync with slave1 after the resync, so make # sure it doesn't take a full resync. realm.run([kproplog, '-R'], slave1) check_ulog(1, 1, 1, [None], slave1) kpropd1.send_signal(signal.SIGUSR1) wait_for_prop(kpropd1, True, 1, 9) check_ulog(4, 6, 9, [None, pr2, pr1, pr1], slave1) kpropd2.send_signal(signal.SIGUSR1) wait_for_prop(kpropd2, False, 9, 9) check_ulog(3, 7, 9, [None, pr1, pr1], slave2) # Make another change and check that it propagates incrementally to # both slaves. realm.run([kadminl, 'modprinc', '+allow_tix', pr2]) check_ulog(10, 1, 10, [None, pr1, pr3, pr2, pr2, pr2, pr2, pr1, pr1, pr2]) kpropd1.send_signal(signal.SIGUSR1) wait_for_prop(kpropd1, False, 9, 10) check_ulog(5, 6, 10, [None, pr2, pr1, pr1, pr2], slave1) realm.run([kadminl, 'getprinc', pr2], env=slave1, expected_msg='Attributes:\n') kpropd2.send_signal(signal.SIGUSR1) wait_for_prop(kpropd2, False, 9, 10) check_ulog(4, 7, 10, [None, pr1, pr1, pr2], slave2) realm.run([kadminl, 'getprinc', pr2], env=slave2, expected_msg='Attributes:\n') # Create a policy and check that it propagates via full resync. realm.run([kadminl, 'addpol', '-minclasses', '2', 'testpol']) check_ulog(1, 1, 1, [None]) kpropd1.send_signal(signal.SIGUSR1) wait_for_prop(kpropd1, True, 10, 1) check_ulog(1, 1, 1, [None], slave1) realm.run([kadminl, 'getpol', 'testpol'], env=slave1, expected_msg='Minimum number of password character classes: 2') kpropd2.send_signal(signal.SIGUSR1) wait_for_prop(kpropd2, True, 10, 1) check_ulog(1, 1, 1, [None], slave2) realm.run([kadminl, 'getpol', 'testpol'], env=slave2, expected_msg='Minimum number of password character classes: 2') # Modify the policy and test that it also propagates via full resync. realm.run([kadminl, 'modpol', '-minlength', '17', 'testpol']) check_ulog(1, 1, 1, [None]) kpropd1.send_signal(signal.SIGUSR1) wait_for_prop(kpropd1, True, 1, 1) check_ulog(1, 1, 1, [None], slave1) realm.run([kadminl, 'getpol', 'testpol'], env=slave1, expected_msg='Minimum password length: 17') kpropd2.send_signal(signal.SIGUSR1) wait_for_prop(kpropd2, True, 1, 1) check_ulog(1, 1, 1, [None], slave2) realm.run([kadminl, 'getpol', 'testpol'], env=slave2, expected_msg='Minimum password length: 17') # Delete the policy and test that it propagates via full resync. realm.run([kadminl, 'delpol', 'testpol']) check_ulog(1, 1, 1, [None]) kpropd1.send_signal(signal.SIGUSR1) wait_for_prop(kpropd1, True, 1, 1) check_ulog(1, 1, 1, [None], slave1) realm.run([kadminl, 'getpol', 'testpol'], env=slave1, expected_code=1, expected_msg='Policy does not exist') kpropd2.send_signal(signal.SIGUSR1) wait_for_prop(kpropd2, True, 1, 1) check_ulog(1, 1, 1, [None], slave2) realm.run([kadminl, 'getpol', 'testpol'], env=slave2, expected_code=1, expected_msg='Policy does not exist') # Modify a principal on the master and test that it propagates incrementally. realm.run([kadminl, 'modprinc', '-maxlife', '10 minutes', pr1]) check_ulog(2, 1, 2, [None, pr1]) kpropd1.send_signal(signal.SIGUSR1) wait_for_prop(kpropd1, False, 1, 2) check_ulog(2, 1, 2, [None, pr1], slave1) realm.run([kadminl, 'getprinc', pr1], env=slave1, expected_msg='Maximum ticket life: 0 days 00:10:00') kpropd2.send_signal(signal.SIGUSR1) wait_for_prop(kpropd2, False, 1, 2) check_ulog(2, 1, 2, [None, pr1], slave2) realm.run([kadminl, 'getprinc', pr1], env=slave2, expected_msg='Maximum ticket life: 0 days 00:10:00') # Delete a principal and test that it propagates incrementally. realm.run([kadminl, 'delprinc', pr3]) check_ulog(3, 1, 3, [None, pr1, pr3]) kpropd1.send_signal(signal.SIGUSR1) wait_for_prop(kpropd1, False, 2, 3) check_ulog(3, 1, 3, [None, pr1, pr3], slave1) realm.run([kadminl, 'getprinc', pr3], env=slave1, expected_code=1, expected_msg='Principal does not exist') kpropd2.send_signal(signal.SIGUSR1) wait_for_prop(kpropd2, False, 2, 3) check_ulog(3, 1, 3, [None, pr1, pr3], slave2) realm.run([kadminl, 'getprinc', pr3], env=slave2, expected_code=1, expected_msg='Principal does not exist') # Rename a principal and test that it propagates incrementally. renpr = "quacked@" + realm.realm realm.run([kadminl, 'renprinc', pr1, renpr]) check_ulog(6, 1, 6, [None, pr1, pr3, renpr, pr1, renpr]) kpropd1.send_signal(signal.SIGUSR1) wait_for_prop(kpropd1, False, 3, 6) check_ulog(6, 1, 6, [None, pr1, pr3, renpr, pr1, renpr], slave1) realm.run([kadminl, 'getprinc', pr1], env=slave1, expected_code=1, expected_msg='Principal does not exist') realm.run([kadminl, 'getprinc', renpr], env=slave1) kpropd2.send_signal(signal.SIGUSR1) wait_for_prop(kpropd2, False, 3, 6) check_ulog(6, 1, 6, [None, pr1, pr3, renpr, pr1, renpr], slave2) realm.run([kadminl, 'getprinc', pr1], env=slave2, expected_code=1, expected_msg='Principal does not exist') realm.run([kadminl, 'getprinc', renpr], env=slave2) pr1 = renpr # Reset the ulog on the master to force a full resync. realm.run([kproplog, '-R']) check_ulog(1, 1, 1, [None]) kpropd1.send_signal(signal.SIGUSR1) wait_for_prop(kpropd1, True, 6, 1) check_ulog(1, 1, 1, [None], slave1) kpropd2.send_signal(signal.SIGUSR1) wait_for_prop(kpropd2, True, 6, 1) check_ulog(1, 1, 1, [None], slave2) # Stop the kprop daemons so we can test kpropd -t. stop_daemon(kpropd1) stop_daemon(kpropd2) # Test the case where no updates are needed. out = realm.run_kpropd_once(slave1, ['-d']) if 'KDC is synchronized' not in out: fail('Expected synchronized from kpropd -t') check_ulog(1, 1, 1, [None], slave1) # Make a change on the master and fetch it incrementally. realm.run([kadminl, 'modprinc', '-maxlife', '5 minutes', pr1]) check_ulog(2, 1, 2, [None, pr1]) out = realm.run_kpropd_once(slave1, ['-d']) if 'Got incremental updates (sno=2 ' not in out: fail('Expected full dump and synchronized from kpropd -t') check_ulog(2, 1, 2, [None, pr1], slave1) realm.run([kadminl, 'getprinc', pr1], env=slave1, expected_msg='Maximum ticket life: 0 days 00:05:00') # Propagate a policy change via full resync. realm.run([kadminl, 'addpol', '-minclasses', '3', 'testpol']) check_ulog(1, 1, 1, [None]) out = realm.run_kpropd_once(slave1, ['-d']) if ('Full propagation transfer finished' not in out or 'KDC is synchronized' not in out): fail('Expected full dump and synchronized from kpropd -t') check_ulog(1, 1, 1, [None], slave1) realm.run([kadminl, 'getpol', 'testpol'], env=slave1, expected_msg='Minimum number of password character classes: 3') success('iprop tests') krb5-1.16/src/tests/resolve/0000755000704600001450000000000013211554426015606 5ustar ghudsonlibuuidkrb5-1.16/src/tests/resolve/fake-addrinfo-test.c0000644000704600001450000000016513211554426021423 0ustar ghudsonlibuuid/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ #define USE_FAKE_ADDRINFO #include "addrinfo-test.c" krb5-1.16/src/tests/resolve/resolve.c0000644000704600001450000001032013211554426017425 0ustar ghudsonlibuuid/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* tests/resolve/resolve.c */ /* * Copyright 1995 by the Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ /* * A simple program to test the functionality of the resolver library. * It simply will try to get the IP address of the host, and then look * up the name from the address. If the resulting name does not contain the * domain name, then the resolve library is broken. * * Warning: It is possible to fool this program into thinking everything is * alright by a clever use of /etc/hosts - but this is better than nothing. * * Usage: * resolve [hostname] * * When invoked with no arguments, gethostname is used for the local host. * */ /* This program tests the resolve library and sees if it is broken... */ #include "autoconf.h" #include #if STDC_HEADERS #include #else #ifndef HAVE_STRCHR #define strchr index #endif char *strchr(); #endif #ifdef HAVE_SYS_PARAM_H #include #endif #ifdef HAVE_SYS_SOCKET_H #include #endif #ifdef HAVE_STDLIB_H #include #endif #ifdef HAVE_UNISTD_H #include #endif #include #include int main(argc, argv) int argc; char **argv; { char myname[MAXHOSTNAMELEN+1]; char *ptr, *fqdn; struct in_addr addrcopy; struct hostent *host; int quiet = 0; argc--; argv++; while (argc) { if ((strcmp(*argv, "--quiet") == 0) || (strcmp(*argv, "-q") == 0)) { quiet++; } else break; argc--; argv++; } if (argc >= 1) { strncpy(myname, *argv, MAXHOSTNAMELEN); } else { if(gethostname(myname, MAXHOSTNAMELEN)) { perror("gethostname failure"); exit(1); } } myname[MAXHOSTNAMELEN] = '\0'; /* for safety */ /* Look up the address... */ if (!quiet) printf("Hostname: %s\n", myname); /* Set the hosts db to close each time - effectively rewinding file */ sethostent(0); if((host = gethostbyname (myname)) == NULL) { fprintf(stderr, "Could not look up address for hostname '%s' - fatal\n", myname); exit(2); } fqdn = strdup(host->h_name); if (fqdn == NULL) { perror("strdup"); exit(2); } ptr = host->h_addr_list[0]; #define UC(a) (((int)a)&0xff) if (!quiet) printf("Host address: %d.%d.%d.%d\n", UC(ptr[0]), UC(ptr[1]), UC(ptr[2]), UC(ptr[3])); memcpy(&addrcopy.s_addr, ptr, 4); /* Convert back to full name */ if ((host = gethostbyaddr(&addrcopy.s_addr, 4, AF_INET)) == NULL) { if (!quiet) fprintf(stderr, "Error looking up IP address\n"); } else { free(fqdn); fqdn = strdup(host->h_name); if (fqdn == NULL) { perror("strdup"); exit (2); } } if (quiet) printf("%s\n", fqdn); else printf("FQDN: %s\n", fqdn); if (!quiet) printf("Resolve library appears to have passed the test\n"); /* All ok */ exit(0); } krb5-1.16/src/tests/resolve/deps0000644000704600001450000000110713211554426016463 0ustar ghudsonlibuuid# # Generated makefile dependencies follow. # $(OUTPRE)resolve.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ resolve.c $(OUTPRE)addrinfo-test.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-thread.h \ addrinfo-test.c $(OUTPRE)fake-addrinfo-test.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(top_srcdir)/include/fake-addrinfo.h $(top_srcdir)/include/k5-platform.h \ $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/port-sockets.h \ $(top_srcdir)/include/socket-utils.h addrinfo-test.c \ fake-addrinfo-test.c krb5-1.16/src/tests/resolve/addrinfo-test.c0000644000704600001450000002233013211554426020515 0ustar ghudsonlibuuid/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* tests/resolve/addrinfo-test.c */ /* * Copyright 2004 by the Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ /* * A simple program to test the functionality of the getaddrinfo function. * * Usage: * addrinfo-test [-t|-u|-R|-I] [-d|-s|-r] [-p port] [-P] [hostname] * * When invoked with no arguments, NULL is used for the node name, * which (at least with a non-null "port") means a socket address * is desired that can be used with connect() or bind() (depending * on whether "-P" is given). */ #include #include #include #include #include /* needed for IPPROTO_* on NetBSD */ #ifdef USE_FAKE_ADDRINFO #include "fake-addrinfo.h" #endif static const char *protoname (int p) { static char buf[30]; #define X(N) if (p == IPPROTO_ ## N) return #N X(TCP); X(UDP); X(ICMP); #ifdef IPPROTO_IPV6 X(IPV6); #endif #ifdef IPPROTO_GRE X(GRE); #endif #ifdef IPPROTO_NONE X(NONE); #endif X(RAW); #ifdef IPPROTO_COMP X(COMP); #endif snprintf(buf, sizeof(buf), " %-2d", p); return buf; } static const char *socktypename (int t) { static char buf[30]; switch (t) { case SOCK_DGRAM: return "DGRAM"; case SOCK_STREAM: return "STREAM"; case SOCK_RAW: return "RAW"; case SOCK_RDM: return "RDM"; case SOCK_SEQPACKET: return "SEQPACKET"; } snprintf(buf, sizeof(buf), " %-2d", t); return buf; } static char *whoami; static void usage () { fprintf(stderr, "usage:\n" "\t%s [ options ] [host]\n" "options:\n" "\t-t\tspecify protocol IPPROTO_TCP\n" "\t-u\tspecify protocol IPPROTO_UDP\n" "\t-R\tspecify protocol IPPROTO_RAW\n" "\t-I\tspecify protocol IPPROTO_ICMP\n" "\n" "\t-d\tspecify socket type SOCK_DGRAM\n" "\t-s\tspecify socket type SOCK_STREAM\n" "\t-r\tspecify socket type SOCK_RAW\n" "\n" "\t-4\tspecify address family AF_INET\n" #ifdef AF_INET6 "\t-6\tspecify address family AF_INET6\n" #endif "\n" "\t-p P\tspecify port P (service name or port number)\n" "\t-N\thostname is numeric, skip DNS query\n" "\t-n\tservice/port is numeric (sets AI_NUMERICSERV)\n" "\t-P\tset AI_PASSIVE\n" "\n" "default: protocol 0, socket type 0, address family 0, null port\n" , whoami); /* [ -t | -u | -R | -I ] [ -d | -s | -r ] [ -p port ] */ exit (1); } static const char *familyname (int f) { static char buf[30]; switch (f) { default: snprintf(buf, sizeof(buf), "AF %d", f); return buf; case AF_INET: return "AF_INET"; #ifdef AF_INET6 case AF_INET6: return "AF_INET6"; #endif } } #define eaistr(X) (X == EAI_SYSTEM ? strerror(errno) : gai_strerror(X)) int main (int argc, char *argv[]) { struct addrinfo *ap, *ap2; int err, numerichost = 0, numericserv = 0; char *hname, *port = 0, *sep; struct addrinfo hints; whoami = strrchr(argv[0], '/'); if (whoami == 0) whoami = argv[0]; else whoami = whoami+1; memset(&hints, 0, sizeof(hints)); hints.ai_flags = 0; hints.ai_socktype = 0; hname = 0; hints.ai_family = 0; if (argc == 1) usage (); while (++argv, --argc > 0) { char *arg; arg = *argv; if (*arg != '-') hname = arg; else if (arg[1] == 0 || arg[2] != 0) usage (); else switch (arg[1]) { case 'u': hints.ai_protocol = IPPROTO_UDP; break; case 't': hints.ai_protocol = IPPROTO_TCP; break; case 'R': hints.ai_protocol = IPPROTO_RAW; break; case 'I': hints.ai_protocol = IPPROTO_ICMP; break; case 'd': hints.ai_socktype = SOCK_DGRAM; break; case 's': hints.ai_socktype = SOCK_STREAM; break; case 'r': hints.ai_socktype = SOCK_RAW; break; case 'p': if (argv[1] == 0 || argv[1][0] == 0 || argv[1][0] == '-') usage (); port = argv[1]; argc--, argv++; break; case '4': hints.ai_family = AF_INET; break; #ifdef AF_INET6 case '6': hints.ai_family = AF_INET6; break; #endif case 'N': numerichost = 1; break; case 'n': numericserv = 1; break; case 'P': hints.ai_flags |= AI_PASSIVE; break; default: usage (); } } if (hname && !numerichost) hints.ai_flags |= AI_CANONNAME; if (numerichost) { #ifdef AI_NUMERICHOST hints.ai_flags |= AI_NUMERICHOST; #else fprintf(stderr, "AI_NUMERICHOST not defined on this platform\n"); exit(1); #endif } if (numericserv) { #ifdef AI_NUMERICSERV hints.ai_flags |= AI_NUMERICSERV; #else fprintf(stderr, "AI_NUMERICSERV not defined on this platform\n"); exit(1); #endif } printf("getaddrinfo(hostname %s, service %s,\n" " hints { ", hname ? hname : "(null)", port ? port : "(null)"); sep = ""; #define Z(FLAG) if (hints.ai_flags & AI_##FLAG) printf("%s%s", sep, #FLAG), sep = "|" Z(CANONNAME); Z(PASSIVE); #ifdef AI_NUMERICHOST Z(NUMERICHOST); #endif #ifdef AI_NUMERICSERV Z(NUMERICSERV); #endif if (sep[0] == 0) printf ("no-flags"); if (hints.ai_family) printf(" %s", familyname(hints.ai_family)); if (hints.ai_socktype) printf(" SOCK_%s", socktypename(hints.ai_socktype)); if (hints.ai_protocol) printf(" IPPROTO_%s", protoname(hints.ai_protocol)); printf(" }):\n"); err = getaddrinfo(hname, port, &hints, &ap); if (err) { printf("\terror => %s\n", eaistr(err)); return 1; } for (ap2 = ap; ap2; ap2 = ap2->ai_next) { char hbuf[NI_MAXHOST], pbuf[NI_MAXSERV]; /* If we don't do this, even AIX's own getnameinfo will reject the sockaddr structures. The sa_len field doesn't get set either, on AIX, but getnameinfo won't complain. */ if (ap2->ai_addr->sa_family == 0) { printf("BAD: sa_family zero! fixing...\n"); ap2->ai_addr->sa_family = ap2->ai_family; } else if (ap2->ai_addr->sa_family != ap2->ai_family) { printf("BAD: sa_family != ai_family! fixing...\n"); ap2->ai_addr->sa_family = ap2->ai_family; } if (getnameinfo(ap2->ai_addr, ap2->ai_addrlen, hbuf, sizeof(hbuf), pbuf, sizeof(pbuf), NI_NUMERICHOST | NI_NUMERICSERV)) { strlcpy(hbuf, "...", sizeof(hbuf)); strlcpy(pbuf, "...", sizeof(pbuf)); } printf("%p:\n" "\tfamily = %s\tproto = %-4s\tsocktype = %s\n", (void *) ap2, familyname(ap2->ai_family), protoname (ap2->ai_protocol), socktypename (ap2->ai_socktype)); if (ap2->ai_canonname) { if (ap2->ai_canonname[0]) printf("\tcanonname = %s\n", ap2->ai_canonname); else printf("BAD: ai_canonname is set but empty!\n"); } else if (ap2 == ap && (hints.ai_flags & AI_CANONNAME)) { printf("BAD: first ai_canonname is null!\n"); } printf("\taddr = %-28s\tport = %s\n", hbuf, pbuf); err = getnameinfo(ap2->ai_addr, ap2->ai_addrlen, hbuf, sizeof (hbuf), pbuf, sizeof(pbuf), NI_NAMEREQD); if (err) printf("\tgetnameinfo(NI_NAMEREQD): %s\n", eaistr(err)); else printf("\tgetnameinfo => %s, %s\n", hbuf, pbuf); } freeaddrinfo(ap); return 0; } krb5-1.16/src/tests/resolve/Makefile.in0000644000704600001450000000127713211554426017662 0ustar ghudsonlibuuidmydir=tests$(S)resolve BUILDTOP=$(REL)..$(S).. OBJS=resolve.o addrinfo-test.o fake-addrinfo-test.o SRCS=$(srcdir)/resolve.c $(srcdir)/addrinfo-test.c \ $(srcdir)/fake-addrinfo-test.c all: resolve addrinfo-test fake-addrinfo-test resolve: resolve.o $(CC_LINK) -o $@ resolve.o $(LIBS) addrinfo-test: addrinfo-test.o $(CC_LINK) -o $@ addrinfo-test.o $(SUPPORT_LIB) $(LIBS) fake-addrinfo-test: fake-addrinfo-test.o $(CC_LINK) -o $@ fake-addrinfo-test.o $(SUPPORT_LIB) $(LIBS) check: resolve addrinfo-test fake-addrinfo-test $(RUN_TEST) ./resolve $(RUN_TEST) ./addrinfo-test -p telnet $(RUN_TEST) ./fake-addrinfo-test -p telnet install: clean: $(RM) resolve addrinfo-test fake-addrinfo-test krb5-1.16/src/tests/t_princflags.py0000755000704600001450000001036113211554426017160 0ustar ghudsonlibuuid#!/usr/bin/python from k5test import * from princflags import * import re realm = K5Realm(create_host=False, get_creds=False) # Regex pattern to match an empty attribute line from kadmin getprinc emptyattr = re.compile('^Attributes:$', re.MULTILINE) # Regex pattern to match a kadmin getprinc output for a flag tuple def attr_pat(ftuple): return re.compile('^Attributes: ' + ftuple.flagname() + '$', re.MULTILINE) # Test one flag tuple for kadmin ank. def one_kadmin_flag(ftuple): pat = attr_pat(ftuple) realm.run([kadminl, 'ank', ftuple.setspec(), '-pw', 'password', 'test']) out = realm.run([kadminl, 'getprinc', 'test']) if not pat.search(out): fail('Failed to set flag ' + ftuple.flagname()) realm.run([kadminl, 'modprinc', ftuple.clearspec(), 'test']) out = realm.run([kadminl, 'getprinc', 'test']) if not emptyattr.search(out): fail('Failed to clear flag ' + ftuple.flagname()) realm.run([kadminl, 'delprinc', 'test']) # Generate a custom kdc.conf with default_principal_flags set # according to ftuple. def genkdcconf(ftuple): d = { 'realms': { '$realm': { 'default_principal_flags': ftuple.setspec() }}} return realm.special_env('tmp', True, kdc_conf=d) # Test one ftuple for kdc.conf default_principal_flags. def one_kdcconf(ftuple): e = genkdcconf(ftuple) pat = attr_pat(ftuple) realm.run([kadminl, 'ank', '-pw', 'password', 'test'], env=e) out = realm.run([kadminl, 'getprinc', 'test']) if not pat.search(out): fail('Failed to set flag ' + ftuple.flagname() + ' via kdc.conf') realm.run([kadminl, 'delprinc', 'test']) # Principal name for kadm5.acl line def ftuple2pname(ftuple, doset): pname = 'set_' if doset else 'clear_' return pname + ftuple.flagname() # Translate a strconv ftuple to a spec string for kadmin. def ftuple2kadm_spec(ftuple, doset): ktuple = kadmin_itable[ftuple.flag] if ktuple.invert != ftuple.invert: # Could do: # doset = not doset # but this shouldn't happen. raise ValueError return ktuple.spec(doset) # Generate a line for kadm5.acl. def acl_line(ftuple, doset): pname = ftuple2pname(ftuple, doset) spec = ftuple.spec(doset) return "%s * %s %s\n" % (realm.admin_princ, pname, spec) # Test one kadm5.acl line for a ftuple. def one_aclcheck(ftuple, doset): pname = ftuple2pname(ftuple, doset) pat = attr_pat(ftuple) outname = ftuple.flagname() # Create the principal and check that the flag is correctly set or # cleared. realm.run_kadmin(['ank', '-pw', 'password', pname]) out = realm.run([kadminl, 'getprinc', pname]) if doset: if not pat.search(out): fail('Failed to set flag ' + outname + ' via kadm5.acl') else: if not emptyattr.search(out): fail('Failed to clear flag ' + outname + ' via kadm5.acl') # If acl forces flag to be set, try to clear it, and vice versa. spec = ftuple2kadm_spec(ftuple, not doset) realm.run_kadmin(['modprinc', spec, pname]) out = realm.run([kadminl, 'getprinc', pname]) if doset: if not pat.search(out): fail('Failed to keep flag ' + outname + ' set') else: if not emptyattr.search(out): fail('Failed to keep flag ' + outname + ' clear') # Set all flags simultaneously, even the ones that aren't defined yet. def lamptest(): pat = re.compile('^Attributes: ' + ' '.join(flags2namelist(0xffffffff)) + '$', re.MULTILINE) realm.run([kadminl, 'ank', '-pw', 'password', '+0xffffffff', 'test']) out = realm.run([kadminl, 'getprinc', 'test']) if not pat.search(out): fail('Failed to simultaenously set all flags') realm.run([kadminl, 'delprinc', 'test']) for ftuple in kadmin_ftuples: one_kadmin_flag(ftuple) for ftuple in strconv_ftuples: one_kdcconf(ftuple) f = open(os.path.join(realm.testdir, 'acl'), 'w') for ftuple in strconv_ftuples: f.write(acl_line(ftuple, True)) f.write(acl_line(ftuple, False)) f.close() realm.start_kadmind() realm.prep_kadmin() for ftuple in strconv_ftuples: one_aclcheck(ftuple, True) one_aclcheck(ftuple, False) lamptest() success('KDB principal flags') krb5-1.16/src/tests/t_preauth.py0000644000704600001450000002363113211554426016501 0ustar ghudsonlibuuid#!/usr/bin/python from k5test import * # Test that the kdcpreauth client_keyblock() callback matches the key # indicated by the etype info, and returns NULL if no key was selected. testpreauth = os.path.join(buildtop, 'plugins', 'preauth', 'test', 'test.so') conf = {'plugins': {'kdcpreauth': {'module': 'test:' + testpreauth}, 'clpreauth': {'module': 'test:' + testpreauth}}} realm = K5Realm(create_host=False, get_creds=False, krb5_conf=conf) realm.run([kadminl, 'modprinc', '+requires_preauth', realm.user_princ]) realm.run([kadminl, 'setstr', realm.user_princ, 'teststring', 'testval']) realm.run([kadminl, 'addprinc', '-nokey', '+requires_preauth', 'nokeyuser']) realm.kinit(realm.user_princ, password('user'), expected_msg='testval') realm.kinit('nokeyuser', password('user'), expected_code=1, expected_msg='no key') # Preauth type -123 is the test preauth module type; 133 is FAST # PA-FX-COOKIE; 2 is encrypted timestamp. # Test normal preauth flow. expected_trace = ('Sending unauthenticated request', '/Additional pre-authentication required', 'Preauthenticating using KDC method data', 'Processing preauth types:', 'Preauth module test (-123) (real) returned: 0/Success', 'Produced preauth for next request: 133, -123', 'Decrypted AS reply') realm.run(['./icred', realm.user_princ, password('user')], expected_msg='testval', expected_trace=expected_trace) # Test successful optimistic preauth. expected_trace = ('Attempting optimistic preauth', 'Processing preauth types: -123', 'Preauth module test (-123) (real) returned: 0/Success', 'Produced preauth for next request: -123', 'Decrypted AS reply') realm.run(['./icred', '-o', '-123', realm.user_princ, password('user')], expected_trace=expected_trace) # Test optimistic preauth failing on client, followed by successful # preauth using the same module. expected_trace = ('Attempting optimistic preauth', 'Processing preauth types: -123', '/induced optimistic fail', 'Sending unauthenticated request', '/Additional pre-authentication required', 'Preauthenticating using KDC method data', 'Processing preauth types:', 'Preauth module test (-123) (real) returned: 0/Success', 'Produced preauth for next request: 133, -123', 'Decrypted AS reply') realm.run(['./icred', '-o', '-123', '-X', 'fail_optimistic', realm.user_princ, password('user')], expected_msg='testval', expected_trace=expected_trace) # Test optimistic preauth failing on KDC, followed by successful preauth # using the same module. realm.run([kadminl, 'setstr', realm.user_princ, 'failopt', 'yes']) expected_trace = ('Attempting optimistic preauth', 'Processing preauth types: -123', 'Preauth module test (-123) (real) returned: 0/Success', 'Produced preauth for next request: -123', '/Preauthentication failed', 'Preauthenticating using KDC method data', 'Processing preauth types:', 'Preauth module test (-123) (real) returned: 0/Success', 'Produced preauth for next request: 133, -123', 'Decrypted AS reply') realm.run(['./icred', '-o', '-123', realm.user_princ, password('user')], expected_msg='testval', expected_trace=expected_trace) realm.run([kadminl, 'delstr', realm.user_princ, 'failopt']) # Test KDC_ERR_MORE_PREAUTH_DATA_REQUIRED and secure cookies. realm.run([kadminl, 'setstr', realm.user_princ, '2rt', 'secondtrip']) expected_trace = ('Sending unauthenticated request', '/Additional pre-authentication required', 'Preauthenticating using KDC method data', 'Processing preauth types:', 'Preauth module test (-123) (real) returned: 0/Success', 'Produced preauth for next request: 133, -123', '/More preauthentication data is required', 'Continuing preauth mech -123', 'Processing preauth types: -123, 133', 'Produced preauth for next request: 133, -123', 'Decrypted AS reply') realm.run(['./icred', realm.user_princ, password('user')], expected_msg='2rt: secondtrip', expected_trace=expected_trace) # Test client-side failure after KDC_ERR_MORE_PREAUTH_DATA_REQUIRED, # falling back to encrypted timestamp. expected_trace = ('Sending unauthenticated request', '/Additional pre-authentication required', 'Preauthenticating using KDC method data', 'Processing preauth types:', 'Preauth module test (-123) (real) returned: 0/Success', 'Produced preauth for next request: 133, -123', '/More preauthentication data is required', 'Continuing preauth mech -123', 'Processing preauth types: -123, 133', '/induced 2rt fail', 'Preauthenticating using KDC method data', 'Processing preauth types:', 'Encrypted timestamp (for ', 'module encrypted_timestamp (2) (real) returned: 0/Success', 'Produced preauth for next request: 133, 2', 'Decrypted AS reply') realm.run(['./icred', '-X', 'fail_2rt', realm.user_princ, password('user')], expected_msg='2rt: secondtrip', expected_trace=expected_trace) # Test KDC-side failure after KDC_ERR_MORE_PREAUTH_DATA_REQUIRED, # falling back to encrypted timestamp. realm.run([kadminl, 'setstr', realm.user_princ, 'fail2rt', 'yes']) expected_trace = ('Sending unauthenticated request', '/Additional pre-authentication required', 'Preauthenticating using KDC method data', 'Processing preauth types:', 'Preauth module test (-123) (real) returned: 0/Success', 'Produced preauth for next request: 133, -123', '/More preauthentication data is required', 'Continuing preauth mech -123', 'Processing preauth types: -123, 133', 'Preauth module test (-123) (real) returned: 0/Success', 'Produced preauth for next request: 133, -123', '/Preauthentication failed', 'Preauthenticating using KDC method data', 'Processing preauth types:', 'Encrypted timestamp (for ', 'module encrypted_timestamp (2) (real) returned: 0/Success', 'Produced preauth for next request: 133, 2', 'Decrypted AS reply') realm.run(['./icred', realm.user_princ, password('user')], expected_msg='2rt: secondtrip', expected_trace=expected_trace) realm.run([kadminl, 'delstr', realm.user_princ, 'fail2rt']) # Test tryagain flow by inducing a KDC_ERR_ENCTYPE_NOSUPP error on the KDC. realm.run([kadminl, 'setstr', realm.user_princ, 'err', 'testagain']) expected_trace = ('Sending unauthenticated request', '/Additional pre-authentication required', 'Preauthenticating using KDC method data', 'Processing preauth types:', 'Preauth module test (-123) (real) returned: 0/Success', 'Produced preauth for next request: 133, -123', '/KDC has no support for encryption type', 'Recovering from KDC error 14 using preauth mech -123', 'Preauth tryagain input types (-123): -123, 133', 'Preauth module test (-123) tryagain returned: 0/Success', 'Followup preauth for next request: -123, 133', 'Decrypted AS reply') realm.run(['./icred', realm.user_princ, password('user')], expected_msg='tryagain: testagain', expected_trace=expected_trace) # Test a client-side tryagain failure, falling back to encrypted # timestamp. expected_trace = ('Sending unauthenticated request', '/Additional pre-authentication required', 'Preauthenticating using KDC method data', 'Processing preauth types:', 'Preauth module test (-123) (real) returned: 0/Success', 'Produced preauth for next request: 133, -123', '/KDC has no support for encryption type', 'Recovering from KDC error 14 using preauth mech -123', 'Preauth tryagain input types (-123): -123, 133', '/induced tryagain fail', 'Preauthenticating using KDC method data', 'Processing preauth types:', 'Encrypted timestamp (for ', 'module encrypted_timestamp (2) (real) returned: 0/Success', 'Produced preauth for next request: 133, 2', 'Decrypted AS reply') realm.run(['./icred', '-X', 'fail_tryagain', realm.user_princ, password('user')], expected_trace=expected_trace) # Test that multiple stepwise initial creds operations can be # performed with the same krb5_context, with proper tracking of # clpreauth module request handles. realm.run([kadminl, 'addprinc', '-pw', 'pw', 'u1']) realm.run([kadminl, 'addprinc', '+requires_preauth', '-pw', 'pw', 'u2']) realm.run([kadminl, 'addprinc', '+requires_preauth', '-pw', 'pw', 'u3']) realm.run([kadminl, 'setstr', 'u2', '2rt', 'extra']) out = realm.run(['./icinterleave', 'pw', 'u1', 'u2', 'u3']) if out != ('step 1\nstep 2\nstep 3\nstep 1\nfinish 1\nstep 2\nno attr\n' 'step 3\nno attr\nstep 2\n2rt: extra\nstep 3\nfinish 3\nstep 2\n' 'finish 2\n'): fail('unexpected output from icinterleave') success('Pre-authentication framework tests') krb5-1.16/src/tests/t_sn2princ.py0000755000704600001450000001012213211554426016561 0ustar ghudsonlibuuid#!/usr/bin/python from k5test import * offline = (len(args) > 0 and args[0] != "no") conf = {'domain_realm': {'kerberos.org': 'R1', 'example.com': 'R2', 'mit.edu': 'R3'}} no_rdns_conf = {'libdefaults': {'rdns': 'false'}} no_canon_conf = {'libdefaults': {'dns_canonicalize_hostname': 'false'}} realm = K5Realm(create_kdb=False, krb5_conf=conf) no_rdns = realm.special_env('no_rdns', False, krb5_conf=no_rdns_conf) no_canon = realm.special_env('no_canon', False, krb5_conf=no_canon_conf) def testbase(host, nametype, princhost, princrealm, env=None): # Run the sn2princ harness with a specified host and name type and # the fixed service string 'svc', and compare the result to the # expected hostname and realm part. out = realm.run(['./s2p', host, 'SVC', nametype], env=env).rstrip() expected = 'SVC/%s@%s' % (princhost, princrealm) if out != expected: fail('Expected %s, got %s' % (expected, out)) def test(host, princhost, princrealm): # Test with the host-based name type in the default environment. testbase(host, 'srv-hst', princhost, princrealm) def testnc(host, princhost, princrealm): # Test with the host-based name type with canonicalization disabled. testbase(host, 'srv-hst', princhost, princrealm, env=no_canon) def testnr(host, princhost, princrealm): # Test with the host-based name type with reverse lookup disabled. testbase(host, 'srv-hst', princhost, princrealm, env=no_rdns) def testu(host, princhost, princrealm): # Test with the unknown name type. testbase(host, 'unknown', princhost, princrealm) # With the unknown principal type, we do not canonicalize or downcase, # but we do remove a trailing period and look up the realm. testu('ptr-mismatch.kerberos.org', 'ptr-mismatch.kerberos.org', 'R1') testu('Example.COM', 'Example.COM', 'R2') testu('abcde', 'abcde', '') # A ':port' or ':instance' trailer should be ignored for realm lookup. # If there is more than one colon in the name, we assume it's an IPv6 # address and don't treat it as having a trailer. testu('example.com.:123', 'example.com.:123', 'R2') testu('Example.COM:xyZ', 'Example.COM:xyZ', 'R2') testu('example.com.::123', 'example.com.::123', '') # With dns_canonicalize_hostname=false, we downcase and remove # trailing dots but do not canonicalize the hostname. Trailers do not # get downcased. testnc('ptr-mismatch.kerberos.org', 'ptr-mismatch.kerberos.org', 'R1') testnc('Example.COM', 'example.com', 'R2') testnc('abcde', 'abcde', '') testnc('example.com.:123', 'example.com:123', 'R2') testnc('Example.COM:xyZ', 'example.com:xyZ', 'R2') testnc('example.com.::123', 'example.com.::123', '') if offline: skip_rest('sn2princ tests', 'offline mode requested') # For the online tests, we rely on ptr-mismatch.kerberos.org forward # and reverse resolving to these names. oname = 'ptr-mismatch.kerberos.org' fname = 'www.kerberos.org' # Verify forward resolution before testing for it. try: ai = socket.getaddrinfo(oname, None, 0, 0, 0, socket.AI_CANONNAME) except socket.gaierror: skip_rest('sn2princ tests', 'cannot forward resolve %s' % oname) (family, socktype, proto, canonname, sockaddr) = ai[0] if canonname.lower() != fname: skip_rest('sn2princ tests', '%s forward resolves to %s, not %s' % (oname, canonname, fname)) # Test forward-only canonicalization (rdns=false). testnr(oname, fname, 'R1') testnr(oname + ':123', fname + ':123', 'R1') testnr(oname + ':xyZ', fname + ':xyZ', 'R1') # Verify reverse resolution before testing for it. try: names = socket.getnameinfo(sockaddr, socket.NI_NAMEREQD) except socket.gaierror: skip_rest('reverse sn2princ tests', 'cannot reverse resolve %s' % oname) rname = names[0].lower() if rname == fname: skip_rest('reverse sn2princ tests', '%s reverse resolves to %s ' 'which should be different from %s' % (oname, rname, fname)) # Test default canonicalization (forward and reverse lookup). test(oname, rname, 'R3') test(oname + ':123', rname + ':123', 'R3') test(oname + ':xyZ', rname + ':xyZ', 'R3') success('krb5_sname_to_principal tests') krb5-1.16/src/tests/gss-threads/0000755000704600001450000000000013211554426016353 5ustar ghudsonlibuuidkrb5-1.16/src/tests/gss-threads/README0000644000704600001450000001470513211554426017242 0ustar ghudsonlibuuid[Out of date; needs updating for thread safety test support. -- KR 2005-02-09] # Copyright 1993 by OpenVision Technologies, Inc. # # Permission to use, copy, modify, distribute, and sell this software # and its documentation for any purpose is hereby granted without fee, # provided that the above copyright notice appears in all copies and # that both that copyright notice and this permission notice appear in # supporting documentation, and that the name of OpenVision not be used # in advertising or publicity pertaining to distribution of the software # without specific, written prior permission. OpenVision makes no # representations about the suitability of this software for any # purpose. It is provided "as is" without express or implied warranty. # # OPENVISION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, # INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO # EVENT SHALL OPENVISION BE LIABLE FOR ANY SPECIAL, INDIRECT OR # CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF # USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR # OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. This directory contains a sample GSS-API client and server application. In addition to serving as an example of GSS-API programming, this application is also intended to be a tool for testing the performance of GSS-API implementations. Each time the client is invoked, it performs one or more exchanges with the server. Each exchange with the server consists primarily of the following steps: 1. A TCP/IP connection is established. 2. (optional, on by default) The client and server establish a GSS-API context, and the server prints the identify of the client. / 3. The client sends a message to the server. The message may / be plaintext, cryptographically "signed" but not encrypted, | or encrypted (default). | 0 or | 4. The server decrypts the message (if necessary), verifies more | its signature (if there is one) and prints it. times| | 5. The server sends either a signature block (the default) or an | empty token back to the client to acknowledge the message. \ \ 6. If the server sent a signature block, the client verifies it and prints a message indicating that it was verified. 7. The client sends an empty block to the server to tell it that the exchange is finished. 8. The client and server close the TCP/IP connection and destroy the GSS-API context. The client also supports the -v1 flag which uses an older exchange format compatible with previous releases of Kerberos and with samples shipped in the Microsoft SDK. The server's command line usage is gss-server [-port port] [-verbose] [-once] [-inetd] [-export] [-logfile file] service_name where service_name is a GSS-API service name of the form "service@host" (or just "service", in which case the local host name is used). The command-line options have the following meanings: -port The TCP port on which to accept connections. Default is 4444. -once Tells the server to exit after a single exchange, rather than persisting. -inetd Tells the server that it is running out of inetd, so it should interact with the client on stdin rather than binding to a network port. Implies "-once". -export Tells the server to test the gss_export_sec_context function after establishing a context with a client. -logfile The file to which the server should append its output, rather than sending it to stdout. The client's command line usage is gss-client [-port port] [-mech mechanism] [-d] [-f] [-q] [-seq] [-noreplay] [-nomutual] [-ccount count] [-mcount count] [-na] [-nw] [-nx] [-nm] host service_name msg where host is the host running the server, service_name is the service name that the server will establish connections as (if you don't specify the host name in the service name when running gss-server, and it's running on a different machine from gss-client, make sure to specify the server's host name in the service name you specify to gss-client!) and msg is the message. The command-line options have the following meanings: -port The TCP port to which to connect. Default is 4444. -mech The OID of the GSS-API mechanism to use. -d Tells the client to delegate credentials to the server. For the Kerberos GSS-API mechanism, this means that a forwardable TGT will be sent to the server, which will put it in its credential cache (you must have acquired your tickets with "kinit -f" for this to work). -seq Tells the client to enforce ordered message delivery via sequencing. -noreplay Tells the client to disable the use of replay detection. -nomutual Tells the client to disable the use of mutual authentication. -f Tells the client that the "msg" argument is actually the name of a file whose contents should be used as the message. -q Tells the client to be quiet, i.e., to only print error messages. -ccount Specifies how many sessions the client should initiate with the server (the "connection count"). -mcount Specifies how many times the message should be sent to the server in each session (the "message count"). -na Tells the client not to do any authentication with the server. Implies "-nw", "-nx" and "-nm". -nw Tells the client not to "wrap" messages. Implies "-nx". -nx Tells the client not to encrypt messages. -nm Tells the client not to ask the server to send back a cryptographic checksum ("MIC"). To run the server on a host, you need to make sure that the principal corresponding to service_name is in the default keytab on the server host, and that the gss-server process can read the keytab. For example, the service name "host@server" corresponds to the Kerberos principal "host/server.domain.com@REALM". This sample application uses the following GSS-API functions: gss_accept_sec_context gss_inquire_names_for_mech gss_acquire_cred gss_oid_to_str gss_delete_sec_context gss_release_buffer gss_display_name gss_release_cred gss_display_status gss_release_name gss_export_sec_context gss_release_oid gss_get_mic gss_release_oid_set gss_import_name gss_str_to_oid gss_import_sec_context gss_unwrap gss_init_sec_context gss_verify_mic gss_inquire_context gss_wrap This application was originally written by Barry Jaspan of OpenVision Technologies, Inc. It was updated significantly by Jonathan Kamens of OpenVision Technologies, Inc. $Id$ krb5-1.16/src/tests/gss-threads/gss-misc.h0000644000704600001450000000350413211554426020253 0ustar ghudsonlibuuid/* * Copyright 1994 by OpenVision Technologies, Inc. * * Permission to use, copy, modify, distribute, and sell this software * and its documentation for any purpose is hereby granted without fee, * provided that the above copyright notice appears in all copies and * that both that copyright notice and this permission notice appear in * supporting documentation, and that the name of OpenVision not be used * in advertising or publicity pertaining to distribution of the software * without specific, written prior permission. OpenVision makes no * representations about the suitability of this software for any * purpose. It is provided "as is" without express or implied warranty. * * OPENVISION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO * EVENT SHALL OPENVISION BE LIABLE FOR ANY SPECIAL, INDIRECT OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ #ifndef _GSSMISC_H_ #define _GSSMISC_H_ #include #include extern FILE *display_file; int send_token(int s, int flags, gss_buffer_t tok); int recv_token(int s, int *flags, gss_buffer_t tok); void display_status(char *msg, OM_uint32 maj_stat, OM_uint32 min_stat); void display_ctx_flags(OM_uint32 flags); void print_token(gss_buffer_t tok); /* Token types */ #define TOKEN_NOOP (1<<0) #define TOKEN_CONTEXT (1<<1) #define TOKEN_DATA (1<<2) #define TOKEN_MIC (1<<3) /* Token flags */ #define TOKEN_CONTEXT_NEXT (1<<4) #define TOKEN_WRAPPED (1<<5) #define TOKEN_ENCRYPTED (1<<6) #define TOKEN_SEND_MIC (1<<7) extern gss_buffer_t empty_token; #endif krb5-1.16/src/tests/gss-threads/gss-client.c0000644000704600001450000006612213211554426020576 0ustar ghudsonlibuuid/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* * Copyright 1994 by OpenVision Technologies, Inc. * * Permission to use, copy, modify, distribute, and sell this software * and its documentation for any purpose is hereby granted without fee, * provided that the above copyright notice appears in all copies and * that both that copyright notice and this permission notice appear in * supporting documentation, and that the name of OpenVision not be used * in advertising or publicity pertaining to distribution of the software * without specific, written prior permission. OpenVision makes no * representations about the suitability of this software for any * purpose. It is provided "as is" without express or implied warranty. * * OPENVISION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO * EVENT SHALL OPENVISION BE LIABLE FOR ANY SPECIAL, INDIRECT OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* * Copyright (C) 2003, 2004, 2008 by the Massachusetts Institute of Technology. * All rights reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #include "k5-platform.h" #ifdef _WIN32 #include #include #else #include #include #include #include #include #include #include #include #include #endif #include #include "gss-misc.h" #include "port-sockets.h" #include "fake-addrinfo.h" static int verbose = 1; static void usage() { fprintf(stderr, "Usage: gss-client [-port port] [-mech mechanism] [-d]\n"); fprintf(stderr, " [-seq] [-noreplay] [-nomutual]"); fprintf(stderr, " [-threads num]"); fprintf(stderr, "\n"); fprintf(stderr, " [-f] [-q] [-ccount count] [-mcount count]\n"); fprintf(stderr, " [-v1] [-na] [-nw] [-nx] [-nm] host service msg\n"); exit(1); } /* * Function: get_server_info * * Purpose: Sets up a socket address for the named host and port. * * Arguments: * * host (r) the target host name * port (r) the target port, in host byte order * * Returns: 0 on success, or -1 on failure * * Effects: * * The host name is resolved with gethostbyname(), and "saddr" is set * to the desired socket address. If an error occurs, an error * message is displayed and -1 is returned. */ struct sockaddr_in saddr; static int get_server_info(char *host, u_short port) { struct hostent *hp; hp = gethostbyname(host); if (hp == NULL) { fprintf(stderr, "Unknown host: %s\n", host); return -1; } saddr.sin_family = hp->h_addrtype; memcpy(&saddr.sin_addr, hp->h_addr, sizeof(saddr.sin_addr)); saddr.sin_port = htons(port); return 0; } /* * Function: connect_to_server * * Purpose: Opens a TCP connection to the name host and port. * * Arguments: * * host (r) the target host name * port (r) the target port, in host byte order * * Returns: the established socket file desciptor, or -1 on failure * * Effects: * * The host name is resolved with gethostbyname(), and the socket is * opened and connected. If an error occurs, an error message is * displayed and -1 is returned. */ static int connect_to_server() { int s; s = socket(AF_INET, SOCK_STREAM, 0); if (s < 0) { perror("creating socket"); return -1; } if (connect(s, (struct sockaddr *)&saddr, sizeof(saddr)) < 0) { perror("connecting to server"); (void)closesocket(s); return -1; } return s; } /* * Function: client_establish_context * * Purpose: establishes a GSS-API context with a specified service and * returns the context handle * * Arguments: * * s (r) an established TCP connection to the service * service_name (r) the ASCII service name of the service * gss_flags (r) GSS-API delegation flag (if any) * auth_flag (r) whether to actually do authentication * v1_format (r) whether the v1 sample protocol should be used * oid (r) OID of the mechanism to use * context (w) the established GSS-API context * ret_flags (w) the returned flags from init_sec_context * * Returns: 0 on success, -1 on failure * * Effects: * * service_name is imported as a GSS-API name and a GSS-API context is * established with the corresponding service; the service should be * listening on the TCP connection s. The default GSS-API mechanism * is used, and mutual authentication and replay detection are * requested. * * If successful, the context handle is returned in context. If * unsuccessful, the GSS-API error messages are displayed on stderr * and -1 is returned. */ static int client_establish_context(int s, char *service_name, OM_uint32 gss_flags, int auth_flag, int v1_format, gss_OID oid, gss_ctx_id_t *gss_context, OM_uint32 *ret_flags) { if (auth_flag) { gss_buffer_desc send_tok, recv_tok, *token_ptr; gss_name_t target_name; OM_uint32 maj_stat, min_stat, init_sec_min_stat; int token_flags; /* * Import the name into target_name. Use send_tok to save * local variable space. */ send_tok.value = service_name; send_tok.length = strlen(service_name); maj_stat = gss_import_name(&min_stat, &send_tok, (gss_OID)gss_nt_service_name, &target_name); if (maj_stat != GSS_S_COMPLETE) { display_status("parsing name", maj_stat, min_stat); return -1; } if (!v1_format) { if (send_token(s, TOKEN_NOOP | TOKEN_CONTEXT_NEXT, empty_token) < 0) { (void)gss_release_name(&min_stat, &target_name); return -1; } } /* * Perform the context-establishement loop. * * On each pass through the loop, token_ptr points to the token * to send to the server (or GSS_C_NO_BUFFER on the first pass). * Every generated token is stored in send_tok which is then * transmitted to the server; every received token is stored in * recv_tok, which token_ptr is then set to, to be processed by * the next call to gss_init_sec_context. * * GSS-API guarantees that send_tok's length will be non-zero * if and only if the server is expecting another token from us, * and that gss_init_sec_context returns GSS_S_CONTINUE_NEEDED if * and only if the server has another token to send us. */ token_ptr = GSS_C_NO_BUFFER; *gss_context = GSS_C_NO_CONTEXT; do { maj_stat = gss_init_sec_context(&init_sec_min_stat, GSS_C_NO_CREDENTIAL, gss_context, target_name, oid, gss_flags, 0, NULL, token_ptr, NULL, &send_tok, ret_flags, NULL); if (token_ptr != GSS_C_NO_BUFFER) free(recv_tok.value); if (send_tok.length != 0) { if (verbose) { printf("Sending init_sec_context token (size=%d)...", (int)send_tok.length); } if (send_token(s, v1_format ? 0 : TOKEN_CONTEXT, &send_tok) < 0) { (void)gss_release_buffer(&min_stat, &send_tok); (void)gss_release_name(&min_stat, &target_name); if (*gss_context != GSS_C_NO_CONTEXT) { gss_delete_sec_context(&min_stat, gss_context, GSS_C_NO_BUFFER); *gss_context = GSS_C_NO_CONTEXT; } return -1; } } (void)gss_release_buffer(&min_stat, &send_tok); if (maj_stat != GSS_S_COMPLETE && maj_stat != GSS_S_CONTINUE_NEEDED) { display_status("initializing context", maj_stat, init_sec_min_stat); (void)gss_release_name(&min_stat, &target_name); if (*gss_context != GSS_C_NO_CONTEXT) { gss_delete_sec_context(&min_stat, gss_context, GSS_C_NO_BUFFER); } return -1; } if (maj_stat == GSS_S_CONTINUE_NEEDED) { if (verbose) printf("continue needed..."); if (recv_token(s, &token_flags, &recv_tok) < 0) { (void)gss_release_name(&min_stat, &target_name); return -1; } token_ptr = &recv_tok; } if (verbose) printf("\n"); } while (maj_stat == GSS_S_CONTINUE_NEEDED); (void)gss_release_name(&min_stat, &target_name); } else if (send_token(s, TOKEN_NOOP, empty_token) < 0) { return -1; } return 0; } static void read_file(char *file_name, gss_buffer_t in_buf) { int fd, count; struct stat stat_buf; fd = open(file_name, O_RDONLY, 0); if (fd < 0) { perror("open"); fprintf(stderr, "Couldn't open file %s\n", file_name); exit(2); } if (fstat(fd, &stat_buf) < 0) { perror("fstat"); exit(3); } in_buf->length = stat_buf.st_size; if (in_buf->length == 0) { in_buf->value = NULL; return; } in_buf->value = malloc(in_buf->length); if (in_buf->value == NULL) { fprintf(stderr, "Couldn't allocate %d byte buffer for reading file\n", (int)in_buf->length); exit(4); } /* This code used to check for incomplete reads, but you can't get * an incomplete read on any file for which fstat() is meaningful. */ count = read(fd, in_buf->value, in_buf->length); if (count < 0) { perror("read"); exit(5); } if ((size_t)count < in_buf->length) { fprintf(stderr, "Warning, only read in %d bytes, expected %d\n", count, (int)in_buf->length); } } /* * Function: call_server * * Purpose: Call the "sign" service. * * Arguments: * * host (r) the host providing the service * port (r) the port to connect to on host * service_name (r) the GSS-API service name to authenticate to * gss_flags (r) GSS-API delegation flag (if any) * auth_flag (r) whether to do authentication * wrap_flag (r) whether to do message wrapping at all * encrypt_flag (r) whether to do encryption while wrapping * mic_flag (r) whether to request a MIC from the server * msg (r) the message to have "signed" * use_file (r) whether to treat msg as an input file name * mcount (r) the number of times to send the message * * Returns: 0 on success, -1 on failure * * Effects: * * call_server opens a TCP connection to and establishes a * GSS-API context with service_name over the connection. It then * seals msg in a GSS-API token with gss_wrap, sends it to the server, * reads back a GSS-API signature block for msg from the server, and * verifies it with gss_verify. -1 is returned if any step fails, * otherwise 0 is returned. */ static int call_server(char *host, u_short port, gss_OID oid, char *service_name, OM_uint32 gss_flags, int auth_flag, int wrap_flag, int encrypt_flag, int mic_flag, int v1_format, char *msg, int use_file, size_t mcount) { gss_ctx_id_t context; gss_buffer_desc in_buf, out_buf, sname, tname, oid_name; int s, state, is_local, is_open, flags, token_flags; OM_uint32 ret_flags, maj_stat, min_stat, lifetime, context_flags; gss_name_t src_name, targ_name; gss_OID mechanism, name_type; gss_qop_t qop_state; gss_OID_set mech_names; size_t i; /* Open connection. */ s = connect_to_server(); if (s < 0) return -1; /* Establish context. */ if (client_establish_context(s, service_name, gss_flags, auth_flag, v1_format, oid, &context, &ret_flags) < 0) { (void)closesocket(s); return -1; } if (auth_flag && verbose) { /* Display the flags. */ display_ctx_flags(ret_flags); /* Get context information. */ maj_stat = gss_inquire_context(&min_stat, context, &src_name, &targ_name, &lifetime, &mechanism, &context_flags, &is_local, &is_open); if (maj_stat != GSS_S_COMPLETE) { display_status("inquiring context", maj_stat, min_stat); return -1; } maj_stat = gss_display_name(&min_stat, src_name, &sname, &name_type); if (maj_stat != GSS_S_COMPLETE) { display_status("displaying source name", maj_stat, min_stat); return -1; } maj_stat = gss_display_name(&min_stat, targ_name, &tname, NULL); if (maj_stat != GSS_S_COMPLETE) { display_status("displaying target name", maj_stat, min_stat); return -1; } printf("\"%.*s\" to \"%.*s\", lifetime %d, flags %x, %s, %s\n", (int)sname.length, (char *)sname.value, (int)tname.length, (char *)tname.value, lifetime, context_flags, is_local ? "locally initiated" : "remotely initiated", is_open ? "open" : "closed"); (void)gss_release_name(&min_stat, &src_name); (void)gss_release_name(&min_stat, &targ_name); (void)gss_release_buffer(&min_stat, &sname); (void)gss_release_buffer(&min_stat, &tname); maj_stat = gss_oid_to_str(&min_stat, name_type, &oid_name); if (maj_stat != GSS_S_COMPLETE) { display_status("converting oid->string", maj_stat, min_stat); return -1; } printf("Name type of source name is %.*s.\n", (int)oid_name.length, (char *)oid_name.value); (void)gss_release_buffer(&min_stat, &oid_name); /* Now get the names supported by the mechanism. */ maj_stat = gss_inquire_names_for_mech(&min_stat, mechanism, &mech_names); if (maj_stat != GSS_S_COMPLETE) { display_status("inquiring mech names", maj_stat, min_stat); return -1; } maj_stat = gss_oid_to_str(&min_stat, mechanism, &oid_name); if (maj_stat != GSS_S_COMPLETE) { display_status("converting oid->string", maj_stat, min_stat); return -1; } printf("Mechanism %.*s supports %d names\n", (int)oid_name.length, (char *)oid_name.value, (int)mech_names->count); (void)gss_release_buffer(&min_stat, &oid_name); for (i = 0; i < mech_names->count; i++) { maj_stat = gss_oid_to_str(&min_stat, &mech_names->elements[i], &oid_name); if (maj_stat != GSS_S_COMPLETE) { display_status("converting oid->string", maj_stat, min_stat); return -1; } printf(" %d: %.*s\n", (int)i, (int)oid_name.length, (char *)oid_name.value); (void)gss_release_buffer(&min_stat, &oid_name); } (void)gss_release_oid_set(&min_stat, &mech_names); } if (use_file) { read_file(msg, &in_buf); } else { /* Seal the message. */ in_buf.value = msg; in_buf.length = strlen(msg); } for (i = 0; i < mcount; i++) { if (wrap_flag) { maj_stat = gss_wrap(&min_stat, context, encrypt_flag, GSS_C_QOP_DEFAULT, &in_buf, &state, &out_buf); if (maj_stat != GSS_S_COMPLETE) { display_status("wrapping message", maj_stat, min_stat); (void)closesocket(s); (void)gss_delete_sec_context(&min_stat, &context, GSS_C_NO_BUFFER); return -1; } else if (encrypt_flag && !state) { fprintf(stderr, "Warning! Message not encrypted.\n"); } } else { out_buf = in_buf; } /* Send to server. */ flags = 0; if (!v1_format) { flags = TOKEN_DATA | (wrap_flag ? TOKEN_WRAPPED : 0) | (encrypt_flag ? TOKEN_ENCRYPTED : 0) | (mic_flag ? TOKEN_SEND_MIC : 0); } if (send_token(s, flags, &out_buf) < 0) { (void)closesocket(s); (void)gss_delete_sec_context(&min_stat, &context, GSS_C_NO_BUFFER); return -1; } if (out_buf.value != in_buf.value) (void)gss_release_buffer(&min_stat, &out_buf); /* Read signature block into out_buf. */ if (recv_token(s, &token_flags, &out_buf) < 0) { (void)closesocket(s); (void)gss_delete_sec_context(&min_stat, &context, GSS_C_NO_BUFFER); return -1; } if (mic_flag) { /* Verify signature block. */ maj_stat = gss_verify_mic(&min_stat, context, &in_buf, &out_buf, &qop_state); if (maj_stat != GSS_S_COMPLETE) { display_status("verifying signature", maj_stat, min_stat); (void)closesocket(s); (void)gss_delete_sec_context(&min_stat, &context, GSS_C_NO_BUFFER); return -1; } if (verbose) printf("Signature verified.\n"); } else if (verbose) { printf("Response received.\n"); } free(out_buf.value); } if (use_file) free(in_buf.value); /* Send NOOP. */ if (!v1_format) (void)send_token(s, TOKEN_NOOP, empty_token); if (auth_flag) { /* Delete context. */ maj_stat = gss_delete_sec_context(&min_stat, &context, &out_buf); if (maj_stat != GSS_S_COMPLETE) { display_status("deleting context", maj_stat, min_stat); (void)closesocket(s); (void)gss_delete_sec_context(&min_stat, &context, GSS_C_NO_BUFFER); return -1; } (void)gss_release_buffer(&min_stat, &out_buf); } (void)closesocket(s); return 0; } static void parse_oid(char *mechanism, gss_OID *oid) { char *mechstr = 0, *cp; gss_buffer_desc tok; OM_uint32 maj_stat, min_stat; if (isdigit((unsigned char)mechanism[0])) { if (asprintf(&mechstr, "{ %s }", mechanism) < 0) { fprintf(stderr, "Couldn't allocate mechanism scratch!\n"); return; } for (cp = mechstr; *cp; cp++) { if (*cp == '.') *cp = ' '; } tok.value = mechstr; } else { tok.value = mechanism; } tok.length = strlen(tok.value); maj_stat = gss_str_to_oid(&min_stat, &tok, oid); if (maj_stat != GSS_S_COMPLETE) { display_status("str_to_oid", maj_stat, min_stat); return; } if (mechstr) free(mechstr); } static int max_threads = 1; #ifdef _WIN32 static thread_count = 0; static HANDLE hMutex = NULL; static HANDLE hEvent = NULL; void init_handles(void) { hMutex = CreateMutex(NULL, FALSE, NULL); hEvent = CreateEvent(NULL, FALSE, FALSE, NULL); } void cleanup_handles(void) { CloseHandle(hMutex); CloseHandle(hEvent); } BOOL wait_and_increment_thread_counter(void) { for (;;) { if (WaitForSingleObject(hMutex, INFINITE) == WAIT_OBJECT_0) { if (thread_count < max_threads) { thread_count++; ReleaseMutex(hMutex); return TRUE; } else { ReleaseMutex(hMutex); if (WaitForSingleObject(hEvent, INFINITE) == WAIT_OBJECT_0) continue; else return FALSE; } } else { return FALSE; } } } BOOL decrement_and_signal_thread_counter(void) { if (WaitForSingleObject(hMutex, INFINITE) == WAIT_OBJECT_0) { if (thread_count == max_threads) SetEvent(hEvent); thread_count--; ReleaseMutex(hMutex); return TRUE; } else { return FALSE; } } #else /* assume pthread */ static pthread_mutex_t counter_mutex = PTHREAD_MUTEX_INITIALIZER; static pthread_cond_t counter_cond = PTHREAD_COND_INITIALIZER; int counter = 0; static int wait_and_increment_thread_counter(void) { int err; err = pthread_mutex_lock(&counter_mutex); if (err) { perror("pthread_mutex_lock"); return 0; } if (counter == max_threads) { err = pthread_cond_wait(&counter_cond, &counter_mutex); if (err) { pthread_mutex_unlock(&counter_mutex); perror("pthread_cond_wait"); return 0; } } counter++; pthread_mutex_unlock(&counter_mutex); return 1; } static void decrement_and_signal_thread_counter(void) { int err; sleep(1); err = pthread_mutex_lock(&counter_mutex); if (err) { perror("pthread_mutex_lock"); return; } if (counter == max_threads) pthread_cond_broadcast(&counter_cond); counter--; pthread_mutex_unlock(&counter_mutex); } #endif static char *service_name, *server_host, *msg; static char *mechanism = 0; static u_short port = 4444; static int use_file = 0; static OM_uint32 gss_flags = GSS_C_MUTUAL_FLAG | GSS_C_REPLAY_FLAG; static OM_uint32 min_stat; static gss_OID oid = GSS_C_NULL_OID; static int mcount = 1, ccount = 1; static int auth_flag, wrap_flag, encrypt_flag, mic_flag, v1_format; static void * worker_bee(void *unused) { printf("worker bee!\n"); if (call_server(server_host, port, oid, service_name, gss_flags, auth_flag, wrap_flag, encrypt_flag, mic_flag, v1_format, msg, use_file, mcount) < 0) { if (max_threads == 1) exit(6); } if (max_threads > 1) decrement_and_signal_thread_counter(); free(unused); return NULL; } int main(int argc, char **argv) { int i; display_file = stdout; auth_flag = wrap_flag = encrypt_flag = mic_flag = 1; v1_format = 0; /* Parse arguments. */ argc--; argv++; while (argc) { if (strcmp(*argv, "-port") == 0) { argc--; argv++; if (!argc) usage(); port = atoi(*argv); } else if (strcmp(*argv, "-mech") == 0) { argc--; argv++; if (!argc) usage(); mechanism = *argv; } else if (strcmp(*argv, "-threads") == 0) { argc--; argv++; if (!argc) usage(); max_threads = atoi(*argv); } else if (strcmp(*argv, "-d") == 0) { gss_flags |= GSS_C_DELEG_FLAG; } else if (strcmp(*argv, "-seq") == 0) { gss_flags |= GSS_C_SEQUENCE_FLAG; } else if (strcmp(*argv, "-noreplay") == 0) { gss_flags &= ~GSS_C_REPLAY_FLAG; } else if (strcmp(*argv, "-nomutual") == 0) { gss_flags &= ~GSS_C_MUTUAL_FLAG; } else if (strcmp(*argv, "-f") == 0) { use_file = 1; } else if (strcmp(*argv, "-q") == 0) { verbose = 0; } else if (strcmp(*argv, "-ccount") == 0) { argc--; argv++; if (!argc) usage(); ccount = atoi(*argv); if (ccount <= 0) usage(); } else if (strcmp(*argv, "-mcount") == 0) { argc--; argv++; if (!argc) usage(); mcount = atoi(*argv); if (mcount < 0) usage(); } else if (strcmp(*argv, "-na") == 0) { auth_flag = wrap_flag = encrypt_flag = mic_flag = 0; } else if (strcmp(*argv, "-nw") == 0) { wrap_flag = 0; } else if (strcmp(*argv, "-nx") == 0) { encrypt_flag = 0; } else if (strcmp(*argv, "-nm") == 0) { mic_flag = 0; } else if (strcmp(*argv, "-v1") == 0) { v1_format = 1; } else { break; } argc--; argv++; } if (argc != 3) usage(); #ifdef _WIN32 if (max_threads < 1) { fprintf(stderr, "warning: there must be at least one thread\n"); max_threads = 1; } init_handles(); SetEnvironmentVariable("KERBEROSLOGIN_NEVER_PROMPT", "1"); #endif server_host = *argv++; service_name = *argv++; msg = *argv++; if (mechanism) parse_oid(mechanism, &oid); if (get_server_info(server_host, port) < 0) exit(1); if (max_threads == 1) { for (i = 0; i < ccount; i++) worker_bee(0); } else { for (i = 0; i < ccount; i++) { if (wait_and_increment_thread_counter()) { #ifdef _WIN32 uintptr_t handle = _beginthread(worker_bee, 0, (void *)NULL); if (handle == (uintptr_t)-1) exit(7); #else int err; pthread_t thr; err = pthread_create(&thr, 0, worker_bee, malloc(12)); if (err) { perror("pthread_create"); exit(7); } (void)pthread_detach(thr); #endif } else { exit(8); } } } if (oid != GSS_C_NULL_OID) (void)gss_release_oid(&min_stat, &oid); #ifdef _WIN32 cleanup_handles(); #else if (max_threads > 1) sleep(10); #endif return 0; } krb5-1.16/src/tests/gss-threads/gss-server.c0000644000704600001450000006134013211554426020623 0ustar ghudsonlibuuid/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* * Copyright 1994 by OpenVision Technologies, Inc. * * Permission to use, copy, modify, distribute, and sell this software * and its documentation for any purpose is hereby granted without fee, * provided that the above copyright notice appears in all copies and * that both that copyright notice and this permission notice appear in * supporting documentation, and that the name of OpenVision not be used * in advertising or publicity pertaining to distribution of the software * without specific, written prior permission. OpenVision makes no * representations about the suitability of this software for any * purpose. It is provided "as is" without express or implied warranty. * * OPENVISION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO * EVENT SHALL OPENVISION BE LIABLE FOR ANY SPECIAL, INDIRECT OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* * Copyright (C) 2004,2008 by the Massachusetts Institute of Technology. * All rights reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #include "autoconf.h" #include #ifdef _WIN32 #include #include #else #include #include #include #include #include #include #endif #ifdef HAVE_UNISTD_H #include #endif #include #include #include #include "gss-misc.h" #include "port-sockets.h" #ifdef HAVE_STRING_H #include #else #include #endif static void usage() { fprintf(stderr, "Usage: gss-server [-port port] [-verbose] [-once]"); #ifdef _WIN32 fprintf(stderr, " [-threads num]"); #endif fprintf(stderr, "\n"); fprintf(stderr, " [-inetd] [-export] [-logfile file] " "service_name\n"); exit(1); } FILE *logfile; int verbose = 0; /* * Function: server_acquire_creds * * Purpose: imports a service name and acquires credentials for it * * Arguments: * * service_name (r) the ASCII service name * server_creds (w) the GSS-API service credentials * * Returns: 0 on success, -1 on failure * * Effects: * * The service name is imported with gss_import_name, and service * credentials are acquired with gss_acquire_cred. If either opertion * fails, an error message is displayed and -1 is returned; otherwise, * 0 is returned. */ static int server_acquire_creds(char *service_name, gss_cred_id_t *server_creds) { gss_buffer_desc name_buf; gss_name_t server_name; OM_uint32 maj_stat, min_stat; name_buf.value = service_name; name_buf.length = strlen(name_buf.value) + 1; maj_stat = gss_import_name(&min_stat, &name_buf, (gss_OID)gss_nt_service_name, &server_name); if (maj_stat != GSS_S_COMPLETE) { display_status("importing name", maj_stat, min_stat); return -1; } maj_stat = gss_acquire_cred(&min_stat, server_name, 0, GSS_C_NULL_OID_SET, GSS_C_ACCEPT, server_creds, NULL, NULL); if (maj_stat != GSS_S_COMPLETE) { display_status("acquiring credentials", maj_stat, min_stat); return -1; } (void)gss_release_name(&min_stat, &server_name); return 0; } /* * Function: server_establish_context * * Purpose: establishses a GSS-API context as a specified service with * an incoming client, and returns the context handle and associated * client name * * Arguments: * * s (r) an established TCP connection to the client * service_creds (r) server credentials, from gss_acquire_cred * context (w) the established GSS-API context * client_name (w) the client's ASCII name * * Returns: 0 on success, -1 on failure * * Effects: * * Any valid client request is accepted. If a context is established, * its handle is returned in context and the client name is returned * in client_name and 0 is returned. If unsuccessful, an error * message is displayed and -1 is returned. */ static int server_establish_context(int s, gss_cred_id_t server_creds, gss_ctx_id_t *context, gss_buffer_t client_name, OM_uint32 *ret_flags) { gss_buffer_desc send_tok, recv_tok, oid_name; gss_name_t client; gss_OID doid; OM_uint32 maj_stat, min_stat, acc_sec_min_stat; int token_flags; if (recv_token(s, &token_flags, &recv_tok) < 0) return -1; if (recv_tok.value) { free(recv_tok.value); recv_tok.value = NULL; } if (!(token_flags & TOKEN_NOOP)) { if (logfile) { fprintf(logfile, "Expected NOOP token, got %d token instead\n", token_flags); } return -1; } *context = GSS_C_NO_CONTEXT; if (token_flags & TOKEN_CONTEXT_NEXT) { do { if (recv_token(s, &token_flags, &recv_tok) < 0) return -1; if (verbose && logfile) { fprintf(logfile, "Received token (size=%d): \n", (int)recv_tok.length); print_token(&recv_tok); } maj_stat = gss_accept_sec_context(&acc_sec_min_stat, context, server_creds, &recv_tok, GSS_C_NO_CHANNEL_BINDINGS, &client, &doid, &send_tok, ret_flags, NULL, NULL); if (recv_tok.value) { free(recv_tok.value); recv_tok.value = NULL; } if (send_tok.length != 0) { if (verbose && logfile) { fprintf(logfile, "Sending accept_sec_context token (size=%d):\n", (int)send_tok.length); print_token(&send_tok); } if (send_token(s, TOKEN_CONTEXT, &send_tok) < 0) { if (logfile) fprintf(logfile, "failure sending token\n"); return -1; } (void)gss_release_buffer(&min_stat, &send_tok); } if (maj_stat != GSS_S_COMPLETE && maj_stat != GSS_S_CONTINUE_NEEDED) { display_status("accepting context", maj_stat, acc_sec_min_stat); if (*context != GSS_C_NO_CONTEXT) { gss_delete_sec_context(&min_stat, context, GSS_C_NO_BUFFER); } return -1; } if (verbose && logfile) { if (maj_stat == GSS_S_CONTINUE_NEEDED) fprintf(logfile, "continue needed...\n"); else fprintf(logfile, "\n"); fflush(logfile); } } while (maj_stat == GSS_S_CONTINUE_NEEDED); /* display the flags */ display_ctx_flags(*ret_flags); if (verbose && logfile) { maj_stat = gss_oid_to_str(&min_stat, doid, &oid_name); if (maj_stat != GSS_S_COMPLETE) { display_status("converting oid->string", maj_stat, min_stat); return -1; } fprintf(logfile, "Accepted connection using mechanism OID %.*s.\n", (int)oid_name.length, (char *)oid_name.value); (void)gss_release_buffer(&min_stat, &oid_name); } maj_stat = gss_display_name(&min_stat, client, client_name, &doid); if (maj_stat != GSS_S_COMPLETE) { display_status("displaying name", maj_stat, min_stat); return -1; } maj_stat = gss_release_name(&min_stat, &client); if (maj_stat != GSS_S_COMPLETE) { display_status("releasing name", maj_stat, min_stat); return -1; } } else { client_name->length = *ret_flags = 0; if (logfile) fprintf(logfile, "Accepted unauthenticated connection.\n"); } return 0; } /* * Function: create_socket * * Purpose: Opens a listening TCP socket. * * Arguments: * * port (r) the port number on which to listen * * Returns: the listening socket file descriptor, or -1 on failure * * Effects: * * A listening socket on the specified port and created and returned. * On error, an error message is displayed and -1 is returned. */ static int create_socket(u_short port) { struct sockaddr_in saddr; int s, on = 1; saddr.sin_family = AF_INET; saddr.sin_port = htons(port); saddr.sin_addr.s_addr = INADDR_ANY; s = socket(AF_INET, SOCK_STREAM, 0); if (s < 0) { perror("creating socket"); return -1; } /* Let the socket be reused right away. */ (void)setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof(on)); if (bind(s, (struct sockaddr *)&saddr, sizeof(saddr)) < 0) { perror("binding socket"); (void)close(s); return -1; } if (listen(s, 5) < 0) { perror("listening on socket"); (void)close(s); return -1; } return s; } static float timeval_subtract(struct timeval *tv1, struct timeval *tv2) { return ((tv1->tv_sec - tv2->tv_sec) + ((float)(tv1->tv_usec - tv2->tv_usec)) / 1000000); } /* * Yes, yes, this isn't the best place for doing this test. * DO NOT REMOVE THIS UNTIL A BETTER TEST HAS BEEN WRITTEN, THOUGH. * -TYT */ static int test_import_export_context(gss_ctx_id_t *context) { OM_uint32 min_stat, maj_stat; gss_buffer_desc context_token, copied_token; struct timeval tm1, tm2; /* Attempt to save and then restore the context. */ gettimeofday(&tm1, (struct timezone *)0); maj_stat = gss_export_sec_context(&min_stat, context, &context_token); if (maj_stat != GSS_S_COMPLETE) { display_status("exporting context", maj_stat, min_stat); return 1; } gettimeofday(&tm2, NULL); if (verbose && logfile) { fprintf(logfile, "Exported context: %d bytes, %7.4f seconds\n", (int)context_token.length, timeval_subtract(&tm2, &tm1)); } copied_token.length = context_token.length; copied_token.value = malloc(context_token.length); if (copied_token.value == 0) { if (logfile) { fprintf(logfile, "Couldn't allocate memory to copy context " "token.\n"); } return 1; } memcpy(copied_token.value, context_token.value, copied_token.length); maj_stat = gss_import_sec_context(&min_stat, &copied_token, context); if (maj_stat != GSS_S_COMPLETE) { display_status("importing context", maj_stat, min_stat); return 1; } free(copied_token.value); gettimeofday(&tm1, NULL); if (verbose && logfile) { fprintf(logfile, "Importing context: %7.4f seconds\n", timeval_subtract(&tm1, &tm2)); } (void)gss_release_buffer(&min_stat, &context_token); return 0; } /* * Function: sign_server * * Purpose: Performs the "sign" service. * * Arguments: * * s (r) a TCP socket on which a connection has been * accept()ed * service_name (r) the ASCII name of the GSS-API service to * establish a context as * export (r) whether to test context exporting * * Returns: -1 on error * * Effects: * * sign_server establishes a context, and performs a single sign request. * * A sign request is a single GSS-API sealed token. The token is * unsealed and a signature block, produced with gss_sign, is returned * to the sender. The context is the destroyed and the connection * closed. * * If any error occurs, -1 is returned. */ static int sign_server(int s, gss_cred_id_t server_creds, int export) { gss_buffer_desc client_name, xmit_buf, msg_buf; gss_ctx_id_t context; OM_uint32 maj_stat, min_stat, ret_flags; int i, conf_state, token_flags; char *cp; /* Establish a context with the client */ if (server_establish_context(s, server_creds, &context, &client_name, &ret_flags) < 0) return -1; if (context == GSS_C_NO_CONTEXT) { printf("Accepted unauthenticated connection.\n"); } else { printf("Accepted connection: \"%.*s\"\n", (int)client_name.length, (char *)client_name.value); (void)gss_release_buffer(&min_stat, &client_name); if (export) { for (i = 0; i < 3; i++) { if (test_import_export_context(&context)) return -1; } } } do { /* Receive the message token */ if (recv_token(s, &token_flags, &xmit_buf) < 0) return -1; if (token_flags & TOKEN_NOOP) { if (logfile) fprintf(logfile, "NOOP token\n"); if (xmit_buf.value) { free(xmit_buf.value); xmit_buf.value = 0; } break; } if (verbose && logfile) { fprintf(logfile, "Message token (flags=%d):\n", token_flags); print_token(&xmit_buf); } if (context == GSS_C_NO_CONTEXT && (token_flags & (TOKEN_WRAPPED | TOKEN_ENCRYPTED | TOKEN_SEND_MIC))) { if (logfile) { fprintf(logfile, "Unauthenticated client requested " "authenticated services!\n"); } if (xmit_buf.value) { free(xmit_buf.value); xmit_buf.value = 0; } return -1; } if (token_flags & TOKEN_WRAPPED) { maj_stat = gss_unwrap(&min_stat, context, &xmit_buf, &msg_buf, &conf_state, NULL); if (maj_stat != GSS_S_COMPLETE) { display_status("unsealing message", maj_stat, min_stat); if (xmit_buf.value) { free(xmit_buf.value); xmit_buf.value = 0; } return -1; } else if (!conf_state && (token_flags & TOKEN_ENCRYPTED)) { fprintf(stderr, "Warning! Message not encrypted.\n"); } if (xmit_buf.value) { free(xmit_buf.value); xmit_buf.value = 0; } } else { msg_buf = xmit_buf; } if (logfile) { fprintf(logfile, "Received message: "); cp = msg_buf.value; if (isprint((unsigned char)cp[0]) && isprint((unsigned char)cp[1])) { fprintf(logfile, "\"%.*s\"\n", (int)msg_buf.length, (char *)msg_buf.value); } else { fprintf(logfile, "\n"); print_token(&msg_buf); } } if (token_flags & TOKEN_SEND_MIC) { /* Produce a signature block for the message. */ maj_stat = gss_get_mic(&min_stat, context, GSS_C_QOP_DEFAULT, &msg_buf, &xmit_buf); if (maj_stat != GSS_S_COMPLETE) { display_status("signing message", maj_stat, min_stat); return -1; } if (msg_buf.value) { free(msg_buf.value); msg_buf.value = 0; } /* Send the signature block to the client. */ if (send_token(s, TOKEN_MIC, &xmit_buf) < 0) return -1; if (xmit_buf.value) { free(xmit_buf.value); xmit_buf.value = 0; } } else { if (msg_buf.value) { free(msg_buf.value); msg_buf.value = 0; } if (send_token(s, TOKEN_NOOP, empty_token) < 0) return -1; } } while (1 /* loop will break if NOOP received */); if (context != GSS_C_NO_CONTEXT) { /* Delete context. */ maj_stat = gss_delete_sec_context(&min_stat, &context, NULL); if (maj_stat != GSS_S_COMPLETE) { display_status("deleting context", maj_stat, min_stat); return -1; } } if (logfile) fflush(logfile); return 0; } static int max_threads = 1; #ifdef _WIN32 static thread_count = 0; static HANDLE hMutex = NULL; static HANDLE hEvent = NULL; void init_handles(void) { hMutex = CreateMutex(NULL, FALSE, NULL); hEvent = CreateEvent(NULL, FALSE, FALSE, NULL); } void cleanup_handles(void) { CloseHandle(hMutex); CloseHandle(hEvent); } BOOL wait_and_increment_thread_counter(void) { for (;;) { if (WaitForSingleObject(hMutex, INFINITE) == WAIT_OBJECT_0) { if (thread_count < max_threads) { thread_count++; ReleaseMutex(hMutex); return TRUE; } else { ReleaseMutex(hMutex); if (WaitForSingleObject(hEvent, INFINITE) == WAIT_OBJECT_0) continue; else return FALSE; } } else { return FALSE; } } } BOOL decrement_and_signal_thread_counter(void) { if (WaitForSingleObject(hMutex, INFINITE) == WAIT_OBJECT_0) { if (thread_count == max_threads) SetEvent(hEvent); thread_count--; ReleaseMutex(hMutex); return TRUE; } else { return FALSE; } } #else /* assume pthread */ static pthread_mutex_t counter_mutex = PTHREAD_MUTEX_INITIALIZER; static pthread_cond_t counter_cond = PTHREAD_COND_INITIALIZER; int counter = 0; static int wait_and_increment_thread_counter(void) { int err; err = pthread_mutex_lock(&counter_mutex); if (err) { perror("pthread_mutex_lock"); return 0; } if (counter == max_threads) { err = pthread_cond_wait(&counter_cond, &counter_mutex); if (err) { pthread_mutex_unlock(&counter_mutex); perror("pthread_cond_wait"); return 0; } } counter++; pthread_mutex_unlock(&counter_mutex); return 1; } static void decrement_and_signal_thread_counter(void) { int err; err = pthread_mutex_lock(&counter_mutex); if (err) { perror("pthread_mutex_lock"); return; } if (counter == max_threads) pthread_cond_broadcast(&counter_cond); counter--; pthread_mutex_unlock(&counter_mutex); } #endif struct _work_plan { int s; gss_cred_id_t server_creds; int export; }; static void * worker_bee(void *param) { struct _work_plan *work = param; /* This return value is not checked, because there's not really anything to * do if it fails. */ sign_server(work->s, work->server_creds, work->export); closesocket(work->s); free(work); #if defined _WIN32 || 1 if (max_threads > 1) decrement_and_signal_thread_counter(); #endif return NULL; } int main(int argc, char **argv) { char *service_name; gss_cred_id_t server_creds; OM_uint32 min_stat; u_short port = 4444; int once = 0; int do_inetd = 0; int export = 0; signal(SIGPIPE, SIG_IGN); logfile = stdout; display_file = stdout; argc--; argv++; while (argc) { if (strcmp(*argv, "-port") == 0) { argc--; argv++; if (!argc) usage(); port = atoi(*argv); } else if (strcmp(*argv, "-threads") == 0) { argc--; argv++; if (!argc) usage(); max_threads = atoi(*argv); } else if (strcmp(*argv, "-verbose") == 0) { verbose = 1; } else if (strcmp(*argv, "-once") == 0) { once = 1; } else if (strcmp(*argv, "-inetd") == 0) { do_inetd = 1; } else if (strcmp(*argv, "-export") == 0) { export = 1; } else if (strcmp(*argv, "-logfile") == 0) { argc--; argv++; if (!argc) usage(); /* * Gross hack, but it makes it unnecessary to add an extra argument * to disable logging, and makes the code more efficient because it * doesn't actually write data to /dev/null. */ if (!strcmp(*argv, "/dev/null")) { logfile = display_file = NULL; } else { logfile = fopen(*argv, "a"); display_file = logfile; if (!logfile) { perror(*argv); exit(1); } } } else { break; } argc--; argv++; } if (argc != 1) usage(); if ((*argv)[0] == '-') usage(); #ifdef _WIN32 if (max_threads < 1) { fprintf(stderr, "warning: there must be at least one thread\n"); max_threads = 1; } if (max_threads > 1 && do_inetd) { fprintf(stderr, "warning: one thread may be used in conjunction " "with inetd\n"); } init_handles(); #endif service_name = *argv; if (server_acquire_creds(service_name, &server_creds) < 0) return -1; if (do_inetd) { close(1); close(2); sign_server(0, server_creds, export); close(0); } else { int stmp; stmp = create_socket(port); if (stmp >= 0) { if (listen(stmp, max_threads == 1 ? 0 : max_threads) < 0) perror("listening on socket"); do { struct _work_plan * work = malloc(sizeof(struct _work_plan)); if (work == NULL) { fprintf(stderr, "fatal error: out of memory"); break; } /* Accept a TCP connection */ work->s = accept(stmp, NULL, 0); if (work->s < 0) { perror("accepting connection"); continue; } work->server_creds = server_creds; work->export = export; if (max_threads == 1) { worker_bee(work); } else { if (wait_and_increment_thread_counter()) { #ifdef _WIN32 uintptr_t handle = _beginthread(worker_bee, 0, work); if (handle == (uintptr_t)-1) { closesocket(work->s); free(work); } #else int err; pthread_t thr; err = pthread_create(&thr, 0, worker_bee, work); if (err) { perror("pthread_create"); closesocket(work->s); free(work); } (void)pthread_detach(thr); #endif } else { fprintf(stderr, "fatal error incrementing thread " "counter"); closesocket(work->s); free(work); break; } } } while (!once); closesocket(stmp); } } (void)gss_release_cred(&min_stat, &server_creds); #ifdef _WIN32 cleanup_handles(); #else if (max_threads > 1) { while (1) sleep(999999); } #endif return 0; } krb5-1.16/src/tests/gss-threads/deps0000644000704600001450000000154113211554426017232 0ustar ghudsonlibuuid# # Generated makefile dependencies follow. # $(OUTPRE)gss-client.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/gssapi/gssapi.h $(BUILDTOP)/include/gssapi/gssapi_generic.h \ $(top_srcdir)/include/fake-addrinfo.h $(top_srcdir)/include/k5-platform.h \ $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/port-sockets.h \ $(top_srcdir)/include/socket-utils.h gss-client.c gss-misc.h $(OUTPRE)gss-misc.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/gssapi/gssapi.h $(BUILDTOP)/include/gssapi/gssapi_generic.h \ $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-thread.h \ gss-misc.c gss-misc.h $(OUTPRE)gss-server.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/gssapi/gssapi.h $(BUILDTOP)/include/gssapi/gssapi_generic.h \ $(top_srcdir)/include/port-sockets.h gss-misc.h gss-server.c krb5-1.16/src/tests/gss-threads/gss-misc.c0000644000704600001450000002652113211554426020252 0ustar ghudsonlibuuid/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* * Copyright 1994 by OpenVision Technologies, Inc. * * Permission to use, copy, modify, distribute, and sell this software * and its documentation for any purpose is hereby granted without fee, * provided that the above copyright notice appears in all copies and * that both that copyright notice and this permission notice appear in * supporting documentation, and that the name of OpenVision not be used * in advertising or publicity pertaining to distribution of the software * without specific, written prior permission. OpenVision makes no * representations about the suitability of this software for any * purpose. It is provided "as is" without express or implied warranty. * * OPENVISION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO * EVENT SHALL OPENVISION BE LIABLE FOR ANY SPECIAL, INDIRECT OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* * Copyright (C) 2003, 2004 by the Massachusetts Institute of Technology. * All rights reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #include "autoconf.h" #include #ifdef _WIN32 #include #include #else #include #include #include #endif #include #ifdef HAVE_UNISTD_H #include #endif #include /* need struct timeval */ #if HAVE_TIME_H && (!HAVE_SYS_TIME_H || TIME_WITH_SYS_TIME) # include #endif #if HAVE_SYS_TIME_H # include #endif #include #include "gss-misc.h" /* for store_32_be */ #include "k5-platform.h" #ifdef HAVE_STDLIB_H #include #else extern char *malloc(); #endif FILE *display_file; gss_buffer_desc empty_token_buf = { 0, (void *)"" }; gss_buffer_t empty_token = &empty_token_buf; static void display_status_1(char *m, OM_uint32 code, int type); static int write_all(int fildes, char *buf, unsigned int nbyte) { int ret; char *ptr; for (ptr = buf; nbyte; ptr += ret, nbyte -= ret) { ret = send(fildes, ptr, nbyte, 0); if (ret < 0) { if (errno == EINTR) continue; return ret; } else if (ret == 0) { return ptr - buf; } } return ptr - buf; } static int read_all(int fildes, char *buf, unsigned int nbyte) { int ret; char *ptr; fd_set rfds; struct timeval tv; FD_ZERO(&rfds); FD_SET(fildes, &rfds); tv.tv_sec = 10; tv.tv_usec = 0; for (ptr = buf; nbyte; ptr += ret, nbyte -= ret) { if (select(FD_SETSIZE, &rfds, NULL, NULL, &tv) <= 0 || !FD_ISSET(fildes, &rfds)) return ptr - buf; ret = recv(fildes, ptr, nbyte, 0); if (ret < 0) { if (errno == EINTR) continue; return ret; } else if (ret == 0) { return ptr - buf; } } return ptr - buf; } /* * Function: send_token * * Purpose: Writes a token to a file descriptor. * * Arguments: * * s (r) an open file descriptor * flags (r) the flags to write * tok (r) the token to write * * Returns: 0 on success, -1 on failure * * Effects: * * If the flags are non-null, send_token writes the token flags (a * single byte, even though they're passed in in an integer). Next, * the token length (as a network long) and then the token data are * written to the file descriptor s. It returns 0 on success, and -1 * if an error occurs or if it could not write all the data. */ int send_token(int s, int flags, gss_buffer_t tok) { int ret; unsigned char char_flags = (unsigned char)flags; unsigned char lenbuf[4]; if (char_flags) { ret = write_all(s, (char *)&char_flags, 1); if (ret != 1) { perror("sending token flags"); return -1; } } if (tok->length > 0xffffffffUL) abort(); store_32_be(tok->length, lenbuf); ret = write_all(s, (char *)lenbuf, 4); if (ret < 0) { perror("sending token length"); return -1; } else if (ret != 4) { if (display_file) { fprintf(display_file, "sending token length: %d of %d bytes written\n", ret, 4); } return -1; } ret = write_all(s, tok->value, tok->length); if (ret < 0) { perror("sending token data"); return -1; } else if ((size_t)ret != tok->length) { if (display_file) { fprintf(display_file, "sending token data: %d of %d bytes written\n", ret, (int)tok->length); } return -1; } return 0; } /* * Function: recv_token * * Purpose: Reads a token from a file descriptor. * * Arguments: * * s (r) an open file descriptor * flags (w) the read flags * tok (w) the read token * * Returns: 0 on success, -1 on failure * * Effects: * * recv_token reads the token flags (a single byte, even though * they're stored into an integer, then reads the token length (as a * network long), allocates memory to hold the data, and then reads * the token data from the file descriptor s. It blocks to read the * length and data, if necessary. On a successful return, the token * should be freed with gss_release_buffer. It returns 0 on success, * and -1 if an error occurs or if it could not read all the data. */ int recv_token(int s, int *flags, gss_buffer_t tok) { int ret; unsigned char char_flags; unsigned char lenbuf[4]; ret = read_all(s, (char *)&char_flags, 1); if (ret < 0) { perror("reading token flags"); return -1; } else if (!ret) { if (display_file) fputs("reading token flags: 0 bytes read\n", display_file); return -1; } else { *flags = char_flags; } if (char_flags == 0) { lenbuf[0] = 0; ret = read_all(s, (char *)&lenbuf[1], 3); if (ret < 0) { perror("reading token length"); return -1; } else if (ret != 3) { if (display_file) { fprintf(display_file, "reading token length: %d of %d bytes read\n", ret, 3); } return -1; } } else { ret = read_all(s, (char *)lenbuf, 4); if (ret < 0) { perror("reading token length"); return -1; } else if (ret != 4) { if (display_file) { fprintf(display_file, "reading token length: %d of %d bytes read\n", ret, 4); } return -1; } } tok->length = load_32_be(lenbuf); tok->value = malloc(tok->length ? tok->length : 1); if (tok->length && tok->value == NULL) { if (display_file) fprintf(display_file, "Out of memory allocating token data\n"); return -1; } ret = read_all(s, (char *)tok->value, tok->length); if (ret < 0) { perror("reading token data"); free(tok->value); return -1; } else if ((size_t)ret != tok->length) { fprintf(stderr, "sending token data: %d of %d bytes written\n", ret, (int)tok->length); free(tok->value); return -1; } return 0; } static void display_status_1(char *m, OM_uint32 code, int type) { OM_uint32 min_stat; gss_buffer_desc msg; OM_uint32 msg_ctx; msg_ctx = 0; while (1) { (void)gss_display_status(&min_stat, code, type, GSS_C_NULL_OID, &msg_ctx, &msg); if (display_file) { fprintf(display_file, "GSS-API error %s: %s\n", m, (char *)msg.value); } (void)gss_release_buffer(&min_stat, &msg); if (!msg_ctx) break; } } /* * Function: display_status * * Purpose: displays GSS-API messages * * Arguments: * * msg a string to be displayed with the message * maj_stat the GSS-API major status code * min_stat the GSS-API minor status code * * Effects: * * The GSS-API messages associated with maj_stat and min_stat are * displayed on stderr, each preceeded by "GSS-API error : " and * followed by a newline. */ void display_status(char *msg, OM_uint32 maj_stat, OM_uint32 min_stat) { display_status_1(msg, maj_stat, GSS_C_GSS_CODE); display_status_1(msg, min_stat, GSS_C_MECH_CODE); } /* * Function: display_ctx_flags * * Purpose: displays the flags returned by context initation in * a human-readable form * * Arguments: * * int ret_flags * * Effects: * * Strings corresponding to the context flags are printed on * stdout, preceded by "context flag: " and followed by a newline */ void display_ctx_flags(OM_uint32 flags) { if (flags & GSS_C_DELEG_FLAG) fprintf(display_file, "context flag: GSS_C_DELEG_FLAG\n"); if (flags & GSS_C_MUTUAL_FLAG) fprintf(display_file, "context flag: GSS_C_MUTUAL_FLAG\n"); if (flags & GSS_C_REPLAY_FLAG) fprintf(display_file, "context flag: GSS_C_REPLAY_FLAG\n"); if (flags & GSS_C_SEQUENCE_FLAG) fprintf(display_file, "context flag: GSS_C_SEQUENCE_FLAG\n"); if (flags & GSS_C_CONF_FLAG) fprintf(display_file, "context flag: GSS_C_CONF_FLAG \n"); if (flags & GSS_C_INTEG_FLAG) fprintf(display_file, "context flag: GSS_C_INTEG_FLAG \n"); } void print_token(gss_buffer_t tok) { size_t i; unsigned char *p = tok->value; if (!display_file) return; for (i = 0; i < tok->length; i++, p++) { fprintf(display_file, "%02x ", *p); if (i % 16 == 15) { fprintf(display_file, "\n"); } } fprintf(display_file, "\n"); fflush(display_file); } #ifdef _WIN32 #include #include int gettimeofday(struct timeval *tv, void *ignore_tz) { struct _timeb tb; _tzset(); _ftime(&tb); if (tv) { tv->tv_sec = tb.time; tv->tv_usec = tb.millitm * 1000; } return 0; } #endif /* _WIN32 */ krb5-1.16/src/tests/gss-threads/Makefile.in0000644000704600001450000000237113211554426020423 0ustar ghudsonlibuuid# Derived from appl/gss-sample, January 2005. mydir=tests$(S)gss-threads BUILDTOP=$(REL)..$(S).. DEFINES = -DUSE_AUTOCONF_H -DGSSAPI_V2 PTHREAD_LIBS=@PTHREAD_LIBS@ SRCS= $(srcdir)/gss-client.c $(srcdir)/gss-misc.c $(srcdir)/gss-server.c OBJS= gss-client.o gss-misc.o gss-server.o all-unix: all-unix-@THREAD_SUPPORT@ all-unix-1: gss-server gss-client all-unix-0: all-windows: $(OUTPRE)gss-server.exe $(OUTPRE)gss-client.exe gss-server: gss-server.o gss-misc.o $(GSS_DEPLIBS) $(KRB5_BASE_DEPLIBS) $(CC_LINK) $(PTHREAD_CFLAGS) -o gss-server gss-server.o gss-misc.o $(GSS_LIBS) $(KRB5_BASE_LIBS) $(THREAD_LINKOPTS) gss-client: gss-client.o gss-misc.o $(GSS_DEPLIBS) $(KRB5_BASE_DEPLIBS) $(CC_LINK) $(PTHREAD_CFLAGS) -o gss-client gss-client.o gss-misc.o $(GSS_LIBS) $(KRB5_BASE_LIBS) $(THREAD_LINKOPTS) $(OUTPRE)gss-server.exe: $(OUTPRE)gss-server.obj $(OUTPRE)gss-misc.obj $(GLIB) $(KLIB) link $(EXE_LINKOPTS) -out:$@ $** ws2_32.lib $(OUTPRE)gss-client.exe: $(OUTPRE)gss-client.obj $(OUTPRE)gss-misc.obj $(GLIB) $(KLIB) link $(EXE_LINKOPTS) -out:$@ $** ws2_32.lib clean-unix:: $(RM) gss-server gss-client install-unix: # $(INSTALL_PROGRAM) gss-client $(DESTDIR)$(CLIENT_BINDIR)/gss-tclient # $(INSTALL_PROGRAM) gss-server $(DESTDIR)$(SERVER_BINDIR)/gss-tserver krb5-1.16/src/tests/t_policy.py0000755000704600001450000001524713211554426016337 0ustar ghudsonlibuuid#!/usr/bin/python from k5test import * import re realm = K5Realm(create_host=False, start_kadmind=True) # Test password quality enforcement. realm.run([kadminl, 'addpol', '-minlength', '6', '-minclasses', '2', 'pwpol']) realm.run([kadminl, 'addprinc', '-randkey', '-policy', 'pwpol', 'pwuser']) realm.run([kadminl, 'cpw', '-pw', 'sh0rt', 'pwuser'], expected_code=1, expected_msg='Password is too short') realm.run([kadminl, 'cpw', '-pw', 'longenough', 'pwuser'], expected_code=1, expected_msg='Password does not contain enough character classes') realm.run([kadminl, 'cpw', '-pw', 'l0ngenough', 'pwuser']) # Test some password history enforcement. Even with no history value, # the current password should be denied. realm.run([kadminl, 'cpw', '-pw', 'l0ngenough', 'pwuser'], expected_code=1, expected_msg='Cannot reuse password') realm.run([kadminl, 'modpol', '-history', '2', 'pwpol']) realm.run([kadminl, 'cpw', '-pw', 'an0therpw', 'pwuser']) realm.run([kadminl, 'cpw', '-pw', 'l0ngenough', 'pwuser'], expected_code=1, expected_msg='Cannot reuse password') realm.run([kadminl, 'cpw', '-pw', '3rdpassword', 'pwuser']) realm.run([kadminl, 'cpw', '-pw', 'l0ngenough', 'pwuser']) # Test references to nonexistent policies. realm.run([kadminl, 'addprinc', '-randkey', '-policy', 'newpol', 'newuser']) realm.run([kadminl, 'getprinc', 'newuser'], expected_msg='Policy: newpol [does not exist]\n') realm.run([kadminl, 'modprinc', '-policy', 'newpol', 'pwuser']) # pwuser should allow reuse of the current password since newpol doesn't exist. realm.run([kadminl, 'cpw', '-pw', '3rdpassword', 'pwuser']) # Regression test for #8427 (min_life check with nonexistent policy). realm.run([kadmin, '-p', 'pwuser', '-w', '3rdpassword', 'cpw', '-pw', '3rdpassword', 'pwuser']) # Create newpol and verify that it is enforced. realm.run([kadminl, 'addpol', '-minlength', '3', 'newpol']) realm.run([kadminl, 'getprinc', 'pwuser'], expected_msg='Policy: newpol\n') realm.run([kadminl, 'cpw', '-pw', 'aa', 'pwuser'], expected_code=1, expected_msg='Password is too short') realm.run([kadminl, 'cpw', '-pw', '3rdpassword', 'pwuser'], expected_code=1, expected_msg='Cannot reuse password') realm.run([kadminl, 'getprinc', 'newuser'], expected_msg='Policy: newpol\n') realm.run([kadminl, 'cpw', '-pw', 'aa', 'newuser'], expected_code=1, expected_msg='Password is too short') # Delete the policy and verify that it is no longer enforced. realm.run([kadminl, 'delpol', 'newpol']) realm.run([kadminl, 'getpol', 'newpol'], expected_code=1, expected_msg='Policy does not exist') realm.run([kadminl, 'cpw', '-pw', 'aa', 'pwuser']) # Test basic password lockout support. realm.run([kadminl, 'addpol', '-maxfailure', '2', '-failurecountinterval', '5m', 'lockout']) realm.run([kadminl, 'modprinc', '+requires_preauth', '-policy', 'lockout', 'user']) # kinit twice with the wrong password. realm.run([kinit, realm.user_princ], input='wrong\n', expected_code=1, expected_msg='Password incorrect while getting initial credentials') realm.run([kinit, realm.user_princ], input='wrong\n', expected_code=1, expected_msg='Password incorrect while getting initial credentials') # Now the account should be locked out. m = 'Client\'s credentials have been revoked while getting initial credentials' realm.run([kinit, realm.user_princ], expected_code=1, expected_msg=m) # Check that modprinc -unlock allows a further attempt. realm.run([kadminl, 'modprinc', '-unlock', 'user']) realm.kinit(realm.user_princ, password('user')) # Make sure a nonexistent policy reference doesn't prevent authentication. realm.run([kadminl, 'delpol', 'lockout']) realm.kinit(realm.user_princ, password('user')) # Regression test for issue #7099: databases created prior to krb5 1.3 have # multiple history keys, and kadmin prior to 1.7 didn't necessarily use the # first one to create history entries. realm.stop() realm = K5Realm(start_kdc=False) # Create a history principal with two keys. realm.run(['./hist', 'make']) realm.run([kadminl, 'addpol', '-history', '2', 'pol']) realm.run([kadminl, 'modprinc', '-policy', 'pol', 'user']) realm.run([kadminl, 'cpw', '-pw', 'pw2', 'user']) # Swap the keys, simulating older kadmin having chosen the second entry. realm.run(['./hist', 'swap']) # Make sure we can read the history entry. realm.run([kadminl, 'cpw', '-pw', password('user'), 'user'], expected_code=1, expected_msg='Cannot reuse password') # Test key/salt constraints. realm.stop() krb5_conf1 = {'libdefaults': {'supported_enctypes': 'aes256-cts'}} realm = K5Realm(krb5_conf=krb5_conf1, create_host=False, get_creds=False) # Add policy. realm.run([kadminl, 'addpol', '-allowedkeysalts', 'aes256-cts', 'ak']) realm.run([kadminl, 'addprinc', '-randkey', '-e', 'aes256-cts', 'server']) # Test with one-enctype allowed_keysalts. realm.run([kadminl, 'modprinc', '-policy', 'ak', 'server']) out = realm.run([kadminl, 'cpw', '-randkey', '-e', 'aes128-cts', 'server'], expected_code=1) if not 'Invalid key/salt tuples' in out: fail('allowed_keysalts policy not applied properly') realm.run([kadminl, 'cpw', '-randkey', '-e', 'aes256-cts', 'server']) # Now test a multi-enctype allowed_keysalts. Test that subsets are allowed, # the the complete set is allowed, that order doesn't matter, and that # enctypes outside the set are not allowed. # Test modpol. realm.run([kadminl, 'modpol', '-allowedkeysalts', 'aes256-cts,rc4-hmac', 'ak']) realm.run([kadminl, 'getpol', 'ak'], expected_msg='Allowed key/salt types: aes256-cts,rc4-hmac') # Test subsets and full set. realm.run([kadminl, 'cpw', '-randkey', '-e', 'rc4-hmac', 'server']) realm.run([kadminl, 'cpw', '-randkey', '-e', 'aes256-cts', 'server']) realm.run([kadminl, 'cpw', '-randkey', '-e', 'aes256-cts,rc4-hmac', 'server']) realm.run([kadminl, 'cpw', '-randkey', '-e', 'rc4-hmac,aes256-cts', 'server']) # Check that the order we got is the one from the policy. realm.run([kadminl, 'getprinc', '-terse', 'server'], expected_msg='2\t1\t6\t18\t0\t1\t6\t23\t0') # Test partially intersecting sets. realm.run([kadminl, 'cpw', '-randkey', '-e', 'rc4-hmac,aes128-cts', 'server'], expected_code=1, expected_msg='Invalid key/salt tuples') realm.run([kadminl, 'cpw', '-randkey', '-e', 'rc4-hmac,aes256-cts,aes128-cts', 'server'], expected_code=1, expected_msg='Invalid key/salt tuples') # Test reset of allowedkeysalts. realm.run([kadminl, 'modpol', '-allowedkeysalts', '-', 'ak']) out = realm.run([kadminl, 'getpol', 'ak']) if 'Allowed key/salt types' in out: fail('failed to clear allowedkeysalts') realm.run([kadminl, 'cpw', '-randkey', '-e', 'aes128-cts', 'server']) success('Policy tests') krb5-1.16/src/tests/au_dict.json0000644000704600001450000000164213211554426016435 0ustar ghudsonlibuuid{ "event_name":"", "event_success":0, "evidence_tkt_id":"", "fromport":0, "fromaddr":{ "type":0, "length":0, "ip":[]}, "kdc_status":"", "rep_etype":0, "rep.ticket":{ "authtime":0, "cname":{ "components":[], "realm":"", "length":0, "type":0}, "end":0, "flags":0, "sess_etype":0, "srv_etype":0, "sname":{ "components":[], "realm":"", "length":0, "type":0}}, "req.avail_etypes":[], "req.client":{ "components":[], "realm":"", "length":0, "type":0}, "req_id":"", "req.kdc_options":0, "req.pa_type":[], "req.server":{ "components":[], "realm":"", "length":0, "type":0}, "req.tkt_end":0, "s4u2proxy_user":{ "components":[], "realm":"", "length":0, "type":0}, "s4u2self_user":{ "components":[], "realm":"", "length":0, "type":0}, "stage":1, "tkt_in_id":"", "tkt_renewed":0, "tkt_out_id":"", "tkt_validated":0, "u2u_user":{ "components":[], "realm":"", "length":0, "type":0}, "violation":0 } krb5-1.16/src/tests/icred.c0000644000704600001450000000751013211554426015364 0ustar ghudsonlibuuid/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* tests/icred.c - test harness for getting initial creds */ /* * Copyright (C) 2013 by the Massachusetts Institute of Technology. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ /* * This program exercises the init_creds APIs in ways kinit doesn't. Right now * it is very simplistic, but it can be extended as needed. */ #include "k5-platform.h" #include static krb5_context ctx; static void check(krb5_error_code code) { const char *errmsg; if (code) { errmsg = krb5_get_error_message(ctx, code); fprintf(stderr, "%s\n", errmsg); krb5_free_error_message(ctx, errmsg); exit(1); } } int main(int argc, char **argv) { const char *princstr, *password; krb5_principal client; krb5_init_creds_context icc; krb5_get_init_creds_opt *opt; krb5_creds creds; krb5_boolean stepwise = FALSE; krb5_preauthtype ptypes[64]; int c, nptypes = 0; char *val; check(krb5_init_context(&ctx)); check(krb5_get_init_creds_opt_alloc(ctx, &opt)); while ((c = getopt(argc, argv, "so:X:")) != -1) { switch (c) { case 's': stepwise = TRUE; break; case 'o': assert(nptypes < 64); ptypes[nptypes++] = atoi(optarg); break; case 'X': val = strchr(optarg, '='); if (val != NULL) *val++ = '\0'; else val = "yes"; check(krb5_get_init_creds_opt_set_pa(ctx, opt, optarg, val)); break; default: abort(); } } argc -= optind; argv += optind; if (argc != 2) abort(); princstr = argv[0]; password = argv[1]; check(krb5_parse_name(ctx, princstr, &client)); if (nptypes > 0) krb5_get_init_creds_opt_set_preauth_list(opt, ptypes, nptypes); if (stepwise) { /* Use the stepwise interface. */ check(krb5_init_creds_init(ctx, client, NULL, NULL, 0, NULL, &icc)); check(krb5_init_creds_set_password(ctx, icc, password)); check(krb5_init_creds_get(ctx, icc)); krb5_init_creds_free(ctx, icc); } else { /* Use the traditional one-shot interface. */ check(krb5_get_init_creds_password(ctx, &creds, client, password, NULL, NULL, 0, NULL, opt)); krb5_free_cred_contents(ctx, &creds); } krb5_get_init_creds_opt_free(ctx, opt); krb5_free_principal(ctx, client); krb5_free_context(ctx); return 0; } krb5-1.16/src/tests/t_hooks.py0000755000704600001450000000037513211554426016157 0ustar ghudsonlibuuid#!/usr/bin/python from k5test import * # Test that KDC send and recv hooks work correctly. realm = K5Realm(create_host=False, get_creds=False) realm.run(['./hooks', realm.user_princ, password('user')]) realm.stop() success('send and recv hook tests') krb5-1.16/src/tests/responder.c0000644000704600001450000003735113211554426016305 0ustar ghudsonlibuuid/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* tests/responder.c - Test harness for responder callbacks and the like. */ /* * Copyright 2013 Red Hat, Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* * A helper for testing PKINIT and responder callbacks. * * This test helper takes multiple options and one argument. * * responder [options] principal * -X preauth_option -> preauth options, as for kinit * -x challenge -> expected responder challenge, of the form * "question=challenge" * -r response -> provide a reponder answer, in the form * "question=answer" * -c -> print the pkinit challenge * -p identity=pin -> provide a pkinit answer, in the form "identity=pin" * -o index=value:pin -> provide an OTP answer, in the form "index=value:pin" * principal -> client principal name * * If the responder callback isn't called, that's treated as an error. * * If an expected responder challenge is specified, when the responder * callback is called, the challenge associated with the specified question is * compared against the specified value. If the value provided to the * callback doesn't parse as JSON, a literal string compare is performed, * otherwise both values are parsed as JSON and then re-encoded before * comparison. In either case, the comparison must succeed. * * Any missing data or mismatches are treated as errors. */ #include #include #include #include #include struct responder_data { krb5_boolean called; krb5_boolean print_pkinit_challenge; const char *challenge; const char *response; const char *pkinit_answer; const char *otp_answer; }; static krb5_error_code responder(krb5_context ctx, void *rawdata, krb5_responder_context rctx) { krb5_error_code err; char *key, *value, *pin, *encoded1, *encoded2; const char *challenge; k5_json_value decoded1, decoded2; k5_json_object ids; k5_json_number val; krb5_int32 token_flags; struct responder_data *data = rawdata; krb5_responder_pkinit_challenge *chl; krb5_responder_otp_challenge *ochl; unsigned int i, n; data->called = TRUE; /* Check that a particular challenge has the specified expected value. */ if (data->challenge != NULL) { /* Separate the challenge name and its expected value. */ key = strdup(data->challenge); if (key == NULL) exit(ENOMEM); value = key + strcspn(key, "="); if (*value != '\0') *value++ = '\0'; /* Read the challenge. */ challenge = krb5_responder_get_challenge(ctx, rctx, key); err = k5_json_decode(value, &decoded1); /* Check for "no challenge". */ if (challenge == NULL && *value == '\0') { fprintf(stderr, "OK: (no challenge) == (no challenge)\n"); } else if (err != 0) { /* It's not JSON, so assume we're just after a string compare. */ if (strcmp(challenge, value) == 0) { fprintf(stderr, "OK: \"%s\" == \"%s\"\n", challenge, value); } else { fprintf(stderr, "ERROR: \"%s\" != \"%s\"\n", challenge, value); exit(1); } } else { /* Assume we're after a JSON compare - decode the actual value. */ err = k5_json_decode(challenge, &decoded2); if (err != 0) { fprintf(stderr, "error decoding \"%s\"\n", challenge); exit(1); } /* Re-encode the expected challenge and the actual challenge... */ err = k5_json_encode(decoded1, &encoded1); if (err != 0) { fprintf(stderr, "error encoding json data\n"); exit(1); } err = k5_json_encode(decoded2, &encoded2); if (err != 0) { fprintf(stderr, "error encoding json data\n"); exit(1); } k5_json_release(decoded1); k5_json_release(decoded2); /* ... and see if they look the same. */ if (strcmp(encoded1, encoded2) == 0) { fprintf(stderr, "OK: \"%s\" == \"%s\"\n", encoded1, encoded2); } else { fprintf(stderr, "ERROR: \"%s\" != \"%s\"\n", encoded1, encoded2); exit(1); } free(encoded1); free(encoded2); } free(key); } /* Provide a particular response for a challenge. */ if (data->response != NULL) { /* Separate the challenge and its data content... */ key = strdup(data->response); if (key == NULL) exit(ENOMEM); value = key + strcspn(key, "="); if (*value != '\0') *value++ = '\0'; /* ... and pass it in. */ err = krb5_responder_set_answer(ctx, rctx, key, value); if (err != 0) { fprintf(stderr, "error setting response\n"); exit(1); } free(key); } if (data->print_pkinit_challenge) { /* Read the PKINIT challenge, formatted as a structure. */ err = krb5_responder_pkinit_get_challenge(ctx, rctx, &chl); if (err != 0) { fprintf(stderr, "error getting pkinit challenge\n"); exit(1); } if (chl != NULL) { for (n = 0; chl->identities[n] != NULL; n++) continue; for (i = 0; chl->identities[i] != NULL; i++) { if (chl->identities[i]->token_flags != -1) { printf("identity %u/%u: %s (flags=0x%lx)\n", i + 1, n, chl->identities[i]->identity, (long)chl->identities[i]->token_flags); } else { printf("identity %u/%u: %s\n", i + 1, n, chl->identities[i]->identity); } } } krb5_responder_pkinit_challenge_free(ctx, rctx, chl); } /* Provide a particular response for the PKINIT challenge. */ if (data->pkinit_answer != NULL) { /* Read the PKINIT challenge, formatted as a structure. */ err = krb5_responder_pkinit_get_challenge(ctx, rctx, &chl); if (err != 0) { fprintf(stderr, "error getting pkinit challenge\n"); exit(1); } /* * In case order matters, if the identity starts with "FILE:", exercise * the set_answer function, with the real answer second. */ if (chl != NULL && chl->identities != NULL && chl->identities[0] != NULL) { if (strncmp(chl->identities[0]->identity, "FILE:", 5) == 0) krb5_responder_pkinit_set_answer(ctx, rctx, "foo", "bar"); } /* Provide the real answer. */ key = strdup(data->pkinit_answer); if (key == NULL) exit(ENOMEM); value = strrchr(key, '='); if (value != NULL) *value++ = '\0'; else value = ""; err = krb5_responder_pkinit_set_answer(ctx, rctx, key, value); if (err != 0) { fprintf(stderr, "error setting response\n"); exit(1); } free(key); /* * In case order matters, if the identity starts with "PKCS12:", * exercise the set_answer function, with the real answer first. */ if (chl != NULL && chl->identities != NULL && chl->identities[0] != NULL) { if (strncmp(chl->identities[0]->identity, "PKCS12:", 7) == 0) krb5_responder_pkinit_set_answer(ctx, rctx, "foo", "bar"); } krb5_responder_pkinit_challenge_free(ctx, rctx, chl); } /* * Something we always check: read the PKINIT challenge, both as a * structure and in JSON form, reconstruct the JSON form from the * structure's contents, and check that they're the same. */ challenge = krb5_responder_get_challenge(ctx, rctx, KRB5_RESPONDER_QUESTION_PKINIT); if (challenge != NULL) { krb5_responder_pkinit_get_challenge(ctx, rctx, &chl); if (chl == NULL) { fprintf(stderr, "pkinit raw challenge set, " "but structure is NULL\n"); exit(1); } if (k5_json_object_create(&ids) != 0) { fprintf(stderr, "error creating json objects\n"); exit(1); } for (i = 0; chl->identities[i] != NULL; i++) { token_flags = chl->identities[i]->token_flags; if (k5_json_number_create(token_flags, &val) != 0) { fprintf(stderr, "error creating json number\n"); exit(1); } if (k5_json_object_set(ids, chl->identities[i]->identity, val) != 0) { fprintf(stderr, "error adding json number to object\n"); exit(1); } k5_json_release(val); } /* Encode the structure... */ err = k5_json_encode(ids, &encoded1); if (err != 0) { fprintf(stderr, "error encoding json data\n"); exit(1); } k5_json_release(ids); /* ... and see if they look the same. */ if (strcmp(encoded1, challenge) != 0) { fprintf(stderr, "\"%s\" != \"%s\"\n", encoded1, challenge); exit(1); } krb5_responder_pkinit_challenge_free(ctx, rctx, chl); free(encoded1); } /* Provide a particular response for an OTP challenge. */ if (data->otp_answer != NULL) { if (krb5_responder_otp_get_challenge(ctx, rctx, &ochl) == 0) { key = strchr(data->otp_answer, '='); if (key != NULL) { /* Make a copy of the answer that we can chop up. */ key = strdup(data->otp_answer); if (key == NULL) return ENOMEM; /* Isolate the ti value. */ value = strchr(key, '='); *value++ = '\0'; n = atoi(key); /* Break the value and PIN apart. */ pin = strchr(value, ':'); if (pin != NULL) *pin++ = '\0'; err = krb5_responder_otp_set_answer(ctx, rctx, n, value, pin); if (err != 0) { fprintf(stderr, "error setting response\n"); exit(1); } free(key); } krb5_responder_otp_challenge_free(ctx, rctx, ochl); } } return 0; } int main(int argc, char **argv) { krb5_context context; krb5_ccache ccache; krb5_get_init_creds_opt *opts; krb5_principal principal; krb5_creds creds; krb5_error_code err; const char *errmsg; char *opt, *val; struct responder_data response; int c; err = krb5_init_context(&context); if (err != 0) { fprintf(stderr, "error starting Kerberos: %s\n", error_message(err)); return err; } err = krb5_get_init_creds_opt_alloc(context, &opts); if (err != 0) { fprintf(stderr, "error initializing options: %s\n", error_message(err)); return err; } err = krb5_cc_default(context, &ccache); if (err != 0) { fprintf(stderr, "error resolving default ccache: %s\n", error_message(err)); return err; } err = krb5_get_init_creds_opt_set_out_ccache(context, opts, ccache); if (err != 0) { fprintf(stderr, "error setting output ccache: %s\n", error_message(err)); return err; } memset(&response, 0, sizeof(response)); while ((c = getopt(argc, argv, "X:x:cr:p:")) != -1) { switch (c) { case 'X': /* Like kinit, set a generic preauth option. */ opt = strdup(optarg); val = opt + strcspn(opt, "="); if (*val != '\0') { *val++ = '\0'; } err = krb5_get_init_creds_opt_set_pa(context, opts, opt, val); if (err != 0) { fprintf(stderr, "error setting option \"%s\": %s\n", opt, error_message(err)); return err; } free(opt); break; case 'x': /* Check that a particular question has a specific challenge. */ response.challenge = optarg; break; case 'c': /* Note that we want a dump of the PKINIT challenge structure. */ response.print_pkinit_challenge = TRUE; break; case 'r': /* Set a verbatim response for a verbatim challenge. */ response.response = optarg; break; case 'p': /* Set a PKINIT answer for a specific PKINIT identity. */ response.pkinit_answer = optarg; break; case 'o': /* Set an OTP answer for a specific OTP tokeninfo. */ response.otp_answer = optarg; break; } } if (argc > optind) { err = krb5_parse_name(context, argv[optind], &principal); if (err != 0) { fprintf(stderr, "error parsing name \"%s\": %s", argv[optind], error_message(err)); return err; } } else { fprintf(stderr, "error: no principal name provided\n"); return -1; } err = krb5_get_init_creds_opt_set_responder(context, opts, responder, &response); if (err != 0) { fprintf(stderr, "error setting responder: %s\n", error_message(err)); return err; } memset(&creds, 0, sizeof(creds)); err = krb5_get_init_creds_password(context, &creds, principal, NULL, NULL, NULL, 0, NULL, opts); if (err == 0) krb5_free_cred_contents(context, &creds); krb5_free_principal(context, principal); krb5_get_init_creds_opt_free(context, opts); krb5_cc_close(context, ccache); if (!response.called) { fprintf(stderr, "error: responder callback wasn't called\n"); err = 1; } else if (err) { errmsg = krb5_get_error_message(context, err); fprintf(stderr, "error: krb5_get_init_creds_password failed: %s\n", errmsg); krb5_free_error_message(context, errmsg); err = 2; } krb5_free_context(context); return err; } krb5-1.16/src/tests/t_cve-2013-1417.py0000755000704600001450000000054213211554426016562 0ustar ghudsonlibuuid#!/usr/bin/python from k5test import * realm = K5Realm(realm='TEST') # CVE-2013-1417 KDC dereferences null pointer realm.kinit(realm.user_princ, password('user')) realm.run([kvno, '-S', 'host', 'example.com'], expected_code=1) # Make sure KDC is still running. realm.kinit(realm.user_princ, password('user')) success('CVE-2013-1417 regression test') krb5-1.16/src/tests/gcred.c0000644000704600001450000000701413211554426015361 0ustar ghudsonlibuuid/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* tests/gcred.c - Test harness for referrals */ /* * Copyright (C) 2012 by the Massachusetts Institute of Technology. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ /* * This program is intended to be run from a python script as: * * gcred nametype princname * * where nametype is one of "unknown", "principal", "srv-inst", and "srv-hst", * and princname is the name of the service principal. gcred acquires * credentials for the specified server principal. On success, gcred displays * the server principal name of the obtained credentials to stdout and exits * with status 0. On failure, gcred displays the error message for the failed * operation to stderr and exits with status 1. */ #include "k5-int.h" static krb5_context ctx; static void check(krb5_error_code code) { const char *errmsg; if (code) { errmsg = krb5_get_error_message(ctx, code); fprintf(stderr, "%s\n", errmsg); krb5_free_error_message(ctx, errmsg); exit(1); } } int main(int argc, char **argv) { krb5_principal client, server; krb5_ccache ccache; krb5_creds in_creds, *creds; char *name; check(krb5_init_context(&ctx)); /* Parse arguments. */ assert(argc == 3); check(krb5_parse_name(ctx, argv[2], &server)); if (strcmp(argv[1], "unknown") == 0) server->type = KRB5_NT_UNKNOWN; else if (strcmp(argv[1], "principal") == 0) server->type = KRB5_NT_PRINCIPAL; else if (strcmp(argv[1], "srv-inst") == 0) server->type = KRB5_NT_SRV_INST; else if (strcmp(argv[1], "srv-hst") == 0) server->type = KRB5_NT_SRV_HST; else abort(); check(krb5_cc_default(ctx, &ccache)); check(krb5_cc_get_principal(ctx, ccache, &client)); memset(&in_creds, 0, sizeof(in_creds)); in_creds.client = client; in_creds.server = server; check(krb5_get_credentials(ctx, 0, ccache, &in_creds, &creds)); check(krb5_unparse_name(ctx, creds->server, &name)); printf("%s\n", name); krb5_free_unparsed_name(ctx, name); krb5_free_creds(ctx, creds); krb5_free_principal(ctx, client); krb5_free_principal(ctx, server); krb5_cc_close(ctx, ccache); krb5_free_context(ctx); return 0; } krb5-1.16/src/tests/t_kdb.py0000755000704600001450000005421513211554426015576 0ustar ghudsonlibuuid#!/usr/bin/python from k5test import * import time from itertools import imap # Run kdbtest against the BDB module. realm = K5Realm(create_kdb=False) realm.run(['./kdbtest']) # Set up an OpenLDAP test server if we can. if (not os.path.exists(os.path.join(plugins, 'kdb', 'kldap.so')) and not os.path.exists(os.path.join(buildtop, 'lib', 'libkdb_ldap.a'))): skip_rest('LDAP KDB tests', 'LDAP KDB module not built') if 'SLAPD' not in os.environ and not which('slapd'): skip_rest('LDAP KDB tests', 'slapd not found') slapadd = which('slapadd') if not slapadd: skip_rest('LDAP KDB tests', 'slapadd not found') ldapdir = os.path.abspath('ldap') dbdir = os.path.join(ldapdir, 'ldap') slapd_conf = os.path.join(ldapdir, 'slapd.d') slapd_out = os.path.join(ldapdir, 'slapd.out') slapd_pidfile = os.path.join(ldapdir, 'pid') ldap_pwfile = os.path.join(ldapdir, 'pw') ldap_sock = os.path.join(ldapdir, 'sock') ldap_uri = 'ldapi://%s/' % ldap_sock.replace(os.path.sep, '%2F') schema = os.path.join(srctop, 'plugins', 'kdb', 'ldap', 'libkdb_ldap', 'kerberos.openldap.ldif') top_dn = 'cn=krb5' admin_dn = 'cn=admin,cn=krb5' admin_pw = 'admin' shutil.rmtree(ldapdir, True) os.mkdir(ldapdir) os.mkdir(slapd_conf) os.mkdir(dbdir) if 'SLAPD' in os.environ: slapd = os.environ['SLAPD'] else: # Some Linux installations have AppArmor or similar restrictions # on the slapd binary, which would prevent it from accessing the # build directory. Try to defeat this by copying the binary. system_slapd = which('slapd') slapd = os.path.join(ldapdir, 'slapd') shutil.copy(system_slapd, slapd) def slap_add(ldif): proc = subprocess.Popen([slapadd, '-b', 'cn=config', '-F', slapd_conf], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) (out, dummy) = proc.communicate(ldif) output(out) return proc.wait() # Configure the pid file and some authorization rules we will need for # SASL testing. if slap_add('dn: cn=config\n' 'objectClass: olcGlobal\n' 'olcPidFile: %s\n' 'olcAuthzRegexp: ' '".*uidNumber=%d,cn=peercred,cn=external,cn=auth" "%s"\n' 'olcAuthzRegexp: "uid=digestuser,cn=digest-md5,cn=auth" "%s"\n' % (slapd_pidfile, os.geteuid(), admin_dn, admin_dn)) != 0: skip_rest('LDAP KDB tests', 'slapd basic configuration failed') # Find a working writable database type, trying mdb (added in OpenLDAP # 2.4.27) and bdb (deprecated and sometimes not built due to licensing # incompatibilities). for dbtype in ('mdb', 'bdb'): # Try to load the module. This could fail if OpenLDAP is built # without module support, so ignore errors. slap_add('dn: cn=module,cn=config\n' 'objectClass: olcModuleList\n' 'olcModuleLoad: back_%s\n' % dbtype) dbclass = 'olc%sConfig' % dbtype.capitalize() if slap_add('dn: olcDatabase=%s,cn=config\n' 'objectClass: olcDatabaseConfig\n' 'objectClass: %s\n' 'olcSuffix: %s\n' 'olcRootDN: %s\n' 'olcRootPW: %s\n' 'olcDbDirectory: %s\n' % (dbtype, dbclass, top_dn, admin_dn, admin_pw, dbdir)) == 0: break else: skip_rest('LDAP KDB tests', 'could not find working slapd db type') if slap_add('include: file://%s\n' % schema) != 0: skip_rest('LDAP KDB tests', 'failed to load Kerberos schema') # Load the core schema if we can. ldap_homes = ['/etc/ldap', '/etc/openldap', '/usr/local/etc/openldap', '/usr/local/etc/ldap'] local_schema_path = '/schema/core.ldif' core_schema = next((i for i in imap(lambda x:x+local_schema_path, ldap_homes) if os.path.isfile(i)), None) if core_schema: if slap_add('include: file://%s\n' % core_schema) != 0: core_schema = None slapd_pid = -1 def kill_slapd(): global slapd_pid if slapd_pid != -1: os.kill(slapd_pid, signal.SIGTERM) slapd_pid = -1 atexit.register(kill_slapd) out = open(slapd_out, 'w') subprocess.call([slapd, '-h', ldap_uri, '-F', slapd_conf], stdout=out, stderr=out) out.close() pidf = open(slapd_pidfile, 'r') slapd_pid = int(pidf.read()) pidf.close() output('*** Started slapd (pid %d, output in %s)\n' % (slapd_pid, slapd_out)) # slapd detaches before it finishes setting up its listener sockets # (they are bound but listen() has not been called). Give it a second # to finish. time.sleep(1) # Run kdbtest against the LDAP module. conf = {'realms': {'$realm': {'database_module': 'ldap'}}, 'dbmodules': {'ldap': {'db_library': 'kldap', 'ldap_kerberos_container_dn': top_dn, 'ldap_kdc_dn': admin_dn, 'ldap_kadmind_dn': admin_dn, 'ldap_service_password_file': ldap_pwfile, 'ldap_servers': ldap_uri}}} realm = K5Realm(create_kdb=False, kdc_conf=conf) input = admin_pw + '\n' + admin_pw + '\n' realm.run([kdb5_ldap_util, 'stashsrvpw', admin_dn], input=input) realm.run(['./kdbtest']) # Run a kdb5_ldap_util command using the test server's admin DN and password. def kldaputil(args, **kw): return realm.run([kdb5_ldap_util, '-D', admin_dn, '-w', admin_pw] + args, **kw) # kdbtest can't currently clean up after itself since the LDAP module # doesn't support krb5_db_destroy. So clean up after it with # kdb5_ldap_util before proceeding. kldaputil(['destroy', '-f']) ldapmodify = which('ldapmodify') ldapsearch = which('ldapsearch') if not ldapmodify or not ldapsearch: skip_rest('some LDAP KDB tests', 'ldapmodify or ldapsearch not found') def ldap_search(args): proc = subprocess.Popen([ldapsearch, '-H', ldap_uri, '-b', top_dn, '-D', admin_dn, '-w', admin_pw, args], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) (out, dummy) = proc.communicate() return out def ldap_modify(ldif, args=[]): proc = subprocess.Popen([ldapmodify, '-H', ldap_uri, '-D', admin_dn, '-x', '-w', admin_pw] + args, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) (out, dummy) = proc.communicate(ldif) output(out) def ldap_add(dn, objectclass, attrs=[]): in_data = 'dn: %s\nobjectclass: %s\n' % (dn, objectclass) in_data += '\n'.join(attrs) + '\n' ldap_modify(in_data, ['-a']) # Create krbContainer objects for use as subtrees. ldap_add('cn=t1,cn=krb5', 'krbContainer') ldap_add('cn=t2,cn=krb5', 'krbContainer') ldap_add('cn=x,cn=t1,cn=krb5', 'krbContainer') ldap_add('cn=y,cn=t2,cn=krb5', 'krbContainer') # Create a realm, exercising all of the realm options. kldaputil(['create', '-s', '-P', 'master', '-subtrees', 'cn=t2,cn=krb5', '-containerref', 'cn=t2,cn=krb5', '-sscope', 'one', '-maxtktlife', '5min', '-maxrenewlife', '10min', '-allow_svr']) # Modify the realm, exercising overlapping subtree pruning. kldaputil(['modify', '-subtrees', 'cn=x,cn=t1,cn=krb5:cn=t1,cn=krb5:cn=t2,cn=krb5:cn=y,cn=t2,cn=krb5', '-containerref', 'cn=t1,cn=krb5', '-sscope', 'sub', '-maxtktlife', '5hour', '-maxrenewlife', '10hour', '+allow_svr']) out = kldaputil(['list']) if out != 'KRBTEST.COM\n': fail('Unexpected kdb5_ldap_util list output') # Create a principal at a specified DN. This is a little dodgy # because we're sticking a krbPrincipalAux objectclass onto a subtree # krbContainer, but it works and it avoids having to load core.schema # in the test LDAP server. realm.run([kadminl, 'ank', '-randkey', '-x', 'dn=cn=krb5', 'princ1'], expected_code=1, expected_msg='DN is out of the realm subtree') realm.run([kadminl, 'ank', '-randkey', '-x', 'dn=cn=t2,cn=krb5', 'princ1']) realm.run([kadminl, 'getprinc', 'princ1'], expected_msg='Principal: princ1') realm.run([kadminl, 'ank', '-randkey', '-x', 'dn=cn=t2,cn=krb5', 'again'], expected_code=1, expected_msg='ldap object is already kerberized') # Check that we can't set linkdn on a non-standalone object. realm.run([kadminl, 'modprinc', '-x', 'linkdn=cn=t1,cn=krb5', 'princ1'], expected_code=1, expected_msg='link information can not be set') # Create a principal with a specified linkdn. realm.run([kadminl, 'ank', '-randkey', '-x', 'linkdn=cn=krb5', 'princ2'], expected_code=1, expected_msg='DN is out of the realm subtree') realm.run([kadminl, 'ank', '-randkey', '-x', 'linkdn=cn=t1,cn=krb5', 'princ2']) # Check that we can't reset linkdn. realm.run([kadminl, 'modprinc', '-x', 'linkdn=cn=t2,cn=krb5', 'princ2'], expected_code=1, expected_msg='kerberos principal is already linked') # Create a principal with a specified containerdn. realm.run([kadminl, 'ank', '-randkey', '-x', 'containerdn=cn=krb5', 'princ3'], expected_code=1, expected_msg='DN is out of the realm subtree') realm.run([kadminl, 'ank', '-randkey', '-x', 'containerdn=cn=t1,cn=krb5', 'princ3']) realm.run([kadminl, 'modprinc', '-x', 'containerdn=cn=t2,cn=krb5', 'princ3'], expected_code=1, expected_msg='containerdn option not supported') # Create and modify a ticket policy. kldaputil(['create_policy', '-maxtktlife', '3hour', '-maxrenewlife', '6hour', '-allow_forwardable', 'tktpol']) kldaputil(['modify_policy', '-maxtktlife', '4hour', '-maxrenewlife', '8hour', '+requires_preauth', 'tktpol']) out = kldaputil(['view_policy', 'tktpol']) if ('Ticket policy: tktpol\n' not in out or 'Maximum ticket life: 0 days 04:00:00\n' not in out or 'Maximum renewable life: 0 days 08:00:00\n' not in out or 'Ticket flags: DISALLOW_FORWARDABLE REQUIRES_PRE_AUTH' not in out): fail('Unexpected kdb5_ldap_util view_policy output') out = kldaputil(['list_policy']) if out != 'tktpol\n': fail('Unexpected kdb5_ldap_util list_policy output') # Associate the ticket policy to a principal. realm.run([kadminl, 'ank', '-randkey', '-x', 'tktpolicy=tktpol', 'princ4']) out = realm.run([kadminl, 'getprinc', 'princ4']) if ('Maximum ticket life: 0 days 04:00:00\n' not in out or 'Maximum renewable life: 0 days 08:00:00\n' not in out or 'Attributes: DISALLOW_FORWARDABLE REQUIRES_PRE_AUTH\n' not in out): fail('Unexpected getprinc output with ticket policy') # Destroying the policy should fail while a principal references it. kldaputil(['destroy_policy', '-force', 'tktpol'], expected_code=1) # Dissociate the ticket policy from the principal. realm.run([kadminl, 'modprinc', '-x', 'tktpolicy=', 'princ4']) out = realm.run([kadminl, 'getprinc', 'princ4']) if ('Maximum ticket life: 0 days 05:00:00\n' not in out or 'Maximum renewable life: 0 days 10:00:00\n' not in out or 'Attributes:\n' not in out): fail('Unexpected getprinc output without ticket policy') # Destroy the ticket policy. kldaputil(['destroy_policy', '-force', 'tktpol']) kldaputil(['view_policy', 'tktpol'], expected_code=1) out = kldaputil(['list_policy']) if out: fail('Unexpected kdb5_ldap_util list_policy output after destroy') # Create another ticket policy to be destroyed with the realm. kldaputil(['create_policy', 'tktpol2']) # Try to create a password policy conflicting with a ticket policy. realm.run([kadminl, 'addpol', 'tktpol2'], expected_code=1, expected_msg='Already exists while creating policy "tktpol2"') # Try to create a ticket policy conflicting with a password policy. realm.run([kadminl, 'addpol', 'pwpol']) out = kldaputil(['create_policy', 'pwpol'], expected_code=1) if 'Already exists while creating policy object' not in out: fail('Expected error not seen in kdb5_ldap_util output') # Try to use a password policy as a ticket policy. realm.run([kadminl, 'modprinc', '-x', 'tktpolicy=pwpol', 'princ4'], expected_code=1, expected_msg='Object class violation') # Use a ticket policy as a password policy (CVE-2014-5353). This # works with a warning; use kadmin.local -q so the warning is shown. realm.run([kadminl, '-q', 'modprinc -policy tktpol2 princ4'], expected_msg='WARNING: policy "tktpol2" does not exist') # Do some basic tests with a KDC against the LDAP module, exercising the # db_args processing code. realm.start_kdc(['-x', 'nconns=3', '-x', 'host=' + ldap_uri, '-x', 'binddn=' + admin_dn, '-x', 'bindpwd=' + admin_pw]) realm.addprinc(realm.user_princ, password('user')) realm.addprinc(realm.host_princ) realm.extract_keytab(realm.host_princ, realm.keytab) realm.kinit(realm.user_princ, password('user')) realm.run([kvno, realm.host_princ]) realm.klist(realm.user_princ, realm.host_princ) # Test auth indicator support realm.addprinc('authind', password('authind')) realm.run([kadminl, 'setstr', 'authind', 'require_auth', 'otp radius']) out = ldap_search('(krbPrincipalName=authind*)') if 'krbPrincipalAuthInd: otp' not in out: fail('Expected krbPrincipalAuthInd value not in output') if 'krbPrincipalAuthInd: radius' not in out: fail('Expected krbPrincipalAuthInd value not in output') realm.run([kadminl, 'getstrs', 'authind'], expected_msg='require_auth: otp radius') # Test service principal aliases. realm.addprinc('canon', password('canon')) ldap_modify('dn: krbPrincipalName=canon@KRBTEST.COM,cn=t1,cn=krb5\n' 'changetype: modify\n' 'add: krbPrincipalName\n' 'krbPrincipalName: alias@KRBTEST.COM\n' '-\n' 'add: krbCanonicalName\n' 'krbCanonicalName: canon@KRBTEST.COM\n') realm.run([kadminl, 'getprinc', 'alias'], expected_msg='Principal: canon@KRBTEST.COM\n') realm.run([kadminl, 'getprinc', 'canon'], expected_msg='Principal: canon@KRBTEST.COM\n') realm.run([kvno, 'alias', 'canon']) out = realm.run([klist]) if 'alias@KRBTEST.COM\n' not in out or 'canon@KRBTEST.COM' not in out: fail('After fetching alias and canon, klist is missing one or both') realm.kinit(realm.user_princ, password('user'), ['-S', 'alias']) realm.klist(realm.user_princ, 'alias@KRBTEST.COM') # Make sure an alias to the local TGS is still treated like an alias. ldap_modify('dn: krbPrincipalName=krbtgt/KRBTEST.COM@KRBTEST.COM,' 'cn=KRBTEST.COM,cn=krb5\n' 'changetype: modify\n' 'add:krbPrincipalName\n' 'krbPrincipalName: tgtalias@KRBTEST.COM\n' '-\n' 'add: krbCanonicalName\n' 'krbCanonicalName: krbtgt/KRBTEST.COM@KRBTEST.COM\n') realm.run([kadminl, 'getprinc', 'tgtalias'], expected_msg='Principal: krbtgt/KRBTEST.COM@KRBTEST.COM') realm.kinit(realm.user_princ, password('user')) realm.run([kvno, 'tgtalias']) realm.klist(realm.user_princ, 'tgtalias@KRBTEST.COM') # Make sure aliases work in header tickets. realm.run([kadminl, 'modprinc', '-maxrenewlife', '3 hours', 'user']) realm.run([kadminl, 'modprinc', '-maxrenewlife', '3 hours', 'krbtgt/KRBTEST.COM']) realm.kinit(realm.user_princ, password('user'), ['-l', '1h', '-r', '2h']) realm.run([kvno, 'alias']) realm.kinit(realm.user_princ, flags=['-R', '-S', 'alias']) realm.klist(realm.user_princ, 'alias@KRBTEST.COM') # Test client principal aliases, with and without preauth. realm.kinit('canon', password('canon')) realm.kinit('alias', password('canon'), expected_code=1, expected_msg='not found in Kerberos database') realm.kinit('alias', password('canon'), ['-C']) realm.run([kvno, 'alias']) realm.klist('canon@KRBTEST.COM', 'alias@KRBTEST.COM') realm.run([kadminl, 'modprinc', '+requires_preauth', 'canon']) realm.kinit('canon', password('canon')) realm.kinit('alias', password('canon'), ['-C']) # Test password history. def test_pwhist(nhist): def cpw(n, **kwargs): realm.run([kadminl, 'cpw', '-pw', str(n), princ], **kwargs) def cpw_fail(n): cpw(n, expected_code=1) output('*** Testing password history of size %d\n' % nhist) princ = 'pwhistprinc' + str(nhist) pol = 'pwhistpol' + str(nhist) realm.run([kadminl, 'addpol', '-history', str(nhist), pol]) realm.run([kadminl, 'addprinc', '-policy', pol, '-nokey', princ]) for i in range(nhist): # Set a password, then check that all previous passwords fail. cpw(i) for j in range(i + 1): cpw_fail(j) # Set one more new password, and make sure the oldest key is # rotated out. cpw(nhist) cpw_fail(1) cpw(0) for n in (1, 2, 3, 4, 5): test_pwhist(n) # Regression test for #8193: test password character class requirements. princ = 'charclassprinc' pol = 'charclasspol' realm.run([kadminl, 'addpol', '-minclasses', '3', pol]) realm.run([kadminl, 'addprinc', '-policy', pol, '-nokey', princ]) realm.run([kadminl, 'cpw', '-pw', 'abcdef', princ], expected_code=1) realm.run([kadminl, 'cpw', '-pw', 'Abcdef', princ], expected_code=1) realm.run([kadminl, 'cpw', '-pw', 'Abcdef1', princ]) # Test principal renaming and make sure last modified is changed def get_princ(princ): out = realm.run([kadminl, 'getprinc', princ]) return dict(map(str.strip, x.split(":", 1)) for x in out.splitlines()) realm.addprinc("rename", password('rename')) renameprinc = get_princ("rename") realm.run([kadminl, '-p', 'fake@KRBTEST.COM', 'renprinc', 'rename', 'renamed']) renamedprinc = get_princ("renamed") if renameprinc['Last modified'] == renamedprinc['Last modified']: fail('Last modified data not updated when principal was renamed') # Regression test for #7980 (fencepost when dividing keys up by kvno). realm.run([kadminl, 'addprinc', '-randkey', '-e', 'aes256-cts,aes128-cts', 'kvnoprinc']) realm.run([kadminl, 'cpw', '-randkey', '-keepold', '-e', 'aes256-cts,aes128-cts', 'kvnoprinc']) realm.run([kadminl, 'getprinc', 'kvnoprinc'], expected_msg='Number of keys: 4') realm.run([kadminl, 'cpw', '-randkey', '-keepold', '-e', 'aes256-cts,aes128-cts', 'kvnoprinc']) realm.run([kadminl, 'getprinc', 'kvnoprinc'], expected_msg='Number of keys: 6') # Regression test for #8041 (NULL dereference on keyless principals). realm.run([kadminl, 'addprinc', '-nokey', 'keylessprinc']) realm.run([kadminl, 'getprinc', 'keylessprinc'], expected_msg='Number of keys: 0') realm.run([kadminl, 'cpw', '-randkey', '-e', 'aes256-cts,aes128-cts', 'keylessprinc']) realm.run([kadminl, 'cpw', '-randkey', '-keepold', '-e', 'aes256-cts,aes128-cts', 'keylessprinc']) realm.run([kadminl, 'getprinc', 'keylessprinc'], expected_msg='Number of keys: 4') realm.run([kadminl, 'purgekeys', '-all', 'keylessprinc']) realm.run([kadminl, 'getprinc', 'keylessprinc'], expected_msg='Number of keys: 0') # Test for 8354 (old password history entries when -keepold is used) realm.run([kadminl, 'addpol', '-history', '2', 'keepoldpasspol']) realm.run([kadminl, 'addprinc', '-policy', 'keepoldpasspol', '-pw', 'aaaa', 'keepoldpassprinc']) for p in ('bbbb', 'cccc', 'aaaa'): realm.run([kadminl, 'cpw', '-keepold', '-pw', p, 'keepoldpassprinc']) if runenv.sizeof_time_t <= 4: skipped('y2038 LDAP test', 'platform has 32-bit time_t') else: # Test storage of timestamps after y2038. realm.run([kadminl, 'modprinc', '-pwexpire', '2040-02-03', 'user']) realm.run([kadminl, 'getprinc', 'user'], expected_msg=' 2040\n') realm.stop() # Briefly test dump and load. dumpfile = os.path.join(realm.testdir, 'dump') realm.run([kdb5_util, 'dump', dumpfile]) realm.run([kdb5_util, 'load', dumpfile], expected_code=1, expected_msg='KDB module requires -update argument') realm.run([kdb5_util, 'load', '-update', dumpfile]) # Destroy the realm. kldaputil(['destroy', '-f']) out = kldaputil(['list']) if out: fail('Unexpected kdb5_ldap_util list output after destroy') if not core_schema: skip_rest('LDAP SASL tests', 'core schema not found') if runenv.have_sasl != 'yes': skip_rest('LDAP SASL tests', 'SASL support not built') # Test SASL EXTERNAL auth. Remove the DNs and service password file # from the DB module config. os.remove(ldap_pwfile) dbmod = conf['dbmodules']['ldap'] dbmod['ldap_kdc_sasl_mech'] = dbmod['ldap_kadmind_sasl_mech'] = 'EXTERNAL' del dbmod['ldap_service_password_file'] del dbmod['ldap_kdc_dn'], dbmod['ldap_kadmind_dn'] realm = K5Realm(create_kdb=False, kdc_conf=conf) realm.run([kdb5_ldap_util, 'create', '-s', '-P', 'master']) realm.start_kdc() realm.addprinc(realm.user_princ, password('user')) realm.kinit(realm.user_princ, password('user')) realm.stop() realm.run([kdb5_ldap_util, 'destroy', '-f']) # Test SASL DIGEST-MD5 auth. We need to set a clear-text password for # the admin DN, so create a person entry (requires the core schema). # Restore the service password file in the config and set authcids. ldap_add('cn=admin,cn=krb5', 'person', ['sn: dummy', 'userPassword: admin']) dbmod['ldap_kdc_sasl_mech'] = dbmod['ldap_kadmind_sasl_mech'] = 'DIGEST-MD5' dbmod['ldap_kdc_sasl_authcid'] = 'digestuser' dbmod['ldap_kadmind_sasl_authcid'] = 'digestuser' dbmod['ldap_service_password_file'] = ldap_pwfile realm = K5Realm(create_kdb=False, kdc_conf=conf) input = admin_pw + '\n' + admin_pw + '\n' realm.run([kdb5_ldap_util, 'stashsrvpw', 'digestuser'], input=input) realm.run([kdb5_ldap_util, 'create', '-s', '-P', 'master']) realm.start_kdc() realm.addprinc(realm.user_princ, password('user')) realm.kinit(realm.user_princ, password('user')) realm.stop() # Exercise DB options, which should cause binding to fail. realm.run([kadminl, '-x', 'sasl_authcid=ab', 'getprinc', 'user'], expected_code=1, expected_msg='Cannot bind to LDAP server') realm.run([kadminl, '-x', 'bindpwd=wrong', 'getprinc', 'user'], expected_code=1, expected_msg='Cannot bind to LDAP server') realm.run([kdb5_ldap_util, 'destroy', '-f']) # We could still use tests to exercise: # * DB arg handling in krb5_ldap_create # * krbAllowedToDelegateTo attribute processing # * A load operation overwriting a standalone principal entry which # already exists but doesn't have a krbPrincipalName attribute # matching the principal name. # * A bunch of invalid-input error conditions # # There is no coverage for the following because it would be difficult: # * Out-of-memory error conditions # * Handling of failures from slapd (including krb5_retry_get_ldap_handle) # * Handling of servers which don't support mod-increment # * krb5_ldap_delete_krbcontainer (only happens if krb5_ldap_create fails) success('LDAP and DB2 KDB tests') krb5-1.16/src/tests/t_kdcpolicy.py0000644000704600001450000000456213211554426017014 0ustar ghudsonlibuuid#!/usr/bin/python from k5test import * from datetime import datetime import re testpreauth = os.path.join(buildtop, 'plugins', 'preauth', 'test', 'test.so') testpolicy = os.path.join(buildtop, 'plugins', 'kdcpolicy', 'test', 'kdcpolicy_test.so') krb5_conf = {'plugins': {'kdcpreauth': {'module': 'test:' + testpreauth}, 'clpreauth': {'module': 'test:' + testpreauth}, 'kdcpolicy': {'module': 'test:' + testpolicy}}} kdc_conf = {'realms': {'$realm': {'default_principal_flags': '+preauth', 'max_renewable_life': '1d'}}} realm = K5Realm(krb5_conf=krb5_conf, kdc_conf=kdc_conf) realm.run([kadminl, 'addprinc', '-pw', password('fail'), 'fail']) def verify_time(out, target_time): times = re.findall(r'\d\d/\d\d/\d\d \d\d:\d\d:\d\d', out) times = [datetime.strptime(t, '%m/%d/%y %H:%M:%S') for t in times] divisor = 1 while len(times) > 0: starttime = times.pop(0) endtime = times.pop(0) renewtime = times.pop(0) if str((endtime - starttime) * divisor) != target_time: fail('unexpected lifetime value') if str((renewtime - endtime) * divisor) != target_time: fail('unexpected renewable value') # Service tickets should have half the lifetime of initial # tickets. divisor = 2 rflags = ['-r', '1d', '-l', '12h'] # Test AS+TGS success path. realm.kinit(realm.user_princ, password('user'), rflags + ['-X', 'indicators=SEVEN_HOURS']) realm.run([kvno, realm.host_princ]) realm.run(['./adata', realm.host_princ], expected_msg='+97: [SEVEN_HOURS]') out = realm.run([klist, '-e', realm.ccache]) verify_time(out, '7:00:00') # Test AS+TGS success path with different values. realm.kinit(realm.user_princ, password('user'), rflags + ['-X', 'indicators=ONE_HOUR']) realm.run([kvno, realm.host_princ]) realm.run(['./adata', realm.host_princ], expected_msg='+97: [ONE_HOUR]') out = realm.run([klist, '-e', realm.ccache]) verify_time(out, '1:00:00') # Test TGS failure path (using previous creds). realm.run([kvno, 'fail@%s' % realm.realm], expected_code=1, expected_msg='KDC policy rejects request') # Test AS failure path. realm.kinit('fail@%s' % realm.realm, password('fail'), expected_code=1, expected_msg='KDC policy rejects request') success('kdcpolicy tests') krb5-1.16/src/tests/rdreq.c0000644000704600001450000000776513211554426015427 0ustar ghudsonlibuuid/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* tests/rdreq.c - Test harness for krb5_rd_req */ /* * Copyright (C) 2014 by the Massachusetts Institute of Technology. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #include #include #include #include int main(int argc, char **argv) { krb5_context context; krb5_principal client_princ, tkt_princ, server_princ; krb5_ccache ccache; krb5_creds *cred, mcred; krb5_auth_context auth_con; krb5_data apreq; krb5_error_code ret, code; const char *tkt_name, *server_name, *emsg; /* Parse arguments. */ if (argc < 2 || argc > 3) { fprintf(stderr, "Usage: rdreq tktname [servername]\n"); exit(1); } tkt_name = argv[1]; server_name = argv[2]; if (krb5_init_context(&context) != 0) abort(); /* Parse the requested principal names. */ if (krb5_parse_name(context, tkt_name, &tkt_princ) != 0) abort(); if (server_name != NULL) { if (krb5_parse_name(context, server_name, &server_princ) != 0) abort(); server_princ->type = KRB5_NT_SRV_HST; } else { server_princ = NULL; } /* Produce an AP-REQ message. */ if (krb5_cc_default(context, &ccache) != 0) abort(); if (krb5_cc_get_principal(context, ccache, &client_princ) != 0) abort(); memset(&mcred, 0, sizeof(mcred)); mcred.client = client_princ; mcred.server = tkt_princ; if (krb5_get_credentials(context, 0, ccache, &mcred, &cred) != 0) abort(); auth_con = NULL; if (krb5_mk_req_extended(context, &auth_con, 0, NULL, cred, &apreq) != 0) abort(); /* Consume the AP-REQ message without using a replay cache. */ krb5_auth_con_free(context, auth_con); if (krb5_auth_con_init(context, &auth_con) != 0) abort(); if (krb5_auth_con_setflags(context, auth_con, 0) != 0) abort(); ret = krb5_rd_req(context, &auth_con, &apreq, server_princ, NULL, NULL, NULL); /* Display the result. */ if (ret) { code = ret - ERROR_TABLE_BASE_krb5; if (code < 0 || code > 127) code = 60; /* KRB_ERR_GENERIC */ emsg = krb5_get_error_message(context, ret); printf("%d %s\n", code, emsg); krb5_free_error_message(context, emsg); } else { printf("0 success\n"); } krb5_free_data_contents(context, &apreq); krb5_auth_con_free(context, auth_con); krb5_free_creds(context, cred); krb5_cc_close(context, ccache); krb5_free_principal(context, client_princ); krb5_free_principal(context, tkt_princ); krb5_free_principal(context, server_princ); krb5_free_context(context); return 0; } krb5-1.16/src/tests/verify/0000755000704600001450000000000013211554426015433 5ustar ghudsonlibuuidkrb5-1.16/src/tests/verify/kdb5_verify.c0000644000704600001450000003435313211554426020020 0ustar ghudsonlibuuid/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* tests/verify/kdb5_verify.c */ /* * Copyright 1990,1991 by the Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #include "k5-int.h" #include "kdb.h" #include "com_err.h" #include #include #define REALM_SEP '@' #define REALM_SEP_STR "@" struct mblock { krb5_deltat max_life; krb5_deltat max_rlife; krb5_timestamp expiration; krb5_flags flags; krb5_kvno mkvno; } mblock = { /* XXX */ KRB5_KDB_MAX_LIFE, KRB5_KDB_MAX_RLIFE, KRB5_KDB_EXPIRATION, KRB5_KDB_DEF_FLAGS, 0 }; int set_dbname_help (krb5_context, char *, char *); static void usage(who, status) char *who; int status; { fprintf(stderr, "usage: %s -p prefix -n num_to_check [-d dbpathname] [-r realmname]\n", who); fprintf(stderr, "\t [-D depth] [-k enctype] [-M mkeyname]\n"); exit(status); } krb5_keyblock master_keyblock; krb5_principal master_princ; krb5_encrypt_block master_encblock; krb5_pointer master_random; char *str_master_princ; static char *progname; static char *cur_realm = 0; static char *mkey_name = 0; static char *mkey_password = 0; static krb5_boolean manual_mkey = FALSE; int check_princ (krb5_context, char *); int main(argc, argv) int argc; char *argv[]; { extern char *optarg; int optchar, i, n; char tmp[4096], tmp2[BUFSIZ], *str_princ; krb5_context context; krb5_error_code retval; char *dbname = 0; int enctypedone = 0; int num_to_check; char principal_string[BUFSIZ]; char *suffix = 0; size_t suffix_size = 0; int depth, errors; krb5_init_context(&context); if (strrchr(argv[0], '/')) argv[0] = strrchr(argv[0], '/')+1; progname = argv[0]; memset(principal_string, 0, sizeof(principal_string)); num_to_check = 0; depth = 1; while ((optchar = getopt(argc, argv, "D:P:p:n:d:r:R:k:M:e:m")) != -1) { switch(optchar) { case 'D': depth = atoi(optarg); /* how deep to go */ break; case 'P': /* Only used for testing!!! */ mkey_password = optarg; break; case 'p': /* prefix name to check */ strncpy(principal_string, optarg, sizeof(principal_string) - 1); principal_string[sizeof(principal_string) - 1] = '\0'; suffix = principal_string + strlen(principal_string); suffix_size = sizeof(principal_string) - (suffix - principal_string); break; case 'n': /* how many to check */ num_to_check = atoi(optarg); break; case 'd': /* set db name */ dbname = optarg; break; case 'r': cur_realm = optarg; break; case 'k': master_keyblock.enctype = atoi(optarg); enctypedone++; break; case 'M': /* master key name in DB */ mkey_name = optarg; break; case 'm': manual_mkey = TRUE; break; case '?': default: usage(progname, 1); /*NOTREACHED*/ } } if (!(num_to_check && suffix)) usage(progname, 1); if (!enctypedone) master_keyblock.enctype = DEFAULT_KDC_ENCTYPE; if (!krb5_c_valid_enctype(master_keyblock.enctype)) { com_err(progname, KRB5_PROG_ETYPE_NOSUPP, "while setting up enctype %d", master_keyblock.enctype); exit(1); } krb5_use_enctype(context, &master_encblock, master_keyblock.enctype); if (!dbname) dbname = DEFAULT_KDB_FILE; /* XXX? */ if (!cur_realm) { if ((retval = krb5_get_default_realm(context, &cur_realm))) { com_err(progname, retval, "while retrieving default realm name"); exit(1); } } if ((retval = set_dbname_help(context, progname, dbname))) exit(retval); errors = 0; fprintf(stdout, "\nChecking "); for (n = 1; n <= num_to_check; n++) { /* build the new principal name */ /* we can't pick random names because we need to generate all the names again given a prefix and count to test the db lib and kdb */ (void) snprintf(suffix, suffix_size, "%d", n); (void) snprintf(tmp, sizeof(tmp), "%s-DEPTH-1", principal_string); str_princ = tmp; if (check_princ(context, str_princ)) errors++; for (i = 2; i <= depth; i++) { (void) snprintf(tmp2, sizeof(tmp2), "/%s-DEPTH-%d", principal_string, i); tmp2[sizeof(tmp2) - 1] = '\0'; strncat(tmp, tmp2, sizeof(tmp) - 1 - strlen(tmp)); str_princ = tmp; if (check_princ(context, str_princ)) errors++; } } if (errors) fprintf(stdout, "\n%d errors/principals failed.\n", errors); else fprintf(stdout, "\nNo errors.\n"); krb5_finish_random_key(context, &master_encblock, &master_random); krb5_finish_key(context, &master_encblock); retval = krb5_db_fini(context); memset(master_keyblock.contents, 0, (size_t) master_keyblock.length); if (retval && retval != KRB5_KDB_DBNOTINITED) { com_err(progname, retval, "while closing database"); exit(1); } krb5_free_keyblock_contents(context, &master_keyblock); if (str_master_princ) { krb5_free_unparsed_name(context, str_master_princ); } krb5_free_principal(context, master_princ); krb5_free_context(context); exit(0); } int check_princ(context, str_princ) krb5_context context; char * str_princ; { krb5_error_code retval; krb5_db_entry *kdbe = NULL; krb5_keyblock pwd_key, db_key; krb5_data pwd, salt; krb5_principal princ; /* char *str_mod_name; */ char princ_name[4096]; snprintf(princ_name, sizeof(princ_name), "%s@%s", str_princ, cur_realm); if ((retval = krb5_parse_name(context, princ_name, &princ))) { com_err(progname, retval, "while parsing '%s'", princ_name); goto out; } pwd.data = princ_name; /* must be able to regenerate */ pwd.length = strlen(princ_name); if ((retval = krb5_principal2salt(context, princ, &salt))) { com_err(progname, retval, "while converting principal to salt for '%s'", princ_name); krb5_free_principal(context, princ); goto out; } if ((retval = krb5_string_to_key(context, &master_encblock, &pwd_key, &pwd, &salt))) { com_err(progname, retval, "while converting password to key for '%s'", princ_name); krb5_free_data_contents(context, &salt); krb5_free_principal(context, princ); goto out; } krb5_free_data_contents(context, &salt); if ((retval = krb5_db_get_principal(context, princ, 0, &kdbe))) { com_err(progname, retval, "while attempting to verify principal's existence"); krb5_free_principal(context, princ); goto out; } krb5_free_principal(context, princ); if ((retval = krb5_dbe_decrypt_key_data(context, NULL, kdbe->key_data, &db_key, NULL))) { com_err(progname, retval, "while decrypting key for '%s'", princ_name); goto errout; } if ((pwd_key.enctype != db_key.enctype) || (pwd_key.length != db_key.length)) { fprintf (stderr, "\tKey types do not agree (%d expected, %d from db)\n", pwd_key.enctype, db_key.enctype); errout: krb5_db_free_principal(context, kdbe); return(-1); } else { if (memcmp((char *)pwd_key.contents, (char *) db_key.contents, (size_t) pwd_key.length)) { fprintf(stderr, "\t key did not match stored value for %s\n", princ_name); goto errout; } } free(pwd_key.contents); free(db_key.contents); if (kdbe->key_data[0].key_data_kvno != 1) { fprintf(stderr,"\tkvno did not match stored value for %s.\n", princ_name); goto errout; } if (kdbe->max_life != mblock.max_life) { fprintf(stderr, "\tmax life did not match stored value for %s.\n", princ_name); goto errout; } if (kdbe->max_renewable_life != mblock.max_rlife) { fprintf(stderr, "\tmax renewable life did not match stored value for %s.\n", princ_name); goto errout; } if (kdbe->expiration != mblock.expiration) { fprintf(stderr, "\texpiration time did not match stored value for %s.\n", princ_name); goto errout; } /* if ((retval = krb5_unparse_name(context, kdbe.mod_name, &str_mod_name))) com_err(progname, retval, "while unparsing mode name"); else { if (strcmp(str_mod_name, str_master_princ) != 0) { fprintf(stderr, "\tmod name isn't the master princ (%s not %s).\n", str_mod_name, str_master_princ); free(str_mod_name); goto errout; } else free(str_mod_name); } */ if (kdbe->attributes != mblock.flags) { fprintf(stderr, "\tAttributes did not match stored value for %s.\n", princ_name); goto errout; } out: krb5_db_free_principal(context, kdbe); return(0); } int set_dbname_help(context, pname, dbname) krb5_context context; char *pname; char *dbname; { krb5_error_code retval; krb5_data pwd, scratch; char *args[2]; krb5_db_entry *master_entry; /* assemble & parse the master key name */ if ((retval = krb5_db_setup_mkey_name(context, mkey_name, cur_realm, 0, &master_princ))) { com_err(pname, retval, "while setting up master key name"); return(1); } if (mkey_password) { pwd.data = mkey_password; pwd.length = strlen(mkey_password); retval = krb5_principal2salt(context, master_princ, &scratch); if (retval) { com_err(pname, retval, "while calculated master key salt"); return(1); } if ((retval = krb5_string_to_key(context, &master_encblock, &master_keyblock, &pwd, &scratch))) { com_err(pname, retval, "while transforming master key from password"); return(1); } free(scratch.data); } else { if ((retval = krb5_db_fetch_mkey(context, master_princ, master_keyblock.enctype, manual_mkey, FALSE, (char *) NULL, NULL, NULL, &master_keyblock))) { com_err(pname, retval, "while reading master key"); return(1); } } /* Ick! Current DAL interface requires that the default_realm field be set in the krb5_context. */ if ((retval = krb5_set_default_realm(context, cur_realm))) { com_err(pname, retval, "setting default realm"); return 1; } /* Pathname is passed to db2 via 'args' parameter. */ args[1] = NULL; if (asprintf(&args[0], "dbname=%s", dbname) < 0) { com_err(pname, errno, "while setting up db parameters"); return 1; } if ((retval = krb5_db_open(context, args, KRB5_KDB_OPEN_RO))) { com_err(pname, retval, "while initializing database"); return(1); } if ((retval = krb5_db_fetch_mkey_list(context, master_princ, &master_keyblock))) { com_err(pname, retval, "while verifying master key"); (void) krb5_db_fini(context); return(1); } if ((retval = krb5_db_get_principal(context, master_princ, 0, &master_entry))) { com_err(pname, retval, "while retrieving master entry"); (void) krb5_db_fini(context); return(1); } if ((retval = krb5_unparse_name(context, master_princ, &str_master_princ))) { com_err(pname, retval, "while unparsing master principal"); krb5_db_fini(context); return(1); } if ((retval = krb5_process_key(context, &master_encblock, &master_keyblock))) { com_err(pname, retval, "while processing master key"); (void) krb5_db_fini(context); return(1); } if ((retval = krb5_init_random_key(context, &master_encblock, &master_keyblock, &master_random))) { com_err(pname, retval, "while initializing random key generator"); krb5_finish_key(context, &master_encblock); (void) krb5_db_fini(context); return(1); } mblock.max_life = master_entry->max_life; mblock.max_rlife = master_entry->max_renewable_life; mblock.expiration = master_entry->expiration; /* don't set flags, master has some extra restrictions */ mblock.mkvno = master_entry->key_data[0].key_data_kvno; krb5_db_free_principal(context, master_entry); free(args[0]); return 0; } krb5-1.16/src/tests/verify/deps0000644000704600001450000000143713211554426016316 0ustar ghudsonlibuuid# # Generated makefile dependencies follow. # $(OUTPRE)kdb5_verify.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(SS_DEPS) \ $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \ $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-int-pkinit.h \ $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \ $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \ $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/kdb.h \ $(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/authdata_plugin.h \ $(top_srcdir)/include/krb5/plugin.h $(top_srcdir)/include/port-sockets.h \ $(top_srcdir)/include/socket-utils.h kdb5_verify.c krb5-1.16/src/tests/verify/pkey.c0000644000704600001450000000072413211554426016552 0ustar ghudsonlibuuid/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* tests/verify/pkey.c */ /* * Copyright 1991 by the Massachusetts Institute of Technology. * All Rights Reserved. * * For copying and distribution information, please see the file * . * */ #include void pkey(k) unsigned char *k; { int i; unsigned int foo; for (i = 0 ; i < 8 ; i++) { foo = *k++; fprintf(stderr, "%x ", foo); } } krb5-1.16/src/tests/verify/Makefile.in0000644000704600001450000000052513211554426017502 0ustar ghudsonlibuuidmydir=tests$(S)verify BUILDTOP=$(REL)..$(S).. KDB5_DEP_LIB=$(THREAD_LINKOPTS) $(DL_LIB) SRCS=$(srcdir)/kdb5_verify.c all: kdb5_verify kdb5_verify: kdb5_verify.o $(KDB5_DEPLIBS) $(KRB5_BASE_DEPLIBS) $(CC_LINK) -o kdb5_verify kdb5_verify.o $(KDB5_LIBS) $(KDB5_DEP_LIB) $(KRB5_BASE_LIBS) install: clean: $(RM) kdb5_verify.o kdb5_verify krb5-1.16/src/tests/t_salt.py0000755000704600001450000000657513211554426016007 0ustar ghudsonlibuuid#!/usr/bin/python from k5test import * import re realm = K5Realm(create_user=False) # Check that a non-default salt type applies only to the key it is # matched with and not to subsequent keys. e1 and e2 are enctypes, # and salt is a non-default salt type. def test_salt(realm, e1, salt, e2): keysalts = e1 + ':' + salt + ',' + e2 realm.run([kadminl, 'ank', '-e', keysalts, '-pw', 'password', 'user']) out = realm.run([kadminl, 'getprinc', 'user']) if len(re.findall(':' + salt, out)) != 1: fail(salt + ' present in second enctype or not present') realm.run([kadminl, 'delprinc', 'user']) # Enctype/salt pairs chosen with non-default salt types. # The enctypes are mostly arbitrary, though afs3 must only be used with des. # We do not enforce that v4 salts must only be used with des, but it seems # like a good idea. salts = [('des-cbc-crc', 'afs3'), ('des3-cbc-sha1', 'norealm'), ('arcfour-hmac', 'onlyrealm'), ('des-cbc-crc', 'v4'), ('aes128-cts-hmac-sha1-96', 'special')] # These enctypes are chosen to cover the different string-to-key routines. # Omit ":normal" from aes256 to check that salttype defaulting works. second_kstypes = ['aes256-cts-hmac-sha1-96', 'arcfour-hmac:normal', 'des3-cbc-sha1:normal', 'des-cbc-crc:normal'] # Test using different salt types in a principal's key list. # Parameters from one key in the list must not leak over to later ones. for e1, string in salts: for e2 in second_kstypes: test_salt(realm, e1, string, e2) def test_dup(realm, ks): realm.run([kadminl, 'ank', '-e', ks, '-pw', 'password', 'ks_princ']) out = realm.run([kadminl, 'getprinc', 'ks_princ']) lines = out.split('\n') keys = [l for l in lines if 'Key: ' in l] uniq = set(keys) # 'Key:' matches 'MKey:' as well so len(keys) has one extra if (len(uniq) != len(keys)) or len(keys) > len(ks.split(',')): fail('Duplicate keysalt detection failed for keysalt ' + ks) realm.run([kadminl, 'delprinc', 'ks_princ']) # All in-tree callers request duplicate suppression from # krb5_string_to_keysalts(); we should check that it works, respects # aliases, and doesn't result in an infinite loop. dup_kstypes = ['arcfour-hmac-md5:normal,rc4-hmac:normal', 'aes256-cts-hmac-sha1-96:normal,aes128-cts,aes256-cts', 'aes256-cts-hmac-sha1-96:normal,aes256-cts:special,' + 'aes256-cts-hmac-sha1-96:normal'] for ks in dup_kstypes: test_dup(realm, ks) # Attempt to create a principal with a non-des enctype and the afs3 salt, # verifying that the expected error is received and the principal creation # fails. def test_reject_afs3(realm, etype): query = 'ank -e ' + etype + ':afs3 -pw password princ1' realm.run([kadminl, 'ank', '-e', etype + ':afs3', '-pw', 'password', 'princ1'], expected_code=1, expected_msg='Invalid key generation parameters from KDC') realm.run([kadminl, 'getprinc', 'princ1'], expected_code=1, expected_msg='Principal does not exist') # Verify that the afs3 salt is rejected for arcfour and pbkdf2 enctypes. # We do not currently do any verification on the key-generation parameters # for the triple-DES enctypes, so that test is commented out. test_reject_afs3(realm, 'arcfour-hmac') test_reject_afs3(realm, 'aes256-cts-hmac-sha1-96') #test_reject_afs3(realm, 'des3-cbc-sha1') success("Salt types") krb5-1.16/src/tests/t_kprop.py0000755000704600001450000000641413211554426016167 0ustar ghudsonlibuuid#!/usr/bin/python from k5test import * conf_slave = {'dbmodules': {'db': {'database_name': '$testdir/db.slave'}}} def setup_acl(realm): acl_file = os.path.join(realm.testdir, 'kpropd-acl') acl = open(acl_file, 'w') acl.write(realm.host_princ + '\n') acl.close() def check_output(kpropd): output('*** kpropd output follows\n') while True: line = kpropd.stdout.readline() if 'Database load process for full propagation completed' in line: break output('kpropd: ' + line) if 'Rejected connection' in line: fail('kpropd rejected connection from kprop') # kprop/kpropd are the only users of krb5_auth_con_initivector, so run # this test over all enctypes to exercise mkpriv cipher state. for realm in multipass_realms(create_user=False): slave = realm.special_env('slave', True, kdc_conf=conf_slave) # Set up the kpropd acl file. setup_acl(realm) # Create the slave db. dumpfile = os.path.join(realm.testdir, 'dump') realm.run([kdb5_util, 'dump', dumpfile]) realm.run([kdb5_util, 'load', dumpfile], slave) realm.run([kdb5_util, 'stash', '-P', 'master'], slave) # Make some changes to the master db. realm.addprinc('wakawaka') # Start kpropd. kpropd = realm.start_kpropd(slave, ['-d']) realm.run([kdb5_util, 'dump', dumpfile]) realm.run([kprop, '-f', dumpfile, '-P', str(realm.kprop_port()), hostname]) check_output(kpropd) realm.run([kadminl, 'listprincs'], slave, expected_msg='wakawaka') # default_realm tests follow. # default_realm and domain_realm different than realm.realm (test -r argument). conf_slave2 = {'dbmodules': {'db': {'database_name': '$testdir/db.slave2'}}} krb5_conf_slave2 = {'libdefaults': {'default_realm': 'FOO'}, 'domain_realm': {hostname: 'FOO'}} # default_realm and domain_realm map differ. conf_slave3 = {'dbmodules': {'db': {'database_name': '$testdir/db.slave3'}}} krb5_conf_slave3 = {'domain_realm': {hostname: 'BAR'}} realm = K5Realm(create_user=False) slave2 = realm.special_env('slave2', True, kdc_conf=conf_slave2, krb5_conf=krb5_conf_slave2) slave3 = realm.special_env('slave3', True, kdc_conf=conf_slave3, krb5_conf=krb5_conf_slave3) setup_acl(realm) # Create the slave db. dumpfile = os.path.join(realm.testdir, 'dump') realm.run([kdb5_util, 'dump', dumpfile]) realm.run([kdb5_util, '-r', realm.realm, 'load', dumpfile], slave2) realm.run([kdb5_util, 'load', dumpfile], slave3) # Make some changes to the master db. realm.addprinc('wakawaka') # Test override of default_realm with -r realm argument. kpropd = realm.start_kpropd(slave2, ['-r', realm.realm, '-d']) realm.run([kdb5_util, 'dump', dumpfile]) realm.run([kprop, '-r', realm.realm, '-f', dumpfile, '-P', str(realm.kprop_port()), hostname]) check_output(kpropd) realm.run([kadminl, '-r', realm.realm, 'listprincs'], slave2, expected_msg='wakawaka') stop_daemon(kpropd) # Test default_realm and domain_realm mismatch. kpropd = realm.start_kpropd(slave3, ['-d']) realm.run([kdb5_util, 'dump', dumpfile]) realm.run([kprop, '-f', dumpfile, '-P', str(realm.kprop_port()), hostname]) check_output(kpropd) realm.run([kadminl, 'listprincs'], slave3, expected_msg='wakawaka') success('kprop tests') krb5-1.16/src/tests/t_errmsg.py0000755000704600001450000000235513211554426016333 0ustar ghudsonlibuuid#!/usr/bin/python from k5test import * realm = K5Realm(create_kdb=False) # Test err_fmt, using klist -c to induce errors. fmt1 = 'FOO Error: %M (see http://localhost:1234/%C for more information)' conf1 = {'libdefaults': {'err_fmt': fmt1}} e1 = realm.special_env('fmt1', False, krb5_conf=conf1) out = realm.run([klist, '-c', 'testdir/xx/yy'], env=e1, expected_code=1) if out != ('klist: FOO Error: No credentials cache found (filename: ' 'testdir/xx/yy) (see http://localhost:1234/-1765328189 for more ' 'information)\n'): fail('err_fmt expansion failed') conf2 = {'libdefaults': {'err_fmt': '%M - %C'}} e2 = realm.special_env('fmt2', False, krb5_conf=conf2) out = realm.run([klist, '-c', 'testdir/xx/yy'], env=e2, expected_code=1) if out != ('klist: No credentials cache found (filename: testdir/xx/yy) - ' '-1765328189\n'): fail('err_fmt expansion failed') conf3 = {'libdefaults': {'err_fmt': '%%%M %-% %C%'}} e3 = realm.special_env('fmt3', False, krb5_conf=conf3) out = realm.run([klist, '-c', 'testdir/xx/yy'], env=e3, expected_code=1) if out != ('klist: %No credentials cache found (filename: testdir/xx/yy) %-% ' '-1765328189%\n'): fail('err_fmt expansion failed') success('error message tests') krb5-1.16/src/tests/hist.c0000644000704600001450000000737313211554426015254 0ustar ghudsonlibuuid/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* tests/hist.c - Perform unusual operations on history keys */ /* * Copyright (C) 2012 by the Massachusetts Institute of Technology. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ /* * This program is invoked from t_pwhist.py to simulate some conditions * normally only seen in databases created before krb5 1.3. With the "make" * argument, the history key is rolled over to a kvno containing two keys * (since krb5 1.3 we ordinarily ensure that there's only one). With the * "swap" argument, the two history keys are swapped in order; we use this * operation to simulate the case where krb5 1.7 or earlier chose something * other than the first history key to create pasword history entries. */ #include #include static void check(krb5_error_code ret) { if (ret) { fprintf(stderr, "Unexpected failure, aborting\n"); abort(); } } int main(int argc, char **argv) { krb5_context ctx; krb5_db_entry *ent; krb5_principal hprinc; kadm5_principal_ent_rec kent; krb5_key_salt_tuple ks[2]; krb5_key_data kd; kadm5_config_params params = { 0 }; void *handle; char *realm; long mask = KADM5_PRINCIPAL | KADM5_MAX_LIFE | KADM5_ATTRIBUTES; check(kadm5_init_krb5_context(&ctx)); check(krb5_parse_name(ctx, "kadmin/history", &hprinc)); check(krb5_get_default_realm(ctx, &realm)); params.mask |= KADM5_CONFIG_REALM; params.realm = realm; check(kadm5_init(ctx, "user", "", "", ¶ms, KADM5_STRUCT_VERSION, KADM5_API_VERSION_4, NULL, &handle)); if (strcmp(argv[1], "make") == 0) { memset(&kent, 0, sizeof(kent)); kent.principal = hprinc; kent.max_life = KRB5_KDB_DISALLOW_ALL_TIX; kent.attributes = 0; ks[0].ks_enctype = ENCTYPE_AES256_CTS_HMAC_SHA1_96; ks[0].ks_salttype = KRB5_KDB_SALTTYPE_NORMAL; ks[1].ks_enctype = ENCTYPE_AES128_CTS_HMAC_SHA1_96; ks[1].ks_salttype = KRB5_KDB_SALTTYPE_NORMAL; check(kadm5_create_principal_3(handle, &kent, mask, 2, ks, NULL)); } else if (strcmp(argv[1], "swap") == 0) { check(krb5_db_get_principal(ctx, hprinc, 0, &ent)); kd = ent->key_data[0]; ent->key_data[0] = ent->key_data[1]; ent->key_data[1] = kd; check(krb5_db_put_principal(ctx, ent)); krb5_db_free_principal(ctx, ent); } krb5_free_default_realm(ctx, realm); kadm5_destroy(handle); krb5_free_principal(ctx, hprinc); krb5_free_context(ctx); return 0; } krb5-1.16/src/tests/t_kadmin_parsing.py0000644000704600001450000000734013211554426020016 0ustar ghudsonlibuuid#!/usr/bin/python from k5test import * # This file contains tests for kadmin command parsing. Principal # flags (which can also be used in kadm5.acl or krb5.conf) are tested # in t_princflags.py. # kadmin recognizes time intervals using either the # krb5_string_to_deltat() formats or the relative getdate.y formats. # (Absolute getdate.y formats also work with the current time # subtracted; this isn't very useful and we won't test it here.) intervals = ( # krb5_string_to_deltat() formats. Whitespace ( \t\n) is allowed # before or between most elements or at the end, but not after # 's'. Negative or oversized numbers are allowed in most places, # but not after the first number in an HH:MM:SS form. ('28s', '0 days 00:00:28'), ('7m ', '0 days 00:07:00'), ('6m 9s', '0 days 00:06:09'), ('2h', '0 days 02:00:00'), ('2h-5s', '0 days 01:59:55'), ('2h3m', '0 days 02:03:00'), ('2h3m5s', '0 days 02:03:05'), ('5d ', '5 days 00:00:00'), ('5d-48s', '4 days 23:59:12'), ('5d18m', '5 days 00:18:00'), ('5d -6m56s', '4 days 23:54:56'), ('5d4h', '5 days 04:00:00'), ('5d4h 1s', '5 days 04:00:01'), ('5d4h3m', '5 days 04:03:00'), (' \t 15d \n 4h 3m 2s', '15 days 04:03:02'), ('10-8:45:0', '10 days 08:45:00'), ('1000:67:99', '41 days 17:08:39'), ('999:11', '41 days 15:11:00'), ('382512', '4 days 10:15:12'), # getdate.y relative formats (and "never", which is handled # specially as a zero interval). Any number of relative forms can # be specified in any order. Whitespace is ignored before or # after any token. "month" and "year" are allowed as units but # depend on the current time, so we won't test them. Plural unit # names are treated identically to singular unit names. Numbers # before unit names are optional and may be signed; there are also # aliases for some numbers. "ago" inverts the interval up to the # point where it appears. ('never', '0 days 00:00:00'), ('fortnight', '14 days 00:00:00'), ('3 day ago 4 weeks 8 hours', '25 days 08:00:00'), ('8 second -3 secs 5 minute ago 63 min', '0 days 00:57:55'), ('min mins min mins min', '0 days 00:05:00'), ('tomorrow tomorrow today yesterday now last minute', '0 days 23:59:00'), ('this second next minute first hour third fortnight fourth day ' 'fifth weeks sixth sec seventh secs eighth second ninth mins tenth ' 'day eleventh min twelfth sec', '91 days 01:22:34')) realm = K5Realm(create_host=False, get_creds=False) realm.run([kadminl, 'addpol', 'pol']) for instr, outstr in intervals: realm.run([kadminl, 'modprinc', '-maxlife', instr, realm.user_princ]) msg = 'Maximum ticket life: ' + outstr + '\n' realm.run([kadminl, 'getprinc', realm.user_princ], expected_msg=msg) realm.run([kadminl, 'modprinc', '-maxrenewlife', instr, realm.user_princ]) msg = 'Maximum renewable life: ' + outstr + '\n' realm.run([kadminl, 'getprinc', realm.user_princ], expected_msg=msg) realm.run([kadminl, 'modpol', '-maxlife', instr, 'pol']) msg = 'Maximum password life: ' + outstr + '\n' realm.run([kadminl, 'getpol', 'pol'], expected_msg=msg) realm.run([kadminl, 'modpol', '-minlife', instr, 'pol']) msg = 'Minimum password life: ' + outstr + '\n' realm.run([kadminl, 'getpol', 'pol'], expected_msg=msg) realm.run([kadminl, 'modpol', '-failurecountinterval', instr, 'pol']) msg = 'Password failure count reset interval: ' + outstr + '\n' realm.run([kadminl, 'getpol', 'pol'], expected_msg=msg) realm.run([kadminl, 'modpol', '-lockoutduration', instr, 'pol']) msg = 'Password lockout duration: ' + outstr + '\n' realm.run([kadminl, 'getpol', 'pol'], expected_msg=msg) success('kadmin command parsing tests') krb5-1.16/src/tests/localauth.c0000644000704600001450000000461613211554426016256 0ustar ghudsonlibuuid/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* tests/localauth.c - test harness for kuserok and aname_to_lname */ /* * Copyright (C) 2013 by the Massachusetts Institute of Technology. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #include #include static krb5_context ctx; static void check(krb5_error_code code) { const char *errmsg; if (code) { errmsg = krb5_get_error_message(ctx, code); fprintf(stderr, "%s\n", errmsg); krb5_free_error_message(ctx, errmsg); exit(1); } } int main(int argc, char **argv) { krb5_principal princ; char buf[1024]; if (argc < 2 || argc > 3) { fprintf(stderr, "Usage: localauth principal [localuser]\n"); return 1; } check(krb5_init_context(&ctx)); check(krb5_parse_name(ctx, argv[1], &princ)); if (argc == 3) { printf("%s\n", krb5_kuserok(ctx, princ, argv[2]) ? "yes" : "no"); } else { check(krb5_aname_to_localname(ctx, princ, sizeof(buf), buf)); printf("%s\n", buf); } krb5_free_principal(ctx, princ); krb5_free_context(ctx); return 0; } krb5-1.16/src/tests/t_changepw.py0000755000704600001450000000263513211554426016631 0ustar ghudsonlibuuid#!/usr/bin/python from k5test import * # This file is intended to cover any password-changing mechanism. For # now it only contains a regression test for #7868. realm = K5Realm(create_host=False, get_creds=False, start_kadmind=True) # Mark a principal as expired and change its password through kinit. realm.run([kadminl, 'modprinc', '-pwexpire', '1 day ago', 'user']) pwinput = password('user') + '\nabcd\nabcd\n' realm.run([kinit, realm.user_princ], input=pwinput) # Do the same thing with FAST, with tracing turned on. realm.run([kadminl, 'modprinc', '-pwexpire', '1 day ago', 'user']) pwinput = 'abcd\nefgh\nefgh\n' tracefile = os.path.join(realm.testdir, 'trace') realm.run(['env', 'KRB5_TRACE=' + tracefile, kinit, '-T', realm.ccache, realm.user_princ], input=pwinput) # Read the trace and check that FAST was used when getting the # kadmin/changepw ticket. f = open(tracefile, 'r') trace = f.read() f.close() getting_changepw = fast_used_for_changepw = False for line in trace.splitlines(): if 'Getting initial credentials for user@' in line: getting_changepw_ticket = False if 'Setting initial creds service to kadmin/changepw' in line: getting_changepw_ticket = True if getting_changepw_ticket and 'Using FAST' in line: fast_used_for_changepw = True if not fast_used_for_changepw: fail('FAST was not used to get kadmin/changepw ticket') success('Password change tests') krb5-1.16/src/tests/t_unlockiter.py0000755000704600001450000000140013211554426017201 0ustar ghudsonlibuuid#!/usr/bin/python from k5test import * # Default KDB iteration is locked. Expect write lock failure unless # unlocked iteration is explicitly requested. realm = K5Realm(create_user=False, create_host=False, start_kdc=False) realm.run(['./unlockiter'], expected_code=1) realm.run(['./unlockiter', '-u']) realm.run(['./unlockiter', '-l'], expected_code=1) # Set default to unlocked iteration. Only explicitly requested locked # iteration should block the write lock. realm = K5Realm(create_user=False, create_host=False, start_kdc=False, krb5_conf={'dbmodules': {'db': {'unlockiter': 'true'}}}) realm.run(['./unlockiter']) realm.run(['./unlockiter', '-u']) realm.run(['./unlockiter', '-l'], expected_code=1) success('Unlocked iteration unit tests') krb5-1.16/src/tests/t_kdc_log.py0000755000704600001450000000116513211554426016434 0ustar ghudsonlibuuid#!/usr/bin/python from k5test import * # Make a TGS request with an expired ticket. realm = K5Realm() realm.stop() realm.start_kdc(['-T', '3600']) realm.run([kvno, realm.host_princ], expected_code=1) kdc_logfile = os.path.join(realm.testdir, 'kdc.log') f = open(kdc_logfile, 'r') found_skew = False for line in f: if 'Clock skew too great' in line: found_skew = True if realm.user_princ not in line: fail('Client principal not logged in expired-ticket TGS request') f.close() if not found_skew: fail('Did not find KDC log line for expired-ticket TGS request') success('KDC logging tests') krb5-1.16/src/tests/deps0000644000704600001450000002452313211554426015013 0ustar ghudsonlibuuid# # Generated makefile dependencies follow. # $(OUTPRE)adata.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h \ $(top_srcdir)/include/k5-err.h $(top_srcdir)/include/k5-gmt_mktime.h \ $(top_srcdir)/include/k5-int-pkinit.h $(top_srcdir)/include/k5-int.h \ $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-plugin.h \ $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/k5-trace.h \ $(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/authdata_plugin.h \ $(top_srcdir)/include/krb5/plugin.h $(top_srcdir)/include/port-sockets.h \ $(top_srcdir)/include/socket-utils.h adata.c $(OUTPRE)etinfo.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h \ $(top_srcdir)/include/k5-err.h $(top_srcdir)/include/k5-gmt_mktime.h \ $(top_srcdir)/include/k5-int-pkinit.h $(top_srcdir)/include/k5-int.h \ $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-plugin.h \ $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/k5-trace.h \ $(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/authdata_plugin.h \ $(top_srcdir)/include/krb5/plugin.h $(top_srcdir)/include/port-sockets.h \ $(top_srcdir)/include/socket-utils.h etinfo.c $(OUTPRE)forward.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h \ $(top_srcdir)/include/k5-err.h $(top_srcdir)/include/k5-gmt_mktime.h \ $(top_srcdir)/include/k5-int-pkinit.h $(top_srcdir)/include/k5-int.h \ $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-plugin.h \ $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/k5-trace.h \ $(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/authdata_plugin.h \ $(top_srcdir)/include/krb5/plugin.h $(top_srcdir)/include/port-sockets.h \ $(top_srcdir)/include/socket-utils.h forward.c $(OUTPRE)gcred.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h \ $(top_srcdir)/include/k5-err.h $(top_srcdir)/include/k5-gmt_mktime.h \ $(top_srcdir)/include/k5-int-pkinit.h $(top_srcdir)/include/k5-int.h \ $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-plugin.h \ $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/k5-trace.h \ $(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/authdata_plugin.h \ $(top_srcdir)/include/krb5/plugin.h $(top_srcdir)/include/port-sockets.h \ $(top_srcdir)/include/socket-utils.h gcred.c $(OUTPRE)hist.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/gssapi/gssapi.h $(BUILDTOP)/include/gssrpc/types.h \ $(BUILDTOP)/include/kadm5/admin.h $(BUILDTOP)/include/kadm5/chpass_util_strings.h \ $(BUILDTOP)/include/kadm5/kadm_err.h $(BUILDTOP)/include/krb5/krb5.h \ $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ $(COM_ERR_DEPS) $(top_srcdir)/include/gssrpc/auth.h \ $(top_srcdir)/include/gssrpc/auth_gss.h $(top_srcdir)/include/gssrpc/auth_unix.h \ $(top_srcdir)/include/gssrpc/clnt.h $(top_srcdir)/include/gssrpc/rename.h \ $(top_srcdir)/include/gssrpc/rpc.h $(top_srcdir)/include/gssrpc/rpc_msg.h \ $(top_srcdir)/include/gssrpc/svc.h $(top_srcdir)/include/gssrpc/svc_auth.h \ $(top_srcdir)/include/gssrpc/xdr.h $(top_srcdir)/include/k5-buf.h \ $(top_srcdir)/include/k5-err.h $(top_srcdir)/include/k5-gmt_mktime.h \ $(top_srcdir)/include/k5-int-pkinit.h $(top_srcdir)/include/k5-int.h \ $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-plugin.h \ $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/k5-trace.h \ $(top_srcdir)/include/kdb.h $(top_srcdir)/include/krb5.h \ $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/plugin.h \ $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \ hist.c $(OUTPRE)hooks.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h \ $(top_srcdir)/include/k5-err.h $(top_srcdir)/include/k5-gmt_mktime.h \ $(top_srcdir)/include/k5-int-pkinit.h $(top_srcdir)/include/k5-int.h \ $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-plugin.h \ $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/k5-trace.h \ $(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/authdata_plugin.h \ $(top_srcdir)/include/krb5/plugin.h $(top_srcdir)/include/port-sockets.h \ $(top_srcdir)/include/socket-utils.h hooks.c $(OUTPRE)hrealm.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h \ $(top_srcdir)/include/k5-err.h $(top_srcdir)/include/k5-gmt_mktime.h \ $(top_srcdir)/include/k5-int-pkinit.h $(top_srcdir)/include/k5-int.h \ $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-plugin.h \ $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/k5-trace.h \ $(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/authdata_plugin.h \ $(top_srcdir)/include/krb5/plugin.h $(top_srcdir)/include/port-sockets.h \ $(top_srcdir)/include/socket-utils.h hrealm.c $(OUTPRE)icinterleave.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h \ $(top_srcdir)/include/k5-err.h $(top_srcdir)/include/k5-gmt_mktime.h \ $(top_srcdir)/include/k5-int-pkinit.h $(top_srcdir)/include/k5-int.h \ $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-plugin.h \ $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/k5-trace.h \ $(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/authdata_plugin.h \ $(top_srcdir)/include/krb5/plugin.h $(top_srcdir)/include/port-sockets.h \ $(top_srcdir)/include/socket-utils.h icinterleave.c $(OUTPRE)icred.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/krb5/krb5.h $(COM_ERR_DEPS) $(top_srcdir)/include/k5-platform.h \ $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/krb5.h \ icred.c $(OUTPRE)kdbtest.$(OBJEXT): $(BUILDTOP)/include/gssapi/gssapi.h \ $(BUILDTOP)/include/gssrpc/types.h $(BUILDTOP)/include/kadm5/admin.h \ $(BUILDTOP)/include/kadm5/chpass_util_strings.h $(BUILDTOP)/include/kadm5/kadm_err.h \ $(BUILDTOP)/include/krb5/krb5.h $(COM_ERR_DEPS) $(top_srcdir)/include/gssrpc/auth.h \ $(top_srcdir)/include/gssrpc/auth_gss.h $(top_srcdir)/include/gssrpc/auth_unix.h \ $(top_srcdir)/include/gssrpc/clnt.h $(top_srcdir)/include/gssrpc/rename.h \ $(top_srcdir)/include/gssrpc/rpc.h $(top_srcdir)/include/gssrpc/rpc_msg.h \ $(top_srcdir)/include/gssrpc/svc.h $(top_srcdir)/include/gssrpc/svc_auth.h \ $(top_srcdir)/include/gssrpc/xdr.h $(top_srcdir)/include/kdb.h \ $(top_srcdir)/include/krb5.h kdbtest.c $(OUTPRE)localauth.$(OBJEXT): $(BUILDTOP)/include/krb5/krb5.h \ $(COM_ERR_DEPS) $(top_srcdir)/include/krb5.h localauth.c $(OUTPRE)plugorder.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/gssapi/gssapi.h $(BUILDTOP)/include/gssrpc/types.h \ $(BUILDTOP)/include/kadm5/admin.h $(BUILDTOP)/include/kadm5/chpass_util_strings.h \ $(BUILDTOP)/include/kadm5/kadm_err.h $(BUILDTOP)/include/krb5/krb5.h \ $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ $(COM_ERR_DEPS) $(top_srcdir)/include/gssrpc/auth.h \ $(top_srcdir)/include/gssrpc/auth_gss.h $(top_srcdir)/include/gssrpc/auth_unix.h \ $(top_srcdir)/include/gssrpc/clnt.h $(top_srcdir)/include/gssrpc/rename.h \ $(top_srcdir)/include/gssrpc/rpc.h $(top_srcdir)/include/gssrpc/rpc_msg.h \ $(top_srcdir)/include/gssrpc/svc.h $(top_srcdir)/include/gssrpc/svc_auth.h \ $(top_srcdir)/include/gssrpc/xdr.h $(top_srcdir)/include/k5-buf.h \ $(top_srcdir)/include/k5-err.h $(top_srcdir)/include/k5-gmt_mktime.h \ $(top_srcdir)/include/k5-int-pkinit.h $(top_srcdir)/include/k5-int.h \ $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-plugin.h \ $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/k5-trace.h \ $(top_srcdir)/include/kdb.h $(top_srcdir)/include/krb5.h \ $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/plugin.h \ $(top_srcdir)/include/krb5/pwqual_plugin.h $(top_srcdir)/include/port-sockets.h \ $(top_srcdir)/include/socket-utils.h plugorder.c $(OUTPRE)responder.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/krb5/krb5.h $(COM_ERR_DEPS) $(top_srcdir)/include/k5-json.h \ $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-thread.h \ $(top_srcdir)/include/krb5.h responder.c $(OUTPRE)s2p.$(OBJEXT): $(BUILDTOP)/include/krb5/krb5.h \ $(COM_ERR_DEPS) $(top_srcdir)/include/krb5.h s2p.c $(OUTPRE)s4u2proxy.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h \ $(top_srcdir)/include/k5-err.h $(top_srcdir)/include/k5-gmt_mktime.h \ $(top_srcdir)/include/k5-int-pkinit.h $(top_srcdir)/include/k5-int.h \ $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-plugin.h \ $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/k5-trace.h \ $(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/authdata_plugin.h \ $(top_srcdir)/include/krb5/plugin.h $(top_srcdir)/include/port-sockets.h \ $(top_srcdir)/include/socket-utils.h s4u2proxy.c $(OUTPRE)unlockiter.$(OBJEXT): $(BUILDTOP)/include/gssapi/gssapi.h \ $(BUILDTOP)/include/gssrpc/types.h $(BUILDTOP)/include/kadm5/admin.h \ $(BUILDTOP)/include/kadm5/chpass_util_strings.h $(BUILDTOP)/include/kadm5/kadm_err.h \ $(BUILDTOP)/include/krb5/krb5.h $(COM_ERR_DEPS) $(top_srcdir)/include/gssrpc/auth.h \ $(top_srcdir)/include/gssrpc/auth_gss.h $(top_srcdir)/include/gssrpc/auth_unix.h \ $(top_srcdir)/include/gssrpc/clnt.h $(top_srcdir)/include/gssrpc/rename.h \ $(top_srcdir)/include/gssrpc/rpc.h $(top_srcdir)/include/gssrpc/rpc_msg.h \ $(top_srcdir)/include/gssrpc/svc.h $(top_srcdir)/include/gssrpc/svc_auth.h \ $(top_srcdir)/include/gssrpc/xdr.h $(top_srcdir)/include/kdb.h \ $(top_srcdir)/include/krb5.h unlockiter.c krb5-1.16/src/tests/t_certauth.py0000644000704600001450000000365213211554426016651 0ustar ghudsonlibuuid#!/usr/bin/python from k5test import * # Skip this test if pkinit wasn't built. if not os.path.exists(os.path.join(plugins, 'preauth', 'pkinit.so')): skip_rest('certauth tests', 'PKINIT module not built') certs = os.path.join(srctop, 'tests', 'dejagnu', 'pkinit-certs') ca_pem = os.path.join(certs, 'ca.pem') kdc_pem = os.path.join(certs, 'kdc.pem') privkey_pem = os.path.join(certs, 'privkey.pem') user_pem = os.path.join(certs, 'user.pem') modpath = os.path.join(buildtop, 'plugins', 'certauth', 'test', 'certauth_test.so') pkinit_krb5_conf = {'realms': {'$realm': { 'pkinit_anchors': 'FILE:%s' % ca_pem}}, 'plugins': {'certauth': {'module': ['test1:' + modpath, 'test2:' + modpath], 'enable_only': ['test1', 'test2']}}} pkinit_kdc_conf = {'realms': {'$realm': { 'default_principal_flags': '+preauth', 'pkinit_eku_checking': 'none', 'pkinit_identity': 'FILE:%s,%s' % (kdc_pem, privkey_pem), 'pkinit_indicator': ['indpkinit1', 'indpkinit2']}}} file_identity = 'FILE:%s,%s' % (user_pem, privkey_pem) realm = K5Realm(krb5_conf=pkinit_krb5_conf, kdc_conf=pkinit_kdc_conf, get_creds=False) # Let the test module match user to CN=user, with indicators. realm.kinit(realm.user_princ, flags=['-X', 'X509_user_identity=%s' % file_identity]) realm.klist(realm.user_princ) realm.run([kvno, realm.host_princ]) realm.run(['./adata', realm.host_princ], expected_msg='+97: [test1, test2, user, indpkinit1, indpkinit2]') # Let the test module mismatch with user2 to CN=user. realm.addprinc("user2@KRBTEST.COM") out = realm.kinit("user2@KRBTEST.COM", flags=['-X', 'X509_user_identity=%s' % file_identity], expected_code=1, expected_msg='kinit: Certificate mismatch') success("certauth tests") krb5-1.16/src/tests/t_stringattr.py0000755000704600001450000000343413211554426017234 0ustar ghudsonlibuuid#!/usr/bin/python # Copyright (C) 2011 by the Massachusetts Institute of Technology. # All rights reserved. # Export of this software from the United States of America may # require a specific license from the United States Government. # It is the responsibility of any person or organization contemplating # export to obtain such a license before exporting. # # WITHIN THAT CONSTRAINT, permission to use, copy, modify, and # distribute this software and its documentation for any purpose and # without fee is hereby granted, provided that the above copyright # notice appear in all copies and that both that copyright notice and # this permission notice appear in supporting documentation, and that # the name of M.I.T. not be used in advertising or publicity pertaining # to distribution of the software without specific, written prior # permission. Furthermore if you modify this software you must label # your software as modified software and not distribute it in such a # fashion that it might be confused with the original M.I.T. software. # M.I.T. makes no representations about the suitability of # this software for any purpose. It is provided "as is" without express # or implied warranty. from k5test import * realm = K5Realm(start_kadmind=True, create_host=False, get_creds=False) realm.prep_kadmin() realm.run_kadmin(['getstrs', 'user'], expected_msg='(No string attributes.)') realm.run_kadmin(['setstr', 'user', 'attr1', 'value1']) realm.run_kadmin(['setstr', 'user', 'attr2', 'value2']) realm.run_kadmin(['delstr', 'user', 'attr1']) realm.run_kadmin(['setstr', 'user', 'attr3', 'value3']) out = realm.run_kadmin(['getstrs', 'user']) if ('attr2: value2' not in out or 'attr3: value3' not in out or 'attr1:' in out): fail('Final attribute query') success('KDB string attributes') krb5-1.16/src/tests/t_pwqual.py0000755000704600001450000000577713211554426016360 0ustar ghudsonlibuuid#!/usr/bin/python from k5test import * plugin = os.path.join(buildtop, "plugins", "pwqual", "test", "pwqual_test.so") dictfile = os.path.join(os.getcwd(), 'testdir', 'dict') pconf = {'plugins': {'pwqual': {'module': 'combo:' + plugin}}} dconf = {'realms': {'$realm': {'dict_file': dictfile}}} realm = K5Realm(krb5_conf=pconf, kdc_conf=dconf, create_user=False, create_host=False) # Write a short dictionary file. f = open(dictfile, 'w') f.write('birds\nbees\napples\noranges\n') f.close() realm.run([kadminl, 'addpol', 'pol']) # The built-in "empty" module rejects empty passwords even without a policy. realm.run([kadminl, 'addprinc', '-pw', '', 'p1'], expected_code=1, expected_msg='Empty passwords are not allowed') # The built-in "dict" module rejects dictionary words, but only with a policy. realm.run([kadminl, 'addprinc', '-pw', 'birds', 'p2']) realm.run([kadminl, 'addprinc', '-pw', 'birds', '-policy', 'pol', 'p3'], expected_code=1, expected_msg='Password is in the password dictionary') # The built-in "princ" module rejects principal components, only with a policy. realm.run([kadminl, 'addprinc', '-pw', 'p4', 'p4']) realm.run([kadminl, 'addprinc', '-pw', 'p5', '-policy', 'pol', 'p5'], expected_code=1, expected_msg='Password may not match principal name') # The dynamic "combo" module rejects pairs of dictionary words. realm.run([kadminl, 'addprinc', '-pw', 'birdsoranges', 'p6'], expected_code=1, expected_msg='Password may not be a pair of dictionary words') # These plugin ordering tests aren't specifically related to the # password quality interface, but are convenient to put here. def test_order(realm, testname, conf, expected): conf = {'plugins': {'pwqual': conf}} env = realm.special_env(testname, False, krb5_conf=conf) out = realm.run(['./plugorder'], env=env) if out.split() != expected: fail('order test: ' + testname) realm.stop() realm = K5Realm(create_kdb=False) # Check the test harness with no special configuration. test_order(realm, 'noconf', {}, ['blt1', 'blt2', 'blt3']) # Test the basic order: dynamic modules, then built-in modules, each # in registration order. conf = {'module': ['dyn3:' + plugin, 'dyn1:' + plugin, 'dyn2:' + plugin]} test_order(realm, 'basic', conf, ['dyn3', 'dyn1', 'dyn2', 'blt1', 'blt2', 'blt3']) # Disabling modules should not affect the order of other modules. conf['disable'] = ['dyn1', 'blt3'] test_order(realm, 'disable', conf, ['dyn3', 'dyn2', 'blt1', 'blt2']) # enable_only should reorder the modules, but can't resurrect disabled # modules or create ones from thin air. conf['enable_only'] = ['dyn2', 'blt3', 'blt2', 'dyn1', 'dyn3', 'xxx'] test_order(realm, 'enable_only', conf, ['dyn2', 'blt2', 'dyn3']) # Duplicate modules should be pruned by preferring earlier entries. conf = {'module': ['dyn3:' + plugin, 'dyn1:' + plugin, 'dyn3:' + plugin]} test_order(realm, 'duplicate', conf, ['dyn3', 'dyn1', 'blt1', 'blt2', 'blt3']) success('Password quality interface tests') krb5-1.16/src/tests/icinterleave.c0000644000704600001450000001020213211554426016740 0ustar ghudsonlibuuid/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* tests/icinterleave.c - interleaved init_creds_step test harness */ /* * Copyright (C) 2017 by the Massachusetts Institute of Technology. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ /* * This test harness performs multiple initial creds operations using * krb5_init_creds_step(), interleaving the operations to test the scoping of * the preauth state. All principals must have the same password (or not * require a password). */ #include "k5-int.h" static krb5_context ctx; static void check(krb5_error_code code) { const char *errmsg; if (code) { errmsg = krb5_get_error_message(ctx, code); fprintf(stderr, "%s\n", errmsg); krb5_free_error_message(ctx, errmsg); exit(1); } } int main(int argc, char **argv) { const char *password; char **princstrs; krb5_principal client; krb5_init_creds_context *iccs; krb5_data req, *reps, realm; krb5_boolean any_left; int i, nclients, master; unsigned int flags; if (argc < 3) { fprintf(stderr, "Usage: icinterleave password princ1 princ2 ...\n"); exit(1); } password = argv[1]; princstrs = argv + 2; nclients = argc - 2; check(krb5_init_context(&ctx)); /* Create an initial creds context for each client principal. */ iccs = calloc(nclients, sizeof(*iccs)); assert(iccs != NULL); for (i = 0; i < nclients; i++) { check(krb5_parse_name(ctx, princstrs[i], &client)); check(krb5_init_creds_init(ctx, client, NULL, NULL, 0, NULL, &iccs[i])); check(krb5_init_creds_set_password(ctx, iccs[i], password)); krb5_free_principal(ctx, client); } reps = calloc(nclients, sizeof(*reps)); assert(reps != NULL); any_left = TRUE; while (any_left) { any_left = FALSE; for (i = 0; i < nclients; i++) { if (iccs[i] == NULL) continue; any_left = TRUE; printf("step %d\n", i + 1); req = empty_data(); realm = empty_data(); check(krb5_init_creds_step(ctx, iccs[i], &reps[i], &req, &realm, &flags)); if (!(flags & KRB5_INIT_CREDS_STEP_FLAG_CONTINUE)) { printf("finish %d\n", i + 1); krb5_init_creds_free(ctx, iccs[i]); iccs[i] = NULL; continue; } master = 0; krb5_free_data_contents(ctx, &reps[i]); check(krb5_sendto_kdc(ctx, &req, &realm, &reps[i], &master, 0)); krb5_free_data_contents(ctx, &req); krb5_free_data_contents(ctx, &realm); } } for (i = 0; i < nclients; i++) krb5_free_data_contents(ctx, &reps[i]); free(reps); free(iccs); krb5_free_context(ctx); return 0; } krb5-1.16/src/tests/t_keytab.py0000755000704600001450000001255213211554426016313 0ustar ghudsonlibuuid#!/usr/bin/python from k5test import * for realm in multipass_realms(create_user=False): # Test kinit with a keytab. realm.kinit(realm.host_princ, flags=['-k']) realm = K5Realm(get_creds=False, start_kadmind=True) # Test kinit with a partial keytab. pkeytab = realm.keytab + '.partial' realm.run([ktutil], input=('rkt %s\ndelent 1\nwkt %s\n' % (realm.keytab, pkeytab))) realm.kinit(realm.host_princ, flags=['-k', '-t', pkeytab]) # Test kinit with no keys for client in keytab. realm.kinit(realm.user_princ, flags=['-k'], expected_code=1, expected_msg='no suitable keys') # Test kinit and klist with client keytab defaults. realm.extract_keytab(realm.user_princ, realm.client_keytab); realm.run([kinit, '-k', '-i']) realm.klist(realm.user_princ) realm.run([kdestroy]) realm.kinit(realm.user_princ, flags=['-k', '-i']) realm.klist(realm.user_princ) out = realm.run([klist, '-k', '-i']) if realm.client_keytab not in out or realm.user_princ not in out: fail('Expected output not seen from klist -k -i') # Test implicit request for keytab (-i or -t without -k) realm.run([kdestroy]) realm.kinit(realm.host_princ, flags=['-t', realm.keytab], expected_msg='keytab specified, forcing -k') realm.klist(realm.host_princ) realm.run([kdestroy]) realm.kinit(realm.user_princ, flags=['-i'], expected_msg='keytab specified, forcing -k') realm.klist(realm.user_princ) # Test extracting keys with multiple key versions present. os.remove(realm.keytab) realm.run([kadminl, 'cpw', '-randkey', '-keepold', realm.host_princ]) out = realm.run([kadminl, 'ktadd', '-norandkey', realm.host_princ]) if 'with kvno 1,' not in out or 'with kvno 2,' not in out: fail('Expected output not seen from kadmin.local ktadd -norandkey') out = realm.run([klist, '-k', '-e']) if ' 1 host/' not in out or ' 2 host/' not in out: fail('Expected output not seen from klist -k -e') # Test again using kadmin over the network. realm.prep_kadmin() os.remove(realm.keytab) out = realm.run_kadmin(['ktadd', '-norandkey', realm.host_princ]) if 'with kvno 1,' not in out or 'with kvno 2,' not in out: fail('Expected output not seen from kadmin.local ktadd -norandkey') out = realm.run([klist, '-k', '-e']) if ' 1 host/' not in out or ' 2 host/' not in out: fail('Expected output not seen from klist -k -e') # Test handling of kvno values beyond 255. Use kadmin over the # network since we used to have an 8-bit limit on kvno marshalling. # Test one key rotation, verifying that the expected new kvno appears # in the keytab and in the principal entry. def test_key_rotate(realm, princ, expected_kvno): realm.run_kadmin(['ktadd', '-k', realm.keytab, princ]) realm.run([kadminl, 'ktrem', princ, 'old']) realm.kinit(princ, flags=['-k']) msg = '%d %s' % (expected_kvno, princ) out = realm.run([klist, '-k'], expected_msg=msg) msg = 'Key: vno %d,' % expected_kvno out = realm.run_kadmin(['getprinc', princ], expected_msg=msg) princ = 'foo/bar@%s' % realm.realm realm.addprinc(princ) os.remove(realm.keytab) realm.run([kadminl, 'modprinc', '-kvno', '253', princ]) test_key_rotate(realm, princ, 254) test_key_rotate(realm, princ, 255) test_key_rotate(realm, princ, 256) test_key_rotate(realm, princ, 257) realm.run([kadminl, 'modprinc', '-kvno', '32766', princ]) test_key_rotate(realm, princ, 32767) test_key_rotate(realm, princ, 32768) test_key_rotate(realm, princ, 32769) realm.run([kadminl, 'modprinc', '-kvno', '65534', princ]) test_key_rotate(realm, princ, 65535) test_key_rotate(realm, princ, 1) test_key_rotate(realm, princ, 2) # Test that klist -k can read a keytab entry without a 32-bit kvno and # reports the 8-bit key version. record = '\x00\x01' # principal component count record += '\x00\x0bKRBTEST.COM' # realm record += '\x00\x04user' # principal component record += '\x00\x00\x00\x01' # name type (NT-PRINCIPAL) record += '\x54\xf7\x4d\x35' # timestamp record += '\x02' # key version record += '\x00\x12' # enctype record += '\x00\x20' # key length record += '\x00' * 32 # key bytes f = open(realm.keytab, 'w') f.write('\x05\x02\x00\x00\x00' + chr(len(record))) f.write(record) f.close() msg = ' 2 %s' % realm.user_princ out = realm.run([klist, '-k'], expected_msg=msg) # Make sure zero-fill isn't treated as a 32-bit kvno. f = open(realm.keytab, 'w') f.write('\x05\x02\x00\x00\x00' + chr(len(record) + 4)) f.write(record) f.write('\x00\x00\x00\x00') f.close() msg = ' 2 %s' % realm.user_princ out = realm.run([klist, '-k'], expected_msg=msg) # Make sure a hand-crafted 32-bit kvno is recognized. f = open(realm.keytab, 'w') f.write('\x05\x02\x00\x00\x00' + chr(len(record) + 4)) f.write(record) f.write('\x00\x00\x00\x03') f.close() msg = ' 3 %s' % realm.user_princ out = realm.run([klist, '-k'], expected_msg=msg) # Test parameter expansion in profile variables realm.stop() conf = {'libdefaults': { 'default_keytab_name': 'testdir/%{null}abc%{uid}', 'default_client_keytab_name': 'testdir/%{null}xyz%{uid}'}} realm = K5Realm(krb5_conf=conf, create_kdb=False) del realm.env['KRB5_KTNAME'] del realm.env['KRB5_CLIENT_KTNAME'] uidstr = str(os.getuid()) msg = 'FILE:testdir/abc%s' % uidstr out = realm.run([klist, '-k'], expected_code=1, expected_msg=msg) msg = 'FILE:testdir/xyz%s' % uidstr out = realm.run([klist, '-ki'], expected_code=1, expected_msg=msg) success('Keytab-related tests') krb5-1.16/src/tests/forward.c0000644000704600001450000000652113211554426015743 0ustar ghudsonlibuuid/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* tests/forward.c - test harness for getting forwarded creds */ /* * Copyright (C) 2016 by the Massachusetts Institute of Technology. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ /* This test program overwrites the default credential cache with a forwarded * TGT obtained using the TGT presently in the cache. */ #include "k5-int.h" static krb5_context ctx; static void check(krb5_error_code code) { const char *errmsg; if (code) { errmsg = krb5_get_error_message(ctx, code); fprintf(stderr, "%s\n", errmsg); krb5_free_error_message(ctx, errmsg); exit(1); } } int main() { krb5_ccache cc; krb5_creds mcred, tgt, *fcred; krb5_principal client, tgtprinc; krb5_flags options; /* Open the default ccache and get the client and TGT principal names. */ check(krb5_init_context(&ctx)); check(krb5_cc_default(ctx, &cc)); check(krb5_cc_get_principal(ctx, cc, &client)); check(krb5_build_principal_ext(ctx, &tgtprinc, client->realm.length, client->realm.data, KRB5_TGS_NAME_SIZE, KRB5_TGS_NAME, client->realm.length, client->realm.data, 0)); /* Fetch the TGT credential. */ memset(&mcred, 0, sizeof(mcred)); mcred.client = client; mcred.server = tgtprinc; check(krb5_cc_retrieve_cred(ctx, cc, 0, &mcred, &tgt)); /* Get a forwarded TGT. */ mcred.times = tgt.times; mcred.times.starttime = 0; options = (tgt.ticket_flags & KDC_TKT_COMMON_MASK) | KDC_OPT_FORWARDED; check(krb5_get_cred_via_tkt(ctx, &tgt, options, NULL, &mcred, &fcred)); /* Reinitialize the default ccache with the forwarded TGT. */ check(krb5_cc_initialize(ctx, cc, client)); check(krb5_cc_store_cred(ctx, cc, fcred)); krb5_free_creds(ctx, fcred); krb5_free_cred_contents(ctx, &tgt); krb5_free_principal(ctx, tgtprinc); krb5_free_principal(ctx, client); krb5_cc_close(ctx, cc); krb5_free_context(ctx); return 0; } krb5-1.16/src/tests/t_etype_info.py0000644000704600001450000001006213211554426017164 0ustar ghudsonlibuuid#!/usr/bin/python from k5test import * supported_enctypes = 'aes128-cts des3-cbc-sha1 rc4-hmac des-cbc-crc:afs3' conf = {'libdefaults': {'allow_weak_crypto': 'true'}, 'realms': {'$realm': {'supported_enctypes': supported_enctypes}}} realm = K5Realm(create_host=False, get_creds=False, krb5_conf=conf) realm.run([kadminl, 'addprinc', '-pw', 'pw', '+requires_preauth', 'preauthuser']) realm.run([kadminl, 'addprinc', '-pw', 'pw', '-e', 'rc4-hmac', '+requires_preauth', 'rc4user']) realm.run([kadminl, 'addprinc', '-nokey', '+requires_preauth', 'nokeyuser']) # Run the test harness for the given principal and request enctype # list. Compare the output to the expected lines, ignoring order. def test_etinfo(princ, enctypes, expected_lines): lines = realm.run(['./etinfo', princ, enctypes]).splitlines() if sorted(lines) != sorted(expected_lines): fail('Unexpected output for princ %s, etypes %s' % (princ, enctypes)) # With no newer enctypes in the request, PA-ETYPE-INFO2, # PA-ETYPE-INFO, and PA-PW-SALT appear in the AS-REP, each listing one # key for the most preferred matching enctype. test_etinfo('user', 'rc4-hmac-exp des3 rc4 des-cbc-crc', ['asrep etype_info2 des3-cbc-sha1 KRBTEST.COMuser', 'asrep etype_info des3-cbc-sha1 KRBTEST.COMuser', 'asrep pw_salt KRBTEST.COMuser']) # With a newer enctype in the request (even if it is not the most # preferred enctype and doesn't match any keys), only PA-ETYPE-INFO2 # appears. test_etinfo('user', 'rc4 aes256-cts', ['asrep etype_info2 rc4-hmac KRBTEST.COMuser']) # In preauth-required errors, PA-PW-SALT does not appear, but the same # etype-info2 values are expected. test_etinfo('preauthuser', 'rc4-hmac-exp des3 rc4 des-cbc-crc', ['error etype_info2 des3-cbc-sha1 KRBTEST.COMpreauthuser', 'error etype_info des3-cbc-sha1 KRBTEST.COMpreauthuser']) test_etinfo('preauthuser', 'rc4 aes256-cts', ['error etype_info2 rc4-hmac KRBTEST.COMpreauthuser']) # AFS3 salt for DES enctypes is conveyed using s2kparams in # PA-ETYPE-INFO2, not at all in PA-ETYPE-INFO, and with a special padata # type instead of PA-PW-SALT. test_etinfo('user', 'des-cbc-crc rc4', ['asrep etype_info2 des-cbc-crc KRBTEST.COM 01', 'asrep etype_info des-cbc-crc KRBTEST.COM', 'asrep afs3_salt KRBTEST.COM']) test_etinfo('preauthuser', 'des-cbc-crc rc4', ['error etype_info2 des-cbc-crc KRBTEST.COM 01', 'error etype_info des-cbc-crc KRBTEST.COM']) # DES keys can be used with other DES enctypes. The requested enctype # shows up in the etype-info, not the database key enctype. test_etinfo('user', 'des-cbc-md4 rc4', ['asrep etype_info2 des-cbc-md4 KRBTEST.COM 01', 'asrep etype_info des-cbc-md4 KRBTEST.COM', 'asrep afs3_salt KRBTEST.COM']) test_etinfo('user', 'des-cbc-md5 rc4', ['asrep etype_info2 des KRBTEST.COM 01', 'asrep etype_info des KRBTEST.COM', 'asrep afs3_salt KRBTEST.COM']) # If no keys are found matching the request enctypes, a # preauth-required error can be generated with no etype-info at all # (to allow for preauth mechs which don't depend on long-term keys). # An AS-REP cannot be generated without preauth as there is no reply # key. test_etinfo('rc4user', 'des3', []) test_etinfo('nokeyuser', 'des3', []) # Verify that etype-info2 is included in a MORE_PREAUTH_DATA_REQUIRED # error if the client does optimistic preauth. realm.stop() testpreauth = os.path.join(buildtop, 'plugins', 'preauth', 'test', 'test.so') conf = {'plugins': {'kdcpreauth': {'module': 'test:' + testpreauth}, 'clpreauth': {'module': 'test:' + testpreauth}}} realm = K5Realm(create_host=False, get_creds=False, krb5_conf=conf) realm.run([kadminl, 'setstr', realm.user_princ, '2rt', '2rtval']) out = realm.run(['./etinfo', realm.user_princ, 'aes128-cts', '-123']) if out != 'more etype_info2 aes128-cts KRBTEST.COMuser\n': fail('Unexpected output for MORE_PREAUTH_DATA_REQUIRED test') success('KDC etype-info tests') krb5-1.16/src/tests/t_kadm5_hook.py0000755000704600001450000000102613211554426017047 0ustar ghudsonlibuuid#!/usr/bin/python from k5test import * plugin = os.path.join(buildtop, "plugins", "kadm5_hook", "test", "kadm5_hook_test.so") hook_krb5_conf = {'plugins': {'kadm5_hook': { 'module': 'test:' + plugin}}} realm = K5Realm(krb5_conf=hook_krb5_conf, create_user=False, create_host=False) realm.run([kadminl, 'addprinc', '-randkey', 'test'], expected_msg='create: stage precommit') realm.run([kadminl, 'renprinc', 'test', 'test2'], expected_msg='rename: stage precommit') success('kadm5_hook') krb5-1.16/src/tests/t_rdreq.py0000755000704600001450000001123213211554426016143 0ustar ghudsonlibuuid#!/usr/bin/python from k5test import * conf = {'realms': {'$realm': {'supported_enctypes': 'aes256-cts aes128-cts'}}} realm = K5Realm(create_host=False, kdc_conf=conf) # Define some server principal names. princ1 = 'host/1@%s' % realm.realm princ2 = 'host/2@%s' % realm.realm princ3 = 'HTTP/3@%s' % realm.realm princ4 = 'HTTP/4@%s' % realm.realm matchprinc = 'host/@' nomatchprinc = 'x/@' realm.addprinc(princ1) realm.addprinc(princ2) realm.addprinc(princ3) def test(tserver, server, expected): args = ['./rdreq', tserver] if server is not None: args += [server] out = realm.run(args) if out.strip() != expected: fail('unexpected rdreq output') # No keytab present. nokeytab_err = "45 Key table file '%s' not found" % realm.keytab test(princ1, None, nokeytab_err) test(princ1, princ1, nokeytab_err) test(princ1, matchprinc, nokeytab_err) # Keytab present, successful decryption. realm.extract_keytab(princ1, realm.keytab) test(princ1, None, '0 success') test(princ1, princ1, '0 success') test(princ1, matchprinc, '0 success') # Explicit server principal not found in keytab. test(princ2, princ2, '45 No key table entry found for host/2@KRBTEST.COM') # Matching server principal does not match any entries in keytab (with # and without ticket server present in keytab). nomatch_err = '45 Server principal x/@ does not match any keys in keytab' test(princ1, nomatchprinc, nomatch_err) test(princ2, nomatchprinc, nomatch_err) # Ticket server does not match explicit server principal (with and # without ticket server present in keytab). test(princ1, princ2, '45 No key table entry found for host/2@KRBTEST.COM') test(princ2, princ1, '35 Cannot decrypt ticket for host/2@KRBTEST.COM using keytab key for ' 'host/1@KRBTEST.COM') # Ticket server not found in keytab during iteration. test(princ2, None, '35 Request ticket server host/2@KRBTEST.COM not found in keytab ' '(ticket kvno 1)') # Ticket server found in keytab but is not matched by server principal # (but other principals in keytab do match). realm.extract_keytab(princ3, realm.keytab) test(princ3, matchprinc, '35 Request ticket server HTTP/3@KRBTEST.COM found in keytab but does ' 'not match server principal host/@') # Service ticket is out of date. os.remove(realm.keytab) realm.run([kadminl, 'ktadd', princ1]) test(princ1, None, '44 Request ticket server host/1@KRBTEST.COM kvno 1 not found in keytab; ' 'ticket is likely out of date') test(princ1, princ1, '44 Cannot find key for host/1@KRBTEST.COM kvno 1 in keytab') # kvno mismatch due to ticket principal mismatch with explicit server. test(princ2, princ1, '35 Cannot find key for host/1@KRBTEST.COM kvno 1 in keytab (request ' 'ticket server host/2@KRBTEST.COM)') # Keytab is out of date. realm.run([kadminl, 'cpw', '-randkey', princ1]) realm.kinit(realm.user_princ, password('user')) test(princ1, None, '44 Request ticket server host/1@KRBTEST.COM kvno 3 not found in keytab; ' 'keytab is likely out of date') test(princ1, princ1, '44 Cannot find key for host/1@KRBTEST.COM kvno 3 in keytab') # Ticket server and kvno found but not with ticket enctype. os.remove(realm.keytab) realm.extract_keytab(princ1, realm.keytab) pkeytab = realm.keytab + '.partial' realm.run([ktutil], input=('rkt %s\ndelent 1\nwkt %s\n' % (realm.keytab, pkeytab))) os.rename(pkeytab, realm.keytab) realm.run([klist, '-ke']) test(princ1, None, '44 Request ticket server host/1@KRBTEST.COM kvno 3 found in keytab but ' 'not with enctype aes256-cts') # This is a bad code (KRB_AP_ERR_NOKEY) and message, because # krb5_kt_get_entry returns the same result for this and not finding # the principal at all. But it's an uncommon case; GSSAPI apps # usually use a matching principal and missing key enctypes are rare. test(princ1, princ1, '45 No key table entry found for host/1@KRBTEST.COM') # Ticket server, kvno, and enctype matched, but key does not work. realm.run([kadminl, 'cpw', '-randkey', princ1]) realm.run([kadminl, 'modprinc', '-kvno', '3', princ1]) os.remove(realm.keytab) realm.extract_keytab(princ1, realm.keytab) test(princ1, None, '31 Request ticket server host/1@KRBTEST.COM kvno 3 enctype aes256-cts ' 'found in keytab but cannot decrypt ticket') test(princ1, princ1, '31 Cannot decrypt ticket for host/1@KRBTEST.COM using keytab key for ' 'host/1@KRBTEST.COM') # Test that aliases work. The ticket server (princ4) isn't present in # keytab, but there is a usable princ1 entry with the same key. realm.run([kadminl, 'renprinc', princ1, princ4]) test(princ4, None, '0 success') test(princ4, princ1, '0 success') test(princ4, matchprinc, '0 success') success('krb5_rd_req tests') krb5-1.16/src/tests/t_referral.py0000755000704600001450000001270713211554426016640 0ustar ghudsonlibuuid#!/usr/bin/python from k5test import * # Create a pair of realms, where KRBTEST1.COM can authenticate to # REFREALM and has a domain-realm mapping for 'd' pointing to it. drealm = {'domain_realm': {'d': 'REFREALM'}} realm, refrealm = cross_realms(2, xtgts=((0,1),), args=({'kdc_conf': drealm}, {'realm': 'REFREALM', 'create_user': False}), create_host=False) refrealm.addprinc('a/x.d') savefile = os.path.join(realm.testdir, 'ccache.copy') os.rename(realm.ccache, savefile) # Get credentials and check that we got a referral to REFREALM. def testref(realm, nametype): shutil.copyfile(savefile, realm.ccache) realm.run(['./gcred', nametype, 'a/x.d@']) out = realm.run([klist]).split('\n') if len(out) != 8: fail('unexpected number of lines in klist output') if out[5].split()[4] != 'a/x.d@' or out[6].split()[4] != 'a/x.d@REFREALM': fail('unexpected service principals in klist output') # Get credentials and check that we get an error, not a referral. def testfail(realm, nametype): shutil.copyfile(savefile, realm.ccache) realm.run(['./gcred', nametype, 'a/x.d@'], expected_code=1, expected_msg='not found in Kerberos database') # Create a modified KDC environment and restart the KDC. def restart_kdc(realm, kdc_conf): env = realm.special_env('extravars', True, kdc_conf=kdc_conf) realm.stop_kdc() realm.start_kdc(env=env) # With no KDC configuration besides [domain_realm], we should get a # referral for a NT-SRV-HST or NT-SRV-INST server name, but not an # NT-UNKNOWN or NT-PRINCIPAL server name. testref(realm, 'srv-hst') testref(realm, 'srv-inst') testfail(realm, 'principal') testfail(realm, 'unknown') # With host_based_services matching the first server name component # ("a"), we should get a referral for an NT-UNKNOWN server name. # host_based_services can appear in either [kdcdefaults] or the realm # section, with the realm values supplementing the kdcdefaults values. # NT-SRV-HST server names should be unaffected by host_based_services, # and NT-PRINCIPAL server names shouldn't get a referral regardless. restart_kdc(realm, {'kdcdefaults': {'host_based_services': '*'}}) testref(realm, 'unknown') testfail(realm, 'principal') restart_kdc(realm, {'kdcdefaults': {'host_based_services': ['b', 'a,c']}}) testref(realm, 'unknown') restart_kdc(realm, {'realms': {'$realm': {'host_based_services': 'a b c'}}}) testref(realm, 'unknown') restart_kdc(realm, {'kdcdefaults': {'host_based_services': 'a'}, 'realms': {'$realm': {'host_based_services': 'b c'}}}) testref(realm, 'unknown') restart_kdc(realm, {'kdcdefaults': {'host_based_services': 'b,c'}, 'realms': {'$realm': {'host_based_services': 'a,b'}}}) testref(realm, 'unknown') restart_kdc(realm, {'kdcdefaults': {'host_based_services': 'b,c'}}) testfail(realm, 'unknown') testref(realm, 'srv-hst') # With no_host_referrals matching the first server name component, we # should not get a referral even for NT-SRV-HOST server names restart_kdc(realm, {'kdcdefaults': {'no_host_referral': '*'}}) testfail(realm, 'srv-hst') restart_kdc(realm, {'kdcdefaults': {'no_host_referral': ['b', 'a,c']}}) testfail(realm, 'srv-hst') restart_kdc(realm, {'realms': {'$realm': {'no_host_referral': 'a b c'}}}) testfail(realm, 'srv-hst') restart_kdc(realm, {'kdcdefaults': {'no_host_referral': 'a'}, 'realms': {'$realm': {'no_host_referral': 'b c'}}}) testfail(realm, 'srv-hst') restart_kdc(realm, {'kdcdefaults': {'no_host_referral': 'b,c'}, 'realms': {'$realm': {'no_host_referral': 'a,b'}}}) testfail(realm, 'srv-hst') restart_kdc(realm, {'kdcdefaults': {'no_host_referral': 'b,c'}}) testref(realm, 'srv-hst') # no_host_referrals should override host_based_services for NT-UNKNWON # server names. restart_kdc(realm, {'kdcdefaults': {'no_host_referral': '*', 'host_based_services': '*'}}) testfail(realm, 'unknown') realm.stop() refrealm.stop() # Regression test for #7483: a KDC should not return a host referral # to its own realm. drealm = {'domain_realm': {'d': 'KRBTEST.COM'}} realm = K5Realm(kdc_conf=drealm, create_host=False) tracefile = os.path.join(realm.testdir, 'trace') realm.run(['env', 'KRB5_TRACE=' + tracefile, './gcred', 'srv-hst', 'a/x.d@'], expected_code=1) f = open(tracefile, 'r') trace = f.read() f.close() if 'back to same realm' in trace: fail('KDC returned referral to service realm') realm.stop() # Test client referrals. Use the test KDB module for KRBTEST1.COM to # simulate referrals since our built-in modules do not support them. # No cross-realm TGTs are necessary. kdcconf = {'realms': {'$realm': {'database_module': 'test'}}, 'dbmodules': {'test': {'db_library': 'test', 'alias': {'user': '@KRBTEST2.COM', 'abc@XYZ': '@KRBTEST2.COM'}}}} r1, r2 = cross_realms(2, xtgts=(), args=({'kdc_conf': kdcconf, 'create_kdb': False}, None), create_host=False) r2.addprinc('abc\@XYZ', 'pw') r1.start_kdc() r1.kinit('user', expected_code=1, expected_msg='not found in Kerberos database') r1.kinit('user', password('user'), ['-C']) r1.klist('user@KRBTEST2.COM', 'krbtgt/KRBTEST2.COM') r1.kinit('abc@XYZ', 'pw', ['-E']) r1.klist('abc\@XYZ@KRBTEST2.COM', 'krbtgt/KRBTEST2.COM') success('KDC host referral tests') krb5-1.16/src/tests/t_skew.py0000755000704600001450000000421113211554426015776 0ustar ghudsonlibuuid#!/usr/bin/python from k5test import * # Create a realm with the KDC one hour in the past. realm = K5Realm(start_kdc=False) realm.start_kdc(['-T', '-3600']) # kinit (no preauth) should work, and should set a clock skew allowing # kvno to work, with or without FAST. realm.kinit(realm.user_princ, password('user')) realm.run([kvno, realm.host_princ]) realm.kinit(realm.user_princ, password('user'), flags=['-T', realm.ccache]) realm.run([kvno, realm.host_princ]) realm.run([kdestroy]) # kinit (with preauth) should work, with or without FAST. realm.run([kadminl, 'modprinc', '+requires_preauth', 'user']) realm.kinit(realm.user_princ, password('user')) realm.run([kvno, realm.host_princ]) realm.kinit(realm.user_princ, password('user'), flags=['-T', realm.ccache]) realm.run([kvno, realm.host_princ]) realm.run([kdestroy]) realm.stop() # Repeat the above tests with kdc_timesync disabled. conf = {'libdefaults': {'kdc_timesync': '0'}} realm = K5Realm(start_kdc=False, krb5_conf=conf) realm.start_kdc(['-T', '-3600']) # Get tickets to use for FAST kinit tests. The start time offset is # ignored by the KDC since we aren't getting postdatable tickets, but # serves to suppress the client clock skew check on the KDC reply. fast_cache = realm.ccache + '.fast' realm.kinit(realm.user_princ, password('user'), flags=['-s', '-3600s', '-c', fast_cache]) # kinit should detect too much skew in the KDC response. kinit with # FAST should fail from the KDC since the armor AP-REQ won't be valid. realm.kinit(realm.user_princ, password('user'), expected_code=1, expected_msg='Clock skew too great in KDC reply') realm.kinit(realm.user_princ, None, flags=['-T', fast_cache], expected_code=1, expected_msg='Clock skew too great while') # kinit (with preauth) should fail from the KDC, with or without FAST. realm.run([kadminl, 'modprinc', '+requires_preauth', 'user']) realm.kinit(realm.user_princ, password('user'), expected_code=1, expected_msg='Clock skew too great while') realm.kinit(realm.user_princ, None, flags=['-T', fast_cache], expected_code=1, expected_msg='Clock skew too great while') success('Clock skew tests') krb5-1.16/src/tests/create/0000755000704600001450000000000013211554426015372 5ustar ghudsonlibuuidkrb5-1.16/src/tests/create/deps0000644000704600001450000000143713211554426016255 0ustar ghudsonlibuuid# # Generated makefile dependencies follow. # $(OUTPRE)kdb5_mkdums.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(SS_DEPS) \ $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \ $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-int-pkinit.h \ $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \ $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \ $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/kdb.h \ $(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/authdata_plugin.h \ $(top_srcdir)/include/krb5/plugin.h $(top_srcdir)/include/port-sockets.h \ $(top_srcdir)/include/socket-utils.h kdb5_mkdums.c krb5-1.16/src/tests/create/kdb5_mkdums.c0000644000704600001450000003201113211554426017740 0ustar ghudsonlibuuid/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* tests/create/kdb5_mkdums.c */ /* * Copyright 1990,1991 by the Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ /* * * Edit a KDC database. */ #include "k5-int.h" #include "kdb.h" #include "com_err.h" #include #include #define REALM_SEP '@' #define REALM_SEP_STR "@" struct mblock { krb5_deltat max_life; krb5_deltat max_rlife; krb5_timestamp expiration; krb5_flags flags; krb5_kvno mkvno; } mblock = { /* XXX */ KRB5_KDB_MAX_LIFE, KRB5_KDB_MAX_RLIFE, KRB5_KDB_EXPIRATION, KRB5_KDB_DEF_FLAGS, 1 }; int set_dbname_help (char *, char *); static void usage(who, status) char *who; int status; { fprintf(stderr, "usage: %s -p prefix -n num_to_create [-d dbpathname] [-r realmname]\n", who); fprintf(stderr, "\t [-D depth] [-k enctype] [-M mkeyname]\n"); exit(status); } int master_princ_set = 0; krb5_keyblock master_keyblock; krb5_principal master_princ; krb5_pointer master_random; krb5_context test_context; static char *progname; static char *cur_realm = 0; static char *mkey_name = 0; static char *mkey_password = 0; static krb5_boolean manual_mkey = FALSE; void add_princ (krb5_context, char *); int main(argc, argv) int argc; char *argv[]; { extern char *optarg; int optchar, i, n; char tmp[4096], tmp2[BUFSIZ], *str_newprinc; krb5_error_code retval; char *dbname = 0; int enctypedone = 0; int num_to_create; char principal_string[BUFSIZ]; char *suffix = 0; size_t suffix_size = 0; int depth; krb5_init_context(&test_context); if (strrchr(argv[0], '/')) argv[0] = strrchr(argv[0], '/')+1; progname = argv[0]; memset(principal_string, 0, sizeof(principal_string)); num_to_create = 0; depth = 1; while ((optchar = getopt(argc, argv, "D:P:p:n:d:r:k:M:e:m")) != -1) { switch(optchar) { case 'D': depth = atoi(optarg); /* how deep to go */ break; case 'P': /* Only used for testing!!! */ mkey_password = optarg; break; case 'p': /* prefix name to create */ strncpy(principal_string, optarg, sizeof(principal_string) - 1); principal_string[sizeof(principal_string) - 1] = '\0'; suffix = principal_string + strlen(principal_string); suffix_size = sizeof(principal_string) - (suffix - principal_string); break; case 'n': /* how many to create */ num_to_create = atoi(optarg); break; case 'd': /* set db name */ dbname = optarg; break; case 'r': cur_realm = optarg; break; case 'k': master_keyblock.enctype = atoi(optarg); enctypedone++; break; case 'M': /* master key name in DB */ mkey_name = optarg; break; case 'm': manual_mkey = TRUE; break; case '?': default: usage(progname, 1); /*NOTREACHED*/ } } if (!(num_to_create && suffix)) usage(progname, 1); if (!enctypedone) master_keyblock.enctype = DEFAULT_KDC_ENCTYPE; if (!krb5_c_valid_enctype(master_keyblock.enctype)) { com_err(progname, KRB5_PROG_ETYPE_NOSUPP, "while setting up enctype %d", master_keyblock.enctype); exit(1); } if (!dbname) dbname = DEFAULT_KDB_FILE; /* XXX? */ if (!cur_realm) { if ((retval = krb5_get_default_realm(test_context, &cur_realm))) { com_err(progname, retval, "while retrieving default realm name"); exit(1); } } if ((retval = set_dbname_help(progname, dbname))) exit(retval); for (n = 1; n <= num_to_create; n++) { /* build the new principal name */ /* we can't pick random names because we need to generate all the names again given a prefix and count to test the db lib and kdb */ (void) snprintf(suffix, suffix_size, "%d", n); (void) snprintf(tmp, sizeof(tmp), "%s-DEPTH-1", principal_string); tmp[sizeof(tmp) - 1] = '\0'; str_newprinc = tmp; add_princ(test_context, str_newprinc); for (i = 2; i <= depth; i++) { (void) snprintf(tmp2, sizeof(tmp2), "/%s-DEPTH-%d", principal_string, i); tmp2[sizeof(tmp2) - 1] = '\0'; strncat(tmp, tmp2, sizeof(tmp) - 1 - strlen(tmp)); str_newprinc = tmp; add_princ(test_context, str_newprinc); } } retval = krb5_db_fini(test_context); memset(master_keyblock.contents, 0, (size_t) master_keyblock.length); if (retval && retval != KRB5_KDB_DBNOTINITED) { com_err(progname, retval, "while closing database"); exit(1); } if (master_princ_set) krb5_free_principal(test_context, master_princ); krb5_free_context(test_context); exit(0); } void add_princ(context, str_newprinc) krb5_context context; char * str_newprinc; { krb5_error_code retval; krb5_principal newprinc; krb5_db_entry *newentry; char princ_name[4096]; newentry = calloc(1, sizeof(*newentry)); if (newentry == NULL) { com_err(progname, ENOMEM, "while allocating DB entry"); return; } snprintf(princ_name, sizeof(princ_name), "%s@%s", str_newprinc, cur_realm); if ((retval = krb5_parse_name(context, princ_name, &newprinc))) { com_err(progname, retval, "while parsing '%s'", princ_name); return; } /* Add basic data */ newentry->len = KRB5_KDB_V1_BASE_LENGTH; newentry->attributes = mblock.flags; newentry->max_life = mblock.max_life; newentry->max_renewable_life = mblock.max_rlife; newentry->expiration = mblock.expiration; newentry->pw_expiration = mblock.expiration; /* Add princ to db entry */ if ((retval = krb5_copy_principal(context, newprinc, &newentry->princ))) { com_err(progname, retval, "while encoding princ to db entry for '%s'", princ_name); krb5_free_principal(context, newprinc); goto error; } { /* Add mod princ to db entry */ krb5_timestamp now; retval = krb5_timeofday(context, &now); if (retval) { com_err(progname, retval, "while fetching date"); krb5_free_principal(context, newprinc); goto error; } retval = krb5_dbe_update_mod_princ_data(context, newentry, now, master_princ); if (retval) { com_err(progname, retval, "while encoding mod_princ data"); krb5_free_principal(context, newprinc); goto error; } } { /* Add key and salt data to db entry */ krb5_data pwd, salt; krb5_keyblock key; if ((retval = krb5_principal2salt(context, newprinc, &salt))) { com_err(progname, retval, "while converting princ to salt for '%s'", princ_name); krb5_free_principal(context, newprinc); goto error; } krb5_free_principal(context, newprinc); pwd.length = strlen(princ_name); pwd.data = princ_name; /* must be able to regenerate */ if ((retval = krb5_c_string_to_key(context, master_keyblock.enctype, &pwd, &salt, &key))) { com_err(progname,retval,"while converting password to key for '%s'", princ_name); krb5_free_data_contents(context, &salt); goto error; } krb5_free_data_contents(context, &salt); if ((retval = krb5_dbe_create_key_data(context, newentry))) { com_err(progname, retval, "while creating key_data for '%s'", princ_name); free(key.contents); goto error; } if ((retval = krb5_dbe_encrypt_key_data(context, &master_keyblock, &key, NULL, 1, newentry->key_data))) { com_err(progname, retval, "while encrypting key for '%s'", princ_name); free(key.contents); goto error; } free(key.contents); } if ((retval = krb5_db_put_principal(context, newentry))) { com_err(progname, retval, "while storing principal date"); goto error; } error: /* Do cleanup of newentry regardless of error */ krb5_db_free_principal(context, newentry); return; } int set_dbname_help(pname, dbname) char *pname; char *dbname; { krb5_error_code retval; krb5_data pwd, scratch; char *args[2]; krb5_db_entry *master_entry; /* assemble & parse the master key name */ if ((retval = krb5_db_setup_mkey_name(test_context, mkey_name, cur_realm, 0, &master_princ))) { com_err(pname, retval, "while setting up master key name"); return(1); } master_princ_set = 1; if (mkey_password) { pwd.data = mkey_password; pwd.length = strlen(mkey_password); retval = krb5_principal2salt(test_context, master_princ, &scratch); if (retval) { com_err(pname, retval, "while calculated master key salt"); return(1); } if ((retval = krb5_c_string_to_key(test_context, master_keyblock.enctype, &pwd, &scratch, &master_keyblock))) { com_err(pname, retval, "while transforming master key from password"); return(1); } free(scratch.data); } else { if ((retval = krb5_db_fetch_mkey(test_context, master_princ, master_keyblock.enctype, manual_mkey, FALSE, 0, NULL, NULL, &master_keyblock))) { com_err(pname, retval, "while reading master key"); return(1); } } /* Ick! Current DAL interface requires that the default_realm field be set in the krb5_context. */ if ((retval = krb5_set_default_realm(test_context, cur_realm))) { com_err(pname, retval, "setting default realm"); return 1; } /* Pathname is passed to db2 via 'args' parameter. */ args[1] = NULL; if (asprintf(&args[0], "dbname=%s", dbname) < 0) { com_err(pname, errno, "while setting up db parameters"); return 1; } if ((retval = krb5_db_open(test_context, args, KRB5_KDB_OPEN_RO))) { com_err(pname, retval, "while initializing database"); return(1); } /* Done with args */ free(args[0]); if ((retval = krb5_db_fetch_mkey_list(test_context, master_princ, &master_keyblock))){ com_err(pname, retval, "while verifying master key"); (void) krb5_db_fini(test_context); return(1); } if ((retval = krb5_db_get_principal(test_context, master_princ, 0, &master_entry))) { com_err(pname, retval, "while retrieving master entry"); (void) krb5_db_fini(test_context); return(1); } mblock.max_life = master_entry->max_life; mblock.max_rlife = master_entry->max_renewable_life; mblock.expiration = master_entry->expiration; /* don't set flags, master has some extra restrictions */ mblock.mkvno = master_entry->key_data[0].key_data_kvno; krb5_db_free_principal(test_context, master_entry); return 0; } krb5-1.16/src/tests/create/Makefile.in0000644000704600001450000000055013211554426017437 0ustar ghudsonlibuuidmydir=tests$(S)create BUILDTOP=$(REL)..$(S).. SRCS=$(srcdir)/kdb5_mkdums.c KDB5_DEP_LIBS=$(THREAD_LINKOPTS) $(DL_LIB) all: kdb5_mkdums kdb5_mkdums: kdb5_mkdums.o $(KDB5_DEPLIBS) $(KRB5_BASE_DEPLIBS) $(CC_LINK) -o kdb5_mkdums kdb5_mkdums.o $(KDB5_DEP_LIBS) $(KDB5_LIBS) $(KRB5_BASE_LIBS) all: kdb5_mkdums install: clean: $(RM) kdb5_mkdums.o kdb5_mkdums krb5-1.16/src/tests/t_mkey.py0000755000704600001450000003502413211554426016000 0ustar ghudsonlibuuid#!/usr/bin/python from k5test import * import random import re import struct # Convenience constants for use as expected enctypes. defetype is the # default enctype for master keys. aes256 = 'aes256-cts-hmac-sha1-96' aes128 = 'aes128-cts-hmac-sha1-96' des3 = 'des3-cbc-sha1' defetype = aes256 realm = K5Realm(create_host=False, start_kadmind=True) realm.prep_kadmin() stash_file = os.path.join(realm.testdir, 'stash') # Count the number of principals in the realm. nprincs = len(realm.run([kadminl, 'listprincs']).splitlines()) # List the currently active mkeys and compare against expected # results. Each argument must be a sequence of four elements: an # expected kvno, an expected enctype, whether the key is expected to # have an activation time, and whether the key is expected to be # currently active. list_mkeys_re = re.compile(r'^KVNO: (\d+), Enctype: (\S+), ' '(Active on: [^\*]+|No activate time set)( \*)?$') def check_mkey_list(*expected): # Split the output of kdb5_util list_mkeys into lines and ignore the first. outlines = realm.run([kdb5_util, 'list_mkeys']).splitlines()[1:] if len(outlines) != len(expected): fail('Unexpected number of list_mkeys output lines') for line, ex in zip(outlines, expected): m = list_mkeys_re.match(line) if not m: fail('Unrecognized list_mkeys output line') kvno, enctype, act_time, active = m.groups() exp_kvno, exp_enctype, exp_act_time_present, exp_active = ex if kvno != str(exp_kvno): fail('Unexpected master key version') if enctype != exp_enctype: fail('Unexpected master key enctype') if act_time.startswith('Active on: ') != exp_act_time_present: fail('Unexpected presence or absence of mkey activation time') if (active == ' *') != exp_active: fail('Master key unexpectedly active or inactive') # Get the K/M principal. Verify that it has the expected mkvno. Each # remaining argment must be a sequence of two elements: an expected # key version and an expected enctype. keyline_re = re.compile(r'^Key: vno (\d+), (\S+)$') def check_master_dbent(expected_mkvno, *expected_keys): outlines = realm.run([kadminl, 'getprinc', 'K/M']).splitlines() mkeyline = [l for l in outlines if l.startswith('MKey: vno ')] if len(mkeyline) != 1 or mkeyline[0] != ('MKey: vno %d' % expected_mkvno): fail('Unexpected mkvno in K/M DB entry') keylines = [l for l in outlines if l.startswith('Key: vno ')] if len(keylines) != len(expected_keys): fail('Unexpected number of key lines in K/M DB entry') for line, ex in zip(keylines, expected_keys): m = keyline_re.match(line) if not m: fail('Unrecognized key line in K/M DB entry') kvno, enctype = m.groups() exp_kvno, exp_enctype = ex if kvno != str(exp_kvno): fail('Unexpected key version in K/M DB entry') if enctype != exp_enctype: fail('Unexpected enctype in K/M DB entry') # Check the stash file. Each argument must be a sequence of two # elements: an expected key version and an expected enctype. klist_re = re.compile(r'^\s*(\d+) K/M@KRBTEST.COM \((\S+)\)') def check_stash(*expected): # Split the output of klist -e -k into lines and ignore the first three. outlines = realm.run([klist, '-e', '-k', stash_file]).splitlines()[3:] if len(outlines) != len(expected): fail('Unexpected number of lines in stash file klist') for line, ex in zip(outlines, expected): m = klist_re.match(line) if not m: fail('Unrecognized stash file klist line') kvno, enctype = m.groups() exp_kvno, exp_enctype = ex if kvno != str(exp_kvno): fail('Unexpected stash file klist kvno') if enctype != exp_enctype: fail('Unexpected stash file klist enctype') # Verify that the user principal has the expected mkvno. def check_mkvno(princ, expected_mkvno): msg = 'MKey: vno %d\n' % expected_mkvno realm.run([kadminl, 'getprinc', princ], expected_msg=msg) # Change the password using either kadmin.local or kadmin, then check # the mkvno of the principal against expected_mkvno and verify that # the running KDC can access the new key. def change_password_check_mkvno(local, princ, password, expected_mkvno): cmd = ['cpw', '-pw', password, princ] if local: realm.run([kadminl] + cmd) else: realm.run_kadmin(cmd) check_mkvno(princ, expected_mkvno) realm.kinit(princ, password) # Add a master key with the specified options and a random password. def add_mkey(options): pw = ''.join(random.choice(string.ascii_uppercase) for x in range(5)) realm.run([kdb5_util, 'add_mkey'] + options, input=(pw + '\n' + pw + '\n')) # Run kdb5_util update_princ_encryption (with the dry-run option if # specified) and verify the output against the expected mkvno, number # of updated principals, and number of already-current principals. mkvno_re = {False: re.compile(r'^Principals whose keys are being re-encrypted ' 'to master key vno (\d+) if necessary:$'), True: re.compile(r'^Principals whose keys WOULD BE re-encrypted ' 'to master key vno (\d+):$')} count_re = {False: re.compile(r'^(\d+) principals processed: (\d+) updated, ' '(\d+) already current$'), True: re.compile(r'^(\d+) principals processed: (\d+) would be ' 'updated, (\d+) already current$')} def update_princ_encryption(dry_run, expected_mkvno, expected_updated, expected_current): opts = ['-f', '-v'] if dry_run: opts += ['-n'] out = realm.run([kdb5_util, 'update_princ_encryption'] + opts) lines = out.splitlines() # Parse the first line to get the target mkvno. m = mkvno_re[dry_run].match(lines[0]) if not m: fail('Unexpected first line of update_princ_encryption output') if m.group(1) != str(expected_mkvno): fail('Unexpected master key version in update_princ_encryption output') # Parse the last line to get the principal counts. m = count_re[dry_run].match(lines[-1]) if not m: fail('Unexpected last line of update_princ_encryption output') total, updated, current = m.groups() if (total != str(expected_updated + expected_current) or updated != str(expected_updated) or current != str(expected_current)): fail('Unexpected counts from update_princ_encryption') # Check the initial state of the realm. check_mkey_list((1, defetype, True, True)) check_master_dbent(1, (1, defetype)) check_stash((1, defetype)) check_mkvno(realm.user_princ, 1) # Check that stash will fail if a temp stash file is already present. collisionfile = os.path.join(realm.testdir, 'stash_tmp') f = open(collisionfile, 'w') f.close() realm.run([kdb5_util, 'stash'], expected_code=1, expected_msg='Temporary stash file already exists') os.unlink(collisionfile) # Add a new master key with no options. Verify that: # 1. The new key appears in list_mkeys but has no activation time and # is not active. # 2. The new key appears in the K/M DB entry and is the current key to # encrypt that entry. # 3. The stash file is not modified (since we did not pass -s). # 4. The old key is used for password changes. add_mkey([]) check_mkey_list((2, defetype, False, False), (1, defetype, True, True)) check_master_dbent(2, (2, defetype), (1, defetype)) change_password_check_mkvno(True, realm.user_princ, 'abcd', 1) change_password_check_mkvno(False, realm.user_princ, 'user', 1) # Verify that use_mkey won't make all master keys inactive. realm.run([kdb5_util, 'use_mkey', '1', 'now+1day'], expected_code=1, expected_msg='there must be one master key currently active') check_mkey_list((2, defetype, False, False), (1, defetype, True, True)) # Make the new master key active. Verify that: # 1. The new key has an activation time in list_mkeys and is active. # 2. The new key is used for password changes. # 3. The running KDC can access the new key. realm.run([kdb5_util, 'use_mkey', '2', 'now-1day']) check_mkey_list((2, defetype, True, True), (1, defetype, True, False)) change_password_check_mkvno(True, realm.user_princ, 'abcd', 2) change_password_check_mkvno(False, realm.user_princ, 'user', 2) # Check purge_mkeys behavior with both master keys still in use. realm.run([kdb5_util, 'purge_mkeys', '-f', '-v'], expected_msg='All keys in use, nothing purged.') # Do an update_princ_encryption dry run and for real. Verify that: # 1. The target master key is 2 (the active mkvno). # 2. nprincs - 2 principals were updated and one principal was # skipped (K/M is not included in the output and user was updated # above). # 3. The dry run doesn't change user/admin's mkvno but the real update # does. # 4. The old stashed master key is sufficient to access the DB (via # MKEY_AUX tl-data which keeps the current master key encrypted in # each of the old master keys). update_princ_encryption(True, 2, nprincs - 2, 1) check_mkvno(realm.admin_princ, 1) update_princ_encryption(False, 2, nprincs - 2, 1) check_mkvno(realm.admin_princ, 2) realm.stop_kdc() realm.start_kdc() realm.kinit(realm.user_princ, 'user') # Update all principals back to mkvno 1 and to mkvno 2 again, to # verify that update_princ_encryption targets the active master key. realm.run([kdb5_util, 'use_mkey', '2', 'now+1day']) update_princ_encryption(False, 1, nprincs - 1, 0) check_mkvno(realm.user_princ, 1) realm.run([kdb5_util, 'use_mkey', '2', 'now-1day']) update_princ_encryption(False, 2, nprincs - 1, 0) check_mkvno(realm.user_princ, 2) # Test the safety check for purging with an outdated stash file. realm.run([kdb5_util, 'purge_mkeys', '-f'], expected_code=1, expected_msg='stash file needs updating') # Update the master stash file and check it. Save a copy of the old # one for a later test. shutil.copy(stash_file, stash_file + '.old') realm.run([kdb5_util, 'stash']) check_stash((2, defetype), (1, defetype)) # Do a purge_mkeys dry run and for real. Verify that: # 1. Master key 1 is purged. # 2. The dry run doesn't remove mkvno 1 but the real one does. # 3. The old stash file is no longer sufficient to access the DB. # 4. If the stash file is updated, it no longer contains mkvno 1. # 5. use_mkey now gives an error if we refer to mkvno 1. # 6. A second purge_mkeys gives the right message. out = realm.run([kdb5_util, 'purge_mkeys', '-v', '-n', '-f']) if 'KVNO: 1' not in out or '1 key(s) would be purged' not in out: fail('Unexpected output from purge_mkeys dry-run') check_mkey_list((2, defetype, True, True), (1, defetype, True, False)) check_master_dbent(2, (2, defetype), (1, defetype)) out = realm.run([kdb5_util, 'purge_mkeys', '-v', '-f']) check_mkey_list((2, defetype, True, True)) check_master_dbent(2, (2, defetype)) os.rename(stash_file, stash_file + '.save') os.rename(stash_file + '.old', stash_file) realm.run([kadminl, 'getprinc', 'user'], expected_code=1, expected_msg='Unable to decrypt latest master key') os.rename(stash_file + '.save', stash_file) realm.run([kdb5_util, 'stash']) check_stash((2, defetype)) realm.run([kdb5_util, 'use_mkey', '1'], expected_code=1, expected_msg='1 is an invalid KVNO value') realm.run([kdb5_util, 'purge_mkeys', '-f', '-v'], expected_msg='There is only one master key which can not be purged.') # Add a third master key with a specified enctype. Verify that: # 1. The new master key receives the correct number. # 2. The enctype argument is respected. # 3. The new master key is stashed (by itself, at the moment). # 4. We can roll over to the new master key and use it. add_mkey(['-s', '-e', aes128]) check_mkey_list((3, aes128, False, False), (2, defetype, True, True)) check_master_dbent(3, (3, aes128), (2, defetype)) check_stash((3, aes128)) realm.run([kdb5_util, 'use_mkey', '3', 'now-1day']) update_princ_encryption(False, 3, nprincs - 1, 0) check_mkey_list((3, aes128, True, True), (2, defetype, True, False)) check_mkvno(realm.user_princ, 3) # Regression test for #7994 (randkey does not update principal mkvno) # and #7995 (-keepold does not re-encrypt old keys). add_mkey(['-s']) realm.run([kdb5_util, 'use_mkey', '4', 'now-1day']) realm.run([kadminl, 'cpw', '-randkey', '-keepold', realm.user_princ]) # With #7994 unfixed, mkvno of user will still be 3. check_mkvno(realm.user_princ, 4) # With #7995 unfixed, old keys are still encrypted with mkvno 3. update_princ_encryption(False, 4, nprincs - 2, 1) realm.run([kdb5_util, 'purge_mkeys', '-f']) out = realm.run([kadminl, 'xst', '-norandkey', realm.user_princ]) if 'Decrypt integrity check failed' in out or 'added to keytab' not in out: fail('Preserved old key data not updated to new master key') realm.stop() # Load a dump file created with krb5 1.6, before the master key # rollover changes were introduced. Write out an old-format stash # file consistent with the dump's master password ("footes"). The K/M # entry in this database will not have actkvno tl-data because it was # created prior to master key rollover support. Verify that: # 1. We can access the database using the old-format stash file. # 2. list_mkeys displays the same list as for a post-1.7 KDB. dumpfile = os.path.join(srctop, 'tests', 'dumpfiles', 'dump.16') os.remove(stash_file) f = open(stash_file, 'w') f.write(struct.pack('=HL24s', 16, 24, '\xF8\x3E\xFB\xBA\x6D\x80\xD9\x54\xE5\x5D\xF2\xE0' '\x94\xAD\x6D\x86\xB5\x16\x37\xEC\x7C\x8A\xBC\x86')) f.close() realm.run([kdb5_util, 'load', dumpfile]) nprincs = len(realm.run([kadminl, 'listprincs']).splitlines()) check_mkvno('K/M', 1) check_mkey_list((1, des3, True, True)) # Create a new master key and verify that, without actkvkno tl-data: # 1. list_mkeys displays the same as for a post-1.7 KDB. # 2. update_princ_encryption still targets mkvno 1. # 3. libkadm5 still uses mkvno 1 for key changes. # 4. use_mkey creates the same list as for a post-1.7 KDB. add_mkey([]) check_mkey_list((2, defetype, False, False), (1, des3, True, True)) update_princ_encryption(False, 1, 0, nprincs - 1) realm.run([kadminl, 'addprinc', '-randkey', realm.user_princ]) check_mkvno(realm.user_princ, 1) realm.run([kdb5_util, 'use_mkey', '2', 'now-1day']) check_mkey_list((2, defetype, True, True), (1, des3, True, False)) # Regression test for #8395. Purge the master key and verify that a # master key fetch does not segfault. realm.run([kadminl, 'purgekeys', '-all', 'K/M']) realm.run([kadminl, 'getprinc', realm.user_princ], expected_code=1, expected_msg='Cannot find master key record in database') success('Master key rollover tests') krb5-1.16/src/tests/adata.c0000644000704600001450000002443513211554426015355 0ustar ghudsonlibuuid/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* tests/adata.c - Test harness for KDC authorization data */ /* * Copyright (C) 2014 by the Massachusetts Institute of Technology. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ /* * Usage: ./adata [-c ccname] [-p clientprinc] serviceprinc * [ad-type ad-contents ...] * * This program acquires credentials for the specified service principal, using * the specified or default ccache, possibly including requested authdata. The * resulting ticket is decrypted using the default keytab, and the authdata in * the ticket are displayed to stdout. * * In the requested authdata types, the type may be prefixed with '?' for an * AD-IF-RELEVANT container, '!' for an AD-MANDATORY-FOR-KDC container, or '^' * for an AD-KDC-ISSUED container checksummed with a random AES256 key. * Multiple prefixes may be specified for nested container. * * In the output, authdata containers will be flattened and displayed with the * above prefixes or '+' for an AD-CAMMAC container. AD-KDC-ISSUED and * AD-CAMMAC containers will be verified with the appropriate key. Nested * containers only display the prefix for the innermost container. */ #include #include static krb5_context ctx; static void display_authdata_list(krb5_authdata **list, krb5_keyblock *skey, krb5_keyblock *tktkey, char prefix_byte); static void check(krb5_error_code code) { const char *errmsg; if (code) { errmsg = krb5_get_error_message(ctx, code); fprintf(stderr, "%s\n", errmsg); krb5_free_error_message(ctx, errmsg); exit(1); } } static krb5_authdatatype get_type_for_prefix(int prefix_byte) { if (prefix_byte == '?') return KRB5_AUTHDATA_IF_RELEVANT; if (prefix_byte == '!') return KRB5_AUTHDATA_MANDATORY_FOR_KDC; if (prefix_byte == '^') return KRB5_AUTHDATA_KDC_ISSUED; if (prefix_byte == '+') return KRB5_AUTHDATA_CAMMAC; abort(); } static int get_prefix_byte(krb5_authdata *ad) { if (ad->ad_type == KRB5_AUTHDATA_IF_RELEVANT) return '?'; if (ad->ad_type == KRB5_AUTHDATA_MANDATORY_FOR_KDC) return '!'; if (ad->ad_type == KRB5_AUTHDATA_KDC_ISSUED) return '^'; if (ad->ad_type == KRB5_AUTHDATA_CAMMAC) return '+'; abort(); } /* Construct a container of type ad_type for the single authdata element * content. For KDC-ISSUED containers, use a random checksum key. */ static krb5_authdata * make_container(krb5_authdatatype ad_type, krb5_authdata *content) { krb5_authdata *list[2], **enclist, *ad; krb5_keyblock kb; list[0] = content; list[1] = NULL; if (ad_type == KRB5_AUTHDATA_KDC_ISSUED) { check(krb5_c_make_random_key(ctx, ENCTYPE_AES256_CTS_HMAC_SHA1_96, &kb)); check(krb5_make_authdata_kdc_issued(ctx, &kb, NULL, list, &enclist)); krb5_free_keyblock_contents(ctx, &kb); } else { check(krb5_encode_authdata_container(ctx, ad_type, list, &enclist)); } /* Grab the first element from the encoded list and free the array. */ ad = enclist[0]; free(enclist); return ad; } /* Parse typestr and contents into an authdata element. */ static krb5_authdata * make_authdata(const char *typestr, const char *contents) { krb5_authdata *inner_ad, *ad; if (*typestr == '?' || *typestr == '!' || *typestr == '^') { inner_ad = make_authdata(typestr + 1, contents); ad = make_container(get_type_for_prefix(*typestr), inner_ad); free(inner_ad->contents); free(inner_ad); return ad; } ad = malloc(sizeof(*ad)); assert(ad != NULL); ad->magic = KV5M_AUTHDATA; ad->ad_type = atoi(typestr); ad->length = strlen(contents); ad->contents = (unsigned char *)strdup(contents); assert(ad->contents != NULL); return ad; } static krb5_authdata ** get_container_contents(krb5_authdata *ad, krb5_keyblock *skey, krb5_keyblock *tktkey) { krb5_authdata **inner_ad; if (ad->ad_type == KRB5_AUTHDATA_KDC_ISSUED) check(krb5_verify_authdata_kdc_issued(ctx, skey, ad, NULL, &inner_ad)); else if (ad->ad_type == KRB5_AUTHDATA_CAMMAC) check(k5_unwrap_cammac_svc(ctx, ad, tktkey, &inner_ad)); else check(krb5_decode_authdata_container(ctx, ad->ad_type, ad, &inner_ad)); return inner_ad; } /* Decode and display authentication indicator authdata. */ static void display_auth_indicator(krb5_authdata *ad) { krb5_data **strs = NULL, **p; check(k5_authind_decode(ad, &strs)); assert(strs != NULL); printf("["); for (p = strs; *p != NULL; p++) { printf("%.*s", (int)(*p)->length, (*p)->data); if (*(p + 1) != NULL) printf(", "); } printf("]"); k5_free_data_ptr_list(strs); } /* Display ad as either a hex dump or ASCII text. */ static void display_binary_or_ascii(krb5_authdata *ad) { krb5_boolean binary = FALSE; unsigned char *p; for (p = ad->contents; p < ad->contents + ad->length; p++) { if (!isascii(*p) || !isprint(*p)) binary = TRUE; } if (binary) { for (p = ad->contents; p < ad->contents + ad->length; p++) printf("%02X", *p); } else { printf("%.*s", (int)ad->length, ad->contents); } } /* Display the contents of an authdata element, prefixed by prefix_byte. skey * must be the ticket session key. */ static void display_authdata(krb5_authdata *ad, krb5_keyblock *skey, krb5_keyblock *tktkey, int prefix_byte) { krb5_authdata **inner_ad; if (ad->ad_type == KRB5_AUTHDATA_IF_RELEVANT || ad->ad_type == KRB5_AUTHDATA_MANDATORY_FOR_KDC || ad->ad_type == KRB5_AUTHDATA_KDC_ISSUED || ad->ad_type == KRB5_AUTHDATA_CAMMAC) { /* Decode and display the contents. */ inner_ad = get_container_contents(ad, skey, tktkey); display_authdata_list(inner_ad, skey, tktkey, get_prefix_byte(ad)); krb5_free_authdata(ctx, inner_ad); return; } printf("%c", prefix_byte); printf("%d: ", (int)ad->ad_type); if (ad->ad_type == KRB5_AUTHDATA_AUTH_INDICATOR) display_auth_indicator(ad); else display_binary_or_ascii(ad); printf("\n"); } static void display_authdata_list(krb5_authdata **list, krb5_keyblock *skey, krb5_keyblock *tktkey, char prefix_byte) { if (list == NULL) return; for (; *list != NULL; list++) display_authdata(*list, skey, tktkey, prefix_byte); } int main(int argc, char **argv) { const char *ccname = NULL, *clientname = NULL; krb5_principal client, server; krb5_ccache ccache; krb5_keytab keytab; krb5_creds in_creds, *creds; krb5_ticket *ticket; krb5_authdata **req_authdata = NULL, *ad; krb5_keytab_entry ktent; size_t count; int c; check(krb5_init_context(&ctx)); while ((c = getopt(argc, argv, "+c:p:")) != -1) { switch (c) { case 'c': ccname = optarg; break; case 'p': clientname = optarg; break; default: abort(); } } argv += optind; /* Parse arguments. */ assert(*argv != NULL); check(krb5_parse_name(ctx, *argv++, &server)); count = 0; for (; argv[0] != NULL && argv[1] != NULL; argv += 2) { ad = make_authdata(argv[0], argv[1]); req_authdata = realloc(req_authdata, (count + 2) * sizeof(*req_authdata)); assert(req_authdata != NULL); req_authdata[count++] = ad; req_authdata[count] = NULL; } assert(*argv == NULL); if (ccname != NULL) check(krb5_cc_resolve(ctx, ccname, &ccache)); else check(krb5_cc_default(ctx, &ccache)); if (clientname != NULL) check(krb5_parse_name(ctx, clientname, &client)); else check(krb5_cc_get_principal(ctx, ccache, &client)); memset(&in_creds, 0, sizeof(in_creds)); in_creds.client = client; in_creds.server = server; in_creds.authdata = req_authdata; check(krb5_get_credentials(ctx, KRB5_GC_NO_STORE, ccache, &in_creds, &creds)); check(krb5_decode_ticket(&creds->ticket, &ticket)); check(krb5_kt_default(ctx, &keytab)); check(krb5_kt_get_entry(ctx, keytab, server, ticket->enc_part.kvno, ticket->enc_part.enctype, &ktent)); check(krb5_decrypt_tkt_part(ctx, &ktent.key, ticket)); display_authdata_list(ticket->enc_part2->authorization_data, ticket->enc_part2->session, &ktent.key, ' '); while (count > 0) { free(req_authdata[--count]->contents); free(req_authdata[count]); } free(req_authdata); krb5_free_keytab_entry_contents(ctx, &ktent); krb5_free_creds(ctx, creds); krb5_free_ticket(ctx, ticket); krb5_free_principal(ctx, client); krb5_free_principal(ctx, server); krb5_cc_close(ctx, ccache); krb5_kt_close(ctx, keytab); krb5_free_context(ctx); return 0; } krb5-1.16/src/tests/dejagnu/0000755000704600001450000000000013211554426015544 5ustar ghudsonlibuuidkrb5-1.16/src/tests/dejagnu/pkinit-certs/0000755000704600001450000000000013211554426020160 5ustar ghudsonlibuuidkrb5-1.16/src/tests/dejagnu/pkinit-certs/generic.p120000644000704600001450000000465513211554426022132 0ustar ghudsonlibuuid0 0 o *H  ` \0 X0 *H 00 *H 0 *H  0QA̓0w2Lts*|GBJ/gnJapL$7nAW\ܷ'z2g86%YR6nOOoQc3 P̥m '=}<tKLUiQ,QX sU_iv.P*~ Ekٹ2aT[Tpi'& ?x3+ x:~'xɄ_28V&c=%"k영pW0ȹWxq8H0..T *^n,x*@:pOĵ], 8Rz_I N{W9zTӁ3R3v˫ mUDzi`>wP#5`ۂA๕X&J3 9cnoi՝>X~0B,4>YfFHN ؊hɱwq~t;>jc-T9ɽHbiM\BS,څ㙌?o?Z)Twi~ `3c\^$\̔b5dl㌤q\` a@u7T7"2M`]DT[,7ӗi\xB*#n.sIŁ6[l*$G7 -*1%0# *H  1Ëfxͅ2ehE010!0 +B ^tk"Ó!HWnrܟ%{DANGlkrb5-1.16/src/tests/dejagnu/pkinit-certs/privkey-enc.pem0000644000704600001450000000332713211554426023124 0ustar ghudsonlibuuid-----BEGIN RSA PRIVATE KEY----- Proc-Type: 4,ENCRYPTED DEK-Info: DES-EDE3-CBC,7DF54DB740F92845 3I3F5dJkYmjX49YRQub+AzWPOJock699vQZV3oxcAabcZWtLVbQ75QBXXBPEtm3j LAqb3gRxfETHNHsSIEwGtN3rYre1UdKs3Bu9ROQNTvlbCwRdss3JA1kGhJu2o5bu hf5sjpfR+ivf2prJ4whfhb4+efCHE0Ll669V33D2kbPKX0VCokkRmxsIoVtHd2qu d1HM/EkjxrOy/GHZ+93mkSeWC4hz56VL5ApGOV4wHuphdvKy121mU0mjtQRKF2El N7DtM9/AIAkLPx5wxrTJXuELd+BBDPbRMwmvgqCX1m8sJLJT2fBzVKRKWexowp7T d3j9hT+kMiWCTgd4vJ+i/KPkK460Cy9PzFrzCtWut4jh6rZ+F9Tdp1g4Np0ygWAg q9tV4RC7ylW0DeseRTXTLuohngfu0h7mXuhutr1Xmq+SoRuhBllZyexV4jJMc1kZ 2nv9RJ+h7mCAQbLSVvWCZpngfK2IcZhi4hfNiiQ/wqc6rE3eaBIR9E60kaCeBpWB rxZm4VHOrwJw0GsaCRLQez1F65Ulk4TA+7TYJWnW/MGrvBptuBamwxk28Ts6eOee RVwb/AdY4QBVJKKT+/e3Lfy409evmdTAA2N+tbYzALC1cH4ex4sO0BifaLmKo3t1 fC2FLna4P9F17bbjcS1lSWVJKodofUEt4H03X7LaMhwe+sLRuKBIoTH2nLPHLIYg B8NO1yFiJPFL0a8fi9kG8JJlCPkASQC5vcYg6BE40b7h7T4qw0HmkuH3i6TX6bsG nQlryJ2BfQM+IT3MTEh/T1iHPZcTwFLPF9HMnZ/ydL/nM2kElF6YfMClFvuDGULQ zmsvG4D/ndSisapJQeoevAwtCHybh8/3cy8CoAjBE9C1JlHOvP2+64rzvFVUAKfa z5aZQQJKcdXcKcM8u8PgEyCN5x5tBqWQjSHR904k25KRkePAh8SoiSDuNQPwtzbB RHesvkaSXuUaN7q1+oJzeQvzO8i79ud0Diu5y2KePrlB4HBSWCuWmvz9U+WvGBiw KpEUAp/YpkqB1as4IUBDNjV1Y77cyUZ+/8EkPgAvB9wltCCAyQ5xi1h70cDJdabj swabRD5JV1JLalFMDrOeOPZh1heaTNHXV8f7m8rMVeYVzVTM1JoQLlvKxcc3LVfN 9RLn/vTN7Ox//+385UiozC/PAo/Cep6Z1Wz+cwsd62HH0LVimVt2mrmHRKY983cw U6cZyhvcTB5UOdJdhwbHfnxQipWRu//XRYY/yVdB6W2J4Gzh//adJfKOmHd8+cB+ y8Q1yZP3diTGkhyY9pkXS7Gv2Q9mcXlMJtoyb7rqBIL/osVTKdsZn7Cj6ZYB6ftF +hKQKNs/bKXYs3PF09UOInfUf57pENSr1AQBQceAisAsr8znRYsFlpqZ5L8G6um7 XBneZ1RBj41wheB8g3kL6hj2UrXrE2rxDAw175a3BaxP/Wc2JgGcBWyJTVcZ35Ab f24UNlrfcJdgEFETEiy12WY2VaqJCSY3J6YSimHDbffX+ku8QgU1shZf9z8K1l1A OJQzbjlxPZT/k4cfw/Xi0rHdgWGcmL7tKLkTcrG/AixdEoI9KCSlQGSksI8CfFmj -----END RSA PRIVATE KEY----- krb5-1.16/src/tests/dejagnu/pkinit-certs/kdc.pem0000644000704600001450000000333113211554426021424 0ustar ghudsonlibuuid-----BEGIN CERTIFICATE----- MIIE4TCCA8mgAwIBAgIBAjANBgkqhkiG9w0BAQsFADCBpzELMAkGA1UEBhMCVVMx FjAUBgNVBAgMDU1hc3NhY2h1c2V0dHMxEjAQBgNVBAcMCUNhbWJyaWRnZTEMMAoG A1UECgwDTUlUMSkwJwYDVQQLDCBJbnNlY3VyZSBQS0lOSVQgS2VyYmVyb3MgdGVz dCBDQTEzMDEGA1UEAwwqcGtpbml0IHRlc3Qgc3VpdGUgQ0E7IGRvIG5vdCB1c2Ug b3RoZXJ3aXNlMB4XDTE3MDgyNTE4MzIxMFoXDTI4MDgwNzE4MzIxMFowSTELMAkG A1UEBhMCVVMxFjAUBgNVBAgMDU1hc3NhY2h1c2V0dHMxFDASBgNVBAoMC0tSQlRF U1QuQ09NMQwwCgYDVQQDDANLREMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK AoIBAQC/BxU//lImv03EhSCSXe2e2RbzDmC4RJAsqkYVtYIA6dMayAKIf38sauKi HUvH+wLq39/ZM8kvTbQw9rJysH6C2mabpyFzSwro65a6nYSrGXbZfGmC5oyIUy7u K6zeVmSEUFC25C4rqnOmRTozmcZEdDZAvwsn0EyTuWtk2jK8Hi7MJmNJOSpQKHr6 bIfiz17CwuurKoGLlgw/HNWfRpSPHVtmm0T7fllCrJBIB6mCawpI7zyGYEu1AwM6 VDgl6KQw6/6kPXZwGM7ffK/6Qsettf9keCbbWW3bF0A20Gh4VevYiagAqmQdJS8i jimuGNlOc8t/vreqXd6BpVgq/eg9AgMBAAGjggFzMIIBbzAdBgNVHQ4EFgQUrxLg V1TSrSKJgpC3MabCqfQIPaswgdQGA1UdIwSBzDCByYAUrxLgV1TSrSKJgpC3MabC qfQIPauhga2kgaowgacxCzAJBgNVBAYTAlVTMRYwFAYDVQQIDA1NYXNzYWNodXNl dHRzMRIwEAYDVQQHDAlDYW1icmlkZ2UxDDAKBgNVBAoMA01JVDEpMCcGA1UECwwg SW5zZWN1cmUgUEtJTklUIEtlcmJlcm9zIHRlc3QgQ0ExMzAxBgNVBAMMKnBraW5p dCB0ZXN0IHN1aXRlIENBOyBkbyBub3QgdXNlIG90aGVyd2lzZYIBATALBgNVHQ8E BAMCA+gwDAYDVR0TAQH/BAIwADBIBgNVHREEQTA/oD0GBisGAQUCAqAzMDGgDRsL S1JCVEVTVC5DT02hIDAeoAMCAQGhFzAVGwZrcmJ0Z3QbC0tSQlRFU1QuQ09NMBIG A1UdJQQLMAkGBysGAQUCAwUwDQYJKoZIhvcNAQELBQADggEBAFMX7ZTpNPdzFwkE hrab7fSDeoG+mN0yorY8e5Evx6sE7pXOtHgHIjQY2Ys0lk2mhbsIKptL/R6jTxWR rbmU6jFNFeJgn5ba3NWdhlUiZ8WKe2knp6uc9ZDIK007XaKA4rRoHlJ3vHXoF+ga JFOYwRzCtAlmsOCQ0UetoC3Ju6Y6NhCXIE8f81dsh6RMADoQT0n/fcLY/JtbbLXK ANTIWHm0oSX9wvOU/yZkYGuwcPd91cc6Mea8f3J8D/OiatMZXc3719extmeR6Cv6 aba31kv9wtbxVuxkR7HhjlJhzhqfzfIp3tNREaIxPb/qKGWBOjwxGRqSUkdEqMvD GjaSlyc= -----END CERTIFICATE----- krb5-1.16/src/tests/dejagnu/pkinit-certs/make-certs.sh0000755000704600001450000001347013211554426022557 0ustar ghudsonlibuuid#!/bin/sh -e NAMETYPE=1 KEYSIZE=2048 DAYS=4000 REALM=KRBTEST.COM LOWREALM=krbtest.com KRB5_PRINCIPAL_SAN=1.3.6.1.5.2.2 KRB5_UPN_SAN=1.3.6.1.4.1.311.20.2.3 PKINIT_KDC_EKU=1.3.6.1.5.2.3.5 PKINIT_CLIENT_EKU=1.3.6.1.5.2.3.4 TLS_SERVER_EKU=1.3.6.1.5.5.7.3.1 TLS_CLIENT_EKU=1.3.6.1.5.5.7.3.2 EMAIL_PROTECTION_EKU=1.3.6.1.5.5.7.3.4 # Add TLS EKUs to these if we're testing with NSS and we still have to # piggy-back on the TLS trust settings. KDC_EKU_LIST=$PKINIT_KDC_EKU CLIENT_EKU_LIST=$PKINIT_CLIENT_EKU cat > openssl.cnf << EOF [req] prompt = no distinguished_name = \$ENV::SUBJECT [ca] CN = test CA certificate C = US ST = Massachusetts L = Cambridge O = MIT OU = Insecure PKINIT Kerberos test CA CN = pkinit test suite CA; do not use otherwise [kdc] C = US ST = Massachusetts O = KRBTEST.COM CN = KDC [user] C = US ST = Massachusetts O = KRBTEST.COM CN = user [exts_ca] subjectKeyIdentifier = hash authorityKeyIdentifier = keyid:always,issuer:always keyUsage = nonRepudiation,digitalSignature,keyEncipherment,dataEncipherment,keyAgreement,keyCertSign,cRLSign basicConstraints = critical,CA:TRUE [components_kdc] 0.component=GeneralString:krbtgt 1.component=GeneralString:$REALM [princ_kdc] nametype=EXPLICIT:0,INTEGER:$NAMETYPE components=EXPLICIT:1,SEQUENCE:components_kdc [krb5princ_kdc] realm=EXPLICIT:0,GeneralString:$REALM princ=EXPLICIT:1,SEQUENCE:princ_kdc [exts_kdc] subjectKeyIdentifier = hash authorityKeyIdentifier = keyid:always,issuer:always keyUsage = nonRepudiation,digitalSignature,keyEncipherment,keyAgreement basicConstraints = critical,CA:FALSE subjectAltName = otherName:$KRB5_PRINCIPAL_SAN;SEQUENCE:krb5princ_kdc extendedKeyUsage = $KDC_EKU_LIST [components_client] component=GeneralString:user [princ_client] nametype=EXPLICIT:0,INTEGER:$NAMETYPE components=EXPLICIT:1,SEQUENCE:components_client [krb5princ_client] realm=EXPLICIT:0,GeneralString:$REALM princ=EXPLICIT:1,SEQUENCE:princ_client [exts_client] subjectKeyIdentifier = hash authorityKeyIdentifier = keyid:always,issuer:always keyUsage = nonRepudiation,digitalSignature,keyEncipherment,keyAgreement basicConstraints = critical,CA:FALSE subjectAltName = otherName:$KRB5_PRINCIPAL_SAN;SEQUENCE:krb5princ_client extendedKeyUsage = $CLIENT_EKU_LIST [exts_upn_client] subjectKeyIdentifier = hash authorityKeyIdentifier = keyid:always,issuer:always keyUsage = nonRepudiation,digitalSignature,keyEncipherment,keyAgreement basicConstraints = critical,CA:FALSE subjectAltName = otherName:$KRB5_UPN_SAN;UTF8:user@$LOWREALM extendedKeyUsage = $CLIENT_EKU_LIST [exts_upn2_client] subjectKeyIdentifier = hash authorityKeyIdentifier = keyid:always,issuer:always keyUsage = nonRepudiation,digitalSignature,keyEncipherment,keyAgreement basicConstraints = critical,CA:FALSE subjectAltName = otherName:$KRB5_UPN_SAN;UTF8:user extendedKeyUsage = $CLIENT_EKU_LIST [exts_upn3_client] subjectKeyIdentifier = hash authorityKeyIdentifier = keyid:always,issuer:always keyUsage = nonRepudiation,digitalSignature,keyEncipherment,keyAgreement basicConstraints = critical,CA:FALSE subjectAltName = otherName:$KRB5_UPN_SAN;UTF8:user@$REALM extendedKeyUsage = $CLIENT_EKU_LIST EOF # Generate a private key. openssl genrsa $KEYSIZE -nodes > privkey.pem openssl rsa -in privkey.pem -out privkey-enc.pem -des3 -passout pass:encrypted # Generate a "CA" certificate. SUBJECT=ca openssl req -config openssl.cnf -new -x509 -extensions exts_ca \ -set_serial 1 -days $DAYS -key privkey.pem -out ca.pem # Generate a KDC certificate. SUBJECT=kdc openssl req -config openssl.cnf -new -key privkey.pem -out kdc.csr SUBJECT=kdc openssl x509 -extfile openssl.cnf -extensions exts_kdc \ -set_serial 2 -days $DAYS -req -CA ca.pem -CAkey privkey.pem \ -out kdc.pem -in kdc.csr # Generate a client certificate and PKCS#12 bundles. SUBJECT=user openssl req -config openssl.cnf -new -key privkey.pem \ -out user.csr SUBJECT=user openssl x509 -extfile openssl.cnf -extensions exts_client \ -set_serial 3 -days $DAYS -req -CA ca.pem -CAkey privkey.pem \ -out user.pem -in user.csr openssl pkcs12 -export -in user.pem -inkey privkey.pem -out user.p12 \ -passout pass: openssl pkcs12 -export -in user.pem -inkey privkey.pem -out user-enc.p12 \ -passout pass:encrypted # Generate a client certificate and PKCS#12 bundles with a UPN SAN. SUBJECT=user openssl req -config openssl.cnf -new -key privkey.pem \ -out user-upn.csr SUBJECT=user openssl x509 -extfile openssl.cnf -extensions exts_upn_client \ -set_serial 4 -days $DAYS -req -CA ca.pem -CAkey privkey.pem \ -out user-upn.pem -in user-upn.csr openssl pkcs12 -export -in user-upn.pem -inkey privkey.pem -out user-upn.p12 \ -passout pass: SUBJECT=user openssl req -config openssl.cnf -new -key privkey.pem \ -out user-upn2.csr SUBJECT=user openssl x509 -extfile openssl.cnf -extensions exts_upn2_client \ -set_serial 5 -days $DAYS -req -CA ca.pem -CAkey privkey.pem \ -out user-upn2.pem -in user-upn2.csr openssl pkcs12 -export -in user-upn2.pem -inkey privkey.pem \ -out user-upn2.p12 -passout pass: SUBJECT=user openssl req -config openssl.cnf -new -key privkey.pem \ -out user-upn3.csr SUBJECT=user openssl x509 -extfile openssl.cnf -extensions exts_upn3_client \ -set_serial 6 -days $DAYS -req -CA ca.pem -CAkey privkey.pem \ -out user-upn3.pem -in user-upn3.csr openssl pkcs12 -export -in user-upn3.pem -inkey privkey.pem \ -out user-upn3.p12 -passout pass: # Generate a client certificate and PKCS#12 bundle with no PKINIT extensions. SUBJECT=user openssl req -config openssl.cnf -new -key privkey.pem \ -out generic.csr SUBJECT=user openssl x509 -set_serial 7 -days $DAYS -req -CA ca.pem \ -CAkey privkey.pem -out generic.pem -in generic.csr openssl pkcs12 -export -in generic.pem -inkey privkey.pem -out generic.p12 \ -passout pass: # Clean up. rm -f openssl.cnf kdc.csr user.csr user-upn.csr user-upn2.csr user-upn3.csr rm -f generic.csr krb5-1.16/src/tests/dejagnu/pkinit-certs/user-upn.pem0000644000704600001450000000326413211554426022446 0ustar ghudsonlibuuid-----BEGIN CERTIFICATE----- MIIExTCCA62gAwIBAgIBBDANBgkqhkiG9w0BAQsFADCBpzELMAkGA1UEBhMCVVMx FjAUBgNVBAgMDU1hc3NhY2h1c2V0dHMxEjAQBgNVBAcMCUNhbWJyaWRnZTEMMAoG A1UECgwDTUlUMSkwJwYDVQQLDCBJbnNlY3VyZSBQS0lOSVQgS2VyYmVyb3MgdGVz dCBDQTEzMDEGA1UEAwwqcGtpbml0IHRlc3Qgc3VpdGUgQ0E7IGRvIG5vdCB1c2Ug b3RoZXJ3aXNlMB4XDTE3MDgyNTE4MzIxMVoXDTI4MDgwNzE4MzIxMVowSjELMAkG A1UEBhMCVVMxFjAUBgNVBAgMDU1hc3NhY2h1c2V0dHMxFDASBgNVBAoMC0tSQlRF U1QuQ09NMQ0wCwYDVQQDDAR1c2VyMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB CgKCAQEAvwcVP/5SJr9NxIUgkl3tntkW8w5guESQLKpGFbWCAOnTGsgCiH9/LGri oh1Lx/sC6t/f2TPJL020MPaycrB+gtpmm6chc0sK6OuWup2Eqxl22XxpguaMiFMu 7ius3lZkhFBQtuQuK6pzpkU6M5nGRHQ2QL8LJ9BMk7lrZNoyvB4uzCZjSTkqUCh6 +myH4s9ewsLrqyqBi5YMPxzVn0aUjx1bZptE+35ZQqyQSAepgmsKSO88hmBLtQMD OlQ4JeikMOv+pD12cBjO33yv+kLHrbX/ZHgm21lt2xdANtBoeFXr2ImoAKpkHSUv Io4prhjZTnPLf763ql3egaVYKv3oPQIDAQABo4IBVjCCAVIwHQYDVR0OBBYEFK8S 4FdU0q0iiYKQtzGmwqn0CD2rMIHUBgNVHSMEgcwwgcmAFK8S4FdU0q0iiYKQtzGm wqn0CD2roYGtpIGqMIGnMQswCQYDVQQGEwJVUzEWMBQGA1UECAwNTWFzc2FjaHVz ZXR0czESMBAGA1UEBwwJQ2FtYnJpZGdlMQwwCgYDVQQKDANNSVQxKTAnBgNVBAsM IEluc2VjdXJlIFBLSU5JVCBLZXJiZXJvcyB0ZXN0IENBMTMwMQYDVQQDDCpwa2lu aXQgdGVzdCBzdWl0ZSBDQTsgZG8gbm90IHVzZSBvdGhlcndpc2WCAQEwCwYDVR0P BAQDAgPoMAwGA1UdEwEB/wQCMAAwKwYDVR0RBCQwIqAgBgorBgEEAYI3FAIDoBIM EHVzZXJAa3JidGVzdC5jb20wEgYDVR0lBAswCQYHKwYBBQIDBDANBgkqhkiG9w0B AQsFAAOCAQEAceeR7lFXkEEjcMGK/mvNOT5zXcq27ipYuV5HBgGGNLqiawc7NTxF ocyZf9HujNOMvBNblTml2GJQ9wmyQesVTGgJFTGORS2sFizICq19jISxrv44cdeF X/KQxNmnviClkL9jfA/6oKU0uSpvUAUet3MmDuo8O7ebVXVEmQdvLrhP9ycHGq8u qG+5qjN4dpf/ejtCCMGGZdUdPxPosoXJzf17hpyt8/YQohKG2igLSy1O68tuHTXb L4yiB52JQdnJfOU1a+vUSk425zMI00MU1aLcDxcjI64kxYBpWflDqn9Ky0N6vA1i OoBZgRFeQSELxUp7SUsK4xO2gPM2w0zzvQ== -----END CERTIFICATE----- krb5-1.16/src/tests/dejagnu/pkinit-certs/user-upn3.pem0000644000704600001450000000326413211554426022531 0ustar ghudsonlibuuid-----BEGIN CERTIFICATE----- MIIExTCCA62gAwIBAgIBBjANBgkqhkiG9w0BAQsFADCBpzELMAkGA1UEBhMCVVMx FjAUBgNVBAgMDU1hc3NhY2h1c2V0dHMxEjAQBgNVBAcMCUNhbWJyaWRnZTEMMAoG A1UECgwDTUlUMSkwJwYDVQQLDCBJbnNlY3VyZSBQS0lOSVQgS2VyYmVyb3MgdGVz dCBDQTEzMDEGA1UEAwwqcGtpbml0IHRlc3Qgc3VpdGUgQ0E7IGRvIG5vdCB1c2Ug b3RoZXJ3aXNlMB4XDTE3MDgyNTE4MzIxMVoXDTI4MDgwNzE4MzIxMVowSjELMAkG A1UEBhMCVVMxFjAUBgNVBAgMDU1hc3NhY2h1c2V0dHMxFDASBgNVBAoMC0tSQlRF U1QuQ09NMQ0wCwYDVQQDDAR1c2VyMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB CgKCAQEAvwcVP/5SJr9NxIUgkl3tntkW8w5guESQLKpGFbWCAOnTGsgCiH9/LGri oh1Lx/sC6t/f2TPJL020MPaycrB+gtpmm6chc0sK6OuWup2Eqxl22XxpguaMiFMu 7ius3lZkhFBQtuQuK6pzpkU6M5nGRHQ2QL8LJ9BMk7lrZNoyvB4uzCZjSTkqUCh6 +myH4s9ewsLrqyqBi5YMPxzVn0aUjx1bZptE+35ZQqyQSAepgmsKSO88hmBLtQMD OlQ4JeikMOv+pD12cBjO33yv+kLHrbX/ZHgm21lt2xdANtBoeFXr2ImoAKpkHSUv Io4prhjZTnPLf763ql3egaVYKv3oPQIDAQABo4IBVjCCAVIwHQYDVR0OBBYEFK8S 4FdU0q0iiYKQtzGmwqn0CD2rMIHUBgNVHSMEgcwwgcmAFK8S4FdU0q0iiYKQtzGm wqn0CD2roYGtpIGqMIGnMQswCQYDVQQGEwJVUzEWMBQGA1UECAwNTWFzc2FjaHVz ZXR0czESMBAGA1UEBwwJQ2FtYnJpZGdlMQwwCgYDVQQKDANNSVQxKTAnBgNVBAsM IEluc2VjdXJlIFBLSU5JVCBLZXJiZXJvcyB0ZXN0IENBMTMwMQYDVQQDDCpwa2lu aXQgdGVzdCBzdWl0ZSBDQTsgZG8gbm90IHVzZSBvdGhlcndpc2WCAQEwCwYDVR0P BAQDAgPoMAwGA1UdEwEB/wQCMAAwKwYDVR0RBCQwIqAgBgorBgEEAYI3FAIDoBIM EHVzZXJAS1JCVEVTVC5DT00wEgYDVR0lBAswCQYHKwYBBQIDBDANBgkqhkiG9w0B AQsFAAOCAQEAurL26+vQNYFbJNAFJ3yHOt1nwAVO4/OlCtgqzOAq0nBs35HY10Qe y8eRcxrLmm4O/Wy+Rwre2v3pIP0AclvIytDzEm6K3Pgj4yJfUUM3VhnSOlXQP6UG D9Z9pVxNiDeykj5/SzxwOQAmJbPcMx9aRwP9wOLMwUxi5sKHQlL9YUTC1hffhuYY Yccc2dHWd5IyaKaLp9yBVXQryNdVTBYrGA2ZqcwETmcXqU/wCo/Rmf10Ra1sj88X VfTb4Sr0j9RaSKeXRZgbEu6kz9i2WK70dcDke08xRv4xVfrlbXrfIS+Va9WYKxrf Xb0XCkKp32Q0EHqapeJrCcuQtnDMGvncTQ== -----END CERTIFICATE----- krb5-1.16/src/tests/dejagnu/pkinit-certs/ca.pem0000644000704600001450000000333513211554426021252 0ustar ghudsonlibuuid-----BEGIN CERTIFICATE----- MIIE5TCCA82gAwIBAgIBATANBgkqhkiG9w0BAQsFADCBpzELMAkGA1UEBhMCVVMx FjAUBgNVBAgMDU1hc3NhY2h1c2V0dHMxEjAQBgNVBAcMCUNhbWJyaWRnZTEMMAoG A1UECgwDTUlUMSkwJwYDVQQLDCBJbnNlY3VyZSBQS0lOSVQgS2VyYmVyb3MgdGVz dCBDQTEzMDEGA1UEAwwqcGtpbml0IHRlc3Qgc3VpdGUgQ0E7IGRvIG5vdCB1c2Ug b3RoZXJ3aXNlMB4XDTE3MDgyNTE4MzIxMFoXDTI4MDgwNzE4MzIxMFowgacxCzAJ BgNVBAYTAlVTMRYwFAYDVQQIDA1NYXNzYWNodXNldHRzMRIwEAYDVQQHDAlDYW1i cmlkZ2UxDDAKBgNVBAoMA01JVDEpMCcGA1UECwwgSW5zZWN1cmUgUEtJTklUIEtl cmJlcm9zIHRlc3QgQ0ExMzAxBgNVBAMMKnBraW5pdCB0ZXN0IHN1aXRlIENBOyBk byBub3QgdXNlIG90aGVyd2lzZTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC ggEBAL8HFT/+Uia/TcSFIJJd7Z7ZFvMOYLhEkCyqRhW1ggDp0xrIAoh/fyxq4qId S8f7Aurf39kzyS9NtDD2snKwfoLaZpunIXNLCujrlrqdhKsZdtl8aYLmjIhTLu4r rN5WZIRQULbkLiuqc6ZFOjOZxkR0NkC/CyfQTJO5a2TaMrweLswmY0k5KlAoevps h+LPXsLC66sqgYuWDD8c1Z9GlI8dW2abRPt+WUKskEgHqYJrCkjvPIZgS7UDAzpU OCXopDDr/qQ9dnAYzt98r/pCx621/2R4JttZbdsXQDbQaHhV69iJqACqZB0lLyKO Ka4Y2U5zy3++t6pd3oGlWCr96D0CAwEAAaOCARgwggEUMB0GA1UdDgQWBBSvEuBX VNKtIomCkLcxpsKp9Ag9qzCB1AYDVR0jBIHMMIHJgBSvEuBXVNKtIomCkLcxpsKp 9Ag9q6GBraSBqjCBpzELMAkGA1UEBhMCVVMxFjAUBgNVBAgMDU1hc3NhY2h1c2V0 dHMxEjAQBgNVBAcMCUNhbWJyaWRnZTEMMAoGA1UECgwDTUlUMSkwJwYDVQQLDCBJ bnNlY3VyZSBQS0lOSVQgS2VyYmVyb3MgdGVzdCBDQTEzMDEGA1UEAwwqcGtpbml0 IHRlc3Qgc3VpdGUgQ0E7IGRvIG5vdCB1c2Ugb3RoZXJ3aXNlggEBMAsGA1UdDwQE AwIB/jAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQArUoCjqxsY /m3nx/5BQSkBAL4T5RgWIX+L4y4GXloYYlafpw+SxRq0QffFm5fpCJBnMd21MbPl k/YA+oq0/76cKyQmJ6h/Wl4KHCKKMmvGuhCEXzmrevk/EJ8lJXNdPfbBueAuLeyU 7X9tO8i9fJ59AZ9YWD9d//puOF+8xeHPxJIxHcR2jHpUOJPtm4yVu1LreHiJJTu4 Xotp9yMpJu/uJM3aBKVS5N/5JreraLj9N6N8nZ/7nEw9Dj1zzGHcHCcqtcxz1oOH Zbg5Jo8HhVhIHxKdKLvwEk60P+lkGFIE+IUmhWfcbbprTGs7VhxREwxaWyCapCOk qlhbJdEcjHr2 -----END CERTIFICATE----- krb5-1.16/src/tests/dejagnu/pkinit-certs/generic.pem0000644000704600001450000000233113211554426022276 0ustar ghudsonlibuuid-----BEGIN CERTIFICATE----- MIIDZjCCAk4CAQcwDQYJKoZIhvcNAQELBQAwgacxCzAJBgNVBAYTAlVTMRYwFAYD VQQIDA1NYXNzYWNodXNldHRzMRIwEAYDVQQHDAlDYW1icmlkZ2UxDDAKBgNVBAoM A01JVDEpMCcGA1UECwwgSW5zZWN1cmUgUEtJTklUIEtlcmJlcm9zIHRlc3QgQ0Ex MzAxBgNVBAMMKnBraW5pdCB0ZXN0IHN1aXRlIENBOyBkbyBub3QgdXNlIG90aGVy d2lzZTAeFw0xNzA4MjUxODMyMTFaFw0yODA4MDcxODMyMTFaMEoxCzAJBgNVBAYT AlVTMRYwFAYDVQQIDA1NYXNzYWNodXNldHRzMRQwEgYDVQQKDAtLUkJURVNULkNP TTENMAsGA1UEAwwEdXNlcjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB AL8HFT/+Uia/TcSFIJJd7Z7ZFvMOYLhEkCyqRhW1ggDp0xrIAoh/fyxq4qIdS8f7 Aurf39kzyS9NtDD2snKwfoLaZpunIXNLCujrlrqdhKsZdtl8aYLmjIhTLu4rrN5W ZIRQULbkLiuqc6ZFOjOZxkR0NkC/CyfQTJO5a2TaMrweLswmY0k5KlAoevpsh+LP XsLC66sqgYuWDD8c1Z9GlI8dW2abRPt+WUKskEgHqYJrCkjvPIZgS7UDAzpUOCXo pDDr/qQ9dnAYzt98r/pCx621/2R4JttZbdsXQDbQaHhV69iJqACqZB0lLyKOKa4Y 2U5zy3++t6pd3oGlWCr96D0CAwEAATANBgkqhkiG9w0BAQsFAAOCAQEAAniIG+xJ 6rXbrH2kt40GE58fFzrIlzhG4VzncNnpFitvPEMzN0kMa5LBX5/zSYiMawQBQ7C0 FpCjz+n82VVW8iabCNoqUUNwOP7ZYmsoraHT9klSak/mLfAXOyOG3DUV9jntivnl HUIiDO7Pf6GnVVROio9psQEVOX1+W1uq9Vs79+F5GI/s0QR9dG0qXvdJ0h5UdVee 8LVXQOi3cQKyBOwECwt0HA0pJwwcD6w9e8Y2NYTeOTamWGQVEV3NlcvtdSVuDJ8y lTke2YbEKyHdcsQ1vrDHtdyfEmJcgO5c9EL5ptYJB7Yv1QiwWJOhLdT13IBYvOtO ebOF6zAD73Bpkw== -----END CERTIFICATE----- krb5-1.16/src/tests/dejagnu/pkinit-certs/user-upn2.p120000644000704600001450000000537513211554426022356 0ustar ghudsonlibuuid0 0  *H   0 0_ *H P0L0E *H 0 *H  0 TJ~-Y ]66<=M-~iVel|,r %\1]#Er;U ?Hb H+HR=ÉWk1=Zjx1cgJMDf~k'vWo135]UqsXA(yu#dٲ\!\o1t]$(I6ۃ?Q &́l"Yօ29mqƺwVk5/N9@xۧHT )~nSB'NFIS."v[u|@Drv"ٱj<߬зdn Ao*fDA~\-8Jp!>G" *\8ϸ'O*A2欒.Iax kΕc;q/] RU 9k~Y2'‰V4ɰNOnEJJ npѻWHduj 35K($0oqw쩁I!i "'rj{POٕŵCZQlOcNlPƺtl;L` 0?H΂}NCH4ׂru+cR7c}7V5vL 7f5JqK[V_)j$p;ppވcXDƨv 3ξ~t4@oVKB (:%ۻ{V: q^:wiEaUxL80 j ުµ4ge׌a%5:?$ %6KjKγF"llPSϏ(8Z1"ݿbupPM Rx`Q{=TnȂc6u!L7YqJ~aɉ>Y\_ 9\yď-BJ_i=SdDw/Ucfh fU`UWVi+#%>U%V]Xž&kk5\7ʥH,q~ղ^ (,3 7ے$Wlt]0uwG/QS/H" w F]ȏxbنݪZAx&^i21ڪK+~=>41~׹޼a^[m790A *H 2.0*0& *H  00 *H  0jv(KFfVڪ E?[)wB#H5xM jS o| $Kܙ"{nݏ`5IylF1R{ S*?V_u F1|^ M_RoNS>j娡f5 6Q|>ǶS} _^n&بaH$>췜D \ݾNp%Ҹ9v I ئu^iIދ$jv>xm |Ag7n`F< DWJ!0Vue'S.S=_7y E=*%>yفN!G*nVo~-.fd\HiC_azb2eܥcD9[➫aZ  Q]+u&&kꅔ|KTW~>oK~ܗxO#C86ˑsаM|!1h/ PȶB$#RIsO?{y?Ÿ} yp*%wo<HnuF Ґ@~ҹA5Oіbt6$qاEM  rg^ou&WgW K!П0a"^<$.aF޺ /H C->?S\Kn$8vճEH-b(ؤ}kIPM1pFp~ $(f&rbbh.$Z ZsN~=mav)({2T _ ъ8'2YB%D(]DZOKYް{ GھSz}Z꣘3eηVT$I4-dZ^;a-hbyUK&e0hk%3uB7ZDf5F SМ*G7Gpb~t*T;l1Z^{ӽA"J-VݺPWVR_/|69 k-ߋH^#b%.3c"9/&ӨDQNv6П5LP`_`pܥN44'kXNRa&3}ZmsI.6BP~*rZy%9L֕r/ikG}Ζzzpzpu>^M>1%0# *H  1K",qy"ˍ5,&010!0 +i";DŽgr*e'qGyuAkrb5-1.16/src/tests/dejagnu/pkinit-certs/user.pem0000644000704600001450000000330413211554426021641 0ustar ghudsonlibuuid-----BEGIN CERTIFICATE----- MIIE0zCCA7ugAwIBAgIBAzANBgkqhkiG9w0BAQsFADCBpzELMAkGA1UEBhMCVVMx FjAUBgNVBAgMDU1hc3NhY2h1c2V0dHMxEjAQBgNVBAcMCUNhbWJyaWRnZTEMMAoG A1UECgwDTUlUMSkwJwYDVQQLDCBJbnNlY3VyZSBQS0lOSVQgS2VyYmVyb3MgdGVz dCBDQTEzMDEGA1UEAwwqcGtpbml0IHRlc3Qgc3VpdGUgQ0E7IGRvIG5vdCB1c2Ug b3RoZXJ3aXNlMB4XDTE3MDgyNTE4MzIxMVoXDTI4MDgwNzE4MzIxMVowSjELMAkG A1UEBhMCVVMxFjAUBgNVBAgMDU1hc3NhY2h1c2V0dHMxFDASBgNVBAoMC0tSQlRF U1QuQ09NMQ0wCwYDVQQDDAR1c2VyMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB CgKCAQEAvwcVP/5SJr9NxIUgkl3tntkW8w5guESQLKpGFbWCAOnTGsgCiH9/LGri oh1Lx/sC6t/f2TPJL020MPaycrB+gtpmm6chc0sK6OuWup2Eqxl22XxpguaMiFMu 7ius3lZkhFBQtuQuK6pzpkU6M5nGRHQ2QL8LJ9BMk7lrZNoyvB4uzCZjSTkqUCh6 +myH4s9ewsLrqyqBi5YMPxzVn0aUjx1bZptE+35ZQqyQSAepgmsKSO88hmBLtQMD OlQ4JeikMOv+pD12cBjO33yv+kLHrbX/ZHgm21lt2xdANtBoeFXr2ImoAKpkHSUv Io4prhjZTnPLf763ql3egaVYKv3oPQIDAQABo4IBZDCCAWAwHQYDVR0OBBYEFK8S 4FdU0q0iiYKQtzGmwqn0CD2rMIHUBgNVHSMEgcwwgcmAFK8S4FdU0q0iiYKQtzGm wqn0CD2roYGtpIGqMIGnMQswCQYDVQQGEwJVUzEWMBQGA1UECAwNTWFzc2FjaHVz ZXR0czESMBAGA1UEBwwJQ2FtYnJpZGdlMQwwCgYDVQQKDANNSVQxKTAnBgNVBAsM IEluc2VjdXJlIFBLSU5JVCBLZXJiZXJvcyB0ZXN0IENBMTMwMQYDVQQDDCpwa2lu aXQgdGVzdCBzdWl0ZSBDQTsgZG8gbm90IHVzZSBvdGhlcndpc2WCAQEwCwYDVR0P BAQDAgPoMAwGA1UdEwEB/wQCMAAwOQYDVR0RBDIwMKAuBgYrBgEFAgKgJDAioA0b C0tSQlRFU1QuQ09NoREwD6ADAgEBoQgwBhsEdXNlcjASBgNVHSUECzAJBgcrBgEF AgMEMA0GCSqGSIb3DQEBCwUAA4IBAQClwfj6ACfmDie1YoKzr3zSWZJKZimv7wG1 iZMNPE6bw22ZmE+P+Vq6WrY5M5e4u7ZdvFmkVq3rUA0HoU6bk3YLGapgsEAG6W1R LVzxwoYDf4poOMqjCL34eLFdlVeRDADiulROE8bJGrPLJIiqeii0c7Kzxxuh5nxl QHDgNV0fHQQJlejgJssOqgGErsCXCq7k6kkqB8MnKVMErRjsYuY3YI2tpjxBq9nA A9dXgIU1zEUVzfpxzBjL9+2pMctbL1y4/ePpTP1+PlfI81TwrQNvMGYjxKNZM1ab lZt37n8GQUZQyZ2TacR4JyY+w20ivE/JPN0L3Ncmem6bO1CULpwO -----END CERTIFICATE----- krb5-1.16/src/tests/dejagnu/pkinit-certs/user-enc.p120000644000704600001450000000542513211554426022233 0ustar ghudsonlibuuid0 0  *H   0 0w *H h0d0] *H 0 *H  0N"00Ş_w+z:3>@qeb@$+N<]ebXgafzrLo<|킋"M2 +kdEȶXӳu?)"IS 3{,u=4҇%3mP$W.;EJf* q@#Ƽa50A *H 2.0*0& *H  00 *H  0Kd~ȻN[-/d9V 7?lrM;&Ѓ8|ўV^S 5ʰ A"RhlG*N9UlF _Y:`h} r$F0{Nz䓿Q8gN-F  HfTyRN[y.ۮ,:1ަCxK\.ihn(6ǡ]b<$̋ߊi{%Όo q;ߓ?$YMAĪ韺3=XV~3fQ,=_L0f+3e㕁׼qzM`l+!YgY4*.ۃTZywae 6H%0P)tF;s~ڷ^t(v`"poJ^n逜A aΊ*aݬcd1{[_`FD:l&XI!a# smDj=u3C;^.R6u|,\=4 `8g Pa4b_lf3`g^D2Fx$!R 4K |ZaW 9kObdiaI[[;Ui;ɤآ~j} k. 4w&vknd1q;fFu~lŀyP3傎K,2i<6\5FY󬡆$aDrC!E( zOpm`1ƨ(_>m%\ [>|gc tߐ|13]hO= plz p̢+ӺWrU6H4p,@Sq/li: Ϣ>lD"{:c UE_y[9Ct3{وcSD>aʚ˜o3MSӇ6̥-#]_:G2Ej3Q{aF10r*/w A34GǤʂRF=,Xfe蘋w7l1_~ot5bێmFS=H0sΤ?]cPhw$+lh̾x$]9"~4-UzʕyJ kյmN?\M@?XPeH4]%E݉I:Qo͂b( 3OMߩx n*.9)̣֦h!Sy2|23LYx~9|o]Bƣ\Wu$$55;A ߕI}CoIi?[){>^8HC+& sq6uRI^7Ϯ8;- xKGwڦ/v{ʘ4+ju0eO#1/54jP 6ә0E8倔&4}WtNGr ll ۲'?)E`zRW#CxtnSk: } z%%F06g"XLL@y fNbe{AF9G^K1ub@HoiVPde<ݘm_҆{_X8rHfib <ķ̦F^o'Lj9X2;sc? ~v5(Y7љ )U'Nn%^dڷ\'&zfM-ϱwi j= +~a9ZxX9MpNݢ0A *H 2.0*0& *H  00 *H  0 & -Ꙃ*kle\ Q#-ƠRv޹|R\] N ̪DzHVv:C#?(1|ݿB/A u=K!R_Rj|GV|v g> ť~- slL{T4lϮM]fG,vl>3yЌ2QoՔEX XѵׯJXU(9}0[mmy+pKʭf8]I,+Ϊ55Q9t"-I=ZU}mam@йJOZo^}IՁ9R涙OpMMO=?h|N-₄O$ˆ҃Bip8&*W=囻{=+-{KQ6g,+t9R1ToNB`,KLr"npr *TڧO@XdWt#%~U3!:[þf䤵(gTY%W#tbRq=CҨTy6gN\/ O]Ģ+-rޣ=7gaBeJv]?keڰX+,WO;!<-Jf΃OcMn0 (pтjmuVY7)pUPlZ&Vmz;]TAh8G/Tb" Đ9 UȤ0ּ|Wٲt"d=j"x1@vH6Yz74$Z}d_nv9)gYu kCN%o≷9Egh䀅,dp$Ҭ .߱l{-]O=Sϖ'}ԋq3nEā1ovF|9hBW+28zuV5y^us 9h'ۑdb*9qf>y,ܰ/ZҢwSiV/6bYFSj1jj/q@U1%0# *H  1jaӉ{010!0 +,6=.%$ @WOv\krb5-1.16/src/tests/dejagnu/pkinit-certs/privkey.pem0000644000704600001450000000321713211554426022357 0ustar ghudsonlibuuid-----BEGIN RSA PRIVATE KEY----- MIIEpAIBAAKCAQEAvwcVP/5SJr9NxIUgkl3tntkW8w5guESQLKpGFbWCAOnTGsgC iH9/LGrioh1Lx/sC6t/f2TPJL020MPaycrB+gtpmm6chc0sK6OuWup2Eqxl22Xxp guaMiFMu7ius3lZkhFBQtuQuK6pzpkU6M5nGRHQ2QL8LJ9BMk7lrZNoyvB4uzCZj STkqUCh6+myH4s9ewsLrqyqBi5YMPxzVn0aUjx1bZptE+35ZQqyQSAepgmsKSO88 hmBLtQMDOlQ4JeikMOv+pD12cBjO33yv+kLHrbX/ZHgm21lt2xdANtBoeFXr2Imo AKpkHSUvIo4prhjZTnPLf763ql3egaVYKv3oPQIDAQABAoIBAEe7ACa8d9qm4SvX FYkAjjakq/JuxrDKxhyPf6utMXjoVGXtDs50matzI1DekVMxlUHe+O5VfMkvc2cj a5SXY5n9KqRuGKhzWFBoDnxao7Of5zn5dqE5szGJksjKS6pdZHcutXBHtHKfGbgo rJctuf6AaNLdKfI0TFz4NjRznrN2NyFQGhXzPpq34Qm3Rg91hVlU3A8FYjE7ez6b vlJBsbKqnvzxEQMWTk0z0bWC79zE1ElH3Hpwfwb2cG7H4EXf0j6N5k2zODg7C45I xWtlES+OpZqdDH6mKFBQojU375j6rb2plZGkTA+qxX9GvG7GsF5aOM6Wkge7SUeT NUY2lB0CgYEA83u0TtxCMye1p+ykZwQdcEKR+l4aSjNsM2V2s8Zy4eZseR7f5fgZ 71ggIpzK9pjT55OiYJOwsEkZAPB0gBgiEcqJgow52w3Hg8sUU5LBEahUpx3Qm64W 64WNIOL9oVXYQu1S/yJ3iWPMQcH1xIlDtPPC1LH+yHyEOnGe4szIeccCgYEAyNkN K2JEbbfK7Wsh3/MOtx5KCkzJzFClTSQZ55IxRUf+myauljKt+kI99jYV6eoicAJv SMHQeYurLtSkhuyptAHUqo5xgH0HZ7cE7LV1nfam2p588Yg21nIId9XLDPK4AvCx Phz1oznaiGMu4jB7esozuW4FKxB1kRmUikM8bdsCgYEA23jMRLFhsr6+jclPP9SD vKck8mtUg0Hq7EEvSEk/UMTlTiA4bhC/P/FNtiVjBfkoOXvoR+mYwK6DLUeRm80l GKhaXySLGhtHllK91b9Y7NOwypqjaVD5M/9EATraqEy7DUjjITsuSNd+TF/LawbX 0wpOum5fXNRwVEYKlCFHLA0CgYApr3LeSDzvkK/batrTAj1RoEW5sYpIj4xfYFjI CT2UpYagaPzfS5F0WX9GtJ8Dt4aCPN8f+KnuMCDNTXEAV+o45BBhfcLs6gY5bnDl OBw7NtAWm8JO1viatXwwcvz7qPysD4yZ2aTZxc4ndH5sj6dxKrpliAIml/nuraJ4 t8+49QKBgQCxJ7ZDlM9J0quVivSui5aoZ7iLEiu6GSZ5yF1HSNXY69OnqQK3UxMl aERCn/cKqtquJQK3v1IE6k6uAaoM7PXDVKqKSH0Z1Jpqciqjg+J/i7Vym6oCdjer 6zt6P7Q13f9X9uUlZBnNrT9jk5WjR9pSpxAc0vU78VKa0lZMZ3bROg== -----END RSA PRIVATE KEY----- krb5-1.16/src/tests/dejagnu/pkinit-certs/user-upn3.p120000644000704600001450000000541513211554426022352 0ustar ghudsonlibuuid0 0  *H   0 0o *H `0\0U *H 0 *H  0;ݱ9}1(O"ٷϖv Qx)h~53ڋ %E 7V~綠@ o帚w&Kʬ?ܶ7UlWbs̴G$ 1a C1!?7TM3ؤۿ{6}~Q$z$xCۤFIf <B7A?*F;Ij@&p(amr9M@^)@}$@h^a w!$1M@`DZ~5;$-!ΔuJ6)i;%%0 _-zWPSE BP'T(~wò')| x&\\}WڕzK b%&"!L8b4훳qjtAff@L-% z↢=;0d"r3p[_h0{ :#| & *.ZԫeDrJSwCQN{i֣-a%y+"%P_,:%"DX[Y/#)NM[qF uɗ6X&BN'b$#"~{*紘іP@S;}Q𨘧nV&ۡI@97ta{˝2(5^/wngc|=/ `S} SYIL*fK) IWYWs pBL:Xn\=#)O@"S E($W F .:Eə7)&y框6frJc>6=\׎ 8Z1׿GM6ax1عC9uhTZk]!&-Rq8M)(nGS1+C/Re_TFki6\o[XWH4Fz۔D2YR y. o>PÞY0A *H 2.0*0& *H  00 *H  0϶hU&b}iZ.pP;="*lIwHucQb LkàDoiӐŖ!ok=]&,%~mηInDN{,YI)UDgv~I}DW6]t^#B@Pg5Sh gm kѧr4ȏ% \+7$dٻ^¯_D  k}]I>``7@=Q THB( ~ØdpdݢYp%,E1;z#̠u-ZTScq 𵊅^.U^"A G^<- xaj-ף9H/lU+bL9~38x-^ugeRiZr<&w)''x+͝\HyZ ~|<meШpT*z!ԡ_tRetzE٬|jMMjө*qxhmY&c$v, ֡:➃edی0 ^|(+\.qz?]XARG88k*ϓq^K@#6t/(3v}~ӟ}^0#l*n +jF$*Oϟ}9 f@Q9@c2n` H5C e=BA)sNDcu`%cSWP@oA_]/kN#L3<Ʀh [$'3Lﰭ4{+0(pP̭qhg^jv\b B[]F1?"1O-0H`H*v:|,LC/`L@4PE&#B5pdLj:yN=N{@D&01ǽMP. SJĭLH΀jGMExb:yԍL/Fod[0^\ktЏ&HD,i^f(Yz`#l \U97哜ݓ3qqNjص!`iF1Ca?Dʷk5CH%xWꛖҝqnedV$\n8FT)I}FAʹXQ^ڠ[.4s\#7D^W刑Uy~wW[ߧ#kx &:cZ}I@ las?WOOݴ-,MG O ٣m-rK& D|so0ɒ*H(Z5}wF,v2O[4AUq_Hh \aˠnNXL[_%\/I_.Δ|"TB8oQ׫!E{xzBGi/FNcc=*uَ!*2¶I{9 k#vYmv'п~#`:GT8L'0(rH xޥ'hi.^GL-yg<ߎsl܋إϰo#N[\xQ1wP\,\Z;ч>45ב#:> 3lF *5Ɩi Q7Đ#\4_CBF~ӲI,?oMR+˷4r}.]ȹ@g2!RT$M,fJR!b炶f|bB!Ҋ\d+nwwh:UowRZlr0A *H 2.0*0& *H  00 *H  072>ȤC\'~M 'f9{{N7q܊/6pqܩyQ\L46\ C2‚OtYq .c`P~ꗄ2cJ,RGWIRl?H1o6#}`("ƽ6 9CVj-pB\N w>Jh ?B\QFDz"%.~ O5{vTr჉se!8B##ՍIlgEG I#j63M'c͖Ұ5;-C2Jh=O0 'ۯfkSz38ĬeS1ߤ| IhՑ-'EB3"d(u^]=Z7-rQ_ՔN.[L*:ANE-۫@˼L|ӆ}SxIK˞2ޭxڼP*|%碲XHkW>MrZNgUa#ƶ{SQ9:|f$ln*py$PaC lڶTPD |uWj>oe!rܙʥmZl_ jЭ;$ețg풰.wU` &"*EŹ5c&r.bp˪ P9@ >Ƃ*>B:<()_W]Cb8#U@9bdKBڒ: ?hQ-!* bT @E?7FjGm 8Z @Bת) oݛ )69P4B`m˘.W'OЍǞ#Eu` L}k[ )yi?xax >*5YTD` F2S:$פB c1-ƜS3όQdorVn`>L,vDwba2؜8(74:lz#6T`#n8E綗Uj# /7ڱUz=Lhjm;}FĪj=jx^INNS #endif #include #include #include #include #include #include #include #include #include #include #ifdef HAVE_UNISTD_H #include #endif #include "com_err.h" char *progname; static void usage() { fprintf(stderr, "%s: port program argv0 argv1 ...\n", progname); exit(1); } int main(argc, argv) int argc; char **argv; { unsigned short port; char *path; int sock, acc; int one = 1; struct sockaddr_in l_inaddr, f_inaddr; /* local, foreign address */ socklen_t namelen = sizeof(f_inaddr); #ifdef POSIX_SIGNALS struct sigaction csig; #endif progname = argv[0]; if(argc <= 3) usage(); if(atoi(argv[1]) == 0) usage(); port = htons(atoi(argv[1])); path = argv[2]; if ((sock = socket(PF_INET, SOCK_STREAM, 0)) < 0) { com_err(progname, errno, "creating socket"); exit(3); } (void) setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *)&one, sizeof (one)); memset(&l_inaddr, 0, sizeof(l_inaddr)); l_inaddr.sin_family = AF_INET; l_inaddr.sin_addr.s_addr = 0; l_inaddr.sin_port = port; if (bind(sock, (struct sockaddr *)&l_inaddr, sizeof(l_inaddr))) { com_err(progname, errno, "binding socket"); exit(3); } if (listen(sock, 1) == -1) { com_err(progname, errno, "listening"); exit(3); } printf("Ready!\n"); fflush(stdout); if ((acc = accept(sock, (struct sockaddr *)&f_inaddr, &namelen)) == -1) { com_err(progname, errno, "accepting"); exit(3); } dup2(acc, 0); dup2(acc, 1); dup2(acc, 2); close(sock); sock = 0; /* Don't wait for a child signal... Otherwise dejagnu gets confused */ #ifdef POSIX_SIGNALS csig.sa_handler = (RETSIGTYPE (*)())0; sigemptyset(&csig.sa_mask); csig.sa_flags = 0; sigaction(SIGCHLD, &csig, (struct sigaction *)0); #else signal(SIGCHLD, SIG_IGN); #endif if(execv(path, &argv[3])) fprintf(stderr, "t_inetd: Could not exec %s\n", path); exit(1); } krb5-1.16/src/tests/dejagnu/config/0000755000704600001450000000000013211554426017011 5ustar ghudsonlibuuidkrb5-1.16/src/tests/dejagnu/config/default.exp0000644000704600001450000016606313211554426021167 0ustar ghudsonlibuuid# Basic expect script for Kerberos tests. # This is a DejaGnu test script. # Written by Ian Lance Taylor, Cygnus Support, . # This script is automatically run by DejaGnu before running any of # the Kerberos test scripts. # This file provides several functions which deal with a local # Kerberos database. We have to do this such that we don't interfere # with any existing Kerberos database. We will create all the files # in the directory $tmppwd, which will have been created by the # testsuite default script. We will use $REALMNAME as our Kerberos # realm name, defaulting to KRBTEST.COM. set timeout 100 set stty_init {erase \^h kill \^u} set env(TERM) dumb set des3_krbtgt 0 set tgt_support_desmd5 0 # The names of the individual passes must be unique; lots of things # depend on it. The PASSES variable may not contain comments; only # small pieces get evaluated, so comments will do strange things. # Most of the purpose of using multiple passes is to exercise the # dependency of various bugs on configuration file settings, # particularly with regards to encryption types. # The des.no-kdc-md5 pass will fail if the KDC does not constrain # session key enctypes to those in its permitted_enctypes list. It # works by assuming enctype similarity, thus allowing the client to # request a des-cbc-md4 session key. Since only des-cbc-crc is in the # KDC's permitted_enctypes list, the TGT will be unusable. # KLUDGE for tracking down leaking ptys if 0 { rename spawn oldspawn rename wait oldwait proc spawn { args } { upvar 1 spawn_id spawn_id verbose "spawn: args=$args" set pid [eval oldspawn $args] verbose "spawn: pid=$pid spawn_id=$spawn_id" return $pid } proc wait { args } { upvar 1 spawn_id spawn_id verbose "wait: args=$args" set ret [eval oldwait $args] verbose "wait: $ret" return $ret } } if { [string length $VALGRIND] } { rename spawn valgrind_aux_spawn proc spawn { args } { global VALGRIND upvar 1 spawn_id spawn_id set newargs {} set inflags 1 set eatnext 0 foreach arg $args { if { $arg == "-ignore" \ || $arg == "-open" \ || $arg == "-leaveopen" } { lappend newargs $arg set eatnext 1 continue } if [string match "-*" $arg] { lappend newargs $arg continue } if { $eatnext } { set eatnext 0 lappend newargs $arg continue } if { $inflags } { set inflags 0 # Only run valgrind for local programs, not # system ones. #&&![string match "/bin/sh" $arg] sh is used to start kadmind! if [string match "/" [string index $arg 0]]&&![string match "/bin/ls" $arg]&&![regexp {/kshd$} $arg] { set newargs [concat $newargs $VALGRIND] } } lappend newargs $arg } set pid [eval valgrind_aux_spawn $newargs] return $pid } } # Hack around Solaris 9 kernel race condition that causes last output # from a pty to get dropped. if { $PRIOCNTL_HACK } { catch {exec priocntl -s -c FX -m 30 -p 30 -i pid [getpid]} rename spawn oldspawn proc spawn { args } { upvar 1 spawn_id spawn_id set newargs {} set inflags 1 set eatnext 0 foreach arg $args { if { $arg == "-ignore" \ || $arg == "-open" \ || $arg == "-leaveopen" } { lappend newargs $arg set eatnext 1 continue } if [string match "-*" $arg] { lappend newargs $arg continue } if { $eatnext } { set eatnext 0 lappend newargs $arg continue } if { $inflags } { set inflags 0 set newargs [concat $newargs {priocntl -e -c FX -p 0}] } lappend newargs $arg } set pid [eval oldspawn $newargs] return $pid } } # The des.des3-tgt.no-kdc-des3 pass will fail if the KDC doesn't # constrain ticket key enctypes to those in permitted_enctypes. It # does this by not putting des3 in the permitted_enctypes, while # creating a TGT princpal that has a des3 key as well as a des key. # XXX -- master_key_type is fragile w.r.t. permitted_enctypes; it is # possible to configure things such that you have a master_key_type # that is not permitted, and the error message used to be cryptic. set passes { { des mode=udp des3_krbtgt=0 {supported_enctypes=des-cbc-crc:normal} {dummy=[verbose -log "DES TGT, DES enctype"]} } { des.des3tgt mode=udp des3_krbtgt=1 {supported_enctypes=des-cbc-crc:normal} {dummy=[verbose -log "DES3 TGT, DES enctype"]} } { des3 mode=udp des3_krbtgt=1 {supported_enctypes=des3-cbc-sha1:normal des-cbc-crc:normal} {dummy=[verbose -log "DES3 TGT, DES3 + DES enctypes"]} } { aes-des mode=udp des3_krbtgt=0 {supported_enctypes=aes256-cts-hmac-sha1-96:normal des-cbc-crc:normal} {permitted_enctypes(kdc)=aes256-cts-hmac-sha1-96 des-cbc-crc} {permitted_enctypes(client)=aes256-cts-hmac-sha1-96 des-cbc-crc} {permitted_enctypes(server)=aes256-cts-hmac-sha1-96 des-cbc-crc} {master_key_type=aes256-cts-hmac-sha1-96} {dummy=[verbose -log "AES + DES enctypes"]} } { aes-only mode=udp des3_krbtgt=0 {supported_enctypes=aes256-cts-hmac-sha1-96:normal} {permitted_enctypes(kdc)=aes256-cts-hmac-sha1-96} {permitted_enctypes(client)=aes256-cts-hmac-sha1-96} {permitted_enctypes(server)=aes256-cts-hmac-sha1-96} {allow_weak_crypto(kdc)=false} {allow_weak_crypto(slave)=false} {allow_weak_crypto(client)=false} {allow_weak_crypto(server)=false} {master_key_type=aes256-cts-hmac-sha1-96} {dummy=[verbose -log "AES enctypes"]} } { aes-sha2-only mode=udp des3_krbtgt=0 {supported_enctypes=aes256-sha2:normal} {permitted_enctypes(kdc)=aes256-sha2} {permitted_enctypes(slave)=aes256-sha2} {permitted_enctypes(client)=aes256-sha2} {permitted_enctypes(server)=aes256-sha2} {default_tgs_enctypes(kdc)=aes256-sha2} {default_tgs_enctypes(slave)=aes256-sha2} {default_tgs_enctypes(client)=aes256-sha2} {default_tgs_enctypes(server)=aes256-sha2} {default_tkt_enctypes(kdc)=aes256-sha2} {default_tkt_enctypes(slave)=aes256-sha2} {default_tkt_enctypes(client)=aes256-sha2} {default_tkt_enctypes(server)=aes256-sha2} {allow_weak_crypto(kdc)=false} {allow_weak_crypto(slave)=false} {allow_weak_crypto(client)=false} {allow_weak_crypto(server)=false} {master_key_type=aes256-sha2} {dummy=[verbose -log "aes256-sha2 enctype"]} } { camellia-only mode=udp des3_krbtgt=0 {supported_enctypes=camellia256-cts:normal} {permitted_enctypes(kdc)=camellia256-cts} {permitted_enctypes(slave)=camellia256-cts} {permitted_enctypes(client)=camellia256-cts} {permitted_enctypes(server)=camellia256-cts} {default_tgs_enctypes(kdc)=camellia256-cts} {default_tgs_enctypes(slave)=camellia256-cts} {default_tgs_enctypes(client)=camellia256-cts} {default_tgs_enctypes(server)=camellia256-cts} {default_tkt_enctypes(kdc)=camellia256-cts} {default_tkt_enctypes(slave)=camellia256-cts} {default_tkt_enctypes(client)=camellia256-cts} {default_tkt_enctypes(server)=camellia256-cts} {allow_weak_crypto(kdc)=false} {allow_weak_crypto(slave)=false} {allow_weak_crypto(client)=false} {allow_weak_crypto(server)=false} {master_key_type=camellia256-cts} {dummy=[verbose -log "Camellia-256 enctype"]} } { aes-des3 mode=udp des3_krbtgt=0 {supported_enctypes=aes256-cts-hmac-sha1-96:normal des3-cbc-sha1:normal des-cbc-crc:normal} {permitted_enctypes(kdc)=aes256-cts-hmac-sha1-96 des3-cbc-sha1 des-cbc-crc} {permitted_enctypes(client)=aes256-cts-hmac-sha1-96 des3-cbc-sha1 des-cbc-crc} {permitted_enctypes(server)=aes256-cts-hmac-sha1-96 des3-cbc-sha1 des-cbc-crc} {master_key_type=aes256-cts-hmac-sha1-96} {dummy=[verbose -log "AES + DES3 + DES enctypes"]} } { aes-des3tgt mode=udp des3_krbtgt=1 {supported_enctypes=aes256-cts-hmac-sha1-96:normal des3-cbc-sha1:normal des-cbc-crc:normal} {permitted_enctypes(kdc)=aes256-cts-hmac-sha1-96 des3-cbc-sha1 des-cbc-crc} {permitted_enctypes(client)=aes256-cts-hmac-sha1-96 des3-cbc-sha1 des-cbc-crc} {permitted_enctypes(server)=aes256-cts-hmac-sha1-96 des3-cbc-sha1 des-cbc-crc} {master_key_type=aes256-cts-hmac-sha1-96} {dummy=[verbose -log "AES + DES enctypes, DES3 TGT"]} } { des-v4 mode=udp des3_krbtgt=0 {supported_enctypes=des-cbc-crc:v4} {default_tkt_enctypes(client)=des-cbc-crc} {dummy=[verbose -log "DES TGT, DES-CRC enctype, V4 salt"]} } { des-md5-v4 mode=udp des3_krbtgt=0 {supported_enctypes=des-cbc-md5:v4 des-cbc-crc:v4} {default_tkt_enctypes(client)=des-cbc-md5 des-cbc-crc} {dummy=[verbose -log "DES TGT, DES-MD5 and -CRC enctypes, V4 salt"]} } { all-enctypes mode=udp des3_krbtgt=0 {allow_weak_crypto(kdc)=false} {allow_weak_crypto(slave)=false} {allow_weak_crypto(client)=false} {allow_weak_crypto(server)=false} {dummy=[verbose -log "all default enctypes"]} } { des.no-kdc-md5 mode=udp des3_krbtgt=0 tgt_support_desmd5=0 {permitted_enctypes(kdc)=des-cbc-crc} {default_tgs_enctypes(client)=des-cbc-md5 des-cbc-md4 des-cbc-crc} {default_tkt_enctypes(client)=des-cbc-md5 des-cbc-md4 des-cbc-crc} {supported_enctypes=des-cbc-crc:normal} {master_key_type=des-cbc-crc} {dummy=[verbose -log \ "DES TGT, KDC permitting only des-cbc-crc"]} } { des.des3-tgt.no-kdc-des3 mode=udp tgt_support_desmd5=0 {permitted_enctypes(kdc)=des-cbc-crc} {default_tgs_enctypes(client)=des-cbc-crc} {default_tkt_enctypes(client)=des-cbc-crc} {supported_enctypes=des3-cbc-sha1:normal des-cbc-crc:normal} {master_key_type=des-cbc-crc} {dummy=[verbose -log \ "DES3 TGT, KDC permitting only des-cbc-crc"]} } } # des.md5-tgt is set as unused, since it won't trigger the error case # if SUPPORT_DESMD5 isn't honored. # The des.md5-tgt pass will fail if enctype similarity is inconsisent; # between 1.0.x and 1.1, the decrypt functions became more strict # about matching enctypes, while the KDB retrieval functions didn't # coerce the enctype to match what was requested. It works by setting # SUPPORT_DESMD5 on the TGT principal, forcing an enctype of # des-cbc-md5 on the TGT key. Since the database only contains a # des-cbc-crc key, the decrypt will fail if enctypes are not coerced. # des.no-kdc-md5.client-md4-skey is retained in unsed_passes, even # though des.no-kdc-md5 is roughly equivalent, since the associated # comment needs additional investigation at some point re the kadmin # client. # The des.no-kdc-md5.client-md4-skey will fail on TGS requests due to # the KDC issuing session keys that it won't accept. It will also # fail for a kadmin client, but for different reasons, since the kadm5 # library does some curious filtering of enctypes, and also uses # get_in_tkt() rather than get_init_creds(); the former does an # intersection of the enctypes provided by the caller and those listed # in the config file! set unused_passes { { des.md5-tgt des3_krbtgt=0 tgt_support_desmd5=1 supported_enctypes=des-cbc-crc:normal {permitted_enctypes(kdc)=des-cbc-md5 des-cbc-md4 des-cbc-crc} {permitted_enctypes(client)=des-cbc-md5 des-cbc-md4 des-cbc-crc} {dummy=[verbose -log "DES TGT, SUPPORTS_DESMD5"]} } { des.md5-tgt.no-kdc-md5 des3_krbtgt=0 tgt_support_desmd5=1 {permitted_enctypes(kdc)=des-cbc-crc} {default_tgs_enctypes(client)=des-cbc-crc} {default_tkt_enctypes(client)=des-cbc-crc} {supported_enctypes=des-cbc-crc:normal} {master_key_type=des-cbc-crc} {dummy=[verbose -log \ "DES TGT, SUPPORTS_DESMD5, KDC permitting only des-cbc-crc"]} } { des.no-kdc-md5.client-md4-skey des3_krbtgt=0 {permitted_enctypes(kdc)=des-cbc-crc} {permitted_enctypes(client)=des-cbc-crc des-cbc-md4} {default_tgs_enctypes(client)=des-cbc-crc des-cbc-md4} {default_tkt_enctypes(client)=des-cbc-md4} {supported_enctypes=des-cbc-crc:normal} {dummy=[verbose -log \ "DES TGT, DES enctype, KDC permitting only des-cbc-crc, client requests des-cbc-md4 session key"]} } { all-enctypes des3_krbtgt=1 {supported_enctypes=\ aes256-cts-hmac-sha1-96:normal aes256-cts-hmac-sha1-96:norealm \ aes128-cts-hmac-sha1-96:normal aes128-cts-hmac-sha1-96:norealm \ des3-cbc-sha1:normal des3-cbc-sha1:none \ des-cbc-md5:normal des-cbc-md4:normal des-cbc-crc:normal \ des-cbc-md5:v4 des-cbc-md4:v4 des-cbc-crc:v4 \ } {dummy=[verbose -log "DES3 TGT, default enctypes"]} } { aes-tcp mode=tcp des3_krbtgt=0 {supported_enctypes=aes256-cts-hmac-sha1-96:normal} {permitted_enctypes(kdc)=aes256-cts-hmac-sha1-96} {permitted_enctypes(client)=aes256-cts-hmac-sha1-96} {permitted_enctypes(server)=aes256-cts-hmac-sha1-96} {master_key_type=aes256-cts-hmac-sha1-96} {dummy=[verbose -log "AES via TCP"]} } } # {supported_enctypes=des-cbc-md5:normal des-cbc-crc:normal twofish256-hmac-sha1:normal } # This shouldn't be necessary on dejagnu-1.4 and later, but 1.3 seems # to need it because its runtest.exp doesn't deal with PASS at all. if [info exists PASS] { foreach pass $passes { if { [lsearch -exact $PASS [lindex $pass 0]] >= 0 } { lappend MULTIPASS $pass } } } else { set MULTIPASS $passes } set last_passname_conf "" set last_passname_db "" # We do everything in a temporary directory. if ![info exists TMPDIR] { set tmppwd "[pwd]/tmpdir" if ![file isdirectory $tmppwd] { catch "exec mkdir $tmppwd" status } } else { set tmppwd $TMPDIR } verbose "tmppwd=$tmppwd" # On Ultrix, use /bin/sh5 in preference to /bin/sh. if ![info exists BINSH] { if [file exists /bin/sh5] { set BINSH /bin/sh5 } else { set BINSH /bin/sh } } # For security, we must not use generally known passwords. This is # because some of the tests may be run as root. If the passwords were # generally know, then somebody could work out the appropriate # Kerberos ticket to use, and come in when, say, the telnetd daemon # was being tested by root. The window for doing this is very very # small, so the password does not have to be perfect, it just can't be # constant. if ![info exists KEY] { catch {exec $BINSH -c "echo $$"} KEY verbose "KEY is $KEY" set keyfile [open $tmppwd/KEY w] puts $keyfile "$KEY" close $keyfile } # Clear away any files left over from a previous run. # We can't use them now because we don't know the right KEY. # krb5.conf might change if running tests on another host file delete $tmppwd/krb5.conf $tmppwd/kdc.conf $tmppwd/slave.conf \ $tmppwd/krb5.client.conf $tmppwd/krb5.server.conf \ $tmppwd/krb5.kdc.conf $tmppwd/krb5.slave.conf proc delete_db {} { global tmppwd # Master and slave db files file delete $tmppwd/kdc-db $tmppwd/kdc-db.ok $tmppwd/kdc-db.kadm5 \ $tmppwd/kdc-db.kadm5.lock \ $tmppwd/kdc-db.ulog \ $tmppwd/slave-db $tmppwd/slave-db.ok $tmppwd/slave-db.kadm5 $tmppwd/slave-db.kadm5.lock \ $tmppwd/slave-db~ $tmppwd/slave-db~.ok $tmppwd/slave-db~.kadm5 $tmppwd/slave-db~.kadm5.lock # Creating a new database means we need a new srvtab. file delete $tmppwd/srvtab $tmppwd/cpw_srvtab } delete_db # Put the installed kerberos directories on PATH. # This needs to be fixed for V5. # set env(PATH) $env(PATH):/usr/kerberos/bin:/usr/kerberos/etc # verbose "PATH=$env(PATH)" # Some of the tests expect $env(USER) to be set. if ![info exists env(USER)] { if [info exists env(LOGNAME)] { set env(USER) $env(LOGNAME) } else { if [info exists logname] { set env(USER) $logname } else { catch "exec whoami" env(USER) } } } # set the realm. The user can override this on the runtest line. if ![info exists REALMNAME] { set REALMNAME "KRBTEST.COM" } verbose "Test realm is $REALMNAME" # Find some programs we need. We use the binaries from the build tree # if they exist. If they do not, then they must be in PATH. We # expect $objdir to be ...tests/dejagnu. foreach i { {KDB5_UTIL $objdir/../../kadmin/dbutil/kdb5_util} {KRB5KDC $objdir/../../kdc/krb5kdc} {KADMIND $objdir/../../kadmin/server/kadmind} {KADMIN $objdir/../../kadmin/cli/kadmin} {KADMIN_LOCAL $objdir/../../kadmin/cli/kadmin.local} {KINIT $objdir/../../clients/kinit/kinit} {KTUTIL $objdir/../../kadmin/ktutil/ktutil} {KLIST $objdir/../../clients/klist/klist} {KDESTROY $objdir/../../clients/kdestroy/kdestroy} {RESOLVE $objdir/../resolve/resolve} {T_INETD $objdir/t_inetd} {KPROPLOG $objdir/../../slave/kproplog} {KPASSWD $objdir/../../clients/kpasswd/kpasswd} {KPROPD $objdir/../../slave/kpropd} {KPROP $objdir/../../slave/kprop} } { set varname [lindex $i 0] if ![info exists $varname] { eval set varval [lindex $i 1] set varval [findfile $varval] set $varname $varval verbose "$varname=$varval" } { eval set varval \$$varname verbose "$varname already set to $varval" } } verbose "setting up onexit handler (old handler=[exit -onexit])" exit -onexit [concat { verbose "calling stop_kerberos_daemons (onexit handler)" stop_kerberos_daemons; } [exit -onexit]] # run_once # Many tests are independent of the actual enctypes used, which is # what our passes are (currently) all about. Use this to prevent # multiple invocations. If a test depends on, say, the master key # type but nothing else, you could also use the master key type in the # tag name, and avoid redundant tests in additional passes using the # same master key type. proc run_once { tag body } { global run_once_tags if ![info exists run_once_tags($tag)] { set run_once_tags($tag) 1 uplevel 1 $body } } # check_exit_status # Check the exit status of a spawned program (using the caller's value # of spawn_id). Returns 1 if the program succeeded, 0 if it failed. proc check_exit_status { testname } { upvar 1 spawn_id spawn_id verbose "about to wait ($testname)" set status_list [wait -i $spawn_id] verbose "wait -i $spawn_id returned $status_list ($testname)" catch "close -i $spawn_id" if { [lindex $status_list 2] != 0 || [lindex $status_list 3] != 0 } { verbose -log "exit status: $status_list" fail "$testname" return 0 } else { return 1 } } # # ENVSTACK # # These procedures implement an environment variable stack. They use # the global variable $envvars_tosave for the purpose of identifying # which environment variables to save. They also track which ones are # unset at any particular point. The stack pointer is $envstackp, # which is an integer. The arrays $envstack$envstackp and # $unenvstack$envstackp store respectively the set of old environment # variables/values pushed onto the stack and the set of old unset # environment variables for a given value of $envstackp. # Changing the value of $envvars_tosave after performing the first # push operation may result in strangeness. # # envstack_push # # Push set of current environment variables. # proc envstack_push { } { global env global envvars_tosave global envstackp global envstack$envstackp global unenvstack$envstackp verbose "envstack_push: starting, sp=$envstackp" foreach i $envvars_tosave { if [info exists env($i)] { verbose "envstack_push: saving $i=$env($i)" set envstack${envstackp}($i) $env($i) } { verbose "envstack_push: marking $i as unset" set unenvstack${envstackp}($i) unset } } incr envstackp verbose "envstack_push: exiting, sp=$envstackp" } # # envstack_pop # # Pop set of current environment variables. # proc envstack_pop { } { global env global envstackp verbose "envstack_pop: starting, sp=$envstackp" incr envstackp -1 global envstack$envstackp # YUCK!!! no obvious better way though... global unenvstack$envstackp if {$envstackp < 0} { perror "envstack_pop: stack underflow!" return } if [info exists envstack$envstackp] { foreach i [array names envstack$envstackp] { if [info exists env($i)] { verbose "envstack_pop: $i was $env($i)" } eval set env($i) \$envstack${envstackp}($i) verbose "envstack_pop: restored $i to $env($i)" } unset envstack$envstackp } if [info exists unenvstack$envstackp] { foreach i [array names unenvstack$envstackp] { if [info exists env($i)] { verbose "envstack_pop: $i was $env($i)" unset env($i) verbose "envstack_pop: $i unset" } { verbose "envstack_pop: ignoring already unset $i" } } unset unenvstack$envstackp } verbose "envstack_pop: exiting, sp=$envstackp" } # # Initialize the envstack # set envvars_tosave { KRB5_CONFIG KRB5CCNAME KRB5_CLIENT_KTNAME KRB5RCACHEDIR KRB5_KDC_PROFILE } set krb5_init_vars [list ] # XXX -- fix me later! foreach i $runvarlist { verbose "processing $i" if {[regexp "^(\[^=\]*)=(.*)" $i foo evar evalue]} { verbose "adding $evar to savelist" lappend envvars_tosave $evar verbose "savelist $envvars_tosave" lappend krb5_init_vars $i } # Make sure we don't get confused by translated messages # or localized times. lappend envvars_tosave "LC_ALL" lappend krb5_init_vars "LC_ALL=C" } set envstackp 0 envstack_push # setup_runtime_flags # Sets the proper flags for shared libraries. # Configuration is through a site.exp and the runvarlist variable # Returns 1 if variables were already set, otherwise 0 proc setup_runtime_env { } { global env global krb5_init_vars # Set the variables foreach i $krb5_init_vars { regexp "^(\[^=\]*)=(.*)" $i foo evar evalue set env($evar) "$evalue" verbose "$evar=$evalue" } return 0 } # get_hostname # This procedure sets the global variale hostname to the local # hostname as seen by krb5_sname_to_principal. Returns 1 on success, # 0 on failure. proc get_hostname { } { global RESOLVE global hostname global tmppwd if {[info exists hostname]} { return 1 } envstack_push setup_runtime_env catch "exec $RESOLVE -q >$tmppwd/hostname" exec_output envstack_pop if ![string match "" $exec_output] { verbose -log $exec_output perror "can't get hostname" return 0 } set file [open $tmppwd/hostname r] if { [ gets $file hostname ] == -1 } { perror "no output from hostname" return 0 } close $file file delete $tmppwd/hostname set hostname [string tolower $hostname] return 1 } # modify_principal name options... proc modify_principal { name args } { global KADMIN_LOCAL global REALMNAME envstack_push setup_kerberos_env kdc spawn $KADMIN_LOCAL -r $REALMNAME envstack_pop expect_after { eof { fail "modprinc (kadmin.local)" return 0 } timeout { fail "modprinc (kadmin.local)" return 0 } } expect "kadmin.local: " send "modprinc $args $name\r" expect -re "modprinc \[^\n\r\]* $name" expect -re "Principal .* modified." send "quit\r" expect eof catch expect_after if ![check_exit_status "kadmin.local modprinc"] { perror "kadmin.local modprinc exited abnormally" } return 1 } # kdc listens on +0..+3, depending whether we're testing reachable or not # client tries +1 and +6 # kadmind +4 # kpasswd +5 # (nothing) +6 # application servers (krlogind, telnetd, krshd, ftpd, etc) +8 # iprop +9 (if enabled) # kpropd +10 if [info exists PORTBASE] { set portbase $PORTBASE } else { set portbase 3085 } set ulog 0 # setup_kerberos_files # This procedure will create some Kerberos files which must be created # manually before trying to run any Kerberos programs. Returns 1 on # success, 0 on failure. proc setup_kerberos_files { } { global REALMNAME global hostname global tmppwd global supported_enctypes global last_passname_conf global multipass_name global master_key_type global mode global portbase global ulog if ![get_hostname] { return 0 } setup_krb5_conf client setup_krb5_conf server setup_krb5_conf kdc setup_krb5_conf slave # Create a kdc.conf file. if { ![file exists $tmppwd/kdc.conf] \ || $last_passname_conf != $multipass_name } { set conffile [open $tmppwd/kdc.conf w] puts $conffile "\[kdcdefaults\]" puts $conffile " kdc_listen = $portbase,[expr 1 + $portbase],[expr 2 + $portbase]" puts $conffile " kdc_tcp_listen = $portbase,[expr 1 + $portbase],[expr 2 + $portbase]" puts $conffile "" puts $conffile "\[realms\]" puts $conffile " $REALMNAME = \{" # Testing with a colon in the name exercises default handling # for pathnames. puts $conffile " key_stash_file = $tmppwd/stash:foo" puts $conffile " acl_file = $tmppwd/acl" puts $conffile " kadmind_port = [expr 4 + $portbase]" puts $conffile " kpasswd_port = [expr 5 + $portbase]" puts $conffile " max_life = 1:00:00" puts $conffile " max_renewable_life = 3:00:00" if [info exists master_key_type] { puts $conffile " master_key_type = $master_key_type" } puts $conffile " master_key_name = master/key" if [info exists supported_enctypes] { puts $conffile " supported_enctypes = $supported_enctypes" } if { $mode == "tcp" } { puts $conffile " kdc_listen = [expr 3 + $portbase]" puts $conffile " kdc_tcp_listen = [expr 1 + $portbase],[expr 3 + $portbase]" } else { puts $conffile " kdc_listen = [expr 1 + $portbase]" puts $conffile " kdc_tcp_listen = [expr 3 + $portbase]" } puts $conffile " default_principal_expiration = 2037.12.31.23.59.59" puts $conffile " default_principal_flags = -postdateable forwardable" puts $conffile " dict_file = $tmppwd/dictfile" if { $ulog != 0 } { puts $conffile " iprop_enable = true" puts $conffile " iprop_port = [expr 9 + $portbase]" puts $conffile " iprop_logfile = $tmppwd/db.ulog" } else { puts $conffile "# no ulog" } puts $conffile " \}" puts $conffile "" close $conffile } # Create a config file for the slave KDC (kpropd only, no normal # KDC processes). if { ![file exists $tmppwd/slave.conf] \ || $last_passname_conf != $multipass_name } { set conffile [open $tmppwd/slave.conf w] puts $conffile "\[kdcdefaults\]" puts $conffile " kdc_listen = $portbase,[expr 1 + $portbase],[expr 2 + $portbase]" puts $conffile " kdc_tcp_listen = $portbase,[expr 1 + $portbase],[expr 2 + $portbase]" puts $conffile "" puts $conffile "\[realms\]" puts $conffile " $REALMNAME = \{" # Testing with a colon in the name exercises default handling # for pathnames. puts $conffile " key_stash_file = $tmppwd/slave-stash" puts $conffile " acl_file = $tmppwd/slave-acl" puts $conffile " kadmind_port = [expr 4 + $portbase]" puts $conffile " kpasswd_port = [expr 5 + $portbase]" puts $conffile " max_life = 1:00:00" puts $conffile " max_renewable_life = 3:00:00" if [info exists master_key_type] { puts $conffile " master_key_type = $master_key_type" } puts $conffile " master_key_name = master/key" if [info exists supported_enctypes] { puts $conffile " supported_enctypes = $supported_enctypes" } if { $mode == "tcp" } { puts $conffile " kdc_listen = [expr 3 + $portbase]" puts $conffile " kdc_tcp_listen = [expr 1 + $portbase],[expr 3 + $portbase]" } else { puts $conffile " kdc_listen = [expr 1 + $portbase]" puts $conffile " kdc_tcp_listen = [expr 3 + $portbase]" } puts $conffile " default_principal_expiration = 2037.12.31.23.59.59" puts $conffile " default_principal_flags = -postdateable forwardable" puts $conffile " dict_file = $tmppwd/dictfile" if { $ulog != 0 } { puts $conffile " iprop_enable = true" puts $conffile " iprop_port = [expr 9 + $portbase]" puts $conffile " iprop_logfile = $tmppwd/slave-db.ulog" } else { puts $conffile "# no ulog" } puts $conffile " \}" puts $conffile "" close $conffile } # Create ACL file. set aclfile [open $tmppwd/acl w] puts $aclfile "krbtest/admin@$REALMNAME *" puts $aclfile "kiprop/$hostname@$REALMNAME p" close $aclfile # Create dictfile file. if ![file exists $tmppwd/dictfile] { set dictfile [open $tmppwd/dictfile w] puts $dictfile "weak_password" close $dictfile } set last_passname_conf $multipass_name return 1 } proc reset_kerberos_files { } { global tmppwd file delete $tmppwd/kdc.conf $tmppwd/slave.conf $tmppwd/krb5.client.conf \ $tmppwd/krb5.server.conf $tmppwd/krb5.kdc.conf setup_kerberos_files } proc setup_krb5_conf { {type client} } { global tmppwd global hostname global REALMNAME global last_passname_conf global multipass_name global default_tgs_enctypes global default_tkt_enctypes global permitted_enctypes global allow_weak_crypto global mode global portbase global srcdir set pkinit_certs [findfile "[pwd]/$srcdir/pkinit-certs" "[pwd]/$srcdir/pkinit-certs" "$srcdir/pkinit-certs"] # Create a krb5.conf file. if { ![file exists $tmppwd/krb5.$type.conf] \ || $last_passname_conf != $multipass_name } { set conffile [open $tmppwd/krb5.$type.conf w] puts $conffile "\[libdefaults\]" puts $conffile " default_realm = $REALMNAME" puts $conffile " dns_lookup_kdc = false" if [info exists allow_weak_crypto($type)] { puts $conffile " allow_weak_crypto = $allow_weak_crypto($type)" } else { puts $conffile " allow_weak_crypto = true" } puts $conffile " pkinit_anchors = FILE:$pkinit_certs/ca.pem" if [info exists default_tgs_enctypes($type)] { puts $conffile \ " default_tgs_enctypes = $default_tgs_enctypes($type)" } if [info exists default_tkt_enctypes($type)] { puts $conffile \ " default_tkt_enctypes = $default_tkt_enctypes($type)" } if [info exists permitted_enctypes($type)] { puts $conffile \ " permitted_enctypes = $permitted_enctypes($type)" } if { $mode == "tcp" } { puts $conffile " udp_preference_limit = 1" } puts $conffile " plugin_base_dir = $tmppwd/../../../plugins" puts $conffile "" puts $conffile "\[realms\]" puts $conffile " $REALMNAME = \{" # There's probably nothing listening here. It would be a good # test for the handling of a non-responsive KDC address. However, # on some systems, like Tru64, we often wind up with the client's # socket bound to this address, causing our request to appear in # our incoming queue as if it were a response, which causes test # failures. If we were running the client and KDC on different # hosts, this would be okay.... #puts $conffile " kdc = $hostname:[expr 6 + $portbase]" puts $conffile " pkinit_identity = FILE:$pkinit_certs/kdc.pem,$pkinit_certs/privkey.pem" puts $conffile " pkinit_anchors = FILE:$pkinit_certs/ca.pem" puts $conffile " kdc = $hostname:[expr 1 + $portbase]" puts $conffile " admin_server = $hostname:[expr 4 + $portbase]" puts $conffile " kpasswd_server = $hostname:[expr 5 + $portbase]" puts $conffile " database_module = foo_db2" puts $conffile " \}" puts $conffile "" puts $conffile "\[domain_realm\]" puts $conffile " $hostname = $REALMNAME" puts $conffile "" puts $conffile "\[logging\]" puts $conffile " admin_server = FILE:$tmppwd/kadmind5.log" puts $conffile " kdc = FILE:$tmppwd/kdc.log" puts $conffile " default = FILE:$tmppwd/others.log" puts $conffile "" puts $conffile "\[dbmodules\]" puts $conffile " db_module_dir = $tmppwd/../../../plugins/kdb" puts $conffile " foo_db2 = {" puts $conffile " db_library = db2" puts $conffile " database_name = $tmppwd/$type-db" puts $conffile " }" close $conffile } } # Save the original values of the environment variables we are going # to muck with. # XXX deal with envstack later. if [info exists env(KRB5_CONFIG)] { set orig_krb5_conf $env(KRB5_CONFIG) } else { catch "unset orig_krb5_config" } if [info exists env(KRB5CCNAME)] { set orig_krb5ccname $env(KRB5CCNAME) } else { catch "unset orig_krb5ccname" } if [info exists env(KRB5_CLIENT_KTNAME)] { set orig_krb5clientktname $env(KRB5_CLIENT_KTNAME) } else { catch "unset orig_krb5clientktname" } if [ info exists env(KRB5RCACHEDIR)] { set orig_krb5rcachedir $env(KRB5RCACHEDIR) } else { catch "unset orig_krb5rcachedir" } # setup_kerberos_env # Set the environment variables needed to run Kerberos programs. proc setup_kerberos_env { {type client} } { global REALMNAME global env global tmppwd global hostname global krb5_init_vars global portbase # Set the environment variable KRB5_CONFIG to point to our krb5.conf file. # All the Kerberos tools check KRB5_CONFIG. # Actually, V5 doesn't currently use this. set env(KRB5_CONFIG) $tmppwd/krb5.$type.conf verbose "KRB5_CONFIG=$env(KRB5_CONFIG)" # Direct the Kerberos programs at a local ticket file. set env(KRB5CCNAME) $tmppwd/tkt verbose "KRB5CCNAME=$env(KRB5CCNAME)" # Direct the Kerberos programs at a local client keytab. set env(KRB5_CLIENT_KTNAME) $tmppwd/client_keytab verbose "KRB5_CLIENT_KTNAME=$env(KRB5_CLIENT_KTNAME)" # Direct the Kerberos server at a cache file stored in the # temporary directory. set env(KRB5RCACHEDIR) $tmppwd verbose "KRB5RCACHEDIR=$env(KRB5RCACHEDIR)" # Get the run time environment variables... (including LD_LIBRARY_PATH) setup_runtime_env # Set our kdc config file, if needed. switch $type { client - server { catch {unset env(KRB5_KDC_PROFILE)} } kdc { set env(KRB5_KDC_PROFILE) $tmppwd/kdc.conf } slave { set env(KRB5_KDC_PROFILE) $tmppwd/slave.conf } default { error "unknown config file type $type" } } if [info exists env(KRB5_KDC_PROFILE)] { verbose "KRB5_KDC_PROFILE=$env(KRB5_KDC_PROFILE)" } # Create an environment setup script. (For convenience) if ![file exists $tmppwd/$type-env.sh] { set envfile [open $tmppwd/$type-env.sh w] puts $envfile "KRB5_CONFIG=$env(KRB5_CONFIG)" puts $envfile "KRB5CCNAME=$env(KRB5CCNAME)" puts $envfile "KRB5_CLIENT_KTNAME=$env(KRB5_CLIENT_KTNAME)" puts $envfile "KRB5RCACHEDIR=$env(KRB5RCACHEDIR)" if [info exists env(KRB5_KDC_PROFILE)] { puts $envfile "KRB5_KDC_PROFILE=$env(KRB5_KDC_PROFILE)" } else { puts $envfile "unset KRB5_KDC_PROFILE" } puts $envfile "export KRB5_CONFIG KRB5CCNAME KRB5RCACHEDIR" puts $envfile "export KRB5_KDC_PROFILE KRB5_CLIENT_KTNAME" foreach i $krb5_init_vars { regexp "^(\[^=\]*)=(.*)" $i foo evar evalue puts $envfile "$evar=$env($evar)" puts $envfile "export $evar" } close $envfile } if ![file exists $tmppwd/$type-env.csh] { set envfile [open $tmppwd/$type-env.csh w] puts $envfile "setenv KRB5_CONFIG $env(KRB5_CONFIG)" puts $envfile "setenv KRB5CCNAME $env(KRB5CCNAME)" puts $envfile "setenv KRB5_CLIENT_KTNAME $env(KRB5_CLIENT_KTNAME)" puts $envfile "setenv KRB5RCACHEDIR $env(KRB5RCACHEDIR)" if [info exists env(KRB5_KDC_PROFILE)] { puts $envfile "setenv KRB5_KDC_PROFILE $env(KRB5_KDC_PROFILE)" } else { puts $envfile "unsetenv KRB5_KDC_PROFILE" } foreach i $krb5_init_vars { regexp "^(\[^=\]*)=(.*)" $i foo evar evalue puts $envfile "setenv $evar $env($evar)" } close $envfile } return 1 } # setup_kerberos_db # Initialize the Kerberos database. If the argument is non-zero, call # pass at relevant points. Returns 1 on success, 0 on failure. proc setup_kerberos_db { standalone } { global REALMNAME KDB5_UTIL KADMIN_LOCAL KEY global tmppwd hostname global spawn_id global des3_krbtgt tgt_support_desmd5 global multipass_name last_passname_db set failall 0 if {!$standalone && [file exists $tmppwd/kdc-db.ok] \ && $last_passname_db == $multipass_name} { return 1 } delete_db envstack_push if { ![setup_kerberos_files] || ![setup_kerberos_env kdc] } { set failall 1 } # Set up a common expect_after for use in multiple places. set def_exp_after { timeout { set test "$test (timeout)" break } eof { set test "$test (eof)" break } } set test "kdb5_util create" set body { if $failall { break } #exec xterm verbose "starting $test" spawn $KDB5_UTIL -r $REALMNAME create -W expect_after $def_exp_after expect "Enter KDC database master key:" set test "kdb5_util create (verify)" send "masterkey$KEY\r" expect "Re-enter KDC database master key to verify:" set test "kdb5_util create" send "masterkey$KEY\r" expect { -re "\[Cc\]ouldn't" { expect eof break } "Cannot find/read stored" exp_continue "Warning: proceeding without master key" exp_continue eof { } } catch expect_after if ![check_exit_status kdb5_util] { break } } set ret [catch $body] catch expect_after if $ret { set failall 1 if $standalone { fail $test } } else { if $standalone { pass $test } } # Stash the master key in a file. set test "kdb5_util stash" set body { if $failall { break } spawn $KDB5_UTIL -r $REALMNAME stash verbose "starting $test" expect_after $def_exp_after expect "Enter KDC database master key:" send "masterkey$KEY\r" expect eof catch expect_after if ![check_exit_status kdb5_util] { break } } set ret [catch $body] catch "expect eof" catch expect_after if $ret { set failall 1 if $standalone { fail $test } else { delete_db } } else { if $standalone { pass $test } } # Add an admin user. set test "kadmin.local ank krbtest/admin" set body { if $failall { break } spawn $KADMIN_LOCAL -r $REALMNAME verbose "starting $test" expect_after $def_exp_after expect "kadmin.local: " send "ank krbtest/admin@$REALMNAME\r" # It echos... expect "ank krbtest/admin@$REALMNAME\r" expect "Enter password for principal \"krbtest/admin@$REALMNAME\":" send "adminpass$KEY\r" expect "Re-enter password for principal \"krbtest/admin@$REALMNAME\":" send "adminpass$KEY\r" expect { "Principal \"krbtest/admin@$REALMNAME\" created" { } "Principal or policy already exists while creating*" { } } expect "kadmin.local: " send "quit\r" expect eof catch expect_after if ![check_exit_status kadmin_local] { break } } set ret [catch $body] catch "expect eof" catch expect_after if $ret { set failall 1 if $standalone { fail $test } else { delete_db } } else { if $standalone { pass $test } } # Add an incremental-propagation service. set test "kadmin.local ank krbtest/fast" set body { if $failall { break } spawn $KADMIN_LOCAL -r $REALMNAME verbose "starting $test" expect_after $def_exp_after expect "kadmin.local: " send "ank +requires_preauth krbtest/fast@$REALMNAME\r" expect "Enter password for principal \"krbtest/fast@$REALMNAME\":" send "adminpass$KEY\r" expect "Re-enter password for principal \"krbtest/fast@$REALMNAME\":" send "adminpass$KEY\r" expect { "Principal \"krbtest/fast@$REALMNAME\" created" { } "Principal or policy already exists while creating*" { } } expect "kadmin.local: " send "quit\r" expect eof catch expect_after if ![check_exit_status kadmin_local] { break } } set ret [catch $body] catch "expect eof" catch expect_after if $ret { set failall 1 if $standalone { fail $test } else { delete_db } } else { if $standalone { pass $test } } if $des3_krbtgt { # Set the TGT key to DES3. set test "kadmin.local TGT to DES3" set body { if $failall { break } spawn $KADMIN_LOCAL -r $REALMNAME -e des3-cbc-sha1:normal verbose "starting $test" expect_after $def_exp_after expect "kadmin.local: " send "cpw -randkey krbtgt/$REALMNAME@$REALMNAME\r" # It echos... expect "cpw -randkey krbtgt/$REALMNAME@$REALMNAME\r" expect { "Key for \"krbtgt/$REALMNAME@$REALMNAME\" randomized." { } } expect "kadmin.local: " send "quit\r" expect eof catch expect_after if ![check_exit_status kadmin_local] { break } } set ret [catch $body] catch "expect eof" catch expect_after if $ret { set failall 1 if $standalone { fail $test } else { delete_db } } else { if $standalone { pass $test } } } if $tgt_support_desmd5 { # Make TGT support des-cbc-md5 set test "kadmin.local TGT to SUPPORT_DESMD5" set body { if $failall { break } spawn $KADMIN_LOCAL -r $REALMNAME verbose "starting $test" expect_after $def_exp_after expect "kadmin.local: " send "modprinc +support_desmd5 krbtgt/$REALMNAME@$REALMNAME\r" # It echos... expect "modprinc +support_desmd5 krbtgt/$REALMNAME@$REALMNAME\r" expect { "Principal \"krbtgt/$REALMNAME@$REALMNAME\" modified.\r\n" { } } expect "kadmin.local: " send "quit\r" expect eof catch expect_after if ![check_exit_status kadmin_local] { break } } set ret [catch $body] catch "expect eof" catch expect_after if $ret { set failall 1 if $standalone { fail $test } else { delete_db } } else { if $standalone { pass $test } } } envstack_pop # create the admin database lock file catch "exec touch $tmppwd/adb.lock" set last_passname_db $multipass_name return 1 } # setup_slave_db # Initialize the slave Kerberos database. Returns 1 on success, 0 on # failure. proc setup_slave_db { } { global REALMNAME global KDB5_UTIL global KADMIN_LOCAL global KEY global tmppwd global spawn_id set failall 0 envstack_push if { ![setup_kerberos_files] || ![setup_kerberos_env slave] } { set failall 1 } # Set up a common expect_after for use in multiple places. set def_exp_after { timeout { set test "$test (timeout)" break } eof { set test "$test (eof)" break } } set test "slave kdb5_util create " set body { if $failall { break } #exec xterm verbose "starting $test" spawn $KDB5_UTIL -r $REALMNAME create -W expect_after $def_exp_after expect "Enter KDC database master key:" set test "slave kdb5_util create (verify)" send "masterkey$KEY\r" expect "Re-enter KDC database master key to verify:" set test "slave kdb5_util create" send "masterkey$KEY\r" expect { -re "\[Cc\]ouldn't" { expect eof break } "Cannot find/read stored" exp_continue "Warning: proceeding without master key" exp_continue eof { } } catch expect_after if ![check_exit_status kdb5_util] { break } } set ret [catch $body] catch expect_after if $ret { set failall 1 } # Stash the master key in a file. set test "slave kdb5_util stash" set body { if $failall { break } spawn $KDB5_UTIL -r $REALMNAME stash verbose "starting $test" expect_after $def_exp_after expect "Enter KDC database master key:" send "masterkey$KEY\r" expect eof catch expect_after if ![check_exit_status kdb5_util] { break } } set ret [catch $body] catch "expect eof" catch expect_after if $ret { set failall 1 delete_db } if !$failall { # create the admin database lock file catch "exec touch $tmppwd/slave-adb.lock" } return [expr !$failall] } proc start_kpropd {} { global kpropd_pid kpropd_spawn_id KPROPD T_INETD KDB5_UTIL portbase tmppwd global spawn_id envstack_push setup_kerberos_env slave spawn $KPROPD -S -d -t -P [expr 10 + $portbase] -s $tmppwd/srvtab -f $tmppwd/incoming-slave-datatrans -p $KDB5_UTIL -a $tmppwd/kpropd-acl set kpropd_pid [exp_pid] set kpropd_spawn_id $spawn_id # send_user [list $KPROPD -S -d -P [expr 10 + $portbase] -s $tmppwd/srvtab -f $tmppwd/incoming-slave-datatrans -p $KDB5_UTIL -a $tmppwd/kpropd-acl]\n # spawn_shell envstack_pop } # start_kerberos_daemons # A procedure to build a Kerberos database and start up the kerberos # and kadmind daemons. This sets the global variables kdc_pid, # kdc_spawn_id, kadmind_pid, and kadmind_spawn_id. The procedure # stop_kerberos_daemons should be used to stop the daemons. If the # argument is non-zero, call pass at relevant points. Returns 1 on # success, 0 on failure. proc start_kerberos_daemons { standalone } { global BINSH global REALMNAME global KRB5KDC global KADMIND global KEY global kdc_pid global kdc_spawn_id global kadmind_pid global kadmind_spawn_id global tmppwd global env global timeout if ![setup_kerberos_db 0] { return 0 } if {$standalone} { file delete $tmppwd/krb.log $tmppwd/kadmind.log $tmppwd/krb5kdc_rcache } # Start up the kerberos daemon # Why are we doing all this with the log file you may ask. # We need a handle on when the server starts. If we log the output # of the server to say stderr, then if we stop looking for output, # buffers will fill and the server will stop working.... # So, we look to see when a line is added to the log file and then # check it.. # The same thing is done a little later for the kadmind set kdc_lfile $tmppwd/kdc.log set kadmind_lfile $tmppwd/kadmind5.log set kdc_pidfile $tmppwd/kdc.pid set kadmind_pidfile $tmppwd/kadmind.pid envstack_push setup_kerberos_env kdc # Nuke pid file - to test if setup file delete $kdc_pidfile spawn $KRB5KDC -r $REALMNAME -n -P $kdc_pidfile envstack_pop set kdc_pid [exp_pid] set kdc_spawn_id $spawn_id expect { "starting" { } eof { if {$standalone} { verbose -log "krb5kdc failed to start" fail "krb5kdc" } else { perror "krb5kdc failed to start" } stop_kerberos_daemons return 0 } } if (![file exists $kdc_pidfile]) { fail "krb5kdc pidfile" stop_kerberos_daemons return 0 } set f [open $kdc_pidfile "r"] if {[gets $f foundpid] < 0 || ![string equal $kdc_pid $foundpid]} { fail "krb5kdc pid file contents" close $f stop_kerberos_daemons return 0 } close $f if {$standalone} { pass "krb5kdc" } # Give the kerberos daemon a few seconds to get set up. # sleep 2 # # Save setting of KRB5_KTNAME. We do not want to override kdc.conf # file during kadmind startup. (this is in case user has KRB5_KTNAME # set before starting make check) # if [info exists env(KRB5_KTNAME)] { set start_save_ktname $env(KRB5_KTNAME) } catch "unset env(KRB5_KTNAME)" # Start up the kadmind daemon envstack_push setup_kerberos_env kdc file delete $kadmind_pidfile spawn $BINSH -c "exec $KADMIND -r $REALMNAME -W -nofork -P $kadmind_pidfile" envstack_pop set kadmind_pid [exp_pid] set kadmind_spawn_id $spawn_id # Restore KRB5_KTNAME if [info exists start_save_ktname] { set env(KRB5_KTNAME) $start_save_ktname unset start_save_ktname } expect { "Seeding random number" exp_continue "No principal in keytab matches desired name" { dump_db exp_continue } "starting" { } eof { verbose -log "kadmind failed to start" if {$standalone} { fail "kadmind" } else { perror "kadmind failed to start" } stop_kerberos_daemons return 0 } } if (![file exists $kadmind_pidfile]) { fail "kadmind pidfile" stop_kerberos_daemons return 0 } set f [open $kadmind_pidfile "r"] if {[gets $f foundpid] < 0 || ![string equal $kadmind_pid $foundpid]} { fail "kadmind pid file contents" close $f stop_kerberos_daemons return 0 } close $f if {$standalone} { pass "kadmind" } # Give the kadmind daemon a few seconds to get set up. # sleep 2 return 1 } # stop_kerberos_daemons # Stop the kerberos daemons. Returns 1 on success, 0 on failure. proc stop_kerberos_daemons { } { global kdc_pid global kdc_spawn_id global kadmind_pid global kadmind_spawn_id verbose "entered stop_kerberos_daemons" if [info exists kdc_pid] { if [catch "exec kill $kdc_pid" msg] { verbose "kill kdc: $msg" } if [catch "expect -i $kdc_spawn_id eof" msg] { verbose "expect kdc eof: $msg" } set kdc_list [wait -i $kdc_spawn_id] verbose "wait -i $kdc_spawn_id returned $kdc_list (kdc)" unset kdc_pid unset kdc_list } if [info exists kadmind_pid] { if [catch "exec kill $kadmind_pid" msg] { verbose "kill kadmind: $msg" } if [catch "expect -i $kadmind_spawn_id eof" msg] { verbose "expect kadmind eof: $msg" } set kadmind_list [wait -i $kadmind_spawn_id] verbose "wait -i $kadmind_spawn_id returned $kadmind_list (kadmind5)" unset kadmind_pid unset kadmind_list } verbose "exiting stop_kerberos_daemons" return 1 } # add_kerberos_key # Add an key to the Kerberos database. start_kerberos_daemons must be # called before this procedure. If the standalone argument is # non-zero, call pass at relevant points. Returns 1 on success, 0 on # failure. proc add_kerberos_key { kkey standalone } { global REALMNAME global KADMIN global KEY global spawn_id # Use kadmin to add an key. set test "kadmin ank $kkey" set body { envstack_push setup_kerberos_env client spawn $KADMIN -p krbtest/admin@$REALMNAME -q "ank $kkey@$REALMNAME" envstack_pop verbose "starting $test" expect_after { "Cannot contact any KDC" { set test "$test (lost KDC)" break } timeout { set test "$test (timeout)" break } eof { set test "$test (eof)" break } } expect -re "assword\[^\r\n\]*: *" send "adminpass$KEY\r" expect "Enter password for principal \"$kkey@$REALMNAME\":" send "$kkey" send "$KEY\r" expect "Re-enter password for principal \"$kkey@$REALMNAME\":" send "$kkey" send "$KEY\r" expect { "Principal \"$kkey@$REALMNAME\" created" { } "Principal or policy already exists while creating*" { } } expect eof if ![check_exit_status kadmin] { break } } set ret [catch $body] catch "expect eof" catch expect_after if $ret { if $standalone { fail $test } return 0 } else { if $standalone { pass $test } return 1 } } # dump_db proc dump_db { } { global KADMIN_LOCAL global REALMNAME spawn $KADMIN_LOCAL -r $REALMNAME expect_after { eof { perror "failed to get debugging dump of database (eof)" } timeout { perror "failed to get debugging dump of database (timeout)" } } expect "kadmin.local: " send "getprincs\r" expect "kadmin.local: " send "quit\r" expect eof catch expect_after } # add_random_key # Add a key with a random password to the Kerberos database. # start_kerberos_daemons must be called before this procedure. If the # standalone argument is non-zero, call pass at relevant points. # Returns 1 on success, 0 on failure. proc add_random_key { kkey standalone } { global REALMNAME global KADMIN global KEY global spawn_id # Use kadmin to add an key. set test "kadmin ark $kkey" set body { envstack_push setup_kerberos_env client spawn $KADMIN -p krbtest/admin@$REALMNAME -q "ank -randkey $kkey@$REALMNAME" envstack_pop expect_after { timeout { set test "$test (timeout)" break } eof { set test "$test (eof)" break } } expect -re "assword\[^\r\n\]*: *" send "adminpass$KEY\r" expect { "Principal \"$kkey@$REALMNAME\" created" { } "Principal or policy already exists while creating*" { } } expect eof if ![check_exit_status kadmin] { break } } if [catch $body] { catch expect_after if $standalone { fail $test } return 0 } else { catch expect_after if $standalone { pass $test } return 1 } } # setup_srvtab # Set up a srvtab file. start_kerberos_daemons and add_random_key # $id/$hostname must be called before this procedure. If the # argument is non-zero, call pass at relevant points. Returns 1 on # success, 0 on failure. If the id field is not provided, host is used. proc setup_srvtab { standalone {id host} } { global REALMNAME global KADMIN_LOCAL global KEY global tmppwd global hostname global spawn_id global last_service if {!$standalone && [file exists $tmppwd/srvtab] && $last_service == $id} { return 1 } file delete $tmppwd/srvtab $tmppwd/srvtab.old if ![get_hostname] { return 0 } file delete $hostname-new-srvtab envstack_push setup_kerberos_env kdc spawn $KADMIN_LOCAL -r $REALMNAME envstack_pop expect_after { -re "(.*)\r\nkadmin.local: " { fail "kadmin.local srvtab (unmatched output: $expect_out(1,string))" if {!$standalone} { file delete $tmppwd/srvtab } catch "expect_after" return 0 } timeout { fail "kadmin.local srvtab" if {!$standalone} { file delete $tmppwd/srvtab } catch "expect_after" return 0 } eof { fail "kadmin.local srvtab" if {!$standalone} { file delete $tmppwd/srvtab } catch "expect_after" return 0 } } expect "kadmin.local: " send "xst -k $hostname-new-srvtab $id/$hostname kiprop/$hostname\r" expect "xst -k $hostname-new-srvtab $id/$hostname kiprop/$hostname\r\n" expect { -re ".*Entry for principal $id/$hostname.* added to keytab WRFILE:$hostname-new-srvtab." { } -re "\r\nkadmin.local: " { if {$standalone} { fail "kadmin.local srvtab" } else { file delete $tmppwd/srvtab } catch expect_after return 0 } } expect "kadmin.local: " send "quit\r" expect eof catch expect_after if ![check_exit_status "kadmin.local srvtab"] { if {!$standalone} { file delete $tmppwd/srvtab } return 0 } catch "exec mv -f $hostname-new-srvtab $tmppwd/srvtab" exec_output if ![string match "" $exec_output] { verbose -log "$exec_output" perror "can't mv new srvtab" return 0 } if {$standalone} { pass "kadmin.local srvtab" } # Make the srvtab file globally readable in case we are using a # root shell and the srvtab is NFS mounted. catch "exec chmod a+r $tmppwd/srvtab" # Remember what we just extracted set last_service $id return 1 } # kinit # Use kinit to get a ticket. If the argument is non-zero, call pass # at relevant points. Returns 1 on success, 0 on failure. proc kinit { name pass standalone } { global REALMNAME global KINIT global spawn_id # Use kinit to get a ticket. # # For now always get forwardable tickets. Later when we need to make # tests that distiguish between forwardable tickets and otherwise # we should but another option to this proc. --proven # spawn $KINIT -5 -f $name@$REALMNAME expect { "Password for $name@$REALMNAME:" { verbose "kinit started" } timeout { fail "kinit" return 0 } eof { fail "kinit" return 0 } } send "$pass\r" expect eof if ![check_exit_status kinit] { return 0 } if {$standalone} { pass "kinit" } return 1 } proc kinit_renew { name pass standalone } { global REALMNAME global KINIT global spawn_id spawn $KINIT -5 -f $name@$REALMNAME expect { "Password for $name@$REALMNAME:" { verbose "kinit started" } timeout { fail "kinit" return 0 } eof { fail "kinit" return 0 } } send "$pass\r" expect eof if ![check_exit_status kinit] { return 0 } spawn $KINIT -R expect eof if ![check_exit_status "kinit_renew"] { return 0 } return 1 } # Retrieve a ticket using FAST armor proc kinit_fast { name pass standalone } { global REALMNAME global KINIT global spawn_id global env # Use kinit to get a ticket. # spawn $KINIT -5 -f -T $env(KRB5CCNAME) $name@$REALMNAME expect { "Password for $name@$REALMNAME:" { verbose "kinit started" } timeout { fail "kinit_fast" return 0 } eof { fail "kinit_fast" return 0 } } send "$pass\r" expect eof if ![check_exit_status kinit] { return 0 } if {$standalone} { pass "kinit_fast" } return 1 } proc kinit_anonymous { name } { global REALMNAME global KINIT global spawn_id # Use kinit to get a ticket. # spawn $KINIT -5 -f -n $name@$REALMNAME expect { "Password for $name@$REALMNAME:" { fail "kinit_anonymous (password requested)" return 0 } timeout { fail "kinit_anonymous (timeout)" return 0 } eof { } } if ![check_exit_status kinit] { fail "kinit anonymous" } pass "kinit anonymous" return 1 } proc kinit_kt { name keytab standalone testname } { global REALMNAME global KINIT global spawn_id # Use kinit to get a ticket. # # For now always get forwardable tickets. Later when we need to make # tests that distiguish between forwardable tickets and otherwise # we should but another option to this proc. --proven # spawn $KINIT -5 -f -k -t $keytab $name@$REALMNAME expect { timeout { fail "kinit $testname" return 0 } eof { } } if ![check_exit_status "kinit $testname"] { return 0 } if {$standalone} { pass "kinit $testname" } return 1 } # List tickets. Requires client and server names, and test name. # Checks that klist exist status is zero. # Records pass or fail, and returns 1 or 0. proc do_klist { myname servname testname } { global KLIST global tmppwd spawn $KLIST -5 -e expect { -re "Ticket cache:\[ \]*(.+:)?$tmppwd/tkt.*Default principal:\[ \]*$myname.*$servname\r\n" { verbose "klist started" } timeout { fail $testname return 0 } eof { fail $testname return 0 } } expect eof if ![check_exit_status $testname] { return 0 } pass $testname return 1 } proc do_klist_kt { keytab testname } { global KLIST global tmppwd spawn $KLIST -5 -e -k $keytab expect { -re "Keytab name:\[ \]*(.+:)?.*KVNO Principal\r\n---- -*\r\n" { verbose "klist started" } timeout { fail $testname return 0 } eof { fail $testname return 0 } } set more 1 while {$more} { expect { -re { *[0-9][0-9]* *[a-zA-Z/@.-]* \([/a-zA-Z 0-9-]*\) *\r\n} { verbose -log "key: $expect_out(buffer)" } eof { set more 0 } } } if ![check_exit_status $testname] { return 0 } pass $testname return 1 } proc do_klist_err { testname } { global KLIST global spawn_id spawn $KLIST -5 # Might say "credentials cache" or "credentials cache file". expect { -re "klist: No credentials cache found.*\r\n" { verbose "klist started" } timeout { fail $testname return 0 } eof { fail $testname return 0 } } # We can't use check_exit_status, because we expect an exit status # of 1. catch "expect eof" set status_list [wait -i $spawn_id] verbose "wait -i $spawn_id returned $status_list ($testname)" if { [lindex $status_list 2] != 0 } { fail "$testname (bad exit status) $status_list" return 0 } else { if { [lindex $status_list 3] != 1 } { fail "$testname (bad exit status) $status_list" return 0 } else { pass $testname } } return 1 } proc do_kdestroy { testname } { global KDESTROY global spawn_id spawn $KDESTROY -5 if ![check_exit_status $testname] { fail $testname return 0 } pass $testname return 1 } proc xst { keytab name } { global KADMIN_LOCAL global REALMNAME envstack_push setup_kerberos_env kdc spawn $KADMIN_LOCAL -r $REALMNAME envstack_pop catch expect_after expect_after { -re "(.*)\r\nkadmin.local: " { fail "kadmin.local xst $keytab (unmatched output: $expect_out(1,string)" catch "expect_after" return 0 } timeout { fail "kadmin.local xst $keytab (timeout)" catch "expect_after" return 0 } eof { fail "kadmin.local xst $keytab (eof)" catch "expect_after" return 0 } } expect "kadmin.local: " send "xst -k $keytab $name\r" expect -re "xst -k \[^\r\n\]*\r\n.*Entry for principal .* added to keytab WRFILE:.*\r\nkadmin.local: " send "quit\r" expect eof catch expect_after if ![check_exit_status "kadmin.local $keytab"] { perror "kadmin.local xst $keytab exited abnormally" return 0 } return 1 } # helpful sometimes for debugging the test suite proc export_debug_envvars { } { global env foreach i {KDB5_UTIL KRB5KDC KADMIND KADMIN KADMIN_LOCAL KINIT KTUTIL KLIST KPASSWD REALMNAME GSSCLIENT KPROPLOG} { global $i if [info exists $i] { set env($i) [set $i] } } } proc spawn_xterm { } { export_debug_envvars exec "xterm" } proc spawn_shell { } { export_debug_envvars spawn "sh" exp_interact } krb5-1.16/src/tests/dejagnu/deps0000644000704600001450000000020713211554426016421 0ustar ghudsonlibuuid# # Generated makefile dependencies follow. # $(OUTPRE)t_inetd.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(COM_ERR_DEPS) t_inetd.c krb5-1.16/src/tests/dejagnu/Makefile.in0000644000704600001450000000205513211554426017613 0ustar ghudsonlibuuidmydir=tests$(S)dejagnu BUILDTOP=$(REL)..$(S).. RUNTEST = @RUNTEST@ $(DEJAFLAGS) RUNTESTFLAGS = SRCS=$(srcdir)/t_inetd.c all: t_inetd install: check: check-runtest-@HAVE_RUNTEST@ check-runtest-no: @echo "+++" @echo "+++ WARNING: tests/dejagnu tests not run." @echo "+++ runtest is unavailable." @echo "+++" @echo 'Skipped dejagnu tests: runtest not found' >> $(SKIPTESTS) # Set VALGRIND at run time, that may be changed when running 'make'. check-runtest-yes: t_inetd site.exp $(RUNTEST) --tool krb VALGRIND="$(VALGRIND)" $(RUNTESTFLAGS) t_inetd: t_inetd.o $(KRB5_BASE_DEPLIBS) $(CC_LINK) -o t_inetd t_inetd.o $(KRB5_BASE_LIBS) clean: $(RM) t_inetd t_inetd.o site.exp runenv.vars runenv.vals clean-unix:: $(RM) -rf tmpdir dbg.log krb.log krb.sum runenv.vals: Makefile $(RUN_SETUP); for i in $(RUN_VARS); do \ eval echo "{$$i=\$$$$i}"; done > runenv.vals site.exp: runenv.vals Makefile echo "set runvarlist [list `cat runenv.vals | tr '\n' ' '`]" | \ sed -e 's%=\.%='`pwd`'/.%g' > site.exp echo "set PRIOCNTL_HACK @PRIOCNTL_HACK@" >> site.exp krb5-1.16/src/tests/dejagnu/proxy-certs/0000755000704600001450000000000013211554426020043 5ustar ghudsonlibuuidkrb5-1.16/src/tests/dejagnu/proxy-certs/proxy-ideal.pem0000644000704600001450000000654413211554426023014 0ustar ghudsonlibuuid-----BEGIN RSA PRIVATE KEY----- MIIEpQIBAAKCAQEA1zudnpN8FP7iLn1vgkyTSn/RQxXx1yt6zikHaMrVPjkjXPPU oCFpWS3eeI4aQFoj93L5MwZDmSxOflBAqLwV2AMAacrYnNPJIkHtbYKdVsvw9b4I NTWqV9/DOODO7UowyMppmO35/pUXaLL+AjHjLw1/EhQ3ZYtqfpAMOkf5TnS5GtqZ FlrYgZKE8vTC8BxDKM7FYhWYz7kp/tG3S8O/RTnP7Nd+h1YdpmlHBGfuwIRIJz5x Nw6KIcCy3Q0NNoKnh00WVwLmR+x11BGSkMjiZZkwJ5D0RObSg13QD/itrGoV2gtP zjQgNPfTrjsMvyOWAAFrWVR3QLTxnnmXsqnXvwIDAQABAoIBAQCqvhpeMDXhGgoo Q03wmfrGwPsrMv91aIK1hYrhMPdVs1JAbRYiKh8+pcq07FYa8udRaB4UwkVh/+oM /nEs6niRsl/jjQ2l68TFrnNByroynvr6l9Q/EeGecF6Ygo7lY1OsFhcLQM5vjarS XhxvdU/6hcRmfS8tGRpUaMWqfmpiN3YgJcgt8SoYhiwAYDTMJjNyWC61lO7IqNVR 4kntiM24sfAu1sdZynX8Gp2GrpNChapEuhilQ8RayjuStEYr2abcSIjfZFHQXN7o TnjL+AQUzc/ZTXDGnIe9ZzZeFz8UCueeoN6KPxfrq9UUWRL6qt7gOIMdhYR6lFxt 6pj6kLhxAoGBAO5DTnTKDfCMY2/AsTzCJvMGSY0bT1rsdDxrpqjrbUSeMHV3s5Lm vEPnnm+05FD/vi99+HZjHXAZFkhA3ubij2qWFPBnQ5YUoh17IW/Ae4bzY2uXikgL tLZ+R+OrcGYQQlvPn//PLsxbfdk5vraqzm08kIX0T4o4Iz8ST5NFJ8hVAoGBAOdB ahXr14563Cjeu0pSQ1nXoz3IXdnDwePXasYhxQHl8Ayk8qZS5pt7r07H3dqq6pvn e09gZINJe47B9UhkR3H5bPyz/kujKS4zqo3Zlbryzm3V0BWqjNj+j8E2YuQKNQr+ c480jn2FzwW66w0i3n4U4KUn1w2/iq5AnVzyNkPDAoGAWLYEsyU79XE/4K79DqM3 P0r6/afKbw8U5B4syj4FzAOeBU6RNMPmGt5VNkBCtgnSdPpRFTsoDcG5cyN8GrkG Lug8WZoJJwr9pT5gH6yqEX/zZ27f1J1PJpd0CsedLNMm8eonJ2arhPkXrVZ7tKV6 AGAJa2agatUmAmi96hZYjpUCgYEA32abJEgsedEIhFb/GYI03ELryRCaUXfCA+gj lvoihn3qE1z5qGGns4adyX5dPRQmBqxtvDXDg+zl9vg6i0+MkXdCqTD8tXcOnjp9 RgFvmyVa9FI8beHPpQTuPNncWK3fpho/6pT8Hhi48LEsxwjrZWOnzQSaxQZH46Q6 IQNAFt8CgYEAkflxXvA2/2naix+riaBzv5EVJB7ilbfWiWtq2LEAtwrQ5XNFjrtK g45jKrZ/ezAzTfPa5Dwn4xcImd0MIavnJhDu2ATxMGB0GATLlDH2HZvU7UwKLpTW 6Hlol4yRcX4GSEOxJ2ZpWYNIOYH0yDf1qLJXs1j8Fi3zWRe+V1kff4w= -----END RSA PRIVATE KEY----- -----BEGIN CERTIFICATE----- MIIE3TCCA8WgAwIBAgIBBTANBgkqhkiG9w0BAQUFADCBmTELMAkGA1UEBhMCVVMx FjAUBgNVBAgTDU1hc3NhY2h1c2V0dHMxEjAQBgNVBAcTCUNhbWJyaWRnZTEMMAoG A1UEChMDTUlUMSIwIAYDVQQLExlJbnNlY3VyZSBLZXJiZXJvcyB0ZXN0IENBMSww KgYDVQQDFCN0ZXN0IHN1aXRlIENBOyBkbyBub3QgdXNlIG90aGVyd2lzZTAeFw0x NDA1MDIxOTA2MDlaFw0yNTA0MTQxOTA2MDlaME8xCzAJBgNVBAYTAlVTMRYwFAYD VQQIEw1NYXNzYWNodXNldHRzMRQwEgYDVQQKEwtLUkJURVNULkNPTTESMBAGA1UE AxMJbG9jYWxob3N0MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA1zud npN8FP7iLn1vgkyTSn/RQxXx1yt6zikHaMrVPjkjXPPUoCFpWS3eeI4aQFoj93L5 MwZDmSxOflBAqLwV2AMAacrYnNPJIkHtbYKdVsvw9b4INTWqV9/DOODO7UowyMpp mO35/pUXaLL+AjHjLw1/EhQ3ZYtqfpAMOkf5TnS5GtqZFlrYgZKE8vTC8BxDKM7F YhWYz7kp/tG3S8O/RTnP7Nd+h1YdpmlHBGfuwIRIJz5xNw6KIcCy3Q0NNoKnh00W VwLmR+x11BGSkMjiZZkwJ5D0RObSg13QD/itrGoV2gtPzjQgNPfTrjsMvyOWAAFr WVR3QLTxnnmXsqnXvwIDAQABo4IBdzCCAXMwHQYDVR0OBBYEFHO5+DSYzq8rvQhU ldyvn0y4AqlHMIHGBgNVHSMEgb4wgbuAFHO5+DSYzq8rvQhUldyvn0y4AqlHoYGf pIGcMIGZMQswCQYDVQQGEwJVUzEWMBQGA1UECBMNTWFzc2FjaHVzZXR0czESMBAG A1UEBxMJQ2FtYnJpZGdlMQwwCgYDVQQKEwNNSVQxIjAgBgNVBAsTGUluc2VjdXJl IEtlcmJlcm9zIHRlc3QgQ0ExLDAqBgNVBAMUI3Rlc3Qgc3VpdGUgQ0E7IGRvIG5v dCB1c2Ugb3RoZXJ3aXNlggEBMAsGA1UdDwQEAwID6DAMBgNVHRMBAf8EAjAAMFkG A1UdEQRSMFCCFnByb3h5xaB1YmplY3TDhGx0w5FhbWWCE3Byb3h5U3ViamVjdEFs dE5hbWWHBH8AAAGHEAAAAAAAAAAAAAAAAAAAAAGCCWxvY2FsaG9zdDATBgNVHSUE DDAKBggrBgEFBQcDATANBgkqhkiG9w0BAQUFAAOCAQEAfTctgFjQSaevBi64q7yh GNsK3PqeNEALZz4pSXRbOwm0E4RpYIS7uqg1C4zJ5Zbd4V/dOX7q+T/iBS7gErzS rj21jH3Ggc92TmXzcFxMDCxLV0hO8xFkqg3P4sslJESOHxvEMTTf5s893yUb8vJ/ DCvZXXRoRwPot9MFozkmcQcaTNunREWFvn4i4JXcMCSAfWTd+/VkpVsy69u3tj68 7G2/K5nalvZikutEC+DyfyBuvDAoxIYzCi3VtQxCalW28Q5hzWV21QsvKTP5QBsh RaU2r0O58lZPPvrOrtWQBCudUgsnoraVLrjJshEQ4z/ZA9fVtX2ndCSIoyWpWk01 gQ== -----END CERTIFICATE----- krb5-1.16/src/tests/dejagnu/proxy-certs/make-certs.sh0000755000704600001450000000715513211554426022445 0ustar ghudsonlibuuid#!/bin/sh -e PWD=`pwd` NAMETYPE=1 KEYSIZE=2048 DAYS=4000 REALM=KRBTEST.COM TLS_SERVER_EKU=1.3.6.1.5.5.7.3.1 PROXY_EKU_LIST=$TLS_SERVER_EKU cat > openssl.cnf << EOF [req] prompt = no distinguished_name = \$ENV::SUBJECT [ca] default_ca = test_ca [test_ca] new_certs_dir = $PWD serial = $PWD/ca.srl database = $PWD/ca.db certificate = $PWD/ca.pem private_key = $PWD/privkey.pem default_days = $DAYS x509_extensions = exts_proxy policy = proxyname default_md = sha1 unique_subject = no email_in_dn = no [signer] CN = test CA certificate C = US ST = Massachusetts L = Cambridge O = MIT OU = Insecure Kerberos test CA CN = test suite CA; do not use otherwise [proxy] C = US ST = Massachusetts O = KRBTEST.COM CN = PROXYinSubject [localhost] C = US ST = Massachusetts O = KRBTEST.COM CN = localhost [proxyname] C = supplied ST = supplied O = supplied CN = supplied [exts_ca] subjectKeyIdentifier = hash authorityKeyIdentifier = keyid:always,issuer:always keyUsage = nonRepudiation,digitalSignature,keyEncipherment,dataEncipherment,keyAgreement,keyCertSign,cRLSign basicConstraints = critical,CA:TRUE [exts_proxy] subjectKeyIdentifier = hash authorityKeyIdentifier = keyid:always,issuer:always keyUsage = nonRepudiation,digitalSignature,keyEncipherment,keyAgreement basicConstraints = critical,CA:FALSE subjectAltName = DNS:proxyŠubjectÄltÑame,DNS:proxySubjectAltName,IP:127.0.0.1,IP:::1,DNS:localhost extendedKeyUsage = $PROXY_EKU_LIST [exts_proxy_no_san] subjectKeyIdentifier = hash authorityKeyIdentifier = keyid:always,issuer:always keyUsage = nonRepudiation,digitalSignature,keyEncipherment,keyAgreement basicConstraints = critical,CA:FALSE extendedKeyUsage = $PROXY_EKU_LIST EOF # Generate a private key. openssl genrsa $KEYSIZE -nodes > privkey.pem # Generate a "CA" certificate. SUBJECT=signer openssl req -config openssl.cnf -new -x509 -extensions exts_ca \ -set_serial 1 -days $DAYS -key privkey.pem -out ca.pem # Generate proxy certificate signing requests. SUBJECT=proxy openssl req -config openssl.cnf -new -key privkey.pem \ -out proxy.csr SUBJECT=localhost openssl req -config openssl.cnf -new -key privkey.pem \ -out localhost.csr # Issue the certificate with the right name in a subjectAltName. echo 02 > ca.srl cat /dev/null > ca.db SUBJECT=proxy openssl ca -config openssl.cnf -extensions exts_proxy \ -batch -days $DAYS -notext -out tmp.pem -in proxy.csr cat privkey.pem tmp.pem > proxy-san.pem # Issue a certificate that only has the name in the subject field SUBJECT=proxy openssl ca -config openssl.cnf -extensions exts_proxy_no_san \ -batch -days $DAYS -notext -out tmp.pem -in localhost.csr cat privkey.pem tmp.pem > proxy-subject.pem # Issue a certificate that doesn't include any matching name values. SUBJECT=proxy openssl ca -config openssl.cnf -extensions exts_proxy_no_san \ -batch -days $DAYS -notext -out tmp.pem -in proxy.csr cat privkey.pem tmp.pem > proxy-no-match.pem # Issue a certificate that contains all matching name values. SUBJECT=proxy openssl ca -config openssl.cnf -extensions exts_proxy \ -batch -days $DAYS -notext -out tmp.pem -in localhost.csr cat privkey.pem tmp.pem > proxy-ideal.pem # Corrupt the signature on the certificate. SUBJECT=proxy openssl x509 -outform der -in proxy-ideal.pem -out bad.der length=`od -Ad bad.der | tail -n 1 | awk '{print $1}'` dd if=/dev/zero bs=1 of=bad.der count=16 seek=`expr $length - 16` SUBJECT=proxy openssl x509 -inform der -in bad.der -out tmp.pem cat privkey.pem tmp.pem > proxy-badsig.pem # Clean up. rm -f openssl.cnf proxy.csr localhost.csr privkey.pem ca.db ca.db.old ca.srl ca.srl.old ca.db.attr ca.db.attr.old 02.pem 03.pem 04.pem 05.pem tmp.pem bad.der krb5-1.16/src/tests/dejagnu/proxy-certs/ca.pem0000644000704600001450000000324413211554426021134 0ustar ghudsonlibuuid-----BEGIN CERTIFICATE----- MIIEuzCCA6OgAwIBAgIBATANBgkqhkiG9w0BAQUFADCBmTELMAkGA1UEBhMCVVMx FjAUBgNVBAgTDU1hc3NhY2h1c2V0dHMxEjAQBgNVBAcTCUNhbWJyaWRnZTEMMAoG A1UEChMDTUlUMSIwIAYDVQQLExlJbnNlY3VyZSBLZXJiZXJvcyB0ZXN0IENBMSww KgYDVQQDFCN0ZXN0IHN1aXRlIENBOyBkbyBub3QgdXNlIG90aGVyd2lzZTAeFw0x NDA1MDIxOTA2MDhaFw0yNTA0MTQxOTA2MDhaMIGZMQswCQYDVQQGEwJVUzEWMBQG A1UECBMNTWFzc2FjaHVzZXR0czESMBAGA1UEBxMJQ2FtYnJpZGdlMQwwCgYDVQQK EwNNSVQxIjAgBgNVBAsTGUluc2VjdXJlIEtlcmJlcm9zIHRlc3QgQ0ExLDAqBgNV BAMUI3Rlc3Qgc3VpdGUgQ0E7IGRvIG5vdCB1c2Ugb3RoZXJ3aXNlMIIBIjANBgkq hkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA1zudnpN8FP7iLn1vgkyTSn/RQxXx1yt6 zikHaMrVPjkjXPPUoCFpWS3eeI4aQFoj93L5MwZDmSxOflBAqLwV2AMAacrYnNPJ IkHtbYKdVsvw9b4INTWqV9/DOODO7UowyMppmO35/pUXaLL+AjHjLw1/EhQ3ZYtq fpAMOkf5TnS5GtqZFlrYgZKE8vTC8BxDKM7FYhWYz7kp/tG3S8O/RTnP7Nd+h1Yd pmlHBGfuwIRIJz5xNw6KIcCy3Q0NNoKnh00WVwLmR+x11BGSkMjiZZkwJ5D0RObS g13QD/itrGoV2gtPzjQgNPfTrjsMvyOWAAFrWVR3QLTxnnmXsqnXvwIDAQABo4IB CjCCAQYwHQYDVR0OBBYEFHO5+DSYzq8rvQhUldyvn0y4AqlHMIHGBgNVHSMEgb4w gbuAFHO5+DSYzq8rvQhUldyvn0y4AqlHoYGfpIGcMIGZMQswCQYDVQQGEwJVUzEW MBQGA1UECBMNTWFzc2FjaHVzZXR0czESMBAGA1UEBxMJQ2FtYnJpZGdlMQwwCgYD VQQKEwNNSVQxIjAgBgNVBAsTGUluc2VjdXJlIEtlcmJlcm9zIHRlc3QgQ0ExLDAq BgNVBAMUI3Rlc3Qgc3VpdGUgQ0E7IGRvIG5vdCB1c2Ugb3RoZXJ3aXNlggEBMAsG A1UdDwQEAwIB/jAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBBQUAA4IBAQAM Mf4ptC6WoQBH3GoTfgBL0WlIeYeSFmLO7IaSjpK0FV6F/yF7iPFSXcpmu23m6USY LRSxnAvxFTi+h1S5Za9O2Pjq88R9nHmesg4v8HJqOw4HpkDowYo2lumjIMfAutyR MQUOujYJW1WyZ2PidN5M1exDeMgQN9nVjUCx/WKD9fnzOjOOR1Sc8Us2KpoyccIi A+ABHubCvSO3cln0Sp7qjkssJScZtouzPu8FYiroTIR+1oSIKTpJiik1EptlsTea L6fHTMHspFhZaiUJFHWTBAgn/dT+UkFntHdHGI6HWBThFVW05hKoarBA7N25W7FN AHyfC0lKds4qFiBQkpdi -----END CERTIFICATE----- krb5-1.16/src/tests/dejagnu/proxy-certs/proxy-subject.pem0000644000704600001450000000634613211554426023375 0ustar ghudsonlibuuid-----BEGIN RSA PRIVATE KEY----- MIIEpQIBAAKCAQEA1zudnpN8FP7iLn1vgkyTSn/RQxXx1yt6zikHaMrVPjkjXPPU oCFpWS3eeI4aQFoj93L5MwZDmSxOflBAqLwV2AMAacrYnNPJIkHtbYKdVsvw9b4I NTWqV9/DOODO7UowyMppmO35/pUXaLL+AjHjLw1/EhQ3ZYtqfpAMOkf5TnS5GtqZ FlrYgZKE8vTC8BxDKM7FYhWYz7kp/tG3S8O/RTnP7Nd+h1YdpmlHBGfuwIRIJz5x Nw6KIcCy3Q0NNoKnh00WVwLmR+x11BGSkMjiZZkwJ5D0RObSg13QD/itrGoV2gtP zjQgNPfTrjsMvyOWAAFrWVR3QLTxnnmXsqnXvwIDAQABAoIBAQCqvhpeMDXhGgoo Q03wmfrGwPsrMv91aIK1hYrhMPdVs1JAbRYiKh8+pcq07FYa8udRaB4UwkVh/+oM /nEs6niRsl/jjQ2l68TFrnNByroynvr6l9Q/EeGecF6Ygo7lY1OsFhcLQM5vjarS XhxvdU/6hcRmfS8tGRpUaMWqfmpiN3YgJcgt8SoYhiwAYDTMJjNyWC61lO7IqNVR 4kntiM24sfAu1sdZynX8Gp2GrpNChapEuhilQ8RayjuStEYr2abcSIjfZFHQXN7o TnjL+AQUzc/ZTXDGnIe9ZzZeFz8UCueeoN6KPxfrq9UUWRL6qt7gOIMdhYR6lFxt 6pj6kLhxAoGBAO5DTnTKDfCMY2/AsTzCJvMGSY0bT1rsdDxrpqjrbUSeMHV3s5Lm vEPnnm+05FD/vi99+HZjHXAZFkhA3ubij2qWFPBnQ5YUoh17IW/Ae4bzY2uXikgL tLZ+R+OrcGYQQlvPn//PLsxbfdk5vraqzm08kIX0T4o4Iz8ST5NFJ8hVAoGBAOdB ahXr14563Cjeu0pSQ1nXoz3IXdnDwePXasYhxQHl8Ayk8qZS5pt7r07H3dqq6pvn e09gZINJe47B9UhkR3H5bPyz/kujKS4zqo3Zlbryzm3V0BWqjNj+j8E2YuQKNQr+ c480jn2FzwW66w0i3n4U4KUn1w2/iq5AnVzyNkPDAoGAWLYEsyU79XE/4K79DqM3 P0r6/afKbw8U5B4syj4FzAOeBU6RNMPmGt5VNkBCtgnSdPpRFTsoDcG5cyN8GrkG Lug8WZoJJwr9pT5gH6yqEX/zZ27f1J1PJpd0CsedLNMm8eonJ2arhPkXrVZ7tKV6 AGAJa2agatUmAmi96hZYjpUCgYEA32abJEgsedEIhFb/GYI03ELryRCaUXfCA+gj lvoihn3qE1z5qGGns4adyX5dPRQmBqxtvDXDg+zl9vg6i0+MkXdCqTD8tXcOnjp9 RgFvmyVa9FI8beHPpQTuPNncWK3fpho/6pT8Hhi48LEsxwjrZWOnzQSaxQZH46Q6 IQNAFt8CgYEAkflxXvA2/2naix+riaBzv5EVJB7ilbfWiWtq2LEAtwrQ5XNFjrtK g45jKrZ/ezAzTfPa5Dwn4xcImd0MIavnJhDu2ATxMGB0GATLlDH2HZvU7UwKLpTW 6Hlol4yRcX4GSEOxJ2ZpWYNIOYH0yDf1qLJXs1j8Fi3zWRe+V1kff4w= -----END RSA PRIVATE KEY----- -----BEGIN CERTIFICATE----- MIIEgjCCA2qgAwIBAgIBAzANBgkqhkiG9w0BAQUFADCBmTELMAkGA1UEBhMCVVMx FjAUBgNVBAgTDU1hc3NhY2h1c2V0dHMxEjAQBgNVBAcTCUNhbWJyaWRnZTEMMAoG A1UEChMDTUlUMSIwIAYDVQQLExlJbnNlY3VyZSBLZXJiZXJvcyB0ZXN0IENBMSww KgYDVQQDFCN0ZXN0IHN1aXRlIENBOyBkbyBub3QgdXNlIG90aGVyd2lzZTAeFw0x NDA1MDIxOTA2MDhaFw0yNTA0MTQxOTA2MDhaME8xCzAJBgNVBAYTAlVTMRYwFAYD VQQIEw1NYXNzYWNodXNldHRzMRQwEgYDVQQKEwtLUkJURVNULkNPTTESMBAGA1UE AxMJbG9jYWxob3N0MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA1zud npN8FP7iLn1vgkyTSn/RQxXx1yt6zikHaMrVPjkjXPPUoCFpWS3eeI4aQFoj93L5 MwZDmSxOflBAqLwV2AMAacrYnNPJIkHtbYKdVsvw9b4INTWqV9/DOODO7UowyMpp mO35/pUXaLL+AjHjLw1/EhQ3ZYtqfpAMOkf5TnS5GtqZFlrYgZKE8vTC8BxDKM7F YhWYz7kp/tG3S8O/RTnP7Nd+h1YdpmlHBGfuwIRIJz5xNw6KIcCy3Q0NNoKnh00W VwLmR+x11BGSkMjiZZkwJ5D0RObSg13QD/itrGoV2gtPzjQgNPfTrjsMvyOWAAFr WVR3QLTxnnmXsqnXvwIDAQABo4IBHDCCARgwHQYDVR0OBBYEFHO5+DSYzq8rvQhU ldyvn0y4AqlHMIHGBgNVHSMEgb4wgbuAFHO5+DSYzq8rvQhUldyvn0y4AqlHoYGf pIGcMIGZMQswCQYDVQQGEwJVUzEWMBQGA1UECBMNTWFzc2FjaHVzZXR0czESMBAG A1UEBxMJQ2FtYnJpZGdlMQwwCgYDVQQKEwNNSVQxIjAgBgNVBAsTGUluc2VjdXJl IEtlcmJlcm9zIHRlc3QgQ0ExLDAqBgNVBAMUI3Rlc3Qgc3VpdGUgQ0E7IGRvIG5v dCB1c2Ugb3RoZXJ3aXNlggEBMAsGA1UdDwQEAwID6DAMBgNVHRMBAf8EAjAAMBMG A1UdJQQMMAoGCCsGAQUFBwMBMA0GCSqGSIb3DQEBBQUAA4IBAQCzGPT+QOrl9mbJ nsGlPlLUOF+PYz0a/9V/iznlofxwCXiRi2ryMpLFbjLeOvjLJ3UzyNKtmEeudTBM yfR4i8tb9WA7Oh0BjK1+kD4688bAUXiIDhueKBjonmPvMd9kq3MDd4vDLkcZk6R4 4IcbdwhzSBmnJH8ha2J82XShPpRq5CZNR9+vTyFwGdGWdPDjTMiXoXAmpRemcEgO iO4Gxvcrg/Z06Ys3eLze7QHNMAEwXhC4rUR34j5I2zgU7CEhff3AktLmnKVa8go8 4BJT/n3XGB+3gdAEihQmgCEZetHH+YxAR0Ppn3ty7fpAlOnbRJqpeu6TMN8x/lL8 c6JtDWRG -----END CERTIFICATE----- krb5-1.16/src/tests/dejagnu/proxy-certs/proxy-badsig.pem0000644000704600001450000000654413211554426023167 0ustar ghudsonlibuuid-----BEGIN RSA PRIVATE KEY----- MIIEpQIBAAKCAQEA1zudnpN8FP7iLn1vgkyTSn/RQxXx1yt6zikHaMrVPjkjXPPU oCFpWS3eeI4aQFoj93L5MwZDmSxOflBAqLwV2AMAacrYnNPJIkHtbYKdVsvw9b4I NTWqV9/DOODO7UowyMppmO35/pUXaLL+AjHjLw1/EhQ3ZYtqfpAMOkf5TnS5GtqZ FlrYgZKE8vTC8BxDKM7FYhWYz7kp/tG3S8O/RTnP7Nd+h1YdpmlHBGfuwIRIJz5x Nw6KIcCy3Q0NNoKnh00WVwLmR+x11BGSkMjiZZkwJ5D0RObSg13QD/itrGoV2gtP zjQgNPfTrjsMvyOWAAFrWVR3QLTxnnmXsqnXvwIDAQABAoIBAQCqvhpeMDXhGgoo Q03wmfrGwPsrMv91aIK1hYrhMPdVs1JAbRYiKh8+pcq07FYa8udRaB4UwkVh/+oM /nEs6niRsl/jjQ2l68TFrnNByroynvr6l9Q/EeGecF6Ygo7lY1OsFhcLQM5vjarS XhxvdU/6hcRmfS8tGRpUaMWqfmpiN3YgJcgt8SoYhiwAYDTMJjNyWC61lO7IqNVR 4kntiM24sfAu1sdZynX8Gp2GrpNChapEuhilQ8RayjuStEYr2abcSIjfZFHQXN7o TnjL+AQUzc/ZTXDGnIe9ZzZeFz8UCueeoN6KPxfrq9UUWRL6qt7gOIMdhYR6lFxt 6pj6kLhxAoGBAO5DTnTKDfCMY2/AsTzCJvMGSY0bT1rsdDxrpqjrbUSeMHV3s5Lm vEPnnm+05FD/vi99+HZjHXAZFkhA3ubij2qWFPBnQ5YUoh17IW/Ae4bzY2uXikgL tLZ+R+OrcGYQQlvPn//PLsxbfdk5vraqzm08kIX0T4o4Iz8ST5NFJ8hVAoGBAOdB ahXr14563Cjeu0pSQ1nXoz3IXdnDwePXasYhxQHl8Ayk8qZS5pt7r07H3dqq6pvn e09gZINJe47B9UhkR3H5bPyz/kujKS4zqo3Zlbryzm3V0BWqjNj+j8E2YuQKNQr+ c480jn2FzwW66w0i3n4U4KUn1w2/iq5AnVzyNkPDAoGAWLYEsyU79XE/4K79DqM3 P0r6/afKbw8U5B4syj4FzAOeBU6RNMPmGt5VNkBCtgnSdPpRFTsoDcG5cyN8GrkG Lug8WZoJJwr9pT5gH6yqEX/zZ27f1J1PJpd0CsedLNMm8eonJ2arhPkXrVZ7tKV6 AGAJa2agatUmAmi96hZYjpUCgYEA32abJEgsedEIhFb/GYI03ELryRCaUXfCA+gj lvoihn3qE1z5qGGns4adyX5dPRQmBqxtvDXDg+zl9vg6i0+MkXdCqTD8tXcOnjp9 RgFvmyVa9FI8beHPpQTuPNncWK3fpho/6pT8Hhi48LEsxwjrZWOnzQSaxQZH46Q6 IQNAFt8CgYEAkflxXvA2/2naix+riaBzv5EVJB7ilbfWiWtq2LEAtwrQ5XNFjrtK g45jKrZ/ezAzTfPa5Dwn4xcImd0MIavnJhDu2ATxMGB0GATLlDH2HZvU7UwKLpTW 6Hlol4yRcX4GSEOxJ2ZpWYNIOYH0yDf1qLJXs1j8Fi3zWRe+V1kff4w= -----END RSA PRIVATE KEY----- -----BEGIN CERTIFICATE----- MIIE3TCCA8WgAwIBAgIBBTANBgkqhkiG9w0BAQUFADCBmTELMAkGA1UEBhMCVVMx FjAUBgNVBAgTDU1hc3NhY2h1c2V0dHMxEjAQBgNVBAcTCUNhbWJyaWRnZTEMMAoG A1UEChMDTUlUMSIwIAYDVQQLExlJbnNlY3VyZSBLZXJiZXJvcyB0ZXN0IENBMSww KgYDVQQDFCN0ZXN0IHN1aXRlIENBOyBkbyBub3QgdXNlIG90aGVyd2lzZTAeFw0x NDA1MDIxOTA2MDlaFw0yNTA0MTQxOTA2MDlaME8xCzAJBgNVBAYTAlVTMRYwFAYD VQQIEw1NYXNzYWNodXNldHRzMRQwEgYDVQQKEwtLUkJURVNULkNPTTESMBAGA1UE AxMJbG9jYWxob3N0MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA1zud npN8FP7iLn1vgkyTSn/RQxXx1yt6zikHaMrVPjkjXPPUoCFpWS3eeI4aQFoj93L5 MwZDmSxOflBAqLwV2AMAacrYnNPJIkHtbYKdVsvw9b4INTWqV9/DOODO7UowyMpp mO35/pUXaLL+AjHjLw1/EhQ3ZYtqfpAMOkf5TnS5GtqZFlrYgZKE8vTC8BxDKM7F YhWYz7kp/tG3S8O/RTnP7Nd+h1YdpmlHBGfuwIRIJz5xNw6KIcCy3Q0NNoKnh00W VwLmR+x11BGSkMjiZZkwJ5D0RObSg13QD/itrGoV2gtPzjQgNPfTrjsMvyOWAAFr WVR3QLTxnnmXsqnXvwIDAQABo4IBdzCCAXMwHQYDVR0OBBYEFHO5+DSYzq8rvQhU ldyvn0y4AqlHMIHGBgNVHSMEgb4wgbuAFHO5+DSYzq8rvQhUldyvn0y4AqlHoYGf pIGcMIGZMQswCQYDVQQGEwJVUzEWMBQGA1UECBMNTWFzc2FjaHVzZXR0czESMBAG A1UEBxMJQ2FtYnJpZGdlMQwwCgYDVQQKEwNNSVQxIjAgBgNVBAsTGUluc2VjdXJl IEtlcmJlcm9zIHRlc3QgQ0ExLDAqBgNVBAMUI3Rlc3Qgc3VpdGUgQ0E7IGRvIG5v dCB1c2Ugb3RoZXJ3aXNlggEBMAsGA1UdDwQEAwID6DAMBgNVHRMBAf8EAjAAMFkG A1UdEQRSMFCCFnByb3h5xaB1YmplY3TDhGx0w5FhbWWCE3Byb3h5U3ViamVjdEFs dE5hbWWHBH8AAAGHEAAAAAAAAAAAAAAAAAAAAAGCCWxvY2FsaG9zdDATBgNVHSUE DDAKBggrBgEFBQcDATANBgkqhkiG9w0BAQUFAAOCAQEAfTctgFjQSaevBi64q7yh GNsK3PqeNEALZz4pSXRbOwm0E4RpYIS7uqg1C4zJ5Zbd4V/dOX7q+T/iBS7gErzS rj21jH3Ggc92TmXzcFxMDCxLV0hO8xFkqg3P4sslJESOHxvEMTTf5s893yUb8vJ/ DCvZXXRoRwPot9MFozkmcQcaTNunREWFvn4i4JXcMCSAfWTd+/VkpVsy69u3tj68 7G2/K5nalvZikutEC+DyfyBuvDAoxIYzCi3VtQxCalW28Q5hzWV21QsvKTP5QBsh RaU2r0O58lZPPvrOrtWQBCudUgsnoraVLrjJshEQ4z/ZAAAAAAAAAAAAAAAAAAAA AA== -----END CERTIFICATE----- krb5-1.16/src/tests/dejagnu/proxy-certs/proxy-no-match.pem0000644000704600001450000000635613211554426023445 0ustar ghudsonlibuuid-----BEGIN RSA PRIVATE KEY----- MIIEpQIBAAKCAQEA1zudnpN8FP7iLn1vgkyTSn/RQxXx1yt6zikHaMrVPjkjXPPU oCFpWS3eeI4aQFoj93L5MwZDmSxOflBAqLwV2AMAacrYnNPJIkHtbYKdVsvw9b4I NTWqV9/DOODO7UowyMppmO35/pUXaLL+AjHjLw1/EhQ3ZYtqfpAMOkf5TnS5GtqZ FlrYgZKE8vTC8BxDKM7FYhWYz7kp/tG3S8O/RTnP7Nd+h1YdpmlHBGfuwIRIJz5x Nw6KIcCy3Q0NNoKnh00WVwLmR+x11BGSkMjiZZkwJ5D0RObSg13QD/itrGoV2gtP zjQgNPfTrjsMvyOWAAFrWVR3QLTxnnmXsqnXvwIDAQABAoIBAQCqvhpeMDXhGgoo Q03wmfrGwPsrMv91aIK1hYrhMPdVs1JAbRYiKh8+pcq07FYa8udRaB4UwkVh/+oM /nEs6niRsl/jjQ2l68TFrnNByroynvr6l9Q/EeGecF6Ygo7lY1OsFhcLQM5vjarS XhxvdU/6hcRmfS8tGRpUaMWqfmpiN3YgJcgt8SoYhiwAYDTMJjNyWC61lO7IqNVR 4kntiM24sfAu1sdZynX8Gp2GrpNChapEuhilQ8RayjuStEYr2abcSIjfZFHQXN7o TnjL+AQUzc/ZTXDGnIe9ZzZeFz8UCueeoN6KPxfrq9UUWRL6qt7gOIMdhYR6lFxt 6pj6kLhxAoGBAO5DTnTKDfCMY2/AsTzCJvMGSY0bT1rsdDxrpqjrbUSeMHV3s5Lm vEPnnm+05FD/vi99+HZjHXAZFkhA3ubij2qWFPBnQ5YUoh17IW/Ae4bzY2uXikgL tLZ+R+OrcGYQQlvPn//PLsxbfdk5vraqzm08kIX0T4o4Iz8ST5NFJ8hVAoGBAOdB ahXr14563Cjeu0pSQ1nXoz3IXdnDwePXasYhxQHl8Ayk8qZS5pt7r07H3dqq6pvn e09gZINJe47B9UhkR3H5bPyz/kujKS4zqo3Zlbryzm3V0BWqjNj+j8E2YuQKNQr+ c480jn2FzwW66w0i3n4U4KUn1w2/iq5AnVzyNkPDAoGAWLYEsyU79XE/4K79DqM3 P0r6/afKbw8U5B4syj4FzAOeBU6RNMPmGt5VNkBCtgnSdPpRFTsoDcG5cyN8GrkG Lug8WZoJJwr9pT5gH6yqEX/zZ27f1J1PJpd0CsedLNMm8eonJ2arhPkXrVZ7tKV6 AGAJa2agatUmAmi96hZYjpUCgYEA32abJEgsedEIhFb/GYI03ELryRCaUXfCA+gj lvoihn3qE1z5qGGns4adyX5dPRQmBqxtvDXDg+zl9vg6i0+MkXdCqTD8tXcOnjp9 RgFvmyVa9FI8beHPpQTuPNncWK3fpho/6pT8Hhi48LEsxwjrZWOnzQSaxQZH46Q6 IQNAFt8CgYEAkflxXvA2/2naix+riaBzv5EVJB7ilbfWiWtq2LEAtwrQ5XNFjrtK g45jKrZ/ezAzTfPa5Dwn4xcImd0MIavnJhDu2ATxMGB0GATLlDH2HZvU7UwKLpTW 6Hlol4yRcX4GSEOxJ2ZpWYNIOYH0yDf1qLJXs1j8Fi3zWRe+V1kff4w= -----END RSA PRIVATE KEY----- -----BEGIN CERTIFICATE----- MIIEhzCCA2+gAwIBAgIBBDANBgkqhkiG9w0BAQUFADCBmTELMAkGA1UEBhMCVVMx FjAUBgNVBAgTDU1hc3NhY2h1c2V0dHMxEjAQBgNVBAcTCUNhbWJyaWRnZTEMMAoG A1UEChMDTUlUMSIwIAYDVQQLExlJbnNlY3VyZSBLZXJiZXJvcyB0ZXN0IENBMSww KgYDVQQDFCN0ZXN0IHN1aXRlIENBOyBkbyBub3QgdXNlIG90aGVyd2lzZTAeFw0x NDA1MDIxOTA2MDhaFw0yNTA0MTQxOTA2MDhaMFQxCzAJBgNVBAYTAlVTMRYwFAYD VQQIEw1NYXNzYWNodXNldHRzMRQwEgYDVQQKEwtLUkJURVNULkNPTTEXMBUGA1UE AxMOUFJPWFlpblN1YmplY3QwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB AQDXO52ek3wU/uIufW+CTJNKf9FDFfHXK3rOKQdoytU+OSNc89SgIWlZLd54jhpA WiP3cvkzBkOZLE5+UECovBXYAwBpytic08kiQe1tgp1Wy/D1vgg1NapX38M44M7t SjDIymmY7fn+lRdosv4CMeMvDX8SFDdli2p+kAw6R/lOdLka2pkWWtiBkoTy9MLw HEMozsViFZjPuSn+0bdLw79FOc/s136HVh2maUcEZ+7AhEgnPnE3DoohwLLdDQ02 gqeHTRZXAuZH7HXUEZKQyOJlmTAnkPRE5tKDXdAP+K2sahXaC0/ONCA099OuOwy/ I5YAAWtZVHdAtPGeeZeyqde/AgMBAAGjggEcMIIBGDAdBgNVHQ4EFgQUc7n4NJjO ryu9CFSV3K+fTLgCqUcwgcYGA1UdIwSBvjCBu4AUc7n4NJjOryu9CFSV3K+fTLgC qUehgZ+kgZwwgZkxCzAJBgNVBAYTAlVTMRYwFAYDVQQIEw1NYXNzYWNodXNldHRz MRIwEAYDVQQHEwlDYW1icmlkZ2UxDDAKBgNVBAoTA01JVDEiMCAGA1UECxMZSW5z ZWN1cmUgS2VyYmVyb3MgdGVzdCBDQTEsMCoGA1UEAxQjdGVzdCBzdWl0ZSBDQTsg ZG8gbm90IHVzZSBvdGhlcndpc2WCAQEwCwYDVR0PBAQDAgPoMAwGA1UdEwEB/wQC MAAwEwYDVR0lBAwwCgYIKwYBBQUHAwEwDQYJKoZIhvcNAQEFBQADggEBAMsP++r4 vki0mBJg3POpp0i+H6zNMimoYLLtM5NvwXinfFuFQKbwLm8QWuHVifjfCYxMUm+l iL5cS/bq+SUWGDmrlOhsuu4+aYaxgNiEyki5Rol6miSOHbfOhzX8yp0EBPpq08dg SEdrTd/FIl4qgkkb1A4RJYZRErn/fbsyjJN66KIfSOXJuC8XMBf03Vw9f2rdrHJa r5lVGvqa4wjO2MPq9vVK52VFrbU/zuyyCUtggyIOwGLGSY0Axtbci+IHToDBQes+ 6W4WwSUCssWfIZXQDLjFw1oRHnN43fXmX5vsVLi7YvOFHOAa1BDnDtCTZit26xVA Mdic66hR2jHP0TE= -----END CERTIFICATE----- krb5-1.16/src/tests/dejagnu/proxy-certs/proxy-san.pem0000644000704600001450000000655013211554426022514 0ustar ghudsonlibuuid-----BEGIN RSA PRIVATE KEY----- MIIEpQIBAAKCAQEA1zudnpN8FP7iLn1vgkyTSn/RQxXx1yt6zikHaMrVPjkjXPPU oCFpWS3eeI4aQFoj93L5MwZDmSxOflBAqLwV2AMAacrYnNPJIkHtbYKdVsvw9b4I NTWqV9/DOODO7UowyMppmO35/pUXaLL+AjHjLw1/EhQ3ZYtqfpAMOkf5TnS5GtqZ FlrYgZKE8vTC8BxDKM7FYhWYz7kp/tG3S8O/RTnP7Nd+h1YdpmlHBGfuwIRIJz5x Nw6KIcCy3Q0NNoKnh00WVwLmR+x11BGSkMjiZZkwJ5D0RObSg13QD/itrGoV2gtP zjQgNPfTrjsMvyOWAAFrWVR3QLTxnnmXsqnXvwIDAQABAoIBAQCqvhpeMDXhGgoo Q03wmfrGwPsrMv91aIK1hYrhMPdVs1JAbRYiKh8+pcq07FYa8udRaB4UwkVh/+oM /nEs6niRsl/jjQ2l68TFrnNByroynvr6l9Q/EeGecF6Ygo7lY1OsFhcLQM5vjarS XhxvdU/6hcRmfS8tGRpUaMWqfmpiN3YgJcgt8SoYhiwAYDTMJjNyWC61lO7IqNVR 4kntiM24sfAu1sdZynX8Gp2GrpNChapEuhilQ8RayjuStEYr2abcSIjfZFHQXN7o TnjL+AQUzc/ZTXDGnIe9ZzZeFz8UCueeoN6KPxfrq9UUWRL6qt7gOIMdhYR6lFxt 6pj6kLhxAoGBAO5DTnTKDfCMY2/AsTzCJvMGSY0bT1rsdDxrpqjrbUSeMHV3s5Lm vEPnnm+05FD/vi99+HZjHXAZFkhA3ubij2qWFPBnQ5YUoh17IW/Ae4bzY2uXikgL tLZ+R+OrcGYQQlvPn//PLsxbfdk5vraqzm08kIX0T4o4Iz8ST5NFJ8hVAoGBAOdB ahXr14563Cjeu0pSQ1nXoz3IXdnDwePXasYhxQHl8Ayk8qZS5pt7r07H3dqq6pvn e09gZINJe47B9UhkR3H5bPyz/kujKS4zqo3Zlbryzm3V0BWqjNj+j8E2YuQKNQr+ c480jn2FzwW66w0i3n4U4KUn1w2/iq5AnVzyNkPDAoGAWLYEsyU79XE/4K79DqM3 P0r6/afKbw8U5B4syj4FzAOeBU6RNMPmGt5VNkBCtgnSdPpRFTsoDcG5cyN8GrkG Lug8WZoJJwr9pT5gH6yqEX/zZ27f1J1PJpd0CsedLNMm8eonJ2arhPkXrVZ7tKV6 AGAJa2agatUmAmi96hZYjpUCgYEA32abJEgsedEIhFb/GYI03ELryRCaUXfCA+gj lvoihn3qE1z5qGGns4adyX5dPRQmBqxtvDXDg+zl9vg6i0+MkXdCqTD8tXcOnjp9 RgFvmyVa9FI8beHPpQTuPNncWK3fpho/6pT8Hhi48LEsxwjrZWOnzQSaxQZH46Q6 IQNAFt8CgYEAkflxXvA2/2naix+riaBzv5EVJB7ilbfWiWtq2LEAtwrQ5XNFjrtK g45jKrZ/ezAzTfPa5Dwn4xcImd0MIavnJhDu2ATxMGB0GATLlDH2HZvU7UwKLpTW 6Hlol4yRcX4GSEOxJ2ZpWYNIOYH0yDf1qLJXs1j8Fi3zWRe+V1kff4w= -----END RSA PRIVATE KEY----- -----BEGIN CERTIFICATE----- MIIE4jCCA8qgAwIBAgIBAjANBgkqhkiG9w0BAQUFADCBmTELMAkGA1UEBhMCVVMx FjAUBgNVBAgTDU1hc3NhY2h1c2V0dHMxEjAQBgNVBAcTCUNhbWJyaWRnZTEMMAoG A1UEChMDTUlUMSIwIAYDVQQLExlJbnNlY3VyZSBLZXJiZXJvcyB0ZXN0IENBMSww KgYDVQQDFCN0ZXN0IHN1aXRlIENBOyBkbyBub3QgdXNlIG90aGVyd2lzZTAeFw0x NDA1MDIxOTA2MDhaFw0yNTA0MTQxOTA2MDhaMFQxCzAJBgNVBAYTAlVTMRYwFAYD VQQIEw1NYXNzYWNodXNldHRzMRQwEgYDVQQKEwtLUkJURVNULkNPTTEXMBUGA1UE AxMOUFJPWFlpblN1YmplY3QwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB AQDXO52ek3wU/uIufW+CTJNKf9FDFfHXK3rOKQdoytU+OSNc89SgIWlZLd54jhpA WiP3cvkzBkOZLE5+UECovBXYAwBpytic08kiQe1tgp1Wy/D1vgg1NapX38M44M7t SjDIymmY7fn+lRdosv4CMeMvDX8SFDdli2p+kAw6R/lOdLka2pkWWtiBkoTy9MLw HEMozsViFZjPuSn+0bdLw79FOc/s136HVh2maUcEZ+7AhEgnPnE3DoohwLLdDQ02 gqeHTRZXAuZH7HXUEZKQyOJlmTAnkPRE5tKDXdAP+K2sahXaC0/ONCA099OuOwy/ I5YAAWtZVHdAtPGeeZeyqde/AgMBAAGjggF3MIIBczAdBgNVHQ4EFgQUc7n4NJjO ryu9CFSV3K+fTLgCqUcwgcYGA1UdIwSBvjCBu4AUc7n4NJjOryu9CFSV3K+fTLgC qUehgZ+kgZwwgZkxCzAJBgNVBAYTAlVTMRYwFAYDVQQIEw1NYXNzYWNodXNldHRz MRIwEAYDVQQHEwlDYW1icmlkZ2UxDDAKBgNVBAoTA01JVDEiMCAGA1UECxMZSW5z ZWN1cmUgS2VyYmVyb3MgdGVzdCBDQTEsMCoGA1UEAxQjdGVzdCBzdWl0ZSBDQTsg ZG8gbm90IHVzZSBvdGhlcndpc2WCAQEwCwYDVR0PBAQDAgPoMAwGA1UdEwEB/wQC MAAwWQYDVR0RBFIwUIIWcHJveHnFoHViamVjdMOEbHTDkWFtZYITcHJveHlTdWJq ZWN0QWx0TmFtZYcEfwAAAYcQAAAAAAAAAAAAAAAAAAAAAYIJbG9jYWxob3N0MBMG A1UdJQQMMAoGCCsGAQUFBwMBMA0GCSqGSIb3DQEBBQUAA4IBAQAH6AWuyRLzMbKq MUlyg9ZIar8p0Ms0/UEaa6Xm3/cfm6HSujtgcYlDN3M86Z3zWzWdTrOHsRr/YSG3 H3YDhJToKqxcjgho+1xdBPm0xuFsJcypRqGj/mIaJSoa+wC2AdY1EdE+URsh87XC SHYNbxAVo8qBHMjtROm6AKb2YusYqHnkT+U6nc4Pn9UnIzmu4wfoSB+X1vtY24TP AtXNYQEG4BkgSrcsgoL+z/+wtZLU8QFk6JRO7Bedq711Oh/taEasZHjRAmnqC5TB Ab2fnwWuoVZHqz2qydeywXUKrZlctuRVdjE++wOt9xuMPKFGo0PKDw/SymCe61Q8 Nc/d2mhz -----END CERTIFICATE----- krb5-1.16/src/tests/dejagnu/krb-standalone/0000755000704600001450000000000013211554426020450 5ustar ghudsonlibuuidkrb5-1.16/src/tests/dejagnu/krb-standalone/simple.exp0000644000704600001450000001041213211554426022455 0ustar ghudsonlibuuid# Test for the simple clients # This is a DejaGnu test script. # This script tests that krb-safe and krb-priv messages work. # This mostly just calls procedures in test/dejagnu/config/default.exp. if ![info exists KLIST] { set KLIST [findfile $objdir/../../clients/klist/klist] } if ![info exists KDESTROY] { set KDESTROY [findfile $objdir/../../clients/kdestroy/kdestroy] } if ![info exists SIM_SERVER] { set SIM_SERVER [findfile $objdir/../../appl/simple/server/sim_server] } if ![info exists SIM_CLIENT] { set SIM_CLIENT [findfile $objdir/../../appl/simple/client/sim_client] } # Set up the Kerberos files and environment. if {![get_hostname] || ![setup_kerberos_files] || ![setup_kerberos_env]} { return } # Initialize the Kerberos database. The argument tells # setup_kerberos_db that it is being called from here. if ![setup_kerberos_db 0] { return } proc start_sim_server_daemon { } { global spawn_id global sim_server_pid global sim_server_spawn_id global SIM_SERVER global T_INETD global tmppwd global portbase # Start the sim_server spawn $SIM_SERVER -p [expr 8 + $portbase] -S $tmppwd/srvtab set sim_server_pid [exp_pid] set sim_server_spawn_id $spawn_id verbose "sim_server_spawn is $sim_server_spawn_id" 1 expect { "starting" { } eof { perror "sim_server failed to start" } } return 1 } proc stop_sim_server_daemon { } { global sim_server_pid global sim_server_spawn_id if [info exists sim_server_pid] { catch "close -i $sim_server_spawn_id" catch "exec kill $sim_server_pid" wait -i $sim_server_spawn_id unset sim_server_pid } return 1 } proc stop_check_sim_server_daemon { } { global sim_server_spawn_id global sim_server_pid # Check the exit status of sim_server - should exit here set status_list [wait -i $sim_server_spawn_id] verbose "wait -i $sim_server_spawn_id returned $status_list (sim_server)" catch "close -i $sim_server_spawn_id" if { [lindex $status_list 2] != 0 || [lindex $status_list 3] != 0 } { send_log "exit status: $status_list\n" verbose "exit status: $status_list" fail "sim_server" } else { pass "sim_server" } # In either case the server shutdown unset sim_server_pid } proc test_sim_client { msg } { global REALMNAME global SIM_CLIENT global hostname global spawn_id global portbase global sim_server_spawn_id # Test the client spawn $SIM_CLIENT -p [expr 8 + $portbase] $hostname verbose "sim_client_spawn is $spawn_id" 1 expect { "Sent checksummed message: " { verbose "received safe message" } timeout { fail $msg return 0 } eof { fail $msg return 0 } } expect { "Sent encrypted message: " { verbose "received private message" } eof { fail $msg return 0 } } expect { "\r" { } } expect { -i $sim_server_spawn_id "Safe message is: 'hi there!'" { } timeout { fail $msg return 0 } eof { fail $msg return 0 } } expect { -i $sim_server_spawn_id "Decrypted message is: 'hi there!'" { } timeout { fail $msg return 0 } eof { fail $msg return 0 } } if ![check_exit_status "simple"] { return 0 } return 1 } # We are about to start up a couple of daemon processes. We do all # the rest of the tests inside a proc, so that we can easily kill the # processes when the procedure ends. proc doit { } { global hostname global KEY global sim_server_pid global sim_server_spawn_id # Start up the kerberos and kadmind daemons. if ![start_kerberos_daemons 0] { return } # Use kadmin to add an host key. if ![add_random_key sample/$hostname 1] { return } # Use ksrvutil to create a srvtab entry for sample if ![setup_srvtab 1 sample] { return } # Use kinit to get a ticket. if ![kinit krbtest/admin adminpass$KEY 1] { return } if ![start_sim_server_daemon] { return } if ![test_sim_client sim_client] { return } pass "simple - standalone" stop_check_sim_server_daemon return } set status [catch doit msg] stop_sim_server_daemon stop_kerberos_daemons if { $status != 0 } { send_error "ERROR: error in simple.exp\n" send_error "$msg\n" exit 1 } krb5-1.16/src/tests/dejagnu/krb-standalone/tcp.exp0000644000704600001450000000535313211554426021762 0ustar ghudsonlibuuid# Standalone Kerberos test. # This is a DejaGnu test script. # This script tests that the Kerberos tools can talk to each other. # This mostly just calls procedures in testsuite/config/default.exp. # We are about to start up a couple of daemon processes. We do all # the rest of the tests inside a proc, so that we can easily kill the # processes when the procedure ends. proc doit { } { global REALMNAME global KLIST global KDESTROY global KEY global KADMIN_LOCAL global KTUTIL global hostname global tmppwd global spawn_id global supported_enctypes global KRBIV global portbase global mode # Start up the kerberos and kadmind daemons. if ![start_kerberos_daemons 1] { return } # Use kadmin to add an host key. if ![add_random_key host/$hostname 1] { return } # Use ksrvutil to create a srvtab entry. # if ![setup_srvtab 1] { # return # } # Use kinit to get a ticket. if ![kinit krbtest/admin adminpass$KEY 1] { return } # Make sure that klist can see the ticket. if ![do_klist "krbtest/admin@$REALMNAME" "krbtgt/$REALMNAME@$REALMNAME" "klist"] { return } # Destroy the ticket. spawn $KDESTROY -5 if ![check_exit_status "kdestroy"] { return } pass "kdestroy" set response {} set got_response 0 set kdcsock "" catch { send_log "connecting to $hostname [expr 3 + $portbase]\n" set kdcsock [socket $hostname [expr 3 + $portbase]] fconfigure $kdcsock -encoding binary -blocking 0 -buffering none puts -nonewline $kdcsock [binary format H* ffffffff] # XXX sleep 3 set response [read $kdcsock] set got_response 1 } msg if [string length $kdcsock] { catch "close $kdcsock" } if $got_response { # send_log [list sent length -1, got back $response] # send_log "\n" if [string length $response]>10 { pass "too-long TCP request" } else { send_log "response too short\n" fail "too-long TCP request" } } else { send_log "too-long connect/exchange failure: $msg\n" fail "too-long TCP request" } } set status 0 run_once tcp { # Set up the Kerberos files and environment. set mode tcp reset_kerberos_files if {![get_hostname] || ![setup_kerberos_files] || ![setup_kerberos_env]} { set mode udp reset_kerberos_files return } # Reset now, for next time we write the config files. set mode udp # Initialize the Kerberos database. The argument tells # setup_kerberos_db that it is being called from here. if ![setup_kerberos_db 1] { reset_kerberos_files return } set status [catch doit msg] } reset_kerberos_files stop_kerberos_daemons if { $status != 0 } { send_error "ERROR: error in standalone.exp\n" send_error "$msg\n" exit 1 } krb5-1.16/src/tests/dejagnu/krb-standalone/kprop.exp0000644000704600001450000000731213211554426022324 0ustar ghudsonlibuuid# Password-changing Kerberos test. # This is a DejaGnu test script. # We are about to start up a couple of daemon processes. We do all # the rest of the tests inside a proc, so that we can easily kill the # processes when the procedure ends. proc setup_slave {} { global tmppwd hostname REALMNAME file delete $tmppwd/slave-stash $tmppwd/slave-acl file copy -force $tmppwd/stash:foo $tmppwd/slave-stash file copy -force $tmppwd/acl $tmppwd/slave-acl if ![file exists $tmppwd/kpropdacl] { set aclfile [open $tmppwd/kpropd-acl w] puts $aclfile "host/$hostname@$REALMNAME" close $aclfile } file copy -force $tmppwd/adb.lock $tmppwd/slave-adb.lock foreach suffix { {} .kadm5 .kadm5.lock .ok } { file copy -force $tmppwd/kdc-db$suffix $tmppwd/slave-db$suffix } } proc scan_kpropd_output {} { global kpropd_spawn_id kpropd_pid # See if kpropd logged anything. It should exit after processing # one kprop connection. expect { -i $kpropd_spawn_id eof { wait -i $kpropd_spawn_id unset kpropd_spawn_id kpropd_pid } timeout { } -re "Connection from \[a-zA-Z.-\]*" { exp_continue } -re "krb5_recvauth" { exp_continue } -re "authenticated client" { exp_continue } -re "calling kdb5_util to load database\r\n" { exp_continue } -re "Child PID is \[0-9\]*\r\n" { exp_continue } -re "Rejected connection" { fail "kprop (rejected)" } } } proc doit { } { global KLIST KDESTROY global REALMNAME KEY global KADMIN_LOCAL KTUTIL KDB5_UTIL KPROPLOG KPROP kpropd_spawn_id global hostname tmppwd spawn_id timeout global KRBIV supported_enctypes portbase mode ulog des3_krbtgt # Delete any db, ulog files delete_db # Initialize the Kerberos database. The argument tells # setup_kerberos_db that it is being called from here. if ![setup_kerberos_db 0] { return } setup_slave if ![start_kerberos_daemons 0] { return } if ![add_random_key host/$hostname 0] { fail "kprop (host key)" return } if ![setup_srvtab 0] { fail "kprop (srvtab)" return } # Get kprop server up and running. envstack_push setup_kerberos_env slave start_kpropd envstack_pop # Use kadmin to add a key. if ![add_kerberos_key wakawaka 0] { return } # Dump master database. envstack_push setup_kerberos_env kdc spawn $KDB5_UTIL dump $tmppwd/slave_datatrans expect eof if ![check_exit_status "kprop (kdb5_util dump)"] { return } # Just in case kpropd is a little slow in starting up... sleep 1 # Try a propagation. spawn $KPROP -f $tmppwd/slave_datatrans -P [expr 10 + $portbase] -s $tmppwd/srvtab $hostname expect eof set kprop_exit [check_exit_status "kprop (exit status)"] # log output for debugging scan_kpropd_output if !$kprop_exit { return } # Examine new database. setup_kerberos_env slave spawn $KADMIN_LOCAL -r $REALMNAME -q listprincs expect { wakawaka@ { expect eof } eof { fail "kprop (updated slave data)" return } timeout { fail "kprop (examining new db)" return } } pass "kprop" } run_once kprop { catch "unset kpropd_pid" catch "unset kpropd_spawn_id" # Set up the Kerberos files and environment. if {![get_hostname] || ![setup_kerberos_files] || ![setup_kerberos_env]} { return } set status [catch doit msg] stop_kerberos_daemons # if kpropd is running, kill it if [info exists kpropd_pid] { catch { exec kill $kpropd_pid expect -i $kpropd_spawn_id eof wait -i $kpropd_spawn_id unset kpropd_pid kpropd_spawn_id } } delete_db if { $status != 0 } { send_error "ERROR: error in kprop.exp\n" send_error "$msg\n" exit 1 } } krb5-1.16/src/tests/dejagnu/krb-standalone/princexpire.exp0000644000704600001450000000407513211554426023524 0ustar ghudsonlibuuidproc doit { } { global REALMNAME global KLIST global KINIT global KDESTROY global KEY global KADMIN_LOCAL global KTUTIL global hostname global tmppwd global spawn_id global supported_enctypes global KRBIV global portbase global mode set princ "expiredprinc" # Start up the kerberos and kadmind daemons. if ![start_kerberos_daemons 0] { return 1 } # Use kadmin to add a key. if ![add_kerberos_key $princ 0] { return 1 } setup_kerberos_env kdc set test "kadmin.local modprinc -expire" spawn $KADMIN_LOCAL -q "modprinc -expire \"2 days ago\" $princ" catch expect_after expect { timeout { fail $test } eof { pass $test } } set k_stat [wait -i $spawn_id] verbose "wait -i $spawn_id returned $k_stat ($test)" catch "close -i $spawn_id" set test "kadmin.local -pwexpire" spawn $KADMIN_LOCAL -q "modprinc -pwexpire \"2 days ago\" $princ" catch expect_after expect { timeout { fail $test } eof { pass $test } } set k_stat [wait -i $spawn_id] verbose "wait -i $spawn_id returned $k_stat ($test)" catch "close -i $spawn_id" setup_kerberos_env client spawn $KINIT -5 -k -t /dev/null $princ expect { "entry in database has expired" { pass $test } "Password has expired" { fail "$test (inappropriate password expiration message)" } timeout { expect eof fail "$test (timeout)" return 0 } eof { fail "$test (eof)" return 0 } } expect eof return 0 } run_once princexpire { # Set up the Kerberos files and environment. if {![get_hostname] || ![setup_kerberos_files] || ![setup_kerberos_env]} { return } # Initialize the Kerberos database. The argument tells # setup_kerberos_db that it is not being called from # standalone.exp. if ![setup_kerberos_db 0] { return } set status [catch doit msg] stop_kerberos_daemons if { $status != 0 } { send_error "ERROR: error in pwchange.exp\n" send_error "$msg\n" exit 1 } } krb5-1.16/src/tests/dejagnu/krb-standalone/standalone.exp0000644000704600001450000001434213211554426023322 0ustar ghudsonlibuuid# Standalone Kerberos test. # This is a DejaGnu test script. # This script tests that the Kerberos tools can talk to each other. # This mostly just calls procedures in testsuite/config/default.exp. # Set up the Kerberos files and environment. if {![get_hostname] || ![setup_kerberos_files] || ![setup_kerberos_env]} { return } # Initialize the Kerberos database. The argument tells # setup_kerberos_db that it is being called from here. if ![setup_kerberos_db 1] { return } # We are about to start up a couple of daemon processes. We do all # the rest of the tests inside a proc, so that we can easily kill the # processes when the procedure ends. proc dump_and_reload {} { global KDB5_UTIL global tmppwd set dumpfile $tmppwd/dump-file set dumpokfile $dumpfile.dump_ok set test1name "kdb5_util dump" set test2name "kdb5_util load" if [file exists $dumpfile] { file delete $dumpfile } if [file exists $dumpokfile] { file delete $dumpokfile } spawn $KDB5_UTIL dump $dumpfile expect { -re "..*" { fail $test1name untested $test2name return } timeout { fail $test1name untested $test2name return } eof { } } if ![check_exit_status $test1name] { untested $test2name return } if ![file exists $dumpfile]||![file exists $dumpokfile] { fail $test1name untested $test2name return } pass $test1name spawn $KDB5_UTIL load $dumpfile expect { -re "..*" { fail $test2name return } timeout { fail $test2name return } eof { } } if [check_exit_status $test2name] { pass $test2name } } proc kinit_wrong_pw { name badpass } { global REALMNAME global KINIT global spawn_id # Use kinit to get a ticket. # # For now always get forwardable tickets. Later when we need to make # tests that distiguish between forwardable tickets and otherwise # we should but another option to this proc. --proven # spawn $KINIT -5 -f $name@$REALMNAME expect { "Password for $name@$REALMNAME:" { verbose "kinit started" } timeout { fail "kinit bad pw" return 0 } eof { fail "kinit bad pw" return 0 } } send "$badpass\r" expect { "Password incorrect while getting initial credentials" { } timeout { fail "kinit bad pw" # kill it? } eof { fail "kinit bad pw" return } } expect eof set status_list [wait -i $spawn_id] catch "close -i $spawn_id" verbose -log "exit status: $status_list" if { [lindex $status_list 2] != 0 || [lindex $status_list 3] != 0 } { pass "kinit bad pw" } else { fail "kinit bad pw" } } proc doit { } { global REALMNAME global KLIST global KDESTROY global KEY global KADMIN_LOCAL global KTUTIL global hostname global tmppwd global spawn_id global supported_enctypes global KRBIV global portbase global mode global tmppwd setup_kerberos_env kdc # Start up the kerberos and kadmind daemons. if ![start_kerberos_daemons 1] { return } # Use kadmin to add an host key. if ![add_random_key host/$hostname 1] { return } spawn $KADMIN_LOCAL -q "addpol fred" catch expect_after expect { timeout { fail "kadmin.local addpol fred" } eof { pass "kadmin.local addpol fred" } } set k_stat [wait -i $spawn_id] verbose "wait -i $spawn_id returned $k_stat (kadmin addpol)" catch "close -i $spawn_id" # Use ksrvutil to create a srvtab entry. if ![setup_srvtab 1] { return } # Test dump and load. Continue on, whatever the result. dump_and_reload spawn $KADMIN_LOCAL -q "getpols" expect { fred { pass "kadmin.local getpols" expect eof } timeout { fail "kadmin.local getpols" } eof { fail "kadmin.local getpols" } } set k_stat [wait -i $spawn_id] verbose "wait -i $spawn_id returned $k_stat (kadmin addpol)" catch "close -i $spawn_id" # Test use of wrong password. kinit_wrong_pw krbtest/admin wrongpassword setup_kerberos_env client # Use kinit to get a ticket. if ![kinit krbtest/admin adminpass$KEY 1] { return } if ![kinit_renew krbtest/admin adminpass$KEY 1] { return } # Make sure that klist can see the ticket. if ![do_klist "krbtest/admin@$REALMNAME" "krbtgt/$REALMNAME@$REALMNAME" "klist"] { return } # Get a ticket to later use with FAST if ![kinit krbtest/fast adminpass$KEY 1] { return } # Use fast to get a ticket if ![kinit_fast krbtest/fast adminpass$KEY 1] { return } # Destroy the ticket. spawn $KDESTROY -5 if ![check_exit_status "kdestroy"] { return } pass "kdestroy" # Double check that the ticket was destroyed. if ![do_klist_err "klist after destroy"] { return } if ![add_random_key WELLKNOWN/ANONYMOUS 0] { return } # If we have anonymous then test it if [file exists "$tmppwd/../../../plugins/preauth/pkinit.so" ] { kinit_anonymous "WELLKNOWN/ANONYMOUS" } if ![add_random_key foo/bar 1] { return } set keytab $tmppwd/fookeytab catch "exec rm -f $keytab" modify_principal foo/bar -kvno 252 foreach vno {253 254 255 256 257 258} { xst $tmppwd/fookeytab foo/bar do_klist_kt $tmppwd/fookeytab "klist keytab foo/bar vno $vno" kinit_kt "foo/bar" $tmppwd/fookeytab 1 "kt kvno $vno" do_klist "foo/bar" "krbtgt/$REALMNAME@$REALMNAME" "klist kt foo/bar vno $vno" do_kdestroy "kdestroy foo/bar vno $vno" } catch "exec rm -f $keytab" # Check that kadmin.local can actually read the correct kvno, even # if we don't expect kadmin to be able to. setup_kerberos_env kdc spawn $KADMIN_LOCAL -r $REALMNAME set ok 1 expect_after { timeout { fail "kadmin.local correct high kvno" ; set ok 0 } eof { fail "kadmin.local correct high kvno" ; set ok 0 } } expect "kadmin.local: " send "getprinc foo/bar\r" # exec sleep 10 expect "Key: vno $vno," send "quit\r" expect eof if [check_exit_status "kadmin.local examine foo/bar for high kvno"] { if $ok { pass "kadmin.local correct high kvno" } } } set status [catch doit msg] stop_kerberos_daemons if { $status != 0 } { send_error "ERROR: error in standalone.exp\n" send_error "$msg\n" exit 1 } krb5-1.16/src/tests/dejagnu/krb-standalone/sample.exp0000644000704600001450000001072013211554426022447 0ustar ghudsonlibuuid# Test for the sample clients # This is a DejaGnu test script. # This script tests that sample user-user communication works. # This mostly just calls procedures in test/dejagnu/config/default.exp. if ![info exists KLIST] { set KLIST [findfile $objdir/../../clients/klist/klist] } if ![info exists KDESTROY] { set KDESTROY [findfile $objdir/../../clients/kdestroy/kdestroy] } if ![info exists SSERVER] { set SSERVER [findfile $objdir/../../appl/sample/sserver/sserver] } if ![info exists SCLIENT] { set SCLIENT [findfile $objdir/../../appl/sample/sclient/sclient] } # Set up the Kerberos files and environment. if {![get_hostname] || ![setup_kerberos_files] || ![setup_kerberos_env]} { return } # Initialize the Kerberos database. The argument tells # setup_kerberos_db that it is being called from here. if ![setup_kerberos_db 0] { return } proc start_sserver_daemon { inetd } { global spawn_id global sserver_pid global sserver_spawn_id global SSERVER global T_INETD global tmppwd global portbase # if inetd = 0, then we are running stand-alone if !{$inetd} { # Start the sserver spawn $SSERVER -p [expr 8 + $portbase] -S $tmppwd/srvtab set sserver_pid [exp_pid] set sserver_spawn_id $spawn_id verbose "sserver_spawn is $sserver_spawn_id" 1 # Give sserver some time to start sleep 2 } else { # Start the sserver spawn $T_INETD [expr 8 + $portbase] $SSERVER sserver -S $tmppwd/srvtab set sserver_pid [exp_pid] set sserver_spawn_id $spawn_id verbose "sserver_spawn (t_inetd) is $sserver_spawn_id" 1 expect { -ex "Ready!" { } eof { error "couldn't start t_inetd helper" } } } return 1 } proc stop_sserver_daemon { } { global sserver_pid global sserver_spawn_id if [info exists sserver_pid] { catch "close -i $sserver_spawn_id" catch "exec kill $sserver_pid" wait -i $sserver_spawn_id unset sserver_pid } return 1 } proc stop_check_sserver_daemon { } { global sserver_spawn_id global sserver_pid # Check the exit status of sserver - should exit here set status_list [wait -i $sserver_spawn_id] verbose "wait -i $sserver_spawn_id returned $status_list (sserver)" catch "close -i $sserver_spawn_id" if { [lindex $status_list 2] != 0 || [lindex $status_list 3] != 0 } { send_log "exit status: $status_list\n" verbose "exit status: $status_list" fail "sserver" } else { pass "sserver" } # In either case the server shutdown unset sserver_pid } proc test_sclient { msg } { global REALMNAME global SCLIENT global hostname global spawn_id global portbase # Test the client spawn $SCLIENT $hostname [expr 8 + $portbase] verbose "sclient_spawn is $spawn_id" 1 expect { "sendauth succeeded, reply is:" { verbose "Start proper message" } timeout { fail $msg return 0 } eof { fail $msg return 0 } } expect { "You are krbtest/admin@$REALMNAME\r" { verbose "received valid sample message"} eof { fail $msg return 0 } } # This last expect seems useless, but without it the test hangs on # NETBSD. expect { "\r" { } } if ![check_exit_status "ssample"] { return 0 } return 1 } # We are about to start up a couple of daemon processes. We do all # the rest of the tests inside a proc, so that we can easily kill the # processes when the procedure ends. proc doit { } { global hostname global KEY global sserver_pid global sserver_spawn_id # Start up the kerberos and kadmind daemons. if ![start_kerberos_daemons 0] { return } # Use kadmin to add an host key. if ![add_random_key sample/$hostname 1] { return } # Use ksrvutil to create a srvtab entry for sample if ![setup_srvtab 1 sample] { return } # Use kinit to get a ticket. if ![kinit krbtest/admin adminpass$KEY 1] { return } run_once sample_standalone { if ![start_sserver_daemon 0 ] { return } if ![test_sclient sclient] { return } pass "sample - standalone" stop_check_sserver_daemon } if ![start_sserver_daemon 1 ] { return } if ![test_sclient sclient-inetd] { return } pass "sample - inetd" stop_check_sserver_daemon return } set status [catch doit msg] stop_sserver_daemon stop_kerberos_daemons if { $status != 0 } { send_error "ERROR: error in sample.exp\n" send_error "$msg\n" exit 1 } krb5-1.16/src/tests/dejagnu/krb-standalone/pwchange.exp0000644000704600001450000000570013211554426022764 0ustar ghudsonlibuuid# Password-changing Kerberos test. # This is a DejaGnu test script. # We are about to start up a couple of daemon processes. We do all # the rest of the tests inside a proc, so that we can easily kill the # processes when the procedure ends. proc kinit_expecting_pwchange { name pass newpass } { global REALMNAME global KINIT global spawn_id # Use kinit to get a ticket. # # For now always get forwardable tickets. Later when we need to make # tests that distiguish between forwardable tickets and otherwise # we should but another option to this proc. --proven # spawn $KINIT -5 -f $name@$REALMNAME expect { "Password for $name@$REALMNAME:" { verbose "kinit started" } timeout { fail "kinit" return 0 } eof { fail "kinit" return 0 } } send "$pass\r" expect { "Enter new password: " { } timeout { fail "kinit (new password prompt)" return 0 } eof { fail "kinit (new password prompt)" return 0 } } send "$newpass\r" expect { " again: " { } timeout { fail "kinit (new password prompt2)" return 0 } eof { fail "kinit (new password prompt2)" return 0 } } send "$newpass\r" expect eof if ![check_exit_status kinit] { return 0 } return 1 } proc doit { } { global REALMNAME global KLIST global KDESTROY global KEY global KADMIN_LOCAL global KTUTIL global hostname global tmppwd global spawn_id global supported_enctypes global KRBIV global portbase global mode # Start up the kerberos and kadmind daemons. if ![start_kerberos_daemons 0] { return } # Use kadmin to add a key. if ![add_kerberos_key pwchanger 0] { return } setup_kerberos_env kdc spawn $KADMIN_LOCAL -q "modprinc +needchange pwchanger" catch expect_after expect { timeout { fail "kadmin.local modprinc +needchange" } eof { pass "kadmin.local modprinc +needchange" } } set k_stat [wait -i $spawn_id] verbose "wait -i $spawn_id returned $k_stat (kadmin modprinc +needchange)" catch "close -i $spawn_id" setup_kerberos_env client if ![kinit_expecting_pwchange pwchanger pwchanger$KEY floople] { return } pass "kinit (password change)" if ![kinit pwchanger floople 0] { return } pass "kinit (new password)" # Destroy the ticket. spawn $KDESTROY -5 if ![check_exit_status "kdestroy"] { return } pass "kdestroy" } run_once pwchange { # Set up the Kerberos files and environment. if {![get_hostname] || ![setup_kerberos_files] || ![setup_kerberos_env]} { return } # Initialize the Kerberos database. The argument tells # setup_kerberos_db that it is being called from here. if ![setup_kerberos_db 0] { return } set status [catch doit msg] stop_kerberos_daemons if { $status != 0 } { send_error "ERROR: error in pwchange.exp\n" send_error "$msg\n" exit 1 } } krb5-1.16/src/tests/dejagnu/krb-standalone/pwhist.exp0000644000704600001450000001200513211554426022502 0ustar ghudsonlibuuid# password history tests # one *non-interactive* kadmin.local request proc onerq { rq pname str {flags ""} } { global REALMNAME global KADMIN_LOCAL spawn $KADMIN_LOCAL -r $REALMNAME -q "$rq $flags $pname" expect_after { timeout { verbose "kadmin.local $rq $flags $pname timed out" catch expect_after kill [exp_pid] close expect eof wait return 0 } eof { verbose "kadmin.local $rq $flags $pname got EOF" catch expect_after wait return 0 } } expect $str expect_after expect eof wait return 1 } proc addprinc { pname pw } { global REALMNAME return [onerq addprinc $pname \ "Principal \"$pname@$REALMNAME\" created." "-pw $pw"] } proc delprinc { pname } { global REALMNAME return [onerq delprinc $pname \ "Principal \"$pname@$REALMNAME\" deleted." "-force"] } proc cpw { pname pw } { global REALMNAME return [onerq cpw $pname \ "Password for \"$pname@$REALMNAME\" changed." "-pw $pw"] } proc modprinc { pname flags } { global REALMNAME return [onerq modprinc $pname \ "Principal \"$pname@$REALMNAME\" modified." $flags] } proc addpol { pname } { if ![onerq addpol $pname ""] { return 0 } return [onerq getpol $pname "Policy: $pname"] } proc delpol { pname } { onerq delpol $pname "" -force return [onerq getpol $pname \ "Policy does not exist while retrieving policy \"$pname\"."] } proc modpol { pname flags } { return [onerq modpol $pname "" $flags] } # Mandatory command must return true. # Issues a break in its parent on failure. proc mustrun { cmd } { if ![eval $cmd] { perror "mandatory command failed: $cmd" uplevel break } } # Fail test if command fails. # Issues a break in its parent on failure. proc chkpass { cmd } { upvar test test if ![eval $cmd] { verbose "unexpected failure: $cmd" fail $test uplevel break } } # Fail test if command succeeds. # Issues a break in its parent on failure. proc chkfail { cmd } { upvar test test if [eval $cmd] { verbose "unexpected success: $cmd" fail $test uplevel break } } # wrapper to run command (actually usually sequence of commands) # # If any part of CMD throws an exception, set failall, otherwise pass. # If failall is already true, report unresolved. proc wraptest { test cmd } { upvar failall failall if $failall { unresolved $test return } if [catch $cmd] { set failall 1 } else { pass $test } } run_once pwhist { # Set up the kerberos database. if {![get_hostname] \ || ![setup_kerberos_files] \ || ![setup_kerberos_env kdc] \ || ![setup_kerberos_db 0]} { return } set failall 0 wraptest "nkeys=1, nhist=3" { mustrun { addpol crashpol } mustrun { modpol crashpol "-history 3"} mustrun { addprinc crash 1111 } mustrun { modprinc crash "-policy crashpol" } chkpass { cpw crash 2222 } chkfail { cpw crash 2222 } chkfail { cpw crash 1111 } } verbose {old_keys [ 1111 ->[] ]} # The following will result in reading/writing past array bounds if # add_to_history() is not patched. # # NOTE: A pass from this test does not mean the bug isn't present; # check with Purify, valgrind, etc. wraptest "array bounds ok on nkeys=1, nhist 3->2" { mustrun { modpol crashpol "-history 2" } chkpass { cpw crash 3333 } } verbose {old_keys [ ->2222 ]} wraptest "verify nhist=2" { mustrun { delprinc crash } mustrun { addprinc crash 1111 } mustrun { modprinc crash "-policy crashpol" } chkpass { cpw crash 2222 } chkfail { cpw crash 2222 } chkfail { cpw crash 1111 } } verbose {old_keys [ ->1111 ]} # The following will fail if growing the history array causes an extra # key to be lost due to failure to shift entries. wraptest "grow nhist 2->3" { mustrun { modpol crashpol "-history 3" } chkpass { cpw crash 3333 } chkfail { cpw crash 3333 } chkfail { cpw crash 2222 } chkfail { cpw crash 1111 } } verbose {old_keys [ 2222 ->1111 ]} wraptest "grow nhist 3->4" { mustrun { modpol crashpol "-history 4" } chkfail { cpw crash 3333 } chkfail { cpw crash 2222 } chkfail { cpw crash 1111 } chkpass { cpw crash 4444 } chkfail { cpw crash 3333 } chkfail { cpw crash 2222 } chkfail { cpw crash 1111 } } verbose {old_keys [ 2222 3333 ->1111 ]} wraptest "shrink nhist 4->3" { mustrun { modpol crashpol "-history 3" } chkfail { cpw crash 4444 } chkfail { cpw crash 3333 } chkfail { cpw crash 2222 } chkfail { cpw crash 1111 } chkpass { cpw crash 5555 } } verbose {old_keys [ 4444 ->3333 ]} wraptest "verify nhist=3" { chkfail { cpw crash 5555 } chkfail { cpw crash 4444 } chkfail { cpw crash 3333 } chkpass { cpw crash 2222 } } verbose {old_keys [ ->4444 5555 ]} wraptest "shrink nhist 3->2" { mustrun { modpol crashpol "-history 2" } chkfail { cpw crash 2222 } chkfail { cpw crash 5555 } chkfail { cpw crash 4444 } chkpass { cpw crash 3333 } } verbose {old_keys [ ->2222 ]} delprinc crash delpol crashpol stop_kerberos_daemons } krb5-1.16/src/tests/dejagnu/krb-standalone/kadmin.exp0000644000704600001450000007021413211554426022435 0ustar ghudsonlibuuid# Kerberos kadmin test. # This is a DejaGnu test script. # This script tests Kerberos kadmin5 using kadmin.local as verification. #++ # kadmin_add - Test add new v5 principal function of kadmin. # # Adds principal $pname with password $password. Returns 1 on success. #-- proc kadmin_add { pname password } { global REALMNAME global KADMIN global KADMIN_LOCAL global KEY global spawn_id global tmppwd set good 0 spawn $KADMIN -p krbtest/admin@$REALMNAME -q "ank $pname" expect_after { "Cannot contact any KDC" { fail "kadmin add $pname lost KDC" catch "expect_after" return 0 } timeout { fail "kadmin add $pname" catch "expect_after" return 0 } eof { fail "kadmin add $pname" catch "expect_after" return 0 } } expect -re "assword\[^\r\n\]*:" { send "adminpass$KEY\r" } expect "Enter password for principal \"$pname@$REALMNAME\":" { send "$password\r" } expect "Re-enter password for principal \"$pname@$REALMNAME\":" { send "$password\r" } expect "Principal \"$pname@$REALMNAME\" created." { set good 1 } expect_after expect eof set k_stat [wait -i $spawn_id] verbose "wait -i $spawn_id returned $k_stat (kadmin add)" catch "close -i $spawn_id" if { $good == 1 } { # # use kadmin.local to verify that a principal was created and that its # salt types are 0 (normal). # envstack_push setup_kerberos_env kdc spawn $KADMIN_LOCAL -r $REALMNAME envstack_pop expect_after { -i $spawn_id timeout { fail "kadmin add $pname" catch "expect_after" return 0 } eof { fail "kadmin add $pname" catch "expect_after" return 0 } } set good 0 expect "kadmin.local: " { send "getprinc $pname\r" } expect "Principal: $pname@$REALMNAME" { set good 1 } expect "Expiration date:" { verbose "got expiration date" } expect "Last password change:" { verbose "got last pwchange" } expect "Password expiration date:" { verbose "got pwexpire date" } expect "Maximum ticket life:" { verbose "got max life" } expect "Maximum renewable life:" { verbose "got max rlife" } expect "Last modified:" { verbose "got last modified" } expect "Last successful authentication:" { verbose "last succ auth" } expect "Last failed authentication:" { verbose "last pw failed" } expect "Failed password attempts:" { verbose "num failed attempts" } expect "Number of keys:" { verbose "num keys"} expect { "Key: " { verbose "Key listed" exp_continue } "Attributes:" { verbose "attributes" } } expect "kadmin.local: " { send "q\r" } expect_after expect eof set k_stat [wait -i $spawn_id] verbose "wait -i $spawn_id returned $k_stat (kadmin.local show)" catch "close -i $spawn_id" if { $good == 1 } { pass "kadmin add $pname" return 1 } else { fail "kadmin add $pname" return 0 } } else { fail "kadmin add $pname" return 0 } } #++ # kadmin_add_rnd - Test add new v5 principal with random key function. # # Adds principal $pname with random key. Returns 1 on success. #-- proc kadmin_add_rnd { pname { flags "" } } { global REALMNAME global KADMIN global KADMIN_LOCAL global KEY global spawn_id global tmppwd set good 0 spawn $KADMIN -p krbtest/admin@$REALMNAME -q "ank -randkey $flags $pname" expect_after { "Cannot contact any KDC" { fail "kadmin add rnd $pname lost KDC" catch "expect_after" return 0 } timeout { fail "kadmin add_rnd $pname" catch "expect_after" return 0 } eof { fail "kadmin add_rnd $pname" catch "expect_after" return 0 } } expect -re "assword\[^\r\n\]*: *" { send "adminpass$KEY\r" } expect "Principal \"$pname@$REALMNAME\" created." { set good 1 } expect_after expect eof set k_stat [wait -i $spawn_id] verbose "wait -i $spawn_id returned $k_stat (kadmin add_rnd)" catch "close -i $spawn_id" if { $good == 1 } { # # use kadmin.local to verify that a principal was created and that its # salt types are 0 (normal). # envstack_push setup_kerberos_env kdc spawn $KADMIN_LOCAL -r $REALMNAME envstack_pop expect_after { -i $spawn_id timeout { fail "kadmin add_rnd $pname" catch "expect_after" return 0 } eof { fail "kadmin add_rnd $pname" catch "expect_after" return 0 } } set good 0 expect "kadmin.local:" { send "getprinc $pname\r" } expect "Principal: $pname@$REALMNAME" { set good 1 } expect "kadmin.local:" { send "q\r" } expect_after expect eof set k_stat [wait -i $spawn_id] verbose "wait -i $spawn_id returned $k_stat (kadmin.local show)" catch "close -i $spawn_id" if { $good == 1 } { pass "kadmin add_rnd $pname" return 1 } else { fail "kadmin add_rnd $pname" return 0 } } else { fail "kadmin add_rnd $pname" return 0 } } #++ # kadmin_show - Test show principal function of kadmin. # # Retrieves entry for $pname. Returns 1 on success. #-- proc kadmin_show { pname } { global REALMNAME global KADMIN global KEY global spawn_id spawn $KADMIN -p krbtest/admin@$REALMNAME -q "get_principal $pname" expect_after { "Cannot contact any KDC" { fail "kadmin show $pname lost KDC" catch "expect_after" return 0 } timeout { fail "kadmin show $pname" catch "expect_after" return 0 } eof { fail "kadmin show $pname" catch "expect_after" return 0 } } expect -re "assword\[^\r\n\]*: *" send "adminpass$KEY\r" expect -re "\r.*Principal: $pname@$REALMNAME.*Key: .*Attributes:.*Policy: .*\r" expect_after expect eof set k_stat [wait -i $spawn_id] verbose "wait -i $spawn_id returned $k_stat (kadmin show)" catch "close -i $spawn_id" pass "kadmin show $pname" return 1 } #++ # kadmin_cpw - Test change password function of kadmin # # Change password of $pname to $password. Returns 1 on success. #-- proc kadmin_cpw { pname password } { global REALMNAME global KADMIN global KEY global spawn_id spawn $KADMIN -p krbtest/admin@$REALMNAME -q "cpw $pname" expect_after { "Cannot contact any KDC" { fail "kadmin cpw $pname lost KDC" catch "expect_after" return 0 } timeout { fail "kadmin cpw $pname" catch "expect_after" return 0 } eof { fail "kadmin cpw $pname" catch "expect_after" return 0 } } expect -re "assword\[^\r\n\]*: *" { send "adminpass$KEY\r" } expect "Enter password for principal \"$pname@$REALMNAME\":" { send "$password\r" } expect "Re-enter password for principal \"$pname@$REALMNAME\":" { send "$password\r" } # When in doubt, jam one of these in there. expect "\r" expect "Password for \"$pname@$REALMNAME\" changed." expect_after expect eof set k_stat [wait -i $spawn_id] verbose "wait -i $spawn_id returned $k_stat (kadmin cpw)" catch "close -i $spawn_id" pass "kadmin cpw $pname" return 1 } #++ # kadmin_cpw_rnd - Test change random key function of kadmin. # # Changes principal $pname's key to a new random key. Returns 1 on success. #-- proc kadmin_cpw_rnd { pname } { global REALMNAME global KADMIN global KEY global spawn_id spawn $KADMIN -p krbtest/admin@$REALMNAME -q "cpw -randkey $pname" expect_after { "Cannot contact any KDC" { fail "kadmin cpw_rnd $pname lost KDC" catch "expect_after" return 0 } timeout { fail "kadmin cpw_rnd $pname" catch "expect_after" return 0 } eof { fail "kadmin cpw_rnd $pname" catch "expect_after" return 0 } } expect -re "assword\[^\r\n\]*: *" { send "adminpass$KEY\r" } # When in doubt, jam one of these in there. expect "\r" expect "Key for \"$pname@$REALMNAME\" randomized." expect_after expect eof set k_stat [wait -i $spawn_id] verbose "wait -i $spawn_id returned $k_stat (kadmin cpw_rnd)" catch "close -i $spawn_id" pass "kadmin cpw_rnd $pname" return 1 } #++ # kadmin_modify - Test modify principal function of kadmin. # # Modifies principal $pname with flags $flags. Returns 1 on success. #-- proc kadmin_modify { pname flags } { global REALMNAME global KADMIN global KEY global spawn_id spawn $KADMIN -p krbtest/admin@$REALMNAME -q "modprinc $flags $pname" expect_after { "Cannot contact any KDC" { fail "kadmin modify $pname ($flags) lost KDC" catch "expect_after" return 0 } timeout { fail "kadmin modify $pname" catch "expect_after" return 0 } eof { fail "kadmin modify $pname" catch "expect_after" return 0 } } expect -re "assword\[^\r\n\]*: *" send "adminpass$KEY\r" # When in doubt, jam one of these in there. expect "\r" expect "Principal \"$pname@$REALMNAME\" modified." expect_after expect eof set k_stat [wait -i $spawn_id] verbose "wait -i $spawn_id returned $k_stat (kadmin modify)" catch "close -i $spawn_id" pass "kadmin modify $pname" return 1 } #++ # kadmin_list - Test list database function of kadmin. # # Lists the database and verifies that output matches regular expression # "(.*@$REALMNAME)*". Returns 1 on success. #-- proc kadmin_list { } { global REALMNAME global KADMIN global KEY global spawn_id # "*" would match everything # "*n" should match a few like kadmin/admin but see ticket 5667 spawn $KADMIN -p krbtest/admin@$REALMNAME -q "get_principals *n" expect_after { "Cannot contact any KDC" { fail "kadmin ldb lost KDC" catch "expect_after" return 0 } "Communication failure" { fail "kadmin ldb got RPC error" catch "expect_after" return 0 } timeout { fail "kadmin ldb" catch "expect_after" return 0 } eof { fail "kadmin ldb" catch "expect_after" return 0 } } expect -re "assword\[^\r\n\]*: *" { send "adminpass$KEY\r" } expect -re "\(.*@$REALMNAME\r\n\)+" expect_after expect eof set k_stat [wait -i $spawn_id] verbose "wait -i $spawn_id returned $k_stat (kadmin list)" catch "close -i $spawn_id" pass "kadmin ldb" return 1 } #++ # kadmin_extract - Test extract service key function of kadmin. # # Extracts service key for service name $name instance $instance. Returns # 1 on success. #-- proc kadmin_extract { instance name } { global REALMNAME global KADMIN global KEY global spawn_id global tmppwd catch "exec rm -f $tmppwd/keytab" spawn $KADMIN -p krbtest/admin@$REALMNAME -q "xst -k $tmppwd/keytab $name/$instance" expect_after { "Cannot contact any KDC" { fail "kadmin xst $instance $name lost KDC" catch "expect_after" return 0 } timeout { fail "kadmin xst $instance $name" catch "expect_after" return 0 } eof { fail "kadmin xst $instance $name" catch "expect_after" return 0 } } expect -re "assword\[^\r\n\]*: *" { send "adminpass$KEY\r" } # expect -re "kadmin: Entry for principal $name/$instance with kvno [0-9], encryption type .* added to keytab WRFILE:$tmppwd/keytab." expect_after expect eof set k_stat [wait -i $spawn_id] verbose "wait -i $spawn_id returned $k_stat (kadmin xst)" catch "close -i $spawn_id" catch "exec rm -f $instance-new-srvtab" pass "kadmin xst $instance $name" return 1 } #++ # kadmin_extractv4 - Test extract service key in v4 format function of # kadmin. # # Extracts service key for service name $name instance $instance in version # 4 format. Returns 1 on success. #-- #proc kadmin_extractv4 { instance name } { # global REALMNAME # global KADMIN # global KEY # global spawn_id # # spawn $KADMIN -p krbtest/admin@$REALMNAME -q "xst4 $instance $name" # expect_after { # "Cannot contact any KDC" { # fail "kadmin xst4 $instance $name lost KDC" # catch "expect_after" # return 0 # } # timeout { # fail "kadmin xst4 $instance $name" # catch "expect_after" # return 0 # } # eof { # fail "kadmin xst4 $instance $name" # catch "expect_after" # return 0 # } # } # expect -re "assword\[^\r\n\]*: *" { # send "adminpass$KEY\r" # } # expect "extracted entry $name to key table $instance-new-v4-srvtab" # expect_after # expect eof # set k_stat [wait -i $spawn_id] # verbose "wait -i $spawn_id returned $k_stat (kadmin xst4)" # catch "close -i $spawn_id" # catch "exec rm -f $instance-new-v4-srvtab" # pass "kadmin xst4 $instance $name" # return 1 #} #++ # kadmin_delete - Test delete principal function of kadmin. # # Deletes principal $pname. Returns 1 on success. #-- proc kadmin_delete { pname } { global REALMNAME global KADMIN global KADMIN_LOCAL global KEY global spawn_id global tmppwd set good 0 spawn $KADMIN -p krbtest/admin@$REALMNAME -q "delprinc -force $pname" expect_after { "Cannot contact any KDC" { fail "kadmin_delete $pname lost KDC" catch "expect_after" return 0 } timeout { fail "kadmin delprinc $pname" catch "expect_after" return 0 } eof { fail "kadmin delprinc $pname" catch "expect_after" return 0 } } expect -re "assword\[^\r\n\]*: *" { send "adminpass$KEY\r" } expect "Principal \"$pname@$REALMNAME\" deleted." { set good 1 } expect_after expect eof set k_stat [wait -i $spawn_id] verbose "wait -i $spawn_id returned $k_stat (kadmin delprinc)" catch "close -i $spawn_id" if { $good == 1 } { # # use kadmin.local to verify that the old principal is not present. # envstack_push setup_kerberos_env kdc spawn $KADMIN_LOCAL -r $REALMNAME envstack_pop expect_after { -i $spawn_id timeout { fail "kadmin delprinc $pname" catch "expect_after" return 0 } eof { fail "kadmin delprinc $pname" catch "expect_after" return 0 } } set good 0 expect "kadmin.local: " { send "getprinc $pname\r" } expect "Principal does not exist while retrieving \"$pname@$REALMNAME\"." { set good 1 } expect "kadmin.local: " { send "quit\r" } expect_after expect eof set k_stat [wait -i $spawn_id] verbose "wait -i $spawn_id returned $k_stat (kadmin.local show)" catch "close -i $spawn_id" if { $good == 1 } { pass "kadmin delprinc $pname" return 1 } else { fail "kadmin delprinc $pname" return 0 } } else { fail "kadmin delprinc $pname" return 0 } } #++ # kadmin_delete - Test delete principal function of kadmin. # # Deletes principal $pname. Returns 1 on success. #-- proc kadmin_delete_locked_down { pname } { global REALMNAME global KADMIN global KADMIN_LOCAL global KEY global spawn_id global tmppwd # # First test that we fail, then unlock and retry # set good 0 spawn $KADMIN -p krbtest/admin@$REALMNAME -q "delprinc -force $pname" expect_after { "Cannot contact any KDC" { fail "kadmin_delete $pname lost KDC" catch "expect_after" return 0 } timeout { fail "kadmin delprinc $pname" catch "expect_after" return 0 } eof { fail "kadmin delprinc $pname" catch "expect_after" return 0 } } expect -re "assword\[^\r\n\]*: *" { send "adminpass$KEY\r" } expect "delete_principal: Operation requires ``delete'' privilege while deleting principal \"$pname@$REALMNAME\"" { set good 1 } expect_after expect eof set k_stat [wait -i $spawn_id] verbose "wait -i $spawn_id returned $k_stat (kadmin delprinc)" catch "close -i $spawn_id" if { $good == 1 } { # # use kadmin.local to remove lockdown. # envstack_push setup_kerberos_env kdc spawn $KADMIN_LOCAL -r $REALMNAME envstack_pop expect_after { -i $spawn_id timeout { fail "kadmin delprinc $pname" catch "expect_after" return 0 } eof { fail "kadmin delprinc $pname" catch "expect_after" return 0 } } set good 0 expect "kadmin.local: " { send "modprinc -lockdown_keys $pname\r" } expect "Principal \"$pname@$REALMNAME\" modified." { set good 1 } expect "kadmin.local: " { send "quit\r" } expect_after expect eof set k_stat [wait -i $spawn_id] verbose "wait -i $spawn_id returned $k_stat (kadmin.local show)" catch "close -i $spawn_id" if { $good == 1 } { set good 0 if {[kadmin_delete $pname]} { set good 1 } } if { $good == 1 } { pass "kadmin delprinc $pname" return 1 } else { fail "kadmin delprinc $pname" return 0 } } else { fail "kadmin delprinc $pname" return 0 } } #++ # kpasswd_cpw - Test password changing using kpasswd. # # Change $princ's password from $opw to $npw. Returns 1 on success. #-- proc kpasswd_cpw { princ opw npw } { global KPASSWD global REALMNAME spawn $KPASSWD $princ expect_after { timeout { fail "kpasswd $princ $npw" # catch "expect_after" return 0 } eof { fail "kpasswd $princ $npw" # catch "expect_after" return 0 } } # expect "Changing password for $princ." # expect "Old password:" { send "$opw\r" } # expect "New password:" { send "$npw\r" } # expect "New password (again):" { send "$npw\r" } expect "Password for $princ@$REALMNAME:" { send "$opw\r" } expect "Enter new password:" { send "$npw\r" } expect "Enter it again:" { send "$npw\r" } # expect "Kerberos password changed." expect "Password changed." expect_after expect eof if ![check_exit_status "kpasswd"] { fail "kpasswd $princ $npw" return 0 } pass "kpasswd $princ $npw" return 1 } #++ # kadmin_addpol - Test add new policy function of kadmin. # # Adds policy $pname. Returns 1 on success. #-- proc kadmin_addpol { pname } { global REALMNAME global KADMIN global KADMIN_LOCAL global KEY global spawn_id global tmppwd set good 0 spawn $KADMIN -p krbtest/admin@$REALMNAME -q "addpol $pname" expect_after { "Cannot contact any KDC" { fail "kadmin addpol $pname lost KDC" catch "expect_after" return 0 } timeout { fail "kadmin addpol $pname" catch "expect_after" return 0 } eof { fail "kadmin addpol $pname" catch "expect_after" return 0 } } expect -re "assword\[^\r\n\]*: *" { send "adminpass$KEY\r" } expect_after expect eof set k_stat [wait -i $spawn_id] verbose "wait -i $spawn_id returned $k_stat (kadmin addpol)" catch "close -i $spawn_id" # # use kadmin.local to verify that a policy was created # envstack_push setup_kerberos_env kdc spawn $KADMIN_LOCAL -r $REALMNAME envstack_pop expect_after { -i $spawn_id timeout { fail "kadmin addpol $pname" catch "expect_after" return 0 } eof { fail "kadmin addpol $pname" catch "expect_after" return 0 } } set good 0 expect "kadmin.local: " { send "getpol $pname\r" } expect "Policy: $pname" { set good 1 } expect "Maximum password life:" { verbose "got max pw life" } expect "Minimum password life:" { verbose "got min pw life" } expect "Minimum password length:" { verbose "got min pw length" } expect "Minimum number of password character classes:" { verbose "got min pw character classes" } expect "Number of old keys kept:" { verbose "got num old keys kept" } expect "kadmin.local: " { send "q\r" } expect_after expect eof set k_stat [wait -i $spawn_id] verbose "wait -i $spawn_id returned $k_stat (kadmin.local showpol)" catch "close -i $spawn_id" if { $good == 1 } { pass "kadmin addpol $pname" return 1 } else { fail "kadmin addpol $pname" return 0 } } #++ # kadmin_delpol - Test delete policy function of kadmin. # # Deletes policy $pname. Returns 1 on success. #-- proc kadmin_delpol { pname } { global REALMNAME global KADMIN global KADMIN_LOCAL global KEY global spawn_id global tmppwd spawn $KADMIN -p krbtest/admin@$REALMNAME -q "delpol -force $pname" expect_after { "Cannot contact any KDC" { fail "kadmin_delpol $pname lost KDC" catch "expect_after" return 0 } timeout { fail "kadmin delpol $pname" catch "expect_after" return 0 } eof { fail "kadmin delpol $pname" catch "expect_after" return 0 } } expect -re "assword\[^\r\n\]*: *" { send "adminpass$KEY\r" } expect_after expect eof set k_stat [wait -i $spawn_id] verbose "wait -i $spawn_id returned $k_stat (kadmin delpol)" catch "close -i $spawn_id" # # use kadmin.local to verify that the old policy is not present. # envstack_push setup_kerberos_env kdc spawn $KADMIN_LOCAL -r $REALMNAME envstack_pop expect_after { -i $spawn_id timeout { fail "kadmin delpol $pname" catch "expect_after" return 0 } eof { fail "kadmin delpol $pname" catch "expect_after" return 0 } } set good 0 expect "kadmin.local: " { send "getpol $pname\r" } expect "Policy does not exist while retrieving policy \"$pname\"." { set good 1 } expect "kadmin.local: " { send "quit\r" } expect_after expect eof set k_stat [wait -i $spawn_id] verbose "wait -i $spawn_id returned $k_stat (kadmin.local showpol)" catch "close -i $spawn_id" if { $good == 1 } { pass "kadmin delpol $pname" return 1 } else { fail "kadmin delpol $pname" return 0 } } #++ # kadmin_listpols - Test list policy database function of kadmin. # # Lists the policies. Returns 1 on success. #-- proc kadmin_listpols { } { global REALMNAME global KADMIN global KEY global spawn_id spawn $KADMIN -p krbtest/admin@$REALMNAME -q "get_policies *" expect_after { "Cannot contact any KDC" { fail "kadmin lpols lost KDC" catch "expect_after" return 0 } timeout { fail "kadmin lpols" catch "expect_after" return 0 } eof { fail "kadmin lpols" catch "expect_after" return 0 } } expect -re "assword\[^\r\n\]*: *" { send "adminpass$KEY\r" } expect_after expect eof set k_stat [wait -i $spawn_id] verbose "wait -i $spawn_id returned $k_stat (kadmin listpols)" catch "close -i $spawn_id" pass "kadmin lpols" return 1 } #++ # kadmin_modpol - Test modify policy function of kadmin. # # Modifies policy $pname with flags $flags. Returns 1 on success. #-- proc kadmin_modpol { pname flags } { global REALMNAME global KADMIN global KEY global spawn_id spawn $KADMIN -p krbtest/admin@$REALMNAME -q "modpol $flags $pname" expect_after { "Cannot contact any KDC" { fail "kadmin modpol $pname ($flags) lost KDC" catch "expect_after" return 0 } timeout { fail "kadmin modpol $pname" catch "expect_after" return 0 } eof { fail "kadmin modpol $pname" catch "expect_after" return 0 } } expect -re "assword\[^\r\n\]*: *" send "adminpass$KEY\r" # When in doubt, jam one of these in there. expect "\r" # Sadly, kadmin doesn't print a confirmation message for policy operations. expect_after expect eof set k_stat [wait -i $spawn_id] verbose "wait -i $spawn_id returned $k_stat (kadmin modpol)" catch "close -i $spawn_id" pass "kadmin modpol $pname" return 1 } #++ # kadmin_showpol - Test show policy function of kadmin. # # Retrieves entry for $pname. Returns 1 on success. #-- proc kadmin_showpol { pname } { global REALMNAME global KADMIN global KEY global spawn_id spawn $KADMIN -p krbtest/admin@$REALMNAME -q "get_policy $pname" expect_after { "Cannot contact any KDC" { fail "kadmin showpol $pname lost KDC" catch "expect_after" return 0 } timeout { fail "kadmin showpol $pname" catch "expect_after" return 0 } eof { fail "kadmin showpol $pname" catch "expect_after" return 0 } } expect -re "assword\[^\r\n\]*: *" send "adminpass$KEY\r" expect -re "\r.*Policy: $pname.*Number of old keys kept: .*\r" expect_after expect eof set k_stat [wait -i $spawn_id] verbose "wait -i $spawn_id returned $k_stat (kadmin showpol)" catch "close -i $spawn_id" pass "kadmin showpol $pname" return 1 } #++ # kdestroy #-- proc kdestroy { } { global KDESTROY spawn $KDESTROY -5 if ![check_exit_status "kdestroy"] { return 0 } return 1 } # Wrap the tests in a procedure, so that we can kill the daemons if # we get some sort of error. proc kadmin_test { } { global hostname # Start up the kerberos and kadmind daemons if {![start_kerberos_daemons 0] } { return } # Test basic kadmin functions. if {![kadmin_add v5principal/instance1 v5principal] \ || ![kadmin_addpol standardpol] \ || ![kadmin_showpol standardpol] \ || ![kadmin_listpols] \ || ![kadmin_modpol standardpol "-minlength 5"] \ || ![kadmin_add v4principal/instance2 v4principal] \ || ![kadmin_add_rnd v5random] \ || ![kadmin_show v5principal/instance1] \ || ![kadmin_show v4principal/instance2] \ || ![kadmin_show v5random] \ || ![kadmin_cpw v5principal/instance1 faroutman] \ || ![kadmin_cpw v4principal/instance2 honkydory] \ || ![kadmin_cpw_rnd v5random] \ || ![kadmin_modify v5random -allow_tix] \ || ![kadmin_modify v5random +allow_tix] \ || ![kadmin_modify v5random "-policy standardpol"] \ || ![kadmin_list] \ || ![kadmin_extract instance1 v5principal] \ || ![kadmin_delete v5random] \ || ![kadmin_delete v4principal/instance2] \ || ![kadmin_delete v5principal/instance1] \ || ![kadmin_delpol standardpol]} { return } # You cannot extract a v4 key... # || ![kadmin_extractv4 instance2 v4principal] \ # now test kpasswd if {![kadmin_add testprinc/instance thisisatest] \ || ![kpasswd_cpw testprinc/instance thisisatest anothertest] \ || ![kpasswd_cpw testprinc/instance anothertest goredsox] \ || ![kadmin_delete testprinc/instance]} { return } # now test that we can kinit with principals/passwords. # We defer kdestroying until after kpasswd at least once to test FAST automatic use in kpasswd if {![kadmin_add testprinc1/instance thisisatest] \ || ![kinit testprinc1/instance thisisatest 0] \ || ![kpasswd_cpw testprinc1/instance thisisatest anothertest] \ || ![kdestroy] \ || ![kinit testprinc1/instance anothertest 0] \ || ![kdestroy] \ || ![kpasswd_cpw testprinc1/instance anothertest goredsox] \ || ![kinit testprinc1/instance goredsox 0] \ || ![kdestroy] \ || ![kadmin_cpw testprinc1/instance betterwork] \ || ![kinit testprinc1/instance betterwork 0] \ || ![kdestroy] \ || ![kadmin_delete testprinc1/instance]} { return } # now test modify changes. if {![kadmin_add testuser longtestpw] \ || ![kinit testuser longtestpw 0] \ || ![kdestroy] \ || ![kadmin_modify testuser "-maxlife \"2500 seconds\""] \ || ![kinit testuser longtestpw 0] \ || ![kdestroy] \ || ![kadmin_delete testuser]} { return } # now test that reducing the history number doesn't make kadmind vulnerable. if {![kadmin_addpol crashpol] \ || ![kadmin_modpol crashpol "-history 5"] \ || ![kadmin_add crash first] \ || ![kadmin_modify crash "-policy crashpol"] \ || ![kadmin_cpw crash second] \ || ![kadmin_cpw crash third] \ || ![kadmin_cpw crash fourth] \ || ![kadmin_modpol crashpol "-history 3"] \ || ![kadmin_cpw crash fifth] \ || ![kadmin_delete crash] \ || ![kadmin_delpol crashpol]} { return } # test retrieval of large number of principals # bug [2877] for { set i 0 } { $i < 200 } { incr i } { if { ![kadmin_add "foo$i" foopass] } { return } } if { ![kadmin_list] } { return } # test fallback to kadmin/admin if {![kadmin_delete_locked_down kadmin/$hostname] \ || ![kadmin_list] \ || ![kadmin_add_rnd kadmin/$hostname -allow_tgs_req] \ || ![kadmin_list]} { return } verbose "kadmin_test succeeded" } run_once kadmin { # Set up the kerberos database. if {![get_hostname] \ || ![setup_kerberos_files] \ || ![setup_kerberos_env] \ || ![setup_kerberos_db 0]} { return } # Run the test. set status [catch kadmin_test msg] # Shut down the kerberos daemons and the rsh daemon. stop_kerberos_daemons if { $status != 0 } { send_error "ERROR: error in kadmin.exp\n" send_error "$msg\n" exit 1 } } krb5-1.16/src/tests/dejagnu/krb-standalone/gssapi.exp0000644000704600001450000001626313211554426022464 0ustar ghudsonlibuuid# Test for the GSS-API. # This is a DejaGnu test script. # This script tests that the GSS-API tester functions correctly. # This mostly just calls procedures in test/dejagnu/config/default.exp. if ![info exists KDESTROY] { set KDESTROY [findfile $objdir/../../clients/kdestroy/kdestroy] } if ![info exists GSSCLIENT] { set GSSCLIENT [findfile $objdir/../../appl/gss-sample/gss-client] } if ![info exists GSSSERVER] { set GSSSERVER [findfile $objdir/../../appl/gss-sample/gss-server] } # Set up the Kerberos files and environment. if {![get_hostname] || ![setup_kerberos_files] || ![setup_kerberos_env]} { return } # Initialize the Kerberos database. The argument tells # setup_kerberos_db that it is being called from here. if ![setup_kerberos_db 0] { return } # # Like kinit in default.exp, but allows us to specify a different ccache. # proc our_kinit { name pass ccache } { global REALMNAME global KINIT global spawn_id # Use kinit to get a ticket. spawn $KINIT -f -5 -c $ccache $name@$REALMNAME expect { "Password for $name@$REALMNAME:" { verbose "kinit started" } timeout { fail "kinit" return 0 } eof { fail "kinit" return 0 } } send "$pass\r" # This last expect seems useless, but without it the test hangs on # AIX. expect { "\r" { } } expect eof if ![check_exit_status kinit] { return 0 } return 1 } # # Destroys a particular ccache. # proc our_kdestroy { ccache } { global KDESTROY global spawn_id spawn $KDESTROY -c $ccache if ![check_exit_status "kdestroy"] { return 0 } return 1 } # # Stops the gss-server. # proc stop_gss_server { } { global gss_server_pid global gss_server_spawn_id if [info exists gss_server_pid] { catch "close -i $gss_server_spawn_id" catch "exec kill $gss_server_pid" wait -i $gss_server_spawn_id unset gss_server_pid } } # # Restore environment variables possibly set. # proc gss_restore_env { } { global env global gss_save_ccname global gss_save_ktname catch "unset env(KRB5CCNAME)" if [info exists gss_save_ccname] { set env(KRB5CCNAME) $gss_save_ccname unset gss_save_ccname } catch "unset env(KRB5_KTNAME)" if [info exists gss_save_ktname] { set env(KRB5_KTNAME) $gss_save_ktname unset gss_save_ktname } } proc run_client {test tkfile client} { global env global hostname global GSSCLIENT global spawn_id global gss_server_spawn_id global REALMNAME global portbase set env(KRB5CCNAME) $tkfile verbose "KRB5CCNAME=$env(KRB5CCNAME)" verbose "spawning gssclient, identity=$client" spawn $GSSCLIENT -d -port [expr 8 + $portbase] $hostname gssservice@$hostname "message from $client" set got_client 0 set got_server 0 expect_after { -i $spawn_id timeout { if {!$got_client} { verbose -log "client timeout" fail $test catch "expect_after" return } } eof { if {!$got_client} { verbose -log "client eof" fail $test catch "expect_after" return } } -i $gss_server_spawn_id timeout { if {!$got_server} { verbose -log "server timeout" fail $test catch "expect_after" return } } eof { if {!$got_server} { verbose -log "server eof" fail $test catch "expect_after" return } } } expect { -i $gss_server_spawn_id "Accepted connection: \"$client@$REALMNAME\"" exp_continue "Received message: \"message from $client\"" { set got_server 1 if {!$got_client} { exp_continue } } -i $spawn_id "Signature verified" { set got_client 1 if {!$got_server} { exp_continue } } } catch "expect_after" if ![check_exit_status $test] { # check_exit_staus already calls fail for us return } pass $test } proc doit { } { global REALMNAME global env global KLIST global KDESTROY global KEY global GSSTEST global GSSSERVER global GSSCLIENT global hostname global tmppwd global spawn_id global timeout global gss_server_pid global gss_server_spawn_id global gss_save_ccname global gss_save_ktname global portbase # Start up the kerberos and kadmind daemons. if ![start_kerberos_daemons 0] { perror "failed to start kerberos daemons" } # Use kadmin to add a key for us. if ![add_kerberos_key gsstest0 0] { perror "failed to set up gsstest0 key" } # Use kadmin to add a key for us. if ![add_kerberos_key gsstest1 0] { perror "failed to set up gsstest1 key" } # Use kadmin to add a key for us. if ![add_kerberos_key gsstest2 0] { perror "failed to set up gsstest2 key" } # Use kadmin to add a key for us. if ![add_kerberos_key gsstest3 0] { perror "failed to set up gsstest3 key" } # Use kadmin to add a service key for us. if ![add_random_key gssservice/$hostname 0] { perror "failed to set up gssservice/$hostname key" } # Use kdb5_edit to create a srvtab entry for gssservice if ![setup_srvtab 0 gssservice] { perror "failed to set up gssservice srvtab" } catch "exec rm -f $tmppwd/gss_tk_0 $tmppwd/gss_tk_1 $tmppwd/gss_tk_2 $tmppwd/gss_tk_3" # Use kinit to get a ticket. if ![our_kinit gsstest0 gsstest0$KEY $tmppwd/gss_tk_0] { perror "failed to kinit gsstest0" } # Use kinit to get a ticket. if ![our_kinit gsstest1 gsstest1$KEY $tmppwd/gss_tk_1] { perror "failed to kinit gsstest1" } # Use kinit to get a ticket. if ![our_kinit gsstest2 gsstest2$KEY $tmppwd/gss_tk_2] { perror "failed to kinit gsstest2" } # Use kinit to get a ticket. if ![our_kinit gsstest3 gsstest3$KEY $tmppwd/gss_tk_3] { perror "failed to kinit gsstest3" } # # Save settings of KRB5CCNAME and KRB5_KTNAME # if [info exists env(KRB5CCNAME)] { set gss_save_ccname $env(KRB5CCNAME) } if [info exists env(KRB5_KTNAME)] { set gss_save_ktname $env(KRB5_KTNAME) } # # set KRB5CCNAME and KRB5_KTNAME # set env(KRB5_KTNAME) FILE:$tmppwd/srvtab verbose "KRB5_KTNAME=$env(KRB5_KTNAME)" # Now start the gss-server. spawn $GSSSERVER -export -logfile $tmppwd/gss-server.log -verbose -port [expr 8 + $portbase] gssservice@$hostname set gss_server_pid [exp_pid] set gss_server_spawn_id $spawn_id expect { "starting" { } eof { perror "gss-server failed to start" } } run_client gssclient0 $tmppwd/gss_tk_0 gssclient0 run_client gssclient1 $tmppwd/gss_tk_1 gssclient1 run_client gssclient2 $tmppwd/gss_tk_2 gssclient2 run_client gssclient3 $tmppwd/gss_tk_3 gssclient3 stop_gss_server gss_restore_env if ![our_kdestroy $tmppwd/gss_tk_0] { perror "failed kdestroy gss_tk_0" 0 } if ![our_kdestroy $tmppwd/gss_tk_1] { perror "failed kdestroy gss_tk_1" 0 } if ![our_kdestroy $tmppwd/gss_tk_2] { perror "failed kdestroy gss_tk_2" 0 } if ![our_kdestroy $tmppwd/gss_tk_3] { perror "failed kdestroy gss_tk_3" 0 } catch "exec rm -f $tmppwd/gss_tk_0 $tmppwd/gss_tk_1 $tmppwd/gss_tk_2 $tmppwd/gss_tk_3" return } set status [catch doit msg] stop_gss_server gss_restore_env stop_kerberos_daemons if { $status != 0 } { perror "error in gssapi.exp" 0 perror $msg 0 } krb5-1.16/src/tests/t_general.py0000755000704600001450000000435513211554426016453 0ustar ghudsonlibuuid#!/usr/bin/python from k5test import * for realm in multipass_realms(create_host=False): # Check that kinit fails appropriately with the wrong password. msg = 'Password incorrect while getting initial credentials' realm.run([kinit, realm.user_princ], input='wrong\n', expected_code=1, expected_msg=msg) # Check that we can kinit as a different principal. realm.kinit(realm.admin_princ, password('admin')) realm.klist(realm.admin_princ) # Test FAST kinit. fastpw = password('fast') realm.run([kadminl, 'ank', '-pw', fastpw, '+requires_preauth', 'user/fast']) realm.kinit('user/fast', fastpw) realm.kinit('user/fast', fastpw, flags=['-T', realm.ccache]) realm.klist('user/fast@%s' % realm.realm) # Test kinit against kdb keytab realm.run([kinit, "-k", "-t", "KDB:", realm.user_princ]) # Test that we can get initial creds with an empty password via the # API. We have to disable the "empty" pwqual module to create a # principal with an empty password. (Regression test for #7642.) conf={'plugins': {'pwqual': {'disable': 'empty'}}} realm = K5Realm(create_user=False, create_host=False, krb5_conf=conf) realm.run([kadminl, 'addprinc', '-pw', '', 'user']) realm.run(['./icred', 'user', '']) realm.run(['./icred', '-s', 'user', '']) realm.stop() realm = K5Realm(create_host=False) # Regression test for #8454 (responder callback isn't used when # preauth is not required). realm.run(['./responder', '-r', 'password=%s' % password('user'), realm.user_princ]) # Test that WRONG_REALM responses aren't treated as referrals unless # they contain a crealm field pointing to a different realm. # (Regression test for #8060.) realm.run([kinit, '-C', 'notfoundprinc'], expected_code=1, expected_msg='not found in Kerberos database') # Spot-check KRB5_TRACE output expected_trace = ('Sending initial UDP request', 'Received answer', 'Selected etype info', 'AS key obtained', 'Decrypted AS reply', 'FAST negotiation: available', 'Storing user@KRBTEST.COM') realm.kinit(realm.user_princ, password('user'), expected_trace=expected_trace) success('FAST kinit, trace logging') krb5-1.16/src/tests/t_keyrollover.py0000755000704600001450000000572713211554426017417 0ustar ghudsonlibuuid#!/usr/bin/python from k5test import * rollover_krb5_conf = {'libdefaults': {'allow_weak_crypto': 'true'}} realm = K5Realm(krbtgt_keysalt='des-cbc-crc:normal', krb5_conf=rollover_krb5_conf) princ1 = 'host/test1@%s' % (realm.realm,) princ2 = 'host/test2@%s' % (realm.realm,) realm.addprinc(princ1) realm.addprinc(princ2) realm.run([kvno, realm.host_princ]) # Change key for TGS, keeping old key. realm.run([kadminl, 'cpw', '-randkey', '-e', 'aes256-cts', '-keepold', realm.krbtgt_princ]) # Ensure that kvno still works with an old TGT. realm.run([kvno, princ1]) realm.run([kadminl, 'purgekeys', realm.krbtgt_princ]) # Make sure an old TGT fails after purging old TGS key. realm.run([kvno, princ2], expected_code=1) msg = 'krbtgt/%s@%s\n\tEtype (skey, tkt): des-cbc-crc, des-cbc-crc' % \ (realm.realm, realm.realm) realm.run([klist, '-e'], expected_msg=msg) # Check that new key actually works. realm.kinit(realm.user_princ, password('user')) realm.run([kvno, realm.host_princ]) msg = 'krbtgt/%s@%s\n\tEtype (skey, tkt): ' \ 'aes256-cts-hmac-sha1-96, aes256-cts-hmac-sha1-96' % \ (realm.realm, realm.realm) realm.run([klist, '-e'], expected_msg=msg) # Test that the KDC only accepts the first enctype for a kvno, for a # local-realm TGS request. To set this up, we abuse an edge-case # behavior of modprinc -kvno. First, set up a DES3 krbtgt entry at # kvno 1 and cache a krbtgt ticket. realm.run([kadminl, 'cpw', '-randkey', '-e', 'des3-cbc-sha1', realm.krbtgt_princ]) realm.run([kadminl, 'modprinc', '-kvno', '1', realm.krbtgt_princ]) realm.kinit(realm.user_princ, password('user')) # Add an AES krbtgt entry at kvno 2, and then reset it to kvno 1 # (modprinc -kvno sets the kvno on all entries without deleting any). realm.run([kadminl, 'cpw', '-randkey', '-keepold', '-e', 'aes256-cts', realm.krbtgt_princ]) realm.run([kadminl, 'modprinc', '-kvno', '1', realm.krbtgt_princ]) out = realm.run([kadminl, 'getprinc', realm.krbtgt_princ]) if 'vno 1, aes256' not in out or 'vno 1, des3' not in out: fail('keyrollover: setup for TGS enctype test failed') # Now present the DES3 ticket to the KDC and make sure it's rejected. realm.run([kvno, realm.host_princ], expected_code=1) realm.stop() # Test a cross-realm TGT key rollover scenario where realm 1 mimics # the Active Directory behavior of always using kvno 0 when issuing # cross-realm TGTs. The first kvno invocation caches a cross-realm # TGT with the old key, and the second kvno invocation sends it to # r2's KDC with no kvno to identify it, forcing the KDC to try # multiple keys. r1, r2 = cross_realms(2) crosstgt_princ = 'krbtgt/%s@%s' % (r2.realm, r1.realm) r1.run([kadminl, 'modprinc', '-kvno', '0', crosstgt_princ]) r1.run([kvno, r2.host_princ]) r2.run([kadminl, 'cpw', '-pw', 'newcross', '-keepold', crosstgt_princ]) r1.run([kadminl, 'cpw', '-pw', 'newcross', crosstgt_princ]) r1.run([kadminl, 'modprinc', '-kvno', '0', crosstgt_princ]) r1.run([kvno, r2.user_princ]) success('keyrollover') krb5-1.16/src/tests/t_renprinc.py0000755000704600001450000000375613211554426016662 0ustar ghudsonlibuuid#!/usr/bin/python # Copyright (C) 2011 by the Massachusetts Institute of Technology. # All rights reserved. # Export of this software from the United States of America may # require a specific license from the United States Government. # It is the responsibility of any person or organization contemplating # export to obtain such a license before exporting. # # WITHIN THAT CONSTRAINT, permission to use, copy, modify, and # distribute this software and its documentation for any purpose and # without fee is hereby granted, provided that the above copyright # notice appear in all copies and that both that copyright notice and # this permission notice appear in supporting documentation, and that # the name of M.I.T. not be used in advertising or publicity pertaining # to distribution of the software without specific, written prior # permission. Furthermore if you modify this software you must label # your software as modified software and not distribute it in such a # fashion that it might be confused with the original M.I.T. software. # M.I.T. makes no representations about the suitability of # this software for any purpose. It is provided "as is" without express # or implied warranty. from k5test import * enctype = "aes128-cts" realm = K5Realm(create_host=False, create_user=False) salttypes = ('normal', 'v4', 'norealm', 'onlyrealm') # For a variety of salt types, test that we can rename a principal and # still get tickets with the same password. for st in salttypes: realm.run([kadminl, 'addprinc', '-e', enctype + ':' + st, '-pw', password(st), st]) realm.kinit(st, password(st)) newprinc = 'new' + st realm.run([kadminl, 'renprinc', st, newprinc]) realm.kinit(newprinc, password(st)) # Rename the normal salt again to test renaming a principal with # special salt type (which it will have after the first rename). realm.run([kadminl, 'renprinc', 'newnormal', 'newnormal2']) realm.kinit('newnormal2', password('normal')) success('Principal renaming tests') krb5-1.16/src/tests/s2p.c0000644000704600001450000000505213211554426015001 0ustar ghudsonlibuuid/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* tests/s2p.c - krb5_name_to_principal test harness */ /* * Copyright (C) 2013 by the Massachusetts Institute of Technology. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #include #include #include #include static krb5_context ctx; static void check(krb5_error_code code) { const char *errmsg; if (code) { errmsg = krb5_get_error_message(ctx, code); fprintf(stderr, "%s\n", errmsg); krb5_free_error_message(ctx, errmsg); exit(1); } } int main(int argc, char **argv) { krb5_principal princ; krb5_int32 type; const char *service, *hostname; char *name; /* Parse arguments. */ assert(argc == 4); hostname = argv[1]; service = argv[2]; if (strcmp(argv[3], "unknown") == 0) type = KRB5_NT_UNKNOWN; else if (strcmp(argv[3], "srv-hst") == 0) type = KRB5_NT_SRV_HST; else abort(); check(krb5_init_context(&ctx)); check(krb5_sname_to_principal(ctx, hostname, service, type, &princ)); check(krb5_unparse_name(ctx, princ, &name)); printf("%s\n", name); krb5_free_unparsed_name(ctx, name); krb5_free_principal(ctx, princ); krb5_free_context(ctx); return 0; } krb5-1.16/src/tests/t_cve-2013-1416.py0000755000704600001450000000062613211554426016564 0ustar ghudsonlibuuid#!/usr/bin/python from k5test import * realm = K5Realm() # CVE-2013-1416 KDC dereferences null pointer realm.kinit(realm.user_princ, password('user')) realm.run([kvno, '/test'], expected_code=1) realm.run([kvno, 'test/'], expected_code=1) realm.run([kvno, '/'], expected_code=1) # Make sure KDC is still running. realm.kinit(realm.user_princ, password('user')) success('CVE-2013-1416 regression test') krb5-1.16/src/tests/t_renew.py0000755000704600001450000001115713211554426016154 0ustar ghudsonlibuuid#!/usr/bin/python from k5test import * from datetime import datetime import re conf = {'realms': {'$realm': {'max_life': '20h', 'max_renewable_life': '20h'}}} realm = K5Realm(create_host=False, get_creds=False, kdc_conf=conf) def test(testname, life, rlife, exp_life, exp_rlife, env=None): global realm flags = ['-l', life] if rlife is not None: flags += ['-r', rlife] realm.kinit(realm.user_princ, password('user'), flags=flags, env=env) out = realm.run([klist, '-f']) if ('Default principal: %s\n' % realm.user_princ) not in out: fail('%s: did not get tickets' % testname) # Extract flags and check the renewable flag against expectations. flags = re.findall(r'Flags: ([a-zA-Z]*)', out)[0] if exp_rlife is None and 'R' in flags: fail('%s: ticket unexpectedly renewable' % testname) if exp_rlife is not None and 'R' not in flags: fail('%s: ticket unexpectedly non-renewable' % testname) # Extract the start time, end time, and renewable end time if present. times = re.findall(r'\d\d/\d\d/\d\d \d\d:\d\d:\d\d', out) times = [datetime.strptime(t, '%m/%d/%y %H:%M:%S') for t in times] starttime = times[0] endtime = times[1] rtime = times[2] if len(times) >= 3 else None # Check the ticket lifetime against expectations. If the lifetime # was determined by the request, there may be a small error # because KDC requests contain an end time rather than a lifetime. life = (endtime - starttime).seconds if abs(life - exp_life) > 5: fail('%s: expected life %d, got %d' % (testname, exp_life, life)) # Check the ticket renewable lifetime against expectations. if exp_rlife is None and rtime is not None: fail('%s: ticket has unexpected renew_till' % testname) if exp_rlife is not None and rtime is None: fail('%s: ticket is renewable but has no renew_till' % testname) if rtime is not None: rlife = (rtime - starttime).seconds if abs(rlife - exp_rlife) > 5: fail('%s: expected rlife %d, got %d' (testname, exp_rlife, rlife)) # Get renewable tickets. test('simple', '1h', '2h', 3600, 7200) # Renew twice, to test that renewed tickets are renewable. realm.kinit(realm.user_princ, flags=['-R']) realm.kinit(realm.user_princ, flags=['-R']) realm.klist(realm.user_princ) # Make sure we can use a renewed ticket. realm.run([kvno, realm.user_princ]) # Make sure we can't renew non-renewable tickets. test('non-renewable', '1h', None, 3600, None) realm.kinit(realm.user_princ, flags=['-R'], expected_code=1, expected_msg="KDC can't fulfill requested option") # Test that -allow_renewable on the client principal works. realm.run([kadminl, 'modprinc', '-allow_renewable', 'user']) test('disallowed client', '1h', '2h', 3600, None) realm.run([kadminl, 'modprinc', '+allow_renewable', 'user']) # Test that -allow_renewable on the server principal works. realm.run([kadminl, 'modprinc', '-allow_renewable', realm.krbtgt_princ]) test('disallowed server', '1h', '2h', 3600, None) realm.run([kadminl, 'modprinc', '+allow_renewable', realm.krbtgt_princ]) # Test that trivially renewable tickets are issued if renew_till <= # till. (Our client code bumps up the requested renewable life to the # requested life.) test('short', '2h', '1h', 7200, 7200) # Test that renewable tickets are issued if till > max life by # default, but not if we configure away the RENEWABLE-OK option. no_opts_conf = {'libdefaults': {'kdc_default_options': '0'}} no_opts = realm.special_env('no_opts', False, krb5_conf=no_opts_conf) realm.run([kadminl, 'modprinc', '-maxlife', '10 hours', 'user']) test('long', '15h', None, 10 * 3600, 15 * 3600) test('long noopts', '15h', None, 10 * 3600, None, env=no_opts) realm.run([kadminl, 'modprinc', '-maxlife', '20 hours', 'user']) # Test maximum renewable life on the client principal. realm.run([kadminl, 'modprinc', '-maxrenewlife', '5 hours', 'user']) test('maxrenewlife client 1', '4h', '5h', 4 * 3600, 5 * 3600) test('maxrenewlife client 2', '6h', '10h', 6 * 3600, 5 * 3600) # Test maximum renewable life on the server principal. realm.run([kadminl, 'modprinc', '-maxrenewlife', '3 hours', realm.krbtgt_princ]) test('maxrenewlife server 1', '2h', '3h', 2 * 3600, 3 * 3600) test('maxrenewlife server 2', '4h', '8h', 4 * 3600, 3 * 3600) # Test realm maximum life. realm.run([kadminl, 'modprinc', '-maxrenewlife', '40 hours', 'user']) realm.run([kadminl, 'modprinc', '-maxrenewlife', '40 hours', realm.krbtgt_princ]) test('maxrenewlife realm 1', '10h', '20h', 10 * 3600, 20 * 3600) test('maxrenewlife realm 2', '21h', '40h', 20 * 3600, 20 * 3600) success('Renewing credentials') krb5-1.16/src/tests/t_proxy.py0000755000704600001450000002175113211554426016216 0ustar ghudsonlibuuid#!/usr/bin/python from k5test import * # Skip this test if we're missing proxy functionality or parts of the proxy. if runenv.tls_impl == 'no': skip_rest('HTTP proxy tests', 'TLS build support not enabled') try: from paste import httpserver except: skip_rest('HTTP proxy tests', 'Python paste module not found') try: import kdcproxy except: skip_rest('HTTP proxy tests', 'Python kdcproxy module not found') # Construct a krb5.conf fragment configuring the client to use a local proxy # server. proxysubjectpem = os.path.join(srctop, 'tests', 'dejagnu', 'proxy-certs', 'proxy-subject.pem') proxysanpem = os.path.join(srctop, 'tests', 'dejagnu', 'proxy-certs', 'proxy-san.pem') proxyidealpem = os.path.join(srctop, 'tests', 'dejagnu', 'proxy-certs', 'proxy-ideal.pem') proxywrongpem = os.path.join(srctop, 'tests', 'dejagnu', 'proxy-certs', 'proxy-no-match.pem') proxybadpem = os.path.join(srctop, 'tests', 'dejagnu', 'proxy-certs', 'proxy-badsig.pem') proxyca = os.path.join(srctop, 'tests', 'dejagnu', 'proxy-certs', 'ca.pem') proxyurl = 'https://localhost:$port5/KdcProxy' proxyurlupcase = 'https://LocalHost:$port5/KdcProxy' proxyurl4 = 'https://127.0.0.1:$port5/KdcProxy' proxyurl6 = 'https://[::1]:$port5/KdcProxy' unanchored_krb5_conf = {'realms': {'$realm': { 'kdc': proxyurl, 'kpasswd_server': proxyurl}}} anchored_name_krb5_conf = {'realms': {'$realm': { 'kdc': proxyurl, 'kpasswd_server': proxyurl, 'http_anchors': 'FILE:%s' % proxyca}}} anchored_upcasename_krb5_conf = {'realms': {'$realm': { 'kdc': proxyurlupcase, 'kpasswd_server': proxyurlupcase, 'http_anchors': 'FILE:%s' % proxyca}}} anchored_kadmin_krb5_conf = {'realms': {'$realm': { 'kdc': proxyurl, 'admin_server': proxyurl, 'http_anchors': 'FILE:%s' % proxyca}}} anchored_ipv4_krb5_conf = {'realms': {'$realm': { 'kdc': proxyurl4, 'kpasswd_server': proxyurl4, 'http_anchors': 'FILE:%s' % proxyca}}} kpasswd_input = (password('user') + '\n' + password('user') + '\n' + password('user') + '\n') def start_proxy(realm, keycertpem): proxy_conf_path = os.path.join(realm.testdir, 'kdcproxy.conf') proxy_exec_path = os.path.join(srctop, 'util', 'paste-kdcproxy.py') conf = open(proxy_conf_path, 'w') conf.write('[%s]\n' % realm.realm) conf.write('kerberos = kerberos://localhost:%d\n' % realm.portbase) conf.write('kpasswd = kpasswd://localhost:%d\n' % (realm.portbase + 2)) conf.close() realm.env['KDCPROXY_CONFIG'] = proxy_conf_path cmd = [proxy_exec_path, str(realm.server_port()), keycertpem] return realm.start_server(cmd, sentinel='proxy server ready') # Fail: untrusted issuer and hostname doesn't match. output("running pass 1: issuer not trusted and hostname doesn't match\n") realm = K5Realm(krb5_conf=unanchored_krb5_conf, get_creds=False, create_host=False) proxy = start_proxy(realm, proxywrongpem) realm.kinit(realm.user_princ, password=password('user'), expected_code=1) stop_daemon(proxy) realm.stop() # Fail: untrusted issuer, host name matches subject. output("running pass 2: subject matches, issuer not trusted\n") realm = K5Realm(krb5_conf=unanchored_krb5_conf, get_creds=False, create_host=False) proxy = start_proxy(realm, proxysubjectpem) realm.kinit(realm.user_princ, password=password('user'), expected_code=1) stop_daemon(proxy) realm.stop() # Fail: untrusted issuer, host name matches subjectAltName. output("running pass 3: subjectAltName matches, issuer not trusted\n") realm = K5Realm(krb5_conf=unanchored_krb5_conf, get_creds=False, create_host=False) proxy = start_proxy(realm, proxysanpem) realm.kinit(realm.user_princ, password=password('user'), expected_code=1) stop_daemon(proxy) realm.stop() # Fail: untrusted issuer, certificate signature is bad. output("running pass 4: subject matches, issuer not trusted\n") realm = K5Realm(krb5_conf=unanchored_krb5_conf, get_creds=False, create_host=False) proxy = start_proxy(realm, proxybadpem) realm.kinit(realm.user_princ, password=password('user'), expected_code=1) stop_daemon(proxy) realm.stop() # Fail: trusted issuer but hostname doesn't match. output("running pass 5: issuer trusted but hostname doesn't match\n") realm = K5Realm(krb5_conf=anchored_name_krb5_conf, get_creds=False, create_host=False) proxy = start_proxy(realm, proxywrongpem) realm.kinit(realm.user_princ, password=password('user'), expected_code=1) stop_daemon(proxy) realm.stop() # Succeed: trusted issuer and host name matches subject. output("running pass 6: issuer trusted, subject matches\n") realm = K5Realm(krb5_conf=anchored_name_krb5_conf, start_kadmind=True, get_creds=False) proxy = start_proxy(realm, proxysubjectpem) realm.kinit(realm.user_princ, password=password('user')) realm.run([kvno, realm.host_princ]) realm.run([kpasswd, realm.user_princ], input=kpasswd_input) stop_daemon(proxy) realm.stop() # Succeed: trusted issuer and host name matches subjectAltName. output("running pass 7: issuer trusted, subjectAltName matches\n") realm = K5Realm(krb5_conf=anchored_name_krb5_conf, start_kadmind=True, get_creds=False) proxy = start_proxy(realm, proxysanpem) realm.kinit(realm.user_princ, password=password('user')) realm.run([kvno, realm.host_princ]) realm.run([kpasswd, realm.user_princ], input=kpasswd_input) stop_daemon(proxy) realm.stop() # Fail: certificate signature is bad. output("running pass 8: issuer trusted and subjectAltName matches, sig bad\n") realm = K5Realm(krb5_conf=anchored_name_krb5_conf, get_creds=False, create_host=False) proxy = start_proxy(realm, proxybadpem) realm.kinit(realm.user_princ, password=password('user'), expected_code=1) stop_daemon(proxy) realm.stop() # Fail: trusted issuer but IP doesn't match. output("running pass 9: issuer trusted but no name matches IP\n") realm = K5Realm(krb5_conf=anchored_ipv4_krb5_conf, get_creds=False, create_host=False) proxy = start_proxy(realm, proxywrongpem) realm.kinit(realm.user_princ, password=password('user'), expected_code=1) stop_daemon(proxy) realm.stop() # Fail: trusted issuer, but subject does not match. output("running pass 10: issuer trusted, but subject does not match IP\n") realm = K5Realm(krb5_conf=anchored_ipv4_krb5_conf, get_creds=False, create_host=False) proxy = start_proxy(realm, proxysubjectpem) realm.kinit(realm.user_princ, password=password('user'), expected_code=1) stop_daemon(proxy) realm.stop() # Succeed: trusted issuer and host name matches subjectAltName. output("running pass 11: issuer trusted, subjectAltName matches IP\n") realm = K5Realm(krb5_conf=anchored_ipv4_krb5_conf, start_kadmind=True, get_creds=False) proxy = start_proxy(realm, proxysanpem) realm.kinit(realm.user_princ, password=password('user')) realm.run([kvno, realm.host_princ]) realm.run([kpasswd, realm.user_princ], input=kpasswd_input) stop_daemon(proxy) realm.stop() # Fail: certificate signature is bad. output("running pass 12: issuer trusted, names don't match, signature bad\n") realm = K5Realm(krb5_conf=anchored_ipv4_krb5_conf, get_creds=False, create_host=False) proxy = start_proxy(realm, proxybadpem) realm.kinit(realm.user_princ, password=password('user'), expected_code=1) stop_daemon(proxy) realm.stop() # Succeed: trusted issuer and host name matches subject, using kadmin # configuration to find kpasswdd. output("running pass 13: issuer trusted, subject matches\n") realm = K5Realm(krb5_conf=anchored_kadmin_krb5_conf, start_kadmind=True, get_creds=False, create_host=False) proxy = start_proxy(realm, proxysubjectpem) realm.run([kpasswd, realm.user_princ], input=kpasswd_input) stop_daemon(proxy) realm.stop() # Succeed: trusted issuer and host name matches subjectAltName, using # kadmin configuration to find kpasswdd. output("running pass 14: issuer trusted, subjectAltName matches\n") realm = K5Realm(krb5_conf=anchored_kadmin_krb5_conf, start_kadmind=True, get_creds=False, create_host=False) proxy = start_proxy(realm, proxysanpem) realm.run([kpasswd, realm.user_princ], input=kpasswd_input) stop_daemon(proxy) realm.stop() # Succeed: trusted issuer and host name matches subjectAltName (give or take # case). output("running pass 15: issuer trusted, subjectAltName case-insensitive\n") realm = K5Realm(krb5_conf=anchored_upcasename_krb5_conf, start_kadmind=True, get_creds=False, create_host=False) proxy = start_proxy(realm, proxysanpem) realm.run([kpasswd, realm.user_princ], input=kpasswd_input) stop_daemon(proxy) realm.stop() success('MS-KKDCP proxy') krb5-1.16/src/tests/t_authdata.py0000644000704600001450000002571213211554426016626 0ustar ghudsonlibuuid#!/usr/bin/python from k5test import * # Load the sample KDC authdata module. greet_path = os.path.join(buildtop, 'plugins', 'authdata', 'greet_server', 'greet_server.so') conf = {'plugins': {'kdcauthdata': {'module': 'greet:' + greet_path}}} realm = K5Realm(krb5_conf=conf) # With no requested authdata, we expect to see SIGNTICKET (512) in an # if-relevant container and the greet authdata in a kdc-issued # container. out = realm.run(['./adata', realm.host_princ]) if '?512: ' not in out or '^-42: Hello' not in out: fail('expected authdata not seen for basic request') # Requested authdata is copied into the ticket, with KDC-only types # filtered out. (128 is win2k-pac, which should be filtered.) out = realm.run(['./adata', realm.host_princ, '-5', 'test1', '?-6', 'test2', '128', 'fakepac', '?128', 'ifrelfakepac', '^-8', 'fakekdcissued', '?^-8', 'ifrelfakekdcissued']) if ' -5: test1' not in out or '?-6: test2' not in out: fail('expected authdata not seen for request with authdata') if 'fake' in out: fail('KDC-only authdata not filtered for request with authdata') realm.run(['./adata', realm.host_princ, '!-1', 'mandatoryforkdc'], expected_code=1, expected_msg='KDC policy rejects request') # The no_auth_data_required server flag should suppress SIGNTICKET, # but not module or request authdata. realm.run([kadminl, 'ank', '-randkey', '+no_auth_data_required', 'noauth']) realm.extract_keytab('noauth', realm.keytab) out = realm.run(['./adata', 'noauth', '-2', 'test']) if '^-42: Hello' not in out or ' -2: test' not in out: fail('expected authdata not seen for no_auth_data_required request') if '512: ' in out: fail('SIGNTICKET authdata seen for no_auth_data_required request') # Cross-realm TGT requests should also suppress SIGNTICKET, but not # module or request authdata. realm.addprinc('krbtgt/XREALM') realm.extract_keytab('krbtgt/XREALM', realm.keytab) out = realm.run(['./adata', 'krbtgt/XREALM', '-3', 'test']) if '^-42: Hello' not in out or ' -3: test' not in out: fail('expected authdata not seen for cross-realm TGT request') if '512: ' in out: fail('SIGNTICKET authdata seen in cross-realm TGT') realm.stop() if not os.path.exists(os.path.join(plugins, 'preauth', 'pkinit.so')): skipped('anonymous ticket authdata tests', 'PKINIT not built') else: # Set up a realm with PKINIT support and get anonymous tickets. certs = os.path.join(srctop, 'tests', 'dejagnu', 'pkinit-certs') ca_pem = os.path.join(certs, 'ca.pem') kdc_pem = os.path.join(certs, 'kdc.pem') privkey_pem = os.path.join(certs, 'privkey.pem') pkinit_conf = {'realms': {'$realm': { 'pkinit_anchors': 'FILE:%s' % ca_pem, 'pkinit_identity': 'FILE:%s,%s' % (kdc_pem, privkey_pem)}}} conf.update(pkinit_conf) realm = K5Realm(krb5_conf=conf, get_creds=False) realm.addprinc('WELLKNOWN/ANONYMOUS') realm.kinit('@%s' % realm.realm, flags=['-n']) # SIGNTICKET and module authdata should be suppressed for # anonymous tickets, but not request authdata. out = realm.run(['./adata', realm.host_princ, '-4', 'test']) if ' -4: test' not in out: fail('expected authdata not seen for anonymous request') if '512: ' in out or '-42: ' in out: fail('SIGNTICKET or greet authdata seen for anonymous request') realm.stop() # Test authentication indicators. Load the test preauth module so we # can control the indicators asserted. testpreauth = os.path.join(buildtop, 'plugins', 'preauth', 'test', 'test.so') krb5conf = {'plugins': {'kdcpreauth': {'module': 'test:' + testpreauth}, 'clpreauth': {'module': 'test:' + testpreauth}}} realm, realm2 = cross_realms(2, args=({'realm': 'LOCAL'}, {'realm': 'FOREIGN'}), krb5_conf=krb5conf, get_creds=False) realm.run([kadminl, 'modprinc', '+requires_preauth', '-maxrenewlife', '2 days', realm.user_princ]) realm.run([kadminl, 'modprinc', '-maxrenewlife', '2 days', realm.host_princ]) realm.run([kadminl, 'modprinc', '-maxrenewlife', '2 days', realm.krbtgt_princ]) realm.extract_keytab(realm.krbtgt_princ, realm.keytab) realm.extract_keytab(realm.host_princ, realm.keytab) realm.extract_keytab('krbtgt/FOREIGN', realm.keytab) realm2.extract_keytab(realm2.krbtgt_princ, realm.keytab) realm2.extract_keytab(realm2.host_princ, realm.keytab) realm2.extract_keytab('krbtgt/LOCAL', realm.keytab) # AS request to local-realm service realm.kinit(realm.user_princ, password('user'), ['-X', 'indicators=indcl', '-r', '2d', '-S', realm.host_princ]) realm.run(['./adata', realm.host_princ], expected_msg='+97: [indcl]') # Ticket modification request realm.kinit(realm.user_princ, None, ['-R', '-S', realm.host_princ]) realm.run(['./adata', realm.host_princ], expected_msg='+97: [indcl]') # AS request to cross TGT realm.kinit(realm.user_princ, password('user'), ['-X', 'indicators=indcl', '-S', 'krbtgt/FOREIGN']) realm.run(['./adata', 'krbtgt/FOREIGN'], expected_msg='+97: [indcl]') # Multiple indicators realm.kinit(realm.user_princ, password('user'), ['-X', 'indicators=indcl indcl2 indcl3']) realm.run(['./adata', realm.krbtgt_princ], expected_msg='+97: [indcl, indcl2, indcl3]') # AS request to local TGT (resulting creds are used for TGS tests) realm.kinit(realm.user_princ, password('user'), ['-X', 'indicators=indcl']) realm.run(['./adata', realm.krbtgt_princ], expected_msg='+97: [indcl]') # Local TGS request for local realm service realm.run(['./adata', realm.host_princ], expected_msg='+97: [indcl]') # Local TGS request for cross TGT service realm.run(['./adata', 'krbtgt/FOREIGN'], expected_msg='+97: [indcl]') # We don't yet have support for passing auth indicators across realms, # so just verify that indicators don't survive cross-realm requests. out = realm.run(['./adata', realm2.krbtgt_princ]) if '97:' in out: fail('auth-indicator seen in cross TGT request to local TGT') out = realm.run(['./adata', 'krbtgt/LOCAL@FOREIGN']) if '97:' in out: fail('auth-indicator seen in cross TGT request to cross TGT') out = realm.run(['./adata', realm2.host_princ]) if '97:' in out: fail('auth-indicator seen in cross TGT request to service') # Test that the CAMMAC signature still works during a krbtgt rollover. realm.run([kadminl, 'cpw', '-randkey', '-keepold', realm.krbtgt_princ]) realm.run(['./adata', realm.host_princ], expected_msg='+97: [indcl]') # Test indicator enforcement. realm.addprinc('restricted') realm.run([kadminl, 'setstr', 'restricted', 'require_auth', 'superstrong']) realm.run([kvno, 'restricted'], expected_code=1, expected_msg='KDC policy rejects request') realm.run([kadminl, 'setstr', 'restricted', 'require_auth', 'indcl']) realm.run([kvno, 'restricted']) realm.kinit(realm.user_princ, password('user'), ['-X', 'indicators=ind1 ind2']) realm.run([kvno, 'restricted'], expected_code=1) realm.run([kadminl, 'setstr', 'restricted', 'require_auth', 'a b c ind2']) realm.run([kvno, 'restricted']) # Regression test for one manifestation of #8139: ensure that # forwarded TGTs obtained across a TGT re-key still work when the # preferred krbtgt enctype changes. realm.kinit(realm.user_princ, password('user'), ['-f']) realm.run([kadminl, 'cpw', '-randkey', '-keepold', '-e', 'des3-cbc-sha1', realm.krbtgt_princ]) realm.run(['./forward']) realm.run([kvno, realm.host_princ]) # Repeat the above test using a renewed TGT. realm.kinit(realm.user_princ, password('user'), ['-r', '2d']) realm.run([kadminl, 'cpw', '-randkey', '-keepold', '-e', 'aes128-cts', realm.krbtgt_princ]) realm.kinit(realm.user_princ, None, ['-R']) realm.run([kvno, realm.host_princ]) realm.stop() realm2.stop() # Load the test KDB module to allow successful S4U2Proxy # auth-indicator requests. testprincs = {'krbtgt/KRBTEST.COM': {'keys': 'aes128-cts'}, 'krbtgt/FOREIGN': {'keys': 'aes128-cts'}, 'user': {'keys': 'aes128-cts', 'flags': '+preauth'}, 'service/1': {'keys': 'aes128-cts', 'flags': '+preauth'}, 'service/2': {'keys': 'aes128-cts'}, 'noauthdata': {'keys': 'aes128-cts', 'flags': '+no_auth_data_required'}} kdcconf = {'realms': {'$realm': {'database_module': 'test'}}, 'dbmodules': {'test': {'db_library': 'test', 'princs': testprincs, 'delegation': {'service/1': 'service/2'}}}} realm = K5Realm(krb5_conf=krb5conf, kdc_conf=kdcconf, create_kdb=False) usercache = 'FILE:' + os.path.join(realm.testdir, 'usercache') realm.extract_keytab(realm.krbtgt_princ, realm.keytab) realm.extract_keytab('krbtgt/FOREIGN', realm.keytab) realm.extract_keytab(realm.user_princ, realm.keytab) realm.extract_keytab('service/1', realm.keytab) realm.extract_keytab('service/2', realm.keytab) realm.extract_keytab('noauthdata', realm.keytab) realm.start_kdc() # S4U2Self (should have no indicators since client did not authenticate) realm.kinit('service/1', None, ['-k', '-f', '-X', 'indicators=inds1']) realm.run([kvno, '-U', 'user', 'service/1']) out = realm.run(['./adata', '-p', realm.user_princ, 'service/1']) if '97:' in out: fail('auth-indicator present in S4U2Self response') # S4U2Proxy (indicators should come from evidence ticket, not TGT) realm.kinit(realm.user_princ, None, ['-k', '-f', '-X', 'indicators=indcl', '-S', 'service/1', '-c', usercache]) realm.run(['./s4u2proxy', usercache, 'service/2']) out = realm.run(['./adata', '-p', realm.user_princ, 'service/2']) if '+97: [indcl]' not in out or '[inds1]' in out: fail('correct auth-indicator not seen for S4U2Proxy req') # Test that KDB module authdata is included in an AS request, by # default or with an explicit PAC request. realm.kinit(realm.user_princ, None, ['-k']) realm.run(['./adata', realm.krbtgt_princ], expected_msg='-456: db-authdata-test') realm.kinit(realm.user_princ, None, ['-k', '--request-pac']) realm.run(['./adata', realm.krbtgt_princ], expected_msg='-456: db-authdata-test') # Test that KDB module authdata is suppressed in an AS request by a # negative PAC request. realm.kinit(realm.user_princ, None, ['-k', '--no-request-pac']) out = realm.run(['./adata', realm.krbtgt_princ]) if '-456: db-authdata-test' in out: fail('DB authdata not suppressed by --no-request-pac') # Test that KDB authdata is included in a TGS request by default. realm.run(['./adata', 'service/1'], expected_msg='-456: db-authdata-test') # Test that KDB authdata is suppressed in a TGS request by the # +no_auth_data_required flag. out = realm.run(['./adata', 'noauthdata']) if '-456: db-authdata-test' in out: fail('DB authdata not suppressed by +no_auth_data_required') # Additional KDB module authdata behavior we don't currently test: # * KDB module authdata is suppressed in TGS requests if the TGT # contains no authdata and the request is not cross-realm or S4U. # * KDB module authdata is suppressed for anonymous tickets. success('Authorization data tests') krb5-1.16/src/tests/threads/0000755000704600001450000000000013211554426015561 5ustar ghudsonlibuuidkrb5-1.16/src/tests/threads/profread.c0000644000704600001450000001775513211554426017546 0ustar ghudsonlibuuid/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* tests/threads/profread.c */ /* * Copyright (C) 2009 by the Massachusetts Institute of Technology. * All rights reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ /* * krb5 profile data retrieval performance testing * initially contributed by Ken Raeburn */ #include "k5-platform.h" #include #include #include #include #include #include #define N_THREADS 4 #define ITER_COUNT 40000 static int init_krb5_first = 0; struct resource_info { struct timeval start_time, end_time; }; struct thread_info { pthread_t tid; struct resource_info r; krb5_context ctx; }; static char *prog; static unsigned int n_threads = N_THREADS; static int iter_count = ITER_COUNT; static int do_pause; static void usage (void) __attribute__((noreturn)); static void usage () { fprintf (stderr, "usage: %s [ options ]\n", prog); fprintf (stderr, "options:\n"); fprintf (stderr, "\t-t N\tspecify number of threads (default %d)\n", N_THREADS); fprintf (stderr, "\t-i N\tset iteration count (default %d)\n", ITER_COUNT); fprintf (stderr, "\t-K\tinitialize a krb5_context for the duration\n"); fprintf (stderr, "\t-P\tpause briefly after starting, to allow attaching dtrace/strace/etc\n"); exit (1); } static int numarg (char *arg) { char *end; long val; val = strtol (arg, &end, 10); if (*arg == 0 || *end != 0) { fprintf (stderr, "invalid numeric argument '%s'\n", arg); usage (); } if (val >= 1 && val <= INT_MAX) return val; fprintf (stderr, "out of range numeric value %ld (1..%d)\n", val, INT_MAX); usage (); } static char optstring[] = "t:i:KP"; static void process_options (int argc, char *argv[]) { int c; prog = strrchr (argv[0], '/'); if (prog) prog++; else prog = argv[0]; while ((c = getopt (argc, argv, optstring)) != -1) { switch (c) { case '?': case ':': usage (); break; case 't': n_threads = numarg (optarg); if (n_threads >= SIZE_MAX / sizeof (struct thread_info)) { n_threads = SIZE_MAX / sizeof (struct thread_info); fprintf (stderr, "limiting n_threads to %u\n", n_threads); } break; case 'i': iter_count = numarg (optarg); break; case 'K': init_krb5_first = 1; break; case 'P': do_pause = 1; break; } } if (argc != optind) usage (); } static long double tvsub (struct timeval t1, struct timeval t2) { /* POSIX says .tv_usec is signed. */ return (t1.tv_sec - t2.tv_sec + (long double) 1.0e-6 * (t1.tv_usec - t2.tv_usec)); } static struct timeval now (void) { struct timeval tv; if (gettimeofday (&tv, NULL) < 0) { perror ("gettimeofday"); exit (1); } return tv; } static void run_iterations (struct resource_info *r) { int i; krb5_error_code err; krb5_context ctx; profile_t prof = NULL; err = krb5_init_context(&ctx); if (err) { com_err(prog, err, "initializing krb5 context"); exit(1); } err = krb5_get_profile(ctx, &prof); if (err) { com_err(prog, err, "fetching profile from context"); exit(1); } r->start_time = now (); for (i = 0; i < iter_count; i++) { int ival; err = profile_get_integer(prof, "one", "two", "three", 42, &ival); if (err) { com_err(prog, err, "fetching value from profile"); exit(1); } } r->end_time = now (); profile_release (prof); krb5_free_context(ctx); } static void * thread_proc (void *p) { run_iterations (p); return 0; } static struct thread_info *tinfo; static krb5_context kctx; static struct rusage start, finish; static struct timeval start_time, finish_time; int main (int argc, char *argv[]) { long double user, sys, wallclock, total; unsigned int i; process_options (argc, argv); /* * Some places in the krb5 library cache data globally. * This option allows you to test the effect of that. */ if (init_krb5_first && krb5_init_context (&kctx) != 0) { fprintf (stderr, "krb5_init_context error\n"); exit (1); } tinfo = calloc (n_threads, sizeof (*tinfo)); if (tinfo == NULL) { perror ("calloc"); exit (1); } printf ("Threads: %d iterations: %d\n", n_threads, iter_count); if (do_pause) { printf ("pid %lu napping...\n", (unsigned long) getpid ()); sleep (10); } printf ("starting...\n"); /* And *now* we start measuring the performance. */ if (getrusage (RUSAGE_SELF, &start) < 0) { perror ("getrusage"); exit (1); } start_time = now (); #define foreach_thread(IDXVAR) for (IDXVAR = 0; IDXVAR < n_threads; IDXVAR++) foreach_thread (i) { int err; err = pthread_create (&tinfo[i].tid, NULL, thread_proc, &tinfo[i].r); if (err) { fprintf (stderr, "pthread_create: %s\n", strerror (err)); exit (1); } } foreach_thread (i) { int err; void *val; err = pthread_join (tinfo[i].tid, &val); if (err) { fprintf (stderr, "pthread_join: %s\n", strerror (err)); exit (1); } } finish_time = now (); if (getrusage (RUSAGE_SELF, &finish) < 0) { perror ("getrusage"); exit (1); } if (init_krb5_first) krb5_free_context (kctx); foreach_thread (i) { printf ("Thread %2d: elapsed time %Lfs\n", i, tvsub (tinfo[i].r.end_time, tinfo[i].r.start_time)); } wallclock = tvsub (finish_time, start_time); /* * Report on elapsed time and CPU usage. Depending what * performance issue you're chasing down, different values may be * of particular interest, so report all the info we've got. */ printf ("Overall run time with %d threads = %Lfs, %.2Lfus per iteration.\n", n_threads, wallclock, 1000000 * wallclock / iter_count); user = tvsub (finish.ru_utime, start.ru_utime); sys = tvsub (finish.ru_stime, start.ru_stime); total = user + sys; printf ("CPU usage: user=%Lfs sys=%Lfs total=%Lfs.\n", user, sys, total); printf ("Utilization: user=%5.1Lf%% sys=%5.1Lf%% total=%5.1Lf%%\n", 100 * user / wallclock, 100 * sys / wallclock, 100 * total / wallclock); printf ("Util/thread: user=%5.1Lf%% sys=%5.1Lf%% total=%5.1Lf%%\n", 100 * user / wallclock / n_threads, 100 * sys / wallclock / n_threads, 100 * total / wallclock / n_threads); printf ("Total CPU use per iteration per thread: %.2Lfus\n", 1000000 * total / n_threads / iter_count); return 0; } krb5-1.16/src/tests/threads/prof1.c0000644000704600001450000000564713211554426016770 0ustar ghudsonlibuuid/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* tests/threads/prof1.c */ /* * Copyright (C) 2004 by the Massachusetts Institute of Technology. * All rights reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #include #include #include #include #include #include #include #include #include #include #include int nthreads = 10; unsigned int delay = 3600; volatile int done = 0; /* XXX hack */ const char *path = "/tmp/foo1.conf:/tmp/foo.conf"; const char *filename = "/tmp/foo.conf"; const char *prog; static void *worker(void *arg) { profile_t p; long err; int i; const char *const names[] = { "one", "two", "three", 0 }; char **values; const char *mypath = (random() & 1) ? path : filename; while (!done) { err = profile_init_path(mypath, &p); if (err) { com_err(prog, err, "calling profile_init(\"%s\")", mypath); exit(1); } for (i = 0; i < 10; i++) { values = 0; err = profile_get_values(p, names, &values); if (err == 0 && values != 0) profile_free_list(values); } profile_release(p); } return 0; } static void *modifier(void *arg) { struct timespec req; while (!done) { req.tv_sec = 0; req.tv_nsec = random() & 499999999; nanosleep(&req, 0); utime(filename, 0); /* printf("."), fflush(stdout); */ } return 0; } int main(int argc, char *argv[]) { int i; pthread_t thr; prog = argv[0]; for (i = 0; i < nthreads; i++) { assert(0 == pthread_create(&thr, 0, worker, 0)); } sleep(1); pthread_create(&thr, 0, modifier, 0); sleep(delay); done = 1; sleep(2); return 0; } krb5-1.16/src/tests/threads/deps0000644000704600001450000000272113211554426016441 0ustar ghudsonlibuuid# # Generated makefile dependencies follow. # $(OUTPRE)t_rcache.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h \ $(top_srcdir)/include/k5-err.h $(top_srcdir)/include/k5-gmt_mktime.h \ $(top_srcdir)/include/k5-int-pkinit.h $(top_srcdir)/include/k5-int.h \ $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-plugin.h \ $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/k5-trace.h \ $(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/authdata_plugin.h \ $(top_srcdir)/include/krb5/plugin.h $(top_srcdir)/include/port-sockets.h \ $(top_srcdir)/include/socket-utils.h t_rcache.c $(OUTPRE)gss-perf.$(OBJEXT): $(BUILDTOP)/include/gssapi/gssapi.h \ $(BUILDTOP)/include/krb5/krb5.h $(COM_ERR_DEPS) $(top_srcdir)/include/krb5.h \ gss-perf.c $(OUTPRE)init_ctx.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/krb5/krb5.h $(COM_ERR_DEPS) $(top_srcdir)/include/k5-platform.h \ $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/krb5.h \ init_ctx.c $(OUTPRE)profread.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/profile.h \ $(COM_ERR_DEPS) $(top_srcdir)/include/k5-platform.h \ $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/krb5.h \ profread.c $(OUTPRE)prof1.$(OBJEXT): $(BUILDTOP)/include/profile.h \ $(COM_ERR_DEPS) prof1.c krb5-1.16/src/tests/threads/init_ctx.c0000644000704600001450000001711313211554426017551 0ustar ghudsonlibuuid/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* tests/threads/init_ctx.c */ /* * Copyright (C) 2009 by the Massachusetts Institute of Technology. * All rights reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ /* * krb5 context creation performance testing * initially contributed by Ken Raeburn */ #include "k5-platform.h" #include #include #include #include #include #define N_THREADS 4 #define ITER_COUNT 40000 static int init_krb5_first = 0; struct resource_info { struct timeval start_time, end_time; }; struct thread_info { pthread_t tid; struct resource_info r; }; static char *prog; static unsigned int n_threads = N_THREADS; static int iter_count = ITER_COUNT; static int do_pause; static void usage (void) __attribute__((noreturn)); static void usage () { fprintf (stderr, "usage: %s [ options ]\n", prog); fprintf (stderr, "options:\n"); fprintf (stderr, "\t-t N\tspecify number of threads (default %d)\n", N_THREADS); fprintf (stderr, "\t-i N\tset iteration count (default %d)\n", ITER_COUNT); fprintf (stderr, "\t-K\tinitialize a krb5_context for the duration\n"); fprintf (stderr, "\t-P\tpause briefly after starting, to allow attaching dtrace/strace/etc\n"); exit (1); } static int numarg (char *arg) { char *end; long val; val = strtol (arg, &end, 10); if (*arg == 0 || *end != 0) { fprintf (stderr, "invalid numeric argument '%s'\n", arg); usage (); } if (val >= 1 && val <= INT_MAX) return val; fprintf (stderr, "out of range numeric value %ld (1..%d)\n", val, INT_MAX); usage (); } static char optstring[] = "t:i:KP"; static void process_options (int argc, char *argv[]) { int c; prog = strrchr (argv[0], '/'); if (prog) prog++; else prog = argv[0]; while ((c = getopt (argc, argv, optstring)) != -1) { switch (c) { case '?': case ':': usage (); break; case 't': n_threads = numarg (optarg); if (n_threads >= SIZE_MAX / sizeof (struct thread_info)) { n_threads = SIZE_MAX / sizeof (struct thread_info); fprintf (stderr, "limiting n_threads to %u\n", n_threads); } break; case 'i': iter_count = numarg (optarg); break; case 'K': init_krb5_first = 1; break; case 'P': do_pause = 1; break; } } if (argc != optind) usage (); } static long double tvsub (struct timeval t1, struct timeval t2) { /* POSIX says .tv_usec is signed. */ return (t1.tv_sec - t2.tv_sec + (long double) 1.0e-6 * (t1.tv_usec - t2.tv_usec)); } static struct timeval now (void) { struct timeval tv; if (gettimeofday (&tv, NULL) < 0) { perror ("gettimeofday"); exit (1); } return tv; } static void run_iterations (struct resource_info *r) { int i; krb5_error_code err; krb5_context ctx; r->start_time = now (); for (i = 0; i < iter_count; i++) { err = krb5_init_context(&ctx); if (err) { com_err(prog, err, "initializing krb5 context"); exit(1); } krb5_free_context(ctx); } r->end_time = now (); } static void * thread_proc (void *p) { run_iterations (p); return 0; } static struct thread_info *tinfo; static krb5_context kctx; static struct rusage start, finish; static struct timeval start_time, finish_time; int main (int argc, char *argv[]) { long double user, sys, wallclock, total; unsigned int i; process_options (argc, argv); /* * Some places in the krb5 library cache data globally. * This option allows you to test the effect of that. */ if (init_krb5_first && krb5_init_context (&kctx) != 0) { fprintf (stderr, "krb5_init_context error\n"); exit (1); } tinfo = calloc (n_threads, sizeof (*tinfo)); if (tinfo == NULL) { perror ("calloc"); exit (1); } printf ("Threads: %d iterations: %d\n", n_threads, iter_count); if (do_pause) { printf ("pid %lu napping...\n", (unsigned long) getpid ()); sleep (10); } printf ("starting...\n"); /* And *now* we start measuring the performance. */ if (getrusage (RUSAGE_SELF, &start) < 0) { perror ("getrusage"); exit (1); } start_time = now (); #define foreach_thread(IDXVAR) for (IDXVAR = 0; IDXVAR < n_threads; IDXVAR++) foreach_thread (i) { int err; err = pthread_create (&tinfo[i].tid, NULL, thread_proc, &tinfo[i].r); if (err) { fprintf (stderr, "pthread_create: %s\n", strerror (err)); exit (1); } } foreach_thread (i) { int err; void *val; err = pthread_join (tinfo[i].tid, &val); if (err) { fprintf (stderr, "pthread_join: %s\n", strerror (err)); exit (1); } } finish_time = now (); if (getrusage (RUSAGE_SELF, &finish) < 0) { perror ("getrusage"); exit (1); } if (init_krb5_first) krb5_free_context (kctx); foreach_thread (i) { printf ("Thread %2d: elapsed time %Lfs\n", i, tvsub (tinfo[i].r.end_time, tinfo[i].r.start_time)); } wallclock = tvsub (finish_time, start_time); /* * Report on elapsed time and CPU usage. Depending what * performance issue you're chasing down, different values may be * of particular interest, so report all the info we've got. */ printf ("Overall run time with %d threads = %Lfs, %Lfms per iteration.\n", n_threads, wallclock, 1000 * wallclock / iter_count); user = tvsub (finish.ru_utime, start.ru_utime); sys = tvsub (finish.ru_stime, start.ru_stime); total = user + sys; printf ("CPU usage: user=%Lfs sys=%Lfs total=%Lfs.\n", user, sys, total); printf ("Utilization: user=%5.1Lf%% sys=%5.1Lf%% total=%5.1Lf%%\n", 100 * user / wallclock, 100 * sys / wallclock, 100 * total / wallclock); printf ("Util/thread: user=%5.1Lf%% sys=%5.1Lf%% total=%5.1Lf%%\n", 100 * user / wallclock / n_threads, 100 * sys / wallclock / n_threads, 100 * total / wallclock / n_threads); printf ("Total CPU use per iteration per thread: %Lfms\n", 1000 * total / n_threads / iter_count); free(tinfo); return 0; } krb5-1.16/src/tests/threads/gss-perf.c0000644000704600001450000003372613211554426017466 0ustar ghudsonlibuuid/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* tests/threads/gss-perf.c */ /* * Copyright (C) 2009 by the Massachusetts Institute of Technology. * All rights reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ /* * GSSAPI performance testing * initially contributed by Ken Raeburn */ /* * Possible to-do items: * - init-mutual testing (process msg back from accept) * - wrap/unwrap testing (one init/accept per thread, loop on wrap/unwrap) * - wrap/unwrap MT testing (one init/accept for process) ? * - init+accept with replay cache * - default to target "host@localhostname" * - input ccache option? * * Also, perhaps try to simulate certain application patterns, like * init/accept, exchange N messages with wrap/unwrap, destroy context, * all in a loop in M parallel threads. */ #include #include #include #include #include #include #include #include #include #include #include #define N_THREADS 2 #define ITER_COUNT 10000 static int init_krb5_first = 0; struct resource_info { struct timeval start_time, end_time; }; struct thread_info { pthread_t tid; struct resource_info r; }; static gss_name_t target; static char *prog, *target_name; static unsigned int n_threads = N_THREADS; static int iter_count = ITER_COUNT; static int do_pause, do_mutual; static int test_init, test_accept; static void usage (void) __attribute__((noreturn)); static void set_target (char *); static void usage () { fprintf (stderr, "usage: %s [ options ] service-name\n", prog); fprintf (stderr, " service-name\tGSSAPI host-based service name (e.g., 'host@FQDN')\n"); fprintf (stderr, "options:\n"); fprintf (stderr, "\t-I\ttest gss_init_sec_context\n"); fprintf (stderr, "\t-A\ttest gss_accept_sec_context\n"); fprintf (stderr, "\t-k K\tspecify keytab (remember FILE: or other prefix!)\n"); fprintf (stderr, "\t-t N\tspecify number of threads (default %d)\n", N_THREADS); fprintf (stderr, "\t-i N\tset iteration count (default %d)\n", ITER_COUNT); fprintf (stderr, "\t-m\tenable mutual authentication flag (but don't do the additional calls)\n"); fprintf (stderr, "\t-K\tinitialize a krb5_context for the duration\n"); fprintf (stderr, "\t-P\tpause briefly after starting, to allow attaching dtrace/strace/etc\n"); exit (1); } static int numarg (char *arg) { char *end; long val; val = strtol (arg, &end, 10); if (*arg == 0 || *end != 0) { fprintf (stderr, "invalid numeric argument '%s'\n", arg); usage (); } if (val >= 1 && val <= INT_MAX) return val; fprintf (stderr, "out of range numeric value %ld (1..%d)\n", val, INT_MAX); usage (); } static char optstring[] = "k:t:i:KPmIA"; static void process_options (int argc, char *argv[]) { int c; prog = strrchr (argv[0], '/'); if (prog) prog++; else prog = argv[0]; while ((c = getopt (argc, argv, optstring)) != -1) { switch (c) { case '?': case ':': usage (); break; case 'k': setenv ("KRB5_KTNAME", optarg, 1); break; case 't': n_threads = numarg (optarg); if (n_threads >= SIZE_MAX / sizeof (struct thread_info)) { n_threads = SIZE_MAX / sizeof (struct thread_info); fprintf (stderr, "limiting n_threads to %u\n", n_threads); } break; case 'i': iter_count = numarg (optarg); break; case 'K': init_krb5_first = 1; break; case 'P': do_pause = 1; break; case 'I': test_init = 1; break; case 'A': test_accept = 1; break; } } if (argc == optind + 1) set_target (argv[optind]); else usage (); if (test_init && test_accept) { fprintf (stderr, "-I and -A are mutually exclusive\n"); usage (); } if (test_init == 0 && test_accept == 0) test_init = 1; } static void display_a_status (const char *s_type, OM_uint32 type, OM_uint32 val) { OM_uint32 mctx = 0; OM_uint32 maj_stat, min_stat; gss_buffer_desc msg = GSS_C_EMPTY_BUFFER; do { maj_stat = gss_display_status (&min_stat, val, type, GSS_C_NO_OID, &mctx, &msg); if (maj_stat != GSS_S_COMPLETE) { fprintf (stderr, "error getting display form of %s status code %#lx\n", s_type, (unsigned long) val); exit (1); } fprintf (stderr, " %s: %.*s\n", s_type, (int) msg.length, (char *) msg.value); gss_release_buffer (&min_stat, &msg); } while (mctx != 0); } static void gss_error(const char *where, OM_uint32 maj_stat, OM_uint32 min_stat) { fprintf (stderr, "%s: %s:\n", prog, where); display_a_status ("major", GSS_C_GSS_CODE, maj_stat); display_a_status ("minor", GSS_C_MECH_CODE, min_stat); exit (1); } static void do_accept (gss_buffer_desc *msg, int iter) { OM_uint32 maj_stat, min_stat; gss_name_t client = GSS_C_NO_NAME; gss_buffer_desc reply = GSS_C_EMPTY_BUFFER; gss_OID oid = GSS_C_NO_OID; gss_ctx_id_t ctx = GSS_C_NO_CONTEXT; OM_uint32 flags = do_mutual ? GSS_C_MUTUAL_FLAG : 0; reply.value = NULL; reply.length = 0; maj_stat = gss_accept_sec_context (&min_stat, &ctx, GSS_C_NO_CREDENTIAL, msg, GSS_C_NO_CHANNEL_BINDINGS, &client, &oid, &reply, &flags, NULL, /* time_rec */ NULL); /* del_cred_handle */ if (maj_stat != GSS_S_COMPLETE && maj_stat != GSS_S_CONTINUE_NEEDED) { fprintf (stderr, "pid %lu thread %#lx failing in iteration %d\n", (unsigned long) getpid (), (unsigned long) pthread_self (), iter); gss_error ("accepting context", maj_stat, min_stat); } gss_release_buffer (&min_stat, &reply); if (ctx != GSS_C_NO_CONTEXT) gss_delete_sec_context (&min_stat, &ctx, GSS_C_NO_BUFFER); gss_release_name (&min_stat, &client); } static gss_buffer_desc do_init () { OM_uint32 maj_stat, min_stat; gss_ctx_id_t ctx = GSS_C_NO_CONTEXT; OM_uint32 flags = 0, ret_flags = 0; gss_buffer_desc msg = GSS_C_EMPTY_BUFFER; if (do_mutual) flags |= GSS_C_MUTUAL_FLAG; msg.value = NULL; msg.length = 0; maj_stat = gss_init_sec_context (&min_stat, GSS_C_NO_CREDENTIAL, &ctx, target, GSS_C_NO_OID, flags, 0, NULL, /* no channel bindings */ NULL, /* no previous token */ NULL, /* ignore mech type */ &msg, &ret_flags, NULL); /* time_rec */ if (maj_stat != GSS_S_COMPLETE && maj_stat != GSS_S_CONTINUE_NEEDED) { gss_error ("initiating", maj_stat, min_stat); } if (ctx != GSS_C_NO_CONTEXT) gss_delete_sec_context (&min_stat, &ctx, GSS_C_NO_BUFFER); return msg; } static void set_target (char *name) { OM_uint32 maj_stat, min_stat; gss_buffer_desc namebuf; target_name = name; namebuf.value = name; namebuf.length = strlen (name); maj_stat = gss_import_name (&min_stat, &namebuf, GSS_C_NT_HOSTBASED_SERVICE, &target); if (maj_stat != GSS_S_COMPLETE) gss_error ("importing target name", maj_stat, min_stat); } static long double tvsub (struct timeval t1, struct timeval t2) { /* POSIX says .tv_usec is signed. */ return (t1.tv_sec - t2.tv_sec + (long double) 1.0e-6 * (t1.tv_usec - t2.tv_usec)); } static struct timeval now (void) { struct timeval tv; if (gettimeofday (&tv, NULL) < 0) { perror ("gettimeofday"); exit (1); } return tv; } static gss_buffer_desc init_msg; static void run_iterations (struct resource_info *r) { int i; OM_uint32 min_stat; r->start_time = now (); for (i = 0; i < iter_count; i++) { if (test_init) { gss_buffer_desc msg = do_init (); gss_release_buffer (&min_stat, &msg); } else if (test_accept) { do_accept (&init_msg, i); } else assert (test_init || test_accept); } r->end_time = now (); } static void * thread_proc (void *p) { run_iterations (p); return 0; } static struct thread_info *tinfo; static krb5_context kctx; static struct rusage start, finish; static struct timeval start_time, finish_time; int main (int argc, char *argv[]) { long double user, sys, wallclock, total; unsigned int i; /* Probably should have a command-line option controlling this, but if a replay cache is used, we can't do just one init_sec_context and easily time just the accept_sec_context side. */ setenv ("KRB5RCACHETYPE", "none", 1); process_options (argc, argv); /* * Some places in the krb5 library cache data globally. * This option allows you to test the effect of that. */ if (init_krb5_first && krb5_init_context (&kctx) != 0) { fprintf (stderr, "krb5_init_context error\n"); exit (1); } tinfo = calloc (n_threads, sizeof (*tinfo)); if (tinfo == NULL) { perror ("calloc"); exit (1); } printf ("Test: %s threads: %d iterations: %d target: %s\n", test_init ? "init" : "accept", n_threads, iter_count, target_name ? target_name : "(NONE)"); if (do_pause) { printf ("pid %lu napping...\n", (unsigned long) getpid ()); sleep (10); } /* * Some tests use one message and process it over and over. Even * if not, this sort of "primes" things by fetching any needed * tickets just once. */ init_msg = do_init (); printf ("starting...\n"); /* And *now* we start measuring the performance. */ if (getrusage (RUSAGE_SELF, &start) < 0) { perror ("getrusage"); exit (1); } start_time = now (); #define foreach_thread(IDXVAR) for (IDXVAR = 0; IDXVAR < n_threads; IDXVAR++) foreach_thread (i) { int err; err = pthread_create (&tinfo[i].tid, NULL, thread_proc, &tinfo[i].r); if (err) { fprintf (stderr, "pthread_create: %s\n", strerror (err)); exit (1); } } foreach_thread (i) { int err; void *val; err = pthread_join (tinfo[i].tid, &val); if (err) { fprintf (stderr, "pthread_join: %s\n", strerror (err)); exit (1); } } finish_time = now (); if (getrusage (RUSAGE_SELF, &finish) < 0) { perror ("getrusage"); exit (1); } if (init_krb5_first) krb5_free_context (kctx); foreach_thread (i) { printf ("Thread %2d: elapsed time %Lfs\n", i, tvsub (tinfo[i].r.end_time, tinfo[i].r.start_time)); } wallclock = tvsub (finish_time, start_time); /* * Report on elapsed time and CPU usage. Depending what * performance issue you're chasing down, different values may be * of particular interest, so report all the info we've got. */ printf ("Overall run time with %d threads = %Lfs, %Lfms per iteration.\n", n_threads, wallclock, 1000 * wallclock / iter_count); user = tvsub (finish.ru_utime, start.ru_utime); sys = tvsub (finish.ru_stime, start.ru_stime); total = user + sys; printf ("CPU usage: user=%Lfs sys=%Lfs total=%Lfs.\n", user, sys, total); printf ("Utilization: user=%5.1Lf%% sys=%5.1Lf%% total=%5.1Lf%%\n", 100 * user / wallclock, 100 * sys / wallclock, 100 * total / wallclock); printf ("Util/thread: user=%5.1Lf%% sys=%5.1Lf%% total=%5.1Lf%%\n", 100 * user / wallclock / n_threads, 100 * sys / wallclock / n_threads, 100 * total / wallclock / n_threads); printf ("Total CPU use per iteration per thread: %Lfms\n", 1000 * total / n_threads / iter_count); return 0; } krb5-1.16/src/tests/threads/t_rcache.c0000644000704600001450000001630113211554426017476 0ustar ghudsonlibuuid/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* tests/threads/t_rcache.c */ /* * Copyright (C) 2006 by the Massachusetts Institute of Technology. * All rights reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #include "k5-int.h" #include #include #include krb5_context ctx; krb5_rcache rcache; krb5_data piece = { .data = "hello", .length = 5 }; time_t end_time; const char *prog; struct tinfo { time_t now; unsigned long my_ctime; unsigned int my_cusec; unsigned int total; int idx; }; #define DEFAULT_N_THREADS 2 #define DEFAULT_INTERVAL 20 /* 5 * 60 */ int init_once = 0; int n_threads = DEFAULT_N_THREADS; int interval = DEFAULT_INTERVAL; int *ip; static void wait_for_tick () { time_t now, next; now = time(0); do { next = time(0); } while (now == next); } static void try_one (struct tinfo *t) { krb5_donot_replay r; krb5_error_code err; char buf[100], buf2[100]; krb5_rcache my_rcache; snprintf(buf, sizeof(buf), "host/all-in-one.mit.edu/%p@ATHENA.MIT.EDU", buf); r.server = buf; r.client = (t->my_cusec & 7) + "abcdefgh@ATHENA.MIT.EDU"; r.msghash = NULL; if (t->now != t->my_ctime) { if (t->my_ctime != 0) { snprintf(buf2, sizeof(buf2), "%3d: %ld %5d\n", t->idx, t->my_ctime, t->my_cusec); printf("%s", buf2); } t->my_ctime = t->now; t->my_cusec = 1; } else t->my_cusec++; r.ctime = t->my_ctime; r.cusec = t->my_cusec; if (!init_once) { err = krb5_get_server_rcache(ctx, &piece, &my_rcache); if (err) { const char *msg = krb5_get_error_message(ctx, err); fprintf(stderr, "%s: %s while initializing replay cache\n", prog, msg); krb5_free_error_message(ctx, msg); exit(1); } } else my_rcache = rcache; err = krb5_rc_store(ctx, my_rcache, &r); if (err) { com_err(prog, err, "storing in replay cache"); exit(1); } if (!init_once) krb5_rc_close(ctx, my_rcache); } static void *run_a_loop (void *x) { struct tinfo t = { 0 }; /* int chr = "ABCDEFGHIJKLMNOPQRSTUVWXYZ_"[(*(int*)x) % 27]; */ t.now = time(0); t.idx = *(int *)x; while (t.now != time(0)) ; t.now = time(0); while (t.now < end_time) { t.now = time(0); try_one(&t); t.total++; #if 0 printf("%c", chr); fflush(stdout); #endif } /* printf("thread %u total %u\n", (unsigned) ((int *)x-ip), t.total);*/ *(int*)x = t.total; return 0; } static void usage(void) { fprintf (stderr, "usage: %s [ options ]\n", prog); fprintf (stderr, "options:\n"); fprintf (stderr, "\t-1\tcreate one rcache handle for process\n"); fprintf (stderr, "\t-t N\tnumber of threads to create (default: %d)\n", DEFAULT_N_THREADS); fprintf (stderr, "\t-i N\tinterval to run test over, in seconds (default: %d)\n", DEFAULT_INTERVAL); exit(1); } static const char optstring[] = "1t:i:"; static void process_options (int argc, char *argv[]) { int c; prog = argv[0]; while ((c = getopt(argc, argv, optstring)) != -1) { switch (c) { case '?': case ':': default: usage (); case '1': init_once = 1; break; case 't': n_threads = atoi (optarg); if (n_threads < 1 || n_threads > 10000) usage (); break; case 'i': interval = atoi (optarg); if (interval < 2 || n_threads > 100000) usage (); break; } } } int main (int argc, char *argv[]) { krb5_error_code err; int i; unsigned long sum; process_options (argc, argv); err = krb5_init_context(&ctx); if (err) { com_err(prog, err, "initializing context"); return 1; } /* * For consistency, run the tests without an existing replay * cache. Since there isn't a way to ask the library for the * pathname that would be used for the rcache, we create an rcache * object and then destroy it. */ err = krb5_get_server_rcache(ctx, &piece, &rcache); if (err) { const char *msg = krb5_get_error_message(ctx, err); fprintf(stderr, "%s: %s while initializing replay cache\n", prog, msg); krb5_free_error_message(ctx, msg); return 1; } err = krb5_rc_destroy(ctx, rcache); if (err) { const char *msg = krb5_get_error_message(ctx, err); fprintf(stderr, "%s: %s while destroying old replay cache\n", prog, msg); krb5_free_error_message(ctx, msg); return 1; } rcache = NULL; if (init_once) { err = krb5_get_server_rcache(ctx, &piece, &rcache); if (err) { const char *msg = krb5_get_error_message(ctx, err); fprintf(stderr, "%s: %s while initializing new replay cache\n", prog, msg); krb5_free_error_message(ctx, msg); return 1; } } ip = malloc(sizeof(int) * n_threads); if (ip == 0 && n_threads > 0) { perror("malloc"); exit(1); } for (i = 0; i < n_threads; i++) ip[i] = i; wait_for_tick (); end_time = time(0) + interval; for (i = 0; i < n_threads; i++) { pthread_t new_thread; int perr; perr = pthread_create(&new_thread, 0, run_a_loop, &ip[i]); if (perr) { errno = perr; perror("pthread_create"); exit(1); } } while (time(0) < end_time + 1) sleep(1); sum = 0; for (i = 0; i < n_threads; i++) { sum += ip[i]; printf("thread %d total %5d, about %.1f per second\n", i, ip[i], ((double) ip[i])/interval); } printf("total %lu in %d seconds, avg ~%.1f/sec, ~%.1f/sec/thread\n", sum, interval, ((double)sum)/interval, ((double)sum)/interval/n_threads); free(ip); if (init_once) krb5_rc_close(ctx, rcache); krb5_free_context(ctx); return 0; } krb5-1.16/src/tests/threads/Makefile.in0000644000704600001450000000221413211554426017625 0ustar ghudsonlibuuid# The test programs here are not built or run by default. You can # build a specific test program with "make gss-perf" or similar. # "make run-t_rcache" will run the replay cache test program in the # proper environment. mydir=tests$(S)threads BUILDTOP=$(REL)..$(S).. SRCS=$(srcdir)/t_rcache.c \ $(srcdir)/gss-perf.c \ $(srcdir)/init_ctx.c \ $(srcdir)/profread.c \ $(srcdir)/prof1.c all: run-t_rcache: t_rcache $(RUN_TEST) ./t_rcache t_rcache: t_rcache.o $(KRB5_BASE_DEPLIBS) $(CC_LINK) -o t_rcache t_rcache.o $(KRB5_BASE_LIBS) $(THREAD_LINKOPTS) prof1: prof1.o $(KRB5_BASE_DEPLIBS) $(CC_LINK) -o prof1 prof1.o $(KRB5_BASE_LIBS) $(THREAD_LINKOPTS) prof1.o: prof1.c gss-perf: gss-perf.o $(KRB5_BASE_DEPLIBS) $(GSS_DEPLIBS) $(CC_LINK) $(PTHREAD_CFLAGS) -o gss-perf gss-perf.o $(GSS_LIBS) $(KRB5_BASE_LIBS) $(THREAD_LINKOPTS) init_ctx: init_ctx.o $(KRB5_BASE_DEPLIBS) $(CC_LINK) $(PTHREAD_CFLAGS) -o init_ctx init_ctx.o $(KRB5_BASE_LIBS) $(THREAD_LINKOPTS) profread: profread.o $(KRB5_BASE_DEPLIBS) $(CC_LINK) $(PTHREAD_CFLAGS) -o profread profread.o $(KRB5_BASE_LIBS) $(THREAD_LINKOPTS) install: clean: $(RM) *.o t_rcache syms prof1 gss-perf krb5-1.16/src/tests/kdbtest.c0000644000704600001450000003734613211554426015750 0ustar ghudsonlibuuid/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* tests/kdbtest.c - test program to exercise KDB modules */ /* * Copyright (C) 2012 by the Massachusetts Institute of Technology. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ /* * This test program uses libkdb5 APIs to exercise as much of the LDAP and DB2 * back ends. */ #include #include #include static krb5_context ctx; #define CHECK(code) check(code, __LINE__) #define CHECK_COND(val) check_cond(val, __LINE__) static void check(krb5_error_code code, int lineno) { const char *errmsg; if (code) { errmsg = krb5_get_error_message(ctx, code); fprintf(stderr, "Unexpected error at line %d: %s\n", lineno, errmsg); krb5_free_error_message(ctx, errmsg); exit(1); } } static void check_cond(int value, int lineno) { if (!value) { fprintf(stderr, "Unexpected result at line %d\n", lineno); exit(1); } } static krb5_data princ_data[2] = { { KV5M_DATA, 6, "xy*(z)" }, { KV5M_DATA, 12, "+<> *()\\#\",;" } }; static krb5_principal_data sample_princ = { KV5M_PRINCIPAL, { KV5M_DATA, 11, "KRBTEST.COM" }, princ_data, 2, KRB5_NT_UNKNOWN }; static krb5_principal_data xrealm_princ = { KV5M_PRINCIPAL, { KV5M_DATA, 12, "KRBTEST2.COM" }, princ_data, 2, KRB5_NT_UNKNOWN }; #define U(x) (unsigned char *)x /* * tl1 through tl4 are normalized to attributes in the LDAP back end. tl5 is * stored as untranslated tl-data. tl3 contains an encoded osa_princ_ent with * a policy reference to "". */ static krb5_tl_data tl5 = { NULL, KRB5_TL_MKVNO, 2, U("\0\1") }; static krb5_tl_data tl4 = { &tl5, KRB5_TL_LAST_ADMIN_UNLOCK, 4, U("\6\0\0\0") }; static krb5_tl_data tl3 = { &tl4, KRB5_TL_KADM_DATA, 32, U("\x12\x34\x5C\x01\x00\x00\x00\x08" "\x3C\x74\x65\x73\x74\x2A\x3E\x00" "\x00\x00\x08\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00") }; static krb5_tl_data tl2 = { &tl3, KRB5_TL_MOD_PRINC, 8, U("\5\6\7\0x@Y\0") }; static krb5_tl_data tl1 = { &tl2, KRB5_TL_LAST_PWD_CHANGE, 4, U("\1\2\3\4") }; /* An encoded osa_print_enc with no policy reference. */ static krb5_tl_data tl_no_policy = { NULL, KRB5_TL_KADM_DATA, 24, U("\x12\x34\x5C\x01\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x02\x00\x00\x00\x00") }; static krb5_key_data keys[] = { { 2, /* key_data_ver */ 2, /* key_data_kvno */ { ENCTYPE_AES256_CTS_HMAC_SHA1_96, KRB5_KDB_SALTTYPE_SPECIAL }, { 32, 7 }, { U("\x17\xF2\x75\xF2\x95\x4F\x2E\xD1" "\xF9\x0C\x37\x7B\xA7\xF4\xD6\xA3" "\x69\xAA\x01\x36\xE0\xBF\x0C\x92" "\x7A\xD6\x13\x3C\x69\x37\x59\xA9"), U("expsalt") } }, { 2, /* key_data_ver */ 2, /* key_data_kvno */ { ENCTYPE_AES128_CTS_HMAC_SHA1_96, 0 }, { 16, 0 }, { U("\xDC\xEE\xB7\x0B\x3D\xE7\x65\x62" "\xE6\x89\x22\x6C\x76\x42\x91\x48"), NULL } } }; #undef U static char polname[] = ""; static krb5_db_entry sample_entry = { 0, KRB5_KDB_V1_BASE_LENGTH, /* mask */ KADM5_PRINCIPAL | KADM5_PRINC_EXPIRE_TIME | KADM5_PW_EXPIRATION | KADM5_ATTRIBUTES | KADM5_MAX_LIFE | KADM5_POLICY | KADM5_MAX_RLIFE | KADM5_LAST_SUCCESS | KADM5_LAST_FAILED | KADM5_FAIL_AUTH_COUNT | KADM5_KEY_DATA | KADM5_TL_DATA, /* attributes */ KRB5_KDB_REQUIRES_PRE_AUTH | KRB5_KDB_REQUIRES_HW_AUTH | KRB5_KDB_DISALLOW_SVR, 1234, /* max_life */ 5678, /* max_renewable_life */ 9012, /* expiration */ 3456, /* pw_expiration */ 1, /* last_success */ 5, /* last_failed */ 2, /* fail_auth_count */ 5, /* n_tl_data */ 2, /* n_key_data */ 0, NULL, /* e_length, e_data */ &sample_princ, &tl1, keys }; static osa_policy_ent_rec sample_policy = { 0, /* version */ polname, /* name */ 1357, /* pw_min_life */ 100, /* pw_max_life */ 6, /* pw_min_length */ 2, /* pw_min_classes */ 3, /* pw_history_num */ 0, /* policy_refcnt */ 2, /* pw_max_fail */ 60, /* pw_failcnt_interval */ 120, /* pw_lockout_duration */ 0, /* attributes */ 2468, /* max_life */ 3579, /* max_renewable_life */ "aes", /* allowed_keysalts */ 0, NULL /* n_tl_data, tl_data */ }; /* Compare pol against sample_policy. */ static void check_policy(osa_policy_ent_t pol) { CHECK_COND(strcmp(pol->name, sample_policy.name) == 0); CHECK_COND(pol->pw_min_life == sample_policy.pw_min_life); CHECK_COND(pol->pw_max_life == sample_policy.pw_max_life); CHECK_COND(pol->pw_min_length == sample_policy.pw_min_length); CHECK_COND(pol->pw_min_classes == sample_policy.pw_min_classes); CHECK_COND(pol->pw_history_num == sample_policy.pw_history_num); CHECK_COND(pol->pw_max_life == sample_policy.pw_max_life); CHECK_COND(pol->pw_failcnt_interval == sample_policy.pw_failcnt_interval); CHECK_COND(pol->pw_lockout_duration == sample_policy.pw_lockout_duration); CHECK_COND(pol->attributes == sample_policy.attributes); CHECK_COND(pol->max_life == sample_policy.max_life); CHECK_COND(pol->max_renewable_life == sample_policy.max_renewable_life); CHECK_COND(strcmp(pol->allowed_keysalts, sample_policy.allowed_keysalts) == 0); } /* Compare ent against sample_entry. */ static void check_entry(krb5_db_entry *ent) { krb5_int16 i, j; krb5_key_data *k1, *k2; krb5_tl_data *tl, etl; CHECK_COND(ent->attributes == sample_entry.attributes); CHECK_COND(ent->max_life == sample_entry.max_life); CHECK_COND(ent->max_renewable_life == sample_entry.max_renewable_life); CHECK_COND(ent->expiration == sample_entry.expiration); CHECK_COND(ent->pw_expiration == sample_entry.pw_expiration); CHECK_COND(ent->last_success == sample_entry.last_success); CHECK_COND(ent->last_failed == sample_entry.last_failed); CHECK_COND(ent->fail_auth_count == sample_entry.fail_auth_count); CHECK_COND(krb5_principal_compare(ctx, ent->princ, sample_entry.princ)); CHECK_COND(ent->n_key_data == sample_entry.n_key_data); for (i = 0; i < ent->n_key_data; i++) { k1 = &ent->key_data[i]; k2 = &sample_entry.key_data[i]; CHECK_COND(k1->key_data_ver == k2->key_data_ver); CHECK_COND(k1->key_data_kvno == k2->key_data_kvno); for (j = 0; j < k1->key_data_ver; j++) { CHECK_COND(k1->key_data_type[j] == k2->key_data_type[j]); CHECK_COND(k1->key_data_length[j] == k2->key_data_length[j]); CHECK_COND(memcmp(k1->key_data_contents[j], k2->key_data_contents[j], k1->key_data_length[j]) == 0); } } for (tl = sample_entry.tl_data; tl != NULL; tl = tl->tl_data_next) { etl.tl_data_type = tl->tl_data_type; CHECK(krb5_dbe_lookup_tl_data(ctx, ent, &etl)); CHECK_COND(tl->tl_data_length == etl.tl_data_length); CHECK_COND(memcmp(tl->tl_data_contents, etl.tl_data_contents, tl->tl_data_length) == 0); } } /* Audit a successful or failed preauth attempt for *entp. Then reload *entp * (by fetching sample_princ) so we can see the effect. */ static void sim_preauth(krb5_timestamp authtime, krb5_boolean ok, krb5_db_entry **entp) { /* Both back ends ignore the request, local_addr, and remote_addr * parameters for now. */ krb5_db_audit_as_req(ctx, NULL, NULL, NULL, *entp, *entp, authtime, ok ? 0 : KRB5KDC_ERR_PREAUTH_FAILED); krb5_db_free_principal(ctx, *entp); CHECK(krb5_db_get_principal(ctx, &sample_princ, 0, entp)); } static krb5_error_code iter_princ_handler(void *data, krb5_db_entry *ent) { int *count = data; CHECK_COND(krb5_principal_compare(ctx, ent->princ, sample_entry.princ)); (*count)++; return 0; } static void iter_pol_handler(void *data, osa_policy_ent_t pol) { int *count = data; CHECK_COND(strcmp(pol->name, sample_policy.name) == 0); (*count)++; } int main() { krb5_db_entry *ent; osa_policy_ent_t pol; krb5_pa_data **e_data; const char *status; int count; CHECK(krb5_init_context_profile(NULL, KRB5_INIT_CONTEXT_KDC, &ctx)); /* If we can, revert to requiring all entries match sample_princ in * iter_princ_handler */ CHECK_COND(krb5_db_inited(ctx) != 0); CHECK(krb5_db_create(ctx, NULL)); CHECK(krb5_db_inited(ctx)); CHECK(krb5_db_fini(ctx)); CHECK_COND(krb5_db_inited(ctx) != 0); CHECK_COND(krb5_db_inited(ctx) != 0); CHECK(krb5_db_open(ctx, NULL, KRB5_KDB_OPEN_RW | KRB5_KDB_SRV_TYPE_ADMIN)); CHECK(krb5_db_inited(ctx)); /* Manipulate a policy, leaving it in place at the end. */ CHECK_COND(krb5_db_put_policy(ctx, &sample_policy) != 0); CHECK_COND(krb5_db_delete_policy(ctx, polname) != 0); CHECK_COND(krb5_db_get_policy(ctx, polname, &pol) == KRB5_KDB_NOENTRY); CHECK(krb5_db_create_policy(ctx, &sample_policy)); CHECK_COND(krb5_db_create_policy(ctx, &sample_policy) != 0); CHECK(krb5_db_get_policy(ctx, polname, &pol)); check_policy(pol); pol->pw_min_length--; CHECK(krb5_db_put_policy(ctx, pol)); krb5_db_free_policy(ctx, pol); CHECK(krb5_db_get_policy(ctx, polname, &pol)); CHECK_COND(pol->pw_min_length == sample_policy.pw_min_length - 1); krb5_db_free_policy(ctx, pol); CHECK(krb5_db_delete_policy(ctx, polname)); CHECK_COND(krb5_db_put_policy(ctx, &sample_policy) != 0); CHECK_COND(krb5_db_delete_policy(ctx, polname) != 0); CHECK_COND(krb5_db_get_policy(ctx, polname, &pol) == KRB5_KDB_NOENTRY); CHECK(krb5_db_create_policy(ctx, &sample_policy)); count = 0; CHECK(krb5_db_iter_policy(ctx, NULL, iter_pol_handler, &count)); CHECK_COND(count == 1); /* Create a principal. */ CHECK_COND(krb5_db_delete_principal(ctx, &sample_princ) == KRB5_KDB_NOENTRY); CHECK_COND(krb5_db_get_principal(ctx, &xrealm_princ, 0, &ent) == KRB5_KDB_NOENTRY); CHECK(krb5_db_put_principal(ctx, &sample_entry)); /* Putting again will fail with LDAP (due to KADM5_PRINCIPAL in mask) * but succeed with DB2, so don't check the result. */ (void)krb5_db_put_principal(ctx, &sample_entry); /* But it should succeed in both back ends with KADM5_LOAD in mask. */ sample_entry.mask |= KADM5_LOAD; CHECK(krb5_db_put_principal(ctx, &sample_entry)); sample_entry.mask &= ~KADM5_LOAD; /* Fetch and compare the added principal. */ CHECK(krb5_db_get_principal(ctx, &sample_princ, 0, &ent)); check_entry(ent); /* We can't set up a successful allowed-to-delegate check through existing * APIs yet, but we can make a failed check. */ CHECK_COND(krb5_db_check_allowed_to_delegate(ctx, &sample_princ, ent, &sample_princ) != 0); /* Exercise lockout code. */ /* Policy params: max_fail 2, failcnt_interval 60, lockout_duration 120 */ /* Initial state: last_success 1, last_failed 5, fail_auth_count 2, * last admin unlock 6 */ /* Check succeeds due to last admin unlock. */ CHECK(krb5_db_check_policy_as(ctx, NULL, ent, ent, 7, &status, &e_data)); /* Failure count resets to 1 due to last admin unlock. */ sim_preauth(8, FALSE, &ent); CHECK_COND(ent->fail_auth_count == 1 && ent->last_failed == 8); /* Failure count resets to 1 due to failcnt_interval */ sim_preauth(70, FALSE, &ent); CHECK_COND(ent->fail_auth_count == 1 && ent->last_failed == 70); /* Failure count resets to 0 due to successful preauth. */ sim_preauth(75, TRUE, &ent); CHECK_COND(ent->fail_auth_count == 0 && ent->last_success == 75); /* Failure count increments to 2 and stops incrementing. */ sim_preauth(80, FALSE, &ent); CHECK_COND(ent->fail_auth_count == 1 && ent->last_failed == 80); sim_preauth(100, FALSE, &ent); CHECK_COND(ent->fail_auth_count == 2 && ent->last_failed == 100); sim_preauth(110, FALSE, &ent); CHECK_COND(ent->fail_auth_count == 2 && ent->last_failed == 100); /* Check fails due to reaching maximum failure count. */ CHECK_COND(krb5_db_check_policy_as(ctx, NULL, ent, ent, 170, &status, &e_data) == KRB5KDC_ERR_CLIENT_REVOKED); /* Check succeeds after lockout_duration has passed. */ CHECK(krb5_db_check_policy_as(ctx, NULL, ent, ent, 230, &status, &e_data)); /* Failure count resets to 1 on next failure. */ sim_preauth(240, FALSE, &ent); CHECK_COND(ent->fail_auth_count == 1 && ent->last_failed == 240); /* Exercise LDAP code to clear a policy reference and to set the key * data on an existing principal. */ CHECK(krb5_dbe_update_tl_data(ctx, ent, &tl_no_policy)); ent->mask = KADM5_POLICY_CLR | KADM5_KEY_DATA; CHECK(krb5_db_put_principal(ctx, ent)); CHECK(krb5_db_delete_policy(ctx, polname)); /* Put the modified entry again (with KDB_TL_USER_INFO tl-data for LDAP) as * from a load operation. */ ent->mask = (sample_entry.mask & ~KADM5_POLICY) | KADM5_LOAD; CHECK(krb5_db_put_principal(ctx, ent)); /* Exercise LDAP code to create a new principal at a DN from * KDB_TL_USER_INFO tl-data. */ CHECK(krb5_db_delete_principal(ctx, &sample_princ)); CHECK(krb5_db_put_principal(ctx, ent)); krb5_db_free_principal(ctx, ent); /* Exercise principal iteration code. */ count = 0; CHECK(krb5_db_iterate(ctx, "xy*", iter_princ_handler, &count, 0)); CHECK_COND(count == 1); CHECK(krb5_db_fini(ctx)); CHECK_COND(krb5_db_inited(ctx) != 0); /* It might be nice to exercise krb5_db_destroy here, but the LDAP module * doesn't support it. */ krb5_free_context(ctx); return 0; } krb5-1.16/src/tests/hrealm.c0000644000704600001450000000611413211554426015545 0ustar ghudsonlibuuid/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* tests/hrealm.c - Test harness for host-realm interfaces */ /* * Copyright (C) 2012 by the Massachusetts Institute of Technology. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ /* * This program is intended to be run from a python script as: * * hrealm -h|-f|-d [hostname] * * Calls krb5_get_host_realm, krb5_get_fallback_host_realm, or * krb5_default_realm depending on the option given. For the first two * choices, hostname or NULL is passed as the argument. The results are * displayed one per line. */ #include "k5-int.h" static krb5_context ctx; static void check(krb5_error_code code) { const char *errmsg; if (code) { errmsg = krb5_get_error_message(ctx, code); fprintf(stderr, "%s\n", errmsg); krb5_free_error_message(ctx, errmsg); exit(1); } } static void display(char **realms) { while (realms != NULL && *realms != NULL) printf("%s\n", *realms++); } int main(int argc, char **argv) { krb5_data d; char **realms, *realm; check(krb5_init_context(&ctx)); /* Parse arguments. */ if (argc < 2 || argc > 3) abort(); if (strcmp(argv[1], "-d") == 0) { check(krb5_get_default_realm(ctx, &realm)); printf("%s\n", realm); krb5_free_default_realm(ctx, realm); } else if (strcmp(argv[1], "-h") == 0) { check(krb5_get_host_realm(ctx, argv[2], &realms)); display(realms); krb5_free_host_realm(ctx, realms); } else if (strcmp(argv[1], "-f") == 0) { assert(argc == 3); d = string2data(argv[2]); check(krb5_get_fallback_host_realm(ctx, &d, &realms)); display(realms); krb5_free_host_realm(ctx, realms); } else { abort(); } krb5_free_context(ctx); return 0; } krb5-1.16/src/tests/t_cve-2012-1014.py0000755000704600001450000000147113211554426016554 0ustar ghudsonlibuuid#!/usr/bin/python import base64 import socket from k5test import * realm = K5Realm() # CVE-2012-1014 KDC dereferences uninitialized pointer # Affects only krb5-1.10.x. s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) a = (hostname, realm.portbase) x1 = base64.b16decode('6A5E305BA103020105A2030201') x2 = base64.b16decode('A44F304DA007030500FEDCBA90A10E30' + '0CA003020101A10530031B0141A2031B' + '0141A30E300CA003020101A10530031B' + '0141A511180F31393934303631303036' + '303331375AA70302012AA80530030201' + '01') for x in range(11, 128): s.sendto(''.join([x1, chr(x), x2]), a) # Make sure kinit still works. realm.kinit(realm.user_princ, password('user')) success('CVE-2012-1014 regression test') krb5-1.16/src/tests/t_y2038.py0000644000704600001450000000626313211554426015620 0ustar ghudsonlibuuid#!/usr/bin/python from k5test import * # These tests will become much less important after the y2038 boundary # has elapsed, and may start exhibiting problems around the year 2075. if runenv.sizeof_time_t <= 4: skip_rest('y2038 timestamp tests', 'platform has 32-bit time_t') # Start a KDC running roughly 21 years in the future, after the y2038 # boundary. Set long maximum lifetimes for later tests. conf = {'realms': {'$realm': {'max_life': '9000d', 'max_renewable_life': '9000d'}}} realm = K5Realm(start_kdc=False, kdc_conf=conf) realm.start_kdc(['-T', '662256000']) # kinit without preauth should succeed with clock skew correction, but # will result in an expired ticket, because we sent an absolute end # time and didn't get a chance to correct it.. realm.kinit(realm.user_princ, password('user')) realm.run([kvno, realm.host_princ], expected_code=1, expected_msg='Ticket expired') # kinit with preauth should succeed and result in a valid ticket, as # we get a chance to correct the end time based on the KDC time. Try # with encrypted timestamp and encrypted challenge. realm.run([kadminl, 'modprinc', '+requires_preauth', 'user']) realm.kinit(realm.user_princ, password('user')) realm.run([kvno, realm.host_princ]) realm.kinit(realm.user_princ, password('user'), flags=['-T', realm.ccache]) realm.run([kvno, realm.host_princ]) # Test that expiration warning works after y2038, by setting a # password expiration time ten minutes after the KDC time. realm.run([kadminl, 'modprinc', '-pwexpire', '662256600 seconds', 'user']) out = realm.kinit(realm.user_princ, password('user')) if 'will expire in less than one hour' not in out: fail('password expiration message') year = int(out.split()[-1]) if year < 2038 or year > 9999: fail('password expiration year') realm.stop_kdc() realm.start_kdc() realm.start_kadmind() realm.prep_kadmin() # Test getdate parsing of absolute timestamps after 2038 and # marshalling over the kadmin protocol. The local time zone will # affect the display time by a little bit, so just look for the year. realm.run_kadmin(['modprinc', '-pwexpire', '2040-02-03', realm.host_princ]) realm.run_kadmin(['getprinc', realm.host_princ], expected_msg=' 2040\n') # Get a ticket whose lifetime crosses the y2038 boundary and # range-check the expiration year as reported by klist. realm.kinit(realm.user_princ, password('user'), flags=['-l', '8000d', '-r', '8500d']) realm.run([kvno, realm.host_princ]) out = realm.run([klist]) if int(out.split('\n')[4].split()[2].split('/')[2]) < 39: fail('unexpected tgt expiration year') if int(out.split('\n')[5].split()[2].split('/')[2]) < 40: fail('unexpected tgt rtill year') if int(out.split('\n')[6].split()[2].split('/')[2]) < 39: fail('unexpected service ticket expiration year') if int(out.split('\n')[7].split()[2].split('/')[2]) < 40: fail('unexpected service ticket rtill year') realm.kinit(realm.user_princ, None, ['-R']) out = realm.run([klist]) if int(out.split('\n')[4].split()[2].split('/')[2]) < 39: fail('unexpected renewed tgt expiration year') if int(out.split('\n')[5].split()[2].split('/')[2]) < 40: fail('unexpected renewed tgt rtill year') success('y2038 tests') krb5-1.16/src/tests/t_hostrealm.py0000755000704600001450000001273613211554426017036 0ustar ghudsonlibuuid#!/usr/bin/python from k5test import * plugin = os.path.join(buildtop, "plugins", "hostrealm", "test", "hostrealm_test.so") # Disable the "dns" module (we can't easily test TXT lookups) and # arrange the remaining modules in an order which makes sense for most # tests. conf = {'plugins': {'hostrealm': {'module': ['test1:' + plugin, 'test2:' + plugin], 'enable_only': ['test2', 'profile', 'domain', 'test1']}}, 'domain_realm': {'.x': 'DOTMATCH', 'x': 'MATCH', '.1': 'NUMMATCH'}} realm = K5Realm(krb5_conf=conf, create_kdb=False) def test(realm, args, expected_realms, msg, env=None): out = realm.run(['./hrealm'] + args, env=env) if out.split('\n') != expected_realms + ['']: fail(msg) def test_error(realm, args, expected_error, msg, env=None): realm.run(['./hrealm'] + args, env=env, expected_code=1, expected_msg=expected_error) def testh(realm, host, expected_realms, msg, env=None): test(realm, ['-h', host], expected_realms, msg, env=env) def testf(realm, host, expected_realms, msg, env=None): test(realm, ['-f', host], expected_realms, msg, env=env) def testd(realm, expected_realm, msg, env=None): test(realm, ['-d'], [expected_realm], msg, env=env) def testh_error(realm, host, expected_error, msg, env=None): test_error(realm, ['-h', host], expected_error, msg, env=env) def testf_error(realm, host, expected_error, msg, env=None): test_error(realm, ['-f', host], expected_error, msg, env=env) def testd_error(realm, expected_error, msg, env=None): test_error(realm, ['-d'], expected_error, msg, env=env) ### ### krb5_get_host_realm tests ### # The test2 module returns a fatal error on hosts beginning with 'z', # and an answer on hosts begining with 'a'. testh_error(realm, 'zoo', 'service not available', 'host_realm test2 z') testh(realm, 'abacus', ['a'], 'host_realm test2 a') # The profile module gives answers for hostnames equal to or ending in # 'X', due to [domain_realms]. There is also an entry for hostnames # ending in '1', but hostnames which appear to be IP or IPv6 addresses # should instead fall through to test1. testh(realm, 'x', ['MATCH'], 'host_realm profile x') testh(realm, '.x', ['DOTMATCH'], 'host_realm profile .x') testh(realm, 'b.x', ['DOTMATCH'], 'host_realm profile b.x') testh(realm, '.b.c.x', ['DOTMATCH'], 'host_realm profile .b.c.x') testh(realm, 'b.1', ['NUMMATCH'], 'host_realm profile b.1') testh(realm, '4.3.2.1', ['4', '3', '2', '1'], 'host_realm profile 4.3.2.1') testh(realm, 'b:c.x', ['b:c', 'x'], 'host_realm profile b:c.x') # hostname cleaning should convert "X." to "x" before matching. testh(realm, 'X.', ['MATCH'], 'host_realm profile X.') # The test1 module returns a list of the hostname components. testh(realm, 'b.c.d', ['b', 'c', 'd'], 'host_realm test1') # If no module returns a result, we should get the referral realm. testh(realm, '', [''], 'host_realm referral realm') ### ### krb5_get_fallback_host_realm tests ### # Return a special environment with realm_try_domains set to n. def try_env(realm, testname, n): conf = {'libdefaults': {'realm_try_domains': str(n)}} return realm.special_env(testname, False, krb5_conf=conf) # The domain module will answer with the uppercased parent domain, # with no special configuration. testf(realm, 'a.b.c', ['B.C'], 'fallback_realm domain a.b.c') # With realm_try_domains = 0, the hostname itself will be looked up as # a realm and returned if found. try0 = try_env(realm, 'try0', 0) testf(realm, 'krbtest.com', ['KRBTEST.COM'], 'fallback_realm try0', env=try0) testf(realm, 'a.b.krbtest.com', ['B.KRBTEST.COM'], 'fallback_realm try0 grandparent', env=try0) testf(realm, 'a.b.c', ['B.C'], 'fallback_realm try0 nomatch', env=try0) # With realm_try_domains = 2, the parent and grandparent will be # checked as well, but it stops there. try2 = try_env(realm, 'try2', 2) testf(realm, 'krbtest.com', ['KRBTEST.COM'], 'fallback_realm try2', env=try2) testf(realm, 'a.b.krbtest.com', ['KRBTEST.COM'], 'fallback_realm try2 grandparent', env=try2) testf(realm, 'a.b.c.krbtest.com', ['B.C.KRBTEST.COM'], 'fallback_realm try2 great-grandparent', env=try2) # The test1 module answers with a list of components. Use an IPv4 # address to bypass the domain module. testf(realm, '1.2.3.4', ['1', '2', '3', '4'], 'fallback_realm test1') # If no module answers, the default realm is returned. The test2 # module returns an error when we try to look that up. testf_error(realm, '', 'service not available', 'fallback_realm default') ### ### krb5_get_default_realm tests ### # The test2 module returns an error. testd_error(realm, 'service not available', 'default_realm test2') # The profile module returns the default realm from the profile. # Disable test2 to expose this behavior. disable_conf = {'plugins': {'hostrealm': {'disable': 'test2'}}} notest2 = realm.special_env('notest2', False, krb5_conf=disable_conf) testd(realm, 'KRBTEST.COM', 'default_realm profile', env=notest2) # The test1 module returns a list of two realms, of which we can only # see the first. Remove the profile default_realm setting to expose # this behavior. remove_default = {'libdefaults': {'default_realm': None}} nodefault_conf = dict(disable_conf.items() + remove_default.items()) nodefault = realm.special_env('nodefault', False, krb5_conf=nodefault_conf) testd(realm, 'one', 'default_realm test1', env=nodefault) success('hostrealm interface tests') krb5-1.16/src/tests/t_cve-2012-1015.py0000755000704600001450000000226513211554426016557 0ustar ghudsonlibuuid#!/usr/bin/python import base64 import socket from k5test import * realm = K5Realm() # CVE-2012-1015 KDC frees uninitialized pointer # Force a failure in krb5_c_make_checksum(), which causes the cleanup # code in kdc_handle_protected_negotiation() to free an uninitialized # pointer in an unpatched KDC. s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) a = (hostname, realm.portbase) x1 = base64.b16decode('6A81A030819DA103020105A20302010A' + 'A30E300C300AA10402020095A2020400' + 'A48180307EA00703050000000000A120' + '301EA003020101A11730151B066B7262' + '7467741B0B4B5242544553542E434F4D' + 'A20D1B0B4B5242544553542E434F4DA3' + '20301EA003020101A11730151B066B72' + '627467741B0B4B5242544553542E434F' + '4DA511180F3139393430363130303630' + '3331375AA7030201') x2 = base64.b16decode('A8083006020106020112') for x in range(0, 128): s.sendto(''.join([x1, chr(x), x2]), a) # Make sure kinit still works. realm.kinit(realm.user_princ, password('user')) success('CVE-2012-1015 regression test') krb5-1.16/src/tests/Makefile.in0000644000704600001450000001663413211554426016206 0ustar ghudsonlibuuidmydir=tests BUILDTOP=$(REL).. SUBDIRS = resolve asn.1 create hammer verify gssapi dejagnu shlib \ gss-threads misc threads RUN_DB_TEST = $(RUN_SETUP) KRB5_KDC_PROFILE=kdc.conf KRB5_CONFIG=krb5.conf \ LC_ALL=C $(VALGRIND) OBJS= adata.o etinfo.o forward.o gcred.o hist.o hooks.o hrealm.o \ icinterleave.o icred.o kdbtest.o localauth.o plugorder.o rdreq.o \ responder.o s2p.o s4u2proxy.o unlockiter.o EXTRADEPSRCS= adata.c etinfo.c forward.c gcred.c hist.c hooks.c hrealm.c \ icinterleave.c icred.c kdbtest.c localauth.c plugorder.c rdreq.o \ responder.c s2p.c s4u2proxy.c unlockiter.c TEST_DB = ./testdb TEST_REALM = FOO.TEST.REALM TEST_MKEY = footes TEST_NUM = 65 TEST_DEPTH = 5 TEST_PREFIX = "foo bar" KADMIN_OPTS= -d $(TEST_DB) -r $(TEST_REALM) -P $(TEST_MKEY) KTEST_OPTS= $(KADMIN_OPTS) -p $(TEST_PREFIX) -n $(TEST_NUM) -D $(TEST_DEPTH) adata: adata.o $(KRB5_BASE_DEPLIBS) $(CC_LINK) -o $@ adata.o $(KRB5_BASE_LIBS) etinfo: etinfo.o $(KRB5_BASE_DEPLIBS) $(CC_LINK) -o $@ etinfo.o $(KRB5_BASE_LIBS) forward: forward.o $(KRB5_BASE_DEPLIBS) $(CC_LINK) -o $@ forward.o $(KRB5_BASE_LIBS) gcred: gcred.o $(KRB5_BASE_DEPLIBS) $(CC_LINK) -o $@ gcred.o $(KRB5_BASE_LIBS) hist: hist.o $(KDB5_DEPLIBS) $(KADMSRV_DEPLIBS) $(KRB5_BASE_DEPLIBS) $(CC_LINK) -o $@ hist.o $(KDB5_LIBS) $(KADMSRV_LIBS) $(KRB5_BASE_LIBS) hooks: hooks.o $(KRB5_BASE_DEPLIBS) $(CC_LINK) -o $@ hooks.o $(KRB5_BASE_LIBS) hrealm: hrealm.o $(KRB5_BASE_DEPLIBS) $(CC_LINK) -o $@ hrealm.o $(KRB5_BASE_LIBS) icinterleave: icinterleave.o $(KRB5_BASE_DEPLIBS) $(CC_LINK) -o $@ icinterleave.o $(KRB5_BASE_LIBS) icred: icred.o $(KRB5_BASE_DEPLIBS) $(CC_LINK) -o $@ icred.o $(KRB5_BASE_LIBS) kdbtest: kdbtest.o $(KDB5_DEPLIBS) $(KADMSRV_DEPLIBS) $(KRB5_BASE_DEPLIBS) $(CC_LINK) -o $@ kdbtest.o $(KDB5_LIBS) $(KADMSRV_LIBS) \ $(KRB5_BASE_LIBS) localauth: localauth.o $(KRB5_BASE_DEPLIBS) $(CC_LINK) -o $@ localauth.o $(KRB5_BASE_LIBS) plugorder: plugorder.o $(KRB5_BASE_DEPLIBS) $(CC_LINK) -o $@ plugorder.o $(KRB5_BASE_LIBS) rdreq: rdreq.o $(KRB5_BASE_DEPLIBS) $(CC_LINK) -o $@ rdreq.o $(KRB5_BASE_LIBS) responder: responder.o $(KRB5_BASE_DEPLIBS) $(CC_LINK) -o $@ responder.o $(KRB5_BASE_LIBS) s2p: s2p.o $(KRB5_BASE_DEPLIBS) $(CC_LINK) -o $@ s2p.o $(KRB5_BASE_LIBS) s4u2proxy: s4u2proxy.o $(KRB5_BASE_DEPLIBS) $(CC_LINK) -o $@ s4u2proxy.o $(KRB5_BASE_LIBS) unlockiter: unlockiter.o $(KDB5_DEPLIBS) $(KADMSRV_DEPLIBS) $(KRB5_BASE_DEPLIBS) $(CC_LINK) -o $@ unlockiter.o $(KDB5_LIBS) $(KADMSRV_LIBS) \ $(KRB5_BASE_LIBS) check-unix: kdb_check kdc.conf: Makefile rm -rf kdc.conf @echo "[realms]" > kdc.conf @echo "$(TEST_REALM) = {" >> kdc.conf @echo " key_stash_file = `pwd`/stash_file" >> kdc.conf @echo "}" >> kdc.conf krb5.conf: Makefile cat $(top_srcdir)/config-files/krb5.conf > krb5.new echo "[dbmodules]" >> krb5.new echo " db_module_dir = `pwd`/../plugins/kdb" >> krb5.new mv krb5.new krb5.conf kdb_check: kdc.conf krb5.conf $(RM) $(TEST_DB)* $(RUN_DB_TEST) ../kadmin/dbutil/kdb5_util $(KADMIN_OPTS) create -W $(RUN_DB_TEST) ../tests/create/kdb5_mkdums $(KTEST_OPTS) $(RUN_DB_TEST) ../tests/verify/kdb5_verify $(KTEST_OPTS) $(RUN_DB_TEST) ../kadmin/dbutil/kdb5_util $(KADMIN_OPTS) dump $(TEST_DB).dump $(RUN_DB_TEST) ../kadmin/dbutil/kdb5_util $(KADMIN_OPTS) dump -ov $(TEST_DB).ovdump $(RUN_DB_TEST) ../kadmin/dbutil/kdb5_util $(KADMIN_OPTS) destroy -f @echo "====> NOTE!" @echo "The following 'create' command is needed due to a change" @echo "in functionality caused by DAL integration. See ticket 3973." @echo ==== $(RUN_DB_TEST) ../kadmin/dbutil/kdb5_util $(KADMIN_OPTS) create -W $(RUN_DB_TEST) ../kadmin/dbutil/kdb5_util $(KADMIN_OPTS) load $(TEST_DB).dump $(RUN_DB_TEST) ../kadmin/dbutil/kdb5_util $(KADMIN_OPTS) load -update -ov $(TEST_DB).ovdump $(RUN_DB_TEST) ../tests/verify/kdb5_verify $(KTEST_OPTS) $(RUN_DB_TEST) ../kadmin/dbutil/kdb5_util $(KADMIN_OPTS) dump $(TEST_DB).dump2 $(RUN_DB_TEST) ../kadmin/dbutil/kdb5_util $(KADMIN_OPTS) dump -ov $(TEST_DB).ovdump2 sort $(TEST_DB).dump > $(TEST_DB).sort sort $(TEST_DB).dump2 > $(TEST_DB).sort2 sort $(TEST_DB).ovdump > $(TEST_DB).ovsort sort $(TEST_DB).ovdump2 > $(TEST_DB).ovsort2 cmp $(TEST_DB).sort $(TEST_DB).sort2 cmp $(TEST_DB).ovsort $(TEST_DB).ovsort2 $(RUN_DB_TEST) ../kadmin/dbutil/kdb5_util $(KADMIN_OPTS) destroy -f $(RM) $(TEST_DB)* stash_file check-pytests: adata etinfo forward gcred hist hooks hrealm icinterleave icred check-pytests: kdbtest localauth plugorder rdreq responder s2p s4u2proxy check-pytests: unlockiter $(RUNPYTEST) $(srcdir)/t_general.py $(PYTESTFLAGS) $(RUNPYTEST) $(srcdir)/t_hooks.py $(PYTESTFLAGS) $(RUNPYTEST) $(srcdir)/t_dump.py $(PYTESTFLAGS) $(RUNPYTEST) $(srcdir)/t_iprop.py $(PYTESTFLAGS) $(RUNPYTEST) $(srcdir)/t_kprop.py $(PYTESTFLAGS) $(RUNPYTEST) $(srcdir)/t_policy.py $(PYTESTFLAGS) $(RUNPYTEST) $(srcdir)/t_changepw.py $(PYTESTFLAGS) $(RUNPYTEST) $(srcdir)/t_pkinit.py $(PYTESTFLAGS) $(RUNPYTEST) $(srcdir)/t_otp.py $(PYTESTFLAGS) $(RUNPYTEST) $(srcdir)/t_localauth.py $(PYTESTFLAGS) $(RUNPYTEST) $(srcdir)/t_kadm5_hook.py $(PYTESTFLAGS) $(RUNPYTEST) $(srcdir)/t_kadm5_auth.py $(PYTESTFLAGS) $(RUNPYTEST) $(srcdir)/t_pwqual.py $(PYTESTFLAGS) $(RUNPYTEST) $(srcdir)/t_hostrealm.py $(PYTESTFLAGS) $(RUNPYTEST) $(srcdir)/t_kdb_locking.py $(PYTESTFLAGS) $(RUNPYTEST) $(srcdir)/t_keyrollover.py $(PYTESTFLAGS) $(RUNPYTEST) $(srcdir)/t_renew.py $(PYTESTFLAGS) $(RUNPYTEST) $(srcdir)/t_renprinc.py $(PYTESTFLAGS) $(RUNPYTEST) $(srcdir)/t_ccache.py $(PYTESTFLAGS) $(RUNPYTEST) $(srcdir)/t_stringattr.py $(PYTESTFLAGS) $(RUNPYTEST) $(srcdir)/t_sesskeynego.py $(PYTESTFLAGS) $(RUNPYTEST) $(srcdir)/t_crossrealm.py $(PYTESTFLAGS) $(RUNPYTEST) $(srcdir)/t_referral.py $(PYTESTFLAGS) $(RUNPYTEST) $(srcdir)/t_skew.py $(PYTESTFLAGS) $(RUNPYTEST) $(srcdir)/t_keytab.py $(PYTESTFLAGS) $(RUNPYTEST) $(srcdir)/t_kadmin_acl.py $(PYTESTFLAGS) $(RUNPYTEST) $(srcdir)/t_kadmin_parsing.py $(PYTESTFLAGS) $(RUNPYTEST) $(srcdir)/t_kdb.py $(PYTESTFLAGS) $(RUNPYTEST) $(srcdir)/t_keydata.py $(PYTESTFLAGS) $(RUNPYTEST) $(srcdir)/t_mkey.py $(PYTESTFLAGS) $(RUNPYTEST) $(srcdir)/t_rdreq.py $(PYTESTFLAGS) $(RUNPYTEST) $(srcdir)/t_sn2princ.py $(PYTESTFLAGS) $(OFFLINE) $(RUNPYTEST) $(srcdir)/t_cve-2012-1014.py $(PYTESTFLAGS) $(RUNPYTEST) $(srcdir)/t_cve-2012-1015.py $(PYTESTFLAGS) $(RUNPYTEST) $(srcdir)/t_cve-2013-1416.py $(PYTESTFLAGS) $(RUNPYTEST) $(srcdir)/t_cve-2013-1417.py $(PYTESTFLAGS) $(RM) au.log $(RUNPYTEST) $(srcdir)/t_audit.py $(PYTESTFLAGS) $(RUNPYTEST) $(srcdir)/jsonwalker.py -d $(srcdir)/au_dict.json \ -i au.log $(RUNPYTEST) $(srcdir)/t_salt.py $(PYTESTFLAGS) $(RUNPYTEST) $(srcdir)/t_etype_info.py $(PYTESTFLAGS) $(RUNPYTEST) $(srcdir)/t_bogus_kdc_req.py $(PYTESTFLAGS) $(RUNPYTEST) $(srcdir)/t_kdc_log.py $(PYTESTFLAGS) $(RUNPYTEST) $(srcdir)/t_proxy.py $(PYTESTFLAGS) $(RUNPYTEST) $(srcdir)/t_unlockiter.py $(PYTESTFLAGS) $(RUNPYTEST) $(srcdir)/t_errmsg.py $(PYTESTFLAGS) $(RUNPYTEST) $(srcdir)/t_authdata.py $(PYTESTFLAGS) $(RUNPYTEST) $(srcdir)/t_preauth.py $(PYTESTFLAGS) $(RUNPYTEST) $(srcdir)/t_princflags.py $(PYTESTFLAGS) $(RUNPYTEST) $(srcdir)/t_tabdump.py $(PYTESTFLAGS) $(RUNPYTEST) $(srcdir)/t_certauth.py $(PYTESTFLAGS) $(RUNPYTEST) $(srcdir)/t_y2038.py $(PYTESTFLAGS) $(RUNPYTEST) $(srcdir)/t_kdcpolicy.py $(PYTESTFLAGS) clean: $(RM) adata etinfo forward gcred hist hooks hrealm icinterleave icred $(RM) kdbtest localauth plugorder rdreq responder s2p s4u2proxy $(RM) unlockiter $(RM) krb5.conf kdc.conf $(RM) -rf kdc_realm/sandbox ldap $(RM) au.log krb5-1.16/src/tests/dump.c0000644000704600001450000000321213211554426015236 0ustar ghudsonlibuuid/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* tests/dump.c */ /* * Copyright 1990 by the Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ /* Dump a krb5_data to stderr (for debugging purposes). */ #include #include "krb5.h" void dump_data (data) krb5_data *data; { unsigned char *ptr = (unsigned char *)data->data; int i; for (i=0; ilength; i++) { fprintf(stderr, "%02x ", ptr[i]); if ((i % 16) == 15) fprintf(stderr, "\n"); } fprintf(stderr, "\n"); } krb5-1.16/src/tests/etinfo.c0000644000704600001450000001436013211554426015563 0ustar ghudsonlibuuid/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* tests/etinfo.c - Test harness for KDC etype-info behavior */ /* * Copyright (C) 2015 by the Massachusetts Institute of Technology. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ /* * Send an AS-REQ to the KDC for a specified principal, with an optionally * specified request enctype list. Decode the output as either an AS-REP or a * KRB-ERROR and display the PA-ETYPE-INFO2, PA-ETYPE-INFO, and PA-PW-SALT * padata in the following format: * * error/asrep etype-info2/etype-info/pw-salt enctype salt [s2kparams] * * enctype is omitted for PA-PW-SALT entries. salt is displayed directly; * s2kparams is displayed in uppercase hex. */ #include "k5-int.h" static krb5_context ctx; static void check(krb5_error_code code) { const char *errmsg; if (code) { errmsg = krb5_get_error_message(ctx, code); fprintf(stderr, "%s\n", errmsg); krb5_free_error_message(ctx, errmsg); exit(1); } } static void display_etinfo(krb5_etype_info_entry **list, const char *l1, const char *l2) { krb5_etype_info_entry *info; char etname[256]; unsigned int i; for (; *list != NULL; list++) { info = *list; check(krb5_enctype_to_name(info->etype, TRUE, etname, sizeof(etname))); printf("%s %s %s ", l1, l2, etname); if (info->length != KRB5_ETYPE_NO_SALT) printf("%.*s", info->length, info->salt); else printf("(default)"); if (info->s2kparams.length > 0) { printf(" "); for (i = 0; i < info->s2kparams.length; i++) printf("%02X", (unsigned char)info->s2kparams.data[i]); } printf("\n"); } } static void display_padata(krb5_pa_data **pa_list, const char *label) { krb5_pa_data *pa; krb5_data d; krb5_etype_info_entry **etinfo_list; for (; pa_list != NULL && *pa_list != NULL; pa_list++) { pa = *pa_list; d = make_data(pa->contents, pa->length); if (pa->pa_type == KRB5_PADATA_ETYPE_INFO2) { check(decode_krb5_etype_info2(&d, &etinfo_list)); display_etinfo(etinfo_list, label, "etype_info2"); krb5_free_etype_info(ctx, etinfo_list); } else if (pa->pa_type == KRB5_PADATA_ETYPE_INFO) { check(decode_krb5_etype_info(&d, &etinfo_list)); display_etinfo(etinfo_list, label, "etype_info"); krb5_free_etype_info(ctx, etinfo_list); } else if (pa->pa_type == KRB5_PADATA_PW_SALT) { printf("%s pw_salt %.*s\n", label, (int)d.length, d.data); } else if (pa->pa_type == KRB5_PADATA_AFS3_SALT) { printf("%s afs3_salt %.*s\n", label, (int)d.length, d.data); } } } int main(int argc, char **argv) { krb5_principal client; krb5_get_init_creds_opt *opt; krb5_init_creds_context icc; krb5_data reply, request, realm; krb5_error *error; krb5_kdc_rep *asrep; krb5_pa_data **padata; krb5_enctype *enctypes, def[] = { ENCTYPE_NULL }; krb5_preauthtype pa_type = KRB5_PADATA_NONE; unsigned int flags; int master = 0; if (argc < 2 && argc > 4) { fprintf(stderr, "Usage: %s princname [enctypes] [patype]\n", argv[0]); exit(1); } check(krb5_init_context(&ctx)); check(krb5_parse_name(ctx, argv[1], &client)); if (argc >= 3) { check(krb5int_parse_enctype_list(ctx, "", argv[2], def, &enctypes)); krb5_set_default_in_tkt_ktypes(ctx, enctypes); free(enctypes); } if (argc >= 4) pa_type = atoi(argv[3]); check(krb5_get_init_creds_opt_alloc(ctx, &opt)); if (pa_type != KRB5_PADATA_NONE) krb5_get_init_creds_opt_set_preauth_list(opt, &pa_type, 1); check(krb5_init_creds_init(ctx, client, NULL, NULL, 0, opt, &icc)); reply = empty_data(); check(krb5_init_creds_step(ctx, icc, &reply, &request, &realm, &flags)); assert(flags == KRB5_INIT_CREDS_STEP_FLAG_CONTINUE); check(krb5_sendto_kdc(ctx, &request, &realm, &reply, &master, 0)); if (decode_krb5_error(&reply, &error) == 0) { decode_krb5_padata_sequence(&error->e_data, &padata); if (error->error == KDC_ERR_PREAUTH_REQUIRED) { display_padata(padata, "error"); } else if (error->error == KDC_ERR_MORE_PREAUTH_DATA_REQUIRED) { display_padata(padata, "more"); } else { fprintf(stderr, "Unexpected error %d\n", (int)error->error); return 1; } krb5_free_pa_data(ctx, padata); krb5_free_error(ctx, error); } else if (decode_krb5_as_rep(&reply, &asrep) == 0) { display_padata(asrep->padata, "asrep"); krb5_free_kdc_rep(ctx, asrep); } else { abort(); } krb5_free_data_contents(ctx, &request); krb5_free_data_contents(ctx, &reply); krb5_free_data_contents(ctx, &realm); krb5_get_init_creds_opt_free(ctx, opt); krb5_init_creds_free(ctx, icc); krb5_free_principal(ctx, client); krb5_free_context(ctx); return 0; } krb5-1.16/src/tests/test1.c0000644000704600001450000001304713211554426015340 0ustar ghudsonlibuuid/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* tests/test1.c - Regression tests for krb5 library */ /* * Copyright 1990 by the Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #include "krb5.h" unsigned char key_one[8] = { 0x10, 0x23, 0x32, 0x45, 0x54, 0x67, 0x76, 0x89 }; unsigned char key_two[8] = { 0xea, 0x89, 0x57, 0x76, 0x5b, 0xcd, 0x0d, 0x34 }; extern void dump_data(); tkt_test_1() { krb5_data *data; krb5_ticket tk_in, *tk_out; krb5_keyblock sess_k, serv_k, *nsess; krb5_enc_tkt_part tk_in_enc; int code; krb5_address *addr_list[2]; krb5_address addr_1; static krb5_octet ip_addr_1[4] = { 18, 72, 0, 122 }; char *out; /* * fill in some values on the "in" side of the ticket */ code = krb5_parse_name ("server/test/1@BOGUS.ORG", &tk_in.server); if (code != 0) { com_err("tkt_test_1", code, " parsing server principal"); return; } serv_k.enctype = 1; /* XXX symbolic constant */ serv_k.length = 8; /* XXX symbolic constant */ serv_k.contents = key_one; sess_k.enctype = 1; /* XXX symbolic constant */ sess_k.length = 8; /* XXX symbolic constant */ sess_k.contents = key_two; tk_in.etype = 1; /* XXX symbolic constant here */ tk_in.skvno = 4; tk_in.enc_part2 = &tk_in_enc; tk_in_enc.flags = 0x11; tk_in_enc.session = &sess_k; tk_in_enc.times.authtime = 42; tk_in_enc.times.starttime = 43; tk_in_enc.times.endtime = 44; code = krb5_parse_name ("client/test/1@BOGUS.ORG", &tk_in_enc.client); if (code != 0) { com_err("tkt_test_1", code, " parsing client principal"); return; } tk_in_enc.transited.length = 0; addr_1.addrtype = ADDRTYPE_INET; /* XXX should be KRB5_ADDR... */ addr_1.length = 4; addr_1.contents = ip_addr_1; addr_list[0] = &addr_1; addr_list[1] = 0; tk_in_enc.caddrs = addr_list; tk_in_enc.authorization_data = 0; code = krb5_encrypt_tkt_part(&serv_k, &tk_in); if (code != 0) { com_err ("tkt_test_1", code, " encrypting ticket"); return; } data = 0; code = krb5_encode_ticket (&tk_in, &data); if (code != 0) { com_err ("tkt_test_1", code, " encoding ticket"); return; } dump_data(data); tk_out = 0; code = krb5_decode_ticket (data, &tk_out); if (code != 0) { com_err ("tkt_test_1", code, "decoding ticket"); return; } /* check the plaintext values */ if (tk_out->etype != 1) { com_err ("tkt_test_1", 0, "wrong etype"); return; } if (tk_out->skvno != 4) { com_err ("tkt_test_1", 0, "wrong kvno"); return; } code = krb5_unparse_name(tk_out->server, &out); if (code != 0) { com_err ("tkt_test_1", code, "couldn't unparse server principal"); return; } if (strcmp (out, "server/test/1@BOGUS.ORG") != 0) { com_err("tkt_test_1", 0, "wrong server principal"); return; } free(out); out = 0; /* decode the ciphertext */ code = krb5_decrypt_tkt_part (&serv_k, tk_out); if (code != 0) { com_err ("tkt_test_1", code, "while decrypting ticket"); return; } /* check the contents */ if (tk_out->enc_part2->flags != 0x11) { com_err("tkt_test_1", 0, "wrong flags"); return; } nsess = tk_out->enc_part2->session; if (nsess->enctype != 1) { com_err("tkt_test_1", 0, "wrong session key type"); return; } if (nsess->length != 8) { com_err("tkt_test_1", 0, "wrong session key length"); return; } if (memcmp(nsess->contents, key_two, 8) != 0) { com_err("tkt_test_1", 0, "wrong session key contents"); return; } code = krb5_unparse_name(tk_out->enc_part2->client, &out); if (code != 0) { com_err ("tkt_test_1", code, "couldn't unparse client principal"); return; } if (strcmp (out, "client/test/1@BOGUS.ORG") != 0) { com_err("tkt_test_1", 0, "wrong client principal"); return; } free(out); out = 0; if (tk_out->enc_part2->transited.length != 0) { com_err("tkt_test_1", 0, "wrong transited length"); return; } /* XXX should check address here, too */ /* XXX should check times here */ /* XXX should check auth. data here */ printf("test 1 passed\n"); } main() { krb5_init_ets(); tkt_test_1(); } krb5-1.16/src/tests/s4u2proxy.c0000644000704600001450000001007113211554426016171 0ustar ghudsonlibuuid/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* tests/s4u2proxy.c - S4U2Proxy test harness */ /* * Copyright (C) 2015 by the Massachusetts Institute of Technology. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ /* * Usage: s4u2proxy evccname targetname * * evccname contains an evidence ticket. The default ccache contains a TGT for * the intermediate service. The default keytab contains a key for the * intermediate service. An S4U2Proxy request is made to get a ticket from * evccname's default principal to the target service. The resulting cred is * stored in the default ccache. */ #include static krb5_context ctx; static void check(krb5_error_code code) { const char *errmsg; if (code) { errmsg = krb5_get_error_message(ctx, code); fprintf(stderr, "%s\n", errmsg); krb5_free_error_message(ctx, errmsg); exit(1); } } int main(int argc, char **argv) { krb5_context context; krb5_ccache defcc, evcc; krb5_principal client_name, int_name, target_name; krb5_keytab defkt; krb5_creds mcred, ev_cred, *new_cred; krb5_ticket *ev_ticket; assert(argc == 3); check(krb5_init_context(&context)); /* Open the default ccache, evidence ticket ccache, and default keytab. */ check(krb5_cc_default(context, &defcc)); check(krb5_cc_resolve(context, argv[1], &evcc)); check(krb5_kt_default(context, &defkt)); /* Determine the client name, intermediate name, and target name. */ check(krb5_cc_get_principal(context, evcc, &client_name)); check(krb5_cc_get_principal(context, defcc, &int_name)); check(krb5_parse_name(context, argv[2], &target_name)); /* Retrieve and decrypt the evidence ticket. */ memset(&mcred, 0, sizeof(mcred)); mcred.client = client_name; mcred.server = int_name; check(krb5_cc_retrieve_cred(context, evcc, 0, &mcred, &ev_cred)); check(krb5_decode_ticket(&ev_cred.ticket, &ev_ticket)); check(krb5_server_decrypt_ticket_keytab(context, defkt, ev_ticket)); /* Make an S4U2Proxy request for the target service. */ mcred.client = client_name; mcred.server = target_name; check(krb5_get_credentials_for_proxy(context, KRB5_GC_NO_STORE, defcc, &mcred, ev_ticket, &new_cred)); /* Store the new cred in the default ccache. */ check(krb5_cc_store_cred(context, defcc, new_cred)); krb5_cc_close(context, defcc); krb5_cc_close(context, evcc); krb5_kt_close(context, defkt); krb5_free_principal(context, client_name); krb5_free_principal(context, int_name); krb5_free_principal(context, target_name); krb5_free_cred_contents(context, &ev_cred); krb5_free_ticket(context, ev_ticket); krb5_free_creds(context, new_cred); krb5_free_context(context); return 0; } krb5-1.16/src/tests/jsonwalker.py0000644000704600001450000000654313211554426016670 0ustar ghudsonlibuuid#!/usr/bin/python import sys try: import cjson except ImportError: print "Warning: skipping audit log verification because the cjson module" \ " is unavailable" sys.exit(0) from collections import defaultdict from optparse import OptionParser class Parser(object): DEFAULTS = {int:0, str:'', list:[]} def __init__(self, defconf=None): self.defaults = None if defconf is not None: self.defaults = self.flatten(defconf) def run(self, logs, verbose=None): result = self.parse(logs) if len(result) != len(self.defaults): diff = set(self.defaults.keys()).difference(result.keys()) print 'Test failed.' print 'The following attributes were not set:' for it in diff: print it sys.exit(1) def flatten(self, defaults): """ Flattens pathes to attributes. Parameters ---------- defaults : a dictionaries populated with default values Returns : dict : with flattened attributes """ result = dict() for path,value in self._walk(defaults): if path in result: print 'Warning: attribute path %s already exists' % path result[path] = value return result def parse(self, logs): result = defaultdict(list) for msg in logs: # each message is treated as a dictionary of dictionaries for a,v in self._walk(msg): # see if path is registered in defaults if a in self.defaults: dv = self.defaults.get(a) if dv is None: # determine default value by type if v is not None: dv = self.DEFAULTS[type(v)] else: print 'Warning: attribute %s is set to None' % a continue # by now we have default value if v != dv: # test passed result[a].append(v) return result def _walk(self, adict): """ Generator that works through dictionary. """ for a,v in adict.iteritems(): if isinstance(v,dict): for (attrpath,u) in self._walk(v): yield (a+'.'+attrpath,u) else: yield (a,v) if __name__ == '__main__': parser = OptionParser() parser.add_option("-i", "--logfile", dest="filename", help="input log file in json fmt", metavar="FILE") parser.add_option("-d", "--defaults", dest="defaults", help="dictionary with defaults", metavar="FILE") (options, args) = parser.parse_args() if options.filename is not None: with open(options.filename, 'r') as f: content = list() for l in f: content.append(cjson.decode(l.rstrip())) f.close() else: print 'Input file in jason format is required' exit() defaults = None if options.defaults is not None: with open(options.defaults, 'r') as f: defaults = cjson.decode(f.read()) f.close() # run test p = Parser(defaults) p.run(content) exit() krb5-1.16/src/tests/t_bogus_kdc_req.py0000755000704600001450000000154113211554426017637 0ustar ghudsonlibuuid#!/usr/bin/python import base64 import socket from k5test import * realm = K5Realm() # Send encodings that are invalid KDC-REQs, but pass krb5_is_as_req() # and krb5_is_tgs_req(), to make sure that the KDC recovers correctly # from failures in decode_krb5_as_req() and decode_krb5_tgs_req(). s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) a = (hostname, realm.portbase) # Bogus AS-REQ x1 = base64.b16decode('6AFF') s.sendto(x1, a) # Make sure kinit still works. realm.kinit(realm.user_princ, password('user')) # Bogus TGS-REQ x2 = base64.b16decode('6CFF') s.sendto(x2, a) # Make sure kinit still works. realm.kinit(realm.user_princ, password('user')) # Not a KDC-REQ, even a little bit x3 = base64.b16decode('FFFF') s.sendto(x3, a) # Make sure kinit still works. realm.kinit(realm.user_princ, password('user')) success('Bogus KDC-REQ test') krb5-1.16/src/tests/t_pkinit.py0000755000704600001450000004240513211554426016332 0ustar ghudsonlibuuid#!/usr/bin/python from k5test import * # Skip this test if pkinit wasn't built. if not os.path.exists(os.path.join(plugins, 'preauth', 'pkinit.so')): skip_rest('PKINIT tests', 'PKINIT module not built') # Check if soft-pkcs11.so is available. try: import ctypes lib = ctypes.LibraryLoader(ctypes.CDLL).LoadLibrary('soft-pkcs11.so') del lib have_soft_pkcs11 = True except: have_soft_pkcs11 = False # Construct a krb5.conf fragment configuring pkinit. certs = os.path.join(srctop, 'tests', 'dejagnu', 'pkinit-certs') ca_pem = os.path.join(certs, 'ca.pem') kdc_pem = os.path.join(certs, 'kdc.pem') user_pem = os.path.join(certs, 'user.pem') privkey_pem = os.path.join(certs, 'privkey.pem') privkey_enc_pem = os.path.join(certs, 'privkey-enc.pem') user_p12 = os.path.join(certs, 'user.p12') user_enc_p12 = os.path.join(certs, 'user-enc.p12') user_upn_p12 = os.path.join(certs, 'user-upn.p12') user_upn2_p12 = os.path.join(certs, 'user-upn2.p12') user_upn3_p12 = os.path.join(certs, 'user-upn3.p12') generic_p12 = os.path.join(certs, 'generic.p12') path = os.path.join(os.getcwd(), 'testdir', 'tmp-pkinit-certs') path_enc = os.path.join(os.getcwd(), 'testdir', 'tmp-pkinit-certs-enc') pkinit_krb5_conf = {'realms': {'$realm': { 'pkinit_anchors': 'FILE:%s' % ca_pem}}} pkinit_kdc_conf = {'realms': {'$realm': { 'default_principal_flags': '+preauth', 'pkinit_eku_checking': 'none', 'pkinit_identity': 'FILE:%s,%s' % (kdc_pem, privkey_pem), 'pkinit_indicator': ['indpkinit1', 'indpkinit2']}}} restrictive_kdc_conf = {'realms': {'$realm': { 'restrict_anonymous_to_tgt': 'true' }}} testprincs = {'krbtgt/KRBTEST.COM': {'keys': 'aes128-cts'}, 'user': {'keys': 'aes128-cts', 'flags': '+preauth'}, 'user2': {'keys': 'aes128-cts', 'flags': '+preauth'}} alias_kdc_conf = {'realms': {'$realm': { 'default_principal_flags': '+preauth', 'pkinit_eku_checking': 'none', 'pkinit_allow_upn': 'true', 'pkinit_identity': 'FILE:%s,%s' % (kdc_pem, privkey_pem), 'database_module': 'test'}}, 'dbmodules': {'test': { 'db_library': 'test', 'alias': {'user@krbtest.com': 'user'}, 'princs': testprincs}}} file_identity = 'FILE:%s,%s' % (user_pem, privkey_pem) file_enc_identity = 'FILE:%s,%s' % (user_pem, privkey_enc_pem) dir_identity = 'DIR:%s' % path dir_enc_identity = 'DIR:%s' % path_enc dir_file_identity = 'FILE:%s,%s' % (os.path.join(path, 'user.crt'), os.path.join(path, 'user.key')) dir_file_enc_identity = 'FILE:%s,%s' % (os.path.join(path_enc, 'user.crt'), os.path.join(path_enc, 'user.key')) p12_identity = 'PKCS12:%s' % user_p12 p12_upn_identity = 'PKCS12:%s' % user_upn_p12 p12_upn2_identity = 'PKCS12:%s' % user_upn2_p12 p12_upn3_identity = 'PKCS12:%s' % user_upn3_p12 p12_generic_identity = 'PKCS12:%s' % generic_p12 p12_enc_identity = 'PKCS12:%s' % user_enc_p12 p11_identity = 'PKCS11:soft-pkcs11.so' p11_token_identity = ('PKCS11:module_name=soft-pkcs11.so:' 'slotid=1:token=SoftToken (token)') # Start a realm with the test kdb module for the following UPN SAN tests. realm = K5Realm(krb5_conf=pkinit_krb5_conf, kdc_conf=alias_kdc_conf, create_kdb=False) realm.start_kdc() # Compatibility check: cert contains UPN "user", which matches the # request principal user@KRBTEST.COM if parsed as a normal principal. realm.kinit(realm.user_princ, flags=['-X', 'X509_user_identity=%s' % p12_upn2_identity]) # Compatibility check: cert contains UPN "user@KRBTEST.COM", which matches # the request principal user@KRBTEST.COM if parsed as a normal principal. realm.kinit(realm.user_princ, flags=['-X', 'X509_user_identity=%s' % p12_upn3_identity]) # Cert contains UPN "user@krbtest.com" which is aliased to the request # principal. realm.kinit(realm.user_princ, flags=['-X', 'X509_user_identity=%s' % p12_upn_identity]) # Test an id-pkinit-san match to a post-canonical principal. realm.kinit('user@krbtest.com', flags=['-E', '-X', 'X509_user_identity=%s' % p12_identity]) # Test a UPN match to a post-canonical principal. (This only works # for the cert with the UPN containing just "user", as we don't allow # UPN reparsing when comparing to the canonicalized client principal.) realm.kinit('user@krbtest.com', flags=['-E', '-X', 'X509_user_identity=%s' % p12_upn2_identity]) # Test a mismatch. msg = 'kinit: Client name mismatch while getting initial credentials' realm.run([kinit, '-X', 'X509_user_identity=%s' % p12_upn2_identity, 'user2'], expected_code=1, expected_msg=msg) realm.stop() realm = K5Realm(krb5_conf=pkinit_krb5_conf, kdc_conf=pkinit_kdc_conf, get_creds=False) # Sanity check - password-based preauth should still work. realm.run(['./responder', '-r', 'password=%s' % password('user'), realm.user_princ]) realm.kinit(realm.user_princ, password=password('user')) realm.klist(realm.user_princ) realm.run([kvno, realm.host_princ]) # Test anonymous PKINIT. realm.kinit('@%s' % realm.realm, flags=['-n'], expected_code=1, expected_msg='not found in Kerberos database') realm.addprinc('WELLKNOWN/ANONYMOUS') realm.kinit('@%s' % realm.realm, flags=['-n']) realm.klist('WELLKNOWN/ANONYMOUS@WELLKNOWN:ANONYMOUS') realm.run([kvno, realm.host_princ]) out = realm.run(['./adata', realm.host_princ]) if '97:' in out: fail('auth indicators seen in anonymous PKINIT ticket') # Test anonymous kadmin. f = open(os.path.join(realm.testdir, 'acl'), 'a') f.write('WELLKNOWN/ANONYMOUS@WELLKNOWN:ANONYMOUS a *') f.close() realm.start_kadmind() realm.run([kadmin, '-n', 'addprinc', '-pw', 'test', 'testadd']) realm.run([kadmin, '-n', 'getprinc', 'testadd'], expected_code=1, expected_msg="Operation requires ``get'' privilege") realm.stop_kadmind() # Test with anonymous restricted; FAST should work but kvno should fail. r_env = realm.special_env('restrict', True, kdc_conf=restrictive_kdc_conf) realm.stop_kdc() realm.start_kdc(env=r_env) realm.kinit('@%s' % realm.realm, flags=['-n']) realm.kinit('@%s' % realm.realm, flags=['-n', '-T', realm.ccache]) realm.run([kvno, realm.host_princ], expected_code=1, expected_msg='KDC policy rejects request') # Regression test for #8458: S4U2Self requests crash the KDC if # anonymous is restricted. realm.kinit(realm.host_princ, flags=['-k']) realm.run([kvno, '-U', 'user', realm.host_princ]) # Go back to a normal KDC and disable anonymous PKINIT. realm.stop_kdc() realm.start_kdc() realm.run([kadminl, 'delprinc', 'WELLKNOWN/ANONYMOUS']) # Run the basic test - PKINIT with FILE: identity, with no password on the key. realm.run(['./responder', '-x', 'pkinit=', '-X', 'X509_user_identity=%s' % file_identity, realm.user_princ]) realm.kinit(realm.user_princ, flags=['-X', 'X509_user_identity=%s' % file_identity]) realm.klist(realm.user_princ) realm.run([kvno, realm.host_princ]) # Try again using RSA instead of DH. realm.kinit(realm.user_princ, flags=['-X', 'X509_user_identity=%s' % file_identity, '-X', 'flag_RSA_PROTOCOL=yes']) realm.klist(realm.user_princ) # Test a DH parameter renegotiation by temporarily setting a 4096-bit # minimum on the KDC. (Preauth type 16 is PKINIT PA_PK_AS_REQ; # 109 is PKINIT TD_DH_PARAMETERS; 133 is FAST PA-FX-COOKIE.) minbits_kdc_conf = {'realms': {'$realm': {'pkinit_dh_min_bits': '4096'}}} minbits_env = realm.special_env('restrict', True, kdc_conf=minbits_kdc_conf) realm.stop_kdc() realm.start_kdc(env=minbits_env) expected_trace = ('Sending unauthenticated request', '/Additional pre-authentication required', 'Preauthenticating using KDC method data', 'Preauth module pkinit (16) (real) returned: 0/Success', 'Produced preauth for next request: 133, 16', '/Key parameters not accepted', 'Preauth tryagain input types (16): 109, 133', 'trying again with KDC-provided parameters', 'Preauth module pkinit (16) tryagain returned: 0/Success', 'Followup preauth for next request: 16, 133') realm.kinit(realm.user_princ, flags=['-X', 'X509_user_identity=%s' % file_identity], expected_trace=expected_trace) realm.stop_kdc() realm.start_kdc() # Run the basic test - PKINIT with FILE: identity, with a password on the key, # supplied by the prompter. # Expect failure if the responder does nothing, and we have no prompter. realm.run(['./responder', '-x', 'pkinit={"%s": 0}' % file_enc_identity, '-X', 'X509_user_identity=%s' % file_enc_identity, realm.user_princ], expected_code=2) realm.kinit(realm.user_princ, flags=['-X', 'X509_user_identity=%s' % file_enc_identity], password='encrypted') realm.klist(realm.user_princ) realm.run([kvno, realm.host_princ]) realm.run(['./adata', realm.host_princ], expected_msg='+97: [indpkinit1, indpkinit2]') # Run the basic test - PKINIT with FILE: identity, with a password on the key, # supplied by the responder. # Supply the response in raw form. realm.run(['./responder', '-x', 'pkinit={"%s": 0}' % file_enc_identity, '-r', 'pkinit={"%s": "encrypted"}' % file_enc_identity, '-X', 'X509_user_identity=%s' % file_enc_identity, realm.user_princ]) # Supply the response through the convenience API. realm.run(['./responder', '-X', 'X509_user_identity=%s' % file_enc_identity, '-p', '%s=%s' % (file_enc_identity, 'encrypted'), realm.user_princ]) realm.klist(realm.user_princ) realm.run([kvno, realm.host_princ]) # PKINIT with DIR: identity, with no password on the key. os.mkdir(path) os.mkdir(path_enc) shutil.copy(privkey_pem, os.path.join(path, 'user.key')) shutil.copy(privkey_enc_pem, os.path.join(path_enc, 'user.key')) shutil.copy(user_pem, os.path.join(path, 'user.crt')) shutil.copy(user_pem, os.path.join(path_enc, 'user.crt')) realm.run(['./responder', '-x', 'pkinit=', '-X', 'X509_user_identity=%s' % dir_identity, realm.user_princ]) realm.kinit(realm.user_princ, flags=['-X', 'X509_user_identity=%s' % dir_identity]) realm.klist(realm.user_princ) realm.run([kvno, realm.host_princ]) # PKINIT with DIR: identity, with a password on the key, supplied by the # prompter. # Expect failure if the responder does nothing, and we have no prompter. realm.run(['./responder', '-x', 'pkinit={"%s": 0}' % dir_file_enc_identity, '-X', 'X509_user_identity=%s' % dir_enc_identity, realm.user_princ], expected_code=2) realm.kinit(realm.user_princ, flags=['-X', 'X509_user_identity=%s' % dir_enc_identity], password='encrypted') realm.klist(realm.user_princ) realm.run([kvno, realm.host_princ]) # PKINIT with DIR: identity, with a password on the key, supplied by the # responder. # Supply the response in raw form. realm.run(['./responder', '-x', 'pkinit={"%s": 0}' % dir_file_enc_identity, '-r', 'pkinit={"%s": "encrypted"}' % dir_file_enc_identity, '-X', 'X509_user_identity=%s' % dir_enc_identity, realm.user_princ]) # Supply the response through the convenience API. realm.run(['./responder', '-X', 'X509_user_identity=%s' % dir_enc_identity, '-p', '%s=%s' % (dir_file_enc_identity, 'encrypted'), realm.user_princ]) realm.klist(realm.user_princ) realm.run([kvno, realm.host_princ]) # PKINIT with PKCS12: identity, with no password on the bundle. realm.run(['./responder', '-x', 'pkinit=', '-X', 'X509_user_identity=%s' % p12_identity, realm.user_princ]) realm.kinit(realm.user_princ, flags=['-X', 'X509_user_identity=%s' % p12_identity]) realm.klist(realm.user_princ) realm.run([kvno, realm.host_princ]) # PKINIT with PKCS12: identity, with a password on the bundle, supplied by the # prompter. # Expect failure if the responder does nothing, and we have no prompter. realm.run(['./responder', '-x', 'pkinit={"%s": 0}' % p12_enc_identity, '-X', 'X509_user_identity=%s' % p12_enc_identity, realm.user_princ], expected_code=2) realm.kinit(realm.user_princ, flags=['-X', 'X509_user_identity=%s' % p12_enc_identity], password='encrypted') realm.klist(realm.user_princ) realm.run([kvno, realm.host_princ]) # PKINIT with PKCS12: identity, with a password on the bundle, supplied by the # responder. # Supply the response in raw form. realm.run(['./responder', '-x', 'pkinit={"%s": 0}' % p12_enc_identity, '-r', 'pkinit={"%s": "encrypted"}' % p12_enc_identity, '-X', 'X509_user_identity=%s' % p12_enc_identity, realm.user_princ]) # Supply the response through the convenience API. realm.run(['./responder', '-X', 'X509_user_identity=%s' % p12_enc_identity, '-p', '%s=%s' % (p12_enc_identity, 'encrypted'), realm.user_princ]) realm.klist(realm.user_princ) realm.run([kvno, realm.host_princ]) # Match a single rule. rule = '^user@KRBTEST.COM$' realm.run([kadminl, 'setstr', realm.user_princ, 'pkinit_cert_match', rule]) realm.kinit(realm.user_princ, flags=['-X', 'X509_user_identity=%s' % p12_identity]) realm.klist(realm.user_princ) # Match a combined rule (default prefix is &&). rule = 'CN=user$digitalSignature,keyEncipherment' realm.run([kadminl, 'setstr', realm.user_princ, 'pkinit_cert_match', rule]) realm.kinit(realm.user_princ, flags=['-X', 'X509_user_identity=%s' % p12_identity]) realm.klist(realm.user_princ) # Fail an && rule. rule = '&&O=OTHER.COM^user@KRBTEST.COM$' realm.run([kadminl, 'setstr', realm.user_princ, 'pkinit_cert_match', rule]) msg = 'kinit: Certificate mismatch while getting initial credentials' realm.kinit(realm.user_princ, flags=['-X', 'X509_user_identity=%s' % p12_identity], expected_code=1, expected_msg=msg) # Pass an || rule. rule = '||O=KRBTEST.COM^otheruser@KRBTEST.COM$' realm.run([kadminl, 'setstr', realm.user_princ, 'pkinit_cert_match', rule]) realm.kinit(realm.user_princ, flags=['-X', 'X509_user_identity=%s' % p12_identity]) realm.klist(realm.user_princ) # Fail an || rule. rule = '||O=OTHER.COM^otheruser@KRBTEST.COM$' realm.run([kadminl, 'setstr', realm.user_princ, 'pkinit_cert_match', rule]) msg = 'kinit: Certificate mismatch while getting initial credentials' realm.kinit(realm.user_princ, flags=['-X', 'X509_user_identity=%s' % p12_identity], expected_code=1, expected_msg=msg) # Authorize a client cert with no PKINIT extensions using subject and # issuer. (Relies on EKU checking being turned off.) rule = '&&CN=user$O=MIT,' realm.run([kadminl, 'setstr', realm.user_princ, 'pkinit_cert_match', rule]) realm.kinit(realm.user_princ, flags=['-X', 'X509_user_identity=%s' % p12_generic_identity]) realm.klist(realm.user_princ) if not have_soft_pkcs11: skip_rest('PKINIT PKCS11 tests', 'soft-pkcs11.so not found') softpkcs11rc = os.path.join(os.getcwd(), 'testdir', 'soft-pkcs11.rc') realm.env['SOFTPKCS11RC'] = softpkcs11rc # PKINIT with PKCS11: identity, with no need for a PIN. conf = open(softpkcs11rc, 'w') conf.write("%s\t%s\t%s\t%s\n" % ('user', 'user token', user_pem, privkey_pem)) conf.close() # Expect to succeed without having to supply any more information. realm.run(['./responder', '-x', 'pkinit=', '-X', 'X509_user_identity=%s' % p11_identity, realm.user_princ]) realm.kinit(realm.user_princ, flags=['-X', 'X509_user_identity=%s' % p11_identity]) realm.klist(realm.user_princ) realm.run([kvno, realm.host_princ]) # PKINIT with PKCS11: identity, with a PIN supplied by the prompter. os.remove(softpkcs11rc) conf = open(softpkcs11rc, 'w') conf.write("%s\t%s\t%s\t%s\n" % ('user', 'user token', user_pem, privkey_enc_pem)) conf.close() # Expect failure if the responder does nothing, and there's no prompter realm.run(['./responder', '-x', 'pkinit={"%s": 0}' % p11_token_identity, '-X', 'X509_user_identity=%s' % p11_identity, realm.user_princ], expected_code=2) realm.kinit(realm.user_princ, flags=['-X', 'X509_user_identity=%s' % p11_identity], password='encrypted') realm.klist(realm.user_princ) realm.run([kvno, realm.host_princ]) # Supply the wrong PIN, and verify that we ignore the draft9 padata offer # in the KDC method data after RFC 4556 PKINIT fails. expected_trace = ('PKINIT client has no configured identity; giving up', 'PKINIT client ignoring draft 9 offer from RFC 4556 KDC') realm.kinit(realm.user_princ, flags=['-X', 'X509_user_identity=%s' % p11_identity], password='wrong', expected_code=1, expected_trace=expected_trace) # PKINIT with PKCS11: identity, with a PIN supplied by the responder. # Supply the response in raw form. realm.run(['./responder', '-x', 'pkinit={"%s": 0}' % p11_token_identity, '-r', 'pkinit={"%s": "encrypted"}' % p11_token_identity, '-X', 'X509_user_identity=%s' % p11_identity, realm.user_princ]) # Supply the response through the convenience API. realm.run(['./responder', '-X', 'X509_user_identity=%s' % p11_identity, '-p', '%s=%s' % (p11_token_identity, 'encrypted'), realm.user_princ]) realm.klist(realm.user_princ) realm.run([kvno, realm.host_princ]) success('PKINIT tests') krb5-1.16/src/tests/t_dump.py0000755000704600001450000000756013211554426016004 0ustar ghudsonlibuuid#!/usr/bin/python from k5test import * from filecmp import cmp # Make sure we can dump and load an ordinary database, and that # principals and policies survive a dump/load cycle. realm = K5Realm(start_kdc=False) realm.run([kadminl, 'addpol', 'fred']) # Create a dump file. dumpfile = os.path.join(realm.testdir, 'dump') realm.run([kdb5_util, 'dump', dumpfile]) # Write additional policy records to the dump. Use the 1.8 format for # one of them, to test retroactive compatibility (for issue #8213). f = open('testdir/dump', 'a') f.write('policy compat 0 0 3 4 5 0 ' '0 0 0\n') f.write('policy barney 0 0 1 1 1 0 ' '0 0 0 0 0 0 - 1 ' '2 28 ' 'fd100f5064625f6372656174696f6e404b5242544553542e434f4d00\n') f.close() # Destroy and load the database; check that the policies exist. # Spot-check principal and policy fields. realm.run([kdb5_util, 'destroy', '-f']) realm.run([kdb5_util, 'load', dumpfile]) out = realm.run([kadminl, 'getprincs']) if realm.user_princ not in out or realm.host_princ not in out: fail('Missing principal after load') out = realm.run([kadminl, 'getprinc', realm.user_princ]) if 'Expiration date: [never]' not in out or 'MKey: vno 1' not in out: fail('Principal has wrong value after load') out = realm.run([kadminl, 'getpols']) if 'fred\n' not in out or 'barney\n' not in out: fail('Missing policy after load') realm.run([kadminl, 'getpol', 'compat'], expected_msg='Number of old keys kept: 5') realm.run([kadminl, 'getpol', 'barney'], expected_msg='Number of old keys kept: 1') # Dump/load again, and make sure everything is still there. realm.run([kdb5_util, 'dump', dumpfile]) realm.run([kdb5_util, 'load', dumpfile]) out = realm.run([kadminl, 'getprincs']) if realm.user_princ not in out or realm.host_princ not in out: fail('Missing principal after load') out = realm.run([kadminl, 'getpols']) if 'compat\n' not in out or 'fred\n' not in out or 'barney\n' not in out: fail('Missing policy after second load') srcdumpdir = os.path.join(srctop, 'tests', 'dumpfiles') srcdump = os.path.join(srcdumpdir, 'dump') srcdump_r18 = os.path.join(srcdumpdir, 'dump.r18') srcdump_r13 = os.path.join(srcdumpdir, 'dump.r13') srcdump_b7 = os.path.join(srcdumpdir, 'dump.b7') srcdump_ov = os.path.join(srcdumpdir, 'dump.ov') # Load a dump file from the source directory. realm.run([kdb5_util, 'destroy', '-f']) realm.run([kdb5_util, 'load', srcdump]) realm.run([kdb5_util, 'stash', '-P', 'master']) def dump_compare(realm, opt, srcfile): realm.run([kdb5_util, 'dump'] + opt + [dumpfile]) if not cmp(srcfile, dumpfile, False): fail('Dump output does not match %s' % srcfile) # Dump the resulting DB in each non-iprop format and compare with # expected outputs. dump_compare(realm, [], srcdump) dump_compare(realm, ['-r18'], srcdump_r18) dump_compare(realm, ['-r13'], srcdump_r13) dump_compare(realm, ['-b7'], srcdump_b7) dump_compare(realm, ['-ov'], srcdump_ov) def load_dump_check_compare(realm, opt, srcfile): realm.run([kdb5_util, 'destroy', '-f']) realm.run([kdb5_util, 'load'] + opt + [srcfile]) realm.run([kadminl, 'getprincs'], expected_msg='user@') realm.run([kadminl, 'getprinc', 'nokeys'], expected_msg='Number of keys: 0') realm.run([kadminl, 'getpols'], expected_msg='testpol') dump_compare(realm, opt, srcfile) # Load each format of dump, check it, re-dump it, and compare. load_dump_check_compare(realm, ['-r18'], srcdump_r18) load_dump_check_compare(realm, ['-r13'], srcdump_r13) load_dump_check_compare(realm, ['-b7'], srcdump_b7) # Loading the last (-b7 format) dump won't have loaded the # per-principal kadm data. Load that incrementally with -ov. realm.run([kadminl, 'getprinc', 'user'], expected_msg='Policy: [none]') realm.run([kdb5_util, 'load', '-update', '-ov', srcdump_ov]) realm.run([kadminl, 'getprinc', 'user'], expected_msg='Policy: testpol') success('Dump/load tests') krb5-1.16/src/tests/t_otp.py0000755000704600001450000002046113211554426015634 0ustar ghudsonlibuuid#!/usr/bin/python # # Author: Nathaniel McCallum # # Copyright (c) 2013 Red Hat, Inc. # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. # # This script tests OTP, both UDP and Unix Sockets, with a variety of # configuration. It requires pyrad to run, but exits gracefully if not found. # It also deliberately shuts down the test daemons between tests in order to # test how OTP handles the case of short daemon restarts. # from k5test import * from Queue import Empty import StringIO import struct try: from pyrad import packet, dictionary except ImportError: skip_rest('OTP tests', 'Python pyrad module not found') try: from multiprocessing import Process, Queue except ImportError: skip_rest('OTP tests', 'Python version 2.6 required') # We could use a dictionary file, but since we need so few attributes, # we'll just include them here. radius_attributes = ''' ATTRIBUTE User-Name 1 string ATTRIBUTE User-Password 2 octets ATTRIBUTE NAS-Identifier 32 string ''' class RadiusDaemon(Process): MAX_PACKET_SIZE = 4096 DICTIONARY = dictionary.Dictionary(StringIO.StringIO(radius_attributes)) def listen(self, addr): raise NotImplementedError() def recvRequest(self, data): raise NotImplementedError() def run(self): addr = self._args[0] secr = self._args[1] pswd = self._args[2] outq = self._args[3] if secr: with open(secr) as file: secr = file.read().strip() data = self.listen(addr) outq.put("started") (buf, sock, addr) = self.recvRequest(data) pkt = packet.AuthPacket(secret=secr, dict=RadiusDaemon.DICTIONARY, packet=buf) usernm = [] passwd = [] for key in pkt.keys(): if key == 'User-Password': passwd = map(pkt.PwDecrypt, pkt[key]) elif key == 'User-Name': usernm = pkt[key] reply = pkt.CreateReply() replyq = {'user': usernm, 'pass': passwd} if passwd == [pswd]: reply.code = packet.AccessAccept replyq['reply'] = True else: reply.code = packet.AccessReject replyq['reply'] = False outq.put(replyq) if addr is None: sock.send(reply.ReplyPacket()) else: sock.sendto(reply.ReplyPacket(), addr) sock.close() class UDPRadiusDaemon(RadiusDaemon): def listen(self, addr): sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) sock.bind((addr.split(':')[0], int(addr.split(':')[1]))) return sock def recvRequest(self, sock): (buf, addr) = sock.recvfrom(RadiusDaemon.MAX_PACKET_SIZE) return (buf, sock, addr) class UnixRadiusDaemon(RadiusDaemon): def listen(self, addr): sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) if os.path.exists(addr): os.remove(addr) sock.bind(addr) sock.listen(1) return (sock, addr) def recvRequest(self, (sock, addr)): conn = sock.accept()[0] sock.close() os.remove(addr) buf = "" remain = RadiusDaemon.MAX_PACKET_SIZE while True: buf += conn.recv(remain) remain = RadiusDaemon.MAX_PACKET_SIZE - len(buf) if (len(buf) >= 4): remain = struct.unpack("!BBH", buf[0:4])[2] - len(buf) if (remain <= 0): return (buf, conn, None) def verify(daemon, queue, reply, usernm, passwd): try: data = queue.get(timeout=1) except Empty: sys.stderr.write("ERROR: Packet not received by daemon!\n") daemon.terminate() sys.exit(1) assert data['reply'] is reply assert data['user'] == [usernm] assert data['pass'] == [passwd] daemon.join() def otpconfig(toktype, username=None, indicators=None): val = '[{"type": "%s"' % toktype if username is not None: val += ', "username": "%s"' % username if indicators is not None: qind = ['"%s"' % s for s in indicators] jsonlist = '[' + ', '.join(qind) + ']' val += ', "indicators":' + jsonlist val += '}]' return val prefix = "/tmp/%d" % os.getpid() secret_file = prefix + ".secret" socket_file = prefix + ".socket" with open(secret_file, "w") as file: file.write("otptest") atexit.register(lambda: os.remove(secret_file)) conf = {'plugins': {'kdcpreauth': {'enable_only': 'otp'}}, 'otp': {'udp': {'server': '127.0.0.1:$port9', 'secret': secret_file, 'strip_realm': 'true', 'indicator': ['indotp1', 'indotp2']}, 'unix': {'server': socket_file, 'strip_realm': 'false'}}} queue = Queue() realm = K5Realm(kdc_conf=conf) realm.run([kadminl, 'modprinc', '+requires_preauth', realm.user_princ]) flags = ['-T', realm.ccache] server_addr = '127.0.0.1:' + str(realm.portbase + 9) ## Test UDP fail / custom username daemon = UDPRadiusDaemon(args=(server_addr, secret_file, 'accept', queue)) daemon.start() queue.get() realm.run([kadminl, 'setstr', realm.user_princ, 'otp', otpconfig('udp', 'custom')]) realm.kinit(realm.user_princ, 'reject', flags=flags, expected_code=1) verify(daemon, queue, False, 'custom', 'reject') ## Test UDP success / standard username daemon = UDPRadiusDaemon(args=(server_addr, secret_file, 'accept', queue)) daemon.start() queue.get() realm.run([kadminl, 'setstr', realm.user_princ, 'otp', otpconfig('udp')]) realm.kinit(realm.user_princ, 'accept', flags=flags) verify(daemon, queue, True, realm.user_princ.split('@')[0], 'accept') realm.extract_keytab(realm.krbtgt_princ, realm.keytab) realm.run(['./adata', realm.krbtgt_princ], expected_msg='+97: [indotp1, indotp2]') # Repeat with an indicators override in the string attribute. daemon = UDPRadiusDaemon(args=(server_addr, secret_file, 'accept', queue)) daemon.start() queue.get() oconf = otpconfig('udp', indicators=['indtok1', 'indtok2']) realm.run([kadminl, 'setstr', realm.user_princ, 'otp', oconf]) realm.kinit(realm.user_princ, 'accept', flags=flags) verify(daemon, queue, True, realm.user_princ.split('@')[0], 'accept') realm.extract_keytab(realm.krbtgt_princ, realm.keytab) realm.run(['./adata', realm.krbtgt_princ], expected_msg='+97: [indtok1, indtok2]') # Detect upstream pyrad bug # https://github.com/wichert/pyrad/pull/18 try: auth = packet.Packet.CreateAuthenticator() packet.Packet(authenticator=auth, secret="").ReplyPacket() except AssertionError: skip_rest('OTP UNIX domain socket tests', 'pyrad assertion bug detected') ## Test Unix fail / custom username daemon = UnixRadiusDaemon(args=(socket_file, '', 'accept', queue)) daemon.start() queue.get() realm.run([kadminl, 'setstr', realm.user_princ, 'otp', otpconfig('unix', 'custom')]) realm.kinit(realm.user_princ, 'reject', flags=flags, expected_code=1) verify(daemon, queue, False, 'custom', 'reject') ## Test Unix success / standard username daemon = UnixRadiusDaemon(args=(socket_file, '', 'accept', queue)) daemon.start() queue.get() realm.run([kadminl, 'setstr', realm.user_princ, 'otp', otpconfig('unix')]) realm.kinit(realm.user_princ, 'accept', flags=flags) verify(daemon, queue, True, realm.user_princ, 'accept') success('OTP tests') krb5-1.16/src/tests/t_kdb_locking.py0000755000704600001450000000155313211554426017301 0ustar ghudsonlibuuid#!/usr/bin/python # This is a regression test for # https://bugzilla.redhat.com/show_bug.cgi?id=586032 . # # We start a KDC, remove the kadm5 lock file, use the KDC, re-create the # kadm5 lock file, and use kadmin.local. The kinit should fail, and the # kadmin.local should succeed. import os from k5test import * p = 'foo' realm = K5Realm(create_user=False) realm.addprinc(p, p) kadm5_lock = os.path.join(realm.testdir, 'db.kadm5.lock') if not os.path.exists(kadm5_lock): fail('kadm5 lock file not created: ' + kadm5_lock) os.unlink(kadm5_lock) realm.kinit(p, p, [], expected_code=1, expected_msg='A service is not available') f = open(kadm5_lock, 'w') f.close() output = realm.run([kadminl, 'modprinc', '-allow_tix', p]) if 'Cannot lock database' in output: fail('krb5kdc still holds a lock on the principal db') success('KDB locking tests') krb5-1.16/src/tests/unlockiter.c0000644000704600001450000001652213211554426016460 0ustar ghudsonlibuuid/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* tests/unlockiter.c - test program for unlocked iteration */ /* * Copyright (C) 2014 by the Massachusetts Institute of Technology. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ /* * Test unlocked KDB iteration. */ #include #include #include #include #include #include #include #include #include #include /* Some platforms need memset() for FD_ZERO */ #include struct cb_arg { int inpipe; int outpipe; int timeout; int done; }; /* Helper function for cb(): read a sync byte (with possible timeout), then * write a sync byte. */ static int syncpair_rw(const char *name, struct cb_arg *arg, char *cp, int timeout) { struct timeval tv; fd_set rset; int nfds; FD_ZERO(&rset); FD_SET(arg->inpipe, &rset); tv.tv_sec = timeout; tv.tv_usec = 0; printf("cb: waiting for %s sync pair\n", name); nfds = select(arg->inpipe + 1, &rset, NULL, NULL, (timeout == 0) ? NULL : &tv); if (nfds < 0) return -1; if (nfds == 0) { errno = ETIMEDOUT; return -1; } if (read(arg->inpipe, cp, 1) < 0) return -1; printf("cb: writing %s sync pair\n", name); if (write(arg->outpipe, cp, 1) < 0) return -1; return 0; } /* On the first iteration only, receive and send sync bytes to the locking * child to drive its locking activities. */ static krb5_error_code cb(void *argin, krb5_db_entry *ent) { struct cb_arg *arg = argin; char c = '\0'; if (arg->done) return 0; if (syncpair_rw("first", arg, &c, 0) < 0) { com_err("cb", errno, "first sync pair"); return errno; } if (syncpair_rw("second", arg, &c, arg->timeout) < 0) { com_err("cb", errno, "second sync pair"); return errno; } printf("cb: waiting for final sync byte\n"); if (read(arg->inpipe, &c, 1) < 0) { com_err("cb", errno, "final sync byte"); return errno; } arg->done = 1; return 0; } /* Parent process: iterate over the KDB, using a callback that synchronizes * with the locking child. */ static int iterator(struct cb_arg *cb_arg, char **db_args, pid_t child) { krb5_error_code retval; krb5_context ctx; retval = krb5_init_context_profile(NULL, KRB5_INIT_CONTEXT_KDC, &ctx); if (retval) goto cleanup; retval = krb5_db_open(ctx, db_args, KRB5_KDB_OPEN_RW | KRB5_KDB_SRV_TYPE_ADMIN); if (retval) goto cleanup; retval = krb5_db_iterate(ctx, NULL, cb, cb_arg, 0); if (retval) goto cleanup; retval = krb5_db_fini(ctx); cleanup: krb5_free_context(ctx); if (retval) { com_err("iterator", retval, ""); kill(child, SIGTERM); exit(1); } return retval; } /* Helper function for locker(): write, then receive a sync byte. */ static int syncpair_wr(const char *name, int inpipe, int outpipe, unsigned char *cp) { printf("locker: writing %s sync pair\n", name); if (write(outpipe, cp, 1) < 0) return -1; printf("locker: waiting for %s sync pair\n", name); if (read(inpipe, cp, 1) < 0) return -1; return 0; } /* Child process: acquire and release a write lock on the KDB, synchronized * with parent. */ static int locker(int inpipe, int outpipe, char **db_args) { krb5_error_code retval; unsigned char c = '\0'; krb5_context ctx; retval = krb5_init_context_profile(NULL, KRB5_INIT_CONTEXT_KDC, &ctx); if (retval) goto cleanup; retval = krb5_db_open(ctx, db_args, KRB5_KDB_OPEN_RW | KRB5_KDB_SRV_TYPE_ADMIN); if (retval) goto cleanup; if (syncpair_wr("first", inpipe, outpipe, &c) < 0) { retval = errno; goto cleanup; } printf("locker: acquiring lock...\n"); retval = krb5_db_lock(ctx, KRB5_DB_LOCKMODE_EXCLUSIVE); if (retval) goto cleanup; printf("locker: acquired lock\n"); if (syncpair_wr("second", inpipe, outpipe, &c) < 0) { retval = errno; goto cleanup; } krb5_db_unlock(ctx); printf("locker: released lock\n"); printf("locker: writing final sync byte\n"); if (write(outpipe, &c, 1) < 0) { retval = errno; goto cleanup; } retval = krb5_db_fini(ctx); cleanup: if (retval) com_err("locker", retval, ""); krb5_free_context(ctx); exit(retval != 0); } static void usage(const char *prog) { fprintf(stderr, "usage: %s [-lu] [-t timeout]\n", prog); exit(1); } int main(int argc, char *argv[]) { struct cb_arg cb_arg; pid_t child; char *db_args[2] = { NULL, NULL }; int c; int cstatus; int pipe_to_locker[2], pipe_to_iterator[2]; cb_arg.timeout = 1; cb_arg.done = 0; while ((c = getopt(argc, argv, "lt:u")) != -1) { switch (c) { case 'l': db_args[0] = "lockiter"; break; case 't': cb_arg.timeout = atoi(optarg); break; case 'u': db_args[0] = "unlockiter"; break; default: usage(argv[0]); } } if (pipe(pipe_to_locker) < 0) { com_err(argv[0], errno, "pipe(p_il)"); exit(1); } if (pipe(pipe_to_iterator) < 0) { com_err(argv[0], errno, "pipe(p_li)"); exit(1); } cb_arg.inpipe = pipe_to_iterator[0]; cb_arg.outpipe = pipe_to_locker[1]; child = fork(); switch (child) { case -1: com_err(argv[0], errno, "fork"); exit(1); break; case 0: locker(pipe_to_locker[0], pipe_to_iterator[1], db_args); break; default: if (iterator(&cb_arg, db_args, child)) exit(1); if (wait(&cstatus) < 0) { com_err(argv[0], errno, "wait"); exit(1); } if (WIFSIGNALED(cstatus)) exit(1); if (WIFEXITED(cstatus) && WEXITSTATUS(cstatus) != 0) { exit(1); } } exit(0); } krb5-1.16/src/tests/t_ccache.py0000755000704600001450000001603713211554426016244 0ustar ghudsonlibuuid#!/usr/bin/python # Copyright (C) 2011 by the Massachusetts Institute of Technology. # All rights reserved. # Export of this software from the United States of America may # require a specific license from the United States Government. # It is the responsibility of any person or organization contemplating # export to obtain such a license before exporting. # # WITHIN THAT CONSTRAINT, permission to use, copy, modify, and # distribute this software and its documentation for any purpose and # without fee is hereby granted, provided that the above copyright # notice appear in all copies and that both that copyright notice and # this permission notice appear in supporting documentation, and that # the name of M.I.T. not be used in advertising or publicity pertaining # to distribution of the software without specific, written prior # permission. Furthermore if you modify this software you must label # your software as modified software and not distribute it in such a # fashion that it might be confused with the original M.I.T. software. # M.I.T. makes no representations about the suitability of # this software for any purpose. It is provided "as is" without express # or implied warranty. from k5test import * realm = K5Realm(create_host=False) keyctl = which('keyctl') out = realm.run([klist, '-c', 'KEYRING:process:abcd'], expected_code=1) test_keyring = (keyctl is not None and 'Unknown credential cache type' not in out) if not test_keyring: skipped('keyring ccache tests', 'keyring support not built') # Test kdestroy and klist of a non-existent ccache. realm.run([kdestroy]) realm.run([klist], expected_code=1, expected_msg='No credentials cache found') # Test kinit with an inaccessible ccache. realm.kinit(realm.user_princ, password('user'), flags=['-c', 'testdir/xx/yy'], expected_code=1, expected_msg='Failed to store credentials') # Test klist -s with a single ccache. realm.run([klist, '-s'], expected_code=1) realm.kinit(realm.user_princ, password('user')) realm.run([klist, '-s']) realm.kinit(realm.user_princ, password('user'), ['-l', '-1s']) realm.run([klist, '-s'], expected_code=1) realm.kinit(realm.user_princ, password('user'), ['-S', 'kadmin/admin']) realm.run([klist, '-s']) realm.run([kdestroy]) realm.run([klist, '-s'], expected_code=1) realm.addprinc('alice', password('alice')) realm.addprinc('bob', password('bob')) realm.addprinc('carol', password('carol')) def collection_test(realm, ccname): oldccname = realm.env['KRB5CCNAME'] realm.env['KRB5CCNAME'] = ccname realm.run([klist, '-A', '-s'], expected_code=1) realm.kinit('alice', password('alice')) realm.run([klist], expected_msg='Default principal: alice@') realm.run([klist, '-A', '-s']) realm.run([kdestroy]) output = realm.run([klist], expected_code=1) if 'No credentials cache' not in output and 'not found' not in output: fail('Initial kdestroy failed to destroy primary cache.') output = realm.run([klist, '-l'], expected_code=1) if not output.endswith('---\n') or output.count('\n') != 2: fail('Initial kdestroy failed to empty cache collection.') realm.run([klist, '-A', '-s'], expected_code=1) realm.kinit('alice', password('alice')) realm.kinit('carol', password('carol')) output = realm.run([klist, '-l']) if '---\ncarol@' not in output or '\nalice@' not in output: fail('klist -l did not show expected output after two kinits.') realm.kinit('alice', password('alice')) output = realm.run([klist, '-l']) if '---\nalice@' not in output or output.count('\n') != 4: fail('klist -l did not show expected output after re-kinit for alice.') realm.kinit('bob', password('bob')) output = realm.run([klist, '-A', ccname]) if 'bob@' not in output.splitlines()[1] or 'alice@' not in output or \ 'carol' not in output or output.count('Default principal:') != 3: fail('klist -A did not show expected output after kinit for bob.') realm.run([kswitch, '-p', 'carol']) output = realm.run([klist, '-l']) if '---\ncarol@' not in output or output.count('\n') != 5: fail('klist -l did not show expected output after kswitch to carol.') # Switch to specifying the collection name on the command line # (only works with klist/kdestroy for now, not kinit/kswitch). realm.env['KRB5CCNAME'] = oldccname realm.run([kdestroy, '-c', ccname]) output = realm.run([klist, '-l', ccname]) if 'carol@' in output or 'bob@' not in output or output.count('\n') != 4: fail('kdestroy failed to remove only primary ccache.') realm.run([klist, '-s', ccname], expected_code=1) realm.run([klist, '-A', '-s', ccname]) realm.run([kdestroy, '-A', '-c', ccname]) output = realm.run([klist, '-l', ccname], expected_code=1) if not output.endswith('---\n') or output.count('\n') != 2: fail('kdestroy -a failed to empty cache collection.') realm.run([klist, '-A', '-s', ccname], expected_code=1) collection_test(realm, 'DIR:' + os.path.join(realm.testdir, 'cc')) if test_keyring: def cleanup_keyring(anchor, name): out = realm.run(['keyctl', 'list', anchor]) if ('keyring: ' + name + '\n') in out: keyid = realm.run(['keyctl', 'search', anchor, 'keyring', name]) realm.run(['keyctl', 'unlink', keyid.strip(), anchor]) # Use realm.testdir as the collection name to avoid conflicts with # other build trees. cname = realm.testdir col_ringname = '_krb_' + cname cleanup_keyring('@s', col_ringname) collection_test(realm, 'KEYRING:session:' + cname) cleanup_keyring('@s', col_ringname) # Test legacy keyring cache linkage. realm.env['KRB5CCNAME'] = 'KEYRING:' + cname realm.run([kdestroy, '-A']) realm.kinit(realm.user_princ, password('user')) msg = 'KEYRING:legacy:' + cname + ':' + cname realm.run([klist, '-l'], expected_msg=msg) # Make sure this cache is linked to the session keyring. id = realm.run([keyctl, 'search', '@s', 'keyring', cname]) realm.run([keyctl, 'list', id.strip()], expected_msg='user: __krb5_princ__') # Remove the collection keyring. When the collection is # reinitialized, the legacy cache should reappear inside it # automatically as the primary cache. cleanup_keyring('@s', col_ringname) realm.run([klist], expected_msg=realm.user_princ) coll_id = realm.run([keyctl, 'search', '@s', 'keyring', '_krb_' + cname]) msg = id.strip() + ':' realm.run([keyctl, 'list', coll_id.strip()], expected_msg=msg) # Destroy the cache and check that it is unlinked from the session keyring. realm.run([kdestroy]) realm.run([keyctl, 'search', '@s', 'keyring', cname], expected_code=1) cleanup_keyring('@s', col_ringname) # Test parameter expansion in default_ccache_name realm.stop() conf = {'libdefaults': {'default_ccache_name': 'testdir/%{null}abc%{uid}'}} realm = K5Realm(krb5_conf=conf, create_kdb=False) del realm.env['KRB5CCNAME'] uidstr = str(os.getuid()) msg = 'testdir/abc%s' % uidstr realm.run([klist], expected_code=1, expected_msg=msg) success('Credential cache tests') krb5-1.16/src/tests/shlib/0000755000704600001450000000000013211554426015230 5ustar ghudsonlibuuidkrb5-1.16/src/tests/shlib/deps0000644000704600001450000000047413211554426016113 0ustar ghudsonlibuuid# # Generated makefile dependencies follow. # $(OUTPRE)t_loader.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/gssapi/gssapi.h $(BUILDTOP)/include/krb5/krb5.h \ $(COM_ERR_DEPS) $(top_srcdir)/include/k5-platform.h \ $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/krb5.h \ t_loader.c krb5-1.16/src/tests/shlib/t_loader.c0000644000704600001450000003202413211554426017166 0ustar ghudsonlibuuid/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* tests/shlib/t_loader.c */ /* * Copyright (C) 2005 by the Massachusetts Institute of Technology. * All rights reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #include "k5-platform.h" #include "krb5.h" #include "gssapi/gssapi.h" #define HAVE_DLOPEN 1 static int verbose = 1; #ifdef HAVE_DLFCN_H # include #endif /* Solaris man page recommends link.h too */ /* lazy = 1 means resolve symbols later, 0 means now; any other flags we should be testing? On Windows, maybe? Return value is the library handle. On error, print a message and exit. */ #define do_open(LIB,REV,FLAGS) do_open_1(LIB,REV,FLAGS,__LINE__) static void *do_open_1(const char *libname, const char *rev, int lazy, int line); /* Look up a function symbol in the library and return a pointer. The return value may need casting to the correct type. On error, print a message and exit. */ static void *get_sym_1(void *libhandle, const char *sym, int line); #define get_sym(LIB, NAME) get_sym_1(LIB, NAME, __LINE__) #define GET_FSYM(TYPE, LIB, NAME) ((TYPE) get_sym(LIB, NAME)) #define get_gfun(LIB, NAME) ((OM_uint32 KRB5_CALLCONV(*)()) get_sym(LIB, NAME)) /* Close dynamically-opened library. If the OS reports an error in doing so, print a message and exit. */ #define do_close(X) do_close_1(X, __LINE__) static void do_close_1(void *libhandle, int line); #ifdef HAVE_DLOPEN #ifdef _AIX # define SHLIB_SUFFIX ".a" #else # define SHLIB_SUFFIX ".so" #endif #define HORIZ 25 static void *do_open_1(const char *libname, const char *rev, int lazy, int line) { void *p; char *namebuf; int r; if (verbose) printf("from line %d: do_open(%s)...%*s", line, libname, HORIZ-strlen(libname), ""); #ifdef _AIX r = asprintf(&namebuf, "lib%s%s", libname, SHLIB_SUFFIX); #else r = asprintf(&namebuf, "lib%s%s(shr.o.%s)", libname, SHLIB_SUFFIX, rev); #endif if (r < 0) { perror("asprintf"); exit(1); } #ifndef RTLD_MEMBER #define RTLD_MEMBER 0 #endif p = dlopen(namebuf, (lazy ? RTLD_LAZY : RTLD_NOW) | RTLD_MEMBER); if (p == 0) { fprintf(stderr, "dlopen of %s failed: %s\n", namebuf, dlerror()); exit(1); } free(namebuf); if (verbose) printf("done: %p\n", p); return p; } #define SYM_PREFIX "" static void *get_sym_1(void *libhandle, const char *symname, int line) { void *s; /* Bah. Fix this later, if we care. */ assert(strlen(SYM_PREFIX) == 0); if (verbose) printf("from line %d: get_sym(%s)...%*s", line, symname, HORIZ-strlen(symname), ""); s = dlsym(libhandle, symname); if (s == 0) { fprintf(stderr, "symbol %s not found\n", symname); exit(1); } if (verbose) printf("done: %p\n", s); return s; } static void do_close_1(void *libhandle, int line) { if (verbose) { char pbuf[3*sizeof(libhandle)+4]; snprintf(pbuf, sizeof(pbuf), "%p", libhandle); printf("from line %d: do_close(%s)...%*s", line, pbuf, HORIZ-1-strlen(pbuf), ""); } if (dlclose(libhandle) != 0) { fprintf(stderr, "dlclose failed: %s\n", dlerror()); exit(1); } if (verbose) printf("done\n"); } #elif defined _WIN32 static void *do_open(const char *libname, int lazy) { /* To be written? */ abort(); } static void *get_sym(void *libhandle, const char *symname) { abort(); } static void do_close(void *libhandle) { abort(); } #else static void *do_open(const char *libname, int lazy) { printf("don't know how to do dynamic loading here, punting\n"); exit(0); } static void *get_sym(void *libhandle, const char *symname) { abort(); } static void do_close(void *libhandle) { abort(); } #endif int main() { void *celib, *k5lib, *gsslib, *celib2; (void) setvbuf(stdout, 0, _IONBF, 0); #if 0 /* Simplest test: Load, then unload out of order. */ celib = do_open("com_err", "3.0", 0); k5lib = do_open("krb5", "3.2", 0); gsslib = do_open("gssapi_krb5", "2.2", 0); celib2 = do_open("com_err", "3.0", 0); do_close(celib); do_close(k5lib); do_close(celib2); do_close(gsslib); #endif celib = do_open("com_err", "3.0", 0); k5lib = do_open("krb5", "3.2", 0); gsslib = do_open("gssapi_krb5", "2.2", 0); celib2 = do_open("com_err", "3.0", 0); do_close(celib2); { typedef krb5_error_code KRB5_CALLCONV (*ict)(krb5_context *); typedef void KRB5_CALLCONV (*fct)(krb5_context); ict init_context = (ict) get_sym(k5lib, "krb5_init_context"); fct free_context = (fct) get_sym(k5lib, "krb5_free_context"); krb5_context ctx; krb5_error_code err; #define CALLING(S) (verbose ? printf("at line %d: calling %s...%*s", __LINE__, #S, (int)(HORIZ+1-strlen(#S)), "") : 0) #define DONE() (verbose ? printf("done\n") : 0) CALLING(krb5_init_context); err = init_context(&ctx); DONE(); if (err) { fprintf(stderr, "error 0x%lx initializing context\n", (unsigned long) err); exit(1); } CALLING(krb5_free_context); free_context(ctx); DONE(); } celib2 = do_open("com_err", "3.0", 0); do_close(celib); do_close(k5lib); do_close(celib2); do_close(gsslib); /* Test gssapi_krb5 without having loaded anything else. */ gsslib = do_open("gssapi_krb5", "2.2", 1); { OM_uint32 KRB5_CALLCONV (*init_sec_context)(OM_uint32 *, gss_cred_id_t, gss_ctx_id_t *, gss_name_t, gss_OID, OM_uint32, OM_uint32, gss_channel_bindings_t, gss_buffer_t, gss_OID *, gss_buffer_t, OM_uint32 *, OM_uint32 *) = get_gfun(gsslib, "gss_init_sec_context"); OM_uint32 KRB5_CALLCONV (*import_name)(OM_uint32 *, gss_buffer_t, gss_OID, gss_name_t *) = get_gfun(gsslib, "gss_import_name"); OM_uint32 KRB5_CALLCONV (*release_buffer)(OM_uint32 *, gss_buffer_t) = get_gfun(gsslib, "gss_release_buffer"); OM_uint32 KRB5_CALLCONV (*release_name)(OM_uint32 *, gss_name_t *) = get_gfun(gsslib, "gss_release_name"); OM_uint32 KRB5_CALLCONV (*delete_sec_context)(OM_uint32 *, gss_ctx_id_t *, gss_buffer_t) = get_gfun(gsslib, "gss_delete_sec_context"); OM_uint32 gmaj, gmin; OM_uint32 retflags; gss_ctx_id_t gctx = GSS_C_NO_CONTEXT; gss_buffer_desc token; gss_name_t target; static gss_buffer_desc target_name_buf = { 9, "x@mit.edu" }; static gss_OID_desc service_name = { 10, "\x2a\x86\x48\x86\xf7\x12\x01\x02\x01\x04" }; CALLING(gss_import_name); gmaj = import_name(&gmin, &target_name_buf, &service_name, &target); DONE(); if (gmaj != GSS_S_COMPLETE) { fprintf(stderr, "import_name reports error major 0x%lx minor 0x%lx(%ld)\n", (unsigned long) gmaj, (unsigned long) gmin, (signed long) gmin); exit(1); } /* This will probably get different errors, depending on whether we have tickets at the time. Doesn't matter much, we're ignoring the error and testing whether we're doing cleanup properly. (Though the internal cleanup needed in the two cases might be different.) */ CALLING(gss_init_sec_context); gmaj = init_sec_context(&gmin, GSS_C_NO_CREDENTIAL, &gctx, target, GSS_C_NULL_OID, 0, 0, NULL, GSS_C_NO_BUFFER, NULL, &token, &retflags, NULL); DONE(); /* Ignore success/failure indication. */ if (token.length) { CALLING(gss_release_buffer); release_buffer(&gmin, &token); DONE(); } CALLING(gss_release_name); release_name(&gmin, &target); DONE(); if (gctx != GSS_C_NO_CONTEXT) { CALLING(gss_delete_sec_context); delete_sec_context(&gmin, gctx, GSS_C_NO_BUFFER); DONE(); } } do_close(gsslib); /* Test gssapi_krb5 with com_err already loaded, then unload com_err first. */ celib = do_open("com_err", "3.0", 1); gsslib = do_open("gssapi_krb5", "2.2", 1); { OM_uint32 KRB5_CALLCONV (*init_sec_context)(OM_uint32 *, gss_cred_id_t, gss_ctx_id_t *, gss_name_t, gss_OID, OM_uint32, OM_uint32, gss_channel_bindings_t, gss_buffer_t, gss_OID *, gss_buffer_t, OM_uint32 *, OM_uint32 *) = get_gfun(gsslib, "gss_init_sec_context"); OM_uint32 KRB5_CALLCONV (*import_name)(OM_uint32 *, gss_buffer_t, gss_OID, gss_name_t *) = get_gfun(gsslib, "gss_import_name"); OM_uint32 KRB5_CALLCONV (*release_buffer)(OM_uint32 *, gss_buffer_t) = get_gfun(gsslib, "gss_release_buffer"); OM_uint32 KRB5_CALLCONV (*release_name)(OM_uint32 *, gss_name_t *) = get_gfun(gsslib, "gss_release_name"); OM_uint32 KRB5_CALLCONV (*delete_sec_context)(OM_uint32 *, gss_ctx_id_t *, gss_buffer_t) = get_gfun(gsslib, "gss_delete_sec_context"); OM_uint32 gmaj, gmin; OM_uint32 retflags; gss_ctx_id_t gctx = GSS_C_NO_CONTEXT; gss_buffer_desc token; gss_name_t target; static gss_buffer_desc target_name_buf = { 9, "x@mit.edu" }; static gss_OID_desc service_name = { 10, "\x2a\x86\x48\x86\xf7\x12\x01\x02\x01\x04" }; CALLING(gss_import_name); gmaj = import_name(&gmin, &target_name_buf, &service_name, &target); DONE(); if (gmaj != GSS_S_COMPLETE) { fprintf(stderr, "import_name reports error major 0x%lx minor 0x%lx(%ld)\n", (unsigned long) gmaj, (unsigned long) gmin, (signed long) gmin); exit(1); } /* This will probably get different errors, depending on whether we have tickets at the time. Doesn't matter much, we're ignoring the error and testing whether we're doing cleanup properly. (Though the internal cleanup needed in the two cases might be different.) */ CALLING(gss_init_sec_context); gmaj = init_sec_context(&gmin, GSS_C_NO_CREDENTIAL, &gctx, target, GSS_C_NULL_OID, 0, 0, NULL, GSS_C_NO_BUFFER, NULL, &token, &retflags, NULL); DONE(); /* Ignore success/failure indication. */ if (token.length) { CALLING(gss_release_buffer); release_buffer(&gmin, &token); DONE(); } CALLING(gss_release_name); release_name(&gmin, &target); DONE(); if (gctx != GSS_C_NO_CONTEXT) { CALLING(gss_delete_sec_context); delete_sec_context(&gmin, gctx, GSS_C_NO_BUFFER); DONE(); } } do_close(celib); do_close(gsslib); return 0; } krb5-1.16/src/tests/shlib/Makefile.in0000644000704600001450000000052513211554426017277 0ustar ghudsonlibuuidmydir=tests$(S)shlib BUILDTOP=$(REL)..$(S).. #VALGRIND=valgrind #VALGRINDFLAGS=--tool=memcheck --leak-check=yes --show-reachable=yes SRCS=$(srcdir)/t_loader.c all: run-t_loader: t_loader $(RUN_TEST) ./t_loader t_loader: t_loader.o $(CC_LINK) -o t_loader t_loader.o $(DL_LIB) check-unix: install: clean: $(RM) t_loader.o t_loader krb5-1.16/src/tests/hooks.c0000644000704600001450000002144713211554426015426 0ustar ghudsonlibuuid/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* tests/hooks.c - test harness for KDC send and recv hooks */ /* * Copyright (C) 2016 by the Massachusetts Institute of Technology. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "k5-int.h" static krb5_context ctx; static void check_code(krb5_error_code code, const char *file, int line) { const char *errmsg; if (code) { errmsg = krb5_get_error_message(ctx, code); fprintf(stderr, "%s:%d -- %s (code=%d)\n", file, line, errmsg, (int)code); krb5_free_error_message(ctx, errmsg); exit(1); } } #define check(code) check_code((code), __FILE__, __LINE__) /* Verify that the canonicalize bit is set in an AS-REQ and remove it. */ static krb5_error_code test_send_as_req(krb5_context context, void *data, const krb5_data *realm, const krb5_data *message, krb5_data **new_message_out, krb5_data **reply_out) { krb5_kdc_req *as_req; int cmp; assert(krb5_is_as_req(message)); check(decode_krb5_as_req(message, &as_req)); assert(as_req->msg_type == KRB5_AS_REQ); assert(as_req->kdc_options & KDC_OPT_CANONICALIZE); assert(as_req->client->realm.length == realm->length); cmp = memcmp(as_req->client->realm.data, realm->data, realm->length); assert(cmp == 0); /* Remove the canonicalize flag and create a new message. */ as_req->kdc_options &= ~KDC_OPT_CANONICALIZE; check(encode_krb5_as_req(as_req, new_message_out)); krb5_free_kdc_req(context, as_req); return 0; } /* Verify that reply is an AS-REP with kvno 1 and a valid enctype. */ static krb5_error_code test_recv_as_rep(krb5_context context, void *data, krb5_error_code code, const krb5_data *realm, const krb5_data *message, const krb5_data *reply, krb5_data **new_reply) { krb5_kdc_rep *as_rep; assert(code == 0); assert(krb5_is_as_rep(reply)); check(decode_krb5_as_rep(reply, &as_rep)); assert(as_rep->msg_type == KRB5_AS_REP); assert(as_rep->ticket->enc_part.kvno == 1); assert(krb5_c_valid_enctype(as_rep->ticket->enc_part.enctype)); krb5_free_kdc_rep(context, as_rep); return 0; } /* Create a fake error reply. */ static krb5_error_code test_send_error(krb5_context context, void *data, const krb5_data *realm, const krb5_data *message, krb5_data **new_message_out, krb5_data **reply_out) { krb5_error_code ret; krb5_error err; krb5_principal client, server; char *realm_str, *princ_str; int r; realm_str = k5memdup0(realm->data, realm->length, &ret); check(ret); r = asprintf(&princ_str, "invalid@%s", realm_str); assert(r > 0); check(krb5_parse_name(ctx, princ_str, &client)); free(princ_str); r = asprintf(&princ_str, "krbtgt@%s", realm_str); assert(r > 0); check(krb5_parse_name(ctx, princ_str, &server)); free(princ_str); free(realm_str); err.magic = KV5M_ERROR; err.ctime = 1971196337; err.cusec = 0; err.susec = 97008; err.stime = 1458219390; err.error = 6; err.client = client; err.server = server; err.text = string2data("CLIENT_NOT_FOUND"); err.e_data = empty_data(); check(encode_krb5_error(&err, reply_out)); krb5_free_principal(ctx, client); krb5_free_principal(ctx, server); return 0; } static krb5_error_code test_recv_error(krb5_context context, void *data, krb5_error_code code, const krb5_data *realm, const krb5_data *message, const krb5_data *reply, krb5_data **new_reply) { /* The send hook created a reply, so this hook should not be executed. */ abort(); } /* Modify an AS-REP reply, change the msg_type to KRB5_TGS_REP. */ static krb5_error_code test_recv_modify_reply(krb5_context context, void *data, krb5_error_code code, const krb5_data *realm, const krb5_data *message, const krb5_data *reply, krb5_data **new_reply) { krb5_kdc_rep *as_rep; assert(code == 0); assert(krb5_is_as_rep(reply)); check(decode_krb5_as_rep(reply, &as_rep)); as_rep->msg_type = KRB5_TGS_REP; check(encode_krb5_as_rep(as_rep, new_reply)); krb5_free_kdc_rep(context, as_rep); return 0; } /* Return an error given by the callback data argument. */ static krb5_error_code test_send_return_value(krb5_context context, void *data, const krb5_data *realm, const krb5_data *message, krb5_data **new_message_out, krb5_data **reply_out) { assert(data != NULL); return *(krb5_error_code *)data; } /* Return an error given by the callback argument. */ static krb5_error_code test_recv_return_value(krb5_context context, void *data, krb5_error_code code, const krb5_data *realm, const krb5_data *message, const krb5_data *reply, krb5_data **new_reply) { assert(data != NULL); return *(krb5_error_code *)data; } int main(int argc, char *argv[]) { const char *principal, *password; krb5_principal client; krb5_get_init_creds_opt *opts; krb5_creds creds; krb5_error_code ret, test_return_code; if (argc != 3) { fprintf(stderr, "Usage: %s princname password\n", argv[0]); exit(1); } principal = argv[1]; password = argv[2]; check(krb5_init_context(&ctx)); check(krb5_parse_name(ctx, principal, &client)); /* Use a send hook to modify an outgoing AS-REQ. The library will detect * the modification in the reply. */ check(krb5_get_init_creds_opt_alloc(ctx, &opts)); krb5_get_init_creds_opt_set_canonicalize(opts, 1); krb5_set_kdc_send_hook(ctx, test_send_as_req, NULL); krb5_set_kdc_recv_hook(ctx, test_recv_as_rep, NULL); ret = krb5_get_init_creds_password(ctx, &creds, client, password, NULL, NULL, 0, NULL, opts); assert(ret == KRB5_KDCREP_MODIFIED); krb5_get_init_creds_opt_free(ctx, opts); /* Use a send hook to synthesize a KRB-ERROR reply. */ krb5_set_kdc_send_hook(ctx, test_send_error, NULL); krb5_set_kdc_recv_hook(ctx, test_recv_error, NULL); ret = krb5_get_init_creds_password(ctx, &creds, client, password, NULL, NULL, 0, NULL, NULL); assert(ret == KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN); /* Use a recv hook to modify a KDC reply. */ krb5_set_kdc_send_hook(ctx, NULL, NULL); krb5_set_kdc_recv_hook(ctx, test_recv_modify_reply, NULL); ret = krb5_get_init_creds_password(ctx, &creds, client, password, NULL, NULL, 0, NULL, NULL); assert(ret == KRB5KRB_AP_ERR_MSG_TYPE); /* Verify that the user data pointer works in the send hook. */ test_return_code = KRB5KDC_ERR_PREAUTH_FAILED; krb5_set_kdc_send_hook(ctx, test_send_return_value, &test_return_code); krb5_set_kdc_recv_hook(ctx, NULL, NULL); ret = krb5_get_init_creds_password(ctx, &creds, client, password, NULL, NULL, 0, NULL, NULL); assert(ret == KRB5KDC_ERR_PREAUTH_FAILED); /* Verify that the user data pointer works in the recv hook. */ test_return_code = KRB5KDC_ERR_NULL_KEY; krb5_set_kdc_send_hook(ctx, NULL, NULL); krb5_set_kdc_recv_hook(ctx, test_recv_return_value, &test_return_code); ret = krb5_get_init_creds_password(ctx, &creds, client, password, NULL, NULL, 0, NULL, NULL); assert(ret == KRB5KDC_ERR_NULL_KEY); krb5_free_principal(ctx, client); krb5_free_context(ctx); return 0; } krb5-1.16/src/tests/hammer/0000755000704600001450000000000013211554426015400 5ustar ghudsonlibuuidkrb5-1.16/src/tests/hammer/pp.c0000644000704600001450000000112113211554426016156 0ustar ghudsonlibuuid/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* tests/hammer/pp.c */ /* * Copyright 1991 by the Massachusetts Institute of Technology. * All Rights Reserved. * * For copying and distribution information, please see the file * . */ #include "krb5.h" void print_principal(p) krb5_principal p; { char *buf; krb5_error_code retval; if (retval = krb5_unparse_name(p, &buf)) { com_err("DEBUG: Print_principal", retval, "while unparsing name"); exit(1); } printf("%s\n", buf); free(buf); } krb5-1.16/src/tests/hammer/deps0000644000704600001450000000136413211554426016262 0ustar ghudsonlibuuid# # Generated makefile dependencies follow. # $(OUTPRE)kdc5_hammer.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h \ $(top_srcdir)/include/k5-err.h $(top_srcdir)/include/k5-gmt_mktime.h \ $(top_srcdir)/include/k5-int-pkinit.h $(top_srcdir)/include/k5-int.h \ $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-plugin.h \ $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/k5-trace.h \ $(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/authdata_plugin.h \ $(top_srcdir)/include/krb5/plugin.h $(top_srcdir)/include/port-sockets.h \ $(top_srcdir)/include/socket-utils.h kdc5_hammer.c krb5-1.16/src/tests/hammer/Makefile.in0000644000704600001450000000037613211554426017453 0ustar ghudsonlibuuidmydir=tests$(S)hammer BUILDTOP=$(REL)..$(S).. SRCS=$(srcdir)/kdc5_hammer.c all: kdc5_hammer kdc5_hammer: kdc5_hammer.o $(KRB5_BASE_DEPLIBS) $(CC_LINK) -o kdc5_hammer kdc5_hammer.o $(KRB5_BASE_LIBS) install: clean: $(RM) kdc5_hammer.o kdc5_hammer krb5-1.16/src/tests/hammer/kdc5_hammer.c0000644000704600001450000003300013211554426017717 0ustar ghudsonlibuuid/* tests/hammer/kdc5_hammer.c */ /* * Copyright 1990,1991 by the Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #include "k5-int.h" #include "com_err.h" #include #define KRB5_DEFAULT_OPTIONS 0 #define KRB5_DEFAULT_LIFE 60*60*8 /* 8 hours */ #define KRB5_RENEWABLE_LIFE 60*60*2 /* 2 hours */ struct h_timer { float ht_cumulative; float ht_min; float ht_max; krb5_int32 ht_observations; }; extern int optind; extern char *optarg; char *prog; static int brief; static char *cur_realm = 0; static int do_timer = 0; krb5_data tgtname = { 0, KRB5_TGS_NAME_SIZE, KRB5_TGS_NAME }; int verify_cs_pair (krb5_context, char *, krb5_principal, char *, char *, int, int, int, krb5_ccache); int get_tgt (krb5_context, char *, krb5_principal *, krb5_ccache); static void usage(who, status) char *who; int status; { fprintf(stderr, "usage: %s -p prefix -n num_to_check [-c cachename] [-r realmname]\n", who); fprintf(stderr, "\t [-D depth]\n"); fprintf(stderr, "\t [-P preauth type] [-R repeat_count] [-t] [-b] [-v] \n"); exit(status); } static krb5_preauthtype * patype = NULL, patypedata[2] = { 0, -1 }; static krb5_context test_context; struct timeval tstart_time, tend_time; struct timezone dontcare; struct h_timer in_tkt_times = { 0.0, 1000000.0, -1.0, 0 }; struct h_timer tgs_req_times = { 0.0, 1000000.0, -1.0, 0 }; /* * Timer macros. */ #define swatch_on() ((void) gettimeofday(&tstart_time, &dontcare)) #define swatch_eltime() ((gettimeofday(&tend_time, &dontcare)) ? -1.0 : \ (((float) (tend_time.tv_sec - \ tstart_time.tv_sec)) + \ (((float) (tend_time.tv_usec - \ tstart_time.tv_usec))/1000000.0))) int main(argc, argv) int argc; char **argv; { krb5_ccache ccache = NULL; char *cache_name = NULL; /* -f option */ int option; int errflg = 0; krb5_error_code code; int num_to_check, n, i, j, repeat_count, counter; int n_tried, errors; char prefix[BUFSIZ], client[4096], server[4096]; int depth; char ctmp[4096], ctmp2[BUFSIZ], stmp[4096], stmp2[BUFSIZ]; krb5_principal client_princ; krb5_error_code retval; krb5_init_context(&test_context); if (strrchr(argv[0], '/')) prog = strrchr(argv[0], '/')+1; else prog = argv[0]; num_to_check = 0; depth = 1; repeat_count = 1; brief = 0; n_tried = 0; errors = 0; while ((option = getopt(argc, argv, "D:p:n:c:R:P:e:bvr:t")) != -1) { switch (option) { case 't': do_timer = 1; break; case 'b': brief = 1; break; case 'v': brief = 0; break; case 'R': repeat_count = atoi(optarg); /* how many times? */ break; case 'r': cur_realm = optarg; break; case 'D': depth = atoi(optarg); /* how deep to go */ break; case 'p': /* prefix name to check */ strncpy(prefix, optarg, sizeof(prefix) - 1); prefix[sizeof(prefix) - 1] = '\0'; break; case 'n': /* how many to check */ num_to_check = atoi(optarg); break; case 'P': patypedata[0] = atoi(optarg); patype = patypedata; break; case 'c': if (ccache == NULL) { cache_name = optarg; code = krb5_cc_resolve (test_context, cache_name, &ccache); if (code != 0) { com_err (prog, code, "resolving %s", cache_name); errflg++; } } else { fprintf(stderr, "Only one -c option allowed\n"); errflg++; } break; case '?': default: errflg++; break; } } if (!(num_to_check && prefix[0])) usage(prog, 1); if (!cur_realm) { if ((retval = krb5_get_default_realm(test_context, &cur_realm))) { com_err(prog, retval, "while retrieving default realm name"); exit(1); } } if (ccache == NULL) { if ((code = krb5_cc_default(test_context, &ccache))) { com_err(prog, code, "while getting default ccache"); exit(1); } } memset(ctmp, 0, sizeof(ctmp)); memset(stmp, 0, sizeof(stmp)); for (counter = 0; counter < repeat_count; counter++) { fprintf(stderr, "\nRound %d\n", counter); for (n = 1; n <= num_to_check; n++) { /* build the new principal name */ /* we can't pick random names because we need to generate all the names again given a prefix and count to test the db lib and kdb */ ctmp[0] = '\0'; for (i = 1; i <= depth; i++) { (void) snprintf(ctmp2, sizeof(ctmp2), "%s%s%d-DEPTH-%d", (i != 1) ? "/" : "", prefix, n, i); ctmp2[sizeof(ctmp2) - 1] = '\0'; strncat(ctmp, ctmp2, sizeof(ctmp) - 1 - strlen(ctmp)); ctmp[sizeof(ctmp) - 1] = '\0'; snprintf(client, sizeof(client), "%s@%s", ctmp, cur_realm); if (get_tgt (test_context, client, &client_princ, ccache)) { errors++; n_tried++; continue; } n_tried++; stmp[0] = '\0'; for (j = 1; j <= depth; j++) { (void) snprintf(stmp2, sizeof(stmp2), "%s%s%d-DEPTH-%d", (j != 1) ? "/" : "", prefix, n, j); stmp2[sizeof (stmp2) - 1] = '\0'; strncat(stmp, stmp2, sizeof(stmp) - 1 - strlen(stmp)); stmp[sizeof(stmp) - 1] = '\0'; snprintf(server, sizeof(server), "%s@%s", stmp, cur_realm); if (verify_cs_pair(test_context, client, client_princ, stmp, cur_realm, n, i, j, ccache)) errors++; n_tried++; } krb5_free_principal(test_context, client_princ); } } } fprintf (stderr, "\nTried %d. Got %d errors.\n", n_tried, errors); if (do_timer) { if (in_tkt_times.ht_observations) fprintf(stderr, "%8d AS_REQ requests: %9.6f average (min: %9.6f, max:%9.6f)\n", in_tkt_times.ht_observations, in_tkt_times.ht_cumulative / (float) in_tkt_times.ht_observations, in_tkt_times.ht_min, in_tkt_times.ht_max); if (tgs_req_times.ht_observations) fprintf(stderr, "%8d TGS_REQ requests: %9.6f average (min: %9.6f, max:%9.6f)\n", tgs_req_times.ht_observations, tgs_req_times.ht_cumulative / (float) tgs_req_times.ht_observations, tgs_req_times.ht_min, tgs_req_times.ht_max); } (void) krb5_cc_close(test_context, ccache); krb5_free_context(test_context); exit(errors); } static krb5_error_code get_server_key(context, server, enctype, key) krb5_context context; krb5_principal server; krb5_enctype enctype; krb5_keyblock ** key; { krb5_error_code retval; krb5_encrypt_block eblock; char * string; krb5_data salt; krb5_data pwd; if ((retval = krb5_principal2salt(context, server, &salt))) return retval; if ((retval = krb5_unparse_name(context, server, &string))) goto cleanup_salt; pwd.data = string; pwd.length = strlen(string); if ((*key = (krb5_keyblock *)malloc(sizeof(krb5_keyblock)))) { krb5_use_enctype(context, &eblock, enctype); if ((retval = krb5_string_to_key(context, &eblock, *key, &pwd, &salt))) free(*key); } else retval = ENOMEM; free(string); cleanup_salt: free(salt.data); return retval; } int verify_cs_pair(context, p_client_str, p_client, service, hostname, p_num, c_depth, s_depth, ccache) krb5_context context; char *p_client_str; krb5_principal p_client; char * service; char * hostname; int p_num, c_depth, s_depth; krb5_ccache ccache; { krb5_error_code retval; krb5_creds creds; krb5_creds * credsp = NULL; krb5_ticket * ticket = NULL; krb5_keyblock * keyblock = NULL; krb5_auth_context auth_context = NULL; krb5_data request_data = empty_data(); char * sname; float dt; if (brief) fprintf(stderr, "\tprinc (%d) client (%d) for server (%d)\n", p_num, c_depth, s_depth); else fprintf(stderr, "\tclient %s for server %s\n", p_client_str, service); /* Initialize variables */ memset(&creds, 0, sizeof(creds)); /* Do client side */ if (asprintf(&sname, "%s@%s", service, hostname) >= 0) { retval = krb5_parse_name(context, sname, &creds.server); free(sname); } else retval = ENOMEM; if (retval) return(retval); /* obtain ticket & session key */ if ((retval = krb5_cc_get_principal(context, ccache, &creds.client))) { com_err(prog, retval, "while getting client princ for %s", hostname); return retval; } if ((retval = krb5_get_credentials(context, 0, ccache, &creds, &credsp))) { com_err(prog, retval, "while getting creds for %s", hostname); return retval; } if (do_timer) swatch_on(); if ((retval = krb5_mk_req_extended(context, &auth_context, 0, NULL, credsp, &request_data))) { com_err(prog, retval, "while preparing AP_REQ for %s", hostname); goto cleanup; } krb5_auth_con_free(context, auth_context); auth_context = NULL; /* Do server side now */ if ((retval = get_server_key(context, credsp->server, credsp->keyblock.enctype, &keyblock))) { com_err(prog, retval, "while getting server key for %s", hostname); goto cleanup; } if (krb5_auth_con_init(context, &auth_context)) { com_err(prog, retval, "while creating auth_context for %s", hostname); goto cleanup; } if (krb5_auth_con_setuseruserkey(context, auth_context, keyblock)) { com_err(prog, retval, "while setting auth_context key %s", hostname); goto cleanup; } if ((retval = krb5_rd_req(context, &auth_context, &request_data, NULL /* server */, 0, NULL, &ticket))) { com_err(prog, retval, "while decoding AP_REQ for %s", hostname); goto cleanup; } if (do_timer) { dt = swatch_eltime(); tgs_req_times.ht_cumulative += dt; tgs_req_times.ht_observations++; if (dt > tgs_req_times.ht_max) tgs_req_times.ht_max = dt; if (dt < tgs_req_times.ht_min) tgs_req_times.ht_min = dt; } if (!(krb5_principal_compare(context,ticket->enc_part2->client,p_client))){ char *returned_client; if ((retval = krb5_unparse_name(context, ticket->enc_part2->client, &returned_client))) com_err (prog, retval, "Client not as expected, but cannot unparse client name"); else com_err (prog, 0, "Client not as expected (%s).", returned_client); retval = KRB5_PRINC_NOMATCH; free(returned_client); } else { retval = 0; } cleanup: krb5_free_cred_contents(context, &creds); krb5_free_ticket(context, ticket); krb5_auth_con_free(context, auth_context); krb5_free_keyblock(context, keyblock); krb5_free_data_contents(context, &request_data); krb5_free_creds(context, credsp); return retval; } int get_tgt (context, p_client_str, p_client, ccache) krb5_context context; char *p_client_str; krb5_principal *p_client; krb5_ccache ccache; { char *cache_name = NULL; /* -f option */ long lifetime = KRB5_DEFAULT_LIFE; /* -l option */ krb5_error_code code; krb5_creds my_creds; krb5_timestamp start; float dt; krb5_get_init_creds_opt *options; if (!brief) fprintf(stderr, "\tgetting TGT for %s\n", p_client_str); if ((code = krb5_timeofday(context, &start))) { com_err(prog, code, "while getting time of day"); return(-1); } memset(&my_creds, 0, sizeof(my_creds)); if ((code = krb5_parse_name (context, p_client_str, p_client))) { com_err (prog, code, "when parsing name %s", p_client_str); return(-1); } code = krb5_cc_initialize (context, ccache, *p_client); if (code != 0) { com_err (prog, code, "when initializing cache %s", cache_name?cache_name:""); return(-1); } if (do_timer) swatch_on(); code = krb5_get_init_creds_opt_alloc(context, &options); if (code != 0) { com_err(prog, code, "when allocating init cred options"); return(-1); } krb5_get_init_creds_opt_set_tkt_life(options, lifetime); code = krb5_get_init_creds_opt_set_out_ccache(context, options, ccache); if (code != 0) { com_err(prog, code, "when setting init cred output ccache"); return(-1); } code = krb5_get_init_creds_password(context, &my_creds, *p_client, p_client_str, NULL, NULL, 0, NULL, options); if (do_timer) { dt = swatch_eltime(); in_tkt_times.ht_cumulative += dt; in_tkt_times.ht_observations++; if (dt > in_tkt_times.ht_max) in_tkt_times.ht_max = dt; if (dt < in_tkt_times.ht_min) in_tkt_times.ht_min = dt; } krb5_get_init_creds_opt_free(context, options); krb5_free_cred_contents(context, &my_creds); if (code != 0) { com_err (prog, code, "while getting initial credentials"); return(-1); } return(0); } krb5-1.16/src/tests/t_kadmin_acl.py0000755000704600001450000003410513211554426017114 0ustar ghudsonlibuuid#!/usr/bin/python from k5test import * import os realm = K5Realm(create_host=False, create_user=False) def make_client(name): global realm realm.addprinc(name, password(name)) ccache = os.path.join(realm.testdir, 'kadmin_ccache_' + name.replace('/', '_')) realm.kinit(name, password(name), flags=['-S', 'kadmin/admin', '-c', ccache]) return ccache def kadmin_as(client, query, **kwargs): global realm return realm.run([kadmin, '-c', client] + query, **kwargs) all_add = make_client('all_add') all_changepw = make_client('all_changepw') all_delete = make_client('all_delete') all_inquire = make_client('all_inquire') all_list = make_client('all_list') all_modify = make_client('all_modify') all_rename = make_client('all_rename') all_wildcard = make_client('all_wildcard') all_extract = make_client('all_extract') some_add = make_client('some_add') some_changepw = make_client('some_changepw') some_delete = make_client('some_delete') some_inquire = make_client('some_inquire') some_modify = make_client('some_modify') some_rename = make_client('some_rename') restricted_add = make_client('restricted_add') restricted_modify = make_client('restricted_modify') restricted_rename = make_client('restricted_rename') wctarget = make_client('wctarget') admin = make_client('user/admin') none = make_client('none') restrictions = make_client('restrictions') onetwothreefour = make_client('one/two/three/four') realm.run([kadminl, 'addpol', '-minlife', '1 day', 'minlife']) f = open(os.path.join(realm.testdir, 'acl'), 'w') f.write(''' all_add a all_changepw c all_delete d all_inquire i all_list l all_modify im all_rename ad all_wildcard x all_extract ie some_add a selected some_changepw c selected some_delete d selected some_inquire i selected some_modify im selected some_rename d from some_rename a to restricted_add a * +preauth restricted_modify im * +preauth restricted_rename ad * +preauth */* d *2/*1 # The next line is a regression test for #8154; it is not used directly. one/*/*/five l */two/*/* d *3/*1/*2 */admin a wctarget a wild/* restrictions a type1 -policy minlife restrictions a type2 -clearpolicy restrictions a type3 -maxlife 1h -maxrenewlife 2h ''') f.close() realm.start_kadmind() # cpw can generate four different RPC calls depending on options. realm.addprinc('selected', 'oldpw') realm.addprinc('unselected', 'oldpw') for pw in (['-pw', 'newpw'], ['-randkey']): for ks in ([], ['-e', 'aes256-cts']): args = pw + ks kadmin_as(all_changepw, ['cpw'] + args + ['unselected']) kadmin_as(some_changepw, ['cpw'] + args + ['selected']) msg = "Operation requires ``change-password'' privilege" kadmin_as(none, ['cpw'] + args + ['selected'], expected_code=1, expected_msg=msg) kadmin_as(some_changepw, ['cpw'] + args + ['unselected'], expected_code=1, expected_msg=msg) kadmin_as(none, ['cpw'] + args + ['none']) realm.run([kadminl, 'modprinc', '-policy', 'minlife', 'none']) msg = "Current password's minimum life has not expired" kadmin_as(none, ['cpw'] + args + ['none'], expected_code=1, expected_msg=msg) realm.run([kadminl, 'modprinc', '-clearpolicy', 'none']) realm.run([kadminl, 'delprinc', 'selected']) realm.run([kadminl, 'delprinc', 'unselected']) kadmin_as(all_add, ['addpol', 'policy']) realm.run([kadminl, 'delpol', 'policy']) kadmin_as(none, ['addpol', 'policy'], expected_code=1, expected_msg="Operation requires ``add'' privilege") # addprinc can generate two different RPC calls depending on options. for ks in ([], ['-e', 'aes256-cts']): args = ['-pw', 'pw'] + ks kadmin_as(all_add, ['addprinc'] + args + ['unselected']) realm.run([kadminl, 'delprinc', 'unselected']) kadmin_as(some_add, ['addprinc'] + args + ['selected']) realm.run([kadminl, 'delprinc', 'selected']) kadmin_as(restricted_add, ['addprinc'] + args + ['unselected']) realm.run([kadminl, 'getprinc', 'unselected'], expected_msg='REQUIRES_PRE_AUTH') realm.run([kadminl, 'delprinc', 'unselected']) kadmin_as(none, ['addprinc'] + args + ['selected'], expected_code=1, expected_msg="Operation requires ``add'' privilege") kadmin_as(some_add, ['addprinc'] + args + ['unselected'], expected_code=1, expected_msg="Operation requires ``add'' privilege") realm.addprinc('unselected', 'pw') kadmin_as(all_delete, ['delprinc', 'unselected']) realm.addprinc('selected', 'pw') kadmin_as(some_delete, ['delprinc', 'selected']) realm.addprinc('unselected', 'pw') kadmin_as(none, ['delprinc', 'unselected'], expected_code=1, expected_msg="Operation requires ``delete'' privilege") kadmin_as(some_delete, ['delprinc', 'unselected'], expected_code=1, expected_msg="Operation requires ``delete'' privilege") realm.run([kadminl, 'delprinc', 'unselected']) kadmin_as(all_inquire, ['getpol', 'minlife'], expected_msg='Policy: minlife') kadmin_as(none, ['getpol', 'minlife'], expected_code=1, expected_msg="Operation requires ``get'' privilege") realm.run([kadminl, 'modprinc', '-policy', 'minlife', 'none']) kadmin_as(none, ['getpol', 'minlife'], expected_msg='Policy: minlife') realm.run([kadminl, 'modprinc', '-clearpolicy', 'none']) realm.addprinc('selected', 'pw') realm.addprinc('unselected', 'pw') kadmin_as(all_inquire, ['getprinc', 'unselected'], expected_msg='Principal: unselected@KRBTEST.COM') kadmin_as(some_inquire, ['getprinc', 'selected'], expected_msg='Principal: selected@KRBTEST.COM') kadmin_as(none, ['getprinc', 'selected'], expected_code=1, expected_msg="Operation requires ``get'' privilege") kadmin_as(some_inquire, ['getprinc', 'unselected'], expected_code=1, expected_msg="Operation requires ``get'' privilege") kadmin_as(none, ['getprinc', 'none'], expected_msg='Principal: none@KRBTEST.COM') realm.run([kadminl, 'delprinc', 'selected']) realm.run([kadminl, 'delprinc', 'unselected']) kadmin_as(all_list, ['listprincs'], expected_msg='K/M@KRBTEST.COM') kadmin_as(none, ['listprincs'], expected_code=1, expected_msg="Operation requires ``list'' privilege") realm.addprinc('selected', 'pw') realm.addprinc('unselected', 'pw') realm.run([kadminl, 'setstr', 'selected', 'key', 'value']) realm.run([kadminl, 'setstr', 'unselected', 'key', 'value']) kadmin_as(all_inquire, ['getstrs', 'unselected'], expected_msg='key: value') kadmin_as(some_inquire, ['getstrs', 'selected'], expected_msg='key: value') kadmin_as(none, ['getstrs', 'selected'], expected_code=1, expected_msg="Operation requires ``get'' privilege") kadmin_as(some_inquire, ['getstrs', 'unselected'], expected_code=1, expected_msg="Operation requires ``get'' privilege") kadmin_as(none, ['getstrs', 'none'], expected_msg='(No string attributes.)') realm.run([kadminl, 'delprinc', 'selected']) realm.run([kadminl, 'delprinc', 'unselected']) out = kadmin_as(all_modify, ['modpol', '-maxlife', '1 hour', 'policy'], expected_code=1) if 'Operation requires' in out: fail('modpol success (acl)') kadmin_as(none, ['modpol', '-maxlife', '1 hour', 'policy'], expected_code=1, expected_msg="Operation requires ``modify'' privilege") realm.addprinc('selected', 'pw') realm.addprinc('unselected', 'pw') kadmin_as(all_modify, ['modprinc', '-maxlife', '1 hour', 'unselected']) kadmin_as(some_modify, ['modprinc', '-maxlife', '1 hour', 'selected']) kadmin_as(restricted_modify, ['modprinc', '-maxlife', '1 hour', 'unselected']) realm.run([kadminl, 'getprinc', 'unselected'], expected_msg='REQUIRES_PRE_AUTH') kadmin_as(all_inquire, ['modprinc', '-maxlife', '1 hour', 'selected'], expected_code=1, expected_msg="Operation requires ``modify'' privilege") kadmin_as(some_modify, ['modprinc', '-maxlife', '1 hour', 'unselected'], expected_code=1, expected_msg='Operation requires') realm.run([kadminl, 'delprinc', 'selected']) realm.run([kadminl, 'delprinc', 'unselected']) realm.addprinc('selected', 'pw') realm.addprinc('unselected', 'pw') kadmin_as(all_modify, ['purgekeys', 'unselected']) kadmin_as(some_modify, ['purgekeys', 'selected']) kadmin_as(none, ['purgekeys', 'selected'], expected_code=1, expected_msg="Operation requires ``modify'' privilege") kadmin_as(some_modify, ['purgekeys', 'unselected'], expected_code=1, expected_msg="Operation requires ``modify'' privilege") kadmin_as(none, ['purgekeys', 'none']) realm.run([kadminl, 'delprinc', 'selected']) realm.run([kadminl, 'delprinc', 'unselected']) realm.addprinc('from', 'pw') kadmin_as(all_rename, ['renprinc', 'from', 'to']) realm.run([kadminl, 'renprinc', 'to', 'from']) kadmin_as(some_rename, ['renprinc', 'from', 'to']) realm.run([kadminl, 'renprinc', 'to', 'from']) kadmin_as(all_add, ['renprinc', 'from', 'to'], expected_code=1, expected_msg="Insufficient authorization for operation") kadmin_as(all_delete, ['renprinc', 'from', 'to'], expected_code=1, expected_msg="Insufficient authorization for operation") kadmin_as(some_rename, ['renprinc', 'from', 'notto'], expected_code=1, expected_msg="Insufficient authorization for operation") realm.run([kadminl, 'renprinc', 'from', 'notfrom']) kadmin_as(some_rename, ['renprinc', 'notfrom', 'to'], expected_code=1, expected_msg="Insufficient authorization for operation") kadmin_as(restricted_rename, ['renprinc', 'notfrom', 'to'], expected_code=1, expected_msg="Insufficient authorization for operation") realm.run([kadminl, 'delprinc', 'notfrom']) realm.addprinc('selected', 'pw') realm.addprinc('unselected', 'pw') kadmin_as(all_modify, ['setstr', 'unselected', 'key', 'value']) kadmin_as(some_modify, ['setstr', 'selected', 'key', 'value']) kadmin_as(none, ['setstr', 'selected', 'key', 'value'], expected_code=1, expected_msg="Operation requires ``modify'' privilege") kadmin_as(some_modify, ['setstr', 'unselected', 'key', 'value'], expected_code=1, expected_msg='Operation requires') realm.run([kadminl, 'delprinc', 'selected']) realm.run([kadminl, 'delprinc', 'unselected']) kadmin_as(admin, ['addprinc', '-pw', 'pw', 'anytarget']) realm.run([kadminl, 'delprinc', 'anytarget']) kadmin_as(wctarget, ['addprinc', '-pw', 'pw', 'wild/card']) realm.run([kadminl, 'delprinc', 'wild/card']) kadmin_as(wctarget, ['addprinc', '-pw', 'pw', 'wild/card/extra'], expected_code=1, expected_msg='Operation requires') realm.addprinc('admin/user', 'pw') kadmin_as(admin, ['delprinc', 'admin/user']) kadmin_as(admin, ['delprinc', 'none'], expected_code=1, expected_msg='Operation requires') realm.addprinc('four/one/three', 'pw') kadmin_as(onetwothreefour, ['delprinc', 'four/one/three']) kadmin_as(restrictions, ['addprinc', '-pw', 'pw', 'type1']) realm.run([kadminl, 'getprinc', 'type1'], expected_msg='Policy: minlife') realm.run([kadminl, 'delprinc', 'type1']) kadmin_as(restrictions, ['addprinc', '-pw', 'pw', '-policy', 'minlife', 'type2']) realm.run([kadminl, 'getprinc', 'type2'], expected_msg='Policy: [none]') realm.run([kadminl, 'delprinc', 'type2']) kadmin_as(restrictions, ['addprinc', '-pw', 'pw', '-maxlife', '1 minute', 'type3']) out = realm.run([kadminl, 'getprinc', 'type3']) if ('Maximum ticket life: 0 days 00:01:00' not in out or 'Maximum renewable life: 0 days 02:00:00' not in out): fail('restriction (maxlife low, maxrenewlife unspec)') realm.run([kadminl, 'delprinc', 'type3']) kadmin_as(restrictions, ['addprinc', '-pw', 'pw', '-maxrenewlife', '1 day', 'type3']) realm.run([kadminl, 'getprinc', 'type3'], expected_msg='Maximum renewable life: 0 days 02:00:00') realm.run([kadminl, 'addprinc', '-pw', 'pw', 'extractkeys']) kadmin_as(all_wildcard, ['ktadd', '-norandkey', 'extractkeys'], expected_code=1, expected_msg="Operation requires ``extract-keys'' privilege") kadmin_as(all_extract, ['ktadd', '-norandkey', 'extractkeys']) realm.kinit('extractkeys', flags=['-k']) os.remove(realm.keytab) kadmin_as(all_modify, ['modprinc', '+lockdown_keys', 'extractkeys']) kadmin_as(all_changepw, ['cpw', '-pw', 'newpw', 'extractkeys'], expected_code=1, expected_msg="Operation requires ``change-password'' privilege") kadmin_as(all_changepw, ['cpw', '-randkey', 'extractkeys']) kadmin_as(all_extract, ['ktadd', '-norandkey', 'extractkeys'], expected_code=1, expected_msg="Operation requires ``extract-keys'' privilege") kadmin_as(all_delete, ['delprinc', 'extractkeys'], expected_code=1, expected_msg="Operation requires ``delete'' privilege") kadmin_as(all_rename, ['renprinc', 'extractkeys', 'renamedprinc'], expected_code=1, expected_msg="Operation requires ``delete'' privilege") kadmin_as(all_modify, ['modprinc', '-lockdown_keys', 'extractkeys'], expected_code=1, expected_msg="Operation requires ``modify'' privilege") realm.run([kadminl, 'modprinc', '-lockdown_keys', 'extractkeys']) kadmin_as(all_extract, ['ktadd', '-norandkey', 'extractkeys']) realm.kinit('extractkeys', flags=['-k']) os.remove(realm.keytab) # Verify that self-service key changes require an initial ticket. realm.run([kadminl, 'cpw', '-pw', password('none'), 'none']) realm.run([kadminl, 'modprinc', '+allow_tgs_req', 'kadmin/admin']) realm.kinit('none', password('none')) realm.run([kvno, 'kadmin/admin']) msg = 'Operation requires initial ticket' realm.run([kadmin, '-c', realm.ccache, 'cpw', '-pw', 'newpw', 'none'], expected_code=1, expected_msg=msg) realm.run([kadmin, '-c', realm.ccache, 'cpw', '-pw', 'newpw', '-e', 'aes256-cts', 'none'], expected_code=1, expected_msg=msg) realm.run([kadmin, '-c', realm.ccache, 'cpw', '-randkey', 'none'], expected_code=1, expected_msg=msg) realm.run([kadmin, '-c', realm.ccache, 'cpw', '-randkey', '-e', 'aes256-cts', 'none'], expected_code=1, expected_msg=msg) success('kadmin ACL enforcement') krb5-1.16/src/tests/misc/0000755000704600001450000000000013211554426015062 5ustar ghudsonlibuuidkrb5-1.16/src/tests/misc/test_cxx_gss.cpp0000644000704600001450000000026613211554426020307 0ustar ghudsonlibuuid// Test that the gssapi.h header is compatible with C++ application code. #include #include "gssapi/gssapi.h" int main () { printf("hello, world\n"); return 0; } krb5-1.16/src/tests/misc/test_chpw_message.c0000644000704600001450000001321713211554426020736 0ustar ghudsonlibuuid/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* tests/misc/test_getpw.c */ /* * Copyright (C) 2012 by the Red Hat Inc. * All rights reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #include "autoconf.h" #include "krb5.h" #include #include #include #include #include #include static krb5_data result_utf8 = { 0, 23, "This is a valid string.", }; static krb5_data result_invalid_utf8 = { 0, 19, "\0This is not valid.", }; static krb5_data result_ad_complex = { 0, 30, "\0\0" /* zero bytes */ "\0\0\0\0" /* min length */ "\0\0\0\0" /* history */ "\0\0\0\1" /* properties, complex */ "\0\0\0\0\0\0\0\0" /* expire */ "\0\0\0\0\0\0\0\0" /* min age */ }; static krb5_data result_ad_length = { 0, 30, "\0\0" /* zero bytes */ "\0\0\0\x0d" /* min length, 13 charaters */ "\0\0\0\0" /* history */ "\0\0\0\0" /* properties */ "\0\0\0\0\0\0\0\0" /* expire */ "\0\0\0\0\0\0\0\0" /* min age */ }; static krb5_data result_ad_history = { 0, 30, "\0\0" /* zero bytes */ "\0\0\0\0" /* min length */ "\0\0\0\x09" /* history, 9 passwords */ "\0\0\0\0" /* properties */ "\0\0\0\0\0\0\0\0" /* expire */ "\0\0\0\0\0\0\0\0" /* min age */ }; static krb5_data result_ad_age = { 0, 30, "\0\0" /* zero bytes */ "\0\0\0\0" /* min length */ "\0\0\0\0" /* history, 9 passwords */ "\0\0\0\0" /* properties */ "\0\0\0\0\0\0\0\0" /* expire */ "\0\0\x01\x92\x54\xd3\x80\0" /* min age, 2 days */ }; static krb5_data result_ad_all = { 0, 30, "\0\0" /* zero bytes */ "\0\0\0\x05" /* min length, 5 characters */ "\0\0\0\x0D" /* history, 13 passwords */ "\0\0\0\x01" /* properties, complex */ "\0\0\0\0\0\0\0\0" /* expire */ "\0\0\0\xc9\x2a\x69\xc0\0" /* min age, 1 day */ }; static void check(krb5_error_code code) { if (code != 0) { com_err("t_vfy_increds", code, ""); abort(); } } static void check_msg(const char *real, const char *expected) { if (strstr(real, expected) == NULL) { fprintf(stderr, "Expected to see: %s\n", expected); abort(); } } int main(void) { krb5_context context; char *msg; setlocale(LC_ALL, "C"); check(krb5_init_context(&context)); /* Valid utf-8 data in the result should be returned as is */ check(krb5_chpw_message(context, &result_utf8, &msg)); printf(" UTF8 valid: %s\n", msg); check_msg(msg, "This is a valid string."); free(msg); /* Invalid data should have a generic message. */ check(krb5_chpw_message(context, &result_invalid_utf8, &msg)); printf(" UTF8 invalid: %s\n", msg); check_msg(msg, "contact your administrator"); free(msg); /* AD data with complex data requirement */ check(krb5_chpw_message(context, &result_ad_complex, &msg)); printf(" AD complex: %s\n", msg); check_msg(msg, "The password must include numbers or symbols."); check_msg(msg, "Don't include any part of your name in the password."); free(msg); /* AD data with min password length */ check(krb5_chpw_message(context, &result_ad_length, &msg)); printf(" AD length: %s\n", msg); check_msg(msg, "The password must contain at least 13 characters."); free(msg); /* AD data with history requirements */ check(krb5_chpw_message(context, &result_ad_history, &msg)); printf(" AD history: %s\n", msg); check_msg(msg, "The password must be different from the previous 9 " "passwords."); free(msg); /* AD data with minimum age */ check(krb5_chpw_message(context, &result_ad_age, &msg)); printf(" AD min age: %s\n", msg); check_msg(msg, "The password can only be changed every 2 days."); free(msg); /* AD data with all */ check(krb5_chpw_message(context, &result_ad_all, &msg)); printf(" AD all: %s\n", msg); check_msg(msg, "The password can only be changed once a day."); check_msg(msg, "The password must be different from the previous 13 " "passwords."); check_msg(msg, "The password must contain at least 5 characters."); check_msg(msg, "The password must include numbers or symbols."); check_msg(msg, "Don't include any part of your name in the password."); free(msg); krb5_free_context(context); exit(0); } krb5-1.16/src/tests/misc/test_cxx_k5int.cpp0000644000704600001450000000071513211554426020544 0ustar ghudsonlibuuid// Test that the krb5 internal headers are compatible with C++ code. // (Some Windows-specific code is in C++ in this source tree.) #include #include "k5-int.h" #include "k5-ipc_stream.h" #include "k5-utf8.h" int main (int argc, char *argv[]) { krb5_context ctx; if (krb5_init_context(&ctx) != 0) { printf("krb5_init_context returned an error\n"); return 1; } printf("hello, world\n"); krb5_free_context(ctx); return 0; } krb5-1.16/src/tests/misc/deps0000644000704600001450000000542413211554426015745 0ustar ghudsonlibuuid# # Generated makefile dependencies follow. # $(OUTPRE)test_getpw.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-thread.h \ test_getpw.c $(OUTPRE)test_chpw_message.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/krb5/krb5.h $(COM_ERR_DEPS) $(top_srcdir)/include/krb5.h \ test_chpw_message.c $(OUTPRE)test_getsockname.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ test_getsockname.c $(OUTPRE)test_cxx_krb5.$(OBJEXT): $(BUILDTOP)/include/krb5/krb5.h \ $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(top_srcdir)/include/krb5.h \ $(top_srcdir)/include/krb5/locate_plugin.h test_cxx_krb5.cpp $(OUTPRE)test_cxx_k5int.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h \ $(top_srcdir)/include/k5-err.h $(top_srcdir)/include/k5-gmt_mktime.h \ $(top_srcdir)/include/k5-int-pkinit.h $(top_srcdir)/include/k5-int.h \ $(top_srcdir)/include/k5-ipc_stream.h $(top_srcdir)/include/k5-platform.h \ $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \ $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/k5-utf8.h \ $(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/authdata_plugin.h \ $(top_srcdir)/include/krb5/plugin.h $(top_srcdir)/include/port-sockets.h \ $(top_srcdir)/include/socket-utils.h test_cxx_k5int.cpp $(OUTPRE)test_cxx_gss.$(OBJEXT): $(BUILDTOP)/include/gssapi/gssapi.h \ test_cxx_gss.cpp $(OUTPRE)test_cxx_rpc.$(OBJEXT): $(BUILDTOP)/include/gssapi/gssapi.h \ $(BUILDTOP)/include/gssrpc/types.h $(top_srcdir)/include/gssrpc/auth.h \ $(top_srcdir)/include/gssrpc/auth_gss.h $(top_srcdir)/include/gssrpc/auth_unix.h \ $(top_srcdir)/include/gssrpc/clnt.h $(top_srcdir)/include/gssrpc/rename.h \ $(top_srcdir)/include/gssrpc/rpc.h $(top_srcdir)/include/gssrpc/rpc_msg.h \ $(top_srcdir)/include/gssrpc/svc.h $(top_srcdir)/include/gssrpc/svc_auth.h \ $(top_srcdir)/include/gssrpc/xdr.h test_cxx_rpc.cpp $(OUTPRE)test_cxx_kadm5.$(OBJEXT): $(BUILDTOP)/include/gssapi/gssapi.h \ $(BUILDTOP)/include/gssrpc/types.h $(BUILDTOP)/include/kadm5/admin.h \ $(BUILDTOP)/include/kadm5/chpass_util_strings.h $(BUILDTOP)/include/kadm5/kadm_err.h \ $(BUILDTOP)/include/krb5/krb5.h $(COM_ERR_DEPS) $(top_srcdir)/include/gssrpc/auth.h \ $(top_srcdir)/include/gssrpc/auth_gss.h $(top_srcdir)/include/gssrpc/auth_unix.h \ $(top_srcdir)/include/gssrpc/clnt.h $(top_srcdir)/include/gssrpc/rename.h \ $(top_srcdir)/include/gssrpc/rpc.h $(top_srcdir)/include/gssrpc/rpc_msg.h \ $(top_srcdir)/include/gssrpc/svc.h $(top_srcdir)/include/gssrpc/svc_auth.h \ $(top_srcdir)/include/gssrpc/xdr.h $(top_srcdir)/include/kdb.h \ $(top_srcdir)/include/krb5.h test_cxx_kadm5.cpp krb5-1.16/src/tests/misc/test_getpw.c0000644000704600001450000000345513211554426017422 0ustar ghudsonlibuuid/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* tests/misc/test_getpw.c */ /* * Copyright (C) 2005 by the Massachusetts Institute of Technology. * All rights reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #include "autoconf.h" #include "k5-platform.h" #include #include #include #include #include int main() { uid_t my_uid; struct passwd *pwd, pwx; char pwbuf[BUFSIZ]; int x; my_uid = getuid(); printf("my uid: %ld\n", (long) my_uid); x = k5_getpwuid_r(my_uid, &pwx, pwbuf, sizeof(pwbuf), &pwd); printf("k5_getpwuid_r returns %d\n", x); if (x != 0) exit(1); printf(" username is '%s'\n", pwd->pw_name); exit(0); } krb5-1.16/src/tests/misc/test_nfold.c0000644000704600001450000000412113211554426017365 0ustar ghudsonlibuuid/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* * Copyright (C) 1998 by the FundsXpress, INC. * * All rights reserved. * * Export of this software from the United States of America may require * a specific license from the United States Government. It is the * responsibility of any person or organization contemplating export to * obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of FundsXpress. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. FundsXpress makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include #include #include int main(int argc, char *argv[]) { int inlen, outlen, i; unsigned char *instr, *outstr; if (argc != 3) { fprintf(stderr, "%s: instr outlen\n", argv[0]); exit(1); } instr = (unsigned char *) argv[1]; inlen = strlen(instr)*8; outlen = atoi(argv[2]); if (outlen%8) { fprintf(stderr, "outlen must be a multiple of 8\n"); exit(1); } if ((outstr = (unsigned char *) malloc(outlen/8)) == NULL) { fprintf(stderr, "ENOMEM\n"); exit(1); } krb5int_nfold(inlen,instr,outlen,outstr); printf("%d-fold(",outlen); for (i=0; i<(inlen/8); i++) printf("%02x",instr[i]); printf(") = "); for (i=0; i<(outlen/8); i++) printf("%02x",outstr[i]); printf("\n"); exit(0); } krb5-1.16/src/tests/misc/Makefile.in0000644000704600001450000000440713211554426017134 0ustar ghudsonlibuuidmydir=tests$(S)misc BUILDTOP=$(REL)..$(S).. OBJS=\ test_getpw.o \ test_chpw_message.o SRCS=\ $(srcdir)/test_getpw.c \ $(srcdir)/test_chpw_message.c \ $(srcdir)/test_getsockname.c \ $(srcdir)/test_cxx_krb5.cpp \ $(srcdir)/test_cxx_k5int.cpp \ $(srcdir)/test_cxx_gss.cpp \ $(srcdir)/test_cxx_rpc.cpp \ $(srcdir)/test_cxx_kadm5.cpp all: test_getpw test_chpw_message check: test_getpw test_chpw_message test_cxx_krb5 test_cxx_gss test_cxx_rpc test_cxx_k5int test_cxx_kadm5 $(RUN_TEST) ./test_getpw $(RUN_TEST) ./test_chpw_message $(RUN_TEST) ./test_cxx_krb5 $(RUN_TEST) ./test_cxx_k5int $(RUN_TEST) ./test_cxx_gss $(RUN_TEST) ./test_cxx_rpc $(RUN_TEST) ./test_cxx_kadm5 test_getpw: $(OUTPRE)test_getpw.$(OBJEXT) $(SUPPORT_DEPLIB) $(CC_LINK) $(ALL_CFLAGS) -o test_getpw $(OUTPRE)test_getpw.$(OBJEXT) $(SUPPORT_LIB) test_chpw_message: $(OUTPRE)test_chpw_message.$(OBJEXT) $(SUPPORT_DEPLIB) $(CC_LINK) $(ALL_CFLAGS) -o test_chpw_message $(OUTPRE)test_chpw_message.$(OBJEXT) $(KRB5_BASE_LIBS) $(LIBS) test_getsockname: $(OUTPRE)test_getsockname.$(OBJEXT) $(CC_LINK) $(ALL_CFLAGS) -o test_getsockname $(OUTPRE)test_getsockname.$(OBJEXT) $(LIBS) test_cxx_krb5: $(OUTPRE)test_cxx_krb5.$(OBJEXT) $(KRB5_DEPLIB) $(CXX_LINK) $(ALL_CXXFLAGS) -o test_cxx_krb5 $(OUTPRE)test_cxx_krb5.$(OBJEXT) $(KRB5_BASE_LIBS) $(LIBS) test_cxx_k5int: $(OUTPRE)test_cxx_k5int.$(OBJEXT) $(KRB5_DEPLIB) $(CXX_LINK) $(ALL_CXXFLAGS) -o test_cxx_k5int $(OUTPRE)test_cxx_k5int.$(OBJEXT) $(KRB5_BASE_LIBS) $(LIBS) test_cxx_gss: $(OUTPRE)test_cxx_gss.$(OBJEXT) $(CXX_LINK) $(ALL_CXXFLAGS) -o test_cxx_gss $(OUTPRE)test_cxx_gss.$(OBJEXT) $(LIBS) test_cxx_rpc: $(OUTPRE)test_cxx_rpc.$(OBJEXT) $(GSSRPC_DEPLIBS) $(CXX_LINK) $(ALL_CXXFLAGS) -o test_cxx_rpc $(OUTPRE)test_cxx_rpc.$(OBJEXT) $(GSSRPC_LIBS) $(KRB5_BASE_LIBS) $(LIBS) test_cxx_kadm5: $(OUTPRE)test_cxx_kadm5.$(OBJEXT) $(KADMCLNT_DEPLIBS) $(CXX_LINK) $(ALL_CXXFLAGS) -o test_cxx_kadm5 $(OUTPRE)test_cxx_kadm5.$(OBJEXT) $(KADMCLNT_LIBS) $(KRB5_BASE_LIBS) $(LIBS) test_cxx_krb5.$(OBJEXT): test_cxx_krb5.cpp test_cxx_gss.$(OBJEXT): test_cxx_gss.cpp test_cxx_rpc.$(OBJEXT): test_cxx_rpc.cpp test_cxx_kadm5.$(OBJEXT): test_cxx_kadm5.cpp install: clean: $(RM) test_getpw test_chpw_message test_cxx_krb5 test_cxx_gss test_cxx_k5int test_cxx_rpc test_cxx_kadm5 *.o krb5-1.16/src/tests/misc/test_getsockname.c0000644000704600001450000000717313211554426020575 0ustar ghudsonlibuuid/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* tests/misc/test_getsockname.c */ /* * Copyright (C) 1995 by the Massachusetts Institute of Technology. * All rights reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ /* * test_getsockname.c * * This routine demonstrates a bug in the socket emulation library of * Solaris and other monstrosities that uses STREAMS. On other * machines with a real networking layer, it prints the local * interface address that is used to send a message to a specific * host. On Solaris, it prints out 0.0.0.0. */ #include "autoconf.h" #include #include #include #include #include #include #include #include #include int main(argc, argv) int argc; char *argv[]; { int sock; GETSOCKNAME_ARG3_TYPE i; struct hostent *host; struct sockaddr_in s_sock; /* server address */ struct sockaddr_in c_sock; /* client address */ char *hostname; if (argc == 2) { hostname = argv[1]; } else { fprintf(stderr, "Usage: %s hostname\n", argv[0]); exit(1); } /* Look up server host */ if ((host = gethostbyname(hostname)) == (struct hostent *) 0) { fprintf(stderr, "%s: unknown host\n", hostname); exit(1); } /* Set server's address */ (void) memset(&s_sock, 0, sizeof(s_sock)); memcpy(&s_sock.sin_addr, host->h_addr, sizeof(s_sock.sin_addr)); #ifdef DEBUG printf("s_sock.sin_addr is %s\n", inet_ntoa(s_sock.sin_addr)); #endif s_sock.sin_family = AF_INET; s_sock.sin_port = htons(5555); /* Open a socket */ if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { perror("socket"); exit(1); } memset(&c_sock, 0, sizeof(c_sock)); c_sock.sin_family = AF_INET; /* Bind it to set the address; kernel will fill in port # */ if (bind(sock, (struct sockaddr *)&c_sock, sizeof(c_sock)) < 0) { perror("bind"); exit(1); } /* "connect" the datagram socket; this is necessary to get a local address properly bound for getsockname() below. */ if (connect(sock, (struct sockaddr *)&s_sock, sizeof(s_sock)) == -1) { perror("connect"); exit(1); } /* Get my address */ memset(&c_sock, 0, sizeof(c_sock)); i = sizeof(c_sock); if (getsockname(sock, (struct sockaddr *)&c_sock, &i) < 0) { perror("getsockname"); exit(1); } printf("My interface address is: %s\n", inet_ntoa(c_sock.sin_addr)); exit(0); } krb5-1.16/src/tests/misc/test_cxx_kadm5.cpp0000644000704600001450000000052413211554426020511 0ustar ghudsonlibuuid// Test that the kadm5 header is compatible with C++ application code. #include "kadm5/admin.h" krb5_context ctx; kadm5_config_params p_in, p_out; int main (int argc, char *argv[]) { if (argc == 47 && kadm5_get_config_params(ctx, 1, &p_in, &p_out)) { printf("error\n"); return 1; } printf("hello, world\n"); return 0; } krb5-1.16/src/tests/misc/test_cxx_rpc.cpp0000644000704600001450000000044013211554426020271 0ustar ghudsonlibuuid// Test that the rpc.h header is compatible with C++ application code. #include "gssrpc/rpc.h" struct sockaddr_in s_in; int main (int argc, char *argv[]) { if (argc == 47 && get_myaddress (&s_in)) { printf("error\n"); return 1; } printf("hello, world\n"); return 0; } krb5-1.16/src/tests/misc/test_cxx_krb5.cpp0000644000704600001450000000062413211554426020354 0ustar ghudsonlibuuid// Test that the krb5.h header is compatible with C++ application code. #include #include "krb5.h" #include "krb5/locate_plugin.h" #include "profile.h" int main (int argc, char *argv[]) { krb5_context ctx; if (krb5_init_context(&ctx) != 0) { printf("krb5_init_context returned an error\n"); return 1; } printf("hello, world\n"); krb5_free_context(ctx); return 0; } krb5-1.16/src/tests/plugorder.c0000644000704600001450000000637713211554426016313 0ustar ghudsonlibuuid/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* tests/plugorder.c - Test harness to display the order of loaded plugins */ /* * Copyright (C) 2013 by the Massachusetts Institute of Technology. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ /* * This file registers a few dummy built-in pwqual modules, then prints out the * order of pwqual modules returned by k5_plugin_load_all. The choice of the * pwqual interface is mostly arbitrary; it is an interface which libkrb5 * itself doesn't use, for which we have a test module. */ #include "k5-int.h" #include static krb5_context ctx; static void check(krb5_error_code code) { const char *errmsg; if (code) { errmsg = krb5_get_error_message(ctx, code); fprintf(stderr, "%s\n", errmsg); krb5_free_error_message(ctx, errmsg); exit(1); } } static krb5_error_code blt1(krb5_context context, int maj_ver, int min_ver, krb5_plugin_vtable vtable) { ((krb5_pwqual_vtable)vtable)->name = "blt1"; return 0; } static krb5_error_code blt2(krb5_context context, int maj_ver, int min_ver, krb5_plugin_vtable vtable) { ((krb5_pwqual_vtable)vtable)->name = "blt2"; return 0; } static krb5_error_code blt3(krb5_context context, int maj_ver, int min_ver, krb5_plugin_vtable vtable) { ((krb5_pwqual_vtable)vtable)->name = "blt3"; return 0; } int main() { krb5_plugin_initvt_fn *modules = NULL, *mod; struct krb5_pwqual_vtable_st vt; check(krb5_init_context(&ctx)); check(k5_plugin_register(ctx, PLUGIN_INTERFACE_PWQUAL, "blt1", blt1)); check(k5_plugin_register(ctx, PLUGIN_INTERFACE_PWQUAL, "blt2", blt2)); check(k5_plugin_register(ctx, PLUGIN_INTERFACE_PWQUAL, "blt3", blt3)); check(k5_plugin_load_all(ctx, PLUGIN_INTERFACE_PWQUAL, &modules)); for (mod = modules; *mod != NULL; mod++) { check((*mod)(ctx, 1, 1, (krb5_plugin_vtable)&vt)); printf("%s\n", vt.name); } k5_plugin_free_modules(ctx, modules); return 0; } krb5-1.16/src/slave/0000755000704600001450000000000013211554426014077 5ustar ghudsonlibuuidkrb5-1.16/src/slave/deps0000644000704600001450000001155213211554426014761 0ustar ghudsonlibuuid# # Generated makefile dependencies follow. # $(OUTPRE)kprop.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(top_srcdir)/include/fake-addrinfo.h \ $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \ $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-int-pkinit.h \ $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \ $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \ $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/krb5.h \ $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/plugin.h \ $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \ kprop.c kprop.h $(OUTPRE)kprop_util.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h \ $(top_srcdir)/include/k5-err.h $(top_srcdir)/include/k5-gmt_mktime.h \ $(top_srcdir)/include/k5-int-pkinit.h $(top_srcdir)/include/k5-int.h \ $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-plugin.h \ $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/k5-trace.h \ $(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/authdata_plugin.h \ $(top_srcdir)/include/krb5/plugin.h $(top_srcdir)/include/port-sockets.h \ $(top_srcdir)/include/socket-utils.h kprop.h kprop_util.c $(OUTPRE)kpropd.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/gssapi/gssapi.h $(BUILDTOP)/include/gssrpc/types.h \ $(BUILDTOP)/include/kadm5/admin.h $(BUILDTOP)/include/kadm5/chpass_util_strings.h \ $(BUILDTOP)/include/kadm5/kadm_err.h $(BUILDTOP)/include/krb5/krb5.h \ $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ $(COM_ERR_DEPS) $(top_srcdir)/include/fake-addrinfo.h \ $(top_srcdir)/include/gssrpc/auth.h $(top_srcdir)/include/gssrpc/auth_gss.h \ $(top_srcdir)/include/gssrpc/auth_unix.h $(top_srcdir)/include/gssrpc/clnt.h \ $(top_srcdir)/include/gssrpc/rename.h $(top_srcdir)/include/gssrpc/rpc.h \ $(top_srcdir)/include/gssrpc/rpc_msg.h $(top_srcdir)/include/gssrpc/svc.h \ $(top_srcdir)/include/gssrpc/svc_auth.h $(top_srcdir)/include/gssrpc/xdr.h \ $(top_srcdir)/include/iprop.h $(top_srcdir)/include/iprop_hdr.h \ $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \ $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-int-pkinit.h \ $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \ $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \ $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/kdb.h \ $(top_srcdir)/include/kdb_log.h $(top_srcdir)/include/krb5.h \ $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/plugin.h \ $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \ kprop.h kpropd.c $(OUTPRE)kpropd_rpc.$(OBJEXT): $(BUILDTOP)/include/gssapi/gssapi.h \ $(BUILDTOP)/include/gssrpc/types.h $(top_srcdir)/include/gssrpc/auth.h \ $(top_srcdir)/include/gssrpc/auth_gss.h $(top_srcdir)/include/gssrpc/auth_unix.h \ $(top_srcdir)/include/gssrpc/clnt.h $(top_srcdir)/include/gssrpc/rename.h \ $(top_srcdir)/include/gssrpc/rpc.h $(top_srcdir)/include/gssrpc/rpc_msg.h \ $(top_srcdir)/include/gssrpc/svc.h $(top_srcdir)/include/gssrpc/svc_auth.h \ $(top_srcdir)/include/gssrpc/xdr.h $(top_srcdir)/include/iprop.h \ kpropd_rpc.c $(OUTPRE)kproplog.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/gssapi/gssapi.h $(BUILDTOP)/include/gssrpc/types.h \ $(BUILDTOP)/include/kadm5/admin.h $(BUILDTOP)/include/kadm5/chpass_util_strings.h \ $(BUILDTOP)/include/kadm5/kadm_err.h $(BUILDTOP)/include/krb5/krb5.h \ $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ $(COM_ERR_DEPS) $(top_srcdir)/include/gssrpc/auth.h \ $(top_srcdir)/include/gssrpc/auth_gss.h $(top_srcdir)/include/gssrpc/auth_unix.h \ $(top_srcdir)/include/gssrpc/clnt.h $(top_srcdir)/include/gssrpc/rename.h \ $(top_srcdir)/include/gssrpc/rpc.h $(top_srcdir)/include/gssrpc/rpc_msg.h \ $(top_srcdir)/include/gssrpc/svc.h $(top_srcdir)/include/gssrpc/svc_auth.h \ $(top_srcdir)/include/gssrpc/xdr.h $(top_srcdir)/include/iprop.h \ $(top_srcdir)/include/iprop_hdr.h $(top_srcdir)/include/k5-buf.h \ $(top_srcdir)/include/k5-err.h $(top_srcdir)/include/k5-gmt_mktime.h \ $(top_srcdir)/include/k5-int-pkinit.h $(top_srcdir)/include/k5-int.h \ $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-plugin.h \ $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/k5-trace.h \ $(top_srcdir)/include/kdb.h $(top_srcdir)/include/kdb_log.h \ $(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/authdata_plugin.h \ $(top_srcdir)/include/krb5/plugin.h $(top_srcdir)/include/port-sockets.h \ $(top_srcdir)/include/socket-utils.h kproplog.c krb5-1.16/src/slave/kprop.c0000644000704600001450000004557313211554426015414 0ustar ghudsonlibuuid/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* slave/kprop.c */ /* * Copyright 1990,1991,2008 by the Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #include "k5-int.h" #include #include #include #include #include #include #include #include #include #include #include #include "com_err.h" #include "fake-addrinfo.h" #include "kprop.h" #ifndef GETSOCKNAME_ARG3_TYPE #define GETSOCKNAME_ARG3_TYPE unsigned int #endif static char *kprop_version = KPROP_PROT_VERSION; static char *progname = NULL; static int debug = 0; static char *srvtab = NULL; static char *slave_host; static char *realm = NULL; static char *def_realm = NULL; static char *file = KPROP_DEFAULT_FILE; /* The Kerberos principal we'll be sending as, initialized in get_tickets. */ static krb5_principal my_principal; static krb5_creds creds; static krb5_address *sender_addr; static krb5_address *receiver_addr; static const char *port = KPROP_SERVICE; static char *dbpathname; static void parse_args(krb5_context context, int argc, char **argv); static void get_tickets(krb5_context context); static void usage(void); static void open_connection(krb5_context context, char *host, int *fd_out); static void kerberos_authenticate(krb5_context context, krb5_auth_context *auth_context, int fd, krb5_principal me, krb5_creds **new_creds); static int open_database(krb5_context context, char *data_fn, int *size); static void close_database(krb5_context context, int fd); static void xmit_database(krb5_context context, krb5_auth_context auth_context, krb5_creds *my_creds, int fd, int database_fd, int in_database_size); static void send_error(krb5_context context, krb5_creds *my_creds, int fd, char *err_text, krb5_error_code err_code); static void update_last_prop_file(char *hostname, char *file_name); static void usage() { fprintf(stderr, _("\nUsage: %s [-r realm] [-f file] [-d] [-P port] " "[-s srvtab] slave_host\n\n"), progname); exit(1); } int main(int argc, char **argv) { int fd, database_fd, database_size; krb5_error_code retval; krb5_context context; krb5_creds *my_creds; krb5_auth_context auth_context; setlocale(LC_ALL, ""); retval = krb5_init_context(&context); if (retval) { com_err(argv[0], retval, _("while initializing krb5")); exit(1); } parse_args(context, argc, argv); get_tickets(context); database_fd = open_database(context, file, &database_size); open_connection(context, slave_host, &fd); kerberos_authenticate(context, &auth_context, fd, my_principal, &my_creds); xmit_database(context, auth_context, my_creds, fd, database_fd, database_size); update_last_prop_file(slave_host, file); printf(_("Database propagation to %s: SUCCEEDED\n"), slave_host); krb5_free_cred_contents(context, my_creds); close_database(context, database_fd); krb5_free_default_realm(context, def_realm); exit(0); } static void parse_args(krb5_context context, int argc, char **argv) { int c; krb5_error_code ret; progname = argv[0]; while ((c = getopt(argc, argv, "r:f:dP:s:")) != -1) { switch (c) { case 'r': realm = optarg; break; case 'f': file = optarg; break; case 'd': debug++; break; case 'P': port = optarg; break; case 's': srvtab = optarg; break; default: usage(); } } if (argc - optind != 1) usage(); slave_host = argv[optind]; if (realm == NULL) { ret = krb5_get_default_realm(context, &def_realm); if (ret) { com_err(progname, errno, _("while getting default realm")); exit(1); } realm = def_realm; } } static void get_tickets(krb5_context context) { char *server; krb5_error_code retval; krb5_keytab keytab = NULL; krb5_principal server_princ = NULL; /* Figure out what tickets we'll be using to send. */ retval = sn2princ_realm(context, NULL, KPROP_SERVICE_NAME, realm, &my_principal); if (retval) { com_err(progname, errno, _("while setting client principal name")); exit(1); } /* Construct the principal name for the slave host. */ memset(&creds, 0, sizeof(creds)); retval = sn2princ_realm(context, slave_host, KPROP_SERVICE_NAME, realm, &server_princ); if (retval) { com_err(progname, errno, _("while setting server principal name")); exit(1); } retval = krb5_unparse_name_flags(context, server_princ, KRB5_PRINCIPAL_UNPARSE_NO_REALM, &server); if (retval) { com_err(progname, retval, _("while unparsing server name")); exit(1); } if (srvtab != NULL) { retval = krb5_kt_resolve(context, srvtab, &keytab); if (retval) { com_err(progname, retval, _("while resolving keytab")); exit(1); } } retval = krb5_get_init_creds_keytab(context, &creds, my_principal, keytab, 0, server, NULL); if (retval) { com_err(progname, retval, _("while getting initial credentials\n")); exit(1); } if (keytab != NULL) krb5_kt_close(context, keytab); krb5_free_unparsed_name(context, server); krb5_free_principal(context, server_princ); } static void open_connection(krb5_context context, char *host, int *fd_out) { krb5_error_code retval; GETSOCKNAME_ARG3_TYPE socket_length; struct addrinfo hints, *res, *answers; struct sockaddr *sa; struct sockaddr_storage my_sin; int s, error; *fd_out = -1; memset(&hints, 0, sizeof(hints)); hints.ai_family = PF_UNSPEC; hints.ai_socktype = SOCK_STREAM; hints.ai_flags = AI_ADDRCONFIG; error = getaddrinfo(host, port, &hints, &answers); if (error != 0) { com_err(progname, 0, "%s: %s", host, gai_strerror(error)); exit(1); } s = -1; retval = EINVAL; for (res = answers; res != NULL; res = res->ai_next) { s = socket(res->ai_family, res->ai_socktype, res->ai_protocol); if (s < 0) { com_err(progname, errno, _("while creating socket")); exit(1); } if (connect(s, res->ai_addr, res->ai_addrlen) < 0) { retval = errno; close(s); s = -1; continue; } /* We successfully connect()ed */ *fd_out = s; retval = sockaddr2krbaddr(context, res->ai_family, res->ai_addr, &receiver_addr); if (retval != 0) { com_err(progname, retval, _("while converting server address")); exit(1); } break; } freeaddrinfo(answers); if (s == -1) { com_err(progname, retval, _("while connecting to server")); exit(1); } /* Set sender_addr. */ socket_length = sizeof(my_sin); if (getsockname(s, (struct sockaddr *)&my_sin, &socket_length) < 0) { com_err(progname, errno, _("while getting local socket address")); exit(1); } sa = (struct sockaddr *)&my_sin; if (sockaddr2krbaddr(context, sa->sa_family, sa, &sender_addr) != 0) { com_err(progname, errno, _("while converting local address")); exit(1); } } static void kerberos_authenticate(krb5_context context, krb5_auth_context *auth_context, int fd, krb5_principal me, krb5_creds **new_creds) { krb5_error_code retval; krb5_error *error = NULL; krb5_ap_rep_enc_part *rep_result; retval = krb5_auth_con_init(context, auth_context); if (retval) exit(1); krb5_auth_con_setflags(context, *auth_context, KRB5_AUTH_CONTEXT_DO_SEQUENCE); retval = krb5_auth_con_setaddrs(context, *auth_context, sender_addr, receiver_addr); if (retval) { com_err(progname, retval, _("in krb5_auth_con_setaddrs")); exit(1); } retval = krb5_sendauth(context, auth_context, &fd, kprop_version, me, creds.server, AP_OPTS_MUTUAL_REQUIRED, NULL, &creds, NULL, &error, &rep_result, new_creds); if (retval) { com_err(progname, retval, _("while authenticating to server")); if (error != NULL) { if (error->error == KRB_ERR_GENERIC) { if (error->text.data) { fprintf(stderr, _("Generic remote error: %s\n"), error->text.data); } } else if (error->error) { com_err(progname, (krb5_error_code)error->error + ERROR_TABLE_BASE_krb5, _("signalled from server")); if (error->text.data) { fprintf(stderr, _("Error text from server: %s\n"), error->text.data); } } krb5_free_error(context, error); } exit(1); } krb5_free_ap_rep_enc_part(context, rep_result); } /* * Open the Kerberos database dump file. Takes care of locking it * and making sure that the .ok file is more recent that the database * dump file itself. * * Returns the file descriptor of the database dump file. Also fills * in the size of the database file. */ static int open_database(krb5_context context, char *data_fn, int *size) { struct stat stbuf, stbuf_ok; char *data_ok_fn; int fd, err; dbpathname = strdup(data_fn); if (dbpathname == NULL) { com_err(progname, ENOMEM, _("allocating database file name '%s'"), data_fn); exit(1); } fd = open(dbpathname, O_RDONLY); if (fd < 0) { com_err(progname, errno, _("while trying to open %s"), dbpathname); exit(1); } err = krb5_lock_file(context, fd, KRB5_LOCKMODE_SHARED | KRB5_LOCKMODE_DONTBLOCK); if (err == EAGAIN || err == EWOULDBLOCK || errno == EACCES) { com_err(progname, 0, _("database locked")); exit(1); } else if (err) { com_err(progname, err, _("while trying to lock '%s'"), dbpathname); exit(1); } if (fstat(fd, &stbuf)) { com_err(progname, errno, _("while trying to stat %s"), data_fn); exit(1); } if (asprintf(&data_ok_fn, "%s.dump_ok", data_fn) < 0) { com_err(progname, ENOMEM, _("while trying to malloc data_ok_fn")); exit(1); } if (stat(data_ok_fn, &stbuf_ok)) { com_err(progname, errno, _("while trying to stat %s"), data_ok_fn); free(data_ok_fn); exit(1); } if (stbuf.st_mtime > stbuf_ok.st_mtime) { com_err(progname, 0, _("'%s' more recent than '%s'."), data_fn, data_ok_fn); exit(1); } free(data_ok_fn); *size = stbuf.st_size; return fd; } static void close_database(krb5_context context, int fd) { int err; err = krb5_lock_file(context, fd, KRB5_LOCKMODE_UNLOCK); if (err) com_err(progname, err, _("while unlocking database '%s'"), dbpathname); free(dbpathname); close(fd); } /* * Now we send over the database. We use the following protocol: * Send over a KRB_SAFE message with the size. Then we send over the * database in blocks of KPROP_BLKSIZE, encrypted using KRB_PRIV. * Then we expect to see a KRB_SAFE message with the size sent back. * * At any point in the protocol, we may send a KRB_ERROR message; this * will abort the entire operation. */ static void xmit_database(krb5_context context, krb5_auth_context auth_context, krb5_creds *my_creds, int fd, int database_fd, int in_database_size) { krb5_int32 n; krb5_data inbuf, outbuf; char buf[KPROP_BUFSIZ]; krb5_error_code retval; krb5_error *error; krb5_ui_4 database_size = in_database_size, send_size, sent_size; /* Send over the size. */ send_size = htonl(database_size); inbuf.data = (char *)&send_size; inbuf.length = sizeof(send_size); /* must be 4, really */ /* KPROP_CKSUMTYPE */ retval = krb5_mk_safe(context, auth_context, &inbuf, &outbuf, NULL); if (retval) { com_err(progname, retval, _("while encoding database size")); send_error(context, my_creds, fd, _("while encoding database size"), retval); exit(1); } retval = krb5_write_message(context, &fd, &outbuf); if (retval) { krb5_free_data_contents(context, &outbuf); com_err(progname, retval, _("while sending database size")); exit(1); } krb5_free_data_contents(context, &outbuf); /* Initialize the initial vector. */ retval = krb5_auth_con_initivector(context, auth_context); if (retval) { send_error(context, my_creds, fd, "failed while initializing i_vector", retval); com_err(progname, retval, _("while allocating i_vector")); exit(1); } /* Send over the file, block by block. */ inbuf.data = buf; sent_size = 0; while ((n = read(database_fd, buf, sizeof(buf)))) { inbuf.length = n; retval = krb5_mk_priv(context, auth_context, &inbuf, &outbuf, NULL); if (retval) { snprintf(buf, sizeof(buf), "while encoding database block starting at %d", sent_size); com_err(progname, retval, "%s", buf); send_error(context, my_creds, fd, buf, retval); exit(1); } retval = krb5_write_message(context, &fd, &outbuf); if (retval) { krb5_free_data_contents(context, &outbuf); com_err(progname, retval, _("while sending database block starting at %d"), sent_size); exit(1); } krb5_free_data_contents(context, &outbuf); sent_size += n; if (debug) printf("%d bytes sent.\n", sent_size); } if (sent_size != database_size) { com_err(progname, 0, _("Premature EOF found for database file!")); send_error(context, my_creds, fd, "Premature EOF found for database file!", KRB5KRB_ERR_GENERIC); exit(1); } /* * OK, we've sent the database; now let's wait for a success * indication from the remote end. */ retval = krb5_read_message(context, &fd, &inbuf); if (retval) { com_err(progname, retval, _("while reading response from server")); exit(1); } /* * If we got an error response back from the server, display * the error message */ if (krb5_is_krb_error(&inbuf)) { retval = krb5_rd_error(context, &inbuf, &error); if (retval) { com_err(progname, retval, _("while decoding error response from server")); exit(1); } if (error->error == KRB_ERR_GENERIC) { if (error->text.data) { fprintf(stderr, _("Generic remote error: %s\n"), error->text.data); } } else if (error->error) { com_err(progname, (krb5_error_code)error->error + ERROR_TABLE_BASE_krb5, _("signalled from server")); if (error->text.data) { fprintf(stderr, _("Error text from server: %s\n"), error->text.data); } } krb5_free_error(context, error); exit(1); } retval = krb5_rd_safe(context,auth_context,&inbuf,&outbuf,NULL); if (retval) { com_err(progname, retval, "while decoding final size packet from server"); exit(1); } memcpy(&send_size, outbuf.data, sizeof(send_size)); send_size = ntohl(send_size); if (send_size != database_size) { com_err(progname, 0, _("Kpropd sent database size %d, expecting %d"), send_size, database_size); exit(1); } free(inbuf.data); free(outbuf.data); } static void send_error(krb5_context context, krb5_creds *my_creds, int fd, char *err_text, krb5_error_code err_code) { krb5_error error; const char *text; krb5_data outbuf; memset(&error, 0, sizeof(error)); krb5_us_timeofday(context, &error.ctime, &error.cusec); error.server = my_creds->server; error.client = my_principal; error.error = err_code - ERROR_TABLE_BASE_krb5; if (error.error > 127) error.error = KRB_ERR_GENERIC; text = (err_text != NULL) ? err_text : error_message(err_code); error.text.length = strlen(text) + 1; error.text.data = strdup(text); if (error.text.data) { if (!krb5_mk_error(context, &error, &outbuf)) { (void)krb5_write_message(context, &fd, &outbuf); krb5_free_data_contents(context, &outbuf); } free(error.text.data); } } static void update_last_prop_file(char *hostname, char *file_name) { char *file_last_prop; int fd; static char last_prop[] = ".last_prop"; if (asprintf(&file_last_prop, "%s.%s%s", file_name, hostname, last_prop) < 0) { com_err(progname, ENOMEM, _("while allocating filename for update_last_prop_file")); return; } fd = THREEPARAMOPEN(file_last_prop, O_WRONLY | O_CREAT | O_TRUNC, 0600); if (fd < 0) { com_err(progname, errno, _("while creating 'last_prop' file, '%s'"), file_last_prop); free(file_last_prop); return; } write(fd, "", 1); free(file_last_prop); close(fd); } krb5-1.16/src/slave/kpropd_rpc.c0000644000704600001450000000266713211554426016421 0ustar ghudsonlibuuid/* -*- mode: c; c-file-style: "bsd"; indent-tabs-mode: t -*- */ /* * Copyright 2004 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ /* * Please do not edit this file. * It was generated using rpcgen. */ #include /* for memset */ #include "iprop.h" /* Default timeout can be changed using clnt_control() */ static struct timeval TIMEOUT = { 25, 0 }; void * iprop_null_1(void *argp, CLIENT *clnt) { static char clnt_res; memset(&clnt_res, 0, sizeof(clnt_res)); if (clnt_call (clnt, IPROP_NULL, (xdrproc_t) xdr_void, (caddr_t) argp, (xdrproc_t) xdr_void, (caddr_t) &clnt_res, TIMEOUT) != RPC_SUCCESS) { return (NULL); } return ((void *)&clnt_res); } kdb_incr_result_t * iprop_get_updates_1(kdb_last_t *argp, CLIENT *clnt) { static kdb_incr_result_t clnt_res; memset(&clnt_res, 0, sizeof(clnt_res)); if (clnt_call (clnt, IPROP_GET_UPDATES, (xdrproc_t) xdr_kdb_last_t, (caddr_t) argp, (xdrproc_t) xdr_kdb_incr_result_t, (caddr_t) &clnt_res, TIMEOUT) != RPC_SUCCESS) { return (NULL); } return (&clnt_res); } kdb_fullresync_result_t * iprop_full_resync_1(void *argp, CLIENT *clnt) { static kdb_fullresync_result_t clnt_res; memset(&clnt_res, 0, sizeof(clnt_res)); if (clnt_call (clnt, IPROP_FULL_RESYNC, (xdrproc_t) xdr_void, (caddr_t) argp, (xdrproc_t) xdr_kdb_fullresync_result_t, (caddr_t) &clnt_res, TIMEOUT) != RPC_SUCCESS) { return (NULL); } return (&clnt_res); } krb5-1.16/src/slave/kslave_update0000644000704600001450000000132413211554426016651 0ustar ghudsonlibuuid#!/bin/sh # # Propagate if database (principal.db) has been modified since last dump # (dumpfile.dump_ok) or if database has been dumped since last successful # propagation (dumpfile..last_prop) KDB_DIR=/usr/local/var/krb5kdc KDB_FILE=$KDB_DIR/principal.db DUMPFILE=$KDB_DIR/slave_datatrans KDB5_UTIL=/usr/local/sbin/kdb5_util KPROP=/usr/local/sbin/kprop SLAVE=$1 if [ -z "${SLAVE}" ] then echo "Usage $0 slave_server" fi if [ "`ls -t $DUMPFILE.dump_ok $KDB_FILE | sed -n 1p`" = "$KDB_FILE" -o \ "`ls -t $DUMPFILE.${SLAVE}.last_prop $DUMPFILE.dump_ok | \ sed -n 1p`" = "$DUMPFILE.dump_ok" ] then date $KDB5_UTIL dump $DUMPFILE > /dev/null $KPROP -d -f $DUMPFILE ${SLAVE} rm $DUMPFILE fi krb5-1.16/src/slave/kprop_util.c0000644000704600001450000000700513211554426016435 0ustar ghudsonlibuuid/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* slave/kprop_util.c */ /* * Copyright (C) 2010 by the Massachusetts Institute of Technology. * All rights reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ /* sockaddr2krbaddr() utility function used by kprop and kpropd */ #include "k5-int.h" #include "kprop.h" #include #include /* * Convert an IPv4 or IPv6 socket address to a newly allocated krb5_address. * There is similar code elsewhere in the tree, so this should possibly become * a libkrb5 API in the future. */ krb5_error_code sockaddr2krbaddr(krb5_context context, int family, struct sockaddr *sa, krb5_address **dest) { krb5_address addr; addr.magic = KV5M_ADDRESS; if (family == AF_INET) { struct sockaddr_in *sa4 = sa2sin(sa); addr.addrtype = ADDRTYPE_INET; addr.length = sizeof(sa4->sin_addr); addr.contents = (krb5_octet *) &sa4->sin_addr; } else if (family == AF_INET6) { struct sockaddr_in6 *sa6 = sa2sin6(sa); if (IN6_IS_ADDR_V4MAPPED(&sa6->sin6_addr)) { addr.addrtype = ADDRTYPE_INET; addr.contents = (krb5_octet *) &sa6->sin6_addr + 12; addr.length = 4; } else { addr.addrtype = ADDRTYPE_INET6; addr.length = sizeof(sa6->sin6_addr); addr.contents = (krb5_octet *) &sa6->sin6_addr; } } else return KRB5_PROG_ATYPE_NOSUPP; return krb5_copy_addr(context, &addr, dest); } /* Construct a host-based principal, similar to krb5_sname_to_principal() but * with a specified realm. */ krb5_error_code sn2princ_realm(krb5_context context, const char *hostname, const char *sname, const char *realm, krb5_principal *princ_out) { krb5_error_code ret; char *canonhost, localname[MAXHOSTNAMELEN]; *princ_out = NULL; assert(sname != NULL && realm != NULL); /* If hostname is NULL, use the local hostname. */ if (hostname == NULL) { if (gethostname(localname, MAXHOSTNAMELEN) != 0) return SOCKET_ERRNO; hostname = localname; } ret = krb5_expand_hostname(context, hostname, &canonhost); if (ret) return ret; ret = krb5_build_principal(context, princ_out, strlen(realm), realm, sname, canonhost, (char *)NULL); krb5_free_string(context, canonhost); if (!ret) (*princ_out)->type = KRB5_NT_SRV_HST; return ret; } krb5-1.16/src/slave/kprop.h0000644000704600001450000000345113211554426015406 0ustar ghudsonlibuuid/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* slave/kprop.h */ /* * Copyright 1990,1991 by the Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #define KPROP_SERVICE_NAME "host" #define TGT_SERVICE_NAME "krbtgt" #define KPROP_SERVICE "krb5_prop" #define KPROP_PORT 754 #define KPROP_PROT_VERSION "kprop5_01" #define KPROP_BUFSIZ 32768 /* pathnames are in osconf.h, included via k5-int.h */ int sockaddr2krbaddr(krb5_context context, int family, struct sockaddr *sa, krb5_address **dest); krb5_error_code sn2princ_realm(krb5_context context, const char *hostname, const char *sname, const char *realm, krb5_principal *princ_out); krb5-1.16/src/slave/Makefile.in0000644000704600001450000000174713211554426016155 0ustar ghudsonlibuuidmydir=slave BUILDTOP=$(REL).. all: kprop kpropd kproplog CLIENTSRCS= $(srcdir)/kprop.c $(srcdir)/kprop_util.c CLIENTOBJS= kprop.o kprop_util.o SERVERSRCS= $(srcdir)/kpropd.c $(srcdir)/kpropd_rpc.c $(srcdir)/kprop_util.c SERVEROBJS= kpropd.o kpropd_rpc.o kprop_util.o LOGSRCS= $(srcdir)/kproplog.c LOGOBJS= kproplog.o SRCS= $(CLIENTSRCS) $(SERVERSRCS) $(LOGSRCS) kprop: $(CLIENTOBJS) $(KRB5_BASE_DEPLIBS) $(CC_LINK) -o kprop $(CLIENTOBJS) $(KRB5_BASE_LIBS) @LIBUTIL@ kpropd: $(SERVEROBJS) $(KDB5_DEPLIB) $(KADMCLNT_DEPLIBS) $(KRB5_BASE_DEPLIBS) $(APPUTILS_DEPLIB) $(CC_LINK) -o kpropd $(SERVEROBJS) $(KDB5_LIB) $(KADMCLNT_LIBS) $(KRB5_BASE_LIBS) $(APPUTILS_LIB) @LIBUTIL@ kproplog: $(LOGOBJS) $(CC_LINK) -o kproplog $(LOGOBJS) $(KADMSRV_LIBS) $(KRB5_BASE_LIBS) install: for f in kprop kpropd kproplog; do \ $(INSTALL_PROGRAM) $$f \ $(DESTDIR)$(SERVER_BINDIR)/`echo $$f|sed '$(transform)'`; \ done clean: $(RM) $(CLIENTOBJS) $(SERVEROBJS) $(LOGOBJS) $(RM) kprop kpropd kproplog krb5-1.16/src/slave/kpropd.c0000644000704600001450000014337713211554426015561 0ustar ghudsonlibuuid/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* slave/kpropd.c */ /* * Copyright (C) 1998 by the FundsXpress, INC. * * All rights reserved. * * Export of this software from the United States of America may require * a specific license from the United States Government. It is the * responsibility of any person or organization contemplating export to * obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of FundsXpress. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. FundsXpress makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ /* * Copyright 1990,1991,2007 by the Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #include "k5-int.h" #include "com_err.h" #include "fake-addrinfo.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "kprop.h" #include #include "iprop.h" #include #include #ifndef GETSOCKNAME_ARG3_TYPE #define GETSOCKNAME_ARG3_TYPE unsigned int #endif #ifndef GETPEERNAME_ARG3_TYPE #define GETPEERNAME_ARG3_TYPE unsigned int #endif #if defined(NEED_DAEMON_PROTO) extern int daemon(int, int); #endif #define SYSLOG_CLASS LOG_DAEMON int runonce = 0; /* * This struct simulates the use of _kadm5_server_handle_t * * This is a COPY of kadm5_server_handle_t from * lib/kadm5/clnt/client_internal.h! */ typedef struct _kadm5_iprop_handle_t { krb5_ui_4 magic_number; krb5_ui_4 struct_version; krb5_ui_4 api_version; char *cache_name; int destroy_cache; CLIENT *clnt; krb5_context context; kadm5_config_params params; struct _kadm5_iprop_handle_t *lhandle; } *kadm5_iprop_handle_t; static char *kprop_version = KPROP_PROT_VERSION; static kadm5_config_params params; static char *progname; static int debug = 0; static int nodaemon = 0; static char *srvtab = NULL; static int standalone = 0; static const char *pid_file = NULL; static pid_t fullprop_child = (pid_t)-1; static krb5_principal server; /* This is our server principal name */ static krb5_principal client; /* This is who we're talking to */ static krb5_context kpropd_context; static krb5_auth_context auth_context; static char *realm = NULL; /* Our realm */ static char *def_realm = NULL; /* Ref pointer for default realm */ static char *file = KPROPD_DEFAULT_FILE; static char *temp_file_name; static char *kdb5_util = KPROPD_DEFAULT_KDB5_UTIL; static char *kerb_database = NULL; static char *acl_file_name = KPROPD_ACL_FILE; static krb5_address *sender_addr; static krb5_address *receiver_addr; static const char *port = KPROP_SERVICE; static char **db_args = NULL; static int db_args_size = 0; static void parse_args(int argc, char **argv); static void do_standalone(void); static void doit(int fd); static krb5_error_code do_iprop(void); static void kerberos_authenticate(krb5_context context, int fd, krb5_principal *clientp, krb5_enctype *etype, struct sockaddr_storage *my_sin); static krb5_boolean authorized_principal(krb5_context context, krb5_principal p, krb5_enctype auth_etype); static void recv_database(krb5_context context, int fd, int database_fd, krb5_data *confmsg); static void load_database(krb5_context context, char *kdb_util, char *database_file_name); static void send_error(krb5_context context, int fd, krb5_error_code err_code, char *err_text); static void recv_error(krb5_context context, krb5_data *inbuf); static unsigned int backoff_from_master(int *cnt); static kadm5_ret_t kadm5_get_kiprop_host_srv_name(krb5_context context, const char *realm_name, char **host_service_name); static void usage() { fprintf(stderr, _("\nUsage: %s [-r realm] [-s srvtab] [-dS] [-f slave_file]\n"), progname); fprintf(stderr, _("\t[-F kerberos_db_file ] [-p kdb5_util_pathname]\n")); fprintf(stderr, _("\t[-x db_args]* [-P port] [-a acl_file]\n")); fprintf(stderr, _("\t[-A admin_server] [--pid-file=pid_file]\n")); exit(1); } static krb5_error_code write_pid_file(const char *path) { FILE *fp; unsigned long pid; fp = fopen(path, "w"); if (fp == NULL) return errno; pid = (unsigned long)getpid(); if (fprintf(fp, "%ld\n", pid) < 0 || fclose(fp) == EOF) return errno; return 0; } typedef void (*sig_handler_fn)(int sig); static void signal_wrapper(int sig, sig_handler_fn handler) { #ifdef POSIX_SIGNALS struct sigaction s_action; memset(&s_action, 0, sizeof(s_action)); sigemptyset(&s_action.sa_mask); s_action.sa_handler = handler; sigaction(sig, &s_action, NULL); #else signal(sig, handler); #endif } static void alarm_handler(int sig) { static char *timeout_msg = "Full propagation timed out\n"; write(STDERR_FILENO, timeout_msg, strlen(timeout_msg)); exit(1); } static void usr1_handler(int sig) { /* Nothing to do, just let the signal interrupt sleep(). */ } static void kill_do_standalone(int sig) { if (fullprop_child > 0) { if (debug) { fprintf(stderr, _("Killing fullprop child (%d)\n"), (int)fullprop_child); } kill(fullprop_child, sig); } /* Make sure our exit status code reflects our having been signaled */ signal_wrapper(sig, SIG_DFL); kill(getpid(), sig); } static void atexit_kill_do_standalone(void) { if (fullprop_child > 0) kill(fullprop_child, SIGHUP); } int main(int argc, char **argv) { krb5_error_code retval; kdb_log_context *log_ctx; int devnull, sock; struct stat st; setlocale(LC_ALL, ""); parse_args(argc, argv); if (fstat(0, &st) == -1) { com_err(progname, errno, _("while checking if stdin is a socket")); exit(1); } /* * Detect whether we're running from inetd; if not then we're in * standalone mode. */ standalone = !S_ISSOCK(st.st_mode); log_ctx = kpropd_context->kdblog_context; signal_wrapper(SIGPIPE, SIG_IGN); if (standalone) { /* "ready" is a sentinel for the test framework. */ if (!debug && !nodaemon) { daemon(0, 0); } else { printf(_("ready\n")); fflush(stdout); } if (pid_file != NULL) { retval = write_pid_file(pid_file); if (retval) { syslog(LOG_ERR, _("Could not write pid file %s: %s"), pid_file, strerror(errno)); exit(1); } } } else { /* * We're an inetd nowait service. Let's not risk anything * read/write from/to the inetd socket unintentionally. */ devnull = open("/dev/null", O_RDWR); if (devnull == -1) { syslog(LOG_ERR, _("Could not open /dev/null: %s"), strerror(errno)); exit(1); } sock = dup(0); if (sock == -1) { syslog(LOG_ERR, _("Could not dup the inetd socket: %s"), strerror(errno)); exit(1); } dup2(devnull, STDIN_FILENO); dup2(devnull, STDOUT_FILENO); dup2(devnull, STDERR_FILENO); close(devnull); doit(sock); exit(0); } if (log_ctx == NULL || log_ctx->iproprole != IPROP_SLAVE) { do_standalone(); /* do_standalone() should never return */ assert(0); } /* * This is the iprop case. We'll fork a child to run do_standalone(). The * parent will run do_iprop(). We try to kill the child if we get killed. * Catch SIGUSR1, which can be used to interrupt the sleep timer and force * an iprop request. */ signal_wrapper(SIGHUP, kill_do_standalone); signal_wrapper(SIGINT, kill_do_standalone); signal_wrapper(SIGQUIT, kill_do_standalone); signal_wrapper(SIGTERM, kill_do_standalone); signal_wrapper(SIGSEGV, kill_do_standalone); signal_wrapper(SIGUSR1, usr1_handler); atexit(atexit_kill_do_standalone); fullprop_child = fork(); switch (fullprop_child) { case -1: com_err(progname, errno, _("do_iprop failed.\n")); break; case 0: do_standalone(); /* do_standalone() should never return */ /* NOTREACHED */ break; default: retval = do_iprop(); /* do_iprop() can return due to failures and runonce. */ kill(fullprop_child, SIGHUP); wait(NULL); if (retval) com_err(progname, retval, _("do_iprop failed.\n")); else exit(0); } exit(1); } /* Use getaddrinfo to determine a wildcard listener address, preferring * IPv6 if available. */ static int get_wildcard_addr(struct addrinfo **res) { struct addrinfo hints; int error; memset(&hints, 0, sizeof(hints)); hints.ai_socktype = SOCK_STREAM; hints.ai_flags = AI_PASSIVE | AI_ADDRCONFIG; hints.ai_family = AF_INET6; error = getaddrinfo(NULL, port, &hints, res); if (error == 0) return 0; hints.ai_family = AF_INET; return getaddrinfo(NULL, port, &hints, res); } static void do_standalone() { struct sockaddr_in frominet; struct addrinfo *res; GETPEERNAME_ARG3_TYPE fromlen; int finet, s, ret, error, val, status; pid_t child_pid; pid_t wait_pid; error = get_wildcard_addr(&res); if (error != 0) { fprintf(stderr, _("getaddrinfo: %s\n"), gai_strerror(error)); exit(1); } finet = socket(res->ai_family, res->ai_socktype, res->ai_protocol); if (finet < 0) { com_err(progname, errno, _("while obtaining socket")); exit(1); } val = 1; if (setsockopt(finet, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val)) < 0) com_err(progname, errno, _("while setting SO_REUSEADDR option")); #if defined(IPV6_V6ONLY) /* Make sure dual-stack support is enabled on IPv6 listener sockets if * possible. */ val = 0; if (res->ai_family == AF_INET6 && setsockopt(finet, IPPROTO_IPV6, IPV6_V6ONLY, &val, sizeof(val)) < 0) com_err(progname, errno, _("while unsetting IPV6_V6ONLY option")); #endif ret = bind(finet, res->ai_addr, res->ai_addrlen); if (ret < 0) { com_err(progname, errno, _("while binding listener socket")); exit(1); } if (listen(finet, 5) < 0) { com_err(progname, errno, "in listen call"); exit(1); } for (;;) { memset(&frominet, 0, sizeof(frominet)); fromlen = sizeof(frominet); if (debug) fprintf(stderr, _("waiting for a kprop connection\n")); s = accept(finet, (struct sockaddr *) &frominet, &fromlen); if (s < 0) { int e = errno; if (e != EINTR) { com_err(progname, e, _("while accepting connection")); } } child_pid = fork(); switch (child_pid) { case -1: com_err(progname, errno, _("while forking")); exit(1); case 0: close(finet); doit(s); close(s); _exit(0); default: do { wait_pid = waitpid(child_pid, &status, 0); } while (wait_pid == -1 && errno == EINTR); if (wait_pid == -1) { /* Something bad happened; panic. */ if (debug) { fprintf(stderr, _("waitpid() failed to wait for doit() " "(%d %s)\n"), errno, strerror(errno)); } com_err(progname, errno, _("while waiting to receive database")); exit(1); } if (debug) { fprintf(stderr, _("Database load process for full propagation " "completed.\n")); } close(s); /* If we are the fullprop child in iprop mode, notify the parent * process that it should poll for incremental updates. */ if (fullprop_child == 0) kill(getppid(), SIGUSR1); else if (runonce) exit(0); } } exit(0); } static void doit(int fd) { struct sockaddr_storage from; int on = 1; GETPEERNAME_ARG3_TYPE fromlen; krb5_error_code retval; krb5_data confmsg; int lock_fd; mode_t omask; krb5_enctype etype; int database_fd; char host[INET6_ADDRSTRLEN + 1]; signal_wrapper(SIGALRM, alarm_handler); alarm(params.iprop_resync_timeout); fromlen = sizeof(from); if (getpeername(fd, (struct sockaddr *)&from, &fromlen) < 0) { #ifdef ENOTSOCK if (errno == ENOTSOCK && fd == 0 && !standalone) { fprintf(stderr, _("%s: Standard input does not appear to be a network " "socket.\n" "\t(Not run from inetd, and missing the -S option?)\n"), progname); exit(1); } #endif fprintf(stderr, "%s: ", progname); perror("getpeername"); exit(1); } if (setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, &on, sizeof(on)) < 0) { com_err(progname, errno, _("while attempting setsockopt (SO_KEEPALIVE)")); } if (getnameinfo((const struct sockaddr *) &from, fromlen, host, sizeof(host), NULL, 0, 0) == 0) { syslog(LOG_INFO, _("Connection from %s"), host); if (debug) fprintf(stderr, "Connection from %s\n", host); } /* * Now do the authentication */ kerberos_authenticate(kpropd_context, fd, &client, &etype, &from); if (!authorized_principal(kpropd_context, client, etype)) { char *name; retval = krb5_unparse_name(kpropd_context, client, &name); if (retval) { com_err(progname, retval, "While unparsing client name"); exit(1); } if (debug) { fprintf(stderr, _("Rejected connection from unauthorized principal %s\n"), name); } syslog(LOG_WARNING, _("Rejected connection from unauthorized principal %s"), name); free(name); exit(1); } omask = umask(077); lock_fd = open(temp_file_name, O_RDWR | O_CREAT, 0600); (void)umask(omask); retval = krb5_lock_file(kpropd_context, lock_fd, KRB5_LOCKMODE_EXCLUSIVE | KRB5_LOCKMODE_DONTBLOCK); if (retval) { com_err(progname, retval, _("while trying to lock '%s'"), temp_file_name); exit(1); } database_fd = open(temp_file_name, O_WRONLY | O_CREAT | O_TRUNC, 0600); if (database_fd < 0) { com_err(progname, errno, _("while opening database file, '%s'"), temp_file_name); exit(1); } recv_database(kpropd_context, fd, database_fd, &confmsg); if (rename(temp_file_name, file)) { com_err(progname, errno, _("while renaming %s to %s"), temp_file_name, file); exit(1); } retval = krb5_lock_file(kpropd_context, lock_fd, KRB5_LOCKMODE_SHARED); if (retval) { com_err(progname, retval, _("while downgrading lock on '%s'"), temp_file_name); exit(1); } load_database(kpropd_context, kdb5_util, file); retval = krb5_lock_file(kpropd_context, lock_fd, KRB5_LOCKMODE_UNLOCK); if (retval) { com_err(progname, retval, _("while unlocking '%s'"), temp_file_name); exit(1); } close(lock_fd); /* * Send the acknowledgement message generated in * recv_database, then close the socket. */ retval = krb5_write_message(kpropd_context, &fd, &confmsg); if (retval) { krb5_free_data_contents(kpropd_context, &confmsg); com_err(progname, retval, _("while sending # of received bytes")); exit(1); } krb5_free_data_contents(kpropd_context, &confmsg); if (close(fd) < 0) { com_err(progname, errno, _("while trying to close database file")); exit(1); } exit(0); } /* Default timeout can be changed using clnt_control() */ static struct timeval full_resync_timeout = { 25, 0 }; static kdb_fullresync_result_t * full_resync(CLIENT *clnt) { static kdb_fullresync_result_t clnt_res; uint32_t vers = IPROPX_VERSION_1; /* max version we support */ enum clnt_stat status; memset(&clnt_res, 0, sizeof(clnt_res)); status = clnt_call(clnt, IPROP_FULL_RESYNC_EXT, (xdrproc_t)xdr_u_int32, &vers, (xdrproc_t)xdr_kdb_fullresync_result_t, &clnt_res, full_resync_timeout); if (status == RPC_PROCUNAVAIL) { status = clnt_call(clnt, IPROP_FULL_RESYNC, (xdrproc_t)xdr_void, &vers, (xdrproc_t)xdr_kdb_fullresync_result_t, &clnt_res, full_resync_timeout); } return (status == RPC_SUCCESS) ? &clnt_res : NULL; } /* * Beg for incrementals from the KDC. * * Returns 0 on success IFF runonce is true. * Returns non-zero on failure due to errors. */ krb5_error_code do_iprop() { kadm5_ret_t retval; krb5_principal iprop_svc_principal; void *server_handle = NULL; char *iprop_svc_princstr = NULL, *master_svc_princstr = NULL; unsigned int pollin, backoff_time; int backoff_cnt = 0, reinit_cnt = 0; struct timeval iprop_start, iprop_end; unsigned long usec; time_t frrequested = 0, now; kdb_incr_result_t *incr_ret; kdb_last_t mylast; kdb_fullresync_result_t *full_ret; kadm5_iprop_handle_t handle; if (debug) fprintf(stderr, _("Incremental propagation enabled\n")); pollin = params.iprop_poll_time; if (pollin == 0) pollin = 10; if (master_svc_princstr == NULL) { retval = kadm5_get_kiprop_host_srv_name(kpropd_context, realm, &master_svc_princstr); if (retval) { com_err(progname, retval, _("%s: unable to get kiprop host based " "service name for realm %s\n"), progname, realm); return retval; } } retval = sn2princ_realm(kpropd_context, NULL, KIPROP_SVC_NAME, realm, &iprop_svc_principal); if (retval) { com_err(progname, retval, _("while trying to construct host service principal")); return retval; } retval = krb5_unparse_name(kpropd_context, iprop_svc_principal, &iprop_svc_princstr); if (retval) { com_err(progname, retval, _("while canonicalizing principal name")); krb5_free_principal(kpropd_context, iprop_svc_principal); return retval; } krb5_free_principal(kpropd_context, iprop_svc_principal); reinit: /* * Authentication, initialize rpcsec_gss handle etc. */ if (debug) { fprintf(stderr, _("Initializing kadm5 as client %s\n"), iprop_svc_princstr); } retval = kadm5_init_with_skey(kpropd_context, iprop_svc_princstr, srvtab, master_svc_princstr, ¶ms, KADM5_STRUCT_VERSION, KADM5_API_VERSION_4, db_args, &server_handle); if (retval) { if (debug) fprintf(stderr, _("kadm5 initialization failed!\n")); if (retval == KADM5_RPC_ERROR) { reinit_cnt++; if (server_handle) kadm5_destroy(server_handle); server_handle = NULL; handle = NULL; com_err(progname, retval, _( "while attempting to connect" " to master KDC ... retrying")); backoff_time = backoff_from_master(&reinit_cnt); if (debug) { fprintf(stderr, _("Sleeping %d seconds to re-initialize " "kadm5 (RPC ERROR)\n"), backoff_time); } sleep(backoff_time); goto reinit; } else { if (retval == KADM5_BAD_CLIENT_PARAMS || retval == KADM5_BAD_SERVER_PARAMS) { com_err(progname, retval, _("while initializing %s interface"), progname); usage(); } reinit_cnt++; com_err(progname, retval, _("while initializing %s interface, retrying"), progname); backoff_time = backoff_from_master(&reinit_cnt); if (debug) { fprintf(stderr, _("Sleeping %d seconds to re-initialize " "kadm5 (krb5kdc not running?)\n"), backoff_time); } sleep(backoff_time); goto reinit; } } if (debug) fprintf(stderr, _("kadm5 initialization succeeded\n")); /* * Reset re-initialization count to zero now. */ reinit_cnt = backoff_time = 0; /* * Reset the handle to the correct type for the RPC call */ handle = server_handle; for (;;) { incr_ret = NULL; full_ret = NULL; /* * Get the most recent ulog entry sno + ts, which * we package in the request to the master KDC */ retval = ulog_get_last(kpropd_context, &mylast); if (retval) { com_err(progname, retval, _("reading update log header")); goto done; } /* * Loop continuously on an iprop_get_updates_1(), * so that we can keep probing the master for updates * or (if needed) do a full resync of the krb5 db. */ if (debug) { fprintf(stderr, _("Calling iprop_get_updates_1 " "(sno=%u sec=%u usec=%u)\n"), (unsigned int)mylast.last_sno, (unsigned int)mylast.last_time.seconds, (unsigned int)mylast.last_time.useconds); } gettimeofday(&iprop_start, NULL); incr_ret = iprop_get_updates_1(&mylast, handle->clnt); if (incr_ret == (kdb_incr_result_t *)NULL) { clnt_perror(handle->clnt, _("iprop_get_updates call failed")); if (server_handle) kadm5_destroy(server_handle); server_handle = NULL; handle = (kadm5_iprop_handle_t)NULL; if (debug) { fprintf(stderr, _("Reinitializing iprop because get updates " "failed\n")); } goto reinit; } switch (incr_ret->ret) { case UPDATE_FULL_RESYNC_NEEDED: /* * If we're already asked for a full resync and we still * need one and the last one hasn't timed out then just keep * asking for updates as eventually the resync will finish * (or, if it times out we'll just try again). Note that * doit() also applies a timeout to the full resync, thus * it's OK for us to do the same here. */ now = time(NULL); if (frrequested && (now - frrequested) < params.iprop_resync_timeout) { if (debug) fprintf(stderr, _("Still waiting for full resync\n")); break; } else { frrequested = now; if (debug) fprintf(stderr, _("Full resync needed\n")); syslog(LOG_INFO, _("kpropd: Full resync needed.")); full_ret = full_resync(handle->clnt); if (full_ret == NULL) { clnt_perror(handle->clnt, _("iprop_full_resync call failed")); kadm5_destroy(server_handle); server_handle = NULL; handle = NULL; goto reinit; } } switch (full_ret->ret) { case UPDATE_OK: if (debug) fprintf(stderr, _("Full resync request granted\n")); syslog(LOG_INFO, _("Full resync request granted.")); backoff_cnt = 0; break; case UPDATE_BUSY: /* * Exponential backoff */ if (debug) fprintf(stderr, _("Exponential backoff\n")); backoff_cnt++; break; case UPDATE_PERM_DENIED: if (debug) fprintf(stderr, _("Full resync permission denied\n")); syslog(LOG_ERR, _("Full resync, permission denied.")); goto error; case UPDATE_ERROR: if (debug) fprintf(stderr, _("Full resync error from master\n")); syslog(LOG_ERR, _(" Full resync, " "error returned from master KDC.")); goto error; default: backoff_cnt = 0; if (debug) { fprintf(stderr, _("Full resync invalid result from master\n")); } syslog(LOG_ERR, _("Full resync, " "invalid return from master KDC.")); break; } break; case UPDATE_OK: backoff_cnt = 0; frrequested = 0; /* * ulog_replay() will convert the ulog updates to db * entries using the kdb conv api and will commit * the entries to the slave kdc database */ if (debug) { fprintf(stderr, _("Got incremental updates " "(sno=%u sec=%u usec=%u)\n"), (unsigned int)incr_ret->lastentry.last_sno, (unsigned int)incr_ret->lastentry.last_time.seconds, (unsigned int)incr_ret->lastentry.last_time.useconds); } retval = ulog_replay(kpropd_context, incr_ret, db_args); if (retval) { const char *msg = krb5_get_error_message(kpropd_context, retval); if (debug) { fprintf(stderr, _("ulog_replay failed (%s), updates not " "registered\n"), msg); } syslog(LOG_ERR, _("ulog_replay failed (%s), updates " "not registered."), msg); krb5_free_error_message(kpropd_context, msg); break; } gettimeofday(&iprop_end, NULL); usec = (iprop_end.tv_sec - iprop_start.tv_sec) * 1000000 + iprop_end.tv_usec - iprop_start.tv_usec; syslog(LOG_INFO, _("Incremental updates: %d updates / %lu us"), incr_ret->updates.kdb_ulog_t_len, usec); if (debug) { fprintf(stderr, _("Incremental updates: %d updates / " "%lu us\n"), incr_ret->updates.kdb_ulog_t_len, usec); } break; case UPDATE_PERM_DENIED: if (debug) fprintf(stderr, _("get_updates permission denied\n")); syslog(LOG_ERR, _("get_updates, permission denied.")); goto error; case UPDATE_ERROR: if (debug) fprintf(stderr, _("get_updates error from master\n")); syslog(LOG_ERR, _("get_updates, error returned from master KDC.")); goto error; case UPDATE_BUSY: /* * Exponential backoff */ if (debug) fprintf(stderr, _("get_updates master busy; backoff\n")); backoff_cnt++; break; case UPDATE_NIL: /* * Master-slave are in sync */ if (debug) fprintf(stderr, _("KDC is synchronized with master.\n")); backoff_cnt = 0; frrequested = 0; break; default: backoff_cnt = 0; if (debug) fprintf(stderr, _("get_updates invalid result from master\n")); syslog(LOG_ERR, _("get_updates, invalid return from master KDC.")); break; } if (runonce == 1 && incr_ret->ret != UPDATE_FULL_RESYNC_NEEDED) goto done; /* * Sleep for the specified poll interval (Default is 2 mts), * or do a binary exponential backoff if we get an * UPDATE_BUSY signal */ if (backoff_cnt > 0) { backoff_time = backoff_from_master(&backoff_cnt); if (debug) { fprintf(stderr, _("Busy signal received " "from master, backoff for %d secs\n"), backoff_time); } sleep(backoff_time); } else { if (debug) { fprintf(stderr, _("Waiting for %d seconds before checking " "for updates again\n"), pollin); } sleep(pollin); } } error: if (debug) fprintf(stderr, _("ERROR returned by master, bailing\n")); syslog(LOG_ERR, _("ERROR returned by master KDC, bailing.\n")); done: free(iprop_svc_princstr); free(master_svc_princstr); krb5_free_default_realm(kpropd_context, def_realm); kadm5_destroy(server_handle); krb5_db_fini(kpropd_context); ulog_fini(kpropd_context); krb5_free_context(kpropd_context); return (runonce == 1) ? 0 : 1; } /* Do exponential backoff, since master KDC is BUSY or down. */ static unsigned int backoff_from_master(int *cnt) { unsigned int btime; btime = (unsigned int)(2<<(*cnt)); if (btime > MAX_BACKOFF) { btime = MAX_BACKOFF; (*cnt)--; } return btime; } static void kpropd_com_err_proc(const char *whoami, long code, const char *fmt, va_list args) #if !defined(__cplusplus) && (__GNUC__ > 2) __attribute__((__format__(__printf__, 3, 0))) #endif ; static void kpropd_com_err_proc(const char *whoami, long code, const char *fmt, va_list args) { char error_buf[8096]; error_buf[0] = '\0'; if (fmt) vsnprintf(error_buf, sizeof(error_buf), fmt, args); syslog(LOG_ERR, "%s%s%s%s%s", whoami ? whoami : "", whoami ? ": " : "", code ? error_message(code) : "", code ? " " : "", error_buf); } static void parse_args(int argc, char **argv) { char **newargs; int c; krb5_error_code retval; enum { PID_FILE = 256 }; struct option long_options[] = { { "pid-file", 1, NULL, PID_FILE }, }; memset(¶ms, 0, sizeof(params)); /* Since we may modify the KDB with ulog_replay(), we must read the KDC * profile. */ retval = krb5int_init_context_kdc(&kpropd_context); if (retval) { com_err(argv[0], retval, _("while initializing krb5")); exit(1); } progname = argv[0]; while ((c = getopt_long(argc, argv, "A:f:F:p:P:r:s:DdSa:tx:", long_options, NULL)) != -1) { switch (c) { case 'A': params.mask |= KADM5_CONFIG_ADMIN_SERVER; params.admin_server = optarg; break; case 'f': file = optarg; break; case 'F': kerb_database = optarg; break; case 'p': kdb5_util = optarg; break; case 'P': port = optarg; break; case 'r': realm = optarg; break; case 's': srvtab = optarg; break; case 'D': nodaemon++; break; case 'd': debug++; break; case 'S': /* Standalone mode is now auto-detected; see main(). */ break; case 'a': acl_file_name = optarg; break; case 't': /* Undocumented option - for testing only. Run the kpropd * server exactly once. */ runonce = 1; break; case 'x': newargs = realloc(db_args, (db_args_size + 2) * sizeof(*db_args)); if (newargs == NULL) { com_err(argv[0], errno, _("copying db args")); exit(1); } db_args = newargs; db_args[db_args_size] = optarg; db_args[db_args_size + 1] = NULL; db_args_size++; break; case PID_FILE: pid_file = optarg; break; default: usage(); } } if (optind != argc) usage(); openlog("kpropd", LOG_PID | LOG_ODELAY, SYSLOG_CLASS); if (!debug) set_com_err_hook(kpropd_com_err_proc); if (realm == NULL) { retval = krb5_get_default_realm(kpropd_context, &def_realm); if (retval) { com_err(progname, retval, _("Unable to get default realm")); exit(1); } realm = def_realm; } else { retval = krb5_set_default_realm(kpropd_context, realm); if (retval) { com_err(progname, retval, _("Unable to set default realm")); exit(1); } } /* Construct service name from local hostname. */ retval = sn2princ_realm(kpropd_context, NULL, KPROP_SERVICE_NAME, realm, &server); if (retval) { com_err(progname, retval, _("while trying to construct my service name")); exit(1); } /* Construct the name of the temporary file. */ if (asprintf(&temp_file_name, "%s.temp", file) < 0) { com_err(progname, ENOMEM, _("while allocating filename for temp file")); exit(1); } params.realm = realm; params.mask |= KADM5_CONFIG_REALM; retval = kadm5_get_config_params(kpropd_context, 1, ¶ms, ¶ms); if (retval) { com_err(progname, retval, _("while initializing")); exit(1); } if (params.iprop_enabled == TRUE) { ulog_set_role(kpropd_context, IPROP_SLAVE); if (ulog_map(kpropd_context, params.iprop_logfile, params.iprop_ulogsize)) { com_err(progname, errno, _("Unable to map log!\n")); exit(1); } } } /* * Figure out who's calling on the other end of the connection.... */ static void kerberos_authenticate(krb5_context context, int fd, krb5_principal *clientp, krb5_enctype *etype, struct sockaddr_storage *my_sin) { krb5_error_code retval; krb5_ticket *ticket; struct sockaddr_storage r_sin; GETSOCKNAME_ARG3_TYPE sin_length; krb5_keytab keytab = NULL; char *name, etypebuf[100]; /* Set recv_addr and send_addr. */ sockaddr2krbaddr(context, my_sin->ss_family, (struct sockaddr *)my_sin, &sender_addr); sin_length = sizeof(r_sin); if (getsockname(fd, (struct sockaddr *)&r_sin, &sin_length)) { com_err(progname, errno, _("while getting local socket address")); exit(1); } sockaddr2krbaddr(context, r_sin.ss_family, (struct sockaddr *)&r_sin, &receiver_addr); if (debug) { retval = krb5_unparse_name(context, server, &name); if (retval) { com_err(progname, retval, _("while unparsing client name")); exit(1); } fprintf(stderr, "krb5_recvauth(%d, %s, %s, ...)\n", fd, kprop_version, name); free(name); } retval = krb5_auth_con_init(context, &auth_context); if (retval) { syslog(LOG_ERR, _("Error in krb5_auth_con_ini: %s"), error_message(retval)); exit(1); } retval = krb5_auth_con_setflags(context, auth_context, KRB5_AUTH_CONTEXT_DO_SEQUENCE); if (retval) { syslog(LOG_ERR, _("Error in krb5_auth_con_setflags: %s"), error_message(retval)); exit(1); } retval = krb5_auth_con_setaddrs(context, auth_context, receiver_addr, sender_addr); if (retval) { syslog(LOG_ERR, _("Error in krb5_auth_con_setaddrs: %s"), error_message(retval)); exit(1); } if (srvtab != NULL) { retval = krb5_kt_resolve(context, srvtab, &keytab); if (retval) { syslog(LOG_ERR, _("Error in krb5_kt_resolve: %s"), error_message(retval)); exit(1); } } retval = krb5_recvauth(context, &auth_context, &fd, kprop_version, server, 0, keytab, &ticket); if (retval) { syslog(LOG_ERR, _("Error in krb5_recvauth: %s"), error_message(retval)); exit(1); } retval = krb5_copy_principal(context, ticket->enc_part2->client, clientp); if (retval) { syslog(LOG_ERR, _("Error in krb5_copy_prinicpal: %s"), error_message(retval)); exit(1); } *etype = ticket->enc_part.enctype; if (debug) { retval = krb5_unparse_name(context, *clientp, &name); if (retval) { com_err(progname, retval, _("while unparsing client name")); exit(1); } retval = krb5_enctype_to_string(*etype, etypebuf, sizeof(etypebuf)); if (retval) { com_err(progname, retval, _("while unparsing ticket etype")); exit(1); } fprintf(stderr, _("authenticated client: %s (etype == %s)\n"), name, etypebuf); free(name); } krb5_free_ticket(context, ticket); } static krb5_boolean authorized_principal(krb5_context context, krb5_principal p, krb5_enctype auth_etype) { char *name, *ptr, buf[1024]; krb5_error_code retval; FILE *acl_file; int end; krb5_enctype acl_etype; retval = krb5_unparse_name(context, p, &name); if (retval) return FALSE; acl_file = fopen(acl_file_name, "r"); if (acl_file == NULL) return FALSE; while (!feof(acl_file)) { if (!fgets(buf, sizeof(buf), acl_file)) break; end = strlen(buf) - 1; if (buf[end] == '\n') buf[end] = '\0'; if (!strncmp(name, buf, strlen(name))) { ptr = buf + strlen(name); /* If the next character is not whitespace or null, then the match * is only partial. Continue on to new lines. */ if (*ptr != '\0' && !isspace((int)*ptr)) continue; /* Otherwise, skip trailing whitespace. */ for (; *ptr != '\0' && isspace((int)*ptr); ptr++) ; /* * Now, look for an etype string. If there isn't one, return true. * If there is an invalid string, continue. If there is a valid * string, return true only if it matches the etype passed in, * otherwise continue. */ if (*ptr != '\0' && ((retval = krb5_string_to_enctype(ptr, &acl_etype)) || (acl_etype != auth_etype))) continue; free(name); fclose(acl_file); return TRUE; } } free(name); fclose(acl_file); return FALSE; } static void recv_database(krb5_context context, int fd, int database_fd, krb5_data *confmsg) { krb5_ui_4 database_size, received_size; int n; char buf[1024]; krb5_data inbuf, outbuf; krb5_error_code retval; /* Receive and decode size from client. */ retval = krb5_read_message(context, &fd, &inbuf); if (retval) { send_error(context, fd, retval, "while reading database size"); com_err(progname, retval, _("while reading size of database from client")); exit(1); } if (krb5_is_krb_error(&inbuf)) recv_error(context, &inbuf); retval = krb5_rd_safe(context,auth_context,&inbuf,&outbuf,NULL); if (retval) { send_error(context, fd, retval, "while decoding database size"); krb5_free_data_contents(context, &inbuf); com_err(progname, retval, _("while decoding database size from client")); exit(1); } memcpy(&database_size, outbuf.data, sizeof(database_size)); krb5_free_data_contents(context, &inbuf); krb5_free_data_contents(context, &outbuf); database_size = ntohl(database_size); /* Initialize the initial vector. */ retval = krb5_auth_con_initivector(context, auth_context); if (retval) { send_error(context, fd, retval, "failed while initializing i_vector"); com_err(progname, retval, _("while initializing i_vector")); exit(1); } if (debug) fprintf(stderr, _("Full propagation transfer started.\n")); /* Now start receiving the database from the net. */ received_size = 0; while (received_size < database_size) { retval = krb5_read_message(context, &fd, &inbuf); if (retval) { snprintf(buf, sizeof(buf), "while reading database block starting at offset %d", received_size); com_err(progname, retval, "%s", buf); send_error(context, fd, retval, buf); exit(1); } if (krb5_is_krb_error(&inbuf)) recv_error(context, &inbuf); retval = krb5_rd_priv(context, auth_context, &inbuf, &outbuf, NULL); if (retval) { snprintf(buf, sizeof(buf), "while decoding database block starting at offset %d", received_size); com_err(progname, retval, "%s", buf); send_error(context, fd, retval, buf); krb5_free_data_contents(context, &inbuf); exit(1); } n = write(database_fd, outbuf.data, outbuf.length); krb5_free_data_contents(context, &inbuf); krb5_free_data_contents(context, &outbuf); if (n < 0) { snprintf(buf, sizeof(buf), "while writing database block starting at offset %d", received_size); send_error(context, fd, errno, buf); } else if ((unsigned int)n != outbuf.length) { snprintf(buf, sizeof(buf), "incomplete write while writing database block starting " "at \noffset %d (%d written, %d expected)", received_size, n, outbuf.length); send_error(context, fd, KRB5KRB_ERR_GENERIC, buf); } received_size += outbuf.length; } /* OK, we've seen the entire file. Did we get too many bytes? */ if (received_size > database_size) { snprintf(buf, sizeof(buf), "Received %d bytes, expected %d bytes for database file", received_size, database_size); send_error(context, fd, KRB5KRB_ERR_GENERIC, buf); } if (debug) fprintf(stderr, _("Full propagation transfer finished.\n")); /* Create message acknowledging number of bytes received, but * don't send it until kdb5_util returns successfully. */ database_size = htonl(database_size); inbuf.data = (char *)&database_size; inbuf.length = sizeof(database_size); retval = krb5_mk_safe(context,auth_context,&inbuf,confmsg,NULL); if (retval) { com_err(progname, retval, "while encoding # of receieved bytes"); send_error(context, fd, retval, "while encoding # of received bytes"); exit(1); } } static void send_error(krb5_context context, int fd, krb5_error_code err_code, char *err_text) { krb5_error error; const char *text; krb5_data outbuf; char buf[1024]; memset(&error, 0, sizeof(error)); krb5_us_timeofday(context, &error.stime, &error.susec); error.server = server; error.client = client; text = (err_text != NULL) ? err_text : error_message(err_code); error.error = err_code - ERROR_TABLE_BASE_krb5; if (error.error > 127) { error.error = KRB_ERR_GENERIC; if (err_text) { snprintf(buf, sizeof(buf), "%s %s", error_message(err_code), err_text); text = buf; } } error.text.length = strlen(text) + 1; error.text.data = strdup(text); if (error.text.data) { if (!krb5_mk_error(context, &error, &outbuf)) { (void)krb5_write_message(context, &fd, &outbuf); krb5_free_data_contents(context, &outbuf); } free(error.text.data); } } void recv_error(krb5_context context, krb5_data *inbuf) { krb5_error *error; krb5_error_code retval; retval = krb5_rd_error(context, inbuf, &error); if (retval) { com_err(progname, retval, _("while decoding error packet from client")); exit(1); } if (error->error == KRB_ERR_GENERIC) { if (error->text.data) fprintf(stderr, _("Generic remote error: %s\n"), error->text.data); } else if (error->error) { com_err(progname, (krb5_error_code)error->error + ERROR_TABLE_BASE_krb5, _("signaled from server")); if (error->text.data) { fprintf(stderr, _("Error text from client: %s\n"), error->text.data); } } krb5_free_error(context, error); exit(1); } static void load_database(krb5_context context, char *kdb_util, char *database_file_name) { static char *edit_av[10]; int error_ret, child_pid, count; /* has been included, so BSD will be defined on * BSD systems. */ #if BSD > 0 && BSD <= 43 #ifndef WEXITSTATUS #define WEXITSTATUS(w) (w).w_retcode #endif union wait waitb; #else int waitb; #endif kdb_log_context *log_ctx; if (debug) fprintf(stderr, "calling kdb5_util to load database\n"); log_ctx = context->kdblog_context; edit_av[0] = kdb_util; count = 1; if (realm) { edit_av[count++] = "-r"; edit_av[count++] = realm; } edit_av[count++] = "load"; if (kerb_database) { edit_av[count++] = "-d"; edit_av[count++] = kerb_database; } if (log_ctx && log_ctx->iproprole == IPROP_SLAVE) edit_av[count++] = "-i"; edit_av[count++] = database_file_name; edit_av[count++] = NULL; switch (child_pid = fork()) { case -1: com_err(progname, errno, _("while trying to fork %s"), kdb_util); exit(1); case 0: execv(kdb_util, edit_av); com_err(progname, errno, _("while trying to exec %s"), kdb_util); _exit(1); /*NOTREACHED*/ default: if (debug) fprintf(stderr, "Load PID is %d\n", child_pid); if (wait(&waitb) < 0) { com_err(progname, errno, _("while waiting for %s"), kdb_util); exit(1); } } if (!WIFEXITED(waitb)) { com_err(progname, 0, _("%s load terminated"), kdb_util); exit(1); } error_ret = WEXITSTATUS(waitb); if (error_ret) { com_err(progname, 0, _("%s returned a bad exit status (%d)"), kdb_util, error_ret); exit(1); } return; } /* * Get the host base service name for the kiprop principal. Returns * KADM5_OK on success. Caller must free the storage allocated * for host_service_name. */ static kadm5_ret_t kadm5_get_kiprop_host_srv_name(krb5_context context, const char *realm_name, char **host_service_name) { char *name, *host; host = params.admin_server; /* XXX */ if (asprintf(&name, "%s/%s", KADM5_KIPROP_HOST_SERVICE, host) < 0) { free(host); return ENOMEM; } *host_service_name = name; return KADM5_OK; } krb5-1.16/src/slave/kproplog.c0000644000704600001450000003636113211554426016111 0ustar ghudsonlibuuid/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ /* * This module will parse the update logs on the master or slave servers. */ #include "k5-int.h" #include #include #include #include #include #include #include #include #include static char *progname; static void usage() { fprintf(stderr, _("\nUsage: %s [-h] [-v] [-v] [-e num]\n\t%s -R\n\n"), progname, progname); exit(1); } /* * Print the attribute flags of principal in human readable form. */ static void print_flags(unsigned int flags) { unsigned int i; static char *prflags[] = { "DISALLOW_POSTDATED", /* 0x00000001 */ "DISALLOW_FORWARDABLE", /* 0x00000002 */ "DISALLOW_TGT_BASED", /* 0x00000004 */ "DISALLOW_RENEWABLE", /* 0x00000008 */ "DISALLOW_PROXIABLE", /* 0x00000010 */ "DISALLOW_DUP_SKEY", /* 0x00000020 */ "DISALLOW_ALL_TIX", /* 0x00000040 */ "REQUIRES_PRE_AUTH", /* 0x00000080 */ "REQUIRES_HW_AUTH", /* 0x00000100 */ "REQUIRES_PWCHANGE", /* 0x00000200 */ "UNKNOWN_0x00000400", /* 0x00000400 */ "UNKNOWN_0x00000800", /* 0x00000800 */ "DISALLOW_SVR", /* 0x00001000 */ "PWCHANGE_SERVICE", /* 0x00002000 */ "SUPPORT_DESMD5", /* 0x00004000 */ "NEW_PRINC", /* 0x00008000 */ "UNKNOWN_0x00010000", /* 0x00010000 */ "UNKNOWN_0x00020000", /* 0x00020000 */ "UNKNOWN_0x00040000", /* 0x00040000 */ "UNKNOWN_0x00080000", /* 0x00080000 */ "OK_AS_DELEGATE", /* 0x00100000 */ "OK_TO_AUTH_AS_DELEGATE", /* 0x00200000 */ "NO_AUTH_DATA_REQUIRED", /* 0x00400000 */ }; for (i = 0; i < sizeof(prflags) / sizeof(*prflags); i++) { if (flags & (krb5_flags)(1 << i)) printf("\t\t\t%s\n", prflags[i]); } } /* ctime() for uint32_t* */ static char * ctime_uint32(uint32_t *time32) { time_t tmp; tmp = *time32; return ctime(&tmp); } /* Display time information. */ static void print_time(uint32_t *timep) { if (*timep == 0L) printf("\t\t\tNone\n"); else printf("\t\t\t%s", ctime_uint32(timep)); } static void print_deltat(uint32_t *deltat) { krb5_error_code ret; static char buf[30]; ret = krb5_deltat_to_string(*deltat, buf, sizeof(buf)); if (ret) printf("\t\t\t(error)\n"); else printf("\t\t\t%s\n", buf); } /* Display string in hex primitive. */ static void print_hex(const char *tag, utf8str_t *str) { unsigned int i; unsigned int len; len = str->utf8str_t_len; printf("\t\t\t%s(%d): 0x", tag, len); for (i = 0; i < len; i++) printf("%02x", (krb5_octet)str->utf8str_t_val[i]); printf("\n"); } /* Display string primitive. */ static void print_str(const char *tag, utf8str_t *str) { krb5_error_code ret; char *s; s = k5memdup0(str->utf8str_t_val, str->utf8str_t_len, &ret); if (s == NULL) { fprintf(stderr, _("\nCouldn't allocate memory")); exit(1); } printf("\t\t\t%s(%d): %s\n", tag, str->utf8str_t_len, s); free(s); } /* Display data components. */ static void print_data(const char *tag, kdbe_data_t *data) { printf("\t\t\tmagic: 0x%x\n", data->k_magic); print_str(tag, &data->k_data); } /* Display the principal components. */ static void print_princ(kdbe_princ_t *princ) { int i, len; kdbe_data_t *data; print_str("realm", &princ->k_realm); len = princ->k_components.k_components_len; data = princ->k_components.k_components_val; for (i = 0; i < len; i++, data++) print_data("princ", data); } /* Display individual key. */ static void print_key(kdbe_key_t *k) { unsigned int i; utf8str_t *str; printf("\t\t\tver: %d\n", k->k_ver); printf("\t\t\tkvno: %d\n", k->k_kvno); for (i = 0; i < k->k_enctype.k_enctype_len; i++) printf("\t\t\tenc type: 0x%x\n", k->k_enctype.k_enctype_val[i]); str = k->k_contents.k_contents_val; for (i = 0; i < k->k_contents.k_contents_len; i++, str++) print_hex("key", str); } /* Display all key data. */ static void print_keydata(kdbe_key_t *keys, unsigned int len) { unsigned int i; for (i = 0; i < len; i++, keys++) print_key(keys); } /* Display TL item. */ static void print_tl(kdbe_tl_t *tl) { int i, len; printf("\t\t\ttype: 0x%x\n", tl->tl_type); len = tl->tl_data.tl_data_len; printf("\t\t\tvalue(%d): 0x", len); for (i = 0; i < len; i++) printf("%02x", (krb5_octet)tl->tl_data.tl_data_val[i]); printf("\n"); } /* Display TL data items. */ static void print_tldata(kdbe_tl_t *tldata, int len) { int i; printf("\t\t\titems: %d\n", len); for (i = 0; i < len; i++, tldata++) print_tl(tldata); } /* * Print the individual types if verbose mode was specified. * If verbose-verbose then print types along with respective values. */ static void print_attr(kdbe_val_t *val, int vverbose) { switch (val->av_type) { case AT_ATTRFLAGS: printf(_("\t\tAttribute flags\n")); if (vverbose) print_flags(val->kdbe_val_t_u.av_attrflags); break; case AT_MAX_LIFE: printf(_("\t\tMaximum ticket life\n")); if (vverbose) print_deltat(&val->kdbe_val_t_u.av_max_life); break; case AT_MAX_RENEW_LIFE: printf(_("\t\tMaximum renewable life\n")); if (vverbose) print_deltat(&val->kdbe_val_t_u.av_max_renew_life); break; case AT_EXP: printf(_("\t\tPrincipal expiration\n")); if (vverbose) print_time(&val->kdbe_val_t_u.av_exp); break; case AT_PW_EXP: printf(_("\t\tPassword expiration\n")); if (vverbose) print_time(&val->kdbe_val_t_u.av_pw_exp); break; case AT_LAST_SUCCESS: printf(_("\t\tLast successful auth\n")); if (vverbose) print_time(&val->kdbe_val_t_u.av_last_success); break; case AT_LAST_FAILED: printf(_("\t\tLast failed auth\n")); if (vverbose) print_time(&val->kdbe_val_t_u.av_last_failed); break; case AT_FAIL_AUTH_COUNT: printf(_("\t\tFailed passwd attempt\n")); if (vverbose) printf("\t\t\t%d\n", val->kdbe_val_t_u.av_fail_auth_count); break; case AT_PRINC: printf(_("\t\tPrincipal\n")); if (vverbose) print_princ(&val->kdbe_val_t_u.av_princ); break; case AT_KEYDATA: printf(_("\t\tKey data\n")); if (vverbose) { print_keydata(val->kdbe_val_t_u.av_keydata.av_keydata_val, val->kdbe_val_t_u.av_keydata.av_keydata_len); } break; case AT_TL_DATA: printf(_("\t\tTL data\n")); if (vverbose) { print_tldata(val->kdbe_val_t_u.av_tldata.av_tldata_val, val->kdbe_val_t_u.av_tldata.av_tldata_len); } break; case AT_LEN: printf(_("\t\tLength\n")); if (vverbose) printf("\t\t\t%d\n", val->kdbe_val_t_u.av_len); break; case AT_PW_LAST_CHANGE: printf(_("\t\tPassword last changed\n")); if (vverbose) print_time(&val->kdbe_val_t_u.av_pw_last_change); break; case AT_MOD_PRINC: printf(_("\t\tModifying principal\n")); if (vverbose) print_princ(&val->kdbe_val_t_u.av_mod_princ); break; case AT_MOD_TIME: printf(_("\t\tModification time\n")); if (vverbose) print_time(&val->kdbe_val_t_u.av_mod_time); break; case AT_MOD_WHERE: printf(_("\t\tModified where\n")); if (vverbose) print_str("where", &val->kdbe_val_t_u.av_mod_where); break; case AT_PW_POLICY: printf(_("\t\tPassword policy\n")); if (vverbose) print_str("policy", &val->kdbe_val_t_u.av_pw_policy); break; case AT_PW_POLICY_SWITCH: printf(_("\t\tPassword policy switch\n")); if (vverbose) printf("\t\t\t%d\n", val->kdbe_val_t_u.av_pw_policy_switch); break; case AT_PW_HIST_KVNO: printf(_("\t\tPassword history KVNO\n")); if (vverbose) printf("\t\t\t%d\n", val->kdbe_val_t_u.av_pw_hist_kvno); break; case AT_PW_HIST: printf(_("\t\tPassword history\n")); if (vverbose) printf("\t\t\tPW history elided\n"); break; } /* switch */ } /* * Print the update entry information */ static void print_update(kdb_hlog_t *ulog, uint32_t entry, uint32_t ulogentries, unsigned int verbose) { XDR xdrs; uint32_t start_sno, i, j, indx; char *dbprinc; kdb_ent_header_t *indx_log; kdb_incr_update_t upd; if (entry && (entry < ulog->kdb_num)) start_sno = ulog->kdb_last_sno - entry; else start_sno = ulog->kdb_first_sno - 1; for (i = start_sno; i < ulog->kdb_last_sno; i++) { indx = i % ulogentries; indx_log = INDEX(ulog, indx); /* * Check for corrupt update entry */ if (indx_log->kdb_umagic != KDB_ULOG_MAGIC) { fprintf(stderr, _("Corrupt update entry\n\n")); exit(1); } printf("---\n"); printf(_("Update Entry\n")); printf(_("\tUpdate serial # : %u\n"), indx_log->kdb_entry_sno); /* The initial entry after a reset is a dummy entry; skip it. */ if (indx_log->kdb_entry_size == 0) { printf(_("\tDummy entry\n")); continue; } memset(&upd, 0, sizeof(kdb_incr_update_t)); xdrmem_create(&xdrs, (char *)indx_log->entry_data, indx_log->kdb_entry_size, XDR_DECODE); if (!xdr_kdb_incr_update_t(&xdrs, &upd)) { printf(_("Entry data decode failure\n\n")); exit(1); } printf(_("\tUpdate operation : ")); if (upd.kdb_deleted) printf(_("Delete\n")); else printf(_("Add\n")); dbprinc = malloc(upd.kdb_princ_name.utf8str_t_len + 1); if (dbprinc == NULL) { printf(_("Could not allocate principal name\n\n")); exit(1); } strncpy(dbprinc, upd.kdb_princ_name.utf8str_t_val, upd.kdb_princ_name.utf8str_t_len); dbprinc[upd.kdb_princ_name.utf8str_t_len] = 0; printf(_("\tUpdate principal : %s\n"), dbprinc); printf(_("\tUpdate size : %u\n"), indx_log->kdb_entry_size); printf(_("\tUpdate committed : %s\n"), indx_log->kdb_commit ? "True" : "False"); if (indx_log->kdb_time.seconds == 0L) { printf(_("\tUpdate time stamp : None\n")); } else{ printf(_("\tUpdate time stamp : %s"), ctime_uint32(&indx_log->kdb_time.seconds)); } printf(_("\tAttributes changed : %d\n"), upd.kdb_update.kdbe_t_len); if (verbose) { for (j = 0; j < upd.kdb_update.kdbe_t_len; j++) print_attr(&upd.kdb_update.kdbe_t_val[j], verbose > 1 ? 1 : 0); } xdr_free(xdr_kdb_incr_update_t, (char *)&upd); free(dbprinc); } } /* Return a read-only mmap of the ulog, or NULL on failure. Assumes fd is * released on process exit. */ static kdb_hlog_t * map_ulog(const char *filename) { int fd; struct stat st; kdb_hlog_t *ulog; fd = open(filename, O_RDONLY); if (fd == -1) return NULL; if (fstat(fd, &st) < 0) return NULL; ulog = mmap(0, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0); return (ulog == MAP_FAILED) ? NULL : ulog; } int main(int argc, char **argv) { int c; unsigned int verbose = 0; bool_t headeronly = FALSE, reset = FALSE; uint32_t entry = 0; krb5_context context; kadm5_config_params params; kdb_hlog_t *ulog = NULL; setlocale(LC_ALL, ""); progname = argv[0]; while ((c = getopt(argc, argv, "Rvhe:")) != -1) { switch (c) { case 'h': headeronly = TRUE; break; case 'e': entry = atoi(optarg); break; case 'R': reset = TRUE; break; case 'v': verbose++; break; default: usage(); } } if (krb5_init_context(&context)) { fprintf(stderr, _("Unable to initialize Kerberos\n\n")); exit(1); } memset(¶ms, 0, sizeof(params)); if (kadm5_get_config_params(context, 1, ¶ms, ¶ms)) { fprintf(stderr, _("Couldn't read database_name\n\n")); exit(1); } printf(_("\nKerberos update log (%s)\n"), params.iprop_logfile); if (reset) { if (ulog_map(context, params.iprop_logfile, params.iprop_ulogsize)) { fprintf(stderr, _("Unable to map log file %s\n\n"), params.iprop_logfile); exit(1); } if (ulog_init_header(context) != 0) { fprintf(stderr, _("Couldn't reinitialize ulog file %s\n\n"), params.iprop_logfile); exit(1); } printf(_("Reinitialized the ulog.\n")); exit(0); } ulog = map_ulog(params.iprop_logfile); if (ulog == NULL) { fprintf(stderr, _("Unable to map log file %s\n\n"), params.iprop_logfile); exit(1); } if (ulog->kdb_hmagic != KDB_ULOG_HDR_MAGIC) { fprintf(stderr, _("Corrupt header log, exiting\n\n")); exit(1); } printf(_("Update log dump :\n")); printf(_("\tLog version # : %u\n"), ulog->db_version_num); printf(_("\tLog state : ")); switch (ulog->kdb_state) { case KDB_STABLE: printf(_("Stable\n")); break; case KDB_UNSTABLE: printf(_("Unstable\n")); break; case KDB_CORRUPT: printf(_("Corrupt\n")); break; default: printf(_("Unknown state: %d\n"), ulog->kdb_state); break; } printf(_("\tEntry block size : %u\n"), ulog->kdb_block); printf(_("\tNumber of entries : %u\n"), ulog->kdb_num); if (ulog->kdb_last_sno == 0) { printf(_("\tLast serial # : None\n")); } else { if (ulog->kdb_first_sno == 0) { printf(_("\tFirst serial # : None\n")); } else { printf(_("\tFirst serial # : ")); printf("%u\n", ulog->kdb_first_sno); } printf(_("\tLast serial # : ")); printf("%u\n", ulog->kdb_last_sno); } if (ulog->kdb_last_time.seconds == 0L) { printf(_("\tLast time stamp : None\n")); } else { if (ulog->kdb_first_time.seconds == 0L) { printf(_("\tFirst time stamp : None\n")); } else { printf(_("\tFirst time stamp : %s"), ctime_uint32(&ulog->kdb_first_time.seconds)); } printf(_("\tLast time stamp : %s\n"), ctime_uint32(&ulog->kdb_last_time.seconds)); } if (!headeronly && ulog->kdb_num) print_update(ulog, entry, params.iprop_ulogsize, verbose); printf("\n"); kadm5_free_config_params(context, ¶ms); krb5_free_context(context); return 0; } krb5-1.16/src/ccapi/0000755000704600001450000000000013211554426014044 5ustar ghudsonlibuuidkrb5-1.16/src/ccapi/common/0000755000704600001450000000000013211554426015334 5ustar ghudsonlibuuidkrb5-1.16/src/ccapi/common/cci_debugging.c0000644000704600001450000000410113211554426020245 0ustar ghudsonlibuuid/* ccapi/common/cci_debugging.c */ /* * Copyright 2006 Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #include "cci_common.h" #include "cci_os_debugging.h" /* ------------------------------------------------------------------------ */ cc_int32 _cci_check_error (cc_int32 in_error, const char *in_function, const char *in_file, int in_line) { /* Do not log for flow control errors or when there is no error at all */ if (in_error != ccNoError && in_error != ccIteratorEnd) { cci_debug_printf ("%s() got %d at %s: %d", in_function, in_error, in_file, in_line); } return in_error; } /* ------------------------------------------------------------------------ */ void cci_debug_printf (const char *in_format, ...) { va_list args; va_start (args, in_format); cci_os_debug_vprintf (in_format, args); va_end (args); } krb5-1.16/src/ccapi/common/cci_identifier.h0000644000704600001450000000550013211554426020445 0ustar ghudsonlibuuid/* ccapi/common/cci_identifier.h */ /* * Copyright 2006 Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #ifndef CCI_IDENTIFIER_H #define CCI_IDENTIFIER_H #include "cci_types.h" extern const cci_identifier_t cci_identifier_uninitialized; cc_int32 cci_identifier_new_uuid (cci_uuid_string_t *out_uuid_string); cc_int32 cci_identifier_new (cci_identifier_t *out_identifier, cci_uuid_string_t in_server_id); cc_int32 cci_identifier_copy (cci_identifier_t *out_identifier, cci_identifier_t in_handle); cc_int32 cci_identifier_release (cci_identifier_t in_identifier); cc_int32 cci_identifier_compare (cci_identifier_t in_identifier, cci_identifier_t in_compare_to_identifier, cc_uint32 *out_equal); cc_int32 cci_identifier_is_for_server (cci_identifier_t in_identifier, cci_uuid_string_t in_server_id, cc_uint32 *out_is_for_server); cc_int32 cci_identifier_compare_server_id (cci_identifier_t in_identifier, cci_identifier_t in_compare_to_identifier, cc_uint32 *out_equal_server_id); cc_int32 cci_identifier_is_initialized (cci_identifier_t in_identifier, cc_uint32 *out_is_initialized); cc_uint32 cci_identifier_read (cci_identifier_t *out_identifier, k5_ipc_stream io_stream); cc_uint32 cci_identifier_write (cci_identifier_t in_identifier, k5_ipc_stream io_stream); #endif /* CCI_IDENTIFIER_H */ krb5-1.16/src/ccapi/common/cci_os_identifier.h0000644000704600001450000000263113211554426021150 0ustar ghudsonlibuuid/* ccapi/common/cci_os_identifier.h */ /* * Copyright 2006 Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #ifndef CCI_OS_IDENTIFIER_H #define CCI_OS_IDENTIFIER_H #include "cci_types.h" cc_int32 cci_os_identifier_new_uuid (cci_uuid_string_t *out_uuid_string); #endif /* CCI_OS_IDENTIFIER_H */ krb5-1.16/src/ccapi/common/cci_types.h0000644000704600001450000000652713211554426017501 0ustar ghudsonlibuuid/* ccapi/common/cci_types.h */ /* * Copyright 2006 Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #ifndef CCI_TYPES_H #define CCI_TYPES_H #include #include typedef char *cci_uuid_string_t; struct cci_identifier_d; typedef struct cci_identifier_d *cci_identifier_t; enum cci_msg_id_t { /* cc_context_t */ cci_context_first_msg_id, cci_context_unused_release_msg_id, /* Unused. Handle for old clients. */ cci_context_sync_msg_id, cci_context_get_change_time_msg_id, cci_context_wait_for_change_msg_id, cci_context_get_default_ccache_name_msg_id, cci_context_open_ccache_msg_id, cci_context_open_default_ccache_msg_id, cci_context_create_ccache_msg_id, cci_context_create_default_ccache_msg_id, cci_context_create_new_ccache_msg_id, cci_context_new_ccache_iterator_msg_id, cci_context_lock_msg_id, cci_context_unlock_msg_id, cci_context_last_msg_id, /* cc_ccache_t */ cci_ccache_first_msg_id, cci_ccache_destroy_msg_id, cci_ccache_set_default_msg_id, cci_ccache_get_credentials_version_msg_id, cci_ccache_get_name_msg_id, cci_ccache_get_principal_msg_id, cci_ccache_set_principal_msg_id, cci_ccache_store_credentials_msg_id, cci_ccache_remove_credentials_msg_id, cci_ccache_new_credentials_iterator_msg_id, cci_ccache_move_msg_id, cci_ccache_lock_msg_id, cci_ccache_unlock_msg_id, cci_ccache_get_last_default_time_msg_id, cci_ccache_get_change_time_msg_id, cci_ccache_wait_for_change_msg_id, cci_ccache_get_kdc_time_offset_msg_id, cci_ccache_set_kdc_time_offset_msg_id, cci_ccache_clear_kdc_time_offset_msg_id, cci_ccache_last_msg_id, /* cc_ccache_iterator_t */ cci_ccache_iterator_first_msg_id, cci_ccache_iterator_release_msg_id, cci_ccache_iterator_next_msg_id, cci_ccache_iterator_clone_msg_id, cci_ccache_iterator_last_msg_id, /* cc_credentials_iterator_t */ cci_credentials_iterator_first_msg_id, cci_credentials_iterator_release_msg_id, cci_credentials_iterator_next_msg_id, cci_credentials_iterator_clone_msg_id, cci_credentials_iterator_last_msg_id, cci_max_msg_id /* must be last! */ }; #endif /* CCI_TYPES_H */ krb5-1.16/src/ccapi/common/cci_array_internal.c0000644000704600001450000002274713211554426021344 0ustar ghudsonlibuuid/* ccapi/common/cci_array_internal.c */ /* * Copyright 2006, 2007 Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #include "cci_common.h" #include "cci_array_internal.h" #ifdef WIN32 #include "k5-platform.h" #endif /* ------------------------------------------------------------------------ */ struct cci_array_d { cci_array_object_t *objects; cc_uint64 count; cc_uint64 max_count; cci_array_object_release_t object_release; }; struct cci_array_d cci_array_initializer = { NULL, 0, 0, NULL }; #define CCI_ARRAY_COUNT_INCREMENT 16 /* ------------------------------------------------------------------------ */ static cc_int32 cci_array_resize (cci_array_t io_array, cc_uint64 in_new_count) { cc_int32 err = ccNoError; cc_uint64 new_max_count = 0; if (!io_array) { err = cci_check_error (ccErrBadParam); } if (!err) { cc_uint64 old_max_count = io_array->max_count; new_max_count = io_array->max_count; if (in_new_count > old_max_count) { /* Expand the array */ while (in_new_count > new_max_count) { new_max_count += CCI_ARRAY_COUNT_INCREMENT; } } else if ((in_new_count + CCI_ARRAY_COUNT_INCREMENT) < old_max_count) { /* Shrink the array, but never drop below CC_ARRAY_COUNT_INCREMENT */ while ((in_new_count + CCI_ARRAY_COUNT_INCREMENT) < new_max_count && (new_max_count > CCI_ARRAY_COUNT_INCREMENT)) { new_max_count -= CCI_ARRAY_COUNT_INCREMENT; } } } if (!err && io_array->max_count != new_max_count) { cci_array_object_t *objects = io_array->objects; if (!objects) { objects = malloc (new_max_count * sizeof (*objects)); } else { objects = realloc (objects, new_max_count * sizeof (*objects)); } if (!objects) { err = cci_check_error (ccErrNoMem); } if (!err) { io_array->objects = objects; io_array->max_count = new_max_count; } } return cci_check_error (err); } #ifdef TARGET_OS_MAC #pragma mark - #endif /* ------------------------------------------------------------------------ */ cc_int32 cci_array_new (cci_array_t *out_array, cci_array_object_release_t in_array_object_release) { cc_int32 err = ccNoError; cci_array_t array = NULL; if (!out_array) { err = cci_check_error (ccErrBadParam); } if (!err) { array = malloc (sizeof (*array)); if (array) { *array = cci_array_initializer; array->object_release = in_array_object_release; } else { err = cci_check_error (ccErrNoMem); } } if (!err) { *out_array = array; array = NULL; } cci_array_release (array); return cci_check_error (err); } /* ------------------------------------------------------------------------ */ cc_int32 cci_array_release (cci_array_t io_array) { cc_int32 err = ccNoError; if (!err && io_array) { cc_uint64 i; if (io_array->object_release) { for (i = 0; i < io_array->count; i++) { io_array->object_release (io_array->objects[i]); } } free (io_array->objects); free (io_array); } return err; } /* ------------------------------------------------------------------------ */ cc_uint64 cci_array_count (cci_array_t in_array) { return in_array ? in_array->count : 0; } /* ------------------------------------------------------------------------ */ cci_array_object_t cci_array_object_at_index (cci_array_t io_array, cc_uint64 in_position) { if (io_array && in_position < io_array->count) { return io_array->objects[in_position]; } else { if (!io_array) { cci_debug_printf ("%s() got NULL array", __FUNCTION__); } else { cci_debug_printf ("%s() got bad index %lld (count = %lld)", __FUNCTION__, in_position, io_array->count); } return NULL; } } #ifdef TARGET_OS_MAC #pragma mark - #endif /* ------------------------------------------------------------------------ */ cc_int32 cci_array_insert (cci_array_t io_array, cci_array_object_t in_object, cc_uint64 in_position) { cc_int32 err = ccNoError; if (!io_array ) { err = cci_check_error (ccErrBadParam); } if (!in_object) { err = cci_check_error (ccErrBadParam); } if (!err) { /* Don't try to insert past the end and don't overflow the array */ if (in_position > io_array->count || io_array->count == UINT64_MAX) { err = cci_check_error (ccErrBadParam); } } if (!err) { err = cci_array_resize (io_array, io_array->count + 1); } if (!err) { cc_uint64 move_count = io_array->count - in_position; if (move_count > 0) { memmove (&io_array->objects[in_position + 1], &io_array->objects[in_position], move_count * sizeof (*io_array->objects)); } io_array->objects[in_position] = in_object; io_array->count++; } return cci_check_error (err); } /* ------------------------------------------------------------------------ */ cc_int32 cci_array_remove (cci_array_t io_array, cc_uint64 in_position) { cc_int32 err = ccNoError; if (!io_array) { err = cci_check_error (ccErrBadParam); } if (!err && in_position >= io_array->count) { err = cci_check_error (ccErrBadParam); } if (!err) { cc_uint64 move_count = io_array->count - in_position - 1; cci_array_object_t object = io_array->objects[in_position]; if (move_count > 0) { memmove (&io_array->objects[in_position], &io_array->objects[in_position + 1], move_count * sizeof (*io_array->objects)); } io_array->count--; if (io_array->object_release) { io_array->object_release (object); } cci_array_resize (io_array, io_array->count); } return cci_check_error (err); } /* ------------------------------------------------------------------------ */ cc_int32 cci_array_move (cci_array_t io_array, cc_uint64 in_position, cc_uint64 in_new_position, cc_uint64 *out_real_new_position) { cc_int32 err = ccNoError; if (!io_array ) { err = cci_check_error (ccErrBadParam); } if (!out_real_new_position) { err = cci_check_error (ccErrBadParam); } if (!err && in_position >= io_array->count) { err = cci_check_error (ccErrBadParam); } if (!err && in_new_position > io_array->count) { err = cci_check_error (ccErrBadParam); } if (!err) { cc_uint64 move_from = 0; cc_uint64 move_to = 0; cc_uint64 move_count = 0; cc_uint64 real_new_position = 0; if (in_position < in_new_position) { /* shift right, making an empty space so the * actual new position is one less in_new_position */ move_from = in_position + 1; move_to = in_position; move_count = in_new_position - in_position - 1; real_new_position = in_new_position - 1; } else if (in_position > in_new_position) { /* shift left */ move_from = in_new_position; move_to = in_new_position + 1; move_count = in_position - in_new_position; real_new_position = in_new_position; } else { real_new_position = in_new_position; } if (move_count > 0) { cci_array_object_t object = io_array->objects[in_position]; memmove (&io_array->objects[move_to], &io_array->objects[move_from], move_count * sizeof (*io_array->objects)); io_array->objects[real_new_position] = object; } *out_real_new_position = real_new_position; } return cci_check_error (err); } /* ------------------------------------------------------------------------ */ cc_int32 cci_array_push_front (cci_array_t io_array, cc_uint64 in_position) { cc_uint64 real_new_position = 0; return cci_array_move (io_array, in_position, 0, &real_new_position); } krb5-1.16/src/ccapi/common/mac/0000755000704600001450000000000013211554426016074 5ustar ghudsonlibuuidkrb5-1.16/src/ccapi/common/mac/cci_os_debugging.c0000644000704600001450000000273513211554426021521 0ustar ghudsonlibuuid/* ccapi/common/mac/cci_os_debugging.c */ /* * Copyright 2006 Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #include "cci_os_debugging.h" #include /* ------------------------------------------------------------------------ */ void cci_os_debug_vprintf (const char *in_format, va_list in_args) { dvprintf (in_format, in_args); } krb5-1.16/src/ccapi/common/mac/cci_os_identifier.c0000644000704600001450000000542413211554426021706 0ustar ghudsonlibuuid/* ccapi/common/mac/cci_os_identifier.c */ /* * Copyright 2006 Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #include "cci_common.h" #include "cci_os_identifier.h" #include /* ------------------------------------------------------------------------ */ cc_int32 cci_os_identifier_new_uuid (cci_uuid_string_t *out_uuid_string) { cc_int32 err = ccNoError; cci_uuid_string_t uuid_string = NULL; CFUUIDRef uuid = NULL; CFStringRef uuid_stringref = NULL; CFStringEncoding encoding = kCFStringEncodingUTF8; CFIndex length = 0; if (!out_uuid_string) { err = cci_check_error (ccErrBadParam); } if (!err) { uuid = CFUUIDCreate (kCFAllocatorDefault); if (!uuid) { err = cci_check_error (ccErrNoMem); } } if (!err) { uuid_stringref = CFUUIDCreateString (kCFAllocatorDefault, uuid); if (!uuid_stringref) { err = cci_check_error (ccErrNoMem); } } if (!err) { length = CFStringGetMaximumSizeForEncoding (CFStringGetLength (uuid_stringref), encoding) + 1; uuid_string = malloc (length); if (!uuid_string) { err = cci_check_error (ccErrNoMem); } } if (!err) { if (!CFStringGetCString (uuid_stringref, uuid_string, length, encoding)) { err = cci_check_error (ccErrNoMem); } } if (!err) { *out_uuid_string = uuid_string; uuid_string = NULL; /* take ownership */ } if (uuid_string ) { free (uuid_string); } if (uuid_stringref) { CFRelease (uuid_stringref); } if (uuid ) { CFRelease (uuid); } return cci_check_error (err); } krb5-1.16/src/ccapi/common/cci_common.h0000644000704600001450000000346313211554426017621 0ustar ghudsonlibuuid/* ccapi/common/cci_common.h */ /* * Copyright 2006, 2007 Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #ifndef CCI_COMMON_H #define CCI_COMMON_H #include #include #include #include #include #include #include #include #if TARGET_OS_MAC #include #define VECTOR_FUNCTIONS_INITIALIZER ,NULL #else #include "win-mac.h" #define VECTOR_FUNCTIONS_INITIALIZER #endif #define k_cci_context_initial_ccache_name "Initial default ccache" #include "cci_cred_union.h" #include "cci_debugging.h" #include "cci_identifier.h" #include "cci_message.h" #include "k5-ipc_stream.h" #endif /* CCI_COMMON_H */ krb5-1.16/src/ccapi/common/cci_message.c0000644000704600001450000001430613211554426017746 0ustar ghudsonlibuuid/* ccapi/common/cci_message.c */ /* * Copyright 2006 Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #include "cci_common.h" /* ------------------------------------------------------------------------ */ cc_int32 cci_message_invalid_object_err (enum cci_msg_id_t in_request_name) { cc_int32 err = ccNoError; if (in_request_name > cci_context_first_msg_id && in_request_name < cci_context_last_msg_id) { err = ccErrInvalidContext; } else if (in_request_name > cci_ccache_first_msg_id && in_request_name < cci_ccache_last_msg_id) { err = ccErrInvalidCCache; } else if (in_request_name > cci_ccache_iterator_first_msg_id && in_request_name < cci_ccache_iterator_last_msg_id) { err = ccErrInvalidCCacheIterator; } else if (in_request_name > cci_credentials_iterator_first_msg_id && in_request_name < cci_credentials_iterator_last_msg_id) { err = ccErrInvalidCredentialsIterator; } else { err = ccErrBadInternalMessage; } return cci_check_error (err); } /* ------------------------------------------------------------------------ */ cc_int32 cci_message_new_request_header (k5_ipc_stream *out_request, enum cci_msg_id_t in_request_name, cci_identifier_t in_identifier) { cc_int32 err = ccNoError; k5_ipc_stream request = NULL; if (!out_request) { err = cci_check_error (ccErrBadParam); } if (!err) { err = krb5int_ipc_stream_new (&request); } if (!err) { err = krb5int_ipc_stream_write_uint32 (request, in_request_name); } if (!err) { err = cci_identifier_write (in_identifier, request); } if (!err) { *out_request = request; request = NULL; } krb5int_ipc_stream_release (request); return cci_check_error (err); } /* ------------------------------------------------------------------------ */ cc_int32 cci_message_read_request_header (k5_ipc_stream in_request, enum cci_msg_id_t *out_request_name, cci_identifier_t *out_identifier) { cc_int32 err = ccNoError; cc_uint32 request_name; cci_identifier_t identifier = NULL; if (!in_request ) { err = cci_check_error (ccErrBadParam); } if (!out_request_name) { err = cci_check_error (ccErrBadParam); } if (!out_identifier ) { err = cci_check_error (ccErrBadParam); } if (!err) { err = krb5int_ipc_stream_read_uint32 (in_request, &request_name); } if (!err) { err = cci_identifier_read (&identifier, in_request); } if (!err) { *out_request_name = request_name; *out_identifier = identifier; identifier = NULL; /* take ownership */ } cci_identifier_release (identifier); return cci_check_error (err); } /* ------------------------------------------------------------------------ */ cc_int32 cci_message_new_reply_header (k5_ipc_stream *out_reply, cc_int32 in_error) { cc_int32 err = ccNoError; k5_ipc_stream reply = NULL; if (!out_reply) { err = cci_check_error (ccErrBadParam); } if (!err) { err = krb5int_ipc_stream_new (&reply); } if (!err) { err = krb5int_ipc_stream_write_int32 (reply, in_error); } if (!err) { *out_reply = reply; reply = NULL; } krb5int_ipc_stream_release (reply); return cci_check_error (err); } /* ------------------------------------------------------------------------ */ cc_int32 cci_message_read_reply_header (k5_ipc_stream in_reply, cc_int32 *out_reply_error) { cc_int32 err = ccNoError; cc_int32 reply_err = 0; if (!in_reply ) { err = cci_check_error (ccErrBadParam); } if (!out_reply_error) { err = cci_check_error (ccErrBadParam); } if (!err) { err = krb5int_ipc_stream_read_int32 (in_reply, &reply_err); } if (!err) { *out_reply_error = reply_err; } return cci_check_error (err); } #ifdef TARGET_OS_MAC #pragma mark - #endif /* ------------------------------------------------------------------------ */ uint32_t krb5int_ipc_stream_read_time (k5_ipc_stream io_stream, cc_time_t *out_time) { int32_t err = 0; int64_t t = 0; if (!io_stream) { err = cci_check_error (ccErrBadParam); } if (!out_time ) { err = cci_check_error (ccErrBadParam); } if (!err) { err = krb5int_ipc_stream_read_int64 (io_stream, &t); } if (!err) { *out_time = t; } return cci_check_error (err); } /* ------------------------------------------------------------------------ */ uint32_t krb5int_ipc_stream_write_time (k5_ipc_stream io_stream, cc_time_t in_time) { int32_t err = 0; if (!io_stream) { err = cci_check_error (ccErrBadParam); } if (!err) { err = krb5int_ipc_stream_write_int64 (io_stream, in_time); } return cci_check_error (err); } krb5-1.16/src/ccapi/common/cci_array_internal.h0000644000704600001450000000501113211554426021332 0ustar ghudsonlibuuid/* ccapi/common/cci_array_internal.h */ /* * Copyright 2006 Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #ifndef CCI_ARRAY_INTERNAL_H #define CCI_ARRAY_INTERNAL_H #include "cci_types.h" struct cci_array_object_d; typedef struct cci_array_object_d *cci_array_object_t; typedef cc_int32 (*cci_array_object_release_t) (cci_array_object_t); struct cci_array_d; typedef struct cci_array_d *cci_array_t; cc_int32 cci_array_new (cci_array_t *out_array, cci_array_object_release_t in_array_object_release); cc_int32 cci_array_release (cci_array_t io_array); cc_uint64 cci_array_count (cci_array_t in_array); cci_array_object_t cci_array_object_at_index (cci_array_t io_array, cc_uint64 in_position); cc_int32 cci_array_insert (cci_array_t io_array, cci_array_object_t in_object, cc_uint64 in_position); cc_int32 cci_array_remove (cci_array_t io_array, cc_uint64 in_position); cc_int32 cci_array_move (cci_array_t io_array, cc_uint64 in_position, cc_uint64 in_new_position, cc_uint64 *out_real_new_position); cc_int32 cci_array_push_front (cci_array_t io_array, cc_uint64 in_position); #endif /* CCI_ARRAY_INTERNAL_H */ krb5-1.16/src/ccapi/common/cci_os_debugging.h0000644000704600001450000000264313211554426020764 0ustar ghudsonlibuuid/* ccapi/common/cci_os_debugging.h */ /* * Copyright 2006 Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #ifndef CCI_OS_DEBUGGING_H #define CCI_OS_DEBUGGING_H #include "cci_types.h" #include void cci_os_debug_vprintf (const char *in_format, va_list in_args); #endif /* CCI_OS_DEBUGGING_H */ krb5-1.16/src/ccapi/common/cci_message.h0000644000704600001450000000444513211554426017756 0ustar ghudsonlibuuid/* ccapi/common/cci_message.h */ /* * Copyright 2006 Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #ifndef CCI_MESSAGE_H #define CCI_MESSAGE_H #include "cci_types.h" cc_int32 cci_message_invalid_object_err (enum cci_msg_id_t in_request_name); cc_int32 cci_message_new_request_header (k5_ipc_stream *out_request, enum cci_msg_id_t in_request_name, cci_identifier_t in_identifier); cc_int32 cci_message_read_request_header (k5_ipc_stream in_request, enum cci_msg_id_t *out_request_name, cci_identifier_t *out_identifier); cc_int32 cci_message_new_reply_header (k5_ipc_stream *out_reply, cc_int32 in_error); cc_int32 cci_message_read_reply_header (k5_ipc_stream in_reply, cc_int32 *out_reply_error); uint32_t krb5int_ipc_stream_read_time (k5_ipc_stream io_stream, cc_time_t *out_time); uint32_t krb5int_ipc_stream_write_time (k5_ipc_stream io_stream, cc_time_t in_time); #endif /* CCI_MESSAGE_H */ krb5-1.16/src/ccapi/common/cci_debugging.h0000644000704600001450000000340013211554426020253 0ustar ghudsonlibuuid/* ccapi/common/cci_debugging.h */ /* * Copyright 2006 Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #ifndef CCI_DEBUGGING_H #define CCI_DEBUGGING_H #include "cci_types.h" cc_int32 _cci_check_error (cc_int32 in_err, const char *in_function, const char *in_file, int in_line); #define cci_check_error(err) _cci_check_error(err, __FUNCTION__, __FILE__, __LINE__) void cci_debug_printf (const char *in_format, ...) #if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 7) __attribute__ ((__format__ (__printf__, 1, 2))) #endif ; #endif /* CCI_DEBUGGING_H */ krb5-1.16/src/ccapi/common/cci_identifier.c0000644000704600001450000002274513211554426020452 0ustar ghudsonlibuuid/* ccapi/common/cci_identifier.c */ /* * Copyright 2006, 2007 Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #include "cci_common.h" #include "cci_os_identifier.h" struct cci_identifier_d { cci_uuid_string_t server_id; cci_uuid_string_t object_id; }; struct cci_identifier_d cci_identifier_initializer = { NULL, NULL }; #define cci_uninitialized_server_id "NEEDS_SYNC" #define cci_uninitialized_object_id "NEEDS_SYNC" struct cci_identifier_d cci_identifier_uninitialized_d = { cci_uninitialized_server_id, cci_uninitialized_object_id }; const cci_identifier_t cci_identifier_uninitialized = &cci_identifier_uninitialized_d; /* ------------------------------------------------------------------------ */ cc_int32 cci_identifier_new_uuid (cci_uuid_string_t *out_uuid_string) { return cci_os_identifier_new_uuid (out_uuid_string); } /* ------------------------------------------------------------------------ */ static cc_int32 cci_identifier_alloc (cci_identifier_t *out_identifier, cci_uuid_string_t in_server_id, cci_uuid_string_t in_object_id) { cc_int32 err = ccNoError; cci_identifier_t identifier = NULL; if (!out_identifier) { err = cci_check_error (ccErrBadParam); } if (!in_server_id ) { err = cci_check_error (ccErrBadParam); } if (!in_object_id ) { err = cci_check_error (ccErrBadParam); } if (!err) { identifier = malloc (sizeof (*identifier)); if (identifier) { *identifier = cci_identifier_initializer; } else { err = cci_check_error (ccErrNoMem); } } if (!err) { identifier->server_id = strdup (in_server_id); if (!identifier->server_id) { err = cci_check_error (ccErrNoMem); } } if (!err) { identifier->object_id = strdup (in_object_id); if (!identifier->object_id) { err = cci_check_error (ccErrNoMem); } } if (!err) { *out_identifier = identifier; identifier = NULL; /* take ownership */ } cci_identifier_release (identifier); return cci_check_error (err); } /* ------------------------------------------------------------------------ */ cc_int32 cci_identifier_new (cci_identifier_t *out_identifier, cci_uuid_string_t in_server_id) { cc_int32 err = ccNoError; cci_uuid_string_t object_id = NULL; if (!out_identifier) { err = cci_check_error (ccErrBadParam); } if (!in_server_id ) { err = cci_check_error (ccErrBadParam); } if (!err) { err = cci_os_identifier_new_uuid (&object_id); } if (!err) { err = cci_identifier_alloc (out_identifier, in_server_id, object_id); } if (object_id) { free (object_id); } return cci_check_error (err); } /* ------------------------------------------------------------------------ */ cc_int32 cci_identifier_copy (cci_identifier_t *out_identifier, cci_identifier_t in_identifier) { cc_int32 err = ccNoError; if (!out_identifier) { err = cci_check_error (ccErrBadParam); } if (!in_identifier ) { err = cci_check_error (ccErrBadParam); } if (!err) { err = cci_identifier_alloc (out_identifier, in_identifier->server_id, in_identifier->object_id); } return cci_check_error (err); } /* ------------------------------------------------------------------------ */ cc_int32 cci_identifier_release (cci_identifier_t in_identifier) { cc_int32 err = ccNoError; /* Do not free the static "uninitialized" identifier */ if (!err && in_identifier && in_identifier != cci_identifier_uninitialized) { free (in_identifier->server_id); free (in_identifier->object_id); free (in_identifier); } return cci_check_error (err); } #ifdef TARGET_OS_MAC #pragma mark - #endif /* ------------------------------------------------------------------------ */ cc_int32 cci_identifier_compare (cci_identifier_t in_identifier, cci_identifier_t in_compare_to_identifier, cc_uint32 *out_equal) { cc_int32 err = ccNoError; if (!in_identifier ) { err = cci_check_error (ccErrBadParam); } if (!in_compare_to_identifier) { err = cci_check_error (ccErrBadParam); } if (!out_equal ) { err = cci_check_error (ccErrBadParam); } if (!err) { *out_equal = (!strcmp (in_identifier->object_id, in_compare_to_identifier->object_id) && !strcmp (in_identifier->server_id, in_compare_to_identifier->server_id)); } return cci_check_error (err); } /* ------------------------------------------------------------------------ */ cc_int32 cci_identifier_is_for_server (cci_identifier_t in_identifier, cci_uuid_string_t in_server_id, cc_uint32 *out_is_for_server) { cc_int32 err = ccNoError; if (!in_identifier ) { err = cci_check_error (ccErrBadParam); } if (!in_server_id ) { err = cci_check_error (ccErrBadParam); } if (!out_is_for_server) { err = cci_check_error (ccErrBadParam); } if (!err) { *out_is_for_server = (!strcmp (in_identifier->server_id, in_server_id) || !strcmp (in_identifier->server_id, cci_uninitialized_server_id)); } return cci_check_error (err); } /* ------------------------------------------------------------------------ */ cc_int32 cci_identifier_compare_server_id (cci_identifier_t in_identifier, cci_identifier_t in_compare_to_identifier, cc_uint32 *out_equal_server_id) { cc_int32 err = ccNoError; if (!in_identifier ) { err = cci_check_error (ccErrBadParam); } if (!in_compare_to_identifier) { err = cci_check_error (ccErrBadParam); } if (!out_equal_server_id ) { err = cci_check_error (ccErrBadParam); } if (!err) { *out_equal_server_id = (!strcmp (in_identifier->server_id, in_compare_to_identifier->server_id)); } return cci_check_error (err); } /* ------------------------------------------------------------------------ */ cc_int32 cci_identifier_is_initialized (cci_identifier_t in_identifier, cc_uint32 *out_is_initialized) { cc_int32 err = ccNoError; if (!in_identifier ) { err = cci_check_error (ccErrBadParam); } if (!out_is_initialized) { err = cci_check_error (ccErrBadParam); } if (!err) { *out_is_initialized = (strcmp (in_identifier->server_id, cci_uninitialized_server_id) != 0); } return cci_check_error (err); } #ifdef TARGET_OS_MAC #pragma mark - #endif /* ------------------------------------------------------------------------ */ cc_uint32 cci_identifier_read (cci_identifier_t *out_identifier, k5_ipc_stream io_stream) { cc_int32 err = ccNoError; cci_uuid_string_t server_id = NULL; cci_uuid_string_t object_id = NULL; if (!out_identifier) { err = cci_check_error (ccErrBadParam); } if (!io_stream ) { err = cci_check_error (ccErrBadParam); } if (!err) { err = krb5int_ipc_stream_read_string (io_stream, &server_id); } if (!err) { err = krb5int_ipc_stream_read_string (io_stream, &object_id); } if (!err) { err = cci_identifier_alloc (out_identifier, server_id, object_id); } krb5int_ipc_stream_free_string (server_id); krb5int_ipc_stream_free_string (object_id); return cci_check_error (err); } /* ------------------------------------------------------------------------ */ cc_uint32 cci_identifier_write (cci_identifier_t in_identifier, k5_ipc_stream io_stream) { cc_int32 err = ccNoError; if (!in_identifier) { err = cci_check_error (ccErrBadParam); } if (!io_stream ) { err = cci_check_error (ccErrBadParam); } if (!err) { err = krb5int_ipc_stream_write_string (io_stream, in_identifier->server_id); } if (!err) { err = krb5int_ipc_stream_write_string (io_stream, in_identifier->object_id); } return cci_check_error (err); } krb5-1.16/src/ccapi/common/cci_cred_union.h0000644000704600001450000000474013211554426020455 0ustar ghudsonlibuuid/* ccapi/common/cci_cred_union.h */ /* * Copyright 2006 Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #ifndef CCI_CRED_UNION_H #define CCI_CRED_UNION_H #include "cci_types.h" #include cc_uint32 cci_credentials_union_release (cc_credentials_union *io_credentials); cc_uint32 cci_credentials_union_read (cc_credentials_union **out_credentials_union, k5_ipc_stream io_stream); cc_uint32 cci_credentials_union_write (const cc_credentials_union *in_credentials_union, k5_ipc_stream io_stream); cc_uint32 cci_cred_union_release (cred_union *io_cred_union); cc_uint32 cci_credentials_union_to_cred_union (const cc_credentials_union *in_credentials_union, cred_union **out_cred_union); cc_uint32 cci_cred_union_to_credentials_union (const cred_union *in_cred_union, cc_credentials_union **out_credentials_union); cc_uint32 cci_cred_union_compare_to_credentials_union (const cred_union *in_cred_union_compat, const cc_credentials_union *in_credentials_union, cc_uint32 *out_equal); #endif /* CCI_CRED_UNION_H */ krb5-1.16/src/ccapi/common/win/0000755000704600001450000000000013211554426016131 5ustar ghudsonlibuuidkrb5-1.16/src/ccapi/common/win/ccs_request.idl0000644000704600001450000000463313211554426021151 0ustar ghudsonlibuuid/* * $Header$ * * Copyright 2008 Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ [ uuid (906B0CE0-C70B-1067-B317-00DD010662DA), version(1.0), pointer_default(unique) ] interface ccs_request { typedef char CC_CHAR; typedef unsigned char CC_UCHAR; typedef int CC_INT32; typedef unsigned int CC_UINT32; const long HSIZE = 8; void ccs_rpc_request( [in] const long rpcmsg, /* Message type */ [in, size_is(HSIZE)] const char tsphandle[], [in, string] const char* pszUUID, /* Requestor's UUID */ [in] const long lenRequest, /* Length of buffer */ [in, size_is(lenRequest)] const char* pszRequest, /* Data buffer */ [in] const long serverStartTime,/* Which server session we're talking to */ [out] long* status ); /* Return code */ void ccs_rpc_connect( [in] const long rpcmsg, /* Message type */ [in, size_is(HSIZE)] const char tsphandle[], [in, string] const char* pszUUID, /* Requestor's UUID */ [out] long* status ); /* Return code */ CC_UINT32 ccs_authenticate( [in, string] const CC_CHAR* name ); } krb5-1.16/src/ccapi/common/win/cci_os_debugging.c0000644000704600001450000000314413211554426021551 0ustar ghudsonlibuuid/* ccapi/common/win/cci_os_debugging.c */ /* * Copyright 2008 Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #include #include #include "cci_os_debugging.h" #include "win-utils.h" /* ------------------------------------------------------------------------ */ void cci_os_debug_vprintf (const char *in_format, va_list in_args) { #ifdef DEBUG printf ( "%s %ld ", timestamp(), GetCurrentThreadId() ); vprintf ( in_format, in_args ); printf ( "\n" ); #endif } krb5-1.16/src/ccapi/common/win/cci_os_identifier.c0000644000704600001450000000376713211554426021753 0ustar ghudsonlibuuid/* ccapi/common/win/cci_os_identifier.c */ /* * Copyright 2008 Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #include "cci_common.h" #include "cci_os_identifier.h" #include /* ------------------------------------------------------------------------ */ cc_int32 cci_os_identifier_new_uuid (cci_uuid_string_t *out_uuid_string) { cc_int32 err = ccNoError; UUID uuid; char* uuidStringTemp; err = UuidCreate(&uuid); if (!err) { err = UuidToString(&uuid, &uuidStringTemp); } if (!err) { *out_uuid_string = malloc(1+strlen(uuidStringTemp)); if (*out_uuid_string) { strcpy(*out_uuid_string, uuidStringTemp); } RpcStringFree(&uuidStringTemp); } cci_debug_printf("cci_os_identifier_new_uuid returning %s", *out_uuid_string); return cci_check_error (err); }krb5-1.16/src/ccapi/common/win/ccs_request.Acf0000644000704600001450000000242013211554426021062 0ustar ghudsonlibuuid/* * $Header$ * * Copyright 2008 Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ [implicit_handle(handle_t ccs_request_IfHandle)] interface ccs_request { } krb5-1.16/src/ccapi/common/win/OldCC/0000755000704600001450000000000013211554426017055 5ustar ghudsonlibuuidkrb5-1.16/src/ccapi/common/win/OldCC/ccutil.def0000644000704600001450000000005613211554426021021 0ustar ghudsonlibuuid;LIBRARY COMERR32 HEAPSIZE 8192 EXPORTS krb5-1.16/src/ccapi/common/win/OldCC/util.cxx0000644000704600001450000003360413211554426020564 0ustar ghudsonlibuuid/* * $Header$ * * Copyright 2008 Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #include #include // for _snprintf #include #include extern "C" { #include "cci_debugging.h" #include "ccutils.h" } #include "util.h" #include "secure.hxx" void* malloc_alloc_p(size_t size) { return malloc(size); } void free_alloc_p(void *pptr) { void **real_pptr = (void**)pptr; if (*real_pptr) { free(*real_pptr); *real_pptr = 0; } } extern "C" DWORD alloc_textual_sid( PSID pSid, // binary Sid LPSTR *pTextualSid // buffer for Textual representaion of Sid ) { PSID_IDENTIFIER_AUTHORITY psia; DWORD dwSubAuthorities; DWORD dwSidRev = SID_REVISION; DWORD dwCounter; DWORD dwSidSize; *pTextualSid = 0; // // test if Sid passed in is valid // if(!IsValidSid(pSid)) return ERROR_INVALID_PARAMETER; // obtain SidIdentifierAuthority psia = GetSidIdentifierAuthority(pSid); // obtain sidsubauthority count dwSubAuthorities =* GetSidSubAuthorityCount(pSid); // // compute buffer length // S-SID_REVISION- + identifierauthority- + subauthorities- + NULL // dwSidSize = (15 + 12 + (12 * dwSubAuthorities) + 1) * sizeof(TCHAR); *pTextualSid = (LPSTR)malloc_alloc_p(dwSidSize); if (!*pTextualSid) return GetLastError(); LPSTR TextualSid = *pTextualSid; // // prepare S-SID_REVISION- // wsprintf(TextualSid, TEXT("S-%lu-"), dwSidRev ); // // prepare SidIdentifierAuthority // if ( (psia->Value[0] != 0) || (psia->Value[1] != 0) ) { wsprintf(TextualSid + lstrlen(TextualSid), TEXT("0x%02hx%02hx%02hx%02hx%02hx%02hx"), (USHORT)psia->Value[0], (USHORT)psia->Value[1], (USHORT)psia->Value[2], (USHORT)psia->Value[3], (USHORT)psia->Value[4], (USHORT)psia->Value[5]); } else { wsprintf(TextualSid + lstrlen(TextualSid), TEXT("%lu"), (ULONG)(psia->Value[5] ) + (ULONG)(psia->Value[4] << 8) + (ULONG)(psia->Value[3] << 16) + (ULONG)(psia->Value[2] << 24) ); } // // loop through SidSubAuthorities // for (dwCounter=0 ; dwCounter < dwSubAuthorities ; dwCounter++) { wsprintf(TextualSid + lstrlen(TextualSid), TEXT("-%lu"), *GetSidSubAuthority(pSid, dwCounter) ); } return 0; } DWORD alloc_token_user(HANDLE hToken, PTOKEN_USER *pptu) { DWORD status = 0; DWORD size = 0; *pptu = 0; GetTokenInformation(hToken, TokenUser, *pptu, 0, &size); if (size == 0) status = GetLastError(); if (!status) { if (!(*pptu = (PTOKEN_USER)malloc_alloc_p(size))) status = GetLastError(); } if (!status) { if (!GetTokenInformation(hToken, TokenUser, *pptu, size, &size)) status = GetLastError(); } if (status && *pptu) { free_alloc_p(pptu); } return status; } DWORD alloc_username( PSID Sid, LPSTR* pname, LPSTR* pdomain = 0 ) { DWORD status = 0; DWORD name_len = 0; DWORD domain_len = 0; SID_NAME_USE snu; LPSTR name = 0; LPSTR domain = 0; *pname = 0; if (pdomain) *pdomain = 0; LookupAccountSidA(NULL, Sid, 0, &name_len, 0, &domain_len, &snu); if ((name_len == 0) || (domain_len == 0)) status = GetLastError(); if (!status) { if (!(name = (LPSTR)malloc_alloc_p(name_len))) status = GetLastError(); } if (!status) { if (!(domain = (LPSTR)malloc_alloc_p(domain_len))) status = GetLastError(); } if (!status) { if (!LookupAccountSidA(NULL, Sid, name, &name_len, domain, &domain_len, &snu)) status = GetLastError(); } if (status) { if (name) free_alloc_p(&name); if (domain) free_alloc_p(&domain); } else { if (pdomain) { *pname = name; *pdomain = domain; } else { DWORD size = name_len + domain_len + 1; *pname = (LPSTR)malloc_alloc_p(size); if (!*pname) status = GetLastError(); else _snprintf(*pname, size, "%s\\%s", name, domain); } } return status; } DWORD get_authentication_id(HANDLE hToken, LUID* pAuthId) { TOKEN_STATISTICS ts; DWORD len; if (!GetTokenInformation(hToken, TokenStatistics, &ts, sizeof(ts), &len)) return GetLastError(); *pAuthId = ts.AuthenticationId; return 0; } DWORD alloc_name_9x( LPSTR* pname, LPSTR postfix ) { char prefix[] = "krbcc"; DWORD len = (sizeof(prefix) - 1) + 1 + strlen(postfix) + 1; *pname = (LPSTR)malloc_alloc_p(len); if (!*pname) return GetLastError(); _snprintf(*pname, len, "%s.%s", prefix, postfix); return 0; } DWORD alloc_name_NT(LPSTR* pname, LPSTR postfix) { DWORD status = 0; HANDLE hToken = 0; LUID auth_id; #ifdef _DEBUG PTOKEN_USER ptu = 0; LPSTR name = 0; LPSTR domain = 0; LPSTR sid = 0; #endif char prefix[] = "krbcc"; // Play it safe and say 3 characters are needed per 8 bits (byte). // Note that 20 characters are needed for a 64-bit number in // decimal (plus one for the string termination. // and include room for sessionId. char lid[3*sizeof(LUID)+1+5]; DWORD sessionId; DWORD len = 0; *pname = 0; status = SecureClient::Token(hToken); if (!status) { status = get_authentication_id(hToken, &auth_id); } if (!status) { if (!ProcessIdToSessionId(GetCurrentProcessId(), &sessionId)) sessionId = 0; } #ifdef _DEBUG if (!status) {status = alloc_token_user(hToken, &ptu);} if (!status) {status = alloc_username(ptu->User.Sid, &name, &domain);} if (!status) {status = alloc_textual_sid(ptu->User.Sid, &sid);} #endif if (!status) { _snprintf(lid, sizeof(lid), "%I64u.%u", auth_id, sessionId); lid[sizeof(lid)-1] = 0; // be safe len = (sizeof(prefix) - 1) + 1 + strlen(lid) + 1 + strlen(postfix) + 1; *pname = (LPSTR)malloc_alloc_p(len); if (!*pname) status = GetLastError(); } // // We used to allocate a name of the form: // "prefix.domain.name.sid.lid.postfix" (usually under 80 // characters, depending on username). However, XP thought this // was "invalid" (too long?) for some reason. // // Therefore, we now use "prefix.lid.postfix" // and for Terminal server we use "prefix.lid.sessionId.postfix" // if (!status) { _snprintf(*pname, len, "%s.%s.%s", prefix, lid, postfix); } #ifdef _DEBUG if (sid) free_alloc_p(&sid); if (name) free_alloc_p(&name); if (domain) free_alloc_p(&domain); if (ptu) free_alloc_p(&ptu); #endif if (hToken && hToken != INVALID_HANDLE_VALUE) CloseHandle(hToken); if (status && *pname) free_alloc_p(pname); return status; } extern "C" DWORD alloc_name(LPSTR* pname, LPSTR postfix, BOOL isNT) { return isNT ? alloc_name_NT(pname, postfix) : alloc_name_9x(pname, postfix); } extern "C" DWORD alloc_own_security_descriptor_NT(PSECURITY_DESCRIPTOR* ppsd) { DWORD status = 0; HANDLE hToken = 0; PTOKEN_USER ptu = 0; PSID pSid = 0; PACL pAcl = 0; DWORD size = 0; SECURITY_DESCRIPTOR sd; *ppsd = 0; if (!status) {status = SecureClient::Token(hToken);} // Get SID: if (!status) {status = alloc_token_user(hToken, &ptu);} if (!status) { size = GetLengthSid(ptu->User.Sid); pSid = (PSID) malloc_alloc_p(size); if (!pSid) status = GetLastError(); } if (!status) { if (!CopySid(size, pSid, ptu->User.Sid)) status = GetLastError(); } if (!status) { // Prepare ACL: size = sizeof(ACL); // Add an ACE: size += sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD) + GetLengthSid(pSid); pAcl = (PACL) malloc_alloc_p(size); if (!pAcl) status = GetLastError(); } if (!status) { if (!InitializeAcl(pAcl, size, ACL_REVISION)) status = GetLastError(); } if (!status) { if (!AddAccessAllowedAce(pAcl, ACL_REVISION, GENERIC_ALL, pSid)) status = GetLastError(); } if (!status) { // Prepare SD itself: if (!InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION)) status = GetLastError(); } if (!status) { if (!SetSecurityDescriptorDacl(&sd, TRUE, pAcl, FALSE)) status = GetLastError(); } if (!status) { if (!SetSecurityDescriptorOwner(&sd, pSid, FALSE)) status = GetLastError(); } if (!status) { if (!IsValidSecurityDescriptor(&sd)) status = ERROR_INVALID_PARAMETER; } if (!status) { // We now have a SD. Let's copy it. { // This should not succeed. Instead it should give us the size. BOOL ok = MakeSelfRelativeSD(&sd, 0, &size); } if (size == 0) status = GetLastError(); } if (!status) { *ppsd = (PSECURITY_DESCRIPTOR) malloc_alloc_p(size); if (!*ppsd) status = GetLastError(); } if (!status) { if (!MakeSelfRelativeSD(&sd, *ppsd, &size)) status = GetLastError(); } if (ptu) free_alloc_p(&ptu); if (pSid) free_alloc_p(&pSid); if (pAcl) free_alloc_p(&pAcl); if (hToken && hToken != INVALID_HANDLE_VALUE) CloseHandle(hToken); if (status && *ppsd) free_alloc_p(ppsd); return status; } DWORD alloc_module_file_name( char* module, char** pname ) { const DWORD max = 8192; DWORD status = 0; DWORD got = 0; DWORD size = 512; // use low number to test... HMODULE h = 0; BOOL ok = FALSE; char* name = 0; if (!pname) return ERROR_INVALID_PARAMETER; *pname = 0; h = GetModuleHandle(module); if (!h) return GetLastError(); // We assume size < max and size > 0 while (!status && !ok) { if (size > max) { // XXX - Assert? status = ERROR_INVALID_DATA; continue; } if (name) free_alloc_p(&name); name = (char*)malloc_alloc_p(size + 1); if (!name) { status = ERROR_NOT_ENOUGH_MEMORY; continue; } name[size] = 0; got = GetModuleFileName(h, name, size); if (!got) { status = GetLastError(); // sanity check: if (!status) { // XXX - print nasty message...assert? status = ERROR_INVALID_DATA; } continue; } // To know we're ok, we need to verify that what we got // was bigger than GetModuleSize thought it got. ok = got && (got < size) && !name[got]; size *= 2; } if (status && name) free_alloc_p(&name); else *pname = name; return status; } DWORD alloc_module_dir_name( char* module, char** pname ) { DWORD status = alloc_module_file_name(module, pname); if (!status) { char* name = *pname; char* p = name + strlen(name); while ((p >= name) && (*p != '\\') && (*p != '/')) p--; if (p < name) { free_alloc_p(pname); status = ERROR_INVALID_DATA; } else { *p = 0; } } return status; } DWORD alloc_module_dir_name_with_file( char* module, char* file, char** pname ) { DWORD status = alloc_module_dir_name(module, pname); if (!status) { char* name = *pname; size_t name_size = strlen(name); size_t size = name_size + 1 + strlen(file) + 1; char* result = (char*)malloc_alloc_p(size); if (!result) { status = ERROR_NOT_ENOUGH_MEMORY; free_alloc_p(pname); } else { strcpy(result, name); result[name_size] = '\\'; strcpy(result + name_size + 1, file); free_alloc_p(pname); *pname = result; } } return status; } DWORD alloc_cmdline_2_args(char* prog, char* arg1, char* arg2, char** pname) { DWORD status = 0; size_t size = strlen(prog) + strlen(arg1) + strlen(arg2) + 4; char* result = (char*)malloc_alloc_p(size); if (!result) { status = ERROR_NOT_ENOUGH_MEMORY; } else { strcpy(result, prog); strcat(result, " "); strcat(result, arg1); strcat(result, " "); strcat(result, arg2); *pname = result; } cci_debug_printf("%s made <%s>", __FUNCTION__, result); return status; } krb5-1.16/src/ccapi/common/win/OldCC/secure.hxx0000644000704600001450000000351613211554426021101 0ustar ghudsonlibuuid/* * $Header$ * * Copyright 2008 Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #pragma once #include #include "autolock.hxx" class SecureClient { public: static DWORD Attach(); static DWORD Detach(); static DWORD Token(HANDLE& hToken); static void Start(SecureClient*& s); static void Stop(SecureClient*& s); #if 0 static DWORD CheckImpersonation(); static bool IsImp(); static DWORD DuplicateImpAsPrimary(HANDLE& hPrimary); #endif SecureClient(); ~SecureClient(); DWORD Error(); private: static CcOsLock s_lock; static DWORD s_refcount; static DWORD s_error; static HANDLE s_hToken; DWORD m_Error; HANDLE m_hToken; bool m_NeedRestore; }; krb5-1.16/src/ccapi/common/win/OldCC/opts.cxx0000644000704600001450000001060513211554426020570 0ustar ghudsonlibuuid/* * $Header$ * * Copyright 2008 Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #include #include #include #include #if 0 const struct Opts* GetOpts( ) { bool done = false; struct Opts* o; if (!(o = new Opts)) goto cleanup; if (!(o->pszString = new char[lstrlenA(opts.pszString) + 1])) goto cleanup; if (!(o->pszEndpoint = new char[lstrlenA(opts.pszEndpoint) + 1])) goto cleanup; strcpy(o->pszString, opts.pszString); strcpy(o->pszEndpoint, opts.pszEndpoint); done = true; cleanup: if (!done) { FreeOpts(o); o = 0; } return o; } void FreeOpts( struct Opts* o ) { if (o) { if (o->pszString) delete [] o->pszString; if (o->pszEndpoint) delete [] o->pszEndpoint; delete o; } } #endif bool ParseOpts::IsValidOpt( char ch ) { return (m_ValidOpts[ch % 256] != 0); } void ParseOpts::PrintOpt( char ch, char* text ) { if (IsValidOpt(ch)) fprintf(stderr, " -%c %s\n", ch, text); } void ParseOpts::UsageOpts( char * program, int code ) { fprintf(stderr, "Usage: %s [options]\n", program); PrintOpt('k', "stop server"); #ifdef CCAPI_TEST_OPTIONS PrintOpt('s', "string"); PrintOpt('e', "endpoint"); PrintOpt('m', "maxcalls"); PrintOpt('n', "mincalls"); PrintOpt('f', "flag_wait_op"); PrintOpt('u', "unprotected"); PrintOpt('b', "use security callback"); #endif PrintOpt('c', "output debug info to console"); exit(code); } void ParseOpts::SetValidOpts( char* valid_opts ) { memset(m_ValidOpts, 0, sizeof(m_ValidOpts)); char *p = valid_opts; for (p = valid_opts; *p; p++) { m_ValidOpts[*p % sizeof(m_ValidOpts)] = 1; } } void ParseOpts::Parse( Opts& opts, int argc, char **argv ) { int i; for (i = 1; i < argc; i++) { if ((*argv[i] == '-') || (*argv[i] == '/')) { char ch = tolower(*(argv[i]+1)); if (!IsValidOpt(ch)) UsageOpts(argv[0]); switch (ch) { case 'k': opts.bShutdown = TRUE; break; #ifdef CCAPI_TEST_OPTIONS case 's': opts.pszString = argv[++i]; break; case 'e': opts.pszEndpoint = argv[++i]; break; case 'm': opts.cMaxCalls = (unsigned int) atoi(argv[++i]); break; case 'n': opts.cMinCalls = (unsigned int) atoi(argv[++i]); break; case 'f': opts.fDontWait = (unsigned int) atoi(argv[++i]); break; case 'u': opts.bDontProtect = TRUE; break; case 'b': opts.bSecCallback = TRUE; break; #endif case 'c': opts.bConsole = TRUE; break; case 'h': case '?': default: UsageOpts(argv[0]); } } else UsageOpts(argv[0]); } } ParseOpts::ParseOpts(char* valid_opts) { SetValidOpts(valid_opts); } ParseOpts::ParseOpts() { } ParseOpts::~ParseOpts() { } krb5-1.16/src/ccapi/common/win/OldCC/init.hxx0000644000704600001450000000634513211554426020561 0ustar ghudsonlibuuid/* * $Header$ * * Copyright 2008 Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #pragma once #include "autolock.hxx" #include typedef RPC_STATUS (RPC_ENTRY *FP_RpcBindingSetAuthInfoExA)( IN RPC_BINDING_HANDLE Binding, IN unsigned char __RPC_FAR * ServerPrincName, IN unsigned long AuthnLevel, IN unsigned long AuthnSvc, IN RPC_AUTH_IDENTITY_HANDLE AuthIdentity, OPTIONAL IN unsigned long AuthzSvc, IN RPC_SECURITY_QOS *SecurityQos OPTIONAL ); typedef RPC_STATUS (RPC_ENTRY *FP_RpcBindingSetAuthInfoExW)( IN RPC_BINDING_HANDLE Binding, IN unsigned short __RPC_FAR * ServerPrincName, IN unsigned long AuthnLevel, IN unsigned long AuthnSvc, IN RPC_AUTH_IDENTITY_HANDLE AuthIdentity, OPTIONAL IN unsigned long AuthzSvc, OPTIONAL IN RPC_SECURITY_QOS *SecurityQOS ); typedef RPC_STATUS (RPC_ENTRY *FP_RpcServerRegisterIfEx)( IN RPC_IF_HANDLE IfSpec, IN UUID __RPC_FAR * MgrTypeUuid, IN RPC_MGR_EPV __RPC_FAR * MgrEpv, IN unsigned int Flags, IN unsigned int MaxCalls, IN RPC_IF_CALLBACK_FN __RPC_FAR *IfCallback ); #ifdef UNICODE #define FP_RpcBindingSetAuthInfoEx FP_RpcBindingSetAuthInfoExW #define FN_RpcBindingSetAuthInfoEx "RpcBindingSetAuthInfoExW" #else #define FP_RpcBindingSetAuthInfoEx FP_RpcBindingSetAuthInfoExA #define FN_RpcBindingSetAuthInfoEx "RpcBindingSetAuthInfoExA" #endif #define FN_RpcServerRegisterIfEx "RpcServerRegisterIfEx" class Init { public: struct InitInfo { BOOL isNT; FP_RpcBindingSetAuthInfoEx fRpcBindingSetAuthInfoEx; FP_RpcServerRegisterIfEx fRpcServerRegisterIfEx; }; static DWORD Initialize(); static DWORD Cleanup(); static DWORD Info(InitInfo& info); static bool Initialized() { return s_init; } private: static CcOsLock s_lock; static DWORD s_refcount; static DWORD s_error; static bool s_init; static InitInfo s_info; static HINSTANCE s_hRpcDll; }; #define INIT_INIT_EX(trap, error) \ do \ { \ if (!Init::Initialized()) \ { \ DWORD rc = Init::Initialize(); \ if (rc) return (trap) ? (error) : rc; \ } \ } while(0) krb5-1.16/src/ccapi/common/win/OldCC/ccutils.c0000644000704600001450000001056513211554426020676 0ustar ghudsonlibuuid/* ccapi/common/win/OldCC/ccutils.c */ /* * Copyright 2008 Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #include #include #include #include "cci_debugging.h" #include "util.h" BOOL isNT() { OSVERSIONINFO osvi; DWORD status = 0; BOOL bSupportedVersion = FALSE; BOOL bIsNT = FALSE; memset(&osvi, 0, sizeof(osvi)); osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); status = !GetVersionEx(&osvi); // Returns a boolean. Invert to 0 is OK. if (!status) { switch(osvi.dwPlatformId) { case VER_PLATFORM_WIN32_WINDOWS: bIsNT = FALSE; bSupportedVersion = TRUE; break; case VER_PLATFORM_WIN32_NT: bIsNT = TRUE; bSupportedVersion = TRUE; break; case VER_PLATFORM_WIN32s: default: bIsNT = FALSE; break; } if (!bSupportedVersion) { cci_debug_printf("%s Running on an unsupported version of Windows", __FUNCTION__); status = 1; } } return (!status && bIsNT && bSupportedVersion); } char* allocEventName(char* uuid_string, char* suffix) { LPSTR event_name = NULL; cc_int32 err = ccNoError; event_name = malloc(strlen(uuid_string) + strlen(suffix) + 3); if (!event_name) err = cci_check_error(ccErrNoMem); if (!err) { strcpy(event_name, uuid_string); strcat(event_name, "_"); strcat(event_name, suffix); } return event_name; } HANDLE createThreadEvent(char* uuid, char* suffix) { LPSTR event_name = NULL; HANDLE hEvent = NULL; PSECURITY_ATTRIBUTES psa = 0; // Everything having to do with SECURITY_ATTRIBUTES sa = { 0 }; // sa, psa, security is copied DWORD status = 0; // from the previous implementation. psa = isNT() ? &sa : 0; if (isNT()) { sa.nLength = sizeof(sa); status = alloc_own_security_descriptor_NT(&sa.lpSecurityDescriptor); cci_check_error(status); } if (!status) { event_name = allocEventName(uuid, suffix); if (!event_name) status = cci_check_error(ccErrNoMem); } #if 0 cci_debug_printf("%s event_name:%s", __FUNCTION__, event_name); #endif if (!status) { hEvent = CreateEvent(psa, FALSE, FALSE, event_name); if (!hEvent) status = cci_check_error(GetLastError()); } if (!status) ResetEvent(hEvent); if (event_name) free(event_name); if (isNT()) free(sa.lpSecurityDescriptor); return hEvent; } HANDLE openThreadEvent(char* uuid, char* suffix) { LPSTR event_name = NULL; HANDLE hEvent = NULL; DWORD status = 0; event_name = allocEventName(uuid, suffix); if (!event_name) status = cci_check_error(ccErrNoMem); #if 0 cci_debug_printf("%s event_name:%s", __FUNCTION__, event_name); #endif if (!status) { hEvent = OpenEvent(EVENT_MODIFY_STATE, FALSE, event_name); if (!hEvent) status = cci_check_error(GetLastError()); } if (event_name) free(event_name); return hEvent; } krb5-1.16/src/ccapi/common/win/OldCC/ccutil.cxx0000644000704600001450000001176513211554426021076 0ustar ghudsonlibuuid/* * $Header$ * * Copyright 2008 Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #include #include "init.hxx" #include "secure.hxx" extern "C" { #include "cci_debugging.h" } CcOsLock Init::s_lock; DWORD Init::s_refcount = 0; DWORD Init::s_error = ERROR_INVALID_HANDLE; bool Init::s_init = false; Init::InitInfo Init::s_info = { 0 }; HINSTANCE Init::s_hRpcDll = 0; #define INIT "INIT: " static void ShowInfo( Init::InitInfo& info ); DWORD Init::Info( InitInfo& info ) { // This funciton will not do automatic initialization. CcAutoLock AL(s_lock); if (!s_init) { memset(&info, 0, sizeof(info)); return s_error ? s_error : ERROR_INVALID_HANDLE; } else { info = s_info; return 0; } } DWORD Init::Initialize() { CcAutoLock AL(s_lock); cci_debug_printf("%s s_init:%d", __FUNCTION__, s_init); if (s_init) { s_refcount++; return 0; } SecureClient s; DWORD status = 0; OSVERSIONINFO osvi; BOOL isSupportedVersion = FALSE; memset(&s_info, 0, sizeof(s_info)); memset(&osvi, 0, sizeof(osvi)); osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); status = !GetVersionEx(&osvi); // Returns a boolean. Invert to 0 is OK. if (!status) { switch(osvi.dwPlatformId) { case VER_PLATFORM_WIN32_WINDOWS: s_info.isNT = FALSE; isSupportedVersion = TRUE; break; case VER_PLATFORM_WIN32_NT: s_info.isNT = TRUE; isSupportedVersion = TRUE; break; case VER_PLATFORM_WIN32s: default: s_info.isNT = FALSE; break; } if (!isSupportedVersion) { cci_debug_printf("%s Trying to run on an unsupported version of Windows", __FUNCTION__); status = 1; } } if (!status) {status = !s_info.isNT;} if (!status) {status = !(s_hRpcDll = LoadLibrary(TEXT("rpcrt4.dll")));} if (!status) { s_info.fRpcBindingSetAuthInfoEx = (FP_RpcBindingSetAuthInfoEx) GetProcAddress(s_hRpcDll, TEXT(FN_RpcBindingSetAuthInfoEx)); if (!s_info.fRpcBindingSetAuthInfoEx) { cci_debug_printf(" Running on NT but could not find RpcBindinSetAuthInfoEx"); status = 1; } } if (!status) { s_info.fRpcServerRegisterIfEx = (FP_RpcServerRegisterIfEx) GetProcAddress(s_hRpcDll, TEXT(FN_RpcServerRegisterIfEx)); if (!s_info.fRpcServerRegisterIfEx) { cci_debug_printf(" Running on NT but could not find RpcServerRegisterIfEx"); status = 1; } } if (!status) { status = SecureClient::Attach(); if (status) { cci_debug_printf(" SecureClient::Attach() failed (%u)", status); } } if (status) { memset(&s_info, 0, sizeof(s_info)); if (s_hRpcDll) { FreeLibrary(s_hRpcDll); s_hRpcDll = 0; } cci_debug_printf(" Init::Attach() failed (%u)", status); } else { s_refcount++; s_init = true; ShowInfo(s_info); } s_error = status; return status; } DWORD Init::Cleanup( ) { CcAutoLock AL(s_lock); s_refcount--; if (s_refcount) return 0; if (!s_init) return 0; DWORD error = 0; if (s_hRpcDll) { FreeLibrary(s_hRpcDll); s_hRpcDll = 0; } error = SecureClient::Detach(); memset(&s_info, 0, sizeof(s_info)); s_init = false; s_error = 0; if (error) { cci_debug_printf(" Init::Detach() had an error (%u)", error); } return error; } static void ShowInfo( Init::InitInfo& info ) { if (info.isNT) { cci_debug_printf(" Running on Windows NT using secure mode"); } else { cci_debug_printf(" Running insecurely on non-NT Windows"); } return; } krb5-1.16/src/ccapi/common/win/OldCC/name.h0000644000704600001450000000261313211554426020150 0ustar ghudsonlibuuid/* ccapi/common/win/OldCC/name.h */ /* * Copyright 2008 Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #pragma once #ifdef _WIN64 #define CCAPI_MODULE "krbcc64" #else #define CCAPI_MODULE "krbcc32" #endif #define CCAPI_DLL CCAPI_MODULE ".dll" #define CCAPI_EXE "ccapiserver.exe"krb5-1.16/src/ccapi/common/win/OldCC/autolock.hxx0000644000704600001450000000500313211554426021425 0ustar ghudsonlibuuid/* ccapi/common/win/OldCC/autolock.hxx */ /* * Copyright (C) 1998 by Danilo Almeida. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef __AUTOLOCK_HXX__ #define __AUTOLOCK_HXX__ #include class CcOsLock { CRITICAL_SECTION cs; bool valid; public: CcOsLock() {InitializeCriticalSection(&cs); valid = true; } ~CcOsLock() {DeleteCriticalSection(&cs); valid = false;} void lock() {if (valid) EnterCriticalSection(&cs);} void unlock() {if (valid) LeaveCriticalSection(&cs);} bool trylock() {return valid ? (TryEnterCriticalSection(&cs) ? true : false) : false; } }; class CcAutoLock { CcOsLock& m_lock; public: static void Start(CcAutoLock*& a, CcOsLock& lock) { a = new CcAutoLock(lock); }; static void Stop (CcAutoLock*& a) { delete a; a = 0; }; CcAutoLock(CcOsLock& lock):m_lock(lock) { m_lock.lock(); } ~CcAutoLock() { m_lock.unlock(); } }; class CcAutoTryLock { CcOsLock& m_lock; bool m_locked; public: CcAutoTryLock(CcOsLock& lock):m_lock(lock) { m_locked = m_lock.trylock(); } ~CcAutoTryLock() { if (m_locked) m_lock.unlock(); m_locked = false; } bool IsLocked() const { return m_locked; } }; #endif /* __AUTOLOCK_HXX */ krb5-1.16/src/ccapi/common/win/OldCC/init.cxx0000644000704600001450000001176713211554426020560 0ustar ghudsonlibuuid/* * $Header$ * * Copyright 2008 Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #include #include "init.hxx" #include "secure.hxx" extern "C" { #include "cci_debugging.h" } CcOsLock Init::s_lock; DWORD Init::s_refcount = 0; DWORD Init::s_error = ERROR_INVALID_HANDLE; bool Init::s_init = false; Init::InitInfo Init::s_info = { 0 }; HINSTANCE Init::s_hRpcDll = 0; #define INIT "INIT: " static void ShowInfo( Init::InitInfo& info ); DWORD Init::Info( InitInfo& info ) { // This funciton will not do automatic initialization. CcAutoLock AL(s_lock); if (!s_init) { memset(&info, 0, sizeof(info)); return s_error ? s_error : ERROR_INVALID_HANDLE; } else { info = s_info; return 0; } } DWORD Init::Initialize() { CcAutoLock AL(s_lock); // cci_debug_printf("%s s_init:%d", __FUNCTION__, s_init); if (s_init) { s_refcount++; return 0; } SecureClient s; DWORD status = 0; OSVERSIONINFO osvi; BOOL isSupportedVersion = FALSE; memset(&s_info, 0, sizeof(s_info)); memset(&osvi, 0, sizeof(osvi)); osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); status = !GetVersionEx(&osvi); // Returns a boolean. Invert to 0 is OK. if (!status) { switch(osvi.dwPlatformId) { case VER_PLATFORM_WIN32_WINDOWS: s_info.isNT = FALSE; isSupportedVersion = TRUE; break; case VER_PLATFORM_WIN32_NT: s_info.isNT = TRUE; isSupportedVersion = TRUE; break; case VER_PLATFORM_WIN32s: default: s_info.isNT = FALSE; break; } if (!isSupportedVersion) { cci_debug_printf("%s Trying to run on an unsupported version of Windows", __FUNCTION__); status = 1; } } if (!status) {status = !s_info.isNT;} if (!status) {status = !(s_hRpcDll = LoadLibrary(TEXT("rpcrt4.dll")));} if (!status) { s_info.fRpcBindingSetAuthInfoEx = (FP_RpcBindingSetAuthInfoEx) GetProcAddress(s_hRpcDll, TEXT(FN_RpcBindingSetAuthInfoEx)); if (!s_info.fRpcBindingSetAuthInfoEx) { cci_debug_printf(" Running on NT but could not find RpcBindinSetAuthInfoEx"); status = 1; } } if (!status) { s_info.fRpcServerRegisterIfEx = (FP_RpcServerRegisterIfEx) GetProcAddress(s_hRpcDll, TEXT(FN_RpcServerRegisterIfEx)); if (!s_info.fRpcServerRegisterIfEx) { cci_debug_printf(" Running on NT but could not find RpcServerRegisterIfEx"); status = 1; } } if (!status) { status = SecureClient::Attach(); if (status) { cci_debug_printf(" SecureClient::Attach() failed (%u)", status); } } if (status) { memset(&s_info, 0, sizeof(s_info)); if (s_hRpcDll) { FreeLibrary(s_hRpcDll); s_hRpcDll = 0; } cci_debug_printf(" Init::Attach() failed (%u)", status); } else { s_refcount++; s_init = true; ShowInfo(s_info); } s_error = status; return status; } DWORD Init::Cleanup( ) { CcAutoLock AL(s_lock); s_refcount--; if (s_refcount) return 0; if (!s_init) return 0; DWORD error = 0; if (s_hRpcDll) { FreeLibrary(s_hRpcDll); s_hRpcDll = 0; } error = SecureClient::Detach(); memset(&s_info, 0, sizeof(s_info)); s_init = false; s_error = 0; if (error) { cci_debug_printf(" Init::Detach() had an error (%u)", error); } return error; } static void ShowInfo( Init::InitInfo& info ) { if (info.isNT) { cci_debug_printf(" Running on Windows NT using secure mode"); } else { cci_debug_printf(" Running insecurely on non-NT Windows"); } return; } krb5-1.16/src/ccapi/common/win/OldCC/opts.hxx0000644000704600001450000000347713211554426020606 0ustar ghudsonlibuuid/* * $Header$ * * Copyright 2008 Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #pragma once class ParseOpts { public: struct Opts { char* pszString; char* pszEndpoint; unsigned int cMinCalls; unsigned int cMaxCalls; unsigned int fDontWait; bool bDontProtect; bool bShutdown; bool bSecCallback; bool bConsole; }; ParseOpts(char* valid_opts); ParseOpts(); ~ParseOpts(); void SetValidOpts(char* valid_opts); void Parse(Opts& opts, int argc, char **argv); private: bool IsValidOpt(char ch); void PrintOpt(char ch, char* text); void UsageOpts(char* program, int code = 0); char m_ValidOpts[256]; }; krb5-1.16/src/ccapi/common/win/OldCC/secure.cxx0000644000704600001450000001063113211554426021070 0ustar ghudsonlibuuid/* * $Header$ * * Copyright 2008 Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #include #include "secure.hxx" extern "C" { #include "cci_debugging.h" } CcOsLock SecureClient::s_lock; DWORD SecureClient::s_refcount = 0; DWORD SecureClient::s_error = 0; HANDLE SecureClient::s_hToken = 0; #include "util.h" #define SC "SecureClient::" DWORD SecureClient::Attach( ) { CcAutoLock AL(s_lock); if (s_hToken) { s_refcount++; return 0; } if (OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &s_hToken)) { s_refcount++; s_error = 0; } else { s_hToken = 0; s_error = GetLastError(); } return s_error; } DWORD SecureClient::Detach( ) { CcAutoLock AL(s_lock); s_refcount--; if (s_refcount) return 0; if (!s_hToken) return 0; DWORD error = 0; if (!CloseHandle(s_hToken)) error = GetLastError(); s_hToken = 0; s_error = 0; return error; } DWORD SecureClient::Token(HANDLE& hToken) { // This function will not do automatic initialization. CcAutoLock AL(s_lock); hToken = 0; if (!s_hToken) { cci_debug_printf("%s no process token initialized (%u)", __FUNCTION__, s_error); return s_error ? s_error : ERROR_INVALID_HANDLE; } else { DWORD status = 0; if (!DuplicateHandle(GetCurrentProcess(), s_hToken, GetCurrentProcess(), &hToken, 0, FALSE, DUPLICATE_SAME_ACCESS)) { status = GetLastError(); cci_debug_printf(" Could not duplicate handle (%u)", status); } return status; } } void SecureClient::Start(SecureClient*& s) { s = new SecureClient; } void SecureClient::Stop(SecureClient*& s) { delete s; s = 0; } /////////////////////////////////////////////////////////////////////////////// /* This constructor turns off impersonation. * It is OK for OpenThreadToken to return an error -- that just means impersonation * is off. */ SecureClient::SecureClient(): m_Error(0), m_hToken(0), m_NeedRestore(false) { HANDLE hThread = GetCurrentThread(); HANDLE hThDuplicate; int status = DuplicateHandle( GetCurrentProcess(), hThread, GetCurrentProcess(), &hThDuplicate, TOKEN_ALL_ACCESS, FALSE, 0); if (!status) return; if (!OpenThreadToken(hThDuplicate, TOKEN_ALL_ACCESS, FALSE, &m_hToken)) { m_Error = GetLastError(); return; } if (SetThreadToken(&hThDuplicate, NULL)) { m_NeedRestore = true; } else { m_Error = GetLastError(); } CloseHandle(hThDuplicate); } SecureClient::~SecureClient() { if (m_NeedRestore) { HANDLE hThread = GetCurrentThread(); if (!SetThreadToken(&hThread, m_hToken)) { m_Error = cci_check_error(GetLastError()); } } if (m_hToken) { if (!CloseHandle(m_hToken)) { m_Error = cci_check_error(GetLastError()); } } } DWORD SecureClient::Error() { return m_Error; }krb5-1.16/src/ccapi/common/win/OldCC/ccutils.h0000644000704600001450000000317013211554426020675 0ustar ghudsonlibuuid/* ccapi/common/win/OldCC/ccutils.h */ /* * Copyright 2008 Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #ifndef __CCUTILS_H__ #define __CCUTILS_H__ #ifdef __cplusplus extern "C" { #endif #if 0 } #endif #define REPLY_SUFFIX (char*)"reply" #define LISTEN_SUFFIX (char*)"listen" BOOL isNT(); char* allocEventName (char* uuid, char* suffix); HANDLE createThreadEvent(char* uuid, char* suffix); HANDLE openThreadEvent (char* uuid, char* suffix); #ifdef __cplusplus } #endif #endif /* __CCUTILS_H__ */ krb5-1.16/src/ccapi/common/win/OldCC/util.h0000644000704600001450000000363513211554426020212 0ustar ghudsonlibuuid/* ccapi/common/win/OldCC/util.h */ /* * Copyright 2008 Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #ifndef __UTIL_H__ #define __UTIL_H__ #ifdef __cplusplus extern "C" { #endif #if 0 } #endif BOOL isNT(); void* user_allocate( size_t size ); void user_free( void* ptr ); void free_alloc_p( void* pptr ); DWORD alloc_name( LPSTR* pname, LPSTR postfix, BOOL isNT ); DWORD alloc_own_security_descriptor_NT( PSECURITY_DESCRIPTOR* ppsd ); DWORD alloc_module_dir_name( char* module, char** pname ); DWORD alloc_module_dir_name_with_file( char* module, char* file, char** pname ); DWORD alloc_cmdline_2_args( char* prog, char* arg1, char* arg2, char** pname); #ifdef __cplusplus } #endif #endif /* __UTIL_H__ */ krb5-1.16/src/ccapi/common/win/tls.h0000644000704600001450000000545113211554426017111 0ustar ghudsonlibuuid/* ccapi/common/win/tls.h */ /* * Copyright 2008 Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ /* Thread local storage for client threads. */ #ifndef _tls_h #define _tls_h #include "windows.h" #include "time.h" #include "rpc.h" #include "k5-ipc_stream.h" #define UUID_SIZE 128 /* The client code can be run in any client thread. The thread-specific data is defined here. */ struct tspdata { BOOL _listening; BOOL _CCAPI_Connected; RPC_ASYNC_STATE* _rpcState; HANDLE _replyEvent; time_t _sst; k5_ipc_stream _stream; char _uuid[UUID_SIZE]; }; void tspdata_setListening (struct tspdata* p, BOOL b); void tspdata_setConnected (struct tspdata* p, BOOL b); void tspdata_setReplyEvent(struct tspdata* p, HANDLE h); void tspdata_setRpcAState (struct tspdata* p, RPC_ASYNC_STATE* rpcState); void tspdata_setSST (struct tspdata* p, time_t t); void tspdata_setStream (struct tspdata* p, k5_ipc_stream s); void tspdata_setUUID (struct tspdata* p, unsigned char __RPC_FAR* uuidString); HANDLE tspdata_getReplyEvent(const struct tspdata* p); BOOL tspdata_getListening(const struct tspdata* p); BOOL tspdata_getConnected(const struct tspdata* p); RPC_ASYNC_STATE* tspdata_getRpcAState(const struct tspdata* p); time_t tspdata_getSST (const struct tspdata* p); k5_ipc_stream tspdata_getStream (const struct tspdata* p); char* tspdata_getUUID (const struct tspdata* p); BOOL WINAPI GetTspData(DWORD tlsIndex, struct tspdata** pdw); #endif _tls_h krb5-1.16/src/ccapi/common/win/win-utils.c0000644000704600001450000000463213211554426020235 0ustar ghudsonlibuuid/* ccapi/common/win/win-utils.c */ /* * Copyright 2008 Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #include #include #include #include "windows.h" #include #include #include "win-utils.h" #include "cci_debugging.h" #pragma warning (disable : 4996) #define UUID_SIZE 128 char* clientPrefix = "CCAPI_CLIENT_"; char* serverPrefix = "CCS_LISTEN_"; unsigned char* pszProtocolSequence = "ncalrpc"; #define MAX_TIMESTAMP 40 char _ts[MAX_TIMESTAMP]; char* clientEndpoint(const char* UUID) { char* _clientEndpoint = (char*)malloc(strlen(UUID) + strlen(clientPrefix) + 2); strcpy(_clientEndpoint, clientPrefix); strncat(_clientEndpoint, UUID, UUID_SIZE); // cci_debug_printf("%s returning %s", __FUNCTION__, _clientEndpoint); return _clientEndpoint; } char* serverEndpoint(const char* user) { char* _serverEndpoint = (char*)malloc(strlen(user) + strlen(serverPrefix) + 2); strcpy(_serverEndpoint, serverPrefix); strncat(_serverEndpoint, user, UUID_SIZE); return _serverEndpoint; } char* timestamp() { SYSTEMTIME _stime; GetSystemTime(&_stime); GetTimeFormat(LOCALE_SYSTEM_DEFAULT, 0, &_stime, "HH:mm:ss", _ts, sizeof(_ts)-1); return _ts; } krb5-1.16/src/ccapi/common/win/tls.c0000644000704600001450000000604413211554426017103 0ustar ghudsonlibuuid/* ccapi/common/win/tls.c */ /* * Copyright 2008 Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #include "string.h" #include #include #include "tls.h" void tspdata_setUUID(struct tspdata* p, unsigned char __RPC_FAR* uuidString) { strncpy(p->_uuid, uuidString, UUID_SIZE-1); }; void tspdata_setListening (struct tspdata* p, BOOL b) {p->_listening = b;} void tspdata_setConnected (struct tspdata* p, BOOL b) {p->_CCAPI_Connected = b;} void tspdata_setReplyEvent(struct tspdata* p, HANDLE h) {p->_replyEvent = h;} void tspdata_setRpcAState (struct tspdata* p, RPC_ASYNC_STATE* rpcState) { p->_rpcState = rpcState;} void tspdata_setSST (struct tspdata* p, time_t t) {p->_sst = t;} void tspdata_setStream (struct tspdata* p, k5_ipc_stream s) {p->_stream = s;} BOOL tspdata_getListening (const struct tspdata* p) {return p->_listening;} BOOL tspdata_getConnected (const struct tspdata* p) {return p->_CCAPI_Connected;} HANDLE tspdata_getReplyEvent(const struct tspdata* p) {return p->_replyEvent;} time_t tspdata_getSST (const struct tspdata* p) {return p->_sst;} k5_ipc_stream tspdata_getStream (const struct tspdata* p) {return p->_stream;} char* tspdata_getUUID (const struct tspdata* p) {return p->_uuid;} RPC_ASYNC_STATE* tspdata_getRpcAState (const struct tspdata* p) {return p->_rpcState;} BOOL WINAPI GetTspData(DWORD dwTlsIndex, struct tspdata** pdw) { struct tspdata* pData; // The stored memory pointer pData = (struct tspdata*)TlsGetValue(dwTlsIndex); if (pData == NULL) { pData = malloc(sizeof(*pData)); if (pData == NULL) return FALSE; memset(pData, 0, sizeof(*pData)); TlsSetValue(dwTlsIndex, pData); } (*pdw) = pData; return TRUE; } krb5-1.16/src/ccapi/common/win/win-utils.h0000644000704600001450000000340313211554426020235 0ustar ghudsonlibuuid/* ccapi/common/win/win-utils.h */ /* * Copyright 2008 Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #ifndef _win_utils_h #define _win_utils_h #ifndef TRUE #define TRUE (1==1) #endif #ifndef FALSE #define FALSE (1==0) #endif static enum ccapiMsgType { CCMSG_INVALID = 0, CCMSG_CONNECT, CCMSG_REQUEST, CCMSG_CONNECT_REPLY, CCMSG_REQUEST_REPLY, CCMSG_DISCONNECT, CCMSG_LISTEN, CCMSG_PING, CCMSG_QUIT }; char* clientEndpoint(const char* UUID); char* serverEndpoint(const char* UUID); extern unsigned char* pszProtocolSequence; char* timestamp(); #endif // _win_utils_hkrb5-1.16/src/ccapi/common/win/ccs_reply.Acf0000644000704600001450000000245413211554426020534 0ustar ghudsonlibuuid/* * $Header$ * * Copyright 2008 Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ [implicit_handle(handle_t ccs_reply_IfHandle)] interface ccs_reply { [async] ccapi_listen(); } krb5-1.16/src/ccapi/common/win/ccs_reply.Idl0000644000704600001450000000515513211554426020554 0ustar ghudsonlibuuid/* * $Header$ * * Copyright 2008 Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ [ uuid (6E3B5060-CA46-1067-B31A-00DD010662DA), version(1.0), pointer_default(unique) ] /* This interface sends a cci_stream via rpc. */ interface ccs_reply { const long HSIZE = 8; /* The reply from the server to a request from the client: */ void ccs_rpc_request_reply( [in] const long rpcmsg, /* Message type */ [in, size_is(HSIZE)] const char tsphandle[], [in, string] const char* uuid, [in] const long srvStartTime, /* Server Start Time */ [in] const long cbIn, /* Length of buffer */ [in, size_is(cbIn)] const unsigned char chIn[], /* Data buffer */ [out] long* status ); /* Return code */ void ccs_rpc_connect_reply( [in] const long rpcmsg, /* Message type */ [in, size_is(HSIZE)] const char tsphandle[], [in, string] const char* uuid, [in] const long srvStartTime, /* Server Start Time */ [out] long* status ); /* Return code */ void ccapi_listen( handle_t hBinding, [in] const long rpcmsg, /* Message type */ [out] long* status ); /* Return code */ } krb5-1.16/src/ccapi/common/Makefile.in0000644000704600001450000000444113211554426017404 0ustar ghudsonlibuuidmydir=ccapi$(S)common BUILDTOP=$(REL)..$(S).. SUBDIRS=unix SRCS= \ cci_array_internal.c \ cci_cred_union.c \ cci_debugging.c \ cci_identifier.c \ cci_message.c \ cci_stream.c STLIBOBJS= \ cci_array_internal.o \ cci_cred_union.o \ cci_debugging.o \ cci_identifier.o \ cci_message.o \ cci_stream.o OBJS= \ $(OUTPRE)cci_array_internal.$(OBJEXT) \ $(OUTPRE)cci_cred_union.$(OBJEXT) \ $(OUTPRE)cci_debugging.$(OBJEXT) \ $(OUTPRE)cci_identifier.$(OBJEXT) \ $(OUTPRE)cci_message.$(OBJEXT) \ $(OUTPRE)cci_stream.$(OBJEXT) all-unix: all-libobjs clean-unix:: clean-libobjs @libobj_frag@ # +++ Dependency line eater +++ # # Makefile dependencies follow. This must be the last section in # the Makefile.in file # cci_array_internal.so cci_array_internal.po $(OUTPRE)cci_array_internal.$(OBJEXT): \ $(COM_ERR_DEPS) $(top_srcdir)/include/CredentialsCache.h \ cci_array_internal.c cci_array_internal.h cci_common.h \ cci_cred_union.h cci_debugging.h cci_identifier.h cci_message.h \ cci_stream.h cci_types.h cci_cred_union.so cci_cred_union.po $(OUTPRE)cci_cred_union.$(OBJEXT): \ $(COM_ERR_DEPS) $(top_srcdir)/include/CredentialsCache.h \ cci_common.h cci_cred_union.c cci_cred_union.h cci_debugging.h \ cci_identifier.h cci_message.h cci_stream.h cci_types.h cci_debugging.so cci_debugging.po $(OUTPRE)cci_debugging.$(OBJEXT): \ $(COM_ERR_DEPS) $(top_srcdir)/include/CredentialsCache.h \ cci_common.h cci_cred_union.h cci_debugging.c cci_debugging.h \ cci_identifier.h cci_message.h cci_os_debugging.h cci_stream.h \ cci_types.h cci_identifier.so cci_identifier.po $(OUTPRE)cci_identifier.$(OBJEXT): \ $(COM_ERR_DEPS) $(top_srcdir)/include/CredentialsCache.h \ cci_common.h cci_cred_union.h cci_debugging.h cci_identifier.c \ cci_identifier.h cci_message.h cci_os_identifier.h \ cci_stream.h cci_types.h cci_message.so cci_message.po $(OUTPRE)cci_message.$(OBJEXT): \ $(COM_ERR_DEPS) $(top_srcdir)/include/CredentialsCache.h \ cci_common.h cci_cred_union.h cci_debugging.h cci_identifier.h \ cci_message.c cci_message.h cci_stream.h cci_types.h cci_stream.so cci_stream.po $(OUTPRE)cci_stream.$(OBJEXT): \ $(COM_ERR_DEPS) $(top_srcdir)/include/CredentialsCache.h \ cci_common.h cci_cred_union.h cci_debugging.h cci_identifier.h \ cci_message.h cci_stream.c cci_stream.h cci_types.h krb5-1.16/src/ccapi/common/cci_cred_union.c0000644000704600001450000010504013211554426020443 0ustar ghudsonlibuuid/* ccapi/common/cci_cred_union.c */ /* * Copyright 2006 Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #include "cci_common.h" #ifdef TARGET_OS_MAC #pragma mark - #endif /* ------------------------------------------------------------------------ */ static cc_uint32 cci_credentials_v4_release (cc_credentials_v4_t *io_v4creds) { cc_int32 err = ccNoError; if (!io_v4creds) { err = ccErrBadParam; } if (!err) { memset (io_v4creds, 0, sizeof (*io_v4creds)); free (io_v4creds); } return err; } /* ------------------------------------------------------------------------ */ static cc_uint32 cci_credentials_v4_read (cc_credentials_v4_t **out_v4creds, k5_ipc_stream io_stream) { cc_int32 err = ccNoError; cc_credentials_v4_t *v4creds = NULL; if (!io_stream ) { err = cci_check_error (ccErrBadParam); } if (!out_v4creds) { err = cci_check_error (ccErrBadParam); } if (!err) { v4creds = malloc (sizeof (*v4creds)); if (!v4creds) { err = cci_check_error (ccErrNoMem); } } if (!err) { err = krb5int_ipc_stream_read_uint32 (io_stream, &v4creds->version); } if (!err) { err = krb5int_ipc_stream_read (io_stream, v4creds->principal, cc_v4_name_size); } if (!err) { err = krb5int_ipc_stream_read (io_stream, v4creds->principal_instance, cc_v4_instance_size); } if (!err) { err = krb5int_ipc_stream_read (io_stream, v4creds->service, cc_v4_name_size); } if (!err) { err = krb5int_ipc_stream_read (io_stream, v4creds->service_instance, cc_v4_instance_size); } if (!err) { err = krb5int_ipc_stream_read (io_stream, v4creds->realm, cc_v4_realm_size); } if (!err) { err = krb5int_ipc_stream_read (io_stream, v4creds->session_key, cc_v4_key_size); } if (!err) { err = krb5int_ipc_stream_read_int32 (io_stream, &v4creds->kvno); } if (!err) { err = krb5int_ipc_stream_read_int32 (io_stream, &v4creds->string_to_key_type); } if (!err) { err = krb5int_ipc_stream_read_time (io_stream, &v4creds->issue_date); } if (!err) { err = krb5int_ipc_stream_read_int32 (io_stream, &v4creds->lifetime); } if (!err) { err = krb5int_ipc_stream_read_uint32 (io_stream, &v4creds->address); } if (!err) { err = krb5int_ipc_stream_read_int32 (io_stream, &v4creds->ticket_size); } if (!err) { err = krb5int_ipc_stream_read (io_stream, v4creds->ticket, cc_v4_ticket_size); } if (!err) { *out_v4creds = v4creds; v4creds = NULL; } free (v4creds); return cci_check_error (err); } /* ------------------------------------------------------------------------ */ static cc_uint32 cci_credentials_v4_write (cc_credentials_v4_t *in_v4creds, k5_ipc_stream io_stream) { cc_int32 err = ccNoError; if (!io_stream ) { err = cci_check_error (ccErrBadParam); } if (!in_v4creds) { err = cci_check_error (ccErrBadParam); } if (!err) { err = krb5int_ipc_stream_write_uint32 (io_stream, in_v4creds->version); } if (!err) { err = krb5int_ipc_stream_write (io_stream, in_v4creds->principal, cc_v4_name_size); } if (!err) { err = krb5int_ipc_stream_write (io_stream, in_v4creds->principal_instance, cc_v4_instance_size); } if (!err) { err = krb5int_ipc_stream_write (io_stream, in_v4creds->service, cc_v4_name_size); } if (!err) { err = krb5int_ipc_stream_write (io_stream, in_v4creds->service_instance, cc_v4_instance_size); } if (!err) { err = krb5int_ipc_stream_write (io_stream, in_v4creds->realm, cc_v4_realm_size); } if (!err) { err = krb5int_ipc_stream_write (io_stream, in_v4creds->session_key, cc_v4_key_size); } if (!err) { err = krb5int_ipc_stream_write_int32 (io_stream, in_v4creds->kvno); } if (!err) { err = krb5int_ipc_stream_write_int32 (io_stream, in_v4creds->string_to_key_type); } if (!err) { err = krb5int_ipc_stream_write_time (io_stream, in_v4creds->issue_date); } if (!err) { err = krb5int_ipc_stream_write_int32 (io_stream, in_v4creds->lifetime); } if (!err) { err = krb5int_ipc_stream_write_uint32 (io_stream, in_v4creds->address); } if (!err) { err = krb5int_ipc_stream_write_int32 (io_stream, in_v4creds->ticket_size); } if (!err) { err = krb5int_ipc_stream_write (io_stream, in_v4creds->ticket, cc_v4_ticket_size); } return cci_check_error (err); } #ifdef TARGET_OS_MAC #pragma mark - #endif /* ------------------------------------------------------------------------ */ static cc_uint32 cci_cc_data_contents_release (cc_data *io_ccdata) { cc_int32 err = ccNoError; if (!io_ccdata && io_ccdata->data) { err = ccErrBadParam; } if (!err) { if (io_ccdata->length) { memset (io_ccdata->data, 0, io_ccdata->length); } free (io_ccdata->data); } return err; } /* ------------------------------------------------------------------------ */ static cc_uint32 cci_cc_data_release (cc_data *io_ccdata) { cc_int32 err = ccNoError; if (!io_ccdata) { err = ccErrBadParam; } if (!err) { cci_cc_data_contents_release (io_ccdata); free (io_ccdata); } return err; } /* ------------------------------------------------------------------------ */ static cc_uint32 cci_cc_data_read (cc_data *io_ccdata, k5_ipc_stream io_stream) { cc_int32 err = ccNoError; cc_uint32 type = 0; cc_uint32 length = 0; char *data = NULL; if (!io_stream) { err = cci_check_error (ccErrBadParam); } if (!io_ccdata) { err = cci_check_error (ccErrBadParam); } if (!err) { err = krb5int_ipc_stream_read_uint32 (io_stream, &type); } if (!err) { err = krb5int_ipc_stream_read_uint32 (io_stream, &length); } if (!err && length > 0) { data = malloc (length); if (!data) { err = cci_check_error (ccErrNoMem); } if (!err) { err = krb5int_ipc_stream_read (io_stream, data, length); } } if (!err) { io_ccdata->type = type; io_ccdata->length = length; io_ccdata->data = data; data = NULL; } free (data); return cci_check_error (err); } /* ------------------------------------------------------------------------ */ static cc_uint32 cci_cc_data_write (cc_data *in_ccdata, k5_ipc_stream io_stream) { cc_int32 err = ccNoError; if (!io_stream) { err = cci_check_error (ccErrBadParam); } if (!in_ccdata) { err = cci_check_error (ccErrBadParam); } if (!err) { err = krb5int_ipc_stream_write_uint32 (io_stream, in_ccdata->type); } if (!err) { err = krb5int_ipc_stream_write_uint32 (io_stream, in_ccdata->length); } if (!err && in_ccdata->length > 0) { err = krb5int_ipc_stream_write (io_stream, in_ccdata->data, in_ccdata->length); } return cci_check_error (err); } #ifdef TARGET_OS_MAC #pragma mark - #endif /* ------------------------------------------------------------------------ */ static cc_uint32 cci_cc_data_array_release (cc_data **io_ccdata_array) { cc_int32 err = ccNoError; if (!io_ccdata_array) { err = ccErrBadParam; } if (!err) { cc_uint32 i; for (i = 0; io_ccdata_array && io_ccdata_array[i]; i++) { cci_cc_data_release (io_ccdata_array[i]); } free (io_ccdata_array); } return err; } /* ------------------------------------------------------------------------ */ static cc_uint32 cci_cc_data_array_read (cc_data ***io_ccdata_array, k5_ipc_stream io_stream) { cc_int32 err = ccNoError; cc_uint32 count = 0; cc_data **array = NULL; cc_uint32 i; if (!io_stream ) { err = cci_check_error (ccErrBadParam); } if (!io_ccdata_array) { err = cci_check_error (ccErrBadParam); } if (!err) { err = krb5int_ipc_stream_read_uint32 (io_stream, &count); } if (!err && count > 0) { array = malloc ((count + 1) * sizeof (*array)); if (array) { for (i = 0; i <= count; i++) { array[i] = NULL; } } else { err = cci_check_error (ccErrNoMem); } } if (!err) { for (i = 0; !err && i < count; i++) { array[i] = malloc (sizeof (cc_data)); if (!array[i]) { err = cci_check_error (ccErrNoMem); } if (!err) { err = cci_cc_data_read (array[i], io_stream); } } } if (!err) { *io_ccdata_array = array; array = NULL; } cci_cc_data_array_release (array); return cci_check_error (err); } /* ------------------------------------------------------------------------ */ static cc_uint32 cci_cc_data_array_write (cc_data **in_ccdata_array, k5_ipc_stream io_stream) { cc_int32 err = ccNoError; cc_uint32 count = 0; if (!io_stream) { err = cci_check_error (ccErrBadParam); } /* in_ccdata_array may be NULL */ if (!err) { for (count = 0; in_ccdata_array && in_ccdata_array[count]; count++); err = krb5int_ipc_stream_write_uint32 (io_stream, count); } if (!err) { cc_uint32 i; for (i = 0; !err && i < count; i++) { err = cci_cc_data_write (in_ccdata_array[i], io_stream); } } return cci_check_error (err); } #ifdef TARGET_OS_MAC #pragma mark - #endif /* ------------------------------------------------------------------------ */ cc_credentials_v5_t cci_credentials_v5_initializer = { NULL, NULL, { 0, 0, NULL }, 0, 0, 0, 0, 0, 0, NULL, { 0, 0, NULL }, { 0, 0, NULL }, NULL }; /* ------------------------------------------------------------------------ */ static cc_uint32 cci_credentials_v5_release (cc_credentials_v5_t *io_v5creds) { cc_int32 err = ccNoError; if (!io_v5creds) { err = ccErrBadParam; } if (!err) { free (io_v5creds->client); free (io_v5creds->server); cci_cc_data_contents_release (&io_v5creds->keyblock); cci_cc_data_array_release (io_v5creds->addresses); cci_cc_data_contents_release (&io_v5creds->ticket); cci_cc_data_contents_release (&io_v5creds->second_ticket); cci_cc_data_array_release (io_v5creds->authdata); free (io_v5creds); } return err; } /* ------------------------------------------------------------------------ */ static cc_uint32 cci_credentials_v5_read (cc_credentials_v5_t **out_v5creds, k5_ipc_stream io_stream) { cc_int32 err = ccNoError; cc_credentials_v5_t *v5creds = NULL; if (!io_stream ) { err = cci_check_error (ccErrBadParam); } if (!out_v5creds) { err = cci_check_error (ccErrBadParam); } if (!err) { v5creds = malloc (sizeof (*v5creds)); if (v5creds) { *v5creds = cci_credentials_v5_initializer; } else { err = cci_check_error (ccErrNoMem); } } if (!err) { err = krb5int_ipc_stream_read_string (io_stream, &v5creds->client); } if (!err) { err = krb5int_ipc_stream_read_string (io_stream, &v5creds->server); } if (!err) { err = cci_cc_data_read (&v5creds->keyblock, io_stream); } if (!err) { err = krb5int_ipc_stream_read_time (io_stream, &v5creds->authtime); } if (!err) { err = krb5int_ipc_stream_read_time (io_stream, &v5creds->starttime); } if (!err) { err = krb5int_ipc_stream_read_time (io_stream, &v5creds->endtime); } if (!err) { err = krb5int_ipc_stream_read_time (io_stream, &v5creds->renew_till); } if (!err) { err = krb5int_ipc_stream_read_uint32 (io_stream, &v5creds->is_skey); } if (!err) { err = krb5int_ipc_stream_read_uint32 (io_stream, &v5creds->ticket_flags); } if (!err) { err = cci_cc_data_array_read (&v5creds->addresses, io_stream); } if (!err) { err = cci_cc_data_read (&v5creds->ticket, io_stream); } if (!err) { err = cci_cc_data_read (&v5creds->second_ticket, io_stream); } if (!err) { err = cci_cc_data_array_read (&v5creds->authdata, io_stream); } if (!err) { *out_v5creds = v5creds; v5creds = NULL; } cci_credentials_v5_release (v5creds); return cci_check_error (err); } /* ------------------------------------------------------------------------ */ static cc_uint32 cci_credentials_v5_write (cc_credentials_v5_t *in_v5creds, k5_ipc_stream io_stream) { cc_int32 err = ccNoError; if (!io_stream ) { err = cci_check_error (ccErrBadParam); } if (!in_v5creds) { err = cci_check_error (ccErrBadParam); } if (!err) { err = krb5int_ipc_stream_write_string (io_stream, in_v5creds->client); } if (!err) { err = krb5int_ipc_stream_write_string (io_stream, in_v5creds->server); } if (!err) { err = cci_cc_data_write (&in_v5creds->keyblock, io_stream); } if (!err) { err = krb5int_ipc_stream_write_time (io_stream, in_v5creds->authtime); } if (!err) { err = krb5int_ipc_stream_write_time (io_stream, in_v5creds->starttime); } if (!err) { err = krb5int_ipc_stream_write_time (io_stream, in_v5creds->endtime); } if (!err) { err = krb5int_ipc_stream_write_time (io_stream, in_v5creds->renew_till); } if (!err) { err = krb5int_ipc_stream_write_uint32 (io_stream, in_v5creds->is_skey); } if (!err) { err = krb5int_ipc_stream_write_uint32 (io_stream, in_v5creds->ticket_flags); } if (!err) { err = cci_cc_data_array_write (in_v5creds->addresses, io_stream); } if (!err) { err = cci_cc_data_write (&in_v5creds->ticket, io_stream); } if (!err) { err = cci_cc_data_write (&in_v5creds->second_ticket, io_stream); } if (!err) { err = cci_cc_data_array_write (in_v5creds->authdata, io_stream); } return cci_check_error (err); } #ifdef TARGET_OS_MAC #pragma mark - #endif /* ------------------------------------------------------------------------ */ cc_uint32 cci_credentials_union_release (cc_credentials_union *io_cred_union) { cc_int32 err = ccNoError; if (!io_cred_union) { err = ccErrBadParam; } if (!err) { if (io_cred_union->version == cc_credentials_v4) { cci_credentials_v4_release (io_cred_union->credentials.credentials_v4); } else if (io_cred_union->version == cc_credentials_v5) { cci_credentials_v5_release (io_cred_union->credentials.credentials_v5); } free (io_cred_union); } return err; } /* ------------------------------------------------------------------------ */ cc_uint32 cci_credentials_union_read (cc_credentials_union **out_credentials_union, k5_ipc_stream io_stream) { cc_int32 err = ccNoError; cc_credentials_union *credentials_union = NULL; if (!io_stream ) { err = cci_check_error (ccErrBadParam); } if (!out_credentials_union) { err = cci_check_error (ccErrBadParam); } if (!err) { credentials_union = calloc (1, sizeof (*credentials_union)); if (!credentials_union) { err = cci_check_error (ccErrNoMem); } } if (!err) { err = krb5int_ipc_stream_read_uint32 (io_stream, &credentials_union->version); } if (!err) { if (credentials_union->version == cc_credentials_v4) { err = cci_credentials_v4_read (&credentials_union->credentials.credentials_v4, io_stream); } else if (credentials_union->version == cc_credentials_v5) { err = cci_credentials_v5_read (&credentials_union->credentials.credentials_v5, io_stream); } else { err = ccErrBadCredentialsVersion; } } if (!err) { *out_credentials_union = credentials_union; credentials_union = NULL; } if (credentials_union) { cci_credentials_union_release (credentials_union); } return cci_check_error (err); } /* ------------------------------------------------------------------------ */ cc_uint32 cci_credentials_union_write (const cc_credentials_union *in_credentials_union, k5_ipc_stream io_stream) { cc_int32 err = ccNoError; if (!io_stream ) { err = cci_check_error (ccErrBadParam); } if (!in_credentials_union) { err = cci_check_error (ccErrBadParam); } if (!err) { err = krb5int_ipc_stream_write_uint32 (io_stream, in_credentials_union->version); } if (!err) { if (in_credentials_union->version == cc_credentials_v4) { err = cci_credentials_v4_write (in_credentials_union->credentials.credentials_v4, io_stream); } else if (in_credentials_union->version == cc_credentials_v5) { err = cci_credentials_v5_write (in_credentials_union->credentials.credentials_v5, io_stream); } else { err = ccErrBadCredentialsVersion; } } return cci_check_error (err); } #ifdef TARGET_OS_MAC #pragma mark - #pragma mark -- CCAPI v2 Compat -- #endif /* ------------------------------------------------------------------------ */ cc_credentials_v5_compat cci_credentials_v5_compat_initializer = { NULL, NULL, { 0, 0, NULL }, 0, 0, 0, 0, 0, 0, NULL, { 0, 0, NULL }, { 0, 0, NULL }, NULL }; /* ------------------------------------------------------------------------ */ cc_uint32 cci_cred_union_release (cred_union *io_cred_union) { cc_int32 err = ccNoError; if (!io_cred_union) { err = ccErrBadParam; } if (!err) { if (io_cred_union->cred_type == CC_CRED_V4) { memset (io_cred_union->cred.pV4Cred, 0, sizeof (cc_credentials_v4_compat)); free (io_cred_union->cred.pV4Cred); } else if (io_cred_union->cred_type == CC_CRED_V5) { free (io_cred_union->cred.pV5Cred->client); free (io_cred_union->cred.pV5Cred->server); cci_cc_data_contents_release (&io_cred_union->cred.pV5Cred->keyblock); cci_cc_data_array_release (io_cred_union->cred.pV5Cred->addresses); cci_cc_data_contents_release (&io_cred_union->cred.pV5Cred->ticket); cci_cc_data_contents_release (&io_cred_union->cred.pV5Cred->second_ticket); cci_cc_data_array_release (io_cred_union->cred.pV5Cred->authdata); free (io_cred_union->cred.pV5Cred); } free (io_cred_union); } return err; } /* ------------------------------------------------------------------------ */ static cc_uint32 cci_cc_data_copy_contents (cc_data *io_ccdata, cc_data *in_ccdata) { cc_int32 err = ccNoError; char *data = NULL; if (!io_ccdata) { err = cci_check_error (ccErrBadParam); } if (!in_ccdata) { err = cci_check_error (ccErrBadParam); } if (!err && in_ccdata->length > 0) { data = malloc (in_ccdata->length); if (data) { memcpy (data, in_ccdata->data, in_ccdata->length); } else { err = cci_check_error (ccErrNoMem); } } if (!err) { io_ccdata->type = in_ccdata->type; io_ccdata->length = in_ccdata->length; io_ccdata->data = data; data = NULL; } free (data); return cci_check_error (err); } /* ------------------------------------------------------------------------ */ static cc_uint32 cci_cc_data_array_copy (cc_data ***io_ccdata_array, cc_data **in_ccdata_array) { cc_int32 err = ccNoError; cc_uint32 count = 0; cc_data **array = NULL; cc_uint32 i; if (!io_ccdata_array) { err = cci_check_error (ccErrBadParam); } if (!err) { for (count = 0; in_ccdata_array && in_ccdata_array[count]; count++); } if (!err && count > 0) { array = malloc ((count + 1) * sizeof (*array)); if (array) { for (i = 0; i <= count; i++) { array[i] = NULL; } } else { err = cci_check_error (ccErrNoMem); } } if (!err) { for (i = 0; !err && i < count; i++) { array[i] = malloc (sizeof (cc_data)); if (!array[i]) { err = cci_check_error (ccErrNoMem); } if (!err) { err = cci_cc_data_copy_contents (array[i], in_ccdata_array[i]); } } } if (!err) { *io_ccdata_array = array; array = NULL; } cci_cc_data_array_release (array); return cci_check_error (err); } /* ------------------------------------------------------------------------ */ cc_uint32 cci_credentials_union_to_cred_union (const cc_credentials_union *in_credentials_union, cred_union **out_cred_union) { cc_int32 err = ccNoError; cred_union *compat_cred_union = NULL; if (!in_credentials_union) { err = cci_check_error (ccErrBadParam); } if (!out_cred_union ) { err = cci_check_error (ccErrBadParam); } if (!err) { compat_cred_union = calloc (1, sizeof (*compat_cred_union)); if (!compat_cred_union) { err = cci_check_error (ccErrNoMem); } } if (!err) { if (in_credentials_union->version == cc_credentials_v4) { cc_credentials_v4_compat *compat_v4creds = NULL; compat_v4creds = malloc (sizeof (*compat_v4creds)); if (!compat_v4creds) { err = cci_check_error (ccErrNoMem); } if (!err) { cc_credentials_v4_t *v4creds = in_credentials_union->credentials.credentials_v4; compat_cred_union->cred_type = CC_CRED_V4; compat_cred_union->cred.pV4Cred = compat_v4creds; compat_v4creds->kversion = v4creds->version; strncpy (compat_v4creds->principal, v4creds->principal, KRB_NAME_SZ+1); strncpy (compat_v4creds->principal_instance, v4creds->principal_instance, KRB_INSTANCE_SZ+1); strncpy (compat_v4creds->service, v4creds->service, KRB_NAME_SZ+1); strncpy (compat_v4creds->service_instance, v4creds->service_instance, KRB_INSTANCE_SZ+1); strncpy (compat_v4creds->realm, v4creds->realm, KRB_REALM_SZ+1); memcpy (compat_v4creds->session_key, v4creds->session_key, 8); compat_v4creds->kvno = v4creds->kvno; compat_v4creds->str_to_key = v4creds->string_to_key_type; compat_v4creds->issue_date = v4creds->issue_date; compat_v4creds->lifetime = v4creds->lifetime; compat_v4creds->address = v4creds->address; compat_v4creds->ticket_sz = v4creds->ticket_size; memcpy (compat_v4creds->ticket, v4creds->ticket, MAX_V4_CRED_LEN); compat_v4creds->oops = 0; } } else if (in_credentials_union->version == cc_credentials_v5) { cc_credentials_v5_t *v5creds = in_credentials_union->credentials.credentials_v5; cc_credentials_v5_compat *compat_v5creds = NULL; compat_v5creds = malloc (sizeof (*compat_v5creds)); if (compat_v5creds) { *compat_v5creds = cci_credentials_v5_compat_initializer; } else { err = cci_check_error (ccErrNoMem); } if (!err) { if (!v5creds->client) { err = cci_check_error (ccErrBadParam); } else { compat_v5creds->client = strdup (v5creds->client); if (!compat_v5creds->client) { err = cci_check_error (ccErrNoMem); } } } if (!err) { if (!v5creds->server) { err = cci_check_error (ccErrBadParam); } else { compat_v5creds->server = strdup (v5creds->server); if (!compat_v5creds->server) { err = cci_check_error (ccErrNoMem); } } } if (!err) { err = cci_cc_data_copy_contents (&compat_v5creds->keyblock, &v5creds->keyblock); } if (!err) { err = cci_cc_data_array_copy (&compat_v5creds->addresses, v5creds->addresses); } if (!err) { err = cci_cc_data_copy_contents (&compat_v5creds->ticket, &v5creds->ticket); } if (!err) { err = cci_cc_data_copy_contents (&compat_v5creds->second_ticket, &v5creds->second_ticket); } if (!err) { err = cci_cc_data_array_copy (&compat_v5creds->authdata, v5creds->authdata); } if (!err) { compat_cred_union->cred_type = CC_CRED_V5; compat_cred_union->cred.pV5Cred = compat_v5creds; compat_v5creds->keyblock = v5creds->keyblock; compat_v5creds->authtime = v5creds->authtime; compat_v5creds->starttime = v5creds->starttime; compat_v5creds->endtime = v5creds->endtime; compat_v5creds->renew_till = v5creds->renew_till; compat_v5creds->is_skey = v5creds->is_skey; compat_v5creds->ticket_flags = v5creds->ticket_flags; } } else { err = cci_check_error (ccErrBadCredentialsVersion); } } if (!err) { *out_cred_union = compat_cred_union; compat_cred_union = NULL; } if (compat_cred_union) { cci_cred_union_release (compat_cred_union); } return cci_check_error (err); } /* ------------------------------------------------------------------------ */ cc_uint32 cci_cred_union_to_credentials_union (const cred_union *in_cred_union, cc_credentials_union **out_credentials_union) { cc_int32 err = ccNoError; cc_credentials_union *creds_union = NULL; if (!in_cred_union ) { err = cci_check_error (ccErrBadParam); } if (!out_credentials_union) { err = cci_check_error (ccErrBadParam); } if (!err) { creds_union = calloc (1, sizeof (*creds_union)); if (!creds_union) { err = cci_check_error (ccErrNoMem); } } if (!err) { if (in_cred_union->cred_type == CC_CRED_V4) { cc_credentials_v4_compat *compat_v4creds = in_cred_union->cred.pV4Cred; cc_credentials_v4_t *v4creds = NULL; if (!err) { v4creds = malloc (sizeof (*v4creds)); if (!v4creds) { err = cci_check_error (ccErrNoMem); } } if (!err) { creds_union->version = cc_credentials_v4; creds_union->credentials.credentials_v4 = v4creds; v4creds->version = compat_v4creds->kversion; strncpy (v4creds->principal, compat_v4creds->principal, KRB_NAME_SZ); strncpy (v4creds->principal_instance, compat_v4creds->principal_instance, KRB_INSTANCE_SZ); strncpy (v4creds->service, compat_v4creds->service, KRB_NAME_SZ); strncpy (v4creds->service_instance, compat_v4creds->service_instance, KRB_INSTANCE_SZ); strncpy (v4creds->realm, compat_v4creds->realm, KRB_REALM_SZ); memcpy (v4creds->session_key, compat_v4creds->session_key, 8); v4creds->kvno = compat_v4creds->kvno; v4creds->string_to_key_type = compat_v4creds->str_to_key; v4creds->issue_date = compat_v4creds->issue_date; v4creds->lifetime = compat_v4creds->lifetime; v4creds->address = compat_v4creds->address; v4creds->ticket_size = compat_v4creds->ticket_sz; memcpy (v4creds->ticket, compat_v4creds->ticket, MAX_V4_CRED_LEN); } } else if (in_cred_union->cred_type == CC_CRED_V5) { cc_credentials_v5_compat *compat_v5creds = in_cred_union->cred.pV5Cred; cc_credentials_v5_t *v5creds = NULL; if (!err) { v5creds = malloc (sizeof (*v5creds)); if (v5creds) { *v5creds = cci_credentials_v5_initializer; } else { err = cci_check_error (ccErrNoMem); } } if (!err) { if (!compat_v5creds->client) { err = cci_check_error (ccErrBadParam); } else { v5creds->client = strdup (compat_v5creds->client); if (!v5creds->client) { err = cci_check_error (ccErrNoMem); } } } if (!err) { if (!compat_v5creds->server) { err = cci_check_error (ccErrBadParam); } else { v5creds->server = strdup (compat_v5creds->server); if (!v5creds->server) { err = cci_check_error (ccErrNoMem); } } } if (!err) { err = cci_cc_data_copy_contents (&v5creds->keyblock, &compat_v5creds->keyblock); } if (!err) { err = cci_cc_data_array_copy (&v5creds->addresses, compat_v5creds->addresses); } if (!err) { err = cci_cc_data_copy_contents (&v5creds->ticket, &compat_v5creds->ticket); } if (!err) { err = cci_cc_data_copy_contents (&v5creds->second_ticket, &compat_v5creds->second_ticket); } if (!err) { err = cci_cc_data_array_copy (&v5creds->authdata, compat_v5creds->authdata); } if (!err) { creds_union->version = cc_credentials_v5; creds_union->credentials.credentials_v5 = v5creds; v5creds->authtime = compat_v5creds->authtime; v5creds->starttime = compat_v5creds->starttime; v5creds->endtime = compat_v5creds->endtime; v5creds->renew_till = compat_v5creds->renew_till; v5creds->is_skey = compat_v5creds->is_skey; v5creds->ticket_flags = compat_v5creds->ticket_flags; } } else { err = cci_check_error (ccErrBadCredentialsVersion); } } if (!err) { *out_credentials_union = creds_union; creds_union = NULL; } if (creds_union) { cci_credentials_union_release (creds_union); } return cci_check_error (err); } /* ------------------------------------------------------------------------ */ cc_uint32 cci_cred_union_compare_to_credentials_union (const cred_union *in_cred_union_compat, const cc_credentials_union *in_credentials_union, cc_uint32 *out_equal) { cc_int32 err = ccNoError; cc_uint32 equal = 0; if (!in_cred_union_compat) { err = cci_check_error (ccErrBadParam); } if (!in_credentials_union) { err = cci_check_error (ccErrBadParam); } if (!out_equal ) { err = cci_check_error (ccErrBadParam); } if (!err) { if (in_cred_union_compat->cred_type == CC_CRED_V4 && in_credentials_union->version == cc_credentials_v4) { cc_credentials_v4_compat *old_creds_v4 = in_cred_union_compat->cred.pV4Cred; cc_credentials_v4_t *new_creds_v4 = in_credentials_union->credentials.credentials_v4; if (old_creds_v4 && new_creds_v4 && !strcmp (old_creds_v4->principal, new_creds_v4->principal) && !strcmp (old_creds_v4->principal_instance, new_creds_v4->principal_instance) && !strcmp (old_creds_v4->service, new_creds_v4->service) && !strcmp (old_creds_v4->service_instance, new_creds_v4->service_instance) && !strcmp (old_creds_v4->realm, new_creds_v4->realm) && (old_creds_v4->issue_date == (long) new_creds_v4->issue_date)) { equal = 1; } } else if (in_cred_union_compat->cred_type == CC_CRED_V5 && in_credentials_union->version == cc_credentials_v5) { cc_credentials_v5_compat *old_creds_v5 = in_cred_union_compat->cred.pV5Cred; cc_credentials_v5_t *new_creds_v5 = in_credentials_union->credentials.credentials_v5; /* Really should use krb5_parse_name and krb5_principal_compare */ if (old_creds_v5 && new_creds_v5 && !strcmp (old_creds_v5->client, new_creds_v5->client) && !strcmp (old_creds_v5->server, new_creds_v5->server) && (old_creds_v5->starttime == new_creds_v5->starttime)) { equal = 1; } } } if (!err) { *out_equal = equal; } return cci_check_error (err); } krb5-1.16/src/ccapi/common/unix/0000755000704600001450000000000013211554426016317 5ustar ghudsonlibuuidkrb5-1.16/src/ccapi/common/unix/Makefile.in0000644000704600001450000000026613211554426020370 0ustar ghudsonlibuuidmydir=ccapi$(S)common$(S)unix BUILDTOP=$(REL)..$(S)..$(S).. STLIBOBJS= OBJS= SRCS= all-unix: all-libobjs clean-unix:: clean-libobjs @libobj_frag@ # +++ Dependency line eater +++ krb5-1.16/src/ccapi/server/0000755000704600001450000000000013211554426015352 5ustar ghudsonlibuuidkrb5-1.16/src/ccapi/server/ccs_list.h0000644000704600001450000001444013211554426017331 0ustar ghudsonlibuuid/* ccapi/server/ccs_list.h */ /* * Copyright 2006, 2007 Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #ifndef CCS_LIST_H #define CCS_LIST_H #include "ccs_types.h" cc_int32 ccs_cache_collection_list_new (ccs_cache_collection_list_t *out_list); cc_int32 ccs_cache_collection_list_count (ccs_cache_collection_list_t in_list, cc_uint64 *out_count); cc_int32 ccs_cache_collection_list_find (ccs_cache_collection_list_t in_list, cci_identifier_t in_identifier, ccs_cache_collection_t *out_cache_collection); cc_int32 ccs_cache_collection_list_add (ccs_cache_collection_list_t io_list, ccs_cache_collection_t in_cache_collection); cc_int32 ccs_cache_collection_list_remove (ccs_cache_collection_list_t io_list, cci_identifier_t in_identifier); cc_int32 ccs_cache_collection_list_release (ccs_cache_collection_list_t io_list); #ifdef TARGET_OS_MAC #pragma mark - #endif cc_int32 ccs_ccache_list_new (ccs_ccache_list_t *out_list); cc_int32 ccs_ccache_list_new_iterator (ccs_ccache_list_t in_list, ccs_pipe_t in_client_pipe, ccs_ccache_list_iterator_t *out_list_iterator); cc_int32 ccs_ccache_list_count (ccs_ccache_list_t in_list, cc_uint64 *out_count); cc_int32 ccs_ccache_list_find (ccs_ccache_list_t in_list, cci_identifier_t in_identifier, ccs_ccache_t *out_ccache); cc_int32 ccs_ccache_list_find_iterator (ccs_ccache_list_t in_list, cci_identifier_t in_identifier, ccs_ccache_list_iterator_t *out_list_iterator); cc_int32 ccs_ccache_list_add (ccs_ccache_list_t io_list, ccs_ccache_t in_ccache); cc_int32 ccs_ccache_list_remove (ccs_ccache_list_t io_list, cci_identifier_t in_identifier); cc_int32 ccs_ccache_list_push_front (ccs_ccache_list_t io_list, cci_identifier_t in_identifier); cc_int32 ccs_ccache_list_release (ccs_ccache_list_t io_list); cc_int32 ccs_ccache_list_iterator_write (ccs_ccache_list_iterator_t in_list_iterator, k5_ipc_stream in_stream); cc_int32 ccs_ccache_list_iterator_clone (ccs_ccache_list_iterator_t in_list_iterator, ccs_ccache_list_iterator_t *out_list_iterator); cc_int32 ccs_ccache_list_iterator_next (ccs_ccache_list_iterator_t io_list_iterator, ccs_ccache_t *out_ccache); cc_int32 ccs_ccache_list_iterator_release (ccs_ccache_list_iterator_t io_list_iterator); #ifdef TARGET_OS_MAC #pragma mark - #endif cc_int32 ccs_credentials_list_new (ccs_credentials_list_t *out_list); cc_int32 ccs_credentials_list_new_iterator (ccs_credentials_list_t in_list, ccs_pipe_t in_client_pipe, ccs_credentials_list_iterator_t *out_list_iterator); cc_int32 ccs_credentials_list_count (ccs_credentials_list_t in_list, cc_uint64 *out_count); cc_int32 ccs_credentials_list_find (ccs_credentials_list_t in_list, cci_identifier_t in_identifier, ccs_credentials_t *out_credentials); cc_int32 ccs_credentials_list_find_iterator (ccs_credentials_list_t in_list, cci_identifier_t in_identifier, ccs_credentials_list_iterator_t *out_list_iterator); cc_int32 ccs_credentials_list_add (ccs_credentials_list_t io_list, ccs_credentials_t in_credential); cc_int32 ccs_credentials_list_remove (ccs_credentials_list_t io_list, cci_identifier_t in_identifier); cc_int32 ccs_credentials_list_release (ccs_credentials_list_t io_list); cc_int32 ccs_credentials_list_iterator_write (ccs_credentials_list_iterator_t in_list_iterator, k5_ipc_stream in_stream); cc_int32 ccs_credentials_list_iterator_clone (ccs_credentials_list_iterator_t in_list_iterator, ccs_credentials_list_iterator_t *out_list_iterator); cc_int32 ccs_credentials_list_iterator_next (ccs_credentials_list_iterator_t io_list_iterator, ccs_credentials_t *out_credential); cc_int32 ccs_credentials_list_iterator_release (ccs_credentials_list_iterator_t io_list_iterator); #ifdef TARGET_OS_MAC #pragma mark - #endif cc_int32 ccs_generic_list_iterator_invalidate (ccs_generic_list_iterator_t io_list_iterator); #endif /* CCS_LIST_H */ krb5-1.16/src/ccapi/server/ccs_types.h0000644000704600001450000000643113211554426017523 0ustar ghudsonlibuuid/* ccapi/server/ccs_types.h */ /* * Copyright 2006, 2007 Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #ifndef CCS_TYPES_H #define CCS_TYPES_H #ifdef WIN32 #pragma warning ( disable : 4068) #endif #include "cci_types.h" struct cci_array_d; typedef struct cci_array_d *ccs_client_array_t; typedef struct cci_array_d *ccs_callback_array_t; typedef struct cci_array_d *ccs_callbackref_array_t; typedef struct cci_array_d *ccs_iteratorref_array_t; typedef struct cci_array_d *ccs_lock_array_t; #ifdef TARGET_OS_MAC #pragma mark - #endif /* ccs_os_pipe_t is IPC-specific so it's special cased here */ #if TARGET_OS_MAC #include typedef mach_port_t ccs_pipe_t; /* Mach IPC port */ #define CCS_PIPE_NULL MACH_PORT_NULL #else #ifdef WIN32 /* On Windows, a pipe is s struct: */ #include "ccs_win_pipe.h" typedef struct ccs_win_pipe_t* ccs_pipe_t; #define CCS_PIPE_NULL (ccs_pipe_t)NULL #else typedef int ccs_pipe_t; /* Unix domain socket */ #define CCS_PIPE_NULL -1 #endif #endif #ifdef TARGET_OS_MAC #pragma mark - #endif struct ccs_callback_d; typedef struct ccs_callback_d *ccs_callback_t; struct ccs_list_d; struct ccs_list_iterator_d; /* Used for iterator array invalidate function */ typedef struct ccs_list_iterator_d *ccs_generic_list_iterator_t; typedef struct ccs_list_d *ccs_cache_collection_list_t; typedef struct ccs_list_d *ccs_ccache_list_t; typedef struct ccs_list_iterator_d *ccs_ccache_list_iterator_t; typedef struct ccs_list_d *ccs_credentials_list_t; typedef struct ccs_list_iterator_d *ccs_credentials_list_iterator_t; #ifdef TARGET_OS_MAC #pragma mark - #endif struct ccs_client_d; typedef struct ccs_client_d *ccs_client_t; struct ccs_lock_d; typedef struct ccs_lock_d *ccs_lock_t; struct ccs_lock_state_d; typedef struct ccs_lock_state_d *ccs_lock_state_t; struct ccs_credentials_d; typedef struct ccs_credentials_d *ccs_credentials_t; typedef ccs_credentials_list_iterator_t ccs_credentials_iterator_t; struct ccs_ccache_d; typedef struct ccs_ccache_d *ccs_ccache_t; typedef ccs_ccache_list_iterator_t ccs_ccache_iterator_t; struct ccs_cache_collection_d; typedef struct ccs_cache_collection_d *ccs_cache_collection_t; #endif /* CCS_TYPES_H */ krb5-1.16/src/ccapi/server/ccs_ccache.h0000644000704600001450000000771213211554426017570 0ustar ghudsonlibuuid/* ccapi/server/ccs_ccache.h */ /* * Copyright 2006 Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #ifndef CCS_CCACHE_H #define CCS_CCACHE_H #include "ccs_types.h" cc_int32 ccs_ccache_new (ccs_ccache_t *out_ccache, cc_uint32 in_cred_vers, const char *in_name, const char *in_principal, ccs_ccache_list_t io_ccache_list); cc_int32 ccs_ccache_reset (ccs_ccache_t io_ccache, ccs_cache_collection_t io_cache_collection, cc_uint32 in_cred_vers, const char *in_principal); cc_int32 ccs_ccache_swap_contents (ccs_ccache_t io_source_ccache, ccs_ccache_t io_destination_ccache, ccs_cache_collection_t io_cache_collection); cc_int32 ccs_ccache_release (ccs_ccache_t io_ccache); cc_int32 ccs_ccache_changed (ccs_ccache_t io_ccache, ccs_cache_collection_t io_cache_collection); cc_int32 ccs_ccache_compare_identifier (ccs_ccache_t in_ccache, cci_identifier_t in_identifier, cc_uint32 *out_equal); cc_int32 ccs_ccache_compare_name (ccs_ccache_t in_ccache, const char *in_name, cc_uint32 *out_equal); cc_int32 ccs_ccache_notify_default_state_changed (ccs_ccache_t io_ccache, ccs_cache_collection_t io_cache_collection, cc_uint32 in_new_default_state); cc_int32 ccs_ccache_find_credentials_iterator (ccs_ccache_t in_ccache, cci_identifier_t in_identifier, ccs_credentials_iterator_t *out_credentials_iterator); cc_int32 ccs_ccache_write (ccs_ccache_t in_ccache, k5_ipc_stream io_stream); cc_int32 ccs_ccache_write_name (ccs_ccache_t in_ccache, k5_ipc_stream io_stream); cc_int32 ccs_ccache_handle_message (ccs_pipe_t in_client_pipe, ccs_pipe_t in_reply_pipe, ccs_ccache_t io_ccache, ccs_cache_collection_t io_cache_collection, enum cci_msg_id_t in_request_name, k5_ipc_stream in_request_data, cc_uint32 *out_will_block, k5_ipc_stream *out_reply_data); #endif /* CCS_CCACHE_H */ krb5-1.16/src/ccapi/server/ccs_list.c0000644000704600001450000003407213211554426017327 0ustar ghudsonlibuuid/* ccapi/server/ccs_list.c */ /* * Copyright 2006, 2007 Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #include "ccs_common.h" #include "ccs_list_internal.h" /* ------------------------------------------------------------------------ */ static cc_int32 ccs_cache_collection_list_object_release (ccs_list_object_t io_object) { return cci_check_error (ccs_cache_collection_release ((ccs_cache_collection_t) io_object)); } /* ------------------------------------------------------------------------ */ static cc_int32 ccs_cache_collection_list_object_compare_identifier (ccs_list_object_t in_cache_collection, cci_identifier_t in_identifier, cc_uint32 *out_equal) { return ccs_cache_collection_compare_identifier ((ccs_cache_collection_t) in_cache_collection, in_identifier, out_equal); } /* ------------------------------------------------------------------------ */ cc_int32 ccs_cache_collection_list_new (ccs_cache_collection_list_t *out_list) { return ccs_list_new (out_list, ccErrInvalidContext, ccErrInvalidContext, ccs_cache_collection_list_object_compare_identifier, ccs_cache_collection_list_object_release); } /* ------------------------------------------------------------------------ */ cc_int32 ccs_cache_collection_list_count (ccs_cache_collection_list_t in_list, cc_uint64 *out_count) { return ccs_list_count (in_list, out_count); } /* ------------------------------------------------------------------------ */ cc_int32 ccs_cache_collection_list_find (ccs_cache_collection_list_t in_list, cci_identifier_t in_identifier, ccs_cache_collection_t *out_cache_collection) { return ccs_list_find (in_list, in_identifier, (ccs_list_object_t *) out_cache_collection); } /* ------------------------------------------------------------------------ */ cc_int32 ccs_cache_collection_list_add (ccs_cache_collection_list_t io_list, ccs_cache_collection_t in_cache_collection) { return ccs_list_add (io_list, (ccs_list_object_t) in_cache_collection); } /* ------------------------------------------------------------------------ */ cc_int32 ccs_cache_collection_list_remove (ccs_cache_collection_list_t io_list, cci_identifier_t in_identifier) { return ccs_list_remove (io_list, in_identifier); } /* ------------------------------------------------------------------------ */ cc_int32 ccs_cache_collection_list_release (ccs_cache_collection_list_t io_list) { return ccs_list_release (io_list); } #ifdef TARGET_OS_MAC #pragma mark - #endif /* ------------------------------------------------------------------------ */ static cc_int32 ccs_ccache_list_object_release (ccs_list_object_t io_ccache) { return cci_check_error (ccs_ccache_release ((ccs_ccache_t) io_ccache)); } /* ------------------------------------------------------------------------ */ static cc_int32 ccs_ccache_list_object_compare_identifier (ccs_list_object_t in_ccache, cci_identifier_t in_identifier, cc_uint32 *out_equal) { return ccs_ccache_compare_identifier ((ccs_ccache_t) in_ccache, in_identifier, out_equal); } /* ------------------------------------------------------------------------ */ cc_int32 ccs_ccache_list_new (ccs_ccache_list_t *out_list) { return ccs_list_new (out_list, ccErrInvalidCCache, ccErrInvalidCCacheIterator, ccs_ccache_list_object_compare_identifier, ccs_ccache_list_object_release); } /* ------------------------------------------------------------------------ */ cc_int32 ccs_ccache_list_new_iterator (ccs_ccache_list_t in_list, ccs_pipe_t in_client_pipe, ccs_ccache_list_iterator_t *out_list_iterator) { return ccs_list_new_iterator (in_list, in_client_pipe, out_list_iterator); } /* ------------------------------------------------------------------------ */ cc_int32 ccs_ccache_list_count (ccs_ccache_list_t in_list, cc_uint64 *out_count) { return ccs_list_count (in_list, out_count); } /* ------------------------------------------------------------------------ */ cc_int32 ccs_ccache_list_find (ccs_ccache_list_t in_list, cci_identifier_t in_identifier, ccs_ccache_t *out_ccache) { return ccs_list_find (in_list, in_identifier, (ccs_list_object_t *) out_ccache); } /* ------------------------------------------------------------------------ */ cc_int32 ccs_ccache_list_find_iterator (ccs_ccache_list_t in_list, cci_identifier_t in_identifier, ccs_ccache_list_iterator_t *out_list_iterator) { return ccs_list_find_iterator (in_list, in_identifier, (ccs_list_iterator_t *) out_list_iterator); } /* ------------------------------------------------------------------------ */ cc_int32 ccs_ccache_list_add (ccs_ccache_list_t io_list, ccs_ccache_t in_ccache) { return ccs_list_add (io_list, (ccs_list_object_t) in_ccache); } /* ------------------------------------------------------------------------ */ cc_int32 ccs_ccache_list_remove (ccs_ccache_list_t io_list, cci_identifier_t in_identifier) { return ccs_list_remove (io_list, in_identifier); } /* ------------------------------------------------------------------------ */ cc_int32 ccs_ccache_list_push_front (ccs_ccache_list_t io_list, cci_identifier_t in_identifier) { return ccs_list_push_front (io_list, in_identifier); } /* ------------------------------------------------------------------------ */ cc_int32 ccs_ccache_list_release (ccs_ccache_list_t io_list) { return ccs_list_release (io_list); } /* ------------------------------------------------------------------------ */ cc_int32 ccs_ccache_list_iterator_write (ccs_ccache_list_iterator_t in_list_iterator, k5_ipc_stream in_stream) { return ccs_list_iterator_write (in_list_iterator, in_stream); } /* ------------------------------------------------------------------------ */ cc_int32 ccs_ccache_list_iterator_clone (ccs_ccache_list_iterator_t in_list_iterator, ccs_ccache_list_iterator_t *out_list_iterator) { return ccs_list_iterator_clone (in_list_iterator, out_list_iterator); } /* ------------------------------------------------------------------------ */ cc_int32 ccs_ccache_list_iterator_next (ccs_ccache_list_iterator_t io_list_iterator, ccs_ccache_t *out_ccache) { return ccs_list_iterator_next (io_list_iterator, (ccs_list_object_t *) out_ccache); } /* ------------------------------------------------------------------------ */ cc_int32 ccs_ccache_list_iterator_release (ccs_ccache_list_iterator_t io_list_iterator) { return ccs_list_iterator_release (io_list_iterator); } #ifdef TARGET_OS_MAC #pragma mark- #endif /* ------------------------------------------------------------------------ */ static cc_int32 ccs_credentials_list_object_release (ccs_list_object_t io_object) { return cci_check_error (ccs_credentials_release ((ccs_credentials_t) io_object)); } /* ------------------------------------------------------------------------ */ static cc_int32 ccs_credentials_list_object_compare_identifier (ccs_list_object_t in_credentials, cci_identifier_t in_identifier, cc_uint32 *out_equal) { return ccs_credentials_compare_identifier ((ccs_credentials_t) in_credentials, in_identifier, out_equal); } /* ------------------------------------------------------------------------ */ cc_int32 ccs_credentials_list_new (ccs_credentials_list_t *out_list) { return ccs_list_new (out_list, ccErrInvalidCredentials, ccErrInvalidCredentialsIterator, ccs_credentials_list_object_compare_identifier, ccs_credentials_list_object_release); } /* ------------------------------------------------------------------------ */ cc_int32 ccs_credentials_list_new_iterator (ccs_credentials_list_t in_list, ccs_pipe_t in_client_pipe, ccs_credentials_list_iterator_t *out_list_iterator) { return ccs_list_new_iterator (in_list, in_client_pipe, out_list_iterator); } /* ------------------------------------------------------------------------ */ cc_int32 ccs_credentials_list_count (ccs_credentials_list_t in_list, cc_uint64 *out_count) { return ccs_list_count (in_list, out_count); } /* ------------------------------------------------------------------------ */ cc_int32 ccs_credentials_list_find (ccs_credentials_list_t in_list, cci_identifier_t in_identifier, ccs_credentials_t *out_credentials) { return ccs_list_find (in_list, in_identifier, (ccs_list_object_t *) out_credentials); } /* ------------------------------------------------------------------------ */ cc_int32 ccs_credentials_list_find_iterator (ccs_credentials_list_t in_list, cci_identifier_t in_identifier, ccs_credentials_list_iterator_t *out_list_iterator) { return ccs_list_find_iterator (in_list, in_identifier, (ccs_list_iterator_t *) out_list_iterator); } /* ------------------------------------------------------------------------ */ cc_int32 ccs_credentials_list_add (ccs_credentials_list_t io_list, ccs_credentials_t in_credential) { return ccs_list_add (io_list, (ccs_list_object_t) in_credential); } /* ------------------------------------------------------------------------ */ cc_int32 ccs_credentials_list_remove (ccs_credentials_list_t io_list, cci_identifier_t in_identifier) { return ccs_list_remove (io_list, in_identifier); } /* ------------------------------------------------------------------------ */ cc_int32 ccs_credentials_list_release (ccs_credentials_list_t io_list) { return ccs_list_release (io_list); } /* ------------------------------------------------------------------------ */ cc_int32 ccs_credentials_list_iterator_write (ccs_credentials_list_iterator_t in_list_iterator, k5_ipc_stream in_stream) { return ccs_list_iterator_write (in_list_iterator, in_stream); } /* ------------------------------------------------------------------------ */ cc_int32 ccs_credentials_list_iterator_clone (ccs_credentials_list_iterator_t in_list_iterator, ccs_credentials_list_iterator_t *out_list_iterator) { return ccs_list_iterator_clone (in_list_iterator, out_list_iterator); } /* ------------------------------------------------------------------------ */ cc_int32 ccs_credentials_list_iterator_next (ccs_credentials_list_iterator_t io_list_iterator, ccs_credentials_t *out_credential) { return ccs_list_iterator_next (io_list_iterator, (ccs_list_object_t *) out_credential); } /* ------------------------------------------------------------------------ */ cc_int32 ccs_credentials_list_iterator_release (ccs_credentials_list_iterator_t io_list_iterator) { return ccs_list_iterator_release (io_list_iterator); } #ifdef TARGET_OS_MAC #pragma mark- #endif /* ------------------------------------------------------------------------ */ cc_int32 ccs_generic_list_iterator_invalidate (ccs_generic_list_iterator_t io_list_iterator) { return ccs_list_iterator_invalidate (io_list_iterator); } krb5-1.16/src/ccapi/server/ccs_server.h0000644000704600001450000000426613211554426017671 0ustar ghudsonlibuuid/* ccapi/server/ccs_server.h */ /* * Copyright 2006 Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #ifndef CCS_SERVER_H #define CCS_SERVER_H #include "ccs_types.h" cc_int32 ccs_server_new_identifier (cci_identifier_t *out_identifier); cc_int32 ccs_server_add_client (ccs_pipe_t in_connection_pipe); cc_int32 ccs_server_remove_client (ccs_pipe_t in_connection_pipe); cc_int32 ccs_server_client_for_pipe (ccs_pipe_t in_client_pipe, ccs_client_t *out_client); cc_int32 ccs_server_client_is_valid (ccs_pipe_t in_client_pipe, cc_uint32 *out_client_is_valid); cc_int32 ccs_server_handle_request (ccs_pipe_t in_client_pipe, ccs_pipe_t in_reply_pipe, k5_ipc_stream in_request); cc_int32 ccs_server_send_reply (ccs_pipe_t in_reply_pipe, cc_int32 in_reply_err, k5_ipc_stream in_reply_data); cc_uint64 ccs_server_client_count (); #endif /* CCS_SERVER_H */ krb5-1.16/src/ccapi/server/ccs_common.h0000644000704600001450000000324413211554426017646 0ustar ghudsonlibuuid/* ccapi/server/ccs_common.h */ /* * Copyright 2006 Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #ifndef CCS_COMMON_H #define CCS_COMMON_H #include "cci_common.h" #include #include "ccs_array.h" #include "ccs_list.h" #include "ccs_cache_collection.h" #include "ccs_ccache_iterator.h" #include "ccs_ccache.h" #include "ccs_credentials_iterator.h" #include "ccs_credentials.h" #include "ccs_lock.h" #include "ccs_lock_state.h" #include "ccs_pipe.h" #include "ccs_client.h" #include "ccs_callback.h" #include "ccs_server.h" #endif /* CCS_COMMON_H */ krb5-1.16/src/ccapi/server/ccs_cache_collection.c0000644000704600001450000011562413211554426021635 0ustar ghudsonlibuuid/* ccapi/server/ccs_cache_collection.c */ /* * Copyright 2006, 2007 Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #include "k5-platform.h" /* pull in asprintf decl/defn */ #include "ccs_common.h" #include "ccs_os_notify.h" struct ccs_cache_collection_d { cc_time_t last_changed_time; cc_uint64 next_unique_name; cci_identifier_t identifier; ccs_lock_state_t lock_state; ccs_ccache_list_t ccaches; ccs_callback_array_t change_callbacks; }; struct ccs_cache_collection_d ccs_cache_collection_initializer = { 0, 0, NULL, NULL, NULL, NULL }; /* ------------------------------------------------------------------------ */ cc_int32 ccs_cache_collection_new (ccs_cache_collection_t *out_cache_collection) { cc_int32 err = ccNoError; ccs_cache_collection_t cache_collection = NULL; if (!out_cache_collection) { err = cci_check_error (ccErrBadParam); } if (!err) { cache_collection = malloc (sizeof (*cache_collection)); if (cache_collection) { *cache_collection = ccs_cache_collection_initializer; } else { err = cci_check_error (ccErrNoMem); } } if (!err) { err = ccs_server_new_identifier (&cache_collection->identifier); } if (!err) { err = ccs_lock_state_new (&cache_collection->lock_state, ccErrInvalidContext, ccErrContextLocked, ccErrContextUnlocked); } if (!err) { err = ccs_ccache_list_new (&cache_collection->ccaches); } if (!err) { err = ccs_callback_array_new (&cache_collection->change_callbacks); } if (!err) { err = ccs_cache_collection_changed (cache_collection); } if (!err) { *out_cache_collection = cache_collection; cache_collection = NULL; } ccs_cache_collection_release (cache_collection); return cci_check_error (err); } /* ------------------------------------------------------------------------ */ cc_int32 ccs_cache_collection_release (ccs_cache_collection_t io_cache_collection) { cc_int32 err = ccNoError; if (!err && io_cache_collection) { cci_identifier_release (io_cache_collection->identifier); ccs_lock_state_release (io_cache_collection->lock_state); ccs_ccache_list_release (io_cache_collection->ccaches); ccs_callback_array_release (io_cache_collection->change_callbacks); free (io_cache_collection); } return cci_check_error (err); } /* ------------------------------------------------------------------------ */ cc_int32 ccs_cache_collection_compare_identifier (ccs_cache_collection_t in_cache_collection, cci_identifier_t in_identifier, cc_uint32 *out_equal) { cc_int32 err = ccNoError; if (!in_cache_collection) { err = cci_check_error (ccErrBadParam); } if (!in_identifier ) { err = cci_check_error (ccErrBadParam); } if (!out_equal ) { err = cci_check_error (ccErrBadParam); } if (!err) { err = cci_identifier_compare (in_cache_collection->identifier, in_identifier, out_equal); } return cci_check_error (err); } #ifdef TARGET_OS_MAC #pragma mark - #endif /* ------------------------------------------------------------------------ */ cc_int32 ccs_cache_collection_changed (ccs_cache_collection_t io_cache_collection) { cc_int32 err = ccNoError; k5_ipc_stream reply_data = NULL; if (!io_cache_collection) { err = cci_check_error (ccErrBadParam); } if (!err) { cc_time_t now = time (NULL); if (io_cache_collection->last_changed_time < now) { io_cache_collection->last_changed_time = now; } else { io_cache_collection->last_changed_time++; } } if (!err) { err = krb5int_ipc_stream_new (&reply_data); } if (!err) { err = krb5int_ipc_stream_write_time (reply_data, io_cache_collection->last_changed_time); } if (!err) { /* Loop over callbacks sending messages to them */ cc_uint64 i; cc_uint64 count = ccs_callback_array_count (io_cache_collection->change_callbacks); for (i = 0; !err && i < count; i++) { ccs_callback_t callback = ccs_callback_array_object_at_index (io_cache_collection->change_callbacks, i); err = ccs_callback_reply_to_client (callback, reply_data); if (!err) { cci_debug_printf ("%s: Removing callback reference %p.", __FUNCTION__, callback); err = ccs_callback_array_remove (io_cache_collection->change_callbacks, i); break; } } } if (!err) { err = ccs_os_notify_cache_collection_changed (io_cache_collection); } krb5int_ipc_stream_release (reply_data); return cci_check_error (err); } /* ------------------------------------------------------------------------ */ static cc_int32 ccs_cache_collection_invalidate_change_callback (ccs_callback_owner_t io_cache_collection, ccs_callback_t in_callback) { cc_int32 err = ccNoError; if (!io_cache_collection) { err = cci_check_error (ccErrBadParam); } if (!in_callback ) { err = cci_check_error (ccErrBadParam); } if (!err) { /* Remove callback */ ccs_cache_collection_t cache_collection = (ccs_cache_collection_t) io_cache_collection; cc_uint64 i; cc_uint64 count = ccs_callback_array_count (cache_collection->change_callbacks); for (i = 0; !err && i < count; i++) { ccs_callback_t callback = ccs_callback_array_object_at_index (cache_collection->change_callbacks, i); if (callback == in_callback) { cci_debug_printf ("%s: Removing callback reference %p.", __FUNCTION__, callback); err = ccs_callback_array_remove (cache_collection->change_callbacks, i); break; } } } return cci_check_error (err); } #ifdef TARGET_OS_MAC #pragma mark - #endif /* ------------------------------------------------------------------------ */ static cc_int32 ccs_cache_collection_find_ccache_by_name (ccs_cache_collection_t in_cache_collection, const char *in_name, ccs_ccache_t *out_ccache) { cc_int32 err = ccNoError; ccs_ccache_list_iterator_t iterator = NULL; if (!in_cache_collection) { err = cci_check_error (ccErrBadParam); } if (!in_name ) { err = cci_check_error (ccErrBadParam); } if (!out_ccache ) { err = cci_check_error (ccErrBadParam); } if (!err) { err = ccs_ccache_list_new_iterator (in_cache_collection->ccaches, CCS_PIPE_NULL, &iterator); } while (!err) { ccs_ccache_t ccache = NULL; err = ccs_ccache_list_iterator_next (iterator, &ccache); if (!err) { cc_uint32 equal = 0; err = ccs_ccache_compare_name (ccache, in_name, &equal); if (!err && equal) { *out_ccache = ccache; break; } } } if (err == ccIteratorEnd) { err = ccErrCCacheNotFound; } if (iterator) { ccs_ccache_list_iterator_release (iterator); } return cci_check_error (err); } #ifdef TARGET_OS_MAC #pragma mark - #endif /* ------------------------------------------------------------------------ */ cc_int32 ccs_cache_collection_find_ccache (ccs_cache_collection_t in_cache_collection, cci_identifier_t in_identifier, ccs_ccache_t *out_ccache) { cc_int32 err = ccNoError; if (!in_cache_collection) { err = cci_check_error (ccErrBadParam); } if (!in_identifier ) { err = cci_check_error (ccErrBadParam); } if (!out_ccache ) { err = cci_check_error (ccErrBadParam); } if (!err) { err = ccs_ccache_list_find (in_cache_collection->ccaches, in_identifier, out_ccache); } return cci_check_error (err); } /* ------------------------------------------------------------------------ */ cc_int32 ccs_ccache_collection_move_ccache (ccs_cache_collection_t io_cache_collection, cci_identifier_t in_source_identifier, ccs_ccache_t io_destination_ccache) { cc_int32 err = ccNoError; ccs_ccache_t source_ccache = NULL; if (!io_cache_collection ) { err = cci_check_error (ccErrBadParam); } if (!in_source_identifier ) { err = cci_check_error (ccErrBadParam); } if (!io_destination_ccache) { err = cci_check_error (ccErrBadParam); } if (!err) { err = ccs_cache_collection_find_ccache (io_cache_collection, in_source_identifier, &source_ccache); } if (!err) { err = ccs_ccache_swap_contents (source_ccache, io_destination_ccache, io_cache_collection); } if (!err) { err = ccs_cache_collection_destroy_ccache (io_cache_collection, in_source_identifier); } return cci_check_error (err); } /* ------------------------------------------------------------------------ */ cc_int32 ccs_cache_collection_destroy_ccache (ccs_cache_collection_t io_cache_collection, cci_identifier_t in_identifier) { cc_int32 err = ccNoError; ccs_ccache_t ccache = NULL; if (!io_cache_collection) { err = cci_check_error (ccErrBadParam); } if (!in_identifier ) { err = cci_check_error (ccErrBadParam); } if (!err) { err = ccs_cache_collection_find_ccache (io_cache_collection, in_identifier, &ccache); } if (!err) { /* Notify before deletion because after deletion the ccache * will no longer exist (and won't know about its clients) */ err = ccs_ccache_changed (ccache, io_cache_collection); } if (!err) { err = ccs_ccache_list_remove (io_cache_collection->ccaches, in_identifier); } return cci_check_error (err); } #ifdef TARGET_OS_MAC #pragma mark - #endif /* ------------------------------------------------------------------------ */ cc_int32 ccs_cache_collection_find_ccache_iterator (ccs_cache_collection_t in_cache_collection, cci_identifier_t in_identifier, ccs_ccache_iterator_t *out_ccache_iterator) { cc_int32 err = ccNoError; if (!in_cache_collection) { err = cci_check_error (ccErrBadParam); } if (!in_identifier ) { err = cci_check_error (ccErrBadParam); } if (!out_ccache_iterator) { err = cci_check_error (ccErrBadParam); } if (!err) { err = ccs_ccache_list_find_iterator (in_cache_collection->ccaches, in_identifier, out_ccache_iterator); } return cci_check_error (err); } #ifdef TARGET_OS_MAC #pragma mark - #endif /* ------------------------------------------------------------------------ */ cc_int32 ccs_cache_collection_find_credentials_iterator (ccs_cache_collection_t in_cache_collection, cci_identifier_t in_identifier, ccs_ccache_t *out_ccache, ccs_credentials_iterator_t *out_credentials_iterator) { cc_int32 err = ccNoError; ccs_ccache_list_iterator_t iterator = NULL; if (!in_cache_collection ) { err = cci_check_error (ccErrBadParam); } if (!in_identifier ) { err = cci_check_error (ccErrBadParam); } if (!out_credentials_iterator) { err = cci_check_error (ccErrBadParam); } if (!err) { err = ccs_ccache_list_new_iterator (in_cache_collection->ccaches, CCS_PIPE_NULL, &iterator); } while (!err) { ccs_ccache_t ccache = NULL; err = ccs_ccache_list_iterator_next (iterator, &ccache); if (!err) { cc_int32 terr = ccs_ccache_find_credentials_iterator (ccache, in_identifier, out_credentials_iterator); if (!terr) { *out_ccache = ccache; break; } } } if (err == ccIteratorEnd) { err = cci_check_error (ccErrInvalidCredentialsIterator); } if (iterator) { ccs_ccache_list_iterator_release (iterator); } return cci_check_error (err); } #ifdef TARGET_OS_MAC #pragma mark - #endif /* ------------------------------------------------------------------------ */ static cc_int32 ccs_cache_collection_get_next_unique_ccache_name (ccs_cache_collection_t io_cache_collection, char **out_name) { cc_int32 err = ccNoError; cc_uint64 count = 0; char *name = NULL; if (!io_cache_collection) { err = cci_check_error (ccErrBadParam); } if (!out_name ) { err = cci_check_error (ccErrBadParam); } if (!err) { err = ccs_cache_collection_list_count (io_cache_collection->ccaches, &count); } if (!err) { if (count > 0) { while (!err) { int ret = asprintf (&name, "%lld", io_cache_collection->next_unique_name++); if (ret < 0 || !name) { err = cci_check_error (ccErrNoMem); } if (!err) { ccs_ccache_t ccache = NULL; /* temporary to hold ccache pointer */ err = ccs_cache_collection_find_ccache_by_name (io_cache_collection, name, &ccache); } if (err == ccErrCCacheNotFound) { err = ccNoError; break; /* found a unique one */ } } } else { name = strdup (k_cci_context_initial_ccache_name); if (!name) { err = cci_check_error (ccErrNoMem); } } } if (!err) { *out_name = name; name = NULL; } free (name); return cci_check_error (err); } /* ------------------------------------------------------------------------ */ static cc_int32 ccs_cache_collection_get_default_ccache (ccs_cache_collection_t in_cache_collection, ccs_ccache_t *out_ccache) { cc_int32 err = ccNoError; cc_uint64 count = 0; if (!in_cache_collection) { err = cci_check_error (ccErrBadParam); } if (!out_ccache ) { err = cci_check_error (ccErrBadParam); } if (!err) { err = ccs_ccache_list_count (in_cache_collection->ccaches, &count); } if (!err) { if (count > 0) { /* First ccache is the default */ ccs_ccache_list_iterator_t iterator = NULL; err = ccs_ccache_list_new_iterator (in_cache_collection->ccaches, CCS_PIPE_NULL, &iterator); if (!err) { err = ccs_ccache_list_iterator_next (iterator, out_ccache); } ccs_ccache_list_iterator_release (iterator); } else { err = cci_check_error (ccErrCCacheNotFound); } } return cci_check_error (err); } /* ------------------------------------------------------------------------ */ cc_int32 ccs_cache_collection_set_default_ccache (ccs_cache_collection_t io_cache_collection, cci_identifier_t in_identifier) { cc_int32 err = ccNoError; ccs_ccache_t old_default = NULL; ccs_ccache_t new_default = NULL; cc_uint32 equal = 0; if (!io_cache_collection) { err = cci_check_error (ccErrBadParam); } if (!in_identifier ) { err = cci_check_error (ccErrBadParam); } if (!err) { err = ccs_cache_collection_get_default_ccache (io_cache_collection, &old_default); } if (!err) { err = ccs_ccache_compare_identifier (old_default, in_identifier, &equal); } if (!err && !equal) { err = ccs_ccache_list_push_front (io_cache_collection->ccaches, in_identifier); if (!err) { err = ccs_ccache_notify_default_state_changed (old_default, io_cache_collection, 0 /* no longer default */); } if (!err) { err = ccs_cache_collection_get_default_ccache (io_cache_collection, &new_default); } if (!err) { err = ccs_ccache_notify_default_state_changed (new_default, io_cache_collection, 1 /* now default */); } if (!err) { err = ccs_cache_collection_changed (io_cache_collection); } } return cci_check_error (err); } #ifdef TARGET_OS_MAC #pragma mark - #pragma mark -- IPC Messages -- #endif /* ------------------------------------------------------------------------ */ static cc_int32 ccs_cache_collection_sync (ccs_cache_collection_t io_cache_collection, k5_ipc_stream in_request_data, k5_ipc_stream io_reply_data) { cc_int32 err = ccNoError; if (!io_cache_collection) { err = cci_check_error (ccErrBadParam); } if (!in_request_data ) { err = cci_check_error (ccErrBadParam); } if (!io_reply_data ) { err = cci_check_error (ccErrBadParam); } if (!err) { err = cci_identifier_write (io_cache_collection->identifier, io_reply_data); } return cci_check_error (err); } /* ------------------------------------------------------------------------ */ static cc_int32 ccs_cache_collection_get_change_time (ccs_cache_collection_t io_cache_collection, k5_ipc_stream in_request_data, k5_ipc_stream io_reply_data) { cc_int32 err = ccNoError; if (!io_cache_collection) { err = cci_check_error (ccErrBadParam); } if (!in_request_data ) { err = cci_check_error (ccErrBadParam); } if (!io_reply_data ) { err = cci_check_error (ccErrBadParam); } if (!err) { err = krb5int_ipc_stream_write_time (io_reply_data, io_cache_collection->last_changed_time); } return cci_check_error (err); } /* ------------------------------------------------------------------------ */ static cc_int32 ccs_cache_collection_wait_for_change (ccs_pipe_t in_client_pipe, ccs_pipe_t in_reply_pipe, ccs_cache_collection_t io_cache_collection, k5_ipc_stream in_request_data, k5_ipc_stream io_reply_data, cc_uint32 *out_will_block) { cc_int32 err = ccNoError; cc_time_t last_wait_for_change_time = 0; cc_uint32 will_block = 0; if (!ccs_pipe_valid (in_client_pipe)) { err = cci_check_error (ccErrBadParam); } if (!ccs_pipe_valid (in_reply_pipe )) { err = cci_check_error (ccErrBadParam); } if (!io_cache_collection ) { err = cci_check_error (ccErrBadParam); } if (!in_request_data ) { err = cci_check_error (ccErrBadParam); } if (!out_will_block ) { err = cci_check_error (ccErrBadParam); } if (!err) { err = krb5int_ipc_stream_read_time (in_request_data, &last_wait_for_change_time); } if (!err) { if (last_wait_for_change_time < io_cache_collection->last_changed_time) { err = krb5int_ipc_stream_write_time (io_reply_data, io_cache_collection->last_changed_time); } else { ccs_callback_t callback = NULL; err = ccs_callback_new (&callback, ccErrInvalidContext, in_client_pipe, in_reply_pipe, (ccs_callback_owner_t) io_cache_collection, ccs_cache_collection_invalidate_change_callback); if (!err) { err = ccs_callback_array_insert (io_cache_collection->change_callbacks, callback, ccs_callback_array_count (io_cache_collection->change_callbacks)); if (!err) { callback = NULL; /* take ownership */ } will_block = 1; } ccs_callback_release (callback); } } if (!err) { *out_will_block = will_block; } return cci_check_error (err); } /* ------------------------------------------------------------------------ */ static cc_int32 ccs_cache_collection_get_default_ccache_name (ccs_cache_collection_t io_cache_collection, k5_ipc_stream in_request_data, k5_ipc_stream io_reply_data) { cc_int32 err = ccNoError; cc_uint64 count = 0; if (!io_cache_collection) { err = cci_check_error (ccErrBadParam); } if (!in_request_data ) { err = cci_check_error (ccErrBadParam); } if (!io_reply_data ) { err = cci_check_error (ccErrBadParam); } if (!err) { err = ccs_cache_collection_list_count (io_cache_collection->ccaches, &count); } if (!err) { if (count > 0) { ccs_ccache_t ccache = NULL; err = ccs_cache_collection_get_default_ccache (io_cache_collection, &ccache); if (!err) { err = ccs_ccache_write_name (ccache, io_reply_data); } } else { err = krb5int_ipc_stream_write_string (io_reply_data, k_cci_context_initial_ccache_name); } } return cci_check_error (err); } /* ------------------------------------------------------------------------ */ static cc_int32 ccs_cache_collection_open_ccache (ccs_cache_collection_t io_cache_collection, k5_ipc_stream in_request_data, k5_ipc_stream io_reply_data) { cc_int32 err = ccNoError; char *name = NULL; ccs_ccache_t ccache = NULL; if (!io_cache_collection) { err = cci_check_error (ccErrBadParam); } if (!in_request_data ) { err = cci_check_error (ccErrBadParam); } if (!io_reply_data ) { err = cci_check_error (ccErrBadParam); } if (!err) { err = krb5int_ipc_stream_read_string (in_request_data, &name); } if (!err) { err = ccs_cache_collection_find_ccache_by_name (io_cache_collection, name, &ccache); } if (!err) { err = ccs_ccache_write (ccache, io_reply_data); } krb5int_ipc_stream_free_string (name); return cci_check_error (err); } /* ------------------------------------------------------------------------ */ static cc_int32 ccs_cache_collection_open_default_ccache (ccs_cache_collection_t io_cache_collection, k5_ipc_stream in_request_data, k5_ipc_stream io_reply_data) { cc_int32 err = ccNoError; ccs_ccache_t ccache = NULL; if (!io_cache_collection) { err = cci_check_error (ccErrBadParam); } if (!in_request_data ) { err = cci_check_error (ccErrBadParam); } if (!io_reply_data ) { err = cci_check_error (ccErrBadParam); } if (!err) { err = ccs_cache_collection_get_default_ccache (io_cache_collection, &ccache); } if (!err) { err = ccs_ccache_write (ccache, io_reply_data); } return cci_check_error (err); } /* ------------------------------------------------------------------------ */ static cc_int32 ccs_cache_collection_create_ccache (ccs_cache_collection_t io_cache_collection, k5_ipc_stream in_request_data, k5_ipc_stream io_reply_data) { cc_int32 err = ccNoError; char *name = NULL; cc_uint32 cred_vers; char *principal = NULL; ccs_ccache_t ccache = NULL; if (!io_cache_collection) { err = cci_check_error (ccErrBadParam); } if (!in_request_data ) { err = cci_check_error (ccErrBadParam); } if (!io_reply_data ) { err = cci_check_error (ccErrBadParam); } if (!err) { err = krb5int_ipc_stream_read_string (in_request_data, &name); } if (!err) { err = krb5int_ipc_stream_read_uint32 (in_request_data, &cred_vers); } if (!err) { err = krb5int_ipc_stream_read_string (in_request_data, &principal); } if (!err) { cc_int32 terr = ccs_cache_collection_find_ccache_by_name (io_cache_collection, name, &ccache); if (!terr) { err = ccs_ccache_reset (ccache, io_cache_collection, cred_vers, principal); } else { err = ccs_ccache_new (&ccache, cred_vers, name, principal, io_cache_collection->ccaches); } } if (!err) { err = ccs_ccache_write (ccache, io_reply_data); } if (!err) { err = ccs_cache_collection_changed (io_cache_collection); } krb5int_ipc_stream_free_string (name); krb5int_ipc_stream_free_string (principal); return cci_check_error (err); } /* ------------------------------------------------------------------------ */ static cc_int32 ccs_cache_collection_create_default_ccache (ccs_cache_collection_t io_cache_collection, k5_ipc_stream in_request_data, k5_ipc_stream io_reply_data) { cc_int32 err = ccNoError; cc_uint32 cred_vers; char *principal = NULL; ccs_ccache_t ccache = NULL; if (!io_cache_collection) { err = cci_check_error (ccErrBadParam); } if (!in_request_data ) { err = cci_check_error (ccErrBadParam); } if (!io_reply_data ) { err = cci_check_error (ccErrBadParam); } if (!err) { err = krb5int_ipc_stream_read_uint32 (in_request_data, &cred_vers); } if (!err) { err = krb5int_ipc_stream_read_string (in_request_data, &principal); } if (!err) { err = ccs_cache_collection_get_default_ccache (io_cache_collection, &ccache); if (!err) { err = ccs_ccache_reset (ccache, io_cache_collection, cred_vers, principal); } else if (err == ccErrCCacheNotFound) { char *name = NULL; err = ccs_cache_collection_get_next_unique_ccache_name (io_cache_collection, &name); if (!err) { err = ccs_ccache_new (&ccache, cred_vers, name, principal, io_cache_collection->ccaches); } free (name); } } if (!err) { err = ccs_ccache_write (ccache, io_reply_data); } if (!err) { err = ccs_cache_collection_changed (io_cache_collection); } krb5int_ipc_stream_free_string (principal); return cci_check_error (err); } /* ------------------------------------------------------------------------ */ static cc_int32 ccs_cache_collection_create_new_ccache (ccs_cache_collection_t io_cache_collection, k5_ipc_stream in_request_data, k5_ipc_stream io_reply_data) { cc_int32 err = ccNoError; cc_uint32 cred_vers; char *principal = NULL; char *name = NULL; ccs_ccache_t ccache = NULL; if (!io_cache_collection) { err = cci_check_error (ccErrBadParam); } if (!in_request_data ) { err = cci_check_error (ccErrBadParam); } if (!io_reply_data ) { err = cci_check_error (ccErrBadParam); } if (!err) { err = krb5int_ipc_stream_read_uint32 (in_request_data, &cred_vers); } if (!err) { err = krb5int_ipc_stream_read_string (in_request_data, &principal); } if (!err) { err = ccs_cache_collection_get_next_unique_ccache_name (io_cache_collection, &name); } if (!err) { err = ccs_ccache_new (&ccache, cred_vers, name, principal, io_cache_collection->ccaches); } if (!err) { err = ccs_ccache_write (ccache, io_reply_data); } if (!err) { err = ccs_cache_collection_changed (io_cache_collection); } free (name); krb5int_ipc_stream_free_string (principal); return cci_check_error (err); } /* ------------------------------------------------------------------------ */ static cc_int32 ccs_cache_collection_new_ccache_iterator (ccs_cache_collection_t io_cache_collection, ccs_pipe_t in_client_pipe, k5_ipc_stream in_request_data, k5_ipc_stream io_reply_data) { cc_int32 err = ccNoError; ccs_ccache_iterator_t ccache_iterator = NULL; if (!io_cache_collection) { err = cci_check_error (ccErrBadParam); } if (!in_request_data ) { err = cci_check_error (ccErrBadParam); } if (!io_reply_data ) { err = cci_check_error (ccErrBadParam); } if (!err) { err = ccs_ccache_list_new_iterator (io_cache_collection->ccaches, in_client_pipe, &ccache_iterator); } if (!err) { err = ccs_ccache_list_iterator_write (ccache_iterator, io_reply_data); } return cci_check_error (err); } /* ------------------------------------------------------------------------ */ static cc_int32 ccs_cache_collection_lock (ccs_pipe_t in_client_pipe, ccs_pipe_t in_reply_pipe, ccs_cache_collection_t io_cache_collection, k5_ipc_stream in_request_data, cc_uint32 *out_will_block, k5_ipc_stream io_reply_data) { cc_int32 err = ccNoError; cc_uint32 lock_type; cc_uint32 block; if (!ccs_pipe_valid (in_client_pipe)) { err = cci_check_error (ccErrBadParam); } if (!io_cache_collection ) { err = cci_check_error (ccErrBadParam); } if (!in_request_data ) { err = cci_check_error (ccErrBadParam); } if (!out_will_block ) { err = cci_check_error (ccErrBadParam); } if (!io_reply_data ) { err = cci_check_error (ccErrBadParam); } if (!err) { err = krb5int_ipc_stream_read_uint32 (in_request_data, &lock_type); } if (!err) { err = krb5int_ipc_stream_read_uint32 (in_request_data, &block); } if (!err) { err = ccs_lock_state_add (io_cache_collection->lock_state, in_client_pipe, in_reply_pipe, lock_type, block, out_will_block); } return cci_check_error (err); } /* ------------------------------------------------------------------------ */ static cc_int32 ccs_cache_collection_unlock (ccs_pipe_t in_client_pipe, ccs_cache_collection_t io_cache_collection, k5_ipc_stream in_request_data, k5_ipc_stream io_reply_data) { cc_int32 err = ccNoError; if (!ccs_pipe_valid (in_client_pipe)) { err = cci_check_error (ccErrBadParam); } if (!io_cache_collection ) { err = cci_check_error (ccErrBadParam); } if (!in_request_data ) { err = cci_check_error (ccErrBadParam); } if (!io_reply_data ) { err = cci_check_error (ccErrBadParam); } if (!err) { err = ccs_lock_state_remove (io_cache_collection->lock_state, in_client_pipe); } return cci_check_error (err); } #ifdef TARGET_OS_MAC #pragma mark - #endif /* ------------------------------------------------------------------------ */ cc_int32 ccs_cache_collection_handle_message (ccs_pipe_t in_client_pipe, ccs_pipe_t in_reply_pipe, ccs_cache_collection_t io_cache_collection, enum cci_msg_id_t in_request_name, k5_ipc_stream in_request_data, cc_uint32 *out_will_block, k5_ipc_stream *out_reply_data) { cc_int32 err = ccNoError; cc_uint32 will_block = 0; k5_ipc_stream reply_data = NULL; if (!ccs_pipe_valid (in_client_pipe)) { err = cci_check_error (ccErrBadParam); } if (!ccs_pipe_valid (in_reply_pipe) ) { err = cci_check_error (ccErrBadParam); } if (!io_cache_collection ) { err = cci_check_error (ccErrBadParam); } if (!in_request_data ) { err = cci_check_error (ccErrBadParam); } if (!out_will_block ) { err = cci_check_error (ccErrBadParam); } if (!out_reply_data ) { err = cci_check_error (ccErrBadParam); } if (!err) { err = krb5int_ipc_stream_new (&reply_data); } if (!err) { if (in_request_name == cci_context_unused_release_msg_id) { /* Old release message. Do nothing. */ } else if (in_request_name == cci_context_sync_msg_id) { err = ccs_cache_collection_sync (io_cache_collection, in_request_data, reply_data); } else if (in_request_name == cci_context_get_change_time_msg_id) { err = ccs_cache_collection_get_change_time (io_cache_collection, in_request_data, reply_data); } else if (in_request_name == cci_context_wait_for_change_msg_id) { err = ccs_cache_collection_wait_for_change (in_client_pipe, in_reply_pipe, io_cache_collection, in_request_data, reply_data, &will_block); } else if (in_request_name == cci_context_get_default_ccache_name_msg_id) { err = ccs_cache_collection_get_default_ccache_name (io_cache_collection, in_request_data, reply_data); } else if (in_request_name == cci_context_open_ccache_msg_id) { err = ccs_cache_collection_open_ccache (io_cache_collection, in_request_data, reply_data); } else if (in_request_name == cci_context_open_default_ccache_msg_id) { err = ccs_cache_collection_open_default_ccache (io_cache_collection, in_request_data, reply_data); } else if (in_request_name == cci_context_create_ccache_msg_id) { err = ccs_cache_collection_create_ccache (io_cache_collection, in_request_data, reply_data); } else if (in_request_name == cci_context_create_default_ccache_msg_id) { err = ccs_cache_collection_create_default_ccache (io_cache_collection, in_request_data, reply_data); } else if (in_request_name == cci_context_create_new_ccache_msg_id) { err = ccs_cache_collection_create_new_ccache (io_cache_collection, in_request_data, reply_data); } else if (in_request_name == cci_context_new_ccache_iterator_msg_id) { err = ccs_cache_collection_new_ccache_iterator (io_cache_collection, in_client_pipe, in_request_data, reply_data); } else if (in_request_name == cci_context_lock_msg_id) { err = ccs_cache_collection_lock (in_client_pipe, in_reply_pipe, io_cache_collection, in_request_data, &will_block, reply_data); } else if (in_request_name == cci_context_unlock_msg_id) { err = ccs_cache_collection_unlock (in_client_pipe, io_cache_collection, in_request_data, reply_data); } else { err = ccErrBadInternalMessage; } } if (!err) { *out_will_block = will_block; if (!will_block) { *out_reply_data = reply_data; reply_data = NULL; /* take ownership */ } else { *out_reply_data = NULL; } } krb5int_ipc_stream_release (reply_data); return cci_check_error (err); } krb5-1.16/src/ccapi/server/ccs_credentials_iterator.c0000644000704600001450000001462613211554426022565 0ustar ghudsonlibuuid/* ccapi/server/ccs_credentials_iterator.c */ /* * Copyright 2006, 2007 Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #include "ccs_common.h" /* ------------------------------------------------------------------------ */ static cc_int32 ccs_credentials_iterator_release (ccs_credentials_iterator_t io_credentials_iterator, ccs_ccache_t io_ccache, k5_ipc_stream in_request_data, k5_ipc_stream io_reply_data) { cc_int32 err = ccNoError; if (!io_credentials_iterator) { err = cci_check_error (ccErrBadParam); } if (!io_ccache ) { err = cci_check_error (ccErrBadParam); } if (!in_request_data ) { err = cci_check_error (ccErrBadParam); } if (!io_reply_data ) { err = cci_check_error (ccErrBadParam); } if (!err) { err = ccs_credentials_list_iterator_release (io_credentials_iterator); } return cci_check_error (err); } /* ------------------------------------------------------------------------ */ static cc_int32 ccs_credentials_iterator_next (ccs_credentials_iterator_t io_credentials_iterator, ccs_ccache_t io_ccache, k5_ipc_stream in_request_data, k5_ipc_stream io_reply_data) { cc_int32 err = ccNoError; ccs_credentials_t credentials = NULL; if (!io_credentials_iterator) { err = cci_check_error (ccErrBadParam); } if (!io_ccache ) { err = cci_check_error (ccErrBadParam); } if (!in_request_data ) { err = cci_check_error (ccErrBadParam); } if (!io_reply_data ) { err = cci_check_error (ccErrBadParam); } if (!err) { err = ccs_credentials_list_iterator_next (io_credentials_iterator, &credentials); } if (!err) { err = ccs_credentials_write (credentials, io_reply_data); } return cci_check_error (err); } /* ------------------------------------------------------------------------ */ static cc_int32 ccs_credentials_iterator_clone (ccs_credentials_iterator_t io_credentials_iterator, ccs_ccache_t io_ccache, k5_ipc_stream in_request_data, k5_ipc_stream io_reply_data) { cc_int32 err = ccNoError; ccs_credentials_iterator_t credentials_iterator = NULL; if (!io_credentials_iterator) { err = cci_check_error (ccErrBadParam); } if (!io_ccache ) { err = cci_check_error (ccErrBadParam); } if (!in_request_data ) { err = cci_check_error (ccErrBadParam); } if (!io_reply_data ) { err = cci_check_error (ccErrBadParam); } if (!err) { err = ccs_credentials_list_iterator_clone (io_credentials_iterator, &credentials_iterator); } if (!err) { err = ccs_credentials_list_iterator_write (credentials_iterator, io_reply_data); } return cci_check_error (err); } #ifdef TARGET_OS_MAC #pragma mark - #endif /* ------------------------------------------------------------------------ */ cc_int32 ccs_credentials_iterator_handle_message (ccs_credentials_iterator_t io_credentials_iterator, ccs_ccache_t io_ccache, enum cci_msg_id_t in_request_name, k5_ipc_stream in_request_data, k5_ipc_stream *out_reply_data) { cc_int32 err = ccNoError; k5_ipc_stream reply_data = NULL; if (!in_request_data) { err = cci_check_error (ccErrBadParam); } if (!out_reply_data ) { err = cci_check_error (ccErrBadParam); } if (!err) { err = krb5int_ipc_stream_new (&reply_data); } if (!err) { if (in_request_name == cci_credentials_iterator_release_msg_id) { err = ccs_credentials_iterator_release (io_credentials_iterator, io_ccache, in_request_data, reply_data); } else if (in_request_name == cci_credentials_iterator_next_msg_id) { err = ccs_credentials_iterator_next (io_credentials_iterator, io_ccache, in_request_data, reply_data); } else if (in_request_name == cci_credentials_iterator_clone_msg_id) { err = ccs_credentials_iterator_clone (io_credentials_iterator, io_ccache, in_request_data, reply_data); } else { err = ccErrBadInternalMessage; } } if (!err) { *out_reply_data = reply_data; reply_data = NULL; /* take ownership */ } krb5int_ipc_stream_release (reply_data); return cci_check_error (err); } krb5-1.16/src/ccapi/server/ccs_lock_state.h0000644000704600001450000000442713211554426020512 0ustar ghudsonlibuuid/* ccapi/server/ccs_lock_state.h */ /* * Copyright 2006 Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #ifndef CCS_LOCK_STATE_H #define CCS_LOCK_STATE_H #include "ccs_types.h" cc_int32 ccs_lock_state_new (ccs_lock_state_t *out_lock_state, cc_int32 in_invalid_object_err, cc_int32 in_pending_lock_err, cc_int32 in_no_lock_err); cc_int32 ccs_lock_state_release (ccs_lock_state_t io_lock_state); cc_int32 ccs_lock_state_add (ccs_lock_state_t io_lock_state, ccs_pipe_t in_client_pipe, ccs_pipe_t in_reply_pipe, cc_uint32 in_lock_type, cc_uint32 in_block, cc_uint32 *out_will_send_reply); cc_int32 ccs_lock_state_remove (ccs_lock_state_t io_lock_state, ccs_pipe_t in_client_pipe); cc_int32 ccs_lock_state_invalidate_lock (ccs_lock_state_t io_lock_state, ccs_lock_t in_lock); #endif /* CCS_LOCK_STATE_H */ krb5-1.16/src/ccapi/server/ccs_server.c0000644000704600001450000003472613211554426017670 0ustar ghudsonlibuuid/* ccapi/server/ccs_server.c */ /* * Copyright 2006, 2007 Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #include "ccs_common.h" #include "ccs_os_server.h" /* Server Globals: */ cci_uuid_string_t g_server_id = NULL; ccs_cache_collection_t g_cache_collection = NULL; ccs_client_array_t g_client_array = NULL; /* ------------------------------------------------------------------------ */ int main (int argc, const char *argv[]) { cc_int32 err = 0; if (!err) { err = ccs_os_server_initialize (argc, argv); } if (!err) { err = cci_identifier_new_uuid (&g_server_id); } if (!err) { err = ccs_cache_collection_new (&g_cache_collection); } if (!err) { err = ccs_client_array_new (&g_client_array); } if (!err) { err = ccs_os_server_listen_loop (argc, argv); } if (!err) { free (g_server_id); cci_check_error (ccs_cache_collection_release (g_cache_collection)); cci_check_error (ccs_client_array_release (g_client_array)); err = ccs_os_server_cleanup (argc, argv); } return cci_check_error (err) ? 1 : 0; } #ifdef TARGET_OS_MAC #pragma mark - #endif /* ------------------------------------------------------------------------ */ cc_int32 ccs_server_new_identifier (cci_identifier_t *out_identifier) { return cci_check_error (cci_identifier_new (out_identifier, g_server_id)); } #ifdef TARGET_OS_MAC #pragma mark - #endif /* ------------------------------------------------------------------------ */ cc_int32 ccs_server_add_client (ccs_pipe_t in_connection_pipe) { cc_int32 err = ccNoError; ccs_client_t client = NULL; if (!err) { err = ccs_client_new (&client, in_connection_pipe); } if (!err) { cci_debug_printf ("%s: Adding client %p.", __FUNCTION__, client); err = ccs_client_array_insert (g_client_array, client, ccs_client_array_count (g_client_array)); } return cci_check_error (err); } /* ------------------------------------------------------------------------ */ cc_int32 ccs_server_remove_client (ccs_pipe_t in_connection_pipe) { cc_int32 err = ccNoError; if (!err) { cc_uint64 i; cc_uint64 count = ccs_client_array_count (g_client_array); cc_uint32 found = 0; for (i = 0; !err && i < count; i++) { ccs_client_t client = ccs_client_array_object_at_index (g_client_array, i); err = ccs_client_uses_pipe (client, in_connection_pipe, &found); if (!err && found) { cci_debug_printf ("%s: Removing client %p.", __FUNCTION__, client); err = ccs_client_array_remove (g_client_array, i); break; } } if (!err && !found) { cci_debug_printf ("WARNING %s() didn't find client in client list.", __FUNCTION__); } } return cci_check_error (err); } /* ------------------------------------------------------------------------ */ cc_int32 ccs_server_client_for_pipe (ccs_pipe_t in_client_pipe, ccs_client_t *out_client) { cc_int32 err = ccNoError; ccs_client_t client_for_pipe = NULL; if (!ccs_pipe_valid (in_client_pipe)) { err = cci_check_error (ccErrBadParam); } if (!out_client ) { err = cci_check_error (ccErrBadParam); } if (!err) { cc_uint64 i; cc_uint64 count = ccs_client_array_count (g_client_array); for (i = 0; !err && i < count; i++) { ccs_client_t client = ccs_client_array_object_at_index (g_client_array, i); cc_uint32 uses_pipe = 0; err = ccs_client_uses_pipe (client, in_client_pipe, &uses_pipe); if (!err && uses_pipe) { client_for_pipe = client; break; } } } if (!err) { *out_client = client_for_pipe; /* may be NULL if not found */ } return cci_check_error (err); } /* ------------------------------------------------------------------------ */ cc_int32 ccs_server_client_is_valid (ccs_pipe_t in_client_pipe, cc_uint32 *out_client_is_valid) { cc_int32 err = ccNoError; ccs_client_t client = NULL; if (!ccs_pipe_valid (in_client_pipe)) { err = cci_check_error (ccErrBadParam); } if (!out_client_is_valid ) { err = cci_check_error (ccErrBadParam); } if (!err) { err = ccs_server_client_for_pipe (in_client_pipe, &client); } if (!err) { *out_client_is_valid = (client != NULL); } return cci_check_error (err); } #ifdef TARGET_OS_MAC #pragma mark - #endif /* ------------------------------------------------------------------------ */ static cc_int32 ccs_server_request_demux (ccs_pipe_t in_client_pipe, ccs_pipe_t in_reply_pipe, ccs_cache_collection_t in_cache_collection, enum cci_msg_id_t in_request_name, cci_identifier_t in_request_identifier, k5_ipc_stream in_request_data, cc_uint32 *out_will_block, k5_ipc_stream *out_reply_data) { cc_int32 err = ccNoError; if (!ccs_pipe_valid (in_reply_pipe)) { err = cci_check_error (ccErrBadParam); } if (!in_request_data ) { err = cci_check_error (ccErrBadParam); } if (!out_will_block ) { err = cci_check_error (ccErrBadParam); } if (!out_reply_data ) { err = cci_check_error (ccErrBadParam); } if (!err) { if (in_request_name > cci_context_first_msg_id && in_request_name < cci_context_last_msg_id) { /* Note: context identifier doesn't need to match. * Client just uses the identifier to detect server relaunch. */ if (!err) { err = ccs_cache_collection_handle_message (in_client_pipe, in_reply_pipe, in_cache_collection, in_request_name, in_request_data, out_will_block, out_reply_data); } } else if (in_request_name > cci_ccache_first_msg_id && in_request_name < cci_ccache_last_msg_id) { ccs_ccache_t ccache = NULL; err = ccs_cache_collection_find_ccache (in_cache_collection, in_request_identifier, &ccache); if (!err) { err = ccs_ccache_handle_message (in_client_pipe, in_reply_pipe, ccache, in_cache_collection, in_request_name, in_request_data, out_will_block, out_reply_data); } } else if (in_request_name > cci_ccache_iterator_first_msg_id && in_request_name < cci_ccache_iterator_last_msg_id) { ccs_ccache_iterator_t ccache_iterator = NULL; err = ccs_cache_collection_find_ccache_iterator (in_cache_collection, in_request_identifier, &ccache_iterator); if (!err) { err = ccs_ccache_iterator_handle_message (ccache_iterator, in_cache_collection, in_request_name, in_request_data, out_reply_data); } if (!err) { *out_will_block = 0; /* can't block */ } } else if (in_request_name > cci_credentials_iterator_first_msg_id && in_request_name < cci_credentials_iterator_last_msg_id) { ccs_credentials_iterator_t credentials_iterator = NULL; ccs_ccache_t ccache = NULL; err = ccs_cache_collection_find_credentials_iterator (in_cache_collection, in_request_identifier, &ccache, &credentials_iterator); if (!err) { err = ccs_credentials_iterator_handle_message (credentials_iterator, ccache, in_request_name, in_request_data, out_reply_data); } if (!err) { *out_will_block = 0; /* can't block */ } } else { err = ccErrBadInternalMessage; } } return cci_check_error (err); } #ifdef TARGET_OS_MAC #pragma mark - #endif /* ------------------------------------------------------------------------ */ cc_int32 ccs_server_handle_request (ccs_pipe_t in_client_pipe, ccs_pipe_t in_reply_pipe, k5_ipc_stream in_request) { cc_int32 err = ccNoError; enum cci_msg_id_t request_name = 0; cci_identifier_t request_identifier = NULL; cc_uint32 will_block = 0; k5_ipc_stream reply_data = NULL; if (!ccs_pipe_valid (in_client_pipe)) { err = cci_check_error (ccErrBadParam); } if (!ccs_pipe_valid (in_reply_pipe) ) { err = cci_check_error (ccErrBadParam); } if (!in_request ) { err = cci_check_error (ccErrBadParam); } if (!err) { err = cci_message_read_request_header (in_request, &request_name, &request_identifier); } if (!err) { cc_uint32 server_err = 0; cc_uint32 valid = 0; ccs_cache_collection_t cache_collection = g_cache_collection; server_err = cci_identifier_is_for_server (request_identifier, g_server_id, &valid); if (!server_err && !valid) { server_err = cci_message_invalid_object_err (request_name); } if (!server_err) { /* Monolithic server implementation would need to select * cache collection here. Currently we only support per-user * servers so we always use the same cache collection. */ server_err = ccs_server_request_demux (in_client_pipe, in_reply_pipe, cache_collection, request_name, request_identifier, in_request, &will_block, &reply_data); } if (server_err || !will_block) { /* send a reply now if the server isn't blocked on something */ err = ccs_server_send_reply (in_reply_pipe, server_err, reply_data); } } cci_identifier_release (request_identifier); krb5int_ipc_stream_release (reply_data); return cci_check_error (err); } /* ------------------------------------------------------------------------ */ cc_int32 ccs_server_send_reply (ccs_pipe_t in_reply_pipe, cc_int32 in_reply_err, k5_ipc_stream in_reply_data) { cc_int32 err = ccNoError; k5_ipc_stream reply = NULL; if (!ccs_pipe_valid (in_reply_pipe) ) { err = cci_check_error (ccErrBadParam); } if (!err) { err = cci_message_new_reply_header (&reply, in_reply_err); } if (!err && in_reply_data && krb5int_ipc_stream_size (in_reply_data) > 0) { err = krb5int_ipc_stream_write (reply, krb5int_ipc_stream_data (in_reply_data), krb5int_ipc_stream_size (in_reply_data)); } if (!err) { err = ccs_os_server_send_reply (in_reply_pipe, reply); } krb5int_ipc_stream_release (reply); return cci_check_error (err); } /* ------------------------------------------------------------------------ */ cc_uint64 ccs_server_client_count () { return ccs_client_array_count (g_client_array); } krb5-1.16/src/ccapi/server/mac/0000755000704600001450000000000013211554426016112 5ustar ghudsonlibuuidkrb5-1.16/src/ccapi/server/mac/ccs_os_notify.c0000644000704600001450000000604313211554426021122 0ustar ghudsonlibuuid/* ccapi/server/mac/ccs_os_notify.c */ /* * Copyright 2006-2008 Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #include "ccs_common.h" #include "ccs_os_notify.h" #include /* ------------------------------------------------------------------------ */ cc_int32 ccs_os_notify_cache_collection_changed (ccs_cache_collection_t io_cache_collection) { cc_int32 err = ccNoError; if (!io_cache_collection) { err = cci_check_error (ccErrBadParam); } if (!err) { CFNotificationCenterRef center = CFNotificationCenterGetDistributedCenter (); if (center) { CFNotificationCenterPostNotification (center, kCCAPICacheCollectionChangedNotification, NULL, NULL, TRUE); } } return cci_check_error (err); } /* ------------------------------------------------------------------------ */ cc_int32 ccs_os_notify_ccache_changed (ccs_cache_collection_t io_cache_collection, const char *in_ccache_name) { cc_int32 err = ccNoError; if (!io_cache_collection) { err = cci_check_error (ccErrBadParam); } if (!in_ccache_name ) { err = cci_check_error (ccErrBadParam); } if (!err) { CFNotificationCenterRef center = CFNotificationCenterGetDistributedCenter (); CFStringRef name = CFStringCreateWithCString (kCFAllocatorDefault, in_ccache_name, kCFStringEncodingUTF8); if (center && name) { CFNotificationCenterPostNotification (center, kCCAPICCacheChangedNotification, name, NULL, TRUE); } if (name) { CFRelease (name); } } return cci_check_error (err); } krb5-1.16/src/ccapi/server/mac/edu.mit.Kerberos.CCacheServer.plist0000644000704600001450000000163013211554426024603 0ustar ghudsonlibuuid Label edu.mit.Kerberos.CCacheServer LimitLoadToSessionType Background Program /System/Library/CoreServices/CCacheServer.app/Contents/MacOS/CCacheServer MachServices edu.mit.Kerberos.CCacheServer.ipcLookup HideUntilCheckIn ResetAtClose edu.mit.Kerberos.CCacheServer.ipcService EnableTransactions OnDemand ThrottleInterval 0 EnvironmentVariables CFFIXED_USER_HOME /var/empty krb5-1.16/src/ccapi/server/mac/CCacheServerInfo.plist0000644000704600001450000000235613211554426022306 0ustar ghudsonlibuuid CFBundleDevelopmentRegion English CFBundleExecutable CCacheServer CFBundleGetInfoString 4.1 CFBundleIconFile CFBundleIdentifier edu.mit.Kerberos.CCacheServer CFBundleInfoDictionaryVersion 6.0 CFBundleName Kerberos Credentials Cache Server CFBundlePackageType APPL CFBundleSignature CCSa CFBundleVersion 0.0.1d1 CFBundleShortVersionString 5.5 CFBundleGetInfoString 5.5 Copyright MIT KfMDisplayVersion 5.5 Copyright MIT KfMDisplayCopyright Copyright MIT NSHumanReadableCopyright 5.5 Copyright MIT LSBackgroundOnly 1 krb5-1.16/src/ccapi/server/mac/ccs_os_pipe.c0000644000704600001450000000506613211554426020553 0ustar ghudsonlibuuid/* ccapi/server/mac/ccs_os_pipe.c */ /* * Copyright 2006 Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #include "ccs_common.h" #include "ccs_os_pipe.h" #include /* On macOS ccs_pipe_t is a mach_port_t */ /* ------------------------------------------------------------------------ */ cc_int32 ccs_os_pipe_valid (ccs_pipe_t in_pipe) { return MACH_PORT_VALID (in_pipe); } /* ------------------------------------------------------------------------ */ cc_int32 ccs_os_pipe_compare (ccs_pipe_t in_pipe, ccs_pipe_t in_compare_to_pipe, cc_uint32 *out_equal) { cc_int32 err = ccNoError; if (!in_pipe ) { err = cci_check_error (ccErrBadParam); } if (!in_compare_to_pipe) { err = cci_check_error (ccErrBadParam); } if (!out_equal ) { err = cci_check_error (ccErrBadParam); } if (!err) { *out_equal = (in_pipe == in_compare_to_pipe); } return cci_check_error (err); } /* ------------------------------------------------------------------------ */ cc_int32 ccs_os_pipe_copy (ccs_pipe_t *out_pipe, ccs_pipe_t in_pipe) { cc_int32 err = 0; *out_pipe = in_pipe; return cci_check_error (err); } /* ------------------------------------------------------------------------ */ cc_int32 ccs_os_pipe_release (ccs_pipe_t io_pipe) { cc_int32 err = 0; /* Nothing to do here on macOS */ return cci_check_error (err); } krb5-1.16/src/ccapi/server/mac/ccs_os_server.c0000644000704600001450000000656313211554426021127 0ustar ghudsonlibuuid/* ccapi/server/mac/ccs_os_server.c */ /* * Copyright 2006 Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #include "ccs_common.h" #include #include "k5_mig_server.h" #include "ccs_os_server.h" /* ------------------------------------------------------------------------ */ int32_t k5_ipc_server_add_client (mach_port_t in_client_port) { return cci_check_error (ccs_server_add_client (in_client_port)); } /* ------------------------------------------------------------------------ */ int32_t k5_ipc_server_remove_client (mach_port_t in_client_port) { return cci_check_error (ccs_server_remove_client (in_client_port)); } /* ------------------------------------------------------------------------ */ kern_return_t k5_ipc_server_handle_request (mach_port_t in_connection_port, mach_port_t in_reply_port, k5_ipc_stream in_request_stream) { return cci_check_error (ccs_server_handle_request (in_connection_port, in_reply_port, in_request_stream)); } #pragma mark - /* ------------------------------------------------------------------------ */ cc_int32 ccs_os_server_initialize (int argc, const char *argv[]) { cc_int32 err = 0; openlog (argv[0], LOG_CONS | LOG_PID, LOG_AUTH); syslog (LOG_INFO, "Starting up."); return cci_check_error (err); } /* ------------------------------------------------------------------------ */ cc_int32 ccs_os_server_cleanup (int argc, const char *argv[]) { cc_int32 err = 0; syslog (LOG_NOTICE, "Exiting."); return cci_check_error (err); } /* ------------------------------------------------------------------------ */ cc_int32 ccs_os_server_listen_loop (int argc, const char *argv[]) { return cci_check_error (k5_ipc_server_listen_loop ()); } /* ------------------------------------------------------------------------ */ cc_int32 ccs_os_server_send_reply (ccs_pipe_t in_reply_pipe, k5_ipc_stream in_reply_stream) { return cci_check_error (k5_ipc_server_send_reply (in_reply_pipe, in_reply_stream)); } krb5-1.16/src/ccapi/server/ccs_lock.h0000644000704600001450000000474613211554426017316 0ustar ghudsonlibuuid/* ccapi/server/ccs_lock.h */ /* * Copyright 2006 Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #ifndef CCS_LOCK_H #define CCS_LOCK_H #include "ccs_types.h" cc_int32 ccs_lock_new (ccs_lock_t *out_lock, cc_uint32 in_type, cc_int32 in_invalid_object_err, ccs_pipe_t in_client_pipe, ccs_pipe_t in_reply_pipe, ccs_lock_state_t in_lock_state_owner); cc_int32 ccs_lock_release (ccs_lock_t io_lock); cc_int32 ccs_lock_grant_lock (ccs_lock_t io_lock); cc_uint32 ccs_lock_is_pending (ccs_lock_t in_lock, cc_uint32 *out_pending); cc_int32 ccs_lock_type (ccs_lock_t in_lock, cc_uint32 *out_lock_type); cc_int32 ccs_lock_is_read_lock (ccs_lock_t in_lock, cc_uint32 *out_is_read_lock); cc_int32 ccs_lock_is_write_lock (ccs_lock_t in_lock, cc_uint32 *out_is_write_lock); cc_int32 ccs_lock_is_for_client_pipe (ccs_lock_t in_lock, ccs_pipe_t in_client_pipe, cc_uint32 *out_is_for_client_pipe); cc_int32 ccs_lock_client_pipe (ccs_lock_t in_lock, ccs_pipe_t *out_client_pipe); #endif /* CCS_LOCK_H */ krb5-1.16/src/ccapi/server/ccs_list_internal.c0000644000704600001450000005202113211554426021215 0ustar ghudsonlibuuid/* ccapi/server/ccs_list_internal.c */ /* * Copyright 2006, 2007 Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #include "ccs_list_internal.h" #include "cci_array_internal.h" #include "cci_identifier.h" #include "ccs_server.h" typedef enum { ccs_list_action_insert, ccs_list_action_remove, ccs_list_action_push_front } ccs_list_action_enum; /* ------------------------------------------------------------------------ */ struct ccs_list_d { cci_array_t objects; cci_array_t iterators; cc_int32 object_not_found_err; cc_int32 iterator_not_found_err; ccs_object_compare_identifier_t object_compare_identifier; }; struct ccs_list_d ccs_list_initializer = { NULL, NULL, -1, -1, NULL }; /* ------------------------------------------------------------------------ */ struct ccs_list_iterator_d { cci_identifier_t identifier; ccs_pipe_t client_pipe; ccs_list_t list; cc_uint64 current; }; struct ccs_list_iterator_d ccs_list_iterator_initializer = { NULL, CCS_PIPE_NULL, NULL, 0 }; static cc_int32 ccs_list_iterator_new (ccs_list_iterator_t *out_list_iterator, ccs_list_t in_list, ccs_pipe_t in_client_pipe); static cc_int32 ccs_list_iterator_object_release (cci_array_object_t io_list_iterator); static cc_int32 ccs_list_iterator_update (ccs_list_iterator_t io_list_iterator, ccs_list_action_enum in_action, cc_uint64 in_object_index); #ifdef TARGET_OS_MAC #pragma mark - #endif /* ------------------------------------------------------------------------ */ cc_int32 ccs_list_new (ccs_list_t *out_list, cc_int32 in_object_not_found_err, cc_int32 in_iterator_not_found_err, ccs_object_compare_identifier_t in_object_compare_identifier, ccs_object_release_t in_object_release) { cc_int32 err = ccNoError; ccs_list_t list = NULL; if (!out_list) { err = cci_check_error (ccErrBadParam); } if (!err) { list = malloc (sizeof (*list)); if (list) { *list = ccs_list_initializer; list->object_not_found_err = in_object_not_found_err; list->iterator_not_found_err = in_iterator_not_found_err; list->object_compare_identifier = in_object_compare_identifier; } else { err = cci_check_error (ccErrNoMem); } } if (!err) { err = cci_array_new (&list->objects, in_object_release); } if (!err) { err = cci_array_new (&list->iterators, ccs_list_iterator_object_release); } if (!err) { *out_list = list; list = NULL; } ccs_list_release (list); return cci_check_error (err); } /* ------------------------------------------------------------------------ */ cc_int32 ccs_list_release (ccs_list_t io_list) { cc_int32 err = ccNoError; if (!err && io_list) { cci_array_release (io_list->iterators); cci_array_release (io_list->objects); free (io_list); } return err; } /* ------------------------------------------------------------------------ */ cc_int32 ccs_list_new_iterator (ccs_list_t io_list, ccs_pipe_t in_client_pipe, ccs_list_iterator_t *out_list_iterator) { return cci_check_error (ccs_list_iterator_new (out_list_iterator, io_list, in_client_pipe)); } /* ------------------------------------------------------------------------ */ cc_int32 ccs_list_release_iterator (ccs_list_t io_list, cci_identifier_t in_identifier) { cc_int32 err = ccNoError; ccs_list_iterator_t iterator = NULL; if (!io_list ) { err = cci_check_error (ccErrBadParam); } if (!in_identifier) { err = cci_check_error (ccErrBadParam); } if (!err) { err = ccs_list_find_iterator (io_list, in_identifier, &iterator); } if (!err) { err = ccs_list_iterator_release (iterator); } return cci_check_error (err); } /* ------------------------------------------------------------------------ */ cc_int32 ccs_list_count (ccs_list_t in_list, cc_uint64 *out_count) { cc_int32 err = ccNoError; if (!in_list ) { err = cci_check_error (ccErrBadParam); } if (!out_count) { err = cci_check_error (ccErrBadParam); } if (!err) { *out_count = cci_array_count (in_list->objects); } return cci_check_error (err); } /* ------------------------------------------------------------------------ */ static ccs_list_iterator_t ccs_list_iterator_at_index (ccs_list_t in_list, cc_uint64 in_index) { return (ccs_list_iterator_t) cci_array_object_at_index (in_list->iterators, in_index); } /* ------------------------------------------------------------------------ */ static cc_int32 ccs_list_find_index (ccs_list_t in_list, cci_identifier_t in_identifier, cc_uint64 *out_object_index) { cc_int32 err = ccNoError; cc_int32 found = 0; if (!in_list ) { err = cci_check_error (ccErrBadParam); } if (!in_identifier ) { err = cci_check_error (ccErrBadParam); } if (!out_object_index) { err = cci_check_error (ccErrBadParam); } if (!err && !found) { cc_uint64 i; for (i = 0; !err && i < cci_array_count (in_list->objects); i++) { cc_uint32 equal = 0; cci_array_object_t object = cci_array_object_at_index (in_list->objects, i); err = in_list->object_compare_identifier (object, in_identifier, &equal); if (!err && equal) { found = 1; *out_object_index = i; break; } } } if (!err && !found) { err = cci_check_error (in_list->object_not_found_err); } return cci_check_error (err); } /* ------------------------------------------------------------------------ */ cc_int32 ccs_list_find (ccs_list_t in_list, cci_identifier_t in_identifier, ccs_list_object_t *out_object) { cc_int32 err = ccNoError; cc_uint64 i; if (!in_list ) { err = cci_check_error (ccErrBadParam); } if (!in_identifier) { err = cci_check_error (ccErrBadParam); } if (!out_object ) { err = cci_check_error (ccErrBadParam); } if (!err) { err = ccs_list_find_index (in_list, in_identifier, &i); } if (!err) { *out_object = cci_array_object_at_index (in_list->objects, i); } return cci_check_error (err); } /* ------------------------------------------------------------------------ */ static cc_int32 ccs_list_find_iterator_index (ccs_list_t in_list, cci_identifier_t in_identifier, cc_uint64 *out_object_index) { cc_int32 err = ccNoError; cc_int32 found = 0; if (!in_list ) { err = cci_check_error (ccErrBadParam); } if (!in_identifier ) { err = cci_check_error (ccErrBadParam); } if (!out_object_index) { err = cci_check_error (ccErrBadParam); } if (!err && !found) { cc_uint64 i; for (i = 0; !err && i < cci_array_count (in_list->iterators); i++) { cc_uint32 equal = 0; ccs_list_iterator_t iterator = ccs_list_iterator_at_index (in_list, i); err = cci_identifier_compare (iterator->identifier, in_identifier, &equal); if (!err && equal) { found = 1; *out_object_index = i; break; } } } if (!err && !found) { // Don't report this error to the log file. Non-fatal. return in_list->object_not_found_err; } else { return cci_check_error (err); } } /* ------------------------------------------------------------------------ */ cc_int32 ccs_list_find_iterator (ccs_list_t in_list, cci_identifier_t in_identifier, ccs_list_iterator_t *out_list_iterator) { cc_int32 err = ccNoError; cc_uint64 i; if (!in_list ) { err = cci_check_error (ccErrBadParam); } if (!in_identifier ) { err = cci_check_error (ccErrBadParam); } if (!out_list_iterator) { err = cci_check_error (ccErrBadParam); } if (!err) { err = ccs_list_find_iterator_index (in_list, in_identifier, &i); } if (!err) { *out_list_iterator = ccs_list_iterator_at_index (in_list, i); } return cci_check_error (err); } /* ------------------------------------------------------------------------ */ cc_int32 ccs_list_add (ccs_list_t io_list, ccs_list_object_t in_object) { cc_int32 err = ccNoError; cc_uint64 add_index; if (!io_list ) { err = cci_check_error (ccErrBadParam); } if (!in_object) { err = cci_check_error (ccErrBadParam); } if (!err) { add_index = cci_array_count (io_list->objects); err = cci_array_insert (io_list->objects, in_object, add_index); } if (!err) { /* Fixup iterator indexes */ cc_uint64 i; for (i = 0; !err && i < cci_array_count (io_list->iterators); i++) { ccs_list_iterator_t iterator = ccs_list_iterator_at_index (io_list, i); err = ccs_list_iterator_update (iterator, ccs_list_action_insert, add_index); } } return cci_check_error (err); } /* ------------------------------------------------------------------------ */ cc_int32 ccs_list_remove (ccs_list_t io_list, cci_identifier_t in_identifier) { cc_int32 err = ccNoError; cc_uint64 remove_index; if (!io_list ) { err = cci_check_error (ccErrBadParam); } if (!in_identifier) { err = cci_check_error (ccErrBadParam); } if (!err) { err = ccs_list_find_index (io_list, in_identifier, &remove_index); } if (!err) { err = cci_array_remove (io_list->objects, remove_index); } if (!err) { /* Fixup iterator indexes */ cc_uint64 i; for (i = 0; !err && i < cci_array_count (io_list->iterators); i++) { ccs_list_iterator_t iterator = ccs_list_iterator_at_index (io_list, i); err = ccs_list_iterator_update (iterator, ccs_list_action_remove, remove_index); } } return cci_check_error (err); } /* ------------------------------------------------------------------------ */ cc_int32 ccs_list_push_front (ccs_list_t io_list, cci_identifier_t in_identifier) { cc_int32 err = ccNoError; cc_uint64 push_front_index; if (!io_list ) { err = cci_check_error (ccErrBadParam); } if (!in_identifier) { err = cci_check_error (ccErrBadParam); } if (!err) { err = ccs_list_find_index (io_list, in_identifier, &push_front_index); } if (!err) { err = cci_array_push_front (io_list->objects, push_front_index); } if (!err) { /* Fixup iterator indexes */ cc_uint64 i; for (i = 0; !err && i < cci_array_count (io_list->iterators); i++) { ccs_list_iterator_t iterator = ccs_list_iterator_at_index (io_list, i); err = ccs_list_iterator_update (iterator, ccs_list_action_push_front, push_front_index); } } return cci_check_error (err); } #ifdef TARGET_OS_MAC #pragma mark - #endif /* ------------------------------------------------------------------------ */ static cc_int32 ccs_list_iterator_new (ccs_list_iterator_t *out_list_iterator, ccs_list_t io_list, ccs_pipe_t in_client_pipe) { cc_int32 err = ccNoError; ccs_list_iterator_t list_iterator = NULL; if (!out_list_iterator) { err = cci_check_error (ccErrBadParam); } if (!io_list ) { err = cci_check_error (ccErrBadParam); } /* client_pipe may be NULL if the iterator exists for internal server use */ if (!err) { list_iterator = malloc (sizeof (*list_iterator)); if (list_iterator) { *list_iterator = ccs_list_iterator_initializer; } else { err = cci_check_error (ccErrNoMem); } } if (!err) { err = ccs_server_new_identifier (&list_iterator->identifier); } if (!err) { list_iterator->list = io_list; list_iterator->current = 0; err = cci_array_insert (io_list->iterators, (cci_array_object_t) list_iterator, cci_array_count (io_list->iterators)); } if (!err && ccs_pipe_valid (in_client_pipe)) { ccs_client_t client = NULL; err = ccs_pipe_copy (&list_iterator->client_pipe, in_client_pipe); if (!err) { err = ccs_server_client_for_pipe (in_client_pipe, &client); } if (!err) { err = ccs_client_add_iterator (client, list_iterator); } } if (!err) { *out_list_iterator = list_iterator; list_iterator = NULL; } ccs_list_iterator_release (list_iterator); return cci_check_error (err); } /* ------------------------------------------------------------------------ */ cc_int32 ccs_list_iterator_write (ccs_list_iterator_t in_list_iterator, k5_ipc_stream in_stream) { cc_int32 err = ccNoError; if (!in_list_iterator) { err = cci_check_error (ccErrBadParam); } if (!in_stream ) { err = cci_check_error (ccErrBadParam); } if (!err) { err = cci_identifier_write (in_list_iterator->identifier, in_stream); } return cci_check_error (err); } /* ------------------------------------------------------------------------ */ cc_int32 ccs_list_iterator_clone (ccs_list_iterator_t in_list_iterator, ccs_list_iterator_t *out_list_iterator) { cc_int32 err = ccNoError; ccs_list_iterator_t list_iterator = NULL; if (!in_list_iterator ) { err = cci_check_error (ccErrBadParam); } if (!out_list_iterator) { err = cci_check_error (ccErrBadParam); } if (!err) { err = ccs_list_iterator_new (&list_iterator, in_list_iterator->list, in_list_iterator->client_pipe); } if (!err) { list_iterator->current = in_list_iterator->current; *out_list_iterator = list_iterator; list_iterator = NULL; } ccs_list_iterator_release (list_iterator); return cci_check_error (err); } /* ------------------------------------------------------------------------ */ static cc_int32 ccs_list_iterator_object_release (cci_array_object_t io_list_iterator) { cc_int32 err = ccNoError; ccs_list_iterator_t list_iterator = (ccs_list_iterator_t) io_list_iterator; if (!io_list_iterator) { err = ccErrBadParam; } if (!err && ccs_pipe_valid (list_iterator->client_pipe)) { ccs_client_t client = NULL; err = ccs_server_client_for_pipe (list_iterator->client_pipe, &client); if (!err && client) { /* if client object still has a reference to us, remove it */ err = ccs_client_remove_iterator (client, list_iterator); } } if (!err) { ccs_pipe_release (list_iterator->client_pipe); cci_identifier_release (list_iterator->identifier); free (io_list_iterator); } return err; } /* ------------------------------------------------------------------------ */ cc_int32 ccs_list_iterator_release (ccs_list_iterator_t io_list_iterator) { cc_int32 err = ccNoError; if (!err && io_list_iterator) { cc_uint64 i = 0; if (ccs_list_find_iterator_index (io_list_iterator->list, io_list_iterator->identifier, &i) == ccNoError) { /* cci_array_remove will call ccs_list_iterator_object_release */ err = cci_array_remove (io_list_iterator->list->iterators, i); } else { cci_debug_printf ("Warning: iterator not in iterator list!"); } } return err; } /* ------------------------------------------------------------------------ */ cc_int32 ccs_list_iterator_invalidate (ccs_list_iterator_t io_list_iterator) { cc_int32 err = ccNoError; ccs_list_iterator_t list_iterator = (ccs_list_iterator_t) io_list_iterator; if (!io_list_iterator) { err = ccErrBadParam; } if (!err) { /* Client owner died. Remove client reference and then the iterator. */ if (ccs_pipe_valid (list_iterator->client_pipe)) { ccs_pipe_release (list_iterator->client_pipe); list_iterator->client_pipe = CCS_PIPE_NULL; } err = ccs_list_iterator_release (io_list_iterator); } return err; } /* ------------------------------------------------------------------------ */ cc_int32 ccs_list_iterator_current (ccs_list_iterator_t io_list_iterator, ccs_list_object_t *out_object) { cc_int32 err = ccNoError; if (!io_list_iterator) { err = cci_check_error (ccErrBadParam); } if (!out_object ) { err = cci_check_error (ccErrBadParam); } if (!err) { if (io_list_iterator->current < cci_array_count (io_list_iterator->list->objects)) { *out_object = cci_array_object_at_index (io_list_iterator->list->objects, io_list_iterator->current); } else { err = ccIteratorEnd; } } return cci_check_error (err); } /* ------------------------------------------------------------------------ */ cc_int32 ccs_list_iterator_next (ccs_list_iterator_t io_list_iterator, ccs_list_object_t *out_object) { cc_int32 err = ccNoError; if (!io_list_iterator) { err = cci_check_error (ccErrBadParam); } if (!out_object ) { err = cci_check_error (ccErrBadParam); } if (!err) { if (io_list_iterator->current < cci_array_count (io_list_iterator->list->objects)) { *out_object = cci_array_object_at_index (io_list_iterator->list->objects, io_list_iterator->current); io_list_iterator->current++; } else { err = ccIteratorEnd; } } return cci_check_error (err); } /* ------------------------------------------------------------------------ */ static cc_int32 ccs_list_iterator_update (ccs_list_iterator_t io_list_iterator, ccs_list_action_enum in_action, cc_uint64 in_object_index) { cc_int32 err = ccNoError; if (!io_list_iterator) { err = cci_check_error (ccErrBadParam); } if (!err) { /* When the list changes adjust the current index so that */ /* we don't unnecessarily skip or double count items */ if (in_action == ccs_list_action_insert) { if (io_list_iterator->current > in_object_index) { io_list_iterator->current++; } } else if (in_action == ccs_list_action_remove) { if (io_list_iterator->current >= in_object_index) { io_list_iterator->current--; } } else if (in_action == ccs_list_action_push_front) { if (io_list_iterator->current < in_object_index) { io_list_iterator->current++; } } else { err = cci_check_error (ccErrBadParam); } } return cci_check_error (err); } krb5-1.16/src/ccapi/server/ccs_array.h0000644000704600001450000001204013211554426017466 0ustar ghudsonlibuuid/* ccapi/server/ccs_array.h */ /* * Copyright 2006, 2007 Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #ifndef CCS_ARRAY_H #define CCS_ARRAY_H #include "ccs_types.h" cc_int32 ccs_client_array_new (ccs_client_array_t *out_array); cc_int32 ccs_client_array_release (ccs_client_array_t io_array); cc_uint64 ccs_client_array_count (ccs_client_array_t in_array); ccs_client_t ccs_client_array_object_at_index (ccs_client_array_t io_array, cc_uint64 in_position); cc_int32 ccs_client_array_insert (ccs_client_array_t io_array, ccs_client_t in_client, cc_uint64 in_position); cc_int32 ccs_client_array_remove (ccs_client_array_t io_array, cc_uint64 in_position); #ifdef TARGET_OS_MAC #pragma mark - #endif cc_int32 ccs_lock_array_new (ccs_lock_array_t *out_array); cc_int32 ccs_lock_array_release (ccs_lock_array_t io_array); cc_uint64 ccs_lock_array_count (ccs_lock_array_t in_array); ccs_lock_t ccs_lock_array_object_at_index (ccs_lock_array_t io_array, cc_uint64 in_position); cc_int32 ccs_lock_array_insert (ccs_lock_array_t io_array, ccs_lock_t in_lock, cc_uint64 in_position); cc_int32 ccs_lock_array_remove (ccs_lock_array_t io_array, cc_uint64 in_position); cc_int32 ccs_lock_array_move (ccs_lock_array_t io_array, cc_uint64 in_position, cc_uint64 in_new_position, cc_uint64 *out_real_new_position); #ifdef TARGET_OS_MAC #pragma mark - #endif cc_int32 ccs_callback_array_new (ccs_callback_array_t *out_array); cc_int32 ccs_callback_array_release (ccs_callback_array_t io_array); cc_uint64 ccs_callback_array_count (ccs_callback_array_t in_array); ccs_callback_t ccs_callback_array_object_at_index (ccs_callback_array_t io_array, cc_uint64 in_position); cc_int32 ccs_callback_array_insert (ccs_callback_array_t io_array, ccs_callback_t in_callback, cc_uint64 in_position); cc_int32 ccs_callback_array_remove (ccs_callback_array_t io_array, cc_uint64 in_position); #ifdef TARGET_OS_MAC #pragma mark - #endif cc_int32 ccs_callbackref_array_new (ccs_callbackref_array_t *out_array); cc_int32 ccs_callbackref_array_release (ccs_callbackref_array_t io_array); cc_uint64 ccs_callbackref_array_count (ccs_callbackref_array_t in_array); ccs_callback_t ccs_callbackref_array_object_at_index (ccs_callbackref_array_t io_array, cc_uint64 in_position); cc_int32 ccs_callbackref_array_insert (ccs_callbackref_array_t io_array, ccs_callback_t in_callback, cc_uint64 in_position); cc_int32 ccs_callbackref_array_remove (ccs_callbackref_array_t io_array, cc_uint64 in_position); #ifdef TARGET_OS_MAC #pragma mark - #endif cc_int32 ccs_iteratorref_array_new (ccs_iteratorref_array_t *out_array); cc_int32 ccs_iteratorref_array_release (ccs_iteratorref_array_t io_array); cc_uint64 ccs_iteratorref_array_count (ccs_iteratorref_array_t in_array); ccs_generic_list_iterator_t ccs_iteratorref_array_object_at_index (ccs_iteratorref_array_t io_array, cc_uint64 in_position); cc_int32 ccs_iteratorref_array_insert (ccs_iteratorref_array_t io_array, ccs_generic_list_iterator_t in_iterator, cc_uint64 in_position); cc_int32 ccs_iteratorref_array_remove (ccs_iteratorref_array_t io_array, cc_uint64 in_position); #endif /* CCS_ARRAY_H */ krb5-1.16/src/ccapi/server/ccs_client.h0000644000704600001450000000407113211554426017633 0ustar ghudsonlibuuid/* ccapi/server/ccs_client.h */ /* * Copyright 2006 Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #ifndef CCS_CLIENT_H #define CCS_CLIENT_H #include "ccs_types.h" cc_int32 ccs_client_new (ccs_client_t *out_client, ccs_pipe_t in_client_pipe); cc_int32 ccs_client_release (ccs_client_t io_client); cc_int32 ccs_client_add_callback (ccs_client_t io_client, ccs_callback_t in_lock); cc_int32 ccs_client_remove_callback (ccs_client_t io_client, ccs_callback_t in_lock); cc_int32 ccs_client_add_iterator (ccs_client_t io_client, ccs_generic_list_iterator_t in_iterator); cc_int32 ccs_client_remove_iterator (ccs_client_t io_client, ccs_generic_list_iterator_t in_iterator); cc_int32 ccs_client_uses_pipe (ccs_client_t in_client, ccs_pipe_t in_pipe, cc_uint32 *out_uses_pipe); #endif /* CCS_CLIENT_H */ krb5-1.16/src/ccapi/server/ccs_credentials.h0000644000704600001450000000403213211554426020647 0ustar ghudsonlibuuid/* ccapi/server/ccs_credentials.h */ /* * Copyright 2006 Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #ifndef CCS_CREDENTIALS_H #define CCS_CREDENTIALS_H #include "ccs_types.h" cc_int32 ccs_credentials_new (ccs_credentials_t *out_credentials, k5_ipc_stream in_stream, cc_uint32 in_ccache_version, ccs_credentials_list_t io_credentials_list); cc_int32 ccs_credentials_release (ccs_credentials_t io_credentials); cc_int32 ccs_credentials_write (ccs_credentials_t in_credentials, k5_ipc_stream io_stream); cc_int32 ccs_credentials_compare_identifier (ccs_credentials_t in_credentials, cci_identifier_t in_identifier, cc_uint32 *out_equal); #endif /* CCS_CREDENTIALS_H */ krb5-1.16/src/ccapi/server/deps0000644000704600001450000002645013211554426016237 0ustar ghudsonlibuuid# # Generated makefile dependencies follow. # ccs_array.so ccs_array.po $(OUTPRE)ccs_array.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(COM_ERR_DEPS) $(top_srcdir)/include/CredentialsCache.h \ $(top_srcdir)/include/CredentialsCache2.h $(top_srcdir)/include/k5-ipc_stream.h \ $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-thread.h \ $(srcdir)/../common/cci_array_internal.h $(srcdir)/../common/cci_common.h \ $(srcdir)/../common/cci_cred_union.h $(srcdir)/../common/cci_debugging.h \ $(srcdir)/../common/cci_identifier.h $(srcdir)/../common/cci_message.h \ $(srcdir)/../common/cci_types.h ccs_array.c ccs_array.h \ ccs_cache_collection.h ccs_callback.h ccs_ccache.h \ ccs_ccache_iterator.h ccs_client.h ccs_common.h ccs_credentials.h \ ccs_credentials_iterator.h ccs_list.h ccs_lock.h ccs_lock_state.h \ ccs_pipe.h ccs_server.h ccs_types.h ccs_cache_collection.so ccs_cache_collection.po $(OUTPRE)ccs_cache_collection.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(COM_ERR_DEPS) $(top_srcdir)/include/CredentialsCache.h \ $(top_srcdir)/include/CredentialsCache2.h $(top_srcdir)/include/k5-ipc_stream.h \ $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-thread.h \ $(srcdir)/../common/cci_common.h $(srcdir)/../common/cci_cred_union.h \ $(srcdir)/../common/cci_debugging.h $(srcdir)/../common/cci_identifier.h \ $(srcdir)/../common/cci_message.h $(srcdir)/../common/cci_types.h \ ccs_array.h ccs_cache_collection.c ccs_cache_collection.h \ ccs_callback.h ccs_ccache.h ccs_ccache_iterator.h ccs_client.h \ ccs_common.h ccs_credentials.h ccs_credentials_iterator.h \ ccs_list.h ccs_lock.h ccs_lock_state.h ccs_os_notify.h \ ccs_pipe.h ccs_server.h ccs_types.h ccs_callback.so ccs_callback.po $(OUTPRE)ccs_callback.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(COM_ERR_DEPS) $(top_srcdir)/include/CredentialsCache.h \ $(top_srcdir)/include/CredentialsCache2.h $(top_srcdir)/include/k5-ipc_stream.h \ $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-thread.h \ $(srcdir)/../common/cci_common.h $(srcdir)/../common/cci_cred_union.h \ $(srcdir)/../common/cci_debugging.h $(srcdir)/../common/cci_identifier.h \ $(srcdir)/../common/cci_message.h $(srcdir)/../common/cci_types.h \ ccs_array.h ccs_cache_collection.h ccs_callback.c ccs_callback.h \ ccs_ccache.h ccs_ccache_iterator.h ccs_client.h ccs_common.h \ ccs_credentials.h ccs_credentials_iterator.h ccs_list.h \ ccs_lock.h ccs_lock_state.h ccs_pipe.h ccs_server.h \ ccs_types.h ccs_ccache.so ccs_ccache.po $(OUTPRE)ccs_ccache.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(COM_ERR_DEPS) $(top_srcdir)/include/CredentialsCache.h \ $(top_srcdir)/include/CredentialsCache2.h $(top_srcdir)/include/k5-ipc_stream.h \ $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-thread.h \ $(srcdir)/../common/cci_common.h $(srcdir)/../common/cci_cred_union.h \ $(srcdir)/../common/cci_debugging.h $(srcdir)/../common/cci_identifier.h \ $(srcdir)/../common/cci_message.h $(srcdir)/../common/cci_types.h \ ccs_array.h ccs_cache_collection.h ccs_callback.h ccs_ccache.c \ ccs_ccache.h ccs_ccache_iterator.h ccs_client.h ccs_common.h \ ccs_credentials.h ccs_credentials_iterator.h ccs_list.h \ ccs_lock.h ccs_lock_state.h ccs_os_notify.h ccs_pipe.h \ ccs_server.h ccs_types.h ccs_ccache_iterator.so ccs_ccache_iterator.po $(OUTPRE)ccs_ccache_iterator.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(COM_ERR_DEPS) $(top_srcdir)/include/CredentialsCache.h \ $(top_srcdir)/include/CredentialsCache2.h $(top_srcdir)/include/k5-ipc_stream.h \ $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-thread.h \ $(srcdir)/../common/cci_common.h $(srcdir)/../common/cci_cred_union.h \ $(srcdir)/../common/cci_debugging.h $(srcdir)/../common/cci_identifier.h \ $(srcdir)/../common/cci_message.h $(srcdir)/../common/cci_types.h \ ccs_array.h ccs_cache_collection.h ccs_callback.h ccs_ccache.h \ ccs_ccache_iterator.c ccs_ccache_iterator.h ccs_client.h \ ccs_common.h ccs_credentials.h ccs_credentials_iterator.h \ ccs_list.h ccs_lock.h ccs_lock_state.h ccs_pipe.h ccs_server.h \ ccs_types.h ccs_client.so ccs_client.po $(OUTPRE)ccs_client.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(COM_ERR_DEPS) $(top_srcdir)/include/CredentialsCache.h \ $(top_srcdir)/include/CredentialsCache2.h $(top_srcdir)/include/k5-ipc_stream.h \ $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-thread.h \ $(srcdir)/../common/cci_common.h $(srcdir)/../common/cci_cred_union.h \ $(srcdir)/../common/cci_debugging.h $(srcdir)/../common/cci_identifier.h \ $(srcdir)/../common/cci_message.h $(srcdir)/../common/cci_types.h \ ccs_array.h ccs_cache_collection.h ccs_callback.h ccs_ccache.h \ ccs_ccache_iterator.h ccs_client.c ccs_client.h ccs_common.h \ ccs_credentials.h ccs_credentials_iterator.h ccs_list.h \ ccs_lock.h ccs_lock_state.h ccs_pipe.h ccs_server.h \ ccs_types.h ccs_credentials.so ccs_credentials.po $(OUTPRE)ccs_credentials.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(COM_ERR_DEPS) $(top_srcdir)/include/CredentialsCache.h \ $(top_srcdir)/include/CredentialsCache2.h $(top_srcdir)/include/k5-ipc_stream.h \ $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-thread.h \ $(srcdir)/../common/cci_common.h $(srcdir)/../common/cci_cred_union.h \ $(srcdir)/../common/cci_debugging.h $(srcdir)/../common/cci_identifier.h \ $(srcdir)/../common/cci_message.h $(srcdir)/../common/cci_types.h \ ccs_array.h ccs_cache_collection.h ccs_callback.h ccs_ccache.h \ ccs_ccache_iterator.h ccs_client.h ccs_common.h ccs_credentials.c \ ccs_credentials.h ccs_credentials_iterator.h ccs_list.h \ ccs_lock.h ccs_lock_state.h ccs_pipe.h ccs_server.h \ ccs_types.h ccs_credentials_iterator.so ccs_credentials_iterator.po \ $(OUTPRE)ccs_credentials_iterator.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(COM_ERR_DEPS) $(top_srcdir)/include/CredentialsCache.h \ $(top_srcdir)/include/CredentialsCache2.h $(top_srcdir)/include/k5-ipc_stream.h \ $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-thread.h \ $(srcdir)/../common/cci_common.h $(srcdir)/../common/cci_cred_union.h \ $(srcdir)/../common/cci_debugging.h $(srcdir)/../common/cci_identifier.h \ $(srcdir)/../common/cci_message.h $(srcdir)/../common/cci_types.h \ ccs_array.h ccs_cache_collection.h ccs_callback.h ccs_ccache.h \ ccs_ccache_iterator.h ccs_client.h ccs_common.h ccs_credentials.h \ ccs_credentials_iterator.c ccs_credentials_iterator.h \ ccs_list.h ccs_lock.h ccs_lock_state.h ccs_pipe.h ccs_server.h \ ccs_types.h ccs_list.so ccs_list.po $(OUTPRE)ccs_list.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(COM_ERR_DEPS) $(top_srcdir)/include/CredentialsCache.h \ $(top_srcdir)/include/CredentialsCache2.h $(top_srcdir)/include/k5-ipc_stream.h \ $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-thread.h \ $(srcdir)/../common/cci_array_internal.h $(srcdir)/../common/cci_common.h \ $(srcdir)/../common/cci_cred_union.h $(srcdir)/../common/cci_debugging.h \ $(srcdir)/../common/cci_identifier.h $(srcdir)/../common/cci_message.h \ $(srcdir)/../common/cci_types.h ccs_array.h ccs_cache_collection.h \ ccs_callback.h ccs_ccache.h ccs_ccache_iterator.h ccs_client.h \ ccs_common.h ccs_credentials.h ccs_credentials_iterator.h \ ccs_list.c ccs_list.h ccs_list_internal.h ccs_lock.h \ ccs_lock_state.h ccs_pipe.h ccs_server.h ccs_types.h ccs_list_internal.so ccs_list_internal.po $(OUTPRE)ccs_list_internal.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(COM_ERR_DEPS) $(top_srcdir)/include/CredentialsCache.h \ $(top_srcdir)/include/CredentialsCache2.h $(top_srcdir)/include/k5-ipc_stream.h \ $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-thread.h \ $(srcdir)/../common/cci_array_internal.h $(srcdir)/../common/cci_common.h \ $(srcdir)/../common/cci_cred_union.h $(srcdir)/../common/cci_debugging.h \ $(srcdir)/../common/cci_identifier.h $(srcdir)/../common/cci_message.h \ $(srcdir)/../common/cci_types.h ccs_array.h ccs_cache_collection.h \ ccs_callback.h ccs_ccache.h ccs_ccache_iterator.h ccs_client.h \ ccs_common.h ccs_credentials.h ccs_credentials_iterator.h \ ccs_list.h ccs_list_internal.c ccs_list_internal.h \ ccs_lock.h ccs_lock_state.h ccs_pipe.h ccs_server.h \ ccs_types.h ccs_lock.so ccs_lock.po $(OUTPRE)ccs_lock.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(COM_ERR_DEPS) $(top_srcdir)/include/CredentialsCache.h \ $(top_srcdir)/include/CredentialsCache2.h $(top_srcdir)/include/k5-ipc_stream.h \ $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-thread.h \ $(srcdir)/../common/cci_common.h $(srcdir)/../common/cci_cred_union.h \ $(srcdir)/../common/cci_debugging.h $(srcdir)/../common/cci_identifier.h \ $(srcdir)/../common/cci_message.h $(srcdir)/../common/cci_types.h \ ccs_array.h ccs_cache_collection.h ccs_callback.h ccs_ccache.h \ ccs_ccache_iterator.h ccs_client.h ccs_common.h ccs_credentials.h \ ccs_credentials_iterator.h ccs_list.h ccs_lock.c ccs_lock.h \ ccs_lock_state.h ccs_pipe.h ccs_server.h ccs_types.h ccs_lock_state.so ccs_lock_state.po $(OUTPRE)ccs_lock_state.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(COM_ERR_DEPS) $(top_srcdir)/include/CredentialsCache.h \ $(top_srcdir)/include/CredentialsCache2.h $(top_srcdir)/include/k5-ipc_stream.h \ $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-thread.h \ $(srcdir)/../common/cci_common.h $(srcdir)/../common/cci_cred_union.h \ $(srcdir)/../common/cci_debugging.h $(srcdir)/../common/cci_identifier.h \ $(srcdir)/../common/cci_message.h $(srcdir)/../common/cci_types.h \ ccs_array.h ccs_cache_collection.h ccs_callback.h ccs_ccache.h \ ccs_ccache_iterator.h ccs_client.h ccs_common.h ccs_credentials.h \ ccs_credentials_iterator.h ccs_list.h ccs_lock.h ccs_lock_state.c \ ccs_lock_state.h ccs_pipe.h ccs_server.h ccs_types.h ccs_pipe.so ccs_pipe.po $(OUTPRE)ccs_pipe.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(COM_ERR_DEPS) $(top_srcdir)/include/CredentialsCache.h \ $(top_srcdir)/include/CredentialsCache2.h $(top_srcdir)/include/k5-ipc_stream.h \ $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-thread.h \ $(srcdir)/../common/cci_common.h $(srcdir)/../common/cci_cred_union.h \ $(srcdir)/../common/cci_debugging.h $(srcdir)/../common/cci_identifier.h \ $(srcdir)/../common/cci_message.h $(srcdir)/../common/cci_types.h \ ccs_array.h ccs_cache_collection.h ccs_callback.h ccs_ccache.h \ ccs_ccache_iterator.h ccs_client.h ccs_common.h ccs_credentials.h \ ccs_credentials_iterator.h ccs_list.h ccs_lock.h ccs_lock_state.h \ ccs_os_pipe.h ccs_pipe.c ccs_pipe.h ccs_server.h ccs_types.h ccs_server.so ccs_server.po $(OUTPRE)ccs_server.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(COM_ERR_DEPS) $(top_srcdir)/include/CredentialsCache.h \ $(top_srcdir)/include/CredentialsCache2.h $(top_srcdir)/include/k5-ipc_stream.h \ $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-thread.h \ $(srcdir)/../common/cci_common.h $(srcdir)/../common/cci_cred_union.h \ $(srcdir)/../common/cci_debugging.h $(srcdir)/../common/cci_identifier.h \ $(srcdir)/../common/cci_message.h $(srcdir)/../common/cci_types.h \ ccs_array.h ccs_cache_collection.h ccs_callback.h ccs_ccache.h \ ccs_ccache_iterator.h ccs_client.h ccs_common.h ccs_credentials.h \ ccs_credentials_iterator.h ccs_list.h ccs_lock.h ccs_lock_state.h \ ccs_os_server.h ccs_pipe.h ccs_server.c ccs_server.h \ ccs_types.h krb5-1.16/src/ccapi/server/ccs_credentials_iterator.h0000644000704600001450000000351713211554426022567 0ustar ghudsonlibuuid/* ccapi/server/ccs_credentials_iterator.h */ /* * Copyright 2006 Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #ifndef CCS_CREDENTIALS_ITERATOR_H #define CCS_CREDENTIALS_ITERATOR_H #include "ccs_types.h" cc_int32 ccs_credentials_iterator_handle_message (ccs_credentials_iterator_t io_credentials_iterator, ccs_ccache_t io_ccache, enum cci_msg_id_t in_request_name, k5_ipc_stream in_request_data, k5_ipc_stream *out_reply_data); #endif /* CCS_CREDENTIALS_ITERATOR_H */ krb5-1.16/src/ccapi/server/ccs_list_internal.h0000644000704600001450000000774113211554426021233 0ustar ghudsonlibuuid/* ccapi/server/ccs_list_internal.h */ /* * Copyright 2006 Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #ifndef CCS_LIST_INTERNAL_H #define CCS_LIST_INTERNAL_H #include "ccs_common.h" #include "cci_array_internal.h" struct ccs_list_d; typedef struct ccs_list_d *ccs_list_t; struct ccs_list_iterator_d; typedef struct ccs_list_iterator_d *ccs_list_iterator_t; typedef cci_array_object_t ccs_list_object_t; typedef cc_int32 (*ccs_object_release_t) (ccs_list_object_t); typedef cc_int32 (*ccs_object_compare_identifier_t) (ccs_list_object_t, cci_identifier_t, cc_uint32 *); cc_int32 ccs_list_new (ccs_list_t *out_list, cc_int32 in_object_not_found_err, cc_int32 in_iterator_not_found_err, ccs_object_compare_identifier_t in_object_compare_identifier, ccs_object_release_t in_object_release); cc_int32 ccs_list_release (ccs_list_t io_list); cc_int32 ccs_list_new_iterator (ccs_list_t io_list, ccs_pipe_t in_client_pipe, ccs_list_iterator_t *out_list_iterator); cc_int32 ccs_list_release_iterator (ccs_list_t io_list, cci_identifier_t in_identifier); cc_int32 ccs_list_count (ccs_list_t in_list, cc_uint64 *out_count); cc_int32 ccs_list_find (ccs_list_t in_list, cci_identifier_t in_identifier, ccs_list_object_t *out_object); cc_int32 ccs_list_find_iterator (ccs_list_t in_list, cci_identifier_t in_identifier, ccs_list_iterator_t *out_list_iterator); cc_int32 ccs_list_add (ccs_list_t io_list, ccs_list_object_t in_object); cc_int32 ccs_list_remove (ccs_list_t io_list, cci_identifier_t in_identifier); cc_int32 ccs_list_push_front (ccs_list_t io_list, cci_identifier_t in_identifier); cc_int32 ccs_list_iterator_write (ccs_list_iterator_t in_list_iterator, k5_ipc_stream in_stream); cc_int32 ccs_list_iterator_clone (ccs_list_iterator_t in_list_iterator, ccs_list_iterator_t *out_list_iterator); cc_int32 ccs_list_iterator_current (ccs_list_iterator_t io_list_iterator, ccs_list_object_t *out_object); cc_int32 ccs_list_iterator_next (ccs_list_iterator_t io_list_iterator, ccs_list_object_t *out_object); cc_int32 ccs_list_iterator_invalidate (ccs_list_iterator_t io_list_iterator); cc_int32 ccs_list_iterator_release (ccs_list_iterator_t io_list_iterator); #endif /* CCS_LIST_INTERNAL_H */ krb5-1.16/src/ccapi/server/ccs_callback.c0000644000704600001450000001661013211554426020106 0ustar ghudsonlibuuid/* ccapi/server/ccs_callback.c */ /* * Copyright 2006 Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #include "ccs_common.h" struct ccs_callback_d { cc_int32 pending; cc_int32 invalid_object_err; ccs_pipe_t client_pipe; ccs_pipe_t reply_pipe; ccs_callback_owner_t owner; /* pointer to owner */ ccs_callback_owner_invalidate_t owner_invalidate; }; struct ccs_callback_d ccs_callback_initializer = { 1, 1, CCS_PIPE_NULL, CCS_PIPE_NULL, NULL, NULL }; /* ------------------------------------------------------------------------ */ cc_int32 ccs_callback_new (ccs_callback_t *out_callback, cc_int32 in_invalid_object_err, ccs_pipe_t in_client_pipe, ccs_pipe_t in_reply_pipe, ccs_callback_owner_t in_owner, ccs_callback_owner_invalidate_t in_owner_invalidate_function) { cc_int32 err = ccNoError; ccs_callback_t callback = NULL; ccs_client_t client = NULL; if (!out_callback ) { err = cci_check_error (ccErrBadParam); } if (!ccs_pipe_valid (in_client_pipe)) { err = cci_check_error (ccErrBadParam); } if (!ccs_pipe_valid (in_reply_pipe) ) { err = cci_check_error (ccErrBadParam); } if (!in_owner ) { err = cci_check_error (ccErrBadParam); } if (!in_owner_invalidate_function ) { err = cci_check_error (ccErrBadParam); } if (!err) { callback = malloc (sizeof (*callback)); if (callback) { *callback = ccs_callback_initializer; } else { err = cci_check_error (ccErrNoMem); } } if (!err) { err = ccs_server_client_for_pipe (in_client_pipe, &client); } if (!err) { err = ccs_pipe_copy (&callback->client_pipe, in_client_pipe); } if (!err) { err = ccs_pipe_copy (&callback->reply_pipe, in_reply_pipe); } if (!err) { callback->client_pipe = in_client_pipe; callback->reply_pipe = in_reply_pipe; callback->invalid_object_err = in_invalid_object_err; callback->owner = in_owner; callback->owner_invalidate = in_owner_invalidate_function; err = ccs_client_add_callback (client, callback); } if (!err) { *out_callback = callback; callback = NULL; } ccs_callback_release (callback); return cci_check_error (err); } /* ------------------------------------------------------------------------ */ cc_int32 ccs_callback_release (ccs_callback_t io_callback) { cc_int32 err = ccNoError; if (!err && io_callback) { ccs_client_t client = NULL; if (io_callback->pending) { err = ccs_server_send_reply (io_callback->reply_pipe, io_callback->invalid_object_err, NULL); io_callback->pending = 0; } if (!err) { err = ccs_server_client_for_pipe (io_callback->client_pipe, &client); } if (!err && client) { /* if client object still has a reference to us, remove it */ err = ccs_client_remove_callback (client, io_callback); } if (!err) { ccs_pipe_release (io_callback->client_pipe); ccs_pipe_release (io_callback->reply_pipe); free (io_callback); } } return cci_check_error (err); } /* ------------------------------------------------------------------------ */ cc_int32 ccs_callback_invalidate (ccs_callback_t io_callback) { cc_int32 err = ccNoError; if (!io_callback) { err = cci_check_error (ccErrBadParam); } if (!err) { io_callback->pending = 0; /* client is dead, don't try to talk to it */ if (io_callback->owner_invalidate) { err = io_callback->owner_invalidate (io_callback->owner, io_callback); } else { cci_debug_printf ("WARNING %s() unable to notify callback owner!", __FUNCTION__); } } return cci_check_error (err); } /* ------------------------------------------------------------------------ */ cc_int32 ccs_callback_reply_to_client (ccs_callback_t io_callback, k5_ipc_stream in_stream) { cc_int32 err = ccNoError; if (!io_callback) { err = cci_check_error (ccErrBadParam); } if (!err) { if (io_callback->pending) { cci_debug_printf ("%s: callback %p replying to client.", __FUNCTION__, io_callback); err = ccs_server_send_reply (io_callback->reply_pipe, err, in_stream); if (err) { cci_debug_printf ("WARNING %s() called on a lock belonging to a dead client!", __FUNCTION__); } io_callback->pending = 0; } else { cci_debug_printf ("WARNING %s() called on non-pending callback!", __FUNCTION__); } } return cci_check_error (err); } /* ------------------------------------------------------------------------ */ cc_uint32 ccs_callback_is_pending (ccs_callback_t in_callback, cc_uint32 *out_pending) { cc_int32 err = ccNoError; if (!in_callback) { err = cci_check_error (ccErrBadParam); } if (!out_pending) { err = cci_check_error (ccErrBadParam); } if (!err) { *out_pending = in_callback->pending; } return cci_check_error (err); } /* ------------------------------------------------------------------------ */ cc_int32 ccs_callback_is_for_client_pipe (ccs_callback_t in_callback, ccs_pipe_t in_client_pipe, cc_uint32 *out_is_for_client_pipe) { cc_int32 err = ccNoError; if (!in_callback ) { err = cci_check_error (ccErrBadParam); } if (!ccs_pipe_valid (in_client_pipe)) { err = cci_check_error (ccErrBadParam); } if (!out_is_for_client_pipe ) { err = cci_check_error (ccErrBadParam); } if (!err) { err = ccs_pipe_compare (in_callback->client_pipe, in_client_pipe, out_is_for_client_pipe); } return cci_check_error (err); } /* ------------------------------------------------------------------------ */ cc_int32 ccs_callback_client_pipe (ccs_callback_t in_callback, ccs_pipe_t *out_client_pipe) { cc_int32 err = ccNoError; if (!in_callback ) { err = cci_check_error (ccErrBadParam); } if (!out_client_pipe) { err = cci_check_error (ccErrBadParam); } if (!err) { *out_client_pipe = in_callback->client_pipe; } return cci_check_error (err); } krb5-1.16/src/ccapi/server/ccs_callback.h0000644000704600001450000000466513211554426020122 0ustar ghudsonlibuuid/* ccapi/server/ccs_callback.h */ /* * Copyright 2006 Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #ifndef CCS_CALLBACK_H #define CCS_CALLBACK_H #include "ccs_types.h" struct ccs_callback_owner_d; typedef struct ccs_callback_owner_d *ccs_callback_owner_t; typedef cc_int32 (*ccs_callback_owner_invalidate_t) (ccs_callback_owner_t, ccs_callback_t); cc_int32 ccs_callback_new (ccs_callback_t *out_callback, cc_int32 in_invalid_object_err, ccs_pipe_t in_client_pipe, ccs_pipe_t in_reply_pipe, ccs_callback_owner_t in_owner, ccs_callback_owner_invalidate_t in_owner_invalidate_function); cc_int32 ccs_callback_release (ccs_callback_t io_callback); cc_int32 ccs_callback_invalidate (ccs_callback_t io_callback); cc_int32 ccs_callback_reply_to_client (ccs_callback_t io_callback, k5_ipc_stream in_stream); cc_uint32 ccs_callback_is_pending (ccs_callback_t in_callback, cc_uint32 *out_pending); cc_int32 ccs_callback_is_for_client_pipe (ccs_callback_t in_callback, ccs_pipe_t in_client_pipe, cc_uint32 *out_is_for_client_pipe); cc_int32 ccs_callback_client_pipe (ccs_callback_t in_callback, ccs_pipe_t *out_client_pipe); #endif /* CCS_CALLBACK_H */ krb5-1.16/src/ccapi/server/ccs_os_pipe.h0000644000704600001450000000322213211554426020010 0ustar ghudsonlibuuid/* ccapi/server/ccs_os_pipe.h */ /* * Copyright 2006 Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #ifndef CCS_OS_PIPE_H #define CCS_OS_PIPE_H #include "ccs_types.h" cc_int32 ccs_os_pipe_valid (ccs_pipe_t in_pipe); cc_int32 ccs_os_pipe_compare (ccs_pipe_t in_pipe, ccs_pipe_t in_compare_to_pipe, cc_uint32 *out_equal); cc_int32 ccs_os_pipe_copy (ccs_pipe_t *out_pipe, ccs_pipe_t in_pipe); cc_int32 ccs_os_pipe_release (ccs_pipe_t io_pipe); #endif /* CCS_OS_PIPE_H */ krb5-1.16/src/ccapi/server/ccs_os_server.h0000644000704600001450000000321013211554426020356 0ustar ghudsonlibuuid/* ccapi/server/ccs_os_server.h */ /* * Copyright 2006 Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #ifndef CCS_OS_SERVER_H #define CCS_OS_SERVER_H #include "ccs_types.h" cc_int32 ccs_os_server_initialize (int argc, const char *argv[]); cc_int32 ccs_os_server_cleanup (int argc, const char *argv[]); cc_int32 ccs_os_server_listen_loop (int argc, const char *argv[]); cc_int32 ccs_os_server_send_reply (ccs_pipe_t in_reply_pipe, k5_ipc_stream in_reply_stream); #endif /* CCS_OS_SERVER_H */ krb5-1.16/src/ccapi/server/ccs_array.c0000644000704600001450000002433713211554426017475 0ustar ghudsonlibuuid/* ccapi/server/ccs_array.c */ /* * Copyright 2006, 2007 Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #include "ccs_common.h" #include "cci_array_internal.h" /* ------------------------------------------------------------------------ */ static cc_int32 ccs_client_object_release (cci_array_object_t io_client) { return cci_check_error (ccs_client_release ((ccs_client_t) io_client)); } /* ------------------------------------------------------------------------ */ cc_int32 ccs_client_array_new (ccs_client_array_t *out_array) { return cci_array_new (out_array, ccs_client_object_release); } /* ------------------------------------------------------------------------ */ cc_int32 ccs_client_array_release (ccs_client_array_t io_array) { return cci_array_release (io_array); } /* ------------------------------------------------------------------------ */ cc_uint64 ccs_client_array_count (ccs_client_array_t in_array) { return cci_array_count (in_array); } /* ------------------------------------------------------------------------ */ ccs_client_t ccs_client_array_object_at_index (ccs_client_array_t io_array, cc_uint64 in_position) { return (ccs_client_t) cci_array_object_at_index (io_array, in_position); } /* ------------------------------------------------------------------------ */ cc_int32 ccs_client_array_insert (ccs_client_array_t io_array, ccs_client_t in_client, cc_uint64 in_position) { return cci_array_insert (io_array, (cci_array_object_t) in_client, in_position); } /* ------------------------------------------------------------------------ */ cc_int32 ccs_client_array_remove (ccs_client_array_t io_array, cc_uint64 in_position) { return cci_array_remove (io_array, in_position); } #ifdef TARGET_OS_MAC #pragma mark - #endif /* ------------------------------------------------------------------------ */ static cc_int32 ccs_lock_object_release (cci_array_object_t io_lock) { return cci_check_error (ccs_lock_release ((ccs_lock_t) io_lock)); } /* ------------------------------------------------------------------------ */ cc_int32 ccs_lock_array_new (ccs_lock_array_t *out_array) { return cci_array_new (out_array, ccs_lock_object_release); } /* ------------------------------------------------------------------------ */ cc_int32 ccs_lock_array_release (ccs_lock_array_t io_array) { return cci_array_release (io_array); } /* ------------------------------------------------------------------------ */ cc_uint64 ccs_lock_array_count (ccs_lock_array_t in_array) { return cci_array_count (in_array); } /* ------------------------------------------------------------------------ */ ccs_lock_t ccs_lock_array_object_at_index (ccs_lock_array_t io_array, cc_uint64 in_position) { return (ccs_lock_t) cci_array_object_at_index (io_array, in_position); } /* ------------------------------------------------------------------------ */ cc_int32 ccs_lock_array_insert (ccs_lock_array_t io_array, ccs_lock_t in_lock, cc_uint64 in_position) { return cci_array_insert (io_array, (cci_array_object_t) in_lock, in_position); } /* ------------------------------------------------------------------------ */ cc_int32 ccs_lock_array_remove (ccs_lock_array_t io_array, cc_uint64 in_position) { return cci_array_remove (io_array, in_position); } /* ------------------------------------------------------------------------ */ cc_int32 ccs_lock_array_move (ccs_lock_array_t io_array, cc_uint64 in_position, cc_uint64 in_new_position, cc_uint64 *out_real_new_position) { return cci_array_move (io_array, in_position, in_new_position, out_real_new_position); } #ifdef TARGET_OS_MAC #pragma mark - #endif /* ------------------------------------------------------------------------ */ static cc_int32 ccs_callback_object_release (cci_array_object_t io_callback) { return cci_check_error (ccs_callback_release ((ccs_callback_t) io_callback)); } /* ------------------------------------------------------------------------ */ cc_int32 ccs_callback_array_new (ccs_callback_array_t *out_array) { return cci_array_new (out_array, ccs_callback_object_release); } /* ------------------------------------------------------------------------ */ cc_int32 ccs_callback_array_release (ccs_callback_array_t io_array) { return cci_array_release (io_array); } /* ------------------------------------------------------------------------ */ cc_uint64 ccs_callback_array_count (ccs_callback_array_t in_array) { return cci_array_count (in_array); } /* ------------------------------------------------------------------------ */ ccs_callback_t ccs_callback_array_object_at_index (ccs_callback_array_t io_array, cc_uint64 in_position) { return (ccs_callback_t) cci_array_object_at_index (io_array, in_position); } /* ------------------------------------------------------------------------ */ cc_int32 ccs_callback_array_insert (ccs_callback_array_t io_array, ccs_callback_t in_callback, cc_uint64 in_position) { return cci_array_insert (io_array, (cci_array_object_t) in_callback, in_position); } /* ------------------------------------------------------------------------ */ cc_int32 ccs_callback_array_remove (ccs_callback_array_t io_array, cc_uint64 in_position) { return cci_array_remove (io_array, in_position); } #ifdef TARGET_OS_MAC #pragma mark - #endif /* ------------------------------------------------------------------------ */ cc_int32 ccs_callbackref_array_new (ccs_callbackref_array_t *out_array) { /* Ref arrays do not own their contents; pass NULL for release function */ return cci_array_new (out_array, NULL); } /* ------------------------------------------------------------------------ */ cc_int32 ccs_callbackref_array_release (ccs_callbackref_array_t io_array) { return cci_array_release (io_array); } /* ------------------------------------------------------------------------ */ cc_uint64 ccs_callbackref_array_count (ccs_callbackref_array_t in_array) { return cci_array_count (in_array); } /* ------------------------------------------------------------------------ */ ccs_callback_t ccs_callbackref_array_object_at_index (ccs_callbackref_array_t io_array, cc_uint64 in_position) { return (ccs_callback_t) cci_array_object_at_index (io_array, in_position); } /* ------------------------------------------------------------------------ */ cc_int32 ccs_callbackref_array_insert (ccs_callbackref_array_t io_array, ccs_callback_t in_callback, cc_uint64 in_position) { return cci_array_insert (io_array, (cci_array_object_t) in_callback, in_position); } /* ------------------------------------------------------------------------ */ cc_int32 ccs_callbackref_array_remove (ccs_callbackref_array_t io_array, cc_uint64 in_position) { return cci_array_remove (io_array, in_position); } #ifdef TARGET_OS_MAC #pragma mark - #endif /* ------------------------------------------------------------------------ */ cc_int32 ccs_iteratorref_array_new (ccs_iteratorref_array_t *out_array) { /* Ref arrays do not own their contents; pass NULL for release function */ return cci_array_new (out_array, NULL); } /* ------------------------------------------------------------------------ */ cc_int32 ccs_iteratorref_array_release (ccs_iteratorref_array_t io_array) { return cci_array_release (io_array); } /* ------------------------------------------------------------------------ */ cc_uint64 ccs_iteratorref_array_count (ccs_iteratorref_array_t in_array) { return cci_array_count (in_array); } /* ------------------------------------------------------------------------ */ ccs_generic_list_iterator_t ccs_iteratorref_array_object_at_index (ccs_iteratorref_array_t io_array, cc_uint64 in_position) { return (ccs_generic_list_iterator_t) cci_array_object_at_index (io_array, in_position); } /* ------------------------------------------------------------------------ */ cc_int32 ccs_iteratorref_array_insert (ccs_iteratorref_array_t io_array, ccs_generic_list_iterator_t in_iterator, cc_uint64 in_position) { return cci_array_insert (io_array, (cci_array_object_t) in_iterator, in_position); } /* ------------------------------------------------------------------------ */ cc_int32 ccs_iteratorref_array_remove (ccs_iteratorref_array_t io_array, cc_uint64 in_position) { return cci_array_remove (io_array, in_position); } krb5-1.16/src/ccapi/server/ccs_pipe.c0000644000704600001450000000414313211554426017305 0ustar ghudsonlibuuid/* ccapi/server/ccs_pipe.c */ /* * Copyright 2006 Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #include "ccs_common.h" #include "ccs_os_pipe.h" /* ------------------------------------------------------------------------ */ cc_int32 ccs_pipe_valid (ccs_pipe_t in_pipe) { return ccs_os_pipe_valid (in_pipe); } /* ------------------------------------------------------------------------ */ cc_int32 ccs_pipe_compare (ccs_pipe_t in_pipe, ccs_pipe_t in_compare_to_pipe, cc_uint32 *out_equal) { return ccs_os_pipe_compare (in_pipe, in_compare_to_pipe, out_equal); } /* ------------------------------------------------------------------------ */ cc_int32 ccs_pipe_copy (ccs_pipe_t *out_pipe, ccs_pipe_t in_pipe) { return ccs_os_pipe_copy (out_pipe, in_pipe); } /* ------------------------------------------------------------------------ */ cc_int32 ccs_pipe_release (ccs_pipe_t io_pipe) { return ccs_os_pipe_release (io_pipe); } krb5-1.16/src/ccapi/server/ccs_lock_state.c0000644000704600001450000004450013211554426020501 0ustar ghudsonlibuuid/* ccapi/server/ccs_lock_state.c */ /* * Copyright 2006, 2007 Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #include "ccs_common.h" struct ccs_lock_state_d { cc_int32 invalid_object_err; cc_int32 pending_lock_err; cc_int32 no_lock_err; ccs_lock_array_t locks; cc_uint64 first_pending_lock_index; }; struct ccs_lock_state_d ccs_lock_state_initializer = { 1, 1, 1, NULL, 0 }; /* ------------------------------------------------------------------------ */ cc_int32 ccs_lock_state_new (ccs_lock_state_t *out_lock_state, cc_int32 in_invalid_object_err, cc_int32 in_pending_lock_err, cc_int32 in_no_lock_err) { cc_int32 err = ccNoError; ccs_lock_state_t lock_state = NULL; if (!out_lock_state) { err = cci_check_error (ccErrBadParam); } if (!err) { lock_state = malloc (sizeof (*lock_state)); if (lock_state) { *lock_state = ccs_lock_state_initializer; } else { err = cci_check_error (ccErrNoMem); } } if (!err) { err = ccs_lock_array_new (&lock_state->locks); } if (!err) { lock_state->invalid_object_err = in_invalid_object_err; lock_state->pending_lock_err = in_pending_lock_err; lock_state->no_lock_err = in_no_lock_err; *out_lock_state = lock_state; lock_state = NULL; } ccs_lock_state_release (lock_state); return cci_check_error (err); } /* ------------------------------------------------------------------------ */ cc_int32 ccs_lock_state_release (ccs_lock_state_t io_lock_state) { cc_int32 err = ccNoError; if (!err && io_lock_state) { ccs_lock_array_release (io_lock_state->locks); free (io_lock_state); } return cci_check_error (err); } #ifdef TARGET_OS_MAC #pragma mark - #endif /* ------------------------------------------------------------------------ */ static cc_int32 ccs_lock_status_add_pending_lock (ccs_lock_state_t io_lock_state, ccs_pipe_t in_client_pipe, ccs_pipe_t in_reply_pipe, cc_uint32 in_lock_type, cc_uint64 *out_lock_index) { cc_int32 err = ccNoError; ccs_lock_t lock = NULL; if (!io_lock_state ) { err = cci_check_error (ccErrBadParam); } if (!ccs_pipe_valid (in_client_pipe)) { err = cci_check_error (ccErrBadParam); } if (!ccs_pipe_valid (in_reply_pipe) ) { err = cci_check_error (ccErrBadParam); } if (!err) { err = ccs_lock_new (&lock, in_lock_type, io_lock_state->invalid_object_err, in_client_pipe, in_reply_pipe, io_lock_state); } if (!err) { err = ccs_lock_array_insert (io_lock_state->locks, lock, ccs_lock_array_count (io_lock_state->locks)); if (!err) { lock = NULL; /* take ownership */ } } if (!err) { *out_lock_index = ccs_lock_array_count (io_lock_state->locks) - 1; } ccs_lock_release (lock); return cci_check_error (err); } /* ------------------------------------------------------------------------ */ static cc_int32 ccs_lock_status_remove_lock (ccs_lock_state_t io_lock_state, cc_uint64 in_lock_index) { cc_int32 err = ccNoError; if (!io_lock_state) { err = cci_check_error (ccErrBadParam); } if (!err) { err = ccs_lock_array_remove (io_lock_state->locks, in_lock_index); if (!err && in_lock_index < io_lock_state->first_pending_lock_index) { io_lock_state->first_pending_lock_index--; } } return cci_check_error (err); } /* ------------------------------------------------------------------------ */ static cc_int32 ccs_lock_status_grant_lock (ccs_lock_state_t io_lock_state, cc_uint64 in_pending_lock_index) { cc_int32 err = ccNoError; ccs_lock_t pending_lock = NULL; cc_uint32 type = 0; if (!io_lock_state) { err = cci_check_error (ccErrBadParam); } if (!err) { pending_lock = ccs_lock_array_object_at_index (io_lock_state->locks, in_pending_lock_index); if (!pending_lock || in_pending_lock_index < io_lock_state->first_pending_lock_index) { err = cci_check_error (ccErrBadParam); } } if (!err) { err = ccs_lock_type (pending_lock, &type); } if (!err && (type == cc_lock_upgrade || type == cc_lock_downgrade)) { /* lock upgrades or downgrades. Find the old lock and remove it. */ ccs_pipe_t pending_client_pipe = CCS_PIPE_NULL; err = ccs_lock_client_pipe (pending_lock, &pending_client_pipe); if (!err) { cc_uint64 i; for (i = 0; !err && i < io_lock_state->first_pending_lock_index; i++) { ccs_lock_t lock = ccs_lock_array_object_at_index (io_lock_state->locks, i); cc_uint32 is_lock_for_client = 0; err = ccs_lock_is_for_client_pipe (lock, pending_client_pipe, &is_lock_for_client); if (!err && is_lock_for_client) { cci_debug_printf ("%s: Removing old lock %p at index %d to replace with pending lock %p.", __FUNCTION__, lock, (int) i, pending_lock); err = ccs_lock_status_remove_lock (io_lock_state, i); if (!err) { i--; in_pending_lock_index--; /* We removed one so back up an index */ } break; } } } } if (!err) { cc_uint64 new_lock_index = 0; err = ccs_lock_array_move (io_lock_state->locks, in_pending_lock_index, io_lock_state->first_pending_lock_index, &new_lock_index); if (!err) { io_lock_state->first_pending_lock_index++; } } if (!err) { err = ccs_lock_grant_lock (pending_lock); } return cci_check_error (err); } #ifdef TARGET_OS_MAC #pragma mark - #endif /* ------------------------------------------------------------------------ */ static cc_int32 ccs_lock_state_check_pending_lock (ccs_lock_state_t io_lock_state, ccs_pipe_t in_pending_lock_client_pipe, cc_uint32 in_pending_lock_type, cc_uint32 *out_grant_lock) { cc_int32 err = ccNoError; cc_uint32 is_write_locked = 0; cc_uint32 client_has_lock = 0; cc_uint32 other_clients_have_locks = 0; cc_uint32 client_lock_type = 0; cc_uint64 client_lock_index = 0; cc_uint32 grant_lock = 0; if (!io_lock_state ) { err = cci_check_error (ccErrBadParam); } if (!ccs_pipe_valid (in_pending_lock_client_pipe)) { err = cci_check_error (ccErrBadParam); } if (!out_grant_lock ) { err = cci_check_error (ccErrBadParam); } if (!err) { cc_uint64 i; cc_uint64 lock_count = io_lock_state->first_pending_lock_index; for (i = 0; !err && i < lock_count; i++) { ccs_lock_t lock = ccs_lock_array_object_at_index (io_lock_state->locks, i); cc_uint32 lock_type = 0; cc_uint32 lock_is_for_client = 0; err = ccs_lock_type (lock, &lock_type); if (!err) { err = ccs_lock_is_for_client_pipe (lock, in_pending_lock_client_pipe, &lock_is_for_client); } if (!err) { if (lock_type == cc_lock_write || lock_type == cc_lock_upgrade) { is_write_locked = 1; } if (!lock_is_for_client) { other_clients_have_locks = 1; } else if (!client_has_lock) { /* only record type of 1st lock */ client_has_lock = 1; client_lock_type = lock_type; client_lock_index = i; } } } } if (!err) { cc_uint64 lock_count = io_lock_state->first_pending_lock_index; if (in_pending_lock_type == cc_lock_write) { if (client_has_lock) { err = cci_check_error (ccErrBadLockType); } else { grant_lock = (lock_count == 0); } } else if (in_pending_lock_type == cc_lock_read) { if (client_has_lock) { err = cci_check_error (ccErrBadLockType); } else { grant_lock = !is_write_locked; } } else if (in_pending_lock_type == cc_lock_upgrade) { if (!client_has_lock || (client_lock_type != cc_lock_read && client_lock_type != cc_lock_downgrade)) { err = cci_check_error (ccErrBadLockType); } else { /* don't grant if other clients have read locks */ grant_lock = !other_clients_have_locks; } } else if (in_pending_lock_type == cc_lock_downgrade) { if (!client_has_lock || (client_lock_type != cc_lock_write && client_lock_type != cc_lock_upgrade)) { err = cci_check_error (ccErrBadLockType); } else { /* downgrades can never block */ grant_lock = 1; } } else { err = cci_check_error (ccErrBadLockType); } } if (!err) { *out_grant_lock = grant_lock; } return cci_check_error (err); } /* ------------------------------------------------------------------------ */ static cc_int32 ccs_lock_status_try_to_grant_pending_locks (ccs_lock_state_t io_lock_state) { cc_int32 err = ccNoError; cc_uint32 done = 0; if (!io_lock_state) { err = cci_check_error (ccErrBadParam); } /* Look at the pending locks and see if we can grant them. * Note that downgrade locks mean we must check all pending locks each pass * since a downgrade lock might be last in the list. */ while (!err && !done) { cc_uint64 i; cc_uint64 count = ccs_lock_array_count (io_lock_state->locks); cc_uint32 granted_lock = 0; for (i = io_lock_state->first_pending_lock_index; !err && i < count; i++) { ccs_lock_t lock = ccs_lock_array_object_at_index (io_lock_state->locks, i); cc_uint32 lock_type = 0; ccs_pipe_t client_pipe = CCS_PIPE_NULL; cc_uint32 can_grant_lock_now = 0; err = ccs_lock_client_pipe (lock, &client_pipe); if (!err) { err = ccs_lock_type (lock, &lock_type); } if (!err) { err = ccs_lock_state_check_pending_lock (io_lock_state, client_pipe, lock_type, &can_grant_lock_now); } if (!err && can_grant_lock_now) { err = ccs_lock_status_grant_lock (io_lock_state, i); if (!err) { granted_lock = 1; } } } if (!err && !granted_lock) { /* we walked over all the locks and couldn't grant any of them */ done = 1; } } return cci_check_error (err); } #ifdef TARGET_OS_MAC #pragma mark - #endif /* ------------------------------------------------------------------------ */ cc_int32 ccs_lock_state_add (ccs_lock_state_t io_lock_state, ccs_pipe_t in_client_pipe, ccs_pipe_t in_reply_pipe, cc_uint32 in_lock_type, cc_uint32 in_block, cc_uint32 *out_will_send_reply) { cc_int32 err = ccNoError; cc_uint32 can_grant_lock_now = 0; if (!io_lock_state ) { err = cci_check_error (ccErrBadParam); } if (!ccs_pipe_valid (in_client_pipe)) { err = cci_check_error (ccErrBadParam); } if (!ccs_pipe_valid (in_reply_pipe) ) { err = cci_check_error (ccErrBadParam); } if (!out_will_send_reply ) { err = cci_check_error (ccErrBadParam); } if (!err) { /* Sanity check: if there are any pending locks for this client * the client must have timed out waiting for our reply. Remove any * existing pending locks for the client. */ cc_uint64 i; for (i = io_lock_state->first_pending_lock_index; !err && i < ccs_lock_array_count (io_lock_state->locks); i++) { ccs_lock_t lock = ccs_lock_array_object_at_index (io_lock_state->locks, i); cc_uint32 has_pending_lock_for_client = 0; err = ccs_lock_is_for_client_pipe (lock, in_client_pipe, &has_pending_lock_for_client); if (!err && has_pending_lock_for_client) { cci_debug_printf ("WARNING %s: Removing unexpected pending lock %p at index %d.", __FUNCTION__, lock, (int) i); err = ccs_lock_status_remove_lock (io_lock_state, i); if (!err) { i--; /* We removed one so back up an index */ } } } } if (!err) { err = ccs_lock_state_check_pending_lock (io_lock_state, in_client_pipe, in_lock_type, &can_grant_lock_now); } if (!err) { if (!can_grant_lock_now && (in_block == cc_lock_noblock)) { err = cci_check_error (io_lock_state->pending_lock_err); } else { cc_uint64 new_lock_index = 0; err = ccs_lock_status_add_pending_lock (io_lock_state, in_client_pipe, in_reply_pipe, in_lock_type, &new_lock_index); if (!err && can_grant_lock_now) { err = ccs_lock_status_grant_lock (io_lock_state, new_lock_index); if (!err && (in_lock_type == cc_lock_downgrade)) { /* downgrades can allow us to grant other locks */ err = ccs_lock_status_try_to_grant_pending_locks (io_lock_state); } } } } if (!err) { /* ccs_lock_state_add sends its replies via callback so caller shouldn't */ *out_will_send_reply = 1; } return cci_check_error (err); } /* ------------------------------------------------------------------------ */ cc_int32 ccs_lock_state_remove (ccs_lock_state_t io_lock_state, ccs_pipe_t in_client_pipe) { cc_int32 err = ccNoError; cc_uint32 found_lock = 0; if (!io_lock_state ) { err = cci_check_error (ccErrBadParam); } if (!ccs_pipe_valid (in_client_pipe)) { err = cci_check_error (ccErrBadParam); } if (!err) { cc_uint64 i; /* Remove all locks for this client. * There should only be one so warn if there are multiple */ for (i = 0; !err && i < io_lock_state->first_pending_lock_index; i++) { ccs_lock_t lock = ccs_lock_array_object_at_index (io_lock_state->locks, i); cc_uint32 is_for_client = 0; err = ccs_lock_is_for_client_pipe (lock, in_client_pipe, &is_for_client); if (!err && is_for_client) { if (found_lock) { cci_debug_printf ("WARNING %s: Found multiple locks for client.", __FUNCTION__); } found_lock = 1; cci_debug_printf ("%s: Removing lock %p at index %d.", __FUNCTION__, lock, (int) i); err = ccs_lock_status_remove_lock (io_lock_state, i); if (!err) { i--; /* We removed one so back up an index */ } } } } if (!err && !found_lock) { err = cci_check_error (io_lock_state->no_lock_err); } if (!err) { err = ccs_lock_status_try_to_grant_pending_locks (io_lock_state); } return cci_check_error (err); } /* ------------------------------------------------------------------------ */ cc_int32 ccs_lock_state_invalidate_lock (ccs_lock_state_t io_lock_state, ccs_lock_t in_lock) { cc_int32 err = ccNoError; if (!io_lock_state) { err = ccErrBadParam; } if (!err) { cc_uint64 i; cc_uint64 count = ccs_lock_array_count (io_lock_state->locks); for (i = 0; !err && i < count; i++) { ccs_lock_t lock = ccs_lock_array_object_at_index (io_lock_state->locks, i); if (lock == in_lock) { err = ccs_lock_status_remove_lock (io_lock_state, i); if (!err) { err = ccs_lock_status_try_to_grant_pending_locks (io_lock_state); break; } } } } return cci_check_error (err); } krb5-1.16/src/ccapi/server/win/0000755000704600001450000000000013211554426016147 5ustar ghudsonlibuuidkrb5-1.16/src/ccapi/server/win/WorkItem.cpp0000644000704600001450000000776413211554426020432 0ustar ghudsonlibuuid/* * $Header$ * * Copyright 2008 Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #include #include "assert.h" #pragma warning (disable : 4996) #include "win-utils.h" #include "WorkItem.h" extern "C" { #include "cci_debugging.h" } // CountedBuffer makes a copy of the data. Each CountedBuffer must be deleted. void deleteBuffer(char** buf) { if (*buf) { delete [](*buf); *buf = NULL; } } // WorkItem contains a CountedBuffer which must be deleted, // so each WorkItem must be deleted. WorkItem::WorkItem(k5_ipc_stream buf, WIN_PIPE* pipe, const long type, const long sst) : _buf(buf), _rpcmsg(type), _pipe(pipe), _sst(sst) { } WorkItem::WorkItem(const WorkItem& item) : _buf(NULL), _rpcmsg(0), _pipe(NULL), _sst(0) { k5_ipc_stream _buf = NULL; krb5int_ipc_stream_new(&_buf); krb5int_ipc_stream_write(_buf, krb5int_ipc_stream_data(item.payload()), krb5int_ipc_stream_size(item.payload()) ); WorkItem(_buf, item._pipe, item._rpcmsg, item._sst); } WorkItem::WorkItem() : _buf(NULL), _rpcmsg(CCMSG_INVALID), _pipe(NULL), _sst(0) { } WorkItem::~WorkItem() { if (_buf) krb5int_ipc_stream_release(_buf); if (_pipe) ccs_win_pipe_release(_pipe); } const k5_ipc_stream WorkItem::take_payload() { k5_ipc_stream temp = payload(); _buf = NULL; return temp; } WIN_PIPE* WorkItem::take_pipe() { WIN_PIPE* temp = pipe(); _pipe = NULL; return temp; } WorkList::WorkList() { assert(InitializeCriticalSectionAndSpinCount(&cs, 0x80000400)); } WorkList::~WorkList() { // Delete any WorkItems in the queue: WorkItem* item; cci_debug_printf("%s", __FUNCTION__); char buf[2048]; char* pbuf = (char*)buf; while (remove(&item)) { cci_debug_printf("WorkList::~WorkList() deleting %s", item->print(pbuf)); delete item; } DeleteCriticalSection(&cs); } char* WorkItem::print(char* buf) { sprintf(buf, "WorkItem msg#:%d sst:%ld pipe:<%s>/0x%X", _rpcmsg, _sst, ccs_win_pipe_getUuid(_pipe), ccs_win_pipe_getHandle(_pipe)); return buf; } int WorkList::initialize() { hEvent = CreateEvent(NULL, FALSE, FALSE, NULL); return 0; } int WorkList::cleanup() { CloseHandle(hEvent); hEvent = INVALID_HANDLE_VALUE; return 0; } void WorkList::wait() { WaitForSingleObject(hEvent, INFINITE); } int WorkList::add(WorkItem* item) { EnterCriticalSection(&cs); wl.push_front(item); LeaveCriticalSection(&cs); SetEvent(hEvent); return 1; } int WorkList::remove(WorkItem** item) { bool bEmpty; bEmpty = wl.empty() & 1; if (!bEmpty) { EnterCriticalSection(&cs); *item = wl.back(); wl.pop_back(); LeaveCriticalSection(&cs); } return !bEmpty; } krb5-1.16/src/ccapi/server/win/ccs_win_pipe.h0000644000704600001450000000506213211554426020765 0ustar ghudsonlibuuid/* ccapi/server/win/ccs_win_pipe.h */ /* * Copyright 2008 Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #ifndef _ccs_win_pipe_h_ #define _ccs_win_pipe_h_ #include "windows.h" #include "CredentialsCache.h" /* ------------------------------------------------------------------------ */ /* On Windows, a pipe is a struct containing a UUID and a handle. Both the UUID and handle are supplied by the client. The UUID is used to build the client's reply endpoint. The handle is to the requesting client thread's thread local storage struct, so that the client's one and only reply handler can put reply data where the requesting thread will be able to see it. */ struct ccs_win_pipe_t { char* uuid; UINT64 clientHandle; }; typedef struct ccs_win_pipe_t WIN_PIPE; struct ccs_win_pipe_t* ccs_win_pipe_new(const char* uuid, const UINT64 h); cc_int32 ccs_win_pipe_release (const WIN_PIPE* io_pipe); cc_int32 ccs_win_pipe_compare (const WIN_PIPE* win_pipe_1, const WIN_PIPE* win_pipe_2, cc_uint32 *out_equal); cc_int32 ccs_win_pipe_copy (WIN_PIPE** out_pipe, const WIN_PIPE* in_pipe); cc_int32 ccs_win_pipe_valid (const WIN_PIPE* in_pipe); char* ccs_win_pipe_getUuid (const WIN_PIPE* in_pipe); UINT64 ccs_win_pipe_getHandle (const WIN_PIPE* in_pipe); #endif // _ccs_win_pipe_h_ krb5-1.16/src/ccapi/server/win/ccs_win_pipe.c0000644000704600001450000001173713211554426020766 0ustar ghudsonlibuuid/* ccapi/server/win/ccs_win_pipe.c */ /* * Copyright 2008 Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #include "assert.h" #include #include #include "ccs_win_pipe.h" #include "cci_debugging.h" /* Ref: struct ccs_win_pipe_t { char* uuid; UINT64 clientHandle; } */ /* ------------------------------------------------------------------------ */ struct ccs_win_pipe_t* ccs_win_pipe_new (const char* uuid, const UINT64 h) { cc_int32 err = ccNoError; struct ccs_win_pipe_t* out_pipe = NULL; char* uuidCopy = NULL; if (!err) { if (!uuid) {err = cci_check_error(ccErrBadParam);} } if (!err) { uuidCopy = (char*)malloc(1+strlen(uuid)); if (!uuidCopy) {err = cci_check_error(ccErrBadParam);} strcpy(uuidCopy, uuid); } if (!err) { out_pipe = (struct ccs_win_pipe_t*)malloc(sizeof(struct ccs_win_pipe_t)); if (!out_pipe) {err = cci_check_error(ccErrBadParam);} out_pipe->uuid = uuidCopy; out_pipe->clientHandle = h; } #if 0 cci_debug_printf("0x%X = %s(%s, 0x%X)", out_pipe, __FUNCTION__, uuid, h); #endif return out_pipe; } /* ------------------------------------------------------------------------ */ cc_int32 ccs_win_pipe_copy (WIN_PIPE** out_pipe, const WIN_PIPE* in_pipe) { *out_pipe = ccs_win_pipe_new( ccs_win_pipe_getUuid (in_pipe), ccs_win_pipe_getHandle(in_pipe) ); return (*out_pipe) ? ccNoError : ccErrBadParam; } /* ------------------------------------------------------------------------ */ cc_int32 ccs_win_pipe_release(const WIN_PIPE* in_pipe) { cc_int32 err = ccNoError; if (!ccs_win_pipe_valid(in_pipe)) {err = cci_check_error(ccErrBadParam);} if (!err) { if (!in_pipe->uuid) free(in_pipe->uuid); if (!in_pipe) free(in_pipe); } return err; } /* ------------------------------------------------------------------------ */ cc_int32 ccs_win_pipe_valid (const WIN_PIPE* in_pipe) { if (!in_pipe) { cci_check_error(ccErrBadParam); return FALSE; } if (!in_pipe->uuid) { cci_check_error(ccErrBadParam); return FALSE; } return TRUE; } /* ------------------------------------------------------------------------ */ cc_int32 ccs_win_pipe_compare (const WIN_PIPE* in_pipe_1, const WIN_PIPE* in_pipe_2, cc_uint32 *out_equal) { cc_int32 err = ccNoError; int seq = 0; *out_equal = FALSE; if (!ccs_win_pipe_valid(in_pipe_1)) {err = cci_check_error(ccErrBadParam);} if (!ccs_win_pipe_valid(in_pipe_2)) {err = cci_check_error(ccErrBadParam);} if (!out_equal) {err = cci_check_error(ccErrBadParam);} /* A disconnect doesn't have a tls* with it -- only the uuid. SO only compare the uuids. */ if (!err) { seq = strcmp( ccs_win_pipe_getUuid(in_pipe_1), ccs_win_pipe_getUuid(in_pipe_2) ); *out_equal = (seq == 0); } return err; } /* ------------------------------------------------------------------------ */ char* ccs_win_pipe_getUuid (const WIN_PIPE* in_pipe) { char* result = NULL; if (!ccs_win_pipe_valid(in_pipe)) {cci_check_error(ccErrBadParam);} else {result = in_pipe->uuid;} return result; } /* ------------------------------------------------------------------------ */ UINT64 ccs_win_pipe_getHandle (const WIN_PIPE* in_pipe) { UINT64 result = 0; if (!ccs_win_pipe_valid(in_pipe)) {cci_check_error(ccErrBadParam);} else {result = in_pipe->clientHandle;} return result; } krb5-1.16/src/ccapi/server/win/ccs_os_server.cpp0000644000704600001450000010344613211554426021522 0ustar ghudsonlibuuid/* * $Header$ * * Copyright 2008 Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #include "process.h" #include "windows.h" extern "C" { #include "ccs_common.h" #include "ccs_os_notify.h" #include "ccs_os_server.h" #include "ccs_reply.h" #include "ccs_request.h" #include "win-utils.h" #include "ccutils.h" } #include "WorkQueue.h" #include "util.h" #include "opts.hxx" #include "init.hxx" #pragma warning (disable : 4996) BOOL bListen = TRUE; /* Why aren't bool and true defined? */ const char* sessID = NULL; /* The logon session we are running on behalf of. */ time_t _sst = 0; unsigned char* pszNetworkAddress = NULL; unsigned char* pszStringBinding = NULL; BOOL bRpcHandleInited = FALSE; _RPC_ASYNC_STATE* rpcState = NULL; /* Thread procedures can take only one void* argument. We put all the args we want to pass into this struct and then pass a pointer to the struct: */ struct RpcRcvArgs { char* networkAddress; unsigned char* protocolSequence; unsigned char* sessID; /* Used for this server's endpoint */ unsigned char* uuid; /* Used for client's UUID */ ParseOpts::Opts* opts; RPC_STATUS status; } rpcargs = { NULL, /* pszNetworkAddress */ (unsigned char*)"ncalrpc", /* pszProtocolSequence */ NULL, /* sessID placeholder */ NULL, /* uuid placeholder */ NULL }; /* Opts placeholder */ /* Command line format: argv[0] Program name argv[1] session ID to use argv[2] "D" Debug: go into infinite loop in ccs_os_server_initialize so process can be attached in debugger. Any other value: continue */ #define N_FIXED_ARGS 3 #define SERVER_REPLY_RPC_HANDLE ccs_reply_IfHandle /* Forward declarations: */ void receiveLoop(void* rpcargs); void connectionListener(void* rpcargs); void Usage(const char* argv0); void printError(TCHAR* msg); void setMySST() {_sst = time(&_sst);} time_t getMySST() {return _sst;} RPC_STATUS send_connection_reply(ccs_pipe_t in_pipe); void RPC_ENTRY clientListener( _RPC_ASYNC_STATE*, void* Context, RPC_ASYNC_EVENT Event); RPC_STATUS RPC_ENTRY sec_callback( IN RPC_IF_ID *Interface, IN void *Context); RPC_STATUS send_init(char* clientUUID); //DWORD alloc_name(LPSTR* pname, LPSTR postfix); /* The layout of the rest of this module: The four entrypoints defined in ccs_os_server.h: ccs_os_server_initialize cc_int32 ccs_os_server_cleanup cc_int32 ccs_os_server_listen_loop cc_int32 ccs_os_server_send_reply Other routines needed by those four. */ /* ------------------------------------------------------------------------ */ cc_int32 ccs_os_server_initialize (int argc, const char *argv[]) { cc_int32 err = 0; ParseOpts::Opts opts = { 0 }; ParseOpts PO; BOOL bAdjustedShutdown = FALSE; HMODULE hKernel32 = GetModuleHandle("kernel32"); if (!err) { sessID = argv[1]; setMySST(); opts.cMinCalls = 1; opts.cMaxCalls = 20; opts.fDontWait = TRUE; #ifdef CCAPI_TEST_OPTIONS PO.SetValidOpts("kemnfubc"); #else PO.SetValidOpts("kc"); #endif PO.Parse(opts, argc, (char**)argv); // while(*argv[2] == 'D') {} /* Hang here to attach process with debugger. */ if (hKernel32) { typedef BOOL (WINAPI *FP_SetProcessShutdownParameters)(DWORD, DWORD); FP_SetProcessShutdownParameters pSetProcessShutdownParameters = (FP_SetProcessShutdownParameters) GetProcAddress(hKernel32, "SetProcessShutdownParameters"); if (pSetProcessShutdownParameters) { bAdjustedShutdown = pSetProcessShutdownParameters(100, 0); } } cci_debug_printf("%s Shutdown Parameters", bAdjustedShutdown ? "Adjusted" : "Did not adjust"); err = Init::Initialize(); } // if (!err) { // if (opts.bShutdown) { // status = shutdown_server(opts.pszEndpoint); // } // } // else { // status = startup_server(opts); // } if (!err) { err = worklist_initialize(); } if (err) { Init::Cleanup(); fprintf( stderr, "An error occured while %s the server (%u)\n", opts.bShutdown ? "shutting down" : "starting/running", err); exit(cci_check_error (err)); } return cci_check_error (err); } /* ------------------------------------------------------------------------ */ cc_int32 ccs_os_server_cleanup (int argc, const char *argv[]) { cc_int32 err = 0; cci_debug_printf("%s for user <%s> shutting down.", argv[0], argv[1]); worklist_cleanup(); return cci_check_error (err); } /* ------------------------------------------------------------------------ */ /* This function takes work items off the work queue and executes them. * This is the one and only place where the multi-threaded Windows code * calls into the single-threaded common code. * * The actual 'listening' for requests from clients happens after receiveloop * establishes the RPC endpoint the clients will connect to and the RPC procedures * put the work items into the work queue. */ cc_int32 ccs_os_server_listen_loop (int argc, const char *argv[]) { cc_int32 err = 0; uintptr_t threadStatus; ParseOpts::Opts opts = { 0 }; ParseOpts PO; BOOL bQuitIfNoClients = FALSE; opts.cMinCalls = 1; opts.cMaxCalls = 20; opts.fDontWait = TRUE; #ifdef CCAPI_TEST_OPTIONS PO.SetValidOpts("kemnfubc"); #else PO.SetValidOpts("kc"); #endif PO.Parse(opts, argc, (char**)argv); //++ debug stuff #define INFO_BUFFER_SIZE 32767 TCHAR infoBuf[INFO_BUFFER_SIZE]; DWORD bufCharCount = INFO_BUFFER_SIZE; // Get and display the user name. bufCharCount = INFO_BUFFER_SIZE; if( !GetUserName( infoBuf, &bufCharCount ) ) printError( TEXT("GetUserName") ); //-- /* Sending the reply from within the request RPC handler doesn't seem to work. So we listen for requests in a separate thread and put the requests in a queue. */ rpcargs.sessID = (unsigned char*)sessID; rpcargs.opts = &opts; /// TODO: check for NULL handle, error, etc. probably move to initialize func... threadStatus = _beginthread(receiveLoop, 0, (void*)&rpcargs); /* We handle the queue entries here. Work loop: */ while (ccs_server_client_count() > 0 || !bQuitIfNoClients) { worklist_wait(); while (!worklist_isEmpty()) { k5_ipc_stream buf = NULL; long rpcmsg = CCMSG_INVALID; time_t serverStartTime = 0xDEADDEAD; RPC_STATUS status = 0; char* uuid = NULL; k5_ipc_stream stream = NULL; ccs_pipe_t pipe = NULL; ccs_pipe_t pipe2 = NULL; if (worklist_remove(&rpcmsg, &pipe, &buf, &serverStartTime)) { uuid = ccs_win_pipe_getUuid(pipe); #if 0 cci_debug_printf("%s: processing WorkItem msg:%ld pipeUUID:<%s> pipeHandle:0x%X SST:%ld", __FUNCTION__, rpcmsg, uuid, ccs_win_pipe_getHandle(pipe), serverStartTime); #endif if (serverStartTime <= getMySST()) { switch (rpcmsg) { case CCMSG_CONNECT: { cci_debug_printf(" Processing CONNECT"); rpcargs.uuid = (unsigned char*)uuid; // Even if a disconnect message is received before this code finishes, // it won't be dequeued and processed until after this code finishes. // So we can add the client after starting the connection listener. connectionListener((void*)&rpcargs); status = rpcargs.status; if (!status) { status = ccs_server_add_client(pipe); } if (!status) {status = send_connection_reply(pipe);} break; } case CCMSG_DISCONNECT: { cci_debug_printf(" Processing DISCONNECT"); if (!status) { status = ccs_server_remove_client(pipe); } break; } case CCMSG_REQUEST: cci_debug_printf(" Processing REQUEST"); ccs_pipe_copy(&pipe2, pipe); // Dispatch message here, setting both pipes to the client UUID: err = ccs_server_handle_request (pipe, pipe2, buf); break; case CCMSG_PING: cci_debug_printf(" Processing PING"); err = krb5int_ipc_stream_new (&stream); err = krb5int_ipc_stream_write(stream, "This is a test of the emergency broadcasting system", 52); err = ccs_os_server_send_reply(pipe, stream); break; case CCMSG_QUIT: bQuitIfNoClients = TRUE; break; default: cci_debug_printf("Huh? Received invalid message type %ld from UUID:<%s>", rpcmsg, uuid); break; } if (buf) krb5int_ipc_stream_release(buf); /* Don't free uuid, which was allocated here. A pointer to it is in the rpcargs struct which was passed to connectionListener which will be received by ccapi_listen when the client exits. ccapi_listen needs the uuid to know which client to disconnect. */ } // Server's start time is different from what the client thinks. // That means the server has rebooted since the client connected. else { cci_debug_printf("Whoops! Server has rebooted since client established connection."); } } else {cci_debug_printf("Huh? Queue not empty but no item to remove.");} } } return cci_check_error (err); } /* ------------------------------------------------------------------------ */ cc_int32 ccs_os_server_send_reply (ccs_pipe_t in_pipe, k5_ipc_stream in_reply_stream) { /* ccs_pipe_t in_reply_pipe is a char* reply endpoint. k5_ipc_stream in_reply_stream is the data to be sent. */ cc_int32 err = 0; char* uuid = ccs_win_pipe_getUuid(in_pipe); UINT64 h = ccs_win_pipe_getHandle(in_pipe); if (!err) { err = send_init(uuid); // Sets RPC handle to be used. } if (!err) { RpcTryExcept { long status; ccs_rpc_request_reply( // make call with user message CCMSG_REQUEST_REPLY, /* Message type */ (unsigned char*)&h, /* client's tspdata* */ (unsigned char*)uuid, getMySST(), krb5int_ipc_stream_size(in_reply_stream), /* Length of buffer */ (const unsigned char*)krb5int_ipc_stream_data(in_reply_stream), /* Data buffer */ &status ); /* Return code */ } RpcExcept(1) { cci_check_error(RpcExceptionCode()); } RpcEndExcept } /* The calls to the remote procedures are complete. */ /* Free whatever we allocated: */ err = RpcBindingFree(&SERVER_REPLY_RPC_HANDLE); return cci_check_error (err); } /* Windows-specific routines: */ void Usage(const char* argv0) { printf("Usage:\n"); printf("%s [m maxcalls] [n mincalls] [f dontwait] [h|?]]\n", argv0); printf(" CCAPI server process.\n"); printf(" h|? whow usage message. <\n"); } /* ------------------------------------------------------------------------ */ /* The receive thread repeatedly issues RpcServerListen. When a message arrives, it is handled in the RPC procedure. */ void receiveLoop(void* rpcargs) { struct RpcRcvArgs* rcvargs = (struct RpcRcvArgs*)rpcargs; RPC_STATUS status = FALSE; unsigned char* pszSecurity = NULL; LPSTR endpoint = NULL; LPSTR event_name = NULL; PSECURITY_DESCRIPTOR psd = NULL; HANDLE hEvent = 0; Init::InitInfo info; cci_debug_printf("THREAD BEGIN: %s", __FUNCTION__); status = Init::Info(info); /* Build complete RPC endpoint using previous CCAPI implementation: */ if (!status) { if (!rcvargs->opts->pszEndpoint) { if (!status) { status = alloc_name(&endpoint, "ep", isNT()); } if (!status) { status = alloc_name(&event_name, "startup", isNT()); } if (!status) { hEvent = OpenEvent(EVENT_MODIFY_STATE, FALSE, event_name); // We ignore any error opening the event because we do not know who started us. // [Comment paraphrased from previous implementation, whence it was copied.] } } else { endpoint = rcvargs->opts->pszEndpoint; } } cci_debug_printf("%s Registering endpoint %s", __FUNCTION__, endpoint); if (!status && isNT()) { status = alloc_own_security_descriptor_NT(&psd); } if (!status) { status = RpcServerUseProtseqEp(rcvargs->protocolSequence, rcvargs->opts->cMaxCalls, (RPC_CSTR)endpoint, rcvargs->opts->bDontProtect ? 0 : psd); // SD } if (!status) { status = RpcServerRegisterAuthInfo(0, // server principal RPC_C_AUTHN_WINNT, 0, 0); } while (bListen && !status) { cci_debug_printf("%s is listening ...", __FUNCTION__); if (!info.isNT) { status = RpcServerRegisterIf(ccs_request_ServerIfHandle, // interface NULL, // MgrTypeUuid NULL); // MgrEpv; null means use default } else { status = info.fRpcServerRegisterIfEx(ccs_request_ServerIfHandle, // interface NULL, // MgrTypeUuid NULL, // MgrEpv; 0 means default RPC_IF_ALLOW_SECURE_ONLY, rcvargs->opts->cMaxCalls, rcvargs->opts->bSecCallback ? (RPC_IF_CALLBACK_FN*)sec_callback : 0 ); } if (!status) { status = RpcServerListen(rcvargs->opts->cMinCalls, rcvargs->opts->cMaxCalls, rcvargs->opts->fDontWait); } if (!status) { if (rcvargs->opts->fDontWait) { if (hEvent) SetEvent(hEvent); // Ignore any error -- SetEvent is an optimization. status = RpcMgmtWaitServerListen(); } } } if (status) { // Cleanup in case of errors: if (hEvent) CloseHandle(hEvent); free_alloc_p(&event_name); free_alloc_p(&psd); if (endpoint && (endpoint != rcvargs->opts->pszEndpoint)) free_alloc_p(&endpoint); } // tell main thread to shutdown since it won't receive any more messages worklist_add(CCMSG_QUIT, NULL, NULL, 0); _endthread(); } // End receiveLoop #if 0 return status; } #endif /* ------------------------------------------------------------------------ */ /* The connection listener thread waits forever for a call to the CCAPI_CLIENT_ endpoint, ccapi_listen function to complete. If the call completes or gets an RPC exception, it means the client has disappeared. A separate connectionListener is started for each client that has connected to the server. */ void connectionListener(void* rpcargs) { struct RpcRcvArgs* rcvargs = (struct RpcRcvArgs*)rpcargs; RPC_STATUS status = FALSE; char* endpoint; unsigned char* pszOptions = NULL; unsigned char * pszUuid = NULL; endpoint = clientEndpoint((char*)rcvargs->uuid); rpcState = (RPC_ASYNC_STATE*)malloc(sizeof(RPC_ASYNC_STATE)); status = RpcAsyncInitializeHandle(rpcState, sizeof(RPC_ASYNC_STATE)); cci_debug_printf(""); cci_debug_printf("%s About to LISTEN to <%s>", __FUNCTION__, endpoint); rpcState->UserInfo = rcvargs->uuid; rpcState->NotificationType = RpcNotificationTypeApc; rpcState->u.APC.NotificationRoutine = clientListener; rpcState->u.APC.hThread = 0; /* [If in use] Free previous binding: */ if (bRpcHandleInited) { // Free previous binding (could have been used to call ccapi_listen // in a different client thread). // Don't check result or update status. RpcStringFree(&pszStringBinding); RpcBindingFree(&SERVER_REPLY_RPC_HANDLE); bRpcHandleInited = FALSE; } /* Set up binding to the client's endpoint: */ if (!status) { status = RpcStringBindingCompose( pszUuid, pszProtocolSequence, pszNetworkAddress, (RPC_CSTR)endpoint, pszOptions, &pszStringBinding); } /* Set the binding handle that will be used to bind to the server. */ if (!status) { status = RpcBindingFromStringBinding(pszStringBinding, &SERVER_REPLY_RPC_HANDLE); } if (!status) {bRpcHandleInited = TRUE;} RpcTryExcept { cci_debug_printf(" Calling remote procedure ccapi_listen"); ccapi_listen(rpcState, SERVER_REPLY_RPC_HANDLE, CCMSG_LISTEN, &status); /* Asynchronous call will return immediately. */ } RpcExcept(1) { status = cci_check_error(RpcExceptionCode()); } RpcEndExcept rcvargs->status = status; } // End connectionListener void RPC_ENTRY clientListener( _RPC_ASYNC_STATE* pAsync, void* Context, RPC_ASYNC_EVENT Event ) { ccs_pipe_t pipe = ccs_win_pipe_new((char*)pAsync->UserInfo, NULL); cci_debug_printf("%s(0x%X, ...) async routine for <0x%X:%s>!", __FUNCTION__, pAsync, pAsync->UserInfo, pAsync->UserInfo); worklist_add( CCMSG_DISCONNECT, pipe, NULL, /* No payload with connect request */ (const time_t)0 ); /* No server session number with connect request */ } void printError( TCHAR* msg ) { DWORD eNum; TCHAR sysMsg[256]; TCHAR* p; eNum = GetLastError( ); FormatMessage( FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, eNum, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), sysMsg, 256, NULL ); // Trim the end of the line and terminate it with a null p = sysMsg; while( ( *p > 31 ) || ( *p == 9 ) ) ++p; do { *p-- = 0; } while( ( p >= sysMsg ) && ( ( *p == '.' ) || ( *p < 33 ) ) ); // Display the message cci_debug_printf("%s failed with error %d (%s)", msg, eNum, sysMsg); } RPC_STATUS send_init(char* clientUUID) { RPC_STATUS status; unsigned char * pszUuid = NULL; unsigned char * pszOptions = NULL; /* Use a convenience function to concatenate the elements of */ /* the string binding into the proper sequence. */ status = RpcStringBindingCompose(pszUuid, pszProtocolSequence, pszNetworkAddress, (unsigned char*)clientEndpoint(clientUUID), pszOptions, &pszStringBinding); if (status) {return (status);} /* Set the binding handle that will be used to bind to the RPC server [the 'client']. */ status = RpcBindingFromStringBinding(pszStringBinding, &SERVER_REPLY_RPC_HANDLE); return (status); } RPC_STATUS send_finish() { RPC_STATUS status; /* Can't shut down client -- it runs listen function which */ /* server uses to detect the client going away. */ /* The calls to the remote procedures are complete. */ /* Free the string and the binding handle */ status = RpcStringFree(&pszStringBinding); // remote calls done; unbind if (status) {return (status);} status = RpcBindingFree(&SERVER_REPLY_RPC_HANDLE); // remote calls done; unbind return (status); } RPC_STATUS send_connection_reply(ccs_pipe_t in_pipe) { char* uuid = ccs_win_pipe_getUuid (in_pipe); UINT64 h = ccs_win_pipe_getHandle(in_pipe); RPC_STATUS status = send_init(uuid); RpcTryExcept { ccs_rpc_connect_reply( // make call with user message CCMSG_CONNECT_REPLY, /* Message type */ (unsigned char*)&h, /* client's tspdata* */ (unsigned char*)uuid, getMySST(), /* Server's session number = it's start time */ &status ); /* Return code */ } RpcExcept(1) { cci_check_error(RpcExceptionCode()); } RpcEndExcept status = send_finish(); return (status); } #if 0 DWORD alloc_name(LPSTR* pname, LPSTR postfix) { DWORD len = strlen(sessID) + 1 + strlen(postfix) + 1; *pname = (LPSTR)malloc(len); if (!*pname) return GetLastError(); _snprintf(*pname, len, "%s.%s", sessID, postfix); return 0; } #endif RPC_STATUS GetPeerName( RPC_BINDING_HANDLE hClient, LPTSTR pszClientName, int iMaxLen) { RPC_STATUS Status = RPC_S_OK; RPC_BINDING_HANDLE hServer = NULL; PTBYTE pszStringBinding = NULL; PTBYTE pszClientNetAddr = NULL; PTBYTE pszProtSequence = NULL; memset(pszClientName, 0, iMaxLen * sizeof(TCHAR)); __try { // Create a partially bound server handle from the client handle. Status = RpcBindingServerFromClient (hClient, &hServer); if (Status != RPC_S_OK) __leave; // Get the partially bound server string binding and parse it. Status = RpcBindingToStringBinding (hServer, &pszStringBinding); if (Status != RPC_S_OK) __leave; // String binding only contains protocol sequence and client // address, and is not currently implemented for named pipes. Status = RpcStringBindingParse (pszStringBinding, NULL, &pszProtSequence, &pszClientNetAddr, NULL, NULL); if (Status != RPC_S_OK) __leave; int iLen = lstrlen(pszClientName) + 1; if (iMaxLen < iLen) Status = RPC_S_BUFFER_TOO_SMALL; lstrcpyn(pszClientName, (LPCTSTR)pszClientNetAddr, iMaxLen); } __finally { if (pszProtSequence) RpcStringFree (&pszProtSequence); if (pszClientNetAddr) RpcStringFree (&pszClientNetAddr); if (pszStringBinding) RpcStringFree (&pszStringBinding); if (hServer) RpcBindingFree (&hServer); } return Status; } struct client_auth_info { RPC_AUTHZ_HANDLE authz_handle; unsigned char* server_principal; // need to RpcFreeString this ULONG authn_level; ULONG authn_svc; ULONG authz_svc; }; RPC_STATUS GetClientId( RPC_BINDING_HANDLE hClient, char* client_id, int max_len, client_auth_info* info ) { RPC_AUTHZ_HANDLE authz_handle = 0; unsigned char* server_principal = 0; ULONG authn_level = 0; ULONG authn_svc = 0; ULONG authz_svc = 0; RPC_STATUS status = 0; memset(client_id, 0, max_len); if (info) { memset(info, 0, sizeof(client_auth_info)); } status = RpcBindingInqAuthClient(hClient, &authz_handle, info ? &server_principal : 0, &authn_level, &authn_svc, &authz_svc); if (status == RPC_S_OK) { if (info) { info->server_principal = server_principal; info->authz_handle = authz_handle; info->authn_level = authn_level; info->authn_svc = authn_svc; info->authz_svc = authz_svc; } if (authn_svc == RPC_C_AUTHN_WINNT) { WCHAR* username = (WCHAR*)authz_handle; int len = lstrlenW(username) + 1; if (max_len < len) status = RPC_S_BUFFER_TOO_SMALL; _snprintf(client_id, max_len, "%S", username); } else { status = RPC_S_UNKNOWN_AUTHN_SERVICE; } } return status; } char* rpc_error_to_string( RPC_STATUS status ) { switch(status) { case RPC_S_OK: return "OK"; case RPC_S_INVALID_BINDING: return "Invalid binding"; case RPC_S_WRONG_KIND_OF_BINDING: return "Wrong binding"; case RPC_S_BINDING_HAS_NO_AUTH: RpcRaiseException(RPC_S_BINDING_HAS_NO_AUTH); return "Binding has no auth"; default: return "BUG: I am confused"; } } void print_client_info( RPC_STATUS peer_status, const char* peer_name, RPC_STATUS client_status, const char* client_id, client_auth_info* info ) { if (peer_status == RPC_S_OK || peer_status == RPC_S_BUFFER_TOO_SMALL) { cci_debug_printf("%s Peer Name is \"%s\"", __FUNCTION__, peer_name); } else { cci_debug_printf("%s Error %u getting Peer Name (%s)", __FUNCTION__, peer_status, rpc_error_to_string(peer_status)); } if (client_status == RPC_S_OK || client_status == RPC_S_BUFFER_TOO_SMALL) { if (info) { cci_debug_printf("%s Client Auth Info" "\tServer Principal: %s\n" "\tAuthentication Level: %d\n" "\tAuthentication Service: %d\n" "\tAuthorization Service: %d\n", __FUNCTION__, info->server_principal, info->authn_level, info->authn_svc, info->authz_svc); } cci_debug_printf("%s Client ID is \"%s\"", __FUNCTION__, client_id); } else { cci_debug_printf("%s Error getting Client Info (%u = %s)", __FUNCTION__, client_status, rpc_error_to_string(client_status)); } } DWORD sid_check() { DWORD status = 0; HANDLE hToken_c = 0; HANDLE hToken_s = 0; PTOKEN_USER ptu_c = 0; PTOKEN_USER ptu_s = 0; DWORD len = 0; BOOL bImpersonate = FALSE; // Note GetUserName will fail while impersonating at identify // level. The workaround is to impersonate, OpenThreadToken, // revert, call GetTokenInformation, and finally, call // LookupAccountSid. // XXX - Note: This workaround does not appear to work. // OpenThreadToken fails with error 1346: "Either a requid // impersonation level was not provided or the provided // impersonation level is invalid". status = RpcImpersonateClient(0); if (!status) { bImpersonate = TRUE; if (!OpenThreadToken(GetCurrentThread(), TOKEN_QUERY, FALSE, &hToken_c)) status = GetLastError(); } if (!status) { status = RpcRevertToSelf(); } if (!status) { bImpersonate = FALSE; len = 0; GetTokenInformation(hToken_c, TokenUser, ptu_c, 0, &len); if (len == 0) status = 1; } if (!status) { if (!(ptu_c = (PTOKEN_USER)LocalAlloc(0, len))) status = GetLastError(); } if (!status) { if (!GetTokenInformation(hToken_c, TokenUser, ptu_c, len, &len)) status = GetLastError(); } if (!status) { if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hToken_s)) status = GetLastError(); } if (!status) { len = 0; GetTokenInformation(hToken_s, TokenUser, ptu_s, 0, &len); if (len == 0) status = GetLastError(); } if (!status) { if (!(ptu_s = (PTOKEN_USER)LocalAlloc(0, len))) status = GetLastError(); } if (!status) { if (!GetTokenInformation(hToken_s, TokenUser, ptu_s, len, &len)) status = GetLastError(); } if (!EqualSid(ptu_s->User.Sid, ptu_c->User.Sid)) status = RPC_S_ACCESS_DENIED; /* Cleanup: */ if (!hToken_c && !bImpersonate) cci_debug_printf("%s Cannot impersonate (%u)", __FUNCTION__, status); else if (!hToken_c) cci_debug_printf("%s Failed to open client token (%u)", __FUNCTION__, status); else if (bImpersonate) cci_debug_printf("%s Failed to revert (%u)", __FUNCTION__, status); else if (!ptu_c) cci_debug_printf("%s Failed to get client token user info (%u)", __FUNCTION__, status); else if (!hToken_s) cci_debug_printf("%s Failed to open server token (%u)", __FUNCTION__, status); else if (!ptu_s) cci_debug_printf("%s Failed to get server token user info (%u)", __FUNCTION__, status); else if (status == RPC_S_ACCESS_DENIED) cci_debug_printf("%s SID **does not** match!", __FUNCTION__); else if (status == RPC_S_OK) cci_debug_printf("%s SID matches!", __FUNCTION__); else if (status) { cci_debug_printf("%s unrecognized error %u", __FUNCTION__, status); abort(); } if (bImpersonate) RpcRevertToSelf(); if (hToken_c && hToken_c != INVALID_HANDLE_VALUE) CloseHandle(hToken_c); if (ptu_c) LocalFree(ptu_c); if (hToken_s && hToken_s != INVALID_HANDLE_VALUE) CloseHandle(hToken_s); if (ptu_s) LocalFree(ptu_s); if (status) cci_debug_printf("%s returning %u", __FUNCTION__, status); return status; } RPC_STATUS RPC_ENTRY sec_callback( IN RPC_IF_ID *Interface, IN void *Context) { char peer_name[1024]; char client_name[1024]; RPC_STATUS peer_status; RPC_STATUS client_status; cci_debug_printf("%s", __FUNCTION__); peer_status = GetPeerName(Context, peer_name, sizeof(peer_name)); client_status = GetClientId(Context, client_name, sizeof(client_name), 0); print_client_info(peer_status, peer_name, client_status, client_name, 0); DWORD sid_status = sid_check(); cci_debug_printf("%s returning (%u)", __FUNCTION__, sid_status); return sid_status; } /*********************************************************************/ /* MIDL allocate and free */ /*********************************************************************/ extern "C" void __RPC_FAR * __RPC_USER midl_user_allocate(size_t len) { return(malloc(len)); } extern "C" void __RPC_USER midl_user_free(void __RPC_FAR * ptr) { free(ptr); } /* stubs */ extern "C" cc_int32 ccs_os_notify_cache_collection_changed (ccs_cache_collection_t cc) { return 0; } extern "C" cc_int32 ccs_os_notify_ccache_changed (ccs_cache_collection_t cc, const char *name) { return 0; } krb5-1.16/src/ccapi/server/win/WorkQueue.cpp0000644000704600001450000000504613211554426020607 0ustar ghudsonlibuuid/* * $Header$ * * Copyright 2008 Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #include "WorkQueue.h" extern "C" { #include "cci_debugging.h" } #include "WorkItem.h" WorkList worklist; EXTERN_C int worklist_initialize() { return worklist.initialize(); } EXTERN_C int worklist_cleanup() { return worklist.cleanup(); } EXTERN_C void worklist_wait() { worklist.wait(); } /* C interfaces: */ EXTERN_C BOOL worklist_isEmpty() { return worklist.isEmpty() ? TRUE : FALSE; } EXTERN_C int worklist_add( const long rpcmsg, const ccs_pipe_t pipe, const k5_ipc_stream stream, const time_t serverStartTime) { return worklist.add(new WorkItem(stream, pipe, rpcmsg, serverStartTime) ); } EXTERN_C int worklist_remove(long* rpcmsg, ccs_pipe_t* pipe, k5_ipc_stream* stream, time_t* sst) { WorkItem* item = NULL; cc_int32 err = worklist.remove(&item); *rpcmsg = item->type(); *pipe = item->take_pipe(); *stream = item->take_payload(); *sst = item->sst(); delete item; return err; } krb5-1.16/src/ccapi/server/win/workitem.h0000644000704600001450000000234313211554426020163 0ustar ghudsonlibuuid#ifndef __WorkItem #define __WorkItem #include #include "windows.h" extern "C" { #include "ccs_pipe.h" } class WorkItem { private: k5_ipc_stream _buf; WIN_PIPE* _pipe; const long _rpcmsg; const long _sst; public: WorkItem( k5_ipc_stream buf, WIN_PIPE* pipe, const long type, const long serverStartTime); WorkItem( const WorkItem&); WorkItem(); ~WorkItem(); const k5_ipc_stream payload() const {return _buf;} const k5_ipc_stream take_payload(); WIN_PIPE* take_pipe(); WIN_PIPE* pipe() const {return _pipe;} const long type() const {return _rpcmsg;} const long sst() const {return _sst;} char* print(char* buf); }; class WorkList { private: std::list wl; CRITICAL_SECTION cs; HANDLE hEvent; public: WorkList(); ~WorkList(); int initialize(); int cleanup(); void wait(); int add(WorkItem*); int remove(WorkItem**); bool isEmpty() {return wl.empty();} }; #endif // __WorkItem krb5-1.16/src/ccapi/server/win/ccs_os_pipe.c0000644000704600001450000000447413211554426020612 0ustar ghudsonlibuuid/* ccapi/server/win/ccs_os_pipe.c */ /* * Copyright 2008 Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #include "ccs_common.h" #include "ccs_os_pipe.h" #include "ccs_win_pipe.h" /* ------------------------------------------------------------------------ */ /* On Windows, a pipe is a struct. See ccs_win_pipe.h for details. */ /* ------------------------------------------------------------------------ */ cc_int32 ccs_os_pipe_valid (ccs_pipe_t in_pipe) { return ccs_win_pipe_valid(in_pipe); } /* ------------------------------------------------------------------------ */ cc_int32 ccs_os_pipe_copy (ccs_pipe_t* out_pipe, ccs_pipe_t in_pipe) { return ccs_win_pipe_copy( out_pipe, in_pipe); } /* ------------------------------------------------------------------------ */ cc_int32 ccs_os_pipe_release (ccs_pipe_t io_pipe) { return ccs_win_pipe_release(io_pipe); } /* ------------------------------------------------------------------------ */ cc_int32 ccs_os_pipe_compare (ccs_pipe_t pipe_1, ccs_pipe_t pipe_2, cc_uint32 *out_equal) { return ccs_win_pipe_compare(pipe_1, pipe_2, out_equal); } krb5-1.16/src/ccapi/server/win/Server.sln0000644000704600001450000000153013211554426020132 0ustar ghudsonlibuuid Microsoft Visual Studio Solution File, Format Version 9.00 # Visual Studio 2005 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Server", "Server.vcproj", "{114DCD80-6D13-4AAA-9510-B51CE6D94C1C}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Win32 = Debug|Win32 Release|Win32 = Release|Win32 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {114DCD80-6D13-4AAA-9510-B51CE6D94C1C}.Debug|Win32.ActiveCfg = Debug|Win32 {114DCD80-6D13-4AAA-9510-B51CE6D94C1C}.Debug|Win32.Build.0 = Debug|Win32 {114DCD80-6D13-4AAA-9510-B51CE6D94C1C}.Release|Win32.ActiveCfg = Release|Win32 {114DCD80-6D13-4AAA-9510-B51CE6D94C1C}.Release|Win32.Build.0 = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection EndGlobal krb5-1.16/src/ccapi/server/win/Makefile.in0000644000704600001450000001010513211554426020211 0ustar ghudsonlibuuid# makefile: Constructs the Kerberos for Windows CCAPI server. #BUILDTOP is krb5/src and is relative to krb5/src/ccapi/server/win, for making Makefile. BUILDTOP=..\..\.. CCAPI = $(BUILDTOP)\CCAPI CO = $(CCAPI)\common COWIN = $(CCAPI)\common\win CCUTIL = $(CCAPI)\common\win\OldCC SRVDIR = $(CCAPI)\server SRVWIN = $(SRVDIR)\win POSIX = $(BUILDTOP)\lib\krb5\posix SRCTMP = $(SRVWIN)\srctmp !if defined(KRB5_KFW_COMPILE) KFWINC= /I$(BUILDTOP)\..\..\krbcc\include !endif OBJS = $(OUTPRE)cci_array_internal.$(OBJEXT) \ $(OUTPRE)cci_cred_union.$(OBJEXT) \ $(OUTPRE)cci_debugging.$(OBJEXT) \ $(OUTPRE)cci_identifier.$(OBJEXT) \ $(OUTPRE)cci_message.$(OBJEXT) \ $(OUTPRE)cci_os_debugging.$(OBJEXT) \ $(OUTPRE)cci_os_identifier.$(OBJEXT) \ $(OUTPRE)ccs_array.$(OBJEXT) \ $(OUTPRE)ccs_cache_collection.$(OBJEXT) \ $(OUTPRE)ccs_callback.$(OBJEXT) \ $(OUTPRE)ccs_ccache.$(OBJEXT) \ $(OUTPRE)ccs_ccache_iterator.$(OBJEXT) \ $(OUTPRE)ccs_client.$(OBJEXT) \ $(OUTPRE)ccs_credentials.$(OBJEXT) \ $(OUTPRE)ccs_credentials_iterator.$(OBJEXT) \ $(OUTPRE)ccs_list.$(OBJEXT) \ $(OUTPRE)ccs_list_internal.$(OBJEXT) \ $(OUTPRE)ccs_lock.$(OBJEXT) \ $(OUTPRE)ccs_lock_state.$(OBJEXT) \ $(OUTPRE)ccs_os_pipe.$(OBJEXT) \ $(OUTPRE)ccs_os_server.$(OBJEXT) \ $(OUTPRE)ccs_pipe.$(OBJEXT) \ $(OUTPRE)ccs_reply_c.$(OBJEXT) \ $(OUTPRE)ccs_request_proc.$(OBJEXT) \ $(OUTPRE)ccs_server.$(OBJEXT) \ $(OUTPRE)ccs_win_pipe.$(OBJEXT) \ $(OUTPRE)ccs_request_s.$(OBJEXT) \ $(OUTPRE)ccutils.$(OBJEXT) \ $(OUTPRE)init.$(OBJEXT) \ $(OUTPRE)opts.$(OBJEXT) \ $(OUTPRE)secure.$(OBJEXT) \ $(OUTPRE)tls.$(OBJEXT) \ $(OUTPRE)util.$(OBJEXT) \ $(OUTPRE)win-utils.$(OBJEXT) \ $(OUTPRE)WorkItem.$(OBJEXT) \ $(OUTPRE)WorkQueue.$(OBJEXT) ##### Options # Because all the sources are pulled together into the temp directory SRCTMP, # the only includes we need are to directories outside of ccapi. LOCALINCLUDES = /I..\$(BUILDTOP) /I..\$(BUILDTOP)\include /I..\$(BUILDTOP)\include\krb5 $(KFWINC) \ -I..\$(BUILDTOP)\util\et /I. MIDLI = /I..\$(BUILDTOP)\include CPPFLAGS = $(CPPFLAGS) /EHsc -D_CRTAPI1=_cdecl -D_CRTAPI2=_cdecl -DWINVER=0x0501 \ -D_WIN32_WINNT=0x0501 -D_CRT_SECURE_NO_WARNINGS ##### Linker LINK = link LIBS = ..\$(SLIB) rpcrt4.lib advapi32.lib ws2_32.lib user32.lib LFLAGS = /nologo $(LOPTS) all: Makefile copysrc midl $(OUTPRE)ccapiserver.exe finish ccs_request.h ccs_request_c.c ccs_request_s.c : ccs_request.idl ccs_request.acf midl $(MIDL_OPTIMIZATION) $(MIDLI) -oldnames -cpp_cmd $(CC) -cpp_opt "-E" \ ccs_request.idl ccs_reply.h ccs_reply_c.c ccs_reply_s.c : ccs_reply.idl ccs_reply.acf midl $(MIDL_OPTIMIZATION) $(MIDLI) -oldnames -cpp_cmd $(CC) -cpp_opt "-E" \ ccs_reply.idl copysrc : echo "Copying all sources needed to build ccapiserver.exe to $(SRCTMP)" if NOT exist $(SRCTMP)\nul mkdir $(SRCTMP) xcopy /D/Y $(CO)\*.* $(SRCTMP) xcopy /D/Y $(COWIN)\*.* $(SRCTMP) xcopy /D/Y $(CCUTIL)\*.* $(SRCTMP) xcopy /D/Y $(SRVDIR)\*.* $(SRCTMP) xcopy /D/Y $(SRVWIN)\*.* $(SRCTMP) cd $(SRCTMP) if NOT exist $(OUTPRE)\nul mkdir $(OUTPRE) midl : ccs_request.h ccs_reply.h VERSIONRC = $(BUILDTOP)\..\windows\version.rc CCAPISERVERRES = $(OUTPRE)ccapiserver.res $(CCAPISERVERRES): $(VERSIONRC) $(RC) $(RCFLAGS) -DCCAPISERVER_APP -fo $@ -r $** $(OUTPRE)ccapiserver.exe: $(OBJS) $(CCAPISERVERRES) $(LINK) $(LFLAGS) /map:$*.map /out:$@ $(OBJS) $(LIBS) $(CCAPISERVERRES) $(conlibsdll) $(conflags) finish : @echo "Finished building ccapiserver.exe" cd clean: if exist $(OUTPRE)*.exe del $(OUTPRE)*.exe if exist $(OUTPRE)*.obj del $(OUTPRE)*.obj if exist $(OUTPRE)*.res del $(OUTPRE)*.res if exist $(OUTPRE)*.map del $(OUTPRE)*.map if exist $(OUTPRE)*.pdb del $(OUTPRE)*.pdb if exist *.err del *.err if exist $(SRCTMP) rmdir /s /q $(SRCTMP) krb5-1.16/src/ccapi/server/win/WorkQueue.h0000644000704600001450000000404413211554426020251 0ustar ghudsonlibuuid/* ccapi/server/win/WorkQueue.h */ /* * Copyright 2007 Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #ifndef _work_queue_h #define _work_queue_h #include "windows.h" #include "ccs_pipe.h" EXTERN_C int worklist_initialize(); EXTERN_C int worklist_cleanup(); /* Wait for work to be added to the list (via worklist_add) from another thread */ EXTERN_C void worklist_wait(); EXTERN_C BOOL worklist_isEmpty(); EXTERN_C int worklist_add( const long rpcmsg, const ccs_pipe_t pipe, const k5_ipc_stream stream, const time_t serverStartTime); EXTERN_C int worklist_remove(long* rpcmsg, ccs_pipe_t* pipe, k5_ipc_stream* stream, time_t* serverStartTime); #endif // _work_queue_h krb5-1.16/src/ccapi/server/win/Server.vcproj0000644000704600001450000001043213211554426020642 0ustar ghudsonlibuuid krb5-1.16/src/ccapi/server/win/ccs_request_proc.c0000644000704600001450000001002713211554426021656 0ustar ghudsonlibuuid/* ccapi/server/win/ccs_request_proc.c */ /* * Copyright 2008 Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #include #include #include "ccs_request.h" // header file generated by MIDL compiler #include "cci_debugging.h" #include "WorkQueue.h" #include "win-utils.h" #include "ccs_win_pipe.h" void ccs_rpc_request( const long rpcmsg, /* Message type */ const char tspHandle[], /* Client's tspdata* */ const char* pszUUID, /* Where client will listen for the reply */ const long lenRequest, /* Length of buffer */ const char pbRequest[], /* Data buffer */ const long serverStartTime, /* Which server session we're talking to */ long* return_status ) { /* Return code */ cc_int32 status = 0; k5_ipc_stream stream; UINT64* p = (UINT64*)(tspHandle); WIN_PIPE* pipe = NULL; #if 0 cci_debug_printf("%s rpcmsg:%d; UUID:<%s> SST:<%s>", __FUNCTION__, rpcmsg, pszUUID, serverStartTime); #endif status = (rpcmsg != CCMSG_REQUEST) && (rpcmsg != CCMSG_PING); if (!status) { status = krb5int_ipc_stream_new (&stream); /* Create a stream for the request data */ } if (!status) { /* Put the data into the stream */ status = krb5int_ipc_stream_write (stream, pbRequest, lenRequest); } pipe = ccs_win_pipe_new(pszUUID, *p); worklist_add(rpcmsg, pipe, stream, serverStartTime); *return_status = status; } void ccs_rpc_connect( const long rpcmsg, /* Message type */ const char tspHandle[], /* Client's tspdata* */ const char* pszUUID, /* Data buffer */ long* return_status ) { /* Return code */ UINT64* p = (UINT64*)(tspHandle); WIN_PIPE* pipe = ccs_win_pipe_new(pszUUID, *p); #if 0 cci_debug_printf("%s; rpcmsg:%d; UUID: <%s>", __FUNCTION__, rpcmsg, pszUUID); #endif worklist_add( rpcmsg, pipe, NULL, /* No payload with connect request */ (const time_t)0 ); /* No server session number with connect request */ } // 'Authentication' is client setting a value in a file and the server // returning that value plus one. CC_UINT32 ccs_authenticate(const CC_CHAR* name) { HANDLE hMap = 0; PDWORD pvalue = 0; CC_UINT32 result = 0; DWORD status = 0; #if 0 cci_debug_printf("%s ( %s )", __FUNCTION__, name); #endif hMap = OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE, (LPSTR)name); status = !hMap; if (!status) { pvalue = (PDWORD)MapViewOfFile(hMap, FILE_MAP_WRITE, 0, 0, 0); status = !pvalue; } if (!status) { *pvalue += 1; result = *pvalue; } if (pvalue) { UnmapViewOfFile(pvalue); } if (hMap) CloseHandle(hMap); return result; } krb5-1.16/src/ccapi/server/ccs_lock.c0000644000704600001450000001677713211554426017320 0ustar ghudsonlibuuid/* ccapi/server/ccs_lock.c */ /* * Copyright 2006 Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #include "ccs_common.h" struct ccs_lock_d { cc_uint32 type; ccs_lock_state_t lock_state_owner; ccs_callback_t callback; }; struct ccs_lock_d ccs_lock_initializer = { 0, NULL, NULL }; static cc_int32 ccs_lock_invalidate_callback (ccs_callback_owner_t io_lock, ccs_callback_t in_callback); /* ------------------------------------------------------------------------ */ cc_int32 ccs_lock_new (ccs_lock_t *out_lock, cc_uint32 in_type, cc_int32 in_invalid_object_err, ccs_pipe_t in_client_pipe, ccs_pipe_t in_reply_pipe, ccs_lock_state_t in_lock_state_owner) { cc_int32 err = ccNoError; ccs_lock_t lock = NULL; if (!out_lock ) { err = cci_check_error (ccErrBadParam); } if (!ccs_pipe_valid (in_client_pipe)) { err = cci_check_error (ccErrBadParam); } if (!ccs_pipe_valid (in_reply_pipe) ) { err = cci_check_error (ccErrBadParam); } if (!in_lock_state_owner ) { err = cci_check_error (ccErrBadParam); } if (in_type != cc_lock_read && in_type != cc_lock_write && in_type != cc_lock_upgrade && in_type != cc_lock_downgrade) { err = cci_check_error (ccErrBadLockType); } if (!err) { lock = malloc (sizeof (*lock)); if (lock) { *lock = ccs_lock_initializer; } else { err = cci_check_error (ccErrNoMem); } } if (!err) { lock->type = in_type; lock->lock_state_owner = in_lock_state_owner; err = ccs_callback_new (&lock->callback, in_invalid_object_err, in_client_pipe, in_reply_pipe, (ccs_callback_owner_t) lock, ccs_lock_invalidate_callback); } if (!err) { *out_lock = lock; lock = NULL; } ccs_lock_release (lock); return cci_check_error (err); } /* ------------------------------------------------------------------------ */ cc_int32 ccs_lock_release (ccs_lock_t io_lock) { cc_int32 err = ccNoError; if (!err && io_lock) { ccs_callback_release (io_lock->callback); free (io_lock); } return cci_check_error (err); } /* ------------------------------------------------------------------------ */ static cc_int32 ccs_lock_invalidate_callback (ccs_callback_owner_t io_lock, ccs_callback_t in_callback) { cc_int32 err = ccNoError; if (!io_lock ) { err = cci_check_error (ccErrBadParam); } if (!in_callback) { err = cci_check_error (ccErrBadParam); } if (!err) { ccs_lock_t lock = (ccs_lock_t) io_lock; err = ccs_lock_state_invalidate_lock (lock->lock_state_owner, lock); } return cci_check_error (err); } /* ------------------------------------------------------------------------ */ cc_int32 ccs_lock_grant_lock (ccs_lock_t io_lock) { cc_int32 err = ccNoError; if (!io_lock) { err = cci_check_error (ccErrBadParam); } if (!err) { err = ccs_callback_reply_to_client (io_lock->callback, NULL); } return cci_check_error (err); } /* ------------------------------------------------------------------------ */ cc_uint32 ccs_lock_is_pending (ccs_lock_t in_lock, cc_uint32 *out_pending) { cc_int32 err = ccNoError; if (!in_lock ) { err = cci_check_error (ccErrBadParam); } if (!out_pending) { err = cci_check_error (ccErrBadParam); } if (!err) { err = ccs_callback_is_pending (in_lock->callback, out_pending); } return cci_check_error (err); } /* ------------------------------------------------------------------------ */ cc_int32 ccs_lock_type (ccs_lock_t in_lock, cc_uint32 *out_lock_type) { cc_int32 err = ccNoError; if (!in_lock ) { err = cci_check_error (ccErrBadParam); } if (!out_lock_type) { err = cci_check_error (ccErrBadParam); } if (!err) { *out_lock_type = in_lock->type; } return cci_check_error (err); } /* ------------------------------------------------------------------------ */ cc_int32 ccs_lock_is_read_lock (ccs_lock_t in_lock, cc_uint32 *out_is_read_lock) { cc_int32 err = ccNoError; if (!in_lock ) { err = cci_check_error (ccErrBadParam); } if (!out_is_read_lock) { err = cci_check_error (ccErrBadParam); } if (!err) { *out_is_read_lock = (in_lock->type == cc_lock_read || in_lock->type == cc_lock_downgrade); } return cci_check_error (err); } /* ------------------------------------------------------------------------ */ cc_int32 ccs_lock_is_write_lock (ccs_lock_t in_lock, cc_uint32 *out_is_write_lock) { cc_int32 err = ccNoError; if (!in_lock ) { err = cci_check_error (ccErrBadParam); } if (!out_is_write_lock) { err = cci_check_error (ccErrBadParam); } if (!err) { *out_is_write_lock = (in_lock->type == cc_lock_write || in_lock->type == cc_lock_upgrade); } return cci_check_error (err); } /* ------------------------------------------------------------------------ */ cc_int32 ccs_lock_is_for_client_pipe (ccs_lock_t in_lock, ccs_pipe_t in_client_pipe, cc_uint32 *out_is_for_client_pipe) { cc_int32 err = ccNoError; if (!in_lock ) { err = cci_check_error (ccErrBadParam); } if (!ccs_pipe_valid (in_client_pipe)) { err = cci_check_error (ccErrBadParam); } if (!out_is_for_client_pipe ) { err = cci_check_error (ccErrBadParam); } if (!err) { err = ccs_callback_is_for_client_pipe (in_lock->callback, in_client_pipe, out_is_for_client_pipe); } return cci_check_error (err); } /* ------------------------------------------------------------------------ */ cc_int32 ccs_lock_client_pipe (ccs_lock_t in_lock, ccs_pipe_t *out_client_pipe) { cc_int32 err = ccNoError; if (!in_lock ) { err = cci_check_error (ccErrBadParam); } if (!out_client_pipe) { err = cci_check_error (ccErrBadParam); } if (!err) { err = ccs_callback_client_pipe (in_lock->callback, out_client_pipe); } return cci_check_error (err); } krb5-1.16/src/ccapi/server/ccs_client.c0000644000704600001450000001665313211554426017637 0ustar ghudsonlibuuid/* ccapi/server/ccs_client.c */ /* * Copyright 2006 Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #include "ccs_common.h" struct ccs_client_d { ccs_pipe_t client_pipe; /* The following arrays do not own their contents */ ccs_callbackref_array_t callbacks; ccs_iteratorref_array_t iterators; }; struct ccs_client_d ccs_client_initializer = { CCS_PIPE_NULL, NULL, NULL }; /* ------------------------------------------------------------------------ */ cc_int32 ccs_client_new (ccs_client_t *out_client, ccs_pipe_t in_client_pipe) { cc_int32 err = ccNoError; ccs_client_t client = NULL; if (!out_client ) { err = cci_check_error (ccErrBadParam); } if (!ccs_pipe_valid (in_client_pipe)) { err = cci_check_error (ccErrBadParam); } if (!err) { client = malloc (sizeof (*client)); if (client) { *client = ccs_client_initializer; } else { err = cci_check_error (ccErrNoMem); } } if (!err) { err = ccs_callbackref_array_new (&client->callbacks); } if (!err) { err = ccs_iteratorref_array_new (&client->iterators); } if (!err) { err = ccs_pipe_copy (&client->client_pipe, in_client_pipe); } if (!err) { *out_client = client; client = NULL; } ccs_client_release (client); return cci_check_error (err); } /* ------------------------------------------------------------------------ */ cc_int32 ccs_client_release (ccs_client_t io_client) { cc_int32 err = ccNoError; if (!err && io_client) { cc_uint64 i; cc_uint64 callback_count = ccs_callbackref_array_count (io_client->callbacks); cc_uint64 iterator_count = ccs_iteratorref_array_count (io_client->iterators); for (i = 0; !err && i < callback_count; i++) { ccs_callback_t callback = ccs_callbackref_array_object_at_index (io_client->callbacks, i); cci_debug_printf ("%s: Invalidating callback reference %p.", __FUNCTION__, callback); ccs_callback_invalidate (callback); } for (i = 0; !err && i < iterator_count; i++) { ccs_generic_list_iterator_t iterator = ccs_iteratorref_array_object_at_index (io_client->iterators, i); cci_debug_printf ("%s: Invalidating iterator reference %p.", __FUNCTION__, iterator); ccs_generic_list_iterator_invalidate (iterator); } ccs_callbackref_array_release (io_client->callbacks); ccs_iteratorref_array_release (io_client->iterators); ccs_pipe_release (io_client->client_pipe); free (io_client); } return cci_check_error (err); } /* ------------------------------------------------------------------------ */ cc_int32 ccs_client_add_callback (ccs_client_t io_client, ccs_callback_t in_callback) { cc_int32 err = ccNoError; if (!io_client ) { err = cci_check_error (ccErrBadParam); } if (!in_callback) { err = cci_check_error (ccErrBadParam); } if (!err) { err = ccs_callbackref_array_insert (io_client->callbacks, in_callback, ccs_callbackref_array_count (io_client->callbacks)); } return cci_check_error (err); } /* ------------------------------------------------------------------------ */ cc_int32 ccs_client_remove_callback (ccs_client_t io_client, ccs_callback_t in_callback) { cc_int32 err = ccNoError; cc_uint32 found_callback = 0; if (!io_client) { err = cci_check_error (ccErrBadParam); } if (!err) { cc_uint64 i; cc_uint64 lock_count = ccs_callbackref_array_count (io_client->callbacks); for (i = 0; !err && i < lock_count; i++) { ccs_callback_t callback = ccs_callbackref_array_object_at_index (io_client->callbacks, i); if (callback == in_callback) { cci_debug_printf ("%s: Removing callback reference %p.", __FUNCTION__, callback); found_callback = 1; err = ccs_callbackref_array_remove (io_client->callbacks, i); break; } } } if (!err && !found_callback) { cci_debug_printf ("%s: WARNING! callback not found.", __FUNCTION__); } return cci_check_error (err); } /* ------------------------------------------------------------------------ */ cc_int32 ccs_client_add_iterator (ccs_client_t io_client, ccs_generic_list_iterator_t in_iterator) { cc_int32 err = ccNoError; if (!io_client ) { err = cci_check_error (ccErrBadParam); } if (!in_iterator) { err = cci_check_error (ccErrBadParam); } if (!err) { err = ccs_iteratorref_array_insert (io_client->iterators, in_iterator, ccs_iteratorref_array_count (io_client->iterators)); } return cci_check_error (err); } /* ------------------------------------------------------------------------ */ cc_int32 ccs_client_remove_iterator (ccs_client_t io_client, ccs_generic_list_iterator_t in_iterator) { cc_int32 err = ccNoError; cc_uint32 found_iterator = 0; if (!io_client) { err = cci_check_error (ccErrBadParam); } if (!err) { cc_uint64 i; cc_uint64 lock_count = ccs_iteratorref_array_count (io_client->iterators); for (i = 0; !err && i < lock_count; i++) { ccs_generic_list_iterator_t iterator = ccs_iteratorref_array_object_at_index (io_client->iterators, i); if (iterator == in_iterator) { cci_debug_printf ("%s: Removing iterator reference %p.", __FUNCTION__, iterator); found_iterator = 1; err = ccs_iteratorref_array_remove (io_client->iterators, i); break; } } } if (!err && !found_iterator) { cci_debug_printf ("%s: WARNING! iterator not found.", __FUNCTION__); } return cci_check_error (err); } /* ------------------------------------------------------------------------ */ cc_int32 ccs_client_uses_pipe (ccs_client_t in_client, ccs_pipe_t in_pipe, cc_uint32 *out_uses_pipe) { cc_int32 err = ccNoError; if (!in_client ) { err = cci_check_error (ccErrBadParam); } if (!in_pipe ) { err = cci_check_error (ccErrBadParam); } if (!out_uses_pipe) { err = cci_check_error (ccErrBadParam); } if (!err) { err = ccs_pipe_compare (in_client->client_pipe, in_pipe, out_uses_pipe); } return cci_check_error (err); } krb5-1.16/src/ccapi/server/ccs_ccache.c0000644000704600001450000013147213211554426017564 0ustar ghudsonlibuuid/* ccapi/server/ccs_ccache.c */ /* * Copyright 2006, 2007 Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #include "ccs_common.h" #include "ccs_os_notify.h" struct ccs_ccache_d { cci_identifier_t identifier; ccs_lock_state_t lock_state; cc_uint32 creds_version; char *name; char *v4_principal; char *v5_principal; cc_time_t last_default_time; cc_time_t last_changed_time; cc_uint32 kdc_time_offset_v4_valid; cc_time_t kdc_time_offset_v4; cc_uint32 kdc_time_offset_v5_valid; cc_time_t kdc_time_offset_v5; ccs_credentials_list_t credentials; ccs_callback_array_t change_callbacks; }; struct ccs_ccache_d ccs_ccache_initializer = { NULL, NULL, 0, NULL, NULL, NULL, 0, 0, 0, 0, 0, 0, NULL, NULL }; /* ------------------------------------------------------------------------ */ cc_int32 ccs_ccache_new (ccs_ccache_t *out_ccache, cc_uint32 in_creds_version, const char *in_name, const char *in_principal, ccs_ccache_list_t io_ccache_list) { cc_int32 err = ccNoError; ccs_ccache_t ccache = NULL; if (!out_ccache ) { err = cci_check_error (ccErrBadParam); } if (!in_name ) { err = cci_check_error (ccErrBadParam); } if (!in_principal) { err = cci_check_error (ccErrBadParam); } if (!err) { ccache = malloc (sizeof (*ccache)); if (ccache) { *ccache = ccs_ccache_initializer; } else { err = cci_check_error (ccErrNoMem); } } if (!err) { err = ccs_server_new_identifier (&ccache->identifier); } if (!err) { err = ccs_lock_state_new (&ccache->lock_state, ccErrInvalidCCache, ccErrCCacheLocked, ccErrCCacheUnlocked); } if (!err) { ccache->name = strdup (in_name); if (!ccache->name) { err = cci_check_error (ccErrNoMem); } } if (!err) { ccache->creds_version = in_creds_version; if (ccache->creds_version == cc_credentials_v4) { ccache->v4_principal = strdup (in_principal); if (!ccache->v4_principal) { err = cci_check_error (ccErrNoMem); } } else if (ccache->creds_version == cc_credentials_v5) { ccache->v5_principal = strdup (in_principal); if (!ccache->v5_principal) { err = cci_check_error (ccErrNoMem); } } else { err = cci_check_error (ccErrBadCredentialsVersion); } } if (!err) { err = ccs_credentials_list_new (&ccache->credentials); } if (!err) { err = ccs_callback_array_new (&ccache->change_callbacks); } if (!err) { cc_uint64 now = time (NULL); cc_uint64 count = 0; err = ccs_ccache_list_count (io_ccache_list, &count); if (!err) { /* first cache is default */ ccache->last_default_time = (count == 0) ? now : 0; cci_debug_printf ("%s ccache->last_default_time is %d.", __FUNCTION__, ccache->last_default_time); ccache->last_changed_time = now; } } if (!err) { /* Add self to the list of ccaches */ err = ccs_ccache_list_add (io_ccache_list, ccache); } if (!err) { *out_ccache = ccache; ccache = NULL; } ccs_ccache_release (ccache); return cci_check_error (err); } /* ------------------------------------------------------------------------ */ cc_int32 ccs_ccache_reset (ccs_ccache_t io_ccache, ccs_cache_collection_t io_cache_collection, cc_uint32 in_creds_version, const char *in_principal) { cc_int32 err = ccNoError; char *v4_principal = NULL; char *v5_principal = NULL; ccs_credentials_list_t credentials = NULL; if (!io_ccache ) { err = cci_check_error (ccErrBadParam); } if (!io_cache_collection) { err = cci_check_error (ccErrBadParam); } if (!in_principal ) { err = cci_check_error (ccErrBadParam); } if (!err) { io_ccache->creds_version = in_creds_version; if (io_ccache->creds_version == cc_credentials_v4) { v4_principal = strdup (in_principal); if (!v4_principal) { err = cci_check_error (ccErrNoMem); } } else if (io_ccache->creds_version == cc_credentials_v5) { v5_principal = strdup (in_principal); if (!v5_principal) { err = cci_check_error (ccErrNoMem); } } else { err = cci_check_error (ccErrBadCredentialsVersion); } } if (!err) { err = ccs_credentials_list_new (&credentials); } if (!err) { io_ccache->kdc_time_offset_v4 = 0; io_ccache->kdc_time_offset_v4_valid = 0; io_ccache->kdc_time_offset_v5 = 0; io_ccache->kdc_time_offset_v5_valid = 0; if (io_ccache->v4_principal) { free (io_ccache->v4_principal); } io_ccache->v4_principal = v4_principal; v4_principal = NULL; /* take ownership */ if (io_ccache->v5_principal) { free (io_ccache->v5_principal); } io_ccache->v5_principal = v5_principal; v5_principal = NULL; /* take ownership */ ccs_credentials_list_release (io_ccache->credentials); io_ccache->credentials = credentials; credentials = NULL; /* take ownership */ err = ccs_ccache_changed (io_ccache, io_cache_collection); } free (v4_principal); free (v5_principal); ccs_credentials_list_release (credentials); return cci_check_error (err); } /* ------------------------------------------------------------------------ */ cc_int32 ccs_ccache_swap_contents (ccs_ccache_t io_source_ccache, ccs_ccache_t io_destination_ccache, ccs_cache_collection_t io_cache_collection) { cc_int32 err = ccNoError; if (!io_source_ccache ) { err = cci_check_error (ccErrBadParam); } if (!io_destination_ccache) { err = cci_check_error (ccErrBadParam); } if (!err) { struct ccs_ccache_d temp_ccache = *io_destination_ccache; /* swap everything */ *io_destination_ccache = *io_source_ccache; *io_source_ccache = temp_ccache; /* swap back the name and identifier */ io_source_ccache->identifier = io_destination_ccache->identifier; io_destination_ccache->identifier = temp_ccache.identifier; io_source_ccache->name = io_destination_ccache->name; io_destination_ccache->name = temp_ccache.name; } if (!err) { err = ccs_ccache_changed (io_source_ccache, io_cache_collection); } if (!err) { err = ccs_ccache_changed (io_destination_ccache, io_cache_collection); } return cci_check_error (err); } /* ------------------------------------------------------------------------ */ cc_int32 ccs_ccache_release (ccs_ccache_t io_ccache) { cc_int32 err = ccNoError; if (!err && io_ccache) { cci_identifier_release (io_ccache->identifier); ccs_lock_state_release (io_ccache->lock_state); free (io_ccache->name); free (io_ccache->v4_principal); free (io_ccache->v5_principal); ccs_credentials_list_release (io_ccache->credentials); ccs_callback_array_release (io_ccache->change_callbacks); free (io_ccache); } return cci_check_error (err); } #ifdef TARGET_OS_MAC #pragma mark - #endif /* ------------------------------------------------------------------------ */ cc_int32 ccs_ccache_compare_identifier (ccs_ccache_t in_ccache, cci_identifier_t in_identifier, cc_uint32 *out_equal) { cc_int32 err = ccNoError; if (!in_ccache ) { err = cci_check_error (ccErrBadParam); } if (!in_identifier) { err = cci_check_error (ccErrBadParam); } if (!out_equal ) { err = cci_check_error (ccErrBadParam); } if (!err) { err = cci_identifier_compare (in_ccache->identifier, in_identifier, out_equal); } return cci_check_error (err); } /* ------------------------------------------------------------------------ */ cc_int32 ccs_ccache_compare_name (ccs_ccache_t in_ccache, const char *in_name, cc_uint32 *out_equal) { cc_int32 err = ccNoError; if (!in_ccache) { err = cci_check_error (ccErrBadParam); } if (!in_name ) { err = cci_check_error (ccErrBadParam); } if (!out_equal) { err = cci_check_error (ccErrBadParam); } if (!err) { *out_equal = (strcmp (in_ccache->name, in_name) == 0); } return cci_check_error (err); } #ifdef TARGET_OS_MAC #pragma mark - #endif /* ------------------------------------------------------------------------ */ cc_int32 ccs_ccache_changed (ccs_ccache_t io_ccache, ccs_cache_collection_t io_cache_collection) { cc_int32 err = ccNoError; k5_ipc_stream reply_data = NULL; if (!io_ccache ) { err = cci_check_error (ccErrBadParam); } if (!io_cache_collection) { err = cci_check_error (ccErrBadParam); } if (!err) { cc_time_t now = time (NULL); if (io_ccache->last_changed_time < now) { io_ccache->last_changed_time = now; } else { io_ccache->last_changed_time++; } } if (!err) { err = ccs_cache_collection_changed (io_cache_collection); } if (!err) { err = krb5int_ipc_stream_new (&reply_data); } if (!err) { err = krb5int_ipc_stream_write_time (reply_data, io_ccache->last_changed_time); } if (!err) { /* Loop over callbacks sending messages to them */ cc_uint64 i; cc_uint64 count = ccs_callback_array_count (io_ccache->change_callbacks); for (i = 0; !err && i < count; i++) { ccs_callback_t callback = ccs_callback_array_object_at_index (io_ccache->change_callbacks, i); err = ccs_callback_reply_to_client (callback, reply_data); if (!err) { cci_debug_printf ("%s: Removing callback reference %p.", __FUNCTION__, callback); err = ccs_callback_array_remove (io_ccache->change_callbacks, i); break; } } } if (!err) { err = ccs_os_notify_ccache_changed (io_cache_collection, io_ccache->name); } krb5int_ipc_stream_release (reply_data); return cci_check_error (err); } /* ------------------------------------------------------------------------ */ static cc_int32 ccs_ccache_invalidate_change_callback (ccs_callback_owner_t io_ccache, ccs_callback_t in_callback) { cc_int32 err = ccNoError; if (!io_ccache ) { err = cci_check_error (ccErrBadParam); } if (!in_callback) { err = cci_check_error (ccErrBadParam); } if (!err) { /* Remove callback */ ccs_ccache_t ccache = (ccs_ccache_t) io_ccache; cc_uint64 i; cc_uint64 count = ccs_callback_array_count (ccache->change_callbacks); for (i = 0; !err && i < count; i++) { ccs_callback_t callback = ccs_callback_array_object_at_index (ccache->change_callbacks, i); if (callback == in_callback) { cci_debug_printf ("%s: Removing callback reference %p.", __FUNCTION__, callback); err = ccs_callback_array_remove (ccache->change_callbacks, i); break; } } } return cci_check_error (err); } /* ------------------------------------------------------------------------ */ cc_int32 ccs_ccache_notify_default_state_changed (ccs_ccache_t io_ccache, ccs_cache_collection_t io_cache_collection, cc_uint32 in_new_default_state) { cc_int32 err = ccNoError; if (!io_ccache ) { err = cci_check_error (ccErrBadParam); } if (!io_cache_collection) { err = cci_check_error (ccErrBadParam); } if (!err && in_new_default_state) { cc_time_t now = time (NULL); if (io_ccache->last_default_time < now) { io_ccache->last_default_time = now; } else { io_ccache->last_default_time++; } } if (!err) { err = ccs_ccache_changed (io_ccache, io_cache_collection); } return cci_check_error (err); } #ifdef TARGET_OS_MAC #pragma mark - #endif /* ------------------------------------------------------------------------ */ cc_int32 ccs_ccache_find_credentials_iterator (ccs_ccache_t in_ccache, cci_identifier_t in_identifier, ccs_credentials_iterator_t *out_credentials_iterator) { cc_int32 err = ccNoError; if (!in_ccache ) { err = cci_check_error (ccErrBadParam); } if (!in_identifier ) { err = cci_check_error (ccErrBadParam); } if (!out_credentials_iterator) { err = cci_check_error (ccErrBadParam); } if (!err) { err = ccs_credentials_list_find_iterator (in_ccache->credentials, in_identifier, out_credentials_iterator); } // Don't report ccErrInvalidCredentials to the log file. Non-fatal. return (err == ccErrInvalidCredentials) ? err : cci_check_error (err); } #ifdef TARGET_OS_MAC #pragma mark - #endif /* ------------------------------------------------------------------------ */ cc_int32 ccs_ccache_write (ccs_ccache_t in_ccache, k5_ipc_stream io_stream) { cc_int32 err = ccNoError; if (!in_ccache) { err = cci_check_error (ccErrBadParam); } if (!io_stream) { err = cci_check_error (ccErrBadParam); } if (!err) { err = cci_identifier_write (in_ccache->identifier, io_stream); } return cci_check_error (err); } /* ------------------------------------------------------------------------ */ cc_int32 ccs_ccache_write_name (ccs_ccache_t in_ccache, k5_ipc_stream io_stream) { cc_int32 err = ccNoError; if (!in_ccache) { err = cci_check_error (ccErrBadParam); } if (!io_stream) { err = cci_check_error (ccErrBadParam); } if (!err) { err = krb5int_ipc_stream_write_string (io_stream, in_ccache->name); } return cci_check_error (err); } #ifdef TARGET_OS_MAC #pragma mark - #pragma mark -- IPC Messages -- #endif /* ------------------------------------------------------------------------ */ static cc_int32 ccs_ccache_destroy (ccs_ccache_t io_ccache, ccs_cache_collection_t io_cache_collection, k5_ipc_stream in_request_data, k5_ipc_stream io_reply_data) { cc_int32 err = ccNoError; if (!io_ccache ) { err = cci_check_error (ccErrBadParam); } if (!io_cache_collection) { err = cci_check_error (ccErrBadParam); } if (!in_request_data ) { err = cci_check_error (ccErrBadParam); } if (!io_reply_data ) { err = cci_check_error (ccErrBadParam); } if (!err) { err = ccs_cache_collection_destroy_ccache (io_cache_collection, io_ccache->identifier); } if (!err) { /* ccache has been destroyed so just mark the cache collection */ err = ccs_cache_collection_changed (io_cache_collection); } return cci_check_error (err); } /* ------------------------------------------------------------------------ */ static cc_int32 ccs_ccache_set_default (ccs_ccache_t io_ccache, ccs_cache_collection_t io_cache_collection, k5_ipc_stream in_request_data, k5_ipc_stream io_reply_data) { cc_int32 err = ccNoError; if (!io_ccache ) { err = cci_check_error (ccErrBadParam); } if (!io_cache_collection) { err = cci_check_error (ccErrBadParam); } if (!in_request_data ) { err = cci_check_error (ccErrBadParam); } if (!io_reply_data ) { err = cci_check_error (ccErrBadParam); } if (!err) { err = ccs_cache_collection_set_default_ccache (io_cache_collection, io_ccache->identifier); } return cci_check_error (err); } /* ------------------------------------------------------------------------ */ static cc_int32 ccs_ccache_get_credentials_version (ccs_ccache_t io_ccache, ccs_cache_collection_t io_cache_collection, k5_ipc_stream in_request_data, k5_ipc_stream io_reply_data) { cc_int32 err = ccNoError; if (!io_ccache ) { err = cci_check_error (ccErrBadParam); } if (!io_cache_collection) { err = cci_check_error (ccErrBadParam); } if (!in_request_data ) { err = cci_check_error (ccErrBadParam); } if (!io_reply_data ) { err = cci_check_error (ccErrBadParam); } if (!err) { err = krb5int_ipc_stream_write_uint32 (io_reply_data, io_ccache->creds_version); } return cci_check_error (err); } /* ------------------------------------------------------------------------ */ static cc_int32 ccs_ccache_get_name (ccs_ccache_t io_ccache, ccs_cache_collection_t io_cache_collection, k5_ipc_stream in_request_data, k5_ipc_stream io_reply_data) { cc_int32 err = ccNoError; if (!io_ccache ) { err = cci_check_error (ccErrBadParam); } if (!io_cache_collection) { err = cci_check_error (ccErrBadParam); } if (!in_request_data ) { err = cci_check_error (ccErrBadParam); } if (!io_reply_data ) { err = cci_check_error (ccErrBadParam); } if (!err) { err = krb5int_ipc_stream_write_string (io_reply_data, io_ccache->name); } return cci_check_error (err); } /* ------------------------------------------------------------------------ */ static cc_int32 ccs_ccache_get_principal (ccs_ccache_t io_ccache, ccs_cache_collection_t io_cache_collection, k5_ipc_stream in_request_data, k5_ipc_stream io_reply_data) { cc_int32 err = ccNoError; cc_uint32 version = 0; if (!io_ccache ) { err = cci_check_error (ccErrBadParam); } if (!io_cache_collection) { err = cci_check_error (ccErrBadParam); } if (!in_request_data ) { err = cci_check_error (ccErrBadParam); } if (!io_reply_data ) { err = cci_check_error (ccErrBadParam); } if (!err) { err = krb5int_ipc_stream_read_uint32 (in_request_data, &version); } if (!err && version == cc_credentials_v4_v5) { err = cci_check_error (ccErrBadCredentialsVersion); } if (!err) { if (version == cc_credentials_v4) { err = krb5int_ipc_stream_write_string (io_reply_data, io_ccache->v4_principal); } else if (version == cc_credentials_v5) { err = krb5int_ipc_stream_write_string (io_reply_data, io_ccache->v5_principal); } else { err = cci_check_error (ccErrBadCredentialsVersion); } } return cci_check_error (err); } /* ------------------------------------------------------------------------ */ static cc_int32 ccs_ccache_set_principal (ccs_ccache_t io_ccache, ccs_cache_collection_t io_cache_collection, k5_ipc_stream in_request_data, k5_ipc_stream io_reply_data) { cc_int32 err = ccNoError; cc_uint32 version = 0; char *principal = NULL; if (!io_ccache ) { err = cci_check_error (ccErrBadParam); } if (!io_cache_collection) { err = cci_check_error (ccErrBadParam); } if (!in_request_data ) { err = cci_check_error (ccErrBadParam); } if (!io_reply_data ) { err = cci_check_error (ccErrBadParam); } if (!err) { err = krb5int_ipc_stream_read_uint32 (in_request_data, &version); } if (!err) { err = krb5int_ipc_stream_read_string (in_request_data, &principal); } if (!err) { /* reset KDC time offsets because they are per-KDC */ if (version == cc_credentials_v4) { io_ccache->kdc_time_offset_v4 = 0; io_ccache->kdc_time_offset_v4_valid = 0; if (io_ccache->v4_principal) { free (io_ccache->v4_principal); } io_ccache->v4_principal = principal; principal = NULL; /* take ownership */ } else if (version == cc_credentials_v5) { io_ccache->kdc_time_offset_v5 = 0; io_ccache->kdc_time_offset_v5_valid = 0; if (io_ccache->v5_principal) { free (io_ccache->v5_principal); } io_ccache->v5_principal = principal; principal = NULL; /* take ownership */ } else { err = cci_check_error (ccErrBadCredentialsVersion); } } if (!err) { io_ccache->creds_version |= version; err = ccs_ccache_changed (io_ccache, io_cache_collection); } krb5int_ipc_stream_free_string (principal); return cci_check_error (err); } /* ------------------------------------------------------------------------ */ static cc_int32 ccs_ccache_store_credentials (ccs_ccache_t io_ccache, ccs_cache_collection_t io_cache_collection, k5_ipc_stream in_request_data, k5_ipc_stream io_reply_data) { cc_int32 err = ccNoError; ccs_credentials_t credentials = NULL; if (!io_ccache ) { err = cci_check_error (ccErrBadParam); } if (!io_cache_collection) { err = cci_check_error (ccErrBadParam); } if (!in_request_data ) { err = cci_check_error (ccErrBadParam); } if (!io_reply_data ) { err = cci_check_error (ccErrBadParam); } if (!err) { err = ccs_credentials_new (&credentials, in_request_data, io_ccache->creds_version, io_ccache->credentials); } if (!err) { err = ccs_ccache_changed (io_ccache, io_cache_collection); } return cci_check_error (err); } /* ------------------------------------------------------------------------ */ static cc_int32 ccs_ccache_remove_credentials (ccs_ccache_t io_ccache, ccs_cache_collection_t io_cache_collection, k5_ipc_stream in_request_data, k5_ipc_stream io_reply_data) { cc_int32 err = ccNoError; cci_identifier_t credentials_identifier = NULL; if (!io_ccache ) { err = cci_check_error (ccErrBadParam); } if (!io_cache_collection) { err = cci_check_error (ccErrBadParam); } if (!in_request_data ) { err = cci_check_error (ccErrBadParam); } if (!io_reply_data ) { err = cci_check_error (ccErrBadParam); } if (!err) { err = cci_identifier_read (&credentials_identifier, in_request_data); } if (!err) { err = ccs_credentials_list_remove (io_ccache->credentials, credentials_identifier); } if (!err) { err = ccs_ccache_changed (io_ccache, io_cache_collection); } cci_identifier_release (credentials_identifier); return cci_check_error (err); } /* ------------------------------------------------------------------------ */ static cc_int32 ccs_ccache_new_credentials_iterator (ccs_ccache_t io_ccache, ccs_cache_collection_t io_cache_collection, ccs_pipe_t in_client_pipe, k5_ipc_stream in_request_data, k5_ipc_stream io_reply_data) { cc_int32 err = ccNoError; ccs_credentials_iterator_t credentials_iterator = NULL; if (!io_ccache ) { err = cci_check_error (ccErrBadParam); } if (!io_cache_collection) { err = cci_check_error (ccErrBadParam); } if (!in_request_data ) { err = cci_check_error (ccErrBadParam); } if (!io_reply_data ) { err = cci_check_error (ccErrBadParam); } if (!err) { err = ccs_credentials_list_new_iterator (io_ccache->credentials, in_client_pipe, &credentials_iterator); } if (!err) { err = ccs_credentials_list_iterator_write (credentials_iterator, io_reply_data); } return cci_check_error (err); } /* ------------------------------------------------------------------------ */ static cc_int32 ccs_ccache_move (ccs_ccache_t io_ccache, ccs_cache_collection_t io_cache_collection, k5_ipc_stream in_request_data, k5_ipc_stream io_reply_data) { cc_int32 err = ccNoError; cci_identifier_t source_identifier = NULL; if (!io_ccache ) { err = cci_check_error (ccErrBadParam); } if (!io_cache_collection) { err = cci_check_error (ccErrBadParam); } if (!in_request_data ) { err = cci_check_error (ccErrBadParam); } if (!io_reply_data ) { err = cci_check_error (ccErrBadParam); } if (!err) { /* Note: message is sent as the destination ccache to avoid */ /* extra work on the server when deleting it the source ccache. */ err = cci_identifier_read (&source_identifier, in_request_data); } if (!err) { err = ccs_ccache_collection_move_ccache (io_cache_collection, source_identifier, io_ccache); } if (!err) { err = ccs_ccache_changed (io_ccache, io_cache_collection); } cci_identifier_release (source_identifier); return cci_check_error (err); } /* ------------------------------------------------------------------------ */ static cc_int32 ccs_ccache_lock (ccs_pipe_t in_client_pipe, ccs_pipe_t in_reply_pipe, ccs_ccache_t io_ccache, ccs_cache_collection_t io_cache_collection, k5_ipc_stream in_request_data, cc_uint32 *out_will_block, k5_ipc_stream io_reply_data) { cc_int32 err = ccNoError; cc_uint32 lock_type; cc_uint32 block; if (!ccs_pipe_valid (in_client_pipe)) { err = cci_check_error (ccErrBadParam); } if (!io_ccache ) { err = cci_check_error (ccErrBadParam); } if (!io_cache_collection ) { err = cci_check_error (ccErrBadParam); } if (!in_request_data ) { err = cci_check_error (ccErrBadParam); } if (!out_will_block ) { err = cci_check_error (ccErrBadParam); } if (!io_reply_data ) { err = cci_check_error (ccErrBadParam); } if (!err) { err = krb5int_ipc_stream_read_uint32 (in_request_data, &lock_type); } if (!err) { err = krb5int_ipc_stream_read_uint32 (in_request_data, &block); } if (!err) { err = ccs_lock_state_add (io_ccache->lock_state, in_client_pipe, in_reply_pipe, lock_type, block, out_will_block); } return cci_check_error (err); } /* ------------------------------------------------------------------------ */ static cc_int32 ccs_ccache_unlock (ccs_pipe_t in_client_pipe, ccs_ccache_t io_ccache, ccs_cache_collection_t io_cache_collection, k5_ipc_stream in_request_data, k5_ipc_stream io_reply_data) { cc_int32 err = ccNoError; if (!ccs_pipe_valid (in_client_pipe)) { err = cci_check_error (ccErrBadParam); } if (!io_ccache ) { err = cci_check_error (ccErrBadParam); } if (!io_cache_collection ) { err = cci_check_error (ccErrBadParam); } if (!in_request_data ) { err = cci_check_error (ccErrBadParam); } if (!io_reply_data ) { err = cci_check_error (ccErrBadParam); } if (!err) { err = ccs_lock_state_remove (io_ccache->lock_state, in_client_pipe); } return cci_check_error (err); } /* ------------------------------------------------------------------------ */ static cc_int32 ccs_ccache_get_last_default_time (ccs_ccache_t io_ccache, ccs_cache_collection_t io_cache_collection, k5_ipc_stream in_request_data, k5_ipc_stream io_reply_data) { cc_int32 err = ccNoError; if (!io_ccache ) { err = cci_check_error (ccErrBadParam); } if (!io_cache_collection) { err = cci_check_error (ccErrBadParam); } if (!in_request_data ) { err = cci_check_error (ccErrBadParam); } if (!io_reply_data ) { err = cci_check_error (ccErrBadParam); } if (!err && io_ccache->last_default_time == 0) { err = cci_check_error (ccErrNeverDefault); } if (!err) { err = krb5int_ipc_stream_write_time (io_reply_data, io_ccache->last_default_time); } return cci_check_error (err); } /* ------------------------------------------------------------------------ */ static cc_int32 ccs_ccache_get_change_time (ccs_ccache_t io_ccache, ccs_cache_collection_t io_cache_collection, k5_ipc_stream in_request_data, k5_ipc_stream io_reply_data) { cc_int32 err = ccNoError; if (!io_ccache ) { err = cci_check_error (ccErrBadParam); } if (!io_cache_collection) { err = cci_check_error (ccErrBadParam); } if (!in_request_data ) { err = cci_check_error (ccErrBadParam); } if (!io_reply_data ) { err = cci_check_error (ccErrBadParam); } if (!err) { err = krb5int_ipc_stream_write_time (io_reply_data, io_ccache->last_changed_time); } return cci_check_error (err); } /* ------------------------------------------------------------------------ */ static cc_int32 ccs_ccache_wait_for_change (ccs_pipe_t in_client_pipe, ccs_pipe_t in_reply_pipe, ccs_ccache_t io_ccache, ccs_cache_collection_t io_cache_collection, k5_ipc_stream in_request_data, k5_ipc_stream io_reply_data, cc_uint32 *out_will_block) { cc_int32 err = ccNoError; cc_time_t last_wait_for_change_time = 0; cc_uint32 will_block = 0; if (!ccs_pipe_valid (in_client_pipe)) { err = cci_check_error (ccErrBadParam); } if (!ccs_pipe_valid (in_reply_pipe )) { err = cci_check_error (ccErrBadParam); } if (!io_ccache ) { err = cci_check_error (ccErrBadParam); } if (!io_cache_collection ) { err = cci_check_error (ccErrBadParam); } if (!in_request_data ) { err = cci_check_error (ccErrBadParam); } if (!out_will_block ) { err = cci_check_error (ccErrBadParam); } if (!err) { err = krb5int_ipc_stream_read_time (in_request_data, &last_wait_for_change_time); } if (!err) { if (last_wait_for_change_time < io_ccache->last_changed_time) { cci_debug_printf ("%s returning immediately", __FUNCTION__); err = krb5int_ipc_stream_write_time (io_reply_data, io_ccache->last_changed_time); } else { ccs_callback_t callback = NULL; err = ccs_callback_new (&callback, ccErrInvalidCCache, in_client_pipe, in_reply_pipe, (ccs_callback_owner_t) io_ccache, ccs_ccache_invalidate_change_callback); if (!err) { err = ccs_callback_array_insert (io_ccache->change_callbacks, callback, ccs_callback_array_count (io_ccache->change_callbacks)); if (!err) { callback = NULL; /* take ownership */ } cci_debug_printf ("%s blocking", __FUNCTION__); will_block = 1; } ccs_callback_release (callback); } } if (!err) { *out_will_block = will_block; } return cci_check_error (err); } /* ------------------------------------------------------------------------ */ static cc_int32 ccs_ccache_get_kdc_time_offset (ccs_ccache_t io_ccache, ccs_cache_collection_t io_cache_collection, k5_ipc_stream in_request_data, k5_ipc_stream io_reply_data) { cc_int32 err = ccNoError; cc_uint32 cred_vers = 0; if (!io_ccache ) { err = cci_check_error (ccErrBadParam); } if (!io_cache_collection) { err = cci_check_error (ccErrBadParam); } if (!in_request_data ) { err = cci_check_error (ccErrBadParam); } if (!io_reply_data ) { err = cci_check_error (ccErrBadParam); } if (!err) { err = krb5int_ipc_stream_read_uint32 (in_request_data, &cred_vers); } if (!err) { if (cred_vers == cc_credentials_v4) { if (io_ccache->kdc_time_offset_v4_valid) { err = krb5int_ipc_stream_write_time (io_reply_data, io_ccache->kdc_time_offset_v4); } else { err = cci_check_error (ccErrTimeOffsetNotSet); } } else if (cred_vers == cc_credentials_v5) { if (io_ccache->kdc_time_offset_v5_valid) { err = krb5int_ipc_stream_write_time (io_reply_data, io_ccache->kdc_time_offset_v5); } else { err = cci_check_error (ccErrTimeOffsetNotSet); } } else { err = cci_check_error (ccErrBadCredentialsVersion); } } return cci_check_error (err); } /* ------------------------------------------------------------------------ */ static cc_int32 ccs_ccache_set_kdc_time_offset (ccs_ccache_t io_ccache, ccs_cache_collection_t io_cache_collection, k5_ipc_stream in_request_data, k5_ipc_stream io_reply_data) { cc_int32 err = ccNoError; cc_uint32 cred_vers = 0; if (!io_ccache ) { err = cci_check_error (ccErrBadParam); } if (!io_cache_collection) { err = cci_check_error (ccErrBadParam); } if (!in_request_data ) { err = cci_check_error (ccErrBadParam); } if (!io_reply_data ) { err = cci_check_error (ccErrBadParam); } if (!err) { err = krb5int_ipc_stream_read_uint32 (in_request_data, &cred_vers); } if (!err) { if (cred_vers == cc_credentials_v4) { err = krb5int_ipc_stream_read_time (in_request_data, &io_ccache->kdc_time_offset_v4); if (!err) { io_ccache->kdc_time_offset_v4_valid = 1; } } else if (cred_vers == cc_credentials_v5) { err = krb5int_ipc_stream_read_time (in_request_data, &io_ccache->kdc_time_offset_v5); if (!err) { io_ccache->kdc_time_offset_v5_valid = 1; } } else { err = cci_check_error (ccErrBadCredentialsVersion); } } if (!err) { err = ccs_ccache_changed (io_ccache, io_cache_collection); } return cci_check_error (err); } /* ------------------------------------------------------------------------ */ static cc_int32 ccs_ccache_clear_kdc_time_offset (ccs_ccache_t io_ccache, ccs_cache_collection_t io_cache_collection, k5_ipc_stream in_request_data, k5_ipc_stream io_reply_data) { cc_int32 err = ccNoError; cc_uint32 cred_vers = 0; if (!io_ccache ) { err = cci_check_error (ccErrBadParam); } if (!io_cache_collection) { err = cci_check_error (ccErrBadParam); } if (!in_request_data ) { err = cci_check_error (ccErrBadParam); } if (!io_reply_data ) { err = cci_check_error (ccErrBadParam); } if (!err) { err = krb5int_ipc_stream_read_uint32 (in_request_data, &cred_vers); } if (!err) { if (cred_vers == cc_credentials_v4) { io_ccache->kdc_time_offset_v4 = 0; io_ccache->kdc_time_offset_v4_valid = 0; } else if (cred_vers == cc_credentials_v5) { io_ccache->kdc_time_offset_v5 = 0; io_ccache->kdc_time_offset_v5_valid = 0; } else { err = cci_check_error (ccErrBadCredentialsVersion); } } if (!err) { err = ccs_ccache_changed (io_ccache, io_cache_collection); } return cci_check_error (err); } #ifdef TARGET_OS_MAC #pragma mark - #endif /* ------------------------------------------------------------------------ */ cc_int32 ccs_ccache_handle_message (ccs_pipe_t in_client_pipe, ccs_pipe_t in_reply_pipe, ccs_ccache_t io_ccache, ccs_cache_collection_t io_cache_collection, enum cci_msg_id_t in_request_name, k5_ipc_stream in_request_data, cc_uint32 *out_will_block, k5_ipc_stream *out_reply_data) { cc_int32 err = ccNoError; cc_uint32 will_block = 0; k5_ipc_stream reply_data = NULL; if (!ccs_pipe_valid (in_client_pipe)) { err = cci_check_error (ccErrBadParam); } if (!ccs_pipe_valid (in_reply_pipe) ) { err = cci_check_error (ccErrBadParam); } if (!io_cache_collection ) { err = cci_check_error (ccErrBadParam); } if (!in_request_data ) { err = cci_check_error (ccErrBadParam); } if (!out_will_block ) { err = cci_check_error (ccErrBadParam); } if (!out_reply_data ) { err = cci_check_error (ccErrBadParam); } if (!err) { err = krb5int_ipc_stream_new (&reply_data); } if (!err) { if (in_request_name == cci_ccache_destroy_msg_id) { err = ccs_ccache_destroy (io_ccache, io_cache_collection, in_request_data, reply_data); } else if (in_request_name == cci_ccache_set_default_msg_id) { err = ccs_ccache_set_default (io_ccache, io_cache_collection, in_request_data, reply_data); } else if (in_request_name == cci_ccache_get_credentials_version_msg_id) { err = ccs_ccache_get_credentials_version (io_ccache, io_cache_collection, in_request_data, reply_data); } else if (in_request_name == cci_ccache_get_name_msg_id) { err = ccs_ccache_get_name (io_ccache, io_cache_collection, in_request_data, reply_data); } else if (in_request_name == cci_ccache_get_principal_msg_id) { err = ccs_ccache_get_principal (io_ccache, io_cache_collection, in_request_data, reply_data); } else if (in_request_name == cci_ccache_set_principal_msg_id) { err = ccs_ccache_set_principal (io_ccache, io_cache_collection, in_request_data, reply_data); } else if (in_request_name == cci_ccache_store_credentials_msg_id) { err = ccs_ccache_store_credentials (io_ccache, io_cache_collection, in_request_data, reply_data); } else if (in_request_name == cci_ccache_remove_credentials_msg_id) { err = ccs_ccache_remove_credentials (io_ccache, io_cache_collection, in_request_data, reply_data); } else if (in_request_name == cci_ccache_new_credentials_iterator_msg_id) { err = ccs_ccache_new_credentials_iterator (io_ccache, io_cache_collection, in_client_pipe, in_request_data, reply_data); } else if (in_request_name == cci_ccache_move_msg_id) { err = ccs_ccache_move (io_ccache, io_cache_collection, in_request_data, reply_data); } else if (in_request_name == cci_ccache_lock_msg_id) { err = ccs_ccache_lock (in_client_pipe, in_reply_pipe, io_ccache, io_cache_collection, in_request_data, &will_block, reply_data); } else if (in_request_name == cci_ccache_unlock_msg_id) { err = ccs_ccache_unlock (in_client_pipe, io_ccache, io_cache_collection, in_request_data, reply_data); } else if (in_request_name == cci_ccache_get_last_default_time_msg_id) { err = ccs_ccache_get_last_default_time (io_ccache, io_cache_collection, in_request_data, reply_data); } else if (in_request_name == cci_ccache_get_change_time_msg_id) { err = ccs_ccache_get_change_time (io_ccache, io_cache_collection, in_request_data, reply_data); } else if (in_request_name == cci_ccache_wait_for_change_msg_id) { err = ccs_ccache_wait_for_change (in_client_pipe, in_reply_pipe, io_ccache, io_cache_collection, in_request_data, reply_data, &will_block); } else if (in_request_name == cci_ccache_get_kdc_time_offset_msg_id) { err = ccs_ccache_get_kdc_time_offset (io_ccache, io_cache_collection, in_request_data, reply_data); } else if (in_request_name == cci_ccache_set_kdc_time_offset_msg_id) { err = ccs_ccache_set_kdc_time_offset (io_ccache, io_cache_collection, in_request_data, reply_data); } else if (in_request_name == cci_ccache_clear_kdc_time_offset_msg_id) { err = ccs_ccache_clear_kdc_time_offset (io_ccache, io_cache_collection, in_request_data, reply_data); } else { err = ccErrBadInternalMessage; } } if (!err) { *out_will_block = will_block; if (!will_block) { *out_reply_data = reply_data; reply_data = NULL; /* take ownership */ } else { *out_reply_data = NULL; } } krb5int_ipc_stream_release (reply_data); return cci_check_error (err); } krb5-1.16/src/ccapi/server/Makefile.in0000644000704600001450000000231713211554426017422 0ustar ghudsonlibuuidmydir=ccapi$(S)server BUILDTOP=$(REL)..$(S).. SUBDIRS=unix LOCALINCLUDES= -I$(srcdir)/../common STLIBOBJS= \ ccs_array.o \ ccs_cache_collection.o \ ccs_callback.o \ ccs_ccache.o \ ccs_ccache_iterator.o \ ccs_client.o \ ccs_credentials.o \ ccs_credentials_iterator.o \ ccs_list.o \ ccs_list_internal.o \ ccs_lock.o \ ccs_lock_state.o \ ccs_pipe.o \ ccs_server.o OBJS= \ $(OUTPRE)ccs_array.$(OBJEXT) \ $(OUTPRE)ccs_cache_collection.$(OBJEXT) \ $(OUTPRE)ccs_callback.$(OBJEXT) \ $(OUTPRE)ccs_ccache.$(OBJEXT) \ $(OUTPRE)ccs_ccache_iterator.$(OBJEXT) \ $(OUTPRE)ccs_client.$(OBJEXT) \ $(OUTPRE)ccs_credentials.$(OBJEXT) \ $(OUTPRE)ccs_credentials_iterator.$(OBJEXT) \ $(OUTPRE)ccs_list.$(OBJEXT) \ $(OUTPRE)ccs_list_internal.$(OBJEXT) \ $(OUTPRE)ccs_lock.$(OBJEXT) \ $(OUTPRE)ccs_lock_state.$(OBJEXT) \ $(OUTPRE)ccs_pipe.$(OBJEXT) \ $(OUTPRE)ccs_server.$(OBJEXT) SRCS= \ ccs_array.c \ ccs_cache_collection.c \ ccs_callback.c \ ccs_ccache.c \ ccs_ccache_iterator.c \ ccs_client.c \ ccs_credentials.c \ ccs_credentials_iterator.c \ ccs_list.c \ ccs_list_internal.c \ ccs_lock.c \ ccs_lock_state.c \ ccs_pipe.c \ ccs_server.c all-unix: all-libobjs clean-unix:: clean-libobjs @libobj_frag@ krb5-1.16/src/ccapi/server/ccs_pipe.h0000644000704600001450000000316113211554426017311 0ustar ghudsonlibuuid/* ccapi/server/ccs_pipe.h */ /* * Copyright 2006 Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #ifndef CCS_PIPE_H #define CCS_PIPE_H #include "ccs_types.h" cc_int32 ccs_pipe_valid (ccs_pipe_t in_pipe); cc_int32 ccs_pipe_compare (ccs_pipe_t in_pipe, ccs_pipe_t in_compare_to_pipe, cc_uint32 *out_equal); cc_int32 ccs_pipe_copy (ccs_pipe_t *out_pipe, ccs_pipe_t in_pipe); cc_int32 ccs_pipe_release (ccs_pipe_t io_pipe); #endif /* CCS_PIPE_H */ krb5-1.16/src/ccapi/server/unix/0000755000704600001450000000000013211554426016335 5ustar ghudsonlibuuidkrb5-1.16/src/ccapi/server/unix/deps0000644000704600001450000000003013211554426017204 0ustar ghudsonlibuuid# No dependencies here. krb5-1.16/src/ccapi/server/unix/Makefile.in0000644000704600001450000000022613211554426020402 0ustar ghudsonlibuuidmydir=ccapi$(S)server$(S)unix BUILDTOP=$(REL)..$(S)..$(S).. STLIBOBJS= OBJS= SRCS= all-unix: all-libobjs clean-unix:: clean-libobjs @libobj_frag@ krb5-1.16/src/ccapi/server/ccs_ccache_iterator.h0000644000704600001450000000341613211554426021476 0ustar ghudsonlibuuid/* ccapi/server/ccs_ccache_iterator.h */ /* * Copyright 2006 Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #ifndef CCS_CCACHE_ITERATOR_H #define CCS_CCACHE_ITERATOR_H #include "ccs_types.h" cc_int32 ccs_ccache_iterator_handle_message (ccs_ccache_iterator_t io_ccache_iterator, ccs_cache_collection_t io_cache_collection, enum cci_msg_id_t in_request_name, k5_ipc_stream in_request_data, k5_ipc_stream *out_reply_data); #endif /* CCS_CCACHE_ITERATOR_H */ krb5-1.16/src/ccapi/server/ccs_cache_collection.h0000644000704600001450000000777513211554426021651 0ustar ghudsonlibuuid/* ccapi/server/ccs_cache_collection.h */ /* * Copyright 2006 Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #ifndef CCS_CACHE_COLLECTION_H #define CCS_CACHE_COLLECTION_H #include "ccs_types.h" cc_int32 ccs_cache_collection_new (ccs_cache_collection_t *out_cache_collection); cc_int32 ccs_cache_collection_release (ccs_cache_collection_t io_cache_collection); cc_int32 ccs_cache_collection_compare_identifier (ccs_cache_collection_t in_cache_collection, cci_identifier_t in_identifier, cc_uint32 *out_equal); cc_int32 ccs_cache_collection_changed (ccs_cache_collection_t io_cache_collection); cc_int32 ccs_cache_collection_set_default_ccache (ccs_cache_collection_t in_cache_collection, cci_identifier_t in_identifier); cc_int32 ccs_cache_collection_find_ccache (ccs_cache_collection_t in_cache_collection, cci_identifier_t in_identifier, ccs_ccache_t *out_ccache); cc_int32 ccs_ccache_collection_move_ccache (ccs_cache_collection_t io_cache_collection, cci_identifier_t in_source_identifier, ccs_ccache_t io_destination_ccache); cc_int32 ccs_cache_collection_destroy_ccache (ccs_cache_collection_t in_cache_collection, cci_identifier_t in_identifier); cc_int32 ccs_cache_collection_find_ccache_iterator (ccs_cache_collection_t in_cache_collection, cci_identifier_t in_identifier, ccs_ccache_iterator_t *out_ccache_iterator); cc_int32 ccs_cache_collection_find_credentials_iterator (ccs_cache_collection_t in_cache_collection, cci_identifier_t in_identifier, ccs_ccache_t *out_ccache, ccs_credentials_iterator_t *out_credentials_iterator); cc_int32 ccs_cache_collection_handle_message (ccs_pipe_t in_client_pipe, ccs_pipe_t in_reply_pipe, ccs_cache_collection_t io_cache_collection, enum cci_msg_id_t in_request_name, k5_ipc_stream in_request_data, cc_uint32 *out_will_block, k5_ipc_stream *out_reply_data); #endif /* CCS_CACHE_COLLECTION_H */ krb5-1.16/src/ccapi/server/ccs_ccache_iterator.c0000644000704600001450000001432013211554426021465 0ustar ghudsonlibuuid/* ccapi/server/ccs_ccache_iterator.c */ /* * Copyright 2006, 2007 Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #include "ccs_common.h" /* ------------------------------------------------------------------------ */ static cc_int32 ccs_ccache_iterator_release (ccs_ccache_iterator_t io_ccache_iterator, ccs_cache_collection_t io_cache_collection, k5_ipc_stream in_request_data, k5_ipc_stream io_reply_data) { cc_int32 err = ccNoError; if (!io_ccache_iterator ) { err = cci_check_error (ccErrBadParam); } if (!io_cache_collection) { err = cci_check_error (ccErrBadParam); } if (!in_request_data ) { err = cci_check_error (ccErrBadParam); } if (!io_reply_data ) { err = cci_check_error (ccErrBadParam); } if (!err) { err = ccs_ccache_list_iterator_release (io_ccache_iterator); } return cci_check_error (err); } /* ------------------------------------------------------------------------ */ static cc_int32 ccs_ccache_iterator_next (ccs_ccache_iterator_t io_ccache_iterator, ccs_cache_collection_t io_cache_collection, k5_ipc_stream in_request_data, k5_ipc_stream io_reply_data) { cc_int32 err = ccNoError; ccs_ccache_t ccache = NULL; if (!io_ccache_iterator ) { err = cci_check_error (ccErrBadParam); } if (!io_cache_collection) { err = cci_check_error (ccErrBadParam); } if (!in_request_data ) { err = cci_check_error (ccErrBadParam); } if (!io_reply_data ) { err = cci_check_error (ccErrBadParam); } if (!err) { err = ccs_ccache_list_iterator_next (io_ccache_iterator, &ccache); } if (!err) { err = ccs_ccache_write (ccache, io_reply_data); } return cci_check_error (err); } /* ------------------------------------------------------------------------ */ static cc_int32 ccs_ccache_iterator_clone (ccs_ccache_iterator_t io_ccache_iterator, ccs_cache_collection_t io_cache_collection, k5_ipc_stream in_request_data, k5_ipc_stream io_reply_data) { cc_int32 err = ccNoError; ccs_ccache_iterator_t ccache_iterator = NULL; if (!io_ccache_iterator ) { err = cci_check_error (ccErrBadParam); } if (!io_cache_collection) { err = cci_check_error (ccErrBadParam); } if (!in_request_data ) { err = cci_check_error (ccErrBadParam); } if (!io_reply_data ) { err = cci_check_error (ccErrBadParam); } if (!err) { err = ccs_ccache_list_iterator_clone (io_ccache_iterator, &ccache_iterator); } if (!err) { err = ccs_ccache_list_iterator_write (ccache_iterator, io_reply_data); } return cci_check_error (err); } #ifdef TARGET_OS_MAC #pragma mark - #endif /* ------------------------------------------------------------------------ */ cc_int32 ccs_ccache_iterator_handle_message (ccs_ccache_iterator_t io_ccache_iterator, ccs_cache_collection_t io_cache_collection, enum cci_msg_id_t in_request_name, k5_ipc_stream in_request_data, k5_ipc_stream *out_reply_data) { cc_int32 err = ccNoError; k5_ipc_stream reply_data = NULL; if (!in_request_data) { err = cci_check_error (ccErrBadParam); } if (!out_reply_data ) { err = cci_check_error (ccErrBadParam); } if (!err) { err = krb5int_ipc_stream_new (&reply_data); } if (!err) { if (in_request_name == cci_ccache_iterator_release_msg_id) { err = ccs_ccache_iterator_release (io_ccache_iterator, io_cache_collection, in_request_data, reply_data); } else if (in_request_name == cci_ccache_iterator_next_msg_id) { err = ccs_ccache_iterator_next (io_ccache_iterator, io_cache_collection, in_request_data, reply_data); } else if (in_request_name == cci_ccache_iterator_clone_msg_id) { err = ccs_ccache_iterator_clone (io_ccache_iterator, io_cache_collection, in_request_data, reply_data); } else { err = ccErrBadInternalMessage; } } if (!err) { *out_reply_data = reply_data; reply_data = NULL; /* take ownership */ } krb5int_ipc_stream_release (reply_data); return cci_check_error (err); } krb5-1.16/src/ccapi/server/ccs_credentials.c0000644000704600001450000001123013211554426020640 0ustar ghudsonlibuuid/* ccapi/server/ccs_credentials.c */ /* * Copyright 2006 Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #include "ccs_common.h" struct ccs_credentials_d { cc_credentials_union *cred_union; cci_identifier_t identifier; }; struct ccs_credentials_d ccs_credentials_initializer = { NULL, NULL }; /* ------------------------------------------------------------------------ */ cc_int32 ccs_credentials_new (ccs_credentials_t *out_credentials, k5_ipc_stream in_stream, cc_uint32 in_ccache_version, ccs_credentials_list_t io_credentials_list) { cc_int32 err = ccNoError; ccs_credentials_t credentials = NULL; if (!out_credentials) { err = cci_check_error (ccErrBadParam); } if (!in_stream ) { err = cci_check_error (ccErrBadParam); } if (!err) { credentials = malloc (sizeof (*credentials)); if (credentials) { *credentials = ccs_credentials_initializer; } else { err = cci_check_error (ccErrNoMem); } } if (!err) { err = cci_credentials_union_read (&credentials->cred_union, in_stream); } if (!err && !(credentials->cred_union->version & in_ccache_version)) { /* ccache does not have a principal set for this credentials version */ err = cci_check_error (ccErrBadCredentialsVersion); } if (!err) { err = ccs_server_new_identifier (&credentials->identifier); } if (!err) { err = ccs_credentials_list_add (io_credentials_list, credentials); } if (!err) { *out_credentials = credentials; credentials = NULL; } ccs_credentials_release (credentials); return cci_check_error (err); } /* ------------------------------------------------------------------------ */ cc_int32 ccs_credentials_release (ccs_credentials_t io_credentials) { cc_int32 err = ccNoError; if (!err && io_credentials) { cci_credentials_union_release (io_credentials->cred_union); cci_identifier_release (io_credentials->identifier); free (io_credentials); } return cci_check_error (err); } /* ------------------------------------------------------------------------ */ cc_int32 ccs_credentials_write (ccs_credentials_t in_credentials, k5_ipc_stream io_stream) { cc_int32 err = ccNoError; if (!in_credentials) { err = cci_check_error (ccErrBadParam); } if (!io_stream ) { err = cci_check_error (ccErrBadParam); } if (!err) { err = cci_identifier_write (in_credentials->identifier, io_stream); } if (!err) { err = cci_credentials_union_write (in_credentials->cred_union, io_stream); } return cci_check_error (err); } /* ------------------------------------------------------------------------ */ cc_int32 ccs_credentials_compare_identifier (ccs_credentials_t in_credentials, cci_identifier_t in_identifier, cc_uint32 *out_equal) { cc_int32 err = ccNoError; if (!in_credentials) { err = cci_check_error (ccErrBadParam); } if (!in_identifier ) { err = cci_check_error (ccErrBadParam); } if (!out_equal ) { err = cci_check_error (ccErrBadParam); } if (!err) { err = cci_identifier_compare (in_credentials->identifier, in_identifier, out_equal); } return cci_check_error (err); } krb5-1.16/src/ccapi/server/ccs_os_notify.h0000644000704600001450000000311013211554426020357 0ustar ghudsonlibuuid/* ccapi/server/ccs_os_notify.h */ /* * Copyright 2006-2008 Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #ifndef CCS_OS_NOTIFY_H #define CCS_OS_NOTIFY_H #include "ccs_types.h" cc_int32 ccs_os_notify_cache_collection_changed (ccs_cache_collection_t io_cache_collection); cc_int32 ccs_os_notify_ccache_changed (ccs_cache_collection_t io_cache_collection, const char *in_ccache_name); #endif /* CCS_OS_NOTIFY_H */ krb5-1.16/src/ccapi/doc/0000755000704600001450000000000013211554426014611 5ustar ghudsonlibuuidkrb5-1.16/src/ccapi/doc/CCAPI-Windows-Design.html0000644000704600001450000002374713211554426021172 0ustar ghudsonlibuuid Windows CCAPI RPC design

Proposed RPC design for Windows CCAPI clients and server

The proposal is for a single user; the solution is replicated for each user logged onto the PC.

Conventions & clarifications

"Client" and "server" refer to the CCAPI client and server.

The CCAPI client acts as both an RPC client and RPC server and the CCAPI server acts as both an RPC client and RPC server.

  • The RPC call from the CCAPI client to the CCAPI server is called the "request." In this mode, the CCAPI client is the RPC client and the CCAPI server is the RPC server.
  • The RPC call from the CCAPI server to the CCAPI client is called the "reply." In this mode, the CCAPI client is the RPC server and the CCAPI server is the RPC client.

The Windows username is referred to below as "<USER>."

The Windows Logon Security Identifier is referred to as "<LSID>."

<UUID> means a thread-specific UUID.

<SST> means server start time, a time_t.

A description of client and server authentication has not been added yet.

Design Requirements

  • The server's OS-independent code is single threaded, because it must operate on platforms that do not allow multiple threads.
  • The client and server must be able to maintain connections, where state is maintained between individual messages.
  • Individual messages must be handled in a single threaded server.
  • The server must be able to detect when a client dies, so that any connection state can be cleaned up.

Design

The server and each client create an RPC endpoint. The server's endpoint is CCS_<LSID> and the client's endpoint is CCAPI_<UUID>, where each client geta a UUID.

On Windows, the server's ccs_pipe_t type is a char* and is set to the client UUID.

How is the request handled in the server and the reply sent to the client?

One straightforward way is for the reply to be the returned data in the request RPC call (an [out] parameter). That is, data passed from the RPC server to the RPC client. The request handler calls ccs_server_handle_request. Eventually, the server code calls ccs_os_server_send_reply, which saves the reply somewhere. When the server eventually returns to the request handler, the handler returns the saved reply to the client.

But this doesn't work. If two clients A and B ask for the same lock, A will acquire the lock and B will have to wait. But if the single threaded server waits for B's lock, it will never handle A's unlock message. Therefore the server must return to B's request handler and not send a reply to B. So this method will not work.

Instead, there are listener and worker threads in Windows-specific code.

The client's cci_os_ipc function waits for ccs_reply. The client sends the request, including it's UUID, from which the server can construct the endpoint on which to call ccs_reply.

The server's listener thread listens for RPC requests. The request handler puts each request/reply endpoint in a queue and returns to the client.

The server's worker thread removes items from the queue, calls ccs_server_handle_request. ccs_server_handle_request takes both the request data and the client UUID . Eventually ccs_os_server_send_reply is called, with the reply data and client UUID in the reply_pipe. ccs_os_server_send_reply calls ccs_reply on the client's endpoint, which sends the reply to the client.

Is there any security issue with the client listening for RPC calls from the server?

Connections

If the client wants state to be maintained on the server, the client creates a connection. When the connection is closed, the server cleans up any state associated with the connection.

Any given thread in an application process could want to create a connection. When cci_ipc_thread_init is called, the connection thread-local variables are initialized. New connections are created when cci_os_ipc() (via _cci_ipc_send) is called and no connection was previously established. Basically we lazily establish connections so the client doesn't talk to the server until it has to.

Detecting client exit

The server must be able to detect when clients disappear, so the server can free any resources that had been held for the client.

The Windows RPC API does not appear to provide a notification for an endpoint disappearing. It does provide a way to ask if an endpoint is listening. This is useful for polling, but we want a better performing solution than that.

The client has an isAlive function on its endpoint.

To detect the client disappearing without using polling, the server makes an asynchronous call to the isAlive function on the client's endpoint. The isAlive function never returns. When the client exits for any reason, it's endpoint will be closed and the server's function call will return an error. The asynchronous call on the server means no additional threads are used.

Windows provides a number of notification methods to signal I/O completion. Among them are I/O completion ports and callback functions. I chose callback functions because they appear to consume fewer resources.

RPC Endpoint / Function summary

  • The server creates one CCS_<LSID> endpoint to listen for connection requests and client requests. It has the functions
    • ccs_rpc_connect(msgtype, UUIDlen, <UUID>, status)
    • ccs_rpc_request(msgtype, UUIDlen, <UUID>, msglen, msg, SST, status) called by client. NB: The windows server sets the in_client_pipe to the in_reply_pipe.
  • Each client thread creates a CCAPI_<UUID> endpoint. It has the functions
    • isAlive [function never returns.]
    • ccs_rpc_request_reply(msgtype, SST, replylen, reply, status)
    • ccs_rpc_connect_reply(msgtype, SST, status

Windows-specific implementation details

Client CCAPI library initialization:

This code runs when the CCAPI DLL is loaded.

  • ?

Client initialization:

This code runs when cci_os_ipc_thread_init is called:

  • Generate <UUID> and save in thread-specific storage. This serves as the client ID / ccs_pipe_t.
  • Create client endpoint.
  • Listen on client endpoint.
  • Create canonical server connection endpoint from the <LSID>, which the client and server should have in common.
  • Test if server is listening to the CCS_<LSID> endpoint.
    • If not, quit. (! Start it?)
  • Call ccs_connect(<UUID>) on the CCS_<LSID> endpoint.
  • Save SST in thread-specific storage.

Server initialization:

[old]

  • Server is initialized by client starting a new process. There should be only one server process per Windows username.

[new]

  • Server is started by kfwlogon (as is done currently).
  • Capture server start time (SST).
  • Start listener thread, create listener endpoint, listen on CCS_<LSID> endpoint.

Establishing a connection:

  • Client calls ccs_connect(<UUID>) on server's CCS_<LSID> endpoint.
  • Client gets back and stores SST in thread-specific storage.
  • If new connection, server ...
    • adds connection to connection table
    • calls isAlive on CCAPI_<UUID>.
      • NB: isAlive never returns.

Client request:

The server's reply to the client's request is not synchronous.

  • Client calls ccs_rpc_request(msglen, msg, msgtype, UUIDlen, <UUID>, SST, status) on server's endpoint.
  • Server listen thread receives message, queues request.
  • Server worker thread dequeues request, processes, calls ccs_rpc_reply(replylen, reply, msgtype, status) on CCAPI_<UUID>.
  • Server checks SST. If server's SST is different, it means server has restarted since client created connection.
  • Client receives reply.

Detecting client exit

  • When connection created, client created an endpoint.
  • Server calls isAlive on client's endpoint.
  • When isAlive returns, the server's notification callback will be called. Call back routine queues a DISCONNECT pseudo-message. When the server's worker thread handles the DISCONNECT, it will release connection resources.

Detecting server exit

  • Client's call to ccs_rpc_request will return an error if the server has gone away.

 

------
Stop:
Start:

krb5-1.16/src/ccapi/lib/0000755000704600001450000000000013211554426014612 5ustar ghudsonlibuuidkrb5-1.16/src/ccapi/lib/ccapi_context_change_time.h0000644000704600001450000000337513211554426022141 0ustar ghudsonlibuuid/* ccapi/lib/ccapi_context_change_time.h */ /* * Copyright 2006 Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #ifndef CCAPI_CONTEXT_CHANGE_TIME_H #define CCAPI_CONTEXT_CHANGE_TIME_H #include "cci_common.h" cc_int32 cci_context_change_time_thread_init (void); void cci_context_change_time_thread_fini (void); cc_int32 cci_context_change_time_get (cc_time_t *out_change_time); cc_int32 cci_context_change_time_update (cci_identifier_t in_identifier, cc_time_t in_new_change_time); cc_int32 cci_context_change_time_sync (cci_identifier_t in_new_identifier); #endif /* CCAPI_CONTEXT_CHANGE_TIME_H */ krb5-1.16/src/ccapi/lib/ccapi_ipc.c0000644000704600001450000001051313211554426016670 0ustar ghudsonlibuuid/* ccapi/lib/ccapi_ipc.c */ /* * Copyright 2006 Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #include "ccapi_ipc.h" #include "ccapi_os_ipc.h" /* ------------------------------------------------------------------------ */ cc_int32 cci_ipc_process_init (void) { return cci_os_ipc_process_init (); } /* ------------------------------------------------------------------------ */ cc_int32 cci_ipc_thread_init (void) { return cci_os_ipc_thread_init (); } /* ------------------------------------------------------------------------ */ static cc_int32 _cci_ipc_send (enum cci_msg_id_t in_request_name, cc_int32 in_launch_server, cci_identifier_t in_identifier, k5_ipc_stream in_request_data, k5_ipc_stream *out_reply_data) { cc_int32 err = ccNoError; k5_ipc_stream request = NULL; k5_ipc_stream reply = NULL; cc_int32 reply_error = 0; if (!in_identifier) { err = cci_check_error (ccErrBadParam); } /* in_request_data may be NULL */ /* out_reply_data may be NULL */ if (!err) { err = cci_message_new_request_header (&request, in_request_name, in_identifier); } if (!err && in_request_data) { err = krb5int_ipc_stream_write (request, krb5int_ipc_stream_data (in_request_data), krb5int_ipc_stream_size (in_request_data)); } if (!err) { err = cci_os_ipc (in_launch_server, request, &reply); if (!err && krb5int_ipc_stream_size (reply) > 0) { err = cci_message_read_reply_header (reply, &reply_error); } } if (!err && reply_error) { err = reply_error; } if (!err && out_reply_data) { *out_reply_data = reply; reply = NULL; /* take ownership */ } krb5int_ipc_stream_release (request); krb5int_ipc_stream_release (reply); return cci_check_error (err); } /* ------------------------------------------------------------------------ */ cc_int32 cci_ipc_send (enum cci_msg_id_t in_request_name, cci_identifier_t in_identifier, k5_ipc_stream in_request_data, k5_ipc_stream *out_reply_data) { return cci_check_error (_cci_ipc_send (in_request_name, 1, in_identifier, in_request_data, out_reply_data)); } /* ------------------------------------------------------------------------ */ cc_int32 cci_ipc_send_no_launch (enum cci_msg_id_t in_request_name, cci_identifier_t in_identifier, k5_ipc_stream in_request_data, k5_ipc_stream *out_reply_data) { return cci_check_error (_cci_ipc_send (in_request_name, 0, in_identifier, in_request_data, out_reply_data)); } krb5-1.16/src/ccapi/lib/ccapi_credentials.h0000644000704600001450000000355613211554426020430 0ustar ghudsonlibuuid/* ccapi/lib/ccapi_credentials.h */ /* * Copyright 2006 Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #ifndef CCAPI_CREDENTIALS_H #define CCAPI_CREDENTIALS_H #include "cci_common.h" cc_int32 cci_credentials_read (cc_credentials_t *out_credentials, k5_ipc_stream in_stream); cc_int32 cci_credentials_write (cc_credentials_t in_credentials, k5_ipc_stream in_stream); cc_int32 ccapi_credentials_compare (cc_credentials_t in_credentials, cc_credentials_t in_compare_to_credentials, cc_uint32 *out_equal); cc_int32 ccapi_credentials_release (cc_credentials_t io_credentials); #endif /* CCAPI_CREDENTIALS_H */ krb5-1.16/src/ccapi/lib/ccapi_v2.exports0000644000704600001450000000056513211554426017734 0ustar ghudsonlibuuidcc_shutdown cc_create cc_close cc_destroy cc_get_change_time cc_open cc_store cc_remove_cred cc_set_principal cc_get_principal cc_get_cred_version cc_get_name cc_seq_fetch_NCs_begin cc_seq_fetch_NCs_next cc_seq_fetch_NCs_end cc_seq_fetch_creds_begin cc_seq_fetch_creds_next cc_seq_fetch_creds_end cc_get_NC_info cc_free_principal cc_free_name cc_free_creds cc_free_NC_info krb5-1.16/src/ccapi/lib/ccapi_string.h0000644000704600001450000000272613211554426017437 0ustar ghudsonlibuuid/* ccapi/lib/ccapi_string.h */ /* * Copyright 2006 Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #ifndef CCAPI_STRING_H #define CCAPI_STRING_H #include "cci_common.h" cc_int32 cci_string_new (cc_string_t *out_string, char *in_cstring); cc_int32 ccapi_string_release (cc_string_t in_string); #endif /* CCAPI_STRING_H */ krb5-1.16/src/ccapi/lib/ccapi.exports0000644000704600001450000000001613211554426017314 0ustar ghudsonlibuuidcc_initialize krb5-1.16/src/ccapi/lib/ccapi_context.h0000644000704600001450000000724413211554426017615 0ustar ghudsonlibuuid/* ccapi/lib/ccapi_context.h */ /* * Copyright 2006 Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #ifndef CCAPI_CONTEXT_H #define CCAPI_CONTEXT_H #include "cci_common.h" /* Used for freeing ccapi context in thread fini calls * Does not tell the server you are exiting. */ cc_int32 cci_context_destroy (cc_context_t in_context); cc_int32 ccapi_context_release (cc_context_t in_context); cc_int32 ccapi_context_get_change_time (cc_context_t in_context, cc_time_t *out_time); cc_int32 ccapi_context_wait_for_change (cc_context_t in_context); cc_int32 ccapi_context_get_default_ccache_name (cc_context_t in_context, cc_string_t *out_name); cc_int32 ccapi_context_open_ccache (cc_context_t in_context, const char *in_name, cc_ccache_t *out_ccache); cc_int32 ccapi_context_open_default_ccache (cc_context_t in_context, cc_ccache_t *out_ccache); cc_int32 ccapi_context_create_ccache (cc_context_t in_context, const char *in_name, cc_uint32 in_cred_vers, const char *in_principal, cc_ccache_t *out_ccache); cc_int32 ccapi_context_create_default_ccache (cc_context_t in_context, cc_uint32 in_cred_vers, const char *in_principal, cc_ccache_t *out_ccache); cc_int32 ccapi_context_create_new_ccache (cc_context_t in_context, cc_uint32 in_cred_vers, const char *in_principal, cc_ccache_t *out_ccache); cc_int32 ccapi_context_new_ccache_iterator (cc_context_t in_context, cc_ccache_iterator_t *out_iterator); cc_int32 ccapi_context_lock (cc_context_t in_context, cc_uint32 in_lock_type, cc_uint32 in_block); cc_int32 ccapi_context_unlock (cc_context_t in_context); cc_int32 ccapi_context_compare (cc_context_t in_context, cc_context_t in_compare_to_context, cc_uint32 *out_equal); #ifdef WIN32 void cci_thread_init__auxinit(); #endif #endif /* CCAPI_CONTEXT_H */ krb5-1.16/src/ccapi/lib/ccapi_credentials_iterator.h0000644000704600001450000000510413211554426022330 0ustar ghudsonlibuuid/* ccapi/lib/ccapi_credentials_iterator.h */ /* * Copyright 2006 Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #ifndef CCAPI_CREDENTIALS_ITERATOR_H #define CCAPI_CREDENTIALS_ITERATOR_H #include "cci_common.h" cc_int32 cci_credentials_iterator_new (cc_credentials_iterator_t *out_credentials_iterator, cci_identifier_t in_identifier); cc_int32 cci_credentials_iterator_write (cc_credentials_iterator_t in_credentials_iterator, k5_ipc_stream in_stream); cc_int32 ccapi_credentials_iterator_release (cc_credentials_iterator_t io_credentials_iterator); cc_int32 ccapi_credentials_iterator_next (cc_credentials_iterator_t in_credentials_iterator, cc_credentials_t *out_credentials); cc_int32 ccapi_credentials_iterator_clone (cc_credentials_iterator_t in_credentials_iterator, cc_credentials_iterator_t *out_credentials_iterator); cc_int32 cci_credentials_iterator_get_compat_version (cc_credentials_iterator_t in_credentials_iterator, cc_uint32 *out_compat_version); cc_int32 cci_credentials_iterator_set_compat_version (cc_credentials_iterator_t io_credentials_iterator, cc_uint32 in_compat_version); #endif /* CCAPI_CREDENTIALS_ITERATOR_H */ krb5-1.16/src/ccapi/lib/ccapi_ccache.c0000644000704600001450000005577213211554426017343 0ustar ghudsonlibuuid/* ccapi/lib/ccapi_ccache.c */ /* * Copyright 2006, 2007 Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #include "ccapi_ccache.h" #include "ccapi_string.h" #include "ccapi_credentials.h" #include "ccapi_credentials_iterator.h" #include "ccapi_ipc.h" /* ------------------------------------------------------------------------ */ typedef struct cci_ccache_d { cc_ccache_f *functions; #if TARGET_OS_MAC cc_ccache_f *vector_functions; #endif cci_identifier_t identifier; cc_time_t last_wait_for_change_time; cc_uint32 compat_version; } *cci_ccache_t; /* ------------------------------------------------------------------------ */ struct cci_ccache_d cci_ccache_initializer = { NULL VECTOR_FUNCTIONS_INITIALIZER, NULL, 0 }; cc_ccache_f cci_ccache_f_initializer = { ccapi_ccache_release, ccapi_ccache_destroy, ccapi_ccache_set_default, ccapi_ccache_get_credentials_version, ccapi_ccache_get_name, ccapi_ccache_get_principal, ccapi_ccache_set_principal, ccapi_ccache_store_credentials, ccapi_ccache_remove_credentials, ccapi_ccache_new_credentials_iterator, ccapi_ccache_move, ccapi_ccache_lock, ccapi_ccache_unlock, ccapi_ccache_get_last_default_time, ccapi_ccache_get_change_time, ccapi_ccache_compare, ccapi_ccache_get_kdc_time_offset, ccapi_ccache_set_kdc_time_offset, ccapi_ccache_clear_kdc_time_offset, ccapi_ccache_wait_for_change }; /* ------------------------------------------------------------------------ */ cc_int32 cci_ccache_new (cc_ccache_t *out_ccache, cci_identifier_t in_identifier) { cc_int32 err = ccNoError; cci_ccache_t ccache = NULL; if (!out_ccache ) { err = cci_check_error (ccErrBadParam); } if (!in_identifier) { err = cci_check_error (ccErrBadParam); } if (!err) { ccache = malloc (sizeof (*ccache)); if (ccache) { *ccache = cci_ccache_initializer; } else { err = cci_check_error (ccErrNoMem); } } if (!err) { ccache->functions = malloc (sizeof (*ccache->functions)); if (ccache->functions) { *ccache->functions = cci_ccache_f_initializer; } else { err = cci_check_error (ccErrNoMem); } } if (!err) { err = cci_identifier_copy (&ccache->identifier, in_identifier); } if (!err) { *out_ccache = (cc_ccache_t) ccache; ccache = NULL; /* take ownership */ } ccapi_ccache_release ((cc_ccache_t) ccache); return cci_check_error (err); } /* ------------------------------------------------------------------------ */ cc_int32 cci_ccache_write (cc_ccache_t in_ccache, k5_ipc_stream in_stream) { cc_int32 err = ccNoError; cci_ccache_t ccache = (cci_ccache_t) in_ccache; if (!in_ccache) { err = cci_check_error (ccErrBadParam); } if (!in_stream) { err = cci_check_error (ccErrBadParam); } if (!err) { err = cci_identifier_write (ccache->identifier, in_stream); } return cci_check_error (err); } #ifdef TARGET_OS_MAC #pragma mark - #endif /* ------------------------------------------------------------------------ */ cc_int32 ccapi_ccache_release (cc_ccache_t io_ccache) { cc_int32 err = ccNoError; cci_ccache_t ccache = (cci_ccache_t) io_ccache; if (!io_ccache) { err = ccErrBadParam; } if (!err) { cci_identifier_release (ccache->identifier); free ((char *) ccache->functions); free (ccache); } return err; } /* ------------------------------------------------------------------------ */ cc_int32 ccapi_ccache_destroy (cc_ccache_t io_ccache) { cc_int32 err = ccNoError; cci_ccache_t ccache = (cci_ccache_t) io_ccache; if (!io_ccache) { err = cci_check_error (ccErrBadParam); } if (!err) { err = cci_ipc_send (cci_ccache_destroy_msg_id, ccache->identifier, NULL, NULL); } if (!err) { err = ccapi_ccache_release (io_ccache); } return cci_check_error (err); } /* ------------------------------------------------------------------------ */ cc_int32 ccapi_ccache_set_default (cc_ccache_t io_ccache) { cc_int32 err = ccNoError; cci_ccache_t ccache = (cci_ccache_t) io_ccache; if (!io_ccache) { err = cci_check_error (ccErrBadParam); } if (!err) { err = cci_ipc_send (cci_ccache_set_default_msg_id, ccache->identifier, NULL, NULL); } return cci_check_error (err); } /* ------------------------------------------------------------------------ */ cc_int32 ccapi_ccache_get_credentials_version (cc_ccache_t in_ccache, cc_uint32 *out_credentials_version) { cc_int32 err = ccNoError; cci_ccache_t ccache = (cci_ccache_t) in_ccache; k5_ipc_stream reply = NULL; if (!in_ccache ) { err = cci_check_error (ccErrBadParam); } if (!out_credentials_version) { err = cci_check_error (ccErrBadParam); } if (!err) { err = cci_ipc_send (cci_ccache_get_credentials_version_msg_id, ccache->identifier, NULL, &reply); } if (!err) { err = krb5int_ipc_stream_read_uint32 (reply, out_credentials_version); } krb5int_ipc_stream_release (reply); return cci_check_error (err); } /* ------------------------------------------------------------------------ */ cc_int32 ccapi_ccache_get_name (cc_ccache_t in_ccache, cc_string_t *out_name) { cc_int32 err = ccNoError; cci_ccache_t ccache = (cci_ccache_t) in_ccache; k5_ipc_stream reply = NULL; char *name = NULL; if (!in_ccache) { err = cci_check_error (ccErrBadParam); } if (!out_name ) { err = cci_check_error (ccErrBadParam); } if (!err) { err = cci_ipc_send (cci_ccache_get_name_msg_id, ccache->identifier, NULL, &reply); } if (!err) { err = krb5int_ipc_stream_read_string (reply, &name); } if (!err) { err = cci_string_new (out_name, name); } krb5int_ipc_stream_release (reply); krb5int_ipc_stream_free_string (name); return cci_check_error (err); } /* ------------------------------------------------------------------------ */ cc_int32 ccapi_ccache_get_principal (cc_ccache_t in_ccache, cc_uint32 in_credentials_version, cc_string_t *out_principal) { cc_int32 err = ccNoError; cci_ccache_t ccache = (cci_ccache_t) in_ccache; k5_ipc_stream request = NULL; k5_ipc_stream reply = NULL; char *principal = NULL; if (!in_ccache ) { err = cci_check_error (ccErrBadParam); } if (!out_principal) { err = cci_check_error (ccErrBadParam); } if (!err) { err = krb5int_ipc_stream_new (&request); } if (!err) { err = krb5int_ipc_stream_write_uint32 (request, in_credentials_version); } if (!err) { err = cci_ipc_send (cci_ccache_get_principal_msg_id, ccache->identifier, request, &reply); } if (!err) { err = krb5int_ipc_stream_read_string (reply, &principal); } if (!err) { err = cci_string_new (out_principal, principal); } krb5int_ipc_stream_release (request); krb5int_ipc_stream_release (reply); krb5int_ipc_stream_free_string (principal); return cci_check_error (err); } /* ------------------------------------------------------------------------ */ cc_int32 ccapi_ccache_set_principal (cc_ccache_t io_ccache, cc_uint32 in_credentials_version, const char *in_principal) { cc_int32 err = ccNoError; cci_ccache_t ccache = (cci_ccache_t) io_ccache; k5_ipc_stream request = NULL; if (!io_ccache ) { err = cci_check_error (ccErrBadParam); } if (!in_principal) { err = cci_check_error (ccErrBadParam); } if (!err) { err = krb5int_ipc_stream_new (&request); } if (!err) { err = krb5int_ipc_stream_write_uint32 (request, in_credentials_version); } if (!err) { err = krb5int_ipc_stream_write_string (request, in_principal); } if (!err) { err = cci_ipc_send (cci_ccache_set_principal_msg_id, ccache->identifier, request, NULL); } krb5int_ipc_stream_release (request); return cci_check_error (err); } /* ------------------------------------------------------------------------ */ cc_int32 ccapi_ccache_store_credentials (cc_ccache_t io_ccache, const cc_credentials_union *in_credentials_union) { cc_int32 err = ccNoError; cci_ccache_t ccache = (cci_ccache_t) io_ccache; k5_ipc_stream request = NULL; if (!io_ccache ) { err = cci_check_error (ccErrBadParam); } if (!in_credentials_union) { err = cci_check_error (ccErrBadParam); } if (!err) { err = krb5int_ipc_stream_new (&request); } if (!err) { err = cci_credentials_union_write (in_credentials_union, request); } if (!err) { err = cci_ipc_send (cci_ccache_store_credentials_msg_id, ccache->identifier, request, NULL); } krb5int_ipc_stream_release (request); return cci_check_error (err); } /* ------------------------------------------------------------------------ */ cc_int32 ccapi_ccache_remove_credentials (cc_ccache_t io_ccache, cc_credentials_t in_credentials) { cc_int32 err = ccNoError; cci_ccache_t ccache = (cci_ccache_t) io_ccache; k5_ipc_stream request = NULL; if (!io_ccache ) { err = cci_check_error (ccErrBadParam); } if (!in_credentials) { err = cci_check_error (ccErrBadParam); } if (!err) { err = krb5int_ipc_stream_new (&request); } if (!err) { err = cci_credentials_write (in_credentials, request); } if (!err) { err = cci_ipc_send (cci_ccache_remove_credentials_msg_id, ccache->identifier, request, NULL); } krb5int_ipc_stream_release (request); return cci_check_error (err); } /* ------------------------------------------------------------------------ */ cc_int32 ccapi_ccache_new_credentials_iterator (cc_ccache_t in_ccache, cc_credentials_iterator_t *out_credentials_iterator) { cc_int32 err = ccNoError; cci_ccache_t ccache = (cci_ccache_t) in_ccache; k5_ipc_stream reply = NULL; cci_identifier_t identifier = NULL; if (!in_ccache ) { err = cci_check_error (ccErrBadParam); } if (!out_credentials_iterator) { err = cci_check_error (ccErrBadParam); } if (!err) { err = cci_ipc_send (cci_ccache_new_credentials_iterator_msg_id, ccache->identifier, NULL, &reply); } if (!err) { err = cci_identifier_read (&identifier, reply); } if (!err) { err = cci_credentials_iterator_new (out_credentials_iterator, identifier); } krb5int_ipc_stream_release (reply); cci_identifier_release (identifier); return cci_check_error (err); } /* ------------------------------------------------------------------------ */ /* Note: message is sent as the destination to avoid extra work on the */ /* server when deleting it the source ccache. */ cc_int32 ccapi_ccache_move (cc_ccache_t io_source_ccache, cc_ccache_t io_destination_ccache) { cc_int32 err = ccNoError; cci_ccache_t source_ccache = (cci_ccache_t) io_source_ccache; cci_ccache_t destination_ccache = (cci_ccache_t) io_destination_ccache; k5_ipc_stream request = NULL; if (!io_source_ccache ) { err = cci_check_error (ccErrBadParam); } if (!io_destination_ccache) { err = cci_check_error (ccErrBadParam); } if (!err) { err = krb5int_ipc_stream_new (&request); } if (!err) { err = cci_identifier_write (source_ccache->identifier, request); } if (!err) { err = cci_ipc_send (cci_ccache_move_msg_id, destination_ccache->identifier, request, NULL); } krb5int_ipc_stream_release (request); return cci_check_error (err); } /* ------------------------------------------------------------------------ */ cc_int32 ccapi_ccache_lock (cc_ccache_t io_ccache, cc_uint32 in_lock_type, cc_uint32 in_block) { cc_int32 err = ccNoError; cci_ccache_t ccache = (cci_ccache_t) io_ccache; k5_ipc_stream request = NULL; if (!io_ccache) { err = cci_check_error (ccErrBadParam); } if (!err) { err = krb5int_ipc_stream_new (&request); } if (!err) { err = krb5int_ipc_stream_write_uint32 (request, in_lock_type); } if (!err) { err = krb5int_ipc_stream_write_uint32 (request, in_block); } if (!err) { err = cci_ipc_send (cci_ccache_lock_msg_id, ccache->identifier, request, NULL); } krb5int_ipc_stream_release (request); return cci_check_error (err); } /* ------------------------------------------------------------------------ */ cc_int32 ccapi_ccache_unlock (cc_ccache_t io_ccache) { cc_int32 err = ccNoError; cci_ccache_t ccache = (cci_ccache_t) io_ccache; if (!io_ccache) { err = cci_check_error (ccErrBadParam); } if (!err) { err = cci_ipc_send (cci_ccache_unlock_msg_id, ccache->identifier, NULL, NULL); } return cci_check_error (err); } /* ------------------------------------------------------------------------ */ cc_int32 ccapi_ccache_get_last_default_time (cc_ccache_t in_ccache, cc_time_t *out_last_default_time) { cc_int32 err = ccNoError; cci_ccache_t ccache = (cci_ccache_t) in_ccache; k5_ipc_stream reply = NULL; if (!in_ccache ) { err = cci_check_error (ccErrBadParam); } if (!out_last_default_time) { err = cci_check_error (ccErrBadParam); } if (!err) { err = cci_ipc_send (cci_ccache_get_last_default_time_msg_id, ccache->identifier, NULL, &reply); } if (!err) { err = krb5int_ipc_stream_read_time (reply, out_last_default_time); } krb5int_ipc_stream_release (reply); return cci_check_error (err); } /* ------------------------------------------------------------------------ */ cc_int32 ccapi_ccache_get_change_time (cc_ccache_t in_ccache, cc_time_t *out_change_time) { cc_int32 err = ccNoError; cci_ccache_t ccache = (cci_ccache_t) in_ccache; k5_ipc_stream reply = NULL; if (!in_ccache ) { err = cci_check_error (ccErrBadParam); } if (!out_change_time) { err = cci_check_error (ccErrBadParam); } if (!err) { err = cci_ipc_send (cci_ccache_get_change_time_msg_id, ccache->identifier, NULL, &reply); } if (!err) { err = krb5int_ipc_stream_read_time (reply, out_change_time); } krb5int_ipc_stream_release (reply); return cci_check_error (err); } /* ------------------------------------------------------------------------ */ cc_int32 ccapi_ccache_wait_for_change (cc_ccache_t in_ccache) { cc_int32 err = ccNoError; cci_ccache_t ccache = (cci_ccache_t) in_ccache; k5_ipc_stream request = NULL; k5_ipc_stream reply = NULL; if (!in_ccache) { err = cci_check_error (ccErrBadParam); } if (!err) { err = krb5int_ipc_stream_new (&request); } if (!err) { err = krb5int_ipc_stream_write_time (request, ccache->last_wait_for_change_time); } if (!err) { err = cci_ipc_send (cci_ccache_wait_for_change_msg_id, ccache->identifier, request, &reply); } if (!err) { err = krb5int_ipc_stream_read_time (reply, &ccache->last_wait_for_change_time); } krb5int_ipc_stream_release (request); krb5int_ipc_stream_release (reply); return cci_check_error (err); } /* ------------------------------------------------------------------------ */ cc_int32 ccapi_ccache_compare (cc_ccache_t in_ccache, cc_ccache_t in_compare_to_ccache, cc_uint32 *out_equal) { cc_int32 err = ccNoError; cci_ccache_t ccache = (cci_ccache_t) in_ccache; cci_ccache_t compare_to_ccache = (cci_ccache_t) in_compare_to_ccache; if (!in_ccache ) { err = cci_check_error (ccErrBadParam); } if (!in_compare_to_ccache) { err = cci_check_error (ccErrBadParam); } if (!out_equal ) { err = cci_check_error (ccErrBadParam); } if (!err) { err = cci_identifier_compare (ccache->identifier, compare_to_ccache->identifier, out_equal); } return cci_check_error (err); } /* ------------------------------------------------------------------------ */ cc_int32 ccapi_ccache_get_kdc_time_offset (cc_ccache_t in_ccache, cc_uint32 in_credentials_version, cc_time_t *out_time_offset) { cc_int32 err = ccNoError; cci_ccache_t ccache = (cci_ccache_t) in_ccache; k5_ipc_stream request = NULL; k5_ipc_stream reply = NULL; if (!in_ccache ) { err = cci_check_error (ccErrBadParam); } if (!out_time_offset) { err = cci_check_error (ccErrBadParam); } if (!err) { err = krb5int_ipc_stream_new (&request); } if (!err) { err = krb5int_ipc_stream_write_uint32 (request, in_credentials_version); } if (!err) { err = cci_ipc_send (cci_ccache_get_kdc_time_offset_msg_id, ccache->identifier, request, &reply); } if (!err) { err = krb5int_ipc_stream_read_time (reply, out_time_offset); } krb5int_ipc_stream_release (request); krb5int_ipc_stream_release (reply); return cci_check_error (err); } /* ------------------------------------------------------------------------ */ cc_int32 ccapi_ccache_set_kdc_time_offset (cc_ccache_t io_ccache, cc_uint32 in_credentials_version, cc_time_t in_time_offset) { cc_int32 err = ccNoError; cci_ccache_t ccache = (cci_ccache_t) io_ccache; k5_ipc_stream request = NULL; if (!io_ccache) { err = cci_check_error (ccErrBadParam); } if (!err) { err = krb5int_ipc_stream_new (&request); } if (!err) { err = krb5int_ipc_stream_write_uint32 (request, in_credentials_version); } if (!err) { err = krb5int_ipc_stream_write_time (request, in_time_offset); } if (!err) { err = cci_ipc_send (cci_ccache_set_kdc_time_offset_msg_id, ccache->identifier, request, NULL); } krb5int_ipc_stream_release (request); return cci_check_error (err); } /* ------------------------------------------------------------------------ */ cc_int32 ccapi_ccache_clear_kdc_time_offset (cc_ccache_t io_ccache, cc_uint32 in_credentials_version) { cc_int32 err = ccNoError; cci_ccache_t ccache = (cci_ccache_t) io_ccache; k5_ipc_stream request = NULL; if (!io_ccache) { err = cci_check_error (ccErrBadParam); } if (!err) { err = krb5int_ipc_stream_new (&request); } if (!err) { err = krb5int_ipc_stream_write_uint32 (request, in_credentials_version); } if (!err) { err = cci_ipc_send (cci_ccache_clear_kdc_time_offset_msg_id, ccache->identifier, request, NULL); } krb5int_ipc_stream_release (request); return cci_check_error (err); } #ifdef TARGET_OS_MAC #pragma mark - #endif /* ------------------------------------------------------------------------ */ cc_int32 cci_ccache_get_compat_version (cc_ccache_t in_ccache, cc_uint32 *out_compat_version) { cc_int32 err = ccNoError; cci_ccache_t ccache = (cci_ccache_t) in_ccache; if (!in_ccache ) { err = cci_check_error (ccErrBadParam); } if (!out_compat_version) { err = cci_check_error (ccErrBadParam); } if (!err) { *out_compat_version = ccache->compat_version; } return cci_check_error (err); } /* ------------------------------------------------------------------------ */ cc_int32 cci_ccache_set_compat_version (cc_ccache_t io_ccache, cc_uint32 in_compat_version) { cc_int32 err = ccNoError; cci_ccache_t ccache = (cci_ccache_t) io_ccache; if (!io_ccache) { err = cci_check_error (ccErrBadParam); } if (!err) { ccache->compat_version = in_compat_version; } return cci_check_error (err); } krb5-1.16/src/ccapi/lib/mac/0000755000704600001450000000000013211554426015352 5ustar ghudsonlibuuidkrb5-1.16/src/ccapi/lib/mac/ccapi_vector.exports0000644000704600001450000000335613211554426021450 0ustar ghudsonlibuuid__cc_context_release_vector __cc_context_get_change_time_vector __cc_context_get_default_ccache_name_vector __cc_context_open_ccache_vector __cc_context_open_default_ccache_vector __cc_context_create_ccache_vector __cc_context_create_default_ccache_vector __cc_context_create_new_ccache_vector __cc_context_new_ccache_iterator_vector __cc_context_lock_vector __cc_context_unlock_vector __cc_context_compare_vector __cc_ccache_release_vector __cc_ccache_destroy_vector __cc_ccache_set_default_vector __cc_ccache_get_credentials_version_vector __cc_ccache_get_name_vector __cc_ccache_get_principal_vector __cc_ccache_set_principal_vector __cc_ccache_store_credentials_vector __cc_ccache_remove_credentials_vector __cc_ccache_new_credentials_iterator_vector __cc_ccache_move_vector __cc_ccache_lock_vector __cc_ccache_unlock_vector __cc_ccache_get_last_default_time_vector __cc_ccache_get_change_time_vector __cc_ccache_compare_vector __cc_string_release_vector __cc_credentials_release_vector __cc_credentials_compare_vector __cc_ccache_iterator_release_vector __cc_ccache_iterator_next_vector __cc_credentials_iterator_release_vector __cc_credentials_iterator_next_vector __cc_initialize_vector __cc_shutdown_vector __cc_get_NC_info_vector __cc_get_change_time_vector __cc_open_vector __cc_create_vector __cc_close_vector __cc_destroy_vector __cc_seq_fetch_NCs_begin_vector __cc_seq_fetch_NCs_next_vector __cc_seq_fetch_NCs_end_vector __cc_get_name_vector __cc_get_cred_version_vector __cc_set_principal_vector __cc_get_principal_vector __cc_store_vector __cc_remove_cred_vector __cc_seq_fetch_creds_begin_vector __cc_seq_fetch_creds_next_vector __cc_seq_fetch_creds_end_vector __cc_free_principal_vector __cc_free_name_vector __cc_free_creds_vector __cc_free_NC_info_vector krb5-1.16/src/ccapi/lib/mac/ccapi_vector.c0000644000704600001450000007463413211554426020175 0ustar ghudsonlibuuid/* ccapi/lib/mac/ccapi_vector.c */ /* * Copyright 2006 Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #include "ccapi_vector.h" #include "ccapi_context.h" #include "ccapi_string.h" #include "ccapi_ccache.h" #include "ccapi_credentials.h" #include "ccapi_ccache_iterator.h" #include "ccapi_credentials_iterator.h" /* ------------------------------------------------------------------------ */ static void cci_swap_string_functions (cc_string_t io_string) { cc_string_f temp = *(io_string->functions); *((cc_string_f *)io_string->functions) = *(io_string->vector_functions); *((cc_string_f *)io_string->vector_functions) = temp; } /* ------------------------------------------------------------------------ */ static void cci_swap_context_functions (cc_context_t io_context) { cc_context_f temp = *(io_context->functions); *((cc_context_f *)io_context->functions) = *(io_context->vector_functions); *((cc_context_f *)io_context->vector_functions) = temp; } /* ------------------------------------------------------------------------ */ static void cci_swap_ccache_functions (cc_ccache_t io_ccache) { cc_ccache_f temp = *(io_ccache->functions); *((cc_ccache_f *)io_ccache->functions) = *(io_ccache->vector_functions); *((cc_ccache_f *)io_ccache->vector_functions) = temp; } /* ------------------------------------------------------------------------ */ static void cci_swap_credentials_functions (cc_credentials_t io_credentials) { cc_credentials_f temp = *(io_credentials->functions); *((cc_credentials_f *)io_credentials->functions) = *(io_credentials->otherFunctions); *((cc_credentials_f *)io_credentials->otherFunctions) = temp; } /* ------------------------------------------------------------------------ */ static void cci_swap_ccache_iterator_functions (cc_ccache_iterator_t io_ccache_iterator) { cc_ccache_iterator_f temp = *(io_ccache_iterator->functions); *((cc_ccache_iterator_f *)io_ccache_iterator->functions) = *(io_ccache_iterator->vector_functions); *((cc_ccache_iterator_f *)io_ccache_iterator->vector_functions) = temp; } /* ------------------------------------------------------------------------ */ static void cci_swap_credentials_iterator_functions (cc_credentials_iterator_t io_credentials_iterator) { cc_credentials_iterator_f temp = *(io_credentials_iterator->functions); *((cc_credentials_iterator_f *)io_credentials_iterator->functions) = *(io_credentials_iterator->vector_functions); *((cc_credentials_iterator_f *)io_credentials_iterator->vector_functions) = temp; } #pragma mark - /* ------------------------------------------------------------------------ */ cc_int32 __cc_initialize_vector (cc_context_t *out_context, cc_int32 in_version, cc_int32 *out_supported_version, char const **out_vendor) { return cc_initialize (out_context, in_version, out_supported_version, out_vendor); } #pragma mark - /* ------------------------------------------------------------------------ */ cc_int32 __cc_string_release_vector (cc_string_t in_string) { cci_swap_string_functions (in_string); return ccapi_string_release (in_string); } #pragma mark - /* ------------------------------------------------------------------------ */ cc_int32 __cc_context_release_vector (cc_context_t io_context) { cci_swap_context_functions (io_context); return ccapi_context_release (io_context); } /* ------------------------------------------------------------------------ */ cc_int32 __cc_context_get_change_time_vector (cc_context_t in_context, cc_time_t *out_change_time) { cc_int32 err = ccNoError; cci_swap_context_functions (in_context); err = ccapi_context_get_change_time (in_context, out_change_time); cci_swap_context_functions (in_context); return err; } /* ------------------------------------------------------------------------ */ cc_int32 __cc_context_get_default_ccache_name_vector (cc_context_t in_context, cc_string_t *out_name) { cc_int32 err = ccNoError; cci_swap_context_functions (in_context); err = ccapi_context_get_default_ccache_name (in_context, out_name); cci_swap_context_functions (in_context); return err; } /* ------------------------------------------------------------------------ */ cc_int32 __cc_context_open_ccache_vector (cc_context_t in_context, const char *in_name, cc_ccache_t *out_ccache) { cc_int32 err = ccNoError; cci_swap_context_functions (in_context); err = ccapi_context_open_ccache (in_context, in_name, out_ccache); cci_swap_context_functions (in_context); return err; } /* ------------------------------------------------------------------------ */ cc_int32 __cc_context_open_default_ccache_vector (cc_context_t in_context, cc_ccache_t *out_ccache) { cc_int32 err = ccNoError; cci_swap_context_functions (in_context); err = ccapi_context_open_default_ccache (in_context, out_ccache); cci_swap_context_functions (in_context); return err; } /* ------------------------------------------------------------------------ */ cc_int32 __cc_context_create_ccache_vector (cc_context_t in_context, const char *in_name, cc_uint32 in_cred_vers, const char *in_principal, cc_ccache_t *out_ccache) { cc_int32 err = ccNoError; cci_swap_context_functions (in_context); err = ccapi_context_create_ccache (in_context, in_name, in_cred_vers, in_principal, out_ccache); cci_swap_context_functions (in_context); return err; } /* ------------------------------------------------------------------------ */ cc_int32 __cc_context_create_default_ccache_vector (cc_context_t in_context, cc_uint32 in_cred_vers, const char *in_principal, cc_ccache_t *out_ccache) { cc_int32 err = ccNoError; cci_swap_context_functions (in_context); err = ccapi_context_create_default_ccache (in_context, in_cred_vers, in_principal, out_ccache); cci_swap_context_functions (in_context); return err; } /* ------------------------------------------------------------------------ */ cc_int32 __cc_context_create_new_ccache_vector (cc_context_t in_context, cc_uint32 in_cred_vers, const char *in_principal, cc_ccache_t *out_ccache) { cc_int32 err = ccNoError; cci_swap_context_functions (in_context); err = ccapi_context_create_new_ccache (in_context, in_cred_vers, in_principal, out_ccache); cci_swap_context_functions (in_context); return err; } /* ------------------------------------------------------------------------ */ cc_int32 __cc_context_new_ccache_iterator_vector (cc_context_t in_context, cc_ccache_iterator_t *out_iterator) { cc_int32 err = ccNoError; cci_swap_context_functions (in_context); err = ccapi_context_new_ccache_iterator (in_context, out_iterator); cci_swap_context_functions (in_context); return err; } /* ------------------------------------------------------------------------ */ cc_int32 __cc_context_lock_vector (cc_context_t in_context, cc_uint32 in_lock_type, cc_uint32 in_block) { cc_int32 err = ccNoError; cci_swap_context_functions (in_context); err = ccapi_context_lock (in_context, in_lock_type, in_block); cci_swap_context_functions (in_context); return err; } /* ------------------------------------------------------------------------ */ cc_int32 __cc_context_unlock_vector (cc_context_t in_context) { cc_int32 err = ccNoError; cci_swap_context_functions (in_context); err = ccapi_context_unlock (in_context); cci_swap_context_functions (in_context); return err; } /* ------------------------------------------------------------------------ */ cc_int32 __cc_context_compare_vector (cc_context_t in_context, cc_context_t in_compare_to_context, cc_uint32 *out_equal) { cc_int32 err = ccNoError; cci_swap_context_functions (in_context); err = ccapi_context_compare (in_context, in_compare_to_context, out_equal); cci_swap_context_functions (in_context); return err; } #pragma mark - /* ------------------------------------------------------------------------ */ cc_int32 __cc_ccache_release_vector (cc_ccache_t io_ccache) { cci_swap_ccache_functions (io_ccache); return ccapi_ccache_release (io_ccache); } /* ------------------------------------------------------------------------ */ cc_int32 __cc_ccache_destroy_vector (cc_ccache_t io_ccache) { cci_swap_ccache_functions (io_ccache); return ccapi_ccache_destroy (io_ccache); } /* ------------------------------------------------------------------------ */ cc_int32 __cc_ccache_set_default_vector (cc_ccache_t io_ccache) { cc_int32 err = ccNoError; cci_swap_ccache_functions (io_ccache); err = ccapi_ccache_set_default (io_ccache); cci_swap_ccache_functions (io_ccache); return err; } /* ------------------------------------------------------------------------ */ cc_uint32 __cc_ccache_get_credentials_version_vector (cc_ccache_t in_ccache, cc_uint32 *out_credentials_version) { cc_int32 err = ccNoError; cci_swap_ccache_functions (in_ccache); err = ccapi_ccache_get_credentials_version (in_ccache, out_credentials_version); cci_swap_ccache_functions (in_ccache); return err; } /* ------------------------------------------------------------------------ */ cc_int32 __cc_ccache_get_name_vector (cc_ccache_t in_ccache, cc_string_t *out_name) { cc_int32 err = ccNoError; cci_swap_ccache_functions (in_ccache); err = ccapi_ccache_get_name (in_ccache, out_name); cci_swap_ccache_functions (in_ccache); return err; } /* ------------------------------------------------------------------------ */ cc_int32 __cc_ccache_get_principal_vector (cc_ccache_t in_ccache, cc_uint32 in_credentials_version, cc_string_t *out_principal) { cc_int32 err = ccNoError; cci_swap_ccache_functions (in_ccache); err = ccapi_ccache_get_principal (in_ccache, in_credentials_version, out_principal); cci_swap_ccache_functions (in_ccache); return err; } /* ------------------------------------------------------------------------ */ cc_int32 __cc_ccache_set_principal_vector (cc_ccache_t io_ccache, cc_uint32 in_credentials_version, const char *in_principal) { cc_int32 err = ccNoError; cci_swap_ccache_functions (io_ccache); err = ccapi_ccache_set_principal (io_ccache, in_credentials_version, in_principal); cci_swap_ccache_functions (io_ccache); return err; } /* ------------------------------------------------------------------------ */ cc_int32 __cc_ccache_store_credentials_vector (cc_ccache_t io_ccache, const cc_credentials_union *in_credentials_union) { cc_int32 err = ccNoError; cci_swap_ccache_functions (io_ccache); err = ccapi_ccache_store_credentials (io_ccache, in_credentials_union); cci_swap_ccache_functions (io_ccache); return err; } /* ------------------------------------------------------------------------ */ cc_int32 __cc_ccache_remove_credentials_vector (cc_ccache_t io_ccache, cc_credentials_t in_credentials) { cc_int32 err = ccNoError; cci_swap_ccache_functions (io_ccache); cci_swap_credentials_functions (in_credentials); err = ccapi_ccache_remove_credentials (io_ccache, in_credentials); cci_swap_ccache_functions (io_ccache); cci_swap_credentials_functions (in_credentials); return err; } /* ------------------------------------------------------------------------ */ cc_int32 __cc_ccache_new_credentials_iterator_vector (cc_ccache_t in_ccache, cc_credentials_iterator_t *out_credentials_iterator) { cc_int32 err = ccNoError; cci_swap_ccache_functions (in_ccache); err = ccapi_ccache_new_credentials_iterator (in_ccache, out_credentials_iterator); cci_swap_ccache_functions (in_ccache); return err; } /* ------------------------------------------------------------------------ */ cc_int32 __cc_ccache_move_vector (cc_ccache_t io_source_ccache, cc_ccache_t io_destination_ccache) { cc_int32 err = ccNoError; cci_swap_ccache_functions (io_source_ccache); cci_swap_ccache_functions (io_destination_ccache); err = ccapi_ccache_move (io_source_ccache, io_destination_ccache); cci_swap_ccache_functions (io_source_ccache); cci_swap_ccache_functions (io_destination_ccache); return err; } /* ------------------------------------------------------------------------ */ cc_int32 __cc_ccache_lock_vector (cc_ccache_t io_ccache, cc_uint32 in_lock_type, cc_uint32 in_block) { cc_int32 err = ccNoError; cci_swap_ccache_functions (io_ccache); err = ccapi_ccache_lock (io_ccache, in_lock_type, in_block); cci_swap_ccache_functions (io_ccache); return err; } /* ------------------------------------------------------------------------ */ cc_int32 __cc_ccache_unlock_vector (cc_ccache_t io_ccache) { cc_int32 err = ccNoError; cci_swap_ccache_functions (io_ccache); err = ccapi_ccache_unlock (io_ccache); cci_swap_ccache_functions (io_ccache); return err; } /* ------------------------------------------------------------------------ */ cc_int32 __cc_ccache_get_last_default_time_vector (cc_ccache_t in_ccache, cc_time_t *out_last_default_time) { cc_int32 err = ccNoError; cci_swap_ccache_functions (in_ccache); err = ccapi_ccache_get_last_default_time (in_ccache, out_last_default_time); cci_swap_ccache_functions (in_ccache); return err; } /* ------------------------------------------------------------------------ */ cc_int32 __cc_ccache_get_change_time_vector (cc_ccache_t in_ccache, cc_time_t *out_change_time) { cc_int32 err = ccNoError; cci_swap_ccache_functions (in_ccache); err = ccapi_ccache_get_change_time (in_ccache, out_change_time); cci_swap_ccache_functions (in_ccache); return err; } /* ------------------------------------------------------------------------ */ cc_int32 __cc_ccache_compare_vector (cc_ccache_t in_ccache, cc_ccache_t in_compare_to_ccache, cc_uint32 *out_equal) { cc_int32 err = ccNoError; cci_swap_ccache_functions (in_ccache); cci_swap_ccache_functions (in_compare_to_ccache); err = ccapi_ccache_compare (in_ccache, in_compare_to_ccache, out_equal); cci_swap_ccache_functions (in_ccache); cci_swap_ccache_functions (in_compare_to_ccache); return err; } #pragma mark - /* ------------------------------------------------------------------------ */ cc_int32 __cc_credentials_release_vector (cc_credentials_t io_credentials) { cci_swap_credentials_functions (io_credentials); return ccapi_credentials_release (io_credentials); } /* ------------------------------------------------------------------------ */ cc_int32 __cc_credentials_compare_vector (cc_credentials_t in_credentials, cc_credentials_t in_compare_to_credentials, cc_uint32 *out_equal) { cc_int32 err = ccNoError; cci_swap_credentials_functions (in_credentials); cci_swap_credentials_functions (in_compare_to_credentials); err = ccapi_credentials_compare (in_credentials, in_compare_to_credentials, out_equal); cci_swap_credentials_functions (in_credentials); cci_swap_credentials_functions (in_compare_to_credentials); return err; } #pragma mark - /* ------------------------------------------------------------------------ */ cc_int32 __cc_ccache_iterator_release_vector (cc_ccache_iterator_t io_ccache_iterator) { cci_swap_ccache_iterator_functions (io_ccache_iterator); return ccapi_ccache_iterator_release (io_ccache_iterator); } /* ------------------------------------------------------------------------ */ cc_int32 __cc_ccache_iterator_next_vector (cc_ccache_iterator_t in_ccache_iterator, cc_ccache_t *out_ccache) { cc_int32 err = ccNoError; cci_swap_ccache_iterator_functions (in_ccache_iterator); err = ccapi_ccache_iterator_next (in_ccache_iterator, out_ccache); cci_swap_ccache_iterator_functions (in_ccache_iterator); return err; } #pragma mark - /* ------------------------------------------------------------------------ */ cc_int32 __cc_credentials_iterator_release_vector (cc_credentials_iterator_t io_credentials_iterator) { cci_swap_credentials_iterator_functions (io_credentials_iterator); return ccapi_credentials_iterator_release (io_credentials_iterator); } /* ------------------------------------------------------------------------ */ cc_int32 __cc_credentials_iterator_next_vector (cc_credentials_iterator_t in_credentials_iterator, cc_credentials_t *out_credentials) { cc_int32 err = ccNoError; cci_swap_credentials_iterator_functions (in_credentials_iterator); err = ccapi_credentials_iterator_next (in_credentials_iterator, out_credentials); cci_swap_credentials_iterator_functions (in_credentials_iterator); return err; } #pragma mark - /* ------------------------------------------------------------------------ */ cc_int32 __cc_shutdown_vector (apiCB **io_context) { cci_swap_context_functions (*io_context); return cc_shutdown (io_context); } /* ------------------------------------------------------------------------ */ cc_int32 __cc_get_NC_info_vector (apiCB *in_context, infoNC ***out_info) { cc_int32 err = ccNoError; cci_swap_context_functions (in_context); err = cc_get_NC_info (in_context, out_info); cci_swap_context_functions (in_context); return err; } /* ------------------------------------------------------------------------ */ cc_int32 __cc_get_change_time_vector (apiCB *in_context, cc_time_t *out_change_time) { cc_int32 err = ccNoError; cci_swap_context_functions (in_context); err = cc_get_change_time (in_context, out_change_time); cci_swap_context_functions (in_context); return err; } /* ------------------------------------------------------------------------ */ cc_int32 __cc_open_vector (apiCB *in_context, const char *in_name, cc_int32 in_version, cc_uint32 in_flags, ccache_p **out_ccache) { cc_int32 err = ccNoError; cci_swap_context_functions (in_context); err = cc_open (in_context, in_name, in_version, in_flags, out_ccache); cci_swap_context_functions (in_context); return err; } /* ------------------------------------------------------------------------ */ cc_int32 __cc_create_vector (apiCB *in_context, const char *in_name, const char *in_principal, cc_int32 in_version, cc_uint32 in_flags, ccache_p **out_ccache) { cc_int32 err = ccNoError; cci_swap_context_functions (in_context); err = cc_create (in_context, in_name, in_principal, in_version, in_flags, out_ccache); cci_swap_context_functions (in_context); return err; } /* ------------------------------------------------------------------------ */ cc_int32 __cc_close_vector (apiCB *in_context, ccache_p **io_ccache) { cc_int32 err = ccNoError; cci_swap_context_functions (in_context); cci_swap_ccache_functions (*io_ccache); err = cc_close (in_context, io_ccache); cci_swap_context_functions (in_context); return err; } /* ------------------------------------------------------------------------ */ cc_int32 __cc_destroy_vector (apiCB *in_context, ccache_p **io_ccache) { cc_int32 err = ccNoError; cci_swap_context_functions (in_context); cci_swap_ccache_functions (*io_ccache); err = cc_destroy (in_context, io_ccache); cci_swap_context_functions (in_context); return err; } /* ------------------------------------------------------------------------ */ cc_int32 __cc_seq_fetch_NCs_begin_vector (apiCB *in_context, ccache_cit **out_iterator) { cc_int32 err = ccNoError; cci_swap_context_functions (in_context); err = cc_seq_fetch_NCs_begin (in_context, out_iterator); cci_swap_context_functions (in_context); return err; } /* ------------------------------------------------------------------------ */ cc_int32 __cc_seq_fetch_NCs_next_vector (apiCB *in_context, ccache_p **out_ccache, ccache_cit *in_iterator) { cc_int32 err = ccNoError; cci_swap_context_functions (in_context); cci_swap_ccache_iterator_functions ((ccache_cit_ccache *)in_iterator); err = cc_seq_fetch_NCs_next (in_context, out_ccache, in_iterator); cci_swap_context_functions (in_context); cci_swap_ccache_iterator_functions ((ccache_cit_ccache *)in_iterator); return err; } /* ------------------------------------------------------------------------ */ cc_int32 __cc_seq_fetch_NCs_end_vector (apiCB *in_context, ccache_cit **io_iterator) { cc_int32 err = ccNoError; cci_swap_context_functions (in_context); cci_swap_ccache_iterator_functions ((ccache_cit_ccache *) *io_iterator); err = cc_seq_fetch_NCs_end (in_context, io_iterator); cci_swap_context_functions (in_context); return err; } /* ------------------------------------------------------------------------ */ cc_int32 __cc_get_name_vector (apiCB *in_context, ccache_p *in_ccache, char **out_name) { cc_int32 err = ccNoError; cci_swap_context_functions (in_context); cci_swap_ccache_functions (in_ccache); err = cc_get_name (in_context, in_ccache, out_name); cci_swap_context_functions (in_context); cci_swap_ccache_functions (in_ccache); return err; } /* ------------------------------------------------------------------------ */ cc_int32 __cc_get_cred_version_vector (apiCB *in_context, ccache_p *in_ccache, cc_int32 *out_version) { cc_int32 err = ccNoError; cci_swap_context_functions (in_context); cci_swap_ccache_functions (in_ccache); err = cc_get_cred_version (in_context, in_ccache, out_version); cci_swap_context_functions (in_context); cci_swap_ccache_functions (in_ccache); return err; } /* ------------------------------------------------------------------------ */ cc_int32 __cc_set_principal_vector (apiCB *in_context, ccache_p *io_ccache, cc_int32 in_version, char *in_principal) { cc_int32 err = ccNoError; cci_swap_context_functions (in_context); cci_swap_ccache_functions (io_ccache); err = cc_set_principal (in_context, io_ccache, in_version, in_principal); cci_swap_context_functions (in_context); cci_swap_ccache_functions (io_ccache); return err; } /* ------------------------------------------------------------------------ */ cc_int32 __cc_get_principal_vector (apiCB *in_context, ccache_p *in_ccache, char **out_principal) { cc_int32 err = ccNoError; cci_swap_context_functions (in_context); cci_swap_ccache_functions (in_ccache); err = cc_get_principal (in_context, in_ccache, out_principal); cci_swap_context_functions (in_context); cci_swap_ccache_functions (in_ccache); return err; } /* ------------------------------------------------------------------------ */ cc_int32 __cc_store_vector (apiCB *in_context, ccache_p *io_ccache, cred_union in_credentials) { cc_int32 err = ccNoError; cci_swap_context_functions (in_context); cci_swap_ccache_functions (io_ccache); err = cc_store (in_context, io_ccache, in_credentials); cci_swap_context_functions (in_context); cci_swap_ccache_functions (io_ccache); return err; } /* ------------------------------------------------------------------------ */ cc_int32 __cc_remove_cred_vector (apiCB *in_context, ccache_p *in_ccache, cred_union in_credentials) { cc_int32 err = ccNoError; cci_swap_context_functions (in_context); cci_swap_ccache_functions (in_ccache); err = cc_remove_cred (in_context, in_ccache, in_credentials); cci_swap_context_functions (in_context); cci_swap_ccache_functions (in_ccache); return err; } /* ------------------------------------------------------------------------ */ cc_int32 __cc_seq_fetch_creds_begin_vector (apiCB *in_context, const ccache_p *in_ccache, ccache_cit **out_iterator) { cc_int32 err = ccNoError; cci_swap_context_functions (in_context); cci_swap_ccache_functions ((ccache_p *)in_ccache); err = cc_seq_fetch_creds_begin (in_context, in_ccache, out_iterator); cci_swap_context_functions (in_context); cci_swap_ccache_functions ((ccache_p *)in_ccache); return err; } /* ------------------------------------------------------------------------ */ cc_int32 __cc_seq_fetch_creds_next_vector (apiCB *in_context, cred_union **out_creds, ccache_cit *in_iterator) { cc_int32 err = ccNoError; cci_swap_context_functions (in_context); cci_swap_credentials_iterator_functions ((ccache_cit_creds *)in_iterator); err = cc_seq_fetch_creds_next (in_context, out_creds, in_iterator); cci_swap_context_functions (in_context); cci_swap_credentials_iterator_functions ((ccache_cit_creds *)in_iterator); return err; } /* ------------------------------------------------------------------------ */ cc_int32 __cc_seq_fetch_creds_end_vector (apiCB *in_context, ccache_cit **io_iterator) { cc_int32 err = ccNoError; cci_swap_context_functions (in_context); cci_swap_credentials_iterator_functions ((ccache_cit_creds *) *io_iterator); err = cc_seq_fetch_creds_end (in_context, io_iterator); cci_swap_context_functions (in_context); return err; } /* ------------------------------------------------------------------------ */ cc_int32 __cc_free_principal_vector (apiCB *in_context, char **io_principal) { cc_int32 err = ccNoError; cci_swap_context_functions (in_context); err = cc_free_principal (in_context, io_principal); cci_swap_context_functions (in_context); return err; } /* ------------------------------------------------------------------------ */ cc_int32 __cc_free_name_vector (apiCB *in_context, char **io_name) { cc_int32 err = ccNoError; cci_swap_context_functions (in_context); err = cc_free_name (in_context, io_name); cci_swap_context_functions (in_context); return err; } /* ------------------------------------------------------------------------ */ cc_int32 __cc_free_creds_vector (apiCB *in_context, cred_union **io_credentials) { cc_int32 err = ccNoError; cci_swap_context_functions (in_context); err = cc_free_creds (in_context, io_credentials); cci_swap_context_functions (in_context); return err; } /* ------------------------------------------------------------------------ */ cc_int32 __cc_free_NC_info_vector (apiCB *in_context, infoNC ***io_info) { cc_int32 err = ccNoError; cci_swap_context_functions (in_context); err = cc_free_NC_info (in_context, io_info); cci_swap_context_functions (in_context); return err; } krb5-1.16/src/ccapi/lib/mac/ccapi_vector.h0000644000704600001450000002506613211554426020175 0ustar ghudsonlibuuid/* ccapi/lib/mac/ccapi_vector.h */ /* * Copyright 2006 Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #include cc_int32 __cc_initialize_vector (cc_context_t *out_context, cc_int32 in_version, cc_int32 *out_supported_version, char const **out_vendor); cc_int32 __cc_string_release_vector (cc_string_t in_string); cc_int32 __cc_context_release_vector (cc_context_t io_context); cc_int32 __cc_context_get_change_time_vector (cc_context_t in_context, cc_time_t *out_change_time); cc_int32 __cc_context_get_default_ccache_name_vector (cc_context_t in_context, cc_string_t *out_name); cc_int32 __cc_context_open_ccache_vector (cc_context_t in_context, const char *in_name, cc_ccache_t *out_ccache); cc_int32 __cc_context_open_default_ccache_vector (cc_context_t in_context, cc_ccache_t *out_ccache); cc_int32 __cc_context_create_ccache_vector (cc_context_t in_context, const char *in_name, cc_uint32 in_cred_vers, const char *in_principal, cc_ccache_t *out_ccache); cc_int32 __cc_context_create_default_ccache_vector (cc_context_t in_context, cc_uint32 in_cred_vers, const char *in_principal, cc_ccache_t *out_ccache); cc_int32 __cc_context_create_new_ccache_vector (cc_context_t in_context, cc_uint32 in_cred_vers, const char *in_principal, cc_ccache_t *out_ccache); cc_int32 __cc_context_new_ccache_iterator_vector (cc_context_t in_context, cc_ccache_iterator_t *out_iterator); cc_int32 __cc_context_lock_vector (cc_context_t in_context, cc_uint32 in_lock_type, cc_uint32 in_block); cc_int32 __cc_context_unlock_vector (cc_context_t in_context); cc_int32 __cc_context_compare_vector (cc_context_t in_context, cc_context_t in_compare_to_context, cc_uint32 *out_equal); cc_int32 __cc_ccache_release_vector (cc_ccache_t io_ccache); cc_int32 __cc_ccache_destroy_vector (cc_ccache_t io_ccache); cc_int32 __cc_ccache_set_default_vector (cc_ccache_t io_ccache); cc_uint32 __cc_ccache_get_credentials_version_vector (cc_ccache_t in_ccache, cc_uint32 *out_credentials_version); cc_int32 __cc_ccache_get_name_vector (cc_ccache_t in_ccache, cc_string_t *out_name); cc_int32 __cc_ccache_get_principal_vector (cc_ccache_t in_ccache, cc_uint32 in_credentials_version, cc_string_t *out_principal); cc_int32 __cc_ccache_set_principal_vector (cc_ccache_t io_ccache, cc_uint32 in_credentials_version, const char *in_principal); cc_int32 __cc_ccache_store_credentials_vector (cc_ccache_t io_ccache, const cc_credentials_union *in_credentials_union); cc_int32 __cc_ccache_remove_credentials_vector (cc_ccache_t io_ccache, cc_credentials_t in_credentials); cc_int32 __cc_ccache_new_credentials_iterator_vector (cc_ccache_t in_ccache, cc_credentials_iterator_t *out_credentials_iterator); cc_int32 __cc_ccache_move_vector (cc_ccache_t io_source_ccache, cc_ccache_t io_destination_ccache); cc_int32 __cc_ccache_lock_vector (cc_ccache_t io_ccache, cc_uint32 in_lock_type, cc_uint32 in_block); cc_int32 __cc_ccache_unlock_vector (cc_ccache_t io_ccache); cc_int32 __cc_ccache_get_last_default_time_vector (cc_ccache_t in_ccache, cc_time_t *out_last_default_time); cc_int32 __cc_ccache_get_change_time_vector (cc_ccache_t in_ccache, cc_time_t *out_change_time); cc_int32 __cc_ccache_compare_vector (cc_ccache_t in_ccache, cc_ccache_t in_compare_to_ccache, cc_uint32 *out_equal); cc_int32 __cc_credentials_release_vector (cc_credentials_t io_credentials); cc_int32 __cc_credentials_compare_vector (cc_credentials_t in_credentials, cc_credentials_t in_compare_to_credentials, cc_uint32 *out_equal); cc_int32 __cc_ccache_iterator_release_vector (cc_ccache_iterator_t io_ccache_iterator); cc_int32 __cc_ccache_iterator_next_vector (cc_ccache_iterator_t in_ccache_iterator, cc_ccache_t *out_ccache); cc_int32 __cc_credentials_iterator_release_vector (cc_credentials_iterator_t io_credentials_iterator); cc_int32 __cc_credentials_iterator_next_vector (cc_credentials_iterator_t in_credentials_iterator, cc_credentials_t *out_credentials); cc_int32 __cc_shutdown_vector (apiCB **io_context); cc_int32 __cc_get_NC_info_vector (apiCB *in_context, infoNC ***out_info); cc_int32 __cc_get_change_time_vector (apiCB *in_context, cc_time_t *out_change_time); cc_int32 __cc_open_vector (apiCB *in_context, const char *in_name, cc_int32 in_version, cc_uint32 in_flags, ccache_p **out_ccache); cc_int32 __cc_create_vector (apiCB *in_context, const char *in_name, const char *in_principal, cc_int32 in_version, cc_uint32 in_flags, ccache_p **out_ccache); cc_int32 __cc_close_vector (apiCB *in_context, ccache_p **io_ccache); cc_int32 __cc_destroy_vector (apiCB *in_context, ccache_p **io_ccache); cc_int32 __cc_seq_fetch_NCs_begin_vector (apiCB *in_context, ccache_cit **out_iterator); cc_int32 __cc_seq_fetch_NCs_next_vector (apiCB *in_context, ccache_p **out_ccache, ccache_cit *in_iterator); cc_int32 __cc_seq_fetch_NCs_end_vector (apiCB *in_context, ccache_cit **io_iterator); cc_int32 __cc_get_name_vector (apiCB *in_context, ccache_p *in_ccache, char **out_name); cc_int32 __cc_get_cred_version_vector (apiCB *in_context, ccache_p *in_ccache, cc_int32 *out_version); cc_int32 __cc_set_principal_vector (apiCB *in_context, ccache_p *io_ccache, cc_int32 in_version, char *in_principal); cc_int32 __cc_get_principal_vector (apiCB *in_context, ccache_p *in_ccache, char **out_principal); cc_int32 __cc_store_vector (apiCB *in_context, ccache_p *io_ccache, cred_union in_credentials); cc_int32 __cc_remove_cred_vector (apiCB *in_context, ccache_p *in_ccache, cred_union in_credentials); cc_int32 __cc_seq_fetch_creds_begin_vector (apiCB *in_context, const ccache_p *in_ccache, ccache_cit **out_iterator); cc_int32 __cc_seq_fetch_creds_next_vector (apiCB *in_context, cred_union **out_creds, ccache_cit *in_iterator); cc_int32 __cc_seq_fetch_creds_end_vector (apiCB *in_context, ccache_cit **io_iterator); cc_int32 __cc_free_principal_vector (apiCB *in_context, char **io_principal); cc_int32 __cc_free_name_vector (apiCB *in_context, char **io_name); cc_int32 __cc_free_creds_vector (apiCB *in_context, cred_union **io_credentials); cc_int32 __cc_free_NC_info_vector (apiCB *in_context, infoNC ***io_info); krb5-1.16/src/ccapi/lib/mac/ccapi_os_ipc.c0000644000704600001450000000403413211554426020132 0ustar ghudsonlibuuid/* ccapi/lib/mac/ccapi_os_ipc.c */ /* * Copyright 2006 Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #include "ccapi_os_ipc.h" #include "k5_mig_client.h" #define cci_server_bundle_id "edu.mit.Kerberos.CCacheServer" /* ------------------------------------------------------------------------ */ cc_int32 cci_os_ipc_thread_init (void) { /* k5_ipc_send_request handles all thread data for us */ return 0; } /* ------------------------------------------------------------------------ */ cc_int32 cci_os_ipc (cc_int32 in_launch_server, k5_ipc_stream in_request_stream, k5_ipc_stream *out_reply_stream) { return cci_check_error (k5_ipc_send_request (cci_server_bundle_id, in_launch_server, in_request_stream, out_reply_stream)); } krb5-1.16/src/ccapi/lib/ccapi_os_ipc.h0000644000704600001450000000305613211554426017402 0ustar ghudsonlibuuid/* ccapi/lib/ccapi_os_ipc.h */ /* * Copyright 2006 Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #ifndef CCAPI_OS_IPC_H #define CCAPI_OS_IPC_H #include "cci_common.h" cc_int32 cci_os_ipc_process_init (void); cc_int32 cci_os_ipc_thread_init (void); cc_int32 cci_os_ipc (cc_int32 in_launch_server, k5_ipc_stream in_request_stream, k5_ipc_stream *out_reply_stream); #endif /* CCAPI_OS_IPC_H */ krb5-1.16/src/ccapi/lib/ccapi_credentials.c0000644000704600001450000001255713211554426020424 0ustar ghudsonlibuuid/* ccapi/lib/ccapi_credentials.c */ /* * Copyright 2006 Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #include "ccapi_credentials.h" #include "ccapi_string.h" /* ------------------------------------------------------------------------ */ typedef struct cci_credentials_d { cc_credentials_union *data; cc_credentials_f *functions; #if TARGET_OS_MAC cc_credentials_f *vector_functions; #endif cci_identifier_t identifier; } *cci_credentials_t; /* ------------------------------------------------------------------------ */ struct cci_credentials_d cci_credentials_initializer = { NULL, NULL VECTOR_FUNCTIONS_INITIALIZER, NULL }; cc_credentials_f cci_credentials_f_initializer = { ccapi_credentials_release, ccapi_credentials_compare }; cc_credentials_union cci_credentials_union_initializer = { 0, { NULL } }; /* ------------------------------------------------------------------------ */ cc_int32 cci_credentials_read (cc_credentials_t *out_credentials, k5_ipc_stream in_stream) { cc_int32 err = ccNoError; cci_credentials_t credentials = NULL; if (!out_credentials) { err = cci_check_error (ccErrBadParam); } if (!in_stream ) { err = cci_check_error (ccErrBadParam); } if (!err) { credentials = malloc (sizeof (*credentials)); if (credentials) { *credentials = cci_credentials_initializer; } else { err = cci_check_error (ccErrNoMem); } } if (!err) { credentials->functions = malloc (sizeof (*credentials->functions)); if (credentials->functions) { *credentials->functions = cci_credentials_f_initializer; } else { err = cci_check_error (ccErrNoMem); } } if (!err) { err = cci_identifier_read (&credentials->identifier, in_stream); } if (!err) { err = cci_credentials_union_read (&credentials->data, in_stream); } if (!err) { *out_credentials = (cc_credentials_t) credentials; credentials = NULL; /* take ownership */ } if (credentials) { ccapi_credentials_release ((cc_credentials_t) credentials); } return cci_check_error (err); } /* ------------------------------------------------------------------------ */ cc_int32 cci_credentials_write (cc_credentials_t in_credentials, k5_ipc_stream in_stream) { cc_int32 err = ccNoError; cci_credentials_t credentials = (cci_credentials_t) in_credentials; if (!in_credentials) { err = cci_check_error (ccErrBadParam); } if (!in_stream ) { err = cci_check_error (ccErrBadParam); } if (!err) { err = cci_identifier_write (credentials->identifier, in_stream); } return cci_check_error (err); } /* ------------------------------------------------------------------------ */ cc_int32 ccapi_credentials_compare (cc_credentials_t in_credentials, cc_credentials_t in_compare_to_credentials, cc_uint32 *out_equal) { cc_int32 err = ccNoError; cci_credentials_t credentials = (cci_credentials_t) in_credentials; cci_credentials_t compare_to_credentials = (cci_credentials_t) in_compare_to_credentials; if (!in_credentials ) { err = cci_check_error (ccErrBadParam); } if (!in_compare_to_credentials) { err = cci_check_error (ccErrBadParam); } if (!out_equal ) { err = cci_check_error (ccErrBadParam); } if (!err) { err = cci_identifier_compare (credentials->identifier, compare_to_credentials->identifier, out_equal); } return cci_check_error (err); } /* ------------------------------------------------------------------------ */ cc_int32 ccapi_credentials_release (cc_credentials_t io_credentials) { cc_int32 err = ccNoError; cci_credentials_t credentials = (cci_credentials_t) io_credentials; if (!io_credentials) { err = ccErrBadParam; } if (!err) { cci_credentials_union_release (credentials->data); free ((char *) credentials->functions); cci_identifier_release (credentials->identifier); free (credentials); } return err; } krb5-1.16/src/ccapi/lib/ccapi_string.c0000644000704600001450000000600513211554426017424 0ustar ghudsonlibuuid/* ccapi/lib/ccapi_string.c */ /* * Copyright 2006 Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #include "ccapi_string.h" /* ------------------------------------------------------------------------ */ cc_string_d cci_string_d_initializer = { NULL, NULL VECTOR_FUNCTIONS_INITIALIZER }; cc_string_f cci_string_f_initializer = { ccapi_string_release }; /* ------------------------------------------------------------------------ */ cc_int32 cci_string_new (cc_string_t *out_string, char *in_cstring) { cc_int32 err = ccNoError; cc_string_t string = NULL; if (!out_string) { err = cci_check_error (ccErrBadParam); } if (!in_cstring) { err = cci_check_error (ccErrBadParam); } if (!err) { string = malloc (sizeof (*string)); if (string) { *string = cci_string_d_initializer; } else { err = cci_check_error (ccErrNoMem); } } if (!err) { string->functions = malloc (sizeof (*string->functions)); if (string->functions) { *((cc_string_f *) string->functions) = cci_string_f_initializer; } else { err = cci_check_error (ccErrNoMem); } } if (!err) { string->data = strdup (in_cstring); if (!string->data) { err = cci_check_error (ccErrNoMem); } } if (!err) { *out_string = string; string = NULL; /* take ownership */ } if (string) { ccapi_string_release (string); } return cci_check_error (err); } /* ------------------------------------------------------------------------ */ cc_int32 ccapi_string_release (cc_string_t in_string) { cc_int32 err = ccNoError; if (!in_string) { err = ccErrBadParam; } if (!err) { free ((char *) in_string->data); free ((char *) in_string->functions); free (in_string); } return err; } krb5-1.16/src/ccapi/lib/ccapi_v2.c0000644000704600001450000006351213211554426016453 0ustar ghudsonlibuuid/* ccapi/lib/ccapi_v2.c */ /* * Copyright 2006 Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #include "cci_common.h" #include "ccapi_string.h" #include "ccapi_context.h" #include "ccapi_ccache.h" #include "ccapi_ccache_iterator.h" #include "ccapi_credentials.h" #include "ccapi_credentials_iterator.h" #include infoNC infoNC_initializer = { NULL, NULL, CC_CRED_UNKNOWN }; /* ------------------------------------------------------------------------ */ static cc_int32 cci_remap_version (cc_int32 in_v2_version, cc_uint32 *out_v3_version) { cc_result err = ccNoError; if (!out_v3_version) { err = cci_check_error (ccErrBadParam); } if (!err) { if (in_v2_version == CC_CRED_V4) { *out_v3_version = cc_credentials_v4; } else if (in_v2_version == CC_CRED_V5) { *out_v3_version = cc_credentials_v5; } else { err = ccErrBadCredentialsVersion; } } return cci_check_error (err); } /* ------------------------------------------------------------------------ */ static cc_result _cci_remap_error (cc_result in_error, const char *in_function, const char *in_file, int in_line) { _cci_check_error (in_error, in_function, in_file, in_line); if (in_error >= CC_NOERROR && in_error <= CC_ERR_CRED_VERSION) { return in_error; } switch (in_error) { case ccNoError: return CC_NOERROR; case ccIteratorEnd: return CC_END; case ccErrBadParam: case ccErrContextNotFound: case ccErrInvalidContext: case ccErrInvalidCredentials: case ccErrInvalidCCacheIterator: case ccErrInvalidCredentialsIterator: case ccErrInvalidLock: case ccErrBadLockType: return CC_BAD_PARM; case ccErrNoMem: return CC_NOMEM; case ccErrInvalidCCache: case ccErrCCacheNotFound: return CC_NO_EXIST; case ccErrCredentialsNotFound: return CC_NOTFOUND; case ccErrBadName: return CC_BADNAME; case ccErrBadCredentialsVersion: return CC_ERR_CRED_VERSION; case ccErrBadAPIVersion: return CC_BAD_API_VERSION; case ccErrContextLocked: case ccErrContextUnlocked: case ccErrCCacheLocked: case ccErrCCacheUnlocked: return CC_LOCKED; case ccErrServerUnavailable: case ccErrServerInsecure: case ccErrServerCantBecomeUID: case ccErrBadInternalMessage: case ccErrClientNotFound: return CC_IO; case ccErrNotImplemented: return CC_NOT_SUPP; default: cci_debug_printf ("%s(): Unhandled error", __FUNCTION__); return CC_BAD_PARM; } } #define cci_remap_error(err) _cci_remap_error(err, __FUNCTION__, __FILE__, __LINE__) #if TARGET_OS_MAC #pragma mark - #endif /* ------------------------------------------------------------------------ */ cc_result cc_shutdown (apiCB **io_context) { cc_result err = ccNoError; if (!io_context) { err = cci_check_error (ccErrBadParam); } if (!err) { err = ccapi_context_release (*io_context); } if (!err) { *io_context = NULL; } return cci_remap_error (err); } /* ------------------------------------------------------------------------ */ cc_result cc_get_change_time (apiCB *in_context, cc_time_t *out_change_time) { cc_result err = ccNoError; if (!in_context ) { err = cci_check_error (ccErrBadParam); } if (!out_change_time) { err = cci_check_error (ccErrBadParam); } if (!err) { err = ccapi_context_get_change_time (in_context, out_change_time); } return cci_remap_error (err); } /* ------------------------------------------------------------------------ */ cc_result cc_get_NC_info (apiCB *in_context, infoNC ***out_info) { cc_result err = CC_NOERROR; infoNC **info = NULL; cc_uint64 count = 0; /* Preflight the size */ cc_uint64 i; if (!in_context) { err = cci_check_error (ccErrBadParam); } if (!out_info ) { err = cci_check_error (ccErrBadParam); } if (!err) { ccache_cit *iterator = NULL; err = cc_seq_fetch_NCs_begin (in_context, &iterator); while (!err) { ccache_p *ccache = NULL; err = cc_seq_fetch_NCs_next (in_context, &ccache, iterator); if (!err) { count++; } if (ccache) { cc_close (in_context, &ccache); } } if (err == CC_END) { err = CC_NOERROR; } if (!err) { err = cc_seq_fetch_NCs_end (in_context, &iterator); } } if (!err) { info = malloc (sizeof (*info) * (count + 1)); if (info) { for (i = 0; i < count + 1; i++) { info[i] = NULL; } } else { err = cci_check_error (CC_NOMEM); } } if (!err) { ccache_cit *iterator = NULL; err = cc_seq_fetch_NCs_begin (in_context, &iterator); for (i = 0; !err && i < count; i++) { ccache_p *ccache = NULL; err = cc_seq_fetch_NCs_next (in_context, &ccache, iterator); if (!err) { info[i] = malloc (sizeof (*info[i])); if (info[i]) { *info[i] = infoNC_initializer; } else { err = cci_check_error (CC_NOMEM); } } if (!err) { err = cc_get_name (in_context, ccache, &info[i]->name); } if (!err) { err = cc_get_principal (in_context, ccache, &info[i]->principal); } if (!err) { err = cc_get_cred_version (in_context, ccache, &info[i]->vers); } if (ccache) { cc_close (in_context, &ccache); } } if (!err) { err = cc_seq_fetch_NCs_end (in_context, &iterator); } } if (!err) { *out_info = info; info = NULL; } if (info) { cc_free_NC_info (in_context, &info); } return cci_check_error (err); } #if TARGET_OS_MAC #pragma mark - #endif /* ------------------------------------------------------------------------ */ cc_int32 cc_open (apiCB *in_context, const char *in_name, cc_int32 in_version, cc_uint32 in_flags, ccache_p **out_ccache) { cc_result err = ccNoError; cc_ccache_t ccache = NULL; cc_uint32 compat_version; cc_uint32 real_version; if (!in_context) { err = cci_check_error (ccErrBadParam); } if (!in_name ) { err = cci_check_error (ccErrBadParam); } if (!out_ccache) { err = cci_check_error (ccErrBadParam); } if (!err) { err = cci_remap_version (in_version, &compat_version); } if (!err) { err = ccapi_context_open_ccache (in_context, in_name, &ccache); } /* We must not allow a CCAPI v2 caller to open a v5-only ccache as a v4 ccache and vice versa. Allowing that would break (valid) assumptions made by CCAPI v2 callers. */ if (!err) { err = ccapi_ccache_get_credentials_version (ccache, &real_version); } if (!err) { /* check the version and set up the ccache to use it */ if (compat_version & real_version) { err = cci_ccache_set_compat_version (ccache, compat_version); } else { err = ccErrBadCredentialsVersion; } } if (!err) { *out_ccache = ccache; ccache = NULL; } if (ccache) { ccapi_ccache_release (ccache); } return cci_remap_error (err); } /* ------------------------------------------------------------------------ */ cc_result cc_create (apiCB *in_context, const char *in_name, const char *in_principal, cc_int32 in_version, cc_uint32 in_flags, ccache_p **out_ccache) { cc_result err = ccNoError; cc_ccache_t ccache = NULL; cc_uint32 compat_version; if (!in_context) { err = cci_check_error (ccErrBadParam); } if (!in_name ) { err = cci_check_error (ccErrBadParam); } if (!out_ccache) { err = cci_check_error (ccErrBadParam); } if (!err) { err = cci_remap_version (in_version, &compat_version); } if (!err) { err = ccapi_context_create_ccache (in_context, in_name, compat_version, in_principal, &ccache); } if (!err) { err = cci_ccache_set_compat_version (ccache, compat_version); } if (!err) { *out_ccache = ccache; ccache = NULL; } if (ccache) { ccapi_ccache_release (ccache); } return cci_remap_error (err); } /* ------------------------------------------------------------------------ */ cc_result cc_close (apiCB *in_context, ccache_p **io_ccache) { cc_result err = ccNoError; if (!in_context) { err = cci_check_error (ccErrBadParam); } if (!io_ccache ) { err = cci_check_error (ccErrBadParam); } if (!err) { err = ccapi_ccache_release (*io_ccache); } if (!err) { *io_ccache = NULL; } return cci_remap_error (err); } /* ------------------------------------------------------------------------ */ cc_result cc_destroy (apiCB *in_context, ccache_p **io_ccache) { cc_result err = ccNoError; if (!in_context) { err = cci_check_error (ccErrBadParam); } if (!io_ccache ) { err = cci_check_error (ccErrBadParam); } if (!err) { err = ccapi_ccache_destroy (*io_ccache); } if (!err) { *io_ccache = NULL; } return cci_remap_error (err); } /* ------------------------------------------------------------------------ */ cc_result cc_get_name (apiCB *in_context, ccache_p *in_ccache, char **out_name) { cc_result err = ccNoError; cc_string_t name = NULL; if (!in_context) { err = cci_check_error (ccErrBadParam); } if (!in_ccache ) { err = cci_check_error (ccErrBadParam); } if (!out_name ) { err = cci_check_error (ccErrBadParam); } if (!err) { err = ccapi_ccache_get_name (in_ccache, &name); } if (!err) { char *string = strdup (name->data); if (string) { *out_name = string; } else { err = cci_check_error (ccErrNoMem); } } if (name) { ccapi_string_release (name); } return cci_remap_error (err); } /* ------------------------------------------------------------------------ */ cc_result cc_get_cred_version (apiCB *in_context, ccache_p *in_ccache, cc_int32 *out_version) { cc_result err = ccNoError; cc_uint32 compat_version; if (!in_context ) { err = cci_check_error (ccErrBadParam); } if (!in_ccache ) { err = cci_check_error (ccErrBadParam); } if (!out_version) { err = cci_check_error (ccErrBadParam); } if (!err) { err = cci_ccache_get_compat_version (in_ccache, &compat_version); } if (!err) { if (compat_version == cc_credentials_v4) { *out_version = CC_CRED_V4; } else if (compat_version == cc_credentials_v5) { *out_version = CC_CRED_V5; } else { err = ccErrBadCredentialsVersion; } } return cci_remap_error (err); } /* ------------------------------------------------------------------------ */ cc_result cc_set_principal (apiCB *in_context, ccache_p *io_ccache, cc_int32 in_version, char *in_principal) { cc_result err = ccNoError; cc_uint32 version; cc_uint32 compat_version; if (!in_context ) { err = cci_check_error (ccErrBadParam); } if (!io_ccache ) { err = cci_check_error (ccErrBadParam); } if (!in_principal) { err = cci_check_error (ccErrBadParam); } if (!err) { err = cci_remap_version (in_version, &version); } if (!err) { err = cci_ccache_get_compat_version (io_ccache, &compat_version); } if (!err && version != compat_version) { err = cci_check_error (ccErrBadCredentialsVersion); } if (!err) { err = ccapi_ccache_set_principal (io_ccache, version, in_principal); } return cci_remap_error (err); } /* ------------------------------------------------------------------------ */ cc_result cc_get_principal (apiCB *in_context, ccache_p *in_ccache, char **out_principal) { cc_result err = ccNoError; cc_uint32 compat_version; cc_string_t principal = NULL; if (!in_context ) { err = cci_check_error (ccErrBadParam); } if (!in_ccache ) { err = cci_check_error (ccErrBadParam); } if (!out_principal) { err = cci_check_error (ccErrBadParam); } if (!err) { err = cci_ccache_get_compat_version (in_ccache, &compat_version); } if (!err) { err = ccapi_ccache_get_principal (in_ccache, compat_version, &principal); } if (!err) { char *string = strdup (principal->data); if (string) { *out_principal = string; } else { err = cci_check_error (ccErrNoMem); } } if (principal) { ccapi_string_release (principal); } return cci_remap_error (err); } /* ------------------------------------------------------------------------ */ cc_result cc_store (apiCB *in_context, ccache_p *io_ccache, cred_union in_credentials) { cc_result err = ccNoError; cc_credentials_union *creds_union = NULL; if (!in_context) { err = cci_check_error (ccErrBadParam); } if (!io_ccache ) { err = cci_check_error (ccErrBadParam); } if (!err) { err = cci_cred_union_to_credentials_union (&in_credentials, &creds_union); } if (!err) { err = ccapi_ccache_store_credentials (io_ccache, creds_union); } if (creds_union) { cci_credentials_union_release (creds_union); } return cci_remap_error (err); } /* ------------------------------------------------------------------------ */ cc_result cc_remove_cred (apiCB *in_context, ccache_p *in_ccache, cred_union in_credentials) { cc_result err = ccNoError; cc_credentials_iterator_t iterator = NULL; cc_uint32 found = 0; if (!in_context) { err = cci_check_error (ccErrBadParam); } if (!in_ccache ) { err = cci_check_error (ccErrBadParam); } if (!err) { err = ccapi_ccache_new_credentials_iterator (in_ccache, &iterator); } while (!err && !found) { cc_credentials_t creds = NULL; err = ccapi_credentials_iterator_next (iterator, &creds); if (!err) { err = cci_cred_union_compare_to_credentials_union (&in_credentials, creds->data, &found); } if (!err && found) { err = ccapi_ccache_remove_credentials (in_ccache, creds); } ccapi_credentials_release (creds); } if (err == ccIteratorEnd) { err = cci_check_error (ccErrCredentialsNotFound); } return cci_remap_error (err); } #if TARGET_OS_MAC #pragma mark - #endif /* ------------------------------------------------------------------------ */ cc_result cc_seq_fetch_NCs_begin (apiCB *in_context, ccache_cit **out_iterator) { cc_result err = ccNoError; cc_ccache_iterator_t iterator = NULL; if (!in_context ) { err = cci_check_error (ccErrBadParam); } if (!out_iterator) { err = cci_check_error (ccErrBadParam); } if (!err) { err = ccapi_context_new_ccache_iterator (in_context, &iterator); } if (!err) { *out_iterator = (ccache_cit *) iterator; iterator = NULL; /* take ownership */ } if (iterator) { ccapi_ccache_iterator_release (iterator); } return cci_remap_error (err); } /* ------------------------------------------------------------------------ */ cc_result cc_seq_fetch_NCs_next (apiCB *in_context, ccache_p **out_ccache, ccache_cit *in_iterator) { cc_result err = ccNoError; cc_ccache_iterator_t iterator = (cc_ccache_iterator_t) in_iterator; cc_ccache_t ccache = NULL; const char *saved_ccache_name; if (!in_context ) { err = cci_check_error (ccErrBadParam); } if (!out_ccache ) { err = cci_check_error (ccErrBadParam); } if (!in_iterator) { err = cci_check_error (ccErrBadParam); } /* CCache iterators need to return some ccaches twice (when v3 ccache has * two kinds of credentials). To do that, we return such ccaches twice * v4 first, then v5. */ if (!err) { err = cci_ccache_iterator_get_saved_ccache_name (iterator, &saved_ccache_name); } if (!err) { if (saved_ccache_name) { err = ccapi_context_open_ccache (in_context, saved_ccache_name, &ccache); if (!err) { err = cci_ccache_set_compat_version (ccache, cc_credentials_v5); } if (!err) { err = cci_ccache_iterator_set_saved_ccache_name (iterator, NULL); } } else { cc_uint32 version = 0; err = ccapi_ccache_iterator_next (iterator, &ccache); if (!err) { err = ccapi_ccache_get_credentials_version (ccache, &version); } if (!err) { if (version == cc_credentials_v4_v5) { cc_string_t name = NULL; err = cci_ccache_set_compat_version (ccache, cc_credentials_v4); if (!err) { err = ccapi_ccache_get_name (ccache, &name); } if (!err) { err = cci_ccache_iterator_set_saved_ccache_name (iterator, name->data); } if (name) { ccapi_string_release (name); } } else { err = cci_ccache_set_compat_version (ccache, version); } } } } if (!err) { *out_ccache = ccache; ccache = NULL; /* take ownership */ } if (ccache) { ccapi_ccache_release (ccache); } return cci_remap_error (err); } /* ------------------------------------------------------------------------ */ cc_result cc_seq_fetch_NCs_end (apiCB *in_context, ccache_cit **io_iterator) { cc_result err = ccNoError; cc_ccache_iterator_t iterator = (cc_ccache_iterator_t) *io_iterator; if (!in_context ) { err = cci_check_error (ccErrBadParam); } if (!io_iterator) { err = cci_check_error (ccErrBadParam); } if (!err) { err = ccapi_ccache_iterator_release (iterator); } if (!err) { *io_iterator = NULL; } return cci_remap_error (err); } #if TARGET_OS_MAC #pragma mark - #endif /* ------------------------------------------------------------------------ */ cc_result cc_seq_fetch_creds_begin (apiCB *in_context, const ccache_p *in_ccache, ccache_cit **out_iterator) { cc_result err = ccNoError; cc_credentials_iterator_t iterator = NULL; cc_uint32 compat_version; if (!in_context ) { err = cci_check_error (ccErrBadParam); } if (!in_ccache ) { err = cci_check_error (ccErrBadParam); } if (!out_iterator) { err = cci_check_error (ccErrBadParam); } if (!err) { err = cci_ccache_get_compat_version ((cc_ccache_t) in_ccache, &compat_version); } if (!err) { err = ccapi_ccache_new_credentials_iterator ((cc_ccache_t) in_ccache, &iterator); } if (!err) { err = cci_credentials_iterator_set_compat_version (iterator, compat_version); } if (!err) { *out_iterator = (ccache_cit *) iterator; iterator = NULL; /* take ownership */ } if (iterator) { ccapi_credentials_iterator_release (iterator); } return cci_remap_error (err); } /* ------------------------------------------------------------------------ */ cc_result cc_seq_fetch_creds_next (apiCB *in_context, cred_union **out_creds, ccache_cit *in_iterator) { cc_result err = ccNoError; cc_credentials_iterator_t iterator = (cc_credentials_iterator_t) in_iterator; cc_uint32 compat_version; if (!in_context ) { err = cci_check_error (ccErrBadParam); } if (!out_creds ) { err = cci_check_error (ccErrBadParam); } if (!in_iterator) { err = cci_check_error (ccErrBadParam); } if (!err) { err = cci_credentials_iterator_get_compat_version (iterator, &compat_version); } while (!err) { cc_credentials_t credentials = NULL; err = ccapi_credentials_iterator_next (iterator, &credentials); if (!err && (credentials->data->version & compat_version)) { /* got the next credentials for the correct version */ err = cci_credentials_union_to_cred_union (credentials->data, out_creds); break; } if (credentials) { ccapi_credentials_release (credentials); } } return cci_remap_error (err); } /* ------------------------------------------------------------------------ */ cc_result cc_seq_fetch_creds_end (apiCB *in_context, ccache_cit **io_iterator) { cc_result err = ccNoError; cc_credentials_iterator_t iterator = (cc_credentials_iterator_t) *io_iterator; if (!in_context ) { err = cci_check_error (ccErrBadParam); } if (!io_iterator) { err = cci_check_error (ccErrBadParam); } if (!err) { err = ccapi_credentials_iterator_release (iterator); } if (!err) { *io_iterator = NULL; } return cci_remap_error (err); } #if TARGET_OS_MAC #pragma mark - #endif /* ------------------------------------------------------------------------ */ cc_result cc_free_principal (apiCB *in_context, char **io_principal) { cc_result err = ccNoError; if (!in_context ) { err = cci_check_error (ccErrBadParam); } if (!io_principal) { err = cci_check_error (ccErrBadParam); } if (!err) { free (*io_principal); *io_principal = NULL; } return cci_remap_error (err); } /* ------------------------------------------------------------------------ */ cc_result cc_free_name (apiCB *in_context, char **io_name) { cc_result err = ccNoError; if (!in_context) { err = cci_check_error (ccErrBadParam); } if (!io_name ) { err = cci_check_error (ccErrBadParam); } if (!err) { free (*io_name); *io_name = NULL; } return cci_remap_error (err); } /* ------------------------------------------------------------------------ */ cc_result cc_free_creds (apiCB *in_context, cred_union **io_credentials) { cc_result err = ccNoError; if (!in_context ) { err = cci_check_error (ccErrBadParam); } if (!io_credentials) { err = cci_check_error (ccErrBadParam); } if (!err) { err = cci_cred_union_release (*io_credentials); if (!err) { *io_credentials = NULL; } } return cci_remap_error (err); } /* ------------------------------------------------------------------------ */ cc_result cc_free_NC_info (apiCB *in_context, infoNC ***io_info) { cc_result err = ccNoError; if (!in_context) { err = cci_check_error (ccErrBadParam); } if (!io_info ) { err = cci_check_error (ccErrBadParam); } if (!err && *io_info) { infoNC **data = *io_info; int i; for (i = 0; data[i] != NULL; i++) { cc_free_principal (in_context, &data[i]->principal); cc_free_name (in_context, &data[i]->name); free (data[i]); } free (data); *io_info = NULL; } return cci_remap_error (err); } krb5-1.16/src/ccapi/lib/deps0000644000704600001450000001333713211554426015477 0ustar ghudsonlibuuid# # Generated makefile dependencies follow. # ccapi_ccache.so ccapi_ccache.po $(OUTPRE)ccapi_ccache.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(COM_ERR_DEPS) $(top_srcdir)/include/CredentialsCache.h \ $(top_srcdir)/include/CredentialsCache2.h $(top_srcdir)/include/k5-ipc_stream.h \ $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-thread.h \ $(srcdir)/../common/cci_common.h $(srcdir)/../common/cci_cred_union.h \ $(srcdir)/../common/cci_debugging.h $(srcdir)/../common/cci_identifier.h \ $(srcdir)/../common/cci_message.h $(srcdir)/../common/cci_types.h \ ccapi_ccache.c ccapi_ccache.h ccapi_credentials.h ccapi_credentials_iterator.h \ ccapi_ipc.h ccapi_string.h ccapi_ccache_iterator.so ccapi_ccache_iterator.po $(OUTPRE)ccapi_ccache_iterator.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(COM_ERR_DEPS) $(top_srcdir)/include/CredentialsCache.h \ $(top_srcdir)/include/CredentialsCache2.h $(top_srcdir)/include/k5-ipc_stream.h \ $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-thread.h \ $(srcdir)/../common/cci_common.h $(srcdir)/../common/cci_cred_union.h \ $(srcdir)/../common/cci_debugging.h $(srcdir)/../common/cci_identifier.h \ $(srcdir)/../common/cci_message.h $(srcdir)/../common/cci_types.h \ ccapi_ccache.h ccapi_ccache_iterator.c ccapi_ccache_iterator.h \ ccapi_ipc.h ccapi_context.so ccapi_context.po $(OUTPRE)ccapi_context.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(COM_ERR_DEPS) $(top_srcdir)/include/CredentialsCache.h \ $(top_srcdir)/include/CredentialsCache2.h $(top_srcdir)/include/k5-ipc_stream.h \ $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-thread.h \ $(srcdir)/../common/cci_common.h $(srcdir)/../common/cci_cred_union.h \ $(srcdir)/../common/cci_debugging.h $(srcdir)/../common/cci_identifier.h \ $(srcdir)/../common/cci_message.h $(srcdir)/../common/cci_types.h \ ccapi_ccache.h ccapi_ccache_iterator.h ccapi_context.c \ ccapi_context.h ccapi_context_change_time.h ccapi_err.h \ ccapi_ipc.h ccapi_string.h ccapi_context_change_time.so ccapi_context_change_time.po \ $(OUTPRE)ccapi_context_change_time.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(COM_ERR_DEPS) $(top_srcdir)/include/CredentialsCache.h \ $(top_srcdir)/include/CredentialsCache2.h $(top_srcdir)/include/k5-ipc_stream.h \ $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-thread.h \ $(srcdir)/../common/cci_common.h $(srcdir)/../common/cci_cred_union.h \ $(srcdir)/../common/cci_debugging.h $(srcdir)/../common/cci_identifier.h \ $(srcdir)/../common/cci_message.h $(srcdir)/../common/cci_types.h \ ccapi_context_change_time.c ccapi_context_change_time.h ccapi_credentials.so ccapi_credentials.po $(OUTPRE)ccapi_credentials.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(COM_ERR_DEPS) $(top_srcdir)/include/CredentialsCache.h \ $(top_srcdir)/include/CredentialsCache2.h $(top_srcdir)/include/k5-ipc_stream.h \ $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-thread.h \ $(srcdir)/../common/cci_common.h $(srcdir)/../common/cci_cred_union.h \ $(srcdir)/../common/cci_debugging.h $(srcdir)/../common/cci_identifier.h \ $(srcdir)/../common/cci_message.h $(srcdir)/../common/cci_types.h \ ccapi_credentials.c ccapi_credentials.h ccapi_string.h ccapi_credentials_iterator.so ccapi_credentials_iterator.po \ $(OUTPRE)ccapi_credentials_iterator.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(COM_ERR_DEPS) $(top_srcdir)/include/CredentialsCache.h \ $(top_srcdir)/include/CredentialsCache2.h $(top_srcdir)/include/k5-ipc_stream.h \ $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-thread.h \ $(srcdir)/../common/cci_common.h $(srcdir)/../common/cci_cred_union.h \ $(srcdir)/../common/cci_debugging.h $(srcdir)/../common/cci_identifier.h \ $(srcdir)/../common/cci_message.h $(srcdir)/../common/cci_types.h \ ccapi_credentials.h ccapi_credentials_iterator.c ccapi_credentials_iterator.h \ ccapi_ipc.h ccapi_err.so ccapi_err.po $(OUTPRE)ccapi_err.$(OBJEXT): \ $(COM_ERR_DEPS) ccapi_err.c ccapi_ipc.so ccapi_ipc.po $(OUTPRE)ccapi_ipc.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(COM_ERR_DEPS) $(top_srcdir)/include/CredentialsCache.h \ $(top_srcdir)/include/CredentialsCache2.h $(top_srcdir)/include/k5-ipc_stream.h \ $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-thread.h \ $(srcdir)/../common/cci_common.h $(srcdir)/../common/cci_cred_union.h \ $(srcdir)/../common/cci_debugging.h $(srcdir)/../common/cci_identifier.h \ $(srcdir)/../common/cci_message.h $(srcdir)/../common/cci_types.h \ ccapi_ipc.c ccapi_ipc.h ccapi_os_ipc.h ccapi_string.so ccapi_string.po $(OUTPRE)ccapi_string.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(COM_ERR_DEPS) $(top_srcdir)/include/CredentialsCache.h \ $(top_srcdir)/include/CredentialsCache2.h $(top_srcdir)/include/k5-ipc_stream.h \ $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-thread.h \ $(srcdir)/../common/cci_common.h $(srcdir)/../common/cci_cred_union.h \ $(srcdir)/../common/cci_debugging.h $(srcdir)/../common/cci_identifier.h \ $(srcdir)/../common/cci_message.h $(srcdir)/../common/cci_types.h \ ccapi_string.c ccapi_string.h ccapi_v2.so ccapi_v2.po $(OUTPRE)ccapi_v2.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(COM_ERR_DEPS) $(top_srcdir)/include/CredentialsCache.h \ $(top_srcdir)/include/CredentialsCache2.h $(top_srcdir)/include/k5-ipc_stream.h \ $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-thread.h \ $(srcdir)/../common/cci_common.h $(srcdir)/../common/cci_cred_union.h \ $(srcdir)/../common/cci_debugging.h $(srcdir)/../common/cci_identifier.h \ $(srcdir)/../common/cci_message.h $(srcdir)/../common/cci_types.h \ ccapi_ccache.h ccapi_ccache_iterator.h ccapi_context.h \ ccapi_credentials.h ccapi_credentials_iterator.h ccapi_string.h \ ccapi_v2.c krb5-1.16/src/ccapi/lib/ccapi_ipc.h0000644000704600001450000000357313211554426016705 0ustar ghudsonlibuuid/* ccapi/lib/ccapi_ipc.h */ /* * Copyright 2006 Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #ifndef CCAPI_IPC_H #define CCAPI_IPC_H #include "cci_common.h" cc_int32 cci_ipc_process_init (void); cc_int32 cci_ipc_thread_init (void); cc_int32 cci_ipc_send (enum cci_msg_id_t in_request_name, cci_identifier_t in_identifier, k5_ipc_stream in_request_data, k5_ipc_stream *out_reply_data); cc_int32 cci_ipc_send_no_launch (enum cci_msg_id_t in_request_name, cci_identifier_t in_identifier, k5_ipc_stream in_request_data, k5_ipc_stream *out_reply_data); #endif /* CCAPI_IPC_H */ krb5-1.16/src/ccapi/lib/ccapi_context.c0000644000704600001450000005705113211554426017611 0ustar ghudsonlibuuid/* ccapi/lib/ccapi_context.c */ /* * Copyright 2006, 2007 Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #include "ccapi_context.h" #include "k5-platform.h" #include "ccapi_ccache.h" #include "ccapi_ccache_iterator.h" #include "ccapi_string.h" #include "ccapi_ipc.h" #include "ccapi_context_change_time.h" #include "ccapi_err.h" #include typedef struct cci_context_d { cc_context_f *functions; #if TARGET_OS_MAC cc_context_f *vector_functions; #endif cci_identifier_t identifier; cc_uint32 synchronized; cc_time_t last_wait_for_change_time; } *cci_context_t; /* ------------------------------------------------------------------------ */ struct cci_context_d cci_context_initializer = { NULL VECTOR_FUNCTIONS_INITIALIZER, NULL, 0, 0 }; cc_context_f cci_context_f_initializer = { ccapi_context_release, ccapi_context_get_change_time, ccapi_context_get_default_ccache_name, ccapi_context_open_ccache, ccapi_context_open_default_ccache, ccapi_context_create_ccache, ccapi_context_create_default_ccache, ccapi_context_create_new_ccache, ccapi_context_new_ccache_iterator, ccapi_context_lock, ccapi_context_unlock, ccapi_context_compare, ccapi_context_wait_for_change }; static cc_int32 cci_context_sync (cci_context_t in_context, cc_uint32 in_launch); #ifdef TARGET_OS_MAC #pragma mark - #endif MAKE_INIT_FUNCTION(cci_process_init); MAKE_FINI_FUNCTION(cci_process_fini); /* ------------------------------------------------------------------------ */ static int cci_process_init (void) { cc_int32 err = ccNoError; if (!err) { err = cci_context_change_time_thread_init (); } if (!err) { err = cci_ipc_process_init (); } if (!err) { add_error_table (&et_CAPI_error_table); } return err; } /* ------------------------------------------------------------------------ */ static void cci_process_fini (void) { if (!INITIALIZER_RAN (cci_process_init) || PROGRAM_EXITING ()) { return; } remove_error_table(&et_CAPI_error_table); cci_context_change_time_thread_fini (); } #ifdef TARGET_OS_MAC #pragma mark - #endif /* ------------------------------------------------------------------------ */ cc_int32 cc_initialize (cc_context_t *out_context, cc_int32 in_version, cc_int32 *out_supported_version, char const **out_vendor) { cc_int32 err = ccNoError; cci_context_t context = NULL; static char *vendor_string = "MIT Kerberos CCAPI"; if (!out_context) { err = cci_check_error (ccErrBadParam); } if (!err) { err = CALL_INIT_FUNCTION (cci_process_init); } if (!err) { switch (in_version) { case ccapi_version_2: case ccapi_version_3: case ccapi_version_4: case ccapi_version_5: case ccapi_version_6: case ccapi_version_7: break; default: err = ccErrBadAPIVersion; break; } } if (!err) { context = malloc (sizeof (*context)); if (context) { *context = cci_context_initializer; } else { err = cci_check_error (ccErrNoMem); } } if (!err) { context->functions = malloc (sizeof (*context->functions)); if (context->functions) { *context->functions = cci_context_f_initializer; } else { err = cci_check_error (ccErrNoMem); } } if (!err) { context->identifier = cci_identifier_uninitialized; *out_context = (cc_context_t) context; context = NULL; /* take ownership */ if (out_supported_version) { *out_supported_version = ccapi_version_max; } if (out_vendor) { *out_vendor = vendor_string; } } ccapi_context_release ((cc_context_t) context); return cci_check_error (err); } #ifdef TARGET_OS_MAC #pragma mark - #endif /* ------------------------------------------------------------------------ */ /* * Currently does not need to talk to the server since the server must * handle cleaning up resources from crashed clients anyway. * * NOTE: if server communication is ever added here, make sure that * krb5_stdcc_shutdown calls an internal function which does not talk to the * server. krb5_stdcc_shutdown is called from thread fini functions and may * crash talking to the server depending on what order the OS calls the fini * functions (ie: if the ipc layer fini function is called first). */ cc_int32 ccapi_context_release (cc_context_t in_context) { cc_int32 err = ccNoError; cci_context_t context = (cci_context_t) in_context; if (!in_context) { err = ccErrBadParam; } if (!err) { cci_identifier_release (context->identifier); free (context->functions); free (context); } return err; } /* ------------------------------------------------------------------------ */ cc_int32 ccapi_context_get_change_time (cc_context_t in_context, cc_time_t *out_change_time) { cc_int32 err = ccNoError; cci_context_t context = (cci_context_t) in_context; k5_ipc_stream reply = NULL; if (!in_context ) { err = cci_check_error (ccErrBadParam); } if (!out_change_time) { err = cci_check_error (ccErrBadParam); } if (!err) { err = cci_context_sync (context, 0); } if (!err) { err = cci_ipc_send_no_launch (cci_context_get_change_time_msg_id, context->identifier, NULL, &reply); } if (!err && krb5int_ipc_stream_size (reply) > 0) { cc_time_t change_time = 0; /* got a response from the server */ err = krb5int_ipc_stream_read_time (reply, &change_time); if (!err) { err = cci_context_change_time_update (context->identifier, change_time); } } if (!err) { err = cci_context_change_time_get (out_change_time); } krb5int_ipc_stream_release (reply); return cci_check_error (err); } /* ------------------------------------------------------------------------ */ cc_int32 ccapi_context_wait_for_change (cc_context_t in_context) { cc_int32 err = ccNoError; cci_context_t context = (cci_context_t) in_context; k5_ipc_stream request = NULL; k5_ipc_stream reply = NULL; if (!in_context) { err = cci_check_error (ccErrBadParam); } if (!err) { err = krb5int_ipc_stream_new (&request); } if (!err) { err = krb5int_ipc_stream_write_time (request, context->last_wait_for_change_time); } if (!err) { err = cci_context_sync (context, 1); } if (!err) { err = cci_ipc_send (cci_context_wait_for_change_msg_id, context->identifier, request, &reply); } if (!err) { err = krb5int_ipc_stream_read_time (reply, &context->last_wait_for_change_time); } krb5int_ipc_stream_release (request); krb5int_ipc_stream_release (reply); return cci_check_error (err); } /* ------------------------------------------------------------------------ */ cc_int32 ccapi_context_get_default_ccache_name (cc_context_t in_context, cc_string_t *out_name) { cc_int32 err = ccNoError; cci_context_t context = (cci_context_t) in_context; k5_ipc_stream reply = NULL; char *reply_name = NULL; char *name = NULL; if (!in_context) { err = cci_check_error (ccErrBadParam); } if (!out_name ) { err = cci_check_error (ccErrBadParam); } if (!err) { err = cci_context_sync (context, 0); } if (!err) { err = cci_ipc_send_no_launch (cci_context_get_default_ccache_name_msg_id, context->identifier, NULL, &reply); } if (!err) { if (krb5int_ipc_stream_size (reply) > 0) { /* got a response from the server */ err = krb5int_ipc_stream_read_string (reply, &reply_name); if (!err) { name = reply_name; } } else { name = k_cci_context_initial_ccache_name; } } if (!err) { err = cci_string_new (out_name, name); } krb5int_ipc_stream_release (reply); krb5int_ipc_stream_free_string (reply_name); return cci_check_error (err); } /* ------------------------------------------------------------------------ */ cc_int32 ccapi_context_open_ccache (cc_context_t in_context, const char *in_name, cc_ccache_t *out_ccache) { cc_int32 err = ccNoError; cci_context_t context = (cci_context_t) in_context; k5_ipc_stream request = NULL; k5_ipc_stream reply = NULL; cci_identifier_t identifier = NULL; if (!in_context ) { err = cci_check_error (ccErrBadParam); } if (!in_name ) { err = cci_check_error (ccErrBadParam); } if (!out_ccache ) { err = cci_check_error (ccErrBadParam); } if (!err) { err = krb5int_ipc_stream_new (&request); } if (!err) { err = krb5int_ipc_stream_write_string (request, in_name); } if (!err) { err = cci_context_sync (context, 0); } if (!err) { err = cci_ipc_send_no_launch (cci_context_open_ccache_msg_id, context->identifier, request, &reply); } if (!err && !(krb5int_ipc_stream_size (reply) > 0)) { err = ccErrCCacheNotFound; } if (!err) { err = cci_identifier_read (&identifier, reply); } if (!err) { err = cci_ccache_new (out_ccache, identifier); } cci_identifier_release (identifier); krb5int_ipc_stream_release (reply); krb5int_ipc_stream_release (request); return cci_check_error (err); } /* ------------------------------------------------------------------------ */ cc_int32 ccapi_context_open_default_ccache (cc_context_t in_context, cc_ccache_t *out_ccache) { cc_int32 err = ccNoError; cci_context_t context = (cci_context_t) in_context; k5_ipc_stream reply = NULL; cci_identifier_t identifier = NULL; if (!in_context) { err = cci_check_error (ccErrBadParam); } if (!out_ccache) { err = cci_check_error (ccErrBadParam); } if (!err) { err = cci_context_sync (context, 0); } if (!err) { err = cci_ipc_send_no_launch (cci_context_open_default_ccache_msg_id, context->identifier, NULL, &reply); } if (!err && !(krb5int_ipc_stream_size (reply) > 0)) { err = ccErrCCacheNotFound; } if (!err) { err = cci_identifier_read (&identifier, reply); } if (!err) { err = cci_ccache_new (out_ccache, identifier); } cci_identifier_release (identifier); krb5int_ipc_stream_release (reply); return cci_check_error (err); } /* ------------------------------------------------------------------------ */ cc_int32 ccapi_context_create_ccache (cc_context_t in_context, const char *in_name, cc_uint32 in_cred_vers, const char *in_principal, cc_ccache_t *out_ccache) { cc_int32 err = ccNoError; cci_context_t context = (cci_context_t) in_context; k5_ipc_stream request = NULL; k5_ipc_stream reply = NULL; cci_identifier_t identifier = NULL; if (!in_context ) { err = cci_check_error (ccErrBadParam); } if (!in_name ) { err = cci_check_error (ccErrBadParam); } if (!in_principal) { err = cci_check_error (ccErrBadParam); } if (!out_ccache ) { err = cci_check_error (ccErrBadParam); } if (!err) { err = krb5int_ipc_stream_new (&request); } if (!err) { err = krb5int_ipc_stream_write_string (request, in_name); } if (!err) { err = krb5int_ipc_stream_write_uint32 (request, in_cred_vers); } if (!err) { err = krb5int_ipc_stream_write_string (request, in_principal); } if (!err) { err = cci_context_sync (context, 1); } if (!err) { err = cci_ipc_send (cci_context_create_ccache_msg_id, context->identifier, request, &reply); } if (!err) { err = cci_identifier_read (&identifier, reply); } if (!err) { err = cci_ccache_new (out_ccache, identifier); } cci_identifier_release (identifier); krb5int_ipc_stream_release (reply); krb5int_ipc_stream_release (request); return cci_check_error (err); } /* ------------------------------------------------------------------------ */ cc_int32 ccapi_context_create_default_ccache (cc_context_t in_context, cc_uint32 in_cred_vers, const char *in_principal, cc_ccache_t *out_ccache) { cc_int32 err = ccNoError; cci_context_t context = (cci_context_t) in_context; k5_ipc_stream request = NULL; k5_ipc_stream reply = NULL; cci_identifier_t identifier = NULL; if (!in_context ) { err = cci_check_error (ccErrBadParam); } if (!in_principal) { err = cci_check_error (ccErrBadParam); } if (!out_ccache ) { err = cci_check_error (ccErrBadParam); } if (!err) { err = krb5int_ipc_stream_new (&request); } if (!err) { err = krb5int_ipc_stream_write_uint32 (request, in_cred_vers); } if (!err) { err = krb5int_ipc_stream_write_string (request, in_principal); } if (!err) { err = cci_context_sync (context, 1); } if (!err) { err = cci_ipc_send (cci_context_create_default_ccache_msg_id, context->identifier, request, &reply); } if (!err) { err = cci_identifier_read (&identifier, reply); } if (!err) { err = cci_ccache_new (out_ccache, identifier); } cci_identifier_release (identifier); krb5int_ipc_stream_release (reply); krb5int_ipc_stream_release (request); return cci_check_error (err); } /* ------------------------------------------------------------------------ */ cc_int32 ccapi_context_create_new_ccache (cc_context_t in_context, cc_uint32 in_cred_vers, const char *in_principal, cc_ccache_t *out_ccache) { cc_int32 err = ccNoError; cci_context_t context = (cci_context_t) in_context; k5_ipc_stream request = NULL; k5_ipc_stream reply = NULL; cci_identifier_t identifier = NULL; if (!in_context ) { err = cci_check_error (ccErrBadParam); } if (!in_principal) { err = cci_check_error (ccErrBadParam); } if (!out_ccache ) { err = cci_check_error (ccErrBadParam); } if (!err) { err = krb5int_ipc_stream_new (&request); } if (!err) { err = krb5int_ipc_stream_write_uint32 (request, in_cred_vers); } if (!err) { err = krb5int_ipc_stream_write_string (request, in_principal); } if (!err) { err = cci_context_sync (context, 1); } if (!err) { err = cci_ipc_send (cci_context_create_new_ccache_msg_id, context->identifier, request, &reply); } if (!err) { err = cci_identifier_read (&identifier, reply); } if (!err) { err = cci_ccache_new (out_ccache, identifier); } cci_identifier_release (identifier); krb5int_ipc_stream_release (reply); krb5int_ipc_stream_release (request); return cci_check_error (err); } /* ------------------------------------------------------------------------ */ cc_int32 ccapi_context_new_ccache_iterator (cc_context_t in_context, cc_ccache_iterator_t *out_iterator) { cc_int32 err = ccNoError; cci_context_t context = (cci_context_t) in_context; k5_ipc_stream reply = NULL; cci_identifier_t identifier = NULL; if (!in_context ) { err = cci_check_error (ccErrBadParam); } if (!out_iterator) { err = cci_check_error (ccErrBadParam); } if (!err) { err = cci_context_sync (context, 0); } if (!err) { err = cci_ipc_send_no_launch (cci_context_new_ccache_iterator_msg_id, context->identifier, NULL, &reply); } if (!err) { if (krb5int_ipc_stream_size (reply) > 0) { err = cci_identifier_read (&identifier, reply); } else { identifier = cci_identifier_uninitialized; } } if (!err) { err = cci_ccache_iterator_new (out_iterator, identifier); } krb5int_ipc_stream_release (reply); cci_identifier_release (identifier); return cci_check_error (err); } /* ------------------------------------------------------------------------ */ cc_int32 ccapi_context_lock (cc_context_t in_context, cc_uint32 in_lock_type, cc_uint32 in_block) { cc_int32 err = ccNoError; cci_context_t context = (cci_context_t) in_context; k5_ipc_stream request = NULL; if (!in_context) { err = cci_check_error (ccErrBadParam); } if (!err) { err = krb5int_ipc_stream_new (&request); } if (!err) { err = krb5int_ipc_stream_write_uint32 (request, in_lock_type); } if (!err) { err = krb5int_ipc_stream_write_uint32 (request, in_block); } if (!err) { err = cci_context_sync (context, 1); } if (!err) { err = cci_ipc_send (cci_context_lock_msg_id, context->identifier, request, NULL); } krb5int_ipc_stream_release (request); return cci_check_error (err); } /* ------------------------------------------------------------------------ */ cc_int32 ccapi_context_unlock (cc_context_t in_context) { cc_int32 err = ccNoError; cci_context_t context = (cci_context_t) in_context; if (!in_context) { err = cci_check_error (ccErrBadParam); } if (!err) { err = cci_context_sync (context, 1); } if (!err) { err = cci_ipc_send (cci_context_unlock_msg_id, context->identifier, NULL, NULL); } return cci_check_error (err); } /* ------------------------------------------------------------------------ */ cc_int32 ccapi_context_compare (cc_context_t in_context, cc_context_t in_compare_to_context, cc_uint32 *out_equal) { cc_int32 err = ccNoError; cci_context_t context = (cci_context_t) in_context; cci_context_t compare_to_context = (cci_context_t) in_compare_to_context; if (!in_context ) { err = cci_check_error (ccErrBadParam); } if (!in_compare_to_context) { err = cci_check_error (ccErrBadParam); } if (!out_equal ) { err = cci_check_error (ccErrBadParam); } if (!err) { err = cci_context_sync (context, 0); } if (!err) { err = cci_context_sync (compare_to_context, 0); } if (!err) { /* If both contexts can't talk to the server, then * we assume they are equivalent */ err = cci_identifier_compare (context->identifier, compare_to_context->identifier, out_equal); } return cci_check_error (err); } #ifdef TARGET_OS_MAC #pragma mark - #endif /* ------------------------------------------------------------------------ */ static cc_int32 cci_context_sync (cci_context_t in_context, cc_uint32 in_launch) { cc_int32 err = ccNoError; cci_context_t context = (cci_context_t) in_context; k5_ipc_stream reply = NULL; cci_identifier_t new_identifier = NULL; if (!in_context) { err = cci_check_error (ccErrBadParam); } if (!err) { /* Use the uninitialized identifier because we may be talking */ /* to a different server which would reject our identifier and */ /* the point of this message is to sync with the server's id */ if (in_launch) { err = cci_ipc_send (cci_context_sync_msg_id, cci_identifier_uninitialized, NULL, &reply); } else { err = cci_ipc_send_no_launch (cci_context_sync_msg_id, cci_identifier_uninitialized, NULL, &reply); } } if (!err) { if (krb5int_ipc_stream_size (reply) > 0) { err = cci_identifier_read (&new_identifier, reply); } else { new_identifier = cci_identifier_uninitialized; } } if (!err) { cc_uint32 equal = 0; err = cci_identifier_compare (context->identifier, new_identifier, &equal); if (!err && !equal) { if (context->identifier) { cci_identifier_release (context->identifier); } context->identifier = new_identifier; new_identifier = NULL; /* take ownership */ } } if (!err && context->synchronized) { err = cci_context_change_time_sync (context->identifier); } if (!err && !context->synchronized) { /* Keep state about whether this is the first call to avoid always */ /* modifying the global change time on the context's first ipc call. */ context->synchronized = 1; } cci_identifier_release (new_identifier); krb5int_ipc_stream_release (reply); return cci_check_error (err); } krb5-1.16/src/ccapi/lib/ccapi_ccache_iterator.c0000644000704600001450000002310313211554426021233 0ustar ghudsonlibuuid/* ccapi/lib/ccapi_ccache_iterator.c */ /* * Copyright 2006 Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #include "ccapi_ccache_iterator.h" #include "ccapi_ccache.h" #include "ccapi_ipc.h" /* ------------------------------------------------------------------------ */ typedef struct cci_ccache_iterator_d { cc_ccache_iterator_f *functions; #if TARGET_OS_MAC cc_ccache_iterator_f *vector_functions; #endif cci_identifier_t identifier; char *saved_ccache_name; } *cci_ccache_iterator_t; /* ------------------------------------------------------------------------ */ struct cci_ccache_iterator_d cci_ccache_iterator_initializer = { NULL VECTOR_FUNCTIONS_INITIALIZER, NULL, NULL }; cc_ccache_iterator_f cci_ccache_iterator_f_initializer = { ccapi_ccache_iterator_release, ccapi_ccache_iterator_next, ccapi_ccache_iterator_clone }; /* ------------------------------------------------------------------------ */ cc_int32 cci_ccache_iterator_new (cc_ccache_iterator_t *out_ccache_iterator, cci_identifier_t in_identifier) { cc_int32 err = ccNoError; cci_ccache_iterator_t ccache_iterator = NULL; if (!in_identifier ) { err = cci_check_error (ccErrBadParam); } if (!out_ccache_iterator) { err = cci_check_error (ccErrBadParam); } if (!err) { ccache_iterator = malloc (sizeof (*ccache_iterator)); if (ccache_iterator) { *ccache_iterator = cci_ccache_iterator_initializer; } else { err = cci_check_error (ccErrNoMem); } } if (!err) { ccache_iterator->functions = malloc (sizeof (*ccache_iterator->functions)); if (ccache_iterator->functions) { *ccache_iterator->functions = cci_ccache_iterator_f_initializer; } else { err = cci_check_error (ccErrNoMem); } } if (!err) { err = cci_identifier_copy (&ccache_iterator->identifier, in_identifier); } if (!err) { *out_ccache_iterator = (cc_ccache_iterator_t) ccache_iterator; ccache_iterator = NULL; /* take ownership */ } ccapi_ccache_iterator_release ((cc_ccache_iterator_t) ccache_iterator); return cci_check_error (err); } /* ------------------------------------------------------------------------ */ cc_int32 cci_ccache_iterator_write (cc_ccache_iterator_t in_ccache_iterator, k5_ipc_stream in_stream) { cc_int32 err = ccNoError; cci_ccache_iterator_t ccache_iterator = (cci_ccache_iterator_t) in_ccache_iterator; if (!in_ccache_iterator) { err = cci_check_error (ccErrBadParam); } if (!in_stream ) { err = cci_check_error (ccErrBadParam); } if (!err) { err = cci_identifier_write (ccache_iterator->identifier, in_stream); } return cci_check_error (err); } /* ------------------------------------------------------------------------ */ cc_int32 ccapi_ccache_iterator_release (cc_ccache_iterator_t io_ccache_iterator) { cc_int32 err = ccNoError; cci_ccache_iterator_t ccache_iterator = (cci_ccache_iterator_t) io_ccache_iterator; if (!io_ccache_iterator) { err = ccErrBadParam; } if (!err) { cc_uint32 initialized = 0; err = cci_identifier_is_initialized (ccache_iterator->identifier, &initialized); if (!err && initialized) { err = cci_ipc_send (cci_ccache_iterator_release_msg_id, ccache_iterator->identifier, NULL, NULL); if (err) { cci_debug_printf ("%s: cci_ipc_send failed with error %d", __FUNCTION__, err); err = ccNoError; } } } if (!err) { free ((char *) ccache_iterator->functions); cci_identifier_release (ccache_iterator->identifier); free (ccache_iterator->saved_ccache_name); free (ccache_iterator); } return err; } /* ------------------------------------------------------------------------ */ cc_int32 ccapi_ccache_iterator_next (cc_ccache_iterator_t in_ccache_iterator, cc_ccache_t *out_ccache) { cc_int32 err = ccNoError; cci_ccache_iterator_t ccache_iterator = (cci_ccache_iterator_t) in_ccache_iterator; k5_ipc_stream reply = NULL; cci_identifier_t identifier = NULL; if (!in_ccache_iterator) { err = cci_check_error (ccErrBadParam); } if (!out_ccache ) { err = cci_check_error (ccErrBadParam); } if (!err) { cc_uint32 initialized = 0; err = cci_identifier_is_initialized (ccache_iterator->identifier, &initialized); if (!err && !initialized) { /* server doesn't actually exist. Pretend we're empty. */ err = cci_check_error (ccIteratorEnd); } } if (!err) { err = cci_ipc_send (cci_ccache_iterator_next_msg_id, ccache_iterator->identifier, NULL, &reply); } if (!err) { err = cci_identifier_read (&identifier, reply); } if (!err) { err = cci_ccache_new (out_ccache, identifier); } krb5int_ipc_stream_release (reply); cci_identifier_release (identifier); return cci_check_error (err); } /* ------------------------------------------------------------------------ */ cc_int32 ccapi_ccache_iterator_clone (cc_ccache_iterator_t in_ccache_iterator, cc_ccache_iterator_t *out_ccache_iterator) { cc_int32 err = ccNoError; cci_ccache_iterator_t ccache_iterator = (cci_ccache_iterator_t) in_ccache_iterator; k5_ipc_stream reply = NULL; cc_uint32 initialized = 0; cci_identifier_t identifier = NULL; if (!in_ccache_iterator ) { err = cci_check_error (ccErrBadParam); } if (!out_ccache_iterator) { err = cci_check_error (ccErrBadParam); } if (!err) { err = cci_identifier_is_initialized (ccache_iterator->identifier, &initialized); } if (!err) { if (initialized) { err = cci_ipc_send (cci_ccache_iterator_next_msg_id, ccache_iterator->identifier, NULL, &reply); if (!err) { err = cci_identifier_read (&identifier, reply); } } else { /* server doesn't actually exist. Make another dummy one. */ identifier = cci_identifier_uninitialized; } } if (!err) { err = cci_ccache_iterator_new (out_ccache_iterator, identifier); } cci_identifier_release (identifier); krb5int_ipc_stream_release (reply); return cci_check_error (err); } /* ------------------------------------------------------------------------ */ cc_int32 cci_ccache_iterator_get_saved_ccache_name (cc_ccache_iterator_t in_ccache_iterator, const char **out_saved_ccache_name) { cc_int32 err = ccNoError; cci_ccache_iterator_t ccache_iterator = (cci_ccache_iterator_t) in_ccache_iterator; if (!in_ccache_iterator ) { err = cci_check_error (ccErrBadParam); } if (!out_saved_ccache_name) { err = cci_check_error (ccErrBadParam); } if (!err) { *out_saved_ccache_name = ccache_iterator->saved_ccache_name; } return cci_check_error (err); } /* ------------------------------------------------------------------------ */ cc_int32 cci_ccache_iterator_set_saved_ccache_name (cc_ccache_iterator_t io_ccache_iterator, const char *in_saved_ccache_name) { cc_int32 err = ccNoError; cci_ccache_iterator_t ccache_iterator = (cci_ccache_iterator_t) io_ccache_iterator; char *new_saved_ccache_name = NULL; if (!io_ccache_iterator) { err = cci_check_error (ccErrBadParam); } if (!err && in_saved_ccache_name) { new_saved_ccache_name = strdup (in_saved_ccache_name); if (!new_saved_ccache_name) { err = ccErrNoMem; } } if (!err) { free (ccache_iterator->saved_ccache_name); ccache_iterator->saved_ccache_name = new_saved_ccache_name; new_saved_ccache_name = NULL; /* take ownership */ } free (new_saved_ccache_name); return cci_check_error (err); } krb5-1.16/src/ccapi/lib/win/0000755000704600001450000000000013211554426015407 5ustar ghudsonlibuuidkrb5-1.16/src/ccapi/lib/win/ccs_reply_proc.c0000644000704600001450000000675113211554426020572 0ustar ghudsonlibuuid/* ccapi/lib/win/ccs_reply_proc.c */ /* * Copyright 2008 Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #include #include #include #include "cci_debugging.h" #include "ccs_reply.h" /* generated by MIDL compiler */ #include "ccutils.h" #include "tls.h" #include "win-utils.h" void ccs_rpc_request_reply( const long rpcmsg, /* Message type */ const char tspHandle[], /* Client's tspdata* */ const char* uuid, /* uuid for making thread-specific event name */ const long srvStartTime, /* Server Start Time */ const long cbIn, /* Length of buffer */ const char* chIn, /* Data buffer */ long* ret_status ) { /* Return code */ HANDLE hEvent = openThreadEvent(uuid, REPLY_SUFFIX); struct tspdata* tsp; k5_ipc_stream stream; long status = 0; #if 0 cci_debug_printf("%s! msg#:%d SST:%ld uuid:%s", __FUNCTION__, rpcmsg, srvStartTime, uuid); #endif memcpy(&tsp, tspHandle, sizeof(tsp)); if (!status) { status = krb5int_ipc_stream_new (&stream); /* Create a stream for the request data */ } if (!status) { /* Put the data into the stream */ status = krb5int_ipc_stream_write (stream, chIn, cbIn); } if (!status) { /* Put the data into the stream */ tspdata_setStream(tsp, stream); } SetEvent(hEvent); CloseHandle(hEvent); *ret_status = status; } void ccs_rpc_connect_reply( const long rpcmsg, /* Message type */ const char tspHandle[], /* Client's tspdata* */ const char* uuid, /* uuid for making thread-specific event name */ const long srvStartTime, /* Server Start Time */ long* status ) { /* Return code */ HANDLE hEvent = openThreadEvent(uuid, REPLY_SUFFIX); DWORD* p = (DWORD*)(tspHandle); #if 0 cci_debug_printf("%s! msg#:%d SST:%ld uuid:%s", __FUNCTION__, rpcmsg, srvStartTime, uuid); #endif SetEvent(hEvent); CloseHandle(hEvent); } void ccapi_listen( RPC_ASYNC_STATE* rpcState, handle_t hBinding, const long rpcmsg, /* Message type */ long* status ) { /* Return code */ cci_debug_printf("%s %s!", __FUNCTION__, rpcState->UserInfo); *status = 0; } krb5-1.16/src/ccapi/lib/win/WINCCAPI.sln0000644000704600001450000000153413211554426017325 0ustar ghudsonlibuuid Microsoft Visual Studio Solution File, Format Version 9.00 # Visual Studio 2005 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "WINCCAPI", "WINCCAPI.vcproj", "{1137FC16-E53E-48C1-8293-085B4BE68C32}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Win32 = Debug|Win32 Release|Win32 = Release|Win32 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {1137FC16-E53E-48C1-8293-085B4BE68C32}.Debug|Win32.ActiveCfg = Debug|Win32 {1137FC16-E53E-48C1-8293-085B4BE68C32}.Debug|Win32.Build.0 = Debug|Win32 {1137FC16-E53E-48C1-8293-085B4BE68C32}.Release|Win32.ActiveCfg = Release|Win32 {1137FC16-E53E-48C1-8293-085B4BE68C32}.Release|Win32.Build.0 = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection EndGlobal krb5-1.16/src/ccapi/lib/win/dllmain.cxx0000644000704600001450000002134213211554426017555 0ustar ghudsonlibuuid/* * $Header$ * * Copyright 2008 Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ extern "C" { #include #include #include "dllmain.h" #include "tls.h" #include "cci_debugging.h" #include "ccapi_context.h" #include "ccapi_ipc.h" #include "client.h" void cci_process_init__auxinit(); } #define CCAPI_V2_MUTEX_NAME TEXT("MIT_CCAPI_V4_MUTEX") // Process-specific data: static DWORD dwTlsIndex; static char _user[UNLEN+1]; // Username is used as part of the server and client endpoints. static HANDLE sessionToken; static char* ep_prefices[] = {"CCS", "CCAPI"}; HANDLE hCCAPIv2Mutex = NULL; DWORD firstThreadID = 0; // These data structures are used by the old CCAPI implementation // to keep track of the state of the RPC connection. All data is static. static Init init; static Client client; DWORD GetTlsIndex() {return dwTlsIndex;} // DllMain() is the entry-point function for this DLL. BOOL WINAPI DllMain(HINSTANCE hinstDLL, // DLL module handle DWORD fdwReason, // reason called LPVOID lpvReserved) { // reserved struct tspdata* ptspdata; BOOL fIgnore; BOOL bStatus; DWORD status = 0; // 0 is success. DWORD maxUN = sizeof(_user); unsigned int i = 0; unsigned int j = 0; switch (fdwReason) { // The DLL is loading due to process initialization or a call to LoadLibrary: case DLL_PROCESS_ATTACH: cci_debug_printf("%s DLL_PROCESS_ATTACH", __FUNCTION__); // Process-wide mutex used to allow only one thread at a time into the RPC code: hCCAPIv2Mutex = CreateMutex(NULL, FALSE, CCAPI_V2_MUTEX_NAME); // Figure out our username; it's process-wide: bStatus = GetUserName(_user, &maxUN); if (!bStatus) return bStatus; // Remove any characters that aren't valid endpoint characters: while (_user[j] != 0) { if (isalnum(_user[j])) _user[i++] = _user[j]; j++; } _user[i] = '\0'; // Our logon session is determined in client.cxx, old CCAPI code carried // over to this implementation. // Allocate a TLS index: if ((dwTlsIndex = TlsAlloc()) == TLS_OUT_OF_INDEXES) return FALSE; cci_process_init__auxinit(); // Don't break; fallthrough: Initialize the TLS index for first thread. // The attached process creates a new thread: case DLL_THREAD_ATTACH: cci_debug_printf("%s DLL_THREAD_ATTACH", __FUNCTION__); // Don't actually rely on this case for allocation of resources. // Applications (like SecureCRT) may have threads already // created (say 'A' and 'B') before the dll is loaded. If the dll // is loaded in thread 'A' but then used in thread 'B', thread 'B' // will never execute this code. fIgnore = TlsSetValue(dwTlsIndex, NULL); // Do not call cci_ipc_thread_init() yet; defer until we actually // need it. On XP, cci_ipc_thread_init() will cause additional // threads to be immediately spawned, which will bring us right // back here again ad infinitum, until windows // resources are exhausted. break; // The thread of the attached process terminates: case DLL_THREAD_DETACH: cci_debug_printf("%s DLL_THREAD_DETACH", __FUNCTION__); // Release the allocated memory for this thread ptspdata = (struct tspdata*)TlsGetValue(dwTlsIndex); if (ptspdata != NULL) { free(ptspdata); TlsSetValue(dwTlsIndex, NULL); } break; // DLL unload due to process termination or FreeLibrary: case DLL_PROCESS_DETACH: cci_debug_printf("%s DLL_PROCESS_DETACH", __FUNCTION__); //++ Copied from previous implementation: // Process Teardown "Problem" // // There are two problems that occur during process teardown: // // 1) Windows (NT/9x/2000) does not keep track of load/unload // ordering dependencies for use in process teardown. // // 2) The RPC exception handling in the RPC calls do not work // during process shutdown in Win9x. // // When a process is being torn down in Windows, the krbcc DLL // may get a DLL_PROCESS_DETACH before other DLLs are done // with it. Thus, it may disconnect from the RPC server // before the last shutdown RPC call. // // On NT/2000, this is ok because the RPC call will fail and just // return an error. // // On Win9x/Me, the RPC exception will not be caught. // However, Win9x ignores exceptions during process shutdown, // so the exception will never be seen unless a debugger is // attached to the proccess. // // A good potential woraround would be to have a global // variable that denotes whether the DLL is attached to the // process. If it is not, all entrypoints into the DLL should // return failure. // // A not as good workaround is below but ifdefed out. // // However, we can safely ignore this problem since it can // only affects people running debuggers under 9x/Me who are // using multiple DLLs that use this DLL. // WaitForSingleObject( hCCAPIv2Mutex, INFINITE ); #if 0 bool process_teardown_workaround = false; if (lpvReserved) { Init::InitInfo info; status = Init::Info(info); if (status) break; if (!info.isNT) process_teardown_workaround = true; } if (process_teardown_workaround) break; #endif // return value is ignored, so we set status for debugging purposes status = Client::Cleanup(); status = Init::Cleanup(); ReleaseMutex( hCCAPIv2Mutex ); CloseHandle( hCCAPIv2Mutex ); //-- Copied from previous implementation. // Release the allocated memory for this thread: ptspdata = (struct tspdata*)TlsGetValue(dwTlsIndex); if (ptspdata != NULL) free(ptspdata); TlsFree(dwTlsIndex); // Release the TLS index. // Ideally, we would enumerate all other threads here and // release their thread local storage as well. break; default: cci_debug_printf("%s unexpected reason %d", __FUNCTION__, fdwReason); break; } UNREFERENCED_PARAMETER(hinstDLL); // no whining! UNREFERENCED_PARAMETER(lpvReserved); return status ? FALSE : TRUE; } #ifdef __cplusplus // If used by C++ code, extern "C" { // we need to export the C interface #endif #ifdef __cplusplus } #endif /*********************************************************************/ /* MIDL allocate and free */ /*********************************************************************/ extern "C" void __RPC_FAR * __RPC_USER MIDL_user_allocate(size_t len) { return(malloc(len)); } extern "C" void __RPC_USER MIDL_user_free(void __RPC_FAR * ptr) { free(ptr); } krb5-1.16/src/ccapi/lib/win/OldCC/0000755000704600001450000000000013211554426016333 5ustar ghudsonlibuuidkrb5-1.16/src/ccapi/lib/win/OldCC/client.h0000644000704600001450000000361413211554426017766 0ustar ghudsonlibuuid/* ccapi/lib/win/OldCC/client.h */ /* * Copyright 2008 Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #ifndef __DLL_CLIENT_H__ #define __DLL_CLIENT_H__ #include "autolock.hxx" #include "init.hxx" class Client { public: static DWORD Initialize(char* ep OPTIONAL); static DWORD Cleanup(); static DWORD Reconnect(char* ep OPTIONAL); static bool Initialized() { return s_init; } static CcOsLock sLock; private: static bool s_init; static DWORD Disconnect(); static DWORD Connect(char* ep OPTIONAL); }; #define CLIENT_INIT_EX(trap, error) \ do \ { \ INIT_INIT_EX(trap, error); \ if (!Client::Initialized()) \ { \ DWORD status = Client::Initialize(0); \ if (status) return (trap) ? (error) : status; \ } \ } while(0) #endif krb5-1.16/src/ccapi/lib/win/OldCC/ccapi.h0000644000704600001450000001435213211554426017570 0ustar ghudsonlibuuid/* this ALWAYS GENERATED file contains the definitions for the interfaces */ /* File created by MIDL compiler version 6.00.0366 */ /* at Fri Nov 30 10:06:16 2007 */ /* Compiler settings for ccapi.idl: Oic, W1, Zp8, env=Win32 (32b run) protocol : dce , ms_ext, c_ext, oldnames error checks: allocation ref bounds_check enum stub_data VC __declspec() decoration level: __declspec(uuid()), __declspec(selectany), __declspec(novtable) DECLSPEC_UUID(), MIDL_INTERFACE() */ //@@MIDL_FILE_HEADING( ) #pragma warning( disable: 4049 ) /* more than 64k source lines */ /* verify that the version is high enough to compile this file*/ #ifndef __REQUIRED_RPCNDR_H_VERSION__ #define __REQUIRED_RPCNDR_H_VERSION__ 440 #endif #include "rpc.h" #include "rpcndr.h" #ifndef __ccapi_h__ #define __ccapi_h__ #if defined(_MSC_VER) && (_MSC_VER >= 1020) #pragma once #endif /* Forward Declarations */ #ifdef __cplusplus extern "C"{ #endif void * __RPC_USER MIDL_user_allocate(size_t); void __RPC_USER MIDL_user_free( void * ); #ifndef __ccapi_INTERFACE_DEFINED__ #define __ccapi_INTERFACE_DEFINED__ /* interface ccapi */ /* [implicit_handle][unique][version][uuid] */ typedef /* [context_handle] */ struct opaque_handle_CTX *HCTX; typedef /* [context_handle] */ struct opaque_handle_CACHE *HCACHE; typedef /* [context_handle] */ struct opaque_handle_CACHE_ITER *HCACHE_ITER; typedef /* [context_handle] */ struct opaque_handle_CRED_ITER *HCRED_ITER; typedef unsigned char CC_CHAR; typedef unsigned char CC_UCHAR; typedef int CC_INT32; typedef unsigned int CC_UINT32; typedef CC_INT32 CC_TIME_T; enum __MIDL_ccapi_0001 { STK_AFS = 0, STK_DES = 1 } ; enum __MIDL_ccapi_0002 { CC_API_VER_1 = 1, CC_API_VER_2 = 2 } ; enum __MIDL_ccapi_0003 { KRB_NAME_SZ = 40, KRB_INSTANCE_SZ = 40, KRB_REALM_SZ = 40, MAX_V4_CRED_LEN = 1250 } ; typedef struct _NC_INFO { /* [string] */ CC_CHAR *name; /* [string] */ CC_CHAR *principal; CC_INT32 vers; } NC_INFO; typedef struct _NC_INFO_LIST { CC_UINT32 length; /* [size_is] */ NC_INFO *info; } NC_INFO_LIST; typedef struct _V4_CRED { CC_UCHAR kversion; CC_CHAR principal[ 41 ]; CC_CHAR principal_instance[ 41 ]; CC_CHAR service[ 41 ]; CC_CHAR service_instance[ 41 ]; CC_CHAR realm[ 41 ]; CC_UCHAR session_key[ 8 ]; CC_INT32 kvno; CC_INT32 str_to_key; CC_INT32 issue_date; CC_INT32 lifetime; CC_UINT32 address; CC_INT32 ticket_sz; CC_UCHAR ticket[ 1250 ]; } V4_CRED; typedef struct _CC_DATA { CC_UINT32 type; CC_UINT32 length; /* [size_is] */ CC_UCHAR *data; } CC_DATA; typedef struct _CC_DATA_LIST { CC_UINT32 count; /* [size_is] */ CC_DATA *data; } CC_DATA_LIST; typedef struct _V5_CRED { /* [string] */ CC_CHAR *client; /* [string] */ CC_CHAR *server; CC_DATA keyblock; CC_TIME_T authtime; CC_TIME_T starttime; CC_TIME_T endtime; CC_TIME_T renew_till; CC_UINT32 is_skey; CC_UINT32 ticket_flags; CC_DATA_LIST addresses; CC_DATA ticket; CC_DATA second_ticket; CC_DATA_LIST authdata; } V5_CRED; typedef /* [switch_type] */ union _CRED_PTR_UNION { /* [case()] */ V4_CRED *pV4Cred; /* [case()] */ V5_CRED *pV5Cred; } CRED_PTR_UNION; typedef struct _CRED_UNION { CC_INT32 cred_type; /* [switch_is] */ CRED_PTR_UNION cred; } CRED_UNION; CC_INT32 rcc_initialize( /* [out] */ HCTX *pctx); CC_INT32 rcc_shutdown( /* [out][in] */ HCTX *pctx); CC_INT32 rcc_get_change_time( /* [in] */ HCTX ctx, /* [out] */ CC_TIME_T *time); CC_INT32 rcc_create( /* [in] */ HCTX ctx, /* [string][in] */ const CC_CHAR *name, /* [string][in] */ const CC_CHAR *principal, /* [in] */ CC_INT32 vers, /* [in] */ CC_UINT32 flags, /* [out] */ HCACHE *pcache); CC_INT32 rcc_open( /* [in] */ HCTX ctx, /* [string][in] */ const CC_CHAR *name, /* [in] */ CC_INT32 vers, /* [in] */ CC_UINT32 flags, /* [out] */ HCACHE *pcache); CC_INT32 rcc_close( /* [out][in] */ HCACHE *pcache); CC_INT32 rcc_destroy( /* [out][in] */ HCACHE *pcache); CC_INT32 rcc_seq_fetch_NCs_begin( /* [in] */ HCTX ctx, /* [out] */ HCACHE_ITER *piter); CC_INT32 rcc_seq_fetch_NCs_end( /* [out][in] */ HCACHE_ITER *piter); CC_INT32 rcc_seq_fetch_NCs_next( /* [in] */ HCACHE_ITER iter, /* [out] */ HCACHE *pcache); CC_INT32 rcc_seq_fetch_NCs( /* [in] */ HCTX ctx, /* [out][in] */ HCACHE_ITER *piter, /* [out] */ HCACHE *pcache); CC_INT32 rcc_get_NC_info( /* [in] */ HCTX ctx, /* [out] */ NC_INFO_LIST **info_list); CC_INT32 rcc_get_name( /* [in] */ HCACHE cache, /* [string][out] */ CC_CHAR **name); CC_INT32 rcc_set_principal( /* [in] */ HCACHE cache, /* [in] */ CC_INT32 vers, /* [string][in] */ const CC_CHAR *principal); CC_INT32 rcc_get_principal( /* [in] */ HCACHE cache, /* [string][out] */ CC_CHAR **principal); CC_INT32 rcc_get_cred_version( /* [in] */ HCACHE cache, /* [out] */ CC_INT32 *vers); CC_INT32 rcc_lock_request( /* [in] */ HCACHE cache, /* [in] */ CC_INT32 lock_type); CC_INT32 rcc_store( /* [in] */ HCACHE cache, /* [in] */ CRED_UNION cred); CC_INT32 rcc_remove_cred( /* [in] */ HCACHE cache, /* [in] */ CRED_UNION cred); CC_INT32 rcc_seq_fetch_creds( /* [in] */ HCACHE cache, /* [out][in] */ HCRED_ITER *piter, /* [out] */ CRED_UNION **cred); CC_INT32 rcc_seq_fetch_creds_begin( /* [in] */ HCACHE cache, /* [out] */ HCRED_ITER *piter); CC_INT32 rcc_seq_fetch_creds_end( /* [out][in] */ HCRED_ITER *piter); CC_INT32 rcc_seq_fetch_creds_next( /* [in] */ HCRED_ITER iter, /* [out] */ CRED_UNION **cred); CC_UINT32 Connect( /* [string][in] */ CC_CHAR *name); void Shutdown( void); extern handle_t ccapi_IfHandle; extern RPC_IF_HANDLE ccapi_ClientIfHandle; extern RPC_IF_HANDLE ccapi_ServerIfHandle; #endif /* __ccapi_INTERFACE_DEFINED__ */ /* Additional Prototypes for ALL interfaces */ void __RPC_USER HCTX_rundown( HCTX ); void __RPC_USER HCACHE_rundown( HCACHE ); void __RPC_USER HCACHE_ITER_rundown( HCACHE_ITER ); void __RPC_USER HCRED_ITER_rundown( HCRED_ITER ); /* end of Additional Prototypes */ #ifdef __cplusplus } #endif #endif krb5-1.16/src/ccapi/lib/win/OldCC/client.cxx0000644000704600001450000003354013211554426020342 0ustar ghudsonlibuuid/* * $Header$ * * Copyright 2008 Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #include "stdio.h" // KPKDBG #include "ccs_request.h" #include "ccapi.h" #include "util.h" extern "C" { #include "cci_debugging.h" #include "tls.h" // KPKDBG } #include "client.h" #include "init.hxx" #include "name.h" #include "secure.hxx" #define SECONDS_TO_WAIT 10 #define STARTUP "CLIENT STARTUP: " #define DISCONNECT "CLIENT DISCONNECT: " bool Client::s_init = false; CcOsLock Client::sLock; static DWORD bind_client(char* ep OPTIONAL, Init::InitInfo& info, LPSTR* endpoint) { DWORD status = 0; unsigned char * pszStringBinding = NULL; if (!ep) { status = alloc_name(endpoint, "ep", isNT()); } else { *endpoint = ep; } if (!status) { /* Use a convenience function to concatenate the elements of */ /* the string binding into the proper sequence. */ status = RpcStringBindingCompose(0, // uuid (unsigned char*)"ncalrpc", // protseq 0, // address (unsigned char*)(*endpoint), // endpoint 0, // options &pszStringBinding); cci_check_error(status); } if (!status) { /* Set the binding handle that will be used to bind to the server. */ status = RpcBindingFromStringBinding(pszStringBinding, &ccs_request_IfHandle); cci_check_error(status); } if (!status) { // Win9x might call RpcBindingSetAuthInfo (not Ex), but it does not // quite work on Win9x... if (isNT()) { RPC_SECURITY_QOS qos; qos.Version = RPC_C_SECURITY_QOS_VERSION; qos.Capabilities = RPC_C_QOS_CAPABILITIES_DEFAULT; qos.IdentityTracking = RPC_C_QOS_IDENTITY_STATIC; qos.ImpersonationType = RPC_C_IMP_LEVEL_IDENTIFY; status = info.fRpcBindingSetAuthInfoEx(ccs_request_IfHandle, 0, // principal RPC_C_AUTHN_LEVEL_CONNECT, RPC_C_AUTHN_WINNT, 0, // current address space RPC_C_AUTHZ_NAME, &qos); cci_check_error(status); } } if (pszStringBinding) { DWORD status = RpcStringFree(&pszStringBinding); cci_check_error(status); } return cci_check_error(status); } DWORD find_server(Init::InitInfo& info, LPSTR endpoint) { DWORD status = 0; LPSTR event_name = 0; HANDLE hEvent = 0; SECURITY_ATTRIBUTES sa = { 0 }; PSECURITY_ATTRIBUTES psa = 0; STARTUPINFO si = { 0 }; PROCESS_INFORMATION pi = { 0 }; char* szExe = 0; char* szDir = 0; BOOL bRes = FALSE; char* cmdline = NULL; #if 0 HANDLE hToken = 0; #endif psa = isNT() ? &sa : 0; cci_debug_printf("%s Looking for server; ccs_request_IfHandle:0x%X", __FUNCTION__, ccs_request_IfHandle); status = cci_check_error(RpcMgmtIsServerListening(ccs_request_IfHandle)); if (status == RPC_S_NOT_LISTENING) { cci_debug_printf(" Server *NOT* found!"); si.cb = sizeof(si); status = alloc_module_dir_name(CCAPI_DLL, &szDir); if (!status) { status = alloc_module_dir_name_with_file(CCAPI_DLL, CCAPI_EXE, &szExe); } if (!status) { status = alloc_name(&event_name, "startup", isNT()); cci_check_error(status); } if (!status) { if (isNT()) { sa.nLength = sizeof(sa); status = alloc_own_security_descriptor_NT(&sa.lpSecurityDescriptor); cci_check_error(status); } } if (!status) { hEvent = CreateEvent(psa, FALSE, FALSE, event_name); cci_debug_printf(" CreateEvent(... %s) returned hEvent 0x%X", event_name, hEvent); if (!hEvent) status = GetLastError(); } if (!status) { #if 0 if (SecureClient::IsImp()) { cci_debug_printf(STARTUP "Token is impersonation token")); SecureClient::DuplicateImpAsPrimary(hToken); } else { cci_debug_printf(STARTUP "Token is NOT impersonation token")); } #endif #if 0 if (hToken) bRes = CreateProcessAsUser(hToken, szExe, // app name NULL, // cmd line psa, // SA psa, // SA FALSE, CREATE_NEW_PROCESS_GROUP | //CREATE_NEW_CONSOLE | NORMAL_PRIORITY_CLASS | // CREATE_NO_WINDOW | DETACHED_PROCESS | 0 , NULL, // environment szDir, // current dir &si, &pi); else #endif alloc_cmdline_2_args(szExe, endpoint, "-D", &cmdline); bRes = CreateProcess( szExe, // app name NULL, //cmdline, // cmd line is psa, // SA psa, // SA FALSE, CREATE_NEW_PROCESS_GROUP | NORMAL_PRIORITY_CLASS | #ifdef CCAPI_LAUNCH_SERVER_WITH_CONSOLE CREATE_NEW_CONSOLE | #else DETACHED_PROCESS | #endif 0, NULL, // environment szDir, // current dir &si, &pi); if (!bRes) { status = GetLastError(); cci_debug_printf(" CreateProcess returned %d; LastError: %d", bRes, status); } cci_debug_printf(" Waiting..."); } cci_check_error(status); if (!status) { status = WaitForSingleObject(hEvent, (SECONDS_TO_WAIT)*1000); status = RpcMgmtIsServerListening(ccs_request_IfHandle); } } else if (status) { cci_debug_printf(" unexpected error while looking for server: 0D%d / 0U%u / 0X%X", status, status, status); } #if 0 if (hToken) CloseHandle(hToken); #endif if (szDir) free_alloc_p(&szDir); if (szExe) free_alloc_p(&szExe); if (hEvent) CloseHandle(hEvent); if (pi.hThread) CloseHandle(pi.hThread); if (pi.hProcess) CloseHandle(pi.hProcess); if (sa.lpSecurityDescriptor) free_alloc_p(&sa.lpSecurityDescriptor); return cci_check_error(status); } static DWORD make_random_challenge(DWORD *challenge_out) { HCRYPTPROV provider; DWORD status = 0; *challenge_out = 0; if (!CryptAcquireContext(&provider, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) { status = GetLastError(); cci_check_error(status); return status; } if (!CryptGenRandom(provider, sizeof(*challenge_out), (BYTE *)challenge_out)) { status = GetLastError(); cci_check_error(status); return status; } if (!CryptReleaseContext(provider, 0)) { /* * Note: even though CryptReleaseContext() failed, we don't really * care since a) we've already successfully obtained our challenge * anyway and b) at least one of the potential errors, "ERROR_BUSY" * does not really seem to be an error at all. So GetLastError() is * logged for informational purposes only and should not be returned. */ cci_check_error(GetLastError()); } return status; } static DWORD authenticate_server(Init::InitInfo& info) { DWORD challenge, desired_response; HANDLE hMap = 0; LPSTR mem_name = 0; PDWORD pvalue = 0; CC_UINT32 response = 0; SECURITY_ATTRIBUTES sa = { 0 }; DWORD status = 0; cci_debug_printf("%s entry", __FUNCTION__); status = alloc_name(&mem_name, "auth", isNT()); cci_check_error(status); if (!status) { status = make_random_challenge(&challenge); desired_response = challenge + 1; cci_check_error(status); } if (!status) { if (isNT()) { sa.nLength = sizeof(sa); status = alloc_own_security_descriptor_NT(&sa.lpSecurityDescriptor); } } cci_check_error(status); if (!status) { hMap = CreateFileMapping(INVALID_HANDLE_VALUE, isNT() ? &sa : 0, PAGE_READWRITE, 0, sizeof(DWORD), mem_name); if (!hMap) status = GetLastError(); } cci_check_error(status); if (!status) { pvalue = (PDWORD)MapViewOfFile(hMap, FILE_MAP_ALL_ACCESS, 0, 0, 0); if (!pvalue) status = GetLastError(); } cci_check_error(status); if (!status) { *pvalue = challenge; RpcTryExcept { response = ccs_authenticate( (CC_CHAR*)mem_name ); } RpcExcept(1) { status = RpcExceptionCode(); cci_check_error(status); } RpcEndExcept; } cci_check_error(status); if (!status) { // Check response if ((response != desired_response) && (*pvalue != desired_response)) { cci_debug_printf(" Could not authenticate server."); status = ERROR_ACCESS_DENIED; // XXX - CO_E_NOMATCHINGSIDFOUND? } else { cci_debug_printf(" Server authenticated!"); } cci_check_error(status); } free_alloc_p(&mem_name); free_alloc_p(&sa.lpSecurityDescriptor); if (pvalue) { BOOL ok = UnmapViewOfFile(pvalue); // DEBUG_ASSERT(ok); } if (hMap) CloseHandle(hMap); return status; } DWORD Client::Disconnect() { DWORD status = 0; if (ccs_request_IfHandle) { /* The calls to the remote procedures are complete. */ /* Free the binding handle */ status = RpcBindingFree(&ccs_request_IfHandle); } s_init = false; return status; } DWORD Client::Connect(char* ep OPTIONAL) { LPSTR endpoint = 0; DWORD status = 0; if (!ccs_request_IfHandle) { Init::InitInfo info; status = Init::Info(info); cci_check_error(status); if (!status) { status = bind_client(ep, info, &endpoint); cci_check_error(status); } if (!status) { status = find_server(info, endpoint); cci_check_error(status); } if (!status) { status = authenticate_server(info); cci_check_error(status); } } if (endpoint && (endpoint != ep)) free_alloc_p(&endpoint); if (status) Client::Disconnect(); return status; } DWORD Client::Initialize(char* ep OPTIONAL) { CcAutoTryLock AL(Client::sLock); if (!AL.IsLocked() || s_init) return 0; SecureClient s; ccs_request_IfHandle = NULL; DWORD status = Client::Connect(ep); if (!status) s_init = true; return status; } DWORD Client::Cleanup() { CcAutoLock AL(Client::sLock); SecureClient s; return Client::Disconnect(); } DWORD Client::Reconnect(char* ep OPTIONAL) { CcAutoLock AL(Client::sLock); SecureClient s; DWORD status = 0; if (Initialized()) { DWORD status = Client::Cleanup(); } if ( (!status) ) { status = Client::Initialize(ep); } return status; } krb5-1.16/src/ccapi/lib/win/dllmain.h0000644000704600001450000000267213211554426017207 0ustar ghudsonlibuuid/* ccapi/lib/win/dllmain.h */ /* * Copyright 2008 Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #ifndef _dll_h #define _dll_h #include "windows.h" #ifdef __cplusplus // If used by C++ code, extern "C" { // we need to export the C interface #endif DWORD GetTlsIndex(); #ifdef __cplusplus } #endif #endif _dll_h krb5-1.16/src/ccapi/lib/win/WINCCAPI.vcproj0000644000704600001450000000453313211554426020036 0ustar ghudsonlibuuid krb5-1.16/src/ccapi/lib/win/Makefile.in0000644000704600001450000001026213211554426017455 0ustar ghudsonlibuuid# makefile: Constructs the Kerberos for Windows CCAPI DLL. # OBJS = $(OUTPRE)ccapi_ccache.obj \ $(OUTPRE)ccapi_ccache_iterator.obj \ $(OUTPRE)ccapi_context.obj \ $(OUTPRE)ccapi_context_change_time.obj \ $(OUTPRE)ccapi_credentials.obj \ $(OUTPRE)ccapi_credentials_iterator.obj \ $(OUTPRE)ccapi_ipc.obj \ $(OUTPRE)ccapi_err.obj \ $(OUTPRE)ccapi_os_ipc.obj \ $(OUTPRE)ccapi_string.obj \ $(OUTPRE)ccapi_v2.obj \ $(OUTPRE)cci_array_internal.obj \ $(OUTPRE)cci_cred_union.obj \ $(OUTPRE)cci_debugging.obj \ $(OUTPRE)cci_identifier.obj \ $(OUTPRE)cci_message.obj \ $(OUTPRE)cci_os_debugging.obj \ $(OUTPRE)cci_os_identifier.obj \ $(OUTPRE)ccs_reply_proc.obj \ $(OUTPRE)ccs_reply_s.obj \ $(OUTPRE)ccs_request_c.obj \ $(OUTPRE)ccutils.obj \ $(OUTPRE)client.obj \ $(OUTPRE)dllmain.obj \ $(OUTPRE)init.obj \ $(OUTPRE)secure.obj \ $(OUTPRE)tls.obj \ $(OUTPRE)util.obj \ $(OUTPRE)win-utils.obj ##### Options # Set NODEBUG if building release instead of debug #BUILDTOP is krb5/src and is relative to krb5/src/ccapi/lib/win, for making Makefile. BUILDTOP= ..\..\.. CCAPI = $(BUILDTOP)\CCAPI CO = $(CCAPI)\common COWIN = $(CCAPI)\common\win CCUTIL = $(CCAPI)\common\win\OldCC LIBDIR = $(CCAPI)\lib LIBWIN = $(LIBDIR)\win POSIX = $(BUILDTOP)\lib\krb5\posix OLDCC = $(LIBWIN)\OldCC SRCTMP = $(LIBWIN)\srctmp !if defined(KRB5_KFW_COMPILE) KFWINC= /I$(BUILDTOP)\..\..\krbcc\include !endif # Because all the sources are pulled together into the temp directory SRCTMP, # the only includes we need are to directories outside of ccapi. LOCALINCLUDES = /I..\$(BUILDTOP) /I..\$(BUILDTOP)\include /I..\$(BUILDTOP)\include\krb5 $(KFWINC) \ -I..\$(BUILDTOP)\util\et MIDLINCLUDES = /I..\$(BUILDTOP)\include CPPFLAGS = $(CPPFLAGS) /EHsc -D_CRTAPI1=_cdecl -D_CRTAPI2=_cdecl -DWINVER=0x0501 \ -D_WIN32_WINNT=0x0501 -D_CRT_SECURE_NO_WARNINGS $(cvarsdll) ##### Linker LINK = link LIBS = ..\$(CLIB) ..\$(SLIB) kernel32.lib ws2_32.lib user32.lib advapi32.lib LFLAGS = /nologo $(LOPTS) all: Makefile copysrc midl $(OUTPRE)$(CCLIB).dll finish ccs_request.h ccs_request_c.c ccs_request_s.c : ccs_request.idl ccs_request.acf midl $(MIDL_OPTIMIZATION) $(MIDLI) -oldnames -cpp_cmd $(CC) -cpp_opt "-E" \ ccs_request.idl ccs_reply.h ccs_reply_c.c ccs_reply_s.c : ccs_reply.idl ccs_reply.acf midl $(MIDL_OPTIMIZATION) $(MIDLI) -oldnames -cpp_cmd $(CC) -cpp_opt "-E" \ ccs_reply.idl copysrc : echo "Copying all sources needed to build $(CCLIB).dll to $(SRCTMP)" if NOT exist $(SRCTMP)\nul mkdir $(SRCTMP) xcopy /D/Y $(CO)\*.* $(SRCTMP) xcopy /D/Y $(COWIN)\*.* $(SRCTMP) xcopy /D/Y $(CCUTIL)\*.* $(SRCTMP) xcopy /D/Y $(LIBDIR)\*.* $(SRCTMP) xcopy /D/Y $(LIBWIN)\*.* $(SRCTMP) xcopy /D/Y $(OLDCC)\*.* $(SRCTMP) cd $(SRCTMP) if NOT exist $(OUTPRE)\nul mkdir $(OUTPRE) midl : ccs_request.h ccs_reply.h VERSIONRC = $(BUILDTOP)\..\windows\version.rc CCLIBRES = $(OUTPRE)$(CCLIB).res # Main program: $(CCLIBRES): $(VERSIONRC) $(RC) $(RCFLAGS) -DCCAPI_LIB -fo $@ -r $** $(OUTPRE)$(CCLIB).dll: $(OBJS) $(CCLIB).def $(CCLIBRES) $(LINK) $(LFLAGS) -entry:$(ENTRYPOINT) -dll /map:$*.map /out:$@ /DEF:$(CCLIB).def $(OBJS) \ /implib:$(CCLIB).lib $(dllflags) $(LIBS) $(KFWLIB) $(SCLIB) $(CCLIBRES) rpcrt4.lib $(conlibsdll) $(conflags) $(CCLIB).def: echo ;$(CCLIB).def is generated by a Makefile rule. > $(CCLIB).def echo HEAPSIZE 8192 >> $(CCLIB).def echo EXPORTS >> $(CCLIB).def type ccapi.exports >> $(CCLIB).def type ccapi_v2.exports >> $(CCLIB).def type debug.exports >> $(CCLIB).def finish: echo "Finished in ccapi/lib/win." cd .. install: echo "Doing nothing for make install" clean: if exist $(OUTPRE)*.exe del $(OUTPRE)*.exe if exist $(OUTPRE)*.obj del $(OUTPRE)*.obj if exist $(OUTPRE)*.res del $(OUTPRE)*.res if exist $(OUTPRE)*.map del $(OUTPRE)*.map if exist $(OUTPRE)*.pdb del $(OUTPRE)*.pdb if exist *.err del *.err if exist $(SRCTMP) rmdir /s /q $(SRCTMP) krb5-1.16/src/ccapi/lib/win/ccapi_os_ipc.cxx0000644000704600001450000003477013211554426020561 0ustar ghudsonlibuuid/* * $Header$ * * Copyright 2008 Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ extern "C" { #include "k5-thread.h" #include "ccapi_os_ipc.h" #include "cci_debugging.h" #include "ccs_reply.h" #include "ccs_request.h" #include "ccutils.h" #include "tls.h" #include "util.h" #include "win-utils.h" } #include "autolock.hxx" #include "CredentialsCache.h" #include "secure.hxx" #include "opts.hxx" #include "client.h" extern "C" DWORD GetTlsIndex(); #define SECONDS_TO_WAIT 10 #define CLIENT_REQUEST_RPC_HANDLE ccs_request_IfHandle extern HANDLE hCCAPIv2Mutex; ParseOpts::Opts opts = { 0 }; PSECURITY_ATTRIBUTES psa = 0; SECURITY_ATTRIBUTES sa = { 0 }; /* The layout of the rest of this module: The entrypoints defined in ccs_os_ipc.h: cci_os_ipc_thread_init cci_os_ipc Other routines needed by those four. cci_os_connect handle_exception */ cc_int32 ccapi_connect(const struct tspdata* tsp); static DWORD handle_exception(DWORD code, struct tspdata* ptspdata); extern "C" { cc_int32 cci_os_ipc_msg( cc_int32 in_launch_server, k5_ipc_stream in_request_stream, cc_int32 in_msg, k5_ipc_stream* out_reply_stream); } /* ------------------------------------------------------------------------ */ extern "C" cc_int32 cci_os_ipc_process_init (void) { RPC_STATUS status; if (!isNT()) { status = RpcServerRegisterIf(ccs_reply_ServerIfHandle, // interface NULL, // MgrTypeUuid NULL); // MgrEpv; null means use default } else { status = RpcServerRegisterIfEx(ccs_reply_ServerIfHandle, // interface NULL, // MgrTypeUuid NULL, // MgrEpv; 0 means default RPC_IF_ALLOW_SECURE_ONLY, RPC_C_LISTEN_MAX_CALLS_DEFAULT, NULL); // No security callback. } cci_check_error(status); if (!status) { status = RpcServerRegisterAuthInfo(0, // server principal RPC_C_AUTHN_WINNT, 0, 0 ); cci_check_error(status); } return status; // ugh. needs translation } /* ------------------------------------------------------------------------ */ extern "C" cc_int32 cci_os_ipc_thread_init (void) { cc_int32 err = ccNoError; struct tspdata* ptspdata; HANDLE replyEvent = NULL; UUID __RPC_FAR uuid; RPC_CSTR __RPC_FAR uuidString = NULL; char* endpoint = NULL; if (!GetTspData(GetTlsIndex(), &ptspdata)) return ccErrNoMem; err = cci_check_error(UuidCreate(&uuid)); // Get a UUID if (err == RPC_S_OK) { // Convert to string err = UuidToString(&uuid, &uuidString); cci_check_error(err); } if (!err) { // Save in thread local storage tspdata_setUUID(ptspdata, uuidString); endpoint = clientEndpoint((const char *)uuidString); err = RpcServerUseProtseqEp((RPC_CSTR)"ncalrpc", RPC_C_PROTSEQ_MAX_REQS_DEFAULT, (RPC_CSTR)endpoint, sa.lpSecurityDescriptor); // SD free(endpoint); cci_check_error(err); } #if 0 cci_debug_printf("%s UUID:<%s>", __FUNCTION__, tspdata_getUUID(ptspdata)); #endif // Initialize old CCAPI if necessary: if (!err) if (!Init:: Initialized()) err = Init:: Initialize( ); if (!err) if (!Client::Initialized()) err = Client::Initialize(0); if (!err) { /* Whenever a reply to an RPC request is received, the RPC caller needs to know when the reply has been received. It does that by waiting for a client-specific event to be set. Define the event name to be _reply: */ replyEvent = createThreadEvent((char*)uuidString, REPLY_SUFFIX); } if (!err) { static bool bListening = false; if (!bListening) { err = RpcServerListen(1, RPC_C_LISTEN_MAX_CALLS_DEFAULT, TRUE); cci_check_error(err); } bListening = err == 0; } if (replyEvent) tspdata_setReplyEvent(ptspdata, replyEvent); else err = cci_check_error(GetLastError()); if (uuidString) RpcStringFree(&uuidString); return cci_check_error(err); } /* ------------------------------------------------------------------------ */ cc_int32 cci_os_ipc (cc_int32 in_launch_server, k5_ipc_stream in_request_stream, k5_ipc_stream* out_reply_stream) { return cci_os_ipc_msg( in_launch_server, in_request_stream, CCMSG_REQUEST, out_reply_stream); } extern "C" cc_int32 cci_os_ipc_msg( cc_int32 in_launch_server, k5_ipc_stream in_request_stream, cc_int32 in_msg, k5_ipc_stream* out_reply_stream) { cc_int32 err = ccNoError; cc_int32 done = FALSE; cc_int32 try_count = 0; cc_int32 server_died = FALSE; TCHAR* pszStringBinding= NULL; struct tspdata* ptspdata = NULL; char* uuid = NULL; int lenUUID = 0; unsigned int trycount = 0; time_t sst = 0; STARTUPINFO si = { 0 }; PROCESS_INFORMATION pi = { 0 }; HANDLE replyEvent = 0; BOOL bCCAPI_Connected= FALSE; BOOL bListening = FALSE; unsigned char tspdata_handle[8] = { 0 }; if (!in_request_stream) { err = cci_check_error (ccErrBadParam); } if (!out_reply_stream ) { err = cci_check_error (ccErrBadParam); } if (!GetTspData(GetTlsIndex(), &ptspdata)) {return ccErrBadParam;} bListening = tspdata_getListening(ptspdata); if (!bListening) { err = cci_check_error(cci_os_ipc_thread_init()); bListening = !err; tspdata_setListening(ptspdata, bListening); } bCCAPI_Connected = tspdata_getConnected (ptspdata); replyEvent = tspdata_getReplyEvent (ptspdata); sst = tspdata_getSST (ptspdata); uuid = tspdata_getUUID(ptspdata); // The lazy connection to the server has been put off as long as possible! // ccapi_connect starts listening for replies as an RPC server and then // calls ccs_rpc_connect. if (!err && !bCCAPI_Connected) { err = cci_check_error(ccapi_connect(ptspdata)); bCCAPI_Connected = !err; tspdata_setConnected(ptspdata, bCCAPI_Connected); } // Clear replyEvent so we can detect when a reply to our request has been received: ResetEvent(replyEvent); //++ Use the old CCAPI implementation to try to talk to the server: // It has all the code to use the RPC in a thread-safe way, make the endpoint, // (re)connect and (re)start the server. // Note: the old implementation wrapped the thread-safety stuff in a macro. // Here it is expanded and thus duplicated for each RPC call. The new code has // a very limited number of RPC calls, unlike the older code. WaitForSingleObject( hCCAPIv2Mutex, INFINITE ); SecureClient* s = 0; SecureClient::Start(s); CcAutoLock* a = 0; CcAutoLock::Start(a, Client::sLock); // New code using new RPC procedures for sending the data and receiving a reply: if (!err) { RpcTryExcept { if (!GetTspData(GetTlsIndex(), &ptspdata)) {return ccErrBadParam;} uuid = tspdata_getUUID(ptspdata); lenUUID = 1 + strlen(uuid); /* 1+ includes terminating \0. */ #if 0 cci_debug_printf("%s calling remote ccs_rpc_request tsp*:0x%X", __FUNCTION__, ptspdata); cci_debug_printf(" rpcmsg:%d; UUID[%d]:<%s> SST:%ld", in_msg, lenUUID, uuid, sst); #endif /* copy ptr into handle; ptr may be 4 or 8 bytes, depending on platform; handle is always 8 */ memcpy(tspdata_handle, &ptspdata, sizeof(ptspdata)); ccs_rpc_request( /* make call with user message: */ in_msg, /* Message type */ tspdata_handle, /* Our tspdata* will be sent back to the reply proc. */ (unsigned char*)uuid, krb5int_ipc_stream_size(in_request_stream), (unsigned char*)krb5int_ipc_stream_data(in_request_stream), /* Data buffer */ sst, /* session start time */ (long*)(&err) ); /* Return code */ } RpcExcept(1) { err = handle_exception(RpcExceptionCode(), ptspdata); } RpcEndExcept; } cci_check_error(err); CcAutoLock::Stop(a); SecureClient::Stop(s); ReleaseMutex(hCCAPIv2Mutex); //-- Use the old CCAPI implementation to try to talk to the server. // Wait for reply handler to set event: if (!err) { err = cci_check_error(WaitForSingleObject(replyEvent, INFINITE));//(SECONDS_TO_WAIT)*1000)); } if (!err) { err = cci_check_error(RpcMgmtIsServerListening(CLIENT_REQUEST_RPC_HANDLE)); } if (!err && server_died) { err = cci_check_error (ccErrServerUnavailable); } #if 0 if (err == BOOTSTRAP_UNKNOWN_SERVICE && !in_launch_server) { err = ccNoError; /* If the server is not running just return an empty stream. */ } #endif if (!err) { *out_reply_stream = tspdata_getStream(ptspdata); } return cci_check_error (err); } static DWORD handle_exception(DWORD code, struct tspdata* ptspdata) { cci_debug_printf("%s code %u; ccs_request_IfHandle:0x%X", __FUNCTION__, code, ccs_request_IfHandle); if ( (code == RPC_S_SERVER_UNAVAILABLE) || (code == RPC_S_INVALID_BINDING) ) { Client::Cleanup(); tspdata_setConnected(ptspdata, FALSE); } return code; } /* Establish a CCAPI connection with the server. * The connect logic here is identical to the logic in the send request code. * TODO: merge this connect code with that request code. */ cc_int32 ccapi_connect(const struct tspdata* tsp) { BOOL bListen = TRUE; HANDLE replyEvent = 0; RPC_STATUS status = FALSE; char* uuid = NULL; unsigned char tspdata_handle[8] = {0}; /* Start listening to our uuid before establishing the connection, * so that when the server tries to call ccapi_listen, we will be ready. */ /* Build complete RPC uuid using previous CCAPI implementation: */ replyEvent = tspdata_getReplyEvent(tsp); uuid = tspdata_getUUID(tsp); cci_debug_printf("%s is listening ...", __FUNCTION__); // Clear replyEvent so we can detect when a reply to our connect request has been received: ResetEvent(replyEvent); // We use the old CCAPI implementation to try to talk to the server. // It has all the code to make the uuid, (re)connect and (re)start the server. WaitForSingleObject( hCCAPIv2Mutex, INFINITE ); SecureClient* s = 0; SecureClient::Start(s); CcAutoLock* a = 0; CcAutoLock::Start(a, Client::sLock); // Initialize old CCAPI if necessary: if (!status) if (!Init:: Initialized()) status = Init:: Initialize( ); if (!status) if (!Client::Initialized()) status = Client::Initialize(0); // New code using new RPC procedures for sending the data and receiving a reply: if (!status) { memcpy(tspdata_handle, &tsp, sizeof(tsp)); RpcTryExcept { ccs_rpc_connect( /* make call with user message: */ CCMSG_CONNECT, /* Message type */ tspdata_handle, /* Our tspdata* will be sent back to the reply proc. */ (unsigned char*)uuid, (long*)(&status) ); /* Return code */ } RpcExcept(1) { cci_check_error(RpcExceptionCode()); status = ccErrBadInternalMessage; } RpcEndExcept; } CcAutoLock::Stop(a); SecureClient::Stop(s); ReleaseMutex(hCCAPIv2Mutex); if (!status) { #if 0 cci_debug_printf("%s Waiting for replyEvent.", __FUNCTION__); #endif status = WaitForSingleObject(replyEvent, INFINITE);//(SECONDS_TO_WAIT)*1000); status = cci_check_error(RpcMgmtIsServerListening(CLIENT_REQUEST_RPC_HANDLE)); cci_debug_printf(" Server %sFOUND!", (status) ? "NOT " : ""); } if (status) { cci_debug_printf(" unexpected error while looking for server... (%u)", status); } return status; } krb5-1.16/src/ccapi/lib/win/debug.exports0000644000704600001450000000035513211554426020126 0ustar ghudsonlibuuid cci_debug_printf _cci_check_error cci_os_ipc cci_os_ipc_msg cci_os_ipc_thread_init krb5int_ipc_stream_data krb5int_ipc_stream_write krb5int_ipc_stream_new ccs_authenticate cci_os_ipc_process_init krb5-1.16/src/ccapi/lib/libkrb5-ccapi.exports0000644000704600001450000000001113211554426020637 0ustar ghudsonlibuuidcc_close krb5-1.16/src/ccapi/lib/ccapi_err.et0000644000704600001450000000674213211554426017104 0ustar ghudsonlibuuid# # $Header$ # # Copyright 1998-2006 Massachusetts Institute of Technology. # All Rights Reserved. # # Export of this software from the United States of America may # require a specific license from the United States Government. # It is the responsibility of any person or organization contemplating # export to obtain such a license before exporting. # # WITHIN THAT CONSTRAINT, permission to use, copy, modify, and # distribute this software and its documentation for any purpose and # without fee is hereby granted, provided that the above copyright # notice appear in all copies and that both that copyright notice and # this permission notice appear in supporting documentation, and that # the name of M.I.T. not be used in advertising or publicity pertaining # to distribution of the software without specific, written prior # permission. Furthermore if you modify this software you must label # your software as modified software and not distribute it in such a # fashion that it might be confused with the original M.I.T. software. # M.I.T. makes no representations about the suitability of # this software for any purpose. It is provided "as is" without express # or implied warranty. # error_table_base 201 error_table_manager "Credentials Cache" error_table CAPI # 201 error_code ccIteratorEnd, "Reached end of iterator" error_code ccErrBadParam, "Invalid argument" error_code ccErrNoMem, "Out of memory" error_code ccErrInvalidContext, "Invalid credentials cache context" error_code ccErrInvalidCCache, "Invalid credentials cache" # 206 index 5 error_code ccErrInvalidString, "Invalid credentials cache string" error_code ccErrInvalidCredentials, "Invalid credentials" error_code ccErrInvalidCCacheIterator, "Invalid credentials cache iterator" error_code ccErrInvalidCredentialsIterator, "Invalid credentials iterator" error_code ccErrInvalidLock, "Invalid iterator" # 211 index 10 error_code ccErrBadName, "Invalid credentials cache name" error_code ccErrBadCredentialsVersion, "Invalid credentials cache version (not 4 or 5)" error_code ccErrBadAPIVersion, "Invalid CCAPI version" error_code ccErrContextLocked, "Credentials cache context is already locked" error_code ccErrContextUnlocked, "Credentials cache context is already unlocked" # 216 index 15 error_code ccErrCCacheLocked, "Credentials cache is already locked" error_code ccErrCCacheUnlocked, "Credentials cache is already unlocked" error_code ccErrBadLockType, "Invalid credentials cache lock type" error_code ccErrNeverDefault, "Credentials cache has never been the default cache" error_code ccErrCredentialsNotFound, "Credentials not found" # 221 index 20 error_code ccErrCCacheNotFound, "Credentials cache not found" error_code ccErrContextNotFound, "Credentials cache context not found" error_code ccErrServerUnavailable, "Credentials cache server unavailable" error_code ccErrServerInsecure, "Credentials cache server in this bootstrap is owned by another user" error_code ccErrServerCantBecomeUID, "Credentials cache server failed to change effective uids" # 226 index 25 error_code ccErrTimeOffsetNotSet, "Credentials cache time offset not set" end krb5-1.16/src/ccapi/lib/Makefile.in0000644000704600001450000000237513211554426016666 0ustar ghudsonlibuuidmydir=ccapi$(S)lib BUILDTOP=$(REL)..$(S).. SUBDIRS=unix LOCALINCLUDES=-I$(srcdir)/../common -I. SHLIB_EXPDEPS= $(COM_ERR_DEPLIB) $(SUPPORT_DEPLIB) SHLIB_EXPLIBS=-lcom_err $(SUPPORT_LIB) RELDIR=../ccapi/lib LIBBASE=krb5-ccapi LIBMAJOR=1 LIBMINOR=0 STOBJLISTS= \ OBJS.ST \ unix/OBJS.ST STLIBOBJS= \ ccapi_ccache.o \ ccapi_ccache_iterator.o \ ccapi_context.o \ ccapi_context_change_time.o \ ccapi_credentials.o \ ccapi_credentials_iterator.o \ ccapi_err.o \ ccapi_ipc.o \ ccapi_string.o \ ccapi_v2.o OBJS= \ $(OUTPRE)ccapi_ccache.$(OUTPRE) \ $(OUTPRE)ccapi_ccache_iterator.$(OUTPRE) \ $(OUTPRE)ccapi_context.$(OUTPRE) \ $(OUTPRE)ccapi_context_change_time.$(OUTPRE) \ $(OUTPRE)ccapi_credentials.$(OUTPRE) \ $(OUTPRE)ccapi_credentials_iterator.$(OUTPRE) \ $(OUTPRE)ccapi_err.$(OUTPRE) \ $(OUTPRE)ccapi_ipc.$(OUTPRE) \ $(OUTPRE)ccapi_string.$(OUTPRE) \ $(OUTPRE)ccapi_v2.$(OUTPRE) SRCS= \ ccapi_ccache.c \ ccapi_ccache_iterator.c \ ccapi_context.c \ ccapi_context_change_time.c \ ccapi_credentials.c \ ccapi_credentials_iterator.c \ ccapi_err.c \ ccapi_ipc.c \ ccapi_string.c \ ccapi_v2.c ccapi_err.c ccapi_err.h : ccapi_err.et all-unix: all-libobjs all-liblinks clean-unix:: clean-libobjs clean-liblinks clean-libs @lib_frag@ @libobj_frag@ krb5-1.16/src/ccapi/lib/unix/0000755000704600001450000000000013211554426015575 5ustar ghudsonlibuuidkrb5-1.16/src/ccapi/lib/unix/deps0000644000704600001450000000003013211554426016444 0ustar ghudsonlibuuid# No dependencies here. krb5-1.16/src/ccapi/lib/unix/stubs.c0000644000704600001450000000022313211554426017076 0ustar ghudsonlibuuid#include #include "ccapi_os_ipc.h" cc_int32 cci_os_ipc_thread_init (void) { return EINVAL; } void cci_os_ipc_thread_fini (void) { } krb5-1.16/src/ccapi/lib/unix/Makefile.in0000644000704600001450000000034513211554426017644 0ustar ghudsonlibuuidmydir=ccapi$(S)lib$(S)unix BUILDTOP=$(REL)..$(S)..$(S).. LOCALINCLUDES= -I$(srcdir)/.. -I$(srcdir)/../../common STLIBOBJS= stubs.o OBJS= $(OUTPRE)stubs.$(OBJEXT) all-unix: all-libobjs clean-unix:: clean-libobjs @libobj_frag@ krb5-1.16/src/ccapi/lib/ccapi_ccache.h0000644000704600001450000001104213211554426017326 0ustar ghudsonlibuuid/* ccapi/lib/ccapi_ccache.h */ /* * Copyright 2006 Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #ifndef CCAPI_CCACHE_H #define CCAPI_CCACHE_H #include "cci_common.h" cc_int32 cci_ccache_new (cc_ccache_t *out_ccache, cci_identifier_t in_identifier); cc_int32 ccapi_ccache_release (cc_ccache_t io_ccache); cc_int32 cci_ccache_write (cc_ccache_t in_ccache, k5_ipc_stream in_stream); cc_int32 ccapi_ccache_destroy (cc_ccache_t io_ccache); cc_int32 ccapi_ccache_set_default (cc_ccache_t io_ccache); cc_int32 ccapi_ccache_get_credentials_version (cc_ccache_t in_ccache, cc_uint32 *out_credentials_version); cc_int32 ccapi_ccache_get_name (cc_ccache_t in_ccache, cc_string_t *out_name); cc_int32 ccapi_ccache_get_principal (cc_ccache_t in_ccache, cc_uint32 in_credentials_version, cc_string_t *out_principal); cc_int32 ccapi_ccache_set_principal (cc_ccache_t io_ccache, cc_uint32 in_credentials_version, const char *in_principal); cc_int32 ccapi_ccache_store_credentials (cc_ccache_t io_ccache, const cc_credentials_union *in_credentials_union); cc_int32 ccapi_ccache_remove_credentials (cc_ccache_t io_ccache, cc_credentials_t in_credentials); cc_int32 ccapi_ccache_new_credentials_iterator (cc_ccache_t in_ccache, cc_credentials_iterator_t *out_credentials_iterator); cc_int32 ccapi_ccache_move (cc_ccache_t io_source_ccache, cc_ccache_t io_destination_ccache); cc_int32 ccapi_ccache_lock (cc_ccache_t io_ccache, cc_uint32 in_lock_type, cc_uint32 in_block); cc_int32 ccapi_ccache_unlock (cc_ccache_t io_ccache); cc_int32 ccapi_ccache_get_last_default_time (cc_ccache_t in_ccache, cc_time_t *out_last_default_time); cc_int32 ccapi_ccache_get_change_time (cc_ccache_t in_ccache, cc_time_t *out_change_time); cc_int32 ccapi_ccache_wait_for_change (cc_ccache_t in_ccache); cc_int32 ccapi_ccache_compare (cc_ccache_t in_ccache, cc_ccache_t in_compare_to_ccache, cc_uint32 *out_equal); cc_int32 ccapi_ccache_get_kdc_time_offset (cc_ccache_t in_ccache, cc_uint32 in_credentials_version, cc_time_t *out_time_offset); cc_int32 ccapi_ccache_set_kdc_time_offset (cc_ccache_t io_ccache, cc_uint32 in_credentials_version, cc_time_t in_time_offset); cc_int32 ccapi_ccache_clear_kdc_time_offset (cc_ccache_t io_ccache, cc_uint32 in_credentials_version); cc_int32 cci_ccache_get_compat_version (cc_ccache_t in_ccache, cc_uint32 *out_compat_version); cc_int32 cci_ccache_set_compat_version (cc_ccache_t io_ccache, cc_uint32 in_compat_version); #endif /* CCAPI_CCACHE_H */ krb5-1.16/src/ccapi/lib/ccapi_ccache_iterator.h0000644000704600001450000000463013211554426021244 0ustar ghudsonlibuuid/* ccapi/lib/ccapi_ccache_iterator.h */ /* * Copyright 2006 Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #ifndef CCAPI_CCACHE_ITERATOR_H #define CCAPI_CCACHE_ITERATOR_H #include "cci_common.h" cc_int32 cci_ccache_iterator_new (cc_ccache_iterator_t *out_ccache_iterator, cci_identifier_t in_identifier); cc_int32 cci_ccache_iterator_write (cc_ccache_iterator_t in_ccache_iterator, k5_ipc_stream in_stream); cc_int32 ccapi_ccache_iterator_release (cc_ccache_iterator_t io_ccache_iterator); cc_int32 ccapi_ccache_iterator_next (cc_ccache_iterator_t in_ccache_iterator, cc_ccache_t *out_ccache); cc_int32 ccapi_ccache_iterator_clone (cc_ccache_iterator_t in_ccache_iterator, cc_ccache_iterator_t *out_ccache_iterator); cc_int32 cci_ccache_iterator_get_saved_ccache_name (cc_ccache_iterator_t in_ccache_iterator, const char **out_saved_ccache_name); cc_int32 cci_ccache_iterator_set_saved_ccache_name (cc_ccache_iterator_t io_ccache_iterator, const char *in_saved_ccache_name); #endif /* CCAPI_CCACHE_ITERATOR_H */ krb5-1.16/src/ccapi/lib/ccapi_credentials_iterator.c0000644000704600001450000002117513211554426022331 0ustar ghudsonlibuuid/* ccapi/lib/ccapi_credentials_iterator.c */ /* * Copyright 2006 Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #include "ccapi_credentials_iterator.h" #include "ccapi_credentials.h" #include "ccapi_ipc.h" /* ------------------------------------------------------------------------ */ typedef struct cci_credentials_iterator_d { cc_credentials_iterator_f *functions; #if TARGET_OS_MAC cc_credentials_iterator_f *vector_functions; #endif cci_identifier_t identifier; cc_uint32 compat_version; } *cci_credentials_iterator_t; /* ------------------------------------------------------------------------ */ struct cci_credentials_iterator_d cci_credentials_iterator_initializer = { NULL VECTOR_FUNCTIONS_INITIALIZER, NULL, 0 }; cc_credentials_iterator_f cci_credentials_iterator_f_initializer = { ccapi_credentials_iterator_release, ccapi_credentials_iterator_next, ccapi_credentials_iterator_clone }; /* ------------------------------------------------------------------------ */ cc_int32 cci_credentials_iterator_new (cc_credentials_iterator_t *out_credentials_iterator, cci_identifier_t in_identifier) { cc_int32 err = ccNoError; cci_credentials_iterator_t credentials_iterator = NULL; if (!out_credentials_iterator) { err = cci_check_error (ccErrBadParam); } if (!in_identifier ) { err = cci_check_error (ccErrBadParam); } if (!err) { credentials_iterator = malloc (sizeof (*credentials_iterator)); if (credentials_iterator) { *credentials_iterator = cci_credentials_iterator_initializer; } else { err = cci_check_error (ccErrNoMem); } } if (!err) { credentials_iterator->functions = malloc (sizeof (*credentials_iterator->functions)); if (credentials_iterator->functions) { *credentials_iterator->functions = cci_credentials_iterator_f_initializer; } else { err = cci_check_error (ccErrNoMem); } } if (!err) { err = cci_identifier_copy (&credentials_iterator->identifier, in_identifier); } if (!err) { *out_credentials_iterator = (cc_credentials_iterator_t) credentials_iterator; credentials_iterator = NULL; /* take ownership */ } if (credentials_iterator) { ccapi_credentials_iterator_release ((cc_credentials_iterator_t) credentials_iterator); } return cci_check_error (err); } /* ------------------------------------------------------------------------ */ cc_int32 cci_credentials_iterator_write (cc_credentials_iterator_t in_credentials_iterator, k5_ipc_stream in_stream) { cc_int32 err = ccNoError; cci_credentials_iterator_t credentials_iterator = (cci_credentials_iterator_t) in_credentials_iterator; if (!in_credentials_iterator) { err = cci_check_error (ccErrBadParam); } if (!in_stream ) { err = cci_check_error (ccErrBadParam); } if (!err) { err = cci_identifier_write (credentials_iterator->identifier, in_stream); } return cci_check_error (err); } /* ------------------------------------------------------------------------ */ cc_int32 ccapi_credentials_iterator_release (cc_credentials_iterator_t io_credentials_iterator) { cc_int32 err = ccNoError; cci_credentials_iterator_t credentials_iterator = (cci_credentials_iterator_t) io_credentials_iterator; if (!io_credentials_iterator) { err = ccErrBadParam; } if (!err) { err = cci_ipc_send (cci_credentials_iterator_release_msg_id, credentials_iterator->identifier, NULL, NULL); if (err) { cci_debug_printf ("%s: cci_ipc_send failed with error %d", __FUNCTION__, err); err = ccNoError; } } if (!err) { free ((char *) credentials_iterator->functions); cci_identifier_release (credentials_iterator->identifier); free (credentials_iterator); } return err; } /* ------------------------------------------------------------------------ */ cc_int32 ccapi_credentials_iterator_next (cc_credentials_iterator_t in_credentials_iterator, cc_credentials_t *out_credentials) { cc_int32 err = ccNoError; cci_credentials_iterator_t credentials_iterator = (cci_credentials_iterator_t) in_credentials_iterator; k5_ipc_stream reply = NULL; if (!in_credentials_iterator) { err = cci_check_error (ccErrBadParam); } if (!out_credentials ) { err = cci_check_error (ccErrBadParam); } if (!err) { err = cci_ipc_send (cci_credentials_iterator_next_msg_id, credentials_iterator->identifier, NULL, &reply); } if (!err) { err = cci_credentials_read (out_credentials, reply); } krb5int_ipc_stream_release (reply); return cci_check_error (err); } /* ------------------------------------------------------------------------ */ cc_int32 ccapi_credentials_iterator_clone (cc_credentials_iterator_t in_credentials_iterator, cc_credentials_iterator_t *out_credentials_iterator) { cc_int32 err = ccNoError; cci_credentials_iterator_t credentials_iterator = (cci_credentials_iterator_t) in_credentials_iterator; k5_ipc_stream reply = NULL; cci_identifier_t identifier = NULL; if (!in_credentials_iterator ) { err = cci_check_error (ccErrBadParam); } if (!out_credentials_iterator) { err = cci_check_error (ccErrBadParam); } if (!err) { err = cci_ipc_send (cci_credentials_iterator_next_msg_id, credentials_iterator->identifier, NULL, &reply); } if (!err) { err = cci_identifier_read (&identifier, reply); } if (!err) { err = cci_credentials_iterator_new (out_credentials_iterator, identifier); } krb5int_ipc_stream_release (reply); cci_identifier_release (identifier); return cci_check_error (err); } #ifdef TARGET_OS_MAC #pragma mark - #endif /* ------------------------------------------------------------------------ */ cc_int32 cci_credentials_iterator_get_compat_version (cc_credentials_iterator_t in_credentials_iterator, cc_uint32 *out_compat_version) { cc_int32 err = ccNoError; cci_credentials_iterator_t credentials_iterator = (cci_credentials_iterator_t) in_credentials_iterator; if (!in_credentials_iterator) { err = cci_check_error (ccErrBadParam); } if (!out_compat_version ) { err = cci_check_error (ccErrBadParam); } if (!err) { *out_compat_version = credentials_iterator->compat_version; } return cci_check_error (err); } /* ------------------------------------------------------------------------ */ cc_int32 cci_credentials_iterator_set_compat_version (cc_credentials_iterator_t io_credentials_iterator, cc_uint32 in_compat_version) { cc_int32 err = ccNoError; cci_credentials_iterator_t credentials_iterator = (cci_credentials_iterator_t) io_credentials_iterator; if (!io_credentials_iterator) { err = cci_check_error (ccErrBadParam); } if (!err) { credentials_iterator->compat_version = in_compat_version; } return cci_check_error (err); } krb5-1.16/src/ccapi/lib/ccapi_context_change_time.c0000644000704600001450000001566513211554426022141 0ustar ghudsonlibuuid/* ccapi/lib/ccapi_context_change_time.c */ /* * Copyright 2006, 2007 Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #include "ccapi_context_change_time.h" #include "cci_common.h" #include "k5-thread.h" static cci_identifier_t g_change_time_identifer = NULL; static cc_time_t g_change_time = 0; static cc_time_t g_change_time_offset = 0; static k5_mutex_t g_change_time_mutex = K5_MUTEX_PARTIAL_INITIALIZER; /* ------------------------------------------------------------------------ */ cc_int32 cci_context_change_time_thread_init (void) { return k5_mutex_finish_init(&g_change_time_mutex); } /* ------------------------------------------------------------------------ */ void cci_context_change_time_thread_fini (void) { k5_mutex_destroy(&g_change_time_mutex); } /* ------------------------------------------------------------------------ */ /* WARNING! Mutex must be locked when calling this! */ static cc_int32 cci_context_change_time_update_identifier (cci_identifier_t in_new_identifier, cc_uint32 *out_server_ids_match, cc_uint32 *out_old_server_running, cc_uint32 *out_new_server_running) { cc_int32 err = ccNoError; cc_uint32 server_ids_match = 0; cc_uint32 old_server_running = 0; cc_uint32 new_server_running = 0; if (!in_new_identifier) { err = cci_check_error (err); } if (!err && !g_change_time_identifer) { g_change_time_identifer = cci_identifier_uninitialized; } if (!err) { err = cci_identifier_compare_server_id (g_change_time_identifer, in_new_identifier, &server_ids_match); } if (!err && out_old_server_running) { err = cci_identifier_is_initialized (g_change_time_identifer, &old_server_running); } if (!err && out_new_server_running) { err = cci_identifier_is_initialized (in_new_identifier, &new_server_running); } if (!err && !server_ids_match) { cci_identifier_t new_change_time_identifer = NULL; err = cci_identifier_copy (&new_change_time_identifer, in_new_identifier); if (!err) { /* Save the new identifier */ if (g_change_time_identifer) { cci_identifier_release (g_change_time_identifer); } g_change_time_identifer = new_change_time_identifer; } } if (!err) { if (out_server_ids_match ) { *out_server_ids_match = server_ids_match; } if (out_old_server_running) { *out_old_server_running = old_server_running; } if (out_new_server_running) { *out_new_server_running = new_server_running; } } return cci_check_error (err); } #ifdef TARGET_OS_MAC #pragma mark - #endif /* ------------------------------------------------------------------------ */ cc_int32 cci_context_change_time_get (cc_time_t *out_change_time) { cc_int32 err = ccNoError; k5_mutex_lock (&g_change_time_mutex); *out_change_time = g_change_time + g_change_time_offset; k5_mutex_unlock (&g_change_time_mutex); return err; } /* ------------------------------------------------------------------------ */ cc_int32 cci_context_change_time_update (cci_identifier_t in_identifier, cc_time_t in_new_change_time) { cc_int32 err = ccNoError; k5_mutex_lock (&g_change_time_mutex); if (!in_identifier) { err = cci_check_error (err); } if (!err) { if (g_change_time < in_new_change_time) { /* Only update if it increases the time. May be a different server. */ g_change_time = in_new_change_time; cci_debug_printf ("%s: setting change time to %d", __FUNCTION__, in_new_change_time); } } if (!err) { err = cci_context_change_time_update_identifier (in_identifier, NULL, NULL, NULL); } k5_mutex_unlock (&g_change_time_mutex); return err; } /* ------------------------------------------------------------------------ */ cc_int32 cci_context_change_time_sync (cci_identifier_t in_new_identifier) { cc_int32 err = ccNoError; cc_uint32 server_ids_match = 0; cc_uint32 server_was_running = 0; cc_uint32 server_is_running = 0; k5_mutex_lock (&g_change_time_mutex); if (!in_new_identifier) { err = cci_check_error (err); } if (!err) { err = cci_context_change_time_update_identifier (in_new_identifier, &server_ids_match, &server_was_running, &server_is_running); } if (!err && !server_ids_match) { /* Increment the change time so callers re-read */ g_change_time_offset++; /* If the server died, absorb the offset */ if (server_was_running && !server_is_running) { cc_time_t now = time (NULL); g_change_time += g_change_time_offset; g_change_time_offset = 0; /* Make sure the change time increases, ideally with the current time */ g_change_time = (g_change_time < now) ? now : g_change_time; } cci_debug_printf ("%s noticed server changed (" "server_was_running = %d; server_is_running = %d; " "g_change_time = %d; g_change_time_offset = %d", __FUNCTION__, server_was_running, server_is_running, g_change_time, g_change_time_offset); } k5_mutex_unlock (&g_change_time_mutex); return err; } krb5-1.16/src/ccapi/deps0000644000704600001450000000003013211554426014713 0ustar ghudsonlibuuid# No dependencies here. krb5-1.16/src/ccapi/test/0000755000704600001450000000000013211554426015023 5ustar ghudsonlibuuidkrb5-1.16/src/ccapi/test/test_cc_initialize.c0000644000704600001450000000045613211554426021041 0ustar ghudsonlibuuid#include #include #include "test_ccapi_check.h" #include "test_ccapi_constants.h" #include "test_ccapi_context.h" #include "test_ccapi_ccache.h" int main (int argc, const char * argv[]) { cc_int32 err = ccNoError; T_CCAPI_INIT; err = check_cc_initialize(); return err; } krb5-1.16/src/ccapi/test/test_ccapi_log.c0000644000704600001450000000155413211554426020153 0ustar ghudsonlibuuid#ifndef _TEST_CCAPI_LOG_C_ #define _TEST_CCAPI_LOG_C_ #include "test_ccapi_log.h" void _log_error_v(const char *file, int line, const char *format, va_list ap) { fprintf(stdout, "\n\t%s:%d: ", file, line); if (!format) { fprintf(stdout, "An unknown error occurred"); } else { vfprintf(stdout, format, ap); } fflush(stdout); } void _log_error(const char *file, int line, const char *format, ...) { va_list ap; va_start(ap, format); _log_error_v(file, line, format, ap); va_end(ap); } void test_header(const char *msg) { if (msg != NULL) { fprintf(stdout, "\nChecking %s... ", msg); fflush(stdout); } } void test_footer(const char *msg, int err) { if (msg != NULL) { if (!err) { fprintf(stdout, "OK\n"); } else { fprintf(stdout, "\n*** %d failure%s in %s ***\n", err, (err == 1) ? "" : "s", msg); } } } #endif /* _TEST_CCAPI_LOG_C_ */ krb5-1.16/src/ccapi/test/test_ccapi_globals.h0000644000704600001450000000230713211554426021017 0ustar ghudsonlibuuid#ifndef _TEST_CCAPI_GLOBALS_H_ #define _TEST_CCAPI_GLOBALS_H_ #include // gets us TARGET_OS_MAC #if defined(macintosh) || (defined(__MACH__) && defined(__APPLE__)) #include #endif #ifdef TARGET_OS_MAC #include #else #include #endif /* GLOBALS */ extern unsigned int total_failure_count; extern unsigned int failure_count; extern const char *current_test_name; extern const char *current_test_activity; extern const char * ccapi_error_strings[30]; const char *translate_ccapi_error(cc_int32 err); #define T_CCAPI_INIT \ do { \ current_test_name = NULL; \ current_test_activity = NULL; \ } while( 0 ) #define BEGIN_TEST(name) \ do { \ current_test_name = name; \ failure_count = 0; \ test_header(current_test_name); \ } while( 0 ) #define BEGIN_CHECK_ONCE(x) \ do { \ if (x) { \ current_test_activity = x; \ } \ } while( 0 ) #define END_CHECK_ONCE \ do { \ current_test_activity = NULL; \ } while( 0 ) #define END_TEST_AND_RETURN \ test_footer(current_test_name, failure_count); \ total_failure_count += failure_count; \ return failure_count; #endif /* _TEST_CCAPI_GLOBALS_H_ */ krb5-1.16/src/ccapi/test/test_ccapi_util.c0000644000704600001450000000716213211554426020350 0ustar ghudsonlibuuid#include #include #include #include #include #include #include "k5-platform.h" /* pull in asprintf decl/defn */ #include "test_ccapi_util.h" // --------------------------------------------------------------------------- cc_int32 destroy_all_ccaches(cc_context_t context) { cc_int32 err = ccNoError; cc_ccache_t ccache = NULL; while (!err) { err = cc_context_open_default_ccache(context, &ccache); if (!err) { err = cc_ccache_destroy(ccache); } } if (err == ccErrCCacheNotFound) { err = ccNoError; } else { log_error("cc_context_open_default_ccache or cc_ccache_destroy failed with %s (%d)", translate_ccapi_error(err), err); } return err; } // --------------------------------------------------------------------------- cc_int32 new_v5_creds_union (cc_credentials_union *out_union, const char *realm) { cc_int32 err = ccNoError; cc_credentials_union *cred_union = NULL; cc_credentials_v5_t *v5creds = NULL; static int num_runs = 1; char *client = NULL; char *server = NULL; if (!out_union) { err = ccErrBadParam; } if (!err) { v5creds = malloc (sizeof (*v5creds)); if (!v5creds) { err = ccErrNoMem; } } if (!err) { asprintf(&client, "client@%s", realm); asprintf(&server, "host/%d%s@%s", num_runs++, realm, realm); if (!client || !server) { err = ccErrNoMem; } } if (!err) { v5creds->client = client; v5creds->server = server; v5creds->keyblock.type = 1; v5creds->keyblock.length = 0; v5creds->keyblock.data = NULL; v5creds->authtime = time (NULL); v5creds->starttime = time (NULL); v5creds->endtime = time(NULL) + 1000; v5creds->renew_till = time(NULL) + 10000; v5creds->is_skey = 0; v5creds->ticket_flags = TKT_FLG_FORWARDABLE | TKT_FLG_PROXIABLE | TKT_FLG_RENEWABLE | TKT_FLG_INITIAL; v5creds->addresses = NULL; v5creds->ticket.type = 0; v5creds->ticket.length = 0; v5creds->ticket.data = NULL; v5creds->second_ticket.type = 0; v5creds->second_ticket.length = 0; v5creds->second_ticket.data = NULL; v5creds->authdata = NULL; } if (!err) { cred_union = malloc (sizeof (*cred_union)); if (cred_union) { cred_union->version = cc_credentials_v5; cred_union->credentials.credentials_v5 = v5creds; } else { err = ccErrNoMem; } } if (!err) { *out_union = *cred_union; cred_union = NULL; } return err; } // --------------------------------------------------------------------------- void release_v5_creds_union(cc_credentials_union *creds_union) { cc_credentials_v5_t *v5creds = NULL; if (creds_union) { if (creds_union->credentials.credentials_v5) { v5creds = creds_union->credentials.credentials_v5; if (v5creds->client) { free(v5creds->client); } if (v5creds->server) { free(v5creds->server); } if (v5creds->keyblock.data) { free(v5creds->keyblock.data); } if (v5creds->ticket.data) { free(v5creds->ticket.data); } if (v5creds->second_ticket.data) { free(v5creds->second_ticket.data); } free(v5creds); } //free(creds_union); } } // --------------------------------------------------------------------------- // return zero when both unions are considered equal, non-zero when not int compare_v5_creds_unions(const cc_credentials_union *a, const cc_credentials_union *b) { int retval = -1; if (a && b && (a->version == cc_credentials_v5) && (a->version == b->version) && (strcmp(a->credentials.credentials_v5->client, b->credentials.credentials_v5->client) == 0) && (strcmp(a->credentials.credentials_v5->server, b->credentials.credentials_v5->server) == 0)) { retval = 0; } return retval; } krb5-1.16/src/ccapi/test/test_ccapi_context.c0000644000704600001450000007430313211554426021060 0ustar ghudsonlibuuid#include #include "test_ccapi_context.h" #include #include "test_ccapi_check.h" #include "test_ccapi_util.h" int check_cc_initialize(void) { cc_int32 err = 0; cc_context_t context = NULL; BEGIN_TEST("cc_initialize"); // try every api_version err = check_once_cc_initialize(&context, ccapi_version_2, NULL, NULL, ccNoError, "cc_initialize with ccapi_version_2"); // err == CC_BAD_API_VERSION (9) would be imported by CredentialsCache2.h err = check_once_cc_initialize(&context, ccapi_version_3, NULL, NULL, ccNoError, "cc_initialize with ccapi_version_3"); // !err err = check_once_cc_initialize(&context, ccapi_version_4, NULL, NULL, ccNoError, "cc_initialize with ccapi_version_4"); // " err = check_once_cc_initialize(&context, ccapi_version_5, NULL, NULL, ccNoError, "cc_initialize with ccapi_version_5"); // " err = check_once_cc_initialize(&context, ccapi_version_6, NULL, NULL, ccNoError, "cc_initialize with ccapi_version_6"); // " // try bad api_version err = check_once_cc_initialize(&context, INT_MAX, NULL, NULL, ccErrBadAPIVersion, NULL); // err == ccErrBadAPIVersion // try bad param err = check_once_cc_initialize(NULL, ccapi_version_3, NULL, NULL, ccErrBadParam, NULL); // err == ccErrBadParam END_TEST_AND_RETURN } cc_int32 check_once_cc_initialize(cc_context_t *out_context, cc_int32 in_version, cc_int32 *out_supported_version, char const **out_vendor, cc_int32 expected_err, const char *description) { cc_int32 err = 0; cc_context_t context; cc_int32 possible_return_values[4] = { ccNoError, ccErrNoMem, ccErrBadAPIVersion, ccErrBadParam, }; BEGIN_CHECK_ONCE(description); #define possible_ret_val_count sizeof(possible_return_values)/sizeof(possible_return_values[0]) err = cc_initialize(out_context, in_version, out_supported_version, out_vendor); // check returned error check_err(err, expected_err, possible_return_values); if (out_context) { context = *out_context; } else { context = NULL; } // check output parameters if (!err) { check_if(context == NULL, NULL); if (context) { cc_context_release(context); *out_context = NULL; } } else { check_if(context != NULL, NULL); } return err; } int check_cc_context_release(void) { cc_int32 err = 0; cc_context_t context = NULL; BEGIN_TEST("cc_context_release"); #ifndef cc_context_release log_error("cc_context_release is not implemented yet"); failure_count++; #else // try with valid context err = check_once_cc_context_release(&context, ccNoError, NULL); // try with NULL //err = check_once_cc_context_release(NULL, ccErrInvalidContext); /* calling with NULL context crashes, because this macro expands to ((NULL) -> functions -> release (NULL)) which is dereferencing NULL which is bad. */ if (context) { cc_context_release(context); } #endif /* cc_context_release */ END_TEST_AND_RETURN } cc_int32 check_once_cc_context_release(cc_context_t *out_context, cc_int32 expected_err, const char *description) { cc_int32 err = 0; cc_context_t context = NULL; cc_int32 possible_return_values[2] = { ccNoError, ccErrInvalidContext, }; BEGIN_CHECK_ONCE(description); #ifdef cc_context_release #define possible_ret_val_count sizeof(possible_return_values)/sizeof(possible_return_values[0]) if (out_context) { err = cc_initialize(out_context, ccapi_version_3, NULL, NULL); if (!err) { context = *out_context; } } if (err != ccNoError) { log_error("failure in cc_initialize, unable to perform check"); return err; } else { err = cc_context_release(context); // check returned error check_err(err, expected_err, possible_return_values); } *out_context = NULL; #endif /* cc_context_release */ END_CHECK_ONCE; return err; } int check_cc_context_get_change_time(void) { cc_int32 err = 0; cc_context_t context = NULL; cc_time_t last_change_time = 0; cc_ccache_t ccache = NULL; cc_credentials_union creds_union; cc_credentials_iterator_t creds_iterator = NULL; cc_credentials_t credentials = NULL; BEGIN_TEST("cc_context_get_change_time"); #ifndef cc_context_get_change_time log_error("cc_context_get_change_time is not implemented yet"); failure_count++; #else /* * Make a context * make sure the change time changes after: * a ccache is created * a ccache is destroyed * a credential is stored * a credential is removed * a ccache principal is changed * the default ccache is changed * clean up memory */ err = cc_initialize(&context, ccapi_version_3, NULL, NULL); if (!err) { // try bad parameters first err = check_once_cc_context_get_change_time(context, NULL, ccErrBadParam, "NULL param, should fail"); // make sure we have a default ccache err = cc_context_open_default_ccache(context, &ccache); if (err == ccErrCCacheNotFound) { err = cc_context_create_default_ccache(context, cc_credentials_v5, "foo/bar@BAZ.ORG", &ccache); } if (!err) { err = cc_ccache_release(ccache); } // either the default ccache already existed or we just created it // either way, the get_change_time should now give something > 0 check_once_cc_context_get_change_time(context, &last_change_time, ccNoError, "first-run, should be > 0"); // create a ccache err = cc_context_create_new_ccache(context, cc_credentials_v5, "foo@BAR.ORG", &ccache); check_once_cc_context_get_change_time(context, &last_change_time, ccNoError, "after creating a new ccache"); // store a credential if (!err) { new_v5_creds_union(&creds_union, "BAR.ORG"); err = cc_ccache_store_credentials(ccache, &creds_union); release_v5_creds_union(&creds_union); } check_once_cc_context_get_change_time(context, &last_change_time, ccNoError, "after storing a credential"); if (!err) { // change principal (fails with ccErrBadInternalMessage) err = cc_ccache_set_principal(ccache, cc_credentials_v5, "foo@BAR.ORG"); if (err) { log_error("failed to change ccache's principal - %s (%d)", translate_ccapi_error(err), err); failure_count++; err = ccNoError; } } check_once_cc_context_get_change_time(context, &last_change_time, ccNoError, "after changing a principle"); // remove a credential if (!err) { err = cc_ccache_new_credentials_iterator(ccache, &creds_iterator); } if (!err) { err = cc_credentials_iterator_next(creds_iterator, &credentials); } if (err == ccIteratorEnd) { err = ccNoError; } if (!err) { err = cc_ccache_remove_credentials(ccache, credentials); } check_once_cc_context_get_change_time(context, &last_change_time, ccNoError, "after removing a credential"); if (!err) { // change default ccache err = cc_ccache_set_default(ccache); check_once_cc_context_get_change_time(context, &last_change_time, ccNoError, "after changing default ccache"); } if (ccache) { // destroy a ccache err = cc_ccache_destroy(ccache); check_once_cc_context_get_change_time(context, &last_change_time, ccNoError, "after destroying a ccache"); } } if (context) { cc_context_release(context); } #endif /* cc_get_change_time */ END_TEST_AND_RETURN } cc_int32 check_once_cc_context_get_change_time(cc_context_t context, cc_time_t *time, cc_int32 expected_err, const char *description) { cc_int32 err = 0; cc_time_t last_change_time; cc_time_t current_change_time = 0; cc_int32 possible_return_values[3] = { ccNoError, ccErrInvalidContext, ccErrBadParam, }; BEGIN_CHECK_ONCE(description); #ifdef cc_context_get_change_time #define possible_ret_val_count sizeof(possible_return_values)/sizeof(possible_return_values[0]) if (time != NULL) { // if we were passed NULL, then we're looking to pass a bad param err = cc_context_get_change_time(context, ¤t_change_time); } else { err = cc_context_get_change_time(context, NULL); } check_err(err, expected_err, possible_return_values); if (!err) { last_change_time = *time; check_if(current_change_time <= last_change_time, "context change time did not increase when it was supposed to (%d <= %d)", current_change_time, last_change_time); *time = current_change_time; } #endif /* cc_context_get_change_time */ END_CHECK_ONCE; return err; } int check_cc_context_get_default_ccache_name(void) { cc_int32 err = 0; cc_context_t context = NULL; cc_ccache_t ccache = NULL; cc_string_t name = NULL; BEGIN_TEST("cc_context_get_default_ccache_name"); #ifndef cc_context_get_default_ccache_name log_error("cc_context_get_default_ccache_name is not implemented yet"); failure_count++; #else err = cc_initialize(&context, ccapi_version_3, NULL, NULL); if (!err) { // try bad parameters first err = check_once_cc_context_get_default_ccache_name(context, NULL, ccErrBadParam, NULL); // try with no default err = destroy_all_ccaches(context); err = cc_context_open_default_ccache(context, &ccache); if (err != ccErrCCacheNotFound) { log_error("didn't remove all ccaches"); } err = check_once_cc_context_get_default_ccache_name(context, &name, ccNoError, NULL); // try normally err = cc_context_create_default_ccache(context, cc_credentials_v5, "foo@BAR.ORG", &ccache); if (ccache) { cc_ccache_release(ccache); } err = check_once_cc_context_get_default_ccache_name(context, &name, ccNoError, NULL); } if (context) { cc_context_release(context); } #endif /* cc_context_get_default_ccache_name */ END_TEST_AND_RETURN } cc_int32 check_once_cc_context_get_default_ccache_name(cc_context_t context, cc_string_t *name, cc_int32 expected_err, const char *description) { cc_int32 err = 0; cc_int32 possible_return_values[4] = { ccNoError, ccErrInvalidContext, ccErrBadParam, ccErrNoMem, }; BEGIN_CHECK_ONCE(description); #ifdef cc_context_get_default_ccache_name #define possible_ret_val_count sizeof(possible_return_values)/sizeof(possible_return_values[0]) if (name != NULL) { // if we were passed NULL, then we're looking to pass a bad param err = cc_context_get_default_ccache_name(context, name); } else { err = cc_context_get_default_ccache_name(context, NULL); } // check returned error check_err(err, expected_err, possible_return_values); // not really anything else to check if (name && *name) { cc_string_release(*name); } #endif /* cc_context_get_default_ccache_name */ END_CHECK_ONCE; return err; } int check_cc_context_open_ccache(void) { cc_int32 err = 0; cc_context_t context = NULL; cc_ccache_t ccache = NULL; cc_string_t name = NULL; BEGIN_TEST("cc_context_open_ccache"); #ifndef cc_context_open_ccache log_error("cc_context_open_ccache is not implemented yet"); failure_count++; #else err = cc_initialize(&context, ccapi_version_3, NULL, NULL); if (!err) { // make sure we have a default ccache err = cc_context_open_default_ccache(context, &ccache); if (err == ccErrCCacheNotFound) { err = cc_context_create_default_ccache(context, cc_credentials_v5, "foo/bar@BAZ.ORG", &ccache); } if (!err) { err = cc_ccache_release(ccache); ccache = NULL; } // try default ccache err = cc_context_get_default_ccache_name(context, &name); if (!err) { err = check_once_cc_context_open_ccache(context, name->data, &ccache, ccNoError, NULL); } // try bad parameters err = check_once_cc_context_open_ccache(context, NULL, &ccache, ccErrBadParam, NULL); err = check_once_cc_context_open_ccache(context, name->data, NULL, ccErrBadParam, NULL); // try a ccache that doesn't exist (create one and then destroy it) err = cc_context_create_new_ccache(context, cc_credentials_v5, "foo@BAR.ORG", &ccache); if (!err) { err = cc_ccache_get_name(ccache, &name); } if (!err) { err = cc_ccache_destroy(ccache); ccache = NULL; } err = check_once_cc_context_open_ccache(context, name->data, &ccache, ccErrCCacheNotFound, NULL); } if (context) { cc_context_release(context); } #endif /* cc_context_open_ccache */ END_TEST_AND_RETURN } cc_int32 check_once_cc_context_open_ccache(cc_context_t context, const char *name, cc_ccache_t *ccache, cc_int32 expected_err, const char *description) { cc_int32 err = 0; cc_string_t stored_name = NULL; cc_int32 possible_return_values[6] = { ccNoError, ccErrBadName, ccErrInvalidContext, ccErrNoMem, ccErrCCacheNotFound, ccErrBadParam, }; BEGIN_CHECK_ONCE(description); #ifdef cc_context_open_ccache #define possible_ret_val_count sizeof(possible_return_values)/sizeof(possible_return_values[0]) if (ccache != NULL) { // if we were passed NULL, then we're looking to pass a bad param err = cc_context_open_ccache(context, name, ccache); } else { err = cc_context_open_ccache(context, name, NULL); } // check returned error check_err(err, expected_err, possible_return_values); if (!err) { check_if(*ccache == NULL, NULL); if (!err) { err = cc_ccache_get_name(*ccache, &stored_name); } if (!err) { check_if(strcmp(stored_name->data, name), NULL); } if (stored_name) { cc_string_release(stored_name); } if (ccache && *ccache) { cc_ccache_release(*ccache); *ccache = NULL; } } #endif /* cc_context_open_ccache */ END_CHECK_ONCE; return err; } int check_cc_context_open_default_ccache(void) { cc_int32 err = 0; cc_context_t context = NULL; cc_ccache_t ccache = NULL; BEGIN_TEST("cc_context_open_default_ccache"); #ifndef cc_context_open_default_ccache log_error("cc_context_open_default_ccache is not implemented yet"); failure_count++; #else err = cc_initialize(&context, ccapi_version_3, NULL, NULL); if (!err) { // make sure we have a default ccache err = cc_context_create_default_ccache(context, cc_credentials_v5, "foo/bar@BAZ.ORG", &ccache); if (ccache) { cc_ccache_release(ccache); } // try default ccache if (!err) { err = check_once_cc_context_open_default_ccache(context, &ccache, ccNoError, NULL); } // try bad parameters err = check_once_cc_context_open_default_ccache(context, NULL, ccErrBadParam, NULL); // try with no default ccache (destroy all ccaches first) err = destroy_all_ccaches(context); err = check_once_cc_context_open_default_ccache(context, &ccache, ccErrCCacheNotFound, NULL); } if (context) { cc_context_release(context); } #endif /* cc_context_open_default_ccache */ END_TEST_AND_RETURN } cc_int32 check_once_cc_context_open_default_ccache(cc_context_t context, cc_ccache_t *ccache, cc_int32 expected_err, const char *description) { cc_int32 err = 0; cc_string_t given_name = NULL; cc_string_t default_name = NULL; cc_int32 possible_return_values[5] = { ccNoError, ccErrInvalidContext, ccErrNoMem, ccErrCCacheNotFound, ccErrBadParam, }; BEGIN_CHECK_ONCE(description); #ifdef cc_context_open_default_ccache #define possible_ret_val_count sizeof(possible_return_values)/sizeof(possible_return_values[0]) if (ccache != NULL) { // if we were passed NULL, then we're looking to pass a bad param err = cc_context_open_default_ccache(context, ccache); } else { err = cc_context_open_default_ccache(context, NULL); } // check returned error check_err(err, expected_err, possible_return_values); if (!err) { check_if(*ccache == NULL, NULL); // make sure this ccache is the one we were looking to get back (compare name with cc_context_get_default_ccache_name) err = cc_ccache_get_name(*ccache, &given_name); err = cc_context_get_default_ccache_name(context, &default_name); if (given_name && default_name) { check_if(strcmp(given_name->data, default_name->data), "name of ccache returned by cc_context_open_default_ccache doesn't match name returned by cc_context_get_default_ccache_name"); } if (given_name) { cc_string_release(given_name); } if (default_name) { cc_string_release(default_name); } if (ccache && *ccache) { cc_ccache_release(*ccache); *ccache = NULL; } } #endif /* cc_context_open_default_ccache */ END_CHECK_ONCE; return err; } int check_cc_context_create_ccache(void) { cc_int32 err = 0; cc_context_t context = NULL; cc_ccache_t ccache = NULL; cc_string_t name = NULL; BEGIN_TEST("cc_context_create_ccache"); #ifndef cc_context_create_ccache log_error("cc_context_create_ccache is not implemented yet"); failure_count++; #else err = cc_initialize(&context, ccapi_version_3, NULL, NULL); if (!err) { // try making a ccache with a non-unique name (the existing default's name) if (!err) { err = cc_context_create_default_ccache(context, cc_credentials_v5, "foo/bar@BAZ.ORG", &ccache); } if (!err) { err = cc_ccache_get_name(ccache, &name); } if (ccache) { cc_ccache_release(ccache); } if (!err) { err = check_once_cc_context_create_ccache(context, name->data, cc_credentials_v5, "foo@BAR.ORG", &ccache, ccNoError, NULL); } // try making a ccache with a unique name (the now destroyed default's name) if (ccache) { cc_ccache_destroy(ccache); } if (!err) { err = check_once_cc_context_create_ccache(context, name->data, cc_credentials_v5, "foo/baz@BAR.ORG", &ccache, ccNoError, NULL); } // try bad parameters err = check_once_cc_context_create_ccache(context, NULL, cc_credentials_v5, "foo@BAR.ORG", &ccache, ccErrBadParam, "NULL name"); // NULL name err = check_once_cc_context_create_ccache(context, "name", cc_credentials_v4_v5, "foo@BAR.ORG", &ccache, ccErrBadCredentialsVersion, "invalid creds_vers"); // invalid creds_vers err = check_once_cc_context_create_ccache(context, "name", cc_credentials_v5, NULL, &ccache, ccErrBadParam, "NULL principal"); // NULL principal err = check_once_cc_context_create_ccache(context, "name", cc_credentials_v5, "foo@BAR.ORG", NULL, ccErrBadParam, "NULL ccache"); // NULL ccache } if (name) { cc_string_release(name); } if (ccache) { cc_ccache_destroy(ccache); } if (context) { cc_context_release(context); } #endif /* cc_context_create_ccache */ END_TEST_AND_RETURN } cc_int32 check_once_cc_context_create_ccache(cc_context_t context, const char *name, cc_uint32 cred_vers, const char *principal, cc_ccache_t *ccache, cc_int32 expected_err, const char *description) { cc_int32 err = 0; cc_string_t stored_name = NULL; cc_string_t stored_principal = NULL; cc_uint32 stored_creds_vers = 0; cc_int32 possible_return_values[6] = { ccNoError, ccErrBadName, ccErrBadParam, ccErrInvalidContext, ccErrNoMem, ccErrBadCredentialsVersion, }; BEGIN_CHECK_ONCE(description); #ifdef cc_context_create_ccache #define possible_ret_val_count sizeof(possible_return_values)/sizeof(possible_return_values[0]) err = cc_context_create_ccache(context, name, cred_vers, principal, ccache); // check returned error check_err(err, expected_err, possible_return_values); if (!err) { check_if(*ccache == NULL, NULL); // make sure all of the ccache's info matches what we gave it // name err = cc_ccache_get_name(*ccache, &stored_name); if (!err) { check_if(strcmp(stored_name->data, name), NULL); } if (stored_name) { cc_string_release(stored_name); } // cred_vers // FIXME Documented function name of cc_ccache_get_credentials_version is a typo. // FIXME Documented type of creds param the wrong signedness (should be unsigned) for cc_ccache_get_credentials_version, cc_context_create_ccache, cc_context_create_default_ccache, cc_context_create_new_ccache err = cc_ccache_get_credentials_version(*ccache, &stored_creds_vers); if (!err) { check_if(stored_creds_vers != cred_vers, NULL); } // principal err = cc_ccache_get_principal(*ccache, cc_credentials_v5, &stored_principal); if (!err) { check_if(strcmp(stored_principal->data, principal), NULL); } if (stored_principal) { cc_string_release(stored_principal); } if (ccache && *ccache) { cc_ccache_destroy(*ccache); *ccache = NULL; } } #endif /* cc_context_create_ccache */ END_CHECK_ONCE; return err; } int check_cc_context_create_default_ccache(void) { cc_int32 err = 0; cc_context_t context = NULL; cc_ccache_t ccache = NULL; cc_string_t name = NULL; BEGIN_TEST("cc_context_create_default_ccache"); #ifndef cc_context_create_default_ccache log_error("cc_context_create_default_ccache is not implemented yet"); failure_count++; #else err = cc_initialize(&context, ccapi_version_3, NULL, NULL); if (!err) { // try making the default when there are no existing ccaches err = destroy_all_ccaches(context); if (!err) { err = check_once_cc_context_create_default_ccache(context, cc_credentials_v5, "foo@BAR.ORG", &ccache, ccNoError, NULL); } if (ccache) { cc_ccache_release(ccache); } // try making a new default when one already exists if (!err) { err = check_once_cc_context_create_default_ccache(context, cc_credentials_v5, "foo/baz@BAR.ORG", &ccache, ccNoError, NULL); } // try bad parameters err = check_once_cc_context_create_default_ccache(context, cc_credentials_v4_v5, "foo@BAR.ORG", &ccache, ccErrBadCredentialsVersion, "invalid creds_vers"); // invalid creds_vers err = check_once_cc_context_create_default_ccache(context, cc_credentials_v5, NULL, &ccache, ccErrBadParam, "NULL principal"); // NULL principal err = check_once_cc_context_create_default_ccache(context, cc_credentials_v5, "foo@BAR.ORG", NULL, ccErrBadParam, "NULL ccache"); // NULL ccache } if (name) { cc_string_release(name); } if (ccache) { cc_ccache_destroy(ccache); } if (context) { cc_context_release(context); } #endif /* cc_context_create_default_ccache */ END_TEST_AND_RETURN } cc_int32 check_once_cc_context_create_default_ccache(cc_context_t context, cc_uint32 cred_vers, const char *principal, cc_ccache_t *ccache, cc_int32 expected_err, const char *description) { cc_int32 err = 0; cc_string_t stored_principal = NULL; cc_uint32 stored_creds_vers = 0; cc_int32 possible_return_values[6] = { ccNoError, ccErrBadName, // how can this be possible when the name isn't a parameter? ccErrBadParam, ccErrInvalidContext, ccErrNoMem, ccErrBadCredentialsVersion, }; BEGIN_CHECK_ONCE(description); #ifdef cc_context_create_default_ccache #define possible_ret_val_count sizeof(possible_return_values)/sizeof(possible_return_values[0]) err = cc_context_create_default_ccache(context, cred_vers, principal, ccache); // check returned error check_err(err, expected_err, possible_return_values); if (!err) { if (ccache) { check_if(*ccache == NULL, NULL); } // make sure all of the ccache's info matches what we gave it // cred_vers err = cc_ccache_get_credentials_version(*ccache, &stored_creds_vers); if (!err) { check_if(stored_creds_vers != cred_vers, NULL); } // principal err = cc_ccache_get_principal(*ccache, cc_credentials_v5, &stored_principal); if (!err) { check_if(strcmp(stored_principal->data, principal), NULL); } if (stored_principal) { cc_string_release(stored_principal); } if (ccache && *ccache) { cc_ccache_release(*ccache); *ccache = NULL; } } #endif /* cc_context_create_default_ccache */ END_CHECK_ONCE; return err; } int check_cc_context_create_new_ccache(void) { cc_int32 err = 0; cc_context_t context = NULL; cc_ccache_t ccache = NULL; cc_string_t name = NULL; BEGIN_TEST("cc_context_create_new_ccache"); #ifndef cc_context_create_new_ccache log_error("cc_context_create_new_ccache is not implemented yet"); failure_count++; #else err = cc_initialize(&context, ccapi_version_3, NULL, NULL); if (!err) { // try making when there are no existing ccaches (should have name of default) err = destroy_all_ccaches(context); if (!err) { err = check_once_cc_context_create_new_ccache(context, 1, cc_credentials_v5, "foo@BAR.ORG", &ccache, ccNoError, NULL); } if (ccache) { cc_ccache_release(ccache); } // try making a new ccache when one already exists (should not have name of default) if (!err) { err = check_once_cc_context_create_new_ccache(context, 0, cc_credentials_v5, "foo/baz@BAR.ORG", &ccache, ccNoError, NULL); } if (ccache) { cc_ccache_release(ccache); } // try bad parameters err = check_once_cc_context_create_new_ccache(context, 1, cc_credentials_v4_v5, "foo@BAR.ORG", &ccache, ccErrBadCredentialsVersion, "invalid creds_vers"); // invalid creds_vers err = check_once_cc_context_create_new_ccache(context, 1, cc_credentials_v5, NULL, &ccache, ccErrBadParam, "NULL principal"); // NULL principal err = check_once_cc_context_create_new_ccache(context, 1, cc_credentials_v5, "foo@BAR.ORG", NULL, ccErrBadParam, "NULL ccache"); // NULL ccache } if (name) { cc_string_release(name); } if (ccache) { cc_ccache_destroy(ccache); } if (context) { cc_context_release(context); } #endif /* cc_context_create_new_ccache */ END_TEST_AND_RETURN } cc_int32 check_once_cc_context_create_new_ccache(cc_context_t context, cc_int32 should_be_default, cc_uint32 cred_vers, const char *principal, cc_ccache_t *ccache, cc_int32 expected_err, const char *description) { cc_int32 err = 0; cc_string_t name = NULL; cc_string_t stored_name = NULL; cc_string_t stored_principal = NULL; cc_uint32 stored_creds_vers = 0; cc_int32 possible_return_values[6] = { ccNoError, ccErrBadName, // how can this be possible when the name isn't a parameter? ccErrBadParam, ccErrInvalidContext, ccErrNoMem, ccErrBadCredentialsVersion, }; BEGIN_CHECK_ONCE(description); #ifdef cc_context_create_new_ccache #define possible_ret_val_count sizeof(possible_return_values)/sizeof(possible_return_values[0]) err = cc_context_create_new_ccache(context, cred_vers, principal, ccache); // check returned error check_err(err, expected_err, possible_return_values); if (!err) { if (ccache) { check_if(*ccache == NULL, NULL); } // make sure all of the ccache's info matches what we gave it if (!err) { err = cc_context_get_default_ccache_name(context, &name); } if (!err) { err = cc_ccache_get_name(*ccache, &stored_name); } if (!err) { if (should_be_default) { check_if(strcmp(stored_name->data, name->data), "new ccache does not have name of default"); } else { check_if((strcmp(stored_name->data, name->data) == 0), "new cache has name of default"); } } if (name) { cc_string_release(name); } if (stored_name) { cc_string_release(stored_name); } // cred_vers err = cc_ccache_get_credentials_version(*ccache, &stored_creds_vers); if (!err) { check_if(stored_creds_vers != cred_vers, NULL); } // principal err = cc_ccache_get_principal(*ccache, cc_credentials_v5, &stored_principal); if (!err) { check_if(strcmp(stored_principal->data, principal), NULL); } if (stored_principal) { cc_string_release(stored_principal); } if (ccache && *ccache) { cc_ccache_release(*ccache); *ccache = NULL; } } #endif /* cc_context_create_new_ccache */ END_CHECK_ONCE; return err; } int check_cc_context_new_ccache_iterator(void) { cc_int32 err = 0; cc_context_t context = NULL; cc_ccache_t ccache = NULL; cc_string_t name = NULL; cc_ccache_iterator_t iterator = NULL; BEGIN_TEST("cc_context_new_ccache_iterator"); #ifndef cc_context_new_ccache_iterator log_error("cc_context_new_ccache_iterator is not implemented yet"); failure_count++; #else err = cc_initialize(&context, ccapi_version_3, NULL, NULL); if (!err) { err = destroy_all_ccaches(context); } if (!err) { // try making when there are no existing ccaches (shouldn't make a difference, but just in case) check_once_cc_context_new_ccache_iterator(context, &iterator, ccNoError, "when there are no existing ccaches"); err = cc_context_create_default_ccache(context, cc_credentials_v5, "foo@BAR.ORG", &ccache); } if (!err) { // try making when at least one ccache already exists (just to cover all our bases) check_once_cc_context_new_ccache_iterator(context, &iterator, ccNoError, "when at least one ccache already exists"); // try bad parameters check_once_cc_context_new_ccache_iterator(context, NULL, ccErrBadParam, "NULL param"); // NULL iterator } // we'll do a comprehensive test of cc_ccache_iterator related functions later in the test suite if (name) { cc_string_release(name); } if (ccache) { cc_ccache_destroy(ccache); } if (context) { cc_context_release(context); } #endif /* cc_context_new_ccache_iterator */ END_TEST_AND_RETURN } cc_int32 check_once_cc_context_new_ccache_iterator(cc_context_t context, cc_ccache_iterator_t *iterator, cc_int32 expected_err, const char *description) { cc_int32 err = ccNoError; cc_int32 possible_return_values[4] = { ccNoError, ccErrBadParam, ccErrNoMem, ccErrInvalidContext, }; BEGIN_CHECK_ONCE(description); #ifdef cc_context_create_new_ccache #define possible_ret_val_count sizeof(possible_return_values)/sizeof(possible_return_values[0]) err = cc_context_new_ccache_iterator(context, iterator); // check returned error check_err(err, expected_err, possible_return_values); // we'll do a comprehensive test of cc_ccache_iterator related functions later #endif /* cc_context_create_new_ccache */ return err; } // --------------------------------------------------------------------------- int check_cc_context_compare(void) { cc_int32 err = 0; cc_context_t context_a = NULL; cc_context_t context_b = NULL; cc_uint32 equal = 0; BEGIN_TEST("cc_context_compare"); #ifndef cc_context_compare log_error("cc_context_compare is not implemented yet"); failure_count++; #else err = cc_initialize(&context_a, ccapi_version_3, NULL, NULL); if (!err) { err = cc_initialize(&context_b, ccapi_version_3, NULL, NULL); } check_once_cc_context_compare(context_a, context_a, &equal, ccNoError, "valid params, same contexts"); check_once_cc_context_compare(context_a, context_b, &equal, ccNoError, "valid params, different contexts"); check_once_cc_context_compare(context_a, NULL, &equal, ccErrBadParam, "NULL compare_to context"); check_once_cc_context_compare(context_a, context_b, NULL, ccErrBadParam, "NULL out param"); if (context_a) { cc_context_release(context_a); } if (context_b) { cc_context_release(context_b); } #endif /* cc_context_compare */ END_TEST_AND_RETURN } cc_int32 check_once_cc_context_compare(cc_context_t context, cc_context_t compare_to, cc_uint32 *equal, cc_int32 expected_err, const char *description) { cc_int32 err = ccNoError; cc_int32 possible_return_values[4] = { ccNoError, ccErrInvalidContext, ccErrBadParam, ccErrServerUnavailable, }; BEGIN_CHECK_ONCE(description); #ifdef cc_context_compare #define possible_ret_val_count sizeof(possible_return_values)/sizeof(possible_return_values[0]) err = cc_context_compare(context, compare_to, equal); if (!err) { *equal = 0; } // check returned error check_err(err, expected_err, possible_return_values); #endif /* cc_context_compare */ return err; } krb5-1.16/src/ccapi/test/test_cc_create.c0000644000704600001450000000041713211554426020140 0ustar ghudsonlibuuid#include #include #include "test_ccapi_check.h" #include "test_ccapi_constants.h" #include "test_ccapi_v2.h" int main (int argc, const char * argv[]) { cc_int32 err = ccNoError; T_CCAPI_INIT; err = check_cc_create(); return err; } krb5-1.16/src/ccapi/test/test_cc_get_name.c0000644000704600001450000000042113211554426020447 0ustar ghudsonlibuuid#include #include #include "test_ccapi_check.h" #include "test_ccapi_constants.h" #include "test_ccapi_v2.h" int main (int argc, const char * argv[]) { cc_int32 err = ccNoError; T_CCAPI_INIT; err = check_cc_get_name(); return err; } krb5-1.16/src/ccapi/test/test_ccapi_v2.h0000644000704600001450000000711113211554426017721 0ustar ghudsonlibuuid#ifndef _TEST_CCAPI_V2_H_ #define _TEST_CCAPI_V2_H_ #include "test_ccapi_globals.h" #ifdef TARGET_OS_MAC #include #else #include #endif int check_cc_shutdown(void); cc_result check_once_cc_shutdown(apiCB **out_context, cc_result expected_err, const char *description); int check_cc_get_change_time(void); cc_int32 check_once_cc_get_change_time(apiCB *context, cc_time_t *time, cc_result expected_err, const char *description); int check_cc_open(void); cc_result check_once_cc_open(apiCB *context, const char *name, cc_int32 version, ccache_p **ccache, cc_result expected_err, const char *description); int check_cc_create(void); cc_result check_once_cc_create(apiCB *context, const char *name, cc_int32 cred_vers, const char *principal, ccache_p **ccache, cc_int32 expected_err, const char *description); int check_cc_close(void); cc_result check_once_cc_close(apiCB *context, ccache_p *ccache, cc_result expected_err, const char *description); int check_cc_destroy(void); cc_result check_once_cc_destroy(apiCB *context, ccache_p *ccache, cc_int32 expected_err, const char *description); int check_cc_get_cred_version(void); cc_result check_once_cc_get_cred_version(apiCB *context, ccache_p *ccache, cc_int32 expected_cred_vers, cc_int32 expected_err, const char *description); int check_cc_get_name(void); cc_int32 check_once_cc_get_name(apiCB *context, ccache_p *ccache, const char *expected_name, cc_int32 expected_err, const char *description); int check_cc_get_principal(void); cc_result check_once_cc_get_principal(apiCB *context, ccache_p *ccache, const char *expected_principal, cc_int32 expected_err, const char *description); int check_cc_set_principal(void); cc_int32 check_once_cc_set_principal(apiCB *context, ccache_p *ccache, cc_int32 cred_vers, const char *in_principal, cc_int32 expected_err, const char *description); int check_cc_store(void); cc_result check_once_cc_store(apiCB *context, ccache_p *ccache, const cred_union in_creds, cc_int32 expected_err, const char *description); int check_cc_remove_cred(void); cc_result check_once_cc_remove_cred(apiCB *context, ccache_p *ccache, cred_union in_creds, cc_int32 expected_err, const char *description); int check_cc_seq_fetch_NCs_begin(void); cc_result check_once_cc_seq_fetch_NCs_begin(apiCB *context, ccache_cit **iterator, cc_result expected_err, const char *description); int check_cc_seq_fetch_NCs_next(void); cc_result check_once_cc_seq_fetch_NCs_next(apiCB *context, ccache_cit *iterator, cc_uint32 expected_count, cc_result expected_err, const char *description); int check_cc_get_NC_info(void); cc_result check_once_cc_get_NC_info(apiCB *context, const char *expected_name, const char *expected_principal, cc_int32 expected_version, cc_uint32 expected_count, cc_result expected_err, const char *description); int check_cc_seq_fetch_creds_begin(void); cc_result check_once_cc_seq_fetch_creds_begin(apiCB *context, ccache_p *ccache, ccache_cit **iterator, cc_result expected_err, const char *description); int check_cc_seq_fetch_creds_next(void); cc_result check_once_cc_seq_fetch_creds_next(apiCB *context, ccache_cit *iterator, cc_uint32 expected_count, cc_result expected_err, const char *description); #endif /* _TEST_CCAPI_V2_H_ */ krb5-1.16/src/ccapi/test/test_constants.c0000644000704600001450000000045213211554426020243 0ustar ghudsonlibuuid#include #include #include "test_ccapi_check.h" #include "test_ccapi_constants.h" #include "test_ccapi_context.h" #include "test_ccapi_ccache.h" int main (int argc, const char * argv[]) { cc_int32 err = ccNoError; T_CCAPI_INIT; err = check_constants(); return err; } krb5-1.16/src/ccapi/test/test_cc_ccache_destroy.c0000644000704600001450000000046213211554426021654 0ustar ghudsonlibuuid#include #include #include "test_ccapi_check.h" #include "test_ccapi_constants.h" #include "test_ccapi_context.h" #include "test_ccapi_ccache.h" int main (int argc, const char * argv[]) { cc_int32 err = ccNoError; T_CCAPI_INIT; err = check_cc_ccache_destroy(); return err; } krb5-1.16/src/ccapi/test/test_cc_ccache_get_name.c0000644000704600001450000000046313211554426021743 0ustar ghudsonlibuuid#include #include #include "test_ccapi_check.h" #include "test_ccapi_constants.h" #include "test_ccapi_context.h" #include "test_ccapi_ccache.h" int main (int argc, const char * argv[]) { cc_int32 err = ccNoError; T_CCAPI_INIT; err = check_cc_ccache_get_name(); return err; } krb5-1.16/src/ccapi/test/test_ccapi_log.h0000644000704600001450000000112313211554426020150 0ustar ghudsonlibuuid#ifndef _TEST_CCAPI_LOG_H_ #define _TEST_CCAPI_LOG_H_ #include #include #include "test_ccapi_globals.h" #define log_error(format, ...) \ _log_error(__FILE__, __LINE__, format , ## __VA_ARGS__) void _log_error_v(const char *file, int line, const char *format, va_list ap); void _log_error(const char *file, int line, const char *format, ...) #if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 7) __attribute__ ((__format__ (__printf__, 3, 4))) #endif ; void test_header(const char *msg); void test_footer(const char *msg, int err); #endif /* _TEST_CCAPI_LOG_H_ */ krb5-1.16/src/ccapi/test/test_cc_ccache_set_principal.c0000644000704600001450000000047013211554426023016 0ustar ghudsonlibuuid#include #include #include "test_ccapi_check.h" #include "test_ccapi_constants.h" #include "test_ccapi_context.h" #include "test_ccapi_ccache.h" int main (int argc, const char * argv[]) { cc_int32 err = ccNoError; T_CCAPI_INIT; err = check_cc_ccache_set_principal(); return err; } krb5-1.16/src/ccapi/test/test_ccapi.bat0000644000704600001450000000300113211554426017623 0ustar ghudsonlibuuid# test_ccapi.bat @echo "\nBeginning test of CCAPI...\n" @echo "\nThese tests are based on the CCAPI v3 revision 8 draft documentation.\n" #run_test simple_lock_test teststest_constants.exe tests\test_cc_initialize.exe tests\test_cc_context_get_version.exe exit 0 tests\test_cc_context_release.exe tests\test_cc_context_get_change_time.exe tests\test_cc_context_get_default_ccache_name.exe tests\test_cc_context_open_ccache.exe tests\test_cc_context_open_default_ccache.exe tests\test_cc_context_create_ccache.exe tests\test_cc_context_create_default_ccache.exe tests\test_cc_context_create_new_ccache.exe tests\test_cc_context_new_ccache_iterator.exe tests\test_cc_context_compare.exe tests\test_cc_ccache_release.exe tests\test_cc_ccache_destroy.exe tests\test_cc_ccache_set_default.exe tests\test_cc_ccache_get_credentials_version.exe tests\test_cc_ccache_get_name.exe tests\test_cc_ccache_get_principal.exe tests\test_cc_ccache_set_principal.exe tests\test_cc_ccache_store_credentials.exe tests\test_cc_ccache_remove_credentials.exe tests\test_cc_ccache_new_credentials_iterator.exe tests\test_cc_ccache_get_change_time.exe tests\test_cc_ccache_get_last_default_time.exe tests\test_cc_ccache_move.exe tests\test_cc_ccache_compare.exe tests\test_cc_ccache_get_kdc_time_offset.exe tests\test_cc_ccache_set_kdc_time_offset.exe tests\test_cc_ccache_clear_kdc_time_offset.exe tests\test_cc_ccache_iterator_next.exe tests\test_cc_credentials_iterator_next.exe @echo "Finished testing CCAPI." krb5-1.16/src/ccapi/test/test_ccapi_check.c0000644000704600001450000000150213211554426020440 0ustar ghudsonlibuuid#include "test_ccapi_check.h" int _check_if(int expression, const char *file, int line, const char *expression_string, const char *format, ...) { if (expression) { failure_count++; // call with NULL format to get a generic error message if (format == NULL) { _log_error(file, line, expression_string); } // call with format and varargs for a more useful error message else { va_list ap; va_start(ap, format); _log_error_v(file, line, format, ap); va_end(ap); } if (current_test_activity) { fprintf(stdout, " (%s)", current_test_activity); } } return (expression != 0); } int array_contains_int(cc_int32 *array, int size, cc_int32 value) { if (array != NULL && size > 0) { int i = 0; while (i < size && array[i] != value) { i++; } if (i < size) { return 1; } } return 0; } krb5-1.16/src/ccapi/test/test_cc_context_create_default_ccache.c0000644000704600001450000000050113211554426024670 0ustar ghudsonlibuuid#include #include #include "test_ccapi_check.h" #include "test_ccapi_constants.h" #include "test_ccapi_context.h" #include "test_ccapi_ccache.h" int main (int argc, const char * argv[]) { cc_int32 err = ccNoError; T_CCAPI_INIT; err = check_cc_context_create_default_ccache(); return err; } krb5-1.16/src/ccapi/test/test_cc_seq_fetch_NCs_begin.c0000644000704600001450000000043413211554426022544 0ustar ghudsonlibuuid#include #include #include "test_ccapi_check.h" #include "test_ccapi_constants.h" #include "test_ccapi_v2.h" int main (int argc, const char * argv[]) { cc_int32 err = ccNoError; T_CCAPI_INIT; err = check_cc_seq_fetch_NCs_begin(); return err; } krb5-1.16/src/ccapi/test/test_cc_context_create_new_ccache.c0000644000704600001450000000047513211554426024047 0ustar ghudsonlibuuid#include #include #include "test_ccapi_check.h" #include "test_ccapi_constants.h" #include "test_ccapi_context.h" #include "test_ccapi_ccache.h" int main (int argc, const char * argv[]) { cc_int32 err = ccNoError; T_CCAPI_INIT; err = check_cc_context_create_new_ccache(); return err; } krb5-1.16/src/ccapi/test/main.c0000644000704600001450000000546013211554426016120 0ustar ghudsonlibuuid#include #include // #include #include "test_ccapi_check.h" #include "test_ccapi_constants.h" #include "test_ccapi_context.h" #include "test_ccapi_ccache.h" #include "test_ccapi_iterators.h" #include "test_ccapi_v2.h" int main (int argc, const char * argv[]) { cc_int32 err = ccNoError; // cc_ccache_iterator_t cache_iterator = NULL; // cc_credentials_iterator_t cred_iterator = NULL; fprintf(stdout, "Testing CCAPI against CCAPI v3 rev 8 documentation...\n"); fprintf(stdout, "Warning: this test suite is woefully incomplete and unpolished.\n"); T_CCAPI_INIT; // *** ccapi v2 compat *** err = check_cc_shutdown(); err = check_cc_get_change_time(); err = check_cc_open(); err = check_cc_create(); err = check_cc_close(); err = check_cc_destroy(); err = check_cc_get_cred_version(); err = check_cc_get_name(); err = check_cc_get_principal(); err = check_cc_set_principal(); err = check_cc_store(); err = check_cc_remove_cred(); err = check_cc_seq_fetch_NCs_begin(); err = check_cc_seq_fetch_NCs_next(); err = check_cc_seq_fetch_creds_begin(); err = check_cc_seq_fetch_creds_next(); err = check_cc_get_NC_info(); err = check_constants(); // *** cc_context *** err = check_cc_initialize(); err = check_cc_context_release(); err = check_cc_context_get_change_time(); err = check_cc_context_get_default_ccache_name(); err = check_cc_context_open_ccache(); err = check_cc_context_open_default_ccache(); err = check_cc_context_create_ccache(); err = check_cc_context_create_default_ccache(); err = check_cc_context_create_new_ccache(); err = check_cc_context_new_ccache_iterator(); // err = check_cc_context_lock(); // err = check_cc_context_unlock(); err = check_cc_context_compare(); // *** cc_ccache *** err = check_cc_ccache_release(); err = check_cc_ccache_destroy(); err = check_cc_ccache_set_default(); err = check_cc_ccache_get_credentials_version(); err = check_cc_ccache_get_name(); err = check_cc_ccache_get_principal(); err = check_cc_ccache_set_principal(); err = check_cc_ccache_store_credentials(); err = check_cc_ccache_remove_credentials(); err = check_cc_ccache_new_credentials_iterator(); // err = check_cc_ccache_lock(); // err = check_cc_ccache_unlock(); err = check_cc_ccache_get_change_time(); err = check_cc_ccache_get_last_default_time(); err = check_cc_ccache_move(); err = check_cc_ccache_compare(); err = check_cc_ccache_get_kdc_time_offset(); err = check_cc_ccache_set_kdc_time_offset(); err = check_cc_ccache_clear_kdc_time_offset(); // *** cc_ccache_iterator *** err = check_cc_ccache_iterator_next(); // *** cc_credentials_iterator *** err = check_cc_credentials_iterator_next(); fprintf(stdout, "\nFinished testing CCAPI. %d failure%s in total.\n", total_failure_count, (total_failure_count == 1) ? "" : "s"); return err; } krb5-1.16/src/ccapi/test/test_cc_get_NC_info.c0000644000704600001450000000042413211554426021045 0ustar ghudsonlibuuid#include #include #include "test_ccapi_check.h" #include "test_ccapi_constants.h" #include "test_ccapi_v2.h" int main (int argc, const char * argv[]) { cc_int32 err = ccNoError; T_CCAPI_INIT; err = check_cc_get_NC_info(); return err; } krb5-1.16/src/ccapi/test/test_cc_credentials_iterator_next.c0000644000704600001450000000053713211554426024144 0ustar ghudsonlibuuid#include #include #include "test_ccapi_check.h" #include "test_ccapi_constants.h" #include "test_ccapi_context.h" #include "test_ccapi_ccache.h" #include "test_ccapi_iterators.h" int main (int argc, const char * argv[]) { cc_int32 err = ccNoError; T_CCAPI_INIT; err = check_cc_credentials_iterator_next(); return err; } krb5-1.16/src/ccapi/test/test_cc_ccache_new_credentials_iterator.c0000644000704600001450000000050313211554426025236 0ustar ghudsonlibuuid#include #include #include "test_ccapi_check.h" #include "test_ccapi_constants.h" #include "test_ccapi_context.h" #include "test_ccapi_ccache.h" int main (int argc, const char * argv[]) { cc_int32 err = ccNoError; T_CCAPI_INIT; err = check_cc_ccache_new_credentials_iterator(); return err; } krb5-1.16/src/ccapi/test/test_cc_ccache_get_change_time.c0000644000704600001450000000047213211554426023266 0ustar ghudsonlibuuid#include #include #include "test_ccapi_check.h" #include "test_ccapi_constants.h" #include "test_ccapi_context.h" #include "test_ccapi_ccache.h" int main (int argc, const char * argv[]) { cc_int32 err = ccNoError; T_CCAPI_INIT; err = check_cc_ccache_get_change_time(); return err; } krb5-1.16/src/ccapi/test/test_cc_seq_fetch_creds_begin.c0000644000704600001450000000043613211554426023163 0ustar ghudsonlibuuid#include #include #include "test_ccapi_check.h" #include "test_ccapi_constants.h" #include "test_ccapi_v2.h" int main (int argc, const char * argv[]) { cc_int32 err = ccNoError; T_CCAPI_INIT; err = check_cc_seq_fetch_creds_begin(); return err; } krb5-1.16/src/ccapi/test/test_cc_ccache_store_credentials.c0000644000704600001450000000047413211554426023677 0ustar ghudsonlibuuid#include #include #include "test_ccapi_check.h" #include "test_ccapi_constants.h" #include "test_ccapi_context.h" #include "test_ccapi_ccache.h" int main (int argc, const char * argv[]) { cc_int32 err = ccNoError; T_CCAPI_INIT; err = check_cc_ccache_store_credentials(); return err; } krb5-1.16/src/ccapi/test/Makefile.w320000644000704600001450000000363313211554426017102 0ustar ghudsonlibuuid# . is ccapi/test. CO = ..\common COWIN = $(CO)\win LIBDIR = ..\lib LIBWIN = $(LIBDIR)\win SRV = ..\server SRVWIN = ..\server\win !include INC = -I..\..\include -I..\..\util\et -I$(CO) -I$(COWIN) -I$(LIBDIR) -I$(LIBWIN) !if "$(CPU)" == "i386" cflags = $(cflags) /EHsc /MTd -D_CRTAPI1=_cdecl -D_CRTAPI2=_cdecl -DWINVER=0x0501 -D_WIN32_WINNT=0x0501 \ $(INC) !else cflags = $(cflags) /W3 -D_CRTAPI1= -D_CRTAPI2= $(INC) !endif LIBS = $(LIBWIN)\ccapi.lib DSTROOT = . SRC = $(DSTROOT) #OBJDIR = $(DSTROOT)\obj OBJDIR = . OBJEXT = obj TESTDIR = $(DSTROOT)\tests TESTEXT = exe DSTDIR = $(DSTROOT)\ccapi_tests PINGOBJS = pingtest.obj SIMPLEOBJS = simple_lock_test.obj comobjs = cci_debugging.obj cci_stream.obj cowobjs = cci_os_debugging.obj libobjs = ccs_request_c.obj #all: build-base simple_lock_test pingtest all: build-base pingtest # compile base files used by all tests build-base: $(comobjs) $(libobjs) $(srvobjs) @echo "Base objects built." # rule to compile src files .c.obj: $(cc) $(cdebug) $(cflags) /Fo$(OBJDIR)\$(*B).$(OBJEXT) $(SRC)\$(*B).c $(comobjs) : $(CO)\$(*B).c $(cc) $(cdebug) $(cflags) $(CO)\$(*B).c $(cowobjs) : $(COWIN)\$(*B).c $(cc) $(cdebug) $(cflags) $(COWIN)\$(*B).c $(libobjs) : $(LIBWIN)\$(*B).c $(cc) $(cdebug) $(cflags) $(LIBWIN)\$(*B).c #$(srvobjs) : $(SRVWIN)\$*.c # $(cc) $(cdebug) $(cflags) $(SRVWIN)\$*.c simple_lock_test: simple_lock_test.obj $(OBJS) @echo R3+ Build $(*B) in $(TESTDIR) $(cc) $(cdebug) $(cflags) $(*B).c $(link) $(linkdebug) $(conflags) -out:$(TESTDIR)\$(*B).exe $(*B).obj \ $(LIBS) rpcrt4.lib @echo R3- Built $(*B) in $(TESTDIR) pingtest: pingtest.obj @echo R4+ Build $(*B) in $(TESTDIR) $(cc) $(cdebug) $(cflags) $(*B).c $(link) $(linkdebug) $(conflags) -out:$(*B).exe $(PINGOBJS) $(libobjs) $(srvobjs) \ $(LIBS) rpcrt4.lib @echo R4- Built $(*B) in $(TESTDIR) clean: DEL *.$(OBJEXT)krb5-1.16/src/ccapi/test/test_cc_ccache_remove_credentials.c0000644000704600001450000000047513211554426024041 0ustar ghudsonlibuuid#include #include #include "test_ccapi_check.h" #include "test_ccapi_constants.h" #include "test_ccapi_context.h" #include "test_ccapi_ccache.h" int main (int argc, const char * argv[]) { cc_int32 err = ccNoError; T_CCAPI_INIT; err = check_cc_ccache_remove_credentials(); return err; } krb5-1.16/src/ccapi/test/test_cc_shutdown.c0000644000704600001450000000042113211554426020543 0ustar ghudsonlibuuid#include #include #include "test_ccapi_check.h" #include "test_ccapi_constants.h" #include "test_ccapi_v2.h" int main (int argc, const char * argv[]) { cc_int32 err = ccNoError; T_CCAPI_INIT; err = check_cc_shutdown(); return err; } krb5-1.16/src/ccapi/test/test_cc_ccache_compare.c0000644000704600001450000000046213211554426021611 0ustar ghudsonlibuuid#include #include #include "test_ccapi_check.h" #include "test_ccapi_constants.h" #include "test_ccapi_context.h" #include "test_ccapi_ccache.h" int main (int argc, const char * argv[]) { cc_int32 err = ccNoError; T_CCAPI_INIT; err = check_cc_ccache_compare(); return err; } krb5-1.16/src/ccapi/test/test_cc_context_get_default_ccache_name.c0000644000704600001450000000050313211554426025206 0ustar ghudsonlibuuid#include #include #include "test_ccapi_check.h" #include "test_ccapi_constants.h" #include "test_ccapi_context.h" #include "test_ccapi_ccache.h" int main (int argc, const char * argv[]) { cc_int32 err = ccNoError; T_CCAPI_INIT; err = check_cc_context_get_default_ccache_name(); return err; } krb5-1.16/src/ccapi/test/test_cc_context_open_ccache.c0000644000704600001450000000046713211554426022675 0ustar ghudsonlibuuid#include #include #include "test_ccapi_check.h" #include "test_ccapi_constants.h" #include "test_ccapi_context.h" #include "test_ccapi_ccache.h" int main (int argc, const char * argv[]) { cc_int32 err = ccNoError; T_CCAPI_INIT; err = check_cc_context_open_ccache(); return err; } krb5-1.16/src/ccapi/test/test_ccapi_constants.h0000644000704600001450000000020513211554426021403 0ustar ghudsonlibuuid#ifndef _TEST_CCAPI_CONSTANTS_H_ #define _TEST_CCAPI_CONSTANTS_H_ int check_constants(void); #endif /* _TEST_CCAPI_CONSTANTS_H_ */ krb5-1.16/src/ccapi/test/test_cc_destroy.c0000644000704600001450000000042013211554426020360 0ustar ghudsonlibuuid#include #include #include "test_ccapi_check.h" #include "test_ccapi_constants.h" #include "test_ccapi_v2.h" int main (int argc, const char * argv[]) { cc_int32 err = ccNoError; T_CCAPI_INIT; err = check_cc_destroy(); return err; } krb5-1.16/src/ccapi/test/test_ccapi_ccache.h0000644000704600001450000000647013211554426020607 0ustar ghudsonlibuuid#ifndef _TEST_CCAPI_CCACHE_H_ #define _TEST_CCAPI_CCACHE_H_ #include "test_ccapi_globals.h" int check_cc_ccache_release(void); cc_int32 check_once_cc_ccache_release(cc_context_t context, cc_ccache_t ccache, cc_int32 expected_err, const char *description); int check_cc_ccache_destroy(void); cc_int32 check_once_cc_ccache_destroy(cc_context_t context, cc_ccache_t ccache, cc_int32 expected_err, const char *description); int check_cc_ccache_set_default(void); cc_int32 check_once_cc_ccache_set_default(cc_context_t context, cc_ccache_t ccache, cc_int32 expected_err, const char *description); int check_cc_ccache_get_credentials_version(void); cc_int32 check_once_cc_ccache_get_credentials_version(cc_ccache_t ccache, cc_uint32 expected_cred_vers, cc_int32 expected_err, const char *description); int check_cc_ccache_get_name(void); cc_int32 check_once_cc_ccache_get_name(cc_ccache_t ccache, const char *expected_name, cc_int32 expected_err, const char *description); int check_cc_ccache_get_principal(void); cc_int32 check_once_cc_ccache_get_principal(cc_ccache_t ccache, cc_uint32 cred_vers, const char *expected_principal, cc_int32 expected_err, const char *description); int check_cc_ccache_set_principal(void); cc_int32 check_once_cc_ccache_set_principal(cc_ccache_t ccache, cc_uint32 cred_vers, const char *in_principal, cc_int32 expected_err, const char *description); int check_cc_ccache_store_credentials(void); cc_int32 check_once_cc_ccache_store_credentials(cc_ccache_t ccache, const cc_credentials_union *credentials, cc_int32 expected_err, const char *description); int check_cc_ccache_remove_credentials(void); cc_int32 check_once_cc_ccache_remove_credentials(cc_ccache_t ccache, cc_credentials_t in_creds, cc_int32 expected_err, const char *description); int check_cc_ccache_new_credentials_iterator(void); cc_int32 check_once_cc_ccache_new_credentials_iterator(cc_ccache_t ccache, cc_credentials_iterator_t *iterator, cc_int32 expected_err, const char *description); int check_cc_ccache_get_change_time(void); cc_int32 check_once_cc_ccache_get_change_time(cc_ccache_t ccache, cc_time_t *last_time, cc_int32 expected_err, const char *description); int check_cc_ccache_get_last_default_time(void); cc_int32 check_once_cc_ccache_get_last_default_time(cc_ccache_t ccache, cc_time_t *last_time, cc_int32 expected_err, const char *description); int check_cc_ccache_move(void); cc_int32 check_once_cc_ccache_move(cc_ccache_t source, cc_ccache_t destination, cc_int32 expected_err, const char *description); int check_cc_ccache_compare(void); cc_int32 check_once_cc_ccache_compare(cc_ccache_t ccache, cc_ccache_t compare_to, cc_uint32 *equal, cc_int32 expected_err, const char *description); int check_cc_ccache_get_kdc_time_offset(void); cc_int32 check_once_cc_ccache_get_kdc_time_offset(cc_ccache_t ccache, cc_int32 credentials_version, cc_time_t *time_offset, cc_int32 expected_err, const char *description); int check_cc_ccache_set_kdc_time_offset(void); cc_int32 check_once_cc_ccache_set_kdc_time_offset(cc_ccache_t ccache, cc_int32 credentials_version, cc_time_t time_offset, cc_int32 expected_err, const char *description); int check_cc_ccache_clear_kdc_time_offset(void); cc_int32 check_once_cc_ccache_clear_kdc_time_offset(cc_ccache_t ccache, cc_int32 credentials_version, cc_int32 expected_err, const char *description); #endif /* _TEST_CCAPI_CCACHE_H_ */ krb5-1.16/src/ccapi/test/test_cc_context_new_ccache_iterator.c0000644000704600001450000000047713211554426024437 0ustar ghudsonlibuuid#include #include #include "test_ccapi_check.h" #include "test_ccapi_constants.h" #include "test_ccapi_context.h" #include "test_ccapi_ccache.h" int main (int argc, const char * argv[]) { cc_int32 err = ccNoError; T_CCAPI_INIT; err = check_cc_context_new_ccache_iterator(); return err; } krb5-1.16/src/ccapi/test/deps0000644000704600001450000000000013211554426015667 0ustar ghudsonlibuuidkrb5-1.16/src/ccapi/test/test_cc_context_get_change_time.c0000644000704600001450000000047313211554426023545 0ustar ghudsonlibuuid#include #include #include "test_ccapi_check.h" #include "test_ccapi_constants.h" #include "test_ccapi_context.h" #include "test_ccapi_ccache.h" int main (int argc, const char * argv[]) { cc_int32 err = ccNoError; T_CCAPI_INIT; err = check_cc_context_get_change_time(); return err; } krb5-1.16/src/ccapi/test/test_cc_context_open_default_ccache.c0000644000704600001450000000047713211554426024402 0ustar ghudsonlibuuid#include #include #include "test_ccapi_check.h" #include "test_ccapi_constants.h" #include "test_ccapi_context.h" #include "test_ccapi_ccache.h" int main (int argc, const char * argv[]) { cc_int32 err = ccNoError; T_CCAPI_INIT; err = check_cc_context_open_default_ccache(); return err; } krb5-1.16/src/ccapi/test/test_cc_ccache_release.c0000644000704600001450000000046213211554426021603 0ustar ghudsonlibuuid#include #include #include "test_ccapi_check.h" #include "test_ccapi_constants.h" #include "test_ccapi_context.h" #include "test_ccapi_ccache.h" int main (int argc, const char * argv[]) { cc_int32 err = ccNoError; T_CCAPI_INIT; err = check_cc_ccache_release(); return err; } krb5-1.16/src/ccapi/test/test_ccapi_v2.c0000644000704600001450000015346213211554426017727 0ustar ghudsonlibuuid#include #include "k5-platform.h" /* pull in asprintf decl/defn */ #include "test_ccapi_v2.h" #include #include #include "test_ccapi_check.h" #include "test_ccapi_util.h" // --------------------------------------------------------------------------- static cc_result destroy_all_ccaches_v2(apiCB *context) { cc_result err = CC_NOERROR; infoNC **info = NULL; int i = 0; err = cc_get_NC_info(context, &info); for (i = 0; !err && info[i]; i++) { ccache_p *ccache = NULL; err = cc_open(context, info[i]->name, info[i]->vers, 0, &ccache); if (!err) { cc_destroy(context, &ccache); } } if (info) { cc_free_NC_info(context, &info); } if (err) { log_error("cc_get_NC_info or cc_open failed with %s (%d)", translate_ccapi_error(err), err); } return err; } // --------------------------------------------------------------------------- // return zero when both unions are considered equal, non-zero when not static int compare_v5_creds_unions_compat(const cred_union *a, const cred_union *b) { int retval = -1; if (a && b && a->cred_type == b->cred_type) { if (a->cred_type == CC_CRED_V5) { if (!strcmp(a->cred.pV5Cred->client, b->cred.pV5Cred->client) && !strcmp(a->cred.pV5Cred->server, b->cred.pV5Cred->server) && a->cred.pV5Cred->starttime == b->cred.pV5Cred->starttime) { retval = 0; } } else if (a->cred_type == CC_CRED_V4) { if (!strcmp (a->cred.pV4Cred->principal, b->cred.pV4Cred->principal) && !strcmp (a->cred.pV4Cred->principal_instance, b->cred.pV4Cred->principal_instance) && !strcmp (a->cred.pV4Cred->service, b->cred.pV4Cred->service) && !strcmp (a->cred.pV4Cred->service_instance, b->cred.pV4Cred->service_instance) && !strcmp (a->cred.pV4Cred->realm, b->cred.pV4Cred->realm) && a->cred.pV4Cred->issue_date == b->cred.pV4Cred->issue_date) { retval = 0; } } } return retval; } // --------------------------------------------------------------------------- static cc_result new_v5_creds_union_compat (cred_union *out_union, const char *realm) { cc_result err = CC_NOERROR; cred_union *creds_union = NULL; cc_credentials_v5_compat *v5creds = NULL; static int num_runs = 1; char *client = NULL; char *server = NULL; if (!out_union) { err = CC_BAD_PARM; } if (!err) { v5creds = malloc (sizeof (*v5creds)); if (!v5creds) { err = CC_NOMEM; } } if (!err) { asprintf(&client, "client@%s", realm); asprintf(&server, "host/%d%s@%s", num_runs++, realm, realm); if (!client || !server) { err = CC_NOMEM; } } if (!err) { v5creds->client = client; v5creds->server = server; v5creds->keyblock.type = 1; v5creds->keyblock.length = 0; v5creds->keyblock.data = NULL; v5creds->authtime = time (NULL); v5creds->starttime = time (NULL); v5creds->endtime = time(NULL) + 1000; v5creds->renew_till = time(NULL) + 10000; v5creds->is_skey = 0; v5creds->ticket_flags = TKT_FLG_FORWARDABLE | TKT_FLG_PROXIABLE | TKT_FLG_RENEWABLE | TKT_FLG_INITIAL; v5creds->addresses = NULL; v5creds->ticket.type = 0; v5creds->ticket.length = 0; v5creds->ticket.data = NULL; v5creds->second_ticket.type = 0; v5creds->second_ticket.length = 0; v5creds->second_ticket.data = NULL; v5creds->authdata = NULL; } if (!err) { creds_union = malloc (sizeof (*creds_union)); if (creds_union) { creds_union->cred_type = CC_CRED_V5; creds_union->cred.pV5Cred = v5creds; } else { err = CC_NOMEM; } } if (!err) { *out_union = *creds_union; creds_union = NULL; } return err; } // --------------------------------------------------------------------------- static void release_v5_creds_union_compat(cred_union *creds_union) { cc_credentials_v5_compat *v5creds = NULL; if (creds_union) { if (creds_union->cred.pV5Cred) { v5creds = creds_union->cred.pV5Cred; if (v5creds->client) { free(v5creds->client); } if (v5creds->server) { free(v5creds->server); } if (v5creds->keyblock.data) { free(v5creds->keyblock.data); } if (v5creds->ticket.data) { free(v5creds->ticket.data); } if (v5creds->second_ticket.data) { free(v5creds->second_ticket.data); } free(v5creds); } } } // --------------------------------------------------------------------------- int check_cc_shutdown(void) { cc_result err = 0; apiCB *context = NULL; BEGIN_TEST("cc_shutdown"); // try with valid context err = check_once_cc_shutdown(&context, CC_NOERROR, NULL); // try with NULL err = check_once_cc_shutdown(NULL, CC_BAD_PARM, NULL); if (context) { cc_shutdown(&context); } END_TEST_AND_RETURN } cc_result check_once_cc_shutdown(apiCB **out_context, cc_result expected_err, const char *description) { cc_result err = 0; apiCB *context = NULL; cc_result possible_return_values[2] = { CC_NOERROR, CC_BAD_PARM, }; BEGIN_CHECK_ONCE(description); #define possible_ret_val_count sizeof(possible_return_values)/sizeof(possible_return_values[0]) if (out_context) { err = cc_initialize(out_context, ccapi_version_2, NULL, NULL); if (!err) { context = *out_context; } else { log_error("failure in cc_initialize, unable to perform check"); return err; } } if (!err) { err = cc_shutdown(&context); // check returned error check_err(err, expected_err, possible_return_values); } if (out_context) { *out_context = NULL; } END_CHECK_ONCE; return err; } // --------------------------------------------------------------------------- int check_cc_get_change_time(void) { cc_result err = 0; apiCB *context = NULL; cc_time_t last_change_time = 0; ccache_p *ccache = NULL; cred_union creds_union; BEGIN_TEST("cc_get_change_time"); /* * Make a context * make sure the change time changes after: * a ccache is created * a ccache is destroyed * a credential is stored * a credential is removed * a ccache principal is changed * clean up memory */ err = cc_initialize(&context, ccapi_version_2, NULL, NULL); if (!err) { // try bad parameters first err = check_once_cc_get_change_time(context, NULL, CC_BAD_PARM, "NULL param, should fail"); // get_change_time should always give something > 0 check_once_cc_get_change_time(context, &last_change_time, CC_NOERROR, "first-run, should be > 0"); // create a ccache err = cc_create(context, "TEST_CCACHE", "foo@BAR.ORG", CC_CRED_V5, 0, &ccache); if (err) { log_error("failed to create a ccache - %s (%d)", translate_ccapi_error(err), err); failure_count++; } check_once_cc_get_change_time(context, &last_change_time, CC_NOERROR, "after creating a new ccache"); if (!err) { // change principal err = cc_set_principal(context, ccache, CC_CRED_V5, "foo@BAR.ORG"); if (err) { log_error("failed to change ccache's principal - %s (%d)", translate_ccapi_error(err), err); failure_count++; err = CC_NOERROR; } } check_once_cc_get_change_time(context, &last_change_time, CC_NOERROR, "after changing a principle"); new_v5_creds_union_compat(&creds_union, "BAR.ORG"); // store a credential if (!err) { err = cc_store(context, ccache, creds_union); if (err) { log_error("failed to store a credential - %s (%d)", translate_ccapi_error(err), err); failure_count++; err = CC_NOERROR; } } check_once_cc_get_change_time(context, &last_change_time, CC_NOERROR, "after storing a credential"); // remove a credential if (!err) { err = cc_remove_cred(context, ccache, creds_union); if (err) { log_error("failed to remove a credential - %s (%d)", translate_ccapi_error(err), err); failure_count++; err = CC_NOERROR; } } check_once_cc_get_change_time(context, &last_change_time, CC_NOERROR, "after removing a credential"); release_v5_creds_union_compat(&creds_union); if (ccache) { // destroy a ccache err = cc_destroy(context, &ccache); check_once_cc_get_change_time(context, &last_change_time, CC_NOERROR, "after destroying a ccache"); } } if (context) { cc_shutdown(&context); } END_TEST_AND_RETURN } // --------------------------------------------------------------------------- cc_int32 check_once_cc_get_change_time(apiCB *context, cc_time_t *last_time, cc_result expected_err, const char *description) { cc_result err = 0; cc_time_t last_change_time; cc_time_t current_change_time = 0; cc_result possible_return_values[3] = { CC_NOERROR, CC_BAD_PARM, CC_NO_EXIST, }; BEGIN_CHECK_ONCE(description); #define possible_ret_val_count sizeof(possible_return_values)/sizeof(possible_return_values[0]) if (last_time != NULL) { // if we were passed NULL, then we're looking to pass a bad param err = cc_get_change_time(context, ¤t_change_time); } else { err = cc_get_change_time(context, NULL); } check_err(err, expected_err, possible_return_values); if (!err) { last_change_time = *last_time; check_if(current_change_time <= last_change_time, "context change time did not increase when it was supposed to (%d <= %d)", current_change_time, last_change_time); *last_time = current_change_time; } END_CHECK_ONCE; return err; } // --------------------------------------------------------------------------- int check_cc_open(void) { cc_result err = 0; apiCB *context = NULL; ccache_p *ccache = NULL; char *name = "TEST_OPEN_CCACHE"; BEGIN_TEST("cc_open"); err = cc_initialize(&context, ccapi_version_2, NULL, NULL); if (!err) { // create a ccache err = cc_create(context, name, "foo@BAR.ORG", CC_CRED_V5, 0, &ccache); if (err) { log_error("failed to create a ccache - %s (%d)", translate_ccapi_error(err), err); failure_count++; } if (!err) { err = cc_close(context, &ccache); ccache = NULL; } // try default ccache if (!err) { err = check_once_cc_open(context, name, CC_CRED_V5, &ccache, CC_NOERROR, NULL); } // check version if (!err) { err = check_once_cc_open(context, name, CC_CRED_V4, &ccache, CC_ERR_CRED_VERSION, NULL); } // try bad parameters err = check_once_cc_open(context, NULL, CC_CRED_V5, &ccache, CC_BAD_PARM, NULL); err = check_once_cc_open(context, name, CC_CRED_V5, NULL, CC_BAD_PARM, NULL); err = check_once_cc_open(context, name, CC_CRED_UNKNOWN, &ccache, CC_ERR_CRED_VERSION, NULL); } if (context) { cc_shutdown(&context); } END_TEST_AND_RETURN } // --------------------------------------------------------------------------- cc_result check_once_cc_open(apiCB *context, const char *name, cc_int32 version, ccache_p **ccache, cc_result expected_err, const char *description) { cc_result err = 0; char *stored_name = NULL; cc_result possible_return_values[5] = { CC_NOERROR, CC_BAD_PARM, CC_NO_EXIST, CC_NOMEM, CC_ERR_CRED_VERSION }; BEGIN_CHECK_ONCE(description); #define possible_ret_val_count sizeof(possible_return_values)/sizeof(possible_return_values[0]) if (ccache != NULL) { // if we were passed NULL, then we're looking to pass a bad param err = cc_open(context, name, version, 0, ccache); } else { err = cc_open(context, name, version, 0, NULL); } // check returned error check_err(err, expected_err, possible_return_values); if (!err) { check_if(*ccache == NULL, NULL); if (!err) { err = cc_get_name(context, *ccache, &stored_name); } if (!err) { check_if(strcmp(stored_name, name), NULL); } if (stored_name) { cc_free_name(context, &stored_name); } if (ccache && *ccache) { cc_ccache_release(*ccache); *ccache = NULL; } } END_CHECK_ONCE; return err; } // --------------------------------------------------------------------------- int check_cc_create(void) { cc_result err = 0; apiCB *context = NULL; ccache_p *ccache = NULL; char *name = "TEST_CC_CREATE"; BEGIN_TEST("cc_create"); err = cc_initialize(&context, ccapi_version_2, NULL, NULL); if (!err) { if (!err) { err = cc_open(context, name, CC_CRED_V5, 0, &ccache); if (!err) { err = cc_destroy (context, &ccache); } else { err = CC_NOERROR; /* ccache does not exist */ } } // try making a ccache with a unique name (the now destroyed cache's name) if (!err) { err = check_once_cc_create(context, name, CC_CRED_V5, "foo@BAR.ORG", &ccache, CC_NOERROR, NULL); } // try making a ccache with a non-unique name (the existing cache's name) if (!err) { err = check_once_cc_create(context, name, CC_CRED_V5, "foo/baz@BAR.ORG", &ccache, CC_NOERROR, NULL); } // try bad parameters err = check_once_cc_create(context, NULL, CC_CRED_V5, "foo@BAR.ORG", &ccache, CC_BAD_PARM, "NULL name"); // NULL name err = check_once_cc_create(context, "name", CC_CRED_MAX, "foo@BAR.ORG", &ccache, CC_ERR_CRED_VERSION, "invalid creds_vers"); // invalid creds_vers err = check_once_cc_create(context, "name", CC_CRED_V5, NULL, &ccache, CC_BAD_PARM, "NULL principal"); // NULL principal err = check_once_cc_create(context, "name", CC_CRED_V5, "foo@BAR.ORG", NULL, CC_BAD_PARM, "NULL ccache"); // NULL ccache } if (ccache) { cc_destroy(context, &ccache); } if (context) { cc_shutdown(&context); } END_TEST_AND_RETURN } // --------------------------------------------------------------------------- cc_result check_once_cc_create(apiCB *context, const char *name, cc_int32 cred_vers, const char *principal, ccache_p **ccache, cc_int32 expected_err, const char *description) { cc_result err = 0; char *stored_name = NULL; char *stored_principal = NULL; cc_int32 stored_creds_vers = 0; cc_result possible_return_values[6] = { CC_NOERROR, CC_BADNAME, CC_BAD_PARM, CC_NO_EXIST, CC_NOMEM, CC_ERR_CRED_VERSION, }; BEGIN_CHECK_ONCE(description); #define possible_ret_val_count sizeof(possible_return_values)/sizeof(possible_return_values[0]) err = cc_create(context, name, principal, cred_vers, 0, ccache); // check returned error check_err(err, expected_err, possible_return_values); if (!err) { check_if(*ccache == NULL, NULL); // make sure all of the ccache's info matches what we gave it // name err = cc_get_name(context, *ccache, &stored_name); if (!err) { check_if(strcmp(stored_name, name), NULL); } if (stored_name) { cc_free_name(context, &stored_name); } // cred_vers err = cc_get_cred_version(context, *ccache, &stored_creds_vers); if (!err) { check_if(stored_creds_vers != cred_vers, NULL); } // principal err = cc_get_principal(context, *ccache, &stored_principal); if (!err) { check_if(strcmp(stored_principal, principal), NULL); } if (stored_principal) { cc_free_principal(context, &stored_principal); } if (ccache && *ccache) { cc_destroy(context, ccache); *ccache = NULL; } } END_CHECK_ONCE; return err; } // --------------------------------------------------------------------------- int check_cc_close(void) { cc_result err = 0; apiCB *context = NULL; ccache_p *ccache = NULL; char *name = "TEST_CC_CLOSE"; BEGIN_TEST("cc_close"); err = cc_initialize(&context, ccapi_version_2, NULL, NULL); if (!err) { err = cc_create(context, name, "foo@BAR.ORG", CC_CRED_V5, 0, &ccache); } if (!err) { check_once_cc_close(context, ccache, CC_NOERROR, NULL); ccache = NULL; } if (context) { cc_shutdown(&context); } END_TEST_AND_RETURN } // --------------------------------------------------------------------------- cc_result check_once_cc_close(apiCB *context, ccache_p *ccache, cc_result expected_err, const char *description) { cc_result err = CC_NOERROR; cc_result possible_return_values[2] = { CC_NOERROR, CC_BAD_PARM }; char *name = NULL; err = cc_get_name(context, ccache, &name); err = cc_close(context, &ccache); ccache = NULL; BEGIN_CHECK_ONCE(description); #define possible_ret_val_count sizeof(possible_return_values)/sizeof(possible_return_values[0]) // check returned error check_err(err, expected_err, possible_return_values); if (!err && name) { // try opening released ccache to make sure it still exists err = cc_open(context, name, CC_CRED_V5, 0, &ccache); } check_if(err == CC_NO_EXIST, "released ccache was actually destroyed instead"); check_if(err != CC_NOERROR, "released ccache cannot be opened"); if (ccache) { cc_destroy(context, &ccache); } if (name) { cc_free_name(context, &name); } END_CHECK_ONCE; return err; } // --------------------------------------------------------------------------- int check_cc_destroy(void) { cc_result err = 0; apiCB *context = NULL; ccache_p *ccache = NULL; char *name = "TEST_CC_DESTROY"; BEGIN_TEST("cc_destroy"); err = cc_initialize(&context, ccapi_version_2, NULL, NULL); if (!err) { err = cc_create(context, name, "foo@BAR.ORG", CC_CRED_V5, 0, &ccache); } if (!err) { check_once_cc_destroy(context, ccache, CC_NOERROR, NULL); ccache = NULL; } if (context) { cc_shutdown(&context); } END_TEST_AND_RETURN } // --------------------------------------------------------------------------- cc_result check_once_cc_destroy(apiCB *context, ccache_p *ccache, cc_int32 expected_err, const char *description) { cc_result err = CC_NOERROR; cc_result possible_return_values[2] = { CC_NOERROR, CC_BAD_PARM, }; char *name = NULL; BEGIN_CHECK_ONCE(description); #ifdef cc_ccache_destroy #define possible_ret_val_count sizeof(possible_return_values)/sizeof(possible_return_values[0]) err = cc_get_name(context, ccache, &name); err = cc_destroy(context, &ccache); ccache = NULL; // check returned error check_err(err, expected_err, possible_return_values); if (!err && name) { // try opening released ccache to make sure it still exists err = cc_open(context, name, CC_CRED_V5, 0, &ccache); } check_if(err != CC_NO_EXIST, "destroyed ccache was actually released instead"); if (ccache) { cc_destroy(context, &ccache); } if (name) { cc_free_name(context, &name); } #endif /* cc_ccache_destroy */ END_CHECK_ONCE; return err; } // --------------------------------------------------------------------------- int check_cc_get_cred_version(void) { cc_result err = 0; apiCB *context = NULL; ccache_p *ccache = NULL; char *name = "TEST_CC_GET_CRED_VERSION_V5"; BEGIN_TEST("cc_get_cred_version"); err = cc_initialize(&context, ccapi_version_2, NULL, NULL); // try one created with v5 creds if (!err) { err = cc_create(context, name, "foo@BAR.ORG", CC_CRED_V5, 0, &ccache); } if (!err) { check_once_cc_get_cred_version(context, ccache, CC_CRED_V5, CC_NOERROR, "v5 creds"); } else { log_error("cc_context_create_new_ccache failed, can't complete test"); failure_count++; } if (ccache) { cc_destroy(context, &ccache); ccache = NULL; } err = CC_NOERROR; // try one created with v4 creds if (!err) { err = cc_create(context, name, "foo@BAR.ORG", CC_CRED_V4, 0, &ccache); } if (!err) { check_once_cc_get_cred_version(context, ccache, CC_CRED_V4, CC_NOERROR, "v4 creds"); } else { log_error("cc_context_create_new_ccache failed, can't complete test"); failure_count++; } if (ccache) { cc_destroy(context, &ccache); ccache = NULL; } if (context) { cc_shutdown(&context); } END_TEST_AND_RETURN } // --------------------------------------------------------------------------- cc_result check_once_cc_get_cred_version(apiCB *context, ccache_p *ccache, cc_int32 expected_cred_vers, cc_int32 expected_err, const char *description) { cc_result err = CC_NOERROR; cc_result possible_return_values[3] = { CC_NOERROR, CC_BAD_PARM, CC_NO_EXIST, }; cc_int32 stored_cred_vers = 0; BEGIN_CHECK_ONCE(description); #define possible_ret_val_count sizeof(possible_return_values)/sizeof(possible_return_values[0]) err = cc_get_cred_version(context, ccache, &stored_cred_vers); // check returned error check_err(err, expected_err, possible_return_values); if (!err) { check_if(stored_cred_vers != expected_cred_vers, NULL); } END_CHECK_ONCE; return err; } // --------------------------------------------------------------------------- int check_cc_get_name(void) { cc_result err = 0; apiCB *context = NULL; ccache_p *ccache = NULL; BEGIN_TEST("cc_get_name"); err = cc_initialize(&context, ccapi_version_2, NULL, NULL); if (!err) { err = destroy_all_ccaches_v2(context); } // try with unique ccache (which happens to be default) if (!err) { err = cc_create(context, "0", "foo@BAR.ORG", CC_CRED_V5, 0, &ccache); } if (!err) { check_once_cc_get_name(context, ccache, "0", CC_NOERROR, "unique ccache (which happens to be default)"); } else { log_error("cc_context_create_ccache failed, can't complete test"); failure_count++; } if (ccache) { cc_close(context, &ccache); ccache = NULL; } // try with unique ccache (which is not default) if (!err) { err = cc_context_create_ccache(context, "1", CC_CRED_V5, "foo@BAR.ORG", &ccache); } if (!err) { check_once_cc_get_name(context, ccache, "1", CC_NOERROR, "unique ccache (which is not default)"); } else { log_error("cc_context_create_ccache failed, can't complete test"); failure_count++; } // try with bad param if (!err) { check_once_cc_get_name(context, ccache, NULL, CC_BAD_PARM, "NULL param"); } if (ccache) { cc_close(context, &ccache); ccache = NULL; } if (context) { err = destroy_all_ccaches_v2(context); cc_shutdown(&context); } END_TEST_AND_RETURN } // --------------------------------------------------------------------------- cc_int32 check_once_cc_get_name(apiCB *context, ccache_p *ccache, const char *expected_name, cc_int32 expected_err, const char *description) { cc_result err = CC_NOERROR; cc_result possible_return_values[4] = { CC_NOERROR, CC_NOMEM, CC_BAD_PARM, CC_NO_EXIST, }; char *stored_name = NULL; BEGIN_CHECK_ONCE(description); #define possible_ret_val_count sizeof(possible_return_values)/sizeof(possible_return_values[0]) if (expected_name == NULL) { // we want to try with a NULL param err = cc_get_name(context, ccache, NULL); } else { err = cc_get_name(context, ccache, &stored_name); } // check returned error check_err(err, expected_err, possible_return_values); if (!err) { check_if(strcmp(stored_name, expected_name), NULL); } if (stored_name) { cc_free_name(context, &stored_name); } END_CHECK_ONCE; return err; } // --------------------------------------------------------------------------- int check_cc_get_principal(void) { cc_result err = 0; apiCB *context = NULL; ccache_p *ccache = NULL; char *name_v5 = "TEST_CC_GET_PRINCIPAL_V5"; char *name_v4 = "TEST_CC_GET_PRINCIPAL_V4"; BEGIN_TEST("cc_get_principal"); err = cc_initialize(&context, ccapi_version_2, NULL, NULL); if (!err) { err = destroy_all_ccaches_v2(context); } // try with krb5 principal if (!err) { err = cc_create(context, name_v5, "foo/BAR@BAZ.ORG", CC_CRED_V5, 0, &ccache); } if (!err) { check_once_cc_get_principal(context, ccache, "foo/BAR@BAZ.ORG", CC_NOERROR, "trying to get krb5 princ for krb5 ccache"); } else { log_error("cc_create failed, can't complete test"); failure_count++; } if (ccache) { cc_close(context, &ccache); ccache = NULL; } // try with krb4 principal if (!err) { err = cc_create(context, name_v4, "foo.BAR@BAZ.ORG", CC_CRED_V4, 0, &ccache); } if (!err) { check_once_cc_get_principal(context, ccache, "foo.BAR@BAZ.ORG", CC_NOERROR, "trying to get krb4 princ for krb4 ccache"); } else { log_error("cc_create failed, can't complete test"); failure_count++; } // try with bad param if (!err) { check_once_cc_get_principal(context, ccache, NULL, CC_BAD_PARM, "passed null out param"); } if (ccache) { cc_close(context, &ccache); ccache = NULL; } if (context) { err = destroy_all_ccaches_v2(context); cc_shutdown(&context); } END_TEST_AND_RETURN } // --------------------------------------------------------------------------- cc_result check_once_cc_get_principal(apiCB *context, ccache_p *ccache, const char *expected_principal, cc_int32 expected_err, const char *description) { cc_result err = CC_NOERROR; char *stored_principal = NULL; cc_result possible_return_values[4] = { CC_NOERROR, CC_NOMEM, CC_NO_EXIST, CC_BAD_PARM }; BEGIN_CHECK_ONCE(description); #define possible_ret_val_count sizeof(possible_return_values)/sizeof(possible_return_values[0]) if (expected_principal == NULL) { // we want to try with a NULL param err = cc_get_principal(context, ccache, NULL); } else { err = cc_get_principal(context, ccache, &stored_principal); } // check returned error check_err(err, expected_err, possible_return_values); if (!err) { check_if(strcmp(stored_principal, expected_principal), "expected princ == \"%s\" stored princ == \"%s\"", expected_principal, stored_principal); } if (stored_principal) { cc_free_principal(context, &stored_principal); } END_CHECK_ONCE; return err; } // --------------------------------------------------------------------------- int check_cc_set_principal(void) { cc_result err = 0; apiCB *context = NULL; ccache_p *ccache = NULL; char *name_v5 = "TEST_CC_GET_PRINCIPAL_V5"; char *name_v4 = "TEST_CC_GET_PRINCIPAL_V4"; BEGIN_TEST("cc_set_principal"); err = cc_initialize(&context, ccapi_version_2, NULL, NULL); if (!err) { err = destroy_all_ccaches_v2(context); } // bad params if (!err) { err = cc_create(context, name_v5, "foo@BAZ.ORG", CC_CRED_V5, 0, &ccache); } if (!err) { check_once_cc_set_principal(context, ccache, CC_CRED_MAX, "foo/BAZ@BAR.ORG", CC_ERR_CRED_VERSION, "CC_CRED_MAX (not allowed)"); check_once_cc_set_principal(context, ccache, CC_CRED_V5, NULL, CC_BAD_PARM, "NULL principal"); } else { log_error("cc_create failed, can't complete test"); failure_count++; } if (ccache) { cc_destroy(context, &ccache); ccache = NULL; } // empty ccache // replace v5 ccache's principal if (!err) { err = cc_create(context, name_v5, "foo@BAZ.ORG", CC_CRED_V5, 0, &ccache); } if (!err) { check_once_cc_set_principal(context, ccache, CC_CRED_V5, "foo/BAZ@BAR.ORG", CC_NOERROR, "replace v5 only ccache's principal (empty ccache)"); check_once_cc_set_principal(context, ccache, CC_CRED_V4, "foo.BAZ@BAR.ORG", CC_ERR_CRED_VERSION, "replace v5 principal with v4"); } else { log_error("cc_create failed, can't complete test"); failure_count++; } if (ccache) { cc_destroy(context, &ccache); ccache = NULL; } // replace v4 ccache's principal if (!err) { err = cc_create(context, name_v4, "foo@BAZ.ORG", CC_CRED_V4, 0, &ccache); } if (!err) { check_once_cc_set_principal(context, ccache, CC_CRED_V4, "foo.BAZ@BAR.ORG", CC_NOERROR, "replace v4 only ccache's principal (empty ccache)"); check_once_cc_set_principal(context, ccache, CC_CRED_V5, "foo/BAZ@BAR.ORG", CC_ERR_CRED_VERSION, "replace v4 principal with v5"); } else { log_error("cc_create failed, can't complete test"); failure_count++; } if (ccache) { cc_destroy(context, &ccache); ccache = NULL; } if (context) { err = destroy_all_ccaches_v2(context); cc_shutdown(&context); } END_TEST_AND_RETURN } // --------------------------------------------------------------------------- cc_int32 check_once_cc_set_principal(apiCB *context, ccache_p *ccache, cc_int32 cred_vers, const char *in_principal, cc_int32 expected_err, const char *description) { cc_result err = CC_NOERROR; char *stored_principal = NULL; cc_result possible_return_values[5] = { CC_NOERROR, CC_NOMEM, CC_NO_EXIST, CC_ERR_CRED_VERSION, CC_BAD_PARM }; BEGIN_CHECK_ONCE(description); #define possible_ret_val_count sizeof(possible_return_values)/sizeof(possible_return_values[0]) err = cc_set_principal(context, ccache, cred_vers, (char *) in_principal); // check returned error check_err(err, expected_err, possible_return_values); if (!err) { err = cc_get_principal(context, ccache, &stored_principal); } // compare stored with input if (!err) { check_if(strcmp(stored_principal, in_principal), "expected princ == \"%s\" stored princ == \"%s\"", in_principal, stored_principal); } if (stored_principal) { cc_free_principal(context, &stored_principal); } END_CHECK_ONCE; return err; } // --------------------------------------------------------------------------- int check_cc_store(void) { cc_result err = 0; apiCB *context = NULL; ccache_p *ccache = NULL; ccache_p *dup_ccache = NULL; cred_union creds_union; char *name = NULL; BEGIN_TEST("cc_store"); err = cc_initialize(&context, ccapi_version_2, NULL, NULL); if (!err) { err = destroy_all_ccaches_v2(context); } if (!err) { err = cc_create(context, "TEST_CC_STORE", "foo@BAR.ORG", CC_CRED_V5, 0, &ccache); } // cred with matching version and realm if (!err) { err = new_v5_creds_union_compat(&creds_union, "BAR.ORG"); if (!err) { check_once_cc_store(context, ccache, creds_union, CC_NOERROR, "ok creds"); release_v5_creds_union_compat(&creds_union); } } // invalid creds if (!err) { err = new_v5_creds_union_compat(&creds_union, "BAR.ORG"); if (!err) { if (creds_union.cred.pV5Cred->client) { free(creds_union.cred.pV5Cred->client); creds_union.cred.pV5Cred->client = NULL; } check_once_cc_store(context, ccache, creds_union, CC_BAD_PARM, "invalid creds (NULL client string)"); release_v5_creds_union_compat(&creds_union); } } // bad creds version if (!err) { err = new_v5_creds_union_compat(&creds_union, "BAR.ORG"); if (!err) { creds_union.cred_type = CC_CRED_MAX; check_once_cc_store(context, ccache, creds_union, CC_ERR_CRED_VERSION, "CC_CRED_MAX (invalid) into a ccache with only v5 princ"); creds_union.cred_type = CC_CRED_V4; check_once_cc_store(context, ccache, creds_union, CC_ERR_CRED_VERSION, "v4 creds into a v5 ccache"); creds_union.cred_type = CC_CRED_V5; release_v5_creds_union_compat(&creds_union); } } // non-existent ccache if (ccache) { err = cc_get_name(context, ccache, &name); if (!err) { err = cc_open(context, name, CC_CRED_V5, 0, &dup_ccache); } if (name) { cc_free_name(context, &name); } if (dup_ccache) { cc_destroy(context, &dup_ccache); } } if (!err) { err = new_v5_creds_union_compat(&creds_union, "BAR.ORG"); if (!err) { check_once_cc_store(context, ccache, creds_union, CC_NO_EXIST, "invalid ccache"); release_v5_creds_union_compat(&creds_union); } } if (ccache) { cc_close(context, &ccache); } if (context) { destroy_all_ccaches_v2(context); cc_shutdown(&context); } END_TEST_AND_RETURN } // --------------------------------------------------------------------------- cc_result check_once_cc_store(apiCB *context, ccache_p *ccache, const cred_union in_creds, cc_int32 expected_err, const char *description) { cc_result err = CC_NOERROR; ccache_cit *iterator = NULL; int found = 0; cc_result possible_return_values[5] = { CC_NOERROR, CC_BAD_PARM, CC_ERR_CACHE_FULL, CC_ERR_CRED_VERSION, CC_NO_EXIST }; BEGIN_CHECK_ONCE(description); #define possible_ret_val_count sizeof(possible_return_values)/sizeof(possible_return_values[0]) err = cc_store(context, ccache, in_creds); // check returned error check_err(err, expected_err, possible_return_values); // make sure credentials were truly stored if (!err) { err = cc_seq_fetch_creds_begin(context, ccache, &iterator); } while (!err && !found) { cred_union *creds = NULL; err = cc_seq_fetch_creds_next(context, &creds, iterator); if (!err) { found = !compare_v5_creds_unions_compat(&in_creds, creds); } if (creds) { cc_free_creds(context, &creds); } } if (err == CC_END) { check_if(found, "stored credentials not found in ccache"); err = CC_NOERROR; } if (iterator) { cc_seq_fetch_creds_end(context, &iterator); } END_CHECK_ONCE; return err; } // --------------------------------------------------------------------------- int check_cc_remove_cred(void) { cc_result err = 0; apiCB *context = NULL; ccache_p *ccache = NULL; cred_union *creds_array[10]; ccache_cit *iterator = NULL; char *name = NULL; unsigned int i; BEGIN_TEST("cc_remove_cred"); err = cc_initialize(&context, ccapi_version_2, NULL, NULL); if (!err) { err = destroy_all_ccaches_v2(context); } if (!err) { err = cc_create(context, "TEST_CC_REMOVE_CRED", "foo@BAR.ORG", CC_CRED_V5, 0, &ccache); } // store 10 creds and retrieve their cc_credentials_t representations for(i = 0; !err && (i < 10); i++) { cred_union creds; new_v5_creds_union_compat(&creds, "BAR.ORG"); err = cc_store(context, ccache, creds); if (err) { log_error("failure to store creds_union in remove_creds test"); } release_v5_creds_union_compat(&creds); } if (!err) { err = cc_seq_fetch_creds_begin(context, ccache, &iterator); } for (i = 0; !err && i < 10; i++) { creds_array[i] = NULL; err = cc_seq_fetch_creds_next(context, &creds_array[i], iterator); } if (err == CC_END) { err = CC_NOERROR; } // remove 10 valid creds for (i = 0; !err && (i < 10); i++) { check_once_cc_remove_cred(context, ccache, *creds_array[i], CC_NOERROR, "10 ok creds"); } // non-existent creds (remove same one twice) check_once_cc_remove_cred(context, ccache, *creds_array[0], CC_NOTFOUND, "removed same creds twice"); // non-existent ccache if (ccache) { ccache_p *dup_ccache = NULL; err = cc_get_name(context, ccache, &name); if (!err) { err = cc_open(context, name, CC_CRED_V5, 0, &dup_ccache); } if (!err) { err = cc_destroy(context, &dup_ccache); check_once_cc_remove_cred(context, ccache, *creds_array[0], CC_NO_EXIST, "invalid ccache"); } if (name) { cc_free_name(context, &name); } } for(i = 0; i < 10 && creds_array[i]; i++) { cc_free_creds(context, &creds_array[i]); } if (iterator) { cc_seq_fetch_creds_end(context, &iterator); iterator = NULL; } if (ccache) { cc_close(context, &ccache); } if (context) { destroy_all_ccaches_v2(context); cc_shutdown(&context); } END_TEST_AND_RETURN } // --------------------------------------------------------------------------- cc_result check_once_cc_remove_cred(apiCB *context, ccache_p *ccache, cred_union in_creds, cc_int32 expected_err, const char *description) { cc_result err = CC_NOERROR; ccache_cit *iterator = NULL; int found = 0; cc_result possible_return_values[5] = { CC_NOERROR, CC_BAD_PARM, CC_ERR_CRED_VERSION, CC_NOTFOUND, CC_NO_EXIST }; BEGIN_CHECK_ONCE(description); #define possible_ret_val_count sizeof(possible_return_values)/sizeof(possible_return_values[0]) err = cc_remove_cred(context, ccache, in_creds); // check returned error check_err(err, expected_err, possible_return_values); // make sure credentials were truly stored if (!err) { err = cc_seq_fetch_creds_begin(context, ccache, &iterator); } while (!err && !found) { cred_union *creds = NULL; err = cc_seq_fetch_creds_next(context, &creds, iterator); if (!err) { found = !compare_v5_creds_unions_compat(&in_creds, creds); } if (creds) { cc_free_creds(context, &creds); } } if (err == CC_END) { check_if(found, "credentials not removed from ccache"); err = CC_NOERROR; } if (iterator) { cc_seq_fetch_creds_end(context, &iterator); } END_CHECK_ONCE; return err; } // --------------------------------------------------------------------------- int check_cc_seq_fetch_NCs_begin(void) { cc_result err = 0; apiCB *context = NULL; ccache_p *ccache = NULL; ccache_cit *iterator = NULL; BEGIN_TEST("cc_seq_fetch_NCs_begin"); err = cc_initialize(&context, ccapi_version_2, NULL, NULL); if (!err) { err = destroy_all_ccaches_v2(context); } if (!err) { // try making when there are no existing ccaches (shouldn't make a difference, but just in case) check_once_cc_seq_fetch_NCs_begin(context, &iterator, CC_NOERROR, "when there are no existing ccaches"); err = cc_create(context, "TEST_CC_SEQ_FETCH_NCS_BEGIN", "foo@BAR.ORG", CC_CRED_V5, 0, &ccache); } if (!err) { // try making when at least one ccache already exists (just to cover all our bases) check_once_cc_seq_fetch_NCs_begin(context, &iterator, CC_NOERROR, "when at least one ccache already exists"); // try bad parameters check_once_cc_seq_fetch_NCs_begin(context, NULL, CC_BAD_PARM, "NULL param"); // NULL iterator } // we'll do a comprehensive test of cc_ccache_iterator related functions later in the test suite if (ccache ) { cc_close(context, &ccache); } if (context) { cc_shutdown(&context); } END_TEST_AND_RETURN } // --------------------------------------------------------------------------- cc_result check_once_cc_seq_fetch_NCs_begin(apiCB *context, ccache_cit **iterator, cc_result expected_err, const char *description) { cc_result err = CC_NOERROR; cc_result possible_return_values[4] = { CC_NOERROR, CC_BAD_PARM, CC_NOMEM, CC_NO_EXIST }; BEGIN_CHECK_ONCE(description); #define possible_ret_val_count sizeof(possible_return_values)/sizeof(possible_return_values[0]) err = cc_seq_fetch_NCs_begin(context, iterator); // check returned error check_err(err, expected_err, possible_return_values); // we'll do a comprehensive test of cc_ccache_iterator related functions later return err; } // --------------------------------------------------------------------------- int check_cc_seq_fetch_NCs_next(void) { cc_result err = 0; apiCB *context = NULL; ccache_p *ccache = NULL; ccache_cit *iterator = NULL; unsigned int i; BEGIN_TEST("cc_seq_fetch_NCs_next"); err = cc_initialize(&context, ccapi_version_2, NULL, NULL); if (!err) { err = destroy_all_ccaches_v2(context); } // iterate with no ccaches if (!err) { err = cc_seq_fetch_NCs_begin(context, &iterator); } check_once_cc_seq_fetch_NCs_next(context, iterator, 0, CC_NOERROR, "iterating over an empty collection"); if (iterator) { cc_seq_fetch_creds_end(context, &iterator); iterator = NULL; } // iterate with one ccache if (!err) { destroy_all_ccaches_v2(context); err = cc_create(context, "TEST_CC_SEQ_FETCH_NCS_NEXT", "foo@BAR.ORG", CC_CRED_V5, 0, &ccache); } if (ccache) { cc_close(context, &ccache); ccache = NULL; } if (!err) { err = cc_seq_fetch_NCs_begin(context, &iterator); } check_once_cc_seq_fetch_NCs_next(context, iterator, 1, CC_NOERROR, "iterating over a collection of 1 ccache"); if (iterator) { cc_seq_fetch_creds_end(context, &iterator); iterator = NULL; } // iterate with several ccaches if (!err) { destroy_all_ccaches_v2(context); } for(i = 0; !err && (i < 1000); i++) { char *name = NULL; if (i%100 == 0) fprintf(stdout, "."); asprintf (&name, "TEST_CC_SEQ_FETCH_NCS_NEXT_%d", i); err = cc_create(context, name, "foo@BAR.ORG", CC_CRED_V5, 0, &ccache); if (ccache) { cc_close(context, &ccache); ccache = NULL; } free (name); } if (!err) { err = cc_seq_fetch_NCs_begin(context, &iterator); } check_once_cc_seq_fetch_NCs_next(context, iterator, 1000, CC_NOERROR, "iterating over a collection of 1000 ccache"); if (iterator) { cc_seq_fetch_creds_end(context, &iterator); iterator = NULL; } if (ccache) { cc_close(context, &ccache); } if (iterator) { cc_seq_fetch_creds_end(context, &iterator); } if (context) { destroy_all_ccaches_v2(context); cc_shutdown(&context); } END_TEST_AND_RETURN } // --------------------------------------------------------------------------- cc_result check_once_cc_seq_fetch_NCs_next(apiCB *context, ccache_cit *iterator, cc_uint32 expected_count, cc_result expected_err, const char *description) { cc_result err = CC_NOERROR; cc_result possible_return_values[5] = { CC_NOERROR, CC_END, CC_BAD_PARM, CC_NOMEM, CC_NO_EXIST }; #define possible_ret_val_count sizeof(possible_return_values)/sizeof(possible_return_values[0]) ccache_p *ccache = NULL; cc_uint32 actual_count = 0; BEGIN_CHECK_ONCE(description); while (!err) { err = cc_seq_fetch_NCs_next(context, &ccache, iterator); if (ccache) { actual_count++; cc_close(context, &ccache); ccache = NULL; } } if (err == CC_END) { err = CC_NOERROR; } // check returned error check_err(err, expected_err, possible_return_values); check_if(actual_count != expected_count, "iterator didn't iterate over all ccaches"); END_CHECK_ONCE; return err; } // --------------------------------------------------------------------------- int check_cc_get_NC_info(void) { cc_result err = 0; apiCB *context = NULL; ccache_p *ccache = NULL; unsigned int i; BEGIN_TEST("cc_get_NC_info"); err = cc_initialize(&context, ccapi_version_2, NULL, NULL); if (!err) { err = destroy_all_ccaches_v2(context); } // iterate with no ccaches check_once_cc_get_NC_info(context, "", "", CC_CRED_MAX, 0, CC_NOERROR, "iterating over an empty collection"); // iterate with one ccache if (!err) { destroy_all_ccaches_v2(context); err = cc_create(context, "TEST_CC_GET_NC_INFO", "foo@BAR.ORG", CC_CRED_V5, 0, &ccache); } if (ccache) { cc_close(context, &ccache); ccache = NULL; } check_once_cc_get_NC_info(context, "TEST_CC_GET_NC_INFO", "foo@BAR.ORG", CC_CRED_V5, 1, CC_NOERROR, "iterating over a collection of 1 ccache"); // iterate with several ccaches if (!err) { destroy_all_ccaches_v2(context); } for(i = 0; !err && (i < 1000); i++) { char *name = NULL; if (i%100 == 0) fprintf(stdout, "."); asprintf (&name, "TEST_CC_GET_NC_INFO_%d", i); err = cc_create(context, name, "foo@BAR.ORG", CC_CRED_V5, 0, &ccache); if (ccache) { cc_close(context, &ccache); ccache = NULL; } free (name); } check_once_cc_get_NC_info(context, "TEST_CC_GET_NC_INFO", "foo@BAR.ORG", CC_CRED_V5, 1000, CC_NOERROR, "iterating over a collection of 1000 ccache"); if (ccache) { cc_close(context, &ccache); } if (context) { destroy_all_ccaches_v2(context); cc_shutdown(&context); } END_TEST_AND_RETURN } // --------------------------------------------------------------------------- cc_result check_once_cc_get_NC_info(apiCB *context, const char *expected_name_prefix, const char *expected_principal, cc_int32 expected_version, cc_uint32 expected_count, cc_result expected_err, const char *description) { cc_result err = CC_NOERROR; infoNC **info = NULL; cc_result possible_return_values[4] = { CC_NOERROR, CC_BAD_PARM, CC_NOMEM, CC_NO_EXIST }; #define possible_ret_val_count sizeof(possible_return_values)/sizeof(possible_return_values[0]) cc_uint32 actual_count = 0; BEGIN_CHECK_ONCE(description); err = cc_get_NC_info(context, &info); for (actual_count = 0; !err && info[actual_count]; actual_count++) { check_if(strncmp(info[actual_count]->name, expected_name_prefix, strlen(expected_name_prefix)), "got incorrect ccache name"); check_if(strcmp(info[actual_count]->principal, expected_principal), "got incorrect principal name"); check_if(info[actual_count]->vers != expected_version, "got incorrect cred version"); } // check returned error check_err(err, expected_err, possible_return_values); check_if(actual_count != expected_count, "NC info didn't list all ccaches"); if (info) { cc_free_NC_info (context, &info); } END_CHECK_ONCE; return err; } // --------------------------------------------------------------------------- int check_cc_seq_fetch_creds_begin(void) { cc_result err = 0; apiCB *context = NULL; ccache_p *ccache = NULL; ccache_p *dup_ccache = NULL; ccache_cit *creds_iterator = NULL; char *name = NULL; BEGIN_TEST("cc_seq_fetch_creds_begin"); err = cc_initialize(&context, ccapi_version_2, NULL, NULL); if (!err) { err = destroy_all_ccaches_v2(context); } if (!err) { err = cc_create(context, "TEST_CC_SEQ_FETCH_CREDS_BEGIN", "foo@BAR.ORG", CC_CRED_V5, 0, &ccache); } // valid params if (!err) { check_once_cc_seq_fetch_creds_begin(context, ccache, &creds_iterator, CC_NOERROR, "valid params"); } if (creds_iterator) { cc_seq_fetch_creds_end(context, &creds_iterator); creds_iterator = NULL; } // NULL out param if (!err) { check_once_cc_seq_fetch_creds_begin(context, ccache, NULL, CC_BAD_PARM, "NULL out iterator param"); } if (creds_iterator) { cc_seq_fetch_creds_end(context, &creds_iterator); creds_iterator = NULL; } // non-existent ccache if (ccache) { err = cc_get_name(context, ccache, &name); if (!err) { err = cc_open(context, name, CC_CRED_V5, 0, &dup_ccache); } if (name) { cc_free_name(context, &name); } if (dup_ccache) { cc_destroy(context, &dup_ccache); } } if (!err) { check_once_cc_seq_fetch_creds_begin(context, ccache, &creds_iterator, CC_NO_EXIST, "invalid ccache"); } if (creds_iterator) { cc_seq_fetch_creds_end(context, &creds_iterator); creds_iterator = NULL; } if (ccache) { cc_close(context, &ccache); } if (context) { destroy_all_ccaches_v2(context); cc_shutdown(&context); } END_TEST_AND_RETURN } // --------------------------------------------------------------------------- cc_result check_once_cc_seq_fetch_creds_begin(apiCB *context, ccache_p *ccache, ccache_cit **iterator, cc_result expected_err, const char *description) { cc_result err = CC_NOERROR; cc_result possible_return_values[5] = { CC_NOERROR, CC_BAD_PARM, CC_NOMEM, CC_NO_EXIST }; BEGIN_CHECK_ONCE(description); #define possible_ret_val_count sizeof(possible_return_values)/sizeof(possible_return_values[0]) err = cc_seq_fetch_creds_begin(context, ccache, iterator); // check returned error check_err(err, expected_err, possible_return_values); END_CHECK_ONCE; return err; } // --------------------------------------------------------------------------- int check_cc_seq_fetch_creds_next(void) { cc_result err = 0; apiCB *context = NULL; ccache_p *ccache = NULL; cred_union creds_union; ccache_cit *iterator = NULL; unsigned int i; BEGIN_TEST("cc_seq_fetch_creds_next"); err = cc_initialize(&context, ccapi_version_2, NULL, NULL); if (!err) { err = destroy_all_ccaches_v2(context); } // iterate with no creds if (!err) { err = cc_create(context, "TEST_CC_SEQ_FETCH_CREDS_NEXT", "foo@BAR.ORG", CC_CRED_V5, 0, &ccache); } if (!err) { err = cc_seq_fetch_creds_begin(context, ccache, &iterator); } check_once_cc_seq_fetch_creds_next(context, iterator, 0, CC_NOERROR, "iterating over an empty ccache"); if (iterator) { cc_seq_fetch_creds_end(context, &iterator); iterator = NULL; } if (ccache) { cc_close(context, &ccache); ccache = NULL; } // iterate with one cred if (!err) { destroy_all_ccaches_v2(context); err = cc_create(context, "TEST_CC_SEQ_FETCH_CREDS_NEXT", "foo@BAR.ORG", CC_CRED_V5, 0, &ccache); } if (!err) { new_v5_creds_union_compat(&creds_union, "BAR.ORG"); err = cc_store(context, ccache, creds_union); release_v5_creds_union_compat(&creds_union); } if (!err) { err = cc_seq_fetch_creds_begin(context, ccache, &iterator); } check_once_cc_seq_fetch_creds_next(context, iterator, 1, CC_NOERROR, "iterating over a ccache with 1 cred"); if (iterator) { cc_seq_fetch_creds_end(context, &iterator); iterator = NULL; } if (ccache) { cc_close(context, &ccache); ccache = NULL; } // iterate with several creds if (!err) { destroy_all_ccaches_v2(context); err = cc_create(context, "TEST_CC_SEQ_FETCH_CREDS_NEXT", "foo@BAR.ORG", CC_CRED_V5, 0, &ccache); } for(i = 0; !err && (i < 1000); i++) { if (i%100 == 0) fprintf(stdout, "."); new_v5_creds_union_compat(&creds_union, "BAR.ORG"); err = cc_store(context, ccache, creds_union); release_v5_creds_union_compat(&creds_union); } if (!err) { err = cc_seq_fetch_creds_begin(context, ccache, &iterator); } check_once_cc_seq_fetch_creds_next(context, iterator, 1000, CC_NOERROR, "iterating over a ccache with 1000 creds"); if (ccache) { cc_close(context, &ccache); } if (iterator) { cc_seq_fetch_creds_end(context, &iterator); } if (context) { destroy_all_ccaches_v2(context); cc_shutdown(&context); } END_TEST_AND_RETURN } // --------------------------------------------------------------------------- cc_result check_once_cc_seq_fetch_creds_next(apiCB *context, ccache_cit *iterator, cc_uint32 expected_count, cc_result expected_err, const char *description) { cc_result err = CC_NOERROR; cred_union *creds = NULL; cc_uint32 actual_count = 0; cc_result possible_return_values[5] = { CC_NOERROR, CC_END, CC_BAD_PARM, CC_NOMEM, CC_NO_EXIST, }; BEGIN_CHECK_ONCE(description); #define possible_ret_val_count sizeof(possible_return_values)/sizeof(possible_return_values[0]) while (!err) { err = cc_seq_fetch_creds_next(context, &creds, iterator); if (creds) { actual_count++; cc_free_creds(context, &creds); creds = NULL; } } if (err == CC_END) { err = CC_NOERROR; } // check returned error check_err(err, expected_err, possible_return_values); check_if(actual_count != expected_count, "iterator didn't iterate over all ccaches"); END_CHECK_ONCE; return err; } krb5-1.16/src/ccapi/test/test_cc_ccache_move.c0000644000704600001450000000045713211554426021135 0ustar ghudsonlibuuid#include #include #include "test_ccapi_check.h" #include "test_ccapi_constants.h" #include "test_ccapi_context.h" #include "test_ccapi_ccache.h" int main (int argc, const char * argv[]) { cc_int32 err = ccNoError; T_CCAPI_INIT; err = check_cc_ccache_move(); return err; } krb5-1.16/src/ccapi/test/test_cc_get_cred_version.c0000644000704600001450000000043113211554426022212 0ustar ghudsonlibuuid#include #include #include "test_ccapi_check.h" #include "test_ccapi_constants.h" #include "test_ccapi_v2.h" int main (int argc, const char * argv[]) { cc_int32 err = ccNoError; T_CCAPI_INIT; err = check_cc_get_cred_version(); return err; } krb5-1.16/src/ccapi/test/test_cc_context_compare.c0000644000704600001450000000046313211554426022070 0ustar ghudsonlibuuid#include #include #include "test_ccapi_check.h" #include "test_ccapi_constants.h" #include "test_ccapi_context.h" #include "test_ccapi_ccache.h" int main (int argc, const char * argv[]) { cc_int32 err = ccNoError; T_CCAPI_INIT; err = check_cc_context_compare(); return err; } krb5-1.16/src/ccapi/test/test_ccapi_iterators.h0000644000704600001450000000103113211554426021401 0ustar ghudsonlibuuid#ifndef _TEST_CCAPI_ITERATORS_H_ #define _TEST_CCAPI_ITERATORS_H_ #include "test_ccapi_globals.h" int check_cc_ccache_iterator_next(void); cc_int32 check_once_cc_ccache_iterator_next(cc_ccache_iterator_t iterator, cc_uint32 expected_count, cc_int32 expected_err, const char *description); int check_cc_credentials_iterator_next(void); cc_int32 check_once_cc_credentials_iterator_next(cc_credentials_iterator_t iterator, cc_uint32 expected_count, cc_int32 expected_err, const char *description); #endif /* _TEST_CCAPI_ITERATORS_H_ */ krb5-1.16/src/ccapi/test/test_cc_ccache_get_credentials_version.c0000644000704600001450000000050213211554426025057 0ustar ghudsonlibuuid#include #include #include "test_ccapi_check.h" #include "test_ccapi_constants.h" #include "test_ccapi_context.h" #include "test_ccapi_ccache.h" int main (int argc, const char * argv[]) { cc_int32 err = ccNoError; T_CCAPI_INIT; err = check_cc_ccache_get_credentials_version(); return err; } krb5-1.16/src/ccapi/test/test_cc_set_principal.c0000644000704600001450000000042613211554426021531 0ustar ghudsonlibuuid#include #include #include "test_ccapi_check.h" #include "test_ccapi_constants.h" #include "test_ccapi_v2.h" int main (int argc, const char * argv[]) { cc_int32 err = ccNoError; T_CCAPI_INIT; err = check_cc_set_principal(); return err; } krb5-1.16/src/ccapi/test/test_cc_seq_fetch_NCs_next.c0000644000704600001450000000043313211554426022435 0ustar ghudsonlibuuid#include #include #include "test_ccapi_check.h" #include "test_ccapi_constants.h" #include "test_ccapi_v2.h" int main (int argc, const char * argv[]) { cc_int32 err = ccNoError; T_CCAPI_INIT; err = check_cc_seq_fetch_NCs_next(); return err; } krb5-1.16/src/ccapi/test/test_cc_ccache_clear_kdc_time_offset.c0000644000704600001450000000050013211554426024447 0ustar ghudsonlibuuid#include #include #include "test_ccapi_check.h" #include "test_ccapi_constants.h" #include "test_ccapi_context.h" #include "test_ccapi_ccache.h" int main (int argc, const char * argv[]) { cc_int32 err = ccNoError; T_CCAPI_INIT; err = check_cc_ccache_clear_kdc_time_offset(); return err; } krb5-1.16/src/ccapi/test/test_ccapi_iterators.c0000644000704600001450000001445713211554426021414 0ustar ghudsonlibuuid#include "test_ccapi_globals.h" #include "test_ccapi_iterators.h" #include "test_ccapi_check.h" #include "test_ccapi_util.h" // --------------------------------------------------------------------------- int check_cc_ccache_iterator_next(void) { cc_int32 err = 0; cc_context_t context = NULL; cc_ccache_t ccache = NULL; cc_ccache_iterator_t iterator = NULL; unsigned int i; BEGIN_TEST("cc_ccache_iterator_next"); err = cc_initialize(&context, ccapi_version_3, NULL, NULL); if (!err) { err = destroy_all_ccaches(context); } // iterate with no ccaches if (!err) { err = cc_context_new_ccache_iterator(context, &iterator); } check_once_cc_ccache_iterator_next(iterator, 0, ccNoError, "iterating over an empty collection"); if (iterator) { cc_ccache_iterator_release(iterator); iterator = NULL; } // iterate with one ccache if (!err) { destroy_all_ccaches(context); err = cc_context_create_new_ccache(context, cc_credentials_v5, "foo@BAR.ORG", &ccache); } if (ccache) { cc_ccache_release(ccache); ccache = NULL; } if (!err) { err = cc_context_new_ccache_iterator(context, &iterator); } check_once_cc_ccache_iterator_next(iterator, 1, ccNoError, "iterating over a collection of 1 ccache"); if (iterator) { cc_ccache_iterator_release(iterator); iterator = NULL; } // iterate with several ccaches if (!err) { destroy_all_ccaches(context); } for(i = 0; !err && (i < 1000); i++) { if (i%100 == 0) fprintf(stdout, "."); err = cc_context_create_new_ccache(context, cc_credentials_v5, "foo@BAR.ORG", &ccache); if (ccache) { cc_ccache_release(ccache); ccache = NULL; } } if (!err) { err = cc_context_new_ccache_iterator(context, &iterator); } check_once_cc_ccache_iterator_next(iterator, 1000, ccNoError, "iterating over a collection of 1000 ccache"); if (iterator) { cc_ccache_iterator_release(iterator); iterator = NULL; } if (ccache) { cc_ccache_release(ccache); } if (iterator) { cc_ccache_iterator_release(iterator); } if (context) { destroy_all_ccaches(context); cc_context_release(context); } END_TEST_AND_RETURN } cc_int32 check_once_cc_ccache_iterator_next(cc_ccache_iterator_t iterator, cc_uint32 expected_count, cc_int32 expected_err, const char *description) { cc_int32 err = ccNoError; // BEGIN_CHECK_ONCE(description); cc_int32 possible_return_values[6] = { ccNoError, ccIteratorEnd, ccErrBadParam, ccErrNoMem, ccErrInvalidCCacheIterator, ccErrCCacheNotFound, }; #define possible_ret_val_count sizeof(possible_return_values)/sizeof(possible_return_values[0]) cc_ccache_t ccache = NULL; cc_uint32 actual_count = 0; while (!err) { err = cc_ccache_iterator_next(iterator, &ccache); if (ccache) { actual_count++; cc_ccache_release(ccache); ccache = NULL; } } if (err == ccIteratorEnd) { err = ccNoError; } // check returned error check_err(err, expected_err, possible_return_values); check_if(actual_count != expected_count, "iterator didn't iterate over all ccaches"); // END_CHECK_ONCE; return err; } // --------------------------------------------------------------------------- int check_cc_credentials_iterator_next(void) { cc_int32 err = 0; cc_context_t context = NULL; cc_ccache_t ccache = NULL; cc_credentials_union creds_union; cc_credentials_iterator_t iterator = NULL; unsigned int i; BEGIN_TEST("cc_credentials_iterator_next"); err = cc_initialize(&context, ccapi_version_3, NULL, NULL); if (!err) { err = destroy_all_ccaches(context); } // iterate with no creds if (!err) { err = cc_context_create_new_ccache(context, cc_credentials_v5, "foo@BAR.ORG", &ccache); } if (!err) { err = cc_ccache_new_credentials_iterator(ccache, &iterator); } check_once_cc_credentials_iterator_next(iterator, 0, ccNoError, "iterating over an empty ccache"); if (iterator) { cc_ccache_iterator_release(iterator); iterator = NULL; } if (ccache) { cc_ccache_release(ccache); ccache = NULL; } // iterate with one cred if (!err) { destroy_all_ccaches(context); err = cc_context_create_new_ccache(context, cc_credentials_v5, "foo@BAR.ORG", &ccache); } if (!err) { new_v5_creds_union(&creds_union, "BAR.ORG"); err = cc_ccache_store_credentials(ccache, &creds_union); release_v5_creds_union(&creds_union); } if (!err) { err = cc_ccache_new_credentials_iterator(ccache, &iterator); } check_once_cc_credentials_iterator_next(iterator, 1, ccNoError, "iterating over a ccache with 1 cred"); if (iterator) { cc_credentials_iterator_release(iterator); iterator = NULL; } if (ccache) { cc_ccache_release(ccache); ccache = NULL; } // iterate with several creds if (!err) { destroy_all_ccaches(context); err = cc_context_create_new_ccache(context, cc_credentials_v5, "foo@BAR.ORG", &ccache); } for(i = 0; !err && (i < 1000); i++) { if (i%100 == 0) fprintf(stdout, "."); new_v5_creds_union(&creds_union, "BAR.ORG"); err = cc_ccache_store_credentials(ccache, &creds_union); release_v5_creds_union(&creds_union); } if (!err) { err = cc_ccache_new_credentials_iterator(ccache, &iterator); } check_once_cc_credentials_iterator_next(iterator, 1000, ccNoError, "iterating over a ccache with 1000 creds"); if (ccache) { cc_ccache_release(ccache); } if (iterator) { cc_credentials_iterator_release(iterator); } if (context) { destroy_all_ccaches(context); cc_context_release(context); } END_TEST_AND_RETURN } cc_int32 check_once_cc_credentials_iterator_next(cc_credentials_iterator_t iterator, cc_uint32 expected_count, cc_int32 expected_err, const char *description) { cc_int32 err = ccNoError; cc_credentials_t creds = NULL; cc_uint32 actual_count = 0; cc_int32 possible_return_values[5] = { ccNoError, ccIteratorEnd, ccErrBadParam, ccErrNoMem, ccErrInvalidCredentialsIterator, }; BEGIN_CHECK_ONCE(description); #define possible_ret_val_count sizeof(possible_return_values)/sizeof(possible_return_values[0]) while (!err) { err = cc_credentials_iterator_next(iterator, &creds); if (creds) { actual_count++; cc_credentials_release(creds); creds = NULL; } } if (err == ccIteratorEnd) { err = ccNoError; } // check returned error check_err(err, expected_err, possible_return_values); check_if(actual_count != expected_count, "iterator didn't iterate over all ccaches"); END_CHECK_ONCE; return err; } krb5-1.16/src/ccapi/test/test_ccapi_check.h0000644000704600001450000000311713211554426020451 0ustar ghudsonlibuuid#ifndef _TEST_CCAPI_CHECK_H_ #define _TEST_CCAPI_CHECK_H_ #include #include #include "test_ccapi_log.h" #include "test_ccapi_globals.h" int _check_if(int expression, const char *file, int line, const char *expression_string, const char *format, ...); #define check_int(a, b) \ check_if(a != b, NULL) /* * if expression evaluates to true, check_if increments the failure_count and prints: * * check_if(a!=a, NULL); * ==> "/path/to/file:line: a!=a" * * check_if(a!=a, "This shouldn't be happening"); * ==> "/path/to/file:line: This shouldn't be happening" * * check_if(a!=a, "This has happened %d times now", 3); * ==> "/path/to/file:line: This has happened 3 times now" */ #define check_if(expression, format, ...) \ _check_if(expression, __FILE__, __LINE__, #expression, format , ## __VA_ARGS__) #define check_if_not(expression, format, ...) \ check_if(!(expression), format, ## __VA_ARGS__) // first check if err is what we were expecting to get back // then check if err is even in the set of errors documented for the function #define check_err(err, expected_err, possible_return_values) \ do { \ check_if(err != expected_err, "unexpected error %s (%d), expected %s (%d)", translate_ccapi_error(err), err, translate_ccapi_error(expected_err), expected_err); \ check_if_not(array_contains_int(possible_return_values, possible_ret_val_count, err), "error not documented as a possible return value: %s (%d)", translate_ccapi_error(err), err); \ } while( 0 ) int array_contains_int(cc_int32 *array, int size, cc_int32 value); #endif /* _TEST_CCAPI_CHECK_H_ */ krb5-1.16/src/ccapi/test/test_ccapi_util.h0000644000704600001450000000067113211554426020353 0ustar ghudsonlibuuid#ifndef _TEST_CCAPI_UTIL_H_ #define _TEST_CCAPI_UTIL_H_ #include "test_ccapi_globals.h" #include "test_ccapi_log.h" cc_int32 destroy_all_ccaches(cc_context_t context); cc_int32 new_v5_creds_union(cc_credentials_union *out_union, const char *realm); void release_v5_creds_union(cc_credentials_union *creds_union); int compare_v5_creds_unions(const cc_credentials_union *a, const cc_credentials_union *b); #endif /* _TEST_CCAPI_UTIL_H_ */ krb5-1.16/src/ccapi/test/test_ccapi_constants.c0000644000704600001450000000472213211554426021406 0ustar ghudsonlibuuid#include "test_ccapi_constants.h" #include "test_ccapi_globals.h" #include "test_ccapi_check.h" int check_constants(void) { BEGIN_TEST("constants"); /* API versions */ check_int(ccapi_version_2, 2); check_int(ccapi_version_3, 3); check_int(ccapi_version_4, 4); check_int(ccapi_version_5, 5); check_int(ccapi_version_6, 6); /* Errors */ check_int(ccNoError , 0 ); // 0 check_int(ccIteratorEnd , 201); // 201 check_int(ccErrBadParam , 202); // 202 check_int(ccErrNoMem , 203); // 203 check_int(ccErrInvalidContext , 204); // 204 check_int(ccErrInvalidCCache , 205); // 205 check_int(ccErrInvalidString , 206); // 206 check_int(ccErrInvalidCredentials , 207); // 207 check_int(ccErrInvalidCCacheIterator , 208); // 208 check_int(ccErrInvalidCredentialsIterator , 209); // 209 check_int(ccErrInvalidLock , 210); // 210 check_int(ccErrBadName , 211); // 211 check_int(ccErrBadCredentialsVersion , 212); // 212 check_int(ccErrBadAPIVersion , 213); // 213 check_int(ccErrContextLocked , 214); // 214 check_int(ccErrContextUnlocked , 215); // 215 check_int(ccErrCCacheLocked , 216); // 216 check_int(ccErrCCacheUnlocked , 217); // 217 check_int(ccErrBadLockType , 218); // 218 check_int(ccErrNeverDefault , 219); // 219 check_int(ccErrCredentialsNotFound , 220); // 220 check_int(ccErrCCacheNotFound , 221); // 221 check_int(ccErrContextNotFound , 222); // 222 check_int(ccErrServerUnavailable , 223); // 223 check_int(ccErrServerInsecure , 224); // 224 check_int(ccErrServerCantBecomeUID , 225); // 225 check_int(ccErrTimeOffsetNotSet , 226); // 226 check_int(ccErrBadInternalMessage , 227); // 227 check_int(ccErrNotImplemented , 228); // 228 /* Credentials versions */ check_int(cc_credentials_v4, 1); check_int(cc_credentials_v5, 2); check_int(cc_credentials_v4_v5, (cc_credentials_v4 | cc_credentials_v5)); /* Lock types */ check_int(cc_lock_read, 0); check_int(cc_lock_write, 1); check_int(cc_lock_upgrade, 2); check_int(cc_lock_downgrade, 3); /* Locking Modes */ check_int(cc_lock_noblock, 0); check_int(cc_lock_block, 1); END_TEST_AND_RETURN } krb5-1.16/src/ccapi/test/test_cc_context_release.c0000644000704600001450000000046313211554426022062 0ustar ghudsonlibuuid#include #include #include "test_ccapi_check.h" #include "test_ccapi_constants.h" #include "test_ccapi_context.h" #include "test_ccapi_ccache.h" int main (int argc, const char * argv[]) { cc_int32 err = ccNoError; T_CCAPI_INIT; err = check_cc_context_release(); return err; } krb5-1.16/src/ccapi/test/test_cc_store.c0000644000704600001450000000041613211554426020030 0ustar ghudsonlibuuid#include #include #include "test_ccapi_check.h" #include "test_ccapi_constants.h" #include "test_ccapi_v2.h" int main (int argc, const char * argv[]) { cc_int32 err = ccNoError; T_CCAPI_INIT; err = check_cc_store(); return err; } krb5-1.16/src/ccapi/test/pingtest.c0000644000704600001450000000705313211554426017031 0ustar ghudsonlibuuid// pingtest.c // // Test RPC to server, with PING message, which exists for no other purpose than this test. #include #include #include #include #include "cci_debugging.h" #include "CredentialsCache.h" #include "win-utils.h" #include "ccs_request.h" #define CLIENT_REQUEST_RPC_HANDLE ccs_request_IfHandle extern cc_int32 cci_os_ipc_thread_init (void); extern cc_int32 cci_os_ipc_msg( cc_int32 in_launch_server, k5_ipc_stream in_request_stream, cc_int32 in_msg, k5_ipc_stream* out_reply_stream); static DWORD dwTlsIndex; DWORD GetTlsIndex() {return dwTlsIndex;} RPC_STATUS send_test(char* endpoint) { unsigned char* pszNetworkAddress = NULL; unsigned char* pszOptions = NULL; unsigned char* pszStringBinding = NULL; unsigned char* pszUuid = NULL; RPC_STATUS status; status = RpcStringBindingCompose(pszUuid, (RPC_CSTR)"ncalrpc", pszNetworkAddress, (unsigned char*)endpoint, pszOptions, &pszStringBinding); cci_debug_printf("%s pszStringBinding = %s", __FUNCTION__, pszStringBinding); if (status) {return cci_check_error(status);} /* Set the binding handle that will be used to bind to the RPC server [the 'client']. */ status = RpcBindingFromStringBinding(pszStringBinding, &CLIENT_REQUEST_RPC_HANDLE); if (status) {return cci_check_error(status);} status = RpcStringFree(&pszStringBinding); // Temp var no longer needed. if (!status) { RpcTryExcept { cci_debug_printf("%s calling remote procedure 'ccs_authenticate'", __FUNCTION__); status = ccs_authenticate((CC_CHAR*)"DLLMAIN TEST!"); cci_debug_printf(" ccs_authenticate returned %d", status); } RpcExcept(1) { status = cci_check_error(RpcExceptionCode()); } RpcEndExcept } cci_check_error(RpcBindingFree(&CLIENT_REQUEST_RPC_HANDLE)); return (status); } int main( int argc, char *argv[]) { cc_int32 err = 0; cc_context_t context = NULL; k5_ipc_stream send_stream = NULL; k5_ipc_stream reply_stream = NULL; char* message = "Hello, RPC!"; if ((dwTlsIndex = TlsAlloc()) == TLS_OUT_OF_INDEXES) return FALSE; // send_test("krbcc.229026.0.ep"); #if 0 err = cc_initialize(&context, ccapi_version_7, NULL, NULL); #endif if (!err) { err = cci_os_ipc_thread_init(); } if (!err) { err = krb5int_ipc_stream_new (&send_stream); err = krb5int_ipc_stream_write(send_stream, message, 1+strlen(message)); } if (!err) { err = cci_os_ipc_msg(TRUE, send_stream, CCMSG_PING, &reply_stream); } Sleep(10*1000); cci_debug_printf("Try finishing async call."); Sleep(INFINITE); cci_debug_printf("main: return. err == %d", err); return 0; } /*********************************************************************/ /* MIDL allocate and free */ /*********************************************************************/ void __RPC_FAR * __RPC_USER midl_user_allocate(size_t len) { return(malloc(len)); } void __RPC_USER midl_user_free(void __RPC_FAR * ptr) { free(ptr); } krb5-1.16/src/ccapi/test/test_cc_open.c0000644000704600001450000000041513211554426017634 0ustar ghudsonlibuuid#include #include #include "test_ccapi_check.h" #include "test_ccapi_constants.h" #include "test_ccapi_v2.h" int main (int argc, const char * argv[]) { cc_int32 err = ccNoError; T_CCAPI_INIT; err = check_cc_open(); return err; } krb5-1.16/src/ccapi/test/test_cc_get_principal.c0000644000704600001450000000042613211554426021515 0ustar ghudsonlibuuid#include #include #include "test_ccapi_check.h" #include "test_ccapi_constants.h" #include "test_ccapi_v2.h" int main (int argc, const char * argv[]) { cc_int32 err = ccNoError; T_CCAPI_INIT; err = check_cc_get_principal(); return err; } krb5-1.16/src/ccapi/test/test_cc_ccache_iterator_next.c0000644000704600001450000000047013211554426023051 0ustar ghudsonlibuuid#include #include #include "test_ccapi_check.h" #include "test_ccapi_constants.h" #include "test_ccapi_context.h" #include "test_ccapi_ccache.h" int main (int argc, const char * argv[]) { cc_int32 err = ccNoError; T_CCAPI_INIT; err = check_cc_ccache_iterator_next(); return err; } krb5-1.16/src/ccapi/test/test_cc_ccache_get_last_default_time.c0000644000704600001450000000050013211554426024500 0ustar ghudsonlibuuid#include #include #include "test_ccapi_check.h" #include "test_ccapi_constants.h" #include "test_ccapi_context.h" #include "test_ccapi_ccache.h" int main (int argc, const char * argv[]) { cc_int32 err = ccNoError; T_CCAPI_INIT; err = check_cc_ccache_get_last_default_time(); return err; } krb5-1.16/src/ccapi/test/simple_lock_test.c0000644000704600001450000000430013211554426020524 0ustar ghudsonlibuuid/* simple_lock_test.c Initializes two contexts in two different threads and tries to get read locks on both at the same time. Hangs at line 24. */ #include #include #include "test_ccapi_log.h" #if defined(macintosh) || (defined(__MACH__) && defined(__APPLE__)) #include #endif #ifdef TARGET_OS_MAC #include #include #include #else #include "CredentialsCache.h" #endif void *other_thread (void) { cc_int32 err; cc_context_t context = NULL; err = cc_initialize(&context, ccapi_version_7, NULL, NULL); log_error("thread: attempting lock. may hang. err == %d", err); if (!err) { // hangs with cc_lock_read which should succeed immediately, but does not hang with write, upgrade, and downgrade, which fail immediately err = cc_context_lock(context, cc_lock_read, cc_lock_noblock); } if (context) { cc_context_unlock(context); cc_context_release(context); context = NULL; } log_error("thread: return. err == %d", err); } int main (int argc, char *argv[]) { cc_int32 err; int status; cc_context_t context = NULL; #ifdef TARGET_OS_MAC pthread_t thread_id; #endif err = cc_initialize(&context, ccapi_version_7, NULL, NULL); if (!err) { err = cc_context_lock(context, cc_lock_read, cc_lock_noblock); } log_error("main: initialized and read locked context. err == %d", err); #ifdef TARGET_OS_MAC status = pthread_create (&thread_id, NULL, (void *) other_thread, NULL); if (status != 0) { log_error("pthread_create() returned %d", status); exit(-1); } pthread_join(thread_id, NULL); #else #endif log_error("main: unlocking and releasing context. err == %d", err); if (context) { log_error("main: calling cc_context_unlock"); cc_context_unlock(context); log_error("main: calling cc_context_release"); cc_context_release(context); context = NULL; } log_error("main: return. err == %d", err); #if defined(_WIN32) UNREFERENCED_PARAMETER(status); // no whining! #endif return 0; } krb5-1.16/src/ccapi/test/test_cc_context_create_ccache.c0000644000704600001450000000047113211554426023172 0ustar ghudsonlibuuid#include #include #include "test_ccapi_check.h" #include "test_ccapi_constants.h" #include "test_ccapi_context.h" #include "test_ccapi_ccache.h" int main (int argc, const char * argv[]) { cc_int32 err = ccNoError; T_CCAPI_INIT; err = check_cc_context_create_ccache(); return err; } krb5-1.16/src/ccapi/test/test_ccapi.sh0000644000704600001450000000417113211554426017500 0ustar ghudsonlibuuid#!/bin/sh # run with ./test-ccapi.sh to run CCAPI tests TEST_DIR="tests" failure_count=0 function run_test { if [[ -e $TEST_DIR/$1 ]]; then ./$TEST_DIR/$1 failure_count=`expr $failure_count + $?` fi } printf "\nBeginning test of CCAPI...\n" printf "\nThese tests are based on the CCAPI v3 revision 8 draft documentation.\n" run_test simple_lock_test run_test test_constants run_test test_cc_initialize run_test test_cc_context_release run_test test_cc_context_get_change_time run_test test_cc_context_get_default_ccache_name run_test test_cc_context_open_ccache run_test test_cc_context_open_default_ccache run_test test_cc_context_create_ccache run_test test_cc_context_create_default_ccache run_test test_cc_context_create_new_ccache run_test test_cc_context_new_ccache_iterator run_test test_cc_context_compare run_test test_cc_ccache_release run_test test_cc_ccache_destroy run_test test_cc_ccache_set_default run_test test_cc_ccache_get_credentials_version run_test test_cc_ccache_get_name run_test test_cc_ccache_get_principal run_test test_cc_ccache_set_principal run_test test_cc_ccache_store_credentials run_test test_cc_ccache_remove_credentials run_test test_cc_ccache_new_credentials_iterator run_test test_cc_ccache_get_change_time run_test test_cc_ccache_get_last_default_time run_test test_cc_ccache_move run_test test_cc_ccache_compare run_test test_cc_ccache_get_kdc_time_offset run_test test_cc_ccache_set_kdc_time_offset run_test test_cc_ccache_clear_kdc_time_offset run_test test_cc_ccache_iterator_next run_test test_cc_credentials_iterator_next run_test test_cc_shutdown run_test test_cc_get_change_time run_test test_cc_open run_test test_cc_create run_test test_cc_close run_test test_cc_destroy run_test test_cc_get_cred_version run_test test_cc_get_name run_test test_cc_get_principal run_test test_cc_set_principal run_test test_cc_store run_test test_cc_remove_cred run_test test_cc_seq_fetch_NCs_begin run_test test_cc_seq_fetch_NCs_next run_test test_cc_seq_fetch_creds_begin run_test test_cc_seq_fetch_creds_next run_test test_cc_get_NC_info printf "\nFinished testing CCAPI. $failure_count failures in total.\n" exit 0krb5-1.16/src/ccapi/test/test_cc_ccache_set_default.c0000644000704600001450000000046613211554426022466 0ustar ghudsonlibuuid#include #include #include "test_ccapi_check.h" #include "test_ccapi_constants.h" #include "test_ccapi_context.h" #include "test_ccapi_ccache.h" int main (int argc, const char * argv[]) { cc_int32 err = ccNoError; T_CCAPI_INIT; err = check_cc_ccache_set_default(); return err; } krb5-1.16/src/ccapi/test/Makefile.in0000644000704600001450000001731513211554426017077 0ustar ghudsonlibuuidmydir=ccapi$(S)test BUILDTOP=..$(S).. CCAPI=$(BUILDTOP)$(S)CCAPI !if defined(KRB5_KFW_COMPILE) KFWINC= /I$(BUILDTOP)\..\..\krbcc\include !endif # Because all the sources are in ., # the only includes we need are to directories outside of ccapi. LOCALINCLUDES = /I$(BUILDTOP) /I$(BUILDTOP)$(S)include /I$(BUILDTOP)$(S)include$(S)krb5 $(KFWINC) \ -I$(BUILDTOP)$(S)util$(S)et /I. -I$(CCAPI)$(S)COMMON -I$(CCAPI)$(S)LIB # run with "make all" to create CCAPI tests in "/tmp/ccapi_test" # run resulting tests with "sh test_ccapi.sh" ##DOS##CPPFLAGS = $(CPPFLAGS) /EHsc -D_CRTAPI1=_cdecl -D_CRTAPI2=_cdecl -DWINVER=0x0501 \ ##DOS## -D_WIN32_WINNT=0x0501 -D_CRT_SECURE_NO_WARNINGS ##DOS##WINH = cci_debugging.h \ ##DOS## ccs_reply.h \ ##DOS## ccs_request.h \ ##DOS## ccs_request_c.c \ ##DOS## cci_types.h \ ##DOS## win-utils.h ##DOS##LIBSRC=ccapi_ccache.c \ ##DOS## ccapi_ccache_iterator.c \ ##DOS## ccapi_context.c \ ##DOS## ccapi_context_change_time.c \ ##DOS## ccapi_err.c \ ##DOS## ccapi_ipc.c \ ##DOS## ccapi_credentials.c \ ##DOS## ccapi_credentials_iterator.c \ ##DOS## ccapi_string.c \ ##DOS## ccapi_v2.c ##DOS##COMSRC=cci_cred_union.c \ ##DOS## cci_identifier.c \ ##DOS## cci_message.c ##DOS##COWSRC=cci_os_identifier.c SRCDIR = . DSTROOT = $(SRCDIR) OBJDIR = $(DSTROOT)$(S)ccapi_intermediates DSTDIR = $(DSTROOT)$(S)ccapi_test TESTDIR = $(DSTDIR)$(S)tests SRCTMP = $(SRCDIR)\srctmp SCRIPT_NAME = test_ccapi.sh OBJECTS = $(OUTPRE)test_ccapi_ccache.$(OBJEXT) \ $(OUTPRE)test_ccapi_check.$(OBJEXT) \ $(OUTPRE)test_ccapi_constants.$(OBJEXT) \ $(OUTPRE)test_ccapi_context.$(OBJEXT) \ $(OUTPRE)test_ccapi_v2.$(OBJEXT) \ $(OUTPRE)test_ccapi_globals.$(OBJEXT) \ $(OUTPRE)test_ccapi_iterators.$(OBJEXT) \ $(OUTPRE)test_ccapi_log.$(OBJEXT) \ $(OUTPRE)test_ccapi_util.$(OBJEXT) PINGOBJS = $(OUTPRE)ccapi_ccache.$(OBJEXT) \ $(OUTPRE)ccapi_ccache_iterator.$(OBJEXT) \ $(OUTPRE)ccapi_context.$(OBJEXT) \ $(OUTPRE)ccapi_context_change_time.$(OBJEXT) \ $(OUTPRE)ccapi_err.$(OBJEXT) \ $(OUTPRE)ccapi_ipc.$(OBJEXT) \ $(OUTPRE)ccapi_credentials.$(OBJEXT) \ $(OUTPRE)ccapi_credentials_iterator.$(OBJEXT) \ $(OUTPRE)ccapi_string.$(OBJEXT) \ $(OUTPRE)ccapi_v2.$(OBJEXT) \ $(OUTPRE)cci_cred_union.$(OBJEXT) \ $(OUTPRE)cci_identifier.$(OBJEXT) \ $(OUTPRE)cci_os_identifier.$(OBJEXT) \ $(OUTPRE)cci_message.$(OBJEXT) \ $(OUTPRE)ccs_request_c.$(OBJEXT) \ $(OUTPRE)pingtest.$(OBJEXT) \ $(OBJECTS) TESTALLOBJS=$(OUTPRE)main.$(OBJEXT) \ $(OBJECTS) TEST_NAMES = test_cc_ccache_iterator_next \ test_constants \ test_cc_initialize \ test_cc_credentials_iterator_next MORE_TESTS = test_cc_context_release \ test_cc_context_get_change_time \ test_cc_context_get_default_ccache_name \ test_cc_context_open_ccache \ test_cc_context_open_default_ccache \ test_cc_context_create_ccache \ test_cc_context_create_default_ccache \ test_cc_context_create_new_ccache \ test_cc_context_new_ccache_iterator \ test_cc_context_compare \ test_cc_ccache_release \ test_cc_ccache_destroy \ test_cc_ccache_set_default \ test_cc_ccache_get_credentials_version \ test_cc_ccache_get_name \ test_cc_ccache_get_principal \ test_cc_ccache_set_principal \ test_cc_ccache_store_credentials \ test_cc_ccache_remove_credentials \ test_cc_ccache_new_credentials_iterator \ test_cc_ccache_get_change_time \ test_cc_ccache_get_last_default_time \ test_cc_ccache_move \ test_cc_ccache_compare \ test_cc_ccache_get_kdc_time_offset \ test_cc_ccache_set_kdc_time_offset \ test_cc_ccache_clear_kdc_time_offset \ test_cc_shutdown \ test_cc_get_change_time \ test_cc_open \ test_cc_create \ test_cc_close \ test_cc_destroy \ test_cc_get_cred_version \ test_cc_get_name \ test_cc_get_principal \ test_cc_set_principal \ test_cc_store \ test_cc_remove_cred \ test_cc_seq_fetch_NCs_begin \ test_cc_seq_fetch_NCs_next \ test_cc_seq_fetch_creds_begin \ test_cc_seq_fetch_creds_next \ test_cc_get_NC_info ##### Linker LINK = link LIBS = -lkrb5 ##DOS##LIBS = $(CLIB) $(SLIB) advapi32.lib rpcrt4.lib user32.lib ws2_32.lib $(CCLIB).lib LFLAGS = /nologo $(LOPTS) all-mac: setup-test-dir pingtest simple_lock_test build-base build-tests link-tests copy-script success-message all-windows: setup-windows build-base $(OUTPRE)pingtest.exe build-tests build-testall copy-script success-message # compile base files used by all tests build-base: $(PINGOBJS) ##++ These two rules build each element of the list: # compile each test build-tests: $(TEST_NAMES) @echo build-tests complete. $(TEST_NAMES): @echo DBG: $@ $(CC) $(ALL_CFLAGS) -Fe$(TESTDIR)$(S)$@.exe -Fd$(OBJDIR)$(S)$@.obj $@.c $(OBJECTS) $(LIBS) # Clean .obj from .: $(RM) $@.$(OBJEXT) ##-- These two rules build each element of the list. # Make a build directory setup-test-dir: @echo "Removing old destination directory... $(DSTDIR)" if [ -d "$(DSTDIR)" ]; then chmod -R u+w "$(DSTDIR)" && rm -rf "$(DSTDIR)"; fi mkdir -p "$(TESTDIR)" if [ -d "$(OBJDIR)" ]; then chmod -R u+w "$(OBJDIR)" && rm -rf "$(OBJDIR)"; fi mkdir -p "$(OBJDIR)" ## The same trick as used in TEST_NAMES to run an action on each element ofthe list WINH: setup-windows: $(WINH) $(LIBSRC) $(COMSRC) $(COWSRC) if NOT exist $(TESTDIR) mkdir $(TESTDIR) if NOT exist $(OBJDIR) mkdir $(OBJDIR) set LINK = link # This rule assumes that nmake in ..\lib\win has already run. # That is how ..\Makefile.in is set up. $(WINH): copy ..\lib\win\srctmp\$@ . $(LIBSRC): copy ..\lib\$@ . $(COMSRC): copy ..\common\$@ . $(COWSRC): copy ..\common\win\$@ . # This rule assumes that nmake in ..\lib\win\ has already run. $(OUTPRE)pingtest.exe: $(OBJECTS) $(PINGOBJS) # There doesn't appear to be any way to examine a variable and return a value # indicating whether a string is present in it. We use a perl script to # check the LIB variable. If the path to $(CCLIB).lib isn't present, the script # deletes a.tmp and the following nmake actions correct LIB. echo %%PATH%% > a.tmp perl setlib.pl if not exist a.tmp ( @echo Adding ..\lib\win\srctmp to LIB set LIB=%%LIB%%;..\lib\win\srctmp ) $(LINK) $(linkdebug) /map:$(@B)1.map -out:$(*B)1.exe $(conflags) $(PINGOBJS) $(LIBS) $(LINK) $(LFLAGS) /map:$(@B)2.map /out:$(*B)2.exe $(conflags) $(PINGOBJS) $(LIBS) $(conlibsdll) link-tests: $(TEST_NAMES) build-testall: $(TEST_NAMES) $(OBJECTS) $(TESTALLOBJS) testall.exe testall.exe: $(LINK) $(linkdebug) /map:$(@B)1.map -out:$(*B)1.exe $(conflags) $(TESTALLOBJS) $(LIBS) $(conslibdll) simple_lock_test: $(CC) -o $(TESTDIR)/simple_lock_test simple_lock_test.c $(LIBS) copy-script: $(CP) $(SCRIPT_NAME) $(DSTDIR)$(S)$(SCRIPT_NAME) success-message: @echo @echo "CCAPI tests created in $(DSTDIR)" .PHONY: clean clean: -rm -rf "$(OBJDIR)" -rm -rf $(LIBSRC) -rm -rf $(WINH) krb5-1.16/src/ccapi/test/test_cc_get_change_time.c0000644000704600001450000000043013211554426021772 0ustar ghudsonlibuuid#include #include #include "test_ccapi_check.h" #include "test_ccapi_constants.h" #include "test_ccapi_v2.h" int main (int argc, const char * argv[]) { cc_int32 err = ccNoError; T_CCAPI_INIT; err = check_cc_get_change_time(); return err; } krb5-1.16/src/ccapi/test/test_cc_seq_fetch_creds_next.c0000644000704600001450000000043513211554426023054 0ustar ghudsonlibuuid#include #include #include "test_ccapi_check.h" #include "test_ccapi_constants.h" #include "test_ccapi_v2.h" int main (int argc, const char * argv[]) { cc_int32 err = ccNoError; T_CCAPI_INIT; err = check_cc_seq_fetch_creds_next(); return err; } krb5-1.16/src/ccapi/test/test_cc_remove_cred.c0000644000704600001450000000042413211554426021165 0ustar ghudsonlibuuid#include #include #include "test_ccapi_check.h" #include "test_ccapi_constants.h" #include "test_ccapi_v2.h" int main (int argc, const char * argv[]) { cc_int32 err = ccNoError; T_CCAPI_INIT; err = check_cc_remove_cred(); return err; } krb5-1.16/src/ccapi/test/test_cc_ccache_set_kdc_time_offset.c0000644000704600001450000000047613211554426024170 0ustar ghudsonlibuuid#include #include #include "test_ccapi_check.h" #include "test_ccapi_constants.h" #include "test_ccapi_context.h" #include "test_ccapi_ccache.h" int main (int argc, const char * argv[]) { cc_int32 err = ccNoError; T_CCAPI_INIT; err = check_cc_ccache_set_kdc_time_offset(); return err; } krb5-1.16/src/ccapi/test/setlib.pl0000644000704600001450000000026613211554426016646 0ustar ghudsonlibuuid#!perl -w $b = "lib\\win\\srctmp"; $a = $ENV{LIB}; if (! ($a =~ /$b/) ) { print "$b Not in LIB!\n"; system("del a.tmp"); } else {print "$b in LIB.\n";} exit(0);krb5-1.16/src/ccapi/test/test_cc_close.c0000644000704600001450000000041613211554426020001 0ustar ghudsonlibuuid#include #include #include "test_ccapi_check.h" #include "test_ccapi_constants.h" #include "test_ccapi_v2.h" int main (int argc, const char * argv[]) { cc_int32 err = ccNoError; T_CCAPI_INIT; err = check_cc_close(); return err; } krb5-1.16/src/ccapi/test/test_ccapi_ccache.c0000644000704600001450000015163213211554426020603 0ustar ghudsonlibuuid#include #include #include #include #include "test_ccapi_check.h" #include "test_ccapi_util.h" #include "test_ccapi_context.h" #include "test_ccapi_ccache.h" // --------------------------------------------------------------------------- int check_cc_ccache_release(void) { cc_int32 err = 0; cc_context_t context = NULL; cc_ccache_t ccache = NULL; BEGIN_TEST("cc_ccache_release"); #ifndef cc_ccache_release log_error("cc_ccache_release is not implemented yet"); failure_count++; #else err = cc_initialize(&context, ccapi_version_3, NULL, NULL); if (!err) { err = cc_context_create_new_ccache(context, cc_credentials_v5, "foo@BAR.ORG", &ccache); } if (!err) { check_once_cc_ccache_release(context, ccache, ccNoError, NULL); ccache = NULL; } if (context) { cc_context_release(context); } #endif /* cc_ccache_release */ END_TEST_AND_RETURN } cc_int32 check_once_cc_ccache_release(cc_context_t context, cc_ccache_t ccache, cc_int32 expected_err, const char *description) { cc_int32 err = ccNoError; cc_int32 possible_return_values[2] = { ccNoError, ccErrInvalidCCache, }; cc_string_t name = NULL; err = cc_ccache_get_name(ccache, &name); err = cc_ccache_release(ccache); ccache = NULL; BEGIN_CHECK_ONCE(description); #ifdef cc_ccache_release #define possible_ret_val_count sizeof(possible_return_values)/sizeof(possible_return_values[0]) // check returned error check_err(err, expected_err, possible_return_values); if (!err && name) { // try opening released ccache to make sure it still exists err = cc_context_open_ccache(context, name->data, &ccache); } check_if(err == ccErrCCacheNotFound, "released ccache was actually destroyed instead"); if (ccache) { cc_ccache_destroy(ccache); } if (name) { cc_string_release(name); } #endif /* cc_ccache_release */ END_CHECK_ONCE; return err; } // --------------------------------------------------------------------------- int check_cc_ccache_destroy(void) { cc_int32 err = 0; cc_context_t context = NULL; cc_ccache_t ccache = NULL; BEGIN_TEST("cc_ccache_destroy"); #ifndef cc_ccache_destroy log_error("cc_ccache_destroy is not implemented yet"); failure_count++; #else err = cc_initialize(&context, ccapi_version_3, NULL, NULL); if (!err) { err = cc_context_create_new_ccache(context, cc_credentials_v5, "foo@BAR.ORG", &ccache); } if (!err) { check_once_cc_ccache_destroy(context, ccache, ccNoError, NULL); ccache = NULL; } if (context) { cc_context_release(context); } #endif /* cc_ccache_destroy */ END_TEST_AND_RETURN } cc_int32 check_once_cc_ccache_destroy(cc_context_t context, cc_ccache_t ccache, cc_int32 expected_err, const char *description) { cc_int32 err = ccNoError; cc_int32 possible_return_values[2] = { ccNoError, ccErrInvalidCCache, }; cc_string_t name = NULL; BEGIN_CHECK_ONCE(description); #ifdef cc_ccache_destroy #define possible_ret_val_count sizeof(possible_return_values)/sizeof(possible_return_values[0]) err = cc_ccache_get_name(ccache, &name); err = cc_ccache_destroy(ccache); ccache = NULL; // check returned error check_err(err, expected_err, possible_return_values); if (!err && name) { // try opening released ccache to make sure it still exists err = cc_context_open_ccache(context, name->data, &ccache); } check_if(err != ccErrCCacheNotFound, "destroyed ccache was actually released instead"); if (ccache) { cc_ccache_destroy(ccache); } if (name) { cc_string_release(name); } #endif /* cc_ccache_destroy */ END_CHECK_ONCE; return err; } // --------------------------------------------------------------------------- int check_cc_ccache_set_default(void) { cc_int32 err = 0; cc_context_t context = NULL; cc_ccache_t ccache = NULL; BEGIN_TEST("cc_ccache_set_default"); #ifndef cc_ccache_set_default log_error("cc_ccache_set_default is not implemented yet"); failure_count++; #else err = cc_initialize(&context, ccapi_version_3, NULL, NULL); // try when it's the only ccache (already default) if (!err) { err = destroy_all_ccaches(context); } if (!err) { err = cc_context_create_new_ccache(context, cc_credentials_v5, "foo@BAR.ORG", &ccache); } if (!err) { check_once_cc_ccache_set_default(context, ccache, ccNoError, "when it's the only ccache (already default)"); } if (ccache) { err = cc_ccache_release(ccache); ccache = NULL; } // try when it's not the only ccache (and not default) if (!err) { err = cc_context_create_new_ccache(context, cc_credentials_v5, "baz@BAR.ORG", &ccache); } if (!err) { check_once_cc_ccache_set_default(context, ccache, ccNoError, "when it's not the only ccache (and not default)"); } if (ccache) { err = cc_ccache_release(ccache); ccache = NULL; } // try when it's not the only ccache (and already default) if (!err) { err = cc_context_open_default_ccache(context, &ccache); } if (!err) { check_once_cc_ccache_set_default(context, ccache, ccNoError, "when it's not the only ccache (and already default)"); } if (ccache) { err = cc_ccache_release(ccache); ccache = NULL; } if (!err) { err = destroy_all_ccaches(context); } if (context) { cc_context_release(context); } #endif /* cc_ccache_set_default */ END_TEST_AND_RETURN } cc_int32 check_once_cc_ccache_set_default(cc_context_t context, cc_ccache_t ccache, cc_int32 expected_err, const char *description) { cc_int32 err = ccNoError; cc_int32 possible_return_values[3] = { ccNoError, ccErrInvalidCCache, ccErrCCacheNotFound, }; cc_ccache_t default_ccache = NULL; cc_string_t name = NULL; cc_string_t default_name = NULL; BEGIN_CHECK_ONCE(description); #ifdef cc_ccache_set_default #define possible_ret_val_count sizeof(possible_return_values)/sizeof(possible_return_values[0]) err = cc_ccache_set_default(ccache); // check returned error check_err(err, expected_err, possible_return_values); if (!err) { err = cc_ccache_get_name(ccache, &name); } if (!err) { err = cc_context_open_default_ccache(context, &default_ccache); } if (!err) { err = cc_ccache_get_name(default_ccache, &default_name); } if (name && default_name) { check_if(strcmp(name->data, default_name->data), NULL); } else { check_if(1, "cc_ccache_get_name failed"); } if (default_ccache) { cc_ccache_release(default_ccache); } //if (ccache) { cc_ccache_destroy(ccache); } // ccache is released by the caller if (default_name) { cc_string_release(default_name); } if (name) { cc_string_release(name); } #endif /* cc_ccache_set_default */ END_CHECK_ONCE; return err; } // --------------------------------------------------------------------------- int check_cc_ccache_get_credentials_version(void) { cc_int32 err = 0; cc_context_t context = NULL; cc_ccache_t ccache = NULL; BEGIN_TEST("cc_ccache_get_credentials_version"); #ifndef cc_ccache_get_credentials_version log_error("cc_ccache_get_credentials_version is not implemented yet"); failure_count++; #else err = cc_initialize(&context, ccapi_version_3, NULL, NULL); // try one created with v5 creds if (!err) { err = cc_context_create_new_ccache(context, cc_credentials_v5, "foo@BAR.ORG", &ccache); } if (!err) { check_once_cc_ccache_get_credentials_version(ccache, cc_credentials_v5, ccNoError, "v5 creds"); } else { log_error("cc_context_create_new_ccache failed, can't complete test"); failure_count++; } // try it with added v4 creds if (!err) { err = cc_ccache_set_principal(ccache, cc_credentials_v4, "foo@BAR.ORG"); } if (!err) { check_once_cc_ccache_get_credentials_version(ccache, cc_credentials_v4_v5, ccNoError, "v5 with v4 creds added"); } else { log_error("cc_ccache_set_principal failed, can't complete test"); failure_count++; } if (ccache) { cc_ccache_destroy(ccache); ccache = NULL; } err = ccNoError; // try one created with v4 creds if (!err) { err = cc_context_create_new_ccache(context, cc_credentials_v4, "foo@BAR.ORG", &ccache); } if (!err) { check_once_cc_ccache_get_credentials_version(ccache, cc_credentials_v4, ccNoError, "v4 creds"); } else { log_error("cc_context_create_new_ccache failed, can't complete test"); failure_count++; } // try it with added v5 creds if (!err) { err = cc_ccache_set_principal(ccache, cc_credentials_v5, "foo@BAR.ORG"); } if (!err) { check_once_cc_ccache_get_credentials_version(ccache, cc_credentials_v4_v5, ccNoError, "v4 with v5 creds added"); } else { log_error("cc_ccache_set_principal failed, can't complete test"); failure_count++; } if (ccache) { cc_ccache_destroy(ccache); ccache = NULL; } if (context) { cc_context_release(context); } #endif /* cc_ccache_get_credentials_version */ END_TEST_AND_RETURN } cc_int32 check_once_cc_ccache_get_credentials_version(cc_ccache_t ccache, cc_uint32 expected_cred_vers, cc_int32 expected_err, const char *description) { cc_int32 err = ccNoError; cc_int32 possible_return_values[4] = { ccNoError, ccErrInvalidCCache, ccErrBadParam, ccErrCCacheNotFound, }; cc_uint32 stored_cred_vers = 0; BEGIN_CHECK_ONCE(description); #ifdef cc_ccache_get_credentials_version #define possible_ret_val_count sizeof(possible_return_values)/sizeof(possible_return_values[0]) err = cc_ccache_get_credentials_version(ccache, &stored_cred_vers); // check returned error check_err(err, expected_err, possible_return_values); if (!err) { check_if(stored_cred_vers != expected_cred_vers, NULL); } #endif /* cc_ccache_get_credentials_version */ END_CHECK_ONCE; return err; } // --------------------------------------------------------------------------- int check_cc_ccache_get_name(void) { cc_int32 err = 0; cc_context_t context = NULL; cc_ccache_t ccache = NULL; BEGIN_TEST("cc_ccache_get_name"); #ifndef cc_ccache_get_name log_error("cc_ccache_get_name is not implemented yet"); failure_count++; #else err = cc_initialize(&context, ccapi_version_3, NULL, NULL); if (!err) { err = destroy_all_ccaches(context); } // try with unique ccache (which happens to be default) if (!err) { err = cc_context_create_ccache(context, "0", cc_credentials_v5, "foo@BAR.ORG", &ccache); } if (!err) { check_once_cc_ccache_get_name(ccache, "0", ccNoError, "unique ccache (which happens to be default)"); } else { log_error("cc_context_create_ccache failed, can't complete test"); failure_count++; } if (ccache) { cc_ccache_release(ccache); ccache = NULL; } // try with unique ccache (which is not default) if (!err) { err = cc_context_create_ccache(context, "1", cc_credentials_v5, "foo@BAR.ORG", &ccache); } if (!err) { check_once_cc_ccache_get_name(ccache, "1", ccNoError, "unique ccache (which is not default)"); } else { log_error("cc_context_create_ccache failed, can't complete test"); failure_count++; } // try with bad param if (!err) { check_once_cc_ccache_get_name(ccache, NULL, ccErrBadParam, "NULL param"); } if (ccache) { cc_ccache_release(ccache); ccache = NULL; } if (context) { err = destroy_all_ccaches(context); cc_context_release(context); } #endif /* cc_ccache_get_name */ END_TEST_AND_RETURN } cc_int32 check_once_cc_ccache_get_name(cc_ccache_t ccache, const char *expected_name, cc_int32 expected_err, const char *description) { cc_int32 err = ccNoError; cc_int32 possible_return_values[4] = { ccNoError, ccErrInvalidCCache, ccErrBadParam, ccErrCCacheNotFound, }; cc_string_t stored_name = NULL; BEGIN_CHECK_ONCE(description); #ifdef cc_ccache_get_name #define possible_ret_val_count sizeof(possible_return_values)/sizeof(possible_return_values[0]) if (expected_name == NULL) { // we want to try with a NULL param err = cc_ccache_get_name(ccache, NULL); } else { err = cc_ccache_get_name(ccache, &stored_name); } // check returned error check_err(err, expected_err, possible_return_values); if (!err) { check_if(strcmp(stored_name->data, expected_name), NULL); } if (stored_name) { cc_string_release(stored_name); } #endif /* cc_ccache_get_name */ END_CHECK_ONCE; return err; } // --------------------------------------------------------------------------- cc_int32 check_once_cc_ccache_get_principal(cc_ccache_t ccache, cc_uint32 cred_vers, const char *expected_principal, cc_int32 expected_err, const char *description) { cc_int32 err = ccNoError; cc_string_t stored_principal = NULL; cc_int32 possible_return_values[6] = { ccNoError, ccErrNoMem, ccErrBadCredentialsVersion, ccErrBadParam, ccErrInvalidCCache, ccErrCCacheNotFound, }; BEGIN_CHECK_ONCE(description); #ifdef cc_ccache_get_principal #define possible_ret_val_count sizeof(possible_return_values)/sizeof(possible_return_values[0]) if (expected_principal == NULL) { // we want to try with a NULL param err = cc_ccache_get_principal(ccache, cred_vers, NULL); } else { err = cc_ccache_get_principal(ccache, cred_vers, &stored_principal); } // check returned error check_err(err, expected_err, possible_return_values); if (!err) { check_if(strcmp(stored_principal->data, expected_principal), "expected princ == \"%s\" stored princ == \"%s\"", expected_principal, stored_principal->data); } if (stored_principal) { cc_string_release(stored_principal); } #endif /* cc_ccache_get_principal */ END_CHECK_ONCE; return err; } // --------------------------------------------------------------------------- int check_cc_ccache_get_principal(void) { cc_int32 err = 0; cc_context_t context = NULL; cc_ccache_t ccache = NULL; BEGIN_TEST("cc_ccache_get_principal"); #ifndef cc_ccache_get_principal log_error("cc_ccache_get_principal is not implemented yet"); failure_count++; #else err = cc_initialize(&context, ccapi_version_3, NULL, NULL); if (!err) { err = destroy_all_ccaches(context); } // try with krb5 principal if (!err) { err = cc_context_create_new_ccache(context, cc_credentials_v5, "foo/BAR@BAZ.ORG", &ccache); } if (!err) { check_once_cc_ccache_get_principal(ccache, cc_credentials_v5, "foo/BAR@BAZ.ORG", ccNoError, "trying to get krb5 princ for krb5 ccache"); } else { log_error("cc_context_create_new_ccache failed, can't complete test"); failure_count++; } if (ccache) { cc_ccache_release(ccache); ccache = NULL; } // try with krb4 principal if (!err) { err = cc_context_create_new_ccache(context, cc_credentials_v4, "foo.BAR@BAZ.ORG", &ccache); } if (!err) { check_once_cc_ccache_get_principal(ccache, cc_credentials_v4, "foo.BAR@BAZ.ORG", ccNoError, "trying to get krb4 princ for krb4 ccache"); } else { log_error("cc_context_create_new_ccache failed, can't complete test"); failure_count++; } // try with bad param if (!err) { // cc_ccache_t doesn't have any concept of the difference between a v4 and v5 principal check_once_cc_ccache_get_principal(ccache, cc_credentials_v4_v5, "foo.BAR@BAZ.ORG", ccErrBadCredentialsVersion, "passing cc_credentials_v4_v5 (shouldn't be allowed)"); check_once_cc_ccache_get_principal(ccache, cc_credentials_v5, NULL, ccErrBadParam, "passed null out param"); } if (ccache) { cc_ccache_release(ccache); ccache = NULL; } if (context) { err = destroy_all_ccaches(context); cc_context_release(context); } #endif /* cc_ccache_get_principal */ END_TEST_AND_RETURN } // --------------------------------------------------------------------------- int check_cc_ccache_set_principal(void) { cc_int32 err = 0; cc_context_t context = NULL; cc_ccache_t ccache = NULL; BEGIN_TEST("cc_ccache_set_principal"); #ifndef cc_ccache_set_principal log_error("cc_ccache_set_principal is not implemented yet"); failure_count++; #else err = cc_initialize(&context, ccapi_version_3, NULL, NULL); if (!err) { err = destroy_all_ccaches(context); } // bad params if (!err) { err = cc_context_create_new_ccache(context, cc_credentials_v5, "foo@BAZ.ORG", &ccache); } if (!err) { check_once_cc_ccache_set_principal(ccache, cc_credentials_v4_v5, "foo/BAZ@BAR.ORG", ccErrBadCredentialsVersion, "cc_credentials_v4_v5 (not allowed)"); check_once_cc_ccache_set_principal(ccache, cc_credentials_v5, NULL, ccErrBadParam, "NULL principal"); } else { log_error("cc_context_create_new_ccache failed, can't complete test"); failure_count++; } if (ccache) { cc_ccache_destroy(ccache); ccache = NULL; } // empty ccache // replace v5 only ccache's principal if (!err) { err = cc_context_create_new_ccache(context, cc_credentials_v5, "foo@BAZ.ORG", &ccache); } if (!err) { check_once_cc_ccache_set_principal(ccache, cc_credentials_v5, "foo/BAZ@BAR.ORG", ccNoError, "replace v5 only ccache's principal (empty ccache)"); } else { log_error("cc_context_create_new_ccache failed, can't complete test"); failure_count++; } if (ccache) { cc_ccache_destroy(ccache); ccache = NULL; } // add v4 principal to v5 only ccache if (!err) { err = cc_context_create_new_ccache(context, cc_credentials_v5, "foo@BAZ.ORG", &ccache); } if (!err) { check_once_cc_ccache_set_principal(ccache, cc_credentials_v4, "foo.BAZ@BAR.ORG", ccNoError, "add v4 principal to v5 only ccache (empty ccache)"); } else { log_error("cc_context_create_new_ccache failed, can't complete test"); failure_count++; } if (ccache) { cc_ccache_destroy(ccache); ccache = NULL; } // replace v4 only ccache's principal if (!err) { err = cc_context_create_new_ccache(context, cc_credentials_v4, "foo@BAZ.ORG", &ccache); } if (!err) { check_once_cc_ccache_set_principal(ccache, cc_credentials_v4, "foo.BAZ@BAR.ORG", ccNoError, "replace v4 only ccache's principal (empty ccache)"); } else { log_error("cc_context_create_new_ccache failed, can't complete test"); failure_count++; } if (ccache) { cc_ccache_destroy(ccache); ccache = NULL; } // add v5 principal to v4 only ccache if (!err) { err = cc_context_create_new_ccache(context, cc_credentials_v4, "foo@BAZ.ORG", &ccache); } if (!err) { check_once_cc_ccache_set_principal(ccache, cc_credentials_v5, "foo/BAZ@BAR.ORG", ccNoError, "add v5 principal to v4 only ccache (empty ccache)"); } else { log_error("cc_context_create_new_ccache failed, can't complete test"); failure_count++; } if (ccache) { cc_ccache_destroy(ccache); ccache = NULL; } // with credentials // replace v5 only ccache's principal // add v4 principal to v5 only ccache // replace v4 only ccache's principal // add v5 principal to v4 only ccache if (context) { err = destroy_all_ccaches(context); cc_context_release(context); } #endif /* cc_ccache_set_principal */ END_TEST_AND_RETURN } cc_int32 check_once_cc_ccache_set_principal(cc_ccache_t ccache, cc_uint32 cred_vers, const char *in_principal, cc_int32 expected_err, const char *description) { cc_int32 err = ccNoError; cc_string_t stored_principal = NULL; cc_int32 possible_return_values[6] = { ccNoError, ccErrNoMem, ccErrInvalidCCache, ccErrBadCredentialsVersion, ccErrBadParam, ccErrCCacheNotFound, }; BEGIN_CHECK_ONCE(description); #ifdef cc_ccache_set_principal #define possible_ret_val_count sizeof(possible_return_values)/sizeof(possible_return_values[0]) err = cc_ccache_set_principal(ccache, cred_vers, in_principal); // check returned error check_err(err, expected_err, possible_return_values); if (!err) { err = cc_ccache_get_principal(ccache, cred_vers, &stored_principal); } // compare stored with input if (!err) { check_if(strcmp(stored_principal->data, in_principal), "expected princ == \"%s\" stored princ == \"%s\"", in_principal, stored_principal->data); } if (stored_principal) { cc_string_release(stored_principal); } #endif /* cc_ccache_set_principal */ END_CHECK_ONCE; return err; } // --------------------------------------------------------------------------- int check_cc_ccache_store_credentials(void) { cc_int32 err = 0; cc_context_t context = NULL; cc_ccache_t ccache = NULL; cc_ccache_t dup_ccache = NULL; cc_credentials_union creds_union; cc_string_t name = NULL; BEGIN_TEST("cc_ccache_store_credentials"); #ifndef cc_ccache_store_credentials log_error("cc_ccache_store_credentials is not implemented yet"); failure_count++; #else err = cc_initialize(&context, ccapi_version_3, NULL, NULL); if (!err) { err = destroy_all_ccaches(context); } if (!err) { err = cc_context_create_new_ccache(context, cc_credentials_v5, "foo@BAR.ORG", &ccache); } // cred with matching version and realm if (!err) { err = new_v5_creds_union(&creds_union, "BAR.ORG"); } if (!err) { check_once_cc_ccache_store_credentials(ccache, &creds_union, ccNoError, "ok creds"); } if (&creds_union) { release_v5_creds_union(&creds_union); } // try with bad params check_once_cc_ccache_store_credentials(ccache, NULL, ccErrBadParam, "NULL creds param"); // invalid creds if (!err) { err = new_v5_creds_union(&creds_union, "BAR.ORG"); } if (!err) { if (creds_union.credentials.credentials_v5->client) { free(creds_union.credentials.credentials_v5->client); creds_union.credentials.credentials_v5->client = NULL; } check_once_cc_ccache_store_credentials(ccache, &creds_union, ccErrBadParam, "invalid creds (NULL client string)"); } if (&creds_union) { release_v5_creds_union(&creds_union); } // bad creds version if (!err) { err = new_v5_creds_union(&creds_union, "BAR.ORG"); } if (!err) { creds_union.version = cc_credentials_v4_v5; check_once_cc_ccache_store_credentials(ccache, &creds_union, ccErrBadCredentialsVersion, "v4_v5 creds (invalid) into a ccache with only v5 princ"); creds_union.version = cc_credentials_v4; check_once_cc_ccache_store_credentials(ccache, &creds_union, ccErrBadCredentialsVersion, "v4 creds into a ccache with only v5 princ"); creds_union.version = cc_credentials_v5; } if (&creds_union) { release_v5_creds_union(&creds_union); } // non-existent ccache if (ccache) { err = cc_ccache_get_name(ccache, &name); if (!err) { err = cc_context_open_ccache(context, name->data, &dup_ccache); } if (name) { cc_string_release(name); } if (dup_ccache) { cc_ccache_destroy(dup_ccache); } } if (!err) { err = new_v5_creds_union(&creds_union, "BAR.ORG"); } if (!err) { check_once_cc_ccache_store_credentials(ccache, &creds_union, ccErrInvalidCCache, "invalid ccache"); } if (&creds_union) { release_v5_creds_union(&creds_union); } if (ccache) { cc_ccache_release(ccache); } if (context) { destroy_all_ccaches(context); cc_context_release(context); } #endif /* cc_ccache_store_credentials */ END_TEST_AND_RETURN } cc_int32 check_once_cc_ccache_store_credentials(cc_ccache_t ccache, const cc_credentials_union *credentials, cc_int32 expected_err, const char *description) { cc_int32 err = ccNoError; cc_credentials_iterator_t creds_iterator = NULL; cc_credentials_t creds = NULL; cc_int32 possible_return_values[6] = { ccNoError, ccErrBadParam, ccErrInvalidCCache, ccErrInvalidCredentials, ccErrBadCredentialsVersion, ccErrCCacheNotFound, }; BEGIN_CHECK_ONCE(description); #ifdef cc_ccache_store_credentials #define possible_ret_val_count sizeof(possible_return_values)/sizeof(possible_return_values[0]) err = cc_ccache_store_credentials(ccache, credentials); // check returned error check_err(err, expected_err, possible_return_values); // make sure credentials were truly stored if (!err) { err = cc_ccache_new_credentials_iterator(ccache, &creds_iterator); } while (!err) { err = cc_credentials_iterator_next(creds_iterator, &creds); if (creds) { if (compare_v5_creds_unions(credentials, creds->data) == 0) { break; } cc_credentials_release(creds); creds = NULL; } } if (err == ccIteratorEnd) { check_if((creds != NULL), "stored credentials not found in ccache"); err = ccNoError; } if (creds) { cc_credentials_release(creds); } #endif /* cc_ccache_store_credentials */ END_CHECK_ONCE; return err; } // --------------------------------------------------------------------------- int check_cc_ccache_remove_credentials(void) { cc_int32 err = 0; cc_context_t context = NULL; cc_ccache_t ccache = NULL; cc_ccache_t dup_ccache = NULL; cc_credentials_t creds_array[10]; cc_credentials_t creds = NULL; cc_credentials_union creds_union; cc_credentials_iterator_t creds_iterator = NULL; cc_string_t name = NULL; unsigned int i; BEGIN_TEST("cc_ccache_remove_credentials"); #ifndef cc_ccache_remove_credentials log_error("cc_ccache_remove_credentials is not implemented yet"); failure_count++; #else err = cc_initialize(&context, ccapi_version_3, NULL, NULL); if (!err) { err = destroy_all_ccaches(context); } if (!err) { err = cc_context_create_new_ccache(context, cc_credentials_v5, "foo@BAR.ORG", &ccache); } // store 10 creds and retrieve their cc_credentials_t representations for(i = 0; !err && (i < 10); i++) { new_v5_creds_union(&creds_union, "BAR.ORG"); err = cc_ccache_store_credentials(ccache, &creds_union); if (&creds_union) { release_v5_creds_union(&creds_union); } } if (err) { log_error("failure to store creds_union in remove_creds test"); } if (!err) { err = cc_ccache_new_credentials_iterator(ccache, &creds_iterator); } i = 0; while (!err && i < 10) { err = cc_credentials_iterator_next(creds_iterator, &creds); if (creds) { creds_array[i++] = creds; creds = NULL; } } if (err == ccIteratorEnd) { err = ccNoError; } // remove 10 valid creds for (i = 0; !err && (i < 8); i++) { check_once_cc_ccache_remove_credentials(ccache, creds_array[i], ccNoError, "10 ok creds"); } // NULL param check_once_cc_ccache_remove_credentials(ccache, NULL, ccErrBadParam, "NULL creds in param"); // non-existent creds (remove same one twice) check_once_cc_ccache_remove_credentials(ccache, creds_array[0], ccErrInvalidCredentials, "removed same creds twice"); // non-existent ccache if (ccache) { err = cc_ccache_get_name(ccache, &name); if (!err) { err = cc_context_open_ccache(context, name->data, &dup_ccache); } if (name) { cc_string_release(name); } if (dup_ccache) { cc_ccache_destroy(dup_ccache); } } if (!err) { err = new_v5_creds_union(&creds_union, "BAR.ORG"); } if (!err) { check_once_cc_ccache_remove_credentials(ccache, creds_array[8], ccErrInvalidCCache, "invalid ccache"); } for(i = 0; i < 10; i++) { if (creds_array[i]) { cc_credentials_release(creds_array[i]); } } if (ccache) { cc_ccache_release(ccache); } if (context) { destroy_all_ccaches(context); cc_context_release(context); } #endif /* cc_ccache_remove_credentials */ END_TEST_AND_RETURN } cc_int32 check_once_cc_ccache_remove_credentials(cc_ccache_t ccache, cc_credentials_t in_creds, cc_int32 expected_err, const char *description) { cc_int32 err = ccNoError; cc_credentials_iterator_t creds_iterator = NULL; cc_credentials_t creds = NULL; cc_int32 possible_return_values[6] = { ccNoError, ccErrBadParam, ccErrInvalidCCache, ccErrInvalidCredentials, ccErrCredentialsNotFound, ccErrCCacheNotFound, }; BEGIN_CHECK_ONCE(description); #ifdef cc_ccache_remove_credentials #define possible_ret_val_count sizeof(possible_return_values)/sizeof(possible_return_values[0]) err = cc_ccache_remove_credentials(ccache, in_creds); // check returned error check_err(err, expected_err, possible_return_values); // make sure credentials were truly removed if (!err) { err = cc_ccache_new_credentials_iterator(ccache, &creds_iterator); } while (!err) { err = cc_credentials_iterator_next(creds_iterator, &creds); if (creds) { if (compare_v5_creds_unions(in_creds->data, creds->data) == 0) { break; } cc_credentials_release(creds); creds = NULL; } } if (err == ccIteratorEnd) { err = ccNoError; } else { check_if((creds != NULL), "credentials not removed from ccache"); } if (creds) { cc_credentials_release(creds); } #endif /* cc_ccache_remove_credentials */ END_CHECK_ONCE; return err; } // --------------------------------------------------------------------------- int check_cc_ccache_new_credentials_iterator(void) { cc_int32 err = 0; cc_context_t context = NULL; cc_ccache_t ccache = NULL; cc_ccache_t dup_ccache = NULL; cc_credentials_iterator_t creds_iterator = NULL; cc_string_t name = NULL; BEGIN_TEST("cc_ccache_new_credentials_iterator"); #ifndef cc_ccache_new_credentials_iterator log_error("cc_ccache_new_credentials_iterator is not implemented yet"); failure_count++; #else err = cc_initialize(&context, ccapi_version_3, NULL, NULL); if (!err) { err = destroy_all_ccaches(context); } if (!err) { err = cc_context_create_new_ccache(context, cc_credentials_v5, "foo@BAR.ORG", &ccache); } // valid params if (!err) { check_once_cc_ccache_new_credentials_iterator(ccache, &creds_iterator, ccNoError, "valid params"); } if (creds_iterator) { cc_credentials_iterator_release(creds_iterator); creds_iterator = NULL; } // NULL out param if (!err) { check_once_cc_ccache_new_credentials_iterator(ccache, NULL, ccErrBadParam, "NULL out iterator param"); } if (creds_iterator) { cc_credentials_iterator_release(creds_iterator); creds_iterator = NULL; } // non-existent ccache if (ccache) { err = cc_ccache_get_name(ccache, &name); if (!err) { err = cc_context_open_ccache(context, name->data, &dup_ccache); } if (name) { cc_string_release(name); } if (dup_ccache) { cc_ccache_destroy(dup_ccache); } } if (!err) { check_once_cc_ccache_new_credentials_iterator(ccache, &creds_iterator, ccErrInvalidCCache, "invalid ccache"); } if (creds_iterator) { cc_credentials_iterator_release(creds_iterator); creds_iterator = NULL; } if (ccache) { cc_ccache_release(ccache); } if (context) { destroy_all_ccaches(context); cc_context_release(context); } #endif /* cc_ccache_new_credentials_iterator */ END_TEST_AND_RETURN } cc_int32 check_once_cc_ccache_new_credentials_iterator(cc_ccache_t ccache, cc_credentials_iterator_t *iterator, cc_int32 expected_err, const char *description) { cc_int32 err = ccNoError; cc_int32 possible_return_values[5] = { ccNoError, ccErrBadParam, ccErrNoMem, ccErrCCacheNotFound, ccErrInvalidCCache, }; BEGIN_CHECK_ONCE(description); #ifdef cc_ccache_new_credentials_iterator #define possible_ret_val_count sizeof(possible_return_values)/sizeof(possible_return_values[0]) err = cc_ccache_new_credentials_iterator(ccache, iterator); // check returned error check_err(err, expected_err, possible_return_values); #endif /* cc_ccache_new_credentials_iterator */ END_CHECK_ONCE; return err; } // --------------------------------------------------------------------------- cc_int32 check_once_cc_ccache_get_change_time(cc_ccache_t ccache, cc_time_t *last_time, cc_int32 expected_err, const char *description) { cc_int32 err = ccNoError; cc_time_t this_time = 0; cc_int32 possible_return_values[4] = { ccNoError, ccErrInvalidCCache, ccErrBadParam, ccErrCCacheNotFound, }; BEGIN_CHECK_ONCE(description); #ifdef cc_ccache_get_change_time #define possible_ret_val_count sizeof(possible_return_values)/sizeof(possible_return_values[0]) if (last_time == NULL) { err = cc_ccache_get_change_time(ccache, NULL); // passed NULL to compare against because intention is actually to pass bad param instead } else { err = cc_ccache_get_change_time(ccache, &this_time); } // check returned error check_err(err, expected_err, possible_return_values); if ((!err) && last_time) { check_if(this_time <= *last_time, "change time didn't increase when expected"); *last_time = this_time; } #endif /* cc_ccache_get_change_time */ END_CHECK_ONCE; return err; } // --------------------------------------------------------------------------- int check_cc_ccache_get_change_time(void) { cc_int32 err = 0; cc_context_t context = NULL; cc_ccache_t dummy_ccache = NULL; cc_ccache_t ccache = NULL; cc_credentials_union creds_union; cc_credentials_iterator_t creds_iterator = NULL; cc_credentials_t credentials = NULL; cc_time_t last_time = 0; BEGIN_TEST("cc_ccache_get_change_time"); #ifndef cc_ccache_get_change_time log_error("cc_ccache_get_change_time is not implemented yet"); failure_count++; #else err = cc_initialize(&context, ccapi_version_3, NULL, NULL); if (!err) { err = destroy_all_ccaches(context); } // create some ccaches (so that the one we keep around as 'ccache' is not default) if (!err) { err = cc_context_create_new_ccache(context, cc_credentials_v5, "foo@BAR.ORG", &ccache); } if (ccache) { cc_ccache_release(ccache); } if (!err) { err = cc_context_create_new_ccache(context, cc_credentials_v5, "foo@BAZ.ORG", &ccache); } // change it in all the ways it can change, checking after each // the ccache is created if (!err) { check_once_cc_ccache_get_change_time(ccache, &last_time, ccNoError, "new ccache (change time should be > 0)"); } // the ccache is made default if (!err) { err = cc_ccache_set_default(ccache); } if (!err) { check_once_cc_ccache_get_change_time(ccache, &last_time, ccNoError, "non-default ccache became default"); } // the ccache is made not-default if (!err) { err = cc_context_create_new_ccache(context, cc_credentials_v5, "something@ELSE.COM", &dummy_ccache); } if (!err) { err = cc_ccache_set_default(dummy_ccache); } if (dummy_ccache) { cc_ccache_release(dummy_ccache); } if (!err) { check_once_cc_ccache_get_change_time(ccache, &last_time, ccNoError, "default ccache became non-default"); } // try with bad params // NULL out param if (!err) { check_once_cc_ccache_get_change_time(ccache, NULL, ccErrBadParam, "NULL out param for time"); } // store a credential if (!err) { new_v5_creds_union(&creds_union, "BAR.ORG"); err = cc_ccache_store_credentials(ccache, &creds_union); release_v5_creds_union(&creds_union); } check_once_cc_ccache_get_change_time(ccache, &last_time, ccNoError, "stored new credential"); if (!err) { // change principal (fails with ccErrBadInternalMessage) err = cc_ccache_set_principal(ccache, cc_credentials_v5, "foo@BAR.ORG"); if (err) { log_error("failed to change ccache's principal - %s (%d)", translate_ccapi_error(err), err); failure_count++; err = ccNoError; } } check_once_cc_context_get_change_time(context, &last_time, ccNoError, "after changing a principle"); // remove a credential if (!err) { err = cc_ccache_new_credentials_iterator(ccache, &creds_iterator); } if (!err) { err = cc_credentials_iterator_next(creds_iterator, &credentials); } if (err == ccIteratorEnd) { err = ccNoError; } if (!err) { err = cc_ccache_remove_credentials(ccache, credentials); } check_once_cc_context_get_change_time(context, &last_time, ccNoError, "after removing a credential"); // invalid ccache if (!err) { err = destroy_all_ccaches(context); } if (!err) { check_once_cc_ccache_get_change_time(ccache, &last_time, ccErrInvalidCCache, "getting change time on destroyed ccache"); } if (ccache) { cc_ccache_release(ccache); } if (context) { destroy_all_ccaches(context); cc_context_release(context); } #endif /* cc_ccache_get_change_time */ END_TEST_AND_RETURN } // --------------------------------------------------------------------------- cc_int32 check_once_cc_ccache_get_last_default_time(cc_ccache_t ccache, cc_time_t *last_time, cc_int32 expected_err, const char *description) { cc_int32 err = ccNoError; cc_time_t this_time = 0; cc_int32 possible_return_values[5] = { ccNoError, ccErrInvalidCCache, ccErrBadParam, ccErrNeverDefault, ccErrCCacheNotFound, }; BEGIN_CHECK_ONCE(description); #ifdef cc_ccache_get_last_default_time #define possible_ret_val_count sizeof(possible_return_values)/sizeof(possible_return_values[0]) if (last_time == NULL) { err = cc_ccache_get_last_default_time(ccache, NULL); // passed NULL to compare against because intention is actually to pass bad param instead } else { err = cc_ccache_get_last_default_time(ccache, &this_time); } // check returned error check_err(err, expected_err, possible_return_values); if (!err && last_time) { check_if(this_time > *last_time, "last default time isn't as expected"); *last_time = this_time; } #endif /* cc_ccache_get_last_default_time */ END_CHECK_ONCE; return err; } // --------------------------------------------------------------------------- int check_cc_ccache_get_last_default_time(void) { cc_int32 err = 0; cc_context_t context = NULL; cc_ccache_t ccache_1 = NULL; cc_ccache_t ccache_2 = NULL; cc_time_t last_time_1 = 0; cc_time_t last_time_2 = 0; cc_string_t name = NULL; BEGIN_TEST("cc_ccache_get_last_default_time"); #ifndef cc_ccache_get_last_default_time log_error("cc_ccache_get_last_default_time is not implemented yet"); failure_count++; #else err = cc_initialize(&context, ccapi_version_3, NULL, NULL); if (!err) { err = destroy_all_ccaches(context); } // create 2 ccaches if (!err) { err = cc_context_create_new_ccache(context, cc_credentials_v5, "foo@ONE.ORG", &ccache_1); } if (!err) { err = cc_context_create_new_ccache(context, cc_credentials_v5, "foo@TWO.ORG", &ccache_2); } if (!err) { err = cc_ccache_get_change_time(ccache_1, &last_time_1); } // since we destroyed all ccaches before creating these two, // ccache_1 should be default and ccache_2 should never have been default if (!err) { check_once_cc_ccache_get_last_default_time(ccache_1, &last_time_1, ccNoError, "ccache_1 default at creation"); check_once_cc_ccache_get_last_default_time(ccache_2, &last_time_2, ccErrNeverDefault, "ccache_2 never default"); } // make ccache_2 default and check each of their times again if (!err) { err = cc_ccache_set_default(ccache_2); } if (!err) { err = cc_ccache_get_change_time(ccache_2, &last_time_2); } if (!err) { check_once_cc_ccache_get_last_default_time(ccache_1, &last_time_1, ccNoError, "ccache_1 no longer default"); check_once_cc_ccache_get_last_default_time(ccache_2, &last_time_2, ccNoError, "ccache_2 newly default"); } // NULL param if (!err) { check_once_cc_ccache_get_last_default_time(ccache_1, NULL, ccErrBadParam, "NULL out param"); } // non-existent ccache if (ccache_2) { cc_ccache_release(ccache_2); ccache_2 = NULL; } if (!err) { err = cc_ccache_get_name(ccache_1, &name); } if (!err) { err = cc_context_open_ccache(context, name->data, &ccache_2); } if (!err) { cc_ccache_destroy(ccache_2); ccache_2 = NULL; } if (!err) { check_once_cc_ccache_get_last_default_time(ccache_1, &last_time_1, ccErrInvalidCCache, "destroyed ccache"); } if (ccache_1) { cc_ccache_release(ccache_1); } if (context) { destroy_all_ccaches(context); cc_context_release(context); } #endif /* cc_ccache_get_last_default_time */ END_TEST_AND_RETURN } // --------------------------------------------------------------------------- int check_cc_ccache_move(void) { cc_int32 err = 0; cc_context_t context = NULL; cc_ccache_t source = NULL; cc_ccache_t destination = NULL; cc_credentials_union creds_union; unsigned int i = 0; BEGIN_TEST("cc_ccache_move"); #ifndef cc_ccache_move log_error("cc_ccache_move is not implemented yet"); failure_count++; #else err = cc_initialize(&context, ccapi_version_3, NULL, NULL); if (!err) { err = destroy_all_ccaches(context); } // create 2 ccaches if (!err) { err = cc_context_create_new_ccache(context, cc_credentials_v5, "foo@ONE.ORG", &source); } if (!err) { err = cc_context_create_new_ccache(context, cc_credentials_v5, "foo@TWO.ORG", &destination); } // store credentials in each for (i = 0; !err && (i < 10); i++) { new_v5_creds_union(&creds_union, "ONE.ORG"); err = cc_ccache_store_credentials(source, &creds_union); } for (i = 0; !err && (i < 10); i++) { new_v5_creds_union(&creds_union, "TWO.ORG"); err = cc_ccache_store_credentials(destination, &creds_union); } // move source into destination if (!err) { check_once_cc_ccache_move(source, destination, ccNoError, "valid params"); } // NULL param if (!err) { check_once_cc_ccache_move(destination, NULL, ccErrBadParam, "NULL destination param"); } // non-existent ccache if (!err) { check_once_cc_ccache_move(destination, source, ccErrInvalidCCache, "recently moved source as destination param"); } if (source) { cc_ccache_release(source); } if (destination) { cc_ccache_release(destination); } if (context) { destroy_all_ccaches(context); cc_context_release(context); } #endif /* cc_ccache_move */ END_TEST_AND_RETURN } cc_int32 check_once_cc_ccache_move(cc_ccache_t source, cc_ccache_t destination, cc_int32 expected_err, const char *description) { cc_int32 err = ccNoError; cc_credentials_t dst_creds[10] = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, }; cc_credentials_t creds = NULL; cc_credentials_iterator_t cred_iterator = NULL; unsigned int i = 0; cc_string_t src_principal = NULL; cc_string_t dst_principal = NULL; cc_int32 possible_return_values[4] = { ccNoError, ccErrBadParam, ccErrInvalidCCache, ccErrCCacheNotFound, }; BEGIN_CHECK_ONCE(description); #ifdef cc_ccache_move #define possible_ret_val_count sizeof(possible_return_values)/sizeof(possible_return_values[0]) if (destination) { // verify all of destination's credentials are no longer there (save a list and call remove_cred for each, expecting an err in response) if (!err) { err = cc_ccache_new_credentials_iterator(destination, &cred_iterator); } while (!err && (i < 10)) { err = cc_credentials_iterator_next(cred_iterator, &creds); if (creds) { dst_creds[i++] = creds; } } if (err == ccIteratorEnd) { err = ccNoError; } if (cred_iterator) { cc_credentials_iterator_release(cred_iterator); cred_iterator = NULL; } // verify that destination's principal has changed to source's (strcmp) if (!err) { err = cc_ccache_get_principal(source, cc_credentials_v5, &src_principal); } } if (!err) { err = cc_ccache_move(source, destination); } // check returned error check_err(err, expected_err, possible_return_values); if (!err) { // verify all of destination's credentials are no longer there (save a list and call remove_cred for each, expecting an err in response) i = 0; while (dst_creds[i] && (i < 10)) { err = cc_ccache_remove_credentials(destination, dst_creds[i]); check_if(!(!err || err == ccErrCredentialsNotFound || ccErrInvalidCredentials), "credentials in destination not removed as promised"); cc_credentials_release(dst_creds[i]); i++; } err = ccNoError; } // verify that destination's principal has changed to source's (strcmp) if (!err) { err = cc_ccache_get_principal(destination, cc_credentials_v5, &dst_principal); } if (!err) { check_if(strcmp(src_principal->data, dst_principal->data), "destination principal not overwritten by source"); } // verify that handles for source are no longer valid (get_change_time) if (src_principal) { cc_string_release(src_principal); src_principal = NULL; } if (!err) { err = cc_ccache_get_principal(source, cc_credentials_v5, &src_principal); check_if(err != ccErrInvalidCCache, "source ccache was not invalidated after move"); } if (cred_iterator) { cc_credentials_iterator_release(cred_iterator); } if (src_principal) { cc_string_release(src_principal); } if (dst_principal) { cc_string_release(dst_principal); } #endif /* cc_ccache_move */ END_CHECK_ONCE; return err; } // --------------------------------------------------------------------------- int check_cc_ccache_compare(void) { cc_int32 err = 0; cc_context_t context = NULL; cc_ccache_t ccache_a = NULL; cc_ccache_t ccache_b = NULL; cc_uint32 equal = 0; BEGIN_TEST("cc_ccache_compare"); #ifndef cc_ccache_compare log_error("cc_ccache_compare is not implemented yet"); failure_count++; #else err = cc_initialize(&context, ccapi_version_3, NULL, NULL); if (!err) { err = destroy_all_ccaches(context); } if (!err) { err = cc_context_create_new_ccache(context, cc_credentials_v5, "foo@BAR.ORG", &ccache_a); } if (!err) { err = cc_context_open_default_ccache(context, &ccache_b); } equal = 1; check_once_cc_ccache_compare(ccache_a, ccache_a, &equal, ccNoError, "compare ccache with same pointer"); equal = 1; check_once_cc_ccache_compare(ccache_a, ccache_b, &equal, ccNoError, "compare different handles to same ccache"); if (ccache_b) { cc_ccache_release(ccache_b); ccache_b = NULL; } if (!err) { err = cc_context_create_new_ccache(context, cc_credentials_v5, "baz@BAR.ORG", &ccache_b); } equal = 0; check_once_cc_ccache_compare(ccache_a, ccache_b, &equal, ccNoError, "compare different ccaches"); check_once_cc_ccache_compare(ccache_a, NULL, &equal, ccErrBadParam, "NULL compare_to ccache"); check_once_cc_ccache_compare(ccache_a, ccache_b, NULL, ccErrBadParam, "NULL out param"); if (ccache_a) { cc_ccache_release(ccache_a); } if (ccache_b) { cc_ccache_release(ccache_b); } if (context) { err = destroy_all_ccaches(context); cc_context_release(context); } #endif /* cc_ccache_compare */ END_TEST_AND_RETURN } cc_int32 check_once_cc_ccache_compare(cc_ccache_t ccache, cc_ccache_t compare_to, cc_uint32 *equal, cc_int32 expected_err, const char *description) { cc_int32 err = ccNoError; cc_uint32 actually_equal = 0; cc_int32 possible_return_values[4] = { ccNoError, ccErrInvalidContext, ccErrBadParam, ccErrServerUnavailable, }; BEGIN_CHECK_ONCE(description); #ifdef cc_ccache_compare #define possible_ret_val_count sizeof(possible_return_values)/sizeof(possible_return_values[0]) if (equal) { actually_equal = *equal; } err = cc_ccache_compare(ccache, compare_to, equal); if (!err && equal) { if (actually_equal) { check_if(actually_equal != *equal, "equal ccaches not considered equal"); } else { check_if(actually_equal != *equal, "non-equal ccaches considered equal"); } } // check returned error check_err(err, expected_err, possible_return_values); #endif /* cc_ccache_compare */ return err; } // --------------------------------------------------------------------------- int check_cc_ccache_get_kdc_time_offset(void) { cc_int32 err = 0; cc_context_t context = NULL; cc_ccache_t ccache = NULL; cc_time_t time_offset = 0; BEGIN_TEST("cc_ccache_get_kdc_time_offset"); #ifndef cc_ccache_get_kdc_time_offset log_error("cc_ccache_get_kdc_time_offset is not implemented yet"); failure_count++; #else err = cc_initialize(&context, ccapi_version_3, NULL, NULL); if (!err) { err = destroy_all_ccaches(context); } if (!err) { err = cc_context_create_new_ccache(context, cc_credentials_v5, "foo@BAR.ORG", &ccache); } time_offset = 0; check_once_cc_ccache_get_kdc_time_offset(ccache, cc_credentials_v5, &time_offset, ccErrTimeOffsetNotSet, "brand new ccache (offset not yet set)"); time_offset = 10; if (!err) { err = cc_ccache_set_kdc_time_offset(ccache, cc_credentials_v5, time_offset); } if (!err) { check_once_cc_ccache_get_kdc_time_offset(ccache, cc_credentials_v5, &time_offset, ccNoError, "offset set for v5 but not v4"); } if (!err) { check_once_cc_ccache_get_kdc_time_offset(ccache, cc_credentials_v4, &time_offset, ccErrTimeOffsetNotSet, "asking for v4 offset when only v5 is set"); } if (!err) { err = cc_ccache_set_kdc_time_offset(ccache, cc_credentials_v4, time_offset); } if (!err) { check_once_cc_ccache_get_kdc_time_offset(ccache, cc_credentials_v4, &time_offset, ccNoError, "asking for v4 offset when v4 and v5 are set"); } check_once_cc_ccache_get_kdc_time_offset(ccache, cc_credentials_v5, NULL, ccErrBadParam, "NULL time_offset out param"); check_once_cc_ccache_get_kdc_time_offset(ccache, cc_credentials_v4_v5, &time_offset, ccErrBadCredentialsVersion, "v4_v5 creds_vers in param (invalid)"); if (ccache) { cc_ccache_release(ccache); } if (context) { err = destroy_all_ccaches(context); cc_context_release(context); } #endif /* cc_ccache_get_kdc_time_offset */ END_TEST_AND_RETURN } cc_int32 check_once_cc_ccache_get_kdc_time_offset(cc_ccache_t ccache, cc_int32 credentials_version, cc_time_t *time_offset, cc_int32 expected_err, const char *description) { cc_int32 err = ccNoError; cc_time_t expected_offset; cc_int32 possible_return_values[7] = { ccNoError, ccErrTimeOffsetNotSet, ccErrCCacheNotFound, ccErrInvalidCCache, ccErrBadParam, ccErrServerUnavailable, ccErrBadCredentialsVersion, }; BEGIN_CHECK_ONCE(description); #ifdef cc_ccache_get_kdc_time_offset #define possible_ret_val_count sizeof(possible_return_values)/sizeof(possible_return_values[0]) if (time_offset) { expected_offset = *time_offset; } err = cc_ccache_get_kdc_time_offset(ccache, credentials_version, time_offset); // check returned error check_err(err, expected_err, possible_return_values); if (!err && time_offset) { check_if(*time_offset != expected_offset, "kdc time offset doesn't match expected value"); } #endif /* cc_ccache_get_kdc_time_offset */ return err; } // --------------------------------------------------------------------------- int check_cc_ccache_set_kdc_time_offset(void) { cc_int32 err = 0; cc_context_t context = NULL; cc_ccache_t ccache = NULL; BEGIN_TEST("cc_ccache_set_kdc_time_offset"); #ifndef cc_ccache_set_kdc_time_offset log_error("cc_ccache_set_kdc_time_offset is not implemented yet"); failure_count++; #else err = cc_initialize(&context, ccapi_version_3, NULL, NULL); if (!err) { err = destroy_all_ccaches(context); } if (!err) { err = cc_context_create_new_ccache(context, cc_credentials_v5, "foo@BAR.ORG", &ccache); } check_once_cc_ccache_set_kdc_time_offset(ccache, cc_credentials_v5, 0, ccNoError, "first time setting offset (v5)"); check_once_cc_ccache_set_kdc_time_offset(ccache, cc_credentials_v4, 0, ccNoError, "first time setting offset (v4)"); check_once_cc_ccache_set_kdc_time_offset(ccache, cc_credentials_v4_v5, 0, ccErrBadCredentialsVersion, "invalid creds_vers (v4_v5)"); if (ccache) { cc_ccache_release(ccache); } if (context) { err = destroy_all_ccaches(context); cc_context_release(context); } #endif /* cc_ccache_set_kdc_time_offset */ END_TEST_AND_RETURN } cc_int32 check_once_cc_ccache_set_kdc_time_offset(cc_ccache_t ccache, cc_int32 credentials_version, cc_time_t time_offset, cc_int32 expected_err, const char *description) { cc_int32 err = ccNoError; cc_time_t stored_offset = 0; cc_int32 possible_return_values[6] = { ccNoError, ccErrCCacheNotFound, ccErrInvalidCCache, ccErrBadParam, ccErrServerUnavailable, ccErrBadCredentialsVersion, }; BEGIN_CHECK_ONCE(description); #ifdef cc_ccache_set_kdc_time_offset #define possible_ret_val_count sizeof(possible_return_values)/sizeof(possible_return_values[0]) err = cc_ccache_set_kdc_time_offset(ccache, credentials_version, time_offset); // check returned error check_err(err, expected_err, possible_return_values); if (!err) { err = cc_ccache_get_kdc_time_offset(ccache, credentials_version, &stored_offset); } if (!err) { check_if(time_offset != stored_offset, "kdc time offset doesn't match expected value"); } #endif /* cc_ccache_set_kdc_time_offset */ return err; } // --------------------------------------------------------------------------- int check_cc_ccache_clear_kdc_time_offset(void) { cc_int32 err = 0; cc_context_t context = NULL; cc_ccache_t ccache = NULL; BEGIN_TEST("cc_ccache_clear_kdc_time_offset"); #ifndef cc_ccache_clear_kdc_time_offset log_error("cc_ccache_clear_kdc_time_offset is not implemented yet"); failure_count++; #else err = cc_initialize(&context, ccapi_version_3, NULL, NULL); if (!err) { err = destroy_all_ccaches(context); } if (!err) { err = cc_context_create_new_ccache(context, cc_credentials_v5, "foo@BAR.ORG", &ccache); } check_once_cc_ccache_clear_kdc_time_offset(ccache, cc_credentials_v5, ccNoError, "clearing an offset that was never set (v5)"); check_once_cc_ccache_clear_kdc_time_offset(ccache, cc_credentials_v4, ccNoError, "clearing an offset that was never set (v4)"); err = cc_ccache_set_kdc_time_offset(ccache, cc_credentials_v5, 0); err = cc_ccache_set_kdc_time_offset(ccache, cc_credentials_v4, 0); check_once_cc_ccache_clear_kdc_time_offset(ccache, cc_credentials_v5, ccNoError, "clearing v5"); check_once_cc_ccache_clear_kdc_time_offset(ccache, cc_credentials_v4, ccNoError, "clearing v4"); check_once_cc_ccache_clear_kdc_time_offset(ccache, cc_credentials_v4_v5, ccErrBadCredentialsVersion, "bad in param creds vers (v4_v5)"); if (ccache) { cc_ccache_release(ccache); } if (context) { err = destroy_all_ccaches(context); cc_context_release(context); } #endif /* cc_ccache_clear_kdc_time_offset */ END_TEST_AND_RETURN } cc_int32 check_once_cc_ccache_clear_kdc_time_offset(cc_ccache_t ccache, cc_int32 credentials_version, cc_int32 expected_err, const char *description) { cc_int32 err = ccNoError; cc_time_t stored_offset = 0; cc_int32 possible_return_values[6] = { ccNoError, ccErrCCacheNotFound, ccErrInvalidCCache, ccErrBadParam, ccErrServerUnavailable, ccErrBadCredentialsVersion, }; BEGIN_CHECK_ONCE(description); #ifdef cc_ccache_clear_kdc_time_offset #define possible_ret_val_count sizeof(possible_return_values)/sizeof(possible_return_values[0]) err = cc_ccache_clear_kdc_time_offset(ccache, credentials_version); // check returned error check_err(err, expected_err, possible_return_values); if (!err) { err = cc_ccache_get_kdc_time_offset(ccache, credentials_version, &stored_offset); check_if(err != ccErrTimeOffsetNotSet, "time offset not cleared"); } #endif /* cc_ccache_clear_kdc_time_offset */ return err; } krb5-1.16/src/ccapi/test/test_cc_ccache_get_principal.c0000644000704600001450000000047013211554426023002 0ustar ghudsonlibuuid#include #include #include "test_ccapi_check.h" #include "test_ccapi_constants.h" #include "test_ccapi_context.h" #include "test_ccapi_ccache.h" int main (int argc, const char * argv[]) { cc_int32 err = ccNoError; T_CCAPI_INIT; err = check_cc_ccache_get_principal(); return err; } krb5-1.16/src/ccapi/test/test_ccapi_globals.c0000644000704600001450000000347513211554426021021 0ustar ghudsonlibuuid#include "test_ccapi_globals.h" /* GLOBALS */ unsigned int total_failure_count = 0; unsigned int failure_count = 0; const char *current_test_name; const char *current_test_activity; const char * ccapi_error_strings[30] = { "ccNoError", /* 0 */ "ccIteratorEnd", /* 201 */ "ccErrBadParam", "ccErrNoMem", "ccErrInvalidContext", "ccErrInvalidCCache", "ccErrInvalidString", /* 206 */ "ccErrInvalidCredentials", "ccErrInvalidCCacheIterator", "ccErrInvalidCredentialsIterator", "ccErrInvalidLock", "ccErrBadName", /* 211 */ "ccErrBadCredentialsVersion", "ccErrBadAPIVersion", "ccErrContextLocked", "ccErrContextUnlocked", "ccErrCCacheLocked", /* 216 */ "ccErrCCacheUnlocked", "ccErrBadLockType", "ccErrNeverDefault", "ccErrCredentialsNotFound", "ccErrCCacheNotFound", /* 221 */ "ccErrContextNotFound", "ccErrServerUnavailable", "ccErrServerInsecure", "ccErrServerCantBecomeUID", "ccErrTimeOffsetNotSet", /* 226 */ "ccErrBadInternalMessage", "ccErrNotImplemented", }; const char * ccapiv2_error_strings[24] = { "CC_NOERROR", "CC_BADNAME", "CC_NOTFOUND", "CC_END", "CC_IO", "CC_WRITE", "CC_NOMEM", "CC_FORMAT", "CC_LOCKED", "CC_BAD_API_VERSION", "CC_NO_EXIST", "CC_NOT_SUPP", "CC_BAD_PARM", "CC_ERR_CACHE_ATTACH", "CC_ERR_CACHE_RELEASE", "CC_ERR_CACHE_FULL", "CC_ERR_CRED_VERSION" }; const char *translate_ccapi_error(cc_int32 err) { if (err == 0) { return ccapi_error_strings[0]; } else if (err >= 0 && err <= 16){ return ccapiv2_error_strings[err]; } else if (err >= 201 && err <= 228){ return ccapi_error_strings[err - 200]; } else { return "\"Invalid or private CCAPI error\""; } return ""; } krb5-1.16/src/ccapi/test/test_cc_ccache_get_kdc_time_offset.c0000644000704600001450000000047613211554426024154 0ustar ghudsonlibuuid#include #include #include "test_ccapi_check.h" #include "test_ccapi_constants.h" #include "test_ccapi_context.h" #include "test_ccapi_ccache.h" int main (int argc, const char * argv[]) { cc_int32 err = ccNoError; T_CCAPI_INIT; err = check_cc_ccache_get_kdc_time_offset(); return err; } krb5-1.16/src/ccapi/test/test_ccapi_context.h0000644000704600001450000000511113211554426021054 0ustar ghudsonlibuuid#ifndef _TEST_CCAPI_CONTEXT_H_ #define _TEST_CCAPI_CONTEXT_H_ #include "test_ccapi_globals.h" int check_cc_initialize(void); cc_int32 check_once_cc_initialize(cc_context_t *out_context, cc_int32 in_version, cc_int32 *out_supported_version, char const **out_vendor, cc_int32 expected_err, const char *description); int check_cc_context_get_version(void); cc_int32 check_once_cc_context_get_version(cc_context_t *out_context, cc_int32 in_version, cc_int32 *out_supported_version, char const **out_vendor, cc_int32 expected_err, const char *description); int check_cc_context_release(void); cc_int32 check_once_cc_context_release(cc_context_t *out_context, cc_int32 expected_err, const char *description); int check_cc_context_get_change_time(void); cc_int32 check_once_cc_context_get_change_time(cc_context_t context, cc_time_t *time, cc_int32 expected_err, const char *description); int check_cc_context_get_default_ccache_name(void); cc_int32 check_once_cc_context_get_default_ccache_name(cc_context_t context, cc_string_t *name, cc_int32 expected_err, const char *description); int check_cc_context_open_ccache(void); cc_int32 check_once_cc_context_open_ccache(cc_context_t context, const char *name, cc_ccache_t *ccache, cc_int32 expected_err, const char *description); int check_cc_context_open_default_ccache(void); cc_int32 check_once_cc_context_open_default_ccache(cc_context_t context, cc_ccache_t *ccache, cc_int32 expected_err, const char *description); int check_cc_context_create_ccache(void); cc_int32 check_once_cc_context_create_ccache(cc_context_t context, const char *name, cc_uint32 cred_vers, const char *principal, cc_ccache_t *ccache, cc_int32 expected_err, const char *description); int check_cc_context_create_default_ccache(void); cc_int32 check_once_cc_context_create_default_ccache(cc_context_t context, cc_uint32 cred_vers, const char *principal, cc_ccache_t *ccache, cc_int32 expected_err, const char *description); int check_cc_context_create_new_ccache(void); cc_int32 check_once_cc_context_create_new_ccache(cc_context_t context, cc_int32 should_be_default, cc_uint32 cred_vers, const char *principal, cc_ccache_t *ccache, cc_int32 expected_err, const char *description); int check_cc_context_new_ccache_iterator(void); cc_int32 check_once_cc_context_new_ccache_iterator(cc_context_t context, cc_ccache_iterator_t *iterator, cc_int32 expected_err, const char *description); int check_cc_context_compare(void); cc_int32 check_once_cc_context_compare(cc_context_t context, cc_context_t compare_to, cc_uint32 *equal, cc_int32 expected_err, const char *description); #endif /* _TEST_CCAPI_CONTEXT_H_ */ krb5-1.16/src/ccapi/test/Pingtest.sln0000644000704600001450000000156013211554426017340 0ustar ghudsonlibuuid Microsoft Visual Studio Solution File, Format Version 9.00 # Visual Studio 2005 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Pingtest", "Pingtest.vcproj", "{04017001-3222-43C4-A03C-8423B5349276}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Win32 = Debug|Win32 Release|Win32 = Release|Win32 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {04017001-3222-43C4-A03C-8423B5349276}.Debug|Win32.ActiveCfg = Debug|Win32 {04017001-3222-43C4-A03C-8423B5349276}.Debug|Win32.Build.0 = Debug|Win32 {04017001-3222-43C4-A03C-8423B5349276}.Release|Win32.ActiveCfg = Release|Win32 {04017001-3222-43C4-A03C-8423B5349276}.Release|Win32.Build.0 = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection EndGlobal krb5-1.16/src/ccapi/Makefile.in0000644000704600001450000000013413211554426016107 0ustar ghudsonlibuuidmydir=ccapi BUILDTOP=$(REL).. SUBDIRS= lib server test WINSUBDIRS= lib\win server\win test krb5-1.16/src/doc/0000755000704600001450000000000013211555165013533 5ustar ghudsonlibuuidkrb5-1.16/src/doc/Doxyfile.in0000644000704600001450000000106213211554426015644 0ustar ghudsonlibuuidPROJECT_NAME = Kerberos_doxygen OUTPUT_DIRECTORY = doxy JAVADOC_AUTOBRIEF = YES OPTIMIZE_OUTPUT_FOR_C = YES WARN_IF_UNDOCUMENTED = NO SHOW_FILES = NO EXTENSION_MAPPING = hin=C INPUT = @SRC@/include/krb5/krb5.hin @DOC@/doxy_examples EXAMPLE_PATH = @DOC@/doxy_examples GENERATE_HTML = NO GENERATE_LATEX = NO GENERATE_XML = YES PREDEFINED = KRB5_DEPRECATED KRB5_OLD_CRYPTO CLASS_DIAGRAMS = NO CASE_SENSE_NAMES = NO QUIET = YES krb5-1.16/src/doc/deps0000644000704600001450000000003013211554426014401 0ustar ghudsonlibuuid# No dependencies here. krb5-1.16/src/doc/version.py.in0000644000704600001450000000047213211554426016201 0ustar ghudsonlibuuid#include "patchlevel.h" r_major = KRB5_MAJOR_RELEASE r_minor = KRB5_MINOR_RELEASE r_patch = KRB5_PATCHLEVEL #ifdef KRB5_RELTAIL r_tail = KRB5_RELTAIL #else r_tail = None #endif #ifdef KRB5_RELDATE r_date = KRB5_RELDATE #else r_date = None #endif #ifdef KRB5_RELTAG r_tag = KRB5_RELTAG #else r_date = None #endif krb5-1.16/src/doc/Makefile.in0000644000704600001450000001020413211554426015574 0ustar ghudsonlibuuidmydir=doc BUILDTOP=$(REL).. SPHINX_ARGS=@MAINT@-W SPHINX_BUILD=sphinx-build $(SPHINX_ARGS) DOXYGEN=doxygen docsrc=$(top_srcdir)/../doc localstatedir=@localstatedir@ runstatedir=@runstatedir@ sysconfdir=@sysconfdir@ DEFCCNAME=@DEFCCNAME@ DEFKTNAME=@DEFKTNAME@ DEFCKTNAME=@DEFCKTNAME@ RST_SOURCES= _static \ _templates \ conf.py \ index.rst \ admin \ appdev \ basic \ build \ formats \ plugindev \ user \ about.rst \ build_this.rst \ copyright.rst \ mitK5defaults.rst \ mitK5features.rst \ mitK5license.rst \ notice.rst \ resources.rst PDFDIR=$(docsrc)/pdf PDFDOCS= admin appdev basic build plugindev user LATEXOPTS= # Create HTML documentation in $(docsrc)/html suitable for a # release tarball or the web site (that is, without substitutions for # configured paths). This can be done in an unconfigured source tree # as: # make -f Makefile.in SPHINX_ARGS= htmlsrc html: composite rm -rf $(docsrc)/html $(SPHINX_BUILD) -q rst_composite $(docsrc)/html # Dummy target for use in an unconfigured source tree. htmlsrc: $(MAKE) -f Makefile.in srcdir=. top_srcdir=.. PYTHON=python html clean # Create HTML documentation in html_subst suitable for # installation by an OS package, with substitutions for configured # paths. substhtml: composite paths.py rm -rf html_subst cp paths.py rst_composite $(SPHINX_BUILD) -t pathsubs -q rst_composite html_subst # Create an ASCII (okay, UTF-8) version of the NOTICE file notice.txt: $(docsrc)/conf.py $(docsrc)/notice.rst $(docsrc)/version.py $(SPHINX_BUILD) -b text -t notice -q $(docsrc) . NOTICE: notice.txt cp notice.txt $(top_srcdir)/../NOTICE $(PDFDIR): composite $(SPHINX_BUILD) -b latex -q rst_composite $(PDFDIR) # sphinx-build generates a gmake-specific Makefile that we don't use mv $(PDFDIR)/Makefile $(PDFDIR)/GMakefile # Not pretty. Can't use a suffix rule .tex.pdf without a Makefile in # $(PDFDIR) because pdflatex looks for include files in the current # working directory. The sphinx-build Makefile is quite conservative # and runs pdflatex five times; we can be slightly less conservative. pdf: $(PDFDIR) (cd $(PDFDIR) && \ for i in $(PDFDOCS); do \ texfile=`echo $${i}.tex` && \ idxfile=`echo $${i}.idx` && \ pdflatex $(LATEXOPTS) $$texfile && \ pdflatex $(LATEXOPTS) $$texfile && \ makeindex -s python.ist $$idxfile || true; \ pdflatex $(LATEXOPTS) $$texfile && \ pdflatex $(LATEXOPTS) $$texfile; done && \ rm -f *.dvi *.log *.ind *.aux *.toc *.syn *.idx *.out *.ilg *.pla \ ) # Use doxygen to generate API documentation, translate it into RST # format, and then create a composite of $(docsrc)'s RST and the # generated files in rst_composite. Used by the html and substhtml targets. composite: Doxyfile $(docsrc)/version.py rm -rf doxy rst_apiref rst_composite $(DOXYGEN) (cwd=`pwd`; cd $(docsrc)/tools && \ $(PYTHON) doxy.py -i $$cwd/doxy/xml -o $$cwd/rst_apiref) mkdir -p rst_composite do_subdirs="$(RST_SOURCES)" ; \ for i in $$do_subdirs; do \ cp -r $(docsrc)/$$i rst_composite; \ done cp rst_apiref/*.rst rst_composite/appdev/refs/api cp rst_apiref/types/*.rst rst_composite/appdev/refs/types cp rst_apiref/macros/*.rst rst_composite/appdev/refs/macros cp $(docsrc)/version.py rst_composite Doxyfile: $(srcdir)/Doxyfile.in sed -e 's|@SRC@|$(top_srcdir)|g' \ -e 's|@DOC@|$(top_srcdir)/../doc|g' $(srcdir)/Doxyfile.in > $@ paths.py: rm -f $@ echo 'bindir = "``$(CLIENT_BINDIR)``"' > $@ echo 'sbindir = "``$(SERVER_BINDIR)``"' >> $@ echo 'libdir = "``$(KRB5_LIBDIR)``"' >> $@ echo 'localstatedir = "``$(localstatedir)``"' >> $@ echo 'runstatedir = "``$(runstatedir)``"' >> $@ echo 'sysconfdir = "``$(sysconfdir)``"' >> $@ echo 'ccache = "``$(DEFCCNAME)``"' >> $@ echo 'keytab = "``$(DEFKTNAME)``"' >> $@ echo 'ckeytab = "``$(DEFCKTNAME)``"' >> $@ # Dummy rule that man/Makefile can invoke version.py: $(docsrc)/version.py $(docsrc)/version.py: $(top_srcdir)/patchlevel.h $(srcdir)/version.py.in rm -f $@ $(CC) -E -I$(top_srcdir) - < $(srcdir)/version.py.in > $@ clean: rm -rf doxy rst_apiref rst_composite rst_notice html_subst \ Doxyfile paths.py $(docsrc)/version.py notice.txt \ $(docsrc)/html/.doctrees $(docsrc)/pdf/.doctrees \ $(docsrc)/tools/*.pyc krb5-1.16/src/build-tools/0000755000704600001450000000000013211554426015222 5ustar ghudsonlibuuidkrb5-1.16/src/build-tools/gssrpc.pc.in0000644000704600001450000000037713211554426017463 0ustar ghudsonlibuuidprefix=@prefix@ exec_prefix=@exec_prefix@ libdir=@libdir@ includedir=@includedir@ vendor=MIT Name: gssrpc Description: GSSAPI RPC implementation Version: @KRB5_VERSION@ Cflags: -I${includedir} Libs: -L${libdir} -lgssrpc Requires.private: mit-krb5-gssapi krb5-1.16/src/build-tools/kdb.pc.in0000644000704600001450000000050013211554426016706 0ustar ghudsonlibuuidprefix=@prefix@ exec_prefix=@exec_prefix@ libdir=@libdir@ includedir=@includedir@ KDB5_DB_LIB=@KDB5_DB_LIB@ Name: kdb Description: Kerberos database access libraries Version: @KRB5_VERSION@ Requires.private: mit-krb5-gssapi mit-krb5 gssrpc Cflags: -I${includedir} Libs: -L${libdir} -lkdb5 Libs.private: ${KDB5_DB_LIB} krb5-1.16/src/build-tools/deps0000644000704600001450000000003013211554426016071 0ustar ghudsonlibuuid# No dependencies here. krb5-1.16/src/build-tools/krb5-config.in0000755000704600001450000001502613211554426017667 0ustar ghudsonlibuuid#!/bin/sh # Copyright 2001, 2002, 2003 by the Massachusetts Institute of Technology. # All Rights Reserved. # # Export of this software from the United States of America may # require a specific license from the United States Government. # It is the responsibility of any person or organization contemplating # export to obtain such a license before exporting. # # WITHIN THAT CONSTRAINT, permission to use, copy, modify, and # distribute this software and its documentation for any purpose and # without fee is hereby granted, provided that the above copyright # notice appear in all copies and that both that copyright notice and # this permission notice appear in supporting documentation, and that # the name of M.I.T. not be used in advertising or publicity pertaining # to distribution of the software without specific, written prior # permission. Furthermore if you modify this software you must label # your software as modified software and not distribute it in such a # fashion that it might be confused with the original M.I.T. software. # M.I.T. makes no representations about the suitability of # this software for any purpose. It is provided "as is" without express # or implied warranty. # # # Configurable parameters set by autoconf version_string="Kerberos 5 release @KRB5_VERSION@" prefix=@prefix@ exec_prefix=@exec_prefix@ includedir=@includedir@ libdir=@libdir@ CC_LINK='@CC_LINK@' KDB5_DB_LIB=@KDB5_DB_LIB@ LDFLAGS='@LDFLAGS@' RPATH_FLAG='@RPATH_FLAG@' PROG_RPATH_FLAGS='@PROG_RPATH_FLAGS@' PTHREAD_CFLAGS='@PTHREAD_CFLAGS@' DL_LIB='@DL_LIB@' DEFCCNAME='@DEFCCNAME@' DEFKTNAME='@DEFKTNAME@' DEFCKTNAME='@DEFCKTNAME@' LIBS='@LIBS@' GEN_LIB=@GEN_LIB@ # Defaults for program library=krb5 # Some constants vendor_string="Massachusetts Institute of Technology" # Process arguments # Yes, we are sloppy, library specifications can come before options while test $# != 0; do case $1 in --all) do_all=1 ;; --cflags) do_cflags=1 ;; --defccname) do_defccname=1 ;; --defcktname) do_defcktname=1 ;; --defktname) do_defktname=1 ;; --deps) do_deps=1 ;; --exec-prefix) do_exec_prefix=1 ;; --help) do_help=1 ;; --libs) do_libs=1 ;; --prefix) do_prefix=1 ;; --vendor) do_vendor=1 ;; --version) do_version=1 ;; krb5) library=krb5 ;; gssapi) library=gssapi ;; gssrpc) library=gssrpc ;; kadm-client) library=kadm_client ;; kadm-server) library=kadm_server ;; kdb) library=kdb ;; *) echo "$0: Unknown option \`$1' -- use \`--help' for usage" exit 1 esac shift done # If required options - provide help if test -z "$do_all" -a -z "$do_version" -a -z "$do_vendor" -a \ -z "$do_prefix" -a -z "$do_vendor" -a -z "$do_exec_prefix" -a \ -z "$do_defccname" -a -z "$do_defktname" -a -z "$do_defcktname" -a \ -z "$do_cflags" -a -z "$do_libs"; then do_help=1 fi if test -n "$do_help"; then echo "Usage: $0 [OPTIONS] [LIBRARIES]" echo "Options:" echo " [--help] Help" echo " [--all] Display version, vendor, and various values" echo " [--version] Version information" echo " [--vendor] Vendor information" echo " [--prefix] Kerberos installed prefix" echo " [--exec-prefix] Kerberos installed exec_prefix" echo " [--defccname] Show built-in default ccache name" echo " [--defktname] Show built-in default keytab name" echo " [--defcktname] Show built-in default client keytab name" echo " [--cflags] Compile time CFLAGS" echo " [--libs] List libraries required to link [LIBRARIES]" echo "Libraries:" echo " krb5 Kerberos 5 application" echo " gssapi GSSAPI application with Kerberos 5 bindings" echo " gssrpc GSSAPI RPC application" echo " kadm-client Kadmin client" echo " kadm-server Kadmin server" echo " kdb Application that accesses the kerberos database" exit 0 fi if test -n "$do_all"; then all_exit= do_version=1 do_prefix=1 do_exec_prefix=1 do_vendor=1 title_version="Version: " title_prefix="Prefix: " title_exec_prefix="Exec_prefix: " title_vendor="Vendor: " else all_exit="exit 0" fi if test -n "$do_version"; then echo "$title_version$version_string" $all_exit fi if test -n "$do_vendor"; then echo "$title_vendor$vendor_string" $all_exit fi if test -n "$do_prefix"; then echo "$title_prefix$prefix" $all_exit fi if test -n "$do_exec_prefix"; then echo "$title_exec_prefix$exec_prefix" $all_exit fi if test -n "$do_defccname"; then echo "$DEFCCNAME" $all_exit fi if test -n "$do_defktname"; then echo "$DEFKTNAME" $all_exit fi if test -n "$do_defcktname"; then echo "$DEFCKTNAME" $all_exit fi if test -n "$do_cflags"; then if test x"$includedir" != x"/usr/include" ; then echo "-I${includedir}" else echo '' fi fi if test -n "$do_libs"; then # Assumes /usr/lib is the standard library directory everywhere... if test "$libdir" = /usr/lib; then libdirarg= else libdirarg="-L$libdir" fi # Ugly gross hack for our build tree lib_flags=`echo $CC_LINK | sed -e 's/\$(CC)//' \ -e 's/\$(PURE)//' \ -e 's#\$(PROG_RPATH_FLAGS)#'"$PROG_RPATH_FLAGS"'#' \ -e 's#\$(PROG_RPATH)#'$libdir'#' \ -e 's#\$(PROG_LIBPATH)#'$libdirarg'#' \ -e 's#\$(RPATH_FLAG)#'"$RPATH_FLAG"'#' \ -e 's#\$(LDFLAGS)#'"$LDFLAGS"'#' \ -e 's#\$(PTHREAD_CFLAGS)#'"$PTHREAD_CFLAGS"'#' \ -e 's#\$(CFLAGS)##'` if test $library = 'kdb'; then lib_flags="$lib_flags -lkdb5 $KDB5_DB_LIB" library=krb5 fi if test $library = 'kadm_server'; then lib_flags="$lib_flags -lkadm5srv_mit -lkdb5 $KDB5_DB_LIB" library=gssrpc fi if test $library = 'kadm_client'; then lib_flags="$lib_flags -lkadm5clnt_mit" library=gssrpc fi if test $library = 'gssrpc'; then lib_flags="$lib_flags -lgssrpc" library=gssapi fi if test $library = 'gssapi'; then lib_flags="$lib_flags -lgssapi_krb5" library=krb5 fi if test $library = 'krb5'; then lib_flags="$lib_flags -lkrb5 -lk5crypto -lcom_err" fi # If we ever support a flag to generate output suitable for static # linking, we would output "-lkrb5support $GEN_LIB $LIBS $DL_LIB" # here. echo $lib_flags fi exit 0 krb5-1.16/src/build-tools/t_krbconf0000644000704600001450000000314313211554426017115 0ustar ghudsonlibuuid#!/bin/sh # Copyright 2003 by the Massachusetts Institute of Technology. # All Rights Reserved. # # Export of this software from the United States of America may # require a specific license from the United States Government. # It is the responsibility of any person or organization contemplating # export to obtain such a license before exporting. # # WITHIN THAT CONSTRAINT, permission to use, copy, modify, and # distribute this software and its documentation for any purpose and # without fee is hereby granted, provided that the above copyright # notice appear in all copies and that both that copyright notice and # this permission notice appear in supporting documentation, and that # the name of M.I.T. not be used in advertising or publicity pertaining # to distribution of the software without specific, written prior # permission. Furthermore if you modify this software you must label # your software as modified software and not distribute it in such a # fashion that it might be confused with the original M.I.T. software. # M.I.T. makes no representations about the suitability of # this software for any purpose. It is provided "as is" without express # or implied warranty. echo "Testing if krb5-config outputs shell variables" echo " Testing --libs argument" if ./krb5-config --libs kdb | egrep -s '\$' > /dev/null; then echo "Error './krb5-config --libs kdb' contains shell variables" exit 1 fi echo " Testing --cflags argument" if ./krb5-config --cflags | egrep -s '\$' > /dev/null; then echo "Error './krb5-config --cflags' contains shell variables" exit 1 fi echo "krb5-config tests pass" exit 0 krb5-1.16/src/build-tools/krb5-gssapi.pc.in0000644000704600001450000000032513211554426020302 0ustar ghudsonlibuuidprefix=@prefix@ exec_prefix=@exec_prefix@ libdir=@libdir@ includedir=@includedir@ vendor=MIT Name: krb5-gssapi Description: Kerberos implementation of the GSSAPI Version: @KRB5_VERSION@ Requires: mit-krb5-gssapi krb5-1.16/src/build-tools/kadm-server.pc.in0000644000704600001450000000042013211554426020367 0ustar ghudsonlibuuidprefix=@prefix@ exec_prefix=@exec_prefix@ libdir=@libdir@ includedir=@includedir@ Name: kadm-server Description: Kerberos administration server library Version: @KRB5_VERSION@ Requires.private: kdb mit-krb5-gssapi Cflags: -I${includedir} Libs: -L${libdir} -lkadm5srv_mit krb5-1.16/src/build-tools/mit-krb5-gssapi.pc.in0000644000704600001450000000040713211554426021072 0ustar ghudsonlibuuidprefix=@prefix@ exec_prefix=@exec_prefix@ libdir=@libdir@ includedir=@includedir@ Name: mit-krb5-gssapi Description: Kerberos implementation of the GSSAPI Version: @KRB5_VERSION@ Requires.private: mit-krb5 Cflags: -I${includedir} Libs: -L${libdir} -lgssapi_krb5 krb5-1.16/src/build-tools/Makefile.in0000644000704600001450000000306413211554426017272 0ustar ghudsonlibuuidmydir=build-tools BUILDTOP=$(REL).. PKGCONFIG_FILES = \ kadm-client.pc \ kadm-server.pc \ kdb.pc \ mit-krb5.pc \ krb5.pc \ mit-krb5-gssapi.pc \ krb5-gssapi.pc \ gssrpc.pc all-unix: krb5-config $(PKGCONFIG_FILES) krb5-config $(PKGCONFIG_FILES): $(BUILDTOP)/config.status (cd $(BUILDTOP) && $(SHELL) config.status $(mydir)/$@) krb5-config: $(srcdir)/krb5-config.in kadm-client.pc: $(srcdir)/kadm-client.pc.in kadm-server.pc: $(srcdir)/kadm-server.pc.in kdb.pc: $(srcdir)/kdb.pc.in mit-krb5.pc: $(srcdir)/mit-krb5.pc.in krb5.pc: $(srcdir)/krb5.pc.in mit-krb5-gssapi.pc: $(srcdir)/mit-krb5-gssapi.pc.in krb5-gssapi.pc: $(srcdir)/krb5-gssapi.pc.in gssrpc.pc: $(srcdir)/gssrpc.pc.in install-unix: $(INSTALL_SCRIPT) krb5-config $(DESTDIR)$(CLIENT_BINDIR)/krb5-config $(INSTALL_DATA) kadm-client.pc \ $(DESTDIR)$(PKGCONFIG_DIR)/kadm-client.pc $(INSTALL_DATA) kadm-server.pc \ $(DESTDIR)$(PKGCONFIG_DIR)/kadm-server.pc $(INSTALL_DATA) kdb.pc $(DESTDIR)$(PKGCONFIG_DIR)/kdb.pc $(INSTALL_DATA) mit-krb5.pc $(DESTDIR)$(PKGCONFIG_DIR)/mit-krb5.pc $(INSTALL_DATA) krb5.pc $(DESTDIR)$(PKGCONFIG_DIR)/krb5.pc $(INSTALL_DATA) mit-krb5-gssapi.pc \ $(DESTDIR)$(PKGCONFIG_DIR)/mit-krb5-gssapi.pc $(INSTALL_DATA) krb5-gssapi.pc \ $(DESTDIR)$(PKGCONFIG_DIR)/krb5-gssapi.pc $(INSTALL_DATA) gssrpc.pc \ $(DESTDIR)$(PKGCONFIG_DIR)/gssrpc.pc # Test to ensure that krb5-config does not spit out things like # $(PURE) or $(LDFLAGS) in case someone changes config/shlib.conf check-unix: krb5-config $(SHELL) $(srcdir)/t_krbconf distclean-unix: $(RM) $(PKGCONFIG_FILES) krb5-config krb5-1.16/src/build-tools/krb5.pc.in0000644000704600001450000000043313211554426017016 0ustar ghudsonlibuuidprefix=@prefix@ exec_prefix=@exec_prefix@ libdir=@libdir@ includedir=@includedir@ vendor=MIT defccname=@DEFCCNAME@ defktname=@DEFKTNAME@ defcktname=@DEFCKTNAME@ Name: krb5 Description: An implementation of Kerberos network authentication Version: @KRB5_VERSION@ Requires: mit-krb5 krb5-1.16/src/build-tools/mit-krb5.pc.in0000644000704600001450000000054313211554426017607 0ustar ghudsonlibuuidprefix=@prefix@ exec_prefix=@exec_prefix@ libdir=@libdir@ includedir=@includedir@ defccname=@DEFCCNAME@ defktname=@DEFKTNAME@ defcktname=@DEFCKTNAME@ Name: mit-krb5 Description: An implementation of Kerberos network authentication Version: @KRB5_VERSION@ Cflags: -I${includedir} Libs: -L${libdir} -lkrb5 -lk5crypto -lcom_err Libs.private: -lkrb5support krb5-1.16/src/build-tools/kadm-client.pc.in0000644000704600001450000000042413211554426020343 0ustar ghudsonlibuuidprefix=@prefix@ exec_prefix=@exec_prefix@ libdir=@libdir@ includedir=@includedir@ Name: kadm-client Description: Kerberos administration client library Version: @KRB5_VERSION@ Requires.private: mit-krb5-gssapi gssrpc Cflags: -I${includedir} Libs: -L${libdir} -lkadm5clnt_mit krb5-1.16/src/windows/0000755000704600001450000000000013211554426014457 5ustar ghudsonlibuuidkrb5-1.16/src/windows/README0000644000704600001450000003344613211554426015351 0ustar ghudsonlibuuid Building & Running Kerberos 5 on Windows ---------------------------------------- This file documents how to build MIT Kerberos for Windows. The MIT Kerberos for Windows distribution contains additional components not present in the Unix krb5 distribution, most notably the MIT Kerberos Ticket Manager application. To build Kerberos 5 on Windows, you will need the Windows SDK (XP SP3 or later), VisualStudio (2010 Professional SP1), a version of Perl, and some common Unix utilities such as sed/awk/cp/cat installed in the command-line path. To build an MSI installer, you will additionally need the Windows Installer XML (WiX) toolkit, and to ensure that the HTML Help Compiler (hhc.exe) and the WiX tools are in your command-line path. WiX version 3.5 is verified to work with this codebase; WiX 3.7 and newer are incompatible with this codebase. Visual Studio 2012 and the Windows SDK 8 introduce some changes which alter the Kerberos build procedure slightly (noted where appropriate). The Unix utilities can be obtained via the Utilities and SDK for UNIX-based Aplications, which may be enabled as a Windows feature and then the components installed. Note that the Windows nmake will not find the SUA awk utility in the path unless it is named awk.exe; the permissions on the utility may need correcting if awk.exe is created as a copy of the original awk. There is a version of perl available through the SUA, but it is not sufficient to build krb5. An external perl such as Strawberry Perl or ActiveState Perl is necessary. The krb5 source tree may be obtained either directly on the Windows machine with a native git client cloning the krb5 public mirror at https://github.com/krb5/krb5.git or on a separate (Unix) machine and copied over, such as from a VM host onto a Windows VM. The kerbsrc.zip method is no longer supported. After the Windows SDK is installed, you should be able to invoke an SDK command prompt via the start menu (All Programs -> Microsoft Windows SDK vX.Y -> Windows SDK X.Y Command Prompt). Within this window, you can change the build target using the setenv command; run "setenv /?" or see the Windows SDK documentation for details. At the current time, Kerberos 5 can only be built for the x64 target if the host platform is also 64-bit, because it compiles and runs programs during the build. The Windows SDK version 8 does not provide an SDK command prompt; the "Developer Command Prompt for VS2012" or "Visual Studio Command Prompt" must be used instead. Accordingly, there is no setenv script to configure the build environment for different target architectures; the "vcvarsall.bat" script provided by Visual Studio serves this function. IMPORTANT NOTE: By default, the sources are built with debug information and linked against the debug version of the Microsoft C Runtime library, which is not found on most Windows systems unless they have development tools, and requires a separate license to distribute. To build a release version, you need to define NODEBUG either in the environment or the nmake command-line and use setenv to enter a release build environment with "setenv /release" (when using Windows SDK versions lower than 8). Debug information in the compiled binaries and libraries may be retained by defining DEBUG_SYMBOL in the environment or on the nmake command line. Building the code and installer ------------------------ First, make sure you have sed, (g)awk, cat, and cp. You must also define KRB_INSTALL_DIR either in the environment or on the command line (for nmake install). If you are proceeding to build the MSI installer, this directory should be a temporary staging area in or near your build tree. The directory must exist before nmake install is run. The 64-bit installer provides 32-bit libraries, so a 32-bit build and install must be performed before the 64-bit build. 1) set CPU=i386 # Get 32-bit target in environment 2) set KRB_INSTALL_DIR=\path\to\dir # Where bin/include/lib lives 3) setenv /x86 [/release] # Tell nmake to target 32-bit (with Visual Studio 2012, use "vcvarsall.bat x86") 4) cd xxx/src # Go to where the source lives 5) nmake -f Makefile.in prep-windows # Create Makefile for Windows 6) nmake [NODEBUG=1] # Build the sources 7) nmake install [NODEBUG=1] # Copy headers, libs, executables 8) cd windows\installer\wix # Go to where the installer source is 9) nmake # Build the installer 10) rename kfw.msi kfw32.msi # Save the 32-bit installer 11) set CPU=AMD64 # Proceed to the 64-bit build 12) setenv /x64 [/release] # Must set both CPU and nmake env ("vcvarsall.bat amd64" for Visual Studio 2012) 13) cd ..\..\.. # Back to the sources 14) nmake clean # Clean up the 32-bit objects 15) nmake [NODEBUG=1] # Build the sources for 64-bit 16) nmake install [NODEBUG=1] # Copy 64-bit lib/executables 17) cd windows\installer\wix # Back to the installer source 18) nmake clean # Remove 32-bit leavings 19) nmake # Build the 64-bit installer 20) rename kfw.msi kfw64.msi # And name it usefully Running Kerberos 5 Apps: ----------------------- Make sure you have a valid krb5.ini file. By default, an empty krb5.ini is installed in CSIDL_COMMON_APPDATA (that is, %SystemDrive%\ProgramData\MIT\Kerberos5\ on newer-than-XP). (ProgramData is a hidden folder.) You may need to customize it with settings for your site, but since DNS lookups are enabled for locating KDCs, many sites will not need further customization. The file format is identical to that of a Unix krb5.conf file. krb5.ini File: ------------- WARNING: Despite its name, this is not a Windows .ini file. Therefore, do not try to use any .ini tools, including the Windows API or any installer tools to manipulate this file. Its format is subtly different from Windows .ini files! Controlling the Kerberos 5 Run-Time Environment: ----------------------------------------------- The Kerberos 5 configuration file and credentials cache can be controlled with environment variables and registry settings. The environment variable for a particular setting always takes precedence. Next in precedence comes the setting in the registry under HKEY_CURRENT_USER\Software\MIT\Kerberos5. Then comes the registry setting under HKEY_LOCAL_MACHINE\Software\MIT\Kerberos5. If none of those are found, a default value is used. Configuration File: - Environment: KRB5_CONFIG - Registry Value: config - Default: looks in the user's AppData directory, the machine's ProgramData directory, krb5_32.dll's dir and Windows directory Default Credentials Cache: - Environment: KRB5CCNAME - Registry Value: ccname - Default: API: Credentials Cache: ----------------- In addition to standard FILE: (disk file) and MEMORY: (in-process non-shared memory) Windows supports the API: cache type, which is a shared memory cache. Kerberos for Windows also has access to an MSLSA: cache type, which directly accesses the Microsoft Kerberos Logon Session credentials cache. The MSLSA: cache is available when the user logon is performed using Kerberos either to an Active Directory Domain or a non-Microsoft KDC; the ms2mit and mit2ms utilities can also be used to interact with it, though there are some limitations. A user is able to logon to Windows using the Kerberos LSA if the machine is part of a Windows Active Directory domain or if the machine has been configured to authenticate to a non-Microsoft KDC such as MIT. The instructions for configuring a Windows 2000 XP workstation to authenticate to a non-Microsoft KDC are documented in TechNet somewhere. In brief: 1. Install the Windows support tools in order to obtain KSETUP.EXE and KTPASS.EXE. 2. Install the Windows Resource Kit to obtain KERBTRAY.EXE and KLIST.EXE 3. Add Realms and associated KDCs with: *KSETUP /AddKdc []*. If you leave off the DNS SRV records will be used. 4. Specify the password change service host for the realm with: *KSETUP /AddKpasswd * 5. Assign the realm of the local machine with: *KSETUP /SetRealm * where realm must be all upper case. 6. Assign the local machine's password with: *KSETUP /SetComputerPassword * 7. Specify the capabilities of the Realm KDC with: *KSETUP /SetRealmFlags [ ...]* where flags may be *None, SendAddress, TcpSupported, Delegate, *and *NcSupported*, 8. Map principal names to local accounts with: *KSETUP /MapUser * On the MIT KDC, you must then create service principals using the "Password" assigned to the machine. So far the minimum list of principals required appear to be for a machine named "mymachine" in the realm "EXAMPLE.COM" with a domain name of "example.com": * host/mymachine@EXAMPLE.COM * host/mymachine.example.com@EXAMPLE.COM * cifs/mymachine@EXAMPLE.COM * cifs/mymachine.example.com@EXAMPLE.COM There may very well be other services for which principals must be created depending on what services are being executed on the machine. It is very important to note that while you can successfully log into a Windows workstation by authenticating to the KDC without creating a host key; the logon session you receive will not be a Kerberos Logon Session. There will be no Kerberos principal and no LSA cache to access. The result of a real KSETUP configuration looks like this: [C:\4\4NT]ksetup default realm = KRB5.COLUMBIA.EDU (external) ATHENA.MIT.EDU: kdc = kerberos.mit.edu kdc = kerberos-1.mit.edu kdc = kerberos-2.mit.edu kdc = kerberos-3.mit.edu Realm Flags = 0x0 none CC.COLUMBIA.EDU: kdc = kerberos.cc.columbia.edu Realm Flags = 0x0 none GRAND.CENTRAL.ORG: kdc = penn.central.org kdc = grand-opening.mit.edu Realm Flags = 0x0 none KRB5.COLUMBIA.EDU: kdc = yclept.kermit.columbia.edu Realm Flags = 0x0 none OPENAFS.ORG: kdc = virtue.openafs.org Realm Flags = 0x0 none Mapping jaltman@KRB5.COLUMBIA.EDU to jaltman. Mapping jaltman@CC.COLUMBIA.EDU to jaltman. Mapping jaltman@ATHENA.MIT.EDU to jaltman. Mapping all users (*) to a local account by the same name (*). The MSLSA: credential cache relies on the ability to extract the entire Kerberos ticket including the session key from the Kerberos LSA. In an attempt to increase security Microsoft has begun to implement a feature by which they no longer export the session keys for Ticket Getting Tickets. This has the side effect of making them useless to the MIT krb5 library when attempting to request additional service tickets. This new feature has been seen in Windows 2003 Server, Windows 2000 Server SP4, and Windows XP SP2. We assume that it will be implemented in all future Microsoft operating systems supporting the Kerberos SSPI. Microsoft does work closely with MIT and has provided a registry key to disable this new feature. On server platforms the key is specified as: HKLM\SYSTEM\CurrentControlSet\Control\Lsa\Kerberos\Parameters AllowTGTSessionKey = 0x01 (DWORD) On workstation platforms the key is specified as: HKLM\SYSTEM\CurrentControlSet\Control\Lsa\Kerberos AllowTGTSessionKey = 0x01 (DWORD) The Kerberos for Windows installer automatically sets this key on installation and unsets it on uninstall, allowing the MSLSA: cache type to be used. It has been noted that the Microsoft Kerberos LSA does not provide enough information within its KERB_EXTERNAL_TICKET structure to properly construct the Client Principal simply by examining a single ticket. From the MSDN Library: ClientName KERB_EXTERNAL_NAME structure that contains the client name in the ticket. This name is relative to the current domain. DomainName UNICODE_STRING that contains the name of the domain that corresponds to the ServiceName member. This is the domain that issued the ticket. TargetDomainName UNICODE_STRING that contains the name of the domain in which the ticket is valid. For an interdomain ticket, this is the destination domain. AltTargetDomainName UNICODE_STRING that contains a synonym for the destination domain. Every domain has two names: a DNS name and a NetBIOS name. If the name returned in the ticket is different from the name used to request the ticket (the Kerberos Key Distribution Center (KDC) may do name mapping), this string contains the original name. Unfortunately, there is no field here which contains the domain of the client. In order for the krb5_ccache to properly report the client principal name, the client principal name is constructed by utilizing the ClientName and DomainName fields of the Initial TGT associated with the Kerberos LSA credential cache. To disable the use of the TGT info and instead simply use the "DomainName" field of the current ticket define one of the following registry keys depending on whether the change should be system global or just for the current user. HKLM\Software\MIT\Kerberos5\ PreserveInitialTicketIdentity = 0x0 (DWORD) HKCU\Software\MIT\Kerberos5\ PreserveInitialTicketIdentity = 0x0 (DWORD) GSSAPI Sample Client: --------------------- The GSS API Sample Client provided in this distribution is compatible with the gss-server application built on Unix/Linux systems. This client is not compatible with the Platform SDK/Samples/Security/SSPI/GSS/ samples which Microsoft has been shipping as of January 2004. Revised versions of these samples are available upon request to krbdev@mit.edu. More Information: ---------------- For more information, please read the Kerberos 5 documentation in the doc directory of the distribution. krb5-1.16/src/windows/ms2mit/0000755000704600001450000000000013211554426015672 5ustar ghudsonlibuuidkrb5-1.16/src/windows/ms2mit/ms2mit.c0000644000704600001450000001360613211554426017257 0ustar ghudsonlibuuid/* windows/ms2mit/ms2mit.c */ /* * Copyright (C) 2003 by the Massachusetts Institute of Technology. * All rights reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #include "k5-int.h" #include "krb5.h" #include #include #include static char *prog; static void xusage(void) { fprintf(stderr, "xusage: %s [-c ccache]\n", prog); exit(1); } /* Return true if princ is a local (not cross-realm) krbtgt principal. */ krb5_boolean is_local_tgt(krb5_principal princ) { return princ->length == 2 && data_eq_string(princ->data[0], KRB5_TGS_NAME) && data_eq(princ->realm, princ->data[1]); } /* * Check if a ccache has any tickets. */ static krb5_error_code cc_has_tickets(krb5_context kcontext, krb5_ccache ccache, int *has_tickets) { krb5_error_code code; krb5_cc_cursor cursor; krb5_creds creds; krb5_timestamp now = time(0); *has_tickets = 0; code = krb5_cc_set_flags(kcontext, ccache, KRB5_TC_NOTICKET); if (code) return code; code = krb5_cc_start_seq_get(kcontext, ccache, &cursor); if (code) return code; while (!*has_tickets) { code = krb5_cc_next_cred(kcontext, ccache, &cursor, &creds); if (code) break; if (!krb5_is_config_principal(kcontext, creds.server) && ts_after(creds.times.endtime, now)) *has_tickets = 1; krb5_free_cred_contents(kcontext, &creds); } krb5_cc_end_seq_get(kcontext, ccache, &cursor); return 0; } int main(int argc, char *argv[]) { krb5_context kcontext = NULL; krb5_error_code code; krb5_ccache ccache=NULL; krb5_ccache mslsa_ccache=NULL; krb5_cc_cursor cursor; krb5_creds creds; krb5_principal princ = NULL; int found_tgt = 0; int has_tickets; int option; char * ccachestr = 0; prog = strrchr(argv[0], '/'); prog = prog ? (prog + 1) : argv[0]; while ((option = getopt(argc, argv, "c:h")) != -1) { switch (option) { case 'c': ccachestr = optarg; break; case 'h': default: xusage(); break; } } if (code = krb5_init_context(&kcontext)) { com_err(argv[0], code, "while initializing kerberos library"); goto cleanup; } if (code = krb5_cc_resolve(kcontext, "MSLSA:", &mslsa_ccache)) { com_err(argv[0], code, "while opening MS LSA ccache"); goto cleanup; } /* Enumerate tickets from cache looking for a TGT */ if ((code = krb5_cc_start_seq_get(kcontext, mslsa_ccache, &cursor))) { com_err(argv[0], code, "while initiating the cred sequence of MS LSA ccache"); goto cleanup; } while (!found_tgt) { code = krb5_cc_next_cred(kcontext, mslsa_ccache, &cursor, &creds); if (code) break; /* Check if the ticket is a TGT */ if (is_local_tgt(creds.server)) found_tgt = 1; krb5_free_cred_contents(kcontext, &creds); } krb5_cc_end_seq_get(kcontext, mslsa_ccache, &cursor); if (!found_tgt) { fprintf(stderr, "%s: Initial Ticket Getting Tickets are not available from the MS LSA\n", argv[0]); /* Only set the LSA cache as the default if it actually has tickets. */ code = cc_has_tickets(kcontext, mslsa_ccache, &has_tickets); if (code) goto cleanup; if (has_tickets) code = krb5int_cc_user_set_default_name(kcontext, "MSLSA:"); goto cleanup; } if (code = krb5_cc_get_principal(kcontext, mslsa_ccache, &princ)) { com_err(argv[0], code, "while obtaining MS LSA principal"); goto cleanup; } if (ccachestr) code = krb5_cc_resolve(kcontext, ccachestr, &ccache); else code = krb5_cc_resolve(kcontext, "API:", &ccache); if (code) { com_err(argv[0], code, "while getting default ccache"); goto cleanup; } if (code = krb5_cc_initialize(kcontext, ccache, princ)) { com_err (argv[0], code, "when initializing ccache"); goto cleanup; } if (code = krb5_cc_copy_creds(kcontext, mslsa_ccache, ccache)) { com_err (argv[0], code, "while copying MS LSA ccache to default ccache"); goto cleanup; } /* Don't try and set the default cache if the cache name was specified. */ if (ccachestr == NULL) { /* On success set the default cache to API. */ code = krb5int_cc_user_set_default_name(kcontext, "API:"); if (code) { com_err(argv[0], code, "when setting default to API"); goto cleanup; } } cleanup: krb5_free_principal(kcontext, princ); if (ccache != NULL) krb5_cc_close(kcontext, ccache); if (mslsa_ccache != NULL) krb5_cc_close(kcontext, mslsa_ccache); krb5_free_context(kcontext); return code ? 1 : 0; } krb5-1.16/src/windows/ms2mit/mit2ms.c0000644000704600001450000001063713211554426017260 0ustar ghudsonlibuuid/* windows/ms2mit/mit2ms.c */ /* * Copyright (C) 2003,2004 by the Massachusetts Institute of Technology. * All rights reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #include "krb5.h" #include #include #include "k5-platform.h" static char *prog; static void xusage(void) { fprintf(stderr, "xusage: %s [-c ccache]\n", prog); exit(1); } void main( int argc, char *argv[] ) { krb5_context kcontext; krb5_error_code code; krb5_ccache ccache=NULL; krb5_ccache mslsa_ccache=NULL; krb5_cc_cursor cursor; krb5_creds creds; krb5_principal princ; int initial_ticket = 0; int option; char * ccachestr = 0; prog = strrchr(argv[0], '/'); prog = prog ? (prog + 1) : argv[0]; while ((option = getopt(argc, argv, "c:h")) != -1) { switch (option) { case 'c': ccachestr = optarg; break; case 'h': default: xusage(); break; } } if (code = krb5_init_context(&kcontext)) { com_err(argv[0], code, "while initializing kerberos library"); exit(1); } if (ccachestr) code = krb5_cc_resolve(kcontext, ccachestr, &ccache); else code = krb5_cc_default(kcontext, &ccache); if (code) { com_err(argv[0], code, "while getting default ccache"); krb5_free_principal(kcontext, princ); krb5_free_context(kcontext); exit(1); } /* Enumerate tickets from cache looking for an initial ticket */ if ((code = krb5_cc_start_seq_get(kcontext, ccache, &cursor))) { com_err(argv[0], code, "while initiating the cred sequence of MS LSA ccache"); krb5_cc_close(kcontext, ccache); krb5_free_context(kcontext); exit(1); } while (!(code = krb5_cc_next_cred(kcontext, ccache, &cursor, &creds))) { if ( creds.ticket_flags & TKT_FLG_INITIAL ) { krb5_free_cred_contents(kcontext, &creds); initial_ticket = 1; break; } krb5_free_cred_contents(kcontext, &creds); } krb5_cc_end_seq_get(kcontext, ccache, &cursor); if ( !initial_ticket ) { fprintf(stderr, "%s: Initial Ticket Getting Tickets are not available from the MIT default cache\n", argv[0]); krb5_cc_close(kcontext, ccache); krb5_free_context(kcontext); exit(1); } if (code = krb5_cc_get_principal(kcontext, ccache, &princ)) { com_err(argv[0], code, "while obtaining default MIT principal"); krb5_cc_close(kcontext, ccache); krb5_free_context(kcontext); exit(1); } if (code = krb5_cc_resolve(kcontext, "MSLSA:", &mslsa_ccache)) { com_err(argv[0], code, "while opening MS LSA ccache"); krb5_cc_close(kcontext, ccache); krb5_free_context(kcontext); exit(1); } if (code = krb5_cc_copy_creds(kcontext, ccache, mslsa_ccache)) { com_err (argv[0], code, "while copying default MIT ccache to MSLSA ccache"); krb5_free_principal(kcontext, princ); krb5_cc_close(kcontext, ccache); krb5_cc_close(kcontext, mslsa_ccache); krb5_free_context(kcontext); exit(1); } krb5_free_principal(kcontext, princ); krb5_cc_close(kcontext, ccache); krb5_cc_close(kcontext, mslsa_ccache); krb5_free_context(kcontext); return(0); } krb5-1.16/src/windows/ms2mit/Makefile.in0000644000704600001450000000206013211554426017735 0ustar ghudsonlibuuid# Makefile for the Microsoft to MIT cache converter. # Works for k5 release only. # mydir=. BUILDTOP=$(REL)..$(S).. DEFINES = PROG_LIBPATH=-L$(TOPLIBD) -L$(KRB5_LIBDIR) VERSIONRC = $(BUILDTOP)\windows\version.rc RCFLAGS=$(CPPFLAGS) -I$(top_srcdir) -D_WIN32 -DRES_ONLY MS2MIT=$(OUTPRE)ms2mit.exe MIT2MS=$(OUTPRE)mit2ms.exe MS2MITRES=$(MS2MIT:.exe=.res) MIT2MSRES=$(MIT2MS:.exe=.res) $(MS2MITRES): $(VERSIONRC) $(RC) $(RCFLAGS) -DMS2MIT_APP -fo $@ -r $** $(MIT2MSRES): $(VERSIONRC) $(RC) $(RCFLAGS) -DMIT2MS_APP -fo $@ -r $** all-windows: $(MS2MIT) $(MIT2MS) $(MS2MIT): $(OUTPRE)ms2mit.obj $(MS2MITRES) link $(EXE_LINKOPTS) -out:$@ $(OUTPRE)ms2mit.obj $(SLIB) user32.lib advapi32.lib $(KLIB) $(CLIB) $(MS2MITRES) $(_VC_MANIFEST_EMBED_EXE) $(MIT2MS): $(OUTPRE)mit2ms.obj $(MIT2MSRES) link $(EXE_LINKOPTS) -out:$@ $(OUTPRE)mit2ms.obj $(SLIB) user32.lib advapi32.lib $(KLIB) $(CLIB) $(MIT2MSRES) $(_VC_MANIFEST_EMBED_EXE) install: copy $(OUTPRE)ms2mit.exe $(DESTDIR) copy $(OUTPRE)mit2ms.exe $(DESTDIR) clean: $(RM) $(OUTPRE)*.exe krb5-1.16/src/windows/winlevel.h0000644000704600001450000000274313211554426016463 0ustar ghudsonlibuuid/* windows/winlevel.h */ /* * Copyright (C) 2006 by the Massachusetts Institute of Technology. * All rights reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ /* * This is the slave file for Windows version stamping purposes. /* This value should be an ever increasing number that is * updated for each alpha, beta, final release. This will ensure * that file identifiers are unique */ #define KRB5_BUILDLEVEL 0 krb5-1.16/src/windows/version.rc0000644000704600001450000002527713211554426016507 0ustar ghudsonlibuuid#include #include #include "kerberos.ver" #include "winlevel.h" /* * BEGIN COMMON VERSION INFO for GSS and Kerberos version resources */ #define XSTR(x) #x #define STR(x) XSTR(x) #define MAJOR_MINOR STR(KRB5_MAJOR_RELEASE) "." STR(KRB5_MINOR_RELEASE) #if KRB5_PATCHLEVEL != 0 #define MAYBE_PATCH "." STR(KRB5_PATCHLEVEL) #else #define MAYBE_PATCH "" #endif #ifdef KRB5_RELTAIL #define RELTAIL "-" KRB5_RELTAIL #else #define RELTAIL "" #endif #ifdef BETA #define BETA_FLAG VS_FF_PRERELEASE #else #define BETA_FLAG 0 #endif #if !defined(_WIN32) #define Targ_OS VOS__WINDOWS16 #else #define Targ_OS VOS__WINDOWS32 #endif /* we're going to stamp all the DLLs with the same version number */ #define K5_PRODUCT_VERSION_STRING MAJOR_MINOR MAYBE_PATCH RELTAIL "\0" #define K5_PRODUCT_VERSION KRB5_MAJOR_RELEASE, KRB5_MINOR_RELEASE, KRB5_PATCHLEVEL, KRB5_BUILDLEVEL #define K5_COPYRIGHT "Copyright (C) 1997-2017 by the Massachusetts Institute of Technology\0" #define K5_COMPANY_NAME "Massachusetts Institute of Technology.\0" /* * END COMMON VERSION INFO */ /* * BEGIN SPECIFIC VERSION INFO for GSS and Kerberos version resources */ #ifdef SUPPORT_LIB #define K5_DESCRIPTION "Kerberos v5 support - internal support code for " KRB5_PRODUCTNAME_STR #define K5_INTERNAL_NAME "krb5support\0" #define K5_FILETYPE VFT_DLL #if defined(_WIN64) #define K5_ORIGINAL_NAME "k5sprt64.dll\0" #else #define K5_ORIGINAL_NAME "k5sprt32.dll\0" #endif #endif /* support */ #ifdef CE_LIB #define K5_DESCRIPTION "COM_ERR - Common Error Handler for " KRB5_PRODUCTNAME_STR "\0" #define K5_INTERNAL_NAME "comerr\0" #define K5_FILETYPE VFT_DLL #if defined(_WIN64) #define K5_ORIGINAL_NAME "comerr64.dll\0" #else #define K5_ORIGINAL_NAME "comerr32.dll\0" #endif #endif /* comerr */ #ifdef PROF_LIB #define K5_DESCRIPTION "PROFILE - Profile Library " KRB5_PRODUCTNAME_STR "\0" #define K5_INTERNAL_NAME "profile\0" #define K5_FILETYPE VFT_DLL #if defined(_WIN64) #define K5_ORIGINAL_NAME "xpprof64.dll\0" #else #define K5_ORIGINAL_NAME "xpprof32.dll\0" #endif #endif /* profile */ #ifdef KRB5_LIB #define K5_DESCRIPTION "Kerberos v5 - " KRB5_PRODUCTNAME_STR "\0" #define K5_INTERNAL_NAME "krb5\0" #define K5_FILETYPE VFT_DLL #if defined(_WIN64) #define K5_ORIGINAL_NAME "krb5_64.dll\0" #else #define K5_ORIGINAL_NAME "krb5_32.dll\0" #endif #endif /* KRB5 */ #ifdef GSSAPI_LIB #define K5_DESCRIPTION "GSSAPI - GSS API implementation for Kerberos 5 mechanism\0" #define K5_INTERNAL_NAME "gssapi\0" #define K5_FILETYPE VFT_DLL #if defined(_WIN64) #define K5_ORIGINAL_NAME "gssapi64.dll\0" #else #define K5_ORIGINAL_NAME "gssapi32.dll\0" #endif #endif /* GSSAPI */ #ifdef CCAPI_LIB #define K5_DESCRIPTION "Kerberos Credentials Cache DLL\0" #define K5_INTERNAL_NAME "krbcc\0" #define K5_FILETYPE VFT_DLL #if defined(_WIN64) #define K5_ORIGINAL_NAME "krbcc64.dll\0" #else #define K5_ORIGINAL_NAME "krbcc32.dll\0" #endif #endif /* CCAPI_LIB */ #ifdef CCAPISERVER_APP #define K5_DESCRIPTION "Kerberos Credentials Cache API Server\0" #define K5_FILETYPE VFT_APP #define K5_INTERNAL_NAME "CCAPISERVER\0" #define K5_ORIGINAL_NAME "ccapiserver.exe\0" #endif /* CCAPISERVER_APP */ #ifdef LEASH_APP #define K5_DESCRIPTION "MIT Kerberos Ticket Manager - " KRB5_PRODUCTNAME_STR "\0" #define K5_FILETYPE VFT_APP #define K5_INTERNAL_NAME "LEASH\0" #define K5_ORIGINAL_NAME "MIT Kerberos.exe\0" #endif #ifdef LEASHDLL_LIB #define K5_DESCRIPTION "Leash Helper API - " KRB5_PRODUCTNAME_STR "\0" #define K5_INTERNAL_NAME "leashw\0" #define K5_FILETYPE VFT_DLL #if defined(_WIN64) #define K5_ORIGINAL_NAME "leashw64.dll\0" #else #define K5_ORIGINAL_NAME "leashw32.dll\0" #endif #endif /* LEASHDLL_LIB */ #ifdef WSHELPER_LIB #define K5_DESCRIPTION "Winsock Helper (wshelper) API - " KRB5_PRODUCTNAME_STR "\0" #define K5_INTERNAL_NAME "wshelper\0" #define K5_FILETYPE VFT_DLL #if defined(_WIN64) #define K5_ORIGINAL_NAME "wshelper64.dll\0" #else #define K5_ORIGINAL_NAME "wshelper32.dll\0" #endif #endif /* WSHELPER_LIB */ #ifdef KRB4_LIB #define K5_DESCRIPTION "Kerberos v4 - " KRB5_PRODUCTNAME_STR "\0" #define K5_INTERNAL_NAME "krb4\0" #define K5_FILETYPE VFT_DLL #if !defined(_WIN32) #define K5_ORIGINAL_NAME "krb4_16.dll\0" #else #define K5_ORIGINAL_NAME "krb4_32.dll\0" #endif #endif /* KRB4 */ #ifdef SAPKRB_LIB #define K5_DESCRIPTION "Kerberos v5 - " KRB5_PRODUCTNAME_STR " (for SAP)\0" #define K5_INTERNAL_NAME "sapkrb5\0" #define K5_FILETYPE VFT_DLL #if !defined(_WIN32) #define K5_ORIGINAL_NAME "sapkrb16.dll\0" #else #define K5_ORIGINAL_NAME "sapkrb32.dll\0" #endif #endif /* SAPKRB */ #ifdef SAPGSS_LIB #define K5_DESCRIPTION "GSSAPI - GSS API implementation for Kerberos 5 mechanism(for SAP)\0" #define K5_INTERNAL_NAME "sapgss\0" #define K5_FILETYPE VFT_DLL #if !defined(_WIN32) #define K5_ORIGINAL_NAME "sapgss16.dll\0" #else #define K5_ORIGINAL_NAME "sapgss32.dll\0" #endif #endif /* SAPGSS */ #ifdef KRB5_APP #define K5_DESCRIPTION "KRB5 Ticket Manager - " KRB5_PRODUCTNAME_STR "\0" #define K5_FILETYPE VFT_APP #define K5_INTERNAL_NAME "KRB5\0" #define K5_ORIGINAL_NAME "krb5.exe\0" #endif /* KRB5_APP */ #ifdef GSS_APP #define K5_DESCRIPTION "GSS - GSS Sample Application for " KRB5_PRODUCTNAME_STR "\0" #define K5_FILETYPE VFT_APP #define K5_INTERNAL_NAME "GSS\0" #define K5_ORIGINAL_NAME "gss.exe\0" #endif #ifdef TELNET_APP #define K5_DESCRIPTION "Telnet - Telnet Application for " KRB5_PRODUCTNAME_STR "\0" #define K5_FILETYPE VFT_APP #define K5_INTERNAL_NAME "TELNET\0" #define K5_ORIGINAL_NAME "telnet.exe\0" #endif #ifdef KRB524_LIB #define K5_DESCRIPTION "Kerberos v5 to v4 - " KRB5_PRODUCTNAME_STR "\0" #define K5_INTERNAL_NAME "krb524\0" #define K5_FILETYPE VFT_DLL #define K5_ORIGINAL_NAME "krb524.dll\0" #endif /* KRB524_LIB */ #ifdef KRB524_INIT #define K5_DESCRIPTION "Kerberos v5 to v4 Application - " KRB5_PRODUCTNAME_STR "\0" #define K5_INTERNAL_NAME "krb524_init\0" #define K5_FILETYPE VFT_DLL #define K5_ORIGINAL_NAME "krb524_init.exe\0" #endif /* KRB524_INIT */ #ifdef MS2MIT_APP #define K5_DESCRIPTION "Microsoft LSA to MIT Credential Cache Application - " KRB5_PRODUCTNAME_STR "\0" #define K5_INTERNAL_NAME "ms2mit\0" #define K5_FILETYPE VFT_DLL #define K5_ORIGINAL_NAME "ms2mit.exe\0" #endif /* MS2MIT_APP */ #ifdef MIT2MS_APP #define K5_DESCRIPTION "MIT to Microsoft LSA Credential Cache Application - " KRB5_PRODUCTNAME_STR "\0" #define K5_INTERNAL_NAME "mit2ms\0" #define K5_FILETYPE VFT_DLL #define K5_ORIGINAL_NAME "mit2ms.exe\0" #endif /* MIT2MS_APP */ #ifdef KVNO_APP #define K5_DESCRIPTION "Key Version Number Application - " KRB5_PRODUCTNAME_STR "\0" #define K5_INTERNAL_NAME "kvno\0" #define K5_FILETYPE VFT_DLL #define K5_ORIGINAL_NAME "kvno.exe\0" #endif /* KVNO_APP */ #ifdef KPASSWD_APP #define K5_DESCRIPTION "Kerberos Change Password Application - " KRB5_PRODUCTNAME_STR "\0" #define K5_INTERNAL_NAME "kpasswd\0" #define K5_FILETYPE VFT_DLL #define K5_ORIGINAL_NAME "kpasswd.exe\0" #endif /* KPASSWD_APP */ #ifdef KFWLOGON_LIB #define K5_DESCRIPTION "Kerberos Network Provider - " KRB5_PRODUCTNAME_STR "\0" #define K5_INTERNAL_NAME "kfwlogon\0" #define K5_FILETYPE VFT_DLL #define K5_ORIGINAL_NAME "kfwlogon.dll\0" #endif /* KFWLOGON_LIB */ #ifdef KFWCPCC_APP #define K5_DESCRIPTION "Copy Credential Cache Application - " KRB5_PRODUCTNAME_STR "\0" #define K5_INTERNAL_NAME "kfwcpcc\0" #define K5_FILETYPE VFT_DLL #define K5_ORIGINAL_NAME "kfwcpcc.exe\0" #endif /* KFWCPCC_APP */ #ifdef KCPYTKT_APP #define K5_DESCRIPTION "Kerberos Copy Ticket Application - " KRB5_PRODUCTNAME_STR "\0" #define K5_INTERNAL_NAME "kcpytkt\0" #define K5_FILETYPE VFT_DLL #define K5_ORIGINAL_NAME "kcpytkt.exe\0" #endif /* KCPYTKT_APP */ #ifdef KDELTKT_APP #define K5_DESCRIPTION "Kerberos Delete Ticket Application - " KRB5_PRODUCTNAME_STR "\0" #define K5_INTERNAL_NAME "kdeltkt\0" #define K5_FILETYPE VFT_DLL #define K5_ORIGINAL_NAME "kdeltkt.exe\0" #endif /* KDELTKT_APP */ #ifdef KDESTROY_APP #define K5_DESCRIPTION "Kerberos Destroy Credential Cache Application - " KRB5_PRODUCTNAME_STR "\0" #define K5_INTERNAL_NAME "kdestroy\0" #define K5_FILETYPE VFT_DLL #define K5_ORIGINAL_NAME "kdestroy.exe\0" #endif /* KDESTROY_APP */ #ifdef KINIT_APP #define K5_DESCRIPTION "Kerberos Initialize Credential Cache Application - " KRB5_PRODUCTNAME_STR "\0" #define K5_INTERNAL_NAME "kinit\0" #define K5_FILETYPE VFT_DLL #define K5_ORIGINAL_NAME "kinit.exe\0" #endif /* KINIT_APP */ #ifdef KLIST_APP #define K5_DESCRIPTION "Kerberos List Credential Cache Application - " KRB5_PRODUCTNAME_STR "\0" #define K5_INTERNAL_NAME "klist\0" #define K5_FILETYPE VFT_DLL #define K5_ORIGINAL_NAME "klist.exe\0" #endif /* KLIST_APP */ #ifdef KSWITCH_APP #define K5_DESCRIPTION "Kerberos Switch Credential Cache Application - MIT GSS / Kerberos v5 distribution\0" #define K5_INTERNAL_NAME "kswitch\0" #define K5_FILETYPE VFT_APP #define K5_ORIGINAL_NAME "kswitch.exe\0" #endif /* KSWITCH_APP */ #ifdef GSS_CLIENT_APP #define K5_DESCRIPTION "GSS Sample Client Application - " KRB5_PRODUCTNAME_STR "\0" #define K5_INTERNAL_NAME "gss-client\0" #define K5_FILETYPE VFT_DLL #define K5_ORIGINAL_NAME "gss-client.exe\0" #endif /* GSS_CLIENT_APP */ #ifdef GSS_SERVER_APP #define K5_DESCRIPTION "GSS Sample Server Application - " KRB5_PRODUCTNAME_STR "\0" #define K5_INTERNAL_NAME "gss-server\0" #define K5_FILETYPE VFT_DLL #define K5_ORIGINAL_NAME "gss-server.exe\0" #endif /* GSS_SERVER_APP */ /* * END SPECIFIC VERSION INFO */ VS_VERSION_INFO VERSIONINFO FILEVERSION K5_PRODUCT_VERSION PRODUCTVERSION K5_PRODUCT_VERSION FILEFLAGSMASK VS_FFI_FILEFLAGSMASK FILEFLAGS (VS_FF_DEBUG | VS_FF_PRIVATEBUILD | BETA_FLAG) FILEOS Targ_OS FILETYPE K5_FILETYPE BEGIN BLOCK "VarFileInfo" BEGIN VALUE "Translation", 0x0409, 1252 END BLOCK "StringFileInfo" BEGIN BLOCK "040904E4" BEGIN #if defined(VER_EXTRA_LABEL) && defined(VER_EXTRA_VALUE) VALUE VER_EXTRA_LABEL, VER_EXTRA_VALUE #endif #ifdef VER_COMMENT VALUE "Comment", VER_COMMENT #endif #ifdef VER_USERNAME VALUE "Built By", VER_USERNAME #endif #ifdef VER_HOSTNAME VALUE "Build Host", VER_HOSTNAME #endif #ifdef VER_DATE VALUE "Build Time", VER_DATE #endif #ifdef VER_VENDOR VALUE "Modified by Vendor", VER_VENDOR #endif VALUE "CompanyName", K5_COMPANY_NAME VALUE "FileDescription", K5_DESCRIPTION VALUE "FileVersion", K5_PRODUCT_VERSION_STRING VALUE "InternalName", K5_INTERNAL_NAME #ifdef VER_LEGALTRADEMARK_STR VALUE VER_LEGALTRADEMARK_STR #else VALUE "LegalTrademarks", "\0" #endif VALUE "OriginalFilename", K5_ORIGINAL_NAME VALUE "ProductName", K5_ORIGINAL_NAME VALUE "ProductVersion", K5_PRODUCT_VERSION_STRING VALUE "LegalCopyright", K5_COPYRIGHT #ifdef VER_SPECIALBUILD VALUE "SpecialBuild", VER_SPECIALBUILD #endif END END END krb5-1.16/src/windows/build/0000755000704600001450000000000013211554426015556 5ustar ghudsonlibuuidkrb5-1.16/src/windows/build/zipXML.pl0000644000704600001450000000074413211554426017303 0ustar ghudsonlibuuid#!perl -w #use strict; require "makeZip.pl"; use Data::Dumper; sub zipXML { local ($xml, $config) = @_; my $zipsXML = $xml->{Zips}; if (! $zipsXML) {return 0;} local $i = 0; while ($zipsXML->{Zip}[$i]) { local $zip = $zipsXML->{Zip}[$i]; makeZip($zip, $config) if (exists $zip->{name}); ## Ignore dummy entry. $i++; } ## End zip in xml. } return 1; krb5-1.16/src/windows/build/css/0000755000704600001450000000000013211554426016346 5ustar ghudsonlibuuidkrb5-1.16/src/windows/build/css/main-action.css0000644000704600001450000011332213211554426021261 0ustar ghudsonlibuuidBODY { FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: #000000; LINE-HEIGHT: 16px; FONT-FAMILY: Verdana, arial, sans-serif } P { FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: #000000; LINE-HEIGHT: 16px; FONT-FAMILY: Verdana, arial, sans-serif } TD { FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: #000000; LINE-HEIGHT: 16px; FONT-FAMILY: Verdana, arial, sans-serif } TABLE { FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: #000000; LINE-HEIGHT: 16px; FONT-FAMILY: Verdana, arial, sans-serif } TR { FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: #000000; LINE-HEIGHT: 16px; FONT-FAMILY: Verdana, arial, sans-serif } .bodytext { FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: #000000; LINE-HEIGHT: 16px; FONT-FAMILY: Verdana, arial, sans-serif } .stepfield { FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: #000000; LINE-HEIGHT: 16px; FONT-FAMILY: Verdana, arial, sans-serif } #PageContent { PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 20px; MARGIN: 0px; PADDING-TOP: 0px; BACKGROUND-COLOR: #fff; TEXT-ALIGN: left } BODY { PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 0px; MARGIN: 0px; PADDING-TOP: 0px; BACKGROUND-COLOR: #ffffff; TEXT-ALIGN: center } .monospaceInput { FONT: 12px monospace } .wiki-content P { PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 0px; MARGIN: 16px 0px; PADDING-TOP: 0px } .commentblock P { PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 0px; MARGIN: 16px 0px; PADDING-TOP: 0px } .wiki-content-preview { BORDER-RIGHT: #3c78b5 1px solid; PADDING-RIGHT: 5px; PADDING-LEFT: 5px; PADDING-BOTTOM: 5px; BORDER-LEFT: #3c78b5 1px solid; PADDING-TOP: 5px } UL { MARGIN-TOP: 2px; MARGIN-BOTTOM: 2px; PADDING-BOTTOM: 0px; PADDING-TOP: 0px } OL { MARGIN-TOP: 2px; MARGIN-BOTTOM: 2px; PADDING-BOTTOM: 0px; PADDING-TOP: 0px } PRE { PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 0px; MARGIN: 5px 5px 5px 15px; PADDING-TOP: 0px; TEXT-ALIGN: left } .helpheading { PADDING-RIGHT: 4px; PADDING-LEFT: 4px; FONT-WEIGHT: bold; PADDING-BOTTOM: 4px; MARGIN: 10px 0px 0px; PADDING-TOP: 4px; BORDER-BOTTOM: #3c78b5 1px solid; BACKGROUND-COLOR: #d0d9bd } .helpcontent { PADDING-RIGHT: 4px; PADDING-LEFT: 4px; PADDING-BOTTOM: 20px; PADDING-TOP: 4px; BACKGROUND-COLOR: #f5f7f1 } .code { BORDER-RIGHT: #3c78b5 1px dashed; BORDER-TOP: #3c78b5 1px dashed; FONT-SIZE: 11px; MARGIN: 10px; BORDER-LEFT: #3c78b5 1px dashed; LINE-HEIGHT: 13px; BORDER-BOTTOM: #3c78b5 1px dashed; FONT-FAMILY: Courier } .focusedComment { BACKGROUND: #ffffce } .commentBox { BORDER-RIGHT: #bbb 1px solid; PADDING-RIGHT: 10px; BORDER-TOP: #bbb 1px solid; PADDING-LEFT: 10px; PADDING-BOTTOM: 10px; MARGIN: 5px 0px; BORDER-LEFT: #bbb 1px solid; PADDING-TOP: 10px; BORDER-BOTTOM: #bbb 1px solid } .focusedComment { BORDER-RIGHT: #bbb 1px solid; PADDING-RIGHT: 10px; BORDER-TOP: #bbb 1px solid; PADDING-LEFT: 10px; PADDING-BOTTOM: 10px; MARGIN: 5px 0px; BORDER-LEFT: #bbb 1px solid; PADDING-TOP: 10px; BORDER-BOTTOM: #bbb 1px solid } .codeHeader { PADDING-RIGHT: 3px; PADDING-LEFT: 3px; PADDING-BOTTOM: 3px; PADDING-TOP: 3px; BORDER-BOTTOM: #3c78b5 1px dashed; BACKGROUND-COLOR: #eeefcc; TEXT-ALIGN: center } .codeContent { PADDING-RIGHT: 3px; PADDING-LEFT: 3px; PADDING-BOTTOM: 3px; PADDING-TOP: 3px; BACKGROUND-COLOR: #eeefcc; TEXT-ALIGN: left } .preformatted { BORDER-RIGHT: #3c78b5 1px dashed; BORDER-TOP: #3c78b5 1px dashed; FONT-SIZE: 11px; MARGIN: 10px; BORDER-LEFT: #3c78b5 1px dashed; LINE-HEIGHT: 13px; BORDER-BOTTOM: #3c78b5 1px dashed; FONT-FAMILY: Courier } .preformattedHeader { PADDING-RIGHT: 3px; PADDING-LEFT: 3px; PADDING-BOTTOM: 3px; PADDING-TOP: 3px; BORDER-BOTTOM: #3c78b5 1px dashed; BACKGROUND-COLOR: #eeefcc; TEXT-ALIGN: center } .preformattedContent { PADDING-RIGHT: 3px; PADDING-LEFT: 3px; PADDING-BOTTOM: 3px; PADDING-TOP: 3px; BACKGROUND-COLOR: #eeefcc } .panel { BORDER-RIGHT: #3c78b5 1px dashed; BORDER-TOP: #3c78b5 1px dashed; MARGIN: 0px 10px 10px; BORDER-LEFT: #3c78b5 1px dashed; BORDER-BOTTOM: #3c78b5 1px dashed } .panelHeader { PADDING-RIGHT: 3px; PADDING-LEFT: 3px; PADDING-BOTTOM: 3px; PADDING-TOP: 3px; BORDER-BOTTOM: #3c78b5 1px dashed; BACKGROUND-COLOR: #eeefcc; TEXT-ALIGN: center } .panelContent { PADDING-RIGHT: 5px; PADDING-LEFT: 5px; PADDING-BOTTOM: 5px; PADDING-TOP: 5px; BACKGROUND-COLOR: #eeefcc } .anonymousAlert { BORDER-RIGHT: red 1px dashed; PADDING-RIGHT: 5px; BORDER-TOP: red 1px dashed; PADDING-LEFT: 5px; FONT-SIZE: 11px; PADDING-BOTTOM: 10px; MARGIN: 4px; BORDER-LEFT: red 1px dashed; LINE-HEIGHT: 13px; PADDING-TOP: 10px; BORDER-BOTTOM: red 1px dashed; BACKGROUND-COLOR: #eeefcc } .lockAlert { BORDER-RIGHT: red 1px dashed; PADDING-RIGHT: 5px; BORDER-TOP: red 1px dashed; PADDING-LEFT: 5px; FONT-SIZE: 11px; PADDING-BOTTOM: 10px; MARGIN: 4px; BORDER-LEFT: red 1px dashed; WIDTH: 50%; LINE-HEIGHT: 13px; PADDING-TOP: 10px; BORDER-BOTTOM: red 1px dashed; BACKGROUND-COLOR: #eeefcc } .code-keyword { COLOR: #000091 } .code-object { COLOR: #910091 } .code-quote { COLOR: #009100 } .code-comment { COLOR: #808080 } .code-xml .code-keyword { FONT-WEIGHT: bold } .code-tag { COLOR: #000091 } .breadcrumbs { BORDER-RIGHT: #3c78b5 0px solid; PADDING-RIGHT: 0px; BORDER-TOP: #3c78b5 1px solid; PADDING-LEFT: 0px; FONT-SIZE: 11px; PADDING-BOTTOM: 3px; BORDER-LEFT: #3c78b5 0px solid; PADDING-TOP: 3px; BORDER-BOTTOM: #3c78b5 1px solid; BACKGROUND-COLOR: #eeefcc } .navmenu { BORDER-RIGHT: #ccc 1px solid; BORDER-TOP: #ccc 1px solid; BORDER-LEFT: #ccc 1px solid; BORDER-BOTTOM: #ccc 1px solid } .menuheading { PADDING-RIGHT: 4px; PADDING-LEFT: 4px; FONT-WEIGHT: bold; PADDING-BOTTOM: 2px; PADDING-TOP: 4px; BORDER-BOTTOM: #3c78b5 1px solid; BACKGROUND-COLOR: #eeefcc } .menuitems { PADDING-RIGHT: 4px; PADDING-LEFT: 4px; PADDING-BOTTOM: 20px; PADDING-TOP: 4px } .rightpanel { BORDER-LEFT: #ccc 1px solid; BORDER-BOTTOM: #ccc 1px solid } #helpheading { PADDING-RIGHT: 4px; PADDING-LEFT: 4px; FONT-WEIGHT: bold; PADDING-BOTTOM: 4px; MARGIN: 0px; PADDING-TOP: 4px; BORDER-BOTTOM: #3c78b5 1px solid; BACKGROUND-COLOR: #d0d9bd; TEXT-ALIGN: left } #helpcontent { PADDING-RIGHT: 4px; PADDING-LEFT: 4px; PADDING-BOTTOM: 4px; PADDING-TOP: 4px; BACKGROUND-COLOR: #f5f7f1 } .helptab-unselected { PADDING-RIGHT: 5px; PADDING-LEFT: 5px; FONT-WEIGHT: bold; PADDING-BOTTOM: 5px; PADDING-TOP: 5px; BACKGROUND-COLOR: #f5f7f1 } .helptab-selected { PADDING-RIGHT: 5px; PADDING-LEFT: 5px; FONT-WEIGHT: bold; PADDING-BOTTOM: 5px; PADDING-TOP: 5px; BACKGROUND-COLOR: #d0d9bd } .helptabs { PADDING-RIGHT: 5px; PADDING-LEFT: 5px; PADDING-BOTTOM: 5px; MARGIN: 0px; PADDING-TOP: 5px; BACKGROUND-COLOR: #f5f7f1 } .infopanel-heading { PADDING-RIGHT: 0px; PADDING-LEFT: 0px; FONT-WEIGHT: bold; PADDING-BOTTOM: 2px; PADDING-TOP: 4px } .pagebody { } .pageheader { PADDING-RIGHT: 5px; PADDING-LEFT: 0px; PADDING-BOTTOM: 5px; PADDING-TOP: 5px; BORDER-BOTTOM: #3c78b5 1px solid } .pagetitle { FONT-WEIGHT: bold; FONT-SIZE: 22px; COLOR: #003366; FONT-FAMILY: Arial, sans-serif } .newpagetitle { COLOR: #ccc! important } .steptitle { FONT-WEIGHT: bold; FONT-SIZE: 18px; MARGIN-BOTTOM: 7px; COLOR: #003366; FONT-FAMILY: Arial, sans-serif } .substeptitle { PADDING-RIGHT: 4px; PADDING-LEFT: 4px; FONT-WEIGHT: bold; FONT-SIZE: 12px; PADDING-BOTTOM: 1px; MARGIN: 2px 4px 4px; COLOR: #003366; PADDING-TOP: 2px; FONT-FAMILY: Arial, sans-serif } .stepdesc { MARGIN-TOP: 7px; FONT-WEIGHT: normal; FONT-SIZE: 11px; MARGIN-BOTTOM: 7px; COLOR: #666666; LINE-HEIGHT: 16px; FONT-FAMILY: Verdana, arial, sans-serif } .steplabel { FONT-WEIGHT: bold; FLOAT: left; WIDTH: 15%; COLOR: black; MARGIN-RIGHT: 4px; TEXT-ALIGN: right } .stepfield { PADDING-RIGHT: 5px; PADDING-LEFT: 5px; BACKGROUND: #eeefcc; PADDING-BOTTOM: 5px; PADDING-TOP: 5px } .submitButtons { MARGIN-TOP: 5px; TEXT-ALIGN: right } .formtitle { FONT-WEIGHT: bold; FONT-SIZE: 12px; COLOR: #003366; FONT-FAMILY: Arial, sans-serif } .sectionbottom { BORDER-BOTTOM: #3c78b5 1px solid } .topRow { BORDER-TOP: #3c78b5 2px solid } .tabletitle { PADDING-RIGHT: 0px; PADDING-LEFT: 0px; FONT-WEIGHT: bold; FONT-SIZE: 14px; PADDING-BOTTOM: 2px; MARGIN: 8px 4px 2px 0px; COLOR: #003366; PADDING-TOP: 3px; BORDER-BOTTOM: #3c78b5 2px solid; FONT-FAMILY: Arial, sans-serif } .pagesubheading { PADDING-RIGHT: 0px; PADDING-LEFT: 0px; FONT-SIZE: 10px; PADDING-BOTTOM: 5px; COLOR: #666666; PADDING-TOP: 0px } HR { } A:link { COLOR: #003366 } A:visited { COLOR: #003366 } A:active { COLOR: #003366 } A:hover { COLOR: #003366 } H1 A:link { TEXT-DECORATION: none } H1 A:visited { TEXT-DECORATION: none } H1 A:active { TEXT-DECORATION: none } H1 A:hover { BORDER-BOTTOM: #003366 1px dotted } UNKNOWN { MARGIN-TOP: 3px } .logocell { PADDING-RIGHT: 10px; PADDING-LEFT: 10px; PADDING-BOTTOM: 10px; PADDING-TOP: 10px } INPUT { FONT-SIZE: 11px; COLOR: #000000; FONT-FAMILY: verdana, geneva, arial, sans-serif } TEXTAREA { FONT-SIZE: 11px; COLOR: #333333; FONT-FAMILY: verdana, geneva, arial, sans-serif } TEXTAREA.editor { FONT-SIZE: 11px; COLOR: #333333; FONT-FAMILY: verdana, geneva, arial, sans-serif } .spacenametitle-printable { MARGIN: 0px; FONT: 100 20px/25px Impact, Arial, Helvetica; COLOR: #999999 } .spacenametitle-printable A { COLOR: #999999; TEXT-DECORATION: none } .spacenametitle-printable A:visited { COLOR: #999999; TEXT-DECORATION: none } .blogDate { FONT-WEIGHT: bold; COLOR: black; TEXT-DECORATION: none } .blogSurtitle { BORDER-RIGHT: #ddd 1px solid; PADDING-RIGHT: 3px; BORDER-TOP: #ddd 1px solid; PADDING-LEFT: 3px; BACKGROUND: #eeefcc; PADDING-BOTTOM: 3px; MARGIN: 1px 1px 10px; BORDER-LEFT: #ddd 1px solid; PADDING-TOP: 3px; BORDER-BOTTOM: #ddd 1px solid } .blogHeading { PADDING-RIGHT: 0px; PADDING-LEFT: 0px; FONT-WEIGHT: bold; FONT-SIZE: 20px; PADDING-BOTTOM: 0px; MARGIN: 0px; LINE-HEIGHT: normal; PADDING-TOP: 0px } .blogHeading A { COLOR: black; TEXT-DECORATION: none } .endsection { MARGIN-TOP: 10px; COLOR: #666666; align: right } .endsectionleftnav { MARGIN-TOP: 10px; COLOR: #666666; align: right } H1 { PADDING-RIGHT: 2px; PADDING-LEFT: 2px; FONT-WEIGHT: bold; FONT-SIZE: 24px; PADDING-BOTTOM: 2px; MARGIN: 36px 0px 4px; COLOR: #003366; LINE-HEIGHT: normal; PADDING-TOP: 2px; BORDER-BOTTOM: #3c78b5 1px solid; BACKGROUND-COLOR: #eeefcc } H2 { PADDING-RIGHT: 2px; PADDING-LEFT: 2px; FONT-WEIGHT: bold; FONT-SIZE: 18px; PADDING-BOTTOM: 2px; MARGIN: 27px 0px 4px; LINE-HEIGHT: normal; PADDING-TOP: 2px; BORDER-BOTTOM: #3c78b5 1px solid; BACKGROUND-COLOR: #eeefcc } H3 { PADDING-RIGHT: 2px; PADDING-LEFT: 2px; FONT-WEIGHT: bold; FONT-SIZE: 14px; PADDING-BOTTOM: 2px; MARGIN: 21px 0px 4px; LINE-HEIGHT: normal; PADDING-TOP: 2px; BACKGROUND-COLOR: #eeefcc } H4 { PADDING-RIGHT: 2px; PADDING-LEFT: 2px; FONT-WEIGHT: bold; FONT-SIZE: 12px; PADDING-BOTTOM: 2px; MARGIN: 18px 0px 4px; LINE-HEIGHT: normal; PADDING-TOP: 2px; BACKGROUND-COLOR: #eeefcc } H4.search { PADDING-RIGHT: 4px; PADDING-LEFT: 4px; FONT-WEIGHT: normal; FONT-SIZE: 12px; PADDING-BOTTOM: 4px; MARGIN: 18px 0px 4px; LINE-HEIGHT: normal; PADDING-TOP: 4px; BACKGROUND-COLOR: #eeefcc } H5 { PADDING-RIGHT: 2px; PADDING-LEFT: 2px; FONT-WEIGHT: bold; FONT-SIZE: 10px; PADDING-BOTTOM: 2px; MARGIN: 14px 0px 4px; LINE-HEIGHT: normal; PADDING-TOP: 2px; BACKGROUND-COLOR: #eeefcc } H6 { PADDING-RIGHT: 2px; PADDING-LEFT: 2px; FONT-WEIGHT: bold; FONT-SIZE: 8px; PADDING-BOTTOM: 2px; MARGIN: 14px 0px 4px; LINE-HEIGHT: normal; PADDING-TOP: 2px; BACKGROUND-COLOR: #eeefcc } .smallfont { FONT-SIZE: 10px } .descfont { FONT-SIZE: 10px; COLOR: #666666 } .smallerfont { FONT-SIZE: 9px } .smalltext { FONT-SIZE: 10px; COLOR: #666666 } .smalltext A { COLOR: #666666 } .smalltext-blue { FONT-SIZE: 10px; COLOR: #3c78b5 } .surtitle { FONT-SIZE: 14px; MARGIN-BOTTOM: 5px; MARGIN-LEFT: 1px; COLOR: #666666 } .navItemOver { FONT-WEIGHT: bold; FONT-SIZE: 10px; CURSOR: pointer; COLOR: #ffffff; BACKGROUND-COLOR: #003366; voice-family: inherit } .navItemOver A { COLOR: #ffffff; BACKGROUND-COLOR: #003366; TEXT-DECORATION: none } .navItemOver A:visited { COLOR: #ffffff; BACKGROUND-COLOR: #003366; TEXT-DECORATION: none } .navItemOver A:hover { COLOR: #ffffff; BACKGROUND-COLOR: #003366; TEXT-DECORATION: none } .navItem { FONT-WEIGHT: bold; FONT-SIZE: 10px; COLOR: #ffffff; BACKGROUND-COLOR: #3c78b5 } .navItem A { COLOR: #ffffff; TEXT-DECORATION: none } .navItem A:hover { COLOR: #ffffff; TEXT-DECORATION: none } .navItem A:visited { COLOR: #ffffff; TEXT-DECORATION: none } DIV.padded { PADDING-RIGHT: 4px; PADDING-LEFT: 4px; PADDING-BOTTOM: 4px; PADDING-TOP: 4px } DIV.thickPadded { PADDING-RIGHT: 10px; PADDING-LEFT: 10px; PADDING-BOTTOM: 10px; PADDING-TOP: 10px } H3.macrolibrariestitle { MARGIN: 0px } DIV.centered { MARGIN: 10px; TEXT-ALIGN: center } DIV.centered TABLE { MARGIN: 0px auto; TEXT-ALIGN: left } .tableview TABLE { MARGIN: 0px } .tableview TH { PADDING-RIGHT: 0px; PADDING-LEFT: 5px; FONT-SIZE: 12px; PADDING-BOTTOM: 0px; COLOR: #003366; PADDING-TOP: 5px; BORDER-BOTTOM: #3c78b5 2px solid; TEXT-ALIGN: left } .tableview TD { BORDER-RIGHT: #ccc 0px solid; PADDING-RIGHT: 10px; BORDER-TOP: #ccc 0px solid; PADDING-LEFT: 5px; PADDING-BOTTOM: 4px; MARGIN: 0px; BORDER-LEFT: #ccc 0px solid; PADDING-TOP: 4px; BORDER-BOTTOM: #ccc 1px solid; TEXT-ALIGN: left } .grid { MARGIN: 2px 0px 5px; BORDER-COLLAPSE: collapse } .grid TH { BORDER-RIGHT: #ccc 1px solid; PADDING-RIGHT: 4px; BORDER-TOP: #ccc 1px solid; PADDING-LEFT: 4px; BACKGROUND: #eeefcc; PADDING-BOTTOM: 2px; BORDER-LEFT: #ccc 1px solid; PADDING-TOP: 2px; BORDER-BOTTOM: #ccc 1px solid; TEXT-ALIGN: center } .grid TD { BORDER-RIGHT: #ccc 1px solid; PADDING-RIGHT: 4px; BORDER-TOP: #ccc 1px solid; PADDING-LEFT: 4px; PADDING-BOTTOM: 3px; BORDER-LEFT: #ccc 1px solid; PADDING-TOP: 3px; BORDER-BOTTOM: #ccc 1px solid } .gridHover { BACKGROUND-COLOR: #f9f9f9 } TD.infocell { BACKGROUND-COLOR: #eeefcc } .label { FONT-WEIGHT: bold; COLOR: #003366 } LABEL { FONT-WEIGHT: bold; COLOR: #003366 } .error { BACKGROUND-COLOR: #fcc } .errorBox { BORDER-RIGHT: #c00 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #c00 1px solid; PADDING-LEFT: 5px; PADDING-BOTTOM: 5px; MARGIN: 5px; BORDER-LEFT: #c00 1px solid; PADDING-TOP: 5px; BORDER-BOTTOM: #c00 1px solid; BACKGROUND-COLOR: #fcc } .errorMessage { COLOR: #c00 } .success { BACKGROUND-COLOR: #dfd } .successBox { BORDER-RIGHT: #090 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #090 1px solid; MARGIN-TOP: 5px; PADDING-LEFT: 5px; MARGIN-BOTTOM: 5px; PADDING-BOTTOM: 5px; BORDER-LEFT: #090 1px solid; PADDING-TOP: 5px; BORDER-BOTTOM: #090 1px solid; BACKGROUND-COLOR: #dfd } BLOCKQUOTE { PADDING-RIGHT: 10px; PADDING-LEFT: 10px; MARGIN-LEFT: 5px; BORDER-LEFT: #3c78b5 1px solid; MARGIN-RIGHT: 0px } TABLE.confluenceTable { MARGIN: 5px; BORDER-COLLAPSE: collapse } TABLE.confluenceTable TD.confluenceTd { BORDER-RIGHT: #ccc 1px solid; PADDING-RIGHT: 4px; BORDER-TOP: #ccc 1px solid; PADDING-LEFT: 4px; PADDING-BOTTOM: 3px; BORDER-LEFT: #ccc 1px solid; PADDING-TOP: 3px; BORDER-BOTTOM: #ccc 1px solid } TABLE.confluenceTable TH.confluenceTh { BORDER-RIGHT: #ccc 1px solid; PADDING-RIGHT: 4px; BORDER-TOP: #ccc 1px solid; PADDING-LEFT: 4px; PADDING-BOTTOM: 3px; BORDER-LEFT: #ccc 1px solid; PADDING-TOP: 3px; BORDER-BOTTOM: #ccc 1px solid; BACKGROUND-COLOR: #eeefcc; TEXT-ALIGN: center } TD.confluenceTd { BORDER-RIGHT: #ccc 1px solid; PADDING-RIGHT: 4px; BORDER-TOP: #ccc 1px solid; PADDING-LEFT: 4px; PADDING-BOTTOM: 3px; BORDER-LEFT: #ccc 1px solid; PADDING-TOP: 3px; BORDER-BOTTOM: #ccc 1px solid } TH.confluenceTh { BORDER-RIGHT: #ccc 1px solid; PADDING-RIGHT: 4px; BORDER-TOP: #ccc 1px solid; PADDING-LEFT: 4px; PADDING-BOTTOM: 3px; BORDER-LEFT: #ccc 1px solid; PADDING-TOP: 3px; BORDER-BOTTOM: #ccc 1px solid; BACKGROUND-COLOR: #eeefcc; TEXT-ALIGN: center } DIV.small { FONT-SIZE: 9px } H1.pagename { MARGIN-TOP: 0px } IMG.inline { } .loginform { BORDER-RIGHT: #ccc 1px solid; BORDER-TOP: #ccc 1px solid; MARGIN: 5px; BORDER-LEFT: #ccc 1px solid; BORDER-BOTTOM: #ccc 1px solid } .previewnote { FONT-SIZE: 11px; COLOR: red; TEXT-ALIGN: center } .previewcontent { BACKGROUND: #e0e0e0 } .messagecontent { BACKGROUND: #e0e0e0 } .conflictnote { } .createlink { COLOR: maroon } A.createlink { COLOR: maroon } .templateparameter { FONT-SIZE: 9px; COLOR: darkblue } .diffadded { PADDING-RIGHT: 1px; PADDING-LEFT: 4px; BACKGROUND: #ddffdd; PADDING-BOTTOM: 1px; BORDER-LEFT: darkgreen 4px solid; PADDING-TOP: 1px } .diffdeleted { PADDING-RIGHT: 1px; PADDING-LEFT: 4px; BACKGROUND: #ffdddd; PADDING-BOTTOM: 1px; BORDER-LEFT: darkred 4px solid; COLOR: #999; PADDING-TOP: 1px } .diffnochange { PADDING-RIGHT: 1px; PADDING-LEFT: 4px; PADDING-BOTTOM: 1px; BORDER-LEFT: lightgrey 4px solid; PADDING-TOP: 1px } .differror { BACKGROUND: brown } .diff { FONT-SIZE: 12px; LINE-HEIGHT: 14px; FONT-FAMILY: lucida console, courier new, fixed-width } .diffaddedchars { FONT-WEIGHT: bolder; BACKGROUND-COLOR: #99ff99 } .diffremovedchars { FONT-WEIGHT: bolder; BACKGROUND-COLOR: #ff9999; TEXT-DECORATION: line-through } .greybackground { BACKGROUND: #eeefcc } .greybox { BORDER-RIGHT: #ddd 1px solid; PADDING-RIGHT: 3px; BORDER-TOP: #ddd 1px solid; PADDING-LEFT: 3px; PADDING-BOTTOM: 3px; MARGIN: 1px 1px 10px; BORDER-LEFT: #ddd 1px solid; PADDING-TOP: 3px; BORDER-BOTTOM: #ddd 1px solid } .borderedGreyBox { BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 10px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 10px; PADDING-BOTTOM: 10px; BORDER-LEFT: #cccccc 1px solid; PADDING-TOP: 10px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeefcc } .greyboxfilled { BORDER-RIGHT: #ddd 1px solid; PADDING-RIGHT: 3px; BORDER-TOP: #ddd 1px solid; PADDING-LEFT: 3px; BACKGROUND: #eeefcc; PADDING-BOTTOM: 3px; MARGIN: 1px 1px 10px; BORDER-LEFT: #ddd 1px solid; PADDING-TOP: 3px; BORDER-BOTTOM: #ddd 1px solid } .navBackgroundBox { PADDING-RIGHT: 5px; PADDING-LEFT: 5px; FONT-WEIGHT: bold; FONT-SIZE: 22px; BACKGROUND: #3c78b5; PADDING-BOTTOM: 5px; COLOR: white; PADDING-TOP: 5px; FONT-FAMILY: Arial, sans-serif; TEXT-DECORATION: none } .previewBoxTop { BORDER-RIGHT: #3c78b5 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #3c78b5 1px solid; PADDING-LEFT: 5px; PADDING-BOTTOM: 5px; MARGIN: 5px 0px 0px; BORDER-LEFT: #3c78b5 1px solid; PADDING-TOP: 5px; BORDER-BOTTOM: #3c78b5 0px solid; BACKGROUND-COLOR: #eeefcc; TEXT-ALIGN: center } .previewContent { BORDER-RIGHT: #3c78b5 1px solid; PADDING-RIGHT: 10px; BORDER-TOP: #3c78b5 0px solid; PADDING-LEFT: 10px; PADDING-BOTTOM: 10px; MARGIN: 0px; BORDER-LEFT: #3c78b5 1px solid; PADDING-TOP: 10px; BORDER-BOTTOM: #3c78b5 0px solid; BACKGROUND-COLOR: #fff } .previewBoxBottom { BORDER-RIGHT: #3c78b5 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #3c78b5 0px solid; PADDING-LEFT: 5px; PADDING-BOTTOM: 5px; MARGIN: 0px 0px 5px; BORDER-LEFT: #3c78b5 1px solid; PADDING-TOP: 5px; BORDER-BOTTOM: #3c78b5 1px solid; BACKGROUND-COLOR: #eeefcc; TEXT-ALIGN: center } .functionbox { BORDER-RIGHT: #3c78b5 1px solid; PADDING-RIGHT: 3px; BORDER-TOP: #3c78b5 1px solid; PADDING-LEFT: 3px; PADDING-BOTTOM: 3px; MARGIN: 1px 1px 10px; BORDER-LEFT: #3c78b5 1px solid; PADDING-TOP: 3px; BORDER-BOTTOM: #3c78b5 1px solid; BACKGROUND-COLOR: #eeefcc } .functionbox-greyborder { BORDER-RIGHT: #ddd 1px solid; PADDING-RIGHT: 3px; BORDER-TOP: #ddd 1px solid; PADDING-LEFT: 3px; PADDING-BOTTOM: 3px; MARGIN: 1px 1px 10px; BORDER-LEFT: #ddd 1px solid; PADDING-TOP: 3px; BORDER-BOTTOM: #ddd 1px solid; BACKGROUND-COLOR: #eeefcc } .search-highlight { BACKGROUND-COLOR: #ffffcc } .rowNormal { BACKGROUND-COLOR: #ffffff } .rowAlternate { BACKGROUND-COLOR: #f7f7f7 } .rowAlternateNoBottomColor { BACKGROUND-COLOR: #f7f7f7 } .rowAlternateNoBottomNoColor { } .rowAlternateNoBottomColor TD { BORDER-BOTTOM-WIDTH: 0px } .rowAlternateNoBottomNoColor TD { BORDER-BOTTOM-WIDTH: 0px } .rowHighlight { BACKGROUND-COLOR: #eeefcc } TD.greenbar { BORDER-RIGHT: #9c9c9c 1px solid; PADDING-RIGHT: 0px; BORDER-TOP: #9c9c9c 1px solid; PADDING-LEFT: 0px; FONT-SIZE: 2px; BACKGROUND: #00df00; PADDING-BOTTOM: 0px; BORDER-LEFT: #9c9c9c 1px solid; PADDING-TOP: 0px; BORDER-BOTTOM: #9c9c9c 1px solid } TD.redbar { BORDER-RIGHT: #9c9c9c 1px solid; PADDING-RIGHT: 0px; BORDER-TOP: #9c9c9c 1px solid; PADDING-LEFT: 0px; FONT-SIZE: 2px; BACKGROUND: #df0000; PADDING-BOTTOM: 0px; BORDER-LEFT: #9c9c9c 1px solid; PADDING-TOP: 0px; BORDER-BOTTOM: #9c9c9c 1px solid } TD.darkredbar { BORDER-RIGHT: #9c9c9c 1px solid; PADDING-RIGHT: 0px; BORDER-TOP: #9c9c9c 1px solid; PADDING-LEFT: 0px; FONT-SIZE: 2px; BACKGROUND: #af0000; PADDING-BOTTOM: 0px; BORDER-LEFT: #9c9c9c 1px solid; PADDING-TOP: 0px; BORDER-BOTTOM: #9c9c9c 1px solid } TR.testpassed { PADDING-RIGHT: 0px; PADDING-LEFT: 0px; FONT-SIZE: 2px; BACKGROUND: #ddffdd; PADDING-BOTTOM: 0px; PADDING-TOP: 0px } TR.testfailed { PADDING-RIGHT: 0px; PADDING-LEFT: 0px; FONT-SIZE: 2px; BACKGROUND: #ffdddd; PADDING-BOTTOM: 0px; PADDING-TOP: 0px } .toolbar { MARGIN: 0px; BORDER-COLLAPSE: collapse } .toolbar TD { BORDER-RIGHT: #ccc 1px solid; PADDING-RIGHT: 2px; BORDER-TOP: #ccc 1px solid; PADDING-LEFT: 2px; PADDING-BOTTOM: 2px; BORDER-LEFT: #ccc 1px solid; COLOR: #ccc; PADDING-TOP: 2px; BORDER-BOTTOM: #ccc 1px solid } TD.noformatting { BORDER-RIGHT: 0px; PADDING-RIGHT: 0px; BORDER-TOP: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 0px; BORDER-LEFT: 0px; PADDING-TOP: 0px; BORDER-BOTTOM: 0px; TEXT-ALIGN: center } .commentblock { MARGIN: 12px 0px } .license-eval { BORDER-TOP: #bbbbbb 1px solid; FONT-SIZE: 10px; FONT-FAMILY: Verdana, Arial, Helvetica, sans-serif; TEXT-ALIGN: center } .license-none { BORDER-TOP: #bbbbbb 1px solid; FONT-SIZE: 10px; FONT-FAMILY: Verdana, Arial, Helvetica, sans-serif; TEXT-ALIGN: center } .license-nonprofit { BORDER-TOP: #bbbbbb 1px solid; FONT-SIZE: 10px; FONT-FAMILY: Verdana, Arial, Helvetica, sans-serif; TEXT-ALIGN: center } .license-eval { BACKGROUND-COLOR: #ffcccc } .license-none { BACKGROUND-COLOR: #ffcccc } .license-eval B { COLOR: #990000 } .license-none B { COLOR: #990000 } .license-nonprofit { BACKGROUND-COLOR: #ffffff } .bottomshadow { BACKGROUND-IMAGE: url(/confluence/images/border/border_bottom.gif); BACKGROUND-REPEAT: repeat-x; HEIGHT: 12px } .navmenu .operations LI { PADDING-LEFT: 0px; MARGIN-LEFT: 0px; LIST-STYLE-TYPE: none } .navmenu .operations UL { PADDING-LEFT: 0px; MARGIN-LEFT: 0px; LIST-STYLE-TYPE: none } .navmenu .operations UL { MARGIN-BOTTOM: 9px } .navmenu .label { } .toolbar DIV { DISPLAY: none } .toolbar .label { DISPLAY: none } .toolbar .operations { DISPLAY: block } .toolbar .operations UL { DISPLAY: inline; PADDING-LEFT: 0px; MARGIN-LEFT: 10px; LIST-STYLE-TYPE: none } .toolbar .operations LI { DISPLAY: inline; LIST-STYLE-TYPE: none } #foldertab { PADDING-RIGHT: 0px; PADDING-LEFT: 8px; PADDING-BOTTOM: 3px; FONT: bold 11px Verdana, sans-serif; MARGIN-LEFT: 0px; PADDING-TOP: 3px; BORDER-BOTTOM: #3c78b5 1px solid } #foldertab LI { DISPLAY: inline; MARGIN: 0px; LIST-STYLE-TYPE: none } #foldertab LI A { BORDER-RIGHT: #3c78b5 1px solid; PADDING-RIGHT: 0.5em; BORDER-TOP: #3c78b5 1px solid; PADDING-LEFT: 0.5em; BACKGROUND: #3c78b5; PADDING-BOTTOM: 3px; MARGIN-LEFT: 3px; BORDER-LEFT: #3c78b5 1px solid; PADDING-TOP: 3px; BORDER-BOTTOM: #3c78b5 1px; TEXT-DECORATION: none } #foldertab LI A:link { COLOR: #ffffff } #foldertab LI A:visited { COLOR: #ffffff } #foldertab LI A:hover { BORDER-LEFT-COLOR: #003366; BACKGROUND: #003366; BORDER-BOTTOM-COLOR: #003366; COLOR: #ffffff; BORDER-TOP-COLOR: #003366; BORDER-RIGHT-COLOR: #003366 } #foldertab LI A.current { BACKGROUND: white; COLOR: black; BORDER-BOTTOM: white 1px solid } #foldertab LI A.current:link { COLOR: black } #foldertab LI A.current:visited { COLOR: black } #foldertab LI A.current:hover { BACKGROUND: white; COLOR: black; BORDER-BOTTOM: white 1px solid } UL#squaretab { PADDING-LEFT: 0px; FONT: bold 8px Verdana, sans-serif; MARGIN-LEFT: 0px; WHITE-SPACE: nowrap } #squaretab LI { DISPLAY: inline; LIST-STYLE-TYPE: none } #squaretab A { BORDER-RIGHT: #3c78b5 1px solid; PADDING-RIGHT: 6px; BORDER-TOP: #3c78b5 1px solid; PADDING-LEFT: 6px; PADDING-BOTTOM: 2px; BORDER-LEFT: #3c78b5 1px solid; PADDING-TOP: 2px; BORDER-BOTTOM: #3c78b5 1px solid } #squaretab A:link { COLOR: #fff; BACKGROUND-COLOR: #3c78b5; TEXT-DECORATION: none } #squaretab A:visited { COLOR: #fff; BACKGROUND-COLOR: #3c78b5; TEXT-DECORATION: none } #squaretab A:hover { BORDER-LEFT-COLOR: #003366; BORDER-BOTTOM-COLOR: #003366; COLOR: #ffffff; BORDER-TOP-COLOR: #003366; BACKGROUND-COLOR: #003366; TEXT-DECORATION: none; BORDER-RIGHT-COLOR: #003366 } #squaretab LI A#current { BACKGROUND: white; COLOR: black } .blogcalendar { PADDING-RIGHT: 2px; PADDING-LEFT: 2px; FONT-WEIGHT: normal; FONT-SIZE: x-small; PADDING-BOTTOM: 2px; LINE-HEIGHT: 140%; PADDING-TOP: 2px; FONT-FAMILY: verdana, arial, sans-serif } TABLE.blogcalendar { BORDER-RIGHT: #3c78b5 1px solid; BORDER-TOP: #3c78b5 1px solid; BORDER-LEFT: #3c78b5 1px solid; BORDER-BOTTOM: #3c78b5 1px solid } .blogcalendar TH.calendarhead { PADDING-RIGHT: 2px; PADDING-LEFT: 2px; FONT-WEIGHT: bold; FONT-SIZE: x-small; PADDING-BOTTOM: 2px; TEXT-TRANSFORM: uppercase; COLOR: #ffffff; PADDING-TOP: 2px; LETTER-SPACING: 0.3em; BACKGROUND-COLOR: #3c78b5 } A.calendarhead { PADDING-RIGHT: 2px; PADDING-LEFT: 2px; FONT-WEIGHT: bold; FONT-SIZE: x-small; PADDING-BOTTOM: 2px; TEXT-TRANSFORM: uppercase; COLOR: #ffffff; PADDING-TOP: 2px; LETTER-SPACING: 0.3em; BACKGROUND-COLOR: #3c78b5 } .calendarhead:visited { COLOR: white } .calendarhead:active { COLOR: white } .calendarhead:hover { COLOR: white } .blogcalendar TH { PADDING-RIGHT: 2px; PADDING-LEFT: 2px; FONT-WEIGHT: bold; FONT-SIZE: x-small; PADDING-BOTTOM: 2px; PADDING-TOP: 2px; BACKGROUND-COLOR: #eeefcc } .blogcalendar TD { FONT-WEIGHT: normal; FONT-SIZE: x-small } .searchGroup { PADDING-RIGHT: 0px; PADDING-LEFT: 0px; BACKGROUND: #eeefcc; PADDING-BOTTOM: 10px; PADDING-TOP: 0px } .searchGroupHeading { PADDING-RIGHT: 4px; PADDING-LEFT: 4px; FONT-WEIGHT: bold; FONT-SIZE: 10px; PADDING-BOTTOM: 1px; COLOR: #ffffff; PADDING-TOP: 2px; BACKGROUND-COLOR: #3c78b5 } .searchItem { PADDING-RIGHT: 4px; PADDING-LEFT: 4px; PADDING-BOTTOM: 1px; PADDING-TOP: 1px } .searchItemSelected { PADDING-RIGHT: 4px; PADDING-LEFT: 4px; FONT-WEIGHT: bold; BACKGROUND: #ddd; PADDING-BOTTOM: 1px; PADDING-TOP: 1px } .permissionHeading { BORDER-RIGHT: 0px solid; BORDER-TOP: 0px solid; FONT-SIZE: 16px; BORDER-LEFT: 0px solid; BORDER-BOTTOM: #bbb 1px solid; TEXT-ALIGN: left } .permissionTab { BORDER-RIGHT: 0px solid; BORDER-TOP: 0px solid; FONT-SIZE: 10px; BACKGROUND: #3c78b5; BORDER-LEFT: 1px solid; COLOR: #ffffff; BORDER-BOTTOM: 0px solid } .permissionSuperTab { BORDER-RIGHT: 0px solid; BORDER-TOP: 0px solid; BACKGROUND: #003366; BORDER-LEFT: 1px solid; COLOR: #ffffff; BORDER-BOTTOM: 0px solid } .permissionCell { BORDER-RIGHT: 0px solid; BORDER-TOP: 0px solid; BORDER-LEFT: #bbb 1px solid; BORDER-BOTTOM: 0px solid } .warningPanel { BORDER-RIGHT: #f0c000 1px solid; PADDING-RIGHT: 8px; BORDER-TOP: #f0c000 1px solid; PADDING-LEFT: 8px; BACKGROUND: #ffffce; PADDING-BOTTOM: 8px; MARGIN: 10px; BORDER-LEFT: #f0c000 1px solid; PADDING-TOP: 8px; BORDER-BOTTOM: #f0c000 1px solid } .alertPanel { BORDER-RIGHT: #c00 1px solid; PADDING-RIGHT: 8px; BORDER-TOP: #c00 1px solid; PADDING-LEFT: 8px; BACKGROUND: #ffcccc; PADDING-BOTTOM: 8px; MARGIN: 10px; BORDER-LEFT: #c00 1px solid; PADDING-TOP: 8px; BORDER-BOTTOM: #c00 1px solid } .infoPanel { BORDER-RIGHT: #3c78b5 1px solid; PADDING-RIGHT: 8px; BORDER-TOP: #3c78b5 1px solid; PADDING-LEFT: 8px; BACKGROUND: #d8e4f1; PADDING-BOTTOM: 8px; MARGIN: 10px; BORDER-LEFT: #3c78b5 1px solid; PADDING-TOP: 8px; BORDER-BOTTOM: #3c78b5 1px solid } .optionPadded { PADDING-RIGHT: 2px; PADDING-LEFT: 2px; PADDING-BOTTOM: 2px; PADDING-TOP: 2px } .optionSelected { BORDER-RIGHT: #ddd 1px solid; PADDING-RIGHT: 2px; BORDER-TOP: #ddd 1px solid; PADDING-LEFT: 2px; PADDING-BOTTOM: 2px; MARGIN: -1px; BORDER-LEFT: #ddd 1px solid; PADDING-TOP: 2px; BORDER-BOTTOM: #ddd 1px solid; BACKGROUND-COLOR: #ffffcc } .optionSelected A { FONT-WEIGHT: bold; COLOR: black; TEXT-DECORATION: none } .noteMacro { BORDER-RIGHT: #f0c000 1px solid; BORDER-TOP: #f0c000 1px solid; MARGIN-TOP: 5px; MARGIN-BOTTOM: 5px; BORDER-LEFT: #f0c000 1px solid; BORDER-BOTTOM: #f0c000 1px solid; BACKGROUND-COLOR: #ffffce; TEXT-ALIGN: left } .warningMacro { BORDER-RIGHT: #c00 1px solid; BORDER-TOP: #c00 1px solid; MARGIN-TOP: 5px; MARGIN-BOTTOM: 5px; BORDER-LEFT: #c00 1px solid; BORDER-BOTTOM: #c00 1px solid; BACKGROUND-COLOR: #fcc; TEXT-ALIGN: left } .infoMacro { BORDER-RIGHT: #3c78b5 1px solid; BORDER-TOP: #3c78b5 1px solid; MARGIN-TOP: 5px; MARGIN-BOTTOM: 5px; BORDER-LEFT: #3c78b5 1px solid; BORDER-BOTTOM: #3c78b5 1px solid; BACKGROUND-COLOR: #d8e4f1; TEXT-ALIGN: left } .tipMacro { BORDER-RIGHT: #090 1px solid; BORDER-TOP: #090 1px solid; MARGIN-TOP: 5px; MARGIN-BOTTOM: 5px; BORDER-LEFT: #090 1px solid; BORDER-BOTTOM: #090 1px solid; BACKGROUND-COLOR: #dfd; TEXT-ALIGN: left } .informationMacroPadding { PADDING-RIGHT: 0px; PADDING-LEFT: 5px; PADDING-BOTTOM: 0px; PADDING-TOP: 5px } TABLE.infoMacro TD { BORDER-TOP-STYLE: none; BORDER-RIGHT-STYLE: none; BORDER-LEFT-STYLE: none; BORDER-BOTTOM-STYLE: none } TABLE.warningMacro TD { BORDER-TOP-STYLE: none; BORDER-RIGHT-STYLE: none; BORDER-LEFT-STYLE: none; BORDER-BOTTOM-STYLE: none } TABLE.tipMacro TD { BORDER-TOP-STYLE: none; BORDER-RIGHT-STYLE: none; BORDER-LEFT-STYLE: none; BORDER-BOTTOM-STYLE: none } TABLE.noteMacro TD { BORDER-TOP-STYLE: none; BORDER-RIGHT-STYLE: none; BORDER-LEFT-STYLE: none; BORDER-BOTTOM-STYLE: none } TABLE.sectionMacro TD { BORDER-TOP-STYLE: none; BORDER-RIGHT-STYLE: none; BORDER-LEFT-STYLE: none; BORDER-BOTTOM-STYLE: none } TABLE.sectionMacroWithBorder TD.columnMacro { BORDER-RIGHT: #cccccc 1px dashed; BORDER-TOP: #cccccc 1px dashed; BORDER-LEFT: #cccccc 1px dashed; BORDER-BOTTOM: #cccccc 1px dashed } .pagecontent { PADDING-RIGHT: 10px; PADDING-LEFT: 10px; PADDING-BOTTOM: 10px; PADDING-TOP: 10px; TEXT-ALIGN: left } .topBarDiv A:link { COLOR: #ffffff } .topBarDiv A:visited { COLOR: #ffffff } .topBarDiv A:active { COLOR: #ffffff } .topBarDiv A:hover { COLOR: #ffffff } .topBarDiv { COLOR: #ffffff } .topBar { BACKGROUND-COLOR: #003366 } .greyLinks A:link { COLOR: #666666; TEXT-DECORATION: underline } .greyLinks A:visited { COLOR: #666666; TEXT-DECORATION: underline } .greyLinks A:active { COLOR: #666666; TEXT-DECORATION: underline } .greyLinks A:hover { COLOR: #666666; TEXT-DECORATION: underline } .greyLinks { PADDING-RIGHT: 10px; DISPLAY: block; PADDING-LEFT: 10px; PADDING-BOTTOM: 10px; COLOR: #666666; PADDING-TOP: 10px } .logoSpaceLink { COLOR: #999999; TEXT-DECORATION: none } .logoSpaceLink A:link { COLOR: #999999; TEXT-DECORATION: none } .logoSpaceLink A:visited { COLOR: #999999; TEXT-DECORATION: none } .logoSpaceLink A:active { COLOR: #999999; TEXT-DECORATION: none } .logoSpaceLink A:hover { COLOR: #003366; TEXT-DECORATION: none } .basicPanelContainer { BORDER-RIGHT: #3c78b5 1px solid; BORDER-TOP: #3c78b5 1px solid; MARGIN-TOP: 2px; MARGIN-BOTTOM: 8px; BORDER-LEFT: #3c78b5 1px solid; WIDTH: 100%; BORDER-BOTTOM: #3c78b5 1px solid } .basicPanelTitle { PADDING-RIGHT: 5px; PADDING-LEFT: 5px; FONT-WEIGHT: bold; PADDING-BOTTOM: 5px; MARGIN: 0px; COLOR: black; PADDING-TOP: 5px; BACKGROUND-COLOR: #eeefcc } .basicPanelBody { PADDING-RIGHT: 5px; PADDING-LEFT: 5px; PADDING-BOTTOM: 5px; MARGIN: 0px; PADDING-TOP: 5px } .separatorLinks A:link { COLOR: white } .separatorLinks A:visited { COLOR: white } .separatorLinks A:active { COLOR: white } .greynavbar { BORDER-TOP: #3c78b5 1px solid; MARGIN-TOP: 2px; BACKGROUND-COLOR: #eeefcc } DIV.headerField { FLOAT: left; WIDTH: auto; HEIGHT: 100% } .headerFloat { MARGIN-LEFT: auto; WIDTH: 50% } .headerFloatLeft { FLOAT: left; MARGIN-BOTTOM: 10px; MARGIN-RIGHT: 20px } #headerRow { PADDING-RIGHT: 10px; PADDING-LEFT: 10px; PADDING-BOTTOM: 10px; PADDING-TOP: 10px } DIV.license-personal { COLOR: #ffffff; BACKGROUND-COLOR: #003366 } DIV.license-personal A { COLOR: #ffffff } .greyFormBox { BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 5px; PADDING-BOTTOM: 5px; BORDER-LEFT: #cccccc 1px solid; PADDING-TOP: 5px; BORDER-BOTTOM: #cccccc 1px solid } .marginlessForm { MARGIN: 0px } .openPageHighlight { BORDER-RIGHT: #ddd 1px solid; PADDING-RIGHT: 2px; BORDER-TOP: #ddd 1px solid; PADDING-LEFT: 2px; PADDING-BOTTOM: 2px; BORDER-LEFT: #ddd 1px solid; PADDING-TOP: 2px; BORDER-BOTTOM: #ddd 1px solid; BACKGROUND-COLOR: #ffffcc } .editPageInsertLinks { FONT-WEIGHT: bold; FONT-SIZE: 10px; COLOR: #666666 } .editPageInsertLinks A { FONT-WEIGHT: bold; FONT-SIZE: 10px; COLOR: #666666 } .top10 A { FONT-WEIGHT: bold; FONT-SIZE: 2em; COLOR: #003366 } .top25 A { FONT-WEIGHT: bold; FONT-SIZE: 1.6em; COLOR: #003366 } .top50 A { FONT-SIZE: 1.4em; COLOR: #003366 } .top100 A { FONT-SIZE: 1.2em; COLOR: #003366 } .heatmap { MARGIN: 0px auto; WIDTH: 95%; LIST-STYLE-TYPE: none } .heatmap A { TEXT-DECORATION: none } .heatmap A:hover { TEXT-DECORATION: underline } .heatmap LI { DISPLAY: inline } .minitab { PADDING-RIGHT: 0px; MARGIN-TOP: 1px; PADDING-LEFT: 8px; FLOAT: none; MARGIN-BOTTOM: 0px; PADDING-BOTTOM: 3px; FONT: bold 9px Verdana, sans-serif; MARGIN-LEFT: 0px; PADDING-TOP: 3px; BORDER-BOTTOM: #3c78b5 1px solid; TEXT-DECORATION: none } .selectedminitab { BORDER-RIGHT: #3c78b5 1px solid; PADDING-RIGHT: 0.5em; BORDER-TOP: #3c78b5 1px solid; MARGIN-TOP: 1px; PADDING-LEFT: 0.5em; BACKGROUND: white; PADDING-BOTTOM: 3px; MARGIN-LEFT: 3px; BORDER-LEFT: #3c78b5 1px solid; COLOR: #000000; PADDING-TOP: 3px; BORDER-BOTTOM: white 1px solid; TEXT-DECORATION: none } .unselectedminitab { BORDER-RIGHT: #3c78b5 1px solid; PADDING-RIGHT: 0.5em; BORDER-TOP: #3c78b5 1px solid; MARGIN-TOP: 1px; PADDING-LEFT: 0.5em; BACKGROUND: #3c78b5; PADDING-BOTTOM: 3px; MARGIN-LEFT: 3px; BORDER-LEFT: #3c78b5 1px solid; COLOR: #ffffff; PADDING-TOP: 3px; BORDER-BOTTOM: #3c78b5 1px; TEXT-DECORATION: none } A.unselectedminitab:hover { BORDER-LEFT-COLOR: #003366; BACKGROUND: #003366; BORDER-BOTTOM-COLOR: #003366; COLOR: #ffffff; BORDER-TOP-COLOR: #003366; BORDER-RIGHT-COLOR: #003366 } A.unselectedminitab:link { COLOR: white } A.unselectedminitab:visited { COLOR: white } A.selectedminitab:link { COLOR: black } A.selectedminitab:visited { COLOR: black } .linkerror { BACKGROUND-COLOR: #fcc } A.labelOperationLink:link { TEXT-DECORATION: underline } A.labelOperationLink:active { TEXT-DECORATION: underline } A.labelOperationLink:visited { TEXT-DECORATION: underline } A.labelOperationLink:hover { TEXT-DECORATION: underline } A.newLabel:link { BACKGROUND-COLOR: #ddffdd } A.newLabel:active { BACKGROUND-COLOR: #ddffdd } A.newLabel:visited { BACKGROUND-COLOR: #ddffdd } A.newLabel:hover { BACKGROUND-COLOR: #ddffdd } UL.square { LIST-STYLE-TYPE: square } .inline-control-link { PADDING-RIGHT: 2px; PADDING-LEFT: 2px; FONT-SIZE: 9px; BACKGROUND: #ffc; PADDING-BOTTOM: 2px; TEXT-TRANSFORM: uppercase; COLOR: #666; PADDING-TOP: 2px; TEXT-DECORATION: none } .inline-control-link A:link { TEXT-DECORATION: none } .inline-control-link A:active { TEXT-DECORATION: none } .inline-control-link A:visited { TEXT-DECORATION: none } .inline-control-link A:hover { TEXT-DECORATION: none } .inline-control-link { PADDING-RIGHT: 2px; PADDING-LEFT: 2px; FONT-SIZE: 9px; BACKGROUND: #ffc; PADDING-BOTTOM: 2px; TEXT-TRANSFORM: uppercase; CURSOR: pointer; COLOR: #666; PADDING-TOP: 2px; TEXT-DECORATION: none } DIV.auto_complete { BACKGROUND: #fff; WIDTH: 350px } DIV.auto_complete UL { BORDER-RIGHT: #888 1px solid; PADDING-RIGHT: 0px; BORDER-TOP: #888 1px solid; PADDING-LEFT: 0px; PADDING-BOTTOM: 0px; MARGIN: 0px; BORDER-LEFT: #888 1px solid; WIDTH: 100%; PADDING-TOP: 0px; BORDER-BOTTOM: #888 1px solid; LIST-STYLE-TYPE: none } DIV.auto_complete UL LI { PADDING-RIGHT: 3px; PADDING-LEFT: 3px; PADDING-BOTTOM: 3px; MARGIN: 0px; PADDING-TOP: 3px } DIV.auto_complete UL LI.selected { BACKGROUND-COLOR: #ffb } DIV.auto_complete UL STRONG.highlight { PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 0px; MARGIN: 0px; COLOR: #800; PADDING-TOP: 0px } .toogleFormDiv { BORDER-RIGHT: #a7a6aa 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #a7a6aa 1px solid; MARGIN-TOP: 5px; PADDING-LEFT: 5px; PADDING-BOTTOM: 5px; BORDER-LEFT: #a7a6aa 1px solid; PADDING-TOP: 5px; BORDER-BOTTOM: #a7a6aa 1px solid; BACKGROUND-COLOR: white } .toogleInfoDiv { BORDER-RIGHT: #a7a6aa 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #a7a6aa 1px solid; MARGIN-TOP: 10px; DISPLAY: none; PADDING-LEFT: 5px; PADDING-BOTTOM: 5px; BORDER-LEFT: #a7a6aa 1px solid; PADDING-TOP: 5px; BORDER-BOTTOM: #a7a6aa 1px solid; BACKGROUND-COLOR: white } .inputSection { MARGIN-BOTTOM: 20px } #editBox { BACKGROUND-COLOR: #eeefcc } .leftnav LI A { PADDING-RIGHT: 2px; BORDER-TOP: #3c78b5 1px solid; DISPLAY: block; PADDING-LEFT: 5px; PADDING-BOTTOM: 2px; MARGIN: 0px; COLOR: white; PADDING-TOP: 2px; BACKGROUND-COLOR: #3c78b5; TEXT-DECORATION: none } .leftnav LI A:active { COLOR: white } .leftnav LI A:visited { COLOR: white } .leftnav LI A:hover { COLOR: white; BACKGROUND-COLOR: #003366 } .replaced { BACKGROUND-COLOR: #33cc66 } .topPadding { MARGIN-TOP: 20px } .form-block { PADDING-RIGHT: 6px; PADDING-LEFT: 6px; PADDING-BOTTOM: 6px; PADDING-TOP: 6px } .form-error-block { PADDING-RIGHT: 12px; BORDER-TOP: #eeefcc 1px solid; PADDING-LEFT: 12px; BACKGROUND: #fcc; MARGIN-BOTTOM: 6px; PADDING-BOTTOM: 0px; PADDING-TOP: 0px; BORDER-BOTTOM: #eeefcc 1px solid } .form-element-large { FONT-WEIGHT: bold; FONT-SIZE: 16px; COLOR: #003366; FONT-FAMILY: Arial, sans-serif } .form-element-small { FONT-WEIGHT: bold; FONT-SIZE: 12px; COLOR: #003366; FONT-FAMILY: Arial, sans-serif } .form-header { PADDING-RIGHT: 12px; BORDER-TOP: #eeefcc 1px solid; PADDING-LEFT: 12px; BACKGROUND: lightyellow; MARGIN-BOTTOM: 6px; PADDING-BOTTOM: 0px; PADDING-TOP: 0px; BORDER-BOTTOM: #eeefcc 1px solid } .form-header P { MARGIN: 12px 0px; LINE-HEIGHT: normal } .form-block P { MARGIN: 12px 0px; LINE-HEIGHT: normal } .form-error-block P { MARGIN: 12px 0px; LINE-HEIGHT: normal } .form-example { FONT-SIZE: 11px; COLOR: #888 } .form-divider { MARGIN-BOTTOM: 6px; BORDER-BOTTOM: #ccc 1px solid } .form-buttons { PADDING-RIGHT: 10px; BORDER-TOP: #ccc 1px solid; MARGIN-TOP: 6px; PADDING-LEFT: 10px; BACKGROUND: #eeefcc; PADDING-BOTTOM: 10px; PADDING-TOP: 10px; BORDER-BOTTOM: #ccc 1px solid; TEXT-ALIGN: center } .form-buttons INPUT { WIDTH: 100px } .form-block .error { PADDING-RIGHT: 6px; PADDING-LEFT: 6px; MARGIN-BOTTOM: 6px; PADDING-BOTTOM: 6px; PADDING-TOP: 6px } krb5-1.16/src/windows/build/css/main-action(1).css0000644000704600001450000000412413211554426021462 0ustar ghudsonlibuuid.sidebar { BACKGROUND-COLOR: #f0f0f0 } #logodiv { PADDING-RIGHT: 15px; PADDING-LEFT: 10px; PADDING-BOTTOM: 10px; PADDING-TOP: 10px; TEXT-ALIGN: center } #menu { WIDTH: 150px } .leftnav H1 { PADDING-RIGHT: 4px; BORDER-TOP: white 1px solid; PADDING-LEFT: 4px; FONT-WEIGHT: bold; FONT-SIZE: 11px; PADDING-BOTTOM: 4px; MARGIN: 0px; PADDING-TOP: 4px; BORDER-BOTTOM: #ccc 1px solid } .leftnav H5 { PADDING-RIGHT: 0px; BORDER-TOP: white 1px solid; PADDING-LEFT: 0px; FONT-WEIGHT: bold; FONT-SIZE: 11px; PADDING-BOTTOM: 0px; MARGIN: 0px; PADDING-TOP: 0px; BORDER-BOTTOM: #ccc 1px solid } .leftnav H5 A { BORDER-TOP-WIDTH: 0px; PADDING-RIGHT: 5px; DISPLAY: block; PADDING-LEFT: 5px; BORDER-LEFT-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; PADDING-BOTTOM: 5px; PADDING-TOP: 5px; BORDER-RIGHT-WIDTH: 0px; TEXT-DECORATION: none } .leftnav H5 A:hover { BORDER-TOP-WIDTH: 0px; DISPLAY: block; BORDER-LEFT-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BACKGROUND-COLOR: white; BORDER-RIGHT-WIDTH: 0px; TEXT-DECORATION: none } .leftnav UL { PADDING-RIGHT: 0px; DISPLAY: inline; PADDING-LEFT: 0px; PADDING-BOTTOM: 0px; MARGIN: 0px; PADDING-TOP: 0px; LIST-STYLE-TYPE: none } .leftnav LI { PADDING-RIGHT: 0px; DISPLAY: inline; PADDING-LEFT: 0px; PADDING-BOTTOM: 0px; MARGIN: 0px; PADDING-TOP: 0px } .leftnav LI A { PADDING-RIGHT: 2px; DISPLAY: block; PADDING-LEFT: 5px; PADDING-BOTTOM: 2px; MARGIN: 0px; COLOR: white; PADDING-TOP: 2px; TEXT-DECORATION: none } .leftnav LI A.current { COLOR: white; BACKGROUND-COLOR: #003366 } .leftnav LI A:active { COLOR: white } .leftnav LI A:visited { COLOR: white } .leftnav LI A:hover { COLOR: white; BACKGROUND-COLOR: #003366 } .leftnav LI.current { BACKGROUND-COLOR: #487bb7 } .leftnav LI.current A { COLOR: #3c78b5 } #PageContent { PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 0px; MARGIN: 0px; PADDING-TOP: 0px; BACKGROUND-COLOR: #fff; TEXT-ALIGN: left } H1 { PADDING-RIGHT: 0px; PADDING-LEFT: 0px; FONT-WEIGHT: bold; FONT-SIZE: 22px; BORDER-BOTTOM-WIDTH: 0px; PADDING-BOTTOM: 0px; MARGIN: 27px 0px 4px; COLOR: #660000; PADDING-TOP: 0px; FONT-FAMILY: Arial, sans-serif; BACKGROUND-COLOR: #fff } krb5-1.16/src/windows/build/copyfiles.xml0000644000704600001450000003700013211554426020275 0ustar ghudsonlibuuid krb5-1.16/src/windows/build/makeZip.pl0000644000704600001450000000724613211554426017524 0ustar ghudsonlibuuid#!perl -w #use strict; require "prunefiles.pl"; use Data::Dumper; sub makeZip { local ($zip, $config) = @_; local $odr = $config->{Config}; ## Options, directories, repository, environment. local $src = $odr->{src}->{value}; local $out = $odr->{out}->{value}; local $zipname = $zip->{filename}; local $filestem = $config->{Stages}->{PostPackage}->{Config}->{FileStem}->{name}; $zipname =~ s/%filestem%/$filestem/g; if (exists $zip->{Requires}) { local $bMakeIt = 1; local $rverb = $odr->{repository}->{value}; local $j = 0; while ($zip->{Requires}->{Switch}[$j]) { ## Check Require switches local $switch = $zip->{Requires}->{Switch}[$j]; if (exists $switch->{name}) { ## Ignore dummy entry # We handle REPOSITORY and CLEAN switches: if ($switch->{name} =~ /REPOSITORY/i) { $bMakeIt &&= ($switch->{value} =~ /$rverb/i); ## Repository verb must match requirement } elsif ($switch->{name} =~ /CLEAN/i) { ## Clean must be specified $bMakeIt &&= $clean; } else {print "Error -- Unsupported switch $switch->{name} in Requires in ".Dumper($zip); $bMakeIt = 0; } } $j++; } if ( !$bMakeIt ) { if (exists $zip->{Requires}->{ErrorMsg}) { print "Error -- $zip->{Requires}->{ErrorMsg}->{text}\n"; } else { print "Error -- requirements not met for building $zipname.\n"; } return 0; } } local $ziptemp = "$out\\ziptemp"; chdir "$out"; print "Info -- chdir to ".`cd`."\n" if ($verbose); system("rm -rf $ziptemp") if (-d $ziptemp); die "Fatal -- Couldn't remove $ziptemp" if (-d $ziptemp); mkdir($ziptemp); # Set up the zip's config section: $zip->{Config} = $config->{Stages}->{PostPackage}->{Config}; # Add to the copylist's config section. Don't copy Postpackage->Config, # because the CopyList's Config might contain substitution tags. $zip->{CopyList}->{Config}->{FileStem}->{name} = $config->{Stages}->{PostPackage}->{Config}->{FileStem}->{name}; $zip->{CopyList}->{Config}->{From}->{root} = "$src\\pismere"; ## Add zip-specific config settings. $zip->{CopyList}->{Config}->{To}->{root} = $ziptemp; copyFiles($zip->{CopyList}, $config); # Drop down into /ziptemp so the path to the added file won't include : chdir $ziptemp; print "Info -- chdir to ".`cd`."\n" if ($verbose); # Prune any unwanted files or directories from the directory we're about to zip: pruneFiles($zip, $config); local $zipfile = Archive::Zip->new(); local $topdir = $zip->{topdir}; $topdir =~ s/%filestem%/$filestem/g; $zipfile->addTree('.', $topdir); if (-e $zipname) {!system("rm -f $zipname") or die "Error -- Couldn't remove $zipname.";} $zipfile->writeToFileNamed($zipname); chdir("$out"); print "Info -- chdir to ".`cd`."\n" if ($verbose); # move .zip from /ziptemp to . !system("mv -f ziptemp/$zipname .") or die "Error -- Couldn't move $zipname to .."; system("rm -rf ziptemp") if (-d "ziptemp"); ## Clean up any temp directory. print "Info -- created $out\\$zipname.\n" if ($verbose); } return 1;krb5-1.16/src/windows/build/copyfiles.pl0000644000704600001450000001512213211554426020111 0ustar ghudsonlibuuid#!perl -w #use strict; use XML::Simple; use Data::Dumper; sub copyFiles { local ($xml, $config) = @_; local @odr = $config->{Config}; local @files = $xml->{Files}; # Check for includes: if (exists $xml->{Files}->{Include}->{path}) { my $includepath = $xml->{Files}->{Include}->{path}; print "Info -- Including files from $includepath\n"; my $savedDir = `cd`; $savedDir =~ s/\n//g; chdir $originalDir; ## Includes are relative to where we were invoked. print "Info -- chdir to ".`cd`."\n" if ($verbose); my $tmp = new XML::Simple; my $includeXML = $tmp->XMLin($includepath); chdir $savedDir; print "Info -- chdir to ".`cd`."\n" if ($verbose); local $i = 0; while ($includeXML->{File}[$i]) { ## Copy File entries from includeXML. $files[0]->{File}[++$#{$files[0]->{File}}] = $includeXML->{File}[$i]; $i++; } delete $files->{Include}; } ##++ Set up path substitution variables for use inside the copy loop: # A path can contain a variable part, which will be handled here. If the variable part is # the Always or BuildDependent tag, then the variable will be changed to the # build-type-dependent PathFragment. # If the variable part is the IgnoreTag, then the file will not be copied. # If the variable part is %filestem%, it will be replaced with Config->FileStem->name. my ($PathFragment, $BuildDependentTag, $IgnoreTag, $FileStemFragment, $fromRoot, $toRoot); my $bPathTags = (exists $xml->{Config}->{DebugArea}) && (exists $xml->{Config}->{ReleaseArea}); my $bFileStem = (exists $xml->{Config}->{FileStem}); if ($odr->{debug}->{def}) { ## Debug build tags: $PathFragment = $xml->{Config}->{DebugArea}->{value}; $BuildDependentTag = $xml->{Config}->{DebugTag}->{value}; $IgnoreTag = $xml->{Config}->{ReleaseTag}->{value}; } else { ## Release build tags: $PathFragment = $xml->{Config}->{ReleaseArea}->{value}; $BuildDependentTag = $xml->{Config}->{ReleaseTag}->{value}; $IgnoreTag = $xml->{Config}->{DebugTag}->{value}; } my $AlwaysTag = $xml->{Config}->{AlwaysTag}->{value}; $FileStemFragment = $xml->{Config}->{FileStem}->{name}; $fromRoot = $xml->{Config}->{From}->{root}; $toRoot = $xml->{Config}->{To}->{root}; ##-- Set up path substitution variables for use inside the copy loop. # For each file in the file list: # Substitute any variable parts of the path name. # Handle wildcards # Copy local $i = 0; my $bOldDot = 1; my $bDot = 0; while ($files[0]->{File}[$i]) { my ($name, $newname, $from, $to, $file); $file = $files[0]->{File}->[$i]; $name = $file->{name}; if (exists $file->{newname}) {$newname = $file->{newname};} else {$newname = $name;} if ($name && (! exists $file->{ignore})) { ## Ignore or process this entry? $from = "$fromRoot\\$file->{from}\\$name"; $to = "$toRoot\\$file->{to}\\$newname"; # Copy this file? Check for ignore tag [debug-only in release mode or vice versa]. if ( $bPathTags || $bFileStem || (index($from.$to, $IgnoreTag) <0) ) { if ($bPathTags) { ## Apply PathTag substitutions: $from =~ s/$AlwaysTag/$PathFragment/g; $to =~ s/$AlwaysTag/$PathFragment/g; $from =~ s/$BuildDependentTag/$PathFragment/g; $to =~ s/$BuildDependentTag/$PathFragment/g; } if ($bFileStem) { ## FileStem substitution? $from =~ s/%filestem%/$FileStemFragment/g; $to =~ s/%filestem%/$FileStemFragment/g; } # %-DEBUG% substitution: local $DebugFragment = ($odr->{debug}->{def}) ? "-DEBUG" : ""; $from =~ s/%\-DEBUG%/$DebugFragment/g; $to =~ s/%\-DEBUG%/$DebugFragment/g; $to =~ s/\*.*//; ## Truncate to path before any wildcard my $bCopyOK = 1; my $fromcheck = $from; my $bRequired = ! (exists $file->{notrequired}); if ($name =~ /\*/) { ## Wildcard case $fromcheck =~ s/\*.*//; if ($bRequired && (! -d $fromcheck)) { if ($bDot) {print "\n";} die "Fatal -- Can't find $fromcheck"; } $bCopyOK = !system("echo D | xcopy /D /F /Y /S $from $to > a.tmp 2>NUL"); } else { ## Specific file case if ($bRequired && (! -e $fromcheck)) { if ($bDot) {print "\n";} die "Fatal -- Can't find $fromcheck"; } $bCopyOK = !system("echo F | xcopy /D /F /Y $from $to > a.tmp 2>NUL"); } if ($bCopyOK) { ## xcopy OK - show progress # To show progress when files aren't copied, print a string of dots. open(MYINPUTFILE, "; foreach $line (@lines) { $bDot = ($line =~ /^0/); } close(MYINPUTFILE); if (!$bDot && $bOldDot) {print "\n";} if ($bDot) {print "."; STDOUT->flush;} else {print "$from copied to $to\n";} $bOldDot = $bDot; } else { ## xcopy failed if (!exists $file->{notrequired}) { if ($bDot) {print "\n";} die "Fatal -- Copy of $from to $to failed"; } } ## End xcopy succeed or fail } ## End not dummy entry nor ignored } $i++; } if ($bDot) {print "\n";} } return 1; krb5-1.16/src/windows/build/BKWconfig.xml0000644000704600001450000002410013211554426020106 0ustar ghudsonlibuuid krb5-1.16/src/windows/build/Logger.pm0000644000704600001450000000331413211554426017334 0ustar ghudsonlibuuidpackage Logger; use strict; use IO::File; use FindBin; my $bStarted = 0; sub new { my $class = shift; my $file = shift; my $append = shift; $file || die "Usage: \$foo = new Logger filename [append]\n"; my $self = {}; bless $self, $class; $self->{FILE} = $file; $self->{APPEND} = $append?'-a':''; return $self; } sub start { my $self = shift; return 1 if $self->{PIPE}; STDOUT->flush; STDERR->flush; my $fh_out = new IO::File; my $fh_err = new IO::File; my $fh_pipe = new IO::File; $self->{OUT} = $fh_out; $self->{ERR} = $fh_err; $self->{PIPE} = $fh_pipe; $fh_out->open(">&STDOUT") || die; $fh_err->open(">&STDERR") || die; $fh_pipe->open("|$^X $FindBin::Bin/tee.pl $self->{APPEND} $self->{FILE}") || die; STDOUT->fdopen(fileno $fh_pipe, "w") || die; STDERR->fdopen(fileno $fh_pipe, "w") || die; STDOUT->autoflush(1); STDERR->autoflush(1); $SIG{__DIE__} = sub { print STDERR $_[0]; $self->stop; die "\n"; }; $bStarted = 1; return 1; } # 20070314 kpkoch: # There appears to be a bug in ActivePerl where Logger's games with streams # and the SIG DIE handler cause eval to throw exceptions. By deleting the DIE handler, # subsequent evals do not fail. sub no_die_handler { delete $SIG{__DIE__}; } sub stop { my $self = shift; return 0 if !$self->{PIPE}; STDOUT->close; STDERR->close; $self->{PIPE}->close; STDOUT->fdopen(fileno $self->{OUT}, "w"); STDERR->fdopen(fileno $self->{ERR}, "w"); delete $self->{OUT}; delete $self->{ERR}; delete $self->{PIPE}; $bStarted = 0; return 1; } sub DESTROY { my $self = shift; $self->stop if ($bStarted); } 1; krb5-1.16/src/windows/build/site-local.sed0000644000704600001450000000022113211554426020302 0ustar ghudsonlibuuids/// s///krb5-1.16/src/windows/build/which.pl0000644000704600001450000000307513211554426017222 0ustar ghudsonlibuuid#!perl -w use strict; use Config; use File::Basename; use Getopt::Long; $0 = fileparse($0); sub main { Getopt::Long::Configure('bundling', 'no_auto_abbrev', 'no_getopt_compat', 'require_order', 'ignore_case', 'pass_through', 'prefix_pattern=(--|-|\+|\/)', ); my $OPT = {}; GetOptions($OPT, 'help|h|?', 'all|a', 'quiet|q', 'debug|d', 'path:s', ); my $f = shift @ARGV; if ($OPT->{help} || !$f) { usage(); exit(0) if $OPT->{help}; exit(1); } my $p = $OPT->{path} || $ENV{PATH}; my $s = $Config{path_sep}; my @d = split(/$s/, $p); my @e = split(/$s/, lc($ENV{PATHEXT} || '.bat;.exe;.com')); my @f = ($f, map { $f.$_; } @e); my $found = 0; foreach my $d (@d) { print "(Searching $d)\n" if $OPT->{debug}; foreach my $f (@f) { my $df = $d.'\\'.$f; # cannot use $File::Spec->catfile due to UNC. print "(Checking for $df)\n" if $OPT->{debug}; if (-f $df) { exit(0) if $OPT->{quiet}; print "$df\n"; exit(0) if !$OPT->{all}; $found = 1; } } } print "Could not find $f\n" if !$found && !$OPT->{quiet}; exit($found?0:1); } sub usage { print < 'bar'}; my $MAKE = 'NMAKE'; our $config; sub get_info { my $cmd = shift || die; my $which = $^X.' which.pl'; my $full = `$which $cmd`; return 0 if ($? / 256); chomp($full); $full = "\"".$full."\""; return { cmd => $cmd, full => $full}; } sub usage { print < in cvs command /svnbranch /b tag use /branches/ instead of /trunk. /svntag /t tag use /tags/ instead of /trunk. /debug /d Do debug make instead of release make. /[no]make Control the make step. /clean Build clean target. /[no]package Control the packaging step. /[no]sign Control signing of executable files. /verbose /v Debug mode - verbose output. /logfile /l path Where to write output. Default is bkw.pl.log. /nolog Don't save output. Other: NMAKE-options any options you want to pass to NMAKE, which can be: (note: /nologo is always used) USAGE system("$MAKE /?"); } sub handler { my $sig = shift; my $bailmsg = "Bailing out due to SIG$sig!\n"; my $warnmsg = <{config}) {$OPT->{config} = "bkwconfig.xml";} my $configfile = $OPT->{config}; print "Info -- Reading configuration from $configfile.\n"; my $xml = new XML::Simple(); $config = $xml->XMLin($configfile); ## Read in configuration file. # Set up convenience variables: local $odr = $config->{Config}; ## Options, directories, repository, environment. # Build argument description from Config section of the XML, # to parse the rest of the arguments: local @xmlargs; while (($sw, $val) = each %$odr) { local $arg = $sw; if (exists $val->{abbr}) {$arg .= "|$val->{abbr}";} if (exists $val->{value}) { ## Can't do both negations and string values. $arg .= ":s"; } else { if (! ($val->{def} =~ /A/)) {$arg .= "!";} } push @xmlargs, $arg; } if (!GetOptions($OPT, @xmlargs)) {$OPT->{help} = 1;} if ( $OPT->{help} ) { usage(); exit(0); } delete $OPT->{foo}; ##++ Validate required conditions: # List of programs which must be in PATH:' # 'cvs', 'svn', 'hhc', 'makensis', 'plink', 'filever' my @required_list = ('sed', 'awk', 'which', 'cat', 'rm', 'doxygen', 'candle', 'light', 'nmake'); my $requirements_met = 1; my $first_missing = 0; my $error_list = ""; foreach my $required (@required_list) { if (!get_info($required)) { $requirements_met = 0; if (!$first_missing) { $first_missing = 1; $error_list = "Fatal -- Environment problem! The following program(s) are not in PATH:\n"; } $error_list .= "$required\n"; } } if (!$requirements_met) { print $error_list; print "Info -- Update PATH or install the programs and try again.\n"; exit(0); } ##-- Validate required conditions. use Time::gmtime; $ENV{DATE} = gmctime()." GMT"; our $originalDir = `cd`; $originalDir =~ s/\n//g; ##++ Assemble configuration from config file and command line: my $bOutputCleaned = 0; # Scan the configuration for switch definitions: while (($sw, $val) = each %$odr) { next if (! exists $val->{def}); ## ?? Should always exist. # Set/clear environment variables: if ($val->{env}) { if ($val->{def}) {$ENV{$sw} = (exists $val->{value}) ? $val->{value} : 1; } else { delete $ENV{$sw}; undef $sw; } } # If the switch is in the command line, override the stored value: if (exists $OPT->{$sw}) { if (exists $val->{value}) { $val->{value} = $OPT->{$sw}; $val->{def} = 1; } else { $val->{def} = $OPT->{$sw}; ## If -NO, value will be zero. } } # If the switch can be negated, test that, too: if ( ! ($val->{def} =~ /A/)) { local $nosw = "no".$sw; if (exists $OPT->{$nosw}) { ## -NO ? if ($val->{env}) { if (!$val->{def}) { print "Deleting environment variable $sw\n"; delete $ENV{$sw}; undef $sw; } } } } # For any switch definition with fixed values ("options"), validate: if (exists $val->{options}) { local $bValid = 0; # options can be like value1|syn1 value2|syn2|syn3 foreach $option (split(/ /, $val->{options})) { local $bFirst = 1; local $sFirst; foreach $opt (split(/\|/, $option)) { # opt will be like value2, syn2, syn3 if ($bFirst) { $sFirst = $opt; ## Remember the full name of the option. $bFirst = 0; } if ($val->{value} =~ /$opt/i) { $val->{value} = $sFirst; ## Save the full name. $bValid = 1; } } } if (! $bValid) { print "Fatal -- invalid $sw value $val->{value}. Possible values are $val->{options}.\n"; usage(); die; } } } # Set up convenience variables: our $verbose = $odr->{verbose}->{def}; our $vverbose = $odr->{vverbose}->{def}; our $clean = $clean->{clean}->{def}; local $src = $odr->{src}->{value}; local $out = $odr->{out}->{value}; if ($clean && $odr->{package}->{def}) { print "Info -- /clean forces /nopackage.\n"; $odr->{package}->{def} = 0; } if ($vverbose) {print "Debug -- Config: ".Dumper($config);} # Test the unix find command: # List of directories where it might be: my @find_dirs = ('c:\\cygwin\\bin', 'c:\\tools\\cygwin\\bin'); if (exists $odr->{unixfind}->{value}) { ## Was an additional place to look specified? push (@find_dirs, $odr->{unixfind}->{value}); } my $bFindFound = 0; foreach my $dir (@find_dirs) { if (-d $dir) { local $savedPATH = $ENV{PATH}; $ENV{PATH} = $dir.";".$savedPATH; if (-e "a.tmp") {!system("rm a.tmp") or die "Fatal -- Couldn't clean temporary file a.tmp.";} !system("find . -maxdepth 0 -name a.tmp > b.tmp 2>&1") or die "Fatal -- find test failed."; local $filesize = -s "b.tmp"; $ENV{PATH} = $savedPATH; if ($filesize <= 0) { $bFindFound = 1; $odr->{unixfind}->{value} = $dir; last; } } } if (! $bFindFound) { print "Fatal -- unix find command not found in \n"; map {print " $_ "} @find_dirs; print "\n"; die; } # Don't allow /svntag and /svnbranch simultaneously: if ( (length $odr->{svntag}->{value} > 0) && (length $odr->{svnbranch}->{value} > 0) ) { die "Fatal -- Can't specify both /SVNTAG and /SVNBRANCH."; } # /logfile and /nolog interact: if ($odr->{nolog}->{def}) {$odr->{logfile}->{def} = 0;} ##-- Assemble configuration from config file and command line. local $rverb = $odr->{repository}->{value}; if ( (($rverb =~ /checkout/) || ($rverb =~ /export/)) && $clean) { print "Warning -- Because sources are being checked out, make clean will not be run.\n"; $clean = $odr->{clean}->{def} = 0; } my $wd = $src; if (! ($rverb =~ /skip/)) { local $len = 0; if (exists $odr->{username}->{value}) { $len = length $odr->{username}->{value}; } if ($len < 1) { die "Fatal -- you won't get far accessing the repository without specifying a username."; } } # (------------------------------------------------) if ( (-d $wd) && ( ($rverb =~ /export/) || ($rverb =~ /checkout/) ) ) { print "\n\nHEADS UP!!\n\n"; print "/REPOSITORY ".uc($rverb)." will cause everything under $wd to be deleted.\n"; print "If this is not what you intended, here's your chance to bail out!\n\n\n"; print "Are you sure you want to remove everything under $wd? "; my $char = getc; if (! ($char =~ /y/i)) {die "Info -- operation aborted by user."} !system("rm -rf $wd/*") or die "Fatal -- Couldn't clean $wd."; !system("rmdir $wd") or die "Fatal -- Couldn't remove $wd."; } # Begin logging: my $l; if ($odr->{logfile}->{def}) { print "Info -- logging to $odr->{logfile}->{value}.\n"; $l = new Logger $odr->{logfile}->{value}; $l->start; $l->no_die_handler; ## Needed so XML::Simple won't throw exceptions. } print "Command line options:\n"; while ($v = each %$OPT) {print "$v: $OPT->{$v}\n";} print "Executing $cmdline\n"; local $argvsize = @ARGV; local $nmakeargs = ""; if ($argvsize > 0) { map {$nmakeargs .= " $_ "} @ARGV; print "Arguments for NMAKE: $nmakeargs\n"; } print "Info -- Using unix find in $odr->{unixfind}->{value}\n" if ($verbose); ##++ Begin repository action: if ($rverb =~ /skip/) {print "Info -- *** Skipping repository access.\n" if ($verbose);} else { if ($verbose) {print "Info -- *** Begin fetching sources.\n";} local $cvspath = "$src"; if (! -d $cvspath) { ## xcopy will create the entire path for us. !system("echo foo > a.tmp") or die "Fatal -- Couldn't create temporary file in ".`cd`; !system("echo F | xcopy a.tmp $cvspath\\a.tmp") or die "Fatal -- Couldn't xcopy to $cvspath."; !system("rm a.tmp") or die "Fatal -- Couldn't remove temporary file."; !system("rm $cvspath\\a.tmp") or die "Fatal -- Couldn't remove temporary file."; } # Set up cvs environment variables: $ENV{CVSROOT} = $odr->{CVSROOT}->{value}; local $krb5dir = "$wd\\athena\\auth\\krb5"; local $cvscmdroot = "cvs $rverb"; if (length $odr->{cvstag}->{value} > 0) { $cvscmdroot .= " -r $odr->{cvstag}->{value}"; } if (($rverb =~ /checkout/) || ($rverb =~ /export/)) { chdir($src) or die "Fatal -- couldn't chdir to $src\n"; print "Info -- chdir to ".`cd`."\n" if ($verbose); my @cvsmodules = ( 'krb', 'pismere/athena/util/lib/delaydlls', 'pismere/athena/util/lib/getopt', 'pismere/athena/util/guiwrap' ); foreach my $module (@cvsmodules) { local $cvscmd = $cvscmdroot." ".$module; if ($verbose) {print "Info -- cvs command: $cvscmd\n";} !system("$cvscmd") or die "Fatal -- command \"$cvscmd\" failed; return code $?\n"; } } else { ## Update. chdir($wd) or die "Fatal -- couldn't chdir to $wd\n"; print "Info -- chdir to ".`cd`."\n" if ($verbose); if ($verbose) {print "Info -- cvs command: $cvscmdroot\n";} !system($cvscmdroot) or die "Fatal -- command \"$cvscmdroot\" failed; return code $?\n"; } # Set up svn environment variable: $ENV{SVN_SSH} = "plink.exe"; # If the directory structure doesn't exist, many cd commands will fail. if (! -d $krb5dir) { ## xcopy will create the entire path for us. !system("echo foo > a.tmp") or die "Fatal -- Couldn't create temporary file in ".`cd`; !system("echo F | xcopy a.tmp $krb5dir\\a.tmp") or die "Fatal -- Couldn't xcopy to $krb5dir."; !system("rm a.tmp") or die "Fatal -- Couldn't remove temporary file."; !system("rm $krb5dir\\a.tmp") or die "Fatal -- Couldn't remove temporary file."; } chdir($krb5dir) or die "Fatal -- Couldn't chdir to $krb5dir"; print "Info -- chdir to ".`cd`."\n" if ($verbose); my $svncmd = "svn $rverb "; if (($rverb =~ /checkout/) || ($rverb =~ /export/)) { # Append the rest of the checkout/export command: chdir(".."); if ($rverb =~ /export/) { ## svn export will fail if the destination directory exists rmdir "krb5"; } $svncmd .= "svn+ssh://".$odr->{username}->{value}."@".$odr->{SVNURL}->{value}."/krb5/"; if (length $odr->{svntag}->{value} > 0) { $svncmd .= "tags/$odr->{svntag}->{value}"; } elsif (length $odr->{svnbranch}->{value} > 0) { $svncmd .= "branches/$odr->{svnbranch}->{value}"; } else { $svncmd .= "trunk"; } $svncmd .= " krb5"; } if ($verbose) {print "Info -- svn command: $svncmd\n";} !system($svncmd) or die "Fatal -- command \"$svncmd\" failed; return code $?\n"; if ($verbose) {print "Info -- *** End fetching sources.\n";} } ##-- End repository action. ##++ Read in the version information to be able to update the # site-local files in the install build areas. # ** Do this now (after repository update and before first zip) # because making zip files requires some configuration data be set up. local $version_path = $config->{Stages}->{Package}->{Config}->{Paths}->{Versions}->{path}; open(DAT, "$src/$version_path") or die "Could not open $src/$version_path."; @raw = ; close DAT; foreach $line (@raw) { chomp $line; if ($line =~ /#define/) { # Process #define lines: $line =~ s/#define//; # Remove #define token $line =~ s/^\s+//; # and leading & trailing whitespace $line =~ s/\s+$//; local @qr = split("\"", $line); # Try splitting with quotes if (exists $qr[1]) { $qr[0] =~ s/^\s+//; # Clean up whitespace $qr[0] =~ s/\s+$//; $config->{Versions}->{$qr[0]} = $qr[1]; # Save string } else { # No quotes, so local @ar = split(" ", $line); # split with space $ar[0] =~ s/^\s+//; # Clean up whitespace $ar[0] =~ s/\s+$//; $config->{Versions}->{$ar[0]} = $ar[1]; # and save numeric value } } } # Check that the versions we will need for site-local have been defined: my @required_versions = ('VER_PROD_MAJOR', 'VER_PROD_MINOR', 'VER_PROD_REV', 'VER_PROD_MAJOR_STR', 'VER_PROD_MINOR_STR', 'VER_PROD_REV_STR', 'VER_PRODUCTNAME_STR'); $requirements_met = 1; $first_missing = 0; $error_list = ""; foreach my $required (@required_versions) { if (! exists $config->{Versions}->{$required}) { $requirements_met = 0; if (!$first_missing) { $first_missing = 1; $error_list = "Fatal -- The following version(s) are not defined in $src/$version_path.\n"; } $error_list .= "$required\n"; } } if (!$requirements_met) { print $error_list; exit(0); } # Apply any of these tags to filestem: my $filestem = $config->{Stages}->{PostPackage}->{Config}->{FileStem}->{name}; $filestem =~ s/%VERSION_MAJOR%/$config->{Versions}->{'VER_PROD_MAJOR_STR'}/; $filestem =~ s/%VERSION_MINOR%/$config->{Versions}->{'VER_PROD_MINOR_STR'}/; $filestem =~ s/%VERSION_PATCH%/$config->{Versions}->{'VER_PROD_REV_STR'}/; $config->{Stages}->{PostPackage}->{Config}->{FileStem}->{name} = $filestem; ##-- Read in the version information & set config info. ##++ Repository action, part 2: if (($rverb =~ /checkout/) || ($rverb =~ /export/)) { if (! $bOutputCleaned) { ## In case somebody cleaned $out before us. if (-d $out) {!system("rm -rf $out/*") or die "Fatal -- Couldn't clean $out."} ## Clean output directory. else {mkdir($out);} $bOutputCleaned = 1; } zipXML($config->{Stages}->{FetchSources}, $config); ## Make zips. } ##-- End repository action, part 2. ##++ Make action: if ( ($odr->{make}->{def}) ) { if ($verbose) {print "Info -- *** Begin preparing for build.\n";} chdir("$wd") or die "Fatal -- couldn't chdir to $wd\n"; print "Info -- chdir to ".`cd`."\n" if ($verbose); my ($path, $destpath); # Copy athena\scripts\site\graft\krb5\Makefile.src to athena\auth\krb5: $path = "scripts\\site\\graft\\krb5\\Makefile.src"; if (!-e $path) {die "Fatal -- Expected file $wd\\$path not found.";} $destpath = "athena\\auth\\krb5\\Makefile.src"; !system("echo F | xcopy /D $wd\\$path $wd\\$destpath /Y > NUL") or die "Fatal -- Copy of $wd\\$path to $wd\\$destpath failed."; print "Info -- copied $wd\\$path to $wd\\$destpath\n" if ($verbose);; # Add DEBUG_SYMBOL to .../wshelper/Makefile.src: $path = "athena\\wshelper\\wshelper\\Makefile.src"; if (!-e $path) {die "Fatal -- Expected file $wd\\$path not found.";} if (system("grep DEBUG_SYMBOL $path > NUL") != 0) { !system ("echo DEBUG_SYMBOL=1 >> $wd\\$path") or die "Fatal -- Append line to file failed.\n"; print "Info -- Added DEBUG_SYMBOL to $wd\\$path\n" if ($verbose); } # Prune any unwanted directories before the build: pruneFiles($config->{Stages}->{Make}, $config); if ($verbose) {print "Info -- *** End preparing for build.\n";} my ($buildtarget, $buildtext); if ($clean) { $buildtarget = "clean" ; $buildtext = " clean." } else { $buildtarget = "" ; $buildtext = "." } chdir("$wd\\athena") or die "Fatal -- couldn't chdir to source directory $wd\\athena\n"; print "Info -- chdir to ".`cd`."\n" if ($verbose); local $dbgswitch = ($odr->{debug}->{def}) ? " " : "NODEBUG=1"; !system("perl ../scripts/build.pl --softdirs --nolog $buildtarget $dbgswitch BUILD_KFW=1 BUILD_OFFICIAL=1 DEBUG_SYMBOL=1 $nmakeargs") or die "Fatal -- build $buildtarget failed."; chdir("$wd") or die "Fatal -- couldn't chdir to $wd."; print "Info -- chdir to ".`cd`."\n" if ($verbose); if ($clean) { if (-d "staging") { !system("rm -rf staging") or die "Fatal -- Couldn't remove $wd\\staging."; } } if ($verbose) {print "Info -- *** End build".$buildtext."\n";} } ## End make conditional. else {print "Info -- *** Skipping build.\n" if ($verbose);} ##-- Make action. ##++ Package action: if (! $odr->{package}->{def}) { ## If /clean, nopackage will be set. print "Info -- *** Skipping packaging.\n"; if ((-d $out) && ! $bOutputCleaned) { print "Warning -- *** Output directory $out will not be cleaned.\n"; } } else { if ($verbose) {print "Info -- *** Begin prepackage.\n";} if (! $bOutputCleaned) { ## In case somebody cleaned $out before us. if (-d $out) {!system("rm -rf $out/*") or die "Fatal -- Couldn't clean $out."} ## Clean output directory. else {mkdir($out);} $bOutputCleaned = 1; } # The build results are copied to a staging area, where the packager expects to find them. # We put the staging area in the fixed area .../pismere/staging. #my $prepackage = $config->{Stages}->{PrePackage}; #my $staging = "$wd\\staging"; #chdir($wd) or die "Fatal -- couldn't chdir to $wd\n"; #print "Info -- chdir to ".`cd`."\n" if ($verbose); #if (-d "staging") { # !system("rm -rf $staging/*") or die "Fatal -- Couldn't clean $staging."; # } #else { # mkdir($staging) or die "Fatal -- Couldn't create $staging."; # } # Force Where From and To are relative to: #$prepackage->{CopyList}->{Config}->{From}->{root} = "$wd\\athena"; #$prepackage->{CopyList}->{Config}->{To}->{root} = "$wd\\staging"; #copyFiles($prepackage->{CopyList}, $config); ## Copy any files [this step takes a while] # Sign files: #chdir($staging) or die "Fatal -- couldn't chdir to $staging\n"; #print "Info -- chdir to ".`cd`."\n" if ($verbose); #if ($odr->{sign}->{def}) { # signFiles($config->{Stages}->{PostPackage}->{Config}->{Signing}, $config); # } # Create working directories for building the installers: if (-d "$wd\\buildwix") {!system("rm -rf $wd\\buildwix/*") or die "Fatal -- Couldn't clean $wd\\buildwix."} !system("echo D | xcopy /s $wd\\windows\\installer\\wix\\*.* $wd\\buildwix") or die "Fatal -- Couldn't create $wd\\buildwix."; #if (-d "$wd\\buildnsi") {!system("rm -rf $wd\\buildnsi/*") or die "Fatal -- Couldn't clean $wd\\buildnsi."} #!system("echo D | xcopy /s $wd\\staging\\install\\nsis\\*.* $wd\\buildnsi") or die "Fatal -- Couldn't create $wd\\buildnsi."; chdir("$wd\\windows\\installer\\wix") or die "Fatal -- Couldn't cd to $wd\\windows\\installer\\wix"; print "Info -- chdir to ".`cd`."\n" if ($verbose); # Correct errors in files.wxi: #!system("sed 's/WorkingDirectory=\"\\[dirbin\\]\"/WorkingDirectory=\"dirbin\"/g' files.wxi > a.tmp") or die "Fatal -- Couldn't modify files.wxi."; #!system("mv a.tmp files.wxi") or die "Fatal -- Couldn't update files.wxi."; # Make sed script to run on the site-local configuration files: local $tmpfile = "site-local.sed" ; if (-e $tmpfile) {system("del $tmpfile");} # Basic substitutions: local $dblback_wd = $wd; $dblback_wd =~ s/\\/\\\\/g; !system("echo s/%BUILDDIR%/$dblback_wd/ >> $tmpfile") or die "Fatal -- Couldn't modify $tmpfile."; local $dblback_staging = "$wd\\staging"; $dblback_staging =~ s/\\/\\\\/g; !system("echo s/%TARGETDIR%/$dblback_staging/ >> $tmpfile") or die "Fatal -- Couldn't modify $tmpfile."; local $dblback_sample = "$wd\\staging\\sample"; $dblback_sample =~ s/\\/\\\\/g; !system("echo s/%CONFIGDIR-WIX%/$dblback_sample/ >> $tmpfile") or die "Fatal -- Couldn't modify $tmpfile."; !system("echo s/%CONFIGDIR-NSI%/$dblback_staging/ >> $tmpfile") or die "Fatal -- Couldn't modify $tmpfile."; !system("echo s/%VERSION_MAJOR%/$config->{Versions}->{'VER_PROD_MAJOR_STR'}/ >> $tmpfile") or die "Fatal -- Couldn't modify $tmpfile."; !system("echo s/%VERSION_MINOR%/$config->{Versions}->{'VER_PROD_MINOR_STR'}/ >> $tmpfile") or die "Fatal -- Couldn't modify $tmpfile."; !system("echo s/%VERSION_PATCH%/$config->{Versions}->{'VER_PROD_REV_STR'}/ >> $tmpfile") or die "Fatal -- Couldn't modify $tmpfile."; # Strip out some defines so they can be replaced: [used for site-local.nsi] !system("echo /\^!define\.\*RELEASE\.\*\$/d >> $tmpfile") or die "Fatal -- Couldn't modify $tmpfile."; !system("echo /\^!define\.\*DEBUG\.\*\$/d >> $tmpfile") or die "Fatal -- Couldn't modify $tmpfile."; !system("echo /\^!define\.\*BETA\.\*\$/d >> $tmpfile") or die "Fatal -- Couldn't modify $tmpfile."; # Run the script on site-local.wxi: !system("sed -f $tmpfile site-local-tagged.wxi > $wd\\buildwix\\site-local.wxi") or die "Fatal -- Couldn't modify site-local.wxi."; # Now update site-local.nsi: #chdir "..\\nsis"; #print "Info -- chdir to ".`cd`."\n" if ($verbose); #!system("sed -f ..\\wix\\$tmpfile site-local-tagged.nsi > b.tmp") or die "Fatal -- Couldn't modify site-local.wxi."; # Add DEBUG or RELEASE: #if ($odr->{debug}->{def}) { ## debug build # !system("echo !define DEBUG >> b.tmp") or die "Fatal -- Couldn't modify b.tmp."; # } #else { ## release build # !system("echo !define RELEASE >> b.tmp") or die "Fatal -- Couldn't modify b.tmp."; # } # Add BETA if present: #if (exists $config->{Versions}->{'BETA_STR'}) { # !system("echo !define BETA $config->{Versions}->{'BETA_STR'} >> b.tmp") or die "Fatal -- Couldn't modify b.tmp."; # } #!system("mv -f b.tmp $wd\\buildnsi\\site-local.nsi") or die "Fatal -- Couldn't replace site-local.nsi."; # Run the script on nsi-includes-tagged.nsi: #!system("sed -f ..\\wix\\$tmpfile nsi-includes-tagged.nsi > $wd\\buildnsi\\nsi-includes.nsi") or die "Fatal -- Couldn't modify nsi-includes.nsi."; #!system("rm ..\\wix\\$tmpfile") or die "Fatal -- Couldn't remove $tmpfile."; #if ($verbose) {print "Info -- *** End prepackage.\n";} #if ($verbose) {print "Info -- *** Begin package.\n";} # Make the msi: chdir("$wd\\buildwix") or die "Fatal -- Couldn't cd to $wd\\buildwix"; print "Info -- *** Make .msi:\n" if ($verbose); print "Info -- chdir to ".`cd`."\n" if ($verbose); !system("$MAKE") or die "Error -- msi installer build failed."; #chdir("$wd\\buildnsi") or die "Fatal -- Couldn't cd to $wd\\buildnsi"; #print "Info -- *** Make NSIS:\n" if ($verbose); #print "Info -- chdir to ".`cd`."\n" if ($verbose); #!system("cl.exe killer.cpp advapi32.lib") or die "Error -- nsis killer.exe not built."; #!system("rename killer.exe Killer.exe") or die "Error -- Couldn't rename killer.exe"; #!system("makensis kfw.nsi") or die "Error -- executable installer build failed."; # Begin packaging extra items: chdir($wd) or die "Fatal -- Couldn't cd to $wd"; print "Info -- chdir to ".`cd`."\n" if ($verbose); zipXML($config->{Stages}->{PostPackage}, $config); ## Make zips. $config->{Stages}->{PostPackage}->{CopyList}->{Config} = $config->{Stages}->{PostPackage}->{Config}; ## Use the post package config. $config->{Stages}->{PostPackage}->{CopyList}->{Config}->{From}->{root} = "$src\\pismere"; $config->{Stages}->{PostPackage}->{CopyList}->{Config}->{To}->{root} = $out; copyFiles($config->{Stages}->{PostPackage}->{CopyList}, $config); ## Copy any files !system("rm -rf $wd\\buildwix") or die "Fatal -- Couldn't remove $wd\\buildwix."; !system("rm -rf $wd\\buildnsi") or die "Fatal -- Couldn't remove $wd\\buildnsi."; chdir($out) or die "Fatal -- Couldn't cd to $out"; print "Info -- chdir to ".`cd`."\n" if ($verbose); if ($odr->{sign}->{def}) { signFiles($config->{Stages}->{PostPackage}->{Config}->{Signing}, $config); } if ($verbose) {print "Info -- *** End package.\n";} } ##-- Package action. system("rm -rf $src/a.tmp"); ## Clean up junk. system("rm -rf $out/a.tmp"); ## Clean up junk. system("rm -rf $out/ziptemp"); ## Clean up junk. # End logging: if ($odr->{logfile}->{def}) {$l->stop;} return 0; } ## End subroutine main. $SIG{'INT'} = \&handler; $SIG{'QUIT'} = \&handler; exit(main()); krb5-1.16/src/windows/build/bootstrap.xml0000644000704600001450000000136413211554426020321 0ustar ghudsonlibuuid krb5-1.16/src/windows/build/sdkfiles.xml0000644000704600001450000000225413211554426020107 0ustar ghudsonlibuuid krb5-1.16/src/windows/build/tee.pl0000644000704600001450000000310113211554426016663 0ustar ghudsonlibuuid# Usage 'tee filename' # Make sure that when using this as a perl pipe you # print a EOF char! # (This may be a bug in perl 4 for NT) # # Use it like: # open(PIPE, "|$^X tee.pl foo.log") || die "Can't pipe"; # open(STDOUT, ">&PIPE") || die "Can't dup pipe to stdout"; # open(STDERR, ">&PIPE") || die "Can't dup pipe to stderr"; use IO::File; #$SIG{'INT'} = \&handler; #$SIG{'QUIT'} = \&handler; $SIG{'INT'} = 'IGNORE'; $SIG{'QUIT'} = \&handler; my $fh = new IO::File; my $arg = shift; my $file; my $access = ">"; while ($arg) { if ($arg =~ /-a/) { $access = ">>"; } elsif ($arg =~ /-i/) { $SIG{'INT'} = 'IGNORE'; $SIG{'QUIT'} = 'IGNORE'; } else { $file = $arg; last; } $arg = shift; } STDOUT->autoflush(1); if ($file) { $fh->open($access.$file) || die "Could not open $file\n"; $fh->autoflush(1); } while (<>) { $_ = &logtime.$_; print $_; print $fh $_ if $file; } sub logtime { my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time); $mon = $mon + 1; $year %= 100; sprintf ("[%02d/%02d/%02d %02d:%02d:%02d] ", $year, $mon, $mday, $hour, $min, $sec); } sub handler { my $sig = shift; my $bailmsg = &logtime."Bailing out due to SIG$sig!\n"; my $warnmsg = < krb5-1.16/src/windows/build/pruneFiles.pl0000644000704600001450000000224013211554426020225 0ustar ghudsonlibuuid#!perl -w #use strict; use Data::Dumper; sub pruneFiles { local ($xml, $config) = @_; local $prunes = $xml->{Prunes}; if (! $prunes) {return 0;} # Use Unix find instead of Windows find. Save PATH so we can restore it when we're done: local $savedPATH = $ENV{PATH}; $ENV{PATH} = $config->{Config}->{unixfind}->{value}.";".$savedPATH; print "Info -- Processing prunes in ".`cd`."\n" if ($verbose); local $pru = $prunes->{Prune}; local $files = "( "; local $bFirst = 1; while (($key, $val) = each %$pru) { local $flags = $val->{flags}; $flags = "" if (!$flags); if (!$bFirst) {$files .= " -or ";} $bFirst = 0; $files .= "-".$flags."name $key"; print "Info -- Looking for filenames matching $key\n" if ($verbose); } $files .= " )"; local $list = `find . $files`; if (length($list) > 1) { print "Info -- Pruning $list\n" if ($verbose); ! system("rm -rf $list") or die "Unable to prune $list"; } $ENV{PATH} = $savedPATH; } return 1; krb5-1.16/src/windows/build/bkw-automation.html0000644000704600001450000005253513211554426021417 0ustar ghudsonlibuuid lore-bkw-automation - Confluence
The Kerberos for Windows (KfW) build is automated.  A script will fetch the sources from a repository and then build, sign and package all the KfW distribution components.
This description consists of

Setting Up the Build Environment

KfW is built on a Windows PC, in the default Windows shell (cmd.exe). These components must be installed:

  • Visual Studio 2003
    Versions of Visual Studio before or after 2003 are not supported.
  • A recent release of the Microsoft Platform SDK  
  • ActiveState Perl 5.8 or more recent
    Build 631 is known to work.
  • Doxygen
  • sed, awk, cat, rm and find
    These can be obtained from the Cygwin distribution.

    find must be in C:\tools\cygwin\bin, so install Cygwin in C:\tools\cygwin.

    The cygwin awk is a link and the MS shell doesn't deal well with that.  C opy c:\tools\cygwin\bin\gawk to c:\tools\cygwin\bin\awk.
  • Wix
  • NSIS

Environment variables

All the components above must be in PATH. Installing ActivePerl puts perl in the PATH. Doxygen, Cygwin, hhc, wix and nsis need to be added.

perl must be installed so that .pl files are automatically executed with perl. The ActivePerl installation will do this for you.

In the INCLUDE path, the Microsoft Platform SDK must come before the Microsoft Visual C++ include files. In the PATH path, the Platform SDK bin area must come before the Visual Studio VC\bin area. Using a Platform SDK Build Environment window will set this up the right way.  Make sure to use a Platform SDK Windows XP Build Environment shell.

If you make your path modifications permanent via Control Panel / System / Advanced / Environment Variables:  If you use a Platform SDK Build Environment window, it appears that you need to put your PATH components in the System PATH, not the User PATH.

Visual Studio installs hhc in C:\Program Files\HTML Help Workshop.

nmake must be in PATH. If you use a Platform SDK build environment window, it is already done for you.

Running the Script

The build is a perl script controlled by command line switches and an XML configuration file. The config file is required. Settings in the config file can be overridden by optional command line switches. 

There are options for controlling most steps of the build process.  The steps are

  • Verifying the environment
  • Fetching the sources from repositories
  • Building the sources
  • Setting up the packaging environment
  • Building the installers
  • Building the rest of the components

The usage message shows the switches that control these steps:

C:\Projects\KfW>perl bkw.pl /?
Usage: bkw.pl [options] NMAKE-options

  Options are case insensitive.

  Options: 
  /help /?          usage information (what you now see).
  /config /f path   Path to config file. Default is bkwconfig.xml.
  /src /s dir       Source directory to use. Should contain
                    pismere/athena. If cvstag or svntag is null,
                    the directory should be prepopulated.
  /out /o dir       Directory to be created where build results will go
  /repository checkout | co \ What repository action to take.
     /r       update   | up \ Options are to checkout, update, export
              export   | ex \ or take no action [skip]. 
              skip
  /username /u name username used to access svn if checking out.
  /cvstag /c tag    use -r <tag> in cvs command
  /svnbranch /b tag use /branches/<tag> instead of /trunk.
  /svntag /t tag    use /tags/<tag> instead of /trunk.
  /debug /d         Do debug make instead of release make.
  /[no]make         Control the make step.
  /clean            Build clean target.
  /[no]package      Control the packaging step.
  /[no]sign         Control signing of executable files.
  /verbose /v       Debug mode - verbose output.
  /logfile /l path  Where to write output. Default is bkw.pl.log.
  /nolog            Don't save output.

  Other:
    NMAKE-options any options you want to pass to NMAKE, which can be:
                  (note: /nologo is always used)
                  NODEBUG=1

NMAKE-options any options you want to pass to NMAKE, which can be:
(note: /nologo is always used)
[ nmake options follow ]


Notes on the script steps:

Verifying the environment
The script tests for each program that it needs and warns if the program isn't found.

Fetching sources from repositories
If building from a source distribution kit, this section does not apply.

CVSROOT and SVNURL must be specified in the configuration file.

A source zip file can only be produced if checking out fresh sources from a repository. 

If checking out, the entire pismere directory will be deleted.  A warning message requires that you confirm this action.

Building the sources:
/DEBUG controls whether a debug or release build is done.  /CLEAN will build the CLEAN target.

Setting up the packaging environment :
The pre-package steps gathers up build results and puts them in a staging area. 

If /SIGN is specified, .exes, .dlls and .cpls are signed.  The signing command template is in the configuration file.

Building the installers:
The staging area is copied into a fresh area for each of the installers.  The installer results are copied back to the staging area.

Building the rest of the components:
Zip files are built in temporary areas and copied to outdir.  The installers and assorted files are copied from staging to outdir.  If /SIGN is specified, the installers will be signed.

 

Script Internal Details

Copy Lists

CopyLists are used in many places.  For example, files to be put into a .zip are copied to a fresh directory which is then zipped up.  There is an optional Configuration section and a required Files section. 

The configuration section defines the roots of the from and to paths and can optionally define path substitutions. 

The to and from paths are forced by the script rather than being set in the config file.  Comments in the copyfile xml indicate this.

Lengthy copy lists can be kept in separate files and included with the Include directive.  Example:

<Include path="sdkfiles.xml" />

Substitution tags

Filenames in copylists can contain variable 'tags' that are replaced before the file is copied.  Some configuration files contain substitution tags which customize the configuration.  The supported tags are

%VERSION_MAJOR% KfW Version from pismere/athena/include/kerberos.ver.
%VERSION_MINOR% KfW Version from pismere/athena/include/kerberos.ver.
%VERSION_PATCH% KfW Version from pismere/athena/include/kerberos.ver.
%filestem% Defined as kfw-%VERSION_MAJOR%-%VERSION_MINOR%-%VERSION_PATCH%.
%debug% 'dbg.'  Only substituted during a debug build. 
%release% 'rel.'  Only substituted during a release build. 
%bldtype% Always substituted, to 'dbg' or 'rel,' depending on the type of build.
%-DEBUG% '-DEBUG' during a debug build; otherwise empty.
%BUILDDIR% SRCDIR\pismere.  Used in site-local installer configuration files.
%TARGETDIR% SRCDIR\pismere\staging.  Used in site-local installer configuration files.
%CONFIGDIR-WIX% SRCDIR\pismere\staging\sample.  Used in site-local installer configuration files.
%CONFIGDIR-NSI% SRCDIR\pismere\staging.  Used in site-local installer configuration files.

The overall build configuration specifies a debug or release build.  Debug and release results are put in different places.  Files whose location depend on the build type can use %bldtype% in their names.  The script will substitute %bldtype% with either dbg or rel, depending on the build type. 

Example

Here is a copylist entry.  Each segment of the file's path that comes from a different place is in a different color.

Release build.  Config file:

<BKW_Config>
<Config>
<src value ="C:\bkw" />

Copylist comments:

<!-- File from paths are relative to \pismere\athena -->
<!-- File to paths are relative to \ pismere\staging -->

When the script processes this copylist, it will force the from and to paths as indicated.

This line

<File name="comerr32.dll" from="..\target\bin\i386\%bldtype%\" to="\bin\i386" />

will result in C:\bkw\pismere\athena\..\target\bin\i386\rel\comerr32.dll

being copied to C:\bkw\pismere\staging\bin\i386\comerr32.dll.

Other possible attributes in a copylist entry:

  • notrequired
  • newname="filename"

By default, copylist entries are required and the script will die if they aren't present. To ignore missing files, add notrequired.

To rename the file, set the newname attribute.

Remaining Work / Bug List

Implement RETAIL, OFFICIAL, PRERELEASE, PRIVATE, SPECIAL.

Figure out what MIT_ONLY, BUILD_KFW, DEBUG_SYMBOL should be.

TARGET, APPVER.

NODEBUG=1.  Set if release build.

Troubleshooting

Can't clean directory; can't delete file or directory
Make sure a file in the named directory isn't open in another application.

Can't find kerberos.ver
You skipped the repository step and are trying to build in an empty directory.

Directories don't exist or can't be created
This can be a symptom of the Platform SDK bin area not being before the Visual Studio bin areas, such that the version of nmake running is version 8.x.
[This explanation courtesy of Jeff Altman]:
nmake V8 appears to favor executables over shell commands. As a result, using 'mkdir' instead of 'md' in Makefiles, as a command for creating directory trees, fails when the Cygwin mkdir.exe is present in the PATH. Changing the

MKDIR=mkdir
RMDIR=rmdir

macros in the Makefiles to

MKDIR=md
RMDIR=rd

should make the shell versions execute in all cases.

krb5-1.16/src/windows/build/commandandcontrol.pl0000644000704600001450000001341613211554426021622 0ustar ghudsonlibuuid#!perl -w #use strict; sub commandandcontrol { local ($configdefault, $bIgnoreCmdlineConfig) = @_; local $OPT = {foo => 'bar'}; Getopt::Long::Configure('no_bundling', 'no_auto_abbrev', 'no_getopt_compat', 'require_order', 'ignore_case', 'pass_through', 'prefix_pattern=(--|-|\+|\/)' ); GetOptions($OPT, 'help|h|?', 'cvstag|c:s', 'svntag|s:s', 'svnbranch|b:s', 'src|r:s', 'out|o:s', 'debug|d', 'nodebug', 'config|f=s', 'logfile|l:s', 'nolog', 'repository:s', 'username|u:s', 'verbose|v', 'vverbose', 'make!', 'clean', 'package!', 'sign!', ); if ( $OPT->{help} ) { usage(); exit(0); } delete $OPT->{foo}; local $argvsize = @ARGV; if ($argvsize > 0) { print "Error -- invalid argument: $ARGV[0]\n"; usage(); die; } # The first time C&C is called, it is OK to override the default (./bkwconfig.xml) # with a value from the command line. # The second time C&C is called, the repository has been updated and C&C will be passed # /pismere/athena/auth/krb5/windows/build/bkwconfig.xml. That value MUST be used. if ($bIgnoreCmdlineConfig) {$OPT->{config} = $configdefault;} elsif (! exists $OPT->{config}) {$OPT->{config} = $configdefault;} my $configfile = $OPT->{config}; my $bOutputCleaned = 0; print "Info -- Reading configuration from $configfile.\n"; # Get configuration file: local $xml = new XML::Simple(); my $config = $xml->XMLin($configfile); # Set up convenience variables: local $odr = $config->{Config}; ## Options, directories, repository, environment. #while ($v = each %$OPT) {print "$v: $OPT->{$v}\n";} # Scan the configuration for switch definitions: while (($sw, $val) = each %$odr) { next if (! exists $val->{def}); ## ?? Should always exist. # Set/clear environment variables: if ($val->{env}) { if ($val->{def}) {$ENV{$sw} = (exists $val->{value}) ? $val->{value} : 1; } else {delete $ENV{$sw}; } } # If the switch is in the command line, override the stored value: if (exists $OPT->{$sw}) { if (exists $val->{value}) { $val->{value} = $OPT->{$sw}; $val->{def} = 1; } else { $val->{def} = $OPT->{$sw}; ## If no, value will be zero. } } # If the switch can be negated, test that, too: if ( ! ($val->{def} =~ /A/)) { local $nosw = "no".$sw; if (exists $OPT->{$nosw}) { $val->{def} = 0; } } # For any switch definition with fixed values ("options"), validate: if (exists $val->{options}) { local $bValid = 0; # options can be like value1|syn1 value2|syn2|syn3 foreach $option (split(/ /, $val->{options})) { local $bFirst = 1; local $sFirst; foreach $opt (split(/\|/, $option)) { # opt will be like value2, syn2, syn3 if ($bFirst) { $sFirst = $opt; ## Remember the full name of the option. $bFirst = 0; } if ($val->{value} =~ /$opt/i) { $val->{value} = $sFirst; ## Save the full name. $bValid = 1; } } } if (! $bValid) { print "Fatal -- invalid $sw value $val->{value}. Possible values are $val->{options}.\n"; usage(); die; } } } # Don't allow /svntag and /svnbranch simultaneously: if ( (length $odr->{svntag}->{value} > 0) && (length $odr->{svnbranch}->{value} > 0) ) { die "Fatal -- Can't specify both /SVNTAG and /SVNBRANCH."; } return $config; } sub usage { print < in cvs command /svnbranch /b tag use /branches/ instead of /trunk. /svntag /s tag use /tags/ instead of /trunk. /debug /d Do debug make instead of release make. /[no]make Control the make step. /clean Build clean target. /[no]package Control the packaging step. /[no]sign Control signing of executable files. /verbose /v Debug mode - verbose output. /logfile /l path Where to write output. Default is bkw.pl.log. /nolog Don't save output. Other: NMAKE-options any options you want to pass to NMAKE, which can be: (note: /nologo is always used) USAGE system("$MAKE /?"); } return 1;krb5-1.16/src/windows/build/signFiles.pl0000644000704600001450000000215213211554426020036 0ustar ghudsonlibuuid#!perl -w #use strict; use Data::Dumper; sub signFiles { local ($signing, $config) = @_; local $exprs = $signing->{FilePatterns}->{value}; local $template = $signing->{CommandTemplate}->{value}; # Use Unix find instead of Windows find. Save PATH so we can restore it when we're done: local $savedPATH= $ENV{PATH}; $ENV{PATH} = $config->{Config}->{unixfind}->{value}.";".$savedPATH; foreach $expr (split(" ", $exprs)) { ## exprs is something like "*.exe *.dll" local $cmd = "find . -iname \"$expr\""; local $list = `$cmd`; ## $list is files matching *.exe, for example. foreach $target (split("\n", $list)) { $target =~ s|/|\\|g; ## Flip path separators from unix-style to windows-style. local $template2 = $template; $template2 =~ s/%filename%/$target/; print "Info -- Signing $target\n" if ($verbose); !system("$template2") or die "Fatal -- Error signing $target."; } } $ENV{PATH} = $savedPATH; } return 1;krb5-1.16/src/windows/build/repository1.pl0000644000704600001450000001044013211554426020412 0ustar ghudsonlibuuid#!perl -w #use strict; sub repository1 { local ($config) = @_; local $odr = $config->{Config}; ## Options, directories, repository, environment. local $src = $odr->{src}->{value}; local $rverb = $odr->{repository}->{value}; local $wd = $src."\\pismere"; if ($rverb =~ /skip/) {print "Info -- *** Skipping repository access.\n" if ($verbose);} else { if ($verbose) {print "Info -- *** Begin fetching sources.\n";} local $cvspath = "$src"; if (! -d $cvspath) { ## xcopy will create the entire path for us. !system("echo foo > a.tmp") or die "Fatal -- Couldn't create temporary file in ".`cd`; !system("echo F | xcopy a.tmp $cvspath\\a.tmp") or die "Fatal -- Couldn't xcopy to $cvspath."; !system("rm a.tmp") or die "Fatal -- Couldn't remove temporary file."; !system("rm $cvspath\\a.tmp") or die "Fatal -- Couldn't remove temporary file."; } # Set up cvs environment variables: $ENV{CVSROOT} = $odr->{CVSROOT}->{value}; local $krb5dir = "$wd\\athena\\auth\\krb5"; local $cvscmdroot = "cvs $rverb"; if (length $odr->{cvstag}->{value} > 0) { $cvscmdroot .= " -r $odr->{cvstag}->{value}"; } if ($rverb =~ /checkout/) { chdir($src) or die "Fatal -- couldn't chdir to $src\n"; print "Info -- chdir to ".`cd`."\n" if ($verbose); my @cvsmodules = ( 'krb', 'pismere/athena/util/lib/delaydlls', 'pismere/athena/util/lib/getopt', 'pismere/athena/util/guiwrap' ); foreach my $module (@cvsmodules) { local $cvscmd = $cvscmdroot." ".$module; if ($verbose) {print "Info -- cvs command: $cvscmd\n";} !system($cvscmd) or die "Fatal -- command \"$cvscmd\" failed; return code $?\n"; } } else { ## Update. chdir($wd) or die "Fatal -- couldn't chdir to $wd\n"; print "Info -- chdir to ".`cd`."\n" if ($verbose); if ($verbose) {print "Info -- cvs command: $cvscmdroot\n";} !system($cvscmdroot) or die "Fatal -- command \"$cvscmdroot\" failed; return code $?\n"; } # Set up svn environment variable: $ENV{SVN_SSH} = "plink.exe"; # If the directory structure doesn't exist, many cd commands will fail. if (! -d $krb5dir) { ## xcopy will create the entire path for us. !system("echo foo > a.tmp") or die "Fatal -- Couldn't create temporary file in ".`cd`; !system("echo F | xcopy a.tmp $krb5dir\\a.tmp") or die "Fatal -- Couldn't xcopy to $krb5dir."; !system("rm a.tmp") or die "Fatal -- Couldn't remove temporary file."; !system("rm $krb5dir\\a.tmp") or die "Fatal -- Couldn't remove temporary file."; } chdir($krb5dir) or die "Fatal -- Couldn't chdir to $krb5dir"; print "Info -- chdir to ".`cd`."\n" if ($verbose); my $svncmd = "svn $rverb "; if ($rverb =~ /checkout/) { # Append the rest of the checkout command: chdir(".."); $svncmd .= "svn+ssh://".$odr->{username}->{value}."@".$odr->{SVNURL}->{value}."/krb5/"; if (length $odr->{svntag}->{value} > 0) { $svncmd .= "tags/$odr->{svntag}->{value}"; } elsif (length $odr->{svnbranch}->{value} > 0) { $svncmd .= "branches/$odr->{svnbranch}->{value}"; } else { $svncmd .= "trunk"; } $svncmd .= " krb5"; } if ($verbose) {print "Info -- svn command: $svncmd\n";} !system($svncmd) or die "Fatal -- command \"$svncmd\" failed; return code $?\n"; if ($verbose) {print "Info -- *** End fetching sources.\n";} } } return 1;krb5-1.16/src/windows/lib/0000755000704600001450000000000013211554426015225 5ustar ghudsonlibuuidkrb5-1.16/src/windows/lib/vardlg.h0000644000704600001450000000136713211554426016664 0ustar ghudsonlibuuid/* * Copyright (C) 1997 Cygnus Solutions * * Author: Michael Graff */ #ifndef _WINDOWS_LIB_VARDLG_H #define _WINDOWS_LIB_VARDLG_H #include #include #define DLG_BUF 4096 /* * The minimum and maximum dialog box widths we will allow. */ #define MIN_WIDTH 350 #define MAX_WIDTH 600 /* * "build" the dialog box. In this bit of code, we create the dialog box, * create the OK button, and a static label for the banner text. * * If there are items, we also create a Cancel button and one (label, entry) * fields for each item. */ void *vardlg_build(WORD, const char *, const char *, WORD, krb5_prompt *, WORD); void vardlg_config(HWND, WORD, const char *, WORD, krb5_prompt *, WORD); #endif /* _WINDOWS_LIB_VARDLG_H */ krb5-1.16/src/windows/lib/loadfuncs.c0000644000704600001450000000352013211554426017347 0ustar ghudsonlibuuid#define WIN32_LEAN_AND_MEAN #include #include "loadfuncs.h" // // UnloadFuncs: // // This function will reset all the function pointers of a function loaded // by LaodFuncs and will free the DLL instance provided. // void UnloadFuncs( FUNC_INFO fi[], HINSTANCE h ) { int n; if (fi) for (n = 0; fi[n].func_ptr_var; n++) *(fi[n].func_ptr_var) = NULL; if (h) FreeLibrary(h); } // // LoadFuncs: // // This function try to load the functions for a DLL. It returns 0 on failure // and non-zero on success. The parameters are descibed below. // int LoadFuncs( const char* dll_name, FUNC_INFO fi[], HINSTANCE* ph, // [out, optional] - DLL handle int* pindex, // [out, optional] - index of last func loaded (-1 if none) int cleanup, // cleanup function pointers and unload on error int go_on, // continue loading even if some functions cannot be loaded int silent // do not pop-up a system dialog if DLL cannot be loaded ) { HINSTANCE h; int i, n, last_i; int error = 0; UINT em; if (ph) *ph = 0; if (pindex) *pindex = -1; for (n = 0; fi[n].func_ptr_var; n++) *(fi[n].func_ptr_var) = NULL; if (silent) em = SetErrorMode(SEM_FAILCRITICALERRORS); h = LoadLibrary(dll_name); if (silent) SetErrorMode(em); if (!h) return 0; last_i = -1; for (i = 0; (go_on || !error) && (i < n); i++) { void* p = (void*)GetProcAddress(h, fi[i].func_name); if (!p) error = 1; else { last_i = i; *(fi[i].func_ptr_var) = p; } } if (pindex) *pindex = last_i; if (error && cleanup && !go_on) { for (i = 0; i < n; i++) { *(fi[i].func_ptr_var) = NULL; } FreeLibrary(h); return 0; } if (ph) *ph = h; if (error) return 0; return 1; } krb5-1.16/src/windows/lib/registry.h0000644000704600001450000000240413211554426017246 0ustar ghudsonlibuuid/* * Copyright (c) 1997 Cygnus Solutions * * Author: Michael Graff */ #ifndef LIB_WINDOWS_REGISTRY_H #define LIB_WINDOWS_REGISTRY_H #include #include HKEY registry_open(HKEY, char *, REGSAM); void registry_close(HKEY); HKEY registry_key_create(HKEY, char *, REGSAM); int registry_key_delete(HKEY, char *); int registry_string_get(HKEY, char *, char **); int registry_dword_get(HKEY, char *, DWORD *); int registry_string_set(HKEY, char *, char *); int registry_dword_set(HKEY, char *, DWORD); int registry_keyval_dword_set(HKEY, char *, char *, DWORD); int registry_keyval_dword_get(HKEY, char *, char *, DWORD *); int registry_keyval_string_get(HKEY, char *, char *, char **); int registry_keyval_string_set(HKEY, char *, char *, char *); int registry_value_delete(HKEY, char *); int registry_keyval_delete(HKEY, char *, char *); #define CYGNUS_SOLUTIONS "SOFTWARE\\Cygnus Solutions" #define KERBNET_SANS_VERSION CYGNUS_SOLUTIONS "\\Kerbnet" #define KERBNET_BASE KERBNET_SANS_VERSION "\\1" #define KERBNET_TELNET_BASE KERBNET_BASE "\\telnet" #define KERBNET_TELNET_HOST KERBNET_TELNET_BASE "\\hosts" #define KERBNET_CNS_BASE KERBNET_BASE "\\cns" #define KERBNET_HOME "KERBNET_HOME" #endif /* LIB_WINDOWS_REGISTRY_H */ krb5-1.16/src/windows/lib/registry.c0000644000704600001450000000716413211554426017251 0ustar ghudsonlibuuid/* * Copyright (c) 1997 Cygnus Solutions * * Author: Michael Graff */ #include #include #include #include "registry.h" HKEY registry_open(HKEY hkey, char *base, REGSAM sam) { HKEY k = INVALID_HANDLE_VALUE; DWORD err; /* * if the base path is null, return the already open key in hkey */ if (base == NULL) return hkey; err = RegOpenKeyEx(hkey, base, 0, sam, &hkey); if (err != ERROR_SUCCESS) return INVALID_HANDLE_VALUE; return hkey; } void registry_close(HKEY hkey) { CloseHandle(hkey); } HKEY registry_key_create(HKEY hkey, char *sub, REGSAM sam) { HKEY key; DWORD err; DWORD disp; err = RegCreateKeyEx(hkey, sub, 0, 0, REG_OPTION_NON_VOLATILE, sam, NULL, &key, &disp); if (err != ERROR_SUCCESS) return INVALID_HANDLE_VALUE; return key; } int registry_key_delete(HKEY hkey, char *sub) { DWORD err; err = RegDeleteKey(hkey, sub); if (err != ERROR_SUCCESS) return -1; return 0; } int registry_string_get(HKEY hkey, char *sub, char **val) { DWORD err; DWORD type; DWORD datasize; err = RegQueryValueEx(hkey, sub, 0, &type, 0, &datasize); if (err != ERROR_SUCCESS || type != REG_SZ) { *val = NULL; return -1; } *val = malloc(datasize); if (*val == NULL) return -1; err = RegQueryValueEx(hkey, sub, 0, &type, *val, &datasize); if (err != ERROR_SUCCESS) { free(*val); *val = NULL; return -1; } return 0; } int registry_dword_get(HKEY hkey, char *sub, DWORD *val) { DWORD err; DWORD type; DWORD datasize; err = RegQueryValueEx(hkey, sub, 0, &type, 0, &datasize); if (err != ERROR_SUCCESS || type != REG_DWORD) { *val = 0; return -1; } err = RegQueryValueEx(hkey, sub, 0, &type, (BYTE *)val, &datasize); if (err != ERROR_SUCCESS) { *val = 0; return -1; } return 0; } int registry_string_set(HKEY hkey, char *sub, char *x) { DWORD err; err = RegSetValueEx(hkey, sub, 0, REG_SZ, (BYTE *)x, (DWORD)strlen(x) + 1); if (err != ERROR_SUCCESS) return -1; return 0; } int registry_dword_set(HKEY hkey, char *sub, DWORD x) { DWORD err; err = RegSetValueEx(hkey, sub, 0, REG_DWORD, (CONST BYTE *)&x, sizeof(DWORD)); if (err != ERROR_SUCCESS) return -1; return 0; } int registry_keyval_dword_set(HKEY hkey, char *base, char *sub, DWORD val) { HKEY k; int err; k = registry_open(hkey, base, KEY_WRITE); if (k == INVALID_HANDLE_VALUE) return -1; err = registry_dword_set(k, sub, val); registry_close(k); return err; } int registry_keyval_dword_get(HKEY hkey, char *base, char *sub, DWORD *val) { HKEY k; int err; k = registry_open(hkey, base, KEY_READ); if (k == INVALID_HANDLE_VALUE) return -1; err = registry_dword_get(k, sub, val); registry_close(k); return err; } int registry_keyval_string_get(HKEY hkey, char *base, char *sub, char **val) { HKEY k; int err; k = registry_open(hkey, base, KEY_READ); if (k == INVALID_HANDLE_VALUE) { *val = NULL; return -1; } err = registry_string_get(k, sub, val); registry_close(k); return err; } int registry_keyval_string_set(HKEY hkey, char *base, char *sub, char *val) { HKEY k; int err; k = registry_open(hkey, base, KEY_WRITE); if (k == INVALID_HANDLE_VALUE) return -1; err = registry_string_set(k, sub, val); registry_close(k); return err; } int registry_value_delete(HKEY hkey, char *sub) { if (RegDeleteValue(hkey, sub)) return -1; return 0; } int registry_keyval_delete(HKEY hkey, char *base, char *sub) { HKEY k; int err; k = registry_open(hkey, base, KEY_WRITE); if (k == INVALID_HANDLE_VALUE) return -1; err = registry_value_delete(k, sub); registry_close(k); return err; } krb5-1.16/src/windows/lib/vardlg.c0000644000704600001450000002506713211554426016662 0ustar ghudsonlibuuid/* * Copyright (C) 1997 Cygnus Solutions. * * Author: Michael Graff */ /* * Dialog box building for various numbers of (label, entry) fields. * * This code is somewhat hardcoded to build boxes for the krb5_get_init_creds() * function. */ #include #include #include #include #include #include "krb5.h" #include "vardlg.h" /* * a hack, I know... No error checking below, either. */ static unsigned char dlg[DLG_BUF]; /* * Add a WORD (16-bit int) to the buffer. Return the number of characters * added. */ static int ADD_WORD(unsigned char *p, WORD w) { *((WORD *)p) = w; return 2; } static int ADD_DWORD(unsigned char *p, DWORD dw) { *((DWORD *)p) = dw; return 4; } static size_t ADD_UNICODE_STRING(unsigned char *p, const char *s) { WORD *w; size_t i; size_t len; w = (WORD *)p; len = strlen(s) + 1; /* copy the null, too */ for (i = 0 ; i < len ; i++) *w++ = *s++; return (len * 2); } #define DWORD_ALIGN(p) { while ((DWORD)p % 4) *p++ = 0x00; } static size_t ADD_DLGTEMPLATE(unsigned char *dlg, short x, short y, short cx, short cy, const char *caption, const char *fontname, WORD fontsize, WORD n) { unsigned char *p; DLGTEMPLATE dlt; p = dlg; dlt.style = (DS_MODALFRAME | WS_POPUP); if (caption != NULL) dlt.style |= WS_CAPTION; if (fontname != NULL) dlt.style |= DS_SETFONT; dlt.dwExtendedStyle = 0; dlt.cdit = n; dlt.x = x; dlt.y = y; dlt.cx = cx; dlt.cy = cy; memcpy(p, &dlt, sizeof(dlt)); p += sizeof(dlt); p += ADD_WORD(p, 0x0000); /* menu == none */ p += ADD_WORD(p, 0x0000); /* class == default? */ if (caption != NULL) p += ADD_UNICODE_STRING(p, caption); else p += ADD_WORD(p, 0x0000); if (fontname != NULL) { p += ADD_WORD(p, fontsize); p += ADD_UNICODE_STRING(p, fontname); } DWORD_ALIGN(p); return (p - dlg); } static size_t ADD_DLGITEM(unsigned char *dlg, short x, short y, short cx, short cy, const char *label, WORD id, WORD type, DWORD style) { unsigned char *p; DLGITEMTEMPLATE dit; p = dlg; dit.style = style; dit.dwExtendedStyle = 0; dit.x = x; dit.y = y; dit.cx = cx; dit.cy = cy; dit.id = id; memcpy(p, &dit, sizeof(dit)); p += sizeof(dit); p += ADD_WORD(p, 0xffff); p += ADD_WORD(p, type); p += ADD_UNICODE_STRING(p, label); /* * creation data? For now, just make this empty, like the resource * compiler does. */ p += ADD_WORD(p, 0x0000); DWORD_ALIGN(p); return (p - dlg); } #define ADD_DLGITEM_defpushbutton(a, b, c, d, e, f, g) \ ADD_DLGITEM((a), (b), (c), (d), (e), (f), (g), 0x0080, 0x50010001); #define ADD_DLGITEM_pushbutton(a, b, c, d, e, f, g) \ ADD_DLGITEM((a), (b), (c), (d), (e), (f), (g), 0x0080, 0x50010000); #define ADD_DLGITEM_left_static(a, b, c, d, e, f, g) \ ADD_DLGITEM((a), (b), (c), (d), (e), (f), (g), 0x0082, 0x50020000); #define ADD_DLGITEM_centered_static(a, b, c, d, e, f, g) \ ADD_DLGITEM((a), (b), (c), (d), (e), (f), (g), 0x0082, 0x50020001); #define ADD_DLGITEM_right_static(a, b, c, d, e, f, g) \ ADD_DLGITEM((a), (b), (c), (d), (e), (f), (g), 0x0082, 0x50020002); #define ADD_DLGITEM_entry(a, b, c, d, e, f, g) \ ADD_DLGITEM((a), (b), (c), (d), (e), (f), (g), 0x0081, 0x50810080); #define ADD_DLGITEM_hidden_entry(a, b, c, d, e, f, g) \ ADD_DLGITEM((a), (b), (c), (d), (e), (f), (g), 0x0081, 0x508100a0); /* * "build" the dialog box. In this bit of code, we create the dialog box, * create the OK button, and a static label for the banner text. * * If there are items, we also create a Cancel button and one (label, entry) * fields for each item. */ void * vardlg_build(WORD cx, const char *name, const char *banner, WORD n, krb5_prompt prompts[], WORD id) { unsigned char *p; WORD i; p = dlg; /* global */ if (cx < MIN_WIDTH) cx = MIN_WIDTH; if (cx > MAX_WIDTH) cx = MAX_WIDTH; /* * Store the dialog template */ p += ADD_DLGTEMPLATE(p, 0, 0, cx, 0, name ? strlen(name) < 30 ? name : "Kerberos V5" : "Kerberos V5", "MS Sans Serif", 8, (WORD)(n * 2 + 3)); /* * Create a label for the banner. This will be ID (id). */ p += ADD_DLGITEM_left_static(p, 0, 0, 0, 0, "", id++); /* * Each label field is ID (id + 1) + (item * 2), and each entry field * is (id + 2) + (item * 2) */ for (i = 0 ; i < n ; i++) { p += ADD_DLGITEM_right_static(p, 0, 0, 0, 0, "", id++); if (prompts[i].hidden) { p += ADD_DLGITEM_hidden_entry(p, 0, 0, 0, 0, "", id++); } else { p += ADD_DLGITEM_entry(p, 0, 0, 0, 0, "", id++); } } /* * Create the OK and Cancel buttons. */ p += ADD_DLGITEM_defpushbutton(p, 0, 0, 0, 0, "OK", IDOK); if (n != 0) p += ADD_DLGITEM_pushbutton(p, 0, 0, 0, 0, "Cancel", IDCANCEL); return dlg; } #define SPACE_Y 4 /* logical units */ #define SPACE_X 4 /* logical units */ #define ENTRY_PX 120 /* pixels */ #define BUTTON_PX 70 /* pixels */ #define BUTTON_PY 30 /* pixels */ void vardlg_config(HWND hwnd, WORD width, const char *banner, WORD num_prompts, krb5_prompt *prompts, WORD id) { int n; WORD cid; HDC hdc; SIZE csize; SIZE maxsize; LONG cx, cy; LONG ccx, ccy; LONG space_x, space_y; LONG max_x, max_y; LONG banner_y; RECT rect; int done; const char *p; /* * First, set the banner's text. */ Static_SetText(GetDlgItem(hwnd, id), banner); /* * Next, run through the items and set their static text. * Also, set the corresponding edit string and set the * maximum input length. */ cid = (id + 1); for (n = 0 ; n < num_prompts ; n++) { Static_SetText(GetDlgItem(hwnd, cid), prompts[n].prompt); cid++; Edit_SetText(GetDlgItem(hwnd, cid), ""); Edit_LimitText(GetDlgItem(hwnd, cid), prompts[n].reply->length); cid++; } /* * Now run through the entry fields and find the longest string. */ maxsize.cx = maxsize.cy = 0; cid = (id + 1); hdc = GetDC(GetDlgItem(hwnd, cid)); /* assume one label is the same as all the others */ for (n = 0 ; n < num_prompts ; n++) { GetTextExtentPoint32(hdc, prompts[n].prompt, (int)strlen(prompts[n].prompt), &csize); if (csize.cx > maxsize.cx) maxsize.cx = csize.cx; if (csize.cy > maxsize.cy) maxsize.cy = csize.cy; } #if 0 /* * convert the maximum values into pixels. Ugh. */ rect.left = 0; rect.top = 0; rect.right = maxsize.cx; rect.bottom = maxsize.cy; MapDialogRect(hwnd, &rect); max_x = rect.right; max_y = rect.bottom; #else max_x = maxsize.cx; max_y = (long)(((double)maxsize.cy) * 1.5); #endif /* * convert the spacing values, too. Ugh. Ugh. */ rect.left = 0; rect.top = 0; rect.right = SPACE_X; rect.bottom = SPACE_Y; MapDialogRect(hwnd, &rect); space_x = rect.right; space_y = rect.bottom; /* * Now we know the maximum length of the string for the entry labels. Guestimate * that the entry fields should be ENTRY_PX pixels long and resize the dialog * window to fit the longest string plus the entry fields (plus a little for the * spacing between the edges of the windows and the static and edit fields, and * between the static and edit fields themselves.) */ cx = max_x + ENTRY_PX + (space_x * 3); cy = (max_y + space_y) * num_prompts; /* * resize the dialog box itself (take 1) */ SetWindowPos(hwnd, HWND_TOPMOST, 0, 0, cx + 10, cy + 30, SWP_NOMOVE); /* * position the dialog items. First, the banner. (take 1) */ SetWindowPos(GetDlgItem(hwnd, id), HWND_BOTTOM, space_x, space_y, (cx - space_x * 2), max_y, 0); /* * Now that the window for the banner is in place, convert the width into logical units * and find out how many lines we need to reserve room for. */ done = 0; p = banner; banner_y = 0; do { int nFit; int pDx[128]; hdc = GetDC(GetDlgItem(hwnd, id)); GetTextExtentExPoint(hdc, p, (int)strlen(p), cx, &nFit, pDx, &csize); banner_y += csize.cy; p += nFit; } while (*p != 0); banner_y += space_y; /* * position the banner (take 2) */ SetWindowPos(GetDlgItem(hwnd, id), HWND_BOTTOM, space_x, space_y, (cx - space_x * 2), banner_y, 0); /* * Don't forget to include the banner estimate and the buttons, too. Once again, * assume the buttons are BUTTON_PY pixels high. The extra three space_y's are * for between the top of the dialog and the banner, between the banner and the * first label, and between the buttons and the bottom of the screen. */ cy += banner_y + BUTTON_PY + (space_y * 3); /* * resize the dialog box itself (Again... ugh!) */ SetWindowPos(hwnd, HWND_TOPMOST, 0, 0, cx + 10, cy + 30, SWP_NOMOVE); cid = (id + 1); ccy = banner_y + (space_y * 2); ccx = max_x + (space_x * 2); /* where the edit fields start */ for (n = 0 ; n < num_prompts ; n++) { SetWindowPos(GetDlgItem(hwnd, cid), HWND_BOTTOM, space_x, ccy, max_x, max_y, 0); cid++; SetWindowPos(GetDlgItem(hwnd, cid), HWND_BOTTOM, ccx, ccy, ENTRY_PX, max_y - 3, 0); cid++; ccy += (max_y + space_y); } /* * Now the buttons. If there are any entries we will have both an OK and a * Cancel button. If we don't have any entries, we will have only an OK. */ if (num_prompts == 0) { SetWindowPos(GetDlgItem(hwnd, IDOK), HWND_BOTTOM, (cx / 2), cy - space_y - BUTTON_PY, BUTTON_PX, BUTTON_PY, 0); } else { SetWindowPos(GetDlgItem(hwnd, IDOK), HWND_BOTTOM, space_x, cy - space_y - BUTTON_PY, BUTTON_PX, BUTTON_PY, 0); SetWindowPos(GetDlgItem(hwnd, IDCANCEL), HWND_BOTTOM, cx - space_x - BUTTON_PX, cy - space_y - BUTTON_PY, BUTTON_PX, BUTTON_PY, 0); } return; } /* * To use these functions, first create the dialog box and entries. * You will always get an OK button. If there are at least one item, * you will also get a cancel button. The OK button is IDOK, and the cancel * button is IDCANCEL, as usual. * * After calling bld_dlg, the banner will have ID "id", and the labels * will be "1 + id + i * 2" (i is the entry number, starting with zero) and * the entries will be "2 + id + i * 2". * * unsigned char *dlg = vardlg_build(minwidth, banner, num_prompts, * krb5_prompt[], id); * * Then, "run" the dialog using: * * rc = DialogBoxIndirect(hinstance, (LPDLGTEMPLATE)dlg, * HWND_DESKTOP, myDialogProc); * * Note that the vardlg_build function uses a static data area and so cannot * be used more than once before the DialogBoxIndirect() procedure is called. * I assume windows won't need that area after that call is complete. * * In the dialog's _initialization_ procedure, call * * vardlg_config(hwnd, banner, num_prompts, krb5_prompt[], id); * * This function will resize the various elements of the dialog and fill in the * labels. */ krb5-1.16/src/windows/lib/gic.c0000644000704600001450000000645713211554426016147 0ustar ghudsonlibuuid/* * Copyright (C) 1997 Cygnus Solutions. * * Author: Michael Graff */ #include #include #include #include #include #include "krb5.h" #include "vardlg.h" #include "gic.h" /* * Steps performed: * * 1) Create the dialog with all the windows we will need * later. This is done by calling vardlg_build() from * gic_prompter(). * * 2) Run the dialog from within gic_prompter(). If the return * value of the dialog is -1 or IDCANCEL, return an error. * Otherwise, return success. * * 3) From within the dialog initialization code, call * vardlg_config(), which will: * * a) Set all the label strings in all the entry labels and * the banner. * * b) Set the maximum input lengths on the entry fields. * * c) Calculate the size of the text used within the banner. * * d) Calculate the longest string of text used as a label. * * e) Resize each label and each entry within the dialog * to "look nice." * * f) Place the OK and perhaps the Cancel buttons at the bottom * of the dialog. * * 4) When the OK button is clicked, copy all the values from the * input fields and store them in the pointers we are given. * Also, set the actual lengths to what we collected from the * entries. Finally, call EndDialog(IDOK) to end the dialog. */ /* * Yes, a global. It is a PITA to not use them in windows. */ gic_data *gd; /* * initialize the dialog */ static BOOL gic_dialog_init(HWND hwnd, HWND hwndFocus, LPARAM lParam) { vardlg_config(hwnd, gd->width, gd->banner, gd->num_prompts, gd->prompts, (WORD)(gd->id)); return FALSE; } /* * process dialog "commands" */ static void gic_dialog_command(HWND hwnd, int cid, HWND hwndCtl, UINT codeNotify) { int n; WORD id; /* * We are only interested in button clicks, and then only of * type IDOK or IDCANCEL. */ if (codeNotify != BN_CLICKED) return; if (cid != IDOK && cid != IDCANCEL) return; /* * If we are canceled, wipe all the fields and return IDCANCEL. */ if (cid == IDCANCEL) { EndDialog(hwnd, IDCANCEL); return; } /* * must be IDOK... */ id = (gd->id + 2); for (n = 0 ; n < gd->num_prompts ; n++) { Edit_GetText(GetDlgItem(hwnd, id), gd->prompts[n].reply->data, gd->prompts[n].reply->length); gd->prompts[n].reply->length = (unsigned)strlen(gd->prompts[n].reply->data); id += 2; } EndDialog(hwnd, IDOK); } /* * The dialog callback. */ static INT_PTR CALLBACK gic_dialog(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { switch (message) { HANDLE_MSG(hwnd, WM_INITDIALOG, gic_dialog_init); HANDLE_MSG(hwnd, WM_COMMAND, gic_dialog_command); } return FALSE; } /* * All the disgusting code to use the get_init_creds() functions in a * broken environment */ krb5_error_code KRB5_CALLCONV gic_prompter(krb5_context ctx, void *data, const char *name, const char *banner, int num_prompts, krb5_prompt prompts[]) { int rc; void *dlg; gd = data; gd->banner = banner; gd->num_prompts = num_prompts; gd->prompts = prompts; if (gd->width == 0) gd->width = 450; dlg = vardlg_build((WORD)(gd->width), name, gd->banner, (WORD)num_prompts, prompts, (WORD)(gd->id)); rc = DialogBoxIndirect(gd->hinstance, (LPDLGTEMPLATE)dlg, gd->hwnd, gic_dialog); if (rc != IDOK) return 1; return 0; } krb5-1.16/src/windows/lib/cacheapi.h0000644000704600001450000003243713211554426017144 0ustar ghudsonlibuuid/* windows/lib/cacheapi.h */ /* * Copyright 1997 by the Regents of the University of Michigan * * This software is being provided to you, the LICENSEE, by the * Regents of the University of Michigan (UM) under the following * license. By obtaining, using and/or copying this software, you agree * that you have read, understood, and will comply with these terms and * conditions: * * Permission to use, copy, modify and distribute this software and its * documentation for any purpose and without fee or royalty is hereby * granted, provided that you agree to comply with the following copyright * notice and statements, including the disclaimer, and that the same * appear on ALL copies of the software and documentation, including * modifications that you make for internal use or for distribution: * * Copyright 1997 by the Regents of the University of Michigan. * All rights reserved. * * THIS SOFTWARE IS PROVIDED "AS IS", AND UM MAKES NO REPRESENTATIONS * OR WARRANTIES, EXPRESS OR IMPLIED. By way of example, but not * limitation, UM MAKES NO REPRESENTATIONS OR WARRANTIES OF MERCHANTABILITY * OR FITNESS FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF THE LICENSED * SOFTWARE OR DOCUMENTATION WILL NOT INFRINGE ANY THIRD PARTY PATENTS, * COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS. * * The name of the University of Michigan or UM may NOT be used in * advertising or publicity pertaining to distribution of the software. * Title to copyright in this software and any associated documentation * shall at all times remain with UM, and USER agrees to preserve same. * * The University of Michigan * c/o Steve Rothwell * 535 W. William Street * Ann Arbor, Michigan 48013-4943 * U.S.A. */ /* ** CacheAPI.h ** ** The externally visible functions and data structures ** for the Kerberos Common Cache DLL ** This should be the ONLY externally visible file. ** This is ALL anyone should need to call the API. ** ** */ #ifndef Krb_CCacheAPI_h_ #define Krb_CCacheAPI_h_ #include //typedef int cc_int32; #define cc_int32 long #define cc_uint32 unsigned long typedef cc_int32 cc_time_t; #define CC_API_VER_1 1 #define CC_API_VER_2 2 //enum { // CC_API_VER_1 = 1, // CC_API_VER_2 = 2 //}; #define CCACHE_API __declspec(dllexport) cc_int32 /* ** The Official Error Codes */ #define CC_NOERROR 0 #define CC_BADNAME 1 #define CC_NOTFOUND 2 #define CC_END 3 #define CC_IO 4 #define CC_WRITE 5 #define CC_NOMEM 6 #define CC_FORMAT 7 #define CC_LOCKED 8 #define CC_BAD_API_VERSION 9 #define CC_NO_EXIST 10 #define CC_NOT_SUPP 11 #define CC_BAD_PARM 12 #define CC_ERR_CACHE_ATTACH 13 #define CC_ERR_CACHE_RELEASE 14 #define CC_ERR_CACHE_FULL 15 #define CC_ERR_CRED_VERSION 16 /* ** types, structs, & constants */ // Flag bits promised by Ted "RSN" #define CC_FLAGS_RESERVED 0xFFFFFFFF typedef cc_uint32 cc_nc_flags; // set via constants above typedef struct opaque_dll_control_block_type* apiCB; typedef struct opaque_ccache_pointer_type* ccache_p; typedef struct opaque_credential_iterator_type* ccache_cit; #if 0 enum _cc_data_type { type_ticket = 0, /* 0 for ticket, second_ticket */ /* Ted's draft spec says these are to be "as defined in the Kerberos V5 protocol" all I can find are typdefs, can't find an enumerated type or #define */ type_address, /* = <"as defined in the Kerberos V5 protocol"> */ type_authdata, /* = <"as defined in the Kerberos V5 protocol"> */ type_encryption, /* = <"as defined in the Kerberos V5 protocol"> */ cc_data_type_max /* for validation */ }; #endif typedef struct _cc_data { cc_uint32 type; // should be one of _cc_data_type cc_uint32 length; unsigned char* data; // the proverbial bag-o-bits } cc_data; // V5 Credentials typedef struct _cc_creds { char* client; char* server; cc_data keyblock; cc_time_t authtime; cc_time_t starttime; cc_time_t endtime; cc_time_t renew_till; cc_uint32 is_skey; cc_uint32 ticket_flags; cc_data ** addresses; cc_data ticket; cc_data second_ticket; cc_data ** authdata; } cc_creds; // begin V4 stuff // use an enumerated type so all callers infer the same meaning // these values are what krbv4win uses internally. #define STK_AFS 0 #define STK_DES 1 // K4 uses a MAX_KTXT_LEN of 1250 to hold a ticket // K95 uses 256 // To be safe I'll use the larger number, but a factor of 5!!! #define MAX_V4_CRED_LEN 1250 // V4 Credentials enum { KRB_NAME_SZ = 40, KRB_INSTANCE_SZ = 40, KRB_REALM_SZ = 40 }; typedef struct cc_V4credential { unsigned char kversion; char principal[KRB_NAME_SZ + 1]; char principal_instance[KRB_INSTANCE_SZ + 1]; char service[KRB_NAME_SZ + 1]; char service_instance[KRB_INSTANCE_SZ + 1]; char realm[KRB_REALM_SZ + 1]; unsigned char session_key[8]; cc_int32 kvno; // k95 used BYTE skvno cc_int32 str_to_key; // k4 infers dynamically, k95 stores long issue_date; // k95 called this issue_time cc_int32 lifetime; // k95 used LONG expiration_time cc_uint32 address; // IP Address of local host cc_int32 ticket_sz; // k95 used BYTE, k4 ktext uses int to hold up to 1250 unsigned char ticket[MAX_V4_CRED_LEN]; unsigned long oops; // zero to catch runaways } V4Cred_type; enum { CC_CRED_VUNKNOWN = 0, // For validation CC_CRED_V4 = 1, CC_CRED_V5 = 2, CC_CRED_VMAX = 3 // For validation }; typedef union cred_ptr_union_type { V4Cred_type* pV4Cred; cc_creds* pV5Cred; } cred_ptr_union; typedef struct cred_union_type { cc_int32 cred_type; cred_ptr_union cred; } cred_union; typedef struct _infoNC { char* name; char* principal; cc_int32 vers; } infoNC; /* ** The official (externally visible) API */ #ifdef __cplusplus extern "C" /* this entire list of functions */ { #endif /* __cplusplus */ /* ** Main cache routines : initialize, shutdown, get_cache_names, & get_change_time */ CCACHE_API cc_initialize( apiCB** cc_ctx, // < DLL's primary control structure. // returned here, passed everywhere else cc_int32 api_version, // > ver supported by caller (use CC_API_VER_1) cc_int32* api_supported, // < if ~NULL, max ver supported by DLL const char** vendor // < if ~NULL, vendor name in read only C string ); CCACHE_API cc_shutdown( apiCB** cc_ctx // <> DLL's primary control structure. NULL after call. ); CCACHE_API cc_get_change_time( apiCB* cc_ctx, // > DLL's primary control structure cc_time_t* time // < time of last change to main cache ); /* ** Named Cache (NC) routines ** create, open, close, destroy, get_principal, get_cred_version, & ** lock_request ** ** Multiple NCs are allowed within the main cache. Each has a Name ** and kerberos version # (V4 or V5). Caller gets "ccache_ptr"s for ** NCs. */ CCACHE_API cc_create( apiCB* cc_ctx, // > DLL's primary control structure const char* name, // > name of cache to be [destroyed if exists, then] created const char* principal, cc_int32 vers, // > ticket version (CC_CRED_V4 or CC_CRED_V5) cc_uint32 cc_flags, // > options ccache_p** ccache_ptr // < NC control structure ); CCACHE_API cc_open( apiCB* cc_ctx, // > DLL's primary control structure const char* name, // > name of pre-created cache cc_int32 vers, // > ticket version (CC_CRED_V4 or CC_CRED_V5) cc_uint32 cc_flags, // > options ccache_p** ccache_ptr // < NC control structure ); CCACHE_API cc_close( apiCB* cc_ctx, // > DLL's primary control structure ccache_p** ccache_ptr // <> NC control structure. NULL after call. ); CCACHE_API cc_destroy( apiCB* cc_ctx, // > DLL's primary control structure ccache_p** ccache_ptr // <> NC control structure. NULL after call. ); /* ** Ways to get information about the NCs */ CCACHE_API cc_seq_fetch_NCs_begin( apiCB* cc_ctx, ccache_cit** itNCs ); CCACHE_API cc_seq_fetch_NCs_end( apiCB* cc_ctx, ccache_cit** itNCs ); CCACHE_API cc_seq_fetch_NCs_next( apiCB* cc_ctx, ccache_p** ccache_ptr, ccache_cit* itNCs ); CCACHE_API cc_seq_fetch_NCs( apiCB* cc_ctx, // > DLL's primary control structure ccache_p** ccache_ptr, // < NC control structure (free via cc_close()) ccache_cit** itNCs // <> iterator used by DLL, // set to NULL before first call // returned NULL at CC_END ); CCACHE_API cc_get_NC_info( apiCB* cc_ctx, // > DLL's primary control structure struct _infoNC*** ppNCi // < (NULL before call) null terminated, // list of a structs (free via cc_free_infoNC()) ); CCACHE_API cc_free_NC_info( apiCB* cc_ctx, struct _infoNC*** ppNCi // < free list of structs returned by // cc_get_cache_names(). set to NULL on return ); /* ** Functions that provide distinguishing characteristics of NCs. */ CCACHE_API cc_get_name( apiCB* cc_ctx, // > DLL's primary control structure const ccache_p* ccache_ptr, // > NC control structure char** name // < name of NC associated with ccache_ptr // (free via cc_free_name()) ); CCACHE_API cc_set_principal( apiCB* cc_ctx, // > DLL's primary control structure const ccache_p* ccache_pointer, // > NC control structure const cc_int32 vers, const char* principal // > name of principal associated with NC // Free via cc_free_principal() ); CCACHE_API cc_get_principal( apiCB* cc_ctx, // > DLL's primary control structure const ccache_p* ccache_pointer, // > NC control structure char** principal // < name of principal associated with NC // Free via cc_free_principal() ); CCACHE_API cc_get_cred_version( apiCB* cc_ctx, // > DLL's primary control structure const ccache_p* ccache_ptr, // > NC control structure cc_int32* vers // < ticket version associated with NC ); #define CC_LOCK_UNLOCK 1 #define CC_LOCK_READER 2 #define CC_LOCK_WRITER 3 #define CC_LOCK_NOBLOCK 16 CCACHE_API cc_lock_request( apiCB* cc_ctx, // > DLL's primary control structure const ccache_p* ccache_ptr, // > NC control structure const cc_int32 lock_type // > one (or combination) of above defined // lock types ); /* ** Credentials routines (work within an NC) ** store, remove_cred, seq_fetch_creds */ CCACHE_API cc_store( apiCB* cc_ctx, // > DLL's primary control structure ccache_p* ccache_ptr, // > NC control structure const cred_union creds // > credentials to be copied into NC ); CCACHE_API cc_remove_cred( apiCB* cc_ctx, // > DLL's primary control structure ccache_p* ccache_ptr, // > NC control structure const cred_union cred // > credentials to remove from NC ); CCACHE_API cc_seq_fetch_creds( apiCB* cc_ctx, // > DLL's primary control structure const ccache_p* ccache_ptr, // > NC control structure cred_union** creds, // < filled in by DLL, free via cc_free_creds() ccache_cit** itCreds // <> iterator used by DLL, set to NULL // before first call -- Also NULL for final // call if loop ends before CC_END ); CCACHE_API cc_seq_fetch_creds_begin( apiCB* cc_ctx, const ccache_p* ccache_ptr, ccache_cit** itCreds ); CCACHE_API cc_seq_fetch_creds_end( apiCB* cc_ctx, ccache_cit** itCreds ); CCACHE_API cc_seq_fetch_creds_next( apiCB* cc_ctx, cred_union** cred, ccache_cit* itCreds ); /* ** methods of liberation, ** or freeing space via the free that goes with the malloc used to get it ** It's important to use the free carried in the DLL, not the one supplied ** by your compiler vendor. ** ** freeing a NULL pointer is not treated as an error */ CCACHE_API cc_free_principal( apiCB* cc_ctx, // > DLL's primary control structure char** principal // <> ptr to principal to be freed, returned as NULL // (from cc_get_principal()) ); CCACHE_API cc_free_name( apiCB* cc_ctx, // > DLL's primary control structure char** name // <> ptr to name to be freed, returned as NULL // (from cc_get_name()) ); CCACHE_API cc_free_creds( apiCB* cc_ctx, // > DLL's primary control structure cred_union** pCred // <> cred (from cc_seq_fetch_creds()) to be freed // Returned as NULL. ); #ifdef __cplusplus } /* end extern "C" */ #endif /* __cplusplus */ #endif /* Krb_CCacheAPI_h_ */ krb5-1.16/src/windows/lib/gic.h0000644000704600001450000000140313211554426016136 0ustar ghudsonlibuuid/* * Copyright (C) 1997 Cygnus Solutions * * Author: Michael Graff */ #ifndef _WINDOWS_LIB_GIC_H #define _WINDOWS_LIB_GIC_H #include #include #include "krb5.h" typedef struct { HINSTANCE hinstance; /* application instance */ HWND hwnd; /* parent window */ WORD id; /* starting ID */ WORD width; /* max width of the dialog box */ const char *banner; /* the banner */ WORD num_prompts; /* the number of prompts we were passed */ krb5_prompt *prompts; /* the prompts themselves */ } gic_data; krb5_error_code KRB5_CALLCONV gic_prompter(krb5_context, void *, const char *, const char *, int, krb5_prompt []); #endif /* _WINDOWS_LIB_GIC_H */ krb5-1.16/src/windows/lib/Makefile.in0000644000704600001450000000066713211554426017303 0ustar ghudsonlibuuidBUILDTOP = ..\.. LOCALINCLUDES = -I$(BUILDTOP)\windows\include lib-windows: $(OUTPRE)libwin.lib SRCS= vardlg.c gic.c registry.c loadfuncs.c OBJS= $(OUTPRE)vardlg.obj $(OUTPRE)gic.obj $(OUTPRE)registry.obj \ $(OUTPRE)loadfuncs.obj $(OUTPRE)libwin.lib: $(OBJS) lib /nologo /out:$*.lib $(OBJS) all-windows: lib-windows clean-windows:: $(RM) $(OUTPRE)*.exp $(OUTPRE)*.map $(OUTPRE)libwin.lib $(OUTPRE)*.obj install-windows: krb5-1.16/src/windows/wintel/0000755000704600001450000000000013211554426015761 5ustar ghudsonlibuuidkrb5-1.16/src/windows/wintel/ncsa.ico0000644000704600001450000000137613211554426017410 0ustar ghudsonlibuuid ( @p??krb5-1.16/src/windows/wintel/ktelnet.doc0000644000704600001450000004000013211554426020110 0ustar ghudsonlibuuidࡱ> ܥhc ez S"j222`*!i:::::: E Q9L {!X!!Y ::YY!5::555Y::ե,J,FJY55# $ K + Contents The following Help Topics are available: Choosing a Host and PortChoosing_a_Host_and_Port Configuring Kerb*Net Telnet for WindowsConfiguring_Kerb_Net_Telnet_for_Windows Copying and PastingCopying_and_Pasting For Help on Help, press F1 # $ K + Choosing a Host and Port When you first run Kerb*Net Telnet for Windows, it will display a dialog box prompting for the host. Enter the host name or click on the arrow to select one from your history. If you want to connect to a different port from the standard telnet portTelnet_Port, you can include the port number next to the host name, separated by a space. Note that a telnet daemonTelnet_Daemon must be running on that port. # $ K + Configuring Kerb*Net Telnet for Windows You can configure whether Telnet interprets your backspace key as "backspace" or "delete"Backspace_vs_Delete by selecting the appropriate choice from the "Configure" menu. To change fonts, select "Font..." from the "Configure" menu. You can select the font, style (e.g., bold, italic), and size. # $ K + Copying and Pasting To copy text from your telnet window to the clipboard, select the text with the mouse, click on the "Edit" menu, and select "Copy", or use the shortcut "Ctrl+Insert". To paste text from the clipboard into your telnet window, click on the "Edit" menu, and select "Paste", or use the shortcut "Shift+Insert". # $ Telnet Port The standard telnet port is 23. Other services, such as email and FTP, use other ports. # $ Telnet Daemon The telnet daemon is a program on the remote host that enables your telnet program to log you into the host. # $ Backspace vs. Delete On many UNIX hosts, the "Delete" key functions the same way as the "Backspace" key does in Windows. If your Backspace key exhibits incorrect behavior in your telnet window, such as displaying "^H" or "^?", try switching it to the other mode. # Contents $ Contents K Contents + KTELNET:0 # Choosing_a_Host_and_Port $ Choosing a Host and Port K Choosing a Host and Port;host;hostname;port + KTELNET:0 # Configuring_Kerb_Net_Telnet_for_Windows $ Configuring Kerb*Net Telnet for Windows K Configuring Kerb*Net Telnet for Windows;configure;font;backspace;delete + KTELNET:0 # Copying_and_Pasting $ Copying and Pasting K Copying and Pasting;copy;paste;edit + KTELNET:0 # Telnet_Port $ Telnet Port # Telnet_Daemon $ Telnet Daemon # Backspace_vs_Delete $ Backspace vs. Delete /=lllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllll;Skm   )2I\ !"#opqr\ ] ^ _ j k u v   1 2 [ \       ^b \^b Pa + , ; < K L a b y z uP :;m$8lmnY Z [ u h i j u  1 [ -    + ; K a x y z  K,`,Normals0]a .@. Heading 1sPxUck.@. Heading 2hhx0U]c0@0 Heading 3s<U]c*@* Heading 4 h0]c,@, Heading 5s<]c.@. Heading 6s<V]c,@, Heading 7s<]c.@. Heading 8s<V]c. @. Heading 9 s<V]c"A@"Default Paragraph Font"@" Footnote Textc &@ Footnote Referenceh&O2&Topic Text Indent."@B" Normal Indent O Tip/Note Heading"Ob" Tip/Note Text.hOarhTip/Note Text BulletedD E 4 n.@jOjTopic Text BulletedG .E 4 n.@jOjTopic Text NumberedG .E 48.@  "oq\^z !-Hc;G]s-Gz z        o\z !0  z ROBOHELP{ { Ok)B\]ij 0}   - : M ` { Network Sercurity krb5-1.16/src/windows/wintel/telnet.c0000644000704600001450000005531213211554426017426 0ustar ghudsonlibuuid/**************************************************************************** Program: telnet.c PURPOSE: Windows networking kernel - Telnet FUNCTIONS: WinMain() - calls initialization function, processes message loop InitApplication() - initializes window data and registers window InitInstance() - saves instance handle and creates main window MainWndProc() - processes messages About() - processes messages for "About" dialog box COMMENTS: Windows can have several copies of your application running at the same time. The variable hInst keeps track of which instance this application is so that processing will be to the correct window. ****************************************************************************/ #include #include #include #include #include "telnet.h" #include "auth.h" static HANDLE hInst; static HWND hWnd; static CONFIG *tmpConfig; static CONNECTION *con = NULL; static char hostdata[MAXGETHOSTSTRUCT]; static SCREEN *pScr; static int debug = 1; char strTmp[1024]; /* Scratch buffer */ BOOL bAutoConnection = FALSE; short port_no = 23; char szUserName[64]; /* Used in auth.c */ char szHostName[64]; #ifdef KRB4 #define WINDOW_CLASS "K4_telnetWClass" #endif #ifdef KRB5 krb5_context k5_context; #define WINDOW_CLASS "K5_telnetWClass" #endif /* * * FUNCTION: WinMain(HINSTANCE, HINSTANCE, LPSTR, int) * * PURPOSE: calls initialization function, processes message loop * * COMMENTS: * * Windows recognizes this function by name as the initial entry point * for the program. This function calls the application initialization * routine, if no other instance of the program is running, and always * calls the instance initialization routine. It then executes a message * retrieval and dispatch loop that is the top-level control structure * for the remainder of execution. The loop is terminated when a WM_QUIT * message is received, at which time this function exits the application * instance by returning the value passed by PostQuitMessage(). * * If this function must abort before entering the message loop, it * returns the conventional value NULL. */ int PASCAL WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { MSG msg; if (!hPrevInstance) if (!InitApplication(hInstance)) return(FALSE); /* * Perform initializations that apply to a specific instance */ bAutoConnection = parse_cmdline(lpCmdLine); if (!InitInstance(hInstance, nCmdShow)) return(FALSE); #ifdef _WIN32 SetDebugErrorLevel(SLE_WARNING); #endif /* * Acquire and dispatch messages until a WM_QUIT message is received. */ while (GetMessage(&msg, NULL, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); /* Process all non-network messages */ while (PeekMessage(&msg, NULL, 0, WM_NETWORKEVENT-1, PM_REMOVE) || PeekMessage(&msg, NULL, WM_NETWORKEVENT+1, (UINT)-1, PM_REMOVE)) { if (msg.message == WM_QUIT) // Special case: WM_QUIT -- return return msg.wParam; // the value from PostQuitMessage TranslateMessage(&msg); DispatchMessage(&msg); } } return (msg.wParam); /* Returns the value from PostQuitMessage */ } /* * FUNCTION: InitApplication(HINSTANCE) * * PURPOSE: Initializes window data and registers window class * * COMMENTS: * * This function is called at initialization time only if no other * instances of the application are running. This function performs * initialization tasks that can be done once for any number of running * instances. * * In this case, we initialize a window class by filling out a data * structure of type WNDCLASS and calling the Windows RegisterClass() * function. Since all instances of this application use the same window * class, we only need to do this when the first instance is initialized. */ BOOL InitApplication(HINSTANCE hInstance) { WNDCLASS wc; ScreenInit(hInstance); /* * Fill in window class structure with parameters that describe the * main window. */ wc.style = CS_HREDRAW | CS_VREDRAW; /* Class style(s). */ wc.lpfnWndProc = MainWndProc; /* Function to retrieve messages for * windows of this class. */ wc.cbClsExtra = 0; /* No per-class extra data. */ wc.cbWndExtra = 0; /* No per-window extra data. */ wc.hInstance = hInstance; /* Application that owns the class. */ wc.hIcon = NULL; /* LoadIcon(hInstance, "NCSA"); */ wc.hCursor = NULL; /* Cursor(NULL, IDC_ARROW); */ wc.hbrBackground = NULL; /* GetStockObject(WHITE_BRUSH); */ wc.lpszMenuName = NULL; /* Name of menu resource in .RC file. */ wc.lpszClassName = WINDOW_CLASS; /* Name used in call to CreateWindow. */ return(RegisterClass(&wc)); } /* * FUNCTION: InitInstance(HANDLE, int) * * PURPOSE: Saves instance handle and creates main window * * COMMENTS: * * This function is called at initialization time for every instance of * this application. This function performs initialization tasks that * cannot be shared by multiple instances. * * In this case, we save the instance handle in a static variable and * create and display the main program window. */ BOOL InitInstance(HINSTANCE hInstance, int nCmdShow) { int xScreen = 0; int yScreen = 0; WSADATA wsaData; SetScreenInstance(hInstance); /* * Save the instance handle in static variable, which will be used in * many subsequence calls from this application to Windows. */ hInst = hInstance; /* * Create a main window for this application instance. */ hWnd = CreateWindow( WINDOW_CLASS, /* See RegisterClass() call. */ "TCPWin", /* Text for window title bar. */ WS_SYSMENU, /* Window style. */ xScreen / 3, /* Default horizontal position. */ yScreen / 3, /* Default vertical position. */ xScreen / 3, /* Default width. */ yScreen / 3, /* Default height. */ NULL, /* Overlapped windows have no parent */ NULL, /* Use the window class menu. */ hInstance, /* This instance owns this window. */ NULL); /* Pointer not needed. */ if (!hWnd) return (FALSE); if (WSAStartup(0x0101, &wsaData) != 0) { /* Initialize the network */ MessageBox(NULL, "Couldn't initialize Winsock!", NULL, MB_OK | MB_ICONEXCLAMATION); return(FALSE); } if (!OpenTelnetConnection()) { WSACleanup(); return(FALSE); } #ifdef KRB5 krb5_init_context(&k5_context); #endif return (TRUE); } char buf[2048]; /* * FUNCTION: MainWndProc(HWND, UINT, WPARAM, LPARAM) * * PURPOSE: Processes messages * * MESSAGES: * * WM_COMMAND - application menu (About dialog box) * WM_DESTROY - destroy window */ LRESULT CALLBACK MainWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { HGLOBAL hBuffer; LPSTR lpBuffer; int iEvent, cnt, ret; char *tmpCommaLoc; struct sockaddr_in remote_addr; struct hostent *remote_host; switch (message) { case WM_MYSCREENCHANGEBKSP: if (!con) break; con->backspace = wParam; if (con->backspace == VK_BACK) { con->ctrl_backspace = 0x7f; WritePrivateProfileString(INI_TELNET, INI_BACKSPACE, INI_BACKSPACE_BS, TELNET_INI); } else { con->ctrl_backspace = VK_BACK; WritePrivateProfileString(INI_TELNET, INI_BACKSPACE, INI_BACKSPACE_DEL, TELNET_INI); } GetPrivateProfileString(INI_HOSTS, INI_HOST "0", "", buf, 128, TELNET_INI); tmpCommaLoc = strchr(buf, ','); if (tmpCommaLoc == NULL) { strcat (buf, ","); tmpCommaLoc = strchr(buf, ','); } if (tmpCommaLoc) { tmpCommaLoc++; if (con->backspace == VK_BACK) strcpy(tmpCommaLoc, INI_HOST_BS); else strcpy(tmpCommaLoc, INI_HOST_DEL); } WritePrivateProfileString(INI_HOSTS, INI_HOST "0", buf, TELNET_INI); break; case WM_MYSCREENCHAR: { unsigned char c; if (!con) break; if (wParam == VK_BACK) c = con->backspace; else if (wParam == 0x7f) c = con->ctrl_backspace; else if (wParam == VK_SPACE && GetKeyState(VK_CONTROL) < 0) c = 0; else c = wParam; TelnetSend(con->ks, &c, 1, 0); } break; case WM_MYCURSORKEY: /* Acts as a send through: buffer is lParam and length in wParam */ if (!con) break; memcpy(buf, (char *)lParam, wParam); TelnetSend (con->ks, buf, wParam, 0); break; case WM_MYSCREENBLOCK: if (!con) break; hBuffer = (HGLOBAL) wParam; lpBuffer = GlobalLock(hBuffer); TelnetSend(con->ks, lpBuffer, lstrlen(lpBuffer), 0); GlobalUnlock(hBuffer); break; case WM_MYSCREENCLOSE: #if 0 if (con) { kstream_destroy(con->ks); con->ks = NULL; } #endif DestroyWindow(hWnd); break; case WM_QUERYOPEN: return(0); break; case WM_DESTROY: /* message: window being destroyed */ if (con) { kstream_destroy(con->ks); free(con); WSACleanup(); } PostQuitMessage(0); break; case WM_NETWORKEVENT: iEvent = WSAGETSELECTEVENT(lParam); switch (iEvent) { case FD_READ: if (con == NULL) break; cnt = kstream_read(con->ks, buf, 1500); buf[cnt] = 0; parse((CONNECTION *)con, (unsigned char *)buf, cnt); ScreenEm(buf, cnt, con->pScreen); break; case FD_CLOSE: kstream_destroy(con->ks); free(con); con = NULL; WSACleanup(); PostQuitMessage(0); break; case FD_CONNECT: ret = WSAGETSELECTERROR(lParam); if (ret) { wsprintf(buf, "Error %d on Connect", ret); MessageBox(NULL, buf, NULL, MB_OK | MB_ICONEXCLAMATION); kstream_destroy(con->ks); free(con); WSACleanup(); PostQuitMessage(0); break; } start_negotiation(con->ks); break; } break; case WM_HOSTNAMEFOUND: ret = WSAGETASYNCERROR(lParam); if (ret) { wsprintf(buf, "Error %d on GetHostbyName", ret); MessageBox(NULL, buf, NULL, MB_OK | MB_ICONEXCLAMATION); kstream_destroy(con->ks); free(con); WSACleanup(); PostQuitMessage(0); break; } remote_host = (struct hostent *)hostdata; remote_addr.sin_family = AF_INET; memcpy(&(remote_addr.sin_addr), &(remote_host->h_addr[0]), 4); remote_addr.sin_port = htons(port_no); connect(con->socket, (struct sockaddr *)&remote_addr, sizeof(struct sockaddr)); break; case WM_MYSCREENSIZE: con->width = LOWORD(lParam); /* width in characters */ con->height = HIWORD(lParam); /* height in characters */ if (con->bResizeable && con->ks) send_naws(con); wsprintf(buf, "%d", con->height); WritePrivateProfileString(INI_TELNET, INI_HEIGHT, buf, TELNET_INI); wsprintf(buf, "%d", con->width); WritePrivateProfileString(INI_TELNET, INI_WIDTH, buf, TELNET_INI); break; default: /* Passes it on if unproccessed */ return(DefWindowProc(hWnd, message, wParam, lParam)); } return (0); } /* * * FUNCTION: SaveHostName(hostname, port) * * PURPOSE: Saves the currently selected host name and port number * in the KERBEROS.INI file and returns the preferred backspace * setting if one exists for that host. * * RETURNS: VK_BACK or 0x7f depending on the desired backspace setting. */ int SaveHostName(char *host, int port) { char buf[128]; /* Scratch buffer */ char fullhost[128]; /* Host & port combination */ char hostName[10][128]; /* Entries from INI files */ char *comma; /* For parsing del/bs info */ int len; /* Length of fullhost */ int n; /* Number of items written */ int i; /* Index */ int bs; /* What we return */ if (port == 23) /* Default telnet port */ strcpy(fullhost, host); /* ...then don't add it on */ else wsprintf(fullhost, "%s %d", host, port); len = strlen(fullhost); comma = NULL; for (i = 0; i < 10; i++) { wsprintf(buf, INI_HOST "%d", i); /* INI item to fetch */ GetPrivateProfileString(INI_HOSTS, buf, "", hostName[i], 128, TELNET_INI); if (!hostName[i][0]) break; if (strncmp (hostName[i], fullhost, len)) /* A match?? */ continue; /* Nope, keep going */ comma = strchr (hostName[i], ','); } if (comma) { ++comma; /* Past the comma */ while (*comma == ' ') /* Past leading white space */ ++comma; bs = VK_BACK; /* Default for unknown entry */ if (_stricmp(comma, INI_HOST_DEL) == 0) bs = 0x7f; } else { /* No matching entry */ GetPrivateProfileString(INI_TELNET, INI_BACKSPACE, INI_BACKSPACE_BS, buf, sizeof(buf), TELNET_INI); bs = VK_BACK; /* Default value */ if (_stricmp(buf, INI_BACKSPACE_DEL) == 0) bs = 0x7f; } /* * Build up default host name */ strcpy(buf, fullhost); strcat(buf, ", "); strcat(buf, (bs == VK_BACK) ? INI_BACKSPACE_BS : INI_BACKSPACE_DEL); WritePrivateProfileString(INI_HOSTS, INI_HOST "0", buf, TELNET_INI); n = 0; for (i = 0; i < 10; i++) { if (!hostName[i][0]) /* End of the list? */ break; if (strncmp(hostName[i], fullhost, len) != 0) { wsprintf(buf, INI_HOST "%d", ++n); WritePrivateProfileString(INI_HOSTS, buf, hostName[i], TELNET_INI); } } return(bs); } int OpenTelnetConnection(void) { int nReturn, ret; struct sockaddr_in sockaddr; char *p; static struct kstream_crypt_ctl_block ctl; char buf[128]; tmpConfig = calloc(sizeof(CONFIG), 1); if (bAutoConnection) { tmpConfig->title = calloc(lstrlen(szHostName), 1); lstrcpy(tmpConfig->title, (char *) szHostName); } else { nReturn = DoDialog("OPENTELNETDLG", OpenTelnetDlg); if (nReturn == FALSE) return(FALSE); } con = (CONNECTION *) GetNewConnection(); if (con == NULL) return(0); tmpConfig->width = GetPrivateProfileInt(INI_TELNET, INI_WIDTH, DEF_WIDTH, TELNET_INI); tmpConfig->height = GetPrivateProfileInt(INI_TELNET, INI_HEIGHT, DEF_HEIGHT, TELNET_INI); con->width = tmpConfig->width; con->height = tmpConfig->height; con->backspace = SaveHostName(tmpConfig->title, port_no); if (con->backspace == VK_BACK) { tmpConfig->backspace = TRUE; con->ctrl_backspace = 0x7f; } else { tmpConfig->backspace = FALSE; con->ctrl_backspace = 0x08; } tmpConfig->hwndTel = hWnd; con->pScreen = InitNewScreen(tmpConfig); if (!con->pScreen) { assert(FALSE); free(con->pScreen); free(con); free(tmpConfig); return(-1); } ret = (SOCKET) socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (ret == SOCKET_ERROR) { wsprintf(buf, "Socket error on socket = %d!", WSAGetLastError()); MessageBox(NULL, buf, NULL, MB_OK | MB_ICONEXCLAMATION); if (con->pScreen != NULL) DestroyWindow(con->pScreen->hWnd); free(con); free(tmpConfig); return(-1); } con->socket = ret; sockaddr.sin_family = AF_INET; sockaddr.sin_addr.s_addr = htonl(INADDR_ANY); sockaddr.sin_port = htons(0); ret = bind(con->socket, (struct sockaddr *) &sockaddr, (int) sizeof(struct sockaddr_in)); if (ret == SOCKET_ERROR) { wsprintf(buf, "Socket error on bind!"); MessageBox(NULL, buf, NULL, MB_OK | MB_ICONEXCLAMATION); if (con->pScreen != NULL) DestroyWindow(con->pScreen->hWnd); free(con); free(tmpConfig); return(-1); } WSAAsyncSelect(con->socket, hWnd, WM_NETWORKEVENT, FD_READ | FD_CLOSE | FD_CONNECT); lstrcpy(szHostName, tmpConfig->title); p = strchr(szHostName, '@'); if (p != NULL) { *p = 0; strcpy (szUserName, szHostName); strcpy(szHostName, ++p); } WSAAsyncGetHostByName(hWnd, WM_HOSTNAMEFOUND, szHostName, hostdata, MAXGETHOSTSTRUCT); ctl.encrypt = auth_encrypt; ctl.decrypt = auth_decrypt; ctl.init = auth_init; ctl.destroy = auth_destroy; con->ks = kstream_create_from_fd(con->socket, &ctl, NULL); if (con->ks == NULL) return(-1); kstream_set_buffer_mode(con->ks, 0); return(1); } CONNECTION * GetNewConnection(void) { CONNECTION *pCon; pCon = calloc(sizeof(CONNECTION), 1); if (pCon == NULL) return NULL; pCon->backspace = TRUE; pCon->bResizeable = TRUE; return(pCon); } int DoDialog(char *szDialog, DLGPROC lpfnDlgProc) { int nReturn; nReturn = DialogBox(hInst, szDialog, hWnd, lpfnDlgProc); return (nReturn); } /* * FUNCTION: OpenTelnetDlg(HWND, unsigned, WORD, LONG) * * PURPOSE: Processes messages for "Open New Telnet Connection" dialog box * * MESSAGES: * * WM_INITDIALOG - initialize dialog box * WM_COMMAND - Input received */ INT_PTR CALLBACK OpenTelnetDlg(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { char szConnectName[256]; HDC hDC; int xExt, yExt; DWORD Ext; HWND hEdit; int n; int iHostNum = 0; char tmpName[128]; char tmpBuf[80]; char *tmpCommaLoc; switch (message) { case WM_INITDIALOG: hDC = GetDC(hDlg); Ext = GetDialogBaseUnits(); xExt = (190 *LOWORD(Ext)) /4 ; yExt = (72 * HIWORD(Ext)) /8 ; GetPrivateProfileString(INI_HOSTS, INI_HOST "0", "", tmpName, 128, TELNET_INI); if (tmpName[0]) { tmpCommaLoc = strchr(tmpName, ','); if (tmpCommaLoc) *tmpCommaLoc = '\0'; SetDlgItemText(hDlg, TEL_CONNECT_NAME, tmpName); } hEdit = GetWindow(GetDlgItem(hDlg, TEL_CONNECT_NAME), GW_CHILD); while (TRUE) { wsprintf(tmpBuf, INI_HOST "%d", iHostNum++); GetPrivateProfileString(INI_HOSTS, tmpBuf, "", tmpName, 128, TELNET_INI); tmpCommaLoc = strchr(tmpName, ','); if (tmpCommaLoc) *tmpCommaLoc = '\0'; if (tmpName[0]) SendDlgItemMessage(hDlg, TEL_CONNECT_NAME, CB_ADDSTRING, 0, (LPARAM) ((LPSTR) tmpName)); else break; } #ifdef FORWARD EnableWindow(GetDlgItem(hDlg, IDC_FORWARD), 1); SendDlgItemMessage(hDlg, IDC_FORWARD, BM_SETCHECK, forward_flag, 0); if (forward_flag) EnableWindow(GetDlgItem(hDlg, IDC_FORWARDFORWARD), 1); else EnableWindow(GetDlgItem(hDlg, IDC_FORWARDFORWARD), 0); SendDlgItemMessage(hDlg, IDC_FORWARDFORWARD, BM_SETCHECK, forwardable_flag, 0); #endif #ifdef ENCRYPTION EnableWindow(GetDlgItem(hDlg, IDC_ENCRYPT), 1); SendDlgItemMessage(hDlg, IDC_ENCRYPT, BM_SETCHECK, encrypt_flag, 0); #endif EnableWindow(GetDlgItem(hDlg, TEL_CONNECT_USERID), 1); SetWindowPos(hDlg, NULL, (GetSystemMetrics(SM_CXSCREEN)/2)-(xExt/2), (GetSystemMetrics(SM_CYSCREEN)/2)-(yExt/2), 0, 0, SWP_NOSIZE | SWP_NOZORDER | SWP_SHOWWINDOW); ReleaseDC(hDlg, hDC); SendMessage(hEdit, WM_USER + 1, 0, 0); SendMessage(hDlg, WM_SETFOCUS, 0, 0); return (TRUE); case WM_COMMAND: switch (wParam) { case TEL_CANCEL: case IDCANCEL: /* From the menu */ EndDialog(hDlg, FALSE); break; #ifdef FORWARD case IDC_FORWARD: forward_flag = (BOOL)SendDlgItemMessage(hDlg, IDC_FORWARD, BM_GETCHECK, 0, 0); if (forward_flag) EnableWindow(GetDlgItem(hDlg, IDC_FORWARDFORWARD), 1); else EnableWindow(GetDlgItem(hDlg, IDC_FORWARDFORWARD), 0); break; case IDC_FORWARDFORWARD: forwardable_flag = (BOOL)SendDlgItemMessage(hDlg, IDC_FORWARDFORWARD, BM_GETCHECK, 0, 0); break; #endif #if ENCRYPTION case IDC_ENCRYPT: encrypt_flag = (BOOL)SendDlgItemMessage(hDlg, IDC_ENCRYPT, BM_GETCHECK, 0, 0); break; #endif case TEL_CONNECT_USERID: GetDlgItemText(hDlg, TEL_CONNECT_USERID, szUserName, sizeof(szUserName)); break; case TEL_OK: GetDlgItemText(hDlg, TEL_CONNECT_NAME, szConnectName, 256); n = parse_cmdline (szConnectName); if (! n) { MessageBox(hDlg, "You must enter a session name!", NULL, MB_OK); break; } tmpConfig->title = calloc(lstrlen(szHostName) + 1, 1); lstrcpy(tmpConfig->title, szConnectName); EndDialog(hDlg, TRUE); break; } return (FALSE); } return(FALSE); } /* * * FUNCTION: TelnetSend(kstream ks, char *buf, int len, int flags) * * PURPOSE: This is a replacement for the WinSock send() function, to * send a buffer of characters to an output socket. It differs * by retrying endlessly if sending the bytes would cause * the send() to block. observed EWOULDBLOCK * errors when running using TCP Software's PC/TCP 3.0 stack, * even when writing as little as 109 bytes into a socket * that had no more than 9 bytes queued for output. Note also * that a kstream is used during output rather than a socket * to facilitate encryption. * * Eventually, for cleanliness and responsiveness, this * routine should not loop; instead, if the send doesn't * send all the bytes, it should put them into a buffer * and return. Message handling code would send out the * buffer whenever it gets an FD_WRITE message. */ int TelnetSend(kstream ks, char *buf, int len, int flags) { int writelen; int origlen = len; while (TRUE) { writelen = kstream_write(ks, buf, len); if (writelen == len) /* Success, first or Nth time */ return (origlen); if (writelen == SOCKET_ERROR) { if (WSAGetLastError() != WSAEWOULDBLOCK) return (SOCKET_ERROR); /* Some error */ /* For WOULDBLOCK, immediately repeat the send. */ } else { /* Partial write; update the pointers and retry. */ len -= writelen; buf += writelen; } } } /* * Function: Trim leading and trailing white space from a string. * * Parameters: * s - the string to trim. */ void trim(char *s) { int l; int i; for (i = 0; s[i]; i++) if (s[i] != ' ' && s[i] != '\t') break; l = strlen(&s[i]); memmove(s, &s[i], l + 1); for (l--; l >= 0; l--) { if (s[l] != ' ' && s[l] != '\t') break; } s[l + 1] = 0; } /* * * Parse_cmdline * * Reads hostname and port number off the command line. * * Formats: telnet * telnet * telnet * telnet -p * * Returns: TRUE if we have a hostname */ BOOL parse_cmdline(char *cmdline) { char *ptr; *szHostName = '\0'; /* Nothing yet */ if (*cmdline == '\0') /* Empty command line? */ return(FALSE); trim (cmdline); /* Remove excess spaces */ ptr = strchr (cmdline, ' '); /* Find 2nd token */ if (ptr != NULL) { /* Port number given */ *ptr++ = '\0'; /* Separate into 2 words */ port_no = atoi (ptr); } if (*cmdline != '-' && *cmdline != '/') { /* Host name given */ lstrcpy (szHostName, cmdline); return(TRUE); } return(FALSE); } #ifdef DEBUG void hexdump(char *msg, unsigned char *st, int cnt) { int i; char strTmp[128]; OutputDebugString("\r\n"); if (msg != NULL) { OutputDebugString(msg); OutputDebugString("\r\n"); } for(i = 0 ; i < cnt ; i++) { int j; for(j = 0 ; (j < 16) && ((i + j) < cnt) ; j++) { wsprintf(strTmp,"%02x ", st[i + j]); if (j == 8) OutputDebugString("| "); OutputDebugString(strTmp); } i += j - 1; OutputDebugString("\r\n"); } /* end for */ } #endif krb5-1.16/src/windows/wintel/k5stream.c0000644000704600001450000000377113211554426017670 0ustar ghudsonlibuuid/* * * K5stream * * Emulates the kstream package in Kerberos 4 * */ #include #include #include #include "telnet.h" #include "k5stream.h" #include "auth.h" int kstream_destroy(kstream ks) { if (ks != NULL) { auth_destroy(ks); /* Destroy authorizing */ closesocket(ks->fd); /* Close the socket??? */ free(ks); } return 0; } void kstream_set_buffer_mode(kstream ks, int mode) { } kstream kstream_create_from_fd(int fd, const struct kstream_crypt_ctl_block *ctl, kstream_ptr data) { kstream ks; int n; BOOL on = 1; ks = malloc(sizeof(struct kstream_int)); if (ks == NULL) return NULL; ks->fd = fd; setsockopt(ks->fd, SOL_SOCKET, SO_OOBINLINE, (const char *)&on, sizeof(on)); n = auth_init(ks, data); /* Initialize authorizing */ if (n) { free(ks); return NULL; } ks->encrypt = NULL; ks->decrypt = NULL; return ks; } int kstream_write(kstream ks, void *p_data, size_t p_len) { int n; struct kstream_data_block i; #ifdef DEBUG hexdump("plaintext:", p_data, p_len); #endif if (ks->encrypt) { i.ptr = p_data; i.length = p_len; ks->encrypt(&i, NULL, NULL); #ifdef DEBUG hexdump("cyphertext:", p_data, p_len); #endif } n = send(ks->fd, p_data, p_len, 0); /* Write the data */ return n; /* higher layer does retries */ } int kstream_read(kstream ks, void *p_data, size_t p_len) { int n; struct kstream_data_block i; n = recv(ks->fd, p_data, p_len, 0); /* read the data */ if (n < 0) return n; #ifdef DEBUG hexdump("input data:", p_data, n); #endif if (ks->decrypt) { extern int encrypt_flag; if (encrypt_flag == 2) encrypt_flag = 1; i.ptr = p_data; i.length = n; ks->decrypt(&i, NULL, NULL); #ifdef DEBUG hexdump("decrypted data:", p_data, n); #endif } return n; /* higher layer does retries */ } krb5-1.16/src/windows/wintel/dialog.h0000644000704600001450000000263213211554426017374 0ustar ghudsonlibuuid#define IDM_SHOWCONSOLE 700 #define IDM_OPENTELNETDLG 200 #define TEL_CONNECT_NAME 201 #define TEL_USEDEFAULTS 202 #define TEL_MANUALCONFIGURE 203 #define TEL_OK 204 #define TEL_CANCEL 206 #define IDC_FORWARD 207 #define IDC_FORWARDFORWARD 208 #define IDC_ENCRYPT 210 #define TEL_CONNECT_USERID 211 #define IDM_SEND_IP 800 #define IDM_SEND_AYT 801 #define IDM_SEND_ABORT 802 #define CON_SESSIONNAME 302 #define CON_WINDOWTITLE 304 #define CON_COLUMNS132 305 #define CON_COLUMNS80 306 #define CON_BACKSPACE 307 #define CON_DELETE 308 #define CON_CRLF 309 #define CON_CRNUL 310 #define CON_BUFFERS 311 #define CON_SENDS 312 #define CON_OK 320 #define CON_USEDEFAULTS 321 #define CONFIGDLG 300 #define CON_SCRLBCK 317 #define CON_NUMLINES 318 #define PRINTQUEUE 400 #define IDM_PRINTQUEUE 500 #define TEL_PUSH1 601 #define TEL_PUSH2 602 #define TEL_PUSH3 603 #define TEL_PUSH4 604 #define TEL_PUSH5 605 krb5-1.16/src/windows/wintel/enc_des.c0000644000704600001450000003653013211554426017534 0ustar ghudsonlibuuid/*- * Copyright (c) 1991, 1993 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ /* based on @(#)enc_des.c 8.1 (Berkeley) 6/4/93 */ #ifdef ENCRYPTION #include "telnet_arpa.h" #include #include #include "telnet.h" #include "encrypt.h" #define CFB 0 #define OFB 1 #define NO_SEND_IV 1 #define NO_RECV_IV 2 #define NO_KEYID 4 #define IN_PROGRESS (NO_SEND_IV|NO_RECV_IV|NO_KEYID) #define SUCCESS 0 #define xFAILED -1 struct fb { Block krbdes_key; Schedule krbdes_sched; Block temp_feed; unsigned char fb_feed[64]; int need_start; int state[2]; int keyid[2]; int once; struct stinfo { Block str_output; Block str_feed; Block str_iv; Block str_ikey; Schedule str_sched; int str_index; int str_flagshift; } streams[2]; }; static struct fb fb[2]; struct keyidlist { char *keyid; int keyidlen; char *key; int keylen; int flags; } keyidlist [] = { { "\0", 1, 0, 0, 0 }, /* default key of zero */ { 0, 0, 0, 0, 0 } }; #define KEYFLAG_MASK 03 #define KEYFLAG_NOINIT 00 #define KEYFLAG_INIT 01 #define KEYFLAG_OK 02 #define KEYFLAG_BAD 03 #define KEYFLAG_SHIFT 2 #define SHIFT_VAL(a,b) (KEYFLAG_SHIFT*((a)+((b)*2))) #define FB64_IV 1 #define FB64_IV_OK 2 #define FB64_IV_BAD 3 extern kstream EncryptKSGlobalHack; void fb64_stream_iv (Block, struct stinfo *); void fb64_init (struct fb *); static int fb64_start (struct fb *, int, int); int fb64_is (unsigned char *, int, struct fb *); int fb64_reply (unsigned char *, int, struct fb *); static void fb64_session (Session_Key *, int, struct fb *); void fb64_stream_key (Block, struct stinfo *); int fb64_keyid (int, unsigned char *, int *, struct fb *); void cfb64_init(server) int server; { fb64_init(&fb[CFB]); fb[CFB].fb_feed[4] = ENCTYPE_DES_CFB64; fb[CFB].streams[0].str_flagshift = SHIFT_VAL(0, CFB); fb[CFB].streams[1].str_flagshift = SHIFT_VAL(1, CFB); } void ofb64_init(server) int server; { fb64_init(&fb[OFB]); fb[OFB].fb_feed[4] = ENCTYPE_DES_OFB64; fb[CFB].streams[0].str_flagshift = SHIFT_VAL(0, OFB); fb[CFB].streams[1].str_flagshift = SHIFT_VAL(1, OFB); } void fb64_init(fbp) register struct fb *fbp; { memset((void *)fbp, 0, sizeof(*fbp)); fbp->state[0] = fbp->state[1] = xFAILED; fbp->fb_feed[0] = IAC; fbp->fb_feed[1] = SB; fbp->fb_feed[2] = TELOPT_ENCRYPT; fbp->fb_feed[3] = ENCRYPT_IS; } /* * Returns: * -1: some error. Negotiation is done, encryption not ready. * 0: Successful, initial negotiation all done. * 1: successful, negotiation not done yet. * 2: Not yet. Other things (like getting the key from * Kerberos) have to happen before we can continue. */ int cfb64_start(dir, server) int dir; int server; { return(fb64_start(&fb[CFB], dir, server)); } int ofb64_start(dir, server) int dir; int server; { return(fb64_start(&fb[OFB], dir, server)); } static int fb64_start(fbp, dir, server) struct fb *fbp; int dir; int server; { int x; unsigned char *p; register int state; switch (dir) { case DIR_DECRYPT: /* * This is simply a request to have the other side * start output (our input). He will negotiate an * IV so we need not look for it. */ state = fbp->state[dir-1]; if (state == xFAILED) state = IN_PROGRESS; break; case DIR_ENCRYPT: state = fbp->state[dir-1]; if (state == xFAILED) state = IN_PROGRESS; else if ((state & NO_SEND_IV) == 0) break; if (!VALIDKEY(fbp->krbdes_key)) { fbp->need_start = 1; break; } state &= ~NO_SEND_IV; state |= NO_RECV_IV; /* * Create a random feed and send it over. */ des_new_random_key(fbp->temp_feed); des_ecb_encrypt(fbp->temp_feed, fbp->temp_feed, fbp->krbdes_sched, 1); p = fbp->fb_feed + 3; *p++ = ENCRYPT_IS; p++; *p++ = FB64_IV; for (x = 0; x < sizeof(Block); ++x) { if ((*p++ = fbp->temp_feed[x]) == IAC) *p++ = IAC; } *p++ = IAC; *p++ = SE; #ifdef DEBUG printsub('>', &fbp->fb_feed[2], p - &fbp->fb_feed[2]); #endif TelnetSend(EncryptKSGlobalHack, fbp->fb_feed, p - fbp->fb_feed, 0); break; default: return(xFAILED); } return(fbp->state[dir-1] = state); } /* * Returns: * -1: some error. Negotiation is done, encryption not ready. * 0: Successful, initial negotiation all done. * 1: successful, negotiation not done yet. */ int cfb64_is(data, cnt) unsigned char *data; int cnt; { return(fb64_is(data, cnt, &fb[CFB])); } int ofb64_is(data, cnt) unsigned char *data; int cnt; { return(fb64_is(data, cnt, &fb[OFB])); } int fb64_is(data, cnt, fbp) unsigned char *data; int cnt; struct fb *fbp; { unsigned char *p; register int state = fbp->state[DIR_DECRYPT-1]; if (cnt-- < 1) goto failure; switch (*data++) { case FB64_IV: if (cnt != sizeof(Block)) { #ifdef DEBUG if (encrypt_debug_mode) printf("CFB64: initial vector failed on size\r\n"); #endif state = xFAILED; goto failure; } #ifdef DEBUG if (encrypt_debug_mode) { printf("CFB64: initial vector received\r\n"); printf("Initializing Decrypt stream\r\n"); } #endif fb64_stream_iv((void *)data, &fbp->streams[DIR_DECRYPT-1]); p = fbp->fb_feed + 3; *p++ = ENCRYPT_REPLY; p++; *p++ = FB64_IV_OK; *p++ = IAC; *p++ = SE; #ifdef DEBUG printsub('>', &fbp->fb_feed[2], p - &fbp->fb_feed[2]); #endif TelnetSend(EncryptKSGlobalHack, fbp->fb_feed, p - fbp->fb_feed, 0); state = fbp->state[DIR_DECRYPT-1] = IN_PROGRESS; break; default: #if 0 if (encrypt_debug_mode) { printf("Unknown option type: %d\r\n", *(data-1)); printd(data, cnt); printf("\r\n"); } #endif /* FALL THROUGH */ failure: /* * We failed. Send an FB64_IV_BAD option * to the other side so it will know that * things failed. */ p = fbp->fb_feed + 3; *p++ = ENCRYPT_REPLY; p++; *p++ = FB64_IV_BAD; *p++ = IAC; *p++ = SE; #ifdef DEBUG printsub('>', &fbp->fb_feed[2], p - &fbp->fb_feed[2]); #endif TelnetSend(EncryptKSGlobalHack, fbp->fb_feed, p - fbp->fb_feed, 0); break; } return(fbp->state[DIR_DECRYPT-1] = state); } /* * Returns: * -1: some error. Negotiation is done, encryption not ready. * 0: Successful, initial negotiation all done. * 1: successful, negotiation not done yet. */ int cfb64_reply(data, cnt) unsigned char *data; int cnt; { return(fb64_reply(data, cnt, &fb[CFB])); } int ofb64_reply(data, cnt) unsigned char *data; int cnt; { return(fb64_reply(data, cnt, &fb[OFB])); } int fb64_reply(data, cnt, fbp) unsigned char *data; int cnt; struct fb *fbp; { register int state = fbp->state[DIR_ENCRYPT-1]; if (cnt-- < 1) goto failure; switch (*data++) { case FB64_IV_OK: fb64_stream_iv(fbp->temp_feed, &fbp->streams[DIR_ENCRYPT-1]); if (state == xFAILED) state = IN_PROGRESS; state &= ~NO_RECV_IV; encrypt_send_keyid(DIR_ENCRYPT, (unsigned char *)"\0", 1, 1); break; case FB64_IV_BAD: memset(fbp->temp_feed, 0, sizeof(Block)); fb64_stream_iv(fbp->temp_feed, &fbp->streams[DIR_ENCRYPT-1]); state = xFAILED; break; default: #if 0 if (encrypt_debug_mode) { printf("Unknown option type: %d\r\n", data[-1]); printd(data, cnt); printf("\r\n"); } #endif /* FALL THROUGH */ failure: state = xFAILED; break; } return(fbp->state[DIR_ENCRYPT-1] = state); } void cfb64_session(key, server) Session_Key *key; int server; { fb64_session(key, server, &fb[CFB]); } void ofb64_session(key, server) Session_Key *key; int server; { fb64_session(key, server, &fb[OFB]); } static void fb64_session(key, server, fbp) Session_Key *key; int server; struct fb *fbp; { if (!key || key->type != SK_DES) { #ifdef DEBUG if (encrypt_debug_mode) printf("Can't set krbdes's session key (%d != %d)\r\n", key ? key->type : -1, SK_DES); #endif return; } memcpy((void *)fbp->krbdes_key, (void *)key->data, sizeof(Block)); fb64_stream_key(fbp->krbdes_key, &fbp->streams[DIR_ENCRYPT-1]); fb64_stream_key(fbp->krbdes_key, &fbp->streams[DIR_DECRYPT-1]); if (fbp->once == 0) { des_init_random_number_generator(fbp->krbdes_key); fbp->once = 1; } des_key_sched(fbp->krbdes_key, fbp->krbdes_sched); /* * Now look to see if krbdes_start() was was waiting for * the key to show up. If so, go ahead an call it now * that we have the key. */ if (fbp->need_start) { fbp->need_start = 0; fb64_start(fbp, DIR_ENCRYPT, server); } } /* * We only accept a keyid of 0. If we get a keyid of * 0, then mark the state as SUCCESS. */ int cfb64_keyid(dir, kp, lenp) int dir, *lenp; unsigned char *kp; { return(fb64_keyid(dir, kp, lenp, &fb[CFB])); } int ofb64_keyid(dir, kp, lenp) int dir, *lenp; unsigned char *kp; { return(fb64_keyid(dir, kp, lenp, &fb[OFB])); } int fb64_keyid(dir, kp, lenp, fbp) int dir, *lenp; unsigned char *kp; struct fb *fbp; { register int state = fbp->state[dir-1]; if (*lenp != 1 || (*kp != '\0')) { *lenp = 0; return(state); } if (state == xFAILED) state = IN_PROGRESS; state &= ~NO_KEYID; return(fbp->state[dir-1] = state); } #if 0 void fb64_printsub(data, cnt, buf, buflen, type) unsigned char *data, *buf, *type; int cnt, buflen; { char lbuf[32]; register int i; char *cp; buf[buflen-1] = '\0'; /* make sure it's NULL terminated */ buflen -= 1; switch(data[2]) { case FB64_IV: sprintf(lbuf, "%s_IV", type); cp = lbuf; goto common; case FB64_IV_OK: sprintf(lbuf, "%s_IV_OK", type); cp = lbuf; goto common; case FB64_IV_BAD: sprintf(lbuf, "%s_IV_BAD", type); cp = lbuf; goto common; default: sprintf(lbuf, " %d (unknown)", data[2]); cp = lbuf; common: for (; (buflen > 0) && (*buf = *cp++); buf++) buflen--; for (i = 3; i < cnt; i++) { sprintf(lbuf, " %d", data[i]); for (cp = lbuf; (buflen > 0) && (*buf = *cp++); buf++) buflen--; } break; } } void cfb64_printsub(data, cnt, buf, buflen) unsigned char *data, *buf; int cnt, buflen; { fb64_printsub(data, cnt, buf, buflen, "CFB64"); } void ofb64_printsub(data, cnt, buf, buflen) unsigned char *data, *buf; int cnt, buflen; { fb64_printsub(data, cnt, buf, buflen, "OFB64"); } #endif void fb64_stream_iv(seed, stp) Block seed; register struct stinfo *stp; { memcpy((void *)stp->str_iv, (void *)seed, sizeof(Block)); memcpy((void *)stp->str_output, (void *)seed, sizeof(Block)); des_key_sched(stp->str_ikey, stp->str_sched); stp->str_index = sizeof(Block); } void fb64_stream_key(key, stp) Block key; register struct stinfo *stp; { memcpy((void *)stp->str_ikey, (void *)key, sizeof(Block)); des_key_sched(key, stp->str_sched); memcpy((void *)stp->str_output, (void *)stp->str_iv, sizeof(Block)); stp->str_index = sizeof(Block); } /* * DES 64 bit Cipher Feedback * * key --->+-----+ * +->| DES |--+ * | +-----+ | * | v * INPUT --(--------->(+)+---> DATA * | | * +-------------+ * * * Given: * iV: Initial vector, 64 bits (8 bytes) long. * Dn: the nth chunk of 64 bits (8 bytes) of data to encrypt (decrypt). * On: the nth chunk of 64 bits (8 bytes) of encrypted (decrypted) output. * * V0 = DES(iV, key) * On = Dn ^ Vn * V(n+1) = DES(On, key) */ void cfb64_encrypt(s, c) register unsigned char *s; int c; { register struct stinfo *stp = &fb[CFB].streams[DIR_ENCRYPT-1]; register int index; index = stp->str_index; while (c-- > 0) { if (index == sizeof(Block)) { Block b; des_ecb_encrypt(stp->str_output, b, stp->str_sched, 1); memcpy((void *)stp->str_feed,(void *)b,sizeof(Block)); index = 0; } /* On encryption, we store (feed ^ data) which is cypher */ *s = stp->str_output[index] = (stp->str_feed[index] ^ *s); s++; index++; } stp->str_index = index; } int cfb64_decrypt(data) int data; { register struct stinfo *stp = &fb[CFB].streams[DIR_DECRYPT-1]; int index; if (data == -1) { /* * Back up one byte. It is assumed that we will * never back up more than one byte. If we do, this * may or may not work. */ if (stp->str_index) --stp->str_index; return(0); } index = stp->str_index++; if (index == sizeof(Block)) { Block b; des_ecb_encrypt(stp->str_output, b, stp->str_sched, 1); memcpy((void *)stp->str_feed, (void *)b, sizeof(Block)); stp->str_index = 1; /* Next time will be 1 */ index = 0; /* But now use 0 */ } /* On decryption we store (data) which is cypher. */ stp->str_output[index] = data; return(data ^ stp->str_feed[index]); } /* * DES 64 bit Output Feedback * * key --->+-----+ * +->| DES |--+ * | +-----+ | * +-----------+ * v * INPUT -------->(+) ----> DATA * * Given: * iV: Initial vector, 64 bits (8 bytes) long. * Dn: the nth chunk of 64 bits (8 bytes) of data to encrypt (decrypt). * On: the nth chunk of 64 bits (8 bytes) of encrypted (decrypted) output. * * V0 = DES(iV, key) * V(n+1) = DES(Vn, key) * On = Dn ^ Vn */ void ofb64_encrypt(s, c) register unsigned char *s; int c; { register struct stinfo *stp = &fb[OFB].streams[DIR_ENCRYPT-1]; register int index; index = stp->str_index; while (c-- > 0) { if (index == sizeof(Block)) { Block b; des_ecb_encrypt(stp->str_feed, b, stp->str_sched, 1); memcpy((void *)stp->str_feed,(void *)b,sizeof(Block)); index = 0; } *s++ ^= stp->str_feed[index]; index++; } stp->str_index = index; } int ofb64_decrypt(data) int data; { register struct stinfo *stp = &fb[OFB].streams[DIR_DECRYPT-1]; int index; if (data == -1) { /* * Back up one byte. It is assumed that we will * never back up more than one byte. If we do, this * may or may not work. */ if (stp->str_index) --stp->str_index; return(0); } index = stp->str_index++; if (index == sizeof(Block)) { Block b; des_ecb_encrypt(stp->str_feed, b, stp->str_sched, 1); memcpy((void *)stp->str_feed, (void *)b, sizeof(Block)); stp->str_index = 1; /* Next time will be 1 */ index = 0; /* But now use 0 */ } return(data ^ stp->str_feed[index]); } #endif /* ENCRYPTION */ krb5-1.16/src/windows/wintel/encrypt.c0000644000704600001450000005547713211554426017633 0ustar ghudsonlibuuid/* * Copyright (c) 1991, 1993 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ /* based on @(#)encrypt.c 8.1 (Berkeley) 6/4/93 */ /* * Copyright (C) 1990 by the Massachusetts Institute of Technology * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #ifdef ENCRYPTION #include #define isprefix(a, b) (!strncmp((a), (b), strlen(b))) #ifdef KRB4 #include #include #include #include "winsock.h" #include "kerberos.h" #endif #ifdef KRB5 #include #include #include "krb5.h" #include "com_err.h" #endif #include "telnet.h" #include "encrypt.h" #define ENCRYPT_NAMES #include "telnet_arpa.h" /* * These function pointers point to the current routines * for encrypting and decrypting data. */ void (*encrypt_output) (unsigned char *, int); int (*decrypt_input) (int); #ifdef DEBUG int encrypt_debug_mode = 1; int encrypt_verbose = 1; #else int encrypt_verbose = 0; #endif static char dbgbuf [10240]; static int decrypt_mode = 0; static int encrypt_mode = 0; static int autoencrypt = 1; static int autodecrypt = 1; static int havesessionkey = 0; kstream EncryptKSGlobalHack = NULL; #define typemask(x) ((x) > 0 ? 1 << ((x)-1) : 0) static long i_support_encrypt = typemask(ENCTYPE_DES_CFB64) | typemask(ENCTYPE_DES_OFB64); static long i_support_decrypt = typemask(ENCTYPE_DES_CFB64) | typemask(ENCTYPE_DES_OFB64); static long i_wont_support_encrypt = 0; static long i_wont_support_decrypt = 0; #define I_SUPPORT_ENCRYPT (i_support_encrypt & ~i_wont_support_encrypt) #define I_SUPPORT_DECRYPT (i_support_decrypt & ~i_wont_support_decrypt) static long remote_supports_encrypt = 0; static long remote_supports_decrypt = 0; static Encryptions encryptions[] = { { "DES_CFB64", ENCTYPE_DES_CFB64, cfb64_encrypt, cfb64_decrypt, cfb64_init, cfb64_start, cfb64_is, cfb64_reply, cfb64_session, cfb64_keyid, NULL }, { "DES_OFB64", ENCTYPE_DES_OFB64, ofb64_encrypt, ofb64_decrypt, ofb64_init, ofb64_start, ofb64_is, ofb64_reply, ofb64_session, ofb64_keyid, NULL }, { 0, }, }; static unsigned char str_send[64] = { IAC, SB, TELOPT_ENCRYPT, ENCRYPT_SUPPORT }; static unsigned char str_suplen = 0; static unsigned char str_start[72] = { IAC, SB, TELOPT_ENCRYPT }; static unsigned char str_end[] = { IAC, SB, TELOPT_ENCRYPT, 0, IAC, SE }; void encrypt_request_end(void); void encrypt_request_start(unsigned char *, int); void encrypt_enc_keyid(unsigned char *, int); void encrypt_dec_keyid(unsigned char *, int); void encrypt_support(unsigned char *, int); void encrypt_start(unsigned char *, int); void encrypt_end(void); int encrypt_ks_stream(struct kstream_data_block *, /* output */ struct kstream_data_block *, /* input */ struct kstream *); int decrypt_ks_stream(struct kstream_data_block *, /* output */ struct kstream_data_block *, /* input */ struct kstream *); int encrypt_ks_stream(struct kstream_data_block *i, struct kstream_data_block *o, struct kstream *ks) { /* * this is really quite bogus, since it does an in-place encryption... */ if (encrypt_output) { encrypt_output(i->ptr, i->length); return 1; } return 0; } int decrypt_ks_stream(struct kstream_data_block *i, struct kstream_data_block *o, struct kstream *ks) { unsigned int len; /* * this is really quite bogus, since it does an in-place decryption... */ if (decrypt_input) { for (len = 0 ; len < i->length ; len++) ((unsigned char *)i->ptr)[len] = decrypt_input(((unsigned char *)i->ptr)[len]); return 1; } return 0; } int decrypt_ks_hack(unsigned char *buf, int cnt) { int len; /* * this is really quite bogus, since it does an in-place decryption... */ for (len = 0 ; len < cnt ; len++) buf[len] = decrypt_input(buf[len]); #ifdef DEBUG hexdump("hack:", buf, cnt); #endif return 1; } #ifdef DEBUG int printsub(char c, unsigned char *s, size_t len) { size_t i; char *p = dbgbuf; *p++ = c; for (i = 0 ; (i < len) && (p - dbgbuf + 3 < sizeof(dbgbuf)) ; i++) p += sprintf(p, "%02x ", s[i]); dbgbuf[sizeof(dbgbuf) - 1] = '\0'; strncat(p, "\n", sizeof(dbgbuf) - 1 - (p - dbgbuf)); OutputDebugString(dbgbuf); return 0; } #endif /* * parsedat[0] == the suboption we might be negoating, */ void encrypt_parse(kstream ks, unsigned char *parsedat, int end_sub) { char *p = dbgbuf; #ifdef DEBUG printsub('<', parsedat, end_sub); #endif switch(parsedat[1]) { case ENCRYPT_START: encrypt_start(parsedat + 2, end_sub - 2); break; case ENCRYPT_END: encrypt_end(); break; case ENCRYPT_SUPPORT: encrypt_support(parsedat + 2, end_sub - 2); break; case ENCRYPT_REQSTART: encrypt_request_start(parsedat + 2, end_sub - 2); break; case ENCRYPT_REQEND: /* * We can always send an REQEND so that we cannot * get stuck encrypting. We should only get this * if we have been able to get in the correct mode * anyhow. */ encrypt_request_end(); break; case ENCRYPT_IS: encrypt_is(parsedat + 2, end_sub - 2); break; case ENCRYPT_REPLY: encrypt_reply(parsedat + 2, end_sub - 2); break; case ENCRYPT_ENC_KEYID: encrypt_enc_keyid(parsedat + 2, end_sub - 2); break; case ENCRYPT_DEC_KEYID: encrypt_dec_keyid(parsedat + 2, end_sub - 2); break; default: break; } } /* XXX */ Encryptions * findencryption(type) int type; { Encryptions *ep = encryptions; if (!(I_SUPPORT_ENCRYPT & remote_supports_decrypt & typemask(type))) return(0); while (ep->type && ep->type != type) ++ep; return(ep->type ? ep : 0); } Encryptions * finddecryption(int type) { Encryptions *ep = encryptions; if (!(I_SUPPORT_DECRYPT & remote_supports_encrypt & typemask(type))) return(0); while (ep->type && ep->type != type) ++ep; return(ep->type ? ep : 0); } #define MAXKEYLEN 64 static struct key_info { unsigned char keyid[MAXKEYLEN]; int keylen; int dir; int *modep; Encryptions *(*getcrypt)(); } ki[2] = { { { 0 }, 0, DIR_ENCRYPT, &encrypt_mode, findencryption }, { { 0 }, 0, DIR_DECRYPT, &decrypt_mode, finddecryption }, }; void encrypt_init(kstream iks, kstream_ptr data) { Encryptions *ep = encryptions; i_support_encrypt = i_support_decrypt = 0; remote_supports_encrypt = remote_supports_decrypt = 0; encrypt_mode = 0; decrypt_mode = 0; encrypt_output = NULL; decrypt_input = NULL; str_suplen = 4; EncryptKSGlobalHack = iks; while (ep->type) { #ifdef DEBUG if (encrypt_debug_mode) { sprintf(dbgbuf, ">>>I will support %s\n", ENCTYPE_NAME(ep->type)); OutputDebugString(dbgbuf); } #endif i_support_encrypt |= typemask(ep->type); i_support_decrypt |= typemask(ep->type); if ((i_wont_support_decrypt & typemask(ep->type)) == 0) if ((str_send[str_suplen++] = ep->type) == IAC) str_send[str_suplen++] = IAC; if (ep->init) (*ep->init)(0); ++ep; } str_send[str_suplen++] = IAC; str_send[str_suplen++] = SE; } void encrypt_send_support() { if (str_suplen) { /* * If the user has requested that decryption start * immediatly, then send a "REQUEST START" before * we negotiate the type. */ if (autodecrypt) encrypt_send_request_start(); TelnetSend(EncryptKSGlobalHack, str_send, str_suplen, 0); #ifdef DEBUG printsub('>', &str_send[2], str_suplen - 2); #endif str_suplen = 0; } } /* * Called when ENCRYPT SUPPORT is received. */ void encrypt_support(typelist, cnt) unsigned char *typelist; int cnt; { register int type, use_type = 0; Encryptions *ep; /* * Forget anything the other side has previously told us. */ remote_supports_decrypt = 0; while (cnt-- > 0) { type = *typelist++; #ifdef DEBUG if (encrypt_debug_mode) { sprintf(dbgbuf, ">>>Remote supports %s (%d)\n", ENCTYPE_NAME(type), type); OutputDebugString(dbgbuf); } #endif if ((type < ENCTYPE_CNT) && (I_SUPPORT_ENCRYPT & typemask(type))) { remote_supports_decrypt |= typemask(type); if (use_type == 0) use_type = type; } } if (use_type) { ep = findencryption(use_type); if (!ep) return; type = ep->start ? (*ep->start)(DIR_ENCRYPT, 0) : 0; #ifdef DEBUG if (encrypt_debug_mode) { sprintf(dbgbuf, ">>>(*ep->start)() %s returned %d (%s)\n", ENCTYPE_NAME(use_type), type, ENCRYPT_NAME(type)); OutputDebugString(dbgbuf); } #endif if (type < 0) return; encrypt_mode = use_type; if (type == 0) encrypt_start_output(use_type); } } void encrypt_is(data, cnt) unsigned char *data; int cnt; { Encryptions *ep; register int type, ret; if (--cnt < 0) return; type = *data++; if (type < ENCTYPE_CNT) remote_supports_encrypt |= typemask(type); if (!(ep = finddecryption(type))) { #ifdef DEBUG if (encrypt_debug_mode) { sprintf(dbgbuf, ">>>encrypt_reply: " "Can't find type %s (%d) for initial negotiation\n", ENCTYPE_NAME_OK(type) ? ENCTYPE_NAME(type) : "(unknown)", type); OutputDebugString(dbgbuf); } #endif return; } if (!ep->is) { #ifdef DEBUG if (encrypt_debug_mode) { sprintf(dbgbuf, ">>>encrypt_reply: " "No initial negotiation needed for type %s (%d)\n", ENCTYPE_NAME_OK(type) ? ENCTYPE_NAME(type) : "(unknown)", type); OutputDebugString(dbgbuf); } #endif ret = 0; } else { ret = (*ep->is)(data, cnt); #ifdef DEBUG if (encrypt_debug_mode) { sprintf(dbgbuf, "encrypt_reply: " "(*ep->is)(%x, %d) returned %s(%d)\n", data, cnt, (ret < 0) ? "FAIL " : (ret == 0) ? "SUCCESS " : "MORE_TO_DO ", ret); OutputDebugString(dbgbuf); } #endif } if (ret < 0) { autodecrypt = 0; } else { decrypt_mode = type; if (ret == 0 && autodecrypt) encrypt_send_request_start(); } } void encrypt_reply(data, cnt) unsigned char *data; int cnt; { Encryptions *ep; register int ret, type; if (--cnt < 0) return; type = *data++; if (!(ep = findencryption(type))) { #ifdef DEBUG if (encrypt_debug_mode) { sprintf(dbgbuf, ">>>Can't find type %s (%d) for initial negotiation\n", ENCTYPE_NAME_OK(type) ? ENCTYPE_NAME(type) : "(unknown)", type); OutputDebugString(dbgbuf); } #endif return; } if (!ep->reply) { #ifdef DEBUG if (encrypt_debug_mode) { sprintf(dbgbuf, ">>>No initial negotiation needed for type %s (%d)\n", ENCTYPE_NAME_OK(type) ? ENCTYPE_NAME(type) : "(unknown)", type); OutputDebugString(dbgbuf); } #endif ret = 0; } else { ret = (*ep->reply)(data, cnt); #ifdef DEBUG if (encrypt_debug_mode) { sprintf(dbgbuf, "(*ep->reply)(%x, %d) returned %s(%d)\n", data, cnt, (ret < 0) ? "FAIL " : (ret == 0) ? "SUCCESS " : "MORE_TO_DO ", ret); OutputDebugString(dbgbuf); } #endif } #ifdef DEBUG if (encrypt_debug_mode) { sprintf(dbgbuf, ">>>encrypt_reply returned %d\n", ret); OutputDebugString(dbgbuf); } #endif if (ret < 0) { autoencrypt = 0; } else { encrypt_mode = type; if (ret == 0 && autoencrypt) encrypt_start_output(type); } } /* * Called when a ENCRYPT START command is received. */ void encrypt_start(data, cnt) unsigned char *data; int cnt; { Encryptions *ep; if (!decrypt_mode) { /* * Something is wrong. We should not get a START * command without having already picked our * decryption scheme. Send a REQUEST-END to * attempt to clear the channel... */ /* printf("Warning, Cannot decrypt input stream!!!\n"); */ encrypt_send_request_end(); MessageBox(NULL, "Warning, Cannot decrypt input stream!!!", NULL, MB_OK | MB_ICONEXCLAMATION); return; } if (ep = finddecryption(decrypt_mode)) { extern BOOL encrypt_flag; decrypt_input = ep->input; EncryptKSGlobalHack->decrypt = decrypt_ks_stream; encrypt_flag = 2; /* XXX hack */ if (encrypt_verbose) { sprintf(dbgbuf, "[ Input is now decrypted with type %s ]\n", ENCTYPE_NAME(decrypt_mode)); OutputDebugString(dbgbuf); } #ifdef DEBUG if (encrypt_debug_mode) { sprintf(dbgbuf, ">>>Start to decrypt input with type %s\n", ENCTYPE_NAME(decrypt_mode)); OutputDebugString(dbgbuf); } #endif } else { char buf[1024]; wsprintf(buf, "Warning, Cannot decrypt type %s (%d)!!!", ENCTYPE_NAME_OK(decrypt_mode) ? ENCTYPE_NAME(decrypt_mode) : "(unknown)", decrypt_mode); MessageBox(NULL, buf, NULL, MB_OK | MB_ICONEXCLAMATION); encrypt_send_request_end(); } } void encrypt_session_key(key, server) Session_Key *key; int server; { Encryptions *ep = encryptions; havesessionkey = 1; while (ep->type) { if (ep->session) (*ep->session)(key, server); #if defined(notdef) if (!encrypt_output && autoencrypt && !server) encrypt_start_output(ep->type); if (!decrypt_input && autodecrypt && !server) encrypt_send_request_start(); #endif ++ep; } } /* * Called when ENCRYPT END is received. */ void encrypt_end() { decrypt_input = NULL; EncryptKSGlobalHack->decrypt = NULL; #ifdef DEBUG if (encrypt_debug_mode) { sprintf(dbgbuf, ">>>Input is back to clear text\n"); OutputDebugString(dbgbuf); } #endif if (encrypt_verbose) { sprintf(dbgbuf, "[ Input is now clear text ]\n"); OutputDebugString(dbgbuf); } } /* * Called when ENCRYPT REQUEST-END is received. */ void encrypt_request_end() { encrypt_send_end(); } /* * Called when ENCRYPT REQUEST-START is received. If we receive * this before a type is picked, then that indicates that the * other side wants us to start encrypting data as soon as we * can. */ void encrypt_request_start(data, cnt) unsigned char *data; int cnt; { if (encrypt_mode == 0) { return; } encrypt_start_output(encrypt_mode); } static unsigned char str_keyid[(MAXKEYLEN*2)+5] = { IAC, SB, TELOPT_ENCRYPT }; void encrypt_keyid(); void encrypt_enc_keyid(keyid, len) unsigned char *keyid; int len; { encrypt_keyid(&ki[1], keyid, len); } void encrypt_dec_keyid(keyid, len) unsigned char *keyid; int len; { encrypt_keyid(&ki[0], keyid, len); } void encrypt_keyid(kp, keyid, len) struct key_info *kp; unsigned char *keyid; int len; { Encryptions *ep; int dir = kp->dir; register int ret = 0; if (!(ep = (*kp->getcrypt)(*kp->modep))) { if (len == 0) return; kp->keylen = 0; } else if (len == 0) { /* * Empty option, indicates a failure. */ if (kp->keylen == 0) return; kp->keylen = 0; if (ep->keyid) (void)(*ep->keyid)(dir, kp->keyid, &kp->keylen); } else if ((len != kp->keylen) || (memcmp(keyid, kp->keyid, len) != 0)) { /* * Length or contents are different */ kp->keylen = len; memcpy(kp->keyid, keyid, len); if (ep->keyid) (void)(*ep->keyid)(dir, kp->keyid, &kp->keylen); } else { if (ep->keyid) ret = (*ep->keyid)(dir, kp->keyid, &kp->keylen); if ((ret == 0) && (dir == DIR_ENCRYPT) && autoencrypt) encrypt_start_output(*kp->modep); return; } encrypt_send_keyid(dir, kp->keyid, kp->keylen, 0); } void encrypt_send_keyid(dir, keyid, keylen, saveit) int dir; unsigned char *keyid; int keylen; int saveit; { unsigned char *strp; str_keyid[3] = (dir == DIR_ENCRYPT) ? ENCRYPT_ENC_KEYID : ENCRYPT_DEC_KEYID; if (saveit) { struct key_info *kp = &ki[(dir == DIR_ENCRYPT) ? 0 : 1]; memcpy(kp->keyid, keyid, keylen); kp->keylen = keylen; } for (strp = &str_keyid[4]; keylen > 0; --keylen) { if ((*strp++ = *keyid++) == IAC) *strp++ = IAC; } *strp++ = IAC; *strp++ = SE; TelnetSend(EncryptKSGlobalHack, str_keyid, strp - str_keyid, 0); #ifdef DEBUG printsub('>', &str_keyid[2], strp - str_keyid - 2); #endif } void encrypt_auto(on) int on; { if (on < 0) autoencrypt ^= 1; else autoencrypt = on ? 1 : 0; } void decrypt_auto(on) int on; { if (on < 0) autodecrypt ^= 1; else autodecrypt = on ? 1 : 0; } void encrypt_start_output(type) int type; { Encryptions *ep; register unsigned char *p; register int i; if (!(ep = findencryption(type))) { #ifdef DEBUG if (encrypt_debug_mode) { sprintf(dbgbuf, ">>>Can't encrypt with type %s (%d)\n", ENCTYPE_NAME_OK(type) ? ENCTYPE_NAME(type) : "(unknown)", type); OutputDebugString(dbgbuf); } #endif return; } if (ep->start) { i = (*ep->start)(DIR_ENCRYPT, 0); #ifdef DEBUG if (encrypt_debug_mode) { sprintf(dbgbuf, ">>>Encrypt start: %s (%d) %s\n", (i < 0) ? "failed" : "initial negotiation in progress", i, ENCTYPE_NAME(type)); OutputDebugString(dbgbuf); } #endif if (i) return; } p = str_start + 3; *p++ = ENCRYPT_START; for (i = 0; i < ki[0].keylen; ++i) { if ((*p++ = ki[0].keyid[i]) == IAC) *p++ = IAC; } *p++ = IAC; *p++ = SE; TelnetSend(EncryptKSGlobalHack, str_start, p - str_start, 0); #ifdef DEBUG printsub('>', &str_start[2], p - &str_start[2]); #endif /* * If we are already encrypting in some mode, then * encrypt the ring (which includes our request) in * the old mode, mark it all as "clear text" and then * switch to the new mode. */ encrypt_output = ep->output; EncryptKSGlobalHack->encrypt = encrypt_ks_stream; encrypt_mode = type; #ifdef DEBUG if (encrypt_debug_mode) { sprintf(dbgbuf, ">>>Started to encrypt output with type %s\n", ENCTYPE_NAME(type)); OutputDebugString(dbgbuf); } #endif if (encrypt_verbose) { sprintf(dbgbuf, "[ Output is now encrypted with type %s ]\n", ENCTYPE_NAME(type)); OutputDebugString(dbgbuf); } } void encrypt_send_end() { if (!encrypt_output) return; str_end[3] = ENCRYPT_END; TelnetSend(EncryptKSGlobalHack, str_end, sizeof(str_end), 0); #ifdef DEBUG printsub('>', &str_end[2], sizeof(str_end) - 2); #endif /* * Encrypt the output buffer now because it will not be done by * netflush... */ encrypt_output = 0; EncryptKSGlobalHack->encrypt = NULL; #ifdef DEBUG if (encrypt_debug_mode) { sprintf(dbgbuf, ">>>Output is back to clear text\n"); OutputDebugString(dbgbuf); } #endif if (encrypt_verbose) { sprintf(dbgbuf, "[ Output is now clear text ]\n"); OutputDebugString(dbgbuf); } } void encrypt_send_request_start() { register unsigned char *p; register int i; p = &str_start[3]; *p++ = ENCRYPT_REQSTART; for (i = 0; i < ki[1].keylen; ++i) { if ((*p++ = ki[1].keyid[i]) == IAC) *p++ = IAC; } *p++ = IAC; *p++ = SE; TelnetSend(EncryptKSGlobalHack, str_start, p - str_start, 0); #ifdef DEBUG printsub('>', &str_start[2], p - &str_start[2]); if (encrypt_debug_mode) { sprintf(dbgbuf, ">>>Request input to be encrypted\n"); OutputDebugString(dbgbuf); } #endif } void encrypt_send_request_end() { str_end[3] = ENCRYPT_REQEND; TelnetSend(EncryptKSGlobalHack, str_end, sizeof(str_end), 0); #ifdef DEBUG printsub('>', &str_end[2], sizeof(str_end) - 2); if (encrypt_debug_mode) { sprintf(dbgbuf, ">>>Request input to be clear text\n"); OutputDebugString(dbgbuf); } #endif } int encrypt_is_encrypting() { if (encrypt_output && decrypt_input) return 1; return 0; } #ifdef DEBUG void encrypt_debug(mode) int mode; { encrypt_debug_mode = mode; } #endif #if 0 void encrypt_gen_printsub(data, cnt, buf, buflen) unsigned char *data, *buf; int cnt, buflen; { char tbuf[16], *cp; cnt -= 2; data += 2; buf[buflen-1] = '\0'; buf[buflen-2] = '*'; buflen -= 2;; for (; cnt > 0; cnt--, data++) { sprintf(tbuf, " %d", *data); for (cp = tbuf; *cp && buflen > 0; --buflen) *buf++ = *cp++; if (buflen <= 0) return; } *buf = '\0'; } void encrypt_printsub(data, cnt, buf, buflen) unsigned char *data, *buf; int cnt, buflen; { Encryptions *ep; register int type = data[1]; for (ep = encryptions; ep->type && ep->type != type; ep++) ; if (ep->printsub) (*ep->printsub)(data, cnt, buf, buflen); else encrypt_gen_printsub(data, cnt, buf, buflen); } #endif #endif /* ENCRYPTION */ krb5-1.16/src/windows/wintel/telnet_arpa.h0000644000704600001450000002461413211554426020437 0ustar ghudsonlibuuid/* * Copyright (c) 1983, 1993 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * @(#)telnet.h 8.1 (Berkeley) 6/2/93 */ #ifndef _TELNET_H_ #define _TELNET_H_ /* * Definitions for the TELNET protocol. */ #define IAC 255 /* interpret as command: */ #define DONT 254 /* you are not to use option */ #define DO 253 /* please, you use option */ #define WONT 252 /* I won't use option */ #define WILL 251 /* I will use option */ #define SB 250 /* interpret as subnegotiation */ #define GA 249 /* you may reverse the line */ #define EL 248 /* erase the current line */ #define EC 247 /* erase the current character */ #define AYT 246 /* are you there */ #define AO 245 /* abort output--but let prog finish */ #define IP 244 /* interrupt process--permanently */ #define BREAK 243 /* break */ #define DM 242 /* data mark--for connect. cleaning */ #define NOP 241 /* nop */ #define SE 240 /* end sub negotiation */ #define EOR 239 /* end of record (transparent mode) */ #define ABORT 238 /* Abort process */ #define SUSP 237 /* Suspend process */ #define xEOF 236 /* End of file: EOF is already used... */ #define SYNCH 242 /* for telfunc calls */ #ifdef TELCMDS char *telcmds[] = { "EOF", "SUSP", "ABORT", "EOR", "SE", "NOP", "DMARK", "BRK", "IP", "AO", "AYT", "EC", "EL", "GA", "SB", "WILL", "WONT", "DO", "DONT", "IAC", 0, }; #else extern char *telcmds[]; #endif #define TELCMD_FIRST xEOF #define TELCMD_LAST IAC #define TELCMD_OK(x) ((unsigned int)(x) <= TELCMD_LAST && \ (unsigned int)(x) >= TELCMD_FIRST) #define TELCMD(x) telcmds[(x)-TELCMD_FIRST] /* telnet options */ #define TELOPT_BINARY 0 /* 8-bit data path */ #define TELOPT_ECHO 1 /* echo */ #define TELOPT_RCP 2 /* prepare to reconnect */ #define TELOPT_SGA 3 /* suppress go ahead */ #define TELOPT_NAMS 4 /* approximate message size */ #define TELOPT_STATUS 5 /* give status */ #define TELOPT_TM 6 /* timing mark */ #define TELOPT_RCTE 7 /* remote controlled transmission and echo */ #define TELOPT_NAOL 8 /* negotiate about output line width */ #define TELOPT_NAOP 9 /* negotiate about output page size */ #define TELOPT_NAOCRD 10 /* negotiate about CR disposition */ #define TELOPT_NAOHTS 11 /* negotiate about horizontal tabstops */ #define TELOPT_NAOHTD 12 /* negotiate about horizontal tab disposition */ #define TELOPT_NAOFFD 13 /* negotiate about formfeed disposition */ #define TELOPT_NAOVTS 14 /* negotiate about vertical tab stops */ #define TELOPT_NAOVTD 15 /* negotiate about vertical tab disposition */ #define TELOPT_NAOLFD 16 /* negotiate about output LF disposition */ #define TELOPT_XASCII 17 /* extended ascic character set */ #define TELOPT_LOGOUT 18 /* force logout */ #define TELOPT_BM 19 /* byte macro */ #define TELOPT_DET 20 /* data entry terminal */ #define TELOPT_SUPDUP 21 /* supdup protocol */ #define TELOPT_SUPDUPOUTPUT 22 /* supdup output */ #define TELOPT_SNDLOC 23 /* send location */ #define TELOPT_TTYPE 24 /* terminal type */ #define TELOPT_EOR 25 /* end or record */ #define TELOPT_TUID 26 /* TACACS user identification */ #define TELOPT_OUTMRK 27 /* output marking */ #define TELOPT_TTYLOC 28 /* terminal location number */ #define TELOPT_3270REGIME 29 /* 3270 regime */ #define TELOPT_X3PAD 30 /* X.3 PAD */ #define TELOPT_NAWS 31 /* window size */ #define TELOPT_TSPEED 32 /* terminal speed */ #define TELOPT_LFLOW 33 /* remote flow control */ #define TELOPT_LINEMODE 34 /* Linemode option */ #define TELOPT_XDISPLOC 35 /* X Display Location */ #define TELOPT_OLD_ENVIRON 36 /* Old - Environment variables */ #define TELOPT_AUTHENTICATION 37/* Authenticate */ #define TELOPT_ENCRYPT 38 /* Encryption option */ #define TELOPT_NEW_ENVIRON 39 /* New - Environment variables */ #define TELOPT_EXOPL 255 /* extended-options-list */ #define NTELOPTS (1+TELOPT_NEW_ENVIRON) #ifdef TELOPTS char *telopts[NTELOPTS+1] = { "BINARY", "ECHO", "RCP", "SUPPRESS GO AHEAD", "NAME", "STATUS", "TIMING MARK", "RCTE", "NAOL", "NAOP", "NAOCRD", "NAOHTS", "NAOHTD", "NAOFFD", "NAOVTS", "NAOVTD", "NAOLFD", "EXTEND ASCII", "LOGOUT", "BYTE MACRO", "DATA ENTRY TERMINAL", "SUPDUP", "SUPDUP OUTPUT", "SEND LOCATION", "TERMINAL TYPE", "END OF RECORD", "TACACS UID", "OUTPUT MARKING", "TTYLOC", "3270 REGIME", "X.3 PAD", "NAWS", "TSPEED", "LFLOW", "LINEMODE", "XDISPLOC", "OLD-ENVIRON", "AUTHENTICATION", "ENCRYPT", "NEW-ENVIRON", 0, }; #define TELOPT_FIRST TELOPT_BINARY #define TELOPT_LAST TELOPT_NEW_ENVIRON #define TELOPT_OK(x) ((unsigned int)(x) <= TELOPT_LAST) #define TELOPT(x) telopts[(x)-TELOPT_FIRST] #endif /* sub-option qualifiers */ #define TELQUAL_IS 0 /* option is... */ #define TELQUAL_SEND 1 /* send option */ #define TELQUAL_INFO 2 /* ENVIRON: informational version of IS */ #define TELQUAL_REPLY 2 /* AUTHENTICATION: client version of IS */ #define TELQUAL_NAME 3 /* AUTHENTICATION: client version of IS */ #define LFLOW_OFF 0 /* Disable remote flow control */ #define LFLOW_ON 1 /* Enable remote flow control */ #define LFLOW_RESTART_ANY 2 /* Restart output on any char */ #define LFLOW_RESTART_XON 3 /* Restart output only on XON */ /* * LINEMODE suboptions */ #define LM_MODE 1 #define LM_FORWARDMASK 2 #define LM_SLC 3 #define MODE_EDIT 0x01 #define MODE_TRAPSIG 0x02 #define MODE_ACK 0x04 #define MODE_SOFT_TAB 0x08 #define MODE_LIT_ECHO 0x10 #define MODE_MASK 0x1f /* Not part of protocol, but needed to simplify things... */ #define MODE_FLOW 0x0100 #define MODE_ECHO 0x0200 #define MODE_INBIN 0x0400 #define MODE_OUTBIN 0x0800 #define MODE_FORCE 0x1000 #define SLC_SYNCH 1 #define SLC_BRK 2 #define SLC_IP 3 #define SLC_AO 4 #define SLC_AYT 5 #define SLC_EOR 6 #define SLC_ABORT 7 #define SLC_EOF 8 #define SLC_SUSP 9 #define SLC_EC 10 #define SLC_EL 11 #define SLC_EW 12 #define SLC_RP 13 #define SLC_LNEXT 14 #define SLC_XON 15 #define SLC_XOFF 16 #define SLC_FORW1 17 #define SLC_FORW2 18 #define NSLC 18 /* * For backwards compatability, we define SLC_NAMES to be the * list of names if SLC_NAMES is not defined. */ #define SLC_NAMELIST "0", "SYNCH", "BRK", "IP", "AO", "AYT", "EOR", \ "ABORT", "EOF", "SUSP", "EC", "EL", "EW", "RP", \ "LNEXT", "XON", "XOFF", "FORW1", "FORW2", 0, #ifdef SLC_NAMES char *slc_names[] = { SLC_NAMELIST }; #else extern char *slc_names[]; #define SLC_NAMES SLC_NAMELIST #endif #define SLC_NAME_OK(x) ((unsigned int)(x) <= NSLC) #define SLC_NAME(x) slc_names[x] #define SLC_NOSUPPORT 0 #define SLC_CANTCHANGE 1 #define SLC_VARIABLE 2 #define SLC_DEFAULT 3 #define SLC_LEVELBITS 0x03 #define SLC_FUNC 0 #define SLC_FLAGS 1 #define SLC_VALUE 2 #define SLC_ACK 0x80 #define SLC_FLUSHIN 0x40 #define SLC_FLUSHOUT 0x20 #define OLD_ENV_VAR 1 #define OLD_ENV_VALUE 0 #define NEW_ENV_VAR 0 #define NEW_ENV_VALUE 1 #define ENV_ESC 2 #define ENV_USERVAR 3 /* * AUTHENTICATION suboptions */ /* * Who is authenticating who ... */ #define AUTH_WHO_CLIENT 0 /* Client authenticating server */ #define AUTH_WHO_SERVER 1 /* Server authenticating client */ #define AUTH_WHO_MASK 1 /* * amount of authentication done */ #define AUTH_HOW_ONE_WAY 0 #define AUTH_HOW_MUTUAL 2 #define AUTH_HOW_MASK 2 /* * should we be encrypting? (not yet formally standardized) */ #define AUTH_ENCRYPT_OFF 0 #define AUTH_ENCRYPT_ON 4 #define AUTH_ENCRYPT_MASK 4 #define AUTHTYPE_NULL 0 #define AUTHTYPE_KERBEROS_V4 1 #define AUTHTYPE_KERBEROS_V5 2 #define AUTHTYPE_SPX 3 #define AUTHTYPE_MINK 4 #define AUTHTYPE_CNT 5 #define AUTHTYPE_TEST 99 #ifdef AUTH_NAMES char *authtype_names[] = { "NULL", "KERBEROS_V4", "KERBEROS_V5", "SPX", "MINK", 0, }; #else extern char *authtype_names[]; #endif #define AUTHTYPE_NAME_OK(x) ((unsigned int)(x) < AUTHTYPE_CNT) #define AUTHTYPE_NAME(x) authtype_names[x] /* * ENCRYPTion suboptions */ #define ENCRYPT_IS 0 /* I pick encryption type ... */ #define ENCRYPT_SUPPORT 1 /* I support encryption types ... */ #define ENCRYPT_REPLY 2 /* Initial setup response */ #define ENCRYPT_START 3 /* Am starting to send encrypted */ #define ENCRYPT_END 4 /* Am ending encrypted */ #define ENCRYPT_REQSTART 5 /* Request you start encrypting */ #define ENCRYPT_REQEND 6 /* Request you send encrypting */ #define ENCRYPT_ENC_KEYID 7 #define ENCRYPT_DEC_KEYID 8 #define ENCRYPT_CNT 9 #define ENCTYPE_ANY 0 #define ENCTYPE_DES_CFB64 1 #define ENCTYPE_DES_OFB64 2 #define ENCTYPE_CNT 3 #ifdef ENCRYPT_NAMES char *encrypt_names[] = { "IS", "SUPPORT", "REPLY", "START", "END", "REQUEST-START", "REQUEST-END", "ENC-KEYID", "DEC-KEYID", 0, }; char *enctype_names[] = { "ANY", "DES_CFB64", "DES_OFB64", 0, }; #else extern char *encrypt_names[]; extern char *enctype_names[]; #endif #define ENCRYPT_NAME_OK(x) ((unsigned int)(x) < ENCRYPT_CNT) #define ENCRYPT_NAME(x) encrypt_names[x] #define ENCTYPE_NAME_OK(x) ((unsigned int)(x) < ENCTYPE_CNT) #define ENCTYPE_NAME(x) enctype_names[x] #endif /* !_TELNET_H_ */ krb5-1.16/src/windows/wintel/font.c0000644000704600001450000000563213211554426017101 0ustar ghudsonlibuuid/* font.c */ #include #include #include #include "screen.h" #include "ini.h" void ProcessFontChange( HWND hWnd) { static DWORD dwFontColor; /* Color of font if one has been selected */ CHOOSEFONT cf; HDC hDC; SCREEN *pScr; TEXTMETRIC tm; char buf[16]; char szStyle[LF_FACESIZE]; pScr = (SCREEN *) GetWindowLong(hWnd, SCREEN_HANDLE); assert(pScr != NULL); cf.lStructSize = sizeof(cf); cf.hwndOwner = hWnd; cf.lpLogFont = (LPLOGFONT) &(pScr->lf); cf.lpszStyle = szStyle; cf.Flags = CF_INITTOLOGFONTSTRUCT; /* | CF_USESTYLE; */ cf.Flags |= CF_SCREENFONTS; #if 0 cf.Flags |= CF_ANSIONLY; #endif cf.Flags |= CF_FORCEFONTEXIST; cf.Flags |= CF_FIXEDPITCHONLY; cf.Flags |= CF_NOSIMULATIONS; if (ChooseFont(&cf)) { if (pScr->hSelectedFont) DeleteObject(pScr->hSelectedFont); pScr->hSelectedFont = CreateFontIndirect(&(pScr->lf)); pScr->lf.lfUnderline = TRUE; pScr->hSelectedULFont = CreateFontIndirect(&(pScr->lf)); pScr->lf.lfUnderline = FALSE; hDC = GetDC(hWnd); SelectObject(hDC, pScr->hSelectedFont); GetTextMetrics(hDC, &tm); pScr->cxChar = tm.tmAveCharWidth; pScr->cyChar = tm.tmHeight + tm.tmExternalLeading; ReleaseDC(hWnd, hDC); SetWindowPos(hWnd, NULL, 0, 0, pScr->cxChar * pScr->width + FRAME_WIDTH, pScr->cyChar * pScr->height + FRAME_HEIGHT, SWP_NOMOVE | SWP_NOZORDER); dwFontColor = RGB(255, 255, 255); InvalidateRect(hWnd, NULL, TRUE); } WritePrivateProfileString(INI_FONT, "FaceName", pScr->lf.lfFaceName, TELNET_INI); wsprintf(buf, "%d", (int) pScr->lf.lfHeight); WritePrivateProfileString(INI_FONT, "Height", buf, TELNET_INI); wsprintf(buf, "%d", (int) pScr->lf.lfWidth); WritePrivateProfileString(INI_FONT, "Width", buf, TELNET_INI); wsprintf(buf, "%d", (int) pScr->lf.lfEscapement); WritePrivateProfileString(INI_FONT, "Escapement", buf, TELNET_INI); wsprintf(buf, "%d", (int) pScr->lf.lfCharSet); WritePrivateProfileString(INI_FONT, "CharSet", buf, TELNET_INI); wsprintf(buf, "%d", (int) pScr->lf.lfPitchAndFamily); WritePrivateProfileString(INI_FONT, "PitchAndFamily", buf, TELNET_INI); return; } /* ProcessFontChange */ void InitializeStruct( WORD wCommDlgType, LPSTR lpStruct, HWND hWnd) { LPCHOOSEFONT lpFontChunk; if (wCommDlgType == IDC_FONT) { lpFontChunk = (LPCHOOSEFONT) lpStruct; lpFontChunk->lStructSize = sizeof(CHOOSEFONT); lpFontChunk->hwndOwner = hWnd; lpFontChunk->Flags = CF_SCREENFONTS | CF_FIXEDPITCHONLY | CF_INITTOLOGFONTSTRUCT | CF_APPLY; lpFontChunk->rgbColors = RGB(0, 0, 255); lpFontChunk->lCustData = 0L; lpFontChunk->lpfnHook = NULL; lpFontChunk->lpTemplateName = NULL; lpFontChunk->hInstance = NULL; lpFontChunk->lpszStyle = NULL; lpFontChunk->nFontType = SCREEN_FONTTYPE; lpFontChunk->nSizeMin = 0; lpFontChunk->nSizeMax = 0; } } /* InitialiseStruct */ krb5-1.16/src/windows/wintel/negotiat.c0000644000704600001450000005755213211554426017755 0ustar ghudsonlibuuid/* * negotiat.c * * Telnet option negotiation functions * /* * Includes */ /* #define USETEK */ /* #define USERAS */ #ifdef DEBUG /* define this to print the raw network data to debuging monitor */ #define NEGOTIATEDEBUG #endif #if 0 #define PRINT_EVERYTHING /* talk a lot */ #endif #include #include "telnet.h" #include "telnet_arpa.h" #include "auth.h" #include "encrypt.h" #define STNORM 0 #define NEGOTIATE 1 #define ESCFOUND 5 #define IACFOUND 6 unsigned char parsedat[256]; /* Local functions */ static void parse_subnegotiat(kstream ks,int end_sub); /* Local variables */ static char *telstates[]={ "EOF", "Suspend Process", "Abort Process", "Unknown (239)", "Subnegotiation End", "NOP", "Data Mark", "Break", "Interrupt Process", "Abort Output", "Are You There", "Erase Character", "Erase Line", "Go Ahead", "Subnegotiate", "Will", "Won't", "Do", "Don't" }; static char *teloptions[256]={ /* ascii strings for Telnet options */ "Binary", /* 0 */ "Echo", "Reconnection", "Supress Go Ahead", "Message Size Negotiation", "Status", /* 5 */ "Timing Mark", "Remote Controlled Trans and Echo", "Output Line Width", "Output Page Size", "Output Carriage-Return Disposition", /* 10 */ "Output Horizontal Tab Stops", "Output Horizontal Tab Disposition", "Output Formfeed Disposition", "Output Vertical Tabstops", "Output Vertical Tab Disposition", /* 15 */ "Output Linefeed Disposition", "Extended ASCII", "Logout", "Byte Macro", "Data Entry Terminal", /* 20 */ "SUPDUP", "SUPDUP Output", "Send Location", "Terminal Type", "End of Record", /* 25 */ "TACACS User Identification", "Output Marking", "Terminal Location Number", "3270 Regime", "X.3 PAD", /* 30 */ "Negotiate About Window Size", "Terminal Speed", "Toggle Flow Control", "Linemode", "X Display Location", /* 35 */ "Environment", "Authentication", "Data Encryption", "39", "40","41","42","43","44","45","46","47","48","49", "50","51","52","53","54","55","56","57","58","59", "60","61","62","63","64","65","66","67","68","69", "70","71","72","73","74","75","76","77","78","79", "80","81","82","83","84","85","86","87","88","89", "90","91","92","93","94","95","96","97","98","99", "100","101","102","103","104","105","106","107","108","109", "110","111","112","113","114","115","116","117","118","119", "120","121","122","123","124","125","126","127","128","129", "130","131","132","133","134","135","136","137","138","139", "140","141","142","143","144","145","146","147","148","149", "150","151","152","153","154","155","156","157","158","159", "160","161","162","163","164","165","166","167","168","169", "170","171","172","173","174","175","176","177","178","179", "180","181","182","183","184","185","186","187","188","189", "190","191","192","193","194","195","196","197","198","199", "200","201","202","203","204","205","206","207","208","209", "210","211","212","213","214","215","216","217","218","219", "220","221","222","223","224","225","226","227","228","229", "230","231","232","233","234","235","236","237","238","239", "240","241","242","243","244","245","246","247","248","249", "250","251","252","253","254", "Extended Options List" /* 255 */ }; static char *LMoptions[]={ /* ascii strings for Linemode sub-options */ "None", "MODE", "FORWARDMASK", "SLC" }; static char *ModeOptions[]={ /* ascii strings for Linemode edit options */ "None", "EDIT", "TRAPSIG", "ACK", "SOFT TAB", "LIT ECHO" }; static char *SLCoptions[]={ /* ascii strings for Linemode SLC characters */ "None", "SYNCH", "BREAK", "IP", "ABORT OUTPUT", "AYT", "EOR", "ABORT", "EOF", "SUSP", "EC", "EL", "EW", "RP", "LNEXT", "XON", "XOFF", "FORW1", "FORW2", "MCL", "MCR", "MCWL", "MCWR", "MCBOL", "MCEOL", "INSRT", "OVER", "ECR", "EWR", "EBOL", "EEOL" }; static char *SLCflags[]={ /* ascii strings for Linemode SLC flags */ "SLC_NOSUPPORT", "SLC_CANTCHANGE", "SLC_VALUE", "SLC_DEFAULT" }; /* Linemode default character for each function */ static unsigned char LMdefaults[NTELOPTS + 1]={ (unsigned char)-1, /* zero isn't used */ (unsigned char)-1, /* we don't support SYNCH */ 3, /* ^C is default for BRK */ 3, /* ^C is default for IP */ 15, /* ^O is default for AO */ 25, /* ^Y is default for AYT */ /* 5 */ (unsigned char)-1, /* we don't support EOR */ 3, /* ^C is default for ABORT */ 4, /* ^D is default for EOF */ 26, /* ^Z is default for SUSP */ 8, /* ^H is default for EC */ /* 10 */ 21, /* ^U is default for EL */ 23, /* ^W is default for EW */ 18, /* ^R is default for RP */ 22, /* ^V is default for LNEXT */ 17, /* ^Q is default for XON */ /* 15 */ 19, /* ^S is default for XOFF */ 22, /* ^V is default for FORW1 */ 5, /* ^E is default for FORW2 */ (unsigned char)-1, /* we don't support MCL */ (unsigned char)-1, /* we don't support MCR */ /* 20 */ (unsigned char)-1, /* we don't support MCWL */ (unsigned char)-1, /* we don't support MCWR */ (unsigned char)-1, /* we don't support MCBOL */ (unsigned char)-1, /* we don't support MCEOL */ (unsigned char)-1, /* we don't support INSRT */ /* 25 */ (unsigned char)-1, /* we don't support OVER */ (unsigned char)-1, /* we don't support ECR */ (unsigned char)-1, /* we don't support EWR */ (unsigned char)-1, /* we don't support EBOL */ (unsigned char)-1 /* we don't support EEOL */ /* 30 */ }; /* * Function : start_negotiation() * Purpose : Send the initial negotiations on the network and print * the negotitations to the console screen. * Parameters : * dat - the port number to write to * cvs - the console's virtual screen * Returns : none * Calls : tprintf(), netprintf() * Called by : dosessions() */ void start_negotiation(kstream ks) { char buf[128]; /* Send the initial telnet negotiations */ #ifdef ENCRYPTION /* XXX */ if (encrypt_flag) wsprintf(buf,"%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c", IAC, WILL, TELOPT_AUTHENTICATION, IAC, WILL, TELOPT_ENCRYPT, IAC, DO, TELOPT_SGA, IAC, DO, TELOPT_ECHO, IAC, WILL, TELOPT_NAWS ); else #endif wsprintf(buf,"%c%c%c%c%c%c%c%c%c%c%c%c", IAC, WILL, TELOPT_AUTHENTICATION, IAC, DO, TELOPT_SGA, IAC, DO, TELOPT_ECHO, IAC, WILL, TELOPT_NAWS ); TelnetSend(ks,buf,lstrlen(buf),0); #ifdef NOT /* check whether we are going to be output mapping */ if(tw->mapoutput) { netprintf(tw->pnum,"%c%c%c",IAC,DO,TELOPT_BINARY); /* set the flag indicating we wanted server to start transmitting binary */ tw->uwantbinary=1; netprintf(tw->pnum,"%c%c%c",IAC,WILL,TELOPT_BINARY); /* set the flag indicating we want to start transmitting binary */ tw->iwantbinary=1; } /* end if */ #endif /* Print to the console what we just did */ #ifdef NEGOTIATEDEBUG wsprintf(strTmp,"SEND: %s %s\r\n",telstates[DO - TELCMD_FIRST], teloptions[TELOPT_ECHO]); OutputDebugString(strTmp); wsprintf(strTmp,"SEND: %s %s\r\n",telstates[DO - TELCMD_FIRST], teloptions[TELOPT_SGA]); OutputDebugString(strTmp); wsprintf(strTmp,"SEND: %s %s\r\n",telstates[WILL - TELCMD_FIRST], teloptions[TELOPT_NAWS]); OutputDebugString(strTmp); #ifdef NOT tprintf(cvs,"SEND: %s %s\r\n",telstates[DO - TELCMD_FIRST], teloptions[BINARY]); tprintf(cvs,"SEND: %s %s\r\n",telstates[WILL - TELCMD_FIRST], teloptions[BINARY]); #endif #endif } /* end start_negotiation() */ /* * parse * Do the telnet negotiation parsing. * * look at the string which has just come in from outside and * check for special sequences that we are interested in. * * Tries to pass through routine strings immediately, waiting for special * characters ESC and IAC to change modes. */ void parse(CONNECTION *con,unsigned char *st,int cnt) { static int sub_pos; /* the position we are in the subnegotiation parsing */ static int end_sub; /* index of last byte in parsedat in a subnegotiation */ unsigned char *mark, *orig; char buf[256]; kstream ks; ks = con->ks; #ifdef PRINT_EVERYTHING hexdump("Options to process:", st, cnt); #endif /* PRINT_EVERYTHING */ orig = st; /* remember beginning point */ mark = st + cnt; /* set to end of input string */ #ifdef HUH netpush(tw->pnum); #endif /* * traverse string, looking for any special characters which indicate that * we need to change modes. */ while(st < mark) { while(con->telstate != STNORM && st < mark) { switch(con->telstate) { case IACFOUND: /* telnet option negotiation */ if(*st == IAC) { /* real data=255 */ st++; /* real 255 will get sent */ con->telstate = STNORM; break; } /* end if */ if(*st > 239) { con->telstate = *st++; /* by what the option is */ break; } /* end if */ #ifdef NEGOTIATEDEBUG wsprintf(buf, "\r\n strange telnet option"); OutputDebugString(buf); #endif orig=++st; con->telstate=STNORM; break; case EL: /* received a telnet erase line command */ case EC: /* received a telnet erase character command */ case AYT: /* received a telnet Are-You-There command */ case AO: /* received a telnet Abort Output command */ case IP: /* received a telnet Interrupt Process command */ case BREAK: /* received a telnet Break command */ case DM: /* received a telnet Data Mark command */ case NOP: /* received a telnet No Operation command */ case SE: /* received a telnet Subnegotiation End command */ case ABORT: /* received a telnet Abort Process command */ case SUSP: /* received a telnet Suspend Process command */ case xEOF: /* received a telnet EOF command */ #ifdef NEGOTIATEDEBUG wsprintf(buf,"RECV: %s\r\n", telstates[con->telstate-TELCMD_FIRST]); OutputDebugString(buf); #endif con->telstate=STNORM; orig=++st; break; case GA: /* telnet go ahead option*/ #ifdef NEGOTIATEDEBUG wsprintf(buf,"RECV: %s\r\n", telstates[con->telstate-TELCMD_FIRST]); OutputDebugString(buf); #endif con->telstate=STNORM; orig=++st; break; case DO: /* received a telnet DO negotiation */ #ifdef NEGOTIATEDEBUG wsprintf(buf,"RECV: %s %s\r\n", telstates[con->telstate-TELCMD_FIRST],teloptions[*st]); OutputDebugString(buf); #endif switch(*st) { #ifdef NOT case TELOPT_BINARY: /* DO: binary transmission */ if(!tw->ibinary) { /* binary */ if(!tw->iwantbinary) { netprintf(tw->pnum,"%c%c%c", IAC,WILL,BINARY); if(tw->condebug>0) tprintf(cv,"SEND: %s %s\r\n", telstates[WILL - TELCMD_FIRST], teloptions[BINARY]); } /* end if */ else tw->iwantbinary=0; /* turn off this now */ tw->ibinary=1; } /* end if */ else { if(tw->condebug>0) tprintf(cv,"NO REPLY NEEDED: %s %s\r\n", telstates[WILL - TELCMD_FIRST], teloptions[BINARY]); } /* end else */ break; #endif case TELOPT_SGA: /* DO: Suppress go-ahead */ if(!con->igoahead) { /* suppress go-ahead */ wsprintf(buf,"%c%c%c",IAC,WILL,TELOPT_SGA); TelnetSend(ks,buf,lstrlen(buf),0); #ifdef NEGOTIATEDEBUG wsprintf(strTmp,"SEND: %s %s\r\n", telstates[WILL - TELCMD_FIRST], teloptions[TELOPT_SGA]); OutputDebugString(strTmp); OutputDebugString("igoahead"); #endif con->igoahead=1; } /* end if */ else { #ifdef NEGOTIATEDEBUG wsprintf(strTmp, "NO REPLY NEEDED: %s %s\r\n", telstates[WILL - TELCMD_FIRST], teloptions[TELOPT_SGA]); OutputDebugString(strTmp); #endif } /* end else */ break; case TELOPT_TTYPE: /* DO: terminal type negotiation */ if(!con->termsent) { con->termsent=TRUE; wsprintf(buf,"%c%c%c",IAC,WILL,TELOPT_TTYPE); TelnetSend(ks,buf,lstrlen(buf),0); #ifdef NEGOTIATEDEBUG wsprintf(strTmp,"SEND: %s %s\r\n", telstates[WILL - TELCMD_FIRST], teloptions[TELOPT_TTYPE]); OutputDebugString(strTmp); #endif } /* end if */ else { #ifdef NEGOTIATEDEBUG wsprintf(strTmp,"NO REPLY NEEDED: %s %s\r\n", telstates[WILL - TELCMD_FIRST], teloptions[TELOPT_TTYPE]); OutputDebugString(strTmp); #endif } /* end else */ break; #ifdef LATER case TELOPT_LINEMODE: /* DO: linemode negotiation */ tw->lmflag=1; /* set the linemode flag */ netprintf(tw->pnum,"%c%c%c",IAC,WILL,TELOPT_LINEMODE); /* * Tell the other side to send us * its default character set */ netprintf(tw->pnum,"%c%c%c%c", IAC,SB,TELOPT_LINEMODE,SLC,0,SLC_DEFAULT,0,IAC,SE); if(tw->condebug>0) { tprintf(cv,"SEND: %s %s\r\n", telstates[WILL - TELCMD_FIRST], teloptions[TELOPT_LINEMODE]); tprintf(cv, "SEND: SB LINEMODE SLC 0 SLC_DEFAULT 0 IAC SE\r\n"); } /* end if */ break; #endif case TELOPT_NAWS: /* DO: Negotiate About Window Size */ con->bResizeable=TRUE; send_naws(con); break; case TELOPT_AUTHENTICATION: /* DO: Authentication requested */ wsprintf(buf, "%c%c%c", IAC, WILL, TELOPT_AUTHENTICATION); TelnetSend(ks, buf, lstrlen(buf), 0); #ifdef NEGOTIATEDEBUG wsprintf(strTmp,"SEND: %s %s\r\n", telstates[WILL - TELCMD_FIRST], teloptions[TELOPT_AUTHENTICATION]); OutputDebugString(strTmp); #endif break; #ifdef ENCRYPTION case TELOPT_ENCRYPT: /* DO: Remote is willing to receive encrypted */ wsprintf(buf, "%c%c%c", IAC, (encrypt_flag ? WILL : WONT), TELOPT_ENCRYPT); TelnetSend(ks, buf, lstrlen(buf), 0); #ifdef NEGOTIATEDEBUG wsprintf(strTmp,"SEND: %s %s\r\n", telstates[(encrypt_flag ? WILL : WONT) - TELCMD_FIRST], teloptions[TELOPT_ENCRYPT]); OutputDebugString(strTmp); #endif break; #endif /* ENCRYPTION */ default: /* DO: */ wsprintf(buf, "%c%c%c", IAC, WONT, *st); TelnetSend(ks, buf, lstrlen(buf), 0); #ifdef NEGOTIATEDEBUG wsprintf(strTmp,"SEND: %s %s\r\n", telstates[WONT - TELCMD_FIRST], teloptions[*st]); OutputDebugString(strTmp); #endif break; } /* end switch */ con->telstate = STNORM; orig = ++st; break; case DONT: /* Received a telnet DONT option */ switch (*st) { case TELOPT_NAWS: con->bResizeable=FALSE; #ifdef NEGOTIATEDEBUG wsprintf(strTmp,"RECV: %s %s\r\n", telstates[con->telstate-TELCMD_FIRST],teloptions[*st]); OutputDebugString(strTmp); #endif break; #ifdef NOT case BINARY: /* DONT: check for binary neg. */ if(tw->ibinary) { /* binary */ if(!tw->iwantbinary) { netprintf(tw->pnum,"%c%c%c",IAC,WONT,BINARY); if(tw->condebug>0) tprintf(cv,"SEND: %s %s\r\n", telstates[WONT-TELCMD_FIRST], teloptions[BINARY]); } /* end if */ else tw->iwantbinary=0; /* turn off this now */ tw->ibinary=0; tw->mapoutput=0; /* turn output mapping off */ } /* end if */ #ifdef NEGOTIATEDEBUG wsprintf(strTmp,"NO REPLY NEEDED: %s %s\r\n", telstates[WONT-TELCMD_FIRST], teloptions[BINARY]); OutputDebugString(strTmp); #endif break; #endif #ifdef ENCRYPTION case ENCRYPTION: break; #endif } /* all these just fall through to here... */ con->telstate=STNORM; orig=++st; break; case WILL: /* received a telnet WILL option */ #ifdef NEGOTIATEDEBUG wsprintf(strTmp,"RECV: %s %s\r\n", telstates[con->telstate-TELCMD_FIRST], teloptions[*st]); OutputDebugString(strTmp); #endif switch(*st) { #ifdef NOT case TELOPT_BINARY: /* WILL: binary */ if(!tw->ubinary) { /* binary */ if(!tw->uwantbinary) { netprintf(tw->pnum,"%c%c%c", IAC,DO,TELOPT_BINARY); if(tw->condebug>0) tprintf(cv,"SEND: %s %s\r\n", telstates[DO - TELCMD_FIRST], teloptions[TELOPT_BINARY]); } /* end if */ else tw->uwantbinary=0; /* turn off this now */ tw->ubinary=1; } /* end if */ else { if(tw->condebug>0) tprintf(cv,"NO REPLY NEEDED: %s %s\r\n", telstates[DO - TELCMD_FIRST], teloptions[TELOPT_BINARY]); } /* end else */ break; #endif case TELOPT_SGA: /* WILL: suppress go-ahead */ if(!con->ugoahead) { con->ugoahead=1; wsprintf(buf,"%c%c%c",IAC,DO,TELOPT_SGA); /* ack */ TelnetSend(ks,buf,lstrlen(buf),0); #ifdef NEGOTIATEDEBUG wsprintf(strTmp,"SEND: %s %s\r\n", telstates[DO - TELCMD_FIRST], teloptions[TELOPT_SGA]); OutputDebugString(strTmp); #endif } /* end if */ break; case TELOPT_ECHO: /* WILL: echo */ if(!con->echo) { con->echo = 1; wsprintf(buf, "%c%c%c", IAC, DO, TELOPT_ECHO); /* ack */ TelnetSend(ks, buf, lstrlen(buf), 0); #ifdef NEGOTIATEDEBUG wsprintf(strTmp,"SEND: %s %s\r\n", telstates[DO - TELCMD_FIRST], teloptions[TELOPT_ECHO]); OutputDebugString(strTmp); #endif } /* end if */ break; case TELOPT_TM: /* WILL: Timing mark */ con->timing=0; break; #ifdef ENCRYPTION case TELOPT_ENCRYPT: /* WILL: decrypt our input */ wsprintf(buf, "%c%c%c", IAC, (encrypt_flag ? DO : DONT), TELOPT_ENCRYPT); TelnetSend(ks, buf, lstrlen(buf), 0); if (encrypt_flag) encrypt_send_support(); #ifdef NEGOTIATEDEBUG wsprintf(strTmp,"SEND: %s %s\r\n", telstates[(encrypt_flag ? DO : DONT) - TELCMD_FIRST], teloptions[TELOPT_ENCRYPT]); OutputDebugString(strTmp); #endif break; #endif default: wsprintf(buf,"%c%c%c",IAC,DONT,*st); TelnetSend(ks,buf,lstrlen(buf),0); #ifdef NEGOTIATEDEBUG wsprintf(strTmp,"SEND: %s %s\r\n", telstates[DONT-TELCMD_FIRST],teloptions[*st]); OutputDebugString(strTmp); #endif break; } /* end switch */ con->telstate=STNORM; orig=++st; break; case WONT: /* Received a telnet WONT option */ #ifdef NEGOTIATEDEBUG wsprintf(strTmp,"RECV: %s %s\r\n", telstates[con->telstate-TELCMD_FIRST],teloptions[*st]); OutputDebugString((LPSTR)strTmp); #endif con->telstate=STNORM; switch(*st++) { /* which option? */ #ifdef NOT case BINARY: /* WONT: binary */ if(tw->ubinary) { /* binary */ if(!tw->uwantbinary) { netprintf(tw->pnum,"%c%c%c", IAC,DONT,BINARY); if(tw->condebug>0) tprintf(cv,"SEND: %s %s\r\n", telstates[DONT-TELCMD_FIRST], teloptions[BINARY]); } /* end if */ else tw->uwantbinary=0; /* turn off this now */ tw->ubinary=0; tw->mapoutput=0; /* turn output mapping off */ } /* end if */ else { if(tw->condebug>0) tprintf(cv,"NO REPLY NEEDED: %s %s\r\n", telstates[DONT-TELCMD_FIRST], teloptions[BINARY]); } /* end else */ break; #endif case TELOPT_ECHO: /* WONT: echo */ if(con->echo) { con->echo=0; wsprintf(buf,"%c%c%c",IAC,DONT,TELOPT_ECHO); TelnetSend(ks,buf,lstrlen(buf),0); #ifdef NEGOTIATEDEBUG wsprintf(strTmp,"SEND: %s %s\r\n", telstates[DONT-TELCMD_FIRST], teloptions[TELOPT_ECHO]); OutputDebugString(strTmp); OutputDebugString("Other side won't echo!"); #endif } /* end if */ break; case TELOPT_TM: /* WONT: Telnet timing mark option */ con->timing=0; break; #ifdef ENCRYPTION case TELOPT_ENCRYPT: /* WONT: don't encrypt our input */ break; #endif default: break; } /* end switch */ orig=st; break; case SB: /* telnet sub-options negotiation */ con->telstate=NEGOTIATE; orig=st; end_sub=0; sub_pos=con->substate=0; /* Defined for each */ #ifdef OLD_WAY break; #endif case NEGOTIATE: /* until we change sub-negotiation states, accumulate bytes */ if(con->substate==0) { if(*st==IAC) { /* check if we found an IAC byte */ if(*(st+1)==IAC) { /* skip over double IAC's */ st++; parsedat[sub_pos++]=*st++; } /* end if */ else { end_sub=sub_pos; con->substate=*st++; } /* end else */ } /* end if */ else /* otherwise, just stash the byte */ parsedat[sub_pos++]=*st++; } /* end if */ else { con->substate=*st++; /* check if we've really ended the sub-negotiations */ if(con->substate==SE) parse_subnegotiat(ks,end_sub); orig=st; /* * XXX hack to decrypt the rest of the buffer */ if (encrypt_flag == 2) { decrypt_ks_hack(orig, mark - orig); encrypt_flag = 1; } con->telstate=STNORM; } /* end else */ break; default: con->telstate=STNORM; break; } /* end switch */ } /* end while */ /* * quick scan of the remaining string, skip chars while they are * uninteresting */ if(con->telstate==STNORM && stubinary) *st&=127; /* mask off high bit */ #endif st++; } /* end while */ #if 0 if(!tw->timing) parsewrite(tw,orig,st-orig); #endif orig=st; /* forget what we have sent already */ if(sttelstate=IACFOUND; st++; break; default: #ifdef NEGOTIATEDEBUG wsprintf(buf," strange char>128 0x%x\r\n", *st); OutputDebugString(buf); #endif st++; break; } /* end switch */ } /* end if */ } /* end while */ } /* end parse() */ /* * Function : parse_subnegotiat() * Purpose : Parse the telnet sub-negotiations read into the parsedat * array. * Parameters : * end_sub - index of the character in the 'parsedat' array which * is the last byte in a sub-negotiation * Returns : none * Calls : * Called by : parse() */ static void parse_subnegotiat(kstream ks, int end_sub) { char buf[128]; switch(parsedat[0]) { case TELOPT_TTYPE: if(parsedat[1]==1) { /* QAK!!! */ wsprintf(buf,"%c%c%c%cvt100%c%c",IAC,SB,TELOPT_TTYPE, 0,IAC,SE); TelnetSend(ks,(LPSTR)buf,11,0); #ifdef NEGOTIATEDEBUG wsprintf(strTmp,"SB TERMINAL-TYPE SEND\r\n" "SEND: SB TERMINAL-TYPE IS vt100 \r\n len=%d \r\n", lstrlen((LPSTR)buf)); OutputDebugString(strTmp); #endif } break; case TELOPT_AUTHENTICATION: auth_parse(ks, parsedat, end_sub); break; #ifdef ENCRYPTION case TELOPT_ENCRYPT: if (encrypt_flag) encrypt_parse(ks, parsedat, end_sub); break; #endif default: break; } /* end switch */ } /* parse_subnegotiat */ /* * Function : send_naws * Purpose : Send a window size sub-negotiation. * Parameters : * ks - the kstream to send to. * Returns : none */ void send_naws(CONNECTION *con) { unsigned char buf[40]; int len; wsprintf(buf, "%c%c%c", IAC, SB, TELOPT_NAWS); len = 3; buf[len++] = HIBYTE(con->width); if (buf[len-1] == IAC) buf[len++] = IAC; buf[len++] = LOBYTE(con->width); if (buf[len-1] == IAC) buf[len++] = IAC; buf[len++] = HIBYTE(con->height); if (buf[len-1] == IAC) buf[len++] = IAC; buf[len++] = LOBYTE(con->height); if (buf[len-1] == IAC) buf[len++] = IAC; buf[len++] = IAC; buf[len++] = SE; TelnetSend(con->ks, buf, len, 0); #ifdef NEGOTIATEDEBUG wsprintf(buf, "SEND: SB NAWS %d %d %d %d IAC SE\r\n", HIBYTE(con->width), LOBYTE(con->width), HIBYTE(con->height), LOBYTE(con->height)); OutputDebugString(buf); #endif } /* send_naws */ krb5-1.16/src/windows/wintel/ini.h0000644000704600001450000000066113211554426016714 0ustar ghudsonlibuuid/* Defines INI file vocabulary */ #define TELNET_INI "kerberos.ini" #define INI_TELNET "Telnet" #define INI_FONT "Font" #define INI_WIDTH "Width" #define INI_HEIGHT "Height" #define INI_POSITION "Position" #define INI_BACKSPACE "Backspace" #define INI_BACKSPACE_BS "BS" #define INI_BACKSPACE_DEL "DEL" #define INI_HOSTS "Telnet Hosts" #define INI_HOST "Host" #define INI_HOST_BS "BS" #define INI_HOST_DEL "DEL" krb5-1.16/src/windows/wintel/edit.c0000644000704600001450000002771213211554426017063 0ustar ghudsonlibuuid/* edit.c */ #include #include #include #include #include "screen.h" char *cInvertedArray; int bMouseDown = FALSE; int bSelection; static int iLocStart; static int iLocEnd; void Edit_LbuttonDown( HWND hWnd, LPARAM lParam) { SCREEN *pScr; HMENU hMenu; int iTmp; int iXlocStart; int iYlocStart; HDC hDC; pScr = (SCREEN *) GetWindowLong(hWnd, SCREEN_HANDLE); assert(pScr != NULL); hDC = GetDC(hWnd); for (iTmp = 0; iTmp < pScr->width * pScr->height; iTmp++) { if (cInvertedArray[iTmp]) { PatBlt(hDC, iTmp % pScr->width * pScr->cxChar, (int) (iTmp / pScr->width) * pScr->cyChar, pScr->cxChar, pScr->cyChar, DSTINVERT); cInvertedArray[iTmp] = 0; } } bSelection = FALSE; hMenu = GetMenu(hWnd); EnableMenuItem(hMenu, IDM_COPY, MF_GRAYED); ReleaseDC(hWnd, hDC); iXlocStart = (int) LOWORD(lParam) / pScr->cxChar; if (iXlocStart >= pScr->width) iXlocStart = pScr->width - 1; iYlocStart = (int) HIWORD(lParam) / pScr->cyChar; if (iYlocStart >= pScr->height) iYlocStart = pScr->height - 1; iLocStart = iXlocStart + iYlocStart * pScr->width; bMouseDown = TRUE; } /* Edit_LbuttonDown */ void Edit_LbuttonUp( HWND hWnd, LPARAM lParam) { SCREEN *pScr; int iTmp; int iTmp2; HMENU hMenu; bMouseDown = FALSE; if (bSelection) return; bSelection = TRUE; pScr = (SCREEN *) GetWindowLong(hWnd, SCREEN_HANDLE); assert(pScr != NULL); iTmp = (int) LOWORD(lParam) / pScr->cxChar; if (iTmp >= pScr->width) iTmp = pScr->width - 1; iTmp2 = (int) HIWORD(lParam) / pScr->cyChar; if (iTmp2 >= pScr->height) iTmp2 = pScr->height - 1; iLocEnd = iTmp + iTmp2 * pScr->width; if (iLocEnd == iLocStart) { bSelection = FALSE; } else { hMenu = GetMenu(hWnd); EnableMenuItem(hMenu, IDM_COPY, MF_ENABLED); } } /* Edit_LbuttonUp */ void Edit_MouseMove(HWND hWnd, LPARAM lParam){ SCREEN *pScr; int iTmp; int iTmp2; int iXlocCurr; int iYlocCurr; int iLocCurr; int iX; int iX2; int iY; int iY2; SCREENLINE *pScrLine; HDC hDC; pScr = (SCREEN *) GetWindowLong(hWnd, SCREEN_HANDLE); assert(pScr != NULL); hDC = GetDC(hWnd); iXlocCurr = (int) LOWORD(lParam) / pScr->cxChar; if (iXlocCurr >= pScr->width) iXlocCurr = pScr->width - 1; iYlocCurr = (int) HIWORD(lParam) / pScr->cyChar; if (iYlocCurr >= pScr->height) iYlocCurr = pScr->height - 1; iLocCurr = iXlocCurr + (iYlocCurr * pScr->width); if (iLocCurr > iLocStart) { for (iTmp=0; iTmp < iLocStart; iTmp++) { if (cInvertedArray[iTmp]) { PatBlt(hDC, (iTmp % pScr->width) * pScr->cxChar, (int) (iTmp / pScr->width) * pScr->cyChar, pScr->cxChar, pScr->cyChar, DSTINVERT); cInvertedArray[iTmp] = 0; } } iX = iLocStart % pScr->width; iY = (int) (iLocStart / pScr->width); iX2 = iLocCurr % pScr->width; iY2 = (int) (iLocCurr / pScr->width); if (iY == iY2) { pScrLine = GetScreenLineFromY(pScr, iY); for (iTmp2 = iX; iTmp2 < iX2; iTmp2++) { if ((!cInvertedArray[iTmp2 + (pScr->width * iY)]) && pScrLine->text[iTmp2]) { PatBlt(hDC, iTmp2 * pScr->cxChar, iY * pScr->cyChar, pScr->cxChar, pScr->cyChar, DSTINVERT); cInvertedArray[iTmp2 + (pScr->width * iY)] = pScrLine->text[iTmp2]; } } } else { pScrLine = GetScreenLineFromY(pScr, iY); for (iTmp2 = iX; iTmp2 < pScr->width; iTmp2++) { if ((!cInvertedArray[iTmp2 + (pScr->width * iY)]) && pScrLine->text[iTmp2]) { PatBlt(hDC, iTmp2 * pScr->cxChar, iY * pScr->cyChar, pScr->cxChar, pScr->cyChar, DSTINVERT); cInvertedArray[iTmp2 + (pScr->width * iY)] = pScrLine->text[iTmp2]; } } for (iTmp = iY + 1; iTmp < iY2; iTmp++) { pScrLine = GetScreenLineFromY(pScr, iTmp); for (iTmp2 = 0; iTmp2 < pScr->width; iTmp2++) { if ((!cInvertedArray[iTmp2 + (pScr->width * iTmp)]) && pScrLine->text[iTmp2]) { PatBlt(hDC, iTmp2 * pScr->cxChar, iTmp * pScr->cyChar, pScr->cxChar, pScr->cyChar, DSTINVERT); cInvertedArray[iTmp2 + (pScr->width * iTmp)] = pScrLine->text[iTmp2]; } } } if (iY2 != iY) { pScrLine = GetScreenLineFromY(pScr, iY2); for (iTmp2 = 0; iTmp2 < iX2; iTmp2++) { if ((!cInvertedArray[iTmp2 + (pScr->width * iY2)]) && pScrLine->text[iTmp2]) { PatBlt(hDC, iTmp2 * pScr->cxChar, iY2 * pScr->cyChar, pScr->cxChar, pScr->cyChar, DSTINVERT); cInvertedArray[iTmp2 + (pScr->width * iY2)] = pScrLine->text[iTmp2]; } } } } for (iTmp = iLocCurr; iTmp < pScr->width * pScr->height; iTmp++) { if (cInvertedArray[iTmp]) { PatBlt(hDC, (iTmp % pScr->width) * pScr->cxChar, (int) (iTmp / pScr->width) * pScr->cyChar, pScr->cxChar, pScr->cyChar, DSTINVERT); cInvertedArray[iTmp] = 0; } } } else { /* going backwards */ for (iTmp = 0; iTmp < iLocCurr; iTmp++) { if (cInvertedArray[iTmp]) { PatBlt(hDC, (iTmp % pScr->width) * pScr->cxChar, (int) (iTmp / pScr->width) * pScr->cyChar, pScr->cxChar, pScr->cyChar, DSTINVERT); cInvertedArray[iTmp] = 0; } } iX = iLocCurr % pScr->width; iY = (int) (iLocCurr / pScr->width); iX2 = (iLocStart % pScr->width); iY2 = (int) (iLocStart / pScr->width); if (iY == iY2) { pScrLine = GetScreenLineFromY(pScr, iY); for (iTmp2= iX; iTmp2 < iX2; iTmp2++) { if ((!cInvertedArray[iTmp2 + (pScr->width * iY)]) && pScrLine->text[iTmp2]) { PatBlt(hDC, iTmp2 * pScr->cxChar, iY * pScr->cyChar, pScr->cxChar, pScr->cyChar, DSTINVERT); cInvertedArray[iTmp2 + (pScr->width * iY)] = pScrLine->text[iTmp2]; } } } else { pScrLine = GetScreenLineFromY(pScr, iY); for (iTmp2 = iX; iTmp2 < pScr->width; iTmp2++) { if ((!cInvertedArray[iTmp2 + (pScr->width * iY)]) && pScrLine->text[iTmp2]) { PatBlt(hDC, iTmp2 * pScr->cxChar, iY * pScr->cyChar, pScr->cxChar, pScr->cyChar, DSTINVERT); cInvertedArray[iTmp2 + (pScr->width * iY)] = pScrLine->text[iTmp2]; } } for (iTmp = iY + 1; iTmp < iY2; iTmp++) { pScrLine = GetScreenLineFromY(pScr, iTmp); for (iTmp2 = 0; iTmp2 < pScr->width; iTmp2++) { if ((!cInvertedArray[iTmp2 + (pScr->width * iTmp)]) && pScrLine->text[iTmp2]) { PatBlt(hDC, iTmp2 * pScr->cxChar, iTmp * pScr->cyChar, pScr->cxChar, pScr->cyChar, DSTINVERT); cInvertedArray[iTmp2 + (pScr->width * iTmp)] = pScrLine->text[iTmp2]; } } } if (iY2 != iY) { pScrLine = GetScreenLineFromY(pScr, iY2); for (iTmp2 = 0; iTmp2 < iX2; iTmp2++) { if ((!cInvertedArray[iTmp2 + (pScr->width * iY2)]) && pScrLine->text[iTmp2]) { PatBlt(hDC, iTmp2 * pScr->cxChar, iY2 * pScr->cyChar, pScr->cxChar, pScr->cyChar, DSTINVERT); cInvertedArray[iTmp2 + (pScr->width * iY2)] = pScrLine->text[iTmp2]; } } } } for (iTmp = iLocStart; iTmp < pScr->width * pScr->height; iTmp++) { if (cInvertedArray[iTmp]) { PatBlt(hDC, (iTmp % pScr->width) * pScr->cxChar, (int) (iTmp / pScr->width) * pScr->cyChar, pScr->cxChar, pScr->cyChar, DSTINVERT); cInvertedArray[iTmp] = 0; } } } ReleaseDC(hWnd, hDC); } /* Edit_MouseMove */ void Edit_ClearSelection( SCREEN *pScr) { int iTmp; HDC hDC; HMENU hMenu; hDC = GetDC(pScr->hWnd); for (iTmp = 0; iTmp < pScr->width * pScr->height; iTmp++) { if (cInvertedArray[iTmp]) { PatBlt(hDC, (iTmp % pScr->width) * pScr->cxChar, (int) (iTmp / pScr->width) * pScr->cyChar, pScr->cxChar, pScr->cyChar, DSTINVERT); cInvertedArray[iTmp] = 0; } } bSelection = FALSE; hMenu=GetMenu(pScr->hWnd); EnableMenuItem(hMenu, IDM_COPY, MF_GRAYED); ReleaseDC(pScr->hWnd, hDC); } /* Edit_ClearSelection */ void Edit_Copy( HWND hWnd) { int iTmp,iIdx; HGLOBAL hCutBuffer; LPSTR lpCutBuffer; SCREEN *pScr; pScr = (SCREEN *) GetWindowLong(hWnd, SCREEN_HANDLE); assert(pScr != NULL); hCutBuffer= GlobalAlloc(GHND, (DWORD) (pScr->width * pScr->height + 1)); lpCutBuffer= GlobalLock(hCutBuffer); if (iLocStart > iLocEnd) { /* swap variables */ iTmp = iLocStart; iLocStart = iLocEnd; iLocEnd = iLocStart; } iTmp = iLocStart; iIdx = 0; while (iTmp < iLocEnd) { if (!cInvertedArray[iTmp]) { lpCutBuffer[iIdx++] = '\r'; lpCutBuffer[iIdx++] = '\n'; iTmp = (((int) (iTmp / pScr->width)) + 1) * pScr->width; continue; } lpCutBuffer[iIdx++] = cInvertedArray[iTmp++]; } lpCutBuffer[iIdx] = 0; GlobalUnlock(hCutBuffer); OpenClipboard(hWnd); EmptyClipboard(); SetClipboardData(CF_TEXT, hCutBuffer); CloseClipboard(); } /* Edit_Copy */ void Edit_Paste( HWND hWnd) { HGLOBAL hClipMemory; static HGLOBAL hMyClipBuffer; LPSTR lpClipMemory; LPSTR lpMyClipBuffer; SCREEN *pScr; if (hMyClipBuffer) GlobalFree(hMyClipBuffer); OpenClipboard(hWnd); hClipMemory = GetClipboardData(CF_TEXT); hMyClipBuffer = GlobalAlloc(GHND, GlobalSize(hClipMemory)); lpMyClipBuffer = GlobalLock(hMyClipBuffer); lpClipMemory= GlobalLock(hClipMemory); pScr = (SCREEN *) GetWindowLong(hWnd, SCREEN_HANDLE); assert(pScr != NULL); lstrcpy(lpMyClipBuffer, lpClipMemory); #if 0 OutputDebugString(lpMyClipBuffer); #endif PostMessage(pScr->hwndTel, WM_MYSCREENBLOCK, (WPARAM) hMyClipBuffer, (LPARAM) pScr); CloseClipboard(); GlobalUnlock(hClipMemory); GlobalUnlock(hMyClipBuffer); } /* Edit_Paste */ void Edit_LbuttonDblclk( HWND hWnd, LPARAM lParam) { HDC hDC; SCREEN *pScr; int iTmp; int iTmp2; int iXlocStart; int iYloc; SCREENLINE *pScrLine; pScr = (SCREEN *) GetWindowLong(hWnd, SCREEN_HANDLE); assert(pScr != NULL); hDC = GetDC(hWnd); for (iTmp = 0; iTmp < pScr->width * pScr->height; iTmp++) { if (cInvertedArray[iTmp]) { PatBlt(hDC, (iTmp % pScr->width) * pScr->cxChar, (int) (iTmp / pScr->width) * pScr->cyChar, pScr->cxChar, pScr->cyChar, DSTINVERT); cInvertedArray[iTmp] = 0; } } bSelection = FALSE; iXlocStart = (int) LOWORD(lParam) / pScr->cxChar; if (iXlocStart >= pScr->width) iXlocStart = pScr->width - 1; iYloc = (int) HIWORD(lParam) / pScr->cyChar; if (iYloc >= pScr->height) iYloc = pScr->height - 1; iLocStart = iXlocStart + (iYloc * pScr->width); pScrLine = GetScreenLineFromY(pScr, iYloc); iTmp = iXlocStart; while (isalnum((int) pScrLine->text[iTmp])) { PatBlt(hDC, iTmp * pScr->cxChar, iYloc * pScr->cyChar, pScr->cxChar, pScr->cyChar, DSTINVERT); cInvertedArray[iTmp + (iYloc * pScr->width)] = pScrLine->text[iTmp]; iTmp++; } iTmp2 = iXlocStart - 1; while (isalnum((int) pScrLine->text[iTmp2])) { PatBlt(hDC, iTmp2 * pScr->cxChar, iYloc * pScr->cyChar, pScr->cxChar, pScr->cyChar, DSTINVERT); cInvertedArray[iTmp2 + (iYloc * pScr->width)] = pScrLine->text[iTmp2]; iTmp2--; } iLocStart = (iTmp2 + 1) + (iYloc * pScr->width); iLocEnd = iTmp + (iYloc * pScr->width); bSelection = TRUE; ReleaseDC(hWnd, hDC); } /* Edit_LbuttonDblclk */ void Edit_TripleClick( HWND hWnd, LPARAM lParam) { HDC hDC; SCREEN *pScr; int iTmp; int iYloc; SCREENLINE *pScrLine; #if 0 OutputDebugString("Triple Click \r\n"); #endif pScr = (SCREEN *) GetWindowLong(hWnd, SCREEN_HANDLE); assert(pScr != NULL); hDC = GetDC(hWnd); for (iTmp = 0; iTmp < pScr->width * pScr->height; iTmp++) { if (cInvertedArray[iTmp]) { PatBlt(hDC, (iTmp % pScr->width) * pScr->cxChar, (int) (iTmp / pScr->width) * pScr->cyChar, pScr->cxChar, pScr->cyChar, DSTINVERT); cInvertedArray[iTmp] = 0; } } bSelection = FALSE; iYloc = (int) HIWORD(lParam) / pScr->cyChar; if (iYloc >= pScr->height) iYloc = pScr->height - 1; iLocStart = iYloc * pScr->width; pScrLine = GetScreenLineFromY(pScr, iYloc); for (iTmp = 0; iTmp < pScr->width; iTmp++) { if (pScrLine->text[iTmp]) { PatBlt(hDC, iTmp * pScr->cxChar, iYloc * pScr->cyChar, pScr->cxChar, pScr->cyChar, DSTINVERT); cInvertedArray[iTmp + (iYloc * pScr->width)] = pScrLine->text[iTmp]; } else break; } iLocEnd = iTmp + (iYloc * pScr->width); bSelection = TRUE; ReleaseDC(hWnd, hDC); } /* Edit_TripleClick */ krb5-1.16/src/windows/wintel/auth.c0000644000704600001450000004621313211554426017074 0ustar ghudsonlibuuid/* * Implements Kerberos 4 authentication */ #ifdef KRB4 #include #include #include #include "winsock.h" #include "kerberos.h" #endif #ifdef KRB5 #include #include #include "krb5.h" #include "com_err.h" #endif #include "telnet.h" #include "telnet_arpa.h" #ifdef ENCRYPTION #include "encrypt.h" #endif /* * Constants */ #ifdef KRB4 #define KRB_AUTH 0 #define KRB_REJECT 1 #define KRB_ACCEPT 2 #define KRB_CHALLENGE 3 #define KRB_RESPONSE 4 #endif #ifdef KRB5 #define KRB_AUTH 0 /* Authentication data follows */ #define KRB_REJECT 1 /* Rejected (reason might follow) */ #define KRB_ACCEPT 2 /* Accepted */ #define KRB_RESPONSE 3 /* Response for mutual auth. */ #define KRB_FORWARD 4 /* Forwarded credentials follow */ #define KRB_FORWARD_ACCEPT 5 /* Forwarded credentials accepted */ #define KRB_FORWARD_REJECT 6 /* Forwarded credentials rejected */ #endif #ifndef KSUCCESS /* Let K5 use K4 constants */ #define KSUCCESS 0 #define KFAILURE 255 #endif /* * Globals */ #ifdef KRB4 static CREDENTIALS cred; static KTEXT_ST auth; #define KRB_SERVICE_NAME "rcmd" #define KERBEROS_VERSION KERBEROS_V4 static int auth_how; static int k4_auth_send(kstream); static int k4_auth_reply(kstream, unsigned char *, int); #endif #ifdef KRB5 static krb5_data auth; static int auth_how; static krb5_auth_context auth_context; krb5_keyblock *session_key = NULL; #ifdef FORWARD void kerberos5_forward(kstream); #endif #define KRB_SERVICE_NAME "host" #define KERBEROS_VERSION AUTHTYPE_KERBEROS_V5 static int k5_auth_send(kstream, int); static int k5_auth_reply(kstream, int, unsigned char *, int); #endif static int Data(kstream, int, void *, int); #ifdef ENCRYPTION BOOL encrypt_flag = 1; #endif #ifdef FORWARD BOOL forward_flag = 1; /* forward tickets? */ BOOL forwardable_flag = 1; /* get forwardable tickets to forward? */ BOOL forwarded_tickets = 0; /* were tickets forwarded? */ #endif static unsigned char str_data[1024] = { IAC, SB, TELOPT_AUTHENTICATION, 0, AUTHTYPE_KERBEROS_V5, }; static int Data(kstream ks, int type, void *d, int c) { unsigned char *p = str_data + 4; unsigned char *cd = (unsigned char *)d; if (c == -1) c = strlen((char *)cd); *p++ = AUTHTYPE_KERBEROS_V5; *p = AUTH_WHO_CLIENT|AUTH_HOW_MUTUAL; #ifdef ENCRYPTION *p |= AUTH_ENCRYPT_ON; #endif p++; *p++ = type; while (c-- > 0) { if ((*p++ = *cd++) == IAC) *p++ = IAC; } *p++ = IAC; *p++ = SE; return(TelnetSend(ks, (LPSTR)str_data, p - str_data, 0)); } #ifdef ENCRYPTION /* * Function: Enable or disable the encryption process. * * Parameters: * enable - TRUE to enable, FALSE to disable. */ static void auth_encrypt_enable(BOOL enable) { encrypt_flag = enable; } #endif /* * Function: Abort the authentication process * * Parameters: * ks - kstream to send abort message to. */ static void auth_abort(kstream ks, char *errmsg, long r) { char buf[9]; wsprintf(buf, "%c%c%c%c%c%c%c%c", IAC, SB, TELOPT_AUTHENTICATION, TELQUAL_IS, AUTHTYPE_NULL, AUTHTYPE_NULL, IAC, SE); TelnetSend(ks, (LPSTR)buf, 8, 0); if (errmsg != NULL) { strTmp[sizeof(strTmp) - 1] = '\0'; strncpy(strTmp, errmsg, sizeof(strTmp) - 1); if (r != KSUCCESS) { strncat(strTmp, "\n", sizeof(strTmp) - 1 - strlen(strTmp)); #ifdef KRB4 lstrcat(strTmp, krb_get_err_text((int)r)); #endif #ifdef KRB5 lstrcat(strTmp, error_message(r)); #endif } MessageBox(HWND_DESKTOP, strTmp, "Kerberos authentication failed!", MB_OK | MB_ICONEXCLAMATION); } } /* * Function: Copy data to buffer, doubling IAC character if present. * * Parameters: * kstream - kstream to send abort message to. */ static int copy_for_net(unsigned char *to, unsigned char *from, int c) { int n; n = c; while (c-- > 0) { if ((*to++ = *from++) == IAC) { n++; *to++ = IAC; } } return n; } /* * Function: Parse authentication send command * * Parameters: * ks - kstream to send abort message to. * * parsedat - the sub-command data. * * end_sub - index of the character in the 'parsedat' array which * is the last byte in a sub-negotiation * * Returns: Kerberos error code. */ static int auth_send(kstream ks, unsigned char *parsedat, int end_sub) { char buf[2048]; /* be sure that this is > auth.length+9 */ char *pname; int plen; int r; int i; auth_how = -1; for (i = 2; i+1 <= end_sub; i += 2) { if (parsedat[i] == KERBEROS_VERSION) if ((parsedat[i+1] & AUTH_WHO_MASK) == AUTH_WHO_CLIENT) { auth_how = parsedat[i+1] & AUTH_HOW_MASK; break; } } if (auth_how == -1) { auth_abort(ks, NULL, 0); return KFAILURE; } #ifdef KRB4 r = k4_auth_send(ks); #endif /* KRB4 */ #ifdef KRB5 r = k5_auth_send(ks, auth_how); #endif /* KRB5 */ if (!r) return KFAILURE; plen = strlen(szUserName); /* Set by k#_send if needed */ pname = szUserName; wsprintf(buf, "%c%c%c%c", IAC, SB, TELOPT_AUTHENTICATION, TELQUAL_NAME); memcpy(&buf[4], pname, plen); wsprintf(&buf[plen + 4], "%c%c", IAC, SE); TelnetSend(ks, (LPSTR)buf, lstrlen(pname)+6, 0); wsprintf(buf, "%c%c%c%c%c%c%c", IAC, SB, TELOPT_AUTHENTICATION, TELQUAL_IS, KERBEROS_VERSION, auth_how | AUTH_WHO_CLIENT, KRB_AUTH); #if KRB4 auth.length = copy_for_net(&buf[7], auth.dat, auth.length); #endif /* KRB4 */ #if KRB5 auth.length = copy_for_net(&buf[7], auth.data, auth.length); #endif /* KRB5 */ wsprintf(&buf[auth.length+7], "%c%c", IAC, SE); TelnetSend(ks, (LPSTR)buf, auth.length+9, 0); return KSUCCESS; } /* * Function: Parse authentication reply command * * Parameters: * ks - kstream to send abort message to. * * parsedat - the sub-command data. * * end_sub - index of the character in the 'parsedat' array which * is the last byte in a sub-negotiation * * Returns: Kerberos error code. */ static int auth_reply(kstream ks, unsigned char *parsedat, int end_sub) { int n; #ifdef KRB4 n = k4_auth_reply(ks, parsedat, end_sub); #endif #ifdef KRB5 n = k5_auth_reply(ks, auth_how, parsedat, end_sub); #endif return n; } /* * Function: Parse the athorization sub-options and reply. * * Parameters: * ks - kstream to send abort message to. * * parsedat - sub-option string to parse. * * end_sub - last charcter position in parsedat. */ void auth_parse(kstream ks, unsigned char *parsedat, int end_sub) { if (parsedat[1] == TELQUAL_SEND) auth_send(ks, parsedat, end_sub); if (parsedat[1] == TELQUAL_REPLY) auth_reply(ks, parsedat, end_sub); } /* * Function: Initialization routine called kstream encryption system. * * Parameters: * str - kstream to send abort message to. * * data - user data. */ int auth_init(kstream str, kstream_ptr data) { #ifdef ENCRYPTION encrypt_init(str, data); #endif return 0; } /* * Function: Destroy routine called kstream encryption system. * * Parameters: * str - kstream to send abort message to. * * data - user data. */ void auth_destroy(kstream str) { } /* * Function: Callback to encrypt a block of characters * * Parameters: * out - return as pointer to converted buffer. * * in - the buffer to convert * * str - the stream being encrypted * * Returns: number of characters converted. */ int auth_encrypt(struct kstream_data_block *out, struct kstream_data_block *in, kstream str) { out->ptr = in->ptr; out->length = in->length; return(out->length); } /* * Function: Callback to decrypt a block of characters * * Parameters: * out - return as pointer to converted buffer. * * in - the buffer to convert * * str - the stream being encrypted * * Returns: number of characters converted. */ int auth_decrypt(struct kstream_data_block *out, struct kstream_data_block *in, kstream str) { out->ptr = in->ptr; out->length = in->length; return(out->length); } #ifdef KRB4 /* * * K4_auth_send - gets authentication bits we need to send to KDC. * * Result is left in auth * * Returns: 0 on failure, 1 on success */ static int k4_auth_send(kstream ks) { int r; /* Return value */ char instance[INST_SZ]; char *realm; char buf[256]; memset(instance, 0, sizeof(instance)); if (realm = krb_get_phost(szHostName)) lstrcpy(instance, realm); realm = krb_realmofhost(szHostName); if (!realm) { strcpy(buf, "Can't find realm for host \""); strncat(buf, szHostName, sizeof(buf) - 1 - strlen(buf)); strncat(buf, "\"", sizeof(buf) - 1 - strlen(buf)); auth_abort(ks, buf, 0); return KFAILURE; } r = krb_mk_req(&auth, KRB_SERVICE_NAME, instance, realm, 0); if (r == 0) r = krb_get_cred(KRB_SERVICE_NAME, instance, realm, &cred); if (r) { strcpy(buf, "Can't get \""); strncat(buf, KRB_SERVICE_NAME, sizeof(buf) - 1 - strlen(buf)); if (instance[0] != 0) { strncat(buf, ".", sizeof(buf) - 1 - strlen(buf)); lstrcat(buf, instance); } strncat(buf, "@", sizeof(buf) - 1 - strlen(buf)); lstrcat(buf, realm); strncat(buf, "\" ticket", sizeof(buf) - 1 - strlen(buf)); auth_abort(ks, buf, r); return r; } if (!szUserName[0]) /* Copy if not there */ strcpy(szUserName, cred.pname); return(1); } /* * Function: K4 parse authentication reply command * * Parameters: * ks - kstream to send abort message to. * * parsedat - the sub-command data. * * end_sub - index of the character in the 'parsedat' array which * is the last byte in a sub-negotiation * * Returns: Kerberos error code. */ static int k4_auth_reply(kstream ks, unsigned char *parsedat, int end_sub) { time_t t; int x; char buf[512]; int i; des_cblock session_key; des_key_schedule sched; static des_cblock challenge; if (end_sub < 4) return KFAILURE; if (parsedat[2] != KERBEROS_V4) return KFAILURE; if (parsedat[4] == KRB_REJECT) { buf[0] = 0; for (i = 5; i <= end_sub; i++) { if (parsedat[i] == IAC) break; buf[i-5] = parsedat[i]; buf[i-4] = 0; } if (!buf[0]) strcpy(buf, "Authentication rejected by remote machine!"); MessageBox(HWND_DESKTOP, buf, NULL, MB_OK | MB_ICONEXCLAMATION); return KFAILURE; } if (parsedat[4] == KRB_ACCEPT) { if ((parsedat[3] & AUTH_HOW_MASK) == AUTH_HOW_ONE_WAY) return KSUCCESS; if ((parsedat[3] & AUTH_HOW_MASK) != AUTH_HOW_MUTUAL) return KFAILURE; des_key_sched(cred.session, sched); t = time(NULL); memcpy(challenge, &t, 4); memcpy(&challenge[4], &t, 4); des_ecb_encrypt(&challenge, &session_key, sched, 1); /* * Increment the challenge by 1, and encrypt it for * later comparison. */ for (i = 7; i >= 0; --i) { x = (unsigned int)challenge[i] + 1; challenge[i] = x; /* ignore overflow */ if (x < 256) /* if no overflow, all done */ break; } des_ecb_encrypt(&challenge, &challenge, sched, 1); wsprintf(buf, "%c%c%c%c%c%c%c", IAC, SB, TELOPT_AUTHENTICATION, TELQUAL_IS, KERBEROS_V4, AUTH_WHO_CLIENT|AUTH_HOW_MUTUAL, KRB_CHALLENGE); memcpy(&buf[7], session_key, 8); wsprintf(&buf[15], "%c%c", IAC, SE); TelnetSend(ks, (LPSTR)buf, 17, 0); return KSUCCESS; } if (parsedat[4] == KRB_RESPONSE) { if (end_sub < 12) return KFAILURE; if (memcmp(&parsedat[5], challenge, sizeof(challenge)) != 0) { MessageBox(HWND_DESKTOP, "Remote machine is being impersonated!", NULL, MB_OK | MB_ICONEXCLAMATION); return KFAILURE; } return KSUCCESS; } return KFAILURE; } #endif /* KRB4 */ #ifdef KRB5 /* * * K5_auth_send - gets authentication bits we need to send to KDC. * * Code lifted from telnet sample code in the appl directory. * * Result is left in auth * * Returns: 0 on failure, 1 on success * */ static int k5_auth_send(kstream ks, int how) { krb5_error_code r; krb5_ccache ccache; krb5_creds creds; krb5_creds * new_creds; extern krb5_flags krb5_kdc_default_options; krb5_flags ap_opts; char type_check[2]; krb5_data check_data; int len; #ifdef ENCRYPTION krb5_keyblock *newkey = 0; #endif if (r = krb5_cc_default(k5_context, &ccache)) { com_err(NULL, r, "while authorizing."); return(0); } memset((char *)&creds, 0, sizeof(creds)); if (r = krb5_sname_to_principal(k5_context, szHostName, KRB_SERVICE_NAME, KRB5_NT_SRV_HST, &creds.server)) { com_err(NULL, r, "while authorizing."); return(0); } if (r = krb5_cc_get_principal(k5_context, ccache, &creds.client)) { com_err(NULL, r, "while authorizing."); krb5_free_cred_contents(k5_context, &creds); return(0); } if (szUserName[0] == '\0') { /* Get user name now */ len = krb5_princ_component(k5_context, creds.client, 0)->length; memcpy(szUserName, krb5_princ_component(k5_context, creds.client, 0)->data, len); szUserName[len] = '\0'; } if (r = krb5_get_credentials(k5_context, 0, ccache, &creds, &new_creds)) { com_err(NULL, r, "while authorizing."); krb5_free_cred_contents(k5_context, &creds); return(0); } ap_opts = 0; if ((how & AUTH_HOW_MASK) == AUTH_HOW_MUTUAL) ap_opts = AP_OPTS_MUTUAL_REQUIRED; #ifdef ENCRYPTION ap_opts |= AP_OPTS_USE_SUBKEY; #endif if (auth_context) { krb5_auth_con_free(k5_context, auth_context); auth_context = 0; } if ((r = krb5_auth_con_init(k5_context, &auth_context))) { com_err(NULL, r, "while initializing auth context"); return(0); } krb5_auth_con_setflags(k5_context, auth_context, KRB5_AUTH_CONTEXT_RET_TIME); type_check[0] = AUTHTYPE_KERBEROS_V5; type_check[1] = AUTH_WHO_CLIENT| (how & AUTH_HOW_MASK); #ifdef ENCRYPTION type_check[1] |= AUTH_ENCRYPT_ON; #endif check_data.magic = KV5M_DATA; check_data.length = 2; check_data.data = (char *)&type_check; r = krb5_mk_req_extended(k5_context, &auth_context, ap_opts, NULL, new_creds, &auth); #ifdef ENCRYPTION krb5_auth_con_getlocalsubkey(k5_context, auth_context, &newkey); if (session_key) { krb5_free_keyblock(k5_context, session_key); session_key = 0; } if (newkey) { /* * keep the key in our private storage, but don't use it * yet---see kerberos5_reply() below */ if ((newkey->enctype != ENCTYPE_DES_CBC_CRC) && (newkey-> enctype != ENCTYPE_DES_CBC_MD5)) { if ((new_creds->keyblock.enctype == ENCTYPE_DES_CBC_CRC) || (new_creds->keyblock.enctype == ENCTYPE_DES_CBC_MD5)) /* use the session key in credentials instead */ krb5_copy_keyblock(k5_context, &new_creds->keyblock, &session_key); else ; /* What goes here? XXX */ } else { krb5_copy_keyblock(k5_context, newkey, &session_key); } krb5_free_keyblock(k5_context, newkey); } #endif /* ENCRYPTION */ krb5_free_cred_contents(k5_context, &creds); krb5_free_creds(k5_context, new_creds); if (r) { com_err(NULL, r, "while authorizing."); return(0); } return(1); } /* * * K5_auth_reply -- checks the reply for mutual authentication. * * Code lifted from telnet sample code in the appl directory. * */ static int k5_auth_reply(kstream ks, int how, unsigned char *data, int cnt) { #ifdef ENCRYPTION Session_Key skey; #endif static int mutual_complete = 0; data += 4; /* Point to status byte */ switch (*data++) { case KRB_REJECT: if (cnt > 0) { char *s; wsprintf(strTmp, "Kerberos V5 refuses authentication because\n\t"); s = strTmp + strlen(strTmp); strncpy(s, data, cnt); s[cnt] = 0; } else wsprintf(strTmp, "Kerberos V5 refuses authentication"); MessageBox(HWND_DESKTOP, strTmp, "", MB_OK | MB_ICONEXCLAMATION); return KFAILURE; case KRB_ACCEPT: if (!mutual_complete) { if ((how & AUTH_HOW_MASK) == AUTH_HOW_MUTUAL && !mutual_complete) { wsprintf(strTmp, "Kerberos V5 accepted you, but didn't provide" " mutual authentication"); MessageBox(HWND_DESKTOP, strTmp, "", MB_OK | MB_ICONEXCLAMATION); return KFAILURE; } #ifdef ENCRYPTION if (session_key) { skey.type = SK_DES; skey.length = 8; skey.data = session_key->contents; encrypt_session_key(&skey, 0); } #endif } #ifdef FORWARD if (forward_flag) kerberos5_forward(ks); #endif return KSUCCESS; break; case KRB_RESPONSE: if ((how & AUTH_HOW_MASK) == AUTH_HOW_MUTUAL) { /* the rest of the reply should contain a krb_ap_rep */ krb5_ap_rep_enc_part *reply; krb5_data inbuf; krb5_error_code r; inbuf.length = cnt; inbuf.data = (char *)data; if (r = krb5_rd_rep(k5_context, auth_context, &inbuf, &reply)) { com_err(NULL, r, "while authorizing."); return KFAILURE; } krb5_free_ap_rep_enc_part(k5_context, reply); #ifdef ENCRYPTION if (encrypt_flag && session_key) { skey.type = SK_DES; skey.length = 8; skey.data = session_key->contents; encrypt_session_key(&skey, 0); } #endif mutual_complete = 1; } return KSUCCESS; #ifdef FORWARD case KRB_FORWARD_ACCEPT: forwarded_tickets = 1; return KSUCCESS; case KRB_FORWARD_REJECT: forwarded_tickets = 0; if (cnt > 0) { char *s; wsprintf(strTmp, "Kerberos V5 refuses forwarded credentials because\n\t"); s = strTmp + strlen(strTmp); strncpy(s, data, cnt); s[cnt] = 0; } else wsprintf(strTmp, "Kerberos V5 refuses forwarded credentials"); MessageBox(HWND_DESKTOP, strTmp, "", MB_OK | MB_ICONEXCLAMATION); return KFAILURE; #endif /* FORWARD */ default: return KFAILURE; /* Unknown reply type */ } } #ifdef FORWARD void kerberos5_forward(kstream ks) { krb5_error_code r; krb5_ccache ccache; krb5_principal client = 0; krb5_principal server = 0; krb5_data forw_creds; forw_creds.data = 0; if ((r = krb5_cc_default(k5_context, &ccache))) { com_err(NULL, r, "Kerberos V5: could not get default ccache"); return; } if ((r = krb5_cc_get_principal(k5_context, ccache, &client))) { com_err(NULL, r, "Kerberos V5: could not get default principal"); goto cleanup; } if ((r = krb5_sname_to_principal(k5_context, szHostName, KRB_SERVICE_NAME, KRB5_NT_SRV_HST, &server))) { com_err(NULL, r, "Kerberos V5: could not make server principal"); goto cleanup; } if ((r = krb5_auth_con_genaddrs(k5_context, auth_context, ks->fd, KRB5_AUTH_CONTEXT_GENERATE_LOCAL_FULL_ADDR))) { com_err(NULL, r, "Kerberos V5: could not gen local full address"); goto cleanup; } if (r = krb5_fwd_tgt_creds(k5_context, auth_context, 0, client, server, ccache, forwardable_flag, &forw_creds)) { com_err(NULL, r, "Kerberos V5: error getting forwarded creds"); goto cleanup; } /* Send forwarded credentials */ if (!Data(ks, KRB_FORWARD, forw_creds.data, forw_creds.length)) { MessageBox(HWND_DESKTOP, "Not enough room for authentication data", "", MB_OK | MB_ICONEXCLAMATION); } cleanup: if (client) krb5_free_principal(k5_context, client); if (server) krb5_free_principal(k5_context, server); #if 0 /* XXX */ if (forw_creds.data) free(forw_creds.data); #endif krb5_cc_close(k5_context, ccache); } #endif /* FORWARD */ #endif /* KRB5 */ krb5-1.16/src/windows/wintel/intern.c0000644000704600001450000003722513211554426017435 0ustar ghudsonlibuuid/* intern.c */ #include #include #include #include "screen.h" #define ScreenClearAttrib 0 SCREENLINE * GetScreenLineFromY(SCREEN *pScr, int y) { SCREENLINE *pScrLine; int idx; pScrLine = pScr->screen_top; for (idx = 0; idx < pScr->height; idx++) { if (idx == y) return(pScrLine); if (pScrLine == NULL) return(NULL); pScrLine = pScrLine->next; } return(NULL); } SCREENLINE * ScreenClearLine(SCREEN *pScr, SCREENLINE *pScrLine) { memset(pScrLine->attrib, ScreenClearAttrib, pScr->width); memset(pScrLine->text, ' ', pScr->width); return(pScrLine); } void ScreenUnscroll(SCREEN *pScr) { int idx; SCREENLINE *pScrLine; if (pScr->screen_bottom == pScr->buffer_bottom) return; pScr->screen_bottom = pScr->buffer_bottom; pScrLine = pScr->screen_bottom; for (idx = 1; idx < pScr->height; idx++) { if (pScrLine == NULL) return; pScrLine = pScrLine->prev; } pScr->screen_top = pScrLine; } void ScreenCursorOn(SCREEN *pScr) { int y; int nlines; if (pScr->screen_bottom != pScr->buffer_bottom) nlines = pScr->numlines - GetScrollPos(pScr->hWnd, SB_VERT); else nlines = 0; y = pScr->y + nlines; SetCaretPos(pScr->x * pScr->cxChar, (y+1) * pScr->cyChar); ShowCaret(pScr->hWnd); } void ScreenCursorOff(SCREEN *pScr) { HideCaret(pScr->hWnd); } void ScreenELO(SCREEN *pScr, int s) { SCREENLINE *pScrLine; RECT rc; if (s < 0) s = pScr->y; pScrLine = GetScreenLineFromY(pScr,s); memset(pScrLine->attrib, ScreenClearAttrib, pScr->width); memset(pScrLine->text, ' ', pScr->width); rc.left = 0; rc.right = pScr->width * pScr->cxChar; rc.top = pScr->cyChar * s; rc.bottom = pScr->cyChar * (s+1); InvalidateRect(pScr->hWnd, &rc, TRUE); } void ScreenEraseScreen(SCREEN *pScr) { int i; int x1 = 0; int y1 = 0; int x2 = pScr->width; int y2 = pScr->height; int n = -1; for(i = 0; i < pScr->height; i++) ScreenELO(pScr,i); InvalidateRect(pScr->hWnd, NULL, TRUE); UpdateWindow(pScr->hWnd); } void ScreenTabClear(SCREEN *pScr) { int x = 0; while(x <= pScr->width) { pScr->tabs[x] = ' '; x++; } } void ScreenTabInit(SCREEN *pScr) { int x = 0; ScreenTabClear(pScr); while(x <= pScr->width) { pScr->tabs[x] = 'x'; x += 8; } pScr->tabs[pScr->width] = 'x'; } void ScreenReset(SCREEN *pScr) { pScr->top = 0; pScr->bottom = pScr->height-1; pScr->parmptr = 0; pScr->escflg = 0; pScr->DECAWM = 1; pScr->bWrapPending = FALSE; pScr->DECCKM = 0; pScr->DECPAM = 0; /* pScr->DECORG = 0; */ /* pScr->Pattrib = -1; */ pScr->IRM = 0; pScr->attrib = 0; pScr->x = 0; pScr->y = 0; /* pScr->charset = 0; */ ScreenEraseScreen(pScr); ScreenTabInit(pScr); #if 0 /* * QAK - 7/27/90: added because resetting the virtual screen's * wrapping flag doesn't reset telnet window's wrapping */ set_vtwrap(pScrn, pScr->DECAWM); #endif } void ScreenListMove(SCREENLINE *TD, SCREENLINE *BD, SCREENLINE *TI, SCREENLINE *BI) { if (TD->prev != NULL) TD->prev->next = BD->next; /* Maintain circularity */ if (BD->next != NULL) BD->next->prev = TD->prev; TD->prev = TI; /* Place the node in its new home */ BD->next = BI; if (TI != NULL) TI->next = TD; /* Ditto prev->prev */ if (BI != NULL) BI->prev = BD; } void ScreenDelLines(SCREEN *pScr, int n, int s) { SCREENLINE *BI; SCREENLINE *TI; SCREENLINE *TD; SCREENLINE *BD; SCREENLINE *pLine; int idx; RECT rc; HDC hDC; pScr->bWrapPending = FALSE; if (s < 0) s = pScr->y; if (s + n - 1 > pScr->bottom) n = pScr->bottom - s + 1; TD = GetScreenLineFromY(pScr, s); BD = GetScreenLineFromY(pScr, s + n - 1); TI = GetScreenLineFromY(pScr, pScr->bottom); BI = TI->next; /* * Adjust the top of the screen and buffer if they will move. */ if (TD == pScr->screen_top) { if (pScr->screen_top == pScr->buffer_top) pScr->buffer_top = BD->next; pScr->screen_top = BD->next; } /* * Adjust the bottom of the screen and buffer if they will move. */ if (TI == pScr->screen_bottom) { if (pScr->screen_bottom == pScr->buffer_bottom) pScr->buffer_bottom = BD; pScr->screen_bottom = BD; } if (TI != BD) ScreenListMove(TD, BD, TI, BI); /* * Clear the lines moved from the deleted area to the * bottom of the scrolling area. */ pLine = TI; for (idx = 0; idx < n; idx++) { pLine = pLine->next; ScreenClearLine(pScr, pLine); } /* CheckScreen(pScr); */ /* * Scroll the affected area on the screen. */ rc.left = 0; rc.right = pScr->width * pScr->cxChar; rc.top = s * pScr->cyChar; rc.bottom = (pScr->bottom + 1) * pScr->cyChar; hDC = GetDC(pScr->hWnd); ScrollDC(hDC, 0, -pScr->cyChar * n, &rc, &rc, NULL, NULL); PatBlt(hDC, 0, (pScr->bottom - n + 1) * pScr->cyChar, pScr->width * pScr->cxChar, n * pScr->cyChar, WHITENESS); ReleaseDC(pScr->hWnd, hDC); } void ScreenInsertLine(SCREEN *pScr, int s) { ScreenInsLines(pScr, 1, s); } void ScreenInsLines(SCREEN *pScr, int n, int s) { SCREENLINE *TI; SCREENLINE *BI; SCREENLINE *TD; SCREENLINE *BD; SCREENLINE *pLine; int idx; RECT rc; HDC hDC; pScr->bWrapPending = FALSE; if (s < 0) s = pScr->y; if (s + n - 1 > pScr->bottom) n = pScr->bottom - s + 1; /* * Determine the top and bottom of the insert area. Also determine * the top and bottom of the area to be deleted and moved to the * insert area. */ BI = GetScreenLineFromY(pScr, s); TI = BI->prev; TD = GetScreenLineFromY(pScr, pScr->bottom - n + 1); BD = GetScreenLineFromY(pScr, pScr->bottom); /* * Adjust the top of the screen and buffer if they will move. */ if (BI == pScr->screen_top) { if (pScr->screen_top == pScr->buffer_top) pScr->buffer_top = TD; pScr->screen_top = TD; } /* * Adjust the bottom of the screen and buffer if they will move. */ if (BD == pScr->screen_bottom) { if (pScr->screen_bottom == pScr->buffer_bottom) pScr->buffer_bottom = TD->prev; pScr->screen_bottom = TD->prev; } /* * Move lines from the bottom of the scrolling region to the insert area. */ if (TD != BI) ScreenListMove(TD,BD,TI,BI); /* * Clear the inserted lines */ pLine = GetScreenLineFromY(pScr, s); for (idx = 0; idx < n; idx++) { ScreenClearLine(pScr, pLine); pLine = pLine->next; } /* CheckScreen(pScr); */ /* * Scroll the affected area on the screen. */ rc.left = 0; rc.right = pScr->width * pScr->cxChar; rc.top = s * pScr->cyChar; rc.bottom = (pScr->bottom + 1) * pScr->cyChar; hDC = GetDC(pScr->hWnd); ScrollDC(hDC, 0, pScr->cyChar * n, &rc, &rc, NULL, NULL); PatBlt(hDC, 0, s * pScr->cyChar, pScr->width * pScr->cxChar, n * pScr->cyChar, WHITENESS); ReleaseDC(pScr->hWnd, hDC); } void ScreenIndex(SCREEN * pScr) { if (pScr->y >= pScr->bottom) ScreenScroll(pScr); else pScr->y++; pScr->bWrapPending = FALSE; } void ScreenWrapNow(SCREEN *pScr, int *xp, int *yp) { if (pScr->bWrapPending && pScr->x >= pScr->width - 1) { pScr->x = 0; ScreenIndex(pScr); } pScr->bWrapPending = FALSE; *xp = pScr->x; *yp = pScr->y; } void ScreenEraseToEOL(SCREEN *pScr) { int x1 = pScr->x; int y1 = pScr->y; int x2 = pScr->width; int y2 = pScr->y; int n = -1; SCREENLINE *pScrLine; RECT rc; ScreenWrapNow(pScr, &x1, &y1); y2 = y1; #if 0 wsprintf(strTmp,"[EraseEOL:%d]",y2); OutputDebugString(strTmp); #endif pScrLine = GetScreenLineFromY(pScr,y2); memset(&pScrLine->attrib[x1], ScreenClearAttrib, pScr->width-x1+1); memset(&pScrLine->text[x1], ' ', pScr->width - x1 + 1); rc.left = x1 * pScr->cxChar; rc.right = pScr->width * pScr->cxChar; rc.top = pScr->cyChar * y1; rc.bottom = pScr->cyChar * (y1 + 1); InvalidateRect(pScr->hWnd, &rc, TRUE); UpdateWindow(pScr->hWnd); } void ScreenDelChars(SCREEN *pScr, int n) { int x = pScr->x; int y = pScr->y; int width; SCREENLINE *pScrLine; RECT rc; pScr->bWrapPending = FALSE; pScrLine = GetScreenLineFromY(pScr, y); width = pScr->width - x - n; if (width > 0) { memmove(&pScrLine->attrib[x], &pScrLine->attrib[x + n], width); memmove(&pScrLine->text[x], &pScrLine->text[x + n], width); } memset(&pScrLine->attrib[pScr->width - n], ScreenClearAttrib, n); memset(&pScrLine->text[pScr->width - n], ' ', n); rc.left = x * pScr->cxChar; rc.right = pScr->width * pScr->cxChar; rc.top = pScr->cyChar * y; rc.bottom = pScr->cyChar * (y + 1); InvalidateRect(pScr->hWnd, &rc, TRUE); UpdateWindow(pScr->hWnd); } void ScreenRevIndex(SCREEN *pScr) { SCREENLINE *pScrLine; SCREENLINE *pTopLine; pScr->bWrapPending = FALSE; pScrLine = GetScreenLineFromY(pScr, pScr->y); pTopLine = GetScreenLineFromY(pScr, pScr->top); if(pScrLine == pTopLine) ScreenInsertLine(pScr, pScr->y); else pScr->y--; } void ScreenEraseToBOL(SCREEN *pScr) { int x1 = 0; int y1 = pScr->y; int x2 = pScr->x; int y2 = pScr->y; int n = -1; SCREENLINE *pScrLine; pScrLine = GetScreenLineFromY(pScr, pScr->y); ScreenWrapNow(pScr, &x2, &y1); y2 = y1; memset(pScrLine->attrib, ScreenClearAttrib, x2); memset(pScrLine->text, ' ', x2); } void ScreenEraseLine(SCREEN *pScr, int s) { int x1 = 0; int y1 = s; int x2 = pScr->width; int y2 = s; int n = -1; SCREENLINE *pScrLine; RECT rc; if (s < 0) { ScreenWrapNow(pScr, &x1, &y1); s = y2 = y1; x1 = 0; } pScrLine = GetScreenLineFromY(pScr,y1); memset(pScrLine->attrib, ScreenClearAttrib, pScr->width); memset(pScrLine->text, ' ', pScr->width); rc.left = 0; rc.right = pScr->width * pScr->cxChar; rc.top = pScr->cyChar * y1; rc.bottom = pScr->cyChar * (y1+1); InvalidateRect(pScr->hWnd, &rc, TRUE); SendMessage(pScr->hWnd, WM_PAINT, 0, 0); } void ScreenEraseToEndOfScreen(SCREEN *pScr) { int i; int x1 = 0; int y1 = pScr->y+1; int x2 = pScr->width; int y2 = pScr->height; int n = -1; ScreenWrapNow(pScr, &x1, &y1); y1++; x1 = 0; i = y1; ScreenEraseToEOL(pScr); while (i < pScr->height) { ScreenELO(pScr, i); ScreenEraseLine(pScr, i); i++; } } void ScreenRange(SCREEN *pScr) { if (pScr->x < 0) pScr->x = 0; if (pScr->x >= pScr->width) pScr->x = pScr->width - 1; if (pScr->y < 0) pScr->y = 0; if (pScr->y >= pScr->height) pScr->y = pScr->height - 1; } void ScreenAlign(SCREEN *pScr) /* vt100 alignment, fill screen with 'E's */ { char *tt; int i; int j; SCREENLINE *pScrLine; pScrLine = GetScreenLineFromY(pScr, pScr->top); ScreenEraseScreen(pScr); for(j = 0; j < pScr->height; j++) { tt = &pScrLine->text[0]; for(i = 0; i <= pScr->width; i++) *tt++ = 'E'; pScrLine = pScrLine->next; } } void ScreenApClear(SCREEN *pScr) { /* * reset all the ANSI parameters back to the default state */ for(pScr->parmptr=5; pScr->parmptr>=0; pScr->parmptr--) pScr->parms[pScr->parmptr] = -1; pScr->parmptr = 0; } void ScreenSetOption(SCREEN *pScr, int toggle) { if (pScr->parms[0] == -2 && pScr->parms[1] == 1) pScr->DECCKM = toggle; #if 0 switch(pScr->parms[0]) { case -2: /* Set on the '?' char */ switch(pScr->parms[1]) { case 1: /* set/reset cursor key mode */ pScr->DECCKM = toggle; break; #ifdef NOT_SUPPORTED case 2: /* set/reset ANSI/vt52 mode */ break; #endif case 3: /* set/reset column mode */ pScr->x = pScr->y = 0; /* Clear the screen, mama! */ ScreenEraseScreen(pScr); #if 0 /* removed for variable screen size */ if (toggle) /* 132 column mode */ pScr->width = pScr->allwidth; else pScr->width = 79; #endif break; #ifdef NOT_SUPPORTED case 4: /* set/reset scrolling mode */ case 5: /* set/reset screen mode */ case 6: /* set/rest origin mode */ pScr->DECORG = toggle; break; #endif case 7: /* set/reset wrap mode */ pScr->DECAWM = toggle; #if 0 /* * QAK - 7/27/90: added because resetting the virtual screen's * wrapping flag doesn't reset telnet window's wrapping */ set_vtwrap(pScrn, fpScr->DECAWM); #endif break; #ifdef NOT_SUPPORTED case 8: /* set/reset autorepeat mode */ case 9: /* set/reset interlace mode */ break; #endif default: break; } /* end switch */ break; case 4: pScr->IRM=toggle; break; default: break; } /* end switch */ #endif } #ifdef NOT_SUPPORTED void ScreenTab(SCREEN *pScr) { if (pScr->x> = pScr->width) pScr->x = pScr->width; pScr->x++; while (pScr->tabs[fpScr->x] != 'x' && pScr->x < pScr->width) pScr->x++; } #endif BOOL ScreenInsChar(SCREEN *pScr, int x) { int i; SCREENLINE *pScrLine; RECT rc; pScrLine = GetScreenLineFromY(pScr, pScr->y); if (pScrLine == NULL) return(FALSE); for(i = pScr->width - x; i >= pScr->x; i--) { pScrLine->text[x+i] = pScrLine->text[i]; pScrLine->attrib[x+i] = pScrLine->attrib[i]; } memset(&pScrLine->attrib[pScr->x], ScreenClearAttrib, x); memset(&pScrLine->text[pScr->x], ' ', x); rc.left = pScr->cxChar * x; rc.right = pScr->cxChar * (x + pScr->x); rc.top = pScr->cyChar * (pScr->y - 1); rc.bottom = pScr->cyChar * pScr->y; InvalidateRect(pScr->hWnd, &rc, TRUE); SendMessage(pScr->hWnd, WM_PAINT, 0, 0); return(TRUE); } void ScreenSaveCursor(SCREEN *pScr) { pScr->Px = pScr->x; pScr->Py = pScr->y; pScr->Pattrib = pScr->attrib; } void ScreenRestoreCursor(SCREEN *pScr) { pScr->x = pScr->Px; pScr->y = pScr->Py; ScreenRange(pScr); } void ScreenDraw(SCREEN *pScr, int x, int y, int a, int len, char *c) { int idx; SCREENLINE *pScrLine; RECT rc; pScrLine = GetScreenLineFromY(pScr, y); assert(pScrLine != NULL); for(idx = x; idx < x + len; idx++) { pScrLine->text[idx] = c[idx - x]; pScrLine->attrib[idx - x] = a; } rc.left = pScr->cxChar * x; rc.right = pScr->cxChar * (x + len); rc.top = pScr->cyChar * pScr->y; rc.bottom = pScr->cyChar * (pScr->y + 1); InvalidateRect(pScr->hWnd, &rc, TRUE); SendMessage(pScr->hWnd, WM_PAINT, 0, 0); } #if ! defined(NDEBUG) BOOL CheckScreen(SCREEN *pScr) { SCREENLINE *pLinePrev; SCREENLINE *pLine; int nscreen = 0; int nbuffer = 0; int topline = 0; char buf[512]; BOOL bBottom; BOOL bOK; pLine = pScr->buffer_top; if (pLine == NULL) { OutputDebugString("CheckScreen: buffer_top invalid"); MessageBox(NULL, "buffer_top invalid", "CheckScreen", MB_OK); return(FALSE); } bBottom = FALSE; while (TRUE) { pLinePrev = pLine; if (nscreen > 0 || pLine == pScr->screen_top) if (!bBottom) nscreen++; nbuffer++; if (pLine == pScr->screen_top) topline = nbuffer - 1; if (pLine == pScr->screen_bottom) bBottom = TRUE; pLine = pLine->next; if (pLine == NULL) break; if (pLine->prev != pLinePrev) { wsprintf(buf, "Previous ptr of line %d does not match next ptr of line %d", nbuffer, nbuffer - 1); OutputDebugString(buf); MessageBox(NULL, buf, "CheckScreen", MB_OK); } } if (pLinePrev == pScr->buffer_bottom && nscreen == pScr->height) bOK = TRUE; else { OutputDebugString("CheckScreen: Invalid number of lines on screen"); bOK = FALSE; } wsprintf(buf, "screen.width = %d\nscreen.height = %d\nscreen.maxlines = %d\nscreen.numlines = %d\nscreen.x = %d\nscreen.y = %d\nscreen.top = %d\nscreen.bottom = %d\nActual top line = %d\nActual buffer lines = %d\nActual screen lines = %d\nBottom of buffer is %s", pScr->width, pScr->height, pScr->maxlines, pScr->numlines, pScr->x, pScr->y, pScr->top, pScr->bottom, topline, nbuffer, nscreen, (pLinePrev == pScr->buffer_bottom) ? "valid" : "invalid"); MessageBox(NULL, buf, "CheckScreen", MB_OK); return(bOK); } #endif krb5-1.16/src/windows/wintel/struct.h0000644000704600001450000000123213211554426017454 0ustar ghudsonlibuuid#include "winsock.h" #ifdef KRB4 #include "kstream.h" #endif #ifdef KRB5 #include "k5stream.h" #endif #define HCONNECTION HGLOBAL typedef struct CONNECTION { SCREEN *pScreen; /* handle to screen associated with connection */ kstream ks; SOCKET socket; int pnum; /* port number associated with connection */ int telstate; /* telnet state for this connection */ int substate; /* telnet subnegotiation state */ int termsent; int echo; int ugoahead; int igoahead; int timing; int backspace; int ctrl_backspace; int termstate; /* terminal type for this connection */ int width; int height; BOOL bResizeable; } CONNECTION; krb5-1.16/src/windows/wintel/screen.c0000644000704600001450000006701613211554426017416 0ustar ghudsonlibuuid/* screen.c */ #include #include #include #include #include #include "telnet.h" #include "ini.h" #include "auth.h" extern char *encrypt_output; /* XXX hack... I wonder if this will work. These are */ extern char *decrypt_input; /* XXX really functions... */ extern char *cInvertedArray; extern int bMouseDown; extern int bSelection; static SCREEN *ScreenList; static HINSTANCE hInst; static char szScreenClass[] = "ScreenWClass"; static char szScreenMenu[] = "ScreenMenu"; static char cursor_key[8][4] = { /* Send for cursor keys */ "\x1B[D", "\x1B[A", "\x1B[C", "\x1B[B", /* Normal mode */ "\x1BOD", "\x1BOA", "\x1BOC", "\x1BOB", /* Numpad on mode */ }; void ScreenInit(HINSTANCE hInstance) { BOOL b; WNDCLASS wc; hInst = hInstance; ScreenList = NULL; wc.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS; /* Class style(s) */ wc.lpfnWndProc = ScreenWndProc; wc.cbClsExtra = 0; wc.cbWndExtra = sizeof(long); wc.hInstance = hInstance; wc.hIcon = LoadIcon(hInstance, "TERMINAL"); wc.hCursor = LoadCursor(NULL, IDC_IBEAM); wc.hbrBackground = GetStockObject(WHITE_BRUSH); wc.lpszMenuName = szScreenMenu; wc.lpszClassName = szScreenClass; b = RegisterClass(&wc); assert(b); } void SetScreenInstance(HINSTANCE hInstance) { hInst = hInstance; } int GetNewScreen(void) { SCREEN *pScr; static int id = 0; pScr = (SCREEN *) calloc(sizeof(SCREEN), 1); if (pScr == NULL) return(-1); if (ScreenList == NULL) { pScr->next = NULL; pScr->prev = NULL; } else { if (ScreenList->next == NULL) { ScreenList->next = ScreenList; ScreenList->prev = ScreenList; } pScr->next = ScreenList; pScr->prev = ScreenList->prev; ScreenList->prev->next = pScr; ScreenList->prev = pScr; } ScreenList = pScr; return(id++); } SCREENLINE * ScreenNewLine(void) { SCREENLINE *pScrLine; pScrLine = calloc(sizeof(SCREENLINE) + 2*MAX_LINE_WIDTH, 1); if (pScrLine == NULL) return (NULL); pScrLine->text = &pScrLine->buffer[0]; pScrLine->attrib = &pScrLine->buffer[MAX_LINE_WIDTH]; return(pScrLine); } static void MakeWindowTitle(char *host, int width, int height, char *title, int nchars) { char buf[128]; int hlen; hlen = strlen(host); title[0] = 0; if (hlen + 1 > nchars) return; strcpy(title, host); wsprintf(buf, " (%dh x %dw)", height, width); if ((int) strlen(buf) + hlen + 1 > nchars) return; strcat(title, buf); } SCREEN * InitNewScreen(CONFIG *Config) { TEXTMETRIC tm; HMENU hMenu = NULL; SCREEN *scr = NULL; SCREENLINE *pScrLine; SCREENLINE *pScrLineLast; int id; int idx = 0; char title[128]; HDC hDC; HFONT hFont; id = GetNewScreen(); if (id == -1) return(0); scr = ScreenList; assert(scr != NULL); hMenu = LoadMenu(hInst, szScreenMenu); assert(hMenu != NULL); scr->title = Config->title; MakeWindowTitle(Config->title, Config->width, Config->height, title, sizeof(title)); scr->hwndTel = Config->hwndTel; /* save HWND of calling window */ if (Config->backspace) { CheckMenuItem(hMenu, IDM_BACKSPACE, MF_CHECKED); CheckMenuItem(hMenu, IDM_DELETE, MF_UNCHECKED); } else { CheckMenuItem(hMenu, IDM_BACKSPACE, MF_UNCHECKED); CheckMenuItem(hMenu, IDM_DELETE, MF_CHECKED); } hDC = GetDC(NULL); assert(hDC != NULL); scr->lf.lfPitchAndFamily = FIXED_PITCH; GetPrivateProfileString(INI_FONT, "FaceName", "Courier", scr->lf. lfFaceName, LF_FACESIZE, TELNET_INI); scr->lf.lfHeight = (int) GetPrivateProfileInt(INI_FONT, "Height", 0, TELNET_INI); scr->lf.lfWidth = (int) GetPrivateProfileInt(INI_FONT, "Width", 0, TELNET_INI); scr->lf.lfPitchAndFamily = (BYTE) GetPrivateProfileInt(INI_FONT, "PitchAndFamily", 0, TELNET_INI); scr->lf.lfCharSet = (BYTE) GetPrivateProfileInt(INI_FONT, "CharSet", 0, TELNET_INI); scr->lf.lfEscapement = (BYTE) GetPrivateProfileInt(INI_FONT, "Escapement", 0, TELNET_INI); scr->lf.lfQuality = PROOF_QUALITY; scr->hSelectedFont = CreateFontIndirect((LPLOGFONT) &(scr->lf)); hFont = SelectObject(hDC, scr->hSelectedFont); GetTextMetrics(hDC, (LPTEXTMETRIC) &tm); SelectObject(hDC, hFont); scr->cxChar = tm.tmAveCharWidth; scr->cyChar = tm.tmHeight + tm.tmExternalLeading; ReleaseDC(NULL, hDC); scr->width = Config->width; scr->height = Config->height; scr->ID = id; scr->x = 0; scr->y = 0; scr->Oldx = 0; scr->Oldy = 0; scr->attrib = 0; scr->DECAWM = 1; scr->bWrapPending = FALSE; scr->top = 0; scr->bottom = scr->height-1; scr->parmptr = 0; scr->escflg = 0; scr->bAlert = FALSE; scr->numlines = 0; scr->maxlines = 150; cInvertedArray = calloc(scr->width * scr->height, 1); pScrLineLast = ScreenNewLine(); if (pScrLineLast == NULL) return(NULL); scr->screen_top = scr->buffer_top = pScrLineLast; for (idx = 0; idx < scr->height - 1; idx++) { pScrLine = ScreenNewLine(); if (pScrLine == NULL) return(NULL); pScrLine->prev = pScrLineLast; pScrLineLast->next = pScrLine; pScrLineLast = pScrLine; } scr->screen_bottom = scr->buffer_bottom = pScrLine; scr->hWnd = CreateWindow(szScreenClass, title, WS_OVERLAPPEDWINDOW | WS_VSCROLL, CW_USEDEFAULT, CW_USEDEFAULT, scr->cxChar * scr->width + FRAME_WIDTH, scr->cyChar * scr->height + FRAME_HEIGHT, NULL, hMenu, hInst, scr); assert(scr->hWnd != NULL); ShowWindow(scr->hWnd, SW_SHOW); CreateCaret(scr->hWnd, NULL, scr->cxChar, 2); SetCaretPos(scr->x*scr->cxChar, (scr->y+1) * scr->cyChar); ShowCaret(scr->hWnd); return(ScreenList); } void DeleteTopLine( SCREEN *pScr) { assert(pScr->buffer_top != NULL); pScr->buffer_top = pScr->buffer_top->next; assert(pScr->buffer_top != NULL); free(pScr->buffer_top->prev); pScr->buffer_top->prev = NULL; pScr->numlines--; } /* DeleteTopLine */ static void SetScreenScrollBar( SCREEN *pScr) { if (pScr->numlines <= 0) { SetScrollRange(pScr->hWnd, SB_VERT, 0, 100, FALSE); SetScrollPos(pScr->hWnd, SB_VERT, 0, TRUE); EnableScrollBar(pScr->hWnd, SB_VERT, ESB_DISABLE_BOTH); } else { SetScrollRange(pScr->hWnd, SB_VERT, 0, pScr->numlines, FALSE); SetScrollPos(pScr->hWnd, SB_VERT, pScr->numlines, TRUE); EnableScrollBar(pScr->hWnd, SB_VERT, ESB_ENABLE_BOTH); } } /* SetScreenScrollBar */ int ScreenScroll( SCREEN *pScr) { SCREENLINE *pScrLine; SCREENLINE *pPrev; SCREENLINE *pNext; SCREENLINE *pScrollTop; SCREENLINE *pScrollBottom; BOOL bFullScreen = TRUE; HDC hDC; RECT rc; Edit_ClearSelection(pScr); pScrollTop = GetScreenLineFromY(pScr, pScr->top); pScrollBottom = GetScreenLineFromY(pScr, pScr->bottom); if (pScrollTop != pScr->screen_top) { bFullScreen = FALSE; rc.left = 0; rc.right = pScr->cxChar * pScr->width; rc.top = pScr->cyChar * (pScr->top); rc.bottom = pScr->cyChar * (pScr->bottom+1); pNext = pScrollTop->next; pPrev = pScrollTop->prev; pPrev->next = pNext; pNext->prev = pPrev; pScrLine = pScrollTop; ScreenClearLine(pScr, pScrLine); } else { pScr->numlines++; pScrLine = ScreenNewLine(); if (pScrLine == NULL) return(0); pScr->screen_top = pScrollTop->next; } if (pScrLine == NULL) return(0); pNext = pScrollBottom->next; pScrollBottom->next = pScrLine; pScrLine->next = pNext; pScrLine->prev = pScrollBottom; if (pNext != NULL) pNext->prev = pScrLine; if (pScrollBottom != pScr->screen_bottom) { bFullScreen = FALSE; rc.left = 0; rc.right = pScr->cxChar * pScr->width; rc.top = pScr->cyChar * pScr->top; rc.bottom = pScr->cyChar * (pScr->bottom+1); } else { if (pScr->screen_bottom == pScr->buffer_bottom) pScr->buffer_bottom = pScrLine; pScr->screen_bottom = pScrLine; } #if 0 CheckScreen(fpScr); #endif pScr->y++; if (pScr->y > pScr->bottom) pScr->y = pScr->bottom; hDC = GetDC(pScr->hWnd); assert(hDC != NULL); if (bFullScreen) ScrollDC(hDC, 0, -pScr->cyChar, NULL, NULL, NULL, NULL); else ScrollDC(hDC, 0, -pScr->cyChar, &rc, &rc, NULL, NULL); PatBlt(hDC, 0, pScr->bottom * pScr->cyChar, pScr->width * pScr->cxChar, pScr->cyChar, WHITENESS); ReleaseDC(pScr->hWnd, hDC); if (pScr->numlines == pScr->maxlines) DeleteTopLine(pScr); else SetScreenScrollBar(pScr); return(1); } /* ScreenScroll */ int DrawTextScreen( RECT rcInvalid, SCREEN *pScr, HDC hDC) { SCREENLINE *pScrLineTmp; SCREENLINE *pScrLine; int x = 0; int y = 0; int left = 0; int right = 0; int i; int len; char attrib; #define YPOS (y*pScr->cyChar) pScrLine = pScr->screen_top; for (y = 0; y < pScr->height; y++) { if (!pScrLine) continue; if (YPOS >= rcInvalid.top - pScr->cyChar && YPOS <= rcInvalid.bottom + pScr->cyChar) { if (y < 0) y = 0; if (y >= pScr->height) y = pScr->height - 1; left = (rcInvalid.left / pScr->cxChar) - 1; right = (rcInvalid.right / pScr->cxChar) + 1; if (left < 0) left = 0; if (right > pScr->width - 1) right = pScr->width - 1; x = left; while (x <= right) { if (!pScrLine->text[x]) { x++; continue; } if (SCR_isrev(pScrLine->attrib[x])) { SelectObject(hDC, pScr->hSelectedFont); SetTextColor(hDC, RGB(255, 255, 255)); SetBkColor(hDC, RGB(0, 0, 0)); } else if (SCR_isblnk(pScrLine->attrib[x])) { SelectObject(hDC, pScr->hSelectedFont); SetTextColor(hDC, RGB(255, 0, 0)); SetBkColor(hDC, RGB(255, 255, 255)); } else if (SCR_isundl(pScrLine->attrib[x])) { SetTextColor(hDC, RGB(255, 0, 0)); SetBkColor(hDC, RGB(255, 255, 255)); SelectObject(hDC, pScr->hSelectedULFont); } else { SelectObject(hDC,pScr->hSelectedFont); SetTextColor(hDC, RGB(0, 0, 0)); SetBkColor(hDC, RGB(255, 255, 255)); } len = 1; attrib = pScrLine->attrib[x]; for (i = x + 1; i <= right; i++) { if (pScrLine->attrib[i] != attrib || !pScrLine->text[i]) break; len++; } TextOut(hDC, x*pScr->cxChar, y*pScr->cyChar, &pScrLine->text[x], len); x += len; } } pScrLineTmp = pScrLine->next; pScrLine = pScrLineTmp; } return(0); } /* DrawTextScreen */ static BOOL SetInternalScreenSize( SCREEN *pScr, int width, int height) { RECT rc; char *p; int idx; int n; int newlines; SCREENLINE *pNewLine; SCREENLINE *pTopLine; SCREENLINE *pBottomLine; #if 0 int col; int row; int dydestbottom; #endif GetClientRect(pScr->hWnd, &rc); width = (rc.right - rc.left) / pScr->cxChar; height = (rc.bottom - rc.top) / pScr->cyChar; if (pScr->height == height && pScr->width == width) return(FALSE); pScr->Oldx = 0; pScr->Oldy = 0; pScr->attrib = 0; /* Reallocate the inverted array of bytes and copy the values from the old screen to the new screen. */ p = calloc(width * height, 1); ScreenCursorOff(pScr); #if 0 /* Copy inversion array to desitination */ for (col = 0; col < width; col++) { for (row = 0; row < height; row++) { dydestbottom = height - 1 - row; if (col < pScr->width && dydestbottom < pScr->height - 1) p[row * width + col] = cInvertedArray[(pScr->height - 1 - dydestbottom) * pScr->width + col]; } } #endif free(cInvertedArray); cInvertedArray = p; /* Append any new lines which need to be added to accomodate the new screen size. */ pBottomLine = pScr->buffer_bottom; newlines = height - (pScr->height + pScr->numlines); if (newlines > 0) { pScr->y += pScr->numlines; pScr->numlines = 0; for (idx = 0; idx < newlines; idx++) { pNewLine = ScreenNewLine(); if (pNewLine == NULL) return(FALSE); pNewLine->prev = pBottomLine; if (pBottomLine == NULL) return(FALSE); pBottomLine->next = pNewLine; pBottomLine = pNewLine; } } /* If we already have plenty of lines, then we need to get rid of the scrollback lines, if too many exist. The cursor should end up the same distance from the bottom of the screen as is started out in this instance. */ if (newlines < 0) { pScr->y = (height - 1) - (pScr->bottom - pScr->y); if (pScr->y < 0) pScr->y = 0; pScr->numlines = -newlines; n = pScr->numlines - pScr->maxlines; for (idx = 0; idx < n; idx++) DeleteTopLine(pScr); } /* Calculate the position of the buffer relative to the screen. */ pScr->screen_bottom = pBottomLine; pScr->buffer_bottom = pBottomLine; pTopLine = pBottomLine; for (idx = 1; idx < height; idx++) { pTopLine = pTopLine->prev; } pScr->screen_top = pTopLine; pScr->width = width; pScr->height = height; pScr->top = 0; pScr->bottom = height - 1; if (pScr->x >= width) pScr->x = width - 1; if (pScr->y >= height) pScr->y = height - 1; SetScreenScrollBar(pScr); ScreenCursorOn(pScr); return(TRUE); } /* SetInternalScreenSize */ static int ScreenAdjustUp( SCREEN *pScr, int n) { int idx; SCREENLINE *pLine1; SCREENLINE *pLine2; for (idx = 0; idx < n; idx++) { if (pScr->screen_top == pScr->buffer_top) return(-idx); pLine1 = pScr->screen_top->prev; if (pLine1 == NULL) return(-idx); pLine2 = pScr->screen_bottom->prev; if (pLine2 == NULL) return(-idx); pScr->screen_top = pLine1; pScr->screen_bottom = pLine2; } return(idx); } /* ScreenAdjustUp */ static int ScreenAdjustDown( SCREEN *pScr, int n) { int idx; SCREENLINE *pLine1; SCREENLINE *pLine2; for (idx = 0; idx < n; idx++) { if (pScr->screen_bottom == pScr->buffer_bottom) return(-idx); pLine1 = pScr->screen_top->next; if (pLine1 == NULL) return(-idx); pLine2 = pScr->screen_bottom->next; if (pLine2 == NULL) return(-idx); pScr->screen_top = pLine1; pScr->screen_bottom = pLine2; } return(idx); } /* ScreenAdjustDown */ long PASCAL ScreenWndProc( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { MINMAXINFO *lpmmi; SCREEN *pScr; HMENU hMenu; PAINTSTRUCT ps; int x = 0; int y = 0; int ScrollPos; int tmpScroll = 0; int idx; HDC hDC; RECT rc; char title[128]; static int bDoubleClick = FALSE; switch (message) { case WM_COMMAND: pScr = (SCREEN *) GetWindowLong(hWnd, SCREEN_HANDLE); assert (pScr != NULL); switch (wParam) { case IDM_EXIT: if (MessageBox(hWnd, "Terminate this connection?", "Telnet", MB_OKCANCEL) == IDOK) { pScr = (SCREEN *) GetWindowLong(hWnd, SCREEN_HANDLE); assert (pScr != NULL); SendMessage(pScr->hwndTel, WM_MYSCREENCLOSE, 0, (LPARAM) pScr); } break; case IDM_BACKSPACE: hMenu = GetMenu(hWnd); CheckMenuItem(hMenu, IDM_BACKSPACE, MF_CHECKED); CheckMenuItem(hMenu, IDM_DELETE, MF_UNCHECKED); SendMessage(pScr->hwndTel, WM_MYSCREENCHANGEBKSP, VK_BACK, (LPARAM) pScr); break; case IDM_DELETE: hMenu = GetMenu(hWnd); CheckMenuItem(hMenu, IDM_BACKSPACE, MF_UNCHECKED); CheckMenuItem(hMenu, IDM_DELETE, MF_CHECKED); SendMessage(pScr->hwndTel, WM_MYSCREENCHANGEBKSP, 0x7f, (LPARAM) pScr); break; case IDM_FONT: ScreenCursorOff(pScr); ProcessFontChange(hWnd); ScreenCursorOn(pScr); break; case IDM_COPY: Edit_Copy(hWnd); hMenu=GetMenu(hWnd); Edit_ClearSelection(pScr); break; case IDM_PASTE: Edit_Paste(hWnd); break; case IDM_HELP_INDEX: WinHelp(hWnd, HELP_FILE, HELP_INDEX, 0); break; case IDM_ABOUT: #ifdef CYGNUS #ifdef KRB4 strcpy(strTmp, " Kerberos 4 for Windows\n"); #endif #ifdef KRB5 strcpy(strTmp, " KerbNet for Windows\n"); #endif strcat(strTmp, "\n Version 1.00\n\n"); strcat(strTmp, " For support, contact:\n"); strcat(strTmp, " Cygnus Support - (415) 903-1400\n"); #else /* CYGNUS */ strcpy(strTmp, " Kerberos 5 Telnet for Windows\n"); strcat(strTmp, " ALPHA SNAPSHOT 2\n\n"); #endif /* CYGNUS */ if (encrypt_flag) { strcat(strTmp, "\n[Encryption of output requested. State: "); strcat(strTmp, (encrypt_output ? "encrypting]" : "INACTIVE]")); strcat(strTmp, "\n[Decryption of input requested. State: "); strcat(strTmp, (decrypt_input ? "decrypting]\n" : "INACTIVE]\n")); } MessageBox(NULL, strTmp, "Kerberos", MB_OK); break; #if defined(DEBUG) case IDM_DEBUG: CheckScreen(pScr); break; #endif } break; case WM_NCCREATE: pScr = (SCREEN *) ((LPCREATESTRUCT) lParam)->lpCreateParams; pScr->hWnd = hWnd; SetWindowLong(hWnd, SCREEN_HANDLE, (LONG) pScr); SetScrollRange(hWnd, SB_VERT, 0, 100, FALSE); SetScrollPos(hWnd, SB_VERT, 0, TRUE); EnableScrollBar(hWnd, SB_VERT, ESB_DISABLE_BOTH); return(TRUE); case WM_VSCROLL: pScr = (SCREEN *) GetWindowLong(hWnd, SCREEN_HANDLE); assert (pScr != NULL); ScreenCursorOff(pScr); switch(wParam) { case SB_LINEDOWN: if (ScreenAdjustDown(pScr, 1) <= 0) break; hDC = GetDC(hWnd); assert(hDC != NULL); rc.left = 0; rc.right = pScr->cxChar * pScr->width; rc.top = 0; rc.bottom = pScr->cyChar * (pScr->bottom + 1); ScrollDC(hDC, 0, -pScr->cyChar, &rc, &rc, NULL, NULL); ReleaseDC(hWnd, hDC); rc.top = pScr->cyChar * pScr->bottom; InvalidateRect(hWnd, &rc, TRUE); ScrollPos = GetScrollPos(hWnd, SB_VERT); SetScrollPos(hWnd, SB_VERT, ScrollPos + 1, TRUE); UpdateWindow(hWnd); break; case SB_LINEUP: if (ScreenAdjustUp(pScr, 1) <= 0) break; hDC = GetDC(hWnd); assert(hDC != NULL); rc.left = 0; rc.right = pScr->cxChar * pScr->width; rc.top = 0; rc.bottom = pScr->cyChar * (pScr->bottom + 1); ScrollDC(hDC, 0, pScr->cyChar, &rc, &rc, NULL, NULL); ReleaseDC(hWnd, hDC); rc.bottom = pScr->cyChar; InvalidateRect(hWnd, &rc, TRUE); ScrollPos = GetScrollPos(pScr->hWnd, SB_VERT); SetScrollPos(hWnd,SB_VERT, ScrollPos - 1, TRUE); UpdateWindow(hWnd); break; case SB_PAGEDOWN: idx = abs(ScreenAdjustDown(pScr, pScr->height)); hDC = GetDC(hWnd); assert(hDC != NULL); rc.left = 0; rc.right = pScr->cxChar * pScr->width; rc.top = 0; rc.bottom = pScr->cyChar * (pScr->bottom+1); ScrollDC(hDC, 0, -idx * pScr->cyChar, &rc, &rc, NULL, NULL); ReleaseDC(hWnd, hDC); rc.top = pScr->cyChar * (pScr->bottom - idx + 1); InvalidateRect(hWnd, &rc, TRUE); ScrollPos=GetScrollPos(hWnd, SB_VERT); SetScrollPos(hWnd, SB_VERT, ScrollPos + idx, TRUE); break; case SB_PAGEUP: idx = abs(ScreenAdjustUp(pScr, pScr->height)); hDC = GetDC(hWnd); assert(hDC != NULL); rc.left = 0; rc.right = pScr->cxChar * pScr->width; rc.top = 0; rc.bottom = pScr->cyChar * (pScr->bottom + 1); ScrollDC(hDC, 0, idx * pScr->cyChar, &rc, &rc, NULL, NULL); ReleaseDC(hWnd, hDC); rc.bottom = idx * pScr->cyChar; InvalidateRect(hWnd, &rc, TRUE); ScrollPos=GetScrollPos(hWnd, SB_VERT); SetScrollPos(hWnd, SB_VERT, ScrollPos - idx, TRUE); break; case SB_THUMBPOSITION: case SB_THUMBTRACK: ScrollPos = GetScrollPos(hWnd, SB_VERT); tmpScroll = ScrollPos - LOWORD(lParam); if (tmpScroll == 0) break; if (tmpScroll > 0) ScreenAdjustUp(pScr, tmpScroll); else ScreenAdjustDown(pScr, -tmpScroll); if (abs(tmpScroll) < pScr->height) { hDC = GetDC(hWnd); assert(hDC != NULL); rc.left = 0; rc.right = pScr->cxChar * pScr->width; rc.top = 0; rc.bottom = pScr->cyChar * (pScr->bottom + 1); ScrollDC(hDC, 0, tmpScroll * pScr->cyChar, &rc, &rc, NULL, NULL); ReleaseDC(hWnd, hDC); if (tmpScroll > 0) { rc.bottom = tmpScroll * pScr->cyChar; InvalidateRect(hWnd, &rc, TRUE); } else { rc.top = (pScr->bottom + tmpScroll + 1) * pScr->cyChar; InvalidateRect(hWnd, &rc, TRUE); } } else InvalidateRect(hWnd, NULL, TRUE); SetScrollPos(hWnd, SB_VERT, LOWORD(lParam), TRUE); UpdateWindow(hWnd); break; } ScreenCursorOn(pScr); break; case WM_KEYDOWN: if (wParam == VK_INSERT) { if (GetKeyState(VK_SHIFT) < 0) PostMessage(hWnd, WM_COMMAND, IDM_PASTE, 0); else if (GetKeyState(VK_CONTROL) < 0) PostMessage(hWnd, WM_COMMAND, IDM_COPY, 0); break; } /* ** Check for cursor keys. With control pressed, we treat as ** keyboard equivalents to scrolling. Otherwise, we send ** a WM_MYCURSORKEY message with the appropriate string ** to be sent. Sending the actual string allows the upper ** level to be ignorant of keyboard modes, etc. */ if (wParam < VK_PRIOR || wParam > VK_DOWN) /* Is it a cursor key? */ break; if (GetKeyState (VK_CONTROL) >= 0) { /* No control key */ if (wParam >= VK_LEFT && wParam <= VK_DOWN) { pScr = (SCREEN *) GetWindowLong(hWnd, SCREEN_HANDLE); assert (pScr != NULL); wParam = wParam - VK_LEFT + (pScr->DECCKM ? 4 : 0); SendMessage (pScr->hwndTel, WM_MYCURSORKEY, strlen(cursor_key[wParam]), (LPARAM) (char *) cursor_key[wParam]); } } else { /* Control is down */ switch (wParam) { case VK_PRIOR: /* Page up */ SendMessage(hWnd, WM_VSCROLL, SB_PAGEUP, 0); break; case VK_NEXT: /* Page down */ SendMessage(hWnd, WM_VSCROLL, SB_PAGEDOWN, 0); break; case VK_UP: /* Line up */ SendMessage(hWnd, WM_VSCROLL, SB_LINEUP, 0); break; case VK_DOWN: /* Line down */ SendMessage(hWnd, WM_VSCROLL, SB_LINEDOWN, 0); break; } } UpdateWindow(hWnd); break; case WM_CHAR: pScr = (SCREEN *) GetWindowLong(hWnd, SCREEN_HANDLE); assert (pScr != NULL); SendMessage(pScr->hwndTel, WM_MYSCREENCHAR, wParam, (LPARAM) pScr); break; case WM_INITMENU: if (IsClipboardFormatAvailable(CF_TEXT)) EnableMenuItem((HMENU) wParam, IDM_PASTE, MF_ENABLED); else EnableMenuItem((HMENU) wParam, IDM_PASTE, MF_GRAYED); if (bSelection) EnableMenuItem((HMENU) wParam, IDM_COPY, MF_ENABLED); else EnableMenuItem((HMENU) wParam, IDM_COPY, MF_GRAYED); break; case WM_GETMINMAXINFO: pScr = (SCREEN *) GetWindowLong(hWnd, SCREEN_HANDLE); if (pScr == NULL) /* Used on creation when window word not set */ pScr = ScreenList; lpmmi = (MINMAXINFO *) lParam; if (FRAME_WIDTH + MAX_LINE_WIDTH * pScr->cxChar < lpmmi->ptMaxSize.x) lpmmi->ptMaxSize.x = FRAME_WIDTH + MAX_LINE_WIDTH * pScr->cxChar; lpmmi->ptMaxTrackSize.x = lpmmi->ptMaxSize.x; lpmmi->ptMinTrackSize.x = FRAME_WIDTH + 20 * pScr->cxChar; lpmmi->ptMinTrackSize.y = FRAME_HEIGHT + 4 * pScr->cyChar; break; case WM_LBUTTONDOWN: if (bDoubleClick) Edit_TripleClick(hWnd, lParam); else Edit_LbuttonDown(hWnd, lParam); break; case WM_LBUTTONUP: Edit_LbuttonUp(hWnd, lParam); break; case WM_LBUTTONDBLCLK: bDoubleClick = TRUE; SetTimer(hWnd, TIMER_TRIPLECLICK, GetDoubleClickTime(), NULL); Edit_LbuttonDblclk(hWnd, lParam); break; case WM_TIMER: if (wParam == TIMER_TRIPLECLICK) bDoubleClick = FALSE; break; case WM_RBUTTONUP: pScr = (SCREEN *) GetWindowLong(hWnd, SCREEN_HANDLE); assert (pScr != NULL); Edit_Copy(hWnd); Edit_ClearSelection(pScr); Edit_Paste(hWnd); break; case WM_MOUSEMOVE: if (bMouseDown) Edit_MouseMove(hWnd, lParam); break; case WM_RBUTTONDOWN: #if 0 pScr = (SCREEN *) GetWindowLong(hWnd, SCREEN_HANDLE); assert (pScr != NULL); wsprintf(strTmp,"fp->x=%d fp->y=%d text=%s \r\n", pScr->screen_top->x, pScr->screen_top->y, pScr->screen_top->text); OutputDebugString(strTmp); #endif break; case WM_PAINT: pScr = (SCREEN *) GetWindowLong(hWnd, SCREEN_HANDLE); assert (pScr != NULL); BeginPaint (hWnd, &ps); SelectObject(ps.hdc, pScr->hSelectedFont); if (pScr->screen_bottom != NULL) DrawTextScreen(ps.rcPaint, pScr, ps.hdc); else OutputDebugString("screen_bottom is NULL.\r\n"); EndPaint(hWnd, &ps); break; case WM_CLOSE: if (MessageBox(hWnd, "Terminate this connection?", "Telnet", MB_OKCANCEL) == IDOK) { pScr = (SCREEN *) GetWindowLong(hWnd, SCREEN_HANDLE); assert (pScr != NULL); SendMessage(pScr->hwndTel, WM_MYSCREENCLOSE, 0, (LPARAM) pScr); return (DefWindowProc(hWnd, message, wParam, lParam)); } break; case WM_DESTROY: pScr = (SCREEN *) GetWindowLong(hWnd, SCREEN_HANDLE); if (pScr != NULL) DeleteObject(pScr->hSelectedFont); return (DefWindowProc(hWnd, message, wParam, lParam)); case WM_ACTIVATE: if (wParam != WA_INACTIVE) { pScr = (SCREEN *) GetWindowLong(hWnd, SCREEN_HANDLE); assert (pScr != NULL); if (pScr->bAlert) { char strTitle[128]; int idx; GetWindowText(hWnd, strTitle, sizeof(strTitle)); if (strTitle[0] == ALERT) { idx = lstrlen(strTitle); strTitle[idx - 2] = 0; SetWindowText(hWnd, &strTitle[2]); pScr->bAlert = FALSE; } } } return (DefWindowProc(hWnd, message, wParam, lParam)); case WM_SIZE: if (wParam == SIZE_MINIMIZED) break; pScr = (SCREEN *) GetWindowLong(hWnd, SCREEN_HANDLE); assert (pScr != NULL); if (SetInternalScreenSize(pScr, LOWORD(lParam), HIWORD(lParam))) { SendMessage(pScr->hwndTel, WM_MYSCREENSIZE, 0, MAKELONG(pScr->width, pScr->height)); } MakeWindowTitle(pScr->title, pScr->width, pScr->height, title, sizeof(title)); SetWindowText(hWnd, title); break; case WM_SETFOCUS: pScr = (SCREEN *) GetWindowLong(hWnd, SCREEN_HANDLE); assert (pScr != NULL); CreateCaret(hWnd, NULL, pScr->cxChar, 2); ScreenCursorOn(pScr); break; case WM_KILLFOCUS: DestroyCaret(); break; default: return(DefWindowProc(hWnd, message, wParam, lParam)); } return(0); } /* ScreenWndProc */ void ScreenBell( SCREEN *pScr) { char strTitle[128]; int idx; MessageBeep(MB_ICONEXCLAMATION); if (pScr->hWnd != GetActiveWindow()) { FlashWindow(pScr->hWnd, TRUE); if (!pScr->bAlert) { strTitle[0] = ALERT; strTitle[1] = SPACE; GetWindowText(pScr->hWnd, &strTitle[2], sizeof(strTitle) - 2); idx = lstrlen(strTitle); strTitle[idx] = SPACE; strTitle[idx+1] = ALERT; strTitle[idx+2] = 0; SetWindowText(pScr->hWnd, strTitle); } FlashWindow(pScr->hWnd, FALSE); pScr->bAlert = TRUE; } } /* ScreenBell */ void ScreenBackspace(SCREEN *pScr) { RECT rc; pScr->bWrapPending = FALSE; rc.left = pScr->x * pScr->cxChar; rc.right = (pScr->x + 1) * pScr->cxChar; rc.top = pScr->cyChar * pScr->y; rc.bottom = pScr->cyChar * (pScr->y + 1); InvalidateRect(pScr->hWnd, &rc, TRUE); pScr->x--; if (pScr->x < 0) pScr->x = 0; UpdateWindow(pScr->hWnd); } /* ScreenBackspace */ void ScreenTab( SCREEN *pScr) { int num_spaces; int idx; SCREENLINE *pScrLine; int iTest = 0; HDC hDC; num_spaces = TAB_SPACES - (pScr->x % TAB_SPACES); if (pScr->x + num_spaces >= pScr->width) num_spaces = pScr->width - pScr->x; pScrLine = GetScreenLineFromY(pScr, pScr->y); if (pScrLine == NULL) return; for (idx = 0; idx < num_spaces; idx++, pScr->x++) { if (!pScrLine->text[pScr->x]) iTest=1; if (iTest) pScrLine->text[pScr->x] = SPACE; } hDC = GetDC(pScr->hWnd); assert(hDC != NULL); SelectObject(hDC, pScr->hSelectedFont); TextOut(hDC, (pScr->x - num_spaces) * pScr->cxChar, pScr->y * pScr->cyChar, pScrLine->text + pScr->x - num_spaces, num_spaces); ReleaseDC(pScr->hWnd, hDC); if (pScr->x >= pScr->width) pScr->x = pScr->width - 1; pScr->bWrapPending = FALSE; } /* ScreenTab */ void ScreenCarriageFeed( SCREEN *pScr) { pScr->bWrapPending = FALSE; pScr->x = 0; } /* ScreenCarriageFeed */ krb5-1.16/src/windows/wintel/telopts.h0000644000704600001450000001026213211554426017625 0ustar ghudsonlibuuid/* * telopts.h * Used for telnet options **************************************************************************** * * * * * NCSA Telnet * * by Tim Krauskopf, VT100 by Gaige Paulsen, Tek by Aaron Contorer * * Additions by Kurt Mahan, Heeren Pathak, & Quincey Koziol * * * * National Center for Supercomputing Applications * * 152 Computing Applications Building * * 605 E. Springfield Ave. * * Champaign, IL 61820 * * * **************************************************************************** * Quincey Koziol * Defines for telnet options and related things */ #ifndef TELOPTS_H #define TELOPTS_H #define NUMLMODEOPTIONS 30 /* Definitions for telnet protocol */ #define STNORM 0 /* Definition of the lowest telnet byte following an IAC byte */ #define LOW_TEL_OPT 236 #define TEL_EOF 236 #define SUSP 237 #define ABORT 238 #define SE 240 #define NOP 241 #define DM 242 #define BREAK 243 #define IP 244 #define AO 245 #define AYT 246 #define EC 247 #define EL 248 #define GOAHEAD 249 #define SB 250 #define WILLTEL 251 #define WONTTEL 252 #define DOTEL 253 #define DONTTEL 254 #define IAC 255 /* Assigned Telnet Options */ #define BINARY 0 #define ECHO 1 #define RECONNECT 2 #define SGA 3 #define AMSN 4 #define STATUS 5 #define TIMING 6 #define RCTAN 7 #define OLW 8 #define OPS 9 #define OCRD 10 #define OHTS 11 #define OHTD 12 #define OFFD 13 #define OVTS 14 #define OVTD 15 #define OLFD 16 #define XASCII 17 #define LOGOUT 18 #define BYTEM 19 #define DET 20 #define SUPDUP 21 #define SUPDUPOUT 22 #define SENDLOC 23 #define TERMTYPE 24 #define EOR 25 #define TACACSUID 26 #define OUTPUTMARK 27 #define TERMLOCNUM 28 #define REGIME3270 29 #define X3PAD 30 #define NAWS 31 #define TERMSPEED 32 #define TFLOWCNTRL 33 #define LINEMODE 34 #define MODE 1 #define MODE_EDIT 1 #define MODE_TRAPSIG 2 #define MODE_ACK 4 #define MODE_SOFT_TAB 8 #define MODE_LIT_ECHO 16 #define FORWARDMASK 2 #define SLC 3 #define SLC_DEFAULT 3 #define SLC_VALUE 2 #define SLC_CANTCHANGE 1 #define SLC_NOSUPPORT 0 #define SLC_LEVELBITS 3 #define SLC_ACK 128 #define SLC_FLUSHIN 64 #define SLC_FLUSHOUT 32 #define SLC_SYNCH 1 #define SLC_BRK 2 #define SLC_IP 3 #define SLC_AO 4 #define SLC_AYT 5 #define SLC_EOR 6 #define SLC_ABORT 7 #define SLC_EOF 8 #define SLC_SUSP 9 #define SLC_EC 10 #define SLC_EL 11 #define SLC_EW 12 #define SLC_RP 13 #define SLC_LNEXT 14 #define SLC_XON 15 #define SLC_XOFF 16 #define SLC_FORW1 17 #define SLC_FORW2 18 #define SLC_MCL 19 #define SLC_MCR 20 #define SLC_MCWL 21 #define SLC_MCWR 22 #define SLC_MCBOL 23 #define SLC_MCEOL 24 #define SLC_INSRT 25 #define SLC_OVER 26 #define SLC_ECR 27 #define SLC_EWR 28 #define SLC_EBOL 29 #define SLC_EEOL 30 #define XDISPLOC 35 #define ENVIRONMENT 36 #define AUTHENTICATION 37 #define TELOPT_AUTHENTICATION AUTHENTICATION #define DATA_ENCRYPTION 38 #define XOPTIONS 255 #define LINEMODE_MODES_SUPPORTED 0x1B /* * set this flag for linemode special functions which are supported by * Telnet, even though they are not currently active. This is to allow * the other side to negotiate to a "No Support" state for an option * and then change later to supporting it, so we know it's ok to change * our "No Support" state to something else ("Can't Change", "Value", * whatever) */ #define SLC_SUPPORTED 0x10 #define ESCFOUND 5 #define IACFOUND 6 #define NEGOTIATE 1 #endif /* telopts.h */ krb5-1.16/src/windows/wintel/ktelnet.hlp0000644000704600001450000002176413211554426020146 0ustar ghudsonlibuuid?_6#&"",".*+,.aandasBackspaceb`ycanChoosingclickpboardConfig8ureP!tentsCopy0daemonD0eleteEditforfromHelpHosthIfinInsertintoisitKerbkeymenunameNetonorotherPas&gportPprograms_ctsh cutstrdsuchtelnetT textthatTheJtoTousevswindowWindowsYouyouyour/&;)z4 o |CONTEXT||CTXOMAP|FONTo|KWBTREE|KWDATA|KWMAP |PhrImage|PhrIndexe|SYSTEM|TOPIC|TTLBTREEMQHC0bJbLۖʒiS]eUI l! 2Kerb*Net Telnet for WindowsZmainmainrZ secondary(w95sec)Q   2>1>&&- k* $[6&>&U x[-4,03d ߎH! `PWpCfollowing6+TopicsareCavailable#:8\/$HPjP2~ (XForER6 #press F1/:k`1``i`5&@*!6!pi`C T)hSɁ'A aWhen#firs@trunp Fwill3display+dialogboxC@promptT2r: #Enter NT$r#arrowt`one43histo ry <want 3connec Cd@iffereZ3rdh Z,3includeyZ+numbaynexI Csepara ted#space N otenh*mu be3n%"RZ.<':1:57*qP*Tk:9 @=)& CEfigu3wheth0jKitsJK"+delete")6l-rSDappriF@+choicr"L"BvangeHonts FA ...",p j`+(>style(e g .,bold +italic ),size!6q1?`#1@*,38. 8*q]vcopyl"h|" r Dthmouse C0= hU+C>0xFbtrl@"\!#pas]U Bc0G#P)H#Shift@+I4 1j\/,@*-n\*#D( 23;O";sXervbEf# emFTP Vsorts#4 ,1hj,/* ,kqh+ & GgN^$+(remi:k3evnd|hmG 9#!71Vz .2hр*` .`00,e On anyUNIX#hos .FCfun+onssamPew,"!do>~{;exPhibiCorr;behavi]>RK~FA "^H#"^?",tLryachFE%VodeU111RI(MS Sans Serif A8`````/&;)F24backspaceChoosing a Host and PortconfigureConfiguring Kerb*Net Telnet for Windows ContentscopyCopying and Pastingdeleteedit font$host(hostname,paste0port4/&;)LzJContentsChoosing a Host and Port`Configuring Kerb*Net Telnet for WindowsCopying and PastingTelnet Port`Telnet DaemonBackspace vs. Delete/&;)L4hSɁ)&ʨ `U%ߎH`3d.߬. krb5-1.16/src/windows/wintel/telnet.def0000644000704600001450000000202013211554426017726 0ustar ghudsonlibuuid; module-definition file for testdll -- used by LINK.EXE NAME TELNET DESCRIPTION 'Sample Microsoft Windows Application' EXETYPE WINDOWS STUB 'WINSTUB.EXE' SEGMENTS _TEXT CLASS 'CODE' PRELOAD CODE DISCARDABLE DATA PRELOAD MOVEABLE MULTIPLE HEAPSIZE 10240 ; All functions that will be called by any Windows routine ; MUST be exported. EXPORTS MainWndProc @1 ; name of window processing function OpenTelnetDlg @3 ; name of "Open New Telnet Connection" Dialog Function IMPORTS WINSOCK.WSAStartup WINSOCK.WSACleanup WINSOCK.WSAAsyncSelect WINSOCK.WSAGetLastError WINSOCK.WSAAsyncGetHostByName WINSOCK.listen WINSOCK.accept WINSOCK.__wsafdisset WINSOCK.socket WINSOCK.bind WINSOCK.gethostbyname WINSOCK.getsockname WINSOCK.htons WINSOCK.connect WINSOCK.recv WINSOCK.send WINSOCK.htonl WINSOCK.closesocket WINSOCK.select WINSOCK.ioctlsocket WINSOCK.getpeername krb5-1.16/src/windows/wintel/screen.h0000644000704600001450000001437213211554426017420 0ustar ghudsonlibuuidextern long PASCAL ScreenWndProc(HWND,UINT,WPARAM,LPARAM); /* * Definition of attribute bits in the Virtual Screen * * 0 - Bold * 1 - * 2 - * 3 - Underline * 4 - Blink * 5 - * 6 - Reverse * 7 - Graphics character set * */ #define SCR_isbold(x) (x & 0x01) #define SCR_isundl(x) (x & 0x08) #define SCR_isblnk(x) (x & 0x10) #define SCR_isrev(x) (x & 0x40) #define SCR_setrev(x) (x ^= 0x40) #define SCR_isgrph(x) (x & 0x80) #define SCR_inattr(x) (x & 0xd9) #define SCR_graph(x) (x | 0x80) #define SCR_notgraph(x) (x & 0x7F) #define SCREEN_HANDLE 0 /* offset in extra window info */ #define WM_MYSCREENCHAR (WM_USER+1) #define WM_MYSCREENBLOCK (WM_USER+2) #define WM_MYSYSCHAR (WM_USER+3) #define WM_MYSCREENCLOSE (WM_USER+4) #define WM_MYSCREENCHANGEBKSP (WM_USER+5) #define WM_MYSCREENSIZE (WM_USER+6) #define WM_NETWORKEVENT (WM_USER+7) #define WM_HOSTNAMEFOUND (WM_USER+8) #define WM_MYCURSORKEY (WM_USER+9) #define FRAME_HEIGHT ((2* GetSystemMetrics(SM_CYFRAME))+GetSystemMetrics(SM_CYCAPTION)+GetSystemMetrics(SM_CYMENU)+3) #define FRAME_WIDTH (2*GetSystemMetrics(SM_CXFRAME)+GetSystemMetrics(SM_CXVSCROLL)) #define TAB_SPACES 8 #define SPACE 32 #define ALERT 0x21 #define MAX_LINE_WIDTH 512 /* not restricted to 1 byte */ typedef struct SCREENLINE { struct SCREENLINE *next; struct SCREENLINE *prev; int width; char *text; char *attrib; char buffer[0]; } SCREENLINE; typedef struct SCREEN { LPSTR title; HWND hWnd; HWND hwndTel; SCREENLINE *screen_top; SCREENLINE *screen_bottom; SCREENLINE *buffer_top; SCREENLINE *buffer_bottom; int ID; int type; int width; int height; int maxlines; /* Maximum number of scrollback lines */ int numlines; /* Current number of scrollback lines */ int savelines; /* Save lines off top? */ int ESscroll; /* Scroll screen when ES received */ int attrib; /* current attribute */ int x; /* current cursor position */ int y; /* current cursor position */ int Oldx; /* internally used to redraw cursor */ int Oldy; int Px; /* saved cursor pos and attribute */ int Py; int Pattrib; int VSIDC; /* Insert/Delete character mode 0=draw line */ int DECAWM; /* AutoWrap mode 0=off */ BOOL bWrapPending; /* AutoWrap mode is on - wrap on next character */ int DECCKM; /* Cursor key mode */ int DECPAM; /* keyPad Application mode */ int IRM; /* Insert/Replace mode */ int escflg; /* Current Escape level */ int top; /* Vertical bounds of screen */ int bottom; int parmptr; int cxChar; /* Width of the current font */ int cyChar; /* Height of the current font */ BOOL bAlert; int parms[6]; /* Ansi Params */ LOGFONT lf; HFONT hSelectedFont; HFONT hSelectedULFont; char tabs[MAX_LINE_WIDTH]; struct SCREEN *next; struct SCREEN *prev; } SCREEN; typedef struct CONFIG { LPSTR title; HWND hwndTel; int ID; int type; int height; int width; int maxlines; /* Maximum number of scrollback lines */ int backspace; int ESscroll; /* Scroll screen when ES received */ int VSIDC; /* Insert/Delete character mode 0=draw line */ int DECAWM; /* AutoWrap mode 0=off */ int IRM; /* Insert/Replace mode */ } CONFIG; #define TELNET_SCREEN 0 #define CONSOLE_SCREEN 1 #define IDM_FONT 100 #define IDM_BACKSPACE 101 #define IDM_DELETE 102 #define IDM_ABOUT 103 #define IDM_HELP_INDEX 104 #define IDM_EXIT 105 #define HELP_FILE "ktelnet.hlp" #define IDM_COPY 200 #define IDM_PASTE 201 #define IDM_DEBUG 202 #define TIMER_TRIPLECLICK 1000 #define IDC_ALLOCFAIL 1 #define IDC_LOCKFAIL 2 #define IDC_LOADSTRINGFAIL 3 #define IDC_FONT 6 #define DESIREDPOINTSIZE 12 /* Prototypes */ void NEAR InitializeStruct( WORD wCommDlgType, LPSTR lpStruct, HWND hWnd); void ScreenInit( HINSTANCE hInstance); void SetScreenInstance( HINSTANCE hInstance); SCREENLINE *ScreenNewLine(); void ScreenBell( SCREEN *pScr); void ScreenBackspace( SCREEN *pScr); void ScreenTab( SCREEN *pScr); void ScreenCarriageFeed( SCREEN *pScr); int ScreenScroll( SCREEN *pScr); void DeleteTopLine( SCREEN *pScr); /* emul.c */ void ScreenEm( LPSTR c, int len, SCREEN *pScr); /* intern.c */ SCREENLINE *GetScreenLineFromY( SCREEN *pScr, int y); SCREENLINE *ScreenClearLine( SCREEN *pScr, SCREENLINE *pScrLine); void ScreenUnscroll( SCREEN *pScr); void ScreenELO( SCREEN *pScr, int s); void ScreenEraseScreen( SCREEN *pScr); void ScreenTabClear( SCREEN *pScr); void ScreenTabInit( SCREEN *pScr); void ScreenReset( SCREEN *pScr); void ScreenIndex( SCREEN *pScr); void ScreenWrapNow( SCREEN *pScr, int *xp, int *yp); void ScreenEraseToEOL( SCREEN *pScr); void ScreenEraseToBOL( SCREEN *pScr); void ScreenEraseLine( SCREEN *pScr, int s); void ScreenEraseToEndOfScreen( SCREEN *pScr); void ScreenRange( SCREEN *pScr); void ScreenAlign( SCREEN *pScr); void ScreenApClear( SCREEN *pScr); void ScreenSetOption( SCREEN *pScr, int toggle); BOOL ScreenInsChar( SCREEN *pScr, int x); void ScreenSaveCursor( SCREEN *pScr); void ScreenRestoreCursor( SCREEN *pScr); void ScreenDraw( SCREEN *pScr, int x, int y, int a, int len, char *c); void ScreenCursorOff( SCREEN *pScr); void ScreenCursorOn( SCREEN *pScr); void ScreenDelChars( SCREEN *pScr, int n); void ScreenRevIndex( SCREEN *pScr); void ScreenDelLines( SCREEN *pScr, int n, int s); void ScreenInsLines( SCREEN *pScr, int n, int s); #if ! defined(NDEBUG) BOOL CheckScreen( SCREEN *pScr); #endif void ProcessFontChange( HWND hWnd); void Edit_LbuttonDown( HWND hWnd, LPARAM lParam); void Edit_LbuttonDblclk( HWND hWnd, LPARAM lParam); void Edit_LbuttonUp( HWND hWnd, LPARAM lParam); void Edit_TripleClick( HWND hWnd, LPARAM lParam); void Edit_MouseMove( HWND hWnd, LPARAM lParam); void Edit_ClearSelection( SCREEN *pScr); void Edit_Copy( HWND hWnd); void Edit_Paste( HWND hWnd); SCREEN *InitNewScreen( CONFIG *Config); krb5-1.16/src/windows/wintel/k5stream.h0000644000704600001450000000355413211554426017674 0ustar ghudsonlibuuid/* Header file for encrypted-stream library. * Written by Ken Raeburn (Raeburn@Cygnus.COM). * Copyright (C) 1991, 1992, 1994 by Cygnus Support. * * Permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation. * Cygnus Support makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #ifndef K5STREAM_H #define K5STREAM_H typedef struct kstream_int { /* Object we pass around */ int fd; /* Open socket descriptor */ int (*encrypt)(struct kstream_data_block *, /* output */ struct kstream_data_block *, /* input */ struct kstream *kstream); int (*decrypt)(struct kstream_data_block *, /* output */ struct kstream_data_block *, /* input */ struct kstream *kstream); } *kstream; typedef void *kstream_ptr; /* Data send on the kstream */ struct kstream_data_block { kstream_ptr ptr; size_t length; }; struct kstream_crypt_ctl_block { int (*encrypt)(struct kstream_data_block *, /* output */ struct kstream_data_block *, /* input */ kstream); int (*decrypt)(struct kstream_data_block *, /* output */ struct kstream_data_block *, /* input */ kstream); int (*init)(kstream, kstream_ptr); void (*destroy)(kstream); }; /* Prototypes */ int kstream_destroy(kstream); void kstream_set_buffer_mode(kstream, int); kstream kstream_create_from_fd(int fd, const struct kstream_crypt_ctl_block *, kstream_ptr); int kstream_write(kstream, void *, size_t); int kstream_read(kstream, void *, size_t); #endif /* K5STREAM_H */ krb5-1.16/src/windows/wintel/terminal.ico0000644000704600001450000000137613211554426020277 0ustar ghudsonlibuuid ( @krb5-1.16/src/windows/wintel/Makefile.in0000644000704600001450000000245013211554426020027 0ustar ghudsonlibuuid# Makefile for the Kerberos for Windows telnet client # Works for both k4 and k5 releases. # OBJS = $(OUTPRE)telnet.obj $(OUTPRE)negotiat.obj $(OUTPRE)auth.obj \ $(OUTPRE)edit.obj $(OUTPRE)emul.obj $(OUTPRE)font.obj \ $(OUTPRE)intern.obj $(OUTPRE)screen.obj $(OUTPRE)encrypt.obj \ $(OUTPRE)genget.obj ##### Options # Set NODEBUG if building release instead of debug !IF ! defined(KVERSION) KRBOPT =-DFORWARD -DAUTHENTICATION -DENCRYPTION -DDES_ENCRYPTION KVERSION= 5 !endif KRB = KRB$(KVERSION) BUILDTOP=..\.. LOCALINCLUDES= /I$(BUILDTOP) /I$(BUILDTOP)\include /I$(BUILDTOP)\include\krb5 \ /I$(BUILDTOP)\lib\crypto\des RESFILE = $(OUTPRE)telnet.res XOBJS = $(RESFILE) $(OUTPRE)k5stream.obj $(OUTPRE)enc_des.obj DEFINES = /D$(KRB)=1 $(KRBOPT) RFLAGS = $(LOCALINCLUDES) RCFLAGS = $(RFLAGS) -D_WIN32 -DTELNET_APP ##### Linker LINK = link LIBS = $(KLIB) $(CLIB) $(WLIB) SYSLIBS = kernel32.lib ws2_32.lib user32.lib gdi32.lib comdlg32.lib LFLAGS = /nologo $(LOPTS) all: Makefile $(OUTPRE)telnet.exe $(OUTPRE)telnet.exe: telnet.def $(OBJS) $(XOBJS) $(LIBS) $(LINK) $(LFLAGS) /map:$*.map /out:$@ $(OBJS) $(XOBJS) \ $(LIBS) $(SYSLIBS) $(SCLIB) $(_VC_MANIFEST_EMBED_EXE) install: copy $(OUTPRE)telnet.exe $(DESTDIR) clean: $(RM) $(OUTPRE)*.exe $(OUTPRE)*.res $(OUTPRE)*.map $(RESFILE): ..\version.rc krb5-1.16/src/windows/wintel/wt-proto.h0000644000704600001450000000111613211554426017724 0ustar ghudsonlibuuid/* wt-proto.h */ BOOL InitApplication( HINSTANCE ); BOOL InitInstance( HINSTANCE, int ); LRESULT CALLBACK MainWndProc( HWND, UINT, WPARAM, LPARAM ); INT_PTR CALLBACK OpenTelnetDlg( HWND, UINT, WPARAM, LPARAM ); int TelnetSend( kstream, char *, int, int ); int OpenTelnetConnection( void ); int DoDialog( char *szDialog, DLGPROC lpfnDlgProc ); BOOL parse_cmdline( char *cmdline ); CONNECTION * GetNewConnection( void ); void start_negotiation( kstream ks ); krb5-1.16/src/windows/wintel/telnet.rc0000644000704600001450000001722413211554426017610 0ustar ghudsonlibuuid//Microsoft Developer Studio generated resource script. // // XXX since modified by hand... #include "resource.h" #define APSTUDIO_READONLY_SYMBOLS ///////////////////////////////////////////////////////////////////////////// // // Generated from the TEXTINCLUDE 2 resource. // #define APSTUDIO_HIDDEN_SYMBOLS #include "windows.h" #undef APSTUDIO_HIDDEN_SYMBOLS #include "dialog.h" #include "screen.h" ///////////////////////////////////////////////////////////////////////////// #undef APSTUDIO_READONLY_SYMBOLS ///////////////////////////////////////////////////////////////////////////// // English (U.S.) resources #if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) #ifdef _WIN32 LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US #pragma code_page(1252) #endif //_WIN32 ///////////////////////////////////////////////////////////////////////////// // // Dialog // OPENTELNETDLG DIALOG DISCARDABLE 63, 65, 175, 129 #ifdef _WIN32 STYLE DS_ABSALIGN | DS_MODALFRAME | DS_3DLOOK | WS_POPUP | WS_CAPTION | WS_SYSMENU #else STYLE DS_ABSALIGN | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU #endif CAPTION "Open New Telnet Connection" FONT 8, "MS Sans Serif" BEGIN LTEXT "To Host:",IDC_STATIC,3,10,33,10,NOT WS_GROUP COMBOBOX TEL_CONNECT_NAME,37,9,128,76,CBS_DROPDOWN | WS_VSCROLL | WS_GROUP | WS_TABSTOP CONTROL "Forward credentials",IDC_FORWARD,"Button", BS_AUTOCHECKBOX | WS_DISABLED | WS_TABSTOP,37,28,77,10 CONTROL "Forward remote credentials",IDC_FORWARDFORWARD,"Button", BS_AUTOCHECKBOX | WS_DISABLED | WS_TABSTOP,37,44,101,10 CONTROL "Enable encryption",IDC_ENCRYPT,"Button",BS_AUTOCHECKBOX | WS_DISABLED | WS_TABSTOP,37,60,73,10 CONTROL "Connect as userid",IDC_STATIC,"Static", SS_LEFTNOWORDWRAP,15,84,58,8 EDITTEXT TEL_CONNECT_USERID,77,82,80,13,ES_AUTOHSCROLL | WS_DISABLED DEFPUSHBUTTON "OK",TEL_OK,20,106,51,14,WS_GROUP PUSHBUTTON "Cancel",TEL_CANCEL,106,106,51,14 END ABOUTBOX DIALOG DISCARDABLE 69, 33, 175, 148 STYLE DS_ABSALIGN | DS_MODALFRAME | WS_CAPTION | WS_SYSMENU CAPTION "About TCPwin" BEGIN ICON "NCSA",-1,15,12,16,16 CTEXT "Microsoft Windows",-1,48,11,93,8 CTEXT "NCSA TCP/IP Networking Kernel",-1,38,21,120,8 CTEXT "Version 1.0b2",-1,20,31,144,8 PUSHBUTTON "OK",IDOK,72,126,39,14,WS_GROUP | NOT WS_TABSTOP CTEXT "Written By:",606,20,50,144,8 CTEXT "Jon Mittelhauser (jonm@ncsa.uiuc.edu)",607,20,61,144,8 CTEXT "Chris Wilson (cwilson@ncsa.uiuc.edu)",608,20,71,144,8 CTEXT "Special Thanks to:",609,21,97,143,8 CTEXT "Joe Lepore for DPMI interface code",610,20,107,144,8 CTEXT "Keberized by: Cygnus Support",611,20,82,144,8 END CONFIG_DLG DIALOG DISCARDABLE 6, 18, 160, 130 STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU CAPTION "Configure Session" FONT 8, "MS Sans Serif" BEGIN LTEXT "Session Name:",301,1,5,54,8 LTEXT "Default Session",CON_SESSIONNAME,55,5,105,8 LTEXT "Window Title:",303,1,17,49,8 EDITTEXT CON_WINDOWTITLE,53,15,102,12,ES_AUTOHSCROLL CONTROL "132",CON_COLUMNS132,"Button",BS_AUTORADIOBUTTON | WS_GROUP,53,33,39,10 CONTROL "80",CON_COLUMNS80,"Button",BS_AUTORADIOBUTTON,110,33,39, 10 CONTROL "Backspace",CON_BACKSPACE,"Button",BS_AUTORADIOBUTTON | WS_GROUP,53,46,49,10 CONTROL "Delete",CON_DELETE,"Button",BS_AUTORADIOBUTTON,110,46, 39,10 CONTROL "CRLF",CON_CRLF,"Button",BS_AUTORADIOBUTTON | WS_GROUP, 53,59,39,10 CONTROL "CR-NUL",CON_CRNUL,"Button",BS_AUTORADIOBUTTON,110,59,39, 10 CONTROL "Buffers",CON_BUFFERS,"Button",BS_AUTORADIOBUTTON | WS_GROUP,53,72,39,10 CONTROL "Sends",CON_SENDS,"Button",BS_AUTORADIOBUTTON,110,72,39, 10 LTEXT "Columns",313,1,33,49,8 LTEXT "Backspace is",314,1,46,51,8 LTEXT "Return Sends",315,1,59,49,8 LTEXT "Echo Mode",316,1,72,49,8 CONTROL "Scrollback",CON_SCRLBCK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,1,86,50,10 EDITTEXT CON_NUMLINES,53,85,28,12,ES_AUTOHSCROLL LTEXT "lines",319,85,86,33,8 DEFPUSHBUTTON "OK",CON_OK,20,108,50,14,WS_GROUP PUSHBUTTON "Use Defaults",CON_USEDEFAULTS,90,108,50,14 END IDM_PRINTQUEUE DIALOG DISCARDABLE 69, 25, 160, 80 STYLE WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_VSCROLL | WS_HSCROLL | WS_SYSMENU CAPTION "Print Queue" FONT 8, "MS Sans Serif" BEGIN END IDD_DIALOG1 DIALOG DISCARDABLE 0, 0, 183, 92 STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "Dialog" FONT 8, "MS Sans Serif" BEGIN DEFPUSHBUTTON "OK",IDOK,126,7,50,14 PUSHBUTTON "Cancel",IDCANCEL,126,24,50,14 END ///////////////////////////////////////////////////////////////////////////// // // Icon // // Icon with lowest ID value placed first to ensure application icon // remains consistent on all systems. NCSA ICON DISCARDABLE "ncsa.ico" TERMINAL ICON DISCARDABLE "terminal.ico" ///////////////////////////////////////////////////////////////////////////// // // Menu // SCREENMENU MENU DISCARDABLE BEGIN POPUP "&File" BEGIN MENUITEM "E&xit Alt+F4", IDM_EXIT END POPUP "&Edit" BEGIN MENUITEM "&Copy Cltr+Ins", IDM_COPY MENUITEM "&Paste Shift+Ins", IDM_PASTE END POPUP "&Options" BEGIN MENUITEM "&Backspace", IDM_BACKSPACE MENUITEM "&Delete", IDM_DELETE, CHECKED MENUITEM SEPARATOR MENUITEM "&Font...", IDM_FONT END #if 0 POPUP "&Send", GRAYED BEGIN MENUITEM "&Interrupt Process", IDM_SEND_IP MENUITEM "&Are You There?", IDM_SEND_AYT MENUITEM "A&bort Process", IDM_SEND_ABORT END #endif POPUP "&Help" BEGIN MENUITEM "&Index...", IDM_HELP_INDEX MENUITEM SEPARATOR MENUITEM "&About...", IDM_ABOUT END END #ifdef APSTUDIO_INVOKED ///////////////////////////////////////////////////////////////////////////// // // TEXTINCLUDE // 1 TEXTINCLUDE DISCARDABLE BEGIN "resource.h\0" END 2 TEXTINCLUDE DISCARDABLE BEGIN "#define APSTUDIO_HIDDEN_SYMBOLS\r\n" "#include ""windows.h""\r\n" "#undef APSTUDIO_HIDDEN_SYMBOLS\r\n" "#include ""dialog.h""\r\n" "#include ""screen.h""\r\n" "\0" END 3 TEXTINCLUDE DISCARDABLE BEGIN "\r\n" "\0" END #endif // APSTUDIO_INVOKED ///////////////////////////////////////////////////////////////////////////// // // DESIGNINFO // #ifdef APSTUDIO_INVOKED GUIDELINES DESIGNINFO DISCARDABLE BEGIN IDD_DIALOG1, DIALOG BEGIN LEFTMARGIN, 7 RIGHTMARGIN, 176 TOPMARGIN, 7 BOTTOMMARGIN, 85 END END #endif // APSTUDIO_INVOKED #endif // English (U.S.) resources ///////////////////////////////////////////////////////////////////////////// #ifndef APSTUDIO_INVOKED ///////////////////////////////////////////////////////////////////////////// // // Generated from the TEXTINCLUDE 3 resource. // ///////////////////////////////////////////////////////////////////////////// #endif // not APSTUDIO_INVOKED #include "..\version.rc" krb5-1.16/src/windows/wintel/resource.h0000644000704600001450000000074113211554426017763 0ustar ghudsonlibuuid//{{NO_DEPENDENCIES}} // Microsoft Developer Studio generated include file. // Used by telnet.rc // #define IDD_DIALOG1 101 #define IDC_STATIC -1 // Next default values for new objects // #ifdef APSTUDIO_INVOKED #ifndef APSTUDIO_READONLY_SYMBOLS #define _APS_NEXT_RESOURCE_VALUE 103 #define _APS_NEXT_COMMAND_VALUE 40005 #define _APS_NEXT_CONTROL_VALUE 1002 #define _APS_NEXT_SYMED_VALUE 101 #endif #endif krb5-1.16/src/windows/wintel/encrypt.h0000644000704600001450000001436213211554426017624 0ustar ghudsonlibuuid/*- * Copyright (c) 1991, 1993 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * @(#)encrypt.h 8.1 (Berkeley) 6/4/93 */ /* * Copyright (C) 1990 by the Massachusetts Institute of Technology * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #ifdef ENCRYPTION #ifndef __ENCRYPTION__ #define __ENCRYPTION__ #define DIR_DECRYPT 1 #define DIR_ENCRYPT 2 typedef unsigned char Block[8]; typedef unsigned char *BlockT; typedef struct { Block _; } Schedule[16]; #define VALIDKEY(key) ( key[0] | key[1] | key[2] | key[3] | key[4] | key[5] | key[6] | key[7]) #define SAMEKEY(k1, k2) (!memcmp((void *)k1, (void *)k2, sizeof(Block))) typedef struct { short type; int length; unsigned char *data; } Session_Key; #ifdef DEBUG int printsub(char, unsigned char *, size_t); #endif void encrypt_parse(kstream, unsigned char *, int); typedef struct { char *name; int type; void (*output) (unsigned char *, int); int (*input) (int); void (*init) (int); int (*start) (int, int); int (*is) (unsigned char *, int); int (*reply) (unsigned char *, int); void (*session) (Session_Key *, int); int (*keyid) (int, unsigned char *, int *); void (*printsub) (unsigned char *, int, unsigned char *, int); } Encryptions; #define SK_DES 1 /* Matched Kerberos v5 ENCTYPE_DES */ void encrypt_init (kstream, kstream_ptr); Encryptions *findencryption (int); void encrypt_auto (int); void decrypt_auto (int); void encrypt_is (unsigned char *, int); void encrypt_reply (unsigned char *, int); void encrypt_start_input (int); void encrypt_session_key (Session_Key *, int); void encrypt_end_input (void); void encrypt_start_output (int); void encrypt_end_output (void); void encrypt_send_request_start (void); void encrypt_send_request_end (void); void encrypt_send_end (void); void encrypt_wait (void); int encrypt_is_encrypting (void); void encrypt_send_support (void); void encrypt_send_keyid (int, unsigned char *, int, int); int net_write (unsigned char *, int); int encrypt_cmd (int, char **); void encrypt_display (void); void krbdes_encrypt (unsigned char *, int); int krbdes_decrypt (int); int krbdes_is (unsigned char *, int); int krbdes_reply (unsigned char *, int); void krbdes_init (int); int krbdes_start (int, int); void krbdes_session (Session_Key *, int); void krbdes_printsub (unsigned char *, int, unsigned char *, int); void cfb64_encrypt (unsigned char *, int); int cfb64_decrypt (int); void cfb64_init (int); int cfb64_start (int, int); int cfb64_is (unsigned char *, int); int cfb64_reply (unsigned char *, int); void cfb64_session (Session_Key *, int); int cfb64_keyid (int, unsigned char *, int *); void cfb64_printsub (unsigned char *, int, unsigned char *, int); void ofb64_encrypt (unsigned char *, int); int ofb64_decrypt (int); void ofb64_init (int); int ofb64_start (int, int); int ofb64_is (unsigned char *, int); int ofb64_reply (unsigned char *, int); void ofb64_session (Session_Key *, int); int ofb64_keyid (int, unsigned char *, int *); void ofb64_printsub (unsigned char *, int, unsigned char *, int); int KRB5_CALLCONV des_new_random_key (Block); void KRB5_CALLCONV des_set_random_generator_seed (Block); void KRB5_CALLCONV des_key_sched (Block, Schedule); void KRB5_CALLCONV des_ecb_encrypt (Block, Block, Schedule, int); /* int des_string_to_key (char *, Block); */ #ifdef DEBUG extern int encrypt_debug_mode; #endif extern int (*decrypt_input) (int); extern void (*encrypt_output) (unsigned char *, int); int decrypt_ks_hack(unsigned char *, int); #endif /* __ENCRYPTION__ */ #endif /* ENCRYPTION */ krb5-1.16/src/windows/wintel/enc_des.h0000644000704600001450000001200113211554426017524 0ustar ghudsonlibuuid/*- * Copyright (c) 1991, 1993 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * @(#)enc-proto.h 8.1 (Berkeley) 6/4/93 */ /* * Copyright (C) 1990 by the Massachusetts Institute of Technology * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #ifdef ENCRYPTION void encrypt_init (char *, int); Encryptions *findencryption (int); void encrypt_auto (int); void decrypt_auto (int); void encrypt_is (unsigned char *, int); void encrypt_reply (unsigned char *, int); void encrypt_start_input (int); void encrypt_session_key (Session_Key *, int); void encrypt_end_input (void); void encrypt_start_output (int); void encrypt_end_output (void); void encrypt_send_request_start (void); void encrypt_send_request_end (void); void encrypt_send_end (void); void encrypt_wait (void); int encrypt_is_encrypting (void); void encrypt_send_support (void); void encrypt_send_keyid (int, unsigned char *, int, int); int net_write (unsigned char *, int); #ifdef TELENTD void encrypt_wait (void); #else int encrypt_cmd (int, char **); void encrypt_display (void); #endif void krbdes_encrypt (unsigned char *, int); int krbdes_decrypt (int); int krbdes_is (unsigned char *, int); int krbdes_reply (unsigned char *, int); void krbdes_init (int); int krbdes_start (int, int); void krbdes_session (Session_Key *, int); void krbdes_printsub (unsigned char *, int, unsigned char *, int); void cfb64_encrypt (unsigned char *, int); int cfb64_decrypt (int); void cfb64_init (int); int cfb64_start (int, int); int cfb64_is (unsigned char *, int); int cfb64_reply (unsigned char *, int); void cfb64_session (Session_Key *, int); int cfb64_keyid (int, unsigned char *, int *); void cfb64_printsub (unsigned char *, int, unsigned char *, int); void ofb64_encrypt (unsigned char *, int); int ofb64_decrypt (int); void ofb64_init (int); int ofb64_start (int, int); int ofb64_is (unsigned char *, int); int ofb64_reply (unsigned char *, int); void ofb64_session (Session_Key *, int); int ofb64_keyid (int, unsigned char *, int *); void ofb64_printsub (unsigned char *, int, unsigned char *, int); int des_new_random_key (Block); void des_set_random_generator_seed (Block); void des_key_sched (Block, Schedule); void des_ecb_encrypt (Block, Block, Schedule, int); int des_string_to_key (char *, Block); #endif /* ENCRYPTION */ krb5-1.16/src/windows/wintel/auth.h0000644000704600001450000000107013211554426017071 0ustar ghudsonlibuuid/* * Implements Kerberos 4 authentication and ecryption */ #ifndef WINTEL_AUTH_H #define WINTEL_AUTH_H void auth_parse(kstream, unsigned char *, int); int auth_init(kstream, kstream_ptr); void auth_destroy(kstream); int auth_encrypt(struct kstream_data_block *, struct kstream_data_block *, kstream); int auth_decrypt(struct kstream_data_block *, struct kstream_data_block *, kstream); extern BOOL forward_flag; extern BOOL forwardable_flag; extern BOOL forwarded_tickets; #ifdef ENCRYPTION extern BOOL encrypt_flag; #endif #endif /* WINTEL_AUTH_H */ krb5-1.16/src/windows/wintel/telnet.h0000644000704600001450000000124513211554426017427 0ustar ghudsonlibuuid#ifndef TELNET_H_INC #define TELNET_H_INC #include #include #ifdef KRB5 #include "krb5.h" #include "k5stream.h" #endif #include "dialog.h" #include "screen.h" #include "struct.h" #include "wt-proto.h" #include "winsock.h" #include "ini.h" /* globals */ extern char szAutoHostName[64]; extern char szUserName[64]; extern char szHostName[64]; #ifdef KRB5 extern krb5_context k5_context; #endif extern void parse(CONNECTION *, unsigned char *, int); extern void send_naws(CONNECTION *); extern char strTmp[1024]; #define DEF_WIDTH 80 #define DEF_HEIGHT 24 #ifdef DEBUG void hexdump(char *, unsigned char *, int); #endif #endif /* TELNET_H_INC */ krb5-1.16/src/windows/wintel/emul.c0000644000704600001450000004161713211554426017100 0ustar ghudsonlibuuid/* emul.c */ #include "windows.h" #include "screen.h" static int ScreenEmChars(SCREEN *pScr, char *c, int len) { /* * Function: Send a string of characters to the screen. Placement * continues as long as the stream of characters does not contain any * control chracters or cause wrapping to another line. When a control * character is encountered or wrapping occurs, display stops and a * count of the number of characters is returned. * * Parameters: * pScr - the screen to place the characters on. * c - the string of characters to place on the screen. * len - the number of characters contained in the string * * Returns: The number of characters actually placed on the screen. */ int insert; int ocount; int attrib; int extra; int nchars; char *acurrent; /* place to put attributes */ char *current; /* place to put characters */ char *start; SCREENLINE *pScrLine; if (len <= 0) return(0); if (pScr->x != pScr->width - 1) pScr->bWrapPending = FALSE; else { if (pScr->bWrapPending) { pScr->x = 0; pScr->bWrapPending = FALSE; ScreenIndex(pScr); } } pScrLine = GetScreenLineFromY(pScr, pScr->y); if (pScrLine == NULL) return(0); current = &pScrLine->text[pScr->x]; acurrent = &pScrLine->attrib[pScr->x]; start = current; ocount = pScr->x; extra = 0; attrib = pScr->attrib; insert = pScr->IRM; for (nchars = 0; nchars < len && *c >= 32; nchars++) { if (insert) ScreenInsChar(pScr, 1); *current = *c; *acurrent = (char) attrib; c++; if (pScr->x < pScr->width - 1) { acurrent++; current++; pScr->x++; } else { extra = 1; if (pScr->DECAWM) { pScr->bWrapPending = TRUE; nchars++; break; } } } ScreenDraw(pScr, ocount, pScr->y, pScr->attrib, pScr->x - ocount + extra, start); return(nchars); } void ScreenEm(LPSTR c, int len, SCREEN *pScr) { int escflg; /* vt100 escape level */ RECT rc; unsigned int ic; char stat[20]; int i; int nchars; if (pScr->screen_bottom != pScr->buffer_bottom) { ScreenUnscroll(pScr); InvalidateRect(pScr->hWnd, NULL, TRUE); SetScrollPos(pScr->hWnd, SB_VERT, pScr->numlines, TRUE); } ScreenCursorOff(pScr); escflg = pScr->escflg; #ifdef UM if (pScr->localprint && len > 0) { /* see if printer needs anything */ pcount = send_localprint(c, len); len -= pcount; c += pcount; } #endif while (len > 0) { /* * look at first character in the vt100 string, if it is a * non-printable ascii code */ while((*c < 32) && (escflg == 0) && (len > 0)) { switch(*c) { case 0x1b: /* ESC found (begin vt100 control sequence) */ escflg++; break; case -1: /* IAC from telnet session */ escflg = 6; break; #ifdef CISB case 0x05: /* CTRL-E found (answerback) */ bp_ENQ(); break; #endif case 0x07: /* CTRL-G found (bell) */ ScreenBell(pScr); break; case 0x08: /* CTRL-H found (backspace) */ ScreenBackspace(pScr); break; case 0x09: /* CTRL-I found (tab) */ ScreenTab(pScr); /* Later change for versatile tabbing */ break; case 0x0a: /* CTRL-J found (line feed) */ case 0x0b: /* CTRL-K found (treat as line feed) */ case 0x0c: /* CTRL-L found (treat as line feed) */ ScreenIndex(pScr); break; case 0x0d: /* CTRL-M found (carriage feed) */ ScreenCarriageFeed(pScr); break; #if 0 case 0x0e: /* CTRL-N found (invoke Graphics (G1) character set) */ if (pScr->G1) pScr->attrib = VSgraph(pScr->attrib); else pScr->attrib = VSnotgraph(pScr->attrib); pScr->charset = 1; break; case 0x0f: /* CTRL-O found (invoke 'normal' (G0) character set) */ if(pScr->G0) pScr->attrib = VSgraph(pScr->attrib); else pScr->attrib = VSnotgraph(pScr->attrib); pScr->charset = 0; break; #endif #ifdef CISB case 0x10: /* CTRL-P found (undocumented in vt100) */ bp_DLE(c, len); len = 0; break; #endif #if 0 case 0x11: /* CTRL-Q found (XON) (unused presently) */ case 0x13: /* CTRL-S found (XOFF) (unused presently) */ case 0x18: /* CTRL-X found (CAN) (unused presently) */ case 0x1a: /* CTRL-Z found (SUB) (unused presently) */ break; #endif } c++; /* advance to the next character in the string */ len--; /* decrement the counter */ } if (escflg == 0) { /* check for normal character to print */ nchars = ScreenEmChars(pScr, c, len); c += nchars; len -= nchars; } while ((len > 0) && (escflg == 1)) { /* ESC character was found */ switch(*c) { case 0x08: /* CTRL-H found (backspace) */ ScreenBackspace(pScr); break; /* * mostly cursor movement options, and DEC private stuff following */ case '[': ScreenApClear(pScr); escflg = 2; break; case '#': /* various screen adjustments */ escflg = 3; break; case '(': /* G0 character set options */ escflg = 4; break; case ')': /* G1 character set options */ escflg = 5; break; case '>': /* keypad numeric mode (DECKPAM) */ pScr->DECPAM = 0; escflg = 0; break; case '=': /* keypad application mode (DECKPAM) */ pScr->DECPAM = 1; escflg = 0; break; case '7': /* save cursor (DECSC) */ ScreenSaveCursor(pScr); escflg = 0; break; case '8': /* restore cursor (DECRC) */ ScreenRestoreCursor(pScr); escflg = 0; break; #if 0 case 'c': /* reset to initial state (RIS) */ ScreenReset(pScr); escflg = 0; break; #endif case 'D': /* index (move down one line) (IND) */ ScreenIndex(pScr); escflg = 0; break; case 'E': /* next line (move down one line and to first column) (NEL) */ pScr->x = 0; ScreenIndex(pScr); escflg = 0; break; case 'H': /* horizontal tab set (HTS) */ pScr->tabs[pScr->x] = 'x'; escflg = 0; break; #ifdef CISB case 'I': /* undoumented in vt100 */ bp_ESC_I(); break; #endif case 'M': /* reverse index (move up one line) (RI) */ ScreenRevIndex(pScr); escflg = 0; break; case 'Z': /* identify terminal (DECID) */ escflg = 0; break; default: /* put the ESC character into the Screen */ ScreenEmChars(pScr, "\033", 1); /* put the next character into the Screen */ ScreenEmChars(pScr, c, 1); escflg = 0; break; } /* end switch */ c++; len--; } while((escflg == 2) && (len > 0)) { /* '[' handling */ switch(*c) { case 0x08: /* backspace */ ScreenBackspace(pScr); break; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': /* numeric parameters */ if (pScr->parms[pScr->parmptr] < 0) pScr->parms[pScr->parmptr] = 0; pScr->parms[pScr->parmptr] *= 10; pScr->parms[pScr->parmptr] += *c - '0'; break; case '?': /* vt100 mode change */ pScr->parms[pScr->parmptr++] = -2; break; case ';': /* parameter divider */ pScr->parmptr++; break; case 'A': /* cursor up (CUU) */ pScr->bWrapPending = FALSE; rc.left = pScr->x * pScr->cxChar; rc.right = (pScr->x + 1) * pScr->cxChar; rc.top = pScr->cyChar * pScr->y; rc.bottom = pScr->cyChar * (pScr->y + 1); InvalidateRect(pScr->hWnd, &rc, TRUE); if (pScr->parms[0] < 1) pScr->y--; else pScr->y -= pScr->parms[0]; if(pScr->y < pScr->top) pScr->y = pScr->top; ScreenRange(pScr); escflg = 0; SendMessage(pScr->hWnd, WM_PAINT, 0, 0); break; case 'B': /* cursor down (CUD) */ pScr->bWrapPending = FALSE; rc.left = pScr->x * pScr->cxChar; rc.right = (pScr->x + 1) * pScr->cxChar; rc.top = pScr->cyChar * pScr->y; rc.bottom = pScr->cyChar * (pScr->y + 1); InvalidateRect(pScr->hWnd, &rc, TRUE); if (pScr->parms[0] < 1) pScr->y++; else pScr->y += pScr->parms[0]; if (pScr->y > pScr->bottom) pScr->y = pScr->bottom; ScreenRange(pScr); escflg = 0; SendMessage(pScr->hWnd, WM_PAINT, 0, 0); break; case 'C': /* cursor forward (right) (CUF) */ pScr->bWrapPending = FALSE; rc.left = pScr->x * pScr->cxChar; rc.right = (pScr->x + 1) * pScr->cxChar; rc.top = pScr->cyChar * pScr->y; rc.bottom = pScr->cyChar * (pScr->y +1); InvalidateRect(pScr->hWnd, &rc, TRUE); if(pScr->parms[0] < 1) pScr->x++; else pScr->x += pScr->parms[0]; ScreenRange(pScr); if (pScr->x > pScr->width) pScr->x = pScr->width; escflg = 0; SendMessage(pScr->hWnd, WM_PAINT, 0, 0); break; case 'D': /* cursor backward (left) (CUB) */ pScr->bWrapPending = FALSE; rc.left = pScr->x * pScr->cxChar; rc.right = (pScr->x + 1) * pScr->cxChar; rc.top = pScr->cyChar * pScr->y; rc.bottom = pScr->cyChar * (pScr->y + 1); InvalidateRect(pScr->hWnd, &rc, TRUE); if(pScr->parms[0] < 1) pScr->x--; else pScr->x -= pScr->parms[0]; ScreenRange(pScr); escflg = 0; SendMessage(pScr->hWnd, WM_PAINT, 0, 0); break; case 'f': /* horizontal & vertical position (HVP) */ case 'H': /* cursor position (CUP) */ pScr->bWrapPending = FALSE; rc.left = pScr->x * pScr->cxChar; rc.right = (pScr->x + 1) * pScr->cxChar; rc.top = pScr->cyChar * pScr->y; rc.bottom = pScr->cyChar * (pScr->y + 1); InvalidateRect(pScr->hWnd, &rc, TRUE); pScr->x = pScr->parms[1] - 1; pScr->y = pScr->parms[0] - 1; ScreenRange(pScr); /* make certain the cursor position is valid */ escflg = 0; SendMessage(pScr->hWnd, WM_PAINT, 0, 0); break; case 'J': /* erase in display (ED) */ switch(pScr->parms[0]) { case -1: case 0: /* erase from active position to end of screen */ ScreenEraseToEndOfScreen(pScr); break; case 1: /* erase from start of screen to active position */ #if 0 ScreenEraseToPosition(pScr); #endif break; case 2: /* erase whole screen */ ScreenEraseScreen(pScr); break; default: break; } escflg = 0; break; case 'K': /* erase in line (EL) */ switch(pScr->parms[0]) { case -1: case 0: /* erase to end of line */ ScreenEraseToEOL(pScr); break; case 1: /* erase to beginning of line */ ScreenEraseToBOL(pScr); break; case 2: /* erase whole line */ ScreenEraseLine(pScr, -1); break; default: break; } escflg = 0; break; case 'L': /* insert n lines preceding current line (IL) */ if (pScr->parms[0] < 1) pScr->parms[0] = 1; ScreenInsLines(pScr, pScr->parms[0], -1); escflg = 0; break; case 'M': /* delete n lines from current position downward (DL) */ if (pScr->parms[0] < 1) pScr->parms[0] = 1; ScreenDelLines(pScr, pScr->parms[0], -1); escflg = 0; break; case 'P': /* delete n chars from cursor to the left (DCH) */ if (pScr->parms[0] < 1) pScr->parms[0] = 1; ScreenDelChars(pScr, pScr->parms[0]); escflg = 0; break; #if 0 case 'R': /* receive cursor position status from host */ break; #endif #if 0 case 'c': /* device attributes (DA) */ ScreenSendIdent(); escflg = 0; break; #endif case 'g': /* tabulation clear (TBC) */ if (pScr->parms[0] == 3)/* clear all tabs */ ScreenTabClear(pScr); else if (pScr->parms[0] <= 0) /* clear tab stop at active position */ pScr->tabs[pScr->x] = ' '; escflg = 0; break; case 'h': /* set mode (SM) */ ScreenSetOption(pScr,1); escflg = 0; break; case 'i': /* toggle printer */ #if 0 if(pScr->parms[pScr->parmptr] == 5) pScr->localprint = 1; else if (pScr->parms[pScr->parmptr] == 4) pScr->localprint = 0; #endif escflg = 0; break; case 'l': /* reset mode (RM) */ ScreenSetOption(pScr,0); escflg = 0; break; case 'm': /* select graphics rendition (SGR) */ { int temp = 0; while (temp <= pScr->parmptr) { if (pScr->parms[temp] < 1) pScr->attrib &= 128; else pScr->attrib |= 1 << (pScr->parms[temp] - 1); temp++; } } escflg = 0; break; case 'n': /* device status report (DSR) */ switch (pScr->parms[0]) { #if 0 case 0: /* response from vt100; ready, no malfunctions */ case 3: /* response from vt100; malfunction, retry */ #endif case 5: /* send status */ case 6: /* send active position */ wsprintf(stat, "\033[%d;%dR", pScr->y + 1, pScr->x + 1); for (i = 0; stat[i]; i++) SendMessage(pScr->hwndTel, WM_MYSCREENCHAR, stat[i], (LPARAM) pScr); break; } /* end switch */ escflg = 0; break; case 'q': /* load LEDs (unsupported) (DECLL) */ escflg = 0; break; case 'r': /* set top & bottom margins (DECSTBM) */ if (pScr->parms[0] < 0) pScr->top = 0; else pScr->top = pScr->parms[0] - 1; if (pScr->parms[1] < 0) pScr->bottom = pScr->height - 1; else pScr->bottom = pScr->parms[1] - 1; if (pScr->top < 0) pScr->top = 0; if (pScr->top > pScr->height-1) pScr->top = pScr->height-1; if (pScr->bottom < 1) pScr->bottom = pScr->height; if (pScr->bottom >= pScr->height) pScr->bottom = pScr->height - 1; if (pScr->top >= pScr->bottom) {/* check for valid scrolling region */ if (pScr->bottom >= 1) /* * assume the bottom value has * precedence, unless it is as the * top of the screen */ pScr->top = pScr->bottom - 1; else /* totally psychotic case, bottom of screen set to the very top line, move the bottom to below the top */ pScr->bottom = pScr->top + 1; } pScr->x = 0; pScr->y = 0; #if 0 if (pScr->DECORG) pScr->y = pScr->top; /* origin mode relative */ #endif escflg = 0; break; #if 0 case 'x': /* request/report terminal parameters (DECREQTPARM/DECREPTPARM) */ case 'y': /* invoke confidence test (DECTST) */ break; #endif default: escflg = 0; break; } c++; len--; #if 0 if (pScr->localprint && (len > 0)) { /* see if printer needs anything */ pcount = send_localprint(c, len); len -= pcount; c += pcount; } #endif } while ((escflg == 3) && (len > 0)) { /* # Handling */ switch (*c) { case 0x08: /* backspace */ ScreenBackspace(pScr); break; #if 0 case '3': /* top half of double line (DECDHL) */ case '4': /* bottom half of double line (DECDHL) */ case '5': /* single width line (DECSWL) */ case '6': /* double width line (DECDWL) */ break; #endif case '8': /* screen alignment display (DECALN) */ ScreenAlign(pScr); escflg = 0; break; default: escflg = 0; break; } c++; len--; } while ((escflg == 4) && (len > 0)) { /* ( Handling (GO character set) */ switch (*c) { case 0x08: /* backspace */ ScreenBackspace(pScr); break; #if 0 case 'A': /* united kingdom character set (unsupported) */ case 'B': /* ASCII character set */ case '1': /* choose standard graphics (same as ASCII) */ pScr->G0 = 0; if (!pScr->charset) pScr->attrib = ScreenNotGraph(pScr->attrib); escflg = 0; break; case '0': /* choose special graphics set */ case '2': /* alternate character set (special graphics) */ pScr->G0 = 1; if(!pScr->charset) pScr->attrib = ScreenGraph(pScr->attrib); escflg = 0; break; #endif default: escflg = 0; break; } c++; len--; } /* end while */ while((escflg == 5) && (len > 0)) { /* ) Handling (G1 handling) */ switch (*c) { case 0x08: /* backspace */ ScreenBackspace(pScr); break; #if 0 case 'A': /* united kingdom character set (unsupported) */ case 'B': /* ASCII character set */ case '1': /* choose standard graphics (same as ASCII) */ pScr->G1 = 0; if (pScr->charset) pScr->attrib = ScreenNotGraph(pScr->attrib); escflg = 0; break; case '0': /* choose special graphics set */ case '2': /* alternate character set (special graphics) */ pScr->G1 = 1; if(pScr->charset) pScr->attrib = ScreenGraph(pScr->attrib); escflg = 0; break; #endif default: escflg = 0; break; } /* end switch */ c++; len--; } /* end while */ while ((escflg >= 6) && (escflg <= 10) && (len > 0)) { /* Handling IAC */ ic = (unsigned char) *c; switch (escflg) { case 6: /* Handling IAC xx */ if (ic == 255) /* if IAC */ escflg = 0; else if (ic == 250) /* if SB */ escflg = 7; else escflg = 9; break; case 7: /* Handling IAC SB xx */ if (ic == 255) /* if IAC */ escflg = 8; break; case 8: /* Handling IAC SB IAC xx */ if (ic == 255) /* if IAC IAC */ escflg = 7; else if (ic == 240) /* if IAC SE */ escflg = 0; break; case 9: /* IAC xx xx */ escflg = 0; break; } c++; /* advance to the next character in the string */ len--; /* decrement the counter */ } if (escflg > 2 && escflg < 6 && len > 0) { escflg = 0; c++; len--; } } pScr->escflg = escflg; ScreenCursorOn(pScr); } krb5-1.16/src/windows/wintel/ktelnet.hpj0000644000704600001450000000651513211554426020141 0ustar ghudsonlibuuid;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ; Help Project File for KTELNET ; ; This file is maintained by RoboHELP. Do not modify this file directly. ;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * [OPTIONS] ;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ; The Options section contains the following information: ; ; The optional BMROOT= entry sets the directories in which the Help Compiler ; will look for graphics. ; ; The CONTENTS= tells WinHelp which topic contains the contents. ; ; The TITLE= is displayed in the Title Bar of WINHELP.EXE ; ; The BUILD= setting allows you to create different Help systems from ; the same source file. ; ; The COMPRESS= option tells the Help Compiler how much to compress ; the Help file. ;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ;BMROOT=C:\WINDOWS\DESKTOP\KERBEROS 5\WIN95 GUI\CNS HELP TITLE=Kerb*Net Telnet for Windows BUILD=WINDOWS NOTES=1 OLDKEYPHRASE=NO OPTCDROM=0 REPORT=YES COMPRESS=12 ERRORLOG=C:\windows\desktop\kerberos 5\win95 gui\cns help\KTELNET.ERR [BUILDTAGS] ;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ; The Build Tags section specifies to the Help Compiler the names ; of all the valid build tags used in this Help project. ;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * WINDOWS [CONFIG] ;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ; The Config section defines macros which will run at startup. ;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * [FILES] ;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ; The Files section specifies the RTF files for a project. ;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * KTELNET.RTF [ALIAS] ;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ; The Alias section sets up aliases for Topic IDs in your Help system. ;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * [MAP] ;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ; The Map section specifies the project HH files. ;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * [BITMAPS] ;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ; The Bitmaps section specifies the referenced bitmaps used in ; your help system. ;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * [WINDOWS] ;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ; The Windows section contains all of the information about the windows ; in a Help project. ;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ;Gloss = "Glossary",(100,100,350,350),0,(255,255,255),(255,255,255) main=,,29188,, (w95sec)=,,20740,(r14745599),(r14745599),f2 [BAGGAGE] ;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ; The Baggage section specifies any additional files. ;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * krb5-1.16/src/windows/wintel/genget.c0000644000704600001450000000615013211554426017400 0ustar ghudsonlibuuid/*- * Copyright (c) 1991, 1993 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ /* based on @(#)genget.c 8.1 (Berkeley) 6/4/93 */ #include #define LOWER(x) (isupper(x) ? tolower(x) : (x)) /* * The prefix function returns 0 if *s1 is not a prefix * of *s2. If *s1 exactly matches *s2, the negative of * the length is returned. If *s1 is a prefix of *s2, * the length of *s1 is returned. */ int isprefix(s1, s2) register char *s1, *s2; { char *os1; register char c1, c2; if (*s1 == '\0') return(-1); os1 = s1; c1 = *s1; c2 = *s2; while (LOWER(c1) == LOWER(c2)) { if (c1 == '\0') break; c1 = *++s1; c2 = *++s2; } return(*s1 ? 0 : (*s2 ? (s1 - os1) : (os1 - s1))); } static char *ambiguous; /* special return value for command routines */ char ** genget(name, table, stlen) char *name; /* name to match */ char **table; /* name entry in table */ int stlen; { register char **c, **found; register int n; if (name == 0) return 0; found = 0; for (c = table; *c != 0; c = (char **)((char *)c + stlen)) { if ((n = isprefix(name, *c)) == 0) continue; if (n < 0) /* exact match */ return(c); if (found) return(&ambiguous); found = c; } return(found); } /* * Function call version of Ambiguous() */ int Ambiguous(s) char *s; { return((char **)s == &ambiguous); } krb5-1.16/src/windows/installer/0000755000704600001450000000000013211554426016454 5ustar ghudsonlibuuidkrb5-1.16/src/windows/installer/nsis/0000755000704600001450000000000013211554426017430 5ustar ghudsonlibuuidkrb5-1.16/src/windows/installer/nsis/licenses.rtf0000644000704600001450000002225413211554426021757 0ustar ghudsonlibuuid{\rtf1\ansi\ansicpg1252\deff0\deflang1033\deflangfe1033{\fonttbl{\f0\fmodern\fprq1\fcharset0 Courier New;}{\f1\froman\fprq2\fcharset0 Times New Roman;}} {\*\generator Msftedit 5.41.15.1503;}\viewkind4\uc1\pard\tx916\tx1832\tx2748\tx3664\tx4580\tx5496\tx6412\tx7328\tx8244\tx9160\tx10076\tx10992\tx11908\tx12824\tx13740\tx14656\f0\fs20 Copyright Notice and Legal Administrivia\par ----------------------------------------\par \par Copyright (C) 1985-2006 by the Massachusetts Institute of Technology.\par \par All rights reserved.\par \par Export of this software from the United States of America may require a specific license from the United States Government. It is the responsibility of any person or organization contemplating export to obtain such a license before exporting.\par \par WITHIN THAT CONSTRAINT, permission to use, copy, modify, and distribute this software and its documentation for any purpose and without fee is hereby granted, provided that the above copyright notice appear in all copies and that both that copyright notice and\par this permission notice appear in supporting documentation, and that the name of M.I.T. not be used in advertising or publicity pertaining to distribution of the software without specific, written prior permission. Furthermore if you modify this software you must label your software as modified software and not distribute it in such a fashion that it might be confused with the original MIT software. M.I.T. makes no representations about the suitability of this software for any purpose. It is provided "as is" without express or implied warranty.\par \par THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.\par \par Individual source code files are copyright MIT, Cygnus Support, OpenVision, Oracle, Sun Soft, FundsXpress, and others.\par \par Project Athena, Athena, Athena MUSE, Discuss, Hesiod, Kerberos, Moira, and Zephyr are trademarks of the Massachusetts Institute of Technology (MIT). No commercial use of these trademarks may be made without prior written permission of MIT.\par \par "Commercial use" means use of a name in a product or other for-profit manner. It does NOT prevent a commercial firm from referring to the MIT trademarks in order to convey information (although in doing so, recognition of their trademark status should be given).\par \par ----\par \par The following copyright and permission notice applies to the OpenVision Kerberos Administration system located in kadmin/create, kadmin/dbutil, kadmin/passwd, kadmin/server, lib/kadm5, and portions of lib/rpc:\par \par Copyright, OpenVision Technologies, Inc., 1996, All Rights Reserved\par \par WARNING: Retrieving the OpenVision Kerberos Administration system source code, as described below, indicates your acceptance of the following terms. If you do not agree to the following terms, do not retrieve the OpenVision Kerberos administration system.\par \par You may freely use and distribute the Source Code and Object Code compiled from it, with or without modification, but this Source Code is provided to you "AS IS" EXCLUSIVE OF ANY WARRANTY, INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, OR ANY OTHER WARRANTY, WHETHER EXPRESS OR IMPLIED. IN NO EVENT WILL OPENVISION HAVE ANY LIABILITY FOR ANY LOST PROFITS, LOSS OF DATA OR COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY SPECIAL, INDIRECT, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, INCLUDING, WITHOUT LIMITATION, THOSE RESULTING FROM THE USE OF THE SOURCE CODE, OR THE FAILURE OF THE SOURCE CODE TO PERFORM, OR FOR ANY OTHER REASON.\par \par OpenVision retains all copyrights in the donated Source Code. OpenVision also retains copyright to derivative works of the Source Code, whether created by OpenVision or by a third party. The OpenVision copyright notice must be preserved if derivative works are made based on the donated Source Code.\par \par OpenVision Technologies, Inc. has donated this Kerberos Administration system to MIT for inclusion in the standard Kerberos 5 distribution. This donation underscores our commitment to continuing Kerberos technology development and our gratitude for the valuable work which has been performed by MIT and the Kerberos community.\par \par ----\par \par Portions contributed by Matt Crawford were work performed at Fermi National Accelerator Laboratory, which is operated by Universities Research Association, Inc., under contract DE-AC02-76CHO3000 with the U.S. Department of Energy.\par \par ---- The implementation of the Yarrow pseudo-random number generator in src/lib/crypto/yarrow has the following copyright:\par \par Copyright 2000 by Zero-Knowledge Systems, Inc.\par \par 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 Zero-Knowledge Systems, Inc. not be used in advertising or publicity pertaining to distribution of the software without specific, written prior permission. Zero-Knowledge Systems, Inc. makes no representations about the suitability of this software for any purpose. It is provided "as is" without express or implied warranty.\par \par ZERO-KNOWLEDGE SYSTEMS, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL ZERO-KNOWLEDGE SYSTEMS, INC. BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN\par ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTUOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.\par \par ---- The implementation of the AES encryption algorithm in src/lib/crypto/aes has the following copyright:\par \par Copyright (c) 2001, Dr Brian Gladman , Worcester, UK.\par All rights reserved.\par \par LICENSE TERMS\par \par The free distribution and use of this software in both source and binary form is allowed (with or without changes) provided that:\par \par 1. distributions of this source code include the above copyright notice, this list of conditions and the following disclaimer;\par \par 2. distributions in binary form include the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other associated materials;\par \par 3. the copyright holder's name is not used to endorse products built using this software without specific written permission. \par \par DISCLAIMER\par \par This software is provided 'as is' with no explcit or implied warranties in respect of any properties, including, but not limited to, correctness and fitness for purpose.\par \par \par \par Acknowledgements\par ----------------\par \par Appreciation Time!!!! There are far too many people to try to thank them all; many people have contributed to the development of Kerberos V5. This is only a partial listing....\par \par Thanks to Paul Vixie and the Internet Software Consortium for funding the work of Barry Jaspan. This funding was invaluable for the OV administration server integration, as well as the 1.0 release preparation process.\par \par Thanks to John Linn, Scott Foote, and all of the folks at OpenVision Technologies, Inc., who donated their administration server for use in the MIT release of Kerberos.\par \par Thanks to Jeff Bigler, Mark Eichin, Marc Horowitz, Nancy Gilman, Ken Raeburn, and all of the folks at Cygnus Support, who provided innumerable bug fixes and portability enhancements to the Kerberos V5 tree. Thanks especially to Jeff Bigler, for the new user and system administrator's documentation.\par \par Thanks to Doug Engert from ANL for providing many bug fixes, as well as testing to ensure DCE interoperability.\par \par Thanks to Ken Hornstein at NRL for providing many bug fixes and suggestions, and for working on SAM preauthentication.\par \par Thanks to Matt Crawford at FNAL for bugfixes and enhancements.\par \par Thanks to Sean Mullan and Bill Sommerfeld from Hewlett Packard for their many suggestions and bug fixes.\par \par Thanks to Nalin Dahyabhai of RedHat and Chris Evans for locating and providing patches for numerous buffer overruns.\par \par Thanks to Christopher Thompson and Marcus Watts for discovering the ftpd security bug.\par \par Thanks to Paul Nelson of Thursby Software Systems for implementing the Microsoft set password protocol.\par \par Thanks to the members of the Kerberos V5 development team at MIT, both past and present: Danilo Almeida, Jeffrey Altman, Jay Berkenbilt, Richard Basch, Mitch Berger, John Carr, Don Davis, Alexandra Ellwood, Nancy Gilman, Matt Hancher, Sam Hartman, Paul Hill, Marc Horowitz, Eva Jacobus, Miroslav Jurisic, Barry Jaspan, Geoffrey King, John Kohl, Peter Litwack, Scott McGuire, Kevin Mitchell, Cliff Neuman, Paul Park, Ezra Peisach, Chris Provenzano, Ken Raeburn, Jon Rochlis, Jeff Schiller, Jen Selby, Brad Thompson, Harry Tsai, Ted Ts'o, Marshall Vale, Tom Yu.\par \pard\f1\fs24\par } krb5-1.16/src/windows/installer/nsis/kfw-fixed.nsi0000644000704600001450000022047313211554426022037 0ustar ghudsonlibuuid;----------------------------------------------------------------- ; KfW defines and functionality ; Copyright (c) 2004,2005,2006,2007 Massachusetts Institute of Technology ; Copyright (c) 2006,2007 Secure Endpoints Inc. !define KFW_VERSION "${KFW_MAJORVERSION}.${KFW_MINORVERSION}.${KFW_PATCHLEVEL}" !define PROGRAM_NAME "Kerberos for Windows" !ifdef RELEASE !ifndef DEBUG ; !DEBUG on v2.0b4 Name "MIT ${PROGRAM_NAME} ${KFW_VERSION}" !else ; DEBUG on v2.0b4 Name "MIT ${PROGRAM_NAME} ${KFW_VERSION} Checked/Debug" !endif ; End DEBUG/!DEBUG !else !ifdef BETA !ifndef DEBUG ; !DEBUG on v2.0b4 Name "MIT ${PROGRAM_NAME} ${KFW_VERSION} Beta ${BETA}" !else ; DEBUG on v2.0b4 Name "MIT ${PROGRAM_NAME} ${KFW_VERSION} Beta ${BETA} Checked/Debug" !endif ; End DEBUG/!DEBUG !else !ifndef DEBUG ; !DEBUG on v2.0b4 Name "MIT ${PROGRAM_NAME} ${KFW_VERSION} ${__DATE__} ${__TIME__}" !else ; DEBUG on v2.0b4 Name "MIT ${PROGRAM_NAME} ${KFW_VERSION} ${__DATE__} ${__TIME__} Checked/Debug" !endif ; End DEBUG/!DEBUG !endif !endif VIProductVersion "${KFW_MAJORVERSION}.${KFW_MINORVERSION}.${KFW_PATCHLEVEL}.00" VIAddVersionKey "ProductName" "${PROGRAM_NAME}" VIAddVersionKey "CompanyName" "Massachusetts Institute of Technology" VIAddVersionKey "FileVersion" ${VIProductVersion} VIAddVersionKey "ProductVersion" "${KFW_MAJORVERSION}.${KFW_MINORVERSION}.${KFW_PATCHLEVEL}.0" VIAddVersionKey "FileDescription" "MIT Kerberos for Windows Installer" VIAddVersionKey "LegalCopyright" "(C)2004,2005,2006,2007" !ifdef DEBUG VIAddVersionKey "PrivateBuild" "Checked/Debug" !endif ; End DEBUG ;-------------------------------- ;Configuration ;General SetCompressor lzma !ifndef DEBUG OutFile "MITKerberosForWindows.exe" !else OutFile "MITKerberosForWindows-DEBUG.exe" !endif SilentInstall normal ShowInstDetails show XPStyle on !define MUI_ICON "kfw.ico" !define MUI_UNICON "kfw.ico" !define KFW_COMPANY_NAME "Massachusetts Institute of Technology" !define KFW_PRODUCT_NAME "${PROGRAM_NAME}" !define KFW_REGKEY_ROOT "Software\MIT\Kerberos\" !define NIM_REGKEY_ROOT "Software\MIT\NetIDMgr\" CRCCheck force !define REPLACEDLL_NOREGISTER ;Folder selection page InstallDir "$PROGRAMFILES\MIT\Kerberos" ; Install to shorter path ;Remember install folder InstallDirRegKey HKLM "${KFW_REGKEY_ROOT}" "" ;Remember the installer language !define MUI_LANGDLL_REGISTRY_ROOT "HKLM" !define MUI_LANGDLL_REGISTRY_KEY "${KFW_REGKEY_ROOT}" !define MUI_LANGDLL_REGISTRY_VALUENAME "Installer Language" ;Where are the files? !define KFW_BIN_DIR "${KFW_TARGETDIR}\bin\i386" !define KFW_DOC_DIR "${KFW_TARGETDIR}\doc" !define KFW_INC_DIR "${KFW_TARGETDIR}\inc" !define KFW_LIB_DIR "${KFW_TARGETDIR}\lib\i386" !define KFW_SAMPLE_DIR "${KFW_TARGETDIR}\sample" !define KFW_INSTALL_DIR "${KFW_TARGETDIR}\install" !define SYSTEMDIR "$%SystemRoot%\System32" ;-------------------------------- ;Modern UI Configuration !define MUI_LICENSEPAGE !define MUI_CUSTOMPAGECOMMANDS !define MUI_WELCOMEPAGE !define MUI_COMPONENTSPAGE !define MUI_COMPONENTSPAGE_SMALLDESC !define MUI_DIRECTORYPAGE !define MUI_ABORTWARNING !define MUI_FINISHPAGE !define MUI_UNINSTALLER !define MUI_UNCONFIRMPAGE !insertmacro MUI_PAGE_WELCOME !insertmacro MUI_PAGE_LICENSE "Licenses.rtf" !insertmacro MUI_PAGE_COMPONENTS !insertmacro MUI_PAGE_DIRECTORY Page custom KFWPageGetConfigFiles Page custom KFWPageGetStartupConfig !insertmacro MUI_PAGE_INSTFILES !insertmacro MUI_PAGE_FINISH ;-------------------------------- ;Languages !insertmacro MUI_LANGUAGE "English" ;-------------------------------- ;Language Strings ;Descriptions LangString DESC_SecCopyUI ${LANG_ENGLISH} "${PROGRAM_NAME}: English" LangString DESC_secClient ${LANG_ENGLISH} "Client: Allows you to utilize MIT Kerberos from your Windows PC." LangString DESC_secDebug ${LANG_ENGLISH} "Debug Symbols: Used for debugging problems with MIT Kerberos for Windows" LangString DESC_secSDK ${LANG_ENGLISH} "SDK: Allows you to build MIT Kerberos aware applications." LangString DESC_secDocs ${LANG_ENGLISH} "Documentation: Release Notes and User Manuals." ; Popup error messages LangString RealmNameError ${LANG_ENGLISH} "You must specify a realm name for your client to use." LangString ConfigFileError ${LANG_ENGLISH} "You must specify a valid configuration file location from which files can be copied during the install" LangString URLError ${LANG_ENGLISH} "You must specify a URL if you choose the option to download the config files." ; Upgrade/re-install strings LangString UPGRADE_CLIENT ${LANG_ENGLISH} "Upgrade Kerberos Client" LangString REINSTALL_CLIENT ${LANG_ENGLISH} "Re-install Kerberos Client" LangString DOWNGRADE_CLIENT ${LANG_ENGLISH} "Downgrade Kerberos Client" LangString UPGRADE_SDK ${LANG_ENGLISH} "Upgrade Kerberos SDK" LangString REINSTALL_SDK ${LANG_ENGLISH} "Re-install Kerberos SDK" LangString DOWNGRADE_SDK ${LANG_ENGLISH} "Downgrade Kerberos SDK" LangString UPGRADE_DOCS ${LANG_ENGLISH} "Upgrade Kerberos Documentation" LangString REINSTALL_DOCS ${LANG_ENGLISH} "Re-install Kerberos Documentation" LangString DOWNGRADE_DOCS ${LANG_ENGLISH} "Downgrade Kerberos Documentation" ReserveFile "${KFW_CONFIG_DIR}\sample\krb.con" ReserveFile "${KFW_CONFIG_DIR}\sample\krbrealm.con" ReserveFile "${KFW_CONFIG_DIR}\sample\krb5.ini" !insertmacro MUI_RESERVEFILE_INSTALLOPTIONS ;InstallOptions plug-in !insertmacro MUI_RESERVEFILE_LANGDLL ;Language selection dialog ;-------------------------------- ;Reserve Files ;Things that need to be extracted on first (keep these lines before any File command!) ;Only useful for BZIP2 compression !insertmacro MUI_RESERVEFILE_LANGDLL ;-------------------------------- ; Load Macros !include "utils.nsi" ;-------------------------------- ;Installer Sections ;---------------------- ; Kerberos for Windows CLIENT Section "KfW Client" secClient SetShellVarContext all ; Stop any running services or we can't replace the files ; Stop the running processes GetTempFileName $R0 File /oname=$R0 "Killer.exe" nsExec::Exec '$R0 netidmgr.exe' nsExec::Exec '$R0 leash32.exe' nsExec::Exec '$R0 krbcc32s.exe' nsExec::Exec '$R0 k95.exe' nsExec::Exec '$R0 k95g.exe' nsExec::Exec '$R0 krb5.exe' nsExec::Exec '$R0 gss.exe' nsExec::Exec '$R0 afscreds.exe' RMDir /r "$INSTDIR\bin" ; Do client components SetOutPath "$INSTDIR\bin" !insertmacro ReplaceDLL "${KFW_BIN_DIR}\comerr32.dll" "$INSTDIR\bin\comerr32.dll" "$INSTDIR" !insertmacro ReplaceDLL "${KFW_BIN_DIR}\gss.exe" "$INSTDIR\bin\gss.exe" "$INSTDIR" !insertmacro ReplaceDLL "${KFW_BIN_DIR}\gss-client.exe" "$INSTDIR\bin\gss-client.exe" "$INSTDIR" !insertmacro ReplaceDLL "${KFW_BIN_DIR}\gss-server.exe" "$INSTDIR\bin\gss-server.exe" "$INSTDIR" !insertmacro ReplaceDLL "${KFW_BIN_DIR}\gssapi32.dll" "$INSTDIR\bin\gssapi32.dll" "$INSTDIR" !insertmacro ReplaceDLL "${KFW_BIN_DIR}\k524init.exe" "$INSTDIR\bin\k524init.exe" "$INSTDIR" !insertmacro ReplaceDLL "${KFW_BIN_DIR}\kclnt32.dll" "$INSTDIR\bin\kclnt32.dll" "$INSTDIR" !insertmacro ReplaceDLL "${KFW_BIN_DIR}\kdestroy.exe" "$INSTDIR\bin\kdestroy.exe" "$INSTDIR" !insertmacro ReplaceDLL "${KFW_BIN_DIR}\kinit.exe" "$INSTDIR\bin\kinit.exe" "$INSTDIR" !insertmacro ReplaceDLL "${KFW_BIN_DIR}\klist.exe" "$INSTDIR\bin\klist.exe" "$INSTDIR" !insertmacro ReplaceDLL "${KFW_BIN_DIR}\kpasswd.exe" "$INSTDIR\bin\kpasswd.exe" "$INSTDIR" !insertmacro ReplaceDLL "${KFW_BIN_DIR}\kvno.exe" "$INSTDIR\bin\kvno.exe" "$INSTDIR" !insertmacro ReplaceDLL "${KFW_BIN_DIR}\krb5_32.dll" "$INSTDIR\bin\krb5_32.dll" "$INSTDIR" !insertmacro ReplaceDLL "${KFW_BIN_DIR}\k5sprt32.dll" "$INSTDIR\bin\k5sprt32.dll" "$INSTDIR" !insertmacro ReplaceDLL "${KFW_BIN_DIR}\krb524.dll" "$INSTDIR\bin\krb524.dll" "$INSTDIR" !insertmacro ReplaceDLL "${KFW_BIN_DIR}\krbcc32.dll" "$INSTDIR\bin\krbcc32.dll" "$INSTDIR" !insertmacro ReplaceDLL "${KFW_BIN_DIR}\krbcc32s.exe" "$INSTDIR\bin\krbcc32s.exe" "$INSTDIR" !insertmacro ReplaceDLL "${KFW_BIN_DIR}\krbv4w32.dll" "$INSTDIR\bin\krbv4w32.dll" "$INSTDIR" !insertmacro ReplaceDLL "${KFW_BIN_DIR}\netidmgr.chm" "$INSTDIR\bin\netidmgr.chm" "$INSTDIR" !insertmacro ReplaceDLL "${KFW_BIN_DIR}\krb4cred.dll" "$INSTDIR\bin\krb4cred.dll" "$INSTDIR" !insertmacro ReplaceDLL "${KFW_BIN_DIR}\krb5cred.dll" "$INSTDIR\bin\krb5cred.dll" "$INSTDIR" !insertmacro ReplaceDLL "${KFW_BIN_DIR}\krb4cred_en_us.dll" "$INSTDIR\bin\krb4cred_en_us.dll" "$INSTDIR" !insertmacro ReplaceDLL "${KFW_BIN_DIR}\krb5cred_en_us.dll" "$INSTDIR\bin\krb5cred_en_us.dll" "$INSTDIR" !insertmacro ReplaceDLL "${KFW_BIN_DIR}\leashw32.dll" "$INSTDIR\bin\leashw32.dll" "$INSTDIR" !insertmacro ReplaceDLL "${KFW_BIN_DIR}\ms2mit.exe" "$INSTDIR\bin\ms2mit.exe" "$INSTDIR" !insertmacro ReplaceDLL "${KFW_BIN_DIR}\mit2ms.exe" "$INSTDIR\bin\mit2ms.exe" "$INSTDIR" !insertmacro ReplaceDLL "${KFW_BIN_DIR}\kcpytkt.exe" "$INSTDIR\bin\kcpytkt.exe" "$INSTDIR" !insertmacro ReplaceDLL "${KFW_BIN_DIR}\kdeltkt.exe" "$INSTDIR\bin\kdeltkt.exe" "$INSTDIR" !insertmacro ReplaceDLL "${KFW_BIN_DIR}\wshelp32.dll" "$INSTDIR\bin\wshelp32.dll" "$INSTDIR" !insertmacro ReplaceDLL "${KFW_BIN_DIR}\xpprof32.dll" "$INSTDIR\bin\xpprof32.dll" "$INSTDIR" Call GetWindowsVersion Pop $R0 StrCmp $R0 "2000" nid_inst2000 !insertmacro ReplaceDLL "${KFW_BIN_DIR}\netidmgr.exe" "$INSTDIR\bin\netidmgr.exe" "$INSTDIR" !insertmacro ReplaceDLL "${KFW_BIN_DIR}\nidmgr32.dll" "$INSTDIR\bin\nidmgr32.dll" "$INSTDIR" goto nid_done nid_inst2000: !insertmacro ReplaceDLL "${KFW_BIN_DIR}\W2K\netidmgr.exe" "$INSTDIR\bin\netidmgr.exe" "$INSTDIR" !insertmacro ReplaceDLL "${KFW_BIN_DIR}\W2K\nidmgr32.dll" "$INSTDIR\bin\nidmgr32.dll" "$INSTDIR" nid_done: !ifdef DEBUG !IFDEF CL_1400 !insertmacro ReplaceDLL "${SYSTEMDIR}\msvcr80d.dll" "$INSTDIR\bin\msvcr80d.dll" "$INSTDIR" !insertmacro ReplaceDLL "${SYSTEMDIR}\msvcp80d.dll" "$INSTDIR\bin\msvcp80d.dll" "$INSTDIR" !insertmacro ReplaceDLL "${SYSTEMDIR}\mfc80d.dll" "$INSTDIR\bin\mfc80d.dll" "$INSTDIR" !insertmacro ReplaceDLL "${SYSTEMDIR}\MFC80CHS.DLL" "$INSTDIR\bin\MFC80CHS.DLL" "$INSTDIR" !insertmacro ReplaceDLL "${SYSTEMDIR}\MFC80CHT.DLL" "$INSTDIR\bin\MFC80CHT.DLL" "$INSTDIR" !insertmacro ReplaceDLL "${SYSTEMDIR}\MFC80DEU.DLL" "$INSTDIR\bin\MFC80DEU.DLL" "$INSTDIR" !insertmacro ReplaceDLL "${SYSTEMDIR}\MFC80ENU.DLL" "$INSTDIR\bin\MFC80ENU.DLL" "$INSTDIR" !insertmacro ReplaceDLL "${SYSTEMDIR}\MFC80ESP.DLL" "$INSTDIR\bin\MFC80ESP.DLL" "$INSTDIR" !insertmacro ReplaceDLL "${SYSTEMDIR}\MFC80FRA.DLL" "$INSTDIR\bin\MFC80FRA.DLL" "$INSTDIR" !insertmacro ReplaceDLL "${SYSTEMDIR}\MFC80ITA.DLL" "$INSTDIR\bin\MFC80ITA.DLL" "$INSTDIR" !insertmacro ReplaceDLL "${SYSTEMDIR}\MFC80JPN.DLL" "$INSTDIR\bin\MFC80JPN.DLL" "$INSTDIR" !insertmacro ReplaceDLL "${SYSTEMDIR}\MFC80KOR.DLL" "$INSTDIR\bin\MFC80KOR.DLL" "$INSTDIR" !ELSE !IFDEF CL_1310 !insertmacro ReplaceDLL "${SYSTEMDIR}\msvcr71d.dll" "$INSTDIR\bin\msvcr71d.dll" "$INSTDIR" !insertmacro ReplaceDLL "${SYSTEMDIR}\msvcp71d.dll" "$INSTDIR\bin\msvcp71d.dll" "$INSTDIR" !insertmacro ReplaceDLL "${SYSTEMDIR}\mfc71d.dll" "$INSTDIR\bin\mfc71d.dll" "$INSTDIR" !insertmacro ReplaceDLL "${SYSTEMDIR}\MFC71CHS.DLL" "$INSTDIR\bin\MFC71CHS.DLL" "$INSTDIR" !insertmacro ReplaceDLL "${SYSTEMDIR}\MFC71CHT.DLL" "$INSTDIR\bin\MFC71CHT.DLL" "$INSTDIR" !insertmacro ReplaceDLL "${SYSTEMDIR}\MFC71DEU.DLL" "$INSTDIR\bin\MFC71DEU.DLL" "$INSTDIR" !insertmacro ReplaceDLL "${SYSTEMDIR}\MFC71ENU.DLL" "$INSTDIR\bin\MFC71ENU.DLL" "$INSTDIR" !insertmacro ReplaceDLL "${SYSTEMDIR}\MFC71ESP.DLL" "$INSTDIR\bin\MFC71ESP.DLL" "$INSTDIR" !insertmacro ReplaceDLL "${SYSTEMDIR}\MFC71FRA.DLL" "$INSTDIR\bin\MFC71FRA.DLL" "$INSTDIR" !insertmacro ReplaceDLL "${SYSTEMDIR}\MFC71ITA.DLL" "$INSTDIR\bin\MFC71ITA.DLL" "$INSTDIR" !insertmacro ReplaceDLL "${SYSTEMDIR}\MFC71JPN.DLL" "$INSTDIR\bin\MFC71JPN.DLL" "$INSTDIR" !insertmacro ReplaceDLL "${SYSTEMDIR}\MFC71KOR.DLL" "$INSTDIR\bin\MFC71KOR.DLL" "$INSTDIR" !ELSE !IFDEF CL_1300 !insertmacro ReplaceDLL "${SYSTEMDIR}\msvcr70d.dll" "$INSTDIR\bin\msvcr70d.dll" "$INSTDIR" !insertmacro ReplaceDLL "${SYSTEMDIR}\msvcp70d.dll" "$INSTDIR\bin\msvcp70d.dll" "$INSTDIR" !insertmacro ReplaceDLL "${SYSTEMDIR}\mfc70d.dll" "$INSTDIR\bin\mfc70d.dll" "$INSTDIR" !insertmacro ReplaceDLL "${SYSTEMDIR}\MFC70CHS.DLL" "$INSTDIR\bin\MFC70CHS.DLL" "$INSTDIR" !insertmacro ReplaceDLL "${SYSTEMDIR}\MFC70CHT.DLL" "$INSTDIR\bin\MFC70CHT.DLL" "$INSTDIR" !insertmacro ReplaceDLL "${SYSTEMDIR}\MFC70DEU.DLL" "$INSTDIR\bin\MFC70DEU.DLL" "$INSTDIR" !insertmacro ReplaceDLL "${SYSTEMDIR}\MFC70ENU.DLL" "$INSTDIR\bin\MFC70ENU.DLL" "$INSTDIR" !insertmacro ReplaceDLL "${SYSTEMDIR}\MFC70ESP.DLL" "$INSTDIR\bin\MFC70ESP.DLL" "$INSTDIR" !insertmacro ReplaceDLL "${SYSTEMDIR}\MFC70FRA.DLL" "$INSTDIR\bin\MFC70FRA.DLL" "$INSTDIR" !insertmacro ReplaceDLL "${SYSTEMDIR}\MFC70ITA.DLL" "$INSTDIR\bin\MFC70ITA.DLL" "$INSTDIR" !insertmacro ReplaceDLL "${SYSTEMDIR}\MFC70JPN.DLL" "$INSTDIR\bin\MFC70JPN.DLL" "$INSTDIR" !insertmacro ReplaceDLL "${SYSTEMDIR}\MFC70KOR.DLL" "$INSTDIR\bin\MFC70KOR.DLL" "$INSTDIR" !ELSE !insertmacro ReplaceDLL "${SYSTEMDIR}\mfc42d.dll" "$INSTDIR\bin\mfc42d.dll" "$INSTDIR" !insertmacro ReplaceDLL "${SYSTEMDIR}\msvcp60d.dll" "$INSTDIR\bin\msvcp60d.dll" "$INSTDIR" !insertmacro ReplaceDLL "${SYSTEMDIR}\msvcrtd.dll" "$INSTDIR\bin\msvcrtd.dll" "$INSTDIR" !ENDIF !ENDIF !ENDIF !ELSE !IFDEF CL_1400 !insertmacro ReplaceDLL "${SYSTEMDIR}\mfc80.dll" "$INSTDIR\bin\mfc80.dll" "$INSTDIR" !insertmacro ReplaceDLL "${SYSTEMDIR}\msvcr80.dll" "$INSTDIR\bin\msvcr80.dll" "$INSTDIR" !insertmacro ReplaceDLL "${SYSTEMDIR}\msvcp80.dll" "$INSTDIR\bin\msvcp80.dll" "$INSTDIR" !insertmacro ReplaceDLL "${SYSTEMDIR}\MFC80CHS.DLL" "$INSTDIR\bin\MFC80CHS.DLL" "$INSTDIR" !insertmacro ReplaceDLL "${SYSTEMDIR}\MFC80CHT.DLL" "$INSTDIR\bin\MFC80CHT.DLL" "$INSTDIR" !insertmacro ReplaceDLL "${SYSTEMDIR}\MFC80DEU.DLL" "$INSTDIR\bin\MFC80DEU.DLL" "$INSTDIR" !insertmacro ReplaceDLL "${SYSTEMDIR}\MFC80ENU.DLL" "$INSTDIR\bin\MFC80ENU.DLL" "$INSTDIR" !insertmacro ReplaceDLL "${SYSTEMDIR}\MFC80ESP.DLL" "$INSTDIR\bin\MFC80ESP.DLL" "$INSTDIR" !insertmacro ReplaceDLL "${SYSTEMDIR}\MFC80FRA.DLL" "$INSTDIR\bin\MFC80FRA.DLL" "$INSTDIR" !insertmacro ReplaceDLL "${SYSTEMDIR}\MFC80ITA.DLL" "$INSTDIR\bin\MFC80ITA.DLL" "$INSTDIR" !insertmacro ReplaceDLL "${SYSTEMDIR}\MFC80JPN.DLL" "$INSTDIR\bin\MFC80JPN.DLL" "$INSTDIR" !insertmacro ReplaceDLL "${SYSTEMDIR}\MFC80KOR.DLL" "$INSTDIR\bin\MFC80KOR.DLL" "$INSTDIR" !ELSE !IFDEF CL_1310 !insertmacro ReplaceDLL "${SYSTEMDIR}\mfc71.dll" "$INSTDIR\bin\mfc71.dll" "$INSTDIR" !insertmacro ReplaceDLL "${SYSTEMDIR}\msvcr71.dll" "$INSTDIR\bin\msvcr71.dll" "$INSTDIR" !insertmacro ReplaceDLL "${SYSTEMDIR}\msvcp71.dll" "$INSTDIR\bin\msvcp71.dll" "$INSTDIR" !insertmacro ReplaceDLL "${SYSTEMDIR}\MFC71CHS.DLL" "$INSTDIR\bin\MFC71CHS.DLL" "$INSTDIR" !insertmacro ReplaceDLL "${SYSTEMDIR}\MFC71CHT.DLL" "$INSTDIR\bin\MFC71CHT.DLL" "$INSTDIR" !insertmacro ReplaceDLL "${SYSTEMDIR}\MFC71DEU.DLL" "$INSTDIR\bin\MFC71DEU.DLL" "$INSTDIR" !insertmacro ReplaceDLL "${SYSTEMDIR}\MFC71ENU.DLL" "$INSTDIR\bin\MFC71ENU.DLL" "$INSTDIR" !insertmacro ReplaceDLL "${SYSTEMDIR}\MFC71ESP.DLL" "$INSTDIR\bin\MFC71ESP.DLL" "$INSTDIR" !insertmacro ReplaceDLL "${SYSTEMDIR}\MFC71FRA.DLL" "$INSTDIR\bin\MFC71FRA.DLL" "$INSTDIR" !insertmacro ReplaceDLL "${SYSTEMDIR}\MFC71ITA.DLL" "$INSTDIR\bin\MFC71ITA.DLL" "$INSTDIR" !insertmacro ReplaceDLL "${SYSTEMDIR}\MFC71JPN.DLL" "$INSTDIR\bin\MFC71JPN.DLL" "$INSTDIR" !insertmacro ReplaceDLL "${SYSTEMDIR}\MFC71KOR.DLL" "$INSTDIR\bin\MFC71KOR.DLL" "$INSTDIR" !ELSE !IFDEF CL_1300 !insertmacro ReplaceDLL "${SYSTEMDIR}\mfc70.dll" "$INSTDIR\bin\mfc70.dll" "$INSTDIR" !insertmacro ReplaceDLL "${SYSTEMDIR}\msvcr70.dll" "$INSTDIR\bin\msvcr70.dll" "$INSTDIR" !insertmacro ReplaceDLL "${SYSTEMDIR}\msvcp70.dll" "$INSTDIR\bin\msvcp70.dll" "$INSTDIR" !insertmacro ReplaceDLL "${SYSTEMDIR}\MFC70CHS.DLL" "$INSTDIR\bin\MFC70CHS.DLL" "$INSTDIR" !insertmacro ReplaceDLL "${SYSTEMDIR}\MFC70CHT.DLL" "$INSTDIR\bin\MFC70CHT.DLL" "$INSTDIR" !insertmacro ReplaceDLL "${SYSTEMDIR}\MFC70DEU.DLL" "$INSTDIR\bin\MFC70DEU.DLL" "$INSTDIR" !insertmacro ReplaceDLL "${SYSTEMDIR}\MFC70ENU.DLL" "$INSTDIR\bin\MFC70ENU.DLL" "$INSTDIR" !insertmacro ReplaceDLL "${SYSTEMDIR}\MFC70ESP.DLL" "$INSTDIR\bin\MFC70ESP.DLL" "$INSTDIR" !insertmacro ReplaceDLL "${SYSTEMDIR}\MFC70FRA.DLL" "$INSTDIR\bin\MFC70FRA.DLL" "$INSTDIR" !insertmacro ReplaceDLL "${SYSTEMDIR}\MFC70ITA.DLL" "$INSTDIR\bin\MFC70ITA.DLL" "$INSTDIR" !insertmacro ReplaceDLL "${SYSTEMDIR}\MFC70JPN.DLL" "$INSTDIR\bin\MFC70JPN.DLL" "$INSTDIR" !insertmacro ReplaceDLL "${SYSTEMDIR}\MFC70KOR.DLL" "$INSTDIR\bin\MFC70KOR.DLL" "$INSTDIR" !ELSE !insertmacro ReplaceDLL "${SYSTEMDIR}\mfc42.dll" "$INSTDIR\bin\mfc42.dll" "$INSTDIR" !insertmacro ReplaceDLL "${SYSTEMDIR}\msvcp60.dll" "$INSTDIR\bin\msvcp60.dll" "$INSTDIR" !insertmacro ReplaceDLL "${SYSTEMDIR}\msvcrt.dll" "$INSTDIR\bin\msvcrt.dll" "$INSTDIR" !ENDIF !ENDIF !ENDIF !ENDIF !insertmacro ReplaceDLL "${SYSTEMDIR}\psapi.dll" "$INSTDIR\bin\psapi.dll" "$INSTDIR" ; Do WINDOWSDIR components ;SetOutPath "$WINDOWSDIR" !ifdef DEBUG !endif ; Do Windows SYSDIR (Control panel) SetOutPath "$SYSDIR" !insertmacro ReplaceDLL "${KFW_BIN_DIR}\kfwlogon.dll" "$SYSDIR\kfwlogon.dll" "$INSTDIR" File "${KFW_BIN_DIR}\kfwcpcc.exe" ; Get Kerberos config files Call kfw.GetConfigFiles Call KFWCommon.Install ; KfW Reg entries DeleteRegKey HKLM "${KFW_REGKEY_ROOT}\Client\CurrentVersion" WriteRegStr HKLM "${KFW_REGKEY_ROOT}\Client\CurrentVersion" "VersionString" ${KFW_VERSION} WriteRegStr HKLM "${KFW_REGKEY_ROOT}\Client\CurrentVersion" "Title" "KfW" WriteRegStr HKLM "${KFW_REGKEY_ROOT}\Client\CurrentVersion" "Description" "${PROGRAM_NAME}" WriteRegStr HKLM "${KFW_REGKEY_ROOT}\Client\CurrentVersion" "PathName" "$INSTDIR" WriteRegStr HKLM "${KFW_REGKEY_ROOT}\Client\CurrentVersion" "Software Type" "Authentication" WriteRegDWORD HKLM "${KFW_REGKEY_ROOT}\Client\CurrentVersion" "MajorVersion" ${KFW_MAJORVERSION} WriteRegDWORD HKLM "${KFW_REGKEY_ROOT}\Client\CurrentVersion" "MinorVersion" ${KFW_MINORVERSION} WriteRegDWORD HKLM "${KFW_REGKEY_ROOT}\Client\CurrentVersion" "PatchLevel" ${KFW_PATCHLEVEL} DeleteRegKey HKLM "${KFW_REGKEY_ROOT}\Client\${KFW_VERSION}" WriteRegStr HKLM "${KFW_REGKEY_ROOT}\Client\${KFW_VERSION}" "VersionString" ${KFW_VERSION} WriteRegStr HKLM "${KFW_REGKEY_ROOT}\Client\${KFW_VERSION}" "Title" "KfW" WriteRegStr HKLM "${KFW_REGKEY_ROOT}\Client\${KFW_VERSION}" "Description" "${PROGRAM_NAME}" WriteRegStr HKLM "${KFW_REGKEY_ROOT}\Client\${KFW_VERSION}" "PathName" "$INSTDIR" WriteRegStr HKLM "${KFW_REGKEY_ROOT}\Client\${KFW_VERSION}" "Software Type" "Authentication" WriteRegDWORD HKLM "${KFW_REGKEY_ROOT}\Client\${KFW_VERSION}" "MajorVersion" ${KFW_MAJORVERSION} WriteRegDWORD HKLM "${KFW_REGKEY_ROOT}\Client\${KFW_VERSION}" "MinorVersion" ${KFW_MINORVERSION} WriteRegDWORD HKLM "${KFW_REGKEY_ROOT}\Client\${KFW_VERSION}" "PatchLevel" ${KFW_PATCHLEVEL} ; Daemon entries WriteRegStr HKLM "SYSTEM\CurrentControlSet\Services\MIT Kerberos" "" "" WriteRegStr HKLM "SYSTEM\CurrentControlSet\Services\MIT Kerberos\NetworkProvider" "ProviderPath" "$SYSDIR\kfwlogon.dll" WriteRegStr HKLM "SYSTEM\CurrentControlSet\Services\MIT Kerberos\NetworkProvider" "AuthentProviderPath" "$SYSDIR\kfwlogon.dll" WriteRegDWORD HKLM "SYSTEM\CurrentControlSet\Services\MIT Kerberos\NetworkProvider" "Class" 2 WriteRegDWORD HKLM "SYSTEM\CurrentControlSet\Services\MIT Kerberos\NetworkProvider" "VerboseLogging" 10 ; Must also add HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\NetworkProvider\HwOrder ; and HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\NetworkProvider\Order ; to also include the service name. Call AddProvider ReadINIStr $R0 $1 "Field 7" "State" WriteRegStr HKLM "SYSTEM\CurrentControlSet\Services\MIT Kerberos\NetworkProvider" "Name" "MIT Kerberos" ; WinLogon Event Notification WriteRegDWORD HKLM "Software\Microsoft\Windows NT\CurrentVersion\WinLogon\Notify\MIT_KFW" "Asynchronous" 0 WriteRegDWORD HKLM "Software\Microsoft\Windows NT\CurrentVersion\WinLogon\Notify\MIT_KFW" "Impersonate" 0 WriteRegStr HKLM "Software\Microsoft\Windows NT\CurrentVersion\WinLogon\Notify\MIT_KFW" "DLLName" "kfwlogon.dll" WriteRegStr HKLM "Software\Microsoft\Windows NT\CurrentVersion\WinLogon\Notify\MIT_KFW" "Logon" "KFW_Logon_Event" ; NetIdMgr Reg entries WriteRegStr HKLM "Software\MIT\NetIDMgr\PluginManager\Modules\MITKrb5" "ImagePath" "$INSTDIR\bin\krb5cred.dll" WriteRegStr HKLM "Software\MIT\NetIDMgr\PluginManager\Modules\MITKrb5" "PluginList" "Krb5Cred,Krb5Ident" WriteRegStr HKLM "Software\MIT\NetIDMgr\PluginManager\Plugins\Krb5Cred" "Module" "MITKrb5" WriteRegStr HKLM "Software\MIT\NetIDMgr\PluginManager\Plugins\Krb5Cred" "Description" "Kerberos v5 Credentials Provider" WriteRegDWORD HKLM "Software\MIT\NetIDMgr\PluginManager\Plugins\Krb5Cred" "Type" 1 WriteRegDWORD HKLM "Software\MIT\NetIDMgr\PluginManager\Plugins\Krb5Cred" "Flags" 0 WriteRegStr HKLM "Software\MIT\NetIDMgr\PluginManager\Plugins\Krb5Ident" "Module" "MITKrb5" WriteRegStr HKLM "Software\MIT\NetIDMgr\PluginManager\Plugins\Krb5Ident" "Description" "Kerberos v5 Identity Provider" WriteRegStr HKLM "Software\MIT\NetIDMgr\PluginManager\Plugins\Krb5Ident" "Dependencies" "Krb5Cred" WriteRegDWORD HKLM "Software\MIT\NetIDMgr\PluginManager\Plugins\Krb5Ident" "Type" 2 WriteRegDWORD HKLM "Software\MIT\NetIDMgr\PluginManager\Plugins\Krb5Ident" "Flags" 0 WriteRegStr HKLM "Software\MIT\NetIDMgr\PluginManager\Modules\MITKrb4" "ImagePath" "$INSTDIR\bin\krb4cred.dll" WriteRegStr HKLM "Software\MIT\NetIDMgr\PluginManager\Modules\MITKrb4" "PluginList" "Krb4Cred" WriteRegStr HKLM "Software\MIT\NetIDMgr\PluginManager\Plugins\Krb4Cred" "Module" "MITKrb4" WriteRegStr HKLM "Software\MIT\NetIDMgr\PluginManager\Plugins\Krb4Cred" "Description" "Kerberos v4 Credentials Provider" WriteRegStr HKLM "Software\MIT\NetIDMgr\PluginManager\Plugins\Krb4Cred" "Dependencies" "Krb5Cred" WriteRegDWORD HKLM "Software\MIT\NetIDMgr\PluginManager\Plugins\Krb4Cred" "Type" 1 WriteRegDWORD HKLM "Software\MIT\NetIDMgr\PluginManager\Plugins\Krb4Cred" "Flags" 0 ;Write start menu entries CreateDirectory "$SMPROGRAMS\${PROGRAM_NAME}" SetOutPath "$INSTDIR\bin" CreateShortCut "$SMPROGRAMS\${PROGRAM_NAME}\Uninstall ${PROGRAM_NAME}.lnk" "$INSTDIR\Uninstall.exe" ReadINIStr $R0 $1 "Field 2" "State" ; startup CreateShortCut "$SMPROGRAMS\${PROGRAM_NAME}\Network Identity Manager.lnk" "$INSTDIR\bin\netidmgr.exe" "" "$INSTDIR\bin\netidmgr.exe" startshort: StrCmp $R0 "0" nostart CreateShortCut "$SMSTARTUP\Network Identity Manager.lnk" "$INSTDIR\bin\netidmgr.exe" "" "$INSTDIR\bin\netidmgr.exe" 0 SW_SHOWMINIMIZED goto checkconflicts nostart: Delete "$SMSTARTUP\Network Identity Manager.lnk" checkconflicts: Call GetSystemPath Push "krb5_32.dll" Call SearchPath Pop $R0 StrCmp $R0 "" addpath Push $R0 Call GetParent Pop $R0 StrCmp $R0 "$INSTDIR\bin" addpath MessageBox MB_OK|MB_ICONINFORMATION|MB_TOPMOST "A previous installation of MIT Kerberos for Windows binaries has been found in folder $R0. This may interfere with the use of the current installation." addpath: ; Add kfw bin to path Push "$INSTDIR\bin" Call AddToSystemPath Call GetWindowsVersion Pop $R0 StrCmp $R0 "2003" addAllowTgtKey StrCmp $R0 "2000" addAllowTgtKey StrCmp $R0 "XP" addAllowTgtKey goto skipAllowTgtKey addAllowTgtKey: ReadRegDWORD $R0 HKLM "SYSTEM\CurrentControlSet\Control\Lsa\Kerberos\Parameters" "AllowTGTSessionKey" WriteRegDWORD HKLM "${KFW_REGKEY_ROOT}\Client\${KFW_VERSION}" "AllowTGTSessionKeyBackup" $R0 WriteRegDWORD HKLM "SYSTEM\CurrentControlSet\Control\Lsa\Kerberos\Parameters" "AllowTGTSessionKey" "1" ReadRegDWORD $R0 HKLM "SYSTEM\CurrentControlSet\Control\Lsa\Kerberos" "AllowTGTSessionKey" WriteRegDWORD HKLM "${KFW_REGKEY_ROOT}\Client\${KFW_VERSION}" "AllowTGTSessionKeyBackup2" $R0 WriteRegDWORD HKLM "SYSTEM\CurrentControlSet\Control\Lsa\Kerberos" "AllowTGTSessionKey" "1" skipAllowTgtKey: ; The following are keys added for Terminal Server compatibility ; http://support.microsoft.com/default.aspx?scid=kb;EN-US;186499 WriteRegDWORD HKLM "Software\Microsoft\Windows NT\CurrentVersion\Terminal Server\Compatibility\Applications\netidmgr" "Flags" 0x408 WriteRegDWORD HKLM "Software\Microsoft\Windows NT\CurrentVersion\Terminal Server\Compatibility\Applications\kinit" "Flags" 0x408 WriteRegDWORD HKLM "Software\Microsoft\Windows NT\CurrentVersion\Terminal Server\Compatibility\Applications\klist" "Flags" 0x408 WriteRegDWORD HKLM "Software\Microsoft\Windows NT\CurrentVersion\Terminal Server\Compatibility\Applications\kdestroy" "Flags" 0x408 WriteRegDWORD HKLM "Software\Microsoft\Windows NT\CurrentVersion\Terminal Server\Compatibility\Applications\gss" "Flags" 0x408 WriteRegDWORD HKLM "Software\Microsoft\Windows NT\CurrentVersion\Terminal Server\Compatibility\Applications\gss-client" "Flags" 0x408 WriteRegDWORD HKLM "Software\Microsoft\Windows NT\CurrentVersion\Terminal Server\Compatibility\Applications\gss-server" "Flags" 0x408 WriteRegDWORD HKLM "Software\Microsoft\Windows NT\CurrentVersion\Terminal Server\Compatibility\Applications\k524init" "Flags" 0x408 WriteRegDWORD HKLM "Software\Microsoft\Windows NT\CurrentVersion\Terminal Server\Compatibility\Applications\kpasswd" "Flags" 0x408 WriteRegDWORD HKLM "Software\Microsoft\Windows NT\CurrentVersion\Terminal Server\Compatibility\Applications\kvno" "Flags" 0x408 WriteRegDWORD HKLM "Software\Microsoft\Windows NT\CurrentVersion\Terminal Server\Compatibility\Applications\ms2mit" "Flags" 0x408 WriteRegDWORD HKLM "Software\Microsoft\Windows NT\CurrentVersion\Terminal Server\Compatibility\Applications\mit2ms" "Flags" 0x408 WriteRegDWORD HKLM "Software\Microsoft\Windows NT\CurrentVersion\Terminal Server\Compatibility\Applications\mit2ms" "Flags" 0x408 WriteRegDWORD HKLM "Software\Microsoft\Windows NT\CurrentVersion\Terminal Server\Compatibility\Applications\kcpytkt" "Flags" 0x408 WriteRegDWORD HKLM "Software\Microsoft\Windows NT\CurrentVersion\Terminal Server\Compatibility\Applications\kdeltkt" "Flags" 0x408 WriteRegDWORD HKLM "Software\Microsoft\Windows NT\CurrentVersion\Terminal Server\Compatibility\Applications\k95" "Flags" 0x408 WriteRegDWORD HKLM "Software\Microsoft\Windows NT\CurrentVersion\Terminal Server\Compatibility\Applications\k95g" "Flags" 0x408 SectionEnd Section "Debug Symbols" secDebug SetOutPath "$INSTDIR\bin" File "${KFW_BIN_DIR}\comerr32.pdb" File "${KFW_BIN_DIR}\gss.pdb" File "${KFW_BIN_DIR}\gss-client.pdb" File "${KFW_BIN_DIR}\gss-server.pdb" File "${KFW_BIN_DIR}\gssapi32.pdb" File "${KFW_BIN_DIR}\k524init.pdb" File "${KFW_BIN_DIR}\kclnt32.pdb" File "${KFW_BIN_DIR}\kdestroy.pdb" File "${KFW_BIN_DIR}\kinit.pdb" File "${KFW_BIN_DIR}\klist.pdb" File "${KFW_BIN_DIR}\kpasswd.pdb" File "${KFW_BIN_DIR}\kvno.pdb" File "${KFW_BIN_DIR}\krb5_32.pdb" File "${KFW_BIN_DIR}\k5sprt32.pdb" File "${KFW_BIN_DIR}\krb524.pdb" File "${KFW_BIN_DIR}\krbcc32.pdb" File "${KFW_BIN_DIR}\krbcc32s.pdb" File "${KFW_BIN_DIR}\krbv4w32.pdb" File "${KFW_BIN_DIR}\leashw32.pdb" File "${KFW_BIN_DIR}\krb4cred.pdb" File "${KFW_BIN_DIR}\krb5cred.pdb" File "${KFW_BIN_DIR}\ms2mit.pdb" File "${KFW_BIN_DIR}\mit2ms.pdb" File "${KFW_BIN_DIR}\kcpytkt.pdb" File "${KFW_BIN_DIR}\kdeltkt.pdb" File "${KFW_BIN_DIR}\wshelp32.pdb" File "${KFW_BIN_DIR}\xpprof32.pdb" Call GetWindowsVersion Pop $R0 StrCmp $R0 "2000" nidpdb_inst2000 File "${KFW_BIN_DIR}\netidmgr.pdb" File "${KFW_BIN_DIR}\nidmgr32.pdb" goto nidpdb_done nidpdb_inst2000: File "${KFW_BIN_DIR}\W2K\netidmgr.pdb" File "${KFW_BIN_DIR}\W2K\nidmgr32.pdb" nidpdb_done: !IFDEF DEBUG !IFDEF CL_1400 File "${SYSTEMDIR}\msvcr80d.pdb" File "${SYSTEMDIR}\msvcp80d.pdb" File "${SYSTEMDIR}\mfc80d.pdb" !ELSE !IFDEF CL_1310 File "${SYSTEMDIR}\msvcr71d.pdb" File "${SYSTEMDIR}\msvcp71d.pdb" File "${SYSTEMDIR}\mfc71d.pdb" !ELSE !IFDEF CL_1300 File "${SYSTEMDIR}\msvcr70d.pdb" File "${SYSTEMDIR}\msvcp70d.pdb" File "${SYSTEMDIR}\mfc70d.pdb" !ELSE File "${SYSTEMDIR}\mfc42d.pdb" File "${SYSTEMDIR}\msvcp60d.pdb" File "${SYSTEMDIR}\msvcrtd.pdb" !ENDIF !ENDIF !ENDIF !ENDIF SetOutPath "$SYSDIR" File "${KFW_BIN_DIR}\kfwlogon.pdb" File "${KFW_BIN_DIR}\kfwcpcc.pdb" SectionEnd ;---------------------- ; Kerberos for Windows SDK Section "KfW SDK" secSDK RMDir /r "$INSTDIR\inc" RMDir /r "$INSTDIR\lib" RMDir /r "$INSTDIR\install" RMDir /r "$INSTDIR\sample" SetOutPath "$INSTDIR\doc" File /r "${KFW_DOC_DIR}\netiddev.chm" SetOutPath "$INSTDIR\inc\kclient" File /r "${KFW_INC_DIR}\kclient\*" SetOutPath "$INSTDIR\inc\krb4" File /r "${KFW_INC_DIR}\krb4\*" SetOutPath "$INSTDIR\inc\krb5" File /r "${KFW_INC_DIR}\krb5\*" SetOutPath "$INSTDIR\inc\krbcc" File /r "${KFW_INC_DIR}\krbcc\*" SetOutPath "$INSTDIR\inc\leash" File /r "${KFW_INC_DIR}\leash\*" SetOutPath "$INSTDIR\inc\loadfuncs" File /r "${KFW_INC_DIR}\loadfuncs\*" SetOutPath "$INSTDIR\inc\netidmgr" File /r "${KFW_INC_DIR}\netidmgr\*" SetOutPath "$INSTDIR\inc\wshelper" File /r "${KFW_INC_DIR}\wshelper\*" SetOutPath "$INSTDIR\lib\i386" File /r "${KFW_LIB_DIR}\*" SetOutPath "$INSTDIR\install" File /r "${KFW_INSTALL_DIR}\*" SetOutPath "$INSTDIR\sample" File /r "${KFW_SAMPLE_DIR}\*" CreateShortCut "$SMPROGRAMS\${PROGRAM_NAME}\Network Identity Developer Documentation.lnk" "$INSTDIR\bin\netiddev.chm" Call KFWCommon.Install ; KfW Reg entries DeleteRegKey HKLM "${KFW_REGKEY_ROOT}\SDK\CurrentVersion" WriteRegStr HKLM "${KFW_REGKEY_ROOT}\SDK\CurrentVersion" "VersionString" ${KFW_VERSION} WriteRegStr HKLM "${KFW_REGKEY_ROOT}\SDK\CurrentVersion" "Title" "KfW" WriteRegStr HKLM "${KFW_REGKEY_ROOT}\SDK\CurrentVersion" "Description" "${PROGRAM_NAME}" WriteRegStr HKLM "${KFW_REGKEY_ROOT}\SDK\CurrentVersion" "PathName" "$INSTDIR" WriteRegStr HKLM "${KFW_REGKEY_ROOT}\SDK\CurrentVersion" "Software Type" "Authentication" WriteRegDWORD HKLM "${KFW_REGKEY_ROOT}\SDK\CurrentVersion" "MajorVersion" ${KFW_MAJORVERSION} WriteRegDWORD HKLM "${KFW_REGKEY_ROOT}\SDK\CurrentVersion" "MinorVersion" ${KFW_MINORVERSION} WriteRegDWORD HKLM "${KFW_REGKEY_ROOT}\SDK\CurrentVersion" "PatchLevel" ${KFW_PATCHLEVEL} DeleteRegKey HKLM "${KFW_REGKEY_ROOT}\SDK\${KFW_VERSION}" WriteRegStr HKLM "${KFW_REGKEY_ROOT}\SDK\${KFW_VERSION}" "VersionString" ${KFW_VERSION} WriteRegStr HKLM "${KFW_REGKEY_ROOT}\SDK\${KFW_VERSION}" "Title" "KfW" WriteRegStr HKLM "${KFW_REGKEY_ROOT}\SDK\${KFW_VERSION}" "Description" "${PROGRAM_NAME}" WriteRegStr HKLM "${KFW_REGKEY_ROOT}\SDK\${KFW_VERSION}" "PathName" "$INSTDIR" WriteRegStr HKLM "${KFW_REGKEY_ROOT}\SDK\${KFW_VERSION}" "Software Type" "Authentication" WriteRegDWORD HKLM "${KFW_REGKEY_ROOT}\SDK\${KFW_VERSION}" "MajorVersion" ${KFW_MAJORVERSION} WriteRegDWORD HKLM "${KFW_REGKEY_ROOT}\SDK\${KFW_VERSION}" "MinorVersion" ${KFW_MINORVERSION} WriteRegDWORD HKLM "${KFW_REGKEY_ROOT}\SDK\${KFW_VERSION}" "PatchLevel" ${KFW_PATCHLEVEL} WriteRegDWORD HKLM "${KFW_REGKEY_ROOT}\SDK\${KFW_VERSION}" "PatchLevel" ${KFW_PATCHLEVEL} SectionEnd ;---------------------- ; Kerberos for Windows Documentation Section "KfW Documentation" secDocs RMDir /r "$INSTDIR\doc" SetOutPath "$INSTDIR\doc" File "${KFW_DOC_DIR}\relnotes.html" File "${KFW_DOC_DIR}\netidmgr_userdoc.pdf" Call KFWCommon.Install ; KfW Reg entries DeleteRegKey HKLM "${KFW_REGKEY_ROOT}\Documentation\CurrentVersion" WriteRegStr HKLM "${KFW_REGKEY_ROOT}\Documentation\CurrentVersion" "VersionString" ${KFW_VERSION} WriteRegStr HKLM "${KFW_REGKEY_ROOT}\Documentation\CurrentVersion" "Title" "KfW" WriteRegStr HKLM "${KFW_REGKEY_ROOT}\Documentation\CurrentVersion" "Description" "${PROGRAM_NAME}" WriteRegStr HKLM "${KFW_REGKEY_ROOT}\Documentation\CurrentVersion" "PathName" "$INSTDIR" WriteRegStr HKLM "${KFW_REGKEY_ROOT}\Documentation\CurrentVersion" "Software Type" "Authentication" WriteRegDWORD HKLM "${KFW_REGKEY_ROOT}\Documentation\CurrentVersion" "MajorVersion" ${KFW_MAJORVERSION} WriteRegDWORD HKLM "${KFW_REGKEY_ROOT}\Documentation\CurrentVersion" "MinorVersion" ${KFW_MINORVERSION} WriteRegDWORD HKLM "${KFW_REGKEY_ROOT}\Documentation\CurrentVersion" "PatchLevel" ${KFW_PATCHLEVEL} DeleteRegKey HKLM "${KFW_REGKEY_ROOT}\Documentation\${KFW_VERSION}" WriteRegStr HKLM "${KFW_REGKEY_ROOT}\Documentation\${KFW_VERSION}" "VersionString" ${KFW_VERSION} WriteRegStr HKLM "${KFW_REGKEY_ROOT}\Documentation\${KFW_VERSION}" "Title" "KfW" WriteRegStr HKLM "${KFW_REGKEY_ROOT}\Documentation\${KFW_VERSION}" "Description" "${PROGRAM_NAME}" WriteRegStr HKLM "${KFW_REGKEY_ROOT}\Documentation\${KFW_VERSION}" "PathName" "$INSTDIR" WriteRegStr HKLM "${KFW_REGKEY_ROOT}\Documentation\${KFW_VERSION}" "Software Type" "Authentication" WriteRegDWORD HKLM "${KFW_REGKEY_ROOT}\Documentation\${KFW_VERSION}" "MajorVersion" ${KFW_MAJORVERSION} WriteRegDWORD HKLM "${KFW_REGKEY_ROOT}\Documentation\${KFW_VERSION}" "MinorVersion" ${KFW_MINORVERSION} WriteRegDWORD HKLM "${KFW_REGKEY_ROOT}\Documentation\${KFW_VERSION}" "PatchLevel" ${KFW_PATCHLEVEL} WriteRegDWORD HKLM "${KFW_REGKEY_ROOT}\Documentation\${KFW_VERSION}" "PatchLevel" ${KFW_PATCHLEVEL} ;Write start menu entries CreateDirectory "$SMPROGRAMS\${PROGRAM_NAME}" SetOutPath "$INSTDIR\doc" CreateShortCut "$SMPROGRAMS\${PROGRAM_NAME}\Release Notes.lnk" "$INSTDIR\doc\relnotes.html" CreateShortCut "$SMPROGRAMS\${PROGRAM_NAME}\Network Identity Manager User Documentation.lnk" "$INSTDIR\doc\netidmgr_userdoc.pdf" CreateShortCut "$SMPROGRAMS\${PROGRAM_NAME}\Network Identity Manager Documentation.lnk" "$INSTDIR\bin\netidmgr.chm" SectionEnd ;Display the Finish header ;Insert this macro after the sections if you are not using a finish page ;!insertmacro MUI_SECTIONS_FINISHHEADER ;-------------------------------- ;Installer Functions Function .onInit !insertmacro MUI_LANGDLL_DISPLAY ; Set the default install options Push $0 Call IsUserAdmin Pop $R0 StrCmp $R0 "true" checkVer MessageBox MB_OK|MB_ICONSTOP|MB_TOPMOST "You must be an administrator of this machine to install this software." Abort checkVer: ; Check Version of Windows. Do not install onto Windows 95 Call GetWindowsVersion Pop $R0 StrCmp $R0 "95" wrongVersion StrCmp $R0 "98" wrongVersion StrCmp $R0 "ME" wrongVersion StrCmp $R0 "NT 4.0" wrongVersion goto checkIPHLPAPI wrongVersion: MessageBox MB_OK|MB_ICONSTOP|MB_TOPMOST "MIT ${PROGRAM_NAME} requires Microsoft Windows 2000 or higher." Abort checkIPHLPAPI: ClearErrors ReadEnvStr $R0 "WinDir" GetDLLVersion "$R0\System32\iphlpapi.dll" $R1 $R2 IfErrors +1 +3 GetDLLVersion "$R0\System\iphlpapi.dll" $R1 $R2 IfErrors iphlperror IntOp $R3 $R2 / 0x00010000 IntCmpU $R3 1952 iphlpwarning checkprevious checkprevious iphlperror: MessageBox MB_OK|MB_ICONSTOP|MB_TOPMOST "MIT ${PROGRAM_NAME} requires Internet Explorer version 5.01 or higher. IPHLPAPI.DLL is missing." Abort iphlpwarning: MessageBox MB_OK|MB_ICONINFORMATION|MB_TOPMOST "IPHLPAPI.DLL must be upgraded. Please install Internet Explorer 5.01 or higher." checkprevious: ClearErrors ReadRegStr $R0 HKLM \ "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PROGRAM_NAME}" \ "DisplayVersion" IfErrors testWIX StrCmp $R0 "${KFW_VERSION}" contInstall MessageBox MB_OKCANCEL|MB_ICONEXCLAMATION \ "${PROGRAM_NAME} is already installed. $\n$\nClick `OK` to remove the \ previous version or `Cancel` to cancel this upgrade or downgrade." \ IDOK uninstNSIS Abort ;Run the uninstaller uninstNSIS: ReadRegStr $R0 HKLM \ "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PROGRAM_NAME}" \ "UninstallString" ClearErrors ExecWait '$R0 _?=$INSTDIR' ;Do not copy the uninstaller to a temp file IfErrors no_remove_uninstaller ;You can either use Delete /REBOOTOK in the uninstaller or add some code ;here to remove the uninstaller. Use a registry key to check ;whether the user has chosen to uninstall. If you are using an uninstaller ;components page, make sure all sections are uninstalled. Push $R1 Call RestartRequired Pop $R1 StrCmp $R1 "1" Restart DoNotRestart testWIX: ClearErrors ReadRegStr $R0 HKLM \ "Software\Microsoft\Windows\CurrentVersion\Uninstall\{FD5B1F41-81BB-4BBC-9F7E-4B971660AE1A}" \ "DisplayVersion" IfErrors testSWRT MessageBox MB_OKCANCEL|MB_ICONEXCLAMATION \ "${PROGRAM_NAME} is already installed. $\n$\nClick `OK` to remove the \ previous version or `Cancel` to cancel this installation." \ IDOK uninstMSI1 Abort ;Run the uninstaller uninstMSI1: Call GetWindowsVersion Pop $R0 StrCmp $R0 "2000" uninstMSI1_2000 ClearErrors ExecWait 'MSIEXEC /x{FD5B1F41-81BB-4BBC-9F7E-4B971660AE1A} /passive /promptrestart' IfErrors no_remove_uninstaller ;You can either use Delete /REBOOTOK in the uninstaller or add some code ;here to remove the uninstaller. Use a registry key to check ;whether the user has chosen to uninstall. If you are using an uninstaller ;components page, make sure all sections are uninstalled. Push $R1 Call RestartRequired Pop $R1 StrCmp $R1 "1" Restart DoNotRestart uninstMSI1_2000: ClearErrors ExecWait 'MSIEXEC /x{FD5B1F41-81BB-4BBC-9F7E-4B971660AE1A}' IfErrors no_remove_uninstaller ;You can either use Delete /REBOOTOK in the uninstaller or add some code ;here to remove the uninstaller. Use a registry key to check ;whether the user has chosen to uninstall. If you are using an uninstaller ;components page, make sure all sections are uninstalled. Push $R1 Call RestartRequired Pop $R1 StrCmp $R1 "1" Restart DoNotRestart testSWRT: ClearErrors ReadRegStr $R0 HKLM \ "Software\Microsoft\Windows\CurrentVersion\Uninstall\{61211594-AAA1-4A98-A299-757326763CC7}" \ "DisplayVersion" IfErrors testPismere MessageBox MB_OKCANCEL|MB_ICONEXCLAMATION \ "${PROGRAM_NAME} is already installed. $\n$\nClick `OK` to remove the \ previous version or `Cancel` to cancel this installation." \ IDOK uninstMSI2 Abort ;Run the uninstaller uninstMSI2: Call GetWindowsVersion Pop $R0 StrCmp $R0 "2000" uninstMSI2_2000 ClearErrors ExecWait 'MSIEXEC /x{61211594-AAA1-4A98-A299-757326763CC7} /passive /promptrestart' IfErrors no_remove_uninstaller ;You can either use Delete /REBOOTOK in the uninstaller or add some code ;here to remove the uninstaller. Use a registry key to check ;whether the user has chosen to uninstall. If you are using an uninstaller ;components page, make sure all sections are uninstalled. Push $R1 Call RestartRequired Pop $R1 StrCmp $R1 "1" Restart DoNotRestart uninstMSI2_2000: ClearErrors ExecWait 'MSIEXEC /x{61211594-AAA1-4A98-A299-757326763CC7}' IfErrors no_remove_uninstaller ;You can either use Delete /REBOOTOK in the uninstaller or add some code ;here to remove the uninstaller. Use a registry key to check ;whether the user has chosen to uninstall. If you are using an uninstaller ;components page, make sure all sections are uninstalled. Push $R1 Call RestartRequired Pop $R1 StrCmp $R1 "1" Restart DoNotRestart testPismere: ClearErrors ReadRegStr $R0 HKLM \ "Software\Microsoft\Windows\CurrentVersion\Uninstall\{83977767-388D-4DF8-BB08-3BF2401635BD}" \ "DisplayVersion" IfErrors contInstall MessageBox MB_OKCANCEL|MB_ICONEXCLAMATION \ "${PROGRAM_NAME} is already installed. $\n$\nClick `OK` to remove the \ previous version or `Cancel` to cancel this installation." \ IDOK uninstPismere Abort ;Run the uninstaller uninstPismere: Call GetWindowsVersion Pop $R0 StrCmp $R0 "2000" uninstPismere_2000 ClearErrors ExecWait 'MSIEXEC /x{83977767-388D-4DF8-BB08-3BF2401635BD} /passive /promptrestart' IfErrors no_remove_uninstaller ;You can either use Delete /REBOOTOK in the uninstaller or add some code ;here to remove the uninstaller. Use a registry key to check ;whether the user has chosen to uninstall. If you are using an uninstaller ;components page, make sure all sections are uninstalled. Push $R1 Call RestartRequired Pop $R1 StrCmp $R1 "1" Restart DoNotRestart uninstPismere_2000: ClearErrors ExecWait 'MSIEXEC /x{83977767-388D-4DF8-BB08-3BF2401635BD}' IfErrors no_remove_uninstaller ;You can either use Delete /REBOOTOK in the uninstaller or add some code ;here to remove the uninstaller. Use a registry key to check ;whether the user has chosen to uninstall. If you are using an uninstaller ;components page, make sure all sections are uninstalled. Push $R1 Call RestartRequired Pop $R1 StrCmp $R1 "1" Restart DoNotRestart Restart: MessageBox MB_OK|MB_ICONSTOP|MB_TOPMOST "Please reboot and then restart the installer." Abort MessageBox MB_OK|MB_ICONSTOP|MB_TOPMOST "Abort failed" DoNotRestart: no_remove_uninstaller: contInstall: ; Never install debug symbols unless explicitly selected, except in DEBUG mode !IFNDEF DEBUG SectionGetFlags ${secDebug} $0 IntOp $0 $0 & ${SECTION_OFF} SectionSetFlags ${secDebug} $0 !ELSE SectionGetFlags ${secDebug} $0 IntOp $0 $0 | ${SF_SELECTED} SectionSetFlags ${secDebug} $0 !ENDIF ; Our logic should be like this. ; 1) If no KfW components are installed, we do a clean install with default options. (Client/Docs) ; 2) If existing modules are installed, we keep them selected ; 3) If it is an upgrade, we set the text accordingly, else we mark it as a re-install ; TODO: Downgrade? Call IsAnyKfWInstalled Pop $R0 StrCmp $R0 "0" DefaultOptions Call ShouldClientInstall Pop $R2 StrCmp $R2 "0" NoClient StrCmp $R2 "1" ReinstallClient StrCmp $R2 "2" UpgradeClient StrCmp $R2 "3" DowngradeClient SectionGetFlags ${secClient} $0 IntOp $0 $0 | ${SF_SELECTED} SectionSetFlags ${secClient} $0 ;# !insertmacro SelectSection ${secClient} goto skipClient NoClient: ;StrCpy $1 ${secClient} ; Gotta remember which section we are at now... SectionGetFlags ${secClient} $0 IntOp $0 $0 & ${SECTION_OFF} SectionSetFlags ${secClient} $0 goto skipClient UpgradeClient: SectionGetFlags ${secClient} $0 IntOp $0 $0 | ${SF_SELECTED} SectionSetFlags ${secClient} $0 SectionSetText ${secClient} $(UPGRADE_CLIENT) goto skipClient ReinstallClient: SectionGetFlags ${secClient} $0 IntOp $0 $0 | ${SF_SELECTED} SectionSetFlags ${secClient} $0 SectionSetText ${secClient} $(REINSTALL_CLIENT) goto skipClient DowngradeClient: SectionGetFlags ${secClient} $0 IntOp $0 $0 | ${SF_SELECTED} SectionSetFlags ${secClient} $0 SectionSetText ${secClient} $(DOWNGRADE_CLIENT) goto skipClient skipClient: Call ShouldSDKInstall Pop $R2 StrCmp $R2 "0" NoSDK StrCmp $R2 "1" ReinstallSDK StrCmp $R2 "2" UpgradeSDK StrCmp $R2 "3" DowngradeSDK SectionGetFlags ${secSDK} $0 IntOp $0 $0 | ${SF_SELECTED} SectionSetFlags ${secSDK} $0 ;# !insertmacro UnselectSection ${secSDK} goto skipSDK UpgradeSDK: SectionGetFlags ${secSDK} $0 IntOp $0 $0 | ${SF_SELECTED} SectionSetFlags ${secSDK} $0 SectionSetText ${secSDK} $(UPGRADE_SDK) goto skipSDK ReinstallSDK: SectionGetFlags ${secSDK} $0 IntOp $0 $0 | ${SF_SELECTED} SectionSetFlags ${secSDK} $0 SectionSetText ${secSDK} $(REINSTALL_SDK) goto skipSDK DowngradeSDK: SectionGetFlags ${secSDK} $0 IntOp $0 $0 | ${SF_SELECTED} SectionSetFlags ${secSDK} $0 SectionSetText ${secSDK} $(DOWNGRADE_SDK) goto skipSDK NoSDK: SectionGetFlags ${secSDK} $0 IntOp $0 $0 & ${SECTION_OFF} SectionSetFlags ${secSDK} $0 ;# !insertmacro UnselectSection ${secSDK} goto skipSDK skipSDK: Call ShouldDocumentationInstall Pop $R2 StrCmp $R2 "0" NoDocumentation StrCmp $R2 "1" ReinstallDocumentation StrCmp $R2 "2" UpgradeDocumentation StrCmp $R2 "3" DowngradeDocumentation SectionGetFlags ${secDocs} $0 IntOp $0 $0 | ${SF_SELECTED} SectionSetFlags ${secDocs} $0 ;# !insertmacro UnselectSection ${secDocs} goto skipDocumentation UpgradeDocumentation: SectionGetFlags ${secDocs} $0 IntOp $0 $0 | ${SF_SELECTED} SectionSetFlags ${secDocs} $0 SectionSetText ${secDocs} $(UPGRADE_DOCS) goto skipDocumentation ReinstallDocumentation: SectionGetFlags ${secDocs} $0 IntOp $0 $0 | ${SF_SELECTED} SectionSetFlags ${secDocs} $0 SectionSetText ${secDocs} $(REINSTALL_DOCS) goto skipDocumentation DowngradeDocumentation: SectionGetFlags ${secDocs} $0 IntOp $0 $0 | ${SF_SELECTED} SectionSetFlags ${secDocs} $0 SectionSetText ${secDocs} $(DOWNGRADE_DOCS) goto skipDocumentation NoDocumentation: SectionGetFlags ${secDocs} $0 IntOp $0 $0 & ${SECTION_OFF} SectionSetFlags ${secDocs} $0 ;# !insertmacro UnselectSection ${secDocs} goto skipDocumentation skipDocumentation: goto end DefaultOptions: ; Client Selected SectionGetFlags ${secClient} $0 IntOp $0 $0 | ${SF_SELECTED} SectionSetFlags ${secClient} $0 ; SDK NOT selected SectionGetFlags ${secSDK} $0 IntOp $0 $0 & ${SECTION_OFF} SectionSetFlags ${secSDK} $0 ; Documentation selected SectionGetFlags ${secDocs} $0 IntOp $0 $0 | ${SF_SELECTED} SectionSetFlags ${secDocs} $0 goto end end: Pop $0 Push $R0 ; See if we can set a default installation path... ReadRegStr $R0 HKLM "${KFW_REGKEY_ROOT}\Client\CurrentVersion" "PathName" StrCmp $R0 "" TrySDK StrCpy $INSTDIR $R0 goto Nope TrySDK: ReadRegStr $R0 HKLM "${KFW_REGKEY_ROOT}\SDK\CurrentVersion" "PathName" StrCmp $R0 "" TryDocs StrCpy $INSTDIR $R0 goto Nope TryDocs: ReadRegStr $R0 HKLM "${KFW_REGKEY_ROOT}\Documentation\CurrentVersion" "PathName" StrCmp $R0 "" TryRoot StrCpy $INSTDIR $R0 goto Nope TryRoot: ReadRegStr $R0 HKLM "${KFW_REGKEY_ROOT}" "InstallDir" StrCmp $R0 "" Nope StrCpy $INSTDIR $R0 Nope: Pop $R0 GetTempFilename $0 File /oname=$0 KfWConfigPage.ini GetTempFilename $1 File /oname=$1 KfWConfigPage2.ini FunctionEnd ;-------------------------------- ; These are our cleanup functions Function .onInstFailed Delete $0 Delete $1 FunctionEnd Function .onInstSuccess Delete $0 Delete $1 FunctionEnd ;-------------------------------- ;Descriptions !insertmacro MUI_FUNCTION_DESCRIPTION_BEGIN !insertmacro MUI_DESCRIPTION_TEXT ${secClient} $(DESC_secClient) !insertmacro MUI_DESCRIPTION_TEXT ${secSDK} $(DESC_secSDK) !insertmacro MUI_DESCRIPTION_TEXT ${secDocs} $(DESC_secDocs) !insertmacro MUI_DESCRIPTION_TEXT ${secDebug} $(DESC_secDebug) !insertmacro MUI_FUNCTION_DESCRIPTION_END ;-------------------------------- ;Uninstaller Section Section "Uninstall" ; Make sure the user REALLY wants to do this, unless they did a silent uninstall, in which case...let them! IfSilent StartRemove ; New in v2.0b4 MessageBox MB_YESNO "Are you sure you want to remove MIT ${PROGRAM_NAME} from this machine?" IDYES StartRemove abort StartRemove: SetShellVarContext all ; Stop the running processes GetTempFileName $R0 File /oname=$R0 "Killer.exe" nsExec::Exec '$R0 netidmgr.exe' nsExec::Exec '$R0 krbcc32s.exe' Push "$INSTDIR\bin" Call un.RemoveFromSystemPath ; Delete documentation Delete "$INSTDIR\doc\relnotes.html" Delete "$INSTDIR\doc\netidmgr_userdoc.pdf" Delete "$INSTDIR\doc\netiddev.chm" Delete /REBOOTOK "$INSTDIR\bin\comerr32.dll" Delete /REBOOTOK "$INSTDIR\bin\gss.exe" Delete /REBOOTOK "$INSTDIR\bin\gss-client.exe" Delete /REBOOTOK "$INSTDIR\bin\gss-server.exe" Delete /REBOOTOK "$INSTDIR\bin\gssapi32.dll" Delete /REBOOTOK "$INSTDIR\bin\k524init.exe" Delete /REBOOTOK "$INSTDIR\bin\kclnt32.dll" Delete /REBOOTOK "$INSTDIR\bin\kdestroy.exe" Delete /REBOOTOK "$INSTDIR\bin\kinit.exe" Delete /REBOOTOK "$INSTDIR\bin\klist.exe" Delete /REBOOTOK "$INSTDIR\bin\kpasswd.exe" Delete /REBOOTOK "$INSTDIR\bin\kvno.exe" Delete /REBOOTOK "$INSTDIR\bin\krb5_32.dll" Delete /REBOOTOK "$INSTDIR\bin\k5sprt32.dll" Delete /REBOOTOK "$INSTDIR\bin\krb524.dll" Delete /REBOOTOK "$INSTDIR\bin\krbcc32.dll" Delete /REBOOTOK "$INSTDIR\bin\krbcc32s.exe" Delete /REBOOTOK "$INSTDIR\bin\krbv4w32.dll" Delete /REBOOTOK "$INSTDIR\bin\netidmgr.exe" Delete /REBOOTOK "$INSTDIR\bin\netidmgr.chm" Delete /REBOOTOK "$INSTDIR\bin\nidmgr32.dll" Delete /REBOOTOK "$INSTDIR\bin\krb4cred.dll" Delete /REBOOTOK "$INSTDIR\bin\krb5cred.dll" Delete /REBOOTOK "$INSTDIR\bin\krb4cred_en_us.dll" Delete /REBOOTOK "$INSTDIR\bin\krb5cred_en_us.dll" Delete /REBOOTOK "$INSTDIR\bin\leashw32.dll" Delete /REBOOTOK "$INSTDIR\bin\ms2mit.exe" Delete /REBOOTOK "$INSTDIR\bin\mit2ms.exe" Delete /REBOOTOK "$INSTDIR\bin\kcpytkt.exe" Delete /REBOOTOK "$INSTDIR\bin\kdeltkt.exe" Delete /REBOOTOK "$INSTDIR\bin\wshelp32.dll" Delete /REBOOTOK "$INSTDIR\bin\xpprof32.dll" Delete /REBOOTOK "$SYSDIR\bin\kfwlogon.dll" Delete /REBOOTOK "$SYSDIR\bin\kfwcpcc.exe" Delete /REBOOTOK "$INSTDIR\bin\comerr32.pdb" Delete /REBOOTOK "$INSTDIR\bin\gss.pdb" Delete /REBOOTOK "$INSTDIR\bin\gss-client.pdb" Delete /REBOOTOK "$INSTDIR\bin\gss-server.pdb" Delete /REBOOTOK "$INSTDIR\bin\gssapi32.pdb" Delete /REBOOTOK "$INSTDIR\bin\k524init.pdb" Delete /REBOOTOK "$INSTDIR\bin\kclnt32.pdb" Delete /REBOOTOK "$INSTDIR\bin\kdestroy.pdb" Delete /REBOOTOK "$INSTDIR\bin\kinit.pdb" Delete /REBOOTOK "$INSTDIR\bin\klist.pdb" Delete /REBOOTOK "$INSTDIR\bin\kpasswd.pdb" Delete /REBOOTOK "$INSTDIR\bin\kvno.pdb" Delete /REBOOTOK "$INSTDIR\bin\krb5_32.pdb" Delete /REBOOTOK "$INSTDIR\bin\k5sprt32.pdb" Delete /REBOOTOK "$INSTDIR\bin\krb524.pdb" Delete /REBOOTOK "$INSTDIR\bin\krbcc32.pdb" Delete /REBOOTOK "$INSTDIR\bin\krbcc32s.pdb" Delete /REBOOTOK "$INSTDIR\bin\krbv4w32.pdb" Delete /REBOOTOK "$INSTDIR\bin\netidmgr.pdb" Delete /REBOOTOK "$INSTDIR\bin\nidmgr32.pdb" Delete /REBOOTOK "$INSTDIR\bin\krb4cred.pdb" Delete /REBOOTOK "$INSTDIR\bin\krb5cred.pdb" Delete /REBOOTOK "$INSTDIR\bin\leashw32.pdb" Delete /REBOOTOK "$INSTDIR\bin\ms2mit.pdb" Delete /REBOOTOK "$INSTDIR\bin\mit2ms.pdb" Delete /REBOOTOK "$INSTDIR\bin\kcpytkt.pdb" Delete /REBOOTOK "$INSTDIR\bin\kdeltkt.pdb" Delete /REBOOTOK "$INSTDIR\bin\wshelp32.pdb" Delete /REBOOTOK "$INSTDIR\bin\xpprof32.pdb" Delete /REBOOTOK "$SYSDIR\bin\kfwlogon.pdb" Delete /REBOOTOK "$SYSDIR\bin\kfwcpcc.pdb" !IFDEF DEBUG !IFDEF CL_1400 Delete /REBOOTOK "$INSTDIR\bin\msvcr80d.dll" Delete /REBOOTOK "$INSTDIR\bin\msvcr80d.pdb" Delete /REBOOTOK "$INSTDIR\bin\msvcp80d.dll" Delete /REBOOTOK "$INSTDIR\bin\msvcp80d.pdb" Delete /REBOOTOK "$INSTDIR\bin\mfc80d.dll" Delete /REBOOTOK "$INSTDIR\bin\mfc80d.pdb" !ELSE !IFDEF CL_1310 Delete /REBOOTOK "$INSTDIR\bin\msvcr71d.dll" Delete /REBOOTOK "$INSTDIR\bin\msvcr71d.pdb" Delete /REBOOTOK "$INSTDIR\bin\msvcp71d.dll" Delete /REBOOTOK "$INSTDIR\bin\msvcp71d.pdb" Delete /REBOOTOK "$INSTDIR\bin\mfc71d.dll" Delete /REBOOTOK "$INSTDIR\bin\mfc71d.pdb" !ELSE !IFDEF CL_1300 Delete /REBOOTOK "$INSTDIR\bin\msvcr70d.dll" Delete /REBOOTOK "$INSTDIR\bin\msvcr70d.pdb" Delete /REBOOTOK "$INSTDIR\bin\msvcp70d.dll" Delete /REBOOTOK "$INSTDIR\bin\msvcp70d.pdb" Delete /REBOOTOK "$INSTDIR\bin\mfc70d.dll" Delete /REBOOTOK "$INSTDIR\bin\mfc70d.pdb" !ELSE Delete /REBOOTOK "$INSTDIR\bin\mfc42d.dll" Delete /REBOOTOK "$INSTDIR\bin\mfc42d.pdb" Delete /REBOOTOK "$INSTDIR\bin\msvcp60d.dll" Delete /REBOOTOK "$INSTDIR\bin\msvcp60d.pdb" Delete /REBOOTOK "$INSTDIR\bin\msvcrtd.dll" Delete /REBOOTOK "$INSTDIR\bin\msvcrtd.pdb" !ENDIF !ENDIF !ENDIF !ELSE !IFDEF CL_1400 Delete /REBOOTOK "$INSTDIR\bin\mfc80.dll" Delete /REBOOTOK "$INSTDIR\bin\msvcr80.dll" Delete /REBOOTOK "$INSTDIR\bin\msvcp80.dll" Delete /REBOOTOK "$INSTDIR\bin\MFC80CHS.DLL" Delete /REBOOTOK "$INSTDIR\bin\MFC80CHT.DLL" Delete /REBOOTOK "$INSTDIR\bin\MFC80DEU.DLL" Delete /REBOOTOK "$INSTDIR\bin\MFC80ENU.DLL" Delete /REBOOTOK "$INSTDIR\bin\MFC80ESP.DLL" Delete /REBOOTOK "$INSTDIR\bin\MFC80FRA.DLL" Delete /REBOOTOK "$INSTDIR\bin\MFC80ITA.DLL" Delete /REBOOTOK "$INSTDIR\bin\MFC80JPN.DLL" Delete /REBOOTOK "$INSTDIR\bin\MFC80KOR.DLL" !ELSE !IFDEF CL_1310 Delete /REBOOTOK "$INSTDIR\bin\mfc71.dll" Delete /REBOOTOK "$INSTDIR\bin\msvcr71.dll" Delete /REBOOTOK "$INSTDIR\bin\msvcp71.dll" Delete /REBOOTOK "$INSTDIR\bin\MFC71CHS.DLL" Delete /REBOOTOK "$INSTDIR\bin\MFC71CHT.DLL" Delete /REBOOTOK "$INSTDIR\bin\MFC71DEU.DLL" Delete /REBOOTOK "$INSTDIR\bin\MFC71ENU.DLL" Delete /REBOOTOK "$INSTDIR\bin\MFC71ESP.DLL" Delete /REBOOTOK "$INSTDIR\bin\MFC71FRA.DLL" Delete /REBOOTOK "$INSTDIR\bin\MFC71ITA.DLL" Delete /REBOOTOK "$INSTDIR\bin\MFC71JPN.DLL" Delete /REBOOTOK "$INSTDIR\bin\MFC71KOR.DLL" !ELSE !IFDEF CL_1300 Delete /REBOOTOK "$INSTDIR\bin\mfc70.dll" Delete /REBOOTOK "$INSTDIR\bin\msvcr70.dll" Delete /REBOOTOK "$INSTDIR\bin\msvcp70.dll" Delete /REBOOTOK "$INSTDIR\bin\MFC70CHS.DLL" Delete /REBOOTOK "$INSTDIR\bin\MFC70CHT.DLL" Delete /REBOOTOK "$INSTDIR\bin\MFC70DEU.DLL" Delete /REBOOTOK "$INSTDIR\bin\MFC70ENU.DLL" Delete /REBOOTOK "$INSTDIR\bin\MFC70ESP.DLL" Delete /REBOOTOK "$INSTDIR\bin\MFC70FRA.DLL" Delete /REBOOTOK "$INSTDIR\bin\MFC70ITA.DLL" Delete /REBOOTOK "$INSTDIR\bin\MFC70JPN.DLL" Delete /REBOOTOK "$INSTDIR\bin\MFC70KOR.DLL" !ELSE Delete /REBOOTOK "$INSTDIR\bin\mfc42.dll" Delete /REBOOTOK "$INSTDIR\bin\msvcp60.dll" Delete /REBOOTOK "$INSTDIR\bin\msvcrt.dll" !ENDIF !ENDIF !ENDIF !ENDIF Delete /REBOOTOK "$INSTDIR\bin\psapi.dll" RMDir "$INSTDIR\bin" RmDir "$INSTDIR\doc" RmDir "$INSTDIR\lib" RmDir "$INSTDIR\inc" RmDir "$INSTDIR\install" RMDir "$INSTDIR" Delete "$SMPROGRAMS\${PROGRAM_NAME}\Uninstall ${PROGRAM_NAME}.lnk" Delete "$SMPROGRAMS\${PROGRAM_NAME}\Network Identity Manager.lnk" Delete "$SMPROGRAMS\${PROGRAM_NAME}\Release Notes.lnk" Delete "$SMPROGRAMS\${PROGRAM_NAME}\Network Identity Manager User Documentation.lnk" Delete "$SMPROGRAMS\${PROGRAM_NAME}\Network Identity Developer Documentation.lnk" RmDir "$SMPROGRAMS\${PROGRAM_NAME}" Delete "$SMSTARTUP\Network Identity Manager.lnk" IfSilent SkipAsk ; IfFileExists "$WINDIR\krb5.ini" CellExists SkipDelAsk ; RealmExists: MessageBox MB_YESNO "Would you like to keep your configuration files?" IDYES SkipDel SkipAsk: Delete "$WINDIR\krb5.ini" Delete "$WINDIR\krb.con" Delete "$WINDIR\krbrealm.con" SkipDel: Delete "$INSTDIR\Uninstall.exe" ; Restore previous value of AllowTGTSessionKey ReadRegDWORD $R0 HKLM "${KFW_REGKEY_ROOT}\Client\${KFW_VERSION}" "AllowTGTSessionKeyBackup" WriteRegDWORD HKLM "SYSTEM\CurrentControlSet\Control\Lsa\Kerberos\Parameters" "AllowTGTSessionKey" $R0 ReadRegDWORD $R0 HKLM "${KFW_REGKEY_ROOT}\Client\${KFW_VERSION}" "AllowTGTSessionKeyBackup2" WriteRegDWORD HKLM "SYSTEM\CurrentControlSet\Control\Lsa\Kerberos" "AllowTGTSessionKey" $R0 ; The following are keys added for Terminal Server compatibility DeleteRegKey HKLM "Software\Microsoft\Windows NT\CurrentVersion\Terminal Server\Compatibility\Applications\netidmgr" DeleteRegKey HKLM "Software\Microsoft\Windows NT\CurrentVersion\Terminal Server\Compatibility\Applications\kinit" DeleteRegKey HKLM "Software\Microsoft\Windows NT\CurrentVersion\Terminal Server\Compatibility\Applications\klist" DeleteRegKey HKLM "Software\Microsoft\Windows NT\CurrentVersion\Terminal Server\Compatibility\Applications\kdestroy" DeleteRegKey HKLM "Software\Microsoft\Windows NT\CurrentVersion\Terminal Server\Compatibility\Applications\gss" DeleteRegKey HKLM "Software\Microsoft\Windows NT\CurrentVersion\Terminal Server\Compatibility\Applications\gss-client" DeleteRegKey HKLM "Software\Microsoft\Windows NT\CurrentVersion\Terminal Server\Compatibility\Applications\gss-server" DeleteRegKey HKLM "Software\Microsoft\Windows NT\CurrentVersion\Terminal Server\Compatibility\Applications\k524init" DeleteRegKey HKLM "Software\Microsoft\Windows NT\CurrentVersion\Terminal Server\Compatibility\Applications\kpasswd" DeleteRegKey HKLM "Software\Microsoft\Windows NT\CurrentVersion\Terminal Server\Compatibility\Applications\kvno" DeleteRegKey HKLM "Software\Microsoft\Windows NT\CurrentVersion\Terminal Server\Compatibility\Applications\ms2mit" DeleteRegKey HKLM "Software\Microsoft\Windows NT\CurrentVersion\Terminal Server\Compatibility\Applications\mit2ms" DeleteRegKey HKLM "Software\Microsoft\Windows NT\CurrentVersion\Terminal Server\Compatibility\Applications\kcpytkt" DeleteRegKey HKLM "Software\Microsoft\Windows NT\CurrentVersion\Terminal Server\Compatibility\Applications\kdeltkt" DeleteRegKey HKLM "Software\Microsoft\Windows NT\CurrentVersion\Terminal Server\Compatibility\Applications\k95" DeleteRegKey HKLM "Software\Microsoft\Windows NT\CurrentVersion\Terminal Server\Compatibility\Applications\k95g" DeleteRegKey HKLM "${KFW_REGKEY_ROOT}\Client\CurrentVersion" DeleteRegKey HKLM "${KFW_REGKEY_ROOT}\Client" DeleteRegKey HKLM "${KFW_REGKEY_ROOT}\Documentation\CurrentVersion" DeleteRegKey HKLM "${KFW_REGKEY_ROOT}\Documentation" DeleteRegKey HKLM "${KFW_REGKEY_ROOT}\SDK\CurrentVersion" DeleteRegKey HKLM "${KFW_REGKEY_ROOT}\SDK" DeleteRegKey /ifempty HKLM "${KFW_REGKEY_ROOT}" DeleteRegKey HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PROGRAM_NAME}" ; NIM Registry Keys DeleteRegKey HKLM "${NIM_REGKEY_ROOT}\PluginManager\Modules\MITKrb5" DeleteRegKey HKLM "${NIM_REGKEY_ROOT}\PluginManager\Modules\MITKrb4" DeleteRegKey HKLM "${NIM_REGKEY_ROOT}\PluginManager\Plugins\Krb5Cred" DeleteRegKey HKLM "${NIM_REGKEY_ROOT}\PluginManager\Plugins\Krb5Ident" DeleteRegKey HKLM "${NIM_REGKEY_ROOT}\PluginManager\Plugins\Krb4Cred" DeleteRegKey /ifempty HKLM "${NIM_REGKEY_ROOT}\PluginManager\Modules" DeleteRegKey /ifempty HKLM "${NIM_REGKEY_ROOT}\PluginManager\Plugins" DeleteRegKey /ifempty HKLM "${NIM_REGKEY_ROOT}\PluginManager" DeleteRegKey /ifempty HKLM "${NIM_REGKEY_ROOT}" ; WinLogon Event Notification DeleteRegKey HKLM "Software\Microsoft\Windows NT\CurrentVersion\Winlogon\Notify\MIT_KFW" DeleteRegKey HKLM "SYSTEM\CurrentControlSet\Services\MIT Kerberos" RMDir "$INSTDIR" SectionEnd ;-------------------------------- ;Uninstaller Functions Function un.onInit ;Get language from registry ReadRegStr $LANGUAGE ${MUI_LANGDLL_REGISTRY_ROOT} "${MUI_LANGDLL_REGISTRY_KEY}" "${MUI_LANGDLL_REGISTRY_VALUENAME}" FunctionEnd Function un.onUninstSuccess MessageBox MB_OK "Please reboot your machine to complete uninstallation of the software" FunctionEnd ;------------------------------ ; Get the Configurations files from the Internet Function kfw.GetConfigFiles ;Check if we should download Config Files ReadINIStr $R0 $0 "Field 4" "State" StrCmp $R0 "1" DoDownload ;Do nothing if we're keeping the existing file ReadINIStr $R0 $0 "Field 2" "State" StrCmp $R0 "1" done ReadINIStr $R0 $0 "Field 3" "State" StrCmp $R0 "1" UsePackaged ; If none of these, grab file from other location goto CheckOther DoDownload: ReadINIStr $R0 $0 "Field 5" "State" NSISdl::download "$R0/krb5.ini" "$WINDIR\krb5.ini" NSISdl::download "$R0/krb.con" "$WINDIR\krb.con" NSISdl::download "$R0/krbrealm.con" "$WINDIR\krbrealm.con" Pop $R0 ;Get the return value StrCmp $R0 "success" done MessageBox MB_OK|MB_ICONSTOP "Download failed: $R0" goto done UsePackaged: SetOutPath "$WINDIR" File "${KFW_CONFIG_DIR}\sample\krb5.ini" File "${KFW_CONFIG_DIR}\sample\krb.con" File "${KFW_CONFIG_DIR}\sample\krbrealm.con" goto done CheckOther: ReadINIStr $R0 $0 "Field 7" "State" StrCmp $R0 "" done CopyFiles "$R0\krb5.ini" "$WINDIR\krb5.ini" CopyFiles "$R0\krb.con" "$WINDIR\krb.con" CopyFiles "$R0\krbrealm.con" "$WINDIR\krbrealm.con" done: FunctionEnd ;------------------------------- ;Do the page to get the Config files Function KFWPageGetConfigFiles ; Skip this page if we are not installing the client SectionGetFlags ${secClient} $R0 IntOp $R0 $R0 & ${SF_SELECTED} StrCmp $R0 "0" Skip ; Set the install options here startOver: WriteINIStr $0 "Field 2" "Flags" "DISABLED" WriteINIStr $0 "Field 3" "State" "1" WriteINIStr $0 "Field 4" "State" "0" WriteINIStr $0 "Field 6" "State" "0" WriteINIStr $0 "Field 3" "Text" "Use packaged configuration files for the ${SAMPLE_CONFIG_REALM} realm." WriteINIStr $0 "Field 5" "State" "${HTTP_CONFIG_URL}" ; If there is an existing krb5.ini file, allow the user to choose it and make it default IfFileExists "$WINDIR\krb5.ini" +1 notpresent WriteINIStr $0 "Field 2" "Flags" "ENABLED" WriteINIStr $0 "Field 2" "State" "1" WriteINIStr $0 "Field 3" "State" "0" notpresent: !insertmacro MUI_HEADER_TEXT "Kerberos Configuration" "Please choose a method for installing the Kerberos Configuration files:" InstallOptions::dialog $0 Pop $R1 StrCmp $R1 "cancel" exit StrCmp $R1 "back" done StrCmp $R1 "success" done exit: Quit done: ; Check that if a file is set, a valid filename is entered... ReadINIStr $R0 $0 "Field 6" "State" StrCmp $R0 "1" CheckFileName ;Check if a URL is specified, one *IS* specified ReadINIStr $R0 $0 "Field 4" "State" StrCmp $R0 "1" CheckURL Skip CheckURL: ReadINIStr $R0 $0 "Field 5" "State" StrCmp $R0 "" +1 Skip MessageBox MB_OK|MB_ICONSTOP $(URLError) WriteINIStr $0 "Field 4" "State" "0" goto startOver CheckFileName: ReadINIStr $R0 $0 "Field 7" "State" IfFileExists "$R0\krb5.ini" Skip MessageBox MB_OK|MB_ICONSTOP $(ConfigFileError) WriteINIStr $0 "Field 6" "State" "0" goto startOver Skip: FunctionEnd ;------------------------------- ;Do the page to get the Startup Configuration Function KFWPageGetStartupConfig ; Skip this page if we are not installing the client SectionGetFlags ${secClient} $R0 IntOp $R0 $R0 & ${SF_SELECTED} StrCmp $R0 "0" Skip ; Set the install options here !insertmacro MUI_HEADER_TEXT "Network Identity Manager Setup" "Please select Network Identity ticket manager setup options:" InstallOptions::dialog $1 Pop $R1 StrCmp $R1 "cancel" exit StrCmp $R1 "back" done StrCmp $R1 "success" done exit: Quit done: skip: FunctionEnd ;------------- ; Common install routines for each module Function KFWCommon.Install WriteRegStr HKLM "${KFW_REGKEY_ROOT}" "InstallDir" $INSTDIR WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PROGRAM_NAME}" "DisplayName" "${PROGRAM_NAME}" WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PROGRAM_NAME}" "UninstallString" "$INSTDIR\uninstall.exe" !ifndef DEBUG WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PROGRAM_NAME}" "DisplayVersion" "${KFW_VERSION}" !else WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PROGRAM_NAME}" "DisplayVersion" "${KFW_VERSION} Checked/Debug" !endif WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PROGRAM_NAME}" "URLInfoAbout" "http://web.mit.edu/kerberos/" !ifdef DEBUG WriteRegDWORD HKLM "${KFW_REGKEY_ROOT}\CurrentVersion" "Debug" 1 WriteRegDWORD HKLM "${KFW_REGKEY_ROOT}\${KFW_VERSION}" "Debug" 1 !else ; Delete the DEBUG string DeleteRegValue HKLM "${KFW_REGKEY_ROOT}\CurrentVersion" "Debug" DeleteRegValue HKLM "${KFW_REGKEY_ROOT}\${KFW_VERSION}" "Debug" !endif WriteUninstaller "$INSTDIR\Uninstall.exe" FunctionEnd ;------------------------------- ; Check if the client should be checked for default install Function ShouldClientInstall Push $R0 StrCpy $R2 "Client" Call GetInstalledVersion Pop $R0 StrCmp $R0 "" NotInstalled ; Now we see if it's an older or newer version Call GetInstalledVersionMajor Pop $R0 IntCmpU $R0 ${KFW_MAJORVERSION} +1 Upgrade Downgrade Call GetInstalledVersionMinor Pop $R0 IntCmpU $R0 ${KFW_MINORVERSION} +1 Upgrade Downgrade Call GetInstalledVersionPatch Pop $R0 IntCmpU $R0 ${KFW_PATCHLEVEL} Reinstall Upgrade Downgrade Reinstall: StrCpy $R0 "1" Exch $R0 goto end Upgrade: StrCpy $R0 "2" Exch $R0 goto end Downgrade: StrCpy $R0 "3" Exch $R0 goto end NotInstalled: StrCpy $R0 "0" Exch $R0 end: FunctionEnd ;------------------------------- ; Check how the Documentation options should be set Function ShouldDocumentationInstall Push $R0 StrCpy $R2 "Documentation" Call GetInstalledVersion Pop $R0 StrCmp $R0 "" NotInstalled ; Now we see if it's an older or newer version Call GetInstalledVersionMajor Pop $R0 IntCmpU $R0 ${KFW_MAJORVERSION} +1 Upgrade Downgrade Call GetInstalledVersionMinor Pop $R0 IntCmpU $R0 ${KFW_MINORVERSION} +1 Upgrade Downgrade Call GetInstalledVersionPatch Pop $R0 IntCmpU $R0 ${KFW_PATCHLEVEL} Reinstall Upgrade Downgrade Reinstall: StrCpy $R0 "1" Exch $R0 goto end Upgrade: StrCpy $R0 "2" Exch $R0 goto end Downgrade: StrCpy $R0 "3" Exch $R0 goto end NotInstalled: StrCpy $R0 "0" Exch $R0 end: FunctionEnd ;------------------------------- ; Check how the SDK options should be set Function ShouldSDKInstall Push $R0 StrCpy $R2 "SDK" Call GetInstalledVersion Pop $R0 StrCmp $R0 "" NotInstalled ; Now we see if it's an older or newer version Call GetInstalledVersionMajor Pop $R0 IntCmpU $R0 ${KFW_MAJORVERSION} +1 Upgrade Downgrade Call GetInstalledVersionMinor Pop $R0 IntCmpU $R0 ${KFW_MINORVERSION} +1 Upgrade Downgrade Call GetInstalledVersionPatch Pop $R0 IntCmpU $R0 ${KFW_PATCHLEVEL} Reinstall Upgrade Downgrade Reinstall: StrCpy $R0 "1" Exch $R0 goto end Upgrade: StrCpy $R0 "2" Exch $R0 goto end Downgrade: StrCpy $R0 "3" Exch $R0 goto end NotInstalled: StrCpy $R0 "0" Exch $R0 end: FunctionEnd ; See if KfW SDK is installed ; Returns: "1" if it is, 0 if it is not (on the stack) Function IsSDKInstalled Push $R0 StrCpy $R2 "SDK" Call GetInstalledVersion Pop $R0 StrCmp $R0 "" NotInstalled StrCpy $R0 "1" Exch $R0 goto end NotInstalled: StrCpy $R0 "0" Exch $R0 end: FunctionEnd ; See if KfW Client is installed ; Returns: "1" if it is, 0 if it is not (on the stack) Function IsClientInstalled Push $R0 StrCpy $R2 "Client" Call GetInstalledVersion Pop $R0 StrCmp $R0 "" NotInstalled StrCpy $R0 "1" Exch $R0 goto end NotInstalled: StrCpy $R0 "0" Exch $R0 end: FunctionEnd ; See if KfW Documentation is installed ; Returns: "1" if it is, 0 if it is not (on the stack) Function IsDocumentationInstalled Push $R0 StrCpy $R2 "Documentation" Call GetInstalledVersion Pop $R0 StrCmp $R0 "" NotInstalled StrCpy $R0 "1" Exch $R0 goto end NotInstalled: StrCpy $R0 "0" Exch $R0 end: FunctionEnd ;Check to see if any KfW component is installed ;Returns: Value on stack: "1" if it is, "0" if it is not Function IsAnyKfWInstalled Push $R0 Push $R1 Push $R2 Call IsClientInstalled Pop $R0 Call IsSDKInstalled Pop $R1 Call IsDocumentationInstalled Pop $R2 ; Now we must see if ANY of the $Rn values are 1 StrCmp $R0 "1" SomethingInstalled StrCmp $R1 "1" SomethingInstalled StrCmp $R2 "1" SomethingInstalled ;Nothing installed StrCpy $R0 "0" goto end SomethingInstalled: StrCpy $R0 "1" end: Pop $R2 Pop $R1 Exch $R0 FunctionEnd ;-------------------------------- ;Handle what must and what must not be installed Function .onSelChange ; If they install the SDK, they MUST install the client SectionGetFlags ${secSDK} $R0 IntOp $R0 $R0 & ${SF_SELECTED} StrCmp $R0 "1" MakeClientSelected goto end MakeClientSelected: SectionGetFlags ${secClient} $R0 IntOp $R0 $R0 | ${SF_SELECTED} SectionSetFlags ${secClient} $R0 end: FunctionEnd Function AddProvider Push $R0 Push $R1 ReadRegStr $R0 HKLM "SYSTEM\CurrentControlSet\Control\NetworkProvider\HWOrder" "ProviderOrder" Push $R0 StrCpy $R0 "MIT Kerberos" Push $R0 Call StrStr Pop $R0 StrCmp $R0 "" DoOther +1 ReadRegStr $R1 HKLM "SYSTEM\CurrentControlSet\Control\NetworkProvider\HWOrder" "ProviderOrder" StrCpy $R0 "$R1,MIT Kerberos" WriteRegStr HKLM "SYSTEM\CurrentControlSet\Control\NetworkProvider\HWOrder" "ProviderOrder" $R0 DoOther: ReadRegStr $R0 HKLM "SYSTEM\CurrentControlSet\Control\NetworkProvider\Order" "ProviderOrder" Push $R0 StrCpy $R0 "MIT Kerberos" Push $R0 Call StrStr Pop $R0 StrCmp $R0 "" +1 End ReadRegStr $R1 HKLM "SYSTEM\CurrentControlSet\Control\NetworkProvider\Order" "ProviderOrder" StrCpy $R0 "$R1,MIT Kerberos" WriteRegStr HKLM "SYSTEM\CurrentControlSet\Control\NetworkProvider\Order" "ProviderOrder" $R0 End: Pop $R1 Pop $R0 FunctionEnd Function un.RemoveProvider Push $R0 StrCpy $R0 "MIT Kerberos" Push $R0 StrCpy $R0 "SYSTEM\CurrentControlSet\Control\NetworkProvider\HWOrder" Call un.RemoveFromProvider StrCpy $R0 "MIT Kerberos" Push $R0 StrCpy $R0 "SYSTEM\CurrentControlSet\Control\NetworkProvider\Order" Call un.RemoveFromProvider Pop $R0 FunctionEnd Function un.RemoveFromProvider Exch $0 Push $1 Push $2 Push $3 Push $4 Push $5 Push $6 ReadRegStr $1 HKLM "$R0" "ProviderOrder" StrCpy $5 $1 1 -1 # copy last char StrCmp $5 "," +2 # if last char != , StrCpy $1 "$1," # append , Push $1 Push "$0," Call un.StrStr ; Find `$0,` in $1 Pop $2 ; pos of our dir StrCmp $2 "" unRemoveFromPath_done ; else, it is in path # $0 - path to add # $1 - path var StrLen $3 "$0," StrLen $4 $2 StrCpy $5 $1 -$4 # $5 is now the part before the path to remove StrCpy $6 $2 "" $3 # $6 is now the part after the path to remove StrCpy $3 $5$6 StrCpy $5 $3 1 -1 # copy last char StrCmp $5 "," 0 +2 # if last char == , StrCpy $3 $3 -1 # remove last char WriteRegStr HKLM "$R0" "ProviderOrder" $3 unRemoveFromPath_done: Pop $6 Pop $5 Pop $4 Pop $3 Pop $2 Pop $1 Pop $0 FunctionEnd krb5-1.16/src/windows/installer/nsis/site-local-tagged.nsi0000644000704600001450000000060013211554426023424 0ustar ghudsonlibuuid!define KFW_TARGETDIR %TARGETDIR% !define KFW_CONFIG_DIR %CONFIGDIR-NSI% !define KFW_MAJORVERSION %VERSION_MAJOR% !define KFW_MINORVERSION %VERSION_MINOR% !define KFW_PATCHLEVEL %VERSION_PATCH% !define CL_1310 !define RELEASE !define NOT_DEBUG !define BETA 1 !define SAMPLE_CONFIG_REALM "ATHENA.MIT.EDU" !define HTTP_CONFIG_URL "[Obtain a URL from your Kerberos administrator]" krb5-1.16/src/windows/installer/nsis/KfWConfigPage.ini0000644000704600001450000000137713211554426022553 0ustar ghudsonlibuuid[Settings] NumFields=7 [Field 1] Type=label Text=The Kerberos Client may utilize configuration files to assist in contacting KDCs. Where do you want to get these files? Left=0 Right=-1 Top=0 Bottom=20 [Field 2] Type=RadioButton Text=Use existing configuration files from a previous installation. Left=10 Right=-1 Top=25 Bottom=35 [Field 3] Type=RadioButton Text=Use packaged configuration files. Left=10 Right=-1 Top=40 Bottom=50 [Field 4] type=RadioButton Text=Download from web path: State=0 Left=10 Right=-1 Top=55 Bottom=65 [Field 5] type=Text State= Left=20 Right=-1 Top=70 Bottom=80 [Field 6] type=radioButton text=Select a directory Left=10 Right=-1 Top=85 Bottom=95 [Field 7] type=DirRequest Flags=PATH_MUST_EXIST Left=20 Right=-40 Top=100 Bottom=110 krb5-1.16/src/windows/installer/nsis/kfw.ico0000644000704600001450000006117613211554426020726 0ustar ghudsonlibuuid 00h ( 00 h^"00 %'  nM h^(0`wwsxpwpwxwwpwwwwpwwwxwwwwwwwwpwwwwxwwwpwwwwwwwwxwwwwxpxwwwwwwwwxwwwwwwwwxwwwwwwwx8wwwwwwwwwwwwwpxwwwwwwwwwxxwqxwxpwwwxqwuxxuwwxwxxwxwxqwwwqWwwwwwwwwwwwwxw?( @xwxppwwwwwxwwwwwwwwwwwxpwwwwwwwwwwwwwwwwwwxxwwwxwxxwxxxxxwxpwxwx0wwx( wwwpwxwwpwwpwwppwxpw?pppppwpp](0`r’RF27"!fJB2VBFfRLñ624ΞrҲocc(ذj6~rrn"ʸ*")8#&RNkLL_YY1ʾZJI rfztx7DbZN˾qTMnf¦>:6rjj?*)<*"¾[MNF"ʮCrmqO32z~촌b^^ƒjcSR¸(B&.hWW8&"Ŀ.?&&R.,zLFvZfNb¦~dZVB~NBؼr ΎzƪΦƪF6F~*"ޖ~ھ޾DB &ҚvOCBڶneF13 Bvr~*VF־\FH0#:jRZ ȔtʆjڪҶ}nn^64Z.~ZB,.ljɾʶn**İֺŹ 2qSRB&"}ĹʤJ>JF2:" º*^NF@®vh8ʾ̾OFF6"e<,,,,@999999999999999QaXXҍ%s[>~~~1ٻRQ}K4XOOc][[[>>~~~~~~1vDHJKKaHH 5 >V[[[>>~~~~~~11vm,\\\~~~~~~~111^v;P=ǔ\\\\>~~~~~~111&^v;0E*<\<<<>>~~111&vP0|*Ekd<<<<<``V[[>>>11111&%vPC*U<<<<```%V[[[>>>1111]]vvC 6*UU,<`````ƚ?[1111'vvRvvSͶ_w<```x>11}%eBBq*ggggKQ``Zubi>ٴŬzzggggn4` $~!cArzeeHH kgggg_Q`44QaSi/ArHzeBHH/6*gggk_+Z4Z4_aߧ}cO HHzz/BHOD6-kgggk+Y_4Z.ah&o&7cHHzz//BP2Ggggkk+Yw4ZaΑ#?&o&c zzz///BBOHC6gggk8Yu_4ZZ_%1FzzzzzBB/BBXBC6UgkUuu wZZY -&LL1WhHzzzz/zBB/BBD PP6ggE)u aQwwYhjLttOHzz/z///z///|PPP8,u aYww.ԄLttt]3Hzz///z/B/BzRmPPUUl2 aX. ttt&]Rl;zH//BB///BzDv;PP|Up0laX"Xnx5)ttt&]f2TB/B/B//B/v;;0SU062XxN#(8ttt&]RTTPB/BBBBB/Dv;;0p8q6CC2XXOO.N^88MMobRTTI BzBBBBB/vm88p6CC "OO N^tMM TTTTTITBzBBBBzRmq88CP OO HaQ&j&Rl2TTIIIITDzBBBB0|8SCPC OHHnn %%TTIIIII2BBBBD/rEUS0PPC O HHXnn3yl2TTIIIIIIBzBBBaDrU8=0PPPC Hz"__"Be'R{TT2TITIIIIBBB=PPPPCHHz/O__aDDDlCl6TTTTIIIIIIBBBu"pP;PPPHzzBH++ D2T2TTIITIIIIIzBBBuBe;;;PPzz/B/+DTT2TTTIIIIIII2zBBBuYzD;;;Pzz/BBBa_u;22TTTTTTIIIIIIITzBBBYX/D;;mBDD;Dmm00RRRRRvvvvvvvvvvvv񲲲.YODeD;mQQn_+YYu XOO H//DD;mm0 //+uH//BD;_n__+Yuu XXO H//DDD;mm000H//H/zz/BBD;__+Y.u aXO H//DD;m00mHez//BDDD++Y.. aXOO H//DD;mm06R//BBDD+Y.u XXO H///DD;mm006RR/BBBDY.u aXO H//DD;m00RRRvP//BBuu aXOO //DD;mm02RRvvB/Bu XXO H///DD;mm006RRvvvvmB XOO H//DD;mm02RRRvvvv2?( @n¦~N"."ZRVzjb6rpjnn*z޲J2*3yvvºj^^66"&, ONNE~~I"ľjffZ>⾖B~rr2"vv,^VRoVVnVrrn;4""rfú...rJF ‚b.2Ȯnnn~zzf^.fZZxjj}vzvfZ+TRR{ff7 n>*B>>ʒn6z>6־^>2fZ*<bNƶ>"6 fRNA**ʾֆ^rZRƮv^^N&"z~dVVzNV6&:"B"zZV>&"f~:&&vrv: B..F&zz."rn(ynnvbbVVVʚzJ~Bvfjxjf3f^b ƾ<ºrnr>">&*~vvrff:""rj)1p?000K`vlIb%0<`vv(lB u#pӝ!200K`vv((v"@j00~lv`lN"_QG8esJ2K~~NG|ws50K~~v i|CWddKKKv\n9.[L|r5dd}DKDna .kp'Gr= dfTZ]nBn..&?g%{h rd#PTZ䖜n..{pg64qrP}T[)B)H.g%{j AAPzo7%%X$ tZ-nRp%X wwݸѮ"ZX% Ui4j36P>Y"F%%pX iEj336}JVaFckX,uj3376{ov/k%R,[{pR:F///%7,&X6f}k ;Zc//A, XXp+PZZcy%,* X.%x^Syyy%јJ*4444444444444jP[.kOf A-J7[.* M[p{pkxmA-J7[.R @MZppkxm-J[.* j4ZF.xAJ7[.R j44ZFF AA-J7[.R j4ZF( nZF2B"vfNnnn.*zzzvvv 6..fbb222fffrrrzvz v^B"rnr&F.N&"~jZrnn~~~zvvB6.Z:.znb~vz..kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk#@_kZ I6:Skkkk%9&aUd!!D2kkk %R-2kc+'kM0]1Fk< 77Lk#0]k^7?j/ k ]*KkH7\1 k`;Wf24"JC1#k.;Wkk7>(i#k5GQ 7g(AEVOkN$?\TT Vk-a3+7 a-3kkO#38778a,kkkk#a 7+ kkkkk31kk](0` $00000000000000000000000000000000+ zrv]YZ]YY]XW]WS`ZOPD3                    e5ºŶîƪ(-:>CFC=61+)&%&&'&&(**/0/ IpjlĻɿǼľkQ<BCEDC;61-)%'&()*(*./.$F38<:7_+ nikpkm˽װ09G ECED?;5/+())*+*,,012!&I47`YYr;qnpokornq|x{Ŀٿh6$ F DEFEB<50-*+++,-.0225!$L42ókSP|lkQ"tptqnqsosuqu{wzpfD F GFED>82.+-..-01354 "8!%K10qSNlMLnlHEDe2vqttnsvquxswytx|vy߼+=F!ECFD?:53//100564 3!!6$&;" 3dZkKLnQNjZXb^^|Fxruwquysw{tx|vzx|y~? D C BAA>975120134 5"!7"!9$$-t[pflJLqPOcOMZNNldf222_. {uyysw{uy}w{x|z~z{~ӱ#H!A>?<88634228 !4"#0$";!~vhIIsRPgQO\PP[OOlbb[WWp$~ysw~x|z~{|}~Ҵ@?A;;;997343 2: 6 }HDkktsrq}pqzpqzqpvv0|vzz~{|}Ύx: ;589:::543)p gMͦmLJwUSmRQ`QQ^RR`SSaURvii0{z|~賌~+!(67:99<94  Z,ګ۴ոʴνfNJvTSmRRbRQ_QQ`RQcVSxln0y|:%)!777662"+l ڭұ̾»ĽjXTqQPmRSdRQ`QQbRQdVTzoo0|Ȣm)+6 9 !4 4"5"&Y+ӱͽϿοsihKKkSSdRQbSQcTSfVU}oo0ʧ@,#6$ 9!"5!#5"" WADZƼbGGjSSeRQbSQeTTgWW|mo0d8!'7% 8!#5#%9ȇi»äbJIfRRfRQcTRfVWgYZp``0ŷK;%&;%#7!$Y ܖ}Ž˫dLMdRQgSRdUSgZYULL|lg0³wf"F+,8!#33#!*meұêοǬ`JMdQPkUT]QRF?@QEDǸ0þ?..<"$@))?()4})ֽ˭ƿZGIeUS_PQIDFuVJ0ùƿNAA/5C(+>)(>&&<&&TEΫŽɿYGIcVXI@Anc͵0ú¢wLDK>H@'+<%'=&&<%&ÃcĸȻuk[LNTKNhPI0Z75TCG@&'>%&<&&;#'coWT\PRSEF0˿|E22[HH@&&?&%=%$:"&ēk^EFZNO~`[0ü͹POC;@[KH@&$=&%>'%9$$͝q\EHVJJ0üŽ}ZR33VLL[LGA&!='"=)#9%#\ILWHI0üļƿǑvN33D6G]HJ@(%:* :*& B~YGIZHH0üļƿĮŪa738058!&@',:!(umf[JK[GF0»ĽǿغgJ.(n>żlUM^OOYGD0ĽƿּӚvP,ȖpƾiRL]NNXHD0ƿ»ngSFGUHD0ĻPAARFCƼ0ƹbLE^QJ0qr0ʶ0ſ0̛00D裢00x0D۬0 0gk$#Ͷ$ ?( @ $000000000000000000000)$k Y( ս8D GE;1+&%&'()-0sqmr9nllpjlțy>HFA81('')+,/2 "rggOwttoknrnq55K!GD<3,++,-138$%{[Wu]\@?>e2yvvvquytwzuyy>7N%"GG?6/.0/35! 6"$,qgoVWtedkggG}zy{tw~w{{y~~5H!C>962239"#5! G%rVVzhfpefummSQQ}(|vzz~~~nB>:9552/V5$|ddut~vvwwxx0|}=# 6:::/ M[$#"L#d]i\_yji{nnvgi0Ļm=+ >+*bNýrkfYZzkje_a`WW0޲3!- nVsnj\]UUVVVVú0=B,- o+{icYSUvdZ0¸<&+9%'ɓoǿURRSSS0øf ?)+6"% zYRR0qJD D+(7!%s_TSĵ0úg///."K2*/!Ȯ}PPP0ƿŮ]<0,6sYROOO0Y)dPMNNN0ƾྕxMMM0RLL0ɾ00N0 0a0گk$$ ?(     /S________U8xna5.!"&U& dddrnq(B/// e%mmmeacytw67@#222?xxxqlo|wyF, G{vy-[:,G݆~iZM$Gݒ.w]AGݟmYG3GݪueL}}}GܴxxxGͱvvvGvvvsssAO*ÎƑ̓Փܓ$ krb5-1.16/src/windows/installer/nsis/utils.nsi0000644000704600001450000004576413211554426021323 0ustar ghudsonlibuuid;----------------------------------------------- ; Common Utility functions not specific to KFW ;------------------- ; Get the currently installed version and place it on the stack ; Modifies: Nothing Function GetInstalledVersion Push $R0 Push $R1 Push $R4 ReadRegStr $R0 HKLM "${KFW_REGKEY_ROOT}\$R2\CurrentVersion" "VersionString" StrCmp $R0 "" done done: Pop $R4 Pop $R1 Exch $R0 FunctionEnd ; Functions to get each component of the version number Function GetInstalledVersionMajor Push $R0 Push $R1 Push $R4 ReadRegDWORD $R0 HKLM "${KFW_REGKEY_ROOT}\$R2\CurrentVersion" "MajorVersion" StrCmp $R0 "" done done: Pop $R4 Pop $R1 Exch $R0 FunctionEnd Function GetInstalledVersionMinor Push $R0 Push $R1 Push $R4 ReadRegDWORD $R0 HKLM "${KFW_REGKEY_ROOT}\$R2\CurrentVersion" "MinorVersion" StrCmp $R0 "" done done: Pop $R4 Pop $R1 Exch $R0 FunctionEnd Function GetInstalledVersionPatch Push $R0 Push $R1 Push $R4 ReadRegDWORD $R0 HKLM "${KFW_REGKEY_ROOT}\$R2\CurrentVersion" "PatchLevel" StrCmp $R0 "" done done: Pop $R4 Pop $R1 Exch $R0 FunctionEnd ;-------------------------------- ; Macros ;-------------------------------- ; Macros ; Macro - Upgrade DLL File ; Written by Joost Verburg ; ------------------------ ; ; Parameters: ; LOCALFILE - Location of the new DLL file (on the compiler system) ; DESTFILE - Location of the DLL file that should be upgraded ; (on the user's system) ; TEMPBASEDIR - Directory on the user's system to store a temporary file ; when the system has to be rebooted. ; For Win9x support, this should be on the same volume as the ; DESTFILE! ; The Windows temp directory could be located on any volume, ; so you cannot use this directory. ; ; Define REPLACEDLL_NOREGISTER if you want to upgrade a DLL that does not ; have to be registered. ; ; Note: If you want to support Win9x, you can only use ; short filenames (8.3). ; ; Example of usage: ; !insertmacro ReplaceDLL "dllname.dll" "$SYSDIR\dllname.dll" "$SYSDIR" ; !macro ReplaceDLL LOCALFILE DESTFILE TEMPBASEDIR Push $R0 Push $R1 Push $R2 Push $R3 Push $R4 Push $R5 ;------------------------ ;Unique number for labels !define REPLACEDLL_UNIQUE ${__LINE__} ;------------------------ ;Copy the parameters used on run-time to a variable ;This allows the usage of variables as paramter StrCpy $R4 "${DESTFILE}" StrCpy $R5 "${TEMPBASEDIR}" ;------------------------ ;Check file and version ; IfFileExists $R4 0 replacedll.copy_${REPLACEDLL_UNIQUE} ;ClearErrors ; GetDLLVersionLocal "${LOCALFILE}" $R0 $R1 ; GetDLLVersion $R4 $R2 $R3 ;IfErrors replacedll.upgrade_${REPLACEDLL_UNIQUE} ; ;IntCmpU $R0 $R2 0 replacedll.done_${REPLACEDLL_UNIQUE} \ ; replacedll.upgrade_${REPLACEDLL_UNIQUE} ;IntCmpU $R1 $R3 replacedll.done_${REPLACEDLL_UNIQUE} \ ; replacedll.done_${REPLACEDLL_UNIQUE} \ ; replacedll.upgrade_${REPLACEDLL_UNIQUE} ;------------------------ ;Let's replace the DLL! SetOverwrite try ;replacedll.upgrade_${REPLACEDLL_UNIQUE}: !ifndef REPLACEDLL_NOREGISTER ;Unregister the DLL UnRegDLL $R4 !endif ;------------------------ ;Try to copy the DLL directly ClearErrors StrCpy $R0 $R4 Call :replacedll.file_${REPLACEDLL_UNIQUE} IfErrors 0 replacedll.noreboot_${REPLACEDLL_UNIQUE} ;------------------------ ;DLL is in use. Copy it to a temp file and Rename it on reboot. GetTempFileName $R0 $R5 Call :replacedll.file_${REPLACEDLL_UNIQUE} Rename /REBOOTOK $R0 $R4 ;------------------------ ;Register the DLL on reboot !ifndef REPLACEDLL_NOREGISTER WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\RunOnce" \ "Register $R4" 'rundll32.exe "$R4",DllRegisterServer' !endif Goto replacedll.done_${REPLACEDLL_UNIQUE} ;------------------------ ;DLL does not exist - just extract replacedll.copy_${REPLACEDLL_UNIQUE}: StrCpy $R0 $R4 Call :replacedll.file_${REPLACEDLL_UNIQUE} ;------------------------ ;Register the DLL replacedll.noreboot_${REPLACEDLL_UNIQUE}: !ifndef REPLACEDLL_NOREGISTER RegDLL $R4 !endif ;------------------------ ;Done replacedll.done_${REPLACEDLL_UNIQUE}: Pop $R5 Pop $R4 Pop $R3 Pop $R2 Pop $R1 Pop $R0 ;------------------------ ;End Goto replacedll.end_${REPLACEDLL_UNIQUE} ;------------------------ ;Called to extract the DLL replacedll.file_${REPLACEDLL_UNIQUE}: File /oname=$R0 "${LOCALFILE}" Return replacedll.end_${REPLACEDLL_UNIQUE}: ;------------------------ ;Restore settings SetOverwrite lastused !undef REPLACEDLL_UNIQUE !macroend ; GetParameters ; input, none ; output, top of stack (replaces, with e.g. whatever) ; modifies no other variables. Function GetParameters Push $R0 Push $R1 Push $R2 StrCpy $R0 $CMDLINE 1 StrCpy $R1 '"' StrCpy $R2 1 StrCmp $R0 '"' loop StrCpy $R1 ' ' ; we're scanning for a space instead of a quote loop: StrCpy $R0 $CMDLINE 1 $R2 StrCmp $R0 $R1 loop2 StrCmp $R0 "" loop2 IntOp $R2 $R2 + 1 Goto loop loop2: IntOp $R2 $R2 + 1 StrCpy $R0 $CMDLINE 1 $R2 StrCmp $R0 " " loop2 StrCpy $R0 $CMDLINE "" $R2 Pop $R2 Pop $R1 Exch $R0 FunctionEnd !verbose 3 !include "WinMessages.NSH" !verbose 4 Function GetSystemPath Push $0 Call IsNT Pop $0 StrCmp $0 1 GetPath_NT ReadEnvStr $0 PATH goto HavePath GetPath_NT: ReadRegStr $0 HKLM "SYSTEM\CurrentControlSet\Control\Session Manager\Environment" "PATH" HavePath: Exch $0 FunctionEnd ;==================================================== ; AddToSystemPath - Adds the given dir to the search path. ; Input - head of the stack ; Note - Win9x systems requires reboot ;==================================================== Function AddToSystemPath Exch $0 Push $1 Push $2 Push $3 # don't add if the path doesn't exist IfFileExists $0 "" AddToPath_done Call GetSystemPath Pop $1 Push "$1;" Push "$0;" Call StrStr Pop $2 StrCmp $2 "" 0 AddToPath_done Push "$1;" Push "$0\;" Call StrStr Pop $2 StrCmp $2 "" 0 AddToPath_done GetFullPathName /SHORT $3 $0 Push "$1;" Push "$3;" Call StrStr Pop $2 StrCmp $2 "" 0 AddToPath_done Push "$1;" Push "$3\;" Call StrStr Pop $2 StrCmp $2 "" 0 AddToPath_done Call IsNT Pop $1 StrCmp $1 1 AddToPath_NT ; Not on NT StrCpy $1 $WINDIR 2 FileOpen $1 "$1\autoexec.bat" a FileSeek $1 -1 END FileReadByte $1 $2 IntCmp $2 26 0 +2 +2 # DOS EOF FileSeek $1 -1 END # write over EOF FileWrite $1 "$\r$\nSET PATH=%PATH%;$3$\r$\n" FileClose $1 SetRebootFlag true Goto AddToPath_done AddToPath_NT: ReadRegStr $1 HKLM "SYSTEM\CurrentControlSet\Control\Session Manager\Environment" "PATH" StrCpy $2 $1 1 -1 # copy last char StrCmp $2 ";" 0 +2 # if last char == ; StrCpy $1 $1 -1 # remove last char StrCmp $1 "" AddToPath_NTdoIt StrCpy $0 "$1;$0" AddToPath_NTdoIt: WriteRegExpandStr HKLM "SYSTEM\CurrentControlSet\Control\Session Manager\Environment" "PATH" $0 SendMessage ${HWND_BROADCAST} ${WM_WININICHANGE} 0 "STR:Environment" /TIMEOUT=5000 AddToPath_done: Pop $3 Pop $2 Pop $1 Pop $0 FunctionEnd ;==================================================== ; RemoveFromPath - Remove a given dir from the path ; Input: head of the stack ;==================================================== Function un.RemoveFromSystemPath Exch $0 Push $1 Push $2 Push $3 Push $4 Push $5 Push $6 IntFmt $6 "%c" 26 # DOS EOF Call un.IsNT Pop $1 StrCmp $1 1 unRemoveFromPath_NT ; Not on NT StrCpy $1 $WINDIR 2 FileOpen $1 "$1\autoexec.bat" r GetTempFileName $4 FileOpen $2 $4 w GetFullPathName /SHORT $0 $0 StrCpy $0 "SET PATH=%PATH%;$0" Goto unRemoveFromPath_dosLoop unRemoveFromPath_dosLoop: FileRead $1 $3 StrCpy $5 $3 1 -1 # read last char StrCmp $5 $6 0 +2 # if DOS EOF StrCpy $3 $3 -1 # remove DOS EOF so we can compare StrCmp $3 "$0$\r$\n" unRemoveFromPath_dosLoopRemoveLine StrCmp $3 "$0$\n" unRemoveFromPath_dosLoopRemoveLine StrCmp $3 "$0" unRemoveFromPath_dosLoopRemoveLine StrCmp $3 "" unRemoveFromPath_dosLoopEnd FileWrite $2 $3 Goto unRemoveFromPath_dosLoop unRemoveFromPath_dosLoopRemoveLine: SetRebootFlag true Goto unRemoveFromPath_dosLoop unRemoveFromPath_dosLoopEnd: FileClose $2 FileClose $1 StrCpy $1 $WINDIR 2 Delete "$1\autoexec.bat" CopyFiles /SILENT $4 "$1\autoexec.bat" Delete $4 Goto unRemoveFromPath_done unRemoveFromPath_NT: ReadRegStr $1 HKLM "SYSTEM\CurrentControlSet\Control\Session Manager\Environment" "PATH" StrCpy $5 $1 1 -1 # copy last char StrCmp $5 ";" +2 # if last char != ; StrCpy $1 "$1;" # append ; Push $1 Push "$0;" Call un.StrStr ; Find `$0;` in $1 Pop $2 ; pos of our dir StrCmp $2 "" unRemoveFromPath_done ; else, it is in path # $0 - path to add # $1 - path var StrLen $3 "$0;" StrLen $4 $2 StrCpy $5 $1 -$4 # $5 is now the part before the path to remove StrCpy $6 $2 "" $3 # $6 is now the part after the path to remove StrCpy $3 $5$6 StrCpy $5 $3 1 -1 # copy last char StrCmp $5 ";" 0 +2 # if last char == ; StrCpy $3 $3 -1 # remove last char WriteRegExpandStr HKLM "SYSTEM\CurrentControlSet\Control\Session Manager\Environment" "PATH" $3 SendMessage ${HWND_BROADCAST} ${WM_WININICHANGE} 0 "STR:Environment" /TIMEOUT=5000 unRemoveFromPath_done: Pop $6 Pop $5 Pop $4 Pop $3 Pop $2 Pop $1 Pop $0 FunctionEnd ;==================================================== ; IsNT - Returns 1 if the current system is NT, 0 ; otherwise. ; Output: head of the stack ;==================================================== !macro IsNT un Function ${un}IsNT Push $0 ReadRegStr $0 HKLM "SOFTWARE\Microsoft\Windows NT\CurrentVersion" CurrentVersion StrCmp $0 "" 0 IsNT_yes ; we are not NT. Pop $0 Push 0 Return IsNT_yes: ; NT!!! Pop $0 Push 1 FunctionEnd !macroend !insertmacro IsNT "" !insertmacro IsNT "un." ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Uninstall stuff ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;==================================================== ; StrStr - Finds a given string in another given string. ; Returns -1 if not found and the pos if found. ; Input: head of the stack - string to find ; second in the stack - string to find in ; Output: head of the stack ;==================================================== !macro StrStr un Function ${un}StrStr Exch $R1 ; st=haystack,old$R1, $R1=needle Exch ; st=old$R1,haystack Exch $R2 ; st=old$R1,old$R2, $R2=haystack Push $R3 Push $R4 Push $R5 StrLen $R3 $R1 StrCpy $R4 0 ; $R1=needle ; $R2=haystack ; $R3=len(needle) ; $R4=cnt ; $R5=tmp loop: StrCpy $R5 $R2 $R3 $R4 StrCmp $R5 $R1 done StrCmp $R5 "" done IntOp $R4 $R4 + 1 Goto loop done: StrCpy $R1 $R2 "" $R4 Pop $R5 Pop $R4 Pop $R3 Pop $R2 Exch $R1 FunctionEnd !macroend !insertmacro StrStr "" !insertmacro StrStr "un." !ifdef ADDSHAREDDLLUSED ; AddSharedDLL ; ; Increments a shared DLLs reference count. ; Use by passing one item on the stack (the full path of the DLL). ; ; Usage: ; Push $SYSDIR\myDll.dll ; Call AddSharedDLL ; Function AddSharedDLL Exch $R1 Push $R0 ReadRegDword $R0 HKLM Software\Microsoft\Windows\CurrentVersion\SharedDLLs $R1 IntOp $R0 $R0 + 1 WriteRegDWORD HKLM Software\Microsoft\Windows\CurrentVersion\SharedDLLs $R1 $R0 Pop $R0 Pop $R1 FunctionEnd ; un.RemoveSharedDLL ; ; Decrements a shared DLLs reference count, and removes if necessary. ; Use by passing one item on the stack (the full path of the DLL). ; Note: for use in the main installer (not the uninstaller), rename the ; function to RemoveSharedDLL. ; ; Usage: ; Push $SYSDIR\myDll.dll ; Call un.RemoveSharedDLL ; Function un.RemoveSharedDLL Exch $R1 Push $R0 ReadRegDword $R0 HKLM Software\Microsoft\Windows\CurrentVersion\SharedDLLs $R1 StrCmp $R0 "" remove IntOp $R0 $R0 - 1 IntCmp $R0 0 rk rk uk rk: DeleteRegValue HKLM Software\Microsoft\Windows\CurrentVersion\SharedDLLs $R1 goto Remove uk: WriteRegDWORD HKLM Software\Microsoft\Windows\CurrentVersion\SharedDLLs $R1 $R0 Goto noremove remove: Delete /REBOOTOK $R1 noremove: Pop $R0 Pop $R1 FunctionEnd !endif ; GetWindowsVersion ; ; Based on Yazno's function, http://yazno.tripod.com/powerpimpit/ ; Updated by Joost Verburg ; ; Returns on top of stack ; ; Windows Version (95, 98, ME, NT x.x, 2000, XP, 2003) ; or ; '' (Unknown Windows Version) ; ; Usage: ; Call GetWindowsVersion ; Pop $R0 ; ; at this point $R0 is "NT 4.0" or whatnot Function GetWindowsVersion Push $R0 Push $R1 ClearErrors ReadRegStr $R0 HKLM \ "SOFTWARE\Microsoft\Windows NT\CurrentVersion" CurrentVersion IfErrors 0 lbl_winnt ; we are not NT ReadRegStr $R0 HKLM \ "SOFTWARE\Microsoft\Windows\CurrentVersion" VersionNumber StrCpy $R1 $R0 1 StrCmp $R1 '4' 0 lbl_error StrCpy $R1 $R0 3 StrCmp $R1 '4.0' lbl_win32_95 StrCmp $R1 '4.9' lbl_win32_ME lbl_win32_98 lbl_win32_95: StrCpy $R0 '95' Goto lbl_done lbl_win32_98: StrCpy $R0 '98' Goto lbl_done lbl_win32_ME: StrCpy $R0 'ME' Goto lbl_done lbl_winnt: StrCpy $R1 $R0 1 StrCmp $R1 '3' lbl_winnt_x StrCmp $R1 '4' lbl_winnt_x StrCpy $R1 $R0 3 StrCmp $R1 '5.0' lbl_winnt_2000 StrCmp $R1 '5.1' lbl_winnt_XP StrCmp $R1 '5.2' lbl_winnt_2003 lbl_error lbl_winnt_x: StrCpy $R0 "NT $R0" 6 Goto lbl_done lbl_winnt_2000: Strcpy $R0 '2000' Goto lbl_done lbl_winnt_XP: Strcpy $R0 'XP' Goto lbl_done lbl_winnt_2003: Strcpy $R0 '2003' Goto lbl_done lbl_error: Strcpy $R0 '' lbl_done: Pop $R1 Exch $R0 FunctionEnd ; Author: Lilla (lilla@earthlink.net) 2003-06-13 ; function IsUserAdmin uses plugin \NSIS\PlusgIns\UserInfo.dll ; This function is based upon code in \NSIS\Contrib\UserInfo\UserInfo.nsi ; This function was tested under NSIS 2 beta 4 (latest CVS as of this writing). ; ; Usage: ; Call IsUserAdmin ; Pop $R0 ; at this point $R0 is "true" or "false" ; Function IsUserAdmin Push $R0 Push $R1 Push $R2 ClearErrors UserInfo::GetName IfErrors Win9x Pop $R1 UserInfo::GetAccountType Pop $R2 StrCmp $R2 "Admin" 0 Continue ; Observation: I get here when running Win98SE. (Lilla) ; The functions UserInfo.dll looks for are there on Win98 too, ; but just don't work. So UserInfo.dll, knowing that admin isn't required ; on Win98, returns admin anyway. (per kichik) ; MessageBox MB_OK 'User "$R1" is in the Administrators group' StrCpy $R0 "true" Goto Done Continue: ; You should still check for an empty string because the functions ; UserInfo.dll looks for may not be present on Windows 95. (per kichik) StrCmp $R2 "" Win9x StrCpy $R0 "false" ;MessageBox MB_OK 'User "$R1" is in the "$R2" group' Goto Done Win9x: ; comment/message below is by UserInfo.nsi author: ; This one means you don't need to care about admin or ; not admin because Windows 9x doesn't either ;MessageBox MB_OK "Error! This DLL can't run under Windows 9x!" StrCpy $R0 "false" Done: ;MessageBox MB_OK 'User= "$R1" AccountType= "$R2" IsUserAdmin= "$R0"' Pop $R2 Pop $R1 Exch $R0 FunctionEnd Function RestartRequired Push $R1 ;Original Variable Push $R2 Push $R3 ;Counter Variable StrCpy $R1 "0" 1 ;initialize variable with 0 StrCpy $R3 "0" 0 ;Counter Variable ;First Check Current User RunOnce Key EnumRegValue $R2 HKCU "Software\Microsoft\Windows\CurrentVersion\RunOnce" $R3 StrCmp $R2 "" 0 FoundRestart ;Next Check Local Machine RunOnce Key EnumRegValue $R2 HKLM "Software\Microsoft\Windows\CurrentVersion\RunOnce" $R3 StrCmp $R2 "" 0 FoundRestart EnumRegValue $R2 HKLM "SYSTEM\CurrentControlSet\Control\Session Manager\FileRenameOperations" $R3 StrCmp $R2 "" 0 FoundRestart NextValue: EnumRegValue $R2 HKLM "SYSTEM\CurrentControlSet\Control\Session Manager" $R3 StrCmp $R2 "" ExitFunc 0 StrCmp $R2 "PendingFileRenameOperations" FoundRestart 0 IntOp $R3 $R3 + 1 Goto NextValue FoundRestart: StrCpy $R1 "1" 1 ExitFunc: Pop $R3 Pop $R2 Exch $R1 FunctionEnd ; GetParent ; input, top of stack (e.g. C:\Program Files\Poop) ; output, top of stack (replaces, with e.g. C:\Program Files) ; modifies no other variables. ; ; Usage: ; Push "C:\Program Files\Directory\Whatever" ; Call GetParent ; Pop $R0 ; ; at this point $R0 will equal "C:\Program Files\Directory" Function GetParent Exch $R0 Push $R1 Push $R2 Push $R3 StrCpy $R1 0 StrLen $R2 $R0 loop: IntOp $R1 $R1 + 1 IntCmp $R1 $R2 get 0 get StrCpy $R3 $R0 1 -$R1 StrCmp $R3 "\" get Goto loop get: StrCpy $R0 $R0 -$R1 Pop $R3 Pop $R2 Pop $R1 Exch $R0 FunctionEnd ; SearchPath (path, filename) ; input: ; top of stack is the filename ; top of stack minus one is the path ; output: ; top of stack is a fully qualified path or the number "0" ; ; Usage: ; Push "semicolon delimited path" ; Push "filename" ; Call SearchPath ; Pop $R0 ; fqpn ; StrCmp $R0 "" failed ; ; Function SearchPath Exch $R0 ; input - filename Exch Exch $R1 ; input - semicolon delimited path Push $R3 ; worker - index to current end character Push $R4 ; worker - length of $R1 Push $R5 ; worker - copy of directory string/fqpn to search for Push $R6 ; worker - single charcter copy or find handle StrCpy $R3 0 ; init character index StrLen $R4 $R1 ; determine length of semicolon delimited path StrCpy $R5 "" ; init return value findDir: ; find a semi-colon or end of string IntCmp $R3 $R4 exit 0 exit ; we are done if no unprocessed string left loop: StrCpy $R6 $R1 1 $R3 ; get the next character StrCmp $R6 ";" foundDir ; if it is semi-colon, we have found a dir IntOp $R3 $R3 + 1 ; increment index IntCmp $R3 $R4 foundDir ; if we are at end of string, we have a dir Goto loop ; still more chars in this dir foundDir: StrCpy $R5 $R1 $R3 ; copy the dir to $R5 StrCpy $R5 "$R5\$R0" ; construct fqpn IfFileExists $R5 exit ; if file exists we are done StrCpy $R5 "" ; reset return value to null string IntOp $R4 $R4 - $R3 ; compute maxlen of new delimited path IntCmp $R4 0 exit ; no more path left, exit IntOp $R3 $R3 + 1 ; Increment $R3 past the semi-colon StrCpy $R1 $R1 $R4 $R3 ; remove dir from the delimited path StrCpy $R3 0 ; index back to start of new delimited path goto findDir ; get another directory to look in exit: Pop $R6 Exch $R5 ; output - fully qualified pathname Exch Pop $R4 Exch Pop $R3 Exch Pop $R1 Exch Pop $R0 FunctionEnd krb5-1.16/src/windows/installer/nsis/killer.cpp0000644000704600001450000002666213211554426021432 0ustar ghudsonlibuuid/* Process Killer for NSIS script Rob Murawski Released under terms of IBM Open Source agreement for OpenAFS */ #include #include #include #include char strProcessName[256]; typedef BOOL (CALLBACK *PROCENUMPROC)(DWORD, WORD, LPSTR, LPARAM); typedef struct { DWORD dwPID; PROCENUMPROC lpProc; DWORD lParam; BOOL bEnd; } EnumInfoStruct; BOOL WINAPI EnumProcs(PROCENUMPROC lpProc, LPARAM lParam); BOOL WINAPI Enum16(DWORD dwThreadId, WORD hMod16, WORD hTask16, PSZ pszModName, PSZ pszFileName, LPARAM lpUserDefined); // // The EnumProcs function takes a pointer to a callback function // that will be called once per process with the process filename // and process ID. // // lpProc -- Address of callback routine. // // lParam -- A user-defined LPARAM value to be passed to // the callback routine. // // Callback function definition: // BOOL CALLBACK Proc(DWORD dw, WORD w, LPCSTR lpstr, LPARAM lParam); // BOOL WINAPI EnumProcs(PROCENUMPROC lpProc, LPARAM lParam) { OSVERSIONINFO osver; HINSTANCE hInstLib = NULL; HINSTANCE hInstLib2 = NULL; HANDLE hSnapShot = NULL; LPDWORD lpdwPIDs = NULL; PROCESSENTRY32 procentry; BOOL bFlag; DWORD dwSize; DWORD dwSize2; DWORD dwIndex; HMODULE hMod; HANDLE hProcess; char szFileName[MAX_PATH]; EnumInfoStruct sInfo; // ToolHelp Function Pointers. HANDLE (WINAPI *lpfCreateToolhelp32Snapshot)(DWORD, DWORD); BOOL (WINAPI *lpfProcess32First)(HANDLE, LPPROCESSENTRY32); BOOL (WINAPI *lpfProcess32Next)(HANDLE, LPPROCESSENTRY32); // PSAPI Function Pointers. BOOL (WINAPI *lpfEnumProcesses)(DWORD *, DWORD, DWORD *); BOOL (WINAPI *lpfEnumProcessModules)(HANDLE, HMODULE *, DWORD, LPDWORD); DWORD (WINAPI *lpfGetModuleBaseName)(HANDLE, HMODULE, LPTSTR, DWORD); // VDMDBG Function Pointers. INT (WINAPI *lpfVDMEnumTaskWOWEx)(DWORD, TASKENUMPROCEX, LPARAM); // Retrieve the OS version osver.dwOSVersionInfoSize = sizeof(osver); if (!GetVersionEx(&osver)) return FALSE; // If Windows NT 4.0 if (osver.dwPlatformId == VER_PLATFORM_WIN32_NT && osver.dwMajorVersion == 4) { __try { // Get the procedure addresses explicitly. We do // this so we don't have to worry about modules // failing to load under OSes other than Windows NT 4.0 // because references to PSAPI.DLL can't be resolved. hInstLib = LoadLibraryA("PSAPI.DLL"); if (hInstLib == NULL) __leave; hInstLib2 = LoadLibraryA("VDMDBG.DLL"); if (hInstLib2 == NULL) __leave; // Get procedure addresses. lpfEnumProcesses = (BOOL (WINAPI *)(DWORD *, DWORD, DWORD*)) GetProcAddress(hInstLib, "EnumProcesses"); lpfEnumProcessModules = (BOOL (WINAPI *)(HANDLE, HMODULE *, DWORD, LPDWORD)) GetProcAddress(hInstLib, "EnumProcessModules"); lpfGetModuleBaseName = (DWORD (WINAPI *)(HANDLE, HMODULE, LPTSTR, DWORD)) GetProcAddress(hInstLib, "GetModuleBaseNameA"); lpfVDMEnumTaskWOWEx = (INT (WINAPI *)(DWORD, TASKENUMPROCEX, LPARAM)) GetProcAddress(hInstLib2, "VDMEnumTaskWOWEx"); if (lpfEnumProcesses == NULL || lpfEnumProcessModules == NULL || lpfGetModuleBaseName == NULL || lpfVDMEnumTaskWOWEx == NULL) __leave; // // Call the PSAPI function EnumProcesses to get all of the // ProcID's currently in the system. // // NOTE: In the documentation, the third parameter of // EnumProcesses is named cbNeeded, which implies that you // can call the function once to find out how much space to // allocate for a buffer and again to fill the buffer. // This is not the case. The cbNeeded parameter returns // the number of PIDs returned, so if your buffer size is // zero cbNeeded returns zero. // // NOTE: The "HeapAlloc" loop here ensures that we // actually allocate a buffer large enough for all the // PIDs in the system. // dwSize2 = 256 * sizeof(DWORD); do { if (lpdwPIDs) { HeapFree(GetProcessHeap(), 0, lpdwPIDs); dwSize2 *= 2; } lpdwPIDs = (LPDWORD) HeapAlloc(GetProcessHeap(), 0, dwSize2); if (lpdwPIDs == NULL) __leave; if (!lpfEnumProcesses(lpdwPIDs, dwSize2, &dwSize)) __leave; } while (dwSize == dwSize2); // How many ProcID's did we get? dwSize /= sizeof(DWORD); // Loop through each ProcID. for (dwIndex = 0; dwIndex < dwSize; dwIndex++) { szFileName[0] = 0; // Open the process (if we can... security does not // permit every process in the system to be opened). hProcess = OpenProcess( PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, lpdwPIDs[dwIndex]); if (hProcess != NULL) { // Here we call EnumProcessModules to get only the // first module in the process. This will be the // EXE module for which we will retrieve the name. if (lpfEnumProcessModules(hProcess, &hMod, sizeof(hMod), &dwSize2)) { // Get the module name if (!lpfGetModuleBaseName(hProcess, hMod, szFileName, sizeof(szFileName))) szFileName[0] = 0; } CloseHandle(hProcess); } // Regardless of OpenProcess success or failure, we // still call the enum func with the ProcID. if (!lpProc(lpdwPIDs[dwIndex], 0, szFileName, lParam)) break; // Did we just bump into an NTVDM? if (_stricmp(szFileName, "NTVDM.EXE") == 0) { // Fill in some info for the 16-bit enum proc. sInfo.dwPID = lpdwPIDs[dwIndex]; sInfo.lpProc = lpProc; sInfo.lParam = (DWORD) lParam; sInfo.bEnd = FALSE; // Enum the 16-bit stuff. lpfVDMEnumTaskWOWEx(lpdwPIDs[dwIndex], (TASKENUMPROCEX) Enum16, (LPARAM) &sInfo); // Did our main enum func say quit? if (sInfo.bEnd) break; } } } __finally { if (hInstLib) FreeLibrary(hInstLib); if (hInstLib2) FreeLibrary(hInstLib2); if (lpdwPIDs) HeapFree(GetProcessHeap(), 0, lpdwPIDs); } // If any OS other than Windows NT 4.0. } else if (osver.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS || (osver.dwPlatformId == VER_PLATFORM_WIN32_NT && osver.dwMajorVersion > 4)) { __try { hInstLib = LoadLibraryA("Kernel32.DLL"); if (hInstLib == NULL) __leave; // If NT-based OS, load VDMDBG.DLL. if (osver.dwPlatformId == VER_PLATFORM_WIN32_NT) { hInstLib2 = LoadLibraryA("VDMDBG.DLL"); if (hInstLib2 == NULL) __leave; } // Get procedure addresses. We are linking to // these functions explicitly, because a module using // this code would fail to load under Windows NT, // which does not have the Toolhelp32 // functions in KERNEL32.DLL. lpfCreateToolhelp32Snapshot = (HANDLE (WINAPI *)(DWORD,DWORD)) GetProcAddress(hInstLib, "CreateToolhelp32Snapshot"); lpfProcess32First = (BOOL (WINAPI *)(HANDLE,LPPROCESSENTRY32)) GetProcAddress(hInstLib, "Process32First"); lpfProcess32Next = (BOOL (WINAPI *)(HANDLE,LPPROCESSENTRY32)) GetProcAddress(hInstLib, "Process32Next"); if (lpfProcess32Next == NULL || lpfProcess32First == NULL || lpfCreateToolhelp32Snapshot == NULL) __leave; if (osver.dwPlatformId == VER_PLATFORM_WIN32_NT) { lpfVDMEnumTaskWOWEx = (INT (WINAPI *)(DWORD, TASKENUMPROCEX, LPARAM)) GetProcAddress(hInstLib2, "VDMEnumTaskWOWEx"); if (lpfVDMEnumTaskWOWEx == NULL) __leave; } // Get a handle to a Toolhelp snapshot of all processes. hSnapShot = lpfCreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); if (hSnapShot == INVALID_HANDLE_VALUE) { FreeLibrary(hInstLib); return FALSE; } // Get the first process' information. procentry.dwSize = sizeof(PROCESSENTRY32); bFlag = lpfProcess32First(hSnapShot, &procentry); // While there are processes, keep looping. while (bFlag) { // Call the enum func with the filename and ProcID. if (lpProc(procentry.th32ProcessID, 0, procentry.szExeFile, lParam)) { // Did we just bump into an NTVDM? if (_stricmp(procentry.szExeFile, "NTVDM.EXE") == 0) { // Fill in some info for the 16-bit enum proc. sInfo.dwPID = procentry.th32ProcessID; sInfo.lpProc = lpProc; sInfo.lParam = (DWORD) lParam; sInfo.bEnd = FALSE; // Enum the 16-bit stuff. lpfVDMEnumTaskWOWEx(procentry.th32ProcessID, (TASKENUMPROCEX) Enum16, (LPARAM) &sInfo); // Did our main enum func say quit? if (sInfo.bEnd) break; } procentry.dwSize = sizeof(PROCESSENTRY32); bFlag = lpfProcess32Next(hSnapShot, &procentry); } else bFlag = FALSE; } } __finally { if (hInstLib) FreeLibrary(hInstLib); if (hInstLib2) FreeLibrary(hInstLib2); } } else return FALSE; // Free the library. FreeLibrary(hInstLib); return TRUE; } BOOL WINAPI Enum16(DWORD dwThreadId, WORD hMod16, WORD hTask16, PSZ pszModName, PSZ pszFileName, LPARAM lpUserDefined) { BOOL bRet; EnumInfoStruct *psInfo = (EnumInfoStruct *)lpUserDefined; bRet = psInfo->lpProc(psInfo->dwPID, hTask16, pszFileName, psInfo->lParam); if (!bRet) psInfo->bEnd = TRUE; return !bRet; } BOOL CALLBACK MyProcessEnumerator(DWORD dwPID, WORD wTask, LPCSTR szProcess, LPARAM lParam) { /*if (wTask == 0) printf("%5u %s\n", dwPID, szProcess); else printf(" %5u %s\n", wTask, szProcess);*/ if(stricmp(szProcess,strProcessName)==0) { HANDLE hProcess=OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPID); if(hProcess!=NULL) TerminateProcess(hProcess,0); CloseHandle(hProcess); } return TRUE; } void main(int argc, char *argv[]) { if(argc<2) { printf("Please specify the process name to kill\n"); return; } if(strlen((argv[1]))<255) strcpy(strProcessName,(argv[1])); else return; EnumProcs((PROCENUMPROC) MyProcessEnumerator, 0); } krb5-1.16/src/windows/installer/nsis/nsi-includes-tagged.nsi0000644000704600001450000000041713211554426023773 0ustar ghudsonlibuuid!define KFW_TARGETDIR %BUILDDIR%\target !define KFW_EXTRADIR "%BUILDDIR%\target" !define KFW_VERSION %VERSION_MAJOR%.%VERSION_MINOR% !define KFW_MAJORVERSION %VERSION_MAJOR% !define KFW_MINORVERSION %VERSION_MINOR% !define KFW_PATCHLEVEL %VERSION_PATCH% !define CL_1310 krb5-1.16/src/windows/installer/nsis/kfw.nsi0000644000704600001450000000061213211554426020731 0ustar ghudsonlibuuid;KfW Install Script for NSIS ; ; Written by Jeffrey Altman ; based on the OpenAFS installer written by Rob Murawski ; ;Based on: ;NSIS Modern User Interface version 1.63 ;MultiLanguage Example Script ;Written by Joost Verburg ; ; This version compiles with NSIS v2.0b4 !include site-local.nsi !include "MUI.nsh" !include Sections.nsh !include "kfw-fixed.nsi" krb5-1.16/src/windows/installer/nsis/KfWConfigPage2.ini0000644000704600001450000000055113211554426022626 0ustar ghudsonlibuuid[Settings] NumFields=3 [Field 1] Type=label Text=The Network Identity Manager maybe installed with the following optional functionality. Please check those items you wish activated. Left=0 Right=-1 Top=0 Bottom=20 [Field 2] Type=CheckBox Text=Autostart the Network Identity Manager each time you login to Windows. State=1 Left=10 Right=-1 Top=25 Bottom=35 krb5-1.16/src/windows/installer/wix/0000755000704600001450000000000013211554426017263 5ustar ghudsonlibuuidkrb5-1.16/src/windows/installer/wix/runtime_debug.wxi0000644000704600001450000000052413211554426022646 0ustar ghudsonlibuuid krb5-1.16/src/windows/installer/wix/site-local-tagged.wxi0000644000704600001450000000712013211554426023301 0ustar ghudsonlibuuid krb5-1.16/src/windows/installer/wix/files.wxi0000644000704600001450000015416313211554426021130 0ustar ghudsonlibuuid KRB5CONFIG KRB5CCNAME KRB5PRESERVEIDENTITY kerberos.mit.edu kerberos-1.mit.edu kerberos-2.mit.edu kerberos-1.csail.mit.edu kerberos-2.csail.mit.edu LEASHAFSSTATUS LEASHCREATEMISSINGCONFIG LEASHAUTORENEWTICKETS LEASHLOCKFILELOCATIONS LEASHMSLSAIMPORT LEASHLIFETIME LEASHRENEWTILL LEASHRENEWABLE LEASHFORWARDABLE LEASHNOADDRESSES LEASHPROXIABLE LEASHPUBLICIP LEASHUSEKRB4 LEASHHIDEKINITOPTIONS LEASHLIFEMIN LEASHLIFEMAX LEASHRENEWMIN LEASHRENEWMAX LEASHUPPERCASEREALM LEASHTIMEHOST LEASHPRESERVEKINITOPTIONS krb5-1.16/src/windows/installer/wix/kfw.wxs0000755000704600001450000002737213211554426020633 0ustar ghudsonlibuuid Privileged VersionNT >= 501 (Not (VersionNT = 501)) Or (ServicePackLevel >= 3) (Not (VersionNT = 600)) Or (ServicePackLevel >= 2) USELEASH Or USENETIDMGR Not (USELEASH And USENETIDMGR) (Not Installed) And (UPGRADEPISMERE Or UPGRADEKFW Or UPGRADEKFW64) SYSTEMKRB5INI <> "" UILevel = 0 And (Not Installed) And (CCP_Success <> 1) UPGRADENSIS <> "" And UILevel >= 4 UPGRADENSIS <> "" And UILevel < 4 VersionNT >= 500 And &feaKfwClient=3 VersionNT >= 500 And &feaKfwClient=3 VersionNT >= 500 And &feaKfwClient=2 &feaKfwClient=3 &feaKfwClient=3 &feaKfwClient=2 kpLeash leash32.exe Leash Ticket Manager kpNetIDMgr netidmgr.exe Network Identity Manager kpKrbcc krbcc32s.exe Kerberos Credential Cache kpKrbcc64 krbcc64s.exe Kerberos Credential Cache kpK95 k95.exe Kermit 95 kpK95g k95g.exe Kermit 95 GUI kpkrb5 krb5.exe Kerberos Client kpgss gss.exe GSSAPI Test Client kpafscreds afscreds.exe AFS Credentials Manager kccapiserver ccapiserver.exe Credentials Cache API Server kMITKerberos MIT Kerberos.exe MIT Kerberos Ticket Manager krb5-1.16/src/windows/installer/wix/krb5.ini0000644000704600001450000000000013211554426020615 0ustar ghudsonlibuuidkrb5-1.16/src/windows/installer/wix/Makefile0000644000704600001450000000154213211554426020725 0ustar ghudsonlibuuid # Build language LANG=1033 # Program macros CANDLE=candle -nologo LIGHT=light -nologo CD=cd RM=del MAKE=nmake -nologo # Targets OUTPATH=. OBJFILE=$(OUTPATH)\kfw.wixobj MSIFILE=$(OUTPATH)\kfw.msi WIXINCLUDES= \ config.wxi \ features.wxi \ files.wxi \ property.wxi \ runtime.wxi \ site-local.wxi \ lang\strings_$(LANG).wxl \ lang\ui_$(LANG).wxi \ lang\config_$(LANG).wxi CUSTOMDLL=custom\custom.dll all: $(MSIFILE) $(OBJFILE): kfw.wxs $(WIXINCLUDES) $(CANDLE) -out $@ kfw.wxs \ "-dDate=%DATE%" \ "-dTime=%TIME%" \ -dBuildLang=$(LANG) $(MSIFILE): $(OBJFILE) $(CUSTOMDLL) $(LIGHT) -out $@ $(OBJFILE) \ -loc lang\strings_$(LANG).wxl -ext WixUtilExtension.dll $(CUSTOMDLL): custom\custom.cpp $(CD) custom $(MAKE) -f custom.cpp $(CD) .. clean: $(RM) $(OBJFILE) $(RM) $(MSIFILE) $(CD) custom $(MAKE) -f custom.cpp clean $(CD) .. krb5-1.16/src/windows/installer/wix/runtime.wxi0000644000704600001450000000112113211554426021472 0ustar ghudsonlibuuid krb5-1.16/src/windows/installer/wix/lang/0000755000704600001450000000000013211554426020204 5ustar ghudsonlibuuidkrb5-1.16/src/windows/installer/wix/lang/strings_1033.wxl0000644000704600001450000001027013211554426023077 0ustar ghudsonlibuuid Kerberos for Windows (64-bit) KFW64 Kerberos for Windows (32-bit) KFW32 MIT Debug/Checked Beta Massachusetts Institute of Technology Kerberos for Windows Kerberos for Windows Client Kerberos client utilities, libraries and documentation Debug symbols Debugging symbols for Kerberos for Windows components. Leash Credentials Manager Leash credentials manager SDK Libraries and header files for developing software with Kerberos Documentation Documentation You need administrative privileges to install Kerberos for Windows This product requires Windows XP or Higher. The current operating system is not supported. This product requires Windows XP Service Pack 3 This product requires Windows Vista Service Pack 2 Neither Leash nor Network Identity Manager has been selected for this package. Please contact your administrator or the provider of this installation package to resolve this issue. Both Leash and Network Identity Manager has been selected for this package. Only one of these can be selected at one time. Please contact your administrator or the provider of this installation package to resolve this issue. The NSIS based installation of Kerberos for Windows could not be uninstalled because the NSIS uninstaller must be run in Full UI mode. Kerberos for Windows requires Microsoft Internet Explorer version 5.01 or higher. Please resolve this and run the installer again. Build of This build of Kerberos for Windows is for 64-bit Windows versions. Please install the 32-bit version on this operating system. This build of Kerberos for Windows is for 32-bit Windows versions. Please install the 64-bit version on this operating system. krb5-1.16/src/windows/installer/wix/lang/config_1033.wxi0000644000704600001450000000655513211554426022663 0ustar ghudsonlibuuid krb5-1.16/src/windows/installer/wix/lang/ui_1033.wxi0000644000704600001450000032135513211554426022031 0ustar ghudsonlibuuid 1 1 1 The [Wizard] will create a server image of [ProductName], at a specified network location. Click Next to continue or Cancel to exit the [Wizard]. {\VerdanaBold13}Welcome to the [ProductName] [Wizard] 1 Click the Finish button to exit the [Wizard]. {\VerdanaBold13}Completing the [ProductName] [Wizard] 1 {\VerdanaBold13}[ProductName] [Wizard] ended prematurely [ProductName] setup ended prematurely because of an error. Your system has not been modified. To install this program at a later time, please run the installation again. Click the Finish button to exit the [Wizard]. 1 Please wait while the [Wizard] prepares to guide you through the installation. {\VerdanaBold13}Welcome to the [ProductName] [Wizard] 1 Please wait while the [Wizard] [Progress2] [ProductName]. This may take several minutes. [DlgTitleFont][Progress1] [ProductName] 1 {\VerdanaBold13}[ProductName] [Wizard] was interrupted [ProductName] setup was interrupted. Your system has not been modified. To install this program at a later time, please run the installation again. Click the Finish button to exit the [Wizard]. 1 1 1 1 1 1 Browse to the destination folder [DlgTitleFont]Change current destination folder &Enter a new network location or click Browse to browse to one. 1 1 1 1 1 Please specify a network location for the server image of [ProductName] product [DlgTitleFont]Network Location 1 1 1 1 1 1 Browse to the destination folder [DlgTitleFont]Change current destination folder 1 1 Are you sure you want to cancel [ProductName] installation? 1 Installed 1 Disk &Usage 1 InstallMode = "Change" InstallMode = "Custom" ( &feaKfwClient <> 3 And !feaKfwClient <> 3 ) And Not FoundProcesses ( &feaKfwClient <> 3 And !feaKfwClient <> 3 ) And FoundProcesses &feaKfwClient = 3 Or !feaKfwClient = 3 1 Click on the icons in the tree below to change the way features will be installed. Select the way you want features to be installed. [DlgTitleFont]Custom Setup Multiline description of the currently selected item. The size of the currently selected item. <The selection's path> Installed Installed 1 The highlighted volumes (if any) do not have enough disk space available for the currently selected features. You can either remove some files from the highlighted volumes, or choose to install less features onto local drive(s), or select different destination drive(s). The disk space required for the installation of the selected features. [DlgTitleFont]Disk Space Requirements {120}{70}{70}{70}{70} 1 1 1 1 1 1 1 1 1 1 The following applications are using files that need to be updated by this setup. Close these applications and then click Retry to continue the installation or Cancel to exit it. Some files that need to be updated are currently in use. [DlgTitleFont]Files in Use (InstallMode = "Custom" OR InstallMode = "Change") AND &feaKfwClient <> 3 And !feaKfwClient <> 3 (InstallMode = "Custom" OR InstallMode = "Change") AND ( &feaKfwClient = 3 Or !feaKfwClient = 3 ) InstallMode = "Repair" InstallMode = "Typical" OR InstallMode = "Complete" 1 1 The following applications are currently running and need to be closed in order for the installation to progress. Please close them manually or click Next to let [Wizard] close them for you. Some running processes need to be closed. [DlgTitleFont]Close Running Proccesses 1 [ProductName] requires a newer version of iphlpapi.dll than the one that is currently installed on this computer. This file is included in Microsoft Internet Explorer version 5.01 or later. Please install this and re-run the [ProductName] installer. [ProgramName] requires a newer version of iphlpapi.dll [DlgTitleFont]Compliance Check Failed! 1 IAgree = "Yes" AND ShowUserRegistrationDlg = 1 CostingComplete = 1 IAgree = "Yes" AND ShowUserRegistrationDlg <> 1 AND (UPGRADEPISMERE OR UPGRADEKFW OR UPGRADENSIS <> "") IAgree = "Yes" AND ShowUserRegistrationDlg <> 1 AND NOT (UPGRADEPISMERE OR UPGRADEKFW OR UPGRADENSIS <> "") IAgree <> "Yes" IAgree = "Yes" 1 Please read the following license agreement carefully [DlgTitleFont]End-User License Agreement [DlgTitleFont]&Modify 1 1 1 1 [DlgTitleFont]Re&pair 1 1 1 1 [DlgTitleFont]&Remove 1 1 1 1 1 1 Select the operation you wish to perform. [DlgTitleFont]Modify, Repair or Remove installation Allows users to change the way features are installed. Removes [ProductName] from your computer. Repairs errors in the most recent installation state - fixes missing or corrupt files, shortcuts and registry entries. CostingComplete = 1 1 1 The [Wizard] will allow you to change the way [ProductName] features are installed on your computer or even to remove [ProductName] from your computer. Click Next to continue or Cancel to exit the [Wizard]. {\VerdanaBold13}Welcome to the [ProductName] [Wizard] 1 The highlighted volumes do not have enough disk space available for the currently selected features. You can either remove some files from the highlighted volumes, or choose to install less features onto local drive(s), or select different destination drive(s). Disk space required for the installation exceeds available disk space. [DlgTitleFont]Out of Disk Space {120}{70}{70}{70}{70} 1 1 1 The highlighted volumes do not have enough disk space available for the currently selected features. You can either remove some files from the highlighted volumes, or choose to install less features onto local drive(s), or select different destination drive(s). Disk space required for the installation exceeds available disk space. [DlgTitleFont]Out of Disk Space {120}{70}{70}{70}{70} Alternatively, you may choose to disable the installer's rollback functionality. This allows the installer to restore your computer's original state should the installation be interrupted in any way. Click Yes if you wish to take the risk to disable rollback. 1 1 ShowUserRegistrationDlg <> 1 ShowUserRegistrationDlg = 1 Other versions of [ProductName] need to be removed. Click Confirm to uninstall the following version of Kerberos for Windows installed on this computer. Installation of [ProductName] cannot continue unless this program is removed. [DlgTitleFont]Uninstall previous versions CostingComplete = 1 OutOfDiskSpace <> 1 OutOfDiskSpace = 1 AND OutOfNoRbDiskSpace = 0 AND (PROMPTROLLBACKCOST="P" OR NOT PROMPTROLLBACKCOST) OutOfDiskSpace = 1 AND OutOfNoRbDiskSpace = 0 AND PROMPTROLLBACKCOST="D" OutOfDiskSpace = 1 AND OutOfNoRbDiskSpace = 0 AND PROMPTROLLBACKCOST="D" (OutOfDiskSpace = 1 AND OutOfNoRbDiskSpace = 1) OR (OutOfDiskSpace = 1 AND PROMPTROLLBACKCOST="F") 1 The [Wizard] will complete the installation of [ProductName] on your computer. Click Install to continue or Cancel to exit the [Wizard]. {\VerdanaBold13}Resuming the [ProductName] [Wizard] [DlgTitleFont]&Typical 1 1 Not FoundProcesses FoundProcesses [DlgTitleFont]C&ustom 1 1 [DlgTitleFont]C&omplete 1 1 Not FoundProcesses FoundProcesses ShowUserRegistrationDlg <> 1 AND NOT (UPGRADEPISMERE OR UPGRADEKFW) ShowUserRegistrationDlg = 1 AND NOT (UPGRADEPISMERE OR UPGRADEKFW) UPGRADEPISMERE OR UPGRADEKFW OR UPGRADENSIS <> "" 1 Choose the setup type that best suits your needs [DlgTitleFont]Choose Setup Type All program features will be installed. (Requires most disk space) Allows users to choose which program features will be installed and where they will be installed. Recommended for advanced users. Installs the most common program features. Recommended for most users. CD &Key: 1 0 CostingComplete = 1 ProductID 1 Please enter your customer information [DlgTitleFont]Customer Information MIT Kerberos may be installed with the following optional functionality. Please check those items that you wish to activate. Autostart MIT Kerberos each time you login to Windows Get tickets (if there are no existing tickets) when MIT Kerberos is started 1 Not FoundProcesses FoundProcesses LEASHAUTOSTART = 1 LEASHAUTOSTART <> 1 1 MIT Kerberos startup options [DlgTitleFont]Kerberos Options OutOfDiskSpace <> 1 OutOfDiskSpace = 1 AND OutOfNoRbDiskSpace = 0 AND (PROMPTROLLBACKCOST="P" OR NOT PROMPTROLLBACKCOST) OutOfDiskSpace = 1 AND OutOfNoRbDiskSpace = 0 AND PROMPTROLLBACKCOST="D" OutOfDiskSpace = 1 AND OutOfNoRbDiskSpace = 0 AND PROMPTROLLBACKCOST="D" (OutOfDiskSpace = 1 AND OutOfNoRbDiskSpace = 1) OR (OutOfDiskSpace = 1 AND PROMPTROLLBACKCOST="F") 1 InstallMode = "Server Image" (InstallMode = "Custom" OR InstallMode = "Change") AND &feaKfwClient <> 3 And !feaKfwClient <> 3 (InstallMode = "Custom" OR InstallMode = "Change") AND ( &feaKfwClient = 3 Or !feaKfwClient = 3 ) InstallMode = "Repair" InstallMode = "Typical" OR InstallMode = "Complete" Click Install to begin the installation. If you want to review or change any of your installation settings, click Back. Click Cancel to exit the wizard. The [Wizard] is ready to begin the [InstallMode] installation [DlgTitleFont]Ready to Install 1 OutOfDiskSpace <> 1 OutOfDiskSpace <> 1 OutOfDiskSpace = 1 AND OutOfNoRbDiskSpace = 0 AND (PROMPTROLLBACKCOST="P" OR NOT PROMPTROLLBACKCOST) OutOfDiskSpace = 1 AND OutOfNoRbDiskSpace = 0 AND PROMPTROLLBACKCOST="D" OutOfDiskSpace = 1 AND OutOfNoRbDiskSpace = 0 AND PROMPTROLLBACKCOST="D" (OutOfDiskSpace = 1 AND OutOfNoRbDiskSpace = 1) OR (OutOfDiskSpace = 1 AND PROMPTROLLBACKCOST="F") 1 Click Remove to remove [ProductName] from your computer. If you want to review or change any of your installation settings, click Back. Click Cancel to exit the wizard. You have chosen to remove the program from your computer. [DlgTitleFont]Remove Kerberos for Windows OutOfDiskSpace <> 1 OutOfDiskSpace <> 1 OutOfDiskSpace <> 1 OutOfDiskSpace = 1 AND OutOfNoRbDiskSpace = 0 AND (PROMPTROLLBACKCOST="P" OR NOT PROMPTROLLBACKCOST) OutOfDiskSpace = 1 AND OutOfNoRbDiskSpace = 0 AND PROMPTROLLBACKCOST="D" OutOfDiskSpace = 1 AND OutOfNoRbDiskSpace = 0 AND PROMPTROLLBACKCOST="D" (OutOfDiskSpace = 1 AND OutOfNoRbDiskSpace = 1) OR (OutOfDiskSpace = 1 AND PROMPTROLLBACKCOST="F") 1 1 Click Repair to repair the installation of [ProductName]. If you want to review or change any of your installation settings, click Back. Click Cancel to exit the wizard. The [Wizard] is ready to begin the repair of [ProductName]. [DlgTitleFont]Repair Kerberos for Windows 1 Please wait while the installer finishes determining your disk space requirements. (Installed) Or (CCP_Success = 1) (Not Installed) And (CCP_Success <> 1) 1 The [Wizard] will install [ProductName] on your computer. Click Next to continue or Cancel to exit the [Wizard]. {\VerdanaBold13}Welcome to the [ProductName] [Wizard] bytes GB KB MB Entire feature will be unavailable Feature will be installed when required Entire feature will be installed to run from CD Entire feature will be installed on local hard drive Entire feature will be installed to run from network Will be installed to run from CD Will be installed on local hard drive Will be installed to run from network Gathering required information... This feature will remain uninstalled This feature will be set to be installed when required This feature will be installed to run from CD This feature will be installed on the local hard drive This feature will be installed to run from the network This feature will become unavailable Will be installed when required This feature will be available to run from CD This feature will be installed on your local hard drive This feature will be available to run from the network This feature will be uninstalled completely, you won't be able to run it from CD This feature will change from run from CD state to set to be installed when required This feature will remain to be run from CD This feature will change from run from CD state to be installed on the local hard drive This feature frees up [1] on your hard drive. This feature requires [1] on your hard drive. Compiling cost for this feature... This feature will be completely removed This feature will be removed from your local hard drive, but will be set to be installed when required This feature will be removed from your local hard drive, but will be still available to run from CD This feature will remain on you local hard drive This feature will be removed from your local hard drive, but will be still available to run from the network This feature will be uninstalled completely, you won't be able to run it from the network This feature will change from run from network state to set to be installed when required This feature will change from run from network state to be installed on the local hard drive This feature will remain to be run from the network This feature frees up [1] on your hard drive. It has [2] of [3] subfeatures selected. The subfeatures free up [4] on your hard drive. This feature frees up [1] on your hard drive. It has [2] of [3] subfeatures selected. The subfeatures require [4] on your hard drive. This feature requires [1] on your hard drive. It has [2] of [3] subfeatures selected. The subfeatures free up [4] on your hard drive. This feature requires [1] on your hard drive. It has [2] of [3] subfeatures selected. The subfeatures require [4] on your hard drive. Time remaining: {[1] minutes }{[2] seconds} Available Difference Required Disk Size Volume Validating install Copying new files Copying network install files Computing space requirements Computing space requirements Computing space requirements Creating shortcuts Publishing Qualified Components Publishing Product Features Publishing product information Registering Class servers Registering extension servers Registering MIME info Registering program identifiers Allocating registry space Searching for installed applications Binding executables Searching for qualifying products Creating folders Deleting services Creating duplicate files Searching for related applications Installing ODBC components Installing new services Evaluating launch conditions Migrating feature states from related applications Moving files Patching files Updating component registration Registering COM+ Applications and Components Registering fonts Registering product Registering type libraries Registering user Removing duplicated files Updating environment strings Removing applications Removing files Removing folders Removing INI files entries Removing ODBC components Removing system registry values Removing shortcuts Searching for qualifying products Registering modules Unregistering modules Initializing ODBC directories Starting services Stopping services Unpublishing Qualified Components Unpublishing Product Features Unregister Class servers Unregistering COM+ Applications and Components Unregistering extension servers Unregistering fonts Unregistering MIME info Unregistering program identifiers Unregistering type libraries Updating environment strings Writing INI files values Writing system registry values Advertising application Generating script operations for action: Installing system catalog Publishing assembly information Unpublishing assembly information Rolling back action: Removing backup files Removing moved files Unpublishing product information {{Fatal error: }} {{Error [1]. }} Warning [1]. Info [1]. The installer has encountered an unexpected error installing this package. This may indicate a problem with this package. The error code is [1]. {{The arguments are: [2], [3], [4]}} {{Disk full: }} Action [Time]: [1]. [2] [ProductName] {[2]}{, [3]}{, [4]} Message type: [1], Argument: [2] === Logging started: [Date] [Time] === === Logging stopped: [Date] [Time] === Action start [Time]: [1]. Action ended [Time]: [1]. Return value [2]. Time remaining: {[1] minutes }{[2] seconds} Out of memory. Shut down other applications before retrying. Installer is no longer responding. Installer stopped prematurely. Please wait while Windows configures [ProductName] Gathering required information... Removing older versions of this application... Preparing to remove older versions of this application... {[ProductName] }Setup completed successfully. {[ProductName] }Setup failed. Error reading from file: [2]. {{ System error [3].}} Verify that the file exists and that you can access it. Cannot create the file '[2]'. A directory with this name already exists. Cancel the install and try installing to a different location. Please insert the disk: [2] The installer has insufficient privileges to access this directory: [2]. The installation cannot continue. Log on as administrator or contact your system administrator. Error writing to file: [2]. Verify that you have access to that directory. Error reading from file [2]. {{ System error [3].}} Verify that the file exists and that you can access it. Another application has exclusive access to the file '[2]'. Please shut down all other applications, then click Retry. There is not enough disk space to install this file: [2]. Free some disk space and click Retry, or click Cancel to exit. Source file not found: [2]. Verify that the file exists and that you can access it. Error reading from file: [3]. {{ System error [2].}} Verify that the file exists and that you can access it. Error writing to file: [3]. {{ System error [2].}} Verify that you have access to that directory. Source file not found{{(cabinet)}}: [2]. Verify that the file exists and that you can access it. Cannot create the directory '[2]'. A file with this name already exists. Please rename or remove the file and click retry, or click Cancel to exit. The volume [2] is currently unavailable. Please select another. The specified path '[2]' is unavailable. Unable to write to the specified folder: [2]. A network error occurred while attempting to read from the file: [2] An error occurred while attempting to create the directory: [2] A network error occurred while attempting to create the directory: [2] A network error occurred while attempting to open the source file cabinet: [2] The specified path is too long: [2] The Installer has insufficient privileges to modify this file: [2]. A portion of the folder path '[2]' is invalid. It is either empty or exceeds the length allowed by the system. The folder path '[2]' contains words that are not valid in folder paths. The folder path '[2]' contains an invalid character. '[2]' is not a valid short file name. Error getting file security: [3] GetLastError: [2] Invalid Drive: [2] Error applying patch to file [2]. It has probably been updated by other means, and can no longer be modified by this patch. For more information contact your patch vendor. {{System Error: [3]}} A file that is required cannot be installed because the cabinet file [2] is not digitally signed. This may indicate that the cabinet file is corrupt. A file that is required cannot be installed because the cabinet file [2] has an invalid digital signature. This may indicate that the cabinet file is corrupt.{{ Error [3] was returned by WinVerifyTrust.}} Failed to correctly copy [2] file: CRC error. Failed to correctly move [2] file: CRC error. Failed to correctly patch [2] file: CRC error. The file '[2]' cannot be installed because the file cannot be found in cabinet file '[3]'. This could indicate a network error, an error reading from the CD-ROM, or a problem with this package. The cabinet file '[2]' required for this installation is corrupt and cannot be used. This could indicate a network error, an error reading from the CD-ROM, or a problem with this package. There was an error creating a temporary file that is needed to complete this installation.{{ Folder: [3]. System error code: [2]}} Could not create key: [2]. {{ System error [3].}} Verify that you have sufficient access to that key, or contact your support personnel. Could not open key: [2]. {{ System error [3].}} Verify that you have sufficient access to that key, or contact your support personnel. Could not delete value [2] from key [3]. {{ System error [4].}} Verify that you have sufficient access to that key, or contact your support personnel. Could not delete key [2]. {{ System error [3].}} Verify that you have sufficient access to that key, or contact your support personnel. Could not read value [2] from key [3]. {{ System error [4].}} Verify that you have sufficient access to that key, or contact your support personnel. Could not write value [2] to key [3]. {{ System error [4].}} Verify that you have sufficient access to that key, or contact your support personnel. Could not get value names for key [2]. {{ System error [3].}} Verify that you have sufficient access to that key, or contact your support personnel. Could not get sub key names for key [2]. {{ System error [3].}} Verify that you have sufficient access to that key, or contact your support personnel. Could not read security information for key [2]. {{ System error [3].}} Verify that you have sufficient access to that key, or contact your support personnel. Could not increase the available registry space. [2] KB of free registry space is required for the installation of this application. Another installation is in progress. You must complete that installation before continuing this one. Error accessing secured data. Please make sure the Windows Installer is configured properly and try the install again. User '[2]' has previously initiated an install for product '[3]'. That user will need to run that install again before they can use that product. Your current install will now continue. User '[2]' has previously initiated an install for product '[3]'. That user will need to run that install again before they can use that product. Out of disk space -- Volume: '[2]'; required space: [3] KB; available space: [4] KB. Free some disk space and retry. Are you sure you want to cancel? The file [2][3] is being held in use{ by the following process: Name: [4], Id: [5], Window Title: '[6]'}. Close that application and retry. The product '[2]' is already installed, preventing the installation of this product. The two products are incompatible. There is not enough disk space on the volume '[2]' to continue the install with recovery enabled. [3] KB are required, but only [4] KB are available. Click Ignore to continue the install without saving recovery information, click Retry to check for available space again, or click Cancel to quit the installation. Could not access network location [2]. The following applications should be closed before continuing the install: Could not find any previously installed compliant products on the machine for installing this product. An error occurred while applying security settings. [2] is not a valid user or group. This could be a problem with the package, or a problem connecting to a domain controller on the network. Check your network connection and click Retry, or Cancel to end the install. {{Unable to locate the user's SID, system error [3]}} The key [2] is not valid. Verify that you entered the correct key. The installer must restart your system before configuration of [2] can continue. Click Yes to restart now or No if you plan to manually restart later. You must restart your system for the configuration changes made to [2] to take effect. Click Yes to restart now or No if you plan to manually restart later. An installation for [2] is currently suspended. You must undo the changes made by that installation to continue. Do you want to undo those changes? A previous installation for this product is in progress. You must undo the changes made by that installation to continue. Do you want to undo those changes? An installation package for the product [2] cannot be found. Try the installation again using a valid copy of the installation package '[3]'. Installation completed successfully. Installation failed. Product: [2] -- [3] You may either restore your computer to its previous state or continue the install later. Would you like to restore? An error occurred while writing installation information to disk. Check to make sure enough disk space is available, and click Retry, or Cancel to end the install. One or more of the files required to restore your computer to its previous state could not be found. Restoration will not be possible. [2] cannot install one of its required products. Contact your technical support group. {{System Error: [3].}} The older version of [2] cannot be removed. Contact your technical support group. {{System Error [3].}} Installed [2] Configured [2] Removed [2] File [2] was rejected by digital signature policy. The Windows Installer Service could not be accessed. This can occur if you are running Windows in safe mode, or if the Windows Installer is not correctly installed. Contact your support personnel for assistance. There is a problem with this Windows Installer package. A script required for this install to complete could not be run. Contact your support personnel or package vendor. {{Custom action [2] script error [3], [4]: [5] Line [6], Column [7], [8] }} There is a problem with this Windows Installer package. A program required for this install to complete could not be run. Contact your support personnel or package vendor. {{Action: [2], location: [3], command: [4] }} There is a problem with this Windows Installer package. A program run as part of the setup did not finish as expected. Contact your support personnel or package vendor. {{Action [2], location: [3], command: [4] }} There is a problem with this Windows Installer package. A DLL required for this install to complete could not be run. Contact your support personnel or package vendor. {{Action [2], entry: [3], library: [4] }} Removal completed successfully. Removal failed. Advertisement completed successfully. Advertisement failed. Configuration completed successfully. Configuration failed. You must be an Administrator to remove this application. To remove this application, you can log on as an Administrator, or contact your technical support group for assistance. The path [2] is not valid. Please specify a valid path. Out of memory. Shut down other applications before retrying. There is no disk in drive [2]. Please insert one and click Retry, or click Cancel to go back to the previously selected volume. There is no disk in drive [2]. Please insert one and click Retry, or click Cancel to return to the browse dialog and select a different volume. The folder [2] does not exist. Please enter a path to an existing folder. You have insufficient privileges to read this folder. A valid destination folder for the install could not be determined. Error attempting to read from the source install database: [2]. Scheduling reboot operation: Renaming file [2] to [3]. Must reboot to complete operation. Scheduling reboot operation: Deleting file [2]. Must reboot to complete operation. Module [2] failed to register. HRESULT [3]. Contact your support personnel. Module [2] failed to unregister. HRESULT [3]. Contact your support personnel. Failed to cache package [2]. Error: [3]. Contact your support personnel. Could not register font [2]. Verify that you have sufficient permissions to install fonts, and that the system supports this font. Could not unregister font [2]. Verify that you that you have sufficient permissions to remove fonts. Could not create Shortcut [2]. Verify that the destination folder exists and that you can access it. Could not remove Shortcut [2]. Verify that the shortcut file exists and that you can access it. Could not register type library for file [2]. Contact your support personnel. Could not unregister type library for file [2]. Contact your support personnel. Could not update the ini file [2][3]. Verify that the file exists and that you can access it. Could not schedule file [2] to replace file [3] on reboot. Verify that you have write permissions to file [3]. Error removing ODBC driver manager, ODBC error [2]: [3]. Contact your support personnel. Error installing ODBC driver manager, ODBC error [2]: [3]. Contact your support personnel. Error removing ODBC driver: [4], ODBC error [2]: [3]. Verify that you have sufficient privileges to remove ODBC drivers. Error installing ODBC driver: [4], ODBC error [2]: [3]. Verify that the file [4] exists and that you can access it. Error configuring ODBC data source: [4], ODBC error [2]: [3]. Verify that the file [4] exists and that you can access it. Service '[2]' ([3]) failed to start. Verify that you have sufficient privileges to start system services. Service '[2]' ([3]) could not be stopped. Verify that you have sufficient privileges to stop system services. Service '[2]' ([3]) could not be deleted. Verify that you have sufficient privileges to remove system services. Service '[2]' ([3]) could not be installed. Verify that you have sufficient privileges to install system services. Could not update environment variable '[2]'. Verify that you have sufficient privileges to modify environment variables. You do not have sufficient privileges to complete this installation for all users of the machine. Log on as administrator and then retry this installation. Could not set file security for file '[3]'. Error: [2]. Verify that you have sufficient privileges to modify the security permissions for this file. Component Services (COM+ 1.0) are not installed on this computer. This installation requires Component Services in order to complete successfully. Component Services are available on Windows 2000. Error registering COM+ Application. Contact your support personnel for more information. Error unregistering COM+ Application. Contact your support personnel for more information. The description for service '[2]' ([3]) could not be changed. The Windows Installer service cannot update the system file [2] because the file is protected by Windows. You may need to update your operating system for this program to work correctly. {{Package version: [3], OS Protected version: [4]}} The Windows Installer service cannot update the protected Windows file [2]. {{Package version: [3], OS Protected version: [4], SFP Error: [5]}} The Windows Installer service cannot update one or more protected Windows files. {{SFP Error: [2]. List of protected files:\r\n[3]}} User installations are disabled via policy on the machine. An error occured during the installation of assembly component [2]. HRESULT: [3]. {{assembly interface: [4], function: [5], assembly name: [6]}} Custom action data not found. STATUS [2] NSIS Uninstallation failed. Status [2] ABORT: [2] Custom action failed. Phase [2] Failed to determine running processes. Status [2] Failed to install Kerberos network provider. Status [2] NSIS Uninstallation failed to initialize. Uninstaller path [2] returned error [3] NOT Installed Installed AND (RESUME OR Preselected) Installed AND NOT RESUME AND NOT Preselected ]]> @@@@@]]> krb5-1.16/src/windows/installer/wix/lang/license.rtf0000644000704600001450000002301613211554426022345 0ustar ghudsonlibuuid{\rtf1\ansi\ansicpg1252\deff0\deflang1033\deflangfe1033{\fonttbl{\f0\fmodern\fprq1\fcharset0 Courier New;}{\f1\froman\fprq2\fcharset0 Times New Roman;}} {\*\generator Msftedit 5.41.15.1507;}\viewkind4\uc1\pard\nowidctlpar\tx916\tx1832\tx2748\tx3664\tx4580\tx5496\tx6412\tx7328\tx8244\tx9160\tx10076\tx10992\tx11908\tx12824\tx13740\tx14656\f0\fs20 Copyright Notice and Legal Administrivia\par ----------------------------------------\par \par Copyright (C) 1985-2012 by the Massachusetts Institute of Technology.\par \par All rights reserved.\par \par Export of this software from the United States of America may require a specific license from the United States Government. It is the responsibility of any person or organization contemplating export to obtain such a license before exporting.\par \par WITHIN THAT CONSTRAINT, permission to use, copy, modify, and distribute this software and its documentation for any purpose and without fee is hereby granted, provided that the above copyright notice appear in all copies and that both that copyright notice and\par this permission notice appear in supporting documentation, and that the name of M.I.T. not be used in advertising or publicity pertaining to distribution of the software without specific, written prior permission. Furthermore if you modify this software you must label your software as modified software and not distribute it in such a fashion that it might be confused with the original MIT software. M.I.T. makes no representations about the suitability of this software for any purpose. It is provided "as is" without express or implied warranty.\par \par THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.\par \par Individual source code files are copyright MIT, Cygnus Support, OpenVision, Oracle, Sun Soft, FundsXpress, and others.\par \par Project Athena, Athena, Athena MUSE, Discuss, Hesiod, Kerberos, Moira, and Zephyr are trademarks of the Massachusetts Institute of Technology (MIT). No commercial use of these trademarks may be made without prior written permission of MIT.\par \par "Commercial use" means use of a name in a product or other for-profit manner. It does NOT prevent a commercial firm from referring to the MIT trademarks in order to convey information (although in doing so, recognition of their trademark status should be given).\par \par ----\par \par The following copyright and permission notice applies to the OpenVision Kerberos Administration system located in kadmin/create, kadmin/dbutil, kadmin/passwd, kadmin/server, lib/kadm5, and portions of lib/rpc:\par \par Copyright, OpenVision Technologies, Inc., 1996, All Rights Reserved\par \par WARNING: Retrieving the OpenVision Kerberos Administration system source code, as described below, indicates your acceptance of the following terms. If you do not agree to the following terms, do not retrieve the OpenVision Kerberos administration system.\par \par You may freely use and distribute the Source Code and Object Code compiled from it, with or without modification, but this Source Code is provided to you "AS IS" EXCLUSIVE OF ANY WARRANTY, INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, OR ANY OTHER WARRANTY, WHETHER EXPRESS OR IMPLIED. IN NO EVENT WILL OPENVISION HAVE ANY LIABILITY FOR ANY LOST PROFITS, LOSS OF DATA OR COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY SPECIAL, INDIRECT, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, INCLUDING, WITHOUT LIMITATION, THOSE RESULTING FROM THE USE OF THE SOURCE CODE, OR THE FAILURE OF THE SOURCE CODE TO PERFORM, OR FOR ANY OTHER REASON.\par \par OpenVision retains all copyrights in the donated Source Code. OpenVision also retains copyright to derivative works of the Source Code, whether created by OpenVision or by a third party. The OpenVision copyright notice must be preserved if derivative works are made based on the donated Source Code.\par \par OpenVision Technologies, Inc. has donated this Kerberos Administration system to MIT for inclusion in the standard Kerberos 5 distribution. This donation underscores our commitment to continuing Kerberos technology development and our gratitude for the valuable work which has been performed by MIT and the Kerberos community.\par \par ----\par \par Portions contributed by Matt Crawford were work performed at Fermi National Accelerator Laboratory, which is operated by Universities Research Association, Inc., under contract DE-AC02-76CHO3000 with the U.S. Department of Energy.\par \par \pard ----\f1\fs24\par \pard\nowidctlpar\tx916\tx1832\tx2748\tx3664\tx4580\tx5496\tx6412\tx7328\tx8244\tx9160\tx10076\tx10992\tx11908\tx12824\tx13740\tx14656\f0\fs20\par The implementation of the Yarrow pseudo-random number generator in src/lib/crypto/yarrow has the following copyright:\par \par Copyright 2000 by Zero-Knowledge Systems, Inc.\par \par 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 Zero-Knowledge Systems, Inc. not be used in advertising or publicity pertaining to distribution of the software without specific, written prior permission. Zero-Knowledge Systems, Inc. makes no representations about the suitability of this software for any purpose. It is provided "as is" without express or implied warranty.\par \par ZERO-KNOWLEDGE SYSTEMS, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL ZERO-KNOWLEDGE SYSTEMS, INC. BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN\par ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTUOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.\par \par \pard ----\f1\fs24\par \pard\nowidctlpar\tx916\tx1832\tx2748\tx3664\tx4580\tx5496\tx6412\tx7328\tx8244\tx9160\tx10076\tx10992\tx11908\tx12824\tx13740\tx14656\f0\fs20\par The implementation of the AES encryption algorithm in src/lib/crypto/aes has the following copyright:\par \par Copyright (c) 2001, Dr Brian Gladman , Worcester, UK.\par All rights reserved.\par \par LICENSE TERMS\par \par The free distribution and use of this software in both source and binary form is allowed (with or without changes) provided that:\par \par 1. distributions of this source code include the above copyright notice, this list of conditions and the following disclaimer;\par \par 2. distributions in binary form include the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other associated materials;\par \par 3. the copyright holder's name is not used to endorse products built using this software without specific written permission. \par \par DISCLAIMER\par \par This software is provided 'as is' with no explcit or implied warranties in respect of any properties, including, but not limited to, correctness and fitness for purpose.\par \par \par \par Acknowledgements\par ----------------\par \par Appreciation Time!!!! There are far too many people to try to thank them all; many people have contributed to the development of Kerberos V5. This is only a partial listing....\par \par Thanks to Paul Vixie and the Internet Software Consortium for funding the work of Barry Jaspan. This funding was invaluable for the OV administration server integration, as well as the 1.0 release preparation process.\par \par Thanks to John Linn, Scott Foote, and all of the folks at OpenVision Technologies, Inc., who donated their administration server for use in the MIT release of Kerberos.\par \par Thanks to Jeff Bigler, Mark Eichin, Marc Horowitz, Nancy Gilman, Ken Raeburn, and all of the folks at Cygnus Support, who provided innumerable bug fixes and portability enhancements to the Kerberos V5 tree. Thanks especially to Jeff Bigler, for the new user and system administrator's documentation.\par \par Thanks to Doug Engert from ANL for providing many bug fixes, as well as testing to ensure DCE interoperability.\par \par Thanks to Ken Hornstein at NRL for providing many bug fixes and suggestions, and for working on SAM preauthentication.\par \par Thanks to Matt Crawford at FNAL for bugfixes and enhancements.\par \par Thanks to Sean Mullan and Bill Sommerfeld from Hewlett Packard for their many suggestions and bug fixes.\par \par Thanks to Nalin Dahyabhai of RedHat and Chris Evans for locating and providing patches for numerous buffer overruns.\par \par Thanks to Christopher Thompson and Marcus Watts for discovering the ftpd security bug.\par \par Thanks to Paul Nelson of Thursby Software Systems for implementing the Microsoft set password protocol.\par \par Thanks to the members of the Kerberos V5 development team at MIT, both past and present: Danilo Almeida, Jeffrey Altman, Jay Berkenbilt, Richard Basch, Mitch Berger, John Carr, Don Davis, Alexandra Ellwood, Nancy Gilman, Matt Hancher, Sam Hartman, Paul Hill, Marc Horowitz, Eva Jacobus, Miroslav Jurisic, Barry Jaspan, Geoffrey King, John Kohl, Peter Litwack, Scott McGuire, Kevin Mitchell, Cliff Neuman, Paul Park, Ezra Peisach, Chris Provenzano, Ken Raeburn, Jon Rochlis, Jeff Schiller, Jen Selby, Brad Thompson, Harry Tsai, Ted Ts'o, Marshall Vale, Tom Yu.\par \pard\nowidctlpar\f1\fs24\par } krb5-1.16/src/windows/installer/wix/config.wxi0000644000704600001450000001412113211554426021260 0ustar ghudsonlibuuid krb5-1.16/src/windows/installer/wix/platform.wxi0000644000704600001450000002774413211554426021656 0ustar ghudsonlibuuid krb5-1.16/src/windows/installer/wix/custom/0000755000704600001450000000000013211554426020575 5ustar ghudsonlibuuidkrb5-1.16/src/windows/installer/wix/custom/custom.h0000644000704600001450000000503113211554426022257 0ustar ghudsonlibuuid/* Copyright 2004 by the Massachusetts Institute of Technology All rights reserved. Permission to use, copy, modify, and distribute this software and its documentation for any purpose and without fee is hereby granted, provided that the above copyright notice appear in all copies and that both that copyright notice and this permission notice appear in supporting documentation, and that the name of the Massachusetts Institute of Technology (M.I.T.) not be used in advertising or publicity pertaining to distribution of the software without specific, written prior permission. M.I.T. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL M.I.T. 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. */ /* custom.h * * Declarations for Kerberos for Windows MSI setup tools * * rcsid : $Id$ */ #pragma once #include #include #include #include #include #include #define MSIDLLEXPORT UINT __stdcall #define CHECK(x) if((x)) goto _cleanup #define CHECKX(x,y) if(!(x)) { msiErr = (y); goto _cleanup; } #define CHECK2(x,y) if((x)) { msiErr = (y); goto _cleanup; } #define STR_KEY_ORDER _T("SYSTEM\\CurrentControlSet\\Control\\NetworkProvider\\Order") #define STR_VAL_ORDER _T("ProviderOrder") #define STR_SERVICE _T("MIT Kerberos") #define STR_SERVICE_LEN 12 void ShowMsiError(MSIHANDLE, DWORD, DWORD); UINT SetAllowTgtSessionKey( MSIHANDLE hInstall, BOOL pInstall ); UINT KillRunningProcessesSlave( MSIHANDLE hInstall, BOOL bKill ); /* exported */ MSIDLLEXPORT AbortMsiImmediate( MSIHANDLE ); MSIDLLEXPORT UninstallNsisInstallation( MSIHANDLE hInstall ); MSIDLLEXPORT RevertAllowTgtSessionKey( MSIHANDLE hInstall ); MSIDLLEXPORT EnableAllowTgtSessionKey( MSIHANDLE hInstall ); MSIDLLEXPORT KillRunningProcesses( MSIHANDLE hInstall ) ; MSIDLLEXPORT ListRunningProcesses( MSIHANDLE hInstall ); MSIDLLEXPORT InstallNetProvider( MSIHANDLE ); MSIDLLEXPORT UninstallNetProvider ( MSIHANDLE ); #define INP_ERR_PRESENT 1 #define INP_ERR_ADDED 2 #define INP_ERR_ABSENT 3 #define INP_ERR_REMOVED 4 /* Custom errors */ #define ERR_CUSTACTDATA 4001 #define ERR_NSS_FAILED 4003 #define ERR_ABORT 4004 #define ERR_PROC_LIST 4006 #define ERR_NPI_FAILED 4007 #define ERR_NSS_FAILED_CP 4008 krb5-1.16/src/windows/installer/wix/custom/custom.cpp0000644000704600001450000006011313211554426022614 0ustar ghudsonlibuuid#ifdef __NMAKE__ # NMAKE portion. # Build with : nmake /f custom.cpp # Clean with : nmake /f custom.cpp clean # Builds custom.dll OUTPATH = . # program name macros CC = cl /nologo LINK = link /nologo RM = del DLLFILE = $(OUTPATH)\custom.dll DLLEXPORTS =\ -EXPORT:EnableAllowTgtSessionKey \ -EXPORT:RevertAllowTgtSessionKey \ -EXPORT:AbortMsiImmediate \ -EXPORT:UninstallNsisInstallation \ -EXPORT:KillRunningProcesses \ -EXPORT:ListRunningProcesses \ -EXPORT:InstallNetProvider \ -EXPORT:UninstallNetProvider $(DLLFILE): $(OUTPATH)\custom.obj $(LINK) /OUT:$@ /DLL $** $(DLLEXPORTS) $(OUTPATH)\custom.obj: custom.cpp custom.h $(CC) /c /Fo$@ custom.cpp all: $(DLLFILE) clean: $(RM) $(DLLFILE) $(RM) $(OUTPATH)\custom.obj $(RM) $(OUTPATH)\custom.exp !IFDEF __C_TEXT__ #else /* Copyright 2004,2005 by the Massachusetts Institute of Technology All rights reserved. Permission to use, copy, modify, and distribute this software and its documentation for any purpose and without fee is hereby granted, provided that the above copyright notice appear in all copies and that both that copyright notice and this permission notice appear in supporting documentation, and that the name of the Massachusetts Institute of Technology (M.I.T.) not be used in advertising or publicity pertaining to distribution of the software without specific, written prior permission. M.I.T. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL M.I.T. 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. */ /************************************************************** * custom.cpp : Dll implementing custom action to install Kerberos for Windows * * The functions in this file are for use as entry points * for calls from MSI only. The specific MSI parameters * are noted in the comments section of each of the * functions. * * rcsid: $Id$ **************************************************************/ #pragma unmanaged // Only works for Win2k and above #define _WIN32_WINNT 0x500 #include "custom.h" #include // linker stuff #pragma comment(lib, "msi") #pragma comment(lib, "advapi32") #pragma comment(lib, "shell32") #pragma comment(lib, "user32") void ShowMsiError( MSIHANDLE hInstall, DWORD errcode, DWORD param ){ MSIHANDLE hRecord; hRecord = MsiCreateRecord(3); MsiRecordClearData(hRecord); MsiRecordSetInteger(hRecord, 1, errcode); MsiRecordSetInteger(hRecord, 2, param); MsiProcessMessage( hInstall, INSTALLMESSAGE_ERROR, hRecord ); MsiCloseHandle( hRecord ); } static void ShowMsiErrorEx(MSIHANDLE hInstall, DWORD errcode, LPTSTR str, DWORD param ) { MSIHANDLE hRecord; hRecord = MsiCreateRecord(3); MsiRecordClearData(hRecord); MsiRecordSetInteger(hRecord, 1, errcode); MsiRecordSetString(hRecord, 2, str); MsiRecordSetInteger(hRecord, 3, param); MsiProcessMessage(hInstall, INSTALLMESSAGE_ERROR, hRecord); MsiCloseHandle(hRecord); } #define LSA_KERBEROS_KEY "SYSTEM\\CurrentControlSet\\Control\\Lsa\\Kerberos" #define LSA_KERBEROS_PARM_KEY "SYSTEM\\CurrentControlSet\\Control\\Lsa\\Kerberos\\Parameters" #define KFW_CLIENT_KEY "SOFTWARE\\MIT\\Kerberos\\Client\\" #define SESSKEY_VALUE_NAME "AllowTGTSessionKey" #define SESSBACKUP_VALUE_NAME "AllowTGTSessionKeyBackup" #define SESSXPBACKUP_VALUE_NAME "AllowTGTSessionKeyBackupXP" /* Set the AllowTGTSessionKey registry keys on install. Called as a deferred custom action. */ MSIDLLEXPORT EnableAllowTgtSessionKey( MSIHANDLE hInstall ) { return SetAllowTgtSessionKey( hInstall, TRUE ); } /* Unset the AllowTGTSessionKey registry keys on uninstall. Called as a deferred custom action. */ MSIDLLEXPORT RevertAllowTgtSessionKey( MSIHANDLE hInstall ) { return SetAllowTgtSessionKey( hInstall, FALSE ); } UINT SetAllowTgtSessionKey( MSIHANDLE hInstall, BOOL pInstall ) { TCHAR tchVersionString[1024]; TCHAR tchVersionKey[2048]; DWORD size; DWORD type; DWORD value; HKEY hkKfwClient = NULL; HKEY hkLsaKerberos = NULL; HKEY hkLsaKerberosParm = NULL; UINT rv; DWORD phase = 0; // construct the backup key path size = sizeof(tchVersionString) / sizeof(TCHAR); rv = MsiGetProperty( hInstall, _T("CustomActionData"), tchVersionString, &size ); if(rv != ERROR_SUCCESS) { if(pInstall) { ShowMsiError( hInstall, ERR_CUSTACTDATA, rv ); return rv; } else { return ERROR_SUCCESS; } } _tcscpy( tchVersionKey, _T( KFW_CLIENT_KEY ) ); _tcscat( tchVersionKey, tchVersionString ); phase = 1; rv = RegOpenKeyEx( HKEY_LOCAL_MACHINE, tchVersionKey, 0, ((pInstall)?KEY_WRITE:KEY_READ), &hkKfwClient ); if(rv != ERROR_SUCCESS) goto cleanup; phase = 2; rv = RegOpenKeyEx( HKEY_LOCAL_MACHINE, _T( LSA_KERBEROS_KEY ), 0, KEY_READ | KEY_WRITE, &hkLsaKerberos ); if(rv != ERROR_SUCCESS) goto cleanup; phase = 3; rv = RegOpenKeyEx( HKEY_LOCAL_MACHINE, _T( LSA_KERBEROS_PARM_KEY ), 0, KEY_READ | KEY_WRITE, &hkLsaKerberosParm ); if(rv != ERROR_SUCCESS) { hkLsaKerberosParm = NULL; } if(pInstall) { // backup the existing values if(hkLsaKerberosParm) { phase = 4; size = sizeof(value); rv = RegQueryValueEx( hkLsaKerberosParm, _T( SESSKEY_VALUE_NAME ), NULL, &type, (LPBYTE) &value, &size ); if(rv != ERROR_SUCCESS) value = 0; phase = 5; rv = RegSetValueEx( hkKfwClient, _T( SESSBACKUP_VALUE_NAME ), 0, REG_DWORD, (LPBYTE) &value, sizeof(value)); if(rv != ERROR_SUCCESS) goto cleanup; } phase = 6; size = sizeof(value); rv = RegQueryValueEx( hkLsaKerberos, _T( SESSKEY_VALUE_NAME ), NULL, &type, (LPBYTE) &value, &size ); if(rv != ERROR_SUCCESS) value = 0; phase = 7; rv = RegSetValueEx( hkKfwClient, _T( SESSXPBACKUP_VALUE_NAME ), 0, REG_DWORD, (LPBYTE) &value, sizeof(value)); if(rv != ERROR_SUCCESS) goto cleanup; // and now write the actual values phase = 8; value = 1; rv = RegSetValueEx( hkLsaKerberos, _T( SESSKEY_VALUE_NAME ), 0, REG_DWORD, (LPBYTE) &value, sizeof(value)); if(rv != ERROR_SUCCESS) goto cleanup; if(hkLsaKerberosParm) { phase = 9; value = 1; rv = RegSetValueEx( hkLsaKerberosParm, _T( SESSKEY_VALUE_NAME ), 0, REG_DWORD, (LPBYTE) &value, sizeof(value)); if(rv != ERROR_SUCCESS) goto cleanup; } } else { // uninstalling // Don't fail no matter what goes wrong. This is also a rollback action. if(hkLsaKerberosParm) { size = sizeof(value); rv = RegQueryValueEx( hkKfwClient, _T( SESSBACKUP_VALUE_NAME ), NULL, &type, (LPBYTE) &value, &size ); if(rv != ERROR_SUCCESS) value = 0; RegSetValueEx( hkLsaKerberosParm, _T( SESSKEY_VALUE_NAME ), 0, REG_DWORD, (LPBYTE) &value, sizeof(value)); } size = sizeof(value); rv = RegQueryValueEx( hkKfwClient, _T( SESSXPBACKUP_VALUE_NAME ), NULL, &type, (LPBYTE) &value, &size ); if(rv != ERROR_SUCCESS) value = 0; RegSetValueEx( hkLsaKerberos, _T( SESSKEY_VALUE_NAME ), 0, REG_DWORD, (LPBYTE) &value, sizeof(value)); RegDeleteValue( hkKfwClient, _T( SESSXPBACKUP_VALUE_NAME ) ); RegDeleteValue( hkKfwClient, _T( SESSBACKUP_VALUE_NAME ) ); } // all done rv = ERROR_SUCCESS; cleanup: if(rv != ERROR_SUCCESS && pInstall) { ShowMsiError(hInstall, 4005, phase); } if(hkKfwClient) RegCloseKey( hkKfwClient ); if(hkLsaKerberos) RegCloseKey( hkLsaKerberos ); if(hkLsaKerberosParm) RegCloseKey( hkLsaKerberosParm ); return rv; } /* Abort the installation (called as an immediate custom action) */ MSIDLLEXPORT AbortMsiImmediate( MSIHANDLE hInstall ) { DWORD rv; DWORD dwSize = 0; LPTSTR sReason = NULL; LPTSTR sFormatted = NULL; MSIHANDLE hRecord = NULL; LPTSTR cAbortReason = _T("ABORTREASON"); rv = MsiGetProperty( hInstall, cAbortReason, _T(""), &dwSize ); if(rv != ERROR_MORE_DATA) goto _cleanup; sReason = new TCHAR[ ++dwSize ]; rv = MsiGetProperty( hInstall, cAbortReason, sReason, &dwSize ); if(rv != ERROR_SUCCESS) goto _cleanup; hRecord = MsiCreateRecord(3); MsiRecordClearData(hRecord); MsiRecordSetString(hRecord, 0, sReason); dwSize = 0; rv = MsiFormatRecord(hInstall, hRecord, "", &dwSize); if(rv != ERROR_MORE_DATA) goto _cleanup; sFormatted = new TCHAR[ ++dwSize ]; rv = MsiFormatRecord(hInstall, hRecord, sFormatted, &dwSize); if(rv != ERROR_SUCCESS) goto _cleanup; MsiCloseHandle(hRecord); hRecord = MsiCreateRecord(3); MsiRecordClearData(hRecord); MsiRecordSetInteger(hRecord, 1, ERR_ABORT); MsiRecordSetString(hRecord,2, sFormatted); MsiProcessMessage(hInstall, INSTALLMESSAGE_ERROR, hRecord); _cleanup: if(sFormatted) delete sFormatted; if(hRecord) MsiCloseHandle( hRecord ); if(sReason) delete sReason; return ~ERROR_SUCCESS; } /* Kill specified processes that are running on the system */ /* Uses the custom table KillProcess. Called as an immediate action. */ #define MAX_KILL_PROCESSES 255 #define FIELD_SIZE 256 struct _KillProc { TCHAR * image; TCHAR * desc; BOOL found; DWORD pid; }; #define RV_BAIL if(rv != ERROR_SUCCESS) goto _cleanup MSIDLLEXPORT KillRunningProcesses( MSIHANDLE hInstall ) { return KillRunningProcessesSlave( hInstall, TRUE ); } /* When listing running processes, we populate the ListBox table with values associated with the property 'KillableProcesses'. If we actually find any processes worth killing, then we also set the 'FoundProcceses' property to '1'. Otherwise we set it to ''. */ MSIDLLEXPORT ListRunningProcesses( MSIHANDLE hInstall ) { return KillRunningProcessesSlave( hInstall, FALSE ); } UINT KillRunningProcessesSlave( MSIHANDLE hInstall, BOOL bKill ) { UINT rv = ERROR_SUCCESS; _KillProc * kpList; int nKpList = 0; int i; int rowNum = 1; DWORD size; BOOL found = FALSE; MSIHANDLE hDatabase = NULL; MSIHANDLE hView = NULL; MSIHANDLE hViewInsert = NULL; MSIHANDLE hRecord = NULL; MSIHANDLE hRecordInsert = NULL; HANDLE hSnapshot = NULL; PROCESSENTRY32 pe; kpList = new _KillProc[MAX_KILL_PROCESSES]; memset(kpList, 0, sizeof(*kpList) * MAX_KILL_PROCESSES); hDatabase = MsiGetActiveDatabase( hInstall ); if( hDatabase == NULL ) { rv = GetLastError(); goto _cleanup; } // If we are only going to list out the processes, delete all the existing // entries first. if(!bKill) { rv = MsiDatabaseOpenView( hDatabase, _T( "DELETE FROM `ListBox` WHERE `ListBox`.`Property` = 'KillableProcesses'" ), &hView); RV_BAIL; rv = MsiViewExecute( hView, NULL ); RV_BAIL; MsiCloseHandle( hView ); hView = NULL; rv = MsiDatabaseOpenView( hDatabase, _T( "SELECT * FROM `ListBox` WHERE `Property` = 'KillableProcesses'" ), &hViewInsert); RV_BAIL; MsiViewExecute(hViewInsert, NULL); hRecordInsert = MsiCreateRecord(4); if(hRecordInsert == NULL) { rv = GetLastError(); goto _cleanup; } } // Open a view rv = MsiDatabaseOpenView( hDatabase, _T( "SELECT `Image`,`Desc` FROM `KillProcess`" ), &hView); RV_BAIL; rv = MsiViewExecute( hView, NULL ); RV_BAIL; do { rv = MsiViewFetch( hView, &hRecord ); if(rv != ERROR_SUCCESS) { if(hRecord) MsiCloseHandle(hRecord); hRecord = NULL; break; } kpList[nKpList].image = new TCHAR[ FIELD_SIZE ]; kpList[nKpList].image[0] = _T('\0'); kpList[nKpList].desc = new TCHAR[ FIELD_SIZE ]; kpList[nKpList].desc[0] = _T('\0'); nKpList++; size = FIELD_SIZE; rv = MsiRecordGetString(hRecord, 1, kpList[nKpList-1].image, &size); RV_BAIL; size = FIELD_SIZE; rv = MsiRecordGetString(hRecord, 2, kpList[nKpList-1].desc, &size); RV_BAIL; MsiCloseHandle(hRecord); } while(nKpList < MAX_KILL_PROCESSES); hRecord = NULL; // now we have all the processes in the array. Check if they are running. hSnapshot = CreateToolhelp32Snapshot( TH32CS_SNAPPROCESS, 0 ); if(hSnapshot == INVALID_HANDLE_VALUE) { rv = GetLastError(); goto _cleanup; } pe.dwSize = sizeof( PROCESSENTRY32 ); if(!Process32First( hSnapshot, &pe )) { // technically we should at least find the MSI process, but we let this pass rv = ERROR_SUCCESS; goto _cleanup; } do { for(i=0; i copy kfw.msi kfw-modified.msi (edit the kfw-modified.msi to include the necessary changes) > msitran -g kfw.msi kfw-modified.msi kfw-transform.mst (generates kfw-transform.mst, which is the transform) Transforms have an extension of .mst. 'msitran' is a tool distributed as part of the "Windows Installer" SDK (which in turn is a part of the Windows Platform SDK). You can test a transform by : > copy kfw.msi kfw-test.msi > msitran -a kfw-transform.mst kfw-test.msi and then checking the resulting kfw-test.msi to see if all the changes you have made above to kfw-modified.msi is present in kfw-test.msi. 'msitran' will complain if some modification in the transform can not be successfully applied. As mentioned above, you can use a tool like ORCA.EXE to edit the MSI databases directly when editing kfw-modified.msi. More details are given below. ---------------------------------------------------------------------- 2. Configuration Options The logic necessary to implement all of the settings described in the release notes are present in the MSI. Most of these can be controlled by setting the corresponding properties to the desired value. Some settings may require modifying existing registry entries (though not recommended) or adding new resources (like files or registry keys). Instructions for performing these tasks are below. 2.1 Configurable Properties Most configurable properties correspond to registry keys or values. Please refer to the release notes for more information about how these registry settings are used. Due to the logic invoked based on the existence of these registry keys or values, they are only set if the associated property is defined to have a non null value. If the associated property is not defined in the MSI, the registry key or value will not be touched. By default, the MSI does not contain these properties and hence will not set the registry keys. You will need to add properties as needed to the MSI. When one of the configurable properties is set, the installer will use the property value to set the corresponding setting in the HKEY_LOCAL_MACHINE registry hive. HKEY_CURRENT_USER hive is not touched by the installer. For each property, the associated registry setting is referenced by the same text used in the release notes ('Registry and Environment Settings' section). Strings are quoted using single quotes (e.g. 'a string'). An empty string is denoted as ''. Note that you can't author null values into the 'Property' table. Numeric values should be authored as decimal strings. 2.1.1 Setting Properties In order to set a property, a. Open the MSI in ORCA.EXE b. Select the 'Property' table from the list of tables on the left. c. Find the property in the list of properties on the right, double click the value and type the new value. d. If the property does not exist in the property list, right click the list and select 'Add Row', type the property name and the desired value. 2.1.2 Leash GUI properties LEASHAFSSTATUS Setting: afs token retrieval Values : '0' or '1' LEASHCREATEMISSINGCONFIG Setting: automatic generation of missing configuration files Values : '0' or '1' LEASHAUTORENEWTICKETS Setting: automatic ticket renewal Values : '0' or '1' LEASHLOCKFILELOCATIONS Setting: lock configuration files location Values : '0' or '1' LEASHMSLSAIMPORT Setting: automatic importation of MSLSA credentials Values : '0', '1' or '2' 2.1.3 Leash32 DLL properties LEASHLIFETIME Setting: default lifetime (minutes) Values : numeric LEASHRENEWTILL Setting: default renew till time (minutes) Values : numeric LEASHRENEWABLE Setting: default renewable tickets setting Values : '0' or '1' LEASHFORWARDABLE Setting: default forwardable tickets setting Values : '0' or '1' LEASHNOADDRESSES Setting: default addressless tickets setting Values : '0' or '1' LEASHPROXIABLE Setting: default proxiable tickets setting Values : '0' or '1' LEASHPUBLICIP Setting: default public ipv4 address Values : numeric LEASHUSEKRB4 Setting: request kerberos iv tickets Values : '0' or '1' LEASHHIDEKINITOPTIONS Setting: hide advanced kinit options in dialog Values : '0' or '1' LEASHLIFEMIN Setting: minimum kinit dialog lifetime Values : numeric LEASHLIFEMAX Setting: maximum kinit dialog lifetime Values : numeric LEASHRENEWMIN Setting: minimum kinit dialog renew till time Values : numeric LEASHRENEWMAX Setting: maximum kinit dialog renew till time Values : numeric LEASHUPPERCASEREALM Setting: upper case realm Values : '0' or '1' LEASHTIMEHOST Setting: timesync host Values : string LEASHPRESERVEKINITOPTIONS Setting: Preserve ticket initialization dialog options Values : numeric 2.1.4 Kerberos 4 properties KRB4KRBREALMS (realms full pathname) KRB4KRBCONF (config full pathname) KRB4KRBCONFIDIR (dir for both files) Setting: location of krbrealm & krbconf Values : string (note that the three registry settings are conditioned independently. I.e. If you only set KRB4KRBCONF, only the krb.conf setting will be written.) KRB4TICKETFILE Setting: ticket file Values : string 2.1.5 Kerberos 5 properties KRB5CONFIG Setting: location of krb5.ini Values : string KRB5CCNAME Setting: Default credentials cache name Values : string KRB5PRESERVEIDENTITY Setting: MSLSA: credential cache client principal identity generation Values : '0' or '1' 2.2 Existing Registry Entries You can change existing registry values subject to the restrictions mentioned in the Windows Platform SDK. Pay special attention to component keypaths and try to only change the 'Value' column in the 'Registry' table. If you want to add additional registry keys please refer to section 3 (Additional Resources). 2.3 Replacing Configuration Files The Kerberos configuration files (krb5.ini, krb.con, krbrealm.con) can be replaced by your own configuration files. These files are contained in separate MSI components so that you can disable them individually. The recommended method for replacing these files is to first disable the components containing the configuration files that you want to replace, and then add new components for the replacement files. This is outlined below (assuming you are using ORCA.EXE to author the transform). Note that transforms are not a good way to add a new file as an embedded stream. The method outlined here places the file in the same directory as the MSI for deployment. The walkthrough below is to add a custom 'krb5.ini' file. 1) Disable the component that contains the configuration file that you want to replace. 1.1) Locate and select the 'Component' table in the 'Tables' list. 1.2) In the Component table, locate the component you need to change ( Ctrl-F invokes the 'Find' dialog). The component names are listed below in section 2.3.1. For this example, the component name is 'cmf_krb5_ini'. 1.3) Go to the 'Condition' column of the component. 1.4) Enter a condition that evaluates to false. I.e. 'DONOTINSTALL'. (Note that an undefined property always evaluates to false). Note that you can also use this step to disable other configuration files without providing replacements. 2) Add a new component containing the new configuration file. 2.1) Select the 'Component' table in the 'Tables' list. 2.2) Select 'Tables'->'Add Row' (Ctrl-R). 2.3) Enter the following : Component : cmf_my_krb5_ini ComponentId : {835BAAC6-5E54-BFFE-DBCB2F240711} Directory_ : WindowsFolder Attributes : 144 Condition : KeyPath : fil_my_krb5_ini Note that the ComponentId is an uppercase GUID. You can generate one using GUIDGEN.EXE or UUIDGEN.EXE, both of which are included in the Platform SDK. The Attributes value of 144 is a sum of msidbComponentAttributesPermanent (16) and msidbComponentAttributesNeverOverwrite (128). This ensures that local modifications are not overwritten or lost during an installation or uninstallation. These are the same settings used on the default configuration files. 'fil_my_krb5_ini' is a key into the 'File' table which we will fill later. 3) Add a new feature to hold the new component. 3.1) Select the 'Feature' table. 3.2) Add a new row (Ctrl-R or 'Tables'->'Add Row') with the following values: Feature : fea_my_krb5_ini Feature_Parent: feaKfwClient Title : Description : Display : 0 Level : 30 Directory_ : Attributes : 8 It is important to create the new feature under the 'feaKfwClient' feature, which will ensure that the configuration file will be installed when the client binaries are installed. Setting 'Display' to 0 will hide this feature from the feature selection dialog during an interactive installation. A value of 30 for 'Level' allows this feature to be installed by default (on a 'Typical' installation). The 'Attributes' value is msidbFeatureAttributesDisallowAdvertise (8), which is set on all features in the KfW MSI. The KfW MSI is not designed for an advertised installation. 4) Join the component and the feature. 4.1) Select the 'FeatureComponents' table. 4.2) Add a new row with the following values: Feature : fea_my_krb5_ini Component : cmf_my_krb5_ini 5) Add an entry to the 'File' table. 5.1) Select the 'File' table. 5.2) Add a new row with the following values: File : fil_my_krb5_ini Component_ : cmf_my_krb5_ini FileName : krb5.ini FileSize : (enter file size here) ... Attributes : 8192 Sequence : 1000 (leave other fields blank) The 'Attributes' value is msidbFileAttributesNonCompressed (8192). This is because we will be placing this file in the same directory as the MSI instead of embedding the file in it. Transforms do not support updating compressed sources or adding new cabinet streams. Finally, the 'Sequence' value of 1000 will be used later to distinguish the file as being in a separate source location than the other files in the MSI. 6) Set a media source for the file. 6.1) Select the 'Media' table. 6.2) Add a row with the following values : DiskId : 2 LastSequence : 1000 ... (leave other fields blank) The sequence number of 1000 designates this as the media source for the newly added file. 2.3.1 Components for Configuration Files krb5.ini : 'cmf_krb5_ini' (ID {C1AF0670-BBF1-4AA6-B2A6-6C8B1584A1F4}) krb.con : 'cmf_krb_con' (ID {5391A051-CF14-45FF-BF64-CEE78A7A90C2}) krbrealm.con: 'cmf_krbrealm_con' (ID {D667B54F-1C98-43FB-87C6-0F0517623B90}) ---------------------------------------------------------------------- 3. Network Identity Manager Settings Configuration options for Network Identity Manager (NetIDMgr) are stored in the Windows registry. Each option can exist in the user registry hive or the machine registry hive or both. The value defined in the user hive always overrides the value defined in the machine registry hive. All registry keys used by NetIDMgr exist under the key 'Software\MIT\NetIDMgr' under the user and machine hive. Deploying a specific configuration option can be achieved by setting the corresponding registry value either by authoring the keys into the MSI via a transform or by deploying a registry based Group Policy Object. For deployment purposes, it is advisable to deploy values to the machine hive instead of the user hive. Deploying per user settings via the MSI is not supported at this time. 3.1 Common settings for NetIDMgr The following sections describe a partial list of options that can be specified for NetIDMgr. Each set of options is described as a set of registry values. Each section is preceded by the registry key under which the values of that section must be specified. 3.1.1 General settings Registry key : 'Software\MIT\NetIDMgr\CredWindow' -------------- Value : AllowAutoRenew Type : DWORD (Boolean) Default : 1 Enables automatic credential renewal. Value : AllowCritical Type : DWORD (Boolean) Default : 1 Enables critical warning notifications. Value : AllowWarn Type : DWORD (Boolean) Default : 1 Enables warning notifications. Value : AutoDetectNet Type : DWORD (0 or 1) Default : 1 If '1', automatically detects network connectivity changes. Network connectivity change notifications are then sent out to individual plug-ins which can perform actions such as renewing credentials or obtaining new credentials. Value : AutoImport Type : DWORD (0 or 1) Default : 1 If '1', imports credentials from the Windows LSA cache when NetIDMgr starts. Value : AutoInit Type : DWORD (0 or 1) Default : 0 If this value is '1', shows the new credentials dialog if there are no credentials when NetIDMgr starts. Value : AutoStart Type : DWORD (0 or 1) Default : 0 Start NetIDMgr when Windows starts Value : AutoRenewThreshold Type : DWORD (seconds) Default : 600 Specifies the time period before credential expiration that will trigger a credential renewal. Requires AllowAutoRenew to be enabled. Value : CriticalThreshold Type : DWORD (seconds) Default : 300 Specifies the time period before credential expiration that will trigger the second and final warning balloon. Requires AllowCritical to be enabled. Value : DefaultAllowAutoRenew Type : DWORD (Boolean) Default : 1 Specifies the Default AllowAutoRenew value for new identities. Value : DefaultSticky Type : DWORD (0 or 1) Default : 1 If '0', new identities will not be pinned to the display by default. If '1', new identities will be pinned to the display by default. Value : DefaultWindowMode Type : DWORD (0 or 1) Default : 1 If '0', Advanced mode is used If '1', Basic mode is used Value : DestroyCredsOnExit Type : DWORD (0 or 1) Default : 0 If '1', all credentials will be destroyed when NetIDMgr exits. Value : KeepRunning Type : DWORD (0 or 1) Default : 1 If '1', when NetIDMgr application is closed, it will continue to run in the Windows System Notification Area (System Tray). The application can be exited by choosing the 'Exit' menu option. If '0', closing the application will cause it to exit completely. Value : LogToFile Type : DWORD (0 or 1) Default : 0 If '1', debugging information is logged to %TEMP%\nidmdbg.log Value : NotificationAction Type : DWORD (50008 or 50025) Default : 50025 If '50025', the default notification icon menu action will be to Show the Network Identity Manager application windows. If '50008', the default notification icon menu action will be to display the Obtain New Credentials dialog. Value : RefreshTimeout Type : DWORD (seconds) Default : 60 Specifies how often the credential list is refreshed. Value : RenewAtHalfLife Type : DWORD (Boolean) Default : 1 Enables the use of a half-life algorithm for credential renewals. Value : WarnThreshold Type : DWORD (seconds) Default : 900 Specifies the time period before credential expiration that will trigger the first warning balloon. Requires AllowWarn to be enabled. 3.1.2 Common Plug-in settings Registry key : 'Software\MIT\NetIDMgr\PluginManager\Plugins\' -------------- The '' is one of the following for the standard plug-ins : Krb5Cred : Kerberos 5 credentials provider Krb5Ident: Kerberos 5 Identity provider Krb4Cred : Kerberos 4 credentials provider Consult the vendors for the plug-in names of other third party plug-ins. Additionally, the plug-ins configuration panel in the NetIDMgr application provides a list of currently registered plug-ins. Value : Disabled Type : DWORD (0 or 1) Default : 0 If '1', the plug-in will not be loaded. Value : NoUnload Type : DWORD (0 or 1) Default : 0 If '1', the plug-in will not be unloaded from memory when the NetIDMgr application exits or if the plug-in is stopped. The plug-in binary will remain loaded until NetIDMgr terminates. 3.1.3 Settings for the Kerberos 5 credentials provider plug-in Registry key : 'Software\MIT\NetIDMgr\PluginManager\Plugins\Krb5Cred\Parameters' -------------- Value : AutoRenewTickets Type : DWORD (0 or 1) Default : 1 If '1', automatically renews expiring tickets. The thresholds at which renewals happen are controlled in general NetIDMgr settings. Value : CreateMissingConfig Type : DWORD (0 or 1) Default : 0 If '1', creates any missing configuration files. Value : MsLsaImport Type : DWORD (0, 1 or 2) Default : 1 Controls how credentials are imported from the MSLSA cache. This setting can be one of the following. 0 : Never 1 : Always 2 : Only if the principal matches Note that this setting only controls how the Kerberos 5 plug-in handles importing of credentials from the MSLSA cache. Whether or not credentials are imported at start-up is controlled via general NetIDMgr settings as described in section 3.1.1. Value : MsLsaList Type : DWORD (0 or 1) Default : 1 If '1', includes credentials from the MSLSA cache in the credentials listing. Value : UseFullRealmList Type : DWORD (0 or 1) Default : 0 If '1', uses the full realms list as determined by parsing the krb5.ini configuration file in the new credentials dialog box. If this is '0', only the last recently used list of realms will be used. 3.1.3.1 Per-identity settings Registry key 1: 'Software\MIT\NetIDMgr\KCDB\Identity\\Krb5Cred' Registry key 2: 'Software\MIT\NetIDMgr\PluginManager\Plugins\Krb5Cred\Parameters\Realms\' Registry key 3: 'Software\MIT\NetIDMgr\PluginManager\Plugins\Krb5Cred\Parameters' -------------- These settings are generally maintained per-identity. However, if a particular setting is not specified for an identity or if the identity is new, then the values will be looked up in the per-realm configuration key and in the global parameters key in turn. Global defaults should be set in the global parameters key (key 3). Value : Addressless Type : DWORD (boolean) Default : 1 Determines if addressless tickets will be obtained for new identities. Value : DefaultLifetime Type : DWORD Default : 36000 Default ticket lifetime, in seconds. Value : DefaultRenewLifetime Type : DWORD Default : 604800 Default renewable lifetime, in seconds. Value : FileCCList Type : SZ Default : Specifies a comma delimited list of FILE credential caches to monitor for credentials. Value : Forwardable Type : DWORD (0 or 1) Default : 0 Obtain forwardable tickets. Value : MaxLifetime Type : DWORD Default : 86400 Maximum lifetime, in seconds. This value is used to set the range of the user interface controls that allow setting the lifetime of a ticket. Value : MaxRenewLifetime Type : DWORD Default : 2592000 Maximum renewable lifetime, in seconds. The value is used to set the range of the user interface controls that allow setting the renewable lifetime of a ticket. Value : MinLifetime Type : DWORD Default : 60 Minimum lifetime, in seconds. This value is used to set the range of the user interface controls that allow setting the lifetime of a ticket. Value : MinRenewLifetime Type : DWORD Default : 60 Minimum renewable lifetime, in seconds. This value is used to set the range of the user interface controls that allow setting the renewable lifetime of a ticket. Value : Proxiable Type : DWORD (0 or 1) Default : 0 Obtain proxiable tickets. Value : Renewable Type : DWORD (0 or 1) Default : 1 Obtain renewable tickets. 3.1.4 Settings for the Kerberos 4 Credentials Provider Plug-in Registry key 1: 'Software\MIT\NetIDMgr\KCDB\Identity\\Krb4Cred' Registry key 2: 'Software\MIT\NetIDMgr\PluginManager\Plugins\Krb4Cred\Parameters' --------------- Theses settings are also maintained per identity. However, if the setting is not specified for some identity or if the identity is new, then the global default will be used (registry key 2). Global defaults should be set in the second registry key. Value : Krb4NewCreds Type : DWORD (0 or 1) Default : 1 If '1', obtains Kerberos 4 credentials. Note that currently, only one identity can have Kerberos 4 credentials at one time. Value : Krb4Method Type : DWORD (0, 1 or 2) Default : 0 Method for obtaining Kerberos 4 credentials. The values are as follows: 0 : Automatically determine method 1 : Use password 2 : Use Kerberos 5 to 4 translation Value : DefaultLifetime Type : DWORD Default : 36000 The default ticket lifetime, in seconds. Value : MaxLifetime Type : DWORD Default : 86400 Maximum lifetime, in seconds. This value is used to set the range of the user interface controls that allow setting the lifetime. Value : MinLifetime Type : DWORD Default : 60 Minimum lifetime, in seconds. This value is used to set the range of the user interface controls that allow setting the lifetime. ---------------------------------------------------------------------- 4. Additional Resources If you want to add registry keys or files you need to create new components and features for those. Add new features under the 'feaKfwClient' feature and set the 'Level' column for those features to equal the 'Level' for their parent features for consistency. Note that none of the features in the "Kerberos for Windows" MSI package are designed to be installed to run from 'source' or 'advertised'. It is recommended that you set 'msidbFeatureAttributesFavorLocal' (0), 'msidbFeatureAttributesFollowParent' (2) and 'msidbFeatureAttributesDisallowAdvertise' (8) attributes for new features. If you are creating new components, retain the same component GUID when creating new transforms against new releases of the Kerberos MSI package. It is beyond the scope of this document to provide a comprehensive overview of how to add new resources through a transform. Please refer to the "Windows Installer" documentation for details. The relevant section is at : http://msdn.microsoft.com/library/en-us/msi/setup/using_transforms_to_add_resources.asp A sample walkthrough of adding a new configuration file is in section 2.3. ---------------------------------------------------------------------- 5. Upgrades The MSI package is designed to uninstall previous versions of "Kerberos for Windows" during installation. Note that it doesn't directly upgrade an existing installation. This is intentional and ensures that development releases which do not have strictly increasing version numbers are properly upgraded. Versions of Kerberos that are upgraded by the MSI package are : 1) "Kerberos for Windows" 32-bit i386 MSI package Upgrade code {61211594-AAA1-4A98-A299-757326763CC7} Upto current release 2) "Kerberos for Windows" 64-bit amd64 MSI package Upgrade code {6DA9CD86-6028-4852-8C94-452CAC229244} Upto current release 2) "MIT Project Pismere Kerberos for Windows" MSI package and "MIT SWRT Kerberos for Windows" MSI Upgrade code {83977767-388D-4DF8-BB08-3BF2401635BD} All versions 3) "Kerberos for Windows" NSIS package All versions Note that versions of the "Kerberos for Windows" NSIS package had a bug where it couldn't be uninstalled properly in unattended mode. Therefore the MSI package will not try to uninstall an "Kerberos for Windows" NSIS package if running unattended. This means that group policy based deployments will fail on machines that have the "Kerberos for Windows" NSIS package installed. Note that the NSIS package is only available for 32-bit i386. You cannot install both the 32-bit NSIS and 64-bit amd64 MSI packages on the same machine. To install both 32-bit and 64-bit KFW, you must use the MSI packages of both. If you have used a different MSI package to install Kerberos for Windows and wish to upgrade it you can author rows into the 'Upgrade' table to have the "Kerberos for Windows" MSI replace these installations for you. ---------------------------------------------------------------------- 6. FAQ (Q/A's will be added here as needed) ---------------------------------------------------------------------- $Id$ krb5-1.16/src/windows/installer/wix/athena/0000755000704600001450000000000013211554426020523 5ustar ghudsonlibuuidkrb5-1.16/src/windows/installer/wix/athena/krb5.ini0000644000704600001450000000022213211554426022063 0ustar ghudsonlibuuid[libdefaults] default_realm = ATHENA.MIT.EDU [domain_realm] mit.edu = ATHENA.MIT.EDU win.mit.edu = WIN.MIT.EDU csail.mit.edu = CSAIL.MIT.EDU krb5-1.16/src/windows/installer/wix/features.wxi0000644000704600001450000001662413211554426021643 0ustar ghudsonlibuuid LEASHAUTOSTART = 1 krb5-1.16/src/windows/installer/wix/Binary/0000755000704600001450000000000013211554426020507 5ustar ghudsonlibuuidkrb5-1.16/src/windows/installer/wix/Binary/new.bmp0000644000704600001450000000047613211554426022007 0ustar ghudsonlibuuid((   }krb5-1.16/src/windows/installer/wix/Binary/dlgbmp.bmp0000644000704600001450000232201613211554426022462 0ustar ghudsonlibuuidBM 6(: أ qpqNLMB@AB@AB@AB@AB@ANLMqpqqpqB@AMKL_^_nmmqqq|||||||||qqqnmm_^_TSSFDEB@A}|}B@AXWWuuu||||||||||||||||||||||||||||||||||||jijXWWB@AZXYNLMMKLqqq||||||||||||||||||||||||||||||||||||||||||||||||xxx_^_FDEZXYNLMXWWxxx|||||||||MKKMKKMKKMKKMKKMKKMKKMKKMKKMKK||||||||||||||||||xxx_^_B@AqpqMKKMKKMKKMKKMKKMKKMKKMKKZXYXWW|||||||||||||||MKKMKK||||||||||||||||||||||||jiiMKKMKKMKK}|}MKLxxx|||||||||||||||MKKMKK|||||||||||||||||||||xxxMKKMKKMKKB@Aqqq||||||||||||||||||MKKMKK|||||||||||||||||||||MKKMKKMKKqpqXWW|||||||||||||||||||||MKKMKK||||||||||||||||||nmmMKKMKKB@Aqqq|||||||||||||||||||||MKKMKK|||||||||||||||xxxMKKMKKMKL||||||||||||||||||||||||MKKMKK|||||||||||||||MKKMKKqpq[Z[||||||||||||||||||||||||MKKMKK||||||||||||MKKMKKfdeNLMjij||||||||||||||||||||||||MKKMKK|||||||||MKKMKKxxxMKLqpqB@Auuu||||||||||||||||||||||||MKKMKK||||||MKKMKKuuu|||qqqFDEB@A|||||||||||||||||||||||||||MKKMKKqqqMKKMKK||||||||||||jijB@AB@A|||||||||||||||||||||||||||MKKMKKMKKMKK||||||||||||||||||[Z[ZXYB@A|||||||||||||||||||||||||||MKKMKKMKK|||uuu|||||||||||||||xxxIHHB@A|||||||||||||||||||||||||||MKKMKK|||||||||||||||||||||||||||jijB@AB@Axxx||||||||||||||||||||||||MKKMKK|||||||||||||||||||||||||||||||||QOP}|}B@Anmm||||||||||||||||||||||||MKKMKK||||||xxx|||||||||||||||||||||||||||nmmB@Afdefff||||||||||||||||||||||||MKKMKK||||||||||||||||||||||||||||||||||||||||||QOPXWW||||||||||||||||||||||||MKKMKK|||||||||||||||||||||||||||||||||||||||||||||nmmB@AIHH||||||||||||||||||||||||MKKMKK|||xxx|||||||||||||||||||||||||||||||||||||||IHHB@Auuu|||||||||||||||||||||MKKMKKqqq|||||||||||||||||||||||||||||||||||||||cbbfdefdecbb|||||||||||||||||||||MKKMKKuuu||||||||||||||||||||||||||||||||||||uuuB@AIHH|||||||||||||||||||||MKKMKKMKKxxx||||||||||||||||||||||||||||||||||||IHHB@Anmm||||||||||||||||||MKKMKKMKKMKKxxx|||||||||||||||||||||||||||||||||XWWQOP||||||||||||||||||MKKMKK|||MKKMKKxxx||||||||||||||||||||||||||||||ffffdeB@Anmm|||||||||||||||MKKMKK||||||MKKMKK||||||||||||||||||||||||||||||nmmB@A}|}QOP|||||||||||||||MKKMKK|||||||||MKKMKK|||||||||||||||||||||||||||xxxB@AB@Ajij||||||||||||MKKMKK||||||||||||MKKMKK|||||||||||||||||||||||||||B@AIHHxxx|||||||||MKKMKK|||||||||||||||MKKMKK||||||||||||||||||||||||B@AZXY[Z[|||||||||MKKMKK||||||||||||xxx|||MKKMKK|||||||||||||||||||||B@AB@Ajij||||||MKKMKK|||||||||||||||xxx|||MKKMKK|||||||||||||||||||||B@AFDEqqq|||MKKMKK||||||||||||||||||||||||MKKMKKMKKMKKMKKMKKMKKMKKMKKMKK||||||||||||||||||uuuB@AqpqMKLxxxMKKMKK||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||jijNLMfdeMKLMKKMKK||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||[Z[qpqNLMMKKMKK||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||MKLMKKMKK|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||qqqB@AMKKMKK|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||XWWqpqMKKMKK||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||nmmB@AMKKMKK|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||xxxMKL}|}MKKMKK|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||XWWZXYMKKMKK|||||||||||||||||||||||||||||||||||||||||||||||||||||||||xxxXWWNLMMKKMKKMKKMKKMKKMKKMKKMKKMKKMKK_^_xxx||||||||||||||||||||||||||||||||||||||||||||||||qqqMKLZXYZXYB@AXWWjij||||||||||||||||||||||||||||||||||||uuuXWWB@A}|}B@AFDETSS_^_nmmqqq|||||||||qqqnmm_^_MKLB@AqpqqpqNLMB@AB@AB@AB@AB@ANLMqpqkrb5-1.16/src/windows/installer/wix/Binary/up.bmp0000644000704600001450000000047613211554426021642 0ustar ghudsonlibuuid((  krb5-1.16/src/windows/installer/wix/Binary/exclamic.ico0000644000704600001450000000137613211554426022777 0ustar ghudsonlibuuid ( @33133233333333333333$DDDDDDDDDDD@12DDDDDDDDDDDDD2DDDDDD@DDDDDDC2DDDDDD34DDDDDC2DDDDD@30DDDDD3$DDDDD34DDDDD13$DDDDD@DDDDD@1332DDDDDDDDDDDC332DDDDDCDDDDD333$DDDDDDDD1333$DDDD#$DDD@133332DDDD34DDDC33332DDD@30DDD33333$DDB32DDD133333$DDC33DD@13333332DDC33DDC3333332DDC33DD3333333$DC33DD13333333$DC33D@1333333332D@30DC333333332DDDDD333333333$DDDD1333333333$DDD@133333333332DDDC33333333332DDD33333333333$DD133333333333$D@13333333333332D3333333333333"#33333333333333333333333??krb5-1.16/src/windows/installer/wix/Binary/repairic.ico0000644000704600001450000000566613211554426023016 0ustar ghudsonlibuuid & ( @w{px{wp({w(xxx(w(w~xx(~www(zxxw w p  wp wwwwwxpx"DDDDDOxvflOxwffOxvflOxwffOxwxvfOxw~wfOxwvOxw~wOxDDDDDOxwxw?0 ( @ʦkH%zbJs2PkHs%WUI=1%sPkkHH%%sPDZksHW%UI=1%sPԎkH%zbJs2PkH%ssPPkH%zbsJP2kHs%WUI=1s%PkkHH%%sPDZksHW%UI=1s%PԎkH%ܒzbsJP2kH%ssPPkH%zbJs2PksHW%UI=1%sPkkHH%%sPkHs%WUI=1s%PkH%ܒzbsJP2kH%ssPPzzznnnbbbVVVJJJ>>>222&&&ززؕ؉º嗜ĺºĺº㜜ĺ㜕ºĺºĺº*-*-*--{{{{{{?0 krb5-1.16/src/windows/installer/wix/Binary/removico.ico0000644000704600001450000000566613211554426023043 0ustar ghudsonlibuuid & ( @pwwwwfwwvvfwnfflwww|wgwwwg|wgw|wwg|wwwwwwgtDDw~www~ww|wwwwwllw~fftwwvlgtwwwwwwwwwwtwwwwwwwwxD\wwwwGwwwwwep;wv_{{pwegv\!0~v{7pogp8p{4o?o803F??( @ʦkH%zbJs2PkHs%WUI=1%sPkkHH%%sPDZksHW%UI=1%sPԎkH%zbJs2PkH%ssPPkH%zbsJP2kHs%WUI=1s%PkkHH%%sPDZksHW%UI=1s%PԎkH%ܒzbsJP2kH%ssPPkH%zbJs2PksHW%UI=1%sPkkHH%%sPkHs%WUI=1s%PkH%ܒzbsJP2kH%ssPPzzznnnbbbVVVJJJ>>>222&&&j""j""jj"m{j"yymmm{jyymj"joomym"jjojymm"j~mm"jj~jy"j"jj~my"jjj"jm{o~~m"j{oo~j"j"jo~~m""j{oo~jmm{{{oo~~mmm{{o~gj{oojgmjjg""jm" u"mj""uj"u"""juj"y y""uju yuyy"jju y ujE""u??krb5-1.16/src/windows/installer/wix/Binary/bannrbmp.bmp0000644000704600001450000036614613211554426023026 0ustar ghudsonlibuuidBMf6(? 0砠qqpqMNLMAB@AAB@AAB@AAB@AAB@AMNLMqqpqqqpqAB@ALMKL__^_mnmmqqqq||||||||||||qqqqmnmm__^_STSSEFDEAB@A}}|}AB@AWXWWuuuu||||||||||||||||||||||||||||||||||||||||||||||||jjijWXWWAB@AYZXYMNLMLMKLqqqq||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||xxxx__^_EFDEYZXYMNLMWXWWxxxx||||||||||||KMKKKMKKKMKKKMKKKMKKKMKKKMKKKMKKKMKKKMKK||||||||||||||||||||||||xxxx__^_AB@AqqpqKMKKKMKKKMKKKMKKKMKKKMKKKMKKKMKKYZXYWXWW||||||||||||||||||||KMKKKMKK||||||||||||||||||||||||||||||||ijiiKMKKKMKKKMKK}}|}LMKLxxxx||||||||||||||||||||KMKKKMKK||||||||||||||||||||||||||||xxxxKMKKKMKKKMKKAB@Aqqqq||||||||||||||||||||||||KMKKKMKK||||||||||||||||||||||||||||KMKKKMKKKMKKqqpqWXWW||||||||||||||||||||||||||||KMKKKMKK||||||||||||||||||||||||mnmmKMKKKMKKAB@Aqqqq||||||||||||||||||||||||||||KMKKKMKK||||||||||||||||||||xxxxKMKKKMKKLMKL||||||||||||||||||||||||||||||||KMKKKMKK||||||||||||||||||||KMKKKMKKqqpq[[Z[||||||||||||||||||||||||||||||||KMKKKMKK||||||||||||||||KMKKKMKKefdeMNLMjjij||||||||||||||||||||||||||||||||KMKKKMKK||||||||||||KMKKKMKKxxxxLMKLqqpqAB@Auuuu||||||||||||||||||||||||||||||||KMKKKMKK||||||||KMKKKMKKuuuu||||qqqqEFDEAB@A||||||||||||||||||||||||||||||||||||KMKKKMKKqqqqKMKKKMKK||||||||||||||||jjijAB@AAB@A||||||||||||||||||||||||||||||||||||KMKKKMKKKMKKKMKK||||||||||||||||||||||||[[Z[YZXYAB@A||||||||||||||||||||||||||||||||||||KMKKKMKKKMKK||||uuuu||||||||||||||||||||xxxxHIHHAB@A||||||||||||||||||||||||||||||||||||KMKKKMKK||||||||||||||||||||||||||||||||||||jjijAB@AAB@Axxxx||||||||||||||||||||||||||||||||KMKKKMKK||||||||||||||||||||||||||||||||||||||||||||PQOP}}|}AB@Amnmm||||||||||||||||||||||||||||||||KMKKKMKK||||||||xxxx||||||||||||||||||||||||||||||||||||mnmmAB@Aefdeffff||||||||||||||||||||||||||||||||KMKKKMKK||||||||||||||||||||||||||||||||||||||||||||||||||||||||PQOPWXWW||||||||||||||||||||||||||||||||KMKKKMKK||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||mnmmAB@AHIHH||||||||||||||||||||||||||||||||KMKKKMKK||||xxxx||||||||||||||||||||||||||||||||||||||||||||||||||||HIHHAB@Auuuu||||||||||||||||||||||||||||KMKKKMKKqqqq||||||||||||||||||||||||||||||||||||||||||||||||||||bcbbefdeefdebcbb||||||||||||||||||||||||||||KMKKKMKKuuuu||||||||||||||||||||||||||||||||||||||||||||||||uuuuAB@AHIHH||||||||||||||||||||||||||||KMKKKMKKKMKKxxxx||||||||||||||||||||||||||||||||||||||||||||||||HIHHAB@Amnmm||||||||||||||||||||||||KMKKKMKKKMKKKMKKxxxx||||||||||||||||||||||||||||||||||||||||||||WXWWPQOP||||||||||||||||||||||||KMKKKMKK||||KMKKKMKKxxxx||||||||||||||||||||||||||||||||||||||||ffffefdeAB@Amnmm||||||||||||||||||||KMKKKMKK||||||||KMKKKMKK||||||||||||||||||||||||||||||||||||||||mnmmAB@A}}|}PQOP||||||||||||||||||||KMKKKMKK||||||||||||KMKKKMKK||||||||||||||||||||||||||||||||||||xxxxAB@AAB@Ajjij||||||||||||||||KMKKKMKK||||||||||||||||KMKKKMKK||||||||||||||||||||||||||||||||||||AB@AHIHHxxxx||||||||||||KMKKKMKK||||||||||||||||||||KMKKKMKK||||||||||||||||||||||||||||||||AB@AYZXY[[Z[||||||||||||KMKKKMKK||||||||||||||||xxxx||||KMKKKMKK||||||||||||||||||||||||||||AB@AAB@Ajjij||||||||KMKKKMKK||||||||||||||||||||xxxx||||KMKKKMKK||||||||||||||||||||||||||||AB@AEFDEqqqq||||KMKKKMKK||||||||||||||||||||||||||||||||KMKKKMKKKMKKKMKKKMKKKMKKKMKKKMKKKMKKKMKK||||||||||||||||||||||||uuuuAB@AqqpqLMKLxxxxKMKKKMKK||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||jjijMNLMefdeLMKLKMKKKMKK||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||[[Z[qqpqMNLMKMKKKMKK||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||LMKLKMKKKMKK||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||qqqqAB@AKMKKKMKK||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||WXWWqqpqKMKKKMKK||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||mnmmAB@AKMKKKMKK||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||xxxxLMKL}}|}KMKKKMKK||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||WXWWYZXYKMKKKMKK||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||xxxxWXWWMNLMKMKKKMKKKMKKKMKKKMKKKMKKKMKKKMKKKMKKKMKK__^_xxxx||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||qqqqLMKLYZXYYZXYAB@AWXWWjjij||||||||||||||||||||||||||||||||||||||||||||||||uuuuWXWWAB@A}}|}ÉAB@AEFDESTSS__^_mnmmqqqq||||||||||||qqqqmnmm__^_LMKLAB@AqqpqàqqpqMNLMAB@AAB@AAB@AAB@AAB@AMNLMqqpqkrb5-1.16/src/windows/installer/wix/Binary/info.bmp0000644000704600001450000000206613211554426022146 0ustar ghudsonlibuuid &(( @pwpppppwwwwwpwwwwwpwwwpwwwpwpwwxwwwwwpxppwwwxwwwwp??( pwxppwwpwwwpkrb5-1.16/src/windows/installer/wix/Binary/custicon.ico0000644000704600001450000000566613211554426023047 0ustar ghudsonlibuuid & ( @w{px{wp{wxxxww~xx~wwwzxxwwpwpwwwwwxxDDDDDOxvflOxwffOxvflOxwffOxvfOx~wfOxwvOxw~wOxDDDDDOxx?( @ʦkH%zbJs2PkHs%WUI=1%sPkkHH%%sPDZksHW%UI=1%sPԎkH%zbJs2PkH%ssPPkH%zbsJP2kHs%WUI=1s%PkkHH%%sPDZksHW%UI=1s%PԎkH%ܒzbsJP2kH%ssPPkH%zbJs2PksHW%UI=1%sPkkHH%%sPkHs%WUI=1s%PkH%ܒzbsJP2kH%ssPPzzznnnbbbVVVJJJ>>>222&&&ززؕ؉嗜㜜㜕{{{{{{?krb5-1.16/src/windows/installer/wix/Binary/completi.ico0000644000704600001450000000566613211554426023034 0ustar ghudsonlibuuid & ( @w{px{wp{wxxxww~xx~wwwzxxwwpwpwwwwwxxDDDDDOxvflOxwffOxvflOxwffOxvfOx~wfOxwvOxw~wOxDDDDDOxx?( @ʦkH%zbJs2PkHs%WUI=1%sPkkHH%%sPDZksHW%UI=1%sPԎkH%zbJs2PkH%ssPPkH%zbsJP2kHs%WUI=1s%PkkHH%%sPDZksHW%UI=1s%PԎkH%ܒzbsJP2kH%ssPPkH%zbJs2PksHW%UI=1%sPkkHH%%sPkHs%WUI=1s%PkH%ܒzbsJP2kH%ssPPzzznnnbbbVVVJJJ>>>222&&&ززؕ؉嗜㜜㜕{{{{{{?krb5-1.16/src/windows/installer/wix/Binary/insticon.ico0000644000704600001450000000566613211554426023046 0ustar ghudsonlibuuid & ( @{wpxwxwwpxxw~x ~pxxpxwpzxxpxzxxxwwwwwwwwwpwwwwwwwpwwwwwwwwxwxDDDDDOxvflOxwffOxvflOxwffOxvfOx~wfOxwvOxw~wOxDDDDDOxxp ??????( @ʦkH%zbJs2PkHs%WUI=1%sPkkHH%%sPDZksHW%UI=1%sPԎkH%zbJs2PkH%ssPPkH%zbsJP2kHs%WUI=1s%PkkHH%%sPDZksHW%UI=1s%PԎkH%ܒzbsJP2kH%ssPPkH%zbJs2PksHW%UI=1%sPkkHH%%sPkHs%WUI=1s%PkH%ܒzbsJP2kH%ssPPzzznnnbbbVVVJJJ>>>222&&&ززؕ؉嗜㜜㜕{{{{{{p ??????krb5-1.16/src/windows/installer/wix/property.wxi0000644000704600001450000001342013211554426021700 0ustar ghudsonlibuuid 1 -autoinit 1 $(var.ARPComments) kerberos@mit.edu http://web.mit.edu/kerberos http://web.mit.edu/kerberos 50 http://web.mit.edu/kerberos !(loc.CantRemoveNSIS) !(loc.IE501Required) $(var.LeashAfsStatus) $(var.LeashCreateMissingConfig) $(var.LeashAutoRenewTickets) $(var.LeashLockFileLocations) $(var.LeashMsLsaImport) $(var.LeashLifetime) $(var.LeashRenewTill) $(var.LeashRenewable) $(var.LeashForwardable) $(var.LeashNoAddresses) $(var.LeashProxiable) $(var.LeashPublicIp) $(var.LeashUseKrb4) $(var.LeashHideKinitOptions) $(var.LeashLifeMin) $(var.LeashLifeMax) $(var.LeashRenewMin) $(var.LeashRenewMax) $(var.LeashUppercaseRealm) $(var.LeashTimeHost) $(var.LeashPreserveKinitOptions) $(var.Krb4KrbRealms) $(var.Krb4KrbConf) $(var.Krb4ConfigDir) $(var.Krb4TicketFile) $(var.Krb5Config) $(var.Krb5CcName) $(var.Krb5PreserveIdentity) $(var.UseLeash) $(var.UseNetIDMgr) krb5-1.16/src/windows/installer/wix/site-local.wxi0000644000704600001450000000615613211554426022060 0ustar ghudsonlibuuid krb5-1.16/src/windows/kfwlogon/0000755000704600001450000000000013211554426016305 5ustar ghudsonlibuuidkrb5-1.16/src/windows/kfwlogon/kfwcommon.c0000644000704600001450000010523213211554426020454 0ustar ghudsonlibuuid/* Copyright 2005,2006 by the Massachusetts Institute of Technology Copyright 2007 by Secure Endpoints Inc. All rights reserved. Permission to use, copy, modify, and distribute this software and its documentation for any purpose and without fee is hereby granted, provided that the above copyright notice appear in all copies and that both that copyright notice and this permission notice appear in supporting documentation, and that the name of the Massachusetts Institute of Technology (M.I.T.) not be used in advertising or publicity pertaining to distribution of the software without specific, written prior permission. M.I.T. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL M.I.T. 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 "kfwlogon.h" #include #include #include #include #include #include #include #include #include #include #include #include #include /* Function Pointer Declarations for Delayed Loading */ // CCAPI DECL_FUNC_PTR(cc_initialize); DECL_FUNC_PTR(cc_shutdown); DECL_FUNC_PTR(cc_get_NC_info); DECL_FUNC_PTR(cc_free_NC_info); // leash functions DECL_FUNC_PTR(Leash_get_default_lifetime); DECL_FUNC_PTR(Leash_get_default_forwardable); DECL_FUNC_PTR(Leash_get_default_renew_till); DECL_FUNC_PTR(Leash_get_default_noaddresses); DECL_FUNC_PTR(Leash_get_default_proxiable); DECL_FUNC_PTR(Leash_get_default_publicip); DECL_FUNC_PTR(Leash_get_default_use_krb4); DECL_FUNC_PTR(Leash_get_default_life_min); DECL_FUNC_PTR(Leash_get_default_life_max); DECL_FUNC_PTR(Leash_get_default_renew_min); DECL_FUNC_PTR(Leash_get_default_renew_max); DECL_FUNC_PTR(Leash_get_default_renewable); DECL_FUNC_PTR(Leash_get_default_mslsa_import); // krb5 functions DECL_FUNC_PTR(krb5_change_password); DECL_FUNC_PTR(krb5_get_init_creds_opt_init); DECL_FUNC_PTR(krb5_get_init_creds_opt_set_tkt_life); DECL_FUNC_PTR(krb5_get_init_creds_opt_set_renew_life); DECL_FUNC_PTR(krb5_get_init_creds_opt_set_forwardable); DECL_FUNC_PTR(krb5_get_init_creds_opt_set_proxiable); DECL_FUNC_PTR(krb5_get_init_creds_opt_set_address_list); DECL_FUNC_PTR(krb5_get_init_creds_password); DECL_FUNC_PTR(krb5_build_principal_ext); DECL_FUNC_PTR(krb5_cc_get_name); DECL_FUNC_PTR(krb5_cc_resolve); DECL_FUNC_PTR(krb5_cc_default); DECL_FUNC_PTR(krb5_cc_default_name); DECL_FUNC_PTR(krb5_cc_set_default_name); DECL_FUNC_PTR(krb5_cc_initialize); DECL_FUNC_PTR(krb5_cc_destroy); DECL_FUNC_PTR(krb5_cc_close); DECL_FUNC_PTR(krb5_cc_store_cred); DECL_FUNC_PTR(krb5_cc_copy_creds); DECL_FUNC_PTR(krb5_cc_retrieve_cred); DECL_FUNC_PTR(krb5_cc_get_principal); DECL_FUNC_PTR(krb5_cc_start_seq_get); DECL_FUNC_PTR(krb5_cc_next_cred); DECL_FUNC_PTR(krb5_cc_end_seq_get); DECL_FUNC_PTR(krb5_cc_remove_cred); DECL_FUNC_PTR(krb5_cc_set_flags); DECL_FUNC_PTR(krb5_cc_get_type); DECL_FUNC_PTR(krb5_free_context); DECL_FUNC_PTR(krb5_free_cred_contents); DECL_FUNC_PTR(krb5_free_principal); DECL_FUNC_PTR(krb5_get_in_tkt_with_password); DECL_FUNC_PTR(krb5_init_context); DECL_FUNC_PTR(krb5_parse_name); DECL_FUNC_PTR(krb5_timeofday); DECL_FUNC_PTR(krb5_timestamp_to_sfstring); DECL_FUNC_PTR(krb5_unparse_name); DECL_FUNC_PTR(krb5_get_credentials); DECL_FUNC_PTR(krb5_mk_req); DECL_FUNC_PTR(krb5_sname_to_principal); DECL_FUNC_PTR(krb5_get_credentials_renew); DECL_FUNC_PTR(krb5_free_data); DECL_FUNC_PTR(krb5_free_data_contents); DECL_FUNC_PTR(krb5_free_unparsed_name); DECL_FUNC_PTR(krb5_os_localaddr); DECL_FUNC_PTR(krb5_copy_keyblock_contents); DECL_FUNC_PTR(krb5_copy_data); DECL_FUNC_PTR(krb5_free_creds); DECL_FUNC_PTR(krb5_build_principal); DECL_FUNC_PTR(krb5_get_renewed_creds); DECL_FUNC_PTR(krb5_get_default_config_files); DECL_FUNC_PTR(krb5_free_config_files); DECL_FUNC_PTR(krb5_get_default_realm); DECL_FUNC_PTR(krb5_free_default_realm); DECL_FUNC_PTR(krb5_free_ticket); DECL_FUNC_PTR(krb5_decode_ticket); DECL_FUNC_PTR(krb5_get_host_realm); DECL_FUNC_PTR(krb5_free_host_realm); DECL_FUNC_PTR(krb5_free_addresses); DECL_FUNC_PTR(krb5_c_random_make_octets); // ComErr functions DECL_FUNC_PTR(com_err); DECL_FUNC_PTR(error_message); // Profile functions DECL_FUNC_PTR(profile_init); DECL_FUNC_PTR(profile_release); DECL_FUNC_PTR(profile_get_subsection_names); DECL_FUNC_PTR(profile_free_list); DECL_FUNC_PTR(profile_get_string); DECL_FUNC_PTR(profile_release_string); // Service functions DECL_FUNC_PTR(OpenSCManagerA); DECL_FUNC_PTR(OpenServiceA); DECL_FUNC_PTR(QueryServiceStatus); DECL_FUNC_PTR(CloseServiceHandle); DECL_FUNC_PTR(LsaNtStatusToWinError); // LSA Functions DECL_FUNC_PTR(LsaConnectUntrusted); DECL_FUNC_PTR(LsaLookupAuthenticationPackage); DECL_FUNC_PTR(LsaCallAuthenticationPackage); DECL_FUNC_PTR(LsaFreeReturnBuffer); DECL_FUNC_PTR(LsaGetLogonSessionData); // CCAPI FUNC_INFO ccapi_fi[] = { MAKE_FUNC_INFO(cc_initialize), MAKE_FUNC_INFO(cc_shutdown), MAKE_FUNC_INFO(cc_get_NC_info), MAKE_FUNC_INFO(cc_free_NC_info), END_FUNC_INFO }; FUNC_INFO leash_fi[] = { MAKE_FUNC_INFO(Leash_get_default_lifetime), MAKE_FUNC_INFO(Leash_get_default_renew_till), MAKE_FUNC_INFO(Leash_get_default_forwardable), MAKE_FUNC_INFO(Leash_get_default_noaddresses), MAKE_FUNC_INFO(Leash_get_default_proxiable), MAKE_FUNC_INFO(Leash_get_default_publicip), MAKE_FUNC_INFO(Leash_get_default_use_krb4), MAKE_FUNC_INFO(Leash_get_default_life_min), MAKE_FUNC_INFO(Leash_get_default_life_max), MAKE_FUNC_INFO(Leash_get_default_renew_min), MAKE_FUNC_INFO(Leash_get_default_renew_max), MAKE_FUNC_INFO(Leash_get_default_renewable), END_FUNC_INFO }; FUNC_INFO leash_opt_fi[] = { MAKE_FUNC_INFO(Leash_get_default_mslsa_import), END_FUNC_INFO }; FUNC_INFO k5_fi[] = { MAKE_FUNC_INFO(krb5_change_password), MAKE_FUNC_INFO(krb5_get_init_creds_opt_init), MAKE_FUNC_INFO(krb5_get_init_creds_opt_set_tkt_life), MAKE_FUNC_INFO(krb5_get_init_creds_opt_set_renew_life), MAKE_FUNC_INFO(krb5_get_init_creds_opt_set_forwardable), MAKE_FUNC_INFO(krb5_get_init_creds_opt_set_proxiable), MAKE_FUNC_INFO(krb5_get_init_creds_opt_set_address_list), MAKE_FUNC_INFO(krb5_get_init_creds_password), MAKE_FUNC_INFO(krb5_build_principal_ext), MAKE_FUNC_INFO(krb5_cc_get_name), MAKE_FUNC_INFO(krb5_cc_resolve), MAKE_FUNC_INFO(krb5_cc_default), MAKE_FUNC_INFO(krb5_cc_default_name), MAKE_FUNC_INFO(krb5_cc_set_default_name), MAKE_FUNC_INFO(krb5_cc_initialize), MAKE_FUNC_INFO(krb5_cc_destroy), MAKE_FUNC_INFO(krb5_cc_close), MAKE_FUNC_INFO(krb5_cc_copy_creds), MAKE_FUNC_INFO(krb5_cc_store_cred), MAKE_FUNC_INFO(krb5_cc_retrieve_cred), MAKE_FUNC_INFO(krb5_cc_get_principal), MAKE_FUNC_INFO(krb5_cc_start_seq_get), MAKE_FUNC_INFO(krb5_cc_next_cred), MAKE_FUNC_INFO(krb5_cc_end_seq_get), MAKE_FUNC_INFO(krb5_cc_remove_cred), MAKE_FUNC_INFO(krb5_cc_set_flags), MAKE_FUNC_INFO(krb5_cc_get_type), MAKE_FUNC_INFO(krb5_free_context), MAKE_FUNC_INFO(krb5_free_cred_contents), MAKE_FUNC_INFO(krb5_free_principal), MAKE_FUNC_INFO(krb5_get_in_tkt_with_password), MAKE_FUNC_INFO(krb5_init_context), MAKE_FUNC_INFO(krb5_parse_name), MAKE_FUNC_INFO(krb5_timeofday), MAKE_FUNC_INFO(krb5_timestamp_to_sfstring), MAKE_FUNC_INFO(krb5_unparse_name), MAKE_FUNC_INFO(krb5_get_credentials), MAKE_FUNC_INFO(krb5_mk_req), MAKE_FUNC_INFO(krb5_sname_to_principal), MAKE_FUNC_INFO(krb5_get_credentials_renew), MAKE_FUNC_INFO(krb5_free_data), MAKE_FUNC_INFO(krb5_free_data_contents), MAKE_FUNC_INFO(krb5_free_unparsed_name), MAKE_FUNC_INFO(krb5_os_localaddr), MAKE_FUNC_INFO(krb5_copy_keyblock_contents), MAKE_FUNC_INFO(krb5_copy_data), MAKE_FUNC_INFO(krb5_free_creds), MAKE_FUNC_INFO(krb5_build_principal), MAKE_FUNC_INFO(krb5_get_renewed_creds), MAKE_FUNC_INFO(krb5_free_addresses), MAKE_FUNC_INFO(krb5_get_default_config_files), MAKE_FUNC_INFO(krb5_free_config_files), MAKE_FUNC_INFO(krb5_get_default_realm), MAKE_FUNC_INFO(krb5_free_default_realm), MAKE_FUNC_INFO(krb5_free_ticket), MAKE_FUNC_INFO(krb5_decode_ticket), MAKE_FUNC_INFO(krb5_get_host_realm), MAKE_FUNC_INFO(krb5_free_host_realm), MAKE_FUNC_INFO(krb5_free_addresses), MAKE_FUNC_INFO(krb5_c_random_make_octets), END_FUNC_INFO }; FUNC_INFO profile_fi[] = { MAKE_FUNC_INFO(profile_init), MAKE_FUNC_INFO(profile_release), MAKE_FUNC_INFO(profile_get_subsection_names), MAKE_FUNC_INFO(profile_free_list), MAKE_FUNC_INFO(profile_get_string), MAKE_FUNC_INFO(profile_release_string), END_FUNC_INFO }; FUNC_INFO ce_fi[] = { MAKE_FUNC_INFO(com_err), MAKE_FUNC_INFO(error_message), END_FUNC_INFO }; FUNC_INFO service_fi[] = { MAKE_FUNC_INFO(OpenSCManagerA), MAKE_FUNC_INFO(OpenServiceA), MAKE_FUNC_INFO(QueryServiceStatus), MAKE_FUNC_INFO(CloseServiceHandle), MAKE_FUNC_INFO(LsaNtStatusToWinError), END_FUNC_INFO }; FUNC_INFO lsa_fi[] = { MAKE_FUNC_INFO(LsaConnectUntrusted), MAKE_FUNC_INFO(LsaLookupAuthenticationPackage), MAKE_FUNC_INFO(LsaCallAuthenticationPackage), MAKE_FUNC_INFO(LsaFreeReturnBuffer), MAKE_FUNC_INFO(LsaGetLogonSessionData), END_FUNC_INFO }; /* Static Declarations */ static int inited = 0; static HINSTANCE hKrb5 = 0; static HINSTANCE hKrb524 = 0; static HINSTANCE hSecur32 = 0; static HINSTANCE hAdvApi32 = 0; static HINSTANCE hComErr = 0; static HINSTANCE hService = 0; static HINSTANCE hProfile = 0; static HINSTANCE hLeash = 0; static HINSTANCE hLeashOpt = 0; static HINSTANCE hCCAPI = 0; static DWORD TraceOption = 0; static HANDLE hDLL; BOOL IsDebugLogging(void) { DWORD LSPsize; HKEY NPKey; DWORD dwDebug = FALSE; if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, "System\\CurrentControlSet\\Services\\MIT Kerberos\\NetworkProvider", 0, KEY_QUERY_VALUE, &NPKey) == ERROR_SUCCESS) { LSPsize=sizeof(dwDebug); if (RegQueryValueEx(NPKey, "Debug", NULL, NULL, (LPBYTE)&dwDebug, &LSPsize) != ERROR_SUCCESS) { dwDebug = FALSE; } RegCloseKey (NPKey); } return(dwDebug ? TRUE : FALSE); } void DebugEvent0(char *a) { HANDLE h; char *ptbuf[1]; if (IsDebugLogging()) { h = RegisterEventSource(NULL, KFW_LOGON_EVENT_NAME); if (h) { ptbuf[0] = a; ReportEvent(h, EVENTLOG_INFORMATION_TYPE, 0, 0, NULL, 1, 0, (const char **)ptbuf, NULL); DeregisterEventSource(h); } } } #define MAXBUF_ 512 void DebugEvent(char *b,...) { HANDLE h; char *ptbuf[1],buf[MAXBUF_+1]; va_list marker; if (IsDebugLogging()) { h = RegisterEventSource(NULL, KFW_LOGON_EVENT_NAME); if (h) { va_start(marker,b); StringCbVPrintf(buf, MAXBUF_+1,b,marker); buf[MAXBUF_] = '\0'; ptbuf[0] = buf; ReportEvent(h, EVENTLOG_INFORMATION_TYPE, 0, 0, NULL, 1, 0, (const char **)ptbuf, NULL); DeregisterEventSource(h); va_end(marker); } } } static HANDLE hInitMutex = NULL; static BOOL bInit = FALSE; /* KFW_initialize cannot be called from DllEntryPoint */ void KFW_initialize(void) { static int inited = 0; if ( !inited ) { char mutexName[MAX_PATH]; HANDLE hMutex = NULL; sprintf(mutexName, "AFS KFW Init pid=%d", getpid()); hMutex = CreateMutex( NULL, TRUE, mutexName ); if ( GetLastError() == ERROR_ALREADY_EXISTS ) { if ( WaitForSingleObject( hMutex, INFINITE ) != WAIT_OBJECT_0 ) { return; } } if ( !inited ) { inited = 1; LoadFuncs(KRB5_DLL, k5_fi, &hKrb5, 0, 1, 0, 0); LoadFuncs(COMERR_DLL, ce_fi, &hComErr, 0, 0, 1, 0); LoadFuncs(SERVICE_DLL, service_fi, &hService, 0, 1, 0, 0); LoadFuncs(SECUR32_DLL, lsa_fi, &hSecur32, 0, 1, 1, 1); LoadFuncs(PROFILE_DLL, profile_fi, &hProfile, 0, 1, 0, 0); LoadFuncs(LEASH_DLL, leash_fi, &hLeash, 0, 1, 0, 0); LoadFuncs(CCAPI_DLL, ccapi_fi, &hCCAPI, 0, 1, 0, 0); LoadFuncs(LEASH_DLL, leash_opt_fi, &hLeashOpt, 0, 1, 0, 0); } ReleaseMutex(hMutex); CloseHandle(hMutex); } } void KFW_cleanup(void) { if (hLeashOpt) FreeLibrary(hLeashOpt); if (hCCAPI) FreeLibrary(hCCAPI); if (hLeash) FreeLibrary(hLeash); if (hKrb524) FreeLibrary(hKrb524); if (hSecur32) FreeLibrary(hSecur32); if (hService) FreeLibrary(hService); if (hComErr) FreeLibrary(hComErr); if (hProfile) FreeLibrary(hProfile); if (hKrb5) FreeLibrary(hKrb5); } int KFW_is_available(void) { KFW_initialize(); if ( hKrb5 && hComErr && hService && #ifdef USE_MS2MIT hSecur32 && #endif /* USE_MS2MIT */ hProfile && hLeash && hCCAPI ) return TRUE; return FALSE; } /* Given a principal return an existing ccache or create one and return */ int KFW_get_ccache(krb5_context alt_ctx, krb5_principal principal, krb5_ccache * cc) { krb5_context ctx; char * pname = 0; char * ccname = 0; krb5_error_code code; if (!pkrb5_init_context) return 0; if ( alt_ctx ) { ctx = alt_ctx; } else { code = pkrb5_init_context(&ctx); if (code) goto cleanup; } if ( principal ) { code = pkrb5_unparse_name(ctx, principal, &pname); if (code) goto cleanup; ccname = (char *)malloc(strlen(pname) + 5); sprintf(ccname,"API:%s",pname); DebugEvent0(ccname); code = pkrb5_cc_resolve(ctx, ccname, cc); } else { code = pkrb5_cc_default(ctx, cc); if (code) goto cleanup; } cleanup: if (ccname) free(ccname); if (pname) pkrb5_free_unparsed_name(ctx,pname); if (ctx && (ctx != alt_ctx)) pkrb5_free_context(ctx); return(code); } int KFW_kinit( krb5_context alt_ctx, krb5_ccache alt_cc, HWND hParent, char *principal_name, char *password, krb5_deltat lifetime, DWORD forwardable, DWORD proxiable, krb5_deltat renew_life, DWORD addressless, DWORD publicIP ) { krb5_error_code code = 0; krb5_context ctx = 0; krb5_ccache cc = 0; krb5_principal me = 0; char* name = 0; krb5_creds my_creds; krb5_get_init_creds_opt options; krb5_address ** addrs = NULL; int i = 0, addr_count = 0; if (!pkrb5_init_context) return 0; pkrb5_get_init_creds_opt_init(&options); memset(&my_creds, 0, sizeof(my_creds)); if (alt_ctx) { ctx = alt_ctx; } else { code = pkrb5_init_context(&ctx); if (code) goto cleanup; } if ( alt_cc ) { cc = alt_cc; } else { code = pkrb5_cc_default(ctx, &cc); if (code) goto cleanup; } code = pkrb5_parse_name(ctx, principal_name, &me); if (code) goto cleanup; code = pkrb5_unparse_name(ctx, me, &name); if (code) goto cleanup; if (lifetime == 0) lifetime = pLeash_get_default_lifetime(); lifetime *= 60; if (renew_life > 0) renew_life *= 60; if (lifetime) pkrb5_get_init_creds_opt_set_tkt_life(&options, lifetime); pkrb5_get_init_creds_opt_set_forwardable(&options, forwardable ? 1 : 0); pkrb5_get_init_creds_opt_set_proxiable(&options, proxiable ? 1 : 0); pkrb5_get_init_creds_opt_set_renew_life(&options, renew_life); if (addressless) pkrb5_get_init_creds_opt_set_address_list(&options,NULL); else { if (publicIP) { // we are going to add the public IP address specified by the user // to the list provided by the operating system krb5_address ** local_addrs=NULL; DWORD netIPAddr; pkrb5_os_localaddr(ctx, &local_addrs); while ( local_addrs[i++] ); addr_count = i + 1; addrs = (krb5_address **) malloc((addr_count+1) * sizeof(krb5_address *)); if ( !addrs ) { pkrb5_free_addresses(ctx, local_addrs); goto cleanup; } memset(addrs, 0, sizeof(krb5_address *) * (addr_count+1)); i = 0; while ( local_addrs[i] ) { addrs[i] = (krb5_address *)malloc(sizeof(krb5_address)); if (addrs[i] == NULL) { pkrb5_free_addresses(ctx, local_addrs); goto cleanup; } addrs[i]->magic = local_addrs[i]->magic; addrs[i]->addrtype = local_addrs[i]->addrtype; addrs[i]->length = local_addrs[i]->length; addrs[i]->contents = (unsigned char *)malloc(addrs[i]->length); if (!addrs[i]->contents) { pkrb5_free_addresses(ctx, local_addrs); goto cleanup; } memcpy(addrs[i]->contents,local_addrs[i]->contents, local_addrs[i]->length); /* safe */ i++; } pkrb5_free_addresses(ctx, local_addrs); addrs[i] = (krb5_address *)malloc(sizeof(krb5_address)); if (addrs[i] == NULL) goto cleanup; addrs[i]->magic = KV5M_ADDRESS; addrs[i]->addrtype = AF_INET; addrs[i]->length = 4; addrs[i]->contents = (unsigned char *)malloc(addrs[i]->length); if (!addrs[i]->contents) goto cleanup; netIPAddr = htonl(publicIP); memcpy(addrs[i]->contents,&netIPAddr,4); pkrb5_get_init_creds_opt_set_address_list(&options,addrs); } } code = pkrb5_get_init_creds_password(ctx, &my_creds, me, password, // password NULL, // no prompter hParent, // prompter data 0, // start time 0, // service name &options); if (code) goto cleanup; code = pkrb5_cc_initialize(ctx, cc, me); if (code) goto cleanup; code = pkrb5_cc_store_cred(ctx, cc, &my_creds); if (code) goto cleanup; cleanup: if ( addrs ) { for ( i=0;icontents ) free(addrs[i]->contents); free(addrs[i]); } } } if (my_creds.client == me) my_creds.client = 0; pkrb5_free_cred_contents(ctx, &my_creds); if (name) pkrb5_free_unparsed_name(ctx, name); if (me) pkrb5_free_principal(ctx, me); if (cc && (cc != alt_cc)) pkrb5_cc_close(ctx, cc); if (ctx && (ctx != alt_ctx)) pkrb5_free_context(ctx); return(code); } int KFW_get_cred( char * username, char * password, int lifetime, char ** reasonP ) { krb5_context ctx = 0; krb5_ccache cc = 0; char * realm = 0; krb5_principal principal = 0; char * pname = 0; krb5_error_code code; if (!pkrb5_init_context || !username || !password || !password[0]) return 0; DebugEvent0(username); code = pkrb5_init_context(&ctx); if ( code ) goto cleanup; code = pkrb5_get_default_realm(ctx, &realm); if (realm) { pname = malloc(strlen(username) + strlen(realm) + 2); if (!pname) goto cleanup; strcpy(pname, username); strcat(pname, "@"); strcat(pname, realm); } else { goto cleanup; } DebugEvent0(realm); DebugEvent0(pname); code = pkrb5_parse_name(ctx, pname, &principal); if ( code ) goto cleanup; DebugEvent0("parsed name"); code = KFW_get_ccache(ctx, principal, &cc); if ( code ) goto cleanup; DebugEvent0("got ccache"); if ( lifetime == 0 ) lifetime = pLeash_get_default_lifetime(); DebugEvent0("got lifetime"); code = KFW_kinit( ctx, cc, HWND_DESKTOP, pname, password, lifetime, pLeash_get_default_forwardable(), pLeash_get_default_proxiable(), pLeash_get_default_renewable() ? pLeash_get_default_renew_till() : 0, pLeash_get_default_noaddresses(), pLeash_get_default_publicip()); DebugEvent0("kinit returned"); if ( code ) goto cleanup; cleanup: if ( pname ) free(pname); if ( realm ) pkrb5_free_default_realm(ctx, realm); if ( cc ) pkrb5_cc_close(ctx, cc); if ( code && reasonP ) { *reasonP = (char *)perror_message(code); } return(code); } int KFW_set_ccache_dacl(char *filename, HANDLE hUserToken) { // SID_IDENTIFIER_AUTHORITY authority = SECURITY_NT_SID_AUTHORITY; PSID pSystemSID = NULL; DWORD SystemSIDlength = 0, UserSIDlength = 0; PACL ccacheACL = NULL; DWORD ccacheACLlength = 0; PTOKEN_USER pTokenUser = NULL; DWORD retLen; DWORD gle; int ret = 0; if (!filename) { DebugEvent0("KFW_set_ccache_dacl - invalid parms"); return 1; } DebugEvent0("KFW_set_ccache_dacl"); /* Get System SID */ if (!ConvertStringSidToSid("S-1-5-18", &pSystemSID)) { DebugEvent("KFW_set_ccache_dacl - ConvertStringSidToSid GLE = 0x%x", GetLastError()); ret = 1; goto cleanup; } /* Create ACL */ SystemSIDlength = GetLengthSid(pSystemSID); ccacheACLlength = sizeof(ACL) + sizeof(ACCESS_ALLOWED_ACE) + SystemSIDlength - sizeof(DWORD); if (hUserToken) { if (!GetTokenInformation(hUserToken, TokenUser, NULL, 0, &retLen)) { if ( GetLastError() == ERROR_INSUFFICIENT_BUFFER ) { pTokenUser = (PTOKEN_USER) LocalAlloc(LPTR, retLen); if (!GetTokenInformation(hUserToken, TokenUser, pTokenUser, retLen, &retLen)) { DebugEvent("GetTokenInformation failed: GLE = %lX", GetLastError()); } } } if (pTokenUser) { UserSIDlength = GetLengthSid(pTokenUser->User.Sid); ccacheACLlength += sizeof(ACCESS_ALLOWED_ACE) + UserSIDlength - sizeof(DWORD); } } ccacheACL = (PACL) LocalAlloc(LPTR, ccacheACLlength); if (!ccacheACL) { DebugEvent("KFW_set_ccache_dacl - LocalAlloc GLE = 0x%x", GetLastError()); ret = 1; goto cleanup; } InitializeAcl(ccacheACL, ccacheACLlength, ACL_REVISION); AddAccessAllowedAceEx(ccacheACL, ACL_REVISION, 0, STANDARD_RIGHTS_ALL | SPECIFIC_RIGHTS_ALL, pSystemSID); if (pTokenUser) { AddAccessAllowedAceEx(ccacheACL, ACL_REVISION, 0, STANDARD_RIGHTS_ALL | SPECIFIC_RIGHTS_ALL, pTokenUser->User.Sid); if (!SetNamedSecurityInfo( filename, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION | PROTECTED_DACL_SECURITY_INFORMATION, NULL, NULL, ccacheACL, NULL)) { gle = GetLastError(); DebugEvent("SetNamedSecurityInfo DACL (1) failed: GLE = 0x%lX", gle); if (gle != ERROR_NO_TOKEN) ret = 1; } if (!SetNamedSecurityInfo( filename, SE_FILE_OBJECT, OWNER_SECURITY_INFORMATION, pTokenUser->User.Sid, NULL, NULL, NULL)) { gle = GetLastError(); DebugEvent("SetNamedSecurityInfo OWNER (2) failed: GLE = 0x%lX", gle); if (gle != ERROR_NO_TOKEN) ret = 1; } } else { if (!SetNamedSecurityInfo( filename, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION | PROTECTED_DACL_SECURITY_INFORMATION, NULL, NULL, ccacheACL, NULL)) { gle = GetLastError(); DebugEvent("SetNamedSecurityInfo DACL (3) failed: GLE = 0x%lX", gle); if (gle != ERROR_NO_TOKEN) ret = 1; } } cleanup: if (pSystemSID) LocalFree(pSystemSID); if (pTokenUser) LocalFree(pTokenUser); if (ccacheACL) LocalFree(ccacheACL); return ret; } int KFW_set_ccache_dacl_with_user_sid(char *filename, PSID pUserSID) { // SID_IDENTIFIER_AUTHORITY authority = SECURITY_NT_SID_AUTHORITY; PSID pSystemSID = NULL; DWORD SystemSIDlength = 0, UserSIDlength = 0; PACL ccacheACL = NULL; DWORD ccacheACLlength = 0; DWORD gle; int ret = 0; if (!filename) { DebugEvent0("KFW_set_ccache_dacl_with_user_sid - invalid parms"); return 1; } DebugEvent0("KFW_set_ccache_dacl_with_user_sid"); /* Get System SID */ if (!ConvertStringSidToSid("S-1-5-18", &pSystemSID)) { DebugEvent("KFW_set_ccache_dacl - ConvertStringSidToSid GLE = 0x%x", GetLastError()); ret = 1; goto cleanup; } /* Create ACL */ SystemSIDlength = GetLengthSid(pSystemSID); ccacheACLlength = sizeof(ACL) + sizeof(ACCESS_ALLOWED_ACE) + SystemSIDlength - sizeof(DWORD); if (pUserSID) { UserSIDlength = GetLengthSid(pUserSID); ccacheACLlength += sizeof(ACCESS_ALLOWED_ACE) + UserSIDlength - sizeof(DWORD); } ccacheACL = (PACL) LocalAlloc(LPTR, ccacheACLlength); if (!ccacheACL) { DebugEvent("KFW_set_ccache_dacl - LocalAlloc GLE = 0x%x", GetLastError()); ret = 1; goto cleanup; } InitializeAcl(ccacheACL, ccacheACLlength, ACL_REVISION); AddAccessAllowedAceEx(ccacheACL, ACL_REVISION, 0, STANDARD_RIGHTS_ALL | SPECIFIC_RIGHTS_ALL, pSystemSID); if (pUserSID) { AddAccessAllowedAceEx(ccacheACL, ACL_REVISION, 0, STANDARD_RIGHTS_ALL | SPECIFIC_RIGHTS_ALL, pUserSID); if (!SetNamedSecurityInfo( filename, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION | PROTECTED_DACL_SECURITY_INFORMATION, NULL, NULL, ccacheACL, NULL)) { gle = GetLastError(); DebugEvent("SetNamedSecurityInfo DACL (4) failed: GLE = 0x%lX", gle); if (gle != ERROR_NO_TOKEN) ret = 1; } if (!SetNamedSecurityInfo( filename, SE_FILE_OBJECT, OWNER_SECURITY_INFORMATION, pUserSID, NULL, NULL, NULL)) { gle = GetLastError(); DebugEvent("SetNamedSecurityInfo OWNER (5) failed: GLE = 0x%lX", gle); if (gle != ERROR_NO_TOKEN) ret = 1; } } else { if (!SetNamedSecurityInfo( filename, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION | PROTECTED_DACL_SECURITY_INFORMATION, NULL, NULL, ccacheACL, NULL)) { gle = GetLastError(); DebugEvent("SetNamedSecurityInfo DACL (6) failed: GLE = 0x%lX", gle); if (gle != ERROR_NO_TOKEN) ret = 1; } } cleanup: if (pSystemSID) LocalFree(pSystemSID); if (ccacheACL) LocalFree(ccacheACL); return ret; } int KFW_obtain_user_temp_directory(HANDLE hUserToken, char *newfilename, int size) { int retval = 0; DWORD dwSize = size-1; /* leave room for nul */ DWORD dwLen = 0; if (!hUserToken || !newfilename || size <= 0) return 1; *newfilename = '\0'; dwLen = ExpandEnvironmentStringsForUser(hUserToken, "%TEMP%", newfilename, dwSize); if ( !dwLen || dwLen > dwSize ) dwLen = ExpandEnvironmentStringsForUser(hUserToken, "%TMP%", newfilename, dwSize); if ( !dwLen || dwLen > dwSize ) return 1; newfilename[dwSize] = '\0'; return 0; } void KFW_copy_cache_to_system_file(const char * user, const char * filename) { char cachename[MAX_PATH + 8] = "FILE:"; krb5_context ctx = 0; krb5_error_code code; krb5_principal princ = 0; krb5_ccache cc = 0; krb5_ccache ncc = 0; PSECURITY_ATTRIBUTES pSA = NULL; if (!pkrb5_init_context || !user || !filename) return; strncat(cachename, filename, sizeof(cachename)); cachename[sizeof(cachename)-1] = '\0'; DebugEvent("KFW_Logon_Event - ccache %s", cachename); DeleteFile(filename); code = pkrb5_init_context(&ctx); if (code) goto cleanup; code = pkrb5_parse_name(ctx, user, &princ); if (code) goto cleanup; code = KFW_get_ccache(ctx, princ, &cc); if (code) goto cleanup; code = pkrb5_cc_resolve(ctx, cachename, &ncc); if (code) goto cleanup; code = pkrb5_cc_initialize(ctx, ncc, princ); if (code) goto cleanup; code = KFW_set_ccache_dacl(filename, NULL); if (code) goto cleanup; code = pkrb5_cc_copy_creds(ctx,cc,ncc); cleanup: if ( cc ) { pkrb5_cc_close(ctx, cc); cc = 0; } if ( ncc ) { pkrb5_cc_close(ctx, ncc); ncc = 0; } if ( princ ) { pkrb5_free_principal(ctx, princ); princ = 0; } if (ctx) pkrb5_free_context(ctx); } int KFW_copy_file_cache_to_default_cache(char * filename) { char cachename[MAX_PATH + 8] = "FILE:"; krb5_context ctx = 0; krb5_error_code code; krb5_principal princ = 0; krb5_ccache cc = 0; krb5_ccache ncc = 0; int retval = 1; if (!pkrb5_init_context || !filename) return 1; if ( strlen(filename) + sizeof("FILE:") > sizeof(cachename) ) return 1; code = pkrb5_init_context(&ctx); if (code) return 1; strcat(cachename, filename); code = pkrb5_cc_resolve(ctx, cachename, &cc); if (code) { DebugEvent0("kfwcpcc krb5_cc_resolve failed"); goto cleanup; } code = pkrb5_cc_get_principal(ctx, cc, &princ); if (code) { DebugEvent0("kfwcpcc krb5_cc_get_principal failed"); goto cleanup; } code = pkrb5_cc_default(ctx, &ncc); if (code) { DebugEvent0("kfwcpcc krb5_cc_default failed"); goto cleanup; } if (!code) { code = pkrb5_cc_initialize(ctx, ncc, princ); if (!code) code = pkrb5_cc_copy_creds(ctx,cc,ncc); if (code) { DebugEvent0("kfwcpcc krb5_cc_copy_creds failed"); goto cleanup; } } if ( ncc ) { pkrb5_cc_close(ctx, ncc); ncc = 0; } retval=0; /* success */ cleanup: if ( cc ) { pkrb5_cc_close(ctx, cc); cc = 0; } DeleteFile(filename); if ( princ ) { pkrb5_free_principal(ctx, princ); princ = 0; } if (ctx) pkrb5_free_context(ctx); return 0; } int KFW_copy_file_cache_to_api_cache(char * filename) { char cachename[MAX_PATH + 8] = "FILE:"; krb5_context ctx = 0; krb5_error_code code; krb5_principal princ = 0; krb5_ccache cc = 0; krb5_ccache ncc = 0; char *name = NULL; int retval = 1; if (!pkrb5_init_context || !filename) return 1; if ( strlen(filename) + sizeof("FILE:") > sizeof(cachename) ) return 1; code = pkrb5_init_context(&ctx); if (code) return 1; strcat(cachename, filename); code = pkrb5_cc_resolve(ctx, cachename, &cc); if (code) { DebugEvent0("kfwcpcc krb5_cc_resolve failed"); goto cleanup; } code = pkrb5_cc_get_principal(ctx, cc, &princ); if (code) { DebugEvent0("kfwcpcc krb5_cc_get_principal failed"); goto cleanup; } code = pkrb5_unparse_name(ctx, princ, &name); if (code) { DebugEvent0("kfwcpcc krb5_unparse_name failed"); goto cleanup; } sprintf(cachename, "API:%s", name); code = pkrb5_cc_resolve(ctx, cachename, &ncc); if (code) { DebugEvent0("kfwcpcc krb5_cc_default failed"); goto cleanup; } if (!code) { code = pkrb5_cc_initialize(ctx, ncc, princ); if (!code) code = pkrb5_cc_copy_creds(ctx,cc,ncc); if (code) { DebugEvent0("kfwcpcc krb5_cc_copy_creds failed"); goto cleanup; } } if ( ncc ) { pkrb5_cc_close(ctx, ncc); ncc = 0; } retval=0; /* success */ cleanup: if (name) pkrb5_free_unparsed_name(ctx, name); if ( cc ) { pkrb5_cc_close(ctx, cc); cc = 0; } DeleteFile(filename); if ( princ ) { pkrb5_free_principal(ctx, princ); princ = 0; } if (ctx) pkrb5_free_context(ctx); return 0; } int KFW_destroy_tickets_for_principal(char * user) { krb5_context ctx = 0; krb5_error_code code; krb5_principal princ = 0; krb5_ccache cc = 0; if (!pkrb5_init_context) return 0; code = pkrb5_init_context(&ctx); if (code) return 1; code = pkrb5_parse_name(ctx, user, &princ); if (code) goto loop_cleanup; code = KFW_get_ccache(ctx, princ, &cc); if (code) goto loop_cleanup; code = pkrb5_cc_destroy(ctx, cc); if (!code) cc = 0; loop_cleanup: if ( cc ) { pkrb5_cc_close(ctx, cc); cc = 0; } if ( princ ) { pkrb5_free_principal(ctx, princ); princ = 0; } pkrb5_free_context(ctx); return 0; } /* There are scenarios in which an interactive logon will not * result in the LogonScript being executed. This will result * in orphaned cache files being left in the Temp directory. * This function will search for cache files in the Temp * directory and delete any that are older than five minutes. */ void KFW_cleanup_orphaned_caches(void) { char * temppath = NULL; char * curdir = NULL; DWORD count, count2; WIN32_FIND_DATA FindFileData; HANDLE hFind = INVALID_HANDLE_VALUE; FILETIME now; ULARGE_INTEGER uli_now; FILETIME expired; count = GetTempPath(0, NULL); if (count <= 0) return; temppath = (char *) malloc(count); if (!temppath) goto cleanup; count2 = GetTempPath(count, temppath); if (count2 <= 0 || count2 > count) goto cleanup; count = GetCurrentDirectory(0, NULL); curdir = (char *)malloc(count); if (!curdir) goto cleanup; count2 = GetCurrentDirectory(count, curdir); if (count2 <= 0 || count2 > count) goto cleanup; if (!SetCurrentDirectory(temppath)) goto cleanup; GetSystemTimeAsFileTime(&now); uli_now.u.LowPart = now.dwLowDateTime; uli_now.u.HighPart = now.dwHighDateTime; uli_now.QuadPart -= 3000000000; /* 5 minutes == 3 billion 100 nano seconds */ expired.dwLowDateTime = uli_now.u.LowPart; expired.dwHighDateTime = uli_now.u.HighPart; hFind = FindFirstFile("kfwlogon-*", &FindFileData); if (hFind != INVALID_HANDLE_VALUE) { do { if (CompareFileTime(&FindFileData.ftCreationTime, &expired) < 0) { DebugEvent("Deleting orphaned cache file: \"%s\"", FindFileData.cFileName); DeleteFile(FindFileData.cFileName); } } while ( FindNextFile(hFind, &FindFileData) ); } SetCurrentDirectory(curdir); cleanup: if (temppath) free(temppath); if (hFind != INVALID_HANDLE_VALUE) FindClose(hFind); if (curdir) free(curdir); } krb5-1.16/src/windows/kfwlogon/kfwlogon.def0000644000704600001450000000022713211554426020614 0ustar ghudsonlibuuidLIBRARY KFWLOGON EXPORTS DllEntryPoint NPGetCaps NPLogonNotify NPPasswordChangeNotify KFW_Logon_Event LogonEventHandlerA krb5-1.16/src/windows/kfwlogon/kfwlogon.h0000644000704600001450000001350313211554426020306 0ustar ghudsonlibuuid/* Copyright 2005,2006 by the Massachusetts Institute of Technology Copyright 2007 by Secure Endpoints Inc. All rights reserved. Permission to use, copy, modify, and distribute this software and its documentation for any purpose and without fee is hereby granted, provided that the above copyright notice appear in all copies and that both that copyright notice and this permission notice appear in supporting documentation, and that the name of the Massachusetts Institute of Technology (M.I.T.) not be used in advertising or publicity pertaining to distribution of the software without specific, written prior permission. M.I.T. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL M.I.T. 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. */ /* We only support VC 1200 and above anyway */ #pragma once /* _WIN32_WINNT must be 0x0501 or greater to pull in definition of * all required LSA data types when the Vista SDK NtSecAPI.h is used. */ #ifndef _WIN32_WINNT #define _WIN32_WINNT 0x0501 #else #if _WIN32_WINNT < 0x0501 #undef _WIN32_WINNT #define _WIN32_WINNT 0x0501 #endif #endif #include #include #define SECURITY_WIN32 #include #include #include #include typedef int errcode_t; #include #include #include #include #include #include // service definitions #define SERVICE_DLL "advapi32.dll" typedef SC_HANDLE (WINAPI *FP_OpenSCManagerA)(char *, char *, DWORD); typedef SC_HANDLE (WINAPI *FP_OpenServiceA)(SC_HANDLE, char *, DWORD); typedef BOOL (WINAPI *FP_QueryServiceStatus)(SC_HANDLE, LPSERVICE_STATUS); typedef BOOL (WINAPI *FP_CloseServiceHandle)(SC_HANDLE); /* In order to avoid including the private CCAPI headers */ typedef int cc_int32; #define CC_API_VER_1 1 #define CC_API_VER_2 2 #define CCACHE_API cc_int32 /* ** The Official Error Codes */ #define CC_NOERROR 0 #define CC_BADNAME 1 #define CC_NOTFOUND 2 #define CC_END 3 #define CC_IO 4 #define CC_WRITE 5 #define CC_NOMEM 6 #define CC_FORMAT 7 #define CC_LOCKED 8 #define CC_BAD_API_VERSION 9 #define CC_NO_EXIST 10 #define CC_NOT_SUPP 11 #define CC_BAD_PARM 12 #define CC_ERR_CACHE_ATTACH 13 #define CC_ERR_CACHE_RELEASE 14 #define CC_ERR_CACHE_FULL 15 #define CC_ERR_CRED_VERSION 16 enum { CC_CRED_VUNKNOWN = 0, // For validation CC_CRED_V4 = 1, CC_CRED_V5 = 2, CC_CRED_VMAX = 3 // For validation }; typedef struct opaque_dll_control_block_type* apiCB; typedef struct _infoNC { char* name; char* principal; cc_int32 vers; } infoNC; TYPEDEF_FUNC( CCACHE_API, CALLCONV_C, cc_initialize, ( apiCB** cc_ctx, // < DLL's primary control structure. // returned here, passed everywhere else cc_int32 api_version, // > ver supported by caller (use CC_API_VER_1) cc_int32* api_supported, // < if ~NULL, max ver supported by DLL const char** vendor // < if ~NULL, vendor name in read only C string ) ); TYPEDEF_FUNC( CCACHE_API, CALLCONV_C, cc_shutdown, ( apiCB** cc_ctx // <> DLL's primary control structure. NULL after ) ); TYPEDEF_FUNC( CCACHE_API, CALLCONV_C, cc_get_NC_info, ( apiCB* cc_ctx, // > DLL's primary control structure struct _infoNC*** ppNCi // < (NULL before call) null terminated, // list of a structs (free via cc_free_infoNC()) ) ); TYPEDEF_FUNC( CCACHE_API, CALLCONV_C, cc_free_NC_info, ( apiCB* cc_ctx, struct _infoNC*** ppNCi // < free list of structs returned by // cc_get_cache_names(). set to NULL on return ) ); /* End private ccapiv2 headers */ #ifdef _WIN64 #define CCAPI_DLL "krbcc64.dll" #else #define CCAPI_DLL "krbcc32.dll" #endif /* */ #define MAX_USERNAME_LENGTH 256 #define MAX_PASSWORD_LENGTH 256 #define MAX_DOMAIN_LENGTH 256 #define KFW_LOGON_EVENT_NAME TEXT("MIT Kerberos") BOOLEAN APIENTRY DllEntryPoint(HANDLE dll, DWORD reason, PVOID reserved); DWORD APIENTRY NPGetCaps(DWORD index); DWORD APIENTRY NPLogonNotify( PLUID lpLogonId, LPCWSTR lpAuthentInfoType, LPVOID lpAuthentInfo, LPCWSTR lpPreviousAuthentInfoType, LPVOID lpPreviousAuthentInfo, LPWSTR lpStationName, LPVOID StationHandle, LPWSTR *lpLogonScript); DWORD APIENTRY NPPasswordChangeNotify( LPCWSTR lpAuthentInfoType, LPVOID lpAuthentInfo, LPCWSTR lpPreviousAuthentInfoType, LPVOID lpPreviousAuthentInfo, LPWSTR lpStationName, LPVOID StationHandle, DWORD dwChangeInfo); #ifdef __cplusplus extern "C" { #endif void DebugEvent0(char *a); void DebugEvent(char *b,...); DWORD MapAuthError(DWORD code); static BOOL WINAPI UnicodeStringToANSI(UNICODE_STRING uInputString, LPSTR lpszOutputString, int nOutStringLen); int KFW_is_available(void); int KFW_get_cred( char * username, char * password, int lifetime, char ** reasonP ); void KFW_copy_cache_to_system_file(const char * user, const char * filename); int KFW_destroy_tickets_for_principal(char * user); int KFW_set_ccache_dacl(char *filename, HANDLE hUserToken); int KFW_set_ccache_dacl_with_user_sid(char *filename, PSID pUserSID); int KFW_obtain_user_temp_directory(HANDLE hUserToken, char *newfilename, int size); void KFW_cleanup_orphaned_caches(void); void CALLBACK LogonEventHandlerA(HWND hwnd, HINSTANCE hinst, LPSTR lpszCmdLine, int nCmdShow); #ifdef __cplusplus } #endif krb5-1.16/src/windows/kfwlogon/kfwlogon.c0000644000704600001450000004250013211554426020300 0ustar ghudsonlibuuid/* Copyright 2005,2006 by the Massachusetts Institute of Technology Copyright 2007 by Secure Endpoints Inc. All rights reserved. Permission to use, copy, modify, and distribute this software and its documentation for any purpose and without fee is hereby granted, provided that the above copyright notice appear in all copies and that both that copyright notice and this permission notice appear in supporting documentation, and that the name of the Massachusetts Institute of Technology (M.I.T.) not be used in advertising or publicity pertaining to distribution of the software without specific, written prior permission. M.I.T. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL M.I.T. 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 "kfwlogon.h" #include #include #include #include #include #include #include #include static HANDLE hDLL; static HANDLE hInitMutex = NULL; static BOOL bInit = FALSE; BOOLEAN APIENTRY DllEntryPoint(HANDLE dll, DWORD reason, PVOID reserved) { hDLL = dll; switch (reason) { case DLL_PROCESS_ATTACH: /* Initialization Mutex */ hInitMutex = CreateMutex(NULL, FALSE, NULL); break; case DLL_PROCESS_DETACH: CloseHandle(hInitMutex); break; case DLL_THREAD_ATTACH: case DLL_THREAD_DETACH: default: /* Everything else succeeds but does nothing. */ break; } return TRUE; } DWORD APIENTRY NPGetCaps(DWORD index) { switch (index) { case WNNC_NET_TYPE: /* We aren't a file system; We don't have our own type; use somebody else's. */ return WNNC_NET_SUN_PC_NFS; case WNNC_START: /* Say we are already started, even though we might wait after we receive NPLogonNotify */ return 1; default: return 0; } } static BOOL WINAPI UnicodeStringToANSI(UNICODE_STRING uInputString, LPSTR lpszOutputString, int nOutStringLen) { CPINFO CodePageInfo; GetCPInfo(CP_ACP, &CodePageInfo); if (CodePageInfo.MaxCharSize > 1) // Only supporting non-Unicode strings return FALSE; if (uInputString.Buffer && ((LPBYTE) uInputString.Buffer)[1] == '\0') { // Looks like unicode, better translate it // UNICODE_STRING specifies the length of the buffer string in Bytes not WCHARS WideCharToMultiByte(CP_ACP, 0, (LPCWSTR) uInputString.Buffer, uInputString.Length/2, lpszOutputString, nOutStringLen-1, NULL, NULL); lpszOutputString[min(uInputString.Length/2,nOutStringLen-1)] = '\0'; return TRUE; } lpszOutputString[0] = '\0'; return FALSE; } // UnicodeStringToANSI static BOOL is_windows_vista(void) { static BOOL fChecked = FALSE; static BOOL fIsWinVista = FALSE; if (!fChecked) { OSVERSIONINFO Version; memset (&Version, 0x00, sizeof(Version)); Version.dwOSVersionInfoSize = sizeof(Version); if (GetVersionEx (&Version)) { if (Version.dwPlatformId == VER_PLATFORM_WIN32_NT && Version.dwMajorVersion >= 6) fIsWinVista = TRUE; } fChecked = TRUE; } return fIsWinVista; } /* Construct a Logon Script that will cause the LogonEventHandler to be executed * under in the logon session */ #define RUNDLL32_CMDLINE "rundll32.exe kfwlogon.dll,LogonEventHandler " VOID ConfigureLogonScript(LPWSTR *lpLogonScript, char * filename) { DWORD dwLogonScriptLen; LPWSTR lpScript; LPSTR lpTemp; if (!lpLogonScript) return; *lpLogonScript = NULL; if (!filename) return; dwLogonScriptLen = strlen(RUNDLL32_CMDLINE) + strlen(filename) + 2; lpTemp = (LPSTR) malloc(dwLogonScriptLen); if (!lpTemp) return; _snprintf(lpTemp, dwLogonScriptLen, "%s%s", RUNDLL32_CMDLINE, filename); SetLastError(0); dwLogonScriptLen = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, lpTemp, -1, NULL, 0); DebugEvent("ConfigureLogonScript %s requires %d bytes gle=0x%x", lpTemp, dwLogonScriptLen, GetLastError()); lpScript = LocalAlloc(LMEM_ZEROINIT, dwLogonScriptLen * 2); if (lpScript) { if (MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, lpTemp, -1, lpScript, 2 * dwLogonScriptLen)) *lpLogonScript = lpScript; else { DebugEvent("ConfigureLogonScript - MultiByteToWideChar failed gle = 0x%x", GetLastError()); LocalFree(lpScript); } } else { DebugEvent("LocalAlloc failed gle=0x%x", GetLastError()); } free(lpTemp); } DWORD APIENTRY NPLogonNotify( PLUID lpLogonId, LPCWSTR lpAuthentInfoType, LPVOID lpAuthentInfo, LPCWSTR lpPreviousAuthentInfoType, LPVOID lpPreviousAuthentInfo, LPWSTR lpStationName, LPVOID StationHandle, LPWSTR *lpLogonScript) { char uname[MAX_USERNAME_LENGTH+1]=""; char password[MAX_PASSWORD_LENGTH+1]=""; char logonDomain[MAX_DOMAIN_LENGTH+1]=""; MSV1_0_INTERACTIVE_LOGON *IL; DWORD code = 0; char *reason; char *ctemp; BOOLEAN interactive = TRUE; HWND hwndOwner = (HWND)StationHandle; BOOLEAN lowercased_name = TRUE; /* Can we load KFW binaries? */ if ( !KFW_is_available() ) return 0; DebugEvent0("NPLogonNotify start"); /* Remote Desktop / Terminal Server connections to existing sessions * are interactive logons. Unfortunately, because the session already * exists the logon script does not get executed and this prevents * us from being able to execute the rundll32 entrypoint * LogonEventHandlerA which would process the credential cache this * routine will produce. Therefore, we must cleanup orphaned cache * files from this routine. We will take care of it before doing * anything else. */ KFW_cleanup_orphaned_caches(); /* Are we interactive? */ if (lpStationName) interactive = (wcsicmp(lpStationName, L"WinSta0") == 0); if ( !interactive ) { char station[64]="station"; DWORD rv; SetLastError(0); rv = WideCharToMultiByte(CP_UTF8, 0, lpStationName, -1, station, sizeof(station), NULL, NULL); DebugEvent("Skipping NPLogonNotify- LoginId(%d,%d) - Interactive(%d:%s) - gle %d", lpLogonId->HighPart, lpLogonId->LowPart, interactive, rv != 0 ? station : "failure", GetLastError()); return 0; } else DebugEvent("NPLogonNotify - LoginId(%d,%d)", lpLogonId->HighPart, lpLogonId->LowPart); /* Initialize Logon Script to none */ *lpLogonScript=NULL; /* MSV1_0_INTERACTIVE_LOGON and KERB_INTERACTIVE_LOGON are equivalent for * our purposes */ if ( wcsicmp(lpAuthentInfoType,L"MSV1_0:Interactive") && wcsicmp(lpAuthentInfoType,L"Kerberos:Interactive") ) { char msg[64]; WideCharToMultiByte(CP_ACP, 0, lpAuthentInfoType, -1, msg, sizeof(msg), NULL, NULL); msg[sizeof(msg)-1]='\0'; DebugEvent("NPLogonNotify - Unsupported Authentication Info Type: %s", msg); return 0; } IL = (MSV1_0_INTERACTIVE_LOGON *) lpAuthentInfo; /* Convert from Unicode to ANSI */ /*TODO: Use SecureZeroMemory to erase passwords */ if (!UnicodeStringToANSI(IL->UserName, uname, MAX_USERNAME_LENGTH) || !UnicodeStringToANSI(IL->Password, password, MAX_PASSWORD_LENGTH) || !UnicodeStringToANSI(IL->LogonDomainName, logonDomain, MAX_DOMAIN_LENGTH)) return 0; /* Make sure AD-DOMAINS sent from login that is sent to us is stripped */ ctemp = strchr(uname, '@'); if (ctemp) *ctemp = 0; /* is the name all lowercase? */ for ( ctemp = uname; *ctemp ; ctemp++) { if ( !islower(*ctemp) ) { lowercased_name = FALSE; break; } } code = KFW_get_cred(uname, password, 0, &reason); DebugEvent("NPLogonNotify - KFW_get_cred uname=[%s] code=[%d]",uname, code); /* remove any kerberos 5 tickets currently held by the SYSTEM account * for this user */ if (!code) { char filename[MAX_PATH+1] = ""; char acctname[MAX_USERNAME_LENGTH+MAX_DOMAIN_LENGTH+3]=""; PSID pUserSid = NULL; LPTSTR pReferencedDomainName = NULL; DWORD dwSidLen = 0, dwDomainLen = 0, count; SID_NAME_USE eUse; if (_snprintf(acctname, sizeof(acctname), "%s\\%s", logonDomain, uname) < 0) { code = -1; goto cleanup; } count = GetTempPath(sizeof(filename), filename); if (count == 0 || count > (sizeof(filename)-1)) { code = -1; goto cleanup; } if (_snprintf(filename, sizeof(filename), "%s\\kfwlogon-%x.%x", filename, lpLogonId->HighPart, lpLogonId->LowPart) < 0) { code = -1; goto cleanup; } KFW_copy_cache_to_system_file(uname, filename); /* Need to determine the SID */ /* First get the size of the required buffers */ LookupAccountName (NULL, acctname, pUserSid, &dwSidLen, pReferencedDomainName, &dwDomainLen, &eUse); if(dwSidLen){ pUserSid = (PSID) malloc (dwSidLen); memset(pUserSid,0,dwSidLen); } if(dwDomainLen){ pReferencedDomainName = (LPTSTR) malloc (dwDomainLen * sizeof(TCHAR)); memset(pReferencedDomainName,0,dwDomainLen * sizeof(TCHAR)); } //Now get the SID and the domain name if (pUserSid && LookupAccountName( NULL, acctname, pUserSid, &dwSidLen, pReferencedDomainName, &dwDomainLen, &eUse)) { DebugEvent("LookupAccountName obtained user %s sid in domain %s", acctname, pReferencedDomainName); code = KFW_set_ccache_dacl_with_user_sid(filename, pUserSid); #ifdef USE_WINLOGON_EVENT /* If we are on Vista, setup a LogonScript * that will execute the LogonEventHandler entry point via rundll32.exe */ if (is_windows_vista()) { ConfigureLogonScript(lpLogonScript, filename); if (*lpLogonScript) DebugEvent0("LogonScript assigned"); else DebugEvent0("No Logon Script"); } #else ConfigureLogonScript(lpLogonScript, filename); if (*lpLogonScript) DebugEvent0("LogonScript assigned"); else DebugEvent0("No Logon Script"); #endif } else { DebugEvent0("LookupAccountName failed"); DeleteFile(filename); code = -1; } cleanup: if (pUserSid) free(pUserSid); if (pReferencedDomainName) free(pReferencedDomainName); } KFW_destroy_tickets_for_principal(uname); if (code) { char msg[128]; HANDLE h; char *ptbuf[1]; StringCbPrintf(msg, sizeof(msg), "Kerberos ticket acquisition failed: %s", reason); h = RegisterEventSource(NULL, KFW_LOGON_EVENT_NAME); ptbuf[0] = msg; ReportEvent(h, EVENTLOG_WARNING_TYPE, 0, 1008, NULL, 1, 0, ptbuf, NULL); DeregisterEventSource(h); SetLastError(code); } if (code) DebugEvent0("NPLogonNotify failure"); else DebugEvent0("NPLogonNotify success"); return code; } DWORD APIENTRY NPPasswordChangeNotify( LPCWSTR lpAuthentInfoType, LPVOID lpAuthentInfo, LPCWSTR lpPreviousAuthentInfoType, LPVOID lpPreviousAuthentInfo, LPWSTR lpStationName, LPVOID StationHandle, DWORD dwChangeInfo) { return 0; } #include #include #ifdef COMMENT typedef struct _WLX_NOTIFICATION_INFO { ULONG Size; ULONG Flags; PWSTR UserName; PWSTR Domain; PWSTR WindowStation; HANDLE hToken; HDESK hDesktop; PFNMSGECALLBACK pStatusCallback; } WLX_NOTIFICATION_INFO, *PWLX_NOTIFICATION_INFO; #endif VOID KFW_Startup_Event( PWLX_NOTIFICATION_INFO pInfo ) { DebugEvent0("KFW_Startup_Event"); } static BOOL GetSecurityLogonSessionData(HANDLE hToken, PSECURITY_LOGON_SESSION_DATA * ppSessionData) { NTSTATUS Status = 0; #if 0 HANDLE TokenHandle; #endif TOKEN_STATISTICS Stats; DWORD ReqLen; BOOL Success; if (!ppSessionData) return FALSE; *ppSessionData = NULL; #if 0 Success = OpenProcessToken( HANDLE GetCurrentProcess(), TOKEN_QUERY, &TokenHandle ); if ( !Success ) return FALSE; #endif Success = GetTokenInformation( hToken, TokenStatistics, &Stats, sizeof(TOKEN_STATISTICS), &ReqLen ); #if 0 CloseHandle( TokenHandle ); #endif if ( !Success ) return FALSE; Status = LsaGetLogonSessionData( &Stats.AuthenticationId, ppSessionData ); if ( FAILED(Status) || !ppSessionData ) return FALSE; return TRUE; } VOID KFW_Logon_Event( PWLX_NOTIFICATION_INFO pInfo ) { #ifdef USE_WINLOGON_EVENT WCHAR szUserW[128] = L""; char szUserA[128] = ""; char szPath[MAX_PATH] = ""; char szLogonId[128] = ""; DWORD count; char filename[MAX_PATH] = ""; char newfilename[MAX_PATH] = ""; char commandline[MAX_PATH+256] = ""; STARTUPINFO startupinfo; PROCESS_INFORMATION procinfo; HANDLE hf = NULL; LUID LogonId = {0, 0}; PSECURITY_LOGON_SESSION_DATA pLogonSessionData = NULL; HKEY hKey1 = NULL, hKey2 = NULL; DebugEvent0("KFW_Logon_Event - Start"); GetSecurityLogonSessionData( pInfo->hToken, &pLogonSessionData ); if ( pLogonSessionData ) { LogonId = pLogonSessionData->LogonId; DebugEvent("KFW_Logon_Event - LogonId(%d,%d)", LogonId.HighPart, LogonId.LowPart); _snprintf(szLogonId, sizeof(szLogonId), "kfwlogon-%d.%d",LogonId.HighPart, LogonId.LowPart); LsaFreeReturnBuffer( pLogonSessionData ); } else { DebugEvent0("KFW_Logon_Event - Unable to determine LogonId"); return; } count = GetEnvironmentVariable("TEMP", filename, sizeof(filename)); if ( count > sizeof(filename) || count == 0 ) { GetWindowsDirectory(filename, sizeof(filename)); } if ( strlen(filename) + strlen(szLogonId) + 2 > sizeof(filename) ) { DebugEvent0("KFW_Logon_Event - filename too long"); return; } strcat(filename, "\\"); strcat(filename, szLogonId); hf = CreateFile(filename, FILE_ALL_ACCESS, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (hf == INVALID_HANDLE_VALUE) { DebugEvent0("KFW_Logon_Event - file cannot be opened"); return; } CloseHandle(hf); if (KFW_set_ccache_dacl(filename, pInfo->hToken)) { DebugEvent0("KFW_Logon_Event - unable to set dacl"); DeleteFile(filename); return; } if (KFW_obtain_user_temp_directory(pInfo->hToken, newfilename, sizeof(newfilename))) { DebugEvent0("KFW_Logon_Event - unable to obtain temp directory"); return; } if ( strlen(newfilename) + strlen(szLogonId) + 2 > sizeof(newfilename) ) { DebugEvent0("KFW_Logon_Event - new filename too long"); return; } strcat(newfilename, "\\"); strcat(newfilename, szLogonId); if (!MoveFileEx(filename, newfilename, MOVEFILE_COPY_ALLOWED | MOVEFILE_REPLACE_EXISTING | MOVEFILE_WRITE_THROUGH)) { DebugEvent("KFW_Logon_Event - MoveFileEx failed GLE = 0x%x", GetLastError()); return; } _snprintf(commandline, sizeof(commandline), "kfwcpcc.exe \"%s\"", newfilename); GetStartupInfo(&startupinfo); if (CreateProcessAsUser( pInfo->hToken, "kfwcpcc.exe", commandline, NULL, NULL, FALSE, CREATE_NEW_PROCESS_GROUP | DETACHED_PROCESS, NULL, NULL, &startupinfo, &procinfo)) { DebugEvent("KFW_Logon_Event - CommandLine %s", commandline); WaitForSingleObject(procinfo.hProcess, 30000); CloseHandle(procinfo.hThread); CloseHandle(procinfo.hProcess); } else { DebugEvent0("KFW_Logon_Event - CreateProcessFailed"); } DeleteFile(newfilename); DebugEvent0("KFW_Logon_Event - End"); #endif /* USE_WINLOGON_EVENT */ } /* Documentation on the use of RunDll32 entrypoints can be found * at http://support.microsoft.com/kb/164787 */ void CALLBACK LogonEventHandlerA(HWND hwnd, HINSTANCE hinst, LPSTR lpszCmdLine, int nCmdShow) { HANDLE hf = NULL; char commandline[MAX_PATH+256] = ""; STARTUPINFO startupinfo; PROCESS_INFORMATION procinfo; DebugEvent0("LogonEventHandler - Start"); /* Validate lpszCmdLine as a file */ hf = CreateFile(lpszCmdLine, GENERIC_READ | DELETE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (hf == INVALID_HANDLE_VALUE) { DebugEvent("LogonEventHandler - \"%s\" cannot be opened", lpszCmdLine); return; } CloseHandle(hf); _snprintf(commandline, sizeof(commandline), "kfwcpcc.exe \"%s\"", lpszCmdLine); GetStartupInfo(&startupinfo); SetLastError(0); if (CreateProcess( NULL, commandline, NULL, NULL, FALSE, CREATE_NEW_PROCESS_GROUP | DETACHED_PROCESS, NULL, NULL, &startupinfo, &procinfo)) { DebugEvent("KFW_Logon_Event - CommandLine %s", commandline); WaitForSingleObject(procinfo.hProcess, 30000); CloseHandle(procinfo.hThread); CloseHandle(procinfo.hProcess); } else { DebugEvent("KFW_Logon_Event - CreateProcessFailed \"%s\" GLE 0x%x", commandline, GetLastError()); DebugEvent("KFW_Logon_Event PATH %s", getenv("PATH")); } DeleteFile(lpszCmdLine); DebugEvent0("KFW_Logon_Event - End"); } krb5-1.16/src/windows/kfwlogon/kfwcpcc.c0000644000704600001450000000230313211554426020067 0ustar ghudsonlibuuid/* Copyright 2005 by the Massachusetts Institute of Technology All rights reserved. Permission to use, copy, modify, and distribute this software and its documentation for any purpose and without fee is hereby granted, provided that the above copyright notice appear in all copies and that both that copyright notice and this permission notice appear in supporting documentation, and that the name of the Massachusetts Institute of Technology (M.I.T.) not be used in advertising or publicity pertaining to distribution of the software without specific, written prior permission. M.I.T. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL M.I.T. 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 #include "kfwlogon.h" int main(int argc, char *argv[]) { if ( argc != 2 ) return 1; KFW_initialize(); return KFW_copy_file_cache_to_api_cache(argv[1]); } krb5-1.16/src/windows/kfwlogon/Makefile.in0000644000704600001450000000315513211554426020356 0ustar ghudsonlibuuid# Makefile for the KFW Network Provider # mydir=. BUILDTOP=$(REL)..$(S).. DEFINES = -DNO_KRB4 LOCALINCLUDES = -I$(BUILDTOP) -I$(BUILDTOP)\include -I$(BUILDTOP)\windows\include PROG_LIBPATH=-L$(TOPLIBD) -L$(KRB5_LIBDIR) !if defined(VISUALSTUDIOVERSION) !if $(VISUALSTUDIOVERSION:.=) >= 140 !ifdef NODEBUG WINCRTEXTRA = ucrt.lib vcruntime.lib !else WINCRTEXTRA = ucrtd.lib vcruntimed.lib !endif !endif !endif SYSLIBS = kernel32.lib user32.lib advapi32.lib wsock32.lib secur32.lib userenv.lib $(WINCRTEXTRA) VERSIONRC = $(BUILDTOP)\windows\version.rc RCFLAGS=$(CPPFLAGS) -I$(top_srcdir) -D_WIN32 -DRES_ONLY KFWLOGON=$(OUTPRE)kfwlogon.dll KFWCPCC=$(OUTPRE)kfwcpcc.exe LIBRES=$(KFWLOGON:.dll=.res) EXERES=$(KFWCPCC:.exe=.res) $(LIBRES): $(VERSIONRC) $(RC) $(RCFLAGS) -DKFWLOGON_LIB -fo $@ -r $** $(EXERES): $(VERSIONRC) $(RC) $(RCFLAGS) -DKFWCPCC_APP -fo $@ -r $** all-windows: $(OUTPRE)kfwlogon.dll $(OUTPRE)kfwcpcc.exe $(KFWLOGON): $(OUTPRE)kfwlogon.obj $(OUTPRE)kfwcommon.obj $(LIBRES) link $(DLL_LINKOPTS) -out:$@ $(OUTPRE)kfwlogon.obj $(OUTPRE)kfwcommon.obj -entry:DllEntryPoint -def:kfwlogon.def $(SYSLIBS) $(KLIB) $(CLIB) $(SCLIB) ../lib/$(OUTPRE)libwin.lib $(LIBRES) $(_VC_MANIFEST_EMBED_DLL) $(KFWCPCC): $(OUTPRE)kfwcpcc.obj $(OUTPRE)kfwcommon.obj $(EXERES) link $(EXE_LINKOPTS) -out:$@ $(OUTPRE)kfwcpcc.obj $(OUTPRE)kfwcommon.obj $(SYSLIBS) $(KLIB) $(CLIB) $(SCLIB) ../lib/$(OUTPRE)libwin.lib $(EXERES) $(_VC_MANIFEST_EMBED_EXE) install: copy $(OUTPRE)kfwlogon.dll $(DESTDIR) copy $(OUTPRE)kfwcpcc.exe $(DESTDIR) clean: $(RM) $(OUTPRE)*.exe $(OUTPRE)*.dll $(OUTPRE)*.res krb5-1.16/src/windows/cns/0000755000704600001450000000000013211554426015242 5ustar ghudsonlibuuidkrb5-1.16/src/windows/cns/clock45.ico0000644000704600001450000000207613211554426017207 0ustar ghudsonlibuuid 0& V( @??~=?7?(z~v~~??????????????????( @wwwwwwwwwwwwwwwpwwwwwwwwwwwwwwwwwwww??????????????????krb5-1.16/src/windows/cns/cns.ico0000644000704600001450000000207613211554426016526 0ustar ghudsonlibuuid 0& V( @` 6`l߀ ?n^xxpx0x 0 ????( @wpwppwwppwwp``f wpf`wf`f xxwfff`ff`xxffffffpffff`f`ff``????krb5-1.16/src/windows/cns/cns.h0000644000704600001450000001275513211554426016210 0ustar ghudsonlibuuid/* * cns.h * * Public Domain -- written by Cygnus Support. */ /* Only one time, please */ #ifndef KWIN_DEFS #define KWIN_DEFS #if !defined(KRB4) && !defined(KRB5) #define KRB5 #endif #ifndef RC_INVOKED #ifdef KRB4 #include "mit-copyright.h" #include "krb.h" #include "kadm.h" #include "org.h" #endif #ifdef KRB5 #include "winsock.h" #include "krb5.h" #include "krbini.h" #include "com_err.h" #define DEFAULT_TKT_LIFE 120 /* In 5 minute units */ #define ANAME_SZ 40 #define REALM_SZ 40 #define SNAME_SZ 40 #define INST_SZ 40 #define MAX_KPW_LEN 128 /* include space for '.' and '@' */ #define MAX_K_NAME_SZ (ANAME_SZ + INST_SZ + REALM_SZ + 2) #ifdef CYGNUS #define ORGANIZATION "Cygnus Solutions\n(800)CYGNUS-1\nhttp://www.cygnus.com\ninfo@cygnus.com" #endif #define CREDENTIALS char #endif /* * Constants */ #define BLOCK_MAX_SEC 30 /* Blocking timeout duration */ #define KWIN_UPDATE_PERIOD 30000 /* Every 30 seconds update the screen */ #define TIME_BUFFER 300 /* Pop-up time buffer in seconds */ #define WM_KWIN_SETNAME (WM_USER+100) /* Sets the name fields in the dialog */ #endif /* RC_INVOKED */ /* * Menu items */ #define FILE_MENU_ITEMS 3 #define FILE_MENU_MAX_LOGINS 5 #define IDM_KWIN 1000 #define IDM_OPTIONS 1001 #define IDM_EXIT 1002 #define IDM_FIRST_LOGIN 1003 #define IDM_HELP_INDEX 1020 #define IDM_ABOUT 1021 /* * Accelerator */ #define IDA_KWIN 2000 /* * Dialog and dialog item ids */ #define KWIN_DIALOG_CLASS "KERBEROS" /* class for kerberos dialog */ #define KWIN_DIALOG_NAME "Krb5" /* name for kerberos dialog */ #define ID_KWIN 100 /* the main kerberos dialog */ #define IDD_KWIN_FIRST 101 #define IDD_TICKET_LIST_TITLE 101 #define IDD_TICKET_LIST 102 #ifdef KRB4 #define IDD_MIN_TITLE 103 #define IDD_LOGIN_NAME_TITLE 103 #define IDD_LOGIN_INSTANCE_TITLE 104 #define IDD_LOGIN_REALM_TITLE 105 #define IDD_LOGIN_PASSWORD_TITLE 106 #define IDD_MAX_TITLE 106 #define IDD_MIN_EDIT 107 #define IDD_LOGIN_NAME 107 #define IDD_LOGIN_INSTANCE 108 #define IDD_LOGIN_REALM 109 #define IDD_LOGIN_PASSWORD 110 #define IDD_MAX_EDIT 110 #endif #ifdef KRB5 #define IDD_MIN_TITLE 103 #define IDD_LOGIN_NAME_TITLE 103 #define IDD_LOGIN_PASSWORD_TITLE 104 #define IDD_LOGIN_REALM_TITLE 105 #define IDD_MAX_TITLE 105 #define IDD_MIN_EDIT 107 #define IDD_LOGIN_NAME 107 #define IDD_LOGIN_PASSWORD 108 #define IDD_LOGIN_REALM 109 #define IDD_MAX_EDIT 109 #endif #define IDD_MIN_BUTTON 111 #define IDD_CHANGE_PASSWORD 111 #define IDD_TICKET_DELETE 112 #define IDD_LOGIN 113 #define IDD_MAX_BUTTON 113 #define IDD_PASSWORD_CR2 114 /* For better cr handling */ #define IDD_KWIN_LAST 114 #define ID_PASSWORD 200 #define IDD_PASSWORD_NAME 204 #define IDD_PASSWORD_INSTANCE 205 #define IDD_PASSWORD_REALM 206 #define IDD_OLD_PASSWORD 207 #define IDD_NEW_PASSWORD1 208 #define IDD_NEW_PASSWORD2 209 #define IDD_PASSWORD_CR 210 #define ID_OPTS 300 #define IDD_CONF 301 #define IDD_REALMS 302 #define IDD_LIFETIME 303 #define IDD_CCACHE 304 #define IDD_ACTIONS 310 #define IDD_BEEP 311 #define IDD_ALERT 312 #define IDD_TKOPT 320 #define IDD_FORWARDABLE 321 #define IDD_NOADDRESSES 322 /* * the entire range (400 through 499) is reserved for the blasted variable * dialog box thingie. */ #define ID_VARDLG 400 /* * Dialog dimensions */ #define KWIN_MIN_WIDTH 180 #define KWIN_MIN_HEIGHT 110 /* * Icons */ #define IDI_KWIN 1 /* The program icon */ #define ICON_WIDTH 30 /* Width used with icons */ #define ICON_HEIGHT 20 /* Height used with icons */ #define IDI_FIRST_CLOCK 2 #define IDI_0_MIN 2 /* < 5 minutes left */ #define IDI_5_MIN 3 #define IDI_10_MIN 4 #define IDI_15_MIN 5 #define IDI_20_MIN 6 #define IDI_25_MIN 7 #define IDI_30_MIN 8 #define IDI_35_MIN 9 #define IDI_40_MIN 10 #define IDI_45_MIN 11 #define IDI_50_MIN 12 #define IDI_55_MIN 13 #define IDI_60_MIN 14 #define IDI_EXPIRED 15 #define IDI_TICKET 16 #define IDI_LAST_CLOCK 16 #define MAX_ICONS (IDI_LAST_CLOCK - IDI_FIRST_CLOCK + 1) #ifndef RC_INVOKED extern BOOL isblocking; extern HFONT hfontdialog; extern HINSTANCE hinstance; extern BOOL alert; extern BOOL beep; extern char confname[FILENAME_MAX]; #ifdef KRB5 extern krb5_context k5_context; extern krb5_ccache k5_ccache; extern char ccname[FILENAME_MAX]; extern BOOL forwardable; extern BOOL noaddresses; #endif /* * Prototypes */ /* in cns.c */ void kwin_init_name(HWND, char *); void kwin_set_default_focus(HWND); time_t kwin_get_epoch(void); /* in options.c */ BOOL opts_initdialog(HWND, HWND, LPARAM); void opts_command(HWND, int, HWND, UINT); BOOL CALLBACK opts_dlg_proc(HWND, UINT, WPARAM, LPARAM); BOOL opts_dialog(HWND); /* in password.c */ BOOL change_password(HWND, char *, char *, char *, char *, char *); void password_command(HWND, int, HWND, UINT); BOOL password_initdialog(HWND, HWND, LPARAM); BOOL CALLBACK password_dlg_proc(HWND, UINT, WPARAM, LPARAM); BOOL password_dialog(HWND); #ifdef KRB5 krb5_error_code k5_dest_tkt(void); int k5_get_num_cred(int); int k5_kname_parse(char *, char *, char *); krb5_error_code k5_init_ccache(krb5_ccache *); int k5_name_from_ccache(krb5_ccache); krb5_error_code k5_change_password(HWND, krb5_context, char *, char *, char *, char *, char **); #endif /* KRB5 */ HICON kwin_get_icon(time_t); void trim(char *); void start_blocking_hook(int); void end_blocking_hook(void); void center_dialog(HWND); void set_dialog_font(HWND, HFONT); #endif /* RC_INVOKED */ #endif krb5-1.16/src/windows/cns/kerbnet.hpj0000644000704600001450000001013613211554426017400 0ustar ghudsonlibuuid;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ; Help Project File for KERBNET ; ; You may edit this file. ; ; It's probably best not to change the CONTENTS= value ; unless you rename the IDH_CONTENTS context string in ; the KERBNET.DOC file. ; [OPTIONS] ; The optional ROOT= entry sets the working directory for the Help Compiler ; ROOT=C:\PROJECT ; The optional BMROOT= entry sets forth the directories which the ; help compiler will search for bitmaps used in the Help system. ; ;BMROOT=C:\ROBOHELP ; The CONTENTS= tells the help Engine which topic contains the contents CONTENTS=IDH_CONTENTS ; Title is Displayed in the Title Bar of WINHELP.EXE TITLE=Kerb*Net ; The BUILD= setting allows complex Help systems which require ; different versions to use the same source. This is similar to #ifdef's ; in the 'C' language. Everything to the right of the = sign in the ; BUILD= statement is an EXPRESSION. See the Help compiler ; documentation for more information about build expressions. BUILD=WINDOWS ; The Warning Level is used by the Help Compiler (HC.EXE) ; WARNING=1 - Only the most severe warnings are reported ; WARNING=2 - Intermediate Level of warnings ; WARNING=3 - Most stringent error reporting ; The Compress option is used by the Help Compiler to make ; smaller, faster loading .HLP files. However, using compression ; increases Compile times. ; COMPRESS=YES, ON, OFF, NO, TRUE or FALSE OLDKEYPHRASE=NO OPTCDROM=0 NOTES=1 REPORT=YES COMPRESS=12 ERRORLOG=C:\windows\desktop\kerberos 5\win95 gui\cns help\KERBNET.ERR [BUILDTAGS] ; The Build Tags section specifies to the Help Compiler the names ; of all the valid build tags used in this Help project. The [BUILDTAGS] ; section is optional. WINDOWS [CONFIG] ; The config section allows you to define some macros which will be ; executed when the help system is first executed. ; ; The next line gives you browse buttons: ; BrowseButtons() ; ; To create a glossary button which displays a list of defined terms ; in a secondary window, remove the semi colon at the start of the next ; line and do the same with the Glossary window in the [WINDOWS] section ;CreateButton("Glossary_Btn","&Glossary","JI(`bubble.hlp>Gloss',`IDH_Glossary')") ; [FILES] ; The files section is where you specify to the Help Compiler which ; Rich Text Format (.RTF) (your help source) files will be used in the ; Help system. RoboHELP generates and maintains the main .RTF ; file for your Help System. If you desire to have multiple .RTF files, ; simply add the additonal names to the [FILES] section. KERBNET.RTF [ALIAS] ; The Alias section allows you to set up aliases for context strings ; in your help system. ; ; Brief example: ; ; IDH_UserID = IDH_RoboGenerated_Id ; IDH_WMP_MenuID = IDH_RoboGenerated_Id ; IDH_Any = IDH_AnyOther [MAP] ; ; The Map Section is where the C language #defines are translated ; or mapped into the Help System Context Strings. Standard C syntax ; can be employed. The .HH file is meant to be #include(d) into your ; Windows application source code. ; [BITMAPS] ; ; The [BITMAPS] section is where you list any Bitmaps which have ; been placed by reference in the Help System. See the Help compiler ; documentation for more information about placing bitmaps. ; ; The [BITMAPS] section is not really required under Windows 3.1, ; with the advent of the BMROOT item in the [OPTIONS] section. ; ;FOO1.BMP ;FOO2.BMP ;C:\FOO\FOO3.BMP ;And So On [WINDOWS] ; Windows Help can display help in one of 5 secondary windows. ; Before using a secondary window, the window must be defined ; in this section: ; ;Gloss = "Glossary",(100,100,350,350),0,(255,255,255),(255,255,255) main=,,0,, [BAGGAGE] ; ; The Baggage section allows the user to include files which ; will be placed in the internal file system for WinHelp. ; Using files from Baggage is a little faster for CDROM, since ; the CDROM drive table does not need to be read from disk. ; ; Baggage files are referred to as regular bitmaps, except ; that you prefix the filename with '!'. ; ; For Instance: ; {bmc !bitmap.bmp} instead of {bmc bitmap.bmp} ; krb5-1.16/src/windows/cns/kerbnet.doc0000644000704600001450000005400013211554426017362 0ustar ghudsonlibuuidࡱ>  ܥhc e1P:T,,./111111111 21=9W 2 2 2 2 2 282T2<7>7>7>79w7K899X9d=91d2 2 2d2d2=9$411 2 2$4$4$4d21 21 2<7Se9.1Jx1|T0J0|11d2<7$4$4# $ K + Contents The following Help Topics are available: Using Kerb*Net for WindowsUsing_Kerb*Net_for_Windows Troubleshooting Kerb*Net for WindowsTroubleshooting_Kerb*Net_for_Windows Kerberos TicketsKerberos_Tickets Kerberos PrincipalsKerberos_Terms For Help on Help, Press F1 # $ K + Using Kerb*Net for Windows To obtain Kerberos ticketsKerberos_ticket using Kerb*Net for Windows, type your Kerberos primaryKerberos_primary or Kerberos primary/instanceKerberos_Instance (separated by a slash) in the Name box, your Kerberos realmKerberos_Realm in the Realm box, and your password in the Password box, and then click the Login button. To delete your Kerberos tickets, click the Delete button. Also, attempting to obtain new tickets will automatically delete any existing tickets. To change your password, click the Change Password button. This will bring up a dialog box. Enter your primaryKerberos_primary or primary/instanceKerberos_Instance in the Name box, and your Kerberos realmKerberos_Realm in the Realm box. Type your old password in the Old box, and your new password twice, once in each New box. When all of the boxes are properly filled in, click the OK button. You can also specify the following options, by selecting File, and then Options: the location of the Kerberos configuration fileKerberos_Configuration_File the location of the credential cache (ticketKerberos_Ticket file) whether or not Kerb*Net should alert you by popping its window up and/or beeping when your tickets expire whether your tickets should be forwardableForwardable_Tickets # $ K + Troubleshooting Kerb*Net for Windows The file libkrb5.dll must be somewhere in your path. Your Kerberos Config fileKerberos_Configuration_File must be in the location specified in your Options (under the File menu). The directory that you specify for Kerb*Net to put your Credential (ticketKerberos_Ticket file) in must exist. If the Key Distribution Center (KDC) Key_Distribution_Center_KDC is unreachable (perhaps because of network problems), you will be unable to get tickets. If the admin server is unreachable, you will be unable to change your password. # $ K + Kerberos Tickets When you authenticate yourself, Kerberos gives you an initial Kerberos ticket. (A Kerberos ticket is an encrypted protocol message that provides authentication.) Kerberos uses this ticket for network utilities. The ticket transactions are done transparently, so you don't have to worry about their management. However, you may notice that you get an additional ticket for each service. Note that tickets expire. Privileged tickets, such as root instance tickets, usually expire in a few minutes, while tickets that carry more ordinary privileges may be good for several hours or a day, depending on the installation's policy. If your login session extends beyond the time limit, you will have to reauthenticate yourself to Kerberos. # $ K + Kerberos Principals A Kerberos principal is an entity (such as a user or host) that can receive a Kerberos ticket. The Kerberos principal usually contains three parts. The first is the primary, which is the name of the user or service. The second is the instance, which in the case of a user is usually nonexistent (null). Some users may have additional principals with instances such as root or admin. Those users would use these principals only when doing work that requires the permissions that are assigned to these principals. The principal joeuser@BLEEP.COM is completely separate from the principal joeuser/root@BLEEP.COM. In the case of a service, the primary describes the type of service (such as host or pop). The instance is the name of the machine on which it runs; i.e., the host service running on the machine trillium.bleep.com would have the instance trillium.bleep.com, whereas the host service running on the machine daffodil.fubar.org would have the instance daffodil.bleep.org.. The third part of a Kerberos name is the realm. The realm describes which Kerberos installation provided authentication for the principal. The realm is usually the domain name in UPPER CASE letters; the machine trillium.bleep.com would be in the realm BLEEP.COM. When writing a Kerberos principal, the primary is separated from the instance by a slash (if the instance is not null), and the realm follows, preceded by an @ sign. (If the realm is the same as the default realm, it may be omitted.) By convention, the realm is specified in UPPER CASE. The following are examples of valid Kerberos principals: foo bar/admin baz@BLEEP.COM quux/root@BLEEP.COM # $ Kerberos ticket A Kerberos ticketKerberos_Tickets is an encrypted protocol message that provides authentication. Your Kerberos tickets are stored in a credentials cache, which may be a file, or may exist only in memory. # $ Kerberos primary The Kerberos primary is the first part of a Kerberos principalKerberos_Terms. The primary is usually either a user name or a service name. # $ Kerberos Instance The instance is the second part of a Kerberos principalKerberos_Terms. The instance further qualifies the primary. Most user principals have nonexistent (null) instances, but the instance "root" or "admin" may be used to denote a principal with special privileges. In the case of a host, the instance is the fully-qualified hostname. # $ Kerberos Realm A Kerberos realm is an administrative domain. In most cases, the realm name is the same as the internet domain, in UPPER CASE letters. (Note that realm names are case sensitive.) The last part of a Kerberos principalKerberos_Terms (the part after the "@" sign) is the realm. # $ Kerberos Configuration File This file contains information that will help your computer find the correct server for the particular Kerberos realm in which you are trying to obtain tickets. Because the information is particular to your Kerb*Net installation, you will need to get a copy of this file from your system administrator. # $ Forwardable Tickets If you have forwardable tickets, you can forward a copy of them to a remote host. This enables you to use your credentials on the remote host without having to type your password. # $ Key Distribution Center (KDC) A Key Distribution Center (KDC) is a host that issues Kerberos ticketsKerberos_Ticket. # IDH_CONTENTS $ Contents K Contents + KERBNET:0 # Using_Kerb*Net_for_Windows $ Using Kerb*Net for Windows K Using Kerb*Net for Windows;Kerb*Net;cns;Kerberos;Kerberos 5;cns 5 + KERBNET:0 # Troubleshooting_Kerb*Net_for_Windows $ Troubleshooting Kerb*Net for Windows K Troubleshooting Kerb*Net for Windows;troubleshooting;bugs + KERBNET:0 # Kerberos_Tickets $ Kerberos Tickets K Kerberos Tickets;ticket;authenticate;authentication + KERBNET:0 # Kerberos_Terms $ Kerberos Terms K Kerberos Terms;principal;primary;instance;realm + KERBNET:0 # Kerberos_ticket $ Kerberos ticket # Kerberos_primary $ Kerberos primary # Kerberos_Instance $ Kerberos Instance # Kerberos_Realm $ Kerberos Realm # Kerberos_Configuration_File $ Kerberos Configuration File # Forwardable_Tickets $ Forwardable Tickets # Key_Distribution_Center_KDC $ Key Distribution Center (KDC) /=llllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllll;Uoq !"#IYh)%@[' 2 E H I J K L M N O ~ t z MUV^b \^b P`U"'w&'()<K[    K]kABCDbcde *+GH!"-.@AST^b \^b PV`,-?@STghxy01HuP :;q? \ F G u - . + , s 4h(s%: )?@a`a *G!-@-@S,?Sgx/01K@Normal]a ,@, Heading 1sPxUc*@* Heading 2 hhxUc(@( Heading 3 <Uc$@$ Heading 4h^c$@$ Heading 5<c&@& Heading 6<Vc @ Heading 7<"@" Heading 8<V& @& Heading 9 <Vc"A@"Default Paragraph Font O Topic Texthh*O* Topic HeadinghxUc(O( Topic CaptionUc*O"*Topic Text Item h(O2(Topic Text Indent"@B" Normal Indent@R Footnote Text &@a Footnote Referenceh "HJLN &(  ACbd1%1Nk EQdw +=Pcw3SV     1Q=cV 11 !!! !!!!! ! ! ! H & Ab1#-  " UHs@1ANCHORTITLEROBOHELP22Rh)<['EtE[Tk )\ /?+ARiw2Network Sercurity՜.+,0HP`hp x Cygnus7<+ # $ K + Contentsࡱ>krb5-1.16/src/windows/cns/cns-help.doc0000644000704600001450000005400013211554426017441 0ustar ghudsonlibuuidࡱ>  ܥhc e:T,,./111111111218W22222222N266669+778H9X9d81^222^2^28$41122$4$4$4^212126d耻(1Jr1|N0J0|11^26$4$4# $ K + Contents The following Help Topics are available: Using Kerb*Net for WindowsUsing_Kerb*Net_for_Windows Kerberos TicketsKerberos_Tickets Kerberos PrincipalsKerberos_Terms Troubleshooting Kerb*Net for WindowsTroubleshooting_Kerb*Net_for_Windows For Help on Help, Press F1 # $ K + Using Kerb*Net for Windows To obtain Kerberos ticketsKerberos_ticket using Kerb*Net for Windows, type your Kerberos primaryKerberos_primary or Kerberos primary/instanceKerberos_Instance (separated by a slash) in the Name box, your Kerberos realmKerberos_Realm (must be all upper-case) in the Realm box, and your password in the Password box, and then click the Login button. To delete your Kerberos tickets, click the Delete button. Also, attempting to obtain new tickets will automatically delete any existing tickets. To change your password, click the Change Password button. This will bring up a dialog box. Enter your primaryKerberos_primary or primary/instanceKerberos_Instance in the Name box, and your Kerberos realmKerberos_Realm in the Realm box. Type your old password in the Old box, and your new password twice, once in each New box. When all of the boxes are properly filled in, click the OK button. You can also specify the following options, by selecting File, and then Options: the location of the Kerberos configuration fileKerberos_Configuration_File the location of the credential cache (ticketKerberos_Ticket file) whether or not Kerb*Net should alert you by popping its window up and/or beeping when your tickets expire whether your tickets should be forwardableForwardable_Tickets # $ K + Kerberos Tickets When you authenticate yourself, Kerberos gives you an initial Kerberos ticket. (A Kerberos ticket is an encrypted protocol message that provides authentication.) Kerberos uses this ticket for network utilities. The ticket transactions are done transparently, so you don't have to worry about their management. However, you may notice that you get an additional ticket for each service. Note that tickets expire. Privileged tickets, such as root instance tickets, usually expire in a few minutes, while tickets that carry more ordinary privileges may be good for several hours or a day, depending on the installation's policy. If your login session extends beyond the time limit, you will have to reauthenticate yourself to Kerberos. # $ K + Kerberos Principals A Kerberos principal is an entity (such as a user or host) that can receive a Kerberos ticket. The Kerberos principal usually contains three parts. The first is the primary, which is the name of the user or service. The second is the instance, which in the case of a user is usually nonexistent (null). Some users may have additional principals with instances such as root or admin. Those users would use these principals only when doing work that requires the permissions that are assigned to these principals. The principal joeuser@BLEEP.COM is completely separate from the principal joeuser/root@BLEEP.COM. In the case of a service, the primary describes the type of service (such as host or pop). The instance is the name of the machine on which it runs; i.e., the host service running on the machine trillium.bleep.com would have the instance trillium.bleep.com, whereas the host service running on the machine daffodil.fubar.org would have the instance daffodil.bleep.org.. The third part of a Kerberos name is the realm. The realm describes which Kerberos installation provided authentication for the principal. The realm is usually the domain name in UPPER CASE letters; the machine trillium.bleep.com would be in the realm BLEEP.COM. When writing a Kerberos principal, the primary is separated from the instance by a slash (if the instance is not null), and the realm follows, preceded by an @ sign. (If the realm is the same as the default realm, it may be omitted.) By convention, the realm is specified in UPPER CASE. The following are examples of valid Kerberos principals: foo bar/admin baz@BLEEP.COM quux/root@BLEEP.COM # $ K + Troubleshooting Kerb*Net for Windows The file libkrb5.dll must be somewhere in your path. Your Kerberos Config fileKerberos_Configuration_File must be in the location specified in your Options (under the File menu). The directory that you specify for Kerb*Net to put your Credential (ticketKerberos_Ticket file) in must exist. If the Key Distribution Center (KDC) Key_Distribution_Center_KDC is unreachable (perhaps because of network problems), you will be unable to get tickets. If the admin server is unreachable, you will be unable to change your password. # $ Kerberos ticket A Kerberos ticketKerberos_Tickets is an encrypted protocol message that provides authentication. Your Kerberos tickets are stored in a credentials cache, which may be a file, or may exist only in memory. # $ Kerberos primary The Kerberos primary is the first part of a Kerberos principalKerberos_Terms. The primary is usually either a user name or a service name. # $ Kerberos Instance The instance is the second part of a Kerberos principalKerberos_Terms. The instance further qualifies the primary. Most user principals have nonexistent (null) instances, but the instance "root" or "admin" may be used to denote a principal with special privileges. In the case of a host, the instance is the fully-qualified hostname. # $ Kerberos Realm A Kerberos realm is an administrative domain. In most cases, the realm name is the same as the internet domain, in UPPER CASE letters. The last part of a Kerberos principalKerberos_Terms (the part after the "@" sign) is the realm. # $ Kerberos Configuration File This file contains information that will help your computer find the correct server for the particular Kerberos realm in which you are trying to obtain tickets. Because the information is particular to your Kerb*Net installation, you will need to get a copy of this file from your system administrator. # $ Forwardable Tickets If you have forwardable tickets, you can forward a copy of them to a remote host. This enables you to use your credentials on the remote host without having to type your password. # $ Key Distribution Center (KDC) A Key Distribution Center (KDC) is a host that issues Kerberos ticketsKerberos_Ticket. # IDH_CONTENTS $ Contents K Contents + KERBNET:0 # Using_Kerb*Net_for_Windows $ Using Kerb*Net for Windows K Using Kerb*Net for Windows;Kerb*Net;cns;Kerberos;Kerberos 5;cns 5 + KERBNET:0 # Kerberos_Tickets $ Kerberos Tickets K Kerberos Tickets;ticket;authenticate;authentication + KERBNET:0 # Kerberos_Terms $ Kerberos Terms K Kerberos Terms;principal;primary;instance;realm + KERBNET:0 # Troubleshooting_Kerb*Net_for_Windows $ Troubleshooting Kerb*Net for Windows K Troubleshooting Kerb*Net for Windows;troubleshooting;bugs + KERBNET:0 # Kerberos_ticket $ Kerberos ticket # Kerberos_primary $ Kerberos primary # Kerberos_Instance $ Kerberos Instance # Kerberos_Realm $ Kerberos Realm # Kerberos_Configuration_File $ Kerberos Configuration File # Forwardable_Tickets $ Forwardable Tickets # Key_Distribution_Center_KDC $ Key Distribution Center (KDC) /=lllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllll;Uoq !"#IYh) >Yt@ K ^ a b c d e f g h _ ` a b c d e f " * h q ~LablV^b \^b P`2=mx(.=[y@ABCVeu$%&'ew"0123./01OPQR45xy@ALMst^b \^b VP`,-@ATUefvw5uP :;q?89)*u! _ ` z  ^ { Hcdmn 4h'()^_ST?T!"#9./C,-N~MNq4x,@Ls,@TevK@Normal]a &@& Heading 1<xUc*@* Heading 2 hhxUc(@( Heading 3 <Uc$@$ Heading 4h^c$@$ Heading 5<c&@& Heading 6<Vc @ Heading 7<"@" Heading 8<V& @& Heading 9 <Vc"A@"Default Paragraph Font O Topic Texthh*O* Topic HeadinghxUc(O( Topic CaptionUc*O"*Topic Text Item h(O2(Topic Text Indent"@B" Normal Indent@R Footnote Text &@a Footnote Referenceh "aceg_ a c e @B$&02.0OQ%1Nk#4Ew +=Pcw3SV     1#=cV  !!! !!!!! ! ! ! a_ @$0.O#-  " 5ANCHORTITLEROBOHELPzRh)Ut@^mst(=y_un "$,IoNr.?VdxNetwork Sercurity՜.+,0HP`hp x CygnusT;+ # $ K + Contentsࡱ>krb5-1.16/src/windows/cns/cnsres4.rc0000644000704600001450000001404313211554426017153 0ustar ghudsonlibuuid#include #define KRB4 #include "cns.h" IDI_KWIN ICON PRELOAD cns.ico IDI_0_MIN ICON PRELOAD clock00.ico IDI_5_MIN ICON PRELOAD clock05.ico IDI_10_MIN ICON PRELOAD clock10.ico IDI_15_MIN ICON PRELOAD clock15.ico IDI_20_MIN ICON PRELOAD clock20.ico IDI_25_MIN ICON PRELOAD clock25.ico IDI_30_MIN ICON PRELOAD clock30.ico IDI_35_MIN ICON PRELOAD clock35.ico IDI_40_MIN ICON PRELOAD clock40.ico IDI_45_MIN ICON PRELOAD clock45.ico IDI_50_MIN ICON PRELOAD clock50.ico IDI_55_MIN ICON PRELOAD clock55.ico IDI_60_MIN ICON PRELOAD clock60.ico IDI_EXPIRED ICON PRELOAD clockexp.ico IDI_TICKET ICON PRELOAD clocktkt.ico IDM_KWIN MENU PRELOAD BEGIN POPUP "&File" BEGIN MENUITEM "&Options...", IDM_OPTIONS MENUITEM SEPARATOR MENUITEM "E&xit", IDM_EXIT END POPUP "&Help" BEGIN MENUITEM "&Index\tF1", IDM_HELP_INDEX MENUITEM SEPARATOR MENUITEM "&About Kerberos...", IDM_ABOUT END END IDA_KWIN ACCELERATORS PRELOAD BEGIN VK_F1, IDM_HELP_INDEX, VIRTKEY END ID_KWIN DIALOG PRELOAD MOVEABLE DISCARDABLE 0, 0, 276, 114 STYLE WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME | WS_MINIMIZEBOX CLASS KWIN_DIALOG_CLASS CAPTION KWIN_DIALOG_NAME MENU IDM_KWIN FONT 8, "Arial" BEGIN CONTROL " Start Time End Time Ticket", IDD_TICKET_LIST_TITLE, "STATIC", SS_LEFT | WS_CHILD | WS_VISIBLE | WS_GROUP, 16, 7, 240, 8 CONTROL "", IDD_TICKET_LIST, "LISTBOX", LBS_NOTIFY | LBS_DISABLENOSCROLL | LBS_OWNERDRAWFIXED | WS_CHILD | WS_VISIBLE | WS_BORDER | WS_VSCROLL, 8, 18, 261, 52 CONTROL "&Name", IDD_LOGIN_NAME_TITLE, "STATIC", SS_LEFT | WS_CHILD | WS_VISIBLE | WS_GROUP, 6, 69, 27, 8 CONTROL "&Instance", IDD_LOGIN_INSTANCE_TITLE, "STATIC", SS_LEFT | WS_CHILD | WS_VISIBLE | WS_GROUP, 73, 69, 36, 8 CONTROL "&Realm", IDD_LOGIN_REALM_TITLE, "STATIC", SS_LEFT | WS_CHILD | WS_VISIBLE | WS_GROUP, 140, 69, 26, 8 CONTROL "&Password", IDD_LOGIN_PASSWORD_TITLE, "STATIC", SS_LEFT | WS_CHILD | WS_VISIBLE | WS_GROUP, 207, 69, 36, 8 CONTROL "", IDD_LOGIN_NAME, "EDIT", ES_LEFT | ES_AUTOHSCROLL | WS_CHILD | WS_VISIBLE | WS_BORDER | WS_TABSTOP, 6, 79, 62, 12 CONTROL "", IDD_LOGIN_INSTANCE, "EDIT", ES_LEFT | ES_AUTOHSCROLL | WS_CHILD | WS_VISIBLE | WS_BORDER | WS_TABSTOP, 73, 79, 62, 12 CONTROL "", IDD_LOGIN_REALM, "EDIT", ES_LEFT | ES_AUTOHSCROLL | ES_UPPERCASE | WS_CHILD | WS_VISIBLE | WS_BORDER | WS_TABSTOP, 140, 79, 62, 12 CONTROL "", IDD_LOGIN_PASSWORD, "EDIT", ES_LEFT | ES_AUTOHSCROLL | ES_PASSWORD | WS_CHILD | WS_VISIBLE | WS_BORDER | WS_TABSTOP, 207, 79, 62, 12 CONTROL "&Change Password...", IDD_CHANGE_PASSWORD, "BUTTON", BS_PUSHBUTTON | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 6, 96, 74, 14 CONTROL "&Delete", IDD_TICKET_DELETE, "BUTTON", BS_PUSHBUTTON | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 122, 96, 52, 14 CONTROL "&Login", IDD_LOGIN, "BUTTON", BS_DEFPUSHBUTTON | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 216, 96, 52, 14 CONTROL "", IDD_PASSWORD_CR2, "BUTTON", BS_PUSHBUTTON | WS_CHILD | WS_VISIBLE, 5000, 5000, 0, 0 END ID_PASSWORD DIALOG 96, 50, 143, 129 STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "Change Password" FONT 8, "Arial" BEGIN CONTROL "&Name:", -1, "STATIC", SS_LEFT | WS_CHILD | WS_VISIBLE, 5, 9, 53, 8 CONTROL "", IDD_PASSWORD_NAME, "EDIT", ES_LEFT | ES_AUTOHSCROLL | WS_CHILD | WS_VISIBLE | WS_BORDER | WS_GROUP | WS_TABSTOP, 61, 6, 76, 12 CONTROL "&Instance:", -1, "STATIC", SS_LEFT | WS_CHILD | WS_VISIBLE, 5, 26, 53, 8 CONTROL "", IDD_PASSWORD_INSTANCE, "EDIT", ES_LEFT | ES_AUTOHSCROLL | WS_CHILD | WS_VISIBLE | WS_BORDER | WS_TABSTOP, 61, 23, 76, 12 CONTROL "&Realm:", -1, "STATIC", SS_LEFT | WS_CHILD | WS_VISIBLE, 5, 43, 53, 8 CONTROL "", IDD_PASSWORD_REALM, "EDIT", ES_LEFT | ES_AUTOHSCROLL | WS_CHILD | WS_VISIBLE | WS_BORDER | WS_TABSTOP, 61, 40, 76, 12 CONTROL "&Old Password:", -1, "STATIC", SS_LEFT | WS_CHILD | WS_VISIBLE, 5, 60, 53, 8 CONTROL "", IDD_OLD_PASSWORD, "EDIT", ES_LEFT | ES_AUTOHSCROLL | ES_PASSWORD | WS_CHILD | WS_VISIBLE | WS_BORDER | WS_TABSTOP, 61, 57, 76, 12 CONTROL "&New Password:", -1, "STATIC", SS_LEFT | WS_CHILD | WS_VISIBLE, 5, 77, 53, 8 CONTROL "", IDD_NEW_PASSWORD1, "EDIT", ES_LEFT | ES_AUTOHSCROLL | ES_PASSWORD | WS_CHILD | WS_VISIBLE | WS_BORDER | WS_TABSTOP, 61, 74, 76, 12 CONTROL "&New Password:", -1, "STATIC", SS_LEFT | WS_CHILD | WS_VISIBLE, 5, 94, 53, 8 CONTROL "", IDD_NEW_PASSWORD2, "EDIT", ES_LEFT | ES_AUTOHSCROLL | ES_PASSWORD | WS_CHILD | WS_VISIBLE | WS_BORDER | WS_TABSTOP, 61, 91, 76, 12 CONTROL "", IDD_PASSWORD_CR, "BUTTON", BS_PUSHBUTTON | WS_CHILD | WS_VISIBLE, 5000, 5000, 0, 0 CONTROL "OK", IDOK, "BUTTON", BS_DEFPUSHBUTTON | WS_CHILD | WS_VISIBLE | WS_GROUP | WS_TABSTOP, 13, 110, 52, 14 CONTROL "Cancel", IDCANCEL, "BUTTON", BS_PUSHBUTTON | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 77, 110, 52, 14 END ID_OPTS DIALOG 97, 52, 148, 107 STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "Kerberos Options" FONT 8, "Arial" BEGIN CONTROL "&Conf file:", -1, "STATIC", SS_LEFT | WS_CHILD | WS_VISIBLE, 5, 9, 40, 8 CONTROL "", IDD_CONF, "EDIT", ES_LEFT | ES_AUTOHSCROLL | WS_CHILD | WS_VISIBLE | WS_BORDER | WS_TABSTOP, 60, 6, 82, 12 CONTROL "&Realms file:", -1, "STATIC", SS_LEFT | WS_CHILD | WS_VISIBLE, 5, 26, 40, 8 CONTROL "", IDD_REALMS, "EDIT", ES_LEFT | ES_AUTOHSCROLL | WS_CHILD | WS_VISIBLE | WS_BORDER | WS_TABSTOP, 60, 23, 82, 12 CONTROL "&Ticket lifetime:", -1, "STATIC", SS_LEFT | WS_CHILD | WS_VISIBLE, 5, 43, 53, 8 CONTROL "", IDD_LIFETIME, "EDIT", ES_LEFT | ES_AUTOHSCROLL | WS_CHILD | WS_VISIBLE | WS_BORDER | WS_TABSTOP, 60, 40, 20, 12 CONTROL "minutes", -1, "STATIC", SS_LEFT | WS_CHILD | WS_VISIBLE, 85, 43, 46, 8 CONTROL "Action when login expires", 209, "BUTTON", BS_GROUPBOX | WS_CHILD | WS_VISIBLE | WS_GROUP, 5, 56, 138, 23 CONTROL "&Alert ", IDD_ALERT, "BUTTON", BS_AUTOCHECKBOX | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 31, 65, 28, 12 CONTROL "&Beep", IDD_BEEP, "BUTTON", BS_AUTOCHECKBOX | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 80, 65, 39, 12 CONTROL "OK", IDOK, "BUTTON", BS_DEFPUSHBUTTON | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 17, 87, 52, 14 CONTROL "Cancel", IDCANCEL, "BUTTON", BS_PUSHBUTTON | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 81, 87, 52, 14 END krb5-1.16/src/windows/cns/clocktkt.ico0000644000704600001450000000207613211554426017561 0ustar ghudsonlibuuid & 0( @ z   z  wwwwwwwwwwwwp( @Y7p5`Z p ^krb5-1.16/src/windows/cns/krbini.h0000644000704600001450000000316613211554426016677 0ustar ghudsonlibuuid/* Kerberos changed window message */ #define WM_KERBEROS_CHANGED "Kerberos Changed" /* Kerberos Windows initialization file */ #define KERBEROS_INI "kerberos.ini" #ifdef CYGNUS #define KERBEROS_HLP "kerbnet.hlp" #else #define KERBEROS_HLP "krb5.hlp" #endif #define INI_DEFAULTS "Defaults" #define INI_USER "User" /* Default user */ #define INI_INSTANCE "Instance" /* Default instance */ #define INI_REALM "Realm" /* Default realm */ #define INI_POSITION "Position" #define INI_OPTIONS "Options" #define INI_DURATION "Duration" /* Ticket duration in minutes */ #define INI_EXPIRATION "Expiration" /* Action on expiration (alert or beep) */ #define INI_ALERT "Alert" #define INI_BEEP "Beep" #define INI_FILES "Files" #ifdef KRB4 #define INI_KRB_CONF "krb.conf" /* Location of krb.conf file */ #define DEF_KRB_CONF "krb.conf" /* Default name for krb.conf file */ #endif /* KRB4 */ #ifdef KRB5 #define INI_KRB5_CONF "krb5.ini" /* From k5-config.h */ #define INI_KRB_CONF INI_KRB5_CONF /* Location of krb.conf file */ #define DEF_KRB_CONF INI_KRB5_CONF /* Default name for krb.conf file */ #define INI_TICKETOPTS "TicketOptions" /* Ticket options */ #define INI_FORWARDABLE "Forwardable" /* get forwardable tickets */ #define INI_KRB_CCACHE "krb5cc" /* From k5-config.h */ #endif /* KRB5 */ #define INI_KRB_REALMS "krb.realms" /* Location of krb.realms file */ #define DEF_KRB_REALMS "krb.realms" /* Default name for krb.realms file */ #define INI_RECENT_LOGINS "Recent Logins" #define INI_LOGIN "Login" krb5-1.16/src/windows/cns/cns_reg.h0000644000704600001450000000241413211554426017034 0ustar ghudsonlibuuid/* * Copyright (c) 1997 Cygnus Solutions * * Author: Michael Graff */ #include typedef struct cns_reg { DWORD x; /* default dialog size */ DWORD y; DWORD cx; DWORD cy; DWORD lifetime; /* ticket lifetime */ DWORD beep; /* beep on expire/warning? */ DWORD alert; /* alert (deiconify) when tix expired? */ DWORD forwardable; /* get forwardable tickets? */ DWORD conf_override; /* allow changing of confname */ DWORD cc_override; /* allow changing of ccname */ DWORD noaddresses; /* Don't require address in tickets */ char name[MAX_K_NAME_SZ]; /* last user used */ char realm[MAX_K_NAME_SZ]; /* last realm used */ char confname[FILENAME_MAX]; char ccname[FILENAME_MAX]; char def_confname[FILENAME_MAX]; char def_ccname[FILENAME_MAX]; char logins[FILE_MENU_MAX_LOGINS][MAX_K_NAME_SZ]; } cns_reg_t; extern cns_reg_t cns_res; void cns_load_registry(void); void cns_save_registry(void); krb5-1.16/src/windows/cns/cnsres5.rc0000644000704600001450000001616313211554426017161 0ustar ghudsonlibuuid//Microsoft Developer Studio generated resource script. // #define APSTUDIO_READONLY_SYMBOLS ///////////////////////////////////////////////////////////////////////////// // // Generated from the TEXTINCLUDE 2 resource. // #define APSTUDIO_HIDDEN_SYMBOLS #include "windows.h" #undef APSTUDIO_HIDDEN_SYMBOLS #include "cns.h" ///////////////////////////////////////////////////////////////////////////// #undef APSTUDIO_READONLY_SYMBOLS ///////////////////////////////////////////////////////////////////////////// // English (U.S.) resources #if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) #ifdef _WIN32 LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US #pragma code_page(1252) #endif //_WIN32 ///////////////////////////////////////////////////////////////////////////// // // Icon // // Icon with lowest ID value placed first to ensure application icon // remains consistent on all systems. IDI_KWIN ICON PRELOAD DISCARDABLE "cns.ico" IDI_0_MIN ICON PRELOAD DISCARDABLE "clock00.ico" IDI_5_MIN ICON PRELOAD DISCARDABLE "clock05.ico" IDI_10_MIN ICON PRELOAD DISCARDABLE "clock10.ico" IDI_15_MIN ICON PRELOAD DISCARDABLE "clock15.ico" IDI_20_MIN ICON PRELOAD DISCARDABLE "clock20.ico" IDI_25_MIN ICON PRELOAD DISCARDABLE "clock25.ico" IDI_30_MIN ICON PRELOAD DISCARDABLE "clock30.ico" IDI_35_MIN ICON PRELOAD DISCARDABLE "clock35.ico" IDI_40_MIN ICON PRELOAD DISCARDABLE "clock40.ico" IDI_45_MIN ICON PRELOAD DISCARDABLE "clock45.ico" IDI_50_MIN ICON PRELOAD DISCARDABLE "clock50.ico" IDI_55_MIN ICON PRELOAD DISCARDABLE "clock55.ico" IDI_60_MIN ICON PRELOAD DISCARDABLE "clock60.ico" IDI_EXPIRED ICON PRELOAD DISCARDABLE "clockexp.ico" IDI_TICKET ICON PRELOAD DISCARDABLE "clocktkt.ico" ///////////////////////////////////////////////////////////////////////////// // // Menu // IDM_KWIN MENU PRELOAD DISCARDABLE BEGIN POPUP "&File" BEGIN MENUITEM "&Options...", IDM_OPTIONS MENUITEM SEPARATOR MENUITEM "E&xit", IDM_EXIT END POPUP "&Help" BEGIN MENUITEM "&Index\tF1", IDM_HELP_INDEX MENUITEM SEPARATOR MENUITEM "&About Kerberos...", IDM_ABOUT END END ///////////////////////////////////////////////////////////////////////////// // // Accelerator // IDA_KWIN ACCELERATORS PRELOAD MOVEABLE PURE BEGIN VK_F1, IDM_HELP_INDEX, VIRTKEY END ///////////////////////////////////////////////////////////////////////////// // // Dialog // ID_KWIN DIALOG PRELOAD DISCARDABLE 0, 0, 336, 115 STYLE WS_MINIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME #ifdef CYGNUS CAPTION "KerbNet" #else CAPTION "Kerberos" #endif MENU IDM_KWIN CLASS "KERBEROS" FONT 8, "Arial" BEGIN CONTROL " Start Time End Time Ticket", IDD_TICKET_LIST_TITLE,"Static",SS_LEFTNOWORDWRAP | WS_GROUP,16,7,311,8 LISTBOX IDD_TICKET_LIST,8,18,319,52,LBS_OWNERDRAWFIXED | LBS_DISABLENOSCROLL | WS_VSCROLL LTEXT "&Name",IDD_LOGIN_NAME_TITLE,6,69,27,8 LTEXT "&Password",IDD_LOGIN_PASSWORD_TITLE,125,69,42,8 LTEXT "&Realm",IDD_LOGIN_REALM_TITLE,239,69,26,8 EDITTEXT IDD_LOGIN_NAME,6,79,84,12,ES_AUTOHSCROLL EDITTEXT IDD_LOGIN_PASSWORD,126,78,84,12,ES_PASSWORD | ES_AUTOHSCROLL EDITTEXT IDD_LOGIN_REALM,239,79,84,12,ES_AUTOHSCROLL PUSHBUTTON "&Change Password...",IDD_CHANGE_PASSWORD,6,96,84,14 PUSHBUTTON "&Delete",IDD_TICKET_DELETE,141,96,52,14 DEFPUSHBUTTON "&Login",IDD_LOGIN,271,96,52,14 PUSHBUTTON "",IDD_PASSWORD_CR2,5000,5000,6,6,NOT WS_TABSTOP END ID_PASSWORD DIALOG DISCARDABLE 96, 50, 143, 112 STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "Change Password" FONT 8, "Arial" BEGIN LTEXT "&Name:",-1,5,9,53,8,NOT WS_GROUP EDITTEXT IDD_PASSWORD_NAME,61,6,76,12,ES_AUTOHSCROLL | WS_GROUP LTEXT "&Realm:",-1,5,26,53,8,NOT WS_GROUP EDITTEXT IDD_PASSWORD_REALM,61,23,76,12,ES_AUTOHSCROLL LTEXT "&Old Password:",-1,5,43,53,8,NOT WS_GROUP EDITTEXT IDD_OLD_PASSWORD,61,40,76,12,ES_PASSWORD | ES_AUTOHSCROLL LTEXT "&New Password:",-1,5,60,53,8,NOT WS_GROUP EDITTEXT IDD_NEW_PASSWORD1,61,57,76,12,ES_PASSWORD | ES_AUTOHSCROLL LTEXT "&New Password:",-1,5,77,53,8,NOT WS_GROUP EDITTEXT IDD_NEW_PASSWORD2,61,74,76,12,ES_PASSWORD | ES_AUTOHSCROLL PUSHBUTTON "",IDD_PASSWORD_CR,5000,5000,0,0,NOT WS_TABSTOP DEFPUSHBUTTON "OK",IDOK,13,93,52,14,WS_GROUP PUSHBUTTON "Cancel",IDCANCEL,77,93,52,14 END ID_OPTS DIALOG DISCARDABLE 97, 52, 169, 138 STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU #ifdef CYGNUS CAPTION "KerbNet Options" #else CAPTION "Kerberos Options" #endif FONT 8, "Arial" BEGIN LTEXT "&Config file:",-1,5,9,40,8,NOT WS_GROUP EDITTEXT IDD_CONF,70,6,92,12,ES_AUTOHSCROLL LTEXT "Cre&dential cache:",-1,5,26,58,8,NOT WS_GROUP EDITTEXT IDD_CCACHE,70,23,92,12,ES_AUTOHSCROLL LTEXT "&Ticket lifetime:",-1,5,43,53,8,NOT WS_GROUP EDITTEXT IDD_LIFETIME,70,40,32,12,ES_AUTOHSCROLL LTEXT "minutes",-1,109,42,46,8,NOT WS_GROUP GROUPBOX "Action when login expires",IDD_ACTIONS,5,56,158,23, WS_GROUP CONTROL "&Alert ",IDD_ALERT,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,41,65,28,12 CONTROL "&Beep",IDD_BEEP,"Button",BS_AUTOCHECKBOX | WS_TABSTOP, 95,65,39,12 GROUPBOX "Ticket options",IDD_TKOPT,5,86,158,23,WS_GROUP CONTROL "&Forwardable",IDD_FORWARDABLE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,25,95,65,12 CONTROL "&NoAddresses",IDD_NOADDRESSES,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,90,95,65,12 DEFPUSHBUTTON "OK",IDOK,19,117,52,14 PUSHBUTTON "Cancel",IDCANCEL,95,117,52,14 END #ifdef APSTUDIO_INVOKED ///////////////////////////////////////////////////////////////////////////// // // TEXTINCLUDE // 1 TEXTINCLUDE DISCARDABLE BEGIN END 2 TEXTINCLUDE DISCARDABLE BEGIN "#define APSTUDIO_HIDDEN_SYMBOLS\r\n" "#include ""windows.h""\r\n" "#undef APSTUDIO_HIDDEN_SYMBOLS\r\n" "#include ""cns.h""\r\n" "\0" END 3 TEXTINCLUDE DISCARDABLE BEGIN "\r\n" "\0" END #endif // APSTUDIO_INVOKED #endif // English (U.S.) resources ///////////////////////////////////////////////////////////////////////////// #ifndef APSTUDIO_INVOKED ///////////////////////////////////////////////////////////////////////////// // // Generated from the TEXTINCLUDE 3 resource. // ///////////////////////////////////////////////////////////////////////////// #endif // not APSTUDIO_INVOKED #include "..\version.rc" krb5-1.16/src/windows/cns/kerbnet.hlp0000644000704600001450000003771613211554426017417 0ustar ghudsonlibuuid?_?()*,.aadditional@adminadareasauthenticabeBLEEPbleepboxbuttycachecaseCASEC.erchangeclickCOMConfigurD containstZ scredbalsdaffodildeletibesDistEudom<e ncryp"xpirefileFfirstfollowingforForwarda `romhaveHelphostinin ,m tall I nce `cesisjoeuserKDCKerberosKeyslo 21mmaymessagemustnameNetnetwork`nonexgn ubofonOpsorparticula rPass7dp!PrimarincipalPPs` v$ge@otocolvFiblmRremoootrDungsedse~avihouldspecifi ysuchthDat4The:s sT0tfilliumTrouRQogtypeununIoUPPERptsUsHusuyWwk rwhichwiTWi'w$yourself"),)..)@/:;@Aco`mcopyf!getIfInitNnewnotNonlyorgssigns8lasToupusewhenwithYour/&;)z4 W |CONTEXT&|CTXOMAP)|FONT|KWBTREE|KWDATA4|KWMAP|Petra'/|PhrImage|PhrIndexE|SYSTEM|TOPIC|TTLBTREE|TopicIdV7tUcJH "E5@)IjẢ͈wwD5͈֠ДY<&4D6Fc$s 2C#2#34!3l! 2 Kerb*NetBrowseButtons()Zmainmain    2>1>8* h' 68>[ *8R7v :K0 `}||`P-}&P]P\+TopicsCavailable#:\rR/" t ?ForB\#Press F1:hW1FW@ci`2'h:њpGWW |iA an>Ar. P|B?6QѬXt#using Qt@@/h($ ` .0T@0E(@P0: @#Login>"P.>t @+Delete AlsoKatte(mptؽcautomaticallyHany@;exis* aQK dFq;SA::.`Chang,eГ#brR/+dialog #Enter^\1Z17QMQ8OTypeoldXaOldnq#twiceonceD 'NewF Bll#boxe;proper<+fi@lled`Q OK!You aP3oonsCsc!L ,"A1"nci 1!s=|'wSP'P/`HF]Dc+7`z cconfigur#onJ3Y"Kcredent&(@J+)G )$#a@lert3popp6its+window3Hbee  LH#L@ VO:$Q1 Ed2'c'4^N^tvET@ vEtl5}wQU_J3libkrb5dllCsomewher~path#"V+C!J, Iz) +P#und %aL`menu)@Cdirdory ĽputA KCaQ l$vB,pl3hapsiRse##0ms{@H t?$4y1 y y,E':&:%y , &k[*hcateB#giv3ini#t .( Ftt!PsR'Cutil=es2[transa{donec parAmly I#'tZ#wor#ab o#irK@managet3Howeverp~+noe " 5W&&}KPrivilegdDhoH few3m inute#wh.`#camo;orPdina@goodD3sA#hour&s:RdaCdPepen4gHkinst$':policyN"#)inMss3ext<abeyondw time(imitv29kreܱ"t[9 1 NTerms, / @' ,r < FT_@ ee"+ty" ^w3e#e46&re+Wt~"N , V&N 0h[ 0(olS)eZV!j8"  .#Tho*&Sk;reTqus7 SjmZi!s~agnvA@n 2Kcomp ;se<X $' D|/ / @ Nr) tPa @ +1^ ").Ph`|* runsi4e ,0*>#| 9ZM h L"0;3@&a07<#fubar<+havA1q_#' @:'F@1 F@@vB,p4 @z@' @60P)YOF@@0 03n>P <p`l ^+issuest+.;1z@1 HHelvSymbol UL  /&;)F24authenticateauthenticationbugscns cns 5ContentsinstanceKerb*NetKerberos Kerberos 5$Kerberos Terms(Kerberos Tickets,primary0principal4realm8ticket<troubleshooting@Troubleshooting Kerb*Net for WindowsDUsing Kerb*Net for WindowsH/&;)Lz  ContentsUsing Kerb*Net for WindowsTroubleshooting Kerb*Net for WindowsKerberos Tickets Kerberos Terms2Kerberos ticket Kerberos primaryKerberos InstanceKerberos RealmKerberos Configuration FilepForwardable TicketsKey Distribution Center (KDC)o/&;)L4  ѬX-} n>2}||:K0r. |?F]Dp 1h8R7v='wQ/&;)Lz  c:\windows\desktop\kerberos 5\win95 gui\cns help\KERBNET.RTFc:\windows\desktop\kerberos 5\win95 gui\cns help\KERBNET.RTFc:\windows\desktop\kerberos 5\win95 gui\cns help\KERBNET.RTFc:\windows\desktop\kerberos 5\win95 gui\cns help\KERBNET.RTFc:\windows\desktop\kerberos 5\win95 gui\cns help\KERBNET.RTFc:\windows\desktop\kerberos 5\win95 gui\cns help\KERBNET.RTFc:\windows\desktop\kerberos 5\win95 gui\cns help\KERBNET.RTFc:\windows\desktop\kerberos 5\win95 gui\cns help\KERBNET.RTF c:\windows\desktop\kerberos 5\win95 gui\cns help\KERBNET.RTF c:\windows\desktop\kerberos 5\win95 gui\cns help\KERBNET.RTF c:\windows\desktop\kerberos 5\win95 gui\cns help\KERBNET.RTF c:\windows\desktop\kerberos 5\win95 gui\cns help\KERBNET.RTF/&;)Lz  IDH_CONTENTSUsing_Kerb*Net_for_WindowsTroubleshooting_Kerb*Net_for_WindowsKerberos_TicketsKerberos_TermsKerberos_ticketKerberos_primaryKerberos_Instance Kerberos_Realm Kerberos_Configuration_File Forwardable_Tickets Key_Distribution_Center_KDC.߬. krb5-1.16/src/windows/cns/cns_reg.c0000644000704600001450000001317613211554426017036 0ustar ghudsonlibuuid/* * Copyright (c) 1997 Cygnus Solutions * * Author: Michael Graff */ #include #include #include #include #include "cns.h" #include "cns_reg.h" #include "../lib/registry.h" cns_reg_t cns_res; /* yes, a global. Sue me. */ /* * function to load all the data we will want from the registry. If the * registry data cannot be found this function will initialize a default * environment. */ void cns_load_registry(void) { char tmp[1024]; DWORD tdw; char *ts; HKEY key; int i; /* * Set up reasonable default values. These will all be overwritten if * the registry is successfully opened. */ cns_res.name[0] = '\0'; cns_res.realm[0] = '\0'; cns_res.x = 0; cns_res.y = 0; cns_res.cx = 0; cns_res.cy = 0; cns_res.alert = 0; cns_res.beep = 0; cns_res.lifetime = DEFAULT_TKT_LIFE * 5; cns_res.forwardable = 1; cns_res.noaddresses = 0; for (i = 1 ; i < FILE_MENU_MAX_LOGINS ; i++) cns_res.logins[i][0] = '\0'; /* * by default, allow the user to override the config file location and NOT the * cred cache name. */ cns_res.conf_override = 1; cns_res.cc_override = 0; { char *s; s = krb5_cc_default_name(k5_context); strcpy(cns_res.def_ccname, s); } cns_res.def_confname[0] = '\0'; /* * If the system has these keys in the registry, do not allow the user to * override the config file and ccache locations. */ key = registry_open(HKEY_LOCAL_MACHINE, KERBNET_BASE, KEY_READ); if (key != INVALID_HANDLE_VALUE) { if (registry_string_get(key, KERBNET_HOME, &ts) == 0) { cns_res.conf_override = 0; cns_res.def_confname[sizeof(cns_res.def_confname) - 1]; strncpy(cns_res.def_confname, ts, sizeof(cns_res.def_confname) - 1); strncat(cns_res.def_confname, "\\etc\\krb5.conf", sizeof(cns_res.def_confname) - 1 - strlen(cns_res.def_confname)); free(ts); } if (registry_string_get(key, "ccname", &ts) == 0) { cns_res.cc_override = 0; strcpy(cns_res.def_ccname, ts); free(ts); } } /* * Try to open the registry. If we succeed, read the last used values from there. If we * do not get the registry open simply return. */ key = registry_open(HKEY_CURRENT_USER, KERBNET_CNS_BASE, KEY_ALL_ACCESS); if (key == INVALID_HANDLE_VALUE) return; if (registry_dword_get(key, "x", &tdw) == 0) cns_res.x = tdw; if (registry_dword_get(key, "y", &tdw) == 0) cns_res.y = tdw; if (registry_dword_get(key, "cx", &tdw) == 0) cns_res.cx = tdw; if (registry_dword_get(key, "cy", &tdw) == 0) cns_res.cy = tdw; if (registry_dword_get(key, "lifetime", &tdw) == 0) cns_res.lifetime = tdw; if (registry_dword_get(key, "forwardable", &tdw) == 0) cns_res.forwardable = tdw; if (registry_dword_get(key, "noaddresses", &tdw) == 0) cns_res.noaddresses = tdw; if (registry_dword_get(key, "alert", &tdw) == 0) cns_res.alert = tdw; if (registry_dword_get(key, "beep", &tdw) == 0) cns_res.beep = tdw; if (registry_string_get(key, "name", &ts) == 0) { strcpy(cns_res.name, ts); free(ts); } if (registry_string_get(key, "realm", &ts) == 0) { strcpy(cns_res.realm, ts); free(ts); } if (cns_res.conf_override && (registry_string_get(key, "confname", &ts) == 0)) { strcpy(cns_res.confname, ts); free(ts); } else strcpy(cns_res.confname, cns_res.def_confname); if (cns_res.cc_override && (registry_string_get(key, "ccname", &ts) == 0)) { strcpy(cns_res.ccname, ts); free(ts); } else strcpy(cns_res.ccname, cns_res.def_ccname); for (i = 0 ; i < FILE_MENU_MAX_LOGINS ; i++) { sprintf(tmp, "login_%02d", i); if (registry_string_get(key, tmp, &ts) == 0) { strcpy(cns_res.logins[i], ts); free(ts); } } registry_close(key); } /* * save all the registry data, creating the keys if needed. */ void cns_save_registry(void) { char tmp[1024]; HKEY key; int i; /* * First, create the heirachy... This is gross, but functional */ key = registry_key_create(HKEY_CURRENT_USER, CYGNUS_SOLUTIONS, KEY_WRITE); if (key == INVALID_HANDLE_VALUE) return; key = registry_key_create(HKEY_CURRENT_USER, KERBNET_SANS_VERSION, KEY_WRITE); if (key == INVALID_HANDLE_VALUE) return; registry_close(key); key = registry_key_create(HKEY_CURRENT_USER, KERBNET_BASE, KEY_WRITE); if (key == INVALID_HANDLE_VALUE) return; registry_close(key); key = registry_key_create(HKEY_CURRENT_USER, KERBNET_CNS_BASE, KEY_WRITE); if (key == INVALID_HANDLE_VALUE) return; registry_dword_set(key, "x", cns_res.x); registry_dword_set(key, "y", cns_res.y); registry_dword_set(key, "cx", cns_res.cx); registry_dword_set(key, "cy", cns_res.cy); registry_dword_set(key, "alert", cns_res.alert); registry_dword_set(key, "beep", cns_res.beep); registry_dword_set(key, "lifetime", cns_res.lifetime); registry_dword_set(key, "forwardable", cns_res.forwardable); registry_dword_set(key, "noaddresses", cns_res.noaddresses); registry_string_set(key, "name", cns_res.name); registry_string_set(key, "realm", cns_res.realm); if (cns_res.conf_override) { if (strcmp(cns_res.confname, cns_res.def_confname)) registry_string_set(key, "confname", cns_res.confname); else registry_value_delete(key, "confname"); } if (cns_res.cc_override) { if (strcmp(cns_res.ccname, cns_res.def_ccname)) registry_string_set(key, "ccname", cns_res.ccname); else registry_value_delete(key, "ccname"); } for (i = 0 ; i < FILE_MENU_MAX_LOGINS ; i++) if (cns_res.logins[i][0] != '\0') { sprintf(tmp, "login_%02d", i); registry_string_set(key, tmp, cns_res.logins[i]); } registry_close(key); } krb5-1.16/src/windows/cns/clock15.ico0000644000704600001450000000207613211554426017204 0ustar ghudsonlibuuid & 0( @wwwwwwwwwwwwwwwwwwwwwwwwwwwpwwwwwwwwwwwwwwwwwwww??????????????????( @ ~v~~~??????????????????krb5-1.16/src/windows/cns/password.c0000644000704600001450000001717713211554426017265 0ustar ghudsonlibuuid/* * Copyright 1994 by the Massachusetts Institute of Technology. * * For copying and distribution information, please see the file * . */ /* * functions to tweak the options dialog */ #include #include #include #include #include #include #include #include #include #include "cns.h" /* * Function: Changes the password. * * Parameters: * hwnd - the current window from which command was invoked. * * name - name of user to change password for * * instance - instance of user to change password for * * realm - realm in which to change password * * oldpw - the old password * * newpw - the new password to change to * * Returns: TRUE if change took place, FALSE otherwise. */ BOOL change_password(HWND hwnd, char *name, char *instance, char *realm, char *oldpw, char *newpw) { #ifdef KRB4 des_cblock new_key; char *ret_st; int krc; char *p; CREDENTIALS *c; int ncred; char pname[ANAME_SZ]; char pinstance[INST_SZ]; push_credentials(&c, pname, pinstance, &ncred); krc = krb_get_pw_in_tkt(name, instance, realm, PWSERV_NAME, KADM_SINST, 1, oldpw); if (krc != KSUCCESS) { if (krc == INTK_BADPW) p = "Old password is incorrect"; else p = krb_get_err_text(krc); pop_credentials(c, pname, pinstance, ncred); MessageBox(hwnd, p, "", MB_OK | MB_ICONEXCLAMATION); return FALSE; } krc = kadm_init_link(PWSERV_NAME, KRB_MASTER, realm); if (krc != KSUCCESS) { pop_credentials(c, pname, pinstance, ncred); MessageBox(hwnd, kadm_get_err_text(krc), "", MB_OK | MB_ICONEXCLAMATION); return FALSE; } des_string_to_key(newpw, new_key); krc = kadm_change_pw2(new_key, newpw, &ret_st); pop_credentials(c, pname, pinstance, ncred); if (ret_st != NULL) free(ret_st); if (krc != KSUCCESS) { MessageBox(hwnd, kadm_get_err_text(krc), "", MB_OK | MB_ICONEXCLAMATION); return FALSE; } return TRUE; #endif /* KRB4 */ #ifdef KRB5 char *msg; /* Message string */ krb5_error_code code; /* Return value */ code = k5_change_password(hwnd, k5_context, name, realm, oldpw, newpw, &msg); if (code == KRB5KRB_AP_ERR_BAD_INTEGRITY) MessageBox(NULL, "Password incorrect", NULL, MB_ICONEXCLAMATION); else if (code == -1) MessageBox(NULL, (msg ? msg : "Cannot change password"), NULL, MB_ICONEXCLAMATION); else if (code != 0) com_err(NULL, code, (msg ? msg : "while changing password.")); else MessageBox(NULL, (msg ? msg : "Password changed"), "Kerberos", MB_OK | MB_APPLMODAL); return (code == 0); #endif /* KRB5 */ } /* * Function: Process WM_COMMAND messages for the password dialog. */ void password_command(HWND hwnd, int cid, HWND hwndCtl, UINT codeNotify) { char name[ANAME_SZ]; char instance[INST_SZ]; char realm[REALM_SZ]; char oldpw[MAX_KPW_LEN]; char newpw1[MAX_KPW_LEN]; char newpw2[MAX_KPW_LEN]; HCURSOR hcursor; BOOL b; int id; if (codeNotify != BN_CLICKED) { GetDlgItemText(hwnd, IDD_PASSWORD_NAME, name, sizeof(name)); trim(name); GetDlgItemText(hwnd, IDD_PASSWORD_REALM, realm, sizeof(realm)); trim(realm); GetDlgItemText(hwnd, IDD_OLD_PASSWORD, oldpw, sizeof(oldpw)); GetDlgItemText(hwnd, IDD_NEW_PASSWORD1, newpw1, sizeof(newpw1)); GetDlgItemText(hwnd, IDD_NEW_PASSWORD2, newpw2, sizeof(newpw2)); b = strlen(name) && strlen(realm) && strlen(oldpw) && strlen(newpw1) && strlen(newpw2); EnableWindow(GetDlgItem(hwnd, IDOK), b); id = (b) ? IDOK : IDD_PASSWORD_CR; SendMessage(hwnd, DM_SETDEFID, id, 0); return; /* FALSE */ } switch (cid) { case IDOK: if (isblocking) return; /* TRUE */ GetDlgItemText(hwnd, IDD_PASSWORD_NAME, name, sizeof(name)); trim(name); GetDlgItemText(hwnd, IDD_PASSWORD_INSTANCE, instance, sizeof(instance)); trim(instance); GetDlgItemText(hwnd, IDD_PASSWORD_REALM, realm, sizeof(realm)); trim(realm); GetDlgItemText(hwnd, IDD_OLD_PASSWORD, oldpw, sizeof(oldpw)); GetDlgItemText(hwnd, IDD_NEW_PASSWORD1, newpw1, sizeof(newpw1)); GetDlgItemText(hwnd, IDD_NEW_PASSWORD2, newpw2, sizeof(newpw2)); if (strcmp(newpw1, newpw2) != 0) { MessageBox(hwnd, "The two passwords you entered don't match!", "", MB_OK | MB_ICONEXCLAMATION); SetDlgItemText(hwnd, IDD_NEW_PASSWORD1, ""); SetDlgItemText(hwnd, IDD_NEW_PASSWORD2, ""); PostMessage(hwnd, WM_NEXTDLGCTL, (WPARAM)GetDlgItem(hwnd, IDD_NEW_PASSWORD1), MAKELONG(1, 0)); return; /* TRUE */ } hcursor = SetCursor(LoadCursor(NULL, IDC_WAIT)); start_blocking_hook(BLOCK_MAX_SEC); if (change_password(hwnd, name, instance, realm, oldpw, newpw1)) EndDialog(hwnd, IDOK); else PostMessage(hwnd, WM_NEXTDLGCTL, (WPARAM)GetDlgItem(hwnd, IDD_OLD_PASSWORD), MAKELONG(1, 0)); end_blocking_hook(); SetCursor(hcursor); return; /* TRUE */ case IDCANCEL: if (isblocking) WSACancelBlockingCall(); EndDialog(hwnd, IDCANCEL); return; /* TRUE */ case IDD_PASSWORD_CR: id = GetDlgCtrlID(GetFocus()); assert(id != 0); if (id == IDD_NEW_PASSWORD2) PostMessage(hwnd, WM_NEXTDLGCTL, (WPARAM)GetDlgItem(hwnd, IDD_PASSWORD_NAME), MAKELONG(1, 0)); else PostMessage(hwnd, WM_NEXTDLGCTL, 0, 0); return; /* TRUE */ } return; /* FALSE */ } /* * Function: Process WM_INITDIALOG messages for the password dialog. * Set up all initial dialog values from the parent dialog. * * Returns: TRUE if we didn't set the focus here, * FALSE if we did. */ BOOL password_initdialog(HWND hwnd, HWND hwndFocus, LPARAM lParam) { char name[ANAME_SZ]; char realm[REALM_SZ]; HWND hwndparent; int id; #ifdef KRB4 char instance[INST_SZ]; #endif center_dialog(hwnd); set_dialog_font(hwnd, hfontdialog); hwndparent = GetParent(hwnd); assert(hwndparent != NULL); GetDlgItemText(hwndparent, IDD_LOGIN_NAME, name, sizeof(name)); trim(name); SetDlgItemText(hwnd, IDD_PASSWORD_NAME, name); #ifdef KRB4 GetDlgItemText(hwndparent, IDD_LOGIN_INSTANCE, instance, sizeof(instance)); trim(instance); SetDlgItemText(hwnd, IDD_PASSWORD_INSTANCE, instance); #endif GetDlgItemText(hwndparent, IDD_LOGIN_REALM, realm, sizeof(realm)); trim(realm); SetDlgItemText(hwnd, IDD_PASSWORD_REALM, realm); if (strlen(name) == 0) id = IDD_PASSWORD_NAME; else if (strlen(realm) == 0) id = IDD_PASSWORD_REALM; else id = IDD_OLD_PASSWORD; SetFocus(GetDlgItem(hwnd, id)); return FALSE; } /* * Function: Process dialog specific messages for the password dialog. */ BOOL CALLBACK password_dlg_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { switch (message) { HANDLE_MSG(hwnd, WM_INITDIALOG, password_initdialog); HANDLE_MSG(hwnd, WM_COMMAND, password_command); case WM_SETCURSOR: if (isblocking) { SetCursor(LoadCursor(NULL, IDC_WAIT)); SetWindowLongPtr(hwnd, DWLP_MSGRESULT, TRUE); return TRUE; } break; } return FALSE; } /* * Function: Display and process the password dialog. * * Parameters: * hwnd - the parent window for the dialog * * Returns: TRUE if the dialog completed successfully, FALSE otherwise. */ BOOL password_dialog(HWND hwnd) { DLGPROC dlgproc; int rc; #ifdef _WIN32 dlgproc = password_dlg_proc; #else dlgproc = (FARPROC)MakeProcInstance(password_dlg_proc, hinstance); assert(dlgproc != NULL); if (dlgproc == NULL) return FALSE; #endif rc = DialogBox(hinstance, MAKEINTRESOURCE(ID_PASSWORD), hwnd, dlgproc); assert(rc != -1); #ifndef _WIN32 FreeProcInstance((FARPROC)dlgproc); #endif return rc == IDOK; } krb5-1.16/src/windows/cns/kpasswd.c0000644000704600001450000000410613211554426017063 0ustar ghudsonlibuuid/* * Copyright (c) 1997 Cygnus Solutions. * * Author: Michael Graff */ #include #include #include #include "krb5.h" #include "com_err.h" #include "cns.h" #include "../lib/gic.h" /* * k5_change_password * * Use the new functions to change the password. */ krb5_error_code k5_change_password(HWND hwnd, krb5_context context, char *user, char *realm, char *opasswd, char *npasswd, char **text) { krb5_error_code ret; krb5_data result_string; krb5_data result_code_string; int result_code; krb5_get_init_creds_opt opts; krb5_creds creds; krb5_principal princ; char *name; gic_data gd; *text = NULL; name = malloc(strlen(user) + strlen(realm) + 2); if (name == NULL) { *text = "Failed to allocate memory while changing password"; return 1; } sprintf(name, "%s@%s", user, realm); ret = krb5_parse_name(context, name, &princ); free(name); if (ret) { *text = "while parsing name"; return ret; } krb5_get_init_creds_opt_init(&opts); krb5_get_init_creds_opt_set_tkt_life(&opts, 5*60); krb5_get_init_creds_opt_set_renew_life(&opts, 0); krb5_get_init_creds_opt_set_forwardable(&opts, 0); krb5_get_init_creds_opt_set_proxiable(&opts, 0); gd.hinstance = hinstance; gd.hwnd = hwnd; gd.id = ID_VARDLG; ret = krb5_get_init_creds_password(context, &creds, princ, opasswd, gic_prompter, &gd, 0, "kadmin/changepw", &opts); if (ret) { *text = "while getting creds"; return ret; } ret = krb5_change_password(context, &creds, npasswd, &result_code, &result_code_string, &result_string); if (ret) { *text = "while changing password"; return ret; } if (result_code) { *text = malloc(result_code_string.length + result_string.length + 3); if (*text == NULL) return -1; sprintf(*text, "%.*s%s%.*s", result_code_string.length, result_code_string.data, (result_string.length ? ": " : ""), result_string.length, result_string.data ? result_string.data : ""); } return 0; } krb5-1.16/src/windows/cns/cns-help.hlp0000644000704600001450000002725013211554426017466 0ustar ghudsonlibuuid?_`.()*,.aadditional@adminadareasauthenticabebleepBLEEPboxbuttycachecaseCASEC.erchangeclickCOMConfigurD containstZ scredbalsdaffodildeletibesDistEudom<e ncryp"xpirefileFfollowi ngforwa(rdaF pfromhaveHelphostIfinin.m Ptall I n ce `cesisjoeuserKDCKerberosKeyslo/1mmaymessagemustnameNetnetworknonexdnub@ofonOps@orparticula ss7dP@prima rincipalPPs` v!geotocolvi_ReaLlmmoo otrungsedse~a-vihouldslashspecifi  ysuchthtat6TeLtT @stfilliumTro&uTQottypeununFqUPPERptsUsusuyWwherwhichwT4Wi$w$yo urself"),)..)/P:;@Aco`mcopyi!firstgetInitNnewn2nlyorgBssign#heswisToupusewhenwithYour/&;)z4 o |CONTEXT1&|CTXOMAPb|FONT|KWBTREE|KWDATAm|KWMAP|PhrImage|PhrIndexB|SYSTEM|TOPIC|TTLBTREEtTcJH "E5 HjẢ͈wwD5֠،ȔY<&4D6Fc$s "3D1"#3C!3l!2 Kerb*NetBrowseButtons()Zmainmain  RI 2>1>8 _ 8R7vA }|| `-}`:K0&P8NZ+TopicsCavailable#:brP/t Op ForBZ#Press F1:>3143-i`i[ ӂn>@ r. P|? QѬX`pt#usingPt/ho($ ` -0 Kupper-caseU*P)0Y=@!P0O #LoginS".> @+Delete AlsoKattemp tcautomaticallyHany;Pexis* a3K dhQ@Yq1XN.`ChangeEГ#brfC+dialog #Enterrp1n1b8d1OTypeoldXa0Oldnq#twice once 'NewF #boxe0;pro:+filled`Q OK!You@ aBN3ooHns*Csc!L ,"1 "\-i 1~q='>wSP'P/`F$]Dc++0z cconfigur!`onJ3M"Kcredent&(ҠJ+)G $#al ert3poppHits+window3b$ee  ^,H#L@ 8RO4a1ca/-0 .""["hcate#giv 3ini t ."lFtus5P@Cutil=es2[trpansa c@donec pargly C#'tX#worry1abouirKmanagem3How ever~(+noe O(NozKPrivileg_DhjH few3m inute#wh.[#camore;@ordinagood/3s>#hoursIRda@Cdepen4g3kinst "'7policy^##$inLss3e xt;]beyondtime(imit;!XkreޱtU9a1a? TermsX @ NgmRS w"C"C"+!^ty{ 2k\SO3recekqC46re5t\"@ , $O~ 0h 0-(plSoDDX5!j" .#Thos%'? k;req,ui$Smi-!s0Xagn PB !n2[Kcomp;se͜Vn$' | @)SP a@1\").hb|runs@ie,#(>"|@ ;X;h "03whe17<#fubar(<>+60*s4+ 1 * % $au 2 2]t S| v!ֱ +s[ :&C J ~A`+mey#4 1 e *%&Рpe1 0 ߖV D w1$1*i r,'P($41Ntf*e%(fJ1{'6Jhur Ctqu]f& ~ Mhost jb 0Fuj)u mF+  Y3spec$vF\6sfu-~Ptname%41t*% "Ӯ1Rx+kad  D 8 56F;i`netDVlaolrA#af"@"gK7&610 t4L,0%!1<":\&1 &@f2 X%C@CWYO&@0zb&bI&@wlk+ u+X@.1X1 HHelvSymbol UL???/&;)F24authenticateauthenticationbugscns cns 5ContentsinstanceKerb*NetKerberos Kerberos 5$Kerberos Terms(Kerberos Tickets,primary0principal4realm8ticket<troubleshooting@Troubleshooting Kerb*Net for WindowsDUsing Kerb*Net for WindowsH/&;)Lz  ContentsUsing Kerb*Net for WindowsKerberos TicketsKerberos Terms?Troubleshooting Kerb*Net for WindowsGKerberos ticketKerberos primaryKerberos InstanceKerberos RealmKerberos Configuration FileXForwardable Tickets&Key Distribution Center (KDC)/&;)L4  ѬX-}n>G}||:K0?r.|?F]DX 1h8R7v='wQ&.߬.krb5-1.16/src/windows/cns/krb5.def0000644000704600001450000000036613211554426016572 0ustar ghudsonlibuuidNAME KRB5 DESCRIPTION 'KRB5 - Credentials Manager' EXETYPE WINDOWS STUB 'WINSTUB.EXE' SEGMENTS _TEXT CLASS 'CODE' PRELOAD CODE DISCARDABLE DATA PRELOAD MULTIPLE MOVEABLE HEAPSIZE 20480 STACKSIZE 20480 krb5-1.16/src/windows/cns/clock35.ico0000644000704600001450000000207613211554426017206 0ustar ghudsonlibuuid & 0( @wwwwwwwwwwpwwwpwwwwwpwwwwwwwwwwwwwwwwwwww??????????????????( @~z~v~~??????????????????krb5-1.16/src/windows/cns/cns.c0000644000704600001450000013661513211554426016205 0ustar ghudsonlibuuid/* windows/cns/cns.c */ /* * Copyright 1994 by the Massachusetts Institute of Technology. * * For copying and distribution information, please see the file * . */ /* * Main routine of the Kerberos user interface. Also handles * all dialog level management functions. */ #include #include #include #include #include #include #include #include #include #include "cns.h" #include "tktlist.h" #include "cns_reg.h" #include "../lib/gic.h" enum { /* Actions after login */ LOGIN_AND_EXIT, LOGIN_AND_MINIMIZE, LOGIN_AND_RUN, }; /* * Globals */ static HICON kwin_icons[MAX_ICONS]; /* Icons depicting time */ HFONT hfontdialog = NULL; /* Font in which the dialog is drawn. */ static HFONT hfonticon = NULL; /* Font for icon label */ HINSTANCE hinstance; static int dlgncmdshow; /* ncmdshow from WinMain */ #if 0 static UINT wm_kerberos_changed; /* message for cache changing */ #endif static int action; /* After login actions */ static UINT kwin_timer_id; /* Timer being used for update */ BOOL alert; /* Actions on ticket expiration */ BOOL beep; static BOOL alerted; /* TRUE when user already alerted */ BOOL isblocking = FALSE; /* TRUE when blocked in WinSock */ static DWORD blocking_end_time; /* Ending count for blocking timeout */ static FARPROC hook_instance; /* handle for blocking hook function */ char confname[FILENAME_MAX]; /* krb5.conf (or krb.conf for krb4) */ #ifdef KRB5 char ccname[FILENAME_MAX]; /* ccache file location */ BOOL forwardable; /* TRUE to get forwardable tickets */ BOOL noaddresses; krb5_context k5_context; krb5_ccache k5_ccache; #endif /* * Function: Called during blocking operations. Implement a timeout * if nothing occurs within the specified time, cancel the blocking * operation. Also permit the user to press escape in order to * cancel the blocking operation. * * Returns: TRUE if we got and dispatched a message, FALSE otherwise. */ BOOL CALLBACK blocking_hook_proc(void) { MSG msg; BOOL rc; if (GetTickCount() > blocking_end_time) { WSACancelBlockingCall(); return FALSE; } rc = (BOOL)PeekMessage(&msg, NULL, 0, 0, PM_REMOVE); if (!rc) return FALSE; if (msg.message == WM_KEYDOWN && msg.wParam == VK_ESCAPE) { WSACancelBlockingCall(); blocking_end_time = msg.time - 1; return FALSE; } TranslateMessage(&msg); DispatchMessage(&msg); return TRUE; } /* * Function: Set up a blocking hook function. * * Parameters: * timeout - # of seconds to block for before cancelling. */ void start_blocking_hook(int timeout) { FARPROC proc; if (isblocking) return; isblocking = TRUE; blocking_end_time = GetTickCount() + (1000 * timeout); #ifdef _WIN32 proc = WSASetBlockingHook(blocking_hook_proc); #else hook_instance = MakeProcInstance(blocking_hook_proc, hinstance); proc = WSASetBlockingHook(hook_instance); #endif assert(proc != NULL); } /* * Function: End the blocking hook fuction set up above. */ void end_blocking_hook(void) { #ifndef _WIN32 FreeProcInstance(hook_instance); #endif WSAUnhookBlockingHook(); isblocking = FALSE; } /* * Function: Centers the specified window on the screen. * * Parameters: * hwnd - the window to center on the screen. */ void center_dialog(HWND hwnd) { int scrwidth, scrheight; int dlgwidth, dlgheight; RECT r; HDC hdc; if (hwnd == NULL) return; GetWindowRect(hwnd, &r); dlgwidth = r.right - r.left; dlgheight = r.bottom - r.top ; hdc = GetDC(NULL); scrwidth = GetDeviceCaps(hdc, HORZRES); scrheight = GetDeviceCaps(hdc, VERTRES); ReleaseDC(NULL, hdc); r.left = (scrwidth - dlgwidth) / 2; r.top = (scrheight - dlgheight) / 2; MoveWindow(hwnd, r.left, r.top, dlgwidth, dlgheight, TRUE); } /* * Function: Positions the kwin dialog either to the saved location * or the center of the screen if no saved location. * * Parameters: * hwnd - the window to center on the screen. */ static void position_dialog(HWND hwnd) { int scrwidth, scrheight; HDC hdc; int x, y, cx, cy; if (hwnd == NULL) return; hdc = GetDC(NULL); scrwidth = GetDeviceCaps(hdc, HORZRES); scrheight = GetDeviceCaps(hdc, VERTRES); ReleaseDC(NULL, hdc); x = cns_res.x; y = cns_res.y; cx = cns_res.cx; cy = cns_res.cy; if (x > scrwidth || y > scrheight || x + cx <= 0 || y + cy <= 0) center_dialog(hwnd); else MoveWindow(hwnd, x, y, cx, cy, TRUE); } /* * Function: Set font of all dialog items. * * Parameters: * hwnd - the dialog to set the font of */ void set_dialog_font(HWND hwnd, HFONT hfont) { hwnd = GetWindow(hwnd, GW_CHILD); while (hwnd != NULL) { SetWindowFont(hwnd, hfont, 0); hwnd = GetWindow(hwnd, GW_HWNDNEXT); } } /* * Function: Trim leading and trailing white space from a string. * * Parameters: * s - the string to trim. */ void trim(char *s) { int l; int i; for (i = 0 ; s[i] ; i++) if (s[i] != ' ' && s[i] != '\t') break; l = strlen(&s[i]); memmove(s, &s[i], l + 1); for (l--; l >= 0; l--) { if (s[l] != ' ' && s[l] != '\t') break; } s[l + 1] = 0; } /* * Function: This routine figures out the current time epoch and * returns the conversion factor. It exists because Microloss * screwed the pooch on the time() and _ftime() calls in its release * 7.0 libraries. They changed the epoch to Dec 31, 1899! */ time_t kwin_get_epoch(void) { static struct tm jan_1_70 = {0, 0, 0, 1, 0, 70}; time_t epoch = 0; epoch = -mktime(&jan_1_70); /* Seconds til 1970 localtime */ epoch += _timezone; /* Seconds til 1970 GMT */ return epoch; } /* * Function: Save the credentials for later restoration. * * Parameters: * c - Returned pointer to saved credential cache. * * pname - Returned as principal name of session. * * pinstance - Returned as principal instance of session. * * ncred - Returned number of credentials saved. */ static void push_credentials(CREDENTIALS **cp, char *pname, char *pinstance, int *ncred) { #ifdef KRB4 int i; char service[ANAME_SZ]; char instance[INST_SZ]; char realm[REALM_SZ]; CREDENTIALS *c; if (krb_get_tf_fullname(NULL, pname, pinstance, NULL) != KSUCCESS) { pname[0] = 0; pinstance[0] = 0; } *ncred = krb_get_num_cred(); if (*ncred <= 0) return; c= malloc(*ncred * sizeof(CREDENTIALS)); assert(c != NULL); if (c == NULL) { *ncred = 0; return; } for (i = 0; i < *ncred; i++) { krb_get_nth_cred(service, instance, realm, i + 1); krb_get_cred(service, instance, realm, &c[i]); } *cp = c; #endif #ifdef KRB5 /* FIXME */ return; #endif } /* * Function: Restore the saved credentials. * * c - Pointer to saved credential cache. * * pname - Principal name of session. * * pinstance - Principal instance of session. * * ncred - Number of credentials saved. */ static void pop_credentials(CREDENTIALS *c, char *pname, char *pinstance, int ncred) { #ifdef KRB4 int i; if (pname[0]) in_tkt(pname, pinstance); else dest_tkt(); if (ncred <= 0) return; for (i = 0; i < ncred; i++) { krb_save_credentials(c[i].service, c[i].instance, c[i].realm, c[i].session, c[i].lifetime, c[i].kvno, &(c[i].ticket_st), c[i].issue_date); } free(c); #endif #ifdef KRB5 /* FIXME */ return; #endif } /* * Function: Save most recent login triplets for placement on the * bottom of the file menu. * * Parameters: * hwnd - the handle of the window containing the menu to edit. * * name - A login name to save in the recent login list * * instance - An instance to save in the recent login list * * realm - A realm to save in the recent login list */ static void kwin_push_login(HWND hwnd, char *name, char *instance, char *realm) { HMENU hmenu; int i; int id; int ctitems; char fullname[MAX_K_NAME_SZ + 3]; char menuitem[MAX_K_NAME_SZ + 3]; BOOL rc; fullname[sizeof(fullname) - 1] = '\0'; strncpy(fullname, "&x ", sizeof(fullname) - 1); strncat(fullname, name, sizeof(fullname) - 1 - strlen(fullname)); strncat(fullname, ".", sizeof(fullname) - 1 - strlen(fullname)); strncat(fullname, instance, sizeof(fullname) - 1 - strlen(fullname)); strncat(fullname, "@", sizeof(fullname) - 1 - strlen(fullname)); strncat(fullname, realm, sizeof(fullname) - 1 - strlen(fullname)); hmenu = GetMenu(hwnd); assert(hmenu != NULL); hmenu = GetSubMenu(hmenu, 0); assert(hmenu != NULL); ctitems = GetMenuItemCount(hmenu); assert(ctitems >= FILE_MENU_ITEMS); if (ctitems == FILE_MENU_ITEMS) { rc = AppendMenu(hmenu, MF_SEPARATOR, 0, NULL); assert(rc); ctitems++; } for (i = FILE_MENU_ITEMS + 1; i < ctitems; i++) { GetMenuString(hmenu, i, menuitem, sizeof(menuitem), MF_BYPOSITION); if (strcmp(&fullname[3], &menuitem[3]) == 0) { rc = RemoveMenu(hmenu, i, MF_BYPOSITION); assert(rc); ctitems--; break; } } rc = InsertMenu(hmenu, FILE_MENU_ITEMS + 1, MF_BYPOSITION, 1, fullname); assert(rc); ctitems++; if (ctitems - FILE_MENU_ITEMS - 1 > FILE_MENU_MAX_LOGINS) { RemoveMenu(hmenu, ctitems - 1, MF_BYPOSITION); ctitems--; } id = 0; for (i = FILE_MENU_ITEMS + 1; i < ctitems; i++) { GetMenuString(hmenu, i, menuitem, sizeof(menuitem), MF_BYPOSITION); rc = RemoveMenu(hmenu, i, MF_BYPOSITION); assert(rc); menuitem[1] = '1' + id; rc = InsertMenu(hmenu, i, MF_BYPOSITION, IDM_FIRST_LOGIN + id, menuitem); assert(rc); id++; } } /* * Function: Initialize the logins on the file menu form the KERBEROS.INI * file. * * Parameters: * hwnd - handle of the dialog containing the file menu. */ static void kwin_init_file_menu(HWND hwnd) { HMENU hmenu; int i; char menuitem[MAX_K_NAME_SZ + 3]; int id; BOOL rc; hmenu = GetMenu(hwnd); assert(hmenu != NULL); hmenu = GetSubMenu(hmenu, 0); assert(hmenu != NULL); id = 0; for (i = 0; i < FILE_MENU_MAX_LOGINS; i++) { strcpy(menuitem + 3, cns_res.logins[i]); if (!menuitem[3]) continue; menuitem[0] = '&'; menuitem[1] = '1' + id; menuitem[2] = ' '; if (id == 0) { rc = AppendMenu(hmenu, MF_SEPARATOR, 0, NULL); assert(rc); } AppendMenu(hmenu, MF_STRING, IDM_FIRST_LOGIN + id, menuitem); id++; } } /* * Function: Save the items on the file menu in the KERBEROS.INI file. * * Parameters: * hwnd - handle of the dialog containing the file menu. */ static void kwin_save_file_menu(HWND hwnd) { HMENU hmenu; int i; int id; int ctitems; char menuitem[MAX_K_NAME_SZ + 3]; hmenu = GetMenu(hwnd); assert(hmenu != NULL); hmenu = GetSubMenu(hmenu, 0); assert(hmenu != NULL); ctitems = GetMenuItemCount(hmenu); assert(ctitems >= FILE_MENU_ITEMS); id = 0; for (i = FILE_MENU_ITEMS + 1; i < ctitems; i++) { GetMenuString(hmenu, i, menuitem, sizeof(menuitem), MF_BYPOSITION); strcpy(cns_res.logins[id], menuitem + 3); id++; } } /* * Function: Given an expiration time, choose an appropriate * icon to display. * * Parameters: * expiration time of expiration in time() compatible units * * Returns: Handle of icon to display */ HICON kwin_get_icon(time_t expiration) { int ixicon; time_t dt; dt = expiration - time(NULL); dt = dt / 60; /* convert to minutes */ if (dt <= 0) ixicon = IDI_EXPIRED - IDI_FIRST_CLOCK; else if (dt > 60) ixicon = IDI_TICKET - IDI_FIRST_CLOCK; else ixicon = (int)(dt / 5); return kwin_icons[ixicon]; } /* * Function: Intialize name fields in the Kerberos dialog. * * Parameters: * hwnd - the window recieving the message. * * fullname - the full kerberos name to initialize with */ void kwin_init_name(HWND hwnd, char *fullname) { char name[ANAME_SZ]; char instance[INST_SZ]; char realm[REALM_SZ]; int krc; #ifdef KRB5 krb5_error_code code; char *ptr; #endif if (fullname == NULL || fullname[0] == 0) { #ifdef KRB4 strcpy(name, krb_get_default_user()); strcpy(instance, cns_res.instance); krc = krb_get_lrealm(realm, 1); if (krc != KSUCCESS) realm[0] = 0; strcpy(realm, cns_res.realm); #endif /* KRB4 */ #ifdef KRB5 strcpy(name, cns_res.name); *realm = '\0'; code = krb5_get_default_realm(k5_context, &ptr); if (!code) { strcpy(realm, ptr); /* free(ptr); XXX */ } strcpy(realm, cns_res.realm); #endif /* KRB5 */ } else { #ifdef KRB4 kname_parse(name, instance, realm, fullname); SetDlgItemText(hwnd, IDD_LOGIN_INSTANCE, instance); #endif #ifdef KRB5 krc = k5_kname_parse(name, realm, fullname); *instance = '\0'; #endif } SetDlgItemText(hwnd, IDD_LOGIN_NAME, name); SetDlgItemText(hwnd, IDD_LOGIN_REALM, realm); } /* * Function: Set the focus to the name control if no name * exists, the realm control if no realm exists or the * password control. Uses PostMessage not SetFocus. * * Parameters: * hwnd - the Window handle of the parent. */ void kwin_set_default_focus(HWND hwnd) { char name[ANAME_SZ]; char realm[REALM_SZ]; HWND hwnditem; GetDlgItemText(hwnd, IDD_LOGIN_NAME, name, sizeof(name)); trim(name); if (strlen(name) <= 0) hwnditem = GetDlgItem(hwnd, IDD_LOGIN_NAME); else { GetDlgItemText(hwnd, IDD_LOGIN_REALM, realm, sizeof(realm)); trim(realm); if (strlen(realm) <= 0) hwnditem = GetDlgItem(hwnd, IDD_LOGIN_REALM); else hwnditem = GetDlgItem(hwnd, IDD_LOGIN_PASSWORD); } PostMessage(hwnd, WM_NEXTDLGCTL, (WPARAM)hwnditem, MAKELONG(1, 0)); } /* * Function: Save the values which live in the KERBEROS.INI file. * * Parameters: * hwnd - the window handle of the dialog containing fields to * be saved */ static void kwin_save_name(HWND hwnd) { char name[ANAME_SZ]; char instance[INST_SZ]; char realm[REALM_SZ]; GetDlgItemText(hwnd, IDD_LOGIN_NAME, name, sizeof(name)); trim(name); #ifdef KRB4 krb_set_default_user(name); GetDlgItemText(hwnd, IDD_LOGIN_INSTANCE, instance, sizeof(instance)); trim(instance); strcpy(cns_res.instance, instance); #endif #ifdef KRB5 strcpy(cns_res.name, name); *instance = '\0'; #endif GetDlgItemText(hwnd, IDD_LOGIN_REALM, realm, sizeof(realm)); trim(realm); strcpy(cns_res.realm, realm); kwin_push_login(hwnd, name, instance, realm); } /* * Function: Process WM_INITDIALOG messages. Set the fonts * for all items on the dialog and populate the ticket list. * Also set the default values for user, instance and realm. * * Returns: TRUE if we didn't set the focus here, * FALSE if we did. */ static BOOL kwin_initdialog(HWND hwnd, HWND hwndFocus, LPARAM lParam) { LOGFONT lf; HDC hdc; char name[ANAME_SZ]; position_dialog(hwnd); ticket_init_list(GetDlgItem(hwnd, IDD_TICKET_LIST)); kwin_init_file_menu(hwnd); kwin_init_name(hwnd, (char *)lParam); hdc = GetDC(NULL); assert(hdc != NULL); memset(&lf, 0, sizeof(lf)); lf.lfHeight = -MulDiv(9, GetDeviceCaps(hdc, LOGPIXELSY), 72); strcpy(lf.lfFaceName, "Arial"); hfontdialog = CreateFontIndirect(&lf); assert(hfontdialog != NULL); if (hfontdialog == NULL) { ReleaseDC(NULL, hdc); return TRUE; } lf.lfHeight = -MulDiv(8, GetDeviceCaps(hdc, LOGPIXELSY), 72); hfonticon = CreateFontIndirect(&lf); assert(hfonticon != NULL); if (hfonticon == NULL) { ReleaseDC(NULL, hdc); return TRUE; } ReleaseDC(NULL, hdc); set_dialog_font(hwnd, hfontdialog); GetDlgItemText(hwnd, IDD_LOGIN_NAME, name, sizeof(name)); trim(name); if (strlen(name) > 0) SetFocus(GetDlgItem(hwnd, IDD_LOGIN_PASSWORD)); else SetFocus(GetDlgItem(hwnd, IDD_LOGIN_NAME)); ShowWindow(hwnd, dlgncmdshow); kwin_timer_id = SetTimer(hwnd, 1, KWIN_UPDATE_PERIOD, NULL); assert(kwin_timer_id != 0); return FALSE; } /* * Function: Process WM_DESTROY messages. Delete the font * created for use by the controls. */ static void kwin_destroy(HWND hwnd) { RECT r; ticket_destroy(GetDlgItem(hwnd, IDD_TICKET_LIST)); if (hfontdialog != NULL) DeleteObject(hfontdialog); if (hfonticon != NULL) DeleteObject(hfonticon); kwin_save_file_menu(hwnd); GetWindowRect(hwnd, &r); cns_res.x = r.left; cns_res.y = r.top; cns_res.cx = r.right - r.left; cns_res.cy = r.bottom - r.top; KillTimer(hwnd, kwin_timer_id); } /* * Function: Retrievs item WindowRect in hwnd client * coordiate system. * * Parameters: * hwnditem - the item to retrieve * * item - dialog in which into which to translate * * r - rectangle returned */ static void windowrect(HWND hwnditem, HWND hwnd, RECT *r) { GetWindowRect(hwnditem, r); ScreenToClient(hwnd, (LPPOINT)&(r->left)); ScreenToClient(hwnd, (LPPOINT)&(r->right)); } /* * Function: Process WM_SIZE messages. Resize the * list and position the buttons attractively. */ static void kwin_size(HWND hwnd, UINT state, int cxdlg, int cydlg) { #define listgap 8 RECT r; RECT rdlg; int hmargin, vmargin; HWND hwnditem; int cx, cy; int i; int titlebottom; int editbottom; int listbottom; int gap; int left; int titleleft[IDD_MAX_TITLE - IDD_MIN_TITLE + 1]; if (state == SIZE_MINIMIZED) return; GetClientRect(hwnd, &rdlg); /* * The ticket list title */ hwnditem = GetDlgItem(hwnd, IDD_TICKET_LIST_TITLE); if (hwnditem == NULL) return; windowrect(hwnditem, hwnd, &r); hmargin = r.left; vmargin = r.top; cx = cxdlg - 2 * hmargin; cy = r.bottom - r.top; MoveWindow(hwnditem, r.left, r.top, cx, cy, TRUE); /* * The buttons */ cx = 0; for (i = IDD_MIN_BUTTON; i <= IDD_MAX_BUTTON; i++) { hwnditem = GetDlgItem(hwnd, i); windowrect(hwnditem, hwnd, &r); if (i == IDD_MIN_BUTTON) hmargin = r.left; cx += r.right - r.left; } gap = (cxdlg - 2 * hmargin - cx) / (IDD_MAX_BUTTON - IDD_MIN_BUTTON); left = hmargin; for (i = IDD_MIN_BUTTON; i <= IDD_MAX_BUTTON; i++) { hwnditem = GetDlgItem(hwnd, i); windowrect(hwnditem, hwnd, &r); editbottom = -r.top; cx = r.right - r.left; cy = r.bottom - r.top; r.top = rdlg.bottom - vmargin - cy; MoveWindow(hwnditem, left, r.top, cx, cy, TRUE); left += cx + gap; } /* * Edit fields: stretch boxes, keeping the gap between boxes equal to * what it was on entry. */ editbottom += r.top; hwnditem = GetDlgItem(hwnd, IDD_MIN_EDIT); windowrect(hwnditem, hwnd, &r); gap = r.right; hmargin = r.left; editbottom += r.bottom; titlebottom = -r.top; hwnditem = GetDlgItem(hwnd, IDD_MIN_EDIT + 1); windowrect(hwnditem, hwnd, &r); gap = r.left - gap; cx = cxdlg - 2 * hmargin - (IDD_MAX_EDIT - IDD_MIN_EDIT) * gap; cx = cx / (IDD_MAX_EDIT - IDD_MIN_EDIT + 1); left = hmargin; for (i = IDD_MIN_EDIT; i <= IDD_MAX_EDIT; i++) { hwnditem = GetDlgItem(hwnd, i); windowrect(hwnditem, hwnd, &r); cy = r.bottom - r.top; r.top = editbottom - cy; MoveWindow(hwnditem, left, r.top, cx, cy, TRUE); titleleft[i-IDD_MIN_EDIT] = left; left += cx + gap; } /* * Edit field titles */ titlebottom += r.top; windowrect(GetDlgItem(hwnd, IDD_MIN_TITLE), hwnd, &r); titlebottom += r.bottom; listbottom = -r.top; for (i = IDD_MIN_TITLE; i <= IDD_MAX_TITLE; i++) { hwnditem = GetDlgItem(hwnd, i); windowrect(hwnditem, hwnd, &r); cx = r.right - r.left; cy = r.bottom - r.top; r.top = titlebottom - cy; MoveWindow(hwnditem, titleleft[i-IDD_MIN_TITLE], r.top, cx, cy, TRUE); } /* * The list */ listbottom = r.top - listgap; hwnditem = GetDlgItem(hwnd, IDD_TICKET_LIST); windowrect(hwnditem, hwnd, &r); hmargin = r.left; cx = cxdlg - 2 * hmargin; cy = listbottom - r.top; MoveWindow(hwnditem, r.left, r.top, cx, cy, TRUE); } /* * Function: Process WM_GETMINMAXINFO messages */ static void kwin_getminmaxinfo(HWND hwnd, LPMINMAXINFO lpmmi) { lpmmi->ptMinTrackSize.x = (KWIN_MIN_WIDTH * LOWORD(GetDialogBaseUnits())) / 4; lpmmi->ptMinTrackSize.y = (KWIN_MIN_HEIGHT * HIWORD(GetDialogBaseUnits())) / 8; } /* * Function: Process WM_TIMER messages */ static void kwin_timer(HWND hwnd, UINT timer_id) { HWND hwndfocus; time_t t; time_t expiration; BOOL expired; #ifdef KRB4 CREDENTIALS c; int ncred; int i; char service[ANAME_SZ]; char instance[INST_SZ]; char realm[REALM_SZ]; #endif #ifdef KRB5 krb5_error_code code; krb5_cc_cursor cursor; krb5_creds cred; int n; char *s; #endif if (timer_id != 1) { FORWARD_WM_TIMER(hwnd, timer_id, DefDlgProc); return; } expired = FALSE; ticket_init_list(GetDlgItem(hwnd, IDD_TICKET_LIST)); if (alerted) { if (IsIconic(hwnd)) InvalidateRect(hwnd, NULL, TRUE); return; } #ifdef KRB4 ncred = krb_get_num_cred(); for (i = 1; i <= ncred; i++) { krb_get_nth_cred(service, instance, realm, i); if (_stricmp(service, "krbtgt") == 0) { /* Warn if ticket will expire w/i TIME_BUFFER seconds */ krb_get_cred(service, instance, realm, &c); expiration = c.issue_date + (long)c.lifetime * 5L * 60L; t = TIME_BUFFER + time(NULL); if (t >= expiration) { expired = TRUE; /* Don't alert because of stale tickets */ if (t >= expiration + KWIN_UPDATE_PERIOD / 1000) { alerted = TRUE; if (IsIconic(hwnd)) InvalidateRect(hwnd, NULL, TRUE); return; } break; } } } #endif #ifdef KRB5 code = krb5_cc_start_seq_get(k5_context, k5_ccache, &cursor); while (code == 0) { code = krb5_cc_next_cred(k5_context, k5_ccache, &cursor, &cred); if (code) break; n = krb5_princ_component(k5_context, cred.server, 0)->length; s = krb5_princ_component(k5_context, cred.server, 0)->data; if (n != KRB5_TGS_NAME_SIZE) continue; if (memcmp(KRB5_TGS_NAME, s, KRB5_TGS_NAME_SIZE)) continue; /* Warn if ticket will expire w/i TIME_BUFFER seconds */ expiration = cred.times.endtime; t = TIME_BUFFER + time(NULL); if (t >= expiration) { expired = TRUE; /* Don't alert because of stale tickets */ if (t >= expiration + KWIN_UPDATE_PERIOD / 1000) { alerted = TRUE; if (IsIconic(hwnd)) InvalidateRect(hwnd, NULL, TRUE); return; } break; } } if (code == 0 || code == KRB5_CC_END) krb5_cc_end_seq_get(k5_context, k5_ccache, &cursor); #endif if (!expired) { if (IsIconic(hwnd)) InvalidateRect(hwnd, NULL, TRUE); return; } alerted = TRUE; if (beep) MessageBeep(MB_ICONEXCLAMATION); if (alert) { if (IsIconic(hwnd)) { hwndfocus = GetFocus(); ShowWindow(hwnd, SW_RESTORE); SetWindowPos(hwnd, HWND_TOP, 0, 0, 0, 0, SWP_NOACTIVATE | SWP_SHOWWINDOW | SWP_NOMOVE | SWP_NOSIZE); SetFocus(hwndfocus); } SetWindowPos(hwnd, HWND_TOP, 0, 0, 0, 0, SWP_NOACTIVATE | SWP_SHOWWINDOW | SWP_NOMOVE | SWP_NOSIZE); return; } if (IsIconic(hwnd)) InvalidateRect(hwnd, NULL, TRUE); } /* * Function: Process WM_COMMAND messages */ static void kwin_command(HWND hwnd, int cid, HWND hwndCtl, UINT codeNotify) { char name[ANAME_SZ]; char realm[REALM_SZ]; char password[MAX_KPW_LEN]; HCURSOR hcursor; BOOL blogin; HMENU hmenu; char menuitem[MAX_K_NAME_SZ + 3]; char copyright[128]; int id; #ifdef KRB4 char instance[INST_SZ]; int lifetime; int krc; #endif #ifdef KRB5 long lifetime; krb5_error_code code; krb5_principal principal; krb5_creds creds; krb5_get_init_creds_opt opts; gic_data gd; #endif #ifdef KRB4 EnableWindow(GetDlgItem(hwnd, IDD_TICKET_DELETE), krb_get_num_cred() > 0); #endif #ifdef KRB5 EnableWindow(GetDlgItem(hwnd, IDD_TICKET_DELETE), k5_get_num_cred(1) > 0); #endif GetDlgItemText(hwnd, IDD_LOGIN_NAME, name, sizeof(name)); trim(name); blogin = strlen(name) > 0; if (blogin) { GetDlgItemText(hwnd, IDD_LOGIN_REALM, realm, sizeof(realm)); trim(realm); blogin = strlen(realm) > 0; } if (blogin) { GetDlgItemText(hwnd, IDD_LOGIN_PASSWORD, password, sizeof(password)); blogin = strlen(password) > 0; } EnableWindow(GetDlgItem(hwnd, IDD_LOGIN), blogin); id = (blogin) ? IDD_LOGIN : IDD_PASSWORD_CR2; SendMessage(hwnd, DM_SETDEFID, id, 0); if (codeNotify != BN_CLICKED && codeNotify != 0 && codeNotify != 1) return; /* FALSE */ /* * Check to see if this item is in a list of the ``recent hosts'' sort * of list, under the FILE menu. */ if (cid >= IDM_FIRST_LOGIN && cid < IDM_FIRST_LOGIN + FILE_MENU_MAX_LOGINS) { hmenu = GetMenu(hwnd); assert(hmenu != NULL); hmenu = GetSubMenu(hmenu, 0); assert(hmenu != NULL); if (!GetMenuString(hmenu, cid, menuitem, sizeof(menuitem), MF_BYCOMMAND)) return; /* TRUE */ if (menuitem[0]) kwin_init_name(hwnd, &menuitem[3]); return; /* TRUE */ } switch (cid) { case IDM_EXIT: if (isblocking) WSACancelBlockingCall(); WinHelp(hwnd, KERBEROS_HLP, HELP_QUIT, 0); PostQuitMessage(0); return; /* TRUE */ case IDD_PASSWORD_CR2: /* Make CR == TAB */ id = GetDlgCtrlID(GetFocus()); assert(id != 0); if (id == IDD_MAX_EDIT) PostMessage(hwnd, WM_NEXTDLGCTL, (WPARAM)GetDlgItem(hwnd, IDD_MIN_EDIT), MAKELONG(1, 0)); else PostMessage(hwnd, WM_NEXTDLGCTL, 0, 0); return; /* TRUE */ case IDD_LOGIN: if (isblocking) return; /* TRUE */ GetDlgItemText(hwnd, IDD_LOGIN_NAME, name, sizeof(name)); trim(name); GetDlgItemText(hwnd, IDD_LOGIN_REALM, realm, sizeof(realm)); trim(realm); GetDlgItemText(hwnd, IDD_LOGIN_PASSWORD, password, sizeof(password)); SetDlgItemText(hwnd, IDD_LOGIN_PASSWORD, ""); /* nuke the password */ trim(password); #ifdef KRB4 GetDlgItemText(hwnd, IDD_LOGIN_INSTANCE, instance, sizeof(instance)); trim(instance); #endif hcursor = SetCursor(LoadCursor(NULL, IDC_WAIT)); lifetime = cns_res.lifetime; start_blocking_hook(BLOCK_MAX_SEC); #ifdef KRB4 lifetime = (lifetime + 4) / 5; krc = krb_get_pw_in_tkt(name, instance, realm, "krbtgt", realm, lifetime, password); #endif #ifdef KRB5 principal = NULL; /* * convert the name + realm into a krb5 principal string and parse it into a principal */ sprintf(menuitem, "%s@%s", name, realm); code = krb5_parse_name(k5_context, menuitem, &principal); if (code) goto errorpoint; /* * set the various ticket options. First, initialize the structure, then set the ticket * to be forwardable if desired, and set the lifetime. */ krb5_get_init_creds_opt_init(&opts); krb5_get_init_creds_opt_set_forwardable(&opts, forwardable); krb5_get_init_creds_opt_set_tkt_life(&opts, lifetime * 60); if (noaddresses) { krb5_get_init_creds_opt_set_address_list(&opts, NULL); } /* * get the initial creds using the password and the options we set above */ gd.hinstance = hinstance; gd.hwnd = hwnd; gd.id = ID_VARDLG; code = krb5_get_init_creds_password(k5_context, &creds, principal, password, gic_prompter, &gd, 0, NULL, &opts); if (code) goto errorpoint; /* * initialize the credential cache */ code = krb5_cc_initialize(k5_context, k5_ccache, principal); if (code) goto errorpoint; /* * insert the principal into the cache */ code = krb5_cc_store_cred(k5_context, k5_ccache, &creds); errorpoint: if (principal) krb5_free_principal(k5_context, principal); end_blocking_hook(); SetCursor(hcursor); kwin_set_default_focus(hwnd); if (code) { if (code == KRB5KRB_AP_ERR_BAD_INTEGRITY) MessageBox(hwnd, "Password incorrect", NULL, MB_OK | MB_ICONEXCLAMATION); else com_err(NULL, code, "while logging in"); } #endif /* KRB5 */ #ifdef KRB4 if (krc != KSUCCESS) { MessageBox(hwnd, krb_get_err_text(krc), "", MB_OK | MB_ICONEXCLAMATION); return; /* TRUE */ } #endif kwin_save_name(hwnd); alerted = FALSE; switch (action) { case LOGIN_AND_EXIT: SendMessage(hwnd, WM_COMMAND, GET_WM_COMMAND_MPS(IDM_EXIT, 0, 0)); break; case LOGIN_AND_MINIMIZE: ShowWindow(hwnd, SW_MINIMIZE); break; } return; /* TRUE */ case IDD_TICKET_DELETE: if (isblocking) return; /* TRUE */ #ifdef KRB4 krc = dest_tkt(); if (krc != KSUCCESS) MessageBox(hwnd, krb_get_err_text(krc), "", MB_OK | MB_ICONEXCLAMATION); #endif #ifdef KRB5 code = k5_dest_tkt(); #endif kwin_set_default_focus(hwnd); alerted = FALSE; return; /* TRUE */ case IDD_CHANGE_PASSWORD: if (isblocking) return; /* TRUE */ password_dialog(hwnd); kwin_set_default_focus(hwnd); return; /* TRUE */ case IDM_OPTIONS: if (isblocking) return; /* TRUE */ opts_dialog(hwnd); return; /* TRUE */ case IDM_HELP_INDEX: WinHelp(hwnd, KERBEROS_HLP, HELP_INDEX, 0); return; /* TRUE */ case IDM_ABOUT: ticket_init_list(GetDlgItem(hwnd, IDD_TICKET_LIST)); if (isblocking) return; /* TRUE */ #ifdef KRB4 strcpy(copyright, " Kerberos 4 for Windows "); #endif #ifdef KRB5 strcpy(copyright, " Kerberos V5 for Windows "); #endif #ifdef _WIN32 strncat(copyright, "32-bit\n", sizeof(copyright) - 1 - strlen(copyright)); #else strncat(copyright, "16-bit\n", sizeof(copyright) - 1 - strlen(copyright)); #endif strncat(copyright, "\n Version 1.12\n\n", sizeof(copyright) - 1 - strlen(copyright)); #ifdef ORGANIZATION strncat(copyright, " For information, contact:\n", sizeof(copyright) - 1 - strlen(copyright)); strncat(copyright, ORGANIZATION, sizeof(copyright) - 1 - strlen(copyright)); #endif MessageBox(hwnd, copyright, KWIN_DIALOG_NAME, MB_OK); return; /* TRUE */ } return; /* FALSE */ } /* * Function: Process WM_SYSCOMMAND messages by setting * the focus to the password or name on restore. */ static void kwin_syscommand(HWND hwnd, UINT cmd, int x, int y) { if (cmd == SC_RESTORE) kwin_set_default_focus(hwnd); if (cmd == SC_CLOSE) { SendMessage(hwnd, WM_COMMAND, GET_WM_COMMAND_MPS(IDM_EXIT, 0, 0)); return; } FORWARD_WM_SYSCOMMAND(hwnd, cmd, x, y, DefDlgProc); } /* * Function: Process WM_PAINT messages by displaying an * informative icon when we are iconic. */ static void kwin_paint(HWND hwnd) { HDC hdc; PAINTSTRUCT ps; HICON hicon; time_t expiration = 0; time_t dt; char buf[20]; RECT r; #ifdef KRB4 int i; int ncred; char service[ANAME_SZ]; char instance[INST_SZ]; char realm[REALM_SZ]; CREDENTIALS c; #endif #ifdef KRB5 krb5_error_code code; krb5_cc_cursor cursor; krb5_creds c; int n; char *service; #endif if (!IsIconic(hwnd)) { FORWARD_WM_PAINT(hwnd, DefDlgProc); return; } #ifdef KRB4 ncred = krb_get_num_cred(); for (i = 1; i <= ncred; i++) { krb_get_nth_cred(service, instance, realm, i); krb_get_cred(service, instance, realm, &c); if (_stricmp(c.service, "krbtgt") == 0) { expiration = c.issue_date - kwin_get_epoch() + (long)c.lifetime * 5L * 60L; break; } } #endif #ifdef KRB5 code = krb5_cc_start_seq_get(k5_context, k5_ccache, &cursor); while (code == 0) { code = krb5_cc_next_cred(k5_context, k5_ccache, &cursor, &c); if (code) break; n = krb5_princ_component(k5_context, c.server, 0)->length; service = krb5_princ_component(k5_context, c.server, 0)->data; if (n != KRB5_TGS_NAME_SIZE) continue; if (memcmp(KRB5_TGS_NAME, service, KRB5_TGS_NAME_SIZE)) continue; expiration = c.times.endtime; break; } if (code == 0 || code == KRB5_CC_END) krb5_cc_end_seq_get(k5_context, k5_ccache, &cursor); #endif hdc = BeginPaint(hwnd, &ps); GetClientRect(hwnd, &r); DefWindowProc(hwnd, WM_ICONERASEBKGND, (WPARAM)hdc, 0); if (expiration == 0) { strcpy(buf, KWIN_DIALOG_NAME); hicon = LoadIcon(hinstance, MAKEINTRESOURCE(IDI_KWIN)); } else { hicon = kwin_get_icon(expiration); dt = (expiration - time(NULL)) / 60; if (dt <= 0) sprintf(buf, "%s - %s", KWIN_DIALOG_NAME, "Expired"); else if (dt < 60) { dt %= 60; sprintf(buf, "%s - %ld min", KWIN_DIALOG_NAME, dt); } else { dt /= 60; sprintf(buf, "%s - %ld hr", KWIN_DIALOG_NAME, dt); } buf[sizeof(buf) - 1] = '\0'; if (dt > 1) strncat(buf, "s", sizeof(buf) - 1 - strlen(buf)); } DrawIcon(hdc, r.left, r.top, hicon); EndPaint(hwnd, &ps); SetWindowText(hwnd, buf); } /* * Function: Window procedure for the Kerberos control panel dialog. */ LRESULT CALLBACK kwin_wnd_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { #if 0 if (message == wm_kerberos_changed) { /* Message from the ccache */ n = ticket_init_list(GetDlgItem(hwnd, IDD_TICKET_LIST)); EnableWindow(GetDlgItem(hwnd, IDD_TICKET_DELETE), n > 0); return 0; } #endif switch (message) { HANDLE_MSG(hwnd, WM_GETMINMAXINFO, kwin_getminmaxinfo); HANDLE_MSG(hwnd, WM_DESTROY, kwin_destroy); HANDLE_MSG(hwnd, WM_MEASUREITEM, ticket_measureitem); HANDLE_MSG(hwnd, WM_DRAWITEM, ticket_drawitem); case WM_SETCURSOR: if (isblocking) { SetCursor(LoadCursor(NULL, IDC_WAIT)); return TRUE; } break; HANDLE_MSG(hwnd, WM_SIZE, kwin_size); HANDLE_MSG(hwnd, WM_SYSCOMMAND, kwin_syscommand); HANDLE_MSG(hwnd, WM_TIMER, kwin_timer); HANDLE_MSG(hwnd, WM_PAINT, kwin_paint); case WM_ERASEBKGND: if (!IsIconic(hwnd)) break; return 0; case WM_KWIN_SETNAME: kwin_init_name(hwnd, (char *)lParam); } return DefDlgProc(hwnd, message, wParam, lParam); } /* * Function: Dialog procedure called by the dialog manager * to process dialog specific messages. */ static BOOL CALLBACK kwin_dlg_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { switch (message) { HANDLE_MSG(hwnd, WM_INITDIALOG, kwin_initdialog); HANDLE_MSG(hwnd, WM_COMMAND, kwin_command); } return FALSE; } /* * Function: Initialize the kwin dialog class. * * Parameters: * hinstance - the instance to initialize * * Returns: TRUE if dialog class registration is sucessfully, false otherwise. */ static BOOL kwin_init(HINSTANCE hinstance) { WNDCLASS class; ATOM rc; class.style = CS_HREDRAW | CS_VREDRAW; class.lpfnWndProc = (WNDPROC)kwin_wnd_proc; class.cbClsExtra = 0; class.cbWndExtra = DLGWINDOWEXTRA; class.hInstance = hinstance; class.hIcon = NULL; /* LoadIcon(hinstance, MAKEINTRESOURCE(IDI_KWIN)); */ class.hCursor = NULL; class.hbrBackground = NULL; class.lpszMenuName = NULL; class.lpszClassName = KWIN_DIALOG_CLASS; rc = RegisterClass(&class); assert(rc); return rc; } /* * Function: Initialize the KWIN application. This routine should * only be called if no previous instance of the application * exists. Currently it only registers a class for the kwin * dialog type. * * Parameters: * hinstance - the instance to initialize * * Returns: TRUE if initialized sucessfully, false otherwise. */ static BOOL init_application(HINSTANCE hinstance) { BOOL rc; #if 0 #ifdef KRB4 wm_kerberos_changed = krb_get_notification_message(); #endif #ifdef KRB5 wm_kerberos_changed = krb5_get_notification_message(); #endif #endif rc = kwin_init(hinstance); return rc; } /* * Function: Quits the KWIN application. This routine should * be called when the last application instance exits. * * Parameters: * hinstance - the instance which is quitting. * * Returns: TRUE if initialized sucessfully, false otherwise. */ static BOOL quit_application(HINSTANCE hinstance) { return TRUE; } /* * Function: Initialize the current instance of the KWIN application. * * Parameters: * hinstance - the instance to initialize * * ncmdshow - show flag to indicate wheather to come up minimized * or not. * * Returns: TRUE if initialized sucessfully, false otherwise. */ static BOOL init_instance(HINSTANCE hinstance, int ncmdshow) { WORD versionrequested; WSADATA wsadata; int rc; int i; versionrequested = 0x0101; /* We need version 1.1 */ rc = WSAStartup(versionrequested, &wsadata); if (rc != 0) { MessageBox(NULL, "Couldn't initialize Winsock library", "", MB_OK | MB_ICONSTOP); return FALSE; } if (versionrequested != wsadata.wVersion) { WSACleanup(); MessageBox(NULL, "Winsock version 1.1 not available", "", MB_OK | MB_ICONSTOP); return FALSE; } #ifdef KRB5 { krb5_error_code code; code = krb5_init_context(&k5_context); if (!code) { #if 0 /* Not needed under windows */ krb5_init_ets(k5_context); #endif code = k5_init_ccache(&k5_ccache); } if (code) { com_err(NULL, code, "while initializing program"); return FALSE; } k5_name_from_ccache(k5_ccache); } #endif cns_load_registry(); /* * Set up expiration action */ alert = cns_res.alert; beep = cns_res.beep; /* * ticket options */ forwardable = cns_res.forwardable; noaddresses = cns_res.noaddresses; /* * Load clock icons */ for (i = IDI_FIRST_CLOCK; i <= IDI_LAST_CLOCK; i++) kwin_icons[i - IDI_FIRST_CLOCK] = LoadIcon(hinstance, MAKEINTRESOURCE(i)); #ifdef KRB4 krb_start_session(NULL); #endif return TRUE; } /* * Function: Quits the current instance of the KWIN application. * * Parameters: * hinstance - the instance to quit. * * Returns: TRUE if termination was sucessfully, false otherwise. */ static BOOL quit_instance(HINSTANCE hinstance) { int i; #ifdef KRB4 krb_end_session(NULL); #endif #ifdef KRB5 /* FIXME */ krb5_cc_close(k5_context, k5_ccache); #endif WSACleanup(); /* * Unload clock icons */ for (i = IDI_FIRST_CLOCK; i <= IDI_LAST_CLOCK; i++) DestroyIcon(kwin_icons[i - IDI_FIRST_CLOCK]); return TRUE; } /* * Function: Main routine called on program invocation. * * Parameters: * hinstance - the current instance * * hprevinstance - previous instance if one exists or NULL. * * cmdline - the command line string passed by Windows. * * ncmdshow - show flag to indicate wheather to come up minimized * or not. * * Returns: TRUE if initialized sucessfully, false otherwise. */ int PASCAL WinMain(HINSTANCE hinst, HINSTANCE hprevinstance, LPSTR cmdline, int ncmdshow) { DLGPROC dlgproc; HWND hwnd; HACCEL haccel; MSG msg; char *p; char buf[MAX_K_NAME_SZ + 9]; char name[MAX_K_NAME_SZ]; strcpy(buf, cmdline); action = LOGIN_AND_RUN; name[0] = 0; p = strtok(buf, " ,"); while (p != NULL) { if (_stricmp(p, "/exit") == 0) action = LOGIN_AND_EXIT; else if (_stricmp(p, "/minimize") == 0) action = LOGIN_AND_MINIMIZE; else strcpy(name, p); p = strtok(NULL, " ,"); } dlgncmdshow = ncmdshow; hinstance = hinst; #ifndef _WIN32 /* * If a previous instance of this application exits, bring it * to the front and exit. * * This code is not compiled for WIN32, since hprevinstance will always * be NULL. */ if (hprevinstance != NULL) { hwnd = FindWindow(KWIN_DIALOG_CLASS, NULL); if (IsWindow(hwnd) && IsWindowVisible(hwnd)) { if (GetWindowWord(hwnd, GWW_HINSTANCE) == hprevinstance) { if (name[0]) SendMessage(hwnd, WM_KWIN_SETNAME, 0, (LONG)name); ShowWindow(hwnd, ncmdshow); SetWindowPos(hwnd, HWND_TOP, 0, 0, 0, 0, SWP_SHOWWINDOW | SWP_NOMOVE | SWP_NOSIZE); return FALSE; } } } if (hprevinstance == NULL) #endif /* _WIN32 */ if (!init_application(hinstance)) return FALSE; if (!init_instance(hinstance, ncmdshow)) return FALSE; #ifdef _WIN32 dlgproc = kwin_dlg_proc; #else dlgproc = (FARPROC)MakeProcInstance(kwin_dlg_proc, hinstance); assert(dlgproc != NULL); if (dlgproc == NULL) return 1; #endif hwnd = CreateDialogParam(hinstance, MAKEINTRESOURCE(ID_KWIN), HWND_DESKTOP, dlgproc, (LONG)name); assert(hwnd != NULL); if (hwnd == NULL) return 1; haccel = LoadAccelerators(hinstance, MAKEINTRESOURCE(IDA_KWIN)); assert(hwnd != NULL); while (GetMessage(&msg, NULL, 0, 0)) { if (!TranslateAccelerator(hwnd, haccel, &msg) && !IsDialogMessage(hwnd, &msg)) { TranslateMessage(&msg); DispatchMessage(&msg); } } DestroyWindow(hwnd); #ifndef _WIN32 FreeProcInstance((FARPROC)dlgproc); #endif cns_save_registry(); return 0; } #if 0 #define WM_ASYNC_COMPLETED (WM_USER + 1) #define GETHOSTBYNAME_CLASS "krb_gethostbyname" static HTASK htaskasync; /* Asynchronos call in progress */ static BOOL iscompleted; /* True when async call is completed */ /* * This routine is called to cancel a blocking hook call within * the Kerberos library. The need for this routine arises due * to bugs which exist in existing WINSOCK implementations. We * blocking gethostbyname with WSAASyncGetHostByName. In order * to cancel such an operation, this routine must be called. * Applications may call this routine in addition to calls to * WSACancelBlockingCall to get any sucy Async calls canceled. * Return values are as they would be for WSACancelAsyncRequest. */ int krb_cancel_blocking_call(void) { if (htaskasync == NULL) return 0; iscompleted = TRUE; return WSACancelAsyncRequest(htask); } /* * Window proceedure for temporary Windows created in * krb_gethostbyname. Fields completion messages. */ LRESULT CALLBACK krb_gethostbyname_wnd_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { if (message == WM_ASYNC_COMPLETED) { iscompleted = TRUE; return 0; } return DefWindowProc(hwnd, message, wParam, lParam); } /* * The WINSOCK routine gethostbyname has a bug in both FTP and NetManage * implementations which causes the blocking hook, if any, not to be * called. This routine attempts to work around the problem by using * the async routines to emulate the functionality of the synchronous * routines */ struct hostent *PASCAL krb_gethostbyname( const char *name) { HWND hwnd; char buf[MAXGETHOSTSTRUCT]; BOOL FARPROC blockinghook; WNDCLASS wc; static BOOL isregistered; blockinghook = WSASetBlockingHook(NULL); WSASetBlockingHook(blockinghook); if (blockinghook == NULL) return gethostbyname(name); if (RegisterWndClass() == NULL) return gethostbyname(name); if (!isregistered) { wc.style = 0; wc.lpfnWndProc = gethostbyname_wnd_proc; wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.hInstance = hlibinstance; wc.hIcon = NULL; wc.hCursor = NULL; wc.hbrBackground = NULL; wc.lpszMenuName = NULL; wc.lpszClassName = GETHOSTBYNAME_CLASS; if (!RegisterClass(&wc)) return gethostbyname(name); isregistered = TRUE; } hwnd = CreateWindow(GETHOSTBYNAME_CLASS, "", WS_OVERLAPPED, -100, -100, 0, 0, HWND_DESKTOP, NULL, hlibinstance, NULL); if (hwnd == NULL) return gethostbyname(name); htaskasync = WSAAsyncGetHostByName(hwnd, WM_ASYNC_COMPLETED, name, buf, sizeof(buf)); b = blockinghook(NULL); } #endif /* if 0 */ #ifdef KRB5 /* * Function: destroys all tickets in a k5 ccache * * Returns: K5 error code (0 == success) */ krb5_error_code k5_dest_tkt(void) { krb5_error_code code; krb5_principal princ; if (code = krb5_cc_get_principal(k5_context, k5_ccache, &princ)) { com_err(NULL, code, "while retrieving principal name"); return code; } code = krb5_cc_initialize(k5_context, k5_ccache, princ); if (code != 0) { com_err(NULL, code, "when re-initializing cache"); krb5_free_principal(k5_context, princ); return code; } krb5_free_principal(k5_context, princ); return code; } /* * * k5_get_num_cred * * Returns: number of creds in the credential cache, -1 on error * */ int k5_get_num_cred(int verbose) { krb5_error_code code; krb5_cc_cursor cursor; krb5_creds c; int ncreds = 0; if (code = krb5_cc_start_seq_get(k5_context, k5_ccache, &cursor)) { if (code == KRB5_FCC_NOFILE) return 0; if (verbose) com_err(NULL, code, "while starting to retrieve tickets."); return -1; } while (1) { /* Loop and get creds */ code = krb5_cc_next_cred(k5_context, k5_ccache, &cursor, &c); if (code) break; ++ncreds; } if (code != KRB5_CC_END) { /* Error while looping??? */ if (verbose) com_err(NULL, code, "while retrieving a ticket."); return -1; } if (code = krb5_cc_end_seq_get(k5_context, k5_ccache, &cursor)) { if (verbose) com_err(NULL, code, "while closing ccache."); } return ncreds; } static int k5_get_num_cred2() { krb5_error_code code; krb5_cc_cursor cursor; krb5_creds c; int ncreds = 0; code = krb5_cc_start_seq_get(k5_context, k5_ccache, &cursor); if (code == KRB5_FCC_NOFILE) return 0; while (1) { code = krb5_cc_next_cred(k5_context, k5_ccache, &cursor, &c); if (code) break; ++ncreds; } if (code == KRB5_CC_END) krb5_cc_end_seq_get(k5_context, k5_ccache, &cursor); return ncreds; } /* * Function: Parses fullname into name and realm * * Parameters: * name - buffer filled with name of user * realm - buffer filled with realm of user * fullname - string in form name.instance@realm * * Returns: 0 */ int k5_kname_parse(char *name, char *realm, char *fullname) { char *ptr; /* For parsing */ ptr = strchr(fullname, '@'); /* Name, realm separator */ if (ptr != NULL) /* Get realm */ strcpy(realm, ptr + 1); else *realm = '\0'; if (ptr != NULL) { /* Get the name */ strncpy(name, fullname, ptr - fullname); name[ptr - fullname] = '\0'; } else strcpy(name, fullname); ptr = strchr(name, '.'); /* K4 compatability */ if (ptr != NULL) *ptr = '\0'; return 0; } /* * Function: Initializes ccache and catches illegal caches such as * bad format or no permissions. * * Parameters: * ccache - credential cache structure to use * * Returns: krb5_error_code */ krb5_error_code k5_init_ccache(krb5_ccache *ccache) { krb5_error_code code; krb5_principal princ; FILE *fp; code = krb5_cc_default(k5_context, ccache); /* Initialize the ccache */ if (code) return code; code = krb5_cc_get_principal(k5_context, *ccache, &princ); if (code == KRB5_FCC_NOFILE) { /* Doesn't exist yet */ fp = fopen(krb5_cc_get_name(k5_context, *ccache), "w"); if (fp == NULL) /* Can't open it */ return KRB5_FCC_PERM; fclose (fp); } if (code) { /* Bad, delete and try again */ remove(krb5_cc_get_name(k5_context, *ccache)); code = krb5_cc_get_principal(k5_context, *ccache, &princ); if (code == KRB5_FCC_NOFILE) /* Doesn't exist yet */ return 0; if (code) return code; } /* krb5_free_principal(k5_context, princ); */ return 0; } /* * * Function: Reads the name and realm out of the ccache. * * Parameters: * ccache - credentials cache to get info from * * name - buffer to hold user name * * realm - buffer to hold the realm * * * Returns: TRUE if read names, FALSE if not * */ int k5_name_from_ccache(krb5_ccache k5_ccache) { krb5_error_code code; krb5_principal princ; char name[ANAME_SZ]; char realm[REALM_SZ]; char *defname; if (code = krb5_cc_get_principal(k5_context, k5_ccache, &princ)) return FALSE; code = krb5_unparse_name(k5_context, princ, &defname); if (code) { return FALSE; } k5_kname_parse(name, realm, defname); /* Extract the components */ strcpy(cns_res.name, name); strcpy(cns_res.realm, realm); return TRUE; } #endif /* KRB5 */ krb5-1.16/src/windows/cns/clock20.ico0000644000704600001450000000207613211554426017200 0ustar ghudsonlibuuid & 0( @wwwwwwwwwwwwwwwwwwpwwpwwwpwwwwwwwwwwwwwwwwwwww??????????????????( @ߞz~v~~??????????????????krb5-1.16/src/windows/cns/clock30.ico0000644000704600001450000000207613211554426017201 0ustar ghudsonlibuuid & 0( @wwwwwwwwwwwwwwwwwwwwpwwwwwwwwwwwwwwwwwwww??????????????????( @~v~z~v~~??????????????????krb5-1.16/src/windows/cns/clock60.ico0000644000704600001450000000207613211554426017204 0ustar ghudsonlibuuid & 0( @wwwwwwwwwwwwwwwwwwpwwwwwwwwwwwwwwww??????????????????( @??~=?7?/z?~7v?~=?~??????????????????krb5-1.16/src/windows/cns/clock05.ico0000644000704600001450000000207613211554426017203 0ustar ghudsonlibuuid & 0( @wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww??????????????????( @}=]]}??????????????????krb5-1.16/src/windows/cns/tktlist.h0000644000704600001450000000077413211554426017121 0ustar ghudsonlibuuid/* windows/cns/tktlist.h */ /* * Copyright 1994 by the Massachusetts Institute of Technology. * * For copying and distribution information, please see the file * . */ /* Handle all actions of the Kerberos ticket list. */ /* Only one time, please */ #ifndef TKTLIST_DEFS #define TKTLIST_DEFS /* * Prototypes */ BOOL ticket_init_list(HWND); void ticket_destroy(HWND); void ticket_measureitem(HWND, MEASUREITEMSTRUCT *); void ticket_drawitem(HWND, const DRAWITEMSTRUCT *); #endif krb5-1.16/src/windows/cns/clockexp.ico0000644000704600001450000000207613211554426017553 0ustar ghudsonlibuuid & 0( @wpywwwpwwww pwpwy wwwwywwwwwwpwywwywwwywwwwywwywwywwwwwwywpww pwywww wpwyw wwwwwyywwwwypwwwyp ??????????( @|? ?G?cߟ=? G{c??p??krb5-1.16/src/windows/cns/cns-help.hpj0000644000704600001450000001007013211554426017454 0ustar ghudsonlibuuid;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ; Help Project File for KERBNET ; ; You may edit this file. ; ; It's probably best not to change the CONTENTS= value ; unless you rename the IDH_CONTENTS context string in ; the KERBNET.DOC file. ; [OPTIONS] ; The optional ROOT= entry sets the working directory for the Help Compiler ; ROOT=C:\PROJECT ; The optional BMROOT= entry sets forth the directories which the ; help compiler will search for bitmaps used in the Help system. ; ;BMROOT=C:\ROBOHELP ; The CONTENTS= tells the help Engine which topic contains the contents CONTENTS=IDH_CONTENTS ; Title is Displayed in the Title Bar of WINHELP.EXE TITLE=Kerb*Net ; The BUILD= setting allows complex Help systems which require ; different versions to use the same source. This is similar to #ifdef's ; in the 'C' language. Everything to the right of the = sign in the ; BUILD= statement is an EXPRESSION. See the Help compiler ; documentation for more information about build expressions. BUILD=WINDOWS ; The Warning Level is used by the Help Compiler (HC.EXE) ; WARNING=1 - Only the most severe warnings are reported ; WARNING=2 - Intermediate Level of warnings ; WARNING=3 - Most stringent error reporting ; The Compress option is used by the Help Compiler to make ; smaller, faster loading .HLP files. However, using compression ; increases Compile times. ; COMPRESS=YES, ON, OFF, NO, TRUE or FALSE OLDKEYPHRASE=NO OPTCDROM=0 NOTES=1 REPORT=YES COMPRESS=12 ERRORLOG=C:\krbhelp\KERBNET.ERR [BUILDTAGS] ; The Build Tags section specifies to the Help Compiler the names ; of all the valid build tags used in this Help project. The [BUILDTAGS] ; section is optional. WINDOWS [CONFIG] ; The config section allows you to define some macros which will be ; executed when the help system is first executed. ; ; The next line gives you browse buttons: ; BrowseButtons() ; ; To create a glossary button which displays a list of defined terms ; in a secondary window, remove the semi colon at the start of the next ; line and do the same with the Glossary window in the [WINDOWS] section ;CreateButton("Glossary_Btn","&Glossary","JI(`bubble.hlp>Gloss',`IDH_Glossary')") ; [FILES] ; The files section is where you specify to the Help Compiler which ; Rich Text Format (.RTF) (your help source) files will be used in the ; Help system. RoboHELP generates and maintains the main .RTF ; file for your Help System. If you desire to have multiple .RTF files, ; simply add the additonal names to the [FILES] section. KERBNET.RTF [ALIAS] ; The Alias section allows you to set up aliases for context strings ; in your help system. ; ; Brief example: ; ; IDH_UserID = IDH_RoboGenerated_Id ; IDH_WMP_MenuID = IDH_RoboGenerated_Id ; IDH_Any = IDH_AnyOther [MAP] ; ; The Map Section is where the C language #defines are translated ; or mapped into the Help System Context Strings. Standard C syntax ; can be employed. The .HH file is meant to be #include(d) into your ; Windows application source code. ; [BITMAPS] ; ; The [BITMAPS] section is where you list any Bitmaps which have ; been placed by reference in the Help System. See the Help compiler ; documentation for more information about placing bitmaps. ; ; The [BITMAPS] section is not really required under Windows 3.1, ; with the advent of the BMROOT item in the [OPTIONS] section. ; ;FOO1.BMP ;FOO2.BMP ;C:\FOO\FOO3.BMP ;And So On [WINDOWS] ; Windows Help can display help in one of 5 secondary windows. ; Before using a secondary window, the window must be defined ; in this section: ; ;Gloss = "Glossary",(100,100,350,350),0,(255,255,255),(255,255,255) main=,,0,, [BAGGAGE] ; ; The Baggage section allows the user to include files which ; will be placed in the internal file system for WinHelp. ; Using files from Baggage is a little faster for CDROM, since ; the CDROM drive table does not need to be read from disk. ; ; Baggage files are referred to as regular bitmaps, except ; that you prefix the filename with '!'. ; ; For Instance: ; {bmc !bitmap.bmp} instead of {bmc bitmap.bmp} ; krb5-1.16/src/windows/cns/clock25.ico0000644000704600001450000000207613211554426017205 0ustar ghudsonlibuuid & 0( @wwwwwwwwwwwwwwwpwwwpwwwwpwwwwwwwwwwwwwwwwwwww??????????????????( @߶߾z~v~~~??????????????????krb5-1.16/src/windows/cns/clock10.ico0000644000704600001450000000207613211554426017177 0ustar ghudsonlibuuid & 0( @wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww??????????????????( @=Mu~~~??????????????????krb5-1.16/src/windows/cns/debug.c0000644000704600001450000000370013211554426016474 0ustar ghudsonlibuuid#ifdef DEBUG #include #include #include #include void OutputHeading(const char *explanation) { _RPT1(_CRT_WARN, "\n\n%s:\n*********************************\n", explanation ); } /* * The following macros set and clear, respectively, given bits * of the C runtime library debug flag, as specified by a bitmask. */ #define SET_CRT_DEBUG_FIELD(a) \ _CrtSetDbgFlag((a) | _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG)) #define CLEAR_CRT_DEBUG_FIELD(a) \ _CrtSetDbgFlag(~(a) & _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG)) _CrtMemState s1; _CrtMemState s2; _CrtMemState s3; static _CrtMemState *ss1 = NULL; static _CrtMemState *ss2 = NULL; void debug_init(); void debug_check() { _CrtMemState *temp; OutputHeading("Checking memory..."); if (ss1 == NULL) { debug_init(); ss1 = &s1; ss2 = &s2; } _CrtCheckMemory(); /* _CrtMemDumpAllObjectsSince( NULL ); */ _CrtMemCheckpoint( &s2 ); if ( _CrtMemDifference( &s3, &s1, &s2 ) ) _CrtMemDumpStatistics( &s3 ); /* _CrtDumpMemoryLeaks(); */ /* * swap the snapshots around */ temp = ss1; ss1 = ss2; ss2 = temp; } void debug_init() { /* Send all reports to STDOUT */ _CrtSetReportMode( _CRT_WARN, _CRTDBG_MODE_FILE ); _CrtSetReportFile( _CRT_WARN, _CRTDBG_FILE_STDOUT ); _CrtSetReportMode( _CRT_ERROR, _CRTDBG_MODE_FILE ); _CrtSetReportFile( _CRT_ERROR, _CRTDBG_FILE_STDOUT ); _CrtSetReportMode( _CRT_ASSERT, _CRTDBG_MODE_FILE ); _CrtSetReportFile( _CRT_ASSERT, _CRTDBG_FILE_STDOUT ); _CrtMemCheckpoint( &s1 ); /* * Set the debug-heap flag so that freed blocks are kept on the * linked list, to catch any inadvertent use of freed memory */ SET_CRT_DEBUG_FIELD( _CRTDBG_DELAY_FREE_MEM_DF ); /* * Set the debug-heap flag so that memory leaks are reported when * the process terminates. Then, exit. */ SET_CRT_DEBUG_FIELD( _CRTDBG_LEAK_CHECK_DF ); } #endif /* DEBUG */ krb5-1.16/src/windows/cns/Makefile.in0000644000704600001450000000352513211554426017314 0ustar ghudsonlibuuid# Makefile for the Kerberos for Windows ticket manager # Works for both k4 and k5 releases. # NAME = krb5 OBJS = $(OUTPRE)cns.obj $(OUTPRE)tktlist.obj $(OUTPRE)password.obj $(OUTPRE)options.obj ##### Options # Set NODEBUG if building release instead of debug !IF ! defined(KVERSION) KVERSION = 5 !endif KRB = KRB$(KVERSION) !if $(KVERSION) == 4 BUILDTOP = .. LIBDIR = $(BUILDTOP)\lib\krb KLIB = $(LIBDIR)\kerberos.lib RESFILE = $(OUTPRE)cnsres4.res XOBJS = $(RESFILE) LOCALINCLUDES = /I$(BUILDTOP) /I$(BUILDTOP)\include !endif !if $(KVERSION) == 5 BUILDTOP =..\.. LIBDIR = $(BUILDTOP)\lib RESFILE = $(OUTPRE)cnsres5.res XOBJS = $(RESFILE) $(OUTPRE)kpasswd.obj $(OUTPRE)cns_reg.obj LOCALINCLUDES = /I$(BUILDTOP) /I$(BUILDTOP)\include /I$(BUILDTOP)\include\krb5 !endif ##### C Compiler #CC = cl !ifdef NODEBUG DEFINES = /D$(KRB)=1 !else DEFINES = /D$(KRB)=1 /DDEBUG !endif ##### RC Compiler #RC = rc RFLAGS = /D$(KRB)=1 $(LOCALINCLUDES) RCFLAGS = $(RFLAGS) -DKRB5_APP ##### CVSRES -- .res -> .obj converter CVTRES = cvtres ##### Linker LINK = link LIBS = $(KLIB) $(CLIB) $(WLIB) ../lib/$(OUTPRE)libwin.lib SYSLIBS = kernel32.lib ws2_32.lib user32.lib gdi32.lib advapi32.lib LFLAGS = /nologo $(LOPTS) all: Makefile $(OUTPRE)$(NAME).exe $(OUTPRE)$(NAME).exe: $(NAME).def $(OBJS) $(XOBJS) $(LIBS) $(LINK) $(LFLAGS) /map:$*.map /out:$@ $(OBJS) $(XOBJS) \ $(LIBS) $(SYSLIBS) $(SCLIB) $(_VC_MANIFEST_EMBED_EXE) install: $(CP) $(OUTPRE)$(NAME).exe $(DESTDIR) $(CP) krb5.hlp $(DESTDIR) clean: $(RM) $(OUTPRE)*.exe $(RM) $(OUTPRE)*.res $(RM) $(OUTPRE)*.map $(OBJS): cns.h tktlist.h $(RESFILE): cns.h ..\version.rc $(RESFILE): clock00.ico clock05.ico clock10.ico clock15.ico clock20.ico \ clock25.ico clock30.ico clock35.ico clock40.ico clock45.ico \ clock50.ico clock55.ico clock60.ico clockexp.ico clocktkt.ico \ cns.ico krb5-1.16/src/windows/cns/heap.c0000644000704600001450000000137513211554426016331 0ustar ghudsonlibuuid#include #include void heapdump( void ) { _HEAPINFO hinfo; int heapstatus; hinfo._pentry = NULL; while( ( heapstatus = _heapwalk( &hinfo ) ) == _HEAPOK ) { printf( "%6s block at %Fp of size %4.4X\n", ( hinfo._useflag == _USEDENTRY ? "USED" : "FREE" ), hinfo._pentry, hinfo._size ); } switch( heapstatus ) { case _HEAPEMPTY: printf( "OK - empty heap\n" ); break; case _HEAPEND: printf( "OK - end of heap\n" ); break; case _HEAPBADPTR: printf( "ERROR - bad pointer to heap\n" ); break; case _HEAPBADBEGIN: printf( "ERROR - bad start of heap\n" ); break; case _HEAPBADNODE: printf( "ERROR - bad node in heap\n" ); break; } } krb5-1.16/src/windows/cns/options.c0000644000704600001450000001246013211554426017104 0ustar ghudsonlibuuid/* * Copyright 1994 by the Massachusetts Institute of Technology. * * For copying and distribution information, please see the file * . */ /* * functions to tweak the options dialog */ #include #include #include #include #include #include #include #include #include #include "cns.h" #include "tktlist.h" #include "cns_reg.h" /* * Function: Process WM_INITDIALOG messages for the options dialog. * Set up all initial dialog values from the KERBEROS_INI file. * * Returns: TRUE if we didn't set the focus here, * FALSE if we did. */ BOOL opts_initdialog(HWND hwnd, HWND hwndFocus, LPARAM lParam) { center_dialog(hwnd); set_dialog_font(hwnd, hfontdialog); /* krb.conf file */ strcpy(confname, cns_res.confname); #ifndef _WIN32 _strupr(confname); #endif SetDlgItemText(hwnd, IDD_CONF, confname); if (cns_res.conf_override == 0) EnableWindow(GetDlgItem(hwnd, IDD_CONF), 0); else EnableWindow(GetDlgItem(hwnd, IDD_CONF), 1); /* Credential cache file */ strcpy(ccname, cns_res.ccname); #ifndef _WIN32 _strupr(ccname); #endif SetDlgItemText(hwnd, IDD_CCACHE, ccname); if (cns_res.cc_override == 0) EnableWindow(GetDlgItem(hwnd, IDD_CCACHE), 0); else EnableWindow(GetDlgItem(hwnd, IDD_CCACHE), 1); /* Ticket duration */ SetDlgItemInt(hwnd, IDD_LIFETIME, cns_res.lifetime, FALSE); /* Expiration action */ alert = cns_res.alert; SendDlgItemMessage(hwnd, IDD_ALERT, BM_SETCHECK, alert, 0); beep = cns_res.beep; SendDlgItemMessage(hwnd, IDD_BEEP, BM_SETCHECK, beep, 0); forwardable = cns_res.forwardable; SendDlgItemMessage(hwnd, IDD_FORWARDABLE, BM_SETCHECK, forwardable, 0); noaddresses = cns_res.noaddresses; SendDlgItemMessage(hwnd, IDD_NOADDRESSES, BM_SETCHECK, noaddresses, 0); return TRUE; } /* * Function: Process WM_COMMAND messages for the options dialog. */ void opts_command(HWND hwnd, int cid, HWND hwndCtl, UINT codeNotify) { char newname[FILENAME_MAX]; BOOL b; int lifetime; switch (cid) { case IDOK: /* Ticket duration */ lifetime = GetDlgItemInt(hwnd, IDD_LIFETIME, &b, FALSE); if (!b) { MessageBox(hwnd, "Lifetime must be a number!", "", MB_OK | MB_ICONEXCLAMATION); return; /* TRUE */ } cns_res.lifetime = lifetime; if (cns_res.conf_override) { /* krb.conf file */ GetDlgItemText(hwnd, IDD_CONF, newname, sizeof(newname)); trim(newname); if (newname[0] == '\0') strcpy(newname, cns_res.def_confname); if (_stricmp(newname, confname)) { /* file name changed */ MessageBox(NULL, "Change to configuration file location requires a restart" "of KerbNet.\n" "Please exit this application and restart it for the change to take" "effect", "", MB_OK | MB_ICONEXCLAMATION); } strcpy(confname, newname); } /* Credential cache file */ GetDlgItemText(hwnd, IDD_CCACHE, newname, sizeof(newname)); trim(newname); if (newname[0] == '\0') strcpy(newname, cns_res.def_ccname); if (_stricmp(ccname, newname)) { /* Did we change ccache file? */ krb5_error_code code; krb5_ccache cctemp; code = k5_init_ccache(&cctemp); if (code) { /* Problem opening new one? */ com_err(NULL, code, "while changing ccache.\r\nRestoring old ccache."); } else { strcpy(ccname, newname); strcpy(cns_res.ccname, newname); code = krb5_cc_close(k5_context, k5_ccache); k5_ccache = cctemp; /* Copy new into old */ if (k5_name_from_ccache(k5_ccache)) { kwin_init_name(GetParent(hwnd), ""); kwin_set_default_focus(GetParent(hwnd)); } ticket_init_list(GetDlgItem (GetParent(hwnd), IDD_TICKET_LIST)); } } /* * get values for the clickboxes */ alert = SendDlgItemMessage(hwnd, IDD_ALERT, BM_GETCHECK, 0, 0); cns_res.alert = alert; beep = SendDlgItemMessage(hwnd, IDD_BEEP, BM_GETCHECK, 0, 0); cns_res.beep = beep; forwardable = SendDlgItemMessage(hwnd, IDD_FORWARDABLE, BM_GETCHECK, 0, 0); cns_res.forwardable = forwardable; noaddresses = SendDlgItemMessage(hwnd, IDD_NOADDRESSES, BM_GETCHECK, 0, 0); cns_res.noaddresses = noaddresses; EndDialog(hwnd, IDOK); return; /* TRUE */ case IDCANCEL: EndDialog(hwnd, IDCANCEL); return; /* TRUE */ } return; /* FALSE */ } /* * Function: Process dialog specific messages for the opts dialog. */ BOOL CALLBACK opts_dlg_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { switch (message) { HANDLE_MSG(hwnd, WM_INITDIALOG, opts_initdialog); HANDLE_MSG(hwnd, WM_COMMAND, opts_command); } return FALSE; } /* * Function: Display and process the options dialog. * * Parameters: * hwnd - the parent window for the dialog * * Returns: TRUE if the dialog completed successfully, FALSE otherwise. */ BOOL opts_dialog(HWND hwnd) { DLGPROC dlgproc; int rc; #ifdef _WIN32 dlgproc = opts_dlg_proc; #else dlgproc = (FARPROC)MakeProcInstance(opts_dlg_proc, hinstance); assert(dlgproc != NULL); if (dlgproc == NULL) return FALSE; #endif rc = DialogBox(hinstance, MAKEINTRESOURCE(ID_OPTS), hwnd, dlgproc); assert(rc != -1); #ifndef _WIN32 FreeProcInstance((FARPROC)dlgproc); #endif return rc == IDOK; } krb5-1.16/src/windows/cns/clock40.ico0000644000704600001450000000207613211554426017202 0ustar ghudsonlibuuid & 0( @wwwwwwwwwwwwwwwwwpwwwwwwwwwwwwwwwwwwww??????????????????( @~z~v~~??????????????????krb5-1.16/src/windows/cns/clock55.ico0000644000704600001450000000207613211554426017210 0ustar ghudsonlibuuid & 0( @wwwwwwwwwwwwwwwwwwpwwwpwwwwwwwwwww??????????????????( @??~=?7?/z?~6v=~=?~???????????????????krb5-1.16/src/windows/cns/clock50.ico0000644000704600001450000000207613211554426017203 0ustar ghudsonlibuuid & 0( @wwwwwwwwwwwwwwwpwpwwwwwwwwwwwwwwwww??????????????????( @~~z~v~_~??????????????????krb5-1.16/src/windows/cns/clock00.ico0000644000704600001450000000207613211554426017176 0ustar ghudsonlibuuid & 0( @wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww??????????????????( @}}}}}?????????????????krb5-1.16/src/windows/cns/tktlist.c0000644000704600001450000002276613211554426017121 0ustar ghudsonlibuuid/* windows/cns/tktlist.c */ /* * Copyright 1994 by the Massachusetts Institute of Technology. * * For copying and distribution information, please see the file * . */ /* Handle all actions of the Kerberos ticket list. */ #if !defined(KRB5) && !defined(KRB4) #define KRB5 1 #endif #include #include #include #include #include #include #include #ifdef KRB4 #include "mit-copyright.h" #include "kerberos.h" #endif #ifdef KRB5 #include "winsock.h" #include "krb5.h" #include "com_err.h" #endif #include "cns.h" #include "tktlist.h" #define ts2tt(t) (time_t)(uint32_t)(t) /* * Ticket information for a list line */ typedef struct { BOOL ticket; /* TRUE if this is a real ticket */ time_t issue_time; /* time_t of issue */ long lifetime; /* Lifetime for ticket in 5 minute intervals */ char buf[0]; /* String to display */ } TICKETINFO, *LPTICKETINFO; /* * Function: Returns a standard ctime date with day of week and year * removed. * * Parameters: * t - time_t date to convert * * Returns: A pointer to the adjusted time value. */ static char * short_date (time_t t) { static char buf[26 - 4]; char *p; p = ctime(&t); assert(p != NULL); strcpy (buf, p + 4); buf[12] = '\0'; return buf; } /*+ * Function: Initializes and populates the ticket list with all existing * Kerberos tickets. * * Parameters: * hwnd - the window handle of the ticket window. * * Returns: Number of elements in the list or -1 on error */ int ticket_init_list (HWND hwnd) { int ncred; LRESULT rc; int l; LPTICKETINFO lpinfo; char buf[26+2 + 26+2 + ANAME_SZ+1 + INST_SZ+1 + REALM_SZ + 22]; #ifdef KRB4 int i; time_t expiration; char service[ANAME_SZ]; char instance[INST_SZ]; char realm[REALM_SZ]; CREDENTIALS c; #endif #ifdef KRB5 krb5_cc_cursor cursor; krb5_error_code code; krb5_creds c; char *sname; /* Name of the service */ char *flags_string(krb5_creds *cred); #endif SetWindowRedraw(hwnd, FALSE); rc = ListBox_GetCount(hwnd); assert(rc != LB_ERR); if (rc > 0) ticket_destroy(hwnd); while (--rc >= 0) ListBox_DeleteString(hwnd, rc); #ifdef KRB4 ncred = krb_get_num_cred(); for (i = 1; i <= ncred; i++) { krb_get_nth_cred(service, instance, realm, i); krb_get_cred(service, instance, realm, &c); strcpy(buf, " "); strncat(buf, short_date(c.issue_date - kwin_get_epoch()), sizeof(buf) - 1 - strlen(buf)); expiration = c.issue_date - kwin_get_epoch() + (long) c.lifetime * 5L * 60L; strncat(buf, " ", sizeof(buf) - 1 - strlen(buf)); strncat(buf, short_date(expiration), sizeof(buf) - 1 - strlen(buf)); strncat(buf, " ", sizeof(buf) - 1 - strlen(buf)); l = strlen(buf); sprintf(&buf[l], "%s%s%s%s%s (%d)", c.service, (c.instance[0] ? "." : ""), c.instance, (c.realm[0] ? "@" : ""), c.realm, c.kvno); l = strlen(buf); lpinfo = (LPTICKETINFO) malloc(sizeof(TICKETINFO) + l + 1); assert(lpinfo != NULL); if (lpinfo == NULL) return -1; lpinfo->ticket = TRUE; lpinfo->issue_time = c.issue_date - kwin_get_epoch(); /* back to system time */ lpinfo->lifetime = (long) c.lifetime * 5L * 60L; strcpy(lpinfo->buf, buf); rc = ListBox_AddItemData(hwnd, lpinfo); assert(rc >= 0); if (rc < 0) return -1; } #endif #ifdef KRB5 ncred = 0; if (code = krb5_cc_start_seq_get(k5_context, k5_ccache, &cursor)) { if (code != KRB5_FCC_NOFILE) { return -1; } } else { while (1) { code = krb5_cc_next_cred(k5_context, k5_ccache, &cursor, &c); if (code != 0) break; ncred++; strcpy (buf, " "); strncat(buf, short_date(ts2tt(c.times.starttime) - kwin_get_epoch()), sizeof(buf) - 1 - strlen(buf)); strncat(buf, " ", sizeof(buf) - 1 - strlen(buf)); strncat(buf, short_date(ts2tt(c.times.endtime) - kwin_get_epoch()), sizeof(buf) - 1 - strlen(buf)); strncat(buf, " ", sizeof(buf) - 1 - strlen(buf)); /* Add ticket service name and realm */ code = krb5_unparse_name (k5_context, c.server, &sname); if (code) { com_err (NULL, code, "while unparsing server name"); break; } strncat (buf, sname, sizeof(buf) - 1 - strlen(buf)); strncat (buf, flags_string (&c), sizeof(buf) - 1 - strlen(buf)); /* Add flag info */ l = strlen(buf); lpinfo = (LPTICKETINFO) malloc(sizeof(TICKETINFO) + l + 1); assert(lpinfo != NULL); if (lpinfo == NULL) return -1; lpinfo->ticket = TRUE; lpinfo->issue_time = ts2tt(c.times.starttime) - kwin_get_epoch(); lpinfo->lifetime = ts2tt(c.times.endtime) - c.times.starttime; strcpy(lpinfo->buf, buf); rc = ListBox_AddItemData(hwnd, lpinfo); assert(rc >= 0); if (rc < 0) return -1; } if (code == KRB5_CC_END) { /* End of ccache */ if (code = krb5_cc_end_seq_get(k5_context, k5_ccache, &cursor)) { return -1; } } else { return -1; } } #endif if (ncred <= 0) { strcpy(buf, " No Tickets"); lpinfo = (LPTICKETINFO) malloc(sizeof(TICKETINFO) + strlen(buf) + 1); assert(lpinfo != NULL); if (lpinfo == NULL) return -1; lpinfo->ticket = FALSE; strcpy (lpinfo->buf, buf); rc = ListBox_AddItemData(hwnd, lpinfo); assert(rc >= 0); } SetWindowRedraw(hwnd, TRUE); return ncred; } /* * Function: Destroy the ticket list. Make sure to delete all * ticket entries created during ticket initialization. * * Parameters: * hwnd - the window handle of the ticket window. */ void ticket_destroy ( HWND hwnd) { int i; int n; LRESULT rc; n = ListBox_GetCount(hwnd); for (i = 0; i < n; i++) { rc = ListBox_GetItemData(hwnd, i); assert(rc != LB_ERR); if (rc != LB_ERR) free ((void *) rc); } } /* * Function: Respond to the WM_MEASUREITEM message for the ticket list * by setting each list item up at 1/4 inch hight. */ void ticket_measureitem(HWND hwnd, MEASUREITEMSTRUCT *lpmi) { int logpixelsy; HDC hdc; if (lpmi->CtlID != IDD_TICKET_LIST) return; hdc = GetDC(HWND_DESKTOP); logpixelsy = GetDeviceCaps(hdc, LOGPIXELSY); ReleaseDC(HWND_DESKTOP, hdc); lpmi->itemHeight = logpixelsy / 4; /* 1/4 inch */ } /* * Function: Respond to the WM_DRAWITEM message for the ticket list * by displaying a single list item. */ void ticket_drawitem(HWND hwnd, const DRAWITEMSTRUCT *lpdi) { BOOL rc; COLORREF bkcolor; HBRUSH hbrush; UINT textheight; UINT alignment; int left, top; BOOL b; LPTICKETINFO lpinfo; HICON hicon; #if 0 COLORREF textcolor; COLORREF orgbkcolor; COLORREF orgtextcolor; #endif SIZE Size; if (lpdi->CtlID != IDD_TICKET_LIST) return; lpinfo = (LPTICKETINFO) lpdi->itemData; if (lpdi->itemAction == ODA_FOCUS) return; #if 0 if (lpdi->itemState & ODS_SELECTED) { textcolor = GetSysColor(COLOR_HIGHLIGHTTEXT); bkcolor = GetSysColor(COLOR_HIGHLIGHT); orgtextcolor = SetTextColor(lpdi->hDC, textcolor); assert(textcolor != 0x80000000); orgbkcolor = SetBkColor(lpdi->hDC, bkcolor); assert(bkcolor != 0x80000000); } else #endif bkcolor = GetBkColor(lpdi->hDC); hbrush = CreateSolidBrush(bkcolor); assert(hbrush != NULL); FillRect(lpdi->hDC, &(lpdi->rcItem), hbrush); DeleteObject(hbrush); /* * Display the appropriate icon */ if (lpinfo->ticket) { hicon = kwin_get_icon(lpinfo->issue_time + lpinfo->lifetime); left = lpdi->rcItem.left - (32 - ICON_WIDTH) / 2; top = lpdi->rcItem.top; top += (lpdi->rcItem.bottom - lpdi->rcItem.top - 32) / 2; b = DrawIcon(lpdi->hDC, left, top, hicon); assert(b); } /* * Display centered string */ #ifdef _WIN32 GetTextExtentPoint32(lpdi->hDC, "X", 1, &Size); #else GetTextExtentPoint(lpdi->hDC, "X", 1, &Size); #endif textheight = Size.cy; alignment = SetTextAlign(lpdi->hDC, TA_TOP | TA_LEFT); if (lpinfo->ticket) left = lpdi->rcItem.left + ICON_WIDTH; else left = lpdi->rcItem.left; top = lpdi->rcItem.top; top += (lpdi->rcItem.bottom - lpdi->rcItem.top - textheight) / 2; rc = TextOut(lpdi->hDC, left, top, (LPSTR) lpinfo->buf, strlen((LPSTR) lpinfo->buf)); assert(rc); alignment = SetTextAlign(lpdi->hDC, alignment); #if 0 if (lpdi->itemState & ODS_SELECTED) { textcolor = SetTextColor(lpdi->hDC, orgtextcolor); assert(textcolor != 0x80000000); bkcolor = SetBkColor(lpdi->hDC, orgbkcolor); assert(bkcolor != 0x80000000); } #endif } #ifdef KRB5 /* * * Flags_string * * Return buffer with the current flags for the credential * */ char * flags_string(krb5_creds *cred) { static char buf[32]; int i = 0; buf[i++] = ' '; buf[i++] = '('; if (cred->ticket_flags & TKT_FLG_FORWARDABLE) buf[i++] = 'F'; if (cred->ticket_flags & TKT_FLG_FORWARDED) buf[i++] = 'f'; if (cred->ticket_flags & TKT_FLG_PROXIABLE) buf[i++] = 'P'; if (cred->ticket_flags & TKT_FLG_PROXY) buf[i++] = 'p'; if (cred->ticket_flags & TKT_FLG_MAY_POSTDATE) buf[i++] = 'D'; if (cred->ticket_flags & TKT_FLG_POSTDATED) buf[i++] = 'd'; if (cred->ticket_flags & TKT_FLG_INVALID) buf[i++] = 'i'; if (cred->ticket_flags & TKT_FLG_RENEWABLE) buf[i++] = 'R'; if (cred->ticket_flags & TKT_FLG_INITIAL) buf[i++] = 'I'; if (cred->ticket_flags & TKT_FLG_HW_AUTH) buf[i++] = 'H'; if (cred->ticket_flags & TKT_FLG_PRE_AUTH) buf[i++] = 'A'; buf[i++] = ')'; buf[i] = '\0'; if (i <= 3) buf[0] = '\0'; return(buf); } #endif /* KRB5 */ krb5-1.16/src/windows/include/0000755000704600001450000000000013211554426016102 5ustar ghudsonlibuuidkrb5-1.16/src/windows/include/loadfuncs-krb5.h0000644000704600001450000010405113211554426021073 0ustar ghudsonlibuuid#ifndef __LOADFUNCS_KRB5_H__ #define __LOADFUNCS_KRB5_H__ #include "loadfuncs.h" #include #if defined(_WIN64) #define KRB5_DLL "krb5_64.dll" #else #define KRB5_DLL "krb5_32.dll" #endif TYPEDEF_FUNC( void, KRB5_CALLCONV, krb5_free_principal, (krb5_context, krb5_principal) ); TYPEDEF_FUNC( void, KRB5_CALLCONV, krb5_free_authenticator, (krb5_context, krb5_authenticator * ) ); TYPEDEF_FUNC( void, KRB5_CALLCONV, krb5_free_authenticator_contents, (krb5_context, krb5_authenticator * ) ); TYPEDEF_FUNC( void, KRB5_CALLCONV, krb5_free_addresses, (krb5_context, krb5_address * * ) ); TYPEDEF_FUNC( void, KRB5_CALLCONV, krb5_free_address, (krb5_context, krb5_address * ) ); TYPEDEF_FUNC( void, KRB5_CALLCONV, krb5_free_authdata, (krb5_context, krb5_authdata * * ) ); TYPEDEF_FUNC( void, KRB5_CALLCONV, krb5_free_enc_tkt_part, (krb5_context, krb5_enc_tkt_part * ) ); TYPEDEF_FUNC( void, KRB5_CALLCONV, krb5_free_ticket, (krb5_context, krb5_ticket * ) ); TYPEDEF_FUNC( void, KRB5_CALLCONV, krb5_free_tickets, (krb5_context, krb5_ticket * * ) ); TYPEDEF_FUNC( void, KRB5_CALLCONV, krb5_free_kdc_req, (krb5_context, krb5_kdc_req * ) ); TYPEDEF_FUNC( void, KRB5_CALLCONV, krb5_free_kdc_rep, (krb5_context, krb5_kdc_rep * ) ); TYPEDEF_FUNC( void, KRB5_CALLCONV, krb5_free_last_req, (krb5_context, krb5_last_req_entry * * ) ); TYPEDEF_FUNC( void, KRB5_CALLCONV, krb5_free_enc_kdc_rep_part, (krb5_context, krb5_enc_kdc_rep_part * ) ); TYPEDEF_FUNC( void, KRB5_CALLCONV, krb5_free_error, (krb5_context, krb5_error * ) ); TYPEDEF_FUNC( void, KRB5_CALLCONV, krb5_free_ap_req, (krb5_context, krb5_ap_req * ) ); TYPEDEF_FUNC( void, KRB5_CALLCONV, krb5_free_ap_rep, (krb5_context, krb5_ap_rep * ) ); /* Removed around the time of krb5_rc_* change... */ #if 0 TYPEDEF_FUNC( void, KRB5_CALLCONV, krb5_free_safe, (krb5_context, krb5_safe * ) ); TYPEDEF_FUNC( void, KRB5_CALLCONV, krb5_free_priv, (krb5_context, krb5_priv * ) ); TYPEDEF_FUNC( void, KRB5_CALLCONV, krb5_free_priv_enc_part, (krb5_context, krb5_priv_enc_part * ) ); #endif TYPEDEF_FUNC( void, KRB5_CALLCONV, krb5_free_cred, (krb5_context, krb5_cred *) ); TYPEDEF_FUNC( void, KRB5_CALLCONV, krb5_free_creds, (krb5_context, krb5_creds *) ); TYPEDEF_FUNC( void, KRB5_CALLCONV, krb5_free_cred_contents, (krb5_context, krb5_creds *) ); TYPEDEF_FUNC( void, KRB5_CALLCONV, krb5_free_cred_enc_part, (krb5_context, krb5_cred_enc_part *) ); TYPEDEF_FUNC( void, KRB5_CALLCONV, krb5_free_checksum, (krb5_context, krb5_checksum *) ); TYPEDEF_FUNC( void, KRB5_CALLCONV, krb5_free_checksum_contents, (krb5_context, krb5_checksum *) ); TYPEDEF_FUNC( void, KRB5_CALLCONV, krb5_free_keyblock, (krb5_context, krb5_keyblock *) ); TYPEDEF_FUNC( void, KRB5_CALLCONV, krb5_free_keyblock_contents, (krb5_context, krb5_keyblock *) ); TYPEDEF_FUNC( void, KRB5_CALLCONV, krb5_free_pa_data, (krb5_context, krb5_pa_data * *) ); TYPEDEF_FUNC( void, KRB5_CALLCONV, krb5_free_ap_rep_enc_part, (krb5_context, krb5_ap_rep_enc_part *) ); TYPEDEF_FUNC( void, KRB5_CALLCONV, krb5_free_tkt_authent, (krb5_context, krb5_tkt_authent *) ); TYPEDEF_FUNC( void, KRB5_CALLCONV, krb5_free_data, (krb5_context, krb5_data *) ); TYPEDEF_FUNC( void, KRB5_CALLCONV, krb5_free_data_contents, (krb5_context, krb5_data *) ); TYPEDEF_FUNC( void, KRB5_CALLCONV, krb5_free_unparsed_name, (krb5_context, char *) ); TYPEDEF_FUNC( void, KRB5_CALLCONV, krb5_free_cksumtypes, (krb5_context, krb5_cksumtype *) ); /* ------------------------------------------------------------------------- */ TYPEDEF_FUNC( krb5_error_code, KRB5_CALLCONV, krb5_c_encrypt, (krb5_context context, const krb5_keyblock *key, krb5_keyusage usage, const krb5_data *ivec, const krb5_data *input, krb5_enc_data *output) ); TYPEDEF_FUNC( krb5_error_code, KRB5_CALLCONV, krb5_c_decrypt, (krb5_context context, const krb5_keyblock *key, krb5_keyusage usage, const krb5_data *ivec, const krb5_enc_data *input, krb5_data *output) ); TYPEDEF_FUNC( krb5_error_code, KRB5_CALLCONV, krb5_c_encrypt_length, (krb5_context context, krb5_enctype enctype, size_t inputlen, size_t *length) ); TYPEDEF_FUNC( krb5_error_code, KRB5_CALLCONV, krb5_c_block_size, (krb5_context context, krb5_enctype enctype, size_t *blocksize) ); TYPEDEF_FUNC( krb5_error_code, KRB5_CALLCONV, krb5_c_make_random_key, (krb5_context context, krb5_enctype enctype, krb5_keyblock *random_key) ); TYPEDEF_FUNC( krb5_error_code, KRB5_CALLCONV, krb5_c_random_make_octets, (krb5_context context, krb5_data *data) ); TYPEDEF_FUNC( krb5_error_code, KRB5_CALLCONV, krb5_c_random_seed, (krb5_context context, krb5_data *data) ); TYPEDEF_FUNC( krb5_error_code, KRB5_CALLCONV, krb5_c_string_to_key, (krb5_context context, krb5_enctype enctype, const krb5_data *string, const krb5_data *salt, krb5_keyblock *key) ); TYPEDEF_FUNC( krb5_error_code, KRB5_CALLCONV, krb5_c_enctype_compare, (krb5_context context, krb5_enctype e1, krb5_enctype e2, krb5_boolean *similar) ); TYPEDEF_FUNC( krb5_error_code, KRB5_CALLCONV, krb5_c_make_checksum, (krb5_context context, krb5_cksumtype cksumtype, const krb5_keyblock *key, krb5_keyusage usage, const krb5_data *input, krb5_checksum *cksum) ); TYPEDEF_FUNC( krb5_error_code, KRB5_CALLCONV, krb5_c_verify_checksum, (krb5_context context, const krb5_keyblock *key, krb5_keyusage usage, const krb5_data *data, const krb5_checksum *cksum, krb5_boolean *valid) ); TYPEDEF_FUNC( krb5_error_code, KRB5_CALLCONV, krb5_c_checksum_length, (krb5_context context, krb5_cksumtype cksumtype, size_t *length) ); TYPEDEF_FUNC( krb5_error_code, KRB5_CALLCONV, krb5_c_keyed_checksum_types, (krb5_context context, krb5_enctype enctype, unsigned int *count, krb5_cksumtype **cksumtypes) ); /* ------------------------------------------------------------------------- */ TYPEDEF_FUNC( krb5_boolean, KRB5_CALLCONV, valid_enctype, (const krb5_enctype ktype) ); TYPEDEF_FUNC( krb5_boolean, KRB5_CALLCONV, valid_cksumtype, (const krb5_cksumtype ctype) ); TYPEDEF_FUNC( krb5_boolean, KRB5_CALLCONV, is_coll_proof_cksum, (const krb5_cksumtype ctype) ); TYPEDEF_FUNC( krb5_boolean, KRB5_CALLCONV, is_keyed_cksum, (const krb5_cksumtype ctype) ); /* ------------------------------------------------------------------------- */ TYPEDEF_FUNC( krb5_error_code, KRB5_CALLCONV, krb5_init_context, (krb5_context *) ); TYPEDEF_FUNC( void, KRB5_CALLCONV, krb5_free_context, (krb5_context) ); TYPEDEF_FUNC( krb5_error_code, KRB5_CALLCONV, krb5_decrypt_tkt_part, (krb5_context, const krb5_keyblock *, krb5_ticket * ) ); TYPEDEF_FUNC( void, KRB5_CALLCONV, krb5_free_tgt_creds, (krb5_context, krb5_creds ** ) ); TYPEDEF_FUNC( krb5_error_code, KRB5_CALLCONV, krb5_get_credentials, (krb5_context, const krb5_flags, krb5_ccache, krb5_creds *, krb5_creds * *) ); TYPEDEF_FUNC( krb5_error_code, KRB5_CALLCONV, krb5_get_credentials_validate, (krb5_context, const krb5_flags, krb5_ccache, krb5_creds *, krb5_creds * *) ); TYPEDEF_FUNC( krb5_error_code, KRB5_CALLCONV, krb5_get_credentials_renew, (krb5_context, const krb5_flags, krb5_ccache, krb5_creds *, krb5_creds * *) ); TYPEDEF_FUNC( krb5_error_code, KRB5_CALLCONV, krb5_mk_req, (krb5_context, krb5_auth_context *, const krb5_flags, char *, char *, krb5_data *, krb5_ccache, krb5_data * ) ); TYPEDEF_FUNC( krb5_error_code, KRB5_CALLCONV, krb5_mk_req_extended, (krb5_context, krb5_auth_context *, const krb5_flags, krb5_data *, krb5_creds *, krb5_data * ) ); TYPEDEF_FUNC( krb5_error_code, KRB5_CALLCONV, krb5_mk_rep, (krb5_context, krb5_auth_context, krb5_data *) ); TYPEDEF_FUNC( krb5_error_code, KRB5_CALLCONV, krb5_rd_rep, (krb5_context, krb5_auth_context, const krb5_data *, krb5_ap_rep_enc_part * *) ); TYPEDEF_FUNC( krb5_error_code, KRB5_CALLCONV, krb5_mk_error, (krb5_context, const krb5_error *, krb5_data * ) ); TYPEDEF_FUNC( krb5_error_code, KRB5_CALLCONV, krb5_rd_error, (krb5_context, const krb5_data *, krb5_error * * ) ); TYPEDEF_FUNC( krb5_error_code, KRB5_CALLCONV, krb5_rd_safe, (krb5_context, krb5_auth_context, const krb5_data *, krb5_data *, krb5_replay_data *) ); TYPEDEF_FUNC( krb5_error_code, KRB5_CALLCONV, krb5_rd_priv, (krb5_context, krb5_auth_context, const krb5_data *, krb5_data *, krb5_replay_data *) ); TYPEDEF_FUNC( krb5_error_code, KRB5_CALLCONV, krb5_parse_name, (krb5_context, const char *, krb5_principal * ) ); TYPEDEF_FUNC( krb5_error_code, KRB5_CALLCONV, krb5_unparse_name, (krb5_context, krb5_const_principal, char * * ) ); TYPEDEF_FUNC( krb5_error_code, KRB5_CALLCONV, krb5_unparse_name_ext, (krb5_context, krb5_const_principal, char * *, int *) ); TYPEDEF_FUNC( krb5_error_code, KRB5_CALLCONV, krb5_set_principal_realm, (krb5_context, krb5_principal, const char *) ); TYPEDEF_FUNC( krb5_boolean, KRB5_CALLCONV, krb5_principal_compare, (krb5_context, krb5_const_principal, krb5_const_principal) ); TYPEDEF_FUNC( krb5_error_code, KRB5_CALLCONV, krb5_copy_keyblock, (krb5_context, const krb5_keyblock *, krb5_keyblock * *) ); TYPEDEF_FUNC( krb5_error_code, KRB5_CALLCONV, krb5_copy_keyblock_contents, (krb5_context, const krb5_keyblock *, krb5_keyblock *) ); TYPEDEF_FUNC( krb5_error_code, KRB5_CALLCONV, krb5_copy_creds, (krb5_context, const krb5_creds *, krb5_creds * *) ); TYPEDEF_FUNC( krb5_error_code, KRB5_CALLCONV, krb5_copy_data, (krb5_context, const krb5_data *, krb5_data * *) ); TYPEDEF_FUNC( krb5_error_code, KRB5_CALLCONV, krb5_copy_principal, (krb5_context, krb5_const_principal, krb5_principal *) ); TYPEDEF_FUNC( krb5_error_code, KRB5_CALLCONV, krb5_copy_addr, (krb5_context, const krb5_address *, krb5_address * *) ); TYPEDEF_FUNC( krb5_error_code, KRB5_CALLCONV, krb5_copy_addresses, (krb5_context, krb5_address * const *, krb5_address * * *) ); TYPEDEF_FUNC( krb5_error_code, KRB5_CALLCONV, krb5_copy_ticket, (krb5_context, const krb5_ticket *, krb5_ticket * *) ); TYPEDEF_FUNC( krb5_error_code, KRB5_CALLCONV, krb5_copy_authdata, (krb5_context, krb5_authdata * const *, krb5_authdata * * *) ); TYPEDEF_FUNC( krb5_error_code, KRB5_CALLCONV, krb5_copy_authenticator, (krb5_context, const krb5_authenticator *, krb5_authenticator * *) ); TYPEDEF_FUNC( krb5_error_code, KRB5_CALLCONV, krb5_copy_checksum, (krb5_context, const krb5_checksum *, krb5_checksum * *) ); TYPEDEF_FUNC( krb5_error_code, KRB5_CALLCONV, krb5_get_server_rcache, (krb5_context, const krb5_data *, krb5_rcache *) ); TYPEDEF_FUNC( krb5_error_code, KRB5_CALLCONV_C, krb5_build_principal_ext, (krb5_context, krb5_principal *, int, const char *, ...) ); TYPEDEF_FUNC( krb5_error_code, KRB5_CALLCONV_C, krb5_build_principal, (krb5_context, krb5_principal *, int, const char *, ...) ); TYPEDEF_FUNC( krb5_error_code, KRB5_CALLCONV, krb5_425_conv_principal, (krb5_context, const char *name, const char *instance, const char *realm, krb5_principal *princ) ); TYPEDEF_FUNC( krb5_error_code, KRB5_CALLCONV, krb5_524_conv_principal, (krb5_context context, const krb5_principal princ, char *name, char *inst, char *realm) ); TYPEDEF_FUNC( krb5_error_code, KRB5_CALLCONV, krb5_mk_chpw_req, (krb5_context context, krb5_auth_context auth_context, krb5_data *ap_req, char *passwd, krb5_data *packet) ); TYPEDEF_FUNC( krb5_error_code, KRB5_CALLCONV, krb5_rd_chpw_rep, (krb5_context context, krb5_auth_context auth_context, krb5_data *packet, int *result_code, krb5_data *result_data) ); TYPEDEF_FUNC( krb5_error_code, KRB5_CALLCONV, krb5_chpw_result_code_string, (krb5_context context, int result_code, char **result_codestr) ); TYPEDEF_FUNC( krb5_error_code, KRB5_CALLCONV, krb5_kt_register, (krb5_context, struct _krb5_kt_ops * ) ); TYPEDEF_FUNC( krb5_error_code, KRB5_CALLCONV, krb5_kt_resolve, (krb5_context, const char *, krb5_keytab * ) ); TYPEDEF_FUNC( krb5_error_code, KRB5_CALLCONV, krb5_kt_default_name, (krb5_context, char *, int ) ); TYPEDEF_FUNC( krb5_error_code, KRB5_CALLCONV, krb5_kt_default, (krb5_context, krb5_keytab * ) ); TYPEDEF_FUNC( krb5_error_code, KRB5_CALLCONV, krb5_kt_free_entry, (krb5_context, krb5_keytab_entry * ) ); TYPEDEF_FUNC( krb5_error_code, KRB5_CALLCONV, krb5_kt_remove_entry, (krb5_context, krb5_keytab, krb5_keytab_entry * ) ); TYPEDEF_FUNC( krb5_error_code, KRB5_CALLCONV, krb5_kt_add_entry, (krb5_context, krb5_keytab, krb5_keytab_entry * ) ); TYPEDEF_FUNC( krb5_error_code, KRB5_CALLCONV, krb5_cc_resolve, (krb5_context, const char *, krb5_ccache * ) ); TYPEDEF_FUNC( const char*, KRB5_CALLCONV, krb5_cc_default_name, (krb5_context) ); TYPEDEF_FUNC( krb5_error_code, KRB5_CALLCONV, krb5_cc_set_default_name, (krb5_context, const char *) ); TYPEDEF_FUNC( krb5_error_code, KRB5_CALLCONV, krb5_cc_default, (krb5_context, krb5_ccache *) ); TYPEDEF_FUNC( unsigned int, KRB5_CALLCONV, krb5_get_notification_message, (void) ); TYPEDEF_FUNC( krb5_error_code, KRB5_CALLCONV, krb5_cc_copy_creds, (krb5_context context, krb5_ccache incc, krb5_ccache outcc) ); TYPEDEF_FUNC( krb5_error_code, KRB5_CALLCONV, krb5_us_timeofday, (krb5_context, krb5_int32 *, krb5_int32 * ) ); TYPEDEF_FUNC( krb5_error_code, KRB5_CALLCONV, krb5_timeofday, (krb5_context, krb5_int32 * ) ); TYPEDEF_FUNC( krb5_error_code, KRB5_CALLCONV, krb5_os_localaddr, (krb5_context, krb5_address * * *) ); TYPEDEF_FUNC( krb5_error_code, KRB5_CALLCONV, krb5_get_default_realm, (krb5_context, char * * ) ); TYPEDEF_FUNC( krb5_error_code, KRB5_CALLCONV, krb5_set_default_realm, (krb5_context, const char * ) ); TYPEDEF_FUNC( krb5_error_code, KRB5_CALLCONV, krb5_free_default_realm, (krb5_context, const char * ) ); TYPEDEF_FUNC( krb5_error_code, KRB5_CALLCONV, krb5_sname_to_principal, (krb5_context, const char *, const char *, krb5_int32, krb5_principal *) ); TYPEDEF_FUNC( krb5_error_code, KRB5_CALLCONV, krb5_change_password, (krb5_context context, krb5_creds *creds, char *newpw, int *result_code, krb5_data *result_code_string, krb5_data *result_string) ); TYPEDEF_FUNC( krb5_error_code, KRB5_CALLCONV, krb5_get_default_config_files, (char ***filenames) ); TYPEDEF_FUNC( void, KRB5_CALLCONV, krb5_free_config_files, (char **filenames) ); TYPEDEF_FUNC( krb5_error_code, KRB5_CALLCONV, krb5_get_in_tkt, (krb5_context, const krb5_flags, krb5_address * const *, krb5_enctype *, krb5_preauthtype *, krb5_error_code ( * )(krb5_context, const krb5_enctype, krb5_data *, krb5_const_pointer, krb5_keyblock * *), krb5_const_pointer, krb5_error_code ( * )(krb5_context, const krb5_keyblock *, krb5_const_pointer, krb5_kdc_rep * ), krb5_const_pointer, krb5_creds *, krb5_ccache, krb5_kdc_rep * * ) ); TYPEDEF_FUNC( krb5_error_code, KRB5_CALLCONV, krb5_get_in_tkt_with_password, (krb5_context, const krb5_flags, krb5_address * const *, krb5_enctype *, krb5_preauthtype *, const char *, krb5_ccache, krb5_creds *, krb5_kdc_rep * * ) ); TYPEDEF_FUNC( krb5_error_code, KRB5_CALLCONV, krb5_get_in_tkt_with_skey, (krb5_context, const krb5_flags, krb5_address * const *, krb5_enctype *, krb5_preauthtype *, const krb5_keyblock *, krb5_ccache, krb5_creds *, krb5_kdc_rep * * ) ); TYPEDEF_FUNC( krb5_error_code, KRB5_CALLCONV, krb5_get_in_tkt_with_keytab, (krb5_context, const krb5_flags, krb5_address * const *, krb5_enctype *, krb5_preauthtype *, const krb5_keytab, krb5_ccache, krb5_creds *, krb5_kdc_rep * * ) ); TYPEDEF_FUNC( krb5_error_code, KRB5_CALLCONV, krb5_rd_req, (krb5_context, krb5_auth_context *, const krb5_data *, krb5_const_principal, krb5_keytab, krb5_flags *, krb5_ticket * *) ); TYPEDEF_FUNC( krb5_error_code, KRB5_CALLCONV, krb5_kt_read_service_key, (krb5_context, krb5_pointer, krb5_principal, krb5_kvno, krb5_enctype, krb5_keyblock * *) ); TYPEDEF_FUNC( krb5_error_code, KRB5_CALLCONV, krb5_mk_safe, (krb5_context, krb5_auth_context, const krb5_data *, krb5_data *, krb5_replay_data *) ); TYPEDEF_FUNC( krb5_error_code, KRB5_CALLCONV, krb5_mk_priv, (krb5_context, krb5_auth_context, const krb5_data *, krb5_data *, krb5_replay_data *) ); TYPEDEF_FUNC( krb5_error_code, KRB5_CALLCONV, krb5_cc_register, (krb5_context, krb5_cc_ops *, krb5_boolean ) ); TYPEDEF_FUNC( krb5_error_code, KRB5_CALLCONV, krb5_sendauth, (krb5_context, krb5_auth_context *, krb5_pointer, char *, krb5_principal, krb5_principal, krb5_flags, krb5_data *, krb5_creds *, krb5_ccache, krb5_error * *, krb5_ap_rep_enc_part * *, krb5_creds * *) ); TYPEDEF_FUNC( krb5_error_code, KRB5_CALLCONV, krb5_recvauth, (krb5_context, krb5_auth_context *, krb5_pointer, char *, krb5_principal, krb5_int32, krb5_keytab, krb5_ticket * *) ); TYPEDEF_FUNC( krb5_error_code, KRB5_CALLCONV, krb5_mk_ncred, (krb5_context, krb5_auth_context, krb5_creds * *, krb5_data * *, krb5_replay_data *) ); TYPEDEF_FUNC( krb5_error_code, KRB5_CALLCONV, krb5_mk_1cred, (krb5_context, krb5_auth_context, krb5_creds *, krb5_data * *, krb5_replay_data *) ); TYPEDEF_FUNC( krb5_error_code, KRB5_CALLCONV, krb5_rd_cred, (krb5_context, krb5_auth_context, krb5_data *, krb5_creds * * *, krb5_replay_data *) ); TYPEDEF_FUNC( krb5_error_code, KRB5_CALLCONV, krb5_fwd_tgt_creds, (krb5_context, krb5_auth_context, char *, krb5_principal, krb5_principal, krb5_ccache, int forwardable, krb5_data *) ); TYPEDEF_FUNC( krb5_error_code, KRB5_CALLCONV, krb5_auth_con_init, (krb5_context, krb5_auth_context *) ); TYPEDEF_FUNC( krb5_error_code, KRB5_CALLCONV, krb5_auth_con_free, (krb5_context, krb5_auth_context) ); TYPEDEF_FUNC( krb5_error_code, KRB5_CALLCONV, krb5_auth_con_setflags, (krb5_context, krb5_auth_context, krb5_int32) ); TYPEDEF_FUNC( krb5_error_code, KRB5_CALLCONV, krb5_auth_con_getflags, (krb5_context, krb5_auth_context, krb5_int32 *) ); TYPEDEF_FUNC( krb5_error_code, KRB5_CALLCONV, krb5_auth_con_setuseruserkey, (krb5_context, krb5_auth_context, krb5_keyblock *) ); TYPEDEF_FUNC( krb5_error_code, KRB5_CALLCONV, krb5_auth_con_getkey, (krb5_context, krb5_auth_context, krb5_keyblock **) ); TYPEDEF_FUNC( krb5_error_code, KRB5_CALLCONV, krb5_auth_con_getlocalsubkey, (krb5_context, krb5_auth_context, krb5_keyblock * *) ); TYPEDEF_FUNC( krb5_error_code, KRB5_CALLCONV, krb5_auth_con_set_req_cksumtype, (krb5_context, krb5_auth_context, krb5_cksumtype) ); TYPEDEF_FUNC( krb5_error_code, KRB5_CALLCONV, krb5_auth_con_getlocalseqnumber, (krb5_context, krb5_auth_context, krb5_int32 *) ); TYPEDEF_FUNC( krb5_error_code, KRB5_CALLCONV, krb5_auth_con_getremoteseqnumber, (krb5_context, krb5_auth_context, krb5_int32 *) ); TYPEDEF_FUNC( krb5_error_code, KRB5_CALLCONV, krb5_auth_con_setrcache, (krb5_context, krb5_auth_context, krb5_rcache) ); TYPEDEF_FUNC( krb5_error_code, KRB5_CALLCONV, krb5_auth_con_getauthenticator, (krb5_context, krb5_auth_context, krb5_authenticator * *) ); TYPEDEF_FUNC( krb5_error_code, KRB5_CALLCONV, krb5_auth_con_getremotesubkey, (krb5_context, krb5_auth_context, krb5_keyblock * *) ); TYPEDEF_FUNC( krb5_error_code, KRB5_CALLCONV, krb5_read_password, (krb5_context, const char *, const char *, char *, int * ) ); TYPEDEF_FUNC( krb5_error_code, KRB5_CALLCONV, krb5_get_host_realm, (krb5_context, const char *, char * * * ) ); TYPEDEF_FUNC( krb5_error_code, KRB5_CALLCONV, krb5_free_host_realm, (krb5_context, char * const * ) ); TYPEDEF_FUNC( krb5_error_code, KRB5_CALLCONV, krb5_get_realm_domain, (krb5_context, const char *, char ** ) ); TYPEDEF_FUNC( krb5_error_code, KRB5_CALLCONV, krb5_auth_con_genaddrs, (krb5_context, krb5_auth_context, int, int) ); /* ------------------------------------------------------------------------- */ TYPEDEF_FUNC( krb5_error_code, KRB5_CALLCONV, krb5_string_to_enctype, (char *, krb5_enctype *) ); TYPEDEF_FUNC( krb5_error_code, KRB5_CALLCONV, krb5_string_to_salttype, (char *, krb5_int32 *) ); TYPEDEF_FUNC( krb5_error_code, KRB5_CALLCONV, krb5_string_to_cksumtype, (char *, krb5_cksumtype *) ); TYPEDEF_FUNC( krb5_error_code, KRB5_CALLCONV, krb5_string_to_timestamp, (char *, krb5_timestamp *) ); TYPEDEF_FUNC( krb5_error_code, KRB5_CALLCONV, krb5_string_to_deltat, (char *, krb5_deltat *) ); TYPEDEF_FUNC( krb5_error_code, KRB5_CALLCONV, krb5_enctype_to_string, (krb5_enctype, char *, size_t) ); TYPEDEF_FUNC( krb5_error_code, KRB5_CALLCONV, krb5_enctype_to_name, (krb5_enctype, krb5_boolean, char *, size_t) ); TYPEDEF_FUNC( krb5_error_code, KRB5_CALLCONV, krb5_salttype_to_string, (krb5_int32, char *, size_t) ); TYPEDEF_FUNC( krb5_error_code, KRB5_CALLCONV, krb5_cksumtype_to_string, (krb5_cksumtype, char *, size_t) ); TYPEDEF_FUNC( krb5_error_code, KRB5_CALLCONV, krb5_timestamp_to_string, (krb5_timestamp, char *, size_t) ); TYPEDEF_FUNC( krb5_error_code, KRB5_CALLCONV, krb5_timestamp_to_sfstring, (krb5_timestamp, char *, size_t, char *) ); TYPEDEF_FUNC( krb5_error_code, KRB5_CALLCONV, krb5_deltat_to_string, (krb5_deltat, char *, size_t) ); /* ------------------------------------------------------------------------- */ TYPEDEF_FUNC( krb5_error_code, KRB5_CALLCONV, krb5_prompter_posix, (krb5_context context, void *data, const char *name, const char *banner, int num_prompts, krb5_prompt prompts[]) ); TYPEDEF_FUNC( krb5_error_code, KRB5_CALLCONV, krb5_get_init_creds_opt_alloc, (krb5_context ctx, krb5_get_init_creds_opt **opt) ); TYPEDEF_FUNC( void, KRB5_CALLCONV, krb5_get_init_creds_opt_free, (krb5_context ctx, krb5_get_init_creds_opt *opt) ); TYPEDEF_FUNC( void, KRB5_CALLCONV, krb5_get_init_creds_opt_init, (krb5_get_init_creds_opt *opt) ); TYPEDEF_FUNC( void, KRB5_CALLCONV, krb5_get_init_creds_opt_set_tkt_life, (krb5_get_init_creds_opt *opt, krb5_deltat tkt_life) ); TYPEDEF_FUNC( void, KRB5_CALLCONV, krb5_get_init_creds_opt_set_renew_life, (krb5_get_init_creds_opt *opt, krb5_deltat renew_life) ); TYPEDEF_FUNC( void, KRB5_CALLCONV, krb5_get_init_creds_opt_set_forwardable, (krb5_get_init_creds_opt *opt, int forwardable) ); TYPEDEF_FUNC( void, KRB5_CALLCONV, krb5_get_init_creds_opt_set_proxiable, (krb5_get_init_creds_opt *opt, int proxiable) ); TYPEDEF_FUNC( void, KRB5_CALLCONV, krb5_get_init_creds_opt_set_etype_list, (krb5_get_init_creds_opt *opt, krb5_enctype *etype_list, int etype_list_length) ); TYPEDEF_FUNC( void, KRB5_CALLCONV, krb5_get_init_creds_opt_set_address_list, (krb5_get_init_creds_opt *opt, krb5_address **addresses) ); TYPEDEF_FUNC( void, KRB5_CALLCONV, krb5_get_init_creds_opt_set_preauth_list, (krb5_get_init_creds_opt *opt, krb5_preauthtype *preauth_list, int preauth_list_length) ); TYPEDEF_FUNC( void, KRB5_CALLCONV, krb5_get_init_creds_opt_set_salt, (krb5_get_init_creds_opt *opt, krb5_data *salt) ); TYPEDEF_FUNC( void, KRB5_CALLCONV, krb5_get_init_creds_opt_set_change_password_prompt, (krb5_get_init_creds_opt *opt, int prompt) ); TYPEDEF_FUNC( krb5_error_code, KRB5_CALLCONV, krb5_get_init_creds_opt_set_out_ccache, (krb5_context context, krb5_get_init_creds_opt *opt, krb5_ccache ccache) ); TYPEDEF_FUNC( krb5_error_code, KRB5_CALLCONV, krb5_get_init_creds_password, (krb5_context context, krb5_creds *creds, krb5_principal client, char *password, krb5_prompter_fct prompter, void *data, krb5_deltat start_time, char *in_tkt_service, krb5_get_init_creds_opt *options) ); TYPEDEF_FUNC( krb5_error_code, KRB5_CALLCONV, krb5_get_init_creds_keytab, (krb5_context context, krb5_creds *creds, krb5_principal client, krb5_keytab arg_keytab, krb5_deltat start_time, char *in_tkt_service, krb5_get_init_creds_opt *options) ); TYPEDEF_FUNC( void, KRB5_CALLCONV, krb5_verify_init_creds_opt_init, (krb5_verify_init_creds_opt *options) ); TYPEDEF_FUNC( void, KRB5_CALLCONV, krb5_verify_init_creds_opt_set_ap_req_nofail, (krb5_verify_init_creds_opt *options, int ap_req_nofail) ); TYPEDEF_FUNC( krb5_error_code, KRB5_CALLCONV, krb5_verify_init_creds, (krb5_context context, krb5_creds *creds, krb5_principal ap_req_server, krb5_keytab ap_req_keytab, krb5_ccache *ccache, krb5_verify_init_creds_opt *options) ); TYPEDEF_FUNC( krb5_error_code, KRB5_CALLCONV, krb5_get_validated_creds, (krb5_context context, krb5_creds *creds, krb5_principal client, krb5_ccache ccache, char *in_tkt_service) ); TYPEDEF_FUNC( krb5_error_code, KRB5_CALLCONV, krb5_get_renewed_creds, (krb5_context context, krb5_creds *creds, krb5_principal client, krb5_ccache ccache, char *in_tkt_service) ); /* ------------------------------------------------------------------------- */ TYPEDEF_FUNC( krb5_prompt_type*, KRB5_CALLCONV, krb5_get_prompt_types, (krb5_context context) ); /* NOT IN krb5.h HEADER: */ TYPEDEF_FUNC( krb5_error_code, KRB5_CALLCONV, krb5_decode_ticket, (const krb5_data *code, krb5_ticket **rep) ); /* --- more --- */ TYPEDEF_FUNC( char *, KRB5_CALLCONV, krb5_cc_get_name, (krb5_context context, krb5_ccache cache) ); TYPEDEF_FUNC( krb5_error_code, KRB5_CALLCONV, krb5_cc_gen_new, (krb5_context context, krb5_ccache *cache) ); TYPEDEF_FUNC( krb5_error_code, KRB5_CALLCONV, krb5_cc_initialize, (krb5_context context, krb5_ccache cache, krb5_principal principal) ); TYPEDEF_FUNC( krb5_error_code, KRB5_CALLCONV, krb5_cc_destroy, (krb5_context context, krb5_ccache cache) ); TYPEDEF_FUNC( krb5_error_code, KRB5_CALLCONV, krb5_cc_close, (krb5_context context, krb5_ccache cache) ); TYPEDEF_FUNC( krb5_error_code, KRB5_CALLCONV, krb5_cc_store_cred, (krb5_context context, krb5_ccache cache, krb5_creds *creds) ); TYPEDEF_FUNC( krb5_error_code, KRB5_CALLCONV, krb5_cc_retrieve_cred, (krb5_context context, krb5_ccache cache, krb5_flags flags, krb5_creds *mcreds, krb5_creds *creds) ); TYPEDEF_FUNC( krb5_error_code, KRB5_CALLCONV, krb5_cc_get_principal, (krb5_context context, krb5_ccache cache, krb5_principal *principal) ); TYPEDEF_FUNC( krb5_error_code, KRB5_CALLCONV, krb5_cc_start_seq_get, (krb5_context context, krb5_ccache cache, krb5_cc_cursor *cursor) ); TYPEDEF_FUNC( krb5_error_code, KRB5_CALLCONV, krb5_cc_next_cred, (krb5_context context, krb5_ccache cache, krb5_cc_cursor *cursor, krb5_creds *creds) ); TYPEDEF_FUNC( krb5_error_code, KRB5_CALLCONV, krb5_cc_end_seq_get, (krb5_context context, krb5_ccache cache, krb5_cc_cursor *cursor) ); TYPEDEF_FUNC( krb5_error_code, KRB5_CALLCONV, krb5_cc_remove_cred, (krb5_context context, krb5_ccache cache, krb5_flags flags, krb5_creds *creds) ); TYPEDEF_FUNC( krb5_error_code, KRB5_CALLCONV, krb5_cc_set_flags, (krb5_context context, krb5_ccache cache, krb5_flags flags) ); TYPEDEF_FUNC( const char *, KRB5_CALLCONV, krb5_cc_get_type, (krb5_context context, krb5_ccache cache) ); TYPEDEF_FUNC( krb5_error_code, KRB5_CALLCONV, krb5_cc_get_full_name, (krb5_context context, krb5_ccache cache, char **) ); TYPEDEF_FUNC( char *, KRB5_CALLCONV, krb5_kt_get_type, (krb5_context, krb5_keytab keytab) ); TYPEDEF_FUNC( krb5_error_code, KRB5_CALLCONV, krb5_kt_get_name, (krb5_context context, krb5_keytab keytab, char *name, unsigned int namelen) ); TYPEDEF_FUNC( krb5_error_code, KRB5_CALLCONV, krb5_kt_close, (krb5_context context, krb5_keytab keytab) ); TYPEDEF_FUNC( krb5_error_code, KRB5_CALLCONV, krb5_kt_get_entry, (krb5_context context, krb5_keytab keytab, krb5_const_principal principal, krb5_kvno vno, krb5_enctype enctype, krb5_keytab_entry *entry) ); TYPEDEF_FUNC( krb5_error_code, KRB5_CALLCONV, krb5_kt_start_seq_get, (krb5_context context, krb5_keytab keytab, krb5_kt_cursor *cursor) ); TYPEDEF_FUNC( krb5_error_code, KRB5_CALLCONV, krb5_kt_next_entry, (krb5_context context, krb5_keytab keytab, krb5_keytab_entry *entry, krb5_kt_cursor *cursor) ); TYPEDEF_FUNC( krb5_error_code, KRB5_CALLCONV, krb5_kt_end_seq_get, (krb5_context context, krb5_keytab keytab, krb5_kt_cursor *cursor) ); TYPEDEF_FUNC( krb5_error_code, KRB5_CALLCONV, krb5_locate_kdc, (krb5_context context, const krb5_data *realm, struct addrlist *addrlist, int get_masters, int socktype, int family) ); TYPEDEF_FUNC( const char *, KRB5_CALLCONV, krb5_get_error_message, (krb5_context, krb5_error_code) ); TYPEDEF_FUNC( void, KRB5_CALLCONV, krb5_free_error_message, (krb5_context, const char *) ); TYPEDEF_FUNC( void, KRB5_CALLCONV, krb5_clear_error_message, (krb5_context) ); TYPEDEF_FUNC( krb5_boolean, KRB5_CALLCONV, krb5_is_config_principal, (krb5_context, krb5_const_principal) ); TYPEDEF_FUNC( krb5_error_code, KRB5_CALLCONV, krb5_cccol_cursor_new, (krb5_context, krb5_cccol_cursor *) ); TYPEDEF_FUNC( krb5_error_code, KRB5_CALLCONV, krb5_cccol_cursor_next, (krb5_context, krb5_cccol_cursor cursor, krb5_ccache *) ); TYPEDEF_FUNC( krb5_error_code, KRB5_CALLCONV, krb5_cccol_cursor_free, (krb5_context, krb5_cccol_cursor *cursor) ); TYPEDEF_FUNC( krb5_error_code, KRB5_CALLCONV, krb5_cc_cache_match, (krb5_context, krb5_principal, krb5_ccache *) ); TYPEDEF_FUNC( krb5_error_code, KRB5_CALLCONV, krb5_cc_new_unique, (krb5_context, const char *, const char *, krb5_ccache *) ); TYPEDEF_FUNC( krb5_boolean, KRB5_CALLCONV, krb5_cc_support_switch, (krb5_context, const char *) ); TYPEDEF_FUNC( krb5_error_code, KRB5_CALLCONV, krb5_cc_switch, (krb5_context, krb5_ccache) ); TYPEDEF_FUNC( void, KRB5_CALLCONV, krb5_free_string, (krb5_context, char *) ); TYPEDEF_FUNC( krb5_error_code, KRB5_CALLCONV, krb5int_cc_user_set_default_name, (krb5_context context, const char *) ); #endif /* __LOADFUNCS_KRB5_H__ */ krb5-1.16/src/windows/include/loadfuncs.h0000644000704600001450000000165713211554426020242 0ustar ghudsonlibuuid#ifndef __LOADFUNCS_H__ #define __LOADFUNCS_H__ #ifdef __cplusplus extern "C" { #endif #include typedef struct _FUNC_INFO { void** func_ptr_var; char* func_name; } FUNC_INFO; #define DECL_FUNC_PTR(x) FP_##x p##x #define MAKE_FUNC_INFO(x) { (void**) &p##x, #x } #define END_FUNC_INFO { 0, 0 } #define TYPEDEF_FUNC(ret, call, name, args) typedef ret (call *FP_##name) args void UnloadFuncs( FUNC_INFO fi[], HINSTANCE h ); int LoadFuncs( const char* dll_name, FUNC_INFO fi[], HINSTANCE* ph, // [out, optional] - DLL handle int* pindex, // [out, optional] - index of last func loaded (-1 if none) int cleanup, // cleanup function pointers and unload on error int go_on, // continue loading even if some functions cannot be loaded int silent // do not pop-up a system dialog if DLL cannot be loaded ); #ifdef __cplusplus } #endif #endif /* __LOADFUNCS_H__ */ krb5-1.16/src/windows/include/leashwin.h0000644000704600001450000001622713211554426020075 0ustar ghudsonlibuuid#ifndef __LEASHWIN__ #define __LEASHWIN__ ////Is this sufficient? #ifndef NO_KRB4 #include #else #include #define ANAME_SZ 40 #define REALM_SZ 40 #define SNAME_SZ 40 #define INST_SZ 40 /* include space for '.' and '@' */ #define MAX_K_NAME_SZ (ANAME_SZ + INST_SZ + REALM_SZ + 2) #endif #define DLGTYPE_PASSWD 0 #define DLGTYPE_CHPASSWD 1 #define DLGTYPE_MASK 0x0000ffff #define DLGFLAG_READONLYPRINC 0x10000 typedef struct { int dlgtype; // Tells whether dialog box is in change pwd more or init ticket mode??? // (verify this): int dlgstatemax; // What is this??? // The title on the Dialog box - for Renewing or Initializing: LPSTR title; LPSTR principal; } LSH_DLGINFO, FAR *LPLSH_DLGINFO; #define LEASH_USERNAME_SZ 64 #define LEASH_REALM_SZ 192 #define LEASH_TITLE_SZ 128 #define LEASH_CCACHE_NAME_SZ 264 typedef struct { DWORD size; int dlgtype; // Tells whether dialog box is in change pwd mode or init ticket mode LPSTR title; // in v3, set to in.title LPSTR username; // in v3, set to in.username LPSTR realm; // in v3, set to in.realm int use_defaults; int forwardable; int noaddresses; int lifetime; int renew_till; int proxiable; int publicip; // Version 1 of this structure ends here struct { char username[LEASH_USERNAME_SZ]; char realm[LEASH_REALM_SZ]; // Version 2 of this structure ends here char ccache[LEASH_CCACHE_NAME_SZ]; } out; struct { char title[LEASH_TITLE_SZ]; char username[LEASH_USERNAME_SZ]; char realm[LEASH_REALM_SZ]; char ccache[LEASH_CCACHE_NAME_SZ]; } in; } LSH_DLGINFO_EX, *LPLSH_DLGINFO_EX; #define LSH_DLGINFO_EX_V1_SZ (sizeof(DWORD) + 3 * sizeof(LPSTR) + 8 * sizeof(int)) #define LSH_DLGINFO_EX_V2_SZ (LSH_DLGINFO_EX_V1_SZ + LEASH_USERNAME_SZ + LEASH_REALM_SZ) #define LSH_DLGINFO_EX_V3_SZ (LSH_DLGINFO_EX_V2_SZ + LEASH_TITLE_SZ + LEASH_USERNAME_SZ + LEASH_REALM_SZ + 2 * LEASH_CCACHE_NAME_SZ) #ifndef NETIDMGR #define NETID_USERNAME_SZ 128 #define NETID_REALM_SZ 192 #define NETID_TITLE_SZ 256 #define NETID_CCACHE_NAME_SZ 264 #define NETID_DLGTYPE_TGT 0 #define NETID_DLGTYPE_CHPASSWD 1 typedef struct { DWORD size; DWORD dlgtype; // Tells whether dialog box is in change pwd mode or init ticket mode struct { WCHAR title[NETID_TITLE_SZ]; WCHAR username[NETID_USERNAME_SZ]; WCHAR realm[NETID_REALM_SZ]; WCHAR ccache[NETID_CCACHE_NAME_SZ]; DWORD use_defaults; DWORD forwardable; DWORD noaddresses; DWORD lifetime; DWORD renew_till; DWORD proxiable; DWORD publicip; DWORD must_use_specified_principal; } in; struct { WCHAR username[NETID_USERNAME_SZ]; WCHAR realm[NETID_REALM_SZ]; WCHAR ccache[NETID_CCACHE_NAME_SZ]; } out; // Version 1 of this structure ends here } NETID_DLGINFO, *LPNETID_DLGINFO; #define NETID_DLGINFO_V1_SZ (10 * sizeof(DWORD) \ + sizeof(WCHAR) * (NETID_TITLE_SZ + \ 2 * NETID_USERNAME_SZ + 2 * NETID_REALM_SZ + \ 2 * NETID_CCACHE_NAME_SZ)) #endif /* NETIDMGR */ typedef struct TicketList TicketList; struct TicketList { TicketList *next; char *service; char *encTypes; time_t issued; time_t valid_until; time_t renew_until; unsigned long flags; }; typedef struct TICKETINFO TICKETINFO; struct TICKETINFO { TICKETINFO *next; char *principal; /* Principal name/instance@realm */ char *ccache_name; TicketList *ticket_list; int btickets; /* Do we have tickets? */ time_t issued; /* The issue time */ time_t valid_until; /* */ time_t renew_until; /* The Renew time (k5 only) */ unsigned long flags; }; #ifdef __cplusplus extern "C" { #endif int FAR Leash_kinit_dlg(HWND hParent, LPLSH_DLGINFO lpdlginfo); int FAR Leash_kinit_dlg_ex(HWND hParent, LPLSH_DLGINFO_EX lpdlginfoex); int FAR Leash_changepwd_dlg(HWND hParent, LPLSH_DLGINFO lpdlginfo); int FAR Leash_changepwd_dlg_ex(HWND hParent, LPLSH_DLGINFO_EX lpdlginfo); long FAR Leash_checkpwd(char *principal, char *password); long FAR Leash_changepwd(char *principal, char *password, char *newpassword, char** result_string); long FAR Leash_kinit(char *principal, char *password, int lifetime); long FAR Leash_kinit_ex(char * principal, char * password, int lifetime, int forwardable, int proxiable, int renew_life, int addressless, unsigned long publicIP); long FAR Leash_klist(HWND hlist, TICKETINFO FAR *ticketinfo); long FAR Leash_kdestroy(void); long FAR Leash_get_lsh_errno( LONG FAR *err_val); long FAR Leash_renew(void); long FAR Leash_importable(void); long FAR Leash_import(void); BOOL Leash_set_help_file( char FAR *szHelpFile ); LPSTR Leash_get_help_file(void); void Leash_reset_defaults(void); #define NO_TICKETS 0 #define EXPD_TICKETS 2 #define GOOD_TICKETS 1 /* Leash Configuration functions - alters Current User Registry */ DWORD Leash_get_default_lifetime(); DWORD Leash_set_default_lifetime(DWORD minutes); DWORD Leash_reset_default_lifetime(); DWORD Leash_get_default_renew_till(); DWORD Leash_set_default_renew_till(DWORD minutes); DWORD Leash_reset_default_renew_till(); DWORD Leash_get_default_renewable(); DWORD Leash_set_default_renewable(DWORD onoff); DWORD Leash_reset_default_renewable(); DWORD Leash_get_default_forwardable(); DWORD Leash_set_default_forwardable(DWORD onoff); DWORD Leash_reset_default_forwardable(); DWORD Leash_get_default_noaddresses(); DWORD Leash_set_default_noaddresses(DWORD onoff); DWORD Leash_reset_default_noaddresses(); DWORD Leash_get_default_proxiable(); DWORD Leash_set_default_proxiable(DWORD onoff); DWORD Leash_reset_default_proxiable(); DWORD Leash_get_default_publicip(); DWORD Leash_set_default_publicip(DWORD ipv4addr); DWORD Leash_reset_default_publicip(); DWORD Leash_get_default_use_krb4(); DWORD Leash_set_default_use_krb4(DWORD onoff); DWORD Leash_reset_default_use_krb4(); DWORD Leash_get_hide_kinit_options(); DWORD Leash_set_hide_kinit_options(DWORD onoff); DWORD Leash_reset_hide_kinit_options(); DWORD Leash_get_default_life_min(); DWORD Leash_set_default_life_min(DWORD minutes); DWORD Leash_reset_default_life_min(); DWORD Leash_get_default_life_max(); DWORD Leash_set_default_life_max(DWORD minutes); DWORD Leash_reset_default_life_max(); DWORD Leash_get_default_renew_min(); DWORD Leash_set_default_renew_min(DWORD minutes); DWORD Leash_reset_default_renew_min(); DWORD Leash_get_default_renew_max(); DWORD Leash_set_default_renew_max(DWORD minutes); DWORD Leash_reset_default_renew_max(); DWORD Leash_get_lock_file_locations(); DWORD Leash_set_lock_file_locations(DWORD onoff); DWORD Leash_reset_lock_file_locations(); DWORD Leash_get_default_uppercaserealm(); DWORD Leash_set_default_uppercaserealm(DWORD onoff); DWORD Leash_reset_default_uppercaserealm(); DWORD Leash_get_default_mslsa_import(); DWORD Leash_set_default_mslsa_import(DWORD onoffmatch); DWORD Leash_reset_default_mslsa_import(); DWORD Leash_get_default_preserve_kinit_settings(); DWORD Leash_set_default_preserve_kinit_settings(DWORD onoff); DWORD Leash_reset_default_preserve_kinit_settings(); #ifdef __cplusplus } #endif #endif /* LEASHWIN */ krb5-1.16/src/windows/include/leasherr.h0000644000704600001450000000310713211554426020061 0ustar ghudsonlibuuid/* * leasherr.h * This file is the #include file for leasherr.et. * Please do not edit it as it is automatically generated. */ #define LSH_ONLYONEME (40591872L) #define LSH_INVPRINCIPAL (40591873L) #define LSH_FAILEDREALM (40591874L) #define LSH_INVINSTANCE (40591875L) #define LSH_INVREALM (40591876L) #define LSH_EOF (40591877L) #define LSH_EXPIRESOON (40591878L) #define LSH_NOMATCH (40591879L) #define LSH_BADCHARS (40591880L) #define LSH_FATAL_ERROR (40591881L) #define LSH_BADWINSOCK (40591882L) #define LSH_BADTIMESERV (40591883L) #define LSH_NOSOCKET (40591884L) #define LSH_NOCONNECT (40591885L) #define LSH_TIMEFAILED (40591886L) #define LSH_GETTIMEOFDAY (40591887L) #define LSH_SETTIMEOFDAY (40591888L) #define LSH_RECVTIME (40591889L) #define LSH_RECVBYTES (40591890L) #define LSH_ALREADY_SETTIME (40591891L) extern void initialize_lsh_error_table(struct et_list **); #define ERROR_TABLE_BASE_lsh (40591872L) /* for compatibility with older versions... */ #define init_lsh_err_tbl() initialize_lsh_error_table(&_et_list) #define lsh_err_base ERROR_TABLE_BASE_lsh krb5-1.16/src/windows/include/wshelper.h0000644000704600001450000001313113211554426020103 0ustar ghudsonlibuuid/*! \file wshelper.h * WSHelper DNS/Hesiod Library * * This file contains the function declaration for: \n * rgethostbyname() \n * rgethostbyaddr() \n * rgetservbyname() \n * inet_aton() \n * wsh_gethostname() \n * wsh_getdomainname() \n \n * and unsupported functions: \n * gethinfobyname() \n * getmxbyname() \n * getrecordbyname() \n * rrhost() \n */ #ifndef _WSHELPER_ #define _WSHELPER_ #include #include #include #include #ifdef __cplusplus extern "C" { #endif /*! \fn struct hostent * WINAPI rgethostbyname(char *name) * retrieves host information corresponding to a host name in the DNS database * * defined in gethna.c * * \param[in] name Pointer to the null-terminated name of the host to resolve. It can be a fully qualified host name such as x.mit.edu * or it can be a simple host name such as x. If it is a simple host name, the default domain name is * appended to do the search. * \retval a pointer to the structure hostent. a structure allocated by the library. The hostent structure contains * the results of a successful search for the host specified in the name parameter. The caller must never * attempt to modify this structure or to free any of its components. Furthermore, only one copy of this * structure is allocated per call per thread, so the application should copy any information it needs before * issuing another rgethostbyname. * NULL if the search has failed * */ struct hostent * WINAPI rgethostbyname(char *name); /*! \fn struct hostent * WINAPI rgethostbyaddr(char *addr, int len, int type) * retrieves the host information corresponding to a network address in the DNS database * * defined in gethna.c * * \param[in] addr Pointer to an address in network byte order * \param[in] len Length of the address, in bytes * \param[in] type Type of the address, such as the AF_INET address family type (defined as TCP, * UDP, and other associated Internet protocols). Address family types and their corresponding * values are defined in the Winsock2.h header file. * \retval returns a pointer to the hostent structure that contains the name and address corresponding * to the given network address. The structure is allocated by the library. The caller must never * attempt to modify this structure or to free any of its components. Furthermore, only one copy of this * structure is allocated per call per thread, so the application should copy any information it needs before * issuing another rgethostbyaddr. * NULL if the search has failed * */ struct hostent * WINAPI rgethostbyaddr(char *addr, int len, int type); /*! \fn struct servent * WINAPI rgetservbyname(LPSTR name, LPSTR proto) * retrieves service information corresponding to a service name and protocol. * * defined in gethna.c * * \param[in] name Pointer to a null-terminated service name. * \param[in] proto pointer to a null-terminated protocol name. getservbyname should match both * the name and the proto. * \retval a pointer to the servent structure containing the name(s) and service number that match the name and proto * parameters. The structure is allocated by the library. The caller must never * attempt to modify this structure or to free any of its components. Furthermore, only one copy of this * structure is allocated per call per thread, so the application should copy any information it needs before * issuing another rgetservbyname. * NULL if the search has failed * */ struct servent * WINAPI rgetservbyname(LPSTR name, LPSTR proto); /*! \fn LPSTR WINAPI gethinfobyname(LPSTR name) * unsupported */ LPSTR WINAPI gethinfobyname(LPSTR name); /*! \fn LPSTR WINAPI getmxbyname(LPSTR name) * unsupported */ LPSTR WINAPI getmxbyname(LPSTR name); /*! \fn LPSTR WINAPI getrecordbyname(LPSTR name, int rectype) * unsupported */ LPSTR WINAPI getrecordbyname(LPSTR name, int rectype); /*! \fn DWORD WINAPI rrhost( LPSTR lpHost ) * unsupported */ DWORD WINAPI rrhost( LPSTR lpHost ); /*! \fn unsigned long WINAPI inet_aton(register const char *cp, struct in_addr *addr) * converts a string containing an (Ipv4) Internet Protocol dotted address into a proper address for the in_addr structure * * defined in inetaton.c * * \param[in] cp Null-terminated character string representing a number expressed in the * Internet standard ".'' (dotted) notation. * \param[in, out] addr pointer to the in_addr structure. The s_addr memeber will be populated * \retval Returns 1 if the address is valid, 0 if not. */ unsigned long WINAPI inet_aton(register const char *cp, struct in_addr *addr); /*! \fn int WINAPI wsh_gethostname(char* name, int size) * Gets the base part of the hostname * * defined in res_init.c * * \param[in, out] name pointer to a buffer that receives a null-terminated string containing the computer name * \param[in] size specifies the size of the buffer, in chars (must be large * enough to hold NULL-terminated host name) * \retval return 0 ifsuccess, -1 on error. */ int WINAPI wsh_gethostname(char* name, int size); /*! \fn int WINAPI wsh_getdomainname(char* name, int size) * Gets the machine's domain name * * defined in res_init.c * * \param[in, out] name pointer to a buffer that receives a null-terminated string containing the domain name * \param[in] size specifies the size of the buffer, in chars (must be large * enough to hold NULL-terminated domain name) * * \retval return 0 ifsuccess, -1 on error. */ int WINAPI wsh_getdomainname(char* name, int size); #ifdef __cplusplus } #endif #endif /* _WSHELPER_ */ krb5-1.16/src/windows/include/loadfuncs-leash.h0000644000704600001450000001447013211554426021331 0ustar ghudsonlibuuid#ifndef __LOADFUNCS_LEASH_H__ #define __LOADFUNCS_LEASH_H__ #include "loadfuncs.h" #include #if defined(_WIN64) #define LEASH_DLL "leashw64.dll" #else #define LEASH_DLL "leashw32.dll" #endif #define CALLCONV_C TYPEDEF_FUNC( int, CALLCONV_C, Leash_kinit_dlg, (HWND, LPLSH_DLGINFO) ); TYPEDEF_FUNC( int, CALLCONV_C, Leash_kinit_dlg_ex, (HWND, LPLSH_DLGINFO_EX) ); TYPEDEF_FUNC( int, CALLCONV_C, Leash_changepwd_dlg, (HWND, LPLSH_DLGINFO) ); TYPEDEF_FUNC( int, CALLCONV_C, Leash_changepwd_dlg_ex, (HWND, LPLSH_DLGINFO_EX) ); TYPEDEF_FUNC( long, CALLCONV_C, Leash_checkpwd, (char *, char *) ); TYPEDEF_FUNC( long, CALLCONV_C, Leash_changepwd, (char *, char *, char*, char*) ); TYPEDEF_FUNC( long, CALLCONV_C, Leash_kinit, (char *, char *, int) ); TYPEDEF_FUNC( long, CALLCONV_C, Leash_kinit_ex, (char *, char *, int,int, int, int, int, unsigned long) ); TYPEDEF_FUNC( long, CALLCONV_C, Leash_klist, (HWND, TICKETINFO*) ); TYPEDEF_FUNC( long, CALLCONV_C, Leash_kdestroy, (void) ); TYPEDEF_FUNC( long, CALLCONV_C, Leash_get_lsh_errno, (LONG *) ); TYPEDEF_FUNC( BOOL, CALLCONV_C, Leash_set_help_file, (char *) ); TYPEDEF_FUNC( char *, CALLCONV_C, Leash_get_help_file, (void) ); TYPEDEF_FUNC( long, CALLCONV_C, Leash_timesync, (int) ); TYPEDEF_FUNC( DWORD, CALLCONV_C, Leash_get_default_lifetime, (void) ); TYPEDEF_FUNC( DWORD, CALLCONV_C, Leash_set_default_lifetime, (DWORD) ); TYPEDEF_FUNC( DWORD, CALLCONV_C, Leash_reset_default_lifetime, (void) ); TYPEDEF_FUNC( DWORD, CALLCONV_C, Leash_get_default_renew_till, (void) ); TYPEDEF_FUNC( DWORD, CALLCONV_C, Leash_set_default_renew_till, (DWORD) ); TYPEDEF_FUNC( DWORD, CALLCONV_C, Leash_reset_default_renew_till, (void) ); TYPEDEF_FUNC( DWORD, CALLCONV_C, Leash_get_default_forwardable, (void) ); TYPEDEF_FUNC( DWORD, CALLCONV_C, Leash_set_default_forwardable, (DWORD) ); TYPEDEF_FUNC( DWORD, CALLCONV_C, Leash_reset_default_forwardable, (void) ); TYPEDEF_FUNC( DWORD, CALLCONV_C, Leash_get_default_noaddresses, (void) ); TYPEDEF_FUNC( DWORD, CALLCONV_C, Leash_set_default_noaddresses, (DWORD) ); TYPEDEF_FUNC( DWORD, CALLCONV_C, Leash_reset_default_noaddresses, (void) ); TYPEDEF_FUNC( DWORD, CALLCONV_C, Leash_get_default_proxiable, (void) ); TYPEDEF_FUNC( DWORD, CALLCONV_C, Leash_set_default_proxiable, (DWORD) ); TYPEDEF_FUNC( DWORD, CALLCONV_C, Leash_reset_default_proxiable, (void) ); TYPEDEF_FUNC( DWORD, CALLCONV_C, Leash_get_default_publicip, (void) ); TYPEDEF_FUNC( DWORD, CALLCONV_C, Leash_set_default_publicip, (DWORD) ); TYPEDEF_FUNC( DWORD, CALLCONV_C, Leash_reset_default_publicip, (void) ); TYPEDEF_FUNC( DWORD, CALLCONV_C, Leash_get_default_use_krb4, (void) ); TYPEDEF_FUNC( DWORD, CALLCONV_C, Leash_set_default_use_krb4, (DWORD) ); TYPEDEF_FUNC( DWORD, CALLCONV_C, Leash_reset_default_use_krb4, (void) ); TYPEDEF_FUNC( DWORD, CALLCONV_C, Leash_get_default_life_min, (void) ); TYPEDEF_FUNC( DWORD, CALLCONV_C, Leash_set_default_life_min, (DWORD) ); TYPEDEF_FUNC( DWORD, CALLCONV_C, Leash_reset_default_life_min, (void) ); TYPEDEF_FUNC( DWORD, CALLCONV_C, Leash_get_default_life_max, (void) ); TYPEDEF_FUNC( DWORD, CALLCONV_C, Leash_set_default_life_max, (DWORD) ); TYPEDEF_FUNC( DWORD, CALLCONV_C, Leash_reset_default_life_max, (void) ); TYPEDEF_FUNC( DWORD, CALLCONV_C, Leash_get_default_renew_min, (void) ); TYPEDEF_FUNC( DWORD, CALLCONV_C, Leash_set_default_renew_min, (DWORD) ); TYPEDEF_FUNC( DWORD, CALLCONV_C, Leash_reset_default_renew_min, (void) ); TYPEDEF_FUNC( DWORD, CALLCONV_C, Leash_get_default_renew_max, (void) ); TYPEDEF_FUNC( DWORD, CALLCONV_C, Leash_set_default_renew_max, (DWORD) ); TYPEDEF_FUNC( DWORD, CALLCONV_C, Leash_reset_default_renew_max, (void) ); TYPEDEF_FUNC( DWORD, CALLCONV_C, Leash_get_default_renewable, (void) ); TYPEDEF_FUNC( DWORD, CALLCONV_C, Leash_set_default_renewable, (DWORD) ); TYPEDEF_FUNC( DWORD, CALLCONV_C, Leash_reset_default_renewable, (void) ); TYPEDEF_FUNC( DWORD, CALLCONV_C, Leash_get_lock_file_locations, (void) ); TYPEDEF_FUNC( DWORD, CALLCONV_C, Leash_set_lock_file_locations, (DWORD) ); TYPEDEF_FUNC( DWORD, CALLCONV_C, Leash_reset_lock_file_locations, (void) ); TYPEDEF_FUNC( DWORD, CALLCONV_C, Leash_get_default_uppercaserealm, (void) ); TYPEDEF_FUNC( DWORD, CALLCONV_C, Leash_set_default_uppercaserealm, (DWORD) ); TYPEDEF_FUNC( DWORD, CALLCONV_C, Leash_reset_default_uppercaserealm, (void) ); TYPEDEF_FUNC( DWORD, CALLCONV_C, Leash_get_default_mslsa_import, (void) ); TYPEDEF_FUNC( DWORD, CALLCONV_C, Leash_set_default_mslsa_import, (DWORD) ); TYPEDEF_FUNC( DWORD, CALLCONV_C, Leash_reset_default_mslsa_import, (void) ); TYPEDEF_FUNC( DWORD, CALLCONV_C, Leash_get_default_preserve_kinit_settings, (void) ); TYPEDEF_FUNC( DWORD, CALLCONV_C, Leash_set_default_preserve_kinit_settings, (DWORD) ); TYPEDEF_FUNC( DWORD, CALLCONV_C, Leash_reset_default_preserve_kinit_settings, (void) ); TYPEDEF_FUNC( BOOL, CALLCONV_C, Leash_import, (void) ); TYPEDEF_FUNC( long, CALLCONV_C, Leash_importable, (void) ); TYPEDEF_FUNC( int, CALLCONV_C, Leash_renew, (void) ); TYPEDEF_FUNC( void, CALLCONV_C, Leash_reset_defaults, (void) ); /* They are not yet all here... */ #endif /* __LOADFUNCS_LEASH_H__ */ krb5-1.16/src/windows/include/mitwhich.h0000644000704600001450000000524513211554426020075 0ustar ghudsonlibuuid/*! \file mitwhich.h * some defines so that we can figure out which MS OS and subsystem an * application is running under. Also support for finding out which * TCP/IP stack is being used. This is useful when you need to find out * about the domain or the nameservers. */ #if !defined( __MIT_WHICH_H ) #define __MIT_WHICH_H // these should become resources and loaded at run time #define NT_32 "Winsock 2.0" #define NT_16 "Windows NT 16-bit Windows Sockets" #define W95_32 "Microsoft Windows Sockets Version 1.1." #define W95_16 "Microsoft Windows Sockets Version 1.1." #define LWP_16 "Novell Winsock version 1.1" // Note that these are currently in wshelper.h and should be somewhere else #define MS_NT_32 1 #define MS_NT_16 2 #define MS_95_32 3 #define MS_95_16 4 #define NOVELL_LWP_16 5 #define MS_OS_WIN 1 #define MS_OS_95 2 #define MS_OS_NT 4 #define MS_OS_2000 12 #define MS_OS_XP 28 #define MS_OS_2003 60 #define MS_OS_NT_UNKNOWN 124 #define MS_OS_UNKNOWN 0 #define STACK_UNKNOWN 0 #define UNKNOWN_16_UNDER_32 -2 #define UNKNOWN_16_UNDER_16 -3 #define UNKNOWN_32_UNDER_32 -4 #define UNKNOWN_32_UNDER_16 -5 /* @comm these are the current MIT DNS servers, the wshelper and wshelp32 DLLs will do their best to find the correct DNS servers for the local machine however, if all else fails these will be used as a last resort. Site administrators outside of the MIT domain should change these defaults to their own defaults either by editing this file and recompiling or by editing the string tables of the binaries. Don't use App Studio to edit the .RC files. \n #define DNS1 "18.70.0.160" \n #define DNS2 "18.71.0.151" \n #define DNS3 "18.72.0.3" \n \n #define DEFAULT_DOMAIN "mit.edu" \n */ #define DNS1 "18.70.0.160" #define DNS2 "18.71.0.151" #define DNS3 "18.72.0.3" #define DEFAULT_DOMAIN "mit.edu" #ifndef _PATH_RESCONF #if !defined(WINDOWS) && !defined(_WINDOWS) && !defined(_WIN32) #define _PATH_RESCONF "/etc/resolv.conf" #else #define _PATH_RESCONF "c:/net/tcp/resolv.cfg" #endif #endif /* Microsoft TCP/IP registry values that we care about */ #define NT_TCP_PATH "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters" #define NT_TCP_PATH_TRANS "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters\\Transient" #define W95_TCP_PATH "SYSTEM\\CurrentControlSet\\Services\\VxD\\MSTCP" #define NT_DOMAIN_KEY "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters\\Domain" #define NT_NS_KEY "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters\\NameServer" #define W95_DOMAIN_KEY "SYSTEM\\CurrentControlSet\\Services\\VxD\\MSTCP\\Domain" #define W95_NS_KEY "SYSTEM\\CurrentControlSet\\Services\\VxD\\MSTCP\\NameServer" #endif // __MIT_WHICH_H krb5-1.16/src/windows/include/loadfuncs-profile.h0000644000704600001450000000537213211554426021676 0ustar ghudsonlibuuid#ifndef __LOADFUNCS_PROFILE_H__ #define __LOADFUNCS_PROFILE_H__ #include "loadfuncs.h" #include #if defined(_WIN64) #define PROFILE_DLL "xpprof64.dll" #else #define PROFILE_DLL "xpprof32.dll" #endif TYPEDEF_FUNC( long, KRB5_CALLCONV, profile_init, (const_profile_filespec_t *files, profile_t *ret_profile) ); TYPEDEF_FUNC( long, KRB5_CALLCONV, profile_init_path, (const_profile_filespec_list_t filelist, profile_t *ret_profile) ); TYPEDEF_FUNC( long, KRB5_CALLCONV, profile_flush, (profile_t profile) ); TYPEDEF_FUNC( void, KRB5_CALLCONV, profile_abandon, (profile_t profile) ); TYPEDEF_FUNC( void, KRB5_CALLCONV, profile_release, (profile_t profile) ); TYPEDEF_FUNC( long, KRB5_CALLCONV, profile_get_values, (profile_t profile, const char **names, char ***ret_values) ); TYPEDEF_FUNC( void, KRB5_CALLCONV, profile_free_list, (char **list) ); TYPEDEF_FUNC( long, KRB5_CALLCONV, profile_get_string, (profile_t profile, const char *name, const char *subname, const char *subsubname, const char *def_val, char **ret_string) ); TYPEDEF_FUNC( long, KRB5_CALLCONV, profile_get_integer, (profile_t profile, const char *name, const char *subname, const char *subsubname, int def_val, int *ret_default) ); TYPEDEF_FUNC( long, KRB5_CALLCONV, profile_get_relation_names, (profile_t profile, const char **names, char ***ret_names) ); TYPEDEF_FUNC( long, KRB5_CALLCONV, profile_get_subsection_names, (profile_t profile, const char **names, char ***ret_names) ); TYPEDEF_FUNC( long, KRB5_CALLCONV, profile_iterator_create, (profile_t profile, const char **names, int flags, void **ret_iter) ); TYPEDEF_FUNC( void, KRB5_CALLCONV, profile_iterator_free, (void **iter_p) ); TYPEDEF_FUNC( long, KRB5_CALLCONV, profile_iterator, (void **iter_p, char **ret_name, char **ret_value) ); TYPEDEF_FUNC( void, KRB5_CALLCONV, profile_release_string, (char *str) ); TYPEDEF_FUNC( long, KRB5_CALLCONV, profile_update_relation, (profile_t profile, const char **names, const char *old_value, const char *new_value) ); TYPEDEF_FUNC( long, KRB5_CALLCONV, profile_clear_relation, (profile_t profile, const char **names) ); TYPEDEF_FUNC( long, KRB5_CALLCONV, profile_rename_section, (profile_t profile, const char **names, const char *new_name) ); TYPEDEF_FUNC( long, KRB5_CALLCONV, profile_add_relation, (profile_t profile, const char **names, const char *new_value) ); #endif /* __LOADFUNCS_PROFILE_H__ */ krb5-1.16/src/windows/include/hesiod.h0000644000704600001450000001554413211554426017537 0ustar ghudsonlibuuid/*! \file hesiod.h * WSHelper DNS/Hesiod Library * * This file contains the function declaration for: \n * hes_to_bind() \n * hes_resolve() \n * hes_error() \n * hes_free() \n * hes_getmailhost() \n * hes_getservbyname() \n * hes_getpwnam() \n * hes_getpwuid() \n */ #ifndef _HESIOD_ #define _HESIOD_ #include /*! \def HESIOD_CONF * name of the hesiod configuration file. We will look at the file to determine the RHS AND LHS value before using the default. * Here is a sample hesiod.cfg file: \n * lhs .ns \n * rhs .ATHENA.MIT.EDU \n */ #define HESIOD_CONF "c:\\net\\tcp\\hesiod.cfg" /*! \def DEF_RHS * default RHS value is the hesiod configuration file is not present */ #define DEF_RHS ".Athena.MIT.EDU" /*! \def DEF_LHS * default LHS value is the hesiod configuration file is not present */ #define DEF_LHS ".ns" /*! \def HES_ER_UNINIT * HES error code: uninitialized */ #define HES_ER_UNINIT -1 /*! \def HES_ER_OK * HES error code: no error */ #define HES_ER_OK 0 /*! \def HES_ER_NOTFOUND * HES error code: Hesiod name not found by server */ #define HES_ER_NOTFOUND 1 /*! \def HES_ER_CONFIG * HES error code: local problem (no config file?) */ #define HES_ER_CONFIG 2 /*! \def HES_ER_NET * HES error code: network problem */ #define HES_ER_NET 3 #ifdef __cplusplus extern "C" { #endif /*! \fn LPSTR WINAPI hes_to_bind(LPSTR HesiodName, LPSTR HesiodNameType) * hes_to_bind function use the LHS and RHS values and * binds them with the parameters so that a well formed DNS query may * be performed. * * defined in hesiod.c * * \param[in] HesiodName The Hesiod name such as a username or service name * \param[in] HesiodNameType The Hesiod name type such as pobox, passwd, or sloc * \retval Returns NULL if there was an error. Otherwise the pointer to a string containing a valid query is returned. * */ LPSTR WINAPI hes_to_bind( LPSTR HesiodName, LPSTR HesiodNameType ); /*! \fn LPSTR * WINAPI hes_resolve(LPSTR HesiodName, LPSTR HesiodNameType) * This function calls hes_to_bind to form a valid hesiod query, then queries the dns database. * * defined in hesiod.c * * \param[in] HesiodName The Hesiod name such as a username or service name * \param[in] HesiodNameType The Hesiod name type such as pobox, passwd, or sloc * \retval returns a NULL terminated vector of strings (a la argv), * one for each resource record containing Hesiod data, or NULL if * there is any error. If there is an error call hes_error() to get * further information. You will need to call hes_free to free the result * */ LPSTR * WINAPI hes_resolve( LPSTR HesiodName, LPSTR HesiodNameType ); /*! \fn int WINAPI hes_error(void) * The function hes_error may be called to determine the * source of the error. It does not take an argument. * * defined in hesiod.c * * \retval return one of the HES_ER_* codes defined in hesiod.h. */ int WINAPI hes_error( void ); /*! \fn void WINAPI hes_free(LPSTR* hesinfo) * The function hes_free should be called to free up memeory returned by hes_resolve * * defined in hesiod.c * * \param[in] hesinfo a NULL terminiated array of strings returned by hes_resolve */ void WINAPI hes_free( LPSTR* hesinfo ); /*! \struct hes_postoffice * For use in getting post-office information. */ struct hes_postoffice { /*! The post office type, e.g. POP, IMAP */ LPSTR po_type; /*! The post office host, e.g. PO10.MIT.EDU */ LPSTR po_host; /*! The account name on the post office, e.g. tom */ LPSTR po_name; }; /*! \fn struct hes_postoffice * WINAPI hes_getmailhost(LPSTR user) * This call is used to obtain a user's type of mail account and the location of that * account. E.g. POP PO10.MIT.EDU or IMAP IMAP-TEST.MIT.EDU * * defined in hesmailh.c * * \param[in] user The username to be used when querying for the Hesiod Name Type POBOX. * \retval NULL if there was an error or if there was no entry for the * username. Otherwise a pointer to a hes_postoffice structure is * returned. The caller must never attempt to modify this structure or to free * any of its components. Furthermore, only one copy of this structure is allocated per call per thread, so the application should copy any information it needs before * issuing another getmailhost call */ struct hes_postoffice * WINAPI hes_getmailhost(LPSTR user); /*! \fn struct servent * WINAPI hes_getservbyname(LPSTR name, LPSTR proto) * This function will query a Hesiod server for a servent structure given * a service name and protocol. This is a replacement for the Winsock * getservbyname function which normally just uses a local services * file. This allows a site to use a centralized database for adding new * services. * * defined in hesservb.c * * \param[in] name pointer to the official name of the service, eg "POP3". * \param[in] proto pointer to the protocol to use when contacting the service, e.g. "TCP" * \retval NULL if there was an error or a pointer to a servent structure. The caller must * never attempt to modify this structure or to free any of its components. * Furthermore, only one copy of this structure is allocated per call per thread, so the application should copy any information it needs before * issuing another hes_getservbyname call * */ struct servent * WINAPI hes_getservbyname(LPSTR name, LPSTR proto); /*! \fn struct passwd * WINAPI hes_getpwnam(LPSTR nam) * Given a username this function will return the pwd information, eg * username, uid, gid, fullname, office location, phone number, home * directory, and default shell * * defined in hespwnam.c * * \param nam a pointer to the username * \retval NULL if there was an error or a pointer to the passwd structure. The caller must * never attempt to modify this structure or to free any of its components. * Furthermore, only one copy of this structure is allocated per call per thread, so the application should copy any information it needs before * issuing another hes_getpwnam call * */ struct passwd * WINAPI hes_getpwnam(LPSTR nam); /*! struct passwd * WINAPI hes_getpwuid(int uid) * Given a UID this function will return the pwd information, eg username, uid, * gid, fullname, office location, phone number, home directory, and default shell * * defined in hespwnam.c * * \param uid The user ID * \retval NULL if there was an error or a pointer to the passwd structure. The caller must * never attempt to modify this structure or to free any of its components. * Furthermore, only one copy of this structure is allocated per call per thread, so the application should copy any information it needs before * issuing another hes_getpwuid call */ struct passwd * WINAPI hes_getpwuid(int uid); #ifdef __cplusplus } #endif #endif /* _HESIOD_ */ krb5-1.16/src/windows/include/arpa/0000755000704600001450000000000013211554426017025 5ustar ghudsonlibuuidkrb5-1.16/src/windows/include/arpa/nameser.h0000644000704600001450000002102413211554426020627 0ustar ghudsonlibuuid/* * @doc * @module nameser.h | * Copyright (c) 1983, 1989 Regents of the University of California. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * @(#)nameser.h 5.25 (Berkeley) 4/3/91 */ #ifndef _NAMESER_H_ #define _NAMESER_H_ /* * Define constants based on rfc883 */ #define PACKETSZ 512 /* maximum packet size */ #define MAXDNAME 256 /* maximum domain name */ #define MAXCDNAME 255 /* maximum compressed domain name */ #define MAXLABEL 63 /* maximum length of domain label */ /* Number of bytes of fixed size data in query structure */ #define QFIXEDSZ 4 /* number of bytes of fixed size data in resource record */ #define RRFIXEDSZ 10 #if !defined(MAXHOSTNAME) #define MAXHOSTNAME MAXCDNAME #endif /* * Internet nameserver port number */ #define NAMESERVER_PORT 53 /* * Currently defined opcodes */ #define QUERY 0x0 /* standard query */ #define IQUERY 0x1 /* inverse query */ #define STATUS 0x2 /* nameserver status query */ /*#define xxx 0x3 /* 0x3 reserved */ /* non standard */ #define UPDATEA 0x9 /* add resource record */ #define UPDATED 0xa /* delete a specific resource record */ #define UPDATEDA 0xb /* delete all nemed resource record */ #define UPDATEM 0xc /* modify a specific resource record */ #define UPDATEMA 0xd /* modify all named resource record */ #define ZONEINIT 0xe /* initial zone transfer */ #define ZONEREF 0xf /* incremental zone referesh */ /* * Currently defined response codes */ #define NOERROR 0 /* no error */ #define FORMERR 1 /* format error */ #define SERVFAIL 2 /* server failure */ #define NXDOMAIN 3 /* non existent domain */ #define NOTIMP 4 /* not implemented */ #define REFUSED 5 /* query refused */ /* non standard */ #define NOCHANGE 0xf /* update failed to change db */ /* * Type values for resources and queries */ #define T_A 1 /* host address */ #define T_NS 2 /* authoritative server */ #define T_MD 3 /* mail destination */ #define T_MF 4 /* mail forwarder */ #define T_CNAME 5 /* connonical name */ #define T_SOA 6 /* start of authority zone */ #define T_MB 7 /* mailbox domain name */ #define T_MG 8 /* mail group member */ #define T_MR 9 /* mail rename name */ #define T_NULL 10 /* null resource record */ #define T_WKS 11 /* well known service */ #define T_PTR 12 /* domain name pointer */ #define T_HINFO 13 /* host information */ #define T_MINFO 14 /* mailbox information */ #define T_MX 15 /* mail routing information */ #define T_TXT 16 /* text strings */ /* non standard */ #define T_UINFO 100 /* user (finger) information */ #define T_UID 101 /* user ID */ #define T_GID 102 /* group ID */ #define T_UNSPEC 103 /* Unspecified format (binary data) */ /* Query type values which do not appear in resource records */ #define T_AXFR 252 /* transfer zone of authority */ #define T_MAILB 253 /* transfer mailbox records */ #define T_MAILA 254 /* transfer mail agent records */ #define T_ANY 255 /* wildcard match */ /* * Values for class field */ #define C_IN 1 /* the arpa internet */ #define C_CHAOS 3 /* for chaos net at MIT */ #define C_HS 4 /* for Hesiod name server at MIT */ /* Query class values which do not appear in resource records */ #define C_ANY 255 /* wildcard match */ /* * Status return codes for T_UNSPEC conversion routines */ #define CONV_SUCCESS 0 #define CONV_OVERFLOW -1 #define CONV_BADFMT -2 #define CONV_BADCKSUM -3 #define CONV_BADBUFLEN -4 #ifndef BYTE_ORDER #define LITTLE_ENDIAN 1234 /* least-significant byte first (vax) */ #define BIG_ENDIAN 4321 /* most-significant byte first (IBM, net) */ #define PDP_ENDIAN 3412 /* LSB first in word, MSW first in long (pdp) */ #if defined(vax) || defined(ns32000) || defined(sun386) || defined(MIPSEL) || \ defined(BIT_ZERO_ON_RIGHT) #define BYTE_ORDER LITTLE_ENDIAN #endif #if defined(sel) || defined(pyr) || defined(mc68000) || defined(sparc) || \ defined(is68k) || defined(tahoe) || defined(ibm032) || defined(ibm370) || \ defined(MIPSEB) || defined (BIT_ZERO_ON_LEFT) #define BYTE_ORDER BIG_ENDIAN #endif #endif /* BYTE_ORDER */ #ifndef BYTE_ORDER /* you must determine what the correct bit order is for your compiler */ #define BYTE_ORDER LITTLE_ENDIAN /* for Intel x86 series */ #endif /* * Structure for query header, the order of the fields is machine and * compiler dependent, in our case, the bits within a byte are assignd * least significant first, while the order of transmition is most * significant first. This requires a somewhat confusing rearrangement. */ #if defined (_WINDLL) || (_WIN32) /* define UNIX types */ #include #endif typedef struct { u_short id; /* query identification number */ #if BYTE_ORDER == BIG_ENDIAN /* fields in third byte */ u_char qr:1; /* response flag */ u_char opcode:4; /* purpose of message */ u_char aa:1; /* authoritive answer */ u_char tc:1; /* truncated message */ u_char rd:1; /* recursion desired */ /* fields in fourth byte */ u_char ra:1; /* recursion available */ u_char pr:1; /* primary server required (non standard) */ u_char unused:2; /* unused bits */ u_char rcode:4; /* response code */ #endif #if BYTE_ORDER == LITTLE_ENDIAN || BYTE_ORDER == PDP_ENDIAN /* fields in third byte */ u_char rd:1; /* recursion desired */ u_char tc:1; /* truncated message */ u_char aa:1; /* authoritive answer */ u_char opcode:4; /* purpose of message */ u_char qr:1; /* response flag */ /* fields in fourth byte */ u_char rcode:4; /* response code */ u_char unused:2; /* unused bits */ u_char pr:1; /* primary server required (non standard) */ u_char ra:1; /* recursion available */ #endif /* remaining bytes */ u_short qdcount; /* number of question entries */ u_short ancount; /* number of answer entries */ u_short nscount; /* number of authority entries */ u_short arcount; /* number of resource entries */ } HEADER; /* * Defines for handling compressed domain names */ #define INDIR_MASK 0xc0 /* * Structure for passing resource records around. */ struct rrec { short r_zone; /* zone number */ short r_class; /* class number */ short r_type; /* type number */ u_long r_ttl; /* time to live */ int r_size; /* size of data area */ char *r_data; /* pointer to data */ }; extern u_short _getshort(); extern u_long _getlong(); /* * Inline versions of get/put short/long. * Pointer is advanced; we assume that both arguments * are lvalues and will already be in registers. * cp MUST be u_char *. */ #define GETSHORT(s, cp) { \ (s) = *(cp)++ << 8; \ (s) |= *(cp)++; \ } #define GETLONG(l, cp) { \ (l) = *(cp)++ << 8; \ (l) |= *(cp)++; (l) <<= 8; \ (l) |= *(cp)++; (l) <<= 8; \ (l) |= *(cp)++; \ } #define PUTSHORT(s, cp) { \ *(cp)++ = (s) >> 8; \ *(cp)++ = (s); \ } /* * Warning: PUTLONG destroys its first argument. */ #define PUTLONG(l, cp) { \ (cp)[3] = l; \ (cp)[2] = (l >>= 8); \ (cp)[1] = (l >>= 8); \ (cp)[0] = l >> 8; \ (cp) += sizeof(u_long); \ } #endif /* !_NAMESER_H_ */ krb5-1.16/src/windows/include/loadfuncs-com_err.h0000644000704600001450000000152413211554426021657 0ustar ghudsonlibuuid#ifndef __LOADFUNCS_COM_ERR_H__ #define __LOADFUNCS_COM_ERR_H__ #include "loadfuncs.h" #include #if defined(_WIN64) #define COMERR_DLL "comerr64.dll" #else #define COMERR_DLL "comerr32.dll" #endif TYPEDEF_FUNC( void, KRB5_CALLCONV_C, com_err, (const char FAR *, errcode_t, const char FAR *, ...) ); TYPEDEF_FUNC( void, KRB5_CALLCONV, com_err_va, (const char FAR *whoami, errcode_t code, const char FAR *fmt, va_list ap) ); TYPEDEF_FUNC( const char FAR *, KRB5_CALLCONV, error_message, (errcode_t) ); TYPEDEF_FUNC( errcode_t, KRB5_CALLCONV, add_error_table, (const struct error_table FAR *) ); TYPEDEF_FUNC( errcode_t, KRB5_CALLCONV, remove_error_table, (const struct error_table FAR *) ); #endif /* __LOADFUNCS_COM_ERR_H__ */ krb5-1.16/src/windows/include/leashinfo.h0000644000704600001450000000010013211554426020212 0ustar ghudsonlibuuid#define LSH_TIME_HOST 1970 #define LSH_DEFAULT_TICKET_LIFE 1971 krb5-1.16/src/windows/include/resolv.h0000644000704600001450000002151513211554426017571 0ustar ghudsonlibuuid/*! \file resolv.h * WSHelper DNS/Hesiod Library header * This file contains the function declaration for:\n * res_init() \n * res_search() \n * dn_comp() \n * rdn_expand() \n \n * and unsupported functions: \n * res_setopts() \n * res_getopts() \n * res_querydomain() \n * res_mkquery() \n * res_send() \n */ #ifndef _RESOLV_H_ #define _RESOLV_H_ #include #ifndef MAXDNAME #include #endif /*! \def MAXNS * max # name servers we'll track */ #define MAXNS 3 /*! \def MAXDFLSRCH * # default domain levels to try */ #define MAXDFLSRCH 3 /*! \def MAXDNSRCH * max # domains in search path */ #define MAXDNSRCH 6 /*! \def LOCALDOMAINPARTS * min levels in name that is "local" */ #define LOCALDOMAINPARTS 2 /*! \def RES_TIMEOUT * min. seconds between retries */ #define RES_TIMEOUT 5 /*! \def MAXMXRECS * number of records in the preference array in the MX record */ #define MAXMXRECS 8 /*! \struct mxent * structure to hold the MX record */ struct mxent { /*! number of records in the preference field */ int numrecs; /*! holds a 16 bit integer which specifies the preference given to this RR */ u_short pref[MAXMXRECS]; /*! a host willing to act as a mail exchange */ char ** hostname; }; /*! \struct state * This structure holds the state for the resolver query */ struct state { /*! retransmition time interval */ int retrans; /*! number of times to retransmit */ int retry; /*! field option flags - see below. */ long options; /*! field number of name servers */ int nscount; /*! address of name server */ struct sockaddr_in nsaddr_list[MAXNS]; #define nsaddr nsaddr_list[0] /*! current packet id */ u_short id; /*! field default domain */ char defdname[MAXDNAME]; /*! field components of domain to search */ char *dnsrch[MAXDNSRCH+1]; }; /*! \def RES_INIT * resolver option: address initialized */ #define RES_INIT 0x0001 /*! \def RES_DEBUG * resolver option: print debug messages */ #define RES_DEBUG 0x0002 /*! \def RES_AAONLY * resolver option: authoritative answers only */ #define RES_AAONLY 0x0004 /*! \def RES_USEVC * resolver option: use virtual circuit */ #define RES_USEVC 0x0008 /*! \def RES_PRIMARY * resolver option: query primary server only */ #define RES_PRIMARY 0x0010 /*! \def RES_IGNTC * resolver option: ignore trucation errors */ #define RES_IGNTC 0x0020 /*! \def RES_RECURSE * resolver option: recursion desired */ #define RES_RECURSE 0x0040 /*! \def RES_DEFNAMES * resolver option: use default domain name */ #define RES_DEFNAMES 0x0080 /*! \def RES_STAYOPEN * resolver option: Keep TCP socket ope */ #define RES_STAYOPEN 0x0100 /*! \def RES_DNSRCH * resolver option: search up local domain tree */ #define RES_DNSRCH 0x0200 /*! \def RES_DEFAULT * resolver option: Default RES options (RES_RECURSE + RES_DEFNAMES + RES_DNSRCH) */ #define RES_DEFAULT (RES_RECURSE | RES_DEFNAMES | RES_DNSRCH) extern struct state _res; #include /* Private routines shared between libc/net, named, nslookup and others. */ #define fp_query __fp_query #define hostalias __hostalias #define putlong __putlong #define putshort __putshort #define p_class __p_class #define p_time __p_time #define p_type __p_type #ifdef __cplusplus extern "C" { #endif /*! \fn int WINAPI res_init() * \brief retrieves the default domain name and search order. It will look to see if an environment variable LOCALDOMAIN is defined. Otherwise, * the domain associated with the local host is used. Otherwise, it will try to find the domain name from the registry * * defined in res_init.c * * \retval The return value is 0 if the operation was successful. Otherwise the value -1 is returned. */ int WINAPI res_init(); /*! \fn int WINAPI res_search(const char* name, int qclass, int type, u_char* answer, int anslen) * \brief a generic query interface to the DNS name space. The query is performed with the dnsapi and * the answer buffer is populated based on the returned RR set. * * defined in res_quer.c * \param[in] name domain name * \param[in] qclass class of query(such as DNS_CLASS_INTERNET, DNS_CLASS_CSNET, DNS_CLASS_CHAOS, * DNS_CLASS_HESIOD. Defined in windns.h) * \param[in] type type of query(such as DNS_TYPE_A, DNS_TYPE_NS, DNS_TYPE_MX, DNS_TYPE_SRV. Defined in * windns.h) * \param[in] answer buffer to put answer in * \param[in] anslen size of the answer buffer. compare the anslen with the return value, if the return * value is bigger than anslen, it means the answer buffer doesn't contain the complete * response. You will need to call this function again with a bigger answer buffer if * you care about the complete response * * \retval return the size of the response on success, -1 on error * */ int WINAPI res_search(const char *name, int qclass, int type, u_char *answer, int anslen); /*! \fn int WINAPI dn_comp(const u_char* exp_dn, u_char* comp_dn, int length, u_char** dnptrs, u_char** lastdnptr) * \brief Compress domain name 'exp_dn' into 'comp_dn' * * defined in res_comp.c * * \param[in] exp_dn name to compress * \param[in, out] comp_dn result of the compression * \param[in] length the size of the array pointed to by 'comp_dn'. * \param[in, out] dnptrs a list of pointers to previous compressed names. dnptrs[0] * is a pointer to the beginning of the message. The list ends with NULL. * \param[in] lastdnptr a pointer to the end of the arrary pointed to by 'dnptrs'. Side effect * is to update the list of pointers for labels inserted into the * message as we compress the name. If 'dnptr' is NULL, we don't try to * compress names. If 'lastdnptr' is NULL, we don't update the list. * \retval Return the size of the compressed name or -1 */ int WINAPI dn_comp(const u_char *exp_dn, u_char *comp_dn, int length, u_char **dnptrs, u_char * *lastdnptr); /*! \fn int WINAPI rdn_expand(const u_char *msg, const u_char *eomorig, const u_char *comp_dn, u_char *exp_dn, int length); * \brief replacement for dn_expand called rdn_expand. Older versions of the DLL used to this as dn_expand * but this has caused some conflict with more recent versions of the MSDEV libraries. rdn_expand() * expands the compressed domain name comp_dn to a full domain name. Expanded names are converted to upper case. * * defined in res_comp.c * * \param[in] msg msg is a pointer to the beginning of the message * \param[in] eomorig * \param[in] comp_dn the compressed domain name. * \param[in, out] exp_dn a pointer to the result buffer * \param[in] length size of the result in expn_dn * \retval the size of compressed name is returned or -1 if there was an error. */ int WINAPI rdn_expand(const u_char *msg, const u_char *eomorig, const u_char *comp_dn, u_char *exp_dn, int length); /* Microsoft includes an implementation of dn_expand() in winsock */ /* Make sure we do not use it. jaltman@columbia.edu */ #define dn_expand(a,b,c,d,e) rdn_expand(a,b,c,d,e) /*! \fn void WINAPI res_setopts(long opts) * unsupported */ void WINAPI res_setopts(long opts); /*! \fn long WINAPI res_getopts(void) * unsupported */ long WINAPI res_getopts(void); /*! \fn int WINAPI res_mkquery(int op, const char *dname, int qclass, int type, const char *data, int datalen, * const struct rrec *newrr, char *buf, int buflen) * unsupported */ int WINAPI res_mkquery(int op, const char *dname, int qclass, int type, const char *data, int datalen, const struct rrec *newrr, char *buf, int buflen); /*! \fn int WINAPI res_send(const char *msg, int msglen, char *answer, int anslen) * unsupported */ int WINAPI res_send(const char *msg, int msglen, char *answer, int anslen); /*! \fn int WINAPI res_querydomain(const char *name, const char *domain, int qclass, int type, u_char *answer, int anslen); * unsupported */ int WINAPI res_querydomain(const char *name, const char *domain, int qclass, int type, u_char *answer, int anslen); #ifdef __cplusplus } #endif #endif /* !_RESOLV_H_ */ krb5-1.16/src/windows/include/loadfuncs-lsa.h0000644000704600001450000000145513211554426021013 0ustar ghudsonlibuuid#ifndef __LOADFUNCS_LSA_H__ #define __LOADFUNCS_LSA_H__ #include "loadfuncs.h" #define SECUR32_DLL "secur32.dll" #define ADVAPI32_DLL "advapi32.dll" TYPEDEF_FUNC( NTSTATUS, NTAPI, LsaConnectUntrusted, (PHANDLE) ); TYPEDEF_FUNC( NTSTATUS, NTAPI, LsaLookupAuthenticationPackage, (HANDLE, PLSA_STRING, PULONG) ); TYPEDEF_FUNC( NTSTATUS, NTAPI, LsaCallAuthenticationPackage, (HANDLE, ULONG, PVOID, ULONG, PVOID *, PULONG, PNTSTATUS) ); TYPEDEF_FUNC( NTSTATUS, NTAPI, LsaFreeReturnBuffer, (PVOID) ); TYPEDEF_FUNC( ULONG, NTAPI, LsaNtStatusToWinError, (NTSTATUS) ); TYPEDEF_FUNC( NTSTATUS, NTAPI, LsaGetLogonSessionData, (PLUID, PSECURITY_LOGON_SESSION_DATA*) ); #endif /* __LOADFUNCS_LSA_H__ */ krb5-1.16/src/windows/kerberos.ver0000644000704600001450000000472313211554426017017 0ustar ghudsonlibuuid/* kerberos.ver. This is similar to patchlevel.h, but version numbers are independent */ /* * Copyright (C) 2004-2011 by the Massachusetts Institute of Technology. * All rights reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ /* * This is the master file for version stamping purposes. The * checked-in version will contain the correct version information at * all times. Prior to an official release x.y.z, * KRB5_MAJOR_RELEASE=x, KRB5_MINOR_RELEASE=y, and KRB5_PATCHLEVEL=z. * KRB5_RELTAIL will reflect the release state. It will be * "prerelease" for unreleased code either on the trunk or on a * release branch. It will be undefined for a final release. * * Immediately following a final release, the release version numbers * will be incremented, and KRB5_RELTAIL will revert to "prerelease". * * KRB5_RELTAG contains the CVS tag name corresponding to the release. * KRB5_RELDATE identifies the date of the release. They should * normally be undefined for checked-in code. */ /* * ========== * IMPORTANT: * ========== * * If you are a vendor supplying modified code derived from MIT * Kerberos, you SHOULD update KRB5_RELTAIL to identify your * organization. */ #define KRB5_MAJOR_RELEASE 4 #define KRB5_MINOR_RELEASE 1 #define KRB5_PATCHLEVEL 0 #define KRB5_RELTAIL "prerelease" /* #undef KRB5_RELDATE */ #define KRB5_RELTAG "trunk" #define KRB5_PRODUCTNAME_STR "MIT Kerberos for Windows" krb5-1.16/src/windows/Makefile.in0000644000704600001450000000015713211554426016527 0ustar ghudsonlibuuidBUILDTOP=.. NO_OUTPRE=1 !ifndef NO_LEASH LEASH=leash !endif SUBDIRS= lib leashdll $(LEASH) cns ms2mit kfwlogon krb5-1.16/src/windows/leashdll/0000755000704600001450000000000013211554426016247 5ustar ghudsonlibuuidkrb5-1.16/src/windows/leashdll/winerr.c0000644000704600001450000000503713211554426017726 0ustar ghudsonlibuuid/* WINERR.C Jason Hunter 8/2/94 DCNS/IS MIT Contains the error functions for leash and kerberos. Prints out keen windows error messages in english. */ #include #include "conf.h" // Private Include files #include "leashdll.h" #include // Global Variables. static long lsh_errno; static char *err_context; /* error context */ extern int (*Lcom_err)(LPSTR,long,LPSTR,...); extern LPSTR (*Lerror_message)(long); extern LPSTR (*Lerror_table_name)(long); #ifdef WIN16 #define UNDERSCORE "_" #else #define UNDERSCORE #endif HWND GetRootParent (HWND Child) { HWND Last; while (Child) { Last = Child; Child = GetParent (Child); } return Last; } LPSTR err_describe(LPSTR buf, long code) { LPSTR cp, com_err_msg; int offset; long table_num; char *etype; offset = (int) (code & 255); table_num = code - offset; com_err_msg = Lerror_message(code); lstrcpy(buf, com_err_msg); return buf; ////Is this needed at all after the return above? cp = buf; if(com_err_msg != buf) lstrcpy(buf, com_err_msg); cp = buf + lstrlen(buf); *cp++ = '\n'; etype = Lerror_table_name(table_num); wsprintf((LPSTR) cp, (LPSTR) "(%s error %d" #ifdef DEBUG_COM_ERR " (absolute error %ld)" #endif ")", etype, offset //")\nPress F1 for help on this error.", etype, offset #ifdef DEBUG_COM_ERR , code #endif ); return (LPSTR)buf; } int _export lsh_com_err_proc (LPSTR whoami, long code, LPSTR fmt, va_list args) { #ifdef USE_MESSAGE_BOX int retval; HWND hOldFocus; char buf[1024], *cp; /* changed to 512 by jms 8/23/93 */ WORD mbformat = MB_OK | MB_ICONEXCLAMATION; cp = buf; memset(buf, '\0', sizeof(buf)); cp[0] = '\0'; if (code) { err_describe(buf, code); while (*cp) cp++; } if (fmt) { if (fmt[0] == '%' && fmt[1] == 'b') { fmt += 2; mbformat = va_arg(args, WORD); /* if the first arg is a %b, we use it for the message box MB_??? flags. */ } if (code) { *cp++ = '\n'; *cp++ = '\n'; } wvsprintf((LPSTR)cp, fmt, args); } hOldFocus = GetFocus(); retval = MessageBox(/*GetRootParent(hOldFocus)*/NULL, buf, whoami, mbformat | MB_ICONHAND | MB_TASKMODAL); SetFocus(hOldFocus); return retval; #else return IDOK; #endif /* USE_MESSAGE_BOX */ } krb5-1.16/src/windows/leashdll/leashdll.h0000644000704600001450000002110413211554426020206 0ustar ghudsonlibuuid#ifndef _LEASHDLL_H_ #define _LEASHDLL_H_ #include #ifdef __cplusplus extern "C" { #endif #ifndef NO_KRB4 /* * This is a hack needed because the real com_err.h does * not define err_func. We need it in the case where * we pull in the real com_err instead of the krb4 * impostor. */ #ifndef _DCNS_MIT_COM_ERR_H typedef LPSTR (*err_func)(int, long); #endif #include extern void Leash_initialize_krb_error_func(err_func func,struct et_list **); #undef init_krb_err_func #define init_krb_err_func(erf) Leash_initialize_krb_error_func(erf,&_et_list) #include extern void Leash_initialize_kadm_error_table(struct et_list **); #undef init_kadm_err_tbl #define init_kadm_err_tbl() Leash_initialize_kadm_error_table(&_et_list) #define kadm_err_base ERROR_TABLE_BASE_kadm #endif #define krb_err_func Leash_krb_err_func #include int lsh_com_err_proc (LPSTR whoami, long code, LPSTR fmt, va_list args); void FAR Leash_load_com_err_callback(FARPROC,FARPROC,FARPROC); #ifndef KRBERR #define KRBERR(code) (code + krb_err_base) #endif /* Internal Stuff */ #include #define SECURITY_WIN32 #include /* _WIN32_WINNT must be 0x0501 or greater to pull in definition of * all required LSA data types when the Vista SDK NtSecAPI.h is used. */ #ifndef _WIN32_WINNT #define _WIN32_WINNT 0x0501 #else #if _WIN32_WINNT < 0x0501 #undef _WIN32_WINNT #define _WIN32_WINNT 0x0501 #endif #endif #include #include #ifndef NO_KRB4 extern HINSTANCE hKrb4; #endif extern HINSTANCE hKrb5; extern HINSTANCE hProfile; #define TIMEHOST "TIMEHOST" #define LEASH_DEBUG_CLASS_GENERIC 0 #define LEASH_DEBUG_CLASS_KRB4 1 #define LEASH_DEBUG_CLASS_KRB4_APP 2 #define LEASH_PRIORITY_LOW 0 #define LEASH_PRIORITY_HIGH 1 /////////////////////////////////////////////////////////////////////////////// #ifdef _WIN64 #define LEASH_DLL "leashw64.dll" #define KRBCC32_DLL "krbcc64.dll" #else #define LEASH_DLL "leashw32.dll" #define KRBCC32_DLL "krbcc32.dll" #endif #define SERVICE_DLL "advapi32.dll" #define SECUR32_DLL "secur32.dll" ////////////////////////////////////////////////////////////////////////////// #include #include #include #ifndef NO_KRB4 #include #include #endif #include #include #ifndef NO_AFS ////Can't find it! ////#include "afscompat.h" #endif // service definitions typedef SC_HANDLE (WINAPI *FP_OpenSCManagerA)(char *, char *, DWORD); typedef SC_HANDLE (WINAPI *FP_OpenServiceA)(SC_HANDLE, char *, DWORD); typedef BOOL (WINAPI *FP_QueryServiceStatus)(SC_HANDLE, LPSERVICE_STATUS); typedef BOOL (WINAPI *FP_CloseServiceHandle)(SC_HANDLE); ////////////////////////////////////////////////////////////////////////////// #ifndef NO_KRB4 // krb4 functions extern DECL_FUNC_PTR(get_krb_err_txt_entry); extern DECL_FUNC_PTR(k_isinst); extern DECL_FUNC_PTR(k_isname); extern DECL_FUNC_PTR(k_isrealm); extern DECL_FUNC_PTR(kadm_change_your_password); extern DECL_FUNC_PTR(kname_parse); extern DECL_FUNC_PTR(krb_get_cred); extern DECL_FUNC_PTR(krb_get_krbhst); extern DECL_FUNC_PTR(krb_get_lrealm); extern DECL_FUNC_PTR(krb_get_pw_in_tkt); extern DECL_FUNC_PTR(krb_get_tf_realm); extern DECL_FUNC_PTR(krb_mk_req); extern DECL_FUNC_PTR(krb_realmofhost); extern DECL_FUNC_PTR(tf_init); extern DECL_FUNC_PTR(tf_close); extern DECL_FUNC_PTR(tf_get_cred); extern DECL_FUNC_PTR(tf_get_pname); extern DECL_FUNC_PTR(tf_get_pinst); extern DECL_FUNC_PTR(LocalHostAddr); extern DECL_FUNC_PTR(tkt_string); extern DECL_FUNC_PTR(krb_set_tkt_string); extern DECL_FUNC_PTR(initialize_krb_error_func); extern DECL_FUNC_PTR(initialize_kadm_error_table); extern DECL_FUNC_PTR(dest_tkt); extern DECL_FUNC_PTR(lsh_LoadKrb4LeashErrorTables); // XXX extern DECL_FUNC_PTR(krb_in_tkt); extern DECL_FUNC_PTR(krb_save_credentials); extern DECL_FUNC_PTR(krb_get_krbconf2); extern DECL_FUNC_PTR(krb_get_krbrealm2); extern DECL_FUNC_PTR(krb_life_to_time); #endif // krb5 functions extern DECL_FUNC_PTR(krb5_change_password); extern DECL_FUNC_PTR(krb5_get_init_creds_opt_alloc); extern DECL_FUNC_PTR(krb5_get_init_creds_opt_free); extern DECL_FUNC_PTR(krb5_get_init_creds_opt_init); extern DECL_FUNC_PTR(krb5_get_init_creds_opt_set_tkt_life); extern DECL_FUNC_PTR(krb5_get_init_creds_opt_set_renew_life); extern DECL_FUNC_PTR(krb5_get_init_creds_opt_set_forwardable); extern DECL_FUNC_PTR(krb5_get_init_creds_opt_set_proxiable); extern DECL_FUNC_PTR(krb5_get_init_creds_opt_set_renew_life); extern DECL_FUNC_PTR(krb5_get_init_creds_opt_set_address_list); extern DECL_FUNC_PTR(krb5_get_init_creds_opt_set_out_ccache); extern DECL_FUNC_PTR(krb5_get_init_creds_password); extern DECL_FUNC_PTR(krb5_build_principal_ext); extern DECL_FUNC_PTR(krb5_cc_get_name); extern DECL_FUNC_PTR(krb5_cc_resolve); extern DECL_FUNC_PTR(krb5_cc_default); extern DECL_FUNC_PTR(krb5_cc_default_name); extern DECL_FUNC_PTR(krb5_cc_set_default_name); extern DECL_FUNC_PTR(krb5_cc_initialize); extern DECL_FUNC_PTR(krb5_cc_destroy); extern DECL_FUNC_PTR(krb5_cc_close); extern DECL_FUNC_PTR(krb5_cc_copy_creds); extern DECL_FUNC_PTR(krb5_cc_store_cred); // extern DECL_FUNC_PTR(krb5_cc_retrieve_cred); extern DECL_FUNC_PTR(krb5_cc_get_principal); extern DECL_FUNC_PTR(krb5_cc_start_seq_get); extern DECL_FUNC_PTR(krb5_cc_next_cred); extern DECL_FUNC_PTR(krb5_cc_end_seq_get); // extern DECL_FUNC_PTR(krb5_cc_remove_cred); extern DECL_FUNC_PTR(krb5_cc_set_flags); // extern DECL_FUNC_PTR(krb5_cc_get_type); extern DECL_FUNC_PTR(krb5_cc_get_full_name); extern DECL_FUNC_PTR(krb5_free_context); extern DECL_FUNC_PTR(krb5_free_cred_contents); extern DECL_FUNC_PTR(krb5_free_principal); extern DECL_FUNC_PTR(krb5_free_string); extern DECL_FUNC_PTR(krb5_get_in_tkt_with_password); extern DECL_FUNC_PTR(krb5_init_context); extern DECL_FUNC_PTR(krb5_parse_name); extern DECL_FUNC_PTR(krb5_timeofday); extern DECL_FUNC_PTR(krb5_timestamp_to_sfstring); extern DECL_FUNC_PTR(krb5_unparse_name); extern DECL_FUNC_PTR(krb5_get_credentials); extern DECL_FUNC_PTR(krb5_mk_req); extern DECL_FUNC_PTR(krb5_sname_to_principal); extern DECL_FUNC_PTR(krb5_get_credentials_renew); extern DECL_FUNC_PTR(krb5_free_data); extern DECL_FUNC_PTR(krb5_free_data_contents); // extern DECL_FUNC_PTR(krb5_get_realm_domain); extern DECL_FUNC_PTR(krb5_free_unparsed_name); extern DECL_FUNC_PTR(krb5_os_localaddr); extern DECL_FUNC_PTR(krb5_copy_keyblock_contents); extern DECL_FUNC_PTR(krb5_copy_data); extern DECL_FUNC_PTR(krb5_free_creds); extern DECL_FUNC_PTR(krb5_build_principal); extern DECL_FUNC_PTR(krb5_get_renewed_creds); extern DECL_FUNC_PTR(krb5_free_addresses); extern DECL_FUNC_PTR(krb5_get_default_config_files); extern DECL_FUNC_PTR(krb5_free_config_files); extern DECL_FUNC_PTR(krb5_get_default_realm); extern DECL_FUNC_PTR(krb5_free_ticket); extern DECL_FUNC_PTR(krb5_decode_ticket); extern DECL_FUNC_PTR(krb5_get_host_realm); extern DECL_FUNC_PTR(krb5_free_host_realm); extern DECL_FUNC_PTR(krb5_c_random_make_octets); extern DECL_FUNC_PTR(krb5_free_default_realm); extern DECL_FUNC_PTR(krb5_principal_compare); extern DECL_FUNC_PTR(krb5_string_to_deltat); extern DECL_FUNC_PTR(krb5_is_config_principal); extern DECL_FUNC_PTR(krb5_cccol_cursor_new); extern DECL_FUNC_PTR(krb5_cccol_cursor_next); extern DECL_FUNC_PTR(krb5_cccol_cursor_free); extern DECL_FUNC_PTR(krb5_cc_cache_match); extern DECL_FUNC_PTR(krb5_cc_get_type); extern DECL_FUNC_PTR(krb5_cc_new_unique); extern DECL_FUNC_PTR(krb5_cc_support_switch); extern DECL_FUNC_PTR(krb5_cc_switch); extern DECL_FUNC_PTR(krb5int_cc_user_set_default_name); #ifndef NO_KRB4 // Krb524 functions extern DECL_FUNC_PTR(krb524_init_ets); extern DECL_FUNC_PTR(krb524_convert_creds_kdc); #endif // ComErr functions extern DECL_FUNC_PTR(com_err); extern DECL_FUNC_PTR(error_message); // Profile functions extern DECL_FUNC_PTR(profile_init); extern DECL_FUNC_PTR(profile_release); extern DECL_FUNC_PTR(profile_get_subsection_names); extern DECL_FUNC_PTR(profile_free_list); extern DECL_FUNC_PTR(profile_get_string); extern DECL_FUNC_PTR(profile_release_string); extern DECL_FUNC_PTR(profile_get_integer); // Service functions extern DECL_FUNC_PTR(OpenSCManagerA); extern DECL_FUNC_PTR(OpenServiceA); extern DECL_FUNC_PTR(QueryServiceStatus); extern DECL_FUNC_PTR(CloseServiceHandle); extern DECL_FUNC_PTR(LsaNtStatusToWinError); // LSA Functions extern DECL_FUNC_PTR(LsaConnectUntrusted); extern DECL_FUNC_PTR(LsaLookupAuthenticationPackage); extern DECL_FUNC_PTR(LsaCallAuthenticationPackage); extern DECL_FUNC_PTR(LsaFreeReturnBuffer); extern DECL_FUNC_PTR(LsaGetLogonSessionData); #ifdef __cplusplus } #endif #endif /* _LEASHDLL_H_ */ krb5-1.16/src/windows/leashdll/lshcallb.c0000644000704600001450000000055113211554426020200 0ustar ghudsonlibuuid#include int (*Lcom_err)(LPSTR,long,LPSTR,...); LPSTR (*Lerror_message)(long); LPSTR (*Lerror_table_name)(long); void Leash_load_com_err_callback(FARPROC ce, FARPROC em, FARPROC etn) { (FARPROC)Lcom_err=ce; (FARPROC)Lerror_message=em; (FARPROC)Lerror_table_name=etn; } krb5-1.16/src/windows/leashdll/krb5routines.c0000644000704600001450000007163013211554426021056 0ustar ghudsonlibuuid// Module name: krb5routines.c #include #define SECURITY_WIN32 #include /* _WIN32_WINNT must be 0x0501 or greater to pull in definition of * all required LSA data types when the Vista SDK NtSecAPI.h is used. */ #ifndef _WIN32_WINNT #define _WIN32_WINNT 0x0501 #else #if _WIN32_WINNT < 0x0501 #undef _WIN32_WINNT #define _WIN32_WINNT 0x0501 #endif #endif #include #include #include #include #include #include /* Private Include files */ #include "leashdll.h" #include #include "leash-int.h" #define KRB5_DEFAULT_LIFE 60*60*10 /* 10 hours */ char *GetTicketFlag(krb5_creds *cred) { static char buf[32]; int i = 0; buf[i++] = ' '; buf[i++] = '('; if (cred->ticket_flags & TKT_FLG_FORWARDABLE) buf[i++] = 'F'; if (cred->ticket_flags & TKT_FLG_FORWARDED) buf[i++] = 'f'; if (cred->ticket_flags & TKT_FLG_PROXIABLE) buf[i++] = 'P'; if (cred->ticket_flags & TKT_FLG_PROXY) buf[i++] = 'p'; if (cred->ticket_flags & TKT_FLG_MAY_POSTDATE) buf[i++] = 'D'; if (cred->ticket_flags & TKT_FLG_POSTDATED) buf[i++] = 'd'; if (cred->ticket_flags & TKT_FLG_INVALID) buf[i++] = 'i'; if (cred->ticket_flags & TKT_FLG_RENEWABLE) buf[i++] = 'R'; if (cred->ticket_flags & TKT_FLG_INITIAL) buf[i++] = 'I'; if (cred->ticket_flags & TKT_FLG_HW_AUTH) buf[i++] = 'H'; if (cred->ticket_flags & TKT_FLG_PRE_AUTH) buf[i++] = 'A'; buf[i++] = ')'; buf[i] = '\0'; if (i <= 3) buf[0] = '\0'; return buf; } long Leash_convert524( krb5_context alt_ctx ) { #if defined(NO_KRB5) || defined(NO_KRB4) return(0); #else krb5_context ctx = 0; krb5_error_code code = 0; int icode = 0; krb5_principal me = 0; krb5_principal server = 0; krb5_creds *v5creds = 0; krb5_creds increds; krb5_ccache cc = 0; CREDENTIALS * v4creds = NULL; static int init_ets = 1; if (!pkrb5_init_context || !pkrb_in_tkt || !pkrb524_init_ets || !pkrb524_convert_creds_kdc) return 0; v4creds = (CREDENTIALS *) malloc(sizeof(CREDENTIALS)); memset((char *) v4creds, 0, sizeof(CREDENTIALS)); memset((char *) &increds, 0, sizeof(increds)); /* From this point on, we can goto cleanup because increds is initialized. */ if (alt_ctx) { ctx = alt_ctx; } else { code = pkrb5_init_context(&ctx); if (code) goto cleanup; } code = pkrb5_cc_default(ctx, &cc); if (code) goto cleanup; if ( init_ets ) { pkrb524_init_ets(ctx); init_ets = 0; } if (code = pkrb5_cc_get_principal(ctx, cc, &me)) goto cleanup; if ((code = pkrb5_build_principal(ctx, &server, krb5_princ_realm(ctx, me)->length, krb5_princ_realm(ctx, me)->data, "krbtgt", krb5_princ_realm(ctx, me)->data, NULL))) { goto cleanup; } increds.client = me; increds.server = server; increds.times.endtime = 0; increds.keyblock.enctype = ENCTYPE_DES_CBC_CRC; if ((code = pkrb5_get_credentials(ctx, 0, cc, &increds, &v5creds))) { goto cleanup; } if ((icode = pkrb524_convert_creds_kdc(ctx, v5creds, v4creds))) { goto cleanup; } /* initialize ticket cache */ if ((icode = pkrb_in_tkt(v4creds->pname, v4creds->pinst, v4creds->realm) != KSUCCESS)) { goto cleanup; } /* stash ticket, session key, etc. for future use */ if ((icode = pkrb_save_credentials(v4creds->service, v4creds->instance, v4creds->realm, v4creds->session, v4creds->lifetime, v4creds->kvno, &(v4creds->ticket_st), v4creds->issue_date))) { goto cleanup; } cleanup: memset(v4creds, 0, sizeof(v4creds)); free(v4creds); if (v5creds) { pkrb5_free_creds(ctx, v5creds); } if (increds.client == me) me = 0; if (increds.server == server) server = 0; pkrb5_free_cred_contents(ctx, &increds); if (server) { pkrb5_free_principal(ctx, server); } if (me) { pkrb5_free_principal(ctx, me); } pkrb5_cc_close(ctx, cc); if (ctx && (ctx != alt_ctx)) { pkrb5_free_context(ctx); } return !(code || icode); #endif /* NO_KRB5 */ } int LeashKRB5_renew(void) { #ifdef NO_KRB5 return(0); #else krb5_error_code code = 0; krb5_context ctx = 0; krb5_ccache cc = 0; krb5_principal me = 0; krb5_principal server = 0; krb5_creds my_creds; krb5_data *realm = 0; if ( !pkrb5_init_context ) goto cleanup; memset(&my_creds, 0, sizeof(krb5_creds)); code = pkrb5_init_context(&ctx); if (code) goto cleanup; code = pkrb5_cc_default(ctx, &cc); if (code) goto cleanup; code = pkrb5_cc_get_principal(ctx, cc, &me); if (code) goto cleanup; realm = krb5_princ_realm(ctx, me); code = pkrb5_build_principal_ext(ctx, &server, realm->length,realm->data, KRB5_TGS_NAME_SIZE, KRB5_TGS_NAME, realm->length,realm->data, 0); if ( code ) goto cleanup; my_creds.client = me; my_creds.server = server; #ifdef KRB5_TC_NOTICKET pkrb5_cc_set_flags(ctx, cc, 0); #endif code = pkrb5_get_renewed_creds(ctx, &my_creds, me, cc, NULL); #ifdef KRB5_TC_NOTICKET pkrb5_cc_set_flags(ctx, cc, KRB5_TC_NOTICKET); #endif if (code) { if ( code != KRB5KDC_ERR_ETYPE_NOSUPP || code != KRB5_KDC_UNREACH) Leash_krb5_error(code, "krb5_get_renewed_creds()", 0, &ctx, &cc); goto cleanup; } code = pkrb5_cc_initialize(ctx, cc, me); if (code) goto cleanup; code = pkrb5_cc_store_cred(ctx, cc, &my_creds); if (code) goto cleanup; cleanup: if (my_creds.client == me) my_creds.client = 0; if (my_creds.server == server) my_creds.server = 0; pkrb5_free_cred_contents(ctx, &my_creds); if (me) pkrb5_free_principal(ctx, me); if (server) pkrb5_free_principal(ctx, server); if (cc) pkrb5_cc_close(ctx, cc); if (ctx) pkrb5_free_context(ctx); return(code); #endif /* NO_KRB5 */ } #ifndef NO_KRB5 static krb5_error_code KRB5_CALLCONV leash_krb5_prompter( krb5_context context, void *data, const char *name, const char *banner, int num_prompts, krb5_prompt prompts[]); #endif /* NO_KRB5 */ int Leash_krb5_kinit( krb5_context alt_ctx, HWND hParent, char *principal_name, char *password, krb5_deltat lifetime, DWORD forwardable, DWORD proxiable, krb5_deltat renew_life, DWORD addressless, DWORD publicIP ) { #ifdef NO_KRB5 return(0); #else krb5_error_code code = 0; krb5_context ctx = 0; krb5_ccache cc = 0, defcache = 0; krb5_principal me = 0; char* name = 0; krb5_creds my_creds; krb5_get_init_creds_opt * options = NULL; krb5_address ** addrs = NULL; int i = 0, addr_count = 0; int cc_new = 0; const char * deftype = NULL; if (!pkrb5_init_context) return 0; memset(&my_creds, 0, sizeof(my_creds)); if (alt_ctx) { ctx = alt_ctx; } else { code = pkrb5_init_context(&ctx); if (code) goto cleanup; } code = pkrb5_get_init_creds_opt_alloc(ctx, &options); if (code) goto cleanup; code = pkrb5_cc_default(ctx, &defcache); if (code) goto cleanup; code = pkrb5_parse_name(ctx, principal_name, &me); if (code) goto cleanup; deftype = pkrb5_cc_get_type(ctx, defcache); if (me != NULL && pkrb5_cc_support_switch(ctx, deftype)) { /* Use an existing cache for the specified principal if we can. */ code = pkrb5_cc_cache_match(ctx, me, &cc); if (code != 0 && code != KRB5_CC_NOTFOUND) goto cleanup; if (code == KRB5_CC_NOTFOUND) { code = pkrb5_cc_new_unique(ctx, deftype, NULL, &cc); if (code) goto cleanup; cc_new = 1; } pkrb5_cc_close(ctx, defcache); } else { cc = defcache; } code = pkrb5_unparse_name(ctx, me, &name); if (code) goto cleanup; if (lifetime == 0) lifetime = Leash_get_default_lifetime(); else lifetime *= 5*60; if (renew_life > 0) renew_life *= 5*60; if (lifetime) pkrb5_get_init_creds_opt_set_tkt_life(options, lifetime); pkrb5_get_init_creds_opt_set_forwardable(options, forwardable ? 1 : 0); pkrb5_get_init_creds_opt_set_proxiable(options, proxiable ? 1 : 0); pkrb5_get_init_creds_opt_set_renew_life(options, renew_life); if (addressless) pkrb5_get_init_creds_opt_set_address_list(options,NULL); else { if (publicIP) { // we are going to add the public IP address specified by the user // to the list provided by the operating system krb5_address ** local_addrs=NULL; DWORD netIPAddr; pkrb5_os_localaddr(ctx, &local_addrs); while ( local_addrs[i++] ); addr_count = i + 1; addrs = (krb5_address **) malloc((addr_count+1) * sizeof(krb5_address *)); if ( !addrs ) { pkrb5_free_addresses(ctx, local_addrs); assert(0); } memset(addrs, 0, sizeof(krb5_address *) * (addr_count+1)); i = 0; while ( local_addrs[i] ) { addrs[i] = (krb5_address *)malloc(sizeof(krb5_address)); if (addrs[i] == NULL) { pkrb5_free_addresses(ctx, local_addrs); assert(0); } addrs[i]->magic = local_addrs[i]->magic; addrs[i]->addrtype = local_addrs[i]->addrtype; addrs[i]->length = local_addrs[i]->length; addrs[i]->contents = (unsigned char *)malloc(addrs[i]->length); if (!addrs[i]->contents) { pkrb5_free_addresses(ctx, local_addrs); assert(0); } memcpy(addrs[i]->contents,local_addrs[i]->contents, local_addrs[i]->length); /* safe */ i++; } pkrb5_free_addresses(ctx, local_addrs); addrs[i] = (krb5_address *)malloc(sizeof(krb5_address)); if (addrs[i] == NULL) assert(0); addrs[i]->magic = KV5M_ADDRESS; addrs[i]->addrtype = AF_INET; addrs[i]->length = 4; addrs[i]->contents = (unsigned char *)malloc(addrs[i]->length); if (!addrs[i]->contents) assert(0); netIPAddr = htonl(publicIP); memcpy(addrs[i]->contents,&netIPAddr,4); pkrb5_get_init_creds_opt_set_address_list(options,addrs); } } code = pkrb5_get_init_creds_opt_set_out_ccache(ctx, options, cc); if (code) goto cleanup; code = pkrb5_get_init_creds_password(ctx, &my_creds, me, password, // password leash_krb5_prompter, // prompter hParent, // prompter data 0, // start time 0, // service name options); // @TODO: make this an option if ((!code) && (cc != defcache)) { code = pkrb5_cc_switch(ctx, cc); if (!code) { const char *cctype = pkrb5_cc_get_type(ctx, cc); if (cctype != NULL) { char defname[20]; sprintf_s(defname, sizeof(defname), "%s:", cctype); pkrb5int_cc_user_set_default_name(ctx, defname); } } } cleanup: if (code && cc_new) { // don't leave newly-generated empty ccache lying around on failure pkrb5_cc_destroy(ctx, cc); cc = NULL; } if ( addrs ) { for ( i=0;icontents ) free(addrs[i]->contents); free(addrs[i]); } } } if (my_creds.client == me) my_creds.client = 0; pkrb5_free_cred_contents(ctx, &my_creds); if (name) pkrb5_free_unparsed_name(ctx, name); if (me) pkrb5_free_principal(ctx, me); if (cc) pkrb5_cc_close(ctx, cc); if (options) pkrb5_get_init_creds_opt_free(ctx, options); if (ctx && (ctx != alt_ctx)) pkrb5_free_context(ctx); return(code); #endif //!NO_KRB5 } /**************************************/ /* LeashKRB5destroyTicket(): */ /**************************************/ int Leash_krb5_kdestroy( void ) { #ifdef NO_KRB5 return(0); #else krb5_context ctx; krb5_ccache cache; krb5_error_code rc; ctx = NULL; cache = NULL; rc = Leash_krb5_initialize(&ctx); if (rc) return(rc); if (rc = pkrb5_cc_default(ctx, &cache)) return(rc); rc = pkrb5_cc_destroy(ctx, cache); if (ctx != NULL) pkrb5_free_context(ctx); return(rc); #endif //!NO_KRB5 } krb5_error_code Leash_krb5_cc_default(krb5_context *ctx, krb5_ccache *cache) { krb5_error_code rc; krb5_flags flags; char *functionName = NULL; if (*cache == 0) { rc = pkrb5_cc_default(*ctx, cache); if (rc) { functionName = "krb5_cc_default()"; goto on_error; } } #ifdef KRB5_TC_NOTICKET flags = KRB5_TC_NOTICKET; #endif rc = pkrb5_cc_set_flags(*ctx, *cache, flags); if (rc) { if (rc == KRB5_FCC_NOFILE || rc == KRB5_CC_NOTFOUND) { if (*cache != NULL && *ctx != NULL) pkrb5_cc_close(*ctx, *cache); } else { functionName = "krb5_cc_set_flags()"; goto on_error; } } on_error: if (rc && functionName) { Leash_krb5_error(rc, functionName, 0, ctx, cache); } return rc; } /**************************************/ /* Leash_krb5_initialize(): */ /**************************************/ int Leash_krb5_initialize(krb5_context *ctx) { #ifdef NO_KRB5 return(0); #else LPCSTR functionName = NULL; krb5_error_code rc; if (pkrb5_init_context == NULL) return 1; if (*ctx == 0) { if (rc = (*pkrb5_init_context)(ctx)) { functionName = "krb5_init_context()"; return Leash_krb5_error(rc, functionName, 0, ctx, NULL); } } return 0; #endif //!NO_KRB5 } /**************************************/ /* Leash_krb5_error(): */ /**************************************/ int Leash_krb5_error(krb5_error_code rc, LPCSTR FailedFunctionName, int FreeContextFlag, krb5_context * ctx, krb5_ccache * cache) { #ifdef NO_KRB5 return 0; #else #ifdef USE_MESSAGE_BOX char message[256]; const char *errText; errText = perror_message(rc); _snprintf(message, sizeof(message), "%s\n(Kerberos error %ld)\n\n%s failed", errText, rc, FailedFunctionName); message[sizeof(message)-1] = 0; MessageBox(NULL, message, "Kerberos Five", MB_OK | MB_ICONERROR | MB_TASKMODAL | MB_SETFOREGROUND); #endif /* USE_MESSAGE_BOX */ if (ctx != NULL && *ctx != NULL) { if (cache != NULL && *cache != NULL) { pkrb5_cc_close(*ctx, *cache); *cache = NULL; } if (FreeContextFlag) { pkrb5_free_context(*ctx); *ctx = NULL; } } return rc; #endif //!NO_KRB5 } BOOL Leash_ms2mit(BOOL save_creds) { #ifdef NO_KRB5 return(FALSE); #else /* NO_KRB5 */ krb5_context kcontext = 0; krb5_error_code code; krb5_ccache ccache=0; krb5_ccache mslsa_ccache=0; krb5_creds creds; krb5_cc_cursor cursor=0; krb5_principal princ = 0; BOOL rc = FALSE; if ( !pkrb5_init_context ) goto cleanup; if (code = pkrb5_init_context(&kcontext)) goto cleanup; if (code = pkrb5_cc_resolve(kcontext, "MSLSA:", &mslsa_ccache)) goto cleanup; if ( save_creds ) { if (code = pkrb5_cc_get_principal(kcontext, mslsa_ccache, &princ)) goto cleanup; if (code = pkrb5_cc_default(kcontext, &ccache)) goto cleanup; if (code = pkrb5_cc_initialize(kcontext, ccache, princ)) goto cleanup; if (code = pkrb5_cc_copy_creds(kcontext, mslsa_ccache, ccache)) goto cleanup; rc = TRUE; } else { /* Enumerate tickets from cache looking for an initial ticket */ if ((code = pkrb5_cc_start_seq_get(kcontext, mslsa_ccache, &cursor))) goto cleanup; while (!(code = pkrb5_cc_next_cred(kcontext, mslsa_ccache, &cursor, &creds))) { if ( creds.ticket_flags & TKT_FLG_INITIAL ) { rc = TRUE; pkrb5_free_cred_contents(kcontext, &creds); break; } pkrb5_free_cred_contents(kcontext, &creds); } pkrb5_cc_end_seq_get(kcontext, mslsa_ccache, &cursor); } cleanup: if (princ) pkrb5_free_principal(kcontext, princ); if (ccache) pkrb5_cc_close(kcontext, ccache); if (mslsa_ccache) pkrb5_cc_close(kcontext, mslsa_ccache); if (kcontext) pkrb5_free_context(kcontext); return(rc); #endif /* NO_KRB5 */ } #ifndef NO_KRB5 /* User Query data structures and functions */ struct textField { char * buf; /* Destination buffer address */ int len; /* Destination buffer length */ char * label; /* Label for this field */ char * def; /* Default response for this field */ int echo; /* 0 = no, 1 = yes, 2 = asterisks */ }; static int mid_cnt = 0; static struct textField * mid_tb = NULL; #define ID_TEXT 150 #define ID_MID_TEXT 300 static BOOL CALLBACK MultiInputDialogProc( HWND hDialog, UINT message, WPARAM wParam, LPARAM lParam) { int i; switch ( message ) { case WM_INITDIALOG: if ( GetDlgCtrlID((HWND) wParam) != ID_MID_TEXT ) { SetFocus(GetDlgItem( hDialog, ID_MID_TEXT)); return FALSE; } for ( i=0; i < mid_cnt ; i++ ) { if (mid_tb[i].echo == 0) SendDlgItemMessage(hDialog, ID_MID_TEXT+i, EM_SETPASSWORDCHAR, 32, 0); else if (mid_tb[i].echo == 2) SendDlgItemMessage(hDialog, ID_MID_TEXT+i, EM_SETPASSWORDCHAR, '*', 0); } return TRUE; case WM_COMMAND: switch ( LOWORD(wParam) ) { case IDOK: for ( i=0; i < mid_cnt ; i++ ) { if ( !GetDlgItemText(hDialog, ID_MID_TEXT+i, mid_tb[i].buf, mid_tb[i].len) ) *mid_tb[i].buf = '\0'; } /* fallthrough */ case IDCANCEL: EndDialog(hDialog, LOWORD(wParam)); return TRUE; } } return FALSE; } static LPWORD lpwAlign( LPWORD lpIn ) { ULONG ul; ul = (ULONG) lpIn; ul += 3; ul >>=2; ul <<=2; return (LPWORD) ul;; } /* * dialog widths are measured in 1/4 character widths * dialog height are measured in 1/8 character heights */ static LRESULT MultiInputDialog( HINSTANCE hinst, HWND hwndOwner, char * ptext[], int numlines, int width, int tb_cnt, struct textField * tb) { HGLOBAL hgbl; LPDLGTEMPLATE lpdt; LPDLGITEMTEMPLATE lpdit; LPWORD lpw; LPWSTR lpwsz; LRESULT ret; int nchar, i; size_t pwid; hgbl = GlobalAlloc(GMEM_ZEROINIT, 4096); if (!hgbl) return -1; mid_cnt = tb_cnt; mid_tb = tb; lpdt = (LPDLGTEMPLATE)GlobalLock(hgbl); // Define a dialog box. lpdt->style = WS_POPUP | WS_BORDER | WS_SYSMENU | DS_MODALFRAME | WS_CAPTION | DS_CENTER | DS_SETFOREGROUND | DS_3DLOOK | DS_SHELLFONT | DS_NOFAILCREATE; lpdt->cdit = numlines + (2 * tb_cnt) + 2; // number of controls lpdt->x = 10; lpdt->y = 10; lpdt->cx = 20 + width * 4; lpdt->cy = 20 + (numlines + tb_cnt + 4) * 14; lpw = (LPWORD) (lpdt + 1); *lpw++ = 0; // no menu *lpw++ = 0; // predefined dialog box class (by default) lpwsz = (LPWSTR) lpw; nchar = MultiByteToWideChar (CP_ACP, 0, "", -1, lpwsz, 128); lpw += nchar; *lpw++ = 8; // font size (points) lpwsz = (LPWSTR) lpw; nchar = MultiByteToWideChar (CP_ACP, 0, "MS Shell Dlg", -1, lpwsz, 128); lpw += nchar; //----------------------- // Define an OK button. //----------------------- lpw = lpwAlign (lpw); // align DLGITEMTEMPLATE on DWORD boundary lpdit = (LPDLGITEMTEMPLATE) lpw; lpdit->style = WS_CHILD | WS_VISIBLE | BS_DEFPUSHBUTTON | WS_TABSTOP | WS_BORDER; lpdit->dwExtendedStyle = 0; lpdit->x = (lpdt->cx - 14)/4 - 20; lpdit->y = 10 + (numlines + tb_cnt + 2) * 14; lpdit->cx = 40; lpdit->cy = 14; lpdit->id = IDOK; // OK button identifier lpw = (LPWORD) (lpdit + 1); *lpw++ = 0xFFFF; *lpw++ = 0x0080; // button class lpwsz = (LPWSTR) lpw; nchar = MultiByteToWideChar (CP_ACP, 0, "OK", -1, lpwsz, 50); lpw += nchar; *lpw++ = 0; // no creation data //----------------------- // Define an Cancel button. //----------------------- lpw = lpwAlign (lpw); // align DLGITEMTEMPLATE on DWORD boundary lpdit = (LPDLGITEMTEMPLATE) lpw; lpdit->style = WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON | WS_TABSTOP | WS_BORDER; lpdit->dwExtendedStyle = 0; lpdit->x = (lpdt->cx - 14)*3/4 - 20; lpdit->y = 10 + (numlines + tb_cnt + 2) * 14; lpdit->cx = 40; lpdit->cy = 14; lpdit->id = IDCANCEL; // CANCEL button identifier lpw = (LPWORD) (lpdit + 1); *lpw++ = 0xFFFF; *lpw++ = 0x0080; // button class lpwsz = (LPWSTR) lpw; nchar = MultiByteToWideChar (CP_ACP, 0, "Cancel", -1, lpwsz, 50); lpw += nchar; *lpw++ = 0; // no creation data /* Add controls for preface data */ for ( i=0; istyle = WS_CHILD | WS_VISIBLE | SS_LEFT; lpdit->dwExtendedStyle = 0; lpdit->x = 10; lpdit->y = 10 + i * 14; lpdit->cx = strlen(ptext[i]) * 4 + 10; lpdit->cy = 14; lpdit->id = ID_TEXT + i; // text identifier lpw = (LPWORD) (lpdit + 1); *lpw++ = 0xFFFF; *lpw++ = 0x0082; // static class lpwsz = (LPWSTR) lpw; nchar = MultiByteToWideChar (CP_ACP, 0, ptext[i], -1, lpwsz, 2*width); lpw += nchar; *lpw++ = 0; // no creation data } for ( i=0, pwid = 0; istyle = WS_CHILD | WS_VISIBLE | SS_LEFT; lpdit->dwExtendedStyle = 0; lpdit->x = 10; lpdit->y = 10 + (numlines + i + 1) * 14; lpdit->cx = pwid * 4; lpdit->cy = 14; lpdit->id = ID_TEXT + numlines + i; // text identifier lpw = (LPWORD) (lpdit + 1); *lpw++ = 0xFFFF; *lpw++ = 0x0082; // static class lpwsz = (LPWSTR) lpw; nchar = MultiByteToWideChar (CP_ACP, 0, tb[i].label ? tb[i].label : "", -1, lpwsz, 128); lpw += nchar; *lpw++ = 0; // no creation data /*----------------------- * Define an edit control. *-----------------------*/ lpw = lpwAlign (lpw); /* align DLGITEMTEMPLATE on DWORD boundary */ lpdit = (LPDLGITEMTEMPLATE) lpw; lpdit->style = WS_CHILD | WS_VISIBLE | ES_LEFT | WS_TABSTOP | WS_BORDER | (tb[i].echo == 1 ? 0L : ES_PASSWORD); lpdit->dwExtendedStyle = 0; lpdit->x = 10 + (pwid + 1) * 4; lpdit->y = 10 + (numlines + i + 1) * 14; lpdit->cx = (width - (pwid + 1)) * 4; lpdit->cy = 14; lpdit->id = ID_MID_TEXT + i; // identifier lpw = (LPWORD) (lpdit + 1); *lpw++ = 0xFFFF; *lpw++ = 0x0081; // edit class lpwsz = (LPWSTR) lpw; nchar = MultiByteToWideChar (CP_ACP, 0, tb[i].def ? tb[i].def : "", -1, lpwsz, 128); lpw += nchar; *lpw++ = 0; // no creation data } GlobalUnlock(hgbl); ret = DialogBoxIndirect(hinst, (LPDLGTEMPLATE) hgbl, hwndOwner, (DLGPROC) MultiInputDialogProc); GlobalFree(hgbl); switch ( ret ) { case 0: /* Timeout */ return -1; case IDOK: return 1; case IDCANCEL: return 0; default: { char buf[256]; sprintf(buf,"DialogBoxIndirect() failed: %d",GetLastError()); MessageBox(hwndOwner, buf, "GetLastError()", MB_OK | MB_ICONINFORMATION | MB_TASKMODAL); return -1; } } } static int multi_field_dialog(HWND hParent, char * preface, int n, struct textField tb[]) { extern HINSTANCE hLeashInst; size_t maxwidth = 0; int numlines = 0; size_t len; char * plines[16], *p = preface ? preface : ""; int i; for ( i=0; i<16; i++ ) plines[i] = NULL; while (*p && numlines < 16) { plines[numlines++] = p; for ( ;*p && *p != '\r' && *p != '\n'; p++ ); if ( *p == '\r' && *(p+1) == '\n' ) { *p++ = '\0'; p++; } else if ( *p == '\n' ) { *p++ = '\0'; } if ( strlen(plines[numlines-1]) > maxwidth ) maxwidth = strlen(plines[numlines-1]); } for ( i=0;i 40 ? 40 : tb[i].len); if ( maxwidth < len ) maxwidth = len; } return(MultiInputDialog(hLeashInst, hParent, plines, numlines, maxwidth, n, tb)); } static krb5_error_code KRB5_CALLCONV leash_krb5_prompter( krb5_context context, void *data, const char *name, const char *banner, int num_prompts, krb5_prompt prompts[]) { krb5_error_code errcode = 0; int i; struct textField * tb = NULL; int len = 0, blen=0, nlen=0; HWND hParent = (HWND)data; if (name) nlen = strlen(name)+2; if (banner) blen = strlen(banner)+2; tb = (struct textField *) malloc(sizeof(struct textField) * num_prompts); if ( tb != NULL ) { int ok; memset(tb,0,sizeof(struct textField) * num_prompts); for ( i=0; i < num_prompts; i++ ) { tb[i].buf = prompts[i].reply->data; tb[i].len = prompts[i].reply->length; tb[i].label = prompts[i].prompt; tb[i].def = NULL; tb[i].echo = (prompts[i].hidden ? 2 : 1); } ok = multi_field_dialog(hParent,(char *)banner,num_prompts,tb); if ( ok ) { for ( i=0; i < num_prompts; i++ ) prompts[i].reply->length = strlen(prompts[i].reply->data); } else errcode = -2; } if ( tb ) free(tb); if (errcode) { for (i = 0; i < num_prompts; i++) { memset(prompts[i].reply->data, 0, prompts[i].reply->length); } } return errcode; } #endif /* NO_KRB5 */ krb5-1.16/src/windows/leashdll/leash-int.h0000644000704600001450000002107713211554426020313 0ustar ghudsonlibuuid#ifndef __LEASH_INT_H__ #define __LEASH_INT_H__ #include #include #include "leashdll.h" #include #include "tlhelp32.h" #define MIT_PWD_DLL_CLASS "MITPasswordWndDLL" BOOL Register_MITPasswordEditControl( HINSTANCE hInst ); BOOL Unregister_MITPasswordEditControl( HINSTANCE hInst ); // Some defines swiped from leash.h // These are necessary but they must be kept sync'ed with leash.h #define HELPFILE "leash32.hlp" extern char KRB_HelpFile[_MAX_PATH]; // Function Prototypes. int lsh_com_err_proc (LPSTR whoami, long code, LPSTR fmt, va_list args); int DoNiftyErrorReport(long errnum, LPSTR what); LONG Leash_timesync(int); BOOL Leash_ms2mit(BOOL); #ifndef NO_AFS int not_an_API_LeashAFSGetToken(TICKETINFO * ticketinfo, TicketList** ticketList, char * kprinc); long FAR not_an_API_LeashFreeTicketList(TicketList** ticketList) ; #endif // Crap... #include long Leash_int_kinit_ex( krb5_context ctx, HWND hParent, char * principal, char * password, int lifetime, int forwardable, int proxiable, int renew_life, int addressless, unsigned long publicIP, int displayErrors ); long Leash_int_checkpwd( char * principal, char * password, int displayErrors ); long Leash_int_changepwd( char * principal, char * password, char * newpassword, char** result_string, int displayErrors ); int Leash_krb5_kdestroy( void ); int Leash_krb5_kinit( krb5_context, HWND hParent, char * principal_name, char * password, krb5_deltat lifetime, DWORD forwardable, DWORD proxiable, krb5_deltat renew_life, DWORD addressless, DWORD publicIP ); long Leash_convert524( krb5_context ctx ); int Leash_afs_unlog( void ); int Leash_afs_klog( char *, char *, char *, int ); int LeashKRB5_renew(void); LONG write_registry_setting( char* setting, DWORD type, void* buffer, size_t size ); LONG read_registry_setting_user( char* setting, void* buffer, size_t size ); LONG read_registry_setting( char* setting, void* buffer, size_t size ); BOOL get_STRING_from_registry( HKEY hBaseKey, char * key, char * value, char * outbuf, DWORD outlen ); BOOL get_DWORD_from_registry( HKEY hBaseKey, char * key, char * value, DWORD * result ); int config_boolean_to_int( const char *s ); BOOL GetSecurityLogonSessionData(PSECURITY_LOGON_SESSION_DATA * ppSessionData); BOOL IsKerberosLogon(VOID); #ifndef NO_KRB5 int Leash_krb5_error(krb5_error_code rc, LPCSTR FailedFunctionName, int FreeContextFlag, krb5_context *ctx, krb5_ccache *cache); int Leash_krb5_initialize(krb5_context *); krb5_error_code Leash_krb5_cc_default(krb5_context *ctx, krb5_ccache *cache); #endif /* NO_KRB5 */ LPSTR err_describe(LPSTR buf, long code); // toolhelp functions TYPEDEF_FUNC( HANDLE, WINAPI, CreateToolhelp32Snapshot, (DWORD, DWORD) ); TYPEDEF_FUNC( BOOL, WINAPI, Module32First, (HANDLE, LPMODULEENTRY32) ); TYPEDEF_FUNC( BOOL, WINAPI, Module32Next, (HANDLE, LPMODULEENTRY32) ); // psapi functions TYPEDEF_FUNC( DWORD, WINAPI, GetModuleFileNameExA, (HANDLE, HMODULE, LPSTR, DWORD) ); TYPEDEF_FUNC( BOOL, WINAPI, EnumProcessModules, (HANDLE, HMODULE*, DWORD, LPDWORD) ); #define pGetModuleFileNameEx pGetModuleFileNameExA #define TOOLHELPDLL "kernel32.dll" #define PSAPIDLL "psapi.dll" // psapi functions extern DECL_FUNC_PTR(GetModuleFileNameExA); extern DECL_FUNC_PTR(EnumProcessModules); // toolhelp functions extern DECL_FUNC_PTR(CreateToolhelp32Snapshot); extern DECL_FUNC_PTR(Module32First); extern DECL_FUNC_PTR(Module32Next); /* In order to avoid including the private CCAPI headers */ typedef int cc_int32; #define CC_API_VER_1 1 #define CC_API_VER_2 2 #define CCACHE_API cc_int32 /* ** The Official Error Codes */ #define CC_NOERROR 0 #define CC_BADNAME 1 #define CC_NOTFOUND 2 #define CC_END 3 #define CC_IO 4 #define CC_WRITE 5 #define CC_NOMEM 6 #define CC_FORMAT 7 #define CC_LOCKED 8 #define CC_BAD_API_VERSION 9 #define CC_NO_EXIST 10 #define CC_NOT_SUPP 11 #define CC_BAD_PARM 12 #define CC_ERR_CACHE_ATTACH 13 #define CC_ERR_CACHE_RELEASE 14 #define CC_ERR_CACHE_FULL 15 #define CC_ERR_CRED_VERSION 16 enum { CC_CRED_VUNKNOWN = 0, // For validation CC_CRED_V4 = 1, CC_CRED_V5 = 2, CC_CRED_VMAX = 3 // For validation }; typedef struct opaque_dll_control_block_type* apiCB; typedef struct _infoNC { char* name; char* principal; cc_int32 vers; } infoNC; TYPEDEF_FUNC( CCACHE_API, __cdecl, cc_initialize, ( apiCB** cc_ctx, // < DLL's primary control structure. // returned here, passed everywhere else cc_int32 api_version, // > ver supported by caller (use CC_API_VER_1) cc_int32* api_supported, // < if ~NULL, max ver supported by DLL const char** vendor // < if ~NULL, vendor name in read only C string ) ); TYPEDEF_FUNC( CCACHE_API, __cdecl, cc_shutdown, ( apiCB** cc_ctx // <> DLL's primary control structure. NULL after ) ); TYPEDEF_FUNC( CCACHE_API, __cdecl, cc_get_NC_info, ( apiCB* cc_ctx, // > DLL's primary control structure struct _infoNC*** ppNCi // < (NULL before call) null terminated, // list of a structs (free via cc_free_infoNC()) ) ); TYPEDEF_FUNC( CCACHE_API, __cdecl, cc_free_NC_info, ( apiCB* cc_ctx, struct _infoNC*** ppNCi // < free list of structs returned by // cc_get_cache_names(). set to NULL on return ) ); #define CCAPI_DLL "krbcc32.dll" /* The following definitions are summarized from KRB4, KRB5, Leash32, and * Leashw32 modules. They are current as of KfW 2.6.2. There is no * guarrantee that changes to other modules will be updated in this list. */ /* Must match the values used in Leash32.exe */ #define LEASH_SETTINGS_REGISTRY_KEY_NAME "Software\\MIT\\Leash32\\Settings" #define LEASH_SETTINGS_REGISTRY_VALUE_AFS_STATUS "AfsStatus" #define LEASH_SETTINGS_REGISTRY_VALUE_DEBUG_WINDOW "DebugWindow" #define LEASH_SETTINGS_REGISTRY_VALUE_LARGE_ICONS "LargeIcons" #define LEASH_SETTINGS_REGISTRY_VALUE_DESTROY_TKTS "DestroyTickets" #define LEASH_SETTINGS_REGISTRY_VALUE_LOW_TKT_ALARM "LowTicketAlarm" #define LEASH_SETTINGS_REGISTRY_VALUE_AUTO_RENEW_TKTS "AutoRenewTickets" #define LEASH_SETTINGS_REGISTRY_VALUE_UPPERCASEREALM "UpperCaseRealm" #define LEASH_SETTINGS_REGISTRY_VALUE_TIMEHOST "TIMEHOST" #define LEASH_SETTINGS_REGISTRY_VALUE_CREATE_MISSING_CFG "CreateMissingConfig" #define LEASH_SETTINGS_REGISTRY_VALUE_MSLSA_IMPORT "MsLsaImport" /* These values are defined and used within Leashw32.dll */ #define LEASH_REGISTRY_KEY_NAME "Software\\MIT\\Leash" #define LEASH_REGISTRY_VALUE_LIFETIME "lifetime" #define LEASH_REGISTRY_VALUE_RENEW_TILL "renew_till" #define LEASH_REGISTRY_VALUE_RENEWABLE "renewable" #define LEASH_REGISTRY_VALUE_FORWARDABLE "forwardable" #define LEASH_REGISTRY_VALUE_NOADDRESSES "noaddresses" #define LEASH_REGISTRY_VALUE_PROXIABLE "proxiable" #define LEASH_REGISTRY_VALUE_PUBLICIP "publicip" #define LEASH_REGISTRY_VALUE_USEKRB4 "usekrb4" #define LEASH_REGISTRY_VALUE_KINIT_OPT "hide_kinit_options" #define LEASH_REGISTRY_VALUE_LIFE_MIN "life_min" #define LEASH_REGISTRY_VALUE_LIFE_MAX "life_max" #define LEASH_REGISTRY_VALUE_RENEW_MIN "renew_min" #define LEASH_REGISTRY_VALUE_RENEW_MAX "renew_max" #define LEASH_REGISTRY_VALUE_LOCK_LOCATION "lock_file_locations" #define LEASH_REGISTRY_VALUE_PRESERVE_KINIT "preserve_kinit_options" /* must match values used within krbv4w32.dll */ #define KRB4_REGISTRY_KEY_NAME "Software\\MIT\\Kerberos4" #define KRB4_REGISTRY_VALUE_CONFIGFILE "config" #define KRB4_REGISTRY_VALUE_KRB_CONF "krb.conf" #define KRB4_REGISTRY_VALUE_KRB_REALMS "krb.realms" #define KRB4_REGISTRY_VALUE_TICKETFILE "ticketfile" /* must match values used within krb5_32.dll */ #define KRB5_REGISTRY_KEY_NAME "Software\\MIT\\Kerberos5" #define KRB5_REGISTRY_VALUE_CCNAME "ccname" #define KRB5_REGISTRY_VALUE_CONFIGFILE "config" /* must match values used within wshelper.dll */ #define WSHELP_REGISTRY_KEY_NAME "Software\\MIT\\WsHelper" #define WSHELP_REGISTRY_VALUE_DEBUG "DebugOn" #endif /* __LEASH_INT_H__ */ krb5-1.16/src/windows/leashdll/AFSroutines.c0000644000704600001450000005756613211554426020640 0ustar ghudsonlibuuid//* Module name: AFSroutines.c #include #include #include #include /* Private Include files */ #include #include #include "leashdll.h" #include #ifndef NO_AFS #include #include #include #include #endif #include "leash-int.h" #define MAXCELLCHARS 64 #define MAXHOSTCHARS 64 #define MAXHOSTSPERCELL 8 #define TRANSARCAFSDAEMON "TransarcAFSDaemon" typedef struct { char name[MAXCELLCHARS]; short numServers; short flags; struct sockaddr_in hostAddr[MAXHOSTSPERCELL]; char hostName[MAXHOSTSPERCELL][MAXHOSTCHARS]; char *linkedCell; } afsconf_cell; DWORD AfsOnLine = 1; extern DWORD AfsAvailable; int not_an_API_LeashAFSGetToken(TICKETINFO * ticketinfo, TicketList** ticketList, char * kprinc); DWORD GetServiceStatus(LPSTR lpszMachineName, LPSTR lpszServiceName, DWORD *lpdwCurrentState); BOOL SetAfsStatus(DWORD AfsStatus); BOOL GetAfsStatus(DWORD *AfsStatus); void Leash_afs_error(LONG rc, LPCSTR FailedFunctionName); static char *afs_realm_of_cell(afsconf_cell *); static long get_cellconfig_callback(void *, struct sockaddr_in *, char *); static int get_cellconfig(char *, afsconf_cell *, char *); /**************************************/ /* LeashAFSdestroyToken(): */ /**************************************/ int Leash_afs_unlog( void ) { #ifdef NO_AFS return(0); #else long rc; char HostName[64]; DWORD CurrentState; if (!AfsAvailable || GetAfsStatus(&AfsOnLine) && !AfsOnLine) return(0); CurrentState = 0; memset(HostName, '\0', sizeof(HostName)); gethostname(HostName, sizeof(HostName)); if (GetServiceStatus(HostName, TRANSARCAFSDAEMON, &CurrentState) != NOERROR) return(0); if (CurrentState != SERVICE_RUNNING) return(0); rc = ktc_ForgetAllTokens(); return(0); #endif } int not_an_API_LeashAFSGetToken( TICKETINFO * ticketinfo, TicketList** ticketList, char * kerberosPrincipal ) { #ifdef NO_AFS return(0); #else struct ktc_principal aserver; struct ktc_principal aclient; struct ktc_token atoken; int EndMonth; int EndDay; int cellNum; int BreakAtEnd; char UserName[64]; char CellName[64]; char ServiceName[64]; char InstanceName[64]; char EndTime[16]; char Buffer[256]; char Months[12][4] = {"Jan\0", "Feb\0", "Mar\0", "Apr\0", "May\0", "Jun\0", "Jul\0", "Aug\0", "Sep\0", "Oct\0", "Nov\0", "Dec\0"}; char TokenStatus[16]; time_t CurrentTime; struct tm *newtime; DWORD CurrentState; DWORD rc; char HostName[64]; TicketList* list = NULL; if ( ticketinfo ) { ticketinfo->btickets = NO_TICKETS; ticketinfo->principal[0] = '\0'; } if ( !kerberosPrincipal ) kerberosPrincipal = ""; if (!AfsAvailable || GetAfsStatus(&AfsOnLine) && !AfsOnLine) return(0); CurrentState = 0; memset(HostName, '\0', sizeof(HostName)); gethostname(HostName, sizeof(HostName)); if (GetServiceStatus(HostName, TRANSARCAFSDAEMON, &CurrentState) != NOERROR) return(0); if (CurrentState != SERVICE_RUNNING) return(0); BreakAtEnd = 0; cellNum = 0; while (1) { if (rc = ktc_ListTokens(cellNum, &cellNum, &aserver)) { if (rc != KTC_NOENT) return(0); if (BreakAtEnd == 1) break; } BreakAtEnd = 1; memset(&atoken, '\0', sizeof(atoken)); if (rc = ktc_GetToken(&aserver, &atoken, sizeof(atoken), &aclient)) { if (rc == KTC_ERROR) return(0); continue; } if (!list) { list = (TicketList*) calloc(1, sizeof(TicketList)); (*ticketList) = list; } else { list->next = (struct TicketList*) calloc(1, sizeof(TicketList)); list = (TicketList*) list->next; } CurrentTime = time(NULL); newtime = localtime(&atoken.endTime); memset(UserName, '\0', sizeof(UserName)); strcpy(UserName, aclient.name); memset(CellName, '\0', sizeof(CellName)); strcpy(CellName, aclient.cell); memset(InstanceName, '\0', sizeof(InstanceName)); strcpy(InstanceName, aclient.instance); memset(ServiceName, '\0', sizeof(ServiceName)); strcpy(ServiceName, aserver.name); memset(TokenStatus, '\0', sizeof(TokenStatus)); EndDay = newtime->tm_mday; EndMonth = newtime->tm_mon + 1;; sprintf(EndTime, "%02d:%02d:%02d", newtime->tm_hour, newtime->tm_min, newtime->tm_sec); sprintf(Buffer," %s %02d %s %s%s%s@%s %s", Months[EndMonth - 1], EndDay, EndTime, UserName, InstanceName[0] ? "." : "", InstanceName, CellName, TokenStatus); list->theTicket = (char*) calloc(1, sizeof(Buffer)); if (!list->theTicket) { #ifdef USE_MESSAGE_BOX MessageBox(NULL, "Memory Error", "Error", MB_OK); #endif /* USE_MESSAGE_BOX */ return ENOMEM; } strcpy(list->theTicket, Buffer); list->name = strdup(aclient.name); list->inst = aclient.instance[0] ? strdup(aclient.instance) : NULL; list->realm = strdup(aclient.cell); list->encTypes = NULL; list->addrCount = 0; list->addrList = NULL; if ( ticketinfo ) { sprintf(Buffer,"%s@%s",UserName,CellName); if (!ticketinfo->principal[0] || !stricmp(Buffer,kerberosPrincipal)) { strcpy(ticketinfo->principal, Buffer); ticketinfo->issue_date = 0; ticketinfo->lifetime = atoken.endTime; ticketinfo->renew_till = 0; _tzset(); if ( ticketinfo->lifetime - time(0) <= 0L ) ticketinfo->btickets = EXPD_TICKETS; else ticketinfo->btickets = GOOD_TICKETS; } } } return(0); #endif } static char OpenAFSConfigKeyName[] = "SOFTWARE\\OpenAFS\\Client"; static int use_krb524(void) { HKEY parmKey; DWORD code, len; DWORD use524 = 0; code = RegOpenKeyEx(HKEY_CURRENT_USER, OpenAFSConfigKeyName, 0, KEY_QUERY_VALUE, &parmKey); if (code == ERROR_SUCCESS) { len = sizeof(use524); code = RegQueryValueEx(parmKey, "Use524", NULL, NULL, (BYTE *) &use524, &len); RegCloseKey(parmKey); } if (code != ERROR_SUCCESS) { code = RegOpenKeyEx(HKEY_LOCAL_MACHINE, OpenAFSConfigKeyName, 0, KEY_QUERY_VALUE, &parmKey); if (code == ERROR_SUCCESS) { len = sizeof(use524); code = RegQueryValueEx(parmKey, "Use524", NULL, NULL, (BYTE *) &use524, &len); RegCloseKey (parmKey); } } return use524; } int Leash_afs_klog( char *service, char *cell, char *realm, int LifeTime ) { /////#ifdef NO_AFS #if defined(NO_AFS) || defined(NO_KRB4) return(0); #else long rc; ////This is defined in krb.h: CREDENTIALS creds; KTEXT_ST ticket; struct ktc_principal aserver; struct ktc_principal aclient; char realm_of_user[REALM_SZ]; /* Kerberos realm of user */ char realm_of_cell[REALM_SZ]; /* Kerberos realm of cell */ char local_cell[MAXCELLCHARS+1]; char Dmycell[MAXCELLCHARS+1]; struct ktc_token atoken; struct ktc_token btoken; afsconf_cell ak_cellconfig; /* General information about the cell */ char RealmName[128]; char CellName[128]; char ServiceName[128]; DWORD CurrentState; char HostName[64]; BOOL try_krb5 = 0; int retry = 0; int len; #ifndef NO_KRB5 krb5_context context = 0; krb5_ccache _krb425_ccache = 0; krb5_creds increds; krb5_creds * k5creds = 0; krb5_error_code r; krb5_principal client_principal = 0; krb5_flags flags = 0; #endif /* NO_KRB5 */ if (!AfsAvailable || GetAfsStatus(&AfsOnLine) && !AfsOnLine) return(0); if ( !realm ) realm = ""; if ( !cell ) cell = ""; if ( !service ) service = ""; CurrentState = 0; memset(HostName, '\0', sizeof(HostName)); gethostname(HostName, sizeof(HostName)); if (GetServiceStatus(HostName, TRANSARCAFSDAEMON, &CurrentState) != NOERROR) return(0); if (CurrentState != SERVICE_RUNNING) return(0); memset(RealmName, '\0', sizeof(RealmName)); memset(CellName, '\0', sizeof(CellName)); memset(ServiceName, '\0', sizeof(ServiceName)); memset(realm_of_user, '\0', sizeof(realm_of_user)); memset(realm_of_cell, '\0', sizeof(realm_of_cell)); memset(Dmycell, '\0', sizeof(Dmycell)); // NULL or empty cell returns information on local cell if (cell && cell[0]) strcpy(Dmycell, cell); rc = get_cellconfig(Dmycell, &ak_cellconfig, local_cell); if (rc && cell && cell[0]) { memset(Dmycell, '\0', sizeof(Dmycell)); rc = get_cellconfig(Dmycell, &ak_cellconfig, local_cell); } if (rc) return(rc); #ifndef NO_KRB5 if (!(r = Leash_krb5_initialize(&context, &_krb425_ccache))) { int i; memset((char *)&increds, 0, sizeof(increds)); (*pkrb5_cc_get_principal)(context, _krb425_ccache, &client_principal); i = krb5_princ_realm(context, client_principal)->length; if (i > REALM_SZ-1) i = REALM_SZ-1; strncpy(realm_of_user,krb5_princ_realm(context, client_principal)->data,i); realm_of_user[i] = 0; try_krb5 = 1; } #endif /* NO_KRB5 */ #ifndef NO_KRB4 if ( !try_krb5 || !realm_of_user[0] ) { if ((rc = (*pkrb_get_tf_realm)((*ptkt_string)(), realm_of_user)) != KSUCCESS) { return(rc); } } #endif strcpy(realm_of_cell, afs_realm_of_cell(&ak_cellconfig)); if (strlen(service) == 0) strcpy(ServiceName, "afs"); else strcpy(ServiceName, service); if (strlen(cell) == 0) strcpy(CellName, local_cell); else strcpy(CellName, cell); if (strlen(realm) == 0) strcpy(RealmName, realm_of_cell); else strcpy(RealmName, realm); memset(&creds, '\0', sizeof(creds)); #ifndef NO_KRB5 if ( try_krb5 ) { /* First try Service/Cell@REALM */ if (r = (*pkrb5_build_principal)(context, &increds.server, strlen(RealmName), RealmName, ServiceName, CellName, 0)) { try_krb5 = 0; goto use_krb4; } increds.client = client_principal; increds.times.endtime = 0; /* Ask for DES since that is what V4 understands */ increds.keyblock.enctype = ENCTYPE_DES_CBC_CRC; #ifdef KRB5_TC_NOTICKET flags = 0; r = pkrb5_cc_set_flags(context, _krb425_ccache, flags); #endif if (r == 0) r = pkrb5_get_credentials(context, 0, _krb425_ccache, &increds, &k5creds); if (r == KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN || r == KRB5KRB_ERR_GENERIC /* Heimdal */) { /* Next try Service@REALM */ pkrb5_free_principal(context, increds.server); r = pkrb5_build_principal(context, &increds.server, strlen(RealmName), RealmName, ServiceName, 0); if (r == 0) r = pkrb5_get_credentials(context, 0, _krb425_ccache, &increds, &k5creds); } pkrb5_free_principal(context, increds.server); pkrb5_free_principal(context, client_principal); #ifdef KRB5_TC_NOTICKET flags = KRB5_TC_NOTICKET; pkrb5_cc_set_flags(context, _krb425_ccache, flags); #endif (void) pkrb5_cc_close(context, _krb425_ccache); _krb425_ccache = 0; if (r || k5creds == 0) { pkrb5_free_context(context); try_krb5 = 0; goto use_krb4; } /* This code inserts the entire K5 ticket into the token * No need to perform a krb524 translation which is * commented out in the code below */ if ( use_krb524() || k5creds->ticket.length > MAXKTCTICKETLEN ) goto try_krb524d; memset(&aserver, '\0', sizeof(aserver)); strncpy(aserver.name, ServiceName, MAXKTCNAMELEN - 1); strncpy(aserver.cell, CellName, MAXKTCREALMLEN - 1); memset(&atoken, '\0', sizeof(atoken)); atoken.kvno = RXKAD_TKT_TYPE_KERBEROS_V5; atoken.startTime = k5creds->times.starttime; atoken.endTime = k5creds->times.endtime; memcpy(&atoken.sessionKey, k5creds->keyblock.contents, k5creds->keyblock.length); atoken.ticketLen = k5creds->ticket.length; memcpy(atoken.ticket, k5creds->ticket.data, atoken.ticketLen); retry_gettoken5: rc = ktc_GetToken(&aserver, &btoken, sizeof(btoken), &aclient); if (rc != 0 && rc != KTC_NOENT && rc != KTC_NOCELL) { if ( rc == KTC_NOCM && retry < 20 ) { Sleep(500); retry++; goto retry_gettoken5; } goto try_krb524d; } if (atoken.kvno == btoken.kvno && atoken.ticketLen == btoken.ticketLen && !memcmp(&atoken.sessionKey, &btoken.sessionKey, sizeof(atoken.sessionKey)) && !memcmp(atoken.ticket, btoken.ticket, atoken.ticketLen)) { /* Success */ pkrb5_free_creds(context, k5creds); pkrb5_free_context(context); return(0); } // * Reset the "aclient" structure before we call ktc_SetToken. // * This structure was first set by the ktc_GetToken call when // * we were comparing whether identical tokens already existed. len = min(k5creds->client->data[0].length,MAXKTCNAMELEN - 1); strncpy(aclient.name, k5creds->client->data[0].data, len); aclient.name[len] = '\0'; if ( k5creds->client->length > 1 ) { char * p; strcat(aclient.name, "."); p = aclient.name + strlen(aclient.name); len = min(k5creds->client->data[1].length,MAXKTCNAMELEN - strlen(aclient.name) - 1); strncpy(p, k5creds->client->data[1].data, len); p[len] = '\0'; } aclient.instance[0] = '\0'; strcpy(aclient.cell, realm_of_cell); len = min(k5creds->client->realm.length,strlen(realm_of_cell)); if ( strncmp(realm_of_cell, k5creds->client->realm.data, len) ) { char * p; strcat(aclient.name, "@"); p = aclient.name + strlen(aclient.name); len = min(k5creds->client->realm.length,MAXKTCNAMELEN - strlen(aclient.name) - 1); strncpy(p, k5creds->client->realm.data, len); p[len] = '\0'; } rc = ktc_SetToken(&aserver, &atoken, &aclient, 0); if (!rc) { /* Success */ pkrb5_free_creds(context, k5creds); pkrb5_free_context(context); return(0); } try_krb524d: /* This requires krb524d to be running with the KDC */ r = pkrb524_convert_creds_kdc(context, k5creds, &creds); pkrb5_free_creds(context, k5creds); pkrb5_free_context(context); if (r) { try_krb5 = 0; goto use_krb4; } rc = KSUCCESS; } else #endif /* NO_KRB5 */ { use_krb4: rc = KFAILURE; } if (rc != KSUCCESS) { return(rc); } memset(&aserver, '\0', sizeof(aserver)); strncpy(aserver.name, ServiceName, MAXKTCNAMELEN - 1); strncpy(aserver.cell, CellName, MAXKTCNAMELEN - 1); memset(&atoken, '\0', sizeof(atoken)); atoken.kvno = creds.kvno; atoken.startTime = creds.issue_date; atoken.endTime = (*pkrb_life_to_time)(creds.issue_date,creds.lifetime); memcpy(&atoken.sessionKey, creds.session, 8); atoken.ticketLen = creds.ticket_st.length; memcpy(atoken.ticket, creds.ticket_st.dat, atoken.ticketLen); if (!(rc = ktc_GetToken(&aserver, &btoken, sizeof(btoken), &aclient)) && atoken.kvno == btoken.kvno && atoken.ticketLen == btoken.ticketLen && !memcmp(&atoken.sessionKey, &btoken.sessionKey, sizeof(atoken.sessionKey)) && !memcmp(atoken.ticket, btoken.ticket, atoken.ticketLen)) { return(0); } // * Reset the "aclient" structure before we call ktc_SetToken. // * This structure was first set by the ktc_GetToken call when // * we were comparing whether identical tokens already existed. strncpy(aclient.name, creds.pname, MAXKTCNAMELEN - 1); aclient.name[MAXKTCNAMELEN - 1] = '\0'; if (creds.pinst[0]) { strncat(aclient.name, ".", MAXKTCNAMELEN - 1 - strlen(aclient.name)); aclient.name[MAXKTCNAMELEN - 1] = '\0'; strncat(aclient.name, creds.pinst, MAXKTCNAMELEN - 1 - strlen(aclient.name)); aclient.name[MAXKTCNAMELEN - 1] = '\0'; } strcpy(aclient.instance, ""); if ( strcmp(realm_of_cell, creds.realm) ) { strncat(aclient.name, "@", MAXKTCNAMELEN - 1 - strlen(aclient.name)); aclient.name[MAXKTCNAMELEN - 1] = '\0'; strncat(aclient.name, creds.realm, MAXKTCNAMELEN - 1 - strlen(aclient.name)); aclient.name[MAXKTCNAMELEN - 1] = '\0'; } aclient.name[MAXKTCNAMELEN-1] = '\0'; strcpy(aclient.cell, CellName); // * NOTE: On WIN32, the order of SetToken params changed... // * to ktc_SetToken(&aserver, &aclient, &atoken, 0) // * from ktc_SetToken(&aserver, &atoken, &aclient, 0) on Unix... // * The afscompat ktc_SetToken provides the Unix order if (rc = ktc_SetToken(&aserver, &atoken, &aclient, 0)) { Leash_afs_error(rc, "ktc_SetToken()"); return(rc); } return(0); #endif } /**************************************/ /* afs_realm_of_cell(): */ /**************************************/ static char *afs_realm_of_cell(afsconf_cell *cellconfig) { #ifdef NO_AFS return(0); #else char krbhst[MAX_HSTNM]=""; static char krbrlm[REALM_SZ+1]=""; #ifndef NO_KRB5 krb5_context ctx = 0; char ** realmlist=NULL; krb5_error_code r; #endif /* NO_KRB5 */ if (!cellconfig) return 0; #ifndef NO_KRB5 if ( pkrb5_init_context ) { r = pkrb5_init_context(&ctx); if ( !r ) r = pkrb5_get_host_realm(ctx, cellconfig->hostName[0], &realmlist); if ( !r && realmlist && realmlist[0] ) { strcpy(krbrlm, realmlist[0]); pkrb5_free_host_realm(ctx, realmlist); } if (ctx) pkrb5_free_context(ctx); } #endif /* NO_KRB5 */ if ( !krbrlm[0] ) { char *s = krbrlm; char *t = cellconfig->name; int c; while (c = *t++) { if (islower(c)) c=toupper(c); *s++ = c; } *s++ = 0; } return(krbrlm); #endif } /**************************************/ /* get_cellconfig(): */ /**************************************/ static int get_cellconfig(char *cell, afsconf_cell *cellconfig, char *local_cell) { #ifdef NO_AFS return(0); #else int rc; local_cell[0] = (char)0; memset(cellconfig, 0, sizeof(*cellconfig)); /* WIN32: cm_GetRootCellName(local_cell) - NOTE: no way to get max chars */ if (rc = cm_GetRootCellName(local_cell)) { return(rc); } if (strlen(cell) == 0) strcpy(cell, local_cell); /* WIN32: cm_SearchCellFile(cell, pcallback, pdata) */ strcpy(cellconfig->name, cell); return cm_SearchCell(cell, get_cellconfig_callback, NULL, (void*)cellconfig); #endif } /**************************************/ /* get_cellconfig_callback(): */ /**************************************/ static long get_cellconfig_callback(void *cellconfig, struct sockaddr_in *addrp, char *namep) { #ifdef NO_AFS return(0); #else afsconf_cell *cc = (afsconf_cell *)cellconfig; cc->hostAddr[cc->numServers] = *addrp; strcpy(cc->hostName[cc->numServers], namep); cc->numServers++; return(0); #endif } /**************************************/ /* Leash_afs_error(): */ /**************************************/ void Leash_afs_error(LONG rc, LPCSTR FailedFunctionName) { #ifdef NO_AFS return; #else #ifdef USE_MESSAGE_BOX char message[256]; const char *errText; // Using AFS defines as error messages for now, until Transarc // gets back to me with "string" translations of each of these // const. defines. if (rc == KTC_ERROR) errText = "KTC_ERROR"; else if (rc == KTC_TOOBIG) errText = "KTC_TOOBIG"; else if (rc == KTC_INVAL) errText = "KTC_INVAL"; else if (rc == KTC_NOENT) errText = "KTC_NOENT"; else if (rc == KTC_PIOCTLFAIL) errText = "KTC_PIOCTLFAIL"; else if (rc == KTC_NOPIOCTL) errText = "KTC_NOPIOCTL"; else if (rc == KTC_NOCELL) errText = "KTC_NOCELL"; else if (rc == KTC_NOCM) errText = "KTC_NOCM: The service, Transarc AFS Daemon, most likely is not started!"; else errText = "Unknown error!"; sprintf(message, "%s\n(%s failed)", errText, FailedFunctionName); MessageBox(NULL, message, "AFS", MB_OK | MB_ICONERROR | MB_TASKMODAL | MB_SETFOREGROUND); #endif /* USE_MESSAGE_BOX */ return; #endif } DWORD GetServiceStatus( LPSTR lpszMachineName, LPSTR lpszServiceName, DWORD *lpdwCurrentState) { #ifdef NO_AFS return(NOERROR); #else DWORD hr = NOERROR; SC_HANDLE schSCManager = NULL; SC_HANDLE schService = NULL; DWORD fdwDesiredAccess = 0; SERVICE_STATUS ssServiceStatus = {0}; BOOL fRet = FALSE; if ((pOpenSCManagerA == NULL) || (pOpenServiceA == NULL) || (pQueryServiceStatus == NULL) || (pCloseServiceHandle == NULL)) { *lpdwCurrentState = SERVICE_RUNNING; return(NOERROR); } *lpdwCurrentState = 0; fdwDesiredAccess = GENERIC_READ; schSCManager = (*pOpenSCManagerA)(lpszMachineName, NULL, fdwDesiredAccess); if(schSCManager == NULL) { hr = GetLastError(); goto cleanup; } schService = (*pOpenServiceA)(schSCManager, lpszServiceName, fdwDesiredAccess); if(schService == NULL) { hr = GetLastError(); goto cleanup; } fRet = (*pQueryServiceStatus)(schService, &ssServiceStatus); if(fRet == FALSE) { hr = GetLastError(); goto cleanup; } *lpdwCurrentState = ssServiceStatus.dwCurrentState; cleanup: (*pCloseServiceHandle)(schService); (*pCloseServiceHandle)(schSCManager); return(hr); #endif } BOOL SetAfsStatus( DWORD AfsStatus ) { #ifdef NO_AFS return(TRUE); #else return write_registry_setting(LEASH_SETTINGS_REGISTRY_VALUE_AFS_STATUS, REG_DWORD, &AfsStatus, sizeof(AfsStatus)) ? FALSE : TRUE; #endif } BOOL GetAfsStatus( DWORD *AfsStatus ) { #ifdef NO_AFS return(TRUE); #else return read_registry_setting(LEASH_SETTINGS_REGISTRY_VALUE_AFS_STATUS, AfsStatus, sizeof(DWORD)) ? FALSE : TRUE; #endif } krb5-1.16/src/windows/leashdll/lshutil.cpp0000644000704600001450000004271413211554426020447 0ustar ghudsonlibuuid/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* prototype/prototype.c - <<< One-line description of file >>> */ /* leashdll/lshutil.cpp - text maniuplation for principal entry */ /* * Copyright (C) 2012 by the Massachusetts Institute of Technology. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ /* * * Leash Principal Edit Control * * Edit control customized to enter a principal. * -Autocomplete functionality using history of previously successful * authentications * -Option to automatically convert realm to uppercase as user types * -Suggest default realm when no matches available from history */ #include #include // LPOLESTR #include // IAutoComplete #include // CLSID_AutoComplete #include // IAutoCompleteDropDown #include // CoCreateInstance #include #include #include #include "leashwin.h" #include "leashdll.h" #pragma comment(lib, "ole32.lib") // CoCreateInstance // // DynEnumString: // IEnumString implementation that can be dynamically updated after creation. // class DynEnumString : public IEnumString { public: // IUnknown STDMETHODIMP_(ULONG) AddRef() { return ++m_refcount; } STDMETHODIMP_(ULONG) Release() { ULONG refcount = --m_refcount; if (refcount == 0) delete this; return refcount; } STDMETHODIMP QueryInterface(REFIID riid, void** ppvObject) { IUnknown *punk = NULL; if (riid == IID_IUnknown) punk = static_cast(this); else if (riid == IID_IEnumString) punk = static_cast(this); *ppvObject = punk; if (punk == NULL) return E_NOINTERFACE; punk->AddRef(); return S_OK; } // IEnumString public: STDMETHODIMP Clone(IEnumString **ppclone) { LPTSTR *data = m_aStrings.data(); ULONG count = m_aStrings.size(); *ppclone = new DynEnumString(count, data); return S_OK; } STDMETHODIMP Next(ULONG count, LPOLESTR *elements, ULONG *pFetched) { ULONG fetched = 0; while (fetched < count) { if (m_iter == m_aStrings.end()) break; LPTSTR src = *m_iter++; // @TODO: add _UNICODE version DWORD nLengthW = ::MultiByteToWideChar(CP_ACP, 0, &src[0], -1, NULL, 0); LPOLESTR copy = (LPOLESTR )::CoTaskMemAlloc(sizeof(OLECHAR) * nLengthW); if (copy != NULL) { if (::MultiByteToWideChar(CP_ACP, 0, &src[0], -1, copy, nLengthW)) { elements[fetched++] = copy; } else { // failure... // TODO: debug spew ::CoTaskMemFree(copy); copy = NULL; } } } *pFetched = fetched; return fetched == count ? S_OK : S_FALSE; } STDMETHODIMP Reset() { m_iter = m_aStrings.begin(); return S_OK; } STDMETHODIMP Skip(ULONG count) { for (ULONG i=0; i::const_iterator i; for (i = m_aStrings.begin(); i != m_aStrings.end(); i++) { if (_tcscmp(*i, str) == 0) { delete[] (*i); m_aStrings.erase(i); break; } } } private: ULONG m_refcount; std::vector::iterator m_iter; std::vector m_aStrings; }; // Registry key to store history of successfully authenticated principals #define LEASH_REGISTRY_PRINCIPALS_KEY_NAME "Software\\MIT\\Leash\\Principals" // Free principal list obtained by getPrincipalList() static void freePrincipalList(LPTSTR *princs, int count) { int i; if (count) { for (i = 0; i < count; i++) if (princs[i]) free(princs[i]); delete[] princs; } } // Retrieve history of successfully authenticated principals from registry static void getPrincipalList(LPTSTR **outPrincs, int *outPrincCount) { DWORD count = 0; DWORD valCount = 0; DWORD maxLen = 0; LPTSTR tempValName = NULL; LPTSTR *princs = NULL; *outPrincs = NULL; HKEY hKey = NULL; unsigned long rc = RegCreateKeyEx(HKEY_CURRENT_USER, LEASH_REGISTRY_PRINCIPALS_KEY_NAME, 0, 0, 0, KEY_READ, 0, &hKey, 0); if (rc == S_OK) { // get string count rc = RegQueryInfoKey( hKey, NULL, // __out_opt LPTSTR lpClass, NULL, // __inout_opt LPDWORD lpcClass, NULL, // __reserved LPDWORD lpReserved, NULL, // __out_opt LPDWORD lpcSubKeys, NULL, // __out_opt LPDWORD lpcMaxSubKeyLen, NULL, // __out_opt LPDWORD lpcMaxClassLen, &valCount, //__out_opt LPDWORD lpcValues, &maxLen, // __out_opt LPDWORD lpcMaxValueNameLen, NULL, // __out_opt LPDWORD lpcMaxValueLen, NULL, // __out_opt LPDWORD lpcbSecurityDescriptor, NULL // __out_opt PFILETIME lpftLastWriteTime ); } if (valCount == 0) goto cleanup; princs = new LPTSTR[valCount]; if (princs == NULL) goto cleanup; tempValName = new TCHAR[maxLen+1]; if (tempValName == NULL) goto cleanup; // enumerate values... for (DWORD iReg = 0; iReg < valCount; iReg++) { LPTSTR princ = NULL; DWORD size = maxLen+1; rc = RegEnumValue(hKey, iReg, tempValName, &size, NULL, NULL, NULL, NULL); if (rc == ERROR_SUCCESS) princ = _tcsdup(tempValName); if (princ != NULL) princs[count++] = princ; } *outPrincCount = count; count = 0; *outPrincs = princs; princs = NULL; cleanup: if (tempValName) delete[] tempValName; if (princs) freePrincipalList(princs, count); if (hKey) RegCloseKey(hKey); return; } // HookWindow // Utility class to process messages relating to the specified hwnd class HookWindow { public: typedef std::pair map_elem; typedef std::map map; HookWindow(HWND in_hwnd) : m_hwnd(in_hwnd) { // add 'this' to static hash m_ctrl_id = GetDlgCtrlID(in_hwnd); m_parent = ::GetParent(m_hwnd); sm_map.insert(map_elem(m_parent, this)); // grab current window proc and replace with our wndproc m_parent_wndproc = SetWindowLongPtr(m_parent, GWLP_WNDPROC, (ULONG_PTR)(&sWindowProc)); } virtual ~HookWindow() { // unhook hwnd and restore old wndproc SetWindowLongPtr(m_parent, GWLP_WNDPROC, m_parent_wndproc); sm_map.erase(m_parent); } // Process a message // return 'false' to forward message to parent wndproc virtual bool WindowProc(UINT msg, WPARAM wParam, LPARAM lParam, LRESULT *lr) = 0; protected: static LRESULT sWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam); HWND m_hwnd; HWND m_parent; ULONG_PTR m_parent_wndproc; int m_ctrl_id; static map sm_map; }; HookWindow::map HookWindow::sm_map; LRESULT HookWindow::sWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { LRESULT result; // hash hwnd to get object and call actual window proc, // then parent window proc as necessary HookWindow::map::const_iterator iter = sm_map.find(hwnd); if (iter != sm_map.end()) { if (!iter->second->WindowProc(uMsg, wParam, lParam, &result)) result = CallWindowProc((WNDPROC )iter->second->m_parent_wndproc, hwnd, uMsg, wParam, lParam); } else { result = ::DefWindowProc(hwnd, uMsg, wParam, lParam); } return result; } // class PrincipalEditControl : public HookWindow { public: PrincipalEditControl(HWND hwnd, bool bUpperCaseRealm) : HookWindow(hwnd) ,m_ignore_change(0) ,m_bUpperCaseRealm(bUpperCaseRealm) ,m_defaultRealm(NULL) ,m_ctx(0) ,m_enumString(NULL) ,m_acdd(NULL) ,m_princStr(NULL) { pkrb5_init_context(&m_ctx); GetDefaultRealm(); InitAutocomplete(); } ~PrincipalEditControl() { DestroyAutocomplete(); if (m_princStr) delete[] m_princStr; if (m_ctx && m_defaultRealm) pkrb5_free_default_realm(m_ctx, m_defaultRealm); if (m_ctx) pkrb5_free_context(m_ctx); } void ClearHistory() { if (m_enumString != NULL) m_enumString->RemoveAll(); if (m_acdd != NULL) m_acdd->ResetEnumerator(); if (m_princStr != NULL) { delete[] m_princStr; m_princStr = NULL; } } protected: // Convert str to upper case // This should be more-or-less _UNICODE-agnostic static bool StrToUpper(LPTSTR str) { bool bChanged = false; int c; if (str != NULL) { while ((c = *str) != NULL) { if (__isascii(c) && islower(c)) { bChanged = true; *str = _toupper(c); } str++; } } return bChanged; } void GetDefaultRealm() { // @TODO: _UNICODE support here if ((m_defaultRealm == NULL) && m_ctx) { pkrb5_get_default_realm(m_ctx, &m_defaultRealm); } } // Append default realm to user and add to the autocomplete enum string void SuggestDefaultRealm(LPTSTR user) { if (m_defaultRealm == NULL) return; int princ_len = _tcslen(user) + _tcslen(m_defaultRealm) + 1; LPTSTR princStr = new TCHAR[princ_len]; if (princStr) { _sntprintf_s(princStr, princ_len, _TRUNCATE, "%s%s", user, m_defaultRealm); if (m_princStr != NULL && (_tcscmp(princStr, m_princStr) == 0)) { // this string is already added, ok to just bail delete[] princStr; } else { if (m_princStr != NULL) { // get rid of the old suggestion m_enumString->RemoveString(m_princStr); delete[] m_princStr; } // add the new one m_enumString->AddString(princStr); if (m_acdd != NULL) m_acdd->ResetEnumerator(); m_princStr = princStr; } } } bool AdjustRealmCase(LPTSTR princStr, LPTSTR realmStr) { bool bChanged = StrToUpper(realmStr); if (bChanged) { DWORD selStart, selEnd; ::SendMessage(m_hwnd, EM_GETSEL, (WPARAM)&selStart, (LPARAM)&selEnd); ::SetWindowText(m_hwnd, princStr); ::SendMessage(m_hwnd, EM_SETSEL, (WPARAM)selStart, (LPARAM)selEnd); } return bChanged; } bool ProcessText() { bool bChanged = false; int text_len = GetWindowTextLength(m_hwnd); if (text_len > 0) { LPTSTR str = new TCHAR [++text_len]; if (str != NULL) { GetWindowText(m_hwnd, str, text_len); LPTSTR realmStr = strchr(str, '@'); if (realmStr != NULL) { ++realmStr; if (*realmStr == 0) { SuggestDefaultRealm(str); } else if (m_bUpperCaseRealm) { AdjustRealmCase(str, realmStr); bChanged = true; } } delete[] str; } } return bChanged; } virtual bool WindowProc(UINT msg, WPARAM wp, LPARAM lp, LRESULT *lr) { bool bChanged = false; switch (msg) { case WM_COMMAND: if ((LOWORD(wp)==m_ctrl_id) && (HIWORD(wp)==EN_CHANGE)) { if ((!m_ignore_change++) && ProcessText()) { bChanged = true; *lr = 0; } m_ignore_change--; } default: break; } return bChanged; } void InitAutocomplete() { CoInitializeEx(NULL, COINIT_APARTMENTTHREADED); // read strings from registry LPTSTR *princs = NULL; int count = 0; getPrincipalList(&princs, &count); // Create our custom IEnumString implementation HRESULT hRes; DynEnumString *pEnumString = new DynEnumString(count, princs); if (princs) freePrincipalList(princs, count); m_enumString = pEnumString; // Create and initialize IAutoComplete object using IEnumString IAutoComplete *pac = NULL; hRes = CoCreateInstance(CLSID_AutoComplete, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&pac)); if (pac != NULL) { pac->Init(m_hwnd, pEnumString, NULL, NULL); IAutoCompleteDropDown* pacdd = NULL; hRes = pac->QueryInterface(IID_IAutoCompleteDropDown, (LPVOID*)&pacdd); pac->Release(); // @TODO: auto-suggest; other advanced options? #if 0 IAutoComplete2 *pac2; if (SUCCEEDED(pac->QueryInterface(IID_IAutoComplete2, (LPVOID*)&pac2))) { pac2->SetOptions(ACO_AUTOSUGGEST); pac2->Release(); } #endif m_acdd = pacdd; } } void DestroyAutocomplete() { if (m_acdd != NULL) m_acdd->Release(); if (m_enumString != NULL) m_enumString->Release(); } int m_ignore_change; bool m_bUpperCaseRealm; LPTSTR m_defaultRealm; LPTSTR m_princStr; krb5_context m_ctx; DynEnumString *m_enumString; IAutoCompleteDropDown *m_acdd; }; extern "C" void Leash_pec_add_principal(char *principal) { // write princ to registry HKEY hKey; unsigned long rc = RegCreateKeyEx(HKEY_CURRENT_USER, LEASH_REGISTRY_PRINCIPALS_KEY_NAME, 0, 0, 0, KEY_WRITE, 0, &hKey, 0); if (rc) { // TODO: log failure return; } rc = RegSetValueEx(hKey, principal, 0, REG_NONE, NULL, 0); if (rc) { // TODO: log failure } if (hKey) RegCloseKey(hKey); } extern "C" void Leash_pec_clear_history(void *pec) { // clear princs from registry RegDeleteKey(HKEY_CURRENT_USER, LEASH_REGISTRY_PRINCIPALS_KEY_NAME); // ...and from the specified widget static_cast(pec)->ClearHistory(); } extern "C" void *Leash_pec_create(HWND hEdit) { return new PrincipalEditControl( hEdit, Leash_get_default_uppercaserealm() ? true : false); } extern "C" void Leash_pec_destroy(void *pec) { if (pec != NULL) delete ((PrincipalEditControl *)pec); } krb5-1.16/src/windows/leashdll/registry.c0000644000704600001450000000402413211554426020263 0ustar ghudsonlibuuid#include #include "leash-int.h" static LONG write_registry_setting_ex( HKEY hRoot, char* setting, DWORD type, void* buffer, size_t size ) { HKEY hKey = 0; LONG rc = 0; if (rc = RegCreateKeyEx(hRoot, LEASH_SETTINGS_REGISTRY_KEY_NAME, 0, 0, 0, KEY_ALL_ACCESS, 0, &hKey, 0)) goto cleanup; rc = RegSetValueEx(hKey, setting, 0, type, (LPBYTE)buffer, size); cleanup: if (hKey) RegCloseKey(hKey); return rc; } LONG write_registry_setting( char* setting, DWORD type, void* buffer, size_t size ) { return write_registry_setting_ex(HKEY_CURRENT_USER, setting, type, buffer, size); } static LONG read_registry_setting_ex( HKEY hRoot, char* setting, void* buffer, size_t size ) { HKEY hKey = 0; LONG rc = 0; DWORD dwType; DWORD dwCount; if (rc = RegOpenKeyEx(hRoot, LEASH_SETTINGS_REGISTRY_KEY_NAME, 0, KEY_QUERY_VALUE, &hKey)) goto cleanup; memset(buffer, 0, size); dwCount = size; rc = RegQueryValueEx(hKey, setting, NULL, &dwType, (LPBYTE)buffer, &dwCount); cleanup: if (hKey) RegCloseKey(hKey); return rc; } LONG read_registry_setting_user( char* setting, void* buffer, size_t size ) { return read_registry_setting_ex(HKEY_CURRENT_USER, setting, buffer, size); } static LONG read_registry_setting_machine( char* setting, void* buffer, size_t size ) { return read_registry_setting_ex(HKEY_LOCAL_MACHINE, setting, buffer, size); } LONG read_registry_setting( char* setting, void* buffer, size_t size ) { LONG rc; rc = read_registry_setting_user(setting, buffer, size); if (!rc) return rc; rc = read_registry_setting_machine(setting, buffer, size); return rc; } krb5-1.16/src/windows/leashdll/lsh_pwd.rc0000644000704600001450000002102613211554426020236 0ustar ghudsonlibuuid//Microsoft Developer Studio generated resource script. // #include "resource.h" #define APSTUDIO_READONLY_SYMBOLS ///////////////////////////////////////////////////////////////////////////// // // Generated from the TEXTINCLUDE 2 resource. // #define APSTUDIO_HIDDEN_SYMBOLS #include "windows.h" #undef APSTUDIO_HIDDEN_SYMBOLS #include "leashids.h" #include "winver.h" ///////////////////////////////////////////////////////////////////////////// #undef APSTUDIO_READONLY_SYMBOLS ///////////////////////////////////////////////////////////////////////////// // English (U.S.) resources #if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) #ifdef _WIN32 LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US #pragma code_page(1252) #endif //_WIN32 ///////////////////////////////////////////////////////////////////////////// // // Bitmap // LOGOBITMAP BITMAP DISCARDABLE "res\\islogo.bmp" ///////////////////////////////////////////////////////////////////////////// // // Icon // // Icon with lowest ID value placed first to ensure application icon // remains consistent on all systems. LEASHICON ICON DISCARDABLE "res\\leash.ico" ///////////////////////////////////////////////////////////////////////////// // // Dialog // ENTERPASSWORDDLG DIALOG DISCARDABLE 23, 48, 262, 108 STYLE DS_MODALFRAME | WS_POPUP | WS_CLIPCHILDREN | WS_CAPTION | WS_SYSMENU CAPTION "Enter Password" FONT 10, "System" BEGIN EDITTEXT ID_PRINCIPAL,6,17,96,12,ES_AUTOHSCROLL LTEXT "Enter your username:",ID_PRINCCAPTION,6,7,140,8 DEFPUSHBUTTON "OK",IDOK,110,42,32,14 EDITTEXT ID_OLDPASSWORD,6,43,96,12,ES_PASSWORD | ES_AUTOHSCROLL LTEXT "Enter your password:",ID_OLDPCAPTION,6,33,91,8 EDITTEXT ID_DURATION,40,59,20,12 LTEXT "Duration:",-1,6,61,30,8 LTEXT "minutes",-1,62,61,64,8 ICON "LeashIcon",-1,6,78,18,20 PUSHBUTTON "&Cancel",IDCANCEL,30,78,32,14 PUSHBUTTON "&Restart",ID_RESTART,70,78,32,14 PUSHBUTTON "&Help",ID_HELP,110,78,32,14 CONTROL "",ID_PICFRAME,"Static",SS_BLACKFRAME,153,4,100,100 END CHANGEPASSWORDDLG DIALOG DISCARDABLE 27, 41, 270, 155 STYLE DS_MODALFRAME | WS_POPUP | WS_CLIPCHILDREN | WS_CAPTION | WS_SYSMENU CAPTION "Change Password" FONT 8, "System" BEGIN EDITTEXT ID_PRINCIPAL,6,35,96,12,ES_AUTOHSCROLL DEFPUSHBUTTON "OK",IDOK,110,60,32,14 EDITTEXT ID_OLDPASSWORD,6,61,96,12,ES_PASSWORD | ES_AUTOHSCROLL EDITTEXT ID_CONFIRMPASSWORD1,6,87,96,12,ES_PASSWORD | ES_AUTOHSCROLL EDITTEXT ID_CONFIRMPASSWORD2,6,113,96,12,ES_PASSWORD | ES_AUTOHSCROLL LTEXT "Enter your username:",ID_PRINCCAPTION,6,25,140,8 LTEXT "Enter your old password:",ID_OLDPCAPTION,6,51,91,8 LTEXT "Enter your new password:",ID_CONFIRMCAPTION1,6,77,96,8 LTEXT "Retype your new password:",ID_CONFIRMCAPTION2,6,103,100, 8 ICON "LeashIcon",-1,6,134,18,20 PUSHBUTTON "&Cancel",IDCANCEL,30,134,32,14 PUSHBUTTON "&Restart",ID_RESTART,70,134,32,14 PUSHBUTTON "&Help",ID_HELP,110,134,32,14 LTEXT "To change your password, fill in the following fields as they appear.", -1,6,3,140,21 CONTROL "",ID_PICFRAME,"Static",SS_BLACKFRAME,157,27,100,100 END IDD_AUTHENTICATE DIALOGEX 0, 0, 370, 248 STYLE DS_MODALFRAME | DS_3DLOOK | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "Authenticate to Kerberos" FONT 8, "Microsoft Sans Serif" BEGIN EDITTEXT IDC_EDIT_PRINCIPAL,89,42,199,14,ES_AUTOHSCROLL EDITTEXT IDC_EDIT_PASSWORD,89,58,259,14,ES_PASSWORD | ES_AUTOHSCROLL DEFPUSHBUTTON "OK",IDOK,302,219,49,14 PUSHBUTTON "Cancel",IDCANCEL,249,219,49,14 PUSHBUTTON "Hide Advanced",IDC_BUTTON_OPTIONS,146,219,89,14 PUSHBUTTON "Clear History",IDC_BUTTON_CLEAR_HISTORY,288,42,60,14 CONTROL "Remember this principal", IDC_CHECK_REMEMBER_PRINCIPAL, "Button", BS_AUTOCHECKBOX | WS_TABSTOP,89,72,100,14 CONTROL "Ticket Lifetime",IDC_SLIDER_LIFETIME,"msctls_trackbar32", TBS_BOTH | TBS_NOTICKS | WS_TABSTOP,90,97,258,15 CONTROL "Forwardable and Proxiable (can be forwarded to other machines)", IDC_CHECK_FORWARDABLE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,89,123,253,10 CONTROL "Renewable (can be renewed during the renewable lifetime)", IDC_CHECK_RENEWABLE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,89,135,253,10 CONTROL "Slider2",IDC_SLIDER_RENEWLIFE,"msctls_trackbar32", TBS_BOTH | TBS_NOTICKS | WS_TABSTOP,90,178,258,15 RTEXT "Principal:",IDC_STATIC_NAME,13,44,74,8 RTEXT "Password:",IDC_STATIC_PWD,13,60,74,8 RTEXT "Ticket Lifetime:",IDC_STATIC_LIFETIME,23,87,65,8,0, WS_EX_RIGHT LTEXT "Flag this ticket as:",IDC_STATIC_KRB5,32,123,56,8 LTEXT "HMS",IDC_STATIC_LIFETIME_VALUE,90,87,131,8 LTEXT "HMS",IDC_STATIC_RENEW_TILL_VALUE,90,164,141,8 ICON LEASHICON,IDC_PICTURE_LEASH,21,15,20,20 LTEXT "Please Authenticate", IDC_STATIC_NOTICE,51,23,276,8 RTEXT "Renewable Lifetime:",IDC_STATIC_RENEW,10,164,79,8 END IDD_PASSWORD DIALOG DISCARDABLE 0, 0, 382, 150 STYLE DS_MODALFRAME | DS_3DLOOK | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "Change Password" FONT 8, "Microsoft Sans Serif" BEGIN EDITTEXT IDC_EDIT_PRINCIPAL,99,40,259,14,ES_AUTOHSCROLL EDITTEXT IDC_EDIT_PASSWORD,99,60,259,14,ES_PASSWORD | ES_AUTOHSCROLL EDITTEXT IDC_EDIT_PASSWORD2,99,85,259,14,ES_PASSWORD | ES_AUTOHSCROLL EDITTEXT IDC_EDIT_PASSWORD3,99,105,259,14,ES_PASSWORD | ES_AUTOHSCROLL DEFPUSHBUTTON "OK",IDOK,313,125,49,14 PUSHBUTTON "Cancel",IDCANCEL,256,125,49,14 RTEXT "Principal:",IDC_STATIC_NAME,22,43,74,12 RTEXT "Old Password:",IDC_STATIC_PWD,22,63,74,12 ICON LEASHICON,IDC_PICTURE_LEASH,15,15,20,20 LTEXT "Change your Kerberos password or phrase", IDC_STATIC_NOTICE,48,20,276,8 RTEXT "New Password:",IDC_STATIC_PWD2,22,88,74,12 RTEXT "New Password (again):",IDC_STATIC_PWD3,22,108,74,12 END #ifdef APSTUDIO_INVOKED ///////////////////////////////////////////////////////////////////////////// // // TEXTINCLUDE // 1 TEXTINCLUDE DISCARDABLE BEGIN "resource.h\0" END 2 TEXTINCLUDE DISCARDABLE BEGIN "#define APSTUDIO_HIDDEN_SYMBOLS\r\n" "#include ""windows.h""\r\n" "#undef APSTUDIO_HIDDEN_SYMBOLS\r\n" "#include ""leashids.h""\r\n" "#include ""ver.h""\r\n" "\0" END 3 TEXTINCLUDE DISCARDABLE BEGIN "\r\n" "#include ""..\\version.rc""\r\n" "\0" END #endif // APSTUDIO_INVOKED ///////////////////////////////////////////////////////////////////////////// // // DESIGNINFO // #ifdef APSTUDIO_INVOKED GUIDELINES DESIGNINFO DISCARDABLE BEGIN IDD_PASSWORD, DIALOG BEGIN LEFTMARGIN, 7 RIGHTMARGIN, 375 TOPMARGIN, 7 BOTTOMMARGIN, 191 END END #endif // APSTUDIO_INVOKED ///////////////////////////////////////////////////////////////////////////// // // String Table // STRINGTABLE DISCARDABLE BEGIN LSH_TIME_HOST "time" LSH_DEFAULT_TICKET_LIFE "600" LSH_DEFAULT_TICKET_RENEW_TILL "10080" LSH_DEFAULT_TICKET_FORWARD "1" LSH_DEFAULT_TICKET_NOADDRESS "1" LSH_DEFAULT_TICKET_PROXIABLE "0" LSH_DEFAULT_TICKET_PUBLICIP "0" LSH_DEFAULT_TICKET_USEKRB4 "0" LSH_DEFAULT_DIALOG_KINIT_OPT "1" LSH_DEFAULT_DIALOG_LIFE_MIN "30" LSH_DEFAULT_DIALOG_LIFE_MAX "1440" LSH_DEFAULT_DIALOG_RENEW_MIN "600" LSH_DEFAULT_DIALOG_RENEW_MAX "43200" LSH_DEFAULT_TICKET_RENEW "1" LSH_DEFAULT_UPPERCASEREALM "1" LSH_DEFAULT_MSLSA_IMPORT "2" LSH_DEFAULT_PRESERVE_KINIT "0" END STRINGTABLE DISCARDABLE BEGIN LSH_DEFAULT_DIALOG_LOCK_LOCATION "0" END #endif // English (U.S.) resources ///////////////////////////////////////////////////////////////////////////// #ifndef APSTUDIO_INVOKED ///////////////////////////////////////////////////////////////////////////// // // Generated from the TEXTINCLUDE 3 resource. // #include "..\version.rc" ///////////////////////////////////////////////////////////////////////////// #endif // not APSTUDIO_INVOKED krb5-1.16/src/windows/leashdll/reminder.h0000644000704600001450000000065113211554426020227 0ustar ghudsonlibuuid#ifndef __REMINDER_H__ #define __REMINDER_H__ #define Stringize( L ) #L #define MakeString( M, L ) M(L) #define $LINE MakeString( Stringize, __LINE__ ) #define Reminder __FILE__ "(" $LINE ") : Reminder: " #endif //Put this in your .cpp file where ever you need it (NOTE: Don't end this statement with a ';' char) //i.e. -->> #pragma message(Reminder "Your message reminder here!!!") krb5-1.16/src/windows/leashdll/winutil.c0000644000704600001450000000640013211554426020106 0ustar ghudsonlibuuid#include #include "leash-int.h" //#include static ATOM sAtom = 0; static HINSTANCE shInstance = 0; /* Callback for the MITPasswordControl This is a replacement for the normal edit control. It does not show the annoying password char in the edit box so that the number of chars in the password are not known. */ #define PASSWORDCHAR '#' #define DLGHT(ht) (HIWORD(GetDialogBaseUnits())*(ht)/8) #define DLGWD(wd) (LOWORD(GetDialogBaseUnits())*(wd)/4) static LRESULT CALLBACK MITPasswordEditProc( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam ) { static SIZE pwdcharsz; BOOL pass_the_buck = FALSE; if (message > WM_USER && message < 0x7FFF) pass_the_buck = TRUE; switch(message) { case WM_GETTEXT: case WM_GETTEXTLENGTH: case WM_SETTEXT: pass_the_buck = TRUE; break; case WM_PAINT: { HDC hdc; PAINTSTRUCT ps; RECT r; hdc = BeginPaint(hWnd, &ps); GetClientRect(hWnd, &r); Rectangle(hdc, 0, 0, r.right, r.bottom); EndPaint(hWnd, &ps); } break; case WM_SIZE: { MoveWindow(GetDlgItem(hWnd, 1), DLGWD(2), DLGHT(2), pwdcharsz.cx / 2, pwdcharsz.cy, TRUE); } break; case WM_LBUTTONDOWN: case WM_SETFOCUS: { SetFocus(GetDlgItem(hWnd, 1)); } break; case WM_CREATE: { HWND heditchild; char pwdchar = PASSWORDCHAR; HDC hdc; /* Create a child window of this control for default processing. */ hdc = GetDC(hWnd); GetTextExtentPoint32(hdc, &pwdchar, 1, &pwdcharsz); ReleaseDC(hWnd, hdc); heditchild = CreateWindow("edit", "", WS_CHILD | WS_VISIBLE | ES_AUTOHSCROLL | ES_LEFT | ES_PASSWORD | WS_TABSTOP, 0, 0, 0, 0, hWnd, (HMENU)1, ((LPCREATESTRUCT)lParam)->hInstance, NULL); SendMessage(heditchild, EM_SETPASSWORDCHAR, PASSWORDCHAR, 0L); } break; } if (pass_the_buck) return SendMessage(GetDlgItem(hWnd, 1), message, wParam, lParam); return DefWindowProc(hWnd, message, wParam, lParam); } BOOL Register_MITPasswordEditControl( HINSTANCE hInst ) { if (!sAtom) { WNDCLASS wndclass; memset(&wndclass, 0, sizeof(WNDCLASS)); shInstance = hInst; wndclass.style = CS_HREDRAW | CS_VREDRAW; wndclass.lpfnWndProc = (WNDPROC)MITPasswordEditProc; wndclass.cbClsExtra = sizeof(HWND); wndclass.cbWndExtra = 0; wndclass.hInstance = shInstance; wndclass.hbrBackground = (void *)(COLOR_WINDOW + 1); wndclass.lpszClassName = MIT_PWD_DLL_CLASS; wndclass.hCursor = LoadCursor((HINSTANCE)NULL, IDC_IBEAM); sAtom = RegisterClass(&wndclass); } return sAtom ? TRUE : FALSE; } BOOL Unregister_MITPasswordEditControl( HINSTANCE hInst ) { BOOL result = TRUE; if ((hInst != shInstance) || !sAtom) { SetLastError(ERROR_INVALID_PARAMETER); return FALSE; } result = UnregisterClass(MIT_PWD_DLL_CLASS, hInst); if (result) { sAtom = 0; shInstance = 0; } return result; } krb5-1.16/src/windows/leashdll/lsh_pwd.c0000644000704600001450000016621213211554426020063 0ustar ghudsonlibuuid#define SCALE_FACTOR 31/20 /* LSH_PWD.C Jason Hunter 8/2/94 DCNS/IS MIT Re-written for KFW 2.6 by Jeffrey Altman Contains the callback functions for the EnterPassword an ChangePassword dialog boxes and well as the API function calls: Lsh_Enter_Password_Dialog Lsh_Change_Password_Dialog for calling the dialogs. Also contains the callback for the MITPasswordControl. */ /* Standard Include files */ #include #include #include /* Private Inlclude files */ #include "leashdll.h" #include #include #include "leash-int.h" #include "leashids.h" #include #ifndef NO_KRB5 #include #endif /* NO_KRB5 */ #include extern void * Leash_pec_create(HWND hEditCtl); extern void Leash_pec_destroy(void *pAutoComplete); extern void Leash_pec_add_principal(char *principal); extern void Leash_pec_clear_history(void *pec); /* Global Variables. */ static long lsh_errno; static char *err_context; /* error context */ extern HINSTANCE hLeashInst; extern HINSTANCE hKrb4; extern HINSTANCE hKrb5; INT_PTR CALLBACK PasswordProc( HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam ); INT_PTR CALLBACK AuthenticateProc( HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam ); INT_PTR CALLBACK NewPasswordProc( HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam ); long Leash_get_lsh_errno(LONG *err_val) { return lsh_errno; } /*/////// ******** API Calls follow here. ******** /////////*/ static int NetId_dialog(LPLSH_DLGINFO lpdlginfo) { LRESULT lrc; HWND hNetIdMgr; HWND hForeground; hNetIdMgr = FindWindow("IDMgrRequestDaemonCls", "IDMgrRequestDaemon"); if (hNetIdMgr != NULL) { char desiredPrincipal[512]; NETID_DLGINFO *dlginfo; char *desiredName = 0; char *desiredRealm = 0; HANDLE hMap; DWORD tid = GetCurrentThreadId(); char mapname[256]; strcpy(desiredPrincipal, lpdlginfo->principal); /* do we want a specific client principal? */ if (desiredPrincipal[0]) { char * p; desiredName = desiredPrincipal; for (p = desiredName; *p && *p != '@'; p++); if ( *p == '@' ) { *p = '\0'; desiredRealm = ++p; } } sprintf(mapname,"Local\\NetIDMgr_DlgInfo_%lu",tid); hMap = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, 4096, mapname); if (hMap == NULL) { return -1; } else if (hMap != NULL && GetLastError() == ERROR_ALREADY_EXISTS) { CloseHandle(hMap); return -1; } dlginfo = (NETID_DLGINFO *)MapViewOfFileEx(hMap, FILE_MAP_READ|FILE_MAP_WRITE, 0, 0, 4096, NULL); if (dlginfo == NULL) { CloseHandle(hMap); return -1; } hForeground = GetForegroundWindow(); memset(dlginfo, 0, sizeof(NETID_DLGINFO)); dlginfo->size = sizeof(NETID_DLGINFO); if (lpdlginfo->dlgtype == DLGTYPE_PASSWD) dlginfo->dlgtype = NETID_DLGTYPE_TGT; else dlginfo->dlgtype = NETID_DLGTYPE_CHPASSWD; dlginfo->in.use_defaults = 1; if (lpdlginfo->title) { MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED|MB_ERR_INVALID_CHARS, lpdlginfo->title, -1, dlginfo->in.title, NETID_TITLE_SZ); } else if (desiredName && (strlen(desiredName) + strlen(desiredRealm) + 32 < NETID_TITLE_SZ)) { char mytitle[NETID_TITLE_SZ]; sprintf(mytitle, "Obtain Kerberos TGT for %s@%s",desiredName,desiredRealm); MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED|MB_ERR_INVALID_CHARS, mytitle, -1, dlginfo->in.title, NETID_TITLE_SZ); } else { MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED|MB_ERR_INVALID_CHARS, "Obtain Kerberos TGT", -1, dlginfo->in.title, NETID_TITLE_SZ); } if (desiredName) MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED|MB_ERR_INVALID_CHARS, desiredName, -1, dlginfo->in.username, NETID_USERNAME_SZ); if (desiredRealm) MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED|MB_ERR_INVALID_CHARS, desiredRealm, -1, dlginfo->in.realm, NETID_REALM_SZ); lrc = SendMessage(hNetIdMgr, 32810, 0, (LPARAM) tid); UnmapViewOfFile(dlginfo); CloseHandle(hMap); SetForegroundWindow(hForeground); return lrc; } return -1; } static int NetId_dialog_ex(LPLSH_DLGINFO_EX lpdlginfo) { HWND hNetIdMgr; HWND hForeground; hNetIdMgr = FindWindow("IDMgrRequestDaemonCls", "IDMgrRequestDaemon"); if (hNetIdMgr != NULL) { NETID_DLGINFO *dlginfo; char *desiredName = lpdlginfo->username; char *desiredRealm = lpdlginfo->realm; LPSTR title; char *ccache; LRESULT lrc; HANDLE hMap; DWORD tid = GetCurrentThreadId(); char mapname[256]; sprintf(mapname,"Local\\NetIDMgr_DlgInfo_%lu",tid); hMap = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, 4096, mapname); if (hMap == NULL) { return -1; } else if (hMap != NULL && GetLastError() == ERROR_ALREADY_EXISTS) { CloseHandle(hMap); return -1; } dlginfo = (NETID_DLGINFO *)MapViewOfFileEx(hMap, FILE_MAP_READ|FILE_MAP_WRITE, 0, 0, 4096, NULL); if (dlginfo == NULL) { CloseHandle(hMap); return -1; } hForeground = GetForegroundWindow(); if (lpdlginfo->size == LSH_DLGINFO_EX_V1_SZ || lpdlginfo->size == LSH_DLGINFO_EX_V2_SZ) { title = lpdlginfo->title; desiredName = lpdlginfo->username; desiredRealm = lpdlginfo->realm; ccache = NULL; } else { title = lpdlginfo->in.title; desiredName = lpdlginfo->in.username; desiredRealm = lpdlginfo->in.realm; ccache = lpdlginfo->in.ccache; } memset(dlginfo, 0, sizeof(NETID_DLGINFO)); dlginfo->size = sizeof(NETID_DLGINFO); if (lpdlginfo->dlgtype == DLGTYPE_PASSWD) dlginfo->dlgtype = NETID_DLGTYPE_TGT; else dlginfo->dlgtype = NETID_DLGTYPE_CHPASSWD; dlginfo->in.use_defaults = lpdlginfo->use_defaults; dlginfo->in.forwardable = lpdlginfo->forwardable; dlginfo->in.noaddresses = lpdlginfo->noaddresses; dlginfo->in.lifetime = lpdlginfo->lifetime; dlginfo->in.renew_till = lpdlginfo->renew_till; dlginfo->in.proxiable = lpdlginfo->proxiable; dlginfo->in.publicip = lpdlginfo->publicip; if (title) { MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED|MB_ERR_INVALID_CHARS, title, -1, dlginfo->in.title, NETID_TITLE_SZ); } else if (desiredName && (strlen(desiredName) + strlen(desiredRealm) + 32 < NETID_TITLE_SZ)) { char mytitle[NETID_TITLE_SZ]; sprintf(mytitle, "Obtain Kerberos TGT for %s@%s",desiredName,desiredRealm); MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED|MB_ERR_INVALID_CHARS, mytitle, -1, dlginfo->in.title, NETID_TITLE_SZ); } else { MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED|MB_ERR_INVALID_CHARS, "Obtain Kerberos TGT", -1, dlginfo->in.title, NETID_TITLE_SZ); } if (desiredName) MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED|MB_ERR_INVALID_CHARS, desiredName, -1, dlginfo->in.username, NETID_USERNAME_SZ); if (desiredRealm) MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED|MB_ERR_INVALID_CHARS, desiredRealm, -1, dlginfo->in.realm, NETID_REALM_SZ); if (ccache) MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED|MB_ERR_INVALID_CHARS, ccache, -1, dlginfo->in.ccache, NETID_CCACHE_NAME_SZ); lrc = SendMessage(hNetIdMgr, 32810, 0, (LPARAM) tid); if (lrc > 0) { if (lpdlginfo->size == LSH_DLGINFO_EX_V2_SZ) { WideCharToMultiByte(CP_ACP, 0, dlginfo->out.username, -1, lpdlginfo->out.username, LEASH_USERNAME_SZ, NULL, NULL); WideCharToMultiByte(CP_ACP, 0, dlginfo->out.realm, -1, lpdlginfo->out.realm, LEASH_REALM_SZ, NULL, NULL); } if (lpdlginfo->size == LSH_DLGINFO_EX_V3_SZ) { WideCharToMultiByte(CP_ACP, 0, dlginfo->out.ccache, -1, lpdlginfo->out.ccache, LEASH_CCACHE_NAME_SZ, NULL, NULL); } } UnmapViewOfFile(dlginfo); CloseHandle(hMap); SetForegroundWindow(hForeground); return lrc; } return -1; } #define LEASH_DLG_MUTEX_NAME TEXT("Leash_Dialog_Mutex") int Leash_kinit_dlg(HWND hParent, LPLSH_DLGINFO lpdlginfo) { int rc; HANDLE hMutex; rc = NetId_dialog(lpdlginfo); if (rc > -1) return rc; hMutex = CreateMutex(NULL, TRUE, LEASH_DLG_MUTEX_NAME); if ( GetLastError() == ERROR_ALREADY_EXISTS ) { if ( WaitForSingleObject( hMutex, INFINITE ) != WAIT_OBJECT_0 ) { return -1; } ReleaseMutex(hMutex); CloseHandle(hMutex); return 1; /* pretend the dialog was displayed and succeeded */ } lpdlginfo->dlgtype = DLGTYPE_PASSWD; /* set the help file */ Leash_set_help_file(NULL); /* Call the Dialog box with the DLL's Password Callback and the DLL's instance handle. */ rc = DialogBoxParam(hLeashInst, "EnterPasswordDlg", hParent, PasswordProc, (LPARAM)lpdlginfo); ReleaseMutex(hMutex); CloseHandle(hMutex); return rc; } int Leash_kinit_dlg_ex(HWND hParent, LPLSH_DLGINFO_EX lpdlginfo) { int rc; HANDLE hMutex; rc = NetId_dialog_ex(lpdlginfo); if (rc > -1) return rc; hMutex = CreateMutex(NULL, TRUE, LEASH_DLG_MUTEX_NAME); if ( GetLastError() == ERROR_ALREADY_EXISTS ) { if ( WaitForSingleObject( hMutex, INFINITE ) != WAIT_OBJECT_0 ) { return -1; } ReleaseMutex(hMutex); CloseHandle(hMutex); return 1; /* pretend the dialog was displayed and succeeded */ } /* set the help file */ Leash_set_help_file(NULL); /* Call the Dialog box with the DLL's Password Callback and the DLL's instance handle. */ rc = DialogBoxParam(hLeashInst, MAKEINTRESOURCE(IDD_AUTHENTICATE), hParent, AuthenticateProc, (LPARAM)lpdlginfo); ReleaseMutex(hMutex); CloseHandle(hMutex); return rc; } int Leash_changepwd_dlg(HWND hParent, LPLSH_DLGINFO lpdlginfo) { int rc; HANDLE hMutex; rc = NetId_dialog(lpdlginfo); if (rc > -1) return rc; hMutex = CreateMutex(NULL, TRUE, LEASH_DLG_MUTEX_NAME); if ( GetLastError() == ERROR_ALREADY_EXISTS ) { if ( WaitForSingleObject( hMutex, INFINITE ) != WAIT_OBJECT_0 ) { return -1; } ReleaseMutex(hMutex); CloseHandle(hMutex); return 1; /* pretend the dialog was displayed and succeeded */ } lpdlginfo->dlgtype = DLGTYPE_CHPASSWD; /* Call the Dialog box with the DLL's Password Callback and the DLL's instance handle. */ rc = DialogBoxParam(hLeashInst, "CHANGEPASSWORDDLG", hParent, PasswordProc, (LPARAM)lpdlginfo); ReleaseMutex(hMutex); CloseHandle(hMutex); return rc; } int Leash_changepwd_dlg_ex(HWND hParent, LPLSH_DLGINFO_EX lpdlginfo) { int rc; HANDLE hMutex; rc = NetId_dialog_ex(lpdlginfo); if (rc > -1) return rc; hMutex = CreateMutex(NULL, TRUE, LEASH_DLG_MUTEX_NAME); if ( GetLastError() == ERROR_ALREADY_EXISTS ) { if ( WaitForSingleObject( hMutex, INFINITE ) != WAIT_OBJECT_0 ) { return -1; } ReleaseMutex(hMutex); CloseHandle(hMutex); return 1; /* pretend the dialog was displayed and succeeded */ } lpdlginfo->dlgtype = DLGTYPE_CHPASSWD; /* Call the Dialog box with the DLL's Password Callback and the DLL's instance handle. */ rc = DialogBoxParam(hLeashInst, MAKEINTRESOURCE(IDD_PASSWORD), hParent, NewPasswordProc, (LPARAM)lpdlginfo); ReleaseMutex(hMutex); CloseHandle(hMutex); return rc; } /* These little utils are taken from lshutil.c they are added here for the Call back funtion. ****** beginning of added utils from lshutil.c ******/ BOOL IsDlgItem(HWND hWnd, WORD id) { HWND hChild; hChild = GetDlgItem(hWnd, id); return hChild ? IsWindow(hChild) : 0; } int lsh_getkeystate(WORD keyid) { static BYTE keys[256]; GetKeyboardState((LPBYTE) &keys); return (int) keys[keyid]; } LPSTR krb_err_func(int offset, long code) { return(NULL); } /****** End of Added utils from leash.c ******/ int PaintLogoBitmap( HANDLE hPicFrame ) { HBITMAP hBitmap; HBITMAP hOldBitmap; BITMAP Bitmap; HDC hdc, hdcMem; RECT rect; /* Invalidate the drawing space of the picframe. */ InvalidateRect( hPicFrame, NULL, TRUE); UpdateWindow( hPicFrame ); hdc = GetDC(hPicFrame); hdcMem = CreateCompatibleDC(hdc); GetClientRect(hPicFrame, &rect); hBitmap = LoadBitmap(hLeashInst, "LOGOBITMAP"); hOldBitmap = SelectObject(hdcMem, hBitmap); GetObject(hBitmap, sizeof(Bitmap), (LPSTR) &Bitmap); StretchBlt(hdc, 0, 0, rect.right, rect.bottom, hdcMem, 0, 0, Bitmap.bmWidth, Bitmap.bmHeight, SRCCOPY); SelectObject(hdcMem, hOldBitmap); /* pbh 8-15-94 */ ReleaseDC(hPicFrame, hdc); DeleteObject( hBitmap ); /* pbh 8-15-94 */ DeleteDC( hdcMem ); /* pbh 8-15-94 */ return 0; } /* Callback function for the Password Dialog box that initilializes and renews tickets. */ INT_PTR CALLBACK PasswordProc( HWND hDialog, UINT message, WPARAM wParam, LPARAM lParam ) { static POINT Position = { -1, -1 }; static short state; int lifetime; #define ISCHPASSWD (lpdi->dlgtype == DLGTYPE_CHPASSWD) #define STATE_INIT 0 #define STATE_PRINCIPAL 1 #define STATE_OLDPWD 2 #define STATE_NEWPWD1 3 #define STATE_NEWPWD2 4 #define STATE_CLOSED 5 #define NEXTSTATE(newstate) SendMessage(hDialog, WM_COMMAND, ID_NEXTSTATE, newstate) static int ids[STATE_NEWPWD2 + 1] = { 0, ID_PRINCIPAL, ID_OLDPASSWORD, ID_CONFIRMPASSWORD1, ID_CONFIRMPASSWORD2}; static char principal[255], oldpassword[255], newpassword[255], newpassword2[255]; static char *strings[STATE_NEWPWD2 + 1] = { NULL, principal, oldpassword, newpassword, newpassword2}; static LPLSH_DLGINFO lpdi; char gbuf[200]; /* global buffer for random stuff. */ #define checkfirst(id, stuff) IsDlgItem(hDialog, id) ? stuff : 0 #define CGetDlgItemText(hDlg, id, cp, len) checkfirst(id, GetDlgItemText(hDlg, id, cp, len)) #define CSetDlgItemText(hDlg, id, cp) checkfirst(id, SetDlgItemText(hDlg, id, cp)) #define CSetDlgItemInt(hDlg, id, i, b) checkfirst(id, SetDlgItemInt(hDlg, id, i, b)) #define CSendDlgItemMessage(hDlg, id, m, w, l) checkfirst(id, SendDlgItemMessage(hDlg, id, m, w, l)) #define CSendMessage(hwnd, m, w, l) IsWindow(hwnd) ? SendMessage(hwnd, m, w, l) : 0 #define CShowWindow(hwnd, state) IsWindow(hwnd) ? ShowWindow(hwnd, state) : 0 #define GETITEMTEXT(id, cp, maxlen) \ GetDlgItemText(hDialog, id, (LPSTR)(cp), maxlen) #define CloseMe(x) SendMessage(hDialog, WM_COMMAND, ID_CLOSEME, x) #define EDITFRAMEIDOFFSET 500 switch (message) { case WM_INITDIALOG: *( (LPLSH_DLGINFO far *)(&lpdi) ) = (LPLSH_DLGINFO)(LPSTR)lParam; lpdi->dlgstatemax = ISCHPASSWD ? STATE_NEWPWD2 : STATE_OLDPWD; SetWindowText(hDialog, lpdi->title); /* stop at old password for normal password dlg */ SetProp(hDialog, "HANDLES_HELP", (HANDLE)1); if (lpdi->principal) lstrcpy(principal, lpdi->principal); else { principal[0] = '\0'; /* is there a principal already being used? if so, use it. */ } CSetDlgItemText(hDialog, ID_PRINCIPAL, principal); lifetime = Leash_get_default_lifetime(); if (lifetime <= 0) lifetime = 600; /* 10 hours */ CSetDlgItemInt(hDialog, ID_DURATION, lifetime, FALSE); /* setup text of stuff. */ if (Position.x > 0 && Position.y > 0 && Position.x < GetSystemMetrics(SM_CXSCREEN) && Position.y < GetSystemMetrics(SM_CYSCREEN)) SetWindowPos(hDialog, 0, Position.x, Position.y, 0, 0, SWP_NOSIZE | SWP_NOZORDER); /* set window pos to last saved window pos */ /* replace standard edit control with our own password edit control for password entry. */ { RECT r; POINT pxy, psz; HWND hwnd; int i; for (i = ID_OLDPASSWORD; i <= ids[lpdi->dlgstatemax]; i++) { hwnd = GetDlgItem(hDialog, i); GetWindowRect(hwnd, &r); psz.x = r.right - r.left; psz.y = r.bottom - r.top; pxy.x = r.left; pxy.y = r.top; ScreenToClient(hDialog, &pxy); /* create a substitute window: */ DestroyWindow(hwnd); /* kill off old edit window. */ CreateWindow(MIT_PWD_DLL_CLASS, /* our password window :o] */ "", /* no text */ WS_CHILD | WS_VISIBLE | WS_TABSTOP, /* child window, visible,tabstop */ pxy.x, pxy.y, /* x, y coords */ psz.x, psz.y, /* width, height */ hDialog, /* the parent */ (HMENU)i, /* same id *//* id offset for the frames */ (HANDLE)hLeashInst,/* instance handles */ NULL); /* createstruct */ } } state = STATE_INIT; NEXTSTATE(STATE_PRINCIPAL); break; case WM_PAINT: PaintLogoBitmap( GetDlgItem(hDialog, ID_PICFRAME) ); break; case WM_COMMAND: switch (wParam) { case ID_HELP: { WinHelp(GetWindow(hDialog,GW_OWNER), KRB_HelpFile, HELP_CONTEXT, ISCHPASSWD ? ID_CHANGEPASSWORD : ID_INITTICKETS); } break; case ID_CLOSEME: { int i; for (i = STATE_PRINCIPAL; i <= lpdi->dlgstatemax; i++) { memset(strings[i], '\0', 255); SetDlgItemText(hDialog, ids[i], ""); } /* I claim these passwords in the name of planet '\0'... */ RemoveProp(hDialog, "HANDLES_HELP"); state = STATE_CLOSED; EndDialog(hDialog, (int)lParam); return TRUE; } break; case ID_DURATION: break; case ID_PRINCIPAL: case ID_OLDPASSWORD: case ID_CONFIRMPASSWORD1: case ID_CONFIRMPASSWORD2: if (HIWORD(lParam) == EN_SETFOCUS) { /* nothing, for now. */ } break; case ID_NEXTSTATE: { RECT rbtn, redit; POINT p; int idfocus, i, s; HWND hfocus, hbtn; int oldstate = state; state = (int)lParam; idfocus = ids[state]; #ifdef ONE_NEWPWDBOX if (state == STATE_NEWPWD2) SendDlgItemMessage(hDialog, ID_CONFIRMPASSWORD1, WM_SETTEXT, 0, (LONG)(LPSTR)""); #endif for (s = STATE_PRINCIPAL; s <= lpdi->dlgstatemax; s++) { i = ids[s]; if (s > state) SendDlgItemMessage(hDialog, i, WM_SETTEXT, 0, (LONG)(LPSTR)""); EnableWindow(GetDlgItem(hDialog, i), i == idfocus); ShowWindow(GetDlgItem(hDialog, i), (i <= idfocus ? SW_SHOW : SW_HIDE)); /* ShowWindow(GetDlgItem(hDialog, i + CAPTION_OFFSET), (i <= idfocus ? SW_SHOW : SW_HIDE));*/ /* show caption? */ } #ifdef ONE_NEWPWDBOX CSetDlgItemText(hDialog, ID_CONFIRMCAPTION1, state < STATE_NEWPWD2 ? "Enter new password:" : "Enter new password again:"); if (state == STATE_NEWPWD2) { HWND htext; htext = GetDlgItem(hDialog, ID_CONFIRMCAPTION1); FlashAnyWindow(htext); WinSleep(50); FlashAnyWindow(htext); } #endif hfocus = GetDlgItem(hDialog, idfocus); if ( hfocus != (HWND)NULL ){ SetFocus(hfocus); /* switch focus */ if (idfocus >= ID_OLDPASSWORD) SendMessage(hfocus, WM_SETTEXT, 0, (LPARAM) (LPSTR) ""); else { SendMessage(hfocus, EM_SETSEL, 0, MAKELONG(0, -1)); } GetWindowRect(hfocus, &redit); } hbtn = GetDlgItem(hDialog, IDOK); if( IsWindow(hbtn) ){ GetWindowRect(hbtn, &rbtn); p.x = rbtn.left; p.y = redit.top; ScreenToClient(hDialog, &p); SetWindowPos(hbtn, 0, p.x, p.y, 0, 0, SWP_NOSIZE | SWP_NOZORDER); } } break; case IDOK: { char* p_Principal; DWORD value = 0; GETITEMTEXT(ids[state], (LPSTR)strings[state], 255); switch(state) { case STATE_PRINCIPAL: { if (!principal[0]) { MessageBox(hDialog, "You are not allowed to enter a blank principal.", "Invalid Principal", MB_OK | MB_ICONSTOP); NEXTSTATE(STATE_PRINCIPAL); return TRUE; } // Change 'principal' to upper case after checking // "UpperCase" value in the Registry p_Principal = strchr(principal, '@'); if (p_Principal && Leash_get_default_uppercaserealm()) strupr(p_Principal); break; } case STATE_OLDPWD: { int duration; if (!ISCHPASSWD) duration = GetDlgItemInt(hDialog, ID_DURATION, 0, FALSE); if (!oldpassword[0]) { MessageBox(hDialog, "You are not allowed to enter a " "blank password.", "Invalid Password", MB_OK | MB_ICONSTOP); NEXTSTATE(STATE_OLDPWD); return TRUE; } if (lpdi->dlgtype == DLGTYPE_CHPASSWD) lsh_errno = Leash_int_checkpwd(principal, oldpassword, 1); else { lsh_errno = Leash_int_kinit_ex( 0, hDialog, principal, oldpassword, duration, Leash_get_default_forwardable(), Leash_get_default_proxiable(), Leash_get_default_renew_till(), Leash_get_default_noaddresses(), Leash_get_default_publicip(), 1 ); } if (lsh_errno != 0) { int next_state = state; int capslock; char *cp; err_context = ""; switch(lsh_errno) { case LSH_INVPRINCIPAL: case LSH_INVINSTANCE: case LSH_INVREALM: next_state = STATE_PRINCIPAL; break; } capslock = lsh_getkeystate(VK_CAPITAL); /* low-order bit means caps lock is toggled; if so, warn user since there's been an error. */ if (capslock & 1) { lstrcpy((LPSTR)gbuf, (LPSTR)err_context); cp = gbuf + lstrlen((LPSTR)gbuf); if (cp != gbuf) *cp++ = ' '; lstrcpy(cp, "(This may be because your CAPS LOCK key is down.)"); err_context = gbuf; } // XXX DoNiftyErrorReport(lsh_errno, ISCHPASSWD ? "" // XXX : "Ticket initialization failed."); NEXTSTATE(next_state); return TRUE; } if (ISCHPASSWD) break; CloseMe(TRUE); /* success */ } break; case STATE_NEWPWD1: { int i = 0; int bit8 = 0; for( i = 0; i < 255; i++ ){ if( newpassword[i] == '\0' ){ if ( bit8 ) { MessageBox(hDialog, "Passwords should not contain non-ASCII characters.", "Internationalization Warning", MB_OK | MB_ICONINFORMATION); } i = 255; break; } else if( !isprint(newpassword[i]) ){ memset(newpassword, '\0', 255); /* I claim these passwords in the name of planet '\0'... */ MessageBox(hDialog, "Passwords may not contain non-printable characters.", "Invalid Password", MB_OK | MB_ICONSTOP); NEXTSTATE(STATE_NEWPWD1); return TRUE; } else if ( newpassword[i] > 127 ) bit8 = 1; } } break; case STATE_NEWPWD2: if (lstrcmp(newpassword, newpassword2)) { NEXTSTATE(STATE_NEWPWD1); MessageBox(hDialog, "The new password was not entered the same way twice.", "Password validation error", MB_OK | MB_ICONSTOP); return TRUE; } else { /* make them type both pwds again if error */ int next_state = STATE_NEWPWD1; int capslock; char *cp; capslock = lsh_getkeystate(VK_CAPITAL); /* low-order bit means caps lock is toggled; if so, warn user since there's been an error. */ if (capslock & 1) { lstrcpy((LPSTR)gbuf, (LPSTR)err_context); cp = gbuf + lstrlen((LPSTR)gbuf); if (cp != gbuf) *cp++ = ' '; lstrcpy(cp, "(This may be because your CAPS LOCK key is down.)"); err_context = gbuf; } if ((lsh_errno = Leash_int_changepwd(principal, oldpassword, newpassword, 0, 1)) == 0){ CloseMe(TRUE); } else { // XXX - DoNiftyErrorReport(lsh_errno, "Error while changing password."); NEXTSTATE(next_state); return TRUE; } } break; } /* increment state, but send the old state as a parameter */ SendMessage(hDialog, WM_COMMAND, ID_NEXTSTATE, state + 1); } break; case IDCANCEL: CloseMe(FALSE); break; case ID_RESTART: { int i; for (i = ID_OLDPASSWORD; i <= ids[lpdi->dlgstatemax]; i++) SetDlgItemText(hDialog, i, ""); SendMessage(hDialog, WM_COMMAND, ID_NEXTSTATE, STATE_PRINCIPAL); } break; } break; case WM_MOVE: if (state != STATE_CLOSED) #ifdef _WIN32 #define LONG2POINT(l,pt) ((pt).x=(SHORT)LOWORD(l), \ (pt).y=(SHORT)HIWORD(l)) LONG2POINT(lParam,Position); #else Position = MAKEPOINT(lParam); #endif break; } return FALSE; } #define KRB_FILE "KRB.CON" #define KRBREALM_FILE "KRBREALM.CON" #define KRB5_FILE "KRB5.INI" BOOL GetProfileFile( LPSTR confname, UINT szConfname ) { char **configFile = NULL; if (hKrb5 && pkrb5_get_default_config_files(&configFile)) { GetWindowsDirectory(confname,szConfname); confname[szConfname-1] = '\0'; strncat(confname, "\\",sizeof(confname)-strlen(confname)); confname[szConfname-1] = '\0'; strncat(confname, KRB5_FILE,sizeof(confname)-strlen(confname)); confname[szConfname-1] = '\0'; return FALSE; } *confname = 0; if (hKrb5 && configFile) { strncpy(confname, *configFile, szConfname); pkrb5_free_config_files(configFile); } if (!*confname) { GetWindowsDirectory(confname,szConfname); confname[szConfname-1] = '\0'; strncat(confname, "\\",sizeof(confname)-strlen(confname)); confname[szConfname-1] = '\0'; strncat(confname, KRB5_FILE,sizeof(confname)-strlen(confname)); confname[szConfname-1] = '\0'; } return FALSE; } BOOL GetKrb4ConFile( LPSTR confname, UINT szConfname ) { if (hKrb5 ) { // hold krb.con where krb5.ini is located CHAR krbConFile[MAX_PATH]=""; LPSTR pFind; //strcpy(krbConFile, CLeashApp::m_krbv5_profile->first_file->filename); if (GetProfileFile(krbConFile, sizeof(krbConFile))) { GetWindowsDirectory(krbConFile,sizeof(krbConFile)); krbConFile[MAX_PATH-1] = '\0'; strncat(krbConFile, "\\",sizeof(krbConFile)-strlen(krbConFile)); krbConFile[MAX_PATH-1] = '\0'; strncat(krbConFile, KRB5_FILE,sizeof(krbConFile)-strlen(krbConFile)); krbConFile[MAX_PATH-1] = '\0'; } pFind = strrchr(krbConFile, '\\'); if (pFind) { *pFind = 0; strncat(krbConFile, "\\",sizeof(krbConFile)-strlen(krbConFile)); krbConFile[MAX_PATH-1] = '\0'; strncat(krbConFile, KRB_FILE,sizeof(krbConFile)-strlen(krbConFile)); krbConFile[MAX_PATH-1] = '\0'; } else krbConFile[0] = 0; strncpy(confname, krbConFile, szConfname); confname[szConfname-1] = '\0'; } return FALSE; } BOOL GetKrb4RealmFile( LPSTR confname, UINT szConfname ) { if (hKrb5 ) { // hold krb.con where krb5.ini is located CHAR krbRealmConFile[MAX_PATH]; LPSTR pFind; //strcpy(krbRealmConFile, CLeashApp::m_krbv5_profile->first_file->filename); if (GetProfileFile(krbRealmConFile, sizeof(krbRealmConFile))) { GetWindowsDirectory(krbRealmConFile,sizeof(krbRealmConFile)); krbRealmConFile[MAX_PATH-1] = '\0'; strncat(krbRealmConFile, "\\",sizeof(krbRealmConFile)-strlen(krbRealmConFile)); krbRealmConFile[MAX_PATH-1] = '\0'; strncat(krbRealmConFile, KRB5_FILE,sizeof(krbRealmConFile)-strlen(krbRealmConFile)); krbRealmConFile[MAX_PATH-1] = '\0'; } pFind = strrchr(krbRealmConFile, '\\'); if (pFind) { *pFind = 0; strncat(krbRealmConFile, "\\", sizeof(krbRealmConFile)-strlen(krbRealmConFile)); krbRealmConFile[MAX_PATH-1] = '\0'; strncat(krbRealmConFile, KRBREALM_FILE, sizeof(krbRealmConFile)-strlen(krbRealmConFile)); krbRealmConFile[MAX_PATH-1] = '\0'; } else krbRealmConFile[0] = 0; strncpy(confname, krbRealmConFile, szConfname); confname[szConfname-1] = '\0'; } return FALSE; } int readstring(FILE * file, char * buf, int len) { int c,i; memset(buf, '\0', sizeof(buf)); for (i=0, c=fgetc(file); c != EOF ; c=fgetc(file), i++) { if (i < sizeof(buf)) { if (c == '\n') { buf[i] = '\0'; return i; } else { buf[i] = c; } } else { if (c == '\n') { buf[len-1] = '\0'; return(i); } } } if (c == EOF) { if (i > 0 && i < len) { buf[i] = '\0'; return(i); } else { buf[len-1] = '\0'; return(-1); } } return(-1); } typedef struct _slider_info { int slider_id; int text_id; int min; int max; int increment; struct _slider_info * next; } slider_info; static slider_info * sliders = NULL; static slider_info * FreeSlider(slider_info * s) { slider_info * n = NULL; if (s) { n = s->next; free(s); } return n; } static void CleanupSliders(void) { while(sliders) sliders = FreeSlider(sliders); } static unsigned short NewSliderValue(HWND hDialog, int id) { int value = 0; slider_info * s = sliders; while(s) { if (s->slider_id == id) { int pos = CSendDlgItemMessage( hDialog, id, TBM_GETPOS, (WPARAM) 0, (LPARAM) 0); value = s->min + (pos * s->increment); break; } s = s->next; } return(value); } static const char * NewSliderString(int id, int pos) { static char buf[64]=""; char * p = buf; int value = 0; int must_hours = 0; slider_info * s = sliders; while(s) { if (s->slider_id == id) { value = s->min + pos * s->increment; *p = 0; if (value >= 60 * 24) { sprintf(p,"%d day(s) ",value / (60 * 24)); value %= (60 * 24); p += strlen(p); must_hours = 1; } if (must_hours || value >= 60) { sprintf(p,"%d hour(s) ",value / 60); value %= 60; p += strlen(p); } sprintf(p,"%d minute(s) ",value); break; } s = s->next; } return(buf); } static void SetupSlider( HWND hDialog, int sliderID, int textFieldID, int minimum, int maximum, int value) { int min = minimum; int max = maximum; int increment = 0; int range; int roundedMinimum; int roundedMaximum; int roundedValue; slider_info * new_info; if (max < min) { // swap values int temp = max; max = min; min = temp; } range = max - min; if (range < 5*60) { increment = 1; // 1 s if under 5 m } else if (range < 30*60) { increment = 5; // 5 s if under 30 m } else if (range < 60*60) { increment = 15; // 15 s if under 1 h } else if (range < 2*60*60) { increment = 30; // 30 s if under 2 h } else if (range < 5*60*60) { increment = 60; // 1 m if under 5 h } else if (range < 50*60*60) { increment = 5*60; // 5 m if under 50 h } else if (range < 200*60*60) { increment = 15*60; // 15 m if under 200 h } else if (range < 500*60*60) { increment = 30*60; // 30 m if under 500 h } else { increment = 60*60; } // 1 h otherwise roundedMinimum = (min / increment) * increment; if (roundedMinimum > min) { roundedMinimum -= increment; } if (roundedMinimum <= 0) { roundedMinimum += increment; } // make positive roundedMaximum = (max / increment) * increment; if (roundedMaximum < max) { roundedMaximum += increment; } roundedValue = (value / increment) * increment; if (roundedValue < roundedMinimum) { roundedValue = roundedMinimum; } if (roundedValue > roundedMaximum) { roundedValue = roundedMaximum; } if (roundedMinimum == roundedMaximum) { // [textField setTextColor: [NSColor grayColor]]; EnableWindow(GetDlgItem(hDialog,sliderID),FALSE); } else { // [textField setTextColor: [NSColor blackColor]]; EnableWindow(GetDlgItem(hDialog,sliderID),TRUE); } CSendDlgItemMessage( hDialog, sliderID, TBM_SETRANGEMIN, (WPARAM) FALSE, (LPARAM) 0 ); CSendDlgItemMessage( hDialog, sliderID, TBM_SETRANGEMAX, (WPARAM) FALSE, (LPARAM) (roundedMaximum - roundedMinimum) / increment ); CSendDlgItemMessage( hDialog, sliderID, TBM_SETPOS, (WPARAM) TRUE, (LPARAM) (roundedValue - roundedMinimum) / increment); new_info = (slider_info *) malloc(sizeof(slider_info)); new_info->slider_id = sliderID; new_info->text_id = textFieldID; new_info->min = roundedMinimum; new_info->max = roundedMaximum; new_info->increment = increment; new_info->next = sliders; sliders = new_info; SetWindowText(GetDlgItem(hDialog, textFieldID), NewSliderString(sliderID,(roundedValue - roundedMinimum) / increment)); } static void AdjustOptions(HWND hDialog, int show, int hideDiff) { RECT rect; RECT dlgRect; HWND hwnd; int diff; Leash_set_hide_kinit_options(!show); ShowWindow(GetDlgItem(hDialog,IDC_STATIC_LIFETIME),show); ShowWindow(GetDlgItem(hDialog,IDC_STATIC_LIFETIME_VALUE),show); ShowWindow(GetDlgItem(hDialog,IDC_SLIDER_LIFETIME),show); ShowWindow(GetDlgItem(hDialog,IDC_SLIDER_RENEWLIFE),show); ShowWindow(GetDlgItem(hDialog,IDC_STATIC_RENEW),show); ShowWindow(GetDlgItem(hDialog,IDC_STATIC_RENEW_TILL_VALUE),show); ShowWindow(GetDlgItem(hDialog,IDC_CHECK_FORWARDABLE),show); ShowWindow(GetDlgItem(hDialog,IDC_CHECK_NOADDRESS),show); ShowWindow(GetDlgItem(hDialog,IDC_CHECK_RENEWABLE),show); ShowWindow(GetDlgItem(hDialog,IDC_STATIC_KRB5),show); ShowWindow(GetDlgItem(hDialog,IDC_BUTTON_CLEAR_HISTORY),show); GetWindowRect( hDialog, &dlgRect ); diff = dlgRect.top + GetSystemMetrics(SM_CYCAPTION) + GetSystemMetrics(SM_CYDLGFRAME) + (show ? -1 : 1) * hideDiff; hwnd = GetDlgItem(hDialog,IDOK); GetWindowRect(hwnd,&rect); SetWindowPos(hwnd,0,rect.left-dlgRect.left-GetSystemMetrics(SM_CXDLGFRAME),rect.top-diff,0,0,SWP_NOZORDER|SWP_NOSIZE); hwnd = GetDlgItem(hDialog,IDCANCEL); GetWindowRect(hwnd,&rect); SetWindowPos(hwnd,0,rect.left-dlgRect.left-GetSystemMetrics(SM_CXDLGFRAME),rect.top-diff,0,0,SWP_NOZORDER|SWP_NOSIZE); hwnd = GetDlgItem(hDialog,IDC_BUTTON_OPTIONS); GetWindowRect(hwnd,&rect); SetWindowPos(hwnd,0,rect.left-dlgRect.left-GetSystemMetrics(SM_CXDLGFRAME),rect.top-diff,0,0,SWP_NOZORDER|SWP_NOSIZE); hwnd = GetDlgItem(hDialog,IDC_STATIC_VERSION); GetWindowRect(hwnd,&rect); SetWindowPos(hwnd,0,rect.left-dlgRect.left-GetSystemMetrics(SM_CXDLGFRAME),rect.top-diff,0,0,SWP_NOZORDER|SWP_NOSIZE); hwnd = GetDlgItem(hDialog,IDC_STATIC_COPYRIGHT); GetWindowRect(hwnd,&rect); SetWindowPos(hwnd,0,rect.left-dlgRect.left-GetSystemMetrics(SM_CXDLGFRAME),rect.top-diff,0,0,SWP_NOZORDER|SWP_NOSIZE); SetWindowPos(hDialog,0,0,0, dlgRect.right-dlgRect.left, dlgRect.bottom-dlgRect.top+(show ? 1 : - 1) * hideDiff, SWP_NOZORDER|SWP_NOMOVE); CSetDlgItemText(hDialog, IDC_BUTTON_OPTIONS, show ? "Hide Advanced" : "Show Advanced"); } /* Callback function for the Authentication Dialog box that initializes and renews tickets. */ INT_PTR CALLBACK AuthenticateProc( HWND hDialog, UINT message, WPARAM wParam, LPARAM lParam ) { static POINT Position = { -1, -1 }; static char principal[256]=""; static char password[256]=""; static int lifetime=0; static int renew_till=0; static int forwardable=0; static int noaddresses=0; static int proxiable=0; static int publicip=0; static LPLSH_DLGINFO_EX lpdi; static HWND hDlg=0; static HWND hSliderLifetime=0; static HWND hSliderRenew=0; static RECT dlgRect; static int hideDiff = 0; static void *pAutoComplete = 0; long realm_count = 0; int disable_noaddresses = 0; HWND hEditCtrl=0; HWND hFocusCtrl=0; BOOL bReadOnlyPrinc=0; switch (message) { case WM_INITDIALOG: hDlg = hDialog; hEditCtrl = GetDlgItem(hDialog, IDC_EDIT_PRINCIPAL); if (hEditCtrl) pAutoComplete = Leash_pec_create(hEditCtrl); hSliderLifetime = GetDlgItem(hDialog, IDC_STATIC_LIFETIME_VALUE); hSliderRenew = GetDlgItem(hDialog, IDC_STATIC_RENEW_TILL_VALUE); *( (LPLSH_DLGINFO_EX far *)(&lpdi) ) = (LPLSH_DLGINFO_EX)(LPSTR)lParam; if ((lpdi->size != LSH_DLGINFO_EX_V1_SZ && lpdi->size != LSH_DLGINFO_EX_V2_SZ && lpdi->size < LSH_DLGINFO_EX_V3_SZ) || (lpdi->dlgtype & DLGTYPE_MASK) != DLGTYPE_PASSWD) { MessageBox(hDialog, "An incorrect initialization data structure was provided.", "AuthenticateProc()", MB_OK | MB_ICONSTOP); return FALSE; } bReadOnlyPrinc = (lpdi->dlgtype & DLGFLAG_READONLYPRINC) ? TRUE : FALSE; if ( lpdi->size >= LSH_DLGINFO_EX_V2_SZ ) { lpdi->out.username[0] = 0; lpdi->out.realm[0] = 0; } if ( lpdi->size >= LSH_DLGINFO_EX_V3_SZ ) { lpdi->out.ccache[0] = 0; } if ( lpdi->size >= LSH_DLGINFO_EX_V3_SZ ) SetWindowText(hDialog, lpdi->in.title); else SetWindowText(hDialog, lpdi->title); SetProp(hDialog, "HANDLES_HELP", (HANDLE)1); if (lpdi->use_defaults) { lifetime = Leash_get_default_lifetime(); if (lifetime <= 0) lifetime = 600; /* 10 hours */ if (Leash_get_default_renewable()) { renew_till = Leash_get_default_renew_till(); if (renew_till < 0) renew_till = 10800; /* 7 days */ } else renew_till = 0; forwardable = Leash_get_default_forwardable(); if (forwardable < 0) forwardable = 0; noaddresses = Leash_get_default_noaddresses(); if (noaddresses < 0) noaddresses = 0; proxiable = Leash_get_default_proxiable(); if (proxiable < 0) proxiable = 0; publicip = Leash_get_default_publicip(); if (publicip < 0) publicip = 0; } else { forwardable = lpdi->forwardable; noaddresses = lpdi->noaddresses; lifetime = lpdi->lifetime; renew_till = lpdi->renew_till; proxiable = lpdi->proxiable; publicip = lpdi->publicip; } if (lpdi->username && (strlen(lpdi->username) > 0) && lpdi->realm && (strlen(lpdi->realm) > 0)) { sprintf_s(principal, sizeof(principal), "%s@%s", lpdi->username, lpdi->realm); } else { principal[0] = 0; } Edit_SetReadOnly(hEditCtrl, bReadOnlyPrinc); CSetDlgItemText(hDialog, IDC_EDIT_PRINCIPAL, principal); CSetDlgItemText(hDialog, IDC_EDIT_PASSWORD, ""); #if 0 /* 20030619 - mjv wishes to return to the default character */ /* echo spaces */ CSendDlgItemMessage(hDialog, IDC_EDIT_PASSWORD, EM_SETPASSWORDCHAR, 32, 0); #endif /* Set Lifetime Slider * min value = 5 * max value = 1440 * current value */ SetupSlider( hDialog, IDC_SLIDER_LIFETIME, IDC_STATIC_LIFETIME_VALUE, Leash_get_default_life_min(), Leash_get_default_life_max(), lifetime ); CheckDlgButton(hDialog, IDC_CHECK_REMEMBER_PRINCIPAL, TRUE); /* Set Forwardable checkbox */ CheckDlgButton(hDialog, IDC_CHECK_FORWARDABLE, forwardable); /* Set NoAddress checkbox */ CheckDlgButton(hDialog, IDC_CHECK_NOADDRESS, noaddresses); if ( disable_noaddresses ) EnableWindow(GetDlgItem(hDialog,IDC_CHECK_NOADDRESS),FALSE); /* Set Renewable checkbox */ CheckDlgButton(hDialog, IDC_CHECK_RENEWABLE, renew_till); /* if not renewable, disable Renew Till slider */ /* if renewable, set Renew Till slider * min value * max value * current value */ SetupSlider( hDialog, IDC_SLIDER_RENEWLIFE, IDC_STATIC_RENEW_TILL_VALUE, Leash_get_default_renew_min(), Leash_get_default_renew_max(), renew_till); if (renew_till) { EnableWindow(GetDlgItem(hDialog,IDC_SLIDER_RENEWLIFE),TRUE); } else { EnableWindow(GetDlgItem(hDialog,IDC_SLIDER_RENEWLIFE),FALSE); } // Compute sizes of items necessary to show/hide the advanced options GetWindowRect( hDialog, &dlgRect ); { RECT okRect, staticRect; GetWindowRect(GetDlgItem(hDialog,IDC_STATIC_LIFETIME),&staticRect); GetWindowRect(GetDlgItem(hDialog,IDOK),&okRect); hideDiff = okRect.top - staticRect.top; } if ( hKrb5 ) { if (Leash_get_hide_kinit_options()) AdjustOptions(hDialog,0,hideDiff); } else { AdjustOptions(hDialog,0,hideDiff); EnableWindow(GetDlgItem(hDialog,IDC_BUTTON_OPTIONS),FALSE); ShowWindow(GetDlgItem(hDialog,IDC_BUTTON_OPTIONS),SW_HIDE); } /* setup text of stuff. */ if (Position.x > 0 && Position.y > 0 && Position.x < GetSystemMetrics(SM_CXSCREEN) && Position.y < GetSystemMetrics(SM_CYSCREEN)) SetWindowPos(hDialog, HWND_TOP, Position.x, Position.y, 0, 0, SWP_NOSIZE); else /* Center the window on the desktop */ SetWindowPos(hDialog, HWND_TOP, (GetSystemMetrics(SM_CXSCREEN) - dlgRect.right + dlgRect.left)/2, (GetSystemMetrics(SM_CYSCREEN) - dlgRect.bottom + dlgRect.top)/2, 0, 0, SWP_NOSIZE); /* Take keyboard focus */ SetActiveWindow(hDialog); SetForegroundWindow(hDialog); /* put focus on password if princ is read-only */ hFocusCtrl = (bReadOnlyPrinc || principal[0] != '\0') ? GetDlgItem(hDialog, IDC_EDIT_PASSWORD) : hEditCtrl; if (((HWND)wParam) != hFocusCtrl) { SetFocus(hFocusCtrl); } break; case WM_HSCROLL: switch (LOWORD(wParam)) { case TB_THUMBTRACK: case TB_THUMBPOSITION: { long pos = HIWORD(wParam); // the position of the slider int ctrlID = GetDlgCtrlID((HWND)lParam); if (ctrlID == IDC_SLIDER_RENEWLIFE) { SetWindowText(GetDlgItem(hDialog, IDC_STATIC_RENEW_TILL_VALUE), NewSliderString(IDC_SLIDER_RENEWLIFE,pos)); } if (ctrlID == IDC_SLIDER_LIFETIME) { SetWindowText(GetDlgItem(hDialog, IDC_STATIC_LIFETIME_VALUE), NewSliderString(IDC_SLIDER_LIFETIME,pos)); } } break; case TB_BOTTOM: case TB_TOP: case TB_ENDTRACK: case TB_LINEDOWN: case TB_LINEUP: case TB_PAGEDOWN: case TB_PAGEUP: default: { int ctrlID = GetDlgCtrlID((HWND)lParam); long pos = SendMessage(GetDlgItem(hDialog,ctrlID), TBM_GETPOS, 0, 0); // the position of the slider if (ctrlID == IDC_SLIDER_RENEWLIFE) { SetWindowText(GetDlgItem(hDialog, IDC_STATIC_RENEW_TILL_VALUE), NewSliderString(IDC_SLIDER_RENEWLIFE,pos)); } if (ctrlID == IDC_SLIDER_LIFETIME) { SetWindowText(GetDlgItem(hDialog, IDC_STATIC_LIFETIME_VALUE), NewSliderString(IDC_SLIDER_LIFETIME,pos)); } } } break; case WM_COMMAND: switch (wParam) { case IDC_BUTTON_OPTIONS: { AdjustOptions(hDialog,Leash_get_hide_kinit_options(),hideDiff); GetWindowRect(hDialog,&dlgRect); if ( dlgRect.bottom > GetSystemMetrics(SM_CYSCREEN)) SetWindowPos( hDialog,0, dlgRect.left, GetSystemMetrics(SM_CYSCREEN) - dlgRect.bottom + dlgRect.top, 0,0, SWP_NOZORDER|SWP_NOSIZE); } break; case IDC_BUTTON_CLEAR_HISTORY: Leash_pec_clear_history(pAutoComplete); break; case IDC_CHECK_RENEWABLE: { if (IsDlgButtonChecked(hDialog, IDC_CHECK_RENEWABLE)) { EnableWindow(hSliderRenew,TRUE); } else { EnableWindow(hSliderRenew,FALSE); } } break; case ID_HELP: { WinHelp(GetWindow(hDialog,GW_OWNER), KRB_HelpFile, HELP_CONTEXT, ID_INITTICKETS); } break; case ID_CLOSEME: { CleanupSliders(); memset(password,0,sizeof(password)); RemoveProp(hDialog, "HANDLES_HELP"); if (pAutoComplete) { Leash_pec_destroy(pAutoComplete); pAutoComplete = NULL; } EndDialog(hDialog, (int)lParam); return TRUE; } break; case IDOK: { DWORD value = 0; CGetDlgItemText(hDialog, IDC_EDIT_PRINCIPAL, principal, sizeof(principal)); CGetDlgItemText(hDialog, IDC_EDIT_PASSWORD, password, sizeof(password)); if (!principal[0]) { MessageBox(hDialog, "You are not allowed to enter a blank principal.", "Invalid Principal", MB_OK | MB_ICONSTOP); return TRUE; } // @TODO: parse realm portion and auto-uppercase /* if (Leash_get_default_uppercaserealm()) { // found strupr(realm); } */ if (!password[0]) { MessageBox(hDialog, "You are not allowed to enter a blank password.", "Invalid Password", MB_OK | MB_ICONSTOP); return TRUE; } lifetime = NewSliderValue(hDialog, IDC_SLIDER_LIFETIME); forwardable = proxiable = IsDlgButtonChecked(hDialog, IDC_CHECK_FORWARDABLE); noaddresses = IsDlgButtonChecked(hDialog, IDC_CHECK_NOADDRESS); if (IsDlgButtonChecked(hDialog, IDC_CHECK_RENEWABLE)) { renew_till = NewSliderValue(hDialog, IDC_SLIDER_RENEWLIFE); } else { renew_till= 0; } lsh_errno = Leash_int_kinit_ex( 0, hDialog, principal, password, lifetime, forwardable, proxiable, renew_till, noaddresses, publicip, 1 ); if (lsh_errno != 0) { #ifdef COMMENT char gbuf[256]; int capslock; char *cp; #endif err_context = ""; switch(lsh_errno) { case LSH_INVPRINCIPAL: case LSH_INVINSTANCE: CSendDlgItemMessage(hDialog, IDC_EDIT_PRINCIPAL, EM_SETSEL, 0, 256); SetFocus(GetDlgItem(hDialog,IDC_EDIT_PRINCIPAL)); break; case LSH_INVREALM: CSendDlgItemMessage(hDialog, IDC_COMBO_REALM, EM_SETSEL, 0, 256); SetFocus(GetDlgItem(hDialog,IDC_COMBO_REALM)); break; default: CSendDlgItemMessage(hDialog, IDC_EDIT_PASSWORD, EM_SETSEL, 0, 256); SetFocus(GetDlgItem(hDialog,IDC_EDIT_PASSWORD)); return(TRUE); } #ifdef COMMENT capslock = lsh_getkeystate(VK_CAPITAL); /* low-order bit means caps lock is toggled; if so, warn user since there's been an error. */ if (capslock & 1) { lstrcpy((LPSTR)gbuf, (LPSTR)err_context); cp = gbuf + lstrlen((LPSTR)gbuf); if (cp != gbuf) *cp++ = ' '; lstrcpy(cp, "(This may be because your CAPS LOCK key is down.)"); err_context = gbuf; } // XXX DoNiftyErrorReport(lsh_errno, ISCHPASSWD ? "" // XXX : "Ticket initialization failed."); #endif /* COMMENT */ return TRUE; } if ( Leash_get_default_preserve_kinit_settings() ) { Leash_set_default_lifetime(lifetime); if ( renew_till > 0 ) { Leash_set_default_renew_till(renew_till); Leash_set_default_renewable(1); } else { Leash_set_default_renewable(0); } Leash_set_default_forwardable(forwardable); Leash_set_default_noaddresses(noaddresses); } /* @TODO: out username/realm if ( lpdi->size >= LSH_DLGINFO_EX_V2_SZ ) { strncpy(lpdi->out.username, username, LEASH_USERNAME_SZ); lpdi->out.username[LEASH_USERNAME_SZ-1] = 0; strncpy(lpdi->out.realm, realm, LEASH_REALM_SZ); lpdi->out.realm[LEASH_REALM_SZ-1] = 0; } */ if (IsDlgButtonChecked(hDialog, IDC_CHECK_REMEMBER_PRINCIPAL)) Leash_pec_add_principal(principal); CloseMe(TRUE); /* success */ return FALSE; } break; case IDCANCEL: CloseMe(FALSE); break; } break; case WM_MOVE: #ifdef _WIN32 #define LONG2POINT(l,pt) ((pt).x=(SHORT)LOWORD(l), \ (pt).y=(SHORT)HIWORD(l)) LONG2POINT(lParam,Position); #else Position = MAKEPOINT(lParam); #endif break; } return FALSE; } /* Callback function for the Change Password Dialog box */ INT_PTR CALLBACK NewPasswordProc( HWND hDialog, UINT message, WPARAM wParam, LPARAM lParam ) { static POINT Position = { -1, -1 }; static char password[256]=""; static char password2[256]=""; static char password3[256]=""; static LPLSH_DLGINFO_EX lpdi; static HWND hDlg=0; static void *pAutoComplete = NULL; char principal[256]; long realm_count = 0; HWND hEditCtrl = NULL; switch (message) { case WM_INITDIALOG: hDlg = hDialog; *( (LPLSH_DLGINFO_EX far *)(&lpdi) ) = (LPLSH_DLGINFO_EX)(LPSTR)lParam; if ((lpdi->size < LSH_DLGINFO_EX_V3_SZ && lpdi->size != LSH_DLGINFO_EX_V1_SZ && lpdi->size != LSH_DLGINFO_EX_V2_SZ) || lpdi->dlgtype != DLGTYPE_CHPASSWD) { MessageBox(hDialog, "An incorrect initialization data structure was provided.", "PasswordProc()", MB_OK | MB_ICONSTOP); return FALSE; } if ( lpdi->size >= LSH_DLGINFO_EX_V2_SZ ) { lpdi->out.username[0] = 0; lpdi->out.realm[0] = 0; } if ( lpdi->size >= LSH_DLGINFO_EX_V3_SZ ) { lpdi->out.ccache[0] = 0; } if ( lpdi->size >= LSH_DLGINFO_EX_V3_SZ ) SetWindowText(hDialog, lpdi->in.title); else SetWindowText(hDialog, lpdi->title); SetProp(hDialog, "HANDLES_HELP", (HANDLE)1); if (lpdi->username != NULL && (strlen(lpdi->username) > 0) && lpdi->realm != NULL && (strlen(lpdi->realm) > 0)) { sprintf_s(principal, sizeof(principal), "%s@%s", lpdi->username, lpdi->realm); } else { principal[0] = 0; } CSetDlgItemText(hDialog, IDC_EDIT_PRINCIPAL, principal); CSetDlgItemText(hDialog, IDC_EDIT_PASSWORD, ""); CSetDlgItemText(hDialog, IDC_EDIT_PASSWORD2, ""); CSetDlgItemText(hDialog, IDC_EDIT_PASSWORD3, ""); hEditCtrl = GetDlgItem(hDialog, IDC_EDIT_PRINCIPAL); if (hEditCtrl) pAutoComplete = Leash_pec_create(hEditCtrl); #if 0 /* 20030619 - mjv wishes to return to the default character */ /* echo spaces */ CSendDlgItemMessage(hDialog, IDC_EDIT_PASSWORD, EM_SETPASSWORDCHAR, 32, 0); CSendDlgItemMessage(hDialog, IDC_EDIT_PASSWORD2, EM_SETPASSWORDCHAR, 32, 0); CSendDlgItemMessage(hDialog, IDC_EDIT_PASSWORD3, EM_SETPASSWORDCHAR, 32, 0); #endif /* setup text of stuff. */ if (Position.x > 0 && Position.y > 0 && Position.x < GetSystemMetrics(SM_CXSCREEN) && Position.y < GetSystemMetrics(SM_CYSCREEN)) SetWindowPos(hDialog, 0, Position.x, Position.y, 0, 0, SWP_NOSIZE | SWP_NOZORDER); else { /* Center the window on the desktop */ RECT dlgRect; GetWindowRect( hDialog, &dlgRect ); SetWindowPos(hDialog, 0, (GetSystemMetrics(SM_CXSCREEN) - dlgRect.right + dlgRect.left)/2, (GetSystemMetrics(SM_CYSCREEN) - dlgRect.bottom + dlgRect.top)/2, 0, 0, SWP_NOSIZE | SWP_NOZORDER); } /* set window pos to last saved window pos */ break; case WM_COMMAND: switch (wParam) { case ID_HELP: { WinHelp(GetWindow(hDialog,GW_OWNER), KRB_HelpFile, HELP_CONTEXT, ID_INITTICKETS); } break; case ID_CLOSEME: { CleanupSliders(); memset(password,0,sizeof(password)); memset(password2,0,sizeof(password2)); memset(password3,0,sizeof(password3)); RemoveProp(hDialog, "HANDLES_HELP"); EndDialog(hDialog, (int)lParam); if (pAutoComplete != NULL) { Leash_pec_destroy(pAutoComplete); pAutoComplete = NULL; } return TRUE; } break; case IDOK: { DWORD value = 0; int i = 0; int bit8 = 0; CGetDlgItemText(hDialog, IDC_EDIT_PRINCIPAL, principal, sizeof(principal)); CGetDlgItemText(hDialog, IDC_EDIT_PASSWORD, password, sizeof(password)); CGetDlgItemText(hDialog, IDC_EDIT_PASSWORD2, password2, sizeof(password2)); CGetDlgItemText(hDialog, IDC_EDIT_PASSWORD3, password3, sizeof(password3)); if (!principal[0]) { MessageBox(hDialog, "You are not allowed to enter a " "blank username.", "Invalid Principal", MB_OK | MB_ICONSTOP); return TRUE; } if (!password[0] || !password2[0] || !password3[0]) { MessageBox(hDialog, "You are not allowed to enter a " "blank password.", "Invalid Password", MB_OK | MB_ICONSTOP); return TRUE; } for( i = 0; i < 255; i++ ){ if( password2[i] == '\0' ){ if ( bit8 ) { MessageBox(hDialog, "Passwords should not contain non-ASCII characters.", "Internationalization Warning", MB_OK | MB_ICONINFORMATION); } i = 255; break; } else if( !isprint(password2[i]) ){ memset(password2, '\0', sizeof(password2)); memset(password3, '\0', sizeof(password3)); /* I claim these passwords in the name of planet '\0'... */ MessageBox(hDialog, "Passwords may not contain non-printable characters.", "Invalid Password", MB_OK | MB_ICONSTOP); return TRUE; } else if ( password2[i] > 127 ) bit8 = 1; } if (lstrcmp(password2, password3)) { MessageBox(hDialog, "The new password was not entered the same way twice.", "Password validation error", MB_OK | MB_ICONSTOP); return TRUE; } lsh_errno = Leash_int_changepwd(principal, password, password2, 0, 1); if (lsh_errno != 0) { #ifdef COMMENT char gbuf[256]; int capslock; char *cp; #endif /* COMMENT */ err_context = ""; switch(lsh_errno) { case LSH_INVPRINCIPAL: case LSH_INVINSTANCE: case LSH_INVREALM: break; default: return(TRUE); } #ifdef COMMENT capslock = lsh_getkeystate(VK_CAPITAL); /* low-order bit means caps lock is toggled; if so, warn user since there's been an error. */ if (capslock & 1) { lstrcpy((LPSTR)gbuf, (LPSTR)err_context); cp = gbuf + lstrlen((LPSTR)gbuf); if (cp != gbuf) *cp++ = ' '; lstrcpy(cp, "(This may be because your CAPS LOCK key is down.)"); err_context = gbuf; } // XXX DoNiftyErrorReport(lsh_errno, ISCHPASSWD ? "" // XXX : "Ticket initialization failed."); #endif /* COMMENT */ return TRUE; } Leash_pec_add_principal(principal); MessageBox(NULL, "Password successfully changed.", "Password change", MB_OK); CloseMe(TRUE); /* success */ } break; case IDCANCEL: CloseMe(FALSE); break; } break; case WM_MOVE: #ifdef _WIN32 #define LONG2POINT(l,pt) ((pt).x=(SHORT)LOWORD(l), \ (pt).y=(SHORT)HIWORD(l)) LONG2POINT(lParam,Position); #else Position = MAKEPOINT(lParam); #endif break; } return FALSE; } krb5-1.16/src/windows/leashdll/leasherr.et0000644000704600001450000000256613211554426020417 0ustar ghudsonlibuuidERROR_TABLE lsh ERROR_CODE LSH_ONLYONEME, "Only one instance of Leash can be run at a time." ERROR_CODE LSH_INVPRINCIPAL, "Principal invalid." ERROR_CODE LSH_FAILEDREALM, "Realm failed." ERROR_CODE LSH_INVINSTANCE, "Instance invalid." ERROR_CODE LSH_INVREALM, "Realm invalid." ERROR_CODE LSH_EOF, "Unexpected end of Kerberos memory storage." ERROR_CODE LSH_EXPIRESOON, "Warning! Your Kerberos tickets expire soon." ERROR_CODE LSH_NOMATCH, "You did not type the same new password." ERROR_CODE LSH_BADCHARS, "You can only use printable characters in a password." ERROR_CODE LSH_FATAL_ERROR, "Fatal error; cannot run this program." ERROR_CODE LSH_BADWINSOCK, "Couldn't initialize WinSock." ERROR_CODE LSH_BADTIMESERV, "Couldn't find the timeserver host entry." ERROR_CODE LSH_NOSOCKET, "Couldn't open a socket." ERROR_CODE LSH_NOCONNECT, "Couldn't connect to timeserver." ERROR_CODE LSH_TIMEFAILED, "Couldn't get time from server." ERROR_CODE LSH_GETTIMEOFDAY, "Couldn't get local time of day." ERROR_CODE LSH_SETTIMEOFDAY, "Couldn't set local time of day." ERROR_CODE LSH_RECVTIME, "Error while receiving time from server." ERROR_CODE LSH_RECVBYTES, "Protocol problem with timeserver." ERROR_CODE LSH_ALREADY_SETTIME, "The time was already reset. Try using a different program to synchronize the time." end krb5-1.16/src/windows/leashdll/ver.rc0000644000704600001450000000014013211554426017364 0ustar ghudsonlibuuid#define VER_FILEDESCRIPTION_STR "Leash Helper DLL" #include #include krb5-1.16/src/windows/leashdll/lshfunc.c0000644000704600001450000023060513211554426020063 0ustar ghudsonlibuuid#include #include #include #include #include "leashdll.h" #ifndef NO_KRB4 #include #include #else /* General definitions */ #define KSUCCESS 0 #define KFAILURE 255 #endif #include #include #include "leasherr.h" #include "leash-int.h" #include "leashids.h" #include #include "reminder.h" static char FAR *err_context; char KRB_HelpFile[_MAX_PATH] = HELPFILE; #define LEN 64 /* Maximum Hostname Length */ #define LIFE DEFAULT_TKT_LIFE /* lifetime of ticket in 5-minute units */ static char* clean_string( char* s ) { char* p = s; char* b = s; if (!s) return s; for (p = s; *p; p++) { switch (*p) { case '\007': /* Add more cases here */ break; default: *b = *p; b++; } } *b = *p; return s; } static int leash_error_message( const char *error, int rcL, int rc5, int rcA, char* result_string, int displayMB ) { char message[2048]; char *p = message; int size = sizeof(message) - 1; /* -1 to leave room for NULL terminator */ int n; // XXX: ignore AFS for now. if (!rc5 && !rcL) return 0; n = _snprintf(p, size, "%s\n\n", error); p += n; size -= n; if (rc5 && !result_string) { n = _snprintf(p, size, "Kerberos 5: %s (error %ld)\n", perror_message(rc5), rc5 ); p += n; size -= n; } if (rcL) { char buffer[1024]; n = _snprintf(p, size, "\n%s\n", err_describe(buffer, rcL) ); p += n; size -= n; } if (result_string) { n = _snprintf(p, size, "%s\n", result_string); p += n; size -= n; } #ifdef USE_MESSAGE_BOX *p = 0; /* ensure NULL termination of message */ if ( displayMB ) MessageBox(NULL, message, "MIT Kerberos", MB_OK | MB_ICONERROR | MB_TASKMODAL | MB_SETFOREGROUND); #endif /* USE_MESSAGE_BOX */ if (rc5) return rc5; if (rcL) return rcL; return 0; } static char * make_postfix( const char * base, const char * postfix, char ** rcopy ) { int base_size; int ret_size; char * copy = 0; char * ret = 0; base_size = strlen(base) + 1; ret_size = base_size + strlen(postfix) + 1; copy = malloc(base_size); ret = malloc(ret_size); if (!copy || !ret) goto cleanup; strncpy(copy, base, base_size); copy[base_size - 1] = 0; strncpy(ret, base, base_size); strncpy(ret + (base_size - 1), postfix, ret_size - (base_size - 1)); ret[ret_size - 1] = 0; cleanup: if (!copy || !ret) { if (copy) free(copy); if (ret) free(ret); copy = ret = 0; } // INVARIANT: (ret ==> copy) && (copy ==> ret) *rcopy = copy; return ret; } static long make_temp_cache_v5( const char * postfix, krb5_context * pctx ) { static krb5_context ctx = 0; static char * old_cache = 0; // INVARIANT: old_cache ==> ctx && ctx ==> old_cache if (pctx) *pctx = 0; if (!pkrb5_init_context || !pkrb5_free_context || !pkrb5_cc_resolve || !pkrb5_cc_default_name || !pkrb5_cc_set_default_name) return 0; if (old_cache) { krb5_ccache cc = 0; if (!pkrb5_cc_resolve(ctx, pkrb5_cc_default_name(ctx), &cc)) pkrb5_cc_destroy(ctx, cc); pkrb5_cc_set_default_name(ctx, old_cache); free(old_cache); old_cache = 0; } if (ctx) { pkrb5_free_context(ctx); ctx = 0; } if (postfix) { char * tmp_cache = 0; krb5_error_code rc = 0; rc = pkrb5_init_context(&ctx); if (rc) goto cleanup; tmp_cache = make_postfix(pkrb5_cc_default_name(ctx), postfix, &old_cache); if (!tmp_cache) { rc = ENOMEM; goto cleanup; } rc = pkrb5_cc_set_default_name(ctx, tmp_cache); cleanup: if (rc && ctx) { pkrb5_free_context(ctx); ctx = 0; } if (tmp_cache) free(tmp_cache); if (pctx) *pctx = ctx; return rc; } return 0; } long Leash_checkpwd( char *principal, char *password ) { return Leash_int_checkpwd(principal, password, 0); } long Leash_int_checkpwd( char * principal, char * password, int displayErrors ) { long rc = 0; krb5_context ctx = 0; // statically allocated in make_temp_cache_v5 // XXX - we ignore errors in make_temp_cache_v? This is BAD!!! make_temp_cache_v5("_checkpwd", &ctx); rc = Leash_int_kinit_ex( ctx, 0, principal, password, 0, 0, 0, 0, Leash_get_default_noaddresses(), Leash_get_default_publicip(), displayErrors ); make_temp_cache_v5(0, &ctx); return rc; } static long Leash_changepwd_v5( char * principal, char * password, char * newpassword, char** error_str ) { krb5_error_code rc = 0; int result_code; krb5_data result_code_string, result_string; krb5_context context = 0; krb5_principal princ = 0; krb5_get_init_creds_opt opts; krb5_creds creds; DWORD addressless = 0; result_string.data = 0; result_code_string.data = 0; if ( !pkrb5_init_context ) goto cleanup; if (rc = pkrb5_init_context(&context)) { #if 0 com_err(argv[0], ret, "initializing kerberos library"); #endif goto cleanup; } if (rc = pkrb5_parse_name(context, principal, &princ)) { #if 0 com_err(argv[0], ret, "parsing client name"); #endif goto cleanup; } pkrb5_get_init_creds_opt_init(&opts); pkrb5_get_init_creds_opt_set_tkt_life(&opts, 5*60); pkrb5_get_init_creds_opt_set_renew_life(&opts, 0); pkrb5_get_init_creds_opt_set_forwardable(&opts, 0); pkrb5_get_init_creds_opt_set_proxiable(&opts, 0); addressless = Leash_get_default_noaddresses(); if (addressless) pkrb5_get_init_creds_opt_set_address_list(&opts,NULL); if (rc = pkrb5_get_init_creds_password(context, &creds, princ, password, 0, 0, 0, "kadmin/changepw", &opts)) { if (rc == KRB5KRB_AP_ERR_BAD_INTEGRITY) { #if 0 com_err(argv[0], 0, "Password incorrect while getting initial ticket"); #endif } else { #if 0 com_err(argv[0], ret, "getting initial ticket"); #endif } goto cleanup; } if (rc = pkrb5_change_password(context, &creds, newpassword, &result_code, &result_code_string, &result_string)) { #if 0 com_err(argv[0], ret, "changing password"); #endif goto cleanup; } if (result_code) { int len = result_code_string.length + (result_string.length ? (sizeof(": ") - 1) : 0) + result_string.length; if (len && error_str) { *error_str = malloc(len + 1); if (*error_str) _snprintf(*error_str, len + 1, "%.*s%s%.*s", result_code_string.length, result_code_string.data, result_string.length?": ":"", result_string.length, result_string.data); } rc = result_code; goto cleanup; } cleanup: if (result_string.data) pkrb5_free_data_contents(context, &result_string); if (result_code_string.data) pkrb5_free_data_contents(context, &result_code_string); if (princ) pkrb5_free_principal(context, princ); if (context) pkrb5_free_context(context); return rc; } /* * Leash_changepwd * * Try to change the password using krb5. */ long Leash_changepwd( char * principal, char * password, char * newpassword, char** result_string ) { return Leash_int_changepwd(principal, password, newpassword, result_string, 0); } long Leash_int_changepwd( char * principal, char * password, char * newpassword, char** result_string, int displayErrors ) { char* v5_error_str = 0; char* error_str = 0; int rc5 = 0; int rc = 0; if (hKrb5) rc = rc5 = Leash_changepwd_v5(principal, password, newpassword, &v5_error_str); if (!rc) return 0; if (v5_error_str) { int len = 0; char v5_prefix[] = "Kerberos 5: "; char sep[] = "\n"; clean_string(v5_error_str); if (v5_error_str) len += sizeof(sep) + sizeof(v5_prefix) + strlen(v5_error_str) + sizeof(sep); error_str = malloc(len + 1); if (error_str) { char* p = error_str; int size = len + 1; int n; if (v5_error_str) { n = _snprintf(p, size, "%s%s%s%s", sep, v5_prefix, v5_error_str, sep); p += n; size -= n; } if (result_string) *result_string = error_str; } } return leash_error_message("Error while changing password.", 0, rc5, 0, error_str, displayErrors ); } int (*Lcom_err)(LPSTR,long,LPSTR,...); LPSTR (*Lerror_message)(long); LPSTR (*Lerror_table_name)(long); long Leash_kinit( char * principal, char * password, int lifetime ) { return Leash_int_kinit_ex( 0, 0, principal, password, lifetime, Leash_get_default_forwardable(), Leash_get_default_proxiable(), Leash_get_default_renew_till(), Leash_get_default_noaddresses(), Leash_get_default_publicip(), 0 ); } long Leash_kinit_ex( char * principal, char * password, int lifetime, int forwardable, int proxiable, int renew_life, int addressless, unsigned long publicip ) { return Leash_int_kinit_ex( 0, /* krb5 context */ 0, /* parent window */ principal, password, lifetime, forwardable, proxiable, renew_life, addressless, publicip, 0 ); } long Leash_int_kinit_ex( krb5_context ctx, HWND hParent, char * principal, char * password, int lifetime, int forwardable, int proxiable, int renew_life, int addressless, unsigned long publicip, int displayErrors ) { char aname[ANAME_SZ]; char inst[INST_SZ]; char realm[REALM_SZ]; char first_part[256]; char second_part[256]; char temp[1024]; char* custom_msg; int count; int i; int rc5 = 0; int rcA = 0; int rcB = 0; int rcL = 0; if (lifetime < 5) lifetime = 1; else lifetime /= 5; if (renew_life > 0 && renew_life < 5) renew_life = 1; else renew_life /= 5; /* This should be changed if the maximum ticket lifetime */ /* changes */ if (lifetime > 255) lifetime = 255; err_context = "parsing principal"; memset(temp, '\0', sizeof(temp)); memset(inst, '\0', sizeof(inst)); memset(realm, '\0', sizeof(realm)); memset(first_part, '\0', sizeof(first_part)); memset(second_part, '\0', sizeof(second_part)); sscanf(principal, "%[/0-9a-zA-Z._-]@%[/0-9a-zA-Z._-]", first_part, second_part); strcpy(temp, first_part); strcpy(realm, second_part); memset(first_part, '\0', sizeof(first_part)); memset(second_part, '\0', sizeof(second_part)); if (sscanf(temp, "%[@0-9a-zA-Z._-]/%[@0-9a-zA-Z._-]", first_part, second_part) == 2) { strcpy(aname, first_part); strcpy(inst, second_part); } else { count = 0; i = 0; for (i = 0; temp[i]; i++) { if (temp[i] == '.') ++count; } if (count > 1) { strcpy(aname, temp); } else { { strcpy(aname, temp); } } } memset(temp, '\0', sizeof(temp)); strcpy(temp, aname); if (strlen(inst) != 0) { strcat(temp, "/"); strcat(temp, inst); } if (strlen(realm) != 0) { strcat(temp, "@"); strcat(temp, realm); } rc5 = Leash_krb5_kinit(ctx, hParent, temp, password, lifetime, forwardable, proxiable, renew_life, addressless, publicip ); #ifndef NO_AFS if ( !rc5 ) { char c; char *r; char *t; for ( r=realm, t=temp; c=*r; r++,t++ ) *t = isupper(c) ? tolower(c) : c; *t = '\0'; rcA = Leash_afs_klog("afs", temp, "", lifetime); rcB = Leash_afs_klog("afs", "", "", lifetime); if (!(rcA && rcB)) rcA = 0; else if (!rcA) rcA = rcB; } #endif /* NO_AFS */ custom_msg = (rc5 == KRB5KRB_AP_ERR_BAD_INTEGRITY) ? "Password incorrect" : NULL; return leash_error_message("Ticket initialization failed.", rcL, rc5, rcA, custom_msg, displayErrors); } long FAR Leash_renew(void) { if ( hKrb5 && !LeashKRB5_renew() ) { int lifetime; lifetime = Leash_get_default_lifetime() / 5; #ifndef NO_AFS { TicketList * list = NULL, * token; not_an_API_LeashAFSGetToken(NULL,&list,NULL); for ( token = list ; token ; token = token->next ) Leash_afs_klog("afs", token->realm, "", lifetime); not_an_API_LeashFreeTicketList(&list); } #endif /* NO_AFS */ return 1; } return 0; } BOOL GetSecurityLogonSessionData(PSECURITY_LOGON_SESSION_DATA * ppSessionData) { NTSTATUS Status = 0; HANDLE TokenHandle; TOKEN_STATISTICS Stats; DWORD ReqLen; BOOL Success; PSECURITY_LOGON_SESSION_DATA pSessionData; if (!ppSessionData) return FALSE; *ppSessionData = NULL; Success = OpenProcessToken( GetCurrentProcess(), TOKEN_QUERY, &TokenHandle ); if ( !Success ) return FALSE; Success = GetTokenInformation( TokenHandle, TokenStatistics, &Stats, sizeof(TOKEN_STATISTICS), &ReqLen ); CloseHandle( TokenHandle ); if ( !Success ) return FALSE; Status = pLsaGetLogonSessionData( &Stats.AuthenticationId, &pSessionData ); if ( FAILED(Status) || !pSessionData ) return FALSE; *ppSessionData = pSessionData; return TRUE; } // IsKerberosLogon() does not validate whether or not there are valid tickets in the // cache. It validates whether or not it is reasonable to assume that if we // attempted to retrieve valid tickets we could do so. Microsoft does not // automatically renew expired tickets. Therefore, the cache could contain // expired or invalid tickets. Microsoft also caches the user's password // and will use it to retrieve new TGTs if the cache is empty and tickets // are requested. BOOL IsKerberosLogon(VOID) { PSECURITY_LOGON_SESSION_DATA pSessionData = NULL; BOOL Success = FALSE; if ( GetSecurityLogonSessionData(&pSessionData) ) { if ( pSessionData->AuthenticationPackage.Buffer ) { WCHAR buffer[256]; WCHAR *usBuffer; int usLength; Success = FALSE; usBuffer = (pSessionData->AuthenticationPackage).Buffer; usLength = (pSessionData->AuthenticationPackage).Length; if (usLength < 256) { lstrcpynW (buffer, usBuffer, usLength); lstrcatW (buffer,L""); if ( !lstrcmpW(L"Kerberos",buffer) ) Success = TRUE; } } pLsaFreeReturnBuffer(pSessionData); } return Success; } static BOOL IsWindowsVista (void) { static BOOL fChecked = FALSE; static BOOL fIsVista = FALSE; if (!fChecked) { OSVERSIONINFO Version; memset (&Version, 0x00, sizeof(Version)); Version.dwOSVersionInfoSize = sizeof(Version); if (GetVersionEx (&Version)) { if (Version.dwPlatformId == VER_PLATFORM_WIN32_NT && Version.dwMajorVersion >= 6) fIsVista = TRUE; } fChecked = TRUE; } return fIsVista; } static BOOL IsProcessUacLimited (void) { static BOOL fChecked = FALSE; static BOOL fIsUAC = FALSE; if (!fChecked) { NTSTATUS Status = 0; HANDLE TokenHandle; DWORD ElevationLevel; DWORD ReqLen; BOOL Success; if (IsWindowsVista()) { Success = OpenProcessToken( GetCurrentProcess(), TOKEN_QUERY, &TokenHandle ); if ( Success ) { Success = GetTokenInformation( TokenHandle, TokenOrigin+1 /* ElevationLevel */, &ElevationLevel, sizeof(DWORD), &ReqLen ); CloseHandle( TokenHandle ); if ( Success && ElevationLevel == 3 /* Limited */ ) fIsUAC = TRUE; } } fChecked = TRUE; } return fIsUAC; } // This looks really ugly because it is. The result of IsKerberosLogon() // does not prove whether or not there are Kerberos tickets available to // be imported. Only the call to Leash_ms2mit() which actually attempts // to import tickets can do that. However, calling Leash_ms2mit() can // result in a TGS_REQ being sent to the KDC and since Leash_importable() // is called quite often we want to avoid this if at all possible. // Unfortunately, we have be shown at least one case in which the primary // authentication package was not Kerberos and yet there were Kerberos // tickets available. Therefore, if IsKerberosLogon() is not TRUE we // must call Leash_ms2mit() but we still do not want to call it in a // tight loop so we cache the response and assume it won't change. // 2007-03-21 // And the nightmare goes on. On Vista the Lsa call we use to determine // whether or not Kerberos was used for logon fails to return and worse // corrupts the stack. Therefore, we must now test to see if the // operating system is Vista and skip the call to IsKerberosLogon() // if it is. long FAR Leash_importable(void) { if (IsProcessUacLimited()) return FALSE; if ( !IsWindowsVista() && IsKerberosLogon() ) return TRUE; else { static int response = -1; if (response == -1) { response = Leash_ms2mit(0); } return response; } } long FAR Leash_import(void) { if ( Leash_ms2mit(1) ) { int lifetime; lifetime = Leash_get_default_lifetime() / 5; #ifndef NO_AFS { char c; char *r; char *t; char cell[256]; char realm[256]; int i = 0; int rcA = 0; int rcB = 0; krb5_context ctx = 0; krb5_error_code code = 0; krb5_ccache cc = 0; krb5_principal me = 0; if ( !pkrb5_init_context ) goto cleanup; code = pkrb5_init_context(&ctx); if (code) goto cleanup; code = pkrb5_cc_default(ctx, &cc); if (code) goto cleanup; if (code = pkrb5_cc_get_principal(ctx, cc, &me)) goto cleanup; for ( r=realm, t=cell, i=0; ilength; r++,t++,i++ ) { c = krb5_princ_realm(ctx, me)->data[i]; *r = c; *t = isupper(c) ? tolower(c) : c; } *r = *t = '\0'; rcA = Leash_afs_klog("afs", cell, "", lifetime); rcB = Leash_afs_klog("afs", "", "", lifetime); if (!(rcA && rcB)) rcA = 0; else if (!rcA) rcA = rcB; cleanup: if (me) pkrb5_free_principal(ctx, me); if (cc) pkrb5_cc_close(ctx, cc); if (ctx) pkrb5_free_context(ctx); } #endif /* NO_AFS */ return 1; } return 0; } long Leash_kdestroy(void) { Leash_afs_unlog(); Leash_krb5_kdestroy(); return 0; } long FAR not_an_API_LeashFreeTicketList(TicketList** ticketList) { TicketList* tempList = *ticketList, *killList; //if (tempList == NULL) //return -1; while (tempList) { killList = tempList; tempList = (TicketList*)tempList->next; free(killList->service); if (killList->encTypes) free(killList->encTypes); free(killList); } *ticketList = NULL; return 0; } long not_an_API_LeashKRB4GetTickets(TICKETINFO FAR* ticketinfo, TicketList** ticketList) { return(KFAILURE); } long FAR Leash_klist(HWND hlist, TICKETINFO FAR *ticketinfo) { return(KFAILURE); } // This function can be used to set the help file that will be // referenced the DLL's PasswordProcDLL function and err_describe // function. Returns true if the help file has been set to the // argument or the environment variable KERB_HELP. Returns FALSE if // the default helpfile as defined in by HELPFILE in lsh_pwd.h is // used. BOOL Leash_set_help_file( char *szHelpFile ) { char tmpHelpFile[256]; BOOL ret = 0; if( szHelpFile == NULL ){ GetEnvironmentVariable("KERB_HELP", tmpHelpFile, sizeof(tmpHelpFile)); } else { strcpy( KRB_HelpFile, szHelpFile ); ret++; } if( !ret && tmpHelpFile[0] ){ strcpy( KRB_HelpFile, tmpHelpFile ); ret++; } if( !ret){ strcpy( KRB_HelpFile, HELPFILE ); } return(ret); } LPSTR Leash_get_help_file(void) { return( KRB_HelpFile); } int Leash_debug( int class, int priority, char* fmt, ... ) { return 0; } static int get_profile_file(LPSTR confname, UINT szConfname) { char **configFile = NULL; if (hKrb5) { if (pkrb5_get_default_config_files(&configFile) || !configFile[0]) { GetWindowsDirectory(confname,szConfname); confname[szConfname-1] = '\0'; strncat(confname,"\\KRB5.INI",szConfname-strlen(confname)); confname[szConfname-1] = '\0'; return FALSE; } *confname = 0; if (configFile) { strncpy(confname, *configFile, szConfname); confname[szConfname-1] = '\0'; pkrb5_free_config_files(configFile); } } if (!*confname) { GetWindowsDirectory(confname,szConfname); confname[szConfname-1] = '\0'; strncat(confname,"\\KRB5.INI",szConfname-strlen(confname)); confname[szConfname-1] = '\0'; } return FALSE; } static const char *const conf_yes[] = { "y", "yes", "true", "t", "1", "on", 0, }; static const char *const conf_no[] = { "n", "no", "false", "nil", "0", "off", 0, }; int config_boolean_to_int(const char *s) { const char *const *p; for(p=conf_yes; *p; p++) { if (!strcasecmp(*p,s)) return 1; } for(p=conf_no; *p; p++) { if (!strcasecmp(*p,s)) return 0; } /* Default to "no" */ return 0; } /* * Leash_get_default_lifetime: * * This function is used to get the default ticket lifetime for this * process in minutes. A return value of 0 indicates no setting or * "default" setting obtained. * * Here is where we look in order: * * - LIFETIME environment variable * - HKCU\Software\MIT\Leash,lifetime * - HKLM\Software\MIT\Leash,lifetime * - string resource in the leash DLL */ BOOL get_DWORD_from_registry( HKEY hBaseKey, char * key, char * value, DWORD * result ) { HKEY hKey; DWORD dwCount; LONG rc; rc = RegOpenKeyEx(hBaseKey, key, 0, KEY_QUERY_VALUE, &hKey); if (rc) return FALSE; dwCount = sizeof(DWORD); rc = RegQueryValueEx(hKey, value, 0, 0, (LPBYTE) result, &dwCount); RegCloseKey(hKey); return rc?FALSE:TRUE; } BOOL get_STRING_from_registry( HKEY hBaseKey, char * key, char * value, char * outbuf, DWORD outlen ) { HKEY hKey; DWORD dwCount; LONG rc; if (!outbuf || outlen == 0) return FALSE; rc = RegOpenKeyEx(hBaseKey, key, 0, KEY_QUERY_VALUE, &hKey); if (rc) return FALSE; dwCount = outlen; rc = RegQueryValueEx(hKey, value, 0, 0, (LPBYTE) outbuf, &dwCount); RegCloseKey(hKey); return rc?FALSE:TRUE; } static BOOL get_default_lifetime_from_registry( HKEY hBaseKey, DWORD * result ) { return get_DWORD_from_registry(hBaseKey, LEASH_REGISTRY_KEY_NAME, LEASH_REGISTRY_VALUE_LIFETIME, result); } DWORD Leash_reset_default_lifetime( ) { HKEY hKey; LONG rc; rc = RegOpenKeyEx(HKEY_CURRENT_USER, LEASH_REGISTRY_KEY_NAME, 0, KEY_WRITE, &hKey); if (rc) return rc; rc = RegDeleteValue(hKey, LEASH_REGISTRY_VALUE_LIFETIME); RegCloseKey(hKey); return rc; } DWORD Leash_set_default_lifetime( DWORD minutes ) { HKEY hKey; LONG rc; rc = RegCreateKeyEx(HKEY_CURRENT_USER, LEASH_REGISTRY_KEY_NAME, 0, 0, 0, KEY_WRITE, 0, &hKey, 0); if (rc) return rc; rc = RegSetValueEx(hKey, LEASH_REGISTRY_VALUE_LIFETIME, 0, REG_DWORD, (LPBYTE) &minutes, sizeof(DWORD)); RegCloseKey(hKey); return rc; } DWORD Leash_get_default_lifetime( ) { HMODULE hmLeash; char env[32]; DWORD result; if (GetEnvironmentVariable("LIFETIME",env,sizeof(env))) { return atoi(env); } if (get_default_lifetime_from_registry(HKEY_CURRENT_USER, &result) || get_default_lifetime_from_registry(HKEY_LOCAL_MACHINE, &result)) { return result; } if ( hKrb5 ) { CHAR confname[MAX_PATH]; if (!get_profile_file(confname, sizeof(confname))) { profile_t profile; const char *filenames[2]; long retval; filenames[0] = confname; filenames[1] = NULL; if (!pprofile_init(filenames, &profile)) { char * value = NULL; retval = pprofile_get_string(profile, "libdefaults", "ticket_lifetime", NULL, NULL, &value); if (retval == 0 && value) { krb5_deltat d; retval = pkrb5_string_to_deltat(value, &d); if (retval == KRB5_DELTAT_BADFORMAT) { /* Historically some sites use relations of the form 'ticket_lifetime = 24000' where the unit is left out but is assumed to be seconds. Then there are other sites which use the form 'ticket_lifetime = 600' where the unit is assumed to be minutes. While these are technically wrong (a unit needs to be specified), we try to accomodate for this using the safe assumption that the unit is seconds and tack an 's' to the end and see if that works. */ /* Of course, Leash is one of the platforms that historically assumed no units and minutes so this change is going to break some people but its better to be consistent. */ size_t cch; char buf[256]; do { cch = strlen(value) + 2; /* NUL and new 's' */ if (cch > sizeof(buf)) break; strcpy(buf, value); strcat(buf, "s"); retval = pkrb5_string_to_deltat(buf, &d); if (retval == 0) { result = d / 60; } } while(0); } else if (retval == 0) { result = d / 60; } pprofile_release_string(value); } pprofile_release(profile); /* value has been released but we can still use a check for * non-NULL to see if we were able to read a value. */ if (retval == 0 && value) return result; } } } hmLeash = GetModuleHandle(LEASH_DLL); if (hmLeash) { char lifetime[80]; if (LoadString(hmLeash, LSH_DEFAULT_TICKET_LIFE, lifetime, sizeof(lifetime))) { lifetime[sizeof(lifetime) - 1] = 0; return atoi(lifetime); } } return 0; } static BOOL get_default_renew_till_from_registry( HKEY hBaseKey, DWORD * result ) { return get_DWORD_from_registry(hBaseKey, LEASH_REGISTRY_KEY_NAME, LEASH_REGISTRY_VALUE_RENEW_TILL, result); } DWORD Leash_reset_default_renew_till( ) { HKEY hKey; LONG rc; rc = RegOpenKeyEx(HKEY_CURRENT_USER, LEASH_REGISTRY_KEY_NAME, 0, KEY_WRITE, &hKey); if (rc) return rc; rc = RegDeleteValue(hKey, LEASH_REGISTRY_VALUE_RENEW_TILL); RegCloseKey(hKey); return rc; } DWORD Leash_set_default_renew_till( DWORD minutes ) { HKEY hKey; LONG rc; rc = RegCreateKeyEx(HKEY_CURRENT_USER, LEASH_REGISTRY_KEY_NAME, 0, 0, 0, KEY_WRITE, 0, &hKey, 0); if (rc) return rc; rc = RegSetValueEx(hKey, LEASH_REGISTRY_VALUE_RENEW_TILL, 0, REG_DWORD, (LPBYTE) &minutes, sizeof(DWORD)); RegCloseKey(hKey); return rc; } DWORD Leash_get_default_renew_till( ) { HMODULE hmLeash; char env[32]; DWORD result; if(GetEnvironmentVariable("RENEW_TILL",env,sizeof(env))) { return atoi(env); } if (get_default_renew_till_from_registry(HKEY_CURRENT_USER, &result) || get_default_renew_till_from_registry(HKEY_LOCAL_MACHINE, &result)) { return result; } if ( hKrb5 ) { CHAR confname[MAX_PATH]; if (!get_profile_file(confname, sizeof(confname))) { profile_t profile; const char *filenames[2]; int value=0; long retval; filenames[0] = confname; filenames[1] = NULL; if (!pprofile_init(filenames, &profile)) { char * value = NULL; retval = pprofile_get_string(profile, "libdefaults", "renew_lifetime", NULL, NULL, &value); if (retval == 0 && value) { krb5_deltat d; retval = pkrb5_string_to_deltat(value, &d); if (retval == KRB5_DELTAT_BADFORMAT) { /* Historically some sites use relations of the form 'ticket_lifetime = 24000' where the unit is left out but is assumed to be seconds. Then there are other sites which use the form 'ticket_lifetime = 600' where the unit is assumed to be minutes. While these are technically wrong (a unit needs to be specified), we try to accomodate for this using the safe assumption that the unit is seconds and tack an 's' to the end and see if that works. */ /* Of course, Leash is one of the platforms that historically assumed no units and minutes so this change is going to break some people but its better to be consistent. */ size_t cch; char buf[256]; do { cch = strlen(value) + 2; /* NUL and new 's' */ if (cch > sizeof(buf)) break; strcpy(buf, value); strcat(buf, "s"); retval = pkrb5_string_to_deltat(buf, &d); if (retval == 0) { result = d / 60; } } while(0); } else if (retval == 0) { result = d / 60; } pprofile_release_string(value); } pprofile_release(profile); /* value has been released but we can still use a check for * non-NULL to see if we were able to read a value. */ if (retval == 0 && value) return result; pprofile_release(profile); } } } hmLeash = GetModuleHandle(LEASH_DLL); if (hmLeash) { char renew_till[80]; if (LoadString(hmLeash, LSH_DEFAULT_TICKET_RENEW_TILL, renew_till, sizeof(renew_till))) { renew_till[sizeof(renew_till) - 1] = 0; return atoi(renew_till); } } return 0; } static BOOL get_default_forwardable_from_registry( HKEY hBaseKey, DWORD * result ) { return get_DWORD_from_registry(hBaseKey, LEASH_REGISTRY_KEY_NAME, LEASH_REGISTRY_VALUE_FORWARDABLE, result); } DWORD Leash_reset_default_forwardable( ) { HKEY hKey; LONG rc; rc = RegOpenKeyEx(HKEY_CURRENT_USER, LEASH_REGISTRY_KEY_NAME, 0, KEY_WRITE, &hKey); if (rc) return rc; rc = RegDeleteValue(hKey, LEASH_REGISTRY_VALUE_FORWARDABLE); RegCloseKey(hKey); return rc; } DWORD Leash_set_default_forwardable( DWORD minutes ) { HKEY hKey; LONG rc; rc = RegCreateKeyEx(HKEY_CURRENT_USER, LEASH_REGISTRY_KEY_NAME, 0, 0, 0, KEY_WRITE, 0, &hKey, 0); if (rc) return rc; rc = RegSetValueEx(hKey, LEASH_REGISTRY_VALUE_FORWARDABLE, 0, REG_DWORD, (LPBYTE) &minutes, sizeof(DWORD)); RegCloseKey(hKey); return rc; } DWORD Leash_get_default_forwardable( ) { HMODULE hmLeash; char env[32]; DWORD result; if(GetEnvironmentVariable("FORWARDABLE",env,sizeof(env))) { return atoi(env); } if (get_default_forwardable_from_registry(HKEY_CURRENT_USER, &result) || get_default_forwardable_from_registry(HKEY_LOCAL_MACHINE, &result)) { return result; } if ( hKrb5 ) { CHAR confname[MAX_PATH]; if (!get_profile_file(confname, sizeof(confname))) { profile_t profile; const char *filenames[2]; char *value=0; long retval; filenames[0] = confname; filenames[1] = NULL; if (!pprofile_init(filenames, &profile)) { retval = pprofile_get_string(profile, "libdefaults","forwardable", 0, 0, &value); if ( value ) { result = config_boolean_to_int(value); pprofile_release_string(value); pprofile_release(profile); return result; } pprofile_release(profile); } } } hmLeash = GetModuleHandle(LEASH_DLL); if (hmLeash) { char forwardable[80]; if (LoadString(hmLeash, LSH_DEFAULT_TICKET_FORWARD, forwardable, sizeof(forwardable))) { forwardable[sizeof(forwardable) - 1] = 0; return atoi(forwardable); } } return 0; } static BOOL get_default_renewable_from_registry( HKEY hBaseKey, DWORD * result ) { return get_DWORD_from_registry(hBaseKey, LEASH_REGISTRY_KEY_NAME, LEASH_REGISTRY_VALUE_RENEWABLE, result); } DWORD Leash_reset_default_renewable( ) { HKEY hKey; LONG rc; rc = RegOpenKeyEx(HKEY_CURRENT_USER, LEASH_REGISTRY_KEY_NAME, 0, KEY_WRITE, &hKey); if (rc) return rc; rc = RegDeleteValue(hKey, LEASH_REGISTRY_VALUE_RENEWABLE); RegCloseKey(hKey); return rc; } DWORD Leash_set_default_renewable( DWORD minutes ) { HKEY hKey; LONG rc; rc = RegCreateKeyEx(HKEY_CURRENT_USER, LEASH_REGISTRY_KEY_NAME, 0, 0, 0, KEY_WRITE, 0, &hKey, 0); if (rc) return rc; rc = RegSetValueEx(hKey, LEASH_REGISTRY_VALUE_RENEWABLE, 0, REG_DWORD, (LPBYTE) &minutes, sizeof(DWORD)); RegCloseKey(hKey); return rc; } DWORD Leash_get_default_renewable( ) { HMODULE hmLeash; char env[32]; DWORD result; if(GetEnvironmentVariable("RENEWABLE",env,sizeof(env))) { return atoi(env); } if (get_default_renewable_from_registry(HKEY_CURRENT_USER, &result) || get_default_renewable_from_registry(HKEY_LOCAL_MACHINE, &result)) { return result; } if ( hKrb5 ) { CHAR confname[MAX_PATH]; if (!get_profile_file(confname, sizeof(confname))) { profile_t profile; const char *filenames[2]; char *value=0; long retval; filenames[0] = confname; filenames[1] = NULL; if (!pprofile_init(filenames, &profile)) { retval = pprofile_get_string(profile, "libdefaults","renewable", 0, 0, &value); if ( value ) { result = config_boolean_to_int(value); pprofile_release_string(value); pprofile_release(profile); return result; } pprofile_release(profile); } } } hmLeash = GetModuleHandle(LEASH_DLL); if (hmLeash) { char renewable[80]; if (LoadString(hmLeash, LSH_DEFAULT_TICKET_RENEW, renewable, sizeof(renewable))) { renewable[sizeof(renewable) - 1] = 0; return atoi(renewable); } } return 0; } static BOOL get_default_noaddresses_from_registry( HKEY hBaseKey, DWORD * result ) { return get_DWORD_from_registry(hBaseKey, LEASH_REGISTRY_KEY_NAME, LEASH_REGISTRY_VALUE_NOADDRESSES, result); } DWORD Leash_reset_default_noaddresses( ) { HKEY hKey; LONG rc; rc = RegOpenKeyEx(HKEY_CURRENT_USER, LEASH_REGISTRY_KEY_NAME, 0, KEY_WRITE, &hKey); if (rc) return rc; rc = RegDeleteValue(hKey, LEASH_REGISTRY_VALUE_NOADDRESSES); RegCloseKey(hKey); return rc; } DWORD Leash_set_default_noaddresses( DWORD minutes ) { HKEY hKey; LONG rc; rc = RegCreateKeyEx(HKEY_CURRENT_USER, LEASH_REGISTRY_KEY_NAME, 0, 0, 0, KEY_WRITE, 0, &hKey, 0); if (rc) return rc; rc = RegSetValueEx(hKey, LEASH_REGISTRY_VALUE_NOADDRESSES, 0, REG_DWORD, (LPBYTE) &minutes, sizeof(DWORD)); RegCloseKey(hKey); return rc; } DWORD Leash_get_default_noaddresses( ) { HMODULE hmLeash; char env[32]; DWORD result; if ( hKrb5 ) { // if the profile file cannot be opened then the value will be true // if the noaddresses name cannot be found then the value will be true // if true in the library, we can't alter it by other means CHAR confname[MAX_PATH]; result = 1; if (!get_profile_file(confname, sizeof(confname))) { profile_t profile; const char *filenames[2]; char *value=0; long retval; filenames[0] = confname; filenames[1] = NULL; if (!pprofile_init(filenames, &profile)) { retval = pprofile_get_string(profile, "libdefaults","noaddresses", 0, "true", &value); if ( value ) { result = config_boolean_to_int(value); pprofile_release_string(value); } pprofile_release(profile); } } if ( result ) return 1; } // The library default is false, check other locations if(GetEnvironmentVariable("NOADDRESSES",env,sizeof(env))) { return atoi(env); } if (get_default_noaddresses_from_registry(HKEY_CURRENT_USER, &result) || get_default_noaddresses_from_registry(HKEY_LOCAL_MACHINE, &result)) { return result; } hmLeash = GetModuleHandle(LEASH_DLL); if (hmLeash) { char noaddresses[80]; if (LoadString(hmLeash, LSH_DEFAULT_TICKET_NOADDRESS, noaddresses, sizeof(noaddresses))) { noaddresses[sizeof(noaddresses) - 1] = 0; } } return 1; } static BOOL get_default_proxiable_from_registry( HKEY hBaseKey, DWORD * result ) { return get_DWORD_from_registry(hBaseKey, LEASH_REGISTRY_KEY_NAME, LEASH_REGISTRY_VALUE_PROXIABLE, result); } DWORD Leash_reset_default_proxiable( ) { HKEY hKey; LONG rc; rc = RegOpenKeyEx(HKEY_CURRENT_USER, LEASH_REGISTRY_KEY_NAME, 0, KEY_WRITE, &hKey); if (rc) return rc; rc = RegDeleteValue(hKey, LEASH_REGISTRY_VALUE_PROXIABLE); RegCloseKey(hKey); return rc; } DWORD Leash_set_default_proxiable( DWORD minutes ) { HKEY hKey; LONG rc; rc = RegCreateKeyEx(HKEY_CURRENT_USER, LEASH_REGISTRY_KEY_NAME, 0, 0, 0, KEY_WRITE, 0, &hKey, 0); if (rc) return rc; rc = RegSetValueEx(hKey, LEASH_REGISTRY_VALUE_PROXIABLE, 0, REG_DWORD, (LPBYTE) &minutes, sizeof(DWORD)); RegCloseKey(hKey); return rc; } DWORD Leash_get_default_proxiable( ) { HMODULE hmLeash; char env[32]; DWORD result; if(GetEnvironmentVariable("PROXIABLE",env,sizeof(env))) { return atoi(env); } if (get_default_proxiable_from_registry(HKEY_CURRENT_USER, &result) || get_default_proxiable_from_registry(HKEY_LOCAL_MACHINE, &result)) { return result; } if ( hKrb5 ) { CHAR confname[MAX_PATH]; if (!get_profile_file(confname, sizeof(confname))) { profile_t profile; const char *filenames[2]; char *value=0; long retval; filenames[0] = confname; filenames[1] = NULL; if (!pprofile_init(filenames, &profile)) { retval = pprofile_get_string(profile, "libdefaults","proxiable", 0, 0, &value); if ( value ) { result = config_boolean_to_int(value); pprofile_release_string(value); pprofile_release(profile); return result; } pprofile_release(profile); } } } hmLeash = GetModuleHandle(LEASH_DLL); if (hmLeash) { char proxiable[80]; if (LoadString(hmLeash, LSH_DEFAULT_TICKET_PROXIABLE, proxiable, sizeof(proxiable))) { proxiable[sizeof(proxiable) - 1] = 0; return atoi(proxiable); } } return 0; } static BOOL get_default_publicip_from_registry( HKEY hBaseKey, DWORD * result ) { return get_DWORD_from_registry(hBaseKey, LEASH_REGISTRY_KEY_NAME, LEASH_REGISTRY_VALUE_PUBLICIP, result); } DWORD Leash_reset_default_publicip( ) { HKEY hKey; LONG rc; rc = RegOpenKeyEx(HKEY_CURRENT_USER, LEASH_REGISTRY_KEY_NAME, 0, KEY_WRITE, &hKey); if (rc) return rc; rc = RegDeleteValue(hKey, LEASH_REGISTRY_VALUE_PUBLICIP); RegCloseKey(hKey); return rc; } DWORD Leash_set_default_publicip( DWORD minutes ) { HKEY hKey; LONG rc; rc = RegCreateKeyEx(HKEY_CURRENT_USER, LEASH_REGISTRY_KEY_NAME, 0, 0, 0, KEY_WRITE, 0, &hKey, 0); if (rc) return rc; rc = RegSetValueEx(hKey, LEASH_REGISTRY_VALUE_PUBLICIP, 0, REG_DWORD, (LPBYTE) &minutes, sizeof(DWORD)); RegCloseKey(hKey); return rc; } DWORD Leash_get_default_publicip( ) { HMODULE hmLeash; char env[32]; DWORD result; if(GetEnvironmentVariable("PUBLICIP",env,sizeof(env))) { return atoi(env); } if (get_default_publicip_from_registry(HKEY_CURRENT_USER, &result) || get_default_publicip_from_registry(HKEY_LOCAL_MACHINE, &result)) { return result; } hmLeash = GetModuleHandle(LEASH_DLL); if (hmLeash) { char publicip[80]; if (LoadString(hmLeash, LSH_DEFAULT_TICKET_PUBLICIP, publicip, sizeof(publicip))) { publicip[sizeof(publicip) - 1] = 0; return atoi(publicip); } } return 0; } static BOOL get_default_use_krb4_from_registry( HKEY hBaseKey, DWORD * result ) { return get_DWORD_from_registry(hBaseKey, LEASH_REGISTRY_KEY_NAME, LEASH_REGISTRY_VALUE_USEKRB4, result); } DWORD Leash_reset_default_use_krb4( ) { HKEY hKey; LONG rc; rc = RegOpenKeyEx(HKEY_CURRENT_USER, LEASH_REGISTRY_KEY_NAME, 0, KEY_WRITE, &hKey); if (rc) return rc; rc = RegDeleteValue(hKey, LEASH_REGISTRY_VALUE_USEKRB4); RegCloseKey(hKey); return rc; } DWORD Leash_set_default_use_krb4( DWORD minutes ) { HKEY hKey; LONG rc; rc = RegCreateKeyEx(HKEY_CURRENT_USER, LEASH_REGISTRY_KEY_NAME, 0, 0, 0, KEY_WRITE, 0, &hKey, 0); if (rc) return rc; rc = RegSetValueEx(hKey, LEASH_REGISTRY_VALUE_USEKRB4, 0, REG_DWORD, (LPBYTE) &minutes, sizeof(DWORD)); RegCloseKey(hKey); return rc; } DWORD Leash_get_default_use_krb4( ) { return 0; /* don't use krb4 */ } static BOOL get_hide_kinit_options_from_registry( HKEY hBaseKey, DWORD * result ) { return get_DWORD_from_registry(hBaseKey, LEASH_REGISTRY_KEY_NAME, LEASH_REGISTRY_VALUE_KINIT_OPT, result); } DWORD Leash_reset_hide_kinit_options( ) { HKEY hKey; LONG rc; rc = RegOpenKeyEx(HKEY_CURRENT_USER, LEASH_REGISTRY_KEY_NAME, 0, KEY_WRITE, &hKey); if (rc) return rc; rc = RegDeleteValue(hKey, LEASH_REGISTRY_VALUE_KINIT_OPT); RegCloseKey(hKey); return rc; } DWORD Leash_set_hide_kinit_options( DWORD minutes ) { HKEY hKey; LONG rc; rc = RegCreateKeyEx(HKEY_CURRENT_USER, LEASH_REGISTRY_KEY_NAME, 0, 0, 0, KEY_WRITE, 0, &hKey, 0); if (rc) return rc; rc = RegSetValueEx(hKey, LEASH_REGISTRY_VALUE_KINIT_OPT, 0, REG_DWORD, (LPBYTE) &minutes, sizeof(DWORD)); RegCloseKey(hKey); return rc; } DWORD Leash_get_hide_kinit_options( ) { HMODULE hmLeash; DWORD result; if (get_hide_kinit_options_from_registry(HKEY_CURRENT_USER, &result) || get_hide_kinit_options_from_registry(HKEY_LOCAL_MACHINE, &result)) { return result; } hmLeash = GetModuleHandle(LEASH_DLL); if (hmLeash) { char use_krb4[80]; if (LoadString(hmLeash, LSH_DEFAULT_DIALOG_KINIT_OPT, use_krb4, sizeof(use_krb4))) { use_krb4[sizeof(use_krb4) - 1] = 0; return atoi(use_krb4); } } return 0; /* hide unless otherwise indicated */ } static BOOL get_default_life_min_from_registry( HKEY hBaseKey, DWORD * result ) { return get_DWORD_from_registry(hBaseKey, LEASH_REGISTRY_KEY_NAME, LEASH_REGISTRY_VALUE_LIFE_MIN, result); } DWORD Leash_reset_default_life_min( ) { HKEY hKey; LONG rc; rc = RegOpenKeyEx(HKEY_CURRENT_USER, LEASH_REGISTRY_KEY_NAME, 0, KEY_WRITE, &hKey); if (rc) return rc; rc = RegDeleteValue(hKey, LEASH_REGISTRY_VALUE_LIFE_MIN); RegCloseKey(hKey); return rc; } DWORD Leash_set_default_life_min( DWORD minutes ) { HKEY hKey; LONG rc; rc = RegCreateKeyEx(HKEY_CURRENT_USER, LEASH_REGISTRY_KEY_NAME, 0, 0, 0, KEY_WRITE, 0, &hKey, 0); if (rc) return rc; rc = RegSetValueEx(hKey, LEASH_REGISTRY_VALUE_LIFE_MIN, 0, REG_DWORD, (LPBYTE) &minutes, sizeof(DWORD)); RegCloseKey(hKey); return rc; } DWORD Leash_get_default_life_min( ) { HMODULE hmLeash; DWORD result; if (get_default_life_min_from_registry(HKEY_CURRENT_USER, &result) || get_default_life_min_from_registry(HKEY_LOCAL_MACHINE, &result)) { return result; } hmLeash = GetModuleHandle(LEASH_DLL); if (hmLeash) { char use_krb4[80]; if (LoadString(hmLeash, LSH_DEFAULT_DIALOG_LIFE_MIN, use_krb4, sizeof(use_krb4))) { use_krb4[sizeof(use_krb4) - 1] = 0; return atoi(use_krb4); } } return 5; /* 5 minutes */ } static BOOL get_default_life_max_from_registry( HKEY hBaseKey, DWORD * result ) { return get_DWORD_from_registry(hBaseKey, LEASH_REGISTRY_KEY_NAME, LEASH_REGISTRY_VALUE_LIFE_MAX, result); } DWORD Leash_reset_default_life_max( ) { HKEY hKey; LONG rc; rc = RegOpenKeyEx(HKEY_CURRENT_USER, LEASH_REGISTRY_KEY_NAME, 0, KEY_WRITE, &hKey); if (rc) return rc; rc = RegDeleteValue(hKey, LEASH_REGISTRY_VALUE_LIFE_MAX); RegCloseKey(hKey); return rc; } DWORD Leash_set_default_life_max( DWORD minutes ) { HKEY hKey; LONG rc; rc = RegCreateKeyEx(HKEY_CURRENT_USER, LEASH_REGISTRY_KEY_NAME, 0, 0, 0, KEY_WRITE, 0, &hKey, 0); if (rc) return rc; rc = RegSetValueEx(hKey, LEASH_REGISTRY_VALUE_LIFE_MAX, 0, REG_DWORD, (LPBYTE) &minutes, sizeof(DWORD)); RegCloseKey(hKey); return rc; } DWORD Leash_get_default_life_max( ) { HMODULE hmLeash; DWORD result; if (get_default_life_max_from_registry(HKEY_CURRENT_USER, &result) || get_default_life_max_from_registry(HKEY_LOCAL_MACHINE, &result)) { return result; } hmLeash = GetModuleHandle(LEASH_DLL); if (hmLeash) { char use_krb4[80]; if (LoadString(hmLeash, LSH_DEFAULT_DIALOG_LIFE_MAX, use_krb4, sizeof(use_krb4))) { use_krb4[sizeof(use_krb4) - 1] = 0; return atoi(use_krb4); } } return 1440; } static BOOL get_default_renew_min_from_registry( HKEY hBaseKey, DWORD * result ) { return get_DWORD_from_registry(hBaseKey, LEASH_REGISTRY_KEY_NAME, LEASH_REGISTRY_VALUE_RENEW_MIN, result); } DWORD Leash_reset_default_renew_min( ) { HKEY hKey; LONG rc; rc = RegOpenKeyEx(HKEY_CURRENT_USER, LEASH_REGISTRY_KEY_NAME, 0, KEY_WRITE, &hKey); if (rc) return rc; rc = RegDeleteValue(hKey, LEASH_REGISTRY_VALUE_RENEW_MIN); RegCloseKey(hKey); return rc; } DWORD Leash_set_default_renew_min( DWORD minutes ) { HKEY hKey; LONG rc; rc = RegCreateKeyEx(HKEY_CURRENT_USER, LEASH_REGISTRY_KEY_NAME, 0, 0, 0, KEY_WRITE, 0, &hKey, 0); if (rc) return rc; rc = RegSetValueEx(hKey, LEASH_REGISTRY_VALUE_RENEW_MIN, 0, REG_DWORD, (LPBYTE) &minutes, sizeof(DWORD)); RegCloseKey(hKey); return rc; } DWORD Leash_get_default_renew_min( ) { HMODULE hmLeash; DWORD result; if (get_default_renew_min_from_registry(HKEY_CURRENT_USER, &result) || get_default_renew_min_from_registry(HKEY_LOCAL_MACHINE, &result)) { return result; } hmLeash = GetModuleHandle(LEASH_DLL); if (hmLeash) { char use_krb4[80]; if (LoadString(hmLeash, LSH_DEFAULT_DIALOG_RENEW_MIN, use_krb4, sizeof(use_krb4))) { use_krb4[sizeof(use_krb4) - 1] = 0; return atoi(use_krb4); } } return 600; /* 10 hours */ } static BOOL get_default_renew_max_from_registry( HKEY hBaseKey, DWORD * result ) { return get_DWORD_from_registry(hBaseKey, LEASH_REGISTRY_KEY_NAME, LEASH_REGISTRY_VALUE_RENEW_MAX, result); } DWORD Leash_reset_default_renew_max( ) { HKEY hKey; LONG rc; rc = RegOpenKeyEx(HKEY_CURRENT_USER, LEASH_REGISTRY_KEY_NAME, 0, KEY_WRITE, &hKey); if (rc) return rc; rc = RegDeleteValue(hKey, LEASH_REGISTRY_VALUE_RENEW_MAX); RegCloseKey(hKey); return rc; } DWORD Leash_set_default_renew_max( DWORD minutes ) { HKEY hKey; LONG rc; rc = RegCreateKeyEx(HKEY_CURRENT_USER, LEASH_REGISTRY_KEY_NAME, 0, 0, 0, KEY_WRITE, 0, &hKey, 0); if (rc) return rc; rc = RegSetValueEx(hKey, LEASH_REGISTRY_VALUE_RENEW_MAX, 0, REG_DWORD, (LPBYTE) &minutes, sizeof(DWORD)); RegCloseKey(hKey); return rc; } DWORD Leash_get_default_renew_max( ) { HMODULE hmLeash; DWORD result; if (get_default_renew_max_from_registry(HKEY_CURRENT_USER, &result) || get_default_renew_max_from_registry(HKEY_LOCAL_MACHINE, &result)) { return result; } hmLeash = GetModuleHandle(LEASH_DLL); if (hmLeash) { char use_krb4[80]; if (LoadString(hmLeash, LSH_DEFAULT_DIALOG_RENEW_MAX, use_krb4, sizeof(use_krb4))) { use_krb4[sizeof(use_krb4) - 1] = 0; return atoi(use_krb4); } } return 60 * 24 * 30; } static BOOL get_lock_file_locations_from_registry( HKEY hBaseKey, DWORD * result ) { return get_DWORD_from_registry(hBaseKey, LEASH_REGISTRY_KEY_NAME, LEASH_REGISTRY_VALUE_LOCK_LOCATION, result); } DWORD Leash_reset_lock_file_locations( ) { HKEY hKey; LONG rc; rc = RegOpenKeyEx(HKEY_CURRENT_USER, LEASH_REGISTRY_KEY_NAME, 0, KEY_WRITE, &hKey); if (rc) return rc; rc = RegDeleteValue(hKey, LEASH_REGISTRY_VALUE_LOCK_LOCATION); RegCloseKey(hKey); return rc; } DWORD Leash_set_lock_file_locations( DWORD onoff ) { HKEY hKey; LONG rc; rc = RegCreateKeyEx(HKEY_CURRENT_USER, LEASH_REGISTRY_KEY_NAME, 0, 0, 0, KEY_WRITE, 0, &hKey, 0); if (rc) return rc; rc = RegSetValueEx(hKey, LEASH_REGISTRY_VALUE_LOCK_LOCATION, 0, REG_DWORD, (LPBYTE) &onoff, sizeof(DWORD)); RegCloseKey(hKey); return rc; } DWORD Leash_get_lock_file_locations( ) { HMODULE hmLeash; DWORD result; if (get_lock_file_locations_from_registry(HKEY_CURRENT_USER, &result) || get_lock_file_locations_from_registry(HKEY_LOCAL_MACHINE, &result)) { return result; } hmLeash = GetModuleHandle(LEASH_DLL); if (hmLeash) { char lock_file_locations[80]; if (LoadString(hmLeash, LSH_DEFAULT_DIALOG_LOCK_LOCATION, lock_file_locations, sizeof(lock_file_locations))) { lock_file_locations[sizeof(lock_file_locations) - 1] = 0; return atoi(lock_file_locations); } } return 0; } static BOOL get_default_uppercaserealm_from_registry( HKEY hBaseKey, DWORD * result ) { return get_DWORD_from_registry(hBaseKey, LEASH_SETTINGS_REGISTRY_KEY_NAME, LEASH_SETTINGS_REGISTRY_VALUE_UPPERCASEREALM, result); } DWORD Leash_reset_default_uppercaserealm( ) { HKEY hKey; LONG rc; rc = RegOpenKeyEx(HKEY_CURRENT_USER, LEASH_SETTINGS_REGISTRY_KEY_NAME, 0, KEY_WRITE, &hKey); if (rc) return rc; rc = RegDeleteValue(hKey, LEASH_SETTINGS_REGISTRY_VALUE_UPPERCASEREALM); RegCloseKey(hKey); return rc; } DWORD Leash_set_default_uppercaserealm( DWORD onoff ) { HKEY hKey; LONG rc; rc = RegCreateKeyEx(HKEY_CURRENT_USER, LEASH_SETTINGS_REGISTRY_KEY_NAME, 0, 0, 0, KEY_WRITE, 0, &hKey, 0); if (rc) return rc; rc = RegSetValueEx(hKey, LEASH_SETTINGS_REGISTRY_VALUE_UPPERCASEREALM, 0, REG_DWORD, (LPBYTE) &onoff, sizeof(DWORD)); RegCloseKey(hKey); return rc; } DWORD Leash_get_default_uppercaserealm( ) { HMODULE hmLeash; DWORD result; if (get_default_uppercaserealm_from_registry(HKEY_CURRENT_USER, &result) || get_default_uppercaserealm_from_registry(HKEY_LOCAL_MACHINE, &result)) { return result; } hmLeash = GetModuleHandle(LEASH_DLL); if (hmLeash) { char uppercaserealm[80]; if (LoadString(hmLeash, LSH_DEFAULT_UPPERCASEREALM, uppercaserealm, sizeof(uppercaserealm))) { uppercaserealm[sizeof(uppercaserealm) - 1] = 0; return atoi(uppercaserealm); } } return 1; } static BOOL get_default_mslsa_import_from_registry( HKEY hBaseKey, DWORD * result ) { return get_DWORD_from_registry(hBaseKey, LEASH_SETTINGS_REGISTRY_KEY_NAME, LEASH_SETTINGS_REGISTRY_VALUE_MSLSA_IMPORT, result); } DWORD Leash_reset_default_mslsa_import( ) { HKEY hKey; LONG rc; rc = RegOpenKeyEx(HKEY_CURRENT_USER, LEASH_SETTINGS_REGISTRY_KEY_NAME, 0, KEY_WRITE, &hKey); if (rc) return rc; rc = RegDeleteValue(hKey, LEASH_SETTINGS_REGISTRY_VALUE_MSLSA_IMPORT); RegCloseKey(hKey); return rc; } DWORD Leash_set_default_mslsa_import( DWORD onoffmatch ) { HKEY hKey; LONG rc; rc = RegCreateKeyEx(HKEY_CURRENT_USER, LEASH_SETTINGS_REGISTRY_KEY_NAME, 0, 0, 0, KEY_WRITE, 0, &hKey, 0); if (rc) return rc; rc = RegSetValueEx(hKey, LEASH_SETTINGS_REGISTRY_VALUE_MSLSA_IMPORT, 0, REG_DWORD, (LPBYTE) &onoffmatch, sizeof(DWORD)); RegCloseKey(hKey); return rc; } DWORD Leash_get_default_mslsa_import( ) { HMODULE hmLeash; DWORD result; if (get_default_mslsa_import_from_registry(HKEY_CURRENT_USER, &result) || get_default_mslsa_import_from_registry(HKEY_LOCAL_MACHINE, &result)) { return result; } hmLeash = GetModuleHandle(LEASH_DLL); if (hmLeash) { char mslsa_import[80]; if (LoadString(hmLeash, LSH_DEFAULT_MSLSA_IMPORT, mslsa_import, sizeof(mslsa_import))) { mslsa_import[sizeof(mslsa_import) - 1] = 0; return atoi(mslsa_import); } } return 2; /* import only when mslsa realm matches default */ } static BOOL get_default_preserve_kinit_settings_from_registry( HKEY hBaseKey, DWORD * result ) { return get_DWORD_from_registry(hBaseKey, LEASH_REGISTRY_KEY_NAME, LEASH_REGISTRY_VALUE_PRESERVE_KINIT, result); } DWORD Leash_reset_default_preserve_kinit_settings( ) { HKEY hKey; LONG rc; rc = RegOpenKeyEx(HKEY_CURRENT_USER, LEASH_REGISTRY_KEY_NAME, 0, KEY_WRITE, &hKey); if (rc) return rc; rc = RegDeleteValue(hKey, LEASH_REGISTRY_VALUE_PRESERVE_KINIT); RegCloseKey(hKey); return rc; } DWORD Leash_set_default_preserve_kinit_settings( DWORD onoff ) { HKEY hKey; LONG rc; rc = RegCreateKeyEx(HKEY_CURRENT_USER, LEASH_REGISTRY_KEY_NAME, 0, 0, 0, KEY_WRITE, 0, &hKey, 0); if (rc) return rc; rc = RegSetValueEx(hKey, LEASH_REGISTRY_VALUE_PRESERVE_KINIT, 0, REG_DWORD, (LPBYTE) &onoff, sizeof(DWORD)); RegCloseKey(hKey); return rc; } DWORD Leash_get_default_preserve_kinit_settings( ) { HMODULE hmLeash; DWORD result; if (get_default_preserve_kinit_settings_from_registry(HKEY_CURRENT_USER, &result) || get_default_preserve_kinit_settings_from_registry(HKEY_LOCAL_MACHINE, &result)) { return result; } hmLeash = GetModuleHandle(LEASH_DLL); if (hmLeash) { char preserve_kinit_settings[80]; if (LoadString(hmLeash, LSH_DEFAULT_PRESERVE_KINIT, preserve_kinit_settings, sizeof(preserve_kinit_settings))) { preserve_kinit_settings[sizeof(preserve_kinit_settings) - 1] = 0; return atoi(preserve_kinit_settings); } } return 1; } void Leash_reset_defaults(void) { Leash_reset_default_lifetime(); Leash_reset_default_renew_till(); Leash_reset_default_renewable(); Leash_reset_default_forwardable(); Leash_reset_default_noaddresses(); Leash_reset_default_proxiable(); Leash_reset_default_publicip(); Leash_reset_default_use_krb4(); Leash_reset_hide_kinit_options(); Leash_reset_default_life_min(); Leash_reset_default_life_max(); Leash_reset_default_renew_min(); Leash_reset_default_renew_max(); Leash_reset_default_uppercaserealm(); Leash_reset_default_mslsa_import(); Leash_reset_default_preserve_kinit_settings(); } static void acquire_tkt_send_msg_leash(const char *title, const char *ccachename, const char *name, const char *realm) { DWORD leashProcessId = 0; DWORD bufsize = 4096; DWORD step; HANDLE hLeashProcess = NULL; HANDLE hMapFile = NULL; HANDLE hTarget = NULL; HWND hLeashWnd = FindWindow("LEASH.0WNDCLASS", NULL); char *strs; void *view; if (!hLeashWnd) // no leash window return; GetWindowThreadProcessId(hLeashWnd, &leashProcessId); hLeashProcess = OpenProcess(PROCESS_DUP_HANDLE, FALSE, leashProcessId); if (!hLeashProcess) // can't get process handle; use GetLastError() for more info return; hMapFile = CreateFileMapping(INVALID_HANDLE_VALUE, // use paging file NULL, // default security PAGE_READWRITE, // read/write access 0, // max size (high 32) bufsize, // max size (low 32) NULL); // name if (!hMapFile) { // GetLastError() for more info CloseHandle(hLeashProcess); return; } SetForegroundWindow(hLeashWnd); view = MapViewOfFile(hMapFile, FILE_MAP_ALL_ACCESS, 0, 0, bufsize); if (view != NULL) { /* construct a marshalling of data * <principal><realm><ccache> * then send to Leash */ strs = (char *)view; // first reserve space for three more NULLs (4 strings total) bufsize -= 3; // Dialog title if (title != NULL) strcpy_s(strs, bufsize, title); else if (name != NULL && realm != NULL) sprintf_s(strs, bufsize, "MIT Kerberos: Get Ticket for %s@%s", name, realm); else strcpy_s(strs, bufsize, "MIT Kerberos: Get Ticket"); step = strlen(strs); strs += step + 1; bufsize -= step; // name and realm if (name != NULL) { strcpy_s(strs, bufsize, name); step = strlen(strs); strs += step + 1; bufsize -= step; if (realm != NULL) { strcpy_s(strs, bufsize, realm); step = strlen(strs); strs += step + 1; bufsize -= step; } else { *strs = 0; strs++; } } else { *strs = 0; strs++; *strs = 0; strs++; } /* Append the ccache name */ if (ccachename != NULL) strcpy_s(strs, bufsize, ccachename); else *strs = 0; UnmapViewOfFile(view); } // Duplicate the file mapping handle to one leash can use if (DuplicateHandle(GetCurrentProcess(), hMapFile, hLeashProcess, &hTarget, PAGE_READWRITE, FALSE, DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE)) { /* 32809 = ID_OBTAIN_TGT_WITH_LPARAM in src/windows/leash/resource.h */ SendMessage(hLeashWnd, 32809, 0, (LPARAM) hTarget); } else { // GetLastError() } } static int acquire_tkt_send_msg(krb5_context ctx, const char * title, const char * ccachename, krb5_principal desiredKrb5Principal, char * out_ccname, int out_cclen) { krb5_error_code err; HWND hNetIdMgr; HWND hForeground; char *desiredName = 0; char *desiredRealm = 0; /* do we want a specific client principal? */ if (desiredKrb5Principal != NULL) { err = pkrb5_unparse_name (ctx, desiredKrb5Principal, &desiredName); if (!err) { char * p; for (p = desiredName; *p && *p != '@'; p++); if ( *p == '@' ) { *p = '\0'; desiredRealm = ++p; } } } hForeground = GetForegroundWindow(); hNetIdMgr = FindWindow("IDMgrRequestDaemonCls", "IDMgrRequestDaemon"); if (hNetIdMgr != NULL) { HANDLE hMap; DWORD tid = GetCurrentThreadId(); char mapname[256]; NETID_DLGINFO *dlginfo; sprintf(mapname,"Local\\NetIDMgr_DlgInfo_%lu",tid); hMap = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, 4096, mapname); if (hMap == NULL) { return -1; } else if (hMap != NULL && GetLastError() == ERROR_ALREADY_EXISTS) { CloseHandle(hMap); return -1; } dlginfo = (NETID_DLGINFO *)MapViewOfFileEx(hMap, FILE_MAP_READ|FILE_MAP_WRITE, 0, 0, 4096, NULL); if (dlginfo == NULL) { CloseHandle(hMap); return -1; } memset(dlginfo, 0, sizeof(NETID_DLGINFO)); dlginfo->size = sizeof(NETID_DLGINFO); dlginfo->dlgtype = NETID_DLGTYPE_TGT; dlginfo->in.use_defaults = 1; if (title) { MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED|MB_ERR_INVALID_CHARS, title, -1, dlginfo->in.title, NETID_TITLE_SZ); } else if (desiredName && (strlen(desiredName) + strlen(desiredRealm) + 32 < NETID_TITLE_SZ)) { char mytitle[NETID_TITLE_SZ]; sprintf(mytitle, "Obtain Kerberos TGT for %s@%s",desiredName,desiredRealm); MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED|MB_ERR_INVALID_CHARS, mytitle, -1, dlginfo->in.title, NETID_TITLE_SZ); } else { MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED|MB_ERR_INVALID_CHARS, "Obtain Kerberos TGT", -1, dlginfo->in.title, NETID_TITLE_SZ); } if (desiredName) MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED|MB_ERR_INVALID_CHARS, desiredName, -1, dlginfo->in.username, NETID_USERNAME_SZ); if (desiredRealm) MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED|MB_ERR_INVALID_CHARS, desiredRealm, -1, dlginfo->in.realm, NETID_REALM_SZ); if (ccachename) MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED|MB_ERR_INVALID_CHARS, ccachename, -1, dlginfo->in.ccache, NETID_CCACHE_NAME_SZ); SendMessage(hNetIdMgr, 32810, 0, (LPARAM) tid); if (out_ccname && out_cclen > 0) { WideCharToMultiByte(CP_ACP, WC_COMPOSITECHECK, dlginfo->out.ccache, -1, out_ccname, out_cclen, NULL, NULL); } UnmapViewOfFile(dlginfo); CloseHandle(hMap); } else { acquire_tkt_send_msg_leash(title, ccachename, desiredName, desiredRealm); } SetForegroundWindow(hForeground); if (desiredName != NULL) pkrb5_free_unparsed_name(ctx, desiredName); return 0; } static BOOL cc_have_tickets(krb5_context ctx, krb5_ccache cache) { krb5_cc_cursor cur = NULL; krb5_creds creds; krb5_flags flags; krb5_error_code code; BOOL have_tickets = FALSE; // Don't need the actual ticket. flags = KRB5_TC_NOTICKET; code = pkrb5_cc_set_flags(ctx, cache, flags); if (code) goto cleanup; code = pkrb5_cc_start_seq_get(ctx, cache, &cur); if (code) goto cleanup; _tzset(); while (!(code = pkrb5_cc_next_cred(ctx, cache, &cur, &creds))) { if ((!pkrb5_is_config_principal(ctx, creds.server)) && ((time_t)(DWORD)creds.times.endtime - time(0) > 0)) have_tickets = TRUE; pkrb5_free_cred_contents(ctx, &creds); } if (code == KRB5_CC_END) { code = pkrb5_cc_end_seq_get(ctx, cache, &cur); if (code) goto cleanup; flags = 0; code = pkrb5_cc_set_flags(ctx, cache, flags); if (code) goto cleanup; } cleanup: return have_tickets; } static BOOL cc_have_tickets_for_princ(krb5_context ctx, krb5_ccache cache, krb5_principal princ) { krb5_error_code code; krb5_principal cc_princ = NULL; BOOL have_tickets = FALSE; code = pkrb5_cc_get_principal(ctx, cache, &cc_princ); if (code) goto cleanup; if (pkrb5_principal_compare(ctx, princ, cc_princ)) have_tickets = cc_have_tickets(ctx, cache); cleanup: if (cc_princ != NULL) pkrb5_free_principal(ctx, cc_princ); return have_tickets; } static BOOL cc_default_have_tickets(krb5_context ctx) { krb5_ccache cache = NULL; BOOL have_tickets = FALSE; if (pkrb5_cc_default(ctx, &cache) == 0) have_tickets = cc_have_tickets(ctx, cache); if (cache != NULL) pkrb5_cc_close(ctx, cache); return have_tickets; } static BOOL cccol_have_tickets_for_princ(krb5_context ctx, krb5_principal princ, char *ccname, int cclen) { krb5_error_code code; krb5_ccache cache; krb5_cccol_cursor cursor; BOOL have_tickets = FALSE; char *ccfullname; code = pkrb5_cccol_cursor_new(ctx, &cursor); if (code) goto cleanup; while (!have_tickets && !(code = pkrb5_cccol_cursor_next(ctx, cursor, &cache)) && cache != NULL) { if (cc_have_tickets_for_princ(ctx, cache, princ)) { if (pkrb5_cc_get_full_name(ctx, cache, &ccfullname)==0) { strcpy_s(ccname, cclen, ccfullname); pkrb5_free_string(ctx, ccfullname); have_tickets = TRUE; } } pkrb5_cc_close(ctx, cache); } pkrb5_cccol_cursor_free(ctx, &cursor); cleanup: return have_tickets; } static void acquire_tkt_no_princ(krb5_context context, char * ccname, int cclen) { TicketList *list = NULL; krb5_context ctx; DWORD dwMsLsaImport = Leash_get_default_mslsa_import(); DWORD gle; char ccachename[272]=""; char loginenv[16]; BOOL prompt; BOOL haveTickets; GetEnvironmentVariable("KERBEROSLOGIN_NEVER_PROMPT", loginenv, sizeof(loginenv)); prompt = (GetLastError() == ERROR_ENVVAR_NOT_FOUND); ctx = context; SetLastError(0); GetEnvironmentVariable("KRB5CCNAME", ccachename, sizeof(ccachename)); gle = GetLastError(); if ( ((gle == ERROR_ENVVAR_NOT_FOUND) || !ccachename[0]) && context ) { const char * ccdef = pkrb5_cc_default_name(ctx); SetEnvironmentVariable("KRB5CCNAME", ccdef ? ccdef : NULL); GetEnvironmentVariable("KRB5CCNAME", ccachename, sizeof(ccachename)); } haveTickets = cc_default_have_tickets(ctx); if ((!haveTickets) && dwMsLsaImport && Leash_importable() ) { // We have the option of importing tickets from the MSLSA // but should we? Do the tickets in the MSLSA cache belong // to the default realm used by Leash? Does the default // ccache name specify a principal name? Only import if we // aren't going to break the default identity as specified // by the user in Network Identity Manager. int import = 0; BOOL isCCPrinc; /* Determine if the default ccachename is principal name. If so, don't * import the MSLSA: credentials into it unless the names match. */ isCCPrinc = (strncmp("API:",ccachename, 4) == 0 && strchr(ccachename, '@')); if ( dwMsLsaImport == 1 && !isCCPrinc ) { /* always import */ import = 1; } else if ( dwMsLsaImport ) { /* import when realms match */ krb5_error_code code; krb5_ccache mslsa_ccache=NULL; krb5_principal princ = NULL; char *mslsa_principal = NULL; char ms_realm[128] = "", *def_realm = NULL, *r; size_t i; if (code = pkrb5_cc_resolve(ctx, "MSLSA:", &mslsa_ccache)) goto cleanup; if (code = pkrb5_cc_get_principal(ctx, mslsa_ccache, &princ)) goto cleanup; for ( r=ms_realm, i=0; i<krb5_princ_realm(ctx, princ)->length; r++, i++ ) { *r = krb5_princ_realm(ctx, princ)->data[i]; } *r = '\0'; if (code = pkrb5_get_default_realm(ctx, &def_realm)) goto cleanup; if (code = pkrb5_unparse_name(ctx, princ, &mslsa_principal)) goto cleanup; import = (!isCCPrinc && !strcmp(def_realm, ms_realm)) || (isCCPrinc && !strcmp(&ccachename[4], mslsa_principal)); cleanup: if (mslsa_principal) pkrb5_free_unparsed_name(ctx, mslsa_principal); if (def_realm) pkrb5_free_default_realm(ctx, def_realm); if (princ) pkrb5_free_principal(ctx, princ); if (mslsa_ccache) pkrb5_cc_close(ctx, mslsa_ccache); } if ( import ) { Leash_import(); haveTickets = cc_default_have_tickets(ctx); } } if ( prompt && !haveTickets ) { acquire_tkt_send_msg(ctx, NULL, ccachename, NULL, ccname, cclen); /* * If the ticket manager returned an alternative credential cache * remember it as the default for this process. */ if ( ccname && ccname[0] && strcmp(ccachename,ccname) ) { SetEnvironmentVariable("KRB5CCNAME",ccname); } } else if (ccachename[0] && ccname) { strncpy(ccname, ccachename, cclen); ccname[cclen-1] = '\0'; } if ( !context ) pkrb5_free_context(ctx); } static void acquire_tkt_for_princ(krb5_context ctx, krb5_principal desiredPrincipal, char * ccname, int cclen) { DWORD gle; char ccachename[272]=""; char loginenv[16]; BOOL prompt; GetEnvironmentVariable("KERBEROSLOGIN_NEVER_PROMPT", loginenv, sizeof(loginenv)); prompt = (GetLastError() == ERROR_ENVVAR_NOT_FOUND); SetLastError(0); GetEnvironmentVariable("KRB5CCNAME", ccachename, sizeof(ccachename)); gle = GetLastError(); if ((gle == ERROR_ENVVAR_NOT_FOUND || !ccachename[0]) && ctx != NULL) { const char * ccdef = pkrb5_cc_default_name(ctx); SetEnvironmentVariable("KRB5CCNAME", ccdef ? ccdef : NULL); GetEnvironmentVariable("KRB5CCNAME", ccachename, sizeof(ccachename)); } if (!cccol_have_tickets_for_princ(ctx, desiredPrincipal, ccname, cclen)) { if (prompt) { acquire_tkt_send_msg(ctx, NULL, ccachename, desiredPrincipal, ccname, cclen); /* * If the ticket manager returned an alternative credential cache * remember it as the default for this process. */ if (ccname != NULL && ccname[0] && strcmp(ccachename, ccname)) { SetEnvironmentVariable("KRB5CCNAME",ccname); } } } } void FAR not_an_API_Leash_AcquireInitialTicketsIfNeeded(krb5_context context, krb5_principal desiredKrb5Principal, char * ccname, int cclen) { if (!desiredKrb5Principal) { acquire_tkt_no_princ(context, ccname, cclen); } else { acquire_tkt_for_princ(context, desiredKrb5Principal, ccname, cclen); } return; } ���������������������������������������������������������������������������������������������������������������������������krb5-1.16/src/windows/leashdll/leashw32.def���������������������������������������������������������0000644�0007046�0000145�00000005664�13211554426�020372� 0����������������������������������������������������������������������������������������������������ustar �ghudson�������������������������libuuid����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������LIBRARY LEASHW32 DESCRIPTION 'DLL for Kerberos ticket initialization' HEAPSIZE 8092 STACKSIZE 36864 EXPORTS ; DllMain @1 ; Leash_kinit_dlg @3 ; Leash_changepwd_dlg @4 ; Leash_kinit @48 ; Leash_kdestroy @49 ; Leash_klist @50 ; Leash_checkpwd @51 ; Leash_changepwd @52 ; Leash_get_lsh_errno @61 ; initialize_lsh_error_table @80 ; lsh_com_err_proc @81 ; Leash_initialize_krb_error_func @82 ; Leash_initialize_kadm_error_table @83 ; Leash_krb_err_func @84 ; Leash_load_com_err_callback @85 ; Leash_set_help_file @86 ; Leash_get_help_file @87 ; Leash_timesync @88 ; Leash_WhichOS @89 Leash_kinit_dlg Leash_kinit_dlg_ex Leash_changepwd_dlg Leash_changepwd_dlg_ex Leash_kinit Leash_kinit_ex Leash_kdestroy Leash_klist Leash_checkpwd Leash_changepwd Leash_get_lsh_errno initialize_lsh_error_table lsh_com_err_proc Leash_initialize_krb_error_func Leash_initialize_kadm_error_table Leash_krb_err_func Leash_load_com_err_callback Leash_set_help_file Leash_get_help_file Leash_timesync Leash_get_default_lifetime Leash_set_default_lifetime Leash_reset_default_lifetime Leash_get_default_renew_till Leash_set_default_renew_till Leash_reset_default_renew_till Leash_get_default_forwardable Leash_set_default_forwardable Leash_reset_default_forwardable Leash_get_default_renewable Leash_set_default_renewable Leash_reset_default_renewable Leash_get_default_noaddresses Leash_set_default_noaddresses Leash_reset_default_noaddresses Leash_get_default_proxiable Leash_set_default_proxiable Leash_reset_default_proxiable Leash_get_default_publicip Leash_set_default_publicip Leash_reset_default_publicip Leash_get_default_use_krb4 Leash_set_default_use_krb4 Leash_reset_default_use_krb4 Leash_get_default_life_min Leash_set_default_life_min Leash_reset_default_life_min Leash_get_default_life_max Leash_set_default_life_max Leash_reset_default_life_max Leash_get_default_renew_min Leash_set_default_renew_min Leash_reset_default_renew_min Leash_get_default_renew_max Leash_set_default_renew_max Leash_reset_default_renew_max Leash_get_lock_file_locations Leash_set_lock_file_locations Leash_reset_lock_file_locations Leash_get_default_uppercaserealm Leash_set_default_uppercaserealm Leash_reset_default_uppercaserealm Leash_get_default_mslsa_import Leash_set_default_mslsa_import Leash_reset_default_mslsa_import Leash_get_default_preserve_kinit_settings Leash_set_default_preserve_kinit_settings Leash_reset_default_preserve_kinit_settings Leash_import Leash_importable Leash_renew Leash_reset_defaults ; XXX - These have to go... not_an_API_LeashAFSGetToken not_an_API_LeashFreeTicketList not_an_API_LeashKRB4GetTickets not_an_API_LeashGetTimeServerName not_an_API_Leash_AcquireInitialTicketsIfNeeded ����������������������������������������������������������������������������krb5-1.16/src/windows/leashdll/leashdll.c�����������������������������������������������������������0000644�0007046�0000145�00000027060�13211554426�020210� 0����������������������������������������������������������������������������������������������������ustar �ghudson�������������������������libuuid����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#include <windows.h> #include "leashdll.h" #include <leashwin.h> #include "leash-int.h" HINSTANCE hLeashInst; #ifndef NO_KRB4 HINSTANCE hKrb4 = 0; #endif HINSTANCE hKrb5 = 0; HINSTANCE hKrb524 = 0; HINSTANCE hSecur32 = 0; HINSTANCE hComErr = 0; HINSTANCE hService = 0; HINSTANCE hProfile = 0; HINSTANCE hPsapi = 0; HINSTANCE hToolHelp32 = 0; HINSTANCE hCcapi = 0; DWORD AfsAvailable = 0; // krb5 functions DECL_FUNC_PTR(krb5_change_password); DECL_FUNC_PTR(krb5_get_init_creds_opt_alloc); DECL_FUNC_PTR(krb5_get_init_creds_opt_free); DECL_FUNC_PTR(krb5_get_init_creds_opt_init); DECL_FUNC_PTR(krb5_get_init_creds_opt_set_tkt_life); DECL_FUNC_PTR(krb5_get_init_creds_opt_set_renew_life); DECL_FUNC_PTR(krb5_get_init_creds_opt_set_forwardable); DECL_FUNC_PTR(krb5_get_init_creds_opt_set_proxiable); DECL_FUNC_PTR(krb5_get_init_creds_opt_set_address_list); DECL_FUNC_PTR(krb5_get_init_creds_opt_set_out_ccache); DECL_FUNC_PTR(krb5_get_init_creds_password); DECL_FUNC_PTR(krb5_build_principal_ext); DECL_FUNC_PTR(krb5_cc_get_name); DECL_FUNC_PTR(krb5_cc_resolve); DECL_FUNC_PTR(krb5_cc_default); DECL_FUNC_PTR(krb5_cc_default_name); DECL_FUNC_PTR(krb5_cc_set_default_name); DECL_FUNC_PTR(krb5_cc_initialize); DECL_FUNC_PTR(krb5_cc_destroy); DECL_FUNC_PTR(krb5_cc_close); DECL_FUNC_PTR(krb5_cc_store_cred); DECL_FUNC_PTR(krb5_cc_copy_creds); // DECL_FUNC_PTR(krb5_cc_retrieve_cred); DECL_FUNC_PTR(krb5_cc_get_principal); DECL_FUNC_PTR(krb5_cc_start_seq_get); DECL_FUNC_PTR(krb5_cc_next_cred); DECL_FUNC_PTR(krb5_cc_end_seq_get); // DECL_FUNC_PTR(krb5_cc_remove_cred); DECL_FUNC_PTR(krb5_cc_set_flags); // DECL_FUNC_PTR(krb5_cc_get_type); DECL_FUNC_PTR(krb5_free_context); DECL_FUNC_PTR(krb5_free_cred_contents); DECL_FUNC_PTR(krb5_free_principal); DECL_FUNC_PTR(krb5_get_in_tkt_with_password); DECL_FUNC_PTR(krb5_init_context); DECL_FUNC_PTR(krb5_parse_name); DECL_FUNC_PTR(krb5_timeofday); DECL_FUNC_PTR(krb5_timestamp_to_sfstring); DECL_FUNC_PTR(krb5_unparse_name); DECL_FUNC_PTR(krb5_get_credentials); DECL_FUNC_PTR(krb5_mk_req); DECL_FUNC_PTR(krb5_sname_to_principal); DECL_FUNC_PTR(krb5_get_credentials_renew); DECL_FUNC_PTR(krb5_free_data); DECL_FUNC_PTR(krb5_free_data_contents); // DECL_FUNC_PTR(krb5_get_realm_domain); DECL_FUNC_PTR(krb5_free_unparsed_name); DECL_FUNC_PTR(krb5_os_localaddr); DECL_FUNC_PTR(krb5_copy_keyblock_contents); DECL_FUNC_PTR(krb5_copy_data); DECL_FUNC_PTR(krb5_free_creds); DECL_FUNC_PTR(krb5_build_principal); DECL_FUNC_PTR(krb5_get_renewed_creds); DECL_FUNC_PTR(krb5_get_default_config_files); DECL_FUNC_PTR(krb5_free_config_files); DECL_FUNC_PTR(krb5_get_default_realm); DECL_FUNC_PTR(krb5_free_ticket); DECL_FUNC_PTR(krb5_decode_ticket); DECL_FUNC_PTR(krb5_get_host_realm); DECL_FUNC_PTR(krb5_free_host_realm); DECL_FUNC_PTR(krb5_c_random_make_octets); DECL_FUNC_PTR(krb5_free_addresses); DECL_FUNC_PTR(krb5_free_default_realm); DECL_FUNC_PTR(krb5_principal_compare); DECL_FUNC_PTR(krb5_string_to_deltat); DECL_FUNC_PTR(krb5_is_config_principal); DECL_FUNC_PTR(krb5_cccol_cursor_new); DECL_FUNC_PTR(krb5_cccol_cursor_free); DECL_FUNC_PTR(krb5_cccol_cursor_next); DECL_FUNC_PTR(krb5_cc_cache_match); DECL_FUNC_PTR(krb5_cc_get_type); DECL_FUNC_PTR(krb5_cc_new_unique); DECL_FUNC_PTR(krb5_cc_support_switch); DECL_FUNC_PTR(krb5_cc_switch); DECL_FUNC_PTR(krb5_cc_get_full_name); DECL_FUNC_PTR(krb5_free_string); DECL_FUNC_PTR(krb5int_cc_user_set_default_name); // ComErr functions DECL_FUNC_PTR(com_err); DECL_FUNC_PTR(error_message); // Profile functions DECL_FUNC_PTR(profile_init); DECL_FUNC_PTR(profile_release); DECL_FUNC_PTR(profile_get_subsection_names); DECL_FUNC_PTR(profile_free_list); DECL_FUNC_PTR(profile_get_string); DECL_FUNC_PTR(profile_release_string); DECL_FUNC_PTR(profile_get_integer); // Service functions DECL_FUNC_PTR(OpenSCManagerA); DECL_FUNC_PTR(OpenServiceA); DECL_FUNC_PTR(QueryServiceStatus); DECL_FUNC_PTR(CloseServiceHandle); DECL_FUNC_PTR(LsaNtStatusToWinError); // LSA Functions DECL_FUNC_PTR(LsaConnectUntrusted); DECL_FUNC_PTR(LsaLookupAuthenticationPackage); DECL_FUNC_PTR(LsaCallAuthenticationPackage); DECL_FUNC_PTR(LsaFreeReturnBuffer); DECL_FUNC_PTR(LsaGetLogonSessionData); // CCAPI Functions DECL_FUNC_PTR(cc_initialize); DECL_FUNC_PTR(cc_shutdown); DECL_FUNC_PTR(cc_get_NC_info); DECL_FUNC_PTR(cc_free_NC_info); FUNC_INFO k5_fi[] = { MAKE_FUNC_INFO(krb5_change_password), MAKE_FUNC_INFO(krb5_get_init_creds_opt_alloc), MAKE_FUNC_INFO(krb5_get_init_creds_opt_free), MAKE_FUNC_INFO(krb5_get_init_creds_opt_init), MAKE_FUNC_INFO(krb5_get_init_creds_opt_set_tkt_life), MAKE_FUNC_INFO(krb5_get_init_creds_opt_set_renew_life), MAKE_FUNC_INFO(krb5_get_init_creds_opt_set_forwardable), MAKE_FUNC_INFO(krb5_get_init_creds_opt_set_proxiable), MAKE_FUNC_INFO(krb5_get_init_creds_opt_set_address_list), MAKE_FUNC_INFO(krb5_get_init_creds_opt_set_out_ccache), MAKE_FUNC_INFO(krb5_get_init_creds_password), MAKE_FUNC_INFO(krb5_build_principal_ext), MAKE_FUNC_INFO(krb5_cc_get_name), MAKE_FUNC_INFO(krb5_cc_resolve), MAKE_FUNC_INFO(krb5_cc_default), MAKE_FUNC_INFO(krb5_cc_default_name), MAKE_FUNC_INFO(krb5_cc_set_default_name), MAKE_FUNC_INFO(krb5_cc_initialize), MAKE_FUNC_INFO(krb5_cc_destroy), MAKE_FUNC_INFO(krb5_cc_close), MAKE_FUNC_INFO(krb5_cc_copy_creds), MAKE_FUNC_INFO(krb5_cc_store_cred), // MAKE_FUNC_INFO(krb5_cc_retrieve_cred), MAKE_FUNC_INFO(krb5_cc_get_principal), MAKE_FUNC_INFO(krb5_cc_start_seq_get), MAKE_FUNC_INFO(krb5_cc_next_cred), MAKE_FUNC_INFO(krb5_cc_end_seq_get), // MAKE_FUNC_INFO(krb5_cc_remove_cred), MAKE_FUNC_INFO(krb5_cc_set_flags), // MAKE_FUNC_INFO(krb5_cc_get_type), MAKE_FUNC_INFO(krb5_free_context), MAKE_FUNC_INFO(krb5_free_cred_contents), MAKE_FUNC_INFO(krb5_free_principal), MAKE_FUNC_INFO(krb5_get_in_tkt_with_password), MAKE_FUNC_INFO(krb5_init_context), MAKE_FUNC_INFO(krb5_parse_name), MAKE_FUNC_INFO(krb5_timeofday), MAKE_FUNC_INFO(krb5_timestamp_to_sfstring), MAKE_FUNC_INFO(krb5_unparse_name), MAKE_FUNC_INFO(krb5_get_credentials), MAKE_FUNC_INFO(krb5_mk_req), MAKE_FUNC_INFO(krb5_sname_to_principal), MAKE_FUNC_INFO(krb5_get_credentials_renew), MAKE_FUNC_INFO(krb5_free_data), MAKE_FUNC_INFO(krb5_free_data_contents), // MAKE_FUNC_INFO(krb5_get_realm_domain), MAKE_FUNC_INFO(krb5_free_unparsed_name), MAKE_FUNC_INFO(krb5_os_localaddr), MAKE_FUNC_INFO(krb5_copy_keyblock_contents), MAKE_FUNC_INFO(krb5_copy_data), MAKE_FUNC_INFO(krb5_free_creds), MAKE_FUNC_INFO(krb5_build_principal), MAKE_FUNC_INFO(krb5_get_renewed_creds), MAKE_FUNC_INFO(krb5_free_addresses), MAKE_FUNC_INFO(krb5_get_default_config_files), MAKE_FUNC_INFO(krb5_free_config_files), MAKE_FUNC_INFO(krb5_get_default_realm), MAKE_FUNC_INFO(krb5_free_ticket), MAKE_FUNC_INFO(krb5_decode_ticket), MAKE_FUNC_INFO(krb5_get_host_realm), MAKE_FUNC_INFO(krb5_free_host_realm), MAKE_FUNC_INFO(krb5_c_random_make_octets), MAKE_FUNC_INFO(krb5_free_default_realm), MAKE_FUNC_INFO(krb5_principal_compare), MAKE_FUNC_INFO(krb5_string_to_deltat), MAKE_FUNC_INFO(krb5_is_config_principal), MAKE_FUNC_INFO(krb5_cccol_cursor_new), MAKE_FUNC_INFO(krb5_cccol_cursor_next), MAKE_FUNC_INFO(krb5_cccol_cursor_free), MAKE_FUNC_INFO(krb5_cc_cache_match), MAKE_FUNC_INFO(krb5_cc_get_type), MAKE_FUNC_INFO(krb5_cc_new_unique), MAKE_FUNC_INFO(krb5_cc_support_switch), MAKE_FUNC_INFO(krb5_cc_switch), MAKE_FUNC_INFO(krb5_cc_get_full_name), MAKE_FUNC_INFO(krb5_free_string), MAKE_FUNC_INFO(krb5int_cc_user_set_default_name), END_FUNC_INFO }; FUNC_INFO profile_fi[] = { MAKE_FUNC_INFO(profile_init), MAKE_FUNC_INFO(profile_release), MAKE_FUNC_INFO(profile_get_subsection_names), MAKE_FUNC_INFO(profile_free_list), MAKE_FUNC_INFO(profile_get_string), MAKE_FUNC_INFO(profile_release_string), MAKE_FUNC_INFO(profile_get_integer), END_FUNC_INFO }; FUNC_INFO ce_fi[] = { MAKE_FUNC_INFO(com_err), MAKE_FUNC_INFO(error_message), END_FUNC_INFO }; FUNC_INFO service_fi[] = { MAKE_FUNC_INFO(OpenSCManagerA), MAKE_FUNC_INFO(OpenServiceA), MAKE_FUNC_INFO(QueryServiceStatus), MAKE_FUNC_INFO(CloseServiceHandle), MAKE_FUNC_INFO(LsaNtStatusToWinError), END_FUNC_INFO }; FUNC_INFO lsa_fi[] = { MAKE_FUNC_INFO(LsaConnectUntrusted), MAKE_FUNC_INFO(LsaLookupAuthenticationPackage), MAKE_FUNC_INFO(LsaCallAuthenticationPackage), MAKE_FUNC_INFO(LsaFreeReturnBuffer), MAKE_FUNC_INFO(LsaGetLogonSessionData), END_FUNC_INFO }; // CCAPI v2 FUNC_INFO ccapi_fi[] = { MAKE_FUNC_INFO(cc_initialize), MAKE_FUNC_INFO(cc_shutdown), MAKE_FUNC_INFO(cc_get_NC_info), MAKE_FUNC_INFO(cc_free_NC_info), END_FUNC_INFO }; // psapi functions DECL_FUNC_PTR(GetModuleFileNameExA); DECL_FUNC_PTR(EnumProcessModules); FUNC_INFO psapi_fi[] = { MAKE_FUNC_INFO(GetModuleFileNameExA), MAKE_FUNC_INFO(EnumProcessModules), END_FUNC_INFO }; // toolhelp functions DECL_FUNC_PTR(CreateToolhelp32Snapshot); DECL_FUNC_PTR(Module32First); DECL_FUNC_PTR(Module32Next); FUNC_INFO toolhelp_fi[] = { MAKE_FUNC_INFO(CreateToolhelp32Snapshot), MAKE_FUNC_INFO(Module32First), MAKE_FUNC_INFO(Module32Next), END_FUNC_INFO }; BOOL WINAPI DllMain( HANDLE hinstDLL, DWORD fdwReason, LPVOID lpReserved ) { hLeashInst = hinstDLL; switch (fdwReason) { case DLL_PROCESS_ATTACH: { OSVERSIONINFO osvi; LoadFuncs(KRB5_DLL, k5_fi, &hKrb5, 0, 1, 0, 0); LoadFuncs(COMERR_DLL, ce_fi, &hComErr, 0, 0, 1, 0); LoadFuncs(SERVICE_DLL, service_fi, &hService, 0, 1, 0, 0); LoadFuncs(SECUR32_DLL, lsa_fi, &hSecur32, 0, 1, 1, 1); LoadFuncs(PROFILE_DLL, profile_fi, &hProfile, 0, 1, 0, 0); LoadFuncs(CCAPI_DLL, ccapi_fi, &hCcapi, 0, 1, 0, 0); memset(&osvi, 0, sizeof(OSVERSIONINFO)); osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); GetVersionEx(&osvi); // XXX: We should really use feature testing, first // checking for CreateToolhelp32Snapshot. If that's // not around, we try the psapi stuff. // // Only load LSA functions if on NT/2000/XP if(osvi.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS) { // Windows 9x LoadFuncs(TOOLHELPDLL, toolhelp_fi, &hToolHelp32, 0, 1, 0, 0); hPsapi = 0; } else if(osvi.dwPlatformId == VER_PLATFORM_WIN32_NT) { // Windows NT LoadFuncs(PSAPIDLL, psapi_fi, &hPsapi, 0, 1, 0, 0); hToolHelp32 = 0; } /* * Register window class for the MITPasswordControl that * replaces normal edit controls for password input. * zero any fields we don't explicitly set */ hLeashInst = hinstDLL; Register_MITPasswordEditControl(hLeashInst); #ifndef NO_AFS { DWORD AfsStatus = 0; GetAfsStatus(&AfsStatus); AfsAvailable = afscompat_init(); if ( AfsStatus && !AfsAvailable ) SetAfsStatus(0); } #endif return TRUE; } case DLL_PROCESS_DETACH: #ifndef NO_AFS afscompat_close(); #endif if (hKrb5) FreeLibrary(hKrb5); if (hCcapi) FreeLibrary(hCcapi); if (hProfile) FreeLibrary(hProfile); if (hComErr) FreeLibrary(hComErr); if (hService) FreeLibrary(hService); if (hSecur32) FreeLibrary(hSecur32); if (hPsapi) FreeLibrary(hPsapi); if (hToolHelp32) FreeLibrary(hToolHelp32); return TRUE; default: return TRUE; } } ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������krb5-1.16/src/windows/leashdll/timesync.c�����������������������������������������������������������0000644�0007046�0000145�00000017035�13211554426�020254� 0����������������������������������������������������������������������������������������������������ustar �ghudson�������������������������libuuid����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* timesync stuff for leash - 7/28/94 - evanr */ #include <windows.h> #include "leashdll.h" #include <time.h> #include <sys\timeb.h> #include <stdlib.h> #include <string.h> #ifndef NO_KRB4 #include <winkrbid.h> #endif #ifdef WSHELPER #include <wshelper.h> #else #include <winsock2.h> #endif #include <stdio.h> #include "leasherr.h" #include "leashids.h" int ProcessTimeSync(char *, int, char *); #define TM_OFFSET 2208988800 /* timezone.h has a winsock.h conflict */ struct timezone { int tz_minuteswest; int tz_dsttime; }; /************************************/ /* settimeofday(): */ /************************************/ int settimeofday( struct timeval *tv, struct timezone *tz ) { SYSTEMTIME systime; struct tm *newtime; newtime = gmtime((time_t *)&(tv->tv_sec)); systime.wYear = 1900+newtime->tm_year; systime.wMonth = 1+newtime->tm_mon; systime.wDay = newtime->tm_mday; systime.wHour = newtime->tm_hour; systime.wMinute = newtime->tm_min; systime.wSecond = newtime->tm_sec; systime.wMilliseconds = 0; return SetSystemTime(&systime); } /************************************/ /* gettimeofday(): */ /************************************/ int gettimeofday( struct timeval *tv, struct timezone *tz ) { struct _timeb tb; _tzset(); _ftime(&tb); if (tv) { tv->tv_sec = tb.time; tv->tv_usec = tb.millitm * 1000; } if (tz) { tz->tz_minuteswest = tb.timezone; tz->tz_dsttime = tb.dstflag; } return 0; } LONG not_an_API_LeashGetTimeServerName( char *timeServerName, const char *valueName ) { HMODULE hmLeash; char hostname[128]; char value[80]; DWORD dwType; DWORD dwCount; int check = 0; HKEY hKey; HKEY rKey1; HKEY rKey2; LONG lResult; BOOL bEnv; memset(value, '\0', sizeof(value)); memset(hostname, '\0', sizeof(hostname)); GetEnvironmentVariable("TIMEHOST", hostname, sizeof(hostname)); bEnv = (GetLastError() == ERROR_ENVVAR_NOT_FOUND); if (!(bEnv && hostname[0])) { // Check registry for TIMEHOST rKey1 = HKEY_CURRENT_USER; rKey2 = HKEY_LOCAL_MACHINE; for (check = 0; check < 2; check++) { if (ERROR_SUCCESS == RegOpenKeyEx(check == 0 ? rKey1 : rKey2, "Software\\MIT\\Leash32\\Settings", 0, KEY_QUERY_VALUE, &hKey)) { memset(value, '\0', sizeof(value)); lResult = RegQueryValueEx(hKey, (LPTSTR)valueName, NULL, &dwType, NULL, &dwCount); if (lResult == ERROR_SUCCESS) { lResult = RegQueryValueEx(hKey, (LPTSTR)valueName, NULL, &dwType, (LPTSTR)value, &dwCount); if (lResult == ERROR_SUCCESS && *value) { // found strcpy(hostname, value); break; } } } } if (!*hostname) { // Check resource string for TIMEHOST if ((hmLeash = GetModuleHandle(LEASH_DLL)) != NULL) { if (!LoadString(hmLeash, LSH_TIME_HOST, hostname, sizeof(hostname))) memset(hostname, '\0', sizeof(hostname)); } } if (!*hostname) { // OK, _Default_ it will be! :) strcpy(hostname, "time"); } } strcpy(timeServerName, hostname); return 0; } /************************************/ /* Leash_timesync(): */ /************************************/ LONG Leash_timesync(int MessageP) { char tmpstr[2048]; char hostname[128]; int Port; int rc; struct servent *sp; WORD wVersionRequested; WSADATA wsaData; char name[80]; if ((pkrb5_init_context == NULL) #ifndef NO_KRB4 && (ptkt_string == NULL) #endif ) return(0); wVersionRequested = 0x0101; memset(name, '\0', sizeof(name)); memset(hostname, '\0', sizeof(hostname)); memset(tmpstr, '\0', sizeof(tmpstr)); if ((rc = WSAStartup(wVersionRequested, &wsaData))) { wsprintf(tmpstr, "Couldn't initialize WinSock to synchronize time\n\rError Number: %d", rc); WSACleanup(); return(LSH_BADWINSOCK); } sp = getservbyname("time", "udp"); if (sp == 0) Port = htons(IPPORT_TIMESERVER); else Port = sp->s_port; not_an_API_LeashGetTimeServerName(hostname, TIMEHOST); rc = ProcessTimeSync(hostname, Port, tmpstr); #ifdef USE_MESSAGE_BOX if(MessageP != 0) { if (rc && !*tmpstr) { strcpy(tmpstr, "Unable to syncronize time!\n\n"); if (*hostname) { char tmpstr1[2048]; memset(tmpstr1, '\0', sizeof(tmpstr1)); sprintf(tmpstr1, "Unreachable server: %s\n", hostname); strcat(tmpstr, tmpstr1); } } MessageBox(NULL, tmpstr, "Time Server", MB_ICONERROR | MB_OK); } #endif /* USE_MESSAGE_BOX */ WSACleanup(); return(rc); } /************************************/ /* ProcessTimeSync(): */ /************************************/ int ProcessTimeSync(char *hostname, int Port, char *tmpstr) { char buffer[512]; int cc; register long *nettime; register int s; long hosttime; struct hostent *host; struct timeval tv; struct timezone tz; u_long argp; struct sockaddr_in sin; int i; if ((host = gethostbyname(hostname)) == NULL) return(LSH_BADTIMESERV); sin.sin_port = (short)Port; sin.sin_family = host->h_addrtype; memcpy((struct sockaddr *)&sin.sin_addr, host->h_addr, host->h_length); if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { return(LSH_NOSOCKET); } argp = 1; if (ioctlsocket(s, FIONBIO, &argp) != 0) { closesocket(s); return(LSH_NOCONNECT); } if (connect(s, (struct sockaddr *)&sin, sizeof(sin)) < 0) { closesocket(s); return(LSH_NOCONNECT); } send(s, buffer, 40, 0); if (gettimeofday (&tv, &tz) < 0) { closesocket(s); return(LSH_GETTIMEOFDAY); } for (i = 0; i < 4; i++) { if ((cc = recv(s, buffer, 512, 0)) > 0) break; Sleep(500); } if (i == 4) { closesocket(s); return(LSH_RECVTIME); } if (cc != 4) { closesocket(s); return(LSH_RECVBYTES); } nettime = (long *)buffer; hosttime = (long) ntohl (*nettime) - TM_OFFSET; (&tv)->tv_sec = hosttime; if (settimeofday(&tv, &tz) < 0) { closesocket(s); return(LSH_SETTIMEOFDAY); } sprintf(tmpstr, "The time has been syncronized with the server: %s\n\n", hostname); strcat(tmpstr, "To be able to use the Kerberos server, it was necessary to \nset the system time to: ") ; strcat(tmpstr, ctime((time_t *)&hosttime)); strcat(tmpstr, "\n"); closesocket(s); return(0); } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������krb5-1.16/src/windows/leashdll/leashids.h�����������������������������������������������������������0000644�0007046�0000145�00000007045�13211554426�020222� 0����������������������������������������������������������������������������������������������������ustar �ghudson�������������������������libuuid����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// *** Child Windows #define ID_MAINLIST 100 #define ID_COUNTDOWN 101 #define ID_DESTROY 111 #define ID_CHANGEPASSWORD 112 #define ID_INITTICKETS 113 #define ID_SYNCTIME 114 #define ID_UPDATESTATE 120 #define ID_UPDATEDISPLAY 121 #define ID_KRBDLL_DEBUG 122 // *** Menus #define ID_EXIT 200 #define ID_HELP_LEASH 210 #define ID_HELP_KERBEROS 211 #define ID_ABOUT 212 #define ID_CHECKV 299 // *** Password Dialog #define ID_PRINCIPAL 301 #define ID_OLDPASSWORD 302 #define ID_CONFIRMPASSWORD1 303 #define ID_CONFIRMPASSWORD2 304 #define ID_PICFRAME 305 #define ID_PRINCCAPTION 311 #define ID_OLDPCAPTION 312 #define ID_CONFIRMCAPTION1 313 #define ID_CONFIRMCAPTION2 314 #define CAPTION_OFFSET 10 #define ID_DURATION 320 #define ID_RESTART 351 #define ID_CLOSEME 380 // *** About dialog stuff #define ID_LEASH_CPYRT 400 #define ID_LEASH_AUTHOR 401 #define ID_KERB_CPYRT 402 #define ID_KERB_AUTHOR 403 #define ID_LEGALESE 404 #define ID_ASSISTANCE 405 // *** Keyboard accelerator crud #define ID_HELP 1000 #define ID_CONTEXTSENSITIVEHELP 1001 #define ID_ENDCSHELP 1002 #define ID_HELPFIRST 1000 #define ID_HELPLAST 1002 // *** window messages #define WM_STARTUP (WM_USER + 1) #define WM_F1DOWN (WM_USER + 2) #define WM_DOHELP (WM_USER + 3) #define WM_PAINTICON 0x0026 // *** command messages #define ID_NEXTSTATE 10000 #define LSH_TIME_HOST 1970 #define LSH_DEFAULT_TICKET_LIFE 1971 #define LSH_DEFAULT_TICKET_RENEW_TILL 1972 #define LSH_DEFAULT_TICKET_FORWARD 1973 #define LSH_DEFAULT_TICKET_NOADDRESS 1974 #define LSH_DEFAULT_TICKET_PROXIABLE 1975 #define LSH_DEFAULT_TICKET_PUBLICIP 1976 #define LSH_DEFAULT_TICKET_USEKRB4 1977 #define LSH_DEFAULT_DIALOG_KINIT_OPT 1978 #define LSH_DEFAULT_DIALOG_LIFE_MIN 1979 #define LSH_DEFAULT_DIALOG_LIFE_MAX 1980 #define LSH_DEFAULT_DIALOG_RENEW_MIN 1981 #define LSH_DEFAULT_DIALOG_RENEW_MAX 1982 #define LSH_DEFAULT_TICKET_RENEW 1983 #define LSH_DEFAULT_DIALOG_LOCK_LOCATION 1984 #define LSH_DEFAULT_UPPERCASEREALM 1985 #define LSH_DEFAULT_MSLSA_IMPORT 1986 #define LSH_DEFAULT_PRESERVE_KINIT 1987 // Authenticate Dialog #define IDD_AUTHENTICATE 1162 #define IDC_STATIC_IPADDR 1163 #define IDC_STATIC_NAME 1164 #define IDC_STATIC_PWD 1165 #define IDC_EDIT_PRINCIPAL 1166 #define IDC_COMBO_REALM 1167 #define IDC_EDIT_PASSWORD 1168 #define IDC_STATIC_LIFETIME 1169 #define IDC_SLIDER_LIFETIME 1170 #define IDC_STATIC_KRB5 1171 #define IDC_CHECK_FORWARDABLE 1172 #define IDC_CHECK_NOADDRESS 1173 #define IDC_CHECK_RENEWABLE 1174 #define IDC_SLIDER_RENEWLIFE 1175 #define IDC_STATIC_LIFETIME_VALUE 1176 #define IDC_STATIC_RENEW_TILL_VALUE 1177 #define IDC_PICTURE_LEASH 1179 #define IDC_BUTTON_OPTIONS 1086 #define IDC_STATIC_REALM 1087 #define IDC_STATIC_COPYRIGHT 1088 #define IDC_STATIC_NOTICE 1089 #define IDC_STATIC_RENEW 1090 #define IDD_PASSWORD 1091 #define IDC_BUTTON_CLEAR_HISTORY 1092 #define IDC_CHECK_REMEMBER_PRINCIPAL 1093 #define IDC_EDIT_PASSWORD2 1192 #define IDC_STATIC_PWD2 1193 #define IDC_EDIT_PASSWORD3 1194 #define IDC_STATIC_PWD3 1195 #define IDC_STATIC_VERSION 1196 �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������krb5-1.16/src/windows/leashdll/include/�������������������������������������������������������������0000755�0007046�0000145�00000000000�13211554426�017672� 5����������������������������������������������������������������������������������������������������ustar �ghudson�������������������������libuuid����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������krb5-1.16/src/windows/leashdll/include/krb4/��������������������������������������������������������0000755�0007046�0000145�00000000000�13211554426�020534� 5����������������������������������������������������������������������������������������������������ustar �ghudson�������������������������libuuid����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������krb5-1.16/src/windows/leashdll/include/krb4/conf-pc.h�����������������������������������������������0000644�0007046�0000145�00000003774�13211554426�022245� 0����������������������������������������������������������������������������������������������������ustar �ghudson�������������������������libuuid����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 1988 by the Massachusetts Institute of Technology. * * For copying and distribution information, please see the file * <mit-copyright.h>. * * Machine-type definitions: IBM PC 8086 */ #if defined(_WIN32) && !defined(WIN32) #define WIN32 #endif #if ( defined(WIN16) || defined(WIN32) || defined(_WINDOWS)) && !defined(WINDOWS) #define WINDOWS #endif #if defined(__OS2__) && !defined(OS2) #define OS2 #endif #ifdef WIN16 #define BITS16 #else #ifdef MSDOS #define BITS16 #else #define BITS32 #endif #endif #define LSBFIRST #define index(s,c) strchr(s,c) /* PC version of index */ #define rindex(s,c) strrchr(s,c) #if !defined(OS2) && !defined(LWP) /* utils.h under OS/2 */ #define bcmp(s1,s2,n) memcmp((s1),(s2),(n)) #define bcopy(a,b,c) memcpy( (b), (a), (c) ) #define bzero(a,b) memset( (a), 0, (b) ) #endif typedef unsigned char u_char; typedef unsigned long u_long; typedef unsigned short u_short; typedef unsigned int u_int; #define NO_UIDGID_T #if !defined(WINDOWS) && !defined(DWORD) typedef long DWORD; #endif #if defined(PC)&&!defined(WINDOWS) #ifndef LPSTR typedef char *LPSTR; typedef char *LPBYTE; typedef char *CHARPTR; typedef char *LPINT; typedef unsigned int WORD; #endif #define LONG long #define FAR #define PASCAL #define EXPORT #endif #ifdef OS2 #include <utils.h> #define lstrcpy strcpy #define lstrlen strlen #define lstrcmp strcmp #define lstrcpyn strncpy #endif #ifdef WIN32 #define _export #endif #if defined(BITS32) #define far #define near #endif #ifdef WINDOWS #include <windows.h> #endif #ifdef WIN32 #include <windowsx.h> #endif #ifdef WIN16 #pragma message ( "WIN16 in " __FILE__ ) #include <time.h> #include <process.h> #ifndef KRB_INT32 #define KRB_INT32 long #endif #ifndef KRB_UINT32 #define KRB_UINT32 unsigned KRB_INT32 #endif #endif #define RANDOM_KRB_INT32_1 ((KRB_INT32) time(NULL)) #define RANDOM_KRB_INT32_2 ((KRB_INT32) getpid()) #define TIME_GMT_UNIXSEC unix_time_gmt_unixsec((unsigned KRB_INT32 *)0); #ifndef MAXPATHLEN #define MAXPATHLEN _MAX_PATH #endif ����krb5-1.16/src/windows/leashdll/include/krb4/conf.h��������������������������������������������������0000644�0007046�0000145�00000002564�13211554426�021641� 0����������������������������������������������������������������������������������������������������ustar �ghudson�������������������������libuuid����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 1988 by the Massachusetts Institute of Technology. * * For copying and distribution information, please see the file * <mit-copyright.h>. * * Configuration info for operating system, hardware description, * language implementation, C library, etc. * * This file should be included in (almost) every file in the Kerberos * sources, and probably should *not* be needed outside of those * sources. (How do we deal with /usr/include/des.h and * /usr/include/krb.h?) */ #ifndef _CONF_H_ #define _CONF_H_ #include "osconf.h" #ifdef SHORTNAMES #include "names.h" #endif /* * Language implementation-specific definitions */ /* special cases */ #ifdef __HIGHC__ /* broken implementation of ANSI C */ #undef __STDC__ #endif #if !defined(__STDC__) && !defined(PC) #define const #define volatile #define signed typedef char *pointer; /* pointer to generic data */ #ifndef PROTOTYPE #define PROTOTYPE(p) () #endif #else typedef void *pointer; #ifndef PROTOTYPE #define PROTOTYPE(p) p #endif #endif /* Does your compiler understand "void"? */ #ifdef notdef #define void int #endif /* * A few checks to see that necessary definitions are included. */ #ifndef MSBFIRST #ifndef LSBFIRST #error byte order not defined #endif #endif /* machine size */ #ifndef BITS16 #ifndef BITS32 #error number of bits? #endif #endif /* end of checks */ #endif /* _CONF_H_ */ ��������������������������������������������������������������������������������������������������������������������������������������������krb5-1.16/src/windows/leashdll/include/krb4/osconf.h������������������������������������������������0000644�0007046�0000145�00000002340�13211554426�022173� 0����������������������������������������������������������������������������������������������������ustar �ghudson�������������������������libuuid����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 1988 by the Massachusetts Institute of Technology. * * For copying and distribution information, please see the file * <mit-copyright.h>. * * Athena configuration. */ #ifndef _OSCONF_H_ #define _OSCONF_H_ #ifndef PC #if defined(IBMPC) || defined(__MSDOS__) || defined(OS2) || defined(_MSDOS) || defined(_WIN32) #define PC #endif #endif #ifdef tahoe #include "conf-bsdtahoe.h" #else /* !tahoe */ #ifdef vax #include "conf-bsdvax.h" #else /* !vax */ #if defined(mips) && defined(ultrix) #include "conf-ultmips2.h" #else /* !Ultrix MIPS-2 */ #ifdef ibm032 #include "conf-bsdibm032.h" #else /* !ibm032 */ #ifdef apollo #include "conf-bsdapollo.h" #else /* !apollo */ #ifdef sun #ifdef sparc #include "conf-bsdsparc.h" #else /* sun but not sparc */ #ifdef i386 #include "conf-bsd386i.h" #else /* sun but not (sparc or 386i) */ #include "conf-bsdm68k.h" #endif /* i386 */ #endif /* sparc */ #else /* !sun */ #ifdef pyr #include "conf-pyr.h" #else #if defined(PC) || defined(__MSDOS__) || defined(OS2) || defined(_MSDOS) || defined(_WIN32) #include "conf-pc.h" #endif /* PC */ #endif /* pyr */ #endif /* sun */ #endif /* apollo */ #endif /* ibm032 */ #endif /* mips */ #endif /* vax */ #endif /* tahoe */ #endif /* _OSCONF_H_ */ ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������krb5-1.16/src/windows/leashdll/Makefile.in����������������������������������������������������������0000644�0007046�0000145�00000004023�13211554426�020313� 0����������������������������������������������������������������������������������������������������ustar �ghudson�������������������������libuuid����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������BUILDTOP=..\.. ##FIX ME: Enable proper compilation with AFS NO_AFS=1 !ifndef NO_AFS ###AFS_BASE= AFS_INCLUDES=-I$(AFS_BASE)\Include AFS_LIB=$(AFS_BASE)\lib AFS_LIBS=$(AFS_LIB)\afsauthent.lib !else AFS_INCLUDES= AFS_LIBS= !endif DLL_NAME=leashw32 # Use 64-bit DLL_NAME and DEF_FILE on 64-bit platforms !if ("$(CPU)" == "IA64") || ("$(CPU)" == "AMD64") || ("$(CPU)" == "ALPHA64") DLL_NAME=leashw64 !endif DEF_FILE=leashw32.def OBJS= $(OUTPRE)AFSroutines.$(OBJEXT) \ $(OUTPRE)krb5routines.$(OBJEXT) \ $(OUTPRE)leashdll.$(OBJEXT) \ $(OUTPRE)leasherr.$(OBJEXT) \ $(OUTPRE)lsh_pwd.$(OBJEXT) \ $(OUTPRE)lshcallb.$(OBJEXT) \ $(OUTPRE)lshfunc.$(OBJEXT) \ $(OUTPRE)lshutil.$(OBJEXT) \ $(OUTPRE)timesync.$(OBJEXT) \ $(OUTPRE)winerr.$(OBJEXT) \ $(OUTPRE)winutil.$(OBJEXT) \ $(OUTPRE)registry.$(OBJEXT) #TODO: Fix resource compilation RESFILE = $(OUTPRE)lsh_pwd.res XOBJS = $(RESFILE) RCFLAGS = -I$(BUILDTOP)\include -I$(BUILDTOP) -DLEASHDLL_LIB ###From another project inside K 1.9: ###VERSIONRC = $(BUILDTOP)\windows\version.rc ###RCFLAGS=$(CPPFLAGS) -I$(top_srcdir) -D_WIN32 -DRES_ONLY # Set NODEBUG if building release instead of debug LOCALINCLUDES = -I$(BUILDTOP)\include -I$(BUILDTOP)\windows\include -I.\include\krb4 $(AFS_INCLUDES) WINLIBS = kernel32.lib advapi32.lib user32.lib gdi32.lib Version.lib \ ws2_32.lib dnsapi.lib $(BUILDTOP)\ccapi\lib\win\srctmp\$(CCLIB).lib $(AFS_LIBS) WINDLLFLAGS = /nologo /dll /incremental:no /release $(LOPTS) DEFINES = -DWINSOCK -DWIN32 -DWINDOWS -DNO_KRB4 -DUSE_MESSAGE_BOX !ifdef NODEBUG DEFINES = $(DEFINES) !else DEFINES = $(DEFINES) -DDBG !endif !ifdef NO_AFS DEFINES = $(DEFINES) -DNO_AFS !endif all-windows: all-windows: $(OUTPRE)$(DLL_NAME).dll clean-windows:: $(RM) $(OUTPRE)$(DLL_NAME).dll $(OUTPRE)$(DLL_NAME).dll: $(DEF_FILE) $(OBJS) $(XOBJS) link $(WINDLLFLAGS) -def:$(DEF_FILE) -out:$*.dll \ $(OBJS) $(XOBJS) $(WINLIBS) ../lib/$(OUTPRE)libwin.lib $(SCLIB) $(_VC_MANIFEST_EMBED_DLL) #TODO: Add dependencies on include files here $(RESFILE): lsh_pwd.rc ../version.rc ../kerberos.ver �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������krb5-1.16/src/windows/leashdll/resource.h�����������������������������������������������������������0000644�0007046�0000145�00000001065�13211554426�020251� 0����������������������������������������������������������������������������������������������������ustar �ghudson�������������������������libuuid����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//{{NO_DEPENDENCIES}} // Microsoft Developer Studio generated include file. // Used by lsh_pwd.rc // #define IDOK2 5 #define IDCANCEL2 6 #define LEASHICON 100 // Next default values for new objects // #ifdef APSTUDIO_INVOKED #ifndef APSTUDIO_READONLY_SYMBOLS #define _APS_NO_MFC 1 #define _APS_NEXT_RESOURCE_VALUE 103 #define _APS_NEXT_COMMAND_VALUE 40001 #define _APS_NEXT_CONTROL_VALUE 1002 #define _APS_NEXT_SYMED_VALUE 101 #endif #endif ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������krb5-1.16/src/windows/leashdll/leasherr.c�����������������������������������������������������������0000644�0007046�0000145�00000004772�13211554426�020232� 0����������������������������������������������������������������������������������������������������ustar �ghudson�������������������������libuuid����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// ATTENTION: someone in the past edited this file manually // I am continuing this tradition just to get the release out. 3/6/97 // This needs to be revisited and repaired!!!XXXX // pbh /* * leasherr.c * This file is the C file for leasherr.et. * Please do not edit it as it is automatically generated. */ #include <stdlib.h> #include <windows.h> static const char* const text[] = { "Only one instance of Leash can be run at a time.", "Principal invalid.", "Realm failed.", "Instance invalid.", "Realm invalid.", "Unexpected end of Kerberos memory storage.", "Warning! Your Kerberos tickets expire soon.", "You did not type the same new password.", "You can only use printable characters in a password.", "Fatal error; cannot run this program.", "Couldn't initialize WinSock.", "Couldn't find the timeserver host entry.", "Couldn't open a socket.", "Couldn't connect to timeserver.", "Couldn't get time from server.", "Couldn't get local time of day.", "Couldn't set local time of day.", "Error while receiving time from server.", "Protocol problem with timeserver.", "The time was already reset. Try using a different program to synchronize the time.", 0 }; typedef LPSTR (*err_func)(int, long); struct error_table { char const * const * msgs; err_func func; long base; int n_msgs; }; struct et_list { #ifdef WINDOWS HANDLE next; #else struct et_list *next; #endif const struct error_table * table; }; static const struct error_table et = { text, (err_func)0, 40591872L, 20 }; #ifdef WINDOWS void initialize_lsh_error_table(HANDLE *__et_list) { // struct et_list *_link,*_et_list; struct et_list *_link; HANDLE ghlink; ghlink=GlobalAlloc(GHND,sizeof(struct et_list)); _link=GlobalLock(ghlink); _link->next=*__et_list; _link->table=&et; GlobalUnlock(ghlink); *__et_list=ghlink; } #else void initialize_lsh_error_table(struct et_list **__et_list) { struct et_list *_link; _link=malloc(sizeof(struct et_list)); _link->next=*__et_list; _link->table=&et; *__et_list=_link; } #endif #ifdef WINDOWS void Leash_initialize_krb_error_func(err_func func, HANDLE *__et_list) { } void Leash_initialize_kadm_error_table(HANDLE *__et_list) { } #else #include <krberr.h> void Leash_initialize_krb_error_func(err_func func, struct et_list **__et_list) { (*pinitialize_krb_error_func)(func,__et_list); } #include <kadm_err.h> void Leash_initialize_kadm_error_table(struct et_list **__et_list) { initialize_kadm_error_table(__et_list); } #endif ������krb5-1.16/src/windows/leashdll/res/�����������������������������������������������������������������0000755�0007046�0000145�00000000000�13211554426�017040� 5����������������������������������������������������������������������������������������������������ustar �ghudson�������������������������libuuid����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������krb5-1.16/src/windows/leashdll/res/leash.ico��������������������������������������������������������0000644�0007046�0000145�00000022676�13211554426�020645� 0����������������������������������������������������������������������������������������������������ustar �ghudson�������������������������libuuid��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������00��� �%�����(���0���`���� �����������������������������������������������������������������B@A B@AB@AB@AB@AB@AB@AB@AB@AB@AB@AB@AB@AP������������������������������������������������������������������������������������������������������������������������������������B@A@B@AB@AMKL_^_nmmqqq|||||||||qqqnmm_^_TSSFDEB@AB@AB@AP�������������������������������������������������������������������������������������������B@AB@AB@AXWWuuu||||||||||||||||||||||||||||||||||||jijXWWB@AB@AB@A`�������������������������������������������������������������������������������B@A0B@AMKLqqq||||||||||||||||||||||||||||||||||||||||||||||||xxx_^_FDEB@AB@AP����������������������������������������������������������������B@A0B@AXWWxxx|||||||||MKKMKKMKKMKKMKKMKKMKKMKKMKKMKK||||||||||||||||||xxx_^_B@AB@AMKKMKKMKKMKKMKKMKKMKKMKK���������������������������B@AB@AXWW|||||||||||||||MKKMKK||||||||||||||||||||||||jiiMKKMKKMKK���������������������������B@AMKLxxx|||||||||||||||MKKMKK|||||||||||||||||||||xxxMKKMKKMKK�����������������������B@A@B@Aqqq||||||||||||||||||MKKMKK|||||||||||||||||||||MKKMKKMKK��������������������������������B@AXWW|||||||||||||||||||||MKKMKK||||||||||||||||||nmmMKKMKK����������������������������B@A B@Aqqq|||||||||||||||||||||MKKMKK|||||||||||||||xxxMKKMKK����������������������������B@ApMKL||||||||||||||||||||||||MKKMKK|||||||||||||||MKKMKKMKK����������������������������B@A[Z[||||||||||||||||||||||||MKKMKK||||||||||||MKKMKKB@AB@A������������������������������B@Ajij||||||||||||||||||||||||MKKMKK|||||||||MKKMKKxxxMKLB@A������������������������������B@Auuu||||||||||||||||||||||||MKKMKK||||||MKKMKKuuu|||qqqFDEB@A�������������������������B@A@B@A|||||||||||||||||||||||||||MKKMKKqqqMKKMKK||||||||||||jijB@AB@A@������������������������B@A@B@A|||||||||||||||||||||||||||MKKMKKMKKMKK||||||||||||||||||[Z[B@AB@A��������������������B@A@B@A|||||||||||||||||||||||||||MKKMKKMKK|||uuu|||||||||||||||xxxIHHB@A��������������������B@A@B@A|||||||||||||||||||||||||||MKKMKK|||||||||||||||||||||||||||jijB@AB@A ����������������B@AB@Axxx||||||||||||||||||||||||MKKMKK|||||||||||||||||||||||||||||||||QOPB@A��������������������B@Anmm||||||||||||||||||||||||MKKMKK||||||xxx|||||||||||||||||||||||||||nmmB@AB@A0����������������B@Afff||||||||||||||||||||||||MKKMKK||||||||||||||||||||||||||||||||||||||||||QOPB@A����������������B@AXWW||||||||||||||||||||||||MKKMKK|||||||||||||||||||||||||||||||||||||||||||||nmmB@AB@A ������������B@A`IHH||||||||||||||||||||||||MKKMKK|||xxx|||||||||||||||||||||||||||||||||||||||IHHB@Ap������������B@A B@Auuu|||||||||||||||||||||MKKMKKqqq|||||||||||||||||||||||||||||||||||||||cbbB@A����������������B@Acbb|||||||||||||||||||||MKKMKKuuu||||||||||||||||||||||||||||||||||||uuuB@AB@A ������������B@ApIHH|||||||||||||||||||||MKKMKKMKKxxx||||||||||||||||||||||||||||||||||||IHHB@A`������������B@A B@Anmm||||||||||||||||||MKKMKKMKKMKKxxx|||||||||||||||||||||||||||||||||XWWB@A����������������B@AQOP||||||||||||||||||MKKMKK|||MKKMKKxxx||||||||||||||||||||||||||||||fffB@A����������������B@A0B@Anmm|||||||||||||||MKKMKK||||||MKKMKK||||||||||||||||||||||||||||||nmmB@A��������������������B@AQOP|||||||||||||||MKKMKK|||||||||MKKMKK|||||||||||||||||||||||||||xxxB@AB@A����������������B@A B@Ajij||||||||||||MKKMKK||||||||||||MKKMKK|||||||||||||||||||||||||||B@AB@A@��������������������B@AIHHxxx|||||||||MKKMKK|||||||||||||||MKKMKK||||||||||||||||||||||||B@AB@A@��������������������B@AB@A[Z[|||||||||MKKMKK||||||||||||xxx|||MKKMKK|||||||||||||||||||||B@AB@A@������������������������B@A@B@Ajij||||||MKKMKK|||||||||||||||xxx|||MKKMKK|||||||||||||||||||||B@AB@A@����������������������������B@AFDEqqq|||MKKMKK||||||||||||||||||||||||MKKMKKMKKMKKMKKMKKMKKMKKMKKMKK||||||||||||||||||uuuB@A������������������������������������B@AMKLxxxMKKMKK||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||jijB@A������������������������������������B@AB@AMKLMKKMKK||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||[Z[B@A����������������������������������������B@AB@AMKKMKK||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||MKLB@Ap��������������������������������������������B@A0MKKMKK|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||qqqB@AB@A ������������������������������������������������MKKMKK|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||XWWB@A����������������������������������������������������MKKMKK||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||nmmB@AB@A@����������������������������������������������������MKKMKK|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||xxxMKLB@A��������������������������������������������������������MKKMKK|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||XWWB@AB@A��������������������������������������������������������MKKMKK|||||||||||||||||||||||||||||||||||||||||||||||||||||||||xxxXWWB@AB@A0������������������������������������������������������������MKKMKKMKKMKKMKKMKKMKKMKKMKKMKK_^_xxx||||||||||||||||||||||||||||||||||||||||||||||||qqqMKLB@AB@A0���������������������������������������������������������������B@@2B@@DB@AB@AXWWjij||||||||||||||||||||||||||||||||||||uuuXWWB@AB@AB@A����������������������������������������������������������������������������������������������������������������B@APB@AB@AFDETSS_^_nmmqqq|||||||||qqqnmm_^_MKLB@AB@AB@A@������������������������������������������������������������������������������������������������������������������������������������B@APB@AB@AB@AB@AB@AB@AB@AB@AB@AB@AB@AB@A �������������������������������������������������������������������������������������������������������������������?���������������������������������������������������������������������������������������������������������������������������������������������������������������������?�����������������������������������������������������������������������������krb5-1.16/src/windows/leashdll/res/islogo.bmp�������������������������������������������������������0000644�0007046�0000145�00000047226�13211554426�021047� 0����������������������������������������������������������������������������������������������������ustar �ghudson�������������������������libuuid����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������BMN������v���(�������������������������������������������������������������������������p��ww��������������������������������������p����������������p�����p�p���������������������������p�p�wp�����p����xp��w��p��w�����w��x�w����p�wp����p��w�����p�p��p��p��p�p�p��p�������p����p�������w���p��p��p�pp�ppx���p�������w������p�������p����p��p��p�w���p����p�������������p�������w���p��p�p�p����w��w��p�w�����p����������������p���p�����������w�������p������������������������������p�����p�����xp�������������������p�������p���wp��x�����w��p��p��p�w��p�p�p�ppw��p��w�����w��wp���wwxwp�wwxwwwwxwxwwww�wxwwwxwwp��wwwww�wwwwxwxwwx�p��p����p����w������w���p�p���wwwwwxwwww����p����p��p����p��p����p��p����p��p����p��p�p�p��p�p�p��p�p�p��p��p��p��p��w��p��p����p��p����p������p�p�p������wwwwwxwwwwwwyxxywwywwx��������������������������������������������������������������������������������������x��������������������������������������y�������y������y�yy����y����������x��������������x��������������wx���ww���w�����������w���������������������������x���������x����x���x�����������x������������������������������������x����������������������������������������������������������������y���������������������������������������������������������������������������wwx������������������������������������������ww��������yx�����������������������������������������yx����������w�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������krb5-1.16/src/windows/leash/������������������������������������������������������������������������0000755�0007046�0000145�00000000000�13211554426�015553� 5����������������������������������������������������������������������������������������������������ustar �ghudson�������������������������libuuid����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������krb5-1.16/src/windows/leash/AfsProperties.h���������������������������������������������������������0000644�0007046�0000145�00000002666�13211554426�020524� 0����������������������������������������������������������������������������������������������������ustar �ghudson�������������������������libuuid����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#if !defined(AFX_AFSPROPERTIES_H__FD135601_2FCB_11D3_96A2_0000861B8A3C__INCLUDED_) #define AFX_AFSPROPERTIES_H__FD135601_2FCB_11D3_96A2_0000861B8A3C__INCLUDED_ #if _MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000 // AfsProperties.h : header file // ///////////////////////////////////////////////////////////////////////////// // CAfsProperties dialog class CAfsProperties : public CDialog { // Construction private: UINT m_newAfsStatus; UINT m_oldAfsStatus; CWinApp *m_pApp; public: CAfsProperties(CWnd* pParent = NULL); // standard constructor // Dialog Data //{{AFX_DATA(CAfsProperties) enum { IDD = IDD_AFS_PROPERTIES }; // NOTE: the ClassWizard will add data members here //}}AFX_DATA // Overrides // ClassWizard generated virtual function overrides //{{AFX_VIRTUAL(CAfsProperties) protected: virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support //}}AFX_VIRTUAL // Implementation protected: // Generated message map functions //{{AFX_MSG(CAfsProperties) virtual BOOL OnInitDialog(); afx_msg void OnButtonAfsProperties(); virtual void OnOK(); afx_msg void OnRadioAfsEnabled(); afx_msg void OnRadioAfsDisabled(); afx_msg void OnHelp(); //}}AFX_MSG DECLARE_MESSAGE_MAP() }; //{{AFX_INSERT_LOCATION}} // Microsoft Visual C++ will insert additional declarations immediately before the previous line. #endif // !defined(AFX_AFSPROPERTIES_H__FD135601_2FCB_11D3_96A2_0000861B8A3C__INCLUDED_) ��������������������������������������������������������������������������krb5-1.16/src/windows/leash/KrbMiscConfigOpt.cpp����������������������������������������������������0000644�0007046�0000145�00000115275�13211554426�021435� 0����������������������������������������������������������������������������������������������������ustar �ghudson�������������������������libuuid����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//***************************************************************************** // File: KrbMiscConfigOpt.cpp // By: Paul B. Hill // Created: 08/12/1999 // Copyright: @1999 Massachusetts Institute of Technology - All rights // reserved. // Description: CPP file for KrbMiscConfigOpt.cpp. Contains variables // and functions for Kerberos Properties. // // History: // // MM/DD/YY Inits Description of Change // 08/12/99 PBH Original //***************************************************************************** #include "stdafx.h" #include "Leash.h" #include "KrbProperties.h" #include "KrbMiscConfigOpt.h" #include "LeashFileDialog.h" #include "LeashMessageBox.h" #include "lglobals.h" #include <direct.h> #include "reminder.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif /////////////////////////////////////////////////////////////////////// // CKrbMiscConfigOpt property page UINT CKrbMiscConfigOpt::m_DefaultLifeTime; CString CKrbMiscConfigOpt::m_initDefaultLifeTimeMin; CString CKrbMiscConfigOpt::m_newDefaultLifeTimeMin; CEdit CKrbMiscConfigOpt::m_krbLifeTimeMinEditbox; CString CKrbMiscConfigOpt::m_initDefaultLifeTimeHr; CString CKrbMiscConfigOpt::m_newDefaultLifeTimeHr; CEdit CKrbMiscConfigOpt::m_krbLifeTimeHrEditbox; CString CKrbMiscConfigOpt::m_initDefaultLifeTimeDay; CString CKrbMiscConfigOpt::m_newDefaultLifeTimeDay; CEdit CKrbMiscConfigOpt::m_krbLifeTimeDayEditbox; UINT CKrbMiscConfigOpt::m_DefaultRenewTill; CString CKrbMiscConfigOpt::m_initDefaultRenewTillMin; CString CKrbMiscConfigOpt::m_newDefaultRenewTillMin; CEdit CKrbMiscConfigOpt::m_krbRenewTillMinEditbox; CString CKrbMiscConfigOpt::m_initDefaultRenewTillHr; CString CKrbMiscConfigOpt::m_newDefaultRenewTillHr; CEdit CKrbMiscConfigOpt::m_krbRenewTillHrEditbox; CString CKrbMiscConfigOpt::m_initDefaultRenewTillDay; CString CKrbMiscConfigOpt::m_newDefaultRenewTillDay; CEdit CKrbMiscConfigOpt::m_krbRenewTillDayEditbox; UINT CKrbMiscConfigOpt::m_DefaultLifeMin; CString CKrbMiscConfigOpt::m_initDefaultLifeMinMin; CString CKrbMiscConfigOpt::m_newDefaultLifeMinMin; CEdit CKrbMiscConfigOpt::m_krbLifeMinMinEditbox; CString CKrbMiscConfigOpt::m_initDefaultLifeMinHr; CString CKrbMiscConfigOpt::m_newDefaultLifeMinHr; CEdit CKrbMiscConfigOpt::m_krbLifeMinHrEditbox; CString CKrbMiscConfigOpt::m_initDefaultLifeMinDay; CString CKrbMiscConfigOpt::m_newDefaultLifeMinDay; CEdit CKrbMiscConfigOpt::m_krbLifeMinDayEditbox; UINT CKrbMiscConfigOpt::m_DefaultLifeMax; CString CKrbMiscConfigOpt::m_initDefaultLifeMaxMin; CString CKrbMiscConfigOpt::m_newDefaultLifeMaxMin; CEdit CKrbMiscConfigOpt::m_krbLifeMaxMinEditbox; CString CKrbMiscConfigOpt::m_initDefaultLifeMaxHr; CString CKrbMiscConfigOpt::m_newDefaultLifeMaxHr; CEdit CKrbMiscConfigOpt::m_krbLifeMaxHrEditbox; CString CKrbMiscConfigOpt::m_initDefaultLifeMaxDay; CString CKrbMiscConfigOpt::m_newDefaultLifeMaxDay; CEdit CKrbMiscConfigOpt::m_krbLifeMaxDayEditbox; UINT CKrbMiscConfigOpt::m_DefaultRenewMin; CString CKrbMiscConfigOpt::m_initDefaultRenewMinMin; CString CKrbMiscConfigOpt::m_newDefaultRenewMinMin; CEdit CKrbMiscConfigOpt::m_krbRenewMinMinEditbox; CString CKrbMiscConfigOpt::m_initDefaultRenewMinHr; CString CKrbMiscConfigOpt::m_newDefaultRenewMinHr; CEdit CKrbMiscConfigOpt::m_krbRenewMinHrEditbox; CString CKrbMiscConfigOpt::m_initDefaultRenewMinDay; CString CKrbMiscConfigOpt::m_newDefaultRenewMinDay; CEdit CKrbMiscConfigOpt::m_krbRenewMinDayEditbox; UINT CKrbMiscConfigOpt::m_DefaultRenewMax; CString CKrbMiscConfigOpt::m_initDefaultRenewMaxMin; CString CKrbMiscConfigOpt::m_newDefaultRenewMaxMin; CEdit CKrbMiscConfigOpt::m_krbRenewMaxMinEditbox; CString CKrbMiscConfigOpt::m_initDefaultRenewMaxHr; CString CKrbMiscConfigOpt::m_newDefaultRenewMaxHr; CEdit CKrbMiscConfigOpt::m_krbRenewMaxHrEditbox; CString CKrbMiscConfigOpt::m_initDefaultRenewMaxDay; CString CKrbMiscConfigOpt::m_newDefaultRenewMaxDay; CEdit CKrbMiscConfigOpt::m_krbRenewMaxDayEditbox; IMPLEMENT_DYNCREATE(CKrbMiscConfigOpt, CPropertyPage) CKrbMiscConfigOpt::CKrbMiscConfigOpt() : CPropertyPage(CKrbMiscConfigOpt::IDD) { m_noLifeTime = FALSE; m_DefaultLifeTime = 0; m_DefaultRenewTill = 0; m_DefaultLifeMin = 0; m_DefaultLifeMax = 0; m_DefaultRenewMin = 0; m_DefaultRenewMax = 0; m_initUseKrb4 = m_newUseKrb4 = 0; m_initKinitPreserve = m_newKinitPreserve = 0; //{{AFX_DATA_INIT(CKrbConfigOptions) //}}AFX_DATA_INIT } CKrbMiscConfigOpt::~CKrbMiscConfigOpt() { } VOID CKrbMiscConfigOpt::DoDataExchange(CDataExchange* pDX) { TRACE("Entering CKrbMiscConfigOpt::DoDataExchange -- %d\n", pDX->m_bSaveAndValidate); CPropertyPage::DoDataExchange(pDX); //{{AFX_DATA_MAP(CKrbMscConfigOpt) DDX_Control(pDX, IDC_EDIT_LIFETIME_D, m_krbLifeTimeDayEditbox); DDX_Control(pDX, IDC_EDIT_LIFETIME_H, m_krbLifeTimeHrEditbox); DDX_Control(pDX, IDC_EDIT_LIFETIME_M, m_krbLifeTimeMinEditbox); DDX_Control(pDX, IDC_EDIT_RENEWTILL_D, m_krbRenewTillDayEditbox); DDX_Control(pDX, IDC_EDIT_RENEWTILL_H, m_krbRenewTillHrEditbox); DDX_Control(pDX, IDC_EDIT_RENEWTILL_M, m_krbRenewTillMinEditbox); DDX_Control(pDX, IDC_EDIT_LIFE_MIN_D, m_krbLifeMinDayEditbox); DDX_Control(pDX, IDC_EDIT_LIFE_MIN_H, m_krbLifeMinHrEditbox); DDX_Control(pDX, IDC_EDIT_LIFE_MIN_M, m_krbLifeMinMinEditbox); DDX_Control(pDX, IDC_EDIT_LIFE_MAX_D, m_krbLifeMaxDayEditbox); DDX_Control(pDX, IDC_EDIT_LIFE_MAX_H, m_krbLifeMaxHrEditbox); DDX_Control(pDX, IDC_EDIT_LIFE_MAX_M, m_krbLifeMaxMinEditbox); DDX_Control(pDX, IDC_EDIT_RENEW_MIN_D, m_krbRenewMinDayEditbox); DDX_Control(pDX, IDC_EDIT_RENEW_MIN_H, m_krbRenewMinHrEditbox); DDX_Control(pDX, IDC_EDIT_RENEW_MIN_M, m_krbRenewMinMinEditbox); DDX_Control(pDX, IDC_EDIT_RENEW_MAX_D, m_krbRenewMaxDayEditbox); DDX_Control(pDX, IDC_EDIT_RENEW_MAX_H, m_krbRenewMaxHrEditbox); DDX_Control(pDX, IDC_EDIT_RENEW_MAX_M, m_krbRenewMaxMinEditbox); //}}AFX_DATA_MAP } BOOL CKrbMiscConfigOpt::OnInitDialog() { CPropertyPage::OnInitDialog(); DWORD tmp = m_DefaultLifeTime = pLeash_get_default_lifetime(); if (tmp) m_noLifeTime = FALSE; // We now have the value. else m_noLifeTime = TRUE; LPTSTR buf = m_initDefaultLifeTimeDay.GetBuffer(80); _itoa(tmp/24/60, buf, 10); tmp %= (24 * 60); m_initDefaultLifeTimeDay.ReleaseBuffer(); m_newDefaultLifeTimeDay = m_initDefaultLifeTimeDay; buf = m_initDefaultLifeTimeHr.GetBuffer(80); _itoa(tmp/60, buf, 10); tmp %= 60; m_initDefaultLifeTimeHr.ReleaseBuffer(); m_newDefaultLifeTimeHr = m_initDefaultLifeTimeHr; buf = m_initDefaultLifeTimeMin.GetBuffer(80); _itoa(tmp, buf, 10); m_initDefaultLifeTimeMin.ReleaseBuffer(); m_newDefaultLifeTimeMin = m_initDefaultLifeTimeMin; tmp = m_DefaultRenewTill = pLeash_get_default_renew_till(); buf = m_initDefaultRenewTillDay.GetBuffer(80); _itoa(tmp/24/60, buf, 10); tmp %= (24 * 60); m_initDefaultRenewTillDay.ReleaseBuffer(); m_newDefaultRenewTillDay = m_initDefaultRenewTillDay; buf = m_initDefaultRenewTillHr.GetBuffer(80); _itoa(tmp/60, buf, 10); tmp %= 60; m_initDefaultRenewTillHr.ReleaseBuffer(); m_newDefaultRenewTillHr = m_initDefaultRenewTillHr; buf = m_initDefaultRenewTillMin.GetBuffer(80); _itoa(tmp, buf, 10); m_initDefaultRenewTillMin.ReleaseBuffer(); m_newDefaultRenewTillMin = m_initDefaultRenewTillMin; tmp = m_DefaultLifeMin = pLeash_get_default_life_min(); buf = m_initDefaultLifeMinDay.GetBuffer(80); _itoa(tmp/24/60, buf, 10); tmp %= (24 * 60); m_initDefaultLifeMinDay.ReleaseBuffer(); m_newDefaultLifeMinDay = m_initDefaultLifeMinDay; buf = m_initDefaultLifeMinHr.GetBuffer(80); _itoa(tmp/60, buf, 10); tmp %= 60; m_initDefaultLifeMinHr.ReleaseBuffer(); m_newDefaultLifeMinHr = m_initDefaultLifeMinHr; buf = m_initDefaultLifeMinMin.GetBuffer(80); _itoa(tmp, buf, 10); m_initDefaultLifeMinMin.ReleaseBuffer(); m_newDefaultLifeMinMin = m_initDefaultLifeMinMin; tmp = m_DefaultLifeMax = pLeash_get_default_life_max(); buf = m_initDefaultLifeMaxDay.GetBuffer(80); _itoa(tmp/24/60, buf, 10); tmp %= (24 * 60); m_initDefaultLifeMaxDay.ReleaseBuffer(); m_newDefaultLifeMaxDay = m_initDefaultLifeMaxDay; buf = m_initDefaultLifeMaxHr.GetBuffer(80); _itoa(tmp/60, buf, 10); tmp %= 60; m_initDefaultLifeMaxHr.ReleaseBuffer(); m_newDefaultLifeMaxHr = m_initDefaultLifeMaxHr; buf = m_initDefaultLifeMaxMin.GetBuffer(80); _itoa(tmp, buf, 10); m_initDefaultLifeMaxMin.ReleaseBuffer(); m_newDefaultLifeMaxMin = m_initDefaultLifeMaxMin; tmp = m_DefaultRenewMin = pLeash_get_default_renew_min(); buf = m_initDefaultRenewMinDay.GetBuffer(80); _itoa(tmp/24/60, buf, 10); tmp %= (24 * 60); m_initDefaultRenewMinDay.ReleaseBuffer(); m_newDefaultRenewMinDay = m_initDefaultRenewMinDay; buf = m_initDefaultRenewMinHr.GetBuffer(80); _itoa(tmp/60, buf, 10); tmp %= 60; m_initDefaultRenewMinHr.ReleaseBuffer(); m_newDefaultRenewMinHr = m_initDefaultRenewMinHr; buf = m_initDefaultRenewMinMin.GetBuffer(80); _itoa(tmp, buf, 10); m_initDefaultRenewMinMin.ReleaseBuffer(); m_newDefaultRenewMinMin = m_initDefaultRenewMinMin; tmp = m_DefaultRenewMax = pLeash_get_default_renew_max(); buf = m_initDefaultRenewMaxDay.GetBuffer(80); _itoa(tmp/24/60, buf, 10); tmp %= (24 * 60); m_initDefaultRenewMaxDay.ReleaseBuffer(); m_newDefaultRenewMaxDay = m_initDefaultRenewMaxDay; buf = m_initDefaultRenewMaxHr.GetBuffer(80); _itoa(tmp/60, buf, 10); tmp %= 60; m_initDefaultRenewMaxHr.ReleaseBuffer(); m_newDefaultRenewMaxHr = m_initDefaultRenewMaxHr; buf = m_initDefaultRenewMaxMin.GetBuffer(80); _itoa(tmp, buf, 10); m_initDefaultRenewMaxMin.ReleaseBuffer(); m_newDefaultRenewMaxMin = m_initDefaultRenewMaxMin; if (!CLeashApp::m_hKrb5DLL) { GetDlgItem(IDC_EDIT_RENEWTILL_D)->EnableWindow(FALSE); GetDlgItem(IDC_EDIT_RENEWTILL_H)->EnableWindow(FALSE); GetDlgItem(IDC_EDIT_RENEWTILL_M)->EnableWindow(FALSE); GetDlgItem(IDC_EDIT_RENEW_MIN_D)->EnableWindow(FALSE); GetDlgItem(IDC_EDIT_RENEW_MIN_H)->EnableWindow(FALSE); GetDlgItem(IDC_EDIT_RENEW_MIN_M)->EnableWindow(FALSE); GetDlgItem(IDC_EDIT_RENEW_MAX_D)->EnableWindow(FALSE); GetDlgItem(IDC_EDIT_RENEW_MAX_H)->EnableWindow(FALSE); GetDlgItem(IDC_EDIT_RENEW_MAX_M)->EnableWindow(FALSE); } #ifndef NO_KRB4 m_initUseKrb4 = m_newUseKrb4 = (CLeashApp::m_hKrb4DLL ? pLeash_get_default_use_krb4() : 0); CheckDlgButton(IDC_CHECK_REQUEST_KRB4, m_initUseKrb4); if ( !CLeashApp::m_hKrb4DLL ) GetDlgItem(IDC_CHECK_REQUEST_KRB4)->EnableWindow(FALSE); #else ////Or remove these completely? m_initUseKrb4 = m_newUseKrb4 = 0; CheckDlgButton(IDC_CHECK_REQUEST_KRB4, 0); GetDlgItem(IDC_CHECK_REQUEST_KRB4)->EnableWindow(FALSE); #endif m_initKinitPreserve = m_newKinitPreserve = pLeash_get_default_preserve_kinit_settings(); CheckDlgButton(IDC_CHECK_PRESERVE_KINIT_OPTIONS, m_initKinitPreserve); return(TRUE); } BOOL CKrbMiscConfigOpt::OnApply() { DWORD lifetime = ((atoi(m_newDefaultLifeTimeDay)*24 + atoi(m_newDefaultLifeTimeHr)) * 60) + atoi(m_newDefaultLifeTimeMin); DWORD renewtill = ((atoi(m_newDefaultRenewTillDay)*24 + atoi(m_newDefaultRenewTillHr)) * 60) + atoi(m_newDefaultRenewTillMin); DWORD lifemin = ((atoi(m_newDefaultLifeMinDay)*24 + atoi(m_newDefaultLifeMinHr)) * 60) + atoi(m_newDefaultLifeMinMin); DWORD lifemax = ((atoi(m_newDefaultLifeMaxDay)*24 + atoi(m_newDefaultLifeMaxHr)) * 60) + atoi(m_newDefaultLifeMaxMin); DWORD renewmin = ((atoi(m_newDefaultRenewMinDay)*24 + atoi(m_newDefaultRenewMinHr)) * 60) + atoi(m_newDefaultRenewMinMin); DWORD renewmax = ((atoi(m_newDefaultRenewMaxDay)*24 + atoi(m_newDefaultRenewMaxHr)) * 60) + atoi(m_newDefaultRenewMaxMin); // If no changes were made, quit this function if ( m_DefaultLifeTime == lifetime && m_DefaultRenewTill == renewtill && m_DefaultLifeMin == lifemin && m_DefaultLifeMax == lifemax && m_DefaultRenewMin == renewmin && m_DefaultRenewMax == renewmax && m_initUseKrb4 == m_newUseKrb4 && m_initKinitPreserve == m_newKinitPreserve ) return TRUE; if ( lifemin > lifemax ) { MessageBox("The Minimum Ticket Lifetime must be less than the Maximum Ticket Lifetime.", "Leash", MB_OK); return(FALSE); } if (lifetime < lifemin || lifetime > lifemax) { MessageBox("The default Ticket Lifetime must fall within the range specified by the " "Minimum and Maximum Ticket Lifetime fields", "Leash", MB_OK); return(FALSE); } if ( CLeashApp::m_hKrb5DLL && (renewmin > renewmax) ) { MessageBox("The Minimum Ticket Renewable Lifetime must be less than the Maximum Ticket Renewable Lifetime.", "Leash", MB_OK); return(FALSE); } if ( CLeashApp::m_hKrb5DLL && (renewmin < lifemin) ) { MessageBox("The Minimum Renewable Ticket Lifetime must not be smaller than the Minimum Ticket Lifetime.", "Leash", MB_OK); } if ( CLeashApp::m_hKrb5DLL && (renewtill < renewmin || renewtill > renewmax) ) { MessageBox("The default Renewable Ticket Lifetime must fall within the range specified by the " "Minimum and Maximum Renewable Ticket Lifetime fields", "Leash", MB_OK); return(FALSE); } m_DefaultLifeMin = lifemin; pLeash_set_default_life_min(m_DefaultLifeMin); m_initDefaultLifeMinDay = m_newDefaultLifeMinDay; m_initDefaultLifeMinHr = m_newDefaultLifeMinHr ; m_initDefaultLifeMinMin = m_newDefaultLifeMinMin; m_DefaultLifeMax = lifemax; pLeash_set_default_life_max(m_DefaultLifeMax); m_initDefaultLifeMaxDay = m_newDefaultLifeMaxDay; m_initDefaultLifeMaxHr = m_newDefaultLifeMaxHr ; m_initDefaultLifeMaxMin = m_newDefaultLifeMaxMin; m_DefaultRenewMin = renewmin; pLeash_set_default_renew_min(m_DefaultRenewMin); m_initDefaultRenewMinDay = m_newDefaultRenewMinDay; m_initDefaultRenewMinHr = m_newDefaultRenewMinHr ; m_initDefaultRenewMinMin = m_newDefaultRenewMinMin; m_DefaultRenewMax = renewmax; pLeash_set_default_renew_max(m_DefaultRenewMax); m_initDefaultRenewMaxDay = m_newDefaultRenewMaxDay; m_initDefaultRenewMaxHr = m_newDefaultRenewMaxHr ; m_initDefaultRenewMaxMin = m_newDefaultRenewMaxMin; m_DefaultRenewTill = renewtill; pLeash_set_default_renew_till(m_DefaultRenewTill); m_initDefaultRenewTillDay = m_newDefaultRenewTillDay; m_initDefaultRenewTillHr = m_newDefaultRenewTillHr ; m_initDefaultRenewTillMin = m_newDefaultRenewTillMin; if( getenv("LIFETIME") != NULL) { MessageBox("The ticket lifetime is being controlled by the environment " "variable LIFETIME instead of the registry. Leash cannot modify " "the environment. Use the System control panel instead.", "Leash", MB_OK); return(FALSE); } m_DefaultLifeTime = lifetime; pLeash_set_default_lifetime(m_DefaultLifeTime); m_initDefaultLifeTimeDay = m_newDefaultLifeTimeDay; m_initDefaultLifeTimeHr = m_newDefaultLifeTimeHr ; m_initDefaultLifeTimeMin = m_newDefaultLifeTimeMin; // If we're using an environment variable tell the user that we // can't use Leash to modify the value. if (!m_DefaultLifeTime) { MessageBox("A lifetime setting of 0 is special in that it means that " "the application is free to pick whatever default it deems " "appropriate", "Leash", MB_OK); } #ifndef NO_KRB4 if ( m_initUseKrb4 != m_newUseKrb4 ) { pLeash_set_default_use_krb4(m_newUseKrb4); } #endif if ( m_initKinitPreserve != m_newKinitPreserve ) { pLeash_set_default_preserve_kinit_settings(m_newKinitPreserve); } return TRUE; } void CKrbMiscConfigOpt::OnSelchangeEditDefaultLifeTime() { static int in_progress = 0; if (!in_progress && !m_startupPage2) { in_progress = 1; GetDlgItemText(IDC_EDIT_LIFETIME_D, m_newDefaultLifeTimeDay); GetDlgItemText(IDC_EDIT_LIFETIME_H, m_newDefaultLifeTimeHr); GetDlgItemText(IDC_EDIT_LIFETIME_M, m_newDefaultLifeTimeMin); DWORD value = (((atoi(m_newDefaultLifeTimeDay)*24 + atoi(m_newDefaultLifeTimeHr)) * 60) + atoi(m_newDefaultLifeTimeMin)); LPSTR buf = m_newDefaultLifeTimeDay.GetBuffer(80); _itoa(value/24/60, buf, 10); value %= (24 * 60); m_newDefaultLifeTimeDay.ReleaseBuffer(); buf = m_newDefaultLifeTimeHr.GetBuffer(80); _itoa(value/60, buf, 10); value %= 60; m_newDefaultLifeTimeHr.ReleaseBuffer(); buf = m_newDefaultLifeTimeMin.GetBuffer(80); _itoa(value, buf, 10); m_newDefaultLifeTimeMin.ReleaseBuffer(); SetDlgItemText(IDC_EDIT_LIFETIME_D, m_newDefaultLifeTimeDay); SetDlgItemText(IDC_EDIT_LIFETIME_H, m_newDefaultLifeTimeHr); SetDlgItemText(IDC_EDIT_LIFETIME_M, m_newDefaultLifeTimeMin); SetModified(TRUE); in_progress = 0; } } void CKrbMiscConfigOpt::OnEditKillfocusEditDefaultLifeTime() { static int in_progress = 0; if (!in_progress && !m_startupPage2) { in_progress = 1; GetDlgItemText(IDC_EDIT_LIFETIME_D, m_newDefaultLifeTimeDay); GetDlgItemText(IDC_EDIT_LIFETIME_H, m_newDefaultLifeTimeHr); GetDlgItemText(IDC_EDIT_LIFETIME_M, m_newDefaultLifeTimeMin); DWORD value = (((atoi(m_newDefaultLifeTimeDay)*24 + atoi(m_newDefaultLifeTimeHr)) * 60) + atoi(m_newDefaultLifeTimeMin)); LPSTR buf = m_newDefaultLifeTimeDay.GetBuffer(80); _itoa(value/24/60, buf, 10); value %= (24 * 60); m_newDefaultLifeTimeDay.ReleaseBuffer(); buf = m_newDefaultLifeTimeHr.GetBuffer(80); _itoa(value/60, buf, 10); value %= 60; m_newDefaultLifeTimeHr.ReleaseBuffer(); buf = m_newDefaultLifeTimeMin.GetBuffer(80); _itoa(value, buf, 10); m_newDefaultLifeTimeMin.ReleaseBuffer(); SetDlgItemText(IDC_EDIT_LIFETIME_D, m_newDefaultLifeTimeDay); SetDlgItemText(IDC_EDIT_LIFETIME_H, m_newDefaultLifeTimeHr); SetDlgItemText(IDC_EDIT_LIFETIME_M, m_newDefaultLifeTimeMin); SetModified(TRUE); in_progress = 0; } } void CKrbMiscConfigOpt::ResetDefaultLifeTimeEditBox() { // Reset Config Tab's Default LifeTime Editbox DWORD tmp = m_DefaultLifeTime = pLeash_get_default_lifetime(); LPSTR buf = m_newDefaultLifeTimeDay.GetBuffer(80); _itoa(tmp/24/60, buf, 10); tmp %= (24 * 60); m_newDefaultLifeTimeDay.ReleaseBuffer(); buf = m_newDefaultLifeTimeHr.GetBuffer(80); _itoa(tmp/60, buf, 10); tmp %= 60; m_newDefaultLifeTimeHr.ReleaseBuffer(); buf = m_newDefaultLifeTimeMin.GetBuffer(80); _itoa(tmp, buf, 10); m_newDefaultLifeTimeMin.ReleaseBuffer(); ::SetDlgItemText(::GetForegroundWindow(), IDC_EDIT_LIFETIME_D, m_newDefaultLifeTimeDay); ::SetDlgItemText(::GetForegroundWindow(), IDC_EDIT_LIFETIME_H, m_newDefaultLifeTimeHr); ::SetDlgItemText(::GetForegroundWindow(), IDC_EDIT_LIFETIME_M, m_newDefaultLifeTimeMin); } void CKrbMiscConfigOpt::OnSelchangeEditDefaultRenewTill() { static int in_progress = 0; if (!in_progress && !m_startupPage2) { in_progress = 1; GetDlgItemText(IDC_EDIT_RENEWTILL_D, m_newDefaultRenewTillDay); GetDlgItemText(IDC_EDIT_RENEWTILL_H, m_newDefaultRenewTillHr); GetDlgItemText(IDC_EDIT_RENEWTILL_M, m_newDefaultRenewTillMin); DWORD value = (((atoi(m_newDefaultRenewTillDay)*24 + atoi(m_newDefaultRenewTillHr)) * 60) + atoi(m_newDefaultRenewTillMin)); LPSTR buf = m_newDefaultRenewTillDay.GetBuffer(80); _itoa(value/24/60, buf, 10); value %= (24 * 60); m_newDefaultRenewTillDay.ReleaseBuffer(); buf = m_newDefaultRenewTillHr.GetBuffer(80); _itoa(value/60, buf, 10); value %= 60; m_newDefaultRenewTillHr.ReleaseBuffer(); buf = m_newDefaultRenewTillMin.GetBuffer(80); _itoa(value, buf, 10); m_newDefaultRenewTillMin.ReleaseBuffer(); SetDlgItemText(IDC_EDIT_RENEWTILL_D, m_newDefaultRenewTillDay); SetDlgItemText(IDC_EDIT_RENEWTILL_H, m_newDefaultRenewTillHr); SetDlgItemText(IDC_EDIT_RENEWTILL_M, m_newDefaultRenewTillMin); SetModified(TRUE); in_progress = 0; } } void CKrbMiscConfigOpt::OnEditKillfocusEditDefaultRenewTill() { static int in_progress = 0; if (!in_progress && !m_startupPage2) { in_progress = 1; GetDlgItemText(IDC_EDIT_RENEWTILL_D, m_newDefaultRenewTillDay); GetDlgItemText(IDC_EDIT_RENEWTILL_H, m_newDefaultRenewTillHr); GetDlgItemText(IDC_EDIT_RENEWTILL_M, m_newDefaultRenewTillMin); DWORD value = (((atoi(m_newDefaultRenewTillDay)*24 + atoi(m_newDefaultRenewTillHr)) * 60) + atoi(m_newDefaultRenewTillMin)); LPSTR buf = m_newDefaultRenewTillDay.GetBuffer(80); _itoa(value/24/60, buf, 10); value %= (24 * 60); m_newDefaultRenewTillDay.ReleaseBuffer(); buf = m_newDefaultRenewTillHr.GetBuffer(80); _itoa(value/60, buf, 10); value %= 60; m_newDefaultRenewTillHr.ReleaseBuffer(); buf = m_newDefaultRenewTillMin.GetBuffer(80); _itoa(value, buf, 10); m_newDefaultRenewTillMin.ReleaseBuffer(); SetDlgItemText(IDC_EDIT_RENEWTILL_D, m_newDefaultRenewTillDay); SetDlgItemText(IDC_EDIT_RENEWTILL_H, m_newDefaultRenewTillHr); SetDlgItemText(IDC_EDIT_RENEWTILL_M, m_newDefaultRenewTillMin); SetModified(TRUE); in_progress = 0; } } void CKrbMiscConfigOpt::ResetDefaultRenewTillEditBox() { // Reset Config Tab's Default RenewTill Editbox DWORD tmp = m_DefaultRenewTill = pLeash_get_default_lifetime(); LPSTR buf = m_newDefaultRenewTillDay.GetBuffer(80); _itoa(tmp/24/60, buf, 10); tmp %= (24 * 60); m_newDefaultRenewTillDay.ReleaseBuffer(); buf = m_newDefaultRenewTillHr.GetBuffer(80); _itoa(tmp/60, buf, 10); tmp %= 60; m_newDefaultRenewTillHr.ReleaseBuffer(); buf = m_newDefaultRenewTillMin.GetBuffer(80); _itoa(tmp, buf, 10); m_newDefaultRenewTillMin.ReleaseBuffer(); ::SetDlgItemText(::GetForegroundWindow(), IDC_EDIT_RENEWTILL_D, m_newDefaultRenewTillDay); ::SetDlgItemText(::GetForegroundWindow(), IDC_EDIT_RENEWTILL_H, m_newDefaultRenewTillHr); ::SetDlgItemText(::GetForegroundWindow(), IDC_EDIT_RENEWTILL_M, m_newDefaultRenewTillMin); } void CKrbMiscConfigOpt::OnSelchangeEditDefaultLifeMin() { static int in_progress = 0; if (!in_progress && !m_startupPage2) { in_progress = 1; GetDlgItemText(IDC_EDIT_LIFE_MIN_D, m_newDefaultLifeMinDay); GetDlgItemText(IDC_EDIT_LIFE_MIN_H, m_newDefaultLifeMinHr); GetDlgItemText(IDC_EDIT_LIFE_MIN_M, m_newDefaultLifeMinMin); DWORD value = (((atoi(m_newDefaultLifeMinDay)*24 + atoi(m_newDefaultLifeMinHr)) * 60) + atoi(m_newDefaultLifeMinMin)); LPSTR buf = m_newDefaultLifeMinDay.GetBuffer(80); _itoa(value/24/60, buf, 10); value %= (24 * 60); m_newDefaultLifeMinDay.ReleaseBuffer(); buf = m_newDefaultLifeMinHr.GetBuffer(80); _itoa(value/60, buf, 10); value %= 60; m_newDefaultLifeMinHr.ReleaseBuffer(); buf = m_newDefaultLifeMinMin.GetBuffer(80); _itoa(value, buf, 10); m_newDefaultLifeMinMin.ReleaseBuffer(); SetDlgItemText(IDC_EDIT_LIFE_MIN_D, m_newDefaultLifeMinDay); SetDlgItemText(IDC_EDIT_LIFE_MIN_H, m_newDefaultLifeMinHr); SetDlgItemText(IDC_EDIT_LIFE_MIN_M, m_newDefaultLifeMinMin); SetModified(TRUE); in_progress = 0; } } void CKrbMiscConfigOpt::OnEditKillfocusEditDefaultLifeMin() { static int in_progress = 0; if (!in_progress && !m_startupPage2) { in_progress = 1; GetDlgItemText(IDC_EDIT_LIFE_MIN_D, m_newDefaultLifeMinDay); GetDlgItemText(IDC_EDIT_LIFE_MIN_H, m_newDefaultLifeMinHr); GetDlgItemText(IDC_EDIT_LIFE_MIN_M, m_newDefaultLifeMinMin); DWORD value = (((atoi(m_newDefaultLifeMinDay)*24 + atoi(m_newDefaultLifeMinHr)) * 60) + atoi(m_newDefaultLifeMinMin)); LPSTR buf = m_newDefaultLifeMinDay.GetBuffer(80); _itoa(value/24/60, buf, 10); value %= (24 * 60); m_newDefaultLifeMinDay.ReleaseBuffer(); buf = m_newDefaultLifeMinHr.GetBuffer(80); _itoa(value/60, buf, 10); value %= 60; m_newDefaultLifeMinHr.ReleaseBuffer(); buf = m_newDefaultLifeMinMin.GetBuffer(80); _itoa(value, buf, 10); m_newDefaultLifeMinMin.ReleaseBuffer(); SetDlgItemText(IDC_EDIT_LIFE_MIN_D, m_newDefaultLifeMinDay); SetDlgItemText(IDC_EDIT_LIFE_MIN_H, m_newDefaultLifeMinHr); SetDlgItemText(IDC_EDIT_LIFE_MIN_M, m_newDefaultLifeMinMin); SetModified(TRUE); in_progress = 0; } } void CKrbMiscConfigOpt::ResetDefaultLifeMinEditBox() { // Reset Config Tab's Default LifeMin Editbox DWORD tmp = m_DefaultLifeMin = pLeash_get_default_life_min(); LPSTR buf = m_newDefaultLifeMinDay.GetBuffer(80); _itoa(tmp/24/60, buf, 10); tmp %= (24 * 60); m_newDefaultLifeMinDay.ReleaseBuffer(); buf = m_newDefaultLifeMinHr.GetBuffer(80); _itoa(tmp/60, buf, 10); tmp %= 60; m_newDefaultLifeMinHr.ReleaseBuffer(); buf = m_newDefaultLifeMinMin.GetBuffer(80); _itoa(tmp, buf, 10); m_newDefaultLifeMinMin.ReleaseBuffer(); ::SetDlgItemText(::GetForegroundWindow(), IDC_EDIT_LIFE_MIN_D, m_newDefaultLifeMinDay); ::SetDlgItemText(::GetForegroundWindow(), IDC_EDIT_LIFE_MIN_H, m_newDefaultLifeMinHr); ::SetDlgItemText(::GetForegroundWindow(), IDC_EDIT_LIFE_MIN_M, m_newDefaultLifeMinMin); } void CKrbMiscConfigOpt::OnSelchangeEditDefaultLifeMax() { static int in_progress = 0; if (!in_progress && !m_startupPage2) { in_progress = 1; GetDlgItemText(IDC_EDIT_LIFE_MAX_D, m_newDefaultLifeMaxDay); GetDlgItemText(IDC_EDIT_LIFE_MAX_H, m_newDefaultLifeMaxHr); GetDlgItemText(IDC_EDIT_LIFE_MAX_M, m_newDefaultLifeMaxMin); DWORD value = (((atoi(m_newDefaultLifeMaxDay)*24 + atoi(m_newDefaultLifeMaxHr)) * 60) + atoi(m_newDefaultLifeMaxMin)); LPSTR buf = m_newDefaultLifeMaxDay.GetBuffer(80); _itoa(value/24/60, buf, 10); value %= (24 * 60); m_newDefaultLifeMaxDay.ReleaseBuffer(); buf = m_newDefaultLifeMaxHr.GetBuffer(80); _itoa(value/60, buf, 10); value %= 60; m_newDefaultLifeMaxHr.ReleaseBuffer(); buf = m_newDefaultLifeMaxMin.GetBuffer(80); _itoa(value, buf, 10); m_newDefaultLifeMaxMin.ReleaseBuffer(); SetDlgItemText(IDC_EDIT_LIFE_MAX_D, m_newDefaultLifeMaxDay); SetDlgItemText(IDC_EDIT_LIFE_MAX_H, m_newDefaultLifeMaxHr); SetDlgItemText(IDC_EDIT_LIFE_MAX_M, m_newDefaultLifeMaxMin); SetModified(TRUE); in_progress = 0; } } void CKrbMiscConfigOpt::OnEditKillfocusEditDefaultLifeMax() { static int in_progress = 0; if (!in_progress && !m_startupPage2) { in_progress = 1; GetDlgItemText(IDC_EDIT_LIFE_MAX_D, m_newDefaultLifeMaxDay); GetDlgItemText(IDC_EDIT_LIFE_MAX_H, m_newDefaultLifeMaxHr); GetDlgItemText(IDC_EDIT_LIFE_MAX_M, m_newDefaultLifeMaxMin); DWORD value = (((atoi(m_newDefaultLifeMaxDay)*24 + atoi(m_newDefaultLifeMaxHr)) * 60) + atoi(m_newDefaultLifeMaxMin)); LPSTR buf = m_newDefaultLifeMaxDay.GetBuffer(80); _itoa(value/24/60, buf, 10); value %= (24 * 60); m_newDefaultLifeMaxDay.ReleaseBuffer(); buf = m_newDefaultLifeMaxHr.GetBuffer(80); _itoa(value/60, buf, 10); value %= 60; m_newDefaultLifeMaxHr.ReleaseBuffer(); buf = m_newDefaultLifeMaxMin.GetBuffer(80); _itoa(value, buf, 10); m_newDefaultLifeMaxMin.ReleaseBuffer(); SetDlgItemText(IDC_EDIT_LIFE_MAX_D, m_newDefaultLifeMaxDay); SetDlgItemText(IDC_EDIT_LIFE_MAX_H, m_newDefaultLifeMaxHr); SetDlgItemText(IDC_EDIT_LIFE_MAX_M, m_newDefaultLifeMaxMin); SetModified(TRUE); in_progress = 0; } } void CKrbMiscConfigOpt::ResetDefaultLifeMaxEditBox() { // Reset Config Tab's Default LifeMax Editbox DWORD tmp = m_DefaultLifeMax = pLeash_get_default_life_min(); LPSTR buf = m_newDefaultLifeMaxDay.GetBuffer(80); _itoa(tmp/24/60, buf, 10); tmp %= (24 * 60); m_newDefaultLifeMaxDay.ReleaseBuffer(); buf = m_newDefaultLifeMaxHr.GetBuffer(80); _itoa(tmp/60, buf, 10); tmp %= 60; m_newDefaultLifeMaxHr.ReleaseBuffer(); buf = m_newDefaultLifeMaxMin.GetBuffer(80); _itoa(tmp, buf, 10); m_newDefaultLifeMaxMin.ReleaseBuffer(); ::SetDlgItemText(::GetForegroundWindow(), IDC_EDIT_LIFE_MAX_D, m_newDefaultLifeMaxDay); ::SetDlgItemText(::GetForegroundWindow(), IDC_EDIT_LIFE_MAX_H, m_newDefaultLifeMaxHr); ::SetDlgItemText(::GetForegroundWindow(), IDC_EDIT_LIFE_MAX_M, m_newDefaultLifeMaxMin); } void CKrbMiscConfigOpt::OnSelchangeEditDefaultRenewMin() { static int in_progress = 0; if (!in_progress && !m_startupPage2) { in_progress = 1; GetDlgItemText(IDC_EDIT_RENEW_MIN_D, m_newDefaultRenewMinDay); GetDlgItemText(IDC_EDIT_RENEW_MIN_H, m_newDefaultRenewMinHr); GetDlgItemText(IDC_EDIT_RENEW_MIN_M, m_newDefaultRenewMinMin); DWORD value = (((atoi(m_newDefaultRenewMinDay)*24 + atoi(m_newDefaultRenewMinHr)) * 60) + atoi(m_newDefaultRenewMinMin)); LPSTR buf = m_newDefaultRenewMinDay.GetBuffer(80); _itoa(value/24/60, buf, 10); value %= (24 * 60); m_newDefaultRenewMinDay.ReleaseBuffer(); buf = m_newDefaultRenewMinHr.GetBuffer(80); _itoa(value/60, buf, 10); value %= 60; m_newDefaultRenewMinHr.ReleaseBuffer(); buf = m_newDefaultRenewMinMin.GetBuffer(80); _itoa(value, buf, 10); m_newDefaultRenewMinMin.ReleaseBuffer(); SetDlgItemText(IDC_EDIT_RENEW_MIN_D, m_newDefaultRenewMinDay); SetDlgItemText(IDC_EDIT_RENEW_MIN_H, m_newDefaultRenewMinHr); SetDlgItemText(IDC_EDIT_RENEW_MIN_M, m_newDefaultRenewMinMin); SetModified(TRUE); in_progress = 0; } } void CKrbMiscConfigOpt::OnEditKillfocusEditDefaultRenewMin() { static int in_progress = 0; if (!in_progress && !m_startupPage2) { in_progress = 1; GetDlgItemText(IDC_EDIT_RENEW_MIN_D, m_newDefaultRenewMinDay); GetDlgItemText(IDC_EDIT_RENEW_MIN_H, m_newDefaultRenewMinHr); GetDlgItemText(IDC_EDIT_RENEW_MIN_M, m_newDefaultRenewMinMin); DWORD value = (((atoi(m_newDefaultRenewMinDay)*24 + atoi(m_newDefaultRenewMinHr)) * 60) + atoi(m_newDefaultRenewMinMin)); LPSTR buf = m_newDefaultRenewMinDay.GetBuffer(80); _itoa(value/24/60, buf, 10); value %= (24 * 60); m_newDefaultRenewMinDay.ReleaseBuffer(); buf = m_newDefaultRenewMinHr.GetBuffer(80); _itoa(value/60, buf, 10); value %= 60; m_newDefaultRenewMinHr.ReleaseBuffer(); buf = m_newDefaultRenewMinMin.GetBuffer(80); _itoa(value, buf, 10); m_newDefaultRenewMinMin.ReleaseBuffer(); SetDlgItemText(IDC_EDIT_RENEW_MIN_D, m_newDefaultRenewMinDay); SetDlgItemText(IDC_EDIT_RENEW_MIN_H, m_newDefaultRenewMinHr); SetDlgItemText(IDC_EDIT_RENEW_MIN_M, m_newDefaultRenewMinMin); SetModified(TRUE); in_progress = 0; } } void CKrbMiscConfigOpt::ResetDefaultRenewMinEditBox() { // Reset Config Tab's Default RenewMin Editbox DWORD tmp = m_DefaultRenewMin = pLeash_get_default_life_min(); LPSTR buf = m_newDefaultRenewMinDay.GetBuffer(80); _itoa(tmp/24/60, buf, 10); tmp %= (24 * 60); m_newDefaultRenewMinDay.ReleaseBuffer(); buf = m_newDefaultRenewMinHr.GetBuffer(80); _itoa(tmp/60, buf, 10); tmp %= 60; m_newDefaultRenewMinHr.ReleaseBuffer(); buf = m_newDefaultRenewMinMin.GetBuffer(80); _itoa(tmp, buf, 10); m_newDefaultRenewMinMin.ReleaseBuffer(); ::SetDlgItemText(::GetForegroundWindow(), IDC_EDIT_RENEW_MIN_D, m_newDefaultRenewMinDay); ::SetDlgItemText(::GetForegroundWindow(), IDC_EDIT_RENEW_MIN_H, m_newDefaultRenewMinHr); ::SetDlgItemText(::GetForegroundWindow(), IDC_EDIT_RENEW_MIN_M, m_newDefaultRenewMinMin); } void CKrbMiscConfigOpt::OnSelchangeEditDefaultRenewMax() { static int in_progress = 0; if (!in_progress && !m_startupPage2) { in_progress = 1; GetDlgItemText(IDC_EDIT_RENEW_MAX_D, m_newDefaultRenewMaxDay); GetDlgItemText(IDC_EDIT_RENEW_MAX_H, m_newDefaultRenewMaxHr); GetDlgItemText(IDC_EDIT_RENEW_MAX_M, m_newDefaultRenewMaxMin); DWORD value = (((atoi(m_newDefaultRenewMaxDay)*24 + atoi(m_newDefaultRenewMaxHr)) * 60) + atoi(m_newDefaultRenewMaxMin)); LPSTR buf = m_newDefaultRenewMaxDay.GetBuffer(80); _itoa(value/24/60, buf, 10); value %= (24 * 60); m_newDefaultRenewMaxDay.ReleaseBuffer(); buf = m_newDefaultRenewMaxHr.GetBuffer(80); _itoa(value/60, buf, 10); value %= 60; m_newDefaultRenewMaxHr.ReleaseBuffer(); buf = m_newDefaultRenewMaxMin.GetBuffer(80); _itoa(value, buf, 10); m_newDefaultRenewMaxMin.ReleaseBuffer(); SetDlgItemText(IDC_EDIT_RENEW_MAX_D, m_newDefaultRenewMaxDay); SetDlgItemText(IDC_EDIT_RENEW_MAX_H, m_newDefaultRenewMaxHr); SetDlgItemText(IDC_EDIT_RENEW_MAX_M, m_newDefaultRenewMaxMin); SetModified(TRUE); in_progress = 0; } } void CKrbMiscConfigOpt::OnEditKillfocusEditDefaultRenewMax() { static int in_progress = 0; if (!in_progress && !m_startupPage2) { in_progress = 1; GetDlgItemText(IDC_EDIT_RENEW_MAX_D, m_newDefaultRenewMaxDay); GetDlgItemText(IDC_EDIT_RENEW_MAX_H, m_newDefaultRenewMaxHr); GetDlgItemText(IDC_EDIT_RENEW_MAX_M, m_newDefaultRenewMaxMin); DWORD value = (((atoi(m_newDefaultRenewMaxDay)*24 + atoi(m_newDefaultRenewMaxHr)) * 60) + atoi(m_newDefaultRenewMaxMin)); LPSTR buf = m_newDefaultRenewMaxDay.GetBuffer(80); _itoa(value/24/60, buf, 10); value %= (24 * 60); m_newDefaultRenewMaxDay.ReleaseBuffer(); buf = m_newDefaultRenewMaxHr.GetBuffer(80); _itoa(value/60, buf, 10); value %= 60; m_newDefaultRenewMaxHr.ReleaseBuffer(); buf = m_newDefaultRenewMaxMin.GetBuffer(80); _itoa(value, buf, 10); m_newDefaultRenewMaxMin.ReleaseBuffer(); SetDlgItemText(IDC_EDIT_RENEW_MAX_D, m_newDefaultRenewMaxDay); SetDlgItemText(IDC_EDIT_RENEW_MAX_H, m_newDefaultRenewMaxHr); SetDlgItemText(IDC_EDIT_RENEW_MAX_M, m_newDefaultRenewMaxMin); SetModified(TRUE); in_progress = 0; } } void CKrbMiscConfigOpt::ResetDefaultRenewMaxEditBox() { // Reset Config Tab's Default RenewMax Editbox DWORD tmp = m_DefaultRenewMax = pLeash_get_default_life_min(); LPSTR buf = m_newDefaultRenewMaxDay.GetBuffer(80); _itoa(tmp/24/60, buf, 10); tmp %= (24 * 60); m_newDefaultRenewMaxDay.ReleaseBuffer(); buf = m_newDefaultRenewMaxHr.GetBuffer(80); _itoa(tmp/60, buf, 10); tmp %= 60; m_newDefaultRenewMaxHr.ReleaseBuffer(); buf = m_newDefaultRenewMaxMin.GetBuffer(80); _itoa(tmp, buf, 10); m_newDefaultRenewMaxMin.ReleaseBuffer(); ::SetDlgItemText(::GetForegroundWindow(), IDC_EDIT_RENEW_MAX_D, m_newDefaultRenewMaxDay); ::SetDlgItemText(::GetForegroundWindow(), IDC_EDIT_RENEW_MAX_H, m_newDefaultRenewMaxHr); ::SetDlgItemText(::GetForegroundWindow(), IDC_EDIT_RENEW_MAX_M, m_newDefaultRenewMaxMin); } void CKrbMiscConfigOpt::OnCheckUseKrb4() { m_newUseKrb4 = (BOOL)IsDlgButtonChecked(IDC_CHECK_REQUEST_KRB4); } void CKrbMiscConfigOpt::OnCheckKinitPreserve() { m_newKinitPreserve = (BOOL)IsDlgButtonChecked(IDC_CHECK_PRESERVE_KINIT_OPTIONS); } void CKrbMiscConfigOpt::OnShowWindow(BOOL bShow, UINT nStatus) { CPropertyPage::OnShowWindow(bShow, nStatus); if (CLeashApp::m_hKrb5DLL) ResetDefaultLifeTimeEditBox(); SetDlgItemText(IDC_EDIT_LIFETIME_D, m_newDefaultLifeTimeDay); SetDlgItemText(IDC_EDIT_LIFETIME_H, m_newDefaultLifeTimeHr); SetDlgItemText(IDC_EDIT_LIFETIME_M, m_newDefaultLifeTimeMin); SetDlgItemText(IDC_EDIT_RENEWTILL_D, m_newDefaultRenewTillDay); SetDlgItemText(IDC_EDIT_RENEWTILL_H, m_newDefaultRenewTillHr); SetDlgItemText(IDC_EDIT_RENEWTILL_M, m_newDefaultRenewTillMin); SetDlgItemText(IDC_EDIT_LIFE_MIN_D, m_newDefaultLifeMinDay); SetDlgItemText(IDC_EDIT_LIFE_MIN_H, m_newDefaultLifeMinHr); SetDlgItemText(IDC_EDIT_LIFE_MIN_M, m_newDefaultLifeMinMin); SetDlgItemText(IDC_EDIT_LIFE_MAX_D, m_newDefaultLifeMaxDay); SetDlgItemText(IDC_EDIT_LIFE_MAX_H, m_newDefaultLifeMaxHr); SetDlgItemText(IDC_EDIT_LIFE_MAX_M, m_newDefaultLifeMaxMin); SetDlgItemText(IDC_EDIT_RENEW_MIN_D, m_newDefaultRenewMinDay); SetDlgItemText(IDC_EDIT_RENEW_MIN_H, m_newDefaultRenewMinHr); SetDlgItemText(IDC_EDIT_RENEW_MIN_M, m_newDefaultRenewMinMin); SetDlgItemText(IDC_EDIT_RENEW_MAX_D, m_newDefaultRenewMaxDay); SetDlgItemText(IDC_EDIT_RENEW_MAX_H, m_newDefaultRenewMaxHr); SetDlgItemText(IDC_EDIT_RENEW_MAX_M, m_newDefaultRenewMaxMin); } BOOL CKrbMiscConfigOpt::PreTranslateMessage(MSG* pMsg) { if (!m_startupPage2) { if (m_noLifeTime) { MessageBox("A lifetime setting of 0 is special in that it means that " "the application is free to pick whatever default it deems " "appropriate", "Leash", MB_OK); m_noLifeTime = FALSE; } } m_startupPage2 = FALSE; return CPropertyPage::PreTranslateMessage(pMsg); } BEGIN_MESSAGE_MAP(CKrbMiscConfigOpt, CPropertyPage) //{{AFX_MSG_MAP(CKrbConfigOptions) ON_WM_SHOWWINDOW() ON_EN_KILLFOCUS(IDC_EDIT_LIFETIME_D, OnEditKillfocusEditDefaultLifeTime) ON_CBN_SELCHANGE(IDC_EDIT_LIFETIME_D, OnSelchangeEditDefaultLifeTime) ON_EN_KILLFOCUS(IDC_EDIT_LIFETIME_H, OnEditKillfocusEditDefaultLifeTime) ON_CBN_SELCHANGE(IDC_EDIT_LIFETIME_H, OnSelchangeEditDefaultLifeTime) ON_EN_KILLFOCUS(IDC_EDIT_LIFETIME_M, OnEditKillfocusEditDefaultLifeTime) ON_CBN_SELCHANGE(IDC_EDIT_LIFETIME_M, OnSelchangeEditDefaultLifeTime) ON_EN_KILLFOCUS(IDC_EDIT_RENEWTILL_D, OnEditKillfocusEditDefaultRenewTill) ON_CBN_SELCHANGE(IDC_EDIT_RENEWTILL_D, OnSelchangeEditDefaultRenewTill) ON_EN_KILLFOCUS(IDC_EDIT_RENEWTILL_H, OnEditKillfocusEditDefaultRenewTill) ON_CBN_SELCHANGE(IDC_EDIT_RENEWTILL_H, OnSelchangeEditDefaultRenewTill) ON_EN_KILLFOCUS(IDC_EDIT_RENEWTILL_M, OnEditKillfocusEditDefaultRenewTill) ON_CBN_SELCHANGE(IDC_EDIT_RENEWTILL_M, OnSelchangeEditDefaultRenewTill) ON_EN_KILLFOCUS(IDC_EDIT_LIFE_MIN_D, OnEditKillfocusEditDefaultLifeMin) ON_CBN_SELCHANGE(IDC_EDIT_LIFE_MIN_D, OnSelchangeEditDefaultLifeMin) ON_EN_KILLFOCUS(IDC_EDIT_LIFE_MIN_H, OnEditKillfocusEditDefaultLifeMin) ON_CBN_SELCHANGE(IDC_EDIT_LIFE_MIN_H, OnSelchangeEditDefaultLifeMin) ON_EN_KILLFOCUS(IDC_EDIT_LIFE_MIN_M, OnEditKillfocusEditDefaultLifeMin) ON_CBN_SELCHANGE(IDC_EDIT_LIFE_MIN_M, OnSelchangeEditDefaultLifeMin) ON_EN_KILLFOCUS(IDC_EDIT_LIFE_MAX_D, OnEditKillfocusEditDefaultLifeMax) ON_CBN_SELCHANGE(IDC_EDIT_LIFE_MAX_D, OnSelchangeEditDefaultLifeMax) ON_EN_KILLFOCUS(IDC_EDIT_LIFE_MAX_H, OnEditKillfocusEditDefaultLifeMax) ON_CBN_SELCHANGE(IDC_EDIT_LIFE_MAX_H, OnSelchangeEditDefaultLifeMax) ON_EN_KILLFOCUS(IDC_EDIT_LIFE_MAX_M, OnEditKillfocusEditDefaultLifeMax) ON_CBN_SELCHANGE(IDC_EDIT_LIFE_MAX_M, OnSelchangeEditDefaultLifeMax) ON_EN_KILLFOCUS(IDC_EDIT_RENEW_MIN_D, OnEditKillfocusEditDefaultRenewMin) ON_CBN_SELCHANGE(IDC_EDIT_RENEW_MIN_D, OnSelchangeEditDefaultRenewMin) ON_EN_KILLFOCUS(IDC_EDIT_RENEW_MIN_H, OnEditKillfocusEditDefaultRenewMin) ON_CBN_SELCHANGE(IDC_EDIT_RENEW_MIN_H, OnSelchangeEditDefaultRenewMin) ON_EN_KILLFOCUS(IDC_EDIT_RENEW_MIN_M, OnEditKillfocusEditDefaultRenewMin) ON_CBN_SELCHANGE(IDC_EDIT_RENEW_MIN_M, OnSelchangeEditDefaultRenewMin) ON_EN_KILLFOCUS(IDC_EDIT_RENEW_MAX_D, OnEditKillfocusEditDefaultRenewMax) ON_CBN_SELCHANGE(IDC_EDIT_RENEW_MAX_D, OnSelchangeEditDefaultRenewMax) ON_EN_KILLFOCUS(IDC_EDIT_RENEW_MAX_H, OnEditKillfocusEditDefaultRenewMax) ON_CBN_SELCHANGE(IDC_EDIT_RENEW_MAX_H, OnSelchangeEditDefaultRenewMax) ON_EN_KILLFOCUS(IDC_EDIT_RENEW_MAX_M, OnEditKillfocusEditDefaultRenewMax) ON_CBN_SELCHANGE(IDC_EDIT_RENEW_MAX_M, OnSelchangeEditDefaultRenewMax) ON_BN_CLICKED(IDC_CHECK_REQUEST_KRB4, OnCheckUseKrb4) ON_BN_CLICKED(IDC_CHECK_PRESERVE_KINIT_OPTIONS, OnCheckKinitPreserve) //}}AFX_MSG_MAP END_MESSAGE_MAP() �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������krb5-1.16/src/windows/leash/Krb4EditDomainRealmList.h�����������������������������������������������0000644�0007046�0000145�00000004435�13211554426�022307� 0����������������������������������������������������������������������������������������������������ustar �ghudson�������������������������libuuid����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// ************************************************************************************** // File: Krb4EditDomainRealmList.h // By: Arthur David Leather // Created: 12/02/98 // Copyright @1998 Massachusetts Institute of Technology - All rights reserved. // Description: H file for Krb4EditDomainRealmList.cpp. Contains variables and functions // for Kerberos Four Properites // // History: // // MM/DD/YY Inits Description of Change // 12/02/98 ADL Original // ************************************************************************************** #if !defined(AFX_KRB4EDITDOMAINREALMLIST_H__F4D41684_96A4_11D2_94E2_0000861B8A3C__INCLUDED_) #define AFX_KRB4EDITDOMAINREALMLIST_H__F4D41684_96A4_11D2_94E2_0000861B8A3C__INCLUDED_ #if _MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000 // CKrb4EditDomainRealmList.h : header file // ///////////////////////////////////////////////////////////////////////////// // CKrb4EditDomainRealmList dialog class CKrb4EditDomainRealmList : public CDialog { // Construction private: CString m_editItem; CString m_initRealm; CString m_newRealm; CString m_initDomainHost; CString m_newDomainHost; BOOL m_startup; public: CKrb4EditDomainRealmList(LPSTR editItem, CWnd* pParent = NULL); CString GetEditedItem() {return m_editItem;} CString GetRealm() {return m_newRealm;} CString GetDomainHost() {return m_newDomainHost;} // Dialog Data //{{AFX_DATA(CKrb4EditDomainRealmList) enum { IDD = IDD_KRB4_EDIT_DOMAINREALMNAME }; // NOTE: the ClassWizard will add data members here //}}AFX_DATA // Overrides // ClassWizard generated virtual function overrides //{{AFX_VIRTUAL(CKrb4EditDomainRealmList) protected: virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support //}}AFX_VIRTUAL // Implementation protected: // Generated message map functions //{{AFX_MSG(CKrb4EditDomainRealmList) afx_msg void OnShowWindow(BOOL bShow, UINT nStatus); virtual BOOL OnInitDialog(); afx_msg void OnChangeEditDefaultRealm(); afx_msg void OnChangeEditRealmHostname(); virtual void OnOK(); //}}AFX_MSG DECLARE_MESSAGE_MAP() }; //{{AFX_INSERT_LOCATION}} // Microsoft Visual C++ will insert additional declarations immediately before the previous line. #endif // !defined(AFX_KRB4EDITDOMAINREALMLIST_H__F4D41684_96A4_11D2_94E2_0000861B8A3C__INCLUDED_) �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������krb5-1.16/src/windows/leash/out2con.h���������������������������������������������������������������0000644�0007046�0000145�00000001477�13211554426�017326� 0����������������������������������������������������������������������������������������������������ustar �ghudson�������������������������libuuid����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#ifndef OUT2CON_H #define OUT2CON_H /* Call CreateConsoleEcho() to create a console and begin echoing stdout to it. * The original stream (if any) will still receive output from stdout. * Call DestroyConsoleEcho() to stop echoing stdout to the console. * The original stream continues to receive stdout. * * WARNING: it is not safe to use stdout from another thread during * CreateConsoleEcho() or DestroyConsoleEcho() */ class ConsoleEcho; ConsoleEcho * CreateConsoleEcho(); void DestroyConsoleEcho(ConsoleEcho *consoleEcho); // Convenience class to automatically echo to console within a scope class AutoConsoleEcho { public: AutoConsoleEcho() : m_echo(CreateConsoleEcho()) { } ~AutoConsoleEcho() { DestroyConsoleEcho(m_echo); } private: ConsoleEcho* m_echo; }; #endif �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������krb5-1.16/src/windows/leash/KrbProperties.cpp�������������������������������������������������������0000644�0007046�0000145�00000005254�13211554426�021060� 0����������������������������������������������������������������������������������������������������ustar �ghudson�������������������������libuuid����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// File: KrbProperties.cpp // By: Arthur David Leather // Created: 12/02/98 // Copyright @1998 Massachusetts Institute of Technology - All rights reserved. // Description: CPP file for KrbProperties.h. Contains variables and functions // for Kerberos Four Properties // // History: // // MM/DD/YY Inits Description of Change // 02/01/98 ADL Original // ************************************************************************************** #include "stdafx.h" #include "KrbProperties.h" #include "Krb4Properties.h" #include "Leash.h" #include "wshelper.h" #include "lglobals.h" #include "reminder.h" CHAR CKrbProperties::m_krbPath[MAX_PATH]; CHAR CKrbProperties::m_krbrealmPath[MAX_PATH]; BOOL CKrbProperties::KrbPropertiesOn; /////////////////////////////////////////////////////////////////////// // CKrbProperties IMPLEMENT_DYNAMIC(CKrbProperties, CPropertySheet) CKrbProperties::CKrbProperties(UINT nIDCaption, CWnd* pParentWnd, UINT iSelectPage) :CPropertySheet(nIDCaption, pParentWnd, iSelectPage) { } CKrbProperties::CKrbProperties(LPCTSTR pszCaption, CWnd* pParentWnd, UINT iSelectPage) :CPropertySheet(pszCaption, pParentWnd, iSelectPage) { KrbPropertiesOn = FALSE; #ifdef COMMENT // If this will not be fatal, then it does not need to be performed here. if (CLeashApp::m_hKrb5DLL) { char *realm = NULL; pkrb5_get_default_realm(CLeashApp::m_krbv5_context, &realm); if (!realm) { MessageBox("CKrbProperties::Unable to determine default Kerberos REALM.\ \n Consult your Administrator!", "Error", MB_OK); // I don't think this is necessarily fatal. - jaltman // return; } } #endif /* COMMENT */ #ifndef NO_KRB4 CLeashApp::GetKrb4ConFile(m_krbPath,sizeof(m_krbPath)); CLeashApp::GetKrb4RealmFile(m_krbrealmPath,sizeof(m_krbrealmPath)); #endif AddPage(&m_configOptions); AddPage(&m_miscConfigOpt); #ifndef NO_KRB4 if (CLeashApp::m_hKrb4DLL && !CLeashApp::m_hKrb5DLL) { AddPage(&m_krb4RealmHostMaintenance); AddPage(&m_krb4DomainRealmMaintenance); } else #endif if (CLeashApp::m_hKrb5DLL) { AddPage(&m_realmHostMaintenance); AddPage(&m_domainRealmMaintenance); } KrbPropertiesOn = TRUE; } CKrbProperties::~CKrbProperties() { KrbPropertiesOn = FALSE; } void CKrbProperties::OnHelp() { AfxGetApp()->WinHelp(HID_KERBEROS_PROPERTIES_COMMAND); } BEGIN_MESSAGE_MAP(CKrbProperties, CPropertySheet) //{{AFX_MSG_MAP(CKrbProperties) // NOTE - the ClassWizard will add and remove mapping macros here. ON_COMMAND(ID_HELP, OnHelp) //}}AFX_MSG_MAP END_MESSAGE_MAP() /////////////////////////////////////////////////////////////////////// // CKrbProperties message handlers ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������krb5-1.16/src/windows/leash/KrbRealmHostMaintenance.h�����������������������������������������������0000644�0007046�0000145�00000005721�13211554426�022431� 0����������������������������������������������������������������������������������������������������ustar �ghudson�������������������������libuuid����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// ************************************************************************************** // File: KrbRealmHostMaintenance.h // By: Arthur David Leather // Created: 12/02/98 // Copyright @1998 Massachusetts Institute of Technology - All rights reserved. // Description: H file for KrbRealmHostMaintenance.cpp. Contains variables and functions // for Kerberos Four and Five Properties // // History: // // MM/DD/YY Inits Description of Change // 12/02/98 ADL Original // ************************************************************************************** #if !defined(AFX_KRBREALMNAMEMAINTENANCE_H__2FE711C3_8E9A_11D2_94C5_0000861B8A3C__INCLUDED_) #define AFX_KRBREALMNAMEMAINTENANCE_H__2FE711C3_8E9A_11D2_94C5_0000861B8A3C__INCLUDED_ #if _MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000 ///////////////////////////////////////////////////////////////////////////// // CKrbRealmHostMaintenance dialog #include "resource.h" #include "CLeashDragListBox.h" #define MAXLINE 256 class CKrbRealmHostMaintenance : public CPropertyPage { // Construction private: DECLARE_DYNCREATE(CKrbRealmHostMaintenance) CHAR lineBuf[MAXLINE]; CString m_theAdminServerMarked; CString m_theAdminServer; BOOL m_isRealmListBoxInFocus; BOOL m_isStart; BOOL m_initDnsKdcLookup; BOOL m_newDnsKdcLookup; bool OnButtonKdchostAddInternal(); //void ResetDefaultRealmComboBox(); public: //CKrbRealmHostMaintenance(CWnd* pParent = NULL); // standard constructor CKrbRealmHostMaintenance(); virtual ~CKrbRealmHostMaintenance(); // Dialog Data //{{AFX_DATA(CKrbRealmHostMaintenance) enum { IDD = IDD_KRB_REALMHOST_MAINT }; CListBox m_KDCRealmList; CLeashDragListBox m_KDCHostList; //}}AFX_DATA // Overrides // ClassWizard generated virtual function overrides //{{AFX_VIRTUAL(CKrbRealmHostMaintenance) public: virtual BOOL PreTranslateMessage(MSG* pMsg); protected: virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support //}}AFX_VIRTUAL // Implementation protected: // Generated message map functions //{{AFX_MSG(CKrbRealmHostMaintenance) virtual BOOL OnInitDialog(); virtual BOOL OnApply(); virtual void OnCancel(); afx_msg void OnButtonRealmHostAdd(); afx_msg void OnButtonRealmHostEdit(); afx_msg void OnButtonRealmHostRemove(); afx_msg void OnSelchangeListKdcRealm(); afx_msg void OnButtonAdminserver(); afx_msg void OnSetfocusListKdcRealm(); afx_msg void OnButtonKdchostAdd(); afx_msg void OnButtonKdchostRemove(); afx_msg void OnButtonRemoveAdminserver(); afx_msg void OnSelchangeListKdcHost(); afx_msg void OnButtonKdchostEdit(); afx_msg void OnDblclkListKdcRealm(); afx_msg void OnDblclkListKdcHost(); afx_msg void OnButtonRealmhostMaintHelp(); afx_msg void OnCheckDnsKdcLookup(); //}}AFX_MSG DECLARE_MESSAGE_MAP() }; //{{AFX_INSERT_LOCATION}} // Microsoft Visual C++ will insert additional declarations immediately before the previous line. #endif // !defined(AFX_KRBREALMNAMEMAINTENANCE_H__2FE711C3_8E9A_11D2_94C5_0000861B8A3C__INCLUDED_) �����������������������������������������������krb5-1.16/src/windows/leash/LeashUICommandHandler.cpp�����������������������������������������������0000644�0007046�0000145�00000024310�13211554426�022346� 0����������������������������������������������������������������������������������������������������ustar �ghudson�������������������������libuuid����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// -*- mode: c++; c-basic-offset: 4; indent-tabs-mode: nil -*- // leash/LeashUICommandHandler.cpp - implements IUICommandHandler interfaces // // Copyright (C) 2014 by the Massachusetts Institute of Technology. // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // // * Redistributions in binary form must reproduce the above copyright // notice, this list of conditions and the following disclaimer in // the documentation and/or other materials provided with the // distribution. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS // FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE // COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, // INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) // HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, // STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED // OF THE POSSIBILITY OF SUCH DAMAGE. // This file contains the class implementation of the leash implementation // of the UICommandHandler interface. Its primary responsibility is // to accept UI events (i.e., button presses) and perform the // corresponding actions to the leash data structures and display // presentation. #include <UIRibbon.h> #include <UIRibbonPropertyHelpers.h> #include "kfwribbon.h" #include "LeashUICommandHandler.h" #include "resource.h" #include <loadfuncs-leash.h> // Allowing mixed-case realms has both a machine and user-specific knob, // and thus needs a function to manage it. extern DWORD Leash_get_default_uppercaserealm(); extern DECL_FUNC_PTR(Leash_get_default_uppercaserealm); HRESULT LeashUICommandHandler::CreateInstance(IUICommandHandler **out, HWND hwnd) { LeashUICommandHandler *handler; if (out == NULL) return E_POINTER; handler = new LeashUICommandHandler(); handler->mainwin = hwnd; *out = static_cast<IUICommandHandler *>(handler); return S_OK; } ULONG LeashUICommandHandler::AddRef() { return InterlockedIncrement(&refcnt); } ULONG LeashUICommandHandler::Release() { LONG tmp; tmp = InterlockedDecrement(&refcnt); if (tmp == 0) delete this; return tmp; } HRESULT LeashUICommandHandler::QueryInterface(REFIID iid, void **ppv) { if (ppv == NULL) return E_POINTER; if (iid == __uuidof(IUnknown)) { *ppv = static_cast<IUnknown*>(this); } else if (iid == __uuidof(IUICommandHandler)) { *ppv = static_cast<IUICommandHandler*>(this); } else { *ppv = NULL; return E_NOINTERFACE; } AddRef(); return S_OK; } // Called by the framework when a control is activated that may require // an action to be taken, such as a button being pressed or a checkbox // state flipped. (It is not called when the user changes tabs on the // ribbon.) Just proxy these commands through to the existing MFC // handlers by sendding the appropriate message to the main window. // Action only needs to be taken on the EXECUTE verb, so we can // ignore the additional properties surrouding the action, which would // be relevant for other verbs. // // The commandIds are taken from the XML ribbon description. HRESULT LeashUICommandHandler::Execute(UINT32 commandId, UI_EXECUTIONVERB verb, const PROPERTYKEY *key, const PROPVARIANT *currentValue, IUISimplePropertySet *commandExecutionProperties) { if (verb != UI_EXECUTIONVERB_EXECUTE) return E_NOTIMPL; switch(commandId) { case cmdGetTicketButton: SendMessage(mainwin, WM_COMMAND, MAKEWPARAM(ID_INIT_TICKET, 1), 0); break; case cmdRenewTicketButton: SendMessage(mainwin, WM_COMMAND, MAKEWPARAM(ID_RENEW_TICKET, 1), 0); break; case cmdDestroyTicketButton: SendMessage(mainwin, WM_COMMAND, MAKEWPARAM(ID_DESTROY_TICKET, 1), 0); break; case cmdMakeDefaultButton: SendMessage(mainwin, WM_COMMAND, MAKEWPARAM(ID_MAKE_DEFAULT, 1), 0); break; case cmdChangePasswordButton: SendMessage(mainwin, WM_COMMAND, MAKEWPARAM(ID_CHANGE_PASSWORD, 1), 0); break; case cmdIssuedCheckBox: SendMessage(mainwin, WM_COMMAND, MAKEWPARAM(ID_TIME_ISSUED, 1), 0); break; case cmdRenewUntilCheckBox: SendMessage(mainwin, WM_COMMAND, MAKEWPARAM(ID_RENEWABLE_UNTIL, 1), 0); break; case cmdValidUntilCheckBox: SendMessage(mainwin, WM_COMMAND, MAKEWPARAM(ID_VALID_UNTIL, 1), 0); break; case cmdEncTypeCheckBox: SendMessage(mainwin, WM_COMMAND, MAKEWPARAM(ID_ENCRYPTION_TYPE, 1), 0); break; case cmdFlagsCheckBox: SendMessage(mainwin, WM_COMMAND, MAKEWPARAM(ID_SHOW_TICKET_FLAGS, 1), 0); break; case cmdCcacheNameCheckBox: SendMessage(mainwin, WM_COMMAND, MAKEWPARAM(ID_CCACHE_NAME, 1), 0); break; case cmdAutoRenewCheckBox: SendMessage(mainwin, WM_COMMAND, MAKEWPARAM(ID_AUTO_RENEW, 1), 0); break; case cmdExpireAlarmCheckBox: SendMessage(mainwin, WM_COMMAND, MAKEWPARAM(ID_LOW_TICKET_ALARM, 1), 0); break; case cmdDestroyOnExitCheckBox: SendMessage(mainwin, WM_COMMAND, MAKEWPARAM(ID_KILL_TIX_ONEXIT, 1), 0); break; case cmdMixedCaseCheckBox: SendMessage(mainwin, WM_COMMAND, MAKEWPARAM(ID_UPPERCASE_REALM, 1), 0); break; case cmdHelp: SendMessage(mainwin, WM_COMMAND, MAKEWPARAM(ID_HELP_LEASH32, 1), 0); break; case cmdAbout: // ID_APP_ABOUT (0xe140) is defined in afxres.h, an MFC header SendMessage(mainwin, WM_COMMAND, MAKEWPARAM(0xe140, 1), 0); break; case cmdExit: // Save Ribbon customizations here, since this is the only // path to a clean exit from the application. if (app != NULL) app->SaveRibbonState(); // ID_APP_EXIT (0xe141) is defined in afxres.h, an MFC header SendMessage(mainwin, WM_COMMAND, MAKEWPARAM(0xe141, 1), 0); break; default: // Lots of commands we don't need to pass on return S_OK; } return S_OK; } // Looks up a given registry key in this application's Settings space // (analogous to CWinApp::GetProfileInt()), converting it to a // (boolean) PROPVARIANT which is returned in *out. Uses the given // default value if the registry key cannot be loaded. static HRESULT RegKeyToProperty(const char *regkey, bool default, PROPVARIANT *out) { DWORD bsize = sizeof(DWORD), enabled; LONG code; code = RegGetValue(HKEY_CURRENT_USER, "Software\\MIT\\MIT Kerberos\\Settings", regkey, RRF_RT_DWORD, NULL, &enabled, &bsize); if (code == ERROR_FILE_NOT_FOUND) { code = ERROR_SUCCESS; enabled = default ? 1 : 0; } if (FAILED(code) || bsize != sizeof(enabled)) return E_FAIL; return UIInitPropertyFromBoolean(UI_PKEY_BooleanValue, enabled, out); } // Called by the framework when the value of a property needs to be // re-evaluated, e.g., if it has been explicitly invalidated, or at // program startup. This is the way to specify the initial/default // state for ribbon elements which have state, such as checkboxes. // The registry values which are modified by the MFC checkbox // action handlers can be read directly from here in order to present // a consistent visual interface. The MFC handlers only write to the // registry when a value is changed, though, so we must duplicate // the default values which are hardcoded in CLeashView::sm_viewColumns[] // and elsewhere in LeashView.cpp. HRESULT LeashUICommandHandler::UpdateProperty(UINT32 commandId, REFPROPERTYKEY key, const PROPVARIANT *currentValue, PROPVARIANT *newValue) { if (key != UI_PKEY_BooleanValue) return E_NOTIMPL; // These default values duplicate those hardcoded in // CLeashView::sm_viewColumns[] and elsewhere in LeashView.cpp. switch(commandId) { case cmdIssuedCheckBox: return RegKeyToProperty("Issued", false, newValue); case cmdRenewUntilCheckBox: return RegKeyToProperty("Renewable Until", false, newValue); case cmdValidUntilCheckBox: return RegKeyToProperty("Valid Until", true, newValue); case cmdEncTypeCheckBox: return RegKeyToProperty("Encryption Type", false, newValue); case cmdFlagsCheckBox: return RegKeyToProperty("Flags", false, newValue); case cmdCcacheNameCheckBox: return RegKeyToProperty("Credential Cache", false, newValue); case cmdAutoRenewCheckBox: return RegKeyToProperty("AutoRenewTickets", true, newValue); case cmdExpireAlarmCheckBox: return RegKeyToProperty("LowTicketAlarm", true, newValue); case cmdDestroyOnExitCheckBox: return RegKeyToProperty("DestroyTicketsOnExit", false, newValue); case cmdMixedCaseCheckBox: return UIInitPropertyFromBoolean(UI_PKEY_BooleanValue, pLeash_get_default_uppercaserealm(), newValue); default: return E_NOTIMPL; } return E_NOTIMPL; } ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������krb5-1.16/src/windows/leash/Krb4AddToDomainRealmList.cpp��������������������������������������������0000644�0007046�0000145�00000005331�13211554426�022744� 0����������������������������������������������������������������������������������������������������ustar �ghudson�������������������������libuuid����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// File: Krb4AddToDomainRealmList.cpp // By: Arthur David Leather // Created: 12/02/98 // Copyright @1998 Massachusetts Institute of Technology - All rights reserved. // Description: CPP file for Krb4AddToDomainRealmList.h. Contains variables and functions // for Kerberos Four Properties // // History: // // MM/DD/YY Inits Description of Change // 12/02/98 ADL Original // ************************************************************************************** #include "stdafx.h" #include "leash.h" #include "Krb4AddToDomainRealmList.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif ///////////////////////////////////////////////////////////////////////////// // CKrb4AddToDomainRealmList dialog CKrb4AddToDomainRealmList::CKrb4AddToDomainRealmList(CWnd* pParent /*=NULL*/) : CDialog(CKrb4AddToDomainRealmList::IDD, pParent) { m_newRealm = _T(""); m_newDomainHost = _T(""); m_startup = TRUE; //{{AFX_DATA_INIT(CKrb4AddToDomainRealmList) // NOTE: the ClassWizard will add member initialization here //}}AFX_DATA_INIT } void CKrb4AddToDomainRealmList::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); //{{AFX_DATA_MAP(CKrb4AddToDomainRealmList) // NOTE: the ClassWizard will add DDX and DDV calls here //}}AFX_DATA_MAP } BEGIN_MESSAGE_MAP(CKrb4AddToDomainRealmList, CDialog) //{{AFX_MSG_MAP(CKrb4AddToDomainRealmList) ON_WM_SHOWWINDOW() ON_EN_CHANGE(IDC_EDIT_DOMAINHOSTNAME, OnChangeEditDomainhostname) ON_EN_CHANGE(IDC_EDIT_DOMAINREALMNAME, OnChangeEditDomainrealmname) //}}AFX_MSG_MAP END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CKrb4AddToDomainRealmList message handlers void CKrb4AddToDomainRealmList::OnChangeEditDomainhostname() { if (!m_startup) GetDlgItemText(IDC_EDIT_DOMAINHOSTNAME, m_newDomainHost); } void CKrb4AddToDomainRealmList::OnChangeEditDomainrealmname() { if (!m_startup) GetDlgItemText(IDC_EDIT_DOMAINREALMNAME, m_newRealm); } void CKrb4AddToDomainRealmList::OnOK() { //if (m_newRealm.IsEmpty) m_newRealm.TrimLeft(); m_newRealm.TrimRight(); m_newDomainHost.TrimLeft(); m_newDomainHost.TrimRight(); if (m_newRealm.IsEmpty() || m_newDomainHost.IsEmpty()) { // stay MessageBox("OnOK::Both Realm and Domain-Host fields must be filled in!", "Leash", MB_OK); } else if (-1 != m_newRealm.Find(' ') || -1 != m_newDomainHost.Find(' ')) { // stay MessageBox("OnOK::Illegal space found!", "Leash", MB_OK); } else CDialog::OnOK(); // exit } void CKrb4AddToDomainRealmList::OnCancel() { CDialog::OnCancel(); } void CKrb4AddToDomainRealmList::OnShowWindow(BOOL bShow, UINT nStatus) { CDialog::OnShowWindow(bShow, nStatus); m_startup = FALSE; } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������krb5-1.16/src/windows/leash/LeashAboutBox.cpp�������������������������������������������������������0000644�0007046�0000145�00000025312�13211554426�020762� 0����������������������������������������������������������������������������������������������������ustar �ghudson�������������������������libuuid����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//***************************************************************************** // File: LeashAboutBox.cpp // By: Arthur David Leather // Created: 12/02/98 // Copyright: @1998 Massachusetts Institute of Technology - All rights // reserved. // Description: CPP file for LeashAboutBox.h. Contains variables and functions // for the Leash About Box Dialog Box // // History: // // MM/DD/YY Inits Description of Change // 12/02/98 ADL Original //***************************************************************************** #include "stdafx.h" #include "leash.h" #include "LeashAboutBox.h" #include "reminder.h" #include "lglobals.h" #include "psapi.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif ///////////////////////////////////////////////////////////////////////////// // CLeashAboutBox dialog CLeashAboutBox::CLeashAboutBox(CWnd* pParent /*=NULL*/) : CDialog(CLeashAboutBox::IDD, pParent) , m_bListModules(FALSE) { m_missingFileError = FALSE; //{{AFX_DATA_INIT(CLeashAboutBox) m_fileItem = _T(""); //}}AFX_DATA_INIT } void CLeashAboutBox::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); //{{AFX_DATA_MAP(CLeashAboutBox) DDX_Control(pDX, IDC_PROPERTIES, m_propertiesButton); DDX_Control(pDX, IDC_LEASH_MODULES, m_radio_LeashDLLs); DDX_Control(pDX, IDC_LEASH_MODULE_LB, m_LB_DLLsLoaded); DDX_LBString(pDX, IDC_LEASH_MODULE_LB, m_fileItem); //}}AFX_DATA_MAP } BEGIN_MESSAGE_MAP(CLeashAboutBox, CDialog) //{{AFX_MSG_MAP(CLeashAboutBox) ON_WM_HSCROLL() ON_LBN_SELCHANGE(IDC_LEASH_MODULE_LB, OnSelchangeLeashModuleLb) ON_BN_CLICKED(IDC_ALL_MODULES, OnAllModules) ON_BN_CLICKED(IDC_LEASH_MODULES, OnLeashModules) ON_LBN_DBLCLK(IDC_LEASH_MODULE_LB, OnDblclkLeashModuleLb) ON_BN_CLICKED(IDC_PROPERTIES, OnProperties) ON_LBN_SETFOCUS(IDC_LEASH_MODULE_LB, OnSetfocusLeashModuleLb) ON_BN_CLICKED(IDC_NOT_LOADED_MODULES, OnNotLoadedModules) //}}AFX_MSG_MAP END_MESSAGE_MAP() ; ///////////////////////////////////////////////////////////////////////////// // CLeashAboutBox message handlers void CLeashAboutBox::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar) { CDialog::OnHScroll(nSBCode, nPos, pScrollBar); } BOOL CLeashAboutBox::GetModules95(DWORD processID, BOOL allModules) { char szModNames[1024]; MODULEENTRY32 me32 = {0}; HANDLE hProcessSnap = NULL; hProcessSnap = pCreateToolhelp32Snapshot(TH32CS_SNAPMODULE, processID); if (hProcessSnap == (HANDLE)-1) return FALSE; me32.dwSize = sizeof(MODULEENTRY32); if (pModule32First(hProcessSnap, &me32)) { do { lstrcpy(szModNames, me32.szExePath); strupr(szModNames); if (!allModules) { if (!strstr(szModNames, "SYSTEM")) m_LB_DLLsLoaded.AddString(me32.szExePath); } else m_LB_DLLsLoaded.AddString(me32.szExePath); } while (pModule32Next(hProcessSnap, &me32)); } return TRUE; } void CLeashAboutBox::GetModulesNT(DWORD processID, BOOL allModules) { char checkName[1024]; HMODULE hMods[1024]; HANDLE hProcess; DWORD cbNeeded; unsigned int i; // Get a list of all the modules in this process. hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, processID); if (pEnumProcessModules(hProcess, hMods, sizeof(hMods), &cbNeeded)) { for (i = 0; i < (cbNeeded / sizeof(HMODULE)); i++) { char szModName[2048]; // Get the full path to the module's file. if (pGetModuleFileNameEx(hProcess, hMods[i], szModName, sizeof(szModName))) { lstrcpy(checkName, szModName); strupr(checkName); if (!allModules) { if (!strstr(checkName, "SYSTEM32")) m_LB_DLLsLoaded.AddString(szModName); } else m_LB_DLLsLoaded.AddString(szModName); } } } CloseHandle(hProcess); } void CLeashAboutBox::HighlightFirstItem() { UINT numModules = m_LB_DLLsLoaded.GetCount(); CHAR numModulesBuffer [25]; _itoa(numModules, numModulesBuffer, 10); if (numModules) { m_LB_DLLsLoaded.SetCurSel(0); m_propertiesButton.EnableWindow(); } else m_propertiesButton.EnableWindow(FALSE); GetDlgItem(IDC_STATIC_NO_OF_MODULES)->SetWindowText(numModulesBuffer); } DWORD CLeashAboutBox::SetVersionInfo( UINT id_version, UINT id_copyright ) { TCHAR filename[1024]; DWORD dwVersionHandle; LPVOID pVersionInfo = 0; DWORD retval = 0; LPDWORD pLangInfo = 0; LPTSTR szVersion = 0; LPTSTR szCopyright = 0; UINT len = 0; TCHAR sname_version[] = TEXT("FileVersion"); TCHAR sname_copyright[] = TEXT("LegalCopyright"); TCHAR szVerQ[(sizeof("\\StringFileInfo\\12345678\\") + max(sizeof(sname_version) / sizeof(TCHAR), sizeof(sname_copyright) / sizeof(TCHAR)))]; TCHAR * cp = szVerQ; if (!GetModuleFileName(NULL, filename, sizeof(filename))) return GetLastError(); DWORD size = GetFileVersionInfoSize(filename, &dwVersionHandle); if (!size) return GetLastError(); pVersionInfo = malloc(size); if (!pVersionInfo) return ERROR_NOT_ENOUGH_MEMORY; if (!GetFileVersionInfo(filename, dwVersionHandle, size, pVersionInfo)) { retval = GetLastError(); goto cleanup; } if (!VerQueryValue(pVersionInfo, TEXT("\\VarFileInfo\\Translation"), (LPVOID*)&pLangInfo, &len)) { retval = GetLastError(); goto cleanup; } cp += wsprintf(szVerQ, TEXT("\\StringFileInfo\\%04x%04x\\"), LOWORD(*pLangInfo), HIWORD(*pLangInfo)); lstrcpy(cp, sname_version); if (!VerQueryValue(pVersionInfo, szVerQ, (LPVOID*)&szVersion, &len)) { retval = GetLastError() || ERROR_NOT_ENOUGH_MEMORY; goto cleanup; } TCHAR version[100]; _sntprintf(version, sizeof(version), TEXT("MIT Kerberos Version %s"), szVersion); version[sizeof(version) - 1] = 0; GetDlgItem(id_version)->SetWindowText(version); lstrcpy(cp, sname_copyright); if (!VerQueryValue(pVersionInfo, szVerQ, (LPVOID*)&szCopyright, &len)) { retval = GetLastError() || ERROR_NOT_ENOUGH_MEMORY; goto cleanup; } GetDlgItem(id_copyright)->SetWindowText(szCopyright); cleanup: if (pVersionInfo) free(pVersionInfo); return retval; } BOOL CLeashAboutBox::OnInitDialog() { CDialog::OnInitDialog(); // XXX - we need to add some sensible behavior on error. // We need to get the version info and display it... SetVersionInfo(IDC_ABOUT_VERSION, IDC_ABOUT_COPYRIGHT); if (!CLeashApp::m_hToolHelp32 && !CLeashApp::m_hPsapi) m_missingFileError = TRUE; if (m_bListModules) { m_radio_LeashDLLs.SetCheck(TRUE); OnLeashModules(); HighlightFirstItem(); if (!CLeashApp::m_hPsapi) GetDlgItem(IDC_PROPERTIES)->EnableWindow(FALSE); } else { m_radio_LeashDLLs.ShowWindow(SW_HIDE); GetDlgItem(IDC_NOT_LOADED_MODULES)->ShowWindow(SW_HIDE); GetDlgItem(IDC_ALL_MODULES)->ShowWindow(SW_HIDE); GetDlgItem(IDC_PROPERTIES)->ShowWindow(SW_HIDE); GetDlgItem(IDC_STATIC_MODULES_LOADED)->ShowWindow(SW_HIDE); GetDlgItem(IDC_STATIC_NO_OF_MODULES)->ShowWindow(SW_HIDE); m_LB_DLLsLoaded.ShowWindow(SW_HIDE); // shrink window, move 'OK' button const int hideDiff = 150; RECT okRect; CWnd* pOK = GetDlgItem(IDOK); pOK->GetWindowRect(&okRect); ScreenToClient(&okRect); pOK->SetWindowPos(0, okRect.left, okRect.top - hideDiff, 0, 0, SWP_NOZORDER | SWP_NOSIZE); RECT dlgRect; GetWindowRect( &dlgRect ); SetWindowPos(0,0,0, dlgRect.right-dlgRect.left, dlgRect.bottom-dlgRect.top - hideDiff, SWP_NOZORDER|SWP_NOMOVE); } return TRUE; // return TRUE unless you set the focus to a control // EXCEPTION: OCX Property Pages should return FALSE } void CLeashAboutBox::OnSelchangeLeashModuleLb() { } void CLeashAboutBox::OnAllModules() { if (!CLeashApp::m_hToolHelp32 && !CLeashApp::m_hPsapi) return; //error m_LB_DLLsLoaded.ResetContent(); if (!CLeashApp::m_hPsapi) GetModules95(GetCurrentProcessId()); //m_LB_DLLsLoaded.AddString("Doesn't work in Windows 95"); else GetModulesNT(GetCurrentProcessId()); HighlightFirstItem(); } void CLeashAboutBox::OnLeashModules() { if (!CLeashApp::m_hToolHelp32 && !CLeashApp::m_hPsapi) return; // error m_LB_DLLsLoaded.ResetContent(); if (!CLeashApp::m_hPsapi) GetModules95(GetCurrentProcessId(), FALSE); //m_LB_DLLsLoaded.AddString("Doesn't work in Windows 95"); else GetModulesNT(GetCurrentProcessId(), FALSE); HighlightFirstItem(); } void CLeashAboutBox::OnNotLoadedModules() { m_LB_DLLsLoaded.ResetContent(); #ifndef NO_KRB4 if (!CLeashApp::m_hKrb4DLL) m_LB_DLLsLoaded.AddString(KERB4DLL); #endif if (!CLeashApp::m_hKrb5DLL) m_LB_DLLsLoaded.AddString(KERB5DLL); // NOTE: If the snippet below is commented back in, // it should read // if (!CLeashApp::m_hAfsDLL) // m_LB_DLLsLoaded.AddString(AFSAuthentDLL()); //if (!CLeashApp::m_hAfsDLL) //m_LB_DLLsLoaded.AddString(ASFDLL); HighlightFirstItem(); } void CLeashAboutBox::OnDblclkLeashModuleLb() { m_LB_DLLsLoaded.GetText(m_LB_DLLsLoaded.GetCurSel(), m_fileItem); SHELLEXECUTEINFO sei; ZeroMemory(&sei,sizeof(sei)); sei.cbSize = sizeof(sei); sei.lpFile = m_fileItem; sei.lpVerb = "properties"; sei.fMask = SEE_MASK_INVOKEIDLIST; if (!ShellExecuteEx(&sei)) { MessageBox("Can't find selected file or Properties dialog", "Error", MB_OK); } } void CLeashAboutBox::OnProperties() { OnDblclkLeashModuleLb(); } void CLeashAboutBox::OnSetfocusLeashModuleLb() { if (m_LB_DLLsLoaded.GetCount()) m_propertiesButton.EnableWindow(TRUE); } BOOL CLeashAboutBox::PreTranslateMessage(MSG* pMsg) { if (m_missingFileError) { ::MessageBox(NULL, "OnInitDialog::We can't find file\"PSAPI.DLL\" " "or \"KERNEL32.DLL\"!!!\n" "About Box will not work properly.", "Error", MB_OK); m_missingFileError = FALSE; } return CDialog::PreTranslateMessage(pMsg); } ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������krb5-1.16/src/windows/leash/LeashUIApplication.cpp��������������������������������������������������0000644�0007046�0000145�00000022671�13211554426�021745� 0����������������������������������������������������������������������������������������������������ustar �ghudson�������������������������libuuid����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// -*- mode: c++; c-basic-offset: 4; indent-tabs-mode: nil -*- // leash/LeashUIApplication.cpp - Implement IUIApplication for leash // // Copyright (C) 2014 by the Massachusetts Institute of Technology. // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // // * Redistributions in binary form must reproduce the above copyright // notice, this list of conditions and the following disclaimer in // the documentation and/or other materials provided with the // distribution. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS // FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE // COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, // INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) // HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, // STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED // OF THE POSSIBILITY OF SUCH DAMAGE. // Implementation of the LeashUIApplication class. In addition // to the minimum requirements for the IUIApplication interface, // it also saves and loads the ribbon state across application // sessions, and initiates a redraw of the parent window when // the ribbon size changes. #include <UIRibbon.h> #include <UIRibbonPropertyHelpers.h> #include "kfwribbon.h" #include "LeashUIApplication.h" #include "LeashUICommandHandler.h" HWND LeashUIApplication::mainwin; // The input hwnd is the window to which to bind the ribbon, i.e., // the Leash CMainFrame. HRESULT LeashUIApplication::CreateInstance(IUIApplication **out, HWND hwnd) { LeashUIApplication *app = NULL; LeashUICommandHandler *handler; HRESULT ret; if (out == NULL) return E_POINTER; *out = NULL; app = new LeashUIApplication(); ret = LeashUICommandHandler::CreateInstance(&app->commandHandler, hwnd); if (FAILED(ret)) goto out; ret = app->InitializeRibbon(hwnd); if (FAILED(ret)) goto out; mainwin = hwnd; // Only the Leash-specific handler type has the back-pointer. handler = static_cast<LeashUICommandHandler *>(app->commandHandler); handler->app = app; *out = static_cast<IUIApplication *>(app); app = NULL; ret = S_OK; out: if (app != NULL) app->Release(); return ret; } // Create a ribbon framework and ribbon for the LeashUIApplication. // CoInitializeEx() is required to be called before calling any COM // functions. AfxOleInit(), called from CLeashApp::InitInstance(), // makes that call, but it is only scoped to the calling thread, // and the LeashUIApplication is created from CMainFrame, which is // the frame for the MFC document template. It is unclear if the // Leash main thread will be the same thread which runs the frame // from the document template, so call CoInitializeEx() ourselves // just in case. It is safe to call multiple times (it will return // S_FALSE on subsequent calls). HRESULT LeashUIApplication::InitializeRibbon(HWND hwnd) { HRESULT ret; if (hwnd == NULL) return -1; ret = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED); if (FAILED(ret)) return ret; ret = CoCreateInstance(CLSID_UIRibbonFramework, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&ribbonFramework)); if (FAILED(ret)) return ret; ret = ribbonFramework->Initialize(hwnd, this); if (FAILED(ret)) return ret; ret = ribbonFramework->LoadUI(GetModuleHandle(NULL), L"KFW_RIBBON_RIBBON"); if (FAILED(ret)) return ret; return S_OK; } // Import ribbon state (minimization state and Quick Access Toolbar // customizations) from a serialized stream stored in the registry. // In particular, the serialized state does not include the state // of checkboxes and other ribbon controls. // // This functionality is not very important, since we do not offer // much in the way of QAT customization. Paired with SaveRibbonState(). HRESULT LeashUIApplication::LoadRibbonState(IUIRibbon *ribbon) { HRESULT ret; IStream *s; s = SHOpenRegStream2(HKEY_CURRENT_USER, "Software\\MIT\\Kerberos5", "RibbonState", STGM_READ); if (s == NULL) return E_FAIL; ret = ribbon->LoadSettingsFromStream(s); s->Release(); return ret; } // Serialize the ribbon state (minimization state and Quick Access Toolbar // customizations) to the registry. Paired with LoadRibbonState(). HRESULT LeashUIApplication::SaveRibbonState() { HRESULT ret; IStream *s = NULL; IUIRibbon *ribbon = NULL; // No ribbon means no state to save. if (ribbonFramework == NULL) return S_OK; // ViewID of 0 is the ribbon itself. ret = ribbonFramework->GetView(0, IID_PPV_ARGS(&ribbon)); if (FAILED(ret)) return ret; s = SHOpenRegStream2(HKEY_CURRENT_USER, "Software\\MIT\\Kerberos5", "RibbonState", STGM_WRITE); if (s == NULL) { ret = E_FAIL; goto out; } ret = ribbon->SaveSettingsToStream(s); out: if (s != NULL) s->Release(); if (ribbon != NULL) ribbon->Release(); return ret; } UINT LeashUIApplication::GetRibbonHeight() { return ribbonHeight; } ULONG LeashUIApplication::AddRef() { return InterlockedIncrement(&refcnt); } ULONG LeashUIApplication::Release() { LONG tmp; tmp = InterlockedDecrement(&refcnt); if (tmp == 0) { if (commandHandler != NULL) commandHandler->Release(); if (ribbonFramework != NULL) ribbonFramework->Release(); delete this; } return tmp; } HRESULT LeashUIApplication::QueryInterface(REFIID iid, void **ppv) { if (ppv == NULL) return E_POINTER; if (iid == __uuidof(IUnknown)) { *ppv = static_cast<IUnknown*>(this); } else if (iid == __uuidof(IUIApplication)) { *ppv = static_cast<IUIApplication*>(this); } else { *ppv = NULL; return E_NOINTERFACE; } AddRef(); return S_OK; } // This is called by the ribbon framework on events which change the (ribbon) // view, such as creation and resizing. (There may be other non-ribbon views // in the future, but for now, the ribbon is the only one.) With the hybrid // COM/MFC setup used by Leash, the destroy event is not always received, // since the main thread is in the MFC half, and that thread gets the // WM_DESTROY message from the system; the MFC code does not know that it // needs to cleanly destroy the IUIFramework. HRESULT LeashUIApplication::OnViewChanged(UINT32 viewId, UI_VIEWTYPE typeID, IUnknown *view, UI_VIEWVERB verb, INT32 uReasonCode) { IUIRibbon *ribbon; HRESULT ret; // A viewId means "the ribbon". if (viewId != 0 || typeID != UI_VIEWTYPE_RIBBON) return E_NOTIMPL; switch(verb) { case UI_VIEWVERB_DESTROY: return SaveRibbonState(); case UI_VIEWVERB_CREATE: ret = view->QueryInterface(IID_PPV_ARGS(&ribbon)); if (FAILED(ret)) return ret; ret = LoadRibbonState(ribbon); ribbon->Release(); if (FAILED(ret)) return ret; // FALLTHROUGH case UI_VIEWVERB_SIZE: ret = view->QueryInterface(IID_PPV_ARGS(&ribbon)); if (FAILED(ret)) return ret; ret = ribbon->GetHeight(&ribbonHeight); ribbon->Release(); if (FAILED(ret)) return ret; // Tell the main frame to recalculate its layout and redraw. SendMessage(mainwin, WM_RIBBON_RESIZE, 0, NULL); return S_OK; case UI_VIEWVERB_ERROR: // FALLTHROUGH default: return E_NOTIMPL; } } // Provide a command handler to which the command with ID commandId will // be bound. All of our commands get the same handler. // // The typeID argument is just an enum which classifies what type of // command this is, grouping types of buttons together, collections, // etc. Since we only have one command handler, it can safely be ignored. HRESULT LeashUIApplication::OnCreateUICommand(UINT32 commandId, UI_COMMANDTYPE typeID, IUICommandHandler **commandHandler) { return this->commandHandler->QueryInterface(IID_PPV_ARGS(commandHandler)); } // It looks like this is called by the framework when the window with the // ribbon is going away, to give the application a chance to free any // application-specific resources (not from the framwork) that were bound // to a command in OnCreateUICommand. // // We do not have any such resources, so we do not need to implement this // function other than by returning success. HRESULT LeashUIApplication::OnDestroyUICommand(UINT32 commandId, UI_COMMANDTYPE typeID, IUICommandHandler *commandHandler) { return S_OK; } �����������������������������������������������������������������������krb5-1.16/src/windows/leash/KrbMiscConfigOpt.h������������������������������������������������������0000644�0007046�0000145�00000013021�13211554426�021064� 0����������������������������������������������������������������������������������������������������ustar �ghudson�������������������������libuuid����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//***************************************************************************** // File: KrbMiscConfigOpt.h // By: Paul B. Hill // Created: 08/12/1999 // Copyright: @1999 Massachusetts Institute of Technology - All rights // reserved. // Description: H file for KrbMiscConfigOpt.cpp. Contains variables // and functions for Kerberos Properties. // // History: // // MM/DD/YY Inits Description of Change // 08/12/99 PBH Original //***************************************************************************** #if !defined(AFX_MISCCONFIGOPT_H__CD702F99_7495_11D0_8FDC_00C04FC2A0C2__INCLUDED_) #define AFX_MISCONFIGOPT_H__CD702F99_7495_11D0_8FDC_00C04FC2A0C2__INCLUDED_ #if _MSC_VER >= 1000 #pragma once #endif #include "resource.h" /////////////////////////////////////////////////////////////////////// // CKrbMiscConfigOptions dialog class CKrbMiscConfigOpt : public CPropertyPage { // Construction private: DECLARE_DYNCREATE(CKrbMiscConfigOpt) BOOL m_startupPage2; BOOL m_noLifeTime; static UINT m_DefaultLifeTime; static CString m_initDefaultLifeTimeMin; static CString m_newDefaultLifeTimeMin; static CString m_initDefaultLifeTimeHr; static CString m_newDefaultLifeTimeHr; static CString m_initDefaultLifeTimeDay; static CString m_newDefaultLifeTimeDay; static UINT m_DefaultRenewTill; static CString m_initDefaultRenewTillMin; static CString m_newDefaultRenewTillMin; static CString m_initDefaultRenewTillHr; static CString m_newDefaultRenewTillHr; static CString m_initDefaultRenewTillDay; static CString m_newDefaultRenewTillDay; static UINT m_DefaultLifeMin; static CString m_initDefaultLifeMinMin; static CString m_newDefaultLifeMinMin; static CString m_initDefaultLifeMinHr; static CString m_newDefaultLifeMinHr; static CString m_initDefaultLifeMinDay; static CString m_newDefaultLifeMinDay; static UINT m_DefaultLifeMax; static CString m_initDefaultLifeMaxMin; static CString m_newDefaultLifeMaxMin; static CString m_initDefaultLifeMaxHr; static CString m_newDefaultLifeMaxHr; static CString m_initDefaultLifeMaxDay; static CString m_newDefaultLifeMaxDay; static UINT m_DefaultRenewMin; static CString m_initDefaultRenewMinMin; static CString m_newDefaultRenewMinMin; static CString m_initDefaultRenewMinHr; static CString m_newDefaultRenewMinHr; static CString m_initDefaultRenewMinDay; static CString m_newDefaultRenewMinDay; static UINT m_DefaultRenewMax; static CString m_initDefaultRenewMaxMin; static CString m_newDefaultRenewMaxMin; static CString m_initDefaultRenewMaxHr; static CString m_newDefaultRenewMaxHr; static CString m_initDefaultRenewMaxDay; static CString m_newDefaultRenewMaxDay; static void ResetDefaultLifeTimeEditBox(); static void ResetDefaultRenewTillEditBox(); static void ResetDefaultLifeMinEditBox(); static void ResetDefaultLifeMaxEditBox(); static void ResetDefaultRenewMinEditBox(); static void ResetDefaultRenewMaxEditBox(); BOOL m_initUseKrb4; BOOL m_newUseKrb4; BOOL m_initKinitPreserve; BOOL m_newKinitPreserve; public: CKrbMiscConfigOpt(); ~CKrbMiscConfigOpt(); // Dialog Data //{{AFX_DATA(CKrbMiscConfigOpt) enum { IDD = IDD_KRB_PROP_MISC }; static CEdit m_krbLifeTimeDayEditbox; static CEdit m_krbLifeTimeMinEditbox; static CEdit m_krbLifeTimeHrEditbox; static CEdit m_krbRenewTillDayEditbox; static CEdit m_krbRenewTillMinEditbox; static CEdit m_krbRenewTillHrEditbox; static CEdit m_krbRenewMaxDayEditbox; static CEdit m_krbRenewMinDayEditbox; static CEdit m_krbLifeMinDayEditbox; static CEdit m_krbLifeMinMinEditbox; static CEdit m_krbLifeMinHrEditbox; static CEdit m_krbLifeMaxDayEditbox; static CEdit m_krbLifeMaxMinEditbox; static CEdit m_krbLifeMaxHrEditbox; static CEdit m_krbRenewMinMinEditbox; static CEdit m_krbRenewMinHrEditbox; static CEdit m_krbRenewMaxMinEditbox; static CEdit m_krbRenewMaxHrEditbox; //}}AFX_DATA // Overrides // ClassWizard generate virtual function overrides //{{AFX_VIRTUAL(CKrbConfigOptions) public: virtual BOOL PreTranslateMessage(MSG* pMsg); protected: virtual VOID DoDataExchange(CDataExchange* pDX); // DDX/DDV support //}}AFX_VIRTUAL virtual BOOL OnApply(); // Implementation protected: // Generated message map functions //{{AFX_MSG(CKrbMiscConfigOpt) virtual BOOL OnInitDialog(); afx_msg void OnShowWindow(BOOL bShow, UINT nStatus); afx_msg void OnEditKillfocusEditDefaultLifeTime(); afx_msg void OnResetDefaultLifeTimeEditBox(); afx_msg void OnSelchangeEditDefaultLifeTime(); afx_msg void OnEditKillfocusEditDefaultRenewTill(); afx_msg void OnResetDefaultRenewTillEditBox(); afx_msg void OnSelchangeEditDefaultRenewTill(); afx_msg void OnEditKillfocusEditDefaultLifeMin(); afx_msg void OnResetDefaultLifeMinEditBox(); afx_msg void OnSelchangeEditDefaultLifeMin(); afx_msg void OnEditKillfocusEditDefaultLifeMax(); afx_msg void OnResetDefaultLifeMaxEditBox(); afx_msg void OnSelchangeEditDefaultLifeMax(); afx_msg void OnEditKillfocusEditDefaultRenewMin(); afx_msg void OnResetDefaultRenewMinEditBox(); afx_msg void OnSelchangeEditDefaultRenewMin(); afx_msg void OnEditKillfocusEditDefaultRenewMax(); afx_msg void OnResetDefaultRenewMaxEditBox(); afx_msg void OnSelchangeEditDefaultRenewMax(); afx_msg void OnCheckUseKrb4(); afx_msg void OnCheckKinitPreserve(); //}}AFX_MSG DECLARE_MESSAGE_MAP() }; ///////////////////////////////////////////////////////////////////////////// //{{AFX_INSERT_LOCATION}} // Microsoft Developer Studio will insert additional declarations immediately before the previous line. #endif // !defined(AFX_MISCONFIGOPT_H__CD702F99_7495_11D0_8FDC_00C04FC2A0C2__INCLUDED_) ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������krb5-1.16/src/windows/leash/CLeashDragListBox.h�����������������������������������������������������0000644�0007046�0000145�00000001776�13211554426�021201� 0����������������������������������������������������������������������������������������������������ustar �ghudson�������������������������libuuid����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#ifndef _LEASH_DRAGLISTBOX #define _LEASH_DRAGLISTBOX ///////////////////////////////////////////////////////////////////////////// // CLeashDragListBox //#include "AFXCMN.h" class CLeashDragListBox : public CDragListBox { //DECLARE_DYNAMIC(CDragListBoxCLeashDragListBox) CListBox* m_pOtherListBox; CPropertyPage* m_pPage; // Constructors public: CLeashDragListBox(); void initOtherListbox(CPropertyPage* pPage, CListBox* pOtherListBox); // Attributes //int ItemFromPt(CPoint pt, BOOL bAutoScroll = TRUE) const; // Operations virtual void DrawInsert(int nItem); // Overridables virtual BOOL BeginDrag(CPoint pt); virtual void CancelDrag(CPoint pt); virtual UINT Dragging(CPoint pt); virtual void Dropped(int nSrcIndex, CPoint pt); // Implementation public: int m_nLast; void DrawSingle(int nIndex); virtual void PreSubclassWindow(); virtual ~CLeashDragListBox(); protected: //virtual BOOL OnChildNotify(UINT, WPARAM, LPARAM, LRESULT*); }; //class CLeashDragListBox; #endif // _LEASH_DRAGLISTBOX ��krb5-1.16/src/windows/leash/LeashAboutBox.h���������������������������������������������������������0000644�0007046�0000145�00000004760�13211554426�020433� 0����������������������������������������������������������������������������������������������������ustar �ghudson�������������������������libuuid����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//***************************************************************************** // File: LeashAboutBox.cpp // By: Arthur David Leather // Created: 12/02/98 // Copyright: @1998 Massachusetts Institute of Technology - All rights // reserved. // Description: H file for LeashAboutBox.cpp. Contains variables and functions // for the Leash About Box Dialog Box // // History: // // MM/DD/YY Inits Description of Change // 12/02/98 ADL Original //***************************************************************************** #if !defined(AFX_LEASHABOUTBOX_H__B49E3501_4801_11D2_8F7D_0000861B8A3C__INCLUDED_) #define AFX_LEASHABOUTBOX_H__B49E3501_4801_11D2_8F7D_0000861B8A3C__INCLUDED_ #if _MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000 // LeashAboutBox.h : header file // ///////////////////////////////////////////////////////////////////////////// // CLeashAboutBox dialog class CLeashAboutBox : public CDialog { BOOL m_missingFileError; DWORD SetVersionInfo(UINT id_ver, UINT id_copyright); BOOL GetModules95(DWORD processID, BOOL allModules = TRUE); void GetModulesNT(DWORD processID, BOOL allModules = TRUE); void HighlightFirstItem(); // Construction public: CLeashAboutBox(CWnd* pParent = NULL); // standard constructor // Dialog Data //{{AFX_DATA(CLeashAboutBox) enum { IDD = IDD_LEASH_ABOUTBOX }; CButton m_propertiesButton; CButton m_radio_LeashDLLs; CListBox m_LB_DLLsLoaded; CString m_fileItem; BOOL m_bListModules; //}}AFX_DATA // Overrides // ClassWizard generated virtual function overrides //{{AFX_VIRTUAL(CLeashAboutBox) public: virtual BOOL PreTranslateMessage(MSG* pMsg); protected: virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support //}}AFX_VIRTUAL // Implementation protected: // Generated message map functions //{{AFX_MSG(CLeashAboutBox) afx_msg void OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar); virtual BOOL OnInitDialog(); afx_msg void OnSelchangeLeashModuleLb(); afx_msg void OnAllModules(); afx_msg void OnLeashModules(); afx_msg void OnDblclkLeashModuleLb(); afx_msg void OnProperties(); afx_msg void OnSetfocusLeashModuleLb(); afx_msg void OnNotLoadedModules(); //}}AFX_MSG DECLARE_MESSAGE_MAP() }; //{{AFX_INSERT_LOCATION}} // Microsoft Visual C++ will insert additional declarations immediately before the previous line. #endif // !defined(AFX_LEASHABOUTBOX_H__B49E3501_4801_11D2_8F7D_0000861B8A3C__INCLUDED_) ����������������krb5-1.16/src/windows/leash/Krb4EditRealmHostList.h�������������������������������������������������0000644�0007046�0000145�00000004344�13211554426�022014� 0����������������������������������������������������������������������������������������������������ustar �ghudson�������������������������libuuid����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// ************************************************************************************** // File: Krb4EditRealmHostList.h // By: Arthur David Leather // Created: 12/02/98 // Copyright @1998 Massachusetts Institute of Technology - All rights reserved. // Description: H file for Krb4EditRealmHostList.cpp. Contains variables and functions // for Kerberos Four Properties // // History: // // MM/DD/YY Inits Description of Change // 12/02/98 ADL Original // ************************************************************************************** #if !defined(AFX_EDITREALMHOSTLIST_H__26A1E1F7_9117_11D2_94D0_0000861B8A3C__INCLUDED_) #define AFX_EDITREALMHOSTLIST_H__26A1E1F7_9117_11D2_94D0_0000861B8A3C__INCLUDED_ #if _MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000 // EditRealmHostList.h : header file // ///////////////////////////////////////////////////////////////////////////// // CKrb4EditRealmHostList dialog class CKrb4EditRealmHostList : public CDialog { // Construction private: CString m_editItem; CString m_initRealm; CString m_newRealm; CString m_initHost; CString m_newHost; BOOL m_initAdmin; BOOL m_newAdmin; BOOL m_startup; public: CKrb4EditRealmHostList(LPSTR editItem, CWnd* pParent = NULL); CString GetEditedItem() {return m_editItem;} CString GetNewRealm() {return m_newRealm;} // Dialog Data //{{AFX_DATA(CKrb4EditRealmHostList) enum { IDD = IDD_KRB4_EDIT_REALM }; //}}AFX_DATA // Overrides // ClassWizard generated virtual function overrides //{{AFX_VIRTUAL(CKrb4EditRealmHostList) protected: virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support //}}AFX_VIRTUAL // Implementation protected: // Generated message map functions //{{AFX_MSG(CKrb4EditRealmHostList) afx_msg void OnShowWindow(BOOL bShow, UINT nStatus); afx_msg void OnChangeEditDefaultRealm(); afx_msg void OnChangeEditRealmHostname(); afx_msg void OnRadioAdminServer(); afx_msg void OnRadioNoAdminServer(); virtual void OnOK(); virtual BOOL OnInitDialog(); //}}AFX_MSG DECLARE_MESSAGE_MAP() }; //{{AFX_INSERT_LOCATION}} // Microsoft Visual C++ will insert additional declarations immediately before the previous line. #endif // !defined(AFX_EDITREALMHOSTLIST_H__26A1E1F7_9117_11D2_94D0_0000861B8A3C__INCLUDED_) ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������krb5-1.16/src/windows/leash/VSroutines.c������������������������������������������������������������0000644�0007046�0000145�00000004035�13211554426�020042� 0����������������������������������������������������������������������������������������������������ustar �ghudson�������������������������libuuid����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#include <windows.h> #include <winver.h> #if 0 //#ifdef USE_VS #include <vs.h> #define ININAME "leash.ini" int VScheckVersion(HWND hWnd, HANDLE hThisInstance) { VS_Request vrequest; VS_Status status; BOOL ok_to_continue; HCURSOR hcursor; char szFilename[255]; char szVerQ[90]; char *cp; LPSTR lpAppVersion; LPSTR lpAppName; LONG FAR *lpLangInfo; DWORD hVersionInfoID; DWORD size; GLOBALHANDLE hVersionInfo; LPSTR lpVersionInfo; int dumint; int retval; GetModuleFileName(hThisInstance, (LPSTR)szFilename, 255); size = GetFileVersionInfoSize((LPSTR) szFilename, &hVersionInfoID); hVersionInfo = GlobalAlloc(GHND, size); lpVersionInfo = GlobalLock(hVersionInfo); retval = GetFileVersionInfo(szFilename, hVersionInfoID, size, lpVersionInfo); retval = VerQueryValue(lpVersionInfo, "\\VarFileInfo\\Translation", (LPSTR FAR *)&lpLangInfo, &dumint); wsprintf(szVerQ, "\\StringFileInfo\\%04x%04x\\", LOWORD(*lpLangInfo), HIWORD(*lpLangInfo)); cp = szVerQ + lstrlen(szVerQ); lstrcpy(cp, "ProductName"); retval = VerQueryValue(lpVersionInfo, szVerQ, &lpAppName, &dumint); lstrcpy(cp, "ProductVersion"); retval = VerQueryValue(lpVersionInfo, szVerQ, &lpAppVersion, &dumint); hcursor = SetCursor(LoadCursor((HINSTANCE)NULL, IDC_WAIT)); vrequest = VSFormRequest(lpAppName, lpAppVersion, ININAME, NULL, hWnd, V_CHECK_AND_LOG); if ((ok_to_continue = (ReqStatus(vrequest) != V_E_CANCEL)) && v_complain((status = VSProcessRequest(vrequest)), ININAME)) WinVSReportRequest(vrequest, hWnd, "Version Server Status Report"); if (ok_to_continue && status == V_REQUIRED) ok_to_continue = FALSE; VSDestroyRequest(vrequest); SetCursor(hcursor); GlobalUnlock(hVersionInfo); GlobalFree(hVersionInfo); return(ok_to_continue); } #else int VScheckVersion(HWND hWnd, HANDLE hThisInstance) { return(1); } #endif ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������krb5-1.16/src/windows/leash/MainFrm.cpp�������������������������������������������������������������0000644�0007046�0000145�00000030453�13211554426�017615� 0����������������������������������������������������������������������������������������������������ustar �ghudson�������������������������libuuid����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// ************************************************************************************** // File: MainFrm.cpp // By: Arthur David Leather // Created: 12/02/98 // Copyright @1998 Massachusetts Institute of Technology - All rights reserved. // Description: CPP file for MainFrm.h. Contains variables and functions // for Leash // // History: // // MM/DD/YY Inits Description of Change // 12/02/98 ADL Original // ************************************************************************************** #include "stdafx.h" #include "LeashUIApplication.h" #include "Leash.h" #include "MainFrm.h" #include "lglobals.h" //#include "KrbRealmHostMaintenance.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif ///////////////////////////////////////////////////////////////////////////// // CMainFrame #define MIN_LEFT 179 #define MIN_TOP 61 #define MIN_RIGHT 530 #define MIN_BOTTOM 280 #ifndef NO_STATUS_BAR CMFCStatusBar CMainFrame::m_wndStatusBar; #endif CMFCToolBar CMainFrame::m_wndToolBar; CImageList CMainFrame::m_imageList; CImageList CMainFrame::m_disabledImageList; BOOL CMainFrame::m_isMinimum; BOOL CMainFrame::m_isBeingResized; int CMainFrame::m_whatSide; IMPLEMENT_DYNCREATE(CMainFrame, CLeashFrame) BEGIN_MESSAGE_MAP(CMainFrame, CLeashFrame) //{{AFX_MSG_MAP(CMainFrame) ON_WM_CREATE() ON_WM_SIZING() ON_WM_CLOSE() ON_WM_GETMINMAXINFO() ON_COMMAND(ID_APP_EXIT, OnClose) //}}AFX_MSG_MAP // Global help commands ON_COMMAND(ID_HELP_LEASH_, CMainFrame::OnHelpFinder) ON_COMMAND(ID_HELP, CMainFrame::OnHelp) ON_COMMAND(ID_CONTEXT_HELP, CMainFrame::OnContextHelp) ON_MESSAGE_VOID(WM_RIBBON_RESIZE, OnRibbonResize) END_MESSAGE_MAP() static UINT indicators[] = { ID_SEPARATOR, // status line indicator ID_SEPARATOR, ID_SEPARATOR, ID_SEPARATOR }; ///////////////////////////////////////////////////////////////////////////// // CMainFrame construction/destruction CMainFrame::CMainFrame() { m_winRectLeft = 0; m_winRectTop = 0; m_winRectRight = 0; m_winRectBottom = 0; m_whatSide = RESET_MINSIZE; m_isMinimum = FALSE; m_isBeingResized = FALSE; m_bOwnerCreated = FALSE; pApplication = NULL; } CMainFrame::~CMainFrame() { } int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct) { if (CLeashApp::m_useRibbon) { HWND hwnd; HRESULT hr; // Fixup tooltips (cribbed from http://social.msdn.microsoft.com/Forums/en/vcmfcatl/thread/5c5b4879-d278-4d79-8894-99e7f9b322df) CMFCToolTipInfo ttParams; ttParams.m_bVislManagerTheme = TRUE; ttParams.m_bVislManagerTheme = FALSE; ttParams.m_bDrawSeparator = FALSE; ttParams.m_clrFillGradient = afxGlobalData.clrBarFace; ttParams.m_clrFill = RGB(255, 255, 255); ttParams.m_clrBorder = afxGlobalData.clrBarShadow; ttParams.m_clrText = afxGlobalData.clrBarText; theApp.GetTooltipManager()->SetTooltipParams(AFX_TOOLTIP_TYPE_ALL, RUNTIME_CLASS(CMFCToolTipCtrl), &ttParams); CMFCVisualManager::SetDefaultManager(RUNTIME_CLASS(CMFCVisualManagerWindows7)); CDockingManager::SetDockingMode(DT_SMART); m_wndRibbonBar.SetWindows7Look(TRUE); // Initialize the ribbon, keeping a handle to the IUIApplication // so that we can query the ribbon height and save space for it // when calculating our layout. hwnd = this->GetSafeHwnd(); if (hwnd == NULL) printf("Failed to get HWND\n"); hr = LeashUIApplication::CreateInstance(&pApplication, hwnd); if (FAILED(hr)) { MessageBox("LeashUIApplication::CreateInstance!", "Error", MB_OK); return -1; } } if (CLeashFrame::OnCreate(lpCreateStruct) == -1) return -1; ShowWindow(SW_HIDE); /* NT4 and NT5 aren't shipped with a version of MFC that supports // 'CreateEx()' as of 2/1/99 #if _MFC_VER > 0x0421 if (!m_wndToolBar.CreateEx(this) || !m_wndToolBar.LoadToolBar(IDR_MAINFRAME)) { TRACE0("Failed to create toolbar\n"); return -1; // fail to create } #else if (!m_wndToolBar.Create(this) || !m_wndToolBar.LoadToolBar(IDR_MAINFRAME)) { TRACE0("Failed to create toolbar\n"); return -1; // fail to create } #endif */ if ((!CLeashApp::m_useRibbon) && (!m_wndToolBar.Create(this) || !m_wndToolBar.LoadToolBar(IDR_MAINFRAME))) { MessageBox("There is problem creating the Leash Toolbar!", "Error", MB_OK); TRACE0("Failed to create toolbar\n"); return -1; // fail to create } #ifndef NO_STATUS_BAR if (!m_wndStatusBar.Create(this) || !m_wndStatusBar.SetIndicators(indicators, (CLeashApp::m_hAfsDLL ? 4 : 3))) { MessageBox("There is problem creating the Leash Status Bar!", "Error", MB_OK); TRACE0("Failed to create status bar\n"); return -1; // fail to create } #endif // TODO: Remove this if you don't want tool tips or a resizeable toolbar //m_wndToolBar.SetPaneStyle(m_wndToolBar.GetPaneStyle() | // CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC); if (!CLeashApp::m_useRibbon) { // TODO: Delete these three lines if you don't want the toolbar to // be dockable m_wndToolBar.EnableDocking(CBRS_ALIGN_ANY); EnableDocking(CBRS_ALIGN_ANY); DockPane(&m_wndToolBar); } return 0; } BOOL CMainFrame::PreTranslateMessage(MSG* pMsg) { return CLeashFrame::PreTranslateMessage(pMsg); } BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs) { // Use the specific class name we established earlier // Remove the Minimize and Maximize buttons cs.style &= ~WS_MINIMIZEBOX; cs.style &= ~WS_MAXIMIZEBOX; // Initialize the extended window style to display a TaskBar entry with WS_EX_APPWINDOW cs.dwExStyle |= WS_EX_APPWINDOW; // cs.dwExStyle |= WS_EX_OVERLAPPEDWINDOW ; cs.lpszClass = _T("LEASH.0WNDCLASS"); cs.lpszName = _T("MIT Kerberos"); CString strText = AfxGetApp()->GetProfileString(CLeashFrame::s_profileHeading, CLeashFrame::s_profileRect); if (!strText.IsEmpty()) { CRect rect; rect.left = atoi((const char*) strText); rect.top = atoi((const char*) strText + 5); rect.right = atoi((const char*) strText + 10); rect.bottom = atoi((const char*) strText + 15); cs.x = rect.left; cs.y = rect.top; cs.cx = rect.right - rect.left; cs.cy = rect.bottom - rect.top; if ( cs.x < 0 ) cs.x = CW_USEDEFAULT; if ( cs.y < 0 ) cs.y = CW_USEDEFAULT; if ( cs.cx <= 0 ) cs.cx = CLeashFrame::s_rectDefault.right; if ( cs.cy <= 0 ) cs.cy = CLeashFrame::s_rectDefault.bottom; } else { cs.cx = CLeashFrame::s_rectDefault.right; cs.cy = CLeashFrame::s_rectDefault.bottom; cs.y = CW_USEDEFAULT; cs.x = CW_USEDEFAULT; } // Change the following line to call // CLeashFrame::PreCreateWindow(cs) if this is an SDI application. if (!CLeashFrame::PreCreateWindow(cs)) return FALSE; // We create a parent window for our application to ensure that // it has an owner. This way we can disable the TaskBar entry // by removing the WS_EX_APPWINDOW style later on. if ( !m_bOwnerCreated ) { m_bOwnerCreated = m_MainFrameOwner.Create(IDD_FRAMEOWNER); if ( m_bOwnerCreated ) m_MainFrameOwner.ShowWindow(SW_HIDE); } if ( m_bOwnerCreated ) cs.hwndParent = m_MainFrameOwner.GetSafeHwnd(); return TRUE; } BOOL CMainFrame::ShowTaskBarButton(BOOL bVisible) { if (!m_bOwnerCreated) return FALSE; if (bVisible) { ShowWindow(SW_HIDE); ModifyStyleEx(0, WS_EX_APPWINDOW); ShowWindow(SW_SHOW); } else { ShowWindow(SW_HIDE); ModifyStyleEx(WS_EX_APPWINDOW, 0); ShowWindow(SW_SHOW); } return TRUE; } ///////////////////////////////////////////////////////////////////////////// // CMainFrame diagnostics #ifdef _DEBUG void CMainFrame::AssertValid() const { CLeashFrame::AssertValid(); } void CMainFrame::Dump(CDumpContext& dc) const { CLeashFrame::Dump(dc); } #endif //_DEBUG ///////////////////////////////////////////////////////////////////////////// // CMainFrame message handlers void CMainFrame::OnResetWindowSize() { WINDOWPLACEMENT wndpl; wndpl.length = sizeof(WINDOWPLACEMENT); if (!GetWindowPlacement(&wndpl)) { MessageBox("There is a problem getting Leash Window size!", "Error", MB_OK); return; } wndpl.rcNormalPosition = CLeashFrame::s_rectDefault; m_whatSide = SKIP_MINSIZE; if (!SetWindowPlacement(&wndpl)) { MessageBox("There is a problem setting Leash Window size!", "Error", MB_OK); } m_whatSide = RESET_MINSIZE; } void CMainFrame::OnSizing(UINT fwSide, LPRECT pRect) { // Keeps track of Leash window size for function CMainFrame::RecalcLayout m_winRectLeft = pRect->left; m_winRectTop = pRect->top; m_winRectRight = pRect->right; m_winRectBottom = pRect->bottom; if (m_whatSide) m_whatSide = fwSide; CLeashFrame::OnSizing(fwSide, pRect); } void CMainFrame::RecalcLayout(BOOL bNotify) { // MINSIZE - Insurance that we have a minimum Leash window size int width = MIN_RIGHT - MIN_LEFT; int height = MIN_BOTTOM - MIN_TOP; LeashUIApplication *leashUI; RECT border; border.left = border.right = border.bottom = 0; // Leave room for the ribbon. leashUI = static_cast<LeashUIApplication*>(pApplication); border.top = (leashUI != NULL) ? leashUI->GetRibbonHeight() : 0; NegotiateBorderSpace(CFrameWnd::borderSet, &border); BOOL change = FALSE; WINDOWPLACEMENT wndpl; wndpl.length = sizeof(WINDOWPLACEMENT); if (!GetWindowPlacement(&wndpl)) { MessageBox("There is a problem getting Leash Window size!", "Error", MB_OK); return; } if (m_whatSide) { if ((m_winRectRight - m_winRectLeft) < width) { if (m_whatSide == LEFT_SIDE) { wndpl.rcNormalPosition.left = wndpl.rcNormalPosition.right - width; change = TRUE; } else if (m_whatSide == RIGHT_SIDE) { wndpl.rcNormalPosition.right = wndpl.rcNormalPosition.left + width; change = TRUE; } } else if ((m_winRectBottom - m_winRectTop) < height) { if (m_whatSide == TOP_SIDE) { wndpl.rcNormalPosition.top = wndpl.rcNormalPosition.bottom - height; change = TRUE; } else if (m_whatSide == BOTTOM_SIDE) { wndpl.rcNormalPosition.bottom = wndpl.rcNormalPosition.top + height; change = TRUE; } } } if ( change ) { if (!SetWindowPlacement(&wndpl)) { MessageBox("There is a problem setting Leash Window size!", "Error", MB_OK); } } m_isBeingResized = TRUE; CLeashFrame::RecalcLayout(bNotify); } void CMainFrame::OnGetMinMaxInfo(MINMAXINFO FAR* lpMMI) { lpMMI->ptMinTrackSize.x = 650; lpMMI->ptMinTrackSize.y = 240; CLeashFrame::OnGetMinMaxInfo(lpMMI); } void CMainFrame::OnClose(void) { CLeashFrame::OnClose(); } LRESULT CMainFrame::WindowProc(UINT message, WPARAM wParam, LPARAM lParam) { BOOL oldMin = m_isMinimum; //printf("CMainFrame::WindowProc() Msg: %x, WPARAM: %x, LPARAM: %x\n", message, wParam, lParam); switch(message) { case WM_CLOSE: printf("received WM_CLOSE!"); break; case WM_SIZE: switch ( wParam ) { case SIZE_MINIMIZED: m_isMinimum = TRUE; break; case SIZE_MAXIMIZED: case SIZE_RESTORED: m_isMinimum = FALSE; break; } break; case ID_OBTAIN_TGT_WITH_LPARAM: GetActiveView()->SendMessage(ID_OBTAIN_TGT_WITH_LPARAM, wParam, lParam); break; } if ( oldMin != m_isMinimum ) { if ( m_isMinimum ) { ShowTaskBarButton(FALSE); ShowWindow(SW_HIDE); } } return CLeashFrame::WindowProc(message, wParam, lParam); } // Signalled by LeashUIApplication::OnViewChanged when the ribbon height // changes. void CMainFrame::OnRibbonResize() { RecalcLayout(TRUE); } /* void CMainFrame::OnHelp() { } */ /* void CMainFrame::OnContextHelp() { } */ ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������krb5-1.16/src/windows/leash/htmlhelp/���������������������������������������������������������������0000755�0007046�0000145�00000000000�13211554426�017370� 5����������������������������������������������������������������������������������������������������ustar �ghudson�������������������������libuuid����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������krb5-1.16/src/windows/leash/htmlhelp/Images/��������������������������������������������������������0000755�0007046�0000145�00000000000�13211554426�020575� 5����������������������������������������������������������������������������������������������������ustar �ghudson�������������������������libuuid����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������krb5-1.16/src/windows/leash/htmlhelp/Images/Home_Tab.PNG��������������������������������������������0000644�0007046�0000145�00000032406�13211554426�022626� 0����������������������������������������������������������������������������������������������������ustar �ghudson�������������������������libuuid����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������PNG  ��� IHDR��U���t���5 ���sRGB����gAMA�� a��� pHYs����+��4IDATx^} |չ33JX]DDU@n{[۪նum.mm.jVP$VDe_ $!6Y'3=L2 d /rs={,=%Ngu$xǸ8N ѝ b;J'wNmؼ,NBdhPwjce ! #{!??nY'6> θ^ 蛗GMBE1>QjUV7 ָ0Pf4iTrځ BcXya+i+CV??;v!1.(B5g)>*74U HJt`5SwRU)S7RKu=^'b\|특t]]mDGg'%#62TُWې[R qYzz cZr-F@#14UjGFVT3uwG @jP(8)qA0~owDM6`]Ñ[?䉱jm[t4Si|`\;Hㄠ<eq$L] !Z;PU,R&)zܖtvſz'w,bS*/l A#WBj̫]}9D3W鉡ض+w޴]$64bt%ژ{H ߲+1 eۉZ (!`XT0�9nZ & K~}no?ɱKu[TO G$ջvjB:6U!U?v 4g�TDJo56HHPT=Ѯ(Ǭ)BV'$!"UNPäD[}od<ox]I Q֤z\g'.ۻhC@  7;wowrt:]tݷ{b;=l ۭםVkIB#}|o*=;[Z#1f!OrIgĶ%6N0'}vP,EtPuP =& g>$wpMs̓wąЍ%Zk?zwH -1;n&t R܍x(a9^-rG뻱uOh1IXVO?.s�z|fk: Ch 3+J <q\QC-{ɚHx E*dE}O?K~D#p!`̪–zG ̮:lnPx +ȭ >Ϟ$ث~!>f~̩ŇjD̬JlWE8^> u# *xjF{.R-Wo^GA^Y c;<0 ,֥q5=Cܿo`~8v۟րjHS;VD4gvf?? 'i@z {cXn]uyg= ~L3H~Vj|vrՏyJAP&?.gehŏ38hv7Mr /{$[W/hu}- =80h~^^8W<=??dSȥt En,y" \lT)3wɾq+޸YNҿf,&);n@Yfws$Gg4g.uqY" uk :lzkc _z+Oz$\ $/_Ȟjzc<[HmUk_ZJ7\y=nMmu/}` fd0}�y*<R:}yc=,FF7ْ8\al%ɾ_[k.w<mdv?7Pi 2,XQˤ"K!BI$TLCouVC㷕A~]r7s$oYHMZHcM/^y$Nr vTĤ]N{FwGoB@j /08B|BwH"g c˻ز.<*gWߏ:Kk9KZ=!ؕ6 e$?x_IU6 HV4+x˭?|V\Oyf\aMvYWZ <qim2 %k WaY_ RykPkh>G'!n2r CC`h8ɍppU+E0p'yV0GB " ^i$TՇ0I_0RZy�?hQHtsj8mkd|fl}nR5c#]w(ѥұHVi?;?ʑ͇<;YI%Np)t^s&H۪,9ghUd6V>\3"2ʽ*#&NQ]3qT4L+IO%#q8lKqmE~j,r?2􌪑׹+!gc&8a6 ZjLbR(UL)V#Pi}-s;3T:> ` Y^Uoh$A+V2"@F`#`}UG.q1ӖjnեB5Z[u5"k̶UVJ hk5RQ9]-<\5ձޢ|hJ3V(g fxܓ\{r7H~Tr8ECg,j>4XGHEfnR" PDHK]vu_ ;n랜qoI3XRAHU ztI>5meԇF@#0>0J嗕d?9,gݎ~+b{ip*W (Uap0p�dk"bkFm]l-`g"՛w QaчF@#00m4o}]4NI~*wPѱj oLwmQ 8#0qiqGgSYPiAԢI�3hLLUKtHh4g�vLMTHUh143 ׇF@#xSc&Uo�h4An #@VYO6 aRM+O�JUkgH]b,V-AL"/3Ǒttt`ION~i\ TzFuHUYc1[QT}GvDckq@Gs#r^̋qu؎Ӓ/vUe~q`~.Sr!P6*++Ϩ S]Kר8l?۰<JԴ`W|Ǫ 壽ƒRG3>~ApsZ$Wcx,= Am=L.eOovNJIGVwH1mhFv<'\d%r_@'L%p]k%{{eɝ6 mx )ڵ5-QT)A[ShoܐҏkF)-cEܸhFGγ/mJKpݥaw`ڋæނ9Gwʱ!cAYCasZd7j" ”nY>l YN2h?^AuOJ\`A믢3gJAUI _F뇄ɡ,CoނRλ[ږJfhpj\ؑ ˻#C̚4A1>{( ox#Bq.AiGyi9h!έmU<KUJqmԩCN=~ȷjhKڋqѼ%[hn+ ܔzͭ8f悿߲<֌yJ&sv?8۹틝[bD3щ\VC03!mk:~>i+k�K6~-Q`?feơ)M$M(|7}GC X jE=bG*9j߈_ve .GΝl'O pDQWsSRPn 7fߟ{ ݔXcACwO@„IQC|t4aG?GYg.Yp >@XtrVs'M"܄HSւu6΂)a*6؛o͕qv7}]N {A;;p^joΞRfΒ `FBBTt="L?>؝ o2HLˍ2s1}MFWs݄ZZ>x-X0}>37}Yt=k1clDz[A'; OKG?A|m"(,iiitP$U&kQ$\E$ *?DoH>5 .ƾ{`4lFeaBC-Uj߁$֭2Mu;)Skb RP3u]Ad'B[8e6w1e:̴ڛ*G 7;ë-S?F@K22P~=srJ4`C̅ٵl]y0!= };s{oC^\uWes'J:gvm7I敘/u[=&,?'G-֎67 kC!4hŅE()*b} ?]͊HCk¬ӸZ?G�Zk*WuhgT=' o$jAj /SC=b>GNjABjEH͕褆8?y-m7vgՆ@XãPM$QGmƖ$'Y!ګk.?m]519NnF@@�ٕl&/ΏcW sx y 2HB߷Ol[�D_}Oa|[PY|;q& snTr7-?E I{*>Hg',hMX})fϤډ7*S7zNBjmm#00�a VvӦbt!tZZiٚJ'Vvvl48-V,p 5p=' o$j˚_RC-2f/jګᔓ6A3j֑ dlj#0ܟe0J!C[_«6sLS[)1 ](R ,RjovԋbM$ْ`5s?ӫrZPryffc/ZYZP;ea;w6?Z?.Za5Fc;G= ;q&ߏxbUL N<Z^PO%jTW $V+?-(m,ǜ9i{A~a|aw*84## a D ?p4S(4@ dSS;U0KpFr߃[t6/ؖ/{1gHJ9)i D#u} ((-@zt|UfҋY38:Zٝ낓hoRg-|nZ4MKRzM.$0,�yNGm%NeRC]#%pTBNY4i!C"&j YYd�:m7"‹^:А%D9UƠ{g(f/+;_fPwCL4Wְ܊ؔ(TkoU˒běq^L0S} Chq@ UAMu7l@ LASEcWƩmP_fUE"ES`kEYv%ϟ4V ~V+l P$rRyff5 &vۄDh<~jS#<^#hMս,#gH.27nĺZl({wp Sk+:;;(|sv6ȩLh?܏ }"`mn㰩lQXX]*ԕc4E* K2)T~nL8{0z-N۶K)?T쩈Mr;4y2+=3  ff$gP_׊P Jj <ZֈcMNGks!X,l?""kD.gWqzst \?+$Iw\Gz7/?n" QuQ{ D͵,S%_t,A!H0j1[ ~vF޽ u*M6`DOIF=1wߍuXTK |dAA^1rjh2ԠXa;ZO2W[M CKq.wn!x}^8N6 mBCCFQǫsHeU->l7"+[h:5<,a6f.>Cj|ŗ u!meM|QġJ�Uj+m$Ȏ<p?^>%)MΪ.4蔪(N-`DX>wS3a睏?_+w)Dju(DD"" `?G#/ӆQ;9.=i#jJjՇVf;h+39wgl-Sn)8 Vœm'4RQ -^ZsgĄ< LsOTV1}gGVEs/§=dΗ5B4ԔEP'$̍S6v%Mesk_*9Q^`E$&3=2Lgڬ;xtќC׽߈KL@;ƱV:J쒊}5]7]~%&}?IN(iSC)4qbmOP/CMj" M54̌Af[T89`"&A޺H S9̂q-ӧ_~v9N͛;4u3Y֟j{.]H ].{yjIyH._ s9Ϊ6WSBЪFB>#Th:d8C r)II'Բ̢ |~/Z i7Ǟ[&JCB0({E"i6l|G0Ga^_Ԁ p-M?utqxe<NN+ B0'5\݂.VD#Po*ZiOL~((mZ>%Yl9�` oU,1DDxq \\`4V6_œXԳR׆HS:L 5+Z ù+Uˬ)8+fu/ַYRkͣia &sgTnv"˭hSJ"h1lj SZ"޼/hlT$Fg$m'? j[QWl)ap,S~JPr�3 B\l v~~�GEY%Q[9"tp8`Jԙx>-܉}5W"$3ؕ FeIq*_~ӣF'{tDFeLW,'=7]~O^V6ɆIjH5L2qfLdHp#ME$�hhYP0qj 8K(_jxYF,il#9~^̈́E(>>$/AThLGw:H056! l6ʫUAӏ$?PW=C[~^!#CŅ}G#‚̅U.8<xpȰ,}XG~4\>ۆyNI*$2k9^ށ$jP(+S lC3s&xTgԧyv:0۟bǶ",9#e\ᨍ]i:8]A gph5uo#Q4TnBı1v~+i!V?9jVgѡMJ #3wqB�{0] Ȭ6Dp+[҉DΪc;UX'I:ъ$.Ynؽ�SԪT 9m2b="Sqv#0E2q2?(cXR_揆FHtZe" J?ટpZQC_VkeؘuH;Td0X9=UASU7aqڀ霐EVdh^2Lǔ3}8Ȼ3e2Z*]V'Qߎ-2o>@�GMڞ$TѨ,WI,׮9(Gk z!V#{z$J9y~B'lMEɠ:5y"B9?&�%\lJ]}hH'g=Gq[n^'0#a„d9C|o?ל .ឭORkʦ0q:t58 ?'Njzm-WէL�$z5[JSB9LE->lB#ktwgׄ(Ͷ zqmyA' .?_۾^[ k 5DB-ܶ .BV}|$ELcWj:rh$VqB鰔lCattJ=X'_ԤD"!q25H$p8Ֆۨ)Age✹cO> ɡ"0"Rd)H¶[aDMg/w =PZi!T70S h)+k]cEcUAVrHh!9uʠ{j^6:C0s<mCIG;i{H(no^~0'e>G0QF%&]~n_&L DܴT4!@Ɠh:HԶ*b/g=H 5u `$KeL0p'qj Ņ`SCϙc99`ѝiwGW5 qQx68Zt2Z<tD/#HAxrK(BES<bk#&ł9j(OUC!-G[ofk*h\hk!w  /{ʸY�2Y$WLB}xHkG~榍UbyE%ՄI*(:ӝ(cX~\p :!`;<2&g`R|,2w|Pg',DaΐɈ<}s=e5s{$,NOQ 4rR=! Yf]ӓtfsťrڷF"#9PcaR}32ᄸapqeBqџ$2ƺ`Bۍ҆Rjs\H I̱6?)l|hrOw:wmĿ\u&XɈ Y8%9 Z>nLGjچ=?躜ؔ—܆.|{>6SfUm<(H05Ҥ(,?gΞNg>Tۋ~KKnxK?5XO&YUӄbt2IG90.}@N'xk_wsW?I|!GFEE8TOF@#Vvh8L%UTϸZhNT hY(3ĩ!Èd7-nI4qXkXCT\cR<EڢUCTIuUG#kMu<W]#[-c /-F@#8)$U/o_nLFjw [Ox(a^-gx(z3eL}Vp&v%?2Yz?U]Y̻<d0n\OO,ê֏7w{"M|w滑8wUP%H_h_ r�W{+޸nlBސ͝F/+zaߛ 3>`?v.g *˛W<[)G]1yHxHhxxBJ#c x;ܴe+w蛿K-ǫk6b-ljl3bW6LGmGnYw3x՝'#5]2M? Yy%)*5!x8C{1nCx2û\<o#1ua-�DD_$Mk^4)udO5G.VaYEz )ڙ .ߺûyo,TH'Юy9qLjb~D\jFzW cHC\x<<6˥mɇk v 'c ݉d9?rmK6 ˮ]7_ B~qKc;{`jDzUd=Xwv9PݟL70Q?>0{ͼ2MޭUK-d܈Mo?^]$!(Yyf +P=Y4|kRn$2'_ [#| 8 Ptx1zN}ۍ@r [i&vߴ_򸖲z,*<%s;8̞Qy3Vcf.|/8-nVvnCSވS{\w̩g$O<^oS?Y{; ]q7g^{jj [d4wlFahvj/Fpk(<p+pBD_ljxl^uj<زsn.99aK3(RjRÔ_gCmdۘ~%?JA~9[T]mb{]Uq.It*/pE n-_΋(H-]N⾻Dex_ UJjDŻy9+@^6&PקVT%-Y <~/.9?5xTzߓVO;1^˾9Mo,\$}Cʐ~p2UTUByp;?N[0|=X_oƝysH{Y]o<ub}Ыܾ*_Y~TD;\6% M|]iniֶ%!Wo;R?o4$0S~WO*D1Ÿlk=y<7)M'3pazj.n̿BG [k4_\>Tt%{8 _(z_,\A9S?'G ?1>eUnߕop(X`V:1&Xv}m=D;:cD1U9TBi'͘ ID> `d 8ѳ?g"ڸ3]Z`>yzv22bw`:k,#5R˅Բi4B_Muh4WUcZ6F@#0 T遞^aL (_ HC7"=eGՃmNk`;gJ{+PݐC)Iy! <Y֌e,#oqt_qc/r Zc]Vw=K]gNvH?%rRso>44 _'/:4<"E߯p hb+_?c'_h::^tkZXt*??+W3ꙣ hG_ra5T�N&>xiC}=ܙxj}oYͼY즻zM4gSD!۶շPys\O#̓) yYEsф}9ݱ#k:gD˔s3YXLs'1}FJ^z^8)ʰ/p[mx/%cё5XydC.yôm,nf{}<(h T/#c\pW>|@,Rx.qHUb]=//r cU!ԟhs/j#-tA>zT'KF,x}lp�W{#v=g({LF=yo]VwG@ˀE-hAƋ3{D =7]O\2Z KW-,s#.5rP,xC]DO> U{__eE4zlS <ƋX‹^e`?.`׹۔>h`|xDfOMU мw]y%"9\DGr_hRօn:텋ʮ5|@3cPݽ>KU\DøϸzF-bt ݎqzQxSd>t.;@קJ7u:�U{ou3 /ep;h~הxpft\D}-.y֣�@*.|QPuً4ճL]rF@#IUF@#E4zLF@#ФۀF@#"TNJ#hRm@#xM^S'h46h&U/h4Q@#x z IF@# Tu3h4^D@Ii4S~fhTNG#hnFhMջx4Mgyh&UShr4 @_#.cN&Sh4g/=yUT%hշ?ԤePurً@^&ճu5/#`/ѤePurًO&(Or����IENDB`����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������krb5-1.16/src/windows/leash/htmlhelp/Images/Leash_menu_view.jpg�������������������������������������0000644�0007046�0000145�00000015021�13211554426�024410� 0����������������������������������������������������������������������������������������������������ustar �ghudson�������������������������libuuid�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������JFIF��x�x���C�     �C   ��]�"�������������  �J�����!"125AQSVfgu#8a 3BUq46R��������������,��������!1AQa"2qB� ��?�ՇoRd1p9\\uĶ x:@cMb~4Ys!s6.C @a�ARS;8bֳtWX**Ñ&<oeZێ!I RF'_gfD]L[4K"Ž"Cx%m*C'v7Qr^9BMQeV}9|aLmc+$mq)$$`}-5G=>jT{yQh$6�R�驯Z64^&Rm[ݶ"JԴHIi4 w pOKύVUhT:`R"H|K`)Kgrq=z2ۆ\5.Rȉ %F*̙ [ u9}K)C9鯺qwj^6CM.GLt)a.�R,xw%)I3_^ZS~4+."wf"G6�BÄg º`Wxj_Br7[iВⶅa-N�uQvĵJi\3M#Ein* rP JrHlpui;GLs$ "rf8Q=ͣ$xQYSL:%^8dcec_xٗ�CU.! B2ͽr�G$;2Uje�i.MF-Ú̀2ǶZq;|fc:X0mNt[zm*)IRKIگZ+8 p&I[e3ᗖ!-Nll=Uŏ>޾mD?*7ĖpZJ FFyTToXRr u#].Ҍ*bc1{Î4TꑹH7cq ^@鮭]Y͈i@[nBA.@W-h$ Ԡ! T)IHH(t8T‰ #)~򵝁R!T}uЗu.9IR�8q\j:aʬHK%7ɋsS'RZ`JJn7#!++C̼}(Å*{fʧ%N! Rp'ΐ-#y 6O*:"t@Sg?)wO=!QP#e[@R9S_ J7Y__5i4wقaG#rZ� wν~]K]ϩ$@u2U* dJN"fƥ=P`qJĂIyŋ&k5'cڦ4-*LFV $1V G�e6c)u V: PYm8eh)K:ոR]h؃GsW>D8_[ocx1֠3oq{7>q7IpRS:5F%Z%_K̸ڴPGCkuܑj\\O. ԔHH$ W h5rЏڹuu<n)@!�WAQ):.~@S"譙Z FqׯC`,V�Q+ @>!{5}hDvYd\YP*OrG5L~lyF*KN$gwB`~vZMqٴZ <NiTJ}i*r2R O1'r ’QKV ueOSqϬwU6d0\J"bA�ijWe=Z|Oۍ4c-,}tѯZ*t9jRS2% A zS#VRzV_ Al%!!V1%﫡~�vA�>.B_C>ݥ^b>ݣ|?}K4! |?}G~�vtiyD =[.4ću1c�ZSCh3Fm{4Zq>Ft@oac|uYtm곚i vB|!X2pR8} P~+b忩^�q;@eTj#�M2BP@۵K]6F[(IP)-6B3.AJ%G$gc]Sr8$cR�=:.j֩mZEaHe&;p(Uʟ&Rr( c23sW-m,9[v0 8ՙJKE? }G'tyzQ]Wq}" T7cl(uLCNYLvT@A)r1NNavץ̨-.V$7cGY#rTH� .)yzQ]^rUj8j2ƍ$dhnPɌB.q=wO[m̮:َt:LTv) *I+$fU><.;zk}DQLwcrA𸞋O^mqI%zQ]^rQ;MGf\:[oυ :yr%5!*Y .7$yif!t:i؊o| eD p:T~5hx;śpɢI멱ZhdpyN<>GרRJlBjm֗VРIRT�%*�5=[&|?rhѣ^saF�hѣ@4h X9@mVn9p103qPSuٌz<()$3|{ (ͳiXT1*cJ p�qx;P],ںB)~ɷvu.|#3 $y$I$I$I'I2jA~j!B[d8_( @|:v_N!oJȫ<xy8J0 JZ{px K&"ܒYeRZ. JC�u:5Ģ Ikr֕TfJw)CNTH u vgȾV!k}Q5,nHYq }lPIVI꠫ȋ"߸`DTL%4 t;yDRHq {k %HuZCj\OG/)ZؔvH#)mVl4z8A7m˴>q@3dM�@)[_2q{Hvp9MP.V̇$s &׃![IFzlVP-KRMjBRU*}2> o)oLC.nmIRCN,7CoMRc:MUlVRqTeМQ-T /n$]+R:Ar\ *huKSC0V-c;H VUw׸n9*.߮)A\6RHuy�84iB,  +~$vM4a)�yJR�sգѫ=W= W*_}m_vV isc0іF<bqʬ*iV4ujUE5& Zy**B T *oFwVAF/иU-3Xu9Bbe)C-LĶ JĠ6 Kno ?;H%9)bJlmLIT@ kڏ kGת5Y~\R.*Z4IG"6RHN7%:+{WMUgCbe ڠ2'B3ѣFPѣF4hѠ 4h,o6Κ=Mo˩ΠTKnFS]Rh+!!*N r:()PJ=u@m^�- Bs)y` +'��)H]fA'rY 4Rʆ3u z`T \ U]&IR&@Yd,RpNK%\`8R:\Ʃ *F]oRөB"rTe!Ă8+HnKz>ID( \y9Og} <KAJڶY9|Hi 7_e,ԪKEnTQ;ӯ:T{�6$skY%W&nH,ǩJ- [u9X,9R'a;l!?m<bSīSdRO5-ђ[Xwx9)4IqTbPKi.%ШŴPdҸQF~H2C))SVr=R�IǛ*ӝ"&}*cm2m)yH7TM6xpC- L.-[j8nBp:$+JʦV?�$ϣQn9 5xz$ڼV$!2if7% |; ³ 4D-&SG*SގHPSe'(x5kC qѣPF�rZkʋ"_Rdm@DڠBI’2:1뉀#[ 3!$kHM4k% 4hF�ѣFolKU.Zn҃PEjTo- mehy(`WT!M|{ (ͳ"~νh]-)`~rU]JUJqD ;w(kW%vjW%nTVt<Ԣ:J$<#.9Ī%b nVQpbM?6�7,2RHH$E-qɌFJaɸUj#3ɍK-Oaw) CjRoxRT{_UxLjtT%4vK�<R7ԑA/6NHt:{M&^Ġ+āh=-[<P/Z]չ@4� υG |qK4P>X>mَ̽*dʎ+3g;9I0nb]b‚*\իj%ɥ:!SJ+$3`:=4^k&"7HLf1TacF J$=up_f5 T)(~_1%Y85+*pSUcB2;0ktڭdĦ.NWi!fiԢ4<NN"Ƞy* 0/'vܜgN=4zԢo&F?wg! 0[|q%DU)vvҘj Ta 7¼ #`c[C0whYn4ZUoSm5o$ŬYcN_!rۄ+RvXOwЌ ?#!{{|zq޽E}>5V!Hj\Giۉ>e%C/wϜn5Fof?M?&VMHiƍf?M?&VM I57�/=Zo�_4&hc#�hiG�y1|{ (ͳ/_ݗܔH]9ۜݞ^ߋoUe%Pe{Vwh oi3 P}SGRiA*/7n��XiϧUn0cBFnsP)&&*26!,9-a*cԴ%$nNU{Q"\q^vUWXf<w*_u KB %9e=^ߋoߋo.Z/Lz]a<Y1Cs֯Jl{Ƀ'Jy%-q/ė 6+3qoLRʀr--d7%98'[c�[c� F}-Uϵu+SM^Z9e3$< S; FHfۖ.mPϕ4-J !{Ia[k[c�[c�Շnm"iWiքA٨]MFGua172;RDO(~tco vMҫ1]: 0!nK HBtʰT}5>z=5>zU.)cJ*ޱ>&^ͯmRj+x�iSU�[c�[c�jӖa4XgCHֺzk~,}}j^9}T\%۶oac8|Ԇ'���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������krb5-1.16/src/windows/leash/htmlhelp/Images/Leash_properties_krb_2.jpg������������������������������0000644�0007046�0000145�00000142163�13211554426�025675� 0����������������������������������������������������������������������������������������������������ustar �ghudson�������������������������libuuid�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������JFIF��x�x���C�     �C   �"�������������������������� ���_V6N_49ѝW6z}G}ό9|HNuKeeYEeYdVYEeYdVYEeYdVYEeYdVYEeZGiq؇`=N_O8j}-Y ݾq}__:jV`?wki5In Bꐺ. Bꐺ. B򈼢/("򈼢/("^ȡ}z656ttttttttttܰSJ5 /ZWJ4la;f[6[T ���������:'zv%ٌej<2j8#F6,`}v&iq`~wy=q]8ohu eGK_pN`g5IcGqʱe^zu*|vQڲY<twcӵ9mO=r\-ztoZ2A4C#}f7Ip�;W?Ff/Sn9rKXjd]y4<OWq=/eh#/^דa0?M<afz=njx^,0&9zekXcrOFy?YBeo=1MPW8zk o2z[{a9祰?Nk&B<.ݏN<[WtH4B~ǠQȏ8++����n}vɛ =Q uj:q÷}vDRV \.ݏN<[ݞ:oSl>?f^yJqVJƱw9;= ?�rG* n'Siu8x8>7ܺq;te3|C%?a[/p#v=;Snf&tFK/rYVhvөZ:7KU-�SN.G1`A93tВJ#Kì+,� _"wxGzv-ZV;Y9x}o<ZM ?����Ҙ+v:r+FCz3#V Ѹ=���"VSX;ڜpE,1_.by\tf%,aT12���)ܧp55-0{H9U{ ��� 7 <wcӵ9mOhbj�+Y_z44.g!DDDDDDH.SyBSԞ_K/7Yu}wf˩dQ22XfX;ڜpC40ؖG>bаTt㠫%�%œ �C4$?_?U~)sEHE.<i__61FG+H, ГC4$.ݏN<[~kKYR<{B�x^f{ܞ;Ը|71彛�~B!Ǜ|3xܽl1{sX+Fwt|o)8vu|1s|?@'+f&wxGzv- ~~, dB3`0000000QNhn͟^)K̮)"Mk!V a a aC4$.ݏN<[25OG<ﵪy{lQ [~d).i aԐܧps%FVξxPߴ ~S,UmƦ s-l�lly;?"&hI]僻jx3C 4^^;cp7T+ymm;c_#ӭΠB!NԺ.wz揓O=NwcY/f&wxGzv- &o0Lgc^Y2b�!/]!Y24/wmS^&B/]GF*u܄zU2LM hI]僻jx3C���������w���������� 7 <wcӵ9mOedBBBBBBBBBBBBBC'p#v=;Sn ~#-gέ96orzTtIev9tOԠ(/ (/ (/ (/ (/eM,N[SŸ!㝅Xz*KA2~r/a`������������C4$.ݏN<[ؑ{~y<գ<—+'=\yT~2nO6mkʢ�����������fX;ڜpC4173E~,|;V{ɯץr1sKY<_]%ZyCSЧ}JO작?zʽL��������!nwy`ǧjrڞ- p~~��~~�tv����������hI]僻jx3P/JҨ-*JҨ-*JҨ-*JҨ-*JҨ-*JҨ-*JҨ Rp(ݏN.u&thѢgF&thѢgF&thѢgF&thѢgF&thѢgF&thѢgF&thѢ;$Ǔzv;d������vvJo oYM%~:|dz @_'t8KAKymG@7G?Ngt\{ �����.( O3^ܜjYahY}:_<c;_ұ);pRO[_։pw6;�����������������������/�������#4123 5@!0P6%C��HNH8t#H8t#H8t#H8t#H8t#H8t#H8t#H8t#H8t#H8t#H8t#H8t#H8t#H8t#H8PìzJ)6Q՜D²$3S)ťʳM$ЊvuI&MF *ᴣ7f,33!$HY;, , , , , , , , , , 9茆rj9e-ȶ8%r-pS6w=|ɚU{( :+W$FoŞ& ĵNHrK"KTc#CD4CD4CB4#B4#B4#B4#B4#B4#B4#B4#B4#B4#B4#B4#B4#B4#B4#B4#B4#B4#B&(T<Zil`8z!!!!!s"Q!!!!!!!!!!!!!!!!!!!!!!!&$BWN 'œ &L,Y0adɅ &L,Y0adɅ &L,Y0adɅ &L,Y0adɅ &L,Y0adɅ &L,Y0adɅ &L,Y0adɅ &%S \N7�"I[ yʼnYe9@y"oJ/(^ߪ^< hF흚Bb$qh'�#,g&BT0adɅ &L,Y0adɅ &L,Y0adɅ6j3kwO 1W-dpY,?lvh`H A4E)_5&nBat�#,g&l&Q39|Wf8*\D,W3YFZie;<LH+*ye;s[+627-ε![bo\@Ɓ륯<VZIIu3*RFg.wJ_8k#Wi8 9E] /*8=i|VjåS~\ETѬT#)E]}u%f1Fu|؈3Y m|Vl,}# ,EɄ+;B̥ɦ> 9`kVIẤ 8<Jp\uu]'�Zà\5a(gZ.t OTӴА9buNhwi:6V}%L ٚۮ*ĺr\7S Ӥ @:QX%Ufo�J"$Q81xԢu] tDR9hXEE 6DDA<Zuޞ#*۶Q*v"q EnR7C9Fr3g(Q9Fr3g \JQ9Fr3g(Q9Frr)b.L'_q<EɄ+WLhL(vRFŊFB]*JV%ӇQ\7}V5wؤIýgAAAAAAAAAAAAv1$hù7 bcĤnEcJQ^ICEsrb2'<s\FtpG8{p@D]ĪT3TɒQ\N29ʐQXf$$ժlT!Z7=`Y٤ԥìJUbZVhfMd#էZ6h! ѱ釘x, G/i ̩ 3DHHrHvi³У"A4!ԄfZ!$*`.L'_p[*`.L'_pI=A"̍]C%?AD#uZmS^6"Z~U#$oZ%Vʫ3HxPiZk-oC g=AZhѹ'|U>\N287ys3 z9ATԎj~a�R&:1ԮJ_{ ץ#>I¨fhJ~ሳi#\,OOGs'n~.}/爹0e}<p|0:g_:G*ܰ3 zT7IT# Z%Z oʿw"G@`zt LEt3 0tBLjafHU Vߋ*`.L'_p[*`.L'_pBDFtnѺ7FtnѺ7FtnѺ7Fq7FtnѺ7FtnѺ7FtnѺ7FU5UHq\N2PxJ9y&x (OܚlCڈTf$g,th뾖l^ɸ. . . *(:*jV;fhCwP],bs9M<FJ֦b~0y!1B !E%"gL . . . W1D_ra8x4"S""}RF&ˇ1u] IaN,#1R:JaqGV0CrBi()JyXiUpIEH6r(Z@o!0߰Lj_ra8x�ԧ#㈿"qÅK :LpVA.U3oSiDjTPSXĞUE\eܮPЊJ8.L'_pN<&4S ަF*GUVȮd$v#Ҽ- Bд- Bд- Bд�))pj :;Z6xtne/;hF*IVʹQg(g٥%,Q@Y .oRjRn^M;ՔplhZhZ <q\N29GS!8.L'_ppw$ ]C%=@)H0A2+>1ucfzش:[GSi#xP/ dcn=˾ERE 6+T}$e{ym?~E&GoaӉMJդp'?U9Cijh3zaӉ{B8v[4GSه&:,^9A�pL1ItrwMNg 0\~E&GoA$vy`SR=ˉTafk?X$/0+^&s2OT~9}f`z ,IL0*t:3 Jen #x/爹0e}<s�. . . . . . hu#UStnѺ7FtnѺ7FtnѺ7F2ԉx/爹0e}<pE=R=T賄Tzmle(Zr7=#3zW+㈿"qSf-i j 磹9N]FO>~pSx2<xc!q!C2d8q!CS& l O /lÇ G/(0,"8( *\Y¸*Xzv$*pjh%AL<"YLYLYLYLYLYL#N_ra8x%h{5 W.;GqDU/U$JEGqAWGS25ƣ ˫YwPZhq5ơT㈿"q 7p[8Q~'?U09z,[W=/G탅,,t5voT~9>v:F%wWn:X҆$wHHN~ag&rh5vo/Dx/爹0e}<s} VhF`8E~'?U%YL:#šmWm(Ϫ?J{z+U0,ucc]6t$}$bٵ3u$ "iwڱQ/Dx/爹0e}<s}H `g/z#euX5?JFe ` _" `WOE#cX5UnIz#<EɄ+㜦FtnѺ7FtnѺ7FtnѺ-HTRd8q!C2d8q!C2d8q!C2 ㈿"q�NG#<EɄ+�RG"x W=Ѻ7FtnѺ7FtnѺ7FtnѺ-(cѺ7FtnѺ7FtnѺ7FtnѺ7A 1\N2�x WQ&l&Q39|m![v$dIfY˗*C6U%gP4U\ZFDjFDjFDjFDjFDjFDjFDjFDjFDjG_ra8]2m 2 &*pUB&RPydQqLe\T:bW9r.\8qpË.\8qpË.\8qpË.\8qpË.\8qp<q\N2?tx/爹0e}<qWk}Y, OS*9 "S#lRIV4*�E&G"iMjҤl| GiQ + wEXn8)HoU]OlG G"x W#9.LS<q\N28p,. 4I^%9bRJ Tؑ%w CU" r8.L'_p4�Л~D|b=іf@ ->RnOYnGUTdZ_M."UwE_U,;%\(zʩUcAj%]I 7lZ/<EɄ+゛ x'"eH7"x/爹0e}<_ra8x�㈿"q :FjFDjFDjFDjFDjFDjFDjFDjFDjFDjFDjFDjFDjFDjFE&qpË.\8qpË.\8qpË.\8qpË.\8qpË.\8qpË.\8qpË.\8zE&S&:Ɏc&:Ɏc&:Ɏc&:Ɏc&:Ɏc&:Ɏc&:Ɏc&:Ɏc&:Ɏc&:Ɏc&:Ɏc&:Ɏc&:Ɏc&:Ɏc&:Ɉ."qEgWM$4CM$4CM$4CM$4Bu,bTm6clmM$)WMnlm6alz&Cm6cl5s>"q}\'%xYTzc?GM51O9b!磾,?!%,t1:Ծ_rv&&Bj�/BNњ:WML<rMX96v3EC,? eY9(dd>luTHz~N3X\z&1mcLJŏ<>,x|X 5J'vF4dh;#A"Tdh;#AvF4 #C51#AvF4dh4I1$RȖD%,<aK"XyȖD%,<aK"XyȖD%,<aK"XyȖD%,<aK"XyȖD%,<aK"XyȖD%,<aK"XyȖD%,<aK"XyȖD%,<`�,� ��������� !A01PQ`@aq�?j5qY'FS}H0GKAXűeسdj55nH@oUDt r4o=+d1jijb-`7WR0_pct 0 VV ;N毟stZ2IfOw2]�)��������!1 A0@aQqB�?*(:AAAAA?zO򢦥QRI0#$1# I$I$I$I$I$|-hѫ)V{)ӂ2mRo$rnVF9}1˘nEؐg8aUpU =VG9a%VvgYܧz d,"@wSݶ0a0aVl-S[jpUu�2 pU{{};=~0ڷ}{>pUjpU %AŔae^fd};W/ϾV (>}u8*km56pUgYeyV{pU[>N\H)Vv= qŅ9aŅT2pzpUgYVzw5mK^g4 (iCJP҆4 (iCJP҆4 (iCJP҆4 (iCJR�O� ��!123A"CQaq#5rst 4BR@b$P0Sc��?mVgCTo3ǣǣǣǣǣǣǣǣǣǣǣǣǣǣǣǣǣǣǣǣǣǣǣǣǣǣǣǣǣǣǣǣǣǣǣǣǣǣǣǣǣǣǣǣǣǣǣǣǣǣǣǣǣǣǣǣǣǣ 2OhH{'i]c�qXw�m=[K|T֤.V'#'lJJPdR/#U7qЅ /<apVըkV|ᣄ' :!D^%( $/d'p'16*"v5lۡtj9e!4|7A3Ⴊuø0F ǙN)O4 6yBԐE;bRW2"s!<\J&V|[#KLP>+WTTUyߋ)VU  Ea0 *fguj�'J~ZY¦Zʎ0a�o1E<'(g@68t[.%%hem4jbXFRڟ*RV!+ R*ߌPJ0jqO'Tf|RohRUD1,BnFUjmҠj1v~LX$yH@@ >l2 t+o}MUҹWe0\JJi: ıN/( S(B*LS]4J@ 6)agU!nԥHXB0)xWҙ)|�t֢VMbT] iR>H(eZ}n _�_E@0YOaKUm̾<1G;#vF%XJ>}c1(dbQģG;#vEчGdbQģG;#vF%XJ>}c1(dbQģG;#vF%XJ>}c1(dbQģG;#vF%XJ>}c1(dbQģG;#vF%XJ>}c1(dbQģG;#vF%XJ>}c1(dbQģG;#vF%XJ>}c0%n][#T~Kq7̴.,�S.~zFm1Lfm1Lfm1Lfm1Lfm1Lfm1Lfm1Lfm1Lfm1Lfm1Lfm1Lfm1Lfm1Lfm1Lfm1L( O]KW =oἥ26Kd)<zvJt)LYfSutsB *S+ 2FR0EDUD~XԆP+$EY,MZP$gŐ*p*/V@`B]BHmDJJt<+12*ӈ24vXji3HWe! MuF iTeԺsJR " B벑86:aM QS#Jg @L-eemXdBRA?½$C]KW %m1Lfm1Lfm1Lfm1Lfm1Lf CkaK4Jj֪?D&()[a)Y@;nSEf +p6hZˊM_6Q↛Z]*BFwNXLLa% z8ݤ1WpZW_ a ˁ`bՄ!)Uf$ 3<RUW<Iڔ(J'2X 8tjRԩ1T<^sOB_j$IN<8 չ«-[(h9I KRԛ x)+[ ]`z(=RUoD'P4-Y�0ZAR;Y!U%H|5Fm.RԚb�qHdQұȤ: C.(;,|L-U!8ʔ:ZRK۳]m) : *[K FqHp+gt~a hL~TϚ4&]EQP8𤼬)?z@5?y4HK*AQT4 %k85@ūp PZed<LVP;%)*.l)U@SRuFi ⶣTs,<3FTK$)Hk'<-eRjT#ZBCBT"i"w-5BK+L)I*n]eYŶaP87)d3ÍΠP[{ 1ҥYI1R+PmWU0|c1)4Ø%&V9Y1ল-LJwi%US-iu6w#DBi}-oL`fGm0,9Vu)+*W<KlcE9' MvcY;!TBU52'uq!j3RI' u/\$B}Q ZUZ%.yl4HNmMDv]`E5-޿<P*hfI˳~Ii+92꒴+UbmL튩y Ԭت&ֲFl%i,0Bj'JegC|$W;Q->y5jVE`%Z ks JZr#IM\̐(* ] ކ% `6.*`Js%_E !eUۘ?0̙1^Lư[%8R+Wj`ThK<•Y *~8dQJM)vX./VW<RUW<Ii  R+ !2+ < 5nL>PY�̚lK�/R#A*CN&UESqʤ> PH'"MUU2=F*B x'm[WP>`f,bB(T.¨L)d mTY% Z+!ś*I-3%NMj"k_ekZԧac*Xoϙ�RQ9<D7;5T/)TER8qM �ќtqER^lp0ТJ| Xiթ M\uJI'biBSWG)!&ʥO4-ha/Qp+qDi=B/]@d.p]^t̏3:i\AM:[0㎩]+{&@ߏ`fYWBKITS/!lB'OE"Ԃ@+wdQM�C)q3O]6|ʋQ'ͦvYh uਥMb Baab u/\$B}QbnP6D2c&4Li12cLdƘɍ1c&4Li12cLdƘSn4^&beLdƘɍ1c&4Li12cLdƘɍ1c&4LiؑJm9BFd!߄O?){5Կpz GUUU ̔폥aSoΪUg/RG,�/qĈΤbq"VjKIi5P=dG4`>bP) ry_5bb.YEyʎ.:a yyځņk@)"۳qp 0'Em(+&L#HnB7%Z-QR!֐d\m 3XI4O8B*a@d~CNom\R5k'ldUVvEZk'ldUVvEZk'ldUVvEZ j x𩠢?C iu0q9>!T͗E %]%\q©7n*$Hg2ϚpQ!K\f?QIrR-A$a.>*$L֟ޘS fTlf9Ѩ+/r O?nxA[aIaV~KHB(ԗHf+.nhZiU&n6ݞPZ\%r]<椳sRR kTAGCtj%B+ 9REG(aH?؜ݕo;R<JE6>B)MIf6 7d� DhyjMb* b@>* 46ebgQRIO\"d팊2*NȫY;c"d킥23N#C]KW Tp3 |eJ5*Pkie9e%u I!\M'eS TU%Rs0 RrqK"g7Zl'qW~m%BV 5]R�J( %`&A+橕MPٚ,L֣+L�%)+ HM&L�YbQ$Jj�p+!+JV0iSTMDŷpmbf9 eYD(+EטZ0V.S53)kc)CJHDM[n YIJ8kj/m155At`$0#70kKzb&DmQ*yRu rC[dל]Um' za~l(QRI *Y)*W m BDFoa]|x=_=MHfϬ?=W_7pS~!>g٧My*E&>L#q<tiUYm@%Rʼ(@XD}6Gd<>:+na$~hS%Vy dy%(*K qc8ꏷ5[}#KKhkR4 F_~dž x% JC>L!N*N)MN1TmE)"SG7ԥ_i-H4y쏷5}3\l$�SӗSjDH\�KwYF[8}3\l5K}%N*WZ!2C`Hc* +C]KW Tp3Ci֢jF"-Bdz4.) 쒂J3�J]yKJV)襸[BRkbQICi$gu$6m9T' A2M6OQ!�Pg$.\dž*u%/R qI?tJP(K9P-0 u%J¹5&<H~&v3R[](JV1Hm8˕+6 <ݏ4C.TmhlmJb5p^W/#Ri"*>a]|x=_=MHf (BJ gEe4r>Nהը+iy] �#>Ϣ3m̅3:�)2(4(Ϣ3lc�}f1ᥕZzDgA͡XHKH%CCk <>Ϣ3)!B# )HFfY0N0Q[#>Ϣ�RB#&Ғ'hgC RUoD' 4}f11Pº){5Կpz G温 ;krZv9-sݎK\%wc;krZv9-sݎK\%wc;krZv9-sݎK\%wc;k)DZh LO4rZv9-sݎK\%wc;krZv9-sݎK\%wc;krZv9-sݎK\%wc;krZv9-s݅ Xvzx){5Կpz G�!.HCHO[[Ul0k $N8p).[m8GPqoިi;dRꬓTg hi Y"Jd6 �g,7',UUHP%U ebL2xVdl)ҦR[k i G$Zy;PqqT9 ="  gYsf7xTJԀQ#/mp$A1wVɻ+dd앲2nJ7{%lFM[#&dwVɻ+dd앲2nJ�1AISH>} @~(Kh̕T@Veq Hvx0!z"2 �?L餔`V լ~OРZ͕B Wlmm;X%#yTܫj IuihX &Lqi Cg @~(R0CVqVUNBG)N-tvԄFj]0-I$ m˩bjQũ4Ny9 7"SY+M[#&dwVɻ+dd앲2nJ7{%lFM[#&dwVɻ+d."cC]KW Tp3xYR[!)jHm$)IryJBj%8 iO+L4eBE-9RB#)mB:%Y$&4ʤ>Z BSYr m71W[iP҈g|*'YU*ZՂjgyaiEʕe;9NH sL.h"8Wu.vR[( "$gmHyjUzDC(9#Ufr JF0:ա)H<a(Y�"W.Mg^9Ϟ*FEg%G@Bm?(UFHp%%7+%;m}+"Ԣ'y<`GZ8JӬ�0d"k>=x=_=MHfx5f o u/\$B}QϳOwpmDQ>BJ۞q)Ϣ Ԡ JQmV m(�oMUN$* "8^+UMPP4(]1‚~9jY'A[U2!h) g:�aĤ̶7S* %+_D$!"GDMJ 4(]1�-f o u/\$B}QϳOt69u#�X{VJpei`xME^0U,EuX5[4[.6G ui'lS<+x% JƸ愚ԥ6))By�)%mC%M\i-ǐ^RTb8ߤ)s奩,ipvLצ;"<yУIu 4*TQwwc*쌫۲2�nʻ#*쌫۲2�nʻ#*쌫۲2�nʻ LVX_$*\4ReiP*gLƬSVRA,-C]zl-TĄjEOe)R)bIZ—5m0kyR//gV$;2`!B¾¨8d6Sb,*�@$.~xyKzl6*8QH‡Uj[d' i8DM}suN*nQ+3dctEuԩ.MV(O'wPaVK�j5\UHSCNZ_(qJU12q!2ZOeNX5&qD7C5\{ MkIYl۲2�nʻ#*쌫۲2�n33U< 4pS}k~*7"}{O)W0D=W_)W< 4pS}k~*7"}{O]6(ĨJok]{ h@3:m>!BUgGB\/ )Pokf׾c3&S%Vy dmBP[5X>m)*QUP#>L t(g)ʵYNY4c$ڑ1֯a{0tCu( mBR鏷5}3\l4YF yU)In deHuRUbٷqf u-4ַ�CmA@*&J\S̞:7] Ș}3\l5JB5@GD>%IAnY=jǁf o u/\$B}QϳOt3)k_< 8O!% d4R([iu-)ZJL3[(aK(()&6n GӁ p4RP@E%҅]Zҕc1(CUk_< t#j<U7RxiXY PʰqpcS$JSn)2$}Dk" +)ICi$gu$6m9T' A2M6Kem2(Mv>r}XeBό}jJ^Kk,LdW@˂-i%i &lJB*@Ŭa-0%*K-BW< 4pS}k~*7"}{OMF]j&3 _rM)�|xiqB@Ϣ3 Fu% LgpMMFH$>z5z+OH#>Ϣ -֨6�OĤ6VTy#>ϢJg#11u$$$_!EIUWг#>Ϣ8ɬ&/4;@ꧭ_3M!߄O8iU(gTOɻ+dd앲2nJ7{%lFM[#&dwVɻ+dd앲2nJ7{%lFM[#&dwVɻ+dd앲2nJ7{%lFM[#&dwVLM2"_x_ dֹݎK\%wc;krZv9-sݎK\%wc;krZv9-sݎK\%wc;krZv9-s݄A6:g٧C]KW Tp3AHRwfN5AY5NIKf5}3 q!@*He[D%& jUjw}BaLQڒwR,WUUY<٦)B,ƕ!$%U l2}{){5Կpz G>=R@o"y"YA~iW&Y㭬&VE"Қ<_]Zjmhv10)�)&MPKh%0t`CUL$>fQEI-y|I}iLֳ`FUBk _8�Mmn% Lnt ET6)'4!>Ta5DPָX_�?2te~'іOe,FY={/d_2te~'іOe}D5ҸE 3+W7\:B"I�R{⊥PTl3* D}B* DP _8{lRԿ4%*CPPAqm0igXo@0ePS_έĖӥSNJSA.'&s[(Ȓh%M_6S"jB3fla m(yQ)';=J l;5'Ψ-&H [t*8WU;g�(QP]tROԩq�Ω 1*a2I⫏Ż4/Feٟ<:h"8 -KCiP8Ź̛;v+Vع].WhrEm`s?}{){5Կpz G>=Y(ԥ,#Tةy *Gة;bv?h2Dn}30 -%h>z5ϳOt8QUR[hN>L }30 -%h8B3;cv>L h/:NuS|t靁;۟pHg}SϳOw7pS~!>g٧?5/ݕZk DyWulJT3d3CKJl,VE) IUGSJRk#*Maj�8Qaުd#㟅$hRUIQ�) @Yn-^!*m`֯a}{*-+T'm) _}?mJ8j:_%"H #q.(}4J3/Q�* fBz�X0o񶩎 GÂUFҔ03jTdRyR& �Ui3M!߄O8iz< zP4U~hhɏ'm^kNKXwh[%qoQڛLŔ:B�AVT, K(qpHa/\OZ1"8ip\>WrEJO9AVT,iK)-]%e?yo<Y)% Q(SyLT�HRW@8) UvZ&h0( Z 2TB%i1]O>=x=_=MHfgSZIOL\tL.ۢm2鋎}G\JNV3.:b.:~z5ϳOt,!'1q1qpQAbG8鋎Kno�.:b.:`YO>=x=_=MHfAMY,~krZv9-sݎK\%wc;krZv9-sݎK\%wc;krZv9-sݎK\%wc;H&gY0GSL�~'іOe,FY={/d_2te~'іOe,FY={/d_2te~'іOe,FY={/d_2te~<jĪ, 4pS}k~*7"}{k#}{){5Կpz G>=ŵk>=x=_=MH \TrZv9-sݎK\%wc;krZv9-sݎK\%wc;krZv9-sݎK\%wc;krZvUV6y#;krZv9-sݎK\%wc;krZv9-sݎK\%wc;krZv9-sݎK\%wc;krZvLU YM!߄O?){5Կpz G'ք2n (: ҕ 5Jό:/@n3ipJ56Ք3_�|SR kYg 4\ TӍxf/45ZS(4q(M"4[ _M.I!%)BBX%1|Fa3JS3wRDSM ZAU�&9�-,q)B)0m0VYH:SV [|$p> eev_ŔCw9[(u�іFedkFYіFedkFYіFedkFYіFedkFYіFedkFYіFedkFYіFedkFYіFedkFYіFedkFYіFex){5Կpz G"fX4Co֕F։K[ 6,%SQ as4D8G)Mfs+Fxm-JZg+S0.$<Hz- 3*bn *`aڥ$-+!kI 98_fjk?$UZ;!OJBi bYdRlYK\+n V()#u†le]i)qJD*_͞>R7f;mA8qՅWڷ[þP$j$DўF1c1t1Lc1t1Lc1t1Lc1t1Lc1t1Lc1t1Lc1t1Lc1t1Lc1t1Lc1t>=x=_=MHf}{){5Կpz G>=$, Q b=Ђ~9jY'A[U2!h) T$gPy5N/?G놪&O[*hB_㩵HjYlV»jEa&-?8?h#?#>=x=_=MHflI t(!ԝ$pD)+* ijSIce9,kL#! Os9i<GųLVrzkVD|pGn^ɇksEF9IivԱd<B<eҎ+d$TTswBtPCˍi Z1uSYU6p9\%3-*xBYmn,vYp9EG`u@Bhu(ŨR ]0 B4M)*NvP0nډ[X�GIlS@B9E ?4pS}k~*7"}{,QtI L4pS}k~*7"}{X']YMi4BP(O-�!Y#�j7v.:`)$)&Fx.+03BP.l VqA"kKUI3+ L'?qa$LF@@qPf嶩iRUoD' 4pv?p$6BWjEBcBOymHRZl�&Fp~`|\V$fןm&骧AjT{!(I[˧6[O_sLjI4b8HUB,iT=�\NGadnkw.;cUeXyPT� _[n%VN #}QE,&iNz:?)( fR)%UR` cgDSOy*I @ !sx} h(SLYK"h)^�)Z($'ګMGѮl<f EE)UVZq5Ո2LICyKjmS �g4�TJ˩Ny!9Uάv>R fC1o?A~MMSVPJ"l"p5R).=P;Š�*o5`Rk"T1j͜RyiRUoD' 4pY)3h!G0$UJDԤ̶k'_3M!߄O8i�8g٧C]KW Tp3pϳOw7pS~!>haQ0#Z2֌5,h#Z2֌5,h#Z2֌5,h#Z2֌5,h#Z2֌5,h#Z2֌5,h#Z2֌5,h#Z2֌5,h#Z2֌5,h#Z2֌5,h#Z2֌5,h#Z2֌5,h#Z2֌5,h#Z2֌5f o u/\$B}Qt1Lc1t1Lc1t1Lc1t1Lc1t1Lc1t1Lc1t1Lc1t1Lc1t1Lc1t1Lc1t1Lc1t1Lc1t1Lc1t1Lc1o7pS~ Gp>Ţ+dbu1h]elZ.F-Y[#EVŢ+dbu1h]elZ.F-Y[#EVŢ+dbu1h]elZ.F-Y[#EVŢ+dbu1h]elZ.F-Y[#EVŢ+dbu1h]elZ.F-Y[#EVŢ+dbu1h]elZ.F-Y[#EVŢ+dbu1h]elZ.F-Y[#EVŢ+dbu1hWqCe_=MHm(+q` U=!D_Ǥ(ѫ5FcOzBݏHQ?W 'j�vU⏹ N.VZbi.VZbi5D8Ve+L\1r+L\1r+LH5*ό+L\1r+L\1r$v!߄~x.}Eqi(I9T0Qty s0 XB3 .)jU~:VÎ:i* i&ًsCtZRU zj *9DJ0텲2eÞm +ڔiA9⃉Hrqgޡ</=!M&հtnGE IEj$UշfK [.qښD J8Q/W )INM)2N7P;m qMb 1GvSio&%6_){5Կpz/$HU�#,޴e֌zВ낲nSo+`eуL`O7N!-^rzіoZ)!%FYDۊB PiI#Q)( oM`\a0˯9ƒ( uK{1BMBFFPJV$)uCfn!*UYDNfHBCR[/W ܗi Q�83�U[.\`"I�Y9e�RC]KW ¥J ҕWYLٺ".oFE\ތԹsz2.�Rd]ȻKёw7ÄƐ*uM2Ev1+lb+VWh[c]"EmEv(1+lb+VWh[c]"EmEv1+l@RNr"EmEv1+lb+VWh[c]KI 5ԿpQHLL%Q) nj󓟮?�*������!1AQaq 0P@��?!76VӺN;ӺN;ӺN;ӺN;ӺN;ӺN;ӺN;ӺN;ӺN;ӺN;ӺN;ӺN;ӺN;ӺN;ӺD қ]{zx*ݫLjTZ:KvT)DC:EpէUfbmmT!]ZS2@c QiY^s hZV)DCe�2KcY (T~.tނS=====================3_ Sِ޹CACLi=�I1!E\]qGC:*u�\P|RʳZLXL:2zzqVŸK@Pe.W@pѿhq0UUK-C-RmѤW".Es}LTt UUʅ%+ڇPa㤱>lhkc)@ܧ�}{g{g{'{'{'{'{'{'{'{'{'{'{'{'{'{'{'{'{'{'{&#"srOn-]mv67NWm,tlٳf͛6ipZ3f͛6lٳf۷nݻv۷nݻv۷nݻv۷nݻv۷nТFZ/ҭT Pet/ʚr3Ο: 3Ο: 3Ο: 3Ο: 3Ο: 3Ο: 3Ο: 3Ο: 3Ο: 3Ο: 3Ο: 3Ο: 3Ο: 3Ο: 3] 4�x?�=ֹfUe5雧>@Q{^cAm O#hU4l6tX�8Di2Rحp:!e 0AjS\y.裗TÆU^Sͦ]@:G+ \jTv1GG{g0Áv2JT:|bjjo�;oX)wr3Ο: 3Ο: 3Ο: 3Ο: 3Ο: 0O:@ &�1rǎ Z�] -u=$ʝ/ͣ O:娵+]\FZz5QbU"-c/KXڵa\pƥAj?+@h}]FځS q2⅓gl42Y^ӧl�xxÉm d{m',t@(O@Krk1$E[p{DYjqm2� kMjZ-c~ CBFxU 2sҀ[n\.fZr�Q; 9xRnTo:cpQ]%L@2Uahz`&Է!w5+UFo31Tb_:b6]9Xӷm`2R]G, «5 {8 * ua ! Bk5؞aD!rT<E7`݉QKKei|&u/d ^ k'm.2Nu= Aazg`Zu0`%Zttg+Ӳ m{D"#NbiVk|*,W86$i47EbaDu1GuH`s ygC4o>b:s1fQ~'w}?Q�FR\@rl']juZ^BqaUBU^gtRFL4dKnl}~d[nV;n )A` )b=ʩRTPNt=RBUB63UΥW]cws= F7Ay? ^hofxy {u$n&2ì/Cq7F^zZիead`p4 ތLel݂%_Up� z VJ艅\#A НxTL,1jALfellќe:13ʮD5P-SuZs3xH!+<H,VTBP64UM<orbnl]]B XYYyà^� SJe$ɋU%/ &7-kEPQLjY0g 70uH.s^:U%vC2>>1k 'ٷjWa2٠EKb5k@6/Fb A+&v`# @ iWXle]f� EYISY NuD: xzǏ8�juYq<y'O8q<yD 0IzO8q<y'O8Q<Y"]Fb#rc?pа@e,[3E_ۙ]iX3FЩs𼆚քZf4G VRAĢj yu0e-ák Xo6 J6I fT? 5~\ױr̰3 LCí - 0ZΟ.\r˗.\v�d*I�ccE kZD:bJZ4ZPWKC ˫4b uu_JL$m `0Ɠ@f SgLׂ^KR)we<eD1Ri,"6 %ܢ~9#@j+x3,Ѧ+^JQ'; meI BԴ!-Z0ޭX[TԨ)A|)̟�5ΗXyH#?r˗ %QƬxÏN+(st6؍ ;\}(,e6#*1i8ɽib cKp S:0 '@6(4G@B}E7A’Uʹxhy BlD,v) hP#ks *2W{ʽ \ ˜ybې>[-Qg,l-.)tZ %RԠWU�{B`m{g@?x9A@\˜AZMqi4j@4˰?jǏ8<O=;F~ P`r>@80o#Iz^`̕W%P㮊Sa6P"* ^k )X]2 ?An�XGB P�|ڏ4?B{9\ocln<zMbaG+'_Xߏ(�ֶ IO�j:7WTϧmԆ:BPEҝ.,.]&+I _ <Nє"uU"4n47jR_+ƋlƜz9|gKVk\ 4ڡn?otףxvcg<j_In\5tOӕ=ko6SSPH`2@+ۗ<O=;DyEJ"Em? �J jl^N!n͐5J%|7:~MRQ4 VW@ W1+ۣy𣭆+LJvo3Jݨ~JuW+䊌17$V~q)| W+A K0-%ƬxÏNk?pҘUq\eWUUq\eWUUq\eWUUq\eWUUq\eWUUq\eWUUqjc!oWUUq\eWUUq\eWUUq\eWUUq\eWUUq\eWUUq\eWUUq DdSՏq+"wm޳վ3S @^]boTCt$U=RЕɩY&tn[KEmtn V$�@%^5YZwQ9*ʆλE_'L8�eYRB) w0Yh@ EQEQE`߫L19= /*9ɷYpj q+kjH740[=M M.P$(uCEKe}l!`de%BE@rGJU"Ŧ@0V G%m�kfdTAg}?EQEQEPy0,jǏ8a)a UH&5X *?J3* @ڻ`xЪk7i(`XAMlĎLHٕ(4%EXy�βMr.k�3e˾ɧ]fZE1FFK˦E9 cL?Lsą[@,ƛi36!yQP]n{m/h!(YvVl� lf+$Afs!lD"x3v؃چ(K�#NfNwģ SC3`a �'^?pӻ�pwՏq[ pf:n�P;-Ɓ}A)ie7KpAUl4;�6ApDUnSIcI2|6X|;1tWA:|bjjo.+Q\/IJ&F4mX4ˈHVdl�wՏq(+to%�3NE6ICZ^;#�@h٭ |:nT1T-=NFK MfutLJMR5&QU,UudX qև1֪QMj;;{{{{{{{{{{{Zh :.zԦf_ Y3IՕX VMb63'd`M5d<>PMTZc33,)c3}t_;~ʢi(m@F&*jXE0m70[k;-ŋT޷fEo@YK q [leLYcccccbեF@i=;ƬxÏN�c'_~?XߏLlzUZ W@C(K/OU&HU0j+@!JqM˕!ZUkOPLlz#Z�+Ϸ �{An@,k9at\t6C[sWf`�^(>KXIp`�?pӻ_ĥij@0tŏ=JzvHhz bR Z֌\m CjM͔|�ZU0?RyB,αa{̌ D^u{[(D꫟t3uiN lֲà XNT$Ϛ0$A/{uuohSVqx("0IS]m=;W)�?J&znu%\|ʥ-ٲ_$`wS1L$W �:<̺ $hkkoG?%� W+䘐іLCe|I_$'"ҟѢ5Qe|I_$b 0-%~?Xߌ9 Yc?EQEQEQEQEQE^J0"KQۊʮ2*ʮ2*ʮ2*ʮ2*ʮ2*ʮ2*ծwϧwՏq<xR+6Y5~ge 0Vw`sнfJ&,.^m[0%)swxًd.] TX&tA5&tY=;rJ�4FIN'TxK=tД)9T&JPj \D-�&R!eW!PlEjŷBᜐ ȄyP>o0^ rjPce,<<<<<<<<<<<<!CZOע,ICL Y]i3WXdGrmɍP=f6z6:>Kp릵yo 'ٷjWazƌfb7&5 X* `?ʊ(Uܦ]@2Rƃm{,r(<1~ok{WXYnQ`I7XU7rt52mҏεjիVYB\w~?Xߏ)'YC@U;^ 滧2ަX`Hh~~ݕ^wZiGe�YŮ` ){:_Z/ZSM)*{9oM4!mi?pӻ_~ϒbDDS>ݯcӶCC)D]Sf׮Z)p 'kG׺q׉.A*ƳDk0m`oEߏPm ڌjm>]d�PV~?Ĵk mkmB=?4�gmԆR)4: DR[i;ƬxÏNˑQ+dpl؊uON۩ J9k0dUJ ^Ǥcf3V]:t6Զ3oEߏநWdqcf3њŊ  rϩ\UPV߸:nU^Rs6`OYLȺ8TR;ƬxÏN">-ŝo\>- =M ̷>3տOoEߌ]o}KC[S=[ )8-o}ML_V́�C[R_Ow~?Xߌx4q\eWUUq\eWUUq\eWUUq\eWUUq\eWUUq\eWUU]LTKTցQUo)GwՏq�GjǏ8#5czSբʮ2*ʮ2*ʮ2*ʮ2*ʮ2*ʮ2*ʮ2R*ʮ2*ʮ2*ʮ2*ʮ2*ʮ2*ʮ2*ʮ2:KV<~= 4�̶߆i :p[Xٌ'%P9YWHQX٭JJnˎ ,ouF/FOH}4)?*u\p~ET"QbZV !X**q� o ;Xl"bqeM3m�*joqXYQ@HO <*xTS§O <*xTS§O <*xTS§O <*xTS§O <*xTP@ Տqgw}?Q�FR\@rl']juZ^BqaU�HrX2%*hk7RX7 *K ʿq ul�d(4@7UpEi8@7 ޣa'&J?aj�xN >(J�OkZֵkZֵkZֵkZֵkZַwՏq�=;GʶppBnpv$b讃Jt@fQ|JAh$t�Պ_WQS&NHEr(-AZvG'wՏq B|H8tz1( \Pff`^1P 䫼v 7;9ÍJ`6UfPrŵ]TjMLTB1L;Y0(ҍ ytbZq՝lET(Ѥ8ЕehkHȯPV`٢|ɺQ\ @ 7{i̶0YS]Jw~?XߏR0.?pӻzyuLFy F'"vIٲƓTX5k|6l(%Ű8U2 Z>ʺM?w~?Xߏ�2gtI]kMZZD `V"F9Ϝ0ld=$ 5{ D-Lyt? )b{A =R 㢘Am�w8 %)7�3m̀Z�m A)P@Qu,pWP5|e h+1(tX`|:`یKmod2k gDCWW i[J%g2Z<U5S ]1@X* 0gR _ƬxÏNҐJJ(GJRk!�p}�Жnu,R~?Xߏ?pӻ�q5cz0$F <*xTS§O <*xTS§O <*xTS§O <*xTS§O <*xTS§O <*xTS§O <*xTSƧwՏqֵkZֵkZֵkZֵkZֵkZֵkZֵkYyV .\r˗.\r˗.\r˗.\r˗.\r˗.\r˗.\r˗.gȰ8�8bӳkC 0`G,�k-TWԿ꾥�U/}K__R�lB ZM}K__R�WԿ꾥�U/ i0<>�U/}K__R�WԿ꾢<j oǎh66g&toURQ3vSUJ*uOaԴiz CEF7 B +N\'= uNUeun ( Vxp;{`}�_Z4, TE\r$: `l�8r~#<Fx ADӌi]UdmзNO#.1�=O44@M"()`e6!RjsR Cy@R#g1tp`ظOzZEN2Ka#:kEU)oaX r_[G"P3K)1H\CHXǏۥ|�VZjըu).m׹>|ϟ~Qو)'ϟ>|ٯ/V&~|ϟ>aiA=#bD tJ*TRJ*TRJ*TRJ*TRJ*TRJ*TRJ*TRJ*Ts0 R� �����#8��������������5$A G,,,  }MW<<2<;m><<B. rS($91�KB]\w,Ҟ3�|ͤ;0_|o����o_ǭ�:]㌷����yz:]z W//�x3}:]{�ӽs�:]<<�t<:\\羷����9ǽ���z]ypZ5����|?�z]~}1Ͼ��S-/�z]z\|6�}hz]z���<�v�z]v>>O��ì(\NeO�z]zSy�ëuW?Uz]y޻�>��dz�z]������������������z]�������������������^y/mb 0 0 0 0 ]�{������������z]z|�������������z]z �.vT>S���������z]{|=?O��������z]qqqqqqqF0AAAAAAAB[�������>篶sO[������C�0 ##0@1B        �)��������!1Aa Q0q@�?}{3J<o#Zo?hVqqqqs"b+`~pߞFa!HT�wRL ?.5x2OC1�?P@�(B!D"B!D"B!H9HB,j,ꉩ[Tpx^*Ej҇7њrE /PEU;['<]ĵf)sLQ[cx-K/㾵( $c<)L%gCWVzTk{2Zo}MaF w;$#WGSao aA~NA5@ߴ�g9k aBo(E켈�#igwN&[/Zi &3hjHOejF[2!�$XJ'ר U`!�{zăoqpxrNj `oSBAg0ŠFpVml}Gn;@o &B|BP.#9z&[�b;t�ﺨo-p?n =dL!S=0@Q k)~ .DD"J,dPo,iG۷SR pA|Nl%vnRF&A s@,M3+ �Xc �: _^\o]{GHj=�U7@UP-F[~c)hP7B�g Ȃ?X��`%H/GLAcڎy ]7A bG Njo7\̵yz>_ogk_[[ ox_?鴗e ,-? bce252'}="IXf�ek{f;?n&yo|"=sx-E�? yx-Byy_ԍYn X 8 zipoվGxf3c1f3c1f3c1f3c8�)� ������!1AQaq 0@�?MG,ewdS<刞{ǃ؞q s+<<ǜy8q<yǘ1c<ǜy8q<yǘ1c<ǜy8q<UNp=N.xHLR=EWđ")T}MA #1W]އ*Vbo &o &o &o &o &UawAʵ!+rʦ>9J*leeeeeeeeeeeq&$*}_G ͯOH[\>UUJ)V~ s#F0;<h^GȄ+>%ly Zz{ }XwI?*""VWcbܘx@�z/ji9y!:1 (I'{,BD}@Rd/0:Pzn۩0Ϭz@HE "K :Z۳p�X̿@@}i5卨, pqZ`;<%kFWA#/۬XpWop/fz@X{^:|!2h�4KD@4;*%}w56ҳ�bWeJvx@!Zp%jEEw!$c+@I?Q{JB`2F�[&iq6qg^^ �R1F�~F^x+ 3c2URF_y�X�=tnp !0v M%217}暾"C�XxH(X eRo!a/ejNKT* G<@>zUd$r'q H*@J xU>yZ#Ntteɝ\oJT [G2Ha*Љa*$H�e�D|: &<B$0]<�po�\l!#<#\ ' >.0raE 52Ֆ�R@o Gf l$� yR& o �p#MX̹{!~~Wcvq� 59.޹89yZ0p\q�xAr X׬   =w&X t_G6�6"m%B{S̀; AfuWE.R%ׯq>|p;?\cM�! ĉb@�ĀX�2 �O e_+CAW6Λy Uϲ_,V}L1s�6ޟ}CkU�!68"NpQL^? TGҽ"{uJdpKuw;{8cjJH9?mZq�,a>ots)kۏ˜ @P '2p`Wo: %}10�[� $26 JJJJJJJJJJJJJJJJJJJJJJJJJJJJla(E �ȁ#\~F y-�bTVrc-�$7 H Wqk?!+wXCHkXUQ a,PI,M 4&КBhM 4&КBhM 4&КBhM 4&КB��B�*����!1AQa @q0P��?'vUy뮺뮺뮺뮺뮺뮺뮺뮺뮺뮺뮺뮺뮺뮺ɢ\[7 YK\J'NL49LdNՅ&9\ ]5RaXM}w1Z <6#pY&lɣ8Fpp5�!P�j#OG ޞ2sv|gIANgn& ~2L%=CH+x82&E;DzU�%E4J;k/^?՛$@Rg~?Y]Wg+ev~?Y]Wg+ev~?Y]Wg?g~?YG?g~?YG?aa4R̀3() I*\k(t@6f뛢2Ҥ&5k:-P jx{YfɆdS@,ViWcb0f8r3&(ެְ)=8 hp"E2Q䄂U@+ -Skq]PN 7jZ\$bqu[t({rL_/e}2_LW+e}2_LW+e}2_LW+e}2_LW+e}2_LujFRRmLE7rCc$NT)CAJ�yRVCC]n�4lٳf͛2bVs�͛6lٳf͚4hѣF4hѣF4hѣF4hѣF4hѣ(�l(;>j*a�!v5St�WSSHaÔEqX\ vFXdbm *sU7HSsv#PBT7 ȴ pBT3y cD %"xh-B*@Ic|2z�> K6c'cՙuji�z8JG3f$j|B //|p+Y?9?9?9?9?9?9?9?9?9?9?9?9?9?9?9?9?9?9?9?9?9)- CeMP e5v L Z@VTc6g ZRUAd�=ONMO؂-t 1&2lA"8d;Mzu&EC C NA *Vbb4I+/D2%DF?^QH {]U2dɓ&L2dɓ&L2d�Ky;UΥăl~ﰁU>- wH<ZM*% F`T@z喈蚗F4RPBcz(PI_iR+c5RCwI�.B!.Q^IrïPp&nDӱܷ� Hh8h SlxpDG QDMH d,մ ( l!o`>d#`A@H�8d(]Y$E1aB&8W*N"m(s!-(d5*l pERepF6F &x1+6�cn&5<PEjEGTq^4: i]XTPjG'%m L H ]曧C8$*Sj K\ICSc"" T.Ci��`"}4KrW< _AZ mP7p'i mGgQ8bM D!6N;ۑ:Dh1 d`!^=WV1D5!#*1U) u qaJ"@zrh)i#PA&o콘蕒T�vVTpKB`- ׌k P3`($P¥ d^YWwVT�j4OzE} }Ö}4'ևe 2$b_hoRoֶWjw�!79wS8Wl2i0�O,5NeSw8"# ;bC�o'SpC.xZ�iQDUlFE]qQ)r3>`Jw Rh)aM(FT+RUy\f3qi˿׮ËxAnmYkLU:1))�H )R/. sdJ=~jC &' D {: iUPO_ ᖠf[Q,2@ Jh7vcv X'r4!1ī¨:#bn$p)'cD1ݒ %Ov͗J S`m /^O`IbS �5{1E*[H1 3~s~s~s~s~s~s~s~s~s~s~s~s~qFdo tqX3333333333{3!�\vQlP)Tz@^v^vcE#%ƅ8S$&ʐXȆZ EF֣+Qv(!k1qJ[Z]br ` !yʈ GH Z@*j閁,JMEYw9P0ROh��' lՆ>^B r�aGϟ>|ϟ><1%96Y4/#̌G j!ˣ'<TIrwUH@a(b,&ʧr*K 10d]eYch !A7`l! e0aZ8W+:5J,OA-QBlI U~B riEQ% "Н[JͰլ8xV&\Hqn86TMٯϟ#�U:81 qOcNmnaM^Ӑp^=RN"{6Wсe,DK7LIeەX�pPlB 8Vn4:�P a=,XE]!T*)Wf9LBs3< R��j!}S2! @Ab6*Cxd�B@E *n[Jh&R ) [\9cP(K6BTf zmn}UT>]h P>)SfrOeh6Db+qt&Sw,J+buTPww7!/ zb2 QftUZd:T+΍)DD"As+@Tkjm^")\ a T~yy{1ُyy_5O/};1^<rKYUˊ4J#TSu@�2QAŇ1S ڱF 4AWJ$G6N �U}@b_8t QPOϠ &j$עN;G m'dq Zч= N\3Ɗ+v|@ Kz\۴nRfxO\t�滿f<>wo%y�O*paH�҆m8�U*)YUd=F$i/BKUP$q}q$QHT#?KHEGmVldkbj! rBYJFE*R 0ªK[9F4{9!8jxW I6T�`a:9xwA6gW滿f<>S?``U |=>"Bk+bG.n>kӖUtu|= C�XaK;TލlL�9W[2)F#={aj?2GV�^*z, <">l|e2%W#vre뿢<pgσ=iLz=2OU5(+3YK={g &g udw~yy{1ُܹr.\6r\r7._x]cғS/߿~߿~߿~X ߿~߿~߿~g 9sLA_cЃa7l#ok0٤0 tee E�[S8gIVkR"@ A޻ŅZK`,ʈUF!v RdX .U(Ԇ+ѹ>G Ђ6ז-yk^Zזab]uT213T] r\G )�Y�"<򂒀V_H$ocSpuSyAQp-k#CP MRMaT$Q.`@l"/Ʀ\b-҂HQCmWKIrQ]jKt ֖*lRZז-yk^ZזmѢ"?yx}9 7ZKFhl�TcSB��xҎ_T^N_| r!~֭;;:R0R:��@Zf7 m?pE(P@$`t 1Xa% mr˗.\r#i1ZxDհ &@ قZA2)+[WpmI9E0kUDԈM`HFHPe�A-Ww7�@?1F&6$:_4j, Y22D#dh(2Vs P68"^ykZr˗.\rs<LJy[s<LJכJ) WXW4v>r@a𺛔2 '+95Ť!_(BB7Jgt DA=YgL|v`5>! ~PTt޸rA븄&MU�<]9"%*B?-Ja/U�uPc 2:"^vc>;=10PV[MO4i lKYf cEP�4pEȏ|9k0yen QƄKr9I2Uhj9e IDqm �!?mF>1|c>1}C[@X4q覈CF>?-^ymFك<n ,X:�hk`ZQyT�  iܚW@L{DƂAp xGpQ(L%+ptZ(@Rv7tf46WtI[IJb{":)f�pTB쎻@%UBٕYh-!V6�>1|c} cs<LJSw�*ss<LJי�W+۟�Bx ]+DjVN D9\m�!WF$H$5 %I}�\<!Քe!VQIU#/s滸IZ5t*qpcLСEB{.fvl^!s.A2ys#4�^U}ǎRcK5pN*!a'k �uDS�<?3yx}yx}lD+è,A* AW�!\dEp.Q U맍D*hcaM5kGZ fmN >n@UƱhjW򜧀5:IF:I8x.Z(Ȃ ÔRAXZ\$L &{f+4RWOUhyD:fT)ٝ_ss<LJיISlQ9,b&{>l| J�+pA;%'{A]]`A8xk={>l%P�׫Í6p1={>lF.l٘ޝgEi 2zS滹xHA={g.|,4i6 R=�/σ={>l p:#dU*U!OPT3{ggކ@<K$5#9^vc;ιyk^:׆-x^:זx^:ז,T$PT@X,A^W&͛6mf͛6f͛~h 00;<?3yx}y'(ThjWoDDUirˆ~Z^�ꡈ&ү @_|\r˗.\rϣYc"T'Fࣃ�`A^ңh۩EQH{yi?/Td9B"ś��vGD )"2v< )*~G<?3yx}9.(Qt �B�:QP]3Ŏf)qHAaTb7IͧQRJhC cFÑ`_@"rbmLW)zdoje Bp?ɳf͛6lٳf͈ĦP])Օ ԞٻP)=R\4IZ9ZuDrMW^1P6p~AAyLl-,лkwk`8�VKI-s $�] NT4ݗ-ƐFm?(l鈤@UV&]CSU?( @bѢ˔3mRWh6`8J߿~Ԍ5 R/W˙f<>ϼ`t O#=~2H:R;D&@vHbw}3~2ġ^ub"/V<Y��LxCsV!vK?R`?*e◠6Vx�x�x�T[MzȜQCE�<<U{ Ջ,7y{1ُ3 Tit|X,G @�ɈL+ 8�ѡϴD6q^.V6[vwP*ou#dKH&ުt�aR9N[J]St)i]W 2r,LݾŘm^GyLcX}EtQӿOYR CzC`+aR ^vc`{V H@ ~{a PԣB[K.m2膋u-؊4HDѫi306q©,qs<,Bd�)pjŏ0`fq©Eo6ݾd pDoBI+%+4WIoE �J4%kgCT9`!O2S7y{1ُ3,-Gmzb@,޳A#`OXc U:ocq�;Ŋ�z �rNr60B�-_V,X ǠW$+Xc:iGՋ;փPH23rw,XA\/};1%bmN߿~߿~߿~-pQNK^ٳf͛6lٳf͛6lٳf͛6l}U!սq^vcj<�-^vcj<�-^vc:R}tp߿~߿~߿~I b_}߿~߿~߿~yJ ^v^vz& #u3q 8߻ AaO n�9zO#phs 1u bAYiHNt&6" DeԊ4Ct}:ju# H0b" ۥh0I`.=(,7'�qI~A9TCB^vcÒIR7gwծoQ6Ms1HD@rኌUj1Jzc@D]C(@DcW�Fk2g `@!t +,_Q;B7p;VR�Od͙PcG<<!$:DMp,لb 5А QfFS2TU0.G @ }>pϸg3 }>pϸg3 }>pϸg3 }>pϸg3 }>pϸc'�y{1ُ7y{1ُ2RV ǾRRHP�w`<COU$j|B 5%j:'DLȀڠ;qW aG׈| 8@Yn0-= ~EHGJ �[16's<LJיpc<(2t 3xQ>&V@I"Wt`pѭb|V&V{OIw=KGm1J"iƴ JnҺa3J8Oh _i% uK䙠$l',Pm'4dxwj˛` vFJ�x.g>K@ƈE"zjBzGs<LJט( #`,`)0 pݪ@U  裧#5\310(J!DDa 2:"e:$"AzG|PdDG'Cg {ջ{DX/H,dP�\kh:1N�x.gp邧&*s* 򸂲DNqVOESbI@G6�)LY01ꚆZa@D> kYXorC޻X9Ȇ^*AP d7EP?u2zRH 2s ul Jj&aX ڲ#ah}BW0XGWQ W[pElqY45!D=H. MX<$ A ()x\/};1_$X*XV|!&�y3T/!"^1C`bLCź?Xi~BD"HL f|5}qSs v�0\D0codv1 �)^vc�^vc�^vcÇ<PKD�9�9�9�9�9�9�9�9�9�9�9�9�9�9�9�9�9�9�9�9�9�9�9�9�9�9�9�9�9�9�9�9�9�9�9�9�9�9�9�9�9�9�9�9�9�9�9�9�9�9�9�9�9�8�c }>pϸg3 }>pϸg3 }>pϸg3 }>pϸg3 }>pϸg3 }>pϸg3 }>pϸg1_)W<MBYY_D$H"D$H"D$H"D$H"D$H"D$H"D$H"D( $ _N^= r81� J*TR?MS}j*:OxPB  9nZs0Du[DT (PA#cv>^+bͥMPB (M3xAnWK[JocƢ q) @`E1Fu`�'- uH~b9Uq1Ȃ D6iN J<wi.��bgJԽjJ;%"UZG_P ;%AF遢�;qg9?9?9?9~*?a-W#rudX �33󂰱rfx>s)x fmhC�t WM\.w@\RFI�;G?~;V.0Cvc G {8PmG.Sbߡsu;NIXGh]k�CC IJm7e;N/|"$C,eŋ,XbrPp ";lIij΢v(óf͛6l\`X-tlٳf͛6lh nqW̚_ٳf͛6;kEOOE]w{ jիVZjիVZjիVZjիVZjիVZjիVZjիVZjիVx%ijr�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������krb5-1.16/src/windows/leash/htmlhelp/Images/Bullet.gif����������������������������������������������0000644�0007046�0000145�00000001460�13211554426�022514� 0����������������������������������������������������������������������������������������������������ustar �ghudson�������������������������libuuid����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF87a�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������,���������A�",x0aC�;����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������krb5-1.16/src/windows/leash/htmlhelp/Images/Kerberos_auth_serv_fig_5.jpg����������������������������0000644�0007046�0000145�00000032006�13211554426�026205� 0����������������������������������������������������������������������������������������������������ustar �ghudson�������������������������libuuid�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������JFIF��x�x���C�     �C   ��"������������� �D� ���!"1#WAR23BQaq$45V&'6EctCr��������������,� �������!1AQaq"2B� ��?�S)@)@)@`rsw !cpu WihTR@Bpo=iV5s햢~ٙ5XkV544 B"@R>j=K~K~+x]M�gFo-^]Nۇ{?K*Jѫ}>ŤFoV̹e'z MDlUvB0M=K3{%{;߸}O=dm\E)ԭ,*Dzɡ1?ˆ=r%uN">xM9nn*.TҔRRRRRRRRRRRRRR9~{Qڱ:N*) !8HJK¿ʴ׫uxbxSbvQE?C̚E}xN! SS_%{<.�#7/.OmÏ=ˋ d�baANL}hؾVb#7uf\Evd"n*!&lX?уpo> {m."HV^caИȟS^P@|<7 7E]*iJP)JP)JP)JP)Jg9<6a41" NUNo:j-wPq0cR$r]Hm L B"$JD��fd�cj7psdyHmDݸmE00Cjbud?e/2}a<*Ū+ ]7lvlIqh ͐mN4.]-66Jɤs.rUEǔtS"! &""m\ҁJRJRb\"AڤAw! 4Q]DtTE+E]/_Oriسܖt(yiPة 7 �A)Ԡ1D-=1WIb`̶LEL�5p[NJ4Km{^K[r,U?i�Q& I lPp DT !BDTӴw_M+Er|L "(6 Z2u.FqTU7i8N+�m,7d<4cݹ&蛯znVzgK֙3a\EK. s1U9&oIV-p5cRd=WI 7t nMl*mZk K.+F1+$,{�F\qD:W{/_KdmUr;-vN}ˋĿO̯kOB&oQ|r7X̂SpP6։QQ]eD9;0FSmd(-Eòifݟ3|i! 2HOwfѷw^\9oi^GըN\-mn )Ǟڑ&QTQ 7DQEθ>3A(1d?y-v<@rY܎#*L"[tD%i]dV7nK8q_0#%Jr MQ\rm(Ƙ=VES^MjT)JP)JP)JP)Jnݷ%b'dnUvA"*`*lGuTNaa.NY3 +1ۻK{@*n#e(eô22DmYL0W;ߐ&$AB)T*MEtR3NJ3ljD.K I!QHYdUQH@� ̀�t�F_n#I țMmLTw\,[/"XEqޢA͉<B>9mi؆a5˥_iX~4eCjqD3TD�DQ7MP)JP)JPbLV˙YZ/7T=h7$!+nʈEh21EM;q;p7ne m"8v$;Qx!!%:&5%Gf8�<Lۉq i[yxњouqn_ej0"dف!n8 "BHvޮ+)}hP/iAqDEF^Nb*�ҔRRT[}M呾T#6$? =#NcRhUܿfND KئGOtG:O6Ӝ x%JӴQZc΋* LGZ%6HfؾiiWLLqkiu&b\n Q`uΘ=%Df*w싵`=Hk=p_/Iw+e *,lmP9 =ܛ/PmM.zwtŦrjk@qd6bN/roXLt5~[Qm XvI<~R �Gc0jވܩf}ֶW6]p|71[sWxsrfn #mSV;m '"^|r%ZM D2X[ 2`:J(@8((l*葨뤨�lsZzM�7ETi`%PATSNH.yk}xe۝c э #'"[#J.mϗS["yVu[lۆqdXe|-ݯKr-CQFUReWTx($*$oG�I7D$7M,4SԋZlXѲ8PN$Qւ D pS4퐗*h[w.sG{ev)T*;wyX΢et)QڝC9-mN wx9X]!7l@hH%m[R#2%DDEUU]zzb̃:Yl67bKiѼ.i6#(6h-l@q̧o'4dFԠ\~ �|~OkO|OjJ ̧o'4dFԠ\~ �|~OkO|OjJ ̧o'4dFԠ\~ �|~OkO|OjJ ̧o'4dFԠ\~ �|~OkO|OjJ ̧o'4dFԠ\~ �|~OkO|OjJ ̧o'4dFͲYۘbUY2ħwe& ȤJ|#G/= �ŖI1r]]">ãrCeB..b/}Be&a%ǑxS4t߮ [�`cř2 }!HΈJܒ^M.^Qod#k^F٣E(IYMdp)jcL-豑ZH`7AQ]iF`$oTkƕ/5 &-c>4NH : *Ұsg1E&Gjtܭě$3l_d^ +&&7rn$ˡAJ;&JxQN�4oVv趔]G�-ӬuV] [_bŵn6[o("q(n?J#{̵oca}JVN%cBj^T@qFHp/gxO|n { *ID S[>cw?o4w͸ϴoˆAB"q].mm^u֫tvۧ{tl~s-mҎ/Nu3#LJlvQN*8\yBA[֝!@b1_.lZ[IvlWb2)Ԑˮ�H^n4 wZ �-h%e6eȵ61SrhQٴ."ˎǒY>Z6rHܬz)\@6.HteF ~H'h=Eiurһi^rtefLWEmqQ/x$HK.b\7vNWA,�J$̋ -n*Eo^yd=[eOt,s:`DBBUkdiE͹x6:NIYͧT.&f-W[Mkێ$j̺)8rU{Ҭ# Yvo8Gb6۝grmvo9mˎf kpeT]v+̃ːKAq!bL9=yaFԶ o n<y.ʋ_M%k [gS7ۡLu6Dwe!KFf㯑[WvE&ÒuTNtC%n2؁oȑ*KL(FdJ""%N,Eu QmHnĖ=yR]ilFPlT[٢>cN)@)@)@)AfWݎo6MmV밵r͗Cqs#)&@p5 uawvA96DH ]nDBDN7cYM3G.o3BC%`+ ʊEe+DtC /2//پM/v)OZ2�EvTSmCݑvlgLc95o˭"ЂMvyF"=!T BJ�K#5�ݛouo�zL#Ҩ)ԩ/zZ4~C3mꆪ�\F9iztܕ.K#"d$N$BTWd<4)V|m_2(y|_)خItXI͒C)f!Ӎ|]WOg9eeKs| mw75ڭPvضl6-"4 Gm[A�DDDDDDJ ׇu%>vHnXŜz32QA\@Yd (ih2EmBJP)JP)JP)JP)JP)JP)JP)JP)JP)JP)JP)JP)JPk7c[|[y-u:\ezJI! q a5FEA]NM;ezp!d-SM1Sf G.tüID*BB/rYJ2]²̋oox݊SֻAFݕudj>�]5ǼXƦqM[s7H3 ]Q;HuU9sC2CR?zxfn[�k'e/ u*cƲKz.of߻ na$z?=Fbpmޝ7%K=I*5U7U?O.UW̊+Ev+]#"qsdJjوr4_*z>cUeo#{~R+ah5hvT+- |h[i@�EQ;F6]ssϝ*1g'̀TPzDY8tZQteТR R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R RRATOA+X̵G Ӯ^Yc{g>Ř~yrw˒o敭|t{'PS)SgV^Q-K'O1,kWyT�5R%UDDNU 8$!"Zԥ(((((((((((((((p樟ރVj]ּnj}{1z8$ǐ﷗$+Zl+ O̠RH*\[N-b<Xخ:"�(jJTpIvBE_JP)JP)JP)JP)JP)JWdh y鬰ܥps3@ۍTe/v6\:RH#K{qO^ujAL d"p"O w^R m mnb#@x[FeD�DADDDNDoA`b1d<(%6kdۭnj) EQ5@%st &;;pn[pz_7Yqw-@C!U҃Xt Ӯ'c{gE~srȶ˒浲t]A/Vv(KhؑKBO6H@bBܨ>_F},e9pK.;5?wr"s?ϧ*7MMxr!]ĕJ |bZ|?9m`�7g;DN$ �ql˸jp=|7>f"BRe6l`AZdrηH 9ĔK$+**}%ӮyafqYdcb؊ 14TaF؍6]ixƠ_69%uIplf)BT6lTMg+}TҔRRRRRRRRRR®ɺvYa˹KvgN4  ˚^luBF +nП鸼hԂ,@ED'" '$74]m |Fbb"�"(ȉA;gS.F/bMxPJlɷ[$RD(jJ)Mvv )o7Ib[+-6B 5Mv]LNnjs1z9pǑm%kd҃^Q@ѱ",ƞlDQPQUQj|Xs\vj~EKTNTn4$B*-6d=ĵ" Zr6ۼ�on w̉7IE݊7Oh9�Z=>pzzM$5%-n|D:N/lٝ=v|ѝns(Q]HWeTT+)Z&K]#,كjǤbi�.( (mA0msKz EӤ<mhS(: m٢-JRJRJRS}Uvl,|K678\=$Rim  CƝSrLsڢ?2Xf#jZmT&2H<7%ؒmTPTC "y%s_-lqKb}[!"<#<  쨵Pc2\ׇc s6LJDr 4ئJ6g*+q \nxF]d\NjoL5$t[iU7慻l ޗxe:Ыվˌ$DV4ĖqER!DOvOOHm7aDeBnoñ¡&xĨlt<J zbqMy- 8Zmxᔾ>KN?,[Ñ&J,GG/&W* nR+w [(V]_Il۲R9ފ*+) *xQ7%\MItu( ,> PQǦʖL6DEUT8'J'lGʣFj3~~vl82cS8肼⢪�n"UvN}uXR3넼cVa;@)xUL) â qN%˖.�MZgJ/2V9*Gu3)hc9QƮS'H[-#⠶�qTR9M""bH=HLC#1axq$"(z<Ud*Bb:(moS)fc�ȯT!tƜYm j,=i~=\Z>ҳ'"gF8]2<;("J cZsi�ٯvHm]#oK ( ܤC357f"wV{}�nNKqFLJvō=A7ogYC.q$T j T>6-S~thœ+OˠCN}qjmb8W蟗O|)¿D OT>6-S~thœ+OˠCN}qjmb8W蟗O|)¿D OT>6-S~thœ+OˠCN}qjmb8W蟗O|)¿D OT>6-S~thœ+OˠCN}qjmb8W蟗O|)¿D OT>6-S~thœ+OˠCN}qjmb8W蟗O|)¿D OT>3׷ٰ$U.B]8\=$Rim  Cǿ͋G_~]j~e`:de8̶n̹Ynk񀶛l K@w+6+^3LeҺ`By+�bDu|Dۥ>-TgƞlLUPQQQQvTZf׫~;.WYѭ\'xZimQ7TZM4UTjnQ aK^\njimƐ9E '**蛢+"+.3"e6SWn]ʩk>@p 35p2m?ȣEʹ̔f`ET F]ԔQ9*rJ:ۜj#1k-$ZvAǸJG\ 06tGEywV1m1:q'S;Q-OrmQC[cSUTNTDULȘ)|HP}8=}$ uxu}"9nsx,M`^srՔ^b)z7s[;w%-${]UWõTECwƖ|"}bFcGw_yfU&oI3efS9#G_*YJt&fUT8#cƵc.ͯs1{ϬI B{Gvpx<Ό^v/SW]kَ•Ĺr hٮrSp$nz9|k)Zf=^ۢ}\&�u7ዕ ," mDUER("t�5&#e PtB4j>1.BAN)@)@)@)A1<i:ǝrK~}a fD@$(rw ?:'X.\YeՏ Ubl>ll(CɧLUv!Eiنs wm>LH|ƞ j:s#")[Pn5�QwAM�LH\GlXxc#NMJ".l6𐪚*rxr<l+(ޢy#BM9fB Θ7?U>ʚF�Y\aH˧ˏ !ߟ|V¿ WWj֒.b)%+eՙr,4D * *%uj,o{:ۼ؎ySTWdw[1k �:tm"2|!5"D2U7ڀ[=6kbBAPe VD2JW yv:c5佉f\^@ƙ 5{ra myc6~Fҥ)uMLx"q%R%]k:"l"l�*XsN d$?)yn B$fLc)^E7jHG|e\FT �7zCk7 UQPU vH>0EbL%mWQU|O.mb}Ċ^g̯;61'ܭ˄VG0>d` h*/MePd+ZcY-eWbRmWMW)l2UUwU^.*USNɷSoyU_wqxOJI QwEEJR6\_wiN$%NFw nA8Ֆ} b[rd= jUzI%e rZ%c 8qW.܅mH+Vɯ tk0q,mdOF]%B@"H&h*t qح^],8F]sFٖ|N.;nsf"[[uuߤfzwgݴ$b׬VD`ebTi%�xIQQSʷ:״�Xn05*#N'MąUV]U0:Tβajԫ}P.xk/q#B`NlUT}$QC^*%{vQUX[̼vY7&\tŶ#5Fb>u;[G})l%1+2!v@iQuܕ["*"B> ϢEXz$wnx&fm( )計mb�Emhu51jokV_G²HIpm*OiMQlOSt]^X nh1,۲+Ň1)m6+|*v|HHފb|&?c<sJRmZo ~e$tL�͊`D(kD/z*c4ky/ޖ2K:ˎ$}滈Gþ'}kwH5ĺ2er~WfD.҈ 4.dEDPqHUgӣ!QkoVĎmLʹsq%E5uM_vͿ-nf-UQ�mwR"sVB3�p-]ETi<-*nP+AM5:v[%x%-ؿtz%UWuUۂzI QwEEJ}>p1yG?]Xoϼ؀ݔwtzl!U"]ȜĞ6EBnNg6 ͋,*_DE6h6^!ӈ&*VzJl9ɻ6&af>EhucOhTp{e wH-mNS쩟mBOld`Vɿ\rdVe͗qF#^SRWnV/[MEpEWO4da؈\v;I'4lABQ?LON ׮0X{GqǐrېwG+a_b~e+T+_4E�5ዩIw5 uf\6 8넻 DJ]}Z&+e>ηv/9#úG}D*"ɿڊ)S/W(b<.� ty EDd**' BkEjdPoӵ� ƶ{m1fl׼!6(/62A6dԕ%/Nu`k{*̹ 8+2@jۆ4fcemKvSΛΙDJJu6D+)J)J)J)J)J)JDu҃6?ev((( n*-sJ gvjvIZEz,9&~K*EAAo]Bqow+35q,dmqQ=M[5u&ϬP7p^n-j#Jec"8\Xqd1ʹDDWlt%Es}{DkT ]T%mŎ*E^U5jq`VM#̵+brmQC"m&?ʱit[~9L_mO,Ek kXa:EnW r,$^a7$TB#ɵ.C^,-JNr;&ce;]xnG$lwCҮʈ_v"3xdY "u�7i[l%UUU޶*NsϯYzBȬmW(25";ي �EETñFLGE.#t|F„"EܟSq4U$I̫2/-)�ED{(܉QQfFp4Yi";MUmX6KM-MuDvM7E*oX^bm—i|}1Cےݷ%NHΪtJkѪLO[,7uXpMX 2û :@n9`@!)sU 5FϤdZlblo'AR*8N͎L'1~;ߐ`ȩ^_Cu [{!$GmH}ql!01Ehe�AO숉]T;gkc#F"o}4;e̝rO`btUqy# 䪼SrTDڔP4Fhk9^izFertr mpJ>*5p[ۄ.Lj+3O?"#r&DG:o7 wEETT+5D1bctFy'ko 5(j[ 7^}m: j h+jmtw~t뛮S.Qptr"#vhH"t񋓷+Kwˮje帀l2Ma؈EUTT)߲m[""lWM�~e8VѧP-y/vd{cÌ+dET%Ud&Ԣ房޹f0B7jڟycZwݬp~PB##Jꛂ y֯#=OkT!spԛNLltR⢆HQP|U&I攥"^hҺ]A^R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������krb5-1.16/src/windows/leash/htmlhelp/Images/Leash_properties_afs.jpg��������������������������������0000644�0007046�0000145�00000024411�13211554426�025442� 0����������������������������������������������������������������������������������������������������ustar �ghudson�������������������������libuuid�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������JFIF��x�x���C�     �C   ��"�������������� �Z��  ���!1RT"QUW256AVbq#su$&34art7Bv%DEFS�������������.�������Q1!"A2aq� ��?�en]ؗp<M2HQVKm 4Jԣ3>ȏG"(Fy9zNi*gs#R4KNɆ-PIOKm<tTQ/cɽj0;vQ^Niޓ*j؝JRr浤:r G5JI(әO3o쾜Ħ LST'!L4H"u1s$4钻ԯ36љHŦXZ:sNaדwmLjrT^H!h$KQƛbE?+dĪթU '8KQ՛mi%FySUh�=?0;vQ^Niޓ +M舩ֹ+8ΔwAfTY愨Ymbvʀ>|:VŅI̢Ifi[J2,$DgF!WCѽƆѨï'4I Fy9zNb8)^n 6 * R /?Ij/ ~{n2:b5Rj-tDRzG\GPˏdj0;vQ^Niޓ48K*U H#1v&6\ K"^I lFyfD3L'Xr*lh]^CeeKޓ6Fy9zNj0;vE.+lYIJ%ѸқQEf)'2@YDnӽ'l5u;bKht /rdaדw톣ӽ'lIm.?]4$aדw톣ӽ'lIm.3@M9{#uu;aï'4I[F| >Itӗ7Q^Niޓ:sN%g.3@M9{#uu;aï'4I[F| >Itӗ7Q^Niޓ:sN%g.3@M9{#uu;aï'4I[F| >Itӗ7Q^Niޓ:sN%g.3@M9{#uu;aï'4I[F| >Itӗ7Q^Niޓ:sN%g.?]4$aדw톣ӽ'lIm.?]4$aדw톣ӽ'lIm.?]4$aדw톣ӽ'lIm.?]4$aדw톣ӽ'lIm.?]4$aדw톣ӽ'lIm.?]4$aדw톣ӽ'lIm.?]4$aדw톣ӽ'lIm.?]4$aדwAF}=4i5k7,џ$ Q^w+UT[﹭U˔ZGLfѬE)0iXWZ0џW%*/ȌGDȌ�D�V4@̫jJΟ^L,KK:Im֔DD_ 3J3#c߲iRԔI2[zM)I)FڔQT=4)U(׷cp8ʖq˯zcyJnvce2EuBCKr$JTim␴(dJ#&jEll\y�fc o eqSlC,�|u_\qvisS/6 oEtIsܑ+_QsRZ$gfDgb>"FJ*tJ#8YR8*I8.,Zm|]Ө1)*MS[kR Ȓڸ?J\9_\nZ|N_n^_~ס>U )Va'RnFQ┓%Hメ#|&cA[3@rhUz-SMIOLEYۯĮgn}ny"_3>vtWrrꭇhTxU][Ķi%-<hllqf6v(ȌzN!,F$dEDCr~$;wCu޶JOU3hBf򦮟BwkWhQ.8V,潤n- 8ɠ:KQyixn3a&ǙJ*vZgŚfI^&ٶhY32IYk]<nsb$T,ӭJ5%Ggb\5gT]O]ڛFLjYE]U[qO6mg*ttIHB\4I$J/XkOD\v<U&Z(ә+D2/~$;wCu޶Ϫ6ݲI "7j-PiR+-Rea*fq J%wY+"2}$%ZS]NqL-K5M) !nkP#Ah#Ȕw'۽mbĞgn}#w�۷rj? atJXjT3ud\f>33^Ğgn}ny":m3TA|&'۽mbĞgn},a{>O7|0~$;wCu޶,A|&'۽mbĮgn}yeDϓ ß'!7_\n~%s;wC(B&|0n>a Jv[w؆+۽mbYB7spMW3z۾7_\nß'>OBn!Jv[w؇PM>`9|u޶ W3z۾<"opϓĮgn}n!!{>O7|0~%s;wCu޶,9|Ýß' _\n~%s;wC(B'7|0n>aJv[w؆+۽mbYB9sp=W3z۾7_\nß'>OA!Jv[w؇PNn>`9|u޶ W3z۾<"spϓ{Įgn}n!!>O7|0~%s;wCu޶,9|s+۽mbĮgn}yeDϓ-Y L_C+1!Jv[w؏U͈c;}kI2Qd*MDڭZMqOcez[ڴP۔8k$4I3,)dJ\ &[X*6K1ҨUFȉ!gp"Te>Ih[S{k-X)j5"=),Iȋ |ohH�P.+Tާ7?~zv9*4|ݗ0> }d,8d¾16-:؃OhT,hyfdfWgt9_xvm71�OO8ۜM Q%;?6U3Db~m;g"\b��̐�������������������������������������������������������������������� gWs^'?mR>_xp3:`ͧULXNG]h�|<q[-D.33i(=wk[,7yn&$УJҢ<21"ōUN19탮>MMҳ˽Q$@iTV%nJSu{6k5f]b[֬4FI2l;omZmgig\9�ZXj+s7-"ؚ#j5'SG=e��ƍR5ǔCtNÆHYVЬ%QXƟK3`i/1&;n#JТRL ʔF \Q9Q6A-iO&df\kN|d2@�_5s*$EDE0 f~ĪUXȦ賤+j{$RzEh?e)D�Y[RݷWj5DjR4ii5VIVHYDf\V]f.ٮ:)N&ɦ{Y60z_Q,&I̋Pkj{s:6IIKn3jp̐JYˏ"?�ȏqeťIb \J36j'3m Yhޤψ 5J$צ3S/ fKm8JS!d_Z B>2�dƧTbV)2KI8ۭҴ(###.#*Q3rD[FSN8 <fp9$��������������������������������������@^'?mR>_xb>jKљw~m;g"wTE<7>bCZĚd͉[LqMNv2BFIhyEǘaV%{5}; AD4L8MIJ3hW]5$F|7s=#ψbԖ1/lSk5ڃMR Km I*>3?cwDËخ~@~*驹SDwI!0J ޓG ,D2#b P:yiUjE_f@)L)q^cF[jhy%LCW]` 0kuӧ7-[5}䜶B{O鹞C"22 ,�QRP9.xgܷ"+x{>݈#EfThtդ=N ̳4:C^1B٬.]MJ*+WentSO4P!><νK[ha,mz˒\DEÓI:y>U]ji^ccjS2% N>).$Q%/"QR)H) 2jp܃Ona&䄓is7˦h'<K?sYf�NݫqΟPqhT[QKsҗ"nEմ]kEzhѐ9.8$dDF9�V*udJLEi \"W mI&ג3̲-5dG>�ˎQT\BxUFD_Iyf_Ә:삥ё1~St]K2ԕ)QZDVږx*_s;Ŧ<㐪PK:ܺW> Mwѡ\qi)556KDYނ]nk 6SiHZ{f.TjSjR4 JbbK^K!IN%<Y:<ڛi'y>2# Z+*0.g5'YoJQJt",dE}#M+o]Fޗ-5@\dD*-cBGu&*|օ)/sI+ȼ�ԱޑZ"DiK)A*9T6kuKhڎѩ\JɷckYY֮ƙn %>63*I)RPʐZ-4J>j%\LȲ =�t"QR)H) 2jp܃Ona&䄓is7˦8gO^\ݴ*OV-(KL7"m.4hRZf},ȳIDD`@�������������������������������������}3+9F/O韶_`yοtMg|Gӿ~,Q]`ͧULXs.��3$��������������������������������������������������������������������>jǣTϰ<_W:\&γX#iS?tA(Gӿ~,QZ�4ojqi[dZK>1>0@g]d_}C^nZMNص)oii5V⌒$3̸̈^& m]f.{]lS.9{Y60z_Q,&I̋čӉt+CAqaj38dfH%,ȍFIQǑ%`>-vRX%kS`jeUGdy$v|/' noD 3>()BmFjZ| I>uxPK0@gm_Oh XnpSC} Sd\fEYfye柠6�@������du!gf\9uxP 3|/'no xS6tdk.-=wxܳ5=>LO+Jy2CmHKZ)"#33" ~ 3/>uxPK0@gm_OG\ VRC Emk(= 2ˏVJzS-QN(ЃQό31T[n%.IQf}A >p_TNV.G1?V-(%",Ԣ"LȾ}mIbDISM}4TiVәJI|F_@uxPK0@gm_OctGj=ioMq kJx)7#2#Zs ~ 3|/'W^G/' vզW,VgN}Re&a�DH"!P. k5ilRާϗ$ZzםVeK5("""π\ 4ⶇ�<V�Շq[Cv+K7`IൠEx�w4 E: ֺ|XUyuId䅞jȲJ |دTܻsi݌n6d;32J Ьd<7g% '?`x-h x� x'&iXԹ3z<D'1QؑVM%ֵ蒖"5E,Az|LJuu}ыgWs.FgY,꩟ WX#iS?tA( $M_�C`W FpuH]W|(d2,3,CTbcЯPj[Srѓ1~St]K2ԕ)QZDV֤x*_*g.\4+3s-2E&h Kaum0x NbcЯPwp3tQsA]I6*Apԭ!N*drSœCͩFz>h-nӍVd:}MW3?𚎖IqVi̋%Fd|9dsg!Q6/8 VW+wܳնR׮t}0>,ztHl7J &hCKs32Ak^JEzȑSԋN[C=yGإU-¬A^T4ͤ˙ZTLNeMY+o:22#$R5gU?ODKKg\LDm)3ɡ}Stb#aJلh<gV&˹f>LщSh Y7 o8Mi�v,OQ: @(~ĺwͱ&|qX',b"d'OW'%K6IS% ʮnMqq.ht$03)zz.y'EtOv<E?!q\qK @ƈr�==l_qz xc;hڞTZϽVh<�6 L������3('ء\M=RKj -N>RdE /BB /BA^iD~76揹&K7f_vN￑| 17j? !ʛqD~لڏ)1DC'Xq׮~JZ_RF)OcXX+LL�PJc؟S_|P~*Pմ&$h2_o鼵$FYi-]؄Jmn$hJ1hf-UϾqū."""""]l_qz @ބER kl_qz3Sf.y讶Ś&DYxBP7 e`�?'˿?ƵsXo7+Ȏ$!H5)F|DDffb%s+)̏%~EI(U7TO.'Pn<FLV(IMȍN!<j"9>6/8 ,C,e+/(,YUqӨMU'8ŧR8-6mlעImT6I$ #$R\rmWj*kPcAm1ԚZQqZNP-JiVzju&aeWs/^ i]j٪nR#g$dXCL1/>ҹ +w>)[+UuMQĪ3("4vR\SeBI$3q{؜?(?e^,p _ܯPJ8>#7w^z6.GcЯPJ H&iѓ ?*O$^+Bh[$##FBφ^[xK`QlmM%m.#QiQO,˄WAo/mo/mش )!P`FzlVA#GlqJR̈LSxP1sεktێ; v&ɤJnSq\t(uMeI+#Q4<MxEÇKdo?eZ7dsTW�D*rЦ�hU[(w6ls6a(P{0_o8? @~&�~F]~huwj-L"um>ʉHYl|FCB>O~ڥ~}::}3+9 3wTE:dㅻi#2jO71Sq[:J="W|\nw}<ڭHj ȏ 7|cn|6[Ss.h)nw}1zGѹ(KA^/m޷QxouwF/xR1zGnw}D%!Jouw/m޷Qxtn`J.h)nw}1zGѹ(K@DEB7E> t_۽n])=t_۽n7E> E7E> t_۽n])=t_۽n7E> Eזa^/m޷QxouwF/xR1zGnw}D%!Jouw/m޷Qxtn`J.h)nw}1zGѹ(KA^/m޷QxouwF4KB7E> t_۽n]z% / S|6[7|cnãsQu藀D)Mt_۽n7E> Eע^ 7|cn|6[:70%^x4KB7E> t_۽n]y5h@w|cn|6[:70%V W|6[7|cnãsQujO@jO@w|cn|6[:70%V W|6[7|cnãsQujO@jO@w|cn|6[:70%Y$D_pR{1zGnw}6>jq%| [z;"e(8H#3>;Q?MTr�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������krb5-1.16/src/windows/leash/htmlhelp/Images/Renew_Ticket.PNG����������������������������������������0000644�0007046�0000145�00000004610�13211554426�023527� 0����������������������������������������������������������������������������������������������������ustar �ghudson�������������������������libuuid����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������PNG  ��� IHDR���/���M���6=���sRGB����gAMA�� a��� pHYs����+�� IDAThCZklfzkIPGMlLڦIT*>"!R*!)N"թbKڀeQ7u`vlgw>~+1ʞ|3c8W7e~ړ ~ʝ̫4HIW@<>EeC 9Ф!xy`܆ܩqlACnHpfލ><*ť!Wu[GVtrz ha嵸JCր+hܚ^ D.7\?7/_EGpT^|b�ǁjNBP3W7Gώ<7',) Gk>AeF> O2ar-VCwBb;M[clP{γO(v3\/:a.?DX@{Bp84&xGG�Jx2bM"Z+.>hZB @uQ 0y{.}G=~r}R@dbI(`g<v1p0`8r�r,lXw|d$O6hI<i^m]M|J.qB5_ S~ǧgp?07Ȗ6T:=X"o핧yeMC\3$s=csvGa簤,`id%cN[ {m#xj b2\8]׈?b^rMKN <7ORҼnb1 ˜Wx(נipjһU7z X4_(0F Odk~Kj)H5]eUCTE( 䢧CLRCQӼ,qRHļ'=w]0] LKzưhc}:llRƜ, <^N[{fb7.B 5_BHqN:B�m-F RCƔ6ʩDܼ1ܭIl3vfGl:@oeg hX '4#LF]5ܟU=ԪNpC gzo\|O2b�q bDVQ|TKGA*fg"?3Y)i54F59auMG*O,O傏2_""<"QA^gUeK7m:9E%:FMLPIIw0Eߴ|~z9k5H/.&gaO?қQ 26)p$.7݈&<R\"à ~\CCk;cp t] ۿ=#wc\�#wŔ,nE44xK<PhWb2vps9QᦦҘ[}Z%Jn.�DIjPQ6Cs$2rl7ehqKh^5ЗR" %?e8Dg2?x*>ڦQJ=I:ׇzس8{`9ppMh`hH#{Lo9sK7|xJ+wh=o5cZ_kU  Rd(k@[=J&˙1{Lc{Z|~E_?؇2ze' W]+۹I~'^',2vν{tEԁî^d%"~J+\&5- evL1ItU>4wye; Hk5Y6ߕ(/c$`1śB{8ov}9>3i_FcQEyƘ$Ҙx~mb++�;8 }ۧ?`o; UFixrU!\&gvkOY~81@p ~ވ&ul[~fXkg*CG…Zxl*rBϷe{>qF/XZ_>B!gNQmWQL;*!-[Q*Iyqֳ<nydxKIR w]xd2BC5h,JpZ3rBBcL[7_azD_LZ3.|Ӎ8SXr+&uQ 6P&yT+vRlO ` x|ww2#Ҽ2`r\ƔǼRLʝrS>ٙgdOΖ+~W]N@Or {����IENDB`������������������������������������������������������������������������������������������������������������������������krb5-1.16/src/windows/leash/htmlhelp/Images/Change_Password.PNG�������������������������������������0000644�0007046�0000145�00000010147�13211554426�024215� 0����������������������������������������������������������������������������������������������������ustar �ghudson�������������������������libuuid����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������PNG  ��� IHDR���/���M���6=���sRGB����gAMA�� a��� pHYs����+��IDAThCZ p~/rBB (amE[LkVǪTD^:uEAK LVjb Xk((B$!$$!{Ⱦsr'TwHr;1~\H7M̼7t2뉎% @/�,e)EQTROL#aNx^ FcPp!gR!F,c+d& 7\AY%tw#~DǦ#5%�1&mPER{諨T tw9Pr� OV@0[@(`X{|D!ՃΒz=#ãNDވœv(8=(8 Z )C*NJHD`pp@uu4]P hkjD8@XBJZ*&deb6 gL˜@B +\b0SޒAkS p=2e%Pz u`4WO;Zz 5$ʥiq7)x, GˢA5΂y 4ded@Q R'8fCqEL{C rEn  ,N8ύ9_I 0PA<.~(ׇ+Wꡖ(*.=.&C*iRRGJ@K,45PJ g5jw7Qv1ed'c>,~^$/BDӅ ad&23T$x=~\o*%GBd~7<A ra2Zv04}JI$zU=],qÇAy=zk` j^5s)#G"!9gݽttuQZZIidNIxt&PO!} ф \(*F{{zzQ\RJ=l5hLK#;!wwpCaFjNȆ�I+xZ2R>n$ح(Y1)P"fk,L0e0sQ]B/$'w_>as5ڧoXV40L"wwvaEP1iIx�>ݛN=e>E %o5 #- ̺:ڱb8Me'R=H ÅZZ!/vn{+v<@?{J.BKo=0YmhmicGmu%d yØqdDGRU5hØ2e*ʪj}tY Ttg{ +.C!ibHAٮ?gl˴B 7AdDa!knq3U!]| ҙ&cTTctz"BmaNϰ q>1nwp!񯒥+qzy:F tdCyaޅKJ.E |mDaLK#"C_oJCg^ŀ|ၚ0l !/!ն !X5m7171ljn^WԒolj*f! EЙ9=,E\ seMeV-[K|) Y;_\+.U>ǼBo~a+K ݸeX뤻1 K},tz�zpy F 2twpצ6V"3~ j9{=<d>?5Ub&Κ*?;&}jV˦%ˉ0�-̜Y@)w~iZiX_ǧ%3<< Ϲo\�L vo\ lϲV㍊ Z-<Β�O6K+rE\HGqe3| 5|N7<7|іQC"?>Uxv=ʴFd.ou{DS }~tj jJ?O'=Ѽyեã3cl|W|Jcrۑ|8/CCxׁOa1EF(0(%:xyrX20;+0,*g4x|ZCs`=SVގ ¹:&O l}h"swmߒ0e`*�Wydo~:d#YA(T@/u"O,WIܦ7Gx<17@/U##"TPT!@2L#fuZ6j!o o^40׎w,='P|,ʚ,uJ^(b`*} bo;~|K>*oLcL ~?!hAL B8I+i6 ^{(N*&8UO*~0m7 a\p-5 Ӳq(-^wlƊًcWfcFVz.}hY`xZ HD } {qwKͯZ~~Sd#J}-o?1Ӿipv6c`N2 _]?ǥԎkf&W`SW^Ko/ǹh="Ikk0 5 cC{Cl~$NyJKؾ% |p9xiNro8CRj?w.SiXa=rԋ-U6}T, bX h I᭩"<l@$GaÍ@tYPAocXKT*I<;cp:P/8]{?vObuBH7mx`N܆ɭxrAt0"!ш$#fL, cYQV*IE[oK(h]?<d҉3F=>'߭#l&A;0IZ0(GcWAoFm?!fqUM$L}/B?Gn@Ǐg 8< '_O'_~}uc x*ֶ=#%ud,F5 H |Oa&߅]v8̼| <TSqx>.eOQI"%XoqOb|@k98qtyX'r;eafl\,#E FGwj>'OB'oY?7yn®ZAD5bWEg+ܨA7E"7,0$?gsXrvJs!o^\(놛1:Vm/^u,._"!}0ToB`Yqd;8T` 1r t5 OS2!I4Wm"LjD.v;[bnai:t iPE:xTiݹ|};s?T~Obu,70EUhbT0Z Pׂt#04hgA(Vn 6WE|$Hgbh�~( *0xbȪ{C<,5 alYQX|W*وu0oiexkg!͂iӡ==/ ~EDz*|FO@,&f"Fwonކl<Ԧ`g#^^h[jEOP ⶄn)5?=a±w9{-@Z9߹c-~mAňSy`=#](=wqxtd 3l叉E<1H4JX=9f nbUbˍBĄ#b( A?!ZH>?lGI᳀hX$} F:n/;?Z8wm4!dwK>xE)#AWUlMn1mz$6-G[7-ߨMwKі荮wK7*hݒ|%zݒJ*t$mzgO Ϙ����IENDB`�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������krb5-1.16/src/windows/leash/htmlhelp/Images/renewable_until.png�������������������������������������0000644�0007046�0000145�00000002143�13211554426�024462� 0����������������������������������������������������������������������������������������������������ustar �ghudson�������������������������libuuid����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������PNG  ��� IHDR���r������/DL���sRGB����gAMA�� a��� pHYs����od��IDAThCOAo4?@w&D<Q/5bK<(h(.Q(} ҇y7Nq3ffA2;u) ͝׺�kMqdkMqdXr~xX@XLصjZ2<Ks N>^XsI,Q*(V HPe`hB C<oņSl,a4J߂vMk)SWI:_%`]\^I3O_D{mm}K@bCuEjlbI\j3QiYĪ}ZO7?KGNzne-V8IisM٨j< עl1;'OAVK@|C<C;AR /<ËB8:;g V h_!@EQg:Q!jC=bgF#4l\nb(46YOS |f~[gBR /O. D篎?s nz\jbX)؀nMƗ)0&5Mf �`rlcБ6+ԼY xG"[O.Fӷ;�:�M-bVX?<c5*F3@#�SXvłvk2Wᅧv~'p屮'Kk&A{,Z8Ft2&m(gϙ.f&is+ }�V5H3a7,:WMpa[8.a-f&IܮBs ktCwB.fuV/= +=>E;,q.Y%9Nt8+Dxxd=-$jnm7PXY$ؿ(X˪ ̋'t_^ZP @e^C�l/ \?!lYq끜*Zr�)I9N@b=S%֭R\iD2=?ɇ0D����IENDB`�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������krb5-1.16/src/windows/leash/htmlhelp/Images/View_Menu.GIF�������������������������������������������0000644�0007046�0000145�00000022622�13211554426�023026� 0����������������������������������������������������������������������������������������������������ustar �ghudson�������������������������libuuid����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF89a�h��������3��f�������+��+3�+f�+�+�+�U��U3�Uf�U�U�U���3�f������3�f������3�f�ՙ�����3�f���3��3�33�f3�3�3�3+�3+33+f3+3+3+3U�3U33Uf3U3U3U3�333f3333�333f3333�333f3ՙ333�333f333f��f�3f�ff�f�f�f+�f+3f+ff+f+f+fU�fU3fUffUfUfUf�f3ffffff�f3ffffff�f3fffՙfff�f3fffff���3�f��̙�+�+3+f++̙+U�U3UfUU̙U�3f̙�3f̙�3fՙ̙�3f̙���3�f���+�+3+f+++U�U3UfUUÙ�̀3̀f̪̀̀̀�̪3̪f̪̪̪�3fՙ�3f���3�f���+�+3+f+++U�U3UfUUU�3f�3f�3fՙ�3f������������!���,�����h���Em2 ",xp Å FLؐ"Ċ%bѢƋ ?HI(7 Y2%˓+G\,2Ж-VoN>w)4(PGUjtiQN>e ժXjUר`n*kجS ֻY>U8Wnokoݼ~0}Nx㿐G6xb˕% PМEg3yMz?d]ulճG>,5ܭMZkā.tp۽>_sҍ g]V}ӻ |I?o??դ_|�'X|.X{7z2`G]k\ %PzH h(Fڵ(\1C0h4H"+Ƶ9 Ax#mdF> qqZדguͦ@m21Ei=yژ$Zj]}&rT$)e`rɗo,f[9e^e`hgZy9Y7[ Z ܩyj瓩ƚ}Zjr>G骵qy2 1X;&T nB2ZKL(v;n1ׂm[Rbނ[L_o p2knk>|>0,4l8<@-97#m53M3C-1S ['_tAF]uh#Mlm6Yvmrw7t݁>څ#~xxmS-Wn嘋Ao\!Ē#N>4~Ӿ^_yvCa?|G^SMG6U{NvBys^>篯{ ~?~3C蓟 P_>/"̸}݃ІAip6hJd FBϩ|,L`vn$\!L6 4LF|$$14Lbj h8 NiEm}2K$D%.ihE1%bB5dfSZ44>1!O4bIG>(2#cA %rm_ 3N䐕l%kIK:)I>x`75ICȄ&tKbD#5 ;8IanŤ0>nѰ&vI^싡29-s Kf-~ ߴb4fB'=A}a/P� R%v>Q; $߄P)xSOyӞt�8<䟢Ë9>nbϰB(CKD@� 4.%B‚<[X2rMdq#bhdTaT8NbTO3ԛ lf5mXCgM1B�sDa-x6g]0�Bqԁ>u0}K7ꀸF e%EY>Jn|q<$O^Tkk@QIp{F0 @ G:Z(�@P4�A6Bt*0dA DI4dk< + sޕ*"؂}v lX>xDȀ2Ȅ&k>S^3Bog!\"e q.ÍS_v  GXqEw8Vp\9M y N vArY8~jC!ۘ72F*JWkY$To FsAUKcЯ[\-;vkk:F! ]I xAwu3䞚8z7#҂:Zb.^9n  C5J++=aBa4 >ы5}l#UcE7Y> &ė"ihH7yZ&ȑMGף 4߁D3 TH$k7Qˀ,)4l8F9enlG�[s.b0OqYkУ牍 s4)xJB 4Eh�,RϣbdMQT�lZ%Bbb}e Y2V^ipN d|w8LAmO8}�фcRK#$ѐ�Kuؕ&DY+u& ^8{@4N^͖$h悜qfz?օ|V$?MD&ED&2 0G!2&s8ppMFDv>1SR1pjUlrGwx,] N\GN8o7T-!|&|31Q28}38mWetk<(<god/F``FtѠz&lNX6RAze q#v q�%WXz8`X6zbHq?ag`c{qGjdfXra1o!D/CAS腋h'X):?1Rm26q+Q} AQ }|djHzr悧F> a7 _{t'FXw&Р{фBX8'h7Hȉ?WVXxwTh(4t} 状gjR&' yH08Ҙƈ()ёT|$A هո׆ڨxax* %Ȏ{F)!!׉ wUo cy*Lwz6ax{*.)=x)/zǑY39Qif#Ssh{uI0"݂_b)ʸIً�5{i")s ꁍr$#Y 89Dg4 `u! 3b#"B#hdaIQ~KDFzɑiAa%!y&99T35aQɎtɚ+7873Y.Y| OFyGw5`JȇKàKԒ7auIJiyc)#ȁ.xD 0-^,C M⛤"lZ$AA0RO09�D`jw��@ !$J<Zvj![wp%*ZpPrHywnXS)<%ͨ%(!&x9`Py)xz TiqH_kEd1!!m,yH5b)TQ_xj&BQ~5^BNT^"珪ɥ%lIA7a x6*iy6)u 6[V_5[4'0pͅnu*<U u]uZ'uCU9�O7hmQ:ZUQe Xቍڊ`w5|#QzKF |6q_v�a�)y1�ѐs RdF@FdqiEa%& Vyc7hk!DpIj <u(\q)ܙ!�":2lG@{`qOU7ZO-;!\Trk�צ �1\Sq1[rsFU6J#jur%+S{;QP+Jb{=[*j)۟B=+ecP5<o`[ ]� \ & 7hiVx׊Pي TnQs6 5_g۴s낯Jq¾B!'"خk �n*DaKպr ]d1 +Ŷa-|,"@ڇccf5V E 0c DZơ`O% @Kܲ '%X"б{:9! GQo�Dbu4 Pv zV 밺&LYOT7yɡg KIeJīO@fz AK0$:T,v\dJJm)Y1~Q59TZ",k,љ z, ܑ;+3V!Q!a,,!AqZio" B�hDb$Ff~C%T8*"C % BJ ml)2$c4FK 4Dh9�p;$P. ѡЌaд9ú&"-8 31&Q$#p(Զ!xꆪJo'2$qiZA!5Z,a &Rңw8)69z(9*X SJ&@a]*Akq̙ %\ҹ)q aП d}Ќت]j ?}؞i!*B^L2\1k a"L׿!HGgJآe}!rb']((B^-M#ݕ~ l(j 'lQ2b?l ?(Q@ u!9Q!:1T]Қ]&) d )̑!)!=r#.,l~#%%9i᮱aҭ-)q!}~@шE.6+1';EB"X=y&qR~ޔ%r'j>~( ~S.Q!nH=&˝ߴQ)L2L&b>}CuSA񥓽"c&C)M ^`BȞ l!AU?=R"`0!N^ )}dQ4e}wBA"fNU2x`2ݐ}>&->&cw'2#&yر%)FGDnPMTAٰm#"$WwK>!>~J%=]؞Q$N`!/ ¦L3!A-> $aM%Z?M$~'}T'Q'ͪT~/K 4qSإqޟ Fe")_)n2#G"礎iy~F*g%|b+RVQm >`~łRsa؋T*':�nD-~�l߲e-ӷ Zh"txhʢk0Z= ~y0ņ-XeQrRƏ=X'S cЎ -.ô/2e-5H {p8 6WCU#t<ώ5s (َ(1N_7ZbJ#OVcŇ .<aƃ.]|(dѾ~&ŇgBT,4 z`I45&1"ԾdVBA#��hn �hS6 IʁH68yyUSXSeŞfqeCGK{4#|ZF2(H`">&,Plk=$هJ}(}Z .BIFza�B(ƱyKaGStQB¯dJ襣"#ApzlɁLÊ4T('̃iL-Dv2!(5)4[fhm݈ѷ&!R+Q7ƹ6)<G#M+I#ū H(0ΛsI'Ѭo; lI'PR$)Cd2I| @)2U z%V1*TNȤSa1F"ԊJ;W<hw$uBl֓ [N-L0i&<hi`H3<#è)Jӏ׎lg6*K:G1rj?%hvG�gR^QJ}ZF8NZ/2L6l<j$ 0+Ĵ@\%>P8djLjV@uaBHw;R*p i儔wRd9z袗vm2Il#336If-!*0ﳐkسܧW*A0Wƾ:}W088C",qլ):ՊL՘$ `cޱԧkk|B? fZc"&&!4pp@$B&)DŽʙH4eKGqIؙ03{WҤYᄞK~o3fU ]Nq@3u') 5KYӠIo 4ULDY}InkT«xl`yKVNh\@*v IZ60B$*ܟ%&G+'XxEGnIςN3V&p t�$Lc%%=y,L%UHDӓQ ('HlyZd61n˻†ejR $ "&LQz!tȘ Wp avS:L}dd=.ȟhm4{ RSJJm2zD1+ ^e0{_,y)ԒI~$K1aLдѮ<ir ;_1uKh`diU"Eah PsVُKk$DGccUYA511Nb=nْ]UB}f! 1 Jg,*N2,mziV*mV }hfmyv"BsszSveu없fz͛ND14ljlUj藰l\լ#ѲwA)!G�qy=8-lH_da[?bN!,ȫkm,*VG&x6v GAүd"ɽ1KL_IQm7 LT<^uDM',bj-%w&PJ_*!8̆d~< ͘RXɰHP7%rMR=hjwE0'MBcbV$%L0À2|@o*񀃖o5Pz1\*$c$$6;#{S6>UK׹.[c +Xp`0%笾ԪTـΗA֕k富WRS& DA]fVE;?1{Yp? )40$NAI"H1 z8hyW_?rA폍lIK"ғ+ElX7;E'RZL &RzdR/=lid{gXEOIu2$KTk7EX׳f=9Lr|> Z!(OCBA5*9S;`ߎL_hHmqjPD˪l[ " 2;I%((a{'~a]-Xyۘmc<1eBͨ 5GW| K$'* 4McO%azK%bX+!;3k;Mx {$gz1�S,$k I3#yJ B#ـ:aq>o°w{,c ?"2ԣK=bhh{02( `9C&;2b;1>!2x 2<4/ 2{q'[PRܳ,#,?6 |c6I&s%9-)+)," kZiaB \JAxJējUzEq{1$$>�.+#ԫk6qp3ٳ#q3 0S-I3\#2 !([硦1EzB7'*ypLA \,I-һi"8J-"(36 iƾҥG۝Үk*!c *GSӈz4™D4B}Hɜ?I#I#I,*1ʝɗ,J TE,qI KTKǑJh˺˻ KKKKO˹˖˿4L\¤K[|LtÔKM\$ML<Dt| ֔MشLedMMzM1Nz�Ml iLㄆ0ν$NHk |LlΊ8$TdO0OϼOtOMZNTMԇ<*c@MCMsPJ6 -uYQģ6Hpr *N˸kJPWY ]#i0*_1&LL R"!5!E"M&%%=R'5R&R&R%,R!'/,- *5.R-S$eS1pS1@77S:}9;S<=S>@AB<SBS@eTDEEuGuTH:-TKFT>NOPQ%URRETUUeRVXԀ��;��������������������������������������������������������������������������������������������������������������krb5-1.16/src/windows/leash/htmlhelp/Images/View_Menu_tiny.png��������������������������������������0000644�0007046�0000145�00000011070�13211554426�024243� 0����������������������������������������������������������������������������������������������������ustar �ghudson�������������������������libuuid����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������PNG  ��� IHDR���q���-���2\���sRGB����gAMA�� a��� pHYs����+��IDATx^[tUU-%RPEe"jP 8Y:ťθtQ26E᧷ "(Ud '׼ν%05HbZ'{9{sv~;jH.k9yNerB! X^`�4JvoHV: oZE<hӦ-ZJA0XK$* . {r)IFiޣ6Yh*<U!Jرa-ZN'*l۲sp۝Pi$h�WS$X gq]Z3y* iSXa*!F _v\au,ܵ<,+Of?5H0E1Ur;{_A~l2jF~.Zꅀ^ocXrxG`}iDՌ}-:Ut ư$IpܩjFVB/Хe?L"J8SA& W0[# #3_'//o~{3桕^̆p,Lg|[, hw*U,=UlDblV3zAha7b cg61�_ugN\`og8c!dPf{òzb&$[e54!bba6kc뎪+ѱ vˍXñ /C^mnÄoŚ:1YxH5}o7l 1|G]1h|.h #ǔr>ṱeb`<&.D׸x8-Oeڡ)\!修Ũ!wP+UrbDBCgr'RF)STI''{!%BKyͰ1* @|ŧsGTTsgoo|r0A )^OwfF#yPX;l }zA 62s :^�e;Wc݇E]z&>y3o.v~*x`)~h<:vz5` bKz< 4HVl_ TOn ?<끞g#c(]1mѦռSUUI$@TE :\Zj⠦-˳̙"8BMY#Gwh^fqQBr5#|9U0'P=ntEQ<p,aBCGc0ybૹTE%e(+.Fe n㛓(-aWB!wGcK% u K p[(]QJ0Xz1Z1Mғul?@\p2|I5XЩS~2Y1B%>TmX>|1 L)O"aKrBBeײU\8BBR2IP<SEy9Zw솔6d[֛ pqN<1}&v/hZ02/i5 ;b]3 ^ɳya&GD DxSg>sëDQSŔ^nQLv V{Rv}cz8'(EPY6 Aߋ9~^'V. =EMEUlɥE,S( LZ٣M{OyF @-*XtUf*PB,(Kt `j5yS4^RiGK询j~w sm,ҹREju:dg&\9^<u;4m"qw*ͲrsOXbl2SۊtTى߇wCV$OI*5Vŀ[ ь.Z%EkC ] KJ߿9 5jkئ 'n7Ο;SoUN YȽ`GveUM^,7f&`3_!r}e/DyDAl|zcBzWLf^5q@F-dxnk`UCmwu:Y$Aʾ1 f[ �' e솼|-9 /sjl@Pvn%lp2ߎ^J6yyX-^m_bsXz=\cbnMA#1k<]xE`^%XR4IN5?ే U3A(`(2?|-7d8N-{Q5sbp(lxS#vi8̚<3^BX<w:zޘ4Hh/ HtZ]5 voCawV,?߆g'ǨJ@1QdO¢{49.Vx Sd &&Dw�7 vpz˸{'e�cd;ET\k�8 H|xjb4r/Cjrs߱`S,x�;}Cn͐ Hػ= –t5=Qj7733C?w33E˂7!7"HYt|jEQxbL4y]CAd+Ƙ{&;05"AH H>'sZ~܁M^Y_c.P$K6 _B_a;*&@uӂ`ϛSC܅: SB {aN<?t*>`0D]ҊJ@E|f0y G[@B\Tv;`/ pwͩ#lAQA1RE^fD<´1c}!Qr=NDHE©b/m_'E*8)O<2@@ @"M[U"gnpa71r WT.xJ6G\"f0b[С3 :A<{#, Lغq֭]"-` >@ā2&S$:GR2f@o5BEh TZ.@+GȇN+%#r]'&iј#Cv?*|0&9E(X" Ʊ! /āl$&&¹yyj* 5ns#ZA>X[;~�<9O~KgW o6wJ>3�)锹+):NT1BFfP(HޠXQ2OR_-N,D<x *j*he:z3(KZg¥V7*b+)vKN]Ti}rQ6W*B __OH'/(Bju؝I 3`>:#'7mrqΖ2@8ƺshצݘ&Mb䈡=@4LL`Xs\Uo1@B8AޥQW0Ol6&Zw#ԼsQTg%'y.MnFrJsL^{̘5LrQ|kU' g~(ɌW&c_/rJаQ!k&|eF HUC-t>z>pGOBS+n:M$B<Hw4kgi=&݁_ۃؤD""n|po0얻0w|%de'RՈOn==AwDb嚭޽?_.AԈq625ᅈ Vމ즬�9L_dbpQ6-t|j1ΊM215s-?J0LcE%iYw=3 2[_αZcS�ˬ`7Sv'9} ,_'۷ ~7GA~ߨx;1}~|L>2gdl`sbƏY /JO>~dΛ&$<:;3U�dЄZ ;mz,[ V~.Zi]vU6va7oZSHy'7UK�u0�:|'|3cTF*ZwML2!&(D^n XLu*~Q %|N:?up'aQ|lؗ'럻PnJ OK!Hh93*z:"PBj:v}nEj޲]݄]yR\GZNcJJBKl+mNS%@ۆj_eEua1T^f-lؿ$CM>9to6XD B%(X<-<3B)M$HjV�Zf[PYc],E8M@;E 1k">OƟ6NzE6>,$^U|%{L\$$PD~ ҩšlѿuiͶu?ߜ¿�Ν+Z����IENDB`������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������krb5-1.16/src/windows/leash/htmlhelp/Images/expiration_alarm.png������������������������������������0000644�0007046�0000145�00000002415�13211554426�024643� 0����������������������������������������������������������������������������������������������������ustar �ghudson�������������������������libuuid����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������PNG  ��� IHDR���������LZ���sRGB����gAMA�� a��� pHYs����+��IDAThCZKkW=z$ )nlYBdCi)^h:P NWF`LHJ ! /B q^FJj)]Tn6"%;#Q\<\3gX*MO [FO Lٰu"S׀FJs?=viоPWLizod3`PVV?�χP(p(߅M?U=\_:rvne[7;c[^'8~iʕ}qmrK IMٝ[!> αSd߇B$b P0P9jF?ҫx%ׅ\/T.'qa{ ):k1F#JvhE9kr+lo%+S~AhA,m^0ىO3E(3dNabb;Ū;:=I~#E\yɸ|fYa.6}bj﷈ F]ɜs֗I%棭 8:HL� vCQ^άU!%A7y . >usL%074cÒ?G6%6zůхnYV$f0f>%~ Qff bYmZl. c�I;r}~ LG~woA#hc6,PG tD (.?HB$Ƨ7ٯL(ױYaP{~| 3;sbp_cK M¨}EcG)VIhcL2# "rɲU'!=,T\̥c/4;W7ib>RW'FݷԬiMP3y֦0G DXÝ{־{U#%B|ZH.j.+<*/,y' t}*=3/##a'O lJ(T!V]S˗6gYv2"ԏ/>9cX:̏J;SKV_kH]\rBbֶ̔qQc2L˗ş/_|~=._DlugTY@}-'PfЎfw3"w5Rtv=L@?uk樣 hPCҚ W_ߌ`����IENDB`���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������krb5-1.16/src/windows/leash/htmlhelp/Images/Leash_init_ticket_basic.jpg�����������������������������0000644�0007046�0000145�00000060067�13211554426�026073� 0����������������������������������������������������������������������������������������������������ustar �ghudson�������������������������libuuid�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������JFIF��x�x���C�     �C   ��1"������������ �X�� ��!1RV"QSTW25Abqs#6u3Ba$rtv478 D�����������3�������!1QAa"q2BR� ��?�?DZۗUHeV^rǎN(ԓ4DFu z9{Nt?gPdc.e"Ne[+͊aR<*]>D:L<hVcmsL�|xzt6iP•fd;uAG4i4̦ҥV,bɦV)΃)ǟCM)FM4R|&ׂ#",slE-j >ѻV3O6eISA RS%bJ=F5j^n=5-Nӽ\4:sNqwe Ve } 9DӫA6k =DgF++s.nO^t9w\ȅ)F`I)FXXYyփ'^iӮ z9{NeJїXvSiZ"I搒ILDvP/#d:1Cˏ.]ѯ !*R##|#q)ףw놃'^iӮ+{Σ{вkq*vE1M8*YA,XK"p̏ H@_Q`ׯ-Vx!eDgPVrNIYhɵ,132*je,k2u:ףw|XZ'24)s a5&ԝII8�]YP cO76"cSd􄠱[i $k/ Y/r?7�Oףw놃'^iӮ8X^ղNb}-6*c<+%-pn)?Hͣ M17J z9{Nh2u:Kh~T�s|$n'^iӮ z9{N?_m/&1$n'^iӮ z9{N?_m/&1$n'^iӮ z9{N?_m/&1$n'^iӮ z9{N?_m/&1$n'^iӮ z9{N3F|RiF2u:ףw->)~g/&1$n'^iӮ z9{N3F|RiF2u:ףw->)~g/&1$n'^iӮ z9{N3F|RiF2u:ףw->)~g/&1$n'^iӮ z9{N3F|RiF2u:ףw->)~g/&1$n'^iӮ z9{N3F|RiF2u:ףw->)~g/&1$n'^iӮ z9{N3GK 7Iףw놃'^iӮ$GK 7Iףw놃'^iӮ$GK 7Iףw놃'^iӮ$GK 7Iףw놃'^iӮ$GK 7Iףw놃'^iӮ$GK 7Iףw놃'^iӮ$GK 7Iףw놃'^iӮ$GK 7Iףw놃'^iӮ$GK 7Iףw놃'^iӮ$GK 7Iףw놃'^iӮ$F|RiD<Da1[IkYDbfg>tmR#L¾J))Q}DemXKH?f*DEVe[RT4e-1`Z䳜iDDJ5AbiSfzDxݿm65F'�3g;.۴ԛt5r{:vDȌOciWخz̦HX<iyNDIJ-\RDxX((: &/ IJT*UG-$!fmH^%I#I1gn㧭M �7k׷[-W˩v{:?kv8R;x/ro q� lf~&?+QO*KVd٫:iMм7)DmPXk4#&MqZu%%P|u*smjZ0[Vږxq_3z[U:n肋;o %jŔjO(%x4q}Jv\zAmѪ(Ȩ}FٴZ70ZpNrgZ[W۽-7_3z[*IGT?38{ovS)fOʨ^9 9%iKK%7 )$g&E74;oV.L[sjrПSq&Bd!+&X8vKw 'ޖb%4E6i}rP[o|f|w0zEMVeJU<0a㩄ftQ5Wj+719/^U'I(RL 5k&>+;ٛO۽-7_3z[:\9O2PrYrYͥ 4/ G ~$ܷeY"WM&U)nɄB̈Nvx`wNvKw 'ޖbU>囚GY)w7ys(THEYjL'\BehZRb k5/3[",Kg%lyص2i&kJFa<3sRKAЮH~R|n!D><؜|"{+8*MɥF-BiqLo3MMKW|%} ~R|n!FۭvfϗEM'ޖbO۽-OhB&|_7|_Bn)>gn{~R|n!DM'ޖbO۽-<YA@AA CuI;w؇4!{>/>/!7_3z[n)>gn{f"oqp&vKw +ޖb,ЄMn~Rn!yCŚß ßW۽-7_3z[xB7ssuJ;w؆vKwhB&|_7|_Bn)^gn{~Rn!DϋϋM+ޖbW۽-<Y9@9A yCuJ;w؇4!{>/>/!7_3z[n)^gn{f"opp&vKw +ޖb,ЄMn~Rn!yCŚß>/ _3z[n)^gn{f"sppvKw +ޖb,ЄNnn~Rn!yCŚß ß{W۽-7_3z[xB9ssuJ;w؆vKwhB'7|_7|_A)^gn{~Rn!Dϋϋ=+ޖbW۽-<Y9@9AyCuJ;w؇4!>/>/ _3z[n)^gn{f"sppvKw +ޖb,ЄNnn~Rn!yCŚY%wٿѦ/ef2LK~֟"VR r d9{!y4x m$XVko]J63ߧo0 6NT, B{qV=JZFHJKp"�>٫UMj(o^ŰnEN~yղ�iT)_YBJ6DI <T˅,ȳK4ڛ껓mGXkc߽ȋpZuG#؃OhT,hyfdb V{J6N;۱{7dMICN7FfW?-_hן ݧ~"Euݧ~"G��@����������������������������������������������������������������������������������������>o>T:Z}=7Dvg"Dvg";��e[m.%KGIH}`~+۽!-2|U))s?:E) QXQ0^^TkCjS58 :YFXX꒢ZIDx#!rQ*-ߏE\j46Di^buI3Rx1[ *&i+8ҲVk*Fdz|mmm+ٵɸ;E*k_�w8��������������������������������������������������������������������������������}3+>o>89/9#S?A(#S?A(`��s)UaQ)Ψb &.mzч;{{艣JbӢY!pd2I;YELˊ-K/K欵xp΃Cs[,}E:"9GHg TiDKawYZ|'j+Q2 a=r) K;, 8�eelJOx1X%x39Kҭ9jNuttu!1B^:Y3*Y. 2M5Rgc8WWi̭K.]4B|[&|ؔ{*m%C4'2>TʟsTbG$]阶*TJ 0 rf Ayk7dGY@u2[We Ni=MG$j4Xrɔ|Bb#7ZR6NrX)p"=~ǧ&"b na:Qj99+='D"lrz5Tn-wUMbU^ zLSY?=(K hY)fyQOe"dHT6aI"JDKfJfJQ'2/r,&GgPٗ*dj8smf)岙ޑԦFrLXn:wHJM^N*".j#iVȒ8Y&X%|C̽mݽ 2߯S+Yl6ȱ4H3"< e[Mo)oX*o=+GZ4ry#MN*䊔XN4uaKKdef'Џ^+Vv +wИgbNJmش^SG6u-IVXKqna~?ߜ]uKʕOHJhq1nNzd4FyM>&\|mFP:neލœ%'d<0J$W|N%9+*WYyd Ei X6F~Y'Q/U+)j۴BL$EQ~R0LY)j #VnJF\0w UZt+.=*THT[ &A+Gxx)^F+FSD9\m'N&3q_( ,诫EShۓJ2zPI!YRY+Zj֕ '3<]6Cr E,|W"a-T\mM%-XIk~q N8{%'.-N]}۞L&3dOH7Zh%gNrKM&Gb$ [ZJ<\hm FjQx8$Z_Hʒ‡oTdGWe<5x3(4:,lIRL�h\.V&YZӰQ Qqp>waijpuߪ4Zk2),.Iq,IĚXȏ-ZfRm*rhʗtQ&I:a=lpCirp Z"Wn -%űfFГ$onj*Cr,i!q;-*NklR3̊+[끘Ya^BYIn:^JVx)#<Iz\"ZmB\*CS$MAq0%iVR=X(.Y,.ՙI̝èLGV-hhF=dFD(*B.*rI>ƝI6Z2J|Q8Q6?DO\E=:LkJ5sIDIr I ǘ++4 %E*4LC̫9C EI$p,\m7&7o)AOvakׄj DJS%MʝJXP)#0dM FIZ /H̰0s+Ǭ=HE9/R7$5wNgd&:n$xFYd/IiIU' Ljyz4E(SVe[)hu<HZV5]ׅJr_vS~t%ERa!&-f2鬙B֢ѩ,J ;ySUD]:ku͓wH-N I#[~q1}X�>j q3v9 {Df)'^1eN̫S`ݴ9RďQenJMDmTDhYxQWV\YNeũT. JC8${yI7K<ԔK=S$L⦐T H5g63I&ThSĚIŖi9M<>uރc>ʁvjhuueP]6% ml8\(^ij+Z*1W)ڔdzUuWNfTt%cxɐ2y*)"ƧvY[78}Mu Y"3!2'ՠ\r(BmON4kpJVi)Rx(YJV]ui$q\te“A[f]u,?QEUӊ(SԨ,c/)t ʅ*F<Qe.l1MXן({E*9t˜!.;/*M"JVf[GX7q"ZT ̥un) O~փeb)m, d<lVژ?q/S//f*/i. 6oBEUv;}J^8ʜ:I6yٹĝxcKJh3Va2QPz:*o,PSg +$7%R\(t>W!KlĔ\BHj^iR+Ypi)ֺ5)_FMFk2"LAˆm'N&3q\&Xf`Gr)d.f(mR(g_ur&eIuRٙ5 G"q w��������������������������������������@^7?R`O gW S-_hZ"?N3Db"?N3Dbi��2��Q4^hUM*KZRX$+ +3QKmZNF>2!PySR7#-_���������������������������������������������������������������������������������@^7?R`O gW S-_hZ"?N3Db"?N3Dbi��2����������GjX1NrdvmnNq2%)$qx56 rZ-mZTiRq/FF_A2nIen֓M$nG:j#u/Eų?. ٟK3"}G-[v̉2pafTfńӱuK4mp%XK7>~^QH2JSSE1"nFšM2jRxi3{r6ZGsvT\"+(腤lImzWd "sgr5 fiXVrrY }]b&<J| haJRP)FISFeZ,{ ɢ@uܰPTsVI1lÊH^"ՊWlJ;u{&]d܋NzZVX.HC҉rRdkzRkUraoP됩 ]p7m̡.$mK63q5I8fM{kMci6_L)nG)Q碛[)QJm)f2,$�f$O{V/bUMONs[ed< i*"")Y:K",9.[=y&`7Ǧ؆yx;/9G~\QwcM!5XB\uLW<8ehDvRږJY16sӶMve p JaH-O7Ru%6dX%9mAmd|7Ǧ؆yx;l^ {\zko{kMc੷Ǧ؆yx;l^ {\zko{kMc੷Ǧ؆yx;l^ {\zko{kMc੷Ǧ؆yx;l^ {\zko{kMc੷Ǧ؆yx;l^ {\zko{kMc੷Ǧ؆yx;l^ {\zko{kMc੷Ǧ؆yx;l^ {\zko{kMc੷Ǧ؆yx;l^ {\zko{kMc੷Ǧ؆yx;l^ {\zko{kMc੷Ǧ؆yx;l^ {\zko{kMc੷Ǧ؆yx;l^ {\zkSfŏs{Y8D8LHBKY'V6X~ns d8�Lz|L5J}> /OƩ_ϰ5N(u} j@{o,;TE+;TE<=wX�������������~`? >#��@�/ic��|+mD;}JlH[) g2LdX*S$xj1'L}{Gnػ/ߴRDkNmmuN DNaNRsW6R<Nsj vca9/VU12 rK8ĵ JZl&Y(U@24J5\2 Lв#3BF1KR<NsjGm^HvwBٴ%L+&*.#:Ig <ZO7iQPDs^M)DR4=1B D| e#6plx^5)yW"%bδI-iF%&X�2;f "NVi1Av_ʹ$�])'9{e#6pJݫ>ez$;)~n8ҿ5-(#RzȈk^7I;QĩhLC$*2B$k=Z_r4Gm^H9ͫ3}Zc4tNkjEԬᘝV%aÄzh;qܲmN]zOҡ즳4&=Gj>0)'9{e#6pȸ ܣ4g#iѓM;O~pPC~zF}=Gm^H9ͫ*.7hz4O퀅sW6R<Nsj 'ކ{`sW6R<Nsj 'ކ{`sW6R<Nsj 'ކ{`sW6R<Nsj 'ކ{`sW6R<Nsj 'ކ{`sW6R<Nsj 'ކ{`sW6R<Nsj 'ކ{`sW6R<Nsj 'ކ{`sW6R<Nsj 'ކ{`sW6R<Nsj 'ކ{`sW6R<Nsj 'ކ{`sW6R<Nsj 'ކ{`sW6R<Nsj 'ކ{`sW6R<Nsj 'ކ{`sW6R<Nsj 'ކ{`sW6R<Nsj '?&<s(^x@][)'9{M;MxJexOn&b9VMIW]ژm֡&*3RՊJ+QF`@�v2}3+>o>89/9#S?A(#S?A(`��s(����������2!rq&E(Rݩp.k6Q!8fga#Z}е(*tIwJc3VO5ԜXmf ɶD8j"5iYד6+S*c61>z=fdX:rqreN}[& YKQ>F^:ƓFꑂsTT,)\nP}+bi(5:JdN8F.T < Uv22L㨬4 LȔ,99ĒNK3KcKtέ 7&1c!.ԡ顤lPI,E|ZXa&[-;5/�{ )UH^z,qYaqdFQ(Ҝ Ӂp2#3"5a=P붅>Sޯ>9ñc3sCN$M c"<1[`Oim8Lyn*QȍFfE -I,$tm" JV^0>RZRBs2FgFXxs&ÔVNg=NV+GNeکE6iIʚQ(ғ<p.9sӯiծQ("ܧlըO7|9fr^8ĸ0wmN:9Q|9t_I~諅 jLubߧdUdXȱi"NViHd|3qQp}?l=-ץ3BBu=˔A`g6̱<by5! ?�Ѿۘ|nלiqwEf{p=HM>J~ԵgƁ&MhfRss(慠%7?[-Tjܖ oҪfȍeᶧ<8Fۨa>j!p-}a(_Q|ae|kubAZĎH&NgCyd9!B\eפY6HM2JQ"",LQ nqη G:XtN7nKન&oe%k-W=ܨXVi UQCXhRz%d+xh7uqY-b>{)PHE]żM 7ԢI/7 ӧWgsx}`*2<IM}ar:G-^&jzMM''RWNMNqRsZ? 5J#&8総JX~_(u'~]n2@~[[$�G_(um_(uH$�G_(um_(uH$�G_(um_(uH$�G_(um_(uH$�G_(um_(uH$�G_(um_(uH$�G_(um_(uH$�G_(um_(uH$�G_(um_(uH$�G_(um_(uH$�G_(um_(uH$�G_(um_(uH$�G_(um_(uH$�G_(um_(uH$�G_(um_(uH$7x#�Mη&Qe])L7l7o*a)* dj%EgZo@V/.Ϗc@͒ ٱԣm|LbMaymm#�2r�K�,Xُei[pG)V!TJtDrRe,|4x:�}3+>o>89/9#S?A(#S?A(`��s(���������phdru2LS CIJZx8G9geM]WVg$ZD.HY1 -M̍M.<>Qa@p.ejQ[>[틙#3E;?7^n/3fK]YLÏ"TMl6[Su&IyLK#Ik݈IϡiI i N-t(xIe-)dF3/VTIMF\ŰgO˖!hm4҉ũ%dӊ*2NKq|uϨEoUC!Q^vKrCIq8988J܋QuZr\g6$bJN<f7/5Fy'2. g�a*w|gyx�p 3i F^>e'@Zb F^>e'@Zb F^>e'@Zb F^>e'@Zb F^>e'@Zb F^>e'@Zb F^>e'@Zb F^>e'@Zb F^>e'@Zb F^>e'@Zb F^>e'@Zb F^>e'@Zb F^>e'@Zb F^>e'@Zb F^>e'@Zb F^>e'@Zb F^>e'@Zb F^>e'@Zb F^>e'@Zb F^>e'@Zb F^>e'@Zb F^>e'@Zb F^>&&=[ZA\R^*""F~xbX?-1�f@>o>T:Z}=7Dvg"Dvg";��e��������~7cJd]ynp>e$eM4>d$pQΩ pDL2JZ eҚ�_Jw3LJmYeR)z=?c^^yЙ} -CFrشDJm ]5NВ 2žsBҖ8Yx%$x ϹY;N-BץRn ūLNSRz4 m-08�<;WA,oבtCm!"iq)Jdj,85ۀ F}y[q8Y;&D2L#eO< HBS4q)<S_< HڛϏ9JK\+SzGDFxu IВ<LR, /9'9Ȳu9/9'_sOP!$r;_sOP7`$8CI�w`$8n~Iq=@~Iq=@݂z!'\݂z'9BN#'9v Ns<pGv Nsy : /9'u9/9'_sOP!$r;_sOP7`$8CI�w`$8n~Iq=@~Iq=@݂z!'\݂z'9BN#'9v Ns<pGv Nsy : /9'u9/9'_sOP!$r;_sOP7`$8CI�w`$8n~Iq=@~Iq=@݂z!'\݂z'9BN#'9v Ns<p~ns{_sOPyϊJidj, JY %y !�u2}3+>o>89/9#S?A(#S?A(`��s(����������������������������������������������������������������������������������������TjT_W�|ȏӿuLXȏӿuLX~Gu�̠�����������������������������������������7up\wL+rܶߧPj(*]b~#:䙓mx$RRk'+KyxYmvR+h P|B*30K.ݕ&R9TՋgdSV/ E3*5%Vzx"%*& U3%n: -W8ڬ#rQ@-)svR~m;)ڌ, bIt'*7LXlrj3bgt=ט~%Mj⣓(RI,Ӟ Sdg% 3{z^u֝&"]F$vYvKm2m'D:JRN*RDJNT3D6۲rɫtυʧ&_>8V['[uJQ/J&CTbj3W np)' J)N$Q;I:\eQ*'&T]ٙ VY) 5JZ׳ȐGurɫtυʧ&_>9^XGr\'u'ͤDå#J<#͸htFՕԪi3r:SNB^C Ԡ9FI2Qēt̙eZy_YөCZRnMbF#"7# #LGbv`2#�+KzikBք4ċLJ=c�÷�B2\?xGN1ZDM6P\fˏ-HJk2hҜ$jx`qW&Ɓs \?) Ve]Uywt)tqJvN}1պf\32Vn #F>ːuhʑ+iEe $SZv!Ygk}1.=\?S{(ԛ~e~C1!U#TkJ^Yf$xO'YwVm,Nٰ r.aXq+xp$'UVSϢoYxhz1<cC muͭ S* N9Q,VdE"=X]Tt(&KAx1�aYd�{�O�dY5ϝb_0Ɓs \?< ,<<cAyuJ稔W>lI8K.<Ѕ^kFDfN]c5UB2L<T KYRͧSL6IZ�dILi",VwǷɫ/[64=s�P9qU/uwUBjqh$obG%TFqW~5eYݱyS�s�P0HkBj+a}!#Q(3$c1&DLب@^7?R`O gW S-_hZ"?N3D]<{2ݙY"$$҃Q(5$f##S?AZKO;[+a(մGL]'jvRA'DyqYfFX6L,f3_/f*EoK35"lT2`BiK%GQuxG!gs\6ڛb̙Na !Yl; &BM YA9wx~L^~ JA&q%)M,2Q 2Q'H,~2#7,{T۩Y8ӑC6% ߎ鵤&̉)I{w>ԥf34PniZtϓijC NY%FD.z֯N�w]OZc-qʐ-Kum"/,<=B*fU2yLy"I&-,DrAfH3Qb#P"P)j%B5tǢT63LԦCN(IjXN첞井DZC4B4̕O>:C|2^yh<#7o|rSupǏdT.Z*DjۮJ=ͼq"Ru`-I<~W >�nT7: cܪmA-.B1lJ@Q)*,3Tg`GpQ{ſ"RLi9AOEm.ǒ-jׂN`Dg7gp5UnIFGf=- u-! nT֓2"26Ե�dJaq֡~ŊԤOneE(aTmL^toEƔy/)'8f_E2vzTDgSY("e[ϒDjNҖj#=:y\+v5iљ: aQ Es3xȰJUj^t5k=6d=J:鈗 Ӛ5ᑙ`F35J7)]߻\kۨeFO(>fբ;94PNv{)%9bu6l*)!5RaCLfEp̐-E[23-i43I ޔ۾k%mėKZdgah98)% ֈKZ8YZ4"VTpJ8~j#%6Q~ߖvSz2=AB֪Ujlxha/E-ZDj J3<G')tF.\QFrd} qBBs<|VNyسnFϵؓYnAVFIē١kS*lJ4I{MUMnTRKZdb-98)%)kQ?W/ëO�����������������������wf[s,0&L4ȺȆyh2� >hWX"gTO@IQXeZRuXZ~JEG87KpV.ggN:%CFYm쇕$RȈ_sBK5( ԢunӒ|w9Q$F١Y25wD}?zOIIP[1wTeXϩ["mFMd)J5(IjmDk%^v|f/TA@ZKSdDhu mhQbE$%&U6(ooB60 Fp3^OM3pRn-nSeW>{ϭRem4e%f/z{-MAT+M$o@U22Y% '�(ТzML򂫕3 s:y#Eb bev^D}}I4BuQ4}ĒJ5+)C' TySg`Ɯu+%rP%6jmIq`ڍ$IQrТzML '�(+m& ȏT+L&v[ά7ެ)`4tM7嗎8 ,W?;�$<#RU'9y\qC(i`IIh^&|&fff#)ύyTL)~+5gg)*I[#WKk9out w*vCzrv}46KhTsaɳHV)J3AAfUA{2[ kL;VU%l[]-;]˥\dti.;]%%{KTKq3ڛo07M9p)Dg&,5z/U7Z<m # :fFýl[]-;NpdrmvA޶G-dAm�1?�id>wFγX"Me* %Rޑ9iSY)=iJKc"&fN&OufdDL3A�;샽l[]-jA=xo:R"?"Tu2bςD'3#N%IQIRL"䂞7>TdN>MVj*;q!i5IxJ?Q{z[]+Zȭ:ԓV׭W'~KmULq eTj,LӉϡ'z[]w{c[#WKk9out!d"_q&gNCV{:2ʜY;$n(ֵ-FyE£"�TjT_W�|ȏӿuLXȏӿuLz dz8m\ Z%9ljZnGЎJ2?~fUVEKvدj2KFQo1!d+DҼRj<d'.uj­1nS2{ QRda^^s^#rXzh 2FvQnYrXuM4R%5%(lb٧x\|_1@beeFrB Z$Ke%I%$DI"5.U,V48ђ7kd}R N}z<]Gdgr}%DIi5 ӺrdMRMOMf6q$ RKF G,L |;ޗDY9 KD';Xrѱ2ܹҖ"3-N$Q$Mfe`wFѪf/IQ*4ǣq-З ԕFfJ,q=zº&D\&AXb2Ufj^DZlxf`ɣ)(Y4fxQene@R*MZ:v2`F i J'%`[98 [aƪ^^p># ,v!(ȖŰܚTl)02Xp5q*8"3jR[#pJ9ޣHMpt橴gD gZIfFd!%dRpkO87sOg' q,>ļc3ȶYRUQ*Q'+kVg K(G2W,Se^fG QHVLFKlH< F@NNm.wk>wSUY&(,]7 ڻF~Pv:\s[KA;/M). RD"]xȷ%ǂ6ۥ4f+Iё:FkV9f ˅ ՞KG2.tR^fIzn2) {6 YI7$F{\ 9vt[i]2<8햒SLjCmINJ ;QKokKRGX4ܨIK+z6{QH< qXxC¦\vETWO~"T8<&BJuFd'eT.7,_e%~9lg6zŠEH!S!ROZ7%%Ls%j}mit뿅 FjR7ЌQekKFi /dI;;EK#~ (W.kj<nG@a M' -(IzrsO?ce&m,残2RNTd39: 'Ti($Fn.sgZ3Pu+5V:Bd=!HZ#5+29idHťbf\lhZ(F aZr:="ST 4y$~ާۥsQ&3_YD*Srb f XmMMAGmQ~dN; rխ]5qsҔ2j9L擉J8J:I�$IOp� ڥOn\>+,dtތٶ)(|ղqJsI$gxYEuYpOYL4fة!URͳ%EyJ59BsWǿ Jg\=ٙY((NTFf5-I\TjfJ#3=X%?*G)4kM\ڝF)ZQEN(I!XU*t"M|~bXᎱYUr\ei)UY'(C0RObMSQկܱV.:ڨϻN,ReJiŲVjS Y7#lGH57OX/X FU;.ٖe l4.;Le$<af84⥖rz8}ϧRSc!gnHeԢk45FIMe,]at~K?F|Ͼʵ>#UI>Q'g1KyМ$dp _2_Km]qTF(Mi]&+Jx3F$Щk$x')jvWS-FIq~\uqӭ.&imn4CАdRY:'RYK~k,9t#!ʒt pSڝK&u %2&Y$섙$&Ӂcjz]5:}Ҩՠ6FEHVԕ ^ğ-!$*I5H̋3?^\:#Ƶ}��������������������������������}3+>o>89/9#S?A 7)yˉ4-)Q##!bFNAZ"fAé&qNf $-#%a3望ĸe˯SwI6&HX 8e5ivM5[ 923/՜ >LؑŀᲤSɬqыGy=望ĸeO }"TLiOդJ[u9ȜZM)I% I%Bs5bFYf5+^k)i,KM6=:RՓF[ͩgӈ3IZ/O<KP>hE"Π̀PdQi%:T)IDaŒV8cWU[SsM:m2 ClM)Rm)Ruj}T%( Rx|8;ж40JQB@ܓ[0sMZSA? X`'(h 4*\&Pfj "I=Ec)望ĸeOvDA-#MTr{kV"Ң϶cRّiF2 }f[鹕qW*QF;7QjI\^U'qzÃm1-*޳fЩ]NDm;ug+OXd~ĢTTi]|8ңRmRH̕G龪O<KP>'v!m8Kc;t[{d(Sw�1INplQЧ1F 0SU'qzÃ}T%(miNZR <ݍR$fiqI5'32^͏lL)3ҶLs4yI-$I$DŽFfy}T%( Rx|8; H42ߤM2  \#m:3M)DXט>>Xک[t2Q-i4DdMP%`"~1wI\^U'qzÃm25\eSmM"A!FFHғ2sK ,Z7sJnkQ-T)>Fi#HdDiU'qzÃ}T%(WmK{J5I6Q ruIY'o Y</dfBDvǷGuON])ӊ,J?ȱ1I\^U'qzÅL-#K/&*mEvU c% @h݈6ҳqBHZ=S,zOD tl(pS荭<Y$ay< jC/望ĸeOv=FNH,DSeɁAKlh{-"WgD=2wjˬO?mRώq&Nr J~K&I9Af`DC3oĸeOv=T$v42a=f% u6K%TN &RHIp`'ޢSf #; lڌRmh24f 4ȌO}T%( Rx|8;!imni.MN c=盋$,318-Zy"ЂEƵ F$i.m'I,dJ">c5oĸeOvb-#EH݃- d[3?b6)&>z#G3<0T2YfUI6ҡ̅&Y"vIiNj=3n<KP>./Y@pwmEMO\5EbJpK6:aD#IFȌjқ@Q'ODiaűKx4:6NrObxpO<KP>hKHNS92jBFhY֔Fp旈4\ڰ^ڤGvJ*ڂU8v?9XcqfU'qzÃ}T%(W;AZ;,Qm]!Pm5ldIJLȸLhؑ"{@T%F$HI!,C-望ĸeO 4ZԷ=ۤDz|KZB>g ,##(eQ|;q;c6Nffj7I֖MDj#!Z}T%( Rx|8N[QKyVi,A-p=F-HKmI)l|#JDEU'qzÃ}T%(03ibk}T%( Rx|8;жd]Rx|87I\^AiEU'qzÃ}T%(d]Rx|87I\^AiEU'qzÃ}T%(d]Rx|87I\^AiEU'qzÃ}T%(d]Rx|87I\^AiEU'qzÃ}T%(d]Rx|87I\^AiEU'qzÃ}T%(d]Rx|87I\^Ai@^7?R`fMRx|8H$\ury J(*ӉqZRzXU H3`=S�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������krb5-1.16/src/windows/leash/htmlhelp/Images/Kerberos_auth_serv_fig_11.jpg���������������������������0000644�0007046�0000145�00000022646�13211554426�026273� 0����������������������������������������������������������������������������������������������������ustar �ghudson�������������������������libuuid�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������JFIF��x�x���C�     �C   �"������������� �?� ���!38q"1RWv#2AQ6FdGUa$B���������������*� �������!Q"1Aaq2� ��?�������L5Uo=Q߭GDRW-]>HdlmU 'Q:inLڿuLVk˭-ɗ؞bpBۅT;n.#_gb2bz|(e\7tΩ^.'dl]dGp,6r𹃠 Gl{-%L\{ZwZ}{m5۵;����������^w{66,v K\|,EWI~D߯}sT8SZtW#o|mKN,:I!5o1EosT3k[b|x݅/"wo#؊%r֣Wk||3:S3V2K2e8UMTn$Fbz616Wm �����������4]kzcלŎÔZuTkυc)7r"o¨.ujgkN7Dmͩx7W`喧\CI#QY$1ƴ=b9J&w|c4\qklO"W9u:y;QZ$WZrjq~gJfu~jFI>!WXcj]ֹOW;}b&�������������8U7&s=[ L5@huc7&s(nrJM�(ij~s=[ 9}CI 5KUf؄i^̀4-Riv9tU\$ɹۢudcjWro׹Rl3ر_%MZ=4VY懔ybH?�%wTGls=[ 9}CI fsym%m&>bxH0Rt85—#ޯ.R`d,7jz5U5kjrLt{޶ 's=[ ?~ͅ0?9}CI G|R\mpWeE=]4$SFG5sUQTTTTTR+������ &wGa_P~@)YI ’zZ,1Njʋ�'>s=[ 9}CI de@mI[a|WVcswUyRRӵmHè[F-gJٹwjzuTk$UwM'^ѢzW4yl+OLtxn<ozto坽// ~Mqxd*iG5*N#VDW#w[3zW4yl+Onܱ&Lt{޶ '(VIqU_ot$MױUG5QQQSQH������*웓O9}CI�e$7 Ij#lLG$n9*/l+O<t{޶ '%U1�fg<!%nC 9][mg9eViH=KN�Y#ImCIY+fYQdVƣI6Db{F^wGa_P~A;i?!17'vOhX+|5Mۮ̩Ԩc'u;?Y[\owGa_P~A;i?!rĘS3zW4Zwe%W}&TSHE4nDs^5UEEENE"���������K?IF8ؽv)k")rORmыn)kH79L3�agߐ3o)~Ca#0,Lo8ݷJ~E&^ M1wmҟ-i�����K?IF8ؽv)k")rORmыn)kH79L3�agߐ3o)~Ca#0,Lo8ݷJ~E&^ M1wmҟ-i�����K?IF8ؽv)k")rORmыn)kH79L3�agߐ3o)~Ca#0,Lo8ݷJ~E&^ M1wmҟ-i���������K?IF.S")2ORmыn)kH������^ M1wmҟ-iIn]tK_D0�����ORmыn)kHLtbۥ? Z )�����0n]tK_DReۣv)RL�����tbۥ? Z"/d�&O– `����� %ۣv)R{')6ݷJ~@S����������a/d�&O–?IF.S"����� {')6ݷJ~E&^ M1wmҟ-i�����K?IF.S")2ORmыn)kH������^ M1wmҟ-iIn]tK_D0�����ORmыn)kHLtbۥ? Z )�����0n]tK_DReۣv)RL���������tbۥ? Z"/f�<ۤNXM-Kh.նKX=z+\֊Lt{޶ 's=[ LwGa_P~C9U?p~@)l+O<t{޶ '/d�&O–N<?W4ˣv)RL�����tbۥ? Z"/f�<ۤNXM-Kh.նKX=z+\֊Lt{޶ 's=[ LwGa_P~A=�Ui? Lt{޶ 's=[ In]tK_Dc'IXܟ\+ԿOeыn)kH������^ M1wmҟ-iIt'Jz뎥4 LjOQIS|Xdm,ms=EEEEEMp&~s=[ 9}CI�g;i? N<[ LwGa_P~A;i? {')6ݷJ~F2tU½K]O– `���������)~F` 9L{ 03oѲm 2E{"[ Xfj֣R9j_GY=[1vݍ|�Kjj^#ٲ~qJMutuR}kkhlqFգʨՏֆcqߨZT|vu;XmؼJȌ*oƲKgf.媣]nKk^Vk/R;TMF^j/SٿMEU5PֵUJ=AngN};6]CRu]H:^Q8jljTsUjLS[n/9뗓kwk7Sq)mc)b+["3zƲ6gf.7UG&Rʈ%r/bWg5]QS����r7f�Ôa!gߑS=&ūFY6~͍ؑv5Ԓ5rccֲG*6FJԊZ}Y/mS6~$G:7F=V>9GG#1s\"93o\j^2Nkg[ʼnllFcֵ9Q5UFRKm[UGOĈ1ѽkF9ǵ|oDs5ȎEDǔa#$MG ������)~F` 9L{ ҷSuv+\$Ϧ_$X娑F+\٪Ĩ^C }VV*h1IMxR=cFJ9ȨJ5{٨,KuI )ilqCQ1DF6DC+]l[ DzzZh8k֢#Z"!)~Ca#0{ "m9���������������������pr]²E{7تj֣R9j_GY=[1vݍ{�Lljv#ٲ╾2FQJUSgVW*D{V2ko8]r-nfn>E;:ͬe6^%kxdFS7cYM3Sj媣]neDZUԨ2]²E{7تj֣R9j_GY=[1vݍ۬؏f˨sVn˩GU+V6mMZ9\jXœ ko8]r-nfn>E;:ͬe6^%kxdFn{ K/ڲJXUi&ȈV+r9]{9?���dTe?·^wcZI#W*6:1k$rdk[H^5r-=Q4S"9tocc㑎Dtr1s5r#Q;CDq9z1:)o&ƵFTlucZHFֶ)UKOY-/mUSE?#F=V>9GG#1s\"9;@������ [:z fg^/Ԓ,rHVCG#UEEl ]TtQ?]+u>WbUALkEZ(hjȨJ5zvKu }$L#ڈֱj"5" ]l[ DzzZh8k֢#Z"!��������������������������������¦On1.8 I'>O*5'Tc]E@y#bTLm2Jgg5tݮ+Ǫ9^?p+ݫ[92ȽmdiN+|7w_N�t8{ K/ڲ:XUi&HV+r9]{9?v_~sqvbH 9w:xUx!Y<M^7r/E<},[8jmTSl\%cG98^k^\>ܱȟ~Ek#Jvy_奍湼KjqAIpVGA5DtnTG"9g'4LcVbk.kQ$jFX5dTlkbQƲ[n_eڪ<~$G9{\|r1ȎF=cz#湮Dr*'hh.5r/Uf'O5׶6]֣RHʍkZ*R)i|k%Z{hDsǵ#c>79kG"h��;]+u>WbUALkEZ(hjȨJ5KnV*1IMxRHQ#U[% TVT5wQF7V]InRAAoѤqCQ1DF6DAk픖u$HOOKMG1cDkQdD>���������������������������Wdܚyl+O0?9}CI $,mY-4<C)=Mnj?9}CI{¾SdE ^/Z+%_qe<q9'QM׭U7{¾S3zW4���eA7k |$ GsWUz*1芏z." <l&uϙRNѳysGnOPczH/^qd^4g�NZX؎kĻƯ웓O9}CI�۱ t _!dtʰ>[TLWFDr#zret(ڏW%)Y}Dev#ujR&OL](%z3U21ީXDmkUuAi/4^38"d7)smGeƛ^毢)ɺD-QcęIm,uԍHܒS赴ݛUD#ds8RiuNstsfE-5R Y#`нHORܭZ-g!jR7qԼ\oQ~\]5٤l4͕#$Q8Y횊5EeKQUEt RHd¬m:2H5T,4o9咩L^uA6OKIDZIg86L,N}dpK*/M2jq8헬 ~7c*?VZ_VlRҽΗv39ayoڭtVKe%IAOKMG1cDkQdD<fOl]goȒ mL+u==.S۠ces}odʑ;i?!LwGa_P~BkQ-u\QOWM"Iѹ{TsU:������������������������� :cݪgm%I ?ʆ6#'*5je/f�&iO– O)~FJ*{ S=*"ʈ yL3�LzNFݪ5K�)Kga}6?,?UU\G:Gqpon&r����� {')4vn�-$E.^ M1wmҟ-iS=)~F` 9L{ 03or7f� /'O–?IF.S"������������������������� {')6ݷJ~E-Qԧ[v7X,IiECGO򡍈7ʮ]MUWnP;0�����6d7D�g;kSGN.Ej쨨ukƪ۪ ]>Rd0�����K?IF.S")2ORmыn)kH������^ M1wmҟ-iIn]tK_D0�������������������������oRmяv)kHLtbۥ? Z )�����5N?m~Y붪g򹼎t.tm} j'M]KZyՏQp5{"vsQvTT]M5cU}j@�����0n]tK_DReۣv)RL�����tbۥ? Z"/d�&O– `�������������������������QQ}Ju7mqUO䖛]$T4tn*،cx٭DUUvU;:v޽օk- -?^,Y%ՏPSǼ4tcEjnu*pkVڳ,2Ml5..-<һoվۦ^K NSj3%@MG' S>7*owEQQ{'�f�A�͟ [V}埦R)͆ŷC3W~ zt6ph.1;MߔSJ]53ALԩ eeED<qoVo� Nmo.i)Ig[M|Nط/vUqWC$h28y=jEV!LkxZ`9�����tbۥ? Z"/f�<ۤNXM-Kh.նKX=z+\֊Lt{޶ 's=[ LwGa_P~A;i? Lt{޶ 's=[ In]tK_Dc'IXܟ\+ԿOeыn)kH����������������������������u_Q�7_QOBmqk{9MM}FnY`5�"s춗ldGZIQv՞c;,2b[Czs<>bӺLLJ oICs~ƕWڻ/n]Rjǥcn޺tÞ{ߖoc+oVKuX-]<u-8~}m_�ϝBƦ.ޥ;54ueemiOuS"&ҵhlRq14{Ym#Ȱ\FIApn_eucje͎V�T2MSv6Nmn;.+l>3gQȫ**J蹦0s:ytSRd i'tG%\tyr+ټoLGn"1;�@�����S= nTEZicvk=rG_^BTG7§9PՇMl=(䭯U::FXH_͗FUBbs<Rz;ipSOL׶X#H+ct~]F+i_W[y),rSSV?Ӿ8ymdI8R$W*ng>{[?3nSVog?nwhؗԌ_!_r.3QiU4ZĠj]ΝXd]=w]xS�N˩.K87ZnCb>F1Ӿ'Y:'7�+F7LgrY3&>jN UFs4c^kbGZ&z=4={\Li;}fr}Mj�P,闿RR$l;+bzH*zFRN<{8Yj^=ЌfTjlyQݤPMM_,*ԑnvz]=)5tupr7d��������������������������������������������������������������������������������������������������������������������\v,Tګe~9-Μ.G' =3~&.誊&>nط7������������������������������������������������������������������������������������������������������������������������������������������������krb5-1.16/src/windows/leash/htmlhelp/Images/Kerberos_auth_serv_fig_6.jpg����������������������������0000644�0007046�0000145�00000017256�13211554426�026220� 0����������������������������������������������������������������������������������������������������ustar �ghudson�������������������������libuuid�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������JFIF��x�x���C�     �C   ��e"�������������� �<����!1"#AW23Qa&5Uq$%BFs���������������+���������!1AaQq2B� ��?�ҔRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR$y{{ౖw}yӯZ¯4oM‚jl{xѲin,|Lm(by�Kt쀩nNf?@|�GW {>�W{ێ_OߕǺn)u|WH�=2 :��5�e>qVڷ|&M}!sq}$>&W`u+1}NEal-B|*Y%N@ *_o3X+s]N3Zވ#6�fBʣR5}%&3}=f8gߘ kSf [ \h(8nవhC$JQK1>ɨ|>K]4rC$ ļ  pG U>\&2.DJꤨvTB@�](>GRohgܾZkx.qQ5ĤO$HԤgyEm)UD}7e?nmLܰBq&z,.JDd!EMW�,`;]&y) ix ,I:^LDƾWltEqpzLjM\XȰ }?PHv6on{&Qv,zC)Pqل *^Ŀ v㚫�\tYX,&ؔۥf+ٌ !7�vG,~]9̡ G213UfJPx+8?W1S#_.K~y)6NiSmu-*9GDX9`y~^oH71"ؾ�n%*W�iҪ#6TD>t\|s>�ⱨmqء^ Kf- $һuHyUTm5lMkvlY;\[HA$!$� 6uĮ Cԟ9z:'fVv#t>$BcavK?}ɩṩ',b"Z8i,@{y-b4r*A0jⷶ2Df~Qىf<ĒI�$Dn㸝mmÔKb�@$Ulw5ƕs.2nqicq-N "fu@maRq19s׳5Er8 W $Ɯ3>D]N:,0֝-Wlزyn(\zps#)Ub/S�+MKXg:DnU*ЀG^"K�;(Tb쵭m } 9PGA 9]*gzi;c8Q7]>ӬNSqiJT)@)@V7O%?HYNc-!_Sе^i ޚ7U囅c|Vǣd>nYao Pu2,RJ~7�O_Cp}[/ۿ+kݏt;R cM-,{en U u+1�gm[k�ߙ}@>� nL�jUCپIߕ}M<V 4Vcu{}n^ZTK9Yx, UgBSVQˠfGl%E̅G;HNS�.jJLf>{\qύ0) з+ې@)JP)JP)JP)JP|'fGm}` ]=w,X$(, $2p;+b@ҙ۳ܥƭb糼r>͔n-qУMu(CH=ed1=N"c-1H,1%b8@UDE�*���Z_5\lw}{rwsIw}{ӷL4_Q۪€*JM4v<x ̓LTo-h?"8nzV` TsV?L6<NoKeDIK@UeI VDSct)J)JEs20(yYmg� We e<T�x[2ً}#u k0CM'i 4%_p}[c-28/q%ŽݴHete$2A{kY� l: --:- g- ŕKo,i'% DN-X`2JZKgpV1ȥ[>G}ꭨw_cpՄV$bXW@P<T*_Ho/[3q^y*w^={-=8ή:/|^!l@r9J .eC,o<rrBO)ztbȟh} :`>ƪ:O5]\O)E#sqolI;t'# -=�_N[Ãzǫ]e\Cn=[KLXy$,BVe<S}#`Krb q.:o­TrqϧfS/fwx�^r-nn.d/tgo yLwQ69a_1B}@_7꘭uZ uH0 VWRXVRH@5O8{`#Fln37vf 4U^2/蠩jb;m%\\Lx+ \m7VMk57!-сcfXeI}2<ſua�?j ee�(8(oz,>esm[}i2Y [Qky@��`*W5w`39_!b W "dx/ی]ԎTUG>3h{lիsX2\l&2J>߈lԫ�A 5SzUۓ=_O F]![99!'C:1 dOG~G~[ͫʛ}hEĮn?,{+ubTr�`6Os"zy{%HD.-ѸCFՃ_NY(2fV}W' paʫLF^]#)eVؐsr?*{s=={6G0qk ʱ bY,tVT\8,e8cmcbLZݶҸT<OU}c�3mv+63G$OmnJh%#hټ=Ç#gy 2+Dxt!~jAX}2dPn�V޵5QK)J0E츋5}]KצK<xS8<EmmdKhe_R9.YMi9~b?\D$Nget^ HS#[|F6{M3_ֲ.џ'⣈\\Fў9Ub)u~hU iAa--c j"(T���p�ix�c;ޟKޝ?^fyW^VzW \(diX*"f'�=55PZo6Iy8>.;nᑈ<� R R;߱pdaQqn < WRyVީ�e>G&%e3J4aBNDAi%K}:/)gZdqp_K{iM�He  j�@tZ[u[$Z+u<XOcKAcD6@)@)@)Aߎ6~Ք3~0C<S!*;�݀GӪ/fֱ~)7GVȎ"ʬ0S};\c5 !O9$A,6[{akodB)3.+;BbY ^v>6޳&s;$29%Xԏc^Vn &{m^bI? SLi1=jn5}'L-1v=qk4x#<O�>:1?dW<!\wאjX(1WV>:K DhFIX}ϨϬ^5f<ϩlKa^k/V4E[=v}-8bf_E$j:1,@(I*A5?T|n"teʁq7e1Y/ _"eByD++#P&87˞G'yf>2m-ㅤnGRTb.OYO=fx/.v, 0^^VTUrʡ�<X:^g[܌Avc9.2)hؔb *I< Q3"?34FRiJU7qo!G{&-pv䲋 3*DhB&�'i6'v!,r%6;iJ.y rǫ=Gtn�~V_Al/?f/x92wdu@JƊ f?T{OF<':7?n:ѻ u>΍xO۫NcGtn�~O=wөAQ?Si�GPf?T{OF<':7?n:ѻ u>΍xO۫NcGtn�~O=wөAQ?Si�GPf?T{OF<':7?n:ѻ u>΍xO۫NcItn�~TM\3qyț_[3OoC d%$ >kuu] qY|m3uIzr Z֭0&1fYܒ(h ۼ/]gȻ>w8K-Yv/\]Einqqkkqo$љdukX sMIPHHhGUtdeVR)>ŝծ1' -Ͳ!iJ UL{,ۆY矵}~4 " ;2z!>ΆN}}[aggqeqs3Y xe>9Q}S1qJ៧%g~/m+ǘoZԙ볆جG)$%bA!=Myu{̶Ohm Vh׋m 8cc ֹ]GY',96s6o#sZI DI$Ƥ)?1Uۏ_7zF1K䙠$Nn;V ʩLyF3UQ-n!YC^?ܶ{K5޿&7sn7 $ GxQpyN]^fne{oA34QK3$-8S�PM+ >B/0w53mpOGayoz˲W+:GnmXȱ\u@Q@ EϘ{a1m7<bRyN/"qVYKJq1<$1!uJbcgYeymm}w%w3]G*XOI'նH_vk=gObnCY#kLZKbeWAH%IW^gFU(4Є?5>ڎMIr3HHbF dӪ+6 l\e/&N XR4#Uz)J)J)JE캾sa,&㯭aK%8*xeVb*RmAzV0i�丒?n4>}m8lf2\ӯ ج,`Ub0!9RGM/0/nwո5f A�Vw/iEOzf>�  ס߯~<|~B'om\F2S>efopv�F2,B'PM�Z̿V��o�2q&=2P6+#nDz䲶3RHdúÆP@\6Y6<ϱb e%Z;hB  b>�=c禧m;֯5yz`31JÆ@)2Ƒ`{N* i^2C, RUO.Tʃ27M|qܗWWc퐖(Y0Q].W%:77--�#rLWv#b}v R R R R R R R R R R R R u|6煸6YM_Z#nKՃ/dpTʬ9T(3ۖ�`�뛕u�q%i[$i/}uπFp7#$d[_iYdX\8`BrSNcM_)a6_?20zt۫qϩj7ȃ�J^.|J<&}:C^=E={u^xVOߠ۞el}R]� 9#d*XPO _ 9'�5�eLzdlVGݏeelf�Đt=YU mly bk Kv<+>|)�O>zeMOXwY_k[Ya'k<gbˇ 3 GzRd5#]/XTҼd(Y>\�oeoț['25.!,14Q)HaI\%EOѰ:6K2 t3Jnn0Z[F時id,G,((((((((((((((((((((((((((((((urrwPYO^HJ nDhde@G*}VcK�~J :��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������krb5-1.16/src/windows/leash/htmlhelp/Images/Leash_properties_krb_3.jpg������������������������������0000644�0007046�0000145�00000131135�13211554426�025673� 0����������������������������������������������������������������������������������������������������ustar �ghudson�������������������������libuuid�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������JFIF��x�x���C�     �C   �"��������������������������� ���_\qF筵{'D\ydBg%2٬.dk6Fdk6Fdk6Fdk6Fdk6Fdk6Fdk6Fdk6Fdk6Fdk`} 6/}H}uSӜNZBnB�2JMguu7ZCu7ZCu7ZCu7ZCu7ZCy7#y7#y7#y7#y7xX} sTX__Z3 ;�3 ;�3SbʖU/p(dRƫZTIUVVg`vg`vg`1`NB;ӭ5k_s>>^]-03EN̬ڋ`koF*h~\,RVX$lbqgulqeU ZaϪyg[n gӬcڳ cn'֚uzRc\o)ȎCi 4ݿg#^r=~ȗbyJ/=Isɺ,D\V޲Ge-v(^oY:OZfPчQtNKj2{'֚x���������������z�����)#tMZżsjX6I_+z_l"N:!:!:!:i֗^ۨbe݁4g1E&5ak2؂Y:!:!:)#n v僻:Vo<Z{$1زT-Q}\b>ɆUVQZYEieVQZYD./=U&q=`KROkEvn#H)-gtMZż+l5󷱚XHBwkJ]ѧ[� ����AiJ?mι?Dsx,ɦ-Ⱥke�����#dH)-gtMZż[ kjR%˿mK.C/VBM܂��AiXԕ3gų=ôE}kː@����6J4y`Nխ<[ 5KƦb&p6c ZyIޒS4ⁱ12���村Qk؄ �����QLv:ui LZ͛6!!3jY95|]~�����Ai٭q\`��������FF0SZ,֚x(|j JZ_/7Rٙc]'sV@����OsNk:��������6J4y`Nխ<[?^ƲhK/q3#c(2vZԈU*e��� 4ָӮ0 ��������#dH)-gtMZż2jZիfy*Bް@J#5{ՋfĨo-A:N:YlCDlӳZW$idI$I$I$I$I$J5PSZwcZj֞-sl_=�z<zz����OsNp2LFQ&Y>/z6;rݎiZx=ͳ@�������� 4 3ɿ7>Fy(`8I!7Y4Dkx)#tMZżmJ��������`X<=TB Tnծ03 &g0=X<�9`Nխ<[Ġ��������z{v=ߖN{ռU 4ۖn֦,}#e75$ߐ~ v:ui|6%���������Ӱ,+!@���)#tMZżmJ��������`E*��������� `X;ӭ5kO{繶q(��������杊ڭeKC׸w#Y7l]<qZԿ|UZa@���SG,֚x=8��������OsN���������v:ui Qvg`vg`vg`���������� v僻:Vo� r|O^\/.wt3z#rRU>mN -QqАRyzkdN+d�����������v:ui�VPW˭OV :H$肈NgEjNH������������ `X;ӭ5m=ʠNNNNNNNNNNNNNNN3wcX.=@�����YE&/I4bYBY+oW_1̎h)fx%0Fv t-rӬU �����Q LdIf@ҫCCgG)sk} "I|˛0Bb[I:iS';_5:I|}����������������������C O�0�������4215@#0 P!C"36%��HNp8a0G #p8a0G #p8a0G #p8a0G #p8a0G #p8a0G #p8a0G #C0:-1(1Fj,&9%:LZdVU i&UxI6l4iW 1e9l $~ϡ"d@ d 2@ d 2@ d 2@ d 2@ d 2@9茆09U5ew2-9S6wo<4z{&kjY⊰]{j-7PbZNHh֋X"!!!1B9TEBK^ Iƾw \ \ \ \ \\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \i5{i BΞBqJddddddddddddddddddddddddddddddddddddddddddddddddddddddddddLqRyBI[ yʼnYe9@yޔ^P~xc@*m.٩<%Ă784x,g\\N7>p{WP{uwpZĐYţI;dd [F#wVꩠMJrX63urL2L2L2L2L2L j3.L'Iy{Gm_jr[KUՒ8888tiOf5vyjWKQHǣIMe*Ԣ:<3@J,yyT14YNPmiq79M4z2ҫLBۼY[lj};JUII'H*UMϥB2UR[6yjWYC5u<XF*fW&-REJPO  fR5 m,H+VХ]|)vj M< 1騬bϨvuwц\PޤN2I;JA毲8#%'oAg6r)u$ybtsng�F+kFё"J&QJR:x0hŴD0*ؤrа&hmmo`hezxgtT u&ݴRTώ0cYGYGYGYGYGYGYGYGYGYGYGYGYGYGYGYGYGYGYGYGYGYGYGYGYGYGYFe0 Meeeeeeeeeeeed9c&q~w&q~w&Z i&-2j)=sjH4s8�ZN7Nq>%k&H2*2MibRoJ5ӣrfM-4c~w&RJ,#d΋f ZPQDnZA =-w oFoFoFoFoFoFoFoFoBgjnѵP:oQ^QbBF0P0U<ZI+u7;111111O".L'_p֖1W :QS ^RK?viO83-)ի_m^]7Vrj; &$\igή )ru7tG*}~"/q I^%-DOk&mjɭIoNYZduAٔ\ \ \ \ \ \ \ 1* s![u2P(Ĉ�A-wIVV,˨di}"/q$4dc[J?]QZB:tgfQΛU3-DbXm%EmS !%1yP|T|ePIHe2u~ :Uii22k\$?{qra84<avSuCLDiIcʐh˸*\Kn,uH+,\LX<$“qȍsmT^IU p+ڴQ6Ϩ*E\N2g*Ž]Mo-(Da*QrXGvX#"X?vmRhSť>0h9^vdӷ]2tԍm ,{}i {}ċ6^"/q3˯SGfJ$VQ7g:9;ls9D6v ] *LUI/G�טtꬖqu(*>zK1.k >=LYٽJ}I{Ϥ'ܕT^<D_Ʉ+#Phjg(+d_1Ȃp%J7sR2<bch)5V:kx6HǷn{tIJ)o1:j[U"lHv!5lcLF{yooE\N2mVRWo-FnU]QnXH|-ߤUMjԩG}"/qnQv[)K"iը)Vq"r^\$IIטoE\N2-F! wsDFB:8Hc:R SQXb S:-x; WU.<ҬWk�zǬ52I%癋Dyn(JyO<D_Ʉ+#&Ic^H.5NЪkǵrWjڢПAטoE\N2Y H1UhUk#4UUG}"/q pMurF^Al˸*|Ueb3+4ڊ>xfN÷]FhtZGvaZCȮW-x; WDGiB9p8-$bIl;!Ƀ8$k'$2K/bٲiF,ܮ95NG<UYI4vz?ldyO<D_Ʉ+ s42I2N.AZGks2[5Ss Y$X檎vkȼUպrU 7DxRudj&@ZhfUz: F(5 eYAPk(5 eYAPk(5 eYAPk(5 -E ".L'_qm?u.L'_qm?uprj9W'53(8qTWG08888Ԟԟ<<8:~w&:OiΥ5":e'E*42M\'z<-NzP2} 5:iJ*LH&b?X; W[yR݊7bأv(݊7bأv(݊$j-.JnFQnFQDV~w&:~w&:1;blPm AjY*bҽeeeee W <"Sњ"U2쿄_Ʉ+-N�}rfeu+ ĸ ,9/ZV0`fHO~w&:d*wWX1)Uqv]\55mơ:\!`TVq;goDq~w&:=;v(vPء۱Cbv #4cA4cA4c@dD/q^z/q^z/q^~d2\.L'_qm?u")׳7ʣppAw)SEI2~]d]$ZMmЀxg.Xu$8ճq~w&:O55F!T-"XѵX6㚿H2lLɐqOFj8s<{U k~<~w&:~w&:~w&-33333333333333333333333333 z\N2�\N2�k#JV,j}Z n:PfJ/Lњ3DÓvNʺy4f. FCqra8� 9m鴼�)߉?Hfҍ8#A+n G4֢ݢ)gRZA6WUgCqra8� r5Z@" [1-,vzm11&YgCqra8�a_Ʉ+_Ʉ.Lc&1Ɍd2c1Lc&1Ɍd2c1Lc&1Ɍd2c1Lc&1Ɍd2c1Lc&1Ɍd2c1Lc&1Ɍd2c1Lc&1Ɍd2c1Lc&1n[ +8"i!i!i!i!$cYc?cQ4`]7]~1~15xLc?c?jR{ ~G{+4ʓoK�:un&o'Όo!%FYK �Y\jeFM0o,@jb+ڭ@jo!9E5:{<fP7U222HluTHz|r�i5lǬ_Ʉ}Iv|XcgŎϋ;>,V͉5J'4#A4#A4#A4#A4D4#A4#A4#A4#A47#T     l&d$!;aKXwøİ%q,;aKXwøİ%q,;aKXwøİ%q,;aKXwøİ%q,;aKXwøİ%q,;aKXwøİ%q,;aKXwøİ%q,;aKXwø��+����������!01@A Q`Paqp�?n6OEbd?GDjVjk-;onCjС}œ3!砕-O1(P{Tq�hPZ(PB G(QRWM1'*EgF*\P`d5# -EZQ4I@YVt_Kf׶`wX;Oe�-��������!10@A QaqB�? DiDŋ,Xbŋ,Xbŋ,|OS[Ljl P Z 9e˗.\r˗.\r˗.|JjWvSWDK5Ƹz$]kN }=fEg:MrYVNvӼ<,yVYѻ2TIBjĒDQ(J]dgqy̝ح?zpU_ٟ>ɛn{矹Y*=m>v;'}kYo;pdbϞ[϶t%G;S߉t%CpU~?x3n͎1f>.d|ˠY2)VG̵IY2:pU.d|ˠY2 羬Y2)Vt   gҔ\w:cYVzpU_5b/ӂڍڍڍڍڍڍڍڍڍڍڍڍڍڍڍڴ�R� ���!12A"3Qaq#45@rtBR b$0PCDsSc%��?mɬ%acda<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<2m).(g6*zDPs<yAа>9�27L.'#GpJJPhR3UWqЅN2L.a s9Br(L─r4&:,)Qn ,&_-Mq͞*.w&T@7u)6\Մ֯VڒHGpJJPh@GZuĢkכ8N [&F:*�k|(@4k3N^1V"BX K9T5lf%O IDɥs A8-2w.QMRڟZTt 6&hȥ%4cS牶[əYRUE)QMyO7/,KniwkŌJRMk3_#h aO}S t+vsG;Jg~8[.%%hem4]j'G gJ FV뻆iHg#Q?,#j[FP`BniyWҚ)|?s E(7祣4%HrAG+qe2 91B�>fmcm٧4%Dz4%Dz4%Dz4%Dz4%Dz4%Dz4%Dz4%Dz4%Dz4%Dz0nX{#B_{#B_{#B_{#B_{#B_{#B_{#B_{#B_{#B_{#B_{#B_{#B_{#B_{#B_{#B_{#B_{#B_{#B_{#B_{#B_{#B_{#B_{#B_{#B_{#B_{#B_{#B_{#B_{#B_{#B_{#B_{#B_{#B_{#B_{#B_{#B_{#B_{#B_{#B_{#B_{#B_{#B_{#B_{#B_{#B_{#B_{#B_{#+1),3]P)~K%%՚m\Xy;M8AoDaƭljƭljƭljƭljƭljƭljƭljƭljƭljƭljƭljƭljƭljƭljƭT*I=֮#}R zލ.KeY4B|N%) ңN.RSRA%Jea&iC eh-QjCU(DF$aYi6dMw4U8|aA=l7>"avzڈ)Hq@P)Lx1q]\O5HVG ! UvҪ$ߟԻj)8 ҄Zq›lEIRTb[V8 1ǂ *Ѕ}Pį$ETdB2ܚZuت(M%6V@P;k:ZPx5B16ofѢކ[ * 4)ʷUc^EHׁCI\[EJ#ߎa ܴ7|<pl%eMɺqֲf? M7jª Q'?Eͨw%5p,gPH\ӎ5-4*m-!#0^scͯvB)55`#.՛RV4)RX-QBND .L�Vն5m[cVնnIGz%' r/\FEF% idԥI-ЁJ.8RPO%J q!Br1I*m!G^u�* Ҵ o(А9FiFiJI)͍AZs !cSON P)8F"^I+) 8q44O* E!EbFp?(RR ӄ$%^MRnp+A!yx ) qEIUiXӍ(]MpF54CfM& ]UNCbed[ Ͼ]^D6)qJv| LL,gXn$!W]m2Ƈ 1IU6ږkJpYpTo|qv4f[tBO5[!IuN6R %L'\ (b["JҰ<eR,**$ iv奛Gasyo1..i*H"jdu>ȧl()x&25QU/LK.l[4 \9_bK >Ɯܪ\F=:1uJm$t5ȾpyֆJjI6 Zݏޑxsg)$G\�pSW 0XEs%sZ:@5~8}I0ۭ%!Mw x=:eN�>72TqEHVJjl0dԥ vyi [t*qE]UsEO0%+@i(RJM6xVJI..YW'Kèw*Ir0yZåKݤ]3 a8. UC@V*hP)~KEcOBPe6ҕo0*)Z6IY8bm8J$:@,.4 2Q6dҌ[¡gJa >PQLb`,@ pH93UļMڛIT4W/*a./fZݯ\fAmxtp{%R)U5"UBR% ɱ N"QuZW[*֯E¢k%[F5`o0ܴG¿KJ7QUO m+"iD SNREeV΋:!AKd[l!#K0K%Kiںc(݉6<8M7 jÔ)q!TtISypTBǂW%!*.i&ns8ԚKPqQ?|KysK)êU˔˭!&SZ^ȮRQOx,eoP: Vם5#B2\ɗAM�v&<C:Z^F׷B n}82LSǍ̘5+4!a]Jid:B"�?8QPq6H땧\g Zlɽ8LJe%OMᇪ `޼Si))PabW~P"oD%6\ocloclocloclocloclocloclocloclocloclocloclocloclocloclocloclocloclocloclocloclocl$ i) 6666666666666IlP)km9BF!ETO?'}5Ⱦpy G֮#}R!>L&a3@V:K6>HB"aU,Ed+pHUSq|f[l($fGE.֧4(jsfis&TJEEFc >ZQSTU$T<dIJ2iUR�ƙZ'8Q2ޓ2Nd7ǎSjU耓u~q^Hܙq'ek]λ}ٳ&Y"]%#)AAz٭;\Å*AB}+Qa"aU,Bؙ,ۺ+M34#;e1qjtVp\\m ʒP*Ui)4c +dғvk_q-m2<u eƜQQHDSf@V:K6>HL'6RJhGIZ-K+^^;!ETO;!khI兩,ܢ<&^۫ZB}|n" `OO2 [)fɄi1ƗN5焰K(5KehR(2�RY#;H<1))LyJcSRǔ<1))LyJcSRǔ<1)8BfɘoEN"<V-R1P0["TB֟JnRx[,4J(rX.4Cb.X[ XK3 JQ*C RDcw%2 6%?Sv]V  t`exq-G OaY|yBcPǔ&<1 (LyBcPǔ& UNAk}j7"r`D^iqBNL$U�szJ=fe�˱}Ik1> )ETBA4]8$QRNؕT`ψ `.1uԴBTI㇐ffk)ClUsiDŽaN'--(&0.xM>^1ޟ(R,f *u֐rAjmn;xSeNZ/�䆲BIR[ƆV8\rR3ObYf$Gf*n. �(**+}-'2򒼝 USaJւ[_xʄ^ ͅn"_>ܣJ|eV k]!$Y] wC\WTw~evPмS[ѕnYZ$ٵ2ԁrԺ$ gM3*ue0RfqF9ip!+uOL -s:sɞ}}ғi*YZ $"fɖEh@sqAcTiJ6¬ܴK(k\p&JYER[JԚ{Qf ݉m1m1m1m1m1m1m0t侻.1m~]H*ɩsT!TUeh LL0mqMUZiNjgai+RjF"x:ol Pm !NL,od eN[CJ(Z#+SHk8W5y\M  S+yه.⚨ӈ C}5Ⱦpy G{JKrˌ% +§V&,J}[(os$ӉqhCju ļqs#{Pݛ5E}myJik6#SUa٥2gw(-YU� )fQ&%4\>ݑ MH6M .i5M2 !)kKU3߮R39&Jm9pU"ժdRAIy;)ݟ>{&Gۋd*ijpמ%*K2[ (<x�|=Bڕop'Pʗ<4XW+I1e)JQk]x-0*ێ'wD 2j�DJuU&ӊzQ(NiR+&�6Wt HH44IR7T/ !+;iZBYJD&KP ViܕUuM,QU80i֜zA)tB4vbet6\vz֮#}R!>H]>r1QC ܫfp[kzI+Mp)ifЩSNLdgR^MfeL'*I9id6ª( 1&ˍr'(IR M R&7apBNC&EkaNxhM&Y/!ۍiZ+ 8+*nJ|Csv"ѨB2(e)z'}ޞ]ܩv v*S�Xa̱U,֧m7|0-6R(x><]]NE ʦ.XnSL~zi\8ڷ�1,Y ֗BCh~aV*䆥rTNQ9QVŤԈ( IX)>;!ETO;vU-8qVtp !%&SgeQZ�6ܐKw8!%)7*O% bVq> ̫rSKKI\k#,R#r8!Wms3t<nHx4e*J"rQ)kyJq59]Za %2),mN bU 2dS4^uc1'50Ē/PکqirTK@I8H*iLع$g*aÖjHJQ5CD0hETUNf4 ˺/BhV77BE*QAlmib]}UXï(2.,V!dpCs�n *SBJ ӈ �h]1 <KzUSbbfm V % WB"oD'B[eAYBE*1!$wFU 6Rg$_hav"pq͘Bl8f]E$*bY>Z"a^*ah'9O|rHVAi% QQ݊DW$%Q;(''51QMX}䊖m0<:I#3MVgZTĢUj[ɥn8ڕR=ZRuVrY^iYJe7q$QOIN̈́*HՄbW6k(Z|UJR*@P`TLV(iCO?|=nZ@rV:KaDQs $[LMU91)v$=aKʎJ([+!p&!jtSAj tNzEmD o~ڥ$2ׂKE+svSu5yW6z%M݉R3vx,(T]i Ryʏs(J94J�Z=!0w r+`*8a{)m ^B"oD'&krs$P%AUVe F(yg([iJV�>xjnXTpTJ@PKy7զq4U1[b]&a$SJl_.Zm*SaZ͜*腩J}ºWsEֺKǖ޴)\rh;uHZgM%ؚ[ I8ۣZDž9 ƪZ&q$PC)q#<"Қk)ppZqmn9kL@mZ$OE^R NzP^J2Jl%w$A(x!HJKPj JcI> L!\[sV> Xe%Tp}JQJ+'1Kw% jO+l:_Эhqq!NI(1;C,�88f'Ч}5Ⱦpy G{#w$Wv\ekeMSJ\(sđY(DzZ[(V:*K3wG"ȊpfVuSl-e*I8P Ϛ'KSJ3tq ͮKS(}gYn[$]\@0dܵ%YfVݛ7LR)PRÎ퉴Rl6CĬ�]~֨Li.Or1"eSlEkEN!V7 =#t3k2f2vV螙hC\JM-Hql֮#}R!>IJJdUIRRJ ɘ:9=  q'|쌐u.9j wc>| S/4( gvQ%ٌ4Rh0_ o&S*S- =(]X?uX>” E'(E xSTN!(S*GrAwcddr"kU^_t}V?M"oD'IwE^ A8eսy/]!YZ%kN3IE"JjB'N%%Ы` ^aʸ + 6G?6ӯ!E,[ZX(r[tUpY\ ٴ?,zI,U@5^/|Al֮#}R!>wbn.xD>#!&R24B@[EVw9d%e[qR\Ƕ'HbEuO{?ExLwYG,pVmg5N)ϥ~XyY%+&O;-4(,עP.4brUK,L#1k<f]pf 7&ZDRewol rS|=~~;!ETO;jS xhY°ˈKu*Q Ҁԕ,�'q)nc{]{XQ ApICNwMmm )Bm?ru$džEn 其NUh(IK(JZN'8u.P-�0Om4wGkh?! r/\FB}Qޗh˖8&"M?7kN . P)BqYRĔLKXU+rkN5(Ҥ/$*PIO�pX׃ zgqѿ|=~~;!ETO;ҥ:eWq^Sr tbESe⋲-D(RتlK/0(jwW&m'q%dS@مI2ӓXRZg%/BTAp)UAj8)JpBHqFPTZ֩H e閜Tn ^,*A&hJڛ4:#*rv2W[ԙq%M҃Q LK=8X &[a8@AfArhJJC=�Y;4eE0ns{a-TՎ[m8#!NK&܊iO_t}V?M"oD'V㒏\IiBtk;"Y~8…[Sg(j"ZihԣÕ4Y2d&|<x3Ĵ3EnN/K(-իATင"Xh[-fpZf= VRMi_Xʛ쥗ۭ覺XTkߕRRIKiMiɞ2DQ*XiԖ^=Y̿:Jf/9GR�]ȜHZY6Ԋf_b] . # f[mذ7y$sscsu7@R+j[CLmµLԔDZn9bmXra֘ᵥPV 9o&Rɱ?,m•+0RhKK TfTst8&ymi tL4Zpڅ(;�t}V?M"oD'IW.*O H[[3�!?;3\bAΤQWo4s mËX&YJfi)w:�}kw>JdWOs5mKzs!dڙqsrNԒuݰ>щU) v] sSLVJ˸їnj̧C{Pَp!/<կOU9c奦<r:aמ&.A^$ td{ ̂D҂vk*Q+uxu&&$mLdS>boZYZ6(�Eku%vqųLdMH&(r.p$_%,,bI15bRd!(BgehVz qf6ꥵ�<b^돎;)RVQ-�EZ iw5 h3KaL.QG�zTSH#?H#?H#?H#?H#?H#?H#Ak}j7"^�Ak}j7"^�,FiAFTEB#HEƢ4iݝF@(PƑ#F4qn5cHHQ֮#}R!>5/K�^Vl�Q*8Ӌ V'ź9j+(r5g×lRH\+�H)\QϤPLUX{(FD=iWݜNs\Т2QMAN;aZ$ AD$ :<BW\k#m>1Un WysBR*6vB7.V=ɯ? U8~;?wC\WTwϥJ)ZM<k1] &Ly4BcɦM5ИiǓMt&<k0HC {ꤼϑ1] &Ly4BcɦM5ИiǓMt&<k1] -TC֮#}R!>5/K|֮#}R!>5/K�Ý՜<Uf"r<=ǝg3uγN TNh+m:mmmmmmr+W1DxWܢ�qh?! r/\FB}Qk_>.#_D�-@+6S>!ǷQMKĭX�JTuí.]hIּ}{o^&-BEh(΁)8xk4#ݣ1nM_�}u~3^K 6NX}-:^iQC]˜7GwC\WTwϥT*#q֜+ wBPVt9ujf)PRBx9#Qf7BDV$F֭cVhNnj>9ƒ8@ԢNуe1 xPS„yJc W?;!ETO;zg�|?N=N=N=N=N=N=i@�ǒшVz1JF#Yy+=%g$jH�RwC\WTwϥ}>wC\WTwϥ}>wC\WTwϥ{/:N8Zi#}5Ⱦpy GyY_Ĝ>ܵ2t/)‹%eQ_yO4BSm#uTVcT-jT @lJe@ek ,x,aLJ $)4¨~ZQTgS%8DʹAuTxJ$Ҵ. Na[J(T$qrC,˩Ԥ)·T0 @i Ux^> P-%y7P_6 l7yĕfz~2 Ih?! r/\FB}Qk_>RݮAJRNpe 5-dŵv!v qB|&YsePHJMR-%J0j� HPЈ%V^&6$ uKqn;w4X$%+u$Ҽ0,6_H8R.�\J9: Hl#6 5Mp֮#}R!>5/K|֮#}R!>5/K|֮#}R!>�(�Hղ5l[#Vղ5l[#Vղ5l[#Vղ5l[#Vղ5l[#Vղ5l[#Vղ5l}>wC\WTNAk}j7"BnZ/aE&ԃ%>�\=G}P)kD̪TI4d̫ mqII@A4S4S4S&!V ~^^RXKmX&NNNu@$F%UI<S~B_Z<HX~c$Ōm*R@&pdfNS>*m-L)KΑ02%F~V$="seу͕WK"]CL%-]^Ta'^qSsr,@B3f23wrYG>%`y1a--0-.:HRg[)Uh Wgiy1u<bo-K.o7$ O 2Î%n<n0w1V eht+`dj1--o9kaVVǘ|W~_S~B_Z<HP󪱦Z(((yL *DH-iV>(LyBcPT0\uAHĘǔ&<1 (L80"W~_S~B_Z<HwC\WTNAk}j7"Mf(2vF9]+Wdh2vF9]+Wdh2vF9]+Wdh2vF9]+Wdh2vF9]+Wdh2vF9]+Wdh2vF9]+Wdh2vF9]+Wdh2vF9]+Wdh2vF9]+Wdh2vF9]+Wdh2vF9]+Wdh2vF9]+Wdh2vF9]+Wdh2vF9]+Wd<^pp!ETEf]m(+q` v<)p_ݏ8JFǜ%?Wcѫ OjyS5vW>ǂ(WߔX̭[c2em3+lfVZQVuRM82em3+lfV̭[c2tja7[c2em3+lfV̭[bg ݰl"oG#Թ q[ipI9!ǐ5�#^RM4֫O'}l8i-ԒqT7+gZ=U\ -jrQ(˶KHVim$k2[RE1PNqAD9{1%#)<p$fNh2l̢z1!&\(ZsvUlAup=e# !̧"F'K(D],A׬Ľ^rm-VTSwC\WܒM�V?#~o|ߛBK MPJ FM4V<KM87ѿ7ΉMG'}*p,-8␮JTRm)(͹[7N'"\ne:PP{1%#բCCHen+JRH9!WD:S\2RPTnuD=e# n֐/ل�oUf["Z$hN�wC\WPVE˿ԹF.}QKTo.�R˿ԹF.}QKTo.�R 3}PPs4+4+4+4+4+4+4+4+4+IP4h+Wlh+Wlh+Wlh+Wlh+Wlh+Wlh+Wlh+Wlh+Wl@RNcA]"cA]"cA]"cA]"cA]"cA]"cA]"cA]"` 5ȾpQHMBMh)Q߮7;:g~އLz3\oCwtq߮7;:g~އLz3\oCwtq߮7;:g~އLz3\oCwtq߮7;:g~އLz3\oCwtq߮7;:g~އLz3\oCwtq߮7;:g~އLz3\oCwtq߮7;:g~އLz3\oCwtq߮7;:g~އL R݉W|�*��������!1AQaq @0P��?!32EkWu]׺uw^{Wu]׺uw^{Wu]׺uw^{Wu]׺uw^{Wu]׺uw^{Wu]׺uw^{Wu]׺uw^{Wu G›a:xvQUDnUJhϋQD&vP QIO5F/XL$[ACl :Af@"AlWYN  j`0gX�Ⱥ- #'^mlo  JJJJJJJJJJJJJJJJJJJJJy~ .s*Kn9K^3%9 3EmV�i*܎TȦn"8-"ZMPږ{3h2b\ҧ(6Իɽdfr+d%G"".ȋ*r"@55Lf#H9̨B@cRx� /:K4-n5 ?|떹kk++++++++++++++++++*э7Zbbm4ہ)\+09ePIb]�6ݳf͛6l٦,d�6lٳf͛7nݻv۷nݻv۷nݻv۷nݻv۷nݻv,=8>e@j IiG#C\>p5\>p5\>p5\>p5\>p5\>p5\>p5\>p5\>p5\>p5\>p5\>p5\>p5\>p5\>p4�Cc])]C</4gˆ'VɲQ20%qZl!V>&̥a*/ �aM&JG6#Z~+<Z iIVP�%<uG{Zh2ȋ8IM,u䐟zN(2L:5|8 ̈́ȹPpɓ_;Wm;abHI / 5*6QjhE5@gΕg5d1k#t'CyCI)))vFy2֮k|D ܫ@W s},-iۼ�*FZ;yYjPXP0Y,R$pI@nx #i`9 37W\>p5\>�J$O;Wm; +8FID;)& b,&$>!P4hQ̅fhphpyE\]qkJRd&e-)8D$Dm$ĔrW֑;a@$H@Y5u lXp~7�M.+Sp鈲�n8sƃY%^H_fε ʖSV; m0%# ͑?c؂ -;ٱ;@FL59Ph7, (3d"F0%`+2%41 7@bhDߖ[.@Sdt KM~IΆljr \&vaK" [Mn!9Lޕu&gdRxmLL\`wjȳ08δ> HXoi֐k:캰8ޭfQ>1㿑U /˥A+p,&ₙ2irBLˢ!b#vъj42PڹCqI$!`S zv%Եwe:Q]0,\LRL�)Aj%,f쀈-d9tWW,�mИ$MWP|mgd?C+ xzP{7I[NeF. ^ I1*Ck81YwU_t&aQ>J]0/ ^ i8fy,vE R܊Ei/a$tw\J'$ڠ(nȱyAoԡk|'υ[ 66 dapKVѰ)PD3kG`óu4-E㩄_VP,c qOBVs6֡j(dT QnBLeHT) A3zlJ( |:6*@OfQ"CZ2ـIiiU:�%84ŨL Ya/@+2�cq]ETfƴW\(KUM&Xl8Q6Wm<T3r|q_8W+|q_8W+|q_8W+|,ثd4sW+|q_8W+R]F1d|c߫?p&~J?pMT Յ]lh \)I{*<r-%H."sb֬%sKzo6/K)RF]]Qgʫz2`ĥr"g{j%. v. ٔfٰmՌm,5͉;)rf͉@z@nn (z+S/D 8HHz)NBhҡ1wP $D>9F/[ ֌0) i;Nq+lՏm2,Y>8A"ޅl hFcM\hd#Q3dE{I1Z{@W)`.فF _wwwwwwwwwwwwwwwww%m1IKyQ;k"RإF$t4,f_|�%H{KY J5"IA2&$+u:MO`X,:TFdXkt&vvvvvvvvvvvvv snXmȹ"v3lbm#=` eo2M$֞TmV@1Ӥ&#ґqJ `r (Ѯʟૂ@l: pX%,زޗ/Q0QD2ś@%Abf&7ٖDr6|! ! g* kƳY.k:GoX jjjjjjjjjjjjjjjjV<~᷄) ˅39R),B,ڄZWE$&UBXL- n6H~&y�jMzdF1`~Nħ,zղeeJ@h٩#CD@րԬNL<ʌ* N@B.\Wr~?UܟOw'껓]Wr~?UܟOw'껓P->9�1{p%"جmx7!jE/1Ur[1|3]C/$<Lҽ ,:Z4A{EKT,p!$\]&PіCˆf �8!>jǏ6- iB.; J`\D5>'P)7pZ2ө!pGYiɲ.PA4ѽVNk blѵ.S7-$3�QjzMVkgAg 44;(;?1la0`hjXTB SATw(Nj17$ K{F z&rPHpS2F&}Jp[ zؐFQ RQq : Q\xm09YjǏ6K 2?ENL "([Ve$Nm- 0F%"JU,f`*Dj)մ %Ȅ3.hX--w#u-gwmzxl`EiLjr*Qz3cz[½Aȑ笎5�22Mh}ҊE]H-bdXf؀ 3 qz?p8/j3dLL5 6$Kl׎+s1S%ii&X ̗JpհSL! umruهqrӃ.Q1w'g!Ah2(ݧq# 8kQ'EZ .MWa�yoBu$% #@%ngwg߭d-k @ZEjVrW�axo�  4| .PٍQX P.m[s!L,Zt֐{`AAKdhoRH]a9QTJĮkw)v*uIa)]Y0byS&(3U㍷$?o̭DHD:y>}ILAs%ZJ KpW2e6te ΀+a|y60=$P1. N͔5w[|T(,L%K AXd" jǏ6<b1%KkVH hz/Dd$Pxi!8s]fYjWGD85!fDJcԩ9[5L`8 }tgԐvpJB-8)4R­`1)F ٌ!PF@\,+bгarT]a'dLB^8#$@Id^Q&-VNe˻ODa[8U)VY1WЕP|4Ũ!XM6UYg$ JSe-TYB�~ &(1<j&XXm4r" hpJks$eɛFԩdJ3A@n,mgC&kN(WpÈ )3o\aN~F\OoH%d1 BCu2dsQj}ڲfYqd?'6~ B ]!}t7 �lZ]\-"lƲo6IU xI_aV8f}@ڸ 8 /~jaH~'6~ 3Ho"K È풇``$fڳFhVf, M0h*dFMsbx+H !FS9׆WŢZ ݁h0}OúmP5cxyK^9\#ԁeȠK1AiUgD(TCgOj'dU\T8jЀ +~La 8A~^~'6~ 3pR8 sHdxq<CswBa#&Lfk,"E Rs,yPT@!.t+n`: Z7ah�<'6~ qVd/=@D4?$P`'2bU9f`mzTiڦG@iOúmP5cx=@SAmPXpvVD&%ŝq =n[$2 "'J5,S& [2q- 0C0P]OW4,QN f2% 40-iY0PK<,LO)U<\JIK&BumOxt_nl 4LلH?凓}?MXj~c`8RVV/f$@ ͈11Ij"JiǶKuXn58Pf^qF4ax.b7b5[%�Yk ;](D AK,S/L^($s"0ކLᰛC%r(bIiS1DX,EF; yj%7kamRYE[ ȡσ`&X>U^ә93H`!aMa&/<WtjǏ6u(nRTp]"PrE !4 ޭ.Ɩp ~,*S2j53W 2 2<JCJVξ !`$H+\M@02h$e11d`x$A`~�л3 ,:Dڮ*u(q4h 9gZ+QQPҭB) Z:,0Af @Đ_pqx[.xb/Ůo~uι7:\ߝs{o~uι7:\ߝs{o~uι7:\ߝs{o~uΣD̚F�MXOX6jjj* *+51QQaUmp}_BLBex2q9U!&㊑y0O` _9F> 5Ȑ�)zO� 1ՍC'e&T}X{'w\O-p^X숈Vqe0l?o.iRRD7�'TAhlZ$^W-කL߂Ŋc.V`qR5@ZP^x?6!)7�bpq4P"kɏX*ȁDJ@Ta*#=ǐ_,ѓ2U?�Z O|Q,,c �eYeYdQT[V<~«?pz h�N7>|ɀWX`⯜W+K� @ЦC ug515$X^�Ok˗c}\<WӓækYa ߬i�!0V ī#M^׵>e*}(~!x:e*@M]bW4(aDZDVtlgxH0b7 &hM(!o'k* OR!L7>)0FMLIz !'Q!v:+h$J'ÃOFȀ:PQ'S39,WWvzL|^VڼkiY+ԢSvX{'jիRyWn~?U۟vsXACʢjǏ6޸y>Uc}\<W* Oh4 \_c|&jǏ6޸y>:;.Ŝ0^79^-NVpj@7L İS  mb2pdsAxllb*ݬ u.Tw\|CQ jc&:!5v 7ъF&\uM cX #iLPny* /rгooʝƧLX{'"ʽȯ}fOdM-eEIhIjT&Ŏ:Sf3eӵHd|$bnIzB+GGG pPb,52z'an3MbX{'� xo뇓�V<~᷁vT�\~q5\~q5\~q5\~q5\~q5\~q5\~q4b?Um�~xo$MRY֒e03C9Fyq5URBe\xZ` 5?�O:M*#06sʵ419n%OS:BU �ū?pCA&F(PJQ-&FR-L̦e Z GuĀ] /e Ѩ@ ^x[Y-S/]!jy&3*N{ �̚EdmhyF!7f� zp� ͉s%f)$3&۳-XIFzS3k_=W{=imS/.v=ݮݯj EY.۵v|[_Ӫ_1]gZ lT6* Cc*****<"5XǏ3X5.\r˗.\r˗.\r˗.\r˗.\r˗.\r˗.\r˗.\~C"CPSLXC 0`G$(A(*{T�+ڧ^?WOSjd*�" TSj{T�+ڧ^?WOBJQCڧ^?WOSj{T�+ڔWPI|^*f/st D8o+BQ/21'|n*h&kAndbs V% '0$id V:8ü]e~G[ZtZ%vHkO;á4a+7Dږ*|E n$: Q |g*`+|F#Ath"0رSq!0S98% +50nǧF1 $d$M *LCs3K C�BōlXj[+<%uq"7.T0aBZ3As"Lj;$f�EC/-#q0~T%t-$+CPwV<{Ǯ,_իVZj6 bR%_>|Ͽ@(D>|ϟ^ VLxTU�ϟ>|L 8t$@xRJ*TRJ*TRJ*TRJ*TRJ*TRJ*TRJ*TRJ3�U*� �����#8��������������5$A G,,,  }MW<<2<;m><<BOoDY$l/Q1�KB^9v4M֏;0_�Ͽ��������������_B<<,&V����\o}pyO<<\&'Fv<>$<<\{=<>VN<<][?uje<><t<<\<|<>_<<<]km<<>_<<<]!AϮ<>_<<<]IV ?]><<<\#,1p 0>�4|4\/<<<>�O8xN<\/<<<>�O<l<�\/<<<>�E)E*D_\/<<<>>M|\/<<<>}=�����\/<<<>U���\/<<<>����������^�<<<?����������_�F!T�����������_�� C�����������G<<<<<<<8B[�������>篶sO[������C�0 ##0@1B        �)�� ��������!10AQa q@�?=5i|Zg CBϴb88888j&"a7fwkBXQ�{MaʓazS=k!mz׹<6` �B!D"B!D"B!B$QpcHB-@;50 h!^/2׊|[ (tȪËAUQҐSZ!:ҢoͰ4[s6NHB+.SeD!gހ8!Sx-fFsK˂9I`GK{=;Ǡ )ԾzK?P8dٺ1Գ>p5Ϗ!EN� 7efr hH pS77BGαФb3:WBH?4̺=a fΰ7{yMT? =zk1~F3%/ HF4hނǗ2_wBn_ouHVfnJFo%vDu}1ƕs =% g] xt _h}h &2\>'hgX-iwajf[Do`, 845J.2 $nUzk/nf�?WP{gTe"˦yVlʇ9i}JwL~{ͧ㞿?CA^9c�θBS+ιP"i 7;#`$fm_ѝ#x-USvֲo?aj6nf0iസhKnU�Uh�9,:ۡ0iwHIWNA?x"OtG8yc_ uUo|&0io�%Kw #4=zP>6<mB ZkWm?Λ"Zj smféOngpн 9L A?oUZ3x-:fpFo7ih4Ar_PX"릮>#x{Vۙ.�;0{c[෰hVk y6ԨMbrs 7F[m 'g H3 #gm!SzuGEc{3~ơG3c1f3c1f3c1f3c1ϧ�)��������!1QAaq0@ �?L ' n[fӑg;;<= :pi>mwOq=twOq=twOq=twOq=twOq=tѝ%]0"@1k;pY@} D?wS$LDchA #)@iOChF%-Aj PZ-Aj PZ)XUt6IRJ*TR!S K8Მg|34*TRJ*TPU .RDgR˩!$(@<n99 3A!a{w"nvDM ;S;}$ۗEDRChf^s=沄<U@P)ȥj}&ÉT/`/;H M.�eIr-N0o=!]C& EЂH# h&M.�6n_ @> .7oQS*~UbA`3?3֨˟2 ͓fP e ` p' p' ׺Gm16nPm݈ vV&qJ@]p' pCp*Y XE2ER{ݩM7f@ru џ? ,ƿ蕜rY9g!E,F~B7#Wٻމ7wnbT>c( Mok b#xFQP?s:9 ;?yu @M>?82 fK:q!A9bT> q"t �T@UlYCA aj}"%=q>H,71]3Ob}"&jǒNMO16@_=v0qH@s"|4@tL/]BvL$tͅP_Kjrk%'J011z U-9̆>[SDEPj]^Mduv Aw!94kq�<BZ❉7 NA ]j _06o5 \B*@~J֙۠_, LŹd -v?;��5UdwG0~M`zb`Ѡ:JcpoOP<�36Ɋ&u7�$K !pXż6:-`}IB3|Pw))))))�UT.J*P|Q8*TST?AP>1Nqt8~͓'NN ͓|CQ=&@p!O~LCC َ1?T 6}�Ը;庰]a@nVq TY  3 ʡ S,d&Y2ɖLe,d&Y2ߠUCq@-�}�88={A6;8U @7z&s~T?TJ)ԩ"|:tӧN:tӧN:tӧN:t�?K٢ <r<qlрSfk{CTW]h@;T@8/ [FLت Jq 4n[LʇpQPD:#5?r&Ӵ3ak?dC( !OBY !d,BY !d,BY !d,BY !d � �*�����!1AQaq P0@��?'vUy7뮺뮺뮺뮺뮺뮺뮺뮺뮺뮺뮺뮺뮺뮣&pJ!l,e.Keq+901 i;V#3`yp/yt׈QHcq5/kP+gd؍f7ЛͲ4K{&U;MʣBF'9j#OG ޞ2sv|gIANgn& ~2L%=CH+x82&E;DzU�%E4J;k/^?k7Iʀ# >>>>+ev~2?]Wg+ev~2?]Wg+ggggggggggggggggggev~0wNBf@ݔsc xg.C GbrrADuiR@Ũr|r5>DD(�irah&* zU؅# 4ܾ 5/dN-l\;Lk! "F}' Ũ TWT*SMږ!)$ 3wV2u&r_V]_/e2_ W+e|2_ W+e|2_ W+e|2_ W+e|2_ W+ᛸNX�4Q(JPMɕȦHld(h)_;j@*hkF6lٳfL@t#Uf͛6lٳf4hѣF4hѣF4hѣF4hѣF4hяaダtgx;?YLCR t0>`Ԁ?랣=Gz9>s|Q=Gz9>s|Q=Gz9>s|Q=Gz9>s|Q=Gz9>s|Q=Gz9>s|Q=Gz9>s|Q=G;�\8,eR&p t\V*}ݤQ9Y9XEB M`R=PU%D r-80 ^BEXq^ Pĥ.l_/Lޤ�2(>͆X5f]yc('@+^yLٲ+ 0i?�R&L2dɓ&L2dɓ&L2d.& J M:Cn55v KZAPV؍*KmBY82)$Ozp64~ kY 1  #I &yHDb!A *Vbem V܁*3{Dq"tMW|Q=Gz3,DM"nɓ&L2dɓ&L*^$0�H X+2fK2p�qrOf%Tt޸p^,'R^ XCD+7Jin�E �6]ӊF n Yi2@s Q]*INAle;GMdH1"(@g; B17ov�*(R⦘ȌY%MRE !vJn.$h.J/Av#PBT7 ȴ pBT1|PI@ "4D RڀW +^040Y�Q@(_θphi}B ahd @cYIK 1"QA�4-)qٹBeTJs|K1PRh�YNiҖ8(yT5P"IeShz3N Ixo?RNe΢p�ŎRBl� wSmȄf"kwN@ol~HlE!BWؽ 4 -i!RO)8j7@qȁzoMP$޲z (N8:| uEH&Y-ZubbQqkJ�S`EB2[ )P)[hǕ 00X�[Uʪ**֡oPW�k)NPdv.7c U 6{TV!W!^ <Q! AulJ ҐxhFdt(ox T(*[+Plآ`&&�d`F��Nlxg I0B8E�=ONPkF7C01GJiۜm&ϴu)'�XՉ Zљ$o � b 2J5_�=1 vM2Ecb \3t0%Fm{8�㚅 uT>E~N,UTS8e,&k٭TD �̠e&Қ1ݬ")Xݥ V �\ #h+Ln4q**pة  pIQ wd* Sݳe-T ײSq!`-E GD/|}LӞ=gzϜ9>s|Y=gzϜ9>s|Y=gzϜ9>s|y=gzϜC"%_ 'jCK p>s|Y=gzϜ9>s|Y!~�ۑnҪ"Qt6H{ҝ�KU�?m;w"R�Ls!mn\7Tt"y<;M��n@z!35p@Qu=U9.J AVјU`�Q7 U c0Ȋ%% ୒DL� 1lPu@2F*ڲфDup7e&ۦ5Ѡ 5"[Hi4"c: 5>b!Q'*~릴Yńt$0P D ZŶR$0P#?<i@tݱzvo;GmvDLGtQN1"yre: @Vo)J FsHBa  uTG|oύ>7g�L3|oύ>7g�L3(ᔩX1z4$IU5s@)H"``i@n- p՝W-CG 82H@SGleŽn!LȰF, eڀG;kxwmIs=ȪB,maϊ_>+\s⿮|Wϊ_>+\a˲C^Oy{qُC:,B�I )Czg%͠ H> 9Q蹊-:|� pFׂ EHKn]SMXՓm@@^)aN D8'筻v2c!v2c!v2c!v2c=u18LI'"sA noc'c$XZ:[Gך>Ŧ#2| ] x"XLƿzj"M+an4uO}'>IϤg~3?O}'>IϤg~3?!?/};1ɢQ�G:Y"Am@^~fz.| KAVLj!g,!2"8r햞5ղ�iNOLB/!PQ(J/ BJlD}u Eu ZY &Sm 4}C` 0` Xu :3,~ *$1QB5xde�{ЌjU %Mu@bЍ).ZU#`H2EF^xi]:�G_y{qُ�s 8*'ukA@z!Ȁhh^�.%`a/8#K8q(PV(-�Q94TP'.eb՚ +&5u{1 QNΈ PJ6ۥ=-?gq80R1;CI*!@e`RB-0nP57�\ڴQ/M\=ՊcLӢ8@dF@|;"5;p6MK'o}ug༯0o&6u&"VfBۭ;B (-"\]UD(Vf+3Ug`<K&.ϸ58&PKQ胀c<o�+1U߂�9zvtv =GF;/,F81�b`aM{)ݝT"vqq )|RJ3jD-@t#a�C_y{qُ:xK5cv7rK�B!!Z)}▊J�!c ۃ^R/q�fAHt@ -mx ox ++ՍFx5O�PP!?(uP]Ib VaP쐀%e]ER&$O[TD�$[N&(tDKbQˬPPz )�<LJ"6Rw2] S�6)I`k$Yfo@tbMIˌx`rJ]Ss:3yb&)� XvqxU#]/v�9DCӦU-*ݶㆊՌS�PWDfn1-Hٔc䠰jGruD;p D\ym`1OXơs`cmMS> KHw!9� )+Y+zN w+z /};1ɓ@SF tyE~8 S[,0޼L6KGrZIRx]V[ >)P1ep6T1V2#0@ 1Xvb#NM٪g)Q+�2K!Ȑ�'.EdB@*0ht]o]WDVUa FVx' ؘ@zmm WCB5t[YސfqJ#T7g@L/{~|+D�pa>*UBB�@6@(1\ JyL(i�C_y{qُ*( 81*+JXgH�L/3 ,E`L%\G" Oi6P6�IRI ֟�n8pvB(CaULxB&f(t``d':x}ugnВhpHSŗnS:J!I]MK8h!>w<{ �(<0\ӣU = lcҝ_ 8eO^vcÚm2U09XHA6\K4#5,R4D&qeՅqRh ;yhiSL $]Fh 8qK>^(y3X ^vcÌ7ꤦ95~xٛrpDHu95Fq,ɬyC8rjLUR<ZIb9ziGH k B%md]R`w1 W:x}ugާceU4YP RA`]\#-�\u `L"@9q%|�A0d@:j`ŨC;{'`4Mx0 BqR@vOlNH;>mSb(Ѱ7@CJu *%nmJݦȅ:9㧇_y{qُpI`xz! (^D:8XD`+Qc\JY%p`4K˶q:Ex Ԝ9i )TJ^"'Mb;JhE9]G|xJ e1pi�IR-hJ'zBHӚPՈ I@mb ȥ$IVO^vcÊ(d DTrij@+/!hJl?@9n"w;* >M{.iB#$u9�`ㅃ4iE/{憆8@G`Up"8':\3j6x`캄"5ALW->�iD< y GŰ@hx)&wB`�TXcZvk5/h X#4CHN0oJ# c,D=㧇_y{qُ%ʤO\";i޹a P X t,IDD S A}cc8#@赼E)B1ZafrxG kQ VQCBgr$Qcg�&oTC5J gLJ4FGD8Juؒnu7+n $h\R[Jz^a l),_)t@ԂKFYL ^H +MpweplКW3F}#>HϤg3F}#>HϤg3F}#>HϤg36D{xpCCY~؇CD�J鿦?h� y�@>!�@v2�E�3&L2dɓL2dɓ&L<LJ Ga|tΈ$TsvCgb Mbo�,DPAU;u30 5NqtUP h61s3331 XX]o$`*ӗYܽ@}��<LJ A%7k~<C֘3\X,":cͶcDKQJ;48aմRw(R�- 엹E8΀]�aÜ*!"hbkzj%ȅC}kMRO#ԍ;jKb݀f+m�lUќ .]2zz`a]3 I>͕6*r17b_<LJ a)VP< �ZSk={_~3gk̡Glg8ʩ(A<{_~3gk={_3"v/};1z{x9 4L\*@*ɷ*FBS|:o/�Y=g"> (bT;�nڵ/gx'% ";9^1Hh})p���<LJ?Z4!FSsf9J�'"rGU"eMbG'{zȷa9':LO�| ƃGE[` b1k^3knJ]Xe}dM-��<8p2 ͗.ĀHRmܨHnSntt^vc ?4s#8HNP# *-Nr$A T@K:c'ĒQ;&“z^˚r=ݙ4@p*â9k/H+nsmBWJή +U Fw⿦WT51pBd$XJN&�09 #�f<?&L2a<nD@*lD$HOP �r;Gc#?y{qُ8^vc'�c} D;bS9 WF:#||AN?@ZND_^vc7&EȢ$\+@�\A.sB, 216Edl Rss�UkYh}Z Wn...]["AՐIDB8AE(4�6vin蝯2R..4W]-h4wY u^vc#Aval'T;Y.HGʅ#ܺ0}RZh%,Qpӱ=Sj jG !&eG.r fNntkI "i%)(fJFe#MkdQ'`� h^vc'�=cgTnF{>3|gq={>3|gq={>3|gq={�[{8-R\k M vϫp 'ʖ(XUWmpVT�DG G={qRX9#(DܓJY0s'r=3JsIUv��j  \p:+ )6nkpzU Р跚3n%/DIn.c^[5rZ% 30G�@:muQ@B]X;Z ^:׿ n9(ٺnEbFfWw"k&")�Qvaj".XL?Ty{qKnnr Z[v)ZV 9_7S 0?y_N٠Ƞ0c@}�P6L_�Op>S�3EJ�*<$Jggggggd$dv2;Gc%dv2;Gcc{/|SG"eVWD$H"D$H"D$H"D$H"D$H"D$H"D$H"D( $ _N|9SĀ�J*TSBQAnk'xPB  9nZs0Du[DT (PA#cv>^+bͥMPB (M3xAnWﭥ1cQQV8F0wm0�C�YifC(FXϻ�aυDM %ٳLzpVQ̣Mw�9@*&{oa]K֤,L,P2\NPA0:)UZ:AA [d(^704R[P@}Bn8y{:=gzϜ^?҉B+呁z}\b,4DB��gY󂰱rfz>s)x fmhC�t WM\.w@\RFI�;;]g?_�r+P �E؉͗BK!A#=({|uW`F)w1H2ns)9W+ `q�ht1�Mŗs)�`-D0YXbŋ'%�#ĜK<*b;6lٳf͕wAa�m�͛6lٳfƀ(+Qqɪ�͛6lٳc&Tw),v?VZjիVZjիVZjիVZjիVZjիVZjիVZjիVZgV.�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������krb5-1.16/src/windows/leash/htmlhelp/Images/issued.png����������������������������������������������0000644�0007046�0000145�00000002237�13211554426�022603� 0����������������������������������������������������������������������������������������������������ustar �ghudson�������������������������libuuid����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������PNG  ��� IHDR���r������&���sRGB����gAMA�� a��� pHYs����+��4IDAThCZkHTA>6hkB%ZBADTX AEEm Q2MJd?DaZZm][6rػg9w|sΙ]bE+= �$Gd( 8i52$~xyhC۾su�V2';[Z-!n9 8?, lIʇOI4GNAN PvἑˠIi^$T>nBOhzIT+ f4EhcRP俅`Ҥ)hr'..5lE>RjuD[| [c=H!KQ 1M-Y=I dddt1ر(}PAr&,VKT͎'9R#b#5v'yF)6Ծ3r+gr2ė;X}9>AKG$&ġ{t|B?1YRk_C+pj4\,I:j<9kW�J}]F>@mp?4"o u(U7C7Y4_>CJTxvgİ昐j<(HAZA|TmaLY창t56K܂W^Utuu?q-f$Gc\dX? d)1;ٔcEDS$wٮ{DA/|8p3G+e7SfØp,2ft$Ju2']$ #ڤ]P0%Y tyͮA3ewpYDvcwmr j;;ayMb~bFʢM=(58}n?ʱ/Zq8<59,Rs0W1YJwLL !HwEȖw^ a&@#:k-pdE";anv>;ٴ-׍ǿH (ý6�2ql}pr!zw{GuX�y|?c v9:/=4�iv HR m|HdHkdH!s4����IENDB`�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������krb5-1.16/src/windows/leash/htmlhelp/Images/Options_Button.PNG��������������������������������������0000644�0007046�0000145�00000010024�13211554426�024126� 0����������������������������������������������������������������������������������������������������ustar �ghudson�������������������������libuuid����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������PNG  ��� IHDR���4���Z���u���sRGB����gAMA�� a��� pHYs����od��IDATx^Zr/\_7ym<XN%EU\2l9%R%HI_�I�|Is3(%UrԹ ѥs/*CpU_87Ǩ|qۇntyT鏮^87 :ꎇW/FMA.@# }$tAD3RA=DEE3L-hZƒfrMP ²_#D5nvz3\@_YƉț{gS bd(ym> wT�tqMgnxv'Cߓ#4A%"t4| C (AҠ=r_}n.ݍ߹W6>8 :Cr"t]\nM\tN]M\}v }IMSg:B6nC7 ZsNPT5ڜw5;{kw m׏P]|dpv\t9DQAA^[j<">8)y$w8( :ŃSW]Ψ%@T5nvk\{AP 'r5A{'W H} (]\a;8^8gK\}j3 4)zw*ܺ}7؈m}q5&.*gt|V "s0=Rο)Q(~niVߒZv+^T‰|ɛw/TÀ"P9f?8  z � ,j <!׃[>8y S :C/=:=K}  ҊCqjoIjJ-~%g׏ԇ un=l`ʦ4d)t)/ "ruIϚ[^Y˵i8#D; h |3|Vtưm3T "ߣ)~~7g6bEex{ΠF0AQ c}FiqEDb 1uL&v 솿{=fA%ȗL).t04Ĭ)tqu7~puևit7vRe}q5mD #D�a| <<wZut ߮ů{M`GvĦ賌AG]dIr_5h 86H;Qc} "lyc~m}9)I$BGA3Hm;DY7\l`  Fj賌-2$lsr{'[{'W}5uL^'ჾ3k#{B f-8#xӋ ‚M6f0&aBl}Jx1bLѭ]IA) #g~;OHFx4D|}q5M1\ƀ" 8bZ>JZHsm56 (6}2NF",@q뮳ndNI")1#I1ΰ�l0 ڢM*h7 ȠHP*?SD)G]-rȨ9;^6lv|qA-!C)P]|(]M|덉ad( 9lߋ(H ڢMڦ|q5,Jo qM{-TciHD .Å X#Q ڒH1A_YƉ4BncMpomceiNpĸ37�?Ĥ`sf}Ԃ c*A4UG48h+M_Ĥ"'H1kB!D1V}u!# m)؄454 EJM#74޷4AbPAM3y>%LXv?G$o_߅ $B)1,v5pNa]|*rZ y!BBT oJ̷k/_ߎ5YOa6K2);@Og^7{ȷW!&ȓ``B󢛮-ГDP 7 {λ1J$oߧޱ6~6Z:ɼW_xIljR1q>efި@4LfAMs*d]TͨP.Ƶ$NܓGH9 jQ_4Y?#y))PQ_V0heFެ37(:9G:5Rn}ZV}I&h 1)qSg#]jдz +T] HY+66>bqf7j̯Cl #<??Qz:|ƚs~q# S,ڲcm 1{ Iv~GO8Aqv1ʷ8" .$o_9 йuV�πdZ0|N7$a l"["8a"g2 <ɷTJk<:jH4dmSJ8$J2Gv3;3Q٬^kVۧ"]NbĻcT$UBf"n4QDSe6!̆(WyA!ץƬIQ9'd)"y~6-"'E 'n-{?R.XҩqJ}p_6yqg;Qvl+e=G1c`'g'>%-]aaaUA$e1!Ik�bQ<XF.'|KIԊD(JV/R,"mb(D vGnN #dv,c1f(sg~/mSc`7^>w)GA.ΘIXHH@,fLTޞU_VT̓?AcvX3xXE&7buɚk),J#4E*nFYSȊzk$M"Z^=DkDh$?IH,jT;Q5*lJp&ij9 %�Z7L$M=׈R/o}NoҚŨda[S*I/ѯ;pM <-'g<%NɂrZXdӪibx4PDQ+t[n@ RFS(hL'.B?ӀHX( 7~QX\(r5I#HvH3/dC|:;F*zLPONҮ\b5܎'kFIH$hSJj<Jj|ah(G8<o Eߜ<dRajG.E%”g yO! J7h Ydx܏oJdїHѯ=kI/^MMlegc$J5iEq>LEPvI7rAѣsxetX}-KWK" riWGn5T!.dvCx\0aj^Q{n NZ Q >Z>zZ({Ҕ ~ wW}ݬVu-t R(u�luH #<Or cG!8Ҍ BF !&/'m( 0 >ME'~etJ.F "s7 >Z26L&*c)5e<RAxH1H6H$/6С,(#HAV'eyN[m;N9-|͊'ץ#DkL$?;W),J8yKTŋv'xgM[d0(V|\V <ۋj%K2y2ڌ#7}wr_h/e|oSƋ?%hw>[j^_+,/�!R~^p4~S/ 7Ǩ|s/*w2?⫇mju����IENDB`������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������krb5-1.16/src/windows/leash/htmlhelp/Images/Kerberos_auth_serv_fig_10.jpg���������������������������0000644�0007046�0000145�00000026003�13211554426�026261� 0����������������������������������������������������������������������������������������������������ustar �ghudson�������������������������libuuid�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������JFIF��x�x���C�     �C   �"������������� �?� ���1!"8RWv#&2AQaqBdt36 $G���������������*���������!1QaqA"� ��?�"" """fw샔P *+u>ida5-MvyGp<U`N_͍ضղ!~8ʌQޥڣffw>yqg19^w,ű<oPK~4RXuMIk$eE\\ H}pY b𓉰GY _\xxFdNTˉ3'f|^.Ƴ~Q_abb21z o >,Hw/3h߫E+(x@[t|o"YmonG5 U0<ZN'RB[qwjy"bbzN&D@DDD@DDD@E# \/Ńxݼnr#C²'`*~ULݙv>vZ{cYͿ k(0IovKrO}܅rf}LUylբRټ -q >7\,ڷTi#*ĘN-'Y)z]!v-͸E11xֽe'ir" """ """ ".{ݛQal~il~h<]֛\EW>;V%)ӿ.?x17G7o}TZrI33T;?lc}ڑ}H[�T=T=E6_yu^.ïԺ}N[3wXq@3TLRL%]j/Ϝ{7H6DvET=XğL�FH"vo9ET=T=@EmƫWN,LU6Nl�pwBgܺ}nNqxj.52siFﻼdU[~}ސꇶ?4ꇶ?5cg3/Z}d~ecM@Ke2Vi%?wļnπH#)#9}s}˞{cZSJjf{c\?�â2DDD@DDE{A,::3/8(+n5]\Z*qbfsg�lS> tsƞKT!piO`?J6'}"b߻nT=T=>~7fuX~} /Ϊn~]w)%xz#I/>n%v|rAH9Y7ߋmӜn�\CbU;UM\u74XuCI" """ """ (ޠA@R]㪈$j@HLM~թLrYl<2bu8Wԟ<{N'TA3bu8Wԟ<{N'TA3bu8Wԟ<{N'TA3bu8Wԟj1['Yqى{ORuUxsrȶ߻9 AvtD@DDD@Q]OqA-F?k-cꀤQUHVc`~R'yeţp?y1h+OƩgţp?y1h+OƩgţp?y1h+OƩgţp?cDŽ!OǑmw'۽LrYl<)Ȉz[~ג[/Iv #;136V1=eOɋG_OR~4bu8WԟSɋG_OR~4bu8WԟSɋG_OR~4bu8WԟSɋG_OR~54ӏ lC)e;f'}>'IWiϦ-ˏ"~O{'ySLrYl<Ꜧ9 AvtD@DDD@S[O :)A-|'}ݝ9 >>Ωcz` wgANDDD@DD1=eOr'ySLrYl<Ꜧ9 AvtD@DDD@S[O :)A-|'}ݝ9 >>Ωcz` wgANDDD@DD1=eOr'ySLrYl<Ꜧ9 AvtD@DDD@S[O :)A-|'}ݝ9 >>Ωcz` wgANDDD@DD1=eOr'ySLrYl<Ꜧ0K`7A�n΂{cN{cA,::hꇶ?4ꇶ?4A-|'}ݝRL%-l�ys�˳"" ""'y9L2"a7vo<ݝ=PP4XuCuC al~il~h3S[O :CK[�t�gAODDD@DD1=eOrdD-nߺy: z,::hꇶ?4ꇶ?4êӪf9 AvuKꇶ?53 �.΂ YwYY2~ϳx _C|:yq2ّɋG_OR~4bu8WԟSɋG_OR~5jjf%%k`[B@}e<G$$qx [Ʃe Ši G4hz1]C3=<&#YPF\=0i'�@i3<ji2qڞ;r BC_{Y|̭aǜ2է496@H6~koZJ^K.D{VN1! #8{h�ƠۤbVtUAUH13U9iK/X^6)e8؜wqۻqon1.8 M":;<l!x;;L<lTA>eJ;FۉOPՇv"cic^q{9ߨe8vs0bOn{!:n69^UH;13T" ""s=0õ�VbL8Wǟ\G}̶dA3bu8Wԟ<{N'T-]n, R�G 9I!`FD",LA3]neSQAŜȘ8brC2DYٟN5ޞ=UmveAW(*>M$",H<5\kdw|,հr{=d @8Br $QD/,zU=\g&\*giFNT@@DG 94ۏ{¾knp<=DJT*2afq'gf&b!q& 030.k'ˌAGSDӋ5ΝX݅Ȏ1sibu8Wԟw`Z}s87p:M YN7v'8ŝE[-uXW d HzF8YȝE΃ZgvRɓ>}jˈ߹g?*|W&iCm#ᤛlLFɸqxUrFzi A]koI8w^3v6#g>{ƈW V HzqC03;Ok´BͨMQ=o1u $K`pb6.MГVՠ5ʖw0JP2OPSR18A0�0&Im[Ge;fD3F dB"NlZQivYbcXg$5?b}=?F|2ltc E8" DӍTg�&f%$֜kdw|,հr{=d @8Br $QD/, {¾iţp?" {¾k4s뜗_ q9mPRq89,./vn Ken ]N.<7<ɷ$GX³_Խp>Mm7IKrha9X[~&$!$rε Ken ]N.<7<ɷ$G濩{]Iln6˄էrLHBH0c]p=/Dtw:xCY 6vfv3g݈A1b>-x<g̩Zh�Ӛ=q)nLm#^?p+ݫ,r#P##jpþ-,`$<xȃ3gPm\1|ՑG+uV 'f&bۿboeA7k|& Ξ6w~B<Bٝ͝b&~yXq 2jpC[Nhmħj1NE1�W8\ j2qڜ;_K1 '7>X'[[2UI+SKWgyh\'1Ȥw!g%muPqg!Ș8YI @#r2!g'f}cƮY,)5lb#./$.%a1Q;-CƮY,)5lb#./$.%a1Q;-F p<=DJT*2afq'gf&b!q& 030.ivcY=\g& <'\it/UJ, $NDp3M1è;dTGWM+UP\ɆfĘ L +Y6;ݮJ5Qκ2~Ռ&b#i{E1}}ޟfj+�TcN6_PpMĶ#b} 8QwsY4 �﷤GYUpǻ/K;;֊m\ RDsUUJ1 bFfD,ffu<}}ޟfj+�TcN6_PpMĶ#b} 8V)T[PTZzv'%wƘ" 3lz7;ՓO_В p ^zM$uQ {$<UAq k-G>a}*eq ]"&bqqaf�a"[fm.Quy.Km,[Gf9fDRHfB39;3%muPqg!Ș8YI @#r2!g'f}cƮY,)5lb#./$.%a1Q;-CƮY,)5lb#./$.%a1Q;-FNd}dǑ! XAg _gDvOsɢ*gk;; R; 9I&b$ n+p<=DJT*2afq'gf&b!q& 030.k'ˌAGSDӋ5ΝX݅Ȏ1siqDDE-]n, R�G 9I!`FD", %ZڣQAŝ C3"`g)$3!�ȄE#mP?\j1BVVVZn}A.>g['jީ̲V"1-�BH2V .Eoh&?~W�隅]OLހZwR"^H G/;Rmæ�T2_�szf=0DXR9ybEIn}:r.Z+rAIQUU(193txfb*h5uRUPr:i p6x&p&vgf+4W=vUQs: 6WiA1]:afxát:z4O)s +žw"ç;L"&\IaD]nV;mUY#Q(cr32'ffgww33p5Q_q:n%8E1&IwjcîTmJSs+(&[ SM14MIhX^zaߨnu4\)YLmLI<r8;3U˽ɧ/I8u}&:ʨ=axΒ_DI؍?ш^k[C VRdWz㬬Fc( '�8bOFQVܤ2Xʩby–NTN@DG 94ےs:3EOQ,utҵUʌjh*FhIى\I ór94PQT<MsgazV'wag i"r#D`Quy.Km,[Gf9fDRHfB39;3%muPqg!Ș8YI @#r2!g'f}cƮY,)5lb#./$.%a1Q;-CƮY,)5lb#./$.%a1Q;-F!f�.g;6GIn<Sq*+F) ɝFfw&'H/uC2\rǙj,eQǭAq* 1 6q}Dv;3�$ ^plƒ'EHԗs1*+#HD1GLRUF%sK$ )Otgݷe̴lw!2e5T:)EKmr3;I+VDR5;\Z4;0I]1ڍ?Wl\Uvᦈ"rwc >ÏOj j=jX[KkHwi3('i࣊CӖzB0b|p462t&OUPRцdROh'x^@~A(a8؊喣zYc_P/t[b9I53 S])b5M-,'J1V4^ 6+`VZ{M+ׄŻ|'ڎW又zuj*-URqC;03;O_lY�(vq4q-)ع7BN?EBk-M6a}*eEq ]"&bqqaf�ap�A3Fލd$׾ޓIeTqﰼgI/$lFj\BKuϘ_i nEAegbyWxi AYhfٛf˔Dfzcjd<Ct5UBey)mM]YgD+�Bo@-yu;)a $U#ZXX6^/�u=3zgtjK?Dh)1R"$>9pD#k8fb*h5uRUPr:i p6x&p&vgf5Ʃrxj.mG?\vryg'Wlm7L MB쇐J.oC[,lT&\wvH$HIŝ9:]zƪ_4A/rl@Bp Y:QG4lmY&6%E4fu3KljJ7o#o68{8Hg %Ebt[).V+E=U4$SFL&.B;:c}<,i}VVf؃ަ |uBD,tUTO�niЏ@1[Qы}ڣvZ8By)9 鞸zt|=szh֖Y [)\*$>NspcsQު}X7q/tfYO٫` !qy$qw+ qH^Yj!+qIAVqO۽�@av* *yH.4߷Nx֟ah*WQ%]uo]>TsMz\am(ꇶ?5: Eu?�e$Ō_GTA#UZFvbf"m'oJcz` wgA{¾iţp?" {¾k`Ҍ%�=I5L[Gm'�=I^LZ= zb 1h+OƵ{fq-~,lァ:*<9Źq[outS[O : r" """ (ޠA@R]㪈$j@HLM~թLrYl<2bu8Wԟ<{N'TA2/ .(_ԟq佣m�GӴSɋG_OR~4bu8WԟSɋG_OR~54ӏ lC)e;f'}>'IWiϦ-ˏ"~O{'ySLrYl<Ꜧ9 AvtD@DDD@S[O :)A-|'}ݝ9 >>Ωcz` wgANDDD@DD1=eOr'ySLrYl<Ꜧ9 AvtD@DDD@S[O :)A-|'}ݝ9 >>Ωcz` wgANDDD@DD1=eOr'ySLrYl<Ꜧ0K`7A�n΂{cN{cA,::hꇶ?4ꇶ?4A-|'}ݝRL%-l�ys�˳"" ""'y9L2"a7vo<ݝ=PP4XuCuC al~il~h3S[O :CK[�t�gAODDD@DDD@DDD@DDD@DDD@DDD@DDzaj;,?cټqoϏ>A~<wmlȂgţp?dXkB-9�Yc /|VxØ,p9 vmzMy#]ze]%{tqS1]ה�D'O#0H-!EXf7kHtӵ}|r=sFHqt6[TⴱBN@=2n/8w-ٷ&-S}=IזM_+p|.6e٨*-KVo(K? RA8mˉ_뤷W S]f.EUf8!9 ] 3rc(IZyߵVi~8W1h+OƞLZ= zF5pFͧTU*򺼩j*Z6bf F&Im& "<)tLynϻ7M5*QkAţp?1 %qn,/NuvTnNq;ݸ[ """ ""s=0õ�VbL8Wǟ\G}̶dAm(ѽ)ky3)(QMf-P1;m싹>ʛM|+45 5eƎAzܡϻm믹EUCg!5}@@nl,Do UCԵ Rd'8$"ܘY^/35W1Dp="Z[i o;[եFibvmmؼϻ7nLZ= z&5"s Qdy,bWImjc`fG0K։݅݌jN^kj[inS=5O;M;C,2!Ϲ?|U\m;ٟ|t#w Mp*StF >y_vuy1h+OƼHaWm6s&U]sWVx0dRҌtvs2mNjLuɦ}^.}nEjc*qVgv"yb#~?q3}ןmvO&-S}=Iyh9.8w azsڠwbpsY]_nſۀ0m݅mwdDDD@DDD@DDD@DDD@DDD@DDD@DDD@\8?e _Fnf�D8ӹr.g�)ſ.Q=1[% ǀ�d-,EO{Nl6ښZ`<䩞8:hًwbfb}v‹էV>?�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������krb5-1.16/src/windows/leash/htmlhelp/Images/Options_Menu_Open.png�����������������������������������0000644�0007046�0000145�00000024702�13211554426�024710� 0����������������������������������������������������������������������������������������������������ustar �ghudson�������������������������libuuid����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������PNG  ��� IHDR��2������Nc���sRGB����gAMA�� a��� pHYs����od��)WIDATx^sG Ei"Dv#(cbfxYJؕF![uPQ$x H4ngw}܍EߗWeWgMDQ|[U݌\j`cX7~hL 6"SLqEJˏXV@ Lˏa__wa0D"CbcW 0,Kg;=b@$Q+$|'M`~>8�V� ß]b@$Q+E`0NO ]| @X9pzb83 KO Gl@ Hj2 H4Vrxlmҵ/^x p:w %-[vy`43 48[gw(D$gV*6OprҐ$ƾpCc%_B@P3X/[$OG$K+VG Kӳ6JV/$ [N?dcU x,<?+jVZ\Ie'[:.n?%zZ{s`*[@y&p XN?dcU `,T]liiiXlj*E3QL54j:WpղXX`7+*-?w6`L1;kN]Ke We @X~v?-TZ.PT\XLqbSQE3(ol}^5}m ˫]PHv1? @ر+-l nh6D$c 2c XX]P׶,s+l@ �43%i~la? 2dSğ} uǀkͲqpN-+l@ xXnW/%rJSXrXHō15?ka֝k+tvBDxgX`Loə^'8٥xU,WN}V1ڸc~O{Qk a!2+|)y2ɹf&g4uDȖ.-f'm�˺_cKثQ�KGw(g e6V pƲ76 eˉ 3QZiš~@ g 2aYncgߐt7TXX>ң ˥pm0C,څ$ &a%}6vj&Ҋ Kݻ25 @XROl?Sa-VTlZ;Ug2r. [ v,:SvGbПK*Bb92>5o,;5ol 1~7J/I{Ӧ29 @Xvsps~q939O6ğR9 ^iefhHV5ъ!:C!"ALN.+$?=<=0: ƔMS4lHҟűp�l b 룎qp Orr\Wr)X撅ta>]�f ˴< ;7p`96 @Xez+̕Xnv,77'cRsIJdC<Q"vye[rCuv!"+c943�ըK©sTdӳVT@5Y8[gw(D$eÑ e<TnJKqiXR,"&}@Zpb#,ʶ,­;Ql@ /:�1e||6c$$Kt39U,ɽT L$a 'p,HXO/FKC60Y" h%h:j,a 3S i˦P] d 9aXvڽxLO/& l@ @ XV0lI,BW<I4O/X6B9FMaͪly O/$ l@ e vXX^G 1.J&'�2;["U|3K&hpW-v;CaKRX/\k/]%DSPJzc,T0-yaNT@5JLeED!ܚ.Ԇ x @8\iLfˮ–->| Y2Y]*V\!]GGRZ`Y(8<kҾ5zؽ58C陬SƒGQ h,ǮiƮf7խF?TM~~ X @5=~6U52[A+8#\o74 m7cf҆i7*P]v|by6V pƲQ�y +.Vc- [ȬD,Gl@ %T[gNnFcoF+ͫ`ZU:Qdˑy6V p0S9,'7cVRDX>9�@P?N{ K"W"^t�YȖ{˓?^}f%e)<zX""+AaOoD"fW/NSKa :֍�"A<Ù"+@>,!a!t?^Ȗ}Uo?%ꃤ*Iڲ+T c.%_¢P8汩/IǑ-ţ̓Dڠ*Μ4˕ l)0EQ!j^gs~@|2,C3|`�I٩rҗ ?>e7I6 N"+cx_`)gj)Ȕ3IM`S; SwLDX;w@� n:]h+_*1VzMZz@Npz6V XmxV Qb/䮭o}Oov�Bd[Pf\(*o*_עJ |p�Kt߃DS>!hLLLNe;GW4nm٫B!J0LEKT_DV  =}UQ5Zf:NSȿ~]|1 +cIoVI][ QlLlmKj�R_}-HO{g@Hf{V;dr$9vKΜ޴Ux#DGɿPK`"5+-,m|{.a<Ob*(ch mJ.M&Z`L;�ay R�,,Ӂ`in%Do0w%|@T45@zdQƒd[>_43؊l)f]dqKXwXsOR](醉մ3XKVEV@} ,yVnM#0T1kmrCI{UZqi֊0ų9 K)N|o"t lcL%�!Pv 9SH EQdK_džLl7`(^UM4!Dj|³yEN|Uu,P)3VYYt +MKI2/{e5YZ Dw}xg@ S#^՝;q2bӛ*{-0 $eE!lK(^Q SIX:";SLb ĆspTƒWlNʻAZI6RQB{e{e51Z>3t)Ҧʙ0Xn©�cՅpj3K>kGȧ jGOTĵA^2lrS S5dofy%/yN0Tü!Y(OLa`ӕ&wjTZɧꩉ|"^ԃ+/̼ξ䏆\T)}B7�yOOeUPv?IWդYXOJn|AOD"N8*V`sX7h4ug2UA&1ayTd: y^J%%ӣ|X 9KhO/(J7{z)Lꇓq�L)�Bɶq(s 8 b{d"f57c Ł’Lyr6=W9;[*,1;% duP_bL-i* twz{?%[ aFrO"7u 9dimi0,3@ƒtE/<)zd׌&\+īp2[2b-= 9xm@gKG@G۵a%(7 | &ș -I우lc#TI$D[Һ~"_幋g0z>i]lP6 (A6+iANЋN)&˯ž [!-v!}YKx(y=0 �q2�9ڇa%̬&fSJ/P/;cyso/? ozljt(_CEHtdV�H�1>muh6JIdJIO2"\we;` @`wK]JfC[g!"CbJc8){e5ԧK’\tNolsKR8KL i &K&-%Vk)%�$sav7xAQrը>2@V<$Ox6d;t%p `3UzK%vzx]֟%oc#9N8Z#NNH{e5G+%•ⳏ4� cXC!DfY.wm(ߎdH(.p;цm*INbF h |3G/*y{3ș%6V X[ V"OF@B )7L�H:Iaz737ym'XE}31|³Sv'F KR(˻}ƽ^M WqsoFa`#!Ł4l+>Z-<HW)Svf;7XbP{X+4H&qggI8_('J #3 EiF ʱWVC}B[x2Dds(/|"DX2P @,q  #y6ɉ`dvA~n`b~h4&yee{e5G+ >ы� cA|l byӋmA<ls8Vk&)Ia}9tiYqv1>46\XI/>L/=R%(^Y mAOx"~4G$%+f/Fp}{B CbigdFL"ONu'x)(rp'Y”/'K#i',`h ]'<?)<T@ JNsaP lZө?D}~t?Ց/Ld=rvD�D @,W R/?fcXJƧAfzrqʼn<}`£@k`,<p$�+�"cl�+"uuuXV $ +Б_WXV $ f9>Ū5DZ j<a )\yDj͹Qƞhr #IOh[sk7_GƊ"Tk/<N6D׊ݶniў'+xj n>{7S2QJ8.=UKuD[ L(u\)ljKgN-]M ϋrr|rk%Rg.WqNg$Ֆ>)>Wr;SK_YG:ؘ&4N6&kxlt7ҹoH+,':`h$߿7}xFK{]ܣfL hثTcnBBC)MF;{届ñynUP]#f�T7NeΑ<WOmXIOlb|ϯgَJo1ljgMaY(>tV涡s01qZ?+twH,]m)ma t<[nDV@ͽ�$FGC} l->l#a`|~T0p"uL$3 26\ˎQvm>sӅߧLU;StdM*eFuZƀo u:>&fا>w&*=~|ڰ*,Ic-2d[Wo|j7*%gwEv0n:?Q}D > xێ[ȃݗMfZ³B5Gf_~})?-bְ흾+ۺOV 7NЪ`f4).#CHSRw%.X<YkPJeR{mw7㉄V-wz./ [bDVV+;my۶Y;]#m߹h>%VF5Z-pFծҭiVy*ܰq"O[&8hSuJ&}BIo7dS߽O.ˇTJbj+nn?6@2v0khԿ !EGwzsvn;tx~ם+5M쭧ǿOV 4Nh;ε>FK7ի'>YƳrhK7PksI[$;~؉ffB.J,]m EaxuI kyVMQv 9ؕMΔI�Pש/2}p8jqt TmZFj:zS. VPkMd' N:AfD~F*,gf7$҃ ԩ|ʛWT%Mr;,; rbm홸]uv;udWQA::#e9u,j^ΰ@8PXXV $ (,SSKl�+KSď$XV $  IN.@HP?\dcX(X ˱E6Vˉ1-8 |W)tm,|{')ϻ~3===333;;тQy?M_a9:4/W|?xI\(PI Ʋ0_4OE;>C#nRXVi>Ȏw?͆_g0`.&բZ^%S{[w*%֟WO~OO'j[{H^M>&\| |>~>Z3֏] %{QGוm+ΚA+(,UYGwH<1:vNIJZw e]ADl*{^c);븢"&^\6x2OU޺HDms6#'T*ˀ뼨SJ<FYBc_H`y7w�ID&SL&z"ݫ޻*т̆ܖk]E<V=]YAҮWw5{z߸N?%$<odnn!%1yT\yWvQ&\K{[muoZ CI$+?c�6>g?,ih"\foL,'"kzԞS;*ӣv"߷󟪠ZaMXeZGbQИ ӥ彭bPbZ/Us`A0ix+/vJ( ,�}iPGC)#Ҹˆh vj}}hr"BX0xASzT~)Yڑи?5`I@&~�QmQ.�j] ЦkjmX҅@] oPA\L�)lj2/9Mf ?^EK&䤜c~ٶnWz]Jd[Va˻guRݮwwM64\^Є_&C]:�NgEGpKW#^D1J?^XE:L�Zgߪdn_ g'I0ih\^^ۨ'w?wTֲᬶf/ZQ}0mrOAP}GOZ̕.X^z}t,9>> if)/߹ږ Mȿ P@ T{ejWصc�ν n+f \5*GHW0C*ٟ֭{G gn#m&Ac1&w/<ײᬶf/lQ|߁Gm%b{r|U+ 7oK&\ 4ʅ5e!(7hh+rp(xf[w81PܕUB�˫g`__^M8ZT.։v@L VjriǗ'P\?$!4k~.W'tZtW EWeKӚ2+9YWW`,O~.o]eۓb땋C(7r[-]to{qZl9%# �JwLɮ=:254X~7Wߔ.Q +rv)!i+̑V:VjUe�92O'?3ÃSߋk*434-U[yv߶]+x=fTR;'~Xu$S2[Ej-8 �ʹ*l-<=!V粕r>uX:>BkIűLf Jw땮}{Ct>CMa9gcX(acXp(X8+ Bp !Q+:Н\9�Xl�+KS@a9.:Ʒ|5rVXkcY/߭cn  Kԝ||*`J;_sGDn_]gu^wp{VuʺW׬%=< {=_-:rXIc-]jj׈ƚ\+ (,SsN4KONџ/GKn_ \|-'^;_;-* ϛ;9ʐLxC_Yw1mQVKq�܊oZ+d3\br§}Zn.5a/߹-'k( oa)it҈CIm!nfEoR_72?خVևuS]y_v*:0ϙ5a/9hTWtv dծ\Y<]D%81s2LhN-/DS K=. ^Jw-׾xm<Y֕xgs6FC63\\ >df |ege$(knճ%M2]S/ r. '0k5t`3jr_s`eHRĚIWwGj2 ^ *DuV jU5ct$֚xv15Wl,on敞zzj²n|Wu?)(7rcY8z=[s6 _++r:*ntGEen/m,;UtA25'{[2$9ː6D5a>X}{`XXZ, T,+k`f{ �c߁lh`!Qd,Y)Xa�cXS ) "]DƒdB�cS 6%c N2t$4wKƒeNIH.F 0%+: [h}7K;CjSSzdؾxf2< p7]S׽ó e#Xm(CDl=MT"LvReNΥ^sU�8͆h$$6D'B%LB9i+A MNeȐTQc.A"IH^p.X ñs Z2l#3SlN]wLEh`,ÆfϧD6;IM }Z6)Mbe;W)<:5^4Xq rO䴖 sˇ֒OUcC*qN0bY%ETo4^̴d,#^P:g=eX)@X&XV < rl�+îke����IENDB`��������������������������������������������������������������krb5-1.16/src/windows/leash/htmlhelp/Images/Leash_properties_krb5_1.jpg�����������������������������0000644�0007046�0000145�00000065366�13211554426�025772� 0����������������������������������������������������������������������������������������������������ustar �ghudson�������������������������libuuid�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������JFIF��x�x���C�     �C   �~"���������������Z��  ��!1TUV"6QRWs34AStv#25bu7a$Bqr%8&CDG�����������/������!1Q2Aa"qB� ��?�[1 샘N.J)䗎#fDye{,zEW$:sNO|yYJZ'qH�WC 0Up6IrԶj1֖X(f2Iљ_Q:/Sxq:sNO|5 w9~*c'ejdXN7\~;_: R /?Yj. ݪ=6V^m )*0<tjRqJ㤐F!l[{ڢ9SlC]iߩ4y8FkdV2 󗔑쳓bjڥ8W]#[ZSs1C~yI-Ҵ_${b N4Psw{' 6FYs%5!exen6󸘌2)*-m~V$)O- ԩc(Y!CA6J*?Ś[}D2چӿS C]iߩgo-?f;3e %ףy<42[DGUB._DX36Z3'UhHxKR{{f2<r,^}C]iߩ4nd4XM$22RRdjZ䠌ԣ# )ZV%9Iyn*#$v3.V*u)ZL+i:^ 3+]IZӿS C]iߩ4'z{Z,>*9Q6o%OjJJZLѩGqq0dOjU5ٚἘ^\|MȶvTW^2Rǒ u4qZLj:sNO|5 w9~*]7,IR'WRy &OӤ --,qiY))2>qdUf9Prix-'o�a7$`=mQI,ZӿS C]iߩTSS9ꓑ9饛܄JRqҙSdT++%2Q =jWR^gtd=Smj8[zqܝ Tfƻ�Psw{`;=BU?b5F<5'd )SiŤ̘$I$e~i$3TWQzs,HiP!%ZS6%QcvTֲ,zӿS C]iߩcc 41ӿS C]iߩc>Լϵ/�M9Ln4Psw{%ϵ/�f3KNo`;=0uf3KRӛ$:sNO|5 w9~2YRc>Լ41ӿS C]iߩc>Լϵ/�M9Ln4Psw{%ϵ/�f3KNo`;=0uf3KRӛ$:sNO|5 w9~2YRc>Լ41ӿS C]iߩc>Լϵ/�M9Ln4Psw{%ϵ/�f?/�M9Ln4Psw{%��41ӿS C]iߩccӛ$:sNO|5 w9~2YKKNo`;=0uf?/�f?/�M9Ln4Psw{%��41ӿS C]iߩccӛ$:sNO|5 w9~2YKKNo`;=0uf?/�f?/�M9Ln4Psw{%�ϵ/�M9LrlʢDIlU&Kil̯$y}7ו%+"~k9a ̦~Kdal㳌2W[$66PQUݸx2-uiRWhV1!FdՍy,dOv7յP<3_mNojl|.1`hXH`vqku9=FjPhUԞUq_y$V-D vSDQ!<S2ZMWl$Ffz iI = hʪDLfgr[Ĝ┣3;QߊFdD+56U5ڿMKj?�:jYPZ:DX-v\ItLQ>m\4ɦfZyIj V׉~ٙ1;̊mn-~( JJSiTԵBa2$wvlV㳼msԸWe: ,52Sɰ(iTӤlJ;DR%! r;i$*k`Ɋ<Zd픙T&-&[JJKkQk~nC]IvwןmwlS]z;m*>qC΍"$}D(f2pDWU4-TYU`lC 5)Uʨ?-;)("RwN݉rIbI^i-Ǯ$;;ІwB%)ѻI|$ZW^F,RQM~ZʴjHZ&6ͳq5iplF%+;tW LA1%R:-6jNIԟTgJcIOT15߄gxۺ~wnBUw_ |*j?rU]eXVQgKSxǫ%侧1&Wb(;#CQ-yٗ,IQK[4WƻwBN㳼m\$3ʪ>qQpW_gʹK2P}[J؊F[w-M$jFT(#=LJVj:aSWP *Ě(N*1|dW⠈q]Ivw w'q6iZS~?ϥ#W}R5f=m5Fᙶ&䑙cb^F{ =ЯX(juU6nMd'y2vȌ~wnC]Ivwt6f賏 ܍ZZ39/XԋX& X'un))8=mF{_Хn0ݢ2V]T3uwub7d% F)EzF2=zCJmmW) 鑗`PQjABJJe:DEb1ɿ ʅI{,53EЕhWSnZnë~*c$S,{W.))WOMtqEN] Ȕ[T'["mDj,S4m]Ivw w'q6_U׫M8ss57)6ZSGU*L(t<ćnK %$%!IE~#B=Igb4dx쮻%-7d0%KKKޓ5lN㳼mk ;t"%U1s0N۩3>3-؅iAcX!~wnC]Ivw՚3_5}0V㳼mk [t!FoXAs!~nC]JvwVhB3z> ck &wBV㳼mzB9k_a5߄gxۺ~nC՚ޱϵXC %n;;ІwBЄf}>Mw+q65߄gxۺf#7s 9k [t!%n;;Ї4!ckϵ]Jvw w+q6=Y_5}0V㳼mk [t!FoXCϵ]Jvw w+q6=Yk_5}0zV㳼mk [t!FsXAs!~nC]JvwVhB3> ck wBV㳼mzB9k_`߄gxۺ~nC՚ϵXC%n;;ІwBЄg5}>=w+q65߄gxۺf#9s 9 [t!%n;;Ї4!ckϵ]Jvw w+q6=Yk_|9k [t!%n;;Ї4!6Rh$?W)r"Pc%8ظק;""ԣR4H`+@̢'*rQX*U5{xMh읚PJ 9l)I-VqZ4Rgz>M^ in)rEe^e{tSgXDqY3YXXDTJ 53%HiWbJFN1X<F?5:{ť4~]v`WX՚5QQLS>%(�i~A*[:%FsM34髎Y;юL+{ql]C�§-_�VMSE1TdAI0Xid)Y!-'yCVG{3Fӫ萻]@ݮy&\]UoSH[jpmMH˄TIbFwtFTs;~k&leiHm7Fy&VVDVnJHujKaRiGR7kC�`ɠn<[jmNCؙTu)2) $?Y/. U*:(LfTcRgU8!/N>dVhq'*dp޴Wۙ4 �2h!� QO"dD)N:JRI6[n8KN*Y)jv ӍK6W'Oy4T`S(7gLZ|dPP}%F]ZDMfo'T7kC�`ɠn<B:!j4SYf߳sL1qKKDaJj>78{ n*Z]ţ!1b zl<n1m76zHErO`[3'i-ɹ\q$V>"3=;]̲V9ƶ{ry:hͭ*Evϱg#T]tϜ(eir%fj+WJkYk2[ /o#jf:5M:J-e+`7 )k7;;%}JH=: N53XTY6ɄɕG̗kZ\PfSSI2bo/o#3,տ,qzt2\}U.IM.Zcٸ Ԕ*3A(F+#![NuFl楩ĉD\7ICHQ,:w&_o$/_jߖG8fY}~YMZn7@B*NdxE |e>dy~MXt T/:͞GLCrƨ 5*/%)Dax̲V92[+hmh'Ivbz2U>B#-DI}MJq83A+vU] @Œ:+lĆўuʄiM I!h-PQT)̩M̲V92[z#b菵"q> 8m2RmKaO%lRTc^2$?6oW3~ܨ0 q%4ܐn6 [4IjJTTզS;CqY}~YedsXD d2IxܵzdJ;+RN? %64+j7im<?O8+m8MMUXw [s-&z:ɷۄmFQ$=RN‹?Be՛ujw𽊈��������������������������������������������������pDW\?p떗ާ^x*z{"uv=m;ީȂ6_cݿD.|ʰI+𞅏.UedIu7m_yC6R- t2 u:o>٭K=Md2DfB9r,lpFQ`UDĔӪ  B˩Z& :bϑ2."ir~#TIqRD#,R�NF b3tJDPڪrK.ա %Ƅ]w~' >I>לO'VN%M 4ex Ӂe'V6dnC̮ta:q][lm-ey)m*Uy}- *0g]Q6٬Л+^wq "G(�hCo֒Qk#ӬɋRٍ2 Dj5ej,uܢM;;MĩAny4lAjٙ(эfDwm^D2~s2Լ 7At?ϾFӵ25Ǥ!n5%+UVvAxf&W +Vd]O$5v~9cbݱ~=l?u9 ?u9:|zl\k_jK]rU)H.,bt%fӭqKIB֔$)WʾQ5^]jm QLZWClht<g]3KjwBeO8Ǵ'd,ڑ&[Ăz{N4PZбPKU;Q֐znSMż<%jLC5(#+ϓSϓSSi$_ܶX0QgRU-PbڮQ1rٿhֺ^eYS08n Z:DNiJLKxr||8sVUzBEXFħ=RSɍ2Z4܄SF;DU+Fb.5UDhQKU!G:d6Z9F2i;MN1NJ[>ONxC>ONxFe4 ;?ji ^DDHyNuI8�kRI"V؝b0=.ahYYpi O)ťDJCA'jIY$̔퍷'<!'<!|5#nv?5;x^s}ϓS/;>ONxC>ONxEn ?u9 ?u9 NϓSϓSn ?u9 ?u9 NϓSϓSn ?u9 ?u9 NϓSϓSn ?u9 ?u9 NϓSϓSn ?u9 ?u9 NϓSϓSn ?u9 ?u9 NϓSϓSn ?u9 ?u9 NϓSϓSn ?u9 ?u9 NϓSϓSn ?u9 ?u9 pDW\?Ucv/-N<wj;g"""/*tEuKS<vmά[Ng W�wo!0#ӽ#iv?Hr7ͬ >.|hQHCuQ:6ёu�2 )m4'pGi6RHTXeO2Bl$ _ROdzL.Z;]@&g Mb$TTIyie-HKRjjq:k|dl7Dc`y⩒jp CrD)j%A6nm*pTŀ%XKSYàRj02mq`CeŤ]A^nl"M^z.}j ie" gi%. ͮ_Tdc8E-PCr.hgz#XTU"[_9OdܼxoYB ԣ7)i/4Z'R�PkmUXhC+ScRHCA#-;rIq4MCe9R!i($7L &�TwO xM0`yEGy$`*;'�&�TwO xM0`yEGy$`*;'�&�TwO xM0`yEGy$`*;'�&�TwO xM0`yEGy$`*;'�&�TwO xM0`yEGy$`*;'�&�TwO xM0`yEGy$`*;'�&�TwO xM0`yEGy$`*;'�&�TwO xM0`yEGy$`*;'�&�TwO xM0`yEGy$`*;'�&�TwO xM0`yEGy$`*;'�&�TwO xM0`yEGy$`*;'�&�TwO xM0`%LnKKRq#mj/�mWdI�Q0[o�T垈i}玦o-S#z"מ:.0#ӽ#iv?Hjz{"uvMkDz6/@{F"Q:ޢ2 rPFHN;iA;ͤl^X^wO0Ap0bPΓ$Dɼ9'n%J,T%uʯ?5RrfV%cbDA> ImX䥉L7!Z kI-iS*#ȏdHXkWdv::R))lhr6{(pZ Ң3;аAeNF YSLǪryu(JuS DNu4b݊WBh ǜT(t\c*~^3k[Sg)ȫΩ{NY㫫mBn^;;D*U:kPJKJzNTi3O6\$m6N6*̌h ǜT(t\c*~HY eڗKDŧ81ZK,Ge$6JHh ǜT(󑄪H $ZJzR^ffn+s{!�U!�֒^}˰_+ (c.sI|HvKxz@ 8 ].^2!w4(p]%= eBi/P,+vKxz@˰_+YV2!w4a W @eBi/.sI|HgX˰_+].^%a W ]%= Jc.sI|HvKxz@ 8 ].^2!w4(p]%= eBi/P,+vKxz@˰_+YV2!w4a W @eBi/.sI|HgX˰_+].^%a W ]%= Jc.sI|HvKxz@ 8 ].^2!w4(p]%= eBi/P,+vKxz@˰_+YV2!w4a W @eBi/.sI|HgX˰_+ 5XXfi-i8*}) +5)M}7D_(LWw^0RL2!29g+Z_zy㩰[o�T垈i}玿 f*z{"uv=m;ީȂ6_cݿD6|{F"Q:ޢ%шNb %R'nퟛbwj]P>$u*)))NREy$�强FveKybm&-F"""3?W]QbH%p*S)pcTc.2lmF6>-ň{ ؼL6jO"WpYz}ƬeW4LZTl5$ܺOY1]yIZʍ'T%q۴ m 8q HKHm 5-&dq%$_VwnebVy4dj4fkpP31] t50TL1!R0#USӪܣFWuEq R;D}嵫VWMQeU Dy(b;z�!*4ݏJU,T& Hr+^ʒ-bTHJMW{HMI.Mxۨ7!$b>i7 nF1x[7ڌvj=&M?:u CH;+6iԚQbw]yPҗeB k3lTkΨBAIK)V"ChH;7Hvʱh,qz8Ӣ츲8)L $t)$iqJSŸA-z4v1-FTIJkZd(#JQ̝5*�;�5~;R.WTJ?Tf\qAڶKGz$[=QL^k_8˾o�B(JHs`\TÞM\ÖQ{�ʑsɫ2vj @#W0eH9*Ga&`ʑsɫ%TÞM\#W0J<*Ga&``9R;y5sTÞM\(<rvj <P=xH9R;y5s{�ʑsɫ2vj @#W0eH9*Ga&`ʑsɫ%TÞM\#W0J<*Ga&``9R;y5sTÞM\(<rvj <P=xH9R;y5s{�ʑsɫ2vj @#W0eH9*Ga&`ʑsɫ%TÞM\#W0J<*Ga&``9R;y5sTÞM\(£l>qZ2vjk\xeWfXe�*;"-(_(LWw^0z(-eB�drDW\?S` =]r�k~{\UӘiLD�;$5fzwS=m:~m�DuD� K=(oQ?��/��/ � ���/��/ � ���/��/ � ���/��/ � ���/��/ � ���/��/ � ���/��/ � �zxJ8_(L�Q0[o�T垈i}玦o-S#z"מ:.0#ӽ#iv?Hjz{"uvMkDz6/@{F"Q:ޢ2 ����������������������������������������������������������������������������!X)B` cB & ~m�-/O-eB�drDW\?_3`tzwS=m:~ YTdANߢCim`@=(oQ?hJ'[O}BA0����������������������������������������������������������������������������8_(LWw^0Do-S#z"מ:L�_LY떗ާ^xb[Ng W�wo!0#ӽ#iv?Hsm7ͬb%'ؾYDz6/@&����������������������������������������������������������������������������� cB / Ҕ&�(-eB�drDW\?S` =]r�k~{\UӘiLD�;$5fzwS=m:~mlAbx0Vm R1)$c"!<A4Ux�%6L�<[Wh4Ux0�Io_Ǎ [Wh�C%63Io_Ǎ�4Ux�%6L�<[Wh4Ux0�Io_Ǎ [Wh�C%63Io_Ǎ�4Ux�%6L�<[Wh4Ux0�Io_Ǎ [Wh�C%63Io_Ǎ�4Ux�%6L�<[Wh4Ux0�Io_Ǎ [Wh�C%63Io_Ǎ�4Ux�%6L�<[Wh4Ux0�Io_Ǎ [Wh�C%63Io_Ǎ�4Ux�%6L�<[Wh4Ux0�Io_Ǎ [Wh�C%63Io_Ǎ�4Ux�%6L�<[Wh4Ux0�Io_Ǎ [Wh�C%63Io_Ǎ�0ROԉNJ[grQDHm[ۿ� & ~m�-/O-eB�drDW\?_3`tzwS=m:~ YTdANߢCim`Ac*B)̳%benġi%ƣqƺ�d b#>flŊ1]v,x5,V52$%l"m*"Y;z߈mGy'g%9h؍2qNomɌ0UDrM3j,]K WMj-d2/}nm [dP*nXM]mGK(Y*5%ˌNj0lg(*eu8-R݂4HY8$FW%e_u^Y 9ot@ 7kiL+'Ar*(s'FrF35ř"+{kJhf 1*%>S u.N1IkaT\qHZ_IOO ZqqԺίΥkOmzYʨMfPldafꌜI)%(JHYuJD~6c*FdCyNNq-^J9 DDGq�/h+cdQhX퉳Tzz2+KUxӓoe)ʃd0l`0Q,QyL6R&5xyJ"IWUS<WMN^5ڍJcS?:#rehRGre!TGqW߱ī:�ǣPNT�Cī:�R8�)0<JiH1*#p*#pī:��Cī:�R8��LR8� JiH0<JiH1*#p*#pī:��Cī:�R8��LR8� JiH0<JiH1*#p*#pī:��Cī:�R8��LR8� JiH0<JiH1*#p*#pī:��Cī:�R8��LR8� JiH0<JiH1*#p*#pī:��Cī:�R8��LR8� JiH0<JiH1*#p %3Xr:YgVTNjB .�6ؖ�` =]r�kMߦ[/G,EuKS<u]s1VN`G{3Fӫ՘iLD�;$91l_P,DuD� dx> Lţf2m r$Vv J%N1\F{G@향9Vn.[Ai U\2OTWTJ;̏gle3StTH+$fw’*11_B]ih- *".EİH)oy-=祡mqȨRJ ZVf]Q(llQt?Ya1q5*E꤆@[Jѩ⛍GC$3A,ۼȌ1e'3 <�0 v{6:ȩ YJ%нU'O*TbIleaJ/4`_Xk8J*KrNȕ~폽1e'3 <�0d`d%`ΓN"R$Hv J\WVu4ޅ)]Q\f{'2-Y[>MN䳊KRux'caJ]['Wc;cOLgxly a%fH-LRߔQY)RKO>M;N6*T"U{X1%Ke(i(R)쭝Q&мCMAHN2[B%heIIRE"N-!?1e' twǐ2J̥;3 <�0twǐ Y[B:c;cOqN-!?1e'V`twǐ2+0\@Sc;cOLgxly `. )1e'3 <�0J2[B%f wLgxly `-!?;3 <�0twǐ Y[B:c;cOqN-!?1e'V`twǐ2+0\@Sc;cOLgxly `. )1e'3 <�0J2[B%f wLgxly ami;G%tF##3"%S=""LBbgK[5 dDW(/zoJDA;R}Ǧ(t$AzoJCR}Бe+' zoJBD@NǦ(tUgtYKvs:eДDErg}qސd!Ww^0C^!zRHQ0[o�T垈i}玦o-S#z"מ:.0#ӽ#iv?Hjz{"uvMkDz6/@{F"Q:ޢ2Jܞ W[3Mdam2XРEܧ<.Nږ $4䫫Di)YށKd,-es%`Ǭ<YZaU˄4SKfӊ7Oi--bT)u -<)HlxJ ۹KZRLdMĥ)Q\!anU<*7QW]0ћVRDidLcnFvm.LN]N=eQe Kmd6J"%(QJGuUz~;TE".Ur<lv X)Ij5qm~R_NIMĢK6ҳ25hmDl6TƍNwX|\UwSx<aU,'1/L_շx;+"vӡfY3cq3f]~J\yӭ-O(Q]\{[2ɔ )V> RJyl=ܻ+}dj_w[M\? X(Z[ͩ[fkԵ"S @vZT£ђoeHQ9;ӊxɒmՆfcϷ2- ּs"2lܕ FҒhxUƃV>nA ^. PiꡓSfұJ; mY2U+!:}B˵LTƖ&5jS.7NB Чr5G㘷7TVS.Nc^U$׮rTS!>^Lnb/MUQ5c"#zWKYaVll+>TfoIez -NI#"Ž?c$Y*͝9SQ];@8OqM; 'ѳ)E~-o0[JO65ũQ!I`Nh#B֖f lGwW{\KXTp{˛*XD½Gux Y*KȖ9j,D^f{dBU>);6٫FDʥ*aFiY&8RPDþ=o_gr|b1lG-U- 15Ҍ㽴e֥t:Yy0* Vf2c"Z[z1T%8EԒRC�y[O&am- h6bjh6$a9On,9$G!n"Ri$LIfxL: bTeTg3Xf;\0s/.JSN&)K+٩7+Gz5>S%۫E*85Ȋ֒P`ГRJQ+.'uYشw%Z[)UIosv|&#o!vi6ԥ>j.8�q|(0LV՟P)45hDHaܜv̎Cdf&ld##ݣV1"=eU)ě3P̟jIl+dw]j#22ٙ[lߎCi}8+c2>ٿeV7el}~9{�fr o `9[lߎA+c2>ٿP=xl}~9V7Jo fr @㕱[lߎA(<r>ٿ+c%V7el}~9{�fr o `9[lߎA+c2>ٿP=xl}~9V7JڟzŋV7㐦s%Nl#AޡiwgOؿL:qS?/1L<Te0-n&9fDg [Y4%%Ddi2=#冴Eg$QrzE+*6쬤.Q҂m*3%$Мb5tSeESj .4qԌvFJ,d^F{$dbg7dAX$Tu.2T5[qT}ի"R5ȯ;fie((]0ΟdƃPRU ծ nu&BmB5ig=4h>UI}Fmf<c9N,ONJ) Jl ;:bR~k!ܼ)Z̘l>D]7>|jJjƐ/8ۆgiQ) l&J#"; ~.߅ĕo�bj׺+e6ƽZ]AC i$\h%KV⿓l%X%: IPKI(Eq FT#NmJ]9DhRkDJj3K<e^]Q~I% $IE 2 #?/WdQ?=�Ќ_(LWw^0Do-S#z"מ:L�_LY떗ާ^xb[Ng W�wo!0#ӽ#iv?Hsm7ͬb%'ؾYDz6/@&JBI3J###s�>q��>pγw[PP�>pγw[PP�Jγw[P:oC@+:oC 7uE�7u3�>q��>pγw[PP�Jγw[P:oC@+:oC 7uE�7u3�>q��>pγw[PP�Jγw[P:oC@+:oC 7uE�7u3�>q��>pγw[PP�Jγw[P:oC@+:oC 7uE�7u3�>q��>pγw[PP�Jγw[P:oC@+:oC 7uE�7u3�>q��>qduDW^� NuMr$IeP%IJ\$"3=1%d7 SD($rJn|+H/`D%d7 SVCp9ZA{� 'I+!e t_)  Q:IY /iR*ȏ5-M)qo=̈"ҟ�B8_(LWw^0Do-S#z"מ:L�_LY떗ާ^xb[Ng W�wo!0#ӽ#iv?Hsm7ͬc S,ITz3f2d`vfaCmR""-3DbڷbW`&4zx$eG}q,.{PҡLMa͎9.Gq[J-U)]敒)2/=-R!ۻAE*V 6UͭDuQY{ eim&y̌SS+Y¢il6ب"Ď4-!JP%$DDDEql%Sm^hՎaeW_ Z .4Mr vĕ'T'IQ)Mbޱ/TjTJDΎ6}:XXF: -*QcWAmjcQ#*8lפ?@'噶dHCWV4Odjݕ_ B MfK*B"s/QK;,cղIm+YqJvvG/W:fZkL(Sfy4DeRR#Zǽ^^kPެe)JgUTf%J5_H4*�{)3K7XjӦ6n6Q|4{Ոw$c"DZVmf4Tҥ7m6u;w{YꙘ}JóR& 3Iogz꺣ۼbU92ǦWJLMS>QmHZ[y CjDFEFW!wk_N{fZ}Ԋad5 5^Km#RW7̈q0 hWP+ؗRQC!T:HTc֢> Ѥk48ymS!nG6Q(B̎$m3-P𧻹~QaZtֺ?% ˲CV~]X=Rɘ 4hi{*Kh`ͷ یӌ uh)(NSeRHҊd zwĬ$Del o�=Ý%t"j"2 +k ݳXS)MFR9I-fZT9)0Ku:v}^UWhdPS\Lx}X LΥ(NzLSo%i.@m ]NUNaB 6k5b-,֒$ G~FfDyS -mK)^XY}2#/>U:ⱅ:MBciMP-D2IJ<ĸ)Fq v1Pw%Ө֊Uɡ"$~e%ƭ7b<HR .MT{ݯYڦ/ zͪdxSﻊjBJ;Fg[DC`v.RrSg;2dE306֦)FٷuiIlbw ŸyV-%e4:r8Q(iELD$tQҴ%[ï|u:5mF+lfU5Tȥc^W�s-S92Iןpu;U F|ЧIԍTjN5%2,`FUNJQ1t-8NP۔Q J.K+#waݤL=.׷ٷFKNQ&\VR,) %DJǽFJI&kRJ<Qe֢%c7)>DNQf10U{^?s&)$C5&ɝ�͈+$EAxPU ՝^M:Դ1MiZCyƜW$s6'n3N2RUZW%zQّj @i:N*q 2;ԢIH̊Q^fdDf4p=]V%QZDzzij6tD┷ƜqQ)#p#N +L"VX YؙSӒ_Sx;.)r*QfbJMHQg8M+Ȯ. ;2=#aXںNF qUyv͙(\Q!+[*ՔrUz7_lkȲrJ8*KTVBIdYې#%$-J& ��d��������������������������������������p;/JP!X)B`ߦ[/G,EuKS<u6 ~m�-/OwX9TdANߢCV`G{3FӫoXhJ'[O}B1l_PL�������������������1J+#��������������������������������������������������������!X)B` cB & ~m�-/O-eB�drDW\?_3`tzwS=m:~ YTdANߢCim`@=(oQ?hJ'[O}BA0����������������������������������������������������������������������������8_(LWw^0Do-S#z"מ:L�_LY떗ާ^xb[Ng W�wo!0#ӽ#iv?Hsm7ͬb%'ؾYDz6/@&����������������������������������������������������������������������������� cB / Ҕ&�(-eB�drDW\?S` =]r�k~{\UӘiLD�;$5fzwS=m:~m�bsWKamY. ;.'5<UEQ^2YRta{ܕ'F&!g3%Iцs=rTx^�{ܕ'FRtbmxs=rTg3%IщYRta{ܕ'F&!g3%Iцs=rTx^�{ܕ'FRtbmxs=rTg3%IщYRta{ܕ'F&!g3%Iцs=rTx^�{ܕ'FRtbmxs=rTg3%IщYRta{ܕ'F&!g3%Iцs=rTx^�{ܕ'FRtbmxs=rTg3%IщYRta{ܕ'F&!g3%Iцs=rTx^�{ܕ'FRtbmxs=rTg3%IщYRta{ܕ'F&!g3%Iцs=rTx^�{ܕ'FRtbmxs=rTg3%IщYRta{ܕ'F&!g3%Iцs=rTx^�{ܕ'FRtbmxs=rTg3%IщTui*.;+n#iT1Q-%}ĤvHM��Q0[o�T垈i}玦o-S#z"מ:.0#ӽ#=i0QQ[9:ʟHyM)II++`+8iLDG>z, 'M\0tۏU ^Rn?-W#;6br3x(6br3n?-W#;/`n?-W#;6br3x(6br3n?-W#;/`n?-W#;6br3x(6br3n?-W#;/`n?-W#;6br3x(6br3n?-W#;/`n?-W#;6br3x(6br3n?-W#;2*Ǯ=h5OqN&;fi I7ü}1ȭg(Q> 2bS˦~ ZFw:mŪgymr+YOmr+YO<mŪgy~ ZFwz"Dk"DZY˦~ ZFw:mŪgymr+YOmr+YO<mŪgy~ ZFwz"D:T0ce;M+WLN32;ED)Gܒ3q1j`eNy IAW$n2[knq1j`'6#wlF+1q1jasb7|_^fn2еAmŪgy~ ZFwl؍W/t-sknq1j`'6#wF~Sa,s$WI \~ ZFw:mŪgy[\SlYi))pӍu;%}׌Г29HlJEq1jasb7|_^fn2-sknq1j`'6#wlF+ \ۦ~ ZFw:mŪgy͈|e{B1q1jasb7|_^fn2еAmŪgy~ ZFwZlj)P.*y-iSf-fWw^D{qM62jV�YkNq1j`'6#wlF+1q1jasb7|_^fn2еAmŪgy~ ZFwl؍W/t-sknq1j`'6#wlF+ \CZAkNeˆi#Q푗b1}]r�kKC˫1 {68Nd8HB""ȶH3i} yՁӘiLDF[Ng <6Ɩ��@������������������������)6F9^ĩ__{.+P�D5l6JE*" &ΟX\ꖖm:NkHXƽ4jD{6EQfl2j8QmELv\^)b)jY)%rHxFC`ڻ YiJZ:]詃38SNkJ. ZUuQUԚq,`EnFTHuIkn7T!GrRE]D0볇yO*fXM&vsF4%* jRj=7YAzPiJ&EFsΤGr edkŸdfD,xy)]t^c~�KI2)47ޗ&P>z_bJZ QVnٻ'*Kr &MWĞggKQw\EwWH6&+Aek7T)C̩+Iw+O`=k] z~U86zU:j"[y-bSM'WILd;J#7^e|j^E^#$&#Q rM$f%GR"ZsXnj̈6u+S2!0.U! Kۏ! 4AЖeb"+̛?ID ))݌O)8�Kۿde+Ɣϴ;KK%w3.aǷODSSyLQ&sjJIJ5&ud$+H$ܴQ_;o&-z z"5O2<K3+>[,�TtꕤA_UldalES6qO(ԲD0evpi<IfS<+q";,"A_c\"" qv+? Z+?r{1]֥gOz)<ub ՠg%�`{^?'.�F(0-^lP)+F[ =cW˓+RIa/43WT]mCu- P'y)Dd.1^u*1f"-RiY$8l2C_Y$_v64Hw$CRXj5)+m;xq*QyWPIe-#SQ,VPkJSIG;Ȍg`N!3!54iuc%DFvH4+iڗ?Ʉ*R5&SBqWufYeRL,7Ge21XBI)+l"�}hFs3?"^W5Әy�1(�!-&h6&֨Vl1鑦s[ZJȱXZ?1!fpEYq|i$*/- .A%M pxȺdmE$luk%<x߫m\WbЙMUV<\8̚4!ř0H823Yi5ڊu[l@>RٯNf2$%|ԧXCd4HRK"+m1,.- %zb.KmLE(q.M `AjNcިw?K'5��J& ~m�-/O-eB�drDW\?_3`tzwS=lQʶ[*f)c—:3~$O54,2+~�в�+{�% c[sU#sg?|H>V�6KCEb:L6|!lăa|d$Eb:L6|!lăa|d$Eb:L6|!lăa|d$Eb:L6|!lăa|d$Eb:L6|!lăa|d$Eb:L6|!lăa|d$Eb:L6|!lăa|d$Eb:L6|!lăa|d$Eb:L6|!lăa|d$Eb6rD9f2,fQTg,#%őhq$DȮ-yG yތ_?|H>V�6KByEe:H[>o;#lF/a|d$+{�% +ԋHt�v|wG yތ_?|H>V�6KAW#lC=͒|!lăȯR-#)G yތ%_MsU0FNښq 2w_=V�6KA򰇾O_"Hҥz47%5dy\g;n`ַ|9iҍO򰇾O_=͒y-#lkZ'!Jַ|9iҍO򰇾O_=͒yEmk[4CZ19 :QV�6KA򰇾O_"HkwØ(kZ'!J5??|H>V�6KAW5nsӥ3,]xe)2$IW~V�6KA򰇾O_"H�fR,bImTGjKKmH%yIEؿًxD33�4FXC'/?|H?אkwØ(kZ'!J5??|H>V�6KAW5nsӥ k[4FXC'/?|H<"6ƵbrtkwØ(�+{�% XC'/^ZFֵNCN5nsӥa|d$+{�% +ԋHvˮYx)4\SkS%̈́*=A$՚6ehx3?1>V�6KA򰇾O_-#lkZ'!Jַ|9iҍO򰇾O_=͒yEmk[4CZ19 :QV�6KA򰇾O_"HkwØ(kZ'!J5??|H>V�6KAW5nsӥ k[4FXC'/?|H<"7e2ZM".9S}R,\ev{Cz"מ6w?|Hi\.:]$R-؊rdtkyr$,҄Ƚl߶}; TUyh��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������krb5-1.16/src/windows/leash/htmlhelp/Images/Leash_properties_krb_4.jpg������������������������������0000644�0007046�0000145�00000127774�13211554426�025712� 0����������������������������������������������������������������������������������������������������ustar �ghudson�������������������������libuuid�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������JFIF��x�x���C�     �C   �"��������������������������� ���込T:rEƖdv2UQ>J""9(ɖfu#Y5#Y5#Y5#Y5#Y5#Y5#Y5#Y5#Y5#[GYzqԇ\e9}9嬜J)6[ۙ(^^u=iY@~K+wZIwZCu7ZCu7ZCu7ZCu7ZCu7#y7#y7#y7#y7#wuЭ۷<~E�1ѬO ;�3 ;�3 ;6/*,eR B-VE*J,jҢM_RjJ+;�3 ;�3 ;�ɏSrݎiZϬZnVq.7vef\[b6w甦Yd6"F[ S5<t,VMfd.rbfx4bBғeL+_/-jIgv"l僻:VqnPLk6sq! 曷tW_%䘻9nҭKy&R\k̓ ީ^/!9)rlPr;=\%㻝Yg >D%U͙bPzJQsZvZj֞-gIr6ug$u2^kqv^ڜ{]{KKLri{cX, ڈ/j ڈ/j ڈ/j ڈ/{>.()(僻:Vo=Z_H!uj-cK~e6m/~ZYad{zj_;jD殔9jCP殔9jCP殔9jCP殔9jCX,qAN',֚x#`s^nsu킭Q4hl>L$e41idƷ$)soIleUN]F�d���������}1ANjrݎiZxKv?7ěuJ:FXH:qs)6wB}-)r�������������+ b僻:Vo_>si==eBbk4nj㻝cr9oې�������������_W,֚x#d=|5{_[xVqΌ~R쾹]\ uٽ5Ƭܓgs9e`W*P�������_W,֚x56㱩 {-W=%spҧhΥ??ٳu v8khhHlrdŎ6b ^8̮[6Kj^vՅ,~!%HK���<W;v:uiJg IgνoԞH)8+P4f4gvH_R,؊V >D@@���������<W;v:ui Ֆo7Mkl74WitKP#ZqʥWkLt]_L⯘y^=ЧrW=Q���������+ b僻:VoߟslP�������������������_W,֚x>g������������������`9`Nխ<[8�������������������<W;v:ui>Ġ������������������`()-NX;ӭ5kO}6%�������������������}1ANjrݎiZxϹq(�������������������x+ v StMZż~}ͳ@������������������~_LPSZwcZj֞-mJ�������������������+ b僻:VoߟslP�������������������_W,֚x3aFv`vg`vg`vg`vg`vg`vg`|? v 9`Nխ<[ ����+{)atYOJ f/GhӥKf;j ls<vuق'B���� v僻:Vo�����5d[*P &fU}&ag`{X:OD����;rݎinUu'PBu'PBu'PBu'PBu'PBu'PBu'PBu'PBu'PBu'PBu'PBu'PBu'PBu'PBv û:]q2������BB)6D\QzIK�=gTt" d<1y~duU@M_vg[?N{wX;ubd������6ai,HZUaw2l.mobCv^c͏0Bbt2u' ҦO$Y~kmu'`'����������������������j�.������241#35P0@C6! ��˅r\W.˅r\W.˅r\W.˅r\W.˅r\W.˅r\W.˅r\W.˅r\W.˅r\W.˅r\W.˅r\W.˅r\W.˅r\W.˅r\W.˅r>] .%{-z*6aD<!(\NVC] <8X Z[h7BYE䉸MZ Ah-Z Ah-Z Ah-Z Ah-Z Ah-O~m52!9ՉVI&rQ,crÔnV2I@˥rnUewF%˄RvQ0pUA_[%[%[[[[[[[[[[[[[[[[[[[qb,!livKwdvKwdvKwdvKwdvKwd&ūwdvKwdvKwdvKwdvKwdvKwdvKwdvKwdvKwdvKwdvKwdvKwdvKwdvKwdvKwdvKwdvKwdvKwdvKwdvKwdvKwdvKwdvKwdvKwduc>j!I5hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh=ŘO[~d!r4mZJЯ0O8Cێ``l n1n7uxdFBZf/f�c .3]sql,&')kC_ǥa}i&PrU* 1p�\̾0yhhhhhhhhhhhhhh4Y٤ǒ)龍 v1~%'m.$klK,0]]]] lq.=wXҧlX[1!aFZD%&D,&ֻՁaI-%Ǯ ;IJZZZO1F?5޷nQJ:̇ ^Ms+2CX!M! Tn)Kw4Syna~& 0 L5~y٤HIb5L`#]OJd̵3+G G˯ O8JYI8rEf } 5uKwY!ę߸.fKRVܺIf.irئAtQQav?7b8ᬨfQp c V#&`-ˣ(( P$6dYz E1G 1߄ hYID6Vp[YI;*υ؃|@18Z<zv ÝF*jjjjjjjjjjjjjjbU/f֗n[n[n[n[n[n[n[n[n[n[n[n[n[n[^'/v_16 YI)QxbTxJ^LKlDO=!&ccQ͸H } i@- i@- i@- i@- i@- i@- i@- i@!K_bi=i~PX֑ ,TC)K,R_CrŬq2̑Jyf( e;!p,-ZrR*!;|InNabI.]Q#̫`>!eAkAkAkAkAkAkAkAkAkAkAkAkAkAkAkAjc_IKByd Fb0x/-bKB@ge(ulCwqhR.a&IpY[9�G.*<za.KVm(LSה�J垾�N"Hmhq`N$/j0Ĉ/Ĕ Aj0>Z׈MeDXYX;3cs<;89A|٥~^'/ʂIFPʯ{1DSSZ šДDni`f_&y"K� :  5[egq&2jr,U Q̇jJ#�L A'*<z[51j320}a$Υur$"\U_XeQX`tQAԈ_wqU/f֗U^'/^*YTF@)l1E^Y=9Ci[2Ak  Xޗ-һ_IK3vlI[0YX9ֳGG㗬7eZ&#cl$،fY4WVq ']/U~y٤YwK%sRXI,qfYƻV <L�wqU/f֗VA!Ylj+PRx&,^XU =axX{ПÝILJ/U~y٤Tb>^8ɧ %#!F㛹ffH[鰇2 "v$034K%6FC9ňU$La 8btN#Ɋ\ELO̘zb<[vDd^wx_bi=i~U DF $-$$X@х ˀG4j+ 𘺰*JplTaL4A7MF*ШDUM6Gr2Ƹ@k`>Ean#m$v3Iio\WAVpW46�wYsER!)BHaB+BaGAN*<zk,p#mt2p-؉9oHz"|*v{dt a27BЌ"+Y@G18l[L%(xիl&&V4̫sZAbD|)l0#%݊m<5[[5QrKx_bi=i~UM`Ɇ9-Xp w%~cs�v2_>'0ͶĺQps/$ӎq(9ׄ gOtQuR6臉5A({~^'/ʊ#:\y](<93 860^[y6i,}L)9rBv]dȬ4 ęr EY`P>x Xg�{e1{4*c,b@+"qėg%S kbf [ijphqw}x#)`0Î.,*N_A<kMx8Ly\%`K>@i�h¯�Se1{4(JH谧 ghEh*J @QCÌdR,p|1uhJǥ!։_J sh!%PUP I\AHqf90p Z E PCMx_bi=i~V[?/U~y٤Yo�wqU/f֗e2W瘽OZ_�gx_bi=i~V[?/U~y٤Yo�wqU/f֗e2W瘽OZ_�gx_bi=i~V[?/U~y٤Yo�wqU/f֗e2W瘽OZ_�gx_bi=i~V[?/U~y٤Yo�wqU/f֗e2W瘽OZ_�gx_bi=i~V[?/U~y٤Yo�wqU/f֗a.-YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYxIK<z�tXkUjW5\֫sZYL?\\\\\\\O!aA ^'/R;N38nՔ󫿊Oڹ-kݙc{YAc>+1?�&<Wk1�ɿ<z�u/㿆U;lg(ǂ.�Rӆk1Q᧎YAC ?;lC?mǎ?ɿ<z�tMK ] ] ] ]QEDܺ[Krn]-˥t.=vH%t.ܺ[Krn]-˥GW'<z1{4X:N6kfٮ6kfٮ6kfٮ6kfٮ6kfٮ6kfٮ6kfٮ6kfٮ6kfٮ6kfٮ6kfٮ6kfٮ6kfٮ6kfٮ6kfv/f�%2]Y-Y-Y-Y+,k"ÝM}5_M}5SIQ&% 鯦k鯦hq0g_M}5_M}4);/f�!HZOnd 67y�C"ե30Me bg_O;|!opL.`qſ''N=YM*˹_bi=o p-A;4wɗ c@;|} =16ZIJX4vT@3咚'~:m @05~y٤cV5]V>v}ZkgծϫXڗa,XMDtADtADtADtAD2DtADtADtADtAD@;¹E]E]E]EC l^3gqLeS.w˸]2)qLeS.w˸]2)qLeS.w˸]2)qLeS.w˸]2)qLeS.w˸]2)qLeS.w˸]2)qLeS.w˸]2)qLeS.w{��.���������! 1A@0PQ`aq�?x8pϱ^eG>Ԃܛqt'(?_?>ϧWMŲ<#1c1c+9HW~9Y1qB!B,$ޑaR[#; f>mIy¨*.֊Sb{�OanHFV>TeX ~2mK!n>62Y�+�������!1A@0a QB"q�?ƉDiD 0` 0` 0}t'TT&5"ƅ(RH&L2dɓ&L2dɓ&L>)V,訜Iz1΍>4|Ng_&sQs}H1rE[      #tU.E*U6_ U|Ks.e̹2\˙s.e̹2\ɞ)VlZ5e]?o"c:l�Od| qN1 qxtUɡ#I'mztUx4FR:c_?;:q#>|!eOe^{{�x~lzvdb�\Lccccccccc|AAAAAAAsN< 5AIӧE[;NoϧE[}^sNӢZQj-EZQj-EZQj-EZQj-Eq�P�  ���!"123AqQa#5Brt4PR$@b 0CScs��?mɬ$%]a4]<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<0m).(e7*}~H{ަyа<޻�-?(e-Tژ].OBG\.ܔԠФe#b6 8%d ^.`ڵg-a' [ !De˔Qh+6*"6n~H\e!2ok~LUaAQ#ǩNiOErVZfa[jHVE;rRWRBR:}ЇK% ^ĥBn(PXXrҰ5Bu EP *,qft#sWg:x6BTs bTK_nds:XRVVN֠j)s~1[SJS-!Sff\ ]RSJY$J0jqO'Tj&oefKYV:)Jk x!yeZ*F0כ0E(qI5j K | l4eL%Ьs=ԭ-(Um+ՔdzlӸufߌH6ݎq*.ʍ븍)ҐF,F0P\BnixWҚ)}?u6m契 x9 *𴜶2{x,3B-6i4~#G3%tfK̗=љ/{2_Fd~#G.nXFd~#G3%tfK̗=љ/{2_Fd~#G3%tfK̗=љ/{2_Fd~#G3%tfK̗=љ/{2_Fd~#G3%tfK̗=љ/{2_Fd~#G3%tfK̗=љ/{2_Fd~#G3%tfK̗=љ/{ 1),2Z(|}_߹ y9dMˋ�/dөj$Eѫ|jƭ|jƭ|jƭ|jƭ|jƭ|jƭ|jƭ|jƭ|jƭ|jƭ|jƭ|jƭ|jƭ|jƭ|jJ!)=/ݹ˪eRr -tnTJՅjiQήRSRA%Jea&hiC 0^P֖TG2ڐJhH3m&͗$k@USw.X_YһL.˖(E-}#D!@_|Oӈ42*=qƨ!X&k\|5U5TI/ԻbJR b 봡86pȱ#TL &}肶4!h) ?�Oؾpv7" ٔ.S ]*^]=P%6Kr+ (ek:ZͬPz5B16gųdf~#ඕ!EA79VXuh**FB[Kb4/[�?ii^oC-5+.mZoڭ7e eN^oS0Ղ:OMNݢ".d.iZP,.cᐼtƵi hp U/4 KR qDLլ2pƭ|jƭ|jƭ|jƭ@)#(iiU okbUd2Y5)RKt R;-U)[ 4T+ g :�qi >C@pUPVNSxE ˒3:3>2TINK "zM˨}M<uŴ)@ZRo4DUmI+ 8he+HQAXHME%!`ЀABB]}*wZ6TI0%%V ұ)oBNt,`RI6u�l:'|[J&H10ZlҶe()刿�h&3:3fdᬰ I֗Fq)]BaRh*CJB v*za6SC-L"*XRX"im8";qXr3B|m-R,Xݍcœjj @tEVW'nQnuk J /ST @EZP[. Qr ki* R:.ӷam!bOTNkbUd0ST%OYO48zvzre)$GĴ�)ѫx,"�n y+qn6IHSjEZP邎o`PPlq1eU*JjKdԥk9HRKVq캪?(ZIBRlߟ\aX)$'ԹdYS[7BX CT2Hs)eJ t:`)zZ U7^!ľ 5"^vzVE Clҕo *) e6IY7^L޸JtLCOhZ4 2Q6`ҋ[g:r] >(CIrVǥR 0\Is�$^mm mM^+-x?*a./&`ZݗF7^5_i;`YE4P*4tJJWCi6N?Yo$|j &oyb-@.-YE^\2ؕqe8# jnQ"26I#&E_šm XmQ H-6~y!Ŝ6ᙢC�JTU$0kZ5Qig>뀤<@Q U,'^L`UUV> DɕR1]IAMK992 � )q&1ѯTKpaJD'i"/2NHReQ$聳CZAMV:BSEڲ[aSM>ZR&ݍﺇ^p&zbUikS&0{ g&5mRl$XZdpi80ńeAW>00.USQ*E=(w x<eW\W|LJ0[B-$ߍr`j�*fI*y1% CUij+mdNkbUdJl\hэF7ƌo14c|hэF7ƌo14c|hэF7ƌo14c|hэ‚(14c|hэF7ƌo14c|hэF7�;!Wc}!>7fLi3|Qo4F(7fLi3|Qo4F(7fLi3|Qo4F(7fLi3|Qo4F(7fLi3|Qo4F(7fLi3|Qo4F(7fLi3|Qo4F.YX?! l_j; G!q#*RYO4m12VMîkV,@'Iҹ!4qeAJH{#&H Tҵӓ'\6 0[q  ;)bQ7oK< b/%�?ٚVlޓpm "Yp+fj# ͚٥֭Y-eP&q<u-L7J&:8shYm+4L t\6jBV Ab]tږV!Y9;Av訴J bQ 7EMJ.ĻI |1o4-ƅзcB h[ |1o4-ƅзcB h[ |1o4-ƅзcB h[ |1o4-ƅзcB h[Hi�l+o$/\H#OpS�LR(c-_l%)·c)HuW.%%4Z5E6Yl d#uN j- : r\!,K0WilY6@4.TP#qÄ^ nͳLpr@Zm۾)!A@]Vh Nժ! u[kq꒚ _4k-΢?鉶k c5eS\k jkem[4 CneV#WPMl%@ԌbMI˩(7t 5ګ0ڨh04_F~a/#Eh04_F~a/#Eh04_F~a/#Eh04_F~a/#E!JnMwC[ڮ$B}f,Ug,M&ڿ%ƢVVFL\- ZQkWTӁReS`+pbߋt0V -Q61pS! K1$RR@)ҴNUYCMgDU$H$xR[稘Rp4Z TjuĔby̯֎-i'^KZ"w,P|xYWua5iY]z•�y>p64dDC݆ps ~*2{NA S2s)fޫe4I-HBtǂe؝Jިn` WQD>Bê!!mM|@TLQ9Sm6~:{}a[y'}`5}oD'yi`JS#,[x$QrQ@,)EHY R5vNfq24ۥQ^vJm "e%t6lUd_\ y%6-'jiP- ThhSյ*e2eY^϶$P.*ՆIi'A_fHLҥTn c L-X$`Ь TغeHk]j'V \0yHq(Je=>'^VnRL-G2Sh((桚M.47enn-)QBGTIeRp M %&0퉄[iRB_,7.깡m $�JHMje^S"T6艆¬Z= HL]:ݐhW_DQRpٰUZjUr3W`=}ma[y'}`5}oD'at:J]zal�8pEs)j"] J)IHp )ղl7&AzplXDiI@5Ti7:�#cm Qvkdku0ʖ\)-ST7EI ̚@.. l�_f:Ve! NZB2D&8l3@KVq%З/,6Y5W:+uP�x|8IUTL=(ThHqI$sIM4ڜrae0_KǃV6iN&P Ӿz-:AuUqaFAFxKDL[E.ZuRAn4i5)2eZ--JA"tijﴹWBKSvHtSwԲ(Zl`l  l8ׁrQ.ɨ<GR)ԲNSEꩭOY&NlXsɮzbiHϹm-deNttG1\L”6p}dyfkm&Ŝ%eud¶NkbUdO99(k8õaI-8j+o%9Z5$q0n:kmJUk*S.̡#N,*m@ o"QN)(KR9i+ShPd6$Ivfd!)*LY6[ gN~*k_G*%dU*}}%IF*"ҔӨqDY!XT-Hٵ%6R.li#L6Ö 7#&Ta!%m7K#*g9yeԔYuk=Z 5n¶NkbUdO9œZU^-* [֋(r]مg\UPM 7'IڝIM[@MgT)M -%У ~/*W_[ x?K wCV@A+bSʼn2eJ6knVHuam7�Vo&FKZ_AR:^T'Z 1b)fR 95M ڃ NT|!39a22SZk-(61+oֵ|,-bnL[Xm4?sVIX?! l_j; G"C Ui>VCM>ҧ-kJu"H<ym8K+'йYB'4p6B[G2 1I @WLd,KΪe델 6)Ⱥ&OCm&*j1@<ßHKD8hmZ馬$[hI-MC&YHC L"i.hqu㟔M:&X͔E.T/I>ӭUtZ~QLOZ凊ABT_DxAukUdj=FA[^z_Z]z+[.zj'ƚV5dJb]Bf%jӶ .-ԋ¶NkbUdO9$Ϧcslh¦=Pjbae˂�8m3 0 XMeDFd mcZVU Cav|ۯO16q/,HQ4)F\[3)p:zzcIˢaЛk»JFFRe.<B[) hiNL+o$/\H#2& M2�%2w8'Q�٪.ͫ')J$rɔï6̫f*K4Hߛ}kzn h*dƸKk4()?7> sY^HųLx>jӉZytq��?MK7.8qґ@M['%=掙)eeHR_QvJa[y'}`5}oD'P:QPBrFʔ-ThP7D!VQd;rÉ$W6"IHҰ%)U$S'F R+ [KIR_ LI>)PBZu*XdCKrI(3 HzH8tU_3&R]Z!N)tXR#c\(ذqDZ))? LIJTfA[J&J˜Lʛ@[qfǢxɃ-ڰRE.uXzM d/ZƳkAt4(֥ C'NL:DŽ&.55a)mKϪjd8"52eG]3ͫ╗UeKrfdq5 f9C M=- p!Ju^XQ&ۙ-e&[(Pzr,an�@K6[)[RY&蘝eԷ^~K�EhEͤtVɪi6CJUk}#NoK&MNuBV0Ж^iDdVS.r]^mJYuM$Q:Im).4V]uCs)vW&Y-i4}ĭėjMx0~Bؾpv7"Fy6iʦee{m0:֞B6l҈Ji hJʝYM:#d]ċj $d%50"'ܛ@ 0˴lUjnHK(S(]$`RʚS!_�& @7MUu.(_htF[6@xإY9zDaCxγg�\*6Imo6 8PVU: >hA%$V .*qE)MhdKcF*qn0sm0?I:}s"\kŅZ�81thƼBTp.-@6,E\]JZlf˲uB0TS3# h&|yf-l-3i+Hjsy`a0{i$ &/U2L[B:a[HiIq zMTb]:aCaO(:È$Z @Amu\q%m4j�uSi8FVݡh_(:!(Zy6 zE+9mh í) ?e [Bg rʺk.+ RpjHBzh jX@Q)PA (t>q8 悯T[ Ѵۉ?0~Bؾpv7"D-*j2CW:F>*,*!%STҦ֢{8|:iV<ᰧ?'l1\ &PZbAg9ǠA"Cae1,�iEmc.=61 R&i𚤊HͬZ]Lvq[B\QBH'p 'K<Sk(Ǯo 1<[ʢŔ"_&ySAL)C0[VZ|!uϭ O9.a-T_ᵛK*LTWnŶ�ǗT=N~By ܦ*o󲘚J9ʟ$]BO Ki?-+f$'\Ukb=*¶0R窑(֗g\(Me"ZӘ%h K[/˽<mR06m�Cªaj,%@ 0YhF(xD\TROʮ((ks$2(Mf8jK2Dܧ8qO˙_yU1fMYTp%&*r+)& IͶTiVnNۓq-Mn#/�Zqˍ|!$R�D8Qu̧F?QTkDn<} M].h*/˪%]S̴d0HJ@?~]GjU.�߫}T�iP4?$W`K\ Q DCEk/>-qk4&ԹyʃQ(OR'<e3O ,^AJE87>r,ׯ4D]mDrK9DڜQ: y�',FD5fFTkr-&VVBՃUMXqAwBRrUT‰yIYi@*bݍDx n-kiifG_$xg꼊D)y 6[AQ$ 9G(uvJSm*ʃ5n!N)"�h*KmgV..$Mí͖DeM4[@LRG&䏄Crvܲ(2c̐bU( 4fHCAfa(fU*xT`ɩh [ -h�tAbm,%8IHm-<\ `QwBDŽ<0 "ҩ?e S8AJTJh,!8 +o$/\H#M &^=u<]8:նB2txYJoQWʹyN5ƪ\jP"qmC7J&NMK--ʄqլ.&d >nRR:.1iԕڸ{5m%r85B Ez >ֹ[aeuJ%buS4bja¡�(~( J,q  .Y)QSLon:K(SLJu\\.±kZ>Sl(8)S >͜JV2M2[d%5BXRf)l@ )δ/0L6[ZMJp}# YGZ7F Z!hR%T(Rk33 ri>1 JlL5m �WUOI¶NkbUdO9$TK^o \t8�) X+RPrIvXGTm,rċ-`˨C ORkm2w]*Cn L.ae4J/ئ^]jREi 3dҧB#f?69le iH%fݛmKiI+QONN .Y -]�)Iph<fVd|1;iNa&)B�H`Ym!bjmwGgy82l&d]!!(3<i,MwR[rS`1u(V:< (JH²O*~b<F[e04%]7<$,"5;w6Fm`NLC󄤒Y+aǴ_18KIBCBUwI2w5X.]y#EgXL pWU Hber`(M#rP0aTX&Һo}q RNLKӃ8uǃ3MWRT):مmDrKJ k1i0%U*ӌ] .m% @BU3�{-:lXps鄥fJA�!�PVmH7C3j:` D%m|`ц58-k2hxw ,6 !Sюpţ%e ˂@MwB9Y]G<0u7VoYE2] (f.nQb\8MwC8I9utvΈû!,pi%['!Ve)vmBU/"mM'" E:ndJQ< _kŶL8%Yen�l6,,R46¶NkbUdO9wC[ڮ$B}פ~0~Bؾpv7"F%mDr5/+o$/\H#Ia[y'}`5}oD'zKgs ;!Wc}!>k_?{VIX?! l_j; G#^�Y¶NkbUdO9wC[ڮ$B}פ~0~Bؾpv7"F%mDr5/+o$/\H#Ia[y'}`5}oD'zKgs ;!Wc}!>k_?{VIX?! l_j; G#^�Y¶NkbUdO9wC[ڮ$B}פ~0~Bؾpv7"@�FѫtjFѫtjFѫtjFѫtjFѫtjFѫtjFѫtjFѫtjFѫtjFѫtjFѫtjFѫtjFѫtjFѫtWwC[ڮ$B}/\H#u̬8e@*)Ƀ=i4k}G�j>#�fmڏH�6G٤_?ͯQ;(-k8VZt@%TTgўwFytgўwFyt&]5$W_lZ*3;<3;<%QtNkbUdO?�Lv`̈́rBS\~()儷SHjZiH 8ՠm mG!9BwF n ([kL˶֣YE?]0svb PW @mE%Rq\�Q'*EwAYSCTZT0ɪ�5r#=.UDS -Z\BJ_\8n8@eA5HjwpD�ͥ[]j5_gq]eYͳQw&_R S#C`8@WJ᭍| "bRQMWӺ }U#M2]R-9B\RBɥ"KqKtT^"ݧ<sK RpxnNR50aM֩꧘?�I X?! l_j; GPaKR%IjI419$}19$}19$}19$}19$}19$}19$}19$}0}H%5WΟljJ�|#\C>5;\C>5;\C>5;\C>5; ^uٳK@ٮ!mٮ!mٮ!mٮ!m۪}ҌdS/\H#X?! l_j;{6W]ћ+Į͕Wtf+3exJ^%wFl6W]ћ+Į͕Wtf+3exJ^%wFl6W]ћ+Į͕Wtf+3exJ^%wFl6W]ћ+Į͕Wtf+3exJ^%wFl6W]ћ+Į͕Wtf+3exJ^%wFl6W]ћ+Į͕Wtf+3exJ^%wFl6W]ћ+Į͕Wtf+3exJ^%wFl6W]ћ+Į͕Wt<^m-kbUddٗ[mJ AX•ǔ%?Wcɫ OjyBS5v<)PM_ݏ(J&ó|U3(WۄXȭ["Eo2+|dVZb]jNȭ["Eo2+|dVȭ"TF6ȭ["Eo2+|dVl ؾpv7#_z»?ȹwui+ -N(:l<9 !җiZ*6ru 4TӅMls (SUOMg D[!.ֵ QW]:aܑl-6E/PNqAD9@ėWÐRzHBe$ٙE`DYlߜ5D˅ [.cU_[6)Xr_0Y"]PhғD~%`KB\xhMzKb)YRO�$/\H$0�.F(7f%So+eA I*%B[NAn3|Qo&BJ59Rp[n) TJJMqIEFLPilIܛYkk ]*@lCe?#ށ/A(<mY44ZV eiRJIl%@(eUjrkJB–PN#_0ULu%GA@�MY%Eh}1[U BnIX?! l_j;ZRb)ɫlh]eϪ4.�2s ̹F\B.}Qw>л˟TXp9ABd塤f++3{wb1^]xWW|f++IPC3{wb1^]xWW|f++3:WW|f++3{wb1^]x)i6A555/\%8b&n&Ԩ|!D=\hwq߮4C;ƈ{~|!D=\hwq߮4C;ƈ{~|!D=\hwq߮4C;ƈ{~|!D=\hwq߮4C;ƈ{~|!D=\hwq߮4C;ƈ{~|!D=\hwq߮4C;ƈ{~|!D=\hwq߮4C;ƈ{~|!D=\hwp) nll�*�������!1AQaq P@0��?!32E�++++++++++++++ GM莝 ;q7*C4gQD&vP QIOlkF/XL$[ACl :Af@"AlWYN  j`0S,R F�d]j?/6O6pKz rW%rW%rW%rW%rW%rW%rW%rW%rW%rW%rW%rW%rW%rW%rW%rW%rW%rW%rW%rW%rW%_<w9%QF"mV�J]nG*cjdS7āv&jqAKF轙Ei1a.HuiSӌaKj]޲J3S9M 򣎑` DEOjdEyf Rr E3qb$fT! 1)^<e�t֝%cnιkkk++++++++++++++++++{u&&O=,̲ ØZ5.ѯ6lٳf5&c'3f͛6lٳf۷nݻv۷nݻv۷nݻv۷nݻv۷nТE'VT Ԗq_J݊kѮF}kѮF}kѮF}kѮF}kѮF}kѮF}kѮF}kѮF}kѮF}kѮF}kѮF}kѮF}kѮF}kѮF}kѥ] 0dxNǂS,$x^iυNeCd`KⵓB ^(6|MJêT(,^&� šLl2#6FWb6x0 6�JxtѮ 7uK6e :p%1lY9!=q8>�x TGk{!0#' ;6"B&Mv;?ŘXRr6vKMJenQiPsYm!+Ln EmQTT@N7dXǡ[Vu4" ʴp8ыERmW�Js+$څcP0YI< }+P΀ܰG*8}\>p5\>p5\>p5L`֎ul0M><PItdLrn~cf 7! OvU X[Lj&'^εָδ+I1fRRBHAfLIH ,J::'l �J�$R@$ jJakdÆz\>qqjn1Y@ Tx|�UQ1k%k\}E ˽%E-,~+HL ,O glf.s|�b]A4ɵ:\} )� sW֋UW֤CoLZ~"Z˛E{ZWҺ^3 Wev v%ޞ. c`璯LBQ1qd֞apqf\[ E(e>)9噚 fjoPX *~ʱ#*˥A+p,&ₙ2irBLˢ!b#vъj42PڹCqI$!`S zv%Եwe:Q]0,\LRL�)Aj%,f쀈-d9tWW,�mИ$MWP|mgd?戁<=w= 2s@ Nx!Ȍ޵x:]b0(%HDK.ИGːJ/E抜k3UM;E")EBT":,8$`ʼn2 iaVu"[״1ˆ3bcb(%SqJ߭/Df;BE-DH,FDBqABlhV^ И HYI7Ҍa<&v(�O)&,)7 ²<F0\b ADŦGe&[S�OSX$ | knY Ɔ ڱljb* .<bēh<8f=DRD.TqY!ʄω qeBJ3¤`%3!U*DJ4iV~E{{{{{{{{{{{E{E{{%_ՏmDaՏm\у3PH fYhPrRx6D^opf8°-h\!vp6%s.^vih=Tl߅O!%Q/ lK1KS.a; DoS(mF&dqf3 [FsJ-�sZ+9 fe) \{Hbf(RX$�Ffk9vFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFQ_/ՏmI8 fy #cB.Aj<.Rc;VM/JD_A:tB@ P $H ɊP6_ wKY$tUi8MR!+7LE7]"H8Fh쓶7)\zJ4qRC2l@C?U~R=l Q 7tֲ iL#^Ny;W^Ny;W^Ny;W^Ny;W^Ny;W^Ny;W^Ny;W^Ny;WSqu�mXKq&,X,0jm.-x6-- ܶs.WsjZ b R å&28hRBx\/P0мdIg獦r}`5!F)xLȆVF�KSr;?N=aXzSJn鈗?Lt9:tc} U2%p&RA!XΗjRKͥZ&,IioQ~ ;B#@)3{33q6/�pD ،zЄT&ԡVoHD٥KC$* TRɼD<�@-9�e%%LEƒ|L", xR%7�[.ja@.O0x`(2LjBJCH7L7�mXDؖF~_gEpP6�",A@ �a'/p`h[IDjs8./<Em�Hj<jg9A#A� j)'nj<"3z'D<e&p`aOCZ5U5Q;B ҏ䜣p"77ad -XEf0qBu6"[\ FB`79(hn ,TҵA 43?q<W<yhG]sƍ61^-:]:�7�mXKgeءmKN7ٍi :PfB6FRF C�Z& jn@X$@fۘ1ΏtR+$}fBOd!ڥhI� $2NxJ {mɃj6[+7S{^ΞanY;_/ՏmI`mTvZ2#){Tp2n؉%B$&~8u[0hAaoS&b9Ty%` XG–Z :l!yf S"b6Q72(ldI.p#tEp�aZu/oc}Y,pǭy�5 0˔@R@o:oe'`8PFam/k&&Loz1&rh ܨT@X32 j\lRMp cT17deL-HAMT+}T$Z`*%S�'#(& /kڱ ۀ)+yO עA63OVoR`7g:lP�We%1[Zqj2nȂGT63SBd._1rN xCo":W7&ŽKWsfa _cB' Eg`\x4"^߿MѶyuEpaRJ9Drl`7�mX@0wx 5*! X80)K3ol6.�FmA�tMMb_xyW8MKvu/[ j_aSx[/rhz/_(DArMDbJ|6`$h 56rH®40ڪP| a늺c "yxPm9L ȫȼ"}D{J+K/XbHu0ŅѷIgAbp{,WXٗ'yxcLg4yKkIR$i*ABl.  TxCo P  !� %%8acj]N,!6(vbDRse!2wv@„E ةáfP33-Ւs ,Y$j=y⩫ ["Z$ a1S�&lіPzg4q�/ԗ�Cm!VQY! Һs{v4%#bz]ݵXvŜp%s6FZ A7Nh5vJ@D$E*߁& (pjđA*RJ\,s$${ ҠݹpPL l#t'5O؋%j a 7|)ge2.NMNdf\q8-^@A!q@ٕ!;44q0G[HcYF=r*HH�?c}BN3oL@o,?9CkF!$7˚-G&N"3z@WkSC(1ۆ!ے8#oNğB&w;lYa)xrOkWZ4ݽ`CYœ9u ŠmP\[qT?t)onwiJ]e"l@'s0#8*S1I Qo y+Ӡ)bv`|ŵ2t0IkH^} țe}#A)I7F!gJogу#6TY\/+glk"sF#H 6g^lmQ?MRCKF>/BDS]ri Cr|҉(oz+< hBy"waQn""ƀ.n$tZLA8M4JXHY?xCo𝘃xQ2$f&2 h"/3I.jQ$ [hr"ȝ� 7=fRZW6QQ,U`Ko&-mY![-\ P/M+8aҁ~@jjIdVds90~$XTo&夲wѫ;C ز(ẳ3TYK5 FoJOHIL؜(yI `q4xRkڱ N D">;ƽV'RKڤZN$AdYiŏ=mfԒTmcq/f"G�8{5735{z3$.ff),$g]dkN8H9!v<$Rtf"HΪKɁ؀�Hb�Г& [VQ[.e :/kp T*JJDnSS0 oOjMxCoۛ`q�tHb+g16چ˚c^e -HW4k~qv95�~WX4!83, ]3f6GV Evx m�z=~MUe-( E18-~eL#(Vª:Pnhg獦rN1ws?NX)YWGwMS)rŰ1]Œ߯re{`-KK'jǏ6A|4@' B*CbZz"Ѧqj82A6#&Z Ӳ4#zP}D )z8@G(jQWZqlMթ4i1p"d+C L2)<[|@ز\P"D^V!=.MRu+ȍlC`BZRAδ' 1a4A,zѡ0.zA:ER %)@SQn0i A|oDcC8-g63_kڱ 3�mXߙxCo|V<!zv_?=~;_/ՏmjǏ6_c~gkڱ 3�mXߙxCo|V<!zv_?=~;_/ՏmjǏ6_c~gkڱ 3�mXߙxCovT�\~q5\~q5\~q5\~q5\~q5\~q5\~q5\~q5\~q5\~q5\~q5\~q5\~q5\~q52jǏ6X(+r�` 0Py4U{׉^'x{׉^'x>Y�LiW^'x{׉^'x{^De: `bC$>~X06-3jJ;#$NSH[~?H. % @ U9c6�n)@2X�0YL~20$nh#?dIQe&&\>g }|&�Տm'�tjd9TTG X-bIx, cg�EI10K d;?jݼA9)t.`(ڮk* 4GGUbN " dU3c: LKƤ'_VZjծ~qG\.\r˗"jb: wn\r˗kë?clj\r˗.\r˗.\r˗.\r˗.\r˗.\r˗.\r˗.\rDSLX! 0`#rc%SWjT�ڧ?v�+O]WlB`@Ax;T�ڧ?v�+O]SWj@@aRPSWjT�ڧ?v�+O]J+$\x6ceQcLb evYj6E__NUJ(1zM'փa|KO*`H}As/�t,qu^ e|[ZtZ%vHkO;á4a+7Dږ*|E n$: Q k�.xʘ FFFD9abB"a1rpKWר1uW_SČ 9c)bIɐH.T( S$f5!�Sg1p4>gj[+}%uq"7.T0aBZ3As"Lj;$f�EC_-#q0|3K^-[Q HV=?V<{Ǯ,_իVZn1)bs/�'ϟ>| 919�ϟ>|dwIE_>|ϘudexH!БLOJ*TRJ*TRJ*TRJ*TRJ*TRJ*TRJ*TRJ*T0 R� �����#8��������������5$A G,,,  }MW<<2<;m><<BOo@($�b^9v׶3�|͞9 q^S @$B<<<>]}/A.}}}}] W rb|<<<]O�Lw<<<<<\+'<<<<\T˯?�<<<]S=sS׉<]{N#>8<<<\tPh'B<<<\/<<<<<<<\/<<<<<<<\/<<<<<<<\/<<<<<<<\/<<<<<<<\/<<<<<<<\/<<<<<<<\/<<<<<<<\/<<<<<<<^�<<<<<<<_�����J?����_�����( 0M9����G<<<<<<<8B[�������>篶sO[������C�0 ##0@1B        �)���������!1AQaq0@ �?5J=a#΁CB1qqqqq4&"9nDfJ5T&g˅3v_W}ݼu�hXҀ�QB!D"B!D"B! ؑEE!�xY≩[8B_2׊z\T (!*p� :Ru(Kg)oA/,VSGXBJ� 5QhoS5ґR߉pPA), ogzl8v/^CWV8Tkypk Z33:Fs8PfN� z,X . *7GUD)T%B�� o�^R,7#> ;/[>ҊA3*9?(voIǴ,Xbŋ,XbŋoD*snMթϫ)op?\Ǧb|a^<%kJ�г�)S(B"o_VNx-Tϴ;HP‘^ۼQ՝!qEkY@ ;3 K!SQ9پP x z\Ӵ/3,_]ypgaT 3XD8S^<,^88Ynqp�*h&_z Оě3搘G;ҐWZ2" c߁}t^ nT,z=7ʳ-(�0(WM}2="|m}tk8۠US~w[ peJ�D7yu|W{� A@;`ghS+3̣Z.C]SyR 3w>V�8_)s�}+ ^ /; WX*瞐~qrκ;BHӇѳ,w\t D:8�l0[:�ǹ ̧; vh?p7~oð Aax-Z; vo7߅Q-{H"�ێS� ~[�a%3'o| ~@(Ng=Y`v� Vg tq7ߐ-8�տ57c1f3c1f3c1f3c1f3�)�������!1AQaq@0 �?MGjp2SdS;;p2Sz1<xw1<xw1<xw1<xw1<xwiVF:gx Òx>]g^ H ` *}E/đ")T}x #c>Ԭ#N:N:N:N:N:<3W\5jCW7U1W9T&P3c+++++++++++/2!�XV2i++ "ʵr8II@I|qH(%lyMwhXeŠ!(CV@qw6><@@I |.;^A-beSp 2TKOZ :]p\a;L`FE{[Xt7Pz!L$Dˊf7IdedPϘ b}@R,^`uPzt)0Ϙ*`>a�(! ۾^Q}3cǀ͠kF�}G!uޒz}ƦOzߟ<xǏ<xǏX(TO>y^m!r W@z{L>C0k Lxc9:@Bj m~<Bdwt tP@,rH{c�P2 _!G܍.\A薨9Ú4 9ԓPdV!4s⏹t2e?cxE>jv\W۸1Z#�o`Ae<c Lϣ<gL UVA5D pOe-'$AaЎp6{ܗ' X,~5V":W7 Q#c·(65ӫS9 @9`t\(߾�fZ�D^ ̯}G }@Wc`ڱБ Ä"e€;i e+> �u2{btN �zlI4gx^f!C-(CiZ|njr@~O22#;u;>Î(DCS܃DR;.>3c�:^ ҸT`R~c^.O�WC,~ zސ�${jIT=~eë9ݍ=vzP B Vzւs. 2|e"$]zk<b& ORBe$!^{hشOW:"_2KA=?�V%�EȯRjjc z9jS GcXt2+?y] eWC,~cX$xD&Q2Le(D&Q2Le(D&Q2Le(D&P�- (f:p'e!FҰ3��~4 }DjXʜa0^19�? Dռ}hI%X),-u=h�qqqqqqq,Jk8@C#ǨŬ4-cW7ߺBϢ�:|0Lr/Aj蟽j(2CpĀ|Xa )XCZC[zO0"D %]PIBhM 4&КBhM 4&КBhM 4&КBhM 4&Ѐ��)����!1QA 0Paq@��?'vUy7뮺뮺뮺뮺뮺뮺뮺뮺뮺뮺뮺뮺뮺뮣&pJ!l,e.Keq+901 i;V#3`yp/yt׈QHcq5b ylFw&lod֜qʣu8ITH@D�sQz9񓛳:J pX&#;q0kGZa-! AX q7dI�UV*=7Iʀ# g}>^lW+ex}>^lW+ex}>^lW?g}>l�?g}>l�?aa4R̀3() I*\k(|brrADuiR@Ũr|r5?c"K"�LӴ04LJuB=*U lB v^_fbk !`#cEma)w$$DPϽZ0MuB8(|nԵ` M I (]_e_e~_We~_We~_We~_We~_We~_We~_We~_We~_WfV?%IJ 92 ;P +mHY wyQf͛6lٓrf͛6lٳF4hѣF4hѣF4hѣF4hѣF4cxļ)v[O M?$�uy}QGuy}QGuy}QGuy}QGuy}QGuy}QGuy}QGuy}QGuy}QGuy}QGuy}QGuy}QGuy}QGuy}QGuy} ^]NYN"iRM`ir'E)c}T,iT!M C؍@P uRPT@@0G"Ѓ !P@e$U(ᠵlJ[!&)u })Al2NǑ2ji�z8JG3f$j|B �U/|Bdɓ&L2dɓ&L2dɓ&JB`D0[CT<VZSWU4 ufZZ֗]Z NiR]clϥA׻[(< k�~O`&A_xI'PH" N@|7X lTT00Df+F,IM 2ZDhCeċkOoMVdɓ& B0kGuy}QGuy}QGuy}QGuy5ͪ|ZU"*?͙&y#W4`yY,LO 2p�qrOf%Tt޸p^,'/ƵufBQ FR[Cp�fkqH㢹D +07T6H.b ;KSq*D-_ϓ4b$^n}5-#(D9Jy@Ph)d߃ Xa^TPM1vJ5A@%1�(ABS4\?J|s G mƢNJHW_"Q]* SJ 8⇕CU89?ϥJ5@7N pHT5B8՚t-#RR�L&j;ہFʀD+H9L^]J訰 9p+F~-T!/ѺWPM54IC!"{P1ѧwB4YER6k 1R @29@ 4T"A#]- <J&~P@ޮ֛*$OPAhێD Jjg9 <Sdj$/i:(LxVL[ "ģup֔�⊄2eA RRѩ+b`` �UTTB2 H�׈RNPdv.7c U 6{TV!W!^ <Q! AulJ ҐxhFdt(ox T(*[+Plآ`&&�d`FxզH�@Mnb%(hb2*{KwSjS@@N iFZ2Z"1X̫O]&r.dDH tpj.\ gшIHG͐7 (K)͓(><(ڠmCjVe/,lGvH@;Yڗ-w[ڸCͶ0 hQOxD|?⵫~#_*Svv<x͑kIȪ)^߾6P)X@-́f+N,HT^j+:ϼ>γ:ϼ>γ:ϼ>γ:ϼ>γ:ϼ>γ:ϼ>:ϼ>VtSt"}Yguy}Yguy}Ywy}U+3wYguy}Yguy}Yguy}Yguy}Yguy}Yguy}Yguy}Yguy}Yguy}Yguy}Yguy}Yguy}Yguy}YguyN�q Hy{j }�0tз?d#BhVޠ[' rk j[Ic0riae!R (F4*](So"K*Ɩ wSo�:/1s"֍Hq#fw)U٠n�y� BT--fG›IE[yAE@ێHkUič}nSh7EZZ W՗fguY}gYguY}gYguY}gYguY}gYguY}gYguY}gYguY}gYguY}gY8TFi^LJ77s(j 9) j�]&Q\9/ȵSBMo(U{`J!enS!Hu$DkSZB6@z] aȪ*CֶZ .B!` >-tĐ andZ " 5NS(C{<IP؈pl�8ό[cIH ^alڍc IH&]�T#e)sR"ZGΡk�5-4M4M4M4M4M4M4M4[ ¸3'<1 ˑs>F*@ #(3TBpayA y �F\؟dU q[Km8~ Hq Sѽ5V:]B�]l p`N ԟ�D E +i� \!�¨;ؿ/aB&y!\ 4%1`F>iÎA - ZTWFRXBd]׌|Iﻏ xpDHjE`!%Ch1hXmDp{8 m 2´]5Sҩ9v� wIP,�#ƲYl6SB.Hub7XQ*Cxlo"@<c bb:T?/8] *Vd>H0ĆbMJ~&[ggSdoQX8!킚]j>gD#y,.Ua<XK)H< vb/ (h>ko)u�ou;/y{ҁŵ#Eh@,-bH4n-x%A +ZRSZ/!$LHi38@մ!5ha~]XA "*#u e-#sW$ܐ5XH&Bv|\%%((D XPɮ\j(+.$�i0QV?d(U5Ͱadt*+IoPK<&Mec4D > �:+:P`D�2d�i $FBxψGcp�x^LJ]L *>,&qlikKRU'AcL/Un0v.aWqB<eS+-?,g1m59dϔ@im g {B�)k/@ؗ(-B!-R�M_Qk,EX Gu|XqKkRCHpR~^Vữ~wc%3DE*9ĩkʦ5`Mf Dc Xn(W Hl# Yv`\x٥!- EFmc;48X6hX+!D7- |%%hL0lB'D]${0N(::r1->bG8׌|Iﻏ xqD i0:OCK QRHIvQs:ةś(HEl/\#!E[YkF0SZ&mAÐJ:U+[A1t>^1\1)`'am6QĤ%ld_�>†یX%Y7�|"TCǡ�/x^LJUWRd"5to,B&6 j%Д, 0DRlp `w.&=AKQ/&`HhG1,B-1glp))��0�Ax d<f<qHЇ A@(|kFJ xh|%0xuNL FT4\RQ c%0 eofϨOE,GU&HGϐQkh+ _7<q�n4uԋ5Q<h$M @ ӓV8hZG3#U´3I?}L *P 63僾�_9BSaZ"Y3LZ| O(g!^@h*(V!\#X5BJI!u 4L(Aj(Uh2ە4amm6y Z"I#|?Yt _e4"O( -4c�S!sc\F#[0n&ppef,JK_0 kZqL@+ :]A` -�`ˈ*w_dž<9A5�XUN5%4s,4-7M,X� B܁0]/$^ ` �8wG& ku|aB U+*BXڱ�L(GT'kR~_  0ťYX +B]xI.]*C6h�]rod>KA% dȋ+P'ɍdMsu AiS V8Z+o'� "񴄕 c@ 0OaP.7B} &f 2S"xDJͯА@&!PSDdx+sh:%BbA!\%>y™'DBᤷI1lʂ"uVV "tizH9PlFR`*&'ŝtB19WKp-Vp$J*{qأbbI["epSW:=!u1~wm'ʋ @\gm [QInEh1jS "\`ءVn]+9[@T塇1) r@-`$N< ;G@TܒRQ Y*G�"dU[h6f Rla[$d')sj�ʟ�+k͍t<ʑ8A>\KCul4p PJ GKĻ�$ %b@3wsMA& 9BHMهRNR R_[J ;@wrCbNHMB74RrQL!A -!Ik :Z] ^q t +fYVdcG.:nGCEk8d.h.Geg{O/}xcÏi$q@R)ߗQ /;Tbm|# 9&>&Н# Hi1R�p. @'Q( Kr�|SE{WDLlRrhs:I?(gB4@ !@_=PַC6%hUrnnAV_4nI!صkyB Z| W__ C" 8AӲ [ O~w7TIةr f qﺓtq d& bO'GpTpW&í(x3jD@L$tw,VҼ CW dpD͂cC\!y^h648o!�ղ- 5w(�jaʎ޶‰yʇ�!CYQwGRb4��; DM8&@os-HoP"0/[&Rm<xG�pf�E�g{O/}xcÎgy7Nߋq[ȥ$iDJxt A2)_* IJ݌-dbx33DG \�DUpRD� }lhAL#U"1L0*/ kKR PF4->]3+[9L@H Ar(0BTqUy0>uσ3Tm Hᑺ[Ht͚'B<I05_fzUlWFO*¦O):mg 5>$-.)[Z,ׂL'%tnG6noDb�_u;/y{_QBAVu-G "0,6Kr&6?ƸM6! Hy�� (/dUn %m~l4^JER-g m?BBqL+sY6<kEW/Y[Eh+ }Oke.^\VmK@` |6gp A 1Fw &Fiv1 %-P:?eHj8p�T. %琸\MwT󁰑+21!v Pg{O/}xcŎw_dž<?Xg{O/}xcŎw_dž<?Xg{O/}xcŎw_dž<?Xg{O/}xcŎw_dž<?Xg{O/}xcŎw_dž<?Xg{O/}xcŎw_dž<?Xg{O/}xcŎw_dž<?Xg{O/}xcŎw_dž<?Xg{O/}xcŎw_dž<?Xg{O/}x~Ah�4gqwY}gqwY}gqwY}gqwY}gqwY}gqwY}gqwY}gqwY}gqwY}gqwY}gqwY}gqwY}gqwY}gqwX֧O/}x>y{މ�СB (ZQhA@7L*)g뮺xjںp=u]uIm?G<?�/thMC8Z u4 0\ @Q^@1,i?�D!6R^``e <̠[�3wI*g!lB;*�fy$+# c4&4#B5PB_8viPR/�4wo>L~rhD6ʑٌ)@ȉ˼E-�>)iD*iy?G?.#doIiӡI /09^s<#4&fNAïX�X��>tBNbL?>Ƞ3LHt%yy{Zf^[g߿~c,�(rJ.\r˰O'14X0 .\r˗+B.�ﻏ/|SG"eVWD$H"D$H"D$H"D$H"D$H"D$H"D$H"D( $ _ ׾AOH)@LfJ*TSBQAnkZxPB  9nZs0Du[DT (PBGc8M~XWU8śJ?eB (P4Λ'!_ 9DAG9XR>E1Fu`�ꇳeQdN,(ß eW!DM %ٳLzpVQ̣MӮ.��^=P7( /  LF* G[(?0 �P ;%AF遢�;q^ >γ"G%Pyd`t>"ɓDA`4 �uy},rxٝSɔ`JJ3h6 L:^E+&̮@ b; .K@H#$�Q O&#K�aZH.O6] ,` p5]Sɔbe<)9W+ `q�ht1�MrL)�-D0Y8bŋ,NJGa8y*bvlٳf͛+ ~m6lٳf͍QVqɪ͛6lٳc&T~л<+VZjիVZjիVZjիVZjիVZjիVZjիVZjիVZ+L SV?����krb5-1.16/src/windows/leash/htmlhelp/Images/Leash_toolbar.jpg���������������������������������������0000644�0007046�0000145�00000013000�13211554426�024047� 0����������������������������������������������������������������������������������������������������ustar �ghudson�������������������������libuuid�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������JFIF��x�x���C�     �C   ��"��������������� �K�  ����!1AQaq"$4BRT2#37br&DCESsu�������������+���������!1"Aa2Qq#� ��?�O?ůdB*Kd)s;wST459t"ab:KԤ/e�ӉͱO$Mx¶ߐ.װQ%|)&#GmçG,.bB!!c /Vhͧ3l3\DFh*TL+1<nK)1$|( UTF@d.ʾ:r<än~%Q| %18FrAk r1̛ ¦252^Vsdƭ͸&=�&^s cq%5[+MP *"<k1|tp`ˈW6mZdovɕrmW9XV̫&wL'`nZeVWZNV'Z|(g`l)1/u܃JhM^D@Cr5sЩxe~‘BJHCAT;hQd|ry<ze2HwZ]Ey'|:gOsY<"!eo^B<tuGlw�I*"s^b1B<p NCs3甔G4+r-P81~>37211DŹTiByAh)Y d/(c&8p}0I zRIHky=DRs,qXr"'d-ɢ" 2 㱴FW*fk[1!:hK!4zC")򁡣Z3nZF' =|DJTd[5r |0D˳ ")o^)B*v@y\Ii52uE/wz߷[k\5iL|];\3T])Ub.038ydD. յv[ vGW3Y_D¯$l,$ -M{LOK(w3u7)soa!B%q@-;5 lz {o{}?rF"22>&&%xxEJ<⵮ZQ38?sĭBvԗbJ9$UG9ȷIy}hn0ʣT_kf% $jmSu18]-LcIxj%$<#fɮdQ0exx!H"\xþ@Qx/(&M�9^ XwCHT^C&CgLJ_@JRV׳N95> Ϧq$2G؁B)?EpparDFļc<R) :!O*PBBaܽovѸ@`<!/Aϒ ZQu NM�9Ngq+\,5 Lcب;kI@ʉS𒟄Gґjbv޷nyQ=}'pAfp6rGmk xK^rlRTF;k 1xG(}a]v Ή-aq63r%~$HDեjZI4ޕ΍ȱюq*P6,΋M`':/C'l"9Jy1}/"'1n sNrJMP4j>PqDQ8eqph%/U+~)NG:rmeS#bL ɢ,DŤ)⊊ItA4&&~1g NfPNbgQ.Q tRP mmէa璥m[c9W\M&*^xjAѨi;GwbbbK-篔Qv Q$Ԛ9ǜ:V۩ϒ?J y5lӒݖ�!�NM;3#0HE{A}ځɕ2֢ڶ@YxYՃ0>YUچfϵ4)#"{HE[^ۮCZnݧS*e׭V󇽫=c"/ogCweHy{}7+^?mݦy3�?N^fwc"Vj|ys#"|bHEg/~sOmB<3?ƚwn^*ۮB+S~4U<$tU,ߪtU}%iͣ S:_w`+Wʫ6!_lG-j-]m?+۟ф+Q^fWgE^4́҂ө/@9z)Vmv:B&?ly4p*l?рfT΋7c"%6Knt3#Ʉ+tUݟHEefzT ^׭w}*fWc"b٥gK4aJ!KDY]y՞z[[[=wWy}^�oWh�n)~gHy{6:B+H6P�?N)߿\aJ!s_LtUYU?NtL`+V~24ӎltWUY]څ/N4eU<BGHE{9c"/oov2 u0>&^Ufwjʕʺ:B+Rmד#0 Qz,ߪG^uȊ3L!#"%ic"<UY]څ/,֢ڰ<aɎtYUچ2u3р[^w49z(-UuݨveJE[HazESv,ߪC=Cх$tU}%YzK՛uݨRRN=l>Y!/svz}L!#",]9hn<�{ Wx{ڳn D=~"9NjyMm69Oma__~�>2c<xې)0{)R ד˩3tDRP\ҔҧjLUc[ȅFBUͻ)*IYh�<"=D:JV$u=qّv)T?�9eBRW arǠ($[@xDblc2r;r젒(+N4sE[pNUޔ%§0.!A Z=g2T4`+K� .RibN>>n=5= 枎.IGNb4s7O"qL[snԔJ(]G׷ҷSHepO!P'q3N%0Qq>G6s T!;А"\CAût,ԒMSĖ66$S.\DA%åy/ґl.qxadU:DI6T 5nQO<Gϛ?Iz.iDQҨ'2\%q:v}6!˻9/SD:b?|d;.RH^[C:'7®bpHz?ڊThjw|'qidTV-H:_ <CI޸_9dD|hv&C\} \3e6$!ի߃rǞHx}1- v,sP׹u_"߻)!l(mȐUuY!o�l>@m)ҫLE/.c29;xx'PɈm-JYP5$6mM=0>:ۓRaj! ߻›OULZR %۲TOۋe<GH8�Iz@QwAкwLnZX߻|*:rZXd+} 0%ܟa+\e+Rx5Uknw7˹lt!c5P tASpCv• 7J\HMD!8B-[)IYT7Im-!B?DQAE'qdEB@zn@4�Ts?tHQKD M38|K{ �HMi]O~'�\�CsǗ>?Z`"qq5t" sRaZV&yGHDg3ÑobJsȃvk)Yn'0rY6F=ChsQċm"<'q@d<'1H*׹n &,'voi;!:�HmM2ºRYKr,7?p]-InT +T!�ԖIId i"*2Gř4kO[ֵһ1Δ** :['d0.7qcN 4H`\{I` ]ӪVA9UD(ꓲ;(yiJ^czo쉢HHЧhـ3خݕ%U>١ck*+gnvlS}'glPTw?N;]`�Vlq $כ;6 �,kJqݑ4)dޅ׳6Xk_ ;[ǟնCuކtݼ%Mdhk�GooJ'k`\T6;ճ<M/ZnTvR=Kz6ZmvsVηzW}d_\TJJU~,gJwpc-)KwED%G4 @dP3]w`\Y5, FkWvVc-)Kvm䪉YNoDK$;zog|믵�ԤhSz;IA>` ݕu;evB~*;8v;Y?N;]d^o{]k¿f;,뵳fdӜ ZS>gƿ~=6v[N}| ֽɖCuk]ʰz05>F^3e]'k? d7P|cjUVJ;!dz|T)iUѲ4kWMOuu+:P|-$)'2V R�Ҕ7qc1}YPFd.P�ύuRݕmTh{!*>V`ZRnczoE,hP5)0|k_𩨉ٛX'4=†7}Z>krb5-1.16/src/windows/leash/htmlhelp/Images/Leash_debug_window.jpg����������������������������������0000644�0007046�0000145�00000035772�13211554426�025106� 0����������������������������������������������������������������������������������������������������ustar �ghudson�������������������������libuuid�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������JFIF��x�x���C�     �C   �`"������������� �R� ��!S12QRTUWq"3567stuAVbr#aB%$4dv��������������0�������Q!1A"aq2� ��?�eXq;o CzM#%>n\kVUUUJ"@:sn_ ۞PG+mTn H-e:'ۨ="UHE\7*䈉K~nv xzX4u9dHj�M_5 ճ>TMJ]S*V'# ti$vKE{GN j+{eu۪]Y j-2G#LwywMhͻr6Y+km=!Gntóa^U;UesUdk午uؙ/]kYayvgRײ%’EʉU3ju7NxF_}.>EMl:snhͻrvk͢iKzk/tJ&5YrTO4m*vïZ)hJK li#b{XQ]梢e39cS3_q-c(Ζ6 xzX4u9g6%.2%$QVYAQOQʭH>4rd\yr۽|1*i-A5L[ s[3#Q{Qܫer:L:snhͻrȼ:A&*%[lOW MԲ"h2V5ɽ�EavuVhvn)u:xެ&\5ʨ ."wb>v3ǰhͻr6Y*(WGn[u <GI*+)*dZ׉voFǬnmvj˭I>[Z+jֽ J`Y=$ͫUٮiylr*?~圣w_t\۽g,l:sn6-nd]6Ikw@TKK##;Z6DkuUfV5nnZ,ZͣaXۭ$QʌԒV.qLE5s115_Ώ`׋w千G^.m޳BŎ2LWZDvu,Yu-PmմȮ9Z3k%*"ĵǖ6Y\۽g,?O0?O0u,7`׋w千G^.m޳Imm^:ϒѻ\۽g,l:snKh׹O05S/gh݃G^.m޳6 xzY%kܧm)n6Y\۽g,5S6{ YZ7`׋w千G^.m޳Im)Fy-hͻr6Y${ ^<|4u9c`׋w[Fyѯrax>KF:snhͻr-^<h׹O0u%v xzX4u9dѯrakܧ^:ϒѻ\۽g,l:snKh׹O05S/gh݃G^.m޳6 xzY%kܧm^:ϒѻ\۽g,l:snKh�<h�<|4u9c`׋w[GGn6Y\۽g,?O0?O0u%v xzX4u9d�jy�jy-hͻr6Y$S6S/gh݃G^.m޳6 xzY%ڞaڞax>KF:snhͻr- YZ7`׋w千G^.m޳Imm^:ϒѻ\۽g,l:snKh�<h׹O0u%jFԐI<=E mWYLUul)RCPb<fX&#~|uBX.+QK~aEڧTUYbftj#8޿m69jO6~NQ38Lr;kɆzJq')o.lINSUꢹ{Wjr]l-K|jrs+jÖ{ڑ9J1NDkrikqeUtpQ�s7mm9�תO}f˦3<.qW7\ Q? "d|Csۻ%'~_Btm_w.{lNHhV]_lZ[s%$5˚vflM,bѶ8۬4Q[mw:g=PLݽ�*o{I]/2ssrzOwf&:rXn{--&tkb* hI&\55LWC`T`3$u4Wy6R O'#$kUD{uF䞓~.^dnI=/2bq8ZsO8b**߽4c;%i..`|Y]T=|ܜUUZ�{_+ϣf ڒmOJv7[W=sxwr#uI<;y9c9Xs?,;HP5F4m0alVu.fzFѻȋ[$]vKmlT4Tb:3GC&zl\]V$zv?uI<;y$\ɟv�ٟg֢kB<]>4h_n* *_SLԦgEmU{L?eph>c<m,mem2WTUy%m:liܺjvHxwr'H1Z8dR*zY.U1n?^w߯#$S:qW5]ŽD)cDk&%�qfq=ެOZ6EXn[_ȑ74LVԢcj=)-Z$3@lI=/2g,w#W_~iɮ38{ԏRN' 2Zq 5S,F9Ijr#w.wf¸U)ܳ;Ui!u3I5[Yj�[ٺ$\~{.^dϺ[qF?�/?֑0ݶrTb$wY \L$as^v#DEM][Q\lx~t;1 uZUΑHUWf{yI=/27_ÿ5ƪ}7k}z9Nޟ<tqđ͖QrϠU<{.=GO#ƣw~{.^dnI=/2f#(I/s /sOy̍'L*{^^!7_ÿOy̏vT&7BnI]/27_ÿ`M{n{Ȅ~.^dnI]/2=P:?:? %w\~.^d{7u!u"uJ<;y%w\kBopCpD&xwr#uJ<;y ׹׹M+Fxwr#ݬ ïs ïsWy̍+GX*{^^!7_ÿWy̏vT&7BnI]/27_ÿ`M{{ȃ~.^dnI]/2=P:?:?%w\~.^d{9u!u"uJ<;y%w\kBspCpDxwr#uJ<;y ׹׹=+Fxwr#ݬ ïs ïs{Wy̍+GX*^^ _ÿWy̏vT'77AI]/27_ÿ`Nn{n{ȃ~.^dnI]/2=P:?:?%w\~.^d{+3j]h^te0ݨ{P9,toF*uz"}g>j&HݼiZynh%bHU*TQS`*my#>G=F^ϴܑ?7>g(z߃|W-z2so˴Spwm0ۍ[=}f_iΈzdLLDgF"7G [}_LQgߩSۮ:߇lV-uš(g2UYY.0FyeK�z=<ߘQ=kjs%PzЏͩ~E bք~mKV(M6Y^9lsW%En)4;h[6hZE_[l*޳!mLsN Ӷ]M>E_sGzto4;he٣Ug::4}7FLsN Ӷ]M>E_sGzto4;he٣Ug::4}7FLsN Ӷ]M>E_sGzto4;he٣Ug::4}7FLsN Ӷ]M>E_sGzto4;he٣Ug::4}7FLsN Ӷ]M>E_sGzto4;he٣Ug::4}7FLsN Ӷ]M>E_sGzto4;he٣Ug::4}7FLsN Ӷ]M>E_sGzto4;he٣Ug::4}7FLsN Ӷ]M>E_sGzto4;he٣Ug::4}7FLsN Ӷ]M>E_sGzto4;he٣Ug::4}7FLsN Ӷ]M>E_sGzto4;he٣Ug::4}7FLsN Ӷ]M>E_sGzto4;he٣Ug::4}7FLsN Ӷ]M>E_sGzto4;he٣Ug::4}7FLsN Ӷ]M>E_sGzto4;he٣Ug::4}7FLsN Ӷ]M>E_sGzto4;he٣Ug::4}7FLsN Ӷ]M>E_sGztoǮ@O}Z_MX.Mk--%HTbUsʫdD9\i}W7na|f(}]-ڗꭟPzq)gOm~mKV(M8?Ӆ) 21g`!] ���������������������������������������������������������a_cO}Z_`찯Ͼ_g٬swn+=RUoN?E8Џͩ~E Gtpe<tz!|F,2+����������������������������������������������������������r8"�7{,+i}W,a4>ի5wnPzg#j_~Bm=/[?h6SΞNӬD3oŝ|Et���������������������������������������������������������G|d_e}>O}j|>2/w¾Ɵ'>~]fPٻ@~mKV(M8?SB?6g&ޜ~qiuv oȮ�����������������������������������������42<uwg[de6ImMSlHjs ȫ׽ûG|R\mpWeE=U4$SFG5sUQTTTT\��������������a_cO}Z_`찯Ͼ_g٬swn+=RUoN?E8Џͩ~E Gtpe<tz!|F,2+���������������������������������������� K?/�t,M`a|}¦HRiY+)_1ȬYjdEcU5Ù>;_U/؆hWG &h#sdvoGONU_ƛ:W G|R\mpW!eE5U4$SFG1r*ȿskUXsW*$/IIzWM2&H=JܲL@�������������r8"�7{,+i}W,a4>ի5wnPzg#j_~Bm=/[?h6SΞNӬD3oŝ|Et�����������������������������������������b~ۋM k㯣vM,c=d]IS5I@���������������qEnXWgVX8"�7{,+i}W%k/ yhGԿUlӏN#:{m54#j_~Bm=-YOg`!; ����������������������������������������������������������0ȿ |l |d_e}>O}j|>e?wY-ڗꭟPzq)gOm~mKV(M8?Ӆ) 21g`!] ���������������������������������������������������������a_cO}Z_`찯Ͼ_g٬swn+=RUoN?E8Џͩ~E Gtpe<tz!|F,2+����������������������������������������������������������r8"�7{,+i}W,a4>ի5wnPzg#j_~Bm=/[?h6SΞNӬD3oŝ|Et���������������������������������������������������������G|d_e}>O}j|>2/w¾Ɵ'>~]fPٻ@~mKV(M8?SB?6g&ޜ~qiuv oȮ���������������������������������������������������������찯Ͼ_qEnXWgVK_9ٻ7yAЏͩ~E GtjhGԿUlӏN#:{m8[N:=C#v ����������������������������������������������������������9a4>ի0ȿ |l v};7y@f(=Z/[?h6SΞMMڗꭟPzq)gOm iSG7dbC"@���������������������������������������������������������#>2/w¾Ɵ'>~a_cO}Z_.ϳY|f(V{B?6g&ޜ~qiRUoN?E8m:xC; Y7dWH����������������������������������������������������������qEnXWgVX8"�7{,+i}W%k/ yhGԿUlӏN#:{m54#j_~Bm=-YOg`!; ����������������������������������������������������������0ȿ |l |d_e}>O}j|>e?wY-ڗꭟPzq)gOm~mKV(NHf`bm]k<79"fwWxm:x輙7dGJDc c"@wK3wK3$t#=,|t#=,|b@wK3wK3$t#=,|t#=,|b@wK3wK3$t#=,|t#=,|b@wK3wK3$t#=,|t#=,|b@wK3wK3$t#=,|t#=,|b@wK3wK3$t#=,|t#=,|b@wK3wK3$t#=,|t#=,|b@wK3wK3$t#=,|t#=,|b@wK3wK3$t#=,|t#=,|b@wK3wK3$t#=,|t#=,|b@wK3wK3$t#=,|t#=,|b@wK3wK3$t#=,|t#=,|b@wK3wK3$t#=,|t#=,|b@wK3wK3$t#=,|t#=,|b@wK3wK3 qEnXWgVw:ѽ\rS%^Ҝ4>իl5wnPzg#j_~BXuRU8{OO� ������������������������������ �d2�C �d2�C �d2�C �d2�C � � � gVOgVmX9ٻ7yAW{B?6g%WZ/[?h,S�$ѭʒ[ DlGǹtk9wXlHWxtؖчz/ ٺmkٵjښMl]mdeL[xv[. iiu V6wS'ȬFM-Xz]W$8.*]OhrPMhLב3yURI}Q'C8ٸ UWHJU*͒^Z$Qr*yr7b#2kͲhb´L`M+esW]%TDUMPMIxWT[CUfD9cr"ro9ʊ#RKpP<͑Hz7r""YOgHlSl*mMΎJGOShmU4uDŧUʯ.D¸ ;Ķ;xfk]6ͫUtrkek'l gkoYn}U^t4R -45cbU&z߀E!y҃m(,jjvbJtkY1i#d4rTD�RZlՕPDcO"1$k#b*�繭D몹7 x/Ixuv-WEcG%C(9&H%Q5FIǦ<gUh-]}muxktQ69#kUZŊ27cܡi aAEbk=]жں袩zk9.jr4M.byVhVh.%K4X#df\G&/SR͌Ͻ#p|Zgڨ`Ts}K^ƻ]sȨ$W(U +L$6+kz֬o"І b,A[bbk=CVJz1Q&JqhlV!]6ݘf:h�6t92NtQK5һ6,=VxՈpXbr:C[}um ;q漢DEցtW;Uْ$W,c鋅7[mYO^>/dm~]#aDś5t3O>[F-[VQӦF{gnt>/f|MN�[W-竾u:8Bmk3Ux>QQM2SoȍF*W&)sF#aOukds+3ҦĨIlsW?^*;KwVkz'j>G瓵#r_j&yU �fI[÷Vzy^daEׇRi#=jD+!eŌΉ5u+|t약[DبzU5jU;Qb^!l@L(_TF1bGkk5,UsNvР?oH|+,8)LF]m*W=PGU!j깫MUuAot"E$sS$T>F:9g'Y-Ds{*(u1bKMGClWJ9:*Z(5'bl,-Of.S}67扪li+g棕 )ΆEc^z'bG.Oj '`[ [텱]dӣ!Һ5b.Q٩5:9ȩM9_yfpحu_֚&QPwOQGQ�,|#ձڑj8=3Kr zgT8G:z1蝋d=T6O [1 i*:]W[$M%|rS:$~ylR"*RU\ȋq.qNUl^1}5}Udm쒱dUhVlz$eʒK DlGǹtk9wXy;iweoxqHoK 7i%d&=A ؋vV;bK F4OQܫ0MX־frUk5θ9ZօѺ;Ja:=n- .ɞ,Ȏ b?[}k=CW*Jb=$rTr橒**zD·Gf%\.Z|-[tYihS,kcdMkr"1Lo-XbK`Qް6{vGB稪֕n ,cdE b+mՉ+%E\+Q5Q˚HLI B|S:DI${޺$hȯn}t("i d0E%KO{mt집<N lTq'[;cXngX$ĵ2|Qj'dX娒ȱȯ{%kCXzL7Q}jY2کDrwiI5ȶKÉ^esI +e(bl2:X]�R ɨt5uCU-?<�!{-4Mb"nom}I4tbTի&ĵ ?<v]]L9gouhzx 1Nޑ1Q$Q{\ 4uƂ{o+O8pv#V)WeuM;^Ȼ{Po*e'SE_㬧Z<*3UGZ|'* uJfUʈrU\#Z'mU�gYPtdP\UG&Yu|=%,PRQm)z2Y"]*:6\9bKoe<I]-ꖦ ț5BŪǽH䈈~wyLh&aULlTHe{UW5FrMvɞFWԞr8[Jr|s7Vj|W/Me,!r[$*SIvW,�~jd7cA363 ebս!DY )=V{}u2M?z\MYX׾*F+VEcDULurovZY壒 hjgՆ&oDjz|%LrEE"hi[qgH2Ϋ*7lKհU7cA׳VIQ, d{$G+mGyo+O9:Z9(H΁cSI$WX)ruH:*]KmUL3Uw65%/(ʟ}?h:}<丒*Or΍ңS5-V}d{S�g)eվN;`sY^繺̃�$n&*+au5~S[SR%t_�Z͓-{&�4Dv򿾤󍼯<tqY=}MS3qב 7�"""$D,U" v(U-�1��BY7<~WԞsZdSQ*GQ\9rFUWyt`zKTsXh`k6Idcu5TDjm \)cpK\Ȗv]Uv%ύ1F5#VFke<5&'|3$2=Ue{䍯Hj'{#t#)b>7W0 E7FVPnvnfh|,{duZe4,ֻaֈnƃ;y_Ry< U+USѵvsO3!5~1<QTk=ҮYۍ"KBj!JwQRZUFLwD-~fDD81]EG 9lAk/HMSS$Okڵ΂&S#V7cA<o+O9h8 }M~$%rrrNfv{d4>իx[g}NcO}Z_awnPwЏͩ~E bj¸~J;|Ȱ^mj},/욡k4˵DzwY(8<2D,EkUsTE_CZnoedU1:g*5Ȩ;%sU}:wY(8uiɛE4fdurTUjw*1f~UV[U"+ܫde]pPqN7Z=p.&gIVW5DU�+n >{fGEL3,/!]pPqN7Z=p.&'AwY(8u8y $<µsTERfGn >{\,L"" u:wY(8p5S<LcU3$϶W};}hӺA֏|<D\L$N7Z=tpPq"a5<>FEuӺA֏|;}hȸX;n)*Sk+l$1ŽUQrLjgN7Z=tpPq"bjiIBfGn >{\,DkS&]bfGn >{\,4cS�j"dwӺA֏|;}hȸXoY<X/ u:wY(8p5S<L]tpPqN7Z=p.n(Ǵfw.ۥnHLUE=LΛt��FN7Z=tpPq p.]6�1WKMU�Wu:wY(8pM b+dQG5rT뢢/zW X*_ij&yꣲw~n >{fGek?*iO1_jpPqN7Z=p.]6�1WKMU�Wu:wY(8pO1_KT#$ܶ(W=G-UVjoo.NTfGn >{\6m�Lb&t��FN7Z=tpPq2ncq4tۧ\M/5zwY(8u8y t��C?*iѫӺA֏|;}h̸lh&MCY@Ե0]NdV,Q".IlIJJ;c:·c!t։֢.Md47,4Vu:wY(8pO1_:m�Lb&;}hӺA֏|<ˆMU�ncq4fGn >{\6m�Lb&t��FN7Z=tpPq2ncq4tۧ\M/5zwY(8u8yj_w[eIU "Gӹĕ97:鱧Ͼ_zwY(8JV|Dm'DP[˕T5wbCS#suX]N\2\<0P/������krb5-1.16/src/windows/leash/htmlhelp/Images/Leash_display_window.jpg��������������������������������0000644�0007046�0000145�00000234104�13211554426�025453� 0����������������������������������������������������������������������������������������������������ustar �ghudson�������������������������libuuid�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������JFIF��x�x���C�     �C   �w"��������������  �e��� �!1"2T#AQSUVq$3457WuvBRar %bC&DEFst(8cew�������������7�����!1AQ2aq"BR#$� ��?�4MkņUnZRZERvϭ%dϷe:u93鎋Nb?Fk_tx5hnί}Kv+f&I22"Ax^ybSL7͝LCl8tsNg :ӿ[:Q ]X<d'K<..I8Զ]/⑳f:9ϯ4g9_YDZ|ӯ;L84sNgkmv5]b$ا)Ht84g]^ vE-f&ߧ3-hKr yϹug~ia_w>/-[-2_)wR\ePlKyZf2g]{Le^xErM NFm|kz%*4 &&gܜTiϦu93+`5Cfٮ]p*TR9z3ȋҤ{O;�V/3>/,ǃNG4}0ӯ;L` PsβcӠ򸩎Us%93|#7H�aQKr2m*JC"$mOz$_-3L^9yXUu93~icrܸJvHV [RI2Rdi"&,S.knHUW3q3fƘی{J2N }"&/yOupӯ;L84sNg^h)E***kݷwWfr:{ڵ-td.DD$"mFxVH˭9!WE15L^r鈅NG4}0ӯ;LbΤ[nب4 FŦ˜:Qi]f27jV!̖VHoi/J ;.58Jɗ/;6xNG4}0ӯ;LV�C[ L �Z~N=Γ{3z TųZ+~ia_w>_4Hdb3~̶!,dKr{׸JҮ=Nz[TXsuGQ4Fx.βCzs]sӯ;L84sNgYӝbO}KnJJI2? Ȓs~]v])SMIjie%WE^6; yϸpiϦu93m.+s pR'Z)kN8fIdI%o_.WL&4ŽqJORR#!7_w>piϦ0ORZ\`5ި˟)iϐ2hYIdu2[`Ďs'IABRl̔Fim#IiLL|36~iϦu93+GՋίm\Tr<5NTrNJqjJ oi6I� DX3IuME?2LN :ӿÃNG4}1IՓ)EiIh+VlLN GfI2IՓbSEiIh+VlLN GfI2WEV~O{g+߇d_w>piϦ0S)vmZU2Pʐ1Q+8x<n4(V}ޕ{Y L6JNG4}0ӯ;LGRueLJrqQZrj /պA5;0mH5rLnkԸ+ըJ[.AƍRhQ/ A:JOYQ"*sܟ׬̸4sNg :ӿ=vk^ޫԛ~=QsȈ8Nt)mu R-P/Jԙ ]ݴtJ.<3$([h4VJ:;ȃzgz?i͸4sNg :ӿ9c.jDSAiRdd\Smq4Kaޕ{Y :}u~ia_w>J* ]E_w>piϦ+{үk JQpiϦu93;үk >~\u93~ib*/Ou~ia_w>J* ]E_w>piϦ+{үk JQpiϦu93;үk >~\u93~ib*/Ou~ia_w>J* ]E_w>piϦ+{үk JQpiϦu93;үk >~\u93~ib*/Ou~ia_w>J ]E_w>piϦ+{Яk BQpiϦu93+;Яk >~\u93~ib +/Ou~ia_w>B ]E_w>piϦ+{Яk BQpiϦu93+;Яk >~\u93~ib +/Ou~ia_w>B ]E_w>piϦ+{Яk BQpiϦu93+;Яk >~\u93~ib +/Ou~ia_w>B ]E_w>piϦ+{Яk BQpiϦu93+;Яk >~\u93鎩NiȑXi&p$]~w^Cjg<OxWQ3ղӴa^6]O䴗9NŢ<�hMԽ!dtiE� -۪b=,DZYY2)2Kr̈9SWZLUj%Zy,N.9)ko%6Be3[ljw϶ίvjvzliϒ{iNm.=6+vnIQ񐤬p}Y`h1x�WQԬn>gajIn8qW|;4l[V&}ٳ|-]<~j$h$S]ELfKrU_]YitT7QJHtԤ-Ol3VœO_Q>j[.z>My[yI֟\ Z?Ido\l.&&'QV%w鶣gRZ=Ғjv;[_�'K˺lsE+5 eq7!<̔lȰZ/IdoMkFhbc1<q?{/:so\(uf݆zM օSDI3B^HԡMS5BRە+U6zi\)lf Yqfg*2MkFֺ=Ido&"#yǗ#u٧g#ONkVhL\Cr[.7,y4'#{ٜm #5=JTzROCRHӵJIHȔʈgSֺ=IdoMkFѥyŕ�q?&T\jKϕmEcvB;gtgs~mtI).8`~c"kֺ=IdoMkF]ڲ|~ma܇uT:țm[-Agi#,61̗fצ*\r> 2O@C3[^\tFO BZqn5x~YCZ'呾DQTZc i'^s-ɩ7ߚ#Q&Ejt鴈"TKyqo{o-$Ddϰ=Bt3h4Ybd*4N2WVYiid>h5x~YCZ'呾7*DpQx"=jj9*4S[r)Tam/I㌤%/r $i.[i.j.hC۴iZfmhY)96s~G ?,t{Z"pbc4~1U'oi5-5nHMjh$)92IA ̜AHe[) K3S2^q~ɴ}et{Z,Yur&j.c/K %&'|#$YW`E[ǜb+6w|zeIuWe!t^)1P�+sKa̼hQYVrFEꍙ{BkzL4ȖRpu.ȓMI`pN\Z֝>}*_ZRQZ'呾DEwgƱign7jk)ͽXieTTPlf $A,ҳ]lʍkr-ǝo&Pf:GWѝ;t{ZG ?,EQFӌp5[gGu.Θ+Cz֨NrUq dK+lRLI$Ū::|5+^Z]SԥԪDyR $ '%$DgG ?,t{ZEU^gw11i]u;KGseqĤ鲘=6mOoi) q=Y,`I oYD-d6s&]T ԯ g]EgK{P&Tc"*\lrO,YzrP>$)Je""? 5s56�)2io׶~KG T'̶ڀA RddJI`�׬MLؓi5f݆ʜPԶxЬ8ii.9d<m/ 9MkFֹIdo 33ZmUh0-'Q(H~+;_nS(Y^n.`̌Du[.GpiuJp]<zk7^/RHs77#Dd>}5q&}QZ'呾LEQ45~;}:zgs2^!,MhyPAI6;IާFx[`xK$=Fu&ъ)&٧w)=hۏ 6Z'呾=5x~YEhhݷ q�S^7�-on UnmvN jPZydY$(J2JO=Y-+![Hu>G ?,t{Z-LUM;?M[k3jl9+rCiYV]mwrۋS'["O6RTR[Sǝ"2,u$$MkFֺ=IdoM5Qpw~ LPfv/Zu6ȍnbUT҉WT8 Kmy23< H=W%lYVFLdGKﭳZ IYf{[>$Z'呾=5x~YEw*|ƶ˗(LLcޓe w.irmΏsU9UjUR_m:$%z]= G ?,t{Z5 �_= G ?,t{Z+j2s/MkFֺ=Ido W�!~/8zk]$7ևO#}hZ  �!~Z'呾=5x~YB0d �_= G ?,t{Z'?AB �_pֺ=IdoMkFе}L9?ABÇO#}hzk]$7օ`A�pz?=5x~YCZ'呾-_SN~A�pt{ZG ?,j2s/MkFֺ=Ido W�!~/8zk]$7ևO#}hZ  �!~Z'呾=5x~YB0d!^_}k/:5x~YCZ'呾-_S!^_=+MkFֺ=Ido WhvzWA ïZ'呾=5x~YB0ZeBpֺ=IdoMkFе}Lg{Y~k/:5x~YCZ'呾-_S!^_=+MkFֺ=Ido WhvzWA ïZ'呾=5x~YB0ZeBpֺ=IdoMkFе}Lg{Y~k/:5x~YCZ'呾-_S!^_=+MkFֺ=Ido WhvzWA ïZ'呾=5x~YB0ZeBpֺ=IdoMkFе}Lg{Y~k/:5x~YCZ'呾-_S!^_=+MkFֺ=Ido WhvzWA ïZ'呾=5x~YB0Zeml+H$\OC<�}5x~YEjk-Ɲz9Rd|FJ"2?d1(&~plxN=QxiZt䶭h.ASjI%Kج#Tj4)j-w Q3' VOII#ns</qoO�>x^^)�0ÍeoO}u~WՍf{g7y,^bɸ&%*,1u&tHSժ̖:<fv6}"H0ܞ~oFٶbmqS2�Ž�pYejȭPQ[JU6DݗSS-8T&37^p"5u ֋Ub�83]".<VW†Qmm'מ?ޙ_|xiA]M6s) G%ç1Т<L6X[ʵx-ē2+NS]#*;֒ROB:Jt;B"Cu %Vڒʏ()&ddFd$;vk6*Kq"R Jr} [[+{zX`FrK� 5B35M^y3RbtDlA7$DRE૯8! ޖt ݑC]6J9 +Jͥ(Vݪ/]&e•jS?*KC[5uێDyҚR kCm[4zDc8ed?Q*>Ij(5JY˒uʐۤܿ_R DJUQwISCORɪˏ]a$騒Jy2tQ=J%j>ʐPۖJ8Ěxen"JJVxFF]E*ws jQjŠ[eI0Ԇ&4JR LFn׵D1juK|kMG/xtIG]>Ms2!+,N8ڈҴ(+>޼HdJ̲Yߟ[ǖZYM|22JɦpEO=f}~]X{?4-\*.Bn$u!ѷnIT$ Izj4H[ɼ*Ŧ AĈ8lr}ke)S[YfehJHWȝ#$62=Х>pF:nNUV􈊅4e`57I7`,ӽo(Evi]m-U^s؇yҔVm)ؖVw+ <kGdP̆+jΫ>O6aDžIw))A(<i* =u䌪5q\{EtiDzB <hJy$4ffۄ*@W!j-aEV$0+i RuDg!KfDgׂ5ǤS0.J48Ks)Fql-Skh !תZݮiD2aѺgrV+i;'$yQhi~mcie-;p[ qGv]\59KJDmY iJMFjܔ''}"9# ]}r'Hk'r >ӵ%9Y2focF$Tܥ-[撲'4|vnmUVUNU>ܔK9L� )k&BHҘ!$)3�-;OV֟u{EJh슊RY;Df<R lѸ#:&RvZͼ7L0)L R\&IܔH'6;{1& f ZY/ xc.CPV(TvH/SF7mWY؍#|4zjCrĈmRBlq>DxHmi-jWbE ZN=ҪPل E(h4K#Ug&}]yZ}]5\iS814i,7Rҥ6%\JA<*�YM/\?9bwCUCUZ[X pܹ,nI:NaJ}4ׂ,Csy'fmRm"lI1(IStx!wy8/j$̄7bs?��Q ����������������������������������������������������������������������������������������� 6�ߴAu|#{�~ұǟ ͤJIR"7�&-�%y_1ĭu*nلU_� e@t."3%q&^mFEXسjitsƫv}Ԩy_f Pp-ET4xtϥDΚ[hT�Wމ.:<b.Etkxq)+v4&y",u�-+MUX\Sۄ0'wOcT</}Ԩy_fm+Rk䮬NS[KɶOQTu]+%5ڤ91eN<#qc$DfE9É6|%PpR}ZYuʍ*M)*9Q>dɵl+qf}x;/[Gm4T Yqx,i"""zxm~ﺕ7 u*nمƉ"cQh% 㒤^,:ꚪjH[C"Xe3R'M#K/Pr_;C0lwJaej#W FBjܑ%1IwX2,g'd9UkáN>1S08Fo(Fp###>Չͪz6L}Uz�)cT</}Ԩy_f5n!FضiڛљgbҘIg >on=OpUCMykl-q#"nnij]PpR}WђJJVDDeԓ21QՊvEj.m0Fkqi[ܤ(8x SRR\d,hgR}6;C0bJzTSDLTVLR%'0OY5 J>:egܔHUSsbPF7VDJ4[FfՂ4(S4L^`JR}6;C0.TbDJI22dw_֚:QTyh1QY59%r$ǎm1 BK=j<=YlwJ`ﺕ7 2kvڗ>۠JK'PF iZ `]GK%Ũ_q(~C /UʛRN:dG^y";C0lwJas])T"<0j2iI%$y5(ȋ":G*y!5i}%)hOKJ5Li#="˄4n3ﺕ7 u*nم,yl@:EbjzBF٩)dd#,i(zmmȐߐ63:JZ&R}6;C0GPpR}r�v;C0lwJa�qﺕ7 u*nه cT</}Ԩy_fPpR}r�v;C0lwJa�qﺕ7 u*nه cT</}Ԩy_fPpR}r�v;C0lwJa�qﺕ7 u*nه cT</}Ԩy_fPpR}r�v;C0lwJa�qﺕ7 u*nه cT</}Ԩy_fPpR}r�v;C0lwJa�qﺕ7 u*nه cT</}Ԩy_fPpR}r�v;C0lwJa�qﺕ7 u*nه cT</}Ԩy_fPpR}r�v;C0lwJa�qﺕ7 u*nه cT</}Ԩy_fPpR}r�v;C0lwJa�qﺕ7 u*nه cT</}Ԩy_fPpR}r�v;C0lwJa�qﺕ7 u*nه _Zn >2THǂ#l�8�Ny_ߴEu|#=sgSx4c��#MM=?~fer-(%Ҝ环ƌ~Ub�8%Zj gDY>RfZ83?cŃ {&, -G)NJfmxԣNO8�^$+Ϣ=Y-iɉef{VOJZ#3!D{VA+&G [ 3/\%U0O!Dm+$Jb)e*ׯ~M)TfF :.xJ2}qM\:fjfmhd{f6݉MJ_RQ^Dy2gCqVD~sM],'r]m +NQ?nK?郝ML>+ tJ[Jq䤜OG֓3.HGY0nZ[iI1ʪ0fA4%D[Ϩ֫1&˗S.N&bU5^bi_;@*\xV23ΏR#4+Cnmd"c筈6gnR6%m"/\.[ kT^l+Hr! ke5ug>ukW\t6I!j'1DCx-RNX* EBT$y۷)?]XΦ6 Y*]Ҝnr7%D}̈f0J= MCQ(P 5T%Td8ImI>ݤJq':+C,u V Wwj"ñҢ5TSeH}iIA6B<b̽�`k k\FV.)3NiSC0RDoIVRj`l>M^13Fwз]-8#/C u-řOJDl¹4!xYa$VVSx\c>蘬*!"\OSMB Ð`,1e*8ȄqSTy 3NC"RӖjDfX3"32'KT|Yw6Qj٨<w62om».#PoDuJ"d*332Oa?<mg>f{%'��AB*hߤj̔*,kCLjD)x3Q6ATfm"I Jq)KM6ӫ[<%$HQa 2:ܯDTyBv[adsv] U\bfkOkUW3!-@isܻb| U8s*fn׸JQ#, B i%VEA/(C1ᨼ"OFʹ-PPnVފ벦m75|RV]FbEMn6:4[ffFҌZfg1+�E OMj�ЛzS+O) ;cZIH:[9Qu¤_+ON뮲IuUbT o%1Ҹ,zK=?Nt.RН[*JRdfYWR��M%2uvi亪U"�1ȭe>((+o��_m,GLoL̓L"ʼn*D>&_wfΐDFGIZYHյ &VL)5j6):_i7V83ܢvukLʾKAoAzkqm;-nDDO7eꩥ۶%z[rQDtELaNѕ4ڈYIpJ_uJ7J3)~;_o�znL^1<:�.9XvɑmT݄[mnaqdvc)?ū/#;֍f[WtKܕn'Bmdm3Yj<eg34qj$^fJ����������������������������������������������������������������������������������������� /#|y_ߴEu|#=sgSk;Fhx/˪۔V=KJg)#>2?[ITEް�PR�<6*QGɟ>K0iO?&Cm63R֣JHx1|sh9u/_IԿ#~U'g&ّ)\$ pЂ?[`a_ڿ*a˩~GjOՌ[/n:7:La1,9YO_p%\kbvʤXr_ڿ*c<*Q*)R]q8Ä IZT.4Y�9u/_IԿ#~U'x�0>]K;WR~9u/_I*Ӥ?UqMXe$rdEdȽqoԻ"&sR+JT&]9䄶nTdk&i.IN]K;WR~9u/_IʩDFdf;6#6넕>!K4 V-X.!GF*@`ڙvʤX˩~GjOՌ9@`|vʤXr_ڿ*c<T5Pf2ϴڌq kJ{M)7#2#Zs@0mLKWR~|Կ#~U'fG*DU9Y!jOi%FۄF}FhV; b}g*]2fэjjʏY, ^]K;WR~9u/_I&1UT)˛TiVդ̏ IafZʾj.@.~smˍK3%ĶFDk4Fd5$ٓ/dRT]K;WR~frQ 2Mͺ%OHR# V Q.?V>jgڿ*c; Y0/6y%?Vڙ䖯ʤXʨ*匩:t' {hui3/ Y{)ZL\@`ڙ䖯ʤXsjgZ*c;J=>LY+Jy2&iRRDFfgD@0mLKWR~93-_Iwg^hJ-Km ^Vei&}qڢZ{:MɦKnKipjAn^ wS<TmLKWR~gbQWƝK3`i/1&;n#JҢRLͩIjOՇ6y%?V3e^ vO2iRmxL)Q6$u^36y%?Vڙ䖯ʤXڭe_5 [} 9ƦT[#$(Q$I,eE쌨 ͩIjOՇ6y%?V3sjgZ*aͩIjOՌIUT8rt> ҷ's|#7$Ӹ%CFx6s8z4"0o?̔ߕoJixDg$S<TmLKWR~fKne3ioN8h4֔Rn6FeF紅H S<TmLKWR~fQj1&-Y}n[iRpЕEbЬ^2x /6y%?Vڙ䖯ʤXʨ&匩:t˰K-u̼&mei221qsjgZ*aͩIjOՌ�`ڙ䖯ʤXsjgZ*c;�'6y%?Vڙ䖯ʤX ͩIjOՇ6y%?V3sjgZ*aͩIjOՌ�`ڙ䖯ʤXsjgZ*c;�'6y%?Vڙ䖯ʤX ͩIjOՇ6y%?V3sjgZ*aͩIjOՌ�`ڙ䖯ʤXsjgZ*c;�'6y%?Vڙ䖯ʤX ͩIjOՇ6y%?V3sjgZ*aͩIjOՌ�`ڙ䖯ʤXsjgZ*c;�'6y%?Vڙ䖯ʤX ͩIjOՇ6y%?V3sjgZ*aͩIjOՌ�`ڙ䖯ʤXsjgZ*c;�'6y%?Vڙ䖯ʤX ͩIjOՇ6y%?V3sjgZ*aͩIjOՌ�`ڙ䖯ʤXsjgZ*c;�'6y%?Vڙ䖯ʤX ͩIjOՇ6y%?V3sjgZ*aͩIjOՌ�GhcIJܢ#6T-h$tyf,gucաKDX_ឹozAKت6%b*̓)0i ڈHRO$[7a�lxlbxx:Q.Ł!g|LfR D8r987 I[}oYi&uӍ@jӨNJɻ1m҇YuRP($l~ic,|$Z_W#ÊSY41 ӏ ֓Y䭺J\W˥D\4zLW7IĽ�Z̍v�oWu&I%Kif5>%-fMHSÑͣDQ6p\w6[M\.(:Z(.3n4nȱz[z/q0N o.8Jڒ%-N" $G~�aj5Z-rur2e*49q%!ث$3Ch7KQi'Z*ܓfwOe[˨Wۑ7iTyb+TD5LKEY-,$iuX OLn{I=5eJL1ˎr Y6fմ.|.5ւ{4ZMLȢ61ݿ.CLOyyzd;-z�juϟ:r˽IQ.4یMwHJVL3.G[u#WnD{^FGaRʁ<O\bmL"(!o:ɽ$vm#źjQuGyҸ]B&Jr:!)266!BSJm%>ըxu jl$""$n6F귑 ҩwi@i%vW=\lyƚŹ[Lu&rwΚP-JiVwPxkP^\ݳO-/Cҗ"nEiF Zˇ{F{/ $pY�k5wVRjKGoTǩRM-R8YK%+7 .6Ims҂p5zqDܭiu\tش)6TJ;zξf7VDMF`u PE_Et8! }os;3ь𢨲lF;T"@h0{\S\TH=MJVԙ&R""0S~w OԊ}iq**R"⥖SMÉh͵DCZ.Z\Z"=vӣS[)U @}.1@uZKcwJ[dϒH6] 02NR(,O<^üL!BKlcT%]:.Us՘M@ثݲC C2~[m'kn!/6 {MWJ:+3 iL?CdmDd)'Ԥ niVZ>5o 椙BɮSԤ! Tv%R j4:yjmZ5ڏ̧PӊF]8o%R[R6:jq\m2{4thLf;Ie pҒY(T`@5{R5RQ싚a RP솣AUE:'.;mSbGhuML8ƨ=j<+o4BSש뎖nwIvTdQfQ5u8 �R}G��5YfF_+O)4*<wFZu ngHa ) 2@5dY_Պl;zgר:papNm+.twTRunmH5)fjKBnX H�jUJ`>XEN ! 0˓?E)8Lr< -xE$-c:\vj:O—R->%)#uq]CJzSlG!%([aK)iy2jғ2b)\-J}Mx9L;K`[ڛs;RjdE;Q6!M=!%Sh6SɤBr+}^yN幕^g^Ii|jcbvBq3[yɩBq.JIhVRQkƒCaΏW*Tڍ)2-:G99f>u/$'iJ3Z$^=mUi*]"\,PHaQtd~Kja|ͼ!6p/Xj͹[l&MRrb;vWD8:C,8=zl6"2Lnr^սAJ*' ;qmSPӨJJAU%T\T%$ i#"0{�5vҮ'ڕpY$* ]Urm"W̒ؓ*-%U$jE(vǡkgcӚQ3$P#$ӘQnV:ϥVj;vK$`Ą!J4pIJ<�joToOSZJZ+g6ìC7=:6!(Rx+ޣuGhT5H*Ǩo*tʼ"y( FuX8ĥfICIZG:kHHKڒEɪbQ )$:g3C['ʦ_-T$`Tnb2dKr(pꖥV[Q0R q!7T_Ilg HW͙nS\0%U!~WinnpyS L[zyRgD^�b6[u^Tb>*2!kR֤65Br$' %8ⱹŚ ��������������������������������������������������������������� a~F�Hv/W=� a~F�Hv/W:['z,նX]<CK:7)Qd|n?zy#laZOӿR4I; LȎT hO#lFFx%$9j:+; ezy#lakw7ԯ}RT4f~}6K*QǐFȕ]e�P6_0mK^*z-Cf*]$a'hIK<!Fgf6y7k)#ؗU]-)֬]IvفLLjpiޯGFשGk?V8 &L " j>,1EjԄ%h+ԫʛF�#*Mf2:"diL"DDrdiIv @;NZ3&I9R[qTfCӇ7+I]d@BK}Le8iYj,Deĉ6B%2&2#x�|�p&rݧJb2K6qIA)G[̋x'FUyP6_0W-?n @STT- FDj2Iȳ됨.]Nru.QIܹ0VBFD~ -9=#223UyP6_0ޜgqc~yP6_0׈eUϺnJ%:[gKa7!)i['HVN3N-F9VEe?BKDM }ĸiRR3,Jّ)1BF<|>Ӭr)\*܀P;j=%Jh\{ϯbVEUF!菣N^} q񣓤׽|s{wx 3BF<|ި^HǛ/`nHcA6T'SUqHrC7"< MTO$fDY2;MG4䡔鷴 S q^#WVކ ӸD� ezy#labzVJ]5I4)eFT'r[ڣ3lKE))ڵlϫ_T*,@~uV5K +r /C-$.Qި^HǛ/; eט[n%v*jEicT47_Cd ;Y)dDXڥ_tR5>fU[ o0󤔨أJyIud2~BF<|ި^HǛ/E4>oPXWMҍor5Pr\dO% ԵSfj"ZP]FJROw):m\;ܭht5Ѫ%rav:}\*O!)jXHyP6_0ʼD|:tʛ.%%Ė9 G巂"2+&X,߀R1BF<|¨�R1BF<|¨�R1BF<|¨�R1BF<|¨�R1BF<|¨�R1BF<|¨�R1BF<|¨�R1BF<|¨�R1BF<|¨�R1BF<|¨�R1BF<|¨�R1BF<|¨�R1BF<|¨�R1BF<|¨�R1BF<|¨�R1BF<|¨�R1BF<|¨�R1BF<|¨�R1BF<|¨�R1BF<|¨�R1BF<|¨�R1BF<|¨�R1BF<|¨�R1BF<|¨�R1BF<|¨�R1BF<|¨�R1BF<|¨�R1BF<|¨�R1BF<|¨�R1BF<|¨�R1BF<|¨�R1BF<|¨�R1BF<|¨�R1BF<|¨�R1BF<|¨�D]>KM̐"u|#-n(y_l~댰Vi?N�PSHcz~HOӿR\4k4Ύ^e8fIM$e=.O\ӣ_?tK˱nFSQ *[q6@}IRZ6Ҭ&y_[wTmu*La3X.&a)ƩjL$ҳ#BqgWw7ԯ}tLW*iaX OZ7(2,HLŬje|c(gxn7'iZwPޱ,j]ub]NE7dT33W'ag .dPοp7RoT*EXoh� iz]Xy6�nv߽?)i>!i K �?�Y{gdQTQ҂ˑg֤%m:%vfPh(d%m)}Y,�֗K<<!Mͽ4D9붵k^=@U0Ԇ֓!5�ceC�DŸ]bƍ5MTn`O;jvH*�ݛ�Hq颙Q9m;*fyj+P%T)ŦN*c7o:y-'P$ nЄj4KڡK6ZDLˆ[rMyD6"Q#k0VO2r=r7R*3F.BCkG$u)%MTsx _{Rk>dIj;1(Vۆ pƓ%B *O �URӴҡYk rVçS%*˙q2S_5BBv0Rl0s-[ڇגbJW|';jR(IZW&c7'ҙ8.&L6DqF\gwu �0R.:SөFDm&zcI&:;%չ$q?пOz&AI+/D/tٻw^9� ~ Nc*Uj֝~QߨH+JBNQ+%)[JZh F6M==3[yڃM:uxǔ%.zwrF BH֭�bi-ujo)2h٢S 6fRH--ւtDng犝Ǫ7m�^*$I5;ty)W&%[OG<]*� M42rxtءsl؝?(Nv/x&x<fZ1Eغ-NU!jiT.5 fo“<-'�jM7E?rW2b9JSۍ$NL3e,I{KqF[[i-vo}N.9NP_UYBHad?<q6g#%)k7MݟMn5pޚE'[>Din"ݔ8hxqyq l�����������������������������������������������������������������������������������������"n(y_[+<_JfW:z,+շOӿR0Ν�j7<ss֝�� JmQr}RۧO7+1 O=R~LIL >n*У([##KIRל$K'j~Qqh)Ls6JSxOu­T.ܪfמXD)}Dd]",Fe \K))ZLd䌆nDfHkm^ J%]yJCGSOޅ!jBjOkWwZKQS% \*(Amm92wXÜMlʉ׳<g�KUإSkj) *K1Sd[N2ͦ^}\^a|ȹI:"0HI�ym+ D+Mb[}.%?� (xӴocՋFQifq_{@VdL}jKi5(MX#Y.љ[;ާi9ҽB+KH+xUG O.L=qh: fQ}eB}C1BkvG\h-IlJ K|Lq|A#Y �TP5ؒ<p!dGk'd*�-RLQb>#K"\ m$jR֥RDFfgD@*aXWĂbܽX&F$(Rq(~Eiigؓ`�r{6"_BcmQ5DZ̒YRE3"Ų:UW"ɖ =N3!KFIFF48h.I ,*|LJg<q넕Hp #? D^ ' >1T�r>���������������������������������������������������������������������������������������[+<_JfW=2{Oី mƓ~t7TL4)ڤ o|5@�+�� hvSCu$MJ* j"DP^ ՙnJSUgGuPQr;5y 9VZT^p&z4ʕ<Su#ZV֓-Α(H[7T5nTI)H5!D22?`bm tZ^KȒE:rM)#>(/c+O^7c+633Z!N +KΪ"FdD}x2E'1dģ(G\W%))[-94p3XKitwaj/%Of&"fyt! 覢* R.]͈I/E�6Z> IL(&DdƟ\'y8aS&9R2~|&+]n:%@›WnGBfX#Xv]1M-n>ύ1=)6OyCI)ID}FCuGaJL-EN[nK/6NJ$)izXkKXJ*GiǸi䴞]]cotJGk1E0M$FWgRr{4-o�ו]:ЅpeR-'DObq>B䭼mOTu*S7=T[۷:ROG oA(<o6b&Rq2</`6s(QiW\XoDRxQ"+)ڴg)ԆeO[(a27!}S*CI8ƣFĸ-mkKJzROGf %2c:rnDf9%W VlNsϳEjW̳vը53%63sNGW/G~zn$X&^}ź2]m0 {J1-潏4XNm4 Y >�!GBJ)Qkj]4 L5i2f�Hn䖒Q$dEtzkFT\bfգ%*Pw#ǔ=qCyS˕g:RHDe�VYP&T]'Ƶ)VY'wn4I AoNUUBit5mMxlң>#=`{�5j53\YR~FDD1K%r$6ꞵQ+X֍KKj9)"੓qSNy/6K"Wй85."�4j<;6nD}Si<E"Bs%>ܞ"dR⻆ӛp]?X���������������������������������������������������������������������������������������kw}= CGZ_Oi�BP5~:3a^Ν�j7<i~t7T㟍O��`��|=|wc,gr1gڜm*AE_$7~�,ܮc6J8$d}>cJV*S&Tb-FmVDFQ#$}i,2BjӰWDÀFA$G՝YzY,U:6 X<^K{&YK3uX*;,J2Ƥc%Ԭx'T)ÍrV)-L2r""}mH> U!y)mǐIpG_.Jsz܌쨮QmdJIYg$d/KJHs< vvFEJUA̾2yյn~Mv%rRZCPL- Y>Q܋ڠS6:.)9f I?IgħhÌJx&0{Z"%뵄CbUV}ng� Gk^T#)BXyQmƖˬD("$lIB5z*!U$B-if_ Y�n�U`�������������������������������������������������������������������������������������������������EZ_Oi�BP5~:閷~WxД<_u? XWn4)ڤ a�;AM nxx:��1X��AE_$7~�,ܮc6JPQW ߿;v:w+zҎ"�:)mOJTgLKejHxJLDfx#h�F^�BV2 TUD 3isKaԕ*%'qO0Iy:m*YMPﺕ G⩏F%̌GraBвu F$% k ߍ^Iݳ#x�zY8E!R!SEKMQQ:`aVd̤܌VΥȥ:D9"Yx4D9QBUS<rڣ/VHHMaQp>J[T2<2ݜssMꦞyS0+GnSU2=WnK/�qn7yu*ry3�bWjFΣ3T g*?ŴڋG'=vmttz-D(Un*y<RX2QqƼ4u 5Qi6�z;H~L*t"&Ju 2ӛ"*? fNm͎ڲ;^knj:;]Nלk';Ûsb7[KD- j>☉qYqȓh[?R dn!GI "v5RԵZW u[pRUpo%|c&,փ3q,,%>{N{V\mVl-ex=(STƍ[a:̖ %-{RE"4ܵ:e;I]/W%V<%e^oZsb٦ƹg V<7[I۝R<< @ zS$WM7sAңHDqm.sʜaƼXhlw6}ouSS]-dve#$dm6E4l"צPg֦LILޥs<`3$ ' x9Lv-Ix/8̢D23b#nHɚLdE U>Ĕ۲,j}4:R7Sq Br-JZRڽiJukTOQk e5&&K 3!!I%)#qp4ܦTuv~IU SUC46i֖KII)RdGv1#ǕbekuEܕ%TPy%3G96HD&t9Zt*ƒ[PKTR)#S*#:FGlrУs;՘]nŴ葩Pf7lr=Ϟsϭn/x,`"{Z-aebPpCCfSZ= LAї i[V!ۈQ k~\(g\QڕS^'6$)y6DH,:!u^.<-JafmՅM$Ȕۺf[7Ѫk,:NgT]BjS-*C2I"t<d*(zȉ:uSR$FZ&T+C8IZ#RGZu+OŒt 沑9RFLSmnqLG"J%p}o[4V\nrg-^^yYQN:c`zimM�4Wy;o9&�wn=`0^ꌺsUqZ)Ʒ"UmXWKm1Z . jTN4h_RM OߩՍ!ǥέ=OAhL9T̛R6߂nq VJ5lo fotER#eޤr N(ddkf\D674,NO ìFDR}Y/ 8FiVjL]&M"Tr5*r4 EqR6] Mga)'0{Ub4T"JjS2=HeSF)f㚣W&[\xȞUT:jdIuөtR2h$M6I2qjE;] M26KiQiA GU9^KSک?\W Yq1\RVҢ2##.2u>k&U3qrs2nۻ8g�d]T#ܘɪ)r)>8I3wq1/unXn#O;]F<6pOŞOsFwjUMxʈdFzgɨԪuXkT#mÂ6,";r.GP¨N-š2ٸƍUYa֞ju^:RlRYI.$F@vԍ(T߳uy1g%IqFY3MMypޠիԪV-JbFn|Jlt92I=eL҉ %ġM%fڦՋ6]ۢʨ.qgHaҖ4Cͭ.!]$ j, [ iLbܸ3tT{d i2G92&lMF# ƭ7s%qV &);"цq%84еnJzrĥBp\mdӤYpO"Hq/leH*ڔ%Hę;^ШҠByۢN~JK+a$⭵!$Ӯ#iݪ;977Nc]e뉔Jwj=j4H|ƨ^:hu34Q ̨kuҠ5H`w2550|hX,UҪ[Sz*YO[T!5? L4n6ML4jݺnyURW_uЫS"Ll_#KʔI>eHlk6m"*5V�,w":S Dpy,IFoiFF@)|$NPw z /Ԧ;-ji*u)k5( .' ;IiygwSbPvPH!inKSR|DkQ9X@BV{]5"2~z٭\&P&M3DdG!56:)R}oCOϪ OUJ.nRF-͡Ia;nDsNUfIC%˜ KQ+(-%%8JkJIqdiS sLfDcIa/r["u4'JFd 4<z-*qLʀB1OtRSq\4}҂BHmN)Y;vwHWk 'RXv563\sS2DTRgIm s M.Rwə!nkKCLu3C'jYZ hXm`}",,9!um{2d}M4HR6j}jTUIzl2|Z왬QLU:wkSM.(ЃόA{Vf UE=mȕ"(xieJ6F4%'$g~ͭZSITN9nJnN&[wa8",\ȷQէCD=06imT$DgM.kTh7M16Έk^/3il[VDBaTcMs\)֦ʊM{D%d6K"I8im)625;s}dW"ՕᗜGjc4.+"ݷ*Vk'R;JrTEL5m6Ӳ$IRK$"37u+"1yϝ"gXSLW #i[SsNe]ZKvMD*t΍Vznzt4tU5̋dnFjVHW.} Pؓ]1ڞ-xƐADf"VHEWJŏGWiթL<=Ǎ&4XRI%%KVIII* >5�h)\71,̨[Ľz1DueJxI1nM-yP O \I|-hRF>6>eS?Ca}IIJ_*<. un2JI6'3۩ndw,+~pVWY+(,�33 ;XN5V;b"$9f4GuĬ:jJ)3QpDX"",*fUltʬF6ntٛn!g`bvEKM|tTM=J]JDKVq;MrC>=دS[r;+e$)e$Ҝo:RUUfM>fOڃf4G丣qTÊR]n.|׭�JKZMqFNMQυRʲ\4!0`Nv;JmP_~5ғ%s~cϤmn,7kkbƍJчm\T%ÝQpDT ZҤFRy-8 YM%-Faw#Kk-AGo.du/Uft48URB_r*Y#HJ l2\~\ԹQ5 ֻ3u {亲mM%յR%Y5'ɉZ Z# #Kt:Ay=!On̑IԼu՝3ٔKQi&F='3iȾضZ?v+$fFUdX=:]t~,T& BF<.-d7q(8v]J"ZtM8oJ{5xZyOiUiU]TXWv5t[VQZmόfgKn'Nԙ7=] _IkQx x^1mLy&hSvU醴-Nӣ˺+뭿}R#dhT->$VFt&R5nSf܆-JAKP}(22}\ЇQ&ٜL[bO~ [v\9fTv=rYkB^%* =Wxn[HrҖ:,IJL%ʈjG4m [xؕ tKyPFSQm 6wQq`V\|L[:ACsm?pV$Ȥ2L-%-nUgpcQu&jXu%' m*$-)9 I%Gmtm!#6Z{zyN%(&zMMգQk5"J8]loIG4n|MDCƈ1uj =(]j%"2-O!|6 [3fLwim�;w??v3s8;6m/&7?ÍN$q.\R fHICQҊ&WQԮɎv"PZ[Tf:l =Ȕj tV`jjZs&9Ci-oʄajJ^"%/*2e,)H4ӨPaRe;qIb De;tT2<el(s%&ێ'a,f-(V}|'LgN}Ymd<#3ԮE ^&/m[bTf<VpԘg`-Gf$QaELv !҇9ș-rddI)n:JP5̐$�8{P.#{%k/U5ⴓ\bQR-ĩtlx2?PrTЙ$-!͈d!)Bn2J諵{Tлs.i<ATcF kF4I_FQ()) v5=wy׽ĒwJVԧj[6է=z\oz>VTf~X-"""" PzZI׽"UԪUƺ*SˊuH%0.#rMdә]hyKNL>-%q{߲w-877y 4锛B V>+Sj#5x񈌭 &[7=:D6E-RYqlR*Qiæszx:�����������������V~WxД<_zeߕ/%3Wm=qۍ' osƘi?N�PSH99kN� V���PQW ߿;v:w+zүUCpݎ1cjq�#id6C�DEC� ^ W-|j˥bDJe톕n>ݦu/yL5v&U66,Y{ u*%A{p۷>F>�qv)*c9ќaMq;L]6R[?,LYxDi-m%J!]>/u`_Uknud9Qr|\y'#VyRȿ8EMnk#� m,])v�Gdb9[:?V!GL=}dM .`},:&^fK|lRԸ›IVc} �$��������������������������������������������������������������������������������������������V~WxД<_zeߕ/%3Wm=qۍ' osƘi?N�PSH99kN� V���PQW ߿;v:w+zүUCpݎ1cjq� �����(kqQ* Ƕ;vݾ r1O u*%A{p۷>F>�qvN} p%lK~qu~XflN s~\[glK~qu~XflNpu&SHnGmr3�I,�/`Tҟ#|LVMM&U釽F)&E]EՁGI{4VXk^лlz1UT %$d&CGI%֣#.+7CkZkB_j.$X6"Z4-lX"t}7uuϬT5O.GZ-qdJp2uNwjAaנϪ93&[8mm k}uní?XF&\U11<c'dnj NoVf7M"7ct6ԴlYSN#RMaKFN';Fu[ƑyS`˦D(s6_q)I? `ϫ�\:/WW7ϟn<]ˎڜn=bo9S4TZakgQetQ S)J*\X蕵, 7Ӧx^#$KۗTz֤d^*INɖf;m!K\KlJlH:^7b^fmE 1M(vSJm 2JsL;Ī[EA_J qn ݊H|$$Kl7*{7[)֡ζiL [.Lܓ*;J"aӊ' Fva?GkPlVőhB1,Ǣtۻk.9Eġnd΁. In6 SPbە"KJFIalȥ 86VdoE49N;s?'gJ醃gSNnj2ۇӎ"&HIMmJB 1IMpuT;ևCJJ\RPi]6~URt\D9MCلnT*"u(5l%r#8Ğ.k_NhIi1$D$$!rg{D.Eۥwws4Q*)vTɏ=pG7e$JJW#Z󆕤2{_jz"UVme]e4ꋨSly4efI$N{\EXR]^"K55gqUHQ{N5,oZjp:eQ4CR-۲ʭBܺԎ*:tyUKQv!; B"DrޓqYտmGUͪ5\N2MV(Q,Z<8۹ܗ:JU'RzZ Fk-i()y\d'\mM2eW߾,Y5x1H,GS!V6ѹq.$jmJBY(H)Xt[湠kl-IRW+RaɵyIs}UFMBOr;'2:wH|\{z\lO;9g>ೂ ?F5:[-?_:R7L?MbMz3HSN_G=νICOԄE+DLN}==ti%a6kdC"CFoQ$I}6қ\*e1Fij#^S/)yqKm>5Nwk- PhZbGih> 04K9Hl)2-eȕ$[ b͔STiD֖)Vmd%:ѩMm!.!jZP횋r^viThtjuI24,ܖ6票ugG{YiBr։"5L&ya:J]"BdG |[e!OZnVJ)Tܨ4R\rX4)'=yQ,2;'"}75ԙPw6Qm6lxkb:L]R!iZ!5r{T.kj˸,$Sӷ.Fj뎶8'ϘA"r\42AZ;&LHU)ۆOr*<MHMR̒[ D!$+iըVtԚ$7rR);\-.,X;Z|9BWubG5b*ubreje6rlF VOnFzܶr:wiw%NZ:_G\i0p8})4=%B$;G֪.;q4vPnUwi!3DWᤥ iҖ%<H.TUi#B5-()% nlfJk boiJyRsBSmR:v*EoԝC%=j_mRFk7drѠ4 ҩEP*jHKL)2A }8{?T%x&ڬtiOOx4ÉoSRWR-<2#ls%xRrh3rS|'.JinSoz!F"FڃM[浭˖ӻGQ*rq <i .k\.J{){q0K-Ԅ\蚵y_mz#:E^=UB"!r%-d7wP4ֺv\<zR >OS1&K- IAɓuJ[2RIlQ6n=N7<w)uե%r5RSlDȅR& Q2n7!)ɇp$ozI*6װh ]LFWw["aGLt-jQiӝ%)j$;-W@��������������������������������������������������������������kw}= CGZ_Oi�BP5~:3a^Ν�j7<i~t7T㟍O��`��|=|wc,gr1gڜm*AE_$7~�,ܮc6J8������{c{m^w#�JP\Tlw~|cܟiD+K}0q3N*c6&S\fiĭGXx)1P}.ʴw!⍱e+wi8xLT0i5*<eqhm!eP~+ql~]ul[tXS =�)eR_[4<:*n߱3 W'Q6HI4KMx?)G=YB%Qϫ-7g�9ӝS/Jm6V]HSd6Jr:MIVYI]^K'"Jke~�];͇SL7"?C6.6uU%i<rd~ %,M;<bN6%X3�������������������������������������������������������������������������������������������Uߕ/%3Wkw}= CG[c\ezI�?:w@OӿR~7}>Ӡ���UCpݎ1cjq|=|wc,gr1gڜm(+�H����� TJݷo}y܌|;*C]sP^==O;r].E٩+dvǏgo=ڮŰjgd(>Y[fvql꦳Kԫڑ(PjfjVIn4cd^.ԧKwv~ѻ[-uөʔB f6oVm m^ > T/QUꏹ;I߆zt$z;ՒHQ<%6Fx^zUTyM8-%&a7udj2񖴤_.nD&3C?2#IaDJIH6T2vBDi[8qĒpn(Ӵ$gϰ zƣ/ķtL؅P2ũ=[Sn-Me.6nBZpgOC["wR-ZUWMliju©pSp/R:E`Ia-E=1LIj6Czqŏg"5}6\!R}V!FSiuh7}DjRS2.~"B+S˄-Pd5;IfnGKuilԕ4X]S4R7u5OMBɕJEIˀax%{Zl>KjI8k d~giH}HS,M/xqg 7+R`'!t/fMjtMu&NmԒ!5!m#enFx T$cNv,Ljϸ zCMgK2 ipF$fus9%fӍ4ӹvRM&޶NRsfuR׹[:{K":C6ߙJϧVpD~dR:lJ-6mMKΩ6 a{t@kNI ǎkqnjyRRHIffXIldרqͣMM-d[lDJ->py"n}(RjiHsxS51[ɂl mFvŻjo: G oV-S)mNU\e)2BvBn}ĴG�#(�iU֛rŵ˺Up-r4N!c;9.s6I*Nx3rЮA"[=e6{! J'f55eu,S!j Dwīj=qWQHj;C 6_u_z{iřR(tMro1QF~�0G>ߑNRK K%5wFpJ,m<U|c[ȝr[liΉ,y,H)e$tKdR3SLx݄DI85}+զּ/z}ΠQ"TmzTɜ&2ND*$,F[jwVX;U\F-}J SqmtkI!EU tL:VY~SACi/<kMRN73tdpKӯ=Q[VPzC,*"D)S`)qt/̍Ut[W5t[$zFb%Z OfT2ZK[3jBq9Z]GZ&VE1VejU%v[mXvKjS\q݇B!ZR6nѺXTmq\(ΡRu4io&CK/4iQ8IF呠]RӛPo;m~ԉJdIQ4V9IBe6I[ͧ9!.u:n窳SP:#b&Juy\U-F/aK^[ ̯HMRaP*MvR:Iy\l>qyd$ӌ9K{±SNb:3IPIפe[?5$-IZTtEsE"ƭ$f"UteC)oAu56'oeuh#U+7]L1[ȑ#.P֗RZ-ĶcVw*qimPA0 r~tLZQcC{ N'2%.^{}e2L-Rp+֕(Ȍ =_Zb}::ɠfܦ|]-OHqKfrH& I.5Fǩb-ALRn!F^ �������������������������������������������������������������������V~WxД<_zeߕ/%3Wm=qۍ' osƘi?N�PSH99kN� V���PQW ߿;v:w+zүUCpݎ1cjq� �����(kqQ* Ƕ;vݾ r1O u*%A{p۷>F>�qvN} #cJZf^G-%IK%lCκiQ%KC4D0[A4]pl[ȥ:^IL֜8DX,mIxD}C+vEJm]QgM. $m~TG"2!Y=]vniʩD_#2SN#YIKkqYuȌd-n�f[7�L9T\Imo)IvRkJ^kj[f[;sE &G=ؕ]jUZezv}>E$u9딫yNjժMqE,u�Y�/0ꆞ[QtT(2^UUjqw)rF6Q%>{yXl-۪uS6)I*L yżYQXAc$IIšҡa7({[PRY33<YEX@����gu�>`u#����������������������������������������������������������������������������������"n(y_[+<_JfW:z,+շOӿR0Ν�j7<ss֝�����wnueWf1cS^((ۻYc;ٌc=XiG^�@�����P\Tlw~|cܟiW TJݷo}y܌|;(iv(QV)8ڦ,o2_jq~9o.R5c~1S0kiJ,9MMm_:O�x]pXP-ΜyoJCxrC6,EFedG${N7wR^.f[2-6Dx3/ -ey!,{ɶDnZUrdvY)(FeGddF4e?5K-]k=J]^twKSԛneܶžAT+ C"3/-hcj\4y3G�YޒȡU_z:S*tmB69"Yݝy<c9u7w7wNZMwZ-[WN# *ZuҤfLʎ,]ХTP5ؒ<p!dGk'd(KfڵJ^GDR;:\_-ֵmI IDcTQ5N:ˮ@;z%gύQi؄9.:m%-`K% UY !=S~l.=.nԌ䒣i#2jNJxS lMa;NGpJ\mjmZi)&G#gQc@իEYnNAZN*G+Q#[n3Yy{Ѧ٧zwlR:6$Dq3ʳ2n:q򓄕Gln)ސ XM]CPo㱢UhUTlqR:$h󔗝u* m,:oyv̩jGߧ,Ilml4qH>{4OqA5T!j:\[JqimkZP5(fB.d+ZUKsMhߋFvkidK3Z5oRp۝dX-z=V۵i0UWeB߇YxeDm2":*Pݷ[leE2lJoIe[(84.5`6n]V>L(1ΛZuԥR$-B*Q!B[b_BkEirnhMMmSlK[$No}RިeNKP\v<zfqס*Tu(Cɩ3%3=#~+vu"eRJWMzCk)PgLNOd~rHZU6)*/䆢)ԓ6١.-(M)7[#2,śm~[WeNN\4BF$ '2y)QjXV(Qz#GV[U4Q*[J~gBZpr$)g<kW53V7}acOיI<aJ, uKNajSKIL6R)̎v[Tu5%FӄFe6E-mj 5څpRH :qܕIܦ(jmFD%$ۅ^u:ć+OY[ӈHIv|ו[Ir=x. i}Gum+]D*B$TT$ n!#9"u2"Qd&0����������������������������������������������������������������������������kw}= CGZ_Oi�BP5~:3a^Ν�j7<i~t7T㟍O��`��|=|wc,gr1gڜm*AE_$7~�,ܮc6J8������{c{m^w#�JP\Tlw~|cܟiD+K}0M\J"}1Ӫޒj�+ʓ�<CӛX{4jҤժT9iR# IV<#3HenO$qoi)o$()V2Yˆ;H@՞j.~aj[{uINTk)ΙJ-dΡyJ=JK$fDaZcU(ȶ">[ɲHd^KHGoZՍԷcL+&$ D7i;-d mDxNԨf@$}اuKKI$"74^<~i2ywwv-ЩwO&kun;RXp^R<tY/!8BHbYbp~ u�II@ͩ0X/ @d $g}�|{}�E@$D_�������������������������������������������������������������������������������*{OLju|#g2½[q�;AM nx ' os?> i��� *!{gvVXvcV18U₊Hn�|>YݻՖ3]3ՌmN6q�$����� u*%A{p۷>F>�qvpD/v'םù?.҉VaukDٝ۞Im篫ng�)k["f۞Im篫ng�)xUoIfw)g#*/4qYaƝ3�WE}3CZ'"Jn"|4R*TڏqJ#"}2�C!6-iw^ӧuS.m\m C-D 4%-!Yle?ChՈ6EQ�zqzcjD]zѮ7TW!R'7%h5NA N`8PTRVh5Ej\1R I#&Q8{TYˆȌ}�V\4U.ڕ m:19 k<ٕ,qQA&L֣Q G. }ԇw3.(W-6u.nES(ѢmPhwPœ#I*k@kc:PFPiG]ӨX!}QT-'f݊-;^EAשׁ<.zɷ-BH(qȔA7gm&pM4l)NՎ%5$@(˗Zk-y&lٍRڵ؊TY쪙!aN%*yƉڗʸhCíΡHHH"~tU튭.Ǔ ZKCSf$Z DW$~d(t>R`SIDiPB9^ZܘdGtR2q&!`!6?S&A+vha'֪Nn}\kaJk-/&2d$L) atiWt[QzaǯR=,)[Ym %kZHI-k$l NV;ުm 6%L]Bɩ\|YїS6w ֤*kEH&WҤ-8ri*ڨ0lȟ*6g![ui1qD-HZ'TBdT?~Ubr*RݫK҉" Υi[vVJ#Yu 귱pnյ0}RRҖ>ˏ&M| eZg@F]w?.m6.Rm].zt%,//&f:y%Ě������������������������������������������������������#/hZ:Nz R<Pk)[dKA--k8��������������������*{OLju|#g2½[q�;AM nx ' os?> i��� *!{gvVXvcV18U₊Hn�|>YݻՖ3]3ՌmN6q�$����� u*%A{p۷>F>�qvpD/v'םù?.҉V 0^aFdZMTuu8ҏ>eH�SjeNeɏ5NP4RRZ2Ic=xj5fTV%-)ueDY-)`$GuոWZD̋RE*3䨥6\GwYd(`h{aZ\CU_V-Tf}kW{Fgj^PiGtҧH?Z\(9S\vLг,%j7RJ񌓄+kekjrtUS]-m[iZO$%3}t%#-m6\*SvXE \z;Q1Kݹ $pjSpIJ+MNmjj݃2>#hq;dTe22Ql;~nuSF`̱$4jr;ќ%q*fC4&K>_UdcǏ6+r&rJ)2|KNUDu4nHbR6* !.Ȩ~BLC)ļ2y/ĭDQE�۝3dR_qdJzLpZ7%2[kC,I4MH/ŨKtSNd>2^RoJd(93kmOjV7JԸӐFeYI.c̎R;Zv&9Z(!>$}Y0\BpF�Gvfښ~x7n(4tTߎm-4!)#i r(Zy4R֧̦159ME2HjLFC+mYA2_WK䈈:o@lSWy﬚m)ZPMN[!.JJp:ײ)dnHepiru*2[)d[:#qK2,_ܲ66O:}T1-4r&Ҕ'iK^n"Qo^~צZ"h˓9mԼ!3ujan�Z{jf[T7CR5}_-Q ILfb������������������������������������������������������!='^Z]P%סKxܒT&֧/2#"QJHZ-+Bօ]to_NTmnkzuRZKoOnDi[S)JhIRRl&kBy4"uN];qx.I'Iw7Xc}4'HI)+q쟹䦹mզRit'[ #P%K+jrx҇b7UVE@& �������������������V~WxД<_zeߕ/%3Wm=qۍ' osƘi?N�PSH99kN� V���PQW ߿;v:w+zүUCpݎ1cjq� �����(kqQ* Ƕ;vݾ r1O u*%A{p۷>F>�qvN} #�x޸0!΁l!8 u*3'P]yQdnɼ*(|WPtr%5'm)S,?2F5]cU}HZϵGs]͆waמqH5W}DfVVeٴ$s*<%ԝdYɡ9mAoZBБ3L;!kR֧ T J3fcFQyqQmSd-Mn=j}"4% deK]6=_VU=˻j/Kj\n4t$)!r0 RX2kz0UȊl-uquUNU9fL12ћ/IR.%.ipVfFUdMe,,ai[ٓnTX˗%mD[$KpҲhI}FfHVƛO[5"!}BTt&6i2$o-Q%M#w@؍S#zT8M:K2ad:9%VJBeJQ%rרfN~UB#ʛb s! 6]q}MGYo‡oL)SimJDn!ɟ6Ye-:'֧$%Xs#{'Yڢ4Ma2٨%IV9\7DKM$är$|A?m;cRlˢT e%ںB;˵j;tnG㏻<dDՊ5TW(ٖ75qͩU8LE (Y ԣHX v]kQ,*Lߚw]K"Mm}})$&㴕n\[Ov]rL~LTkucnBQm+i3q-2H) H zyT HTѥKUj=Q\/Қ ufRkSƾis]U)G'Zr[@CE[-&'ඣlԓq@%pP{K#����������������������������������������������������� ]ף[?4Kr|΅ +#m"YY@��������������������kw}= CGZ_Oi�BP5~:3a^Ν�j7<i~t7T㟍O��`��|=|wc,gr1gڜm*AE_$7~�,ܮc6J8������{c{m^w#�JP\Tlw~|cܟiD>.V\[.EcN18.rQnݝ.EcN18.B#IWor2E1;j#-,y{m",V1w6RwLh/7j f,hɑ v<̼#-,ոIU6NeO ӉZ=|=}CB*4=54&:')R]4+̶f[--Y=#!xYl5owDӨq֛M} (-1u6R(EG4C' l$-L6)Yu ].euma!iQM ICOM=F{nK]irBHmI-7k#2h%8MdlH;QZ84xa:GLd๱FJ}Gh*=vRLvS/U1TL\D\8ЌcjE".Qd^U;wN;v%Jr%PXZW; {T"RUlܓ-ˮpʸ:4ak3䎷nGSR5\k6$�ATtnOԆjT{>+.oh^dmyu,Zu ר_t0*a-$Mj|Re'ɲMdPj-:ZT'1+f2^?ݜ0v MkץyMB UtG}3).%)dݎҔqg'JG�"}0{ejW\9O&Tȶbd\<ZMJe m$% z!$)dfC{fCHuTΡn#Rq 6nH%Nnvҗ~Cv)t43J]r4U&eI0{pޛXl+ǪTXyR"*eH-iˊ"dmJsY�/ޛJwk.pBW z47k{{̑fJsj"ZodLM>-IU6"1pSbj!n#5%i8Mj�ħjH����������������������������������������������������������������������������*{OLju|#g2½[q�;AM nx ' os?> i��� *!{gvVXvcV18U₊Hn�|>YݻՖ3]3ՌmN6q�$����� u*%A{p۷>F>�qvpD/v'םù?.҉Vav$c3nS <eǛ[lmen$Uű�֏R I|agnJDԥd zI7MmAԧ+${bȥ̑ e[y[iC$$8f{ BE !IS:=ʹBra%WgGR>}aU4˧|ҘVӌ%NQ(E EQouwS#<'P�/Mk-?DkZ7ΚQ\Zr$[} 6q=&jRP+r}iIb$GfZ5Z)t$eIZ zojͲu/j2,=B;[PY8 ; ޭk6}2$).ImI;92"y<, HQaj J7"v+X3Mlyɤ$G 8K@>õTh*jXƦT st%<ls<H%]_[it{E!tUzyNLxJ'ԥsrӵ́"-=Xb湓CoVR;P*M+Km:!8~>[\b-Kb׋]Rjlz*uyoh5I#[$It7O{iRFY$@nb]4\CPD3~4iIT^HZҤ]i#qrF]ѧqt+/t?zY80бdTv}:mۗjp2YDgqnJc)$o-GRX&Z~ MVlȧN;[]u0of-$П4$̉jN@H`>$$,���������������������������������������������������������������������������"n(y_[+<_JfW:z,+շOӿR0Ν�j7<ss֝�����wnueWf1cS^((ۻYc;ٌc=XiG^�@�����tOpd0ۜKq!+2i?d~h� f{Kݻ(>Y[fvql-.*sn<xϪqٝ[+E{1.=oJrCFNq In gy#D}e>#hE=eJvoս&S?\4`JYxלg{ٵbӯ*Q=d!YǬIZ"Ϭ4ZzܭHXb֟z̷>Cm .8д ^pDD}b񢲔v"Ł7m!%*Lzc͒H'∲Ϩ5{< s1![+qְӊ̷ƐDNU,(Yj4fCojP"Zs֤2Bc+4u;u{SmnʢT8܆%n8QȔI'w;LA.I*eTGæto%mʯ"N,sZ46QUR|fl*MCof5伙HWZK%dGֲV$,4:)%֣Xh7++[~ԕFsc ;GNTsMvlZ'h:$v)㪞rz%ϗMhNG.HOFGք8fn� GպeEͫNe!RU:sL Tx(j<$DS& ܕ%%ӑ%}<J[>9p&a\zSJeԚ> B" Hu}Pk=R- |*Tn%9hޔaXȼZ{pDfdGjͼ5 @j" |ڤ<I1p'(L]E3u&v��BaT5 M(4_~]1tyTXsJK:ꐕg:U⩬qv.%O%&Y*K%w-)IK`[O$FE5 XׅA5m^ jdSQ"qҏ9CsVl%F?4fӴ&FP݁tBNsXK*;W\DK{∨JNR_|S)K%>�j{:GrDԋ>o.rSعNmʩ)ÖjAw(rLBcw'V ܠP<xs82S-2nM?(g4-$ ����������������������������������������������������������������������������V~WxД<_zeߕ/%3Wm=qۍ' osƘi?N�PSH99kN� V���PQW ߿;v:w+zҶv?(8 [y9\tJB )<e'D:VQYRnU\3qk,~RD^>2.uutQkKi5().3TJ+t4۽ Bԅ3.ԟa֮蝹~ԢTJU&P3|4>re,2f36,aa%f8TMv=]:*\WHaRY%:q$m2\6EO�2BO{n_nb!\2m׈q,VHoM/)GXcƝ ~Z7OV3ܔZJV%OFrcVB_6ID6jDgvظ>O_$)̥E^_:A]Ƨ" 6<xmJ}İF�!rd�б댛@- [4*D6Ɍ [E?JAoKfP\2]e}~ gj\U`,J*EėQ6ӄGpЇ "?F^i>!T䣒;6A(Ӕ`ˬܷZZV6⎹eSV$:!ǼReXfVJ:2]F-.Dr\&eKZdIIQ�f6o$%"kDE�O+}~Lu̦3:JUFO(Ɨ$␓3ɥ&DJL8Yzgj?L'u.~̾ oQݵXna�-RMQb>#K"T m$jZ֣%$Dff}DD1sX+<7[b+:ihQSG֥uL`TGb yrCTKmZ֔$MJ",�#����������������������������������������������������������������������������������������ju|#-n(y_l~댰Vi?N�PSH4I�?:w@ϧZt��b�� X.=/ne?t1QXrDԢ)HmE pY8e]fx!awP_5  XQ #_Jmא3EeJq[AmAgLQ#Ɋ~|%:Xr>ťoi2bUuK[VIԒRdJI(### V&ЗE5)n $S(қ"3/ r"2q>si=1aUҴ(fDH|׎/_$R}LJ2TuyR_qIRӓIg .1mՋh 4/VOy v�RQ$�VhjaJ*iwBފj, I""aE؊ᔒ�]_e SĔl]BRdFGiy12|sE2c+e,#'-ObJ5Yt nL)z|Ft*Jh<<YGo5"lщ3C(lҞSa44<̤ZGd1nZ}{vˢѫ$T麄dĨIRgPtXz{{KIJe6JtvZ3Dn {&u''3By\ӭW vP"ߒtJy9=)q--댔(~JveGR3s HEs!pf+e-#A!ig8,u˱NI+w!ٲFrHfT#r7524j4lK<rֽThĩ.$vjPY>ۓ*;!J&Joc]m5pn8,8I$^~֯\y7ip*ZQ;Sc74Tz Lrx:hwIue[%ݿYݰ׻dCkMmOٍ`bv.{֕FQtjG"Dy}-M!K,;H$%$J[U-m>:^6_E%2YmnUb]YalF$$B'v6ȌdF^m.�@օV%[֪][^i<zm 3I!Wf+*2wo\u+GDI{wS%AZҼ"q۫N{KvHȌ$0^ 5-bTެ7:feTN>㳾RhڔO>k)36%53X uЇm8| 2PN IGST[fQ%նխXmHuI_ $}G��4rڴ=Gn+:|Y&iTXiq諨30\R|v֚J٤˔<4`ZFg3qHTfdbi#"1����������������������������������������������������������������������������������������EZ_Oi�BP5~:閷~WxД<_u? XWn4)ڤ a�;AM nxx:��1X��AE_$7~�,ܮc6JPQW ߿;v:w+zҎ"|2a$k!wXҮɕQtՑ%ѸHZK'=:ƦQ(pmdI4gqDd^K9yxDFf;dzwn^7qݧZi"šJh0"",`ےbު@i#;*+i[feFY .[lԴ3jڗhPTi4ZzTl(*][XbW(,U9% Х3ڥ ȱ3iáRs`䜌|Jv8ħl +XNXOd;%UgؚV(dvH?"(%ilˉ<) mdJB2!mJVđ(ȱ]D#]/W=RqRD*Q&e𭕟Zw%VvS~.=ӋS%y}\h5mKwm{n.B{f:rc̒񸑌9j.>I׻g'1Kvx巍@ޜ:f"U%07Mkmr=~ݝ1ˌfIxHqy=7Mkmr=~ݝ1ˌfIxHqy㇀[Ҙ^˶йٿn΄\3$n$c8aq˶йٿn΄\3$n$c8aq&r.Go۳&9q/?o8Ügr.Go۳&9q/?o8ÜpeI)k\m EɎ\c2KF30k\m EɎ\c2KF30<RoJa{n.B{f:rc̒񸑌9{n.B{f:rc̒񸑌9�vTҘ^˶йٿn΄\3$n$c8aq˶йٿn΄\3$n$c8aq&r.Go۳&9q/?o8Ügr.Go۳&9q/?o8ÜpeI)k\m EɎ\c2KF30k\m EɎ\c2KF30<RoJa{n.B{f:rc̒񸑌9{n.B{f:rc̒񸑌9�vTҘ^˶йٿn΄\3$n$c8aq˶йٿn΄\3$n$c8aq&r.Go۳&9q/?o8Ügr.Go۳&9q/?o8ÜpeI)k\m EɎ\c2KF30k\m EɎ\c2KF30<RoJa{n.B{f:rc̒񸑌9{n.B{f:rc̒񸑌9�vTҘ^˶йٿn΄\3$n$c8aq˶йٿn΄\3$n$c8aq&r.Go۳&9q/?o8Ügr.Go۳&9q/?o8ÜpeI)k\m EɎ\c2KF30k\m EɎ\c2KF30<RoJa{n.B{f:rc̒񸑌9{n.B{f:rc̒񸑌9�vTҘ^˶йٿn΄\3$n$c8aq˶йٿn΄\3$n$c8aq&r.Go۳&9q/?o8Ügr.Go۳&9q/?o8ÜpeI)k\m EɎ\c2KF30k\m EɎ\c2KF30<RoJa{n.B{f:rc̒񸑌9{n.B{f:rc̒񸑌9�vTҘ^˶йٿn΄\3$n$c8aq˶йٿn΄\3$n$c8aq&r.Go۳&9q/?o8Üg鬓m Eɷ̒񸑌9Sޖ[ն.j6|f4,RD(HV&Dd}F. fz6XpqРfAmvcvlGY5�������������������������������������Uߕ/%3Wkw}= CG[c\ezI�?:w@OӿR~7}>Ӡ���UCpݎ1cjq|=|wc,gr1gڜm(+�H dmE}-!LDKpJQyd"ODYNpyxDFf;dzwn^7qݧ>MwfʄU۷k=ٌu瑼?,EvEB*nג{l:?ޟk^`yիv9Y3)7#(Ur)NQ~#2_'V^ %wpdPzG/mcz2q�%Xn,\<$?vzxtŷg?\�/6zh22 Q۽LkU$[쭇 <cMmf]D wL�XjïڑLUY銪Oqm)6aI)]]wPU{;YW{ʂتh_W.12m Ve[xիBC% {X6FTdн#$PKuƣxO=Jf!-P3Kؒ[kSWIGmu3뵔TGRR2eiISN:MmKIAv$vV];)GPIL'm'HD 0j5'&iE|En*;H")zrO$#ZjwSJ(C(=瀪dTZ+(3Փ{z=-\ɵ)R!5!ڌFK'za饵 /Vw=]{y",]V!vydX]fbrj[R)un8dӄ (5m,ʹnqi*YqjVx\̩JC\+Q`IC`J J LJIL:cRSyk^Ěd#ZJ3h޶Xq6m]zzdq4m|f4J,`dqd4G)jlI@*|m,VF#q[iSI2I b:%PW.]v"یRhњpĔ+'3ԙvaR)Н}:|GuXԤNCpKJ%8Mhzbə¢\}M*O3S% %$֣,a# "�ZƤQ]*HD;-}$:VĈHR<#o.\/M׺BIӯHtFS#2HuN6Tf\7 {[<$qdm >RƝUEStPҌ:)BKDJ^,*F۔ZUVY&ӈujIR֓Co#yud[{=P"2ivҪs*M7ul46nD d{R/OAiYnUZ%5I2I/5.:)g$IW!D(P܋}*NV\y:f}Z (̣Tz{:'"�ٿ;N>r1栊XT]:EzjiOPdC(5ҷ!E,dң#'\)}bJ&qRxgnLIo3%!g5 UK٧[=M-8Ng܎+"2ۭ+AT)Ry%FZҠ:lq y-,(Dj[2{~u<ܘޢ[e_-=S \m:2toZʹ{ &[ 5u57*7ՙ>bY͍JJjQnS8yRdFyk"S:rcT1!-n%3=g'N+csij3؎@Kbafѩ/Qk][pX#<ͅbZ:E3IIv,Y+4-TY`EnOT'0i 4mi49##,dJru2L-`ҚqetDimuMwRL /mzN}SIiW#r�IRKp$9JwM.Tgm}2iqiO2YqpGj2ɤG4mҴrԣS2]L&3%.&BJq))FѤM6}Im)aZUWKEOs55M5JjT8kTcdѳȽPF2,K';VU65Nڕ]}k։ $VM4O[RDg$g^ʬUFICd5FĄGRmƗӒa[C-kQZUitiK#\V1 Kk&IiE4f}ReEuJm2UxTP*"}GRf$lt^8Ԭ2ڣ1zzڗU˒ iijMk9/ԵF5)\~sg<NCSgǩE,p/oGgG'樰٬˪O=&Sm8 ,6 뾡kSj4B]uȍuNbL̉zg}]YߑU v-:A8h*\S#-e'OR",#ףɜ#a?b{3"}$+۽x5d#J[]~Q52uvQ&m*Lx4Qa]b-";5avPXj*-#2Y6}wxd9ޣ=F9TWhԬ!hM,Kn!sWeQ*TC#TzWJc~gqnS>,g,'D(LqoLZjJУm JI)z"+6︫w4GɃU)͘jXuYe q):K2e_o3MoL fyRmB%Yv7,eނUCϗn| c7uTY&uV/־3*J{Ar]y16+^\;S0쥉ѫKf)iq%;(̸T3-ء*D]NM۵c˨>W#9YTBA0ڒi6&FHkJ74ڊ{%W! RCڼГ#Ipy FP(u*c9*aR2mFG]28{Q]>OIkys~;gP/{SfeΣ>Ib!#d.K>Abwҁ߮y\#tN�Bݿ߿7l'C)z:Hu[УnCnHBS8ZDG7XE(1K#Ԥ=RxӑZhgTfJK i')Dˮ~v4w lFI:+C.Idfq$e1sԧ%927 {pjS`=G8m3TdW׻=}EDW_ѵtD7z5Zj�uFWVvJp}j3,̅%.)UfեN4钝Zf\*IuH<7 7o_$r,0GhO^Qr?\A}Qa!*[tWdi22N!aĽk\J7QP<ոh>2=�]gdJ<±ۚ*٨KDjܢTKQ>;ZJYgrzQ!Ize:4=5L %)F}OQR|Y0N6EFnܦSwEr/:ж<,=mgu'GNTl_d-"TȘ&4l�n2 צU v}rT]rT;u@7[0xm*Z[VIHIřGbA})b,e91RkqQjеDFFffE6̣'6$>),5,ҟK:81u-÷rNmNkU1MU{[btJIիnpjec҈իuzw2bVKu95Q5#a$Je).<i٧cGT43yo=ĬN)Fi#4m< ]#M*˕8'SazJUE7R9mujV6X< 4Vuu91fAZTr\k%# 4̐hu^>.=Q5żT$|+JUן $}3[GMh?zO=}ǩ̵ )F#9ڜ)k@TZ<[4whIZͶpR )څ)%Ťmދ3Ѵzg\\[0 n&mb<RmAG0۳x؏1[� �����������������������������������EZ_Oi�BP5~:閷~WxД<_u? XWn4)ڤ a�;AM nxx:��1X��AE_$7~�,ܮc6JPQW ߿;v:w+zҎ"�yxDFf;dzwn^7qݧ^(^+ۅ7׍Ŝgi>2sĊnݝީL&RDWUNٸ%zFgѫP>5Fcp"JX%2JnJO/j Nwاdө+4Kz{"gwXj~L*ۅ:CeR\I-9xڲ?'= ]Q*{]LϬDg"q�˅_3=<MM5R]~Yueȳ?g&%ي[a4Ki:Qj4l)uec��î-!!Vj}T3M$PJIssz#&T:x:SgC>nb$&I<)DY5B2KKC6[Hn\ɳncw3oќn8ٹ�4I&ݖR8ۗ!rl۾5Ōtg8ۇ3'6n#mr&ͻQXZ-Fss8sf�yv[Hn\ɳncw3oќn8e-\6MF7qc9h6͛#rnu)[mː6m@nrm:3mÙ RŶܹ f ,g-ã99q9r�;YnCMn#mr&ͻQXZ-Fss8saR8ۗ!rl۾5Ōtg8ۇ3'6n@k<i-Ԥqm.Bٷ}j1EqgNl2JGr.Mw&[pq�g 7e-\6MF7qc9h6͆[Hn\ɳncw3oќn8ٹ�7!RŶܹ f ,g-ã99q9u)[mː6m@nrm:3mÙ7 F4ݖR8ۗ!rl۾5Ōtg8ۇ3'6n#mr&ͻQXZ-Fss8sf�v܆JGr.Mw&[pq-Ԥqm.Bٷ}j1EqgNl܀yv[Hn\ɳncw3oќn8e-\6MF7qc9h6͛#rnu)[mː6m@nrm:3mÙ RŶܹ f ,g-ã99q9r�;YnCMn#mr&ͻQXZ-Fss8saR8ۗ!rl۾5Ōtg8ۇ3'6n@k<i-Ԥqm.Bٷ}j1EqgNl2JGr.Mw&[pq�g 7e-\6MF7qc9h6͆[Hn\ɳncw3oќn8ٹ�7!RŶܹ f ,g-ã99q9u)[mː6m@nrm:3mÙ7 F4ݖR8ۗ!rl۾5Ōtg8ۇ3'6n#mr&ͻQXZ-Fss8sf�v܆JGr.Mw&[pq-Ԥqm.Bٷ}j1EqgNl܀yv[Hn\ɳncw3oќn8e-\6MF7qc9h6͛#rnu)[mː6m@nrm:3mÙ RŶܹ f ,g-ã99q9r�;YnCMn#mr&ͻQXZ-Fss8saR8ۗ!rl۾5Ōtg8ۇ3'6n@k<i-Ԥqm.Bٷ}j1EqgNl2JGr.Mw&[pq�g 7e-\6MF7qc9h6͆[Hn\ɳncw3oќn8ٹ�7!RŶܹ f ,g-ã99q9U)r.]w&[pq�g ?Ga9MK&#ѕ HM.2SFFlka1c`�0\�������������������������������������V~WxД<_zeߕ/%3Wm=qۍ' osƘi?N�PSH99kN� V���PQW ߿;v:w+zүUCpݎ1cjq� (^+ۅ7׍Ŝgi>2s׊ykZ%#ՠdȏ%b@e2E (ه%ݸ-ٌ]Nsەg;ՓtXÒfnlr9ʳ,ǛWE65y yTa )CG�$6ԗ֜s~6QJة(玲4Hp|cE=n!DhYe vh?|�/6SM駄�i΄R_<mfTbgC$" "vKyիRֽ%jثfMR#ђ>g>k3Oi0BDRܔ[K$%##ǮC+jQ*M*y7)t'{46|qk"B[[)mh%YuJ9Tj||-R'ԘR yHA-$I&'8Z^3Q{h1TMi^z"tGXsAΎΏo~ښ.t[V6} { tgN+̷)Դ!AZdIh_W-SWo[ZLSԚu>Mv$!o{Ʀ&Ո4&jE-Zn}龃GŸ^9A</si5:乯9Շ:}&鷢[)xS~曇ʕ44m4B�uT~>hJN\(J^q<$JM ZPܕ6F{^Ctvlt[ӛBn"OO,:Z-D:S&ޒU*:Sxu)SU-eF8kQJQԣJZF-e3lJsUi rb<Pq Փbr%SSᤐt*gJd(:UDik*p$5n2%Y uϩRn:+YtIf+1b8IZq+7c,zF tH7j*؝%RݸJ5-a2kGD%WITgνT*I^*\l^;f-N>Hq 6hSHIxM850zK)&inc$f3!KSXZkcVbQ#5_VNiTK#۵꓄#ˊɑVpW@uVWmY 0tSy$Rg6$I2FFy$ z#ONͥAjN6$^[O8QRJ;lNڛA�S/CfϯVfTo*=OSi/3fNno>j^4ZLsB&[A%D(=N;/Q`g:֧tYqdҵ8RzKq]ɯ؎$; K0k,GS͎\q46%h4(d{bRhw$P5%T["RJdə6-I{id^2>锾ӺEVS?+f2yϳ9isw(PꓑVڎZdɉ9[2RjS qJI"?\3}P4%ZT}pbjQ,DL-LSMJبZCsA KJjb6;6,܅K.t/(6R0J4Zh^j"Ve^֔tud;RlQ^Jud;r[JVG;f*Ou7e=mԧf68}=[s &H"O (гt*uZiR-ʥmrQ*q-p $i3'jUʍRVָ-m:<JLW&8fwIiЧp$zU"YY}AEJOif*-yk-Cn͡(NxΙ 㤮wR[|*,gŧ0(u7)ɺ82j6[I@Mc #?DZR؝> ieX<+}t:6pǣfDTFĉq6(M Q,8,J5 wz.+s5qHkzS͋}9{{O{XWYε\Y=촭~Es%N>V\W|k#8HzwECbmARe&١{"KQ)T^q+Rc\qAk2%@*S#:oOb%1h!GQPgMu{ QիPuM&[2J$-&GEa2Ѭǹ݉ojqU*0q'ŷx3>%Ud9r@G!Y792Sf4's,;ǍkTk&W+i.ŎHumS(35T 2Q/wIH=665:<ؓ]ym<IDgYK(拾$:jm<tkuLҫ͚T.'Jiƭľm6%m^bbЯЫ$KM&",& ةJNṙQN)8m)Kh5-kƵ j ZU$T.+w]鳥姗HoH.n|9G &W-m8RE䴦M0ɴO>Hf[tЄj"#2oNz܇N@}yP]Lf\tU8m)Fj Q#&ْzsԽlW=<nMʙDdE'Qq,7?r�+u&eJV1%D[]֒kL$٤a'^ڕB򆚳\3y MQ{vs&۵&dfFCHbڕX}.>Lsl͙kM8 %n#*ڤW-[3Չt*IVNHjN]meBBS.DvjPR*tjV*NNIBXqXe֊tr4uMNpJMׯ̥iu~U;rr31ȤaGCo.mܢڅc}^wңnעӚvuZM"&EA*nr1QT.]2m8 <'T]u%¤v۷ܠ[-qf|r$4=8Gvٷ}jl+΢BA\JzJnS qO:k~5f}q@Ս7.sYKy B[Ukk}jUaElBIdzqJmQ->(лi{rUUKV~NC-ř^E9Of)LGRJR:B�p]_w>nrS#w.:?'jso C\kvEvMD0'FC.x-հyXۮ޹l_ZK`0ac͐qH3I6fJQ-'扖Uʗm:կ.t_WӞ>uv[K.jIFvAz·9KBɏoJӳ&fK" j;qUY.Zq-:=KT&Sj+6hqI:h*7y5_Ks]r[&ښSfmy^^efEG^JmOP.jW1oܒ*470H\3J3F2C3 H3Rr#HU~�xjγ&u>䊔$%ZqsrPQnB)#tԐ]}-LQ4%mrێmiLVzl#Q<Y\Ә%mM}7e*4ο޶IS[Tz\d*Tj%oAf2-ʇCA!ɌKd{Ďӊ5wHoI_@�[=t�m�o=�֛z@ڪHvҠʫb:D񟒦Ҥ &VgJKMa{Y,zN<9-ZDԃY<D[=y֪UCS!VvK`"<RaD7HG#kih4g[at`[w5\]V,mT)M9ƳV$RKgQ4bn[S#AU]cnC wgM[ޒ/~S%9.15Ϩ4M0qlU4%-SJ3^L\,m$d3z ** LWv.DB\%2m t\M)kuDồ齍6E~eZZ_J"C1،e8␒j3Y%85QR��������������������������������������������[+<_JfW=2{Oី mƓ~t7TL4)ڤ o|5@�+���((ۻYc;ٌc=XiW *!{gvVXvcV18QW zѴߑZMLs[I "JH$ f"/+ :w|λn% eFuxɏ2SV6&mdvhΡV%*l@h�.C/㐂�tӽD?JQN$oS7,Z5HwkĄ"SXm]B IBd&dDxQ d}c( $J"$ &e!R"L1CѫIt9J2Y-2Io#&RhP(V6Y2*djZPIR[sCчNubF[0'[}owI&~^+8pCb};MPqb)aAf6k��������������������������������������������������������������������������������������������������*{OLju|#g2½[q�;AM nx ' os?> i���ũnR$1>ʐr(lxfIavitQW&fgrE"]nq:&̺jl*kyL.>imI%4PfkI<`Xi?tK53 F+" R\r&@aJR'<)Dy"t^&I7fJRA ymL$<dƴ�lNǷjͥnȅ%e9–l<|1HFZ].IƑtD YKfddxτF;*)u ԖiMmM &Ifj<]J>"N} TsvuRK) 3MydF4�)7RΙGX˩҃in'@D\[γE)�M)MUb%ai%c=0*&,6xw).=s9Z>miiDo} 'vɣp~^[->ѩM%rV4*##%lYMڵj,sF2VJYg9M[uzsiٶI:dG\QC:=QSjnR^mH؍4q8S!m/(a>v&θ}S PL܇ IT'|w2j>`NjM^sq5PMq:>Jڧ<H>31Q2hVɴEnZ1jPb!Lj2^a*K)K&%rLԴHU*)ϵvqk(a\vաʺв4ӂ5%)[fWV5NcqB~%?VQT0lM.+][҂<fЫԚ}ۊl<T]D%{+B(S.7nrIjQe&}HNؑR[۝ŵ2<<y^plzCͼ/T`ĕ()x$j>IwQiTw>ޒ }:ۑi 5Ks\NuԷVAs)E.b᜜j7I_53ChRSPEMJ0TwUq)|uG%/>Bۋ8d#V+UJ6km5u~%0Hbo q Mmm9!"R4bԬ:<ܙiRɐ<#u՚i^5Է) C{' ����������������������������������������������������������������������������������������������Uߕ/%3Wkw}= CG[c\ezI�?:w@OӿR~7}>Ӡ��CW)}uX >OZ֞Gᑨ"<Z1ϴ ޥ;FtwDϭ6jq8dI3<ninW'+>i�/@-fa6HCA<DEڮVO�HtX^BAGh& %(f]:3dSk+Q U$,vI7)Fy3?1GF6ˎl"IRc#DŽyL&Wdi"f&?ݾ^, 0o7Za>mʸRZ(F`yR.3WF·@DX$, >tz\%c^ymKhIeJ3=3/dDCQ#KUIe٫gVBՑ4*ѻj m:O_[b#<,�j-UQt-?'تV+%�$? 7_rl%Lg* xlRTRjJe$}}l]�������������������������������������������������������������������������������������������������*{OLju|#g2½[q�;AM nx ' os?> i�������� Doc{7vMqgxόuYJ3kB""5-#<g<^)*jԹd'{Y[.'Jdeu!{3KsMx9ٜ~gq2R7m5fsە{Zr=="KKujlWY+mֵ%oYٍkSjD[kjtyf$B�DkJڢ,vL> >׼<}�)RY;w ]J23J=cStV#.Qn��Qp���������,*|LJg<q넕Hp #? D^ ' >1T!;rVqYͽs;2TGRD*5%9/4yM$Y'S(We- CcTۦ2/D ѕ\Sm\y74dԵRӪЪ" &CcZqdx܅HQvdx21iFuϺ%z,Ewc1>3Vm2n74%$5nRjeQ.vi?Uͼk. 3i: .686ɴI0?EoC^�D(fn\o1ל cZ7ښNjYvaЇ{6#π`mzOpޒMk4RQɘ[)IK$J|ԣ-iQ'~Y+&m RQjz׈Pe6t}ڒ qBХ$Y Fiv=Iզ7dj$Q*<v' cza<kul;i8jDs%(2FLd] :#:%Tꮛ1jNqNLGP\: /;LNIk*[Ą R][WmK~̻kvT T̈ndذ2ؙIdql7{i%M0l}Z}Mjt\4n ʫLn+KpH%8#QTxLalkJkͽw2iџㄓmɫ~ӴXHGe@r͸d$[mJbYQ؊ϧaHlAGP+) PtaZEAbĽg1{U)Zg> ,TdoN5a7Zq-6J|/u@�,J9&[GNÆ8HY*48}{V2XU cŖė:Q4ӄ0DyJ6j}CXWY*UntiQVUt㢓NyP)RvcozN%-lT/I{{.Q;vX،6q];krD\8^}-23RzX4.=&76\Իutҧ\&UdBXeTwДZ6$mnbk^2ȃZ2АE 2>r+(q'NaQJ%,m\$rk2"_AcQ5DZ̒YRzm]k΍@ARdnN ;FmZ xRTzTkM9f^pTTHb\JӱIdLbȔȥmJY *cwM. L$)L[ʚhI6 41d)/si)ejĄ6Cl*HTJlF[ Dioȕ)m[IFD<GWE_[^YaUPK΅F|ZܦR"2"+ Ly6uSR#N-t]mEI>詜zK&Ȕ<CO2TڝR jl^5o8F͡dr.bdՉ\Xh܎[-4N#-/nCT}PKtbUBm:}YDc`yS!EC2D'BqA–%RX-tNÆ8HY*48}{V2\oJUoz&2Ehq yʝy A8Y D[jZ[fIDġr(AqfI#T%m5mnXr a !plЗg&N|bζ]ZG~D#U`CoMIVQ"SpSO%PqN5ƍjZUbTQo􋢆4ZmYɅJRJ5�ހjQeWQFwʇO[IxAdM7S:iq*BA8�����������������������������������������������������EZ_Oi�BP5~:閷~WxД<_u? XWn4)ڤ a�;AM nxx:��1X������������Ċ=xFI\Sǯ&#?[lQmJMr[OflFd+^V%a). ?%rE2ORc^$(؞[. 4Ӵ[ܸB[m{RI`.%S9UikKMӉ\huZ䒘obT7SfKgޡ^ɨHt4ZjQфD'j.R4)f!EK-Kzf�����������,~$yYp9�  P8DZ�|4 |4$RG��iI0Xig8,#��� U*ئQ'֦ŠLɬL5\%%`>Ip^q3;  !IC�ܖHW0ktyc!ڢRw!di<))2ušб->;N]Ou}ȔminMfDj2JK=I{�8EI|餏iC;K> m/`ig8,#�A�|"",�����������������������������������������������������*{OLju|#g2½[q�;AM nxM#a<۴q)3Ki:c%(bܤOQ7rikN=-not=C =-not=Ax:z[ l{s;t=A9w�l{sr 9KcۛrǷ7/OKcۛ-no^pǷ7:[ =-not=Ax:z[ l{s;t=A9w�l{sr 9KcۛrǷ7/OKcۛ-no^pǷ7:[ =-not=Ax:z[ l{s;t=A9w�l{sr 9KcۛrǷ7/OKcۛ-no^pǷ7:[ =-not=Ax:z[ l{s;t=A9w�l{sr 9KcۛrǷ7/OKcۛ-no^pǷ7:[ =-not=Ax:z[ l{s;t=A9w�l{sr 9KcۛrǷ7/OKcۛ-no^pǷ7:[ =-not=Ax:z[ l{s;t=A9w�l{sr 9KcۛrǷ7/OKcۛ-no^aߕ/%3WkSv<RO? CG_cO\ezOL}Ӫjj5b2JcY'rdE2"mmH_n\+p\dm+"#4"<?ԆJϸ MrcOTR 4a)RTRiHYRM$E, [qTm51nJLLͭd,<YIqxqf31բ~GSGY|�885`ᔾMOorq7o6FvV$U]#~K 96#&/LG](ژĤr\8-wNuFٷwr~/P_17g%̭حIT˲nZ&N =RK=wocoiPMuPT2h5VmNaKy_}H"s)6JcjH "LS.Fk9.rӍ-)xJdOSɤ)&g/5LvmO}f[pp+!]p4{ S3Lش"VɳL<ԢINsm wP$SɈstgkRHԷQ')&GDVfB"_Y|�88wouŜu^SbNMrEp̚xѾKB27RmM(Q-D;F]0ODAd駡D_n,&_^8_9'9kS.D/DZC%Jz%׍5ʲX,dX.7DTԩm!.+Bj$ӜDG?`D6[Q/JZm:5:,&,r5nv:2QH3C0df>Sk:$>#vqQd1T"AMJ,3>i)Dr2woUYV�?;7PUYV�?;7PUYV�?;7PUYV�?;7PUYV�?;7PUYV�?;7PUYV�?;7PUYV�?;7PUYV�?;7PUYV�?;7PUYV�?;7PUYV�?;7PUYV�?;7PUYV�?;7PUYV�?;7PUYV�?c.UW+S" LJ[m-T$nV+vrS#.l*d@WCq2$u[pR7fLqM_ƨ.}F%4Zu'ؤ/(ԇSUmj28ɩI䦙OxM%j6 :c^fI. RMI[٦ثS Uڢ eeeF<9 ӒRUʞe**^ʓ&ܒs%S\=13Q (ZL� &j#<_zL}r<Ȏ&O2&͹ ć:q T(`jZ2 Rmt(J*+n?O/dc(w|-׍Ai-Xkz ckihQ&O&]Fy"MXH&&Q0͸)sM7&Rf $}}J;LZ9D֚u90:k()}<%L}vꭱ]F]5)1ܔ= ԄY`GQz C2ץ&ǥnEdҒ%0nYi5&fbiRV MtIYTTr"WexHpҕ+&+2ZkTGZOeg:m&Wc%),gSWtjg@mdMW>DXckLRp).hkJJ1p2AmI4sNj.SԵυ.,S76[Bvˌ/M9x~iq'{&+P'Zʩ]Lq$Q4j5)IԒ3#OYbB "]2LwH͸V�E;Qird7;}4mϦ-*DJBMJ6ȰDd(uZR*1&c%MrVĈDK(SW!plVm.iYT_["?i&-kOS� [)PdMrA;jum ,JQ""33>c[q&j)*|+db]9TyJ1:]KAi -Q1ꮰ̆]y/ 񶅑j>#Pj VT̪nNi̝v,fSRm9SBHK#TMQm?)SLDLο6^ߟ. y"ɭJ7I"3>#\.δTG)12Mt̺8=U"77S՗={|ȶ< pfk\;ܛz{2)7+cdN VívݸKTgoݾ_DSiD�c:ZIIRLFQ]�8}OJ mM5>6<w҃RD# ;LeBDESMutT dEWR%.D)J\N&}bX˝M& ̶Xmk\uIDLdx< Otqǣ@"< &+G"$VDGw4~ݎfӧR)E*93&(жdPd5!ĺyf[g\?yǚӮ}u Uv+Rjh!WByYqՓmI,zB.w#|߮WkJPX!5"J }H#RjK3${ȍ'ggN{V~D:—Mcdɫ3>o;Ÿs<'?sI*kI&U52r _1G$sigb-wB[M8m5$Ldeޓ~ښox:OTiTQbwVf~6ZHȈ$W;[ji1gSVHk}',rz[!ᦩb< u֭ʟqaf2V\uim<}RK=˧%w놵]teЭBMr;*dzF"sJeiB %A̓gpFUiMnLjCzYét(9[\sGSiI"޷|{KhXdRY:㐔26Wx=Ic#KwUY <jiL?]Y#>T[Sc>|i+O̖KJiND#"I$c6Nmbiݽ OT iiSюENp(FFiD"'ۆ{CQ*W7Q "[ =�8?YI?X_eoPٱnNfSb֮^ 7cteLO'ҴG2I8jB)/T#٫A*Uf-YlU3]pk�JM_\5UZ4%P>y2=K*~-WR e^])}$3%$ }tꝷ(hږĊueiI72K 4IɲMo#]yQz تՈ[ᬪ-Yzdgy-HIus`�":{^7on:>o:D$ڑ'<7#5Q{#xԮSU:J]3&SҧY>dx22[}nߕDO2u2yE."d}%i[%h*I6%65.,S6 Uk̜&Kv13N<񷼛%m𲨢w}k{uVZsZ]>F+\9]܅Te:VHZ[JTO!oQHkQ&'f=a3h \lERGeT\NfQ-ܿi4X#1b*}N&ri6tBُE#qL}_ơ:vMlxSjM=OT#~7GI2m đJB˭]mړd*<IS&]NMз-jB L姤߮KLg1~v7Lc\s5މo2&*+yNFgcԇ/ȶ $:-}%-$J4H2#ǬbOjnaT+ pԛ4;֥-8J 3Q)fGבUTz{*F( nS&"[uea/&/H{"fwfh3)gSNT˪XRRzsb\ۓ{Z%Hæ]>F+\5nM*cUujKd{ZPUO,/MIq)32e#3BQa7fUE.&G:unttI;"d]RT">' ۃVNm׵]q&MW!w,4È#ZIBHQzdBqjVU+)n>qu䓊47F)"3RF}B2GSVj1uw#Jڸ&TFjhY])I”,jZd\-MĹrEsJ=ҐAn ҍ32,6Y (l쾚Eq鑧Ǭ!.&;Gfu+A�dJ"lے HqSH}hIeJR }EOiHW $ę5EZC!,M\ݳ[ɴjIfjRYn.Ï_z uWXfC.]kxBY5Q//"?vYi@C^=jZRϩ9ܔ8rv#_E^G.mR!; ˥e+KFY#.WNVojGǓrY[aJy+m [n|2I9ű$;jڵJ C(qTfri8嶝5IWn<)Bkۗ=:rzMYU[UC~]OQ-tV%tJDNcig] I)5IH+? [`]s2StZTّeqĉ&iܦPyn D�aߛjiF))㾔R%O]gbbMxN_]>F+\2r7]X�8@W[qg6 p2VKVKv_V|�88gl0r*O!N4ëO�Ḭ^,9=m*t5"Dg̔D~1u|#xpYnH x�lmm8.-_tm'llݵj !M^8/=EAKr; I'Ȑ �u@S:'և:}Hh�udKq&_ЪfFB:LM-a]9SB[D2j\)Jq$`X,u`Սv(SVn0 &RL=Qdc2Gև:�wz:'և:}Hh�w}Hhև:�wz:'և:}Hh�w}Hhև:�wz:'և:}Hh�w}Hhև:�wz:'և:}Hh�w}Hhև:�wz:'և:}Hh�w}Hhև:�wz:'և:}Hh�w}Hhև:�wz:'և:}Hh�w}Hhև:�wz:'և:}Hh�w}Hhև:�wz:'և:}Hh�w}Hhև:�wz:'և:3yIl8Z|[I9V ).`�;>,tt~OJ�A'߅ W@7U}Y?*�H�;tt~OJ:? '%_�wޓ WAGGd� �}Y?*�H>,�ރzO:? '%_߅oIGGd� U�wz t f;yYn<Q-X=""W=Gw߅oIGGd� U�wz >,tt~OJ�A'߅ W@7U}Y?*�H�;tt~OJ:? '%_�wޓ WAGGd� �}Y?*�H>,�ރzO:? '%_б/^VYӤ6TZ*#3ݞJO�A.:? '%_߅oIGGd� U�wz >,tt~OJ�A'߅ W@7U}Y?*�H�;tt~OJ:? '%_�wޓ WAGGd� �}Y?*�H>,�ރz\aSzYm�4JKY6gLzc~F5TM"Uւa]]D�ރz_cꭽ6U*ͺUp5$ A$$DDX",eTgZ(4Vf������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������krb5-1.16/src/windows/leash/htmlhelp/Images/Kerberos_auth_serv_fig_12.jpg���������������������������0000644�0007046�0000145�00000043755�13211554426�026300� 0����������������������������������������������������������������������������������������������������ustar �ghudson�������������������������libuuid�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������JFIF��x�x���C�     �C   �0"�������������� �B���!"1#2A$3Q%&'45BaCRSVcqt 6���������������-� ������!1AQaq"2� ��?�"" """ """ """ """ """ """ """ """ """ """ """ """ """ """ """ """ """ """ ""6|>ia156"L#[!]ٿ\;17ܷP<_%qŮik}!aثvd8P#0!!1wbgggvt_vn?SQEV7O%k?>۽2[w_SЫtbb/L Ew\ݍsIG!ղy,4=Ŝ{LejQrI~=>3e{|jˏgfr8؎BbY:FV<~汦Qb&{u+főĚ)3|�KK/z^?{ێӑc5zc'KT;XfE!F,&3`F�m�v�K_r ^rɓةtlՙBTJRn\:lC3ٜYtEg1_ۈVc$SFL@bLB;:lW v6X7I%x`ayCa"ʙu/+ۭ#Iѓ1 ;;;?λHHYJR -޻ӯUJi11y"YE컮fnƹӣ<FSX L =2a(9aay$twb2=VXedz9?lG! 1B,#+?ƞD?sX(~Y=3?MV݈ a>G�_n/S] wzȃ1W{M1Eb%f,3TwBXۖ0_#uz�s�ӯ9gx9`dlT6j̡Z*{%G)g7fI6v!,l:"qTxH/pXj1)&q 1&v!vwggng~`6+n?bw]wͤn<fm00<0ӑuqyJyeL: ֑hɘ݈]g]D@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@T(n5\pclX kb^K 2#8DL R8\Vc�u۳}uJkTO8Ez7G$Gfrwv*3H ;Oc$^I[+ڿLVova)&fg'af�����R˚4L{Mv98^}GvYo]7Ⱥ+X}chz+A;rO;3äbĈ43ܥ)d*۷BFL&uʼnAgؙg;Ȉv\ �6GU3CD?4[w/V?N}ӕ;V.H+=dzs \v#ݜIgqy= o^1 :JvEQhAcawf&bnY۟';W\,pX3s7Zػג,;;8 N�W?wvğu]R08^bQٜ݊,RN+ג{JJiDY�����yW)}' Wr;~ aaC�&78ovH-8e dzQ~?{58wNJwg=H–31^ܓ3|Mv.?yK8܏3ԵHÁ8?ó*wz7?qsy0(cfX??tQv6g:ota\;r(p؃y~ wr"D 933s\ ن+1خlq܉ 7ó7 �m֎�g8\~�at#i ^ ~F Z%*w {ύ\Wz-kf;E[#>G8;$zS:>cu|x ьLܳ;?O""" """ """ """ """ """ """ """ """ """ ""|�fyM5z [֧Z?n}>13!r/l?A_'/w?d&ᛀgȃfѲ�R>G w}(UzVB=ˇkǞ l?[=T`N6B(.˱;;9 Y[Vk1[e=8N?#g]ٙT}_025e5L&3bbɘ@f6v剗>pomv.Η:jϥi3ߦ5/;aXƙ)&82 :֬,V~:ιO[- KVsɌwr>~E6yfl\k2X;""&"le{5]#`-gbKr-Ñ+3ب240s �u.s?˦3Lff;]'m �MʴǭJC ?wc8f}ݜ-F}v MV6XF^jؚɘ~rg>Q;VoZ~ɲ[vFx.|mfuިᙗW �4"kzri,_Y2#f<_w"}ߟlϤѩח~;ɟ}J㶝{bҔR9R+g$^ф0ucv? uqيy3=�Zr)az 2wgg]j~`⡃*x{ǝyx<`D>zH݋>bt\80I oP3bKM!?%$JE$�Ԍᕜb}~;杻3f_N/h}l_4ի? 1bw";e �ɹYP9r}76c%`gwvr'g'+MDDD@DDD@DDD@DDD@Y6�~O)f�Wޖk|7ZGϧ""}9f>�Fd<ER}!+�l<3p 9iT] /_Wfh{J!qfz.\rRJf1>AcŎN@v&hKgv煋-?kK֝�2z\bgk^f48X_Ysk9>/|~lLd|�,?oGly8jh[ئ;W:ې#;?ᛆns-[=`KS3@G 308�Gd=c;wgNx2Moq*y+T5l8dgrSB8 iZFwrgb(�˟Z)y[ŘVacxj*)b3`f8c&ܻ:&[Ggđ3 *Z8n;", ؙXJSNX|uu]<fZZ~{AgI˗)xm+lۖ-wgO\KMI5ƾX^Y%_`pZػV_/&Fn b ,az6\ -M93_ED(9?afwvgvfve~PB8Jccig) ܍�̉skw>r{]'f4v3f_N/h}l_4ի? 1bw";e �ɹYP9r}76c%`gwvr'g' 5c~el|6kW?K04B9 Ũ ii� v'}9E;sֲ wԖ=XdMȓ,ò DTMedtϭ1jX�u`i#OFQ8! :B!{@DDD@DQ{6͍0r[>ڜY݀32&�0rC2DYٜ(x/mnn*~%[ˇX]Gbu5'sNK/[z9d?RٚB0b gdEn5iVDģpq)7.M?N(.19j]Ō01&03b@1 ؀H]%Q4=%W5ӶkjycI=D8$Xc~el|6kW?K04B9 Ũ ii� v'}9E;sֲ wԖ=XdMȓ,ò DTMedtϭ1jX�u`i#OFQ8! :B!{@DDD@DQ{6͍0r[>ڜY݀32&�0rC2DYٜ(x/mnn*~%[ˇX]Gbu5f7¢Zȋ6jqԬ7hG?P'Sn]9 ~QAn6~G?# 2#8Vvg` ab.bȓ?ʧm~0�e`1nv})E$VN$#56#ӑ7l9H20+ְ�2՝"XR0B?ol^G3 M |TY܅,BDD% ?av`G&=_\c! Zz`2C` _c/�u]'A#7w66K880%zF8l՝01 SFfvY�u� �&{|v<\vAmI |E#BH݄ڹM0~"7dWٷ vƿa  ln.3.r;EQzfane" oWLln~Gx`gҒ'y"H)Ñ~FlǻyS//B5fwa'Ǥ9,RuΨ浑n:[5C4"1T:ױIz 1[QˎNcr"NBV 3r$ó;s̱?x {&N| <psvL38qno.UAd󖇪la.lԧ^Ɠʿacncc~& ;@ZόuC<VbxNl$ ˑ7˻�Twy JIy1 ƏwN )5f~+RB)Ŝ%E3^HRV=lA+kB#$ %rGhsEк.Ʉ 2}Z%dg8a+!./šqe*OK9W/ )Q͛q7EbiI]33P6KaX�wjPOpp,C)L]!gSʟ{HrQڶ/#&\ߪ,BYia!""?ʁJ�w}O� ^^K.}ݺPӗG^R?z1UhՂsGr yHIۑl՟ξ_n{ޏoGoOn۞pul]ԟQa<1$ M #x͆OZ\}pGikJ9JG#^Ewfᛆ\""" """ """ """ """ """ """ """ """ """ """ """ ,%< ][~;Z/y/P*YطHyf7/]0<GJeXw] ۧ\{C$!>K, {]y.N4c*lvOABU' 9&af((yӐ ]Iqʕg>Jx!iL!b NܿQQw]G=>BWW119՚ʼncby䋡q^yJyeL: Vhɘ݈]gADDD@DDcǛ>ٰo<U1!#W7"& z gm/#xc9T؞&ĝw"rlb1_ۄةf6)&q 1&v!vwggnQ5lmm/3n{x_!#]G;4!2Dy)gQ h֊ 0�7EeDTpD3|~LD]vò ^mGvbr3K n!ہ,X"1,Ŵ>pgzl.o\p\0$nJ2$]G�ff7.x:L<2G#n  bDfD,3*./w:Ik5& 8| 9lH.둓335ɹe~W,oJ=n foقQ ӎX@6 3vg*/Ƶ\q7Y@b`챹;3Ii'0矸?{ȷQf�&r 17i6b7az.ۖiN&gxӔ^ѭw-o++NVmA 8bnDggn~J"h{.Fk#l=l_#P $rI!!'HB h vөz؋\^h-Af3KZL9cٌHŘ^ySsA_gM7=p܈#wɆXlD/S\gR_gM$<p܈js3#t.YXk/єr՞f%8g r ;; 8O""" ""MXH\H bg/&QZӼix-auJW?L[9uV��ܿ��YL'V硬Ԕf3$x i.$3X'b7[/OT>!^JѴqC03333pɸp2~}Cc7͇nmJ~b~!;rl=߆f[ϷAyL-\~={c3 Fp~ o_*s6K/s{o^WIr$gaȿY 6 6'7cԓuJJ\7n; 0! wbj9 I=*6R HYͦ,L#/$] DE)128p_ۈ,WZF)&bv!vvvv~vui[ԞfmN70 rvq$ac6ٵi6g�MgNY-ջK1!gcqy:Be4] ֱk9F MfRZ |NW!&E^cحssS3sU,cDچ-ҥ'� �ЌC-hcߴ-tmwh<43x*F9ݘfwnDDD@Yk)sWT[ y+%!F3FE�F'Hv\ǚv=:c: 2 X8ؙK$8$2/V,ֵ0Xڔ32'3C'rC2#9 ܌;X]<2;R zkF b"�",3."" """ """ """ """ """ """ """ """ """ """ """ """ """ """ """ "" Ɨ "ƿ٤lVيߌfVņnY0y8`&2NQ{F1_r%rrVǰr$;;sˑ-[5CqT:3Iz2qI ""lfnƹӣ<FSX L =2a(9aayStV�ik#]c*A%zu= M7F&"$\ ;648lD߷On%{L828E4զwbxb{6nC=ܦ^�G+vg'c!!A哤aZyȟJY/7zžo,y]$p>ޥ[S%&\"A.Nc#p<h8g9B vx¡o)!2z .E4M]؈3ɂ��׽۟.v^rɓةtlՙBTJRn\:lC3ٜYtEg1_ۈVc$SFL@bLB;:Ңo.Jkk6= �d":멳$1 `0*KyiԜsɚYnlb{r&9 8o~:p�[+#6t F`#� =kZZUmJFR!I!FDDN( 1UnwoM })"w.YX9!8f Zc{Ƶ 5?I|$]` ێl2Huػ{�R|J?77cc/R1si5 C3bʙu/+ڭ#Iѓ1 ;;;?΂ 櫂8,ml]uQya�Ydvv'G�)=;Oc$^I[+ڿLVova)&fg'af�����~ynIU*AS >ӊ,-ث"&&˳-[�b�Y8V{v IGhdgfiI߂n?4ܞlkX~Vҧ-|F.< ;33|;~Vsy-v[2`ŕޛ#Gj[uaqa#ǔ9Y@ęݚ3aa^ +TahJ&%Kq# ؆˜c1DY>ch5xxe-ԡp9YB7.CFٸw,Ǝneui!"]z-B�Cb>уViʝB|+$ZYNVc=9.F;n$É3P:S:>cu|x ьLܳ;?" """ """ """ """ """ """ """ """ """ """ """ """ """ """ """ """ ""i ,kFn͘MelXi˼vc c/q^(kXZ`3'+RZ7+ a { 7"Nܳ?(�ڳs<ٚs=_kzZn֏ᛟODDr~q^5 SA=2)>ǑHQ lH"skjwqYҿ$d|[R? w.Ks6G3-oJ081,Y_ wtO;kԣyk[xO9 ϫ""<r\׼\gd0�ݩ>wbGx8r$a\\SN;O|5Ik~~KhenY^˷g 1BH|ugo^wvm:=s+X&-{ME慠10�ux9%#LYWSWƣ|g`Sק^R6憤$>�[UlY7-`5<POƅ ?y xg+qwf5vF*/f{vm~f,\7Ig{Eݲ6gѧ%10 D./ew|K堸vuunPfN/h}l_4ի? 1bw";/ rga%o 9+mhK,,NO""" """ """ """ """ """ """ """ """ """ """ """ """ """ """ """ """ "" d�Pˊm ֯airP�Nr5ve-z=؛'nY۟eX\LGN٬٪LuPf9$e!bAۼ%CaGmZ^P5KY, G<V"):8w]Am�M70G6RDʙٹexI}Z l1�,xv^W79s~-,,Zc6*KΓzQNY7#`df2ߕ}$AF{Y< )ZzqsȋnI>ۺ-szv}ӻE^(?7C)z\<UfI^""'wc#+"uCEy࿉|w[コlk/.aw9HŊmfٱW+gS;fDRHfB39;3<gdEn5iVDģpq)7.M?N(#Y DD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@P[߱ f2՝'AX$QcU6<ŀŹڮ \OZ8P؎ox %R 0�;gfg('8f!&.)O=o(y[C_.uow!x,4 FBBO]c�[~?&>];vu{?cy{wHVV 1-w@1!&g`.�θړ,7F> ra~Do?M:�po�{M;sx[nZ\}pGikJ9JG#^EwDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DTm6M C,zܰ׽n d.lǫF]v/(O%?鶶+nh IG01"ffAkiWZj9/'v)Tp4N\}@wזxu3>gغjT?-uL=K1bp(C;;s]~p^6YnJd�sTA( 397~UU}zfln yK%G)qs&~gv.4_ =[ic%-� 凘]ωfyvIu25^S0_#GϦD^33^H_֡uJ|<Qf/Xh�yXه'vfi۟Lڮ,f=qxQT^]vUsG^{rpMRbND˻yc_ٯev]ŜsdQI+HÇX{||V׮=.H,�ԶGdRhKGvIk0zb_ aqooVw-/gDiXUmJPR{2MH$ yg1..qd؟׫fMUj3A<J119?[6dV^<&9KX}o�|/r+yoI9۟5UwxlZ;o*{ɱqᄣi9q~xnUtߨ]3wb2u_g"lߪZ8 Vg&qsn\Xx]şW7yͫKEDB=-Vbτf+aM4pvR,3^Y5Yۆ g@Cdy 3H?!-)o2Ϗ:9mڞ[a߹W.Za)>>E.w^+wIbX0Id 0&,n,x�fmZYFF=nxf�E^dv{WkOk)D"e{sL L3{lZCy_'z|.6n:cֆ_f~@wg^BzˆŐ9C-$nH'ni& ؽvw`k;z#`+[fL*y Vloqn9`/�aKsGW5nWhvkV 7f䙹vvxg=Ώ|8xz6uwfXoYʻEL-B WX'Fcs8oSa Ⱥrѹnr5|m۬[Y"N)&b`qțz/#'Cŕz?Z`r*qh Vfc;q;(KZg+9P5 F̑NNBDn˓ ?)u�occ9bz<z>~L/b3^g?#ìl:R8GOw.\!hm3fb/~i%r~, 9M/Cf@1v{P7"a=/Qֳ9*Mn*ljpY '~(ٝV<bogj'S +?`'kv`x?P~~>vfg\G۷Ͻ8שknmW|S+ock潏8ƭ{QLfQ4]qnqlۖϞqd',嫒2@ݟ1᜸Iɾ]?T^6тJ8;YC4n;0:al;eozKZLdkԘ၊0;p\y/ˁq:mveχb0=ƛ6]>z-KuXfl+FO#3Kwgf:G?RC;Sc炯 yLJno! n&Om9 Ak׵;2ӈ ff#7 w"/,?X={G.>%jly&s#BNEND<<6'F6KyộxY|?|>A|Gpl>:ֹbX ez#�.$ ܄|7ߨ]2ˣ&v킧=xkB5-w)$ a1rOR'60:v,{YGgdU,5\}*}.[3 BJMo>ZӅoR2޼RO �,ڼ=<pn=WUW9|f9ou_VOG|V`x=j'F*Zq`{3i߰ZI1Wp[̓؄Xe?/ff\rry? b“AKf8Q"3DNN_qZzr/ n,fxb;fv3⸜?~;fk8L'G V9Bó/2|f4uLӵr5#Ѳ.ZN\3? }9^EӋ/yN �BliOA!cu3;OUkQIc?Eo<n'`bn fC#^w,6=|IhO g5g,VR9.H2L 1.0pbףi-οzDDW)?M#ݣ8~ݾz<|xZfkjfcfijɌX n;331;HM3QA!o1bO�.2y[ 7; Yd53duK$}8"bq?qֽ~VEaH70嘝ݹ7?!s3O5UԤ) lzӖvv�NV4')�?fX�<F8;飒ݯ!B%J)K ;F 1)l[ُ e9V_,JY=N }G= I}8:FM$z7n ;4ӷ`Xa[>YVQF>zr7x88nXXωcXC qfi (뇴0 !=g&osZst>G23.c@XKN)~ֳ-ϖoȮjLw9WO%k Jmig@h$w!okCFv9k <bN<g�S]![)r0/߆ )KXf"'fO܍.[SvhUX5ݞpÆa5qҜZȱ�فq)ŷ�W{zؿ8o Y'j7O!oz-j/sklV#R 8D5iLjǓexƷ}ۧfK5$Qvc (+qv]"vfrv}0&*c9-KT%x#)%#,Qpۆ �R| vZe] -9jMVFc)6v&BL.N"[^rpm>EfF+Ʌ)SNR5 "BF?d=>m?xݳ{PųMVK%VXE @A\qȋ+5JV[%2d 5k9vbgYB]f&y:Ԋhd^n&?Dyi2~rǎc9i%Ӌ9Wv'S:Q'1VmfbN~ r\*fˑ x-a5! f*yd}c"(�6g&a\sS1;|<}BV1=rk6y&gZG~*Wj<N#Z3T`+0BUiO,a 0KD䛩uK3e18;> fݰˋW!3۱j9EAm;~ߗpY~#T[qն+8e\6(5n4l3,`C(U:}![+5 �v6Q5Dy;pި}s+e98e-=!}G\ղ# C9r8[b"7~\i&E|]elUZǍ"ħ-IC)@C� K9c?yN,~olN&ycb2r:ض%x`JrNLJ~]^1 %w b,A T+Cأ/fn~]oޮi>ưckbpɴ;ݭjqz1C9X'Vr]GιAܭU-{W3xsj1JE 2q<`"#p%�{]o%6%y]׬׆xc.y~ȏrͤ$T|nVk&HP s yn9ovY&L9K?SOA<X;(7Ի/'8Ѵ,E?^ )~ \J$rWhIU01Jq~xg~X{ӷXSLg f*kL>{xČVQ/Xe^)cspmYlg>gvV-dg CU#&+w1v!rw oN3[[grno$1Br0wi~IݜgD->*_NU1l|^N[Wzr|O?w<$YF-<`5>jԂٽWSɞ۳ηe;ZgqGWK^fA4$ n$37>v,&r<Bw/F;ߞ)�<\0_%vgL3'[ HdxmbmUiFYfbw 1ߙ9gn>s [I*,<9 {$DްL�w}$=5tݡnf/e|K k7pMo)Q LP=Xy)F$bRr$b|̓B^0vi]KˁEw\mfc۲g0lP N8˗DGZS#0:7'ܷ͘-z h;z}E@~~ߟB"I8l�78bzg!AwTox%>b ?W#gwgǗ~yj%T &8a:C8Dul` ċ@J7fY۷"bi:\}^}}(WlTFα䎤Zδ<DqzI72 vb3 Owv*vd4v(Oُg~*C$sϘֆmڄy:Y; u�𘔦<8gG~,`l6#5)_0+pQ;;4}]QY9ly:sv}pءz,D$"?oFv~~熹")&&"۝DDUD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DD�������������������krb5-1.16/src/windows/leash/htmlhelp/Images/Kerberos_auth_serv_fig_13.jpg���������������������������0000644�0007046�0000145�00000023677�13211554426�026302� 0����������������������������������������������������������������������������������������������������ustar �ghudson�������������������������libuuid�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������JFIF��x�x���C�     �C   ��"������������ �9�����!"6Vv12ABEF#$s3a&f���������������,� ������1!AQa"q2� ��?�S���������������������������������������������������������ZCcc-\Mi#RֵĔ\:[7TabW%c9\2piH_="IlEݖ@�c@����������������������?P:Y:[slT!Y-2>'a8Tj6[& -K}=v,3-^Ӻz:b-xVivy%|[m}Cjkuy6bcպ/py(k5* ~D-0S{'de)&|iՔ^gCzl L+5&fܽ<ഩh"_LLDƻubu>zp.;u!Zώr$u72 /Cۮ=vօzȢđ"#.pSDOr?߷Qdh.݆sxdJ�����������������������������������������������������;A5g;gj#[XհU&;IER+J9)(A9>q2eDFe[R)qRm8zvoOOctw{IoQwU~{O%&S|RM9mldDd}5L#)0k'GR�2mm^f~|Y=gQqR =!8❛%Nrdmhm\S2QKm-5u۰d,}p9",b)DiRжgT_0k'GR�`O0(dDSh]Wo9{>H (ͫD[2ӏCZ`KN.zKw>]Z]Ḵ)y)G^~ d_&F-FӏߙSL|aYKPlnmcX=V6aŖrC&=FTf5{+m�v �������������������������������������������������cӷ66d{)cӷ66d{�������cӷ66d{)cӷ66d{��������������������������������������������������&=;{kfKœ&=;{kfK)&}LXt�m%YDJKf4ۗo\L,K}EE\U-12?KDn3=SW|$J2ooᶝ~�]}b'YeDtT* ?XI-LۊR <jKѤI(uA1"%Wiv\TS%CBPj.mJ"?~'v�!nhiq,ڮXM#~;4PD5.%|:mz{Tܘ)c?kd܈m\I)+IfGfFFL9é%N%�������������������������������������������������1_2_cO!b}{QI%Eum˞Ms$$[}@w:ǂL186S=s p:DCYqYd{b=�c><H4K>ƮЮ2 lbCT0d6 Z8-%tR&5L#)&6>z]U'b`r=`htv\\5B:! ݐN8v~D/^p3ljukro@iA8ۑ|BV^m&OnO3!kaMӫ2g't3Bҗ &lFDORl j rg殹Ë) [1ycm"R56D֯uSVui)ß\׍:K3s2$˝Xsi6F.p$ j7Kt3Z*[67e<q 脚bNe֤^gMރӫʙ32s*VOe%I= O0k'GR�2m1O+!fx*p ͙/5L#)z+\x*ռk[Gڭ 5$JJmK◒3Bw2?@��������������������������������������������������;0j>ɺu8LD|v=((pOL<mN ,Q gx�Lq 4kBKja Up&3چLP4m>2kOTdKq;/гFl<vCg2&?$(Ҷ⑭ A-^Z4lW2"B#S2"[ﺭ$-ԣ?Qhp U\Μ lN|ȉo[(NjZRG�kG͌}SH֏%X <Gnd_ɝ28qxжeqAsJQ^eGy?V! *W- *p�ƲlΚ=ʙ3"CqQ\V4J{tzEL~S#zq 'I fW!;d| <X~X_xl7�unHoR¥rn/B p k)[A˳:B$0Uh3I줩'!��������������������������������������������8Up&3چLP4m>2kOTdKq;/гFl<vCg2&?$(Ҷ⑭ A-^7s V웧SdϴOGj93B҇ 4ɭ<<C)Q-0B5ڽ>zGI țJۊF-zhp U\Μ lN|ȉo[(NjZRF ?k\AVs/:r$-5;)"%o<Jy:j2J3����&:G|*8LthU�����2]S&v޽C/B|CkBٕhGm)F{C39f �['\['Щ/i:ho*drή 9FqZ {)*I~F_j%k2gaL=}2)$'6-\PFx풔mW3<`>kAa{ջ!iHB{ e})2񬦛3oAmG.ÜTiW'de���������������������������������� V웧SdϴOGj93B҇ 4ɭ<<C)Q-0B5ڽ>zGI țJۊF-z�5ZnN?q>=hu 3J6&lFD <oj8'm$6"ncB+n)дژe; ?k\AVs/:r$-5;)"%o<Jy:j2J30pr [̼Ȑ̈u)놥u(o����������cd1?>V���������tzEL~S#zq 'I fW!;d| <X~X_xl7�unHoR¥rn/B� k)[A˳:B$0Uh3I줩'!8LGnd_ɝ28qxжeqAsJQ^eGy?V! *W- �ƲlΚ=ʙ3"CqQ\V4J{�������������������#yVsv5[eRcU-MģRj،@XL|aYKPyY>>ZCcc-\Mi#R(Ȓ"333؈&UÓ_`8! $7cyϛSM\&ٶm) /4@Z_/vtbr'r(Nk٩~ ?&vq/xng^ys=#dMی~HQm#Z[S Smbk\U :uL.N)JyԔ5[$:뻯 d/L#9-Z +yӑ!mO-VyS KQQ0k'GR�7t9xi[X1O`ՍlqeIEQ6٩*6 Dfo@��������^h՜ŝmcVöYT&=KShq(T"Z#/P 0k'GR�`O0(sp,ۯSqYq#s.L&QPTQ6~̦WVyӶöw9eH\=AxFJ5-ҩDEF�R�" ڱ&Wpt8}merjeX)]㦭(˒9}rc d_&��Y>>CJƱ{l+dË,4"Lz*IQj#4$Vz�@��������Gh57RFc>,Dkkʤ} 1ZEsG%2ձz]S&v޽C/B|CkBٕhGm)F{C39f �['\['О`O0(qَ+]V˖Y&QɦӹvqQNiMu*: Gw ]\. msW><`(ԃii]J鋨|vv$3-_;Go4*|HTw]af~fuI03$ԫx$I=dVHQܸVI$c d_&��Y>>CJƱ{l+dË,4"Lz*IQj#4$Vz�@���������ǧopm~l~8Sǧopm~l~8ի [TbZ{dL1OC!| .9C2l\z<ԭeίhQ慖lU3!ErTN(u*u)%pI$) V,Γ?ԬPks:Չlk NB{_\m);e{q5<�Zh\;EEy.36o%I:Hlhq>Df[)Sgu}{O*}+5]Tb6S1oQ-Es}.cBdKZ\q*#=,[pRV 6^Qexkq-Hz*Lkd9%lK%(3/G*WQPWmƠmDguF2HCdׯg׵x:i1[HBPn<]W˒I$Jo:z۴"D~?' -Inj˨rM փA)m/eOOjuK ˺95%7Yrq[/ˋ_=RӲf+4mji~ ryn-R6mFim%�4;>^Oj 5q+Iq#?-Rs) KdU{>f~M?ͿYӍLzv̗s8Lzv̗s:S�������Lzv̗s8Lzv̗sp:/[/btK +De"BMZJR[5[BINŲTZcmpKU^ݜڤ@JiryOp}jRVjoJU-`UZtxR٥RS>ˊqDFmJV$|HtZ;j1h0Y)i}0H&~35{2h_~]Uk_O{q`c}WbٶT5M^-Umܞƈ7vB#$my+}$!d3=Q%LmZykCh78.8�%*ZH5OGiMk"d;qW11§zE'ѭ]I'JS"ȋm.Opb PGa]5Um<Y%)m)FI3e\4�koLD=?U8o)ttRU7Zf3%0dN+d Wzo=2m{g/l+U]4Q23$rLN',V&^.tj3-8k9tJr67'~kR-<ᛩB\s#&fz*:p 5N9YmKqi8yKBŧ $i'RfGGIߒ6D+m\SUO;N/G Nْp NْpƩ�������&=;{kfKœ&=;{kfK8kOu-:}cWGySܑ!&ͭMN)-ԭFj$bwX-18%nmR G%4ʍe<ɇ oۊ5)+Jq7Ye0*N<J)lҩS)e8"_#ZҶ%+AO>\:-K ^sZY DӬ̘RhuuSyęҙSSLv N.每'0R1l*jȯOn cDf!m6<ROPu6<5!XmЕ- q'Č#릏52i8S^h֮⤓T)MDMldEgf1O(s#ð* KN6u,⒔$2ffc"tgxw7::l *3Z2'T 2RMZ7zgj=3b6Y f(\9&[tB[el/M5{5qlu9?Y5\pԡ.9ǃM3V޽wLyK8SW',64Ji <% ӆY4)3##o"c߶)*slf'}ϣǧopm~l~8Sǧopm~l~8cT���������1_2_1_2_N�������1_2_1_2_N�������1_2_1_2_N�������1_2_1_2_N�������1_2_1_2_N�������1_2_1_2_N����������%N<>V4Mv/WykedTWVܹA-8IRII-Ew&5L#)N1| }e/A d_SL|aYKPyY>>1_2_0k'GR�4WUAy6ֶ[!rkH%Ŷڗ/%&fd~;�������%N<>V4Mv/WykedTWVܹA-8IRII-Ew&5L#)N1| }e/A d_SL|aYKPyY>>1_2_0k'GR�4WUAy6ֶ[!rkH%Ŷڗ/%&fd~;�������%N<>V4Mv/WykedTWVܹA-8IRII-Ew&5L#)N1| }e/A d_SL|aYKPyY>>1_2_0k'GR�4WUAy6ֶ[!rkH%Ŷڗ/%&fd~;�����������YkQ'%'mRӮ(6҇iJ̶JZ)Fucy <$UmM s{-ȖvڷUg6[ҨS>Dy6#I,;{I2#/A kuvAT/#{:>咞SO缪f*u?*4fuOxΏMkfD^&3q}P<|Qr[M)QqVQoqӴ,;#/W@l,3uՑI4h$F|K$dg;&syLR&Y%s$+zJRC01MldSޫQ5ڋeJ[RG$m)-ɴM繊U5Oc}Lw[")<O ǫV*P7PTGږfD$dQҌ؏c&zSY>FK+0o4qb&LH Z] fi#Q0u6Xy��c@���������.Į:7ʆ@rAndp>٨1gK쌧85.[LJvC٣\[km+JԎv6첇1JrDv/h[\i_-�̓"i2 2R̛=َ% 344Rv-U3[\v8 ]Hoq?ꉭ02|ؙgIFf23_z}wQq,ceN#v3*B''II257/Ě\ʱJ)#2fD_ Z\I9Dm?ñm\ж1.+jS[=Q<[yMŚMN#R UM'"5[U=aΧBR]so\7h%saLHII榉2Y%NXt%=bu.sʝY)nMuKVɬ\IeT?_7�t������������>bq+cβP[j/Dz-;#)0KVS1RhW Jҵ#}Mv{,F/oLRvZ-4y}�%3$Ȳ{L1n8̢w>Ԅ&vcgB &:T]b"tV8R-jo|cƜodOkL:u̟!o6&YFlvRkQ$ټꌌl{>ޟ]\KzӆHʡP#n"ddRLf2$%,g1&�W aRcJu̙7–N9O[W*-sk.Dڔnch26SjqfkHԯB3US}s=G=ƈz#OXzsаxT)r\ ĦZ \S(}RdhRyl̽di3ny.=n]OXdK\2VnehRձk"WYlFU 9?ms��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������krb5-1.16/src/windows/leash/htmlhelp/Images/Leash_menu_action.jpg�����������������������������������0000644�0007046�0000145�00000037352�13211554426�024726� 0����������������������������������������������������������������������������������������������������ustar �ghudson�������������������������libuuid�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������JFIF��x�x���C�     �C   ���"��������������� �W�   ���!"1QV#6AUu2$Baq5RSWv 8s%&347Dbc��������������.��������!1AQaq"2� ��?�ܗՇoRd1p9\\uĶ v:@cK6<4Ys!s6.C @a�AS;8bֳtWX**Ñ&<oeZێ!I RF'fD]L[4K"Ž"!V6l;wQ\>s,C-˞Qʬrsb˜VHRIAHqj@r3�%?#JƟTt\ uyQh$6�R�N$�7�HjUTo\JTZZq$Na$SrutqFҴxLeH"S^4�<Fw';J +wubWfv$LZ1ɎyԦTrVyjwk]sEBi4q_T`e;Ù!#;PKN4ⅤZoW1)|j{PFp{Bq"mZfrYljZa(pAVnjnBTCkHab3ei{�I_'{- ˠ[k&LY/ 6Ze;$v^j$<Ա'%?_JR� VE@KlwjF+䶕 qJ Iwh?ֿ�j[>*8MAGnaĩ)z,:ߣxA=�+[TyƫQq^֧m!uɱ㒷KIC[Va] 0K:n26jTN3_oo~޽uGd5f3O'Q#y2".9e*J)ƻdNt/uA SF6adoPZM`8ve�7Օ lzFeD}Q^H[O2-'X}t@h2%#AZZ!#))�wrߦң13qP-kB4">7/2]ozr2�q㮬l ) -/OnFCo2VVy-IIIXP+Og äF团*\8sTu8)J°tiiN(YԊ}TSȇ9M;|W]y *IMvQ Ik&f R^8IhrŬNshϪ q:י*2%b3cR0dIV VUAR{$@νbbɚI%jʓ2B #U#W]2WCU1ʫrL^(,VBtō{.մiArBE9ث"}/t-G1PXݷA8ѩ օF KiLTjkA}/2jH=AѯrFrjr%>:了�+RR ! 3#Q\1B<K[3jמy�T(_-Dd$Ļaׇ*Ldh) ^J <轪"XbA .SߩcB#%ʆ*O�䏦\kU+T62& uTeIS8JZMqٴZ <NiTJ}i*r2RbN$Kw'.J<X6%==N]>.l%$`E; A@=B^ţ˦xSՠR(}p@Z Չg��?5KѪ[\jpbU+94הxYm6\$4TP:dR*rAU;Fq]F¿٦�[#L�6fE|χu�h>�ݩ�ο!f}R#NaR=!9Ke@H)='ճn O폫 Eт|ؠr{<ؠr{^ףrZU$wzgLlP}oWlP}oWgH<FzL]뚨�iCKBVe R�=v@#o^6@Rf7;<B"j+kd$,zh_6kJS)ZT{0#_}kS\ }ˇ Gny(pF@J{OpmskQ>1[D[e)eLFw>9`j`LaB.-7>@O>@OE.m֝zU\㾥<2i�  qAIL<P뫵W E15gaMQ\y[Mžmm VZ}}$mrknM@֥JuR*U"0˜YrCKX7%jݕh̫mOS 3.xܔ3D3!`�gÈYڴ痠a9?Ga9?Y>kV5b+ҭLyP9!Kt甜䜨FZ]L鳕% O()!ho UF�3P nk/Ar~./Ar~.kƺV,Q 2C/- YbCʖjQ;yenPcR^QS82Ai' yWpzja8/'FW>@O>@O_qHba)ywLQdce*N m?J@ lg3Z.ysVӊhNFzt`J5^>^]^]V4{Ueez?#u%MiIV쮅(TrZU$wWZUSBD$6KmRIFVVHWg$b(@.̵YJW9>R!񵇚uXcEͶIZkNRNHJwtQ ŸC*%Q%ԧM9KmrS쁂Fa+"a֬k)_=''W26U 'zLDkpń_5O2V� �u՘$++r}~C+jİx@v_LDjo%TJy1�;\=GR: pۥ$ST&SԕM u ic;V>* ZB.'`X0�(VѣFHM˒j[SA@ʔI�:vߟf]QU|J%Kv4RTkQ뚥%Pҟ@m4N�#1E ,<!jKnkT c)E/%(ܯYϳb*hw$2 j(2{h4R@ Rris+ b-[վn*׈faxZ5|'=c*ӼǡQ՚].U6kRy+̵Sq%$ t~C ݻF?褙5TLJ*T}ix{j B H=I:P"nؔ)R2+imXq%A%(@)i ՕpxmX&2dD& g%/)/.r75")3X,`[-�um%19U@֝ #TSa8(D ꒓ItXnQnI(La!v/)e I;:q_vMNիP D6=ص+ ! sۖ!`rG I6ޛN|ݱf)mSaTҀ ТV�IQ%L=oҠS!:ZMTE2Nj_h!iAٮ-ReƞU[L%9;BBAG 6ڶ=2eW*)3ӦP،xnxً @xJpV*WڟZlm*\zRb<*]nYa]6/(q,t^?-Q=C;&oI28[*\3]B2bJuIy H>QG\-/-!) Zi KdJkiSD!kHA;F գLE}5X5jۢt![ԤJ E-*yƋ,al-kau6$LU(Rq!ZrRP/!mHٻ*8??뉝Ŏ},@Ę +!!sЇ@^HN�stSWlTkaa!Ia6Ƿ^%Z7b%x[h-V.5!rP𒙪BV9[!EX5rxOǧ׭YMD"HRz#r.;N:ԡ*iO\娼ک2avKU튂U$k=b||^ƙխk~ *="q[·ޥI$�IՇQ;Ne6ǑLz^!M]V6o1sPmJ>C%VXC RGa '@e;Χ,H2ʓ6){ ;*ԕ/9<ҮIR#ݧ'fTxfܺBDz<� N^BVtJ]M+R[e]JMWE#qLRP Qjcyߐ0Ψ4RTiVF5)D+lqL0е*䤝$'l,w^pV'U x緣_<؝ѭ`*)`2LⰂPY@ww+|A|ۢЄj*g�# |k^!ώ">Ӧ[7mm%D$oP8� �5?/5i+vgFŔ){+PL‚p|mJfEm饨Ӫi̥KiA(–7'r@C-bpoCM9#OGԺrRS|dxwRb&ݿQL-6ˮ c+Wp]NZU݊�ȕ�9ڗᇄ5jaSظ-+,R(t8 DfTj\|ePSi`Ӆt´b(z5?)`Y3YGeN}InDJq=" <I;ʒA 6$) m_D-F>IU)7"3H9ʣ(GEI(^N%!!wdÂVNyo޹cEu`ybs,#v҆-}QKijF'x6.t[E 2qԶ@G0yh$7哹 8b4Pi4kߟf]0i~o?ٳv.DəHC(%=#‰ 8�tY AT._#zL5(Q,0Pje jN)$+FŠmP ROeΣJw WAa'y2RK+.JVRf!+Pa-ӜZJʜ66ZF}}�ϫMGɢXۍĤ# �Ar^K|GyF޻+fkw܀a%r]$Gu !oPR1Q Sj/;;ƪ5('6)춰wsda7 2PH+jI@$Ӯ4nLӞ-%;nghw;�:{A˾_Kat谦MGz EK JqߤL%7-vٯITi*,;adGi]'!@i\Sj"ƦÒԵq٫mY*;Vd "a; 'j2 FF2CqL@9H/x1۪,+pyn="DgC2__c˪QlRjnGSo{UT !CqʛRrWk!@D2*+ҝW-qqϔZ7lHH$u2@zuײQHؠ ;`h [~ .:EV׭\3YŅ Q}LIjDg9Nd6J #Jr{Zu7D'eKt@)� Z`b* ߩwnƎ'/2XK2gmg sT2>RP;U]Qnt'ă}CN<TI !I8Y iU駡_* <!1Tͨ䣛 )*<ck> V"]Y].e1ae@�/zTqxWt*{XpB%皖TW$7gpp:Y wlˊp]JАn;rr1ߣeM* Mr_KhUN3 ȩ +JvDV|uKV 6W*CKaӄ0`wÛ:qT⣸T*9H$\fe_eƲ(9TC^czƱSk֒ˏ@=%J1LTx6 S{T{*:mh.IJ)TG ңU&PFQ[ Nw_2UJ*oY{@q(_=:)X=ƧEByMiq9۪.[{%}U6m7ۜT{Un0 Ȑ[NRڞ)Od !JIRI?F F) JC0T@r1(N$lWhJW*0Ԧsc#\m27,-D䓒^kVT Rݟ!o%J) Zˌ*$bT?vIJ)oB;ƙ՚"&,0AQ^$dTIg4XI;}JR$b2S^PRU$jZbjYTTen˅ô+$ >>BI3^^fGR`1IGDv܇@ RNRIuy&�in+Fʨߟf]0i~o?ٳv.D qБy\Êd%PJ pJ̚N)dRY?OqUreq ) $wэAX|yI"m_֢&ei1K!+ bu6prUm9A"sN0ߵ*9sj@_ ie;.6P% $m=gRnCf<ķ"Sܗ�AAB=K(n<YAPCc ?ahʺq ݩT)t.Jq.,lTiYZJ0UI3QxlnuN۝Bg� AųfSq5&P L)%ŬmӴbzӦݔZ^ ioKP%{iIRA# nlY1&_ n Dɲˣg� KNd ҊtHMLJn<a湡%+%%CsWP{Ƥ۳V׉r4ñf,>[KC; :]禠>:ZN=&rl(БRi3nCͷS@Hu*g:yܨIr4;Ta&K_-m6 kJ%#$gS $oW!qCjr/"R dCgR1,:PM5ڃޓVІH''N:dweb%iFE-nj+RȒm,!*R8[+RFҕBE:JKDnd˫*3I^ڐRJBЍh%'؟obb1|-]S<LɍRB&-sR:wvgSsCQ` JJd%NOQF_<cUm"[S%VvoeTiPIۼ\`m ~fCnf(vρL#z e�HjUi/:lQ�TGM>3&IB8wvIFq?NּPrZ|]m0�RR2OqPIVt!ҜUTC"bAnA- ~7pU!TÓ۫Sq)ޤ3{ ׅ[58;>!JߔҘL6n{ }*H 8tK)Ȑw&;Ihc;@S1U{Z5klP5$EbO6W5!IXJR0U@G2xDTרiwEV[5ISf6  +"-򪄼=V* ]Q6!UCU` 3u ! p\곥q-]fָyHn3tT/i{�JBIQaa*|7(tȆ$8v!Ium^ĤjPH Y^狱RdAs–ßEݔ:"!tϏFF)Җd*Y  �V6+*uNʣE�"U]6)\Jt `aY`b(BEQR01\$'nwF}?&UQ| aU+ &Ը4Y'h/Im3[- JThI8IQƒ upj&�inh 4k*K~Q͛t?h�fغQ2)J@*j#ZoyQR>>8,]Q%~p֋e݊P PiN‰&9K}P\ eRVvvcґ-fTwX;ZRZe!ޑQA}XeMjyQR>>IM~1EJO.u%/[h.EٌZ_)-.Ʉٗ/sTʉh鶪>T2nqRt4(q*$o.j]Xڬu<)W؟Ge*�{�Ưazw7^whwWܖMv Mrl8Z2rP$YFOUz#"bҢs̝s 8O'd=;5GJ<)W؟PCuޘc>ە%mQڶdSXe*+G)oJ\uڎ'5{}R;itj<RS1XqӅm+Cs N)'bV@sT}Ojaf7d1P^<mn`\% 6nN(Z*QJJyh]#%ѡNbjj~dɯ!2dOG52 R`sT}Oj�`m2#",BSKi*%BjSNڂ!(vIe$Z#8;wQtV-bnoʉWuBiԲ m-Y'm9>U'5GJCο~x=V`8�tx"W4zSfh/ɞS1 xCi5)u;jˢެh2ۑ%*YM7ZJIR ݾsT}Oj&ggE+Q^V}1+%n-Br&79M'JJێ$|Nq]4ZO̸cˑ\ip!%j ʟqKm' *9RwyQR>>9>U'aY/~Z,B!y7fjnLtK PzMG6udɏmiSXT&kmLxNv2PCб X|D$nڗ9>U'5GJ\"m=lU.}N% L9.pP �#x<¿oZn?.n5R_y Pڷ)7dl/9>U'5GJx\k>%ȩFH>R9RiM-훜.p ɾ5GJ<)W؟I]GL(>`IwVe*�{^v#\UIaB Ն+Fʨߟf]0i~o?ٳv.DFR^CK庤;N:dI7pRS&TDU錮DSs[vk-ԣ$=: !+IT2k)8k We\mѩSxo>uL;̖!w* e\ۓ1U]Z%i0LZa e9D(K9F6V5",Ku^|&EtD2\M˜qJyEGo)R7$(nZ#^.}i !SR#(cB%?K@v[9! *Qץ;-DWoPfQgvvӌPx9ӫL.:Wz;|~O\gv/yC9ݐR$J3w5Vuu:;n=2KE:3c*CҭTv,�M7@ZF{a%O*f l(bTlZ֕aACDQ{5tݲI^< iSۊTY;mhK֝Q o*YhϷZku,!|ۮZ+_hRQ'-MĎ̹j8:9-ާXKs+@FR5{~l$ʽc|&g T"Ș}_+{ʛBPF2rՌ�E޸('$mʌƘخM Zchqu'[|K}U>֟�G6Ό1 cR qB8.�7T_<s3<~<9}Q׮;qa.@y)FsڤnHVՌ^QF4hF4hƒ upj&�ijh 4k*K~~͛t?�fغHtƷhkGIk~PѴzE-h?o6PH} Z߽k<+nZ{vh)W#7-H$-х+%)?@j=CFI'E-h?o6PH} Z߽'ڝڟPם4(HtƷhkGIk~PѴzE-h?o#I _:O[z@5{SGh=CI"kGIk~HtƷj{h Gi$P>-h?oOmh $'= Z߽4m@@5{G _:O[=z4(HtƷjEޛ*r0+ z?ϴz� MӺCEpѣYU_l݋ /G6o5YqMR'- (ZXY Iiz]BC*z8LPFkP g~$, Yvrm2o mMɆW!isil�ƴ|֤(OHb1"!iZ 1UyrK{ҵ KJ(ڭo)(tI�Q"`F>OJ{8H|x\\jxqi!z F :BVlP Pu#p#JUěͿmî[q:$vC<䄩RiQ]QTv3u"eJLJ|sNƑ IiˊyJTmؐ*o ,nYgeV)m5AӅ;{HѩjMF̩KR`ӥĎ)c{HjL'Y! m/QLAO7e\v PͽOegdm$uKRePCņq]1I$ mSf\R'iM% r!gxI$'G7e[̵T5JCBb6gջsvw*'z:&m좃LK3[؈L-e. vS+=Vޣ)*^4S5`a+ b ޔ])‹j%)`m OiX3*|k+ӑd,JbIi%O:yahy8JN3u3 :="jԢ7_Az{"S ;qݯ^YE&ӡOHL ç2 }%*K HIX(A AH?@X>"�kWG+ףhIy pZA:nXp}-jU^r3tJE0VMc89<6 \ۗNHNrc!GyTIA}͡;@+jR2z }\pzö-t*ޥ.[!Pl2^q ޅjF%]OPz?~'{=Q5:qROfs©V:m$/Iy ,y̕(8JBv])p. c!+s}-Bm\,iJyȮ�^^xh467xBDj-K(;]@FFpOM})|]T:<HE)F 1[ e(v뜴;:tZpsj5Kŕ.4^>5:j=%R[mdIa=Cǣ }F7*_Xk{nۭq%9VJ-Ev^@^̃Q^ rFG TԅA3(LyZNvi8 lף^LWnhѨ4hѣF4h?AMӺ5OP| T4W5Q?�fغ`ߟf]P^nf7=׶\m/6֐('IswYV%Sԧ-*(C-49SFi\!*P :㎜7rO5rqȥ !3>mla(c! uk$+[zDhs5.yZ!GD4܇o!$<4nkZR os+(. ! MGO:C۔yl/|Էn[]bѠ ΕT~Hrd%1C* )K urf74KJMO7$2_R]%80R<QiRp)R'Ē)ѼIbCMCoo%[JO^+8dqGiQ|<ZmN!?P1+&*Z&U̮S(T տK V'kM _1GN]O*Vj=aol!bKu%vR"T_jDP_}9M8JV<!.5g8d5-TyBDFo9IU K=msƅ+mKN~W*eF\X崹!+M[)vBo�{wWޔzèŤ.!&^iYh(5!,8RRz9ԫ>Dj-:U֙F\!.*TM5'9h#-%avZKo[szm!&r$hi tGzZ6k H;Hq%etHAq(p�UQWx{ʕ4IęJeRhҘ΂xQQM;6Jj&̫4!9 6im41tLv"FZ$GD`)8mI7AJ PQ RsT xeyI}nee.FO8ڒB^m6+n䕶RA)I8 :hmz<zd7fBPI=Z_}]RZgڍ4j*4hѣF4hѣFS0`};T�i7NPCEphѣYU_l݋ /G6o5RtORWv@']:u>q!HX)RO~&!k<~kׇuNNGTګPR&W߹�Q=;~YEtEK&Q y.,cO1 b:ɨQ`]ǦɅ@܎!Ҕ*e%+j8y{[Z tOyoǐ^,Xr=ЯLi!-6c>!La$$qb$RIw;̢T/ؑUY[DCS\i-IBRKDV<+X ])4m2E.gA VS �m pb빡P*iqAqk' 9EnƧ+~vuZ%pQfHI0!Oey+dlR:vՔ]\u~7&BCjJkTaNKLw7%6ڬAT8VvU)ȀvBB1>EoL8 pNw {nuVĆ%CLO%մGtRR1]B/%H2縦a<D+aKHKi}e)Ci+p&ۘ7W@{ECj<=gMEz|hqUNp/3!vI!C? :]د]"R~Tzap#JUogh*^I^UfETj{jViΛ"Bu-\Є,I$M3nRZ#쭀_aSa;I"jt >v?mټ<.b-+w~͗ؔǨ4P&Ѣ* /;v6�9yx3W[-6v|v.s:yFʨѣF4h%Pҟ@m4Nx] Z^uڤ*;?STRLSrFNЖ) iIq2+,PPJ{F4bø:Qlj Ki(@J\ )ۼ`OxMJb_ z( ^ ߚVQ#1t7b+bUv4\t(IP S�YةUzSIJkF[m(BR'$[5hѣQTj&�i\(>`IwZ/ȿGO-?_GJ#'�/F#%~O�ւH'ܓnri0E:#\<V\m}ޘɣZMB1h}}yF=5Ն.Q{==__^~sFhQ{==__^~sFhQ{==__^~sFhQ{==__^~sFhQ{==__^~sFhQ{==__^~sFhQ{==__^~sFhQ{==__^~sFhQ{==__^~sFhQ{==__^~sFhQ{==__^~sFhQ{8r^pXf%х@9JAQ�Fu��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������krb5-1.16/src/windows/leash/htmlhelp/Images/Options_Button_Tiny.png���������������������������������0000644�0007046�0000145�00000004303�13211554426�025274� 0����������������������������������������������������������������������������������������������������ustar �ghudson�������������������������libuuid����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������PNG  ��� IHDR������-���[���sRGB����gAMA�� a��� pHYs����+��XIDATXGWkUWιs_g3tfQ@I4 "1 ?ZM*61jJ4F`E45ZH 0 e: 0s_績34hc=7sc=qDt@%>\MH_݉"˺l~e3 cG‡n4#4 kͦ Qo\}ʊJ񎞾/[@<�9 ~0RѐN9ȤqlVX_6+7ڿvkdžZr(F~b8űq f<ݤqdOWRa͜5Oy'GeɚLEEس&"A{q;#2:IxCXQɢ(ЏdL\B=x +!b>n>4m42LzD%(Ҁ=26Zte:*co55cz^C#6 ]V3mDDDd\dmaLkĂ؇Z}!~Qb ; &9>3EI$+Ɖ5McFdMPE:;Ԗ lL!,) Ƅ'2֐5|IO,/|)d.[X|P/S4f9te4t(ƪ](kpjL~\׎zCIf'LӪ2 !\bGb+vaqoY=DsII-S^k5"\'Pö&&ՕJuOk Rܔqrű&8+{$45qaa zk>j2E-ЃQ{W#4pVD:ƍ&@11]L]{fl[1pK[�a9EY@9u2%GdU;|B\ »cnC{ 5cc"ɇ1gE r2l"! k4!Qp<IgPj 䲒rR*YZ&ȜF+QcX.5XHazIh<\ e䑽&ۼ{aX(P92*<}Pe\T QfyiJ!҄MKq~Wk߻۶ޏcÏ=Ҽ@ Ox^?mtwSRrzR\ kοo9CĞ?bm OuO=9 ^ܳ ~}/F-X]adR2ni@H]^^ZՐsBv8ɩVEǭ!:);O@.ӒG D/?+Ė]irl{zangKlnZ,Ǜܨ_<|embVMK'b$ ʢXЬU4^}|/ßD#N!QT >&''Uk=Y7590 b9D C*jF}Wz`Yad <n7vCK:.T5sYMY:;۰'D.إUmϽd ˻:)$O{vjN~ C_B6b9 >V熎VXy튧c8qz� _D*qqiuV - ڔcy'e:K:a2kajjB=6jxSJTjzyW/ aOe<nUs\U"y{X-B 51Ff'Fj%MDNrD$zZ5Ȓb0$�; <(,Tbyf}O<Y*RhQўعFeXxCAI_<1l ZG<P2YS5jTVIs 5ɼ1'p+$$Gf9b)7[6p&]kht-ؒE^.w;<y8E4fʳYlsҥYmWhi%x1IuKiz$?|9=knɴOɸJ`$Ύā\B,v<= ܣ2l<<˅< FA(ߛsDzee"iw����IENDB`�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������krb5-1.16/src/windows/leash/htmlhelp/Images/View_Menu.PNG�������������������������������������������0000644�0007046�0000145�00000011346�13211554426�023046� 0����������������������������������������������������������������������������������������������������ustar �ghudson�������������������������libuuid����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������PNG  ��� IHDR������Z���N1���sRGB����gAMA�� a��� pHYs����+��{IDATx^] tյ& ZW!1,QjRhY!& Cj4˾ZAUbDcPXKBV)/`$hE yϽsof_nr/=9s>|gH�#4 lAfRϗ y)0D ,،�#@{B^@0`# &<6#�2+t#Dil>Z?3pC98l)Y:obd-z˱k!s8( 뢱'Paw G$ Æ#jX&ea '?%ˁ՟(~Зx$f*d}a2y<5j|zU /RQ]7Pr*Η`_@T;AX?a b40 Qaafa֔/Cxf}W?\ 2ɡ,/R 6 Ⱥ*m,Iy l0 =#dB(PxH3YZlTl%1jx8e3AɲS T kts7zm\O ɡ+%*)i5C/*5EY(U9%Y/PWF߃.Vܪf]S=ځnZQ꓎j>CPxE#0<0#b0bx Ea Ʋ('8Suڎ琩x5+.d4'VQMTOfu}:TϡhQ4Q0߾{Y5{kȕOoĹei$lIId܃^9b\كG˨Ys^vOEd^k-9>~}5?DbxL"##eT0Z ͤ]QwFq=qOt#~*@vo8FHԿ6~s9#y7O9=baހfkG !?4fT.\5.d1|l}0XT{ E9,"r[^ţ5K#7Nkt>bKAXJY7Ck㘜|T,ϡ/~~6jt7{}IGw{Gt4Y|y G>* EBWz&۩?y3"zTe&5݉M*vT.N}Cn2:n<9O@ӮwӃ;'j_MaFvl<=_.^3W֧`&:*gΜEGG'Ο_|\ uFAjF_lл(9=\?2ŷbz Rx"l*mZt|z\IUۥީO1*N8]p{6Au=Z"k<-6l:^m{`&Ďo/_O'2y#Czn]?EQc=8}l}AϿ vVYQ7fXXhaۋ۾:@OA5H[X|n!#x4b zug ^G&)'/SC^GƞO޹#/ QpsFtq7F xBFc4" }hP-�%~0ce�#6`c3>`O&F}?}!,}h HF.ۚxBIqe\rENta ,�z#uxm͵olAzNC6F]b5U&>S׸cڿh'hm?k7BWbhՕQhJ$t6#]󶽷2\ۉ8 8x+CI sD.t -Cc z|^Oȶ6&.ocGpTn &WGSgl]`1" bk޶VS+LGu$Cq#fj>^}mm8%x3:;E"nԵؾV3E/v7gN1'cZ2KQ7ʖ*Tqs1}贎Ȳ[!OL\ a/0MU6y2m94-+QUi/rL󻚻yLƠ{PI9׃7$|yKݧSr$\j+{HP0x,[/TPz,c,k=Lb'!m"65+-v1U+U#s! Xu2]ǫ'@M0J03[֐N?aՑضDMX%;zxJ_8AS G[Yum4Z߂d>J0U7SO*=_TySj%F鲭Gdf `Jr*TRE-%2O\'VfCa-ƥw)ϢymId%wl%c)yɎj탉9C e=Lwٓr'1ln4t=RqH:Rn!c ,'.y 5(|uhggLxv7> 7iM)ۚۘ@#Px9xb >IyAj#?tF:nй䵟 w8,/$u9ןq'pz/l"EV G͟C/]kFDa4H⇌1?V7ۚM1Y4+T %6;IFV>kјxq+rǧ*) ''УؒA\_waƏka:A3s謃^'b낙 b>񏼂( v~Cp4"< ]gېddONߩO5ᨺ$rx㘟WQxBIÚ >ɷ} iӓSoTa?G(cU 7aڔb`e y>W*WVPǑ݂WӅt\~;1(4+p,˛]wG1).9+d'˱@If"=xc[KNߘP|KFG([2ߘ)x:> .ɗ0eGsXLp;ǽ&FxpSQ4p{/ OW5=J~CRgƞ0� ! 0E<a=e3dp1'86 3Gy0D=a0B@jeO *Fc>+?o}#`ux @f_YWmj_ +0_xl8kP,҅ː<k=Nn(z^k ՛uN?2v OdM]uJKzzQR%HMz}VO)fm\d՛ue|oe_4;SWLۼ&]}`F &\KnҼ)s$&d/s[`+`4}ԶW,ЗL]`ƃO Igb! F %j9 i~3Vc/@ӓǔ> CkȡM}y&=!tE"1 !}FOn[P47њO(<PzE3qwjڣOc=wdLhԕUƵ7X$tدzB YfN</CiE,%HWAq]wAUzhGn*W'bs1*xD ЧL]ϦdJC%%C>`mL1l?}T\Er!ՀfzHPmm Ϙ'nWfF(!LXS#2(<wF`0xO8X`#"<B0`e�Y9l!E+cE:9`# ):X+"FhEy!�aHX6dvu.m )UC*J4.ARB?tގoߊXz${dGgх=a(n zJsk.Mqq:%Wms^mҾm{Pub# I!)6-$m?d3v-`xt,dv3.6]Rsv\xԸBrVU0DWBRճPcCxHyp  S= )ߦSt?yHI`# %"DooEfldhNC V8̹ VJh7jRAHNs<ySh<#:' -ILgc84LZNjZ׾ 6qh*+d0űFv�)fuc픷gJ_sb}aGF⼹~ӶjR #'Z' ->X "FhAyʡ�ahX㮯 Z 2#ϰzP^!F H �qay1����IENDB`������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������krb5-1.16/src/windows/leash/htmlhelp/Images/Options_Menu.PNG����������������������������������������0000644�0007046�0000145�00000012756�13211554426�023575� 0����������������������������������������������������������������������������������������������������ustar �ghudson�������������������������libuuid����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������PNG  ��� IHDR��*���W������sRGB����gAMA�� a��� pHYs����od��IDATx^]sGv 'lڬ0TVeY/Jָu6J+ yC-[O}{f·ѽw'�$@1<&1 !*!jQ jd4`@0Pg $I :c�$*i`H=B탵kjɓp%6ݏMUlxY<-t=|=zj ɓp%6ݏ1oɝ?@غvp(l5`ffFULc-~lݏy8/MTiGO[w~#k ۿ>8Qm7ޖnkH+#F-6HU:~6\ﳰD |k5#8^wF>۳Cpa )Բ}W^˶~ayڡ54NÚH\K!_仾Su|2lv^⻛ug}xc2y4Nn!Q_0zj ݟlᇰk 836UX6XU>ƽFiՅf�Jl|15 -uX-X O|&[mN}޼qed8|֛vdcR=>珱m{}Icgdk_xa}wA|ٚx1Xsqܭu|(`NY1,q&y,9f3Ca8x,݂{FGo3꣣'2 ƭ>DZ?KAe+K/%OAMH(cHAmm'Fcs|hKC6ȷ&F7[0fbx[_]%5sco(_CO6^}P;BO7yr컘p`JrNy\rjf!]x UAMozT=;{.#ЋD8w V!Q5귟azLd+ӕUгRr]{m1y>?.+#S{|J+֞wO12B¸aN}ǷQ<^݈ z6׸o: Y>:2Z/djYG?Y?Z^~ =V5>1UP3Œ!@S~&kƺscH qP|$,>;5ܞw03!mTNee%u؏ĞdQ;\9bܸB,C09u۰b/>CuʕR#}ircb9D ٹkWJ0jOO&)-f�L}=׻ u[z>G?ű xP;64/Y|sHĞpxE~q 7!I76ަ˸)ēP3 9thN>ӯvl܍gaMqc _̈*,Ox9j?,M66Ɍ߄"YlW`%U.sEǻsWk?+p POO46G;!|pƘbGv>0J-Ӷ5i|ŷw#Qk1-0χְCr5%%+</}1>_k%=Ps?KOt:v?Ncwp {]l;l56['tc=9ZM'0YCBdYt?1;wަjA6}rEv⻚ rIr.N&1 j Mb  ɕ;A@0 3F%=˸H$@1\ $Mb  HTpI b $%Mb  ɥ[@$@1%f>+'``˖-P=/hv&EC-I_8džHΝ;v]wܿ_}JeN͇jt[i~}7=ٯ'I_8&DT>ʈ*/[djt;3gÞ}dD߇0׻^Ϯmz"E[ݻz~QD']GR'o C9}X>/lL[Y_[׬<QH~ŖV} GZNa5wڔO`wƐMUW-LLIq|4:sΞ`DGzZ�.01)h~-f$-e(~QJoWG$.\cCKz[Y=wnq++hGl<x~ֈ" >҄=HoQko7DuI8:<pڵk0|pI"RE{K rқ0$d *=^LNsW+:("$lKL8)?TUe .dAZ-ZqO/#dC̈́biX)n>}XMgu)?9x2UL+OT:FUYoN@Vq}<]Jҕ"J(#@&{xUM\񝧕krMؼj3 jS֦2>�BTT.;=v._T4557>s{7+}A`gtoא(s~]5m=؃{qhYtf5'SOחoM7}BnO,?/oeڱT1|7k`a7~1JׅARk8mm ,S?ƉxrSAqrz1Fu!9"]tV mx#R8c|Hܷ=]TMmpŏL>~$Bn4V1|s?|w^2~!Zm.] pmU"B()hƎiR|E6})HN-בA2 !)!2Ie yj $]mό|KA>Qbep}fcPfUؖtq""&IU86JOnKʔ2Sbe"-W:'Cۀᖪ}j{U[h07YݷY�%FJPTa4?%q \b QU,Q;BɮЏ "*MsWh" ߀ Fs(^Nj)UYD"b\"}zU*BTT{oFR"'&(/x߅4y�Ռ�M92xA}6M'1?y [_+3ٔ >;̍=0f;g}Hse9ؑ7%N#xvIDe*)")h|8_ta"_Hc#Rb -W/cǡc-oـRؘ~o$ 4Q8sf QÕWa ϩܷЄd)Rڤ&c+^OG\@8vJ$@5Ư_d:fJLLW oC$0_G̈_%UZ՚ϯ69>uwtp~z5koV\yVROh="&xyJKT2d' 3&oj>.O5W 5vͶWmy~Pvln3`bdfk1yĦ!*KRDZK!V#9ujvþ<>Ԛ_L޳+z 60;#'niwr::'Mb  BT5^MT01D5$@}16$@1 D%D-7*@1 D% =H|ۺS&箢"i` Dn,#Mb  QjuvVld <($*M3s"6 Y7Y:c�jߚy MLc-(MTBo) w'Rÿ/ qe\=t6F\J$W+6цl:5Ch!d4Z3oɣ+ë ǃzm*՛߄,YU=Us#%[OH-vƼ-yi*x@Û(ށY" 6^Ưs^]8_(߸0p %Fɕ#t([x꧱8n8Qi^m<P,5`:_2}7AQ/ETUB 7K @o'f#*Nl% %HFz:T2.Waxs=N42%Cf<%]1}5ɴ"kkWɩ|s\?6e'P|P^[hbF[݁}dV!sFB1cDSfRu??3/_DTlEvH_^clPa7?I8dH(BTHEG)p`&R%ˎ VC, ?V؅zVcP,CHhKFPX1t|^[hF[`ɥᤉo|Xs;z81 Fx{U<3jzhɵ#+DՍQt"CP-4ϤR6<^b</0V`[}QSf˖>_ۧZcBՑ&9W^y0n벊=Wol^bi 6PI DU~*Yļ1JL1 DUOoW_@e<W BTڃexe,D%D%D%=TNJJJ0P{ Q HkR BTڃT**lڿ~rCVy$VA TtvH|KO(vCB@JHPD.WC$OI$~$*`NIHC4'ꌼR22>On4U&O R Q QiRVWU! Km )'ohއ`X>%L!(!*ATpbdԉ*[zWB6O2vH\eD`*-u;ѧ9ULpTJY[QFTp$6jg~%idGZzd%D%Ɋ=H*>܌ɃȈjBUXF.WTsK!* 1G-p$*$U3I&sZ'g!*! D:$i%`@JJJ0P{ $<i`H=sI :c9![H����IENDB`������������������krb5-1.16/src/windows/leash/htmlhelp/Images/Get_Ticket_Icon.png�������������������������������������0000644�0007046�0000145�00000003064�13211554426�024300� 0����������������������������������������������������������������������������������������������������ustar �ghudson�������������������������libuuid����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������PNG  ��� IHDR���-���&���PY���sRGB����gAMA�� a��� pHYs����+��IDATXG՗YlTUƿ;KKki̴ X --A!胆Dc%J_>HLT|ID"F0!R (`e6ig:ڹL$v Ν9;a9B= / 4zكs:#S2ig&c㶕%E78rXWoǩcTq\1^b~ %=xrfh°>Mk7L)o= �LD%9߆OtnJtP$y*ٟG5xv lVic2?_G hCSSp7r K5>k~O2ֳ8>|ݽ mí EV8``A_7BиgʼnO )o2!0$T<F= !k olsAD̜< t .z^zwӅ+0)l�iGDaOIv""5RՊp::1x!6y?t�{ЍvD},B}) %((CM[ mȷb/@&*Y# 8|q?BVcWB!z#CqGwMd(p#0H*v"{{ds> Ñwz8& Z88#˰a ETH(/3k_0Wq9#EǑ_Xk!1oEp7/D!:ȒIttRX(]عu,^?2:Ώ:4_T&GmRpU4 㨨)CI<)U':=\i Xх͓;Mi^k׺F G 0F #WԔcUE ,)0I�etp\88Ha+~9 ұF�>C%.*@ .3vjNڰWɨ#zŃPl2Ryf(I<9 %dJ %Ն*!V]aqDJZ=?|u6YA%2A\CF5%%TY™)|v794jz:8x�\sWY\(yEvT:}8E^]bk颻Bf(::PK)8ϽҙlBӝBJ對L /tՎ+paL2v[WoGL 4%`,Q*L{&8 =o䡞]"I"5 & >wȠZ2ϡ ,nju!>)^+];ߘx#⨅x+S(|_4^;ێ< `|}Fmv2<){Q&17'UNf*W/sNҒW����IENDB`����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������krb5-1.16/src/windows/leash/htmlhelp/Images/allowed_mix_case_realm_name.png�������������������������0000644�0007046�0000145�00000003702�13211554426�026764� 0����������������������������������������������������������������������������������������������������ustar �ghudson�������������������������libuuid����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������PNG  ��� IHDR���������LZ���sRGB����gAMA�� a��� pHYs����+��WIDAThCY]LWveۧj]/F0IhBvBM!TRLԵ*ZIlƇ&T>eBTk-h_=w~vgfg[bnn;s9 ?=3 <C A - cpPx|Vs :OE>GAsǎ}r^Ӄ:ntπίOd/z>zu⥕ͧT3'F.lRHfEÎ\& j)uDnԾP0ZBr<1u+^35 |d2,wb,xpcI6 k&#p%/(,2v5dEd1U`4nJl9=NKM KXK_ �K;/!6: az +9q?gPo7'Q_D vnGFvo2B8 o)ZP%/N2hR# b:4 jMt/Ft�w"4=X'yXOٍoL& SFlÇy$1 Ol uImLS6`ّn:|hq"$Y?q@A)*ȫ0:"ox4:08|Qpm~[eݵlkGk=�*??щT,3(;?a,Xa{,k[B*uSCE *PFO뱦n`f1f`($g)Ʒn3F/<#?p㱡nd)aO�8k*B/@nk'"ZO;+9)xvtO X^.))~ԡԮƔ[/2`&p(WQ[[Zxº9kfua ͵;lE}lƶ fabB%& h>MXw#;~Jo(4D\ckʅyZlޏ1Jж:"^u�I&$s/ T^Tq-1Q`[�?~%|ز7v % [`]6;=*X>E+}6"Lw-C;.CZ8z1+> Vj̐ 6NG gf#Jl!w-bVǥ@ek菦XvY~LʌTp#_VnKne*)"HDV~_W ڊKq6~~Ei6G4A+ԊL޾:'lc el <\`Sa =՜C.qI8(NZ"2_C>FDQӏRIAW7SO4Wk}i&+5 `L1B$+7-Dy8</LGAdJ!k`>#ȍ#߻BziC2qnաR>ji 0Ի/"8$BvV ̧6-|!?Ǯ2x{i#OцB G7o# [݇ k` QYoRyk#\mFA0p,>ᏹ9cnn2$SkDMU|!*I "#k]ew[{ݔ֬|G^_q_Owh1 e&ҕļ͵deA6Rp@2'CqLĺӋ$ 嵌ʫZl0V|\ġM_.|rcFk&pb e_%W(+glIZ/b}{<(n(^o0A}:Ѷԙ/f q.00~g[G3@ ,D(Sj脎Yg@߇)zw����IENDB`��������������������������������������������������������������krb5-1.16/src/windows/leash/htmlhelp/Images/Leash_systray_icons.jpg���������������������������������0000644�0007046�0000145�00000007234�13211554426�025332� 0����������������������������������������������������������������������������������������������������ustar �ghudson�������������������������libuuid�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������JFIF��x�x���C�     �C   ��5o"�������������� �6������!1Q"Aa2Bq#3 $CRb���������������.�������!1AQa"q� ��?�ME&)yed54W)鿊fSGlon@P.un874)�5m\�eů6ɚ>{twVuGgq3" ""�W;f>wFzy}#d ] [y.vz6GC5=K:&Fc۳�p"?rN5 :Qzd}U-k{ڽm7JkղA-5Lm79hT""�" ywoEP(jLꨘ9wHw/җ[\O`>P*rcتW.+4�ֻl 㹍KfEͼeXDY0DDD@D,|kg7EP^l[[S %z �#cz�|VzHjbp�GQE$C{in%x_RE]p?-G̜Kz.8\;u-KuXDYDRRAKB" ,.qKe$ÚS˅ښ5TiAA J^/~TZ[K߱W*ziboTnb(oTh sz69kdy/+GOkaYUٗ";U*mLun7R I <uO[!M~uu ҲTM`UWq{Sd'MlSd4L`w^= eR(a%A�`q PPUj.K:w߾𣸻IsU_SPnn_ UNlC$n9ZK^z!NVmd""""H�+8+2VKgAr0ӿ67ކ)ܱ ՛\jn:Q3k44I�H#ΛK[+9'_N:U/S/)],u-থi lq�sZ�iIU=X 䥥 Atk%i==Gc,-7[t҆~8'D4|; I7˒lUER 'xk$�? ,OsѴDPD@�D_ed>I`.stJ+w+5qMAVL`yЕc]~Y ͺto J9sEuWI<f_ s):-;mwTcmZOpcNlkwT&a[eߧs~H}t N~tuܸx΄E 4' TZ{Wנ~tګ[)k!<ma qj 5Dr=#aq~�?jH|UwT^l3<nܻM iOfN{}9<`Z\qFj !" ".[1BKA%A1*flfG7dlTm%]M5ViYfJȑX z|ZZLT٦{H1cnaCf2�&J*aۚM88 V&_z()5K|jW4`ݰNK%Q̭W*F6惷k \LOnXts薾5UtI5+},_dzK@Kmio_%=e;֞riF^1Yӊ3K~WcG/`0; Tw:H='_q ۴|O-~G�S5u5iAD@fV lnjDG]0wGl}x<"f|~5C e!1o[H'CEhrrkJMMg:<yl\rRRRįhhs'Oa߲9bCi)m,Xbox66{vz1[d-*.=T-2.=?g͙4m}  }+*kbDퟥ [$UoNSx]Vb:Ξ�NЇ234.{5Y�:G\Yo X"dVA~ʥ`Nƍ�6֤[EGG=HDtd342F˚Z-DSQU*yI(s?wDM:Õfltq!$R~ǷǕ][ϦV湵�(*r T :sOOT-T3[$cji!7k|ǨOvEȔnM{�d$HѦ먏#U^)臐rMm&7J:=Em�_"hOzcFRո2�@Ks5$~. {,VY*j+k.4h�*DEB l6uU[UYELG$tCLhKfpy;,ndž".mC&7ۿ.;կdkmǐ GƷKxCzUT4: F*.-X\vLcqq(iն[ͼg+nESdT- S$ƤwGʌqS<h"/6Kte@ߖ1�9Zu^8]g5QwI=+)Innꢡ=-su1JҴ3RUDmpc^])XKm,jMu[vimƚnQ6hfg{k Ka[hbQQx" B" ,{~1s}*G f?==yhm躍'&zf6p I[?ކN>sHv6,:IIuܹwkGTO*V|S,QQZ N*suӾ^Ws6G+*2|t9x.vkן6^;"*#mcRdyʸ8mp}-)"Xi1K:󥪿8kxT}'_G\-w[ ¯Syڝ"6ʚMGa$5ދ)y.̒'wDpN7CD6vtV&ku |U._zXl)OrjqO.-M~Ml8DDD@�DDD@�DDD@�DDD@�DDD@�DDD@��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������krb5-1.16/src/windows/leash/htmlhelp/Images/Leash_menu_help.jpg�������������������������������������0000644�0007046�0000145�00000017037�13211554426�024377� 0����������������������������������������������������������������������������������������������������ustar �ghudson�������������������������libuuid�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������JFIF��x�x���C�     �C   ��"�������������� �S�  ���!"1QSUVW#257ATu$aq 38Bst%6DFR��������������,��������!1AQa"q2B� ��?�Myz|;_2ԙ Ej˶u\KhJKBJlOw'cK2\c]"0tx ꐢdLqWBYWX**Ñ&<s-HmBJH؍=vG~p"}e&",((Z7[G)W$e ]eS(O9MsSZϮ_g6,)enG+I%t}̛S᭤U<k*-5=:2<ПOe(6CkP Dŕ=Kʝ+4*vZBKL򎝩$%;3|jZgDC6UR&�)`̞FRC dDbWlɐS^zqҚHiDLJc�K)RQ _m-nc:%t˸)`wfEaB\ lʻ]*z'5-CwrPj4$P71<s#'Qejvjӕr1m+Kۘ*)= J� $u�gi$:eÙ \TNLyQY'w9FyC5jivm'W�Wߐ- iu͎Hv_z*A;R`62k(`!PC[)6&CJט뼿 3jc~^jOZQ8彤M-^㍴M]JO*V"WBvbl4ː !!w{07ܫ||sSudEz|5XA:;7%@QvT)><zӢ-tUWBNl4TΦQl,up:enbI\޾p6=FeD}Q^H[O2-'RGB2?Uj6UֈA n-J BJR<䁞;LΜQAdm� �2+Qe݁R!X4">9Зu.Ν*@n\::v%Đ|drbj KL INr2y<7jJJJZ| oǽQO:U}!ßGSB\+ #R?>gPѺU"PZQ.ζD8)+g?)yuמ(H2PN 5VQIfWMJfl0Q#Rvp54ߨ}i8JdK8 )*JPs)II~bcDf…KՓ*LF+ty #ÛZ ]Wa2չc/Ce[GeYVvp zWHױ{Hv*ȀK m77/A;iOfӍ2B STŝ5Kj-L^eǕi$f;.i嶷#S︖ RTH747zsHG6ܺ:A[PHi h*#r̷=WLi/OD/ɺ'nζh7SUmCbpOh,D�8;ZqV;:D~PDtiNa˻~Bҝ<8j}=NGSu#RHRSpyT͐W( %EMLƔ^L28d) y) n[3ǫKnffE{Q>ɂmD I#ΐM gUZn™TEas0Kv$T r@%jB nGcg/z12c�11`¿�?�|lcO�'~�V<Od1>Տ�8}Y;m1>Տ�8}Y;m1>Տ�8}Y;m1>Տ�8}Y;m1>Տ�8}Y;m1>Տ�8}Y;m1>Տ�8}Y;m1>Տ�8}Y;m1>՘_VܩeW-Ou%y/⚯6�͜aD,PyoЯ}xCB򽕝ou#Nz$ &g m#sմwzm^h,PyoЯ}UJT&qK zIV|΁�q}h.{ٶaƛIRP-'lZ;>^ut1c\Wav`_JcZCI�w ;m٘V?wt_x}]윟^윟^볖g뉶*͵$(9\=;F6ߛoω6GUY l!\C$ӊC{4TRR f|1/|dsPur~6UzWDzr~6UzW;㴛MI .~lE;22[i[Bm㩅wZA(uy)Zo%|I <-OOCtyvcjhNG''eWez{''eWezZ>?HzbwkM?4 ʖ;~c 5'Ŗ܇vTP%$)bHSi$9٘L=2v=2vryʹ.ďbt: \)8O@9@U}&Wr~6UzWDzr~6UzWju7K9.䍋gJ _y"د?^JS[xǽOuݻoc4iqCJwGs*x̤g`9c01c�c01c�f'TWP svT.նfO)�ͽ\~ϫ# iUVvT Iu :9yT⎯C{HMPVe ؃ZӾt:?Q3CM62%HҶ z|[!AB6GzG,5]dSXDo 0$I0\wvG7@ﳎl}nwlxCl4P^=j8SSbIeV!r'=$(lrƒLzjf5lQߒaJhnԔRw?;<?Zo'eNFSavqvhl4Π'b$$BA# }wFy}S;{RJ@2;NԤ%JܽONvi8po*%ϳ^ԕCa=;/%߾HJV}qCOpNh:W뙷%)#<۪e$nI�j׊-L|s"rZщEUqӗ0ٱs�#i t�iQ �w> =ivP5d6TWmġJRM(ptRO4mMUYkj8"Y, lɌ#8cT9(%@+~I_xBOi1V}*PDв̰0\xrUβHe)"y.H׃f"ʊ֞Mo쩗<2 Ia~V TIl$n %E[L (J7tJʁ_xopMOq_ҝTQ yC^R\iԔ+29(& ZyzʊYj2Wg%R; J Y[*C.ic@@D}1` v\dlۮsWaÚJ_%�BcD2\GxTeSkBҲt'rv)'b (|/4ӆr AWӣtYZ#,t.Du:*JO8#+_d-H )pփZYտ&MUH~|U*"BځU)<JJs+[Oh[@fNC1JX sx{G}UILcT b,_]-LZr\K!b;Rۊy :c줨g+6Y ?kg=U?a;y�11` c�11` c+,S�{,SmO{O>+NJ�ILu<NPun�ܠeS<3:"m*aLHB-IJ$swlbN�Q~Sdi;ĴfV֎w::́;O5X4nF_f_ R#~s~ b-Q }:ˑ$9u^Cl:fI 5*-$$j*=Z኏E;F!Dk+Q:x1Ƃ Q\Y~,I„gm)PS %n)jeıڷv uf啰 iA~=T1Qr? Tz)0ԨzsuH PMbV֙w\9q-#;5δCg9UgRi!VjK?&UkoHy(p6;bN�Q~SeA 4/x"JZPyc&yNJLm(?|Pcj \+zU-[qC:9BSjIUC+,T1Qr? Tz)1 3Dau25G5--jTro)T>mzfǕ~Scj*=n-SG=DhkV@\B?p[^o^oW# c:c�11` c�11` IJYOmeC%oe u @52LY2$IiHH'bJ )IH$Y2mm٠N6\4ZqqiJ3ncʡN^gq15<dUm\3Hή?h84=|,4l}EYH٫]"K )K\򐭀>fzE;RwitiuPzK!,J(R W8#sltr3 M/)9`BnyI=QPkf[Re#J)].>3Ӳnխ( Gv,m#4 ܤY\▌kPF^E1XDT[QPVy>c-烖>6+&[GVTt#ǢTФ+ztfe|XUwPTZ2%;$1""$^[an)";*P I)$,V'TW'Rڅ;<{�3-1rj=VakvI�8F+HrsNJ;{N -uQeڈ72i;eb*#>Bt)*J|ʣe+ZIO($82ٗ~a"'Gv101W8WzU;y�11` c�11` c+,S�{,_�dp+:4c|ȋ"Kp0+dYugd$֡vH$m}fӏp4KT:vv|#@z3KCLCQ/OD�$GM"bkQ!Ըo鐰N6ر{%!:Uyǟgx 4lTVPԡJfSQ_gry'jst]]bi︦Mi-8_ϔZ@2ޤna;Wi&tЋUmÿ\ܫ Zvm)hW]ͥ! P� mӧf]ֵRc1c�c8�{c{g\N1g1` c�11` c�12Yϼ$8ZO@8om* trٕO)�ͽ+F<U+F<U wwYvp۱jδ\նH*H' 3_kCXkCY` kCXkCY`( �ߣ[_Ǐߣ[_v`0!.hYPB8 )VOs_kCXkCY`( �ߣ[_d}cTCn( *! U)�v9Pǿʽ?1ǿʽ?3ЮG'yE'Ƕ+#OYcc3mV4G(. hQ=fc3mV4G(. hQ=fc3mV4G(. hQ=fc3mV4G(. hQ=fc3mV4G(. hQ=fc3mV4G(. hQ=fc3mV4G(. hQ=fc3mV4G(. hQ=feC%oeGE'ϳAqJ?jw6d]L\mr\Z*J (4,ʼ$neF:ٗ:[U SiKRy B !㺖r셥2T~Z[%G}˳ZeVT6zvX?=5[sLڧ^e))zlԦ)oR-ݯMU>q0A*\BQmNH<ͬ!ەI'~<@҄u9?}쁥w:�ZYa=Ut%uωzR§j>Zt*e X7݂j%Ml>H!$h[i9Zm'TY̊/@Ng<H~o־x<@҄luA}kf5-%uoζnv\tzJˇ6m 6= nJRʜKkfR̄W=.fP<B]6}""dv2Tz[fO+!a%G`y)־<ҟ�}kf] c}sKzNE­qv}yLl-+()$;F;-^u$dmGQ_k<!io5o2X1�d--=JߚY!!io5셥2T~0r��*xϟv1mxq*fFsy[2v#�3Ю93�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������krb5-1.16/src/windows/leash/htmlhelp/Images/Leash_change_password.JPG�������������������������������0000644�0007046�0000145�00000073134�13211554426�025432� 0����������������������������������������������������������������������������������������������������ustar �ghudson�������������������������libuuid�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������JFIF��x�x���C�     �C   �bC"�������������� �Z�� ��!RSV"1QW26ATUbqs#uBa347rt&5v $CDEFd�����������0� �����Q!1Aa"2qBb� ��?�l9㡦"~!6bccJ njQ̋"ȋӿs\yIjƢ|,J"Iİv_}MҠuSS\aØ%i(*2"%ef\>eKv :sNp0;5sL:%!!�wJK DfIZ<vSf]&Nttgi7RYp ^RzuQN,;z9~lubuU)LHGQqS=*\fN7љp g兌DSz*7&KSbMy6iCK5$FffDDyN%ρ'o]f~^i߹z9~ڕ=ħ)/-Dw`Ę}J[N+IfE Xsتץ5Hoo9Q6o%OlJJZLѱdG�bR.m Pݾe˰aףwk^i߹"xܻC%L66 {A:Kqۙ'|g#RϕDWDI3M*-lQJ1Qwİe;z9~lu-lJqkrO^Q$~T呑qҧn?Wi(*{uM$㸭FI<Եp%0M?ؓy}(0;5`ïG4f3KDjaOM,z萉JI--A8(2%$̲2ϥljrc 0ޗ)Rܑ odmY%c5vSK{+ºez9~lu+ &IܯiT)0$%JIH.dGKtqKi©5(0;5`ïG4[GK6@Maףwk^i߹$@m.n#v :sNp0;5ĖR M$n^i߹z9~渒?]Ti$0;5`ïG4[GK6M$n^i߹z9~渒3@mK&"H݃ӿs\6 :sNq%g.3@M7|Dz9~luKhϊ]g.n#v :sNp0;5Ėџhϊ]4Fuaףwk->)tџi$0;5`ïG4[F|R >)twIaףwk^i߹$F|R 7`ïG4 ӿs\ImK6M$n^i߹z9~渒3@mK&"H݃ӿs\6 :sNq%g.3@M7|Dz9~luKhϊ]Ti$0;5`ïG4[GK6@M7|Dz9~luKhtR 7`ïG4 ӿs\Im.?]4Fuaףwk-GK&"H݃ӿs\6 :sNq%ThtwIaףwk^i߹$@m.n#v :sNp0;5ĖR M$n^i߹z9~渒?]Ti$0;5`ïG4[GK6@M7|Dz9~luKhtR 7`ïG4(/ؕr4Z0BmFp(e}yyhϊ]j}:=r<Td%K&9O9‡RTFGJ-,LȌǗ�WKm�6jq)t)]EߡXݡ|aVۧͱU7 IS"uh譗Y虞f/7& :nnfJQP+/BmHI:H3A6_W0'5Y* 1Zug1a[mTR̋"W {?Gjo~�neE-k&WN&H4k*>:d'ʅi4yDA@{f&Ր)">}C`>?fԟKu'Idi?&Hˠ`{Xi6{TV֧<[9T,q=q9&&z9Ew2NĤ6ONymKT&3"Kjpσϓgn۽󪥺(*eTJ^-oF[u[9<1Y.[ʌiN-ڔӚ&<hfjD#"#Vygn۽n~gn۽án3QֆQ߭MtşsE͍ -oGX(I>#E!iCIR4r,9kƮOT#\kE. )v4v:VDJpD7kuؓ;w-fݍGcZTɎnUQY39*U+ {/ S%YVj:aSWP *Ě(N4|dY蠈{\^mS;qɬn{Dm.j82lIdgGu;wCu;wEN,oe}p> bM.~Uk}g6)eSybJFd\:%މNQDfftvŢ짩:^5r!(BTIVFg6#u;wCu;wF)JGJ>>u۪^.oZ뱭wTU^}dKRoi$tIpQWHڧc9JŒ،qd҂Qȕ-'d/mO[w O[wgۻ9Du.|C-_7ź4}ZEOɦǔj4f% 2V%d^LՕb>^mb,ҍKU]:1p9KRiĴQDKȓ#Yۯğ۾rğ۾r2uS(8}<]ds!p[F4 Z*l&l+MRRDfȳ/f>/!7_?3}m7_?3}muSu60(&|_7|_Bn~gn۽n~gn۽z谉 ğ۾rğ۾rA@AA In!In!޺ ğ۾rğ۾rA@9A In!Jn!޺ß ßį۾rį۾r9@9A Jn!Jn!޺ß ßį۾rį۾r9@9A Jn!Jn!޺ß ßį۾rį۾r9@9A Jn!Jn!޺ß ßį۾rį۾r9@9A Jn!Jn!޺ß ßį۾rį۾r9@9A Jn!Jn!޺ß~%|{~%|{]Dϋϋ=W[w W[wЄNnn~%|{~%|{]Dϋϋ=W[w W[wЄNnn~%|{~%|{]Dϋϋ=W[w W[wЄNnn~%|{~%|{]Dϋϋ=W[w W[wЄNnn~%|{~%|{]Dϋϋ=W[w W[wЄNnn~%|{~%|{]Dϊ4KX[q.i) !TjNIJ#%MZ&hu;wEav+k5:ڑRzO<Zc;!-$gyfc�OۥɟK'}ԷMtwU{= V*Riu$WS R&ۅtto"Q):<)NZ(4cx8z9۔r3҄J;#:YDYX_2-ި{Kat1nZvmBrRR~RNڴsr1i.5WZp)~׳Nƪ]tؖ/7[b]oIF<i-O6Ɋ34*|A7!0/� l4z]?gE+S?,Qv#��P�������������������������������������������������������������������������������������������__+itp W-#=|(7 ~-;T WX#iߺX<Ge�̧ͧ{Kcq+<D2fK53,4KG<\3!x{q$Zu +IpN!΢3<著˝8ϺNE&I.c-<yPk=,G8viUaעo_%۱ҧKq=a%,*]n:fDNy,]#1 �pj$L�r21��������P�����������3��r����������������������������������������������������OO�~|ƘiG�1??ާŽSpGӿuL"Eu?gE<^vZV QYmڄu,!NII3>/{F{͵li~Z\R52#BХ4gj%,~BFۊ�<=x[RЖ^ xfƭ֯ә#.3ՍzХ?sG\#y5!N^eI-Wdd7kq Ԗ[+<^2F_.E EiUI|WÜAT*IZT[Rm╡m"#˄TJS֢<~XyObɳ65*ZEH[2TeȌqgj5Ry؋p5HS//I|XfFQ)"2?)Uk[/=IikPٕOZKl}u-,&0,I/,HDbwfc\.FCnJVYi$FDypf@̻뮷Upϳ ^Id66D=D$G%,#׺UQM~ a,=D˦#n49FC&FEfIt[v[)BKKy AGA%NDY\*N2?)h'/!znYj>Π!dңSmVK' JQ$̖DDG ZӋ4B^wiz8F%R-&۱ߗVq_mc:Hn7gDFfj<l~kҝj݈t$2=I&;(Se[n9 AKdæN/5x(`׎O ǦMq~)-RtUYNSӦ?CݽMrDTP̥&J2")(1n2m먪4[�:1K+ݺh/Xn:zMԣKN' L6.'GG<�1khd: Q&jwP{.Mb:yF,DQhpfǗzƹ$̕!W$'6?k2I fR5(ȈEma5[ͳZ3UM$3337G ?)L>z+)n08xs*ԦGN"A]yմphN"ZSyh>cXckS)M5%Hf[I$�VLJȸO2- ٴhV*MmVK,A>bNR : :ޔ0i&[-,Ii+">ݥjֻ['ZcBjէDSiym+ۚ&SvG=diֵzٗ%P6T P:ԗhJR(KAM+5TdḧUeB /D(<5q$d̓IJKCɒHtaըw*-B.3,--]?|�4dsOzN<Kc hlj])e; &Jm:%/64T%$NBxxTRN2ip\jL6V>!f"3qYJ|b4'23!M8NkQ+%fGf[m(V'K&e"Cyh8ZKNDE MJ;Lhroj]n-_#[I u6WS/!IDfiO ڝORw> [r >l9KDw)$ӖI";5/cTm*-CˬNY)IJSJ?>F:C6Ӗl P]tr3_Sz:&>=7~Y(>Ks㲢QA5ʝkdZ9IfKGfhfu3R=t:{K=G\yDžf}/%4uҧRJi;.Y]9ҡrjN歄?rޝv"< 4lO|Kj<J"=#,Ć򞼋)N]G^삡cUpJclЩ5%D!%E)'PkA4i%_#5dGg/j2n,gr+6ȅ%Dv6 L܏H&h,eyUl~MNP |IqeDm֤8Z9-Ĩ<'!YxS #$呶D$ H8C>mzU6-U]՟^RHqT1̒HS8RH&g>וV":=9�mwGaRF[!Iˆl M]:EiQQiPFfDFfy>,?hF)4}Rj &Ko)&8JHF4 +*WwNs8u[Ț[B[Y1Fqrf}+iKFdTi_`[&UR9ѤȋۓK<NL4digydw)**tJm0ggGm6%lySLI(S!$-=[EBKpN+D,K^jbFE;>VյwBkt*i1( g)T fC+ŎO<ә@H˸*"u 2$/dTǔ(!IhA%wG - >֣M*r)9%hi,LtFY*ZT4ӪNdzZnG%>Fy8�Y{,J<�?»xYQ*LGwqSfuԠG"MFeˇKDFN1M13dM "JR"""z��@�������������������������������������������� 'G '�?>q_LO촏㣀bƘiGSGX#iߺXN3"/i;-��e[=^ xnI5'SQ& :/FfZ\Yg0�PxW+l-[r#SPJ-#�q|qCM!-(IdD_;�������������������������������������������������������������������������������������__+itp W-#=|(7 ~-;T WX#iߺX<Ge�̠������������������������������������������������������������������������������������������¾ ¾ ϜW-#'ZG{QnZwA(GӿuL"Gx@�@�������������8r(3\c/8P-U%(Шk\'tKIW@"Z[ڷxT)ꃋ>쵒|!SR$FZrQ$G*s\l4k/ik/Myo3FxKTą)"R :Zf%gWq~9MNLvHqLTI)Nq -:JwZT S4Q!Te^' S6u";4&$%dY, yEYedj˄Ȳ#Q]ҭE9H--ޏMU:!$dE(5z|z.܊ARl Vz&eY?#W9�F4ۆk,Z`Gq3-I&ͤ $hJ4$r˨7]ܔK%MB٣Jv:J9nQ[%r2Vj2GL cz\t2\ >ți=Rr+bu7Ɖ9|!tXji֧)%ȋ.]<54f:4-N|z[kCPUu')q) !hM!̍.y K&ɦګ ,m/H?/ /H?/,ߤhߤh Xނ{ނ{qKS_~~_O|_~~_O|.0 b sz 4Oz 4O,ANoA}F}=oA}F}=%)/H?/ /H?/9''� 7#D7#D\`ߤhߤh Xނ{ނ{qKS_~~_O|_~~_O|.0 b sz 4Oz 4O,ANoA}F}=oA}F}=%)/H?/ /H?/9''� 7#D7#D\`ߤhߤh Xނ{ނ{qKS_~~_O|_~~_O|.0 b sz 4Oz 4O,ANoA}F}=hUmzcZ1o#cyiђ]R32͑ 1XG10� ¾ ¾ ϜW-#'ZG{QnZwA(GӿuL"Gx@�@�������������<kAuOu)aMO6ZY!gVD|1ca-&@v Z錛Џimz9e  D7hКB5=m, LT%,I.l%,&ZڤGzJ*Ai*JKf2O3VzY~qoRI!)"$dD_ O KVyUC)o<J82KxDYΥK.,J|cd^w+nnDmhBm"A)KRK"ȌDE$&ZY_GNkwoEqcUJ=ѶSJª53ĕ|4.QGBu5**6RI.DS6YI.e#$ C iAUe�Nk:nZ*qZ /fGJQRKŹ2ց^C[W)^Z ؕ("ˇ2'١]!ƱB>kf߄låi&K,Mj"6O7<-YBfҽV$Z.Uc4߂J Y!jGiTiQdz'tMy*uӊK&t"A>/7<-YBqڻ4^>PK\᪈36CiNZ)Zy1ܹe0J[h-%%&dYf ^H<6d,!G&\mgul)*Q8-",,zu<@~[޸ކT1XHȍdܓ#2?/|lr2 coY 1ZjsI)m%Dєx$BO{\Ha~,1i[d*q#ҋ}]ok[27<-YB=(e߆E.3lr2 co7ďJ-wὮ$zQo˿ i[d*q#ҋ}]ok[20Z~, 9f� {\Ha~G 7<-YB=(e߆E.3lr2 co7ďJ-wὮ$zQo˿ i[d*q#ҋ}]ok[20Z~, 9f� {\Ha~G 7<-YB=(e߆E.3lr2 co7ďJ-wὮ$zQo˿ i[d*q#ҋ}]ok[20Z~, 9f� {\Ha~G 7<-YB=(e߆E.3lr2 co7ďJ-wὮ$zQo˿ i[d*q#ҋ}]ok[20Z~, 9f� {\Ha~#YqIDj?9�.O co\ТYiI,V[}+G5w*e̊m6L ҖRQ YfYK9@�v2 'G '�?>q_LO촏㣀bƘiGSGX#iߺXN3"/i;-��e��������������֛kP. 7E>m6{Qi4ȔݤGaM7"Z%FdJ.F~ȴYViǣ ۛ )kgِe%f“<nҮ{6.us Sfm[Iy=1hCr]Uz$4i$)/K5^mH#$J-~.NUu-2L~ BI i1tү"%yQ+#Wm"CޞrMMxi#IyiW"_4ꋖjkd2<ٶX})f:DIdgEm)*3SS:$֝ x.Yh磡Öyp�9su >W`dF|n4f\)QJNe=y)[\5lr2)U۩Ԝ reF-3Q-n$i"3dHE3òm%A8pD9RE"9Lrm" i} JvGt~R%\f\#hn5K#tY)Bj dSt;U,6#S7~]·1 2NN!2fYfҲ>6nqַua'ꍏO,߿fXխ6F'Xv/Wt*r:T(fӇ5,S%?0h4qqTk$KH15[QyH3eY:3<L}kz,XC32ԚmV1:),ˊ8xf%f*'gy|1)ʥGW=VC@iqxjs#m/g$!G![u,ї޷Z_GZްR^^Xu-z[#[48hR`LO0PIIt '*0-bD,AeWUavBMk>'3T%$_)p6'kzQ8[16{I*)e+h< f?V Zm6kF ҝL̕ž>eu/b[Q"#mJ\Oqh3H#5#<@]zMVb'ȶuaK::S+T T̹i%ҹ4j%4["В"E2B#2[dzްn[Nޥ[m�#/(`۸:d ?n[ #oX$�#/(`۸:A ?n[ #oX$�#/(`۸:A ?n[ #oX$�#/(`۸:A ?n[ #oX$�#/(`۸:A ?n[ #oX$�#/(`۸:A ?n[ #oX$�#/(`۸:A ?n[ #oX$�#/(`۸:A ?n[ #oX$ $Kv1).w2nۚRJI$y2̼&۸:m~;{KAAľKH(AK2ȋ3gD #t !b5շ;4QIJ|Ț"RTkRsz$^iW_~ %/bFjoS>X:6AR,Ԓ?*OKmڂ�6@8W?r8W?�be4H:8z 8=MN3"ZwA({Oh��s(������W\T(ηj*:JG4!yʐ "Fk3RL&QK&%ZLZg@$嫼mR)ϘqceTP.--jf))FID",.:;©9"[0H|=d)VIȈ*Mx^_)7 hZ(&*$j} Ȩ~NNeQ{F&GRYtֱAQaVLI6Se� \u4ҝ47ÊJ/4)gd &d?[QCJ, yHSaFR!\{i} 3aS{ l?9 :Z^Dc(ҕiD.%>\4teO*(LKB;FC CcFe=,d頞gI3-puUjWyVDfS5TܒF< 2^j23I-5feUm-i|׭_hmqH]+IT%dde# slIR8 fw� 8 6/8/6#A<R Kg,ᅪ8 6/8/6#A<R K11b/B8 OA<R LAؼп`ob/Bb4.Ok6/8/ؼп`؍K4.ᅪ8 6/8/6#A<R K11b/B8 OA<R LAؼп`ob/Bb4.Ok6/8/ؼп`؍K4.ᅪ8 6/8/6#A<R K11b/B8 OA<R LAؼп`ob/Bb4.Ok6/8/ؼп`؍K4.ᅪ8 6/8/6#A<R K11b/B8 OA<R LAؼп`ob/Bb4.Ok6/8/ؼп`؍K4.ᅪ8 6/8/6#A<R K11b/B8 OA<R LAؼп`ob/Bb4.Ok6/8/ؼп`؍K4.ᅪ8 6/8/6#A<R K11b/B8 OA<R LAؼп`-x~mYNÄBTH%gfyp2BO;wnG$� OO�~|ƘiG�1??ާŽSpGӿuL"Eu?gE<^vZ��������cPTfZ%JԺuBD BlahYFI3ARfYe'SkC VjNhj3 *%a m-*hӲ8Y̔dfe=6ivK֔x**u#.CR)Nfk3QG|#'%7]IiFu/)D} &Rehq'$QfJ2<c0}59zإI%B$�SLdֲٴR,ňB.UMͦ5Hqɭ3d>%6FoM؛BIhQ[VtG*@ SџfC-+mZ)" ,2�痀BpBL5 ̦H.+PJ_tZփ' n-{!/HYiB6-h09/jun89̳"<"2@67osg�xu>l R+$N,yS%p" .TX13 3ƌ7~RZ~RZᝁ�`K\7`K\32@IkIkvH݃?_-p݃?_-p�c{g%g% ov ~v ~;$ԖnԖg`d13 3 7~RZ~RZᝁ�`K\7`K\32@IkIkvH݃?_-p݃?_-p�c{g%g% ov ~v ~;$ԖnԖg`d13 3 7~RZ~RZᝁ�`K\7`K\32@IkIkvH݃?_-p݃?_-p�c{g%g% ov ~v ~;$_#K 3U8)IY+ό 9Y�+9+�1??�beO`ŧ~Db~-;T x��9�������������������������������������������������������������������������������������������8W?r8W?�be4H:8z 8=MN3"ZwA({Oh��s(�����ױ"m87>Dy-mhf?J- #,ȏ*�oKڜ򐦠5HNBQ癚Tɨ22?.G&~)Oak1.ZDC4R"_"%iQf_嗓%CO* |LpRR$o)9-2r1RfI!W0.zTn Is19IB\?5Ԝ4E]R Ȍ-0MyfW zoe}ߥd&u+mRQč qM37mD,g]ѯ: U8? IXv$yqM敡ETdyp?{MSK~Sꃰ]ey 4xAdbnjTٴϋeKcYVLo9,솣qJV.Ng4]!G \2ɳQ.>HJӉCh+6g2diwcQ\<WCFKjK^9mY6)Rғ]%) M'CE$H2IEVI]fg="/DFaVyˑcYk1_2Zj,I`m¦DYC ;3u92ʝM� ]vJS҅ i"5'E9JJZˮbovF[kڦV"-<DKJQȏ# 7f;Wnn i&Bl-3A2a=h[_C‰&fm+HЕ<S35e?#&wcïk:IΙiI<Y,\grWt.eܞ,wJrxY޹+h%<Y,\grWt. b KrxY޹+ !gz]grWtŞB]л@%)-!gz7'<뒻vKR[ŞB]nOy ;%wB� '<뒻ܞ,wJ,AInOy ;%wA<Y,\ Xܞ,wJrxY޹+h%<Y,\grWt. b KrxY޹+ !gz]grWtŞB]л@%)-!gz7'<뒻vKR[ŞB]nOy ;%wB� '<뒻ܞ,wJ,AInOy ;%wA<Y,\ Xܞ,wJrxY޹+h%<Y,\grWt. b KrxY޹+ !gz]grWtŞB]л@%)-!gz7'<뒻vKR[ŞB]nOy ;%wB� '<뒻1J\tk\LL͕)eR[d%fjR'e"yZ?Ջa.P�+9+�1??�beO`ŧ~Db~-;T x��9�������������������8?!;H��Xzت?e,i$!0JHe*,P7ԣw/R`2a�v_۹|f{^ܾ3}J=r(1%۹|f{nQbK{r(7ԣĖ nQ oG!, 7ԣw/R`CX@+ݻoG6_$Ww/R`mܾ3}J= Ia�v_۹|f{^ܾ3}J=r(1%۹|f{nQbK{r(7ԣĖ nQ oG!, 7ԣw/R`CX@+ݻoG6_$Ww/R`mܾ3}J= Ia�v_۹|f{^ܾ3}J=r(1%۹|f{nQbK{r(7ԣĖ nQ oG!, 7ԣw/R`CXC?տ#K;w/R`ɩHhK$)�ؿRI�+9+�1??�beO`ŧ~Db~-;T x��9�qvPpdN%5HPfh#2VqI2(:15mɭ8dHK):KJt^Iȋ2Z7ŢÉg߹|)BER{̧n"=h*qՓ4>3Jg NI%)Ĥx%7y#̋rJTЩKJ@ qŒRJP\M!UJJJj<J+γi7ԧ&zEiOZړtP:ކP^!6AMSo2m *"<;cwx tm Mf=e)3L™CVmhVN R JA,1/tUeVarZKLI-}[BIK.fiN#i-0;T52Y&K"656#uo(4(me)fWQÜC^W}oANj}Y1\SN $ R#I YDyjY((64j;o flhOe1DMo<$M_HZG+r ȕ" j|1$HeѤ98%6HIpk]tP@P}R#3)c2uŠYn6QDYd]"6Sʥ."*mQ̂٨#"qDFhY)*!l3/8”b= DMh3Q%FDR%3#,ȏ2,G0Rѽ0bTSR"KIP$JR\ͳ/9e!هDKy{0}3e ̼;{0}3{f}/wA2f^r}Dיއ; y3/9>"_kCهDKybu̼o{f}/wl%1:^r C;a^gzs/9e!هDKy{0}3 B2l%=}Dיކ!\Ayva^gz>"_kCe ̼;{0}3{f}/wA2f^r}Dיއ; y3/9>"_kCهDKybu̼o{f}/wl%1:^r C;a^gzs/9e!هDKy{0}3 B2l%=}Dיކ!\Ayva^gz>"_kCe ̼;{0}3{f}/wA2f^r}Dיއ; y3/9>"_kCهDKybu̼o{f}/wl%1:^r C;a^gzs/9e!هDKy{0}3 B<o{f}/w֋`RC>n8n>Q謋qJVEgf|&0� +9+�1??�beO`ŧ~Db~-;T x��9ׅS[DG\gV-)Q̌H#u`Uw\ץ*dzNq)$C>Di2Pd̏"%V,묌y#RXV+DՓ2znRCmEz jI(VfsVeK-cRyzOjK/"H)/)I|%M5z:vSf;4b &c7[jl6BsAJm'i<4CoTυ>gm8g%mٴE$! q'e|yS›I-`�ѥԫV+S> s-}/)IJDzi$qk$$ܰi#.tGfŅ/2.[ җٙ+cFddYB]y=pEs(l[ ܹeş&shhBRK ;$ɟp6MRRzs0eȫ46ΞRĽgc4VY.<)Y63%Va; I\u+uɗvh6 }3Fp_d1TxNyD7%Z5l,Ir24"%Ngo_"K.[IcfiaRI&Kz<9G]`U= j>Żi$fDD rV~O=L<ТoLQJQ R$d̳ȋ33l�cF=9Mrúm i} JvGt~R%\f\#EE?n[ #oXbM�#/(`۸:A ?n[ #oX$�#/(`۸:A ?n[ #oX$�#/(`۸:A ?n[ #oX$�#/(`۸:A ?n[ #oX$�#/(`۸:A ?n[ #oX$�#/(`۸:A ?n[ #oX$�#/(`۸:A ?n[ #oX$�#/(`۸:A ?n[ #oX$�#/(`۸:A ?n[ #oX$�#/(`۸:A ?n[ #oX$�#/(`۸:A ?n[ #oX$?ՋbSn[<e#m%GK *�+9+�1??�beO`ŧ~Db~-;T x��9�������������������������������������������������������������������������������������������8W?r8W?�be4H:8z 8=MN3"ZwA({Oh��s(�������������������������������������������������������������L<Qi(u-2$\)ۯz< =n�zP[3}癖N%&f2˄Is7 =n _ .Mئe>+kq %o6J$$g򚌈3"_ ݶ^>T+ebqMM 6vd^S",Yfyp2QQ fen2QpWRػ[Kle22R%-%$Y$=�v{oIvlw[S9u!JU[""/)X[xKsQ=RJfRgBz2dZG4"2>K-pa]4GTSP}YٍvM G> ,π{<gK3`N򶇞[�k@n`f(r}RmFMK>s0MB{i.>D�__+itp W-#=|(7 ~-;T k;z̫U) "t|$y,B HIQp9?gE)*,d<NeLe:[Үm% rH6eIJVMԒB#I}h*TPLV-km q)h͵6%CGHȆ)+ܻMeUYqg0D$ak-c$I/==H\iv4uGMSRxgohgDCYyÎ>Sz j>ԉi` Hb'8<ٵɦJa4AzIA'3d2IxܵzdJ;+RN? %64+D-H<UhJQw63aq$J4*Q)R6Ckc%.h$'2, ;~駪npR '뎒t JF~)$I^Qo]ͤ뮽vŵ*ܝG&Xa $43<MĒK3c~Q"Tf~i0YS$椫a$;DEbwp~)4]z.$iؕjG!)-8>idNJ"Qs#5j궙RΡQŔ%Dst' ><HDK2s59mϫknG|?BP9lΡGi҈FI'Gy%qJqk*RSrihзR KIEpq~mn;ˬFlJyD86UlhFGj<L<ՏrѶt.Tu*1Je-m6Yy,KQj,NsjGKhɆTq2V[s$ۓ G OrCٶ!*ZLѨ~*s!woI 9STyEHiFɸjRc@+j9JvDjUCY+JbbQ'Dҝ$$Ғ"/ eȅvB]55"JңZ)m)H5-"21mD΅we<\TE#/B6!sjRי<gie+2%ptrRu6;$%%I2q(-.V{V" 1T߇ą8ŞolH2$ddDFY |;*,VknGHq*)3'\W@@RӅ_8}8SNb{bE~ҶfQ&UP)}%h4Kk$i<Aݭb-Bmd~-uL2--yV'*-zCSJ˓LS&:5 yh&f-#&=P}5X+<"mŰ7olh"̉CÇosGE������������������������������������������=��W�#"nG1a+1uź5dEdY#c^{VҒXQ{-$ K K6DI�3>j'-Z#Rib;OPе҉iBA:QdV6/8+:a�(?U^{s쳦Ϣ<Aq"j*:pj'b(JoFACJ"9$,'H歜ZeRVouX.&\Met4kuL)kbY%yڥ!y.(�^߾=D{ؗ)|fMtb=x JNT̢ǘR$$F9+mMx>Y&:hf2J`؅�(^6/8+*iS{~Ey&t0G۔?<KCl^qWCP.=IOj{-P^mjk?^y� La8+O�Q֫G_qF[5Q.*�$m=#.B \9EʀE6z.qC>8OÙmɑ&#ٸ&CjJdmDf̋*lQmfǨd9Ļo))J g7.qKq_37o7#{X"l\w tbm-IUQJQ,F3- (s޸Ʉ\k5*G1A0m~6##�č~6P8!��/ʴ: |BveD,lP@ 'G ' ϜW-#'ZG{QnZwA(GӿuL"d3!\L}Mn*4FFؔj#,35iќ^C#"ApNKvدj2KFQoA!d+b[i^i5Dj2Fuj­1nS2{ QRda^D/Aבe䜖\ lp)Th1iU%TE"[MRPN˪pQms̢خ&[&Tg.t)R i%K T&R^fyNȔ$ԼITS]XLK5eꔸP*sq!o9>ؔI &VwN)=XyHy&qy8u)Y%#FFp3>O7'M9g‰\?úmW*ik+ */8M˝)m2#:)q&I"lG,+0j&bHʎQ=CmfO6D32Qgu`M,aAYf5*n/Zlxf`�I)(Y4'fyQene@R*MZ:|90\A#$n>)d+qS9Zkϒ׮PJ#ic1ضJM&fKGϸ"#<֥%=74-4ݷ NjNtJʏg<NK98fTD|Iѭr\ߧ<fi',,̼Yd[YRUQ*Q^c%|> l+Ѩ*#brʹh4$:Y3ȶ2Ru*nWG5Udo .ڻF~Pv:\s[KA;/M). RD3"Īxȷ%ǂ7ҚBC5ldk3NҍjK-"򑊜Zȭa̴s^snK/UE6O}a)&/%(\DSY {\ 9vt[i]2<8)\5!f6峤晧DF%~R԰0##6;M+wm ХL=(VEɧV^t,방;}1DJبBPO fJ,yUI{|p\.R[~뉶5tm!@DLCC*[94i~:]3m/e 3PڐMff,KZ]4Mx}+%"M.~yɲ (.\yV-́T' NNZ/Pi5#-$f~ěŴ5tY*r!ȍN8n:LD&"Imџ]il ,t蕚Z+TcJ!2Ҥ-RCtӤNM$fҳ3,BlCnSiQh ::Idnt8{"STFHLtID%O MmSmַ&׎3k_Xl3u5JUvͪe�mMMA#؛p_Y j֮iJTRp5LIĥdF{;7).�> BSۗ>DnO176moJ5xNiN9$/H{Vdi椢 0ه6*cHUEl%IQh|)QMhN<:{fbD‰TAilRiě�:W$(H3"(J~*=ISZj5/R3<FŠ5FNI!YU*t~&}i&ώ3,τVU\EL4锪,SR[eԓٓfDf<<35kmTg݃Ff 'm24uNE),ӣFR;['ל}H,R7Yݛ2̡M&S%i䇐-fԲQ/(mt]>JޅNYԇv1!RRhkVFIMe+6k=9Q}?W'EDi-Bp?%6Yeh66UkwDbFrb䧊S1TjK)%H<^$>}ffZI99\[eX]&L*&il8!5(RY:'RZiK~3k-48vGC$৵:L0K%2&Y|!&jI5Y暳^z>5F5^FUu-5=R*GrJG~6yGE~C'#%%MI!;*IM$ffE0Y}sDy8믣�����82#h �D%!�8/1yr�4KA^byr��m�]�:h⧠64qS;�Ǝ*zcG=�:h⧠64qS;�Ǝ*zcG=�8$|E@�¾ ¾ ϜW-#'ZG{QnZwA 7)yˉ4-iQHU8Wu- 1W@jcͷ6JRѵPQeeLAog ;'&X((q~=jkTY)mtTedf_!6Vr.43bFʑOK&A#FmSY luQ;A`6UV\:0J~"Rܭ˩DTJoDJI(JI-ix"-LO]Ig JZiҖ6GVN9o6SN ,%p|?TNgX7ͳDues"Π̀PdQi%:T)'IDeŒVycWU[SsM:m2 !dtM)6Ԕ<Di..6U luQ;A`Y[%R!QRI-nPD�:&fgGf\BrF@Bkb Ge3VHIHτ b|?TNgX7ͳDuIXJ>ۤMJRWOfDjNZ&rl"G,!MoUT:q\ k`UX7FKG3xͳDu|?TNgX0լ =oY4*m٤tF@I_|"*%"N!ޕn�JI#2VgluQ;A`6U Oa-hҳo:QSSwhYx8a: 8hNY'G}luQ;A`6U VZڵ%vmR*z> R$fiqI5'#32 6ؙYS%TgեxLs6=<$ND$Yg33Q|?TNgX7ͳDu{ieH&d:+uGunhRQAF~]D>URgLd-l"2&^hIIp|wͳDu|?TNgX0 ytNnj26 F#RI^R#4̾]; -7]Ֆ� {OH HȈ:g :ΰ`v,{J5I6Q ruIY'2o. fBDvǷGuON])ӊ,J?ȳ16U luQ;A`־;/ m*Tڊz2J4Jѻ#"mh愑IȸO=S,zOD tl(pS荭=$ez >O8xͳDu|?TNgX0LttZzly0"H)q-"Hx{daݫ.>Hz>9ę9-),I&Ӌ4-DEfe:ΰog #A 69(e㮘ɶY-RrQ6\ #%ODI`FvٵlldhNYeȲ}luQ;A`6U .Od&ݨ]& "z#km1G6I&YhsO.HihAr"ZX#FSTl Ķ⤖DIp86U luQ;A`V,eu`i#nRRcI{<M%gcP2Ld)2ΠiV۲L7ԓNJp˃Lv6U luQ;A`YI:FR+5ZS\ $HТ4FDe6LNNqKy4{|S,/(6U luQ;AapbdO9Nf3+ki AfZR) 3"藘4\;`Yv5HhU5q+=-?IYg|?TNgX7ͳDu$l;j֎[~Ha8MA)m.)ĤE(ғ2/)gx֍?Fdm큸J6F$HI!r6U luQ;Aap`}K~sDGDn1*CV]p>2^1(2>(E*p@Sێ׳t]I'ZZ5dBluQ;A`6Uڈ,&'e{mKfK\:|*~Daԍa< KdT%1luQ;A`6UVg-L3mΪ'h3v:a2`:ΰog  3mΪ'h3v:&g :ΰaɀc;v:mΪ'h3j2`:ΰog  3mΪ'h3v:&g :ΰaɀc;v:mΪ'h3j2`:ΰog  3mΪ'h3v:&g :ΰaɀc;v:mΪ'h3j2a¾ 6U+l�T_'  1??.4.6(Ԕ ,&T`=|(<Vb,[+KM2I䡴$JRD~j?�iߜ{Q`߆ڏ�l7=nX79p [ oz=�ao~sG~j?�iߜ{Q`߆ڏ�l7=nX79p [ oz=�ao~sG~j?�iߜ{Q`߆ڏ�l7=nX79p [ oz=�ao~sG~j?�iߜ{Q`߆ڏ�l7=nX79p [ oz=�ao~sG~j?�iߜ{Q`߆ڏ�l7=nX79p [ oz=�ao~sG~j?�iߜ{Q`߆ڏ�l7=nX79p [ oz=�ao~sG~j?�iߜ{Q`߆ڏ�l7=nX79p [ oz=�ao~sG~j?�iߜ{Q`߆ڏ�l7=nX79p [ oz=�ao~sG~j?�iߜ{Q`߆ڏ�l7=nX79p [ oz=�ajsTg;&[uDEfgD�D?������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������krb5-1.16/src/windows/leash/htmlhelp/Images/Ticket_Options.PNG��������������������������������������0000644�0007046�0000145�00000014173�13211554426�024107� 0����������������������������������������������������������������������������������������������������ustar �ghudson�������������������������libuuid����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������PNG  ��� IHDR��X���U��� *���sRGB����gAMA�� a��� pHYs����od��IDATx^][sǵI%N&T<\αة*9v WI8" $ݸkuꞞYsۚ-$Xm^f ;z M0s PU0L@ 4@8 Tρ> 4@8 TP` pjn{lّ$I6&eyGSl@pmDn4gG &٘qxpO86Tpw6C}}A#H_[$,< o\)%lr W`Ouop8|Xq�%.XZj|Q8}%|؋HF/Wd Kw֊C˗ ,]>u~fN*6[`=kbW\.~6kot~}S/gom>w郳ete^< W`ޅ?\ %Ut_xΕ(+agMaR%M Gq]6qf/E*AC<]~W1Ϋ"jmp398sz]TUU>27oބή>;q6.X|PDX_H_/d+;p31 j>?\[xl|>/ٙ5և^H_v {ueۇ/_${\�~C8p. 6x".,4>!o|Զ"Ns>4.^ZKѷ>|JIs>y{uhmS߂یϞU%099ZOo_DrЀ VܬKڍO 꺳9=6ۮکDPP+5#7Y1hD7/E<w ?!>Id0ɲr"F1(߀qu$9 $8{NvKh; 6n_nЋBaGyƷΌ!}q4Lȗ6yss'D$!{|01op!׮_1}6ܻw/j.GcZPC? Q`מ51Yh| JL X-C&j ~^ϻ9exyb8P`-Xmϋއ~Xb_!|}}{7oPkw0K?=zճbaG10cb$<{ey8]rtUg{;;=Zld8L<fH~z:ĕi  뱣&ILW\ Rc<v܆E7$V:9x4,D}++~7B6cQ{)xYI)G0ϸ$0 Q7K6+q]gӒk~);w1AuMA_+_ye)5fE]6|<㑸޹sGFY>;\ev~, X3t.YFHOs|l1C-n>_`3o~|'"+CsLXi8bwū?bc. s2|\ìs&Iq?cw`C~ђ'˶νg[{ }qc~j,\*.UhM߫zMӸKxRY{8/ݫ3o+@fHqzzz|;#7n8s ߱H`}vo{(PT_x%Sa\6snb=_o}sq87DIf|>֠HE\kC85s}L:]xrM]EX&cL s]p_rƦ}!LTQ|yxe<ckn/4~s^ny^"_n|~aiW:zŧ}. ܖ4_yxKb+dcrG_nы-hopхg '^}w[-#}Il#T~fV‡L^K;wˇGr(sp.&M0s q)H @F<ip@8 "r p@8P'Ѱ4@8 Tρm4*M0s� &9\Cq&9\F prx/MDZ.TUp¯փUjĕ=޽WxKb+dcR`³ʁcp[ĕC ǎ%L1Sl@06|/,ٱwVs;asE\?c8ōUj\ HÆØy9źk ihkF,?u87>~\<\deIrY�DV?-Ɯ<ZWX<]o-S3u7Zkt:~:j!NsL5Gcu[?wڇsy&OƗ7Z/0- JpuPlxy~]&-OkŸVeBQ_nljaZ~.ztՆURjVwt/ðc V$kڋnlٮbQXEm޺^U4>.vN΋l"1?֕/Gozp̼<x\,&msu$4q@jG , icD#$nǼш;u<A b&_ M̍믻q* DZƟ+baun~fGZ ɋ ai$T| E^u}A M<`XbS0D}`Sjt<P[}sz!h3Z ŚcC7ÁD4gŠ} cOAQ,BEr5,?(z|}8'̭_4δٱ7T7-&: qhQְa%xSudYs"ІcѯkÞ0`>mfNZMKY;{(\U:qlǖ3O>`hFV$\T={f ǎ{)<C҄bƇ:MPf?L .VEͩLجq_0Ek^XŬϻI|h]W/gَ6DbI 7ɬcp3|%-pbl *4jE>Bu%. 0I"Gmy<(' ^ƾ/7g6|o EֈcpR;c3K笮&UUL x~ۋ,xիC\\MfmkZ~8]`iCC~RFBj6,K0Ca.)egQMckc*?b<-ҹyP] ]@3I0*XWF}vT_XÊvp|Zª) Z $}##o9-yǡ*4?ܖ/DloHƟ0'k߬6&yk-hj7X C#n6ИyX=yl#gڨݜW/ТG@h=Gר+t*>b|M'ȟtrc*:s}/,H*rG޴v*itph\08ΜFI: r UbzqD?&P~܂65ki.[݆j8@>ibs5),zd^旆 ؗցO~ר;a`WV_-hfOv{c1ac+pC~|zg캟}}];o =sx~+28 Q#AGeU՚99c�/,b0W_ߐj=VOz8>DF[T\IlU#}.x!X$悕ƤO$~ّ>X`$Z`bl_s .Q4"M0s@VHU9-Ep@s�v  pjoN4@8 TXV8 D`TW`:8\&M0s@VHU9-Ep@s &9ZFLS@5E04Y0 ''(P˞';OC[뿀+׀~UV lҎ &́\_4tL޺ ?u3|Clm9_zm,RBNs7jQ Wq?4]N˼q%``-=Gn>ʷ7G>; ^Cñ9UW//y2,gw1j-Ďǁ\= _w4S>80P6//*XY.X8opp,aA .qc~œ|ceMT,x}8N> 'v \@;'/Nࣁ[p/ڸ~mz{ ,]$##.0ѭ3Z~ΈF9ߜd5E~|E 5+@8/|σEv1GeOd '\˃Cwg~C@UPɪU?j~+4B΅Szm~a*UNӊO70\wvuCßoWlVJX%j4UymAMT3%c-y(Nx.{DM܁ MGK>,;QE4*2 ׺mON^9*."1CfTVŪWLk/~H*$=W9):…k66?7]abr'`ttڿMo^ޤR/}T5X޼ Zn(~U%W/5oD䅗zd K.cZE+ WT<p`6p U`~A5-jM"8 2;eC ";g˦8fE`E`E`:q@NJ1{Y YXX^:q@N>+jM80{8 ++Ջp@8P' X"fO!k!k8 ++Ջp@8P' uR fD`E`S>ز ޴Z Q^ؗqEI^`Vv\yYƉ� U`Ɓs((E9Rݭ($~-KebKP"VJy:n- gUGc*YW$q;" 펫\BvFE$iǦE_lÉ0\8NK`}VFĒHcsU%[V=N0—}qx"yNŇ<"r(vQrMVTƕf#L5sD<( E^\4 L=gce EvޖGv}c]{.SMē_VE;φel %XmB1MRu XvoX/GXE DdS8 +cWы+b^hΪ4/9fzDҽ"{-1ٶ} c˫ً:ᏈT} A]󹳶RJ2+X+""s\`gᓵāg M0sF zS����IENDB`�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������krb5-1.16/src/windows/leash/htmlhelp/Images/Leash_properties_leash.jpg������������������������������0000644�0007046�0000145�00000064255�13211554426�025777� 0����������������������������������������������������������������������������������������������������ustar �ghudson�������������������������libuuid�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������JFIF��x�x���C�     �C   �."��������������������������� ���p:f,٫S+meJS\VIDd$FIDd$FIDd$FIDd$FIDd .^꺻:<vӧ~i|-Y7/UWk5MBP!5MBP!5MBP"r' "r' "G'm53E>nm4F;8#;8#;8#;8#;8#;8EښfeЦz`�����������������qyGxvC4md:>QkkM6dkM6dkM6dkM6dkNN<(yGxv��ĤRtE[*E[*E[*E[*E[*E[*E[*E[*E[*E[WrW;=E!DQ)JEDQ)JEDQ)JEDQ)JEDQ)JEDQ)JEDQҎ<2n3-w^="4s:ܝ+zt2j?26ԚL葲ܜW鼙ԒDQ)JEDQ)JEDQ)JEDQ)Hh; ������������������;õMo|ξ2dtEq0sGg>Fƺ\u9,(<~SETҊ®Y3;ȏ\M]ztҔyXp~&UCmXqyGxv�������������������;= ,mk^ajniG1 K��������������:4^Qi3~蟨Rv0؉<_Jjj12ib5L3L&��������GyGͷڌv 0iǞ~z C1 RRv15k|1}���������GyGDqveqOXIh!&Ih!&Ih!&Ih!&Ih!&ImA)؜];E",EA-KDAM/#'a̤s3*@czZ % hZ %YSF�3,wD@Ad+VBd+VBd+VBd+VBd+VBy-2TKL>܊erS-z˜G$G,~$AvZY{gth 2��������;[ܬ՘z�HMHfÅO yU]~Yӌ? -U}'o4�K`F49wFʦ}'ٗzK͇zK͇zK͇zK͇zK͇zK͇zK͇zK͇zK͇zK͇zCǤ<zCǤ<zGI!�.�������#43 P$@05!26"��UtGQ(q8r9GQ(q8r9GQ(q8r9GQ(q8r9GQ(q8r9GQ(q8r9GQ(pѩjmo6r' cd/osiYАv8$EJI5gʲM(e맬 QY`0 `0 `0 `0 `0 Onmum"ҝl#YoÒ5<U|oh_]i-dφ<. <*r|LJ]4#H4#D4MD4MD4MD4MD4MD4MD4MD4MDFءR`4߳O'Fw$mrFܑ$mrE\mrFܑ$mrFܑ$mrFܑ$mrFܑ$mrFܑ$mrFܑ$mrFܑ$mrFܑ$mrFܑ$mrFܑ$mrFܑ$m ^4I 䏋>k凜B+,"6q#72jZUxKTœC!d2 C!d2 C!d2 C!d2 C!d2 C!d-ٿSRK#Q$"lx8p j{{d v'r?o7B|[lY곤*YIuUk&�]#<zP=CǨx<zP=CǨx<zP=CǨx<zP=CǨx<zP=CǨxL )]|B>Fj4qJ֏6Rb?o�^�XiSr 7(nPܡCr 7(nPܡCr 7(nPܡCr 7(nPܡCr 7(nPܡAKGП2ۣfhOO34'̵Զhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh ynNXGS 3^MiK%jB$so'9{ci -(Sd,WՔŮnW4$oaI=5J"q-[n2eq-[n2eq-[n2eq-[n+un&hOkiuN _FzNGT)N&.-t R шnH՚HXdG .4t2{gzj)9J ]' Vp0)R0aH‘# F)R0aH‘# F)R0aH‘# F)R0aH‘!!7B|n>e?GП2K8 e'9mN!N#7ӊǼ/4B}WxtZ5$_Y{:UJHOl}': \WJ[]&սd2d/m)o!,Rǣ.s<Dw]8# Ig5F4Mukw6pOSfhOOls[R /MvՋm[X![PE*Udtx}WR[ŕom9Y|e]�[.mXM Y{ZR}2<;k{~_=8w%RsVWQV/num&>'\%GjYo?o7B|n>k™3 f)S0aL™3 f)S0aL™3 f)S0aL™3 f)S0aL™3 f)S0aL™3 f)S0aL™3 f)S)J[l _E)[/Uo/uUG;pUЫ%Q ힺz>xjk#m_uJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJ]d )-R :2UgiEi- ;R qj)�N>e?3FI(4Iʨu]> Kl]emgZ'<h{%ڪ"B۔fZH Q(\k *~'e'4shJ]m|mgWi=OL )b:QŷZ΅TzS)Fp4oqjG<tH{N5lhRFE\?G(|&Ec^KEPihZApmr=gk90]pR`fhOO34'}{Oi={Oi={Oi={Oi={Oi={Oi={Oi=vhO�λNNNNNNNNNNNNNNLvvvvvvvv,:::::::::::::::::::$U� �_MzVa%)$ӛg0Ĕeg/B]8o{Z-0K4dk�<o˦hhhhhhhhhhhhhhhF,ƧuacŪclkt QwQWkэRJmmmmmmmmmmmmmmI34'TbkcC4;cC4;cC4;cC4;cC4;cC4;cC4;cC4;cC4;cC4;cC4;cC4;cC4;cC4;cC4;cC4;cC4;cC4;cC4;cC4;cC4;cC4-keoO)նVVZ:e2K׾/(QMe.umeiJVeh8hLNȖ*Ӳ;+BZ1h.Z >ooUucorZr_�i=�_!._it ]t�oʖn~*;�Sÿ7B|캕hڽƭ|bw'|b K1؝SVsyADqyA1Eaÿ7B|9G#rxyeXyeXyeXyeXyeXyeXyeXyeXyeXyeXyeXyeXyeXyeXyeXyeXyeXyeXyeXyeXyeXyeXyeXyeXyeXyeXyeXyeX:$\�!����������!@A1Q�?&I~1׍MUMVlݦfr�X1c1c1c1�#���������!1@ 0A�?J%DJ%(((((,rX|~垙L52()EYeYeYeYeYf'3xcwغe]2AAAAA]2wغezL]}˾.LǦ]c.1|Kfњ3Fh4fњ3Fh4fњ3Fh4fњ1`�N�  ���!132"4AQaq#5CBs PRbr$@DStc0u��?RNTUs}Ǔ'7No<|y9s}Ǔ'7No<|y9s}Ǔ'7No<|y9s}Ǔ'7No<|y9s}Ǔ'7No<|y9s}Ǔ'7No<|y9s}Ǔ'7G鉏S/O�§:~(SD./r �R5KzsMeNU)L]sjuCj[揦 KJ&^hvUq' al+Ɣ-U |ZS-CD-KΨCjQ�WNB `u-DU4ʘY@S!%ðT3p6*"v5lۿT)>ЂxikYѯ�{�%ºyH_Ҽ�ΓOW{(,A)YKu <!9j�94%q ̉BMB!tGg!\8Uz*v֜xP`L]C]ŕJΛ}M\%vHgݥ>_tWU"r呆i�oeփhpP\HHa4mPL«N>բ 4[8]m»EJ*HvxESB(UV+Kn!. R= x sJVbW�ӃH!̯Ib`C-6i~�ycRJ>c5(ԣ;RJ>c5(netjQѩGwF1|tjQѩGwF1|tjQѩGwF1|tjQѩGwF1|tjQѩGwF1|tjQѩGwF1|tjQѩGwF1|tjQѩGwF1|tjQѩGwF1|tjQѩGwF1|tjQѩGwF1|tjQЦjaIQJr8n;Eв mj&ڄ�?\=7=5V?G)M#ѥsվVT-wBBee ɵB)ĬꂗiQ]!fӉTTHhK!z$Vs7,ꂕhLܢ@W4+B5 A?eqlwdц[ ݒF%n7vJn앺0+taVwdц[ ݒF%n7vJn앺0+taVwdц[ ݒF%n7vJn앺0+taVwdц[ ݒF%n7vJn앺0+taVwdц[ ݒF%n7vJn앺0+taVwdц[ ݒF%n7vJ�`u9toRg'�"@-m:AZ_wGYK LT 7o7[j}d1P\n\eg\R4A\onese&l%A@]ngxW`u9toW`u9to�ǩu.r5pz3hKBTֱ2H{) ]hY4"y*6W*љ8R) zj=3l>+b$e- c3tqfq838~n?L7Gg3tqfq838~n?L7Gg3tqfq838~n?L7Gg3tqfq838~n?L7Gg3tqfq838~n?L7GgB'^с\!G?FXmJeM%|/m +B^JE\ÝnyMl]d*8ͩt-RYSU:mDwݘ(e(m.Ik!.ַwD6 BVxD(֐,Mݰ4R\ڴ2g={FSpzH�1�eNIl`#f"HH@L|(G>Q|(G>Q|(G>Q|(G>Q|(G>QLBzN{o"{CzN{o"{CzN{o"I"B111111111111111111111111111111111111111111111111111111Ej=7YǶ)Mڵ*ʶV? 2[ ZB]R!iI'NpO48SR[HZppRD>l7ImzVq 6jJ|/OqQIB SA| :6Yo$\6 Ei�>aTz=r;t^sM Z-N_J<ttwQiaٙ~6OҧPH%>L;ES-jҲ ׄ:mNO8醩+p3Y$f<!+SkBJc+_M  5-t搄DT@ V6>3y4\pV5)ۢQKKy�[n#!Jg@Z[CӬ9:aAJ)�@Ƕ5lk={cXƱcǶ5lk={cXƱcǶ5lk={cXƱcǶ5lk={cXƱLu9t@"`we/5& N\tOmIҋ' =IInM!D6�dj,4$N!Icw[} n rwOD'dSJC̈́ '\[¨uǒ\Te)Y|}R"Fʚ;i?1Bh[Tt) v)WE~RrQ)6Uxx-Lӥ8Ql@VxWIKYza#P_tR)eJ! hζtJqj$RPؙ[|Yjh!h"KQA"}IJ-UxAUctS#G6[He+$JBK'[Sn⦷gWĩۿSZS]tR)JEU6B %oNAxJb] QIdTî;X*l"%lw_ujdZ=LqQoOl`F [1-l`F [1-l`F [1-l`F [1-l`F [1-l`F [1-l`F [1-l`F [1 j=7 b==j=7 b==j=7 b=QhqLf�|HW\ஆPIq#Ik&h)Zy%AZ4-JMTeX\gg1憨 m.!JI)nQpai)BKS%}/ EcM<MH(uN#LtfN='%Yܿ}ףQ- \s,mfqEKN~+K9_B۟"Dr \($.\ }{y`QG. žd R(2.OtrHU�(SJjG1思? r* fD" w,PhO%|?P)]dE!me4�<8 F*MѬˉu5rQ":¾p0vU�(<V>Cm[|Fnr) оh]èT%8<)3+$qhHҍS.U8�J�EJ)y׊‚j+Rdg T I˦\*J_[\\Bl]E,&j\@ hBԵGR#bl9TohK)+E$m))̐P]óq֕ǚ7de|,etKŕQM%TpBti3HҊfB*%e Jvt<JM} ҉^gUH-j В![G.�!K- 'ISTvadiIP,,'2�}*QQ,}V6m{FSpzH�1T<JHhrt((KY#UCо㔎Y[@a�\O<)iZ� 啝p4*@}P@c~Qۥ-fPJL6ZVە* 'rJug%KhH"6ZJ3U_kpEjRi==#]Ie$.Pzc6Һ"r}%,� M$Um櫢ixLd8xE)E3�J[\%$(B*E#CGҝ�BQV_QܣқK.2T\PY%hô)qI HIg`ϖfs›XpV_ԝQZjROH+44ΩIlhq<y!+"AAmv8{"JjY5ֶ)^SK|)3JRҰ)J**n <_>Z$8߂]䍶$G(<S<BGgF 2<�gdQҐrKmUNk a²8p<3|C!.~nK/ݤ!&Tꪵzj!,#L4\5䷝4#X7jBsrxS&)mh� Vڄ}ÖBXSuUW@% <QHT'- *- [+jN/$ޯCxTѕG;�-uiJWpA=j=7 b==j=7 b==j=7"cQr+hr+hr+hr+hr+hr+hr+hr+hr+hr+hr+hr+hr+hr+hr+hr+hr+hr+hr+hr+hr+hr+hr+hr+hr+hr+hr+h u9tB-l?lEz9}mhiyVS +,r ]8MbBVzªp㘴LlQs(ّ-'J'5$.$tƃ+R”A&Ɵ(psHk!V_8)ZSI R˭N]qSI y"5@MyGFP@ Q"ԥ _E0UPp‰fy,!|'x)B"r VBbd&cVdfNVdfNVdfNVdfNVdfNVdfNVdfNVdfNVdfNVdfNVdfNVdfNVdfNVdfNVdfNVdfNVdfNVdfNVdfNVdJ=2\!G> a<A-0AEzD*rI4fJ�Fo+4 芔:ZMv&h ѮiP]QJ8A\9 Rk)Z\Z␫tB U)!*!]ZZ<'D JHj+s|lP]mN)-rJXE@)KQR9%9;]P(+L sxRփ!"VR)D]J$H%"@ W`u9toI} ҹ HzuV(4DHsFX']dya,ӝoJQ27ՔNqrwS�"KJJMYKZbRȥSځBA|NS^aejAJj?9qu95VO)m/6!e$u :m <-ji%J mFRQO7:MP .\[JEu}ʟ''8kR %uWx 6c Ю^&9n% ViR2ꪾhRU�eZ}x^u1G8<Gφ�]m-IYR/G<RԞ RJȲI6MU*cMkAU�(\"SP94KuЭZ#(vΕ.(ձBVkrs¨3UT�d ZLǖ۩}lI -z"vjoy-$4 ]S^S7U %BiKi킶ȅ$I= ?^с\!G>Kcy�pmTہ^IȦg", uhPIunygQP5O]3\lC>.ax3G(M Z4&&%`8)S2)Sz&jA@j3r<1׃(.TUI'F,lx:[M6 L.H(Y`p,9_:R (^E1kPkȋ9y⒐-)b"ϝ�ôsIKlhI[@UԚ؍!Q�(-.V'0@gGɡ pUGrsw0jye!- 񭥄տF�O44d%HLpKk)jnkD;s20)p_M@%) H8&f/45!A8 -pDNB'o,i thH k`H ]h|)$09/qq%"8ft SN!jYcA>أhi!iJLm+q/HL`#zN{o"{CzN{o"0z g? y51泟<sǚ~Yk9cg? y51泟<sǚ~Yk9cg? y51泟<sǚ~Yk9cg? y51泟<sǚ~Yk9cg? y51泟<sǚ~Yk9cg? y51泟<sǚ~Yk9cg? y51泟<sǚ~H$iN{o# v1c0la;c v1c0la;c v1c0la;c v1c0la;c v1c0la;c v1cѤ$ s.S~ GVS|sRex ymGӨek5E e_,g鲂+(&979<!eeECpmG*CS2ֶuun;_H-ƕ(}%d$J \[N.KK85Rg Tp*|J~6@iqUYK>Hzͻnr\m4ZQjmW*lJۢU$ $Zd<[^ZKVT<&kPۿ{g/ 7�=7M\Lc71fF3yьho4c71fF3yьhu$R 2+y(搁$eXPHT]%T' !BJtJq+jDҔQENA>30!"BR]pUQy F駱JM!BBD`:<4$)!#"95Y+}LMb\;3-a`W\c71fF3yьho4c71fF3yьh8EǧSpzH"yTcYوqVvb8;1U*Ggf#YوqVvb8;1U*Ggf#YوqVvb8;1U*Ggf#YوqVvb8;1U*Ggf#YوqVvb8;1U*Ggf#YوqVvbFh(Z@!\?"o8TF{!!Z4$yPd <]p&S+@�ƪ{#U=Cs4@J{#U=F$LB@+U!BqOd$+F$/1OdRZgOiV tk(|Qמ[h<��\6y8d'HQȚIPy?>f6 zGZ֪;dFdN{o#a|$KMa$S{IqTiHBt 3[CiR["IM sYa+zDGsWP+QHu$@>uZ^xNICXs2ID@lT5q*-hק#MWkZ &d@ҚOƜ[vbBG5�ǽnk(6tVJFb@]Uߴ6UXY:f.@ #Be"� }d}ét=MZCn> G4qLqL4]dG&8c&8`)�IEa1a1a1a1I`0pHq`wGtq`wGt<))dȏ?7쏸u9t#tJPM`YhHOh>#ԌCR1}H>#ԌCR1}H>#ԌCR1}H>#ԌCR1}H>#ԌCR1}H>#ԌCR1}H>#ԌCR1}H>#ԌCR1}H>#ԌCR1}H>#ԌCR1}H>#ԌCR1}H>#ԌCR1}H>#ԌCR1}H>#ԌCR1}HRVUPiIOx�+�������!1qAQaP 0@`��?!AIo|+9_)NWrS򜯔|+9_)NWrS򜯔|+9_)NWrS򜯔|+9_)NWrS򜯔|+9_)NWrS򜯔|+9_)NWrS򜯔|+9_)NW 5^TE6\7RdON1e^ ΒC` +*} 4alj;i )b�B'Q)]+V kA!ztԁj؇^/FZ6Md6Md6Md6Md6Md6Md6Md6Md6Md6Md0P ʵiue8b3ѰņwA4z:&o K(jsn2g]}%:WW_hƕ [#nPkԭIVp=+~4,{UAHt 7EJQ% mfٶmfٲl&ɲl&ɲl&ɲl&ɲl&ɲl&ɲl&ɲl&ɲ_X تId鏛eoxultF۶lٳfV^ӳf͛6lٳf۷nݻv۷nݻv۷nݻv۷nݻv۴OD Mr<xVVo@]y -Wdu[]_kZ&d2qp5Cڶ=YgT1j~4C6]]ƈ#UF 硲oΘpW?N(((((((((((VG�xAneCQ=4e\YJ[l̪"9Fmgqd.E^:1NoEBGF�Y)L74xoHM?tjp^.z5.A &^�GmZ^Z nҖRatܗ3~ 0` 0` 0` 0` 0`#H2C;Ǡ4Vg c ^a͌:N)4pϴە._PiIUҺqCMIѫ_:oV@2Of]3w;w7ynyw;w7ynyw;w7ynyw;w7ynyw;w7ynyʣ]ǣ|xo8RO <*xTS§O <*xTS§O <*xTS§O <*xTS§O <*xTS§O <*xTS§O <*xTQ:xڷs5˴�/P''w>ʙ+b YcX,Bt$˗B=\l'_ Ӷ~fe=ޣ;iY̭!Qp1N2�Nz[,4FF6zQ}X2ƩkM?b Xk9t\ Sxk:H}rP\g0b*^ 5 FN۳m: �@s9s9s9s9Z/W960-16W Q=:V-iZJaRC[l 5vNURVcVZkЈFт&\TJryh] 2 Cȝq1rt]_t k\Ռi5/?o&=tgX;GCkCPJ@U㲅E CT*5[ش^߉Кˌ\c՜  m".u:zr3q pyv*}=si}=si}=si}=si}=si}=si}=si}=� A�ǣ|xoT#q ު�^fH@T gaIX4L$Ӌjsmu;VɒzTm r\ 3MhY̊u;w Bv[hUC@J�˸P;+,TpP4F騇Lr2:Kp;RM신~Z 0ҥFA1bN]A'X IJjٸkܘiXRǢ=@N�nd2 Eih-B j 6` (4 B- 16z5ZUk|ЋkGVez]`[59�۷b#)頲E@[)CVIʬUKagDf+qeP LL5R\5K#|SZ5B}lW⢢k& a&+: n8 Ψ:UJG&=Gq Qe;#y Y_a,$.R4 �@ZѯK@ OCNz s9wc7O/4-2֦h,h.jQ"([U~0!tMqս32.k7A7ZHqeKIixEaOYLB5=% ,]oM1 [ /sԦ:!?'t JɃB_?sq%uο :@K(W&]Ѱ[X;VUs1M}] pR"k Z!TXaOJ-(0x&,h`=c� :ޛe5U02% W_gZS4҇Oo"G sjBq 5D#wm;sa^|xoFL^jիVZjիVZjիVZjիVZjիVZjիVZjիVϧQk_W=]-Vw):WwxJ96ӿ^Ӡtjiע2:F)t7X s/*+Ub-dױazQ TTUjU1N,'LPHڃJYXqan44\1 %{K=H.\r˗.\r˗.\r˗.\r˗.\rj�e(BHvkՂuW0YBԙp `4=5$=,4@!h`iyt7Kt4ju -,ŢG@͊F4[?/tu^ 4f$F&6sRX1mNpʱ N`4nCo[Q ցK KM])S-8iߖ"EJrIժd RD.dQT\.'[U*E M]hWsA ibElkLjn;]eEIbE^T7G-:DѵM-BNF9plJ +Qhڦl%,Z#0V=LC(�t QaFl)y 0XQUr.j\ufLô,Vdpa-ZdeSWKS"H kAUpPrh�vwJ @h?]PkfYCҎPAf.j*` E�t)(vI@@L6 Nt] maqZ٥h"ȮbfAFv�M%dC 1oXs~spnbFb٥dЪ=;VӦV�tCqYLŻ ǒu- Fe5(%,ykh ;dLՄY"Ȳ)z˗[4n3E\N%ƁZ$aEkBwǏFUhһeWl]UvʮU*eWl]UvʮU*eWl]UvʮU*eWl]UvʮU*eWl]UvʮU*eWl]UvʮU*eWl]Uvʵk;�<|Xry'O8q<y'O8q<yI'O8q<y'O8q<y'O8q<y'O8 �lx�qO�7P¢hp(`VC6VPWZͼ$S*Q z0iQ \`-E Ē/VX{AE�ӛC@_$bTM @,D`Q(`퍤/]GOEiACP- 7e(�Y3g#<Fx3g#<Fxơ?�L1\/t%ŝ %}`!zs6IBVsuYGuq]vqtre}]%L%\/A`:4MELL1-�3g#<Fx3g#<Fxh֏Lӎ{N98ӎ{N98ӎ{N98ӎ{N98ӎ{N98ӎ{N98ӎ{N98ӎ{N98ӎ{N98ӎ{N98ӎ{N98PA#OcpFz�N_sĀԴwh_1<H-COfcXS �/9FCJ?/9pf0%쳮O̿�1<H KGv2�ӗҥ�6NH^Wt<4Z1ܮd;FTPG`W�lx�Kֱf=gM+xL" j !-x$ZT4]Wdc H4UQUS <u&4U0ĹEij.ֿcFlPJtLƠ@`#z�:<{Zlvqgi;8ĶzjJyg-===vq c 9u�)S|O=k<y/9ԩRJ*WҥJ*TRJv%;NħbS)ؔJv?:^VCyyyyyyyyyyyyyy珘ekt3?� �����M ��������������;Ђ(,,,  {t<<<<<8����������������� �7-0 0 0 0 0/���{qqqqqqvݿӍ����������� ������������������/?�B6ï5\= �������������������}}�������������� ?s<�<���������/ }=�����������<<O<<<<��1q]w}Uqq�[�4M4M4Î8 8!Oo��������z~=s<<< 0 0<9�(����������!1@AaQ q�?^&u�Țy!i;z)JR)JR)DxD}s- ʚ-ƼsuQ5({?>jMt%!$]rjMxQz & n=pV#bE*zae\ǡk-}U\F= _U)JR)JR)JRB1Z= \ǡk|k-scеzB1Z= \ǡ!AAAAAA4?�(���������!Q1qAa @`0�?O~�WϏ mn+몿Lm1_>C$9&to.ϒ.ϒ.ϒ.ϒ.ϒ.ϒ.ϒ.ϒ.ϒ.ϑJo]u(=;>YWJ1Y3TYi_"dǍqS/Gr;܎w#Gr;܎w#GrM(.0Dh2dɓ&L2dɓ&L2d]~y!AAAA@~5P~ӛlP7CTJ}_bEz+^WEz+^WEz+}]>"""""""""#x<}x<O*)P***=˳?������E�*�������!1AQqPa 0@��?놶Dv-V P}]u]u]u]u]u]u]u]u]u]u]u]u]uZsR jT&_6vQ5i]@C%RhA hHeJ{DK}M�Xq)!)]:%uUKThhCA Pan*5�KmЍ bQzbj.B=Qj@*3(KH@D�{OCz===================i{OCz==i{OCz==aJG%p j 7vT*Ci}$[E.x5z-59Ҫid\Po�&`]>jEEʢ-j]:EwE\Fʥۧ#!v]P)\ZPui06�4lqW}D mH ~%K/[ n%Kp-[ n%Kp-[ n%Kp-[ n%Kp-["ezAlRn0(D2Zԇa^"ڐ wqf͛6kAr/۳f͛6lٳf4hѣF4hѣF4hѣF4hѣF2: *1<Mi[o> �U AE5 @;JF@* t'2NUiat~P8`ƐtMll ePɏ뿢Ge-yk^Zז-yk^Zז-yk^Zז-yk^Zז-yk^Zז-yk^X**I NWϵ:D�+ J$".Gh`nDȧ27V,W-:mE($lRS.\r˗.\r˗.\r˗.\r˗.\r˗.\rϟkuϵ:7*j(E'\.*dXD�j0!�[IjŖ9bPSB1vHwS]ӇW.\r˗.\r˗.\r˗.\r˗.\rˉ4 b+Dϵ:F!�8;ʭ|+&_ M{YFs/TC$UH,˸CBMih.V 2lSjh޻Dϵ:y1]сLOŇK69:]{M;"vD'dNȝ;"vD'dNȝ;"vD'dNȝ;"vD'dNȝ;"vD'dNȜ Rg_|\g>|LX۷_f6ͯm3k_f6ͯm3k_f6ͯm3k_f6ͯm3k_f6ͯm3k_f6ͯm3k_f69}_>)',+�+\tbB R޸jKADPƠru#JlҔS� + QD:Iu'BRY5wSΉ,hLz ) {_JBSSQ~w*G4R`ې wѦWGv֠EPT]T%Q^ \&W4wpڬÛ�-D0.#h)DVHdrϙ>g,rϙ>g,rϙ>g,rϙ>g,rϙ>g,rϙ>g,rϙ>g,rϙ>g,|D'HڙF])A<ʤugEs@HbIIhBEċ9kNS $j,.֨+\fF!PTH%62 p{<("b\vhr AC&l*ZCV/V(lQw`8%Ӂ0$V1LaX@|T3hs.ŲZA3GT5AFS=�ȳ@-Ҿbmk6ʄ7y^*Z?^zׯ^zׯ^zׯ^z @|\g>}YuϟkuN OPR e⟈EU p0 Fl$BI6E¼M;bk��AP|՜puRnWukrhj^HRAP-65cuVma<�YBL@;'{ƆQ`$Kh  Y4C 3ZH-vB4 xB\0^ "2EVzQ `9Xpv' ܀{[$>!�Z SM+15`':A}\y,,B昄ºz  Mf&HiR!? �() Z��`8J- 4 rXf׆u.˖K EV(*Zx d:#j!4x�iǞ(0(T3(ZյA nO|PZ2C2&.`'+ 0kC>}Y: {gdB<HDR\9C Fz91.6�#nwW$byJ8 O2BL@PduB+ z!" "_`;~fS v]մ*G�KQ֮O9A Cbpt&ŅZkWL[ѧ`$M}ia:t{]R]u,3~ ʁtG�a#yS9nz92d.:c8B(%E"q|9 G-S,U_ L]bJMA"6!lh|0|Ptv@�!tQTH/^�7R ܪ)3 `E@Q,k|Wd W'!u}Гۧ )]Y5�ZL F[U$8,f QH`dk$ xNn}Xw@ åz (ܵXN|\g>}Y3>� A4~߿~߿~߿~߿~߿~߿~R9z_>09" uCڑV5 lt4AgF!$2T7P9P!Dݓa썥Eыۧ­*QUYPHRv{�]MSK`BP E3T`@,Χ&- SH\k 4Q \i3xg tNCϟ>|ϟ>|ϟ>|ϟ>|ϟ>|^B ˑJ@4[kɈGl�y @F)BB{=J*^T*AP!@ g f ܨruܘ68A0 u#Ұ a&ehEfqZy T.0��`|\aC7 4X!uV-LX" (�; vV�2ۜ#@"w 8Gl`Ut =S#Qe|ӧ@�qN z-h5':1C+ f Vx2-^VFkl0 ½sLK(@6D5W1b ½sL3Nk ښMYX1 ҳVJ~aEWuwaUI-24La$!9|Z`F2Uyf:1G2 h F?˜gYP:1HDTh 怉ʨ _cH-))U㒵6Ew*ZCj7ݏEb 49%d:eꙀBTlB!`z5z|pLepWLe†`aZKP?}i2TuưUrYЪ+Eի+6<Zu^LL<銆3`ڊsfdPyhvQaD" 5D1SQ8dCSCPB [!#ib΅*c@T#:Fm0g_|du߿~߿~߿~߿~߿~߿~߿~- SCAB|ͳm3lg>f6ϙ|ͳm3lg>f(k?o6ϙ|ͳm3lg̷w̕l�ٶ|ͳm3lg>f6ϙ|ͳm3lg>f6ϙ|* iei?q퟿VGeRb4B-2kdڡj#14oEd{$O.D Y)EV"ܨN)wnx_S-LRCu+&"m �qW!k YQqʑ&!y3I%(sd۷_>| CKi|ͳm3lg>f6ϙ|ͳm3lg>f.0BM\Y\cM` c^B A;a.>XH[+ /u�tvR kɝf%�P�teʶGCiq` c^0+%F/! ҍ A6ϙ|ͳm3lg>f6ϙ|ͳm3lg>a*r?uc0-H"D$H"D$H"D$H"D$H"D$H"?; &JJ9yxCPMqm!]Hv965~Q:.Mo/(7 VM \T#i@ Z7D5 4f7o X]/d�,?Dq ,ܨuzB,uD)$j Pga(F]eb lWl�Tr;)Q5-Ƶ낊K4e =C>� `/ %Fl<jv� Ru>N L#O�1&bP:d]jj*,8[bUjU )M9tI|'W+�_ m (5U|'W\?i@+'8[LU=givvWq_ ,a~]\^ JKׯU)rP4?~z--͋`|BS)ؔJv%;Nħb�t%;NħbS)ؔJv%;TT' 8INp$ W3Fxyl 8p(QG 8p(QG 8p(QG 8p(QG 8p(QG 8p(QG 8p(QA3Fz5l���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������krb5-1.16/src/windows/leash/htmlhelp/Images/Options_Menu_Tiny.png�����������������������������������0000644�0007046�0000145�00000016244�13211554426�024734� 0����������������������������������������������������������������������������������������������������ustar �ghudson�������������������������libuuid����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������PNG  ��� IHDR������,���lg���sRGB����gAMA�� a��� pHYs����+��9IDATx^\xT~l*I�]QQRHQ J\E.AB,�BGzOPBM I usv7 E/\y8s7}ʊN'*C%YR YYQTjd">*y[+ڃ*޲<]Z=~fBS(dhԈ>{^ɸz i~/BRmbVWYs?Z;O|]TZ?91�DN-?&A'qɡe~;2. 5CX;ڵiVSv cnj/[BrxW),ËM1vD坝%.rd:Mx c"ێ[.Aɸ"O/M>"WGILY5iKY9ZK,Q1mM9I idxy U>.|cD1mz),ugKq E?P~B+oٌdǃaYrO߻1;nb#eNQCк z-l-Nc[pP*Zbؤs~G�e5 aA8grby?yQʈɰ3=%c; t۸pPvA~Q,;*9+[(^nFù"ϰx%hTBd<| I lL|PI_!7zbM1]Bę\x!0~6 F~?xYpj:;Z+2;"gÆ>Zs~p:]fZ$\y}$~O<,8,~WL)P?c~@*5܏S0gEת(MOuPdB%\3aZ~&?ztj�kb IgF<p-CLhʹ`ϱhi<5gacxޚ"bz\ҴI:splX>?ݪ!JMHj33_&ѧ4`ҬxcNa_DJ匜VMEvaib51K$ƠBAT_?^[}{5c6w^ 6-G*0}Ъ7 ~0K 0 [`닠8_&V>z kc' E18 "`?HZ$w鍀[-fԭ#q=akIM&5 3:G{VLA#mLW*WșD~5jcr9{\۸T%E>RZ &ܔL;| 'ťWN:F']be9`̢ mhVˈ9uDu\wzBA4+KӠf;7.|[} o8kO;Gg&1_LlE!wNy Tpౖ�J| ܈%PEE`~@ LӰԩtz9%2rlTz<fOC.WAFh*+W_WFb^B[~0~=vs#ynkd%j ԘjUt: j7 uG080wνZQtx<{%x?KN0jC-knĮ"L9CF  6a<>Ա;rę} S_9.tt ό@U^񾳾/q>f%CvZ5إ P=*5\tF5-[@Fqh:t{t# ! ~:?a`Z޾BZ_:fR?=ѹ1>-Jtݖ}dy%P*q5"R$OCm!?!Qb}Zoo% jAU("5- [6IR?)AEmP`qKy42Xu'9~Ąʲ #@4'bu/v(CI10 g`(Hps�Wd\l6O9Bd FuC|3O@R9ɢE½iebW1pb䔶N`ec~p*BwÆش*Xh[B'^<eIX 3YZnJIoTXbZ >> B^^ٷ{ ka[-_-ֽ}vs(._EV%<ZNjVٞd7-Rnp1JbU~[aa@+HoP{.޲.MR} ނRFx䔨ī0|w*P,\pv봕܅&J5NrB&W@ͅMxci}I3WPwP2m ]?JXi'Z ©g5[EGPW* ?'K;&νOMX> 8hdѴ,rE"9_W+ E\lȄf[@koA<qE#@C*ٓאun8PVsVGL%#(Y\Bٽc{/Hޘ$d<BJz=Gyjdyj\>|2tjZ<Rӻ뢞֖`G؏~TwLRv:H].'QWقKva(hݺ5{-7CѮmV #HB]={�׋X7%ޤW"[)F8d&"@šr'OǩG+Ӊ4yd.Lu*ߓ^l5]*3ٹ.zHB ^5^z 'B |O121zCErD愣XW}58{& .Hy11m156qhDL [!_FMS1GƎ!/PG<.ł&r ~5_(? v-Ks{aωt桠PPhtX<$tP#*#FQqyt)s\(k+6K@􆅸'C,f~8(<|cY>UwB2x P !uŊA(Gj>ktȸtr nZ0egڕ\NʦPk`ιc$\Dgf8z &AɾWG` l�YM:U2MtU$يG^ϧBDF |\W۰poћjlAʟ_1Q>8/VB �o,|΍ФĠ)%v%*e'dG; tkW3>8Gbӎ|$!>l.VL)uK wPv }[= a>2fLh m_ ~yW㓏fp:#ܚCqExGKY5}WhP3'1}n:& Eב+i/sWJmF(eC�_fΌH\7\ƒx L)4!5f a3O0MqG!9ck`-+pS[v^"l䣫d񇟟/]@\|燪uq>:Kۀ”:#bDPDn`Psn G!R:[MU:pQB͑Ka2zyq:we`*Wl^2[yURv^NV3O'QϦx,}:&nSa폩^D!QTTH-I¥F].C>=qjt ~1"OӋm!_R=1s崃N>뱦i<Y;oh?ގ+<f}>eNC#<ׯ;b!�;qW.rzuFMhP$ ,Af6̕`.;t7iSFv g\.WE~S_& " չ, l7H(hؼ.}ZFm &%s*q-VsNp\RXBo<&5VG|J>):=R^n۫ 7jT ԡq`=שD);~4悫SaL_IkkdUTǶ}qS^잏uz罉;"5׆>4\=j ۠]^[-M4_N3k >G~%b7av~m*4P ?}.y~4-:PˎŤ_5k~S>u]Z[|L\ _~!}|4/{ѩU4ή@0ԬPX-5 a?<hh9"V╷Y?}o{aV:qJvi*q/;,zCu|lj`Y ~mPCeD, 7Ӏٴn'#˫J5W vYcȐXmzC\Ȯ#ȾLa=2sj&¸|>7K7v Kd:T 2Z9?ozsQpqs@ _sI>+0^j[lr3aYx8s0$өPM!=M.K Tw cS`ʷANQ,T$?i|GM.Aۂh:Q"'7jTHȓgBV@KeߙO;\upLP9TEh)j'p 2vaesdjݶ>@+! 6 0w#H8鶐s-we(HYiIo AK2iYȀ$1J#XBnr6ju ԃނF5SX*Z4`y0QP `ܓ7,!C+C%Y|k <(dieB%᫺: *C%,έiw s3%KA n]vv327iw[):44{$˳ߔ'i +LcwWU4,-<?i(& a\|:<JD0"juԪU \ I )Q.i$.Ʉx/hp B/^*KN!@]Ʃ3px2]P#EYi0sU>-kH8}GCC;B`]iyƊt[؜)][)~ϥXz%DrnH|v=$Jd_qWpց z($6V>o=?l3ȹHx y57S>K_{sGcqIHmyX2yl<aROo!8R (㣏jP#쵾R4tM0n4^Zq_A@w N yHvRkܞY(H{dAF^>o4F-MfS;rE^v= 47|HW5isaswBo|cnhda(7 ,|1Tk,}8E`ʌgc/S1= 9p=36,F09\aGIx=)f#| kP"7i %{ZR]T0~)!:{^+p˗0^C_D'iovW6M |雬oT߯>?n N & F2z _ri:&.?E" <ƣ#Y}К h <Kbw1Zt-:E q'Ŋx{gĜ6mۡoF<wCK s >y m\уoZOdIŢX3b>hԤ)@7 X_z xx?x  •L;ꅷ?zzz$;MFh~<~]sgY ~+z&G$μII#TZ{/u/cf5@1!MWax%d2jNxڛĩ8 Lϰ/ SvG_Bu?#;*}Dn.kɆQ<[ :LJnЙcx~ʻ8<q<jOhu[DnÏ M~O̓+tJѽ kECC-_AhI֨ W?oUTr~}PgNnr-9l,% ^J#d*qK]: X1^nGOmyA(A~O?%iB4ߋ6NE[m {9nt Om<f+`<{wo*`U*9.hE`c .ڪ1" +=|wRۃ<KT9jѐ LesEܢ*s(>(-l矆@P.h4s+MqAm<ݑvR&|c\W\X%B_t9 3~!;w;b (% ݵ׬je"A\BR3o[lb <U1ťV/JrHnG>}PwꈝI;`oN~Hؽ-%4͟o˪!Z:^}76.DNOA{_1 ~ C2ډc(:umtsq<U_ꊌR 5R4<#М&TP\+Pswv}VF&w=ܴKXh)C{ ؐ<6Ɵۿ-="̌<28V\]q{+YDL5kxr.o=erhqS;9QyBY}_ kE **�wow-*}# _1W Ue{E�\:E����IENDB`������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������krb5-1.16/src/windows/leash/htmlhelp/Images/Get_Ticket.PNG������������������������������������������0000644�0007046�0000145�00000003770�13211554426�023174� 0����������������������������������������������������������������������������������������������������ustar �ghudson�������������������������libuuid����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������PNG  ��� IHDR���/���M���6=���sRGB����gAMA�� a��� pHYs����od��IDAThCWW?cJX"KY@BS퇶 GM!  uE=|h{<TUe!nm}Ihg&vzp`}wٞJ~(Ul*F{*6HJ7 N4֌ʗmfMs`�Y'2K쓛١OB =tKMOV@/Fڡ(n؀x݃(\lGfU&*JV!g#&6, ;vcj^۟p:(*e d5JAN5'"tGbE"hELQ$nCwݠןZG'"lZBpaX$7!P(XlD=h WŠ$X|H8,D 0_# L"qw_UK𮨍_w2 i' >A�OMi_fVF X\o`, ̷% |,8׏ STPr6/E\e8{6i_gS07[н:k0e;Xo).wub`w\cIU(*W)*8]yr#|V(3GZO* i-uS%$xAo<87g"pu&Wx^_NCx- vMAp~YSHQ[?Wsp{;\ٴɵ0 e8�(AE}W0dpzIYO!Vu F@ q9S] $!6ox@e:T[':T6=$y Gtrvk5  u'yT 4!BQ}>4jxM_w /ujhGV#LsL~?Lf0:n &px|1E� -j4:65@"UxK,a ‚::auV[=5*F_h }7!9im] M&NZ4M@陘]c&/0Uj>nGЛ\="k:i2 $0aVUJ#fX = EV]G,'x jF拘!ӓKV8k(UuW$#O|o֟І4#,H�7 m0?`M,G6dE� "&' ayA~^byحǐ!t�^k鰌:GE%Oowan1ϲ*f==s6λ4XK {Ab^R6Mr]b7BE ^bmTWo#]Ps{t}|ǐمٍ;6ցtNEv,]Qd :J1u{ohqiy\y8- I u4]t;=ߑ{zc]{":r}dڎLAtDƻfTXs_Q\oya~1ksf&|9aNr ,S -q,$ž_^Ÿ ]yJ.gNȆZMgnC?ż1]K"W5~V+y.R+y _XxylZ>־{Rߔۜ7}: stcc*ȷ_; dxcߪ/ k~'.Xs57oX'P΋um̈́2]1ȋI)ʼ29z{R7YS ,����IENDB`��������krb5-1.16/src/windows/leash/htmlhelp/Images/Leash_systray_menu.jpg����������������������������������0000644�0007046�0000145�00000037024�13211554426�025163� 0����������������������������������������������������������������������������������������������������ustar �ghudson�������������������������libuuid�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������JFIF��x�x���C�     �C   ��"������������� �L�� � ���!"1QVW58ATuv#26%Baq34CERbst��������������/�������!1AQaq"2R� ��?�|eq JOKK&Ffde^Lǃ�l/G�p{lMK!1\U"\I3=JYjfD:,cd%Ln"%fٿ#oJ-5N^�O5YoT˽qPKR̂e$j_-]~)]Hgmωoex'ooUS)qe˘n8RD^.?!VTL5t;m.+)%&78�l/4N(:d>nda*LMw] y̏yLg msMs&,iDIJ3""=Đ1Ä?Iv}?AkNdpPhȋU)DEzәEQ%YVAfYWNʝ*b֗ѮjڝO_).eXQ䕸/NEdQ}mJm+רvݘʇeZ7m_L#z#_p*H,_B0*V(?*Yd%Ov̕f[!rZyxf)i2=?=qN3ʲZY. |u%nmN[},3Si>u >m-zT:k}_Cv/ {<sZ-BiQ^*RLxÜ)[s6ln&Iq'-)8U.3YDYeu]!'7v㟈jIQ+ijjSԄ lr z=vƭ (ڊd̉[R%ZQV1%vIs{K^a7 \v ‡2K?kjv,[e-HQ-L 38!+F')*-IEXFF_ se,H\Buĸ\jD,RS$>"hE+2VE0m*YѮڦUDuqӳ3=ZV㸼y*<R%&-H̓FzȆk�l/4E^ys/ ܲWϳ~sK:n^dӴէeTq 򕈘av˓67RҤ'4!\3?[?=$^FGt78:xm:Wr_9hK3⥲QWCOO.;+bce9{ď�l/0/a!�೑$}0/a oDq >FGt78pB L#z#_{8VWıjDYDJQ}}b<޵a}̤:soi.y9Fy{C4JNBq/O$eٳ�qC,5a9 I)BJ[DD^B"Gd?w����������������������������������������/>Z۠_9n,}@lo7q9$J=љCr%ڂ323Zu�1}`~-8ޥ67$KC^B@X5}Y (ac3ɒIm9N\NY ^b -3oc>j?Q~m/1z,g Gj}`~-ڟ1vԵ(>c>j?P3oْKD$R`:[CXϬž_{S!z,g Gj}`~-ړsA Qڇ@X5}NB Z'@X5}t Qڋiy6Ե(>c>j?P3om/1k0P}}`~-,g Gj/ͥ!=KY3oc>j?Q~m/1zp8K)P)VB]iZjCRP*%!D$Ȍ{NH_Gݚz$!)M)nZI$yÆYWUb3[]# ٥_RFJSjS#4Mju5u'|CۼMkkz#q]aaSumwڝYu)?Ȳ~ҟo ��"J$.��@��������������������������������������u[{-}/>Z۠6d7lo$H8ٱԑ w*1H~:qSma·>bإ2MQQ%6Ni8ܾڕt*;LJg*TlDY}!,4i'R>>8qPjJ *$2$IFFd}dzu }q_S~ ̓PMti,8"3#2e&-HC6i~~otFM] ,NJ/ZJݿzF3**uK $%rEBӵX喑l{7+sꈱiM7҄kO-r+=]YWC>(8,+W u)Gbd&C')%9s{̪|L{tt1m꺺֝G[Y<1KUqs߱fE)ݛ]OW ܀W�H7KddnlDH^(HT|HU5E~EGU*+[*#Zur[[$H$-$u9KM䛪>KkYnC(jq)%_^s]`OJQ_(XJTjI4D3-hfgMݿ:_o19]YSf9}DN1hD7%-)ǝ%VI"I%-LDf?#Ͱ|~\m~Y5"_q{I3-P_5'q8+!3x]G,ZUDvZH#I:KQԃJ+Qx&8j)a5e`Ք(lDf֏se ޫJVIVdfi"34M_ui1ۧJ뒭K*tf+%)կ]["\QuqKj>sf-"38+9rYsml,$َ752%+[I Cjj+lbK2b,RT'i$E%m�®}9So:|gmb/R=)I3Aꔞ^`K_jVnwth5{Ia:*'iMF=rg;.Q!SʹL4j4TkT j1wġWE\..޻O4£rԘѬ$n7AQ,tLxD Ȓ!:|ZoQՌ™&qV'Hj:H-ϱ:Hp럵<:" 2ĠS9tYed ?O5D6yyq։ŚHI6k&Ӹă \Ͱ bʻrʆ덛4+id"XY2.uW"QXrȩQ-ehQ4v3?)Sp&o^yYUՕi5DhAhA $Ut㒮2�tvNt���*N,:#X|xd:@ztIj2_h<U:kJMi֒Y1NET.#Z³ I=RfY5v.$^&y/ 8GeXTc3_;"r]e*5 H%ZG1kl9 oERBǚn77stKe%O-T v2"ԒV+%SԽP=WU XʘADjFz"S&jG֢0ǛCNCdN8n4%JS$V~Mǧ'=[1ۘmeU.as}Sbtiz {WjnCCFz҄f25kq!?c%Nez!ůO1nо!<ndU\#nлy59h{J3Ժ2)I%$DZu]qS:kσ9]Wyy8�#?Ȳ~ҟo ��"J$����������������������������������������;_9n,}@;rXknٓ 8ٱԑ �f�RDeh$J³(f!FiZil dM8V{]ZW'‹ȲdDELi%&J[sG-ƛf-WaxĘzCR. qv<WOXR{pv^P[U*G;WᬘkK S/ cJ3B̐3f'^9WmTyo&6(b*->s) V^5ӧ:;l߯vnA΢f80M*;I9)k%0HRRIsP{ϬӑLJedjIDHqt5D}4R-DZ\ aHqk*am{:rPVKly|J4%hde$:޺\D?%Ii /^\YjqeڣiLjJ4+ruNZʾ+,YDɲUD6Hb-!SpIFdo&S[O)UK]i'zwjSY%ԝ ]OML2xq)~dͼ8[5Zr[K=dzSJD=N>d5`9**q+ g`IS)Ѳ#>RЃRH3+x"3+�$ɍ]j'n,[mfm<:uTDK>^Ӛa55]mu2ȅևY5TI4<v!ZqS<:c7b mEm/d$:K=J$D_M{ 3Slv]-(n>I)-2m(M3R Ff+B'q<¯/a؊ۢU7D0*lUTN mFP8 N#utV\.!u:IBC٠KŨtis @":d)bik~$ik"IRxJ;iԺumOaacY*BF3˘M%0Ɔ[T\YLńn^y뻹f+Yc*PҖVE$UW jVVdsdɝT kTⴔ#q([uи˸36,+^z\vy#CI^! -)+S$:KIjYVnwrrw%/.dL̍4!9 DaRӎ'M\BLIm.*B3ԝ9J+lQ.5s:edn\scmR E IomEeLَLC4d$slϜ=ffA[jAC.;g2Kl?m&X<6oաH=5SC}J}I'v2g5u4U:ȟ aiۆ'S=f8.JډGkZn0i$GN%FMy%e LsѕcRHӮ[᭩-YqyIQ!pr7DEy7w_V~C-o""5heffQm&^]_ib ˉ7y3=Yv2òII RMJSk)2"#2QY5pꇈb3wLzhi54 C'EG >wҙ) >C_c:YzKpfIѨٸHyhV(;KY9j0ŗ>rd~Zw6LRԔcgj$6}ϸ=Uu|܆[uV9x>:R~R-&Pٗ Fc2;1_{z{mʹ3д7E׮.}k tʋ8Yv!'C2ʌKI ZٸHJq#C"x\2"OR%7ϸhykQ$Dj2ڟ,>c�r+|:EO8|9W^sG- ON/SiE4UAfty'VzM[%+U F)FZʓ:G]�Y?iOGd?]����������������������������������������/>Z۠_9n,}@loH�qc"@24`r+Y5-r:cuHxeKVB-$GL:76-!QmΦz/gyN"y7RcwiC;6̍'rLee<*)4ۯ㶓R�bfh׫3�AV P#-8ur?mrHԔ Zz_ E=-N)iqKzөE#:#ฬXJ)e$U[P_!=jR�ZJ5LR$Is\553$R$$B"мU[ȩQ])/8nHlmDuڗ5>2u ]vY>4v&\K>FЖI5FI$ZzTRCm>KNL5D"#Dž.LuO-y EQW=4�N%^(b͞b6#R#8mBq-ݤJVhDfzj;ĺ6OWRyByFfZN-}+Ry^t%֓%$҂FFz:=5UUEqKZ6JfBQZuZ\ģI]e>Dv8Z! =9\3NmLD&"* lɉMr)4{ɪLȺĨmN$|� @����������������#?Ȳ~ҟo ��"J$����������������������������������������;_9n,}@;rXknٓ 8ٱԑ �f�RDeh 1Ln|lUÕm mI3^RI1{"sK)gX[.wӑжA8ۉ渤j2QOL{d96KduTs`ܞۭfD *#d>\Ⱥixܲl^osp;!o9 [j"'hכ7$4ⱼ%t'er}Ժ$-ke<2CjI2mhZ+]$vR}d6LY*2MY-2y|51{TSd|d W_™ժ MoR)zِ$4Eeeڿl2xdvXlSM�Ao,ԍђjO0FDdz(㖳]$ U1<J`JP2":N[u4GI|b#./-diVN}Q} $i!os2o^MYY\W{Q6i]5-J58gySlg8;YFMc.K[Ʉ6u-t/R /]iEie_z}ƥPs9J[(q013.tSPQJ=j+3"$~L["}WR e" $@nzJN{E-m% =׻.eҺlJ^rmL&Kk lJ-e)I 6e3dёm߽fdUEC<HZ ֥/nҢQ.[>.O{3't/OKjI><!B^(Z4i4jԃBU_1"dr1xrZ5RXOSDZ%8hCjMᙤ׀d~ Cf3"8qV݊:lFi*oBR2׫ SXҩطD)l5!L/6% <i$NHM�_AF;MsٌRʦigˑqu$Fn=NHf>&d5x~d2c-5uA^yo{If2WZzt1;qqXs6SɪQfIJ71F5Zp;uEryQkS7uLm&tCwT>|q]^/ (C.{қ+ (@/zZ#w%Ɣu3#-s/EL1 �&=R9ɑc6Bd:iiTiyKkJTFbܐm^Sľed_9JJa$K-1F-{ ϩyܞA}'b*kY"eVZخmIxⒷ52sj&Fj՜\y QX`X;pk;+#ZI\*Kde7nGi4Y fgc$ʆG *r_B)6KCjQT4+q'L*:mlZY+dmLex OuZBi8[/f=s!@$Xfi6&3%c[7GFJKC*u>gc=#Iŵܶ+3{S=K q#'JJV!dQw86=1%瘋2wyi^ymť$n!$HmfjZKB-T_h-jauo%FJ-ҔRTdIwn̴3<?nin{%K4G6+iIԢնԓK4djIřOX]jnk~HtSXUNyF?!s%W"M8aħ^sqȶ)*5Y6i$"GqE9oy#fXFzD7>:,ԗI' 4##F21θgvk 6꬟Sc!41%HWZ)iFnS22%ECL ,!J%ni4z\9Ɛalyx} ky72bPmQbmg[Ko^NgO,[Y)! HJt;RBңJOEȪ54_#bvJҴi$q <-Fԟ3B^)QZ>bY=:{ig>zX&Ƅ6Ddg!)5(InRUc;t8rV��B?'),@+����������������������������������������E_{t-ŏ >{I7lo$H]或yV0w+b5QgY-iQPFNBHU8I-TŪN.PFeGϏCZ K-?.=$wUlHuĨϛjVҶ[Q-De&E)1 eY<u;̗j>GRJSIRxĒIQ-eLoN{HwqgE2 V4W%"+i"5-nBHDDZu7<;+f(Ӭj2"m7B2-d}d(߹?.l> yuehqѽK$Fz\C.0욬]iFniqDS)*BȍFI#%I[1-{[\1dok6;V6Q(i`ᒌDzs/b]؏SDiMjQ}zN}}C]|,YHMW۰Zwk*B5vJD mIӬԤ8+y?gfkBr=}/80i%)okK%%j234-4uz'Rg)xӂ_˥-V#s`U5ѽ*K 2s$gAp76U)VcOvɸ)mo 3#"J321Ses.N1_a_&fDfXѪ)V2Gs]:^1'DH?Q`PSΎYY7F^!2$Ӯ$o W7zR ;Ƭ)*Ip6uc5 1P|">K:FFQ"2'(mT6+"d.ݾJ\yimlڌ<Ddㅵ%%w:dpEU"qy6U\[l%ī[ԚRj덵4{8<7KZߎ<?d]Zwvɿ%7LIdzh3XTYAn+X (3A+n v鮅Tpc()8w~QIv3楝ZYL�a;g]fVÜbs6<7fmmfDzj]Zh~xxF`���������������Y?iOGd?]����������������������������������������/>Z۠_9n,}@lYɮqngSF8.FCN5��f�RDeK͉ۇI}؝V5Y[EgNl%ȋrdEYL{ZII22>2@>[lN:Mc西^%;5S]&Bpld_ڭI}z(>[lN:Mc西ĀcS*oy#B9omm]oo_5�X)o;qȪJ6vQ)'sgYhU-FDȺ_|=,Sα=<L5u% 3%G�dh2&RbvkE-�6'n=du(NHk*3cbfRnihn 3.KHR֢BZzIQ"00=&RbvkE-�6'n;mr,4!¶1sTdhzZc,iڶǮ ^պj&DVdzfG'I}؝tK͉ۉ��#&RbvkE-�6'n$iSXT#*F+[SHBSкkE-�6'n&Rbv@��I}؝tK͉ۉ��#&RbvkE-�6'n$��K͉ۏD ɳ%q-]_}kHuJuF`�Y?iOGd?�w����������������������������������������>w{rXknwQ|帱'#3/X&,f1v5"YFՖf,G'w8n(SeQw ns2쒮䭇WRLuK"3"#q3IT�f�RFMYJc7㸥? f9BlmOnҝgWQT8G٩:;˔ζhѭL8'nZީIOȿ`FGgmWyQnwAb#bmônڹήTQe))JG Ț!zggQaʦ`!QvKnx)b#[gjqn.BʄQ}jõ3{푤Ҹ |.CDLLkYl4˧I2va='KDvz%b &V*Q2VE#)I$=FȒHyy"D/+?5- ߂tŘӾ9 ]�׷�=uU^S5CsB--) 2QX.:%݊p4S3A$6`ygCe͖FJpJqj$f}jRfdD-<e5}<wxd~".5\*E-\A N5 ٞ2RP"cD١fKOxjWy.O`SEt TӒpQ6lrZmRM+=n�Ҵt5t*Fu푬{pLz+VU}$k!LsZViQ�Mioiz.ϫ)n;]̙[jYCQ݆o$ӫ1|Bfy�TPߚ,1<blUF=E[L'uuե$ Q5!Y95-ٰ6*CniHU{f+%!;Tf^[ki|MZ꼂QM'!M;>MDJ6Dg.(̌wu9J)d78[Ff3.Ҫ*cpgoQ2ZV[V�Ѝϕz����������OS Y?iOWx�� ��������������������������������������w-ŏu[{-}2~ĸ LS^l,#jT{dI-{.+ѹJg𚕓%`vd"]>7mn)'GRN72icao;!MGm-N8̋rֵ-G5(31SZ{csx#')E*۟ K[B0D3Еשum1RST Iz1Af&h&hI)KSddD_di^]�q a\JTۉ4:Qm5csշYRIMhҊ4dv.!Esʽ`Wӛ (By--K'$hMK#kr ;LH*f4'rX? ژ$dZlAjS4O$6QXcWAaձ$3={avݴzx'Z4Vmc79ȧdJb!%HQSIqpͣ^4/Tf٧٭qv6hwMqyGdD-;!$ _.l/eqLRf9ej䗌wJ,q\od bsB,r`&mQIPHgXC;FI\ct)"TbgDЗ^_o>)5jͬO&,g~%w4 9rUĩYv Ñ\a eF(f(aT#in>K- 9f#q͈Ir*: u(n29O_j"o]"Ay6uO8ֽb<CT�pEU8g]X>Ʈ4 m;Rn-FE}BT8ܟ9iVJ % @qC%9n/9�9n/9�9n/9�9n/9�9n#HE�{xHOS �����������������������������������������qceE_{t̟X?W{ VİVZFn#] !qoH S9S&�|_T*9yF豙ZcJ.K*;JmB"H"qEqCOm,I2^Ea򬦰eGB5aSO2zIY"53x3T cx}/O!9S&�56Ή1⻋9T٥6xfFBj4h)-iOiM7i;.9S&�|_T3$_ʟ7C�rM�� /O!9S&�πK�rM�g%9S&�|_T3>/G*D `|_T?o`>/G*D_ʟ7F|X0?o/O#>,_ʟ7G| >Z%B%v<T!iԴ= R3/�#0 �"J$?')����������������������������������������E_{t-ŏ >{Ia-amyiJE;D_@=wm�xڌЦ;7>=( > N0ĪnMh5FuQUCy="r32SqҤD7[|7ݛ=wm�xڇA뾳oľHQ>m\̯nfkEo^Zo~vnV8JRw+C-LKY_jͿQ[H�G]%z/ @?z/}f}P�}f}t6�KB�6�KCY_jY_jͿP$�#ͿP=wm�xڅ =wm�xڇA뾳oľ( ��A뾳oľ:]%@H�G]%z/ @?z/}f}P Y?iOxjcQLHZJ8jRJ3Rԣ=L�����������������������������������������u[{-}/>Z۠6d߭#(xQpoN�H, . =laD� . =laD� . =laD� . =laD� . =laD� . =laD� . =laD� . =laD� . =laD� . =laD� . =laD� . =laD� . =laD� . =laD� . =laD� . =laD� . =laD� . =laD� . =laD� . =laD� . =laD� . =laD� . =laD� . =laD� . =laD� . =laD� . =laD� . =laD�=Ѷ;c]-{)pi)%hZLI2222= �2������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������krb5-1.16/src/windows/leash/htmlhelp/Images/valid_until.png�����������������������������������������0000644�0007046�0000145�00000002421�13211554426�023614� 0����������������������������������������������������������������������������������������������������ustar �ghudson�������������������������libuuid����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������PNG  ��� IHDR���r������&���sRGB����gAMA�� a��� pHYs����+��IDAThCZkHTYRR*VX}()>08٠C(( /!$`E.T-(+-HX= CUhFqs3sνjW0ww~sQͰk*7q-􇍥?zg>i`KgtC9)aW{t c @1_rE vcbbl.d-/ A>C]}?ׄC\{w2mvďKӗ0ef~9<z/>yK1q$ U풉^E08Zl~*@+!++ Wʉj#lb@)ڶʘeYqC#NdSjWZyFvJLs~i2J+aKr+NB1‘(N)'Ʀ3)TҔ;7)0 ~D,p:$K!Jk镴 [-FS:wd{)0T7m_ԦB*F=pj']ΐ)´T8Fݯ(-g' !c1oxb}5Њ/S^ۛQfY&69l>/\~GDHi!oLo+N8JUZ'[Z/LEPЍdP62()X˕ԄD_J$嵾vog$e#sRlވSG2!N0;QE:<<239vߍ -n‌7U5dB=rFA<7FFJhaĂr!i^�C?_k$NƓIO\ -,gtUܠ6 nk-t^�mԯ/AnFP'Z@X }ĶlX6-G^NN(DI,++4]F/L5@uvPR$L•ya{Pe"=͡4Gz@Ovwj2r1eE@6 m�&@R)5cԛ`i[gZ Վ@t9md�9\,E"{@U/ZA"8t LVZ.2!t;d O3CKf.mH@] �&HJ����IENDB`�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������krb5-1.16/src/windows/leash/htmlhelp/Images/destroy_tickets_on_exit.png�����������������������������0000644�0007046�0000145�00000003316�13211554426�026252� 0����������������������������������������������������������������������������������������������������ustar �ghudson�������������������������libuuid����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������PNG  ��� IHDR���������LZ���sRGB����gAMA�� a��� pHYs����+��cIDAThCYklUf_݊Av)E04llQ@ZH ZHbPKA - 0@ibxE{gfe63Νsw9t;} L!a[Sh;T$1RZR (72N5o^`30^ (C&Q%QWVToOK VۢN/pPivitEQv;v!WUٕzʎ*dϜ qf=`�shxHԷQs`8joLj|=;\nLaUJ.<?X}uD鋞8d7^n匙}I[~ŵ62Ln7Ĵ^/bSåfk)bj f,4c-<?YfG^n`Mgϒ:اqv8j}^$h&jV=4_f2\6i+xU:Pw>6j:bX.4s~V-M>FwiP[W+l/cͅNuj:{cg8.݇5Ni9b$$sLb&5Q.w*'2@g]5:;cOTY].L~CGs$tV}B603Ƙ=87)JH|yƂh1GeJ(:Zr[qD-fiZw($h6Ch=BG6ØW^e[ag8[Wwk4 pm_d 9D<,fb>˽Zq$@͂mxk ȹ6s5RJye xUQ{JmߏiC|.C>9'۽$Af[c:/v²f| EKr W`^9 <:BXc͛qP8ו98$}Yd/QcMrE9w-\ьbTo ce&{iks">پYěw$YTYfm䃵#-I0(pTxl9` oԜ-x s +@)}{lIiаi?Oz`,3xrӥZ(ScŠ3m>+;z$X,7piff}6x{mb۱uV|ZnHhѐ�뿅W :@ ,bkX?zX^, FqA[d/䲖X6%9Xd/1~'G&FΑ> բaWu""6_\tW^!HD"#TQ[>U= Ncc pDevD7jω`}.6=VJQD|" ETi b<ZjAYp`K؉TEp|!~aY,rV9r4bJ5Vӡa_宻v [xIR(W<\ަl??<zUe@h$t-Dн~2;Pw`?= S!w̾IŀrqX'z̀ ͒dg@-ɾ6~#x;_}p����IENDB`������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������krb5-1.16/src/windows/leash/htmlhelp/Images/Leash_menu_file.jpg�������������������������������������0000644�0007046�0000145�00000006567�13211554426�024374� 0����������������������������������������������������������������������������������������������������ustar �ghudson�������������������������libuuid�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������JFIF��x�x���C�     �C   ��*�"��������������  �I�  �����!"1ASVW#2 QU$38Rv%45Bq�������������*����������!1AQ"a2B� ��?�n˕B*@QQuŇ8@.) 22,jm*T-0ߵO4p]s )N Z -iNDuLLNi$`NSU؁IS(-"2#/:T`(dv1ʝ!uAtk¦UUTxPՒ0F<GV_ @ `c^/%d{] L8F zn 7'l$�9k<6u/5�ޕ�Sr2j1U6ZBKLRH)|ݮ%ƫ*f*w0T) TMg�)`N3w'1_pU놸*Y>Y1TbdRS^z%3YËR ziuOz=g]2zi*R]�R,xw%)I3Mw̰-׿r\lїXtQ`ѻ1YHF-M¿ D%EXǡ9rQC4NhIq[Bn'i�x: W;t^UbZ4.UAߍۊI_I�g[6tˇ2@R'&kQYNm#N5Mڛe|rqȻv¢נR6;#H'9RcBӭA8BCMyAIJîo'jf8j9n7\"Zm.6<rV)u)?xvjج+8 .Cl&O�s!!G`g%]ǷZvHSQc=ju;7"*JJ)RTAN5͓:wCO-:*л׃5H%O)j;MAk[ֽ5qb$oϘ/ScԢ3*#ʊByi>"9xfeUKZ"G 4(%BG5)JRR�[fm~J0F?Ү"ڏV!D*O2#z.#)*@N9 ۑ)HJouɋsS'RZ`JJn7#!++C̼|(?~=ttReS܇|z )@VHG,KH⅛~HJu:lqQ)ӻuמ(H2)D3_ J7Y__5i4wl0Q#ܥÄ')x~}$>?%ּT.W+8A%ƊJ%(Z II|œ5 SKI&#de+tx #U+MA+]BeUc/Ce[GE ,)qca>}[U%ڶ=4yQhH;s@C| ƞoi;z$+wˮpRS:5F%Z%_K̸ڴ0G#gU::J|uu �VBA g*nZ\RٛW.ΰGRh8} NI^%޼>TdT= +AH݀N9t boUJ*irMsZY-T6�:HWuUi&M6 E%YkfvT3N0sʿ>T66AyNT*,#%+J~iw ) ܜ(`U`pPLT9wt\!P;%7tOIzf4}tѯZ*t9jRS2% A yzgG V7%RPMyOGHKCeCAEE cLWbv\ԺTBjbcVR7%x<</zA^z?m?VJmL bֆ&_,^hc8<QM]*]eRd<ռwL!l%Fh۴oW$&ĉ>֕Mb\TH-oJ-7ѡ<%Eh@ݳ.0ooa9?7G}0p[-<uЗC=((q$,%**)B|" 6D,a9?7MUFe%ƫ1js ΂օw Q?|zhA;�WN2 οO_fן,!S٣bb~u�hvi11E~u�hvh|?:�;4F"|?:�;4u>{LLBu>:ο=Ѧ&!οO_f]O_f+jx{�h}z#,vo&s�MN"�6FmBTv(1V ZA8>c�:G*J9٪=rD \FXi! $ ��<MdB}$^SJ #]"KEZ ḯ$TJps-Hqn"B&BK@:/#8WHެB}$G%_ߝZ!}LSuh"CE=2B3+Fv'`?w%K hWO~wkXbIT*^f<!MBoJӫU(+)nQ4h oQJQZ@S#+J;m}*x*lIrNYZՊM8 �\JW*r_:2%F-m"DyQ4jIZBApA+^-=8e[qZ]!]Hq茼k qqD kRJEO[RfAd؋F')3G}=l^�K@b-w/\d{E/iMk].2zؽ"4wq 6"ѭw{b_EO[Rf$؋F')3G}=l^�K@b-w/\d{E/iM_+D��OǾ/A.[zVVn ^Nޞ}JB>Ԅs%G J@�MX#g�����������������������������������������������������������������������������������������������������������������������������������������krb5-1.16/src/windows/leash/htmlhelp/Images/encryption_type.png�������������������������������������0000644�0007046�0000145�00000003174�13211554426�024543� 0����������������������������������������������������������������������������������������������������ustar �ghudson�������������������������libuuid����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������PNG  ��� IHDR���r������&���sRGB����gAMA�� a��� pHYs����+��IDAThCZkPTUeu R#<fԄ@<QL39r?!'1cKf*$<il`LkY{<vEw<wͽ;g=ܣczfsz`t᾵@W\3~I!#qщٴԼ(`tF=0�{C@7%`' 96�9&6Npo'u&ʬA`qJF#8:T@8D # s{x_ԅ5c0(0XwkTn^o0P~f) 6NW4ILDjr:R5~%M bai_XΏ61mcJV@dB2rD0d\ cqU 85 |i2R _]=!LV~pKEC]V1_>Emk+Q|;,f q0E,BlLڻa0kF W \,XU!ƏC6&0SFVK;GA\<=_VKrD$CyT/ռ/=j/5_ 3U$#$t/}8/$,E׏ '+NݓW^сX3)gb_ۈ! CM}ok>. ߛQͲl7Cd`Y+~G lB)"?wQy®Jsӳ)G MfG?uwe2OꇖǣK8xU+FE%5dR2-rHɷl龋[:Xϯ焝2zpFBFZc&VV 2lF@œ>oAěץx]|TW῎T~S▤ݮN\uQ;o@k7Eui<F&W޲Uho|Q>S8@AXX|˦y(=V[=JSK">'@K Vo3| 'mc_kDMGޗ8:O*ˁHbʠDgGV ?I?P<GeO-_}ш~c#7h rץ /'MøcaaLFJ+xQ#FQ-HЕL'3CѪ?)m|у ldm |PG^"CK~AF^YC'㯡2| g斐nݑ rff"͡Gtzÿ0){Uyf)Wt>'7�tS+~gKa{�IȄ(m@\3p8//d}hmx��24:e G3r^IC @+#wmtZSl 4f\!{@pӹrnDD{9s4ԭxЈԥ? BUZ)@Z24Ƞ6u CIKR.����IENDB`����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������krb5-1.16/src/windows/leash/htmlhelp/Images/checkbox.png��������������������������������������������0000644�0007046�0000145�00000001153�13211554426�023071� 0����������������������������������������������������������������������������������������������������ustar �ghudson�������������������������libuuid����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������PNG  ��� IHDR��������� ���sRGB����gAMA�� a��� pHYs����+���IDAT8Oc|*&iLT5 2'^^pɞB@RSq_1̚=!@qkQ C%pkHKI1A4(l  2()2:| wlF,ebbd`8tû_e4$^f"�```gccXC!×_p3S%.&Ñ3$ĄN{WY)AS%_? Dbc g;Acd4�{B@?0$ك{ ÓĄyT2"`~l@t, L0@T,031|x!SJFH2|o H.2^-M ))I7yr2ͅeT*$9/F/l@ C�&jT�*,z#T����IENDB`���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������krb5-1.16/src/windows/leash/htmlhelp/Images/Leash_about_leash.jpg�����������������������������������0000644�0007046�0000145�00000123410�13211554426�024702� 0����������������������������������������������������������������������������������������������������ustar �ghudson�������������������������libuuid�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������JFIF��x�x���C�     �C   � "������������� �Z� �!"R#126TVWs$4AQbtu%357Baq CDrc&HUd�������������3�������1Q!"3A2aqRb� ��?�˼?7['Ipͨ]6IU"UUx󟷯#RR0}kb�GT\gm]MaafIiHcO_NjyQ-b�}WN5ߜ;:~s:CպKCZ19Dh(/8waU�v~D]uO 㕫ob$WgDxou D|oY4'5QNQ}N5ߜ;:~sVb;׎۸X`^?^dUUMvhyXoIbTwZP%%D�)hKEMTU7~G[|�}k9zv:u<reR8;(䫲"&ڟYAzkRU߃68%@*�V3LL&N5ߜ;:~sY^ T "7_$x"mc#}$䨡l"m>7]5{ Ǫ �J &eW5>~WOc_{~ޝ}k9zʭ4.._iyI*|SզoXts]ӱӯw?oR^c|y)j/N7F:u󟷩/1�e>m<;ϒN5ߜ;:~s%?ͧ�6y]󟷧c_{~ޤS>K{:~sts]ԗOO16y]󟷧c_{~ޤƾ|y};ϒN5ߜ;:~s%5Skͥ|F:u󟷩/16c_u>m/N7ӯw?oNN5ߜIy}izw%ѽ}k9zv:uKkͧOKӼ.ts]ӱӯw?oR^c_u>m<ƾ|^toc_{~ޝ}k9zi5S>K{:~sts]ԗOO16y]󟷧c_{~ޤS>K{:~sts]ԗ�6c|^toc_{~ޝ}k9zSOKӼ.ts]ӱӯw?oR^c|y)izw%ѽ}k9zv:uKOO1�e>m/N7ӯw?oNN5ߜIy)i?ͥ|F:u󟷩/1�e>m<;ϒN5ߜ;:~s%?ͧ�6y]󟷬K96d o4i[_SsDUUUUQWSc_u>mQ:jPۧ㽯?X5WNˣoOTij}p:-@t_7O_A`šU~d\^+Ym"1X >mH6y,{ƄTGG  * D%?\g8Zb#U\@፬s\ZjPkt $!rBOeO-krw^o~^|Z테_;6>Qq"U'ѕ%..G ;F;/">JuW 58tqtU>xL fMS&Α).wHq[iɧJ°/je8"&nBJcF(w%; R/2)qK]CV"de Q|jzw]}6u殙~}D{9Pwh=H~in6(M7GHju䋜ScnTA(@x9!ȼD>J/K;ۿ6uYj_IyEȡQV%c &F뎈>L}wU��F'K2jNDzJ0k �v’ `B<WoWR~w:z_ԟέTUTU1ݯJh#t;wWԱk\H+\u%@9G ǖۧqm_Q.y6z,(11),XFiq ׽weNMSCT?i㿍=/OxnQ1T5L�YOzDE6g5y吨2(aˍϻnvWQ,n*ct]y4gbYd61-$ep hv$N{*oR~w:z_ԟ΢h^�i_doU[cXBn+"qUD]oV�-]=_wj6t?i㿍^aHBoЅ&/5 R~w:z_ԟΣxM7BOB?i㿍=/OxnN&_wiBP'<wsIOmݼߡ M=_wj6t?i㿍;Л!}ɧMBz_ԟΞ+<wsvZ~4}ɨOK;ۿ}6t Bou&5 Rw:z_ԯΝhMu&=/WxnOK;ۿӻx- Az'JOmRw:wo7:OA_i㿍=/WxnN&_wi:P+<wsJOmݼߠM=_wj}6t_i㿍;Л}ɧMBz_ԯΞ+<wsvZ4}ɨ?K;ۿ}6t Bsu&5Rw:z_ԯΝhNzu&/WxnOK;ۿӻx- AzJOmRw:wo9:OA_i㿍=/WxnN'=_wi:P~+<wsJOmݼM=_wj}6t_i㿍;М}ɧMA_ԯΞ+<wsvZ~5|(ey�cRw:̘˺D6AGVD˓Z|,,\:h&ut?i฼>"bLS,9�0f'^?<N{T9" ĤZF=E-N}_nAыIQ-xd $MQwDm?SE_F?hZ8N\gCE8U_inӢ/#,b_sbOEէֶĦVֵ\܈MUF-Sbz^�ptdŠv~mGc[4wU b]tGiV~'44XN\j+Sa9c eTOMYjPR naÝ4!#G;*H9&(+�%ƪ-tyq!_t֘2^_MULyf C契 ۈٲ'U8*J&$[ eLcV#[;dyRE�uK~]Z3QO:MX7% />>R"Rs&,1̂n,P:ǛlyMh79GDWETX.?S\M:f=dMd1E/z#}�r`=:_C6VĘL۳ F8ꢢ'&զ563c1UoOavZ .8l7ǂ)4*!}%|&Θ2)Y2l#8 h\y BN*o�/7Z,dckGg#9-6bP+޴F HPׂ*q߀3{{vY#Ŷ] ZSݗ 6&%K ; NY,oC&41Q[㱇%S[*F3Y#;7r+Vwil/�'G~sEL6fYZ,:f "$~{+N?l�ڈ^H@ FHFA]z)7 [X9\mD$[0idZ%>;Kv$p'2TBX I]`H[W}:=vTqG>’ȓgɛ dl8�`K B} ]ںkU@TFt,cWbTiK毾:p_־P)Z[?mu&8|g+?ɒmݐ\JBڻM4 4@M4 4@M4 4@M4 4@M4 4@M4 4@M4 4@M4 4A,#YSc?]neV?D~Ɲg:غ]wU b뛉4 sWP -gIu,�qƄr|7eQ5ח\I}ADM�ɮ^uUnS-3EEGQQTMֺƩڹ�fqnUZN!tH0vײ/宯B\,1r;gQm$s1D\iO!OEY ?"I-.*|)m��?n3C$ĪnwobOn't_/�Msxll,~#8jfhu~7N'SM5ɧ!T !]ētTzk g} i`Մ{ R-/GpAvF{ 36DMS_UL KfV,2mĤ@{]T|QQI76v?c'b^TLC&b̍Ir#Tpӧ ccCtYA 16nưFkHÇF]D8QGc»4PPD8m${ӖBAyex4mD\TE⊪(;O'~>v˵ڲU *wf` (<6D o}E= (r)qaWHfZ<#DEO b)n2rmV&>N NEmratD7GRDR5p&j!{ 4-Q$]]lr#&*="+NiIgWa{HH$-##1a3.P9D t')#q#٣/0@T憤#uN@5"Eb6f@qc Bf/( .1*YŘ*y%*ɤj=d 4UPEó [UXdX͌2 ʳzBjӜ]][pMp ܃4|Z%d]jO"<j drRU#WIBXqXl)vGk#;-ɏ6bM 8ӥbI4^i=p"3 x}y!6G5Eb&ۢK#|B;,$c]G?K52fta0%-LJf$r>#Ffsv1r9)V# Yu2@9gy6|">h-IPF]t89ɰ21;'l:UC"c;|0.@VZtų12/p9okЌK6oy`:,P0*4o|~i> 3ͮ3H1r*!j&v$bŕ#%KC.(qM5Una٘Z< <ӏ@mL[x#qBWD]Y/ZeGUOr;^H0dڈ(r4q$15UǓŽT*oߍc 8پ,ь v]▪5=4y%Z&CgFԗ \&$um`}/ofY5j"Lّm%a]QQP~- u=QKAG E # m&WmD%nAlF̛!nr6hVɊު r7s ƈ݅NlI|I ;bFMuRMϱel"nJRܐ\wpBTq/^JZ^6!Qd̋iEp%'Ųn'"k3hڑV&>N <nEmratD7 -4@MGU0.g[Æ�zEL08V[yuDB-ttT@M4 5#hpspiČ#O숻m?tvUL wvZL�>MEUQWdEUHwDTXAz#2e3鎫1u}q@~ ~D]N dQ;|\mmHp @ItMݔGl94\EqM�~TVDU*m.'M5s)9Δ F ( l d D#W1⾲n<e(4.&\dM C~H"W$=Q f S,ܕ-}eQWqDuTDUԎUWMG VYFndWwpP"⨻*"GM44MM44MM4i?)G�Hiŏ#�k4[UY".D~Ɲg:غ|M#E!v'p}FˢbШ�E_>+ZИ]ZkՀ +|-u֚i-yfyO 5oEk-&# E"<}J언$d(h8ԁK'DSqUU6mo:ьoc4s~:/M"ϪN<ziEm&dI�_$y0iIďur7k?H)^V?Wfh;rTrO/˭i'ʩxDdZaiM6D[8~MSzkuğqg1 I#v.H[+hf4`8,~̸뗃hlr�^yl?YUlIzLVd= ~3L8@ Z\ td"sm)nd4e2VXg \)H#o qċQ,ʲjR{#P~jjQԔPeypDeac56+!Ŵ٬ ohUA䫲.ɬ| dtu[uqظhD�^pl򋨙]4(=v_zTמ{|,gTQG[5b\c^L]n2<ӝk$&_)2L*eIQe \BDqMoؔ@(1ZmDOP"""'5l ASO3\wӤ[aV]KߛDY=I]s!ךoWDfaAаhmآ zQ=H Vīd>M�8'DdD򪒪tB-jrJp3 ,(x 162}h kqFQ}X x#U4w>{ڝ m3 DH#=KePqm4*{Z_ՃoH3'/x4ۀF%s"`94+W& INX>ӢNJӼ PRWD[hFAȡ^Xc=0HCk_oT:1ԁ^$X.ؠf]E:eECis۬I0gL 9 Bfb˂p Ki~@rʷro<[đj8N]&@ l9I ST#e2eJ6]mێRGP߃**!kQбʚ{XYvlXzWlx4MψUdh`v]C N./'A|qC<ÂO=^Dtٴ d%uJ\R\ ܇!q?' Qn,uV . d-K6ɸ8MTjc̲dp%m ZRT K]bϩI4UlIt+"snG!' B`x q(q-tΚMfvXą5nĭ,R_nIB@SIfVO 稾&U=]i[#87ͦ$,wk8m:M&a2#ͧ0Mf43\uX8ʠ4vi H0#a2,&i̩rʨD\j'Q|m45Q"^Amk <ZK'poۈbhI!J7|+1DNع@q~/ZfV}./"߂@+Q؅Q^@4Zh9d́@Ncʛ-0H,uCO /#_jp-:^oM~4&l[oUB*rwTjBd@HɖAmƲ 7$7bj 1upYD(+1h3٣z`a">^r,MpLk/44FS@Ɛ)�MiV\J|.T2]Qe|qJ<Uuq@1cRPYC)o-"X-} 9ml;pd3:@ U Si&mUY[_SzҹN{B=Q(wUDDeUǥ#Zv3pX7ffY5 HFzWJjMi\åFaO?%ƛRZ�C5Of1OSZ%׷QC"3 ' ~16o"+|ctNVr#kr̎Ui!Ǟ &-FI$"1vYnF5*0%G0$wZ=vr#h]6עtr);=neArآf+ɈKfH`%_Dy'k5u>;*of271j, "TM|z*_c]ede*i=!3Ꟙ1HɴؤmTyqlu=1uO?q:tfC~[0*&qCa"E__F:HS3GT r<A60|Ke뫖hihiIMX�?FM<,#Y7ʭV~;*uu#4?DA7ikIM馼Aii7M馼AT_kM44MM44MM44MM44MM44MM44MM44MM44MM44MM44MM4i?)G�Hiŏ#�k4[UY"yY"7+}#Be\tUvv�H8CIIRKmYpkesa$MT�["Jm̟#Q7-~<+#S4ӌm槸2|iG^zV3FgBH2dv�{*"ɬhIad8Qil4O6(nr!ԫ?Ԛ&$O)!~-D@v5Y( R^})lJQSziba܆<yd$MSFg“Zڛ8Z.ߎC@̮roĕTy"쾴ԄܫVPÖ;*%2;m};9p%U\FP*b R:Ķa1ح80Շ %|M8NBDU�?X-%eGzhpa Ȩ"j?)qb19gXܗUT#mUv7U/ ޹YQg"z6&ޝc5՗kq(G J,xS+k܅_PV02i[9i=Eb{ͼ"]EPDonsɥqޣc!1&ٸh2mQ�@CWo`5 OAkjlTQk,~:5 2eɾ#{UQ䋲KW>֦\\Nx.Gx0H6uەGhͅ=ubfu\uؑ d}R@Dɚ-TDbc�ScX N!*ʪ*icu {7scndLc"$:5 'D*ګj(ը Ɵ&Ǩ O:<cY,_uQY#5VDTQD"Zk:Ӧ59dJ8)E\qQԊeʺ8AvE`,nY=ZOi(/Gu QE1l4 RPBq|UH͓j J)˰jg/Zjiix5Eq~q~ ֚8tq~cZ|8tq~cZ^MQ~p_81>p_81/8/_�V8/_�VzT_/O/Ki/Î G?էÎ G?ե^/Zjiix5Eq~q~ ֚8tq~cZ|8tq~cZ^MQ~p_81>p_81/8/_�V8/_�VzT_/O/Ki/Î G?էÎ G?ե^/Zjiix5Eq~q~ ֚8tq~cZ|8tq~cZ^MQ~p_81~y}Eix5Dr>"{xs4DTEM}h/Ⱦi?)G�Hiŏ#�k4[UY"r?a'D~Ɲg:�\Meh.AnZauB$xN;)OlՕ 8 .9K㙜9STb;Y,6399M/6WH]x1DA9 :933t~(lo^crε�ic)/:}pwUIEXIdJԹm:dHm mR:]iAey?!!xvj3Tyψ<N aIAEܜA!mξ(l>>e.x:#F3UmM\q"o'@^VUG5es3}":S6Ti4mm_a⭶6h!!za+,#3D-ɥlsP1`q}! =Կ+ +vUKOXIjlY2lw"$VE~ k+ͮLp(eZ16H\2r7NaMQT|)jmc&GB#d@'`g_6$_hې|q l(;{.!Ȯݒ|1XCfDKhbdIזWM%tK_,Fkg&6ۑC¸>y}۽IRMy\tp~K5.b+r#:<"(*%?R&;qwA@ׄ'RCr3 0I50(IG;ȃFFr[# ʞuY |F& >~- (df]]g_Ḟ { F}gac 㚃@4wq&8n2cVPŻR?ˑU$DN:k/korLev]ڴ Jnr}Fsl#@KECzt7+ޜ9 {α#|Hc3�cXsA.u4-&jZlE y[4q7yn նQXC#ܭ0|q εF]za]oDУ~ r -Gt XB,im]vK$^GvwV14_a= I=2k- XMV<!E7^h]_Bs%;q7`"<>/aZ,`H2(mvԜ오umDHC~<u>K\*#UcLMy+FљN3_͗>9WچS(w-ȕڰՎMʎ:Ӎq8vEP)_ww_Iukl ;|KD']h\ezc lrFro)xXM2mQE[犕^ڼ#0,Kp,fC:\fz;Vpm\ie6]-ppfsyqAAj{yIV8B8BN("oqj#U706[#FA\t{$.:4u^ޣfyW467u42VF[Jjəm#"N@)mZ˹r%$#Y<BPj*NvEA Xy6c6#NmoEvTW1"m𢶨̨̓hHAT\WA`FǏ9a3u-`5#໸L#+˻Ic+*sny\Drd0W`nGUt bd*Ki,,zMM,-$Ӽ2<*,b aO[N9UyNS71s"޵*ѧMc7dͩ"�+:˽Y{PKB[r 8n9%wSVDS>IZ?*G&亚Ka__፣&{*;aCWIeYvQXz$֮C2f !,JF<]q Ie �R5ɦ>3d-̝^ѓw`/LʳnWq�H=lM>Adb? vmUDwvŐn#M(c{(k*%Xu dZDfͨepaIyD#(+9d[ȳ[J}ޤIuDŽRv0藛9"bnJ☛;Pߩ&ǜ8"B|P0um?RڛGY4WOV ے4bcɪܢ\T)y(vLeH٪M+fYXϓZ "aFmM6\Gqaw${howE UK/Uhw3S).,{0)I Js5QQ-%EEѺ̓ #zNYݳH#)mY3#/jwԌȧØ3iUX2FՑ:0A,‰Ј94#kf9=F[IVc=n>ɷQѡPYǺqs\2ˮ~t�F@M1l$4ldδD3P m7]/..4ƘIbc24[+ڌrb,o8D%i[׏86?7E}Sd! UͰ#XN&QhU 'ME;d#VԊk.ŃK Σ6m:BOL}_1U^2 x]Y2^=R~ݣ:wJC}.BfS`�\ɉmWvBHP5OTqx}EDZ T\t' )&^o kD5ܙzm`n]PfL(i2͸aYu9'e!q6"Vt#Lw0f/¬b=.Gd괎}>H kma]�j,=c Ĺ1cQyܸɒnnZG^c}7r __Vʕ hxH}O74qQ4u_0 slc!jՇ.+X~k=Y|]uǡg&*&\o+9tW3zTl2Zd DamCUlɰwroZv4F k ./1P;D~Yqq%Wݦtݻ :Z\bɓvf_qu#�2Ӏmn(ot#ETL.ǺMS-zTAl�)iGq Bv;x34q&a*z?GUO?{-򧸹<4َ,8RspdQMET'"XgOf|ڊYjunvO&iM,AAe�2zO6rLFC72ƫ Fb3o7lQX2ٶd䀻:oDZ;-281F#j;הD\qcM}6tZ4IPx YWAK#Db$fD<FQPDU m"}򃦙WZtX1"WE蕑E} 0ÃM.Jؽ Ȭ3.tmk2GlC̸ J""&M^860LBOu+rI!:mض*j()"o i}A>|pu>m~~x6O_4ͧSMi}A>|pu>m~cNR=�V_�-i+|%=vA„0XtԣfHq> 7 Tֻ|22�ƹnϦUNQfvYi{GI7@t3^lp|㦓#ZSb0 B`BHBbCEEEQQ5`~o/ޛySGz[8%9\/ѬSoAS}?DwEZ1CyMX�?FM<,#Y7ʭV~;*uS�wO:#4?DA_\NG?:bk-#Dqt&ozLb< WsԷYfOD6܇|̎ ]).5e^�~@3y'f|�$\F-cWvѬwn{@܇mi[!\- ;{).Sb\NkVT[DJ8Ar?;Fw7YCe_R@nWi^RN<M(KU8خ4܁v798RdVYO]UIr8g1=8%u`&㴱|Yy qZgxJLuBJ%$ĕYEEEq}TuSw517-2OΌD/2\mD PR9,}=ǡ3>̨#TCԖ Q9 2H O7eG>Q/cb9\J#^G$aH, ȊqFd0Ȼ*E|BmT]hKX:FKX΢HA%\IƝl*rEGViM+yUeȸ`ϗ>r}Z8�Q{ër0DqkWN({Q &96Cێ!:$)uBڹ&?asG5"5єM,U'7^I+ceQE͐HrMD Ȁp*KRQRBkW}/; eYT|k+"-;j !DmZ&R9V?Zs8]2,rpJ,[,HqmXExABbN2&s.#0"2 °H)%1!:Ӎ:JW(Z2a@f߼QFl]I uBTOurn90n'RKj3A%ĥID6&SAEyH.߬~[xث1bc(#5Cql'LByN9Tl6]lJ }g]`޾^12XH_+[-b`AqF/bCOu[C0'X2DiSdFU} ߭&G~ҩqım7d-I]Yu"pe#W\5C^}J+s 2],LypUF/gBQGx0X,J$ٖzgw,ǣ>Eϛw}|3H>Sld93YW^dU+bLmfD6sKYM+[狖A{ZwY_v^ vy&;]ɏ*=#g8vG�bSmM`!1y_MQr^xkcEԅ"Lc{U=Y9}Gcr/tؤ:i0nq$bdfNLci+d; tHn*J1@3*IJ\Uz9[ϫz=(vK(*7dRSeTʽ i볩Dnc ULHZ"˴x$5") 7y~c<ȝ瘪QXe:QHzS:Z.~Deo`~om$w7Nm2%Y]Q` DJO:[f+e($UO^hzbrHYMmZ F/rEi2HM"'wy<6>5udMI |J\KzU=6=h1Pz18NjW}l"t=WS˿1+�|-.yóėypߎ˾ڂ>c3YeVI2ŷW8Qq!nvET4"AwuO$ɤUFo)UYL~=l(Mؼ+,XECqllHYU[+a*#I.V<B(d8H:cp@SXk3xWPh%ֲ>!^aR?e#bGǑw_2\$M EH߬ҴI &:}7tIStUTUE\\lzWcG޲VU:42'%.0G]Dhf?dc䎚JjlVq@i࣒9#J�kGpL:uaəKIU^Ly'^FI�DQ2fu敬f3=026<Mzʋ!Q9/mUχ'Dy*"hk0C03:+~/NUm@;m$qy D\BtGȰh[؏oUy+cܯ9Cf]ZF|~jj-Ǻ݌\u/(eYV6-[ av>(8>$]TLwt# є&k۔:ې-i䀊(IdKӉx�Ixu;˵gl^"9;m]kXW7;;RFbj :$l$vxHd=>IJFcJa1aq�]۬DۊۤJ=KGSaTKz*A*ͷڜ( F9r[zgaS2g$R<l_@':w79{œdɰ@ОI\֏ІGw[mG>+M:vďn 7QQV�uC{1.5;DWт!pYQJt=**’3FT[wdcKAے0nF,w -줄$A}W}}Y+@Y<)G'DicWH~5͓>�;,ْ-S%epy1 ሌ}]$Uǃ`S[}n0<ȶW9>+I&V6Ջc3= Bm9'pWe7sH&dnl\bEa{i7ḻOh D4w[3܃4dO yc#GsDzAζ4C8mW#}2 C^/>^4kZE~ n:BdE{Ғ\co[WiiUead*ml\ۇ%TVOնau�&eLrF3 bUV6^o!pJcinVdO_2Us"4fc2lXr%28jvW{ 4s\rj}/c\)54GɗTG.>N4.X kͶUyMz;(q/z.|6ۆy5YGpaH6S,;Fܱ%D6At"=J1oӽv]ͤR\fC&m1KCkpec/x˂xN*;S[޺?�lSko`yսMwdp) ,HjN|S$6ң$!{vD) ;6ƱU7A&ZN8VlPKy{1JBMVzc#<Uw{"{'.<dmMY 4@M4 4@M4 4@M4+|5Jk z%33کꪪU]'E�ADK# cO6zQv**"ۯ7Aղ_�_N_�t%|,#YSc?]aV?D~Ɲg:�XwU /?#s15cYRl2JĹzxWe8Gs$TTTSX|2m -R:I1q<܄#i94|ԽCMu�b=5ʾ/I`W['w"#H<W3ɗF/Uʱ}6ũO Gmj!1.DmI}]h$~v.uЬ?8|ÿ_ ҆F@$42~]ç-nw,X83þ2D#Lj4TmA f]9X+l <zUnb,=1`"m <ۮ:4<RTMy/B.WcK`E턦\7qP]ʐy7M39yuFCX4Ҷ&_&BM8.v/O9OQo޴nzFqF6PmIXщ`Ԋ#7['R6׫3zit-C'ȍݲF(:7W\VW7u왍éRV=ɠN-os Bb뜣>V(I¯.{d4wT0qע; m(ݝS 0"k"z7Z!c\SY _v[R/lNET~" n.IV컪 ZFr>kȟKP,Dn(Dqb | %J:|3j#cE݆?/͡"rBo9lȨm`W%6B }Џ',Ʒ-b箟Rޖ^mIlFdW/fccSVřLWpv. >؛p]j5Tw38O[1S[!$#|6dv< @QBS6Bh(蟭ǝiYؤy 19q}{F„~f.eqd/;&Dj2AHr!ȓO~8q_&̗kYcjgdAuWZvv@N!o!x٢"j$�XrMM6l݆o)XXĨu"�qT[pUɺURUlf+/YhnEu!fKl=tA}; hSa G.qxY5$zrFzc#I"㬧DC}YK8'Ktlx17ښ=&D"eȶ}6sV@17{M8,a礴F!SyVeWjA=vvNBXli4k F'SƖ1". q'U^ =9;#at%>̌UB#إ4ĖD0J҄m#:W ' 5gUAH G%͙11ɇmz:eK:.:�n6s0l?ܗ# yq+bW&^ӭ9)H yV[0od4O7>K#q߅B:[HB5Cb9."vqP-Δ@* (ܗ%u 6V ~]&ȌoV ۈ4F\2c8al="ut&[rtMb#Ndզ\WƜe$ w͓Ich=W&U#|Tjk&1dLgKnG)48(G8AZ%rA=Tϻ}ZNj'uW:Vl'(($D4~Qc}6?'bKs'+N6B 'ms5$"XOb''TƁSwulo摫ڈ(MJÒ;5юM=\2,rvرolص`; ďn\HQY,aSsNGH5Ϫvݴ:Y-K|kZ"#r~;"f$jtl }] I$P`!13E@H>ę֜ȏٚ^;ݐ#%X\^B�t;41qAddcYv*Zt0ptAG?>@!C.kK~Үdi[l5,+%JN.V|dZp̻ !jęS͉_꺭+y\pe9WȱyԼ #J0ՆbNcW8ɁAX/<fzݦSK 8;U,,sȏǓ+B"h$`tVb,B)2{ Z 2a1ZS6oW(鯒w$RޟO#TT.4N+hK–Mi丟Rz-0 qvxNKVmYV՞2^*w$$D8yM1zaOc=EU"]˒D8+ '/DpI"l{Ѭ:E8X^%*:I `FLUNdm.%|FfXG7�jsܸ0]-;aUVܕTILg.0[Y֧AvI fTl MabGejN2E2dP"ډ1nDK.8 &^@x bӭԭ\[9Nm2lNq 6H (sDge'9Th$Yc*}ifaMuI Ѐ*+Fm3KQD@Z2VRS$%8mhţƄm2|VB eDyRp9뎖fG#*ᲞlW6}N:6ˎȌE  l&ιO\emI6ML6'Xݿ` kyU΅f҆cݩvz+ (ɄE(Hh䆪mU5U|m1.UcuСda؞d&$nQ}Rs2ؑ53gVXZiIReX޴\DSAFH" ng�dx6eQhxMW Ecw`AH-4#8#IxeI/QA!ծ6ϻ KlGeIɫM$psDœ5UuK8j+X~ȲF!ݡ;^fɲk-UPuH!f-aVMnU`ΓUlsbƍ`rcqS# 7$SQC@Ve -6/ҺiS#Q?8!n4EwZ˺}gcB\ӳ3͙qfG1-j/qDŠW]hj|~<efC)M46Tsrce`#+O"#ۭ ݺrMd[J?$fyv5Ub/Z5ḗ%qAx=ev%?GRDf2̜4hT* ؀mxlmJNIql T[lrEq)0X"fau)Xsf SZK*[$ )̆UV07q "f!Iak;YȰvTWL^n8\-hcuwa8=aII CIqPRDUQ]QoM\5YY3<%vŲpk|Ef26 9ؒ`&lEUO&]62ߟa/~D.+ElUHUUUWuUl=4@M4 4@M4 4@M4??/j4zw)/kZPɑ>pq]0C3"$UURUUU^J-S�5S�h�cS/f #Jqm */jsVm0ݡ,#YSc?]ncV?D~Ɲg:�XwU /?#s15Hy�ҟH<w= ϊϵv]V߯%@cKe5 z02 lᢑ׊{GSnæn-.ߨjÑMI2ӓѤXc S %x@ìߥ:2.=7P!Ymb)Q!((םߩ^ko4Džw6<NױݏI1k,2I_YR\d'Hri}he;AA:2[DeJz9A2"i)0,*6 Hgds⭱+TRD "Ϝ|1~k bG[ ˺)VRکe\zq)7q=~/ԃiS>eL}�3 }ZX5#}q8!6 � Etkf7~;y;v$:U6U$٣mݷe6˼h,s N=$xԑ b[6 fkL{;boEwu12m^3 }nMhKZfT]X@t~[XJCˁ۪pA]GS7Pcx/ Vy&EGqƅ6ԃN|y^4q\z8Wb9+4CJwA\j9EɶӋ$$oאr�Jo0iɊtl{[{^F"V(t `k֥T׳RX2jL&Q81E4FwgM0da]/9lͶMw c 'Upq%I WgU}2y%W+oټ^2ZX :PSy�pmlz̟IZjX<TTED%رEz{Sqrt/yyŋMː&ȼ(" F3NQf()]RڛCm^,& t8Keb+mmx\,Lrgï7Nd;."ex]maV$e.3]u[w!cY îVnVM3ynT/%qRmL%ts3s*1-BS(>vpФ6wSU1lJ+Iھɶ[_#""i\>O29MLGtl4nDU }@I=EgwLҤ}sȳ91F<rJxg;F\DjUT\ je_|2%ƙ.T6$ޖdN Ȏ) "y7a== P̓Sdg>MNzKX@o#2gBsmcWq:]_ÉMĬ^唫J"cԯ/Fj-r;Lk+;\$a鹠LY9ܵrmm 㓉'QR9)YV.Ss"S3YOvyM|1C-<6!:%? ܸlSmɍ͐d8ZipU V6֒l-yn]@H}mommPR*>bq"B㐗]R ',ݘ0LjmTR<1"V 8}ªTd[Jz{ٕI 3),p%@h�U8Gb=%.K,ZW&|9R\m +!pŰm& *NlN/.wꗄIs?ɤcN6W7f|wgNr__q@-NۧVE"vxԬֱiLˠ2\M ]>T LO _aUm!0][aQ֝G]mu ql )YN^uQGbɦ+ fY.1*m*K. &b]E&kmQfdz7֪0ͺRTg#:wC{ P80u6<1+`6cLfWM^KVeCU9$ 7KCC)[[ٖ.Xs_mc@ o%vIԛrCFؗnP|mh[2XO2ŲCm,r{r+;EC);%RLfUrLrSaSg&ʦEg˦Eb3تrq{1-%qXqAI[6IBtO;ˇ ]a8-ɏ/Sî7!J .n؏HX8<J7HzոJSNۊG�QQ@UlUT,9uMGe ,ضQ뒬U ;NlWQA{־'Sx4<~nKu{atڸl|vɽ{4maq2 wU?Q3eYk^Zm�LyP^ {]JlF=).>rv|/w#x=7+QOycd.Qeڷ +ȁmmPi.Nȡd9y5c)wy-Ę^qQ^e3(ϐ+(qki;;B^ } w׫9z~׈z v:yr Ǒ{OFd;.2Y]U^\KCvvRe5ֵ%QiRKםyG2sr"vXٽPƲ |n5ߘ2jqz2uXM[5aAc.$༈$M,4˲< D2s88ˉ1b2ouK:cG_Kx\m�Š~/}d[Q1|*ǑgO%tl\yGR"QX*?ST�[Oص*9,nK7P<ZmV "*Hh6D0;nmı)6�AoL6dt7"DXCDpX" 7mmeΕ"1ed-8DuB2U5J oc^\Hd0)<=!^ P 67jQ^crs<(9P*:dQ!*,)Vil 925gaxl,;T%p5El"32㰵""F}tgYV^Kѷ]U&ɋ93FJ#A&A pvV"<6#U#e62'8OCQ`k y, lݐL$dwG5fmM>Sy0n1Yq<gHj٣\vWlqb'M:[atܝ1̛3!Dry ͊}3"|{kLxFN24㳤;qR@%E&GYd))' 9E'.}$fM)5f7mo®vSaa--asZ'vKۇrd?-m{ńS =k)QeT7o&ΟŶbji;3\P79<Gl^QGfD6cun7UAODj 8L�<TaMUWoZӧA~*e?[1y{.G4MM44MM44MM4|'�22�ƵY\-M@)];+0_JmI�̤~ oW&8d+"d*)*m^UqA0cp᷅%�_�5n� e#CDvCU NLx|1�GɾW?m�uz±CyMX�?FM<,#Y|7έV~;*uS�wO:#4?DA_\NG?:bk-#E"s+ޤbX*!ZIsTNl�nL~J|T2^c* ;<QJLuF|+ StAGg j'2Dͤe8GUIaa]{wuX4mqV1ղSГ?' \򙾑X*IƼ;8Ө*tDS"Fo° hw>ʨ̘xiad] Еk=~GBs)omξ"Lǒ4Ɛh[047p7EUĶ~w9fzSEVU �eGۮ Zp+t~TgV֔C7v Z:zcvdۊȐ&~.+aZia.*ǭdeFqdD#EP 9( *"{CZ6*̈U-|cߋӶk~˞ܞ'i;GƱy8[̰ڐ޿P,nT܁q ;n ۶PDcp o%o\]WO2"#HH<T#FQ}pF�E[P򛥅:zȌYPyo2 a0Bش)2!'PI`"p­b&,7a3 "L6s@;n:.4ٸ}x[Nd=-UA܅\u[&()iZPUxȐx瑽#TMZIPe;m(,N%Ae 0Dod`?.٫I[iliJ�$\!yd-(*bzvcc5*yJe40{(̫ђq[ude|&2r$U˅"*>)IR7'EV`ņ7w2 ' E덂 -�+"&0rb8NHT6'7da\MBu\eiK�$D(Qmfet=E%ācUvey8&eZx$Dc*9 &|*ŏ˹˭F^ yy0=TIݜͲGdXrn dT1UkArb-P.'H|A~KPXUTGEeTf^[6j)_űxH,'U"m42!&D-)J[.Ļz 3~S:ueW̯btԀ/Ixl=lRqI[Uo4rH:1 d|K,V\4܉@sl֊ {r h=gwqlz>S?t{fjDx03^ABDp;�#TXz9Ŷt&cBfG'ܘ][r6q\>ċ"L}ʿa'2d :i :CXэ.4ӂÎz]VWy?Ar(Q%j&}Iͫ8 m)6iЃky@%j2RtpcWJ}d8Rx ˈ5is.D&G[eP]%^`4hO8Hn6ɈH mKeaMW+sd* Gͺ�#<M6C&ʫ:Lԑ.n[6/6|c-QiEt &m6JOHfl7rAG["{ (;t5uwUrLĠynwT]8.|&U^Iuͅ2e]tK*KYб:&j# $ 'm @A�>3ɢ%tX:Q]T$\x$yRWDA \֪$9c@< c&2),l9 1fAվg5nɋfe|g2RYqiS,MWZ!F AYy7ZXe0Km`t"`'T@t 0= #P[7�?Y1ʦ!2̘-Y.L�VU^bin+f7mD(2݄8^'=Q@mI+2<-Jdܹ8(նN1wɫ.ǛD\ߎ̕Wx:ɗ$S9~uLe,dv0: &-Z Nۇ!9ŭÌDzfCsXF10 G6lGc`m]@ %'^,JUq+\bo�=3&؂nȠ VyBeGe4$2ёyZ7� *r- =Mǝ&| <2q& $ɏbL7ɊzI6|gf�fwظnA=ZDܪZTxco4} GAACSӯ5Jyy-vڂTL'cKee6qiQdVQTz-~G_DXFIY2䃎 =E+ƺм /s<U.5Ճl59b,qQ Mх8)! #XɊaw'̊^ 04~G8"j%2ieGNJG * 6<*#M,jeg-~)'u`lRg1]( @ۏP*U%ǚQ|<7{ 6'ӷÌg"FuC:ijieL5JWJ;pYyVCiU켊$g*Dh-5<nd^٫mFit/[_23ۡ*!(iQ5$y8&Gd~{ӉdSAd }L'qHX nlN)o)xE˴~!V͛+rxq>0m;5in7qʽ^P8#U=nPqv<,Ʉ`G"&o>  o#ZSON;^WYMn.y3s9G�xc!Vq%{,bDj ^vd`E4~P3!9dfɤ�wNS=,oq(TFcI]PmQRg p*S1*XdYitZ>5qv' fLd7S#I͐Y.!T"R/gɚ?m|ieZ , MJؑҬUisy65W{XT;_ʢW>"K _QKV;<d3@S S:P_FAm5b!$Ǒf2Zq\"I EM ^rQݧdc%\ؾ,#ouy;0Gm@G.7=s,02 >,w#bMr\SeUM*p{AZU57KkZ[jpvN8)b[\TRE¢*!w:\K779FAnVm)a{r(9.4b*K됥p]iiiiiiǰ]_lif$x18 vF-q"Guu7_^keX�8j׫6VT}4v<yquj _R^[%x�ƪw�ok4/ŏ#�k4ob�5kzljgӿY}q�u9t�8?cN Def&4N`R2jƂ()@w mDuVb."(J(H{vjL-eSUٯN;d#,>Aӎd]sH(^[C  =desƔgSf=Õ xѱZg{h !,gIq$bob*""jyD vqk*X.wNBMqMh8v܃@qYe;'fE-72+юKO}_!cr�bm2m&1׊Q1�f�/�&`ܮS'AeXp6c *(61sԋ_ֺgȦ8/]t�'r$y#kJ 8cDMIP+7Q:�Qڱ˫걘Y%o ;R~ʤ7 O.niؕ5,(9ͼ:TM zrŕ– =5՚æ8eSqZ9rj>3%{μҨʤU}zA3c_uSX4k9J~SC %t@ړĬ!B;߫<3گ b.nĞR BKrcF$X6"u]&DĞ٭a3spj;R"YB1a2#xT\um'jK& x&1?,dЙXnLaCE�ySzvAU~QޘRc. <5ط(e0㯉1�C WNvY2 |rT%㬿ѵ\sɮɲ<*i%7(�Yv)o2lLch;̽K͜xqۏonm5zbsra k2e8WSr(i(dU75;=֖RkV䈴QdU86\_lk0:flkXklZD-q(n :%2<kq ~r$+7 6euǑW֎8F*f?CAF$ʷ>hgrG6I"D V2<<uX+${HͼFDi$AF�(DUVO=eɡ6tWUEvujAr %yD mAV^r:~¡lm'7*[.К -YH|[lQmL?DUWdW SpQۑw 9Ĺ8BhAM^N8܎Q : c=wiq_r ~fSEڗ H1ہZm#mo 8f6̫t<j Jj młWxf`$4m&^<U w9m�]?C0LU>R,\8Q uK}7M�M#F$"{<Lyduqfv u:P[r-{nO6h<k5ެvuec5Ij\;8b/ I�ҸlCO.:ؖ?S]"tvK 1[nd҈)nvG\bTw{yí6MFKMb$E-A ',x'GCUv ɜ0c׼b,LH֎К#ȃQl<xD(QYܛε2, y \+d#\S bأi؀l v1qm"lB*&:4;cph"Df=c0R D8d<w@Mjv:|ŇScldk@j"X T"*0<)hP8-3س7*mKd#t-%Ar'uc I{b;ˢcυWh^oMʍ@6IMbFe챚 8t)IYwqY:ˌd?d!JZu߫0 ,&aXEib1,6Q NI]NRoy_P<{CWP^["lGyP͉8Hdd&ü:qaqڬ|-NKHGiaFC Wr3"8 G/*Lx&׽fo8[)6,O*hsA,§ԐqMu}4`Hi@$ChA.fV5UX '#<Ӈ(ukşovaSg{(̨wOpaxwL7ipZ:ܓ)Z7SYtS61' 'M#EaJg,è(Ӱ 0-)622"@D 4t<�zgѱwFz58=ʼn`l9$x :odTe8|:n]cW9;lƽ ~j4Tp#<u|̏1|clbN:-5>)8D!)D*&evCӊln~FV]<]_Li}a]$u$&iZG[ffU>ʱ&5.qj_ N,l"L'!_s\Z&M&,d0he7v5MSqye 4"Rpr9L4.?4v"CyH[e@4% zADʞ̡uV9JĢZ˖q[7Zr$ۊ q EQQwiTB.gyF8"`e1f:QY$ri4FPڀp'v]sX9.'P,dhfZ7v5MSqye 4"Rpv?Pp *8!U5wraɖg'tHex.Ȟ{+�6/J9#Uɏr"BːT œ*xDB ׮YUReba9^a9HciedpՈ.Qe4ΞLAWc*�2Xn$yG4XEM]TWvK.#5I. 2Ugdu1HЧ"EZm5Ӟ_;r͎<}DUn.Ô>r eyiU"Ci>rZαX6R9O[[;rk}kHU7$ÀQ]k\]Hg;*Bv MM7!dQe<{DӸXzPN�M"Co>EiIGU <³mztZspi�I+[52%fĴ$nlD! 3UzYe�6kZ'i:'%N2H3.묶pERdDLV:s~ %;?^B/n$bۓA"G}Bl5Y<N%mE0Qɽ1}~8m'v2m<at 2 y,56l$%DRTQ7OiOMԋڊӘNS` [N x(msDIToiiiiiNe#e�ik,jű$,ʩ$�N8rjۆw)/k:U(uǡYC ۈFQvS잴!M(Y6uYymF##$J.蛢ʟ!,?m�up$ZxUsuc+vO7Z1CyMX�?FM<,#Y7ʭV~;*u~_1F QN;쨨tOWȿ"GiV~n'-#Fsv͛-n;Iqɰ#庈*"Ȯ\<$x5s*[3seW%iNa&7妱-wҲ]7Q>]yH&*8ЉT)2*k>1Ccfښ !Y4mPQoZ;M2VK\߄Twx=~ˇ{%2n3X=>q/z8�Smmve1@;,<]KNw#Kjr]e$Q+BecŹv*T4Py8oluLtCx. 7c@>HlkAq#S5PTMIYH hXpb ؄E�tAUOuLv 1eWCqu C3AH&&n]] TpS]lb' 9A{뽾;p.i6.eE7QqaN>*>'7[.IM\߅Twx=~ˇ{%妙cb5e&;[U_UV@xWŇj "*<*ʨr!XcL]ۭv{o/'O[ t%wԾemqbϞrhl<󷊂.yóc~od~;&i*ZEčk @&FiL6V tA^(giXػ(F]�4X"ߛvw7^\6ヤ81E.!CQRR۞ XY @@{M4H{n*/giXػ/|,Bݏ;x";;v<G-=m܍'?G�K?4W F;<ׅ<8w[qpyޭѕtadYTr2F7K}̚Q-QGmLvǦz!Co�׼}�_~zVb40odAȻuzvZigoaDLwՕޟ*.;pr4tU令x WlܽK\<;seI/l$2$"l}O-Zi6.x )rVWʕz+*ٽU5�*\VRdUָE}"$ȨSl@UGQTFSoedcĻ{ " )A~tee_i@@QPE6&JR9K\JUIkx~Ӂg{A禙cbG9>G6U{Z?_vYkl6ɮ  7]|$ؓ8!}qDt,l]"D-s1iQ;4LevofN;l$C*k3Wz?<+|7{|=mmLvt@'!.\tH;ڛj ed"-_,w:q!) hn*\l7]׈ |Lw�R§jᨃF#I{�l@U65c8QOo<A}|yoǗoo&,l]JRVRWɕz+*ٽU5�*zS+CXغcҙ^iLp?scbJe{�{2�>e=)~֞?kPi6.WZzS+CXغcҙ^iLp?scb䐪+m/QH�}sq L̢ꪻUw_]56.7WFˠx88!TEER\E2A:B"&Ȉ/5Sa,#YSc?]ncV?D~Ɲg:غ]wU b뛉4 5A_ Rll&aAƂQJ"nET˚+^} ed!@ro|sjul;SZj:!M:2-8a2;*Ųn'"iTn?dW0^lMmb}WuEv 5iͨ2GfE8^F\yGtMt]}Ld5rmHi +c'7A˹0lqnWdU_5d02z�Wc_AeCH쨊Қ 52~�Ye_AiCH쨊Қ4U?L-,l"bشͯxyEi6E$"쾴տv٦*gdi e} R<bQ}c_ ̊mH;*$9;"/żnr¾^dQg[iBVHIPUT>QG!B{uuf</1'Lco8( )zB(DUdעȪ"h=U@%QB?n6g!O6&ܽk`IfѶ�+HqX 82: -]ɇSd]ӏtCNC6ZCIhmL:"}h#hjy;5UL,F�RdI7͡lfDPG[M4%ۢ.zWJ솿Ի);Eϼ ; *N8ț .1"nWk))v{)"-5YWMGvED48V[yuDE-ttTOq܂Y]?72+;8(`\ISqT]SSA#2Ӫ!"QC#.<"[.{;o*!M:2-8a2;*Ųn'"ii)6kuT$SD͢G�DUYNlӨMRühUY[5݁"žd&q_dPB4UU"D${�0vmgyN|Ʊ\>}ƒy2FiER3%"N嶛k+1m7"PWQWY6ĉ@Op"DCC!$L>OiϟNm6w'Ϩ gq6Dt쨩/>HTO{J2'ڨWuOz pühl y6h[&TE^>z]?/.{x~}S~z]?΃zClK$|9p>+s~ܽӸuwCBx4%LAGSS%U;;6(+r& UB|Yw^軦I~m$1ڊ덚cP׉ *�^F7[n}`YIDDD51!71c�4�fޛY#4?DAֺӿ[\Ohed7>MlK,~e#I!wH_{/ƢmuTA,'^Ѧuge2dJIC }]R%i%Ep-ӞlX7v4§"qkW\l'0|y)&}Z< ;kQS9Xיr̞;}{н'8HR5d99^+$·2kͷR<4tq@Bo#n3لJhwm9,Mr_<Ә FqBm"Zh91^táیș:Jg6:�myA쪶\AK`TضXH8ncGm/D`8^pb0_^j냿Qi@K>voy`v;ݯ{v|>xmʆأ#1FV5MKG]GGElfdmM=4yҺMN(PhمR,! *KI-h4I$Rv .F^C!: {1@1"7[ 5*  b˒Ls'7#Oa}N;wTGMDҙg2@ jJHDMOW(TS"+/D-بWZeշY"$UQvv$Y- 'IiEÓrnQ*_ 8Pؤ!Z%TQmUp p g~dnAVH% O<eȎ'k4ԡ̖4Jd̒1:4D C˩�Wڄ@󈥳9!m-= IYST1,6BH>ʨZ.MtK0'flMƐ8ۭ*QUԨŰr9G[A UW͓j J)˰h9;~MYWȁ3tUkQ̈~xtIq8mbIQT| F$CW}�W_g?5]3(:y69<,F/h2$(R>Dؐq"J:e>&9t0K!MDa</\M` \3M;e,xs CN`.Gap Q8FĻىc,l#M4Sɦ6Kf] [D<n5N"4T5U/VޤطUQd&Ew2N<UvT|'�-U4rn=e/zAþ6}鍹 MoDIH*4<j0& k}Sd-WB8$ɍ#!Thqw ,/먴Ր.^_u;2"Jl݊u][u"EQUgbENr0@ƭ)e@XT+[j6W˨M~,E DCM"u+r!f InYydx_fqCyZy}L2$aqZ:Gf|o�W9W7^mu^Un }GԟL*qe$A%7}3Vq|w\ߗo~>%S�X:Ŵɘj~,FA!%$_]w]շʨhV.&_]Qe_C;[1} u=%뼗g={Oɪ0za*Vea\hE5E-I'-g.ÈYQƶjW- D\UXcIUEU{ q2ZzSc*եs;/5*0q٘7ricg'~A&[2Đ:E81{:`_AV &ղXv r\t7&Y*�`k{Wu*4vI V#GqlQ@aDDDOR"k'n?U3KdLUU8"NUse/25Cp:DoeS%; 5 xhC{`5yUT@SnEnc*էgV{F])s. q2ZkvtrvDw:gE!TM_'K�x�޴vYq?FoK*I`R`;&K|E&TQ[][�_p~ɟz�O�R~G==Ǥ>y#xOH<<?oos/۹k'꬙�UdϽ^w�kьrۦVL %ɭ;S+(N >(qlo}hgޯ;�}U>y�teb?ܞ�"V*+r]kS6vv׉dU7۱ukLOЪhU*7,`٢$$z4~Sc?O)G�Hi 鲫U?cN Dl]q'Qč XXvqf;l#] ޯUR}̋(õ嫇Īoeu֚_O}%vUTs"JWNhu֚_O}%vUTs"J9lC4:Mr/U'Ⱦ;OO}%v!uꪓd_I@U'Ⱦ;N[\UI2/ꪓd_I@-f]iEP?iUI2/Ӗ3C"UR}̋(ôP?ibZk~>E}UR}̋(ô 5ȿUTs"J>>Er؆hu֚_O}%vUTs"J9lC4:Mr/U'Ⱦ;OO}%v!uꪓd_I@U'Ⱦ;N[\UI2/ꪓd_I@-f]iEP?iUI2/Ӗ3C"UR}̋(ôP?ibZk~>E}UR}̋(ô 5ȿUTs"J>>Er؆hu֚_O}%vUTs"J9lC4:Mr/U'Ⱦ;OO}%v!uꪓd_I@U'Ⱦ;N[\UI2/ꪓd_I@-f]iEP?iUI2/Ӗ3C"UR}̋(ôP?ibZk~>E}UR}̋(ô 5ȿUTs"J>>Er؆hu֚_O}%vUTs"J9lC4:Mr/U'Ⱦ;OO}%v!uꪓd_I@U'Ⱦ;N[ 71c�5ncvuY2\dԹ /V)+�]N{()L��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������krb5-1.16/src/windows/leash/htmlhelp/Images/Leash_init_ticket_advanced.jpg��������������������������0000644�0007046�0000145�00000121115�13211554426�026547� 0����������������������������������������������������������������������������������������������������ustar �ghudson�������������������������libuuid�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������JFIF��x�x���C�     �C   �1"������������ �X�� ��!"12QU56ARSTVWqsu#b$3Ba47rtv CDƒ�����������3������!1QAaq"2BR#� ��?�?DZۗUHeV^rǎN(ԓ4DF 6usNx:RiiJF}er2ʷWj¥xT|*txЭ fIg�ӥQBnͧ V)-F;9;93iU8ixAϡC&Iԩ=k°FDZBF۔[Ѷ ڵayV[*JR -⒞iRKԯSMFw5ξNiy ξNiyGvP+unIV^n\jA(uh&2.8Bu`neMN.9(C;&:JFFY23d4z!k[|Ӿ|Ӿ*жhˬ;K\C\U˂H tHI$LbVѻ(ĉ2TǗ םBT+*w7827|Ӿ|Ӿ3{Σ{жkq*vE1M8*YA,XD2Dq :u z]RمnGrPFu8jR4+2-632URX";9;9q>,wuғ4)s-enjOFF�][P cO79"cSd􄠲5,v\H4˳nI,Y:9}<7:9}<Q`mzVE:֧Ɠ=TتŌ󬬖J )lȓ&ᨒL-3_`o,$i;9;9K_`tK IJF6usNxn6usNxRiF6usNxn6usNxRiF6usNxn6usNxRiF6usNxn6usNxRiF6usNxn6usNxgK I;9;9KgK/&_$ng_'4g_'4./:~q|D|Ӿ|Ӿ$~iF6usNxn6usNxgK I;9;9KgK/&_$ng_'4g_'4./:~q|D|Ӿ|Ӿ$~iF6usNxn6usNxgK I;9;9KgK/&_$ng_'4g_'4./:Ӌ$ll%?/:Ӌ$ll%?/:Ӌ$ll%?/:Ӌ$ll%?/:Ӌ$ll%?/:Ӌ$ll%?/:Ӌ$ll%?/:Ӌ$ll%?/:Ӌ$ll%?/:Ӌ$ll%?/:~q|D2fq{LikZn%$Y331F.kF~r)Q|DeF6KzKH?P*DEVe[RTiZbtgR[u(J3#�<q8�3|oɩ6jņs"3+?v=6z݊Ǭdꅇ /)ȓI)QKBТ5()3V Y(: &/ IJT*UG-$!iRRJ"JG&4ǯl]V:|T?/ǯ^պ}_O_nvVw[}d H�c�wG7�?v#|e&7�FI`znZvs3qFڛ $\ugIF4M_IZu%%P|u*smjZ0[Wÿgi_|B>UNu7dA‰Ze>9h5ڼD3qz{iZkP)_жqn٫H6=Z5E6v'RgȸgoW+wЇMInUT$VG(R{y�qov)fOʨ^9 9%iKK%7IRRH֤ :K2g6bŷ:)2KRiIKG }tߴ۾Vj_< <z(\Hi݌W< [G0q4igaWYE}ʩ8OR$ГWl%jtΛ;w!~~n[T.T]'2NȨma5j9n4.m(I/k[ԓrݗjf@]4TjRS&萌",Vii?|B7'vB*ۻR͍b=M>R)aZ* ZilYQ:�R^ V̷Zn&f.i6S#RNi4+$CzoO+wЇMIn4]c:O'=z#}L_֕rݦңP PZ\|7ԗM̚-e{ 7'vC}usՙ3o?:H?s'MIni?|B'!}$A!:oO+wЇMInb"o?:H?s'MIni?|BPM~Ii?|B7'vCՊ�` 7'vC}zB7A#|}tߴ۾VV(B&G?ss?Btߴ۾V;w!DHt~N;w!~Ҿn[=X�a ~Ҿn[:oW+wЇ!}#9!:oW+wЇMJnb"os?:G?s'MJni_|BPM~Hi_|B7+vCՊ�`7+vC|}zB79#|}tߴ۾VV(B&G?ss?Btߴ۾V;w!DH9 oW+wЇMJnb"ss?:G?sMJni_|BPNt~Hi_|B7+vCՊΑ�`}7+vC|}zB99#|}tߴ۾VV(B':G?ss?Aߴ۾V;w!DHt~>;w!~Ҿn[=X�a~Ҿn[:oW+wЇ!#9 oW+wЇMJnb"ss?:G?sMJni_|BPNt~Hi_|B7+vCՊYewˣL_r̯K~֟"VR r dF:Cu,)`pQ6UʹI>yPhqtҤ`q2ަk-X)j5"=),/.ƯƪJQ_<_*tV=:X*6K1ҨUG(!g2dQdZKI7j'Ž;k_ċ^ZuGc؃OhT,hyfdeX7 w/J<E]U'~߉NM$bM�_8ן؏~Db>Ɲ*gF<?;�e����������������������������������������������������������������������������������������+ zzLξ_8|=;b>Ɲ*gF3w詟A(O��9/\J$|K!`Y?HKLr(UJJ\Ÿ:E) %wD]{Rz]N֔`4FDiOl&x,%DGČ\o{^T[5B-imZʦzİz &~O< u�~biMvPm+%iy\H̏Kįj"+Vyު)TS].f_źH�s��������������������������������������������������������������������������������@^>~=> /O[]R79ݫ�_v|ylGӿELFucN3#E�2JVꌶ a:ݓ%mR8sۖO&))Nd%IɒM=3#3,Rz@,Ң&QeZ%DYKYp,dqlftU lcO:$vꔈ[#_#=9""=$C&Q(ҹ=QŰmժwzZ)S賐viq8Փ,s1�sMMؕ sgYg+>^6nT͕mt{n\D) (^re<x--m]L)Km3#_?>J?"'2E.Ĺ67BvU4B*0#ģ1Pma.AI<q## PO̩g:F-4rEޙbITRţBm5NdE;Ze-"˯+n@[F6FVI#QhW.]Jܩ\&)-<3u#R�8">=kۧf"b na:Qj9RV|$҈NO9NS9 UŚ&*=&)% 4,=)Ң4O;b&6, JxP_Ppنu&T+%M-+ 2R8,Lh clˇ 2D9Ηf)岙MMRI3Ԓ~qtbDZRjpШyUiyKQJD! :e4vX.y8_,Mھ- -2 oHnCm&)dG#Z6a-ȍ,tQ7Ov+Gb\{4TGU(̝h& –xRe9pի V=LwИgNJmش^SG6eԷO*JN}aE5Yq"�{ͪ^Ԭ}zEUCYusS!5٫Q'ɗkhzkwߘi}[Y8ZzL_bg%FXE+_CSNvJ^y9QeyCFJT#^Zjz-_[HPVfݤ"a",jŚΥ-QR8iIW<V jUV KOJ#&VI*6Jʈ # *So6VMf$U sn m87N6LwFXe;hmriSCWCi$" *K/�%kRtdIfMtPܫ1CjA?G"%ȘKq%SIKfdM$J>-8ױdũKsҩrikRMzrNri2<Dvß@[Gu me-Q]E$#ew%mɅިȏ&Qy 9k<fQhu&Z %%I3!v~Tb\ZZδg1kk~Dr:ԂJ3_g|]'.˾j~iiBKEcivwM̆ K.K4\h$MJ,ȏ.fm*rhʗtQ&I:a=rԜit]�o?Z"Wn -%ű̍MBLgS1V6'"UPY_B7%?![y[eTۆI‘ȭ~fuUd)nEQĖZuia':dgAWkK[MިKE\qdɨ4n0 [էVR)'aELjrY :ult)m�i Hըω( "ģ6Rl*n81RM쒄<QGbj'<SELkJ$)\kl%&zX!xWxﵚuYҕD!UC E>IX<vcxVK.8z! =-11Dk5JF ǵlJ;>3S&FadE632JMy;fe{q?aCԞm"t}޻3oUd;#-$d/ɥ&DiV ȲpTT[ݢ)F*O pȐ pnש\TkoΗd*L4ӑ҄$ k&P5jp=q)EmQڂ܈fɻqɃ'H91m7CGg`2r&A\#V$I<`˾?*vʽN6 CQ.,HV설J6Jʈ #2#]}oY*K)ڌ*Qq[HtgRMjJOd7Zɫ.MM ku9lg#! MRNn$N,ݓ8h;&6q*߼j[VUbQ@ÅBW|F}CEVUf"e2ۛRLQj_Jo*Lw$걔ɰ6y*)"ƧvY[7Q8 ֛=}sq7hQ؜kVqʦ@ﺒJj >8ѭA)ZIM'1Ĉm+y4n6XYX&&nEX~ܡNGK}rJ葦&'/8YKMY㎾=~! b܄H%4)[m{2%I^{3pMGjrD5=kZAJl)fBlS%{sMwE AK9%o7Fgkkk,2^vq9F t5Ө8h3Va2QPz:*o$YBXuMp6gbnyҮZ:[a+IbJe.!ki5I.IR+c8li y5S6oWFSe7D= m87N6Lv̱^F=-]6Br E+.DS.ښJ[3&i%QG�+z��������������������������������������@^>~=> /O[]R79ݫ�_v|ylGӿELFucN3#E�2��aR-T)k^K Ƥ+$g|0 ] ٶ]jSN9=ȳ"&DxiK� �������������������������������������������������������������������������������� gTǰ'}3W:| -w詟A(ζ#iߢ~Qh?c��P����������Z &)L bԓ!D%9ɒMIɗkQw56 rZ-mZTiRr^(#!mbܓ\ݭ&I*.>u=jF^[f~,϶D0e afTfń24Ny-&Km3Z;,%)zIb_ Q/5vY_aԪh&2C!SIZ#6MZTaffj<AZuYSڕj!ϗeSIr؊s Q%]N`HI<u#P'H E٧"Z\뒾Y,*}IYDuVFdx,^fMT2BQڹJL9ȐzyIqDC>ʬx Z5 EBwXR\YZPd-IIS.7dv-"SOu]IAYЎ 8ΧDYɚ-MxzVn]5rTƦ&N;)҇V&\2%)GŮ}r|')QP&Jw.H- .(Қ)t޹9e6^>ycfзں(o ӥ&.;c.Ǯnax2qTBL9uË-)iRMDQHzh H+OFSHSr qG o(IK:);1Ӄq{kz{kzm:7[_/-cЇ[_/-cЍddom|||Bom|||B5 Au=u=@-MX!X#Y�7[_/-cЇ[_/-cЍddom|||Bom|||B5 Au=u=@-MX!X#Y�7[_/-cЇ[_/-cЍddom|||Bom|||B5 Au=u=@-MX!X#Y�7[_/-cЇ[_/-cЍddom|||Bom|||B5 Au=u=@-MX!X#Y�7[_/-cЇ[_/-cЍddom|||Bom|||B5 Au=u=@-MX!X#Y�7[_/-cЏu;flX?qǚ$3: Id'Æ2y-s?R@�u2}3W+ Sz}ھpj{w};T g[4S?(4Q\��s(����������'"?�KAG�d,vr˯ЙuR ;.*\_'[l$&dfLГZL{{Gnػ/ߴRDkNmmuN DNcɘNR ϥksP|<Z O4afl'"7smԷ\:*F7KZˀZ'*mXL S/tQ%̦A4,FhWxevJ瀠yCS"DZLhϣ:]f%I`dszv#uT-Hr\tʎo2jZx<(nӮ=)b54漚S&h' z|vXTG0nܩ<Z@H9 MjґT1 TVZI%& QgC˰h4;YǪK3I~BPDk6oQ$̈"nH9*Gy`nՌ2=�) n8ҿpZPF$ֽF5XnnzQĩhLC$TdI32"|8^t*Gy9R;x~܇oTP:N!ʋZ׍ *I+*`%јvd۴Z;1CMh</SIj-'\"ʑsūT-_ȸ \4g#nu{OoWc}Hoϔh–k<Z@H9 }>:ߟ(?逆ʑsūT-_Ⱥߟ(?郩 }>wj#W2.74O`C~|DO�k<Z@H9 }>:ߟ(?*Gy9R;x~"C~|DO74O`ʑsūT-_Ⱥߟ(?郩 }>wj#W2.74O`C~|DO�k<Z@H9 }>:ߟ(?*Gy9R;x~"C~|DO74O`ʑsūT-_Ⱥߟ(?郩 }>wj#W2.74O`C~|DO�k<Z@H9 }>:ߟ(?*Gy9R;x~"C~|DO74O`ʑsūT-_Ⱥߟ(?郩 }>wj#W2.74O`C~|DO�k<Z@H9 }>:ߟ(?*Gy9R;x~"C~|DO)4i6 (*]xʑsū7#5I+&_GI7\b9Vիɮ&$7uIo)y("#3.\a�zzL=o}uJ{Tށ_v}ھpcN3#E};T x~'wW�������������sd>Ԯ$Ȣ5}>J[.ruMcHN4gcGZ~Zz:$1_ƚNC6ud"u RyInLL!5 5٬Мgq|Hy!S. sRi0RZ92_7T'JJ(S4g}U mv2zߪpM%ҦBL0؛3i'ʝAOZ6�Uv22L㨬4 LȔ,RuI82YbV>5[Num%a5y u M gHf>ʭx0T-&[-k]fziJ7_$UDZeN4,:N,]7J= 34ipdFfDjO'af]()jfyTV;4MDVwGk`Oim8LynTQ̋&xIpI`zGIvыr*䪥e C5%!'VLg3Y䋝i5 .2v9S:ZCW59_7҃j2Y&S*iDJLg=:񙶛Z-w)MZwܦ4crJK;wF{xѨ8b]{_tU„'Xz/i=,joӕqgd|i.׷m-Qn)T$*SI֗rH,qfY-Y=$:϶�o>f&;k|Ty qfK,{p=HM>J~ԵgƁ&MhfRst0Q A*KOnj۪ >չ-:ߥT'27CS"7%ڟoOoQ: Q1hҷD.[iF~G[b,elY=ʛ&^.m%HHh;��6s:$ϱ j.&BɶBiJRd5ݣƷEhDVv*&uIbUOwjEC%Te%PYsDKR{n~Z4Z:}~R)q$ɰyIA0nD2^e:3<o?H8 $pʱPQ۱4o5=YؓéC+&O-8Z){u=iGRupѸ8aľ ]n@F<k|_|Go`Ѹ8:7[@F<k|_|Go �q}5pH$�Gn/#Ʒx Ѹ8:7[@F<k|_|Go �q}5pH$�Gn/#Ʒx Ѹ8:7[@F<k|_|Go �q}5pH$�Gn/#Ʒx Ѹ8:7[@F<k|_|Go �q}5pH$n�#�eNx‰YWeJS ʇYC5`%Elώ{E)/nϏc@%˚4%cGrOKIVIj=dmu#v��t;i{,KNDݵ9H ڥJS[/9Ԕd]N%�BzzL=o}uJ{Tށ_v}ھpcN3#E};T x~'wW�����������]^Ҷ}bW:KtDՆqc!pIJbgm&Ϯ++3-rϢLr ,BJfFՃ.Dӝ]aٷﱮ{D]oNcU^7O(Ѻ׹&V<t~Qc?d՟8%I)QVl%;$/6IF\Ev^n#YvgзFLM@Iw(xIe-)dF"3#<<ͽYQ$He5s›A>.ZVJ'8fNU%FI5I bsaPTWRܐ\N ө,WnZӒNK:a>I$54Fzȭ/O#�*WO߉@Γ,߉3/1?�b~O߉@i1?uFwe'�@O@4;2�uFwe'�A LAQx�:;2� & L|�Qx�tsTg~&^>bL|�:I93/1?Tg~&^>b߉3/1?�b~O߉@i1?uFwe'�@O@4;2�uFwe'�A LAQx�:;2� & L|�Qx�tsTg~&^>bL|�:I93/1?Tg~&^>b߉3/1?�b~O߉@i1?uFwe'�@O@4;2�uFwe'�A LAQx�:;2� & L|�Qx�tsTg~&^>bVy@4 *W#_x,e!n[��b H� + zzLξ_8|=;b>Ɲ*gF3w詟A(O��9��������+Ӎ*,>SwN׻׫rӌuhU6ɲ6^MD$pQΩ pD|d k,vY-,])ҩ(ަiQ +,JE5oGܧ䗗}�} Yz-"[aWMGS*4$H"8ܴ))VDxJH6~z%iZZ-ۡxi*w*C_R0.JW�=IV ;mYj߯"%B E3r$BD3m SiQ*A�%fJyOՙSq)kN˓-6T>n$%:FgS#�ȿ?<~!nw:J < ILR4NxӞ1<ӂ`tzs'[Tzp_9NxKp N <byӂ`CInQ~O0:p_9x -*=8/ޜN <by%GӞ1<~O0!$�zs'8/ޜ<NxӞ1<ӂ`tzs'[Tzp_9NxKp N <byӂ`CInQ~O0:p_9x -*=8/ޜN <by%GӞ1<~O0!$�zs'8/ޜ<NxӞ1<ӂ`tzs'[Tzp_9NxKp N <byӂ`CInQ~O0:p_9x -*=8/ޜN <by%GӞ1<~O0!$[?Ezs'< q45 JY8%x !�u2}3W+ Sz}ھpj{w};T g[4S?(4Q\��s(����������������������������������������������������������������������������������������Ϯ_`O gTǰ5Mujݫ9[4S?(4QlGӿELG~up�̠��HnX՘+2B r+z|YKЇahRFi#3"I *mɳcyTiQ4C-:eܖ%9>Q@i$sU ঵>Hp#I)*IҤLdddFFC+n8JNGK5Rۊme"> J= z7鯧MoAz\Sˤc{q仾U 9%J\SJMd,Dr$)< =R\Iӂ$Nedoĺ6jaҖmۋ$ՒMFG*<F~^v5oI䦙ЮɶԄY 8юUmꮫBVw֩0L.ҫ193!+5OjܒdL$N7h^۬M%S:*Q48c))QGmf2"Ln{z6r.BCj;HQEen=n& I%J%x#x锅)31a),.JClɤc[S9WhYWkrcQa"yQ:%(&V$Pҧ2qѭ˦#U ]WTZZ4ҧբ) ԄoHyʉ*iR$Zuh츛ijm;Ddy#F>XWS69ˇ[MJ9CS -DD[+J{YbZƅ~ݑY|QOE*yWϔ9+c?೾%dX(D6'e؛~l:DWhN Jw"k%:)4.xjƬ3č$|r/}M]}{|EΫm=;zR҃ݴ닉%+FzTdF|t;F%mr&4nUUEN GjV:*KUD]m+V[ޡ;JjI'蕘wR(5Ha&mx2#,,se*9FRJIEBMRͶN4jI,´.2ʶZ*˶:I)YBq320$2(I#-k?nOYKSyu V0TMqn8Bx/h3QhDffdDFf0 rZ*ff:j[raT'L-EL+2 xҞdF[+w#v5RTX&)j-Z FTy2-D2U`Wg?xr:Rp@rZL”ڴ#4FEg#ViOmDGzm.&"SjJb@-Imɔ,m: ,Ls宛]*DJTsTJƔ3!K$*ݚQߡܫ.SFnM2m=醙*Z,BiYgVZ8hbV)ǻoVcJo+Z 7ۈyډhQHFC]B+s-&cG58$ȔOlȍI#?kQw Z5>UӴNZtY/έ�\Qj#%HVz]ޚTPI)R^oj3,*_)ޑ`d]kT-s㒝SNx]y,g7O%iQrzTFG/jrQwNTpt>ZڄFa\ғԝIC:ם>ȩ!4jturեqNlM%[ujp,(Hrb|\G.Ŵtr4ɞ⚎P(5zRD"TD ʣoԊ9K&TFIQ"#"34Nq9:;=H)ڃ9lB3IlR˓򓓓`B|#!v٪o6rT0Yz(HT=iJyx&)J4ݯ8Ij���������������������������������������������������� /O[]RϮ_`j?/W>s#iߢ~Qh:؏~D�@�������������������K.�>tHOÙq$6aq ,)*I223##% w yS!\Eu8(^Fg=*Rr^Ҍ% w}% w̗|% *k]݊Q*N'J,(0E:+sݜ̦k$Zj42#Z̋Zcw2]@|w2]@|w2]�}% w8JHԣ<dǧS~�?|tN'?!dttՑJ>SHJͧ!kiFZTiRODdeQ6$e�&g|!̗|% 2] |@|w2]�}% w̗|% 2] |@|w2]�}% w̗|% 2] |@|w2]�}% w}����Ϯ_`O gTǰ5Mujݫ9[4S?(4QlGӿELG~up�̠������������������\Ӹ*ϫS̚񖥷RyI$D̋OF<+-#2>v{v{EnCrnCrS7`\7`\l�@|Pܮxu|Pܮx�hT>yW<:>yW<[�4P*}F<+F<+-(>v{v{  Qu=Qu=`{"^ˉGԦ$K]^J+JfV EJ�=G��njfNmj.$F%H}ErNZp\J`fcƟTL92TU.a Qp"|nCrٵ2ҳS* aRqqjoyn D]p@|Pܮxu|Pܮx�hT>yW<:>yW<[�4P*}F<+F<+-(>v{v{  Qu=Qu=`O݃:sè݃:sŰEnCrnCrS7`\7`\l�@|Pܮxu|Pܮx�hT>yW<:>yW<[�4P*}F<+F<+-(>v{v{ ݡZT)CC%VZȋRqgǰ�i( ���@^>~=> /O[]R79ݫ�_v|ylGӿELFucN3#E�2���������������������������������������������������������������������������������������zzL=o}uJ{Tށ_v}ھpcN3#E};T x~'wW��d hJiS+7jO4&#h"RG�I`)0v.-* ghAnSRI 4wё+S(N-Fz]RM˖E5Hj-ۆڛ3ZM%>d.RmR^q-Gej[n 4eF҈jZNV8O<>}iqӵ t[Z#9u#M-($/ ?(h|oU9V.趍RFRbrĚX[UIB]lk}E'UgVy teD9[@Kx:m:Z#4+)DDEzflnѝVP]-MƏ)b/tXeNFBɧ$Rf)CTͭSsF qʢ]V\ALb<uOdhO'"q!6%8Jf&fmvmѴ.Tb~D"D6Q856YKԑpYFI/hTQHCwTȄ-M}aFJVE!eK|8} v2N)+Te8S*YѭDFm)|O#viN~Ԏ}硜*-z4~Atv`Ҥ5tJ$4J'4Ԟ7 ̩JשYт#2^QUoHD:b)6f96$f1q["$^l+RE ӐIbxѻ76fx<d~wVm{ҨU ܒ47-32jKm-)ʰII”X•Z/AS#uݮ/jV{Ynz. '0KCLfڒ_HBTfI,`+mL]U1Vf; n.-8sRiJRX5*N}=Vf9X^DF ,6sܸN)$E$ckac4ӛmm<YSh{oN#JV:6%IM?T=jDJ|eDSk W6͝/He$꒨4d2ɠ gl5k[em3Oz#/�[ݭ(Jڙ#,FNoe{V*}5Q7|ӤOXIdFYfkΥM GTʋ*zCFI%鑺–dJR$(̲g"~Y3E94"V8K#I,O&>@�������������������������������������������������������������������� /O[]RϮ_`j?/W>s#iߢ~Qh:؏~D�@���������������� b+} ص1βX5$)9 R2yQ cUj4IKO,LLZRxsƗ*-{wU)/Ze2&Ƨ",gm,Q-f0PKRfkIg]Wj=ƛ~աí[R h)JKdkC/)KYxI#B]+FZl(6-LLEi2IkIF(RJ3RO}Y5*Z] VeVp>u)jBie?\JSxQ)':Lyҋs8Ҩ ]ijel:pI2d&X"V&zJ)R6s\6e-Rli#%ʌF-=qRv,J1ȇQڥx[iZE"'01ٕu; ܩT!\ZDq{-d[rytw7rYᴳJ%FRi(}&ԣ4xdYJD(ȲE#iӪLZt?--A7eFNK&zr]ٝFaàOLmƈԙJ֕2/vH_IKWaBv OKcn GiҎޕw#֔VO[Ý}ܧa5gncYyva[Iq릓%Q'Nj \WsvteJ3$+YiYOxJ4~9hlR3}znK~,4E>T/'DSJ^iSPIcCN~6[^TKE*5!XKy.g֖]6VmȰ؝qijvϿ/eMJ`\)v:M2ggvg iʈ<v\-]TZCfݴH3cPkH5i#Vq{Bh쒵K>(Mi2uI)QI6dDJ dT|n LL:^`q[ 5-.WZ15:V=KI7T+ąxCt19ayl*(iIJ4#lJ$Z[j=Aʫ %">g!F5-zEq BVm*$9I+=:ƽxh\bp(0]˙I\3Mau ݛhN;3߈⪴.՝lJT©<u"*Z1bJ=,S{\Kթ]\ d~،h/ڵz> ؊%͚5ǖwMX5(E33\ ۠{[v?BzuU(},Ҧ7+#Q1Ӓ)92۴\Mr.=FH>d[Zm,M$n7'9jKe]/6#_ۚEL~Ԗ6M#z,)<L]Qmߗq^UT%PTUJғ2q"KH%+A(ו- -%V5JRj)*r$W.<j|@Q4TW) K5&b* ,sg"En$eȑmf&H_O|MW| Yjϭ]ڍE1nOڠ4$dfjXt>/f3n*T8Ʒ_edՂг$ܙ e}ՠn:0uJsEmkƘre=}#.&H3Ҟn@"_"iy-m$#'PZT׌nc;7Qi&jQdLT{‚j72IY(ilXYIdd^؂m˫.f*E먪q帝ҖG -{j.6ʾNUN*:VɺKQI(Kg.oK¢R52)䴺-zlVtImDm2۬:h$HƵ'x}v6ivwGQ1*u&FIaY=yK)%wE6B^RTƘ=V -i% ZQ`KHƤ5:m-ԧ)SPMwwSN\ͼ"#Л6iWj E.&6ASX4Y#>Ѝn9RMyl^t -: $S%!,jABpķ"y뢓$Ob-R뛴k-2Q$,x1ͯ@\ڄH !o20N9[moLI -J})[~b4:i5-I arBaFIPW y۱V޼iY;_'M^eHU$/Dh՜`lz&W-uEQe.u zJ8*rʏA)rW*TCVcrЅ'-K.P˹<k>`u=DTb[:F㍷KiQ9/J Ik=kDQLW շѮֶjsڃVi#xiiŧz*QxǍJo^vEVI*r5i#g*!v9V/]͹ڍUlUI?za['JO&\q `f2Tpe'pMMєi62JM",8򂵃ѭޛ_-(ZS*"ܠ{ihJ5G$=l~ѶiNa\4ƕ"5J:S'L,%dI#2Ϋvzn &1ثq%dimI7qFhI~mW`uޱ-s!Mn}KN 1g3%Zs)p"8'9̖g>9YNѪt]%ҩΓ'&ɱ2"Cե ɑ`̏GT{OѣGo)rNOdeNFaU.KqOTj{UI4L- ;SI)*A+&&}KulQb6vs)Mil$D.Wq : 9a;3ß@�����������������������}3W+ Sz}ھpj{w};T g[4S?(4Q\��s(����������������FvPJ#IlĠm;=\Sh/GhJUË!ѝb"'FTDJAZۍNZ\[pFIaԬҜdȏdȳ=vOl޵r^6u"¨\U2o"i&S&$IXo@^ў*S)ZCإ[Eӟy&fdI2IJMģ+3VLiYXX,zܷӨkZ݌ݜAgAIukT8q6"7\A(7fm^z 3prȔ򔡧J Y`LAGYkW'*y mb]ohj*d(}Wq nDSYrRI%6<I,$}ԤI*%%IFiS"mR [T)|'{pM2ꝺ.mMp3Q5䦛48IipSfKSO>Mb֝oD?)I!-o74MVR*u8B |oj3jQ3i[jUB)NmhDOrFF?mőtcerN6_!im58uw[j40kKFɫ JrK5(MU㛂3@m~c859\30-6KDI6YՕؕ**M΃+Rd YO)"2"Wq:i,bg񄭌k1.ˆWv>Q.K\IgQ8GX""I:HõJ鱮Ʌ^U:iFQ-W 䖵)*t +q'f]kޮ|#@ddۄTj= 桧ej2hf#JO žqE%FUm5k*BɇS,TrhuqdAҴf L[@�v}R66Fڧx DqqۜS*2cJ-ցꢫ\tzJjcrD̦JB T$ GJ:ń:%=r׌ $SVBݰtㅣYw $,нTU[Q^L^JS)3iٺJDGsFRV%vg@�ڜڶêtH!;i%c NIV$J*J\RDdY]zrɣhU6S`Kn4g3<��S_<JԀ0;iS6IĚC!.-&SLz%*5AKJ ZDF.댽ƒnU\ Wj?,fҟ4)&M (%L)sՍg^( z 6KaOeLʕXTsqR ލIFj"L̿:WU]0*[m[bM@K%6Д0M8%,IJOOjws4y(mmGR[o?Ig-Qo?⧃d-DY> R6Ui+rK5ˀ%[O&K -d̖dhq$fJ3UV=F8ɝ]������������������������������=o}uJ{|@^>~=o@sW�_8x؏~Db>Ɲ*gF<?;�e�����������������?DYKn]A5WRU)+B%H2IM4irm�bP٫TcFI*2}}qƲmB\hQ,HD ݳI&2!) ̦$@+ްh3JLg)3,ci׫(Q[-IetENJRZR6k̏ ȌFďRvc%*e:D*Bq{d5$fZHԒLN [9(-QWDcD!mne'5)GsR RDfBr>ͭn&̊o-&ogzMfmoIK+.zK*d =+i223%%I2#Jdi4dddFFCLR:B7+ԼചL'2'I[K'ˤ?cU33^ dtHmQk$j#>#cĤ6j{<ZSO6YJ%I GI5Jͦ%F$$"4d.:O%%iQh'G™^XRRt);4%92حqk> MV앦RN,IK.HD^$ÿSBz%V.M3䛊V8fNVmZBRj>'I֐,mn!֥P3FDE홑@+.ʬ:Ҩ.\'Zf1$ÝE~LxŢMSMyL֙*)z D3,(] ueZ=25A3$6֓K.%{"Hҵ&Fyxp<K-im&%),BI�-v<JmVyT$CHꖦ[N%ZJo:ψ&BΝVflpƨIfI2FCʔmFh3]"HS.J Ɵed8,deČf2VOh7qy+y[g('YWbX" JMALn]>RdZpCd&x[A`\;bDG^&21jCQhmY M#cldc圚i: +*d2J5o%NJ,EXv!fp.-ץ-Nl9:BluEܒ(d&g/`3 .mFе*mT`-"Lꤩn$ۍ=)C$-][J}'A!u*LD" 0hA�8@WkEe1*4L!UFJINId┲7(ˉY jsk>r&"wwH� ZЅa4 �Ҝh V g46yL:L]eru囙ֵ:)jYYVkND"YM\v-}m;N6�A%\ 9xt͢ n&8Ty {pmֵRf3L[u$JJ"ZM*� m?X!j W VJU:Kls[pkթ'Ɠ-8"N1k+ eQnkQmKR<p7VyOW<$@~J>;RUAP3-SP77�<j];^3DصNӧǦ:ӰeY)sܧCK[:n8ҥ X�].mX_iRʣ)FK֗ !NX"ZR:M$i)ty~@-ʋyr&J6M쇖B DD3 N�]}mh������������������������������@^>~=> /O[]R79ݫ�_v|ylGӿELFucN3#E�2����������������gDZsd:%QM2DSQ))5qq=ԖɗwEJ[h$SI"")]{{UiRd*A8J{k}!DjVZDRKU}j[ORoQ~-Hi-D)*SjFPdP Hum*Yt^9zqd\*LV)(x" F¤VTddZwOhaWR9}L>7[f–RФ JRTf՞Mc=g>mUn垸N{Z+6*V੅T)ڹ>O�)o?h]"SjU":q)8QI3:֔*3R@.-e?͚+j׽P J@KDMF˧-dDޒdKd5ݗg-w4s(u6G!qNGw·#-$lzw�_O/˶^˗:'`F~LER\V"FФaE^(Q5URt)\i1ًYZ&mO&cNPѸF٫)5 �1TnWTqۉpjS !Yqfs"B*MR;]dwF=|S8TT5ɐU:z--whZJTډ%HH^'�cyzۍĥb4YKe -UuZ"&SL:نRQHɵ*Q*ТQ#)]VޢE33 ć"dҝHԙ ѥGÈnZ<U3|n9ǃ~'n?XB_(*z R\ˆ�QcxmFۼϹ*pW (052un38b<Ӌ̂NT.ώi>S ,sO56{7#iv:ظ&M^2RM?C4vA=,jqnA0Fֵ):7fA h*>\gS(E6e/J,o:L sgPQOi5x3V)f1%!" dx"%BY8>*؇uD,UkҩilSZUbvdޔՖQ3˸ wr}jۛ0pa?[ ˯ˏ<PN:Q;Ry. 3ern4y.ZT·=Ӝgy67?_Q�i/e~HڔX6;w"+jqʌRPdeRkk$t$@[ �����������������������������������@^>~=> /O[]R79ݫ�_v|ylGӿELFucN3#E�2���������ykStJITddx2<uhR+Iz@rEy=eQ뚣RԧWT"UnZgHuK48Hhxr݃=>ZcFM IS;ޓrdCK"%ċu-֌OS7�QR͍.,TʭIV593e4v>7 50}#-<K*)PI2d/[Nr5*h$jW$hH##n,OaH2>W�f{OdIS*ʍ.*lgi5i0ʌFѼ"2. [a6Y#6V-pqS0`RHғJPdfX<gwGU�S-4Di-MjqfQ`\9<eKhQŮ͇P̍nKs$!nIRx2A'*peZրf1ei*fMQp[JjJ̍ idfHQ]i ]Ԩ&-M%M&s"I nȐiB[ =]$p bY 1:+&vy/y#zq-GQ%%ėchuZW=PfPSzUSwTU$u8%kmo!I\4t.kgj,c9ހfB^"\)4fG#v+qa+`jQiCj-G 1.2:TbSNBo4�)ě5t 3N&xPU:^)X7m^{B]S[PH3*ao n\AˀVPsMl2幮|hR2"DT8wXi ܼIY-gا)-\"rVi]`R/x"ޏTK(ۧ%TN3EjSɥJ)3=} mU]bẻqeq+x͓q-8Җj3m.)FBMzX'>΀L*t̷͌>I͢ɗMb릷(nω 53əMe06QӭFR=)5GԶw)k5Lȵ"!4M{D|Φ}Pw * a]_$\JOΦB!nȺM&ԢWB\�T=bIv.Ҍ!QՍR^z!>JYGWeFdZ1k ܀c׮ի6l[TQSNE*qc^WmY%'&DfeZe_՛JaT̤U^7p(lSZl{Ĭӎ+7|]s: jm\QAB~NyuVUM_!QTCmn∕')pj{MVLrȭHќ֒V?31чp﷔OTH����������������������������������������=o}uJ{|@^>~=o@sW�_8x؏~Db>Ɲ*gF<?;�e����������[k,diQw�i5 9%gzH$8-jKdM)O#mkIFJ<G-Ã)ɱ':&[2mm$R%.Io:FDFyP[xTJlڶLy)JSb|S%.\m'5gsR RDfBFfmZSdQvLj.JWe"9$sI),<�Eҷ7EI)\i 4mi49IH̲FF+ɭ[[T&2F[&l QCŞg-]ǖ9.H[JxN<&IJH . 38ͥ^[hi}z#DeR\ARfIJ#�jo ˊCfVJԃn. Rn"az3ԂTͭ.%X3#Q(+&y<%z9t`:D4jJCjqn4<FkqaX֬viܚi uVb|RއhL]ԄfdI,$-l==rQT4njTu 2R�GoYjJe|1Gjv)0WFl+a+3Oog1 ͕Jj5 &QQ^1ԧY˳5vX?lDʫD Zw'^p2ӍǷ{UOrKyŽNTi9%- %+*ɞO7`e{{bUj,--"]F.kiCIjy՞ /:De#lbNKKeLV}P6 Ku2Fp#b+unYq= 3&*4;$+>e UQ9T]6Iԥ:d342Id̒I,GL]JʓO):"S H$)\Sؤ].ZhoxhN(Q{fd^� Yw ɭZr:L%Sɔ ,e)L! ?&BXq՚uKxϲJ',Hp"b&ӔgYɬMj=QfJ&JN}SD[-)F'#A% Ƭ2КW(5QO+Dd-jLtOKDSñ,_\el==rQT4njTu 2RƎ80 ZI!I`,@R�����������������������������������������Ϯ_`O gTǰ5Mujݫ9[4S?(4QlGӿELG~up�̠���������������������̗|2];'2:>LS3<%I"q7`\x. Qu=Qu=焼kw2]Nv{v{ xגd*F<+F<+%!! fLJ[|H� 'Qu=%f-*ESpdB g}ZuN2}F۽\+`(b3�t%!z"މ- v+-:,jBˆ\Rx3\HJ|Pܮx;-y.KBnCrnCr/�Z] |S݃:sè݃:s^�. Qu=Qu=焼kw2]Nv{v{ xגd*F<+F<+% wU:>yW<:>yW<% ^KAu|Pܮxu|PܮxK|%!T7`\7`\-y.KBnCrnCr/�Z] |S݃:sè݃:s^�. Qu=Qu=焼kw2]Nv{v{ xגd*F<+F<+% wU:>yW<:>yW<% ^KAu|Pܮxu|PܮxK|%!T7`\7`s^��$-$)i8H^h��zzL=o}uJ{Tށ_v}ھpcN3#E};T x~'wW�����������������������������������U:bQشǜuddI $+&f}2;G3["QypQ-Q$n6(ȉMYˎ80���������������������������������������������������zzL=o}uJ{Tށ_v}ھpcN3#E};T x~'wW��������������������������������������������"LBbgK[5 dDXQ_#pR8]7ޥxC]7ޥxBDtz tz x@{}WO45}WO4$AM^1<M^1<Б wFf>%2<EkVw<`"|Ĉ �O1)4Q!KSiY.%Htz tz x@{}WO45}WO4$AM^1<M^1<Б]7ޥxC]7ޥxBDfU2"`bS\KV))ijQjRDX,d>=>goKJ&%S)_DVX 8&�O2WP:ZG +&.)=-m#�Ti�FJ�.)=-m#�Ti�FJ�.)=-m#�Tj'hl_ێҞRQed32, �s}[i*\5Cn( )Os-iJ,3#Q30�=o}uJ{|@^>~=o@sW�_8x؏~Db>Ɲ*gE^*mEP n##qDdqJ5(M8g%>T؉ صpixOX5,3zץɨfl{Qxc5&?+aoTI:ƓV&j)Q.I9͒X X U{M0Ԝ)L؎̣)hAԃ"RfxID_pRnsC'j,ݛyWfKs@KH pSb+r1ՙ+OqAk&_%q>:KJ'eˮ%$ϩ)jIKtJ IQHI>$)�̾*VjBL =VfR{ӺRfHJϊ{* EMRVr:qi-[jCmI24q%C3l[ -"MdmL 6T u8%iRdʼq UvWZJOrG3uKFR#,gI_8򿆼5wqՉ�ΧP\T)TߘK$#Dٸ()d0D| g,mW**g)ܦ3X@TQ!QQou=:=iJz> Ԛj@2Vk۵J%t W rjcJPf-,x2AXOkmf W&* SJ"AQ`)d ϶Yָξρ_Ǜ(������������������������;wѯsew�b=E9qݦt;-&82rȼLTӻ�t�Ipƞ#?l%kP%RC3TMǕա,!ĚBTz#֢$`{ZN* ;Cs_ǵp$Se&!S6ᖪRP|nD!ՠ%*V8 U'oZ dzZʙ;RLHs Ti4zN-6KRTJ"iǒdJWz2Ƽvuk.pPyn#6Xm7)hRQiFZ}gީҡ̧OLy6vZ &hhҞclԩܪH-Iu}yIdˎ'J0ZDZN<wRʵm]ꂻ!UJ+j1:% <f*.Nq(AԾȒ)r^E#]qcKYe\wvcJR 5 z-xꉩMeڃHԲi顕pn6IRKQ)R撉j-+V ]'6dFKF3%^K,ߜ� 'P(vEk0KLRam Fi9 %jq8j jvecTh ݬ)Jׂyiƕg$6/ 6mlMj#؜Z$4dDxI$l.'el:7coҖ̞mZhZMԬ6(,mFw/3o莵f�Sx^��-N�{�=c��{[v�!规PNZ&ʦĭ9$PS/IaMq8Sfi)ԓ%2<_2]7EK գR\#Ci֓Vۈ2[kI%D} jJs3K`#9eԩ8TJ|,6'Yːj25"Q#ECTk5Wfe`AfRM0&LI9 %jq<fZBl⥣TC䵭u9iJTe%yę!k4 v%^ʭZ-4tf<:ZK*ɨϱ&Z9\:(!FߢPjf.g$!uIu %m{ĞߙaEJvw 6H)ۖ.D4<HaRu)dL[η)L>CEBKQEB4쒅B 86amM/J]A͗5ONzZ�#Y!)#", M&Yv2] |f?�PH�dzv�p,�T<1�__G� #ϱ{ a/bERҤjmJmdp2?E4P7P3O~u 4�*G6Br]Ab\tZWL 2K<hC,k6Ң%%`2}B?\çJMʧ"am؄Դ##uDfHsg4wiuz>T7 +fkBd- BHZTDiZL"222kgAәW1K.D6}㆓B($ܖRs;WUmVjoQ6|ەpզKr>JQTQ6(Н0k..fgI*T,=rWQuPT&qhuHNѫI+NDFdK7P3O~Xqw{��æiTF]7MEVi\GR"J fg(eWPF-<�*?Uo e\�=o}uJ{|@^>~=o@sW�_8x؏~DJدGy.ZY%$F3w詟A yĴi5Ş.&fg!x6WE3d�ּB;OQ-5UND2LjZEJoMk"-UɸU* $-'0puvE վ+mpGe{^nJV3F2#'#>˱fcgy/)A]@K*bST)Q.n#3 DRփ5$F#K^yGqWDkSқHߖG;'Ҟ7q!6o<i\E[ĚS*.qO6˦J($zrDdg=^{=Bo[ D9n4ᚢ # dIՠfIU6 Y-mZTiRr^(#!tԸO̙!#^ T(j[#c]U->OH1HqQin)[ 2i:#ɨRxWkuFUg[IčRyiKfNt)jSМ%GQzٽJ鶇H )p";i"R5e)"233""#bq&,F, IٜYaQ6i$Hm:%QUVO2Dq$҂NNJ5)_ݕ_0mZT+T#Py1┇m- 9QJެjZԈSJD(e%NicI2f8gƜ$?tve[\Q7ͬĸ:)1\RM{%dZspmdɛ6ȧ]o ISBbU*cexi҄' s$"ųK[s&fh)A5ՆE]ʁx"Z5ui16$*-ɗ 3ү>#^mVLrR_RnODmN{f i9oZ to1df/=^4 RڇD,keV1ZFRhzM+HJ.Ȱ=4oSbV}UtIHOK J :PNd^kV:9J%'}V_휉ӯS E(ӔDxN j.%޷8 :$B+,c(KGJBfIR"3Jg}�uTbsP%u:sYoI$gj.��<kUXtTj ǒ$3ʉ$dg#Sktʥ>|iFQKSMzTY,@���-ԣ$%3<NSĸo*+'} JJ2�~���mB-5;.K1[[i+yd5D$Q{fd@@�/l�|@E^٭騜2H4ʡ! JKIJ\$g"f}1h4+lQDn*>}ƒxRuḦ̋S~s~sRVh՗in Y7.AV_4D|{XȺ&kJ 9J 9溄V RYL[S58$ȔOlȍI#?kQwǠ!J 9J 96%4AԢJF~٨Ȉ2!@u>/r u>/r B~ֱ(cܤq$vKVc���)muʋG"SԷ$؈DDDX"��Q:Z9^:Z9^^!J 9J 9NVeWVeW@u>/r u>/r B5hҬ/ĥG\vtpyniJsj3%%XǨdXmhu6Ym$6RJRDDR8wY<V:6Yz%Oi!<gԕ?Y<Vm uloJeRT�p6@ź6Yz%Oyտ*H @5f[zފTum2>S)ř)J3Zy3>؞�zzL=o}uJ{Tށ_v}ھpcN3#׶'g3g&DDar*%4EKICɱcN3#E%mB0kvHεne9$1 yґSum+BIs:wZbSLzUXdj RASFʹ1y8#"a8ƒ< [#W%ێIe=Smn/O<{D9%ssN~ߗ$W_JU#ßSLTH1Sf:%H2IvU{MZM{A;M{njs KL(RKcBDF)Fd:ߵ)Dˉ\J%8"ɭ)X$)$ JHDDD"ЯiJIi$HZ[I+V۩i3J\%Je*SVs{fj5uNjYpDvh(AZT6pfk4R<(Lݙ:|ʅ-jDdҳSdH4{=$I2Q0cSX Zø)2CmԃdLd222###!W'wǶUtXnZ=liDqzlYq#[Y58{$쿈Yڍ ؕ&ZKv!Qg2Zv:TdΤ(Z]څ*=N&piL9uMҢi2RO##.G zl&!eZiIJRD]"",t骓כj 59B6;yP('죦7ORjM8YAQ$ג>-U*hM\Q*5Gju[yt*iK:F2kSp˰Pi#pYՋҍߎUUϚ)]`5UMWej\J+-}TqEwCo(-դ,$5.w^VӚnU(q[1Q OQrw =hh "#,j5jIh #K,^}fe}9wMvv"jeU!)] Z54+Iv$DJ2ށ:"QkZ}.Ѷv"7{#X)0XJUSV > vU8׵Sk+źxTi )uZXg3e:B˚_v5Ţ7|FB9nI\"#$v Z1%9kF3ɑzզ:{Ns*d_:ꈋ&`%)"IEy_jsv{`Ҫ<*mP6ܼTf9*:ʉ%2#9J̔٫ i#N? l@H)MIE0ڢɖHv̴j*a:J[%!VDH %OWv+d=&3apfsJ+4OT*tJTʋ1n:S""^B\MJen5p6SFSZ.̙>UF%>r>;"$RPQ%g/�i#C*t{p]$mf#%ۥ6 ]z] H /nVvz>{$ yi*ʇWƌ]P̳ qIS"^Cle3y N)#o* %/|МcIciLY<RFusijr1O\lUD6pu5ގx4#ZFVԲ2Joݷ.ln]OHD6Zeƌ&nQ6JK{֧V-:ӃQ=ICS:)9JLyy9N�U3(6ϵ |g5(hj:iL=n:{N9d+C5rMR㩊.۩N伀-(Bd)KIҥ ٺKt{E |.gȯ^m:e#i+r|UӛRClnHMw*BjץnUobVC96D+8br3R%,f|tEO/}cQ?�I3mYTz&m쪔FNp)5fM+y/%IQ$BJ5In5 J5&5=fEUy!!NؙJ҃4 Ҟ}Rҳo}, rmtػ!(b=Br[-m$:Ԇh8Nəa_-hR/XVʥ[TLIfE8pBTVt)RzTDDM %uc9PW}AbʅRͤYHn Tʗ%-6Kq(o/70dJ+~p"]fԍ,6'#RYLfAZ%6NȌe"./9gR[>d.R4mZ'T= # ϴ9qj*)K8r<̓mml Et3D]3j#RP[4e(ͷ Fs'4.4S[R6(a.wrq"QT\;쒥\ur&QY1D!m!jIi:bIh T$/]'Ы;4sTuZnqTa%H)xֿ3t \̑UQ !HV)F6Fn>5>uPbtkwȉk1؏ u%iEv(Q6g]lnZuhwD.ly)vhB;.=9 N. JY)""""3"!SlٷSŋ1<\R$Nq[4vRRf ҹ-;ל�� �������������������������������=o}uJ{|@^>~=o@sW�_8xB HInjcu4ZB֖e!&AtxY[x�s\Ugly늬-<U�z�]8 c*<WuV|Ǟ*��.Y[x:> cހNX늬-<U�zqU犿@˧,uV|Ǟ*�ς_Ӏ:> cއ\Ugly�KqU犿C*<W�yt%ς_Y[x�<p\Ugly늬-<U�z�]8 c*<WuV|Ǟ*��.Y[x:> cހNX늬-<U�zqU犿@˧,uV|Ǟ*�ς_Ӏ:> cއ\Ugly�KqU犿C*<W�yt%ς_Y[x�<p\Ugly늬-<U�z�]8 c*<WuV|Ǟ*��.Y[x:> cހNX늬-<U�zqU犿@˧,uV|Ǟ*�ς_Ӏ:> cއ\Ugly�KqU犿C*<W�yt%ς_Y[x�<p\Ugly늬-<U�z�]8 c*<WuV|Ǟ*��.Y[x:> cހNX늬-<U�zqU犿@˧,uV|Ǟ*�ς_Ӏ:> cއ\Ugly�KqU犿C*<W�yt%ς_Y[x�<p\Ugly늬-<U�z�]8 c*<W#z+eǑX>%*r%D($̔De<@Ӏdy30����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������krb5-1.16/src/windows/leash/htmlhelp/Images/Capture.PNG���������������������������������������������0000644�0007046�0000145�00000012270�13211554426�022550� 0����������������������������������������������������������������������������������������������������ustar �ghudson�������������������������libuuid����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������PNG  ��� IHDR��`���I������sRGB����gAMA�� a��� pHYs����od��MIDATx^]ksǵoD.a~&?b>U ǩ- * a[H` d$ HA<3v߽w?fwOOFH]3ݽWg' p}<|4@8 ρ p@8>zV(%M0s@X 95@JI @Y\yK @034@8 ໏~NwWu[MOc.h| v­;@TCR߿re6? O6^ ^ysMpU _??$4/)ipOxBm>svBjbrZM]N�W[{^RJZ Dž~-9V5̯l~ݼR1v)j^|�wν8ڰXGuyx,#Yan- ]P'.ɩ+3juu__;.[/w޷.׶">kNԝ#;@ة>)YrLy|˽%oBъ8ˣ>u?@ϦAoؠ7ع)zgfyuM5:68mpTm߶_9ڈo_D}-|"q]m3'ShWGRcc8y8hp0Bֶ3|"0Qv _iYt{apƠ`m9,FƈRkr<sO,a!r9(½lWOu? Of7_~7\\#]ZZR'.8N<_8lCֿ}OE! _Cȣ& /5A;ա\8OŠ}"A;ߎnslx_,o0Ic9! l}Ȯ�Bv5q8m{10|5B֙p;O^1/Q,GmO9.IiiZ�/'٬�ܜZXXPoVwumNS6AO>6:Շ&ld['nu Z?/}C0Z^W$A6qB70FV'�[Jɽvžs=&iOJ^>lGCn5ݛydD ROLֺ_ }H"Ѭ�bX]>nݺE//U;3; p< T_8-> D0nurqCDM íW*j+acU{E\6nFKkXCie|=LcyCTj ~^6<s׉*ט} qVwiiZ�/OYߕ6ς?C+@ou L4h>- lsguy(Zn,lo-q$:>3[g`!:;g*U(j1}:<a׹dS*r@q?5~^9.]nB߫z`~i*Ӳ筟xN5 FΌ 555 πgjaqQ-s%'E>6b1{$G <\67~Ե>A`yƇY8T{@" [\~;f8 }덎>Lq{%` Nn5_|mq^,^G4_3:*9EQ<Gm7Gb^F&~ŜOkWu? OF*)iF׿ǃ뒽'<& ՚2ҟƼ >?<kbyMvw9퍳@;9HY �T` Z� ;O pe�ϯ<&9 2ra/X�ρI @|J @0",M0mr:4@8 -&9PI?SUۘ.lL.lu%p⷟ڝ;wk)ݻ羚ǗٔrǍ Bpnh^~lE_n`ҟ\4UdN^8@< DO�~70/9O~H쌪kj7%a'RvA:[a|)FmaML/b^S]뎯6M~wm귣<O+ke _ij=?n/1O׿(ƒ<~{މ}[;&3uW5Ŵua߉9�/D  5 އGQ#.yvhzꍡұږXw⧓U淬?Wϵɯ"6Jy�l_W̯߄ ^Ly qt/БNE1^w,Xڪ7&?V dT({Zt 7}WrhP9q?*RCVj1?<g.[%3~C]9C{_ $<,0 :'\dmiCC$6zG/,DW@(mxGW}l<?fbP$0_g$(/9S{NuyŐ?$K'bEpg q})!Hg& *V\t<ylIGghqx)zduاѾNT1ǹ8/&t}PT .{>G>J z9*帅Y7';~FփُY3M~;ɽ#ę`rtD7#_q5ϰ}[$ʎ8Yq"xb¿:,qrb#1^ܧ)#cIy5ۼC̺`> t#ُgrV(\t>} p @im<u/[4/AgG['*~T'pl*V>\n-́*nGq\ݺ^_NssB1Ef&u}c6;'4¶hĄlpq ȿzFp_Oو6O=J }ȋxY8œ٘1TY#>&=Dc;YC|T`7_T-b#|YT`{PœCصm&M~Xq~T " mx#X3. z\BX pn[[ 6Y\QCXjzy&>9O|N5lŗ7_hT.ΨASuQ?U TWMuy(n,<<nK|p7[f[,C񱜲f}miɯ"rT1U#J_?T8fT4mT|y<$qD 1~t%Z_#Ň\6X?( 0Lj*Br}><(۪rì7ґ�=�$ *놢7*Hl1ŀ-^q.> Ky5Եy>m&Wh>XW 8Cׁ~:׆KQ&]{W؆q<͆ _{�0vvOoƜܣ9x2[̓0[?>N#w՛Rq8Apnp~*z5x~֣D[�?� pUE1 8aO,#pP&W_E~^"bjuǗٔ~<`#&bY̶y_Jd|�p@8*DpNz)v�&&69@Uip@8 h"-.T=q@ 8 pU� Z%R2�_&v9PIo$YvRjC2?2Țɚ  ŭ/ӦI_oG-gN(޾~RMLNWS_Q+"�__i6WG>Ui믉 ~*9 vj&D$/<^qWie15o[˯M3\ X )k%-c.Pꝙ͛7ؘ Wዧ`zˈ~/.4}0o˛y-Oh8&v|Lx^8|qDBP?%o,>^Cq-$|p`=s�qå+5ݥ%Lm|BE˅be>ZpYEVF_N@0[6WC{ y.H$p=o@o-DZ/+3ܜZXXPoVwum8*_OH÷Wg=z.ԑ6jW?Sz1J5q׋-\ek /յs֭[Tڟǿ3 0UspW%c}�D\u]7>% %_v⻲Bb?Wo<< 3`]Axφ+<Iԫ}zcd*^M"f(TEbXDLr�UjjjϨ7ZK ?>\*>\jJ5l~X !V\ܿ܈W3_)؆G.|()Xw%u'\wN$yB#* pNKSz<d āJ\d  Dٺ{nlCS��� k5ӓSK%XG8 X#�REPְS��K#DNON/՗p`s(e1g.����IENDB`����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������krb5-1.16/src/windows/leash/htmlhelp/Images/Kerberos_auth_serv_fig_9.jpg����������������������������0000644�0007046�0000145�00000060047�13211554426�026217� 0����������������������������������������������������������������������������������������������������ustar �ghudson�������������������������libuuid�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������JFIF��x�x���C�     �C   �N"�������������� �F���!"1#2AQ$3BVa%&'456qtCRc Sb���������������1� �������!1AQaq"2Br� ��?�"" """ """ """ """ """ """ """ """ """ """ """ """ """ """ """ """ """ """ """ """ ""�O[a͕Rk4˻E}{v&f*Qf`9{G@�A<.뙿i42zO%Ɩ'9OcXJ>cX}X^@<x�#d}+{2[w_SЫtbb/L E~t&ƙG פiGFGWh@c Of{~n3e{|jˏgfr8؎BbY:Fcߔ Ko+~nWWjclY,;-S6a" BNܰ?r & zq�s�ӯW2db*y]5fP=EWΤ; |vgp6urYevF8,Uѓ8;;΃1-دm@mޱw3om$wQ3iF 蘼<2Gn pHE4dB`B.ó""" """ """ """ """lfnƹӣ<FSX L =2a(9aayStV�5XʐInޝ}OB"SMщ0.țgke6"oӋ'^gY|Q}\Ij;<1=K7Iw)eJū.=b9aBydvvV#�~R/n/Sx|r}=_^Wif?(xDL݆`Rn1K;r`iȃ1�l/F�-�Nv^rɓةtlՙBTJRn\:lC3ٜYtEg1_ۈVc$SFL@bLB;:,{b!z19^Gͦ'0Gbʙu/+ۭ#Iѓ1 ;;;?΃)P.j(*cٛ޼^eeGgbppӴzf2JR+ffbffrvaa�����?wvğU]R08^bQٜ݊,RXb>>倓cݦÎNQ}ݸw~[ٽԨE<ZŝWfG4Zۖxٟ~XEѡ._K!Vݺ4Va3n,L2 ? .{;?]DA÷-̰OnuW-39:CЎy߼+1z1v#5h_->7brA_9赬E$l3ӘbcFL<8;m熆o_%^;"(4c 17,u< 櫂8,ml]uQya�Ydvv'G�)=;Oc$^I[+ڿLVova)&fg'af�����~ynIU*AS >,-ث"&{g{ wo^ti~O+Zn͟~?rDUtchankU؞l]k].ίk[8/=VA" c]I؀?蕵SߑM[`6l>nZ=i~+0L:"vY �m֎�g8\~4[w/V?N}ӕ;V.H+=dzs \v#ݜIgqpжAdXed6vbf&ݹf>ڳsy<ٚޯޖK{7ZGϧ""|͛F˧J.2z-%VZ$Wc&pg.w �2I"av?/!�H9|MGn�Ag"mZoPǕm^7t8y.N#ӁwwfgXņgN r1y՝xOx7xl6S8 ģNg3.`.o,FcLalgvGEXkVX\H+?WQfa|-xWt0 sk7zS) $rf/PbeٗE6yfl\k2X;""&"leVv+V;ծI?W{[V`Ss>s;lFW+ &rR6>, "Y&2yqr+͟'m �MʴǭJC ?wc8f~Zn?v3^6 z.ķ.Rܬ91Һq0#A132??[oZ~ɲ[vW#fF>}6r V:voT 8bcF:}Ը11۱\o_m`PiiDm/&sn`yWm;V/S1J(-I(rVH9 a@|?M7=E޽Ko H!;Ȼ}_W~O Iv ~bf=-#3v.~QH+ֳ\-lڙ[ۥM˙gf)Kx|r8iȥAԀݝ^3B:v'EÎ3 c;$4RK4RHoٽLuܭnq]lC-Ћ�NJZs.v'r.;2jn/k; W-~Y]#oF2X6wwaag"vr}5EwS'oٔ):.ػՖ`,}_>GL8ȭb3A3 ?Zy]0sP ��?mYSl|�oWoKBjuf>})ԷFc!d0;JXzWrwnD#19jݘD@\{þ)0ԩ\͗%o>HfMln QK)jꃱ;א17.;33 옞S4<t#e*G!hɿFj(jlC vv{s/_!MbK) z> ] G<?w/k>AaXcp8Ħ 7,svV 1n]D8Ovsy{)#%d rwqfwvexbb8R�)ҌIyds7y/S]5%jA׀BQNEZh8\(݅"vx@DŽC?gFpӎB͊�b I!EX]Du{+3\XFYy4ݙι_.O8q:iYV.~bEגw'w}9f_ C rga%o 9+mhK,,NO""" """ """ """ """ """ """ """ """ """ """ """ vO̸O|FR jf&|G!X999M- n(Znz[xIhܯ܃Ն@p1.܉;r;*Ƈjf:vgP\vB`5Cκ04'(!  " """ ,ZU۷VƸ?rxāX&M^malr~ZY݀32&�0rC2DYٞ=k"/cp٫㟩Xn~DOHܻr7X82isRy]S\ac:NOډgn�\y;&*ݴ{޻6" PYLֱ4f!rX6cqf!!ws7c3}4pqx7 w1F<; ؉_I "" """ """ ".S)Oۂ>Gbū24qC;03;:&ɍr[+J R�G 9I!`FD",XřZ~ň9Gq1Q;-fjOSZ!\d#pH_7f$3g(2<#vo 'Yx[gh|ǿ s~hɤw7zQ <8hx|u 2K=Vv3A! YT?W#P $rI!!'HB  2~fobUu8q k*SWf[9\Vw`) ̉#̄0g#"rvgxZȋ6j�)VDģpq)7.M?N(#Y˔DD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDh2 0k-Yٝx$"Luf?~R�ذ;U "Y ?R's5 dA^q =߂e<%O=b9bhkΰ/f"!(HI "n�#ZX?c! Zz`2C` _f�:O,l_3VwV*L,QM 61fo\v�/o>" |$`nm\_l<g�u:�E�~vIݽ>nzc3 p ^3뚯n(;~S">^ ln.3.r;EQ{D@T i3v0WSI5?'8MNssdn10 y\%2'qE=qy=k"-kJp r(@w wq"byF倩<'gS;u'� ܝag�tz)128p_ۈ,WZF)&bv!vvvv~eə yĸ|U72u_ rzR7&K3R{e"knYM"""" ɛ˕翌g<7tv~~$܎`@q?k~p'aq5|vXbsE4{;?"%qDE7~UwukLf_f�'SG!$2Jg#rux;V{���+MfdG( ccAZce;3O0Ycq1wIN V^_[j7!rDRK!?GjDNr9C\#b;7l9H20+ְ�2՝"XR0B징?ol^G3 M |TY܅,BDD% ?avtYWnϩ_akEӷoPw-m\,}Bac&2@,z4`bѻ GY?8=qy_$cIW)F f簵mSyYSO@ =Q\ -7 xϮj͸X5 LPx18RRGa-)� b<kxx@fzSb!X,|wda*4c*lvOABU' 9&af((yӐ 64Ks,M]q 9 :Y`ggvqAoػ{ \~o o)\^b,Vk&.g ]Iqʕg>Jx!iL!b NܿQvWTn ^iHL]؅vu@DDD@Y?keLSLrt#,FJ9w{?p8F=` rqTxH/uUIѐ;;΃?„L|, v5*;8.NOn5kENU,3*4gϒWǝFfyYr(3Nj7EhьDD@DDDAIܼoktϹg9{X #Lj半BV?( z~]!btHLfw!pU�}Q;GEޡm9K^1u)6<>G ;o goJiBy"E٣+L7^.S }Hzh1f�faffffᙓ#7e˔DD@DDEÿ ˠe2xy(cDv,Z#G193 ̨.�LItSG\gyXX،p(i"iGbძ3}N )dJ.ARM[N@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDDA�dX4ݛ1Zذ=w?wx4' 3_1^(kx[�7Ԗ=XdMȓ,ϳh{.Fk#l=l_#P $rI!!'HB  w>猎'njJ0Yafؘ L <o\1c늊 P\b ~uep>],r\U;ydrX͟$xhg\'j&vbp]s@!.(mž3c7bc*ņIYd03I68]" *&˲<ݍOS`ٌ�!bhbg.FL+8QXn;2qk:P\ڬӻ*-j q1 `B.�M S1֯,-ٙ_\&+7;033 �����vkakUZ32'3C'rC2#9 ܌Q^]ιWEڴ;'zcZ8lJrc!~ˆfb&l5WFkY~ůXղXP[(BbΤ)f"kpr2�7�r�Wew5: K !<v])^p(p˔DD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDm6�ߨڕhJb~!;rl=߆fZFos{o^WIr$gaȿY 6 x nޯםˮRڧH4߰m{RZ XZݚ_ rc. I\ˆaq6f�@${:]G=�R|J?77cc/R1si5 C3bʙu/+ڭ#Iѓ1 ;;;?Ϊ;H1YJ�Ik`10^( E儛B%'M#göRZ�),Co8;7[v*HN/3 m{Vf}o]I#EVF=d>0n/!c٫փjbOõs jRzJTθwf(ӊ?S%qz4zU$/`H O1ӵ[ncj16 ymc'^F0"b8y+J 6lB/Oۤ1%Wq1?I%@xKCRͿųsc/892w\dc稰;`!pW<嵬G% 4\FQv]{:fdCCF?,}.onCK۟E 9&w…y�Jg%(f)h;;.˒V5=N]f3 b�d`BA3bC,EbϭkXC _Ԡ$e!9;ndDDN1PԈ+׫Z6(cafffffnvcKnc_6+vljo3+bH,<0L|xӔ^ѭc=k-WNVnWA 8bnDggn}J"h{.Fk#l=l_#P $rI!!'HB hyvTKwzanLEuHwQ{.뙿i42zO%Ɩ'9OcXJ>cX}X^I=/Ǹ'C=ܦ^�G+vg'c!!A哤ag648lDߧOn%{L828E4զwbxbz'>^n|>F,y]$p>ޥ[S%&\"A.Nc#pJ 4ւpygc 1cVX95q0$%1B1\& zq�s�ӯr ^rɓةtlՙBTJRn\:lC3ٜYtEg1_ۈVc$SFL@bLB;:K`6+n?bw]I%x`ayCa"ʙu/+ۭ#Iѓ1 ;;;?λHێrzγ6PVʶ.9 Z.mLBsBs c E;4y!'�v26<3W/U=;Nc%^Y[+ڿLVova)&fg'aa�����F:3FIJ&l[K3wSsCᜌȟN """ """ """ "*&˺okM:9 ^de1,Sc+VsV%7O%k?HYJ�%]*%4<p,<~Qb&8{u+fĚ)3ٴt r{_+dZٜ6#!NgehAA>o7//&+9[n8n'ۿ#5Zc'KTͽfE!F,&63ɂn޽n�t~�Gk, :WFY+EOdE,As<1C1Ŝ D]\*so} mF2E4d$$.ó"~K`6+n?bw]I%x`ayCz&/)O9[>!b4M3 ;Hco8RD$\I4r/Bp(͂@{jvj~|1I%%s.٘d  ;߱w5 I=*6R HYͦ,L#/$] 4ENsUAW 6ōֶ.(0C,;;D#Tn ^iHL]؅vu?wvğU]R08^bQٜ݊,RN+ג{JJiDY�����uɇ\W'|7n×V5=j!6Fvf]�d&ۗY44!w�K ?4ܞlkX~Vҧ-{F.< ;33{;}5?*ewQj0ZhFy\XH�uV~c%1&qgwf1:[yDD׫1Xf)Ѽ"�͇ z6Q +HfhU/T]$?[bk1m}<mEy2PVYޡE!Ѹvn9�6KE÷-f8'IZ:r!BG<oX;KNT/1X Z"͒vF|1r1؎#vq&vIMž�M熆k_%^;"(G4c 17,tʱO͒8HzS*W$Q%<q[l&1ciMg-LԦ;Z#yH) d\X糲cg>\Hi� 8 ٌ.,%`x;ZVk2 l.^׷HbKүshb~;K$tDD@DD90ݛ^`^pv'a7kֲdlu߆݋7^z.gwLBЀDפcxdꉝM<#o7M"" """ yCpࠫ fnbk[z]xe^ggg@!Y"`b ON+ג{JJiDY������u۳}UuJkTO8Ez7G$Gfrwv*3I "ɇ\""" ۖfX'IZ:r!BG<oX;KNT/1X Z"͒vF|1r1؎#vq&vIByG׶|sC7ac1X]ىgv@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DD/AEHحٳ̭ #swܳL`p3<Le 7?דmhW[ٺ֧Z?fn}>޶kYlbr%rrVǰr$;;s~GW C#sl \a\ Cd$(bQ{F5܎5V;Zi_2n}p7^O0|؍+\f]|N}Xݹa3SMW-t}UN׮n{&WheU&>`#Şb}Kw g䶌[ojAK*՚:zFp.$Vvd^c3{wnԟq;a#oLعC $h@z1p1q~VQ3d0ur)Bӯ)G sCRvWb~_ߪ;i+WrhDl:KN2ͧGe|_եbiд2FO�'9~wWj헳=6?RY 3ufog.?7`~-qfs<S codQA?@D 2`G?O#ᶋe<lT_NJ7Jc!#fa_j'J�E}O pٝ=Ξ#4)c2Lw% anNZ' 48٤i @Nle �r1τ-'ybJj*jy\5f[]ݮ#2�oFܑˆ;wPO6,lH0GA0[IC;+#><x\$T^G`>;^WjcCR ZE1f�3333{32~_'H��5A"/wm��2nmTr,�?zG6~_'H��5A"/wm��2nmTm ,+Qz6p ߷iJL;(;3{pZTP,7 "37fߗ?�S�?zG6dfӑf??�S�?zG6 9c̟۽#o?/wm�ӑf??�S�?zG6 >ߓտ4n�;^B8//0OQq SK^ /RpR.?^C݅}@"̟۽#oddn|?w/mx||:Ηz ~ !j##Dm Lǀ6�^O)fn򷥡ֵ:3s~HNXM\KWqY=^٭c!bhC|�fffjײyΡ7dq29B2L2r�i~G]<3+VTFy#ekAV+I#-gnPg>{U͝PVLP (lE,D߻q 8cukU`ac% O$rq!18b"Mi3]y֨k?M<Ok W2c[2F(;7pI݁9'mSտw?NPM Q|zҼӣm۞WM[5_%ZCi2WcbS!%y 8ȌIݡi;w9 wfoja,wWsV>4d F~Z[{G,o8i_VLf�fÆ^wVэ 34MK.F 5Yh&ceԫB[ąn�Cp//~fӣ2IݯՂjױ4^hZ#^R?N;DųW8SX^Yپ3r�ܷjOޯ۳;?+e �r?|Y4>X\_B/M:y+5jܺC A؝ȺN,~c\5_d g evp`݅D@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@Y*A_,$cϟa+''')�-؝kXZ`3o-z=؛'nY۟gd9ۼ%CaGmZ^P5KY, G<V"):8w]v=#S5Ӷk>j�ycuI=D8$XIu1ͿᢆܶjY\]Ȗ^S;7,OI/X@͆8�{㩪+ctZXXkPlT'A78nF e+nD<˵Y<~7aVh6hx`?!%#p B RU"qoN.{zm?'/Ui_.G/Y2W!>Ų/ggmalr~ZY݀32&�0rC2DYٜ(x/>;}LT}ʶ5$ bQ6kL,oeE񞵑lSqԬ7hG?P'Sn]9 ~QV7]O%HvK Cw{bcq4Ma(cqy;<L3rKGl:{66r<'4=ے'u:3C.+gTZ1YIǟ>V-@NNNSKH�[;/hֱ۞f+'+RZ7+ a { 7"Nܳ>ʱYT?W#P $rI!!'HB  2~fobUu8q k*SWf[9\Vw`) ̉#̄0g#"rvgxZȋ6j�)VDģpq)7.M?N(#Y˔DD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DD[߱ f2՝'AX$ߚ~R�ذ;U "Y ?R'sȂP6KaX�wjPOpp,C)L]!gSʟ{HrQڶ/#&\ߪ,BYia!""?C �Y??~L-z}y/vvCN_1f~^z3銭F�c>[c"BL܏g�u:�E�~vIݽ>nz?8=qy_$cIW)F >6bӸ52!CJ9JG#^Ewfᛆ\""" """ """ """ """ (-FdaVXgj p,EXL]gS1յ6<ŀŹڮ \OZ8P؎ox %R 0�;gfg('8f!&.)O=o(y[C_.uow!x,4 FBBO]c�-o۾?Z_t:ҽ#g[֍�h=X(4|-)�ǞDL#7Vful.jOhoc(}WF&if6xg_}ï_n|oGdۨv30 2 .>6bӸ52!CJ9JG#^EwDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDEF<ѪCdpD2ǭ {VA"zgݟ%SD6zܜ0SѼ4F>Lܨ-{#*YG?Ԛ?Ɗَձ3 cMT?-uL=K1bp(C;;s~p^6YnJd�sTA( 397'f[U_)\sɰm<pL5,F ̛q캗<u|4n팖l�7aw>$n]"l4T\myN׏c[5|xdM>{wNxa!~}nWZ4{*tEbk�cgfYۙX{Jb֔ KhY=-4uG'E) `F$$Nq_\ 8[K]J׭T/V7gQi⌇gVlu)":Nӄ/Ce-9 Z׵$)E]ܙ)giV2g C e,Tvc3?V.ĬR34(yt-V(d!$'1`C^Բ 쬾A޳ ]#  i4G28~vfwn_Y{iﳋ15e}\QevZ\͆ջET2GLOٛg<r-ۿ=dp+cvHC1~ۜn;7&mLRz*.h6էܰmad7{0.]v㏷xZזYoŋMMIp}%~H^yXI~rDDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@Y;[ $F,{R$ԲpX_g7~~r?Vg>b.{�r/2g;nt֫쵧v2r>\?r83heIK?q,=w1V50 0- :\6,-VG%l< 'rFq;sI4@l賳fYZ{2`SeBeV~~(#qϻs -\&ۜj: KrCZM%p8wٻ7$˰pi,:3bsfXoYʻEL-B WX'Fcs8oSa Ⱥrѹnr5|m۬[,JB'108ML ! m=�-D9p+3?坸坔NC3S yQfHi`f'!"f7fɅ}qߔM�YE0hƪGX>L/b3^g?#ìl:R8GOw.\!hmn3fb/~i%r~, 9M/d\ KܾT EhTiu5Jf,[-ZBߊ6grծ(Aأc`bb.YZC,u)ŊOa}N39a515k q ^g.1Omq_3TXZc1^SlM'Wc\Aۆ~\}68DY*Ŵ1K<qܵr_3$ ˀ䙜O~Juo.䡣ܯiCڨ?OF< Zö\񗤿VFI  ǒ.' (ۆfyQIF4<m`[33fX53<,~DOGݝ~M>buN~>ݍ1 >$~�|qa7k9Vt|=Xyv[arݏVrMՑ<7*aэΕ{SZ|+xo>>,,b%�A7"Ofbݠ<3vۂR|]joîHU4Nܘ $wo,hzLi䧣e`1BA GāYFLNFٕ3XkYZ=32᥂R�y"6~F#myR9[4:;o&/MZ=W_>9MJֆ 0ޞ0w8~t2lĺEN.\v*l,dm yݹ~tZ[''"cOo:6Cq/ndZ;a2Wg켓F ڍr6Ļ#0r7*zM㱳 8Sefs23LP]MP"gFbv?wL$_퇏'x5]܆yђ4Xg 3#ﴬ1?f޼/嵈vY\\]ڶ H;PM' ɸg_gntY1`:U�tm�H_?S߯<sǿ |flf\mVj6i6{ %�]φ33ܾ<F.}oX^O+a5=s!=bl"q~bA_٣&!gx>Օu5}<ΩLua+1V#s.=ىٝ۟sd9fr>)#j!QaQrX5|<Q1c[b-c/X[1rH#$n"n_?owY֩bwm7zL5O1ҐtqimYbEϨEtا,iF/xKP.d ' (ds1Ʊ2i$uXY٠u�R6S &E$Rr1ӑd ݉^h|Lb#6Ǭ:l2,g*ϖ  VyHD >Eigն\ ؠ\5Z?v,s8kvn~bc>�FSdؿ ʸy(XJVmg;K<b G7 !#-Nd~Z4pG&X&x^6vq?(m#'ӨkݏfWqѬ 1rl"2ؘgfwhX8/m^(ѭX4s2 Nޱ1#u;1?s]PfG~ѾU߅<O H΄_ZltH*Hב#cN'wwcn՚e,ԒEُ4ہw(ٙߟeyG-3QǕcd9xqy}FngKn9Y-˙ = XoS q|NEY׊ʶ4)I1t~lmבt4u!0Ffv~v�곉|S3oV+[U*ig#8X.bR&1XAŰ&ƍ)On*'V>^)czާ,ۿ/̏k6)"B0^/L Յ%`EintŊmdWþkg!Ⱥےޏ_FXy$b6e\dt˳GFh`)f# ftp+@D�×rn,̳o*ǘz\uzgD`e@7~g&Y/lS4<]XXmXxO(zn;Z8vF_)'5ew3f0pvw]}/DӘ/S֍N>wnFkXֿ#7:|da3 pc߇ve+ܹ]Ulh#N[N+^W]Q rߦ>dpgv++ CRmX{xlEJ9d(Y^!0w;�,&nHav+5�Y5fnr,Kk|fֳe18blD/LC#3quf$GZUy'c2v1><^;%5U"ð6!ix|6^[(2r\\} q8~g_t'R/M" """ """ """ """ """ """ """ """ """ """ """ """ """ """ """ """ ܬ*M@r$�dO m0y,O=>`H/R0Oeq٣hX~u"^Y!!s9$&f̲?'=y_$ҘVla7 z}CW5(î~"g6å:f#꺺-^NM_JԖPXgfϖbx'{y3#iқ^뗪E_CkP$- -g3NZ ģd(%4/<MC3k:짒6j2uǔP>@Ƈ-#;ϸ;r));&zF4ksvwv=VֵMB"sM3rp9}=bNݱVò= [GG=G U=[4B1aA.0{:~q6yhcP3.d^[KhXP{ݙ]'VRL_ndq}mD WR�`fOH܅ȈmL:~j 3B6{ׯވ v{f{fvMKdu6u jFB^,l{Hg>mdu*:lƤ8S!xq|}Y~#Șse6Lf-:}mng&U $Cl~T}#f[D.c7-{haG\fh{1?W;q`Êf-s OtxZ_4*G b[fzl�Qvg|.g/ bZS[V7qՈ>vgߖa�b4|uzi6,W<TlI}g'qᙻ>b�w<6:<AB^i j؍٥&'sn:~p goYG<85q4iʑd~vO-ڶ73wGgJAN[ax̤Fe\FfgoXu2^Zl\ + <vn x!ㅉn[�˛w G ,VGUI犕bnWHaf%>4`2YM]zkb\g/ë2zԙñ?_�LNsX1>a~3~Vn]URbNq8ݽ7?:Vͫa߹jp u,. !dn.E3}. ߽?nL99*j.P͒<Qۆ0W�Q@abg.]/ԚxP*Ú6c8Yx$~"N\z}ZM"8i~|8�%*Pcb%XeiݺgY׊13b4[W13fFnn"oEDN#qJGEuZFę(3lTa)Y"a'2\YX|R0E<Z-}jo8Q غAO/Kvuro#kكչ{W9. 8b~5VoOZ))?f<l rb\SiIRh+0B y=2~'ٙ(]k#]%jKAf,#fX;q8s*'(Ϝ'h1y,]7קkCkCRV־>VA~լ,2pLγ,OӫW3&=MՁ4m{Hw~YE]VBҡfE 33s˻3{/5>kFOsC3fS$;kV:;A8<q٘ٸ혤dU/=/VV M+ Oՙ3eI.GKܵ,T֦ e`z8ffon_ʬ|Zero,c'Amcg[*N q(898k2>+ݲ x]ԲyZ벖Q w/Mܘ߰;3Q8|r)pyGvsbv:ףsaeO9s!xM٢i3>+b8f5,^KdZV(6`!8 6fo?hBav"ffYgyJO'ËZx9d {o NrL]só/yzF79g%;Q_>ŚAIFSˉnՙVx9nuyDnb&f4lO)g{Gv'+m;5ENxµrk|0$!7݋ <m&s%z9qސ87F fy#ge֋U�lH5c�^RPBr+ "">L_V-vZF{!Nb$D:"FOR`13,Y3:`Ƭe˄R#;ό6bMeⳕaВCh92B O ֝V|,RDW�玑=ߞ}�r빭)!h_;NmV]RرŤ9oP%zL=[ۯ/HnZhUЃ6Bv._j4K߷}YH}F)m-FL0/ùCO+oM&r#BII8�I~,-ۊeXm;6ZxPVmozB ԩ_|㜶^NJЁ�8fg&6?܃y'=j:6|_,OdPY<<Xya%rn&g1e+_to+W\G3ٳLW7fgo6~]rX-m>Çԑld%eYXL$�\GVns!ύ^\r/I3ӵ ꃓ;G؅Ԇ''ajc:o)`w vi8SXeϑغ'"<9%fi-g \~3e+dm 9M19]!!Eӽ?k 5\[?K0=9gk= s݉O.o5jG+7b)"$%'>}p縉3(b:s�mi vZbqgHOZ 19./S+K36""" """ """ """ """ """ """ """ """ """ """ """ """ """ """ """ """ ;rP5Z}8u疴3[7䢩W@w郣}# )HZ b0f /X�ĝdػ.멲xZ۳r`޽^huai6. ucgٝuhD~Vݬl޳ UUvo=8fvmBfbYOJ"fD,[3w[홶:OwSεVH9YL#8;r,?uΗO5}C'o~X|̽AEx"'3Dς<qF5^C/vFAm~k7ww\h+�WiWUrh62"<B՘ oFL/.B<ܺm^)wiR#zL "Aw$y7Bw!1vvḶ7yy.TL%앤[1ryZhSdn L<?/͇yjVVOճN֕ǼSa$nD/ԛ'gYQYd&sХb.G؞l,n}c+3Gs Zc >35b9=ig 9܉C2"3N\$B-hR֝-]aڄ.1+|l̸v3/'wCi Dv;E|+BQ D`j<̍n]ߞ]hhlRY-#JVq-*XDV$ F3p"" """ """ """ """ """ """ """ """ """ """ """ """ """ """ """ """ """ �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������krb5-1.16/src/windows/leash/htmlhelp/Images/automatic_ticket_renewal.png����������������������������0000644�0007046�0000145�00000003501�13211554426�026350� 0����������������������������������������������������������������������������������������������������ustar �ghudson�������������������������libuuid����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������PNG  ��� IHDR���������LZ���sRGB����gAMA�� a��� pHYs����+��IDAThCZ[lUn+F#&>`ŶV}Py*%RZbŢ ͂QZq&Cb[Xw[ZhJ 7mGp-eKA?g.{vvkىɞs~̮en(00�}�& t3˭0k?ӭKZTx8kR&RoOo=l1I0^H}NRw|#ztX,p8lHsQ\77a'k3R[ce{3vYjN"u!^AD}hNJ>QZ96n`\sLΊ"/~y-$Cɸ,l.<k^~(MϬjAӁt'TQQ_??ͅ~֑LdzZ?88ӎW<}09ܘmc+k!yvMM{qqcg+:Gۅ-Y٫VvNbW:5"4#5NSQ??BTՠۇIW?3V-(cG1=P6!\ ֢VkL~Iku'^*6ŤJ,21h}<K6%[j XeE|1qek `?@vW* NUE)*1#pUG2ұ$Ӆ ͥYv :/qz j&Tʂh[K;Dr>Zb0w`Z v ׂsS=Tcp^']8ʅd\& i]Ӽ!5sO\Y?'=}>#A r)a_a]¾d[ :W-iOY_*528ϱ+1)^Qa`e^N ||W* lS3Bj4N''DtR"_D~kÚztzy*X{_G1ݒn:l<{ ldkYȧ~N~�c\N*OdڨQb|4KKrqq48|Y|{vX;!}\=.ǵ'pTЏayyT7u@T06,IBsU{h*5f8vl6vDdے>i۱4zq"voX?K?ǹqRO'j7+Y}""1ri\ ]`IUp.Z{EEg-*U,EC?PRϏ`r4voKeR3B^6ͫxۗ tm}?Gr[4L{ RVrMY+eyLZl'Lv%>gEJi] >CWr>1d#Eo¾9`,{B(�ߺ#* C6pc )&43ĕ+Wq ܜ­iA08C[ P BrƪA mA}4mR֎'PWPID^kZx+i"w$[Ǟ NL,QRJȏ;-b,J!(bu~|]%R9cr@ۧ5bړ3^98n9\xq(& 4,[}-_dDFurY Dd7LR' ٢z4JUksSfgEpNY2a9uϠYX`1$.7MRVz{fMF87}�*aF?����IENDB`�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������krb5-1.16/src/windows/leash/htmlhelp/Images/flags.png�����������������������������������������������0000644�0007046�0000145�00000002166�13211554426�022404� 0����������������������������������������������������������������������������������������������������ustar �ghudson�������������������������libuuid����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������PNG  ��� IHDR���r������&���sRGB����gAMA�� a��� pHYs����+�� IDAThCYHTQws\lHm{,"(zM[RF"JSm,vι3:ý1=پ{>DpQ\sH?@T;ɡ� o\9t^a` DMrݲzan;[8ȉSG ?HDkOm}6{P&rm7:e 4g:dBrbjU:zF@ʵ%ŠhL>UF- q{_PV$"PIN$dLZ HÑx#iE~dOVRDD`C$DENC%t:_ӡ%&mi\$bGŊ#Kw .٥Ҏ2>+F6$kc�x3c`{щNfG"=5 F- G*|쵦 ^U=_|ux}+;[(gL(+^ˬN),2s <.*JfQ^قkwi4 ؔ0atZ7wKz|'g 'hE; JъiXVJ sE,?-i!+I}}8mhN>OU+ dh$Z40Е1% yUhwq1xr0erVσ@/tȞ}+Rf?H1#'W2Smr,l/$vB;EUCo76g.AƊ$I7O39p:c ȽpWa4"Eu'E~ʬ(1p4y 2%XϨ͞L[2׏;g;١HOsDrOOs觯Гc&Étʻ9h"xi-BhYA@+2 b#6EVg9dئhqa#H=QсzDC@vE UΑ V-P 5BGڻxjU=N>F4 5LGF@Nk|3Բ����IENDB`����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������krb5-1.16/src/windows/leash/htmlhelp/Images/Make_Default.PNG����������������������������������������0000644�0007046�0000145�00000005526�13211554426�023474� 0����������������������������������������������������������������������������������������������������ustar �ghudson�������������������������libuuid����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������PNG  ��� IHDR���/���M���6=���sRGB����gAMA�� a��� pHYs����+�� IDAThCY pTn汛C6 Mm"%:Q:Q+*/A%mTE[ieuZ^Hjx#&,y;Gsfa wY {|wn~ Ӌ/x0%]p×y:oZ]th7XZ%ϕ`2>]éAwlR^rtq8Ͼ1clݝj+_ŗZ8SIOw1L;TJZ aGt|B?&Kd&d[2҃>gv7G~QT16 w/Dx%a5|4 q5uUpj4>p`!FalC7<90 ''dzt Td #6=B4]aWXp[my#mf]6ΟNO[duX0zgHyϦonI_1t847"t%f 'UR-nOJhI]zfRLlKV+q*<Ĵ<F.lߝUH.!}ul7/{@ոJ>s-|Gہ/ 7#)Xm L͒kRq!wAD`rtjYdPQzxlN#^۽./yYG#vrSw,�4`&YɆjC;3é݅$]Fx)԰ (+NQ]#L #e ./Nu@L ~gZOb,Ţ{֊1H /|qCbCH(mػs$8oa )0/9t-FM* 8eri#֯wKjPQxH<~0-nQ ;SQ9'GBgC+ Bt끩݌LYd VbRb!WQj6r Q=NE[&o,}p-FV� &Ud=8%<`YDP #ecoźf1/P14nN\bba@5*: Ʀ#c\ zn:pS{n8\Ȓ`uH@*ONsx9 >[ +cƭnEc!&!9rt`8BI8D~iVY-@$7f1?cXL&Ʒ}^dLn <#ǧ@9bGb$|t<uWa)#ðmh?`@k Qϓ9>=Mf:]=H*TO k [E|tZسa.n5ƍȯb4 %08M(uf wXㅕEkW(e$lc!0p{~ED\Jnx ZD:]@B~<<Vb</:gp~pNX8I*8./%_J(GK>q Պ,]*n\*}~޲X=r^OF`@|f=?AVb<s%F%M[*d#ݏBڈ̛)4躺i\\GGXX /"#Gʹ|hy<V$&&PE1-BԈY9 _\ y }t2md thv"4ٛK} i;Wy*Qx5B OOTE B?^<~Mv=&5iB<VkU`1Z_<멆e._6b5i;Fw\# Jf(Y݈aubva7rs&?ܔ͍$b|j#So>Oxnƨj:X󇲑G*wbw߰4|Hx$,=[bl^%ӊ>IO 3ak;}O<Flvb1=[.̙S4%.`^l85?˨6Z.C{[C6,<3o&O^f5>/C󱡞>W h0zؼvc~&iݧ :ۉO}g X\mxr dZMK0DNSpV@zM xERAgQwaxևkJL__ʄ\Fq!l4]4|̃|䙱pETfB `>kO`2$_�K;?'9286l_F<7$xuRADEHH-i?LsGzH #a# XDq/;?0o'S8v56sC?_5’9h3(2�:-7XQ8%!"<<iU#AVvGgKMUbt`㽗wn dj wRL'h;>uR0_'4]|�,]Z;)|誼<f񬖡rPW`kӗ;Bk_cPq6kcp 'LX +D'M]�v.'GDTj҄a1K3i^| 2˺#-Zh\]PSm>F4> | fp\+ao6;r"4"&H3*M2ia{S6X7T5-D����IENDB`��������������������������������������������������������������������������������������������������������������������������������������������������������������������������krb5-1.16/src/windows/leash/htmlhelp/Images/Leash_properties_krb5_2.jpg�����������������������������0000644�0007046�0000145�00000051232�13211554426�025756� 0����������������������������������������������������������������������������������������������������ustar �ghudson�������������������������libuuid�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������JFIF��x�x���C�     �C   �~"���������������V�����!TUs"136RVW4Atv#Qb25a$%7Bqru8�����������.�������!1AQa"2q� ��?�[1J샙N.J)䗎#fDye^YR]<j-%'14IBw 1EC Ur6IrԶj1֖XQ'$]c3M;7_xd;{׃wƯ*v2vSUS&zq7쮰 SF~ݪ=6V^m )*0<tjRqJ㤐FA,vݿ,Nӽ'x9zO|k5]K&1Ο/lﳵgo~wcJ{I7 ufo4iZ/BJ= 8S}s:sNf2u=IMVbIMHtAq&Y[{M 2)*-m~V$)O- ԩc(Y!CA6J*?ޙ^zf2u=d;{⳷eʳVTWHEA<Sy2]b#Ϯ2UkzŐ W uML':ĴfHx$f&+b&lf?{~c'^iޓ Nӽ'0ueh3%EUin%%%&FJJ>YJڱ)KqQIbLgc>%a[N+I^Ey rM]R:sNf2u=M+)V)D?OJ@f#Mi/%J%-&h͕Gqe"NQEFk5y1-ԸIo隷-LWD|~&:pk9Ř׃w14IK*DO0ɾ-$KKK*lZVfDJJL)IuVc!&PY-u qXy7$^{v=YvŘ׃w14IY̪X)I͇HnB%)8ҙSdT++%Q =jWR^itd<AEwWmQz&d;{׃wƅeF~RkyrjN&S:ӋI17"Z$WqddϧÉQ]E̱!@Ҝq)-aS8^zkcd;{׃wKA� xA� xޞ3Ի׃w14I>AϹ/^3Ի׃w14I>AϹ/^3Ի׃w14I>AϹ/^3Ի׃w14I>AϹ/^3Ի׃w14I>AϹ/^3Ի׃w14I>AϹ/^3Ի׃w14I>AϹ/^3Ի׃w14I>AϹ/^3Ի׃w14I>AϹ/^3Ի׃w14I>A�AzxRnc'^iޓ Nӽ'2ZKK.2u=d;{%�A�AzxRnc'^iޓ Nӽ'2ZKK.2u=d;{%�A�AzxRnc'^iޓ Nӽ'2ZKK.2u=d;{%�A�AzxRnc'^iޓ Nӽ'2ZKK.2u=d;{%�A�AzxRnc'^iޓ Nӽ'2ZK =K ɰ*U%,4[Kfey$+߸,߁X'Ŋ|B3)_R7e8J\EA^XW[,mɪQ-pd[Ӥu :G ЬFKV+dk'H?;yb<}v߱Xºbob8Ns mg  l.-nkaMFqo +26SQDŢZQjqȊ"O)nLUI33QiʍȴeU"&339-No}n8(xoFdD5푑56U5_OgSTv{K}o6f-5Syr뜖dʼIr$Pa=ɣLmepZ:_l̍;פ̊qZQiBiԩ-jdIm[ߵ-~uJvwGtL7{3hVSa]fQq96m*V]ztS͛iYsXpy4HVFOd-2UvL*LYOl-%%y�]kn)\[n)<[??xMcb"~_{m-,VCjthI#Ilc)' xWplTYU`lC 5)Uʨ?-;)("RwR&JI\{OV2OV22=6D|D663f2mścQZ=0KYVU= DFٶn4\%(£Ya%+;kY%VObJ.tZmQ ԝZ}Qm)%=RjwŹ;;n!;;n!DUEl?Q9LU{ݪʱ쭅ќ.Ϧy/%9ev%^G}{Xhv;kyrin#e6Te-Dn�u 7w}cx~Rxy~Rxy3heUf7=/Z M&m]M:VU$0۹h"i$R7ҥ)E3)IV1BL*ub!%XT5% ŒOxdWA&È-'+w '+wQ|s~WdwkگfVU3jMfsr#ipQQdH̱`}q^7'Q)Q:l)q&xM#$dXOuIvwCuIvwD3|-=my�|r伽drR,mbZT3ƤQb¦L[<HոY$xH3~+qVTzh-Ҡ(#vBPۄkRWh,&XOZHiM͸ڊ!r22Y-^QBP6qI\ILHw`jrߖ6bїe6%ZƤTۧF֛ʩ)6%!z[+ROM.tqEN] Ȕplq[̆̍aaύ;? M3Sv[z&Jh*TbɅ.ۍa8I;HRnQ_zHn$3tu U2<vW]WԖO\u%aKޓ5o_g|d7_g|ddEToU;sTK2݈^m8X,W~Rxy~Rxyn0C7s�9?n)\[n)\[yhf}>M++w ++w7- Ϲp p;;n!p;;n!9?na7_g|d7_g|d<`3{> ßs &̆̇ops~Ry~Ryq7}0WV2WV2n0ZßsϹuJvwCuJvwC C7s�9?n)\[n)\[yhf}=9?)\[n)\[yhg7}>=++w ++w7- Ϲpp;;n!p;;n!9?n`_g|d7_g|d<`3> ßs ̆̇sps~Ry~Ryqn7}0{WV2WV2n0ZßsϹuJvwCuJvwC C9s�9?)\[n)\[yhg7}<9?n)\[n)\[yhrXۍJ˝̐X{n&r"PcKqŇueyȽ QQt$V2w nfQ͌R XRoWij]or]/)t-S A7S”mU5_y_T=ܻM{}2v}ﱪZc1׎*3YYXDTJ 53%HiW Tfj4qGمOyNҚ?vdWp՚5QQ/;Vl�y%(�R*-Ql4Ӧ;dF6fd'q^_;zO{ ~wS~Wg4So6s輈%LDeƆQ4<=sR$_2#Ӽ3E6Яʑ]ڧc#B[=e-�YϕLM[O~lzǂN撖b8N"A/}1q 6*^h]}Q.\̠@L0ԧC Y2&&d+'w^b&b׾áe-�Yв�hmUDB d2E}K#3JHdeqm={�>u ٪]jɚ*- ^o;n,miEԡK%鸏^+B[=e-�Y[]95d$3Ky9DТJɯ7ȱ;dM[iA5Ħ2s)b&2}*knM`*"^f"'Z]_r /of],]:mJ,NidH\)[7qhM!JQ\Ȱ٫#*%rkt0MEUJ^B hV\ޓ3"75Sre6]2{߼yp?W!IYK6lu+YQ6 R=^[L Q3BKGØٚjQ fpmE۵p?p?^jx$=cZj<bT{$LK“p5+QYU-6/LI=r6u)x/# )k3Iӊ&sϧm:k@Ck@Ch6BV(,9U++E7D-Ue"[i4I+8guLJ~៵aQK/Hu Ev]D4R3QK2$S-3<}b-Mط?6?rgdNfFSؒ؊QDR\c.auBDɺW)J%Ų/5XoDZ-ʬHQK.3e9/+ (ĔJ311_ t' _Z sZ s)1*rLjUSME%OG7R̒RڒŒ8j#2,7oRۇWTUYLE2F�fih2Kjr.'}xً(6ߵp?p?ÛȋQUjYHe;F RZےc0Ԗ3 rB5I^J~V[-L]*ZթtA,["KqN&66�gԢ$RƥzM3+{~8k8k"%NTKlQ ¤Uͳg y ,+:2&(4٬^Wڌլ̻>Tvb#="R&Bq(fi^++u?R 2Hȋͯ_vv�Y)5M/>*d0jm$IiewP{%�=LU!� �������������������������������������������=+Z_%?p-/y㳻zVNȏkNTTA�B*EY֝䩞-9Q;lѵ<${!*K B#;T{(ͱuغNjU⾬lMR&iȡ͔}/W,U6=!'^]N}i5).%W Fi)i) 2Eu{o=ZЕ@BT(S+OTVFÌM<ɖddYNFriȦNSIiH^i3K34ti)i)Zo{3usQeV}ȋNT{CRQ5YFmIo0KJ}[lXJSaMyitEm-GA ͚U*33V,J+{㤴4lMQ;[�e(ǹըOZfgΓOwȔw;sN}J >Q߱VCF[*{mg6n:x_;ָ; 9?9 9?9 BcBvUm$*C"KQ>B!Hy7auةpqdiIZ BNWo V(1bN84ZnDm)KtO69<2ɖĥY(<%zLچJlRmV\^vEQgPCq*,4[]z6:vPj8hn.KDfcM,iLB8еbSl6(32=Z٪U(gH-5is]#Jm%Vw_t=nyE2qZ#cmK2S;K-%UQPPS룑-̉7`"-ᐙ 9;KvV ΐ?yH} p3RFaknl{k, PUm~y-+}-BU`4L>Q?mR[iiLrW\_�Z ʺd>U ~s"k6ȈMˋNnqHWHլXi)7O-y5Ye!6w8FR?ḅEڌ\XTiD9SN>pȍXfkFffcg[fZuM(-lQ)i,h֢#Q|`f4Ki�2{f-\SQFI4gWQœsPn 9?9 9?9 D;NONxNONxNӓS0ӓS0A.41n 9?9 9?9 D;NONxNONxNӓS0ӓS0A.41n 9?9 9?9 D;NONxNONxNӓS0ӓS0A.41n 9?9 9?9 D;NONxNONxNӓS0ӓS0A.41n 9?9 9?9 D;NONxNONxpȮi|�[Wϩۇ;@qQL0D[�Q}DD9SdWlJyՓ2#Ӽ3EW!VdGy*g NcC2Am)t|QlGjJnZ xIf�~#^e'j˴pj9r vBAGֺ)iB jQ%$Wol+0JLV}$e dU"5Nܷe'&90::Ve)nQRjUj&w�f?G1]3 tz6%}Q_A8쬖ey)*-#-2k$ٌ;?&9MRkTR$[[G2j&ZDnISm"#%'KQX]Y 6ccH*ԌCK36DDr�kG4G?kyNZC׭ݚ}>h)t`tvJ"Dk;Ԓ28(ʽJ"~2i椔NFB:M7dYbQ);hWזzZqsۥkOKq.} iO)M9#F%<b&w'�c &Nx//[^GG XkvM苣ѣ-a5݀)Mlu,TH{f{kn~Ukf۩E@ETCi]C0Ҍ+i#{U5LpkWyョQ+=n{CFiVJRih�:mYϲgwhq$XNS6W ipLiOک_JFJ�CS6WҟR 8mT0=?#j|@m)qU+�LiOک_JFJ�CS6WҟR 8mT0=?#j|@m)qU+�LiOک_JFJ�CS6WҟR 8mT0=?#j|@m)qU+�LiOک_JFJ�CS6WҟR 8mT0=?#j|@m)qU+�LiOک_JFJ�CS6WҟR 8mT0=?#j|@m)qU+�LiOک_JFJ�CS6WҟR 8mT0:zmʄyDwq͞owݚ+Do-�I;"eSo<u6K~mLY-/y㯺d̈%LDi,HUiJ"ӫX�go=kb%'6/ K>Nרؿ"]0 $}D=ᤏDcM)RbG&)R՜s[ž{JWŽD�yqx=�H"#�������//^G@�����������^_��������������<//=���������������c /z! J�h-e�29gdWlJ玦o-�I;"eSo<u_V9֝䩞-:ev�) "=;S=QZu~RݧqDvD� g1�$K>^k* ŗ}9H]EJ1ndIIRt%D#O| >ǵVh'YITiScIuKR֎x.IDmc2MFjŏUTG!d8T& RO R%ZY?['-US cPŸ䳐{4&Wm#x̺[f^<I=J%CLeaǴ:)ʨEbͬ$4 7y_yX^1nWDz6r6ܔ/,Zq0X"xap믻gg UbPLy;NyK*eJm7rdK2Q!gy\>6?6zY5L5NR},5ji3pּ("%VeVY;lNDJRtJqv5NYo8`L6_(lՖU:N9c=$n\pd2&f3#qzoj2Rbl~k3IL%3:wϩFXsҢ2NB•\+lZJi/?6RhTeHq/8f3gpȖ∍]k܉ "UKPI%T 8Gsm~~9mG?ZPȟFÛSjFdSG5lćsj<'I+ 4ZΪ"eM15J=Ck&CSD8Ne2Rdw-[iVJZd3Oa SP n]ay˹-;>V'VQ'aH [g^aM"-t6,?d+T<Фb89NIWg#J*Iޅqdd[Y.喀/֪uOo;6 DDІIKBWfF3<D��0l-.MRi3gR'LjJsmB$wLg8WKɵpm+M NmK FN$$LJ%j%8'&݌? ճNLdT9h*Rd/iDie<$FFۙ{Q:"ɳYGUT15 FyJ63ꐛ̛3"#"KPi9F,d-*)I\DDW 2f"j9ITّ%KSKhWX\Q]E�A1E˜=IE>QmbySv 8/Hy9Ɣ/M l*Yb$+iԨ $vO P]is o)&ZVś4޲4d.yuR$͏*+9JUQ[;O בr6;jI5+UdYKxI3RM!B.Njo&۵1U[JLDɖ=SJNeٙT8jHH, "X+DRTU 4GݎC(I(jKM޶*ͫQƪdR1j 93 9敚}ۍr︮tR_>G_R\cr15Y42넜I%�?D_b엱(br"qd47&R񾛰[IAQޜVѨ9(faو yR:JRՁn)^I#$B2l��f58vfYŕh Gy-Ԧ#+fWcz%ITetj)&RJ5bBN,W_e}䜚WT;!+c^12ӵ)&[�nDiB FFBKi/u5Ji>Kb2I!$IAEqu+d:V%b"R*vYNJ(\8IK<*⸱-݉ũ^֔Q8ɧ&2"UI'DžQT1NvU31w,d,sc1eKkimNv[hh-dF7z3 tᴒ$8Y]QnVseٸj]JVvB#5KI-՚u(jRA2un$dX$dgT5@ ?f朧f [uR2N)~'}W\>tL3LS*=~KH'.$2DM!\Շ%(D]5cUVv;]9 Cc"0mnɋ&T&]<W.HId,1x7N,ܝvf"mص2gl%)FqVi4^K4tJhFxn2eĥȦW7dɜs̡sZrC斳hԂJt}]FRj 5zrfTaԗ+)Ao_DkƓ3Ŝ_f{k�gXiYK3姳QXK)_y7;oz3#q"�$rD:3T,aSf7yja[d6̌y Uzko{@*CӤ¢P^c:ggDDgָi}Ա.ժ֦Sh~MML!O3`RYi 22”51o}}Uikz^Hfu&6@&uK$. PWTXMD}$FFv0UrǔHuFCirW4/„!AuMjģ$h6��cAKe~X!lWe)D9$8TҜGLRTlR#F=+FhfUjR;M~:wJpJń}dMCby;T, eM?m^I~4"nB7T0j,)ͭݯ-Ób[0N`a rKhRT�D#2";]frqdv^RFSKQEf$Fff5)JJRRQjY%m2<ԛ&Df]K#xԂ#�Kˮ""oٸGGUhb*[fBdծYHl␒4ubƲIfZ5lJ=AO9!i$M"3,HRGqoo5Am-b(um{_PxC+%%I<WG3iɝ5 eML "Fq&S׍j4U\E$޺L DfTpֺljfMAw^̷-v+9ϓ$d4fyJ ]o%U赩vj2]qaGi2iJtI4esDiGqFv >Z: f Yijd̔dkJNDiFxM:ԍT(SX6rv5I^nTq2x-n6ř̆al?s:nc,lՖە*UJ:]",g%ʧDGqM T. a%\9' ũ!FQFqT}M䑣xmg.fNQ .WTa=1ƪN:%:nɓ-A Q&u? tf,ѺFM9Pq8IBI418uFj;.,&S*`N",YSiBP<܅(Σ/ٺ33+J; g-@ET ,0]do8y 48m xNJ}2=v%\_zвE-u -_0de5fGѲ-NbRksr@)2Zig2n %)I:HQj31Q:$z氀����CoX!~iB` ޱB҄&K~mLY-/y㩲[o�drȮi|�[}ծh'NdGy*g NcBȏkNTTA_;7i\d}c(Q?AYDvD� ����������������������������������������������������������������������CoX!~iB` ޱB҄&K~mLY-/y㩲[o�drȮi|�[}ծh'NdGy*g NcBȏkNTTA_;7i\d}c\ƣRrVKBˉrO RQ^$BgmU' &|]VRy6-&|]VRygmU'o BgmU' &|]VRy6-&|]VRygmU'o BgmU' &|]VRy6-&|]VRygmU'o BgmU' &|]VRy6-&|]VRygmU'o BgmU' &|]VRy6-&|]VRygmU'o BgmU' &|]VRy6-&|]VRygmU'o BgmU' &|]VRy6-&|]VRygmU'o BgmU' &|]VRy6-&|]VRygmU'o BgmU' &|]VRy6-&|]VRygmU'o BgmU' &|]VRy6-&|]VRygmU'o BgmU' &|]VRy6-&|]VRygmU'o BgmU' &|]VRy6-&|]VRygmU'o BgmU' &|]VRy6-&|]VRygmU'o BgmU' &|]VRy6-&|]VRygmU'o BMITIq[qJEqJI5WJO[�Do-�I;"eSo<u6K~mLY-/y㯺d̈%LDi,HUiJ"ӫX�go=k@�H������������������������������������������������������������������������ %L�x_&G,햗O-e�29gdWlJ玾4U2#Ӽ3EW!VdGy*g NcC2A� ������������������������������������������������������������������������4L2+Z_%?Sd �坑]):\VNȏkNTTA_;Y֝䩞-:ev�)nָ�������������������������������������������������������������������������2[o�drȮi|�[Mߦ[/#vEvKxsEY:s"=;S=QZu~RfD{Zwz?9OZ$�������������������������������������������������������������������������Do-�I;"eSo<u6K~mLY-/y㯺d̈%LDi,HUiJ"ӫX�go=k@�H������������������������������������������������������������������������ %L�x_&G,햗O-e�29gdWlJ玾4U2#Ӽ3EW!VdGy*g NcC2A� ������������������������������������������������������������������������4L2+Z_%?Sd �坑]):\VNȏkNTTA_;Y֝䩞-:ev�)nָ�������������������������������������������������������������������������2[o�drȮi|�[Mߦ[/#vEvKxsEY:s"=;S=QZu~RfD{Zwz?9OZ$�������������������������������������������������������������������������Do-�I;"eSo<u6K~mLY-/y㯺d̈%LDi,HUiJ"ӫX�go=k@�H������������������������������������������������������������������������ %L�x_&G,햗O-e�29gdWlJ玾4U2#Ӽ3EW!VdGy*g NcC2A� ������������������������������������������������������������������������4L2+Z_%?Sd �坑]):\VNȏkNTTA_;Y֝䩞-:ev�)nָ�������������������������������������������������������������������������2[o�drȮi|�[Mߦ[/#vEvKxsEY:s"=;S=QZu~RfD{Zwz?9OZ$�������������������������������������������������������������������������Do-�I;"eSo<u6K~mLY-/y㯺d̈%LDTmͮ2RSJRRDxUqb++x+9iJ"y4NqصZ`t[Ū1kDUEZLo`~-Vwj3b4NqصZ`t[Ū:-bjg}n?{S;#DUEZLo`~-Vwj3b4NqصZ`t[Ū:-bjg}n?{S;#DUEZLo`~-Vwj3V=t8u+EQ:|8GCq1ސ5>HJI︈ݭEk5fm_.qصZ`t[ŪvOm+Y(0 >]j3Um+Y(0 �VXQ>`Q|-bjg}n?{S;]�VXQ>`f|6t[Ū~-Vw>f|k. id(Ӊr=JQw$#>mGUEZLX*sm J DjWDE�A'F#e{fl+nqصZ`t[Ū�2ш^ͮeEZL:-bjg}ш^hp̯t6Vj3U 'F#e{�2Y[t[Ū~-Vw,#S)T0ju3$WI eEZL:-bjg}quE2:*T5ZyDJJ\"4dhIe#Rѷz-bjg}n?{S;NGCF#e{6Vj3U 'F#e{�2Y[t[Ū~-Vw,GCkemn?{S;qصZ`tb8|_W1>/+ eEZL:-bjg}iւ%ByP<ۊlE׸e}qG6'hÊmɱƓRF´UEZLY:1>/+ Y[t[Ū~-Vw,GCkemn?{S;qصZ`tb8|_W1>/+ eEZL:-bjg}ш^hp̯t6V$5jf=dM;%GS. F_1{"eSo<v..7 ,:$Bxo2,dWו|_+Z_%?ou<әiJ"D{ZwzGiTd��h����������������������4k�EW*cvM�"+ԕ1 � bmfHSdARMZ<ӆ$b:5cd{6EQfl2gqڊ츼%KRW$GX6dR6VWz*`ӚĆR)ZRV-xU떢44X-:6s!%cƴIRIWv!m8'f?a4hq41H:{KmQA-JQu3ߺ}Ŕ[G5TrdTfz-܃Yb25ḔdfD,yE(-tMbO:ZNM_3]@c|�!beK!hZv9T[a7:l'f$Z[i !w�dguXNE5)Z +]D0MTﴅ)M<ʒr\#IdZu*plu""E>[CħMzNx5wGynԼ؊'GHLF?")Id$JD�T&%7^dG-3Zh9 ɇ)u Tl`K4 hp<C?; nf""lɳ@ mδ$ɽFXexWkN=m{.eǷODSSyLQ&sjJIJ5&sI%HV% rwE~C'H|)bי<ʢ,#37O|+DY�e+IW O!لɥä)(J<#R*$xɖMɤ 8%ORKd쳄 +bks'(s]ڥgO~CqݪV~1|=]/@K�W!~~O]��w>`-^lZ (w +q=1^Ff\_*KvH3I35uHQV>GihmmLDʄ<J#&2 ߺ["VldRJC+i= rCͳ$5EPXљoiSNHGzkMOIژXm1%%J|eN8tJ+$Q,V5E�)dFFFG'Fqњyڌ%DF4+iڗ? m HS$JԙN% »#3*eYav[C-# JJ[=Xǣ "?f:,V�0>3�idW?bwP@�Sˍ Z f=24ZNkq}kSY5",?[؎!9y,HSUʍ>4v 4KCKISmF…J<HImE$lsb)Ŋk=szL*h~+6=.}fM@ݎIǐ̘B^ 23Yi5vT>m9~4Kf9ȐiJRa|m!J'*]y^b%E"REܜZ mTXR<d fY{i7wSmo��CZ&K~mLY-/y㩲[o�drȮi|�[}ծh'NdGy*g rEKEMDD'uSZ I|�Y~|d�% flU͝6�6KAadd#ڇIΛ|d�% 鰇O_2j&:l!l̃?|< ͨtl鰇O_2|d�% +6`9?|:l!l̃ڇIΛ|d�% 鰇O_2j&:l!l̃?|< ͨtl鰇O_2|d�% +6`9?|:l!l̃ڇIΛ|d�% 鰇O_2jVrD9f2,fQTgnȌ`"4IQW]UAkg~4bl!l̃?|g^mC)G+yߍ9_ϛhC'/M>2͒x2r᭟7#� lƌ_M>2͒tC'/^mC)G+yߍ9_ϛhC'/M>2͒x2r᭟7ф[oo,S6mvq2+Wߦ?|:l!l̃W6St <T`Sfy-Wě;x[bj4鰇O_2|d�% +mBܵ&O:}iEOadd6�6KAWP7-nΆ15ySC'/M>2͒x-[bj4kwMFtT6�6KAaddz cr￘<̱v|G?m-֝&W^NVC'/M>2͒x/7Je.KnJDj;R^h [h$jA(ȌJ/5ًxD33�iEMadd6�6KA�=| [}iCr￘<l!l̃?|< sj15yܵ&O:*~|d�% 鰇O_2\څkwMFt7-nΊ?|:l!l̃W6lnZQ [bj4鰇O_2|d�% +ͨ^vˮYx)4\Sk6J7Sīw\>o'~Ih-5ۡ^}b;fb鰇O_2|d�% �-[bj4kwMFtT6�6KAaddz cr￘<nZQ?M>2͒tC'/^mBܵ&O:}iEOadd6�6KAWP7-nΆ15ySC'/M>2͒x.deY(BRER]Br:# aĮ+Z_%?ŝadd)\:]$R-؊rdtkyr$,҄Ƚo>óMS����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������krb5-1.16/src/windows/leash/htmlhelp/Images/Kerberos_auth_serv_fig_8.jpg����������������������������0000644�0007046�0000145�00000034744�13211554426�026223� 0����������������������������������������������������������������������������������������������������ustar �ghudson�������������������������libuuid�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������JFIF��x�x���C�     �C   ��"������������� �D� ���!"1#2ARUWQa$34Bq&E6%8Sbv��������������.��������!1aAQq"BRr� ��?�ҔRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRUl8uɻ9&}z>;hidt TAl{4ʘ+l*!; jvqnt;|pD>sxHđDs� 'V[}R3:lH&YpUDMI*WU=0ɣN?;7,V\]eeAF6< %% <#Ōж- �""""vDJ N+VotžΩԠ'X0;b`6#**H&V\`ڤηIw(Q]HWe쨩VI@I{/h&yUEf3 <hq5Ȉ pqUE 1Wx)'-ytuEd50RPP6&."J�*޼Ot6n?7]]PV#Q1Xs-3ersC1WSa%Vne{+=fI2EqEp e~:+*<F޼^u:yی8LZ˞-8dQ!:Tnm64$ "۾»wƳf[Xp]؃2!eׅFhtIŵBU⨧z&C=ycIȋKǺN;E94"ǘ"5j2m=A1D[p$Ek|UE[TD^웪J�t_Lϐio m%3lqjI 2N+/TKn@[ Ӳ_GNDV]q2ꊛjWnS*d"S`;JڔELtP/&]X-rdX`;!uq5$6ӊl{.#3hԼwEbIlrB,X/J0c@^+Sģa۾܁? -2Oo.⎺I.-C1>ِsuEɣo.ޱX%J( $Tp6iڹƱzV1_{ɬZo7{2=+wqg]6& b˅Aqe�5߭o .Y: 3; n#:!뀡芪+u۔o2˂! EEOTZ:C+Ysel$6Jm5t[CqSS[wWn:I=ɶ>k&C=ycIȋKǺN;E94"ǘ"g<w~"/)Voān*mƕ4-!5T^군i~sS4bnZ�D)naepjݷd-O72S/&NwD[IJ-w0+c,]ϱ'*iCp n ' vlw@TL378ʽC8"+.3ِ쓒&$;H<�ؘBkKyRM-E\rlWQ4$2\OJqZIx#u �"7aDU]{dc97kz+cG>.MĪc̺DKKYuμz=r+.qc0]I& B!RblB*Bjh%׸%Yށ`Z}v^TnimQ<TBYH+@J 쾥Jrl]lLPWUM @USxUN*ιϝ9m\mu~{RҿcWQ}Z5iΙp4{o_aХ)@)@iنpvsqLH|vɞi1VTCpw$ 齡Hvq} 5Yqw@6"'$MRATO+J)vgtؑM+nઉ(***/tT{:awF~wC-=so/ XM!*PmxKlK}x"4 Gm[A�DDDDDD숔xW;}՛{SA2Oi]3б9+aev9FSimWtGTUDq$Mʬ=w{IѝnQ.& QSꬒ_JM ̋fy6X7T( k .⪊*cSO Z|/r!u\ja8 NmæMh\Ez:gT�xb?�mɰ�~nnN|E7J@)@)@)@)@)@)@<o1ov_LnNtы<%& 'b-:mu1O?/9&̀98�e^;DD@)""n~ ;͗%Օ:0ΐO<HJ"( ��� ��9RJZsSp_qەwzq(`&e'7r$싁{6m,xOg2y̔vyO3}<IO^J1>o_UhָRwoϴ&O?:=V]HSOΪ>ұ[i~0f5c!jtM*nvZsb*!&ʛ}ct*L$i(y@V�8\ѱ HoTպڡ-s-N1",ƞlDPQU6TZV`pqR6:~y^72S9:1'є{*uvIB"328*ي(lnh ÅiSa숈SyV¾!l+AҸo匭kKG9Pz.]>iemdi\`+iR=;ߊW1?RC{Z7>Ho $u\ȶEzk~uR!$1n*bDq-G6㲱Uǥ<@TM)vnS6Hq 0,'"UUMx}.3u?I/<r}DNnC(wRmwTE]+xl+ZÕ^7χ.p%7l @)DD~+a_J{ OԠ;/,oj[ ViA/O8HHlo^b$Zmrui v0x,+x+.;!݁S-ZAlE=|C+JsgSǙ@ =nvPZ#}$< vUONՊ51~Z V=�H_h1uyAߩ5U{ FfTwyy@1EMtf+ Ω`2ؠa"""9OyV¾!jcL=;y[m#p6-38 6 l""=+�dxN+].緗:l+OyV¾!Qꉋc&)h6 dř/ZJZB%4D<eM�"&(SoyV¾!l+Z(G8xtG]�Ws"zVEb==%Lg+IPAR"E^⫾{ OԮD/ 4JӠa" �"*Vc)<#Ε矴,L-=[b ؤ؄ONTpymE�Ȣj".J.i^q•0\!MHIQqҲDn6,Wt?Q\WXmBQExqQvTB~Z顸}mTp ')bCΒY*=5»DG踱^/Us3?~22ʸӊHJ+tUN],ɒ� _'+u[moh=|C+kg ˩"9Eb踆„\]mDWq$^#%L5Žq|>I3e9F,\DnlslTs _i KK|QHrsw(Pi0n[{(n]'dÜu٘jEՋU'aĈ Kc4T̪nB-GeueNL$)3* ""�����zR=dt=bj\6}v?%i861E�'saUM]LG<"jTz9h�..حBz,”R/9tQ|$YVuK ؾ;eh;uzion&j nmuDRI8"̯Ԉ)jO*GfY.\i0צڋl7~s}չY *n( "Zo(7P,U@(4lxD"5Yt޺[T;e&2qE8͐**ʋZ7eJm1ϳ=/q JvJ5%UByc*mȶD)@)@)@)@)@)@&P,?Z2yix8F<I3Mn"& jue!uOaXscPo.,In"DTpv6^"j&*"Ҧ)7-1_m0So8EpE ]y[3FZؗl'Ǖq$BT!TTTT쨴+o}q}bgź-FT 4ꊨoFdsӫbcvvoIOrjFOL4U7A xާsŃՆ0]ku31O/?]Aؙ#öj[n HCG BAUyRywA0ʴ͟hM-6S42TPEA[EҺ{\Vڼ<1d3y㱹d9.^+b@"zQ󙟒%5"i;0cXr11yq #|Al0|eq|{5ܹP"n8~*j-6d4>,8R*@n]Ě*)ܗn**7ӿz º-Xb Pq%GMH Lpʝ W:Ppʝ W:Ppʝ W:Ppʝ W:Ppʝ W:Ppʝ W:Ppʝ W:Ppʝ W:Ppʝ W:Ppʝ W:Ppʴ8ceb<(b  ?5FP96U,%ntݳ[΄}�,ZWNAzob6P*)EJi緜=Yqc6,CeaU86Bf]RAzVk`,:cGډH3j LW<v{5G'�j\CW^V* u:薻+%-mEqiUU;*-j~֒ 7Ǎkݤ�Fj<Ŷf4Bf�K&ꨕlN11b~&&֋5Ѫqv+<h.x`kp><*.*aMɕf82`گuMIP[Rb{;*j(KbL﮷j~WMyGJ5:ejq,bZHs,į0_j uTf oE}]JV(e)Z&K6k5Evaֱc(c3bS}DF6h>2>Ufzn\7 eR5EM2Oe/4Î@ ˸]3%Sw8uMU"U#%R%UUZwoQW\žKzY!QV!n$ i)J)J)J)J)J)J)J顶.Rˮ yvf7-XiU]}fDy=(xL[9?2kwҸ'Jk6"!EdIMHzh(?_L-zq;;2nimWu6%MqJu(&>8Yw'7:RcssM|yNWbϬ:W'<["JBH/W(lŬx\'�˛ tz EDd**' ݄̊SA1ProsחmaӉM~/;)R".)h5Y4{Eiˣ#"R. .UW묥((((((((((((((>*oS˦\K.5K%٘ܵa_5UuaG4UuLH 4JPL|]1l0Qq߳J=)ۮl!%5!頣djf1~fV2$ueS4Dɻ5 ]Hl6R�])Ԡuf��gOx[;J Uq68I9^W>\l+[P^[!) _\p�.nGp)ӣmԁ䨨'v_2+UNCyɾs5ow^^e㎝ N'a69H͠oX-f, L?.tp|H" nDD'uU_RRRRRRRRRRRRRRRRRRRRRRR-J,z\1YXv;>MA㭴l*u#blu R R R R R R R R R R R R R R R R WVuc˸ܥ~DN#m2آ* "*dD)^8;'}e<ʨ>d=;̸92�R?:wgq`ђ5_mQI"F$4ڽ,>vu�7438HLHm]׃@�;""}?Mش{ z'݋G p~- Q}l^ ͱ3&!dȮ(*(?=ĵ" Zr6ۼPAo-8'͊7ANL;^q9Q FXC鯙Mp[iMI&:J$d^㚁۳\zplt.|}x<4!�wEJP)JP)JP)JP)JP)JP)JP)JP)JP*c�-�?�*(}m\ʥf8웄@46M;308' c.V)JP)JP)JP)][.r |F8bDfD(k,x|1f�pxmcT*Ƅl@x2lJ�vI# lF )_FJT}UE$tӓj|H|?+#1![w^ ��ﰈ" RT>u6b¬+蟧Ov-)¾t$/EE�S%ocEv'{,J6pM""|Sxԋ6Y�Minw}CqsIJ(6(:1'Gy`G3aSd"5m7$*!7zjnqN%Iй <Tv!Ug)@)@)@)@)@)@)@c<+nD'Ou}mO6R \tAU3EZc�f�?,Ƭ#FTI"^f9!82�jץM_Q2</ N  kxZlhzWP)ZvmXΟ![tMMa?I΄fqEx&%b{Dim|# (ZG\dQ�  l]\JԨԬF'n~J#Ѥtɾ/$BOV^Ro}Vi9ͻ:?s'BǩДAA.!KqUJA:0Ն?.rx^ =8򁶍Inkm͆(ΰy#tqMe@%D$]EBjC&hlU$Z.+VteXNiȲvɔ)n Ŋ8"�PR?!皍\??Gۤ&? %n*)S;Unjl}" 6r7!DE7R3-*UU];T((((((((((gmҘO[VtZ2⫎6*`([=Lt 3ŖxՑhʉ0Kۇ9$4p`T@0Z&G6!iЕֻA5Y=mw�@+M oJJ)S| [o Md +0`j*v."ґJ]p]$\7/lOm6/q"߲-vcIJLJsr41dWHoǚ�m쪊hStMqKg7ZպҴLC[ie=$D)l"#͇Y<uBM1@^mIй+G:>=NHg ty[VJ ՗6dV70yw ~n" 81ǔ jHu[nl1Euqsjk**! Ȋ*R5EFg 'tJia3:Ӌ _UwUq`ɉ[rtPt"EBPiJP)JP)JP)JP)JP)JP*c?MNy<P; nIWL{t3V~]"t_2;+= t\$ 7v+#hIRe�! ƕa �rs#<#J}(nP|K *RR/ n [t\h7;Kٽ.B,d@ȲPc<4B$UG,Jf8]m^2U/N  " "_<u#rjђƎ}VYjP6{mQTE۶X΋iGhڮ67sځ[ eY+*.Q=NS DWi>s^x2KWV,8տmWX $]7DȚX! D'>M=dط#5V([ض-Y^s3/)n[T-0a} ZdDM UQTQ7TJp}5;={Lv|0Yy9l늡4~e|V�dvrg̦\2K^ʮ#30J1V}UE6N()ڽX+ bɏD':TmMWHQ7]Z2Æ9DGRxO9)JM HlvzӮ2; $f)nQ>S۰fTGgK`eQIvUUv^Z$a3;;Y#Cs~6s䇛!> mUTjϐJuKqDb%ӕpmR&1Ӂ4M;QmxLKK.h}_d> Ě3:nϦ䐂 T4wWy{QnWlu#6$E8͒(**TZͿzv=bUbܳ m :#i^-'u�7UD}ݱos/-o_uޣ'r~3F3L,4W'lJVǵHP8b7fѦ\%2(*.J{Z13Q?�dݱos/-oMN_j-ovž<<2V'7݉ldgQWngP#-Su%DEZc`{L66yvldFs섪Ըowl[\)}y{eY1-ظW a.) tx3I!TTQ&>ط޹ǗS7ʧVz5'z|h2+\ȎAPDU7^.wl[\)}y{eY1-ظW a.) tx3I!TTQ&>ط޹ǗS7ʧRc}y{=ݱos/Ӟy=5RkA90d2.#e]1NjP9裾訚hyX&+4o^zEA%M̈́\U 7"䈩ޥ]jfkߓ-ovž<,72go0^U" i|�*r11&>ط޹ǗS7ʧR>ط޹ǗWWCm`7<NV,[Vc&Kn ox%ŤN %$qiځ,K]s#Ю1E0Q8@wb26%&Z!00iZv0'11cb4LܒMİ%! &ŷEƃqT[ڪ; igAuN":"}�i{1[Q!*ƭ,Xeg܄\D]n8򘟉XC[f}n}cb"KuXfMw/Nd8*�]ZL9V/%N\kq.IZq8*f}69U,sP\gÝDpr955mSȉV'Ҭ+:.9X" mcDTDq�Q wjFLN/"7|r˭|N_2.Ͱ,>~j0c0 68�("U/2y?ZN1<bpY=qUYPfD˒B=˺߽lu_>zQyRr6fwݠ1\dvH#PSr!{}ur[vݯyjr8l̸).*"*ݑkY jiֻݢ!y9rmEU:`y#jϐJuKqDb%ӕpmR&1Ӂ4M;Q R R R R R R Rl\YeԑEbl(ELUwEZa^\c$Z՛.R'F"Fx+<j%PL+-̦|\-FDmv"l2^I5啩JvvIQm!qwBlHU QR[>uCN}mţ߅8W?NZ=S|=3v`:rnߓ9=֑vmUE ETI7WV}˪8?9[v N+by ́w GtmX]W-q7T@QS]?gQSdMPLW\l4 #2]ې-8򈢂7ƴzfǿݤ27܁y܅@;`�^@o*2VJ)JH3ոrY0CjN;|P\֗d'Duu6Qߌ *) }!Rb|琼%b_Djk-FأKC%D DQcbN<J2b>"bqTTVZ&s\"8q-[02%7BBTQ߉~a.+eEGL""y})(|/~ߪ{zo])ҧ]qEtCqX nc(ɰ6$iDGw-&-:@WX` 0] TlHrT*4nU&j&y1Pf 6ʚ~m;\20ub.ꉺlMXn>8rj[r .*tddeB&D]/U;m7#@ͮqG`\'2ɷ"eBlc.p*Y11jmvfb7MLF:DUOZzf'\>3?|3q�/k_g&Ct3B科31.1E6a?dN;-_+Jh[޻xsʹGx2AԁxB"}UƠZ|՝ykn]sr#!+O극/'GT6MTU!DDOOk×""qbmӎsZUD]2D b<ye|#.ڸ�~=*B*H脛�TF_u6 *.oՂs*dM͵Mn-954h^3gɣ5q-B *mғ[LvT7zɐ0 񐁩G9jLLoˌEMXOWүZ%y+5tvFsm(̇m ^?PȟUk03̲7x8bufpZxg84�ܞlAlTDDzTh<<ߍqsnK1 HBvN]P>Iaxu%T%od`g(7Oڢ.^6Xɱp'ډĢ88N"QDwSo {UɒM+e>O- g+SQSZ4uͮW%Ck P⡣p(e.vui'e-]Q$[u"cqGyNP'ޙ֧ߗ ؾQi1{"iqT_�RZA`�:0K >uMn`WMzo*n$؏eUԼ\Q,mP_Dx& N1q\bZNyҴ8=\[L;lyX1PRrB[dM>BH#|EHE(Sn)6#o,܎ۊ-9m7~a^Ox7Ikͪx;JR`,#WډHOL+ˌdrC]ڳeJD(HEz<DЂJ by+(ޢz#BM9fB =<#N¹Y*9mä.4M "**U2`Ψ}?Mش{ z'݋G p~s.LOM|'>nV#:m&�J9u^'g1c\x[!<@.8Ο\Ŵn3F "o밧" lj y[&_;ofWY뷕[rWerG[QPB5Fx֏YטنSF8?l��;mE\^j@)@)@)@)@)@)@)@)@)@)@)@)@)@)@)@)Aqk6ggzӐZ`-O 4T]{V7inol;K #JMm9"*oҥB`ǭx5mh BCd!JU9M2ܳNqL.d͟!r ;r]Vx鷢JةMJJP+Yi)[1D,vnelHlE̽lԩ1Mh,zOZ:``#ۮTqUNi)* h"D[)ZjR+|7hbzPr[*"(١>SBO*vXCY=\{m !]s5<eGd<Uy*yz芋i4c7[|(Gpf\J`[<k5:Cr][Zp"HN)*d숉UPa# Eb,2� l""=+n٢E)JP)JP)JP)JP)JP)JP)JP)JP)JP)JP)JP)JP)JP)JP)JP)JP)JP)JP)JP)JP)JP)JP)JP)JP)JP)JP)JP)JP)JP)JP)JP)JP)JP)JP)JP)JP)JP)JP)JP)JP)JP����������������������������krb5-1.16/src/windows/leash/htmlhelp/Images/Leash_properties_krb4.jpg�������������������������������0000644�0007046�0000145�00000071443�13211554426�025542� 0����������������������������������������������������������������������������������������������������ustar �ghudson�������������������������libuuid�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������JFIF��x�x���C�     �C   �"������������� �\�� ��!TUV"16QWs234ARSbtuv#ar$%57qE'8BCd�����������0�����!1Q2Aa"qB� ��?� U+1k!ib˴MOVZ=稩hBTR�ldY":sNN򲔵=c(N�#_R50U4Z|zi&,U˴sRͨkZZcqDc5HgqzОOLMǨ`;:`;: v2vSUS&zq7WXZI})MWt$+v MYy4?PTÐeKa\q+Axz]盏fj:sNNj:sNN'Mtƻ:~(orGmjgĿ;Uť=w*d:gݛԒ٭+EФlfqP׋wuP׋wurNl:JjC K2+mq1qDerRUg+_gebM2`J(/2$>k4ȌYO3-`;:`;:Y{2Y*vH+"uuO)M p]vPl!ƃi*͝D.Ci5MAU)]cUt52?Za0up0uqmH&lmRZYqdF: I㑤KǛV̿iܳK~EYXb UkJ (J~FE_y\,KI0up0uqN RL>PCUmV쪄7$j(B:w?�,3P)봅˛�E⼦R=_qg3WC0up0uq\#9鲃R<LJyLF\Q\g,�T3!e9Tr6Kq5Ti6›&,lqKs3i֬N4놡4{eeZ2Q5NS눅W;&INނQ21Q 2_Phi[egI-X+gywH2WC x~\5 x~\Rn JnY%ÔKN{3#5׉MabŹO1U'LRdĚ|d,V+&+lp4$̎fk2k-z\ӿS\ӿS?}q-=-QRE*+#J*%6RtdrR 4Q0up0uqgK )yi,C^.iߩ C^.iߩ,◘&q&7P׋wuP׋wuK!/0d3 7I0up0uqgK )yicu x~\5 x~\dRC?^`s}ĘC^.iߩ C^.iߩ,◘&q&7P׋wuP׋wuK!/0d3 7I0up0uqgK )yicu x~\5 x~\dRC?^`s}ĘC^.iߩ C^.iߩ,K旘&q&7P׋wuP׋wuK!C 7I0up0uq4iyicu x~\5 x~\d/0d?^`s}ĘC^.iߩ C^.iߩ,K旘&q&7P׋wuP׋wuK!C 7I0up0uq4iyicu x~\5 x~\d/0d?^`s}ĘC^.iߩ C^.iߩ,K旘&q&7P׋wu& E*RM:ٙ^I5: WFFw^WR G>sTl!Wӯ)l2[vqrfW2srwC}b~?�K+Uʖ7)~M,߉X�#-IjYqēMF;._-iUvt}MUZmۇ".:JWP 7d(lZ%Q#\kOUTm$(6&E*11ouyR;G~)}U�ҥ TKoR�˗}9<ٜ8v]Y\ hԸ"'nQ-&wg"IffZcgSQT8-'RmxLnH`glzM62KU8O-GKfьIzLȮ2NĤ6ONymKT&3"KjRv>+wB<n</oY֗ 9YN»KLTrl $U"-6ҳiqIHB\I$Jǫe#2b*e&E&,ɋaɶҒFFia_gy[~wnE?T^홊p]wI?ȕkT8֡jFT>Lse3I8K"VWqs-TYU`lC 5)Uʨ?-;)("RwN݉rIbI^i-Dz$;;І+wB%)I|$Zzioسlj5K]G5)k*Ѫ!h6Ɛ!QU+V\2J1gĕJ\ڣ:'R}Qm)%=j;cnl ;t!$;;Ѕ ""ߤTS<�rU]eXVQgKSxǫ%侧1&Wb(;#~;mSjjQ\v4d- b㤞i)Bu_57$9ݶ_gy[~wnF] KO<~YT68G9Z#Si6҉eآUiOr;ЕЖVN%$ddfygژ--z_Y2VXKmLKK%^dfWay~wnCeIvw<mKPX/ag~a*y)}z{ i;xŌYq;=5$;;fQ5MFN\IRJ땝*5 ;t!$;;ЈT5�gF,NQM~ZjHZ&6ͳq5iplF%+;[ )muŚEʺ,5/TC$9wC_gy[ݥ#.8t4252\#Qr3E.Lv_rDخz͜(f%]],Ԥ$(ZTXYFRrv(I/CZ(IRe2 ^\bIDgy^ynM'qV6_gy[5SNy{`Y[m{-+ʟWjnm@I$)qfxܒڝg}6^&[~zqFj*%tHz$7(J2N~wnCeIvwuo`7vXkelyq*ZaK3m}DJw&E#?Cal /0/N㳼l ;t#Oy]$9_6M+qV6_gy[<٢3{?C %n;;І+wBlЄf eJvw +qV<١/? &+wB/V㳼yB9_6M+qV6_gy[f#7sl/0/V㳼l [t!Fo` 9_a6_gy[~nC͚Asl [t!%n;;Ї4!`!~nCeJvw6hB3?C%n;;І+wBlЄg6 eJvw +qV<١l/? +wB/V㳼yB9_6=+qV6_gy[f#9sl/0{/V㳼l [t!Fs` 9_`_gy[~nC͚As [t!%n;;Ї4!̓`!~nCeJvw6hB3?C%n;;І+wBlЄfk6Rh$?\)2q6}>.6.5ƺ2_gy[- 6vjuA(&*rR]Vq/F­?��3jint0vjRK"9c2nlgjuFcgRY,,Q"Y* %4}RJV1%FfI'Ԭe4Rg36KFѬuRx̼ZcI.!DG7^C[VӮ'?�;:6ƥS'֫}aQvaS^GZSGu;*-Ql4Ӧ;dF;3e2f/;5وSb:/=;䩞6`d)Y!-ܼ!p#ӾJ#i?<m`5 n86f]1+6e+ T35GZﭴo^8ڔz\M ITSJZ̴w>r!Dq }rSҫfv'ZFiv:[@ݮqsA>ʄ+S]V"CL8[J"I\Whjm IӍh_K + Q- $y&wX{u?!]5 n8Qy`FllΕCZ Aq +\H2JӊRFXU2`RpYS'e*T2MqN7DqoEiZQN<"WmU-) ^ݚs7kG KHj^p8qf;GvbF j0hf8,[ݎP)n6o8KrN% Ҙ4䛌Fi9'Q>7kG\?h;\xgPQ- .EJiҥ;i'PlCq*4.BqqUrarOT؅,-K8R.7I8yRj4J"I)xϱ0Mmvph^smY]ci˴Yi D(Ƶ%_IݰJ7k"KaFKA*xo-f KUETQ,WS)*4&]I2fY2b/q3?轊@���������������������������������������������������������������Ȯi~JvEwKSo<GӘi%LD=;䩞6_cCqfVU%-K"!RMخ;..,RxAIzJ*5,ӥAmm*4\'q.MIXfFex�I(E2U#`B9LHj==Qf`KFDGڒIOk4 Wg:W%_z ŬDDwcvqD,4 vm,jPu̘$^:ۥ*">ݖ=K17cTPfSSh'<qRJn;n-Had44II7jW[�El58!H1Q5SNLfcp䞦M�R*]&VF&JAgyG}D~SMmVZm͛r$DJȈ,QQ`^rkzc͆Cn+d6(ᔕ!9kZf֣;r8g ֕ΐAwR^hYjx,d♙�J ݙuAt윙ސ7qjS=Mfj"IaQ4*]=oXƬFW$33;9p w}Qp%�. &g-P8" JKHBMJ5(Ȉfff%8A.2.7v\\N˓Sp˓Sp  r~sr~s;.ONy.ONyp\'e8e8\n ?u9 ?u9 p'<'<pA.2.7v\\N˓Sp˓Sp  r~sr~s;.ONy.ONyp\'e8e8\n ?u9 ?u9 p'<'<pA.2.7v\\N˓Sp˓Sp  r~sr~s;.ONy.ONyp\'e8e8\n;.ONyƻ^[y8(w " *vEwKSo<+Z_y=ݟ >wӘi%LD=;䩞6_cCq A˟4R$4qrDdN2;A-m31U bj \M[CRIg#S P#I©X)jjjv;nhKnADxuEm|{VL9vF:*&7$Kq6Y$0LiFOVΥ\Cn*d tj|8t RMTfT㍮>#l;W&y_e?fmHa¡mKk$%)<KgT#$&܋ld}RjPjKb+)o0!-GfK(Aw#-9٦I:_h,2sG6:\9ZgGZ Wgn$WL48fS($WL⣼y\M0$WL⣼y\M0`z⣼y\M0kIq4 !늎Iq4*;'�&�*;'$WL�$WL⣼y\M0`z⣼y\M0kIq4 !늎Iq4*;'�&�*;'$WL�$WL⣼y\M0`z⣼y\M0kIq4 !늎Iq4*;'�&�*;'$WL�$WL⣼y\M0`z⣼y\M0kIq4 !늎Iq4*;'�&�*;'$WL�$WL⣼y\M0`z⣼y\M0kIq4 !늎Iq4*;'�&�*;'$WL�$WL⣼y\M0`z⣼y\M0kIq4 !늎Iq4 Li-q:qHQ]JI'~Do-"(-B�d9g+Z_y]�[lQt{wS=Qm:;{N*g WX�Govgu�"Q;ޢ}[ K>ሔNV9NV#U$G'FFQbMw3^X爵laȂSCqan%1&HysSyH"N*JXڕ,,ҔQME$O$;g{D)·*#3B81f O-3yԡ+ַ Om"tՋR\&SWS(NWn f}qW!T^aZ:TZV*rHE̡Ry$iqUFdfW K"q(ش+Ie줒В)Ip(�V��������������������������������������������������������������:O}dF:O}dF�LL2/b~[/&A{")-/Oυ'N`G|3FӫHjzuuv�iiwXb%'ձ}Dzl_@L���� Xo՚TښZƶTqK| ]ƫQD~ב_9~;4lz!UXJM<Gqfd++"!@`ʹrUzi]ijP2y։>drMK;Qj^qj{;%Qp+TkrP(QW%2 JM;)dqJmJLl`gZ*TaUeɅtrF&!%:qY \c2Y&u:?ˑMj'Rgʦ8NHGRێb*22H #3;57Ӑ�jZ3dZ`&!r]jZ\g9y~'V&SV޳8ܘ׸ީ:J΋xHkh{^*Ϙf䖛7J:$KwCrDzgcjZJc[M34 |evj(MKX|[ISnVǦ%5!=h4kq\kNk�QXӥ"ޜ9]Y!K2Pwpi!Rm{l'*xq% ;v*rs++3j;Um:CHot*rr3Q XׯC2z_t-L]Fj-t8hRnQ%$DQLJ"f�^<�sva)M9hcTQdËA2Ḵq2֣Qc]Qו.hME5KʞU ^DnF4ݩgIخu^ŗtuZE[cWVax5w5x.{kǖKZm'[jgl\bړڞ]~/i{Jw\#T9F=cXЇ[ZƄmnlǶylyk=cXЍpjoc\<<{hF�57[ZƄ=mp4#l\--cBǶylyk@. M{kǖc\<< =cXЇ[ZƄm S{hC--cB6mp4!{kǖdǶylyk=cXЍpjoc\<<{hF�57[ZƄ=mp4#l\--cBǶylyk@. M{kǖc\<< =cXЇ[ZƄm S{hC--cB6mp4!{kǖdǶylyk=cXЍpkm5cQ7:mMIu*eEq/$^dDDE}DD_)>֭[5u~ 'վW ӁLL2/b~[/&FYxdW|%?{>px9TTAN!0#ӾJ#i?<]`@>ሔNVϸb%'ձ}A0�����������cz%ITetj)&J5c!'y,k�2+ )f7 K3P9ŀY2gxs{}`ij; X 2gxs{}`ij; X 3PPi"-*,g~+BTW d`K*`&[6`K0g%0 $lė\6`K*`Ilك??.lė\T7Pٳ~]pك??.n%f $~]qS�BKfIuf $͘3IuLu -0g% 3늘[6`K0g%0 $lė\6`K*`Ilك??.lė\T7Pٳ~]pك??.n%f $~]qS�BKfIuf $͘3IuLu -0g% 3늘[6`K0g%0 $lė\6`K*`IUZF>1)FdK9$g?�R}[%0!}[%0Q`LL2/b~[/&AȮi~JvEwKSo<GӘi%LD=;䩞6_cCqDzl_@,"Q;ޢ}[ d��������������������������������������������������������������������������jY+фjY+р�h_Lآ`ߖ `Ȯi~JvEwKSo<GӘi%LD=;䩞6_cCqDzl_@,"Q;ޢ}[ d��������������������������������������������������������������������������jY+фjY+р�h_Lآ`ߖ `Ȯi~JvEwKSo<GӘi%LD=;䩞6_cCqDzl_@,"Q;ޢ}[ d��������������������������������������������������������������������������jY+фjY+р�h_Lآ`ߖ `Ȯi~JvEwKSo<GӘi%LD=;䩞6_cCqE2? L%'y)<Pd/ !"Rwu"Rwu�/ !"Rwu"Rwu�/ !"Rwu"Rwu�/ !"Rwu"Rwu�/ !"Rwu"Rwu�/ !"Rwu"Rwu�/ !"Rwu"Rwu�/ !"Rwu"Rwu�/ !"Rwu"Rwu�/ !"Rwu"Rwu�/ !"Rwu"Rwu�/ !"Rwu"Rwu�/ !"Rwu"Rwu�/ !"Rwu"Rwu�/ !"Rwu"Rwu�/ !"Rwu"Rwu�/ !"Rwu"Rwu�/ !"Rwu"Rwu�/ !"Rwu"Rwu�/ !"Rwu"Rwu�/ !"Rwu"Rwu�/ !"Rwu"Rwu�/ !"Rwu"Rwu�/ !"Rwu"Rwu�/ !"Rwu"Rwu�/ !"Rwu"Rwu�/ !"Rwu"Rwu�/ kV_ƌnc%21cG(שa 'Ȉ$WY�(-B�d^�h_L,EwKSo<+Z_y=͟ 8<N{N*g WX�Go՘i%LD.ӌ ������������������������������������������������������������������������������~[/&EQ0[o�D0rdW|%?;")zuuv�i YTTAN!8uN|4qX拱n}]N>ሴNVjmm+4(9S >o׈CJoGjxJ>Cqe$˔)TuF} % .qh̝&Պ/v#eU2bj2.VBHd+S7JQ =rJ\mZY5L5NOe},5ji3pּTfiϯUGN�HX|?kY_PڻOO(eHm) 5#VFfeDNmՎȚ] ~]ZiGim 7Rq7dRO8BU-n<ۈ$//AdQ󚯾+l5IH~s ֹ Җ&ɫVq-pR2Js ?q�q_mF`YJ-^Wj1g7PX:Ɍ"Μ~jo!ߢ,V-B4gktj3dDN21Wt`B%6FK\5f١AbnKܼ>c c59Eoe٧ԶYiC쾒nݹl{T3";3UL7ֹiyIE)UVH]J\66:%:]y+|Ԣx2mJM䑖jhmZ{tHrJƫJC q:npF Ƚ)=g5Zč/UEN3H46Q$F١X25ӰaJ~Y**2:vZ"&< u8֟B2ɢX,SȏCD8㯒CI&MSy\fX wem.Nbo'FKLk,�d!rXē20hՒquR'j,Dpi+#ϸY=X=z$h[ԣ\Ur A2*(̨EޓIfR:4e0վe:mȟf *tz-s^q+[ u;f7`iQcM?u25\JZ 9R Uӟy2NSЃZ_m%q.ĬlȌj6>MLF2ֈ푩jp̈JQb"m'myKzt2m.}} g`mZ<^[jSfKEn56<VVZ83i[efdXiU֩3E!oO8S)23!dyn"fL7D+H݊YuCʦ"Yn]x tT!>Gf^Uu*.Z%H()2mln2tq#!tԩ]끜-It=JBͣ7PDjIlqR.S#.gnj?zm~νKUDbui2[*6ԻW)WsܺxSMh{'FLRtbmxHYLRta{'F&!e35IцS=sTx^�{'FLRtbmxS=sTe35IщYLRta{'F&!e35IцS=sTx^�{'FLRtbmxS=sTe35IщYLRta{'F&!e35IцS=sTx^�{'FLRtbmxS=sTe35IщYLRta{'F&!e35IцS=sTx^�{'FLRtbmxS=sTe35IщYLRta{'F&!e35IцS=sTx^�{'F=JD֜Zz+iiY%*Ҳ#.i>=>֭0Q0[o�DȽ& }mпYxdW|%?{>px9TTAN!0#ӾJ#i?<]`@>ሔNVϸb%'ձ}A0���ckWh(u(aF}bS("MQMQA8Ĩ֝I$̌ćLŒ qIJEy""A+zH@ciciPN1*#uR}%I3#/!0P�Zȶ>1*I?![jZqyIg33q^w v23 <�@)qN[b6wǘ Y3 <�@m-1?;lgxly[b%f v23 <�@Je'lgxly. )c;cO2+0\@Swǘ e'V`m-1?c;cOqN[b6wǘ Y3 <�@m-1?;lgxly[b%f v23 <�@Je'lgxly. )c;cO2+0\@Swǘ e'V`m-1?c;cOqN[b6wǘ Y3 <�@Y]B[ZA\R]""F>uw^Wf \Y'M "mD]$~Ǧ1=PA;RCRBD@NǦ1=PǦ1=PjY+ц2ZuZY֑0:,62ڍJ>楫Eq\YtkV_ƌ) ~[/&EQ0[o�D0rdW|%?;")zuuv�i YTTAN!8 DwD/@}(Q>2 �� g[]#1ck(Q"4YNjҖVHK%(cI"=?D}ҿXgh*/c+6z,(pY&T>y#4G2R||u+O[ js%[ɭҜ5"Ye-H3dk2(FF*䒮Qu)x e+%io:?6m)U+s3s]CQ0 m2㎰l94cII)m l`JZ6U%>Ka)OI7I4Y)%y De6nQګmriyp d%wQYwLg SRƅG-BW%$^""(}={Wyx$ nlq-57Ӑ 6= GOqIm&$%e $fg<K [KUL]fS94tcwZPHzg\fh+ˬT/E!1S(! /XV&;jR p5c8Yҁg0Gգ9ZuoBZ_Xʹ]Z nJ1l;1M12%鴹 Jfd)fQ?ZIA*v)e¨B}sZŝSl O솯=z1viZC[H5UDzZEXWø {>1DҭKp,PԎTn7$UI�cd6tMD tjRP>n6$h8Wg .&|]9kCO6H#f4R̕9]v)9q-z,__dXOג_ynMOhhB ѫoa$xOzLG[ZMi3tN[[_el"HQ=ZbȬ:ܷ#mʜ"mZ#RV5 3XښJJQ2 L~E=P~"q:FjJJW_q`J*-5 OXZ'fJmKnÌj&ޤI ԱK^:Wɨs rYKUVVvzE~M*=Aڌћ"2Cii p7zI$}|/®!uA eF)o,S% *-[1E#v哵jvh%ZVY<KuId3$6#3QJ3S+:̩%&J-Mm A-ԑvJR%fT^l)vM)zFNë~;"KvQޱf+2NbEitq܉0$RVϵtƟdJlVkw'Sfz(TuvFe,1q.rN"d+ Ïk֧Zr-:Czвh]qĤudYYt[O!kuNT$H7݊CHRќ'`dRA^WKKn~=0A s[Nf-ݜle|TPOVtꐘZ]vk#&SQjȕ%ئ<n5SIwjطnn�ZA3T*Za'%r5DV2WMT^ec3+f] ̦PfT<ή_)l̞Kk"+j#A-M|^=zufTJֹ{1Ӱ�epk@yk1 Kl4)r5CQjV-Ģ/*wdQi0(5tUMYavKl䧉v6S>9$=KTW^90ˬ:%q=o!&?鴅j3Ӱ)ei4Gi0Iu8UD4=IqRZm&i3ĺ3wzvy\;[Og[YG96Xv75, Cc폖oJv75, `:폖ok>YA(<u, l||P=x>YAf{�l||] @fc] v7%c폖oJv75, a??�S]JnӝZWr3v @�M�;_X=Rmin<U6$Maq7%IRh3JZx-bGD�6VN]գMr[ۉ!1겣%)JKo2۩m޵JFGyi^uM$J;SZZYXl]9ˌ50NeUtem$V1/ S ֢r;{\Bz;kDW]4:#!uz)=XT*ΥOuFJ 5<S͛1]V5"[shqjU5;(8Q RdI"Qs>b՞]IE˿n725 YR)K+}ɪVe1ҶP܂M؊736-½K 9Eg^m#C!wJEZq{bJM$JI"J iH$&\N#jX덍zc1s_pcpwAzTdIqߘ6N<N2PFI,e\Eyߥc2Q\`ߖ oZJ4aPo-"Ioh0Q0[o�DȽ& }mпYxdW|%?{>px9TTAN!0#ӾJ#i?<]`@>ሔNVϸb%'ձ}A0���UW6"h3::1R ̉D�0)jeq.IHZ9CmB-5;.K1[[i+yd5D$Q|&dB&$�̇cӋiFW^a-ec1*S)$s3<y˕f 7uHm-1?c;cO (/yVn>ʳw[a&23 <�@J/yVn>ʳw[a&23 <�@J/yVn>ʳw[a&23 <�@J/yVn>ʳw[a&23 <�@J/yVn>ʳw[a&23 <�@J/yVn>ʳw[a&23 <�@J/yVn>ʳw[a&23 <�@J/yVn>ʳw[a&23 <�@J/yVn>ʳw[a&23 <�@J/yVn>ʳw[a&23 <�@J/yVn>ʳw[a&23 <�@J/yVn>ʳw[a&23 <�@J/yVn>ʳw[a&23 <�@J/yVn>ʳw[a&23 <�@J/yVn>ʳw[a&23 <�@J/yVn>ʳw[a&23 <�@J/yVn>ʳw[a&23 <�@J/yVn>BS49!}ԩfdb3 <�@Y]B[ZA\R]""F>uw^WY ea*-(֖ٖ 5]uM8E}wyu}{i+!e <e KF5%zs%[m%d7 s rdh#[@ݮq_9VCp9ZAu n8 @ً%KОI85,Ҕߌe'վW$iֺCT#:'NꇊIϘ͚IohHDo-"(-B�d9g+Z_y]�[lQt{wS=Qm:;{N*g WX�Govgu�"Q;ޢ}[ K>ሔNV��-.[Yȳ1جSO^"RHoS.WݾˆjyA^ci;-IR #ShuI9(eUҎ.:f hy!L$Չ,/eu-;5k!TP&m5hJwb3WhbW"K�ļ¹u*:rkS,ݺhfPlOBE\mӜydH"I)$FK%ޥ+T_jn8 Z!E(:IJ͖ږd;jD $|77o9vש$Zjo!r+lzio)6MFHKQH"3 ĶgĻq!q̦siT# /đդI.WXR_\CbQNBS_J .LvԤ^kp`%Fr%Aޅf J1)  snܔb*vb%bFbebKirOṢU$Q(,US˅QRo[测:7 _)zJcpVzj#ջq]]}cVZY3rnI))Iv$3{R+q%{"VlʚjԤ|Km&Iђq E(xZ P-z]^L-ɒrֆlG >i3Υ+>rS*svZXr%+,%ܚaڅV%ٶ+<I&G궴ө*"4f.\h.E>Vz!ĵSbבXun<Fm8E Dڵ+F9km�fU5Hhd@{EHuq339 U*ZjRO̔ڗAMI2A-eb(tWQ|=$k}e:n}HT9tz17"E>d#iE-nH5b(_)\C'ʍR{XJ3bUZc+hG'j(jJJ*=NPy1 $mgHm$Ff#RgO Wu]RJM.ZR["햔DJvR)aRl-gVvEh-l#ΣխbVeH*,>OG$,a۾H$:j)+?UȔYeHN͊2PHXcQ\Ec%Wh)CNZteh),9 %i5d>I:$&趟6BZꝠHoT)˧І)9(2N:-nW"ݢzaNzRl;#[9GP5WU>!1Ȼ8FM3*mGS)ҪQh*$T$jyչ!%j-5$pOgV iV2A9+"hҦ-O]?cݑG@*=\lD$;%xڻp#EEI'[[|^=g۩}_ 4,Q"lEvL窛%֨w2 \>c]0?h&KV -n*TجV1փ;^6)c2IBQ$jbJVmJ- j\O6ʎ.e&wԳTj_cR@jT[2n$j&V=Oh^Ȋua�}R8֠0Rk6ZWg¨Y,7QTCf$5̭ękBY2%^C>hk<4;DZi6RRI9X̽m7*2W)Rjq Ʊ$%QSڿ(BzLmu919FS^iua0z~"Vm1Ʌc%8ԢVu*qd_:@_e5k+i1'U\iM1uձN2\wIIkT3Ž$7Ck'J[+h)(O[Uji_\Ֆ;-<KŮKVl[̮JH5OrHWe$�l||] @fc] v7%c폖oJv75, `:폖ok>YA(<u, l||P=x>YAf{�l||] @[S�se5,!69Ew#>)wn oD�/*gh!BukTZB$~BJײ3G6F:q3.�vV5uj!L̎8d)V/'#6փdI9#XIU| 1 WLg܇Q!=I.ժ'bg=2ڌd#&Co3KFKCwE%7g{I}4cu R&Ƭn<-8[N2qr3>Y:ÖӔvh+-8KBQ#J;s3>^-cKEX_cvɩm^ɩ͖la4:iuNLClxnfG{7c7EQ*6\I'PWTXQ]$FF~V�t S^)Y)Ĵۡ<jɭ6xdm%}8ث)*h6璆Y֮i_!AwNMj͌$Kez2͛ujwx[>֭T,ٷ_F~ׅjY+с``ߖ {L2 -/OȮi~J6|(:s=;䩞6_cCV`G|3FӫHxN3}(Q>%pJ'{Ob `�����������fCjiŴ+B� YVn>ʳw[a%eY0C*o"VU2�}"(�%eY0C*o"VU2�}"(�%eY0C*o"VU2�}"(�%eY0C*o"VU2�}"(�%eY0C*o"VU2�}"(�%eY0C*o"VU2�}"(�%eY0C*o"VU2�}"(�%eY0C*o"VU2�}"(�%eY0C*o"VU|;P Huu*Y�dZ(jS㬩mqc<dYq]\ڶG W+kD/`BlڮVֈ6{U lڮVֈ6{U dlJ}JiU*5YszŸ҄s 'վW 'վW�& & }mпDo- =]�[�xsgŽ0#ӾJ#i?5f{wS=Qm:;;1ؾY DwD/@&��������������������������������������������������������������������������'վW 'վW�& & }mпDo- =]�[�xsgŽ0#ӾJ#i?5f{wS=Qm:;;1ؾY DwD/@&��������������������������������������������������������������������������'վW 'վW�& & }mпDo- =]�[�xsgŽ0#ӾJ#i?5f{wS=Qm:;;1ؾY DwD/@&��������������������������������������������������������������������������'վW 'վW�& & }mпDo- =]�[�xsgŽ0#ӾJ#i?5f{wS=Qm:;;ciSJF]A# ,.%Ƥ6 $WL⣼y\M0�z⣼y\M0kIq4`�!늎Iq4*;' �*;'$WL&�$WL⣼y\M0�z⣼y\M0kIq4`�!늎Iq4*;' �*;'$WL&�$WL⣼y\M0�z⣼y\M0kIq4`�!늎Iq4*;' �*;'$WL&�$WL⣼y\M0�z⣼y\M0kIq4`�!늎Iq4*;' �*;'$WL&�$WL⣼y\M0�z⣼y\M0kIq4`�!늎Iq4*;' �*;'$WL&�$WL⣼y\M0�z⣼y\M0kIq4`�!늎Iq4*;' �*;'$WL&�$WL⣼y\M0�z⣼y\M0kIq4`�!늎Iq4*;' �*;'\y F5NSiN(+ ~(�Do-"(-B�d9g+Z_y]�[lQt{wS=Qfk{kTk_ \f1QzIwsyqf,6{wS=QlQm(|9i҆ŭbstRkwØƝ(lZ'1J/` &ŭbstkwØƝ(@(|9i҆ŭbst�lZ'1J|9iҋkwØƝ(lZ'1J/` &ŭbstkwØƝ(@(|9i҆ŭbst�lZ'1J|9iҋkwØƝ(lZ'1J/b*LN݉.m5QE6lJuvA^v<C;ȮGkkwØƝ(lZ'1J=vxַ\E86xַ\E8I,[|9i҆ŭbstk*kuQӇgQ.՚/pHb19:PصNcNzgQn/p '½h"-[4Cb19:Q뵕KƵ(KƵ("-[4Cb19:Q{$j0A*զ6JAG2#UJ %J+eq(ߚ3H-ZM Qg%]lZ'1J|9iҍos|bC_D5ŭbstkwØƝ(P=�}{|9i҆ŭbstd71}! mkwØƝ(lZ'1J6N }{|9i҆ŭbst_Lf3MdޏPKqfd̯"Qf17~ys׫ț3N:⸊3 ŭbstkwØƝ(nˈۋFOlLQ}#_D=-nsӥ [4F71}!os|bCb19:PصNcNl}{&7/=-nsӥ [4F71}!os|bCb19:PصNcNl� v1Sh9IFM)Jd8II{6s3D1|9i҆ŭbsthv90PQ!W&7/IE5ŭbstkwØƝ(:&7/5Mk_Hz[lZ'1J|9iҍos|jC_D5ŭbstkwØƝ(:&7/5Mo_Hz[lZ'1J2ʲQj6NuG HBLq/=u71}"c-EPg Vmё^yԣ33q"EwKSo<+Z_y=ݟ >wӘi%LDF{N*g <}`��s(����������������������k�1EW*b53lpUSfRR2"fdD]3",3V Cp,? GiaUQh˥Sꍥdf-QӍz Z`p jm-Fb75̹Rd $fW\=k]' �ijXBق]D[BgR!2^$ڔw(k?QeQ}q=m655_y333f+E SJL),4x<v3I <[&iMYRawt(zқXB+Z1RՊ^ff4(K떾ѕ@ ޶ � l a�kO-'WXK9; ZAVNL-I2<Rmwr�[H}8YmJRDڌ2H1.o?#6]Bߚ*GH {h콟aIhIS% Juy-.s)ƺJ;l0Tr Ŝj" -zHKK:j,XI5i֮fcZF,ݠF!(mW]]GvkDf_TŬ̥9uxB#}}G$8eOq==m6Okk- m[c9h ̈́es?ZV9D2$o;a_nZZkF<LDmlgRpr?|,J$ܣ$m7=\:pʵBc('M%$h)f1.YLgˣY{\5KThؤ眊N~mwBV?מ Z꼆2!)Td3Bӟ2fFYm^Z|ΤE7N:l5EI$\y)+I%l4T%K.wY߰Ǟ˱_@ ZSFfj5V㋈RIAwObQ�L|s�c"ЎCUyx<]Bߚ*GH,yGenjRwHg7TK͜$4NOVL+ɔINz!f2j"MSg4S\mdiR!%H<ꖖXbKr+T7 2qФ(pTF{]II)T\I.YQ$ڒW9�|rASKaz/JpR%g;H+ۑ^gqI oV!08iK6Ԅu%^Wtzjf9amFұ#$FfII3XF\NKyM8RMǜ3?{ RŚ[(39H33󏝗Pʑ�p?f)c;]B�4T[�f)9d?bnknU:) 4f221~˨[OHLҖ}^VjG6 pYF%݈H?4qwo͵6]Bߚ*GHU.RߔS%*CiiBqR_yc*>1Lf]TjYalP4ui1LJ͓#[6k[V:^rkjMڲI(Lw185\ 0j`:h]=OHQ9kOTKڱ!&?2PyªFTTFF,ڏhțiw^ܥ*L9F2ج٫M*Dnp&6 &Y) ⠻R;e|p쟞8}F ,lPʑ.o?#dqDo-"ɲR:Ec7!hKK.<y(n2?`Ȯi~JvEwKSo<Gx2+4�zظ!\hl<Te %IBqɨȈ{~hWUS6G61xH1Cmz߆�^,vgՙw ^ b^,v6׭K=n Vc} / ϝ{~hmz߆�f7 ^ b^,v6׭K=n Vc} / ϝ{~hmz߆�f7 ^ b^,v6׭K=n Vc} / ϝ{~hmz߆�f7 ^ b^,v6׭K=n Vc} / ϝ{~hmz߆�f7 ^[UclQ) nTܖ,2%)Ev?={~hmz߆�f7~lxlx8mz߆�^,v<%Yv-,1E-,1E<^,v6׭K=n Vc}vGKQzvGKQz6׭K=n {~hUGaQ^{Q^͵{~hmz߆�f7~|x/5t*'!ό؎]Ć*#+y"?[ܖ{;@k%7N1ZCk[j'7=orYt�m[ܖ{;@'yZCk[j'7=orYt�m[ܖ{;@;k[j'7 lTpg ӴorYt�xGlT6s{=Qk%7Ng Ӵhovs{=QвnOk KPֺu-N\L^-ٮ\8 mz߆�^,v<#ovs{=PZGm[ܖ{;@k%7NyZCk[j'7=orYt�m[ܖ{;@;k[j'7 lTpg ӴorYt�xGlT6s{=Qk%7Ng Ӵhovs{=QӡQ7f!DnF#ЛIf+�orYt�m[ܖ{;@7;Z 9mkc-Dz׭K=n {~h<Gpkc-Dz^,v6׭K=nC}õֶ?Nog8{mz߆�^,v<# wֶ?NogZ Q9{~hmz߆�47;Z Q9(?Qp"Scf⚈ZI#QH�!k%7Ng Ӵc}nȮi~J瀡ZeUrb?Uu9DZMJPR+֣| =g6�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������krb5-1.16/src/windows/leash/htmlhelp/Images/Leash_properties_krb_1.jpg������������������������������0000644�0007046�0000145�00000566370�13211554426�025706� 0����������������������������������������������������������������������������������������������������ustar �ghudson�������������������������libuuid�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������JFIF��x�x���C�     �C   �"�������������������������� ���QӘrNKp.9bØp.9bØp.9bØp.9bØp.9bØp.9bØp.9bØp.9bØp.9bØp.9bØp.9bØp.9bØp.9bØp.9bØp.9bØp.9bØp.9bØp.9bØp.9bØp.9bØp.9bØp.9bØp.9bØp.9bØo'`n9~8{Nnf[U!y#:@#:@#:@#:@#:@#:@#:@#:@#:@#:@#:@#:@#:@#:@#:@#:@#:@#:@#:@#:@#:@#:@#:@#:@_qǷ:kEg5y{U&QnFW9:Xg$ΦlcڷgGXgt,Q=S~{#-Я:i<Mw*%T7Dt6JYs_Q{ږ״6BMOR"B*P"B*P"B*P"B*P"B*P"B*P"B*P"B*P"B*P"B*P"B*P"B*P"B*P"B*P"B*P"B*P"B*P">kq<o:mU{i>::f+w?ӟy.]pj< qǽNb�@Y 6ynٟF'-Dam%c >^O+fGp s9f:@=DM1Z; W^WiՅ2]3췥ry'[Y5ZՒ-Z!Z!Z!Z\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\۬^,o~=;8X?Y}=�8P'u~;p�8?jIs޶K5q߾˽C�tM~;fG{Euv͝zVp__'?.%??zza{J~d g)!U޵�Jqjڂ+XEbf+bf+bf+bfYŘYŘYŘYŘYŘYŘYŘYŘYŘYŘYŘYŘYŘYŘYŘYŘYŘYŘYŘYŘYŘYŘYŘYŘYŘYŘYŘYŘYŘYŘي?x^CgǤ"}zAW~szr^M:ˑF:󑎹C�9F:㑎c9F:㑎c9F:㑎c99]qF:㑎c9F:㑎c9F:㑎c9F:㑎c9F:㑎c9F:㑎c9F:㑎c9F:㑎c9F:㑎c9F:㑎c9F:㑎c9F:㑎c9F:㑎c9F:㑎c9F:㑎c9F:㑎c9F:㑎c9F:㑎c9F:㑎c9F:㑎&y~sOS_pq۟O^9NS8ANS8ANS8ANS8ANS8ANS8ANS8ANS8ANS8ANS8ANS8ANS8ANS8ANS8ANS8ANS8ANS8ANS8ANS8ANS8ANS8ANS8ANS8ANS8ANS8ANXH#;ON1yǃx=ǃx=ǃx=ǃx=ǃx=ǃx=ǃx=ǃx=ǃx=ǃx=ǃx=ǃx=ǃx=ǃx=ǃx=ǃx=ǃx=ǃx=ǃx=ǃx=ǃx=ǃx=ǃx=|{{{{{{{{{{{{{{O{{{{{{{{{{{{xG:9Hϧi~[3;³%[UcmgJةVdJd^+E756,Z,Z,Z,[O,SU"G(V%hV%Z,Z,~ڴY+EY+EY+EY3~FY,Z,Z,Z P7,x&v fm&,Z,r%hV%lt+>ajL^+EY+EY+E,MDų?8V%hV%hV%hV֓ 6lĵjC5g1dJI fb`XY+E%Y+E6jLZ,Z,Z,Z;u.&#wvgӴ?-tm-o M3ssu^|wKYo:OZg7uIM:WQqntצSɸ[87oXu7^{7a^~wҽ/)~oK \StO2\R0ys\e㾸$w?>oi,%EƧGtqNYo9 3N3sO~xZMd0z:6� C>ecXo:uwt+f-v1ƉִׅJtN4_FwZγbUk1t6Z(:OW6kVQͨϲJ~qm+޹wDasa28{ZDugWu])l. gJ4p|Ɵ;[D:w]ޜg _vs_b=ėD [Xˊ[i^⻯.:?C?;M~9Giߦ8WG?;j*/S2׸WϹ;cd+:;@G:9Hϧi~[3aY:vSkW8>AG0/i2swmP-OEi?;[gᗙs3>qWӏ] g1?_y?`c%nu=gk3[uʹ};#뙭mQ*V\1"dgױiȽ q9i~yu_Eʁwkϥ#Ha}2=O:ޚE-/%FߩEe6Vg5ʖ-: i1xOoo[;baB}V-:}e;/<gGj \7񏾁qmNtppӇ0tϦRoIsogͪ79kk=w8M7>),5xm>)2k\.1%ǭ/V?{EN'?fsj9RGakhֹqX]C).Y 7[߉ isvUy{_L5WKn}%6Cq9ͤOAz7IRs]3yt~Hm#wvgӴ?-3+%&Z"RA-KDA-KDA-KDA-KDA-KDA-KDA-KDA-KDA-KDAMx% hZ % h-1-KDA-KDA-KDA-KDA-Ki>3+-Y]쭸�DiY_؊l�LD% hZ % hZ % hZ % h]wMsșh_*揱񱈵=2:M>}9Hϧi~[E ΃PZ�������������������������?%4y+ԔU/cҲ6sKtx D-Ҹ�Hn $D[ڳ 7�>h)z<թ.%fUY[�4sjنwӫD+e~4\[j bM+������������������������� tZ|rٟN4ʋ+zA�������������������������o;蜪mxOFc9i7<<^29ޢtgt6W|u+O\tsgJieYcc|V믥kvgQZL:2Uӷܗ-U[L%:kLaN }.1dm9 {sk&P�������������������������(oecwcv1從TYX 5�������������������������<yRVע{4"i[?\mPRr^{ғL�-IRy^դs_>{hR{+1%�RVk1,@`kU]N5gnm+3]IolWs>vTazVz,��������������������������cY`uR;3|ƟyQ}2c@&�������������������������������������������������������������������������PP1yE:)>cO}<j @������������������������������������������������������������������������ f:/:赘X#>ioV6: Ah�lAmmMގ WK~x<)i:~LŻ? :tH^(oiGP>I)*f.L5mm3ܶ#{SULk+:ovN~>rASl~(]z<NAi1-]IUDWh�����������������������������������������������Yκ-f>}9Hϧi~[E ΃PZ~RNfiaazMgm+%2mw|cp4:O׽59M\">t<7ۚv|zǑo96小ֳy޷\IAOZ>빵Fu35׮yzq+z X郰vasMn]j,"V>.(^"hׂx(ׂx(ׂx(ׂx(ׂx(ׂx(ׂx(ׂx(ׂx(ׂx(ׂx(ׂx(ׂx(ׂx(ׂx(ׂx(ׂx(ׂx(ׂx(ׂx(ׂx(ׂx(ׂx(ׂx(ׂx(ׂx(ׂx(ׂx(ׂx(ׂx(׃-D�cY`uR;3|ƟyQecoH3ρ>%Ǻ]/ND+h'uiH3%&5 D8跞{J,ʳկJ+g5ZYKq=A8N^/>^2&+9TV^Py^of����������������������������������������������)Yκ-f>}9Hϧi~[E ΃PZ^R>@�������������������������������������������������������������������CjS  tZ|rٟN4ʋ+zA<|| �������������������������������������������������������������������SԦ @ f:/:赘X#>ioV6: AhyzJ,aŁOZL.s*+jiY^�dhnpxj,4t?nn] {STK3ʎj>cv|&ǧV~ElΤV����������������������������������������������������)Yκ-f>}9Hϧi~[E ΃PZ^R>i1#wFW-Ui|o4o]g0~_=[z{WX]=f:}A?}� =:{:\?B#l/P^_|N+qY]4}kLw�X��������������������������������������������������� N[R�(oecwcv1從TYX 5(O||zO蟏TOdO1ԟG?D�SOT>_I|�?@����������������������������������������������������(u9mJb�cY`uR;3|ƟyQecoH3ρ>'ۑ07 80pÍ7 80pÍ7 80pÍ7 80pÍ7 80pÍ7 80pÍ7 80pÍ7 80pÍ7 80pÍ7 80pÍ7 80pÍ7 80pÍ7 80pÍ7 80pÍ7 80pÍ7 80pÍ7 80pÍ7 80pÍ7 80pÍ7 80pÍ7 80pÍn7�߰;�PrڔC}C,E]vgӴ?-ސgA-/_)E|Lnsѹ;Mi_IjTi~tCc-^셄7"`g@sh+n.]uι)�jאBAZ�����������������������������������������������<|?\Œ+/8>g-|?Rj)Yκ-f>}9Hϧi~[E ΃PZ^R>sw^E6s�?Is+)_$]=jwDu=}nSl-qnä!ʍg1gn8ptIKY_йD\5=߆w=9������������������������������������������������yzBkKSh�PkNQ8pB)Yκ-f>}9Hϧi~[E ΃PZ^R>sm"ٜR %m�o%<?v/Xy~�k:/rmM'He;Ty<#ykts´l~_̰=zW=@�����������������������������������������������^PW."hsûv-L@72t^uk1;Gf};OO*,mtY'BY' "r' "r' "r' "r' "r' "r' "r' "r' "r' "r' "r' "r' "r' "r' "r' "r' "r' "r' "r' "r' "rW$qgiYG"�(u9mJb�cY`uR;3|ƟyQecoH3ρ>$��������������������������������������������������������������������PrڔC}C,E]vgӴ?-ސgA-/_)E|IQ+:h?H�+bV_ O` ���DE" �������������������������������������������������������PrڔC}C,E]vgӴ?-ސgA-/_)E|OtYA_h~|/wsi#'˿G~Ktߓ?~|/Kם+gt=)97Nm#Uv5HX׶ɣҝӊ+F@@��������������������������������������������������SԦ @ f:/:赘X#>ioV6: AhyzJ,QnK zf;Ttksѳ}T.Czq)Q\/Fj}sqX%ϯP6Oh1kAϹw]2ֆ ޗJO}rWTZ#EcO#V ��������������������������������������������������CjS  tZ|rٟN4ʋ+zA<|| �������������������������������������������������������������������SԦ @ f:/:赘X#>ioV6: AhyzJ,|{J2u\ u\ u\ u\ u\ u\ u\ u\ u\ u\ u\ u\ u\ u\ u\ u\ u\ u\ u\ u\ u\ u\ u\ u\ u\ u\ u\ u\ u\ u\ u\ u\ u\ u\ u\ u\ u\ u\ u\ u\ u\ u\ u\ u\ ʪh)Yκ-f>}9Hϧi~[E ΃PZ^R>ܿr[MVd�C^|�>t+CDv,ɍ!^OYj4Զ%: _`BxVj �����������������������������������������������������}Y"ա)Yκ-f>}9Hϧi~[E ΃PZ^R>ܻ:Wk)l96zq-U}M-2}"lt(IzjN4ƻNz8fOaV9 ~N_jV5;LN\C �����������������������������������������������������::ڤZ:1�PP1yE:)>cO}<j CQgm *Lg*עqkR5ZF1jьJ%-Nk:|?////////////////////////////////////ԋVSԦ @ f:/:赘X#>ioV6: AhyzJ," eJeHTeHTeHTeHTeHTeHTeHTeHTeHTeHTeHTeHTeHTeHTeHTeHTeHTeHTeHTeHTeHTeHTeHTeHTeHTeHTeHTeHTeHTeHTeHTeHTeHTeHTeHTeHTeHTeHTeHTeHTeHTeHTeHTeHToĂbSԦ @ f:/:赘X#>ioV6: AhyzJ,A��������������������������������������������������������������������-L@72t^uk1;Gf};OO*,mtY'Ă�������������������������������������������������������������������� N[R�(oecwcv1從TYX 5lZ % hZ % hZ % hZ % hZ % hZ % hZ % hZ % hZ % hZ % hZ % hZ % hZ % hZ % hZ % hZ % hZ % hZ % hZ % hZ % hZ % hZ % hZ % hYMu  tZ|rٟN4ʋ+zA�������������������������������������������������������������������������cY`uR;3|ƟyQecoH3������������������������������������������������������������������������72t^uk1;Gf};OO*,mt������������������������������������������������������������������������Yκ-f>}9Hϧi~[E ΃PZ��TVѹD`촨R@�Ϧz IWZJzcRF)mi ۔�tǮ>>��32B,?o[A&��������������������������������������������������72t^uk1;Gf};OO*,mt*}ٙ[Ia6}<ԼMgm%obm͍mA+lSa:ksvxh>)HoI?Wij?uk_="TuK8]}q)f,y:50fam+ywPtRZ8Ӧ赞w]9I{<nv|۪usgZ:eZjUVeZjUVeZjUVeZjUVeZjUVeZjUVeZjUVeZjUVeZjUVeZjUVeZjUVeZjUVeZjUVeZjUVeZjUVetZ4�(oecwcv1從TYX 5(Ox{Ǫ{g}iߥk%W\\GqV܎硴ٍURo5{ӂg\헏,t n#)v4%gB3$RN]TkqMv||yޙ5) ��������������������������������������������:1�PP1yE:)>cO}<j CQg��������������������������������������������������������������������(u9mJb�cY`uR;3|ƟyQecoH3ρ>'ξgvzl\ײ|~>?P>>O_/NaM48_rh~<ޯ?>iz>~@WϜG1lyOOGPes=f{`/3O? Z[tiY=?QA]y"}_?yן_b�����������������������������������������������-L@72t^uk1;Gf};OO*,mtY'ij(i64vyz^Zh�3'1N#\F{Ӣk7FKg^7]ss~1>Uoȸw\vrlֿgϿX"l3?'`㽋t{W^v{:lazXV���������������������������������������������CjS  tZ|rٟN4ʋ+zA<|| //T1+8!ߗ4 Q1ӆuerݭi s% 9Uogk\V2 poevkCC9[5[ms\ݯOgn1פElS:Zb%.f붣XuT芄����������������������������������������������SԦ @ f:/:赘X#>ioV6: AhyzJ,O<ƽ&4lѲcFɍ&4lѲcFɍ&4lѲcFɍ&4lѲcFɍ&4lѲcFɍ&4lѲcFɍ&4lѲcFɍ&4lѲcFɍ&4lѲcFɍ&4lѲcFɍ&4lѲcFɍ&4lѲcFɍ&4lѲcFɍ&4lѲcFɍ&4lѲcFɍ&4lѲcFɍ&4lѲcFɍ&4lѲcFɍ&4lѲcFɍ&4lѲcFɍ&4lѲcFɍ&4lѲcFɍ&C_�(u9mJb�cY`uR;3|ƟyQecoH3ρ>&7#뜾2v5vSMʣG5Y\ZnYVK ijWxMNt}k;5Ƕ  {`1Ƕ {`1Ƕ {`1Ƕ {`1Ƕ {`1Ƕ {`1Ƕ {`1Ƕ {`1Ƕ {`1Ƕ {`1Ƕ {`1Ƕ {`1Ƕ {`1Ƕ {`1Ƕ {`1Ƕ {`1Ƕ {`1Ƕ {`1Ƕ {`1l5")Yκ-f>}9Hϧi~[E ΃PZ^R>ܻQcja]u|?g5R~mm;;meru-/t6WԺйoQ9޿R`)kE\��������������������������������������������������������ECjS  tZ|rٟN4ʋ+zA<|| 1wQe62o>4=rEqZizp鬱g/[nu볽FKQ}t}iI:GW��������������������������������������������������������>,jjrڔC}C,E]vgӴ?-ސgA-/_)E|Lne$lJTJTJTJTJTJTJTJTJTJTJTJTJTJTJTJTJTJTJTJTJTJTJTJTJTJTJTJTJTJTJTJTJTJTJTJTJTJTJTJTJTJTJTJTe&^:1�PP1yE:)>cO}<j CQg��������������������������������������������������������������������(u9mJb�cY`uR;3|ƟyQecoH3ρ>$yK@�^������y���}_τz������������������������������������������������SԦ @ f:/:赘X#>ioV6: AhyzJ,bqې\7�X9ޖq#͇2վŕ˲ qh.ia{pyG;٫Cr|)�C|NMnaֱ0ϻM3w 708nqXWwwL$FU6[ n7ҽET��������������������������������������������)Yκ-f>}9Hϧi~[E ΃PZ^R>i>[l*72hM?JﻹdztqŅ(+x==镨SMlyZ̦ obyz[oŻ?i9y!sbg[O隿NS^JN9]]3ڪEWU:}y-7^=?-@�������������������������������������������CjS  tZ|rٟN4ʋ+zA<|| �����i*5R@�����������������������������������������������������������(u9mJb�cY`uR;3|ƟyQecoH3ρ>'Ӑ#3فfv`iفfv`iفfv`iفfv`iفfv`iفfv`iفfv`iفfv`iفfv`iفfv`iفfv`iفfv`iفfv`iفfv`iفfv`iفfv`iفfv`iفfv`iفfv`iفfv`iفfv`iفfv`iq.bSԦ @ f:/:赘X#>ioV6: AhyzJ,crβx?͕Gtu[9Y{rVObcID$<y}L}"d#yJsX?Z7>`-=M"C,L/įP6.U1Re)0������������������������������������������ECjS  tZ|rٟN4ʋ+zA<|| 1PX㝋lf�56_Q-5ꓞ -,9Ek7*l6ZΫXO"gn:ݷsYeh#Bn%tW^~8OrY,s=o'AÞMm@n|#ݥ/N#ϠnIݓ\�����������������������������������������βζ-L@72t^uk1;Gf};OO*,mtY'CI7B<3"9w"s =x٭Lf;)z6N$_/;zvȵ;F䝱퉮ysY鎷_<sbN%3MxWKXG 똥)E:l>ƦrqݾzD+8 �����������������������������������������βζ-L@72t^uk1;Gf};OO*,mtY'}BVZ*ŢZ*ŢZ*ŢZ*ŢZ*ŢZ*ŢZ*ŢZ*ŢZ*ŢZ*ŢZ*ŢZ*ŢZ*ŢZ*ŢZ*ŢZ*ŢZ*ŢZ*ŢZ*ŢZ*ŢZ*ŢZ*ŢZ*ŢZ*ŢZ*ŢZ*ŢZ*ŢZ*ŢZ*ŢZ*ŢZ*ŢZ*ŢZ*ŢZ*ŢZ*ŢZ*ŢZ*ŢZ*ŢZ*ŢZ*ŢZ*ŢZ*ŢZ*ŢZ*Ū|E-L@72t^uk1;Gf};OO*,mtY'Ă�������������������������������������������������������������������� N[R�(oecwcv1從TYX 5(O��������������������������������������������������������������������:1�PP1yE:)>cO}<j CQgOO䏧|||||||||||||||||||||||||||||||||||||||||||||ȣuQ1�PP1yE:)>cO}<j CAVJh*ւh*ւh*ւh*ւh*ւh*ւh*ւh*ւh*ւh*ւh*ւh*ւh*ւh*ւh*ւh*ւh*ւh*ւh*ւh*ւh*ւh*ւh*ւh*ւh*ւh*ւh*ւh*ւh*ւh*ւh*ւh*ւh*ւh*ւh*ւh*ւh*ւh*ւh*ւh*ւh*ւh*ւh*ւh*ւh*ւh* � f:/:赘X#>ioV6: Ah������������������������������������������������������������������������C}C,E]vgӴ?-ސgA-�������������������������������������������������������������������������(oecwcv1從TYX 5������������������������������������������������������������������������ tZ|rٟN4ʋ+zA�������������������������������������������������������������������������cY`uR;3|ƟyQecoH3������������������������������������������������������������������������72t^uk1;Gf};OO*,mt������������������������������������������������������������������������Yκ-f>}9Hϧi~[E ΃PZ�������������������������������������������������������������������������PP1yE:)>cO}<j @������������������������������������������������������������������������ f:/:赘X#>ioV6: Ah������������������������������������������������������������������������C}C,E]vgӴ?-ސgA-�������������������������������������������������������������������������(oecwcv1從TYX 5������������������������������������������������������������������������ tZ|rٟN4ʋ+zA�������������������������������������������������������������������������cY`uR;3|ƟyQecoH3������������������������������������������������������������������������72t^uk1;Gf};OO*,mt������������������������������������������������������������������������Yκ-f>}9Hϧi~[E ΃PZ�������������������������������������������������������������������������PP1yE:)>cO}<j @������������������������������������������������������������������������ f:/:赘X#>ioV6(Ĕa%IFQa%IFQa%IFQa%IFQa%IFQa%IFQa%IFQa%IFQa%IFQa%IFQa%IFQa%IFQa%IFQa%IFQa%IFQa%IFQa%IFQa%IFQa%IFQa%IFQa%IFQa%IFQa%IFQa%IFQa&֐t^uk1;Gf};OOcr%u+JC䮴9+JC䮴9+JC䮴9+JC䮴9+JC䮴9+JC䮴9+JC䮴9+JC䮴9+JC䮴9+JC䮴9+JC䮴9+JC䮴9+JC䮴9+JC䮴9+JC䮴9+JC䮴9+JC䮴9+JC䮴9+JC䮴9+JC䮴9+JC䮴9+JC䮴9+JC䮴9+JC䮴9+KcH#>io������������������������~tkqAPvkqAPvkqAPvkqAߛ:=fl*V¥l*V¥l*V¥l*V¥l*V¥l*V¥l*V¥Y A[�*[ [ [ [ [ [ [ XlZUJTJTJTJTJTJTJTu;Gf};ON1������������������������G+\Wg>KDA-KCDX-5zKDA/7ĸ&GSL̈||y;#gzz>Qo||o>$>Grn%XX?_OOO-#>4?OO9#[TB/_OO=G<%*OO}>G}>G >}9Hϧi~[2������������������������<}*O���b1:ou\+[z@�/vNLi)-�ӓ_ds}32Pe~pן\>B,�r*ƺQ|= ��#Z ~<GnȳϿrz=G\ށK�<}sڦ?_6��ztO;Yuzox,ݽ_sFv��72t^uk1;Gf};ON1������������������������G+\wR|E��l9\ioSL/Al~V��laƒz �Ikm4kW,Ziس(haH�r^LEL�9'íigk5לD-]35:+,d �#˕G++jhU|��O!ꙭT^?l=c{<d(n8ݴf��PP1yE:)>cO}8@������������������������G\qNVYeơ\jqeơ\jqeơ\jqImaƒzz<׏GyGyGyGyGyGyG=C ̫EhyGyGW�)x'+gyGyGsڦ??6z<111y11CuDf/:赘X#>io������������������������q'b9~N~G9~N~G9~N~GtTY"y %]xr^ׇ!u]xr^ׇ!u]xr^ׇ!u]xq )G#Ð.9 BÐ.9 BÐ.9 BÐ.9OV?`9 BÐ.9 BÐ.9 BÐ.9 BÐ|rٟN%_~2;04ӳN ;04ӳN ;04ӳN ;04ӳN ;04ӳN ;04ӳN ;04ӳN ;04ӳN ;04ӳN ;04ӳN ;04ӳN ;04ӳN ;04ӳN ;04ӳN ;04ӳN ;04ӳN ;04ӳN ;04ӳN ;04ӳN ;04ӳN ;04ӳN ;04ӳN ;04ӳN ;04ӳN ;04ӳN ;0/7UwF:龴)?����������������������������������������������������������������������������=C#�7��345 126p$%0`!"#@F&BP��Slӝ|(8PQC(qE(8PQC(qE(8PQC(qE(8PQC(qE(8PQC(qE(8PQC(qE(8PQC(qE(8PQC(qE(8PQC(qE(8PQC(qE(8PQC(qE(8PQC(qE(8PQC(qE(8PQC(qE(8PQC(qE(8PQC(qE(8PQC(qE(8PQC(qE(8PQC(qE(8PQC(qE(8PQC(qE(8PQC(qE(8PQC(qE(8PQC(qE(8PQC(qE( Z' >֮lugCaJDĦ+ڙYS;NS;NS;NS;NS;NS;NS;NS;NS;NS;NS;NS;NS;NS;NS;NS;NS;NS;NS;NS;NS;NS;NS;NS;NS;NS;NS;NS;NS;NS;NS;NS;NS;NS;NS;NS;NS;NS;NS;NS;NS;NS;NS;NS;NS;NS;NS;NS;NS;wsrv<hEh٨@_{}Z/uzgzgzgzgzgzgzgzgzgzgzgzgzgzgzgzgzgzgzgzgzgzgzgzgzgzgzgzgzgzgzgzgzgzgzgzgzgzgzgzgzgzgzgzgzgzgzgzgz;wTAinRq2T8ʂ $Xg!Ro�4w ;�M�S)e2LS)e2LS)e2LS)e2LS)e2LS)e2LS)e2LS)e2LS)e2LS)e2LS)e2LS)e2LS)e2LS)e2LS)e2LS)e2LS)e2LS)e2LS)e2LS)e2LS)e2LS)e2LS)e2LS)e2LS)'�M"ƍ$z zq V'VѴ+baMHb:Ant: ]klHCt:C9VѮ6O2XEkt:Ct: IlTt:Ct:Ct:Ct:Ct:Ct:Ct:Ct:Ct:Ct:Ct:Ct:Ct:Ct:Ct:Ct:Ct:Ct:Ct:>,{I)zQʎa D֐)7Ô!#1°^YmSwhfYҗHx{SEKX7MlKX7rWfҍ]e,Bգ۔~J1$JKAYFt+*ɯbwhLjLs})֎Ku؝&Ԥ+f-?0֌`۴vTyYuX4.o0ҙLS)e2LS)e2LS)e2LS)e2LS)e2LS)e2LS)e2LS)e2LS)e2LS)e2LS)e2LS)e2LS)e2LS)e2LS)e2LS)e2LS)e2LS)e'* NE0G00(V�鋷/!ƷU)4]ܪj$\Y){4"W+^3FZHJ(I줆ikL9(ws|cs8 >ŴezA0rî$s�6Vh#lK ֔ďlomAy ѕMW,J#ao nc q?2L,KY[\[Gw3Y0E01:NIK֌Y,&Ws 6jC!d2 C!d2 C!d2 C!d2 C!d2 C!d2 C!d2 C!d2 C!d2 C!d2 C!d2 C!d2 C!d2 C!d2 C!d2 C!d2 C!d2 C!d2SyEgAŮ,<%oFV 5GR^nb0\ctkq=B]-kt"=mM;w33-/Ha7K#\br?`-:q $pk&T ?*x)z>S <t'ԶδV^ o}fKT}{Ta\N+l�ZHJuǖU`Q\@0%}zY2 C!d2 C!d2 3L43L43L43L43L43L43L43L43L43L43L43L43L43L43L4̆C!d2 C!d2 C!d2 C!d2 C!d2 C!d2 C!d2 C!d2 QNqGJkUEbCaMlu_P�nӪf0Rkk,K8uebPe9 +'+6‘IzR_Ġ0ݭ K  b|<Ԥ{i'l[]4{&R5lLC /oT�Q˰vA$٤MǪ#[[MCY(a7l#q}WS)YH),K." ǿI?1^E8N1Գl%6Um̙ݚ`3Li%ifififififififififififififififififififififififififififififififififififiܯMvwb s \VM;A2nތ N2JR-}ikkm.omJmm+K [aU-mmRԵ m2!Kͥ C!V2#Kj\ͥ1KiaDiTiqTV4ʵki].)is{o6Kd2 C!d2 C!d2 C!d2 C!d2 C!d2 C!d2 C!d2 C!d2 C!d2 C!d2 C!d2 C!d2 C!d2 C!d2 C!d2 C!d2 C!d2 7zgzZO^!|3gi={L3gi={L3gi={L3gi={L3*+Q&(v{L3gi={L3gi={L3gi={L3gi={L3gi={L3gi={L3gi={L3gi={L3gi={L3gi={L3gi={L3gi={L3gi={L3gi={L3gi={L3gi={L3gi={L3gi={L3gi={L3gi~6׃tޝޝސzkm!)K(ek@r 9@r 9@r 9@r 9@r 9@r 9@r 9@r 9@r 9@r 9@r 9@r 9@r 9@r 9@r 9@r 9@r 9@r 9@r 9@r 9@r 9@r 9@r 9@r 9@r 9@rU�@ l6H$ d@ l6H$ d@ l6H$ d@ l6H$ d@ l6H$ d@ l6H$ d@ l6H$ d@ l6H$ d@ l6H$ d@ l6H$ d@ l6H$ d@ l6H$ d@ l6H$ d@ l6H$ d@ l6H$ d@ l6H$ d@ l6H$ d@ l6H$ d@ l6H$ d@ l6H$ d@ l6H$ d@ l6H$ d@ l6H$ d@ l6H$ d@ l6H$ d@ l6H F׬1 َ<B~?}cglen4o4o4o4o4o4o4o4o4o4o4o4o4o4o4o4o4o4o4o4o4o4o4o4o4o4o4o4o4o4o4o4o4o4o4o4o4o4o4o4o4o4o4o4o4o4o4o4o4o4o4o4o4o4o4o4o4o4o4o4o4o4o4o4o4o4o4o4o4o4o4o4o4o4o4o4o4o4o4o4o4o4o4o4o4o4o4o4o4o4o4o4o*-N777777777777777777777777777777777777777777777777777Y[~WTѼѼѼѼѼѼѼѼѼѼѼѼѼѼѼѼѼѼѼѼѼѼѼѼѼѼѼѼѼѼѼѼѼѼѼѼѼѼѼѼѼѼѼѼѼѼѼWSqb;ZDɹ7&ܛrnMɹ7&ܛrnMɹ7&ܛrnMɹ7&ܛrnMɹ7&ܛrnMɹ7&ܛrnMɹ7&ܛrnMɹ7&ܛrnMɹ7&ܛrnMɹ7&ܛrnMɹ7&ܛrnMɹ7&v_RBRrnMɹ7&ܛrnMɹ7&ܛrnMɹ7&ܛrnMɹ7&ܛrnMɹ7&ܛrnMɹ7&ܛrnIPsPt7&ܛrnMɹ7&ܛrnMɹ7&ܛrnMɹ7&ܛrnMɹ7&ܛrnMɹ7&ܛrnM"4F{1 σOpD+X 2VZ|7Ij|t|lɫj�U{ڥPkKfuR:J}Z=kKDܦ̼fJYR-pwW8neWIZ{Ӻ_}fT]$]MA.E+R|gnѺɦ7mE }/SDԭh$ڹ7 ɵmw}`!"GIUORMח7N]Kgޚ<B~?}_ i%{,)0;fvB�ד.Kk4{_ ɿ�7ri;YIh%YQ�ˋф<qFj>_ 89u\^CgR~,ۦdwer >a{^ijȪے͓F y%ygVifUwF[TֿLVVN]k#yuy%ourڭk+!eiHK�r k�6; uP/}#06pQ/͈3}FbqL՝rJQluEխNk lĖqu\Lt^]NME'i9a[mefU^MowY5kIqwUhUK}}'w> >};R֫''<.�Y%W]aU흺ED[-a=~՞RVnJN/(0zdU%$-jF!K]}v2zZW7$!3.bFq(әhVIl5:F_N̢ؒ1(гJmi'Ns|$T.^9ϤoJ]e"d>Qʼ+-mb$U xɖW{_8} +W =RzU˦6MK)DE4/V-s[RF 7OfVn,Μb!"²v6RB7{W&nofN]]o_ʫfnhJ˝%.Jk2VQm$i\HսRBIE<!wQ/%rF/̜}B #;:yGe#sUgw5re'' yi%nI+ ZYޒ8~g >L!՞qDQ(*5dTC@;TuIUDvJ'<FZ%z֩>wܿmXSQ'ylYHl`Z?3ٵ흖혃F^)FrmkhאҺF22s"{Kj *\ >oѦn&Y!ʷ2aIIX8}~U_:pü9 yi=w$vГNV]Bǂ3وO|}V0}ҽ gov wlEg{kU}ṃ v0�7<~5i {[?pVnrlI�MX51S#lJ.MJa{0R͖DҮMIw =NVҸ:5gmnmI fEP)>ſ$ÖSbooqO}F)Dz1ReF(F:BE^]((~Kv{(�o#Wi *~Sf5[jlunWX۟ҴjՋ_V"֎S%*-pwW_ ˦S~ސ*M[>JF1mʹ5tޡ!;*OoYKYI$lLVIw8fDuj+RYӼե-Rn /lCawDUdq%mF趬)H7u"mMx(LXc [cD[md*w[kv36}fD.iѣ VvM[xLGe_ ZYĘH3F�wi6if+i^V%dܗLMXw<IwQobͰg5AzSbϣLffs2*:h#FVXV[%m"rt#&if$+Bǂ3وO|}V`S9orn9vYa7�sНxwrΖ5ōTkd&))F8,Fn|jĴ \5p$tWxj+]XX{#@J6p!|-\4kv'13Xzm"Z\͝L-dN"^d.U]*<lx+VRtjk3 9 7hstd|+$)ub?HL7 yI t!flbS Gt ta#NCT,i.�ȲY\d[9j.8IRzѴ6V6- VE7saqnalKz\NmpIUR+ 0+8Kpۧ @8F>vpUH5i,2 + බL<MfS/UTB4^RZݹ%m'[֜d3;21b-ڰH$ dK4]\?W1Q$ljb=G@9q-�vrUB&ɾjJUztDn[mc Sċ_cz21TrNb0Ֆܖϵv8[4֊¯tմIEJ@%.'d]ԺiА1r*MOCjREuQ8Hu'~L@,;Eu)Qz^"^@豳9.%?]Ħ QQ8$UR8}}'w> iн ]] qr6R{ZZZZZZZZZZZZh(x:ErZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZb $ʉ>] tOǩF6$`eVԭv6666666666666666666666666666666660~hh;r֔6666&pS'H�N]Z,pVF8sPqb;6[SVMZ5jjթSVMZ5jjթSVMZ5jjթSVMZ5jjթSVMZ5jjթSVMZ5jjթSVMZ5jjթSVMZ5jjթSVMZ5jjթSVMZ5jjթSVMZ5jjթSVMZ5jjթSVMZ5jjթSVMZ5jjթSVMZ5jjթSVMZ5jjթSVMZ5jjթSVMZ5jjթSVMZ5jjթSVMZ5jjթSVMZ5jjթSVMZ5jjթSVMZ5jjթSVMZ5jjթSVMZ5jjԞ�Qǂ3وO >뭠�4Y</j|&gS. $~~8[�{Hh5>5�iJ+^,J(Cb{cI7HO\imԺ> Gf!?þ6�YJAl6xq b.Ē\J1zi~*-R(XnK$oRx޿LCe/I|+ZmYIޒ؞9 ϲ|>�6 X[^Kg\a\(!PX'BrmؤDFަ1m{8E:Iq#ڨ$su$kյ;i*ک]#bX7YhEHQ&1A_6ʥR西> Gf!?þ6�K]^_1k%HCfB8ͭw<r,W-stNX{9{Snua9Z>Fj}_G٦J8 C_[bA=ϮjŖk"K+ ""yٌLc-}&Qމ>_1kDtb %|*or2ƿFRW Gr> Gf!?þ6�jEg8㢮V&"-$n]U<Wj]s[癸"j+kH]D:Iz'/%s.ҊJX%1{cT&cs1+?oma -F LBFEiؙ4LE??~ 0Vw-UhJM4;Au:ėQ6.RqB2kFm;犽 {g<ϥQǂ3وO >E_|uY`FLVM*%dk0n g4K"`qJv_)m?dA# n-ZHģ$+ ?ЎIw՛`- ۨT]8}6Dk.!>`1M$\`&.WB1!QnKm)ѫX&r7ǎ!ZS7/lFlfK3Q?}n jđj�bb`ݜ2,W|73gc$}.<B~?}mq�np7IW Tg?Zg('wW_> Gf!?þ%:c\/x#=`g('wW_> Gf!?þ6�Zrǎ>x77{J-_!l_$X#!lJJĉgݑ$סjYl6N9^6NE[noKgly\}Kv }ce1Dr7lŧYW\MSGX$X}N}sVnFy\A鼚hi8w&Ez5]T6 g2YYuq8Qi\Km(QiuhՓOJA+X6+[DbHMFu4Q 4U(3Tđќ78tTАAjbԮk&βFRM- 3pqb;o+}zXڏOljoa}h'8[`ǰK(Y!IIy,<i8-CM\ZF>VhkIYYHȴ7+&{#!k:{|Ci{\@ʺB's ھ9Fj֌+n[vH$azmf]i4k�29^#,ut!mb^V {s[SV~v2qK,q#e?a%0DuG+ḄlTe%%!E&G߱62@c ld 62@c ld 62@c ld 62@c ld 62@c ld 62@c ld 62@c ld 62@c ld 62@c ld 62@c ld 62@c ld 62@c ld 62@c ld 62@c ld 62@c ld 62@(T_8F{1 S�M.38@o|5w?3mNܳ|>v=osҳX2mc6zf5Nakrs j3Ș # z.}aliu+8</p7d]N&tI<CxgJڶqI'$юdWQߩ$60ĭ#\'(nY'MpЂs|̆2(Z7+#إqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq+uj+|> Gf!?þ6x?sѬ2-&jʱyZMaQh_ 4UonJEJ+ΔBS[�Yhؔbѕm%TrIƧQK@INkY\>Z<mڵkvms[ӽ( g*/ܴ}E"_)(;n|>݊-S6-J1vFk{ o�0l:65N9'-tfo)ebX>-&ȳq(+|> Gf!?þ6x?A__8F{1 S�\ ,ϥQǂ3وO >"8?OPWf}.<B~?}mq2g3pqb;o+ȧ>YKgly\}~E<p~yeq$nə+)Z[bwJ6e굍s(-͚$Tm]Y<Zʺ OD)% j%!(+|> Gf!?þ6x?l!$ٿŒ4s:)8%xI͌Qd1Բ9(j1&geDq\ΫII9k<Q8䥭hڸsArm bGQuN=L_-3Q\XI,YK&ݥ<:ų+/W_9OVIOﮱcY}qdnwrb:wOђg3pqb;o+ȧx; go)ڔ�IF]P8'[)*U~)Ih,أmX5]1=+:Gz ""/gX2G&EYv #S4Mx& b--HOrX}THK, dyb4mSYK"}l\/x#=`)�8Fʧ3$xϺG6^yuTŏ%zEaJ4H޳Dln#Q$[r3toT;U&^f;k1sG2tI%<h]: ahHlH�՘U+q{Sp]ɽpՓluIbTV6/3hUd)2PWf}.<B~?}mqZ|*)m-+m.42P:|+NЭޚVht4)e42҅)JVSaJR ´L4:t*42NiRN-?F ,ϥQǂ3وO >"8?OPWf}.<B~?}mqrM&|D"o7țM&|D"o7țM&|D"o7țM&|D"o7țM&|D"o7țM&|D"o7țM&|D"o7țM&|D"o7țM&|D"o7țM&|D"o7țM&|D"o7țM&|D"o7țM&|D"o7țM&|D"o7țM&|D"o7țM&|D"o7țM&|D"o7țM&|D"o7țM&|D"o7țM&|D"o7țM&|D"o7țM&|D"o7țM&|D|%~ϖg('wW_O4tIjHRG8ԑƤ5$q#IjHRG8ԑƤ5$q#IjHRG8ԑƤ5$q#IjHRG8ԑƤ5$q#IjHRG8ԑƤ5$q#IjHRG8ԑƤ5$q#IjHRG8ԑƤ5$q#IjHRG8ԑƤ5$q#IjHRG8ԑƤ5$q#IjHRG8ԑƤ5$q#IjHRG8ԑƤ5$q#IjHRG8ԑƤ5$q#IjHRG8ԑƤ5$q#IjHRG8ԑƤ5$q#IjHRG8ԑƤ5$q#IjHRG8ԑƤ5$q#IjHRG8ԑƤ5$q#IjHRG8ԑƤ5$q#IjHRG8ԑƤ5$q#IjHRG8ԑƤ5$q#IjHRG8ԑƤ5$q#IjHREpܕ)$N"v HD%Wk!j-~g3pqb;o+ȧӎ|�_蝛 :TI| A__8F{1 S>o1<ұai䒝Uiq2olX= gwo.X/%1Rᱺ*Da{(}fر()1 ȋ0ҲqdЬ#q5o}qߧ]qq;WQRCK8b-uc8mdzrk!q r<+:ViaN�B+8|}¾\/x#=`)7ֽ)5MO;َ {V+�E O>o{<#Jz-GZVqtQ47 ![BB9jc{3~)JTO�[OVcjïkx!3oj /U0_~WqyiwA +�)!s-| A__8F{1 S>oxue(Լak~Ʉ٩-e#;8:̐azMS_`+FatheQYa NQJ+eZ>e}^aQ�ib?vdW׭#:Tcur'^Á?vW_NJi}1 FB8yp0m-| A__8F{1 S>oR{pj gGl𔖪a0:Euc'S,'J%&o9�(ƍm}+G61'Uի/#}lvf"Bu+rC),وqS1UڢmIr2}m?ooŋcsae2 ƨڿxӭBXS|%~ϖg('wW_O!v,NuA7Mʼn#b6$lBӵJ&$mRqTQJXuE A{(jRҶ6#]:UNY4EŜ~8=;n|z8n_ ݖ[,vWr:YL&n7 O%(+|> Gf!?þ6x8 ^CV Z5hjաCV Z5hjաCV Z5hjաCV Z5hjաCV Z5hjաCV Z5hjաCV Z5hjաCV Z5hjաCV Z5hjաCV Z5hjաCV Z5hjաCV Z5hjաCV Z5hjաCV Z5hjաCV Z5hjաCV Z5hjաCV Z5hjաCV Z5hjաCV Z5hjաCV Z5hjաCV Z5hjաCV %TUYJ-m;ld&v1C\/x#=`)TNqaXn,7 ņqaXn,7 ņqaXn,7 ņqaXn,7 ņqaXn,7 ņqaXn,7 ņqaXn,7 ņqaXn,7 ņqaXn,7 ņqaXn,7 ņqaXn,7 ņqaXn,7 ņqaXn,7 ņqaXn,7 ņqaXn,7 ņqaXn,7 ņqaXn,7 ņqaXn,7 ņqaXn,7 ņqaXn,7 ņqaXn,7 ņqaXn,7 ņqaX*/(+|> Gf!?þ6x?A__8F{1 S�\ ,ϥQǂ3وO >"8?OPWf}.<B~?}mqqeA&3MDR<|۸oO*I�V4JymXɡ!gyA__8F{1 SœɼktDqz&p^u Sz60dATz޵IWhp؝V|ܢ]JF,zJBob8N9TaWw{,vk,* oUtNz޵MtA__8F{1 Sl|".HFIk]\I!^j÷4fh6RF(EXukĒ;yh:njIXliۣ"f%ezUL>cy nnOCQf.؃v붳nQ"x}ۺSSI8sf<VE`(mOrg3pqb;o+ȧx}'[c<M$3avh)f1D1Hf_h N lcZ� sel&J6մJ7 uni&'Yx*ij ' t]%Ud 0wa_ڕӷ2R;#(ڷsFnլ{,f+2PWf}.<B~?}mqgQTpJ]BaNa'Pi6좣kR^/gm7*_.9\b^H�O\|>ϣSx1öm ڭýx! 8If7:4H8ڑqG7Z7wvܖf.`ʌHWv,س 6mDBeA__8F{1 S�\ ,ϥQǂ3وO >"8?OPWf}.<B~?}mqq['~ ӻ$9!HrC$9!HrC$9!HrC$9!HrC$9!HrC$9!HrC$9!HrC$9!HrC$9!HrC$9!HrC$9!HrC$9!HrC$9!HrC$9!HrC$9!HrC$9!HrC$9!HrC$9!HrC$9!HrC$9!HrC$9!HrC$9!HrCOU[Ѷ|%~ϖg('wW_Oocn<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<QY_PWf}.<B~?}mqqρ2?]Om-ZEmJ)eR|W;J?I+J ,ϥQǂ3وO >"8?N90o "o"xG͵M'bsSrlp+av(c){omX;YlqČLN޲9]<fԫXT$;[^78-BC5Aʮ]6x>| A__8F{1 S>!s8u&Rhfc&_4L}JӜ*i/zMҝjLEWqF6c.6MHj2щ!Ui bZ]Zĸ`,jK[':K2Yaٮ,;W>YKgly\}~E<p~saQZy\vG[dldcTZ})bhmHQkwZ5\& 2 ǔI.z6Z(WNI>oUE8gS2 !(hV)!Y/=Yg�+r\/x#=`)zF->BF1-qjhE7lc+zX-F ebR%ܝڮ YV%#Jee_#$mn^%c$B&$EF@4.o{(VҶ6qVзM\& HRX&-D٥FϹ_PWf}.<B~?}mqqς=+/ZjeZjeZjeZjeZjeZjeZjeZjeZjeZjeZjeZjeZjeZjeZjeZjeZjeZjeZjeZjeZjeZjeZjeZjeZjeZjeZjeZjeZjeZjeZjeZjeZjeZjeZjeZjeZjeZjeZjeZjeZjeZjeZjeZjeZҽU|%~ϖg('wW_O+m/t2Fd3$fH̑#2Fd3$fH̑#2Fd3$fH̑#2Fd3$fH̑#2Fd3$fH̑#2Fd3$fH̑#2Fd3$fH̑#2Fd3$fH̑#2Fd3$fH̑#2Fd3$fH̑#2Fd3$fH̑#2Fd3$fH̑#2Fd3$fH̑#2Fd3$fH̑#2Fd3$fH̑#2Fd3$fH̑#2Fd3$fH̑#2Fd3$fH̑#2Fd3$fH̑#2Fd3$fH̑#2Fd3$fH̑#2Fd3$fH̑#2Fd )mSJ ,ϥQǂ3وO >"8?OPWf}.<B~?}mq2g3pqb;o+ȧ>YKgly\}~E<p~̠\/x#=`)�e~ϖg('wW_O-RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRNTWf}.<B~?}mq+LdHi#v4Ƒ;GcHi#v4Ƒ;GcHi#v4Ƒ;GcHi#v4Ƒ;GcHi#v4Ƒ;GcHi#v4Ƒ;GcHi#v4Ƒ;GcHi#v4Ƒ;GcHi#v4Ƒ;GcHi#v4Ƒ;GcHi#v4Ƒ;GcHi#v4Ƒ;GcHi#v4Ƒ;GcHi#v4Ƒ;GcHi#v4Ƒ;GcHi#v4Ƒ;GcHi#v4Ƒ;GcHi#v4Ƒ;GcHi#v4Ƒ;GcHi#v4Ƒ;GcHi#v4Ƒ;GcHi#v4Ƒ;GcHi#v4Ƒ;GcHiG2>iKgly\}cL\/x#=`g('wW_> Gf!?þ6ƙ_8F{1 4ϥQǂ3وO >}.<B~?}mq� M2Rn�9IK:J>uWi6IkVtzXUF_j3pqb;o+%l%~%pEp{b?◚YԮgZ|QW&jܓVng"{-O۳SQ6Ki}YEnKW^*g('wW_u^Y%[}{vs^2RkkVv]ͣFY⮬nnIWAU"TJBIXr٬?Ė#<�[kfGof\#dʦo*ޒֽ| t٬͓HV~Cgۊ'/*4΋Nܴ;t3s#)H'H/vJ6 _304R ܡ\.h%˹VZJ,[8Y2(:1.f+K;|)%.t;wCt;wCt;wCt;wCt;wCt;wCt;wCt;wCt;wCt;wCt;wCt;wCt;wCt;wCt;wCukOg('wW_O-ִ c/Aul&|ƑJYXkK2q-[EoY!G]M<c}41] ~$9Rt[qA5f`Mt{ m1ulBїHB&.+WMѣv_^b )DqYD)ذbUS? *{<)Wud[Dہ)C2 L+m5iJrU,*VW%a0宵Wf}.<B~?}mqڽXyeNO k gVYUוUln#Vpj5OI:d#]/qXuڪ3Y ۞ȨeHnkB,{j öh. %R. bDI9FSAaԹx ѱ6Yn)p#x])U1031R)F7ĘZ%a^' u &|%]5Xurg3pqb;o+ȧ�F|r[PWf}.<B~?}mq2g3pqb;o+ȧ>YKgly\}~E<p~QKRw%+QKRLSZ?�)Ě(Ėk>ko(կJ"(+|> Gf!?þ6x88ED/ҏ'EUNsYaKNjz.1rpѯP%a֔5l5-)}5-(+u)vX~YW+u(jureQŠYJR]GjRU-UjQ8iuɒ-G qG-pjYBYRR+JRۿ@ ,ϥQǂ3وO >"8?O𚎵H^:ȸ>tqkT/̶lo�N KISʎ z^M]2EӮ 9QdQG֮[ B/{G'NעwۜEClͺU& 1P.Rḳ aܤ۶^˥fDzxqHG5n 3JrYXU߸QIVvL\RvWIߩo\/x#=`)�({vֱUk;~!dzi;FlnxSN6ͮM6f%"^1�>ذ*[scu2{fz7da_Q9kI-BЌ¾!zV aG{1-+6x;hw :nCʮxjON$NaQV1jMa>)ĒW)H E=oe'�(+|> Gf!?þ6x?Ks9Ѣ>r5u mtUa9CG̓NApͪDW)7wc\')!ۓ95 E(g֯+kִ“t' h'"FbͭsY-a n|A¤=iBМMa3q_k4$˗N[~NEX5YFȵƬ HQn*aTRb"FdtDͼ,%--?~ϖg('wW_O�U-[#alS\/x#=`)�e~ϖg('wW_O%Omy !6ÐrCal9 !6ÐrCal9 !6ÐrCal9 !6ÐrCal9 !6ÐrCal9 !6ÐrCal9 !6ÐrCal9 !6ÐrCal9 !6ÐrCal9 !6ÐrCal9 !6ÐrCal9 !6ÐrCal9 !6ÐrCal9 !6ÐrCal9 !6ÐrCal9 !6ÐrCal9 !6ÐrCal9 !6ÐrCal9 !6ÐrCal9 !6ÐrCal9 !6ÐrCal9 !6ÐrCal9 !~UF A__8F{1 S>ZS68c68c68c68c68c68c68c68c68c68c68c68c68c68c68c68c68c68c68c68c68c68c68c68c68c68c68c68c68c68c68c68c68c68c68c68c68c68c68c68c68c68c68c68c68c68c68c68c68c68c68c68c68c68c68c68c68c68c68c68c68c68c68c68c68c68c68c68c68c68c68c68c68c68c68c68c68c68c68c68c68c68c68c68c68c68c68c68c68an>g3pqb;o+ȧӎ| =FQ8m)[gqRp�"q% ë�#Dc/!eH\N''CGa|cYi|-ED͒ȮQKRk_;UfϹ_PWf}.<B~?}mqqρ.f%Qob\];d1Tߠž.X\Gedh_)M ſ4dvBi[ٱoV6݇Gx/KmXDfϹ_PWf}.<B~?}mqqρC{>yc,Sjb14坻^цYmMj~xիj,F++%#eBC#O9+LC|,$~W>YKgly\}~E<p~saO.R"I)5NQU1"Nf~�gو,xZ) %١(�S(ɦ63ebu>/GlJn`'YҽTq5ɩk3^6}>g3pqb;o+ȧӎ| =zoӻt[Y1MW8`q+iN:27AO<b x4&�#Ƹ E\A ӢvH'$62W bD+%pYk-M*%o>| A__8F{1 S>.Ct:Ct:Ct:Ct:Ct:Ct:Ct:Ct:Ct:Ct:Ct:Ct:Ct:Ct:Ct:Ct:Ct:Ct:Ct:Ct:Ct:Ct:�| A__8F{1 SˬjL3gDΉ:&tL3gDΉ:&tL3gDΉ:&tL3gDΉ:&tL3gDΉ:&tL3gDΉ:&tL3gDΉ:&tL3gDΉ:&tL3gDΉ:&tL3gDΉ:&tL3gDΉ:&tL3gDΉ:&tL3gDΉ:&tL3gDΉ:&tL3gDΉ:&tL3gDΉ:&tL3gDΉ:&tL3gDΉ:&tL3gDΉ:&tL3gDΉ:&tL3gDΉ:&tL3gDΉ:&tL1kJ ,ϥQǂ3وO >"8?OPWf}.<B~?}mq2g3pqb;o+ȧ>YKgly\}~E<p~zRŬSUӶU{kc�ճlJŋlPzm�~ϖg('wW_OneJ$8MܴzڄS<(\+4+|nT6 mm5i(W $[ܣU>]t֑S3< ף PWf}.<B~?}mq ޵ik'6;&L>dvqY׫\dgvniEjuq2ta&V-)%n-ЗF]튥/+$g1n4[HH8ҕIEuLM#s}I݆f\8XES_a[VY TJB]zHbTs*B8K]NIjOzH])V/PzҲL}tm+ӉL@ w/c*/g3pqb;o+ȧx-|}{v۱^mzbY*� K𝔤]G-9x#;Ndҝp+)H,%eBTw.l+?}D> [ ll^e㷵 ڻ}1+\$4({|)?ԢUta-:R=FEg=pv"aցCXebQ\Sm*)Hy[oܡ;|tg̠\/x#=`)�dDZ^6F9tYwTu9 pE&᭑K$eVfWn$ n-%lѫFNcۻhZQyvV!_oU[)\IyL9z}H5ݶJ~%Ūc<l ">VZmm$Eޚ0W8kr((Vh75^8Rjt{ܵlUbBwdabʥ4Q.-]ڒUq Z"q +ܪ^U T�%~ϖg('wW_O�ppз-PWf}.<B~?}mq2g3pqb;o+ȧӗݒP;y@(wP;y@(wP;y@(wP;y@(wP;y@(wP;y@(wP;y@(wP;y@(wP;y@(wP;y@(wP;y@(wP;y@(wP;y@(wP;y@(wP;y@(wP;y@(wP;y@(wP;y@(wP;y@(wP;y@(wP;y@(wP;y@(wP;"UG(+|> Gf!?þ6x8s/y8^q{/y8^q{/y8^q{/y8^q{/y8^q{/y8^q{/y8^q{/y8^q{/y8^q{/y8^q{/y8^q{/y8^q{/y8^q{/y8^q{/y8^q{/y8^q{/y8^q{/y8^q{/y8^q{/y8^q{/y8^q{/y8^q{/yaˑq}PWf}.<B~?}mqqρ䘦ŎS�U[Q/"Ϲ_PWf}.<B~?}mqqρ];nKS{rtݝvxX1[TcZR7|ޅ},ֲ^Y;ik/>kЫ)[o^ꛄ/nj۩}.VksR7b)B-N5-WhKzIG_m(&jjt7#e7٭UzP-)rYK^!}~ !elpؕ( rJB]#BœSϹ_PWf}.<B~?}mqqρVi:1SVdBMT%-H!t0J] gsG%tmw9Fe`Ԃ{Ա%rQR:ծ'u{Hcȑo\E)V9hWsR7ɭLZ'81unjl{:0ݴa0i_mv!nmj4bUb+JI9utGV 0LX0yn1(G _,&75s謾*q[#}[NIV58V˚źUZuNRQWp6a0Vqd�|%~ϖg('wW_O{n$F#E`] +@J8\=k[?J1"#nsIfY̋Eamsrg]IbYޅ>f1g0Q ԨVi(,mhIUz1P˷gM{W}s0v7ӏx[ڱv>KbZvl*d{+w ԶM-h_ߒa۩l⑎^5ZN.]-<vxYnK A:=Z!XOEIOr\/x#=`)zV@saH=6:w)5PM'7.KamWՈ5K*e,iy9-F8une$ +F77:2o't \KdSSA `V?I;wu`7tR=f.?5:{0iN_]-3s bطoߏW-WgnfpC׆w0s 4`-#kdc Rk�sW>YKgly\}~E<p~sa_�z1ccC+J ,ϥQǂ3وO >"8?N^SnhPСCB 4(hPСCB 4(hPСCB 4(hPСCB 4(hPСCB 4(hPСCB 4(hPСCB 4(hPСCB 4(hPСCB 4(hPСCB 4(hPСCB 4(hPСCB 4(hPСCB 4(hPСCB 4(hPСCB 4(hPСCB 4(hPСCB 4(hPСCB 4(hPСCB 4(hPСCB 4(hPСCB 4(hPСCB 4(hPСAG(+|> Gf!?þ6x?5L3TS5L3TS5L3TS5L3TS5L3TS5L3TS5L3TS5L3TS5L3TS5L3TS5L3TS5L3TS5L3TS5L3TS5L3TS5L3TS5L3TS5L3TS5L3TS5L3TS5L3TS5L3TS5L3TS5L3TS5L3TS5L3TS5L3TS5L3TS5L3TS5L3TS5L3TS5L3TS5L3TS5L3TS5L3TS5L3TS5L3TS5L3TS5L3TS5L3TS5L3TS5L3TS5L3TS5L3TS5L3TSPWf}.<B~?}mq2g3pqb;o+ȧ>YKgly\}~E<p~̠\/x#=`)�e~ϖg('wW_Os(+|> Gf!?þ6x+~:C:C:C:C:C:C:C:C:C:C:C:C:C:C:C:C:C:C:C:C:C:C:C:C:C:C:C:C:C:C:C:C:C:C:C:C:C:C:C:C:C:C:C:C:C:C%*+|> Gf!?þ65)Zv;q;cwv;q;cwv;q;cwv;q;cwv;q;cwv;q;cwv;q;cwv;q;cwv;q;cwv;q;cwv;q;cwv;q;cwv;q;cwv;q;cwv;q;cwv;q;cwv;q;cwv;q;cwv;q;cwv;q;cwv;q;cwv;q;cwv;q;cwJS_8F{1 4ϥQǂ3وO >}.<B~?}mq3pqb;o+iKgly\}cL\/x#=`g('wW_> Gf!?þ6ƙ_8F{1 4ϥQǂ3وO >}.<B~?}mq3pqb;o+iKgly\}cL\/x#=`g('wW_> Gf!?þ6ƙ_8F{1 4ϥQǂ3وO >}.<B~?}mq3pqb;o+iKgly\}cL\/x#=`g('wW_> Gf!?þ6ƙ_8F{1 4ϥQǂ3وO >}.<B~?}mq3pqb;o+iKgly\}cL\/x#=`g('wW_> Gf!?þ6ƙ_8F{1 4ϥQǂ3وO >}.<B~?}mttpL&n7 f3pL&n7 f3pL&n7 f3pL&n7 f3pL&n7 f3pL&n7 f3pL&n7 f3pL&n7 f3pL&n7 f3pL&n7 f3pL&n7 f3pL&n7 f3pL&n7 f3pL&n7 f3pL&n7 f3pL&n7 f3pL&n7 f3pL&n7 f3pL&n7 f3pL&n7 f3pL&n7 f3pL&n7 f3pL&n7 f3pL&n7 f3pL&n7 el<B~?}v"i5țc"ldM62&Dțc"ldM62&Dțc"ldM62&Dțc"ldM62&Dțc"ldM62&Dțc"ldM62&Dțc"ldM62&Dțc"ldM62&Dțc"ldM62&Dțc"ldM62&Dțc"ldM62&Dțc"ldM62&Dțc"ldM62&Dțc"ldM62&Dțc"ldM62&Dțc"ldM62&Dțc"ldM62&Dțc"ldM62&Dțc"ldM62&Dțc"ldM62&Dțc"ldM62&Dțc"ldM62&Dțc"ldM62&Dțc"ldM62&Dțc"ldM650\8F{1 َ<B~?}cgl�EZQwg]|Zv|Zv|Zv|Zv|Zv|Zv|Zv|Zv|Zv|Zv|Zv|Zv|Zv|Zv|Zv|Zv|Zv|Zv|Zv|Zv|Zv|Zv|Zv|Zv|Zv|Zv|Zv|Zv|ZL8Đ%"}lNʑ#*FTR2eHʑ#*FTR2eHʑ#*FTR2eHʑ#*FTn!vtFR*FTR2eHʑ#*FTR2eHʑ#*FTR2eHʑ#*FTR2]eUYI٧#*FTR2eHʑ#*FTR2eHʑ#*FTR2eHʑ#*FTRT'w?\z駪Z]z5kשS^Mz5kשS^Mz5kשS^Mz5\rnU?װy}sTS5L3TS5L3TS5L3TS5L3TS5L3TS5L3TS5L3TM}85L3TS5L3TS5L3TS5L3TS5L3TS5L3TS5L3TQg_ |VsTS5L3TS5L3TS5L3TS5L3TS5L3TS5L3TS5L&k\/x#=g+O4J}Z,V?W52Vu}ı#%}wۊ_ӯa9W-XmjyV֥z�s5__B562('*^qg_ |}U[vj;AReoc9YIKgl�Eq�O(l1k0͍S!mzbX?c[?wۊ_ӯa9JGw2G~آ]JFR|ܵKo/rU*~zkWIe_Ha.]; zWRܵv \5^heamԿ.<,oq/mVWRƻԽ1(&j�g('w?\z駪S,aJURRm6KE:?wۊ_ӯa94ɼEHx5yV^YJY:rq+Y9K=S_N5+�Ѭ>Yp M3Rq 4 cUXf�qg_ |}ÍU)ym/"YɋQCe;U<> ].)KW}.<B~?}ǧz>ő(o&f вUXfjP�n*NC*s쟘뫰|M¦*`M> jQHȥ PԭK=S_N5+�Ӛ"' Jg3N(v5Jm:2Hb6h_IK޾.�,^OQ䰄%6B-4&î,R9Yn[3pqb;=?)�Zx)W+`Zb zJ(J'r2V-?wۊ_ӯa9k$0JVn5jD 솈ILBJ9*'b`lNgxUa.e9q_&nZ4Ij9FC M, 3EaiCaK(ŏa5C.<,od%yk\ fzJvv=Иw)Kgl�Eq�O�]n*NC�9q_¢)p)%uW 5UI�޾.�rr 4ik43pqb;=?ō׾}*׾wԎR;G}H#wԎR;G}H#wԎR;G}H#wԎYԫLM}Cu"GWJZjZjZjZjZjZjZjZjZjZjZjZjZjZjZjZjZjZjZjZjZjZjZjZjZjZjZjZjZM׫kUKsjZjZjZjZjZjZjZjZjZjZjZjZjZjZjZjZjZjZjZjZjZjZjZjZjZjZjZjZ.,JҍR޺ҭpqb;Ӫ;vޏGz?ޏGz?ޏGz?ޏGкe 8^9^Aʿ?<y?<y?<y?<y2Hp:_?<y?<y?<y?<yrKyS?<y?<y?<y?VS U f!?þ1ǂ3وO~qbʩ*șșșșșșșșșșșșșșșșșșșșșșșșșșșșșșșșșșșșșșșșșșșșșșșșșșșșșșșșșșșșșșșșșșșșșșșșșșșșșșșșșșșșșșșșșșșșșșșșșșșșșșϴ8NJ-jW(qG{;Qw(qG{;Qw(qG{;Qw(qG{;Qw(qG{;Qw(qG{;Qw(qG{;Qw(qG{;Qw(qG{;Qw(qG{;Qw(qG{;Qw(qG{;Qw(qG{;Qw(qG{;Qw(qG{;Qw(qG{;Qw(qG{;Qw(qG{;Qw(qG{;Qw(qG{;Qw(qG{;Qw(qG{;Qw(qG{;Qw(qG{;Qw(qG{;Qw(qG{;Ux�>�����!1A"Q` #2a0Bq3P4R@C$b�?QPB:+V ~šS/ݽ;*'y(1@CDؑ;HtZc2$!q`�{J14-T(knEDy$k� hoh>ƺ& MmowZ!K�*� G꽛ĶyڜTDkW'h�V)Ӯ*삩pSj{;C*>-'N`Mtq33JC1*j/=s%[a{cyT!HU`T6ٲhiS&ThVho<sm(y9Odin5<g5Lq Jkix1)}? 54�7b2 ag2*Y챋}y Bʕ*TRJ*TRJRJ*TRJ*TRJ*TRJ*TRJ*TRJ*TRJ*TRJ*TRJ*TRJ*T2_ҿ?V'R,OUɅ=>�U?E?c jS~{Ӳ U# )B-֍Jw a<D�Ml5O$ȸrL4\ӈDlPN!;øk%_P*4>=Jo/8@2eÍ:-࣊B&�ۛ!0'a4\ kF'`*0L#yٺlB`/-"48NơmgZ󢵯r9 2%# hQ(m_2$ sA=؄[�s[㒽)ti1(] r9�O-TNV7U8&33T7!9rSs?$~*Z]&S q ֹAأe]tgec;+yUnct�Bq#)͌nGq>]0A{7Nݔ"pŪw@E_ꁗ @n;ρ>tfUY y;jy?&r:0Us0Qo507|!s)Ppmn3+os  aIfA) qʓ]ha~.bݐ1{RV/|@ vf'hEHh 2 j"UH/&AZ>BhuUxN&Q64P0ƪy .,0V�䛧dE$qnA '\O `T5NBQ8M*C&S=RJ֛(kkg5qfI)> pڦbARuwGG:�B:(`|T�ɟ{~4@ d4^5U5<FBiJքX9iw )h9C:*@q)(TP% o>)OҩRzʆHT ,cӢ�D pŻB0d<%8sG9&4kNiڙW]h @/`7<dH@i}qP&Sx `;́-222$r뎩~ow8ݪh��{'EXq>q7v@�-G?tR;aHd.(gD9D-}:)>�<:#TtOānXJli ּ7Ĕ3Qӡy`7KюI`|@)pFEzZGp4 *o G¦h(|J 7 M*X{F>S;"[U ,R(ՄE~@ ;!*UD~K0 L[o�4G+Qn"K@� {l:!4C h4N+hE\@@q#GxqoGa[ZZOa9Ƙǘϳ SkKPAM7*+ 'xz cE'շp3IU<&IKp%S6Si'm h9ݏivgN8h?Dd'O5<iLUBMD 8D?^K v'yJ?h~]êGT^`*DU (:@<iaOj }� ;Ij9'BcoD"�<rmEcOG�i3TKEKX1 س47 mEdz�e8,cFUVZr3>fP©D<7o�Vgtxdm)ms`o$(D徉tqÕ_19ts}@ʣ 9 CSuOwJ:{ uHh.[OtgD @IxqoC- }�ITAtPŴFF5 ;<[h4wO֖msMT`|hU @qüL0J|̧[MʃL6`ieD{G~Iv8wv{4Έ 1ݣ3)49;oa:8ʌ9;yaSn3êGT%ġp7D9 gEqhDxDa�'EgT3cAuݖlOTE&Gai)HDv@Ш e9PN8(5M摪e4vnuܕ3-!:! (N&)1 "oE2x/7IR:uH#Gy.0azc4I2WG @!$oۺpcMfLy0<':i=s%ƈ{Y"�ȕTķb3L8mW:tgt%㺠68@]fHy*gNp6a5)XuMidi ZD[ (# xmASS`&p0&SM:c(`T7ߺo Q-PtDNxMl!<jP1kKFao$ HQ#G]e~ELB^%dOu"}W3.?L)'x;0уLÂcA\{F=12{l�THLp7V7x9#,Y@ZXP;\'q iUKn^\aU[`�hO*o& 9?Ź7L8CPv\KV "%?AC&NC+GW\n)NNd�gt0y5#AS<O*.%8mj.TZZ$B.%|lvI@ȑþM ל80Q*f kJxL0$S?PuJcå}_x@MYhNAEAL87tll9 eMٹ8FSA-zXuH#8is\;�>)]bJkyEԦ48nz !5WsCqVWuU\n FZn�\"#n^Xˆ@T_L0jONi x`8ꈈAg&|kɉC:>CTY)~*3*-^ȩt!DI#ETd9 3ATJ7_##D6Ϋp,*Ъn|ʛKh-~- #{SLPaNHߧ NGhJ;TI^L$ lTcs={Ct'َAAMRW8âHGZ] `Kyua䌲@6;taj%U2hyU{-XցN\?eak8k@cq䈐G+kSiSfʟVCv b kDDyq- 6͕Wm@B/$ZDCM-Ξo-W@Z낼0d �7.Ky1#GTR:uH#GTR:uH#GTR:uH ӽ2ao s JïZ-~iޯ0'ZڣoW&6*H�deVI~Ⱥ>a{D:KV4jSHaiu7z*m-~MOxw*JJ IG܃NO;yh~|B]ŭ? 'H4&`9Z ?uwj*t�!§Ĩme}XQ,D૶Xg;Ԑ!:4T/wrmFQjs9w�;����!1A "Q#2`a3BRqP0b$Cr4@�?TJE/|_"ȾE/|_"ȾE/|_"ȾE/|_"ȾE/|_"ȾE/|_"ȾE/|_"ȾE/|_"ȾE/|_"ȾE/|_"ȾE/|_"ȾE/|_"ȾE/|_#L|í;!rtK=M=iURy*|1p<njItct2ŜVn1'.c9e2i*SwDة)zG5c,T^mTRJ+J*TRJ*TRJ*TRJ*W}!+eRzjjGF99!-UA#MC{=e SS0j{oCS챒$ޣr[I g--Oe|ѐլa5߻f{pUOڴ=[6j= Uu23g[N (YgOBO,^5Z"1&4f_ FTRJ*TRJ*TRJ*TRJ*TRJ�TMԇq\Ce֧?6KVּ);R>lߑB8 VdzEGЏQjj֤eI)<{':8X 9Xy.ޣ\\jIQj2MJ%lyc]TRJ*TRJ*TRJ*TRJ5sV rud%(lQCgmvgmvgmvgmvbӒ;l;l;l;l;l;l;l;l;l;l;l;l;l;l;l;l;l;l;l;l;?Ӳ: :KJ*TRJ*TRJ*TRJ*TRJ*TRJ*TRJ*TRJ*TRJ*TRJ*TRJ*TRJ*TRJ*T[t?3nޅiiiiiiihrKKKKKKKKKEZZZZZZZZZZZZZZZZZ(ba*L------(nZZZZZZZZ<-iiDZZZQ--䴴:Gn$⟛Дz0oN'%ī =$iz2vC DwT5i Ξ\iXdQFI%COЎj?y-9<dI5iRu1#?sD&gaMMEHWNfzЎtޤI5[MYY$j'4ucӋY%HſMȦcǡ$֚֗jK52GaLԓZzn[~X\ Q|,ʄk!lh؍r#-|{Ebo8Hjdj:4䪹Ӈi\Tb:kj[(&8)Nv#'K79p(=>R�e')$j5clN_?˻>k̬wF ,|S {0Лa |C^G5 w9pKh*E~#1#VINJS,G >kQ<)K ;꿹+ܮ{lNJ%NGgV)(i)2UӤ%;oҋ4f~2њ�&hKr_CW)r6J\P^HiJ“T?Хu'BzrxɯnO$ZSME�M-IjdQ ?TwyID.,vԽz0Yji7_j5+[&mRQ%i�Ό+"Q*SYV z|n:�#R`#N"C|?d4܃ CEz3UQB*%+hCuPwۋGQSFJN4 Q,y?AG䖤'r 98vԲ�B~Hj>U e2h1oB��#M�$j*M`54�ѥdrZY:iGlc:F  M?£"�Chʄތ_T뗂QkM} rGhj2h;t=7ɓ&L2dɓ&L2dɓ&L2dɓ&L2dɓ&L2dѭ92dɓ&L2dɓ&L2dɓ&L2dURR$)JYfI'%FFRL2dɓ&L2dɓ&LrܓYQQ2daܤ%HM9Y؃4Y4׻g/2J[$M>f*u*|J;PЛMg,|Jr8ښ| ͱNh,GͦKCS਎%HCBnkAEYnQ?�<b Գ,NBjUSN4xiZ)TҏoV?#J)_t%OhĮu5d?RIM4oɣyHv �C_:0ПZ濱x6ӂ[$/#{{ڿi:J*#Is;V](C#Ub-"GI՜ZZשWm6=Kr,lJtkIE(U䫫;t=̈%H"#Is;x5mq䭭%܊=XǍ?+)CM9)%:/6P{y2sIVQRhCo*#j%NV6I)#as5h%H9q5F#IVGU챔wzҤ]c7n(:˶ܺ8B?i/s}(i%}!%]Z%zFj(|~ky'?4oi/1=u%6]hd9BmP۫ ۤ W 6C#JN\RJIymŊТ|Qع֧ z1asq$IsG{lH]ȫ^ZТεۤdDv.zGoKJlGW^{pC+'lT̵i?,_R_ˆ˼j֗5ܛQjd$1kqZr!W?sZ .+ԦZ-ۤfjcyX7PsA?Rrqp�VY_Mw']hJ"-5(sQWɩ*ǟƶRx U\n�c)NQ4i݇o(�܇?4OKDGnvԩRJ*TRJ*TRJ*TRJ*TRJ*TRJ*TRJ*TRJ*TRJ*TRJ*TRJ^r~$Gnv2sdkWC(_,ER1}3ipAv4 N?t"0RR4_(K {Ĉ\bzX�(+=4_ݚ}j1(m{Pwz%OdhiFR�J=Hz�Q/%U(S '7v /�?b_\T͙|~ۤ )zOH;`!䌣S"&,a> Wj:oR~H iZ1p"ێƜ<\Rwʿ!=_Dv.zGo2dɓ&L2dɓ&L2dɓ&L2dɓ&L2dɓ&L2dɓ&L2dɓ&L2dɓ&L2dɓ&L2dɓ&L2dɓ%<ǘI֯Ĉ\2";t=#dYv ã7kStkK)/{?A�ӧh2n5YkF8b#Z.Wdɵ=JKR޻! \~)b#%DiojXfPe.Hܞ诖=h[LKGnvj+5VE5<4JkM⃒Ӗ5YEIg9єWՎ0SR5ބSՂ)"o'y5o{rԜUBIEI>qۓUZ, u䓺OKDGnvɓ&L2dɓ&L2dɓ&L2dɓ&L2dɓ&L2dɓ&L2dɓ&L2dɓ&L2dɓ&L2dɓ&L2dɓ&L2d|H%Hfdo$UӇcttc} y$4u⨊Km-W3Kͩ<nR$Dv.zGo%ն[~b9W�:w^hifPMzi⃫zsn7vxT�s/Er+*v#ՕZ;ӷk}'#Is;x/7<٩':7V\SCuЮD_V؍!|H%HܵZQj-EZQj-EZQj-EZQj-EZQj-EZQj-EZQj-EZQj-EZQj-EZQj-EZQj-E";t=#̈%H"#Is;|Ȉ\2";t=#̈%H"#Is;x%+UY$ *m^izqq]>F鸥9vq^ղYLdGnvMOd\J#喳K1z+Uo=*N~#]YQKV^o{DjyjJ>+o[FsB*3R_ 17gOP֊ueCY�i[\U7I%#FS[$/~ũOWqR�eDQWH%HjbTK҂‚$1%YJIp<(I\ɻ\_?<my/ˑoHN4y(G*�i\m;?Gܗ'Rf[oͺT𑊋RRsu!";t=#̈%H4iIF;bV{arKiF~!ӿCͦIJq(iJn2Dg(>(%H^ӌHfg[IN^#*k.qGn93q^[�NKYE~~VJ4iytJ>}OHOZll9 **F Q_iާ7(�3FX-i5/,ua?w5Ȉ%HQH"1snRQRTd]y&ҺKv9(Ħ[/wA(:矩jR^X؇.E[K$|$|MrCѮ ?C{iȨ%H"#Is;x[*Ak*IUrPb.2iE&Z8#Il8(PB (PB (PB (PB (PB (PB (PB (PB (PB (PĈ\N N+Mm�WMqO& y4]/5NXoq*G<yfDd<S);7#Is;x_% G40EQZqx*ܑ%QQN'[֤wLVlHBVȊ$0jN]o>$Gnv2*ʲ*ʲ*ʲ*ʲ*ʲ*ʲ*ʲ*ʲ*ʲ*ʲ*ʲ*ʲ*ʲ*ʲ*ʲ*ʲ*ʲ*ʲ*ʲ*ʲ*ʲ*ʲĈ\2";t=#̈%HsW^_ȇT ouE*d7JׇA(V*IK2.ȵ8�".8~ՓWfjũM疟[pfvM< 3ph˷|I�쇑jȇSpnŵ~ADv.zGo9iHlO-8Iy^�q;Abҝ?sQi5ԃ\QzK|�r+=XK(j}SSF^ϫ<R]jI|z5OE*-)V*?L~#kir&Z{T' Fš8FQKEIQ�+";t=#J*TRJ*TRJ*TRJ*TRJ*TRJ*TRJ*TRJ*TRJ*TRJ*TRJ*TR|H%H}VUzWɪIN((O9";t=#zN:%m_]aQz]䰵5WZY44w)[%7�fr6�u$a;�(E7%S+�R 2{AF0 q\t[}b|ێΧh4>ؒJSkRK3J1{�#e=_1.$Me52>$Gnv1cND|~bø]n|"OAvb<'ݰDQQ~i^/bR.y)GЕZ:7in֧7UUҼM~/t_ƹ";t=#䴴ۤdDv.zGoKDGnvۤdDv.zGoKDGnvۤdDv.zGoKDGnvۤdDv.zGoKDGnvۤdDv.zGoKDGnvۤKIsV\r.Eȹ"\r.Eȹu"\r.Eȹ"\r.]nEȹ"\r.Eȹ"\%Gj-EZ(n*ZQj-E|Uo><<[xR+Ko7;t?>I{61ӃڟԔ~.zGs~ĥ-8O)z { sut%qy7ES٩[�sVU\P;ԆUlˑ%GE-'~٩ U ZRVgDv.}1PMWJ /(SJ\=#p)Х<}'K#5E)QbOSʪd1mԋz]Gaj\XMj�sٕO(cF0Uilb/N\b0uۤ [xX9)Qb6rEDv.P("("("(nKYk-eZYk-eZYk-eZYk-eZYk-eZYk-eZYk-eZYk-eZYk-eZYk-eZYk-eZYk-eZYk-e*."Xb,E"Xb,E"Xb,E"Xb,E"Xb,E"Xb,E"Xb,E"Xb,E"Xb,E"Xb,E"Xb,E"Xb,E"Xb,Et�A���123q!4A "Qr#Bp0Ra`$@CbPS%5cs��?XQ @n6zJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJa:N[vA4G= 2dɓ&L2dɓ&L2dɓ&L2dɓ&L2dɓ&L2dɓ&L2dɓ&L2dɓ&L2dɓ&L2dɓ&L2dɓ&L2dɓ&L2dɓ&L2dɓ&L2dɓ&L2dɓ&L2dɓ&L2dɓ&L2dɓ&L2dɓ&L2dɓ&L2dɓ&L2dɓ&L2dɓ&L2eEEEEEEDl6r&+z'KXw999999spxਆkH[}ט&Lݾ%ȼțrD$ 3 H(~/aHv#9jQ o/so7mV%yv^f�/4?N|[?Qe(!6?/m}OD}(X_K$'EX˜#g|7bCH8C7bCH>DqsK:~$7Qx/DHj<Uwa"#rCDT>LF(†z!EqytX02*|j$dka?wA|o8> &_‘/DS8~Ց-ؿj",Mܭ\NwWt5z!6?jLbFQC 5׋=q v1XmR+ùK4Gy$!y}ygq {SiLj(0oֻ㑒]o[*ߋ."#'y {Nr d/,5!REYS_>ϵ.$G\$k-[ȫz1r1#8Ʊ.KEVyfbH:mQcGz^dA춵\c@D-c[ %!o ;*' IHDMۄc2%fLhUQܩH&َ'x~hE"Ӄ�/bmLiiު/$!gD[6xꍟX1/ru?2[ XDk[ACOD!#x l{q&/BEe`) yn fN+>o>p&= 6 G"'`_t1FT|IS>՚/Q?�zuAHDM۾~a=86= jmH ȲkK1* حG"L s]3}jpbuoC|?QuH&;_ -Ze,!_DĽPMMVcD 1BRA#ۛtDw*asw홂0�$%љ|DNanb1= 1=V2Sw.${l<"7[#:*,(+|%؏l�P﨤gNQHZ6?mpMℶKg)8&N "[x' P\ݩIRp8픜(K% q Dc&L2dɓ&L2dɓ&L2dɓ&L2dɓ&Ls{nM &L2dɓ&L2dɓ&L2dɓ&L2dɓ&L2dɓ&L2dɓ&L2dɓ&L2dɓ&L2dɓ&L2dɓ&L2dɓ&L2dɓ&L2dɓ&L2dɓ&L2dɓ&L2dɓ&L2dɓ&L2dɓ&L2dɓ&L2bQZje)RJe):3UX"*:NSu:NSu:NSu:NSu:NSu:NSu:NSu:NSu:NSu:NSu:NSu:NSu:NSu:NSu:NSu:NSu:NSu:NSu:NSu:NSu:NSu:NSu:NSu:NSu:NSu:NSԴ.X=2e4i)SLM2e4i)SLM2e4i)SLM2e4i)SLM2e4i)SLM2e4i)SLM2e4i)SLM2e4i)SLM2e4i)SLM2e4i)SLM2e4i)SLM2e4i)SLM2e4i)SLM2e4i)SLM2e4i)SLM2e4i)SLM2e4i)SLM2e4i)SLM2e4i)SLM2e4i)SLM2e4i)SLM2e4i)SLM2e4i)SLM2e4i)SLM2e4i)SLM2e4iIvZ~MoegؚvZx8$H"D$H"D$H"D$H"D$H"D$H"D$H"D$H"D$H"D$H"D$H"D$H6p$H"D$H"D$H"D$H"D$H"D$H"D$Hd$H"D$H"D$H"D$H"D$H"D$H"D4-쵌\۫[`Qr2P/H1bh[kv;[C\C `G?MD֯^ս?^#Pzl,Db%ʹTb1^O1~p=w3Yv9}ԴZNjrq<Xƍsv^6z=?O˅ 0⣗�b͸_hcT*"DU/E^0Ď/N3_4 Xb�'55xcL~&^0+QޅlM ~-c6Q_mڛ.zT&7ػǦ�#2:5z\#[-{f+Q#6]?YH:25�'P@s#x_KK?>U慨̗n.]жn]D?+kQ|O=M4)r/%mQz;9wj� *s85\B Q8)s߉x2R~%"6CЇ�Ar'o= ;Q l%#C['Wx^}9QfD VzT **bAoڞ7n�T:�B߮Xͫ*Zbv,%аkmqhzé'Փw-,_\,Qd1̽F6+;R.>^lFnsW6ȑ0sj7w$ Kc}$YXEZ-2ViHH1wQU*+&jqoV|+{`739S`]!l"18EXXV1Zm;zt"-%^**/\1xv%wL߲م}IE} W VĴ#pR X/(x91َqժ,G5=HK61W?YcE=Qos8DW^EHWyQʟc\n#Z;pEEl{YY_e6:[FWy T1ՊFݣ|[CDurT>!"n 7 +WgrFxx $DͶ*7u*bqqh * ռ >V/SV۽dHnz*9}v)ig~uއ%TfKK8 .ĄHh�VI\"Z-hGE,x1U :d|KJ/CrSbs㱱!۾&-$E"a[L6[RYTZ-ڎ,CkToQH-Q 6/Hv"$Xn7,;J/׭]K" d(=;vOEqolv~qd=Z -jf1TQ՗-;eb,(oT~˙;Έ XKB†)ԯG(6b[zTR HNCvVXڂt[fOFudMھrqFZ7{c O#?lsS؇nsxOZRЯDT-GVaQ,1#=_ u>H)gA/s/_Oڇ,J2Ep"+woظ=a7bUr(A=FY푷lW,8:xbh[k|h[5!5#q, V5zTJG8ѯu޽HkwER"ޗlR.ZH0ƯSêiXp:]F{U&5êK={LjB+BHKwE/}K^(6ڄ{ii<CөB*$�Q=r\%h~CWi|7_$QzTEėObZг YaNָБ5-'-ya;N-Ch|<}H HΉzQqeWK B'3Aގݵ׫v-H~Eb>|W2Zx}Ë+-KwbYm01ޗ2!�g sՍsf?U-1,օ RtKK7áediz7lнa3[\8t^}w\]o򥉰ݼmFЎ.B4UKރ# nê|."}KJ S?GBݭU72©ľW¥+o^|<pGhQ_p6b^tv񆥓\渇dw!Gakb"T,-n}�xlR9EM%FoF># oê"Y#oShH,HΉz"h[8u!p {Ї啞Bbojq7�%-ŋ w!"/qaE-> oqB?_vNj&]WZeIFOQӝA7o02;rnn\LFB#(m"G%oԸhy2\6=QTWO J*nwȍ{ C'+b}xJФ֟Q詺./?Fb^%ֈV$%nA3S8n!rioнDe*: ԆF@jq2ґ*5!Qw#3-KGF]!dԅjept4آaaX�֮.T-HHX  AEe"6D!Ŷ9Oͼ[6 j\#"E=N&$NQ}k+uB3/ԻE bB \7fQpܟQV$Dz8b}+!̂˾4nE j6)i+ijabNi橃zB#x0X1ַ#jc#69hg[t񳺮}.a7�P(gY 0EN8QweibK4نG2n3z\*5ƹoRK,pln7^>oR?L\D_.6tL2 +Rwǥ/d.H?;"y k6\Ecz5#-Q`N8I")q^Cryѷ$Dlc[H̷qK̳O؛ LJ-^24TX=PuPF8ַ#�bh{2!w׍jTBzҭԇ]y$7V2\Zi=w% %D*,1j}Wު2D m--mK;<]4-쵌ڷ w^9WEEEEEEEEEEEF wňD-EEEC.^�+ھcREFe@NJEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEECVo1qh݇QQQQP z s$:) n)0&].Rr2["h[k?Us[ ʠEn% O xȗqzkVW�{_ ,x_Fb"6&xV+>AsQT<\^�gGB߮X͉ V8mw ֱըFސ1#VŒRS Wa+w~\ Txޝ O[sKR-Lj~.,D�ijnZp[qw%VRQvI>j'Gk/f=EcC+]P,F1č*FޥEdH!tU7H�?r xS: Љytsc]s6*p.%3r,T3-/IdB߮X͉ We*B9/cׇȸ3*7Xn=gz!Շ fFЉR<\DHM6Y]nCdϊ.5bgzT^x47__*GNw2�GdN, B&D_10toRBV-<vb{H^XnGkXtTK>b"_Mg-|ͩۅv?Zp ^[ /A|8Xޭl$ :C[-,Xt-I/ԆL}4-쵌؟.еoc5n"3�j,F{-zolЭM,*AwW�VҰ-qRʍ�c.ퟹG8z�[n6Yun,oX b-& Kf� 2{H]vA{gGLo·j !D9%!ņ:�c}6h,ۨ= Q<�rFGc%¤m\7T�wXoGYԾ0+Z -z_1Dз3bdW竞Dk5$c _dۤ9!}KBpFHVBUTv2+ap:δib9Ez9ʩ22 FEuL7q$6d>kUCvX"?ֆX)p눊sQhz9}ob1跦o/¢Be&7~7Q!uU7 H1nY"$VMCd&>ȚvZlOY }4-쵌؟c쉡oef8H&]L}4-쵌؟c쉡oef+Ȑ+DwNρuo~_/8Y";D>N"_)Dr_pحK|(LD_^1-;M!aEZ`X.GB߮X͉JZ *8}µքEC9AȈIm xj0Fqt.\+]hDSi'И=P"GXVEr >DarZR#'Ev:^_|8&(5.Ƌ噂$tk9F:5Wp]/s~#kRe0~ORGD.8xQZB"LMP4}4-쵌؞%W9.jeuާjֈtE6 ez)iH{0`6:fw}KcrRO�gOo,%F12/cg^VE �-(@q"<"*6>j-ܤHx:[`j&>[VxD}Tm袺\HY涱#>,�.>q ߉1,7/CaT-K`BsU}gȃ6+% \BzsoT/K4Mjb^Db"L-z2ʟ{HI'_rw"2襧|ypra+B+B+B+B+B+B+B+B+B+B+B+B+B+B+B+B+B+B+B+B+B+B+B+B+B+B+B+B+B+B+B+B+B+B+B+B+B+B+B+B+B+B+B+B+B+B+B+B+B+B+B+B+B+B+B+B+B+B+B+B+B+BTg8"h[k<NЍ2bÛHCȼZ#c =HVk-%RFc[݂i[a|3l ,CU⵮jIFcog wJ#+e/"hT/-pD h2,8qZjFٮ\}Ū^@Ե!4P{ {4kyb\il;E27]DDz[163hڤٮs,Ѣ&/ł/BԐNj6#~#"$53 _slvAG:5?ZZL2dɓ&L2dɓ&L2dɓ&L2dɓ&L2dɓ&L2dɓ&L2dɓ&L2dɓ&L2dɓ&L2dɓ&L2dɓ&L2dɓ&L2dɓ&L2dɓ&L2dɓ&L2dWCdM ~-c6'pͩ±QքGmNUQSďxlDUj�jid,EsU|Kۡ|5UbS9 Ւ귎95W_*E4+x ㅦtHK1۾7v2+dռܾ1#n<\o5a*]KC\W\+%1Et%W*S79 IGnd^U7p>+*w/qO}4-쵌؞'hF/qO}4-쵌؞'hF/qO}4-쵌؞'hF/qO}4-쵌؞'hF/qO}4-쵌؞'hF/qO}4-쵌؞'hFdFnzjzp1$" iCv#xvG+Wdw+V帋v+!Yn-�?�ߜoZj�0EJ>ȚvZlO#kѡX_LKzmϽ9$te^=QfƊ5ʜPzfuƋ]L6Vc~ѻ}T[C.[ٱ1RdOrAܷ/rySbZG~j]X1#pC^q|;-pY+-Ȋ' .pg>%D ʼnl ,;٠GEmCU> o-l/qO}4-쵌؞'hFj"'1�qg-h[qV}K*>]0iT^=wj#^"k绁匘H-OE:q7-^7DV3"%'L,r܄sռ ɄFctL0_?b,#/X¢t CdM ~-c6'ڥb/QE+5:3 ”AKN(n +ƫץڬUF' |Ό0\X$Eg>%.vω #xK|m1ܵFG[:WAd|$ŠD:SG;UkQ!gXMUi7? �qitX]Reѿ!Ȿ#*j^Tm,*8TkU5pXVw^8"h[k<NЍ[8qKؒm㳊^].(ob[(ocQ6PĎqKSdq$P8;'bDm~ !㏲&]:!㏲&]JiN^8"h[k<NЍn!/&КBhM 4&КBhM 4&КBhM 4&КBhM 4&КBhM 4&КBhM 4&КBhM 4&КBhM 4&КBhM 4&КBhM 4&КBhM 4&КBhM 4&КBhM 4&КBhM 4&КBhM 4&КBhM 4&КBhM 4&КBhM 4&КBhM 4&КBhM 4&КBhM 4&КBhM 4&Ѕ :ގ^8"h[k<NЍ3j-%%%#X>^8"h[k<NЍ3cm%7[ō2# H-MER{&,X^Fbb9.;s0ĸg:5142CzWw-/2d6�a#6$WIAL7|K=h#AEjbG BOxdV?F\9Sд,2x] _/qO}4-쵌؞'hFcfwB:3ˈFbpK^8ns�UcCS-׊2Dg[1<oTM�"}wq-M!챉)<4[qsc1Wpq >ԽgR?�أ-�>6v\;!FAeɋv-|=<qDз3bx]`}˾FǹEYpH:"2:'u}jE\~9x.IobQ!Z;7TT0;dydPpճ-X/d_]27D~1? HqQ] ( w2*^T!l5;DsPv-|=<qDз3bx]`[K<%"AЋéjtf>^\B-rp[8} >iޢ։nc) ._,WxYOl< pqmg NDEU%Gܪ8ODq/Q!%F�^nnw*n2"9Hџ(S2l p%[ _/qO}4-쵌؞'hFc&>Rq*ÆUGL,n.{q!Ÿs Cr>5 b5Wйz Ut؎|&%Syn?Q1G\\UF3yL~#:GDT$4s}!/m.k)5lREйr~DƗZZ _/qO}4-쵌؞'hFch_ŎqW+&PPPPPC CdM ~-c6'EmH"D$H"D$H"D$H"D$H"D$H"D$H"D$H"D$H"D$H"D$H"D$H"D$H"D$H"D$H"D$H"D$H"D$H"D$H"D$H"D$H"D$H"D$H" CdM ~-c6'u CdM ~-c6'u CdM ~-c6'u CdM ~-c6'莥>;$|U{3Q"B[ڻq:B}?QbD[GAu迆!{zx쉡oef;B6IM>tPk%m>g"S cuSE0K6_.gr[ǐWՒ rFgdH؞uREkR[χET3Yżn[˒3}o.,БCr2Z";ZZ\j�*\جr� y�".{Q}//sѩrFggri~a{zx쉡oef;B6\pH x D- $E̤?2th[C;�caߊ丈@M<&ndrHxoHy1nޤgDl@j Fo1gdLmcx8#=خϺ">7*N-x_zHndU.lVhh廂mtwJRČroh\u!kb`r Ĝ=1#Vs!F;ȗ]yw^8"h[k<NЍ-$EOAnrztgBGz$Kg[w'?D[ȋiLPT޹/X#D̸G'ӻY�hd{S�"+Kjj;|Ñiv%E66VR߂W)G.=Rtx!omz]|-$  CdM ~-c6'q>;⃢@ڂhQ]&'C976,WlXx2^�6�U=.F-׎XV冊1#ƢùnAȞ[*\b[Ϧ�r t[jj,aDA\r«}vywNTFu]c} vW7RBÅo] ۘ{7 T`wq;cX߷l/qO}4-쵌؞'hF/qO}4-쵌؞'hF/qO}4-쵌؞'hFc\Ct:Ct:Ct:Ct:Ct:Ct:Ct:Ct:Ct:Ct:Ct:Ct:Ct:Ct:Ct:Ct:Ct:Ct:Ct:Ct:Ct:Ct:5#ޗ;l/qO}4-쵌؞'hFcKPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP5gBB߮X͉vmv?A[> uC`_׽˅ [^zxoɃ� B߮X͉vmv?AHqs1|x h>'!F٘/H_*7q\[%#b8cCyؚ}w.[#:E1sz8E? C):/E:{1_nD$5Z>ȚvZlO#k -wCsxp /_ᯈp KN17Ё QYt[ 8 Uևz3OǏɊJz(f+XH/mЋwZ!Beslle1 pر~-Ig\1a ^Ee E>N¤^7Бr_xBL--$M_{zx쉡oef;B6ۉD^*_g]FԻ5�aFG?жYv8cXտA-|U0b^Qj]pS !Ò9P^D݀z+-~bQ1+S�Fijn޼d(7 " X׵.kť֕ݱd9bh^8"h[k<NЍ4tfc67Ps{qSXۜ阣Ħ&#$7]62VBt/27pR]3ɗ#w/iDbYϦ]q26;oD$8W9 ^es< .j~!㏲&]~_p7!㏲&]²R&L2dɓ&L2dɓ&L2dɓ&L2dɓ&L2dɓ&L2dɓ&L2dɓ&L2dɓ&L2dɓ&L2dɓ&L2dɓ&L2dɓ&L2dɓ&L2dɓ&L2dɓ&L2dɓ&L2dɓ&L2dɓ&L2dɓ&L2dɓ&L2dɓ&L2dɓ&L6B߮X͉vmBB߮X͉vmBB߮X͉vmBB߮X͉vmBB߮X͉vmBB߮X͉vkR!R!R!R!R!R!R!R!R!R!R!R!R!R!R!R!R!R!R!R!R!R!R!R!R!R!R!R!R!R!R!R!R!R!R!R!R!R!R!R!R!R!R!R!R!R!R!R!R!R!R!R!R!R!R!R!R!R!R!R!R!R!R!R!R!R!R!R!R!R!R!R!R!R!R!R!R!R!R!R!R!R!R!R!R!R!R!R!R!R!R!R!R[=<qDз3bx3U/3g/s9{^r3g/s9{^r3g/s9{^r3g/s9{^r3g/s9{^r3g/s9{^r3g/s9{^r3g/s9{^r3g/s9{^r3g/s9{^r3g/s9{^r3g/s9{^r3g/s9{^r3g/s9{^r3g/s9{^r3g/s9{^r3g/s9{^r3g/s9{^r3g/s9{^r3g/s9{^r3g/s9{^r3g/s9{^r3g/s9{^r3Uj'O}4-쵌؟c쉡oefdM ~-c6'"h[k?$B߮X͉&>ȚvZlO1Dз3b~Ռj\KKoOJֽfzc;ԌjsL/c'_Kڷ{܍B2>ȚvZlOtAj!}Ų"m~l׈RR/X~l1x^% ܨ${Uni'6nxAtdM ~-c6'T[e;wa%v^ƅkV2w d_A%,u{IOiWB_6!mp}hmm\? YF;LLn[ \%iHwTR% UhGޣ)hUz!wE�"G$a`[HBņ/XO'C%cƊ?JeQn|Ⱦ#>֮d"Db9ҬI Ì|> lR*$XlV7G}ʪXǭ7:ɮH|7 1W?YkjBQ՘TWE]hccׂ Éo?2LH9NgSיNe;SNe;SNe;SNe;SNe;SNe;SNe;SNe;SNe;SNe;SNe;SNe;SNe;SNe;SNe;SNe;SNe;SNe;SNe;SNe;SNe;SNe;SNe;SNe;SNe;SNe;SNe;SNe;SNe;SNe;SNe;TEB߮X͉vUV2ء1/5857ۿodZxq" |8u_qI"msER"O-8jD?#/Bӎx'Yi-id ! >[5 9yg.,3li&YX4]T^-[q:: =_sfQ ?CsVêbRWme[{me[{me[{me[{me[{me[{me[{me[{me[{me[{me[{me[{me[{me[{me[{me[{me[{me[{me[{me[{me[{me[{me[{me[{me[{me[{me[{me[{me[{me[{me ʉ!㏲&] ዁1!ڢ,HX8zOG3q;hh;qr\9|ŗ:5OFBo#(BˈџKe×l1Œ7Q"'o-\czd{\\t5-e",!`rq- ^Zˁ<DsP>�=H_K1 ' 8 ČFqrb}KOAV}#Ȧ nUO꿿!{zx쉡oef;B6 .;-ߋa{zx쉡oef;B6{zx쉡oef;B6{zx쉡oef;B6[~-舑I uP1Q�p#b(#Yl8'crOL/qO}4-쵌؞'hFcNz/|ե19RHpTR{&Ib ;̢Dþ*FN@&|mL;'s's=E- j8mL_2woBЭ yȅ#É[ZETʓ.N"!㏲&]sdψ!(jRe4WGƷ^6\* [UdO|1bTIkP^>!nm˓#-쯊U5-,Hr-јcո넍 #Ew̪#>G}_$_82fpq>m*Xlv5Ș{bÉbt$^Yٽ.޸EĽbTF0/bY7ϊ-֕L*"*v*KZH>%Wycl7C}-?4uhcT{Bϛ/��BB߮X͉vmvi"h1qgFq ;h[==hw'QjQ Du"#֑"j7Z=Gp}K}GLRE~:XޮD"&neO=ΉDj#Y-O�Ez^^D#D|1edz _[kx\Z%XoL+w*p}5^􈳸+ /=<qDз3bx]c<V;(X~+cn.l,zbxN[6+U8`ozIO􊐢Nt$ q[-[RʨZ>N6mglDL29'豢#R}цCGl0k1bBshv5؈ջt6ʣ`;ڜTmw; dz%&ޢǁ"9o[i[񨰜FUT r"-[,>Vn 7uѹ v$/qO}4-쵌؞'hF#$!㏲&]:!㏲&]Wz*BHI !$$BHI !$$BHI !$$BHI !$$BHI !$$BHI !$$BHI !$$BHI !$$BHI !$$BHI !$$BHI !$$BHI !$$BHI !$$BHI !$$BHI !$$BHI !$$BHI !$$BHI !$$BHI !$$BHI !$$BHI !$$BHI !$$BH\D}6B߮X͉vmv?A!JMI5&ԚRjMI5&ԚRjMI5&ԚRjMI5&ԚRjMI5&ԚRjMI5&ԚRjMI5&ԚRjMI5&ԚRjMI5&ԚRjMI5&ԚRjMI5&ԚRjMI5&ԚRjMI5&ԚRjMI5&ԚRjMI5&ԚRjMI5&ԚRjMI5&ԚRjMI5&ԚRjMI5&ԚRjMI5&ԚRjMI5&ԚRjMI5&ԚRjMIץ>ȚvZlO#k 1;*|OQ}j,5�ϖ{5AX.zE�0] 3cZ_G1_BHǺC*n_ːXDK[w^x- _xlUCBB߮X͉vmv?A+57,^uVdj.=D�\0ɑK&UИ= 3`�q ,_//H,EЀp3It5�Dojy~_E06ݣ!㏲&]~KV?˭ϿFK|LM r|IqbG3墢BCg<FxdwkR|n>_"%�Fh̗Gb�/qO}4-쵌؞'hFc:6Tzhb-àBB=D�T#}eg N9H(C,7 K֖"\KK:3ڂGbyw /9$#Y^,Zr!ÊȎrpн=<qDз3bx]i Dl>7z*ކdC_deDE V骮-[Ĉ׾!$#S# $+*Az#RBEV6"=.Oн=<qDз3bx]jܷz7!㏲&]²RWԙ2dɓ&L2dɓ&L2dɓ&L2dɓ&L2dɓ&L2dɓ&L2dɓ&L2dɓ&L2dɓ&L2dɓ&L2dɓ&L2dɓ&L2dɓ&L2dɓ&L2dɓ&L2dɓ&L2dɓ&L2dɓ&L2dɓ&L2dɓ&L2dɓ&L2dɓ&L2eȻa{zx쉡oef;B6{zx쉡oef;B6{zx쉡oef;B6{zx쉡oef;B6/^y^vaW�\$FE�cv$^#u3�{]W#8W">ȚvZlO#k$;ĂArO)9Hn5/yi xP1!ܪ"._WoZzkr/7x }�_rn'<b߂""U_?8^8"h[k<NЍ`O|Y.8u.]rh6$now&ųX2Z#_ j:* /j;\Q-OGfv~!=K;Dw[x/E�./1wz"Ecx)ު,Ktl/EҪ茞^!%uKtVFf;8gB'%>n-ܼu&/RZvk|XiGGW,[!GlyVoѺKpݡDoW/ T[D~Q޾g|KRN#lȘ㐾Q%a1>ȚvZlO#kKIAY �Aqخ#oC#^(:T"_7Z8}GpEŇB?n*¿/_vԖRDc݅&|Śټb}"A[2C{f�]|]u|2[8u6wb5<o/ж]Q&>�Rw&%y]K!h}|-n}iXQ:nqgFޞao\C^�o"'"O>ȚvZlO#k#{nc:m߈7 3d,)g!K՞ !$co l;T+HXvު$%O>2Emʮ#Gs~ObO0 #wr˕Pv{0}HNDcV#"\T0Xc=c`%$ AE?HK KJmؗ?R m8hoKNψ"9N%`-p#6Jnlo!ĵ» VovĽF@9G2}[[ЄFKc/qO}4-쵌؞'hF-$/qO}4-쵌؞'hF/qO}4-쵌؞'hFbj[a{zx쉡oef;B6o3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3t\H .M=<qDз3bx]o+#ط+!Vw=<qDз3bx]n*^^"'_z];qhk+U}o8bz;CU/- z9=O+)b<F^DMNvQKʞHv^Fg%跡r�g_3Er;ML~$b?kR92_v58gsE/s�!wQQ5#Fk^q�\؍ZȭIq/s5S�{ntf"y"5){܍K3u/W"!O<Gh=<qDз3bx]nHzjta_cWlX^:Ǎ^$s1C[,T>%K37ã":w^;UQkW=\TldpYp9SЃf{ՐԽcX-/:^C%θ{3|3S 4{{z"g-oSX#ӎԌȭV]fʞa1L0ox-!^FEjT6$dEͿ ~+~&rq6qo) c:*D_OjQz_u _<F*�#`+n"TGuAiN7^EZUWzO97ra_RXpU^25R4*,w"Cǂ x+\:zhm#TXKjb⽘WdƯkRk CdM ~-c6'Vm?zp.� ,Zj-(soK^_8'%A'tEuBتKswhLp�~-,;,HMHJrcIu̎|~dBw1Bz^3xgb=p39VG(jORe {p8kwD?2!f sqRqBԿphd SwQ{w:z"uf"EKW4]F6=<qDз3bx]iwaa[ųK*L+yńy#/pV9#|�նMDr(#oj/2*."v�_ڱ[TX,\+u׋4MTW2ܬgx-k V01 .'�Ȼ< a3Ĵ0cAXKࢫ-k}ƻȝ_Z_E_9[,(ZOys}clHvBj*Ɖwv'_nW: 2!R6K�B!Ո}%emE]y&D1GS?r�܃]رZܱwh%Kx-X>ȚvZlO#k �ҕ O=<qDз3bx]SXɓ&L2dɓ&L2dɓ&L2dɓ&L2dɓ&L2dɓ&L2dɓ&L2dɓ&L2dɓ&L2dɓ&L2dɓ&L2dɓ&L2dɓ&L2dɓ&L2dɓ&L2dɓ&L2dɓ&L2dɓ&L2dɓ&L2dɓ&L2dɓ&L2dɓ&L2dɓ. CdM ~-c6'2dɓ&L2dɓ&L2dɓ&L2dɓ&L2dɓ&L2dɓ&L2dɓ&L2dɓ&L2dɓ&L2dɓ&L2dɓ&L2dɓ&L2dɓ&L2dɓ&L2dɓ&L2dɓ&L2dɓ&L2dɓ&L2dɓ&L2dɓ&L2dɓ&L2dɓ&L2d!{zx쉡oef;B6{zx쉡oef;B6{zx쉡oef;B6{zx쉡oef;B6{zx쉡oef;B6{zx쉡oef;B6ɓ&L2dɓ&L2dɓ&L2dɓ&L2dɓ&L2dɓ&L2dɓ&L2dɓ&L2dɓ&L2dɓ&L2dɓ&L2dɓ&L2dɓ&L2dɓ&L2dɓ&L2dɓ&L2dɓ&L2dɓ&L2dɓ&L2dɓ&L2dɓ&L2dɓ&L2dɓ&L2d^8"h[k<Wzц99999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999]B߮X͉&>ȚvZlO1Dз3b~I&]L}4-쵌؟c쉡oefdM ~-c6'"h[k?$B߮X͉&>ȚvZlO1Dз3b~I&]L}4-쵌؟c쉡oefdM ~-c6'"h[k?$B߮X͉&>ȚvZlO1Dз3b~I&]L}4-쵌؟c쉡oefdM ~-c6'"h[k?$B߮X͉&>ȚvZlO1Dз3b~I&]L}4-쵌؟c쉡oefdM ~-c6'"h[k?$B߮X͉&>ȚvZlO1Dз3b Э Э Э Э Э Э Э Э Э Э Э Э Э Э Э Э Э Э Э Э Э Э Э Э Э Э Э Э Э Э Э Э Э Э Э Э Э Э Э Э Э Э Э Э Э Э Э Э Э Э Э Э Э Э Э Э Э Э Э Э Э Э Э Э Э Э Э Э Э Э Э Э Э Э Э Э Э Э Э Э Э Э Э Э Э Э Э Э Э Э Э Э Э Э Э Э Э Э "h[k]/+՜T[u"h[k6&]bh[kIyaC= 3C= 3C= 3C= 3C= 3C= 3C= 3BŎOr$H"D$H"D$H"D$H"Cq5My"D$H"D$H"D$H"DWpzmI$H"D$H"D$H"D$Hq6Dз3'O{ީ7]==6;�GB߮Xh>)]h8{/z F?F0Esb^�l'~{zlw:栏|My/~?Y/A79$bGB߮Xh>)DcV? z$w*ފDAr/[mׂo"YjE1r"z[$Dm*K�Ƚk{Xv^r�BkuRkR˯觸~Y~ 7Fgjs?ȿ\q"5)fԹeD_p>[S>�(rܘ1=R>ȚvZcDOwYouaz |1|Kk0!QOѳ{V$eI⯿ܥkHLSlVG|[H6f�ٛZ5ޗiW-gTr([VЫR�_OqM'ō:$)ec)KLL^=`ǬHg\>e,jVzVZ%wBn'^%4I6g?^ԽL(MۑHlG"1nclz=fԏ&]=|Sݗpq\Xp#T8Ҏ"NQOуp5\W <(| ĩ njbԶ(eqw-0!b\?5΅E,[?E==6; 趈xxؖXx]yemUK?'*;alWXb'Ae Ѓ,{Ծǃ�5kH� q"p,o쉡oeg4Oj~yif֘6o K�BzC'nUKV{Zo7FnD�8^^9^o7?}#/\\9f;<OD1Zm?0 Ga҄0Yx/{s}11a⾣ְ7jB CnQR$K%cO~?ZLw`[A|8Vu'r8�,+,<XQnt6}W꿩dM ~-c?{TF?ߧ~#:V:J+ax[JĒ~aĒ'B߮Xh>*r'HTHTHTHTHTHTHTHTHTHTHTHTHTHTH'!R!R!R!R!R!R!R!R!R!R!R!R!R!R 2Hf%HTHTHTHTHTHTHTHTHTHTHTHTHTHTHpR>ȚvZcDOT;(q8r9GQ(q8r9GQ(q8r9GQ(q8rŲ;qޛۉW%K̵2S-L2S-L2S-L2S-L2S-L2S-L2S-Lb/ˠCLjS-L2S-L2S-L2S-L2S-L2S-L2S-L2S-FD|;j eZjeZjeZjeZjeZjeZjeZjeV#p߲&]bh[k6&]I= 5P3"ާ(r(r(r(r(r(r(r(r(r(r(r(r(r(r(r(r(r(r(r(r(r(r(r(r(r(r(r(r(r(r(r(r(r(r(r(r(r(r(r(r(r(r(r(r(r(r(r(r(r(r(r(r(r(r(r(r(r(r(r(r(r(r(r(r(r(r(r(r(r(r(r(r(r(r(r(r(r(r(r(r(r(r(r(r(r(r(r(r(r(r(r(r(r(r(r(r(r(r(r(r(r(r(D [?�,�������1a!Q Aqp0`@P��?!cd(Z|EUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUnT\HCWeҺp2DRD>CI$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$Ir/r J*=*,9ҰꬺˬˬˬˬˬˬˬˬˬˬˬˬˬˬˬˬˬˬˬˬˬˬˬˬˬˬˬˬˬˬˬˬˬˬˬˬˬˬˬˬˬˬˬˬˬˬˬˬˬˬˬˬˬˬˬˬˬˬˬˬˬˬˬˬˬˬˬˬˬˬˬˬˬˬˬˬˬˬˬˬˬˬˬˬˬˬˬˬˬˬˬˬˬˬˬˬˬcGV>N =`{_= 3aG>b>E�����������������������88نөL Jı[5If*SLD1>t`AI'�\c'"\#��VVAf~84c���������������#yTK[ *P4eJ>'Bb'!+b La1'j$̠/* Nlg][1c$h'⊪UDJ+-+I`dʀ( n,r7Jk+\a2U"O."kT嚄V Dl A, VhQ!K������������������bڱJa1Y.A2RD0F(Ln^Û}gvX~pİPI'8@cмN!LS N ¬adjfdZ3"Gaq&\0,F,5$!BN$4$4�Z"ASq4J#1Vr ,Oc }/r1ӀB^A)L-6$t¤''Z-1DhL2dɓ&L2dɓ&L2dɓ&L2dɓ&L2dɓ&L2dɓ&L2dɓ&L2dɓ&L2dɓ&L2dɓ&L2dɓ&L2dɓ&L2dɓ&L2dɓ&L2dɓ&L2dɓ&L2dɓ&Lh|NCB b!bx:L$PS`X|; IBIt1}Fԡ_/Mr8-O`-6B $Fe'AAgs3e[p?c� 1$J2 Q�1A26 g?b3RC$VBLpU�`D&>����������������] ij*2ynB}$? ϸ)IGw"�;epPKt$!=b3Es1GM!x"L ȌɌr"?T)Gv%"ڹ%P<@OY)K!hNZGÀM&xbU B+GAU8f^KH""Ȉ' 虧B}-9NS9NS9NS9NS9NS9NS9NS9NS9NS9NS9NS9NS9NS9NS9NS9NS9NS9NS9NS9NS9NS9NS9NS9NS9NS9NS9NS9NS9NS9NS9NS9NS9NS9NS9NS9NS&C!70@ۄIP4Fܱ&0>h(k0 CyT&IdD`I=1!̵la% hl%a,F2=F%a``I(#gKD|- "SX8HBI- HĬ,k-dBA <q/���������������� ,x^XXf2ۢ�6mmmm3Y$ŘO"mmmmض-bض-bض-bض-bض-bض-bض-bض-bض-bض-bض-bض-bض-bض-bض-mmmmmmmmX x�r@q0 nGpypypypypypypypypypypypypypypypypypypypypypypypypypypypypypypypypypypypypypypypypypypypypypypypypypypy�fm,=APz=APz=APz=APz=APz=APz=APz=APz=APz=APz=APz=APz=APz=APz=APz=APz=APz=APz=APz=APz=APz=APz=APz=APz=APz=APz:[Ozm4u@]D{.k=O)?I$I$I$I$I$I$I$I$I$I$I$H`[J�I$I$I$I$I$I$I((ؖ�I$I$I$I$I$I$4\y̞d'<O2y̞d'<O2y̞d'<O2y̞d'<O2y̞d'<O2y̞d'<O2y̞d'<O2y̞d'<O2y̞d'<O2y̞d'<O2y̞d'<O2y̞dC#(d'<O2y̞d'<O2y̞d'<O2y̞d'<O2y̞d'<O2y̞d'<O2y̞d'd̞d'<O2y̞d'<O2y̞d'<O2y̞d'<O2y̞d'<O2y̞d'<O10)Pۨ}t;*1`4=S }ɢ<�qʼn*:l^aiD*xlc3A]?d!P¨/ +�O^}+&EON"ԑbSEU8+68�EȔ id?� ?jIY3E.( s ( 1])x[wWu+-pf1 ʞ-$&J|MgH1URoU٤#r4-'&Q<i gjF$"Y$!ۑxIԞpVp(R DRJ;Ȭ00@Z61`pMSrx*̀'FfኝTZFZT~)o BI?]B6rS&Q2ϑCv۩=4x k8XIet PwC},FzHclJ10[5s& f1$$,cu�Ykf'Al{АvFK!r$�La\JQ摏U*(!Aq> }8sZ{mۨ}t;gCH6HsEd/}P40ze)AK+bj".6st4Y nqKVn } y'uz Q:jV*cЉT9dE`f<,n]d3s{GSc*xj9ȫ\S8h%dKÑ9+_Uub)2 ͞-ΘR7d2 6Odž.*[bYŸ<GXr'$eȁ :KИE")/j2/vjrQ|~B6p{,TĝZv!ncI2@]AfL@!e[8bMn&\?W!Ą*_]p1D\\[S{8>,0RB@HB0KmgWTE<pclUQUr%#iC.Dd0b̩++Q}!P@a B"%PxIL-,1D7NޢGK[f�ơ!Jf Bw]&dc<@5d؅8Sz3Sx�Cq]JuGsX5 0/ܱ &Yc&*'quB-$Ycqe;H؞�`m2i 6|JQCi򤒖!/fMg5ѧODJS8|Khۜ$< !ԧ&chS<eNFaI?(+t^s! }0h;H/ęk7jKI)x Qw `'Z b7 R!fGRiF!S::sDzrEzHnHHX4&e[+v_ RUlLx�taeD勄XFo;4$L`p&7q14T@qكL=ZЮ0Vz )I2j 1s9.ej Bb޺)kыdZ ).&7q%x>л!C aۉ%glGTȐ$RxN fk0IQ3$5Kc5?8LITxK I5AȪǣ 7jȌ^ 1?<چad3ҟ rS4ɉ I(�R]BtHlb,,+;Hj)r&" jED.IƒL) E2o.bb0/vdԈ�GvqMv OOR.!5V :F)Cv" s>ƮFT59�Bj}Vଏzc Di&x]ِXC![fyF,! @TF!2 5Q=,ҿVCG V�(US!R9-NJhQ*xe.Σk)'P%5 ʫBTG>T*!Xf%Zc2d&3`x Lq? *LO@.S LDQqwKJRxHKun drN n yTQI" :l,C6rC%$BZP-3."!8!NL$!WճBuV#t@lp\ \[wx&A|9B(vu863p$LB Ѕ!2<8s'H uN/1lQضxbqbrD1 LZEQ\SS_cDxZBB"FbkX8bז0db'*q$ޅ{̈Ɗ"rll9*:`ΐ!82I" ӣ>J @J(K<HFޚ4HDO&9$CC 4E D cKSCu*I,L�HlL MQFfT?j#1Hb$`,0أn^}K$I$I$I$I$I$I$I$I$I$nA"OI$oן$I$I$I$I$ 31Ce)MxnI@^B-3D+plQ`�dI$I$I$I$$ nM+rp ]4% k,ú- MgM |�������������������������������������������������P}D{ +!R6U1tg$! YnrcVRa4! 4%';;Yn !8%&pOu""�9ya5TMgFTPe2@<mL! xN KҨU.2&C 'q5"l"V- $@% J'bS"pBSG � $)=利9,Yq ԑRɋm , NP dVᅪ< LCRMSfPhB Fd">["٨}Eo@ԈJ٦S} N @ȈlK~^|\vdH+Ql-W1(_Q5&",;&�qOHbsJ숣N"6415%xṋ9a=NszxZQNʒDqMxzI=18o#G80.qe-,*ݚV�օ3l2K,GL NѬŪs Ǧ!d0R8?W$BϦE&AN"JdyoeѤ]s6 $0N,by|&%9b<r0_ba63!a+C37o@] nmLO1,/bT [^$TH&�U55Y(NF\*@`"-i4 xA^AL>,ɥla((JcTSHLZs$buqĉ\Qd(g)Iԕ$hA~$rgנ Xȧ#8ؔ_ltD3qe(!İU 8ԘJI[�kvj&xQ[Ho.QsYU55Y(=S[Q5"<#55Y(=S[Q5Š#55Y(Rڡ8N,HmbNVHcͰ�qk9HJSvR81rRB 's[ƥ őFxm&jE(S}S[Q5ŠBP·b:5CDg""C͸:V 1)!LzXpBSf$+FimƖ/ *t$SX%0V-%!sAҐ1 +4H v{CNN L55!Q!$<D] �6!t! Ց5hU hE_55Y(UR#gpԨHI-r :"4^XiC 8pG%-2dv>H w6!U(DB{Iɇ�xpSAPe>&n,cb*} E- a<8!<${:/kn4@f(FگE/6̾+-"�g'bF}pP2Շ匰>�<ևfT_ XeT7TMg;ig\{#jKKၘO0 8xň7I,&BS"qhyw~Ldr] 51^߀H{^SmAݥ^*MNRJXl6q-PrPFK#hEoYQ<ʲN*ƒQ4)pcGj5\l!Y0[Lx#i  FXClBu2QP".K.K.K.K.K.K.K.K.K.K.K.K.K.K.K.K.K.K.K.K.K.K.K.K.K.K.K.K.K.K.K0w4ꦷfk=uUrO_B 0pL#˝DL5'`E7dYN8&XM� Dt̔W 9Ģ ٍBSNт5i,Ts=K'#{DMB ט#8k>�ez^  S+`1iϘbAsF^+% QdUƢ}sMުkvj&xQ[wX5^�v7z٨}Em`{uw4ꦷfk=uUiwݚV W]sMުkvj&xQ[wX5^�v7z٨}Em`{e3!Ij>!& MbJI(Gof<�A4<کÌ~;nS[Q5Šۺ*S/J1DYGHnHEGi2! }?-Ѣ1đp+j8 9%=Hsf%SܑU !iIg &e ˭X'SDZ+ux9,6/h"|R} PĞ,Lrr{N曽TMgjȱbYAXI? lAKX{]e\{"5g2eFU\6 %)\"RʚJK1OX_ģZ"&%҂2#D&=L[b5$ y¬D6 BiMnD{ +nkX3),&*1F!ɀ4@Y%a 1Ը8G _{<P8 /~4 q}?t8OcHP5,-ј\D7#Zq<0~N'A l!&958; M'?7z٨}Em`{$9H-Ɯȏ%BR!!$%aWI B('24[NACF" 0Ԩx$KE!D!.ĥ/!E%cbZ7uO"BI!蟡+O!"PlKF !ĉDaA9sMުkvj&xQ[wX5^�v7z٨}Em`{[0- , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , V㷴iMnD{ +nhAB?������������������������������������������������������������������������������������UUI]sMުkvj&xQ[wX5^Cʆ3%1Hj2OoiwݚV WWD$郈&/t9H,V #<B™'T##6H1 hӱ"T2! `b>51t lH| zIWKHb ](4O,RYL2H`L>uMOoiwݚV W&^B9S2&emrD!BX$8vr7I&+fB x E7p!\qTP-ma8<i}(]%' `w>ŋbyFi;nS[Q5Šۺ>b=!DIQg15|,Q&L!H~1kYF<rJ[qєFr;X9"lNF7%E-m: ) (R8 ,* F>bW6#5MOoiwݚV W"zBJ:!xt$ݣiqTm8!3J ETc7Z+f!J$OƸ IĉrFN :H"tj+ v5`"$B/>~iD0p~p+J?MNj< )lj6ӹU55Y(}%I$y"1Fq IC ԗ4"-Pݫ-3$*�CfC+>RU7.c-,C8EBBIC.&ST$HX#D @UqA9qcR;4L"(%-ABpw(cIi;nS[Q5Šۺ ]at].Kt].Kt].Kt].Kt].Kt].Kt].Kt].Kt].Kt].Kt].Kt].Kt].Kt].Kt].Kt].Kt].Kt].Kt].Kt].Kt].Kt]#Xǭs<F#g؜-ӹU55Y(}ľ5?������������������������������������������������������������������J67z٨}Em`{uw4ꦷfk=uUiwݚV W]sMުkvj&xQ[wX5^"XlыS~9]LYbp絥GLWAƶer i?;N曽TMgj&\4.ɍ`O'hOwBKpa+)${81zYviRPJ䐿`lbO,,ƷxЙRWkV[dh#2J^H e- ۮ^,dya“Gr*7BKQq?v7z٨}Em`{5NtNzBbbA&xe8sEktIVMQÊvD#SRF`gŏ BGƏ٥Ss:)P C4nfs<^FR2~ 1MY^ 7ض֓(&+.LL=x'1lH;5! `Fd+"C+)3iMnD{ +nxwBSF"0&wcǎ.,J #K ZZX $1@yy0yxcȹqֲRaL%Lq(3HY .f|N8UAD\XyH1a lEH$6%<ӹU55Y(}s0LQ%Ou$BR"q"xQBMKc x5rG6dDz~ ̤Sd?\38ι߃<yں^Є͙)4RW"z ;.|-+2#2�x,X%$x5zQ|QW[;N曽TMgj:;nS[Q5ŠۺiMnD{ +nd1#ؔdDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDE$ĉu;nS[Q5Šۺ*3$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I&4T[{N曽TMgjC &uXe]X<HMq[y}-ӹU55Y(}z (O4t3G"%7D2b(ANe4H2ԔpXhCvt6DClC@C^)sՀ0\N&8T [{N曽TMgj9]x|R"AOǜo?}$%#fISׄ�qaĹb, _@6+d�u<V$c>528c|c,n R_*-sMުkvj&xQ[wX5^֘`";]B&# 2: 캱 �WkliIh7 O. JYKn#qh�Ѩv.Bp!59㍂BPb|ƣA<P\ ^(C9UJKoiwݚV WxWӥL)D ,c!pYH&XT!q'7P=Xe3?%2C_r7^!h)DB]ϔW�5cR߆^Yoۙ*8xJKoiwݚV WZV `X, `X, `X, `X, `X, `X, `X, `X, `X, `X, `X, `X, `X, `X, `X, `X, `X, `X, `X, `X, `X, `X, ˁKoiwݚV WƬ������������������������������������������������������������������,7z٨}Em`{uw4ꦷfk=uUiwݚV W]sMުkvj&xQ[wX5^�v7z٨}Em`{uw4ꦷfk=u`ug=x{=x{=x{=x{=x{=x{=x{=x{=x{=x{=x{=x{=x{=x{=x{=x{=x{=x{=x{=x{=x{=x{=x{0qGsMުkvj&xQ[u*ޏc\:R)JR)JR)JR)JR)JR)JR)JR)JR)JR)JR)JR)JR)JR)JR)JR)JR)JR)JR)JR)JR)JR)JR)JRHN,x)#z٨}EoݚV٨}EoݚV٨}EoݚV٨}Eo守Ds&s?^Tpptx$hLp=f/쬘𐺞r.~uMnD{ +i[^ɏX$UNSaCU[59J8'Kr;&CGXnZuBVr& O5;s?MnD{ +nE$Ȇq<,`m<d c/ CG!C2<c6%<ĶBQ5&MWxLr1Sdo f1@e30Wc,oh'UP '5v*cՐ�}IKO's4xbc%#Euai,*`S+49N36$�nbPEd2'MgMДPͪ@g;h_%<,xXcDž <,xXcDž <,xXcDž <,xXcDž <,xXcDž <,xXcDž <,xXcDž <,xXcDž <,xXcDž <,xXcDž <,xXcDž <,xXcDž <,xXcDž <,xXcDž <,xXcDž <,,DɓTMgJ`er MZ#Ӹ `MޑARbG&(c8WAA8۴4q ?W1ENC$7p8؉3Gd+IdeFbf#1fBLH\E8CMB8xCL(x$ȗv% KbVO0|I$2DJ'>,:WDIF pD+I75Sz-ZҠw$r`nP&O����������������������������������������������������������������������������Y 曽TMgj.\U`jH+!$C .!iTV?vJr:gr* HH{^O%Hwv>ThcǤ MJI$'0!ִV%K :[]@ESDDSf\A$Ux Z6ETP9)S|Y K41D6GdH0,- 1�%ԇ+f�;N曽TMgj�dmQoiwݚV W]sMުkvj&xQ[wX5^�v7z٨}Em`{іW0;4b!eS}Ĭn7'+jhbM1$g &{mIELROiwݚV WY*2PcXҋ1NW`KsF2z.dH, EYYk3b{5%DicMRo$*D!&maL#2÷Ddq&9,,kD!cX$NRSq>k aaG\ى᪫ e4 a7qiMnD{ +nn^\!MM4Vh< 8L'<Exs9L{n#ĠR 5r,G^X�75E^ك\?DY`Ñ0,P$ՍHI>(Bp p4(: #$?},\X鰑I\Jؒo)RV1 X.(TJ,Ǘ*ҟ�v7z٨}Em`{6,+K�f*X$lxN"N%^j_dUKkT_kI1|_YXNAaL%?ER%4%Àss* =3pp V/ %: j%R1Q�&MFMY>=?ؽ!#IHQKϨw4ꦷfk=uU}tP\Wcr⌁ %đSb#�kИ [| nV8y9@QT}f9rV7_ *ˎ.jvLf4y,ؐJ,tQ Jʰ$`LV!r֭PSL 3LcE](&$p]$P-dx"KF%086+a>eAEF۠`/;N曽TMgj�Gg'iwݚV W]sMުkvj&xQ[wX5^8 O8uD[{N曽TMgjv3UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUbl"BӹU55Y(}O1p|8su& (A夡A{B 4T"#@5DfDʫ{�Hz\^|dLL!MO-sMުkvj&xQ[wX5^xLlZH􎤈*ECs\uJ2$ 54wb]!^6RV,!0Q.Œ8pȳE ]{+d3P]<ħ$d2f[-sMުkvj&xQ[wX5^J/xqY9UJ�YD1Zu+Dv!A:x$G9vӨW{{% w4W77z٨}Em`{[==))1QB Q^&dMׄ.9BVCELRɍ6Z&9d&<&SkF["(Ąָؑ5@iMnD{ +np;"0xJCIeH9 $ J|ə"d`) K\cQ1eDlh_(% K-sMުkvj&xQ[wX5^AhD%,dK"YȖD%,dK"YȖD%,dK"YȖD%,dK"YȖD%,dK"YȖD%,dK"YȖD%,dK"YȖD%,dK"YȖD%,dK"YȖD%,dK"YȖD%,dK"YȖD%,dK"YȖD%,dK"YȖD%,dK"YȖD%,dK"YȖD%,dK"YȖD%,dK"YȖD%,dK"YȖD%,dK"YȖD%,dK"YȖD%,dK"YȖD%,dK"YȖD [{N曽TMgj503*$mmmmmmmmmmmmmmmmmmmmmm\{N曽TMgj:;nS[Q5ŠۺiMnD{ +nӹU55Y(}s8qF';Ydhw?Tx=�Q?jf$qbI]tYdl_7z٨}Em`{FQ)'Hʦb;XEm;tJ>>ھQMO1bi)U YpS@E!s ϸPwH4�7z٨}Em`{[141] !B3:8ɀq@;%]"qf cdQ)!yP'IY:Zz4rN$=]hI` Ŗ8&cS0XChCr,iqqo)r%"ܶB;G9b3\ 5I##RIL ;-`[]-#՟lpz! vk)aT+jSDIchQ�T�7z٨}Em`{ɍf *WD*܏DIO0\3wbJ0b,C,�)!e1RO8P}?4dX!t#p&r^,CJ3Ch0H[zJ3'"M p%0͊"I(8OeƓdcL>:Uj &FjI-#4"<{uw4ꦷfk=uU﵏q`N$ % !.q�U0qűDҘs�I 뜢h72F('IMu "]DK|BV5[ea-92c,2lOt1f8X SPpb@/N<DN!S ʖN4=2! <*[;%^g1\!Z$O\DaD܎lDwjYC億>l|¥CE"9Ce aXӹU55Y(P+HNӹU55Y(N曽TMgj&6sRK5.j\ԹsRK5.j\ԹsRK5.j\ԹsRK5.j\ԹsRK5.j\ԹsRK5.j\ԹsRK5.j\ԹsRK5.j\ԹsRK5.j\ԹsRK5.j\ԹsRK5.j\ԹsRK5.j\ԹsRK5.j\ԹsRK5.j\ԹsRK5.j\ԹsRK5.j\ԹsRK5.j\ԹsRK5.j\ԹsRK5.j\ԹsRK5.j\ԹsRK5.j\ԹsRK5.j\ԹsR{YIOӹU55Y(}q~_~_~_~_~_~_~_~_~_~_~_~_~_~_~_~_~_~_~_~_~_~_~_~_~_~_~_~_~_~_~_~_~_~_~_~_~_~_~_~_~_~_~_~_8ыqR[{N曽TMgj�x`W?fI-sMުkvj&xQ[wX5^4lEưI^Wʫk(Xm%6!GН* rĀǩ(/mrJ&S%eW$niaI;A;^CSCrbsl8ɆGmC[ Lͧe܃@5ΌG SNr ٷ< bnC(sR_ _4 Oy@\,:Ži AǜAIDJlhApjwTbpJ\6T+h�4Rw4ꦷfk=uUAf'qrA\LjQ8u?a\IpWi%>F#PzVl3Tۓv81NL㉎n^DX(e O (ryh~4q8WT;M#IM6BG:-[ 5L #qJt0 ]K0gsk"x#!#)1j>f1`4<3YκD.?A(LddqQx6"ځ!J'- = OdM g 2@-qQZC8`q"r΁KoiwݚV WzƩOW#Tٞs!,�arœYA(4?)vG*jw"B " rɮb늋Xm/&1R2,܀Ѱ-ؒc"Va_ȑ(T_hD BK4bQX!jO v6(]dG-DLb(My!.8`}I9pQco86`v_ˀ$jX5񹔿7z٨}Em`{K# }n\EQl̕$K1_9 &26%U&L2! $L;L}^H7ġAbPDmWtUðZ;2Lpe6�WR\17LJbnqN,Ж[KED\g㍓-c{o6kp⠠~S"du4Ut*%M<Abf԰d n g@iMnD{ +n�Kŷ [{N曽TMgj9 D`X`X`X`X`X`X`X`X`X`X`X`X`X`X`X`X`X`X`X`X`X`X`X`X`X`X`X`X`X`X`X`X`X`X`X`X`X`X`X`X`X`X`X`X\,B{{N曽TMgjp\p\p\p\p\p\p\p\p\p\p\p\p\p\p\p\p\p\p\p\p\p\p\p\p\p\p\p\p\p\p\p\p\p\p\p\p\p\p\p\p\p\p\p\p7uooiwݚV W]sMުkvj&xQ[wX5^�v7z٨}Em`{uw4ꦷfk=uUiwݚV W]sMުkvj&xQ[wXic-:KNRөiԴZu-:KNRөiԴZu-:KNRөiԴZu-:KNRөiԴZu-:KNRөiԴZu-:KNRөiԴZu-:KNRөiԴZu-:KNRөiԴZu-:KNRөiԴZu-:KNRөiԴZu-:KNRөiԴZu-:KNRөiԴZu-:KNRөiԴZu-:KNRөiԴZu-:KNRөiԴZu-:KNRөiԴZu-:KNRөiԴZu-:KNRөiԴZu-:KNRөiԴZu-:KNRөiԴZu-:KNRөiԴZu-:KNRөiԴZu-:KNRөiԴZu-:xiMnD{ +nSA.K.K.K.K.K.K.K.K.K.K.K.K.K.K.K.K.K.K.K.K.K.K.K.K.K.K.K.K.K.K.K.K.K.K.K.K.K.K.K.K.K.K.K.K.K.KMުkvj&xQ[z^dy%K̗/2^dy%K̗/2^dy%K̗/2^dy%K̗/2^dy%K̗/2^dy%K̗/2^dy%K̗/2^dy%K̗/2^dy%K̗/2^dy%K̗/2^dy%K̗/2^dy%K̗/2^dy%K̗/2^dy%K̗/2^dy%K̗/2^dy%K̗/2^dy%K̗/2^dy%K̗/2^dy%K̗/2^dy%K̗/2^dy%K̗/2^dy%K̗/2^dy%K̗/2^dyTMgMnD{ +|TMgMnD{ +|TMgMnD{ +|TMgMnD{ +|TMgMnD{ +|TMgMnD{ +|TMgMnD{ +|TMgMnD{ +|TMgMnD{ +|TMgMnD{ +|TMgMnD{ +|TMgMnD{ +|TMgMnD{ +|TMgMnD{ +|TMgMnD{ +|TMgMnD{ +|TMgMnD{ |ǔ٨}aQ3KR}Ծ_u/KR}Ծ_u/KR}Ծ_u/KR}Ծ_u/KR}Ծ_u/KR}Ծ_u/KR}Ծ_u/KR}Ծ_u/KR}Ծ_u/KR}Ծ_u/KR}Ծ_u/KR}Ծ_u/KR}Ծ_u/KR}Ծ_u/KR}Ծ_u/KR}Ծ_u/KR}Ծ_u/KR}Ծ_u/KR}Ծ_u/KR}Ծ_u/KR}Ծ_u/KR}Ծ_u/KR}Ծ_u/KR}Ծ_u/KR}Ծ5!uvuY򀺉@]D{�صCO7O7O7O7O7O7O7O7O7O7O7O7O7O7LQ>$-“@?����������QAs1�����������b$sWi_����������#3M5Y/DbY98sq98sq98sq98 iw;Op\. p\. p\. p\yN柶1aep\. p\. p\. pTCﶘ\. p\. p\. p\. 55Y/額 M.YB` Rɓfq5OD˔%iGqW;g{#]@!%DUSHpAr0̢V Xqjݚ� dk}^Is+isb20f) u#٘2GӳC 8$Ȅ,I0_&&$u!2K"1r6'(j/f'sO@9¡ky@LO)sR|x[#Yh4-ﶙWxLىMeb$D2ݚ� dk}KJ 0!3S/# %2=;4;u8EJ1;+m %=G,ٍ.M8nɥP18Nԓg8w4�9w0T1O^,.!,і(p; TrûDR h'LI!u<2 8V``g9(9XVS[Q5�"lo $ ?ٞ 18]?OclD;'g;6 ^CU|q FДWy \a"nj($6 (� �Iq uBll Fřao C*RX;ihh11t$g[~ڸ1E(Jfk=�Eu4Fd# Iet?Njt믂)>r8e?"l#]Q7D-'՜� '!^0hh?M 82'|h\) NR ETd2iL38 1%x:]kOjiI!p+/TMgH[#[vhwT�ݢw4�7%")A8rUlz1)iL�J-YkU55Y/Ȁp7\QK[ԷoRޥKz-[ԷoRޥKz-[ԷoRޥKz-[ԷoQECΔdS{=x{=x{=x{r`x{=x{=x{=x{ꃻڴ%r_{=x{=x{=x{Kvffk=�Eb[B&e�tI$I$I$H▭-eG#H$~?IG#H$~?IG#H$~?IG#H%3 ~ige,vV~?IG#H$~?IG#H$~?IG#H$~?ICJ,M(H$~?IG#H$~?IG#H$~?IG#H$~?Ie\t5Y򀺉@]D{'hM����������������������������������������������������������������������������|0a;NYXi>MmmmmmmmmmmmmmmmmmmmmmmmmmdĠ1F� �����0}}}}}}}}}}}}}}}}}}}}}}}}vt2,,,,,,,,,,,,,,,,,,,,,,,,0=ǟ/K͵/u2TӜ0 0�����������������������C 0 0 0 0 0 0 0 �?g�Š�2<m+vq@���������������������������������������������!f� w'h(ow'������<<<<<<<<<<<<<<<>p��~<<<<<<<?���������������������������������������������������������������������������������������������������_���������������������������������������������������������������������������C04E M4M4 3M$3M4M4M$sM4M7qC4 M4<M4MLc <p0 3H M4M5麩<RAA?QB E�37}c@#= 4 mqh�JJz[�E 6 L{)'|J�TU['H02qC=S,+ ?P˝nLPxv:H{Eo�AAAAAAAAAAAA AAAAAN(AB�QAAAAE忯��������������������������_>a|rۯ�������������������������?��������������������������\omSSfjbtN�������������������������~[���������������������������z-v/-㯴c�ӌ��������������������������oO�������������������������������������������������������������������������忯�������������������������������������������������������������������������?��ǝrŞ0]������������������������������������������������~[�lZ!_V^0/7IM4M4M4M4M4M4M4M4M4M4M4M4M4M4M4M�o�[?|6?8m0����������������������������������������������/�忯�o��������������������������������������������������������������������?�ջ�����������������������������������������������������������������~[��VV~ުr�˭m���������������������������������������������������� �o�Z{n`m ' ����������������������������������������������������/�忯�k�|o{~�����������������������������������������������������?�Փ,,,,,,,,,,,,,,,,,,,,,lqǯ�~[��V[7 ,<<<<<<<<<<<<<<<<8 �o�Ynk<<<<<<<<<<<<<<<<(T/�忯�eEȹp|<<<<<<<<<<<<<<<<gms?�՞ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 �~[��V��������������������������������������������������������������������� �o�[<��y����_�������������������������������������������������������/�忯�o[!ji36-/BWs���������������������������������������������������?�ըy Ҟ5;d����������������������������������������������������~[��V��������������������������������������������������������������������� �o�Xp������������������������������������������������������������������#/�忯�a/Q}Ϝ&6������������������������������������������������������?�Քb1}](T9S������������������������������������������������������~[��V^ 2y<<<<<<<<<<<<<<<<<<? �o�X������������������������������������������������������������������/�忯�o��������������������������������������������������������������������?�տ���������������������������������������������������������������������~[��aAAAAAAAAAAAAAAAAAAAAAAA �o��������������������������������������������������������������������������忯�������������������������������������������������������������������������?�������������������������������������������������������������������������~[���3?<?|3m^{<7{Ͽ������������������������������������������������o�U=mkфM_W}}}}}}}}}}}}}}}�忯�o꒼�r-6?=�O���������������������������������������������?�տ���������������������������������������������������������������������~[��V;�s|{,֛k|������������������������������������������������ �o�Z"0\ H[̰;$;DU_����������������������������������������������/�忯�k\oOϬlqí.����������������������������������������������?�ձqqqqqqqqqqqqqqqqqqqqqq�~[��VpF bK p�S8888888888888888888 �o�YO5~��������������������������������������������������������/�忯�dT-=?���������������������������������������������������������?�՚}}}}}}}}}}}}}}}}}}}}}}�~[��V��������������������������������������������������������������������� �o�[ �����������������������������������������������������������/�忯�bcvryKNxL`ϯ��������������������������������������������?�կz%�fYC;GsW,���������������������������������������������~[��V������������������������������������������������������������������ �o�Z3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0(/�忯�`2 z-=,o8^ǭ������������������������������������������?�Հ*=W5K"w⫮J1n�������������������������������������������~[��VlߌO|{L{-������������������������������������������? �o�Z}}}}}}}}}}}}}}}}}}}}}}K/�忯�o��������������������������������������������������������������������?�տ���������������������������������������������������������������������~[��\}}}}}}}}}}}}}}}}}}}}}}} �o�Oqqqqqqqqqqqqqqqqqqqqqqq�忯�������������������������������������������������������������������������?�������������������������������������������������������������������������~[��������������������������������������������������������������������������o��������������������������������������������������������������������������忯�������������������������������������������������������������������������?�������������������������������������������������������������������������~[��������������������������������������������������������������������������o��������������������������������������������������������������������������忯�������������������������������������������������������������������������?�������������������������������������������������������������������������~[��������������������������������������������������������������������������o��������������������������������������������������������������������������忯�������������������������������������������������������������������������?�������������������������������������������������������������������������~[��������������������������������������������������������������������������o��������������������������������������������������������������������������忯}}}}}}}}}}}}}}}}}}}}}}}}0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0[��������������������������������������:���������������������o�������������������������~����z��W<�<7 �<ͼM>�:˿|<忯�����������������������������V���}_�W _��?�fli����v!������������������������������?���}ң[�<��iذ��߿��iTy���~[����������������������������������Zqqqq<@,q~,qq qao��������������������������<<<1o���������������������R����������Cſ<<<<<<<<<<<<<<<<<<<<<<<<<< 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0Ï��+�������!1AQaq `P0@�?΄AD&AJ;'S_G</4bwI( ck^yCx%{e*Ǝ>6iƶ z`Cا\|_hU8.m�#,KEWoݍ67ޜ-x#LTZ*' oY˅˥.z UNҖJ~n}a >p: f_2=[f9Y؍&Tփ,oTőuW|/[lk5KS5(nQʾDq�zB!B!B!B!B'�|>ݏp$7|�~A2GR2 |D #Z%%u'Wa#ew"L&Wz39m3V"\`tގ\ ͭ_R\ JRC- �B!B!B!B!B!B!B!B2cދȁiku#8    dAAAAAAAAAAAAAAAAAAA@24%ߓ|Dˢ;I -T_E)J\Rz)JRC{B Rb)JR}R5,poD't#)JR$w"JR5(N*BPU!#(qHH)KKv5=n:ԥ)JRޏZ <=F)[[S⻾+q[q|ͳ-o"QUmCfkBk(oݧ'~4bemQi,Il.Dfe7[ELng~2iMM_m20գ4_-ۃ F5׍p=S6|% A]lwaUdsf(S_:!OfmU9eYƮ/A^, 戫>6xլ2rAn-a]pT~PKc(<\�t,rRn $9"+˷lHG-NE5îqDI[JU'Ӓ}ٌ3D\-Zh<΍g6mcZȺ4Yl7b__f[jUN76M-+R5ρ !-9b."L&7O-\] degc4SH^!8Gr7twJUj[hnHFmz4tR'/6Џ {.*ce3런SF*c7eMs<Zׂ2!&ƫ;Ius7#8peZuH15*f|󠠺Yw䅖0,Ou{ib^Kw;A7`pZ%.k ԍ S{NϚ*VWn3M d6ZWu? Emd m^No H Wig%)/qēSoIWv\ ȃJ}IJ 4D:H"D'Tҫoٔ[݋0$8SO ں^7WVl _FKX3k,E)5i5.�"]; oLSѺs?0` 0` 0` 0` 0` T0` 0` 0` 0jlc T.r0` 0` 0QQO9q#R莬eV5{GhpɠJ ^D(ITxyhUk؏XbT ]7UyD~1(#yYVTLr}H+m\.o3b"ㄑg.MZh{ 59rbܒqqH\_,>)l,o6Md󗝻 WM�| N[nF濗Qx{̲}HnZeK4E1%)>4"ZQ3.ZIĖg>ôYL4^3 *X"amdזJ,#AEcԇRX{c{ˉjg2Z�b!lDyao(*z -gp=Q:CJM>bx2m{| gTdVt,<4vNHL.H˨4XG&cC}:Q-W֩\w\dmHDwg{؆�>£~^�o@έ;x$4mVJD]޽NW! 'Q}]/cOYV_*1%p/l[;VĕaݹJvLZն$ F b^btlLΗm|ŰmȍcC&ڡ: $(Xr!kdZ 者~n$- 6�bk1E4mGDZF;8 ^Thfn_!$XZ H~}ԇF>?r1!2;0^\칢%3lSC&ܥ_A5Ѭx;A4.eM3qJTJuc ?nPZc{{-j�p6!f.zRfamwZ NEwU*urW" X%ˏhG=jvǞ7 XxSx|e &BSIKt ql>KDl}H~}z]еcAO%Y\2Κl|ָ0A̘/pZhMT?cȭ7&?QifvcȔmfpS~}cSRe)е+Z`19/L+TpMj11SMu}NsjiwZFhF;VQ7sH6*]L}H~$ydWm|c=MQˉDݔcvOg]ϔ~RAQ2B4FXJ SH=<gre | oSRU=L}H~cC4܍6&M#VBMOOSUV5 uſ'&dy&^LLe[<BNbI ju/dNɯeUk؛{yc =Q'E9 oJI:؟֛cXc2lg=ثYSRHlFoo[FDhWje,pzSܝr[Hއwȭ$kZ=7>o"iY[mQ7aE6u3iNQcy|c<0QoM_ԇSRj"뜌CHs2+YBQajX+fmUߠ(^vHOOdcC-DH%[srDeXB^jmGeY]HT3MyVf*<V7bKo6W Nަ>?Bv;f4%ƣ5cŠX16'XmY%[ ()KJG^E M=аR)JR)JR)JR)JR)JR)JR)JR)JR)JR)JR)JRԇF>?r1!܌}H~cC)16g&S;zj4tb6MO,5<!;FC$J`{Яtx^L#Mb 7n]1˱LYkf6|>4#F$םӰEʻ?w,NdULE΍9E"zlʧwZ}p5ؗɼ=QngE,ϗs"SKh^Bwp$!!.sj =YyN ӟa1!ۃV|cȢͻ׫rc^#'_Ed� Uv}!i62WRUjOB3 e_яO詑&nq$'Yi'b6j9ĂH5 FfH1r'#m^E|a1!ЙEG<g.M(Mo?zR/ƇG^'uLuMȮ;o5_Ob! x:I-?6 U;-_!|?^ʚ!8_-Oz4n!"rd{qLd6&\ko<1f 0EwaKבƸg _[;+O"K6li6zԇc$QP>?<U0Zz3^)a/-Yhz:hEHV5s8;&VetV15YYKd1ŜF3z5;ww=\CD<x$ԇZ ֩"s)Te?+J s0u/v43NLLZ)JR)JR)JR)JR)JR)JR)JR)JR)JR61!QG!&JCGV2>]Vv;`ǣv H#dSnバnަ>?BJ[c&R,5Lz/nK<=JA;5"dTN§>GTΚ!v?/]V%ٻz R""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""#ԇF>?Fx�#_ic!;%vƫW,;S$QMFQ~"b(5< So9b'&;6-<k GHy#ZԬ<K=l#Ml*",gtb:{dz9GPm".h{WIRU=Udy Rc䓴7 K%5\9HTu; ^kLc.<f8ۭ{=W< oQ'cկStp#ƿl2|OQOP$YMS{%|v'a癃A\o)>šH^݇i(i#_U=~ӟ`!� 6cC!B!B!B!B!B!B!B!B!B!B!Bz SDi*2ù¬udYȭXɄUE#bΝ7mcC-DH\x"*+KL&E_e:t}ɷΫi?sz jTcM-3"96O5Oj"ڶv-w|WqiՍ1 >eXg~D}C`䧚[O<cQ F=Q/^/KV:WmcC-I<GhOKaDhnݵ.5l@ƓO Cj;/$6g' &Hp4.hbPH%h7rIK�;w]ƴ'ަ>?BJR)JR)JR)JR)JR)JR)JR)JR)JR)JR)JR)KcC#RԇF>?r1!܌}H~cC#RԇF>?r1!܌}H~cC#RԇF>?r10` 0` 0` 0` 0` 0` 0` 0` 0` 0` 0` 0` 0`G2)JR)K!B! !B! !B! VVVVV$̋K_pppVVVVW<Neط҇Ict1-�Gz<`J߁Ek:vOqII�$wY~y 3n炦 -Iv,g]39CY;>=}9 E~KW"�l0Ʀ 2D|7ZC%OsV<Kcouc02@Ldv^q_3Щ\KSֶ87_z 45tC U~7ZD(z'mYo%S-#6CXI?w|!8ȱw4j~Qxs"V v"]bpL�?=}OQ'jV�=?tDTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT>)JR)JR)JR)JR)JR)JR)JR)JR)JR)JR)JR)JR)JWO�+�����!1QaAq `P@0�?KD#Ii4M&Ii4M&Ii4M&Ii4M&Ii4M&Ii4M&Ii4M&Ii4M&Ii4M&Ii4M&Ii4M&Ii4M&IiN:Q(J%DQ(J%DQ(J%DQ(J%DQ(J%DQ(J%DQ(J%DQ(J%DQ(J%DQ(J%DQ(J%DQ(J%DY7)c]aRA  |F&*456IquEMBVƍI.!c7,PeۄrCrFZ\m8*'�I$I$I$I$I$I$I$O���$i)(=d͍lN{+"$\]&v}+G|WUET\O*P" }+yGCIt'O+BP-Gi jط�T=:Rq -s �l�����I$I$I$I$I$I$I$#K JHx<40\ K$q+ dB :"v1]%e=iM5k"in!a̸AC\l}&!6MȫR&r\3EF6ᦚU9X!в(v!JBnsI$I$I$I$I$I$I$I$I$I���Rj` Hk<B����������������������xro7%H%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Yw;^> hi7qM’F ȑLDdHdHdHdHZH!hB$HdHD ȑ؆HdHdHdDWQ!!!Ё-єԆHdI UlSRdHdHdjq alIc rBcuo$2B'U1C$$.C#UVg#Pt!!!!wiV*5Ur)qd** 'DNm.]$U\}!&AE4rqVeI.aJ#kp, T]VIj4gF KN5k1=rmxNof(rkhڍ] }e$(ȓ~]Bm�a2zmK*82S<t6e_iC|Ք9R6%U6^P㡼N*gD&*\*d/dV nS ݇=,^K2MГ\\@O9+[Rۣ" ]�lQ?'P\Ca1"dm |*L9FU+l?%qJ\)L䕤s'˓mo&2pE=H8 Hf]IHvYAJW;uضL>TrOͻ,L">GIHjl~ij;+۶KS7k*`kD%?""U<s9k,B)%9":l˲pJPrq)ӿd5|ȧ7JkL.dDH˙ԪB5M߱fjO':V qMIE34<!`ITwEJK<!xJn}*[RUUI(gcU)*_2SYE+]KrHJx#r�:nۥu|%ːMH$֚%\mFn<NK1!FzQY+?&2J[MP{RK\fn?Qˤ|ri)WCN!+ģNS1ج#]>ct�=_nE?hER ܹ,&vk='KPxIܶNw3)a4"*p "DCq_ح.g5m:Ԗ̥".ÂP<4%$\� ehʶNNlmsb&Vo 3HFCA <Pҟ}QFrL' J= Lt}Hpvwt :ӫIC}YPr4jlH^w?����h8'U ��1&g Wŧ���Y7]bh6ŧPĎ6.29.v}÷RKSRMfrEC:lqe $(.krÁDJR YU[JhmZ'M~1/#p'Ȋ ƹޅК̇#%gU3%�>ؾE pdAӭ{%ǔЦXvN^EM˟$L_5—z L]KGI'/sΎ~Jd_b/]OG*K QN*M*5/țKZ?Ы.]YDX\xoM:Һ"_Hb+?'jDK+"إOqaATņ$7Q*hmȊґYJҬI<i%jŵs5{b([\?`2l�DE׏b;^>A;^>s$( mU6KKƔ^)k.@FA\chJ4%95VQ#)%+Ԝ-sR;JS+bD&WxJ[g7fGF5T4h} dVhc $X\xoe|М) =בu2 .KDH-t*nF(*8WsU?8ri%|jgD V*92"b٦UECFd%TCJeIUJABkd:{Z0쐨ܱU2 u{VMfNU]M# $(dY,K%dY,K%dY,K%dY,K%dY,K%dY,K%dY,K%dY,KX\xoB uD| KnR;PadQt]K*MkRĨb>҇KWYHԱk$Mo Պ.ʊY'B%kʭ"6YnU>@~Qas_X\xo;^>9 La>~NpEJ!UEƮu%_*ғ0(tpq=g[WB?|.TmO9*cE.Zfjս*} $ZLMWq$,.v}÷r#iXeI)HfQOh%*BejFHbR2oᱎW.P>!@&!ڡum US/%$eYPn-5Um$Lu*_ 7-P?B~*\,.v}÷s�ߥ?(߁JYS?(߁`2i|lr'xq _D֣O%bG1p3 jx8V7ob& 2&rQQ6X9*X pSB<ߔX\xoNiEΘG҃wp~B6#ORGNΎcSa+T@m1aHa/m{gcvk,-"IrGMЋ]/Ю~/,.v}÷rXQZ&JQɳd? Q/PC*i%Mv(W_Eypu̹^s'>2 5 &+'<SCXYRM&ۚܠt4QGy�+(߁6` 0` 0` 0` 0` 0` 0` 0` 0` 0` 0`A ;^>9uE׏vDm GQ:%JYTǂCuCH1E׏vFw9,_d֫2pXR LN;>M&<%*F'n&w$@oȃڜsnȟ$"t�8N*N0R\cdeճ+3 "xsR%\Z#W[|tuc�ߔX\xo}yЇhS4+-aM.G1FM2X/™mN(3 D"y4zWS$DXOQ7̥  U(6O�EWlkX JMk; pk;~#p  pm/6q}RҒ#-sqP+dk&bD&nJMlM+7 ,ҢmaC.,.v}÷rX2Ey Eb9U!*g&wEIue6\V(2%rQW?U%W;D"iap6JHʄʍQƺMV>FW 5,'|?(߁`7Gٳ::#]LnFuTBIA5foMtTmU.d{o%mpGDnQ(J%DQ(J%DQ(J%DQ(J%DQ(J%DQ(J%DQ(J%DQ(J%DQ(J%C pX�Z����������������������+ pk;~?(߁B (PB (PB (PB (PB (PB (PB (PB (PB (PB (PB (PB q;^>A;^>A;^>A;^>!J"^O/(R5��jQ|,|W;b<6e䤚'q;^>'B,�\Naɦ b,E./^?oD1Vϖ>2.SNCx9 w 4Tm%iQh'E;ܼR92OjfMjicT_Ɗ|Q}Hf_)�LVkj3uMRn+Z"nÚme-4ON:'DtN:'DtN:'DtN:'DtN:'DtN:'DtN:'DtN:'D~Qas )D,'�\B E,%@u�dNTkJ&RK(Q4(88/qq+L5)ZRc4\4y6j$: iD;D< )M:蓌n(rzRsćВ\"_J$QXc+/P0SK\O_?(߁,.v}÷r:T|o]ou&HX肺Z9S�|7yWN<-} 1tޞ 'exdN�E׏vE66E'9"c*KTƨ;XcRKj~5YJS44#삽&D*gmWenHE_DTa7%d,9$AsI%(CsOS<_UpBDQS &eȫ+*.Ȧ~k;~"Yi(xZZ|TT> ˨[u Ě]^NВxGCBn8K7KTcXIo"ȚY]8媆[-Ri\Glg+Џغֱ/,.v}÷s p Kuqh d*?+6=K7hvF*,l38!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!<?(߁aٌJKEvDj!_5VTz*9f0ctWDԡlh6FKZd""6v~Qas\LrshNJ[Q.zCR*{)"I7yKf5g=AY{ӥ_?eN⪳�(]X\xoPj5FQj5FQj5FQj5FQj5FQj5FQj5FQj5FQj5FQj5FQj5FQ)rk pk;~>.o;{C~Qasӻ[(rU<=$V6'vOVr'Nl7¤C*D80O]6vR5ބnF{YCu<.VKA)�"Ļ 1Rghs1ne']T$=gMv%4)ehr%WU= rYa㍽,$ ${! %ǥY=)FV3+8k5dS$ pM^'+hјV$;BFBUTTB Z2l}/INhk*W^P}4J,lZciɵ_ RsQ(H:+gjNݨjU_<8)\;&gXZ5SݤH| L⹥DA]nq|%mB\t%uGqmIPʁMCuE׏v1cHk;~#pt:Ct:Ct:Ct:Ct:Ct:Ct:Ct:Ct:Ct:Ct:C_E׏vK 6,G1UAOO#­sl\fVŇKl*Fv*fC$ts�Zv~QasIw +$~ēT(`@hFi|Y^¦K1.(B XK=ۦ[_#%rvK<s&'mEXE�tƖO47K5BEb+R*wt]~Sر)OB'WT|TRZ+0씪:ŮƋI9tJwO`.>B&yDA#uZMXUEU4Qӷ p1 ZQC7O'AK«BI ؅UjRaLs�!wO�+t?a%M.$Uk%7D&}bZ#*l{Am~9sdK�$DKi/>=mdK^ JGbFpt;|?(߁Ȑv;cv;cv;cv;cv;cv;cv;cv;cv;cv;cv;c pk;~?(߁,.v}÷K%dY,K%dY,K%dY,K%dY,K%dY,K%dY,K%dY,K%dY,K%dY,K%dY,K%dY,K%d;^>A;^>A;^>A;^>A;^>A;^>A;^>A;^>A;^>A;^>A;^>A;^>A;^>A;^>A;^>A;^>A;^>J~Ƌ wy!䇒Hy!䇒Hy!䇒Hy!䇒Hy!䇒Hy!䇒Hy!䇒Hy!䇒Hy!䇒Hy!䇒Hy!䇒Hy!䇒Hy!䇒Hy!䇒Hy!䇒Hy!䇒Hy!䇒Hy!䇒Hy!䇒Hy!䇒Hy!䇒Hy!䇒Hy!䇒Hy!䇒Hy!䇒DAsBQ(J%DQ(J%? ���'#�������� ];^>舜_�4!{:ZF?�"4IB! $-B!"DhB! $-B!B$B!IA%hHd"BE׏#LmQN#)ZX┴_cR8~J~ NmQNƴ-]Q8 xlpJuQ9i}!X_pEZ/_b ʇ]Ljg 'UݩJU߁[vc#Cp+*'RKr2+kGd_obWCVCp&*U+Y l�/cUI|А]II$FO?$W,XÑc-~^آPRP$.J_2']gȮQ:Cp"dj*X5~19Qas ̂   w?,-~0)JVD(屢CV_+HDhAh4 AhJ!䇒Hy!䇒Hy!䇒Hy!䇒DC$<C$<C$<C$<@ԐC$<C$<C$<C"PIi4M&Ii4M&Ii4M&Ii4M&Ii4M&Ii4M&Ii4M&Ii4M&Ii4M&Ii4M&Ii4M&Ii4M&Ii4FTsn~ٹ7?fsn~ٹ7?fsn~ٹ7?fsn~ٹ7?fsn~ٹ7?fsn~ٹ7?fsn~ٹ7?fsn~ٹ7?fsn~ٹ7?fsn~ٹ7?fsn~ٹ7?fsn~ٹ7?fsn~ٹ��,�����a!1QAq p0`@P��?Ms8c牞<e-hFZ2іe-hFZ2іe-hFZ2іe-hFZ2іe-hFZ2іe-hFZ2іe-hFZ2іe-hFZ2іe-hFZ2іe-hFZ2іe-hFZ2іe-hFZ2іe-hFZ2іe-hFZ2іe-hFZ2іe-hFZ2іe-hFZ2іe-hFZ2іe-hFZ2іe-hFZ2іe-hFZ2іe-hFZ2іe-hFZ2іe-hFZ2іe-hFZ2іg! tpG\RAqqDGbɤh%U  I/̶llllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllvT.uK]ReL<O O z1gXZvpa5�Cib⼻ )Mz.ދ]r3 &6M19C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 % _N A H1~12cDG[(x=,37?*Rq1of$|SFw `. !MQ\afI9C9C9C9 EN"V*z!74"<г89C9C9C;kHBaB�#9C9C9C9C9C9Ct#GB:Ўt#GB:Ўt#GB:Ўt#GB:Ўt#GB:Ўt#GB:Ўt#GB:Ўt#C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9 ZJgMFY Fs  Lيp<)ff;B{Ld H0 @- A(a +) R81:ḘƴF3Bq" dZQY'�h\A= *ff;B1!^40oyC甞*G4MclRɗ9զcpd458,:DKc"Hj 1lN ]0#f/$, Ri"LaOSѪM͚hJ��ߡ �������tdd#1D"DDKpY,)bo#$3o1 C-!2 $ 3 YYy*{XP|V)df/�I.p 6 !ꛚ QH&DJIc `"aO6TPYxǙɪNBgۘcipRM<&dQ|)S22| $(*|a21FdД. qm\ M&`V'K:"3-kNcAYF+5:_DIEXCh*O*5(dj'B4F<,0ט31I1-Q4NzdPePePePePePePePePeHR)E"HR)E"HR)E"HR)E"HR)E"HR)E"HR)E"HR( @P( @P( @P( @P( @P( @P( @P( 7JrhKCwUAR.f0gq_"HK Y >dDk]5Ayexp&3q4!&9,Q nޚ7a9Ĉ-%UѤU5UzP2"#<  '-: )X4<Y5c=rDq'*)`Š :9| LC~PI(Y\\#'dYpg2gz.,D*sSxZ3nTD`'rrD˫,В<Њi193�TX6a@Ƈ <12b*S8`4!j(9C9C9C9C9 t�@������9C9C9C9C9C9C9C9C9C9C9C9C9C9C9Cc< T%Y+7y\90"7!]&oYlIGݦ"|(-ZY02MG<s ;�1=cD` N h-ұjN_Gb3KA&WTL&()p(x1E9UbI u8$Y,?^?OZ r„Αeyv"msXs0kR㊄\Fy!A-hh5܊'XZ-Wqǒ(z̥,tdZV9Z#(a6,א(2s)d`*x'ɸ K:H҉I(lKJvU|/Xi�܀�����������������������������L&IqP&tYO!94�CYfڶ>l0lIY0' ^eK wlfnC5!&Cբ?$<P1ml9 zjw84ZW͛D|bI88c.h;7Ck9 G@ PY\!C լF %r#�����������r)r)r)r)r)r)r)r)r)r)r)r)r)r)r)r+#!�K ĖNRCԡ*zj8bnt@y3!FSL9r>C!LS9 2(2(2(2(2(2(]%Zw@BZJ%FQeFQeFQeFQeFQeFQeFQeFQe�fffffffffffffffffffffffffffffe1LS1LS1LS1LS1LS1LS1LS1LS1LS1LS1LS1LS1LS1LS1LS1LSLS BbelXLe C :�8lhE-ld["ȶE-ld["ȶE-ld["ȶE-ld["ȶE-ld["ȶE-ld["ȶE-ld["ȶE-ld["ȶE-ld["ȶE-ld["ȶE-ld["ȶE-ld["ȶE-ld["ȶE-ld["ȶE-ld["ȶE-ld["ȶE-ld["ȶE-ld["ȶE-ld["ȶE-ld["ȶE-ld["ȶE-ld["ȶE-ld["ȶE-ld["ȶE-diCNu=ө膝OD4z!S :"5 1066bo{c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1cJk#ؑt|gq_鷽a<?;�MyY"*J*J*J*J*J*J*J*J*J*J*J*J*J*J*J*J*J*J*J*J*J*J*JO+*J*J*J*J*J*J*J*J*J*J*J*J*JvO"*J*J*J*J*J*J*J*J*J*J*J*F6Rq/z2èyw޲bb?$I$I$I$I$I$I$I$I$I$I$I$x)1cɲ:�I$I$I$I$I$I$bJe\Tټ&`%�I$I$I$I$I$I&>yY͕#H#rz@d5|6!ND b$9%ř19Jt΂{O�37-K?Et` e2K+ʼn~MmHcYH&Ҫm–e(R(:a 5�o+?󿌚sI)r) Bi%9_wزT"K$6+4Ж)R75Os3�U;;%Ŏū r݇!xo.bAڠ`F4S塚s ^"8fnOD;B6%gZf'+wQX)B)L&֯,:gq_6T<K:p>RyTD2F7 ,q#4?GVҔDjq4=lx䎻`јM% sW cf?RTJԀj$| 9ǰ s$Zԕĭ~&[Z8F7b-['oC$\FQtDi4p)#4?L%A-rp74.B3 >"WfW4t%jI+QЩKqddNp<$J$~%Jx<A7 5Lb<, D 6|!$ &gZI+_Z^G15(mjLJ5z joJVq8Y,J 'n'˒1݈e cm-GZ8mA&Iq>&mĕĭ ZO6%Q1 Q8HN81Leĭ~$N rȚbJV~r܏3RD6@#؅)$dUy55Z/`4F cfHg## 9RBF:N2V)qf$8<%7pty-LƞBVOVxIsP?֯,:gq_6T<85 g3"/ZV:1ZWh#RL3:mptf�F)mT ñ;hCL,!³Y!TKײXXj2çtqLrh<4̒@ƈ\IB{R-4XjI|sh0o!'.~ٝGV󀭅BMʫn0?CjܘR3ㆠJSy�CS.NQ }F$ET![ hQ4/43բ7-O $iJ?(Sj$Ҙ3~ |8X pQx-S;HJkLX4NZ厸 XŎAkٗW!S; {a4)g�Yb_ g( p^rL(o }ĆGM.D〞|D!1[F45*z(xxe $OtA 6tX [EOls37+87(+ C8 9X.JIry-~<d#݈:o"HY`e Ncd C,ZҬDѬLoކ\R\~ǏDX3g"n? iΖ6I*o0N)12Xqh3{&6ЩN,CrQ<\} V3FM3cMpbI "dģM^B|iVT膧00̃<8 &ix[_ RNFXg'XqfI5_ 䋊&tq' pR>iHcuww?xb3Љ#0e#OJ N>M†MtLcb&~D&3$rb[gK776a#Hˏ!yhX"7M6Il]҅dZb s,ܤ 1Qs:X(hNV!h\aR�͇[]ɬ$11F+E"6 J$ac;86BԲ%gcR~L8f4̛-joz2èyweC3jà\'aYHIZi?g؆+(*is6: <fՂ{\Fc,n"LRbv?PÞ>ci A!ъf,)Zau�DMOpt$<ԫDcKrk- %g |E8Fu~,c*\-'l_"FBB/)E#Is( QAÐHR:Yڊ\+A)hcoTȅ&<&JQAu<rő^&V�%Kʡ{."KX(x;xZZq(WLډFqO 0$hŤ02?K=͔QtpzyB`U2q& K` qLXqIHO,ZT͖r; .e"\G౾LׂfrD]7!#qT'5Jȅ ۖ'�1,'L;;v>uDiDp<AZ 7j!QMqDct�18FcRDcWc+\D^F%�Hx"(K]GXa4P&t0»kZr# &T`AH;#tӃ| wC-5D^;8QUO7 JgTl3HZ`N81cxv9FM̒I=u �G@T\ѴK`wOIdMcv՗}>2>q(ۀ6Ŕ؀ :(w�t\NUy� KPSIS漦DSRE+f]f~; zgF@9s-pc2S�L'P=XOPD[4I@Č3asSRwXd8smu*mq1><R!0<d(O�ɔBCìp ,})G 9p$~B֯,:gq_6T<%4*c"n!:C=l�]lj8)BVE?&F/\סJ4e|anXitM8RX?\2N,pZdU1U$X(xPp)OK82&ѳ4XRe /cdž<ЛLob%? rj<G <!fg(C@፤a(FalH5cvI\"xB:BD ,kРs4*#XNj|EI IJi|mÑa8|?j tj45(ObS8+"de/NfuKք:|"I|\<P~[0^  @ax.S8w"ͧ:RX5zLA_0r ɜ9Kn ٿMPOU]&, lT&|Lvb&Gs|c>ѮprDɗAax;'v,-TSBd]6ǐJ?Nlfc6}LW,Yۉ�jIz.~(.:#Z' HRv@H9^@ˠJQXܻj*O?c#ogɏz$cKO>j#B?9$C=p :jbܿ^X0Jżx4$\^%a&#F>8ɦi>(p|oF3Ъ =aI+Ǜ*ɚS&5I<A$+->&)1{_00 DE'QGe\x6Ӌ9Cf-p2'xL%fX29 yu,a0qL[ZF3lc$ƋFf^iħ\!z00ʔ*bD;Cd('`b2fK1Nrd1[=$*\B[/ 5Ҡe㑂ꇕDd%f Zތg|1/RKԥR)zJ^/RKԥR)zJ^/RKԥR)zJ^/RKԥR)zJ^/RKԥR)zJ^/RKԥR)zJ^/RKԥR)zJ^/RKԥR)zJ^/RKԥR)zJ^/RKԥR)zJyKoJJ^/RKԥR)zJ^/R�0a~^/RKԥR)zJ^/RKԥR)zJ^/RKԥR)zJ^/RKԥR)zJ^/RKԥ=?Q$jG9rFtNo.t)zJ^/Q!�NIs=VIR ʼ"KԥR)zJ^/RKԥR)zJ^/RKԥR)zJ^/RKԥR)zJ^/RKᱲ QҤ|1oYqĥR)zKqN5")4 " qDb"ғ'{іC/`I|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||h$e<Jq=^eP<�,?w@UP1w$p+YG1 $<#ɡނ� e ɚI5FAJO%"bp)i*Jʹ"d!z"]6+CNYXi`«& .S/ԜcDD&M�^ryY�m3hi&J'aGŶhQ&(58JٔVM S `SI8XB4% ?DĊfUFl a>یi xAp61C2|#GuׂhqP8CʑM]5LG:J;-2I/ L7|S1W4 T$ ˊRUXKv< si<FLV822y8!/?Gp/z2èyw;EB ZGyrp|�cp m-,q2 *3M|M%Q=y,e d4 b2.*< <+55: D,E=%5, +,!ns xX\<'jo9X~"o~b1$bK y<hnc1gFȵTemc,`㩘,Dp0Kt'Ylmr>/6 ?#@͎UJ|)kԾ#~ _a<?;!D⌹Ja_2^B6t?\MsBB,FG"0cO 7oa_{} {Ȁ⡛81eo&H<H2&|NDiӓre bĝ !14vo !cjK!ȟ؛p>A1^vqK_{e:$,kp5U!Ysw4CJCuZ2!o2I&k1T@sOGp/z2èyw;DLhѨvِ^ߐpfa6c QF^#4F*I֒m?хȈ~P،$cM$ozJin]qdO N3&a& !Vџ ȸUzcI/b}pFV#hxA &bF<fA6eИe=IEi7Ѝa!jN401$>;*tċi$w2Nwq^=drfāXI2o, є|.ĺԜv Oj7Ն0 tc<@3rGf#~ _a<?;o/W[~ _a<?;?p/z2èywxcM1?/ތg|~ _a<?;?p/z2èyw;)K% JI?C=iJL). �ͨHٌYvB%<rZV<?h0An?k-9jO OЄH )\sS6"@ihpYYl3#)!ZfIU?/ތg|QDhP&F8#Ry(Vi0#dd]4QD^(|S)e�^} ;q ^|D' 0q6(v=g)aI;I7kPDǒIȔk!5L="XIr ;'Ǡh8,XU$F ~ "pN͵134pƆ lSQ"HF\Ē<Md gO$h29ŷYF wFρ�y,:gq_3Xt2Bu9c!⺈|z4eÖ"0Xsf sTĈ%ge\)@̧ h~ĸ'O0a8y :'6U'7!�pZÕx gX'dm3.b78|Xy2le Ɔ`%B-K !(\\$tZ{a"~ňS9Pby4OwŜ iA@`X9/p.9$9D&=آ;O?BjZ^[8(�H؆<: Pg(J2FlYbU55Cc( 9F!ȁȘ_5RegYegYegYegYegYegYegYegYegYegYegYegYegYegYegYegYegYegYegYegYegYegYegYegYegYegYegYegYegYegYegYSD7˸~ _a<?;|x7oF? .(HIvCbL6K�` X]∼c"HLnO<а \I`(.9$#ch03c-V#?,KKg}gsydM)M$`.kOAfsC`xTf$0Fk;�DCz$4SY,z ,ɑ xVjO8{k%\HqNF2p&E2G2." xLZ[N`K+;Vpo 2y4ނ搩Zcv3NLpFoooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooob9 FXu3gw4-ھ]3vL :0<&}-ҞsH.}VQw2»4a֖ f &S\iOQa6%(p ! D|8xDZ"zfsp&r~6 p ?XKk-rfs qh>FZ f?fI 䚍IM{oZJhn}`RN)Ȳd%i0|E - vc?pA5i17:lm-E̔a8IcKȲ3[1!X(!.0aA!1 $ 3..4P:ݭ)zqseZJ(./˸~ _a<?;|зj�:h./9|^eP<�,?wBݫ҂{іC/7 vJ FXu3gw4-ڿέ(./˸~ _a<?;|зjg�`%k1iAp~]^ryY�慻W.-FzUT[\H!E�"p0 N0.YKhVYp}$ְ5n'BL06aKOf#9%!/_Y̩K�h./9|^eP<�,?wBݫCC$dn2 71:ʗAZJ&a0){tBB P2„w|_!9hA[b2-6%ed'"j'2A8WS. 2%+,zێƔ$ y6)p*XS YFt&$SVK̲4vLF@K$ЯZ,BvIx)ǁ$ùbC4R8׺%ED0E.X(:O5P ᶔ ?/ތg|h[~,|p H\c!0bmZYWf</nfOrbC"SK.2s&S_AMSY,JM'#IN2WJQ CȖDhY2BQ4MXqckˊ*Az9Tx8QQyK{fgn僞l6eN I0ZP\4_p/z2èyw;nh:?^ 13pЌZu02g10cL[fe\5`e4+ ?D^h8EyW = IO81 <DOc,3 3 N]IڨTp \i 1$S0ǡI?fa5l-Ң߬$ĉ;:wyBCi>DxqmXZ!>2mY9άN◁2LXZRCdXC8 KL:P\4_p/z2èyw;nͤO d )(^$sI!I" cjSN:EO! KT0~hCy [}E*DH(ɣB Hh֍Cu9!. lFBtH/8!w!(E@rc,J C=2m% I6 Ahcm(./˸~ _a<?;|зj�:h./9|^eP<�,?wBݫBNEh_J FXu3gw4-ھ;.36'؟b~͉6'؟b~͉6'؟b~͉6'؟b~͉6'؟b~͉6'؟b~͉6'؟b~͉6'؟b~͉6'؟b~͉6'؟b~͉6'؟b~͉6'؟b~͉6'؟b~͉6'؟b~͉6'؟b~͉6'؟b~͉6'؟b~͉6'؟b~͉6'؟b~͉6'؟b~͉6'؟b~͉6'؟b~͉6'؟b~͉6'؟b~͉6'؟b~͉6'؟b~͉6'؟b~͉6'؟b~͉6'؟b~͉6'؟b~͉6'؟b~͉6'؟b~͉6'؟b~͉6'؟b~͉6'؟b~͉6'؟b~͉6'؟b~͉6'؟b~͉6'؟b~͉6'؟b~͉6'؟b~͉6'؟b~͉6'؟b~hG>ͳ>ͳ>ƿGي[Z=Nm(./˸~ _a<?;|зjǗZZvR)z ^P��DAW  ?/ތg|h[|wcfI $̰3x}<B*r8"G"Me1Ԓm&)Dn%*$<SiF5pNI/ӑs1BpCa UBx[LT&<qLl�f1mK5b"H/l+f1Av " =IƱ*gіiw5HwCg+p2FPX\%PNR�=hw_ZP\4_p/z2èyw;nݏ/S(V+c&zDJX&�Ŵ3&`c&+1 n#$. PK7.VGs=,5:MY V:q6�~-h2 5nw2@:nX5TX ,9_u #)¬�B35gc%/ ?/ތg|h[|wc85_ ے#]ټ?C,14XIt H 1\EFT O\/E[GK>(7TVA=I& Gd6`| bs<HrD#2 ~Q̂&JAg]3'_৾@Ď Iaň\&^2LITx J FXu3gw4-ھ;!bn?VIi ,,aG <s.p$4q,lNoӐ+NӒbЉ8C15v1�GΖ>[LR)їIڒ <s‚$эX 7gj<Hx?)  |ډ78 Nx1￿ vRQ\&,)OƇuEwy,:gq_3o_�Pj!@6*co6ՙ_LJbl'!S2ҰB4`�r׀2m`cc! HQ: o65* smPdr[hIpCieTIC�(42} -245Hi-ِȫlreD |>QJa?"fd�/XSA )O ?/ތg|h[|wau5?I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$M81f (WBP+÷(./˸~ _a<?;|зjOb<(<HTt*: GBQШTt*: GBQШTt*: GBQШTt*: GBQШTt*: GBQШTt*: GBQШTt*: GBQШTt*: GBQШTt*: GBQШTt*: GBQШTt*: GBQШTt*: GBQШTt*: GBQШTt*: GBQШTt*: GBQШTt*: GBQШTt*: GBQШTt*: GBQШTt*: GBQШTt*: GBQШTt*: GBQШTt*: GBQШTt*:򴠸h./9|^eP<�,?wBݫ҂{іC/7 vJ FXu3gw4-ڿέ(./˸~ _a<?;|зjz،s/$:`c^| PR G':"i0i9R!Il@b҂{іC/7 vP$`ܧ[gRhv2΋[ztC7eFBB,MsOTLZ;)09&1!D0؊%Qi0oF;R3%,9vԬDGf=Ia%f+QBNU̬?r0B`CY7,\NO%CZނA '؜IP8%ՕiOYZL& ܖN`rv4 d%X!"JiZP\4_p/z2èyw;nTX'qB̐Q0Qf Ѵ'7.fT〷WiXXCĤYRn8C(zH, ɳ64f Ȳ{mC Q iLf6/IL)2.24s"wbUD!KF3ǦЯ*pŐ~tMGذ.+1&{--dڛ[a�#R#Ɠ_9-҅)P`S+XXȒ|ӡ#Z*8!$X\98 JZRC� h./9|^eP<�,?wBݫ(IpJLAx+rt2 ~îC!e< :؂H0 MPܾ= E8[|0• \cI%ĴI�9 Fk 52 >!:E#as$aqL$d!m2I%`OA]aM1B7e`sA'+D(€G2BkW50[\�i5v0F͘t_ɑ6'?ᖔ ?/ތg|h[|�3 h)FPv@rjk̹Ǥ_+r9:uu[A.!ݝKb1b@ FrGv7!%R)rCF/Lb0ZxnImQJa7ffs& ),2$P4i☻#4$πbfj* /\q(t'\(DxeS HWJwl É S]}I2҃0�ZP\4_p/z2èyw;nuiAp~]^ryY�慻WեEwy,:gq_3o_X ʛZHi"EI-$ZHi"EI-$ZHi"EI-$ZHi"EI-$ZHi"EI-$ZHi"EI-$ZHi"EI-$ZHi"EI-$ZHi"EI-$ZHi"EI-$ZHi"EI-$ZHi"EI-$ZHi"EI-$ZHi"EI-$ZHi"EI-$ZHi"EI-$ZHi"EI-$ZHi"EI-$ZHi"EI-$ZHi"EI-$ZHi"EI-$ZHi"EI-$ZH KPh./9|^eP<�,?wBݫN/ފފފފފފފފފފފފފފފފފފފފފފފފފފފފފފފފފފފފފފފފފފފފފފފފފފފފފފފފފފފފފފފފފފފފފފފފފފފފފފފފފފފފފފފފފފފފފފފފފފފފފފފފފފފފފފފފފފފފފފފފފފފފފފފފފފފފފފފފފފފފފފފފފފފފފފފފފފފފފފފފފފފފފފފފފފފފފފފފފމyl=ͥEwy,:gq_3o__5+]ƁR#RAʤbu-!go`lPD%qS YKR2?⣺h./9|^eP<�,?wBݫow4FQ&蔌$Il(Ϩ+4Ә2,J\pGih4Zi{9Eieք $%:׉LpJ300gԘR2c2཈6ȒRQ1N%�X;ESm)gt!<j>Z⛼҂{іC/7 vyP*|j<A^җHe+T5Pkp@7 G&y0ΜNb2!v&YhQݐMĖg/4<a#r9FoBԩ& X 8,4!&D!~ j`x.(1(t٧<ˈ)+3�ͥEwy,:gq_3o_|<uHa9/+ 22kKV)s%\!pU@\o x8lqsH,>pJ_6Cp3CgԘ,I]qP;HiŽG Ya#ˍ` VB\xEK% #s/Yly-HK/1|P\4_p/z2èyw;nݎC988xd3xɨMf�D2˳ǐMe"M9\?F^B44kКO ˡKp#.jP$)ZeQAQ>Ҍ83Tc:dsnt0xRAAZ`4nPñ:A}Fk V}S z8Dgqkh./9|^eP<�,?wBݫ NXfҴ+JҴ+JҴ+JҴ+JҴ+JҴ+JҴ+JҴ+JҴ+JҴ+JҴ+JҴ+JҴ+JҴ+JҴ+JҴ+JҴ+JҴ+JҴ+JҴ+JҴ+JҴ+JҴ+JҴ+JҴ+JҴ+JҴ+JҴ+JҴ+JҴ+JҴ+JҴ+JҴ+JҴ+JҴ+JҴ+JҴ+JҴ+JҴ+JҴ+JҴ+JҴ+JҴ+JҴ+JҴi6Hm(./˸~ _a<?;|зjÅj%?������������������������������������������������������������������Ln^6 ?/ތg|h[ZP\4_p/z2èyw;nuiAp~]^ryY�慻WեEwy,:gq_3o_V ?/ތg|h[ZP\4_p/z2èyw;c ͞lg<6y͞lg<6y͞lg<6y͞lg<6y͞lg<6y͞lg<6y͞lg<6y͞lg<6y͞lg<6y͞lg<6y͞lg<6y͞lg<6y͞lg<6y͞lg<6y͞lg<6y͞lg<6y͞lg<6y͞lg<6y͞lg<6y͞lg<6y͞lg<6y͞lg<6y͞lg<6y͞=FN{іC/-"'FKRe,foofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofB5"̹/˸~ _a<?;?p/z2èyw;~/9|^eP<�,?w^ryY�{іC/�y,:gq_3�GFXu3gw�-V(-efI�ċ3D Z�yq.lWP#3mS$;{*bXJhgAH[� FXu3gw�)N%'�fRWNC}YȕĒI$~Zg1>(&Ifp'5]bh7HĭL CH,B4h ]16ŬPec| rR&JQ$ZHT Sqp#+qIo-ISh=L[%k$~%k ?/ތg|C\S{fNcP.4&ID1/i Klm\)͡+4}bdSZ'<@>E8$Qz{!H+/x^bi?j{&ZV:3*!i5GDcd($�2̢Y30NЃS+rF'Fmı8'"=% ̀^92d-mS``Ae mNxuaʹѸ<Vb7-MF)ɣE|!{CEcJD'J^-蕮=xlڼP')1,J}e2>@5p灎 %pZ,rhK+,V*UKВ`|}h3S4x/[:Jk5ÖN;<N;<N;<N;<N;<N;<N;<N;<N;<N;<N;<N;<N;<N;<N;<N;<N;<N;<N;<N;<N;<N;<N;<N;<N;<N;<N;<N;<N;<N;<N;`65NR./9|^eP<�,?wCliK 91PgV[XP4 Ќgjptfc-I$RNGP#GfD 04U)#VWCHY}LT RbRR6 ਋ҟ!߁d_ّĩ.pg"F9 [lT\>1)f6 "c`<K� d!�DBM&Dc+48I46rh9pU2*mZQH3dvzs@r]MaGGlY4)jn[sFPcYHY4 jC̊j)II| -!1VF%l`�6 l`�6 l`�6 l`�6 l`�6 l`�6 l`�6 l`�6 l`�6 l`�6 l`�6 l`�6 l`�6 l`�6 l`�6 l` ٪\Ewy,:gq_3o_<Kt,顅#xG(0jA fpyP<{+ˀ^c ŜhO=UFB&dƑ[@B'рlZj ߲ HpEP(X 6ݪ7jZ<WYŌ Pyr%xf[SQǙR.=6m4`¨ᙐd%x1(hNMS&揌qG*QWJ>͕4EDO共?b"FgV$"-ZODF j@ ;&AW(R*<F]VmZJl8c !IJ<Y$�ZP\4_p/z2èyw;n�65UJm(./˸~ _a<?;|зj�:h./9|^eP<�,?wBݫ҂{іC/7 v|Xs`,kŷq<z43֧� o+xDUqF`aJQ~jm]?,#s'EEwy,:gq_3o_ r[QQ@m6 c77%ΐN88߁^\Ki-X،LL_4"2S8xGqc,ͿqRay%7AC/{KVIXݦ9Bs�MJr Vr3MdRP Oj6uh.&O!'NG.$&5=ť !C═LeLE_a8pJfx ߄5o!Adv#L!#XaTD.LwJ FXu3gw4-ھy?6+.M,Hjq졌eUbĵ!fRr"̱d`!aLV:ŗ6dHŔ b�-bǰMd4',b'%РL CLpC81l! �%eQHt#<isK`MY+FT%l҇ ^XCfG襑&gxA`f*GLѡ9wRFÙ+@^)d5V#Kc#&vqif]4cdb\8&Eb[8>ⱎy5yDf3LX:+1!͐רJN{VAYr��h./9|^eP<�,?wBݫ&#mU05'3gˆS 06QꇣVS%M%u91(RT-CH؜*,Y8,uVLY4GwK$MF֬X<Lb!`_9mE!&CT \OQ)<й1 0ɣ0ս¢ LgV!xI틦jSl4Gk9 愀\V=O*!VGI&YT CЈ)-.B@oLhØs;*iAp~]^ryY�慻Wۡ#d�muHE ]ElSNZfb)0Q<6 Q2[,T!$mTqr30A)L@߂Z y!Z1�S(sfFM*"&\ =4#M7-?ccfDƥaeTbl![c 0i)0IBM%i+C$>BztPb|B,X,JGW4BL7ij*ib&S$%je+"2DX&,)oQ^k1$a?c<@߂G�F<B]H 獽Ȋ QiAp~]^ryY�慻W�+"5* Np%Ewy,:gq_3o_V ?/ތg|h[|`w�J<7z7z7z7z7z7z7z7z7z7z7z7z7z7z7z7z7z7z7z7z7z7z7z7z7z7z7z7z7z7z7z7z7z7z7z7z7z7z7z7z7z7z7z7z7z7z7z7z7z7z7z7z7z7z7z7z7z7z7z7z7z7z7z7z7z7z7z7z7z7z7z7z7z7z7z7z7z7z7z7z7z7z7z7z7z7z7z7z7z0)39҂{іC/7 v+b,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>$$y$%iAp~]^ryY�慻Wv; uCz@ pYs8Ao]9 ئ*z>\q⧂,R&' OmLExa,O 2O <& ^ x1đSe ’Qb_ɂ&mE ?uiAp~]^ryY�慻Wv<(A;CI(h0 Ñj׊y%/ ЙQn0"Z2``k$+ x%^k<@Um\I<Pэ}I>sFAz H6BrF3 )Ƽ0"U4.-q6;J FXu3gw4-ھ;Cbpř#38b A@Ssb88U#Ȇp7vMD4P+˦Л/ځZi8LCt3 1I%ވi(nǬeԛ#oS6lw_6 ?/ތg|h[|wcjRHlU##ZQIk:Kb#O/ APub(6V<Rj+O Ɠ'h<bW qmȠkQm KsVi(&X\F/dS\e@|P\4_p/z2èyw;nݎF3ld1b֥#m07XEJrSL5Q4Dz ,13H.WNԄsY(2c<8efL$-BfO,JHaPpo%|P\4_p/z2èyw;n݅ hq+ wB]ЮWt+ wB]ЮWt+ wB]ЮWt+ wB]ЮWt+ wB]ЮWt+ wB]ЮWt+ wB]ЮWt+ wB]ЮWt+ wB]ЮWt+ wB]ЮWt+ wB]ЮWt+ wB]ЮWt+ wB]ЮWt+ wB]ЮWt+ wB]ЮWt+ wB]ЮWt+ wB]ЮWt+ wB]ЮWt+ wB]ЮWt+ wB]ЮWt+ wB]ЮWt+ wB]ЮWt+.GuiAp~]^ryY�慻W1'qLS1LS1LS1LS1LS1LS1LS1LS1LS1LS1LS1LS1LS1LS1LS1LS1LS1LS1LS1LS1LS1LS1LS1LS1LS1LS1LS1LS1LS1LS1LS1LS1LS1LS1LS1LS1LS1LS1LS1LS1LS1LS1LS1LS1LS &?J FXu3gw4-ڿέ(./˸~ _a<?;|зj�:h./9|^eP<�,?wBݫ҂{іC/7 va lEXp~$~o-lJ恮EO�BS!(d$q︨j�`tElBV- [V6҂{іC/7 veCm5JC>lS6!x ~n;M p ěâE,,Xp .q kɁ???s-g&0FÙ&kIf4IM1�P\4_p/z2èyw;n\c(NN_ #bfe3pX0xjFSص^Ȳ)"pII^ TFDq\+%/!LpdP7l׈Rk!-̏.51c*lTc3shcuhP75V&\˞SlP3eSG)1`#G:7L]DnN8H5RY4|R%cR'R Յ)<: _ix;|DQq)E<VRGēq49{"/frf58cv<l JdpJS|0.+&82fq*Lc>fx.",%sMq=c"mc9r]X\cЀC2҂{іC/7 v*jsV9$*Ɋc`%:*k\q\8@ '%(e<ǃ)Ō/੡3!9 0">@b-g8T 4|X :F`Q!�q L+ʃiȎ!�dO7c}B=3(0k4dmxذ<q~+. ڀEQ>A RB *+q_&6�E{@I(ƹRXMR 'S舟/BJC\Ĕڽ Rl{ ~J FXu3gw4-ھSdy').eъ2jqQ0=+`a.<[mSBmB06dRhBN_Hāp3,f.k=%6kɞ2=EXeFj4B%3C2|ئ&*$$#ʈ`E2?(BraA6yxՐ*]7^#`` 9"H׾֪9?i bPxt 5퓌v㊔Ltj)x$Az )\IŚ?eBT/CD12Աav"@4j>B:�hZwDYᇃMTX1+�m(./˸~ _a<?;|зj�G ]P/S,-(./˸~ _a<?;|зj�:h./9|^eP<�,?wBݫ#*C*: *: *: *: *: *: *: *: *: *: *: *: *: *: *: *: *: *: *: *: *: *: *: *: *: *: *: *: *: *: *: *: *: *: *: *: *: *: *: *: *: *: *: *: 1Lo&J FXu3gw4-ھ;p~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~x̗`,J FXu3gw4-ھ;ܿ+\P5 �ZΈ* q� ͥEwy,:gq_3o__7 YH7E`HNe1. _0CF)1y%K&}I?yC.b6p'n74 ,{ 3tHgXA4c+Bn''e46Tr_t9XYXLnEI4`di?\G<Gf ?`4}>W٦ŗcN'6kI"< y4\&:];xИ<:((K-Ԩ!e_fw߮H)/ـ H|O(QǗ(YpP{!WJȰ̚feX~4HNy&M)Ct<x7P^H^Q|P\4_p/z2èyw;nݎF4#*`q+у-9C~)8tQf6n,䔖9K)0g̖rp`mπ1#ec% Yn%jLo#? `0AqoiσGNP>|%EC\斛8O*3qAږ53M#1K7`Leˇ 3-`bL�b_1_A-pLTeMAq{8x,FdI$pspm`U%=T1XTb*\8NN c%.I=P^iu 7!э8`lXq:[NBCb}4#A mc1ʤ3))&Y"/Ww_6 ?/ތg|h[|wc~QeWrX4Lf$Fˆ3$!3J%вILNSPFLi ,0Q6 IEU%h`rx2!u6v àM6)|, S8r7\I:"L!;q&ZmiB+6Ji"1rQ?H0t$ H׊TbayY�q&' $Mp͢I-q!If 8hX O Y1Mt 5z8-0Hv_?$. tPHJrz2q&SH- z$J9$q֦0R8?샷�҂{іC/7 vw/q2%AfQ$k_ʊ-(s-Kr4gJԹ ɉs&TYD: 0C1w rtdB:²U7C4Ԭl16GNuHIaI='!3I$Q"ao@`qJ,[8kpIK;c(7d9M o: gщBqj-JK1l GxQ%r59$]^9PXPdijF YŔ.B'if;5ʔ8" Ru:A:BLBrƚ 7F͋=;MM r `7fg{& #,)\q5ĶrR-i�ͥEwy,:gq_3o__�Gpa#h./9|^eP<�,?wBݫK &%龛龛龛龛龛龛龛龛龛龛龛龛龛龛龛龛龛龛龛龛龛龛龛龛龛龛龛龛龛龛龛龛龛龛龛龛龛龛龛龛龛龛龛龛龛龛龛龛龛龛龛龛龛龛龛龛龛龛龛龛龛龛龛龛龛龛龛龛龛龛龛龛龛龛龛龛龛龛龛龛龛龛龛龛龛龛龛龛蜕?1 Oh./9|^eP<�,?wBݫ6U6 ?/ތg|h[ZP\4_p/z2èyw;nuiAp~]^ryY�慻WեEwy,:gq_3o_V ?/ތg|h[ZP\4_p/z2èyw;iqf6m#iHF6m#iHF6m#iHF6m#iHF6m#iHF6m#iHF6m#iHF6m#iHF6m#iHF6m#iHF6m#iHF6m#iHF6m#iHF6m#iHF6m#iHF6m#iHF6m#iHF6m#iHF6m#iHF6m#iHF6m#iHF6m#iHF6m#iHF : FXu3gw9i$c7_u7_u7_u7_u7_u7_u7_u7_u7_u7_u7_u7_u7_u7_u7_u7_u7_u7_u7_u7_u7_u7_u7_u7_u7_u7_u7_u7_u7_u7_u7_u7_u7_u7_u7_u7_u7_u7_u7_u7_u7_u7_u7_u7_u7_u7_u7_u7_u7_u7_u7_u7_u7_u7_u7_u7_u7_u7_u7_u7_u7_u7_u7_u7_u7_u7_u7_u7_u7_u7_u7_u7_u7_u7_u7_u7_u7_u7_u7_u7_u7_u7_u7_u7_u7_u7_u7_u7_u7_u7_u7_u7_u7_U4|H2T_p/z2èyw;ʳYԬVu+:JΥgRYԬVu+:JΥgRYԬVu+:JΥgRYԬVu+:JΥgRYԬVu+:JΥgRYԬVu+:JΥgRYԬVu+:JΥgRYԬVu+:JΥgRYԬVu+:JΥgRYԬVu+:JΥgRYԬVu+:JΥgRYԬVu+:JΥgRYԬVu+:JΥgRYԬVu+:JΥgRYԬVu+:JΥgRYԬVu+:JΥgRYԬVu+:JΥgRYԬVu+:JΥgRYԬVu+:JΥgRYԬVu+:JΥgRYԬVu+:JΥgRYԬVu+:JΥgRYԬVu+:JΥgRYԬ6y]^ryY�{іC/�y,:gq_3�GFXu3gw?/ތg|~ _a<?;?p/z2èyw;~/9|^eP<�,?w^ryY�{іC/�y,:gq_3�GFXu3gw?/ތg|~ _a<?;?p/z2èyw;~/9|^eP<�,?w^ryY�{іC/�y,:gq_3�GFXu3gw?/ތg|~ _a<?;?p/z2èyw;~/9|^eP<�,?w^ryY�{іC/�y,:gq_3�GFXu3gw?/ތg|~ _a<?;?p/z2èyw;~/9|^eP<�,?w^ryY�{іC/oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooO/ތg|$4I2ZM FZzu>/z2èyw{іC/ތg3iDl$ѩ<雎 [݌_����������',x4Y�����������¬Ӹ_2 o�p����������)HQN ތgᮺl,APTAPTAPTAPTAPTAPTAP.Ć}f.E>sUZViZViZViZViZViZViZViZ9�1j!YiZViZViZViZViZViZViZV)HH&H+JҴ+JҴ+JҴ+JҴ+JҴ+JҴ+JҴW1~ _a<?;�]u4�bPlQf{jd]DxȰND6Úqb'�+և~/�6\g2,T/co�py!]ŖJ-Z|v&_PY[HF`Cd�>w^oғ? Bh|Sbۄ@Gd R�^/9|^eP<�,?� u�l^sLZKdէ$kfV<ɤ Bq7RB=\t/^;O�[ho?E1 hdcE3s1ZoA.I;1Q̅ 7hGv+vc劇v-Z|v&_2/!p_7̥, 7II%IVp)JD5K(D[vxӡd~) J�w^gg ?$$Fi`I'yI%/ͣ}^ryY� 'ZNLAh$9G9m$e�;և~/�<d~ ( xg$JK RMQ)0aN "Ic!8p 7M&*;?]>;/�0BtG ЅkLK: ˗F1gP(xإ)z1=LN"& hYHףlm^u�&D8⣑9ĥ„nD`MLu$o %d`a91 9, {іC/5_O�4@ ȁd` /EwF=<lcO�ߋ|� @zSl{W:KJÏ!E! QR)1Գ+O 8BP�iB edjNrG *.ĝVcUȓ)(1+3 . V�Tē oT2bPYf!PCZ: ^]"pLL%/w;?EI}EXD8E9B ;Y2 ǀ&v3E �p/z2èyw�i�ndlrd0A=rBx,e%s_`O΃0�ߋ|�Ln1ra#IaYE+c<Vyc˛o9Ta&ʦ;97)KmYjKb|D$8(^)(?-Z|v&_+ / 9|P:P Px !0ŵfZ2x|3 x舍 5sNuop�p;wxȰ1s.Hc<a \U4X %1?aDZq]�>/9|^eP<�,?� u�^;O�]>;/�4LO'ո+)DJxz%  ECx?7V`} ^ryY묚bIƖhR AH) R AH) R AH) R AHM14L6y͞lg<6y͞lg<6y͞lg<6y͞!S1!jmK6`XxMlg<6y͞lg<6y͞lg<6y͞lg<Y$1sΣЇ|<6y͞lg<6y͞lg<6y͞lg<6yɰgFXu3fj$,"Ϣ,"Ϣ,"Ϣ,"Ϣ,"Ϣ,"Ϣ,"Ϣ,"Ϣ,"Ϣ,"Ϣ,"Ϣ,"Ϣ,"Ϣ,"ϣ2Spy9.p 7qnw7qnw7qnw7q:Ir 8r�;77qnw7qnw7qnw7qMmYb]iͱnw7qnw7qnw7qnwhq(֕/ތghBD- DBD- DBD- DBD- DBD- DBD- DBD- DB_AAAAAAAGAAAAAAAAAAAAAAA7a<?;�M.,JK~t [Xq9L2{u'$f,貟~),貟~),貟~),貟~),貟~),貟~),貟~),貟~),貟~),貟~),貟~),貟~),貟~),貟~),貟~),貟~),貟~),貟~),貟~),貟~),貟~),貟~),貟~),貟~),貟~),貟~),貟~),貟~),貟~),貟~),貟~),貟~),貟~),貟~),貟~),貟~),貟~),貟~),貟~),貟~),貟~),貟~),貟~),貟~),貟~),貟~),貟~),貟~),貟~),貟~),貟~)`48~p ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������krb5-1.16/src/windows/leash/htmlhelp/Images/Kerberos_auth_serv_fig_7.jpg����������������������������0000644�0007046�0000145�00000016052�13211554426�026212� 0����������������������������������������������������������������������������������������������������ustar �ghudson�������������������������libuuid�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������JFIF��x�x���C�     �C   ��l"������������� �A����!"#1AW2Uq$3Q6BEa %4CGR���������������)��������!1AQaq"B� ��?�"" """ """ """ """ """ """ """ """ """ """ """ """ """ .epf_?^ GL#f-rz6^{jƥK+2&17"LȜ.Dֺ=fkonM~w`&p�`?w?# >/fvoҴ,Wlh#zH�w*78>pz])�̥c};>fw$@34&?dcNo*>`1pMR8?w..B./V+�^f�TA1o⻿oWblY;-S6" BNܰ?A1^zX~[8v7 5e哆w;P9,_\2dby]3fP=EWΤ; |w38 b1TxH/pXj6)&q 1&v!vwggvt,1~db�Hh/[C.bȝS&rd`hi0xpx?yo`2pdaWd#wjNpOpp,C&. QW8m3 c/Qkdlx#&3vEWvok/Q=5cR楕ck`e  Ot@&xNwYk]a5k7 w;HO[\ �j^Nu;7Zo+Kc4bH$kYȄ{@uWh8=.�R1zn>NПs; oUNDVU'w7} WdqqVg&)!�3*r ڷ]7|+ju^m6,OzRB߆! c'nXLjr �WuKX[y?]-eֻr;DKV/X2U1[ <(VQY٢+Rybc>;Ŝ rYmvJ8,UIѓ8;;;: ~~ʘO]14[!IdN�Q9~j4PU<~8|<{wd820+ֲ'fg8'8f!F~Yw Xn*}%jC9.AV7,0 ;>Χ~ϑ_Z7[PѪ ,3h紸p:sRſsv;l'L,3 m cAzB{Ui"2!01wbggggZԥg\s+ ֢rY~[ѽ~1'd0b'j]6鞉/`u5)28XYbiNHI,�~GbYRE+P-^ ,55n?']Q{^"mm-/^y-ѱK\iz,>\лfoi^O]<kf2�Wv!3Yb'�&,21ꝢTF�s[U䰅`*xaw%r'\!dn"wobc2dAo 1 X RIA3.Dm{hLN2EloP�b6{o$PJ�oAy^q"/ ;)zoB*ϖY2x.+R&v`]~9-OaP(ad&A$.;�E 8ye0&`by �uFm8jvk:5qy<m$; ⎷c OLt^K3رiXlTٜD)aK#I)De_Z2;_9὎ $'0Ǹ$/;;},H?ƍxOӓѻO r r)=wG4n�~cih�'9>? "#7?NO{OF<')Ȧ?ƍxOӓѻO r r)=wG4n�~cih�'9>? "#7?NO{OF<')Ȧ?ƍxOӓѻO r r)=wG4n�~:؂VT9*c_޲c~ 3 ;03ƍxOӖվmt;p&Mb1)% cBH "g6g Nt*Xnmdɓ#%_awB0#mbby,}/PXj$SFB&.B;:@ZjyL-o5@;x/v+?2FܺfxqnotZ}'`1[Lˉj0Xob'5]r2[Hy1=31y=sl>L 6BzK%vybj|E``zI__5ff)[Z/g{B9s|F'g=^sb^}6θu. L.f'>2`8|v)XA.}2{՞n}W}K7ִK$2&) 3UTf'oQTloP�b6{o$PJ�oAy^q"/ cֿލg-ӿ!ZFRׯYݘ nD@DD÷-J)wVn3Pcq2s.]!w3TqrVgbnYdvu2~n?go/{�{tJ|^8p13,�rcNFK4qW)֒Z<<{)]rz /?%q}W׫�}=^|l>r %G‘* 95h{VfJ ~{$OG*ݢԧ`>FsnnCnEVvkӻ{rϜ<fr-<M?ϗEكV1Y\Ybo+$24+AL]ܘ,NScBgNIQUݤ=:qyKR٣[!Ͱd NyR&1Hl8leZ5y jĖ%qf䐈̿ԉwuyLmBz*DsصfQ(cr32wffgwwfgUOY{{HR͓s?\^2?#M,l bFĸoW[Gۙ ̈~V=f@7 qccb9۳+U,VoXvravg'a"r'�3 �3Cҳ5sy-pG%\ш ='BF̠$�QyZJ:vJLG>_f'ŗߔ ؎6"{'wǕ-c᮹W{|�6O%o~?{FB6?3pwu" ,ټuܝm{+5#JXbf~9o^1Qe)a$�ܻ7?׏v|ŭtij,OC,iyVwyg x߰E�U"=<f+W4=qO3ݽNm1$uȅFAg]ؙY~uFvz {dQ؈ch7.Eh\G}w>sc"ɒ6ymG#BOo>V֝xj;i1sSOOzM֌ ]6\'J^oLw<U]rdY:u's˸7%X;9~vcq>c!.Sg\W5T߃؈SKxdJzO yJ b0y=zATi͸떲AjAǝqyy=#gvW4 .u/(taɽ,5 ;�bpm]y%b\&g. N_Fp'TsJf<e +<,F1,|Ps=qd|<ymݘa9vf2vfݛe#goHdu=ZEV٬$ bWvyۋ#|Vj]d~fwչu'(MDUr;.#kZR+9)^ 0ذ;\"g~LY߁gujjfׯ<M)0 7.DM3?�=k 7�X3#c'p&"g'ល>S Jݜ}TD&tNB:|'fS=4-Z"�\EPV#~љݹكv|M\!W+H.Ҙfa�.M�Vu⎒nO7 PɁ՗+[>n\ے~{X}<37g `~5~;)~g(.n(QN; uO-90`3wi oj;r#-é]t1;}G�c;?WÅ4\_՝u<?h<?!K4-Fc o#2^FȈww�OoW95?Dprq,BN|wMoZՙRb^ʷhu)'۸ۑvwFSpm[1ltI~^RCr $ ;W Z!giDؙga:3k4qrKI^Jr{M>Xxwᘽ>$~novWު!Rk~ 5yha ܳZ莡nRm87*椦򖤈)^7~"qr3'w"'}a0y (Tj̣P,fd"ήW<YOY{{HR͓s?\^2?#M,l bFĸoW[Gۙ ̈~V=f@7 qccb9۳+U,VoXvravg'a"r'�3 �3Cҳ5sy-pG%\ш ='BF̠$�QyZJ:vJLG>_f'ŗߔ ؎6"{'wǕ""" """ .dp#?YQ _&" 5tο͈ijv_ЮDx;F|e=2B߇xܜ]]ۑn?gm[ySv�י^3ץX\L?% ڭ.&$ʆ8aa.QH0]Y"1gsG$V&pfF\^9�\$᝙ǸgXx2WElYIdZfZC{ 1q0|?/z,wNRcN >;)&jId3Xv'.K.Yϖ+iT3W9s8{=h`Kvk0AzWwN_4 ܿܯz-\T ˝Y�ဈX|ǫb';g 9e.dcr]#ز5½;B}6)?QfɷW$a#џ]ys>q}[/O`Pݔ !$J <>2}/cPZ*tF0^�` DEJ+EsYNig#KL` !0/37ܵΣՍjMeݬL-z }eD?k,,iDVa1K[wO(9ᭊX"Zը+b|SJ ,RHݼ?{k-U %#1<Rf8;;;}UU%U}yWFtrv5.FBvȘԜ[vWIGyU#8EQ93afoVθ!cfvGgn_;W׺{Ҿl@r9J .~Y NF 9㓗`/<Rv;w޽~[WU6 >!FBla�Kz v859=|R7/|5k~3a[ҝwYgG<�emZ)YJ8{}�vDD욮rXgsx=j9<B$ܷ?ܻDA2f-NHhQHQr"�3*r گ]7{: P~={UUc؄ęٝYP ,?c3%"" """ """ """ """ """ """ """ """ """ """ """ """ """ """ """ """ """ """ """ """ """ """ """ """ """ """ """ """Yc<10lPi12fX"iafx_ �7����-2��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������krb5-1.16/src/windows/leash/htmlhelp/Images/Options_Tab.PNG�����������������������������������������0000644�0007046�0000145�00000033144�13211554426�023371� 0����������������������������������������������������������������������������������������������������ustar �ghudson�������������������������libuuid����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������PNG  ��� IHDR��G���s���7e���sRGB����gAMA�� a��� pHYs����+��5IDATx^} `$/ya1,%+HmY We ApkUKZk)UkZV� Y\+"#D ;{ͼ7e;.oν;9s;5z<xWm{ư<�-Ӥ~cC#PwVo„ὑZ*xvҹʋNQ F+iNFp(v/j!mK?Z @ yosM*>9Jځ׬Rkr#9 t�σ0qDnڈs)}j!-5~;8n^$eRz& F< -rDy!RQ?r)ֹ$ SD"AQqxcV\5nPfyƽÑGQnKGvb뎯KKݻ#rBH  .<j9qmBsDi."qr4Ӵ)5$)ǀ&RX\7yHSh3ǎŎw{gZzCm~Hp'i=jBA@hxU #ipa MLh K#T^t17Էb;h:1Xd  $QKM(  <=ڔ#Q/Bquuim606jx OY;3PXCoa<blHϬk7T]g JBIA /mi5 EMiK)6Wp8餓Bp@=rz&x:.j*M+j~ꊷ9qYq+H;G_Қ#qH'u$ZsQjZ\uYxA!CDOi B3á'"۪Z5X~|ΑyZD=ƯQxl6jF^S9c9GW9RENFA !;ZcƈSo}JoM|sT(4!zǘLڢGk(ik#&3O0?<!  xB Rڟz^?^o<Qf6Q!p䧁bO b<"I)Q%{ԁˋ֋O6Sf8ciH6/ >q4feV]zHOҹ9#SƟzh՝A@ goVMeѯ=0 KJ׎)16I[mނoVyڴOѝtcP|lO^H\J|߸<� ȱ`\5  ٴ k?܍?ڍ7[.ۃ}\U͍+ZNw(]8'BQכx{=xs7NӚM_cƇ᫚$`ˑNVe"LoMk%^E/wK/S$D_�,3;4yKz8]&/-dI2"RhUaS,B%[#=A@xS|HQȤы}|t06`SxZJ�J̉駦Qt4I ݴTjO#xJ!s]~d;%ވLoEnw 7ϙ~EZl{45_ m~;% Ex]/ o2t]SX<KEQ xDЖZd:<>8F1JXqx+42T(u7=p4PdIʵ, @*H9B~FL:}tN%:o:y.hI#U5/c&=ytT s[>;m ySAJģq:v^? @^DŽ﷍nX55J|pgSETO6Cy֡?8EͅAdrJQuYr-8 ם&(sMkZ`'| ta~3)"Hs:};ym?S燤LM)]==1@5L9]sf8KEJ!oݣZ st"JIajseZ-)xK# "#?9. ;<jSgan]G'-|WԎiSN;SsܞjP|NgGh-o]w^}M ZSL(r?TU*T TOWҴ_xQT><F@șBLK](| pj.l  o)b'S)etJN vjǻ ;#JӯJԎ_Bc'3QS$rR|i.\~H-f>:n5W#i XD |bRQ|xIe Y*Hh69@١{o'ߘRSHEݼ; /eJ`  ?^ȑ Z{E))ZCgq Ľzy&lSVX#QFߜTy.C P$?Vc ;qb{FjC Ewڄ"on#+l  j"uNEfEp W|'cND|*8},ס Vf.%UUm+)ăO`>ZD 6A@A@hn<V66D<}t~iշW,*ңDQL&iV3ף]3P۳9D"z6%=|F@=뱵j'f9h5?rjI  $�/GuTDkJg2MO˂>q=5q{TeL:Dl  47^NᜰCZ@kh*L/%k(90pҔs& }պeWh6  ͅ/<桩4~0,_Y2l3c2E:)5N=786@ \ VG`ޏ#0zX?/ݻu(#yҲ  ̀~mTD`|nWZidnT} =QOɴ~ Gs^&o( ϡV_  |<9J>Ң  Z<G$rj#  @dA@A@ȑh  6Ç%_ ZA c Ю 稣^]S:8|(V8 ~zSl ͎gaw>33?1ב ͇Ȱm.uQzFdH\R݋okxtstݴiKMMOxounu\+Q҇h22+2ly19G(ΑȷQ9먒oN7w{r'!p~/=ѥ7nw wCZ$ H2dV|9+)"$ƩT~ y7gSD-,ܼ^~;z\:Tw^F[X9MU) /F>gʤ6*3ːsAA^Q򥥺ZZ‹Xe7ൄǬ6?M`CSecI&~E*Zl' =3_yx3cyXgӵ˸DP~A^i渀%R'";Bϭ yI~7ɮ /}*g, {jjݫ?IMDw̟'D֋a80ݗ 2i: ?GA-alKf8bZ7]_U_ 9Yf-XU<Nf WdXrwi4_[lg4m(I&J7cotWl<Fy7 ZdR/kDЏ#kr#XgWNqinrɦEcGs Ћв^M2+ffzȢݻuŒzqل@@htBj9薙BI[Y稨FiP'.g/ |>oY,43䧵,~r9⨑- t̿Ai N'YNZY3HF݀YR0Dq 0Eije83v"腝8nZ_+hL<N?#۟YfndaO|+b@?-^ζǶi'CNzmddO6z +F`q rB꯻D+)=Տcmt]Aa=Kض.v o{}M{ZfBegpkǮdL bjnC]:gz]"[J7aLuYnvSCgïMI7cm<\.R,cUtێ<yGR'CO<' N:;}ESᜡ98BtB+z|SF;a%Lc+w\<Zo|:7x*n>-1J!v2)Zԙ.駼tr8w)C)NJߝ[]6`glixXO]L;q˻)|1|< "Djk)N0SqWMX1=Wm l68|ZԵ\Ǡg4 qiX KNL69O<LӦf3^# h2P,HzACXL._viNSNV=s/x\( }wl3onj\<54P@20fJ4?k2[i t+ 0>[=MV2 &[wC̚ryh tSc[KlcsUNr:_t6cߘ3>'y7E'ijK7xi9G<ZxNK^Xi7wv./e?/63zb,{RУS~]|\e8&0$W*OcT0ӟtr|>r4ȭ G`c]QV\(&KQnG!.l9E-.hzaBU?BۈG'!QM|&jr=q*2l4s66h}nRkj:(GNlX=T"4|<1p@O_O$[+ܻ S ?Gߨ"ULZQ)&`ʶ7uetz u8ˠ{ ]B}wb6ܦyLnf},luV܊ퟭ쮝nƟxtҍmjlTÞƜ?H_-䨯qCiJq|]k0sբO =`Y9wL(ԘV~wgJigL|h~>@jJ|Wf.cwm=ױ;>K/Px]:vrbn|xLjx%+r%)#8sVţ~FӯP(&TQL7O_JvIC=+oD{`"ushmgdJOiIlaiλ{lanD3c,tX)**IdKmmAUɶb7788ƘYh9 ~N@u4 /i4xǀu4k+rsv:R'ꎓl4_˃Ntujuuu))I4 kTXapVϞ\e[h^> 5.1ݒW>H66j^^΋F!:K~HPe3QwSˎe\ؘÏ y8*h 0u<-L V>r7v +MzwU/\ƣ~F7u;e.®i Pkt{Š߽ y|M,kC>߀MZn.Gƹ-+}y~]h7cW-ӻE&ۊHSkӽPG38XUPލe`>jq`" ,^ 1>`OC?XNvc(`\Kݱ+\?z[QyƠIm >b^E͞]pF1o>8ڃt59GZҪɱysԂ帹K*sNx~6/6 OOᲔH)2Nt_u.?Nh7m1B]vcϞj݋}BZ<Zڍ6ۺ<?#aVrܶ|v@<d).g1ʮVޯ󓎊n! b>)z!7jקxt:hʫ%Rʉ!.Zٛ-í } OSONHr'l.8`/O.Å/+um8F+WGx+\b@fK.7:n.G!-u//3&,*c@4'R/c|M|EteDݰ+u)goὩ/{꺦%59zn /7:Rwl:aWAz(X٤6`jQc7a.l2pby+i"`a[J} _|1֭ @t~F:9ţo5Pt/V I+D@t/hK[@Kź9:kQqj?VR>NKfv& u�ܾ~ qV (<(Q"I5?kُƛH{ҽHIXL C^w(A5)Q'ڻnK  hx{մ�&G icQ>˓|EA@'k9j^hgBeA@h~$NK  І|&6$.a!3EH䨣_+-jVk!YA *>OpZHLEL  �9 �RH́!c͑4BSp<s$z!ZMΑƴZ1 c |Gv&SN;B 0"Gu cA@Z1sݸ\G*4"ö(|K BW:O\F^ i;k .%*}*qb&9:%rMF]@ @D [ߛFwPtVSُ7oqCZ$ aN`3^*?݅^XCg'"ɗmjǧŗ_׷N>M <ܺI.:Tw^F[X9MU7g+q[ 2V )<tmy4x:(|xjnN~2f#֦;,hX9ɗm5o%_ZjhۨY_IpQn|Ll*L 9 e2u3ra]mYxs}"W VsaMiѵxX̞i;]+ni�~#6hn\œps \ޑ^m4ݗ 2~ZjJj$6Jgt<W1m$wK#J+^D+OGъPŦċqXAt ):C233гG >tKVneb?ޜnZcӵ|JQ"Y{^J(ڕxPo+&. knovS8:9若4c*p f=6_.폝˘8ѫ=Q!%r9⨑6l(\bWm7Qnk{ntdo&#t0k^>c]//'^6't!S/ROZVsg0w =q Op ݱM-z Zdl)m{<;?knEcw)rV%I:E6ΙGK9:} crĪWP6(*/\˹-NKDS{^Y/A5#,5m,&~Dww?7譛ѵG>2Ԝ6Ymgl yx@+؜7%8ϥ~W<(D(J!v2)ZԙndtSa(ߥy 4o.!w6UV8v,>]ͺcs-'cD~U(0k,p  .2t1wx_+1# bV;ĞxvF<xv~~�/-稑S Ti<b~~7̏>=8wmQ<}U(y|n ~:sDAM 0mDr>69{Tt0�%6Vbۖp> jOGf.FbÜ7s[&ZvtpI%N$"KKi3Oز6ѧ<]pDBǡ7LK C?|>iΑ[5w>{~B1M:٦EIvq=#Tw8KXƁ(6ko_xm,9ZؤoQWk'qv>~~6Qec)e h1yZ9W-У F#یCZ6ݨDmbPh@2F1x9^xC]9J񴓘:a~63dZ-s䈧)))*4Fw:/n.ťMiШk;n._Mt> A@h 1?VWWΝ1F84iר`-b(p#?gO`!o:O>8ŨI46^M*0>GШ"{񏡚CnP zο"e əa/Cg9[ fܹ}c[EQÎ|d6h8eպ"J1!bd[F25Oҍ6-]v='l)0>e:W.v!2ғW.D ݠ63} [鮜hm:Zj5{vAuV.ƜO�jk`lRs?մHsG#EYœKwu}9z`бz]c:}rO45?WB<0pQzV1#=DOչs�ϧ(S/5䃥}ގw:\fG L=?tc6F]7fke`JVr܆kxzYM2;%vڍ={Qw/OJԢmT;5[{dhzmf}:ۊ3~D.Ec|#QPz,G 6# }ڴcX3z%muqEU_4_nCqgl ;FVl5o)?ޑH>U;2 <oк3D/%m#7>^佷FsfeA#9ZBQEQ X.H ʏ~N|8n ra dgst sHT)t l]##}ZсȑUA jA@A@Q5G $驁5G%iQKq:ܥm.Ahaqڈ؄MA@hȴZ/ E@)A@A#Bڸ v@iZLcQKA! V$ aEA@ZODZ^  @WShDDOA@H 5f&]~]u 9A 1]7mVMK "  t9:%//Z><[VCii)HOKňa9GwE(K :bO#A@hZSaN9} /(9ΘRjLN|;+`ɣm\gu۲rvNe 9/$ڨfckN,i|0c,qӥ?R} 3e<r#E)#ĂFnQ׃t_22|HOSi)Ntw [^˟峦w$~Fs,~8שlovNeCYwK%n!em[lwHUmas�sڄ9eSKR4>l72oqy5oA-F|"l=H'e<K'!#xp+rzi -U9C JsQ#EFMϼ7Lw>=s Uۅw.]PeCN1^W6o_@`mΟEXgXۏI&4M0rW y^=zv*X0Jd3V*w-6 ض6"&]\ Fe}/v10+lqorꎲ31;GbG(E33Х2NG.xSkk^Ţ+&\Uanu1 ɉ'ƭSw;q G&ލ r>Pm\ӝr%. c5yC֣BMmlwxƈ*NS 1 UD[G+Ggb/iȉðh,w'l+kv}XSUvEE3>ٿ܄Ii7dڍ";cCHdE/  #}#"ϧ#9p8O+hJmi;D5 pĦ؞p ^{fƏѝJM#ܨDk; l$F#3vG7"W VE4"m&G ox kTEڹk46+ TZdN}6(gӚh6~WkilYzk0 D fJy,-5)))*q6WۨY6i );7c~XXK٨mQ/5IFEΧh` 1(1#LRIZi7;$Rhk c];P(ȕ(vIqA51;Gj]T9bLj?ʯ9PC@/Vk:鶨ĴP*}sSy~Լ6^,7*R@hvgfVi=ٿ Yzg3mUإ6NTcJ p"WAuds#'9\\ \M&G f(#݇]vcϞj݋}@m-jDmA u96XBjmZm\L]Cw Z'nޣym!2cXxAEA Q$Fk^E5w D46}*hkits"ƑEϔ1Ƶږ>Q*ߩOV*Hq/g3Blm-Okaӗѱv߾:.Z%S{ ۍ_ye˻+q@=%FESՍLG 419G2qi'Jd XXqF)?MƋyyt Ćk(6RZ@,Q" @k4A@A@3gJA@A f92  qڳto  3 TA@8GY7A@A@qbL* @{F@,]  Č8G1C&A@A=#2w&oU?,Sk!anotK4CKoaÿ?TOJwNZs pJf7RT~ yGI�Xڸޜ l~6}[ǃh@(/cS4|+F>RóoqyT ^1}Ś6fkϡa}a:nm 6;têP2S͸`i{XTZC VNly:ƵS7wNHػz):W{3EvQ"ۄ 0q`GE}8c)ώ_;*[N9كwFRt_eo&-8϶lhM$IQy#Lq2kL>hHYHJo-Eտ4݆رy <ERcCǫ6G`26audQT7rrjNpNR F_a{6ac =+ {jj74V];ھΛ#Bv: eڲz#`} EFEQs, z.;B$<Qk>$JJsFSvbdqߌhV�B ؾs)̶jvkg(#UCƦIIȴ$%|cc84}Slfv<Gnl}u AJ:}$d/d!/$jiDЙ:O>Q"ọMWzN4C7rVa F4 &+v*^?vR3x$%30#A4TCMRe͍?6Jc\7tgDžAn6{R4"D:f9u;= Gǜoܵͺsa0q&r(B%zt2gHbǓoRڌxe7~udl=mv&!*n79iH(BNP} -PZkP*gK7 ֿdF!a UM(;ZS&yU=h֙ѫN(BLD0qGmNe#1"cSB$DZq V _c 6G~PGǃM;S">.8upH V*:P3Ѳ( =R� yi1 rF~= W՘En|6ނ K N1iWEʧUCƦXӞ/Qv%ѐΰ?/Jq�{ɣmR´ 26Zn$rԺ#up!2RB/@QҠA@A- %QA@糚-  @kGA.qZ?A@A@H')QA@A#)-T.%OA@?u5C;1����IENDB`����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������krb5-1.16/src/windows/leash/htmlhelp/Images/View_Options.PNG����������������������������������������0000644�0007046�0000145�00000012610�13211554426�023570� 0����������������������������������������������������������������������������������������������������ustar �ghudson�������������������������libuuid����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������PNG  ��� IHDR������W��� V���sRGB����gAMA�� a��� pHYs����+��IDATx^] xTյ'I0y)\"(B-XZQ()[ >b  NBxyR@2$r:3'̜3N9k5'3 ǹ[[!@@ 8ZC!Fb+pQD!Pl:/"pAqV8dB!�9EUl@ 8u|~Ӷվ{ma66r 9=3gʍ pEZ3CN!ȆzA†!#vEj{ݯBYObCd<jҒ%:ȟ Y>Pcc!CUذCbGjճ'2\QF5}SaQp&R4j:n$i%+;ThX ڐ_R5!7R{^aY۔gaoH]OT+j7Z_TRxf\-xu<z.zt*9븅,3"!! ױ1RX ߿?mࢷh<ղ!W̋צWiob}ŏXv1Э ˰QQQ<?5f�sPY6Ix�JMyP/ЬפqUյW6d{R$dLLN1hmTlbh-6IO{ gDc^b" eQmy4<~ ^x*Ͼ0?z yXaKG~5ڟ^9!9ZX몁Z7 W_#C49o9Rq/3py%F'7`+?XU2 {umKN5L E@v$p)i,eEʎB^ ^;H3c{Kђ>pzJjNJ5e4)4Z&Xڼ lP0']絭C3-詷w#ϖ}h?r(BZQ-nQlru4=4)UOHМf/*'&OG՘mƴsxz7v%g-];ew?LJ`h;V\:"G5LꐉqHJG<9b\\䌲CZ,.7N5s_lw2TjṧWm6v *Q /t? $]_u4۟r,竚441o0COGqe.L!9 xr *7Jy:F#i.5U xs4}(b5 ]s4T-uNam`md ׎nCQnlx;\/ =޾XGTzytCryUdT6Gw?D/`qv=2;QE۱CmO.׍̉ܔUzHv:!ێmMlMo[ﵱ|30jPC`O}?ٷcTo^iҼ{h?}P'&: ɘQ:rfLmjBss X㐺S= #gz 8?E%Wt={Dl5=gbDJtoR| EZIngN7bгzPø'OF9{5Ų G6^>Y:uAoU4w!}̾XBnI@е$c^!c=<7L3OVT={:O_|M(<5|>ç)X?ÿ||<͎E@o@ҿ-F .4.{Yホ{i1CGg6r932cu.[A$eC:̞UX{- >WߐCfCG &XDiWSV<@@ $O!NL?\rMC@�E@ 68>n)kXC(Cu"~�G!B�Ջ)@ \启{ֶ?/ma6!Fi!Ca6 ˆQF_&5Ꜿ+ƭ"Wv > mܗA}mjW 1kzj|?-8kUz<t|=e +v=ߎᶯ b6V:0|S7sp ܬËzFzg*ĩfz1d6$;n!ͪNfoQ?:gD;VC\%b<6kWΑǩF's>-2_-[L|$X;FՆ'^y WOfk؈x8[]nvhhCnCC=a축d*]9\1ART+[U: li ƣu98UE>5T&LY1Eգ R&15G+*e((o5EU´=,kFS/oNU]-bdT\K;f<<N:E%eRK mTKݤ|P|*$c˘/.p_CGS Ë=a=hŗRV;UHv"R%bX|؝/k-D4#8J>9T6望#F=$MQqwH0~*ֲmj[q;JI%=RM&OH@!'4[VvutKa:'9)'Fg-؋ڽɖ:29h %zcJYmU7(8:`b05cprF5zv>r?!iSq4 o0rB3't6 OPئcs8WGZjRUu 阶IOWf caثv}V`t#g<KP>~ Rlc(Z^VZ{m 0m >^=j[Md'V[Ⱥ&9e =9kR_ٲU>[f:y=>tPvdu}:]P)sSVM*;O=v ,ÉV:!A/ҮHNUsRӯ;IS޴~9 oTR>wK-�.hF?jvȈ?auxa?M'UvGKHˬF]l?)Y):|p/Ckc\Z."y[6>g; M%pr0lDDjs[!LIH'bE:†VN8+¿4c6ϭGȈEI,\ Atb�Ef!#`@#L8dc. L)0B@8dC"p|*RV ႀb @pT)6@ l6)؞#&"DwCFr& ضyrXf8F|l d3KD$A?V׮Tdep 8r@o:cMӶs>n9NN.‚9x88hHD)9iW,EBBcױ1R3FOK{|ܳSQA)٦zg^ 3xy[om➭2vBt4Frh,`)v␇{7LǨvFFtZ&NzR };7&H<W،,B+EkA (ΗDQsRtJDD''hhA<{մuNl:ä.ܵ Up߂E81CLD# U$;I)ƂL.#@ qC&!)1qqq3`ISN[7I (]G'ɑ F"ٸ9Wq40""! $;hAb@ A9$GHNMccb-uNaߜZj9| =!*fJ*5vƿ\}J ޹,i!a@P)O8$;#wޒƭ5Fvz *<\dF`w^tɔ2`I#B,:2!>'OB}}܍8s,҂V*R#𦛼lD9e-s>`Qs›\kϱPXIqfCa8lY` uuz|@໊m Cr3kS4@$"`!# f@G"{ȎTPD!#bapȰ7P0Ik {CpHXk# 2M$$CFZao"`$! 2֮9ŵ:oaŖ2Q5oQ-vh,cFO3N;qԭ5t2B jĊ^=e IܴIa~o'^:M3Rn8eJRnX:;`)'�g'C z{Am�m}uz!Y"}r7hpeTPwR9Ġ[NE߫@G$:okınu" ݁@' l:Ɣp9yuTK|a)jX:[(i-|Y >$^UBΠ o RV+(YWz-jj uL15_FN]_*)N'ݍ25=M^]U+_}3ίCUt4g/d$kM{}oR 3nD&Ȟ4ofyN8͗gtGkSe�#P8d+6<9Di+5 @(lpImSndj&ԑ4މ HqݠAdG翱<=x^d: fAD!#m1Kk%2;" \KȖsSޛ5):`/GWչjTr%Jӿɽ1"ɥtP${frSZu]ErJz!k7j#:C^0p P*j:O*{e+Ee~WFGN-͓:oOd`2AA@8d;lg*@Fje8"#ZB;yJ[:GֻUyוյk⎁nJ|@k=]ސDGS J^݀u5FtUu,vk)z$�hpT"T*; aoD!DBHB@DHXk# "d؛H(I8>vm.k$#*6?ěU����IENDB`������������������������������������������������������������������������������������������������������������������������krb5-1.16/src/windows/leash/htmlhelp/Images/Leash_menu_options.jpg����������������������������������0000644�0007046�0000145�00000043776�13211554426�025153� 0����������������������������������������������������������������������������������������������������ustar �ghudson�������������������������libuuid�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������JFIF��x�x���C�     �C   ��N"�������������� �O�  ���!"1#2AUV6QquSW $3a58BRsv&bce��������������+� �������!1AQaq"B� ��?�f-Ud1p;]\ulU�Oh̉mklx̗-d.*#'BQ<UGسtTRDÛ.ԆpvT-U6TU|Mh_ksHx}e&3UaGHgSAl8pI=iޖO9BM1̞ƾ}qŅ1[qpEUAwMor-f t?5{-|n=uA!#`"('kDMYLs wJm@*<S˺}uZf}j°Vn#K 6UPMgDT^*ovd^C܇:oߪ +)wYl{=^) j{}5ՓޒDh."(4wuMw7 osiN$ei$be"2Gdظ*o|ؼve\EXDKP܂Pf4\.([ |*T]=ʋ:OF_ʸRrUߍ1ѹ)!E]ǴB8U<@gc8. qQ8fuS^*⛪{I曮ڦM|r�&amrT*勭ԍ\TW}($M Yh`ΡPC[)6! l8$̑N>|]s@UMf=fjZG1-"b8@wcU7DWq4^y*ʻ84! > $NMR|}|zSrc>5X_wcouTDQ!$$]Gm{d;"ӄZ] ҝymRx6Gi5Nd{yjiKY7NDzԨ*+̚ESQj/`U'U57cmTtو1AOf>8P[uQp9ӂrOUEvWo=vVn2-W6_]/}R@�q$BN~D*HI|TUYu bJV? Aŋ1`$J{h>iy/C ¢~+`zCnru`TEF!d 9"bH\ȸ['RS�*EǺ󵩫 z9ݷV7xy;*Mt3g>0bɌmEKDD_hUGvUM~cinhnsD|МT/aɨڳy1iJǫɱIM;D5!T 8~.N,w:SPN9Lzg惘l!"oˏm/;xNOm[3aW2-UQZ4ExI$l?y4r%}rItDS!TUDT/[Rc,Fԫ5q]q"DRCTEDS%Tu,eHlh"#"ʠQSkrv]sr6 @}!ٜ;,-wTpּ\k82&%v-,QVex=vw US\lZ_h=)Or0pW) /k[:)Skv=z9MBd0 E^KQQnҟ6gM?iw\dB3+쒢쨆 z0�1U�5 -'=z<~,Ƞ@ڸ!)(m4a�c�jU 3iiiihiii+o_7�fVaӍI7ֿz�Y5q2B0^�'ֿ&!/S�Z�i|?_ gt�4>�y?iF ֿz�Y4#|?_ =Ok�Obb,>"�O 0kj߱ZmL�4{ڲWju:7[X1K`D[ *Ȋ"*fq"_?n[Jۖ�R\ Υc]!zacJ^h"vUptEVSsJ %U`;%Hq)80"yoס)i'EXrWOV(~ܷw<$R=zD2lg$g=eI �BoLJ t~df$Ɯ7GͅlQтQTUDT3PXrW[$;JQ%[*9"l7Z pX,c01"뜻"6jT$*m9I5&7_fG1iǐZVtHU]EU /dUU?bY�~@G'tzc)n iH$і k͸MwD#&Dm],"]rjH%OdX’d{Iܽg <F|=r~Y* .[]O�/TEH߃ecvې\ld0ٚy{M"rMuuF] 6IdSn2E4uYq&Iだ"eKc.<UвoQ]YUWi?k*PSy=ucfgݹHq6�n$2 ^0NB*D /r\,"w>C&wdEțlTI]Uq]T}evt\'~/pC+_e}}{m/YE ;`}VI &bD;"yުZQXK7zm}tJan\r86g *&wL9;;\YUWi?k*PRBؽ^[ɂԧ짣MRȈD0m7EM ^~YU8ު!܋R>Hq{>ߒ>_ 8~U~ڂh <)"/BMTzkoI I8~U~|gʯ2P?k*P>3eW_}_M; 8~U~|gʯ2PwHGpC+_e}}4&YUWj7&5o TB(DUtE./ yy*/YϢ��]eM544M�M4M4 4@4M|y'''jm"8*$***//кWkW!tƞ[+T2rFee̕EUUvDMn܅Ng=,b !뎞�"u]Ȉ7t~F[>ٓC|(*vM}*ma2^☷Sʟr~îf-2~k y * tu;F~Qc$bE$M8H$H$+n/<֪*ZS*xel[k^,$l2WMG%s}.q� PRGqp􇥸4%95!D/PRETR�] Xރ3_A!}Y�^l>.(nIhQvOwm~Lvu0ݍE0VE;Xs$8lS~{Ft5{)t"J^\G<Q]G3%$d'yy&쟤R2#e[FsĈ"3ʊ\L7ET]7ET]RixɧrFJnj¤7}Om/B) niKiq[j"[8$2W0G{fӒLj G}w|MF]V_3_Ʋ+ʞ D[>Yy+e{hA!Ɏ< "Tay (5-5}<Z ˗>uIIWvTQy-5S0[E!Q`hVbUQtN6HTi<8{܈2],L^ fJpeNFЄ}xd2HY87.AȤUTU7]H8YZSɲϰM48s\crDw^;.c·4챛(U=,`:HVm7C6QAI/{cp=3;/RvvĞQ><W9kwlGݯ_0aFz;82Rcے@d>�/eWyz':7V=)IH c{ਭsqmx M^/Å{&, .yQZԟH) Hv4uzo=GA5bQJhvNbOgow׎�Vm+ds}"$Z8. !Ċ&"HHﲦ뼋$,OXU]EKMPnd]W)R{-)&I^7mQUDŽ݅0'^h\qWQC.뵸{}rDdCü8Ll1[w}1Y䂖󎋨9̔Uog[tCȯ`lD$"/⊩oM� ym>ϥM\x!7#QsbqK9npAepdXߔV"b/*Gu誚'oo킦{Zi:Hvu#1ۦ&WyTD9"/UWwWRYska<PWu[/+ CrMChIu!4DTkoTcȫ^Ie᧪WRYsj>*WRYsiԖ_zi>�^Ie᧪WRYsj|z{%G?^IeG Ԗ_Ժ}�X.lSm洏04@PP%1V T#lSӛV ZGͲLd�o8#w3Wh!oMq(M4M4 4@4M�M4WkMksN#]EAuX@1**n*kr/X㟛utS&)mgB;&,6W$Jj{ h`mhWմ]EnA?>֦^YS!X#vl7"q(F*b+!閻Ψ1܏b-B%UvQ4<ꈧ�UR]E7<g^פ% :&+H$n[ {Df<u ʦxn=e]NGPS͊ UEF]l'6 [;j+PII5_g{:ORL1&V!9>:p s{y!{ZXgeq}赝&3Ȭ׺RG9ۄTq$g[*כk>Ϣ+B@oNo$~3m3vuz4%hyDO=Xo V f1L=EfD_LiFr0A9. m<@adN‘Ը݌4DmUoe� G}Q0|IR13V*G8 G6vȑ IGqJXmxqǯ9Sl݅9Ӑ7uD'C7{}ReQ6GQE}<9nUqI~b"",vBO-4"֦׉n;\n<uogݬ F@4 1܇M+A>g4f~EPq؅}MБSQuV_S*Z\n҆<&ɁlݲtSRtIPQxIs*l>ksìK>ӷKNȰ'XmbDfP !#B]ԹrEXj�Od5/Ajo22]W]|"KD<ӻ=EWݭgl&U; *IUo "xU$bM-閩wSߪ0ϽA!!Cu2'8(D벫5F"ŵmLҡ,41g(@=7ܕ|sӜ&ɩ!FZ)/vx#ݣCVv *[IaH p&2#mw$BO**.#~|}G6fL&2KhaX&/<:ъwG�ЛU%$2R_YF ꬊ-̛gXIf6Q!F\t uYMEem,z29m8erC.G ]T"a_DS">(UTDAuk&"U팘O"yS''Q\we?ewFbZߓHY\,nM}D6HX<ZjC@aAADUT߼ɑjihi|GB6 Dbp bN8"|3#%ɿ;SDk%iihiijMhбŬ}xH.oF풂*!"쪊 jM`z~ng_ 3:q:?ޣ4USW6BВiW"):v}4ɱll2`8; G#rXQ$VST]R&<+ܶtW U&ȖLQ|DU_?-ez9%Sx5\Y_Y!THpRcm1l2UyvQ5?_)q_ YE-k@j<UJEz;Ʋ\G}C-ir[py3%dvJwBlNpO t/-y`Xd yETbeW{1MsJh(HSM!)[ϻ6[z/hiYRq&j'kr6CH0 e|dqG 6] # hS#[RrJ׽l4xQ|HT\˼[|)Ʌcҙn)Npٵ`Ѹ₦* n^~iP1|, 4MktkOmvq[Q%C@UD-wsݢKH" V>@{6DԶ$H.#Ed9/CJ_5&dKR7%EQ9{j^n]Al#  gC9n_`"<!1Tv/J|e;)OٯeKc^t[#Vd䤨ɺGty^}by%k??o5%SthC))a vv\F1hZ{K1rUv=;s#|H|:&) ,$#VmCn+en7iܞle*^@5ޜQ➲aKeF6,U:wYeLEϸ<P *kIjf}^^Jkv�=럆8/6s>.G�nN< #ǽ'~ /IAu}u뢗Iu*)?"Njfؒ~=FI%T_Zˬr4 JB9`h*.4\T m)ҕ\qN[mbz|~/zDi᣷gĶU> G"@<UIx&<閗ܰ8`_Mb~ʊnJ诖(4fۦhT^?K.pN>{VLQpɴ.H"*.b5Թi5ycfMڹdIEL QQU7u%-ULxӴ<Qܰ x@!BA7ݦWj{WY]1Bufm7E#OiMoW\馴gۓQ%vod%)UE҈+/%Dff^׳3Q?GGБI7D%#g+X'&馚hiP~� Mj& 4Y(M4M4 4@4M�M4Wk�<stݎWkQ,`xK\/E&G͇{7.yjoe w3PmD]"5ū67[vUޞz}f)oX?e-�K"f$fP֭b7K'Z\!>,mP^EQ|=6hh-`ٵ3SްeJsHQyr&'q6UU�Wg?Y~['5KXyݍqMȕ:'Zar΍n/ 7ܓ Š1xrN]↋U8 +,FlA^5\9qj} *) w}9NX,Ok�޸T~ى0 I؈l4}TZm;|*"mEs~d:*SΑ +-mjAqpZq[% *'Rg?e-�K쥿b}-3*)XVY=, [vb'EIJjgaڹՠ.:ϴ(-ǒ�mO,)fUW)vMNHrhܔ8¾'snj5K=f)oX$q7et?ęD_[ řF P Ȉ(Jn nK�KRtؙ;6ǧǤңbGVQmY-ed[?e-�K쥿b}ѯfo=#]UQSZȧAQM&}B@DM4O>Oafój+ҩ`CʬV+:8i[qL^Lj&k�zcR>�ZRϫ矑MC>'`)-&<iMn`4U6TD%EUD1t(\bƕ|Ѣ RИV$,9+n?9S쫇-I~X,Ok�MqUmDhCʬMdq!HUU),#QKh6U9IDm62_-{NXMDaQ\[Z7H IalWe욧&׊&R?e-�K쥿b}Թ\̧xz(lO |Vg9ao8qAHgT(@7o1Y+H9l 7r`x##EZ0�{%ȇ$E઼eY~['5K|>fTo_lk_쥿b}X,Olk_쥿b}X,Oik�zcR>�H MHX,OoFK:oZY>?&yW߫NdyFiihiii5�9?Y5�9?W@g;8mص^rO7\Dt#A9'Mzu!o N-w:UgᔊIHۦR4ӊ"{+稯R72^Uޢ'iNa3gKaePd<WsR׆q3yČ}&Aj&dnOz*zŐRwyP S'3NW]:]h2;9cl㺢o n~uPoEb2_\CDHEȓd<UН Ʀ�Z~5It)Gܥx%{='TPUm9~K.uGĭk<AzPw%sϫNnWdiY7?6 MUxAWC?^O0/[<\JHW XqG6T<C):[tlE+D8r7'iV29鋲.h;XwgT8,2FAQ ^Nlkw2&LZ5u]=,d�TNɊ:< r#uקqZK p'Mk }mFy.6vUWnvDˋhgOQȵhH/*kSv!u<MaSڧ‚(X֊2L+^!1Fm K̋!n\[S k+}F2Ip,Q$h٫hd%|'{a;ބ(]B߂o c>�={ k?>]ۡ1hAhiX.[FL);L,3˚l*=lr" m@=y.I�齞!DbCqROm]R"C;$LUSI–\|ͪSR\ jQ41ͫ<ysMӎ˃ $�T ̮[VaE~+%nKrDy~[oaGHWSU~?AuI=a'(/$r qoe1-.$Mpe313i](["ШzuxxV-TR[ضVr_rM ؐ4 I\%~u1jAwS�0?97uȉ"`M54@4M�M4M4 4@p_5&=??7G<_5&=??7G :"_Ln<$&?`vWघ}梒"tܾJ"D&nqf %2X]6Z9L Z'":mQHQWܜ>3hN[D3 F!%d<Rn>|jKb |2. :/kqL63]I"qUW"lg]:\mJm>˙g[eź12j5\ٵ fj+ ܐ6H7真ԌgeUEvFD LFYV`0M'\HN"l[f)XKRt&l_f{ ; @Q�ި*E/5bZ2cD1Ge V:Ύc--q/uLl2緵{,yKMPQZcqtl*]4g JԵjO>OK`3Ţ;m#"v &#,0[W&Kq$'MAP 6L5?];Yo΂ҩ3 IGr 1@\U5<>ߥ|w(:܊777a6D%İ2ʝgˁK.:/!v5THzf16Kqc@!A`> JM('w :j]t5/}a;ET҈Ƀ:I|$Poy^}JH?O'H+YNH1cN!1Nh&ڢ*'q!KkVv5=[c_WrvQVМ8o-y.NMfg!jh<}M�KW+/w-�vz]cUV1Wcn\ˈ'.|qxkU wMeLQӥ3 pW!m=DH^$!EE5Fpޅ䵌m  ܯXFSIm2$(Ҵ q/8uW&UVy-#OmDBoTREBsu,5Ad?kT45V] ME8Qfl!Mr \HhjAwS�0?97us#Ș4MdM4 4@4M�M4M4_ɬO���v:_ɬO���v:?6:!Ϩ͗I[Mů"vqċeT^D[ụ鿃II`8�5?DUStEj՜o#±pqذ$Lhmrް$OG{iDz_`@ⵗS Y!ؑR}I2R{nq%wj)m*[jWuUE<Uo#Π]ŕE6v-f1Hqx @\){]=? *2W.Faa}CD5'B)lv_}7aJ jX(ɿM^p.噆i-xq.zS $8>]O9ܯzTENtΩh)J{<wu|:ZO{fHĨheN5[G2T(̋9>,w|v[6O/v꺁<>IdpTOP'\m62Luu SD(kr<DO.ʨed؇.+J. >4ѢrسKGB./Eߊo5ʊ*9Xs4ĥc9R}f}mםA=#Ew<ϋAkG&ui"FyK0t Q {CǞTw*[piܖ�O5O5[1uUeEז;kM!5%e^4qQxG՜ǧ9vkk:EU]1#ԂI("@zI7xM()9T]OE>bqei'ѮuYccb="S řEi0ū%[|LQh8Ʌ:qaS94iU{ʎ2ڨ͕8/gHm&MxW˱zўA!ȭ$6jHB (ʾKv.ik#&�mupي7ے䚀:cVE+8ԂշzpN �qU.\qUXS߱hudX>(B&":t&Ҷ.DL,> e$Ӑ@D'2RbSSVu/Hgj= ;m #hDU԰2vOŮu[<?s0rzZm ͯ9M,GyRd\84y&GYYI5 MLP~�֩̏"`M54@4M�M4M4 4@p_5&=??7G<_5&=??7G B~{sÓ[h $+*)۠xMz׫9O~j-dls^? 9GKED%!;SeY6o^dqV ?܈"JB UvUW}�I0l=\{6݊׵>{-! '>C?<C[bmY5/1]g)H돛`jAlQSRyCTDx:,"ïH 6f21H'3Mu1䨌K47>˅<bmv0q:;+H#]s.aUE!UU6_%]v_tʨRbԶTV-|E8d*#*lyjO{Z ocFCq!EݨFs'$6Hj9}9";kn•+miTtc)"-&cu_3Pnْ~bq2)M\AS"m5r ֌Y 9ذѰhU50tPTEx5<8[EoθQ%"Ԣ0Ln}wRvnH%kJ.Z#4/d"9{=fR'-)'4ڴIBCWC|:nX`qX)4L)[Et% BxMyZKW k$/G˽RsmR%]UU}:iE꽥Fkcl% 'Hl[!m2r#j~KŪrV«9z,EolF␧+%&-68,�O®}9So:$τ=y4D*㷹?X7CO.˸r>>`o!"""#o/)K%apM:й /H80v3 ^آ 8{Uj2+0ޙe<6"qdYpbʎ۪-EO~r%c6{h(k]=Sf;2Or`Čqڧ/(M[ &S]B牼":l[{ *z|F%weeQ*FꉎWS,j੢iJVIxEGPʼGگ8z)"M,ޗ\&5DJHӮ pIU7NK[+N<re(9 2i-|k.?Sdtd KaJ*ap?Zۭ}l{"d>b 1Y[XJe9 /.>u Gbc3=;hEl�uS-|]{uN M4Z^arr؝$|]˦]A滧Jc<>)z욅|mauD<Ce[ V4+M#HCPhl#R:-jRI!G%v+K-(b-{MU%TtDQu3_k2/ƺȪ-o?jgm% UOex*Ӫ\b=4(6ne0.N/vͶ0*:*(.\Q LH]?J鲕lo\tUYd!seTR> w%UHH~!u"dTTWUDwOU>zupOʫY1jςE+Om>|8*,!?&�t C(?�`~roNTeLiQhiiih �x�g�x�]  IHOW|GyA]lW!+a5 0X#,"iA'RA!_&q}綹SV<Rp�]Ei�j1r ې n(wl6WXfBJ며c*+&L /l7G㨦eQrŊITP-1r\) E PQDCMToz^>E5ō *S csEH\%Fܑ-ZiQq]!<fr\·q" 6LKhPGc4(>DvGCIO*K1)XHT7aA�@B"$J9"&U}YnQCf+vgdܖ.$Dj-)鵳N${FW=x>{L�lR�Et8Dy8>fjYUwE=XZ,dHZFۈv�ѴACжuSʠd.h5E$_/%TIQMt$ţz\HNͲǠ69"(4ARDU�OW3V'YX~e$-5 m_7q$MWϧZt%<cX!J1le&XGn@"*H(GtSoz,JXX,+F˒r#%T-mE :*n)aQT4zs}c-lyb.H(M/1⅊㯦1.d5_e5ۛŖ< Ucn6Bܶ|bQTJwFq%kKаt!>bԀhd6:)y{KlhJs֣'$.D)^q1n#-0RE-I�(Xv…ĠY}IGZ3Et 2EEEEkHJ۾|ț߁]I^6N"'—c_&h )y芟NaWY,*lRӒXQ7>ʒJڒ;"oh�q@*F%mU@}'c�U6d(] ҽ)D!ԵG-tQm85^=ؗɭMYa7NFQYKk.#^k͖Tա6WOu櫲mMB 4@=Ъ:Kq 0FZ!#%wW[̇,w^qvmS%$MQ'ǣg N0^Ka["eVY-*y<5L[ SPRtǩ-!U>5,aS)tDPQvMlkmfK"v[&vEؽ$wO=苪>(.O)uG3U'qISčA ӐNJs[Q9V=s͸b;J")D_$^'KfH[V,n|).EioNV[qCqSB؋]-C/? Dn͵"pՏJCB⭫i庒L:5ɿ;P�Ӻ9Lk_?k�%~#OZ�$�I_>W;D�%�O >iW;D�%�O?k�Ok_?k�%~#OZ�@W%~#OZ�I_>$�I_>W;D�%�O >_ɬO���v:?*C_�K__BzٙE;BA̯DDCuOZTI.NSje11Wfr!4b(*"Byy:F?OMg9dXtZgщ- v<AيȼB <@VA"" n]!Fex2_QbQ4' 1`^."(㦈C}y#ɧu&2LH< i+̸'B YmdMB{ te5_Y^㲨+ʦ=c,b�N#e˶r@BEGu ξ:F?Syt4$xabщ J,8UcЈ#ǎ*!6n"UWũ,#A~3Җ �pc)@G x$)}y#ɧu&_(3dOYD*<2 ְJik}46D! Qw<5= CF-oQrU �|PXh�eMA>N.벤'}y#ɧu&6o~uegӚaqڂp0n:: 6ㆦer%^-}ڵO>?dc4ξ֝ p4?ξ:F?Sp4?ξ:F?L bET�:F?OM01MS�M>>?dc4$[1Q$EEMQ/6q7-`(`0є5QlQe6D>>?dc4ξ2"gIG^;j8r4Fm2;Ĝ wU]w* 9>A/QI)Q"eUt]Ӌ[y~E�Yן1|}g_^~kNMxa[lrKYц~GQqVqNwoX?ξ:F?Qvm,+-:̸P~�?}y#ɬ>Qܓ3+LۨawE�모i?��krb5-1.16/src/windows/leash/htmlhelp/Images/Destroy_Ticket.PNG��������������������������������������0000644�0007046�0000145�00000004671�13211554426�024107� 0����������������������������������������������������������������������������������������������������ustar �ghudson�������������������������libuuid����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������PNG  ��� IHDR���/���M���6=���sRGB����gAMA�� a��� pHYs����+�� NIDAThCZklf_~ml7xmUnP*@‰PY"4I*H@G�ITC ڂh8&<R?s ~>z6[+Μ{ws L6 B�o Laxg@F- ><g 0 &J!sfG@&.[ hNv$Y?7Ni-[7HyI`GxۢQ!<B vaZDMKFߕK075Io,|6Ǡjn@O6lߖq0s@lZ*Ay}YǃR'[:LHGSq1:+*R(]w{ ɏKCkh@ل<dT*TQVFp lr0&3zWH|j&d[Yɗ5 %>t&. JJDp9ʉ8 p&@͹6R޸A) :6pD&JX\qkl6Պ{g8cb<c"t:lz1Dô]"_p8Dlt!XH N:߹4&AHJF[5oA<W3M0`�P* F2̳�GJqR!i FO*:[k1",ˣx~K6*t;ox+SgI&9U>`ˆ꼏 "!%&* PRQ})ʒh:Ov9Oycut||ɴYrx6 JN&xX;(c]9%xrZ A$Җ70\@ @PJ LAApB& H i vuɳJb(<C{8c:zioxWF9:/,Jha$%&#Ew7R:ڿa8rFI`mL[`9bRM?o@phOG?m@אf==zt3aD-@C$!շe.Q6e+c4* $sH(""Xg41H޸Su01!9$%79gl<vٮet<?@Q}gFGq9*$쥥Ho@)h#yĽ 8?-9JI"x6-c1 6qqXưgº;Zq=v"]%ŰWt CZK5!r"OK|tF˂')^RDH)ms<4نJzU[J>LF6H<LCl'_r5) gjyVƢ+zG4q2_(n1>}�s u֫Jm,Ώ+JC[:^ V߅†alIM%w %l%0817 /Ԓl">]~=E aآr  ֋6Ș}5uKV'2; h/hCQY⇙r=R|*!'gaǛlQ^1 ܭKx{6H,T`qԯÙQNb!5j-fBZۗXU~z")uanW㮫/ #E3_g9rkbMI^E&k.lliK =͍doԧa3!I6| j<`N_Smo}0[׈caȗf`eP Ps^/t!}׶\*N׻]Yn<Q~h\W uQƙى<i`ǀG2U苄lP~7DC#:i>ZΊ-=VwVG d?OĥR6w4lM"cDGoqy\<9T{#5*`5K"v_l<EhÚ0o>-{OQkC~˛iŢTVDE,xl `IbQ|y+xk։A DZlA eyRxK,sZO cADFtX+E c}uH}jSVqO)T Klmv1JOXBD&-=='Xљd~y2$ЙgT], IƧE? VSl ����IENDB`�����������������������������������������������������������������������krb5-1.16/src/windows/leash/htmlhelp/leash32.hhk����������������������������������������������������0000644�0007046�0000145�00000032356�13211554426�021336� 0����������������������������������������������������������������������������������������������������ustar �ghudson�������������������������libuuid����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<HTML> <!-- Sitemap 1.0 --> <OBJECT type="text/site properties"> </OBJECT> <UL> <LI> <OBJECT type="text/sitemap"> <param name="Keyword" value="about"> <param name="Name" value="KERBEROS"> <param name="Local" value="html/leash_topic_about_kerberos.htm"> </OBJECT> <LI> <OBJECT type="text/sitemap"> <param name="Keyword" value="acknowledgements"> <param name="Name" value="Acknowledgements"> <param name="Local" value="html/leash_acknowledgements.htm"> </OBJECT> <LI> <OBJECT type="text/sitemap"> <param name="Keyword" value="aklog"> <param name="See Also" value="aklog"> </OBJECT> <UL> <LI> <OBJECT type="text/sitemap"> <param name="Keyword" value="exe"> <param name="Local" value="html/leash_external_aklog.htm"> </OBJECT> <LI> <OBJECT type="text/sitemap"> <param name="Keyword" value="man"> <param name="Local" value="html/leash_manpage_aklog.htm"> </OBJECT> </UL> <LI> <OBJECT type="text/sitemap"> <param name="Keyword" value="bugs"> <param name="Name" value="Reporting Problems With Leash"> <param name="Local" value="html/leash_bug_reports.htm"> </OBJECT> <LI> <OBJECT type="text/sitemap"> <param name="Keyword" value="change"> <param name="Name" value="Change Password Command"> <param name="Local" value="html/leash_command_change_password.htm"> </OBJECT> <LI> <OBJECT type="text/sitemap"> <param name="Keyword" value="choose"> <param name="Name" value="How to Choose a Password"> <param name="Local" value="html/leash_topic_password_choice.htm"> </OBJECT> <LI> <OBJECT type="text/sitemap"> <param name="Keyword" value="commands"> <param name="Name" value="Leash Commands"> <param name="Local" value="html/leash_menu_commands.htm"> </OBJECT> <LI> <OBJECT type="text/sitemap"> <param name="Keyword" value="copyright"> <param name="See Also" value="copyright"> </OBJECT> <UL> <LI> <OBJECT type="text/sitemap"> <param name="Keyword" value="kerberos"> <param name="Local" value="html/leash_kerberos_copyright.htm"> </OBJECT> <LI> <OBJECT type="text/sitemap"> <param name="Keyword" value="Leash32"> <param name="Local" value="html/leash_copyright.htm"> </OBJECT> </UL> <LI> <OBJECT type="text/sitemap"> <param name="Keyword" value="debug"> <param name="Name" value="Debug Window Option"> <param name="Local" value="html/leash_view_debug_window.htm"> </OBJECT> <LI> <OBJECT type="text/sitemap"> <param name="Keyword" value="destroy"> <param name="Name" value="Destroy Tickets/Tokens on Exit Option"> <param name="Local" value="html/leash_option_tickets_on_exit.htm"> <param name="Name" value="Destroy Tickets Command"> <param name="Local" value="html/leash_command_destroy_tickets.htm"> </OBJECT> <LI> <OBJECT type="text/sitemap"> <param name="Keyword" value="display"> <param name="Name" value="Leash Display (Kerberometer and Dash Notification)"> <param name="Local" value="html/leash_topic_leash_window.htm"> </OBJECT> <LI> <OBJECT type="text/sitemap"> <param name="Keyword" value="DOS commands"> <param name="Name" value="Using Kerberos in a Command Prompt Environment"> <param name="Local" value="html/leash_topic_kerberos_command_prompt.htm"> </OBJECT> <LI> <OBJECT type="text/sitemap"> <param name="Keyword" value="error"> <param name="See Also" value="error"> </OBJECT> <UL> <LI> <OBJECT type="text/sitemap"> <param name="Keyword" value="57"> <param name="Local" value="html/leash_topic_error_57.htm"> </OBJECT> <LI> <OBJECT type="text/sitemap"> <param name="Keyword" value="62"> <param name="Local" value="html/leash_topic_error_62.htm"> </OBJECT> <LI> <OBJECT type="text/sitemap"> <param name="Keyword" value="8"> <param name="Local" value="html/leash_topic_error_8.htm"> </OBJECT> <LI> <OBJECT type="text/sitemap"> <param name="Keyword" value="invalid principal"> <param name="Local" value="html/leash_topic_invalid_principal.htm"> </OBJECT> </UL> <LI> <OBJECT type="text/sitemap"> <param name="Keyword" value="exit"> <param name="Name" value="Exit/End Leash Program"> <param name="Local" value="html/leash_file_exit.htm"> </OBJECT> <LI> <OBJECT type="text/sitemap"> <param name="Keyword" value="expiration"> <param name="Name" value="Low Ticket/Token Time Alarm Option"> <param name="Local" value="html/leash_option_expiration_alarm.htm"> </OBJECT> <LI> <OBJECT type="text/sitemap"> <param name="Keyword" value="export"> <param name="Name" value="Kerberos Export Restrictions and Source Code Access"> <param name="Local" value="html/leash_export.htm"> </OBJECT> <LI> <OBJECT type="text/sitemap"> <param name="Keyword" value="get"> <param name="Name" value="InitializeTickets Command"> <param name="Local" value="html/leash_command_get_tickets.htm"> </OBJECT> <LI> <OBJECT type="text/sitemap"> <param name="Keyword" value="guide"> <param name="Name" value="Kerberos: How does the other guy know who I am?"> <param name="Local" value="html/leash_topic_kerberos_principals.htm"> </OBJECT> <LI> <OBJECT type="text/sitemap"> <param name="Keyword" value="help"> <param name="See Also" value="help"> </OBJECT> <LI> <OBJECT type="text/sitemap"> <param name="Keyword" value="import"> <param name="Name" value="ImportTickets Command"> <param name="Local" value="html/leash_command_import_tickets.htm"> </OBJECT> <UL> <LI> <OBJECT type="text/sitemap"> <param name="Keyword" value="About Kerberos"> <param name="Local" value="html/leash_topic_about_kerberos.htm"> </OBJECT> <LI> <OBJECT type="text/sitemap"> <param name="Keyword" value="About Leash32"> <param name="Local" value="html/leash_help_about_leash32.htm"> </OBJECT> <LI> <OBJECT type="text/sitemap"> <param name="Keyword" value="online"> <param name="Local" value="html/leash_topic_online_help.htm"> </OBJECT> <LI> <OBJECT type="text/sitemap"> <param name="Keyword" value="Why use Leash32"> <param name="Local" value="html/leash_topic_why_use.htm"> </OBJECT> </UL> <LI> <OBJECT type="text/sitemap"> <param name="Keyword" value="kdestroy"> <param name="See Also" value="kdestroy"> </OBJECT> <UL> <LI> <OBJECT type="text/sitemap"> <param name="Keyword" value="exe"> <param name="Local" value="html/leash_external_kdestroy.htm"> </OBJECT> <LI> <OBJECT type="text/sitemap"> <param name="Keyword" value="man"> <param name="Local" value="html/leash_manpage_kdestroy.htm"> </OBJECT> </UL> <LI> <OBJECT type="text/sitemap"> <param name="Keyword" value="Kerberos"> <param name="Name" value="An Authentication Service for Open Network Systems"> <param name="Local" value="html/leash_topic_kerberos_auth_service.htm"> </OBJECT> <LI> <OBJECT type="text/sitemap"> <param name="Keyword" value="key"> <param name="See Also" value="key"> </OBJECT> <UL> <LI> <OBJECT type="text/sitemap"> <param name="Keyword" value="Ctrl+4"> <param name="Local" value="html/leash_option_krb4_properties.htm"> </OBJECT> <LI> <OBJECT type="text/sitemap"> <param name="Keyword" value="Ctrl+5"> <param name="Local" value="html/leash_option_krb5_properties.htm"> </OBJECT> <LI> <OBJECT type="text/sitemap"> <param name="Keyword" value="Ctrl+A"> <param name="Local" value="html/leash_option_afs_properties.htm"> </OBJECT> <LI> <OBJECT type="text/sitemap"> <param name="Keyword" value="Ctrl+D"> <param name="Local" value="html/leash_command_destroy_tickets.htm"> </OBJECT> <LI> <OBJECT type="text/sitemap"> <param name="Keyword" value="Ctrl+I"> <param name="Local" value="html/leash_command_import_tickets.htm"> </OBJECT> <LI> <OBJECT type="text/sitemap"> <param name="Keyword" value="Ctrl+K"> <param name="Local" value="html/leash_option_kerberos_properties.htm"> </OBJECT> <LI> <OBJECT type="text/sitemap"> <param name="Keyword" value="Ctrl+L"> <param name="Local" value="html/leash_option_leash_properties.htm"> </OBJECT> <LI> <OBJECT type="text/sitemap"> <param name="Keyword" value="Ctrl+R"> <param name="Local" value="html/leash_command_renew_tickets.htm"> </OBJECT> <LI> <OBJECT type="text/sitemap"> <param name="Keyword" value="Ctrl+T"> <param name="Local" value="html/leash_command_get_tickets.htm"> </OBJECT> </UL> <LI> <OBJECT type="text/sitemap"> <param name="Keyword" value="Key"> <param name="See Also" value="Key"> </OBJECT> <UL> <LI> <OBJECT type="text/sitemap"> <param name="Keyword" value="F5"> <param name="Local" value="html/leash_command_update_display.htm"> </OBJECT> </UL> <LI> <OBJECT type="text/sitemap"> <param name="Keyword" value="kinit"> <param name="See Also" value="kinit"> </OBJECT> <UL> <LI> <OBJECT type="text/sitemap"> <param name="Keyword" value="exe"> <param name="Local" value="html/leash_external_kinit.htm"> </OBJECT> <LI> <OBJECT type="text/sitemap"> <param name="Keyword" value="man"> <param name="Local" value="html/leash_manpage_kinit.htm"> </OBJECT> </UL> <LI> <OBJECT type="text/sitemap"> <param name="Keyword" value="klist"> <param name="See Also" value="klist"> </OBJECT> <UL> <LI> <OBJECT type="text/sitemap"> <param name="Keyword" value="exe"> <param name="Local" value="html/leash_external_klist.htm"> </OBJECT> <LI> <OBJECT type="text/sitemap"> <param name="Keyword" value="man"> <param name="Local" value="html/leash_manpage_klist.htm"> </OBJECT> </UL> <LI> <OBJECT type="text/sitemap"> <param name="Keyword" value="large icons"> <param name="Name" value="Large Icons Option"> <param name="Local" value="html/leash_view_large_icons.htm"> </OBJECT> <LI> <OBJECT type="text/sitemap"> <param name="Keyword" value="Leash program"> <param name="Name" value="Leash Program"> <param name="Local" value="html/leash_topic_leash_help_topics.htm"> </OBJECT> <LI> <OBJECT type="text/sitemap"> <param name="Keyword" value="ms2mit"> <param name="See Also" value="ms2mit"> </OBJECT> <UL> <LI> <OBJECT type="text/sitemap"> <param name="Keyword" value="exe"> <param name="Local" value="html/leash_external_ms2mit.htm"> </OBJECT> <LI> <OBJECT type="text/sitemap"> <param name="Keyword" value="man"> <param name="Local" value="html/leash_manpage_ms2mit.htm"> </OBJECT> </UL> <LI> <OBJECT type="text/sitemap"> <param name="Keyword" value="names"> <param name="Name" value="Kerberos Names"> <param name="Local" value="html/leash_topic_kerberos_names.htm"> </OBJECT> <LI> <OBJECT type="text/sitemap"> <param name="Keyword" value="properties"> <param name="See Also" value="properties"> </OBJECT> <UL> <LI> <OBJECT type="text/sitemap"> <param name="Keyword" value="AFS"> <param name="Local" value="html/leash_option_afs_properties.htm"> </OBJECT> <LI> <OBJECT type="text/sitemap"> <param name="Keyword" value="Kerberos"> <param name="Local" value="html/leash_option_kerberos_properties.htm"> </OBJECT> <LI> <OBJECT type="text/sitemap"> <param name="Keyword" value="Kerberos4"> <param name="Local" value="html/leash_option_krb4_properties.htm"> </OBJECT> <LI> <OBJECT type="text/sitemap"> <param name="Keyword" value="Kerberos5"> <param name="Local" value="html/leash_option_krb5_properties.htm"> </OBJECT> <LI> <OBJECT type="text/sitemap"> <param name="Keyword" value="Leash"> <param name="Local" value="html/leash_option_leash_properties.htm"> </OBJECT> </UL> <LI> <OBJECT type="text/sitemap"> <param name="Keyword" value="renew"> <param name="Name" value="RenewTickets Command"> <param name="Local" value="html/leash_command_renew_tickets.htm"> </OBJECT> <LI> <OBJECT type="text/sitemap"> <param name="Keyword" value="reset"> <param name="Name" value="Reset Window Size/Pos Command"> <param name="Local" value="html/leash_command_reset_window.htm"> </OBJECT> <LI> <OBJECT type="text/sitemap"> <param name="Keyword" value="status bar"> <param name="Name" value="Status Bar Option"> <param name="Local" value="html/leash_view_status_bar.htm"> </OBJECT> <LI> <OBJECT type="text/sitemap"> <param name="Keyword" value="synchronize"> <param name="Name" value="Synchronize Time Command"> <param name="Local" value="html/leash_command_sync_time.htm"> </OBJECT> <LI> <OBJECT type="text/sitemap"> <param name="Keyword" value="tickets"> <param name="Name" value="How Kerberos Shares Tickets"> <param name="Local" value="html/leash_topic_sharing_tickets.htm"> </OBJECT> <LI> <OBJECT type="text/sitemap"> <param name="Keyword" value="time"> <param name="Name" value="Kerberos Timing Issues"> <param name="Local" value="html/leash_topic_timing_issues.htm"> </OBJECT> <LI> <OBJECT type="text/sitemap"> <param name="Keyword" value="toolbar"> <param name="Name" value="Toolbar Option"> <param name="Local" value="html/leash_view_toolbar.htm"> </OBJECT> <LI> <OBJECT type="text/sitemap"> <param name="Keyword" value="update"> <param name="Name" value="Update Display Command"> <param name="Local" value="html/leash_command_update_display.htm"> </OBJECT> <LI> <OBJECT type="text/sitemap"> <param name="Keyword" value="uppercase"> <param name="Name" value="Upper Case Realm Name Option"> <param name="Local" value="html/leash_option_upper_case_realm.htm"> </OBJECT> <LI> <OBJECT type="text/sitemap"> <param name="Keyword" value="why"> <param name="Name" value="Why use Leash?"> <param name="Local" value="html/leash_topic_why_use.htm"> </OBJECT> </UL></HTML> ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������krb5-1.16/src/windows/leash/htmlhelp/Table_of_Contents.hhc������������������������������������������0000644�0007046�0000145�00000022356�13211554426�023454� 0����������������������������������������������������������������������������������������������������ustar �ghudson�������������������������libuuid����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN"> <HTML> <HEAD> <meta name="GENERATOR" content="Microsoft® HTML Help Workshop 4.1"> <!-- Sitemap 1.0 --> </HEAD><BODY> <OBJECT type="text/site properties"> <param name="Auto Generated" value="Yes"> </OBJECT> <UL> <LI> <OBJECT type="text/sitemap"> <param name="Name" value="Why Use Leash?"> <param name="Local" value="html/leash_topic_why_use.htm"> </OBJECT> <LI> <OBJECT type="text/sitemap"> <param name="Name" value="Leash Help Topics"> <param name="Local" value="html/leash_topic_leash_help_topics.htm"> </OBJECT> <UL> <LI> <OBJECT type="text/sitemap"> <param name="Name" value="Leash Screen Display (Kerberometer and Dash Notification)"> <param name="Local" value="html/leash_topic_leash_window.htm"> </OBJECT> <LI> <OBJECT type="text/sitemap"> <param name="Name" value="Leash System Tray Tool"> <param name="Local" value="html/leash_topic_leash_systray.htm"> </OBJECT> <UL> <LI> <OBJECT type="text/sitemap"> <param name="Name" value="System Tray Menu"> <param name="Local" value="html/leash_topic_leash_systray.htm"> </OBJECT> </UL> <LI> <OBJECT type="text/sitemap"> <param name="Name" value="Leash Commands"> <param name="Local" value="html/leash_menu_commands.htm"> </OBJECT> <UL> <LI> <OBJECT type="text/sitemap"> <param name="Name" value="Exit Command"> <param name="Local" value="html/leash_file_exit.htm"> </OBJECT> <LI> <OBJECT type="text/sitemap"> <param name="Name" value="Get Ticket(s)/Token(s) Command, Ctrl+T"> <param name="Local" value="html/leash_command_get_tickets.htm"> </OBJECT> <LI> <OBJECT type="text/sitemap"> <param name="Name" value="Import Ticket(s)/Token(s) Command, Ctrl+I"> <param name="Local" value="html/leash_command_import_tickets.htm"> </OBJECT> <LI> <OBJECT type="text/sitemap"> <param name="Name" value="Renew Ticket(s)/Token(s) Command, Ctrl+R"> <param name="Local" value="html/leash_command_renew_tickets.htm"> </OBJECT> <LI> <OBJECT type="text/sitemap"> <param name="Name" value="Destroy Ticket(s)/Token(s) Command, Ctrl+D"> <param name="Local" value="html/leash_command_destroy_tickets.htm"> </OBJECT> <LI> <OBJECT type="text/sitemap"> <param name="Name" value="Change Password Command"> <param name="Local" value="html/leash_command_change_password.htm"> </OBJECT> <LI> <OBJECT type="text/sitemap"> <param name="Name" value="Reset Window Size/Pos Option"> <param name="Local" value="html/leash_command_reset_window.htm"> </OBJECT> <LI> <OBJECT type="text/sitemap"> <param name="Name" value="Synchronize Time"> <param name="Local" value="html/leash_command_sync_time.htm"> </OBJECT> <LI> <OBJECT type="text/sitemap"> <param name="Name" value="Update Display Command, F5"> <param name="Local" value="html/leash_command_update_display.htm"> </OBJECT> <LI> <OBJECT type="text/sitemap"> <param name="Name" value="Large Icons"> <param name="Local" value="html/leash_view_large_icons.htm"> </OBJECT> <LI> <OBJECT type="text/sitemap"> <param name="Name" value="Leash Toolbar"> <param name="Local" value="html/leash_view_toolbar.htm"> </OBJECT> <LI> <OBJECT type="text/sitemap"> <param name="Name" value="Status Bar"> <param name="Local" value="html/leash_view_status_bar.htm"> </OBJECT> <LI> <OBJECT type="text/sitemap"> <param name="Name" value="Debug Window"> <param name="Local" value="html/leash_view_debug_window.htm"> </OBJECT> <LI> <OBJECT type="text/sitemap"> <param name="Name" value="Automatic Ticket Renewal Option"> <param name="Local" value="html/leash_option_auto_renewal.htm"> </OBJECT> <LI> <OBJECT type="text/sitemap"> <param name="Name" value="Destroy Tickets/Tokens on Exit Option"> <param name="Local" value="html/leash_option_destroy_tickets_on_exit.htm"> </OBJECT> <LI> <OBJECT type="text/sitemap"> <param name="Name" value="Expiration Alarm Option"> <param name="Local" value="html/leash_option_expiration_alarm.htm"> </OBJECT> <LI> <OBJECT type="text/sitemap"> <param name="Name" value="Upper Case Realm Name Option"> <param name="Local" value="html/leash_option_upper_case_realm.htm"> </OBJECT> <LI> <OBJECT type="text/sitemap"> <param name="Name" value="Leash Properties Command, Ctrl+L"> <param name="Local" value="html/leash_option_leash_properties.htm"> </OBJECT> <LI> <OBJECT type="text/sitemap"> <param name="Name" value="Kerberos Properties Command, Ctrl+K"> <param name="Local" value="html/leash_option_kerberos_properties.htm"> </OBJECT> <LI> <OBJECT type="text/sitemap"> <param name="Name" value="Kerberos v4 Properties Command, Ctrl+4"> <param name="Local" value="html/leash_option_krb4_properties.htm"> </OBJECT> <LI> <OBJECT type="text/sitemap"> <param name="Name" value="Kerberos v5 Properties Command, Ctrl+5"> <param name="Local" value="html/leash_option_krb5_properties.htm"> </OBJECT> <LI> <OBJECT type="text/sitemap"> <param name="Name" value="AFS Properties Command, Ctrl+A"> <param name="Local" value="html/leash_option_afs_properties.htm"> </OBJECT> <LI> <OBJECT type="text/sitemap"> <param name="Name" value="About Leash"> <param name="Local" value="html/leash_help_about_leash32.htm"> </OBJECT> </UL> </UL> <LI> <OBJECT type="text/sitemap"> <param name="Name" value="Kerberos Help Topics"> <param name="Local" value="html/leash_topic_kerberos_help_topics.htm"> </OBJECT> <UL> <LI> <OBJECT type="text/sitemap"> <param name="Name" value="About Kerberos"> <param name="Local" value="html/leash_topic_about_kerberos.htm"> </OBJECT> <LI> <OBJECT type="text/sitemap"> <param name="Name" value="Kerberos Names"> <param name="Local" value="html/leash_topic_kerberos_names.htm"> </OBJECT> <LI> <OBJECT type="text/sitemap"> <param name="Name" value="Kerberos Tickets"> <param name="Local" value="html/leash_topic_kerberos_tickets.htm"> </OBJECT> <LI> <OBJECT type="text/sitemap"> <param name="Name" value="Using Kerberos in a Command Prompt Environment"> <param name="Local" value="html/leash_topic_kerberos_command_prompt.htm"> </OBJECT> <LI> <OBJECT type="text/sitemap"> <param name="Name" value="Kerberos Timing Issues"> <param name="Local" value="html/leash_topic_timing_issues.htm"> </OBJECT> </UL> <LI> <OBJECT type="text/sitemap"> <param name="Name" value="Kerberos for Windows Command Line Tools Manpages"> <param name="Local" value="html/leash_manpages.htm"> </OBJECT> <UL> <LI> <OBJECT type="text/sitemap"> <param name="Name" value="KINIT Command"> <param name="Local" value="html/leash_manpage_kinit.htm"> </OBJECT> <LI> <OBJECT type="text/sitemap"> <param name="Name" value="KLIST Command"> <param name="Local" value="html/leash_manpage_klist.htm"> </OBJECT> <LI> <OBJECT type="text/sitemap"> <param name="Name" value="KDESTROY Command"> <param name="Local" value="html/leash_manpage_kdestroy.htm"> </OBJECT> <LI> <OBJECT type="text/sitemap"> <param name="Name" value="MS2MIT Command"> <param name="Local" value="html/leash_manpage_ms2mit.htm"> </OBJECT> <LI> <OBJECT type="text/sitemap"> <param name="Name" value="AKLOG Command"> <param name="Local" value="html/leash_manpage_aklog.htm"> </OBJECT> </UL> <LI> <OBJECT type="text/sitemap"> <param name="Name" value="Common Leash Error Messages"> <param name="Local" value="html/leash_errors.htm"> </OBJECT> <UL> <LI> <OBJECT type="text/sitemap"> <param name="Name" value="Kerberos Error 8: Unknown username, instance, or realm."> <param name="Local" value="html/leash_topic_error_8.htm"> </OBJECT> <LI> <OBJECT type="text/sitemap"> <param name="Name" value="Kerberos Error 57: Cannot contact the Kerberos server for the selected realm."> <param name="Local" value="html/leash_topic_error_57.htm"> </OBJECT> <LI> <OBJECT type="text/sitemap"> <param name="Name" value="Kerberos Error 62: Password incorrect."> <param name="Local" value="html/leash_topic_error_62.htm"> </OBJECT> <LI> <OBJECT type="text/sitemap"> <param name="Name" value="Invalid principal."> <param name="Local" value="html/leash_topic_error_invalid_principal.htm"> </OBJECT> </UL> <LI> <OBJECT type="text/sitemap"> <param name="Name" value="How To Use Leash Online Help"> <param name="Local" value="html/leash_topic_online_help.htm"> </OBJECT> <LI> <OBJECT type="text/sitemap"> <param name="Name" value="Leash Copyright"> <param name="Local" value="html/leash_copyright.htm"> </OBJECT> <LI> <OBJECT type="text/sitemap"> <param name="Name" value="Kerberos Copyright"> <param name="Local" value="html/leash_kerberos_copyright.htm"> </OBJECT> <LI> <OBJECT type="text/sitemap"> <param name="Name" value="Kerberos Export Restrictions and Source Code Access"> <param name="Local" value="html/leash_export.htm"> </OBJECT> <LI> <OBJECT type="text/sitemap"> <param name="Name" value="Reporting Bugs and Requesting Assistance"> <param name="Local" value="html/leash_bug_reports.htm"> </OBJECT> <LI> <OBJECT type="text/sitemap"> <param name="Name" value="The MIT Kerberos Team"> <param name="Local" value="html/leash_acknowledgements.htm"> </OBJECT> </UL> </BODY></HTML> ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������krb5-1.16/src/windows/leash/htmlhelp/leash32.hhp����������������������������������������������������0000644�0007046�0000145�00000022563�13211554426�021342� 0����������������������������������������������������������������������������������������������������ustar �ghudson�������������������������libuuid����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������[OPTIONS] Auto Index=Yes Auto TOC=9 Compatibility=1.1 or later Compiled file=leash.chm Contents file=Table_of_Contents.hhc Default Font=Arial,10,0 Default Window=Default Leash Help Window Default topic=html\leash_topic_why_use.htm Display compile progress=Yes Error log file=.\leash.log Full-text search=Yes Index file=leash32.hhk Language=0x409 English (United States) Title=Leash Ticket Manager Help [WINDOWS] Default Leash Help Window="Leash Ticket Manager Help","Table_of_Contents.hhc","leash32.hhk","html\leash_topic_leash_help_topics.htm","html\leash_topic_leash_help_topics.htm",,,,,0x42520,320,0x304e,[0,0,800,560],0x7b0000,,,,,,0 [FILES] html\leash_topic_why_use.htm html\leash_topic_leash_help_topics.htm html\leash_topic_leash_window.htm html\leash_topic_leash_systray.htm html\leash_menu_commands.htm html\leash_file_exit.htm html\leash_command_get_tickets.htm html\leash_command_import_tickets.htm html\leash_command_renew_tickets.htm html\leash_command_destroy_tickets.htm html\leash_command_change_password.htm html\leash_topic_password_choice.htm html\leash_command_reset_window.htm html\leash_command_sync_time.htm html\leash_command_update_display.htm html\leash_view_large_icons.htm html\leash_view_toolbar.htm html\leash_view_status_bar.htm html\leash_view_debug_window.htm html\leash_option_auto_renewal.htm html\leash_option_destroy_tickets_on_exit.htm html\leash_option_expiration_alarm.htm html\leash_option_upper_case_realm.htm html\leash_option_leash_properties.htm html\leash_option_kerberos_properties.htm html\leash_option_krb4_properties.htm html\leash_option_krb5_properties.htm html\leash_option_afs_properties.htm html\leash_menu_help_why_use.htm html\leash_help_about_leash32.htm html\leash_topic_kerberos_help_topics.htm html\leash_topic_about_kerberos.htm html\leash_topic_kerberos_names.htm html\leash_topic_kerberos_tickets.htm html\leash_topic_kerberos_command_prompt.htm html\leash_topic_timing_issues.htm html\leash_external_kdestroy.htm html\leash_external_kinit.htm html\leash_external_klist.htm html\leash_external_ms2mit.htm html\leash_external_aklog.htm html\leash_topic_kerberos_principals.htm html\leash_topic_kerberos_auth_service.htm html\leash_manpages.htm html\leash_manpage_kinit.htm html\leash_manpage_klist.htm html\leash_manpage_kdestroy.htm html\leash_manpage_ms2mit.htm html\leash_manpage_aklog.htm html\leash_errors.htm html\leash_topic_error_8.htm html\leash_topic_error_57.htm html\leash_topic_error_62.htm html\leash_topic_error_invalid_principal.htm html\leash_topic_online_help.htm html\leash_copyright.htm html\leash_kerberos_copyright.htm html\leash_export.htm html\leash_bug_reports.htm html\leash_acknowledgements.htm html\hid_view_toolbar.htm html\afx_hidw_toolbar.htm html\hid_view_status_bar.htm html\afx_hidw_status_bar.htm html\hid_app_about.htm html\hid_app_exit.htm html\hid_help_index.htm html\hid_help_using.htm html\hid_context_help.htm html\hid_sc_size.htm html\hid_sc_move.htm html\hid_sc_minimize.htm html\hid_sc_maximize.htm html\hid_sc_close.htm html\hid_sc_restore.htm [ALIAS] HID_ABOUT_KERBEROS = html\leash_topic_about_kerberos.htm HID_ABOUT_LEASH32_COMMAND = html\leash_menu_commands.htm HID_ABOUT_LEASH32_MODULES = html\leash_help_about_leash32.htm HID_AFS_PROPERTIES_COMMAND = html\leash_option_afs_properties.htm HID_CHANGE_PASSWORD_COMMAND = html\leash_command_change_password.htm HID_DEBUG_WINDOW = html\leash_view_debug_window.htm HID_DEBUG_WINDOW_OPTION = html\leash_view_debug_window.htm HID_DESTROY_TICKETS_COMMAND = html\leash_command_destroy_tickets.htm HID_DESTROY_TICKETS_ON_EXIT = html\leash_option_destroy_tickets_on_exit.htm HID_EXIT_COMMAND = html\leash_file_exit.htm HID_GET_TICKETS_COMMAND = html\leash_command_get_tickets.htm HID_RENEW_TICKETS_COMMAND = html\leash_command_renew_tickets.htm HID_IMPORT_TICKETS_COMMAND = html\leash_command_import_tickets.htm HID_HELP_CONTENTS = html\leash_topic_leash_help_topics.htm HID_KERBEROS_PROPERTIES_ADDDOM = html\leash_option_kerberos_properties.htm HID_KERBEROS_PROPERTIES_ADDHOST = html\leash_option_kerberos_properties.htm HID_KERBEROS_PROPERTIES_ADDHOST = html\leash_option_kerberos_properties.htm HID_KERBEROS_PROPERTIES_ADDRLM = html\leash_option_kerberos_properties.htm HID_KERBEROS_PROPERTIES_COMMAND = html\leash_option_kerberos_properties.htm HID_KERBEROS_PROPERTIES_EDIT = html\leash_option_kerberos_properties.htm HID_KERBEROS_PROPERTIES_EDITDOM = html\leash_option_kerberos_properties.htm HID_KERBEROS_PROPERTIES_EDITHOST = html\leash_option_kerberos_properties.htm HID_KERBEROS_PROPERTIES_LISTDOM = html\leash_option_kerberos_properties.htm HID_KERBEROS_PROPERTIES_LISTRLM = html\leash_option_kerberos_properties.htm HID_KRB4_PROPERTIES_COMMAND = html\leash_option_krb4_properties.htm HID_KRB4_PROPERTIES_EDIT = html\leash_option_krb4_properties.htm HID_KRB5_PROPERTIES_COMMAND = html\leash_option_krb5_properties.htm HID_KRB5_PROPERTIES_EDIT = html\leash_option_krb5_properties.htm HID_KRB5_PROPERTIES_FORWARDING = html\leash_option_krb5_properties.htm HID_LARGE_ICONS_OPTION = html\leash_view_large_icons.htm HID_LEASH_COMMANDS = html\leash_menu_commands.htm HID_LEASH_PROGRAM = html\leash_topic_leash_help_topics.htm HID_LEASH_PROPERTIES_COMMAND = html\leash_option_leash_properties.htm HID_LEASH_PROPERTIES_EDIT = html\leash_option_leash_properties.htm HID_LOW_TICKET_ALARM_OPTION = html\leash_option_expiration_alarm.htm HID_RESET_WINDOW_OPTION = html\leash_command_reset_window.htm HID_SCNCHRONIZE_TIME_OPTION = html\leash_command_sync_time.htm HID_STATUS_BAR_OPTION = html\leash_view_status_bar.htm HID_TOOLBAR_OPTION = html\leash_view_toolbar.htm HID_UPDATE_DISPLAY_COMMAND = html\leash_command_update_display.htm HID_UPPERCASE_REALM_OPTION = html\leash_option_upper_case_realm.htm HID_WHY_USE_LEASH32 = html\leash_topic_why_use.htm ID_CHANGEPASSWORD = html\leash_command_change_password.htm ID_COUNTDOWN = html\leash_option_expiration_alarm.htm ID_DESTROY = html\leash_command_destroy_tickets.htm ID_EXIT = html\leash_file_exit.htm ID_HELP_CHOOSE_PASSWORD = html\leash_topic_password_choice.htm ID_HELP_KERBEROS = html\leash_topic_kerberos_help_topics.htm ID_HELP_LEASH = html\leash_topic_leash_help_topics.htm ID_HELP_PURPOSE = html\leash_topic_why_use.htm ID_INITTICKETS = html\leash_command_get_tickets.htm hid_view_toolbar = html\hid_view_toolbar.htm afx_hidw_toolbar = html\afx_hidw_toolbar.htm hid_view_status_bar = html\hid_view_status_bar.htm afx_hidw_status_bar = html\afx_hidw_status_bar.htm hid_app_about = html\hid_app_about.htm hid_app_exit = html\hid_app_exit.htm hid_help_index = html\hid_help_index.htm hid_help_using = html\hid_help_using.htm hid_context_help = html\hid_context_help.htm hid_sc_size = html\hid_sc_size.htm hid_sc_move = html\hid_sc_move.htm hid_sc_minimize = html\hid_sc_minimize.htm hid_sc_maximize = html\hid_sc_maximize.htm hid_sc_close = html\hid_sc_close.htm hid_sc_restore = html\hid_sc_restore.htm [MAP] #define HID_ABOUT_KERBEROS 98320 #define HID_ABOUT_LEASH32_COMMAND 123200 #define HID_ABOUT_LEASH32_MODULES 131225 #define HID_AFS_PROPERTIES_COMMAND 98327 #define HID_CHANGE_PASSWORD_COMMAND 98315 #define HID_DEBUG_WINDOW 131229 #define HID_DEBUG_WINDOW_OPTION 98317 #define HID_DESTROY_TICKETS_COMMAND 98313 #define HID_DESTROY_TICKETS_ON_EXIT 98321 #define HID_EXIT_COMMAND 123201 #define HID_GET_TICKETS_COMMAND 98343 #define HID_RENEW_TICKETS_COMMAND 98312 #define HID_IMPORT_TICKETS_COMMAND 98342 #define HID_HELP_CONTENTS 98340 #define HID_KERBEROS_PROPERTIES_ADDDOM 131255 #define HID_KERBEROS_PROPERTIES_ADDHOST 131254 #define HID_KERBEROS_PROPERTIES_ADDHOST 131269 #define HID_KERBEROS_PROPERTIES_ADDRLM 131253 #define HID_KERBEROS_PROPERTIES_COMMAND 98337 #define HID_KERBEROS_PROPERTIES_EDIT 131233 #define HID_KERBEROS_PROPERTIES_EDITDOM 131256 #define HID_KERBEROS_PROPERTIES_EDITHOST 131271 #define HID_KERBEROS_PROPERTIES_LISTDOM 131279 #define HID_KERBEROS_PROPERTIES_LISTRLM 131250 #define HID_KRB4_PROPERTIES_COMMAND 98329 #define HID_KRB4_PROPERTIES_EDIT 131232 #define HID_KRB5_PROPERTIES_COMMAND 98330 #define HID_KRB5_PROPERTIES_EDIT 131241 #define HID_KRB5_PROPERTIES_FORWARDING 131240 #define HID_KRBCHECK_OPTION 98335 #define HID_LARGE_ICONS_OPTION 98322 #define HID_LEASH_COMMANDS 131200 #define HID_LEASH_PROGRAM 98319 #define HID_LEASH_PROPERTIES_COMMAND 98331 #define HID_LEASH_PROPERTIES_EDIT 131239 #define HID_LOW_TICKET_ALARM_OPTION 98334 #define HID_RESET_WINDOW_OPTION 98326 #define HID_SCNCHRONIZE_TIME_OPTION 98314 #define HID_STATUS_BAR_OPTION 124929 #define HID_TOOLBAR_OPTION 124928 #define HID_UPDATE_DISPLAY_COMMAND 98316 #define HID_UPPERCASE_REALM_OPTION 98323 #define HID_WHY_USE_LEASH32 98341 #define ID_CHANGEPASSWORD 112 #define ID_COUNTDOWN 101 #define ID_DESTROY 111 #define ID_EXIT 200 #define ID_HELP_CHOOSE_PASSWORD 2511841056 #define ID_HELP_KERBEROS 211 #define ID_HELP_LEASH 210 #define ID_HELP_PURPOSE 115 #define ID_INITTICKETS 113 #define KRB_BAD_NAME 39525457 #define KRB_BAD_TIME 39525413 #DEFINE KRB_ERROR_78 39525454 #define KRB_INCORR_PASSWD 39525438 #define KRB_NO_TKT_FILE 39525446 #define KRB_UNKNOWN_REALM 39525433 #define KRB_UNKNOWN_USER 39525384 #define LSH_INVINSTANCE 40591875 [INFOTYPES] ���������������������������������������������������������������������������������������������������������������������������������������������krb5-1.16/src/windows/leash/htmlhelp/LeashHelp.hhp��������������������������������������������������0000644�0007046�0000145�00000016021�13211554426�021736� 0����������������������������������������������������������������������������������������������������ustar �ghudson�������������������������libuuid����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������[OPTIONS] Binary Index=No Compatibility=1.1 or later Compiled file=LeashHelp.chm Contents file=TOC.hhc Default Window=Leash Help Default topic=Html\Getting_Started.htm Display compile progress=No Full text search stop list file=stoplist.stp Full-text search=Yes Index file=Index.hhk Language=0x409 English (United States) [WINDOWS] Leash Help="MIT Kerberos Help","TOC.hhc","Index.hhk",,,,,,,0x62420,,0x100e,[0,0,800,800],,,,,,,0 [FILES] Html\Getting_Started.htm Html\Change_Password.htm Html\Forget_Password.htm Html\Kerberos.htm Html\Password_Tips.htm Html\Passwords.htm Html\Using_Leash_Menus.htm Html\Tickets.htm Html\Destroy_Tickets.htm Html\Get_Tickets.htm Html\Import_Tickets.htm Html\Renew_Tickets.htm Html\Ticket_Settings.htm Html\View_Tickets.htm Leash.css HTML\FAQ.htm HTML\Options_Menu.htm HTML\Command_Line.htm HTML\MS2MIT.htm HTML\KDESTROY.htm HTML\KLIST.htm HTML\KINIT.htm HTML\Troubleshooting.htm HTML\Kerberos_Terminology.htm HTML\Report_Bugs.htm HTML\Encryption_Types.htm HTML\KCPYTKT.htm HTML\KVNO.htm HTML\KSWITCH.htm HTML\KPASSWD.htm HTML\Export_Tickets.htm HTML\View_Menu.htm HTML\Glossary.htm HTML\Import_Status.htm HTML\Debugging.htm HTML\Keyboard_Shortcuts.htm HTML\Windows_Logon_Tickets.htm HTML\How_Kerberos_Works.htm HTML\Principals.htm HTML\Make_Default.htm HTML\Manage_Multiple_Principals.htm HTML\Forget_Principals.htm HTML\More_Menu.htm HTML\Home_Tab.htm HTML\Options_Tab.htm [ALIAS] HID_ABOUT_KERBEROS = html\How_Kerberos_Works.htm HID_CHANGE_PASSWORD_COMMAND = html\Change_Password.htm HID_DESTROY_TICKETS_COMMAND = html\Destroy_Tickets.htm HID_DESTROY_TICKETS_ON_EXIT = html\Options_Tab.htm HID_EXIT_COMMAND = html\leash_file_exit.htm HID_GET_TICKETS_COMMAND = html\Get_Tickets.htm HID_RENEW_TICKETS_COMMAND = html\Renew_Tickets.htm HID_IMPORT_TICKETS_COMMAND = html\Import_Tickets.htm HID_HELP_CONTENTS = html\Getting_Started.htm HID_KERBEROS_PROPERTIES_ADDDOM = html\leash_option_kerberos_properties.htm HID_KERBEROS_PROPERTIES_ADDHOST = html\leash_option_kerberos_properties.htm HID_KERBEROS_PROPERTIES_ADDHOST = html\leash_option_kerberos_properties.htm HID_KERBEROS_PROPERTIES_ADDRLM = html\leash_option_kerberos_properties.htm HID_KERBEROS_PROPERTIES_COMMAND = html\leash_option_kerberos_properties.htm HID_KERBEROS_PROPERTIES_EDIT = html\leash_option_kerberos_properties.htm HID_KERBEROS_PROPERTIES_EDITDOM = html\leash_option_kerberos_properties.htm HID_KERBEROS_PROPERTIES_EDITHOST = html\leash_option_kerberos_properties.htm HID_KERBEROS_PROPERTIES_LISTDOM = html\leash_option_kerberos_properties.htm HID_KERBEROS_PROPERTIES_LISTRLM = html\leash_option_kerberos_properties.htm HID_KRB5_PROPERTIES_COMMAND = html\leash_option_krb5_properties.htm HID_KRB5_PROPERTIES_EDIT = html\leash_option_krb5_properties.htm HID_KRB5_PROPERTIES_FORWARDING = html\leash_option_krb5_properties.htm HID_LARGE_ICONS_OPTION = html\leash_view_large_icons.htm HID_LEASH_COMMANDS = html\Getting_Started.htm HID_LEASH_PROGRAM = html\Getting_Started.htm HID_LEASH_PROPERTIES_COMMAND = html\leash_option_leash_properties.htm HID_LEASH_PROPERTIES_EDIT = html\leash_option_leash_properties.htm HID_LOW_TICKET_ALARM_OPTION = html\leash_option_expiration_alarm.htm HID_RESET_WINDOW_OPTION = html\leash_command_reset_window.htm HID_SCNCHRONIZE_TIME_OPTION = html\leash_command_sync_time.htm HID_STATUS_BAR_OPTION = html\leash_view_status_bar.htm HID_TOOLBAR_OPTION = html\leash_view_toolbar.htm HID_UPDATE_DISPLAY_COMMAND = html\leash_command_update_display.htm HID_UPPERCASE_REALM_OPTION = html\leash_option_upper_case_realm.htm HID_WHY_USE_LEASH32 = html\leash_topic_why_use.htm ID_CHANGEPASSWORD = html\leash_command_change_password.htm ID_COUNTDOWN = html\leash_option_expiration_alarm.htm ID_DESTROY = html\leash_command_destroy_tickets.htm ID_EXIT = html\leash_file_exit.htm ID_HELP_CHOOSE_PASSWORD = html\leash_topic_password_choice.htm ID_HELP_KERBEROS = html\leash_topic_kerberos_help_topics.htm ID_HELP_LEASH = html\leash_topic_leash_help_topics.htm ID_HELP_PURPOSE = html\leash_topic_why_use.htm ID_INITTICKETS = html\leash_command_get_tickets.htm hid_app_about = html\hid_app_about.htm hid_app_exit = html\hid_app_exit.htm hid_help_index = html\hid_help_index.htm hid_help_using = html\hid_help_using.htm hid_context_help = html\hid_context_help.htm hid_sc_size = html\hid_sc_size.htm hid_sc_move = html\hid_sc_move.htm hid_sc_minimize = html\hid_sc_minimize.htm hid_sc_maximize = html\hid_sc_maximize.htm hid_sc_close = html\hid_sc_close.htm hid_sc_restore = html\hid_sc_restore.htm [MAP] #define HID_ABOUT_KERBEROS 98320 #define HID_ABOUT_LEASH32_COMMAND 123200 #define HID_ABOUT_LEASH32_MODULES 131225 #define HID_AFS_PROPERTIES_COMMAND 98327 #define HID_CHANGE_PASSWORD_COMMAND 98315 #define HID_DEBUG_WINDOW 131229 #define HID_DEBUG_WINDOW_OPTION 98317 #define HID_DESTROY_TICKETS_COMMAND 98313 #define HID_DESTROY_TICKETS_ON_EXIT 98321 #define HID_EXIT_COMMAND 123201 #define HID_GET_TICKETS_COMMAND 98343 #define HID_RENEW_TICKETS_COMMAND 98312 #define HID_IMPORT_TICKETS_COMMAND 98342 #define HID_HELP_CONTENTS 98340 #define HID_KERBEROS_PROPERTIES_ADDDOM 131255 #define HID_KERBEROS_PROPERTIES_ADDHOST 131254 #define HID_KERBEROS_PROPERTIES_ADDHOST 131269 #define HID_KERBEROS_PROPERTIES_ADDRLM 131253 #define HID_KERBEROS_PROPERTIES_COMMAND 98337 #define HID_KERBEROS_PROPERTIES_EDIT 131233 #define HID_KERBEROS_PROPERTIES_EDITDOM 131256 #define HID_KERBEROS_PROPERTIES_EDITHOST 131271 #define HID_KERBEROS_PROPERTIES_LISTDOM 131279 #define HID_KERBEROS_PROPERTIES_LISTRLM 131250 #define HID_KRB4_PROPERTIES_COMMAND 98329 #define HID_KRB4_PROPERTIES_EDIT 131232 #define HID_KRB5_PROPERTIES_COMMAND 98330 #define HID_KRB5_PROPERTIES_EDIT 131241 #define HID_KRB5_PROPERTIES_FORWARDING 131240 #define HID_KRBCHECK_OPTION 98335 #define HID_LARGE_ICONS_OPTION 98322 #define HID_LEASH_COMMANDS 131200 #define HID_LEASH_PROGRAM 98319 #define HID_LEASH_PROPERTIES_COMMAND 98331 #define HID_LEASH_PROPERTIES_EDIT 131239 #define HID_LOW_TICKET_ALARM_OPTION 98334 #define HID_RESET_WINDOW_OPTION 98326 #define HID_SCNCHRONIZE_TIME_OPTION 98314 #define HID_STATUS_BAR_OPTION 124929 #define HID_TOOLBAR_OPTION 124928 #define HID_UPDATE_DISPLAY_COMMAND 98316 #define HID_UPPERCASE_REALM_OPTION 98323 #define HID_WHY_USE_LEASH32 98341 #define ID_CHANGEPASSWORD 112 #define ID_COUNTDOWN 101 #define ID_DESTROY 111 #define ID_EXIT 200 #define ID_HELP_CHOOSE_PASSWORD 2511841056 #define ID_HELP_KERBEROS 211 #define ID_HELP_LEASH 210 #define ID_HELP_PURPOSE 115 #define ID_INITTICKETS 113 #define KRB_BAD_NAME 39525457 #define KRB_BAD_TIME 39525413 #DEFINE KRB_ERROR_78 39525454 #define KRB_INCORR_PASSWD 39525438 #define KRB_NO_TKT_FILE 39525446 #define KRB_UNKNOWN_REALM 39525433 #define KRB_UNKNOWN_USER 39525384 #define LSH_INVINSTANCE 40591875 [INFOTYPES] ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������krb5-1.16/src/windows/leash/htmlhelp/TOC.hhc��������������������������������������������������������0000644�0007046�0000145�00000014360�13211554426�020505� 0����������������������������������������������������������������������������������������������������ustar �ghudson�������������������������libuuid����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN"> <HTML> <HEAD> <meta name="GENERATOR" content="Microsoft® HTML Help Workshop 4.1"> <!-- Sitemap 1.0 --> </HEAD><BODY> <OBJECT type="text/site properties"> <param name="Window Styles" value="0x800425"> </OBJECT> <UL> <LI> <OBJECT type="text/sitemap"> <param name="Name" value="Getting Started"> <param name="Local" value="Html\Getting_Started.htm"> <param name="URL" value="Html\Getting_Started.htm"> </OBJECT> <UL> <LI> <OBJECT type="text/sitemap"> <param name="Name" value="Getting Started"> <param name="Local" value="Html\Getting_Started.htm"> </OBJECT> <LI> <OBJECT type="text/sitemap"> <param name="Name" value="What is Kerberos?"> <param name="Local" value="Html\Kerberos.htm"> </OBJECT> <LI> <OBJECT type="text/sitemap"> <param name="Name" value="Kerberos Terminology"> <param name="Local" value="HTML\Kerberos_Terminology.htm"> </OBJECT> <LI> <OBJECT type="text/sitemap"> <param name="Name" value="How Does Kerberos Work?"> <param name="Local" value="HTML\How_Kerberos_Works.htm"> </OBJECT> <LI> <OBJECT type="text/sitemap"> <param name="Name" value="FAQ"> <param name="Local" value="HTML\FAQ.htm"> </OBJECT> <LI> <OBJECT type="text/sitemap"> <param name="Name" value="Glossary"> <param name="Local" value="HTML\Glossary.htm"> </OBJECT> </UL> <LI> <OBJECT type="text/sitemap"> <param name="Name" value="Tickets"> <param name="Local" value="Html\Tickets.htm"> </OBJECT> <UL> <LI> <OBJECT type="text/sitemap"> <param name="Name" value="About Tickets"> <param name="Local" value="Html\Tickets.htm"> </OBJECT> <LI> <OBJECT type="text/sitemap"> <param name="Name" value="Get Tickets"> <param name="Local" value="Html\Get_Tickets.htm"> <param name="URL" value="Html\Get_Tickets.htm"> </OBJECT> <LI> <OBJECT type="text/sitemap"> <param name="Name" value="Renew Tickets"> <param name="Local" value="Html\Renew_Tickets.htm"> </OBJECT> <LI> <OBJECT type="text/sitemap"> <param name="Name" value="View Tickets"> <param name="Local" value="Html\View_Tickets.htm"> </OBJECT> <LI> <OBJECT type="text/sitemap"> <param name="Name" value="Ticket Settings & Flags"> <param name="Local" value="Html\Ticket_Settings.htm"> </OBJECT> <LI> <OBJECT type="text/sitemap"> <param name="Name" value="Destroy Tickets"> <param name="Local" value="Html\Destroy_Tickets.htm"> </OBJECT> </UL> <LI> <OBJECT type="text/sitemap"> <param name="Name" value="Principals"> <param name="Local" value="HTML\Principals.htm"> </OBJECT> <UL> <LI> <OBJECT type="text/sitemap"> <param name="Name" value="About Principals"> <param name="Local" value="HTML\Principals.htm"> </OBJECT> <LI> <OBJECT type="text/sitemap"> <param name="Name" value="Manage Multiple Principals"> <param name="Local" value="HTML\Manage_Multiple_Principals.htm"> </OBJECT> <LI> <OBJECT type="text/sitemap"> <param name="Name" value="Make Default Principal"> <param name="Local" value="HTML\Make_Default.htm"> </OBJECT> <LI> <OBJECT type="text/sitemap"> <param name="Name" value="Clear Principal History"> <param name="Local" value="HTML\Forget_Principals.htm"> </OBJECT> </UL> <LI> <OBJECT type="text/sitemap"> <param name="Name" value="Passwords"> <param name="Local" value="Html\Passwords.htm"> </OBJECT> <UL> <LI> <OBJECT type="text/sitemap"> <param name="Name" value="About Passwords"> <param name="Local" value="Html\Passwords.htm"> </OBJECT> <LI> <OBJECT type="text/sitemap"> <param name="Name" value="Change Passsword"> <param name="Local" value="Html\Change_Password.htm"> </OBJECT> <LI> <OBJECT type="text/sitemap"> <param name="Name" value="Forgotten Password"> <param name="Local" value="Html\Forget_Password.htm"> </OBJECT> <LI> <OBJECT type="text/sitemap"> <param name="Name" value="Password Tips "> <param name="Local" value="Html\Password_Tips.htm"> </OBJECT> </UL> <LI> <OBJECT type="text/sitemap"> <param name="Name" value="Using Kerberos Menus"> <param name="Local" value="Html\Using_Leash_Menus.htm"> </OBJECT> <UL> <LI> <OBJECT type="text/sitemap"> <param name="Name" value="Home Tab"> <param name="Local" value="HTML\Home_Tab.htm"> </OBJECT> <LI> <OBJECT type="text/sitemap"> <param name="Name" value="Options Tab"> <param name="Local" value="HTML\Options_Tab.htm"> </OBJECT> <LI> <OBJECT type="text/sitemap"> <param name="Name" value="Keyboard Shortcuts"> <param name="Local" value="HTML\Keyboard_Shortcuts.htm"> </OBJECT> </UL> <LI> <OBJECT type="text/sitemap"> <param name="Name" value="Troubleshooting"> <param name="Local" value="HTML\Troubleshooting.htm"> </OBJECT> <UL> <LI> <OBJECT type="text/sitemap"> <param name="Name" value="Troubleshooting"> <param name="Local" value="HTML\Troubleshooting.htm"> </OBJECT> <LI> <OBJECT type="text/sitemap"> <param name="Name" value="Report Bugs"> <param name="Local" value="HTML\Report_Bugs.htm"> </OBJECT> <LI> <OBJECT type="text/sitemap"> <param name="Name" value="Encryption Types"> <param name="Local" value="HTML\Encryption_Types.htm"> </OBJECT> </UL> <LI> <OBJECT type="text/sitemap"> <param name="Name" value="Command Prompt"> <param name="Local" value="HTML\Command_Line.htm"> </OBJECT> <UL> <LI> <OBJECT type="text/sitemap"> <param name="Name" value="KINIT"> <param name="Local" value="HTML\KINIT.htm"> </OBJECT> <LI> <OBJECT type="text/sitemap"> <param name="Name" value="KLIST"> <param name="Local" value="HTML\KLIST.htm"> </OBJECT> <LI> <OBJECT type="text/sitemap"> <param name="Name" value="KDESTROY"> <param name="Local" value="HTML\KDESTROY.htm"> </OBJECT> <LI> <OBJECT type="text/sitemap"> <param name="Name" value="KPASSWD"> <param name="Local" value="HTML\KPASSWD.htm"> </OBJECT> <LI> <OBJECT type="text/sitemap"> <param name="Name" value="KSWITCH"> <param name="Local" value="HTML\KSWITCH.htm"> </OBJECT> <LI> <OBJECT type="text/sitemap"> <param name="Name" value="KVNO"> <param name="Local" value="HTML\KVNO.htm"> </OBJECT> <LI> <OBJECT type="text/sitemap"> <param name="Name" value="KCPYTKT"> <param name="Local" value="HTML\KCPYTKT.htm"> </OBJECT> </UL> </UL> </BODY></HTML> ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������krb5-1.16/src/windows/leash/htmlhelp/Leash.css������������������������������������������������������0000644�0007046�0000145�00000005571�13211554426�021146� 0����������������������������������������������������������������������������������������������������ustar �ghudson�������������������������libuuid����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������body { font-family : Verdana, Geneva, sans-serif; font-size:100%; background-color : white; color : black; } p { font-size:.8em; background-color : white; color : black; } h1 { font-family : Verdana, Geneva, sans-serif; font-size : 1.5em; color : black; } h2 { font-family : Verdana, Geneva, sans-serif; font-size : 1.12em; color : black; } h3 { font-family : Verdana, Geneva, sans-serif; font-size : .9 em; color : black; } ol li { font-size: .8em; margin-top: 4px; margin-bottom: 10px; } ul li { font-size: .8em; margin-top: 4px; margin-bottom: 4px; } table, th, td { border: 1 solid black; border-collapse:collapse; } #table-inner { border: 0; border-collapse:collapse; } #th-inner { border: 0; border-collapse:collapse; } #th-title { border: 0; border-collapse:collapse; background-color:#F0F8FF; } #td-inner { border: 0; border-collapse:collapse; align-left; } table { padding-top: 10px; text-align: left; width: 100%; padding-bottom: 10px; table-layout: auto; } th { font-family : Verdana, Arial, Helvetica, sans-serif; font-size:1em; background-color: #E0E5EB; color : black; padding:8px; width: auto; vertical-align:top; } #th2 { font-family : Verdana, Arial, Helvetica, sans-serif; font-size:0.825em; background-color:#F0F8FF; color : black; padding:8px; width: auto; vertical-align:top; } #th2small { font-family : Verdana, Arial, Helvetica, sans-serif; font-size:0.6em; background-color:#F0F8FF; color : black; padding:6px; width: auto; vertical-align:top; } td { font-family : Verdana, Arial, Helvetica, sans-serif; font-size:0.825em; color : black; padding-left:5px; padding-top:8px; padding-bottom:8px; width: auto; vertical-align:top; } #helpul { font-family : Verdana, Geneva, sans-serif; list-style:none; font-size: 1em; margin-top: 0; margin-left:0; padding-left: 0; } ol li ul li { Verdana, Arial, sans-serif; list-style:none; position:relative; left:-10px; font-size : 1em; } #tableul { Verdana, Geneva, sans-serif; font-size : 1.12em; } #helph2 { font-family : Verdana, Geneva, sans-serif; font-size : 1.12em; color : black; margin-bottom: 4px; } #typed { font-size: 1em; font-family :"Courier New", Courier, monospace; } #button { font-size: 1em; Arial, Helvetica, sans-serif; } .typed { font-size: 1em; font-family :"Courier New", Courier, monospace; } .command { font-size: 1em; font-family :"Courier New", Courier, monospace; white-space: nowrap; } .noborder, .noborder tr, .noborder th, .noborder td { border: none; } .smallfont { font-family : Verdana, Geneva, sans-serif; font-size:.8em; font-weight:normal; } dl { margin:0; padding: 0; font-family: Verdana, Geneva, sans-serif; font-size:0.825em; } dt { margin:0; padding: 0; font-weight: bold; } dd { margin: 0 0 1em 0; padding: 0; } A:link { color : blue; } A:visited { color : purple; } A:active { color : navy; } ���������������������������������������������������������������������������������������������������������������������������������������krb5-1.16/src/windows/leash/htmlhelp/MITKerberosHelp.hhp��������������������������������������������0000644�0007046�0000145�00000015774�13211554426�023046� 0����������������������������������������������������������������������������������������������������ustar �ghudson�������������������������libuuid����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������[OPTIONS] Binary Index=No Compatibility=1.1 or later Compiled file=MITKerberosHelp.chm Contents file=TOC.hhc Default Window=Leash Help Default topic=HTML\Using_Leash_Menus.htm Display compile progress=No Full text search stop list file=stoplist.stp Full-text search=Yes Index file=Index.hhk Language=0x409 English (United States) Title=MIT Kerberos Help [WINDOWS] Leash Help="MIT Kerberos Help","TOC.hhc","Index.hhk",,,,,,,0x62420,,0x100e,[0,0,585,559],,,,,,,0 MIT Kerberos Help="MIT Kerberos Help","TOC.hhc","Index.hhk","Html\Getting_Started.htm",,,,,,0x20,,0x0,[271,372,593,566],,,,,,,0 [FILES] Leash.css HTML\FAQ.htm HTML\Command_Line.htm HTML\KDESTROY.htm HTML\KLIST.htm HTML\KINIT.htm HTML\Troubleshooting.htm HTML\Kerberos_Terminology.htm HTML\Report_Bugs.htm HTML\Encryption_Types.htm HTML\KCPYTKT.htm HTML\KVNO.htm HTML\KSWITCH.htm HTML\KPASSWD.htm HTML\Glossary.htm HTML\Debugging.htm HTML\Keyboard_Shortcuts.htm HTML\How_Kerberos_Works.htm HTML\Principals.htm HTML\Make_Default.htm HTML\Manage_Multiple_Principals.htm HTML\Forget_Principals.htm HTML\Home_Tab.htm HTML\Options_Tab.htm HTML\Getting_Started.htm HTML\Change_Password.htm HTML\Forget_Password.htm HTML\Kerberos.htm HTML\Password_Tips.htm HTML\Using_Leash_Menus.htm HTML\Passwords.htm HTML\Tickets.htm HTML\Destroy_Tickets.htm HTML\Get_Tickets.htm HTML\Renew_Tickets.htm HTML\Ticket_Settings.htm HTML\View_Tickets.htm [ALIAS] HID_ABOUT_KERBEROS = html\Getting_Started.htm HID_CHANGE_PASSWORD_COMMAND = html\Change_Password.htm HID_DESTROY_TICKETS_COMMAND = html\Destroy_Tickets.htm HID_DESTROY_TICKETS_ON_EXIT = html\Options_Tab.htm HID_EXIT_COMMAND = html\leash_file_exit.htm HID_GET_TICKETS_COMMAND = html\Get_Tickets.htm HID_RENEW_TICKETS_COMMAND = html\Renew_Tickets.htm HID_IMPORT_TICKETS_COMMAND = html\Import_Tickets.htm HID_HELP_CONTENTS = html\Getting_Started.htm HID_KERBEROS_PROPERTIES_ADDDOM = html\leash_option_kerberos_properties.htm HID_KERBEROS_PROPERTIES_ADDHOST = html\leash_option_kerberos_properties.htm HID_KERBEROS_PROPERTIES_ADDHOST = html\leash_option_kerberos_properties.htm HID_KERBEROS_PROPERTIES_ADDRLM = html\leash_option_kerberos_properties.htm HID_KERBEROS_PROPERTIES_COMMAND = html\leash_option_kerberos_properties.htm HID_KERBEROS_PROPERTIES_EDIT = html\leash_option_kerberos_properties.htm HID_KERBEROS_PROPERTIES_EDITDOM = html\leash_option_kerberos_properties.htm HID_KERBEROS_PROPERTIES_EDITHOST = html\leash_option_kerberos_properties.htm HID_KERBEROS_PROPERTIES_LISTDOM = html\leash_option_kerberos_properties.htm HID_KERBEROS_PROPERTIES_LISTRLM = html\leash_option_kerberos_properties.htm HID_KRB5_PROPERTIES_COMMAND = html\leash_option_krb5_properties.htm HID_KRB5_PROPERTIES_EDIT = html\leash_option_krb5_properties.htm HID_KRB5_PROPERTIES_FORWARDING = html\leash_option_krb5_properties.htm HID_LARGE_ICONS_OPTION = html\leash_view_large_icons.htm HID_LEASH_COMMANDS = html\Getting_Started.htm HID_LEASH_PROGRAM = html\Getting_Started.htm HID_LEASH_PROPERTIES_COMMAND = html\leash_option_leash_properties.htm HID_LEASH_PROPERTIES_EDIT = html\leash_option_leash_properties.htm HID_LOW_TICKET_ALARM_OPTION = html\leash_option_expiration_alarm.htm HID_RESET_WINDOW_OPTION = html\leash_command_reset_window.htm HID_SCNCHRONIZE_TIME_OPTION = html\leash_command_sync_time.htm HID_STATUS_BAR_OPTION = html\leash_view_status_bar.htm HID_TOOLBAR_OPTION = html\leash_view_toolbar.htm HID_UPDATE_DISPLAY_COMMAND = html\leash_command_update_display.htm HID_UPPERCASE_REALM_OPTION = html\leash_option_upper_case_realm.htm HID_WHY_USE_LEASH32 = html\leash_topic_why_use.htm ID_CHANGEPASSWORD = html\leash_command_change_password.htm ID_COUNTDOWN = html\leash_option_expiration_alarm.htm ID_DESTROY = html\leash_command_destroy_tickets.htm ID_EXIT = html\leash_file_exit.htm ID_HELP_CHOOSE_PASSWORD = html\leash_topic_password_choice.htm ID_HELP_KERBEROS = html\leash_topic_kerberos_help_topics.htm ID_HELP_LEASH = html\leash_topic_leash_help_topics.htm ID_HELP_PURPOSE = html\leash_topic_why_use.htm ID_INITTICKETS = html\leash_command_get_tickets.htm hid_app_about = html\hid_app_about.htm hid_app_exit = html\hid_app_exit.htm hid_help_index = html\hid_help_index.htm hid_help_using = html\hid_help_using.htm hid_context_help = html\hid_context_help.htm hid_sc_size = html\hid_sc_size.htm hid_sc_move = html\hid_sc_move.htm hid_sc_minimize = html\hid_sc_minimize.htm hid_sc_maximize = html\hid_sc_maximize.htm hid_sc_close = html\hid_sc_close.htm hid_sc_restore = html\hid_sc_restore.htm [MAP] #define HID_ABOUT_KERBEROS 98320 #define HID_ABOUT_LEASH32_COMMAND 123200 #define HID_ABOUT_LEASH32_MODULES 131225 #define HID_AFS_PROPERTIES_COMMAND 98327 #define HID_CHANGE_PASSWORD_COMMAND 98315 #define HID_DEBUG_WINDOW 131229 #define HID_DEBUG_WINDOW_OPTION 98317 #define HID_DESTROY_TICKETS_COMMAND 98313 #define HID_DESTROY_TICKETS_ON_EXIT 98321 #define HID_EXIT_COMMAND 123201 #define HID_GET_TICKETS_COMMAND 98343 #define HID_RENEW_TICKETS_COMMAND 98312 #define HID_IMPORT_TICKETS_COMMAND 98342 #define HID_HELP_CONTENTS 98340 #define HID_KERBEROS_PROPERTIES_ADDDOM 131255 #define HID_KERBEROS_PROPERTIES_ADDHOST 131254 #define HID_KERBEROS_PROPERTIES_ADDHOST 131269 #define HID_KERBEROS_PROPERTIES_ADDRLM 131253 #define HID_KERBEROS_PROPERTIES_COMMAND 98337 #define HID_KERBEROS_PROPERTIES_EDIT 131233 #define HID_KERBEROS_PROPERTIES_EDITDOM 131256 #define HID_KERBEROS_PROPERTIES_EDITHOST 131271 #define HID_KERBEROS_PROPERTIES_LISTDOM 131279 #define HID_KERBEROS_PROPERTIES_LISTRLM 131250 #define HID_KRB4_PROPERTIES_COMMAND 98329 #define HID_KRB4_PROPERTIES_EDIT 131232 #define HID_KRB5_PROPERTIES_COMMAND 98330 #define HID_KRB5_PROPERTIES_EDIT 131241 #define HID_KRB5_PROPERTIES_FORWARDING 131240 #define HID_KRBCHECK_OPTION 98335 #define HID_LARGE_ICONS_OPTION 98322 #define HID_LEASH_COMMANDS 131200 #define HID_LEASH_PROGRAM 98319 #define HID_LEASH_PROPERTIES_COMMAND 98331 #define HID_LEASH_PROPERTIES_EDIT 131239 #define HID_LOW_TICKET_ALARM_OPTION 98334 #define HID_RESET_WINDOW_OPTION 98326 #define HID_SCNCHRONIZE_TIME_OPTION 98314 #define HID_STATUS_BAR_OPTION 124929 #define HID_TOOLBAR_OPTION 124928 #define HID_UPDATE_DISPLAY_COMMAND 98316 #define HID_UPPERCASE_REALM_OPTION 98323 #define HID_WHY_USE_LEASH32 98341 #define ID_CHANGEPASSWORD 112 #define ID_COUNTDOWN 101 #define ID_DESTROY 111 #define ID_EXIT 200 #define ID_HELP_CHOOSE_PASSWORD 2511841056 #define ID_HELP_KERBEROS 211 #define ID_HELP_LEASH 210 #define ID_HELP_PURPOSE 115 #define ID_INITTICKETS 113 #define KRB_BAD_NAME 39525457 #define KRB_BAD_TIME 39525413 #DEFINE KRB_ERROR_78 39525454 #define KRB_INCORR_PASSWD 39525438 #define KRB_NO_TKT_FILE 39525446 #define KRB_UNKNOWN_REALM 39525433 #define KRB_UNKNOWN_USER 39525384 #define LSH_INVINSTANCE 40591875 [INFOTYPES] ����krb5-1.16/src/windows/leash/htmlhelp/html/����������������������������������������������������������0000755�0007046�0000145�00000000000�13211554426�020334� 5����������������������������������������������������������������������������������������������������ustar �ghudson�������������������������libuuid����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������krb5-1.16/src/windows/leash/htmlhelp/html/FAQ.htm���������������������������������������������������0000644�0007046�0000145�00000010357�13211554426�021463� 0����������������������������������������������������������������������������������������������������ustar �ghudson�������������������������libuuid����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN"> <html><head> <meta name="GENERATOR" content="Microsoft HTML Help Workshop 4.1"> <link rel="stylesheet" type="text/css" href="Leash.css"> <title>FAQ

Frequently Asked Questions (FAQ)

How do I get tickets?

Click the Get Ticket button in the Home tab. In the Get Ticket window, enter your principal (your Kerberos identity) and password and click Okay. How to: Get Tickets

Back to top

Will I be warned when my tickets are about to expire?

Yes. A pop up window warns you 15, 10, and 5 minutes before your ticket expires. If you would also like an audible alarm at these intervals, go to the Options tab and select Expiration Alarm in the Ticket Options panel.
How to: Use Ticket Options Panel

Back to top

Are my tickets destroyed automatically when I exit MIT Kerberos?

Only if Destroy Tickets on Exit is selected in Ticket Options panel in the Options tab.
How to: Use Ticket Options Panel

Back to top

Why should I use renewable tickets?

Renewable tickets add convenience, especially if you turn on the option to automatically renew them. They allow you to run a batch job without interruption and to work through a long session without continually reentering your password.
About: Renewable Tickets

Back to top

If I set my tickets to renew automatically, will the renewals keep happening if I exit MIT Kerberos?

No. MIT Kerberos can only renew your tickets if the program is running and active. It cannot renew your tickets if you exit the program or if your computer is turned off or in hibernation mode.

Back to top

How to I forward my forwardable tickets?

That depends. Often they are forwarded automatically as needed. Ask your help desk or administrator for information specific to your installation.

Back to top

How do I use my RSA SecurID token with Kerberos?

If your company uses RSA SecurID to control access to Kerberos, you will be prompted to enter your SecurID password after you request a ticket.
How to: Get Tickets

Back to top

Can I use Kerberos with the command line prompt?

Yes. Click here for a list of available commands.

Back to top

Where can I set Kerberos properties?

You cannot use the MIT Kerberos program to set preferences such as default ticket lifetimes. Instead, edit the appropriate configuration file. For more information, visit the MIT Kerberos documentation site.

Back to top

krb5-1.16/src/windows/leash/htmlhelp/html/leash_external_klist.htm0000644000704600001450000000074613211554426025261 0ustar ghudsonlibuuid Why Use

klist.exe program

This application will quickly list all of the tickets you have.

krb5-1.16/src/windows/leash/htmlhelp/html/KPASSWD.htm0000644000704600001450000000275613211554426022174 0ustar ghudsonlibuuid KPASSWD

KPASSWD Command

The following information reproduces the information from UNIX man page for the KPASSWD command.

SYNOPSIS

kpasswd [principal]

DESCRIPTION

The kpasswd command is used to change a Kerberos principal's password. kpasswd first prompts for the current Kerberos password, then prompts the user twice for the new password, and the password is changed. If the principal is governed by a policy that specifies the length and/or number of character classes required in the new password, the new password must conform to the policy. (The five character classes are lower case, upper case, numbers, punctuation, and all other characters.)

OPTIONS

principal Change the password for the Kerberos principal principal. Otherwise, kpasswd uses the principal name from an existing ccache if there is one; if not, the principal is derived from the identity of the user invoking the kpasswd command.

SEE ALSO

  • kadmin
  • kadmind
krb5-1.16/src/windows/leash/htmlhelp/html/leash_topic_error_invalid_principal.htm0000644000704600001450000000116313211554426030321 0ustar ghudsonlibuuid Invalid Principle

Invalid principal.

This usually means that you just clicked on the OK button or pressed Enter without typing your username.

krb5-1.16/src/windows/leash/htmlhelp/html/Using_Leash_Menus.htm0000644000704600001450000002055013211554426024420 0ustar ghudsonlibuuid Using MIT Kerberos Menus Using Kerberos Menus

Using Kerberos Menus

MIT Kerberos uses a ribbon menu. Most commands and options are available in the two tabs in the ribbon at the top of the main window. The Home tab contains command buttons. The Options tab contains checkboxes for controlling ticket and view options.

A few commands and options are controlled in the Get Ticket window. The Get Ticket window allows you to choose ticket settings and to clear your principal history.

Browse the tables below to see what each button and option does. Or click here for an introduction to using MIT Kerberos.

On this pageOn other pages
Learn about.... How to....

Home Tab

Home Tab

MIT Kerberos opens with the Home tab visible. Use the buttons in the Home tab to work with tickets and passwords and to change your default principal. Depending on your installation and your needs, you might not need every button.

The table below gives a quick explanation of each of the buttons. To jump to a detailed How To page for a button, click the button name.

Button Function
Get Tickets Get a new MIT Kerberos ticket.

How to: Get Tickets
Renew Tickets Renew tickets for the selected principal(s). Renewing a ticket extends its valid lifetime, resetting it to the length of the original ticket.

How to: Renew Tickets
Destroy Tickets Destroy all of your MIT Kerberos tickets.

How to: Destroy Tickets
Make Default Make the selected principal the default principal. Not necessary if you have only one principal.

How to: Make Default
Change Password Change your MIT Kerberos password.

How to: Change Password

Back to Top

Options Tab

Home Tab

Click the Options tab to reach the checkboxes that control ticket and view options. The Options tab has two panels. Use the View Options panel to choose which information is displayed for your tickets. Use the Ticket Options panel to turn MIT Kerberos's automatic features on or off.

View Options Panel

The View Options checkboxes control what ticket information is displayed. Select a checkbox to see the information column it controls, or deselect the checkbox to hide it.

The table below gives a quick explanation of each of the View options.

CheckboxInformation Displayed When Checked
checkbox image Issued            
The date and time that your tickets were issued.
checkbox image Renewable Until
The date and time when you will no longer be able to renew your current tickets.

About: Renewable Until
checkbox image Valid Until
When your ticket will expire.

About: Valid Until
checkbox image Encryption Type
The type of encryption used to encrypt your tickets and session keys.

About: Encryption Type
checkbox image Flags              
How the tickets were flagged (renewable and/or fowardable) when you obtained them.

About: Flags

Back to Top

Ticket Options Panel

The Ticket Options checkboxes control MIT Kerberos's automatic features. Select a checkbox to turn a feature on, or deselect a checkbox to turn the feature off.

The table below gives a quick explanation of each of the Ticket options.

Checkbox Select This Option to:
checkbox image Automatic Ticket Renewal
Automatically renew your Kerberos tickets for their entire renewable lifetime, without promptings or requiring a password, when possible.

About: Automatic Ticket Renewal
checkbox image Expiration Alarm
Have MIT Kerberos provide an audible alarm 15, 10, and 5 minutes before your tickets expire.

About: Expiration Alarm
checkbox image Destroy Tickets on Exit
Have MIT Kerberos destroy your tickets when you exit the program.

About: Destroy Tickets on Exit
checkbox image Allow Mixed Case Realm Name
Allow you to get tickets for a realm that has a name that includes lower case letters.

About: Allow Mixed Case Realm Name

Back to Top

krb5-1.16/src/windows/leash/htmlhelp/html/More_Menu.htm0000644000704600001450000000373513211554426022744 0ustar ghudsonlibuuid More Panel

Using the More Panel

Use the More panel to reach features not needed by all users.

Find the More panel

The More panel is the panel on the far right of the ribbon menu. If your Kerberos window is wide enough, you will see the full More panel. If the window is too small to display it, you will see a More button. Click the More button to reach the full panel options.

Option Select if... Details
Forget Principals You have previously entered a principal in the Get Ticket window and saved it, but you no longer want that principal included in the auto-complete feature or list of saved principals. Select this to delete all saved principals from the auto-complete list in the Get Ticket and Change Password windows.
More Forget Principals help
Allow Mixed Case Realm Name If your Kerberos realm name uses any lower case letters. Kerberos realms are a way of logically grouping resources and identities that use Kerberos. By convention, realm names use all upper case letters. This helps distinguish a realm from the DNS domain it corrosponds to. Realm names are case sensitive. So for convenience, anything you enter in the realm field of the Get Ticket window is converted to upper case, unless you turn this option on.

Related help

krb5-1.16/src/windows/leash/htmlhelp/html/hid_sc_maximize.htm0000644000704600001450000000060313211554426024201 0ustar ghudsonlibuuid (Maximize command (System menu))

Maximize command (System menu)

Use this command to enlarge the active window to fill the available space.

krb5-1.16/src/windows/leash/htmlhelp/html/leash_manpage_klist.htm0000644000704600001450000000610513211554426025042 0ustar ghudsonlibuuid KLIST Command

KLIST Command

(from UNIX man page)

User Commands  KLIST ( 1 )

NAME
 klist - list cached Kerberos tickets

SYNOPSIS
 klist [-5] [-4] [-e] [[-c] [-f] [-s] [-a [-n]]] [-k [-t] [-K]]
 [cache_name | keytab_name]

DESCRIPTION

 Klist lists the Kerberos principal and Kerberos tickets held in a
 credentials cache, or the keys held in a keytab file.  If klist was
 built with Kerberos 4 support, the default behavior is to list both
 Kerberos 5 and Kerberos 4 credentials.  Otherwise, klist will default
 to listing only Kerberos 5 credentials.

OPTIONS
 -5 list Kerberos 5 credentials.  This overrides whatever the default
 built-in behavior may be.  This option may be used with -4

 -4 list Kerberos 4 credentials.  This overrides whatever the default
 built-in behavior may be.  This option is only available if kinit was
 built with Kerberos 4 compatibility.  This option may be used with -5

 -e displays the encryption types of the session key and the ticket
 for each credential in the credential cache, or each key in the
 keytab file.

 -c List tickets held in a credentials cache.  This is the default if
 neither -c nor -k is specified.

 -f shows the flags present in the credentials, using the following
 abbreviations:

 F Forwardable
 f forwarded
 P Proxiable
 p proxy
 D postDateable
 d postdated
 R Renewable
 I Initial
 i invalid

 -s causes klist to run silently (produce no output), but to still set
 the exit status according to whether it finds the credentials cache.
 The exit status is `0' if klist finds a credentials cache, and `1' if
 it does not.

 -a display list of addresses in credentials.

 -n show numeric addresses instead of reverse-resolving addresses.

 -k List keys held in a keytab file.

 -t display the time entry timestamps for each keytab entry in the
 keytab file.

 -K display the value of the encryption key in each keytab entry in
 the keytab file.

 If cache_name or keytab_name is not specified, klist will display the
 credentials in the default credentials cache or keytab file as
 appropriate.  If the KRB5CCNAME environment variable is set, its
 value is used to name the default ticket cache.

ENVIRONMENT
 Klist uses the following environment variables:

 KRB5CCNAME Location of the Kerberos 5 credentials (ticket) cache.

 KRBTKFILE Filename of the Kerberos 4 credentials (ticket) cache.

FILES
 /tmp/krb5cc_[uid] default location of Kerberos 5 credentials cache
 ([uid] is the decimal UID of the user).

 /tmp/tkt[uid] default location of Kerberos 4 credentials cache ([uid]
 is the decimal UID of the user).

 /etc/krb5.keytab
 default location for the local host's keytab file.

SEE  ALSO
 kinit(1), kdestroy(1), krb5(3)
krb5-1.16/src/windows/leash/htmlhelp/html/leash_topic_kerberos_tickets.htm0000644000704600001450000000252313211554426026764 0ustar ghudsonlibuuid Kerberos Tickets

Kerberos Tickets

When you authenticate yourself with Kerberos, through either the Leash program or the kinit command, Kerberos gives you an initial Kerberos ticket. (A Kerberos ticket is an encrypted protocol message that provides authentication.) Kerberos uses this ticket for network utilities such as telnet, ftp or email. The ticket transactions are done transparently, so you don't have to worry about their management.

Note, however, that tickets expire. Privileged tickets, such as root instance tickets, expire in a few minutes, while tickets that carry more ordinary privileges may be good for several hours or a day, depending on the installation's policy. On Athena, the default time limit is 10 hours; if your login session extends beyond the time limit, you will have to reauthenticate yourself to Kerberos to get new tickets.

See Also

An Authentication Service

How Does the Other Guy Know Who I Am?

krb5-1.16/src/windows/leash/htmlhelp/html/hid_app_exit.htm0000644000704600001450000000121713211554426023504 0ustar ghudsonlibuuid (File Exit command)

Exit command (File menu)

Use this command to end your <<YourApp>> session. You can also use the Close command on the application Control menu. <<YourApp>> prompts you to save documents with unsaved changes.

krb5-1.16/src/windows/leash/htmlhelp/html/Report_Bugs.htm0000644000704600001450000000210013211554426023272 0ustar ghudsonlibuuid Report_Bugs

Report Bugs or Request Assistance

Bug Reports

We strive to provide a robust product. If you find bugs in Kerberos for Windows, we want to know about them. Please email bug reports to kfw-bugs@MIT.EDU. Please provide as much detail as you can so that we can replicate the issue.

Requesting Assistance/Joining Discussion

The Usenet newsgroup comp.protocols.kerberos is dedicated to discussing Kerberos issues. The mailing list kerberos@MIT.EDU is gatewayed to the newsgroup.

To subscribe to the mailing list, email a request to kerberos-request@MIT.EDU or submit the online subscription form

krb5-1.16/src/windows/leash/htmlhelp/html/leash_view_status_bar.htm0000644000704600001450000000124013211554426025420 0ustar ghudsonlibuuid Status Bar Option

Status Bar

The Status Bar is on by default; turning it off causes the bar at the bottom of the Leash window (with the time remaining on any tickets that you might have) to disappear.

krb5-1.16/src/windows/leash/htmlhelp/html/leash_option_auto_renewal.htm0000644000704600001450000000156513211554426026306 0ustar ghudsonlibuuid Automatic Ticket Renewal Option

Automatic Ticket Renewal Option

When Automatic Ticket Renewal is on, whenever tickets (or tokens) are near expiration (within 15 minutes) Leash will attempt to extend the ticket lifetime either via ticket renewal or ticket importation.  If these attempts fail, Leash will display the ticket initialization dialog.  In this way, Leash ensures that there are always valid Kerberos tickets (and AFS tokens).
krb5-1.16/src/windows/leash/htmlhelp/html/hid_view_toolbar.htm0000644000704600001450000000140013211554426024361 0ustar ghudsonlibuuid (View Toolbar command)

Toolbar command (View menu)

Use this command to display and hide the toolbar, which includes buttons for some of the most common commands in <<YourApp>>, such as File Open. A checkmark appears next to the menu item when the toolbar is displayed.

See Toolbar for help on using the toolbar.

krb5-1.16/src/windows/leash/htmlhelp/html/KCPYTKT.htm0000644000704600001450000000425013211554426022200 0ustar ghudsonlibuuid KCPYTKT

KCPYTKT Command

The following information reproduces the information from UNIX man page for the KCPYTKT command.

SYNOPSIS

kcpytkt [-h] [-c source_ccache [-e etype] [-f flags] dest_ccache service1 service2 ..

DESCRIPTION

kcpykt copies the specified service tickets to the destination credentials cache.

OPTIONS

-c Specifies the source credentials cache from which service tickets will be copied. If no ccache is specified, the default ccache is used.
-e etype Specifies the session key enctype of the service tickets you wish to delete.
-h Prints a usage statement and exits.

ENVIRONMENT

kcpytkt uses the following environment variables:

KRB5CCNAME Location of the credentials (ticket) cache.

FILES

/tmp/krb5cc_[uid] default location of the credentials (ticket) cache ([uid] is the decimal UID of the user).

SEE ALSO

krb5-1.16/src/windows/leash/htmlhelp/html/Home_Tab.htm0000644000704600001450000001052013211554426022522 0ustar ghudsonlibuuid Home Tab

Using the Home Tab

Home Tab

Use the buttons in the Home tab to work with tickets and passwords. Several button functions can also be reached with keyboard shortcuts.
How to: Use Keyboard Shortcuts

ButtonFunction
Get Tickets Click this button to get new MIT Kerberos tickets.

Clicking the button opens the Get Ticket window. Enter your Kerberos principal and password. To verify or change ticket settings and flags, click the Show Advanced button. When you are finished, click Okay.
How to: Get Tickets
Renew Tickets Click this button to renew your tickets.

All of your renewable tickets that have not yet expired will have their renewable lifetimes extended. Each ticket will be reset to the length of the original ticket's lifespan.
How to: Renew Tickets

Note: If you have multiple principals, first select the principal(s) with tickets you want to renew.
Destroy Tickets Click this button to immediately destroy all of your MIT Kerberos tickets.
How to: Destroy Tickets
Make Default Make the selected principal the default principal.

Note: You won't need to use this button if you have only one principal.

Select a principal by clicking it. Then click Make Default to make the selected principal the default one. The default principal is the one whose tickets are used when an application or service asks for tickets without specifying which principal is being authenticated.
How to: Make Default Principal
Change Password Change your MIT Kerberos password.
How to: Change Password

Note: If you have multiple principals, you can enter the appropriate one in the Change Password window, or you can click a principal to select it before using the Change Password button.

Related help

krb5-1.16/src/windows/leash/htmlhelp/html/leash_topic_kerberos_names.htm0000644000704600001450000000277713211554426026434 0ustar ghudsonlibuuid Kerberos Names

Kerberos Names

A Kerberos name contains three parts. The first is the principal name, which is usually a user's or service's name. The second is the instance, which in the case of a user is usually null. Some users may have privileged instances, however, such as "root" or "admin." In the case of a service, the instance is the name of the machine on which it runs; i.e. there can be an rlogin service running on the machine ABC, which is different from the rlogin service running on the machine XYZ. The third part of a Kerberos name is the realm. The realm corresponds to the Kerberos service providing authentication for the principal. For example, at MIT there is a Kerberos running at the Laboratory for Computer Science and one running at Project Athena.

When writing a Kerberos name, the principal name is separated from the instance (if not null) by a period, and the realm (if not the local realm) follows, preceded by an "@" sign. The following are examples of valid Kerberos names:

billb

jis.admin

srz@LCS.MIT.EDU

treese.root@ATHENA.MIT.EDU

krb5-1.16/src/windows/leash/htmlhelp/html/leash_topic_kerberos_help_topics.htm0000644000704600001450000000174713211554426027636 0ustar ghudsonlibuuid Leash Program

Kerberos Help Topics

About Kerberos

Kerberos Names

Kerberos Tickets

Using Kerberos in a Command Prompt Environment

Kerberos Copyright

Kerberos Export Restrictions and Source Code Access

Kerberos Timing Issues

krb5-1.16/src/windows/leash/htmlhelp/html/KDESTROY.htm0000644000704600001450000000647013211554426022321 0ustar ghudsonlibuuid KDESTROY

KDESTROY Command

The following information reproduces the information from UNIX man page for the KDESTROY command.

SYNOPSIS

kdestroy [-A] [-q] [-c cache_name]

DESCRIPTION

The kdestroy utility destroys the user's active Kerberos authorization tickets by writing zeros to the specified credentials cache that contains them. If the credentials cache is not specified, the default credentials cache is destroyed.

OPTIONS

-A Destroys all caches in the collection, if a cache collection is available.
-q Run quietly. Normally kdestroy beeps if it fails to destroy the user's tickets. The -q flag suppresses this behavior.
-c cache_name Use cache_name as the credentials (ticket) cache name and location; if this option is not used, the default cache name and location are used.
The default credentials cache may vary between systems. If the KRB5CCNAME environment variable is set, its value is used to name the default ticket cache.

Most installations recommend that you place the kdestroy command in your .logout file, so that your tickets are destroyed automatically when you log out.

ENVIRONMENT

Kdestroy uses the following environment variables:

KRB5CCNAME Location of the default Kerberos 5 credentials (ticket) cache, in the form type:residual. If no type prefix is present, the FILE type is assumed. The type of the default cache may determine the availability of a cache collection; for instance, a default cache of type DIR causes caches within the directory to be present in the collection.

FILES

/tmp/krb5cc_[uid] default location of Kerberos 5 credentials cache ([uid] is the decimal UID of the user).

SEE ALSO

BUGS

Only the tickets in the specified credentials cache are destroyed. Separate ticket caches are used to hold root instance and password changing tickets. These should probably be destroyed too, or all of a user's tickets kept in a single credentials cache.

krb5-1.16/src/windows/leash/htmlhelp/html/leash_file_exit.htm0000644000704600001450000000164213211554426024175 0ustar ghudsonlibuuid Exit/End Leash Program

Exit Command

From the File menu, you can use this command to exit the Leash program.  If any other means is used to close the Leash window, the Leash program will continue to execute and remain present in the Windows System Tray.

Important Note...

Exiting the Leash program will not destroy your current Kerberos tickets. Unless you have selected this in the options menu, you need to use the destroy tickets command.

krb5-1.16/src/windows/leash/htmlhelp/html/leash_view_large_icons.htm0000644000704600001450000000153513211554426025545 0ustar ghudsonlibuuid Large Icons Option

Large Icons

When this option is checked on the View menu, the icons and fonts in the main window (such as the picture of Kerberos) will be about twice as big as the minimal icon and font size.  Naturally, smaller icons allow many more tickets to fit into a nonscrolling window.  The default setting of Leash is Large Icons.

krb5-1.16/src/windows/leash/htmlhelp/html/leash_manpage_kinit.htm0000644000704600001450000001467113211554426025041 0ustar ghudsonlibuuid KINIT Command

KINIT Command

(from UNIX man page)

User Commands                                            KINIT(1)

NAME
kinit - obtain and cache Kerberos ticket-granting ticket

SYNOPSIS
kinit
[-5] [-4] [-V] [-l lifetime] [-s start_time] [-r
renewable_life] [-p | -P] [-f | -F] [-A] [-v] [-R] [-k
[-t keytab_file]] [-c cache_name] [-S service_name]
[principal]

DESCRIPTION
kinit obtains and caches an initial ticket-granting ticket
for principal.Thetypicaldefaultbehavior Kerberos 5 tickets.
However, if kinit was built with both Kerberos 4 support and
with the default behavior of acquiring both types of tick-
ets, it will try to acquire both Kerberos 5 and Kerberos 4
by default. Any documentation particular to Kerberos 4 does
not apply if Kerberos 4 support was not built into kinit.

OPTIONS
-5 get Kerberos 5 tickets. This overrides whatever the
default built-in behavior may be. This option may be
used with -4

-4 get Kerberos 4 tickets. This overrides whatever the
default built-in behavior may be. This option is only
available if kinit was built with Kerberos 4 compati-
bility. This option may be used with -5

-V display verbose output.

-l lifetime
requests a ticket with the lifetime lifetime. The
value for lifetime must be followed immediately by one
of the following delimiters:

s seconds
m minutes
h hours
d days

as in "kinit -l 90m". You cannot mix units; a value of
`3h30m' will result in an error.

If the -l option is not specified, the default ticket
lifetime (configured by each site) is used. Specifying
a ticket lifetime longer than the maximum ticket life-
time (configured by each site) results in a ticket with
the maximum lifetime.

-s start_time
requests a postdated ticket, valid starting at
start_time. Postdated tickets are issued with the
invalid flag set, and need to be fed back to the kdc
before use. (Not applicaple to Kerberos 4.)

-r renewable_life
requests renewable tickets, with a total lifetime of
renewable_life. The duration is in the same format as
the -l option, with the same delimiters. (Not applica-
ple to Kerberos 4.)

-f request forwardable tickets. (Not applicaple to Ker-
beros 4.)

-F do not request forwardable tickets. (Not applicaple to
Kerberos 4.)

-p request proxiable tickets. (Not applicaple to Kerberos
4.)

-P do not request proxiable tickets. (Not applicaple to
Kerberos 4.)

-A request address-less tickets. (Not applicaple to Ker-
beros 4.)

-v requests that the ticket granting ticket in the cache
(with the invalid flag set) be passed to the kdc for
validation. If the ticket is within its requested time
range, the cache is replaced with the validated ticket.
(Not applicaple to Kerberos 4.)

-R requests renewal of the ticket-granting ticket. Note
that an expired ticket cannot be renewed, even if the
ticket is still within its renewable life. When using
this option with Kerberos 4, the kdc must support Ker-
beros 5 to Kerberos 4 ticket conversion.

-k [-t keytab_file]
requests a host ticket, obtained from a key in the
local host's keytab file. The name and location of the
keytab file may be specified with the -t keytab_file
option; otherwise the default name and location will be
used. When using this option with Kerberos 4, the kdc
must support Kerberos 5 to Kerberos 4 ticket conver-
sion.

-c cache_name
use cache_name as the Kerberos 5 credentials (ticket)
cache name and location; if this option is not used,
the default cache name and location are used.

The default credentials cache may vary between systems.

If the KRB5CCNAME environment variable is set, its
value is used to name the default ticket cache. Any
existing contents of the cache are destroyed by kinit.
(Note: The default name for Kerberos 4 comes from the
KRBTKFILE environment variable. This option does not
apply to Kerberos 4.)

-S service_name
specify an alternate service name to use when getting
initial tickets. (Applicable to Kerberos 5 or if using
both Kerberos 5 and Kerberos 4 with a kdc that supports
Kerberos 5 to Kerberos 4 ticket conversion.)

ENVIRONMENT
Kinit uses the following environment variables:

KRB5CCNAME Location of the Kerberos 5 credentials
(ticket) cache.

KRBTKFILE Filename of the Kerberos 4 credentials
(ticket) cache.

FILES
/tmp/krb5cc_[uid] default location of Kerberos 5 creden-
tials cache ([uid] is the decimal UID of
the user).

/tmp/tkt[uid] default location of Kerberos 4 credentials
cache ([uid] is the decimal UID of the user).

/etc/krb5.keytab
default location for the local host's keytab
file.

SEE ALSO
klist(1), kdestroy(1), krb5(3)


krb5-1.16/src/windows/leash/htmlhelp/html/leash_topic_why_use.htm0000644000704600001450000000634613211554426025114 0ustar ghudsonlibuuid Why use Leash?

Why Use Leash?

Leash is a graphical system-tray tool designed to manage for Kerberos tickets on Microsoft Windows.  Leash is used to obtain Kerberos tickets, change your Kerberos password, and obtain Andrew File System (AFS) tokens.

Leash combines the functionality of several command line tools a user would use to manage Kerberos functions: kinit, klist, kdestroy, ms2mit, aklog, and passwd or kpasswd. Leash combines all of these functions into one user interface and supports  auto-renewal or user notification when tickets are approaching expiration.

There are many ways to execute Leash. In addition to clicking on a Leash shortcut, you can start Leash from the Windows command Prompt or Run... option.  Command-line options may be specified.  If you run Leash with the options -i or -kinit, it will display the ticket initialization dialog and exit; -m or ms2mit or import will import tickets from the Microsoft Windows logon session (if available) and exit; -d or -destroy will destroy all existing tickets and exit; -r or renew will renew existing Kerberos tickets (if possible) and exit; -a or autoinit will display the ticket initialization dialog if you have no Kerberos tickets. 

You may create a shortcut to Leash within your Windows Startup folder (Start Menu->Programs->Startup).   A shortcut to Leash32.exe autoinit ensures that Kerberos tickets are available for the use of Kerberized applications throughout your Windows logon session.

If Leash is not executed before using a Kerberized application, the application may prompt you for your password. Some applications, like lpr, never prompt you for a password. These applications simply terminate with a message indicating that you are not authenticated. Before these applications can successfully be used a separate program, such as Leash or kinit, must be used to first authenticate you using Kerberos. 

Leash does not perform a logon in the sense of the Windows Logon Service.  A logon service would do more than manage Kerberos tickets. A logon service would authenticate you to the local machine, validate access to your local file system and performs additional set-up tasks. These are beyond the scope of Leash. Leash simply allows you to manage Kerberos tickets on behalf of compatible applications and to change your Kerberos password.

krb5-1.16/src/windows/leash/htmlhelp/html/Tickets.htm0000644000704600001450000001425613211554426022464 0ustar ghudsonlibuuid Tickets

About Tickets

The MIT Kerberos program helps you manage your Kerberos tickets. Click the Get Ticket button and enter your principal (your Kerberos identity) and password to obtain a ticket. The ticket allows you to securely access all of the computers and services set up to authenticate you through Kerberos, until the ticket expires, without requiring you to enter your password again.

On this pageOn other pages
Learn about... How to...

Ticket Expiration
Your tickets are valid for a set amount of time before they expire and cannot be used again. Usually tickets are valid for around the length of a work day (e.g., 8 hours). A pop up window warns you 15, 10, and 5 minutes before your tickets expire. To add an audible alarm at the same intervals, go to the Options tab and select Expiration Alarm in the Ticket Options panel.
AdjustView
When you get your ticket, click Show Advanced to view and adjust the ticket's lifetime. Note that some Kerberos installations will not allow you to adjust the ticket lifetime.
How to: Get Tickets
The main window includes a Valid Until column for each of your tickets. After the time listed in this column, the ticket will expire and you must get a new ticket to access network resources that use Kerberos.
How to: View Tickets

Back to Top

Renewable Tickets
When you get your ticket, you have the option of flagging the ticket as renewable. Renewable tickets allow you to run batch jobs without interruption and to work through a long session without continually reentering your password.

Renewable Ticket Expiration Renewable tickets have a normal ticket lifetime, but they also have a renewable lifetime that is much longer (usually several days). Each time you renew your ticket, Kerberos resets the ticket lifetime to the length of the original ticket. You can renew the ticket as often as you need to (once at time or automatically) until the renewable lifetime is reached. Then you must obtain a new ticket.
Obtain Renewable Tickets When you get your ticket, click Show Advanced and then select Renewable under "Flag this ticket as." Use the Renewable Until slider to adjust the ticket's renewable lifetime.
How to: Get Tickets
Renew Once Click the Renew button. Note that you cannot renew expired tickets even if the ticket is still within its renewable lifespan.
How to: Renew Ticket Once
Renew Automatically Go to the Options tab and select Automatic Ticket Renewal in the Ticket Options panel. Note that MIT Kerberos must be active and running in order to renew tickets. This means that if your machine is in hibernation mode or if MIT Kerberos is not running when it is time to renew your tickets, your tickets will not be renewed.
How to: Renew Tickets Automatically
View In the Options tab, the View Options panel checkboxes control what information is displayed for your tickets. Two columns relate to renewable tickets: Renewable Until and Flags.

To see the date and time your renewable tickets expire and can no longer be renewed, go to the Options tab and select the Renewable Until checkbox in the View Options panel. To see which of your tickets are renewable, select Flags.
How to: View Tickets

Back to Top

Forwardable Tickets
When you get your ticket, you have the option of flagging the ticket as forwardable and proxiable. Forwardable and proxiable tickets can be forwarded to the remote host when you connect via telnet, ssh, ftp, rlogin, or similar applications, so you will not need to get new tickets to use remote services.
Obtain Forwardable Tickets View
When you get your ticket, click Show Advanced and then select Forwardable and Proxiable under "Flag this ticket as."
How to: Get Tickets
In the Options tab, the View Options panel checkboxes control what information is displayed for your tickets. Select the Flags checkbox to open a column indicating which of your tickets are forwardable.
How to: View Tickets

Back to Top

krb5-1.16/src/windows/leash/htmlhelp/html/leash_topic_kerberos_command_prompt.htm0000644000704600001450000000201313211554426030327 0ustar ghudsonlibuuid Using Kerberos in a Command Prompt Environment

Using Kerberos in a Command Prompt Environment

Command Prompt commands that are available to perform Kerberos functions

KINIT - Kerberos log-in utility

KLIST - list currently held Kerberos tickets

KDESTROY - destroy Kerberos tickets

MS2MIT - import Kerberos tickets from Windows Logon Session

AKLOG - obtain AFS tokens

krb5-1.16/src/windows/leash/htmlhelp/html/KSWITCH.htm0000644000704600001450000000454113211554426022166 0ustar ghudsonlibuuid KSWITCH

KSWITCH Command

The following information reproduces the information from UNIX man page for the KSWITCH command.

SYNOPSIS

kswitch { -c cache_name | -p principal }

DESCRIPTION

kswitch makes the specified credential cache the primary cache for the collection, if a cache collection is available.

OPTIONS

-c cache_name Directly specifies the credential cache to be made primary.
-p principal Causes the cache collection to be searched for a cache containing credentials for principal. If one is found, that collection is made primary.

ENVIRONMENT

kswitch uses the following environment variables:

KRB5CCNAME Location of the default Kerberos 5 credentials (ticket) cache, in the form type:residual. If no type prefix is present, the FILE type is assumed. The type of the default cache may determine the availability of a cache collection; for instance, a default cache of type DIR causes caches within the directory to be present in the collection.

FILES

/tmp/krb5cc_[uid] default location of Kerberos 5 credentials cache ([uid] is the decimal UID of the user).

SEE ALSO

  • kinit
  • kdestroy
  • klist
  • kerberos (1)
  • krb5-1.16/src/windows/leash/htmlhelp/html/leash_topic_kerberos_auth_service.htm0000644000704600001450000016452213211554426030007 0ustar ghudsonlibuuid An Authentication Service for Open Network Systems

    Kerberos: An Authentication Service for Open Network Systems

    Jennifer G. Steiner

    Project Athena
    Massachusetts Institute of Technology
    Cambridge, MA 02139
    steiner@ATHENA.MIT.EDU

    Clifford Neuman *

    Department of Computer Science, FR-35
    University of Washington
    Seattle, WA 98195
    bcn@CS.WASHINGTON.EDU

    Jeffrey I. Schiller

    Project Athena
    Massachusetts Institute of Technology
    Cambridge, MA 02139
    jis@ATHENA.MIT.EDU

    * Clifford Neuman was a member of the Project Athena staff during the design and initial implementation phase of Kerberos.

    ABSTRACT

    In an open network computing environment, a workstation cannot be trusted to identify its users correctly to network services. Kerberos provides an alternative approach whereby a trusted third-party authentication service is used to verify users' identities. This paper gives an overview of the Kerberos authentication model as implemented for MIT's Project Athena. It describes the protocols used by clients, servers, and Kerberos to achieve authentication. It also describes the management and replication of the database required. The views of Kerberos as seen by the user, programmer, and administrator are described. Finally, the role of Kerberos in the larger Athena picture is given, along with a list of applications that presently use Kerberos for user authentication. We describe the addition of Kerberos authentication to the Sun Network File System as a case study for integrating Kerberos with an existing application.

    Introduction

    This paper gives an overview of Kerberos, an authentication system designed by Miller and Neumanfor open network computing environments, and describes our experience using it at MIT's Project Athena. In the first section of the paper, we explain why a new authentication model is needed for open networks, and what its requirements are. The second section lists the components of the Kerberos software and describes how they interact in providing the authentication service. In Section 3, we describe the Kerberos naming scheme.

    Section 4 presents the building blocks of Kerberos authentication - the ticket and the authenticator. This leads to a discussion of the two authentication protocols: the initial authentication of a user to Kerberos (analogous to logging in), and the protocol for mutual authentication of a potential consumer and a potential producer of a network service.

    Kerberos requires a database of information about its clients; Section 5 describes the database, its management, and the protocol for its modification. Section 6 describes the Kerberos interface to its users, applications programmers, and administrators. In Section 7, we describe how the Project Athena Kerberos fits into the rest of the Athena environment. We also describe the interaction of different Kerberos authentication domains, or realms ; in our case, the relation between the Project Athena Kerberos and the Kerberos running at MIT's Laboratory for Computer Science.

    In Section 8, we mention open issues and problems as yet unsolved. The last section gives the current status of Kerberos at Project Athena. In the appendix, we describe in detail how Kerberos is applied to a network file service to authenticate users who wish to gain access to remote file systems.

    Conventions. Throughout this paper we use terms that may be ambiguous, new to the reader, or used differently elsewhere. Below we state our use of those terms.

    User, Client, Server. By user, we mean a human being who uses a program or service. A client also uses something, but is not necessarily a person; it can be a program. Often network applications consist of two parts; one program which runs on one machine and requests a remote service, and another program which runs on the remote machine and performs that service. We call those the client side and server side of the application, respectively. Often, a client will contact a server on behalf of a user.

    Each entity that uses the Kerberos system, be it a user or a network server, is in one sense a client, since it uses the Kerberos service. So to distinguish Kerberos clients from clients of other services, we use the term principal to indicate such an entity. Note that a Kerberos principal can be either a user or a server. (We describe the naming of Kerberos principals in a later section.)

    Service vs. Server. We use service as an abstract specification of some actions to be performed. A process which performs those actions is called a server. At a given time, there may be several servers (usually running on different machines) performing a given service. For example, at Athena there is one BSD UNIX rlog-in server running on each of our timesharing machines.

    Key, Private Key, Password. Kerberos uses private key encryption. Each Kerberos principal is assigned a large number, its private key, known only to that principal and Kerberos. In the case of a user, the private key is the result of a one-way function applied to the user's password. We use key as shorthand for private key.

    Credentials. Unfortunately, this word has a special meaning for both the Sun Network File System and the Kerberos system. We explicitly state whether we mean NFS credentials or Kerberos credentials, otherwise the term is used in the normal English language sense.

    Master and Slave. It is possible to run Kerberos authentication software on more than one machine. However, there is always only one definitive copy of the Kerberos database. The machine which houses this database is called the master machine, or just the master. Other machines may possess read-only copies of the Kerberos database, and these are called slaves.

    1. Motivation

    In a non-networked personal computing environment, resources and information can be protected by physically securing the personal computer. In a timesharing computing environment, the operating system protects users from one another and controls resources. In order to determine what each user is able to read or modify, it is necessary for the timesharing system to identify each user. This is accomplished when the user logs in.

    In a network of users requiring services from many separate computers, there are three approaches one can take to access control: One can do nothing, relying on the machine to which the user is logged in to prevent unauthorized access; one can require the host to prove its identity, but trust the host's word as to who the user is; or one can require the user to prove her/his identity for each required service.

    In a closed environment where all the machines are under strict control, one can use the first approach. When the organization controls all the hosts communicating over the network, this is a reasonable approach.

    In a more open environment, one might selectively trust only those hosts under organizational control. In this case, each host must be required to prove its identity. The rlog-in and rsh programs use this approach. In those protocols, authentication is done by checking the Internet address from which a connection has been established.

    In the Athena environment, we must be able to honor requests from hosts that are not under organizational control. Users have complete control of their workstations: they can reboot them, bring them up standalone, or even boot off their own tapes. As such, the third approach must be taken; the user must prove her/his identity for each desired service. The server must also prove its identity. It is not sufficient to physically secure the host running a network server; someone elsewhere on the network may be masquerading as the given server.

    Our environment places several requirements on an identification mechanism. First, it must be secure. Circumventing it must be difficult enough that a potential attacker does not find the authentication mechanism to be the weak link. Someone watching the network should not be able to obtain the information necessary to impersonate another user. Second, it must be reliable. Access to many services will depend on the authentication service. If it is not reliable, the system of services as a whole will not be. Third, it should be transparent. Ideally, the user should not be aware of authentication taking place. Finally, it should be scalable. Many systems can communicate with Athena hosts. Not all of these will support our mechanism, but software should not break if they did.

    Kerberos is the result of our work to satisfy the above requirements. When a user walks up to a workstation s/he "logs in". As far as the user can tell, this initial identification is sufficient to prove her/his identity to all the required network servers for the duration of the log-in session. The security of Kerberos relies on the security of several authentication servers, but not on the system from which users log in, nor on the security of the end servers that will be used. The authentication server provides a properly authenticated user with a way to prove her/his identity to servers scattered across the network.

    Authentication is a fundamental building block for a secure networked environment. If, for example, a server knows for certain the identity of a client, it can decide whether to provide the service, whether the user should be given special privileges, who should receive the bill for the service, and so forth. In other words, authorization and accounting schemes can be built on top of the authentication that Kerberos provides, resulting in equivalent security to the lone personal computer or the timesharing system.

    2. What is Kerberos ?

    Kerberos is a trusted third-party authentication service based on the model presented by Needham and Schroeder.It is trusted in the sense that each of its clients believes Kerberos' judgement as to the identity of each of its other clients to be accurate. Time stamps (large numbers representing the current date and time) have been added to the original model to aid in the detection of replay. Replay occurs when a message is stolen off the network and resent later. For a more complete description of replay, and other issues of authentication, see Voydock and Kent.

    2.1. What Does It Do?

    Kerberos keeps a database of its clients and their private keys. The private key is a large number known only to Kerberos and the client it belongs to. In the case that the client is a user, it is an encrypted password. Network services requiring authentication register with Kerberos, as do clients wishing to use those services. The private keys are negotiated at registration.

    Because Kerberos knows these private keys, it can create messages which convince one client that another is really who it claims to be. Kerberos also generates temporary private keys, called session keys, which are given to two clients and no one else. A session key can be used to encrypt messages between two parties.

    Kerberos provides three distinct levels of protection. The application programmer determines which is appropriate, according to the requirements of the application. For example, some applications require only that authenticity be established at the initiation of a network connection, and can assume that further messages from a given network address originate from the authenticated party. Our authenticated network file system uses this level of security.

    Other applications require authentication of each message, but do not care whether the content of the message is disclosed or not. For these, Kerberos provides safe messages. Yet a higher level of security is provided by private messages, where each message is not only authenticated, but also encrypted. Private messages are used, for example, by the Kerberos server itself for sending passwords over the network

    2.2. Software Components

    The Athena implementation comprises several modules (see Figure 1). The Kerberos applications library provides an interface for application clients and application servers. It contains, among others, routines for creating or reading authentication requests, and the routines for creating safe or private messages.

    • Kerberos applications library
    • encryption library
    • database library
    • database administration programs
    • administration server
    • authentication server
    • propogation software
    • user programs
    • applications

    Figure 1. Kerberos Software Components

    Encryption in Kerberos is based on DES, the Data Encryption Standard.The encryption library implements those routines. Several methods of encryption are provided, with tradeoffs between speed and security. An extension to the DES Cypher Block Chaining (CBC) mode, called the Propagating CBC mode, is also provided. In CBC, an error is propagated only through the current block of the cipher, whereas in PCBC, the error is propagated throughout the message. This renders the entire message useless if an error occurs, rather than just a portion of it. The encryption library is an independent module, and may be replaced with other DES implementations or a different encryption library.

    Another replaceable module is the database management system. The current Athena implementation of the database library uses ndbm, although INGRES was originally used. Other database management libraries could be used as well.

    The Kerberos database needs are straightforward; a record is held for each principal, containing the name, private key, and expiration date of the principal, along with some administrative information. (The expiration date is the date after which an entry is no longer valid. It is usually set to a few years into the future at registration.)

    Other user information, such as real name, phone number, and so forth, is kept by another server, the Hesiod nameserver. This way, sensitive information, namely passwords, can be handled by Kerberos, using fairly high security measures; while the non-sensitive information kept by Hesiod is dealt with differently; it can, for example, be sent unencrypted over the network.

    The Kerberos servers use the database library, as do the tools for administering the database.

    The administration server (or KDBM server) provides a read-write network interface to the database. The client side of the program may be run on any machine on the network. The server side, however, must run on the machine housing the Kerberos database in order to make changes to the database.

    The authentication server (or Kerberos server), on the other hand, performs read-only operations on the Kerberos database, namely, the authentication of principals, and generation of session keys. Since this server does not modify the Kerberos database, it may run on a machine housing a read-only copy of the master Kerberos database.

    Database propagation software manages replication of the Kerberos database. It is possible to have copies of the database on several different machines, with a copy of the authentication server running on each machine. Each of these slave machines receives an update of the Kerberos database from the master machine at given intervals.

    Finally, there are end-user programs for logging in to Kerberos, changing a Kerberos password, and displaying or destroying Kerberos tickets (tickets are explained later on).

    3. Kerberos Names

    Part of authenticating an entity is naming it. The process of authentication is the verification that the client is the one named in a request. What does a name consist of? In Kerberos, both users and servers are named. As far as the authentication server is concerned, they are equivalent. A name consists of a primary name, an instance, and a realm, expressed as name.instance@realm (see Figure 2).

    bcn

    treese.root

    jis@LCS.MIT.EDU

    rlog-in.priam@ATHENA.MIT.EDU

    Figure 2. Kerberos Names

    The primary name is the name of the user or the service. The instance is used to distinguish among variations on the primary name. For users, an instance may entail special privileges, such as the "root" or "admin" instances. For services in the Athena environment, the instance is usually the name of the machine on which the server runs. For example, the rlog-in service has different instances on different hosts: rlog-in.priam is the rlog-in server on the host named priam. A Kerberos ticket is only good for a single named server. As such, a separate ticket is required to gain access to different instances of the same service. The realm is the name of an administrative entity that maintains authentication data. For example, different institutions may each have their own Kerberos machine, housing a different database. They have different Kerberos realms. (Realms are discussed further in section 8.2.).

    4. How It Works

    This section describes the Kerberos authentication protocols. The following abbreviations are used in the figures.

    c        ->     client
    s       ->     server
    addr    -> client's network address
    life -> lifetime of ticket
    tgs, TGS -> ticket-granting ticket
    Kerberos -> authentication server
    KDBM -> administration server
    Kx -> x's private key
    Kx,y -> session key for x and y
    {abc}Kx -> abc encrypted in x's key
    Tx,y -> x's ticket to use y
    Ax -> authenticator for x
    WS -> workstation

    As mentioned above, the Kerberos authentication model is based on the Needham and Schroeder key distribution protocol. When a user requests a service, her/his identity must be established. To do this, a ticket is presented to the server, along with proof that the ticket was originally issued to the user, not stolen. There are three phases to authentication through Kerberos. In the first phase, the user obtains credentials to be used to request access to other services. In the second phase, the user requests authentication for a specific service. In the final phase, the user presents those credentials to the end server.

    4.1 Credentials

    There are two types of credentials used in the Kerberos authentication model: tickets and authenticators. Both are based on private key encryption, but they are encrypted using different keys. A ticket is used to securely pass the identity of the person to whom the ticket was issued between the authentication server and the end server. A ticket also passes information that can be used to make sure that the person using the ticket is the same person to which it was issued. The authenticator contains the additional information which, when compared against that in the ticket proves that the client presenting the ticket is the same one to which the ticket was issued.

    A ticket is good for a single server and a single client. It contains the name of the server, the name of the client, the Internet address of the client, a time stamp, a lifetime, and a random session key. This information is encrypted using the key of the server for which the ticket will be used. Once the ticket has been issued, it may be used multiple times by the named client to gain access to the named server, until the ticket expires. Note that because the ticket is encrypted in the key of the server, it is safe to allow the user to pass the ticket on to the server without having to worry about the user modifying the ticket (see Figure 3).

    {s, c, addr, timestamp, life, Ks,c} Ks

    Figure 3. Kerberos Ticket.

    Unlike the ticket, the authenticator can only be used once. A new one must be generated each time a client wants to use a service. This does not present a problem because the client is able to build the authenticator itself. An authenticator contains the name of the client, the workstation's IP address, and the current workstation time. The authenticator is encrypted in the session key that is part of the ticket (see Figure 4).

    { c, addr, timestamp } Ks,c

    Figure 4. A Kerberos Authenticator

    4.2. Getting the Initial Ticket

    When the user walks up to a workstation, only one piece of information can prove her/his identity: the user's password. The initial exchange with the authentication server is designed to minimize the chance that the password will be compromised, while at the same time not allowing a user to properly authenticate her/himself without knowledge of that password. The process of logging in appears to the user to be the same as logging in to a timesharing system. Behind the scenes, though, it is quite different (see Figure 5).


    Figure 5.
    Getting the Initial Ticket.

    The user is prompted for her/his username. Once it has been entered, a request is sent to the authentication server containing the user's name and the name of a special service known as the ticket-granting service.

    The authentication server checks that it knows about the client. If so, it generates a random session key which will later be used between the client and the ticket-granting server. It then creates a ticket for the ticket-granting server which contains the client's name, the name of the ticket-granting server, the current time, a lifetime for the ticket, the client's IP address, and the random session key just created. This is all encrypted in a key known only to the ticket-granting server and the authentication server.

    The authentication server then sends the ticket, along with a copy of the random session key and some additional information, back to the client. This response is encrypted in the client's private key, known only to Kerberos and the client, which is derived from the user's password.

    Once the response has been received by the client, the user is asked for her/his password. The password is converted to a DES key and used to decrypt the response from the authentication server. The ticket and the session key, along with some of the other information, are stored for future use, and the user's password and DES key are erased from memory.

    Once the exchange has been completed, the workstation possesses information that it can use to prove the identity of its user for the lifetime of the ticket-granting ticket. As long as the software on the workstation had not been previously tampered with, no information exists that will allow someone else to impersonate the user beyond the life of the ticket.

    4.3. Requesting a Service

    For the moment, let us pretend that the user already has a ticket for the desired server. In order to gain access to the server, the application builds an authenticator containing the client's name and IP address, and the current time. The authenticator is then encrypted in the session key that was received with the ticket for the server. The client then sends the authenticator along with the ticket to the server in a manner defined by the individual application.

    Once the authenticator and ticket have been received by the server, the server decrypts the ticket, uses the session key included in the ticket to decrypt the authenticator, compares the information in the ticket with that in the authenticator, the IP address from which the request was received, and the present time. If everything matches, it allows the request to proceed (see Figure 6).


    Figure 6.
    Requesting a Service

    It is assumed that clocks are synchronized to within several minutes. If the time in the request is too far in the future or the past, the server treats the request as an attempt to replay a previous request. The server is also allowed to keep track of all past requests with time stamps that are still valid. In order to further foil replay attacks, a request received with the same ticket and time stamp as one already received can be discarded.

    Finally, if the client specifies that it wants the server to prove its identity too, the server adds one to the time stamp the client sent in the authenticator, encrypts the result in the session key, and sends the result back to the client (see Figure 7).


    Figure 7.
    Mutual Authentication

    At the end of this exchange, the server is certain that, according to Kerberos, the client is who it says it is. If mutual authentication occurs, the client is also convinced that the server is authentic. Moreover, the client and server share a key which no one else knows, and can safely assume that a reasonably recent message encrypted in that key originated with the other party.

    4.4 Getting Server Tickets

    Recall that a ticket is only good for a single server. As such, it is necessary to obtain a separate ticket for each service the client wants to use. Tickets for individual servers can be obtained from the ticket-granting service. Since the ticket-granting service is itself a service, it makes use of the service access protocol described in the previous section.

    When a program requires a ticket that has not already been requested, it sends a request to the ticket-granting server (see Figure 8). The request contains the name of the server for which a ticket is requested, along with the ticket-granting ticket and an authenticator built as described in the previous section.


    Figure 8.
    Getting a Server Ticket

    The ticket-granting server then checks the authenticator and ticket-granting ticket as described above. If valid, the ticket-granting server generates a new random session key to be used between the client and the new server. It then builds a ticket for the new server containing the client's name, the server name, the current time, the client's IP address and the new session key it just generated. The lifetime of the new ticket is the minimum of the remaining life for the ticket-granting ticket and the default for the service.

    The ticket-granting server then sends the ticket, along with the session key and other information, back to the client. This time, however, the reply is encrypted in the session key that was part of the ticket-granting ticket. This way, there is no need for the user to enter her/his password again. Figure 9 summarizes the authentication protocols.


    Figure 9.
    Kerberos Authentication Protocols.

    5. Kerberos Database

    Up to this point, we have discussed operations requiring read-only access to the Kerberos database. These operations are performed by the authentication service, which can run on both master and slave machines (see Figure 10).


    Figure 10.
    Authentication Requests.

    In this section, we discuss operations that require write access to the database. These operations are performed by the administration service, called the Kerberos Database Management Service (KDBM). The current implementation stipulates that changes may only be made to the master Kerberos database; slave copies are read-only. Therefore, the KDBM server may only run on the master Kerberos machine (see Figure 11).


    Figure 11.
    Administration Requests

    Note that, while authentication can still occur (on slaves), administration requests cannot be serviced if the master machine is down. In our experience, this has not presented a problem, as administration requests are infrequent.

    The KDBM handles requests from users to change their passwords. The client side of this program, which sends requests to the KDBM over the network, is the kpasswd program. The KDBM also accepts requests from Kerberos administrators, who may add principals to the database, as well as change passwords for existing principals. The client side of the administration program, which also sends requests to the KDBM over the network, is the kadmin program.

    5.1. The KDBM Server

    The KDBM server accepts requests to add principals to the database or change the passwords for existing principals. This service is unique in that the ticket-granting service will not issue tickets for it. Instead, the authentication service itself must be used (the same service that is used to get a ticket-granting ticket). The purpose of this is to require the user to enter a password. If this were not so, then if a user left her/his workstation unattended, a passerby could walk up and change her/his password for them, something which should be prevented. Likewise, if an administrator left her/his workstation unguarded, a passerby could change any password in the system.

    When the KDBM server receives a request, it authorizes it by comparing the authenticated principal name of the requester of the change to the principal name of the target of the request. If they are the same, the request is permitted. If they are not the same, the KDBM server consults an access control list (stored in a file on the master Kerberos system). If the requester's principal name is found in this file, the request is permitted, otherwise it is denied.

    By convention, names with a. NULL instance (the default instance) do not appear in the access control list file; instead, an admin instance is used. Therefore, for a user to become an administrator of Kerberos an admin instance for that username must be created, and added to the access control list. This convention allows an administrator to use a different password for Kerberos administration then s/he would use for normal log-in.

    All requests to the KDBM program, whether permitted or denied, are logged.

    5.2. The kadmin and kpasswd Programs

    Administrators of Kerberos use the kadmin program to add principals to the database, or change the passwords of existing principals. An administrator is required to enter the password for their admin instance name when they invoke the kadmin program. This password is used to fetch a ticket for the KDBM server (see Figure 12).


    Figure 12.
    Kerberos Administration Protocol.

    Users may change their Kerberos passwords using the kpasswd program. They are required to enter their old password when they invoke the program. This password is used to fetch a ticket for the KDBM server.

    5.3. Database Replication

    Each Kerberos realm has a master Kerberos machine, which houses the master copy of the authentication database. It is possible (although not necessary) to have additional, read-only copies of the database on slave machines elsewhere in the system. The advantages of having multiple copies of the database are those usually cited for replication: higher availability and better performance. If the master machine is down, authentication can still be achieved on one of the slave machines. The ability to perform authentication on any one of several machines reduces the probability of a bottleneck at the master machine.

    Keeping multiple copies of the database introduces the problem of data consistency. We have found that very simple methods suffice for dealing with inconsistency. The master database is dumped every hour. The database is sent, in its entirety, to the slave machines, which then update their own databases. A program on the master host, called kprop, sends the update to a peer program, called kpropd, running on each of the slave machines (see Figure 13). First kprop sends a checksum of the new database it is about to send. The checksum is encrypted in the Kerberos master database key, which both the master and slave Kerberos machines possess. The data is then transferred over the network to the kpropd on the slave machine. The slave propagation server calculates a checksum of the data it has received, and if it matches the checksum sent by the master, the new information is used to update the slave's database.


    Figure 13.
    Database Propagation

    All passwords in the Kerberos database are encrypted in the master database key Therefore, the information passed from master to slave over the network is not useful to an eavesdropper. However, it is essential that only information from the master host be accepted by the slaves, and that tampering of data be detected, thus the checksum.

    6. Kerberos From the Outside Looking In

    The section will describe Kerberos from the practical point of view, first as seen by the user, then from the application programmer's viewpoint, and finally, through the tasks of the Kerberos administrator.

    6.1. User's Eye View

    If all goes well, the user will hardly notice that Kerberos is present. In our UNIX implementation, the ticket-granting ticket is obtained from Kerberos as part of the log-in process. The changing of a user's Kerberos password is part of the passwd program. And Kerberos tickets are automatically destroyed when a user logs out.

    If the user's log-in session lasts longer than the lifetime of the ticket-granting ticket (currently 8 hours), the user will notice Kerberos' presence because the next time a Kerberos -authenticated application is executed, it will fail. The Kerberos ticket for it will have expired. At that point, the user can run the kinit program to obtain a new ticket for the ticket-granting server. As when logging in, a password must be provided in order to get it. A user executing the klist command out of curiosity may be surprised at all the tickets which have silently been obtained on her/his behalf for services which require Kerberos authentication.

    6.2. From the Programmer's Viewpoint

    A programmer writing a Kerberos application will often be adding authentication to an already existing network application consisting of a client and server side. We call this process "Kerberizing" a program. Kerberizing usually involves making a call to the Kerberos library in order to perform authentication at the initial request for service. It may also involve calls to the DES library to encrypt messages and data which are subsequently sent between application client and application server.

    The most commonly used library functions are krb_mk_req on the client side, and krb_rd_req on the server side. The krb_mk_req routine takes as parameters the name, instance, and realm of the target server, which will be requested, and possibly a checksum of the data to be sent. The client then sends the message returned by the krb_mk_req call over the network to the server side of the application. When the server receives this message, it makes a call to the library routine krb_rd_req. The routine returns a judgement about the authenticity of the sender's alleged identity.

    If the application requires that messages sent between client and server be secret, then library calls can be made to krb_mk_priv (krb_rd_priv) to encrypt (decrypt) messages in the session key which both sides now share.

    6.3. The Kerberos Administrator's Job

    The Kerberos administrator's job begins with running a program to initialize the database. Another program must be run to register essential principals in the database, such as the Kerberos administrator's name with an admin instance. The Kerberos authentication server and the administration server must be started up. If there are slave databases, the administrator must arrange that the programs to propagate database updates from master to slaves be kicked off periodically.

    After these initial steps have been taken, the administrator manipulates the database over the network, using the kadmin program. Through that program, new principals can be added, and passwords can be changed.

    In particular, when a new Kerberos application is added to the system, the Kerberos administrator must take a few steps to get it working. The server must be registered in the database, and assigned a private key (usually this is an automatically generated random key). Then, some data (including the server's key) must be extracted from the database and installed in a file on the server's machine. The default file is /etc/srvtab. The krb_rd_req library routine called by the server (see the previous section) uses the information in that file to decrypt messages sent encrypted in the server's private key. The /etc/srvtab file authenticates the server as a password typed at a terminal authenticates the user.

    The Kerberos administrator must also ensure that Kerberos machines are physically secure, and would also be wise to maintain backups of the Master database.

    7. The Bigger Picture

    In this section, we describe how Kerberos fits into the Athena environment, including its use by other network services and applications, and how it interacts with remote Kerberos realms. For a more complete description of the Athena environment, please see G. W. Treese.

    7.1. Other Network Services' Use of Kerberos

    Several network applications have been modified to use Kerberos. The rlog-in and rsh commands first try to authenticate using Kerberos. A user with valid Kerberos tickets can rlog-in to another Athena machine without having to set up.rhosts files. If the Kerberos authentication fails, the programs fall back on their usual methods of authorization, in this case, the.rhosts files.

    We have modified the Post Office Protocol to use Kerberos for authenticating users who wish to retrieve their electronic mail from the "post office". A message delivery program, called Zephyr, has been recently developed at Athena, and it uses Kerberos for authentication as well.

    The program for signing up new users, called register, uses both the Service Management System (SMS) and Kerberos. From SMS, it determines whether the information entered by the would-be new Athena user, such as name and MIT identification number, is valid. It then checks with Kerberos to see if the requested username is unique. If all goes well, a new entry is made to the Kerberos database, containing the username and password.

    For a detailed discussion of the use of Kerberos to secure Sun's Network File System, please refer to the appendix..

    7.2. Interaction with Other Kerberi

    It is expected that different administrative organizations will want to use Kerberos for user authentication. It is also expected that in many cases, users in one organization will want to use services in another. Kerberos supports multiple administrative domains. The specification of names in Kerberos includes a field called the realm. This field contains the name of the administrative domain within which the user is to be authenticated.

    Services are usually registered in a single realm and will only accept credentials issued by an authentication server for that realm. A user is usually registered in a single realm (the local realm), but it is possible for her/him to obtain credentials issued by another realm (the remote realm), on the strength of the authentication provided by the local realm. Credentials valid in a remote realm indicate the realm in which the user was originally authenticated. Services in the remote realm can choose whether to honor those credentials, depending on the degree of security required and the level of trust in the realm that initially authenticated the user.

    In order to perform cross-realm authentication, it is necessary that the administrators of each pair of realms select a key to be shared between their realms. A user in the local realm can then request a ticket-granting ticket from the local authentication server for the ticket-granting server in the remote realm. When that ticket is used, the remote ticket-granting server recognizes that the request is not from its own realm, and it uses the previously exchanged key to decrypt the ticket-granting ticket. It then issues a ticket as it normally would, except that the realm field for the client contains the name of the realm in which the client was originally authenticated.

    This approach could be extended to allow one to authenticate oneself through a series of realms until reaching the realm with the desired service. In order to do this, though, it would be necessary to record the entire path that was taken, and not just the name of the initial realm in which the user was authenticated. In such a situation, all that is known by the server is that A says that B says that C says that the user is so-and-so. This statement can only be trusted if everyone along the path is also trusted.

    8. Issues and Open Problems

    There are a number of issues and open problems associated with the Kerberos authentication mechanism. Among the issues are how to decide the correct lifetime for a ticket, how to allow proxies, and how to guarantee workstation integrity.

    The ticket lifetime problem is a matter of choosing the proper tradeoff between security and convenience. If the life of a ticket is long, then if a ticket and its associated session key are stolen or misplaced, they can be used for a longer period of time. Such information can be stolen if a user forgets to log out of a public workstation. Alternatively, if a user has been authenticated on a system that allows multiple users, another user with access to root might be able to find the information needed to use stolen tickets. The problem with giving a ticket a short lifetime, however, is that when it expires, the user will have to obtain a new one which requires the user to enter the password again.

    An open problem is the proxy problem. How can an authenticated user allow a server to acquire other network services on her/his behalf? An example where this would be important is the use of a service that will gain access to protected files directly from a fileserver. Another example of this problem is what we call authentication forwarding. If a user is logged into a workstation and logs in to a remote host, it would be nice if the user had access to the same services available locally, while running a program on the remote host. What makes this difficult is that the user might not trust the remote host, thus authentication forwarding is not desirable in all cases. We do not presently have a solution to this problem.

    Another problem, and one that is important in the Athena environment, is how to guarantee the integrity of the software running on a workstation. This is not so much of a problem on private workstations since the user that will be using it has control over it. On public workstations, however, someone might have come along and modified the log-in program to save the user's password. The only solution presently available in our environment is to make it difficult for people to modify software running on the public workstations. A better solution would require that the user's key never leave a system that the user knows can be trusted. One way this could be done would be if the user possessed a smartcard capable of doing the encryptions required in the authentication protocol.

    9. Status

    A prototype version of Kerberos went into production in September of 1986. Since January of 1987, Kerberos has been Project Athena's sole means of authenticating its 5,000 users, 650 workstations, and 65 servers. In addition, Kerberos is now being used in place of.rhosts files for controlling access in several of Athena's timesharing systems.

    10. Acknowledgments

    Kerberos was initially designed by Steve Miller and Clifford Neuman with suggestions from Jeff Schiller and Jerry Saltzer. Since that time, numerous other people have been involved with the project. Among them are Jim Aspnes, Bob Baldwin, John Barba, Richard Basch, Jim Bloom, Bill Bryant, Mark Colan, Rob French, Dan Geer, John Kohl, John Kubiatowicz, Bob Mckie, Brian Murphy, John Ostlund Ken Raeburn, Chris Reed, Jon Rochlis, Mike Shanzer, Bill Sommerfeld, Ted T'so, Win Treese, and Stan Zanarotti.

    We are grateful to Dan Geer, Kathy Lieben, Josh Lubarr, Ken Raeburn, Jerry Saltzer, Ed Steiner, Robbert van Renesse, and Win Treese whose suggestions much improved earlier drafts of this paper.

    The illustration on the title page is by Betsy Bruemmer.

    Appendix

    Kerberos Application to Sun's Network File System (NFS)

    A key component of the Project Athena workstation system is the interposing of the network between the user's workstation and her/his private file storage (home directory). All private storage resides on a set of computers (currently VAX 11/750s) that are dedicated to this purpose. This allows us to offer services on publicly available UNIX workstations. When a user logs in to one of these publicly available workstations, rather then validate her/his name and password against a locally resident password file, we use Kerberos to determine her/his authenticity. The log-in program prompts for a username (as on any UNIX system). This username is used to fetch a Kerberos ticket-granting ticket. The log-in program uses the password to generate a DES key for decrypting the ticket. If decryption is successful, the user's home directory is located by consulting the Hesiod naming service and mounted through NFS. The log-in program then turns control over to the user's shell, which then can run the traditional per-user customization files because the home directory is now "attached" to the workstation. The Hesiod service is also used to construct an entry in the local password file. (This is for the benefit of programs that look up information in /etc/passwd.)

    From several options for delivery of remote file service, we chose Sun's Network File System. However this system fails to mesh with our needs in a crucial way. NFS assumes that all workstations fall into two categories (as viewed from a file server's point of view): trusted and untrusted. Untrusted systems cannot access any files at all, trusted can. Trusted systems are completely trusted. It is assumed that a trusted system is managed by friendly management. Specifically, it is possible from a trusted workstation to masquerade as any valid user of the file service system and thus gain access to just about every file on the system. (Only files owned by "root" are exempted.).

    In our environment, the management of a workstation (in the traditional sense of UNIX system management) is in the hands of the user currently using it. We make no secret of the root password on our workstations, as we realize that a truly unfriendly user can break in by the very fact that s/he is sitting in the same physical location as the machine and has access to all console functions. Therefore we cannot truly trust our workstations in the NFS interpretation of trust. To allow proper access controls in our environment we had to make some modifications to the base NFS software, and integrate Kerberos into the scheme.

    Unmodified NFS

    In the implementation of NFS that we started with (from the University of Wisconsin), authentication was provided in the form of a piece of data included in each NFS request (called a "credential" in NFS terminology). This credential contains information about the unique user identifier (UID) of the requester and a list of the group identifiers (GIDs) of the requester's membership. This information is then used by the NFS server for access checking. The difference between a trusted and a non-trusted workstation is whether or not its credentials are accepted by the NFS server.

    Modified NFS

    In our environment, NFS servers must accept credentials from a workstation if and only if the credentials indicate the UID of the workstation's user, and no other.

    One obvious solution would be to change the nature of credentials from mere indicators of UID and GIDs to full blown Kerberos authenticated data. However a significant performance penalty would be paid if this solution were adopted. Credentials are exchanged on every NFS operation including all disk read and write activities. Including a Kerberos authentication on each disk transaction would add a fair number of full-blown encryptions (done in software) per transaction and, according to our envelope calculations, would have delivered unacceptable performance. (It would also have required placing the Kerberos library routines in the kernel address space.)

    We needed a hybrid approach, described below. The basic idea is to have the NFS server map credentials received from client workstations, to a valid (and possibly different) credential on the server system. This mapping is performed in the server's kernel on each NFS transaction and is setup at "mount" time by a user-level process that engages in Kerberos - moderated authentication prior to establishing a valid kernel credential mapping.

    To implement this we added a new system call to the kernel (required only on server systems, not on client systems) that provides for the control of the mapping function that maps incoming credentials from client workstations to credentials valid for use on the server (if any). The basic mapping function maps the tuple:

    <CLIENT-IP-ADDRESS, UID-ON-CLIENT>

    to a valid NFS credential on the server system. The CLIENT-IP-ADDRESS is extracted from the NFS request packet and the UID-ON-CLIENT is extracted from the credential supplied by the client system. Note: all information in the client-generated credential except the UID-ON-CLIENT is discarded.

    If no mapping exists, the server reacts in one of two ways, depending it is configured. In our friendly configuration we default the unmappable requests into the credentials for the user "nobody" who has no privileged access and has a unique UID. Unfriendly servers return an NFS access error when no valid mapping can be found for an incoming NFS credential.

    Our new system call is used to add and delete entries from the kernel resident map. It also provides the ability to flush all entries that map to a specific UID on the server system, or flush all entries from a given CLIENT-IP-ADDRESS.

    We modified the mount daemon (which handles NFS mount requests on server systems) to accept a new transaction type, the Kerberos authentication mapping request. Basically, as part of the mounting process, the client system provides a Kerberos authenticator along with an indication of her/his UID-ON-CLIENT (encrypted in the Kerberos authenticator) on the workstation. The server's mount daemon converts the Kerberos principal name into a local username. This username is then looked up in a special file to yield the user's UID and GIDs list. For efficiency, this file is a ndbm database file with the username as the key. From this information, an NFS credential is constructed and handed to the kernel as the valid mapping of the <CLIENT-IP-ADDRESS, CLIENT-UID> tuple for this request.

    At unmount time a request is sent to the mount daemon to remove the previously added mapping from the kernel. It is also possible to send a request at log-out time to invalidate all mapping for the current user on the server in question, thus cleaning up any remaining mappings that exist (though they shouldn't) before the workstation is made available for the next user.

    Security Implications of the Modified NFS

    This implementation is not completely secure. For starters, user data is still sent across the network in an unencrypted, and therefore interceptable, form. The low-level, per-transaction authentication is based on a <CLIENT-IP-ADDRESS, CLIENT-UID> pair provided unencrypted in the request packet. This information could be forged and thus security compromised. However, it should be noted that only while a user is actively using her/his files (i.e., while logged in) are valid mappings in place and therefore this form of attack is limited to when the user in question is logged in. When a user is not logged in, no amount of IP address forgery will permit unauthorized access to her/his files.

    References

    1.S. P. Miller, B. C. Neuman, J. I. Schiller, and J. H. Saltzer, Section E.2.1: Kerberos Authentication and Authorization System, M.I.T. Project Athena, Cambridge, Massachusetts (December 21, 1987).

    2.E. Balkovich, S. R. Lerman, and R. P. Parmelee, "Computing in Higher Education: The Athena Experience," Communications of the ACM. 28(11), pp. 1214-1224, ACM (November, 1985).

    3.R. M. Needham and M. D. Schroeder, "Using Encryption for Authentication in Large Networks of Computers," Communications of the ACM 21(12), pp. 993-999 (December, 1978).

    4.V. L. Voydock and S. T. Kent, "Security Mechanisms in High-Level Network Protocols," Computing Surveys 15(2), ACM (June 1983).

    5.National Bureau of Standards, "Data Encryption Standard," Federal Information Processing Standards Publication 46, Government Printing Office, Washington, D.C. (1977).

    6.S. P. Dyer, "Hesiod," in Usenix Conference Proceedings (Winter, 1988).

    7.W. J. Bryant, Kerberos Programmer's Tutorial, M.I.T. Project Athena (In preparation).

    8.W. J. Bryant, Kerberos Administrator's Manual, M.I.T. Project Athena (In preparation).

    9.G. W. Treese, "Berkeley Unix on 1000 Workstations: Athena Changes to 4.3BSD," in Usenix Conference Proceedings (Winter, 1988)

    10.C. A. DellaFera, M. W. Eichin, R. S. French, D. C. Jedlinsky, J. T. Kohl, and W. E. Sommerfeld, "The Zephyr Notification System," in Usenix Conference Proceedings (Winter, 1988).

    11.M. A. Rosenstein, D. E. Geer, and P. J. Levine, in Usenix Conference Proceedings (Winter, 1988).

    12.R. Sandberg, D. Goldberg, S. Kleiman, D. Walsh, and B. Lyon, "Design and Implementation of the Sun Network Filesystem," in Usenix Conference Proceedings (Summer, 1985).

    krb5-1.16/src/windows/leash/htmlhelp/html/Windows_Logon_Tickets.htm0000644000704600001450000000257013211554426025330 0ustar ghudsonlibuuid Windows Logon Tickets

    Windows Logon Session Tickets

    MIT Kerberos is not the only interface for managing Kerberos tickets. When you log on to a Windows domain, you are issued a Kerberos ticket for your Windows Logon session. This ticket is automatically renewed until you log out of the session, when it is destroyed.

    Sometimes applications that require Kerberos authentication only work with MIT Kerberos. Others work only with the interface that is part of the Windows Logon session. For this reason, you can use MIT Kerberos to import tickets from your Windows domain or export tickets into your Windows Logon session for use with Windows services, depending on your needs.

    Learn about... How to...
    krb5-1.16/src/windows/leash/htmlhelp/html/Import_Tickets.htm0000644000704600001450000000477613211554426024024 0ustar ghudsonlibuuid Import_Tickets

    Import Tickets

    You can import Windows domain tickets that you have already obtained through a Windows Logon session. Imported tickets can be fully used by applications that require the MIT Kerberos interface. In most installations, MIT Kerberos will automatically import these tickets if possible.

    On this pageOn other pages
    How to... Learn about...

    Turn Automatic Import on or off

    In most installations, MIT Kerberos will automatically import tickets if possible. Go to the Options tab and click the Automatic Import Tickets checkbox in the Ticket Options panel to turn the feature on or off.
    How to: Use Ticket Options Panel

    In some cases MIT Kerberos tries to automatically import tickets but is prevented from doing so by the Windows User Access Control (UAC) feature. If this happens the tickets are still displayed in the main window, but have the Import Status of protected. You can turn off UAC on your computer to allow the tickets to be imported.

    Back to top

    Use the Import Ticket button

    If the Automatic Import option is turned off, you can still import tickets.

    1. Go to the Home tab.
    2. Click the Import Tickets button.
    3. Click Okay to confirm that you want to import your tickets and destroy any that are already in MIT Kerberos.

    Back to top

    Related help

    krb5-1.16/src/windows/leash/htmlhelp/html/Passwords.htm0000644000704600001450000000443513211554426023041 0ustar ghudsonlibuuid Passwords

    About Passwords

    Kerberos offers strong and reliable security for computers and network systems that use it for authentication, but it is only as secure as the password you choose. A weak password can jeopardize not only your privacy and information, but also any computers or networks that you access with that password.

    On this pageOn other pages
    Learn about... Learn about... How to...

    Choosing Passwords

    Create a strong password that is not a word found in the dictionary or based on easily available information about yourself. Usually the easiest way to do that is to start with a phrase, not a word. For best security choose a unique password that you have not used with any other application. That way if one application is somehow hacked or compromised, the damage is limited to that application.
    About: Password Tips and Examples

    Maintaining Passwords

    If you ever suspect that your password has been compromised, change it immediately. It's a good idea to occasionally change your password even if you think it is still secure. This habit can limit the damage if your password is compromised without your knowledge.

    Related Help

    krb5-1.16/src/windows/leash/htmlhelp/html/hid_sc_size.htm0000644000704600001450000000141213211554426023327 0ustar ghudsonlibuuid (Size command (System menu))

    Size command (System menu)

    Use this command to display a four-headed arrow so you can size the active window with the arrow keys.

    After the pointer changes to the four-headed arrow:

    1.Press one of the direction keys (left, right, up, or down arrow key) to move the pointer to the border you want to move.

    2.Press a direction key to move the border.

    3.Press ENTER when the window is the size you want.

    Note: This command is unavailable if you maximize the window.

    krb5-1.16/src/windows/leash/htmlhelp/html/leash_copyright.htm0000644000704600001450000000427113211554426024236 0ustar ghudsonlibuuid Leash Copyright

    Leash Copyright

    This software is being provided to you, the LICENSEE, by the Massachusetts Institute of Technology (M.I.T) under the following license. By obtaining, using and/or copying this software, you agree that you have read, understood, and will comply with these terms and conditions:

    Permission to use, copy, modify and distribute this software and its documentation for any purpose and without fee or royalty is hereby granted, provided that you agree to comply with the following copyright notice and statements, including the disclaimer, and that the same appear on ALL copies of the software and documentation, including modifications that you make for internal use or for distribution:

    Copyright 1992-2004 by the Massachusetts Institute of Technology. All rights reserved.

    THIS SOFTWARE IS PROVIDED "AS IS", AND M.I.T. MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED. By way of example, but not limitation, M.I.T. MAKES NO REPRESENTATIONS OR WARRANTIES OF MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF THE LICENSED SOFTWARE OR DOCUMENTATION WILL NOT INFRINGE ANY THIRD PARTY PATENTS, COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS.

    The name of the Massachusetts Institute of Technology or M.I.T. may NOT be used in advertising or publicity pertaining to distribution of the software. Title to copyright in this software and any associated documentation shall at all times remain with M.I.T., and USER agrees to preserve same.

    Project Athena, Athena, Athena MUSE, Discuss, Hesiod, Kerberos, Moira, OLC, X Window System, and Zephyr are trademarks of the Massachusetts Institute of Technology (MIT). No commercial use of these trademarks may be made without prior written permission of MIT.

    krb5-1.16/src/windows/leash/htmlhelp/html/Glossary.htm0000644000704600001450000001274413211554426022661 0ustar ghudsonlibuuid Glossary

    Glossary

    default principal
    Your default principal is the one whose tickets are used when an application or service asks for tickets without specifying which principal is being authenticated. If you have only one principal, that principal is always the default.
    About: Default Principals
    domain
    In Windows, realms are called domains.
    About: Kerberos Terminology (Realms)
    encryption key
    A value that a specific code or algorithm uses to make information unreadable to anyone without a matching key.
    encryption type
    The type of encryption used to encode your tickets and session keys. You can show the encryption types used for your tickets and session keys by selecting that option in the View Options panel in the Options tab.
    How to: Use View Options Panel
    expiration alarm
    Optional audible alarm that warns you 15, 10, and 5 minutes before your tickets expire. Turn the alarm on or off in the Ticket Options panel in the Options tab.
    How to: Use the Ticket Options Panel
    flags
    Properties (renewable and/or forwardable) assigned to a ticket when you obtain it. Show or hide flags with the View Options panel in the Options tab.
    How to: Use View Options Panel
    About: Ticket Settings and Flags
    forwardable
    Tickets flagged as forwardable when you obtain them can be forwarded to the remote host when you connect via telnet, ssh, ftp, rlogin, or similar applications, so you will not need to get new tickets to use remote services.
    About: Ticket Settings and Flags
    issued
    The date and time that your tickets were issued. Show or hide this information with the View Options panel in the Options tab.
    How to: Use View Options Panel
    krbtgt
    The Kerberos Ticket Granting Ticket. If you click on a principal in the main window, you will see all of that principal's tickets. The first one will be for krbtgt because with Kerberos you first obtain a Ticket Granting Ticket that is then used to obtain Service Tickets for each service you use.
    About: Kerberos Terminology (Tickets)
    principal
    A unique identity in Kerberos. For users, it is the identity you use to log on with Kerberos. Principals are a combination of your user name and the name of the realm you belong to.
    About: Principals
    realm
    Kerberos realms are a way of logically grouping resources and identities that use Kerberos. Your realm is the home of your Kerberos identity and your point of entry to the network resources controlled by Kerberos. In Windows, realms are called domains.
    About: Kerberos Terminology (Realms)
    renewable until
    The date and time after which your renewable tickets cannot be renewed any more. Show or hide this information with the View Options panel in the Options tab.
    How to: Use View Options Panel
    RSA SecurID
    A method of using two-factor authentication to control user access to network resources. The two authentication factors are something the user knows (a secret PIN) and something the user has (an automatically generated code displayed either on a special device or on a device the user already owns, such as a phone). If your company uses RSA SecurID, you will need to enter your SecurID password after you use your Kerberos password to submit a Get Ticket request.
    How to: Get tickets
    SecurID
    See RSA SecurID
    session key
    A key used to encrypt and decrypt communications between computers. View the encryption type of your session keys by selecting Encryption Type in the View Options panel in the Options tab.
    How to: Use View Options Panel
    About: Encryption Types
    ticket
    Obtain your ticket by entering your user name and password. The ticket is an encrypted block of data that authenticates you to the group of network resources using Kerberos, allowing you to access those resources for the lifetime of the ticket.
    About:Tickets
    valid until
    The date and time your ticket will expire. Show or hide this information with the View Options panel in the Options tab.
    How to: Use View Options Panel
    krb5-1.16/src/windows/leash/htmlhelp/html/afx_hidw_toolbar.htm0000644000704600001450000000127213211554426024363 0ustar ghudsonlibuuid (toolbar)

    Toolbar

    The toolbar is displayed across the top of the application window, below the menu bar. The toolbar provides quick mouse access to many tools used in <<YourApp>>,

    To hide or display the toolbar, click Toolbar from the View menu.

    krb5-1.16/src/windows/leash/htmlhelp/html/leash_topic_error_8.htm0000644000704600001450000000153213211554426025001 0ustar ghudsonlibuuid Kerberos Error 8

    Kerberos Error 8: Unknown username, instance, or realm.

    This error usually occurs when the username is not known for the designated realm. For example, at the time of this writing, there is no user "zzwn" in the Athena realm, so entering zzwn as a username will generate this error.

    Check the entered username or realm name for spelling mistakes or the wrong case.

    krb5-1.16/src/windows/leash/htmlhelp/html/Options_Tab.htm0000644000704600001450000002035213211554426023271 0ustar ghudsonlibuuid Options Tab

    Using the Options Tab

    Home Tab

    Click the Options tab to reach the checkboxes that control ticket and view options. The Options tab has two panels. Use the View Options panel to choose which information is displayed for your tickets. Use the Ticket Options panel to turn MIT Kerberos's automatic features on or off.

    Scroll down to browse information about both panels, or jump to a section by clicking a link below.

    Learn about....How to....

    Using the View Options Panel

    Click the Options tab at the top of the ribbon menu and look to the left to find the View Options panel. View Options control which ticket information columns are displayed in the main window.

    Select a checkbox to show the information column in the main window. Deselect it to hide the column. Some options are selected by default. For example, "Valid Until" is selected by default, so the main window shows the Valid Until column showing when your tickets will expire.
    How to: View Tickets

    View Options

    Checkbox Select to...
    checkbox image Issued            
    See the date and time your ticket was originally obtained.
    checkbox image Renewable Until
    See the date and time that your renewable tickets expire completely and cannot be renewed. After this time you must get new tickets to access services authenticated by Kerberos.

    If this column shows Not Renewable, the ticket was not flagged as renewable when you obtained it.

    Related Help:
    checkbox image Valid Until
    See when your ticket will expire. Note that you cannot renew a ticket if you let it expire.

    Kerberos alerts you to expiring tickets with a warning in a pop up window. To add an audible warning, select the Expiration Alarm checkbox in the Ticket Options panel.
    How to: Use Ticket Options Panel
    checkbox image Encryption Type
    See the encryption type used to encrypt each session key and ticket. This can be useful when troubleshooting.

    Kerberos supports multiple types of encryption. The type used for a particular ticket or session key is automatically negotiated when you request a ticket or a service.
    About: Encryption Types
    checkbox image Flags              
    See how the tickets were flagged (renewable and/or fowardable) when you obtained them.

    You cannot change the flags on existing tickets. If you need a ticket with different flags, you must get a new ticket.
    About: Ticket Settings and Flags

    Back to Top

    Using the Ticket Options Panel

    Click the Options tab at the top of the ribbon menu and look to the right to find the Ticket Options panel. Ticket Options control MIT Kerberos's automatic features.

    Select a Ticket Option checkbox to turn that feature on. Deselect it to turn the feature off.

    Ticket Options

    Checkbox Select to...
    checkbox image Automatic Ticket Renewal
    Automatically renew tickets flagged as renewable, without promptings or requiring a password, until the renewal lifetime is reached.

    Renewing your tickets allows you to run batch jobs without interruption and to work through a long session without continually reentering your password.
    About: Renewable Tickets

    Note: Automatic ticket renewal will not work if you exit MIT Kerberos or if your machine is in hibernation mode.
    checkbox image Expiration Alarm
    Have MIT Kerberos provide an audible alarm 15, 10, and 5 minutes before your tickets expire.

    Regardless of whether this option is on, MIT Kerberos alerts you to expiring tickets at the same intervals with pop up window. However, the pop up window will not always be visible on a busy desktop.
    About: Ticket Expiration
    checkbox image Destroy Tickets on Exit
    Have MIT Kerberos destroy your tickets when you exit the program.

    Turning this option on provides greater security. However, you will need to turn this off if you want to exit MIT Kerberos while leaving processes running which require your valid tickets.
    checkbox image Allow Mixed Case Realm Name
    Use a Kerberos realm with lower case letters in its name.

    Kerberos realms are a way of logically grouping resources and identities that use Kerberos. By convention, realm names use all upper case letters. This helps distinguish a realm from the DNS domain it corresponds to. Realm names are case sensitive. So for convenience, anything you enter in the realm field of the Get Ticket window is converted to upper case, unless you turn this option on.

    Back to Top

    krb5-1.16/src/windows/leash/htmlhelp/html/Change_Password.htm0000644000704600001450000000337413211554426024124 0ustar ghudsonlibuuid Change Password

    Change Password

    To change your password:

    1. Create or choose a strong new password. It's best to start with a phrase instead of a word.
      About: Password Tips and Examples
    2. If you have multiple principals, you can select the principal you want to manage by clicking it in the main window. Or you can wait and enter your principal in the Change Password window.
    3. Click the Change Password button in the ribbon menu at the of the main window.
    4. Verify your principal (your Kerberos identity) or enter a different one.
    5. Enter your current password.
    6. Enter your new password twice. You must enter it the second time to make sure you have typed it correctly, since you cannot visually confirm what you have typed.
    7. Click Okay.

    Related Help

    krb5-1.16/src/windows/leash/htmlhelp/html/leash_topic_leash_window.htm0000644000704600001450000000707213211554426026111 0ustar ghudsonlibuuid Leash Screen Display (Kerberometer and Dash Notification)

    Leash Screen Display (Kerberometer and Dash Notification)

    The window title contains the name Leash followed by the current date and time.  Below the title are a menu bar; a tool bar (optional); a tree view; and a status bar (optional).

    Leash Display Window

    The root of the Leash tree view shows the active user principal name (user@REALM).  This entry appears with a "+" icon and a Kerberos icon to its left.  Click on this plus icon of a line to expand the branch, displaying a "-" icon.  To retract the branch click on the minus sign.

    Below user principal, the tree contains ticket categories.  Below each ticket category are the current tickets belonging to the group.  Each ticket entry contains the current ticket status, the time it was issued, the time it will expire, and the service principal and flags.  For Kerberos 5 tickets, encryption types and network address information are listed below each ticket.

    The tree updates once per minute.  If you need an immediate update of your ticket status, you can either click in the window or the press the Update Display button on the toolbar.

    On the right of the status bar is a display of the remaining time of your tickets (both Kerberos 4 and Kerberos 5, as some programs obtain only Kerberos 4 tickets, these are not necessarily the same) in hours, minutes, and seconds.  This used to be known as the Kerberometer. 

    Each ticket is described and represented by an icon of a little ticket. The color of the ticket changes based on its viability:

    green = normal

    yellow = tickets are within 15 minutes of expiration

    red = tickets have expired, or you have no tickets

    gray = these tickets are not available to you

    At 15, 10, and 5 minutes before your Kerberos tickets expire, a screen pops up to warn that your Kerberos tickets will expire soon and to give you the opportunity to renew them.  This used to be known as Dash-style notification.

    Andrew File System (AFS) tokens information is displayed only on machines that have either OpenAFS for Windows http://www.openafs.org or Transarc AFS 3.6 for Windows.

    krb5-1.16/src/windows/leash/htmlhelp/html/leash_command_sync_time.htm0000644000704600001450000000210213211554426025705 0ustar ghudsonlibuuid Synchronize Time Option

    Synchronize Time

    This command is found on the Action menu; it is also the sixth button (from the left) in the toolbar.  When you select this command, Leash synchronizes the local machine time with the time server specified in the Leash Properties dialog.

    Note: Kerberos authentication protocol requires loosely synchronized time between computers.  The local machine clock and the Kerberos server clock need to be within five minutes of each other for Kerberos to function properly.  This function can also be performed with the clock icon on the toolbar and has no keyboard equivalent.

    krb5-1.16/src/windows/leash/htmlhelp/html/Destroy_Tickets.htm0000644000704600001450000000416013211554426024166 0ustar ghudsonlibuuid <a>Destroy Tickets</a>

    Destroy Tickets

    Destroy your tickets when you no longer need them to increase security. Once the tickets are destroyed they can no longer be used by anyone.

    How to...

    Destroy tickets immediately

    To immediately destroy all of your MIT Kerberos tickets:

    1. Click the Destroy Ticket button in the Home tab or use the keyboard shortcut [Ctrl + d].
    2. Click Okay to confirm that you want to destroy the tickets.

    Back to Top

    Destroy tickets automatically on exit

    To automatically destroy your tickets when you exit MIT Kerberos:

    1. Open the Options tab.
    2. Find the Ticket Options panel.
    3. If the Destroy Tickets on Exit checkbox is not already selected, click to select it.

    Your tickets are not affected immediately, but they will be automatically destroyed as soon as you exit MIT Kerberos.

    Back to Top

    Related help

    krb5-1.16/src/windows/leash/htmlhelp/html/leash_topic_password_choice.htm0000644000704600001450000001147313211554426026602 0ustar ghudsonlibuuid How to Choose a Password

    How To Choose a Password...

    Your passwords are the keys to many computers, from a bank machine to a multiuser mainframe to a server on a network. Your password helps to prove that you are who you say you are, and ensures your privacy.

    Compromised passwords are the means by which most unauthorized (and unscrupulous) people gain access to a system. Someone logging on under your name has access not only to your computer files, but to most of the facilities of the computer system. Since tampering can have far-reaching and serious consequences, it's important to take to heart the following guidelines for choosing a password.

    Do choose:

    *Something easy for you to remember with at least six characters.

    *Something obscure. For instance, you might deliberately misspell a term or use an odd character in an otherwise familiar term, such as "phnybon" instead of "funnybone." Or use a combination of two unrelated words or a combination of letters and numbers.

    *A combination of letters and numbers, or a phrase like "many colors" and then use only the consonants "mnYc0l0rz."

    *An acronym for your favorite saying, for example, "L!isn!" (Live! It's Saturday Night!)

    Don't choose:

    *Your name in any form - first, middle, last, maiden, spelled backwards, nickname or initials.

    *Your userid, or your userid spelled backwards.

    *Part of your userid or name.

    *Any common name, such as Joe.

    *The name of a close relative, friend, or pet.

    *Your phone or office number, address, birthday, or anniversary.

    *Your license-plate number, your social-security number, or any all numeral password.

    *Names from popular culture, e.g., spock, sleepy.

    *Any word in a dictionary.

    *Passwords of fewer than four characters.

    Mum's the Word

    Never tell anyone your password -- not even your system administrator or account manager -- and don't write it down. Make sure you have chosen a password that you can remember. And, finally, change your password at regular intervals

    Reprinted from i/s, Vol. 4, No. 9,

    May 1989. Revised March 1993.

    Copyright C 1993 MIT Information Systems

    Send comments or questions about this publication to

    <comment-ispubs@mit.edu> or call x3-5150

    Before You Begin...

    Remember that passwords are case-sensitive, and note whether your keyboard has Caps Lock on. Leash is not programmed to inform you about the state of your Caps Lock key.

    How To Use Change Password...

    1.In Leash, click on the Change Password button (the one that says abc and has a green arrow), type your username in the first field of the dialogue box that opens, and press Enter or click OK. You may start over anytime by clicking Restart, stop at any time by clicking Cancel, or get help at any time with the Help button.

    2.Type your current password in the second field and press Enter or click OK.

    The program checks the username and password you entered and notifies you if either is invalid.

    3.Type your new password in the third field and press Enter or click OK.

    4.Retype your new password, to verify it, and press Enter or click OK.

    Once you have entered the new password twice with consistent spellings, the Leash program replaces your old password with the new, if it is a strong password. If Kerberos determines the password is weak, a message notifies you, and you need to repeat steps 1 through 4 with a strong password, as described by the "How To Choose a Password" guidelines above.

    How Change Password Works...

    When you type into the password fields of the dialog box, neither characters nor sounds echo back, thus keeping secret even the number of password characters. The program accepts only printable characters for new passwords, i.e., characters between ASCII codes 0x20 and 0x7E.

    When you have entered the new password twice consistently, the program attempts to change the password via a dialogue with the Kerberos administrative server. Some Kerberos sites, including MIT's Athena environment, check the password's strength before allowing the change to take place and notifies you if it determines that the password is weak.

    krb5-1.16/src/windows/leash/htmlhelp/html/leash_bug_reports.htm0000644000704600001450000000215013211554426024553 0ustar ghudsonlibuuid Reporting Bugs and Requesting Assistance

    Reporting Bugs and Requesting Assistance

    If you find bugs, please mail them to kfw-bugs@MIT.EDU.

    kerberos@MIT.EDU is a mailing list set up for discussing Kerberos issues. It is gatewayed to the Usenet newsgroup 'comp.protocols.kerberos'. If you prefer to read it via mail, send a request to kerberos-request@MIT.EDU to get added or subscribe via the web page: 

    http://mailman.mit.edu/mailman/listinfo/kerberos

     

    krb5-1.16/src/windows/leash/htmlhelp/html/leash_external_kdestroy.htm0000644000704600001450000000113113211554426025764 0ustar ghudsonlibuuid kdestroy.exe

    kdestroy.exe program

    This is another way to destroy your tickets. Running this application will immediately destroy all tickets and tokens you might have, no matter how they were obtained.

    krb5-1.16/src/windows/leash/htmlhelp/html/leash_option_upper_case_realm.htm0000644000704600001450000000134213211554426027120 0ustar ghudsonlibuuid Upper Case Realm Name Option

    Upper Case Realm Name Option

    The default for this (accessible from the Options menu) is on; when this option is selected, the Kerberos realm name that you type (such as ATHENA.MIT.EDU) is converted to upper case regardless of how you type it.

    krb5-1.16/src/windows/leash/htmlhelp/html/Renew_Tickets.htm0000644000704600001450000001022213211554426023611 0ustar ghudsonlibuuid Renew_Tickets

    Renew Tickets

    Renew a ticket to extend its usable lifetime. Each time a ticket is renewed, its lifespan is reset to the original length of the ticket. It can then be used until the new time listed in the "Valid Until" column in the main window.

    Learn about...How to...

    Renew ticket once

    1. If you have more than one principal, click to select all principals with tickets you want to renew.
    2. Click the Renew Ticket button in the Home tab or use the keyboard shortcut [Ctrl + r].

    The ticket lifetime is reset for all of the selected principal's renewable tickets.

    Back to Top

    Renew tickets automatically

    1. Open the Options tab in the main window.
    2. In the Ticket Options panel, select the Automatic Ticket Renewal checkbox if it is not already checked.

    Your renewable tickets will automatically reset their lifetimes before they expire, until the renewable lifetime of the tickets is reached.

    Note: This feature only works while MIT Kerberos is active and running. This means that if your machine is in hibernation mode or if Kerberos is not running when it is time to renew your tickets, your tickets will not be renewed and will expire instead.

    Back to Top

    What's necessary to renew tickets

    You can renew a ticket if the following conditions are met:

    • When you obtained the ticket, the Renewable flag was selected.
      About: Ticket Settings and Flags
    • The "Renewable Until" deadline has not been reached. Show or hide the Renewable Until column with the View Options panel in the Options tab.
      How to: Use View Options Panel
    • The ticket has not already expired.
    • MIT Kerberos is running and your computer is not in hibernation mode.

    Back to Top

    Find how long a ticket can be renewed

    1. Open the Options tab in the main window.
    2. In the View Options panel, select the Renewable Until checkbox.

    The Renewable Until column will appear. You can renew your ticket repeatedly until the date and time in this column is reached.

    Back to Top

    Related help

    Back to Top

    krb5-1.16/src/windows/leash/htmlhelp/html/Password_Tips.htm0000644000704600001450000000524513211554426023655 0ustar ghudsonlibuuid Password Tips

    Password Tips and Examples

    As computing power has gotten faster and cheaper, password cracking generators have gotten better as well. A password cracking program can rapidly try all English words, all combinations of seven or fewer characters, and common passwords such as 12345678 and password123. In addition, anyone with access to your personal information can try names and dates from that information.

    Good Password Requirements

    A strong password:

    • Is at least 8 characters long (preferably longer)
    • Doesn't include your name or other easily obtained personal information
    • Uses a mix of lower case letters, uppercase letters, numbers, and symbols
    • Is only used for one program

    Password Advice and Examples

    To create a strong password that is still easy to remember, try starting with a phrase or sentence. Then play around with symbols, shorthands, and misspellings to make it more secure. Remember that you can have spaces in your password. Some examples:

    • "Beans and rice are my favorite foods" can become Beans&ricearemyFavoriteFoods!, Rbeans&ricemyfavoritefoods? or BeansNRiceRFavz!
    • "I can't wait 2 go to Spain" can become Ican'twait2go2Spain!
    • "Meet me at the store" can become mEEtme@zeStore
    • "Cat or dog?" can become ?KatsRd0gs or you can leave it as is.

    What Makes a Bad Password

    Do not base your password on any of the following. They are far too easy to guess (even if you spell them backwards).

    • Any names, including yours or that of your parents, children, pets, friends, characters from popular media, etc.
    • Your phone number, address, birthday, etc.
    • Your social security, drivers license, or license plate numbers.
    • One or two words found in a dictionary.
    • The phrases "Let me in," "open up," or something similar.
    • Simple patterns like "lolololololo" or "12345678."
    • Any password used as an example in a manual or in help (including the examples given here).
    • A password that you use elsewhere, especially an insecure program or website.

    Related Help

    krb5-1.16/src/windows/leash/htmlhelp/html/Kerberos.htm0000644000704600001450000000711013211554426022621 0ustar ghudsonlibuuid What is Kerberos?

    Kerberos

    What is Kerberos?

    Kerberos is a network authentication protocol that allows users to securely access services over a physically insecure network. Kerberos, or MIT Kerberos, is also the name of this application. MIT Kerberos provides an easy interface to the Kerberos protocol.

    In addition to providing secure access to services, Kerberos adds convenience by allowing you to sign on just once to use many network resources such as servers, hosts, or other services.

    Kerberos gives you this convenience and security through the use of single sign on, mutual authentication, and secret key encryption.

    Single Sign On
    Your Kerberos identity (your principal) and your password allow you to log on just once to access all of the servers, hosts, and other resources that use the Kerberos installation. No matter how many resources you use, you will not need to enter your password again.
    Mutual Authentication
    Authentication is proof of identity. Any protocol or service that demands a password is authenticating the user. However, Kerberos provides mutual authentication, so in addition to proving your identity to the server, it proves that the server you are communicating with is what it claims to be. This protects you against phishing and spoofing.
    Secret-Key Encryption
    Kerberos prevents malicious attempts to intercept your password by encrypting your password before transmitting it. In addition, once you and the server have proved your identities to each other, Kerberos uses secret-key cryptography to secure the rest of your communications. This helps maintain your privacy and the integrity of your data.

    Related Help

    krb5-1.16/src/windows/leash/htmlhelp/html/leash_command_destroy_tickets.htm0000644000704600001450000000210313211554426027133 0ustar ghudsonlibuuid Destroy Tickets Command

    Destroy Ticket(s)/Token(s) Command, Ctrl+D

    This command is found on the Action menu; it is also the fourth button (from the left) in the toolbar.  Use this command to destroy all of the Kerberos tickets (and perhaps AFS tokens) on your local machine.  Leash confirms your intentions before completing the request.  Tickets for individual services may not be destroyed by the Leash Application.

    Once tickets are destroyed, you must Get or Import new tickets before Kerberized applications can once again access network services.

    krb5-1.16/src/windows/leash/htmlhelp/html/leash_option_krb5_properties.htm0000644000704600001450000001335113211554426026734 0ustar ghudsonlibuuid Kerberos Five Properties Command

    Kerberos v5 Properties Command, Ctrl+5

    The Kerberos v5 Properties dialog is accessible from the Options menu. This dialog has two tabs: File Location and Configuration Options.

    File Location:

    Kerberos Five Properties: File Location

    The File Location tab allows you to specify the location of the default Kerberos 5 ticket cache and configuration file.  The Ticket File field specifies the name of the in-memory cache (Ticket File) used to store the Kerberos 5 tickets.  The format of the name is API: followed by the cache name or "MSLSA:".  Disk caches (type "FILE:") are not supported by Kerberos for Windows.  The Configuration File field specifies the path to the Kerberos 5 configuration file, krb5.ini.  If Confirm that new configuration file exists is checked when the configuration file location is changed, then Leash will not accept values which are not pre-existing Kerberos 5 configuration files.


    Configuration Options:

    Kerberos Five Properties: Configuration Options

    On the Configuration Options page, you provide default attribute values to be used when requesting Kerberos 5 tickets from the Kerberos server. 

    When Forwardable tickets are received from the Kerberos Server, these tickets can be forwarded to a remote host when you connect via telnet, ssh, ftp, rlogin, or similar applications.  When tickets are forwarded, there is no need to obtain Kerberos tickets again to access Kerberized services on the remote host.

    When Proxiable tickets are received from the Kerberos Server, these tickets can be passed onto Kerberized services which can in turn act on your behalf.  

    When Renewable tickets are received from the Kerberos Server, the ticket lifetimes may be renewed without prompting the user for her password.  This allows Kerberos tickets to be issued with short lifetimes allowing compromised accounts to be disabled on short notice without requiring the user to enter a password every few hours.  When combined with Automatic Ticket Renewal (Option menu), Leash can maintain valid tickets for a week, a month, or longer by automatically renewing tickets prior to their expiration.  The ability to renew tickets without a password is limited by the tickets renewable lifetime as issued by the Kerberos Server.

    Traditionally, Kerberos tickets have included a list of network addresses within the tickets.  This address list restricts the use of the tickets to the computers which are assigned those addresses.  The use of address lists has become a headache for many users of Kerberos on network connections which use either Network Address Translation (Cable/DSL routers) or Network Address Hiding (VPN) capabilities.  On these networks the address of the client machine appears to be different to the network service than it does to the client.  The result is the Kerberos ticket is deemed to be invalid by the service even though it has not been stolen.  When No Addresses is checked, Kerberos will not insert an address list into the Kerberos tickets.  For Kerberized services which do not require address lists, this will enable Kerberos to be used across NAT and VPN based connections.  

    Note 1:  As of Kerberos 5 release 1.3, the library default is to disable the use of address lists.  Leash will detect the setting from the Kerberos 5 configuration and check the No Addresses box.  If you attempt to re-enable address lists while the library is configured to disable them , Leash will warn you that the Kerberos 5 configuration file must be altered.   

    Note 2: Distributed Computing Environment (DCE) servers require the use of address lists.


    krb5-1.16/src/windows/leash/htmlhelp/html/hid_help_using.htm0000644000704600001450000000055213211554426024031 0ustar ghudsonlibuuid (Using Help command (Help menu))

    Using Help command (Help menu)

    Use this command for instructions about using help.

    krb5-1.16/src/windows/leash/htmlhelp/html/hid_sc_close.htm0000644000704600001450000000130213211554426023460 0ustar ghudsonlibuuid(Close command (Control menus))

    Close command (Control menus)

    Use this command to close the active window or dialog box.

    Double-clicking a Control menu box is the same as choosing the Close command.

    Note: If you have multiple windows open for a single document, the Close command on the document Control menu closes only one window at a time. You can close all windows at once with the Close command on the File menu.

    krb5-1.16/src/windows/leash/htmlhelp/html/Manage_Multiple_Principals.htm0000644000704600001450000000673713211554426026312 0ustar ghudsonlibuuid Multiple Principals

    Manage Multiple Principals

    If you have multiple principals, several features in MIT Kerberos will help you manage them.

    • You can save principals when you enter them in the Get Ticket window. Kerberos will then auto-complete your principal as you start to enter it to get tickets or to change your password.
    • The Make Default button lets you easily and quickly change the default principal.

    All of your principals with tickets are listed in the main window. The default principal is in bold font.

    On this page On other pages
    How to.... How to...

    Manage Multiple Principals

    Enter and save principals When you get tickets for a principal for the first time, enter the principal in the Principal field of the Get Ticket window. Select the "Remember this principal" checkbox to save it. The next time you get tickets or change your password, Kerberos will auto-complete your principal as you enter it.
    Select principal before using buttons Select a principal in the main window by clicking it. The selected principal will now be affected by the buttons in the Home tab (e.g., Change Password). Note that you can select multiple principals before you click the Renew Tickets button.
    Renew tickets If the Automatic Ticket Renewal option is selected, all renewable tickets for all principals are renewed automatically. To renew tickets just for some principals, click the principal(s) with tickets you want to renew in the main window, then click the Renew Ticket button.
    Choose default principal To choose which principal's tickets are used by default when you access a Kerberized service, select a principal in the main window by clicking it and then click the Make Default button.
    How to: Make Default Principal
    Clear saved principals If you have saved a principal that you will no longer use, and you do not want that principal to auto-complete in the Get Ticket and Change Password windows, you can clear your principal history by clicking the Clear History button in the Get Ticket window. Note that MIT Kerberos will immediately clear all of your saved principals.
    How to: Clear Principal History
    krb5-1.16/src/windows/leash/htmlhelp/html/hid_view_status_bar.htm0000644000704600001450000000144013211554426025072 0ustar ghudsonlibuuid (View Status Bar Command)

    Status Bar command (View menu)

    Use this command to display and hide the status bar, which describes the action to be executed by the selected menu item or pressed toolbar button, and keyboard latch state. A checkmark appears next to the menu item when the status bar is displayed.

    See Status Bar for help on using the status bar.

    krb5-1.16/src/windows/leash/htmlhelp/html/leash_acknowledgements.htm0000644000704600001450000000573513211554426025566 0ustar ghudsonlibuuid The MIT Kerberos Team

    The MIT Kerberos Team

    This is by no means a complete list, as we have contributors and collaborators from all over the net.

    MIT Team Members
    The following people are not officially affiliated with MIT, but contribute to the MIT Kerberos V5 effort:
    krb5-1.16/src/windows/leash/htmlhelp/html/Keyboard_Shortcuts.htm0000644000704600001450000000220213211554426024660 0ustar ghudsonlibuuid Keyboard Shortcuts

    Keyboard Shortcuts

    You can use keyboard shortcuts to reach several of the more frequently used functions in MIT Kerberos. To use a shortcut, hold down the [Ctrl] key on your computer's keyboard while pressing the appropriate letter key as shown in the table below.

    Function Keyboard Shortcut
    Get Ticket Ctrl + t
    Renew Ticket Ctrl + r
    Destroy Ticket Ctrl + d

    Related help

    krb5-1.16/src/windows/leash/htmlhelp/html/KLIST.htm0000644000704600001450000001223413211554426021736 0ustar ghudsonlibuuid KLIST

    KLIST Command

    The following information reproduces the information from UNIX man page for the KLIST command.

    SYNOPSIS

    klist [-e] [[-c] [-l] [-A] [-f] [-s] [-a [-n]]] [-k [-t] [-K]] [cache_name | keytab_name]

    DESCRIPTION

    klist lists the Kerberos principal and Kerberos tickets held in a credentials cache, or the keys held in a keytab file.

    OPTIONS

    -e Displays the encryption types of the session key and the ticket for each credential in the credential cache, or each key in the keytab file.
    -c List tickets held in a credentials cache. This is the default if neither -c nor -k is specified.
    -l If a cache collection is available, displays a table summarizing the caches present in the collection.
    -A     If a cache collection is available, displays the contents of all of the caches in the collection.
    -f Shows the flags present in the credentials, using the following abbreviations:
    FForwardable
    fforwarded
    PProxiable
    pproxy
    DpostDateable
    d postdated
    RRenewable
    IInitial
    iinvalid
    HHardware authenticated
    A preAuthenticated
    TTransit policy checked
    OOkay as delegate
    aanonymous
    -s Causes klist to run silently (produce no output), but to still set the exit status according to whether it finds the credentials cache. The exit status is `0' if klist finds a credentials cache, and `1' if it does not or if the tickets are expired.
    -a Display list of addresses in credentials.
    -n Show numeric addresses instead of reverse-resolving addresses.
    -k List keys held in a keytab file.

    ENVIRONMENT

    Klist uses the following environment variables:

    KRB5CCNAME Location of the default Kerberos 5 credentials (ticket) cache, in the form type:residual. If no type prefix is present, the FILE type is assumed. The type of the default cache may determine the availability of a cache collection; for instance, a default cache of type DIR causes caches within the directory to be present in the collection.

    FILES

    /tmp/krb5cc_[uid] default location of Kerberos 5 credentials cache ([uid] is the decimal UID of the user).
    /etc/krb5.keytab default location for the local host's keytab file.

    SEE ALSO

    • kinit(1)
    • kdestroy(1)
    • krb5(3)
    • 
                                                                            KLIST(1)
      
      
      krb5-1.16/src/windows/leash/htmlhelp/html/leash_external_aklog.htm0000644000704600001450000000114113211554426025216 0ustar ghudsonlibuuid aklog.exe

      aklog.exe program

      aklog is a program which may be used to obtain AFS tokens for a cell which may or may not be equivalent to the Kerberos realm whose tickets are used to obtain the tokens.

      krb5-1.16/src/windows/leash/htmlhelp/html/How_Use_Kerberos.htm0000644000704600001450000000553413211554426024262 0ustar ghudsonlibuuid How_Use_Kerberos

      How Do I Use Kerberos?

      It is simple to use Kerberos through the MIT Kerberos program. Click the Get Ticket button and log on to get a Kerberos ticket. This ticket is proof of your identity and allows you to access all of the network resources you are pemitted to use. For the most part, your tickets are passed on through the network without needing anything more from you.

      Kerberos tickets do expire, usually after about the length of a working day.

      Related Help

      It is helpful to understand three concepts before using Kerberos; realms, principals, and tickets.

      Realm

      A Kerberos realm is the group of network resources that that you gain access to when you log on with a Kerberos identity and password. For example, a university might have a Kerberos realm that includes all of the servers that students should be allowed to access. Some companies or universities might maintain more than one realm, potentially overlapping them. If you have access to more than one realm, you must log on to each one separately. By definition, each network resource in a Kerberos realm uses the same Kerberos installation for authentication.

      Principal

      A Kerberos principal is the identity you use to log on through Kerberos. Some people will have more than one principal. For example, an administrator might have a regular principal and a seperate one with admin rights, like root access.

      Tickets

      krb5-1.16/src/windows/leash/htmlhelp/html/Debugging.htm0000644000704600001450000000124213211554426022740 0ustar ghudsonlibuuidDebugging

      Debugging

      MIT Kerberos is an interface to the Kerberos protocol. It issues commands to the Kerberos server on your behalf in response to buttons you click and options you select.

      If you are having a problem with MIT Kerberos not working as you expect, or you if you are writing an application that depends on Kerberos tickets, you might want to see exactly what commands are being issued on your behalf krb5-1.16/src/windows/leash/htmlhelp/html/Troubleshooting.htm0000644000704600001450000000742213211554426024242 0ustar ghudsonlibuuid Troubleshooting

      Troubleshooting

      When I try to renew my ticket, why do I get an error message and see the Get Ticket window?

      The ticket cannot be renewed. This could be because the ticket was not flagged as renewable when you obtained it, or because it expired before you could renew it, or because the ticket's renewable lifetime has been reached. About: Renewable Tickets

      Back to top

      Why did my tickets expire even though I had Automatically Renew Tickets turned on?

      MIT Kerberos can only renew your tickets if the program is running and active. It cannot renew your tickets if you exit the program or if your computer is turned off or in hibernation mode.

      Back to top

      Why doesn't my ticket lifetime match the lifetime I selected with the slider in the Get Ticket window?

      Your Kerberos installation is configured for a maximum ticket lifetime length that is determined by the administrators. If your installation uses a shorter maximum ticket lifetime than the default, the Ticket Lifetime slider might show the default maximum instead of the actual maximum.

      For example, if your Kerberos installation has been configured to issue tickets that expire in 5 hours or less, you might be able to move the slider to show 12 hours but you would still be issued a ticket with a lifetime of only 5 hours.

      Back to top

      How do I set properties like the default ticket lifetime?

      You cannot use the MIT Kerberos program to set properties such as default ticket lifetimes. Instead, edit the appropriate configuration file. For more information, visit the MIT Kerberos documentation site.

      Back to top

      I have multiple principals and have tickets for all of them, but sometimes an application that requires Kerberos doesn't work. What's going on?

      When you try to use a Keberized application, it requests your credentials from Kerberos. Some applications do this by asking for a specific principal's credentials, but others ask generically. When applications make a generic request, Kerberos does not know which principal is being authenticated and checks the default principal for tickets. If the default principal is not the one being authenticated, the application will usually simply fail to work with no warning or notice. How to: Make Default Principal

      Back to top

      krb5-1.16/src/windows/leash/htmlhelp/html/KVNO.htm0000644000704600001450000000716013211554426021627 0ustar ghudsonlibuuidKVNO

      KVNO Command

      Tickets
      To keep passwords from being transmitted in the clear and to provide users the convenience of a single log-on to access multiple services and hosts, Kerberos uses the concept of tickets. Once a user provides a valid identity and password, Kerberos issues the user a ticket with a limited lifetime. In most cases the ticket then allows the user to access all of the servers and hosts he or she should be able to access, for the lifetime of the ticket. When you get tickets through Leash, Kerberos verfies that you are who you say you are by checking your user name and password and then gives you an initial ticket. When you access a service in your Kerberos realm, Leash passes your initial Kerberos ticket to the service. The service verifies the ticket and then issues you a service ticket that allows you access to that service. You don't have to worry about obtaining these new service tickets; they are automatically given to you. You can view service tickets with Leash but cannot directly obtain or destroy them.
      The following information reproduces the information from UNIX man page for the KVNO command.

      SYNOPSIS

      kvno [-c ccache] [-e etype] [-q] [-h] [-P] [-S sname] [-U for_user] service1 service2 ..

      DESCRIPTION

      kvno acquires a service ticket for the specified Kerberos principals and prints out the key version numbers of each.

      OPTIONS

      -c ccache Specifies the name of a credentials cache to use (if not the default).
      -e etype Specifies the enctype which will be requested for the session key of all the services named on the command line. This is useful in certain backward compatibility situations.
      -q Suppress printing output when successful. If a service ticket cannot be obtained, an error message will still be printed and kvno will exit with nonzero status.
      -h Prints a usage statement and exits.
      -P Specifies that the service1 service2 ... arguments are to be treated as services for which credentials should be acquired using constrained delegation. This option is only valid when used in conjunction with protocol transition.
      -S sname Specifies that the service1 service2 ... arguments are interpreted as hostnames, and the service principals are to be constructed from those hostnames and the service name sname. The service hostnames will be canonicalized according to the usual rules for constructing service principals.
      -U for_user Specifies that protocol transition (S4U2Self) is to be used to acquire a ticket on behalf of for_user. If constrained delegation is not requested, the service name must match the credentials cache client principal.

      ENVIRONMENT

      Kvno uses the following environment variables:

      KRB5CCNAME Location of the credentials (ticket) cache.

      FILES

      /tmp/krb5cc_[uid] default location of Kerberos 5 credentials cache ([uid] is the decimal UID of the user).

      SEE ALSO

      krb5-1.16/src/windows/leash/htmlhelp/html/Ticket_Settings.htm0000644000704600001450000001364513211554426024162 0ustar ghudsonlibuuid Ticket Settings

      Ticket Settings and Flags

      When you obtain a new ticket you have a chance to view and change the ticket's settings and flags in the Get Ticket window. You cannot change settings or flags on an existing ticket.

      Learn about... How to...

      Choose Settings and Flags

      To adjust settings for a new ticket:

      1. Click the Get Ticket button.
      2. In the Get Ticket window, click the Show Advanced button if the settings are not already visible.
      3. Make adjustments as necessary. Options that you may not change are visible but appear in gray.
      4. Click Okay to finish getting your ticket.

      Back to Top

      View Settings and Flags

      You can view settings and flags for existing tickets in the main window. If the information you want is not visible, go to the Options tab and use the checkboxes in the View Options panel to open the relevant column.
      How to: View Tickets

      Setting or Flag Relevant Column
      Ticket lifetime Valid Until
      Renewable lifetime Renewable Until
      "Renewable" and "Forwardable and Proxiable" flags Flags

      Back to Top

      Ticket Lifetime

      When to change: You want to adjust the length of time your ticket will be valid before it expires.
      How to change: When you get your ticket, click the Show Advanced button in the Get Ticket window. The Ticket Lifetime slider is below the Password field. Move the slider left to shorten the lifetime; move the slider right to lengthen the lifetime.
      More info Your Kerberos ticket will expire at the end of the lifetime specified with this slider control. Longer lifetimes are more convenient but less secure. To get a longer usable ticket lifetime without losing security, flag the ticket as renewable and then in the main window select the Automatic Ticket Renewal option.
      About: Renewable Tickets

      Back to top

      Flag as Forwardable and Proxiable

      When to use this flag: You will use Kerberized services on a remote host.
      How to change: When you get your ticket, click the Show Advanced button in the Get Ticket window. The "Flag this ticket as" section is below the Ticket Lifetime slider. If the "forwardable and proxiable" checkbox is selected, the ticket will be forwardable. Click the checkbox to select or deselect it.
      More info You can forward tickets flagged as forwardable to the remote host when you connect via telnet, ssh, ftp, rlogin, or similar applications, and you will not need to get new tickets to use remote services. Often your tickets will be forwarded automatically as needed. Ask your help desk or administrator for information specific to your installation.

      Back to top

      Flag as Renewable

      When to use this flag: You want a long interactive session without having to keep entering your password, or you plan to run a long batch job.
      How to change: When you get your ticket, click the Show Advanced button in the Get Ticket window. The "Flag this ticket as" section is below the Ticket Lifetime slider. If the "renewable" checkbox is selected, the ticket will be renewable. Click the checkbox to select or deselect it.

      You can adjust the renewable lifetime of the ticket with the Renew Until slider. Move the slider left to shorten the renewable lifetime of the ticket or move the slider right to lengthen it.
      More info A renewable ticket still has the normal lifetime, but before it expires it can be renewed. Each renewal resets the ticket to the length of the original lifetime (e.g. 10 hours). You can renew the ticket as often as needed until the "Renewable Until" deadline is reached (e.g., 6 days). You do not need to enter your password to renew tickets.

      If you let your ticket expire, you cannot renew it even if the ticket is still within the renewable lifetime. For convenience, you can set your tickets to automatically renew.
      About: Renewable Tickets

      Back to top

      Related help

      krb5-1.16/src/windows/leash/htmlhelp/html/leash_topic_kerberos_principals.htm0000644000704600001450000001606113211554426027464 0ustar ghudsonlibuuid Kerberos: How does the other guy know who I am?

      Kerberos: How Does the Other Guy Know Who I Am?

      A portion of the text below was copied with permission from An Inessential Guide to Athena (5th edition) published by the MIT Student Information Processing Board.

      MIT's Athena Project developed a system known as Kerberos to provide for security on a physically insecure network. A complete description of the mechanisms used by Kerberos to provide this security is beyond the scope of this document. This section describes why Kerberos is necessary in a distributed computing environment, the theory behind Kerberos (with pointers to further information), and the user commands which interface to Kerberos. It also gives hints for using Kerberos more effectively.

      Why Kerberos is needed. Most moderately-sized to large computer systems use some form of password protection scheme to authenticate users; that is, they require a user who wishes to log in to give both his name and a secret password which only he and the computer system know. Anyone who happens to know the password can claim to be that user. It is therefore desirable to prevent people from listening in on the conversation between the computer and the user's terminal or workstation.

      This is relatively easy in the case of terminals directly connected to the machine, since each terminal has its own cable. In a local-area network, several (typically between 10 and 200) computers share one cable, and any computer can listen in on any network traffic. With the advent of network monitoring packages for IBM PC's and similar machines, it is relatively easy for a determined user to set up a program to listen in on a network for any and all passwords being sent over. This would allow an intruder to masquerade as someone else, violating their privacy and perhaps stealing information (academic or otherwise). Note that THE ELECTRONIC COMMUNICATIONS PRIVACY ACT of 1986 makes this a Federal crime punishable by lots of nasty stuff (ask your lawyer for details).

      In addition, since Athena (like the Internet) uses a workstation-based model of computation, with most operations taking place on a single-user workstation with occasional requests (for files, etc.) going to other "server" machines, Athena needed to set up some way to allow users to prove their identity to such server machines.

      A few definitions. Knowledge of the following terms is not essential for use of Kerberos but is helpful in understanding what is going on:

      user:A human being who wishes to use a computer system. A user, through his workstation, may make a series of requests to several servers in the course of a session, and would like to avoid (due to sheer laziness, among other things) having to type his password to each machine in question.

      service:A program or set of programs running on a computer which is accessible over the network. The service would like to know with certainty that the workstation to which it is providing the service is really being used by the user who claims to be logged in on the workstation. Note that workstations are not services, and thus one may not use Kerberos to log into them over the network.

      principal:An entity which can both prove its identity and verify the identities of other principals who wish to communicate with it; each user and each service registered with Kerberos is thus a principal.

      ticket: A block of data which, when given to a user, enables her to prove her identity to a service. Tickets are stored in RAM in an area of memory reserved by the Kerberos cache. They are automatically erased when the computer is rebooted or when the user issues the destroy tickets command from Leash. They may also be destroyed from a Command Prompt by executing the command: kdestroy. Tickets contain information which must be considered private to the user, and thus should be protected. As they contain a time stamp, they cease to be valid after a limited time. One ticket is needed for each service; tickets are used to build authenticators, which are sent over the network to the service.

      authenticator: A block of data which a user's workstation sends over the network to a specific service to prove that the workstation really is in use by that user. An authenticator expires after five minutes. One authenticator is typically built per session of use of a service; once the service decodes the authenticator, it generally permits the user to operate for as long as she wants. This behavior is not in any way mandated by the Kerberos suite of programs and libraries (it is just a detail of the implementation), but it is convenient and considered secure enough for most environments.

      How It Works...

      Kerberos uses a standard encryption-based authentication technique with a few variations designed to increase ease of use across administrative entities and reduce the number of possible "attacks" on the system. The system uses cryptographically sealed tickets and authenticators} which may be passed over the network and decrypted only by a user or machine which knows the appropriate encryption/decryption key.

      Using Kerberos...

      After obtaining your initial ticket getting ticket either by logging onto your workstation or by utilizing a Kerberos Ticket Manager (e.g., Leash), Kerberos aware applications will generate authenticators and obtain service tickets without further end user interaction.  Examples of programs which utilize Kerberos authentication include e-mail, distributed file systems, remote login tools, and browsers.

      Registering with Kerberos...

      To use Kerberos you must have an account registered in a REALM associated with the service(s) you wish to access.  Contact your network administrator to determine the registration procedures for your organization.

      Once registered with Kerberos, tickets are obtained by the login program every time you log onto a workstation. You can also manually obtain new tickets (which you usually do only if your old ones have expired, 10 hours after you log in) by running the program kinit. It prompts for a username, requests an initial ticket from Kerberos, and then asks for your password. If you are not registered with Kerberos, it will print Principal unknown (Kerberos). Unless you mistype your username, this should not happen. To correct this, or any other errors, contact the appropriate Help Desk personnel for your organization.

      krb5-1.16/src/windows/leash/htmlhelp/html/leash_option_krb4_properties.htm0000644000704600001450000000235313211554426026733 0ustar ghudsonlibuuid Kerberos Four Properties Command

      Kerberos v4 Properties Command, Ctrl+4

      The Kerberos v4 Properties dialog is accessible from the Options menu.

      Kerberos Four Properties

      Here, you can specify the name of the in-memory cache used to store the Kerberos 4 tickets.  The format of the name is API: followed by the cache name.  Disk caches are not supported by Kerberos for Windows.

      The paths to the Kerberos 4 configuration files: krb.con and krbrealm.con may be changed from this dialog if necessary.  The default is to store the configuration files in the Windows directory.

      krb5-1.16/src/windows/leash/htmlhelp/html/hid_sc_minimize.htm0000644000704600001450000000060713211554426024203 0ustar ghudsonlibuuid (System Minimize Command)

      Minimize command (application Control menu)

      Use this command to reduce the <<YourApp>> window to an icon.

      krb5-1.16/src/windows/leash/htmlhelp/html/Encryption_Types.htm0000644000704600001450000001210513211554426024363 0ustar ghudsonlibuuid Encryption_Types

      Encryption Types

      Kerberos supports several types of encryption for securing session keys and the tickets. The type used for a particular ticket or session key is automatically negotiated when you request a ticket or a service.

      • When encrypting tickets, the Key Distribution Center (KDC) for your Kerberos installation checks for an encryption type that is shared by both the KDC and the service you are attempting to use.
      • When encrypting session keys, the KDC checks for an encryption type shared by the KDC, the service, and the client requesting the session (you).
      How to... Learn about...

      Weak Encryption Types

      In the table of Encryption Types below, some encryption types are noted as weak. Most of them are encryption types that used to be strong but now, with more computing power available, are considered weak and therefore undesirable. However, they are still sometimes used for backwards compatibility. If Kerberos is installed in a network that contains some older machines running operating systems that do not support the newer encryption types, administrators can choose to allow the weaker encryption when connecting to the older machines.

      Back to Top

      View Encryption Types

      1. Click the Options tab and find the View Options panel.
      2. Click the Encryption Type checkbox to select it. This opens the Encryption Type column in the main window, showing the encryption type associated with each of your tickets and session keys.
        How to: Use Ticket Options Panel
      3. Click and drag the line to the right of the Encryption Type column header to widen the column enough to see both the ticket and session key.
      4. Click the blue triangle to the left of a principal name to see all tickets and session keys issued to that principal. Each ticket and key will have an entry in the Encryption type column.
        How to: View Tickets

      Back to Top

      Supported Encryption Types

      Encryption Type Description
      des- The DES (Data Encryption Standard) family is a symmetric block cipher. It was designed to handle only 56-bit keys which is not enough for modern computing power. It is now considered to be weak encryption.
      • des-cbc-crc (weak)
      • des-cbc-md5 (weak)
      • des-cbc-md4 (weak)
      des3- The triple DES family improves on the original DES (Data Encryption Standard) by using 3 separate 56-bit keys. Some modes of 3DES are considered weak while others are strong (if slow).
      • des3-cbc-sha1
      • des3-cbc-raw (weak)
      • des3-hmac-sha1
      • des3-cbc-sha1-kd
      aes The AES Advanced Encryption Standard family, like DES and 3DES, is a symmetric block cipher and was designed to replace them. It can use multiple key sizes. Kerberos specifies use for 256-bit and 128-bit keys.
      • aes256-cts-hmac-sha1-96
      • aes128-cts-hmac-sha1-96
      rc4 or
      arcfour
      The RC4 (Rivest Cipher 4) is a symmetric stream cipher that can use multiple key sizes. The exportable variations are considered weak, but other variations are strong.
      • arcfour-hmac
      • rc4-hmac
      • arcfour-hmac-md5
      • arcfour-hmac-exp (weak)
      • rc4-hmac-exp (weak)
      • arcfour-hmac-md5-exp(weak)

      Back to Top

      Related Help

      krb5-1.16/src/windows/leash/htmlhelp/html/leash_kerberos_copyright.htm0000644000704600001450000000430313211554426026126 0ustar ghudsonlibuuid Kerberos Copyright

      Kerberos Copyright

      This software is being provided to you, the LICENSEE, by the Massachusetts Institute of Technology (M.I.T.) under the following license. By obtaining, using and/or copying this software, you agree that you have read, understood, and will comply with these terms and conditions:

      Permission to use, copy, modify and distribute this software and its documentation for any purpose and without fee or royalty is hereby granted, provided that you agree to comply with the following copyright notice and statements, including the disclaimer, and that the same appear on ALL copies of the software and documentation, including modifications that you make for internal use or for distribution:

      Copyright 1992-2004 by the Massachusetts Institute of Technology. All rights reserved.

      THIS SOFTWARE IS PROVIDED "AS IS", AND M.I.T. MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED. By way of example, but not limitation, M.I.T. MAKES NO REPRESENTATIONS OR WARRANTIES OF MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF THE LICENSED SOFTWARE OR DOCUMENTATION WILL NOT INFRINGE ANY THIRD PARTY PATENTS, COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS.

      The name of the Massachusetts Institute of Technology or M.I.T. may NOT be used in advertising or publicity pertaining to distribution of the software. Title to copyright in this software and any associated documentation shall at all times remain with M.I.T., and USER agrees to preserve same.

      Project Athena, Athena, Athena MUSE, Discuss, Hesiod, Kerberos, Moira, OLC, X Window System, and Zephyr are trademarks of the Massachusetts Institute of Technology (MIT). No commercial use of these trademarks may be made without prior written permission of MIT.

      krb5-1.16/src/windows/leash/htmlhelp/html/leash_option_destroy_tickets_on_exit.htm0000644000704600001450000000126713211554426030564 0ustar ghudsonlibuuid Destroy Tickets/Tokens on Exit Option

      Destroy Tickets/Tokens on Exit Option

      If this option is selected under the Options menu, Leash destroys your tickets and tokens when you Exit Leash; otherwise, the tickets remain. This option is turned off by default.

      krb5-1.16/src/windows/leash/htmlhelp/html/leash_command_get_tickets.htm0000644000704600001450000000307313211554426026230 0ustar ghudsonlibuuid Get Tickets Command

      Get Ticket(s)/Token(s) Command, Ctrl+T

      This command is found under the Action menu; it is also the first button (from the left) in the toolbar.  Use this command to obtain new Kerberos tickets (and perhaps AFS tokens.)

      Advanced Initialize Tickets Dialog

      Basic Initialize Tickets Dialog

      When you select this commmand, Leash displays a dialog requesting your Username, Kerberos Realm, and Password; if these are correct, Leash will obtain tickets for you.  You may optionally specify a ticket lifetime and various Kerberos 5 ticket options:
      • ticket forwarding
      • addressless tickets
      • renewable ticket times

      See Also

      Kerberos tickets

      AFS tokens

      krb5-1.16/src/windows/leash/htmlhelp/html/leash_manpage_aklog.htm0000644000704600001450000001352313211554426025013 0ustar ghudsonlibuuid AKLOG Command

      AKLOG Command

      (from UNIX man page)

      User Commands                                            AKLOG(1)

      NAME
      aklog - Obtain tokens for authentication to AFS

      SYNOPSIS
      aklog [ -d ] [ -force ] [ -hosts ] [ -zsubs ] [ -noprdb ] [
      [ -cell | -c ] cell [ -k kerberos-realm ] ] [ [ -path | -p ]
      pathname ]

      DESCRIPTION
      The aklog program is used to authenticate to a cell or
      directory in AFS, the Andrew Filesystem, by obtaining AFS
      tokens. Ordinarily, aklog is not used directly but called by
      attach(1).

      If aklog is invoked with no command line arguments, it will
      obtain tokens for the workstation's local cell. It is pos-
      sible to invoke aklog with arbitrarily many cells and path-
      names specified on the command line. aklog knows how to
      expand cell name abbreviations, so short forms of cell names
      can be use used. In addition, aklog understands the follow-
      ing command line options:

      -cell | -c cell
      This flag is not ordinarily necessary since aklog can
      usually figure out when an argument is a cell. It can
      be used to introduce a cell name that would ordinarily
      be mistaken for a path name if this should be required.
      If this flag is omitted, an argument will be treated as
      a cell name if it contains no slashes (/) and is neither
      "." nor ".." .

      -k kerberos-realm
      This flag is valid only when immediately following the
      name of a cell. It is used to tell aklog what kerberos
      realm should be used while authenticating to the preced-
      ing cell. This argument is unnecessary except when the
      workstation is not properly configured. Ordinarily,
      aklog can determine this information on its own.

      -path | -p pathname
      Like the -cell flag, this flag is usually unnecessary.
      When it appears, the next command line argument is
      always treated as a path name. Ordinarily, an argument
      is treated as a path name if it is "." or ".." or if it
      contains a slash (/).

      -hosts
      Prints all the server addresses which may act as a sin-
      gle point of failure in accessing the specified direc-
      tory path. Each element of the path is examined, and as
      new volumes are traversed, if they are not replicated,
      the server's IP address containing the volume will be
      displayed. Attach(1) invokes aklog with this option.
      The output is of the form

      host: IP address

      -zsubs
      Causes the printing of the zephyr subscription informa-
      tion that a person using a given path or cell would
      want. Attach(1) invokes aklog with this option. The
      output is of the form

      zsub: instance

      where instance is the instance of a class filsrv zephyr
      subscription.

      -noprdb
      Ordinarily, aklog looks up the AFS ID corresponding to
      the name of the person invoking the command. Specifying
      this flag turns off this functionality. This may be
      desirable if the protection database is unavailable for
      some reason and tokens are desired anyway.

      -d Turns on printing of debugging information. This option
      is not intended for general users.

      -force
      Forces aklog to obtain new tokens even if the user
      already appears to have tokens identical to the new ones
      they would get. This option is most often required when
      the user has recently been added to an AFS group.

      EXIT CODES
      The exit status of aklog will be one of the following:

      0 Success -- No error occurred.

      1 Usage -- Bad command syntax; accompanied by a usage
      message.

      2 Something failed -- More than one cell or pathname was
      given on the command line and at least one failure
      occurred. A more specific error status is returned
      when only one directive is given.

      3 AFS -- Unable to get AFS configuration or unable to get
      information about a specific cell.

      4 Kerberos -- Unable to get tickets for authentication.

      5 Token -- Unable to get tokens.

      6 Bad pathname -- The path given was not a directory or
      lstat(2) failed on some component of the pathname.

      7 Miscellaneous -- An internal failure occurred. For
      example, aklog returns this if it runs out of memory.

      EXAMPLES
      To get tokens for the local cell:
      % aklog

      To get tokens for the athena.mit.edu cell:
      % aklog athena.mit.edu
      or
      % aklog athena

      To get tokens adequate to read
      /afs/athena.mit.edu/user/p/potato:
      % aklog /afs/athena.mit.edu/user/p/potato

      To get tokens for a test cell that is in a test Kerberos
      realm:
      % aklog testcell.mit.edu -k TESTREALM.MIT.EDU

      SEE ALSO
      attach(1), tokens(1), unlog(1)


      krb5-1.16/src/windows/leash/htmlhelp/html/leash_command_renew_tickets.htm0000644000704600001450000000203413211554426026565 0ustar ghudsonlibuuid Renew Tickets Command

      Renew Ticket(s)/Token(s) Command, Ctrl+R

      This command is found on the Action menu; it is also the second button (from the left) in the toolbar.  Use this command to renew the Kerberos tickets (and perhaps AFS tokens) on your local machine without requiring the use of a password.  If your existing tickets cannot be renewed the ticket initialization dialog will be displayed allowing you to request new tickets.

      Note: This command is only available if your existing Kerberos tickets are renewable.


      krb5-1.16/src/windows/leash/htmlhelp/html/leash_topic_online_help.htm0000644000704600001450000000206713211554426025721 0ustar ghudsonlibuuid Help on Using Leash Online Help

      How To Use Leash Online Help

      In Leash, F1 are the online Help keys. Here's what they do:

      Pressing F1...gets you...

      in the Leash main window: Leash Help Topics -- click the one you need.

      in Leash Help Topics: Contents for How To Use Help -- list of topics explaining the features and functions of Windows online help -- click the one you need.

      in a Leash dialogue box: context-sensitive help, i.e., the specific topic that explains where you are and what you're doing.

      at an error message: explanation for the error message.

      krb5-1.16/src/windows/leash/htmlhelp/html/Button_Menu.htm0000644000704600001450000001140013211554426023301 0ustar ghudsonlibuuid Button Panel

      Using the Button Panel

      Use the main buttons in the riboon menu to work with tickets and passwords. Several button functions can also be reached with keyboard shortcuts.

      Button Click to... Details
      Get Ticket Get a new Kerberos ticket. Click this button to open the Get Ticket window. Enter or select your Kerberos principal and password. To verify or change ticket settings and flags, click Show Advanced. When you are finished, click Okay.
      More Get Tickets help
      Renew Ticket Renew tickets.

      If you have multiple principals, renew tickets for the selected principal(s).

      All of the renewable tickets for the selected principal(s) will have their useable lifetimes extended. Each ticket will be reset to the length of the original ticket's lifespan. Note that you cannot renew tickets that have already expired.
      How to renew tickets
      Destroy Ticket Destroy all existing tickets.

      This button is greyed out and not accessible if the Automatically Import option is selected and you have Windows domain tickets imported from your Windows Logon session.
      About importable (Windows domain) tickets
      Imported Windows domain tickets are obtained and renewed by the Windows Logon session, so if you destroy them in MIT Kerberos they are not destroyed in the Windows session. Kerberos would immediately import them again.
      How to destroy tickets
      Export Ticket Export tickets to use in your Windows Logon session to a Windows domain. Click this button to export a ticket you've obtained with the Get Ticket window into your Windows Logon Session. This allows you to use a computer that is not part of a Kerberos realm (or Windows domain) to access that realm.
      How to export tickets
      Make Default Make the selected principal the default principal.

      You won't need to use this button if you have only one principal.
      Select a principal by clicking it and then click Make Default to make the selected principal the default one. The default principal is the one whose tickets are used when an application or service asks for tickets without specifying which principal is being authenticated. How to Make Default Principal
      Change Password Change your Kerberos password. If you have multiple principals, you can enter or select the appropriate one in the Change Password window. Or you can click a principal to select it before using the Change Password button.
      How to change your password

      Related help

      krb5-1.16/src/windows/leash/htmlhelp/html/Options_Menu.htm0000644000704600001450000000543713211554426023476 0ustar ghudsonlibuuid Options Panel

      Using the Options Panel

      Use the Options panel to manage general MIT Kerberos settings.

      Find the Options panel

      Look to the right of the buttons and View panel. If your Kerberos window is wide enough, you will see the Option checkboxes. If the window is too small to display them, you will see an Options button. Click the Options button to reach the option checkboxes.

      Turning Options on and off

      A checkmark indicates that the option is currently turned on. Click an Option checkbox to turn the option on or off.

      Option Turn this on to... Details
      Destroy Tickets on Exit Have MIT Kerberos destroy your tickets when you exit the program.

      Note: MIT Kerberos cannot permanently destroy tickets you've obtained by logging into a Windows domain, even if you've imported them. Those tickets are destroyed when you log out of the domain.
      Turning this option on provides greater security. However, you will need to turn this off if you want to exit MIT Kerberos but leave processes running which require your valid tickets.
      Automatic Ticket Renewal Automatically renew tickets flagged as renewable, without promptings or requiring a password, until the renewal lifetime is reached. Renewing your tickets allows you to run batch jobs without interruption and to work through a long session without continually reentering your password. About renewable tickets

      Note: Automatic ticket renewal will not work if you exit MIT Kerberos or if your machine is in hibernation mode.
      Expiration Alarm Have Kerberos provide an audible alarm 15, 10, and 5 minutes before your tickets expire. Regardless of whether this option is on, Kerberos alerts you to expiring tickets at the same intervals with pop up window. However, the pop up window will not always be visible on a busy desktop. About ticket expiration

      Related help

      krb5-1.16/src/windows/leash/htmlhelp/html/hid_context_help.htm0000644000704600001450000000120413211554426024363 0ustar ghudsonlibuuid (Help Using Help Command)

      Context Help command

      Use this command to obtain help on some portion of <<YourApp>>. When you choose the toolbar's Context Help button, the mouse pointer will change to an arrow and question mark. Then click somewhere in the <<YourApp>> window, such as another toolbar button. The help topic will be shown for the item you clicked.

      krb5-1.16/src/windows/leash/htmlhelp/html/afx_hidw_status_bar.htm0000644000704600001450000000272213211554426025071 0ustar ghudsonlibuuid (status bar)

      Status Bar

      The status bar is displayed at the bottom of the <<YourApp>> window. To display or hide the status bar, use the Status Bar command in the View menu.

      The left area of the status bar describes actions of menu items as you use the arrow keys to navigate through menus. This area similarly shows messages that describe the actions of toolbar buttons as you press them, before releasing them. If after viewing the description of the toolbar button command you wish not to execute the command, then release the mouse button while the pointer is off the toolbar button.

      The right areas of the status bar indicate which of the following keys are latched down:

      Indicator    Description

      CAP           The Caps Lock key is latched down.

      NUM         The Num Lock key is latched down.

      SCRL         The Scroll Lock key is latched down.

      krb5-1.16/src/windows/leash/htmlhelp/html/leash_topic_about_kerberos.htm0000644000704600001450000000414113211554426026426 0ustar ghudsonlibuuid KERBEROS

      About Kerberos

      In Greek myth, the three-headed dog Kerberos guarded the gates of Hades. These days, Kerberos is an authentication service developed at MIT for open network computing environments such as MITnet. Kerberos verifies that you are who you claim to be by matching your username and password, called a Kerberos principal, to a private key encryption.

      When you start an application that relies on Kerberos authentication, you must identify yourself by giving your Kerberos principal. The Kerberos service checks to make sure that your name and password match the encrypted key before it gives you access to the service you have requested. The security of the network environment is maintained by never sending your unencrypted Kerberos password over the network.

      To use the Athena system, you must have a Kerberos username and password. Some Macintosh and Windows applications at MIT that use Kerberos to authenticate a user's identity are Eudora, Zephyr and AFS.

      See Also

      An Authentication Service for Open Network Systems

      (This technical description of Kerberos, by Steiner, Neuman, and Schiller, is available via anonymous ftp from athena-dist.mit.edu, /pub/kerberos/doc/usenix.txt.)

      Kerberos: How Does the Other Guy Know Who I Am?.

      (This basic introduction to Kerberos and definitions of Kerberos-related terms is available in the SIPB publication An Inessential Guide to Athena.)

      krb5-1.16/src/windows/leash/htmlhelp/html/leash_command_update_display.htm0000644000704600001450000000255613211554426026737 0ustar ghudsonlibuuid Update Display Command

      Update Display Command, F5

      Use this command (in the Actions menu, or the black rectangular icon) to update the display of your current Kerberos tickets. You can also perform this function by clicking in the main Leash window.

      Why Use It...

      Although most end users will likely find this Leash feature irrelevant, application developers and support staff may occasionally find it to be useful. For example, you may want an immediate status check of Kerberos tickets if you have just used command-line kinit or kdestroy and want to check that they have functioned successfully.

      How It Works...

      While Leash automatically checks the status of your Kerberos tickets every 30 seconds, the Update Display command forces an immediate status check.

      krb5-1.16/src/windows/leash/htmlhelp/html/leash_export.htm0000644000704600001450000000302013211554426023536 0ustar ghudsonlibuuid Kerberos Export Restrictions and Source Code Access

      Kerberos Export Restrictions and Source Code Access

      Copyright (C) 1989-2004 by the Massachusetts Institute of Technology

      Export of this software from the United States of America may require a specific license from the United States Government. It is the responsibility of any person or organization contemplating export to obtain such a license before exporting.

      WITHIN THAT CONSTRAINT, permission to use, copy, modify, and distribute this software and its documentation for any purpose and without fee is hereby granted, provided that the above copyright notice appear in all copies and that both that copyright notice and this permission notice appear in supporting documentation, and that the name of M.I.T. not be used in advertising or publicity pertaining to distribution of the software without specific, written prior permission. M.I.T. makes no representations about the suitability of this software for any purpose. It is provided "as is" without express or implied warranty.

      Export of the documentation is not restricted.


      krb5-1.16/src/windows/leash/htmlhelp/html/Principals.htm0000644000704600001450000000744113211554426023160 0ustar ghudsonlibuuid Principals

      About Principals

      Your principal is your Kerberos identity. It is your user name plus the Kerberos realm (or Windows domain) you are part of. For example, if your user name is jdoe and you are part of the SALES.WIDGET.COM realm, your principal is jdoe@SALES.WIDGET.COM.

      Learn about...

      Using a Single Principal

      If like many users you just have one Kerberos identity, you will have just one principal.

      In most installations, MIT Kerberos knows your realm, so when you start to enter your principal in the Get Ticket window it will auto-complete the realm for you. If you select the "Remember this principal" checkbox, the next time you get tickets Kerberos will auto-complete your principal as soon as you start to type.

      The main window shows your principal, along with information about tickets issued to it.
      How to: View Tickets

      Back to top

      Multiple principals

      Some users have multiple principals. For example, administrators often have one principal with standard access and an administrative principal with administrative access. Also, some Kerberos installations require multiple principals to access multiple realms.
      How to: Manage Multiple Principals
      How to: Make Default Principal

      Back to top

      Default Principal

      Your default principal appears in bold font in the main window. If you have a single principal, that principal is always the default. But if you have multiple principals you will need to change the default principal depending on what service or host you need to access.

      When you try to use a Kerberized application, the application attempts to authenticate you by requesting your credentials from Kerberos. Some applications do this by asking for a specific principal's credentials, but others ask generically.

      When applications make a generic request, Kerberos does not know which of your principals is being authenticated and checks the default principal for tickets. If the default principal is not the correct one, the application will usually simply fail to work with no warning or notice.

      To set your default principal, select a principal in the main window and then click the Make Default button.
      How to: Make Default Principal

      Back to top

      krb5-1.16/src/windows/leash/htmlhelp/html/leash_external_kinit.htm0000644000704600001450000000140013211554426025235 0ustar ghudsonlibuuid kinit.exe

      kinit.exe program

      This is a little program which will run a command-prompt, text-based version of the ticket initialization window. (However, unlike in the graphical version, you do not have the option of changing the ticket lifetime.) This can be useful if you have a slow computer, or if you are having difficulty with the graphical version for some reason.

      krb5-1.16/src/windows/leash/htmlhelp/html/Getting_Started.htm0000644000704600001450000001412413211554426024137 0ustar ghudsonlibuuid Getting Started

      Getting Started

      Get tickets and get to work!

      MIT Kerberos provides an easy way to manage your Kerberos tickets. Jump to one of the following starting places, scroll down to browse, or use the table of contents to the left of this page to pick a topic.

      • Unfamiliar with Kerberos tickets? Click here
      • Familiar with Kerberos tickets but new to MIT Kerberos? Click here.
      • Just want a quick introduction to getting tickets? Click here
      • Want help using this help system? Click here

      Unfamiliar with Kerberos?

      Kerberos is a network authentication protocol that uses the concept of short term "tickets" to allow users to securely access services over a physically insecure network. Kerberos, or MIT Kerberos, is also the name of this application. MIT Kerberos provides an easy interface for managing Kerberos tickets.

      Click an introductory topic below to jump to the topic page. Click the back button or "Getting Started" in the table of contents to the left to return to this page.

      TopicDescription
      What is Kerberos? Introduction to Kerberos and what it offers.
      Kerberos Terminology Explanation of principals, realms, and tickets. Provides an overview of how Kerberos works.
      About Tickets Learn about tickets, ticket expiration, renewable tickets, and forwardable tickets.

      Back to Top

      Familiar with Kerberos tickets but new to MIT Kerberos?

      MIT Kerberos is an easy to use interface for managing your Kerberos tickets. The main window shows all of your tickets. The ribbon menu at the top of the window contains command buttons in the Home tab. Click the Options tab to reach checkboxes that control what ticket information is displayed and checkboxes that control MIT Kerberos's automatic behavior.

      Browse the table below to see where to find the commands and options you need.

      How to...
      Get new MIT Kerberos tickets Click the Get Ticket button.
      How to: Get Tickets
      Change ticket flags and settings (e.g., flag a ticket as renewable) In the Get Ticket window, click the Show Advanced button to reach ticket settings and flags.
      About: Ticket Settings and Flags
      Change your password Click the Change Password button.
      How to: Change Password
      Change what ticket information is displayed In the Options tab, select or deselect checkboxes in the View Options panel.
      How to: Use View Options Panel
      Set Kerberos's automatic functions (auto renew, auto destroy, audible ticket expiration alarm) In the Options tab, select or deselect checkboxes in the Ticket Options panel.
      How to: Use Ticket Options Panel
      Renew your tickets Click the Renew Tickets button to renew your tickets one time. To have MIT Kerberos automatically renew all of your tickets, go to the Options tab and select Automatic Ticket Renewal in the Ticket Options panel.
      How to: Renew Tickets
      Destroy your MIT Kerberos tickets Click the Destroy Tickets button.
      How to: Destroy Tickets
      Manage multiple principals When you get tickets for a principal, MIT Kerberos offers to remember the principal for you. The next time you start to enter a saved principal, Kerberos will auto-complete it for you.

      In the main window, click a principal to select it. The Renew Ticket, Change Password, and Make Default buttons then apply to the selected principal.

      How to: Manage Multiple Principals
      Change Kerberos properties You can allow realm names that use lower case letters by selecting Allow Mixed Case Realm in the Ticket Options panel in the Options tab.
      How to: Use Ticket Options Panel

      However, most properties are set by modifying the appropriate configuration file.

      Back to Top

      Introduction to Getting Tickets

      Click the Get Ticket button and enter your principal (your Kerberos identity) and password to obtain a ticket. The ticket allows you to securely access all of the computers and services set up to authenticate you through Kerberos, until the ticket expires, without requiring you to enter your password again.
      How to: Get Tickets

      Using This Help System

      Use the table of contents to the left to explore the available help. Or, if you are looking for information about a particular subject, click the Index or Search tab.

      The help pages contain many links to other pages in the help system. If you click a link, you can return to the page you started on with the Back button or by finding your spot in the table of contents.

      Back to Top

      krb5-1.16/src/windows/leash/htmlhelp/html/hid_sc_restore.htm0000644000704600001450000000067713211554426024054 0ustar ghudsonlibuuid (Restore command (Control menu))

      Restore command (Control menu)

      Use this command to return the active window to its size and position before you chose the Maximize or Minimize command.

      krb5-1.16/src/windows/leash/htmlhelp/html/Renew_Tickets2.htm0000644000704600001450000000770713211554426023711 0ustar ghudsonlibuuid Renew_Tickets

      Renew Tickets

      Renewing your tickets allows you to run batch jobs without interruption and to work through a long session without continually reentering your password. Each time you renew your ticket, Kerberos resets the ticket lifetime to the length of the orginal ticket.

      How to...

      Get renewable tickets

      In most configurations of Kerberos, you can choose to get renewable tickets. In some installations they will even be the default ticket setting.

      1. Click the Get Ticket button on the top of the window.
      2. Enter your user name and password in the Get Ticket window. If the advanced settings are not visible, click Show Advanced Settings.
      3. Under "Flag this ticket as, " select Renewable if it is not already checked.
      4. Use the Renewable Until slider if you want to adjust how many days (or hours) you will be able to renew this ticket.
      5. Click OK.

      See which of your tickets are renewable

      In the main Kerberos window, click the Flags checkbox. The Flags column is added to your view. Renewable tickets have the word "renewbale" in this column.

      Find how long a ticket can be renewed

      In the main Kerberos window, click the Renewable Until checkbox. The Renewable Until column will appear. Your can renew your ticket repeatedly until the date and time in this column is reached, as long as you renew it while it is still valid.

      Renew ticket once

      To renew your existing Kerberos ticket(s) just once, click the Renew Ticket button at the top of the window. Your ticket(s) will be renewed with the same lifespan as the original ticket. The new expiration time is listed in the "Valid Until" column.

      Renew ticket automatically

      To set your Kerberos tickets to automatically renew for the entire renewable lifetime of the tickets, click the Options drop down button and select Automatic Ticket Renewal. If this option is already checked, selecting it will uncheck it and turn automatic renewal off.

      Note: MIT Kerberos can only automatically renew tickets while MIT Kerberos is active and running. This means that if your machine is in hibernation mode or if MIT Kerberos is not running when it is time to renew your tickets, your tickets will not be renewed.

      Renew Ticket Errors

      If any of the conditions listed below is not met, you will see an error message and then the Get Tickets window will open, allowing you to get a new ticket.

      You can renew your existing Kerberos tickets if all of the following are true:

      • The "Get tickets that can be renewed" box was selected when you obtained the ticket;
        and
      • The " renewable by" deadline has not been reached ;
        and
      • Your ticket has not already expired.
      Related help krb5-1.16/src/windows/leash/htmlhelp/html/leash_option_afs_properties.htm0000644000704600001450000000203013211554426026632 0ustar ghudsonlibuuid AFS Properties Command

      AFS Properties Command, Ctrl+A

      The AFS Properties dialog can be found on the Options menu when AFS is available.

      AFS Properties Dialog

      There is a radio button pair to enable or disable the retrieval and display of AFS tokens. There is also an AFS Properties button to bring up the AFS Client Configuration program in order to alter settings for Client Properties, Cell Hosts, and Submounts.

      krb5-1.16/src/windows/leash/htmlhelp/html/leash_menu_commands.htm0000644000704600001450000000544313211554426025055 0ustar ghudsonlibuuid Leash Commands

      Leash Commands

      File:
      File menu

      Exit

      Action:
      Action Menu

      Get Ticket(s)/Token(s)

      Renew Ticket(s)/Token(s)

      Import Ticket(s)/Token(s)

      Destroy Ticket(s)/Token(s)

      Change Password

      Reset Window Size/Pos

      Synchronize Time

      Update Display

      View:
      View menu

      Large Icons

      Toolbar

      Status Bar

      Debug Window

      Options:
      Options menu

      Upper Case Realm Name

      Expiration Alarm

      Destroy Tickets/Tokens on Exit

      Leash Properties

      Kerberos Properties

      Kerberos v4 Properties

      Kerberos v5 Properties

      AFS Properties

      Help:
      Help menu

      About Leash...

      krb5-1.16/src/windows/leash/htmlhelp/html/leash_command_reset_window.htm0000644000704600001450000000117113211554426026431 0ustar ghudsonlibuuid Reset Window Size/Pos Option

      Reset Window Size/Pos Option

      When you select this from the Options menu, the Leash window moves to its default size and position, near the upper left corner of the screen.

      krb5-1.16/src/windows/leash/htmlhelp/html/leash_manpages.htm0000644000704600001450000000112313211554426024012 0ustar ghudsonlibuuid Leash Copyright

      Kerberos for Windows Command Line Tools Manpages

      This section reproduces the manpages for the Kerberos for Windows command line tools.

      krb5-1.16/src/windows/leash/htmlhelp/html/How_Kerberos_Works.htm0000644000704600001450000000257113211554426024631 0ustar ghudsonlibuuid How Kerberos Works

      How Does Kerberos Work?

      The Kerberos protocol uses secret-key cryptography to allow the user and the service the user is accessing to prove their identities to each other and then to encrypt the rest of their communications. This mutual authentication and subsequent encryption maintain privacy and data integrity for both user and service.

      A basic understanding of Kerberos can be gained by reading the Kerberos terminology page. You do not need to know the inner workings of the encryption and authentication to use Kerberos. However, if you are curious to know more, the MIT Kerberos Consortium has an excellent website with links to several varieties of documentation, including a tutorial of the Kerberos protocol. MIT Kerberos Consortium documentation page

      Related Help

      krb5-1.16/src/windows/leash/htmlhelp/html/leash_manpage_kdestroy.htm0000644000704600001450000000540213211554426025557 0ustar ghudsonlibuuid KDESTROY Command

      KDESTROY Command

      (from UNIX man page)

      User Commands  KDESTROY ( 1 )
      
      NAME
       kdestroy - destroy Kerberos tickets
      
      SYNOPSIS
       kdestroy [-5] [-4] [-q] [-c cache_name]
      
      DESCRIPTION
      
       The kdestroy utility destroys the user's active Kerberos
       authorization tickets by writing zeros to the specified credentials
       cache that contains them.  If the credentials cache is not specified,
       the default credentials cache is destroyed.  If kdestroy was built with
       Kerberos 4 support, the default behavior is to destroy both Kerberos 5
       and Kerberos 4 credentials.  Otherwise, kdestroy will default to
       destroying only Kerberos 5 credentials.
      
      OPTIONS
      
       -5 destroy Kerberos 5 credentials.  This overrides whatever the
          default built-in behavior may be.  This option may be used with -4
      
       -4 destroy Kerberos 4 credentials.  This overrides whatever the
          default built-in behavior may be.  This option is only available
          if kinit was built with Kerberos 4 compatibility.  This option may
          be used with -5
      
       -q Run quietly.  Normally kdestroy beeps if it fails to destroy the
          user's tickets.  The -q flag suppresses this behavior.
      
       -c cache_name
          use cache_name as the credentials (ticket) cache name and
          location; if this option is not used, the default cache name and
          location are used.
      
       The default credentials cache may vary between systems.  If the
       KRB5CCNAME environment variable is set, its value is used to name the
       default ticket cache.
      
       Most installations recommend that you place the kdestroy command in
       your .logout file, so that your tickets are destroyed automatically
       when you log out.
      
      ENVIRONMENT
       Kdestroy uses the following environment variables:
      
       KRB5CCNAME Location of the Kerberos 5 credentials (ticket) cache.
      
       KRBTKFILE Filename of the Kerberos 4 credentials (ticket) cache.
      
      FILES
       /tmp/krb5cc_[uid] default location of Kerberos 5 credentials cache
       ([uid] is the decimal UID of the user).
      
       /tmp/tkt[uid] default location of Kerberos 4 credentials cache ([uid]
       is the decimal UID of the user).
      
      SEE  ALSO
       kinit(1), klist(1), krb5(3)
      
      BUGS
       Only the tickets in the specified credentials cache are
       destroyed.  Separate ticket caches are used to hold root instance and
       password changing tickets.  These should probably be destroyed too,
       or all of a user's tickets kept in a single credentials cache.
      krb5-1.16/src/windows/leash/htmlhelp/html/leash_topic_leash_help_topics.htm0000644000704600001450000000235113211554426027106 0ustar ghudsonlibuuid Leash Program

      Leash Program

      leash \'le-sh\ n [ME lees, leshe, fr. OF laisse, fr. laissier] 1: a line for leading or restraining an animal 2a: a set of three animals (as greyhounds, foxes, bucks, or hares) 2b: a set of three - leash vt 3: a Windows program developed at MIT to manage a user's Kerberos tickets.

      Leash Help Topics

      Leash Screen Display (Kerberometer and Dash Notification)

      Leash Commands

      How To Use Leash Online Help

      Leash Copyright

      Acknowledgments

      Reporting Problems with Leash

      krb5-1.16/src/windows/leash/htmlhelp/html/Kerberos_Terminology.htm0000644000704600001450000001141013211554426025207 0ustar ghudsonlibuuid Kerberos Terminology

      Kerberos Terminology

      It is helpful to understand three terms when using Kerberos; principals, realms, and tickets.

      Principals
      A Kerberos principal is a unique identity that uses Kerberos. For users, it is the identity you use to log on to Kerberos. Principals are a combination of your user name and the name of the realm (or domain) you belong to, in the form username@REALM.NAME. For example: jdoe@SALES.WIDGET.COM. Some people will have more than one principal. An administrator might have a regular principal and a separate one with administrative rights. Or if a particular installation uses multiple realms and requires a separate log-on for each one, people with access to multiple realms will have a principal for each realm.

      Because Kerberos provides mutual authentication, the network resources that use Kerberos also have unique principals. However, you do not need to know a service's principal to access it.

      Back to Top
      Realms
      Kerberos realms are a way of logically grouping resources and identities that use Kerberos. Your realm is the home of your Kerberos identity and your point of entry to the network resources controlled by Kerberos. In Windows, realms are called domains.

      When a Kerberos installation is set up, administrators decide how to group identities and network resources into realms. For example, some installations group all network resources into one realm. Others group all identities into one realm that is solely used as an entry point to resources grouped in other realms. Depending on your installation and your needs, you might have a principal (or principals) in only one realm that provides you with all the access you need, or you might have different principals for accessing different realms.

      Realms are usually named after the DNS domain they correspond to, but using all upper case letters. For example, Widget Makers Incorporated might have a realm named WIDGETMAKERSINC.COM. By definition, each network resource in a Kerberos realm uses the same Kerberos installation for authentication.

      Back to Top
      Tickets
      Kerberos uses the concept of tickets to keep passwords from being transmitted in the clear and to provide users the convenience of a single log-on to access multiple services and hosts.

      Once a you provide a valid principal and password, Kerberos issues you a ticket with a limited lifetime. This ticket is an encrypted block of data that authenticates you. In most cases the ticket allows you to access all of the appropriate network resources in the realm you use, for the lifetime of the ticket, without having to take any further action.

      When you access one of these resources, MIT Kerberos passes your initial Ticket Granting Ticket (TGT) to the service. Kerberos verifies the ticket and then issues a separate ticket that allows access to that service. You don't have to worry about obtaining or managing these new service tickets; they are automatically issued. Service tickets can be viewed with MIT Kerberos but cannot be directly obtained or destroyed through it.

      Tickets contain two encryption keys: the ticket key and the session key. The ticket key is shared between the Kerberos infrastructure and the service you are using. The session key is shared between you and the service, and is used to encrypt and decrypt communication with the service.

      Back to Top

      Related Help

      krb5-1.16/src/windows/leash/htmlhelp/html/leash_view_debug_window.htm0000644000704600001450000000237013211554426025733 0ustar ghudsonlibuuid Debug Window Option

      Debug Window

      When this item (found under the Action menu) is checked, the Leash Debug Window appears.

      Debug Window

      From this window, commands that Leash issues to the Kerberos server are visible. Here, you can see exactly what Leash is doing. This action is useful if you are having a problem with Leash and want to see more exactly what is going on, or if you are writing Kerberized applications dependent on Kerberos tickets or the actions of Leash. 

      Note: Debugging is only supported by Kerberos 4 and AFS.  Kerberos 5 protocol operations cannot be debugged using Leash.

      krb5-1.16/src/windows/leash/htmlhelp/html/KINIT.htm0000644000704600001450000002207313211554426021730 0ustar ghudsonlibuuid KINIT

      KINIT Command

      The following information reproduces the information from UNIX man page for the KINIT command.

      SYNOPSIS

      kinit [-V] [-l lifetime] [-s start_time] [-r renewable_life] [-p | -P] [-f | -F] [-a] [-A] [-C] [-E] [-v] [-R] [-k [-t keytab_file]] [-c cache_name] [-n] [-S service_name] [-T armor_ccache] [-X attribute[=value]] [principal]

      DESCRIPTION

      kinit obtains and caches an initial ticket-granting ticket for principal.

      OPTIONS

      -V display verbose output.
      -l lifetime requests a ticket with the lifetime lifetime. The value for lifetime must be followed immediately by one of the following delimiters:
      • s seconds
      • m minutes
      • h hours
      • d days
      as in "kinit -l 90m". You cannot mix units; a value of `3h30m' will result in an error. If the -l option is not specified, the default ticket lifetime (configured by each site) is used. Specifying a ticket lifetime longer than the maximum ticket lifetime (configured by each site) results in a ticket with the maximum lifetime.
      -s start_time requests a postdated ticket, valid starting at -start_time. Postdated tickets are issued with the invalid flag set, and need to be fed back to the kdc before use.
      -r renewable_life requests renewable tickets, with a total lifetime of -renewable_life. The duration is in the same format as the -l option, with the same delimiters.
      -f request forwardable tickets.
      -F do not request forwardable tickets.
      -p request proxiable tickets.
      -P do not request proxiable tickets.
      -a request tickets with the local address[es].
      -A request address-less tickets.
      -k [-t keytab_file] requests a ticket, obtained from a key in the local host's keytab file. The name and location of the keytab file may be specified with the -t keytab_file option; otherwise the default name and location will be used. By default a host ticket is requested but any principal may be specified. On a KDC, the special keytab location KDB: can be used to indicate that kinit should open the KDC database and look up the key directly. This permits an administrator to obtain tickets as any principal that supports password-based authentication.
      -n Requests anonymous processing. Two types of anonymous principals are supported. For fully anonymous Kerberos, configure pkinit on the KDC and configure pkinit_anchors in the client's krb5.conf. Then use the -n option with a principal of the form @REALM (an empty principal name followed by the at-sign and a realm name). If permitted by the KDC, an anonymous ticket will be returned. A second form of anonymous tickets is supported; these realm-exposed tickets hide the identity of the client but not the client's realm. For this mode, use kinit -n with a normal principal name. If supported by the KDC, the principal (but not realm) will be replaced by the anonymous principal. As of release 1.8, the MIT Kerberos KDC only supports fully anonymous operation.
      -T armor_ccache Specifies the name of a credential cache that already contains a ticket. If supported by the KDC, This ccache will be used to armor the request so that an attacker would have to know both the key of the armor ticket and the key of the principal used for authentication in order to attack the request. Armoring also makes sure that the response from the KDC is not modified in transit.
      -c cache_name use cache_name as the Kerberos 5 credentials (ticket) cache name and location; if this option is not used, the default cache name and location are used. The default credentials cache may vary between systems. If the KRB5CCNAME environment variable is set, its value is used to name the default ticket cache. If a principal name is specified and the type of the default credentials cache supports a collection (such as the DIR type), an existing cache containing credentials for the principal is selected or a new one is created and becomes the new primary cache. Otherwise, any existing contents of the default cache are destroyed by kinit.
      -S service_name specify an alternate service name to use when getting initial tickets.
      flag_RSA_PROTOCOL[=yes] specify use of RSA, rather than the default Diffie-Hellman protocol.

      ENVIRONMENT

      Kinit uses the following environment variables:

      KRB5CCNAME Location of the default Kerberos 5 credentials (ticket) cache, in the form type:residual. If no type prefix is present, the FILE type is assumed. The type of the default cache may determine the availability of a cache collection; for instance, a default cache of type DIR causes caches within the directory to be present in the collection.

      FILES

      /tmp/krb5cc_[uid] default location of Kerberos 5 credentials cache ([uid] is the decimal UID of the user).
      /etc/krb5.keytab default location for the local host's keytab file.

      SEE ALSO

      krb5-1.16/src/windows/leash/htmlhelp/html/View_Menu.htm0000644000704600001450000001153613211554426022752 0ustar ghudsonlibuuid View Panel

      Using the View Panel

      Use the View panel to choose which information columns are displayed in the main window. The View panel is to the right of the buttons in the top of the Kerberos window.

      Show or Hide View Columns

      A checkmark next to a View option indicates that the View column is currently shown in the main window. For example, "Valid Until" is selected by default, so the main window shows the Valid Until column unless you unselect that checkbox.

      Viewing Ticket Information

      The columns selected in the View panel show in the main window. Click and drag the line separating two column headings to make a column wider or narrower. Click the blue triangle next to a principal to see information for all of the principal's tickets. More help about viewing tickets

      Column Descriptions

      Checkbox Name Select this checkbox to... Details
      Issued See the date and time your ticket was originally obtained. If the ticket is imported, this is the time it was originally obtained when you logged on to a Windows domain with a Windows Logon session.
      Renewable Until See the date and time that your renewable tickets cannot be renewed any more. After this time you must get a new ticket to access services authenticated by Kerberos. If this column shows Not Renewable, the ticket was not flagged as renewable when you obtained it.

      Related Help:
      Valid Until See when your ticket will expire. Note that you cannot renew a ticket if you let it expire. Kerberos alerts you to expiring tickets with a warning in a pop up window. To add an audible warning, select Expiration Alarm in the Options panel.
      Using the Options Panel
      Encryption Type See the encryption type used to encrypt each session key and ticket. This can be useful when troubleshooting. Kerberos supports multiple types of encryption. The type used for a particular ticket or session key is automatically negotiated when you request a ticket or a service.
      More About Encryption Types
      Flags See how the tickets were flagged (renewable and/or fowardable) when you obtained them. You cannot change how an existing flag is set. If you need a ticket with different flags, you must get a new ticket.
      About ticket settings and flags
      Import Status See which of your tickets have been imported (or can be imported), from a Windows Logon session, and which have been exported (or can be exported) into a Windows Logon session.

      This column is only available when you have Kerberos tickets obtained by logging into Windows Logon session to enter a Windows domain.

      About importable (Windows domain) tickets
      The import status tells you what application was used to obtain the ticket, and what application can fully use it now. Tickets originally obtained by starting a Windows Logon session in a domain are imported or importable to MIT Kerberos, or they are protected from being imported.

      Tickets obtained with the Get Ticket window are eithe exportable or exported to the Windows Logon session. Import Status meanings

      Related help

      krb5-1.16/src/windows/leash/htmlhelp/html/leash_option_leash_properties.htm0000644000704600001450000000651413211554426027170 0ustar ghudsonlibuuid Leash Properties Command

      Leash Properties Command, Ctrl+L

      The Leash Properties dialog, located on the Options menu, allows you to configure operational properties specific to the Leash application which are not accessible directly via the Options menu.


      Leash Properties

      Here you can set a time server from which Leash will obtain the correct time.  Leash needs the correct time because of the time dependencies in Kerberos tickets.  When you specify a time server, Leash tries to get the time from that server when you next run the Synchronize Time command.  The default value for the time server is "time".  If access to a time server were to fail, Leash would notify you, and revert to the server "time".  Whichever server succeeds, Leash would tell you where it found the time.  See the Synchronize Time command for more information.

      The Automatic MSLSA Ticket Importation radio buttons allow you to configure how Leash interacts with the Microsoft Kerberos Authentication Provider.  Leash will automatically import Kerberos Tickets from the Microsoft LSA at startup depending upon the selected option and whether or not the Kerberos Authentication Provider was used for Windows Logon authorization.  Never means do not import tickets from the MSLSA; Always means do import tickets from the MSLSA; and When MSLSA Principal matches Default Realm means import tickets from the MSLSA only if the Kerberos principal belongs to the Kerberos Realm specified within the Kerberos Properties Dialog.

      When Request Kerberos 4 credentials is checked, Leash will attempt to retrieve Kerberos 4 credentials when ticket initialization, renewal, or importation is performed.  Leash will attempt a Kerberos 5 to Kerberos 4 conversion and if that fails an initial Kerberos 4 ticket request will be generated.  Kerberos realms are increasingly configured to support on Kerberos 5.  If the realms you use do not support Kerberos 4 it is suggested that this button be unchecked.

      The Restore Leash Defaults button is used to restore user configurable Leash settings to the defaults as configured either by the local machine system administrator or by the Kerberos for Windows distribution.

      krb5-1.16/src/windows/leash/htmlhelp/html/leash_command_import_tickets.htm0000644000704600001450000000211313211554426026755 0ustar ghudsonlibuuid Import Tickets Command

      Import Ticket(s)/Token(s) Command, Ctrl+I

      This command is found on the Action menu; it is the third button (from the left) in the toolbar.  Use this command to import Kerberos tickets from your Windows Logon Session.  Importing tickets will result in the destruction of existing tickets.  Leash will confirm the operation if necessary.

      Note:  This command is only available if your Windows Logon Session is authenticated using Kerberos.

      See Also

      Kerberos tickets

      AFS tokens

      krb5-1.16/src/windows/leash/htmlhelp/html/leash_help_about_leash32.htm0000644000704600001450000000303313211554426025664 0ustar ghudsonlibuuid About Leash Command

      About Leash

      When you access this window from the Help menu, you see a Module list, three radio buttons, and a Properties button. Modules are executables and dll files that Leash may require.

      About Leash dialog

      The radio buttons let you choose to view a list of:

      • Leash Modules - displays the modules that Leash currently has loaded for its own use;

      • All Modules - displays Leash modules as well as those loaded by the OS;

      • Missing Modules - displays modules that Leash needs for complete functionality but that are not found. (Leash can still function with some modules missing.). This is useful if part of Leash is missing; you can find which files are needed to restore full functionality.

      If you select a module and click on the Properties button, Leash displays the properties of the selected module - both the general properties and those of this particular version.

      krb5-1.16/src/windows/leash/htmlhelp/html/MS2MIT.htm0000644000704600001450000000157413211554426022030 0ustar ghudsonlibuuid MS2MIT

      MS2MIT Command

      The following information reproduces the information from UNIX man page for the MS2MIT command.

      SYNOPSIS

      ms2mit

      DESCRIPTION

      The ms2mit command is used to import Kerberos credentials from the current Windows Logon Session and insert them into the MIT Kerberos default Credentials Cache.

      SEE ALSO

      krb5-1.16/src/windows/leash/htmlhelp/html/hid_help_index.htm0000644000704600001450000000116113211554426024010 0ustar ghudsonlibuuid (Index command (Help menu))

      Index command (Help menu)

      Use this command to display the opening screen of help. From the opening screen, you can jump to step-by-step instructions for using <<YourApp>> and various types of reference information.

      Once you open help, you can click the Contents button whenever you want to return to the opening screen.

      krb5-1.16/src/windows/leash/htmlhelp/html/leash_errors.htm0000644000704600001450000000104413211554426023535 0ustar ghudsonlibuuid Leash Copyright

      Common Leash Error Messages

      This section describes error messages commonly displayed by Leash. krb5-1.16/src/windows/leash/htmlhelp/html/Make_Default.htm0000644000704600001450000000310113211554426023362 0ustar ghudsonlibuuid Make Default

      Make Default Principal

      Your default principal is the one whose tickets are used when an application or service asks for tickets without specifying which principal is being authenticated. If you plan to use an application, service, or network that only one of your principals has access to, first set that principal to be the default.

      If you have only one principal, that principal is automatically the default.

      Set Default Principal

      1. Select the principal by clicking it in the main window (if the principal is not listed, first get tickets for it).
      2. Click the Make Default button.

      The default principal appears in bold font in the main window.

      Related help

      krb5-1.16/src/windows/leash/htmlhelp/html/leash_external_ms2mit.htm0000644000704600001450000000120013211554426025330 0ustar ghudsonlibuuid ms2mit.exe

      ms2mit.exe program

      This is another way to import Windows Logon Session Kerberos tickets for use by Leash and other Kerberos for Windows applications.  The functionality is equivalent to the Import Tickets Command.

      krb5-1.16/src/windows/leash/htmlhelp/html/leash_view_toolbar.htm0000644000704600001450000000340413211554426024717 0ustar ghudsonlibuuid Leash Toolbar

      Leash Toolbar

      By default, this option on the View menu is selected. When it is checked, the toolbar containing icons for commonly used commands is visible. Otherwise, Leash hides it.

      Leash Toolbar

      The Leash Toolbar contains buttons which act as shortcuts to the most frequently used Actions found on the Menubar.  From left to right:

      1. Get Tickets
      2. Renew Tickets
      3. Import Tickets
      4. Destroy Tickets
      5. Change Password
      6. Update Display
      7. Synchronize Time

      krb5-1.16/src/windows/leash/htmlhelp/html/View_Tickets.htm0000644000704600001450000001403113211554426023445 0ustar ghudsonlibuuid View Tickets

      View Tickets

      MIT Kerberos displays your tickets in the main window. The tickets (if any) are organized by the principal who owns them. To the right of the principal are columns with information about the tickets.

      • To show or hide information columns, use the View Options panel in the Options tab. How to: Use View Options Panel
      • To make a column wider or narrower, click and drag the line separating two column headings.
      • To see information for all of a principal's tickets, click the arrow next to the principal name. Otherwise the information displayed applies only to the initial Ticket Granting Ticket (TGT).

      Use the table below to jump to a column description, or scroll down to view all available columns.

      Learn about...

      Column Description
      Principal The identity that has obtained the ticket. This is your user name (e.g., Jsmith) plus the Kerberos realm (or Windows domain) you belong to (e.g., @SERVER.MEGACORP.COM). If like many users you have only one Kerberos name and belong to only one realm, you will have only one principal.

      The principal that is currently the default principal appears in bold. About: Default Principals

      The information displayed in the columns to the right of the principal applies only to the principal's initial Ticket Granting Ticket (TGT). Click the arrow in front of the principal name to expand the view. The expanded view shows all of the tickets and session keys issued to the principal. The TGT is listed with a prefix of krbtgt. Any other tickets and session keys were automatically issued when you accessed a service through Kerberos.
      About: Kerberos Terminology (Tickets)
      Issued The date and time the ticket was originally obtained.
      Renewable Until The date and time marking the end of each ticket's renewable lifetime. If the column is wide enough you will also see the number of days and hours remaining in the ticket's renewable lifetime. After this time, you cannot renew the ticket and must instead get a new one.

      If this column shows Not Renewable, the ticket was not flagged as renewable when you obtained it.

      Related Help:
      Valid Until The date and time the ticket will expire and can no longer be used or renewed. If the column is wide enough you will also see the number of hours and minutes remaining before the ticket expires. Kerberos alerts you to expiring tickets with a warning in a pop up window.

      To add an audible warning, open the Options tab and select Expiration Alarm in the Ticket Options panel.
      How to: Use Ticket Options Panel
      Encryption Type Shows what type of encryption was used to encode the session key and the ticket. Kerberos supports multiple types of encryption. The type used for a particular ticket or session key is automatically negotiated when you request a ticket or a service.
      About: Encryption Types
      Flags Shows how the tickets were flagged (renewable and/or fowardable) when you obtained them. You cannot change how an existing flag is set. If you need a ticket with different flags, you must get a new ticket.

      Forwardable and Proxiable tickets can be forwarded to the remote host when you connect via telnet, ssh, ftp, rlogin, or similar applications.

      Renewable tickets can be renewed until the time and day shown in the Renewable Until column. Each time a ticket is renewed, its lifetime is extended by the length of the original ticket.

      krb5-1.16/src/windows/leash/htmlhelp/html/Command_Line.htm0000644000704600001450000000241713211554426023377 0ustar ghudsonlibuuid Command_Line

      Kerberos with Command Prompt

      MIT Kerberos can be run from the Command Prompt in Windows. The following commands are available. Click a command name to see the relevant UNIX man page.

      KINIT Log in to MIT Kerberos and obtain tickets.
      KLIST List all of your valid tickets.
      KDESTROY  Destroy all of your tickets.
      KPASSWD Change password.
      KSWITCH Specify primary (default) cache.
      KVNO Acquire a service ticket for the specified principal(s) and show the key version numbers.
      KCPYTKT Copy the specified service tickets to the destination credentials cache.
      krb5-1.16/src/windows/leash/htmlhelp/html/hid_app_about.htm0000644000704600001450000000063013211554426023643 0ustar ghudsonlibuuid (About command (Help menu))

      About command (Help menu)

      Use this command to display the copyright notice and version number of your copy of <<YourApp>>.

      krb5-1.16/src/windows/leash/htmlhelp/html/leash_option_expiration_alarm.htm0000644000704600001450000000212613211554426027151 0ustar ghudsonlibuuid Low Ticket/Token Time Alarm Option

      Expiration Alarm Option

      Leash will always pop up windows with warnings that your tickets are about to expire, beginning 15 minutes before the time of expiration and continuing every 5 minutes. However, when this option is selected under the Options menu, a bell will ring as well.

      When you view your tickets and tokens, those shown in yellow are due to expire in less than 15 minutes; those in green have 15 minutes or greater. (A red ticket is one you have but is expired; gray tickets are not available to you at the current time, because Leash or your machine is missing a requisite module or piece of functionality.)

      krb5-1.16/src/windows/leash/htmlhelp/html/leash_topic_timing_issues.htm0000644000704600001450000000177513211554426026314 0ustar ghudsonlibuuid Kerberos Timing Issues

      Kerberos Timing Issues

      To resynchronize your computer's clock to the network's clock, manually set it, or run the leash Synchronize Time Command.  If you are using Windows XP or Windows 2003, the Date and Time Control Panel contains an Internet Time page which can be used to automatically synchronize the clock on a regular basis.

      Why Do It...

      Kerberos authentication uses time stamps as part of its protocol. When the clocks of the Kerberos server and your computer are too far out of synchronization, you cannot authenticate properly.

      krb5-1.16/src/windows/leash/htmlhelp/html/Forget_Password.htm0000644000704600001450000000132213211554426024154 0ustar ghudsonlibuuid Forget Password

      Forgotten Password

      If you forget your password, contact your administrator or help desk.

      Usually you will be given a new, temporary password. If so, open MIT Kerberos and use the temporary password to change your password to a new one that only you know.

      Related help

      krb5-1.16/src/windows/leash/htmlhelp/html/leash_topic_error_62.htm0000644000704600001450000000147413211554426025066 0ustar ghudsonlibuuid Kerberos Error 62

      Kerberos Error 62: Password incorrect.

      This means that either you have misspelled your password or you have gotten the case wrong. Check the state of your CAPS Lock key.

      Characters do not echo to the screen or cause a beep when you type your password so that nearby users won't be able to tell how many letters are in your password.

      krb5-1.16/src/windows/leash/htmlhelp/html/Renew_Tickets2.html0000644000704600001450000001120313211554426024047 0ustar ghudsonlibuuid Renew Tickets
      • Upper Case Realm Name: Turn this option on to convert the realm name you enter in the Initialize Ticket window to all upper case regardless of how you type it. A realm is the area authenticated by a unique Kerberos installation. By convention, the realm is named after the DNS domain it corrosponds to, but uses all upper case letters. Since realm names are case sensitive it is important to use all caps when entering the realm name.
      • Automatic Ticket Renewal: Turn this on to have MIT Kerberos automatically renew your Kerberos tickets for their entire renewable lifetime, without promptings or requiring a password. Please note that automatic ticket renewal will not work if you exit MIT Kerberos.
      • Expiration Alarm: Turn this on and MIT Kerberos will provide an audible alarm 15, 10, and 5 minutes before your tickets expire. Regardless of whether this option is on, MIT Kerberos will provide a visual pop up window alerting you to expiring tickets at the same intervals.
      • Destroy Tickets on Exit: Turn this on and MIT Kerberos will destroy your tickets when you exit MIT Kerberos. If this option is turned off, your tickets are unaffected when you exit MIT Kerberos.
      OptionTurn this on to...Details
      Upper Case Realm NameAutomatically convert the realm name you enter in the Initialize Ticket window to all upper case regardless of how you type it. realm is the area authenticated by a unique Kerberos installation. By convention, the realm is named after the DNS domain it corrosponds to, but uses all upper case letters. Since realm names are case sensitive it is important to use all caps when entering the realm name.
      Automatic Ticket RenewalAutomatically renew your Kerberos tickets for their entire renewable lifetime, without promptings or requiring a password.Renewing your tickets allows you to run batch jobs without interruption and to work through a long session without continually reentering your password. Please note that automatic ticket renewal will not work if you exit MIT Kerberos or if your current  tickets are not renewable.
      Expiration AlarmHave MIT Kerberos  provide an audible alarm 15, 10, and 5 minutes before your tickets expire.Regardless of whether this option is on, MIT Kerberos will provide a visual pop up window alerting you to expiring tickets at the same intervals, but the pop up window will not always be visible on a busy desktop.
      Destroy Tickets on ExitHave MIT Kerberos destroy your tickets when you exit MIT Kerberos.  If this option is turned off, your tickets are unaffected when you exit MIT Kerberos. For highest security you should always destroy your tickets when you are finished using them, and this makes it more automatic.

      krb5-1.16/src/windows/leash/htmlhelp/html/Forget_Principals.htm0000644000704600001450000000344413211554426024465 0ustar ghudsonlibuuid Clear Principal History

      Clear Principal History

      Kerberos saves your principals for you if you select "Remember this principal" in the Get Ticket window. Saved principals then auto-complete when you start to type them in the Get Ticket and Change Password windows.

      If you have saved a principal that you will no longer use, and you do not want that principal to auto-complete, clear your principal history.

      Note: When you clear your principal history, MIT Kerberos clears all of your saved principals. It is not possible to remove some principals while keeping others.

      Clear Principal History

      1. Click the Get Ticket button.
      2. If the advanced options are hidden, click Show Advanced.
      3. Find the Clear History button to the right of the Principal field and click it.
      4. Click Cancel to return to the main window.

      Related help

      krb5-1.16/src/windows/leash/htmlhelp/html/leash_topic_error_57.htm0000644000704600001450000000212113211554426025060 0ustar ghudsonlibuuid Kerberos Error 57

      Kerberos Error 57: Cannot contact the Kerberos server for the selected realm.

      This error has three common causes:

      1.The realm is misspelled, e.g. pbh@AHTENA.MIT.EDU instead of pbh@ATHENA.MIT.EDU (realms are case sensitive).

      2.Your krb.con file contains an entry for ATHENA.MIT.EDU but not athena.mit.edu.

      3.The realm is missing from your KRB.CON file, which should be located in your \net\kerb directory. If you suspect the problem is with your KRB.CON file, either call the Network Help Desk, 3-4101, or copy the /etc/krb.conf file from a nearby UNIX workstation to your \net\kerb\krb.con file.

      krb5-1.16/src/windows/leash/htmlhelp/html/leash_manpage_ms2mit.htm0000644000704600001450000000137713211554426025135 0ustar ghudsonlibuuid MS2MIT Command

      MS2MIT Command

      NAME
      ms2mit - import Kerberos credentials from the current Windows Logon
      Session and insert them into the Kerberos for Windows
      default Credentials Cache

      SYNOPSIS
      ms2mit

      DESCRIPTION



      SEE ALSO
      klist(1), kdestroy(1), krb5(3)
      krb5-1.16/src/windows/leash/htmlhelp/html/leash_topic_leash_systray.htm0000644000704600001450000000476413211554426026325 0ustar ghudsonlibuuid Leash System Tray Tool

      Leash System Tray Tool

      While Leash is running one of the following icons will be displayed in the system tray based upon the current state of your Kerberos tickets.  Clicking on the icon with the first mouse button will open or close the Leash display window.  Clicking with the second mouse button will display a menu of commands.

      System Tray Icons

      • Green:     tickets are valid and have a lifetime of greater than 20 minutes
      • Grey:       no tickets are present
      • Orange:  tickets are valid and about to expire
      • Red:        tickets have expired

      System Tray Menu

      System Tray Menu


      krb5-1.16/src/windows/leash/htmlhelp/html/leash_menu_help_why_use.htm0000644000704600001450000000102113211554426025733 0ustar ghudsonlibuuid Why Use

      Why Use Leash

      This command, found under the Help menu, starts Leash help (the document you are currently viewing).

      krb5-1.16/src/windows/leash/htmlhelp/html/leash_command_change_password.htm0000644000704600001450000000207613211554426027074 0ustar ghudsonlibuuid Change Password Command

      Change Password Command

      The Change Password command is found on the Action menu; it is also the fifth button (from the left) in the toolbar.  This command changes your Kerberos password.

      Change Password Dialog

      Note: This command will not change your local machine password unless your Windows Logon Session is authenticated using Kerberos.

      How To Choose a Password.

      krb5-1.16/src/windows/leash/htmlhelp/html/Export_Tickets.htm0000644000704600001450000000335313211554426024021 0ustar ghudsonlibuuid Export_Tickets

      Export Tickets

      You can export tickets into your Windows Logon session so they can be used with Windows services. This is useful when you want to you use a computer that is not part of a Kerberos realm (or Windows domain) to access that realm (or domain).

      Note: Exporting tickets will destroy any tickets you already have for your Windows Logon session. If you have unexpired tickets when you run the Export Ticket command, MIT Kerberos will warn you and give you the option to cancel the command.

      To export tickets you have already obtained with the Get Ticket window into your Windows Logon session:

      1. Click the Export Ticket button in the Home tab.
      2. Click Okay to confirm that you want to export the tickets and destroy any you already have for your Windows Logon session.

      Related help

      krb5-1.16/src/windows/leash/htmlhelp/html/Get_Tickets.htm0000644000704600001450000000557013211554426023262 0ustar ghudsonlibuuid Get Tickets

      Get Tickets

      Before you can access services that use Kerberos for authentication, you must obtain a Kerberos ticket. If your company uses RSA SecurID to control access to Kerberos, you will be prompted to enter your SecurID password after you request a ticket.

      To get a ticket:

      1. Click the Get Ticket button in the Home tab or use the keyboard shortcut [Ctrl + t].
      2. Your principal is your user name combined with the Kerberos realm you are part of. For example, jdoe@SALES.WIDGET.COM. Enter your principal. Principals you have previously entered and saved will auto-complete.
      3. Enter your password.
      4. To save this principal so Kerberos will auto-complete it for you in the future, select the "Remember this principal" checkbox. If you have multiple principals, Kerberos can remember all of them.
      5. To verify or change ticket settings, click Show Advanced at the bottom of the window and then make any necessary changes.
        • To change the ticket lifetime, click and drag the Ticket Lifetime slider.
        • To get a forwardable ticket, select the Forwardable and Proxiable checkbox.
        • To get a renewable ticket, select the Renewable checkbox.
        About: Ticket Settings and Flags
      6. Click Okay.

        If your company uses RSA SecurID, a popup window will open requiring you to enter your SecurID password. Enter that password (your PIN plus the code currently displayed on your RSA SecurID token) and click Okay.

      Your new ticket is listed in the main window.

      Related Help

      krb5-1.16/src/windows/leash/htmlhelp/html/Import_Status.htm0000644000704600001450000000574613211554426023677 0ustar ghudsonlibuuid Import Status

      Import Status

      The Import Status column in the main window shows whether tickets were obtained with the Get Ticket function in MIT Kerberos or if they were obtained by a Windows Logon session when you logged on to a domain, and whether they have been imported or exported to the other application.

      To show or hide this column, open the Options tab and use the Import Status checkbox in the View Options panel. Note that Import Status is only available if you have obtained tickets through a Windows Logon session.
      How to: Use View Options Panel

      Import Status Meaning
      imported The tickets were obtained when you started a Windows Logon session by logging in to a domain. They have been imported into MIT Kerberos.
      importable The tickets were obtained when you started a Windows Logon session by logging in to a domain.

      They have not been imported into MIT Kerberos because Automatic Import has been turned off. To import them, select Automatic Import in the Ticket Options panel of the Options tab, or click the Import button in the Home tab.
      How to: Use Ticket Options Panel
      How to: Import Tickets
      protected The tickets were obtained when you started a Windows Logon session by logging in to a domain.

      They have not been imported into Windows for Kerberos because User Access Control (UAC) in Windows is preventing that action. If you want to allow the tickets to be imported, turn off your computer's UAC.
      exportable You used the Get Ticket window to obtain these tickets.

      They have not been exported.

      To export these tickets for use with Windows services, click the Export Ticket button. Note that exporting your tickets replaces rather than adds to any existing tickets in your Windows Logon session.
      exported You used the Get Ticket window to obtain these tickets.

      They have been exported into your Windows Logon session and can be used with Windows services.

      Related Help

      krb5-1.16/src/windows/leash/htmlhelp/html/hid_sc_move.htm0000644000704600001450000000075113211554426023330 0ustar ghudsonlibuuid (Move command (Control menu))

      Move command (Control menu)

      Use this command to display a four-headed arrow so you can move the active window or dialog box with the arrow keys.

      Note: This command is unavailable if you maximize the window.

      krb5-1.16/src/windows/leash/htmlhelp/html/leash_option_kerberos_properties.htm0000644000704600001450000001413413211554426027705 0ustar ghudsonlibuuid Kerberos Properties Command

      Kerberos Properties Command, Ctrl+K

      When you select this from the Options menu, Leash will display a tabbed window. The box within this window has four tabs:

      • Default Realm Configuration
      • Ticket Lifetime and Other Initialization Options
      • Realm/Server Mapping
      • DNS/Realm Mapping.

      Default Realm Configuration:
      Default Realm Configuration

      There are two groups, the Kerberos Realm/Host Server and the Computer Host/Domain Name.

      Kerberos Realm/Host Server: In the Your Kerberos Realm field, select a Kerberos realm from the dropdown list. The list is editable using the Realm/Server Mapping tab. Leash automatically fills in your Kerberos server with the first server in the "Servers Hosting a KDC" list on the Realm/Server Mappings tab.

      Computer Host/Domain Name: The field labeled Your Computer's Host Name displays the name of your local machine.  The Your Computer's Domain Name field displays the domain to which your local machine currently belongs.

      Ticket Lifetime and Other Initialization Options:
      Ticket Lifetime

      <>There are two expiration times associated with Kerberos tickets.  The first specifies the length of the time period during which the tickets are valid for use.  The second specifies the length of the renewable lifetime.  Valid Kerberos tickets may have their valid use lifetime repeatedly extended up until the renewable lifetime expires.  The settings on this page are used to configure default lifetime values for Leash to use when requesting Kerberos tickets from the Kerberos server (key distribution center).  The Kerberos server may issue tickets with shorter lifetimes than were requested.

      The minimum and maximum values are used by the ticket initialization dialog box when constructing the Lifetime and Renewable Lifetime sliders.  These sliders can be used to modify the requested ticket lifetimes when Kerberos tickets are initialized.

      When the Request Kerberos 4 credentials button is checked, Leash will attempt to retrieve Kerberos 4 credentials when ticket initialization, renewal, or importation is performed.  Leash will attempt a Kerberos 5 to Kerberos 4 conversion and if that fails an initial Kerberos 4 ticket request will be generated.  Kerberos realms are increasingly configured to support on Kerberos 5.  If the realms you use do not support Kerberos 4 it is suggested that this button be unchecked. <> 

      When the Preserve Ticket Initialization Options button is checked, changes to the Lifetime, Renewable Lifetime, and Kerberos 5 ticket properties on the Ticket Initialization Dialog will be saved as the new default values for the current user.

      Realm/Server Mapping:
      Realm / Server Mapping

      The Kerberos Realms list box is used to add, remove or rename realms from the local Kerberos configuration files. To add a new realm, click on the Insert button beneath the Kerberos Realms list box.  In the dialog, type the name of the new realm and click OK.  However, for the realm to be inserted, it needs one or more servers.  Immediately after you enter the new realm name, you will be prompted for the names of one Kerberos server in that realm.  If you do not enter a server name, Leash will not insert the realm.

      To add servers to an existing realm, select the realm from the Kerberos Realms list box and click the Insert button under Servers Hosting a KDC list box.  You will be prompted for the name of the new server.  You can also remove servers, and designate either one or none as the administrative server.  (The administrative server is the preferred server for performing password changes.)  

      By clicking and dragging on the server that you want to move, you can change their order; this is important because the server listed at the top appears in this window under the Default Realm Configuration tab as the value for Your Kerberos Server.

      The Use DNS KDC Lookup checkbox is used to specify whether or not Kerberos should utilize the domain name service to attempt to find Kerberos Servers when the existing listed servers are not available.

      DNS/Realm Mapping:
      DNS / Realm Mapping

      Each entry here consists of two portions: the domain name (such as .mit.edu) or hostname (such as dialup.athena.mit.edu) followed by a space and the Kerberos realm (such as ATHENA.MIT.EDU) which is used by that domain or machine.  You can insert new entries, edit existing ones, or delete old entries.

      krb5-1.16/src/windows/leash/htmlhelp/html/Distroy_Tickets.htm0000644000704600001450000000033513211554426024172 0ustar ghudsonlibuuid Destroy_Tickets

      Distroy Tickets

      krb5-1.16/src/windows/leash/htmlhelp/Index.hhk0000644000704600001450000003710513211554426021141 0ustar ghudsonlibuuid
      krb5-1.16/src/windows/leash/htmlhelp/Makefile.in0000644000704600001450000000055313211554426021440 0ustar ghudsonlibuuidBUILDTOP=..\..\.. TARGETTYPE=NONE HHCOUT=MITKerberosHelp.chm TARGET=..\$(OUTPRE)"MIT Kerberos.chm" HHP=MITKerberosHelp.hhp ERR=leash.log all: $(HHCOUT) clean: @if exist $(HHCOUT) del $(HHCOUT) @if exist $(TARGET) del $(TARGET) @if exist $(ERR) del $(ERR) $(HHCOUT): $(HHP) - hhc $(HHP) @if exist $(TARGET) del $(TARGET) @copy $(HHCOUT) $(TARGET) krb5-1.16/src/windows/leash/Krb4RealmHostMaintenance.h0000644000704600001450000000477113211554426022521 0ustar ghudsonlibuuid// ************************************************************************************** // File: Krb4RealmHostMaintenance.h // By: Arthur David Leather // Created: 12/02/98 // Copyright @1998 Massachusetts Institute of Technology - All rights reserved. // Description: H file for Krb4RealmHostMaintenance.cpp. Contains variables and functions // for Kerberos Four Properties // // History: // // MM/DD/YY Inits Description of Change // 12/02/98 ADL Original // ************************************************************************************** #if !defined(AFX_REAMLHOSTMAINT_H__2FE711C3_8E9A_11D2_94C5_0000861B8A3C__INCLUDED_) #define AFX_REAMLHOSTMAINT_H__2FE711C3_8E9A_11D2_94C5_0000861B8A3C__INCLUDED_ #if _MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000 // RemoveHostNameList.h : header file // ///////////////////////////////////////////////////////////////////////////// // CKrb4RealmHostMaintenance dialog #define MAXLINE 256 class CKrb4RealmHostMaintenance : public CPropertyPage { // Construction private: DECLARE_DYNCREATE(CKrb4RealmHostMaintenance) CHAR lineBuf[MAXLINE]; INT m_defectiveLines; BOOL m_initDnsKdcLookup; BOOL m_newDnsKdcLookup; void ResetDefaultRealmComboBox(); public: //CKrb4RealmHostMaintenance(CWnd* pParent = NULL); // standard constructor CKrb4RealmHostMaintenance(); virtual ~CKrb4RealmHostMaintenance(); // Dialog Data //{{AFX_DATA(CKrb4RealmHostMaintenance) enum { IDD = IDD_KRB4_REALMHOST_MAINT2 }; CDragListBox m_RealmHostList; //}}AFX_DATA // Overrides // ClassWizard generated virtual function overrides //{{AFX_VIRTUAL(CKrb4RealmHostMaintenance) public: virtual BOOL PreTranslateMessage(MSG* pMsg); protected: virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support //}}AFX_VIRTUAL // Implementation protected: // Generated message map functions //{{AFX_MSG(CKrb4RealmHostMaintenance) virtual BOOL OnInitDialog(); virtual BOOL OnApply(); virtual void OnOK(); virtual void OnCancel(); afx_msg void OnButtonRealmHostAdd(); afx_msg void OnButtonRealmHostEdit(); afx_msg void OnButtonRealmHostRemove(); afx_msg void OnSelchangeListRemoveHost(); afx_msg void OnDblclkListRemoveHost(); afx_msg void OnButtonRealmhostMaintHelp2(); afx_msg void OnCheckDnsKdcLookup(); //}}AFX_MSG DECLARE_MESSAGE_MAP() }; //{{AFX_INSERT_LOCATION}} // Microsoft Visual C++ will insert additional declarations immediately before the previous line. #endif // !defined(AFX_REAMLHOSTMAINT_H__2FE711C3_8E9A_11D2_94C5_0000861B8A3C__INCLUDED_) krb5-1.16/src/windows/leash/KrbListTickets.cpp0000644000704600001450000002435413211554426021170 0ustar ghudsonlibuuid#include "stdafx.h" #include "lglobals.h" #include "krb5.h" static void FreeTicketList(TicketList** ticketList) { TicketList* tempList = *ticketList, *killList; while (tempList) { killList = tempList; tempList = tempList->next; free(killList->service); if (killList->encTypes) free(killList->encTypes); free(killList); } *ticketList = NULL; } void LeashKRB5FreeTicketInfo(TICKETINFO *ticketinfo) { if (ticketinfo->principal) { free(ticketinfo->principal); ticketinfo->principal = NULL; } if (ticketinfo->ccache_name) { pkrb5_free_string(NULL, ticketinfo->ccache_name); ticketinfo->ccache_name = NULL; } if (ticketinfo->ticket_list) FreeTicketList(&ticketinfo->ticket_list); } void LeashKRB5FreeTickets(TICKETINFO **ticketinfolist) { TICKETINFO *ticketinfo = *ticketinfolist, *next; while (ticketinfo) { next = ticketinfo->next; LeashKRB5FreeTicketInfo(ticketinfo); free(ticketinfo); ticketinfo = next; } *ticketinfolist = NULL; } /* * LeashKRB5Error() */ int LeashKRB5Error(krb5_error_code rc, LPCSTR FailedFunctionName) { #ifdef USE_MESSAGE_BOX char message[256]; const char *errText; errText = perror_message(rc); _snprintf(message, sizeof(message), "%s\n(Kerberos error %ld)\n\n%s failed", errText, rc, FailedFunctionName); message[sizeof(message)-1] = 0; MessageBox(NULL, message, "Kerberos Five", MB_OK | MB_ICONERROR | MB_TASKMODAL | MB_SETFOREGROUND); #endif /* USE_MESSAGE_BOX */ return rc; } static char * etype_string(krb5_enctype enctype) { static char buf[100]; krb5_error_code retval; if ((retval = pkrb5_enctype_to_name(enctype, FALSE, buf, sizeof(buf)))) { /* XXX if there's an error != EINVAL, I should probably report it */ sprintf_s(buf, "etype %d", enctype); } return buf; } static void CredToTicketInfo(krb5_creds KRBv5Credentials, TICKETINFO *ticketinfo) { ticketinfo->issued = (DWORD)KRBv5Credentials.times.starttime; ticketinfo->valid_until = (DWORD)KRBv5Credentials.times.endtime; ticketinfo->renew_until = KRBv5Credentials.ticket_flags & TKT_FLG_RENEWABLE ? (DWORD)KRBv5Credentials.times.renew_till : (DWORD)0; _tzset(); if ( ticketinfo->valid_until - time(0) <= 0L ) ticketinfo->btickets = EXPD_TICKETS; else ticketinfo->btickets = GOOD_TICKETS; } static int CredToTicketList(krb5_context ctx, krb5_creds KRBv5Credentials, char *PrincipalName, TicketList ***ticketListTail) { krb5_error_code code = 0; krb5_ticket *tkt=NULL; char *sServerName = NULL; char Buffer[256]; char *functionName = NULL; TicketList *list = NULL; functionName = "krb5_unparse_name()"; code = (*pkrb5_unparse_name)(ctx, KRBv5Credentials.server, &sServerName); if (code) goto cleanup; if (!KRBv5Credentials.times.starttime) KRBv5Credentials.times.starttime = KRBv5Credentials.times.authtime; memset(Buffer, '\0', sizeof(Buffer)); // @fixme: calloc for ptr init list = (TicketList *)calloc(1, sizeof(TicketList)); if (!list) { code = ENOMEM; functionName = "calloc()"; goto cleanup; } list->service = strdup(sServerName); if (!list->service) { code = ENOMEM; functionName = "calloc()"; goto cleanup; } list->issued = (DWORD)KRBv5Credentials.times.starttime; list->valid_until = (DWORD)KRBv5Credentials.times.endtime; if (KRBv5Credentials.ticket_flags & TKT_FLG_RENEWABLE) list->renew_until = (DWORD)KRBv5Credentials.times.renew_till; else list->renew_until = 0; if (!pkrb5_decode_ticket(&KRBv5Credentials.ticket, &tkt)) { wsprintf(Buffer, "Session Key: %s Ticket: %s", etype_string(KRBv5Credentials.keyblock.enctype), etype_string(tkt->enc_part.enctype)); pkrb5_free_ticket(ctx, tkt); tkt = NULL; } else { wsprintf(Buffer, "Session Key: %s", etype_string(KRBv5Credentials.keyblock.enctype)); } list->encTypes = (char *)calloc(1, strlen(Buffer)+1); if (!list->encTypes) { functionName = "calloc()"; code = ENOMEM; goto cleanup; } strcpy(list->encTypes, Buffer); list->flags = KRBv5Credentials.ticket_flags; cleanup: if (code) { LeashKRB5Error(code, functionName); if (list) FreeTicketList(&list); } else { **ticketListTail = list; *ticketListTail = &list->next; } if (sServerName != NULL) (*pkrb5_free_unparsed_name)(ctx, sServerName); return code; } // return 0 if ticketinfo was successfully appended to list, 1 otherwise int do_ccache(krb5_context ctx, krb5_ccache cache, TICKETINFO **ticketInfoTail) { krb5_cc_cursor cur; krb5_creds creds; krb5_principal princ = NULL; krb5_flags flags; krb5_error_code code; char *defname = NULL; char *functionName = NULL; TicketList **ticketListTail; TICKETINFO *ticketinfo = NULL; int retval = 1; // Don't need the actual ticket. flags = KRB5_TC_NOTICKET; code = pkrb5_cc_set_flags(ctx, cache, flags); if (code) { if (code == KRB5_FCC_NOFILE || code == KRB5_CC_NOTFOUND) { // Normal behavior; skip cache but suppress error message box code = 0; } else { functionName = "krb5_cc_set_flags"; } goto cleanup; } code = pkrb5_cc_get_principal(ctx, cache, &princ); if (code) { // Normal behavior; skip cache but suppress error message box code = 0; goto cleanup; } code = pkrb5_unparse_name(ctx, princ, &defname); if (code) { functionName = "krb5_unparse_name"; goto cleanup; } code = pkrb5_cc_start_seq_get(ctx, cache, &cur); if (code) { functionName = "krb5_cc_start_seq_get"; goto cleanup; } if (*ticketInfoTail) ticketinfo = *ticketInfoTail; else // @fixme: calloc to init pointers ticketinfo = (TICKETINFO *)calloc(1, sizeof(TICKETINFO)); if (ticketinfo == NULL) { functionName = "calloc"; code = ENOMEM; goto cleanup; } ticketinfo->next = NULL; ticketinfo->ticket_list = NULL; ticketinfo->principal = strdup(defname); if (ticketinfo->principal == NULL) { functionName = "strdup"; code = ENOMEM; goto cleanup; } code = pkrb5_cc_get_full_name(ctx, cache, &ticketinfo->ccache_name); if (code) { functionName = "krb5_cc_get_full_name"; goto cleanup; } *ticketInfoTail = ticketinfo; ticketListTail = &ticketinfo->ticket_list; while (!(code = pkrb5_cc_next_cred(ctx, cache, &cur, &creds))) { if (!pkrb5_is_config_principal(ctx, creds.server)) { CredToTicketList(ctx, creds, defname, &ticketListTail); CredToTicketInfo(creds, ticketinfo); } pkrb5_free_cred_contents(ctx, &creds); } if (code == KRB5_CC_END) { code = pkrb5_cc_end_seq_get(ctx, cache, &cur); if (code) { functionName = "krb5_cc_end_seq_get"; goto cleanup; } flags = 0; code = pkrb5_cc_set_flags(ctx, cache, flags); if (code) { functionName = "krb5_cc_set_flags"; goto cleanup; } } else { functionName = "krb5_cc_next_cred"; goto cleanup; } cleanup: if (code) LeashKRB5Error(code, functionName); if (ticketinfo) { if (ticketinfo == *ticketInfoTail) retval = 0; else LeashKRB5FreeTickets(&ticketinfo); } if (defname) pkrb5_free_unparsed_name(ctx, defname); if (princ) pkrb5_free_principal(ctx, princ); return retval; } // // Returns 0 for success, 1 for failure // int do_all_ccaches(krb5_context ctx, TICKETINFO **ticketinfotail) { krb5_error_code code; krb5_ccache cache; krb5_cccol_cursor cursor; int retval = 1; char *functionName = NULL; code = pkrb5_cccol_cursor_new(ctx, &cursor); if (code) { functionName = "krb5_cccol_cursor_new"; goto cleanup; } retval = 0; while (!(code = pkrb5_cccol_cursor_next(ctx, cursor, &cache)) && cache != NULL) { // Note that ticketinfotail will be updated here to point to the tail // of the list but the caller of this function will remain with a // pointer to the head. if (do_ccache(ctx, cache, ticketinfotail) == 0) ticketinfotail = &((*ticketinfotail)->next); pkrb5_cc_close(ctx, cache); } if (code) functionName = "krb5_cccol_cursor_next"; pkrb5_cccol_cursor_free(ctx, &cursor); cleanup: if (code) LeashKRB5Error(code, functionName); return retval; } void LeashKRB5ListDefaultTickets(TICKETINFO *ticketinfo) { krb5_error_code code; krb5_context ctx = 0; krb5_ccache cache = 0; char *functionName = NULL; ticketinfo->btickets = NO_TICKETS; ticketinfo->principal = NULL; ticketinfo->ccache_name = NULL; ticketinfo->next = NULL; ticketinfo->ticket_list = NULL; ticketinfo->renew_until = 0; ticketinfo->valid_until = 0; ticketinfo->issued = 0; code = pkrb5_init_context(&ctx); if (code) { functionName = "krb5_init_context"; goto cleanup; } code = pkrb5_cc_default(ctx, &cache); if (code) { functionName = "krb5_cc_default"; goto cleanup; } if (cache != NULL) do_ccache(ctx, cache, &ticketinfo); cleanup: if (code) LeashKRB5Error(code, functionName); if (cache) pkrb5_cc_close(ctx, cache); if (ctx) pkrb5_free_context(ctx); } /* * LeashKRB5ListAllTickets() */ void LeashKRB5ListAllTickets(TICKETINFO **ticketinfo) { krb5_error_code code; krb5_context ctx = 0; char *functionName = NULL; code = pkrb5_init_context(&ctx); if (code) { functionName = "krb5_init_context"; goto cleanup; } do_all_ccaches(ctx, ticketinfo); cleanup: if (code) LeashKRB5Error(code, functionName); if (ctx) pkrb5_free_context(ctx); } krb5-1.16/src/windows/leash/kfwribbon.xml0000644000704600001450000001231113211554426020256 0ustar ghudsonlibuuid res/getticketlarge.bmp res/renewlarge.bmp res/destroylarge.bmp res/makedefaultlarge.bmp res/cpwlarge.bmp