diff options
author | mnag <mnag@FreeBSD.org> | 2008-04-19 21:46:24 +0800 |
---|---|---|
committer | mnag <mnag@FreeBSD.org> | 2008-04-19 21:46:24 +0800 |
commit | 1ed95390b175ae8673933f14555a7bf4f1f5096a (patch) | |
tree | 76743158244507c2643bbfaf9721ab7a8c8d3683 /security/openssh-portable | |
parent | 57b3a47c812818a2afdd011255e006a2978c6f70 (diff) | |
download | freebsd-ports-gnome-1ed95390b175ae8673933f14555a7bf4f1f5096a.tar.gz freebsd-ports-gnome-1ed95390b175ae8673933f14555a7bf4f1f5096a.tar.zst freebsd-ports-gnome-1ed95390b175ae8673933f14555a7bf4f1f5096a.zip |
- Update to 5.0p1
- Port LPK patch to 5.0p1 and add to files dir
- Remove USE_PERL_BUILD since doesn't need [1]
- Update KERB_GSSAPI to 5.0p1
- Update HPN patch to 5.0p1 13v3
- Respect LOCALBASE on configure_args of LPK [2]
- Change MASTER_SITE of snapshot
- portlint(1)
PR: 121826 [2]
Submitted by: Andrew Kolchoogin <andrew___rinet.ru> [2]
Reported by: Björn König <bkoenig___alpha-tierchen.d [1]
Diffstat (limited to 'security/openssh-portable')
-rw-r--r-- | security/openssh-portable/Makefile | 27 | ||||
-rw-r--r-- | security/openssh-portable/distinfo | 21 | ||||
-rw-r--r-- | security/openssh-portable/files/openssh-lpk-5.0p1-0.3.9.patch | 1866 | ||||
-rw-r--r-- | security/openssh-portable/files/patch-auth2.c | 18 | ||||
-rw-r--r-- | security/openssh-portable/files/patch-session.c | 41 |
5 files changed, 1915 insertions, 58 deletions
diff --git a/security/openssh-portable/Makefile b/security/openssh-portable/Makefile index e93940fecca3..9a846065a04f 100644 --- a/security/openssh-portable/Makefile +++ b/security/openssh-portable/Makefile @@ -6,14 +6,15 @@ # PORTNAME= openssh -DISTVERSION= 4.7p1 -PORTREVISION= 1 +DISTVERSION= 5.0p1 PORTEPOCH= 1 CATEGORIES= security ipv6 -MASTER_SITES= ftp://ftp.openbsd.org/pub/OpenBSD/OpenSSH/portable/%SUBDIR%/ \ - ftp://carroll.cac.psu.edu/pub/OpenBSD/OpenSSH/portable/%SUBDIR%/ \ - http://mirror.mcs.anl.gov/openssh/portable/%SUBDIR%/ -MASTER_SITE_SUBDIR= # empty +.if defined(OPENSSH_SNAPSHOT) +MASTER_SITES= http://www.mindrot.org/openssh_snap/ +.else +MASTER_SITES= ${MASTER_SITE_OPENBSD} +MASTER_SITE_SUBDIR= OpenSSH/portable +.endif PKGNAMESUFFIX= ${PORTABLE_SUFFIX}${GSSAPI_SUFFIX}${BASE_SUFFIX} DISTNAME= # empty @@ -23,7 +24,6 @@ COMMENT= The portable version of OpenBSD's OpenSSH .if defined(OPENSSH_SNAPSHOT) PORTREVISION!= date -v-1d +%Y%m%d NO_CHECKSUM= yes -MASTER_SITE_SUBDIR+= snapshot DISTNAME+= ${PORTNAME}-SNAP-${PORTREVISION} .else DISTNAME+= ${PORTNAME}-${DISTVERSION} @@ -39,7 +39,6 @@ MAN8= sftp-server.8 sshd.8 ssh-keysign.8 CONFLICTS?= openssh-3.* ssh-1.* ssh2-3.* USE_OPENSSL= yes -USE_PERL5_BUILD= yes GNU_CONFIGURE= yes CONFIGURE_TARGET= --build=${MACHINE_ARCH}-portbld-freebsd${OSREL} CONFIGURE_ARGS= --prefix=${PREFIX} --with-md5-passwords \ @@ -95,7 +94,7 @@ CONFIGURE_ARGS+= --disable-suid-ssh .if defined(WITH_KERB_GSSAPI) PATCH_DIST_STRIP= -p0 PATCH_SITES+= http://www.sxw.org.uk/computing/patches/ -PATCHFILES+= openssh-4.7p1-gsskex-20070927.patch +PATCHFILES+= openssh-5.0p1-gsskex-20080404.patch .endif PORTABLE_SUFFIX= # empty GSSAPI_SUFFIX= -gssapi @@ -140,18 +139,16 @@ BROKEN= HPN and LPK patches are incompatible .if defined(WITH_HPN) PATCH_DIST_STRIP= -p1 PATCH_SITES+= http://www.psc.edu/networking/projects/hpn-ssh/ -PATCHFILES+= openssh-4.7p1-hpn12v20.diff.gz +PATCHFILES+= openssh-5.0p1-hpn13v3.diff.gz .endif # See http://dev.inversepath.com/trac/openssh-lpk .if defined(WITH_LPK) -PATCH_DIST_STRIP= -p2 -PATCH_SITES+= http://dev.inversepath.com/openssh-lpk/ -PATCHFILES+= openssh-lpk-4.6p1-0.3.9.patch +EXTRA_PATCHES= ${FILESDIR}/openssh-lpk-5.0p1-0.3.9.patch USE_OPENLDAP= yes CPPFLAGS+= "-I${LOCALBASE}/include -DWITH_LDAP_PUBKEY" -CONFIGURE_ARGS+= --with-libs='-lldap' --with-ldflags='-L/usr/local/lib' \ - --with-cppflags='-I/usr/local/include -DWITH_LDAP_PUBKEY' +CONFIGURE_ARGS+= --with-libs='-lldap' --with-ldflags='-L${LOCALBASE}/lib' \ + --with-cppflags='-I${LOCALBASE}/include -DWITH_LDAP_PUBKEY' .endif .if defined(WITH_OVERWRITE_BASE) diff --git a/security/openssh-portable/distinfo b/security/openssh-portable/distinfo index 081637187654..f67d71ba2e51 100644 --- a/security/openssh-portable/distinfo +++ b/security/openssh-portable/distinfo @@ -1,12 +1,9 @@ -MD5 (openssh-4.7p1.tar.gz) = 50a800fd2c6def9e9a53068837e87b91 -SHA256 (openssh-4.7p1.tar.gz) = d47133f0c6737d2889bf8da7bdf389fc2268d1c7fa3cd11a52451501eab548bc -SIZE (openssh-4.7p1.tar.gz) = 991119 -MD5 (openssh-4.7p1-gsskex-20070927.patch) = ad58a9848dcaa3ad5a2ab14182fb9212 -SHA256 (openssh-4.7p1-gsskex-20070927.patch) = 7ef9009baa842c696d356c7e5e5d022797a227531c1662dd998510e45a6dd597 -SIZE (openssh-4.7p1-gsskex-20070927.patch) = 66693 -MD5 (openssh-4.7p1-hpn12v20.diff.gz) = 7a75e87b03e4d713973c5a3330a68ab5 -SHA256 (openssh-4.7p1-hpn12v20.diff.gz) = 4b951b444f3c093ca3dbb1ae6e9825c33610719ee8ca593e660ec8248c5b09c6 -SIZE (openssh-4.7p1-hpn12v20.diff.gz) = 15211 -MD5 (openssh-lpk-4.6p1-0.3.9.patch) = f43a8aae7d69e72f0ec07bc96e46b328 -SHA256 (openssh-lpk-4.6p1-0.3.9.patch) = e12335e8bf020508ea3866db07b306f4c965e3f9de262c06f62fad494e93107e -SIZE (openssh-lpk-4.6p1-0.3.9.patch) = 61605 +MD5 (openssh-5.0p1.tar.gz) = 1f1dfaa775f33dd3328169de9bdc292a +SHA256 (openssh-5.0p1.tar.gz) = 73a58620cd475155be8524f46997ba1942bc9e54204eeb15f0465e54ca279f4f +SIZE (openssh-5.0p1.tar.gz) = 1011556 +MD5 (openssh-5.0p1-gsskex-20080404.patch) = d13bf38e852e38b7f29b9e6993b00b52 +SHA256 (openssh-5.0p1-gsskex-20080404.patch) = 8f8b9910af767ce8e2a5d4854e95c8eb8b089bb250b290d22add38e9ddb1791e +SIZE (openssh-5.0p1-gsskex-20080404.patch) = 68272 +MD5 (openssh-5.0p1-hpn13v3.diff.gz) = 95e7f78d63b419babd820c0653aa47ef +SHA256 (openssh-5.0p1-hpn13v3.diff.gz) = e9000f969705dbdf72f7ea069e5f8a2475eb89e88e014c678ecb102ddf4bcde2 +SIZE (openssh-5.0p1-hpn13v3.diff.gz) = 24060 diff --git a/security/openssh-portable/files/openssh-lpk-5.0p1-0.3.9.patch b/security/openssh-portable/files/openssh-lpk-5.0p1-0.3.9.patch new file mode 100644 index 000000000000..42af2785a984 --- /dev/null +++ b/security/openssh-portable/files/openssh-lpk-5.0p1-0.3.9.patch @@ -0,0 +1,1866 @@ +# +# Based on: http://dev.inversepath.com/openssh-lpk/openssh-lpk-4.6p1-0.3.9.patch +# +--- Makefile.in.orig 2008-03-12 22:41:31.000000000 -0300 ++++ Makefile.in 2008-04-17 21:25:41.000000000 -0300 +@@ -86,7 +86,7 @@ + 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 \ +- audit.o audit-bsm.o platform.o sftp-server.o sftp-common.o ++ audit.o audit-bsm.o platform.o sftp-server.o sftp-common.o ldapauth.o + + 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 +--- README.lpk.orig 2008-04-17 21:24:57.000000000 -0300 ++++ README.lpk 2008-04-17 21:24:57.000000000 -0300 +@@ -0,0 +1,267 @@ ++OpenSSH LDAP PUBLIC KEY PATCH ++Copyright (c) 2003 Eric AUGE (eau@phear.org) ++All rights reserved. ++ ++Redistribution and use in source and binary forms, with or without ++modification, are permitted provided that the following conditions ++are met: ++1. Redistributions of source code must retain the above copyright ++ notice, this list of conditions and the following disclaimer. ++2. Redistributions in binary form must reproduce the above copyright ++ notice, this list of conditions and the following disclaimer in the ++ documentation and/or other materials provided with the distribution. ++3. The name of the author may not be used to endorse or promote products ++ derived from this software without specific prior written permission. ++ ++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. ++ ++purposes of this patch: ++ ++This patch would help to have authentication centralization policy ++using ssh public key authentication. ++This patch could be an alternative to other "secure" authentication system ++working in a similar way (Kerberos, SecurID, etc...), except the fact ++that it's based on OpenSSH and its public key abilities. ++ ++>> FYI: << ++'uid': means unix accounts existing on the current server ++'lpkServerGroup:' mean server group configured on the current server ('lpkServerGroup' in sshd_config) ++ ++example schema: ++ ++ ++ server1 (uid: eau,rival,toto) (lpkServerGroup: unix) ++ ___________ / ++ / \ --- - server3 (uid: eau, titi) (lpkServerGroup: unix) ++ | LDAP Server | \ ++ | eau ,rival | server2 (uid: rival, eau) (lpkServerGroup: unix) ++ | titi ,toto | ++ | userx,.... | server5 (uid: eau) (lpkServerGroup: mail) ++ \___________/ \ / ++ ----- - server4 (uid: eau, rival) (no group configured) ++ \ ++ etc... ++ ++- WHAT WE NEED : ++ ++ * configured LDAP server somewhere on the network (i.e. OpenLDAP) ++ * patched sshd (with this patch ;) ++ * LDAP user(/group) entry (look at users.ldif (& groups.ldif)): ++ User entry: ++ - attached to the 'ldapPublicKey' objectclass ++ - attached to the 'posixAccount' objectclass ++ - with a filled 'sshPublicKey' attribute ++ Example: ++ dn: uid=eau,ou=users,dc=cuckoos,dc=net ++ objectclass: top ++ objectclass: person ++ objectclass: organizationalPerson ++ objectclass: posixAccount ++ objectclass: ldapPublicKey ++ description: Eric AUGE Account ++ userPassword: blah ++ cn: Eric AUGE ++ sn: Eric AUGE ++ uid: eau ++ uidNumber: 1034 ++ gidNumber: 1 ++ homeDirectory: /export/home/eau ++ sshPublicKey: ssh-dss AAAAB3... ++ sshPublicKey: ssh-dss AAAAM5... ++ ++ Group entry: ++ - attached to the 'posixGroup' objectclass ++ - with a 'cn' groupname attribute ++ - with multiple 'memberUid' attributes filled with usernames allowed in this group ++ Example: ++ # few members ++ dn: cn=unix,ou=groups,dc=cuckoos,dc=net ++ objectclass: top ++ objectclass: posixGroup ++ description: Unix based servers group ++ cn: unix ++ gidNumber: 1002 ++ memberUid: eau ++ memberUid: user1 ++ memberUid: user2 ++ ++ ++- HOW IT WORKS : ++ ++ * without patch ++ If a user wants to authenticate to log in a server the sshd, will first look for authentication method allowed (RSAauth,kerberos,etc..) ++ and if RSAauth and tickets based auth fails, it will fallback to standard password authentication (if enabled). ++ ++ * with the patch ++ If a user want to authenticate to log in a server, the sshd will first look for auth method including LDAP pubkey, if the ldappubkey options is enabled. ++ It will do an ldapsearch to get the public key directly from the LDAP instead of reading it from the server filesystem. ++ (usually in $HOME/.ssh/authorized_keys) ++ ++ If groups are enabled, it will also check if the user that wants to login is in the group of the server he is trying to log into. ++ If it fails, it falls back on RSA auth files ($HOME/.ssh/authorized_keys), etc.. and finally to standard password authentication (if enabled). ++ ++ 7 tokens are added to sshd_config : ++ # here is the new patched ldap related tokens ++ # entries in your LDAP must be posixAccount & strongAuthenticationUser & posixGroup ++ UseLPK yes # look the pub key into LDAP ++ LpkServers ldap://10.31.32.5/ ldap://10.31.32.4 ldap://10.31.32.3 # which LDAP server for users ? (URL format) ++ LpkUserDN ou=users,dc=foobar,dc=net # which base DN for users ? ++ LpkGroupDN ou=groups,dc=foobar,dc=net # which base DN for groups ? ++ LpkBindDN cn=manager,dc=foobar,dc=net # which bind DN ? ++ LpkBindPw asecret # bind DN credidentials ++ LpkServerGroup agroupname # the group the server is part of ++ ++ Right now i'm using anonymous binding to get public keys, because getting public keys of someone doesn't impersonate him¸ but there is some ++ flaws you have to take care of. ++ ++- HOW TO INSERT A USER/KEY INTO AN LDAP ENTRY ++ ++ * my way (there is plenty :) ++ - create ldif file (i.e. users.ldif) ++ - cat ~/.ssh/id_dsa.pub OR cat ~/.ssh/id_rsa.pub OR cat ~/.ssh/identity.pub ++ - my way in 4 steps : ++ Example: ++ ++ # you add this to the user entry in the LDIF file : ++ [...] ++ objectclass: posixAccount ++ objectclass: ldapPublicKey ++ [...] ++ sshPubliKey: ssh-dss AAAABDh12DDUR2... ++ [...] ++ ++ # insert your entry and you're done :) ++ ldapadd -D balblabla -w bleh < file.ldif ++ ++ all standard options can be present in the 'sshPublicKey' attribute. ++ ++- WHY : ++ ++ Simply because, i was looking for a way to centralize all sysadmins authentication, easily, without completely using LDAP ++ as authentication method (like pam_ldap etc..). ++ ++ After looking into Kerberos, SecurID, and other centralized secure authentications systems, the use of RSA and LDAP to get ++ public key for authentication allows us to control who has access to which server (the user needs an account and to be in 'strongAuthenticationUser' ++ objectclass within LDAP and part of the group the SSH server is in). ++ ++ Passwords update are no longer a nightmare for a server farm (key pair passphrase is stored on each user's box and private key is locally encrypted using his passphrase ++ so each user can change it as much as he wants). ++ ++ Blocking a user account can be done directly from the LDAP (if sshd is using RSAAuth + ldap only). ++ ++- RULES : ++ Entry in the LDAP server must respect 'posixAccount' and 'ldapPublicKey' which are defined in core.schema. ++ and the additionnal lpk.schema. ++ ++ This patch could allow a smooth transition between standard auth (/etc/passwd) and complete LDAP based authentication ++ (pamldap, nss_ldap, etc..). ++ ++ This can be an alternative to other (old?/expensive?) authentication methods (Kerberos/SecurID/..). ++ ++ Referring to schema at the beginning of this file if user 'eau' is only in group 'unix' ++ 'eau' would ONLY access 'server1', 'server2', 'server3' AND 'server4' BUT NOT 'server5'. ++ If you then modify the LDAP 'mail' group entry to add 'memberUid: eau' THEN user 'eau' would be able ++ to log in 'server5' (i hope you got the idea, my english is bad :). ++ ++ Each server's sshd is patched and configured to ask the public key and the group infos in the LDAP ++ server. ++ When you want to allow a new user to have access to the server parc, you just add him an account on ++ your servers, you add his public key into his entry on the LDAP server, it's done. ++ ++ Because sshds are looking public keys into the LDAP directly instead of a file ($HOME/.ssh/authorized_keys). ++ ++ When the user needs to change his passphrase he can do it directly from his workstation by changing ++ his own key set lock passphrase, and all servers are automatically aware. ++ ++ With a CAREFUL LDAP server configuration you could allow a user to add/delete/modify his own entry himself ++ so he can add/modify/delete himself his public key when needed. ++ ++ FLAWS : ++ LDAP must be well configured, getting the public key of some user is not a problem, but if anonymous LDAP ++ allow write to users dn, somebody could replace someuser's public key by its own and impersonate some ++ of your users in all your server farm be VERY CAREFUL. ++ ++ MITM attack when sshd is requesting the public key, could lead to a compromise of your servers allowing login ++ as the impersonnated user. ++ ++ If LDAP server is down then, fallback on passwd auth. ++ ++ the ldap code part has not been well audited yet. ++ ++- LDAP USER ENTRY EXAMPLES (LDIF Format, look in users.ldif) ++ --- CUT HERE --- ++ dn: uid=jdoe,ou=users,dc=foobar,dc=net ++ objectclass: top ++ objectclass: person ++ objectclass: organizationalPerson ++ objectclass: posixAccount ++ objectclass: ldapPublicKey ++ description: My account ++ cn: John Doe ++ sn: John Doe ++ uid: jdoe ++ uidNumber: 100 ++ gidNumber: 100 ++ homeDirectory: /home/jdoe ++ sshPublicKey: ssh-dss AAAAB3NzaC1kc3MAAAEBAOvL8pREUg9wSy/8+hQJ54YF3AXkB0OZrXB.... ++ [...] ++ --- CUT HERE --- ++ ++- LDAP GROUP ENTRY EXAMPLES (LDIF Format, look in groups.ldif) ++ --- CUT HERE --- ++ dn: cn=unix,ou=groups,dc=cuckoos,dc=net ++ objectclass: top ++ objectclass: posixGroup ++ description: Unix based servers group ++ cn: unix ++ gidNumber: 1002 ++ memberUid: jdoe ++ memberUid: user1 ++ memberUid: user2 ++ [...] ++ --- CUT HERE --- ++ ++>> FYI: << ++Multiple 'sshPublicKey' in a user entry are allowed, as well as multiple 'memberUid' attributes in a group entry ++ ++- COMPILING: ++ 1. Apply the patch ++ 2. ./configure --with-your-options --with-ldap=/prefix/to/ldap_libs_and_includes ++ 3. make ++ 4. it's done. ++ ++- BLA : ++ I hope this could help, and i hope to be clear enough,, or give ideas. questions/comments/improvements are welcome. ++ ++- TODO : ++ Redesign differently. ++ ++- DOCS/LINK : ++ http://pacsec.jp/core05/psj05-barisani-en.pdf ++ http://fritz.potsdam.edu/projects/openssh-lpk/ ++ http://fritz.potsdam.edu/projects/sshgate/ ++ http://dev.inversepath.com/trac/openssh-lpk ++ http://lam.sf.net/ ( http://lam.sourceforge.net/documentation/supportedSchemas.htm ) ++ ++- CONTRIBUTORS/IDEAS/GREETS : ++ - Falk Siemonsmeier. ++ - Jacob Rief. ++ - Michael Durchgraf. ++ - frederic peters. ++ - Finlay dobbie. ++ - Stefan Fisher. ++ - Robin H. Johnson. ++ - Adrian Bridgett. ++ ++- CONTACT : ++ - Eric AUGE <eau@phear.org> ++ - Andrea Barisani <andrea@inversepath.com> +--- auth-rsa.c.orig 2006-11-07 10:14:42.000000000 -0200 ++++ auth-rsa.c 2008-04-17 21:24:57.000000000 -0300 +@@ -175,10 +175,96 @@ + u_long linenum = 0; + struct stat st; + Key *key; ++#ifdef WITH_LDAP_PUBKEY ++ ldap_key_t * k; ++ unsigned int i = 0; ++#endif + + /* Temporarily use the user's uid. */ + temporarily_use_uid(pw); + ++#ifdef WITH_LDAP_PUBKEY ++ /* here is the job */ ++ key = key_new(KEY_RSA1); ++ ++ if (options.lpk.on) { ++ debug("[LDAP] trying LDAP first uid=%s", pw->pw_name); ++ if ( ldap_ismember(&options.lpk, pw->pw_name) > 0) { ++ if ( (k = ldap_getuserkey(&options.lpk, pw->pw_name)) != NULL) { ++ for (i = 0 ; i < k->num ; i++) { ++ char *cp, *options = NULL; ++ ++ for (cp = k->keys[i]->bv_val; *cp == ' ' || *cp == '\t'; cp++) ++ ; ++ if (!*cp || *cp == '\n' || *cp == '#') ++ continue; ++ ++ /* ++ * Check if there are options for this key, and if so, ++ * save their starting address and skip the option part ++ * for now. If there are no options, set the starting ++ * address to NULL. ++ */ ++ if (*cp < '0' || *cp > '9') { ++ int quoted = 0; ++ options = cp; ++ for (; *cp && (quoted || (*cp != ' ' && *cp != '\t')); cp++) { ++ if (*cp == '\\' && cp[1] == '"') ++ cp++; /* Skip both */ ++ else if (*cp == '"') ++ quoted = !quoted; ++ } ++ } else ++ options = NULL; ++ ++ /* Parse the key from the line. */ ++ if (hostfile_read_key(&cp, &bits, key) == 0) { ++ debug("[LDAP] line %d: non ssh1 key syntax", i); ++ continue; ++ } ++ /* cp now points to the comment part. */ ++ ++ /* Check if the we have found the desired key (identified by its modulus). */ ++ if (BN_cmp(key->rsa->n, client_n) != 0) ++ continue; ++ ++ /* check the real bits */ ++ if (bits != (unsigned int)BN_num_bits(key->rsa->n)) ++ logit("[LDAP] Warning: ldap, line %lu: keysize mismatch: " ++ "actual %d vs. announced %d.", (unsigned long)i, BN_num_bits(key->rsa->n), bits); ++ ++ /* We have found the desired key. */ ++ /* ++ * If our options do not allow this key to be used, ++ * do not send challenge. ++ */ ++ if (!auth_parse_options(pw, options, "[LDAP]", (unsigned long) i)) ++ continue; ++ ++ /* break out, this key is allowed */ ++ allowed = 1; ++ ++ /* add the return stuff etc... */ ++ /* Restore the privileged uid. */ ++ restore_uid(); ++ ++ /* return key if allowed */ ++ if (allowed && rkey != NULL) ++ *rkey = key; ++ else ++ key_free(key); ++ ++ ldap_keys_free(k); ++ return (allowed); ++ } ++ } else { ++ logit("[LDAP] no keys found for '%s'!", pw->pw_name); ++ } ++ } else { ++ logit("[LDAP] '%s' is not in '%s'", pw->pw_name, options.lpk.sgroup); ++ } ++ } ++#endif + /* The authorized keys. */ + file = authorized_keys_file(pw); + debug("trying public RSA key file %s", file); +--- auth2-pubkey.c.orig 2006-08-04 23:39:39.000000000 -0300 ++++ auth2-pubkey.c 2008-04-17 21:24:57.000000000 -0300 +@@ -53,6 +53,10 @@ + #include "monitor_wrap.h" + #include "misc.h" + ++#ifdef WITH_LDAP_PUBKEY ++#include "ldapauth.h" ++#endif ++ + /* import */ + extern ServerOptions options; + extern u_char *session_id2; +@@ -186,10 +190,79 @@ + struct stat st; + Key *found; + char *fp; ++#ifdef WITH_LDAP_PUBKEY ++ ldap_key_t * k; ++ unsigned int i = 0; ++#endif + + /* Temporarily use the user's uid. */ + temporarily_use_uid(pw); + ++#ifdef WITH_LDAP_PUBKEY ++ found_key = 0; ++ /* allocate a new key type */ ++ found = key_new(key->type); ++ ++ /* first check if the options is enabled, then try.. */ ++ if (options.lpk.on) { ++ debug("[LDAP] trying LDAP first uid=%s",pw->pw_name); ++ if (ldap_ismember(&options.lpk, pw->pw_name) > 0) { ++ if ((k = ldap_getuserkey(&options.lpk, pw->pw_name)) != NULL) { ++ /* Skip leading whitespace, empty and comment lines. */ ++ for (i = 0 ; i < k->num ; i++) { ++ /* dont forget if multiple keys to reset options */ ++ char *cp, *options = NULL; ++ ++ for (cp = (char *)k->keys[i]->bv_val; *cp == ' ' || *cp == '\t'; cp++) ++ ; ++ if (!*cp || *cp == '\n' || *cp == '#') ++ continue; ++ ++ if (key_read(found, &cp) != 1) { ++ /* no key? check if there are options for this key */ ++ int quoted = 0; ++ debug2("[LDAP] user_key_allowed: check options: '%s'", cp); ++ options = cp; ++ for (; *cp && (quoted || (*cp != ' ' && *cp != '\t')); cp++) { ++ if (*cp == '\\' && cp[1] == '"') ++ cp++; /* Skip both */ ++ else if (*cp == '"') ++ quoted = !quoted; ++ } ++ /* Skip remaining whitespace. */ ++ for (; *cp == ' ' || *cp == '\t'; cp++) ++ ; ++ if (key_read(found, &cp) != 1) { ++ debug2("[LDAP] user_key_allowed: advance: '%s'", cp); ++ /* still no key? advance to next line*/ ++ continue; ++ } ++ } ++ ++ if (key_equal(found, key) && ++ auth_parse_options(pw, options, file, linenum) == 1) { ++ found_key = 1; ++ debug("[LDAP] matching key found"); ++ fp = key_fingerprint(found, SSH_FP_MD5, SSH_FP_HEX); ++ verbose("[LDAP] Found matching %s key: %s", key_type(found), fp); ++ ++ /* restoring memory */ ++ ldap_keys_free(k); ++ xfree(fp); ++ restore_uid(); ++ key_free(found); ++ return found_key; ++ break; ++ } ++ }/* end of LDAP for() */ ++ } else { ++ logit("[LDAP] no keys found for '%s'!", pw->pw_name); ++ } ++ } else { ++ logit("[LDAP] '%s' is not in '%s'", pw->pw_name, options.lpk.sgroup); ++ } ++ } ++#endif + debug("trying public key file %s", file); + + /* Fail quietly if file does not exist */ +--- config.h.in.orig 2008-04-03 07:01:49.000000000 -0300 ++++ config.h.in 2008-04-17 21:24:57.000000000 -0300 +@@ -539,6 +539,9 @@ + /* Define to 1 if you have the <linux/if_tun.h> header file. */ + #undef HAVE_LINUX_IF_TUN_H + ++/* Define if you want LDAP support */ ++#undef WITH_LDAP_PUBKEY ++ + /* Define if your libraries define login() */ + #undef HAVE_LOGIN + +--- configure.ac.orig 2008-03-26 22:33:07.000000000 -0300 ++++ configure.ac 2008-04-17 21:24:57.000000000 -0300 +@@ -1285,6 +1285,37 @@ + esac ] + ) + ++# Check whether user wants LDAP support ++LDAP_MSG="no" ++AC_ARG_WITH(ldap, ++ [ --with-ldap[[=PATH]] Enable LDAP pubkey support (optionally in PATH)], ++ [ ++ if test "x$withval" != "xno" ; then ++ ++ if test "x$withval" != "xyes" ; then ++ CPPFLAGS="$CPPFLAGS -I${withval}/include" ++ LDFLAGS="$LDFLAGS -L${withval}/lib" ++ fi ++ ++ AC_DEFINE([WITH_LDAP_PUBKEY], 1, [Enable LDAP pubkey support]) ++ LIBS="-lldap $LIBS" ++ LDAP_MSG="yes" ++ ++ AC_MSG_CHECKING([for LDAP support]) ++ AC_TRY_COMPILE( ++ [#include <sys/types.h> ++ #include <ldap.h>], ++ [(void)ldap_init(0, 0);], ++ [AC_MSG_RESULT(yes)], ++ [ ++ AC_MSG_RESULT(no) ++ AC_MSG_ERROR([** Incomplete or missing ldap libraries **]) ++ ] ++ ) ++ fi ++ ] ++) ++ + dnl Checks for library functions. Please keep in alphabetical order + AC_CHECK_FUNCS( \ + arc4random \ +@@ -4089,6 +4120,7 @@ + echo " Smartcard support: $SCARD_MSG" + echo " S/KEY support: $SKEY_MSG" + echo " TCP Wrappers support: $TCPW_MSG" ++echo " LDAP support: $LDAP_MSG" + echo " MD5 password support: $MD5_MSG" + echo " libedit support: $LIBEDIT_MSG" + echo " Solaris process contract support: $SPC_MSG" +--- configure.orig 2008-04-03 07:01:50.000000000 -0300 ++++ configure 2008-04-17 21:24:57.000000000 -0300 +@@ -1339,6 +1339,7 @@ + --with-tcp-wrappers[=PATH] Enable tcpwrappers support (optionally in PATH) + --with-libedit[=PATH] Enable libedit support for sftp + --with-audit=module Enable EXPERIMENTAL audit support (modules=debug,bsm) ++ --with-ldap[=PATH] Enable LDAP pubkey support (optionally in PATH) + --with-ssl-dir=PATH Specify path to OpenSSL installation + --without-openssl-header-check Disable OpenSSL version consistency check + --with-ssl-engine Enable OpenSSL (hardware) ENGINE support +@@ -12514,6 +12515,85 @@ + fi + + ++# Check whether user wants LDAP support ++LDAP_MSG="no" ++ ++# Check whether --with-ldap was given. ++if test "${with_ldap+set}" = set; then ++ withval=$with_ldap; ++ if test "x$withval" != "xno" ; then ++ ++ if test "x$withval" != "xyes" ; then ++ CPPFLAGS="$CPPFLAGS -I${withval}/include" ++ LDFLAGS="$LDFLAGS -L${withval}/lib" ++ fi ++ ++ ++cat >>confdefs.h <<\_ACEOF ++#define WITH_LDAP_PUBKEY 1 ++_ACEOF ++ ++ LIBS="-lldap $LIBS" ++ LDAP_MSG="yes" ++ ++ { echo "$as_me:$LINENO: checking for LDAP support" >&5 ++echo $ECHO_N "checking for LDAP support... $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 <sys/types.h> ++ #include <ldap.h> ++int ++main () ++{ ++(void)ldap_init(0, 0); ++ ; ++ return 0; ++} ++_ACEOF ++rm -f conftest.$ac_objext ++if { (ac_try="$ac_compile" ++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_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); } && { ++ test -z "$ac_c_werror_flag" || ++ test ! -s conftest.err ++ } && test -s conftest.$ac_objext; then ++ { echo "$as_me:$LINENO: result: yes" >&5 ++echo "${ECHO_T}yes" >&6; } ++else ++ echo "$as_me: failed program was:" >&5 ++sed 's/^/| /' conftest.$ac_ext >&5 ++ ++ ++ { echo "$as_me:$LINENO: result: no" >&5 ++echo "${ECHO_T}no" >&6; } ++ { { echo "$as_me:$LINENO: error: ** Incomplete or missing ldap libraries **" >&5 ++echo "$as_me: error: ** Incomplete or missing ldap libraries **" >&2;} ++ { (exit 1); exit 1; }; } ++ ++ ++fi ++ ++rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ++ fi ++ ++ ++fi ++ ++ + + + +@@ -29860,6 +29940,7 @@ + echo " Smartcard support: $SCARD_MSG" + echo " S/KEY support: $SKEY_MSG" + echo " TCP Wrappers support: $TCPW_MSG" ++echo " LDAP support: $LDAP_MSG" + echo " MD5 password support: $MD5_MSG" + echo " libedit support: $LIBEDIT_MSG" + echo " Solaris process contract support: $SPC_MSG" +--- ldapauth.c.orig 2008-04-17 21:24:57.000000000 -0300 ++++ ldapauth.c 2008-04-17 21:24:57.000000000 -0300 +@@ -0,0 +1,575 @@ ++/* ++ * $Id: openssh-lpk-4.3p1-0.3.7.patch,v 1.3 2006/04/18 15:29:09 eau Exp $ ++ */ ++ ++/* ++ * ++ * Copyright (c) 2005, Eric AUGE <eau@phear.org> ++ * All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: ++ * ++ * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. ++ * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. ++ * Neither the name of the phear.org nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, ++ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ++ * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, ++ * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; ++ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ++ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++ * ++ * ++ */ ++ ++#include "includes.h" ++ ++#ifdef WITH_LDAP_PUBKEY ++ ++#include <stdio.h> ++#include <stdlib.h> ++#include <unistd.h> ++#include <string.h> ++ ++#include "ldapauth.h" ++#include "log.h" ++ ++static char *attrs[] = { ++ PUBKEYATTR, ++ NULL ++}; ++ ++/* filter building infos */ ++#define FILTER_GROUP_PREFIX "(&(objectclass=posixGroup)" ++#define FILTER_OR_PREFIX "(|" ++#define FILTER_OR_SUFFIX ")" ++#define FILTER_CN_PREFIX "(cn=" ++#define FILTER_CN_SUFFIX ")" ++#define FILTER_UID_FORMAT "(memberUid=%s)" ++#define FILTER_GROUP_SUFFIX ")" ++#define FILTER_GROUP_SIZE(group) (size_t) (strlen(group)+(ldap_count_group(group)*5)+52) ++ ++/* just filter building stuff */ ++#define REQUEST_GROUP_SIZE(filter, uid) (size_t) (strlen(filter)+strlen(uid)+1) ++#define REQUEST_GROUP(buffer, prefilter, pwname) \ ++ buffer = (char *) calloc(REQUEST_GROUP_SIZE(prefilter, pwname), sizeof(char)); \ ++ if (!buffer) { \ ++ perror("calloc()"); \ ++ return FAILURE; \ ++ } \ ++ snprintf(buffer, REQUEST_GROUP_SIZE(prefilter,pwname), prefilter, pwname) ++/* ++XXX OLD group building macros ++#define REQUEST_GROUP_SIZE(grp, uid) (size_t) (strlen(grp)+strlen(uid)+46) ++#define REQUEST_GROUP(buffer,pwname,grp) \ ++ buffer = (char *) calloc(REQUEST_GROUP_SIZE(grp, pwname), sizeof(char)); \ ++ if (!buffer) { \ ++ perror("calloc()"); \ ++ return FAILURE; \ ++ } \ ++ snprintf(buffer,REQUEST_GROUP_SIZE(grp,pwname),"(&(objectclass=posixGroup)(cn=%s)(memberUid=%s))",grp,pwname) ++ */ ++ ++/* ++XXX stock upstream version without extra filter support ++#define REQUEST_USER_SIZE(uid) (size_t) (strlen(uid)+64) ++#define REQUEST_USER(buffer, pwname) \ ++ buffer = (char *) calloc(REQUEST_USER_SIZE(pwname), sizeof(char)); \ ++ if (!buffer) { \ ++ perror("calloc()"); \ ++ return NULL; \ ++ } \ ++ snprintf(buffer,REQUEST_USER_SIZE(pwname),"(&(objectclass=posixAccount)(objectclass=ldapPublicKey)(uid=%s))",pwname) ++ */ ++ ++#define REQUEST_USER_SIZE(uid, filter) (size_t) (strlen(uid)+64+(filter != NULL ? strlen(filter) : 0)) ++#define REQUEST_USER(buffer, pwname, customfilter) \ ++ buffer = (char *) calloc(REQUEST_USER_SIZE(pwname, customfilter), sizeof(char)); \ ++ if (!buffer) { \ ++ perror("calloc()"); \ ++ return NULL; \ ++ } \ ++ snprintf(buffer, REQUEST_USER_SIZE(pwname, customfilter), \ ++ "(&(objectclass=posixAccount)(objectclass=ldapPublicKey)(uid=%s)%s)", \ ++ pwname, (customfilter != NULL ? customfilter : "")) ++ ++/* some portable and working tokenizer, lame though */ ++static int tokenize(char ** o, size_t size, char * input) { ++ unsigned int i = 0, num; ++ const char * charset = " \t"; ++ char * ptr = input; ++ ++ /* leading white spaces are ignored */ ++ num = strspn(ptr, charset); ++ ptr += num; ++ ++ while ((num = strcspn(ptr, charset))) { ++ if (i < size-1) { ++ o[i++] = ptr; ++ ptr += num; ++ if (*ptr) ++ *ptr++ = '\0'; ++ } ++ } ++ o[i] = NULL; ++ return SUCCESS; ++} ++ ++void ldap_close(ldap_opt_t * ldap) { ++ ++ if (!ldap) ++ return; ++ ++ if ( ldap_unbind_ext(ldap->ld, NULL, NULL) < 0) ++ ldap_perror(ldap->ld, "ldap_unbind()"); ++ ++ ldap->ld = NULL; ++ FLAG_SET_DISCONNECTED(ldap->flags); ++ ++ return; ++} ++ ++/* init && bind */ ++int ldap_connect(ldap_opt_t * ldap) { ++ int version = LDAP_VERSION3; ++ ++ if (!ldap->servers) ++ return FAILURE; ++ ++ /* Connection Init and setup */ ++ ldap->ld = ldap_init(ldap->servers, LDAP_PORT); ++ if (!ldap->ld) { ++ ldap_perror(ldap->ld, "ldap_init()"); ++ return FAILURE; ++ } ++ ++ if ( ldap_set_option(ldap->ld, LDAP_OPT_PROTOCOL_VERSION, &version) != LDAP_OPT_SUCCESS) { ++ ldap_perror(ldap->ld, "ldap_set_option(LDAP_OPT_PROTOCOL_VERSION)"); ++ return FAILURE; ++ } ++ ++ /* Timeouts setup */ ++ if (ldap_set_option(ldap->ld, LDAP_OPT_NETWORK_TIMEOUT, &ldap->b_timeout) != LDAP_SUCCESS) { ++ ldap_perror(ldap->ld, "ldap_set_option(LDAP_OPT_NETWORK_TIMEOUT)"); ++ } ++ if (ldap_set_option(ldap->ld, LDAP_OPT_TIMEOUT, &ldap->s_timeout) != LDAP_SUCCESS) { ++ ldap_perror(ldap->ld, "ldap_set_option(LDAP_OPT_TIMEOUT)"); ++ } ++ ++ /* TLS support */ ++ if ( (ldap->tls == -1) || (ldap->tls == 1) ) { ++ if (ldap_start_tls_s(ldap->ld, NULL, NULL ) != LDAP_SUCCESS) { ++ /* failed then reinit the initial connect */ ++ ldap_perror(ldap->ld, "ldap_connect: (TLS) ldap_start_tls()"); ++ if (ldap->tls == 1) ++ return FAILURE; ++ ++ ldap->ld = ldap_init(ldap->servers, LDAP_PORT); ++ if (!ldap->ld) { ++ ldap_perror(ldap->ld, "ldap_init()"); ++ return FAILURE; ++ } ++ ++ if ( ldap_set_option(ldap->ld, LDAP_OPT_PROTOCOL_VERSION, &version) != LDAP_OPT_SUCCESS) { ++ ldap_perror(ldap->ld, "ldap_set_option()"); ++ return FAILURE; ++ } ++ } ++ } ++ ++ ++ if ( ldap_simple_bind_s(ldap->ld, ldap->binddn, ldap->bindpw) != LDAP_SUCCESS) { ++ ldap_perror(ldap->ld, "ldap_simple_bind_s()"); ++ return FAILURE; ++ } ++ ++ /* says it is connected */ ++ FLAG_SET_CONNECTED(ldap->flags); ++ ++ return SUCCESS; ++} ++ ++/* must free allocated ressource */ ++static char * ldap_build_host(char *host, int port) { ++ unsigned int size = strlen(host)+11; ++ char * h = (char *) calloc (size, sizeof(char)); ++ int rc; ++ if (!h) ++ return NULL; ++ ++ rc = snprintf(h, size, "%s:%d ", host, port); ++ if (rc == -1) ++ return NULL; ++ return h; ++} ++ ++static int ldap_count_group(const char * input) { ++ const char * charset = " \t"; ++ const char * ptr = input; ++ unsigned int count = 0; ++ unsigned int num; ++ ++ num = strspn(ptr, charset); ++ ptr += num; ++ ++ while ((num = strcspn(ptr, charset))) { ++ count++; ++ ptr += num; ++ ptr++; ++ } ++ ++ return count; ++} ++ ++/* format filter */ ++char * ldap_parse_groups(const char * groups) { ++ unsigned int buffer_size = FILTER_GROUP_SIZE(groups); ++ char * buffer = (char *) calloc(buffer_size, sizeof(char)); ++ char * g = NULL; ++ char * garray[32]; ++ unsigned int i = 0; ++ ++ if ((!groups)||(!buffer)) ++ return NULL; ++ ++ g = strdup(groups); ++ if (!g) { ++ free(buffer); ++ return NULL; ++ } ++ ++ /* first separate into n tokens */ ++ if ( tokenize(garray, sizeof(garray)/sizeof(*garray), g) < 0) { ++ free(g); ++ free(buffer); ++ return NULL; ++ } ++ ++ /* build the final filter format */ ++ strlcat(buffer, FILTER_GROUP_PREFIX, buffer_size); ++ strlcat(buffer, FILTER_OR_PREFIX, buffer_size); ++ i = 0; ++ while (garray[i]) { ++ strlcat(buffer, FILTER_CN_PREFIX, buffer_size); ++ strlcat(buffer, garray[i], buffer_size); ++ strlcat(buffer, FILTER_CN_SUFFIX, buffer_size); ++ i++; ++ } ++ strlcat(buffer, FILTER_OR_SUFFIX, buffer_size); ++ strlcat(buffer, FILTER_UID_FORMAT, buffer_size); ++ strlcat(buffer, FILTER_GROUP_SUFFIX, buffer_size); ++ ++ free(g); ++ return buffer; ++} ++ ++/* a bit dirty but leak free */ ++char * ldap_parse_servers(const char * servers) { ++ char * s = NULL; ++ char * tmp = NULL, *urls[32]; ++ unsigned int num = 0 , i = 0 , asize = 0; ++ LDAPURLDesc *urld[32]; ++ ++ if (!servers) ++ return NULL; ++ ++ /* local copy of the arg */ ++ s = strdup(servers); ++ if (!s) ++ return NULL; ++ ++ /* first separate into URL tokens */ ++ if ( tokenize(urls, sizeof(urls)/sizeof(*urls), s) < 0) ++ return NULL; ++ ++ i = 0; ++ while (urls[i]) { ++ if (! ldap_is_ldap_url(urls[i]) || ++ (ldap_url_parse(urls[i], &urld[i]) != 0)) { ++ return NULL; ++ } ++ i++; ++ } ++ ++ /* now free(s) */ ++ free (s); ++ ++ /* how much memory do we need */ ++ num = i; ++ for (i = 0 ; i < num ; i++) ++ asize += strlen(urld[i]->lud_host)+11; ++ ++ /* alloc */ ++ s = (char *) calloc( asize+1 , sizeof(char)); ++ if (!s) { ++ for (i = 0 ; i < num ; i++) ++ ldap_free_urldesc(urld[i]); ++ return NULL; ++ } ++ ++ /* then build the final host string */ ++ for (i = 0 ; i < num ; i++) { ++ /* built host part */ ++ tmp = ldap_build_host(urld[i]->lud_host, urld[i]->lud_port); ++ strncat(s, tmp, strlen(tmp)); ++ ldap_free_urldesc(urld[i]); ++ free(tmp); ++ } ++ ++ return s; ++} ++ ++void ldap_options_print(ldap_opt_t * ldap) { ++ debug("ldap options:"); ++ debug("servers: %s", ldap->servers); ++ if (ldap->u_basedn) ++ debug("user basedn: %s", ldap->u_basedn); ++ if (ldap->g_basedn) ++ debug("group basedn: %s", ldap->g_basedn); ++ if (ldap->binddn) ++ debug("binddn: %s", ldap->binddn); ++ if (ldap->bindpw) ++ debug("bindpw: %s", ldap->bindpw); ++ if (ldap->sgroup) ++ debug("group: %s", ldap->sgroup); ++ if (ldap->filter) ++ debug("filter: %s", ldap->filter); ++} ++ ++void ldap_options_free(ldap_opt_t * l) { ++ if (!l) ++ return; ++ if (l->servers) ++ free(l->servers); ++ if (l->u_basedn) ++ free(l->u_basedn); ++ if (l->g_basedn) ++ free(l->g_basedn); ++ if (l->binddn) ++ free(l->binddn); ++ if (l->bindpw) ++ free(l->bindpw); ++ if (l->sgroup) ++ free(l->sgroup); ++ if (l->fgroup) ++ free(l->fgroup); ++ if (l->filter) ++ free(l->filter); ++ if (l->l_conf) ++ free(l->l_conf); ++ free(l); ++} ++ ++/* free keys */ ++void ldap_keys_free(ldap_key_t * k) { ++ ldap_value_free_len(k->keys); ++ free(k); ++ return; ++} ++ ++ldap_key_t * ldap_getuserkey(ldap_opt_t *l, const char * user) { ++ ldap_key_t * k = (ldap_key_t *) calloc (1, sizeof(ldap_key_t)); ++ LDAPMessage *res, *e; ++ char * filter; ++ int i; ++ ++ if ((!k) || (!l)) ++ return NULL; ++ ++ /* Am i still connected ? RETRY n times */ ++ /* XXX TODO: setup some conf value for retrying */ ++ if (!(l->flags & FLAG_CONNECTED)) ++ for (i = 0 ; i < 2 ; i++) ++ if (ldap_connect(l) == 0) ++ break; ++ ++ /* quick check for attempts to be evil */ ++ if ((strchr(user, '(') != NULL) || (strchr(user, ')') != NULL) || ++ (strchr(user, '*') != NULL) || (strchr(user, '\\') != NULL)) ++ return NULL; ++ ++ /* build filter for LDAP request */ ++ REQUEST_USER(filter, user, l->filter); ++ ++ if ( ldap_search_st( l->ld, ++ l->u_basedn, ++ LDAP_SCOPE_SUBTREE, ++ filter, ++ attrs, 0, &l->s_timeout, &res ) != LDAP_SUCCESS) { ++ ++ ldap_perror(l->ld, "ldap_search_st()"); ++ ++ free(filter); ++ free(k); ++ ++ /* XXX error on search, timeout etc.. close ask for reconnect */ ++ ldap_close(l); ++ ++ return NULL; ++ } ++ ++ /* free */ ++ free(filter); ++ ++ /* check if any results */ ++ i = ldap_count_entries(l->ld,res); ++ if (i <= 0) { ++ ldap_msgfree(res); ++ free(k); ++ return NULL; ++ } ++ ++ if (i > 1) ++ debug("[LDAP] duplicate entries, using the FIRST entry returned"); ++ ++ e = ldap_first_entry(l->ld, res); ++ k->keys = ldap_get_values_len(l->ld, e, PUBKEYATTR); ++ k->num = ldap_count_values_len(k->keys); ++ ++ ldap_msgfree(res); ++ return k; ++} ++ ++ ++/* -1 if trouble ++ 0 if user is NOT member of current server group ++ 1 if user IS MEMBER of current server group ++ */ ++int ldap_ismember(ldap_opt_t * l, const char * user) { ++ LDAPMessage *res; ++ char * filter; ++ int i; ++ ++ if ((!l->sgroup) || !(l->g_basedn)) ++ return 1; ++ ++ /* Am i still connected ? RETRY n times */ ++ /* XXX TODO: setup some conf value for retrying */ ++ if (!(l->flags & FLAG_CONNECTED)) ++ for (i = 0 ; i < 2 ; i++) ++ if (ldap_connect(l) == 0) ++ break; ++ ++ /* quick check for attempts to be evil */ ++ if ((strchr(user, '(') != NULL) || (strchr(user, ')') != NULL) || ++ (strchr(user, '*') != NULL) || (strchr(user, '\\') != NULL)) ++ return FAILURE; ++ ++ /* build filter for LDAP request */ ++ REQUEST_GROUP(filter, l->fgroup, user); ++ ++ if (ldap_search_st( l->ld, ++ l->g_basedn, ++ LDAP_SCOPE_SUBTREE, ++ filter, ++ NULL, 0, &l->s_timeout, &res) != LDAP_SUCCESS) { ++ ++ ldap_perror(l->ld, "ldap_search_st()"); ++ ++ free(filter); ++ ++ /* XXX error on search, timeout etc.. close ask for reconnect */ ++ ldap_close(l); ++ ++ return FAILURE; ++ } ++ ++ free(filter); ++ ++ /* check if any results */ ++ if (ldap_count_entries(l->ld, res) > 0) { ++ ldap_msgfree(res); ++ return 1; ++ } ++ ++ ldap_msgfree(res); ++ return 0; ++} ++ ++/* ++ * ldap.conf simple parser ++ * XXX TODO: sanity checks ++ * must either ++ * - free the previous ldap_opt_before replacing entries ++ * - free each necessary previously parsed elements ++ * ret: ++ * -1 on FAILURE, 0 on SUCCESS ++ */ ++int ldap_parse_lconf(ldap_opt_t * l) { ++ FILE * lcd; /* ldap.conf descriptor */ ++ char buf[BUFSIZ]; ++ char * s = NULL, * k = NULL, * v = NULL; ++ int li, len; ++ ++ lcd = fopen (l->l_conf, "r"); ++ if (lcd == NULL) { ++ /* debug("Cannot open %s", l->l_conf); */ ++ perror("ldap_parse_lconf()"); ++ return FAILURE; ++ } ++ ++ while (fgets (buf, sizeof (buf), lcd) != NULL) { ++ ++ if (*buf == '\n' || *buf == '#') ++ continue; ++ ++ k = buf; ++ v = k; ++ while (*v != '\0' && *v != ' ' && *v != '\t') ++ v++; ++ ++ if (*v == '\0') ++ continue; ++ ++ *(v++) = '\0'; ++ ++ while (*v == ' ' || *v == '\t') ++ v++; ++ ++ li = strlen (v) - 1; ++ while (v[li] == ' ' || v[li] == '\t' || v[li] == '\n') ++ --li; ++ v[li + 1] = '\0'; ++ ++ if (!strcasecmp (k, "uri")) { ++ if ((l->servers = ldap_parse_servers(v)) == NULL) { ++ fatal("error in ldap servers"); ++ return FAILURE; ++ } ++ ++ } ++ else if (!strcasecmp (k, "base")) { ++ s = strchr (v, '?'); ++ if (s != NULL) { ++ len = s - v; ++ l->u_basedn = malloc (len + 1); ++ strncpy (l->u_basedn, v, len); ++ l->u_basedn[len] = '\0'; ++ } else { ++ l->u_basedn = strdup (v); ++ } ++ } ++ else if (!strcasecmp (k, "binddn")) { ++ l->binddn = strdup (v); ++ } ++ else if (!strcasecmp (k, "bindpw")) { ++ l->bindpw = strdup (v); ++ } ++ else if (!strcasecmp (k, "timelimit")) { ++ l->s_timeout.tv_sec = atoi (v); ++ } ++ else if (!strcasecmp (k, "bind_timelimit")) { ++ l->b_timeout.tv_sec = atoi (v); ++ } ++ else if (!strcasecmp (k, "ssl")) { ++ if (!strcasecmp (v, "start_tls")) ++ l->tls = 1; ++ } ++ } ++ ++ fclose (lcd); ++ return SUCCESS; ++} ++ ++#endif /* WITH_LDAP_PUBKEY */ +--- ldapauth.h.orig 2008-04-17 21:24:57.000000000 -0300 ++++ ldapauth.h 2008-04-17 21:24:57.000000000 -0300 +@@ -0,0 +1,124 @@ ++/* ++ * $Id: openssh-lpk-4.3p1-0.3.7.patch,v 1.3 2006/04/18 15:29:09 eau Exp $ ++ */ ++ ++/* ++ * ++ * Copyright (c) 2005, Eric AUGE <eau@phear.org> ++ * All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: ++ * ++ * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. ++ * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. ++ * Neither the name of the phear.org nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, ++ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ++ * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, ++ * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; ++ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ++ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++ * ++ * ++ */ ++ ++#ifndef LDAPAUTH_H ++#define LDAPAUTH_H ++ ++#define LDAP_DEPRECATED 1 ++ ++#include <string.h> ++#include <time.h> ++#include <ldap.h> ++#include <lber.h> ++ ++/* tokens in use for config */ ++#define _DEFAULT_LPK_TOKEN "UseLPK" ++#define _DEFAULT_SRV_TOKEN "LpkServers" ++#define _DEFAULT_USR_TOKEN "LpkUserDN" ++#define _DEFAULT_GRP_TOKEN "LpkGroupDN" ++#define _DEFAULT_BDN_TOKEN "LpkBindDN" ++#define _DEFAULT_BPW_TOKEN "LpkBindPw" ++#define _DEFAULT_MYG_TOKEN "LpkServerGroup" ++#define _DEFAULT_FIL_TOKEN "LpkFilter" ++#define _DEFAULT_TLS_TOKEN "LpkForceTLS" ++#define _DEFAULT_BTI_TOKEN "LpkBindTimelimit" ++#define _DEFAULT_STI_TOKEN "LpkSearchTimelimit" ++#define _DEFAULT_LDP_TOKEN "LpkLdapConf" ++ ++/* default options */ ++#define _DEFAULT_LPK_ON 0 ++#define _DEFAULT_LPK_SERVERS NULL ++#define _DEFAULT_LPK_UDN NULL ++#define _DEFAULT_LPK_GDN NULL ++#define _DEFAULT_LPK_BINDDN NULL ++#define _DEFAULT_LPK_BINDPW NULL ++#define _DEFAULT_LPK_SGROUP NULL ++#define _DEFAULT_LPK_FILTER NULL ++#define _DEFAULT_LPK_TLS -1 ++#define _DEFAULT_LPK_BTIMEOUT 10 ++#define _DEFAULT_LPK_STIMEOUT 10 ++#define _DEFAULT_LPK_LDP NULL ++ ++/* flags */ ++#define FLAG_EMPTY 0x00000000 ++#define FLAG_CONNECTED 0x00000001 ++ ++/* flag macros */ ++#define FLAG_SET_EMPTY(x) x&=(FLAG_EMPTY) ++#define FLAG_SET_CONNECTED(x) x|=(FLAG_CONNECTED) ++#define FLAG_SET_DISCONNECTED(x) x&=~(FLAG_CONNECTED) ++ ++/* defines */ ++#define FAILURE -1 ++#define SUCCESS 0 ++#define PUBKEYATTR "sshPublicKey" ++ ++/* ++ * ++ * defined files path ++ * (should be relocated to pathnames.h, ++ * if one day it's included within the tree) ++ * ++ */ ++#define _PATH_LDAP_CONFIG_FILE "/etc/ldap.conf" ++ ++/* structures */ ++typedef struct ldap_options { ++ int on; /* Use it or NOT */ ++ LDAP * ld; /* LDAP file desc */ ++ char * servers; /* parsed servers for ldaplib failover handling */ ++ char * u_basedn; /* user basedn */ ++ char * g_basedn; /* group basedn */ ++ char * binddn; /* binddn */ ++ char * bindpw; /* bind password */ ++ char * sgroup; /* server group */ ++ char * fgroup; /* group filter */ ++ char * filter; /* additional filter */ ++ char * l_conf; /* use ldap.conf */ ++ int tls; /* TLS only */ ++ struct timeval b_timeout; /* bind timeout */ ++ struct timeval s_timeout; /* search timeout */ ++ unsigned int flags; /* misc flags (reconnection, future use?) */ ++} ldap_opt_t; ++ ++typedef struct ldap_keys { ++ struct berval ** keys; /* the public keys retrieved */ ++ unsigned int num; /* number of keys */ ++} ldap_key_t; ++ ++ ++/* function headers */ ++void ldap_close(ldap_opt_t *); ++int ldap_connect(ldap_opt_t *); ++char * ldap_parse_groups(const char *); ++char * ldap_parse_servers(const char *); ++void ldap_options_print(ldap_opt_t *); ++void ldap_options_free(ldap_opt_t *); ++void ldap_keys_free(ldap_key_t *); ++int ldap_parse_lconf(ldap_opt_t *); ++ldap_key_t * ldap_getuserkey(ldap_opt_t *, const char *); ++int ldap_ismember(ldap_opt_t *, const char *); ++ ++#endif +--- lpk-user-example.txt.orig 2008-04-17 21:24:57.000000000 -0300 ++++ lpk-user-example.txt 2008-04-17 21:24:57.000000000 -0300 +@@ -0,0 +1,117 @@ ++ ++Post to ML -> User Made Quick Install Doc. ++Contribution from John Lane <john@lane.uk.net> ++ ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ++ ++OpenSSH LDAP keystore Patch ++=========================== ++ ++NOTE: these notes are a transcript of a specific installation ++ they work for me, your specifics may be different! ++ from John Lane March 17th 2005 john@lane.uk.net ++ ++This is a patch to OpenSSH 4.0p1 to allow it to obtain users' public keys ++from their LDAP record as an alternative to ~/.ssh/authorized_keys. ++ ++(Assuming here that necessary build stuff is in $BUILD) ++ ++cd $BUILD/openssh-4.0p1 ++patch -Np1 -i $BUILD/openssh-lpk-4.0p1-0.3.patch ++mkdir -p /var/empty && ++./configure --prefix=/usr --sysconfdir=/etc/ssh \ ++ --libexecdir=/usr/sbin --with-md5-passwords --with-pam \ ++ --with-libs="-lldap" --with-cppflags="-DWITH_LDAP_PUBKEY" ++Now do. ++make && ++make install ++ ++Add the following config to /etc/ssh/ssh_config ++UseLPK yes ++LpkServers ldap://myhost.mydomain.com ++LpkUserDN ou=People,dc=mydomain,dc=com ++ ++We need to tell sshd about the SSL keys during boot, as root's ++environment does not exist at that time. Edit /etc/rc.d/init.d/sshd. ++Change the startup code from this: ++ echo "Starting SSH Server..." ++ loadproc /usr/sbin/sshd ++ ;; ++to this: ++ echo "Starting SSH Server..." ++ LDAPRC="/root/.ldaprc" loadproc /usr/sbin/sshd ++ ;; ++ ++Re-start the sshd daemon: ++/etc/rc.d/init.d/sshd restart ++ ++Install the additional LDAP schema ++cp $BUILD/openssh-lpk-0.2.schema /etc/openldap/schema/openssh.schema ++ ++Now add the openSSH LDAP schema to /etc/openldap/slapd.conf: ++Add the following to the end of the existing block of schema includes ++include /etc/openldap/schema/openssh.schema ++ ++Re-start the LDAP server: ++/etc/rc.d/init.d/slapd restart ++ ++To add one or more public keys to a user, eg "testuser" : ++ldapsearch -x -W -Z -LLL -b "uid=testuser,ou=People,dc=mydomain,dc=com" -D ++"uid=testuser,ou=People,dc=mydomain,dc=com" > /tmp/testuser ++ ++append the following to this /tmp/testuser file ++objectclass: ldapPublicKey ++sshPublicKey: ssh-rsa ++AAAAB3NzaC1yc2EAAAABJQAAAIB3dsrwqXqD7E4zYYrxwdDKBUQxKMioXy9pxFVai64kAPxjU9KS ++qIo7QfkjslfsjflksjfldfkjsldfjLX/5zkzRmT28I5piGzunPv17S89z8XwSsuAoR1t86t+5dlI ++7eZE/gVbn2UQkQq7+kdDTS2yXV6VnC52N/kKLG3ciBkBAw== General Purpose RSA Key ++ ++Then do a modify: ++ldapmodify -x -D "uid=testuser,ou=People,dc=mydomain,dc=com" -W -f ++/tmp/testuser -Z ++Enter LDAP Password: ++modifying entry "uid=testuser,ou=People,dc=mydomain,dc=com" ++And check the modify is ok: ++ldapsearch -x -W -Z -b "uid=testuser,ou=People,dc=mydomain,dc=com" -D ++"uid=testuser,ou=People,dc=mydomain,dc=com" ++Enter LDAP Password: ++# extended LDIF ++# ++# LDAPv3 ++# base <uid=testuser,ou=People,dc=mydomain,dc=com> with scope sub ++# filter: (objectclass=*) ++# requesting: ALL ++# ++ ++# testuser, People, mydomain.com ++dn: uid=testuser,ou=People,dc=mydomain,dc=com ++uid: testuser ++cn: testuser ++objectClass: account ++objectClass: posixAccount ++objectClass: top ++objectClass: shadowAccount ++objectClass: ldapPublicKey ++shadowLastChange: 12757 ++shadowMax: 99999 ++shadowWarning: 7 ++loginShell: /bin/bash ++uidNumber: 9999 ++gidNumber: 501 ++homeDirectory: /home/testuser ++userPassword:: e1NTSEF9UDgwV1hnM1VjUDRJK0k1YnFiL1d4ZUJObXlZZ3Z3UTU= ++sshPublicKey: ssh-rsa ++AAAAB3NzaC1yc2EAAAABJQAAAIB3dsrwqXqD7E4zYYrxwdDKBUQxKMioXy9pxFVai64kAPxjU9KSqIo7QfkjslfsjflksjfldfkjsldfjLX/5zkzRmT28I5piGzunPv17S89z ++8XwSsuAoR1t86t+5dlI7eZE/gVbn2UQkQq7+kdDTS2yXV6VnC52N/kKLG3ciBkBAw== General Purpose RSA Key ++ ++# search result ++search: 3 ++result: 0 Success ++ ++# numResponses: 2 ++# numEntries: 1 ++ ++Now start a ssh session to user "testuser" from usual ssh client (e.g. ++puTTY). Login should succeed. ++ ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +--- openssh-lpk_openldap.schema.orig 2008-04-17 21:24:57.000000000 -0300 ++++ openssh-lpk_openldap.schema 2008-04-17 21:24:57.000000000 -0300 +@@ -0,0 +1,19 @@ ++# ++# LDAP Public Key Patch schema for use with openssh-ldappubkey ++# Author: Eric AUGE <eau@phear.org> ++# ++# Based on the proposal of : Mark Ruijter ++# ++ ++ ++# octetString SYNTAX ++attributetype ( 1.3.6.1.4.1.24552.500.1.1.1.13 NAME 'sshPublicKey' ++ DESC 'MANDATORY: OpenSSH Public key' ++ EQUALITY octetStringMatch ++ SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 ) ++ ++# printableString SYNTAX yes|no ++objectclass ( 1.3.6.1.4.1.24552.500.1.1.2.0 NAME 'ldapPublicKey' SUP top AUXILIARY ++ DESC 'MANDATORY: OpenSSH LPK objectclass' ++ MUST ( sshPublicKey $ uid ) ++ ) +--- openssh-lpk_sun.schema.orig 2008-04-17 21:24:57.000000000 -0300 ++++ openssh-lpk_sun.schema 2008-04-17 21:24:57.000000000 -0300 +@@ -0,0 +1,21 @@ ++# ++# LDAP Public Key Patch schema for use with openssh-ldappubkey ++# Author: Eric AUGE <eau@phear.org> ++# ++# Schema for Sun Directory Server. ++# Based on the original schema, modified by Stefan Fischer. ++# ++ ++dn: cn=schema ++ ++# octetString SYNTAX ++attributeTypes: ( 1.3.6.1.4.1.24552.500.1.1.1.13 NAME 'sshPublicKey' ++ DESC 'MANDATORY: OpenSSH Public key' ++ EQUALITY octetStringMatch ++ SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 ) ++ ++# printableString SYNTAX yes|no ++objectClasses: ( 1.3.6.1.4.1.24552.500.1.1.2.0 NAME 'ldapPublicKey' SUP top AUXILIARY ++ DESC 'MANDATORY: OpenSSH LPK objectclass' ++ MUST ( sshPublicKey $ uid ) ++ ) +--- servconf.c.orig 2008-02-10 09:48:55.000000000 -0200 ++++ servconf.c 2008-04-17 21:27:34.000000000 -0300 +@@ -40,6 +40,10 @@ + #include "channels.h" + #include "groupaccess.h" + ++#ifdef WITH_LDAP_PUBKEY ++#include "ldapauth.h" ++#endif ++ + static void add_listen_addr(ServerOptions *, char *, u_short); + static void add_one_listen_addr(ServerOptions *, char *, u_short); + +@@ -123,6 +127,24 @@ + options->num_permitted_opens = -1; + options->adm_forced_command = NULL; + options->chroot_directory = NULL; ++#ifdef WITH_LDAP_PUBKEY ++ /* XXX dirty */ ++ options->lpk.ld = NULL; ++ options->lpk.on = -1; ++ options->lpk.servers = NULL; ++ options->lpk.u_basedn = NULL; ++ options->lpk.g_basedn = NULL; ++ options->lpk.binddn = NULL; ++ options->lpk.bindpw = NULL; ++ options->lpk.sgroup = NULL; ++ options->lpk.filter = NULL; ++ options->lpk.fgroup = NULL; ++ options->lpk.l_conf = NULL; ++ options->lpk.tls = -1; ++ options->lpk.b_timeout.tv_sec = -1; ++ options->lpk.s_timeout.tv_sec = -1; ++ options->lpk.flags = FLAG_EMPTY; ++#endif + } + + void +@@ -250,6 +272,32 @@ + options->authorized_keys_file = _PATH_SSH_USER_PERMITTED_KEYS; + if (options->permit_tun == -1) + options->permit_tun = SSH_TUNMODE_NO; ++#ifdef WITH_LDAP_PUBKEY ++ if (options->lpk.on == -1) ++ options->lpk.on = _DEFAULT_LPK_ON; ++ if (options->lpk.servers == NULL) ++ options->lpk.servers = _DEFAULT_LPK_SERVERS; ++ if (options->lpk.u_basedn == NULL) ++ options->lpk.u_basedn = _DEFAULT_LPK_UDN; ++ if (options->lpk.g_basedn == NULL) ++ options->lpk.g_basedn = _DEFAULT_LPK_GDN; ++ if (options->lpk.binddn == NULL) ++ options->lpk.binddn = _DEFAULT_LPK_BINDDN; ++ if (options->lpk.bindpw == NULL) ++ options->lpk.bindpw = _DEFAULT_LPK_BINDPW; ++ if (options->lpk.sgroup == NULL) ++ options->lpk.sgroup = _DEFAULT_LPK_SGROUP; ++ if (options->lpk.filter == NULL) ++ options->lpk.filter = _DEFAULT_LPK_FILTER; ++ if (options->lpk.tls == -1) ++ options->lpk.tls = _DEFAULT_LPK_TLS; ++ if (options->lpk.b_timeout.tv_sec == -1) ++ options->lpk.b_timeout.tv_sec = _DEFAULT_LPK_BTIMEOUT; ++ if (options->lpk.s_timeout.tv_sec == -1) ++ options->lpk.s_timeout.tv_sec = _DEFAULT_LPK_STIMEOUT; ++ if (options->lpk.l_conf == NULL) ++ options->lpk.l_conf = _DEFAULT_LPK_LDP; ++#endif + + /* Turn privilege separation on by default */ + if (use_privsep == -1) +@@ -295,6 +343,12 @@ + sMatch, sPermitOpen, sForceCommand, sChrootDirectory, + sUsePrivilegeSeparation, + sDeprecated, sUnsupported ++#ifdef WITH_LDAP_PUBKEY ++ ,sLdapPublickey, sLdapServers, sLdapUserDN ++ ,sLdapGroupDN, sBindDN, sBindPw, sMyGroup ++ ,sLdapFilter, sForceTLS, sBindTimeout ++ ,sSearchTimeout, sLdapConf ++#endif + } ServerOpCodes; + + #define SSHCFG_GLOBAL 0x01 /* allowed in main section of sshd_config */ +@@ -398,6 +452,20 @@ + { "clientalivecountmax", sClientAliveCountMax, SSHCFG_GLOBAL }, + { "authorizedkeysfile", sAuthorizedKeysFile, SSHCFG_GLOBAL }, + { "authorizedkeysfile2", sAuthorizedKeysFile2, SSHCFG_GLOBAL }, ++#ifdef WITH_LDAP_PUBKEY ++ { _DEFAULT_LPK_TOKEN, sLdapPublickey, SSHCFG_GLOBAL }, ++ { _DEFAULT_SRV_TOKEN, sLdapServers, SSHCFG_GLOBAL }, ++ { _DEFAULT_USR_TOKEN, sLdapUserDN, SSHCFG_GLOBAL }, ++ { _DEFAULT_GRP_TOKEN, sLdapGroupDN, SSHCFG_GLOBAL }, ++ { _DEFAULT_BDN_TOKEN, sBindDN, SSHCFG_GLOBAL }, ++ { _DEFAULT_BPW_TOKEN, sBindPw, SSHCFG_GLOBAL }, ++ { _DEFAULT_MYG_TOKEN, sMyGroup, SSHCFG_GLOBAL }, ++ { _DEFAULT_FIL_TOKEN, sLdapFilter, SSHCFG_GLOBAL }, ++ { _DEFAULT_TLS_TOKEN, sForceTLS, SSHCFG_GLOBAL }, ++ { _DEFAULT_BTI_TOKEN, sBindTimeout, SSHCFG_GLOBAL }, ++ { _DEFAULT_STI_TOKEN, sSearchTimeout, SSHCFG_GLOBAL }, ++ { _DEFAULT_LDP_TOKEN, sLdapConf, SSHCFG_GLOBAL }, ++#endif + { "useprivilegeseparation", sUsePrivilegeSeparation, SSHCFG_GLOBAL }, + { "acceptenv", sAcceptEnv, SSHCFG_GLOBAL }, + { "permittunnel", sPermitTunnel, SSHCFG_GLOBAL }, +@@ -1282,6 +1350,107 @@ + while (arg) + arg = strdelim(&cp); + break; ++#ifdef WITH_LDAP_PUBKEY ++ case sLdapPublickey: ++ intptr = &options->lpk.on; ++ goto parse_flag; ++ case sLdapServers: ++ /* arg = strdelim(&cp); */ ++ p = line; ++ while(*p++); ++ arg = p; ++ if (!arg || *arg == '\0') ++ fatal("%s line %d: missing ldap server",filename,linenum); ++ arg[strlen(arg)] = '\0'; ++ if ((options->lpk.servers = ldap_parse_servers(arg)) == NULL) ++ fatal("%s line %d: error in ldap servers", filename, linenum); ++ memset(arg,0,strlen(arg)); ++ break; ++ case sLdapUserDN: ++ arg = cp; ++ if (!arg || *arg == '\0') ++ fatal("%s line %d: missing ldap server",filename,linenum); ++ arg[strlen(arg)] = '\0'; ++ options->lpk.u_basedn = xstrdup(arg); ++ memset(arg,0,strlen(arg)); ++ break; ++ case sLdapGroupDN: ++ arg = cp; ++ if (!arg || *arg == '\0') ++ fatal("%s line %d: missing ldap server",filename,linenum); ++ arg[strlen(arg)] = '\0'; ++ options->lpk.g_basedn = xstrdup(arg); ++ memset(arg,0,strlen(arg)); ++ break; ++ case sBindDN: ++ arg = cp; ++ if (!arg || *arg == '\0') ++ fatal("%s line %d: missing binddn",filename,linenum); ++ arg[strlen(arg)] = '\0'; ++ options->lpk.binddn = xstrdup(arg); ++ memset(arg,0,strlen(arg)); ++ break; ++ case sBindPw: ++ arg = cp; ++ if (!arg || *arg == '\0') ++ fatal("%s line %d: missing bindpw",filename,linenum); ++ arg[strlen(arg)] = '\0'; ++ options->lpk.bindpw = xstrdup(arg); ++ memset(arg,0,strlen(arg)); ++ break; ++ case sMyGroup: ++ arg = cp; ++ if (!arg || *arg == '\0') ++ fatal("%s line %d: missing groupname",filename, linenum); ++ arg[strlen(arg)] = '\0'; ++ options->lpk.sgroup = xstrdup(arg); ++ if (options->lpk.sgroup) ++ options->lpk.fgroup = ldap_parse_groups(options->lpk.sgroup); ++ memset(arg,0,strlen(arg)); ++ break; ++ case sLdapFilter: ++ arg = cp; ++ if (!arg || *arg == '\0') ++ fatal("%s line %d: missing filter",filename, linenum); ++ arg[strlen(arg)] = '\0'; ++ options->lpk.filter = xstrdup(arg); ++ memset(arg,0,strlen(arg)); ++ break; ++ case sForceTLS: ++ intptr = &options->lpk.tls; ++ arg = strdelim(&cp); ++ if (!arg || *arg == '\0') ++ fatal("%s line %d: missing yes/no argument.", ++ filename, linenum); ++ value = 0; /* silence compiler */ ++ if (strcmp(arg, "yes") == 0) ++ value = 1; ++ else if (strcmp(arg, "no") == 0) ++ value = 0; ++ else if (strcmp(arg, "try") == 0) ++ value = -1; ++ else ++ fatal("%s line %d: Bad yes/no argument: %s", ++ filename, linenum, arg); ++ if (*intptr == -1) ++ *intptr = value; ++ break; ++ case sBindTimeout: ++ intptr = (int *) &options->lpk.b_timeout.tv_sec; ++ goto parse_int; ++ case sSearchTimeout: ++ intptr = (int *) &options->lpk.s_timeout.tv_sec; ++ goto parse_int; ++ break; ++ case sLdapConf: ++ arg = cp; ++ if (!arg || *arg == '\0') ++ fatal("%s line %d: missing LpkLdapConf", filename, linenum); ++ arg[strlen(arg)] = '\0'; ++ options->lpk.l_conf = xstrdup(arg); ++ memset(arg, 0, strlen(arg)); ++ break; ++#endif + + default: + fatal("%s line %d: Missing handler for opcode %s (%d)", +--- servconf.h.orig 2008-03-07 04:31:24.000000000 -0300 ++++ servconf.h 2008-04-17 21:24:57.000000000 -0300 +@@ -16,6 +16,10 @@ + #ifndef SERVCONF_H + #define SERVCONF_H + ++#ifdef WITH_LDAP_PUBKEY ++#include "ldapauth.h" ++#endif ++ + #define MAX_PORTS 256 /* Max # ports. */ + + #define MAX_ALLOW_USERS 256 /* Max # users on allow list. */ +@@ -142,6 +146,9 @@ + int use_pam; /* Enable auth via PAM */ + + int permit_tun; ++#ifdef WITH_LDAP_PUBKEY ++ ldap_opt_t lpk; ++#endif + + int num_permitted_opens; + +--- sshd.c.orig 2008-03-11 08:58:25.000000000 -0300 ++++ sshd.c 2008-04-17 21:24:57.000000000 -0300 +@@ -126,6 +126,10 @@ + int deny_severity; + #endif /* LIBWRAP */ + ++#ifdef WITH_LDAP_PUBKEY ++#include "ldapauth.h" ++#endif ++ + #ifndef O_NOCTTY + #define O_NOCTTY 0 + #endif +@@ -1454,6 +1458,16 @@ + exit(1); + } + ++#ifdef WITH_LDAP_PUBKEY ++ /* ldap_options_print(&options.lpk); */ ++ /* XXX initialize/check ldap connection and set *LD */ ++ if (options.lpk.on) { ++ if (options.lpk.l_conf && (ldap_parse_lconf(&options.lpk) < 0) ) ++ error("[LDAP] could not parse %s", options.lpk.l_conf); ++ if (ldap_connect(&options.lpk) < 0) ++ error("[LDAP] could not initialize ldap connection"); ++ } ++#endif + debug("sshd version %.100s", SSH_RELEASE); + + /* Store privilege separation user for later use if required. */ +--- sshd_config.5.orig 2008-03-26 21:02:02.000000000 -0300 ++++ sshd_config.5 2008-04-17 21:24:57.000000000 -0300 +@@ -964,6 +964,62 @@ + program. + The default is + .Pa /usr/X11R6/bin/xauth . ++.It Cm UseLPK ++Specifies whether LDAP public key retrieval must be used or not. It allow ++an easy centralisation of public keys within an LDAP directory. The argument must be ++.Dq yes ++or ++.Dq no . ++.It Cm LpkLdapConf ++Specifies whether LDAP Public keys should parse the specified ldap.conf file ++instead of sshd_config Tokens. The argument must be a valid path to an ldap.conf ++file like ++.Pa /etc/ldap.conf ++.It Cm LpkServers ++Specifies LDAP one or more [:space:] separated server's url the following form may be used: ++.Pp ++LpkServers ldaps://127.0.0.1 ldap://127.0.0.2 ldap://127.0.0.3 ++.It Cm LpkUserDN ++Specifies the LDAP user DN. ++.Pp ++LpkUserDN ou=users,dc=phear,dc=org ++.It Cm LpkGroupDN ++Specifies the LDAP groups DN. ++.Pp ++LpkGroupDN ou=groups,dc=phear,dc=org ++.It Cm LpkBindDN ++Specifies the LDAP bind DN to use if necessary. ++.Pp ++LpkBindDN cn=Manager,dc=phear,dc=org ++.It Cm LpkBindPw ++Specifies the LDAP bind credential. ++.Pp ++LpkBindPw secret ++.It Cm LpkServerGroup ++Specifies one or more [:space:] separated group the server is part of. ++.Pp ++LpkServerGroup unix mail prod ++.It Cm LpkFilter ++Specifies an additional LDAP filter to use for finding SSH keys ++.Pp ++LpkFilter (hostAccess=master.phear.org) ++.It Cm LpkForceTLS ++Specifies if the LDAP server connection must be tried, forced or not used. The argument must be ++.Dq yes ++or ++.Dq no ++or ++.Dq try . ++.It Cm LpkSearchTimelimit ++Sepcifies the search time limit before the search is considered over. value is ++in seconds. ++.Pp ++LpkSearchTimelimit 3 ++.It Cm LpkBindTimelimit ++Sepcifies the bind time limit before the connection is considered dead. value is ++in seconds. ++.Pp ++LpkBindTimelimit 3 + .El + .Sh TIME FORMATS + .Xr sshd 8 +--- sshd_config.orig 2008-02-10 09:40:12.000000000 -0200 ++++ sshd_config 2008-04-17 21:28:29.000000000 -0300 +@@ -107,6 +107,21 @@ + # no default banner path + #Banner none + ++# here are the new patched ldap related tokens ++# entries in your LDAP must have posixAccount & ldapPublicKey objectclass ++#UseLPK yes ++#LpkLdapConf /etc/ldap.conf ++#LpkServers ldap://10.1.7.1/ ldap://10.1.7.2/ ++#LpkUserDN ou=users,dc=phear,dc=org ++#LpkGroupDN ou=groups,dc=phear,dc=org ++#LpkBindDN cn=Manager,dc=phear,dc=org ++#LpkBindPw secret ++#LpkServerGroup mail ++#LpkFilter (hostAccess=master.phear.org) ++#LpkForceTLS no ++#LpkSearchTimelimit 3 ++#LpkBindTimelimit 3 ++ + # override default of no subsystems + Subsystem sftp /usr/libexec/sftp-server + diff --git a/security/openssh-portable/files/patch-auth2.c b/security/openssh-portable/files/patch-auth2.c index 3a9e7a274684..b21e7327cea3 100644 --- a/security/openssh-portable/files/patch-auth2.c +++ b/security/openssh-portable/files/patch-auth2.c @@ -1,14 +1,14 @@ ---- auth2.c.orig Fri Aug 4 23:39:39 2006 -+++ auth2.c Sat Sep 30 10:38:04 2006 -@@ -44,6 +45,7 @@ +--- auth2.c.orig 2008-04-07 22:16:43.000000000 -0300 ++++ auth2.c 2008-04-07 22:20:03.000000000 -0300 +@@ -41,6 +41,7 @@ + #include "key.h" + #include "hostfile.h" + #include "auth.h" ++#include "canohost.h" #include "dispatch.h" #include "pathnames.h" #include "buffer.h" -+#include "canohost.h" - - #ifdef GSSAPI - #include "ssh-gss.h" -@@ -147,6 +149,13 @@ +@@ -146,6 +147,13 @@ Authmethod *m = NULL; char *user, *service, *method, *style = NULL; int authenticated = 0; @@ -22,7 +22,7 @@ if (authctxt == NULL) fatal("input_userauth_request: no authctxt"); -@@ -190,6 +199,27 @@ +@@ -194,6 +202,27 @@ "(%s,%s) -> (%s,%s)", authctxt->user, authctxt->service, user, service); } diff --git a/security/openssh-portable/files/patch-session.c b/security/openssh-portable/files/patch-session.c index 8f6b5665c976..807d3adfd9bf 100644 --- a/security/openssh-portable/files/patch-session.c +++ b/security/openssh-portable/files/patch-session.c @@ -1,5 +1,5 @@ ---- session.c.orig Mon Oct 23 14:01:56 2006 -+++ session.c Fri Nov 10 12:21:51 2006 +--- session.c.orig 2008-03-26 21:03:05.000000000 -0300 ++++ session.c 2008-04-07 21:57:52.000000000 -0300 @@ -776,6 +776,24 @@ { FILE *f; @@ -25,7 +25,7 @@ if (options.print_motd) { #ifdef HAVE_LOGIN_CAP -@@ -1004,6 +1022,9 @@ +@@ -1005,6 +1023,9 @@ struct passwd *pw = s->pw; #ifndef HAVE_LOGIN_CAP char *path = NULL; @@ -35,7 +35,7 @@ #endif /* Initialize the environment. */ -@@ -1025,6 +1046,9 @@ +@@ -1026,6 +1047,9 @@ } #endif @@ -45,7 +45,7 @@ #ifdef GSSAPI /* Allow any GSSAPI methods that we've used to alter * the childs environment as they see fit -@@ -1044,11 +1068,22 @@ +@@ -1045,11 +1069,22 @@ child_set_env(&env, &envsize, "LOGIN", pw->pw_name); #endif child_set_env(&env, &envsize, "HOME", pw->pw_dir); @@ -72,7 +72,7 @@ #else /* HAVE_LOGIN_CAP */ # ifndef HAVE_CYGWIN /* -@@ -1069,15 +1104,9 @@ +@@ -1070,15 +1105,9 @@ # endif /* HAVE_CYGWIN */ #endif /* HAVE_LOGIN_CAP */ @@ -88,19 +88,18 @@ /* Set custom environment options from RSA authentication. */ if (!options.use_login) { -@@ -1287,6 +1316,10 @@ +@@ -1344,6 +1373,9 @@ void do_setusercontext(struct passwd *pw) { +#ifdef CHROOT -+ char *user_dir; -+ char *new_root; ++ char *user_dir, *new_root; +#endif /* CHROOT */ - #ifndef HAVE_CYGWIN - if (getuid() == 0 || geteuid() == 0) - #endif /* HAVE_CYGWIN */ -@@ -1313,8 +1346,27 @@ - do_pam_setcred(0); + char *chroot_path, *tmp; + + #ifdef WITH_SELINUX +@@ -1369,8 +1401,25 @@ + do_pam_setcred(use_privsep); } # endif /* USE_PAM */ +#ifdef CHROOT @@ -112,24 +111,22 @@ + if(strncmp(new_root, "/./", 3) == 0) { + *new_root = '\0'; + new_root += 2; -+ + if(chroot(user_dir) != 0) + fatal("Couldn't chroot to user directory %s. %s", user_dir, strerror(errno)); + pw->pw_dir = new_root; + break; + } -+ + new_root += 2; + } +#endif /* CHROOT */ if (setusercontext(lc, pw, pw->pw_uid, -- (LOGIN_SETALL & ~LOGIN_SETPATH)) < 0) { -+ (LOGIN_SETALL & ~(LOGIN_SETENV|LOGIN_SETPATH))) < 0) { +- (LOGIN_SETALL & ~(LOGIN_SETPATH|LOGIN_SETUSER))) < 0) { ++ (LOGIN_SETALL & ~(LOGIN_SETPATH|LOGIN_SETUSER|LOGIN_SETENV))) < 0) { perror("unable to set user context"); exit(1); } -@@ -1472,6 +1524,9 @@ - char *argv[10]; +@@ -1540,6 +1589,9 @@ + char *argv[ARGV_MAX]; const char *shell, *shell0, *hostname = NULL; struct passwd *pw = s->pw; +#ifdef HAVE_LOGIN_CAP @@ -138,7 +135,7 @@ /* remove hostkey from the child's memory */ destroy_sensitive_data(); -@@ -1559,6 +1614,10 @@ +@@ -1627,6 +1679,10 @@ */ environ = env; @@ -149,7 +146,7 @@ #if defined(KRB5) && defined(USE_AFS) /* * At this point, we check to see if AFS is active and if we have -@@ -1590,7 +1649,7 @@ +@@ -1658,7 +1714,7 @@ fprintf(stderr, "Could not chdir to home directory %s: %s\n", pw->pw_dir, strerror(errno)); #ifdef HAVE_LOGIN_CAP |