--- /dev/null
+diff -ru openssh-3.6.1p1/auth2-pubkey.c openssh-3.6.1p1-ldappubkey/auth2-pubkey.c
+--- openssh-3.6.1p1/auth2-pubkey.c Thu Jun 6 22:27:56 2002
++++ openssh-3.6.1p1-ldappubkey/auth2-pubkey.c Thu Apr 17 11:53:03 2003
+@@ -174,12 +174,46 @@
+ struct stat st;
+ Key *found;
+ char *fp;
++#ifdef WITH_LDAP_PUBKEY
++ lh host;
++#endif
+
+ if (pw == NULL)
+ return 0;
+
+ /* 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.. */
++ debug("trying LDAP first uid=%s",pw->pw_name);
++
++ /* lets add it */
++ host.url = options.myldap_opt.ldap_server;
++ host.binddn = options.myldap_opt.binddn;
++ host.bindpw = options.myldap_opt.bindpw;
++ host.mgroup = options.myldap_opt.mgroup;
++
++ if(options.myldap_opt.pubkey_from_ldap
++ &&(key_ldap_read(found,pw->pw_name,&host) != 1)) {
++ debug2("LDAP pubkey failed!!!");
++ debug2("URL: %s !!",options.myldap_opt.ldap_server);
++ }
++
++ if (key_equal(found,key)) {
++ found_key = 1;
++ debug("matching key found on LDAP, line %lu",linenum);
++ fp = key_fingerprint(found,SSH_FP_MD5, SSH_FP_HEX);
++ verbose("Found matching %s key: %s",key_type(found),fp);
++ xfree(fp);
++ restore_uid();
++ key_free(found);
++ return found_key;
++ }
++#endif
+
+ debug("trying public key file %s", file);
+
+@@ -189,6 +223,7 @@
+ restore_uid();
+ return 0;
+ }
++
+ /* Open the file containing the authorized keys. */
+ f = fopen(file, "r");
+ if (!f) {
+@@ -196,6 +231,7 @@
+ restore_uid();
+ return 0;
+ }
++
+ if (options.strict_modes &&
+ secure_filename(f, file, pw, line, sizeof(line)) != 0) {
+ fclose(f);
+@@ -204,8 +240,11 @@
+ return 0;
+ }
+
++ /*
+ found_key = 0;
+ found = key_new(key->type);
++ old place of found_key = 0;
++ */
+
+ while (fgets(line, sizeof(line), f)) {
+ char *cp, *options = NULL;
+diff -ru openssh-3.6.1p1/key.c openssh-3.6.1p1-ldappubkey/key.c
+--- openssh-3.6.1p1/key.c Mon Feb 24 02:01:41 2003
++++ openssh-3.6.1p1-ldappubkey/key.c Thu Apr 17 11:48:00 2003
+@@ -36,6 +36,25 @@
+
+ #include <openssl/evp.h>
+
++#ifdef WITH_LDAP_PUBKEY
++#include <ldap.h>
++#include <lber.h>
++
++#define PORT LDAP_PORT
++#define LINEMAX 1024
++/*
++ * defined in core.schema, this is a temporary objectclass which can be
++ * used since i m waiting for pkix schema and pubKey attribute (binary as well
++ * so minor changes for this patch), there will be an update about this ;)
++ * the following defs were for test purposes only
++ * i'm still keeping objectclass=strongAuthenticationuser because of the purpose
++ * this patch, and wrongly using cn for each user to store group includes
++ * refere to the README for a better understanding of this.
++ */
++#define OBJCLASS "objectclass=strongAuthenticationUser"
++#define BASE_REQ "ou=users,dc=foobar,dc=net"
++#endif
++
+ #include "xmalloc.h"
+ #include "key.h"
+ #include "rsa.h"
+@@ -372,6 +391,217 @@
+ OPENSSL_free(buf);
+ return 1;
+ }
++
++#ifdef WITH_LDAP_PUBKEY
++/* returns 1 ok, -1 error */
++int
++/* key_ldap_read(Key *ret, char *uid, char *url, char *binddn, char *bindpw) */
++key_ldap_read(Key *ret, char *uid, lh *host)
++{
++ Key *k;
++ LDAP *ld;
++ LDAPMessage *res,*e;
++ LDAPURLDesc *urlstruct;
++ char *a,*urlssl,objbuf[LINEMAX];
++ struct berval **vals;
++ BerElement *ptr;
++ int version, rc, j, i, success = -1, ssl_size = 0;
++
++ /* version to 3 */
++ version = LDAP_VERSION3;
++
++ /* url based ldap://hostport/dn[?attrs[?scope[?filter[?exts]]]] */
++ rc = ldap_is_ldap_url(host->url);
++ if (rc < 0) {
++ error("key_ldap_read: ldap_is_ldap_url() -> ldap is not an url");
++
++ success = -1;
++ return success;
++ }
++
++ rc = ldap_url_parse(host->url,&urlstruct);
++ if (rc) {
++ error("key_ldap_read: ldap_url_parse() -> ldap couldn't be parsed");
++
++ success = -1;
++ return success;
++ }
++
++ ssl_size = strlen(urlstruct->lud_scheme)+strlen(urlstruct->lud_host)+10;
++
++ urlssl = (char *) malloc( ssl_size * sizeof(char) );
++ if (!urlssl) {
++ error("key_ldap_read: malloc()");
++
++ /* free what has been allocated */
++ ldap_free_urldesc(urlstruct);
++
++ success = -1;
++ return success;
++ }
++ memset(urlssl,0,ssl_size);
++ snprintf(urlssl,ssl_size,"%s://%s:%d",urlstruct->lud_scheme,urlstruct->lud_host,urlstruct->lud_port);
++
++ /* open ldap connection */
++ ld = ldap_init(urlstruct->lud_host,urlstruct->lud_port);
++ if(!ld) {
++ error("key_ldap_read: ldap_init()");
++
++ /* free what has been allocated */
++ free(urlssl);
++ ldap_free_urldesc(urlstruct);
++
++ success = -1;
++ return success;
++ }
++
++ /* setting V3 proto otherwise TLS impossible */
++ if (ldap_set_option(ld,LDAP_OPT_PROTOCOL_VERSION,&version) != LDAP_OPT_SUCCESS) {
++ error("key_ldap_read: ldap couldn't set version for TLS/SSL");
++
++ /* free what has been allocated */
++ free(urlssl);
++ ldap_free_urldesc(urlstruct);
++
++ success = -1;
++ return success;
++ }
++ /* HERE CHOOSE SSL/TLS use the scheme and look for the magic 's' ;) */
++ if (urlstruct->lud_scheme[strlen(urlstruct->lud_scheme)-1] == 's') {
++ if (ldap_initialize(&ld, urlssl) != LDAP_SUCCESS) {
++ error("key_ldap_read: ldap_initialize()");
++
++ /* free what has been allocated */
++ free(urlssl);
++ ldap_free_urldesc(urlstruct);
++
++ success = -1;
++ return success;
++ }
++ } else {
++ if ( (ldap_start_tls_s( ld, NULL, NULL ) != LDAP_SUCCESS)) {
++ ldap_perror( ld, "key_ldap_read: (TLS) ldap_start_tls" );
++ /* recover to normal connection */
++ ld = ldap_init(urlstruct->lud_host,urlstruct->lud_port);
++ if(!ld) {
++ error("key_ldap_read: ldap_init()");
++
++ /* free what has been allocated */
++ free(urlssl);
++ ldap_free_urldesc(urlstruct);
++
++ success = -1;
++ return success;
++ }
++ /* use_ssl=1; */
++ }
++ }
++
++ /* anonymous bind pubkey can be retrieved by anybody */
++ if (ldap_simple_bind_s(ld,host->binddn,host->bindpw) != LDAP_SUCCESS) {
++ error("key_ldap_read: ldap_simple_bind_s()");
++
++ /* free what has been allocated */
++ free(urlssl);
++ ldap_free_urldesc(urlstruct);
++
++ success = -1;
++ return success;
++ }
++
++ /* start ldap search */
++ if (!uid)
++ return success;
++
++ /*
++ *
++ * The user need to have posixAccount & strongAuthenticationuser attributes
++ * to accept the challenge.
++ * posixAccount & strongAuthenticationuser + uid is member of configured group.
++ * ldap user entries MUST respect our standard description.
++ * objectclass still hardcoded, hope to change this soon .
++ *
++ */
++ if (host->mgroup)
++ snprintf(objbuf,LINEMAX,"(&(objectclass=posixAccount)(objectclass=strongAuthenticationUser)(&(cn=*%s*)(uid=%s)))",host->mgroup,uid);
++ else
++ snprintf(objbuf,LINEMAX,"(&(objectclass=posixAccount)(objectclass=strongAuthenticationUser)(uid=%s))",uid);
++
++ /* New filter group inclusive depend on the configuration */
++ /* (&(objectclass=posixAccount)(objectclass=strongAuthenticationUser)(&(cn=*groupname*)(uid=eau))) */
++
++ ldap_search_s(ld,urlstruct->lud_dn,LDAP_SCOPE_SUBTREE,objbuf,NULL,0,&res);
++ i = ldap_count_entries(ld,res);
++
++ for(e=ldap_first_entry(ld,res); e != NULL; e=ldap_next_entry(ld,e)) {
++ ldap_get_dn(ld,e);
++ for(a=ldap_first_attribute(ld,e,&ptr);a!=NULL;a=ldap_next_attribute(ld,e,ptr))
++ {
++ if(strncmp(a,"userCertificate",15) == 0) {
++ vals=ldap_get_values_len(ld,e,a);
++ for(j = 0; vals[j] != NULL; j++) {
++ /* value is here :) vals[j] */
++ k = key_from_blob((unsigned char *)vals[j]->bv_val,(int)vals[j]->bv_len);
++
++ if (!k) {
++ error("key_read: key_from_blob LDAP failed");
++
++ ldap_value_free_len(vals);
++ ldap_free_urldesc(urlstruct);
++ free(urlssl);
++
++ return (-1);
++ }
++
++ /* i dont have type ?!?!?! */
++ if (k->type != KEY_DSA) {
++ error("key_read: type mismatch: encoding error");
++
++ ldap_value_free_len(vals);
++ ldap_free_urldesc(urlstruct);
++ free(urlssl);
++ key_free(k);
++
++ return (-1);
++ }
++
++ if (ret->type == KEY_RSA) {
++ error("LDAP doesnt handle RSA keys yet");
++
++ /* freeing everything */
++ ldap_value_free_len(vals);
++ ldap_free_urldesc(urlstruct);
++ free(urlssl);
++ key_free(k);
++
++ return (-1);
++ } else {
++ if (ret->dsa != NULL)
++ DSA_free(ret->dsa);
++ ret->dsa = k->dsa;
++ k->dsa = NULL;
++ DSA_print_fp(stderr,ret->dsa,8);
++
++ /* freeing everything */
++ ldap_value_free_len(vals);
++ ldap_free_urldesc(urlstruct);
++ free(urlssl);
++ key_free(k);
++
++ success = 1;
++ return success;
++ }
++ }
++ ldap_value_free_len(vals);
++ key_free(k);
++ }
++ }
++ }
++ ldap_free_urldesc(urlstruct);
++ free(urlssl);
++ return success;
++}
++#endif
+
+ /* returns 1 ok, -1 error */
+ int
+diff -ru openssh-3.6.1p1/key.h openssh-3.6.1p1-ldappubkey/key.h
+--- openssh-3.6.1p1/key.h Mon Feb 24 02:01:41 2003
++++ openssh-3.6.1p1-ldappubkey/key.h Thu Apr 17 11:48:05 2003
+@@ -64,6 +64,18 @@
+ char *key_type(Key *);
+ int key_write(Key *, FILE *);
+ int key_read(Key *, char **);
++#ifdef WITH_LDAP_PUBKEY
++/* next step is to handle fallback on ldap servers */
++typedef struct ldaphost {
++ char *url; /* LDAP infos in URL format */
++ char *binddn; /* bind DN */
++ char *bindpw; /* obvious :> */
++ char *mgroup; /* server group name */
++ struct ldaphost *next;
++} lh;
++
++int key_ldap_read(Key *, char *, lh *);
++#endif
+ u_int key_size(Key *);
+
+ Key *key_generate(int, u_int);
+diff -ru openssh-3.6.1p1/servconf.c openssh-3.6.1p1-ldappubkey/servconf.c
+--- openssh-3.6.1p1/servconf.c Mon Feb 24 02:04:34 2003
++++ openssh-3.6.1p1-ldappubkey/servconf.c Thu Apr 17 12:04:42 2003
+@@ -123,6 +123,13 @@
+ options->client_alive_count_max = -1;
+ options->authorized_keys_file = NULL;
+ options->authorized_keys_file2 = NULL;
++#ifdef WITH_LDAP_PUBKEY
++ options->myldap_opt.pubkey_from_ldap = -1;
++ options->myldap_opt.ldap_server = NULL;
++ options->myldap_opt.binddn = NULL;
++ options->myldap_opt.bindpw = NULL;
++ options->myldap_opt.mgroup = NULL;
++#endif
+
+ /* Needs to be accessable in many places */
+ use_privsep = -1;
+@@ -255,6 +262,18 @@
+ }
+ if (options->authorized_keys_file == NULL)
+ options->authorized_keys_file = _PATH_SSH_USER_PERMITTED_KEYS;
++#ifdef WITH_LDAP_PUBKEY
++ if (options->myldap_opt.pubkey_from_ldap == -1)
++ options->myldap_opt.pubkey_from_ldap = 0;
++ if (options->myldap_opt.ldap_server == NULL)
++ options->myldap_opt.ldap_server = _DEFAULT_LDAP_PUBKEY_SERVER;
++ if (options->myldap_opt.binddn == NULL)
++ options->myldap_opt.binddn = _DEFAULT_BINDDN;
++ if (options->myldap_opt.bindpw == NULL)
++ options->myldap_opt.bindpw = _DEFAULT_BINDPW;
++ if (options->myldap_opt.mgroup == NULL)
++ options->myldap_opt.mgroup = _DEFAULT_MGROUP;
++#endif
+
+ /* Turn privilege separation on by default */
+ if (use_privsep == -1)
+@@ -303,6 +322,9 @@
+ sClientAliveCountMax, sAuthorizedKeysFile, sAuthorizedKeysFile2,
+ sUsePrivilegeSeparation,
+ sDeprecated
++#ifdef WITH_LDAP_PUBKEY
++ ,sPubkey_from_ldap, sLdap_server, sBinddn, sBindpw, sMgroup
++#endif
+ } ServerOpCodes;
+
+ /* Textual representation of the tokens. */
+@@ -379,6 +401,13 @@
+ { "clientalivecountmax", sClientAliveCountMax },
+ { "authorizedkeysfile", sAuthorizedKeysFile },
+ { "authorizedkeysfile2", sAuthorizedKeysFile2 },
++#ifdef WITH_LDAP_PUBKEY
++ { "pubkeyfromldap", sPubkey_from_ldap },
++ { "ldapserver", sLdap_server },
++ { "binddn", sBinddn },
++ { "bindpw", sBindpw },
++ { "mygroup", sMgroup },
++#endif
+ { "useprivilegeseparation", sUsePrivilegeSeparation},
+ { NULL, sBadOption }
+ };
+@@ -915,6 +944,54 @@
+ while (arg)
+ arg = strdelim(&cp);
+ break;
++#ifdef WITH_LDAP_PUBKEY
++ case sPubkey_from_ldap:
++ intptr = &options->myldap_opt.pubkey_from_ldap;
++ goto parse_flag;
++ case sLdap_server:
++ /* 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)-1] = '\0';
++ options->myldap_opt.ldap_server=xstrdup(arg);
++ memset(arg,0,strlen(arg));
++ break;
++ case sBinddn:
++ /* arg = strdelim(&cp); */
++ p = line;
++ while(*p++);
++ arg = p;
++ if (!arg || *arg == '\0')
++ fatal("%s line %d: missing binddn",filename,linenum);
++ arg[strlen(arg)-1] = '\0';
++ options->myldap_opt.binddn = xstrdup(arg);
++ memset(arg,0,strlen(arg));
++ break;
++ case sBindpw:
++ /* arg = strdelim(&cp); */
++ p = line;
++ while(*p++);
++ arg = p;
++ if (!arg || *arg == '\0')
++ fatal("%s line %d: missing bindpw",filename,linenum);
++ arg[strlen(arg)-1] = '\0';
++ options->myldap_opt.bindpw=xstrdup(arg);
++ memset(arg,0,strlen(arg));
++ break;
++ case sMgroup:
++ p = line;
++ while (*p++);
++ arg = p;
++ if (!arg || *arg == '\0')
++ fatal("%s line %d: missing groupname",filename, linenum);
++ arg[strlen(arg) - 1] = '\0';
++ options->myldap_opt.mgroup = xstrdup(arg);
++ memset(arg,0,strlen(arg));
++ break;
++#endif
+
+ default:
+ fatal("%s line %d: Missing handler for opcode %s (%d)",
+diff -ru openssh-3.6.1p1/servconf.h openssh-3.6.1p1-ldappubkey/servconf.h
+--- openssh-3.6.1p1/servconf.h Thu Aug 1 03:28:39 2002
++++ openssh-3.6.1p1-ldappubkey/servconf.h Thu Apr 17 11:57:48 2003
+@@ -32,6 +32,22 @@
+ #define PERMIT_NO_PASSWD 2
+ #define PERMIT_YES 3
+
++#ifdef WITH_LDAP_PUBKEY
++#define _DEFAULT_LDAP_PUBKEY_SERVER "localhost"
++#define _DEFAULT_BASEDN "ou=People,dc=company,dc=net"
++#define _DEFAULT_BINDDN NULL
++#define _DEFAULT_BINDPW NULL
++#define _DEFAULT_MGROUP NULL
++
++typedef struct {
++ int pubkey_from_ldap;
++ char *ldap_server; /* ldap URL format where pubkeys are */
++ char *binddn; /* ldap base dn where users resides */
++ char *bindpw; /* ldap bind passwd */
++ char *mgroup; /* ldap server group name, NULL if deactivated */
++} ldap_opt;
++#endif
++
+
+ typedef struct {
+ u_int num_ports;
+@@ -132,6 +148,9 @@
+ char *authorized_keys_file; /* File containing public keys */
+ char *authorized_keys_file2;
+ int pam_authentication_via_kbd_int;
++#ifdef WITH_LDAP_PUBKEY
++ ldap_opt myldap_opt;
++#endif
+ } ServerOptions;
+
+ void initialize_server_options(ServerOptions *);
+diff -ru openssh-3.6.1p1/sshd_config openssh-3.6.1p1-ldappubkey/sshd_config
+--- openssh-3.6.1p1/sshd_config Fri Sep 27 05:21:58 2002
++++ openssh-3.6.1p1-ldappubkey/sshd_config Thu Apr 17 12:21:43 2003
+@@ -89,5 +89,13 @@
+ #Banner /some/path
+ #VerifyReverseMapping no
+
++# here is the new patched ldap related tokens
++# entries in your LDAP must be posixAccount & strongAuthenticationUser
++pubkeyfromldap yes
++ldapserver ldap://localhost/ou=users,dc=cuckoos,dc=net
++binddn cn=Manager,dc=cuckoos,dc=net
++bindpw secret
++mygroup unixmail
++
+ # override default of no subsystems
+ Subsystem sftp /usr/libexec/sftp-server