diff -ruN openssh-4.6p1+x509-6.0.1/aclocal.m4 openssh-4.6p1+x509-6.1/aclocal.m4 --- openssh-4.6p1+x509-6.0.1/aclocal.m4 2007-03-10 09:07:00.000000000 +0200 +++ openssh-4.6p1+x509-6.1/aclocal.m4 2007-10-25 19:06:00.000000000 +0300 @@ -103,7 +103,7 @@ dnl LDAP_LIBEXECDIR dnl LDAP_SYSCONFDIR -AC_DEFUN(AC_WITH_LDAP, +AC_DEFUN([AC_WITH_LDAP], [ dnl dnl Get the ldap paths @@ -279,3 +279,26 @@ AC_SUBST(LDAP_ON) AC_SUBST(LDAP_OFF) ]) + + +# AC_LDAP_FUNCS(FUNCTION...) +# -------------------------------- +AC_DEFUN([AC_LDAP_FUNCS], +[ +dnl +dnl Check ldap functions +dnl +AC_REQUIRE([AC_WITH_LDAP]) +if test "x$ac_ldap" = "xyes"; then + ac_save_CPPFLAGS="$CPPFLAGS" + ac_save_LDFLAGS="$LDFLAGS" + ac_save_LIBS="$LIBS" + CPPFLAGS="$CPPFLAGS $LDAP_CPPFLAGS" + LDFLAGS="$LDFLAGS $LDAP_LDFLAGS" + LIBS="$LDAP_LIBS $LIBS" + AC_CHECK_FUNCS([$1],[],[]) + LIBS="$ac_save_LIBS" + LDFLAGS="$ac_save_LDFLAGS" + CPPFLAGS="$ac_save_CPPFLAGS" +fi +]) diff -ruN openssh-4.6p1+x509-6.0.1/config.h.in openssh-4.6p1+x509-6.1/config.h.in --- openssh-4.6p1+x509-6.0.1/config.h.in 2007-08-07 09:06:01.000000000 +0300 +++ openssh-4.6p1+x509-6.1/config.h.in 2007-10-25 19:06:01.000000000 +0300 @@ -486,6 +486,18 @@ /* Define to 1 if you have the header file. */ #undef HAVE_LDAP_H +/* Define to 1 if you have the `ldap_initialize' function. */ +#undef HAVE_LDAP_INITIALIZE + +/* Define to 1 if you have the `ldap_parse_result' function. */ +#undef HAVE_LDAP_PARSE_RESULT + +/* Define to 1 if you have the `ldap_sasl_bind_s' function. */ +#undef HAVE_LDAP_SASL_BIND_S + +/* Define to 1 if you have the `ldap_search_ext_s' function. */ +#undef HAVE_LDAP_SEARCH_EXT_S + /* Define to 1 if you have the `bsm' library (-lbsm). */ #undef HAVE_LIBBSM diff -ruN openssh-4.6p1+x509-6.0.1/configure openssh-4.6p1+x509-6.1/configure --- openssh-4.6p1+x509-6.0.1/configure 2007-08-07 09:06:02.000000000 +0300 +++ openssh-4.6p1+x509-6.1/configure 2007-10-25 19:06:02.000000000 +0300 @@ -1327,7 +1327,7 @@ --disable-strip Disable calling strip(1) on install --disable-etc-default-login Disable using PATH from /etc/default/login no --disable-x509store Disable X.509 store - --enable-ocsp Enable OCSP validation + --disable-ocsp Disable 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 @@ -27551,20 +27551,30 @@ fi -ssh_ocsp="no" +# enable/disable OCSP requests # Check whether --enable-ocsp was given. if test "${enable_ocsp+set}" = set; then enableval=$enable_ocsp; if test "x$enableval" = "xyes"; then - if test "x$ssh_x509store" = "xyes"; then - ssh_ocsp="yes" - else + if test "x$ssh_x509store" != "xyes"; then { { echo "$as_me:$LINENO: error: cannot enable OCSP when x509store is disabled" >&5 echo "$as_me: error: cannot enable OCSP when x509store is disabled" >&2;} { (exit 1); exit 1; }; } fi + ssh_ocsp="yes" + else + ssh_ocsp="no" fi +else + + if test "x$ssh_x509store" = "xyes"; then + ssh_ocsp="yes" + else + ssh_ocsp="no" + { echo "$as_me:$LINENO: x509store is disabled - skiping OCSP" >&5 +echo "$as_me: x509store is disabled - skiping OCSP" >&6;} + fi fi @@ -28262,6 +28272,122 @@ if test "x$LDAP_ON" = "x"; then LDAP_MSG="yes" fi + + +if test "x$ac_ldap" = "xyes"; then + ac_save_CPPFLAGS="$CPPFLAGS" + ac_save_LDFLAGS="$LDFLAGS" + ac_save_LIBS="$LIBS" + CPPFLAGS="$CPPFLAGS $LDAP_CPPFLAGS" + LDFLAGS="$LDFLAGS $LDAP_LDFLAGS" + LIBS="$LDAP_LIBS $LIBS" + + + + +for ac_func in \ + ldap_initialize \ + ldap_parse_result \ + ldap_sasl_bind_s \ + ldap_search_ext_s \ + +do +as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` +{ echo "$as_me:$LINENO: checking for $ac_func" >&5 +echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6; } +if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* Define $ac_func to an innocuous variant, in case declares $ac_func. + For example, HP-UX 11i declares gettimeofday. */ +#define $ac_func innocuous_$ac_func + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $ac_func (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include +#else +# include +#endif + +#undef $ac_func + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char $ac_func (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined __stub_$ac_func || defined __stub___$ac_func +choke me +#endif + +int +main () +{ +return $ac_func (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&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); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + eval "$as_ac_var=yes" +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + eval "$as_ac_var=no" +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +fi +ac_res=`eval echo '${'$as_ac_var'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } +if test `eval echo '${'$as_ac_var'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +fi +done + + LIBS="$ac_save_LIBS" + LDFLAGS="$ac_save_LDFLAGS" + CPPFLAGS="$ac_save_CPPFLAGS" +fi + else { echo "$as_me:$LINENO: x509store is disabled - skiping LDAP" >&5 echo "$as_me: x509store is disabled - skiping LDAP" >&6;} diff -ruN openssh-4.6p1+x509-6.0.1/configure.ac openssh-4.6p1+x509-6.1/configure.ac --- openssh-4.6p1+x509-6.0.1/configure.ac 2007-08-07 09:06:00.000000000 +0300 +++ openssh-4.6p1+x509-6.1/configure.ac 2007-10-25 19:06:00.000000000 +0300 @@ -3681,19 +3681,27 @@ fi -ssh_ocsp="no" +# enable/disable OCSP requests AC_ARG_ENABLE(ocsp, - [ --enable-ocsp Enable OCSP validation], + [ --disable-ocsp Disable OCSP validation], [ if test "x$enableval" = "xyes"; then - if test "x$ssh_x509store" = "xyes"; then - ssh_ocsp="yes" - else + if test "x$ssh_x509store" != "xyes"; then AC_MSG_ERROR([cannot enable OCSP when x509store is disabled]) fi + ssh_ocsp="yes" + else + ssh_ocsp="no" fi - ] -) + ], + [ + if test "x$ssh_x509store" = "xyes"; then + ssh_ocsp="yes" + else + ssh_ocsp="no" + AC_MSG_NOTICE([x509store is disabled - skiping OCSP]) + fi + ]) if test "x$ssh_ocsp" = "xyes"; then AC_CHECK_FUNCS(OCSP_sendreq_bio, [ @@ -3707,7 +3715,7 @@ [ ssh_ocsp="no" AC_MSG_WARN([Cannot find OCSP functions - OCSP is disabled]) - ]) + ]) fi if test "x$ssh_ocsp" = "xyes"; then AC_DEFINE_UNQUOTED( @@ -3730,6 +3738,12 @@ if test "x$LDAP_ON" = "x"; then LDAP_MSG="yes" fi + AC_LDAP_FUNCS([\ + ldap_initialize \ + ldap_parse_result \ + ldap_sasl_bind_s \ + ldap_search_ext_s \ + ]) else AC_MSG_NOTICE([x509store is disabled - skiping LDAP]) fi diff -ruN openssh-4.6p1+x509-6.0.1/m4/ldap.m4 openssh-4.6p1+x509-6.1/m4/ldap.m4 --- openssh-4.6p1+x509-6.0.1/m4/ldap.m4 2005-07-19 23:11:01.000000000 +0300 +++ openssh-4.6p1+x509-6.1/m4/ldap.m4 2007-10-22 23:05:29.000000000 +0300 @@ -1,7 +1,7 @@ # Options to build with LDAP # # Author: Roumen Petrov -# Revision: 19 Jul 2005 +# Revision: 22 Oct 2007 # dnl The variables provided are : dnl - build flags: @@ -16,7 +16,7 @@ dnl LDAP_LIBEXECDIR dnl LDAP_SYSCONFDIR -AC_DEFUN(AC_WITH_LDAP, +AC_DEFUN([AC_WITH_LDAP], [ dnl dnl Get the ldap paths @@ -192,3 +192,26 @@ AC_SUBST(LDAP_ON) AC_SUBST(LDAP_OFF) ]) + + +# AC_LDAP_FUNCS(FUNCTION...) +# -------------------------------- +AC_DEFUN([AC_LDAP_FUNCS], +[ +dnl +dnl Check ldap functions +dnl +AC_REQUIRE([AC_WITH_LDAP]) +if test "x$ac_ldap" = "xyes"; then + ac_save_CPPFLAGS="$CPPFLAGS" + ac_save_LDFLAGS="$LDFLAGS" + ac_save_LIBS="$LIBS" + CPPFLAGS="$CPPFLAGS $LDAP_CPPFLAGS" + LDFLAGS="$LDFLAGS $LDAP_LDFLAGS" + LIBS="$LDAP_LIBS $LIBS" + AC_CHECK_FUNCS([$1],[],[]) + LIBS="$ac_save_LIBS" + LDFLAGS="$ac_save_LDFLAGS" + CPPFLAGS="$ac_save_CPPFLAGS" +fi +]) diff -ruN openssh-4.6p1+x509-6.0.1/README.x509v3 openssh-4.6p1+x509-6.1/README.x509v3 --- openssh-4.6p1+x509-6.0.1/README.x509v3 2006-04-26 00:16:07.000000000 +0300 +++ openssh-4.6p1+x509-6.1/README.x509v3 2007-10-24 00:53:39.000000000 +0300 @@ -1,6 +1,6 @@ Roumen Petrov Sofia, Bulgaria - Wed Apr 12 2006 + Wed Oct 24 2007 How to use X.509 certificates with OpenSSH? @@ -112,11 +112,18 @@ - WORDDN is case insensitive ! - is like output from command: -$ openssl x509 -noout -subject -in A_CERTIFICATE_FILE +$ openssl x509 -noout -subject -in A_CERTIFICATE_FILE -nameopt oneline - can be in RFC2253 format like output from command: $ openssl x509 -noout -subject -in A_CERTIFICATE_FILE -nameopt RFC2253 +IMPORTANT NOTE (if a distinguished name contain non-ascii character): +- for versions 6.+: + ALWAIS use "openssl x509" command option -nameopt ! + The parser don't and willn't support output without -nameopt +- for versions prior 6.0: + The program could'not parse subject. Use "blob" format (see below). + - Order of items in is not important and separator can be symbol "/", "," or mixed. All following subjects are equal: a)CN=dsa test certificate,OU=OpenSSH Testers,O=Test Team,ST=World,C=XX @@ -131,6 +138,7 @@ $ ( printf 'x509v3-sign-rsa '; openssl x509 -noout -subject \ -in A_OPENSSH_IDENTITY_FILE \ + -nameopt oneline \ ) >> $HOME/.ssh/authorized_keys - "blob" format: diff -ruN openssh-4.6p1+x509-6.0.1/ssh_config.0 openssh-4.6p1+x509-6.1/ssh_config.0 --- openssh-4.6p1+x509-6.0.1/ssh_config.0 2007-03-10 09:07:00.000000000 +0200 +++ openssh-4.6p1+x509-6.1/ssh_config.0 2007-10-25 19:06:00.000000000 +0300 @@ -56,9 +56,12 @@ The intended use for the X.509 server certificate. Without this option no chain verification will be done. Currently accepted uses are case insensitive: - o 'sslserver' , 'SSL server' , 'SSL_server' or 'server' ; - o 'any' , 'Any Purpose' , 'Any_Purpose' or 'AnyPurpose' ; - o 'skip' or '' (empty): do not check purpose. + sslserver | SSL server | SSL_server | server + only SSL-server purpose + any | Any Purpose | Any_Purpose | AnyPurpose + allow any purpose + skip | '' (empty) + do not check purpose The default is ``sslserver''. BatchMode @@ -93,7 +96,9 @@ ``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 '=' ! + tation use '%3D' instead of '=' ! LDAP initialization method may + require URL to be escaped, i.e. use '%2C' instead of ',' (comma). + Escaped URL don't depend from LDAP initialization method. CARevocationFile ``X509 store'' option: This file contain multiple ``Certificate @@ -675,11 +680,11 @@ VAType Specifies whether 'Online Certificate Status Protocol' (OCSP) is used to validate X.509 certificates. Accepted values are case insensitive: - o 'none' : do not use OCSP to validate certificates; - o 'ocspcert' : validate only certificates that specify 'OCSP - Service Locator' URL; - o 'ocspspec' : use specified in the configuration 'OCSP - Responder' to validate all certificates. + none do not use OCSP to validate certificates; + ocspcert validate only certificates that specify 'OCSP + Service Locator' URL; + ocspspec use specified in the configuration 'OCSP + Responder' to validate all certificates. The default is ``none''. VAOCSPResponderURL diff -ruN openssh-4.6p1+x509-6.0.1/ssh_config.5 openssh-4.6p1+x509-6.1/ssh_config.5 --- openssh-4.6p1+x509-6.0.1/ssh_config.5 2007-03-10 09:07:00.000000000 +0200 +++ openssh-4.6p1+x509-6.1/ssh_config.5 2007-10-25 19:06:00.000000000 +0300 @@ -128,31 +128,13 @@ The intended use for the X.509 server certificate. Without this option no chain verification will be done. Currently accepted uses are case insensitive: -.Bl -bullet -compact -.It -.Sq sslserver -, -.Sq SSL server -, -.Sq SSL_server -or -.Sq server -; -.It -.Sq any -, -.Sq Any Purpose -, -.Sq Any_Purpose -or -.Sq AnyPurpose -; -.It -.Sq skip -or -.Sq -.. -(empty): do not check purpose. +.Bl -tag -width Ds -compact +.It Cm sslserver | Cm SSL server | Cm SSL_server | Cm server +only SSL-server purpose +.It Cm any | Cm Any Purpose | Cm Any_Purpose | Cm AnyPurpose +allow any purpose +.It Cm skip | Cm '' Li (empty) +do not check purpose .El The default is .Dq sslserver . @@ -206,6 +188,12 @@ instead of .Sq = ! +LDAP initialization method may require URL to be escaped, i.e. use +.Sq %2C +instead of +.Sq \&, +(comma). +Escaped URL don't depend from LDAP initialization method. .It Cm CARevocationFile .Dq X509 store option: @@ -1185,18 +1173,15 @@ .Sq "Online Certificate Status Protocol" (OCSP) is used to validate X.509 certificates. Accepted values are case insensitive: -.Bl -bullet -compact -.It -.Sq none -: do not use OCSP to validate certificates; -.It -.Sq ocspcert -: validate only certificates that specify +.Bl -tag -offset indent -compact +.It none +do not use OCSP to validate certificates; +.It ocspcert +validate only certificates that specify .Sq "OCSP Service Locator" URL; -.It -.Sq ocspspec -: use specified in the configuration +.It ocspspec +use specified in the configuration .Sq "OCSP Responder" to validate all certificates. .El diff -ruN openssh-4.6p1+x509-6.0.1/sshconnect.c openssh-4.6p1+x509-6.1/sshconnect.c --- openssh-4.6p1+x509-6.0.1/sshconnect.c 2007-03-10 09:07:01.000000000 +0200 +++ openssh-4.6p1+x509-6.1/sshconnect.c 2007-10-25 19:06:01.000000000 +0300 @@ -13,7 +13,7 @@ * called by a name other than "ssh" or "Secure Shell". * * X.509 certificates support, - * Copyright (c) 2002-2005 Roumen Petrov. All rights reserved. + * Copyright (c) 2002-2007 Roumen Petrov. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -748,8 +748,8 @@ if ((host_key->type == KEY_X509_RSA) || (host_key->type == KEY_X509_DSA)) { subject = x509key_subject(host_key); snprintf(extramsg, sizeof(extramsg), - "Distinguished name is %.*s.\n", - (int) X509_NAME_MAXLEN, subject); + "Distinguished name is '%s'.\n", + subject); } else { subject = NULL; *extramsg = '\0'; @@ -1112,8 +1112,7 @@ type, fp); 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.", - (int) X509_NAME_MAXLEN, subject); + error("Distinguished name sent by remote host is '%s'.", subject); xfree(subject); } error("Please contact your system administrator."); diff -ruN openssh-4.6p1+x509-6.0.1/sshd_config openssh-4.6p1+x509-6.1/sshd_config --- openssh-4.6p1+x509-6.0.1/sshd_config 2007-03-10 09:07:00.000000000 +0200 +++ openssh-4.6p1+x509-6.1/sshd_config 2007-10-25 19:06:00.000000000 +0300 @@ -73,8 +73,11 @@ # Note because of OpenSSH options parser limitation # use %3D instead of = ! +# LDAP initialization may require URL to be escaped, i.e. +# use %2C instead of ,(comma). Escaped URL don't depend from +# LDAP initialization method. # Example: -# CAldapURL ldap://localhost:389/dc%3Dexample,dc%3Dcom +# CAldapURL ldap://localhost:389/dc%3Dexample%2Cdc%3Dcom # SSH can use "Online Certificate Status Protocol"(OCSP) # to validate certificate. Set VAType to diff -ruN openssh-4.6p1+x509-6.0.1/sshd_config.0 openssh-4.6p1+x509-6.1/sshd_config.0 --- openssh-4.6p1+x509-6.0.1/sshd_config.0 2007-03-10 09:07:00.000000000 +0200 +++ openssh-4.6p1+x509-6.1/sshd_config.0 2007-10-25 19:06:00.000000000 +0300 @@ -38,9 +38,12 @@ The intended use for the X.509 client certificate. Without this option no chain verification will be done. Currently accepted uses are case insensitive: - o 'sslclient' , 'SSL client' , 'SSL_client' or 'client' ; - o 'any' , 'Any Purpose' , 'Any_Purpose' or 'AnyPurpose' ; - o 'skip' or '' (empty): do not check purpose. + sslclient | SSL client | SSL_client | client + only SSL-client purpose + any | Any Purpose | Any_Purpose | AnyPurpose + allow any purpose + skip | '' (empty) + do not check purpose The default is ``sslclient''. AllowGroups @@ -111,7 +114,10 @@ ``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 '=' ! + options parser limitation use '%3D' instead of '=' ! LDAP ini- + tialization method may require URL to be escaped, i.e. use '%2C' + instead of ',' (comma). Escaped URL don't depend from LDAP ini- + tialization method. CARevocationFile ``X509 store'' option: This file contain multiple ``Certificate @@ -580,11 +586,11 @@ VAType Specifies whether 'Online Certificate Status Protocol' (OCSP) is used to validate X.509 certificates. Accepted values are case insensitive: - o 'none' : do not use OCSP to validate certificates; - o 'ocspcert' : validate only certificates that specify 'OCSP - Service Locator' URL; - o 'ocspspec' : use specified in the configuration 'OCSP - Responder' to validate all certificates. + none do not use OCSP to validate certificates; + ocspcert validate only certificates that specify 'OCSP + Service Locator' URL; + ocspspec use specified in the configuration 'OCSP + Responder' to validate all certificates. The default is ``none''. VAOCSPResponderURL diff -ruN openssh-4.6p1+x509-6.0.1/sshd_config.5 openssh-4.6p1+x509-6.1/sshd_config.5 --- openssh-4.6p1+x509-6.0.1/sshd_config.5 2007-03-10 09:07:00.000000000 +0200 +++ openssh-4.6p1+x509-6.1/sshd_config.5 2007-10-25 19:06:00.000000000 +0300 @@ -100,31 +100,13 @@ The intended use for the X.509 client certificate. Without this option no chain verification will be done. Currently accepted uses are case insensitive: -.Bl -bullet -compact -.It -.Sq sslclient -, -.Sq SSL client -, -.Sq SSL_client -or -.Sq client -; -.It -.Sq any -, -.Sq Any Purpose -, -.Sq Any_Purpose -or -.Sq AnyPurpose -; -.It -.Sq skip -or -.Sq -.. -(empty): do not check purpose. +.Bl -tag -width Ds -compact +.It Cm sslclient | Cm SSL client | Cm SSL_client | Cm client +only SSL-client purpose +.It Cm any | Cm Any Purpose | Cm Any_Purpose | Cm AnyPurpose +allow any purpose +.It Cm skip | Cm '' Li (empty) +do not check purpose .El The default is .Dq sslclient . @@ -228,6 +210,12 @@ instead of .Sq = ! +LDAP initialization method may require URL to be escaped, i.e. use +.Sq %2C +instead of +.Sq \&, +(comma). +Escaped URL don't depend from LDAP initialization method. .It Cm CARevocationFile .Dq X509 store option: @@ -990,18 +978,15 @@ .Sq "Online Certificate Status Protocol" (OCSP) is used to validate X.509 certificates. Accepted values are case insensitive: -.Bl -bullet -compact -.It -.Sq none -: do not use OCSP to validate certificates; -.It -.Sq ocspcert -: validate only certificates that specify +.Bl -tag -offset indent -compact +.It none +do not use OCSP to validate certificates; +.It ocspcert +validate only certificates that specify .Sq "OCSP Service Locator" URL; -.It -.Sq ocspspec -: use specified in the configuration +.It ocspspec +use specified in the configuration .Sq "OCSP Responder" to validate all certificates. .El diff -ruN openssh-4.6p1+x509-6.0.1/ssh-ocsp.c openssh-4.6p1+x509-6.1/ssh-ocsp.c --- openssh-4.6p1+x509-6.0.1/ssh-ocsp.c 2006-09-01 23:38:21.000000000 +0300 +++ openssh-4.6p1+x509-6.1/ssh-ocsp.c 2007-10-04 23:12:47.000000000 +0300 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004-2006 Roumen Petrov. All rights reserved. + * Copyright (c) 2004-2007 Roumen Petrov. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -315,8 +315,7 @@ error("ssh_ocspreq_addcert: sk_OCSP_CERTID_push fail"); return(0); } - subj = xmalloc(X509_NAME_MAXLEN); /*fatal on error*/ - X509_NAME_oneline(X509_get_subject_name(cert), subj, X509_NAME_MAXLEN); + subj = ssh_X509_NAME_oneline(X509_get_subject_name(cert)); /*fatal on error*/ if (!sk_push(subjs, subj)) { error("ssh_ocspreq_addcert: sk_push(..., subj) fail"); return(0); @@ -581,12 +580,11 @@ 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[X509_NAME_MAXLEN]; + char *buf; 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='%.*s'" - , k - , (int) sizeof(buf), buf); + buf = ssh_X509_NAME_oneline(X509_get_subject_name(x)); /*fatal on error*/ + logit("ssh_ocsp_get_basicresp: VA[%d] subject='%s'", k, buf); + xfree(buf); } } #endif /*def SSHOCSPTEST*/ @@ -696,9 +694,7 @@ if (get_log_level() >= SYSLOG_LEVEL_DEBUG3) { char *subject = sk_value(subjs, k); - debug3("ssh_ocsp_check_validity: cert[%d]='%.*s'" - , k - , (int) X509_NAME_MAXLEN, subject); + debug3("ssh_ocsp_check_validity: cert[%d]='%s'", k, subject); } if (!OCSP_resp_find_status( @@ -986,9 +982,9 @@ ssh_ocsp_conn *conn = NULL; if (get_log_level() >= SYSLOG_LEVEL_DEBUG3) { - char buf[X509_NAME_MAXLEN]; - X509_NAME_oneline( X509_get_subject_name(cert), buf, sizeof(buf)); - debug3("ssh_ocsp_validate: for '%.*s'", (int) sizeof(buf), buf); + char *buf = ssh_X509_NAME_oneline(X509_get_subject_name(cert)); /*fatal on error*/ + debug3("ssh_ocsp_validate: for '%s'", buf); + xfree(buf); } switch (va.type) { @@ -997,6 +993,7 @@ fatal("ssh_ocsp_validate: invalid validator type %d", va.type); break; /*;-)*/ case SSHVA_NONE: + debug3("ssh_ocsp_validate: none"); ret = 1; break; case SSHVA_OCSP_CERT: diff -ruN openssh-4.6p1+x509-6.0.1/ssh-x509.c openssh-4.6p1+x509-6.1/ssh-x509.c --- openssh-4.6p1+x509-6.0.1/ssh-x509.c 2007-08-06 20:43:27.000000000 +0300 +++ openssh-4.6p1+x509-6.1/ssh-x509.c 2007-10-24 01:09:03.000000000 +0300 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002-2005 Roumen Petrov. All rights reserved. + * Copyright (c) 2002-2007 Roumen Petrov. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -35,6 +35,9 @@ #include "x509store.h" #include "compat.h" +#ifndef ISSPACE +# define ISSPACE(ch) (isspace((int)(unsigned char)(ch))) +#endif int (*pssh_x509cert_check)(X509 *_cert) = NULL; @@ -49,6 +52,56 @@ } +int +ssh_X509_NAME_print(BIO* bio, X509_NAME *xn) { + static u_long print_flags = ((XN_FLAG_ONELINE & \ + ~XN_FLAG_SPC_EQ & \ + ~XN_FLAG_SEP_MASK) | \ + XN_FLAG_SEP_COMMA_PLUS); + + if (xn == NULL) return(-1); + + X509_NAME_print_ex(bio, xn, 0, print_flags); + BIO_flush(bio); + + return(BIO_pending(bio)); +} + + +char* +ssh_X509_NAME_oneline(X509_NAME *xn) { + char *buf = NULL; + int size; + BIO* mbio = NULL; + + if (xn == NULL) return(NULL); + + mbio = BIO_new(BIO_s_mem()); + if (mbio == NULL) return(buf); + + size = ssh_X509_NAME_print(mbio, xn); + if (size <= 0) { + error("ssh_X509_NAME_oneline: no data in buffer"); + goto done; + } + + buf = xmalloc(size + 1); /*fatal on error*/ + + /* we should request one byte more !?!? */ + if (size != BIO_gets(mbio, buf, size + 1)) { + error("ssh_X509_NAME_oneline: cannot get data from buffer"); + goto done; + } + buf[size] = '\0'; + +done: + /* This call will walk the chain freeing all the BIOs */ + BIO_free_all(mbio); + + return(buf); +} + + #ifndef SSH_X509STORE_DISABLED static const char* x509key_find_subject(const char* s) { @@ -68,21 +121,21 @@ error("x509key_find_subject: no input data"); return(NULL); } - for (; *s && isspace((int)*s); s++) + for (; *s && ISSPACE(*s); s++) {/*skip space*/} for (q=keywords; *q; q++) { len = strlen(*q); if (strncasecmp(s, *q, len) != 0) continue; - for (p = s + len; *p && isspace((int)*p); p++) + for (p = s + len; *p && ISSPACE(*p); p++) {/*skip space*/} if (!*p) { error("x509key_find_subject: no data after keyword"); return(NULL); } if (*p == ':' || *p == '=') { - for (p++; *p && isspace((int)*p); p++) + for (p++; *p && ISSPACE(*p); p++) {/*skip space*/} if (!*p) { error("x509key_find_subject: no data after separator"); @@ -91,7 +144,7 @@ } if (*p == '/' || *p == ',') { /*skip leading [Relative]DistinguishedName elements separator*/ - for (p++; *p && isspace((int)*p); p++) + for (p++; *p && ISSPACE(*p); p++) {/*skip space*/} if (!*p) { error("x509key_find_subject: no data"); @@ -108,10 +161,10 @@ #ifndef SSH_X509STORE_DISABLED static unsigned long ssh_hctol(u_char ch) { -#ifndef CHARSET_EBCDIC -/* '0'-'9' = 0x30 - 0x39 */ -/* 'A'-'F' = 0x41 - 0x46 */ -/* 'a'-'f' = 0x61 - 0x66 */ +/* '0'-'9' = 0x30 - 0x39 (ascii) */ +/* 'A'-'F' = 0x41 - 0x46 (ascii) */ +/* 'a'-'f' = 0x61 - 0x66 (ascii) */ +/* should work for EBCDIC */ if (('0' <= ch) && (ch <= '9')) { return((long)(ch - '0')); } @@ -121,9 +174,6 @@ if (('a' <= ch) && (ch <= 'f')) { return((long)(ch - ('a' - 10))); } -#else -# include "ssh_hctol is not implemented for EBCDIC charset" -#endif return(-1); } @@ -158,6 +208,7 @@ "{\\}\\W%08lX" "{\\}\\U%04lX" "{\\}\\%02X" + "{\\}\\x%02X" - X509_NAME_oneline format */ if (ch == '\\') { if (value) *value = ch; @@ -193,7 +244,35 @@ if (value) *value = v; return(5); } - +#if 0 +/* +The code bellow isn't correct. Let 'O' is not 8-bit string(as example +BMPString) then "X509_NAME_oneline" will output "\x00O"(!). +The X509_NAME_oneline output format will left unsupported, i.e.: +Unsupported: +$ openssl x509 -in cert_file -subject -noout +Supported: + v0.9.7+ +$ openssl x509 -in cert_file -subject -noout -nameopt oneline[,] + v0.9.6 +$ openssl x509 -in cert_file -subject -noout -nameopt oneline [-nameopt ] +*/ + if ((ch == 'x') || (ch == 'X')) { + if (len < 3) { + error("get_escsymbol:" + " to short 8-bit hex sequence"); + return(-1); + } + v = ssh_hatol(++str, 2); + if (v < 0) { + error("get_escsymbol:" + " invalid character in 8-bit hex sequence"); + return(-1); + } + if (value) *value = v; + return(3); + } +#endif v = ssh_hctol(*str); if (v < 0) { /*a character is escaped ?*/ @@ -244,20 +323,23 @@ int type = MBSTRING_ASC; u_long ch; u_char *p; + const u_char *q; size_t k; /*this is internal method and we don't check validity of some arguments*/ p = buf; + q = str; k = sizeof(buf); while ((len > 0) && (k > 0)) { - if (*str == '\0') { + int ch_utf8 = 1; + if (*q == '\0') { error("ssh_X509_NAME_add_entry_by_NID:" " unsupported zero(NIL) symbol in name"); return(0); } - if (*str == '\\') { + if (*q == '\\') { len--; if (len <= 0) { error("ssh_X509_NAME_add_entry_by_NID:" @@ -265,26 +347,35 @@ return(0); } - ret = get_escsymbol(++str, len, &ch); + ret = get_escsymbol(++q, len, &ch); if (ret < 0) return(0); + if (ret == 2) { + /*escaped two hex numbers*/ + ch_utf8 = 0; + } } else { - ret = UTF8_getc(str, len, &ch); + ret = UTF8_getc(q, len, &ch); if(ret < 0) { error("ssh_X509_NAME_add_entry_by_NID:" " cannot get next symbol(%.32s)" - , str); + , q); return(0); } } len -= ret; - str += ret; + q += ret; - /* UTF8_putc return negative if buffer is too short */ - ret = UTF8_putc(p, k, ch); - if (ret < 0) { - error("ssh_X509_NAME_add_entry_by_NID:" - " UTF8_putc fail for symbol %ld", ch); - return(0); + if (ch_utf8) { + /* UTF8_putc return negative if buffer is too short */ + ret = UTF8_putc(p, k, ch); + if (ret < 0) { + error("ssh_X509_NAME_add_entry_by_NID:" + " UTF8_putc fail for symbol %ld", ch); + return(0); + } + } else { + *p = (u_char)ch; + ret = 1; } k -= ret; p += ret; @@ -317,7 +408,7 @@ error("ssh_X509_NAME_add_entry_by_NID: X509_NAME_add_entry_by_NID" " fail with errormsg='%.*s'" " for nid=%d/%.32s" - " and data='%.128s'" + " and data='%.512s'" , sizeof(ebuf), openssl_errormsg(ebuf, sizeof(ebuf)) , nid, OBJ_nid2ln(nid) , str); @@ -341,7 +432,7 @@ p = (char*)str; while (*p) { int nid; - for (; *p && isspace((int)*p); p++) + for (; *p && ISSPACE(*p); p++) {/*skip space*/} if (!*p) break; @@ -373,7 +464,7 @@ } { char *s = q; - for(--s; isspace((int)*s) && (s > p); s--) + for(--s; ISSPACE(*s) && (s > p); s--) {/*skip trailing space*/} *++s = 0; } @@ -399,9 +490,9 @@ break; } - for (; *p && isspace((int)*p); p++) + for (; *p && ISSPACE(*p); p++) {/*skip space*/} - for (q = token - 1; (q >= p) && isspace((int)*q); q--) + for (q = token - 1; (q >= p) && ISSPACE(*q); q--) {/*skip unexpected \n, etc. from end*/} *++q = 0; @@ -434,13 +525,13 @@ debug3("x509key_from_subject: %d is not x509 key", _keytype); return(NULL); } - debug3("x509key_from_subject(%d, [%.*s]) called", - _keytype, X509_NAME_MAXLEN, (_cp ? _cp : "")); + debug3("x509key_from_subject(%d, [%.1024s]) called", + _keytype, (_cp ? _cp : "")); subject = x509key_find_subject(_cp); if (subject == NULL) return(NULL); - debug3("x509key_from_subject: subject=[%.*s]", X509_NAME_MAXLEN, subject); + debug3("x509key_from_subject: subject=[%.1024s]", subject); key = key_new(_keytype); if (key == NULL) { error("x509key_from_subject: out of memory"); @@ -589,13 +680,13 @@ char* x509key_subject(const Key *key) { - char *buf = NULL; + X509_NAME *dn; - if (!x509key_check("x509key_subject", key)) return(buf); + if (!x509key_check("x509key_subject", key)) return(NULL); - buf = xmalloc(X509_NAME_MAXLEN); /*fatal on error*/ - X509_NAME_oneline(X509_get_subject_name(key->x509), buf, X509_NAME_MAXLEN); - return(buf); + /* it is better to match format used in x509key_write_subject */ + dn = X509_get_subject_name(key->x509); + return(ssh_X509_NAME_oneline(dn)); /*fatal on error*/ } @@ -642,9 +733,6 @@ int x509key_write_subject2(const Key *key, const char *keyname, FILE *f) { BIO *out; -#if 0 - char buf[X509_NAME_MAXLEN]; -#endif if (!x509key_check("x509key_write_subject2", key)) return(0); if (keyname == NULL) return(0); @@ -660,12 +748,7 @@ BIO_puts(out, keyname); BIO_puts(out, " Subject:"); -#if 0 - X509_NAME_oneline(X509_get_subject_name(key->x509), buf, sizeof(buf)); - BIO_puts(out, buf); -#else - X509_NAME_print_ex(out, X509_get_subject_name(key->x509), 0, SSH_XN_FLAG_ONELINE); -#endif + ssh_X509_NAME_print(out, X509_get_subject_name(key->x509)); BIO_free_all(out); return(1); @@ -698,7 +781,6 @@ x509key_save_cert(FILE *fp, X509 *x509) { int ret = 0; BIO *out; - char buf[X509_NAME_MAXLEN]; out = BIO_new_fp(fp, BIO_NOCLOSE); if (out == NULL) return(0); @@ -710,20 +792,20 @@ #endif BIO_puts(out, "issuer= "); - X509_NAME_oneline(X509_get_issuer_name(x509), buf, sizeof(buf)); - BIO_puts(out, buf); + ssh_X509_NAME_print(out, X509_get_issuer_name(x509)); BIO_puts(out, "\n"); BIO_puts(out, "subject= "); - X509_NAME_oneline(X509_get_subject_name(x509), buf, sizeof(buf)); - BIO_puts(out, buf); + ssh_X509_NAME_print(out, X509_get_subject_name(x509)); BIO_puts(out, "\n"); + { const char *alstr = (const char*)X509_alias_get0(x509, NULL); if (alstr == NULL) alstr = ""; BIO_puts(out, alstr); BIO_puts(out, "\n"); } + ret = PEM_write_bio_X509(out, x509); if (!ret) { char ebuf[256]; diff -ruN openssh-4.6p1+x509-6.0.1/tests/CA/test-by_ldap.sh.inc openssh-4.6p1+x509-6.1/tests/CA/test-by_ldap.sh.inc --- openssh-4.6p1+x509-6.0.1/tests/CA/test-by_ldap.sh.inc 2007-08-28 01:08:05.000000000 +0300 +++ openssh-4.6p1+x509-6.1/tests/CA/test-by_ldap.sh.inc 2007-10-22 22:30:52.000000000 +0300 @@ -217,7 +217,7 @@ creTestSSHDcfgFile #openssh config parser limitation -SSH_CONF_LDAP_DC=`echo ${SSH_LDAP_DC} | sed -e 's|=|%3D|g'` +SSH_CONF_LDAP_DC=`echo ${SSH_LDAP_DC} | sed -e 's|=|%3D|g' -e 's|,|%2C|'` cat >> "$SSHD_CFG" < +#ifndef LDAP_DEPRECATED + /* to suppress warnings in some 2.3x versions */ +# define LDAP_DEPRECATED 0 +#endif #include @@ -87,6 +91,88 @@ } +/* ================================================================== */ +/* wrappers to some depricated functions */ +static void +ldaplookup_parse_result ( + LDAP *ld, + LDAPMessage *res +) { + static const int freeit = 0; + int result; +#ifdef HAVE_LDAP_PARSE_RESULT + int ret; + char *matcheddn; + char *errmsg; + + ret = ldap_parse_result(ld, res, &result, &matcheddn, &errmsg, NULL, NULL, freeit); + if (ret == LDAP_SUCCESS) { + if (errmsg) ERR_add_error_data(1, errmsg); + } + if (matcheddn) ldap_memfree(matcheddn); + if (errmsg) ldap_memfree(errmsg); +#else + result = ldap_result2error(ld, res, freeit); + openssl_add_ldap_error(result); +#endif +} + + +static int +ldaplookup_bind_s(LDAP *ld) { + int result; + + /* anonymous bind - data must be retrieved by anybody */ +#ifdef HAVE_LDAP_SASL_BIND_S +{ + static struct berval cred = { 0, (char*)"" }; + + result = ldap_sasl_bind_s( + ld, NULL/*dn*/, LDAP_SASL_SIMPLE, &cred, + NULL, NULL, NULL); +} +#else + result = ldap_simple_bind_s(ld, NULL/*binddn*/, NULL/*bindpw*/); +#endif + +#ifdef TRACE_BY_LDAP +fprintf(stderr, "TRACE_BY_LDAP ldaplookup_bind_s:" +" ldap_XXX_bind_s return 0x%x(%s)\n" +, result, ldap_err2string(result)); +#endif + return(result); +} + + +static int +ldaplookup_search_s( + LDAP *ld, + LDAP_CONST char *base, + int scope, + LDAP_CONST char *filter, + char **attrs, + int attrsonly, + LDAPMessage **res +) { + int result; +#ifdef HAVE_LDAP_SEARCH_EXT_S + result = ldap_search_ext_s(ld, base, + scope, filter, attrs, attrsonly, + NULL, NULL, NULL, 0, res); +#else + result = ldap_search_s(ld, base, scope, filter, attrs, attrsonly, res); +#endif + +#ifdef TRACE_BY_LDAP +fprintf(stderr, "TRACE_BY_LDAP ldaplookup_search_s:" +"\n base=%s\n filter=%s\n" +" ldap_search_{XXX}s return 0x%x(%s)\n" +, base, filter +, result, ldap_err2string(result)); +#endif + return(result); +} + /* ================================================================== */ /* LOOKUP by LDAP */ @@ -144,6 +230,8 @@ ldaplookup_ctrl(X509_LOOKUP *ctx, int cmd, const char *argc, long argl, char **retp) { int ret = 0; + (void)argl; + (void)retp; #ifdef TRACE_BY_LDAP fprintf(stderr, "TRACE_BY_LDAP ldaplookup_ctrl: cmd=%d, argc=%s\n", cmd, argc); #endif @@ -199,6 +287,7 @@ #ifdef TRACE_BY_LDAP fprintf(stderr, "TRACE_BY_LDAP ldaplookup_init:\n"); #endif + (void)ctx; return(1); } @@ -208,6 +297,7 @@ #ifdef TRACE_BY_LDAP fprintf(stderr, "TRACE_BY_LDAP ldaplookup_shutdown:\n"); #endif + (void)ctx; return(1); } @@ -233,7 +323,7 @@ goto error; } - ret = ldap_url_parse(url, &p->ldapurl); + ret = ldap_url_parse(p->url, &p->ldapurl); if (ret != 0) { X509byLDAPerr(X509byLDAP_F_LDAPHOST_NEW, X509byLDAP_R_INVALID_URL); openssl_add_ldap_error(ret); @@ -245,11 +335,23 @@ #endif /* open ldap connection */ +#ifdef HAVE_LDAP_INITIALIZE + ret = ldap_initialize(&p->ld, p->url); + if (ret != LDAP_SUCCESS) { + X509byLDAPerr(X509byLDAP_F_LDAPHOST_NEW, X509byLDAP_R_INITIALIZATION_ERROR); + openssl_add_ldap_error(ret); + goto error; + } +#ifdef TRACE_BY_LDAP +fprintf(stderr, "TRACE_BY_LDAP ldaphost_new: ldap_initialize(..., url=%s)\n", p->url); +#endif +#else /*ndef HAVE_LDAP_INITIALIZE*/ 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; } +#endif /*ndef HAVE_LDAP_INITIALIZE*/ { int version = -1; @@ -330,6 +432,9 @@ if (ver == NULL) return(0); p = (ldaphost*) ctx->method_data; +#ifdef TRACE_BY_LDAP +fprintf(stderr, "TRACE_BY_LDAP ldaplookup_set_protocol(..., %s) p=%p\n", ver, (void*)p); +#endif if (p == NULL) return(0); n = (int) strtol(ver, &q, 10); @@ -558,9 +663,8 @@ 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); + ldaplookup_parse_result (ld, res); goto done; } #ifdef TRACE_BY_LDAP @@ -673,8 +777,7 @@ } #endif - /* anonymous bind - data must be retrieved by anybody */ - result = ldap_simple_bind_s(lh->ld, NULL/*binddn*/, NULL/*bindpw*/); + result = ldaplookup_bind_s(lh->ld); if (result != LDAP_SUCCESS) { X509byLDAPerr(X509byLDAP_F_GET_BY_SUBJECT, X509byLDAP_R_UNABLE_TO_BIND); { @@ -690,13 +793,8 @@ 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 - + result = ldaplookup_search_s(lh->ld, lh->ldapurl->lud_dn, + LDAP_SCOPE_SUBTREE, filter, (char**)attrs, 0, &res); if (result != LDAP_SUCCESS) { X509byLDAPerr(X509byLDAP_F_GET_BY_SUBJECT, X509byLDAP_R_SEARCH_FAIL); ldap_msgfree(res); @@ -758,7 +856,7 @@ 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); +fprintf(stderr, "TRACE_BY_LDAP ldaplookup_by_subject: k=%d, tmp=%p\n", k, (void*)tmp); #endif if (tmp == NULL) { diff -ruN openssh-4.6p1+x509-6.0.1/x509_nm_cmp.c openssh-4.6p1+x509-6.1/x509_nm_cmp.c --- openssh-4.6p1+x509-6.0.1/x509_nm_cmp.c 2007-01-27 18:37:52.000000000 +0200 +++ openssh-4.6p1+x509-6.1/x509_nm_cmp.c 2007-10-21 19:48:55.000000000 +0300 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005 Roumen Petrov. All rights reserved. + * Copyright (c) 2005-2007 Roumen Petrov. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -31,6 +31,7 @@ #include "x509store.h" #include "log.h" +#include "xmalloc.h" static int @@ -184,7 +185,7 @@ n = -1; goto done; } - lb = ssh_ASN1_STRING_to_UTF8(&ub, a); + lb = ssh_ASN1_STRING_to_UTF8(&ub, b); if (lb <= 0) { /*second string is greater in case of error or zero length*/ n = 1; @@ -394,16 +395,16 @@ nid = OBJ_obj2nid(neA->object); loc = X509_NAME_get_index_by_NID(b, nid, -1); if (loc < 0) { - char buf1[X509_NAME_MAXLEN]; - char buf2[X509_NAME_MAXLEN]; + char *buf1, *buf2; - X509_NAME_oneline(_a, buf1, sizeof(buf1)); - X509_NAME_oneline(_b, buf2, sizeof(buf2)); + buf1 = ssh_X509_NAME_oneline(_a); /*fatal on error*/ + buf2 = ssh_X509_NAME_oneline(_b); /*fatal on error*/ debug3("ssh_X509_NAME_cmp: insufficient entries with nid=%d(%.40s) in second name." - " na=%.*s, nb=%.*s", + " na=%s, nb=%s", nid, OBJ_nid2ln(nid), - (int) sizeof(buf1), buf1, - (int) sizeof(buf1), buf2); + buf1, buf2); + xfree(buf1); + xfree(buf2); n = -1; break; } diff -ruN openssh-4.6p1+x509-6.0.1/x509store.c openssh-4.6p1+x509-6.1/x509store.c --- openssh-4.6p1+x509-6.0.1/x509store.c 2006-09-01 21:23:45.000000000 +0300 +++ openssh-4.6p1+x509-6.1/x509store.c 2007-10-24 00:15:30.000000000 +0300 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002-2006 Roumen Petrov. All rights reserved. + * Copyright (c) 2002-2007 Roumen Petrov. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -120,13 +120,14 @@ ok = ssh_is_selfsigned(ctx->cert); } if (!ok) { - char buf[X509_NAME_MAXLEN]; - X509_NAME_oneline(X509_get_subject_name(ctx->current_cert), buf, sizeof(buf)); - error("ssh_x509store_cb: subject='%.*s', error %d at %d depth lookup:%.200s", - (int) sizeof(buf), buf, + char *buf; + buf = ssh_X509_NAME_oneline(X509_get_subject_name(ctx->current_cert)); /*fatal on error*/ + error("ssh_x509store_cb: subject='%s', error %d at %d depth lookup:%.200s", + buf, ctx->error, ctx->error_depth, X509_verify_cert_error_string(ctx->error)); + xfree(buf); #if 0 if (ctx->error == X509_V_ERR_CERT_HAS_EXPIRED) ok=1; @@ -267,16 +268,22 @@ #ifndef SSH_X509STORE_DISABLED int/*bool*/ ssh_is_selfsigned(X509 *_cert) { - char buf[X509_NAME_MAXLEN]; X509_NAME *issuer, *subject; issuer = X509_get_issuer_name(_cert); - X509_NAME_oneline(issuer, buf, sizeof(buf)); - debug3("ssh_is_selfsigned: issuer='%.*s'", (int) sizeof(buf), buf); - subject = X509_get_subject_name(_cert); - X509_NAME_oneline(subject, buf, sizeof(buf)); - debug3("ssh_is_selfsigned: subject='%.*s'", (int) sizeof(buf), buf); + + if (get_log_level() >= SYSLOG_LEVEL_DEBUG3) { + char *buf; + + buf = ssh_X509_NAME_oneline(issuer); /*fatal on error*/ + debug3("ssh_is_selfsigned: issuer='%s'", buf); + xfree(buf); + + buf = ssh_X509_NAME_oneline(subject); /*fatal on error*/ + debug3("ssh_is_selfsigned: subject='%s'", buf); + xfree(buf); + } return (ssh_X509_NAME_cmp(issuer, subject) == 0); } @@ -574,13 +581,15 @@ #ifndef SSH_X509STORE_DISABLED if (x509store == NULL) { error("ssh_x509cert_check: context is NULL"); - return(-1); + ret = -1; + goto done; } if (get_log_level() >= SYSLOG_LEVEL_DEBUG3) { - char buf[X509_NAME_MAXLEN]; - X509_NAME_oneline( X509_get_subject_name(_cert), buf, sizeof(buf)); - debug3("ssh_x509cert_check: for '%.*s'", (int) sizeof(buf), buf); + char *buf; + buf = ssh_X509_NAME_oneline(X509_get_subject_name(_cert)); /*fatal on error*/ + debug3("ssh_x509cert_check: for '%s'", buf); + xfree(buf); } csc = X509_STORE_CTX_new(); @@ -592,7 +601,8 @@ /* clear rest of errors in OpenSSL "error buffer" */ ERR_clear_error(); - return(-1); + ret = -1; + goto done; } ret = ssh_verify_cert(csc, _cert); @@ -658,7 +668,11 @@ } } #endif /*def SSH_X509STORE_DISABLED*/ - debug3("ssh_x509cert_check: return %d", ret); +done: +{ + const char *msg = (ret > 0) ? "trusted" : (ret < 0 ? "error" : "rejected"); + debug3("ssh_x509cert_check: return %d(%s)", ret, msg); +} return(ret); } @@ -668,18 +682,17 @@ static void ssh_get_namestr_and_hash( X509_NAME *name, - char *buf, - size_t len, + char **buf, u_long *hash ) { if (name == NULL) { debug("ssh_get_namestr_and_hash: name is NULL"); - if (buf ) *buf = '\0'; + if (buf ) *buf = NULL; if (hash) *hash = 0; /* not correct but :-( */ return; } - if (buf ) X509_NAME_oneline(name, buf, len); + if (buf ) *buf = ssh_X509_NAME_oneline(name); /*fatal on error*/ if (hash) *hash = X509_NAME_hash(name); } @@ -688,7 +701,6 @@ ssh_check_crl(X509_STORE_CTX *_ctx, X509* _issuer, X509_CRL *_crl) { time_t *pcheck_time; int k; - char buf[X509_NAME_MAXLEN]; u_long hash; if (_issuer == NULL) { @@ -710,12 +722,12 @@ return(0); /* ;-) */ } - X509_NAME_oneline(X509_CRL_get_issuer(_crl), buf, sizeof(buf)); + ssh_X509_NAME_print(bio, X509_CRL_get_issuer(_crl)); - BIO_printf(bio, ", Last Update: "); + BIO_printf(bio, "; Last Update: "); ASN1_UTCTIME_print(bio, X509_CRL_get_lastUpdate(_crl)); - BIO_printf(bio, ", Next Update: "); + BIO_printf(bio, "; Next Update: "); ASN1_UTCTIME_print(bio, X509_CRL_get_nextUpdate(_crl)); k = BIO_pending(bio); @@ -723,7 +735,7 @@ k = BIO_read(bio, p, k); p[k] = '\0'; - debug3("ssh_check_crl: Issuer: %s%s", buf, p); + debug3("ssh_check_crl: Issuer: %s", p); xfree(p); BIO_free(bio); @@ -738,17 +750,18 @@ if (/*???(_issuer->ex_flags & EXFLAG_KUSAGE) &&*/ !(_issuer->ex_kusage & KU_CRL_SIGN) ) { - ssh_get_namestr_and_hash(X509_get_subject_name(_issuer), buf, sizeof(buf), &hash); - error("ssh_check_crl:" - " to verify crl signature key usage 'cRLSign'" - " must present in issuer certificate '%.*s' with hash=0x%08lx" - , (int) sizeof(buf), buf - , hash - ); + char *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 + ssh_get_namestr_and_hash(X509_get_subject_name(_issuer), &buf, &hash); + error("ssh_check_crl:" + " to verify crl signature key usage 'cRLSign'" + " must present in issuer certificate '%s' with hash=0x%08lx" + , buf, hash + ); + xfree(buf); return(0); } @@ -761,13 +774,15 @@ } if (X509_CRL_verify(_crl, pkey) <= 0) { - ssh_get_namestr_and_hash(X509_CRL_get_issuer(_crl), buf, sizeof(buf), &hash); + char *buf; + + ssh_get_namestr_and_hash(X509_CRL_get_issuer(_crl), &buf, &hash); error("ssh_check_crl: CRL has invalid signature" - ": issuer='%.*s', hash=0x%08lx" - , (int) sizeof(buf), buf - , hash + ": issuer='%s', hash=0x%08lx" + , buf, hash ); X509_STORE_CTX_set_error(_ctx, X509_V_ERR_CRL_SIGNATURE_FAILURE); + xfree(buf); return(0); } EVP_PKEY_free(pkey); @@ -781,35 +796,41 @@ k = X509_cmp_time(X509_CRL_get_lastUpdate(_crl), pcheck_time); if (k == 0) { - ssh_get_namestr_and_hash(X509_CRL_get_issuer(_crl), buf, sizeof(buf), &hash); + char *buf; + + ssh_get_namestr_and_hash(X509_CRL_get_issuer(_crl), &buf, &hash); error("ssh_check_crl: CRL has invalid lastUpdate field" - ": issuer='%.*s', hash=0x%08lx" - , (int) sizeof(buf), buf - , hash + ": issuer='%s', hash=0x%08lx" + , buf, hash ); X509_STORE_CTX_set_error(_ctx, X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD); + xfree(buf); return(0); } if (k > 0) { - ssh_get_namestr_and_hash(X509_CRL_get_issuer(_crl), buf, sizeof(buf), &hash); + char *buf; + + ssh_get_namestr_and_hash(X509_CRL_get_issuer(_crl), &buf, &hash); error("ssh_check_crl: CRL is not yet valid" - ": issuer='%.*s', hash=0x%08lx" - , (int) sizeof(buf), buf - , hash + ": issuer='%s', hash=0x%08lx" + , buf, hash ); X509_STORE_CTX_set_error(_ctx, X509_V_ERR_CRL_NOT_YET_VALID); + xfree(buf); return(0); } k = X509_cmp_time(X509_CRL_get_nextUpdate(_crl), pcheck_time); if (k == 0) { - ssh_get_namestr_and_hash(X509_CRL_get_issuer(_crl), buf, sizeof(buf), &hash); + char *buf; + + ssh_get_namestr_and_hash(X509_CRL_get_issuer(_crl), &buf, &hash); error("ssh_check_crl: CRL has invalid nextUpdate field" - ": issuer='%.*s', hash=0x%08lx" - , (int) sizeof(buf), buf - , hash + ": issuer='%s', hash=0x%08lx" + , buf, hash ); X509_STORE_CTX_set_error(_ctx, X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD); + xfree(buf); return(0); } #if 0 @@ -825,13 +846,15 @@ } #endif if (k < 0) { - ssh_get_namestr_and_hash(X509_CRL_get_issuer(_crl), buf, sizeof(buf), &hash); + char *buf; + + ssh_get_namestr_and_hash(X509_CRL_get_issuer(_crl), &buf, &hash); error("ssh_check_crl: CRL is expired" - ": issuer='%.*s', hash=0x%08lx" - , (int) sizeof(buf), buf - , hash + ": issuer='%s', hash=0x%08lx" + , buf, hash ); X509_STORE_CTX_set_error(_ctx, X509_V_ERR_CRL_HAS_EXPIRED); + xfree(buf); return(0); } @@ -843,7 +866,7 @@ ssh_is_cert_revoked(X509_STORE_CTX *_ctx, X509_CRL *_crl, X509 *_cert) { X509_REVOKED revoked; int k; - char *p, buf1[X509_NAME_MAXLEN], buf2[X509_NAME_MAXLEN]; + char *dn, *ser, *in; if (_crl == NULL) return(1); revoked.serialNumber = X509_get_serialNumber(_cert); @@ -852,15 +875,15 @@ X509_STORE_CTX_set_error(_ctx, X509_V_ERR_CERT_REVOKED); /* yes, revoked. print log and ...*/ - p = ssh_ASN1_INTEGER_2_string(revoked.serialNumber); - X509_NAME_oneline(X509_get_subject_name(_cert), buf1, sizeof(buf1)); - X509_NAME_oneline(X509_CRL_get_issuer (_crl ), buf2, sizeof(buf2)); - - error("certificate '%.*s' with serial '%.40s' revoked from issuer '%.*s'" - , (int) sizeof(buf1), buf1 - , p - , (int) sizeof(buf2), buf2); - xfree(p); + dn = ssh_X509_NAME_oneline(X509_get_subject_name(_cert)); /*fatal on error*/ + ser = ssh_ASN1_INTEGER_2_string(revoked.serialNumber); + in = ssh_X509_NAME_oneline(X509_CRL_get_issuer (_crl )); /*fatal on error*/ + + error("certificate '%s' with serial '%.40s' revoked from issuer '%s'" + , dn, ser, in); + xfree(dn); + xfree(ser); + xfree(in); return(1); } @@ -882,13 +905,15 @@ } if (get_log_level() >= SYSLOG_LEVEL_DEBUG3) { - char buf[X509_NAME_MAXLEN]; - - X509_NAME_oneline(X509_get_issuer_name(cert), buf, sizeof(buf)); - debug3("ssh_x509revoked_cb: issuer =%.*s", (int) sizeof(buf), buf); + char *buf; - X509_NAME_oneline(X509_get_subject_name(cert), buf, sizeof(buf)); - debug3("ssh_x509revoked_cb: subject=%.*s", (int) sizeof(buf), buf); + buf = ssh_X509_NAME_oneline(X509_get_issuer_name(cert)); /*fatal on error*/ + debug3("ssh_x509revoked_cb: Issuer: %s", buf); + xfree(buf); + + buf = ssh_X509_NAME_oneline(X509_get_subject_name(cert)); /*fatal on error*/ + debug3("ssh_x509revoked_cb: Subject: %s", buf); + xfree(buf); } memset(&xobj, 0, sizeof(xobj)); diff -ruN openssh-4.6p1+x509-6.0.1/x509store.h openssh-4.6p1+x509-6.1/x509store.h --- openssh-4.6p1+x509-6.0.1/x509store.h 2007-02-27 23:00:42.000000000 +0200 +++ openssh-4.6p1+x509-6.1/x509store.h 2007-10-04 22:54:04.000000000 +0300 @@ -1,7 +1,7 @@ #ifndef X509STORE_H #define X509STORE_H /* - * Copyright (c) 2002-2006 Roumen Petrov. All rights reserved. + * Copyright (c) 2002-2007 Roumen Petrov. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -28,11 +28,8 @@ #include -#define X509_NAME_MAXLEN 512 -#define SSH_XN_FLAG_ONELINE ((XN_FLAG_ONELINE & \ - ~XN_FLAG_SPC_EQ & \ - ~XN_FLAG_SEP_MASK) | \ - XN_FLAG_SEP_COMMA_PLUS) +int ssh_X509_NAME_print(BIO* bio, X509_NAME *xn); +char* ssh_X509_NAME_oneline(X509_NAME *xn); int ssh_x509cert_check(X509 *_cert);