diff -ruN openssh-3.9p1+x509h/aclocal.m4 openssh-3.9p1+x509-5.1/aclocal.m4 --- openssh-3.9p1+x509h/aclocal.m4 2001-10-22 03:53:59.000000000 +0300 +++ openssh-3.9p1+x509-5.1/aclocal.m4 2004-11-19 09:06:00.000000000 +0200 @@ -1,4 +1,4 @@ -dnl $Id: aclocal.m4,v 1.5 2001/10/22 00:53:59 tim Exp $ +dnl $Id$ dnl dnl OpenSSH-specific autoconf macros dnl @@ -84,3 +84,192 @@ #include ]) ]) + +# Options to build with LDAP +# +# Author: Roumen Petrov +# Revision: 29 Oct 2004 +# + +AC_DEFUN(AC_WITH_LDAP, +[ +dnl +dnl Get the ldap paths +dnl + +ac_ldap='none' +AC_ARG_ENABLE(ldap, + [ --enable-ldap Enable LDAP queries], + ac_ldap="$enableval" +) + +if test "x$ac_ldap" = xyes; then + ac_ldap_prefix="" + AC_ARG_WITH(ldap-prefix, + [ --with-ldap-prefix=PATH Prefix where LDAP is installed (optional)], + ac_ldap_prefix="$withval" + ) + + AC_ARG_WITH(ldap-bindir, + [ --with-ldap-bindir=PATH Prefix where LDAP user executables are installed (optional)], + [LDAP_BINDIR="$withval"], + [ + if test "x$ac_ldap_prefix" != "x"; then + LDAP_BINDIR="$ac_ldap_prefix/bin" + fi + ] + ) + AC_SUBST(LDAP_BINDIR) + + AC_ARG_WITH(ldap-libexecdir, + [ --with-ldap-libexecdir=PATH Prefix where LDAP program executables are installed (optional)], + [LDAP_LIBEXECDIR="$withval"], + [ + if test "x$ac_ldap_prefix" = "x"; then + LDAP_LIBEXECDIR="/usr/libexec" + else + LDAP_LIBEXECDIR="$ac_ldap_prefix/libexec" + fi + ] + ) + AC_SUBST(LDAP_LIBEXECDIR) +dnl### Check for slapd +dnl if test "x$cross_compiling" = "xyes" ; then +dnl AC_MSG_NOTICE([cannot check for LDAP daemon when cross compiling]) +dnl else +dnl AC_CHECK_FILES( +dnl [ +dnl $LDAP_LIBEXECDIR/slapd +dnl ] +dnl ) +dnl fi + + AC_ARG_WITH(ldap-sysconfdir, + [ --with-ldap-sysconfdir=PATH Prefix where LDAP single-machine data are installed (optional)], + [LDAP_SYSCONFDIR="$withval"], + [LDAP_SYSCONFDIR="$ac_ldap_prefix/etc/openldap"] + ) + AC_SUBST(LDAP_SYSCONFDIR) +dnl### Check for schema files +dnl if test "x$cross_compiling" = "xyes" ; then +dnl AC_MSG_NOTICE([cannot check for schema files existence when cross compiling]) +dnl else +dnl AC_CHECK_FILES( +dnl [ +dnl $LDAP_SYSCONFDIR/schema/core.schema +dnl $LDAP_SYSCONFDIR/schema/cosine.schema +dnl $LDAP_SYSCONFDIR/schema/inetorgperson.schema- +dnl ] +dnl ) +dnl fi + + + AC_ARG_WITH(ldap-libdir, + [ --with-ldap-libdir=PATH Prefix where LDAP libaries are installed (optional)], + [LDAP_LDFLAGS="-L$withval"], + [ + if test "x$ac_ldap_prefix" != "x"; then + LDAP_LDFLAGS="-L$ac_ldap_prefix/lib" + else + LDAP_LDFLAGS="" + fi + ] + ) + AC_SUBST(LDAP_LDFLAGS) + + AC_ARG_WITH(ldap-includedir, + [ --with-ldap-includedir=PATH Prefix where LDAP header files are installed (optional)], + [LDAP_CPPFLAGS="-I$withval"], + [ + if test "x$ac_ldap_prefix" != "x"; then + LDAP_CPPFLAGS="-I$ac_ldap_prefix/include" + else + LDAP_CPPFLAGS="" + fi + ] + ) + AC_SUBST(LDAP_CPPFLAGS) + + + ac_save_CPPFLAGS="$CPPFLAGS" + CPPFLAGS="$CPPFLAGS $LDAP_CPPFLAGS" + AC_CHECK_HEADERS( + [lber.h ldap.h], + [], + [ + AC_MSG_ERROR([cannot found LDAP headers]) + ] + ) + CPPFLAGS="$ac_save_CPPFLAGS" + + ac_ldap_libs="" + AC_ARG_WITH(ldap-libs, + [ --with-ldap-libs=LIBS Specify LDAP libraries to link with. + (defult is -lldap -llber -lssl -lcrypto)], + [ac_ldap_libs="$withval"] + ) + +### Try to link with LDAP libs + ac_save_LDFLAGS="$LDFLAGS" + ac_save_LIBS="$LIBS" + + LDFLAGS="$LDAP_LDFLAGS $LDFLAGS" + ac_LDAP_LINK="" + if test "x$ac_ldap_libs" != "x"; then + AC_MSG_CHECKING([to link with specified LDAP libs]) + + LDAP_LIBS="$ac_ldap_libs" + LIBS="$LDAP_LIBS $ac_save_LIBS" + AC_LINK_IFELSE( + [AC_LANG_CALL([], [ldap_init])], + [ac_LDAP_LINK="yes"] + ) + if test "x$ac_LDAP_LINK" != "xyes"; then + AC_MSG_ERROR([cannot link with specified LDAP libs]) + fi + else + AC_MSG_CHECKING([how to link LDAP libs]) + + LDAP_LIBS="-lldap" + for L in lber ssl crypto; do + LDAP_LIBS="$LDAP_LIBS -l$L" + LIBS="$LDAP_LIBS $ac_save_LIBS" + AC_LINK_IFELSE( + [AC_LANG_CALL([], [ldap_init])], + [ac_LDAP_LINK="yes"] + ) + if test "x$ac_LDAP_LINK" = "xyes"; then + break + fi + done + if test "x$ac_LDAP_LINK" != "xyes"; then + AC_MSG_ERROR([cannot link with default LDAP libs]) + fi + fi + AC_MSG_RESULT([done]) + unset ac_LDAP_LINK + LIBS="$ac_save_LIBS" + LDFLAGS="$ac_save_LDFLAGS" + AC_SUBST([LDAP_LIBS]) + + unset ac_ldap_libs + unset ac_ldap_prefix +else + AC_MSG_NOTICE([LDAP is disabled]) +fi + +if test "x$ac_ldap" = "xyes"; then + AC_DEFINE_UNQUOTED( + LDAP_ENABLED, 1, + [Define if you want to enable LDAP queries]) + LDAP_ON='' + LDAP_OFF='#' +else + LDAP_ON='#' + LDAP_OFF='' +fi +AC_SUBST(LDAP_ON) +AC_SUBST(LDAP_OFF) + +unset ac_ldap +]) diff -ruN openssh-3.9p1+x509h/auth2-hostbased.c openssh-3.9p1+x509-5.1/auth2-hostbased.c --- openssh-3.9p1+x509h/auth2-hostbased.c 2004-01-21 02:02:50.000000000 +0200 +++ openssh-3.9p1+x509-5.1/auth2-hostbased.c 2004-11-19 09:06:01.000000000 +0200 @@ -23,7 +23,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: auth2-hostbased.c,v 1.6 2004/01/19 21:25:15 markus Exp $"); +RCSID("$OpenBSD$"); #include "ssh2.h" #include "xmalloc.h" @@ -44,6 +44,8 @@ extern u_char *session_id2; extern u_int session_id2_len; +static int hostbased_algorithm_allowed(int pktype); + static int userauth_hostbased(Authctxt *authctxt) { @@ -81,6 +83,11 @@ "public key algorithm: %s", pkalg); goto done; } + if (!hostbased_algorithm_allowed(pktype)) { + debug("userauth_hostbased: disallowed " + "public key algorithm: %s", pkalg); + goto done; + } key = key_from_blob(pkblob, blen); if (key == NULL) { error("userauth_hostbased: cannot decode key: %s", pkalg); @@ -127,6 +134,28 @@ return authenticated; } +/* return 1 if given hostbased algorithm is allowed */ +static int +hostbased_algorithm_allowed(int pktype) +{ + char *s, *cp, *p; + + if (options.hostbased_algorithms == NULL) return(1); + + s = cp = xstrdup(options.hostbased_algorithms); + for (p = strsep(&cp, ","); + p && *p != '\0'; + p = strsep(&cp, ",") + ) { + if (pktype == key_type_from_name(p)) { + xfree(s); + return(1); + } + } + xfree(s); + return(0); +} + /* return 1 if given hostkey is allowed */ int hostbased_key_allowed(struct passwd *pw, const char *cuser, char *chost, diff -ruN openssh-3.9p1+x509h/auth2-pubkey.c openssh-3.9p1+x509-5.1/auth2-pubkey.c --- openssh-3.9p1+x509h/auth2-pubkey.c 2004-08-18 09:06:01.000000000 +0300 +++ openssh-3.9p1+x509-5.1/auth2-pubkey.c 2004-11-19 09:06:01.000000000 +0200 @@ -49,6 +49,8 @@ extern u_char *session_id2; extern u_int session_id2_len; +static int pubkey_algorithm_allowed(int pktype); + static int userauth_pubkey(Authctxt *authctxt) { @@ -85,6 +87,11 @@ pkalg); goto done; } + if (!pubkey_algorithm_allowed(pktype)) { + debug("userauth_pubkey: disallowed public key algorithm: %s", + pkalg); + goto done; + } key = key_from_blob(pkblob, blen); if (key == NULL) { error("userauth_pubkey: cannot decode key: %s", pkalg); @@ -166,6 +173,28 @@ return authenticated; } +/* return 1 if given publickey algorithm is allowed */ +static int +pubkey_algorithm_allowed(int pktype) +{ + char *s, *cp, *p; + + if (options.pubkey_algorithms == NULL) return(1); + + s = cp = xstrdup(options.pubkey_algorithms); + for (p = strsep(&cp, ","); + p && *p != '\0'; + p = strsep(&cp, ",") + ) { + if (pktype == key_type_from_name(p)) { + xfree(s); + return(1); + } + } + xfree(s); + return(0); +} + /* return 1 if user allows given key */ static int user_key_allowed2(struct passwd *pw, Key *key, char *file) @@ -249,7 +278,7 @@ fp = key_fingerprint(key, SSH_FP_MD5, SSH_FP_HEX); verbose("Found matching %s key: %s", key_type(found), fp); - if ((key->type == KEY_X509_RSA) || + if ((key->type == KEY_X509_RSA) || (key->type == KEY_X509_DSA)) { if (ssh_x509cert_check(key->x509) != 1) { found_key = 0; diff -ruN openssh-3.9p1+x509h/config.h.in openssh-3.9p1+x509-5.1/config.h.in --- openssh-3.9p1+x509h/config.h.in 2004-08-18 09:06:01.000000000 +0300 +++ openssh-3.9p1+x509-5.1/config.h.in 2004-11-19 09:06:01.000000000 +0200 @@ -639,6 +639,12 @@ /* Define to 1 if you have the header file. */ #undef HAVE_LASTLOG_H +/* Define to 1 if you have the header file. */ +#undef HAVE_LBER_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_LDAP_H + /* Define to 1 if you have the `crypt' library (-lcrypt). */ #undef HAVE_LIBCRYPT @@ -1056,6 +1062,9 @@ /* Define to 1 if you have the `__b64_pton' function. */ #undef HAVE___B64_PTON +/* Define if you want to enable LDAP queries */ +#undef LDAP_ENABLED + /* Define to the address where bug reports for this package should be sent. */ #undef PACKAGE_BUGREPORT diff -ruN openssh-3.9p1+x509h/configure openssh-3.9p1+x509-5.1/configure --- openssh-3.9p1+x509h/configure 2004-08-18 09:06:02.000000000 +0300 +++ openssh-3.9p1+x509-5.1/configure 2004-11-19 09:06:02.000000000 +0200 @@ -309,7 +309,7 @@ # include #endif" -ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT build build_cpu build_vendor build_os host host_cpu host_vendor host_os AWK CPP RANLIB ac_ct_RANLIB INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA AR CAT KILL PERL SED ENT TEST_MINUS_S_SH SH TEST_SHELL PATH_GROUPADD_PROG PATH_USERADD_PROG MAKE_PACKAGE_SUPPORTED LOGIN_PROGRAM_FALLBACK PATH_PASSWD_PROG LD EGREP LIBWRAP LIBPAM INSTALL_SSH_RAND_HELPER SSH_PRIVSEP_USER PROG_LS PROG_NETSTAT PROG_ARP PROG_IFCONFIG PROG_JSTAT PROG_PS PROG_SAR PROG_W PROG_WHO PROG_LAST PROG_LASTLOG PROG_DF PROG_VMSTAT PROG_UPTIME PROG_IPCS PROG_TAIL INSTALL_SSH_PRNG_CMDS OPENSC_CONFIG PRIVSEP_PATH xauth_path STRIP_OPT XAUTH_PATH NROFF MANTYPE mansubdir user_path sshcadir OCSP_ON OCSP_OFF piddir LIBOBJS LTLIBOBJS' +ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT build build_cpu build_vendor build_os host host_cpu host_vendor host_os AWK CPP RANLIB ac_ct_RANLIB INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA AR CAT KILL PERL SED ENT TEST_MINUS_S_SH SH TEST_SHELL PATH_GROUPADD_PROG PATH_USERADD_PROG MAKE_PACKAGE_SUPPORTED LOGIN_PROGRAM_FALLBACK PATH_PASSWD_PROG LD EGREP LIBWRAP LIBPAM INSTALL_SSH_RAND_HELPER SSH_PRIVSEP_USER PROG_LS PROG_NETSTAT PROG_ARP PROG_IFCONFIG PROG_JSTAT PROG_PS PROG_SAR PROG_W PROG_WHO PROG_LAST PROG_LASTLOG PROG_DF PROG_VMSTAT PROG_UPTIME PROG_IPCS PROG_TAIL INSTALL_SSH_PRNG_CMDS OPENSC_CONFIG PRIVSEP_PATH xauth_path STRIP_OPT XAUTH_PATH NROFF MANTYPE mansubdir user_path sshcadir OCSP_ON OCSP_OFF LDAP_BINDIR LDAP_LIBEXECDIR LDAP_SYSCONFDIR LDAP_LDFLAGS LDAP_CPPFLAGS LDAP_LIBS LDAP_ON LDAP_OFF piddir LIBOBJS LTLIBOBJS' ac_subst_files='' # Initialize some variables set by options. @@ -849,6 +849,7 @@ --disable-etc-default-login Disable using PATH from /etc/default/login no --disable-x509store Disable X.509 store --enable-ocsp Enable OCSP validation + --enable-ldap Enable LDAP queries --disable-lastlog disable use of lastlog even if detected no --disable-utmp disable use of utmp even if detected no --disable-utmpx disable use of utmpx even if detected no @@ -894,6 +895,14 @@ --with-4in6 Check for and convert IPv4 in IPv6 mapped addresses --with-bsd-auth Enable BSD auth support --with-sshca-dir=PATH Specify location of ssh CA root + --with-ldap-prefix=PATH Prefix where LDAP is installed (optional) + --with-ldap-bindir=PATH Prefix where LDAP user executables are installed (optional) + --with-ldap-libexecdir=PATH Prefix where LDAP program executables are installed (optional) + --with-ldap-sysconfdir=PATH Prefix where LDAP single-machine data are installed (optional) + --with-ldap-libdir=PATH Prefix where LDAP libaries are installed (optional) + --with-ldap-includedir=PATH Prefix where LDAP header files are installed (optional) + --with-ldap-libs=LIBS Specify LDAP libraries to link with. + (defult is -lldap -llber -lssl -lcrypto) --with-pid-dir=PATH Specify location of ssh.pid file --with-lastlog=FILE|DIR specify lastlog location common locations @@ -23612,6 +23621,460 @@ +# enable LDAP queries +LDAP_MSG="no" +if test "x$ssh_x509store" = "xyes"; then + + +ac_ldap='none' +# Check whether --enable-ldap or --disable-ldap was given. +if test "${enable_ldap+set}" = set; then + enableval="$enable_ldap" + ac_ldap="$enableval" + +fi; + +if test "x$ac_ldap" = xyes; then + ac_ldap_prefix="" + +# Check whether --with-ldap-prefix or --without-ldap-prefix was given. +if test "${with_ldap_prefix+set}" = set; then + withval="$with_ldap_prefix" + ac_ldap_prefix="$withval" + +fi; + + +# Check whether --with-ldap-bindir or --without-ldap-bindir was given. +if test "${with_ldap_bindir+set}" = set; then + withval="$with_ldap_bindir" + LDAP_BINDIR="$withval" +else + + if test "x$ac_ldap_prefix" != "x"; then + LDAP_BINDIR="$ac_ldap_prefix/bin" + fi + + +fi; + + + +# Check whether --with-ldap-libexecdir or --without-ldap-libexecdir was given. +if test "${with_ldap_libexecdir+set}" = set; then + withval="$with_ldap_libexecdir" + LDAP_LIBEXECDIR="$withval" +else + + if test "x$ac_ldap_prefix" = "x"; then + LDAP_LIBEXECDIR="/usr/libexec" + else + LDAP_LIBEXECDIR="$ac_ldap_prefix/libexec" + fi + + +fi; + + + +# Check whether --with-ldap-sysconfdir or --without-ldap-sysconfdir was given. +if test "${with_ldap_sysconfdir+set}" = set; then + withval="$with_ldap_sysconfdir" + LDAP_SYSCONFDIR="$withval" +else + LDAP_SYSCONFDIR="$ac_ldap_prefix/etc/openldap" + +fi; + + + + +# Check whether --with-ldap-libdir or --without-ldap-libdir was given. +if test "${with_ldap_libdir+set}" = set; then + withval="$with_ldap_libdir" + LDAP_LDFLAGS="-L$withval" +else + + if test "x$ac_ldap_prefix" != "x"; then + LDAP_LDFLAGS="-L$ac_ldap_prefix/lib" + else + LDAP_LDFLAGS="" + fi + + +fi; + + + +# Check whether --with-ldap-includedir or --without-ldap-includedir was given. +if test "${with_ldap_includedir+set}" = set; then + withval="$with_ldap_includedir" + LDAP_CPPFLAGS="-I$withval" +else + + if test "x$ac_ldap_prefix" != "x"; then + LDAP_CPPFLAGS="-I$ac_ldap_prefix/include" + else + LDAP_CPPFLAGS="" + fi + + +fi; + + + + ac_save_CPPFLAGS="$CPPFLAGS" + CPPFLAGS="$CPPFLAGS $LDAP_CPPFLAGS" + + +for ac_header in lber.h ldap.h +do +as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 +else + # Is the header compilable? +echo "$as_me:$LINENO: checking $ac_header usability" >&5 +echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +#include <$ac_header> +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_header_compiler=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_header_compiler=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6 + +# Is the header present? +echo "$as_me:$LINENO: checking $ac_header presence" >&5 +echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <$ac_header> +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + ac_header_preproc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_preproc=no +fi +rm -f conftest.err conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6 + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in + yes:no: ) + { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 +echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} + ac_header_preproc=yes + ;; + no:yes:* ) + { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 +echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 +echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 +echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 +echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} + ( + cat <<\_ASBOX +## ------------------------------------------ ## +## Report this to the AC_PACKAGE_NAME lists. ## +## ------------------------------------------ ## +_ASBOX + ) | + sed "s/^/$as_me: WARNING: /" >&2 + ;; +esac +echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + eval "$as_ac_Header=\$ac_header_preproc" +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 + +fi +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +else + + { { echo "$as_me:$LINENO: error: cannot found LDAP headers" >&5 +echo "$as_me: error: cannot found LDAP headers" >&2;} + { (exit 1); exit 1; }; } + + +fi + +done + + CPPFLAGS="$ac_save_CPPFLAGS" + + ac_ldap_libs="" + +# Check whether --with-ldap-libs or --without-ldap-libs was given. +if test "${with_ldap_libs+set}" = set; then + withval="$with_ldap_libs" + ac_ldap_libs="$withval" + +fi; + +### Try to link with LDAP libs + ac_save_LDFLAGS="$LDFLAGS" + ac_save_LIBS="$LIBS" + + LDFLAGS="$LDAP_LDFLAGS $LDFLAGS" + ac_LDAP_LINK="" + if test "x$ac_ldap_libs" != "x"; then + echo "$as_me:$LINENO: checking to link with specified LDAP libs" >&5 +echo $ECHO_N "checking to link with specified LDAP libs... $ECHO_C" >&6 + + LDAP_LIBS="$ac_ldap_libs" + LIBS="$LDAP_LIBS $ac_save_LIBS" + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char ldap_init (); +int +main () +{ +ldap_init (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_LDAP_LINK="yes" + +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + if test "x$ac_LDAP_LINK" != "xyes"; then + { { echo "$as_me:$LINENO: error: cannot link with specified LDAP libs" >&5 +echo "$as_me: error: cannot link with specified LDAP libs" >&2;} + { (exit 1); exit 1; }; } + fi + else + echo "$as_me:$LINENO: checking how to link LDAP libs" >&5 +echo $ECHO_N "checking how to link LDAP libs... $ECHO_C" >&6 + + LDAP_LIBS="-lldap" + for L in lber ssl crypto; do + LDAP_LIBS="$LDAP_LIBS -l$L" + LIBS="$LDAP_LIBS $ac_save_LIBS" + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char ldap_init (); +int +main () +{ +ldap_init (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_LDAP_LINK="yes" + +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + if test "x$ac_LDAP_LINK" = "xyes"; then + break + fi + done + if test "x$ac_LDAP_LINK" != "xyes"; then + { { echo "$as_me:$LINENO: error: cannot link with default LDAP libs" >&5 +echo "$as_me: error: cannot link with default LDAP libs" >&2;} + { (exit 1); exit 1; }; } + fi + fi + echo "$as_me:$LINENO: result: done" >&5 +echo "${ECHO_T}done" >&6 + unset ac_LDAP_LINK + LIBS="$ac_save_LIBS" + LDFLAGS="$ac_save_LDFLAGS" + + + unset ac_ldap_libs + unset ac_ldap_prefix +else + { echo "$as_me:$LINENO: LDAP is disabled" >&5 +echo "$as_me: LDAP is disabled" >&6;} +fi + +if test "x$ac_ldap" = "xyes"; then + +cat >>confdefs.h <<_ACEOF +#define LDAP_ENABLED 1 +_ACEOF + + LDAP_ON='' + LDAP_OFF='#' +else + LDAP_ON='#' + LDAP_OFF='' +fi + + + +unset ac_ldap + + if test "x$LDAP_ON" = "x"; then + LDAP_MSG="yes" + fi +else + { echo "$as_me:$LINENO: x509store is disabled - skiping LDAP" >&5 +echo "$as_me: x509store is disabled - skiping LDAP" >&6;} +fi + + ssh_x509dn_email="yes" if test "x$ssh_x509store" = "xyes"; then # Check for Email in X.509 'Distinguished Name' @@ -24305,7 +24768,7 @@ fi - ac_config_files="$ac_config_files Makefile buildpkg.sh opensshd.init openbsd-compat/Makefile scard/Makefile ssh_prng_cmds tests/CA/Makefile" + ac_config_files="$ac_config_files Makefile buildpkg.sh opensshd.init openbsd-compat/Makefile scard/Makefile ssh_prng_cmds tests/CA/Makefile tests/CA/env" cat >confcache <<\_ACEOF # This file is a shell script that caches the results of configure @@ -24839,6 +25302,7 @@ "scard/Makefile" ) CONFIG_FILES="$CONFIG_FILES scard/Makefile" ;; "ssh_prng_cmds" ) CONFIG_FILES="$CONFIG_FILES ssh_prng_cmds" ;; "tests/CA/Makefile" ) CONFIG_FILES="$CONFIG_FILES tests/CA/Makefile" ;; + "tests/CA/env" ) CONFIG_FILES="$CONFIG_FILES tests/CA/env" ;; "config.h" ) CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;; *) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5 echo "$as_me: error: invalid argument: $ac_config_target" >&2;} @@ -24995,6 +25459,14 @@ s,@sshcadir@,$sshcadir,;t t s,@OCSP_ON@,$OCSP_ON,;t t s,@OCSP_OFF@,$OCSP_OFF,;t t +s,@LDAP_BINDIR@,$LDAP_BINDIR,;t t +s,@LDAP_LIBEXECDIR@,$LDAP_LIBEXECDIR,;t t +s,@LDAP_SYSCONFDIR@,$LDAP_SYSCONFDIR,;t t +s,@LDAP_LDFLAGS@,$LDAP_LDFLAGS,;t t +s,@LDAP_CPPFLAGS@,$LDAP_CPPFLAGS,;t t +s,@LDAP_LIBS@,$LDAP_LIBS,;t t +s,@LDAP_ON@,$LDAP_ON,;t t +s,@LDAP_OFF@,$LDAP_OFF,;t t s,@piddir@,$piddir,;t t s,@LIBOBJS@,$LIBOBJS,;t t s,@LTLIBOBJS@,$LTLIBOBJS,;t t @@ -25536,6 +26008,7 @@ echo " MD5 password support: $MD5_MSG" echo " X.509 store support: $ssh_x509store" echo " OCSP support: $ssh_ocsp" +echo " LDAP queries: $LDAP_MSG" echo " IP address in \$DISPLAY hack: $DISPLAY_HACK_MSG" echo " Translate v4 in v6 hack: $IPV4_IN6_HACK_MSG" echo " BSD Auth support: $BSD_AUTH_MSG" @@ -25559,6 +26032,20 @@ echo "SVR4 style packages are supported with \"make package\"\n" fi +if test "x$LDAP_MSG" = "xyes" ; then +echo "Extra LDAP flags:" +echo " LDAP compiler flags: ${LDAP_CFLAGS}" +echo "LDAP preprocessor flags: ${LDAP_CPPFLAGS}" +echo " LDAP linker flags: ${LDAP_LDFLAGS}" +echo " LDAP libraries: ${LDAP_LIBS}" +echo "" +echo "LDAP paths(used only in tests):" +echo " LDAP sysconfig dir: ${LDAP_SYSCONFDIR}" +echo " LDAP libexec dir: ${LDAP_LIBEXECDIR}" +echo " LDAP bin dir: ${LDAP_BINDIR}" +echo "" +fi + if test "x$PAM_MSG" = "xyes" ; then echo "PAM is enabled. You may need to install a PAM control file " echo "for sshd, otherwise password authentication may fail. " diff -ruN openssh-3.9p1+x509h/configure.ac openssh-3.9p1+x509-5.1/configure.ac --- openssh-3.9p1+x509h/configure.ac 2004-08-18 09:06:00.000000000 +0300 +++ openssh-3.9p1+x509-5.1/configure.ac 2004-11-19 09:06:00.000000000 +0200 @@ -2718,6 +2718,18 @@ AC_SUBST(OCSP_OFF) +# enable LDAP queries +LDAP_MSG="no" +if test "x$ssh_x509store" = "xyes"; then + AC_WITH_LDAP + if test "x$LDAP_ON" = "x"; then + LDAP_MSG="yes" + fi +else + AC_MSG_NOTICE([x509store is disabled - skiping LDAP]) +fi + + ssh_x509dn_email="yes" if test "x$ssh_x509store" = "xyes"; then # Check for Email in X.509 'Distinguished Name' @@ -3042,7 +3054,7 @@ fi AC_EXEEXT -AC_CONFIG_FILES([Makefile buildpkg.sh opensshd.init openbsd-compat/Makefile scard/Makefile ssh_prng_cmds tests/CA/Makefile]) +AC_CONFIG_FILES([Makefile buildpkg.sh opensshd.init openbsd-compat/Makefile scard/Makefile ssh_prng_cmds tests/CA/Makefile tests/CA/env]) AC_OUTPUT # Print summary of options @@ -3091,6 +3103,7 @@ echo " MD5 password support: $MD5_MSG" echo " X.509 store support: $ssh_x509store" echo " OCSP support: $ssh_ocsp" +echo " LDAP queries: $LDAP_MSG" echo " IP address in \$DISPLAY hack: $DISPLAY_HACK_MSG" echo " Translate v4 in v6 hack: $IPV4_IN6_HACK_MSG" echo " BSD Auth support: $BSD_AUTH_MSG" @@ -3114,6 +3127,20 @@ echo "SVR4 style packages are supported with \"make package\"\n" fi +if test "x$LDAP_MSG" = "xyes" ; then +echo "Extra LDAP flags:" +echo " LDAP compiler flags: ${LDAP_CFLAGS}" +echo "LDAP preprocessor flags: ${LDAP_CPPFLAGS}" +echo " LDAP linker flags: ${LDAP_LDFLAGS}" +echo " LDAP libraries: ${LDAP_LIBS}" +echo "" +echo "LDAP paths(used only in tests):" +echo " LDAP sysconfig dir: ${LDAP_SYSCONFDIR}" +echo " LDAP libexec dir: ${LDAP_LIBEXECDIR}" +echo " LDAP bin dir: ${LDAP_BINDIR}" +echo "" +fi + if test "x$PAM_MSG" = "xyes" ; then echo "PAM is enabled. You may need to install a PAM control file " echo "for sshd, otherwise password authentication may fail. " diff -ruN openssh-3.9p1+x509h/key.c openssh-3.9p1+x509-5.1/key.c --- openssh-3.9p1+x509h/key.c 2004-08-18 19:14:27.000000000 +0300 +++ openssh-3.9p1+x509-5.1/key.c 2004-11-19 09:06:01.000000000 +0200 @@ -123,7 +123,7 @@ if ((k->rsa->dmp1 = BN_new()) == NULL) fatal("key_new_private: BN_new failed"); if (k->type == KEY_X509_RSA) { - debug3("key_new_private: X509(rsa) MORE ...?"); + debug3("key_new_private: X509(rsa) MORE ...?"); /* if ((k->x509 = X509_new()) == NULL) fatal("key_new: X509_new failed"); @@ -135,7 +135,7 @@ if ((k->dsa->priv_key = BN_new()) == NULL) fatal("key_new_private: BN_new failed"); if (k->type == KEY_X509_DSA) { - debug3("key_new_private: X509(dsa) MORE ...?"); + debug3("key_new_private: X509(dsa) MORE ...?"); /* if ((k->x509 = X509_new()) == NULL) fatal("key_new: X509_new failed"); diff -ruN openssh-3.9p1+x509h/m4/ldap.m4 openssh-3.9p1+x509-5.1/m4/ldap.m4 --- openssh-3.9p1+x509h/m4/ldap.m4 1970-01-01 02:00:00.000000000 +0200 +++ openssh-3.9p1+x509-5.1/m4/ldap.m4 2004-11-18 23:09:35.000000000 +0200 @@ -0,0 +1,200 @@ +# Options to build with LDAP +# +# Author: Roumen Petrov +# Revision: 7 Nov 2004 +# +dnl The variables provided are : +dnl - paths: +dnl LDAP_BINDIR +dnl LDAP_LIBEXECDIR +dnl LDAP_SYSCONFDIR +dnl - build flags: +dnl LDAP_LDFLAGS +dnl LDAP_LIBS +dnl LDAP_CPPFLAGS +dnl - conditional: +dnl LDAP_ON (e.g. '' or '#') +dnl LDAP_OFF (e.g. '#' or '' - oposite of LDAP_ON) + +AC_DEFUN(AC_WITH_LDAP, +[ +dnl +dnl Get the ldap paths +dnl + +ac_ldap='none' +AC_ARG_ENABLE(ldap, + [ --enable-ldap Enable LDAP queries], + ac_ldap="$enableval" +) + +if test "x$ac_ldap" = xyes; then + ac_ldap_prefix="" + AC_ARG_WITH(ldap-prefix, + [ --with-ldap-prefix=PATH Prefix where LDAP is installed (optional)], + ac_ldap_prefix="$withval" + ) + + AC_ARG_WITH(ldap-bindir, + [ --with-ldap-bindir=PATH Prefix where LDAP user executables are installed (optional)], + [LDAP_BINDIR="$withval"], + [ + if test "x$ac_ldap_prefix" != "x"; then + LDAP_BINDIR="$ac_ldap_prefix/bin" + fi + ] + ) + AC_SUBST(LDAP_BINDIR) + + AC_ARG_WITH(ldap-libexecdir, + [ --with-ldap-libexecdir=PATH Prefix where LDAP program executables are installed (optional)], + [LDAP_LIBEXECDIR="$withval"], + [ + if test "x$ac_ldap_prefix" = "x"; then + LDAP_LIBEXECDIR="/usr/libexec" + else + LDAP_LIBEXECDIR="$ac_ldap_prefix/libexec" + fi + ] + ) + AC_SUBST(LDAP_LIBEXECDIR) +dnl### Check for slapd +dnl if test "x$cross_compiling" = "xyes" ; then +dnl AC_MSG_NOTICE([cannot check for LDAP daemon when cross compiling]) +dnl else +dnl AC_CHECK_FILES( +dnl [ +dnl $LDAP_LIBEXECDIR/slapd +dnl ] +dnl ) +dnl fi + + AC_ARG_WITH(ldap-sysconfdir, + [ --with-ldap-sysconfdir=PATH Prefix where LDAP single-machine data are installed (optional)], + [LDAP_SYSCONFDIR="$withval"], + [LDAP_SYSCONFDIR="$ac_ldap_prefix/etc/openldap"] + ) + AC_SUBST(LDAP_SYSCONFDIR) +dnl### Check for schema files +dnl if test "x$cross_compiling" = "xyes" ; then +dnl AC_MSG_NOTICE([cannot check for schema files existence when cross compiling]) +dnl else +dnl AC_CHECK_FILES( +dnl [ +dnl $LDAP_SYSCONFDIR/schema/core.schema +dnl $LDAP_SYSCONFDIR/schema/cosine.schema +dnl $LDAP_SYSCONFDIR/schema/inetorgperson.schema- +dnl ] +dnl ) +dnl fi + + + AC_ARG_WITH(ldap-libdir, + [ --with-ldap-libdir=PATH Prefix where LDAP libaries are installed (optional)], + [LDAP_LDFLAGS="-L$withval"], + [ + if test "x$ac_ldap_prefix" != "x"; then + LDAP_LDFLAGS="-L$ac_ldap_prefix/lib" + else + LDAP_LDFLAGS="" + fi + ] + ) + AC_SUBST(LDAP_LDFLAGS) + + AC_ARG_WITH(ldap-includedir, + [ --with-ldap-includedir=PATH Prefix where LDAP header files are installed (optional)], + [LDAP_CPPFLAGS="-I$withval"], + [ + if test "x$ac_ldap_prefix" != "x"; then + LDAP_CPPFLAGS="-I$ac_ldap_prefix/include" + else + LDAP_CPPFLAGS="" + fi + ] + ) + AC_SUBST(LDAP_CPPFLAGS) + + + ac_save_CPPFLAGS="$CPPFLAGS" + CPPFLAGS="$CPPFLAGS $LDAP_CPPFLAGS" + AC_CHECK_HEADERS( + [lber.h ldap.h], + [], + [ + AC_MSG_ERROR([cannot found LDAP headers]) + ] + ) + CPPFLAGS="$ac_save_CPPFLAGS" + + ac_ldap_libs="" + AC_ARG_WITH(ldap-libs, + [ --with-ldap-libs=LIBS Specify LDAP libraries to link with. + (default is -lldap -llber -lssl -lcrypto)], + [ac_ldap_libs="$withval"] + ) + +### Try to link with LDAP libs + ac_save_LDFLAGS="$LDFLAGS" + ac_save_LIBS="$LIBS" + + LDFLAGS="$LDAP_LDFLAGS $LDFLAGS" + ac_LDAP_LINK="" + if test "x$ac_ldap_libs" != "x"; then + AC_MSG_CHECKING([to link with specified LDAP libs]) + + LDAP_LIBS="$ac_ldap_libs" + LIBS="$LDAP_LIBS $ac_save_LIBS" + AC_LINK_IFELSE( + [AC_LANG_CALL([], [ldap_init])], + [ac_LDAP_LINK="yes"] + ) + if test "x$ac_LDAP_LINK" != "xyes"; then + AC_MSG_ERROR([cannot link with specified LDAP libs]) + fi + else + AC_MSG_CHECKING([how to link LDAP libs]) + + LDAP_LIBS="-lldap" + for L in lber ssl crypto; do + LDAP_LIBS="$LDAP_LIBS -l$L" + LIBS="$LDAP_LIBS $ac_save_LIBS" + AC_LINK_IFELSE( + [AC_LANG_CALL([], [ldap_init])], + [ac_LDAP_LINK="yes"] + ) + if test "x$ac_LDAP_LINK" = "xyes"; then + break + fi + done + if test "x$ac_LDAP_LINK" != "xyes"; then + AC_MSG_ERROR([cannot link with default LDAP libs]) + fi + fi + AC_MSG_RESULT([done]) + unset ac_LDAP_LINK + LIBS="$ac_save_LIBS" + LDFLAGS="$ac_save_LDFLAGS" + AC_SUBST([LDAP_LIBS]) + + unset ac_ldap_libs + unset ac_ldap_prefix +else + AC_MSG_NOTICE([LDAP is disabled]) +fi + +if test "x$ac_ldap" = "xyes"; then + AC_DEFINE_UNQUOTED( + LDAP_ENABLED, 1, + [Define if you want to enable LDAP queries]) + LDAP_ON='' + LDAP_OFF='#' +else + LDAP_ON='#' + LDAP_OFF='' +fi +AC_SUBST(LDAP_ON) +AC_SUBST(LDAP_OFF) + +unset ac_ldap +]) diff -ruN openssh-3.9p1+x509h/Makefile.in openssh-3.9p1+x509-5.1/Makefile.in --- openssh-3.9p1+x509h/Makefile.in 2004-08-18 09:06:01.000000000 +0300 +++ openssh-3.9p1+x509-5.1/Makefile.in 2004-11-19 09:06:01.000000000 +0200 @@ -43,10 +43,11 @@ CC=@CC@ LD=@LD@ CFLAGS=@CFLAGS@ -CPPFLAGS=-I. -I$(srcdir) @CPPFLAGS@ $(PATHS) @DEFS@ +CPPFLAGS=-I. -I$(srcdir) @CPPFLAGS@ @LDAP_CPPFLAGS@ $(PATHS) @DEFS@ LIBS=@LIBS@ LIBPAM=@LIBPAM@ LIBWRAP=@LIBWRAP@ +LIBLDAP=@LDAP_LDFLAGS@ @LDAP_LIBS@ AR=@AR@ AWK=@AWK@ RANLIB=@RANLIB@ @@ -61,7 +62,13 @@ INSTALL_SSH_PRNG_CMDS=@INSTALL_SSH_PRNG_CMDS@ INSTALL_SSH_RAND_HELPER=@INSTALL_SSH_RAND_HELPER@ -X509_OBJS=ssh-x509.o x509store.o ssh-ocsp.o +@LDAP_ON@LDAP_OBJS=x509_by_ldap.o +@LDAP_OFF@LDAP_OBJS= + +@OCSP_ON@OCSP_OBJS=ssh-ocsp.o +@OCSP_OFF@OCSP_OBJS= + +X509STORE_OBJS=x509store.o $(LDAP_OBJS) $(OCSP_OBJS) TARGETS=ssh$(EXEEXT) sshd$(EXEEXT) ssh-add$(EXEEXT) ssh-keygen$(EXEEXT) ssh-keyscan${EXEEXT} ssh-keysign${EXEEXT} ssh-agent$(EXEEXT) scp$(EXEEXT) ssh-rand-helper${EXEEXT} sftp-server$(EXEEXT) sftp$(EXEEXT) @@ -72,12 +79,12 @@ log.o match.o moduli.o mpaux.o nchan.o packet.o \ readpass.o rsa.o tildexpand.o ttymodes.o xmalloc.o \ atomicio.o key.o dispatch.o kex.o mac.o uidswap.o uuencode.o misc.o \ - monitor_fdpass.o rijndael.o ssh-dss.o ssh-rsa.o dh.o kexdh.o \ + monitor_fdpass.o rijndael.o ssh-dss.o ssh-rsa.o ssh-x509.o dh.o kexdh.o \ kexgex.o kexdhc.o kexgexc.o scard.o msg.o progressmeter.o dns.o \ - entropy.o scard-opensc.o gss-genr.o $(X509_OBJS) + entropy.o scard-opensc.o gss-genr.o SSHOBJS= ssh.o readconf.o clientloop.o sshtty.o \ - sshconnect.o sshconnect1.o sshconnect2.o + sshconnect.o sshconnect1.o sshconnect2.o $(X509STORE_OBJS) SSHDOBJS=sshd.o auth-rhosts.o auth-passwd.o auth-rsa.o auth-rh-rsa.o \ sshpty.o sshlogin.o servconf.o serverloop.o \ @@ -88,7 +95,7 @@ monitor_mm.o monitor.o monitor_wrap.o kexdhs.o kexgexs.o \ auth-krb5.o \ auth2-gss.o gss-serv.o gss-serv-krb5.o \ - loginrec.o auth-pam.o auth-shadow.o auth-sia.o md5crypt.o + loginrec.o auth-pam.o auth-shadow.o auth-sia.o md5crypt.o $(X509STORE_OBJS) MANPAGES = scp.1.out ssh-add.1.out ssh-agent.1.out ssh-keygen.1.out ssh-keyscan.1.out ssh.1.out sshd.8.out sftp-server.8.out sftp.1.out ssh-rand-helper.8.out ssh-keysign.8.out sshd_config.5.out ssh_config.5.out MANPAGES_IN = scp.1 ssh-add.1 ssh-agent.1 ssh-keygen.1 ssh-keyscan.1 ssh.1 sshd.8 sftp-server.8 sftp.1 ssh-rand-helper.8 ssh-keysign.8 sshd_config.5 ssh_config.5 @@ -139,10 +146,10 @@ $(RANLIB) $@ ssh$(EXEEXT): $(LIBCOMPAT) libssh.a $(SSHOBJS) - $(LD) -o $@ $(SSHOBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) + $(LD) -o $@ $(SSHOBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(LIBLDAP) $(LIBS) sshd$(EXEEXT): libssh.a $(LIBCOMPAT) $(SSHDOBJS) - $(LD) -o $@ $(SSHDOBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(LIBWRAP) $(LIBPAM) $(LIBS) + $(LD) -o $@ $(SSHDOBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(LIBWRAP) $(LIBPAM) $(LIBLDAP) $(LIBS) scp$(EXEEXT): $(LIBCOMPAT) libssh.a scp.o progressmeter.o $(LD) -o $@ scp.o progressmeter.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) @@ -156,8 +163,8 @@ ssh-keygen$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-keygen.o $(LD) -o $@ ssh-keygen.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) -ssh-keysign$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-keysign.o - $(LD) -o $@ ssh-keysign.o readconf.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) +ssh-keysign$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-keysign.o readconf.o $(X509STORE_OBJS) + $(LD) -o $@ ssh-keysign.o readconf.o $(X509STORE_OBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(LIBLDAP) $(LIBS) ssh-keyscan$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-keyscan.o $(LD) -o $@ ssh-keyscan.o $(LDFLAGS) -lssh -lopenbsd-compat -lssh $(LIBS) diff -ruN openssh-3.9p1+x509h/pathnames.h openssh-3.9p1+x509-5.1/pathnames.h --- openssh-3.9p1+x509h/pathnames.h 2004-08-18 19:14:27.000000000 +0300 +++ openssh-3.9p1+x509-5.1/pathnames.h 2004-11-19 09:06:00.000000000 +0200 @@ -207,7 +207,7 @@ #define _PATH_USERCA_REVOCATION_FILE "~/" _PATH_SSH_USER_DIR "/ca-bundle.crl" #define _PATH_USERCA_REVOCATION_PATH "~/" _PATH_SSH_USER_DIR "/crl" -/* x509 global store */ +/* x509 system store */ #define _PATH_CA_CERTIFICATE_FILE SSHCADIR "/ca-bundle.crt" #define _PATH_CA_CERTIFICATE_PATH SSHCADIR "/crt" #define _PATH_CA_REVOCATION_FILE SSHCADIR "/ca-bundle.crl" diff -ruN openssh-3.9p1+x509h/readconf.c openssh-3.9p1+x509-5.1/readconf.c --- openssh-3.9p1+x509h/readconf.c 2004-08-18 09:06:01.000000000 +0300 +++ openssh-3.9p1+x509-5.1/readconf.c 2004-11-19 09:06:01.000000000 +0200 @@ -132,10 +132,13 @@ oSendEnv, oControlPath, oControlMaster, oX509rsaSigType, oAllowedServerCertPurpose, + oMandatoryCRL, oCACertificateFile, oCACertificatePath, oCARevocationFile, oCARevocationPath, + oCAldapVersion, oCAldapURL, oUserCACertificateFile, oUserCACertificatePath, oUserCARevocationFile, oUserCARevocationPath, + oUserCAldapVersion, oUserCAldapURL, oVAType, oVACertificateFile, oVAOCSPResponderURL, oDeprecated, oUnsupported @@ -230,14 +233,19 @@ { "controlmaster", oControlMaster }, { "x509rsasigtype", oX509rsaSigType }, { "allowedcertpurpose", oAllowedServerCertPurpose }, + { "mandatorycrl", oMandatoryCRL }, { "cacertificatefile", oCACertificateFile }, { "cacertificatepath", oCACertificatePath }, { "carevocationfile", oCARevocationFile }, { "carevocationpath", oCARevocationPath }, + { "caldapversion", oCAldapVersion }, + { "caldapurl", oCAldapURL }, { "usercacertificatefile", oUserCACertificateFile }, { "usercacertificatepath", oUserCACertificatePath }, { "usercarevocationfile", oUserCARevocationFile }, { "usercarevocationpath", oUserCARevocationPath }, + { "usercaldapversion", oCAldapVersion }, + { "usercaldapurl", oCAldapURL }, { "vatype", oVAType }, { "vacertificatefile", oVACertificateFile }, { "vaocspresponderurl", oVAOCSPResponderURL }, @@ -855,40 +863,73 @@ break; #ifndef SSH_X509STORE_DISABLED + case oMandatoryCRL: + intptr = &options->mandatory_crl; + goto parse_flag; + case oCACertificateFile: + /*X509StoreOptions prefered type is 'const char*' */ + charptr = (char**)&options->ca.certificate_file; + goto parse_string; + case oCACertificatePath: + /*X509StoreOptions prefered type is 'const char*' */ + charptr = (char**)&options->ca.certificate_path; + goto parse_string; + case oCARevocationFile: + /*X509StoreOptions prefered type is 'const char*' */ + charptr = (char**)&options->ca.revocation_file; + goto parse_string; + case oCARevocationPath: + /*X509StoreOptions prefered type is 'const char*' */ + charptr = (char**)&options->ca.revocation_path; + goto parse_string; + case oUserCACertificateFile: + /*X509StoreOptions prefered type is 'const char*' */ + charptr = (char**)&options->userca.certificate_file; + goto parse_string; + case oUserCACertificatePath: + /*X509StoreOptions prefered type is 'const char*' */ + charptr = (char**)&options->userca.certificate_path; + goto parse_string; + case oUserCARevocationFile: + /*X509StoreOptions prefered type is 'const char*' */ + charptr = (char**)&options->userca.revocation_file; + goto parse_string; + case oUserCARevocationPath: - arg = strdelim(&s); - if (!arg || *arg == '\0') - fatal("%s line %d: Missing argument.", filename, linenum); - switch (opcode) { - case oCACertificateFile: - options->ca.certificate_file = xstrdup(arg); break; - case oCACertificatePath: - options->ca.certificate_path = xstrdup(arg); break; - case oCARevocationFile: - options->ca.revocation_file = xstrdup(arg); break; - case oCARevocationPath: - options->ca.revocation_path = xstrdup(arg); break; - case oUserCACertificateFile: - options->userca.certificate_file = xstrdup(arg); break; - case oUserCACertificatePath: - options->userca.certificate_path = xstrdup(arg); break; - case oUserCARevocationFile: - options->userca.revocation_file = xstrdup(arg); break; - case oUserCARevocationPath: - options->userca.revocation_path = xstrdup(arg); break; - default: - break; - } - break; + /*X509StoreOptions prefered type is 'const char*' */ + charptr = (char**)&options->userca.revocation_path; + goto parse_string; #endif /*ndef SSH_X509STORE_DISABLED*/ +#ifdef LDAP_ENABLED + case oCAldapVersion: + /*X509StoreOptions prefered type is 'const char*' */ + charptr = (char**)&options->ca.ldap_ver; + goto parse_string; + + case oCAldapURL: + /*X509StoreOptions prefered type is 'const char*' */ + charptr = (char**)&options->ca.ldap_url; + goto parse_string; + + case oUserCAldapVersion: + /*X509StoreOptions prefered type is 'const char*' */ + charptr = (char**)&options->userca.ldap_ver; + goto parse_string; + + case oUserCAldapURL: + /*X509StoreOptions prefered type is 'const char*' */ + charptr = (char**)&options->userca.ldap_url; + goto parse_string; +#endif /*def LDAP_ENABLED*/ + #ifdef SSH_OCSP_ENABLED case oVAType: arg = strdelim(&s); @@ -900,19 +941,14 @@ break; case oVACertificateFile: + /* VAOptions prefered type is 'const char*' */ + charptr = (char**)&options->va.certificate_file; + goto parse_string; + case oVAOCSPResponderURL: - arg = strdelim(&s); - if (!arg || *arg == '\0') - fatal("%s line %d: Missing argument.", filename, linenum); - switch (opcode) { - default: - break; - case oVACertificateFile: - options->va.certificate_file = xstrdup(arg); break; - case oVAOCSPResponderURL: - options->va.responder_url = xstrdup(arg); break; - } - break; + /* VAOptions prefered type is 'const char*' */ + charptr = (char**)&options->va.responder_url; + goto parse_string; #endif /*def SSH_OCSP_ENABLED*/ case oDeprecated: @@ -921,6 +957,7 @@ return 0; #ifdef SSH_X509STORE_DISABLED + case oMandatoryCRL: case oCACertificateFile: case oCACertificatePath: case oCARevocationFile: @@ -930,6 +967,12 @@ case oUserCARevocationFile: case oUserCARevocationPath: #endif /*def SSH_X509STORE_DISABLED*/ +#ifndef LDAP_ENABLED + case oCAldapVersion: + case oCAldapURL: + case oUserCAldapVersion: + case oUserCAldapURL: +#endif /*ndef LDAP_ENABLED*/ #ifndef SSH_OCSP_ENABLED case oVAType: case oVACertificateFile: @@ -1076,14 +1119,9 @@ options->x509rsasigtype = -1; options->allowedcertpurpose = -1; #ifndef SSH_X509STORE_DISABLED - options->ca.certificate_file = NULL; - options->ca.certificate_path = NULL; - options->ca.revocation_file = NULL; - options->ca.revocation_path = NULL; - options->userca.certificate_file = NULL; - options->userca.certificate_path = NULL; - options->userca.revocation_file = NULL; - options->userca.revocation_path = NULL; + options->mandatory_crl = -1; + ssh_x509store_initialize(&options->ca); + ssh_x509store_initialize(&options->userca); #endif /*ndef SSH_X509STORE_DISABLED*/ #ifdef SSH_OCSP_ENABLED options->va.type = -1; @@ -1097,6 +1135,8 @@ ssh_x509store_init (Options *options) { int x509_store_loaded = 0; + ssh_x509store_mandatory_crl(options->mandatory_crl); + if(ssh_x509store_addlocations(&options->userca)) { x509_store_loaded = 1; } @@ -1108,21 +1148,6 @@ } #endif /*ndef SSH_X509STORE_DISABLED*/ -#ifndef SSH_X509STORE_DISABLED -static void -tilde_expand_filename2(const char **_fn, const char* _default) { - extern uid_t original_real_uid; - - if (*_fn == NULL) { - *_fn = tilde_expand_filename(_default, original_real_uid); - } else { - const char *p = *_fn; - *_fn = tilde_expand_filename(p, original_real_uid); - xfree((void*)p); - } -} -#endif /*ndef SSH_X509STORE_DISABLED*/ - /* * Called after processing other sources of option data, this fills those * options for which no value has been specified with their default values. @@ -1256,19 +1281,15 @@ options->allowedcertpurpose = ssh_get_default_x509purpose(0); ssh_set_x509purpose(0, options->allowedcertpurpose); #ifndef SSH_X509STORE_DISABLED - if (options->ca.certificate_file == NULL) - options->ca.certificate_file = _PATH_CA_CERTIFICATE_FILE; - if (options->ca.certificate_path == NULL) - options->ca.certificate_path = _PATH_CA_CERTIFICATE_PATH; - if (options->ca.revocation_file == NULL) - options->ca.revocation_file = _PATH_CA_REVOCATION_FILE; - if (options->ca.revocation_path == NULL) - options->ca.revocation_path = _PATH_CA_REVOCATION_PATH; - - tilde_expand_filename2(&options->userca.certificate_file, _PATH_USERCA_CERTIFICATE_FILE); - tilde_expand_filename2(&options->userca.certificate_path, _PATH_USERCA_CERTIFICATE_PATH); - tilde_expand_filename2(&options->userca.revocation_file , _PATH_USERCA_REVOCATION_FILE ); - tilde_expand_filename2(&options->userca.revocation_path , _PATH_USERCA_REVOCATION_PATH ); + if (options->mandatory_crl == -1) + options->mandatory_crl = 0; + + ssh_x509store_system_defaults(&options->ca); + + { + extern uid_t original_real_uid; + ssh_x509store_user_defaults(&options->userca, original_real_uid); + } ssh_x509store_init(options); #endif /*ndef SSH_X509STORE_DISABLED*/ diff -ruN openssh-3.9p1+x509h/readconf.h openssh-3.9p1+x509-5.1/readconf.h --- openssh-3.9p1+x509h/readconf.h 2004-08-18 09:06:00.000000000 +0300 +++ openssh-3.9p1+x509-5.1/readconf.h 2004-11-19 09:06:00.000000000 +0200 @@ -141,7 +141,8 @@ /* allowed server certificate purpose */ int allowedcertpurpose; #ifndef SSH_X509STORE_DISABLED - /* sshd PKI(X509) global store */ + int mandatory_crl; + /* sshd PKI(X509) system store */ X509StoreOptions ca; /* sshd PKI(X509) user store */ X509StoreOptions userca; diff -ruN openssh-3.9p1+x509h/README.x509v3 openssh-3.9p1+x509-5.1/README.x509v3 --- openssh-3.9p1+x509h/README.x509v3 2004-03-20 12:56:57.000000000 +0200 +++ openssh-3.9p1+x509-5.1/README.x509v3 2004-11-18 22:33:59.000000000 +0200 @@ -1,6 +1,6 @@ Roumen Petrov Sofia, Bulgaria - Sat Mar 20 2004 + Wed Nov 17 2004 How to use X.509 certificates with OpenSSH? @@ -18,7 +18,7 @@ ..... -----END CERTIFICATE----- Note that to use X.509 certificates in OpenSSH files must contain -private key followed by certificate. +private key followed by certificate that match private key! 1.) server configuration: @@ -56,6 +56,12 @@ integer starting from zero. Hash is result from command like this: $ openssl crl -in crl_file_name -noout -hash +1.1.2.5.) CAldapVersion + LDAP protocol version. Default depend from LDAP library. + +1.1.2.6.) CAldapURL + Hostport and dn of LDAP URL. No default value. + 1.1.3.) HostKey files... Host key for protocol version 2 can contain private key plus X.509 certificate in PEM format. @@ -68,7 +74,7 @@ ... X509COMPAT: RSA succeed for sha1 digest ... This options is intended to collect information about default signature digest type in other SecSH implementations. -When you see this PLEASE send a EMAIL with "X509COMPAT" lines +When you see this PLEASE send me a EMAIL with "X509COMPAT" lines from log files. 1.1.5.) VAType none @@ -146,7 +152,9 @@ - [User]CACertificatePath; - [User]CACertificateFile; - [User]CARevocationFile; -- [User]CARevocationPath. +- [User]CARevocationPath; +- [User]CAldapVersion; +- [User]CAldapURL. Note: When we use own CA we must import CA certificate[s] to "X509 store". More info on: @@ -176,7 +184,7 @@ 3.1.) In openssh build dir run "make check" or "make test". Both commands are equivalent and run regression tests. - If you lake to test only X.509 certificates you can run + If you want to test only X.509 certificates you can run $ make check-certs If certificate test scripts fail might you should setup test @@ -245,8 +253,8 @@ Read sshd_config.5 manual page for valid values. - SSHD_PORT (environment or config) - specifies the port number that server listens on and client connect - to on localhost. The default is 20022. + Specifies the port number that server listens on and client connect + to on SSHD_LISTENADDRESS. The default is 20022. - SSHD_LISTENADDRESS (only in config) Same as sshd option "ListenAddress" but without(!) port number. @@ -271,7 +279,7 @@ Variables related to OCSP tests. - SSH_VA_BASEPORT (environment or config) - test script run one or more OCSP responders at same once. First + Test script run one or more OCSP responders at same once. First responder listen on specified port, second on port plus one and etc. The default is 20080. - SSH_OPENSLL_OCSP_TMOUT=60 @@ -281,6 +289,20 @@ This is work around for missing SO_REUSEADDR socket option in OpenSSL OCSP responder. +3.1.2.5.) LDAP: + In use only when OpenSSH is build with LDAP support! + - SSH_LDAP_DB + (config) + Specifies LDAP database type. The default is ldbm. + - SSH_LDAP_DC + (config) + Specifies domain name component in LDAP distinguished name. + The default is "dc=example,dc=com". + - LDAPD_PORT + (environment or config) + LDAP daemon run by test script run listens on SSHD_LISTENADDRESS + and this port. The default is 20389. + 3.1.3.) Sample commands to run tests: $ OPENSSL=/usr/local/ssl/bin/openssl make check-certs $ SSHD_PORT=1122 SSH_X509TESTS="agent blob_auth" make check-certs @@ -316,6 +338,10 @@ config: Configuration file. +env.in: + Template file. + Currently contain variables related to LDAP directories. + shell.rc: Shell settings. @@ -335,10 +361,14 @@ File with .pub extention contain openssh public key (BLOB format). File with .crt extention contain openssl "text output" for identity files. Files with .p12 extention are for "Microsoft Windows keystore". -Note: .p12 = .pfx for Windows. + Note: .p12 = .pfx for Windows. + 4-cre_crls.sh: Revoke part of client certificates. +5-cre_ldap.sh + Create LDAP ldif files and slapd config. + verify.sh: To check certificates against "Test CA". Note: check only testid_*.crt and testhostkey_*.crt files in current directory. @@ -353,7 +383,10 @@ test-dn_auth_file.sh.inc, test-dn_auth_path.sh.inc, test-agent.sh.inc, -test-crl.sh.inc: +test-crl.sh.inc, +test-alg.sh.inc, +test-ocsp.sh.inc, +test-by_ldap.sh.inc: Test shell scripts. See DESCRIPTION in each file. Note that hostbased authentication we cannot test without to install. @@ -443,5 +476,22 @@ and start/restart the server. Don't forget to inform users that hostkey is changed! +Q.) How to import CA certificates and/or CRLs in LDAP? +A.) You should create a ldif file with LDAP entries that contains + binary atributes "cACertificate" and/or "certificateRevocationList" + and to specify path to file with certificate or CRL in DER format. + Entry should contain objectClass "pkiCA". See definition in core + LDAP schema. After this to use command ldapadd or ldapmodify to + add/modify LDAP data. See command manual pages. + + As example when you build OpenSSH with ldap queries after + regression test see content of file + $(top_builddir)/tests/CA/ldap/ca.ldif . + This file is created by the script + $(srcdir)/tests/CA/5-cre_ldap.sh + and entries are added to LDAP with command: +# ldapadd -x -w secret -D cn=... -H ldap://... \ + -f .../ca.ldif . + See ldapadd manual page for options meaning. Enjoy ;-) diff -ruN openssh-3.9p1+x509h/servconf.c openssh-3.9p1+x509-5.1/servconf.c --- openssh-3.9p1+x509h/servconf.c 2004-08-18 09:06:01.000000000 +0300 +++ openssh-3.9p1+x509-5.1/servconf.c 2004-11-19 09:06:01.000000000 +0200 @@ -125,13 +125,14 @@ options->authorized_keys_file = NULL; options->authorized_keys_file2 = NULL; options->num_accept_env = 0; + + options->hostbased_algorithms = NULL; + options->pubkey_algorithms = NULL; options->x509rsasigtype = -1; options->allowedcertpurpose = -1; #ifndef SSH_X509STORE_DISABLED - options->ca.certificate_file = NULL; - options->ca.certificate_path = NULL; - options->ca.revocation_file = NULL; - options->ca.revocation_path = NULL; + options->mandatory_crl = -1; + ssh_x509store_initialize(&options->ca); #endif /*ndef SSH_X509STORE_DISABLED*/ #ifdef SSH_OCSP_ENABLED options->va.type = -1; @@ -267,6 +268,8 @@ if (options->authorized_keys_file == NULL) options->authorized_keys_file = _PATH_SSH_USER_PERMITTED_KEYS; + /* options->hostbased_algorithms */ + /* options->pubkey_algorithms */ if (options->x509rsasigtype == -1) options->x509rsasigtype = SSH_X509RSA_MD5; options->x509rsasigtype = ssh_x509rsasig(options->x509rsasigtype); @@ -274,14 +277,10 @@ options->allowedcertpurpose = ssh_get_default_x509purpose(1); ssh_set_x509purpose(1, options->allowedcertpurpose); #ifndef SSH_X509STORE_DISABLED - if (options->ca.certificate_file == NULL) - options->ca.certificate_file = _PATH_CA_CERTIFICATE_FILE; - if (options->ca.certificate_path == NULL) - options->ca.certificate_path = _PATH_CA_CERTIFICATE_PATH; - if (options->ca.revocation_file == NULL) - options->ca.revocation_file = _PATH_CA_REVOCATION_FILE; - if (options->ca.revocation_path == NULL) - options->ca.revocation_path = _PATH_CA_REVOCATION_PATH; + if (options->mandatory_crl == -1) + options->mandatory_crl = 0; + ssh_x509store_mandatory_crl(options->mandatory_crl); + ssh_x509store_system_defaults(&options->ca); ssh_x509store_addlocations(&options->ca); #endif /*ndef SSH_X509STORE_DISABLED*/ #ifdef SSH_OCSP_ENABLED @@ -332,8 +331,12 @@ sUsePrivilegeSeparation, sX509rsaSigType, sAllowedClientCertPurpose, + sMandatoryCRL, sCACertificateFile, sCACertificatePath, sCARevocationFile, sCARevocationPath, + sCAldapVersion, sCAldapURL, + sHostbasedAlgorithms, + sPubkeyAlgorithms, sVAType, sVACertificateFile, sVAOCSPResponderURL, sDeprecated, sUnsupported @@ -438,10 +441,15 @@ { "acceptenv", sAcceptEnv }, { "x509rsasigtype", sX509rsaSigType }, { "allowedcertpurpose", sAllowedClientCertPurpose }, + { "mandatorycrl", sMandatoryCRL } , { "cacertificatefile", sCACertificateFile }, { "cacertificatepath", sCACertificatePath }, { "carevocationfile", sCARevocationFile }, { "carevocationpath", sCARevocationPath }, + { "caldapversion", sCAldapVersion }, + { "caldapurl", sCAldapURL }, + { "hostbasedalgorithms", sHostbasedAlgorithms }, + { "pubkeyalgorithms", sPubkeyAlgorithms }, { "vatype", sVAType }, { "vacertificatefile", sVACertificateFile }, { "vaocspresponderurl", sVAOCSPResponderURL }, @@ -988,6 +996,28 @@ } break; + case sHostbasedAlgorithms: + arg = strdelim(&cp); + if (!arg || *arg == '\0') + fatal("%s line %d: Missing argument.", filename, linenum); + if (!key_names_valid2(arg)) + fatal("%.200s line %d: Bad protocol 2 hostbased algorithms '%s'.", + filename, linenum, arg ? arg : ""); + if (options->hostbased_algorithms == NULL) + options->hostbased_algorithms = xstrdup(arg); + break; + + case sPubkeyAlgorithms: + arg = strdelim(&cp); + if (!arg || *arg == '\0') + fatal("%s line %d: Missing argument.", filename, linenum); + if (!key_names_valid2(arg)) + fatal("%.200s line %d: Bad protocol 2 public key algorithms '%s'.", + filename, linenum, arg ? arg : ""); + if (options->pubkey_algorithms == NULL) + options->pubkey_algorithms = xstrdup(arg); + break; + case sX509rsaSigType: arg = strdelim(&cp); if (!arg || *arg == '\0') @@ -1024,6 +1054,10 @@ break; #ifndef SSH_X509STORE_DISABLED + case sMandatoryCRL: + intptr = &options->mandatory_crl; + goto parse_flag; + case sCACertificateFile: case sCACertificatePath: case sCARevocationFile: @@ -1046,6 +1080,22 @@ break; #endif /*ndef SSH_X509STORE_DISABLED*/ +#ifdef LDAP_ENABLED + case sCAldapVersion: + arg = strdelim(&cp); + if (!arg || *arg == '\0') + fatal("%s line %d: Missing argument.", filename, linenum); + options->ca.ldap_ver = xstrdup(arg); + break; + + case sCAldapURL: + arg = strdelim(&cp); + if (!arg || *arg == '\0') + fatal("%s line %d: Missing argument.", filename, linenum); + options->ca.ldap_url = xstrdup(arg); + break; +#endif /*def LDAP_ENABLED*/ + #ifdef SSH_OCSP_ENABLED case sVAType: arg = strdelim(&cp); @@ -1080,11 +1130,16 @@ break; #ifdef SSH_X509STORE_DISABLED + case sMandatoryCRL: case sCACertificateFile: case sCACertificatePath: case sCARevocationFile: case sCARevocationPath: #endif /*def SSH_X509STORE_DISABLED*/ +#ifndef LDAP_ENABLED + case sCAldapVersion: + case sCAldapURL: +#endif /*ndef LDAP_ENABLED*/ #ifndef SSH_OCSP_ENABLED case sVAType: case sVACertificateFile: diff -ruN openssh-3.9p1+x509h/servconf.h openssh-3.9p1+x509-5.1/servconf.h --- openssh-3.9p1+x509h/servconf.h 2004-08-18 09:06:00.000000000 +0300 +++ openssh-3.9p1+x509-5.1/servconf.h 2004-11-19 09:06:00.000000000 +0200 @@ -158,12 +158,15 @@ char *authorized_keys_file2; int use_pam; /* Enable auth via PAM */ + char* hostbased_algorithms; /* Supported hostbased algorithms. */ + char* pubkey_algorithms; /* Supported pubkey algorithms. */ /* rumen-XXX: X509 RSA signature type: md5=0, sha1=1 */ int x509rsasigtype; /* allowed client certificate purpose */ int allowedcertpurpose; #ifndef SSH_X509STORE_DISABLED - /* sshd PKI(X509) global store */ + int mandatory_crl; + /* sshd PKI(X509) system store */ X509StoreOptions ca; #endif /*ndef SSH_X509STORE_DISABLED*/ #ifdef SSH_OCSP_ENABLED diff -ruN openssh-3.9p1+x509h/ssh.0 openssh-3.9p1+x509-5.1/ssh.0 --- openssh-3.9p1+x509h/ssh.0 2004-08-18 21:03:50.000000000 +0300 +++ openssh-3.9p1+x509-5.1/ssh.0 2004-11-19 09:06:00.000000000 +0200 @@ -319,10 +319,11 @@ DSA authentication is read. The default is $HOME/.ssh/identity for protocol version 1, and $HOME/.ssh/id_rsa and $HOME/.ssh/id_dsa for protocol version 2. For protocol version 2 - is possible identity to contain in addition a X.509 certificate. - Identity files may also be specified on a per-host basis in the - configuration file. It is possible to have multiple -i options - (and multiple identities specified in configuration files). + is possible identity to contain in addition X.509 certificate + that match private key. Identity files may also be specified on + a per-host basis in the configuration file. It is possible to + have multiple -i options (and multiple identities specified in + configuration files). -k Disables forwarding (delegation) of GSSAPI credentials to the server. @@ -501,18 +502,19 @@ $HOME/.ssh/identity, $HOME/.ssh/id_dsa, $HOME/.ssh/id_rsa Contains the authentication identity of the user. They are for protocol 1 RSA, protocol 2 DSA, and protocol 2 RSA, respectively. - It is possible protocol version 2 identity to contain identity - plus X.509 certificate. These files contain sensitive data and - should be readable by the user but not accessible by others - (read/write/execute). Note that ssh ignores a private key file - if it is accessible by others. It is possible to specify a - passphrase when generating the key; the passphrase will be used - to encrypt the sensitive part of this file using 3DES. + It is possible protocol version 2 identity to contain private key + followed by X.509 certificate that match it. These files contain + sensitive data and should be readable by the user but not acces- + sible by others (read/write/execute). Note that ssh ignores a + private key file if it is accessible by others. It is possible + to specify a passphrase when generating the key; the passphrase + will be used to encrypt the sensitive part of this file using + 3DES. $HOME/.ssh/identity.pub, $HOME/.ssh/id_dsa.pub, $HOME/.ssh/id_rsa.pub Contains the public key for authentication (public part of the identity file in human-readable form). Note that protocol ver- - sion 2 while a identity contain private key and X.509 certificate + sion 2 if a identity contain private key and X.509 certificate this file must contain that certificate. The contents of the $HOME/.ssh/identity.pub file should be added to the file $HOME/.ssh/authorized_keys on all machines where the user wishes @@ -570,18 +572,18 @@ /etc/ssh/ssh_host_rsa_key These three files contain the private parts of the host keys and are used for RhostsRSAAuthentication and HostbasedAuthentication. - It is possible files to contain private part plus X.509 certifi- - cate for protocol version 2 keys. If the protocol version 1 - RhostsRSAAuthentication method is used, ssh must be setuid root, - since the host key is readable only by root. For protocol ver- - sion 2, ssh uses ssh-keysign(8) to access the host keys for - HostbasedAuthentication. This eliminates the requirement that - ssh be setuid root when that authentication method is used. By - default ssh is not setuid root. When a certificate is used as - host key for hostbased authentication that certificate must have - client purpose too or server configuration must permit connection - without client purpose. For allowed client certificate purposes - see ssh_config(5). + It is possible files to contain private part followed by X.509 + certificate that match it for protocol version 2 keys. If the + protocol version 1 RhostsRSAAuthentication method is used, ssh + must be setuid root, since the host key is readable only by root. + For protocol version 2, ssh uses ssh-keysign(8) to access the + host keys for HostbasedAuthentication. This eliminates the + requirement that ssh be setuid root when that authentication + method is used. By default ssh is not setuid root. When a cer- + tificate is used as host key for hostbased authentication that + certificate must have client purpose too or server configuration + must permit connection without client purpose. For allowed client + certificate purposes see ssh_config(5). /etc/ssh/ca/ca-bundle.crt and /etc/ssh/ca/ca-bundle.crl Part of systemwide ``X.509 store''. The first file contain mul- diff -ruN openssh-3.9p1+x509h/ssh.1 openssh-3.9p1+x509-5.1/ssh.1 --- openssh-3.9p1+x509h/ssh.1 2004-08-18 19:14:28.000000000 +0300 +++ openssh-3.9p1+x509-5.1/ssh.1 2004-11-19 09:06:00.000000000 +0200 @@ -579,7 +579,7 @@ .Pa $HOME/.ssh/id_dsa for protocol version 2. For protocol version 2 is possible identity to contain in addition -a X.509 certificate. +X.509 certificate that match private key. Identity files may also be specified on a per-host basis in the configuration file. It is possible to have multiple @@ -863,8 +863,8 @@ .It Pa $HOME/.ssh/identity, $HOME/.ssh/id_dsa, $HOME/.ssh/id_rsa Contains the authentication identity of the user. They are for protocol 1 RSA, protocol 2 DSA, and protocol 2 RSA, respectively. -It is possible protocol version 2 identity to contain identity plus -X.509 certificate. +It is possible protocol version 2 identity to contain +private key followed by X.509 certificate that match it. These files contain sensitive data and should be readable by the user but not accessible by others (read/write/execute). @@ -877,7 +877,7 @@ .It Pa $HOME/.ssh/identity.pub, $HOME/.ssh/id_dsa.pub, $HOME/.ssh/id_rsa.pub Contains the public key for authentication (public part of the identity file in human-readable form). -Note that protocol version 2 while a identity contain private key and +Note that protocol version 2 if a identity contain private key and X.509 certificate this file must contain that certificate. The contents of the .Pa $HOME/.ssh/identity.pub @@ -932,8 +932,8 @@ This file contains public keys, one per line, in the following format (fields separated by spaces): system name, public key and optional comment field. -When a X.509 certificate is used as host key instead of public key line -contain certificate (old style) or certificate +When a X.509 certificate is used as host key instead of public key +line contain certificate (old style) or certificate .Dq "Distinguished Name" . When different names are used for the same machine, all such names should be listed, separated by @@ -959,8 +959,9 @@ .Cm RhostsRSAAuthentication and .Cm HostbasedAuthentication . -It is possible files to contain private part plus X.509 certificate for -protocol version 2 keys. +It is possible files to contain private part +followed by X.509 certificate that match it +for protocol version 2 keys. If the protocol version 1 .Cm RhostsRSAAuthentication method is used, diff -ruN openssh-3.9p1+x509h/ssh-add.0 openssh-3.9p1+x509-5.1/ssh-add.0 --- openssh-3.9p1+x509h/ssh-add.0 2004-08-18 21:03:46.000000000 +0300 +++ openssh-3.9p1+x509-5.1/ssh-add.0 2004-11-19 09:06:00.000000000 +0200 @@ -77,13 +77,13 @@ $HOME/.ssh/id_dsa Contains the protocol version 2 DSA authentication identity of - the user. It is possible to contain identity plus X.509 certifi- - cate. + the user. It is possible to contain private key followed by + X.509 certificate that match it. $HOME/.ssh/id_rsa Contains the protocol version 2 RSA authentication identity of - the user. It is possible to contain identity plus X.509 certifi- - cate. + the user. It is possible to contain private key followed by + X.509 certificate that match it. Identity files should not be readable by anyone but the user. Note that ssh-add ignores identity files if they are accessible by others. diff -ruN openssh-3.9p1+x509h/ssh-add.1 openssh-3.9p1+x509-5.1/ssh-add.1 --- openssh-3.9p1+x509h/ssh-add.1 2004-08-18 19:14:28.000000000 +0300 +++ openssh-3.9p1+x509-5.1/ssh-add.1 2004-11-19 09:06:00.000000000 +0200 @@ -149,10 +149,12 @@ Contains the protocol version 1 RSA authentication identity of the user. .It Pa $HOME/.ssh/id_dsa Contains the protocol version 2 DSA authentication identity of the user. -It is possible to contain identity plus X.509 certificate. +It is possible to contain private key +followed by X.509 certificate that match it. .It Pa $HOME/.ssh/id_rsa Contains the protocol version 2 RSA authentication identity of the user. -It is possible to contain identity plus X.509 certificate. +It is possible to contain private key +followed by X.509 certificate that match it. .El .Pp Identity files should not be readable by anyone but the user. diff -ruN openssh-3.9p1+x509h/ssh-agent.0 openssh-3.9p1+x509-5.1/ssh-agent.0 --- openssh-3.9p1+x509h/ssh-agent.0 2004-08-18 21:03:47.000000000 +0300 +++ openssh-3.9p1+x509-5.1/ssh-agent.0 2004-11-19 09:06:00.000000000 +0200 @@ -50,7 +50,7 @@ identity has a passphrase, ssh-add(1) asks for the passphrase (using a small X11 application if running under X11, or from the terminal if run- ning without X). It then sends the identity to the agent. Identity can - contain in addition a X.509 certificate. Several identities can be + by X.509 certificate that match private key. Several identities can be stored in the agent; the agent can automatically use any of these identi- ties. ssh-add -l displays the identities currently held by the agent. @@ -94,13 +94,13 @@ $HOME/.ssh/id_dsa Contains the protocol version 2 DSA authentication identity of - the user. It is possible to contain identity plus x509 certifi- - cate. + the user. It is possible to contain private key followed by + X.509 certificate that match it. $HOME/.ssh/id_rsa Contains the protocol version 2 RSA authentication identity of - the user. It is possible to contain identity plus x509 certifi- - cate. + the user. It is possible to contain private key followed by + X.509 certificate that match it. /tmp/ssh-XXXXXXXXXX/agent. Unix-domain sockets used to contain the connection to the authen- diff -ruN openssh-3.9p1+x509h/ssh-agent.1 openssh-3.9p1+x509-5.1/ssh-agent.1 --- openssh-3.9p1+x509h/ssh-agent.1 2004-08-18 19:14:28.000000000 +0300 +++ openssh-3.9p1+x509-5.1/ssh-agent.1 2004-11-19 09:06:00.000000000 +0200 @@ -122,7 +122,7 @@ asks for the passphrase (using a small X11 application if running under X11, or from the terminal if running without X). It then sends the identity to the agent. -Identity can contain in addition a X.509 certificate. +Identity can by X.509 certificate that match private key. Several identities can be stored in the agent; the agent can automatically use any of these identities. .Ic ssh-add -l @@ -186,10 +186,12 @@ Contains the protocol version 1 RSA authentication identity of the user. .It Pa $HOME/.ssh/id_dsa Contains the protocol version 2 DSA authentication identity of the user. -It is possible to contain identity plus x509 certificate. +It is possible to contain private key +followed by X.509 certificate that match it. .It Pa $HOME/.ssh/id_rsa Contains the protocol version 2 RSA authentication identity of the user. -It is possible to contain identity plus x509 certificate. +It is possible to contain private key +followed by X.509 certificate that match it. .It Pa /tmp/ssh-XXXXXXXXXX/agent. Unix-domain sockets used to contain the connection to the authentication agent. diff -ruN openssh-3.9p1+x509h/ssh.c openssh-3.9p1+x509-5.1/ssh.c --- openssh-3.9p1+x509h/ssh.c 2004-08-15 10:23:34.000000000 +0300 +++ openssh-3.9p1+x509-5.1/ssh.c 2004-11-19 09:06:01.000000000 +0200 @@ -18,6 +18,9 @@ * Modified to work with SSL by Niels Provos * in Canada (German citizen). * + * X509 certificates support: + * Copyright (c) 2002-2003 Roumen Petrov. All rights reserved. + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: @@ -40,10 +43,14 @@ */ #include "includes.h" -RCSID("$OpenBSD: ssh.c,v 1.224 2004/07/28 09:40:29 markus Exp $"); +RCSID("$OpenBSD$"); #include #include +#ifdef LDAP_ENABLED +/* OpenSSL extension defined in x509_by_ldap.c */ +extern void ERR_load_X509byLDAP_strings(void); +#endif #include "ssh.h" #include "ssh1.h" @@ -79,6 +86,9 @@ extern char *__progname; +/* ssh-x509.c needs this */ +extern int (*pssh_x509cert_check)(X509 *cert); + /* Flag indicating whether debug mode is on. This can be set on the command line. */ int debug_flag = 0; @@ -185,6 +195,7 @@ __progname = ssh_get_progname(av[0]); init_rng(); + pssh_x509cert_check = ssh_x509cert_check; /* * Save the original real uid. It will be needed later (uid-swapping @@ -487,6 +498,9 @@ SSLeay_add_all_algorithms(); ERR_load_crypto_strings(); +#ifdef LDAP_ENABLED + ERR_load_X509byLDAP_strings(); +#endif /* Initialize the command to execute on remote host. */ buffer_init(&command); diff -ruN openssh-3.9p1+x509h/ssh_config openssh-3.9p1+x509-5.1/ssh_config --- openssh-3.9p1+x509h/ssh_config 2004-08-18 09:06:00.000000000 +0300 +++ openssh-3.9p1+x509-5.1/ssh_config 2004-11-19 09:06:00.000000000 +0200 @@ -37,6 +37,7 @@ # EscapeChar ~ # X509rsaSigType=md5 # AllowedCertPurpose sslserver +# MandatoryCRL no # CACertificateFile /etc/ssh/ca/ca-bundle.crt # CACertificatePath /etc/ssh/ca/crt # CARevocationFile /etc/ssh/ca/ca-bundle.crl diff -ruN openssh-3.9p1+x509h/ssh_config.0 openssh-3.9p1+x509-5.1/ssh_config.0 --- openssh-3.9p1+x509h/ssh_config.0 2004-08-18 09:06:00.000000000 +0300 +++ openssh-3.9p1+x509-5.1/ssh_config.0 2004-11-19 09:06:00.000000000 +0200 @@ -71,27 +71,38 @@ work if UsePrivilegedPort is set to ``yes''. CACertificateFile - This file contain multiple certificates of certificate signers in - PEM format concatenated together. The default is - /etc/ssh/ca/ca-bundle.crt. + ``X509 store'' option: This file contain multiple certificates of + certificate signers in PEM format concatenated together. The + default is /etc/ssh/ca/ca-bundle.crt. CACertificatePath - ``Hash dir'' with certificates of certificate signers. Each cer- - tificate should be stored in separate file with name [HASH].[NUM- - BER], where [HASH] is certificate hash value and [NUMBER] is an - integer starting from zero. The default is /etc/ssh/ca/crt. + ``X509 store'' option: ``Hash dir'' with certificates of certifi- + cate signers. Each certificate should be stored in separate file + with name [HASH].[NUMBER], where [HASH] is certificate hash value + and [NUMBER] is an integer starting from zero. The default is + /etc/ssh/ca/crt. + + CAldapVersion + ``X509 store'' option: Specifies LDAP protocol version. The + default depend from LDAP library. + + CAldapURL + ``X509 store'' option: Specifies hostport and dn of LDAP URLs + (Uniform Resource Locators) as detailed in RFC 2255. The rest of + URL is build internally. Because of OpenSSH options parser limi- + tation use `%3D' instead of `=' ! CARevocationFile - This file contain multiple ``Certificate Revocation List'' (CRL) - of certificate signers in PEM format concatenated together. The - default is /etc/ssh/ca/ca-bundle.crl. + ``X509 store'' option: This file contain multiple ``Certificate + Revocation List'' (CRL) of certificate signers in PEM format con- + catenated together. The default is /etc/ssh/ca/ca-bundle.crl. CARevocationPath - ``Hash dir'' with ``Certificate Revocation List'' (CRL) of cer- - tificate signers. Each CRL should be stored in separate file with - name [HASH].r[NUMBER], where [HASH] is CRL hash value and [NUM- - BER] is an integer starting from zero. The default is - /etc/ssh/ca/crl. + ``X509 store'' option: ``Hash dir'' with ``Certificate Revocation + List'' (CRL) of certificate signers. Each CRL should be stored in + separate file with name [HASH].r[NUMBER], where [HASH] is CRL + hash value and [NUMBER] is an integer starting from zero. The + default is /etc/ssh/ca/crl. ChallengeResponseAuthentication Specifies whether to use challenge response authentication. The @@ -284,12 +295,12 @@ identity is read. The default is $HOME/.ssh/identity for proto- col version 1, and $HOME/.ssh/id_rsa and $HOME/.ssh/id_dsa for protocol version 2. For version 2 is possible identity file to - contain key plus X.509 certificate. Additionally, any identities - represented by the authentication agent will be used for authen- - tication. The file name may use the tilde syntax to refer to a - user's home directory. It is possible to have multiple identity - files specified in configuration files; all these identities will - be tried in sequence. + contain key followed by X.509 certificate that match the key. + Additionally, any identities represented by the authentication + agent will be used for authentication. The file name may use the + tilde syntax to refer to a user's home directory. It is possible + to have multiple identity files specified in configuration files; + all these identities will be tried in sequence. IdentitiesOnly Specifies that ssh should only use the authentication identity @@ -321,6 +332,11 @@ be comma-separated. The default is ``hmac-md5,hmac-sha1,hmac-ripemd160,hmac-sha1-96,hmac-md5-96''. + MandatoryCRL + ``X509 store'' option: Specifies whether CRL must present in + store for all certificates in ``certificate chain'' with atribute + ``X509v3 CRL Distribution Points''. The default is ``no''. + NoHostAuthenticationForLocalhost This option can be used if the home directory is shared across machines. In this case localhost will refer to a different @@ -483,16 +499,26 @@ mand line. UserCACertificateFile - User CACertificateFile , the default is ~/.ssh/ca-bundle.crt. + ``X509 store'' option: User CACertificateFile , the default is + ~/.ssh/ca-bundle.crt. UserCACertificatePath - User CACertificatePath , the default is ~/.ssh/crt. + ``X509 store'' option: User CACertificatePath , the default is + ~/.ssh/crt. + + UserCAldapVersion + ``X509 store'' option: User CAldapVersion. + + UserCAldapURL + ``X509 store'' option: User CAldapURL. UserCARevocationFile - User CARevocationFile , the default is ~/.ssh/ca-bundle.crl. + ``X509 store'' option: User CARevocationFile , the default is + ~/.ssh/ca-bundle.crl. UserCARevocationPath - User CARevocationPath , the default is ~/.ssh/crl. + ``X509 store'' option: User CARevocationPath , the default is + ~/.ssh/crl. UserKnownHostsFile Specifies a file to use for the user host key database instead of diff -ruN openssh-3.9p1+x509h/ssh_config.5 openssh-3.9p1+x509-5.1/ssh_config.5 --- openssh-3.9p1+x509h/ssh_config.5 2004-08-18 09:06:00.000000000 +0300 +++ openssh-3.9p1+x509-5.1/ssh_config.5 2004-11-19 09:06:00.000000000 +0200 @@ -175,28 +175,47 @@ .Cm UsePrivilegedPort is set to .Dq yes . -.Pp .It Cm CACertificateFile +.Dq X509 store +option: This file contain multiple certificates of certificate signers in PEM format concatenated together. The default is .Pa /etc/ssh/ca/ca-bundle.crt . -.Pp .It Cm CACertificatePath +.Dq X509 store +option: .Dq "Hash dir" with certificates of certificate signers. Each certificate should be stored in separate file with name [HASH].[NUMBER], where [HASH] is certificate hash value and [NUMBER] is an integer starting from zero. The default is .Pa /etc/ssh/ca/crt . -.Pp +.It Cm CAldapVersion +.Dq X509 store +option: +Specifies LDAP protocol version. +The default depend from LDAP library. +.It Cm CAldapURL +.Dq X509 store +option: +Specifies hostport and dn of LDAP URLs (Uniform Resource Locators) +as detailed in RFC 2255. The rest of URL is build internally. +Because of OpenSSH options parser limitation use +.Sq %3D +instead of +.Sq = +! .It Cm CARevocationFile +.Dq X509 store +option: This file contain multiple .Dq "Certificate Revocation List" (CRL) of certificate signers in PEM format concatenated together. The default is .Pa /etc/ssh/ca/ca-bundle.crl . -.Pp .It Cm CARevocationPath +.Dq X509 store +option: .Dq "Hash dir" with .Dq "Certificate Revocation List" @@ -504,7 +523,8 @@ and .Pa $HOME/.ssh/id_dsa for protocol version 2. -For version 2 is possible identity file to contain key plus X.509 certificate. +For version 2 is possible identity file to contain key +followed by X.509 certificate that match the key. Additionally, any identities represented by the authentication agent will be used for authentication. The file name may use the tilde @@ -556,6 +576,15 @@ Multiple algorithms must be comma-separated. The default is .Dq hmac-md5,hmac-sha1,hmac-ripemd160,hmac-sha1-96,hmac-md5-96 . +.It Cm MandatoryCRL +.Dq X509 store +option: +Specifies whether CRL must present in store for all certificates in +.Dq certificate chain +with atribute +.Dq X509v3 CRL Distribution Points . +The default is +.Dq no . .It Cm NoHostAuthenticationForLocalhost This option can be used if the home directory is shared across machines. In this case localhost will refer to a different machine on each of @@ -814,26 +843,40 @@ This can be useful when a different user name is used on different machines. This saves the trouble of having to remember to give the user name on the command line. -.Pp .It Cm UserCACertificateFile +.Dq X509 store +option: User .Cm CACertificateFile , the default is .Pa ~/.ssh/ca-bundle.crt . -.Pp .It Cm UserCACertificatePath +.Dq X509 store +option: User .Cm CACertificatePath , the default is .Pa ~/.ssh/crt . -.Pp +.It Cm UserCAldapVersion +.Dq X509 store +option: +User +.Cm CAldapVersion . +.It Cm UserCAldapURL +.Dq X509 store +option: +User +.Cm CAldapURL . .It Cm UserCARevocationFile +.Dq X509 store +option: User .Cm CARevocationFile , the default is .Pa ~/.ssh/ca-bundle.crl . -.Pp .It Cm UserCARevocationPath +.Dq X509 store +option: User .Cm CARevocationPath , the default is diff -ruN openssh-3.9p1+x509h/sshconnect.c openssh-3.9p1+x509-5.1/sshconnect.c --- openssh-3.9p1+x509h/sshconnect.c 2004-08-18 19:14:28.000000000 +0300 +++ openssh-3.9p1+x509-5.1/sshconnect.c 2004-11-19 09:06:01.000000000 +0200 @@ -759,7 +759,7 @@ subject = x509key_subject(host_key); snprintf(extramsg, sizeof(extramsg), "Distinguished name is %.*s.\n", - X509KEY_SUBJECT_MAXLEN, subject); + (int) X509_NAME_MAXLEN, subject); } else { subject = NULL; *extramsg = '\0'; @@ -1091,7 +1091,7 @@ if ((host_key->type == KEY_X509_RSA) || (host_key->type == KEY_X509_DSA)) { char *subject = x509key_subject(host_key); error("Distinguished name sent by remote host is\n%.*s.", - X509KEY_SUBJECT_MAXLEN, subject); + (int) X509_NAME_MAXLEN, subject); xfree(subject); } error("Please contact your system administrator."); diff -ruN openssh-3.9p1+x509h/sshd.0 openssh-3.9p1+x509-5.1/sshd.0 --- openssh-3.9p1+x509h/sshd.0 2004-08-18 21:03:51.000000000 +0300 +++ openssh-3.9p1+x509-5.1/sshd.0 2004-11-19 09:06:00.000000000 +0200 @@ -60,10 +60,11 @@ SSH protocol version 2 Version 2 works similarly: Each host has a host-specific key (RSA or DSA) - used to identify the host. It is possible host key to contain key plus - X.509 certificate. However, when the daemon starts, it does not generate - a server key. Forward security is provided through a Diffie-Hellman key - agreement. This key agreement results in a shared session key. + used to identify the host. It is possible host key to contain private + key followed by X.509 certificate that match it. However, when the dae- + mon starts, it does not generate a server key. Forward security is pro- + vided through a Diffie-Hellman key agreement. This key agreement results + in a shared session key. The rest of the session is encrypted using a symmetric cipher, currently 128-bit AES, Blowfish, 3DES, CAST128, Arcfour, 192-bit AES, or 256-bit @@ -142,8 +143,8 @@ /etc/ssh/ssh_host_rsa_key and /etc/ssh/ssh_host_dsa_key for pro- tocol version 2. It is possible to have multiple host key files for the different protocol versions and host key algorithms. It - is possible host key for protocol version 2 to contain key plus - X.509 certificate. + is possible host key for protocol version 2 to contain private + key followed by X.509 certificate that match it. -i Specifies that sshd is being run from inetd(8). sshd is normally not run from inetd because it needs to generate the server key @@ -396,21 +397,22 @@ /etc/ssh/ssh_host_key, /etc/ssh/ssh_host_dsa_key, /etc/ssh/ssh_host_rsa_key These three files contain the private parts of the host keys. It - is possible to contain private part plus X.509 certificate for - protocol version 2 keys. These files should only be owned by - root, readable only by root, and not accessible to others. Note - that sshd does not start if this file is group/world-accessible. + is possible to contain private part followed by X.509 certificate + that match it for protocol version 2 keys. These files should + only be owned by root, readable only by root, and not accessible + to others. Note that sshd does not start if this file is + group/world-accessible. /etc/ssh/ssh_host_key.pub, /etc/ssh/ssh_host_dsa_key.pub, /etc/ssh/ssh_host_rsa_key.pub These three files contain the public parts of the host keys. These files should be world-readable but writable only by root. Their contents should match the respective private parts. Note - that when corresponding host key contain a certificate in addi- - tion these file must contains that certificate. These files are - not really used for anything; they are provided for the conve- - nience of the user so their contents can be copied to known hosts - files. These files are created using ssh-keygen(1). + that when corresponding host key contain X.509 certificate these + files must contains that certificate. These files are not really + used for anything; they are provided for the convenience of the + user so their contents can be copied to known hosts files. These + files are created using ssh-keygen(1). /etc/moduli Contains Diffie-Hellman groups used for the "Diffie-Hellman Group diff -ruN openssh-3.9p1+x509h/sshd.8 openssh-3.9p1+x509-5.1/sshd.8 --- openssh-3.9p1+x509h/sshd.8 2004-08-18 19:14:28.000000000 +0300 +++ openssh-3.9p1+x509-5.1/sshd.8 2004-11-19 09:06:00.000000000 +0200 @@ -153,7 +153,8 @@ .Ss SSH protocol version 2 Version 2 works similarly: Each host has a host-specific key (RSA or DSA) used to identify the host. -It is possible host key to contain key plus X.509 certificate. +It is possible host key to contain private key +followed by X.509 certificate that match it. However, when the daemon starts, it does not generate a server key. Forward security is provided through a Diffie-Hellman key agreement. This key agreement results in a shared session key. @@ -261,8 +262,8 @@ for protocol version 2. It is possible to have multiple host key files for the different protocol versions and host key algorithms. -It is possible host key for protocol version 2 to contain key plus X.509 -certificate. +It is possible host key for protocol version 2 to contain private key +followed by X.509 certificate that match it. .It Fl i Specifies that .Nm @@ -641,8 +642,9 @@ .Xr sshd_config 5 . .It Pa /etc/ssh/ssh_host_key, /etc/ssh/ssh_host_dsa_key, /etc/ssh/ssh_host_rsa_key These three files contain the private parts of the host keys. -It is possible to contain private part plus X.509 certificate for -protocol version 2 keys. +It is possible to contain private part +followed by X.509 certificate that match it +for protocol version 2 keys. These files should only be owned by root, readable only by root, and not accessible to others. Note that @@ -653,8 +655,8 @@ These files should be world-readable but writable only by root. Their contents should match the respective private parts. -Note that when corresponding host key contain a certificate -in addition these file must contains that certificate. +Note that when corresponding host key contain X.509 certificate +these files must contains that certificate. These files are not really used for anything; they are provided for the convenience of the user so their contents can be copied to known hosts files. diff -ruN openssh-3.9p1+x509h/sshd.c openssh-3.9p1+x509-5.1/sshd.c --- openssh-3.9p1+x509h/sshd.c 2004-08-18 19:14:28.000000000 +0300 +++ openssh-3.9p1+x509-5.1/sshd.c 2004-11-19 09:06:01.000000000 +0200 @@ -108,6 +108,9 @@ extern char *__progname; +/* ssh-x509.c needs this */ +extern int (*pssh_x509cert_check)(X509 *cert); + /* Server configuration options. */ ServerOptions options; @@ -914,6 +917,7 @@ #endif __progname = ssh_get_progname(av[0]); init_rng(); + pssh_x509cert_check = ssh_x509cert_check; /* Save argv. Duplicate so setproctitle emulation doesn't clobber it */ saved_argc = ac; diff -ruN openssh-3.9p1+x509h/sshd_config openssh-3.9p1+x509-5.1/sshd_config --- openssh-3.9p1+x509h/sshd_config 2004-08-18 09:06:00.000000000 +0300 +++ openssh-3.9p1+x509-5.1/sshd_config 2004-11-19 09:06:00.000000000 +0200 @@ -32,6 +32,10 @@ # - "skip" or ""(empty): don`t check purpose. #AllowedCertPurpose sslclient +# Specifies whether CRL must present in store for all certificates in +# certificate chain with atribute "cRLDistributionPoints" +#MandatoryCRL no + # A file with multiple certificates of certificate signers # in PEM format concatenated together. #CACertificateFile /etc/ssh/ca/ca-bundle.crt @@ -50,6 +54,15 @@ # or have symbolic links to them of this form. #CARevocationPath /etc/ssh/ca/crl +# LDAP protocol version. +# Example: +# CAldapVersion 2 + +# Note because of OpenSSH options parser limitation +# use %3D instead of = ! +# Example: +# CAldapURL ldap://localhost:389/dc%3Dexample,dc%3Dcom + # SSH can use "Online Certificate Status Protocol"(OCSP) # to validate certificate. Set VAType to # - none : do not use OCSP to validate certificates; diff -ruN openssh-3.9p1+x509h/sshd_config.0 openssh-3.9p1+x509-5.1/sshd_config.0 --- openssh-3.9p1+x509h/sshd_config.0 2004-08-18 09:06:00.000000000 +0300 +++ openssh-3.9p1+x509-5.1/sshd_config.0 2004-11-19 09:06:00.000000000 +0200 @@ -35,7 +35,6 @@ o `sslclient' , `SSL client' , `SSL_client' or `client' ; o `any' , `Any Purpose' , `Any_Purpose' or `AnyPurpose' ; o `skip' or `' (empty): do not check purpose. - The default is ``sslclient''. AllowGroups @@ -80,27 +79,38 @@ protocol version 2. By default, no banner is displayed. CACertificateFile - This file contain multiple certificates of certificate signers in - PEM format concatenated together. The default is - /etc/ssh/ca/ca-bundle.crt. + ``X509 store'' option: This file contain multiple certificates of + certificate signers in PEM format concatenated together. The + default is /etc/ssh/ca/ca-bundle.crt. CACertificatePath - ``Hash dir'' with certificates of certificate signers. Each cer- - tificate should be stored in separate file with name [HASH].[NUM- - BER], where [HASH] is certificate hash value and [NUMBER] is an - integer starting from zero. The default is /etc/ssh/ca/crt. + ``X509 store'' option: ``Hash dir'' with certificates of certifi- + cate signers. Each certificate should be stored in separate file + with name [HASH].[NUMBER], where [HASH] is certificate hash value + and [NUMBER] is an integer starting from zero. The default is + /etc/ssh/ca/crt. + + CAldapVersion + ``X509 store'' option: Specifies LDAP protocol version. The + default is not specified and depend from LDAP library. + + CAldapURL + ``X509 store'' option: Specifies hostport and dn(distinguished + name) of LDAP URLs (Uniform Resource Locators) as detailed in RFC + 2255. The rest of URL is build internally. Because of OpenSSH + options parser limitation use `%3D' instead of `=' ! CARevocationFile - This file contain multiple ``Certificate Revocation List'' (CRL) - of certificate signers in PEM format concatenated together. The - default is /etc/ssh/ca/ca-bundle.crl. + ``X509 store'' option: This file contain multiple ``Certificate + Revocation List'' (CRL) of certificate signers in PEM format con- + catenated together. The default is /etc/ssh/ca/ca-bundle.crl. CARevocationPath - ``Hash dir'' with ``Certificate Revocation List'' (CRL) of cer- - tificate signers. Each CRL should be stored in separate file with - name [HASH].r[NUMBER], where [HASH] is CRL hash value and [NUM- - BER] is an integer starting from zero. The default is - /etc/ssh/ca/crl. + ``X509 store'' option: ``Hash dir'' with ``Certificate Revocation + List'' (CRL) of certificate signers. Each CRL should be stored in + separate file with name [HASH].r[NUMBER], where [HASH] is CRL + hash value and [NUMBER] is an integer starting from zero. The + default is /etc/ssh/ca/crl. ChallengeResponseAuthentication Specifies whether challenge response authentication is allowed. @@ -183,6 +193,11 @@ cache on logout. The default is ``yes''. Note that this option applies to protocol version 2 only. + HostbasedAlgorithms + Specifies the protocol version 2 algorithms used in ``hostbased'' + authentication that the server accept. The default is all sup- + ported by server. + HostbasedAuthentication Specifies whether rhosts or /etc/hosts.equiv authentication together with successful public key client host authentication is @@ -198,7 +213,8 @@ is group/world-accessible. It is possible to have multiple host key files. ``rsa1'' keys are used for version 1 and ``dsa'' or ``rsa'' are used for version 2 of the SSH protocol. It is possi- - ble host key to contain key plus X.509 certificate for version 2. + ble host key to contain private key followed by X.509 certificate + that match it for version 2. IgnoreRhosts Specifies that .rhosts and .shosts files will not be used in @@ -274,6 +290,11 @@ rated. The default is ``hmac-md5,hmac-sha1,hmac-ripemd160,hmac-sha1-96,hmac-md5-96''. + MandatoryCRL + ``X509 store'' option: Specifies whether CRL must present in + store for all certificates in ``certificate chain'' with atribute + ``X509v3 CRL Distribution Points''. The default is ``no''. + MaxAuthTries Specifies the maximum number of authentication attempts permitted per connection. Once the number of failures reaches half this @@ -352,6 +373,11 @@ selects among multiple protocol versions offered by the server. Specifying ``2,1'' is identical to ``1,2''. + PubkeyAlgorithms + Specifies the protocol version 2 algorithms used in ``publickey'' + authentication that the server accept. The default is all sup- + ported by server. + PubkeyAuthentication Specifies whether public key authentication is allowed. The default is ``yes''. Note that this option applies to protocol diff -ruN openssh-3.9p1+x509h/sshd_config.5 openssh-3.9p1+x509-5.1/sshd_config.5 --- openssh-3.9p1+x509h/sshd_config.5 2004-08-18 09:06:00.000000000 +0300 +++ openssh-3.9p1+x509-5.1/sshd_config.5 2004-11-19 09:06:00.000000000 +0200 @@ -114,7 +114,6 @@ .. (empty): do not check purpose. .El -.Pp The default is .Dq sslclient . .It Cm AllowGroups @@ -174,23 +173,46 @@ This option is only available for protocol version 2. By default, no banner is displayed. .It Cm CACertificateFile +.Dq X509 store +option: This file contain multiple certificates of certificate signers in PEM format concatenated together. The default is .Pa /etc/ssh/ca/ca-bundle.crt . .It Cm CACertificatePath +.Dq X509 store +option: .Dq "Hash dir" with certificates of certificate signers. Each certificate should be stored in separate file with name [HASH].[NUMBER], where [HASH] is certificate hash value and [NUMBER] is an integer starting from zero. The default is .Pa /etc/ssh/ca/crt . +.It Cm CAldapVersion +.Dq X509 store +option: +Specifies LDAP protocol version. +The default is not specified and depend from LDAP library. +.It Cm CAldapURL +.Dq X509 store +option: +Specifies hostport and dn(distinguished name) of LDAP URLs (Uniform Resource Locators) as detailed in RFC 2255. +The rest of URL is build internally. +Because of OpenSSH options parser limitation use +.Sq %3D +instead of +.Sq = +! .It Cm CARevocationFile +.Dq X509 store +option: This file contain multiple .Dq "Certificate Revocation List" (CRL) of certificate signers in PEM format concatenated together. The default is .Pa /etc/ssh/ca/ca-bundle.crl . .It Cm CARevocationPath +.Dq X509 store +option: .Dq "Hash dir" with .Dq "Certificate Revocation List" @@ -323,6 +345,11 @@ The default is .Dq yes . Note that this option applies to protocol version 2 only. +.It Cm HostbasedAlgorithms +Specifies the protocol version 2 algorithms used in +.Dq hostbased +authentication that the server accept. +The default is all supported by server. .It Cm HostbasedAuthentication Specifies whether rhosts or /etc/hosts.equiv authentication together with successful public key client host authentication is allowed @@ -352,7 +379,8 @@ or .Dq rsa are used for version 2 of the SSH protocol. -It is possible host key to contain key plus X.509 certificate +It is possible host key to contain private key +followed by X.509 certificate that match it for version 2. .It Cm IgnoreRhosts Specifies that @@ -475,6 +503,15 @@ Multiple algorithms must be comma-separated. The default is .Dq hmac-md5,hmac-sha1,hmac-ripemd160,hmac-sha1-96,hmac-md5-96 . +.It Cm MandatoryCRL +.Dq X509 store +option: +Specifies whether CRL must present in store for all certificates in +.Dq certificate chain +with atribute +.Dq X509v3 CRL Distribution Points . +The default is +.Dq no . .It Cm MaxAuthTries Specifies the maximum number of authentication attempts permitted per connection. @@ -609,6 +646,11 @@ .Dq 2,1 is identical to .Dq 1,2 . +.It Cm PubkeyAlgorithms +Specifies the protocol version 2 algorithms used in +.Dq publickey +authentication that the server accept. +The default is all supported by server. .It Cm PubkeyAuthentication Specifies whether public key authentication is allowed. The default is diff -ruN openssh-3.9p1+x509h/ssh-keygen.0 openssh-3.9p1+x509-5.1/ssh-keygen.0 --- openssh-3.9p1+x509h/ssh-keygen.0 2004-08-18 21:03:48.000000000 +0300 +++ openssh-3.9p1+x509-5.1/ssh-keygen.0 2004-11-19 09:06:00.000000000 +0200 @@ -214,13 +214,14 @@ $HOME/.ssh/id_dsa Contains the protocol version 2 DSA authentication identity of - the user. It is possible to contain identity plus X.509 certifi- - cate. This file should not be readable by anyone but the user. - It is possible to specify a passphrase when generating the key; - that passphrase will be used to encrypt the private part of this - file using 3DES. This file is not automatically accessed by - ssh-keygen but it is offered as the default file for the private - key. ssh(1) will read this file when a login attempt is made. + the user. It is possible to contain private key followed by + X.509 certificate that match it. This file should not be read- + able by anyone but the user. It is possible to specify a + passphrase when generating the key; that passphrase will be used + to encrypt the private part of this file using 3DES. This file + is not automatically accessed by ssh-keygen but it is offered as + the default file for the private key. ssh(1) will read this file + when a login attempt is made. $HOME/.ssh/id_dsa.pub Contains the protocol version 2 DSA public key for authentica- @@ -228,22 +229,24 @@ $HOME/.ssh/authorized_keys on all machines where the user wishes to log in using public key authentication. There is no need to keep the contents of this file secret. When file - $HOME/.ssh/id_dsa contain DSA identity plus X.509 certificate - this file must contain that certificate! Use ssh-keygen with - option -y to regenerate its content. Note in case with X.509 - certificate you can append content to $HOME/.ssh/authorized_keys - or to add certificate ``Distinguished Name'' / ``Subject'' in - corresponding format to ``authorized keys'' file. See sshd(8). + $HOME/.ssh/id_dsa contain DSA private key followed by X.509 cer- + tificate this file must contain that certificate! Use ssh-keygen + with option -y to regenerate its content. Note in case with + X.509 certificate you can append content to + $HOME/.ssh/authorized_keys or to add certificate ``Distinguished + Name'' / ``Subject'' in corresponding format to ``authorized + keys'' file. See sshd(8). $HOME/.ssh/id_rsa Contains the protocol version 2 RSA authentication identity of - the user. It is possible to contain identity plus X.509 certifi- - cate. This file should not be readable by anyone but the user. - It is possible to specify a passphrase when generating the key; - that passphrase will be used to encrypt the private part of this - file using 3DES. This file is not automatically accessed by - ssh-keygen but it is offered as the default file for the private - key. ssh(1) will read this file when a login attempt is made. + the user. It is possible to contain private key followed by + X.509 certificate that match it. This file should not be read- + able by anyone but the user. It is possible to specify a + passphrase when generating the key; that passphrase will be used + to encrypt the private part of this file using 3DES. This file + is not automatically accessed by ssh-keygen but it is offered as + the default file for the private key. ssh(1) will read this file + when a login attempt is made. $HOME/.ssh/id_rsa.pub Contains the protocol version 2 RSA public key for authentica- @@ -251,12 +254,13 @@ $HOME/.ssh/authorized_keys on all machines where the user wishes to log in using public key authentication. There is no need to keep the contents of this file secret. When file - $HOME/.ssh/id_rsa contain RSA identity plus X.509 certificate - this file must contain that certificate! Use ssh-keygen with - option -y to regenerate its content. Note in case with X.509 - certificate you can append content to $HOME/.ssh/authorized_keys - or to add certificate ``Distinguished Name'' / ``Subject'' in - corresponding format to ``authorized keys'' file. See sshd(8). + $HOME/.ssh/id_rsa contain RSA private key followed by X.509 cer- + tificate this file must contain that certificate! Use ssh-keygen + with option -y to regenerate its content. Note in case with + X.509 certificate you can append content to + $HOME/.ssh/authorized_keys or to add certificate ``Distinguished + Name'' / ``Subject'' in corresponding format to ``authorized + keys'' file. See sshd(8). /etc/moduli Contains Diffie-Hellman groups used for DH-GEX. The file format diff -ruN openssh-3.9p1+x509h/ssh-keygen.1 openssh-3.9p1+x509-5.1/ssh-keygen.1 --- openssh-3.9p1+x509h/ssh-keygen.1 2004-08-18 19:14:28.000000000 +0300 +++ openssh-3.9p1+x509-5.1/ssh-keygen.1 2004-11-19 09:06:00.000000000 +0200 @@ -360,7 +360,8 @@ There is no need to keep the contents of this file secret. .It Pa $HOME/.ssh/id_dsa Contains the protocol version 2 DSA authentication identity of the user. -It is possible to contain identity plus X.509 certificate. +It is possible to contain private key +followed by X.509 certificate that match it. This file should not be readable by anyone but the user. It is possible to specify a passphrase when generating the key; that passphrase will be @@ -379,8 +380,9 @@ There is no need to keep the contents of this file secret. When file .Pa $HOME/.ssh/id_dsa -contain DSA identity plus X.509 certificate this file must contain -that certificate! Use +contain DSA private key followed by X.509 certificate +this file must contain that certificate! +Use .Nm with option -y to regenerate its content. Note in case with X.509 certificate you can append content to @@ -395,7 +397,8 @@ .Xr sshd 8 . .It Pa $HOME/.ssh/id_rsa Contains the protocol version 2 RSA authentication identity of the user. -It is possible to contain identity plus X.509 certificate. +It is possible to contain private key +followed by X.509 certificate that match it. This file should not be readable by anyone but the user. It is possible to specify a passphrase when generating the key; that passphrase will be @@ -414,8 +417,9 @@ There is no need to keep the contents of this file secret. When file .Pa $HOME/.ssh/id_rsa -contain RSA identity plus X.509 certificate this file must contain -that certificate! Use +contain RSA private key followed by X.509 certificate +this file must contain that certificate! +Use .Nm with option -y to regenerate its content. Note in case with X.509 certificate you can append content to diff -ruN openssh-3.9p1+x509h/ssh-keysign.0 openssh-3.9p1+x509-5.1/ssh-keysign.0 --- openssh-3.9p1+x509h/ssh-keysign.0 2004-08-18 21:03:53.000000000 +0300 +++ openssh-3.9p1+x509-5.1/ssh-keysign.0 2004-11-19 09:06:00.000000000 +0200 @@ -29,7 +29,8 @@ readable only by root, and not accessible to others. Since they are readable only by root, ssh-keysign must be set-uid root if hostbased authentication is used. It is possible host key to - contain private parts plus X.509 certificate. + contain private parts followed by X.509 certificate that match + it. SEE ALSO ssh(1), ssh-keygen(1), ssh_config(5), sshd(8) diff -ruN openssh-3.9p1+x509h/ssh-keysign.8 openssh-3.9p1+x509-5.1/ssh-keysign.8 --- openssh-3.9p1+x509h/ssh-keysign.8 2004-08-18 19:14:28.000000000 +0300 +++ openssh-3.9p1+x509-5.1/ssh-keysign.8 2004-11-19 09:06:00.000000000 +0200 @@ -68,7 +68,8 @@ Since they are readable only by root, .Nm must be set-uid root if hostbased authentication is used. -It is possible host key to contain private parts plus X.509 certificate. +It is possible host key to contain private parts +followed by X.509 certificate that match it. .El .Sh SEE ALSO .Xr ssh 1 , diff -ruN openssh-3.9p1+x509h/ssh-ocsp.c openssh-3.9p1+x509-5.1/ssh-ocsp.c --- openssh-3.9p1+x509h/ssh-ocsp.c 2004-03-21 11:37:25.000000000 +0200 +++ openssh-3.9p1+x509-5.1/ssh-ocsp.c 2004-11-07 23:24:04.000000000 +0200 @@ -23,9 +23,12 @@ */ #include "x509store.h" +#ifndef SSH_OCSP_ENABLED +# include "error: OCSP is disabled" +#endif -#ifdef SSH_OCSP_ENABLED #if 0 +# /* not yet implemented */ # define SSH_WITH_SSLOCSP #endif @@ -69,7 +72,6 @@ n = sizeof(sshva_type_map) / sizeof(sshva_type_map[0]); for (k = 0; k < n; k++) { va_type_map *p = sshva_type_map + k; -logit("RUMEN: p->code=%s", p->code); if (strcasecmp(type, p->code) == 0) return(p->id); } @@ -145,6 +147,21 @@ } +static void +openssl_error(const char *ssh_method, const char *openssl_method) { + char buf[512]; + + ERR_error_string_n(ERR_get_error(), buf, sizeof(buf)); + /* clear rest of errors in OpenSSL "error buffer" */ + ERR_clear_error(); + + error("%.128s: %.128s fail with errormsg='%.*s'" + , ssh_method + , openssl_method + , (int) sizeof(buf), buf); +} + + static char* ssh_ASN1_GENERALIZEDTIME_2_string(ASN1_GENERALIZEDTIME *asn1_time) { BIO *bio; @@ -197,14 +214,11 @@ } if (BIO_read_filename(fbio, certs_file) <= 0) { - char ebuf[512]; - error("ssh_load_x509certs:" - " File description is '%.512s'." - " BIO_read_filename(..., '%.512s')" - " fail with errormsg='%.512s'" + openssl_error("ssh_load_x509certs", "BIO_read_filename"); + logit("ssh_load_x509certs:" + " description/filename='%.512s'/'%.512s'" , certs_descrip - , certs_file - , openssl_errormsg(ebuf, sizeof(ebuf))); + , certs_file); goto exit; } @@ -249,7 +263,7 @@ ) { X509 *issuer = NULL; OCSP_CERTID *id = NULL; - char subj[512]; + char subj[X509_NAME_MAXLEN]; if (cert == NULL) { error("ssh_ocspreq_addcert: cert is NULL"); @@ -468,10 +482,7 @@ #ifndef OPENSSL_NO_SOCK bio_conn = BIO_new_connect(conn->host); if (bio_conn == NULL) { - char ebuf[512]; - error("ssh_ocsp_get_response:" - " BIO_new_connect fail with errormsg='%.512s'" - , openssl_errormsg(ebuf, sizeof(ebuf))); + openssl_error("ssh_ocsp_get_response", "BIO_new_connect"); goto exit; } #else @@ -502,19 +513,13 @@ #endif /*def SSH_WITH_SSLOCSP*/ if (BIO_do_connect(bio_conn) <= 0) { - char ebuf[512]; - error("ssh_ocsp_get_response:" - " BIO_do_connect fail with errormsg='%.512s'" - , openssl_errormsg(ebuf, sizeof(ebuf))); + openssl_error("ssh_ocsp_get_response", "BIO_do_connect"); goto exit; } resp = OCSP_sendreq_bio(bio_conn, conn->path, req); if (resp == NULL) { - char ebuf[512]; - error("ssh_ocsp_get_response:" - " OCSP_sendreq_bio fail with errormsg='%.512s'" - , openssl_errormsg(ebuf, sizeof(ebuf))); + openssl_error("ssh_ocsp_get_response", "OCSP_sendreq_bio"); } exit: @@ -553,10 +558,7 @@ br = OCSP_response_get1_basic(resp); if (br == NULL) { - char ebuf[512]; - error("ssh_ocsp_get_basicresp: " - " OCSP_response_get1_basic fail with errormsg='%.512s'" - , openssl_errormsg(ebuf, sizeof(ebuf))); + openssl_error("ssh_ocsp_get_basicresp", "OCSP_response_get1_basic"); return(NULL); } @@ -565,10 +567,7 @@ if (flag == -1) { logit("ssh_ocsp_get_basicresp: WARNING - no nonce in response"); } else { - char ebuf[512]; - error("ssh_ocsp_get_basicresp: " - " OCSP_check_nonce fail with errormsg='%.512s'" - , openssl_errormsg(ebuf, sizeof(ebuf))); + openssl_error("ssh_ocsp_get_basicresp", "OCSP_check_nonce"); goto error; } } @@ -578,10 +577,12 @@ int k; logit("ssh_ocsp_get_basicresp: VA certs num=%d", sk_X509_num(vacrts)); for (k = 0; k < sk_X509_num(vacrts); k++) { - char buf[512]; + char buf[X509_NAME_MAXLEN]; X509 *x = sk_X509_value(vacrts, k); X509_NAME_oneline(X509_get_subject_name(x), buf, sizeof(buf)); - logit("ssh_ocsp_get_basicresp: VA[%d] subject='%.512s'", k, buf); + logit("ssh_ocsp_get_basicresp: VA[%d] subject='%.*s'" + , k + , (int) sizeof(buf), buf); } } #endif /*def SSHOCSPTEST*/ @@ -621,12 +622,8 @@ flag = OCSP_basic_verify(br, NULL, x509store, basic_verify_flags); } if (flag <= 0) { - char ebuf[512]; - error("ssh_ocsp_get_basicresp:" - " flag=%d" - " OCSP_basic_verify fail with errormsg='%.512s'" - , flag - , openssl_errormsg(ebuf, sizeof(ebuf))); + openssl_error("ssh_ocsp_get_basicresp", "OCSP_basic_verify"); + logit("ssh_ocsp_get_basicresp: flag=%d", flag); goto error; } @@ -641,9 +638,9 @@ /* - * Method return: + * Method return value: * 1 - all cert.-s are good - * -1 - error or one cert. with status unknow + * -1 - error or at least one cert. with status unknow * 0 - otherwise, i.e. at least one cert. is revoked and rest are good */ static int @@ -695,9 +692,9 @@ if (get_log_level() >= SYSLOG_LEVEL_DEBUG3) { char *subject = sk_value(subjs, k); - debug3("ssh_ocsp_check_validity:" - " cert[%d]='%.512s'" - , k, subject); + debug3("ssh_ocsp_check_validity: cert[%d]='%.*s'" + , k + , (int) X509_NAME_MAXLEN, subject); } if (!OCSP_resp_find_status( @@ -757,7 +754,7 @@ static int -ssh_ocsp_validate( +ssh_ocsp_validate2( X509 *cert, X509_STORE *x509store, const ssh_ocsp_conn *ocsp @@ -776,7 +773,7 @@ (va.certificate_file != NULL)) { vacrts = ssh_load_x509certs(va.certificate_file, "'OCSP Responder' trusted certificates"); if (vacrts == NULL) goto exit; - debug("ssh_ocsp_validate: VA certs num=%d", sk_X509_num(vacrts)); + debug("ssh_ocsp_validate2: VA certs num=%d", sk_X509_num(vacrts)); } if (!ssh_ocspreq_addcert(cert, x509store, req, ids, subjs)) { @@ -793,7 +790,7 @@ { /*check OCSP response status*/ int flag = OCSP_response_status(resp); if (flag != OCSP_RESPONSE_STATUS_SUCCESSFUL) { - error("ssh_ocsp_validate:" + error("ssh_ocsp_validate2:" " responder error=%d(%.256s)" , flag , OCSP_response_status_str((long/*???*/)flag)); @@ -929,7 +926,7 @@ debug("ssh_aiaocsp_validate: cannot create ocsp connection"); continue; } - ret = ssh_ocsp_validate(cert, x509store, conn); + ret = ssh_ocsp_validate2(cert, x509store, conn); ssh_ocsp_conn_free(&conn); if (ret >= 0) break; @@ -940,7 +937,7 @@ static int -ssh_x509_validate4cert(X509 *cert, X509_STORE *x509store) { +ssh_ocsp_validate4cert(X509 *cert, X509_STORE *x509store) { int found = 0; int ret = -1; int loc = -1; @@ -955,7 +952,7 @@ xe = X509_get_ext(cert, loc); if (xe == NULL) { - debug("ssh_x509_validate4cert: cannot get x509 extension"); + debug("ssh_ocsp_validate4cert: cannot get x509 extension"); continue; } @@ -972,49 +969,44 @@ } if (found) { - debug3("ssh_x509_validate4cert: validation result=%d", ret); + debug3("ssh_ocsp_validate4cert: validation result=%d", ret); } else { - debug3("ssh_x509_validate4cert: no OCSP 'Service Locator' URL"); + debug3("ssh_ocsp_validate4cert: no OCSP 'Service Locator' URL"); } return(found ? ret : 1); } -#endif /*def SSH_OCSP_ENABLED*/ int -ssh_x509_validate(X509 *cert, X509_STORE *x509store) { -#ifndef SSH_OCSP_ENABLED - return(1); -#else +ssh_ocsp_validate(X509 *cert, X509_STORE *x509store) { int ret = -1; ssh_ocsp_conn *conn = NULL; if (get_log_level() >= SYSLOG_LEVEL_DEBUG3) { - char buf[512]; + char buf[X509_NAME_MAXLEN]; X509_NAME_oneline( X509_get_subject_name(cert), buf, sizeof(buf)); - debug3("ssh_x509_validate: for '%.512s'", buf); + debug3("ssh_ocsp_validate: for '%.*s'", (int) sizeof(buf), buf); } switch (va.type) { default: /*when something is missing*/ - fatal("ssh_x509_validate: invalid validator type %d", va.type); + fatal("ssh_ocsp_validate: invalid validator type %d", va.type); break; /*;-)*/ case SSHVA_NONE: ret = 1; break; case SSHVA_OCSP_CERT: - ret = ssh_x509_validate4cert(cert, x509store); + ret = ssh_ocsp_validate4cert(cert, x509store); break; case SSHVA_OCSP_SPEC: conn = ssh_ocsp_conn_new(va.responder_url); if (conn != NULL) { - ret = ssh_ocsp_validate(cert, x509store, conn); + ret = ssh_ocsp_validate2(cert, x509store, conn); ssh_ocsp_conn_free(&conn); } break; } return(ret); -#endif /*def SSH_OCSP_ENABLED*/ } diff -ruN openssh-3.9p1+x509h/ssh-x509.c openssh-3.9p1+x509-5.1/ssh-x509.c --- openssh-3.9p1+x509h/ssh-x509.c 2004-02-22 18:34:20.000000000 +0200 +++ openssh-3.9p1+x509-5.1/ssh-x509.c 2004-11-07 11:50:38.000000000 +0200 @@ -21,6 +21,7 @@ * (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 "ssh-x509.h" #include "log.h" #include @@ -31,6 +32,10 @@ #include "x509store.h" #include "compat.h" +int (*pssh_x509cert_check)(X509 *_cert) = NULL; +int ssh_X509_NAME_cmp(X509_NAME *_a, X509_NAME *_b); + + static char* openssl_errormsg(char *buf, size_t len) { ERR_error_string_n(ERR_get_error(), buf, len); @@ -291,7 +296,7 @@ BIO_write(mbio, blob, blen); BIO_flush(mbio); - debug3("x509key_from_blob:We have %d bytes available in BIO", BIO_pending(mbio)); + debug3("x509key_from_blob: We have %d bytes available in BIO", BIO_pending(mbio)); { /* read X509 certificate from BIO data */ X509* x509 = NULL; @@ -357,8 +362,8 @@ if (!x509key_check("x509key_subject", key)) return(buf); - buf = xmalloc(X509KEY_SUBJECT_MAXLEN); /*fatal on error*/ - X509_NAME_oneline(X509_get_subject_name(key->x509), buf, X509KEY_SUBJECT_MAXLEN); + buf = xmalloc(X509_NAME_MAXLEN); /*fatal on error*/ + X509_NAME_oneline(X509_get_subject_name(key->x509), buf, X509_NAME_MAXLEN); return(buf); } @@ -398,7 +403,7 @@ int x509key_write_subject(const Key *key, FILE *f) { BIO *out; - char buf[X509KEY_SUBJECT_MAXLEN]; + char buf[X509_NAME_MAXLEN]; if (!x509key_check("x509key_write_subject", key)) return(0); @@ -448,7 +453,7 @@ x509key_save_cert(FILE *fp, X509 *x509) { int ret = 0; BIO *out; - char buf[X509KEY_SUBJECT_MAXLEN]; + char buf[X509_NAME_MAXLEN]; out = BIO_new_fp(fp, BIO_NOCLOSE); if (out == NULL) return(0); @@ -597,11 +602,26 @@ * OpenSSL functions X509_NAME_cmp check nids order in X509_NAME. * i.e. X509_NAME{"/C=XX/O=YY"} is not equal to X509_NAME{"/O=YY/C=XX"} */ -static int +int ssh_X509_NAME_cmp(X509_NAME *_a, X509_NAME *_b) { int k, n; X509_NAME *b; +#if 1 + /*XXX: to call fatal when _a or _b is NULL or to use next*/ + if (_a == NULL) { + return((_b == NULL) ? 0 : 1); + } else { + if (_b == NULL) return(-1); + } +#else + if (_a == NULL) { + fatal("ssh_X509_NAME_cmp: first name is NULL"); + } + if (_b == NULL) { + fatal("ssh_X509_NAME_cmp: second name is NULL"); + } +#endif k = sk_X509_NAME_ENTRY_num(_a->entries); n = sk_X509_NAME_ENTRY_num(_b->entries); @@ -624,8 +644,8 @@ nid = OBJ_obj2nid(neA->object); loc = X509_NAME_get_index_by_NID(b, nid, -1); if (loc < 0) { - char buf1[X509KEY_SUBJECT_MAXLEN]; - char buf2[X509KEY_SUBJECT_MAXLEN]; + char buf1[X509_NAME_MAXLEN]; + char buf2[X509_NAME_MAXLEN]; X509_NAME_oneline(_a, buf1, sizeof(buf1)); X509_NAME_oneline(_b, buf2, sizeof(buf2)); @@ -947,7 +967,12 @@ sigblob = NULL; } if (ret > 0) { - ret = ssh_x509cert_check(key->x509); + if (pssh_x509cert_check != NULL) { + ret = pssh_x509cert_check(key->x509); + } else { + error("ssh_x509_verify: pssh_x509cert_check is NULL"); + ret = -1; + } } ret = ret > 0 ? 1 : (ret < 0 ? -1 : 0); debug3("ssh_x509_verify: return %d", ret); diff -ruN openssh-3.9p1+x509h/ssh-x509.h openssh-3.9p1+x509-5.1/ssh-x509.h --- openssh-3.9p1+x509h/ssh-x509.h 2004-02-22 18:24:36.000000000 +0200 +++ openssh-3.9p1+x509-5.1/ssh-x509.h 2004-11-07 11:52:52.000000000 +0200 @@ -24,7 +24,6 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ - #include "includes.h" #include "key.h" #include "buffer.h" @@ -41,7 +40,6 @@ Key* x509key_from_blob(const u_char *blob, int blen); int x509key_to_blob(const Key *key, Buffer *b); -#define X509KEY_SUBJECT_MAXLEN 512 char* x509key_subject(const Key *key); /* @@ -59,7 +57,6 @@ int x509key_save_pem(FILE *fp, const Key *key, const EVP_CIPHER *cipher, u_char *passphrase, int len); - #ifndef SSH_X509STORE_DISABLED int ssh_x509_equal(const Key *a, const Key *b); #endif /*ndef SSH_X509STORE_DISABLED*/ diff -ruN openssh-3.9p1+x509h/tests/CA/1-cre_cadb.sh openssh-3.9p1+x509-5.1/tests/CA/1-cre_cadb.sh --- openssh-3.9p1+x509h/tests/CA/1-cre_cadb.sh 2004-03-20 12:50:15.000000000 +0200 +++ openssh-3.9p1+x509-5.1/tests/CA/1-cre_cadb.sh 2004-10-30 00:17:59.000000000 +0300 @@ -159,12 +159,15 @@ # Key usage: this is typical for a CA certificate. However since it will # prevent it being used as an test self-signed certificate it is best # left out by default. -# Since we generate OpenSSH test CA we comment next line. -#keyUsage = cRLSign, keyCertSign +# Since we verify CRL signatures cRLSign must present +keyUsage = keyCertSign, cRLSign # PKIX recommendations harmless if included in all certificates. subjectKeyIdentifier = hash authorityKeyIdentifier = keyid:always,issuer:always + +# To test CRL presence this extension should exist +crlDistributionPoints = URI:attribute_only_exist EOF diff -ruN openssh-3.9p1+x509h/tests/CA/5-cre_ldap.sh openssh-3.9p1+x509-5.1/tests/CA/5-cre_ldap.sh --- openssh-3.9p1+x509h/tests/CA/5-cre_ldap.sh 1970-01-01 02:00:00.000000000 +0200 +++ openssh-3.9p1+x509-5.1/tests/CA/5-cre_ldap.sh 2004-11-08 20:36:45.000000000 +0200 @@ -0,0 +1,169 @@ +#!/bin/sh +# Copyright (c) 2004 Roumen Petrov, Sofia, Bulgaria +# All rights reserved. +# +# Redistribution and use of this script, with or without modification, is +# permitted provided that the following conditions are met: +# +# 1. Redistributions of this script must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. +# +# DESCRIPTION: Create LDAP files. +# + +CWD=`pwd` +SCRIPTDIR=`echo $0 | sed 's/5-cre_ldap.sh$//'` +. "${SCRIPTDIR}shell.rc" +. "${SCRIPTDIR}functions" +. "${SCRIPTDIR}config" +. ./env + + +if test ! -d ldap/data; then + mkdir -p ldap/data || exit $? +fi + + +# === +cre_base_ldif() { +( + cat < ldap/base.ldif +} + + +# === +cre_ca_ldif() { +( + for type in ${SSH_SIGN_TYPES}; do + N="${CAKEY_PREFIX}-${type}.crt" + if test ! -f "ldap/${N}.der"; then + ${OPENSSL} x509 \ + -in "${SSH_CACERTDIR}/${N}".pem \ + -out "ldap/${N}.der" -outform DER \ + || exit $? + fi + + N="${CAKEY_PREFIX}-${type}.crl" + if test ! -f "ldap/${N}.der"; then + ${OPENSSL} crl \ + -in "${SSH_CACRLDIR}/${N}".pem \ + -out "ldap/${N}.der" -outform DER \ + || exit $? + fi + done +) || return $? + +( + for type in ${SSH_SIGN_TYPES}; do + cat < ldap/ca.ldif +} + + +# === +cre_slapdconf () { +( + cat < ldap/slapd.conf.tmpl + +} + + +# === + +cre_base_ldif && +cre_ca_ldif && +cre_slapdconf && +: ; retval=$? + +show_status $retval "${extd}Creating${norm} ${warn}LDAP${norm} ${attn}files${norm}" diff -ruN openssh-3.9p1+x509h/tests/CA/config openssh-3.9p1+x509-5.1/tests/CA/config --- openssh-3.9p1+x509h/tests/CA/config 2004-03-20 12:02:17.000000000 +0200 +++ openssh-3.9p1+x509-5.1/tests/CA/config 2004-11-11 00:14:50.000000000 +0200 @@ -65,7 +65,9 @@ dn_auth_path agent crl + alg ocsp + by_ldap " fi @@ -162,3 +164,13 @@ # OpenSSL OCSP responder don't use SO_REUSEADDR :-(, so ocsp tests # must wait socket to close. SSH_OPENSLL_OCSP_TMOUT=60 + +# === LDAP: +#SSH_LDAP_DB=bdb +SSH_LDAP_DB=ldbm +SSH_LDAP_DC="dc=example,dc=com" + +if test -z "${LDAPD_PORT}"; then + LDAPD_PORT=20389 +fi +LDAPD_URL="ldap://${SSHD_LISTENADDRESS}:${LDAPD_PORT}" diff -ruN openssh-3.9p1+x509h/tests/CA/env.in openssh-3.9p1+x509-5.1/tests/CA/env.in --- openssh-3.9p1+x509h/tests/CA/env.in 1970-01-01 02:00:00.000000000 +0200 +++ openssh-3.9p1+x509-5.1/tests/CA/env.in 2004-10-29 22:52:46.000000000 +0300 @@ -0,0 +1,4 @@ +# LDAP environment: +@LDAP_ON@LDAP_SYSCONFDIR="@LDAP_SYSCONFDIR@" +@LDAP_ON@LDAP_LIBEXECDIR="@LDAP_LIBEXECDIR@" +@LDAP_ON@LDAP_BINDIR="@LDAP_BINDIR@" diff -ruN openssh-3.9p1+x509h/tests/CA/functions openssh-3.9p1+x509-5.1/tests/CA/functions --- openssh-3.9p1+x509h/tests/CA/functions 2004-02-17 21:23:33.000000000 +0200 +++ openssh-3.9p1+x509-5.1/tests/CA/functions 2004-10-02 00:22:16.000000000 +0300 @@ -238,7 +238,7 @@ retval=0 -#bash bug or ?: when commands are on only one line retval is always zero :-/ !!! +#SHELL bug or ?: when we assign command result to "local xxx=..." retval is always zero :-/ !!! #unix sh don't like local :-) # local subject=`"${OPENSSL}" x509 -noout -subject -in "${identity_file}" $*`; retval=$? subject=`"${OPENSSL}" x509 -noout -subject -in "${identity_file}" $* 2>/dev/null`; retval=$? diff -ruN openssh-3.9p1+x509h/tests/CA/Makefile.in openssh-3.9p1+x509-5.1/tests/CA/Makefile.in --- openssh-3.9p1+x509h/tests/CA/Makefile.in 2004-03-09 21:37:04.000000000 +0200 +++ openssh-3.9p1+x509-5.1/tests/CA/Makefile.in 2004-11-07 10:49:37.000000000 +0200 @@ -6,7 +6,7 @@ all: -clean: +clean: ldap_clean rm -f testhostkey_* rm -f testid_* rm -f testocsp_* @@ -17,11 +17,12 @@ rm -f sshd_x509.log distclean: clean + rm -f env rm -f Makefile # === -check-certs: ca_files hostkeys identities ocsp_certs crl_files +check-certs: ca_files hostkeys identities ocsp_certs crl_files ldap_files @echo $(SHELL) $(srcdir)/openssh_tests.sh @@ -117,3 +118,16 @@ ca-test/catest-bundle.crl: testid_rsa-rsa_md5 testid_dsa-rsa_md5 @echo $(SHELL) $(srcdir)/4-cre_crls.sh + +# === +@LDAP_OFF@ldap_files: +@LDAP_ON@ldap_files: ldap/slapd.conf.tmpl + +@LDAP_ON@ldap/slapd.conf.tmpl: +@LDAP_ON@ @echo +@LDAP_ON@ $(SHELL) $(srcdir)/5-cre_ldap.sh + +@LDAP_OFF@ldap_clean: +@LDAP_ON@ldap_clean: +@LDAP_ON@ rm -f ldap_setup.log +@LDAP_ON@ rm -fr ldap diff -ruN openssh-3.9p1+x509h/tests/CA/openssh_tests.sh openssh-3.9p1+x509-5.1/tests/CA/openssh_tests.sh --- openssh-3.9p1+x509h/tests/CA/openssh_tests.sh 2004-03-20 11:42:40.000000000 +0200 +++ openssh-3.9p1+x509-5.1/tests/CA/openssh_tests.sh 2004-11-11 00:15:10.000000000 +0200 @@ -28,6 +28,7 @@ . "${SCRIPTDIR}shell.rc" . "${SCRIPTDIR}functions" . "${SCRIPTDIR}config" +. "./env" test "x$TEST_SSH_SSH" = "x" && { echo "${warn}Please define ${attn}TEST_SSH_SSH${norm}" ; exit 1; } test "x$TEST_SSH_SSHD" = "x" && { echo "${warn}Please define ${attn}TEST_SSH_SSHD${norm}" ; exit 1; } @@ -79,6 +80,7 @@ cat > "$SSHD_CFG" < /dev/null; then + SSH_LDAP_ENABLED="no" +else + SSH_LDAP_ENABLED="yes" +fi if grep 'Unsupported.*VAType' "${SSHD_LOG}" > /dev/null; then SSH_OCSP_ENABLED="no" else @@ -102,6 +109,10 @@ -e 's|dn_auth_path||g' \ -e 's|crl||g'` fi +echo SSH_LDAP_ENABLED=${SSH_LDAP_ENABLED} +if test "x${SSH_LDAP_ENABLED}" = "xno"; then + SSH_X509TESTS=`echo "${SSH_X509TESTS}" | sed -e 's|by_ldap||g'` +fi echo SSH_OCSP_ENABLED=${SSH_OCSP_ENABLED} if test "x${SSH_OCSP_ENABLED}" = "xno"; then SSH_X509TESTS=`echo "${SSH_X509TESTS}" | sed -e 's|ocsp||g'` @@ -246,7 +257,7 @@ msg="OpenSSH Certificate TeSt-${1}" sshopts="" - #sshopts="${sshopts} -v -v -v + #sshopts="${sshopts} -v -v -v" test -n "$2" && sshopts="${sshopts} -i $2" #assignment to variable "identity_file" crash ksh :-( #identity_file="value_without_significance" @@ -302,20 +313,18 @@ # === do_all () { - printf '%s' "" > "${AUTHORIZEDKEYSFILE}" + create_empty_file "${AUTHORIZEDKEYSFILE}" && chmod 644 "${AUTHORIZEDKEYSFILE}" || return $? - printf '%s' "" > "${SSHD_LOG}" - if test ! -f "${TEST_SSHD_HOSTKEY}"; then - "$TEST_SSH_SSHKEYGEN" -t rsa -f "${TEST_SSHD_HOSTKEY}" -N "" - fi + create_empty_file "${SSHD_LOG}" || return $? + if test ! -f "${TEST_SSHD_HOSTKEY}.pub"; then echo "${warn}Public host file ${attn}${TEST_SSHD_HOSTKEY}.pub${warn} not found !${norm}" return 3 fi ( printf '%s' "${SSHD_LISTENADDRESS} " cat "${TEST_SSHD_HOSTKEY}.pub" - ) > "${USERKNOWNHOSTSFILE}" + ) > "${USERKNOWNHOSTSFILE}" && chmod 644 "${USERKNOWNHOSTSFILE}" || return $? # call the test scripts diff -ruN openssh-3.9p1+x509h/tests/CA/test-alg.sh.inc openssh-3.9p1+x509-5.1/tests/CA/test-alg.sh.inc --- openssh-3.9p1+x509h/tests/CA/test-alg.sh.inc 1970-01-01 02:00:00.000000000 +0200 +++ openssh-3.9p1+x509-5.1/tests/CA/test-alg.sh.inc 2004-10-17 16:17:12.000000000 +0300 @@ -0,0 +1,139 @@ +# +# Copyright (c) 2004 Roumen Petrov, Sofia, Bulgaria +# All rights reserved. +# +# Redistribution and use of this script, with or without modification, is +# permitted provided that the following conditions are met: +# +# 1. Redistributions of this script must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. +# +# DESCRIPTION: Test OpenSSH client authentication: +# - "IdentityFile" contain private key and optional x509 certificate; +# - "AuthorizedKeysFile" contain certificate BLOB. +# - server accept different publickey algorithms. +# Note that "Host-Based Authentication" we cannot test without to install. +# + + +# === +#env. vars: +# alg +testAlg () { + printSeparator + echo " - only ${attn}${alg}${norm} algorithm" + + creTestSSHDcfgFile + if test "x${SSH_X509STORE_DISABLED}" != "xyes"; then + cat >> "$SSHD_CFG" <> "$SSHD_CFG" </dev/null > "${AUTHORIZEDKEYSFILE}" || exit $? + + if test -n "$must_fail"; then + typemsg="${identity_file} ${warn}!${norm}" + else + typemsg="${identity_file}" + fi + runTest "${typemsg}" \ + "${identity_file}" "" "$must_fail" || exit $? + + for type in ${SSH_SIGN_TYPES}; do + if test -n "$withcert"; then + must_fail="" + if test "X$alg" = "Xx509v3-sign-rsa"; then + test "$keytype" = "rsa" || must_fail="yes" + else + test "$keytype" = "dsa" || must_fail="yes" + fi + else + must_fail="yes" + fi + + identity_file="${SSH_CLIENTKEY}-${type}" + "$TEST_SSH_SSHKEYGEN" -f "${identity_file}" -y 2>/dev/null > "${AUTHORIZEDKEYSFILE}" || exit $? + + if test -n "$must_fail"; then + typemsg="${identity_file} ${warn}!${norm}" + else + typemsg="${identity_file}" + fi + runTest "${typemsg}" \ + "${identity_file}" "" "$must_fail" || exit $? + done + done + ); retval=$? + killSSHdaemon + + return $retval +} + + +# === + +do_test () { + retval=0 + if test "x${SSH_X509STORE_DISABLED}" = "xyes"; then + echo "* ${extd}with different publickey ${attn}algorithms${norm}:" + else + echo "* ${extd}against ${attn}CACertificateFile${norm} and different publickey ${attn}algorithms${norm}:" + fi + + for alg in \ + "ssh-rsa" \ + "ssh-dss" \ + "x509v3-sign-rsa" \ + "x509v3-sign-dss" \ + ; do + testAlg; retval=$? + if test $retval -ne 0; then + break + fi + done + return $retval +} diff -ruN openssh-3.9p1+x509h/tests/CA/test-by_ldap.sh.inc openssh-3.9p1+x509-5.1/tests/CA/test-by_ldap.sh.inc --- openssh-3.9p1+x509h/tests/CA/test-by_ldap.sh.inc 1970-01-01 02:00:00.000000000 +0200 +++ openssh-3.9p1+x509-5.1/tests/CA/test-by_ldap.sh.inc 2004-11-07 22:52:06.000000000 +0200 @@ -0,0 +1,215 @@ +# +# Copyright (c) 2004 Roumen Petrov, Sofia, Bulgaria +# All rights reserved. +# +# Redistribution and use of this script, with or without modification, is +# permitted provided that the following conditions are met: +# +# 1. Redistributions of this script must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. +# +# DESCRIPTION: Test OpenSSH client authentication: +# - "IdentityFile" contain private key and x509 certificate; +# - "AuthorizedKeysFile" contain certificate Subject; +# - authorization against: +# - LDAP, without CRL file and hash-dir +# + + +LDAP_SETUP_LOG="${CWD}/ldap_setup.log" +LDAPD_PID="${CWD}/slapd.pid" +LDAPD_ARGS="${CWD}/slapd.args" +LDAPD_CFG="${CWD}/slapd.conf" + +if test -z "${LDAP_BINDIR}"; then + LDAPADD=ldapadd +else + LDAPADD="${LDAP_BINDIR}/ldapadd" +fi + + +# === +#args: +# $1 - info. message for valid cert. +# $2 - request valid cert. to fail flag +# $3 - info. message for revoked cert. +# $4 - request revoked cert. to fail flag +test_all_keys () { + for type in ${SSH_SIGN_TYPES}; do + for SSH_CLIENTKEY in ${TEST_SSH_CLIENTKEYS}; do + identity_file="${SSH_CLIENTKEY}-${type}" + creX509AuthorizedKeysFile "${identity_file}" && + runTest "${identity_file}" \ + "${identity_file}" "$1" "$2" || return $? + + identity_file="${SSH_CLIENTKEY}-${type}-revoked" + creX509AuthorizedKeysFile "${identity_file}" && + runTest "${identity_file}" \ + "${identity_file}" "$3" "$4" || return $? + done + done + return 0 +} + + +# === +creTestLDAPDcfgFile() { +( + cat < ${LDAPD_CFG} + +} + + +# === +runLDAPdaemon() { + if test -f "${LDAPD_PID}"; then + echo "${warn}slapd pid file exist!${norm}" >&2 + fi + + printf ' %s' "starting ${extd}LDAP${norm} server on ${attn}${LDAPD_URL}${norm}" + #for errors check syslog files(LOCAL4 facility) + $SUDO "${LDAP_LIBEXECDIR}/slapd" \ + -f "${LDAPD_CFG}" \ + -h "${LDAPD_URL}" \ + > /dev/null 2>&1 + + sleep 2 + K=0 + while test $K -le 5; do + if test -f "${LDAPD_PID}"; then + break + fi + sleep 1 + K=`expr $K + 1` + done + + test -r "${LDAPD_PID}"; show_status $? + if test ! -r "${LDAPD_PID}"; then + printf "${warn}cannot start slapd:${norm} " >&2 + error_file_not_readable "${LDAPD_PID}" + return 33 + fi + return 0 +} + + +killLDAPdaemon() { +( + $SUDO kill `cat "${LDAPD_PID}" 2>/dev/null` > /dev/null 2>&1 + K=0 + while test $K -le 9; do + if test ! -f "${LDAPD_PID}"; then + break + fi + sleep 1 + K=`expr $K + 1` + done + if test -f "${LDAPD_PID}"; then + $SUDO kill -9 `cat "${LDAPD_PID}" 2>/dev/null` > /dev/null 2>&1 + sleep 1 + $SUDO rm -f "${LDAPD_PID}" > /dev/null 2>&1 + $SUDO rm -f "${LDAPD_ARGS}" > /dev/null 2>&1 + fi + rm -f "${LDAPD_CFG}" + exit 0 +) +} + + +initLDAPdb() { + create_empty_file "${LDAP_SETUP_LOG}" || return $? + + "${LDAPADD}" \ + -x -w secret -D "cn=Manager,${SSH_LDAP_DC}" \ + -H "${LDAPD_URL}" \ + -f "${CWD}/ldap/base.ldif" \ + >> "${LDAP_SETUP_LOG}" 2>&1 || return $? + + "${LDAPADD}" \ + -x -w secret -D "cn=Manager,${SSH_LDAP_DC}" \ + -H "${LDAPD_URL}" \ + -f "${CWD}/ldap/ca.ldif" \ + >> "${LDAP_SETUP_LOG}" 2>&1 || return $? + + return 0 +} + + +# === +# $1 - LDAP version +testLDAP() { + printSeparator + echo "Begin test with LDAP ${extd}version${norm} ${attn}$1${norm}" + + creTestLDAPDcfgFile + creTestSSHDcfgFile + +#openssh config parser limitation +SSH_CONF_LDAP_DC=`echo ${SSH_LDAP_DC} | sed -e 's|=|%3D|g'` + cat >> "$SSHD_CFG" <> "$SSHD_CFG" <> "$SSHD_CFG" <> "$SSHD_CFG" <> "$SSHD_CFG" <> "$SSHD_CFG" < + + +/* ================================================================== */ +/* ERRORS */ +#ifndef OPENSSL_NO_ERR +static ERR_STRING_DATA X509byLDAP_str_functs[] = { + { ERR_PACK(0, X509byLDAP_F_LOOKUPCRTL, 0) , "LOOKUPCRTL" }, + { ERR_PACK(0, X509byLDAP_F_LDAPHOST_NEW, 0) , "LDAPHOST_NEW" }, + { ERR_PACK(0, X509byLDAP_F_SET_PROTOCOL, 0) , "SET_PROTOCOL" }, + { ERR_PACK(0, X509byLDAP_F_RESULT2STORE, 0) , "RESULT2STORE" }, + { ERR_PACK(0, X509byLDAP_F_GET_BY_SUBJECT, 0) , "GET_BY_SUBJECT" }, + { 0, NULL } +}; + + +static ERR_STRING_DATA X509byLDAP_str_reasons[] = { + { X509byLDAP_R_INVALID_CRTLCMD , "invalid control command" }, + { X509byLDAP_R_NOT_LDAP_URL , "not ldap url" }, + { X509byLDAP_R_INVALID_URL , "invalid ldap url" }, + { X509byLDAP_R_INITIALIZATION_ERROR , "ldap initialization error" }, + { X509byLDAP_R_UNABLE_TO_GET_PROTOCOL_VERSION , "unable to get ldap protocol version" }, + { X509byLDAP_R_UNABLE_TO_SET_PROTOCOL_VERSION , "unable to set ldap protocol version" }, + { X509byLDAP_R_UNABLE_TO_COUNT_ENTRIES , "unable to count ldap entries" }, + { X509byLDAP_R_WRONG_LOOKUP_TYPE , "wrong lookup type" }, + { X509byLDAP_R_UNABLE_TO_GET_FILTER , "unable to get ldap filter" }, + { X509byLDAP_R_UNABLE_TO_BIND , "unable to bind to ldap server" }, + { X509byLDAP_R_SEARCH_FAIL , "search failure" }, + { 0, NULL } +}; +#endif /*ndef OPENSSL_NO_ERR*/ + + +void +ERR_load_X509byLDAP_strings(void) { + static int init = 1; + + if (init) { + init = 0; +#ifndef OPENSSL_NO_ERR + ERR_load_strings(ERR_LIB_X509byLDAP, X509byLDAP_str_functs); + ERR_load_strings(ERR_LIB_X509byLDAP, X509byLDAP_str_reasons); +#endif + } +} + + +static char* +ldap_errormsg(char *buf, size_t len, int err) { + snprintf(buf, len, "ldaperror=0x%x(%.256s)", err, ldap_err2string(err)); + return(buf); +} + + +static void +openssl_add_ldap_error(int err) { + char buf[512]; + ERR_add_error_data(1, ldap_errormsg(buf, sizeof(buf), err)); +} + + + +/* ================================================================== */ +/* LOOKUP by LDAP */ + +static const char ATTR_CACERT[] = "cACertificate"; +static const char ATTR_CACRL[] = "certificateRevocationList"; + +typedef struct ldaphost_s ldaphost; +struct ldaphost_s { + char *url; + char *binddn; + char *bindpw; + LDAPURLDesc *ldapurl; + LDAP *ld; + ldaphost *next; +}; + + +static ldaphost* ldaphost_new(const char *url); +static void ldaphost_free(ldaphost *p); + + +static int ldaplookup_ctrl(X509_LOOKUP *ctx, int cmd, const char *argp, long argl, char **ret); +static int ldaplookup_new(X509_LOOKUP *ctx); +static void ldaplookup_free(X509_LOOKUP *ctx); +static int ldaplookup_init(X509_LOOKUP *ctx); +static int ldaplookup_shutdown(X509_LOOKUP *ctx); +static int ldaplookup_by_subject(X509_LOOKUP *ctx, int type, X509_NAME *name, X509_OBJECT *ret); + +static int ldaplookup_add_search(X509_LOOKUP *ctx, const char *url); +static int ldaplookup_set_protocol(X509_LOOKUP *ctx, const char *ver); + + +X509_LOOKUP_METHOD x509_ldap_lookup = { + "Load certs and crls from LDAP server", + ldaplookup_new, /* new */ + ldaplookup_free, /* free */ + ldaplookup_init, /* init */ + ldaplookup_shutdown, /* shutdown */ + ldaplookup_ctrl, /* ctrl */ + ldaplookup_by_subject, /* get_by_subject */ + NULL, /* get_by_issuer_serial */ + NULL, /* get_by_fingerprint */ + NULL, /* get_by_alias */ +}; + + +X509_LOOKUP_METHOD* +X509_LOOKUP_ldap(void) { + return(&x509_ldap_lookup); +} + + +static int +ldaplookup_ctrl(X509_LOOKUP *ctx, int cmd, const char *argc, long argl, char **retp) { + int ret = 0; + +#ifdef TRACE_BY_LDAP +fprintf(stderr, "TRACE_BY_LDAP ldaplookup_ctrl: cmd=%d, argc=%s\n", cmd, argc); +#endif + switch (cmd) { + case X509_L_LDAP_HOST: + ret = ldaplookup_add_search(ctx, argc); + break; + case X509_L_LDAP_VERSION: + ret = ldaplookup_set_protocol(ctx, argc); + break; + default: + X509byLDAPerr(X509byLDAP_F_LOOKUPCRTL, X509byLDAP_R_INVALID_CRTLCMD); + break; + } + return(ret); +} + + +static int +ldaplookup_new(X509_LOOKUP *ctx) { +#ifdef TRACE_BY_LDAP +fprintf(stderr, "TRACE_BY_LDAP ldaplookup_new:\n"); +#endif + if (ctx == NULL) + return(0); + + ctx->method_data = NULL; + return(1); +} + + +static void +ldaplookup_free(X509_LOOKUP *ctx) { + ldaphost *p; +#ifdef TRACE_BY_LDAP +fprintf(stderr, "TRACE_BY_LDAP ldaplookup_free:\n"); +#endif + + if (ctx == NULL) + return; + + p = (ldaphost*) ctx->method_data; + while (p != NULL) { + ldaphost *q = p; + p = p->next; + ldaphost_free(q); + } +} + + +static int +ldaplookup_init(X509_LOOKUP *ctx) { +#ifdef TRACE_BY_LDAP +fprintf(stderr, "TRACE_BY_LDAP ldaplookup_init:\n"); +#endif + return(1); +} + + +static int +ldaplookup_shutdown(X509_LOOKUP *ctx) { +#ifdef TRACE_BY_LDAP +fprintf(stderr, "TRACE_BY_LDAP ldaplookup_shutdown:\n"); +#endif + return(1); +} + + +static ldaphost* +ldaphost_new(const char *url) { + ldaphost *p; + int ret; + + p = OPENSSL_malloc(sizeof(ldaphost)); + if (p == NULL) return(NULL); + + memset(p, 0, sizeof(ldaphost)); + + p->url = OPENSSL_malloc(strlen(url) + 1); + if (p->url == NULL) goto error; + strcpy(p->url, url); + + /*ldap://hostport/dn[?attrs[?scope[?filter[?exts]]]] */ + ret = ldap_is_ldap_url(url); + if (ret < 0) { + X509byLDAPerr(X509byLDAP_F_LDAPHOST_NEW, X509byLDAP_R_NOT_LDAP_URL); + goto error; + } + + ret = ldap_url_parse(url, &p->ldapurl); + if (ret != 0) { + X509byLDAPerr(X509byLDAP_F_LDAPHOST_NEW, X509byLDAP_R_INVALID_URL); + openssl_add_ldap_error(ret); + goto error; + } +#ifdef TRACE_BY_LDAP +fprintf(stderr, "TRACE_BY_LDAP ldaphost_new: ldap_url_desc2str=%s\n", ldap_url_desc2str(p->ldapurl)); +fprintf(stderr, "TRACE_BY_LDAP ldaphost_new: ldapurl->%s://%s:%d\n", p->ldapurl->lud_scheme, p->ldapurl->lud_host, p->ldapurl->lud_port); +#endif + + /* open ldap connection */ + p->ld = ldap_init(p->ldapurl->lud_host, p->ldapurl->lud_port); + if(p->ld == NULL) { + X509byLDAPerr(X509byLDAP_F_LDAPHOST_NEW, X509byLDAP_R_INITIALIZATION_ERROR); + goto error; + } + + { + int version = -1; + + ret = ldap_get_option(p->ld, LDAP_OPT_PROTOCOL_VERSION, &version); + if (ret != LDAP_OPT_SUCCESS) { + X509byLDAPerr(X509byLDAP_F_LDAPHOST_NEW, X509byLDAP_R_UNABLE_TO_GET_PROTOCOL_VERSION ); + goto error; + } +#ifdef TRACE_BY_LDAP +fprintf(stderr, "TRACE_BY_LDAP ldaphost_new: using ldap v%d protocol\n", version); +#endif + } + + return(p); +error: + ldaphost_free(p); + return(NULL); +} + + +static void +ldaphost_free(ldaphost *p) { +#ifdef TRACE_BY_LDAP +fprintf(stderr, "TRACE_BY_LDAP ldaphost_free:\n"); +#endif + if (p == NULL) return; + if (p->url != NULL) OPENSSL_free(p->url); + if (p->binddn != NULL) OPENSSL_free(p->binddn); + if (p->bindpw != NULL) OPENSSL_free(p->bindpw); + if (p->ldapurl != NULL) { + ldap_free_urldesc(p->ldapurl); + p->ldapurl = NULL; + } + if (p->ld != NULL) { + /* how to free ld ???*/ + p->ld = NULL; + } + OPENSSL_free(p); +} + + +static int/*bool*/ +ldaplookup_add_search(X509_LOOKUP *ctx, const char *url) { + ldaphost *p, *q; + + if (ctx == NULL) return(0); + if (url == NULL) return(0); + + q = ldaphost_new(url); + if (q == NULL) return(0); + + p = (ldaphost*) ctx->method_data; + if (p == NULL) { + ctx->method_data = (void*) q; + return(1); + } + + for(; p->next != NULL; p = p->next) { + /*find list end*/ + } + p->next = q; + + return(1); +} + + +static int/*bool*/ +ldaplookup_set_protocol(X509_LOOKUP *ctx, const char *ver) { + ldaphost *p; + char *q = NULL; + int n; + +#ifdef TRACE_BY_LDAP +fprintf(stderr, "TRACE_BY_LDAP ldaplookup_set_protocol(..., %s)\n", ver); +#endif + if (ctx == NULL) return(0); + if (ver == NULL) return(0); + + p = (ldaphost*) ctx->method_data; + if (p == NULL) return(0); + + n = (int) strtol(ver, &q, 10); + if (*q != '\0') return(0); + if ((n < LDAP_VERSION_MIN) || (n > LDAP_VERSION_MAX)) return(0); + + for(; p->next != NULL; p = p->next) { + /*find list end*/ + } +#ifdef TRACE_BY_LDAP +fprintf(stderr, "TRACE_BY_LDAP ldaplookup_set_protocol(...): ver=%d\n", n); +#endif + { + int ret; + const int version = n; + + ret = ldap_set_option(p->ld, LDAP_OPT_PROTOCOL_VERSION, &version); + if (ret != LDAP_OPT_SUCCESS) { + X509byLDAPerr(X509byLDAP_F_SET_PROTOCOL, X509byLDAP_R_UNABLE_TO_SET_PROTOCOL_VERSION); + openssl_add_ldap_error(ret); + return(0); + } + } + + return(1); +} + + +static char* +ldaplookup_filter(X509_NAME *name, const char *attribute) { + char *p = NULL; + int k; + BIO *mbio; + + mbio = BIO_new(BIO_s_mem()); + if (mbio == NULL) return(NULL); + + BIO_puts(mbio, "(&"); + + k = sk_X509_NAME_ENTRY_num(name->entries); + for (--k; k >= 0; k--) { + X509_NAME_ENTRY *ne; + ASN1_STRING *nv; + int nid; + + ne = sk_X509_NAME_ENTRY_value(name->entries, k); + nid = OBJ_obj2nid(ne->object); + + if ( + (nid != NID_organizationName) && + (nid != NID_organizationalUnitName) && + (nid != NID_commonName) + ) continue; + + BIO_puts(mbio, "("); + BIO_puts(mbio, OBJ_nid2sn(nid)); + BIO_puts(mbio, "="); + nv = ne->value; + /* + TODO: + we must escape '(' and ')' symbols and might to check for other symbols (>=128?) + BIO_puts(mbio, M_ASN1_STRING_data(nv)); + */ + { /* escape '(' and ')' */ + p = (char*)M_ASN1_STRING_data(nv); + for (; *p; p++) { + if ((*p == '(') || (*p == ')')) + BIO_write(mbio, "\\", 1); + BIO_write(mbio, p, 1); + } + } + BIO_puts(mbio, ")"); + } + + BIO_puts(mbio, "("); + BIO_puts(mbio, attribute); + BIO_puts(mbio, "=*)"); + + BIO_puts(mbio, ")"); + BIO_flush(mbio); + + k = BIO_pending(mbio); + p = OPENSSL_malloc(k + 1); + if (p == NULL) goto done; + + k = BIO_read(mbio, p, k); + p[k] = '\0'; + +done: + BIO_free_all(mbio); + return(p); +} + + +static int/*bool*/ +ldaplookup_check_attr( + int type, + const char *attr +) { + if (type == X509_LU_X509) + return(strncmp(attr, ATTR_CACERT, sizeof(ATTR_CACERT)) != 0); + + if (type == X509_LU_CRL) + return(strncmp(attr, ATTR_CACRL, sizeof(ATTR_CACRL)) != 0); + + return(0); +} + + +/* + * We will put into store X509 object from passed data in buffer only + * when object name match passed. To compare both names we use our + * method "ssh_X509_NAME_cmp"(it is more general). + */ +static int/*bool*/ +ldaplookup_data2store( + int type, + X509_NAME* name, + void* buf, + int len, + X509_STORE* store +) { + int ok = 0; + BIO *mbio; + + if (name == NULL) return(0); + if (buf == NULL) return(0); + if (len <= 0) return(0); + if (store == NULL) return(0); + + mbio = BIO_new_mem_buf(buf, len); + if (mbio == NULL) return(0); + + switch (type) { + case X509_LU_X509: { + X509 *x509 = d2i_X509_bio(mbio, NULL); + if(x509 == NULL) goto exit; + + /*This is correct since lookup method is by subject*/ + if (ssh_X509_NAME_cmp(name, X509_get_subject_name(x509)) != 0) goto exit; + + ok = X509_STORE_add_cert(store, x509); + } break; + case X509_LU_CRL: { + X509_CRL *crl = d2i_X509_CRL_bio(mbio, NULL); + if(crl == NULL) goto exit; + + if (ssh_X509_NAME_cmp(name, X509_CRL_get_issuer(crl)) != 0) goto exit; + + ok = X509_STORE_add_crl(store, crl); + } break; + } + +exit: + if (mbio != NULL) BIO_free_all(mbio); +#ifdef TRACE_BY_LDAP +fprintf(stderr, "TRACE_BY_LDAP ldaplookup_data2store: ok=%d\n", ok); +#endif + return(ok); +} + + +static int +ldaplookup_result2store( + int type, + X509_NAME* name, + LDAP* ld, + LDAPMessage* res, + X509_STORE* store +) { + int count = 0; + int result; + LDAPMessage *entry; + + result = ldap_count_entries(ld, res); + if (result < 0) { + result = ldap_result2error(ld, res, 0); + X509byLDAPerr(X509byLDAP_F_RESULT2STORE, X509byLDAP_R_UNABLE_TO_COUNT_ENTRIES); + openssl_add_ldap_error(result); + goto done; + } +#ifdef TRACE_BY_LDAP +fprintf(stderr, "TRACE_BY_LDAP ldaplookup_result2store: ldap_count_entries=%d\n", result); +#endif + + for(entry = ldap_first_entry(ld, res); + entry != NULL; + entry = ldap_next_entry(ld, entry) + ) { + char *attr; + BerElement *ber; +#ifdef TRACE_BY_LDAP +{ +char *dn = ldap_get_dn(ld, entry); +fprintf(stderr, "TRACE_BY_LDAP ldaplookup_result2store(): ldap_get_dn=%s\n", dn); +ldap_memfree(dn); +} +#endif + for(attr = ldap_first_attribute(ld, entry, &ber); + attr != NULL; + attr = ldap_next_attribute(ld, entry, ber) + ) { + struct berval **vals; + struct berval **p; + +#ifdef TRACE_BY_LDAP +fprintf(stderr, "TRACE_BY_LDAP ldaplookup_result2store: attr=%s\n", attr); +#endif + if (!ldaplookup_check_attr(type, attr)) continue; + + vals = ldap_get_values_len(ld, entry, attr); + if (vals == NULL) continue; + + for(p = vals; *p; p++) { + struct berval *q = *p; + if (ldaplookup_data2store(type, name, q->bv_val, q->bv_len, store)) { + count++; + } + } + ldap_value_free_len(vals); + } + ber_free(ber, 0); + } +done: +#ifdef TRACE_BY_LDAP +fprintf(stderr, "TRACE_BY_LDAP ldaplookup_result2store: count=%d\n", count); +#endif + return(count); +} + + +static int +ldaplookup_by_subject( + X509_LOOKUP *ctx, + int type, + X509_NAME *name, + X509_OBJECT *ret +) { + int count = 0; + ldaphost *lh; + const char *attrs[2]; + char *filter = NULL; + + + if (ctx == NULL) return(0); + if (name == NULL) return(0); + + lh = (ldaphost*) ctx->method_data; + if (lh == NULL) return(0); + + switch(type) { + case X509_LU_X509: { + attrs[0] = ATTR_CACERT; + } break; + case X509_LU_CRL: { + attrs[0] = ATTR_CACRL; + } break; + default: { + X509byLDAPerr(X509byLDAP_F_GET_BY_SUBJECT, X509byLDAP_R_WRONG_LOOKUP_TYPE); + goto done; + } + } + attrs[1] = NULL; + + filter = ldaplookup_filter(name, attrs[0]); + if (filter == NULL) { + X509byLDAPerr(X509byLDAP_F_GET_BY_SUBJECT, X509byLDAP_R_UNABLE_TO_GET_FILTER); + goto done; + } +#ifdef TRACE_BY_LDAP +fprintf(stderr, "TRACE_BY_LDAP ldaplookup_by_subject: filter=%s\n", filter); +#endif + + for (; lh != NULL; lh = lh->next) { + LDAPMessage *res = NULL; + int result; + +#ifdef TRACE_BY_LDAP +{ +int version = -1; + +ldap_get_option(lh->ld, LDAP_OPT_PROTOCOL_VERSION, &version); +fprintf(stderr, "TRACE_BY_LDAP ldaplookup_by_subject:" +" bind to \"%s://%s:%d\"" +" using ldap v%d protocol\n" +, lh->ldapurl->lud_scheme, lh->ldapurl->lud_host, lh->ldapurl->lud_port +, version +); +} +#endif + + /* anonymous bind - data must be retrieved by anybody */ + result = ldap_simple_bind_s(lh->ld, NULL/*binddn*/, NULL/*bindpw*/); + if (result != LDAP_SUCCESS) { + X509byLDAPerr(X509byLDAP_F_GET_BY_SUBJECT, X509byLDAP_R_UNABLE_TO_BIND); + { + char buf[1024]; + snprintf(buf, sizeof(buf), + " url=\"%s://%s:%d\"" + " ldaperror=0x%x(%.256s)" + , lh->ldapurl->lud_scheme, lh->ldapurl->lud_host, lh->ldapurl->lud_port + , result, ldap_err2string(result) + ); + ERR_add_error_data(1, buf); + } + continue; + } + + result = ldap_search_s(lh->ld, lh->ldapurl->lud_dn, LDAP_SCOPE_SUBTREE, filter, (char**)attrs, 0, &res); +#ifdef TRACE_BY_LDAP +fprintf(stderr, "TRACE_BY_LDAP ldaplookup_by_subject:" +" ldap_search_s return 0x%x(%s)\n" +, result, ldap_err2string(result)); +#endif + + if (result != LDAP_SUCCESS) { + X509byLDAPerr(X509byLDAP_F_GET_BY_SUBJECT, X509byLDAP_R_SEARCH_FAIL); + ldap_msgfree(res); + continue; + } + + result = ldaplookup_result2store(type, name, lh->ld, res, ctx->store_ctx); + if (result > 0) count += result; + + ldap_msgfree(res); + + /*do not call ldap_unbind_s*/ + } + +#ifdef TRACE_BY_LDAP +fprintf(stderr, "TRACE_BY_LDAP ldaplookup_by_subject: count=%d\n", count); +#endif + if (count > 0) { + /* + * we have added at least one to the cache so now pull one out again + */ + union { + struct { + X509_CINF st_x509_cinf; + X509 st_x509; + } x509; + struct { + X509_CRL_INFO st_crl_info; + X509_CRL st_crl; + } crl; + } data; + + X509_OBJECT stmp, *tmp; + int k; + + memset(&data, 0, sizeof(data)); + stmp.type = type; + switch(type) { + case X509_LU_X509: { + data.x509.st_x509_cinf.subject = name; + data.x509.st_x509.cert_info = &data.x509.st_x509_cinf; + stmp.data.x509 = &data.x509.st_x509; + } break; + case X509_LU_CRL: { + data.crl.st_crl_info.issuer = name; + data.crl.st_crl.crl = &data.crl.st_crl_info; + stmp.data.crl = &data.crl.st_crl; + } break; + default: + count = 0; + goto done; + } + + CRYPTO_r_lock(CRYPTO_LOCK_X509_STORE); + k = sk_X509_OBJECT_find(ctx->store_ctx->objs, &stmp); + if (k >= 0) + tmp = sk_X509_OBJECT_value(ctx->store_ctx->objs, k); + else + tmp = NULL; + CRYPTO_r_unlock(CRYPTO_LOCK_X509_STORE); +#ifdef TRACE_BY_LDAP +fprintf(stderr, "TRACE_BY_LDAP ldaplookup_by_subject: k=%d, tmp=%p\n", k, tmp); +#endif + + if (tmp == NULL) { + count = 0; + goto done; + } + + ret->type = tmp->type; + memcpy(&ret->data, &tmp->data, sizeof(ret->data)); + } + +done: + if (filter != NULL) OPENSSL_free(filter); + return(count > 0); +} diff -ruN openssh-3.9p1+x509h/x509_by_ldap.h openssh-3.9p1+x509-5.1/x509_by_ldap.h --- openssh-3.9p1+x509h/x509_by_ldap.h 1970-01-01 02:00:00.000000000 +0200 +++ openssh-3.9p1+x509-5.1/x509_by_ldap.h 2004-11-19 09:06:00.000000000 +0200 @@ -0,0 +1,98 @@ +#ifndef X509_BY_LDAP_H +#define X509_BY_LDAP_H +/* + * Copyright (c) 2004 Roumen Petrov. 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 AUTHOR ``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 AUTHOR 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. + */ + +/* openssh specific includes */ +#include "includes.h" +#ifndef LDAP_ENABLED +# include "error: LDAP is disabled" +#endif + +/* required includes */ +#include +#include + + +#ifdef __cplusplus +extern "C" { +#endif + + +X509_LOOKUP_METHOD* X509_LOOKUP_ldap(void); + +#define X509_L_LDAP_HOST 1 +#define X509_L_LDAP_VERSION 2 + +#define X509_LOOKUP_add_ldap(x,value) \ + X509_LOOKUP_ctrl((x),X509_L_LDAP_HOST,(value),(long)(0),NULL) +#define X509_LOOKUP_set_protocol(x,value) \ + X509_LOOKUP_ctrl((x),X509_L_LDAP_VERSION,(value),(long)(0),NULL) + + +/* Error codes for the X509byLDAP functions. */ +#ifdef NO_ERR /* openssl < 0.7.x */ +# define OPENSSL_NO_ERR /* openssl >= 0.7.x */ +#endif + +#ifndef OPENSSL_NO_ERR + +void ERR_load_X509byLDAP_strings(void); + +/* library */ +#define ERR_LIB_X509byLDAP ERR_LIB_USER + +#define X509byLDAPerr(f,r) ERR_PUT_error(ERR_LIB_X509byLDAP,(f),(r),__FILE__,__LINE__) + +/* BEGIN ERROR CODES */ + +/* Function codes. */ +#define X509byLDAP_F_LOOKUPCRTL 100 +#define X509byLDAP_F_LDAPHOST_NEW 101 +#define X509byLDAP_F_SET_PROTOCOL 102 +#define X509byLDAP_F_RESULT2STORE 103 +#define X509byLDAP_F_GET_BY_SUBJECT 104 + +/* Reason codes. */ +#define X509byLDAP_R_INVALID_CRTLCMD 100 +#define X509byLDAP_R_NOT_LDAP_URL 101 +#define X509byLDAP_R_INVALID_URL 102 +#define X509byLDAP_R_INITIALIZATION_ERROR 103 +#define X509byLDAP_R_UNABLE_TO_GET_PROTOCOL_VERSION 104 +#define X509byLDAP_R_UNABLE_TO_SET_PROTOCOL_VERSION 105 +#define X509byLDAP_R_UNABLE_TO_COUNT_ENTRIES 106 +#define X509byLDAP_R_WRONG_LOOKUP_TYPE 107 +#define X509byLDAP_R_UNABLE_TO_GET_FILTER 108 +#define X509byLDAP_R_UNABLE_TO_BIND 109 +#define X509byLDAP_R_SEARCH_FAIL 110 + +#endif /*ndef OPENSSL_NO_ERR*/ + + +#ifdef __cplusplus +} +#endif + + +#endif /*ndef X509_BY_LDAP_H*/ diff -ruN openssh-3.9p1+x509h/x509store.c openssh-3.9p1+x509-5.1/x509store.c --- openssh-3.9p1+x509h/x509store.c 2004-03-21 12:09:33.000000000 +0200 +++ openssh-3.9p1+x509-5.1/x509store.c 2004-11-15 23:36:10.000000000 +0200 @@ -21,13 +21,20 @@ * (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 "x509store.h" #include "openssl/x509v3.h" #include "log.h" #ifndef SSH_X509STORE_DISABLED #include "xmalloc.h" +#include "pathnames.h" +#include "misc.h" #include "openssl/err.h" +#include "openssl/x509_vfy.h" +#ifdef LDAP_ENABLED +# include "x509_by_ldap.h" +#endif #endif /*ndef SSH_X509STORE_DISABLED*/ /* allowed client/server certificate purpose */ @@ -43,11 +50,14 @@ #ifndef SSH_X509STORE_DISABLED static X509_STORE *x509store = NULL; -#define SSH_CHECK_REVOKED +#if 1 +# define SSH_CHECK_REVOKED +#endif #ifdef SSH_CHECK_REVOKED static X509_STORE *x509revoked = NULL; +static int/*bool*/ x509_mandatory_crl = 0; static int ssh_x509revoked_cb(int ok, X509_STORE_CTX *ctx); @@ -96,10 +106,10 @@ static int ssh_x509store_cb(int ok, X509_STORE_CTX *ctx) { if (!ok) { - char buf[512]; + char buf[X509_NAME_MAXLEN]; X509_NAME_oneline(X509_get_subject_name(ctx->current_cert), buf, sizeof(buf)); - error("ssh_x509store_cb: subject='%.512s', error %d at %d depth lookup:%.200s", - buf, + error("ssh_x509store_cb: subject='%.*s', error %d at %d depth lookup:%.200s", + (int) sizeof(buf), buf, ctx->error, ctx->error_depth, X509_verify_cert_error_string(ctx->error)); @@ -220,6 +230,59 @@ #ifndef SSH_X509STORE_DISABLED +void +ssh_x509store_initialize(X509StoreOptions *options) { + options->certificate_file = NULL; + options->certificate_path = NULL; + options->revocation_file = NULL; + options->revocation_path = NULL; +#ifdef LDAP_ENABLED + options->ldap_ver = NULL; + options->ldap_url = NULL; +#endif +} + + +void +ssh_x509store_system_defaults(X509StoreOptions *options) { + if (options->certificate_file == NULL) + options->certificate_file = _PATH_CA_CERTIFICATE_FILE; + if (options->certificate_path == NULL) + options->certificate_path = _PATH_CA_CERTIFICATE_PATH; + if (options->revocation_file == NULL) + options->revocation_file = _PATH_CA_REVOCATION_FILE; + if (options->revocation_path == NULL) + options->revocation_path = _PATH_CA_REVOCATION_PATH; +#ifdef LDAP_ENABLED + /*nothing to do ;-)*/ +#endif +} + + +static void +tilde_expand_filename2(const char **_fn, const char* _default, uid_t uid) { + if (*_fn == NULL) { + *_fn = tilde_expand_filename(_default, uid); + } else { + const char *p = *_fn; + *_fn = tilde_expand_filename(p, uid); + xfree((void*)p); + } +} + + +void +ssh_x509store_user_defaults(X509StoreOptions *options, uid_t uid) { + tilde_expand_filename2(&options->certificate_file, _PATH_USERCA_CERTIFICATE_FILE, uid); + tilde_expand_filename2(&options->certificate_path, _PATH_USERCA_CERTIFICATE_PATH, uid); + tilde_expand_filename2(&options->revocation_file , _PATH_USERCA_REVOCATION_FILE , uid); + tilde_expand_filename2(&options->revocation_path , _PATH_USERCA_REVOCATION_PATH , uid); +#ifdef LDAP_ENABLED + /*nothing to do ;-)*/ +#endif +} + + static void ssh_x509store_initcontext(void) { if (x509store == NULL) { @@ -233,16 +296,16 @@ if (x509revoked == NULL) { x509revoked = X509_STORE_new(); if (x509revoked == NULL) { - fatal("cannot create x509revoced context"); + fatal("cannot create x509revoked context"); } } #endif } -int +int/*bool*/ ssh_x509store_addlocations(const X509StoreOptions *_locations) { - int flag = 0, flag2 = 0; + int flag; if (_locations == NULL) { error("ssh_x509store_addlocations: _locations is NULL"); @@ -261,6 +324,8 @@ } #endif ssh_x509store_initcontext(); + + flag = 0; /* * Note: * After X509_LOOKUP_{add_dir|load_file} calls we must call @@ -270,7 +335,7 @@ if (_locations->certificate_path != NULL) { X509_LOOKUP *lookup = X509_STORE_add_lookup(x509store, X509_LOOKUP_hash_dir()); if (lookup == NULL) { - fatal("ssh_x509store_addlocations:cannot add hash dir lookup !"); + fatal("ssh_x509store_addlocations: cannot add hash dir lookup !"); return(0); /* ;-) */ } if (X509_LOOKUP_add_dir(lookup, _locations->certificate_path, X509_FILETYPE_PEM)) { @@ -282,7 +347,7 @@ if (_locations->certificate_file != NULL) { X509_LOOKUP *lookup = X509_STORE_add_lookup(x509store, X509_LOOKUP_file()); if (lookup == NULL) { - fatal("ssh_x509store_addlocations:cannot add file lookup !"); + fatal("ssh_x509store_addlocations: cannot add file lookup !"); return(0); /* ;-) */ } if (X509_LOOKUP_load_file(lookup, _locations->certificate_file, X509_FILETYPE_PEM)) { @@ -291,35 +356,100 @@ } ERR_clear_error(); } + /*at least one lookup should succeed*/ + if (flag == 0) return(0); + + flag = 0; #ifdef SSH_CHECK_REVOKED if (_locations->revocation_path != NULL) { X509_LOOKUP *lookup = X509_STORE_add_lookup(x509revoked, X509_LOOKUP_hash_dir()); if (lookup == NULL) { - fatal("ssh_x509store_addlocations:cannot add hash dir revocation lookup !"); + fatal("ssh_x509store_addlocations: cannot add hash dir revocation lookup !"); return(0); /* ;-) */ } if (X509_LOOKUP_add_dir(lookup, _locations->revocation_path, X509_FILETYPE_PEM)) { debug2("hash dir '%.400s' added to x509 revocation store", _locations->revocation_path); - flag2 = 1; + flag = 1; } ERR_clear_error(); } if (_locations->revocation_file != NULL) { X509_LOOKUP *lookup = X509_STORE_add_lookup(x509revoked, X509_LOOKUP_file()); if (lookup == NULL) { - fatal("ssh_x509store_addlocations:cannot add file revocation lookup !"); + fatal("ssh_x509store_addlocations: cannot add file revocation lookup !"); return(0); /* ;-) */ } if (X509_LOOKUP_load_file(lookup, _locations->revocation_file, X509_FILETYPE_PEM)) { debug2("file '%.400s' added to x509 revocation store", _locations->revocation_file); - flag2 = 1; + flag = 1; } ERR_clear_error(); } +#else /*ndef SSH_CHECK_REVOKED*/ + if (_locations->revocation_path != NULL) { + logit("useless option: revocation_path"); + } + if (_locations->revocation_file != NULL) { + logit("useless option: revocation_file"); + } + flag = 1; +#endif /*ndef SSH_CHECK_REVOKED*/ + /*at least one revocation lookup should succeed*/ + if (flag == 0) return(0); + +#ifdef LDAP_ENABLED + if (_locations->ldap_url != NULL) { + X509_LOOKUP *lookup; + + lookup = X509_STORE_add_lookup(x509store, X509_LOOKUP_ldap()); + if (lookup == NULL) { + fatal("ssh_x509store_addlocations: cannot add ldap lookup !"); + return(0); /* ;-) */ + } + if (X509_LOOKUP_add_ldap(lookup, _locations->ldap_url)) { + debug2("ldap url '%.400s' added to x509 store", _locations->ldap_url); + } + if (_locations->ldap_ver != NULL) { + if (!X509_LOOKUP_set_protocol(lookup, _locations->ldap_ver)) { + fatal("ssh_x509store_addlocations: cannot set ldap version !"); + return(0); /* ;-) */ + } + } + /*ERR_clear_error();*/ + +#ifdef SSH_CHECK_REVOKED + lookup = X509_STORE_add_lookup(x509revoked, X509_LOOKUP_ldap()); + if (lookup == NULL) { + fatal("ssh_x509store_addlocations: cannot add ldap lookup(revoked) !"); + return(0); /* ;-) */ + } + if (X509_LOOKUP_add_ldap(lookup, _locations->ldap_url)) { + debug2("ldap url '%.400s' added to x509 store(revoked)", _locations->ldap_url); + } + if (_locations->ldap_ver != NULL) { + if (!X509_LOOKUP_set_protocol(lookup, _locations->ldap_ver)) { + fatal("ssh_x509store_addlocations: cannot set ldap version(revoked) !"); + return(0); /* ;-) */ + } + } + /*ERR_clear_error();*/ +#endif /*def SSH_CHECK_REVOKED*/ + } +#endif /*def LDAP_ENABLED*/ + + return(1); +} + + +int/*bool*/ +ssh_x509store_mandatory_crl(int _mandatory_crl) { +#ifdef SSH_CHECK_REVOKED + x509_mandatory_crl = (_mandatory_crl != 0); + return(x509_mandatory_crl); #else - flag2 = 1; + logit("useless option: mandatory_crl"); + return(_mandatory_crl != 0); #endif - return(flag && flag2); } @@ -408,9 +538,9 @@ } if (get_log_level() >= SYSLOG_LEVEL_DEBUG3) { - char buf[512]; + char buf[X509_NAME_MAXLEN]; X509_NAME_oneline( X509_get_subject_name(_cert), buf, sizeof(buf)); - debug3("ssh_x509cert_check: for '%.512s'", buf); + debug3("ssh_x509cert_check: for '%.*s'", (int) sizeof(buf), buf); } csc = X509_STORE_CTX_new(); @@ -418,7 +548,7 @@ int ecode = ERR_get_error(); char ebuf[256]; ERR_error_string_n(ecode, ebuf, sizeof(ebuf)); - error("ssh_x509cert_check:X509_STORE_CTX_new failed with '%.256s'", ebuf); + error("ssh_x509cert_check: X509_STORE_CTX_new failed with '%.256s'", ebuf); /* clear rest of errors in OpenSSL "error buffer" */ ERR_clear_error(); @@ -427,6 +557,7 @@ ret = ssh_verify_cert(csc, _cert); X509_STORE_CTX_free(csc); +#ifdef SSH_OCSP_ENABLED if (ret > 0) { /* * OpenSSH implementation first verify and validate certificate by @@ -469,11 +600,12 @@ * Therefore instead to send OCSP request in ssh_x509revoked_cb() * we do this here. */ - ret = ssh_x509_validate(_cert, x509store); + ret = ssh_ocsp_validate(_cert, x509store); } +#endif /*def SSH_OCSP_ENABLED*/ #else /*def SSH_X509STORE_DISABLED*/ - if (sshpurpose.index >=0) { + if (sshpurpose.index >= 0) { xptmp = X509_PURPOSE_get0(sshpurpose.index); if (xptmp == NULL) { fatal("ssh_x509cert_check: cannot get purpose from index"); @@ -493,25 +625,23 @@ #ifndef SSH_X509STORE_DISABLED #ifdef SSH_CHECK_REVOKED -static int -ssh_check_crl(X509_STORE_CTX *_ctx, X509_CRL *_crl) { - X509 *cert = NULL; +static int/*bool*/ +ssh_check_crl(X509_STORE_CTX *_ctx, X509* _issuer, X509_CRL *_crl) { time_t *pcheck_time; int k; + if (_issuer == NULL) { + error("ssh_check_crl: issuer is NULL"); + return(0); + } if (_crl == NULL) { + debug("ssh_check_crl: crl is NULL"); return(1); } - cert = X509_STORE_CTX_get_current_cert(_ctx); - if (cert == NULL) { - error("ssh_check_crl: missing current certificate in x509store context"); - return(0); - } - if (get_log_level() >= SYSLOG_LEVEL_DEBUG3) { BIO *bio; - char buf[512]; + char buf[X509_NAME_MAXLEN]; char *p; bio = BIO_new(BIO_s_mem()); @@ -520,7 +650,7 @@ return(0); /* ;-) */ } - X509_NAME_oneline( X509_CRL_get_issuer(_crl), buf, sizeof(buf)); + X509_NAME_oneline(X509_CRL_get_issuer(_crl), buf, sizeof(buf)); BIO_printf(bio, ", Last Update: "); ASN1_UTCTIME_print(bio, X509_CRL_get_lastUpdate(_crl)); @@ -539,16 +669,38 @@ BIO_free(bio); } +/* RFC 3280: + * The cRLSign bit is asserted when the subject public key is used + * for verifying a signature on certificate revocation list (e.g., a + * CRL, delta CRL, or an ARL). This bit MUST be asserted in + * certificates that are used to verify signatures on CRLs. + */ + if (/*???(_issuer->ex_flags & EXFLAG_KUSAGE) &&*/ + !(_issuer->ex_kusage & KU_CRL_SIGN) + ) { + char buf[X509_NAME_MAXLEN]; + + X509_NAME_oneline(X509_get_subject_name(_issuer), buf, sizeof(buf)); + error("ssh_check_crl: to verify crl signature key usage 'cRLSign'" + " must present in issuer certificate '%.*s'" + , (int) sizeof(buf), buf); + #ifdef X509_V_ERR_KEYUSAGE_NO_CRL_SIGN + /*first defined in OpenSSL 0.9.7d*/ + X509_STORE_CTX_set_error(_ctx, X509_V_ERR_KEYUSAGE_NO_CRL_SIGN); + #endif + return(0); + } + { - EVP_PKEY *pkey = X509_get_pubkey(cert); + EVP_PKEY *pkey = X509_get_pubkey(_issuer); if (pkey == NULL) { - error("ssh_check_crl:unable to decode public key"); + error("ssh_check_crl: unable to decode issuer public key"); X509_STORE_CTX_set_error(_ctx, X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY); return(0); } if (X509_CRL_verify(_crl, pkey) <= 0) { - error("ssh_check_crl:CRL has invalid signature"); + error("ssh_check_crl: CRL has invalid signature"); X509_STORE_CTX_set_error(_ctx, X509_V_ERR_CRL_SIGNATURE_FAILURE); return(0); } @@ -564,23 +716,23 @@ k = X509_cmp_time(X509_CRL_get_lastUpdate(_crl), pcheck_time); if (k == 0) { X509_STORE_CTX_set_error(_ctx, X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD); - error("ssh_check_crl:CRL has invalid lastUpdate field"); + error("ssh_check_crl: CRL has invalid lastUpdate field"); return(0); } if (k > 0) { X509_STORE_CTX_set_error(_ctx, X509_V_ERR_CRL_NOT_YET_VALID); - error("ssh_check_crl:CRL is not yet valid"); + error("ssh_check_crl: CRL is not yet valid"); return(0); } k = X509_cmp_time(X509_CRL_get_nextUpdate(_crl), pcheck_time); if (k == 0) { - error("ssh_check_crl:CRL has invalid nextUpdate field"); + error("ssh_check_crl: CRL has invalid nextUpdate field"); X509_STORE_CTX_set_error(_ctx, X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD); return(0); } if (k < 0) { - error("ssh_check_crl:CRL is expired"); + error("ssh_check_crl: CRL is expired"); X509_STORE_CTX_set_error(_ctx, X509_V_ERR_CRL_HAS_EXPIRED); return(0); } @@ -589,16 +741,16 @@ } -static int -ssh_check_crl_cert(X509_STORE_CTX *_ctx, X509_CRL *_crl, X509 *_cert) { +static int/*bool*/ +ssh_is_cert_revoked(X509_STORE_CTX *_ctx, X509_CRL *_crl, X509 *_cert) { X509_REVOKED revoked; int k; - char *p, buf1[512], buf2[512]; + char *p, buf1[X509_NAME_MAXLEN], buf2[X509_NAME_MAXLEN]; if (_crl == NULL) return(1); revoked.serialNumber = X509_get_serialNumber(_cert); k = sk_X509_REVOKED_find(_crl->crl->revoked, &revoked); - if (k < 0) return(1); + if (k < 0) return(0); X509_STORE_CTX_set_error(_ctx, X509_V_ERR_CERT_REVOKED); /* yes, revoked. print log and ...*/ @@ -606,11 +758,13 @@ X509_NAME_oneline(X509_get_subject_name(_cert), buf1, sizeof(buf1)); X509_NAME_oneline(X509_CRL_get_issuer (_crl ), buf2, sizeof(buf2)); - error("certificate '%.512s' with serial '%.40s' revoked from issuer '%.512s'", - buf1, p, buf2); + error("certificate '%.*s' with serial '%.40s' revoked from issuer '%.*s'" + , (int) sizeof(buf1), buf1 + , p + , (int) sizeof(buf2), buf2); xfree(p); - return(0); + return(1); } @@ -630,16 +784,20 @@ } if (get_log_level() >= SYSLOG_LEVEL_DEBUG3) { - char buf[512]; + char buf[X509_NAME_MAXLEN]; X509_NAME_oneline(X509_get_issuer_name(cert), buf, sizeof(buf)); - debug3("ssh_x509revoked_cb:issuer =%.512s", buf); + debug3("ssh_x509revoked_cb: issuer =%.*s", (int) sizeof(buf), buf); X509_NAME_oneline(X509_get_subject_name(cert), buf, sizeof(buf)); - debug3("ssh_x509revoked_cb:subject=%.512s", buf); + debug3("ssh_x509revoked_cb: subject=%.*s", (int) sizeof(buf), buf); } memset(&xobj, 0, sizeof(xobj)); +/* TODO: + * NID_crl_distribution_points may contain one or more + * CRLissuer != cert issuer + */ if (ssh_x509store_lookup( x509revoked, X509_LU_CRL, X509_get_subject_name(cert), @@ -665,7 +823,17 @@ * we already know that all issuers of "current certificate" aren't * revoked. */ - ok = ssh_check_crl(ctx, xobj.data.crl); + ok = ssh_check_crl(ctx, cert, xobj.data.crl); + } else { + if (x509_mandatory_crl) { + int loc; + loc = X509_get_ext_by_NID(cert, NID_crl_distribution_points, -1); + ok = (loc < 0); + if (!ok) { + error("ssh_x509revoked_cb: unable to get issued CRL"); + X509_STORE_CTX_set_error(ctx, X509_V_ERR_UNABLE_TO_GET_CRL); + } + } } X509_OBJECT_free_contents(&xobj); if (!ok) return(0); @@ -675,7 +843,7 @@ x509revoked, X509_LU_CRL, X509_get_issuer_name(cert), &xobj) > 0) { - ok = ssh_check_crl_cert(ctx, xobj.data.crl, cert); + ok = !ssh_is_cert_revoked(ctx, xobj.data.crl, cert); } X509_OBJECT_free_contents(&xobj); /* clear rest of errors in OpenSSL "error buffer" */ diff -ruN openssh-3.9p1+x509h/x509store.h openssh-3.9p1+x509-5.1/x509store.h --- openssh-3.9p1+x509h/x509store.h 2004-03-21 11:09:12.000000000 +0200 +++ openssh-3.9p1+x509-5.1/x509store.h 2004-11-07 22:44:28.000000000 +0200 @@ -24,11 +24,13 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ - #include "includes.h" #include +#define X509_NAME_MAXLEN 512 + + int ssh_x509cert_check(X509 *_cert); int ssh_get_default_x509purpose(int _is_server); @@ -47,16 +49,26 @@ const char *certificate_path; const char *revocation_file; const char *revocation_path; +#ifdef LDAP_ENABLED + const char *ldap_ver; + const char *ldap_url; +#endif } X509StoreOptions; -int ssh_x509store_addlocations(const X509StoreOptions *_locations); +void ssh_x509store_initialize(X509StoreOptions *options); +void ssh_x509store_system_defaults(X509StoreOptions *options); +void ssh_x509store_user_defaults(X509StoreOptions *options, uid_t uid); -int ssh_x509_validate(X509 *cert, X509_STORE *x509store); +int/*bool*/ ssh_x509store_addlocations(const X509StoreOptions *_locations); +int/*bool*/ ssh_x509store_mandatory_crl(int _mandatory_crl); #endif /*ndef SSH_X509STORE_DISABLED*/ #ifdef SSH_X509STORE_DISABLED +#ifdef LDAP_ENABLED +# include "cannot enable LDAP when x509store is disabled" +#endif /*def LDAP_ENABLED*/ #ifdef SSH_OCSP_ENABLED # include "cannot enable OCSP when x509store is disabled" #endif /*def SSH_OCSP_ENABLED*/ @@ -87,6 +99,8 @@ void ssh_set_validator(const VAOptions *_va); /*fatal on error*/ +int ssh_ocsp_validate(X509 *cert, X509_STORE *x509store); + #endif /*def SSH_OCSP_ENABLED*/