Hmmm... what you sent me appears to just hang when I click the "Add new certs" button 
on the RAServer init web page.

In the ldap-utils.lib I have (attched to this email), you will notice it does indeed 
appear to use the DER format when adding certs. I have made a couple ofmodifications 
yu can find by searching for "dwb7". 

So, the question is, why can Eudora under Windows with WorldTalk Client plugin read 
the cert, but Netscape Navigator cannot? In previous emails,  have included what the 
audit log entry when adding the cert to LDAP looks like . . and it looks like it is 
doing what it is supposed to.

Thanks for any and all help!

On Thu, Aug 09, 2001 at 02:42:35PM +0200, Michael Bell wrote:
> Dave Botsch wrote:
> > Netscape Communicator, however, insists there are no such certificates. 
> >Is it expecting something different in terms of the certificate format 
> >or in terms of the DN of the certificate? This is when I go to Security, 
> >People, Search Directory.
> > 
> > I am a bit suspicious as when viewing my ldap entry in Netscape, the 
> >usercertificate field shows the binary garbage in ascii representation.
> 
> That's definitly wrong! I attach an actual version of the ldap-utils.lib
> which much be present in cgi-raserver/lib/ldap-utils.lib. The certs must
> be stored as DER. The browser interprets the attribute userCertificate
> and shows some data of the certificate.
> 
> Cheers,
> 
> Michael
> -- 
> ----------------------------------------------------------------------------
> Michael Bell                             Email: [EMAIL PROTECTED]
> Rechenzentrum - Datacenter        Email (work):
> [EMAIL PROTECTED]
> Humboldt-University of Berlin       Tel.(work): +49 (0)30-2093 2482
> Unter den Linden 6                  Fax.(work): +49 (0)30-2093 2959
> 10099 Berlin
> Germany                                              [OpenCA Core
> Developer]
> 
> http://openca.sourceforge.net
> #!/usr/bin/perl
> 
> ## RA Server Management Utility 
> ## (c) 1999 by Massimiliano Pala
> ## All Rights Reserved
> ##
> ## Project Information:
> ##
> ##    Current Version ..................... $VER
> ##      Project Started on .................. 17/12/1998
> ##      Last Modified on .................... 30/03/2001
> ##      Project Closed on ................... n/a
> ##
> ## Program currently tested with OpenLDAP v.1.2 on Linux, Solaris
> ## and Sleepycat DB.
> ##
> ## DISC CLAIMER: THIS SOFTWARE IS GIVEN AS IS WITHOUT ANY WARRANTIES
> ## ABOUT ANY DAMAGE DERIVED BY THE USE ( CORRECT OR NOT ) OF THIS
> ## SOFTWARE. THE AUTHOR IS THEREFORE NOT RESPONSABLE IN ANY WAY OF
> ## DAMAGES RELATED IN ANY WAY TO THIS OR SUPPORTED SOFTWARE AS WELL.
> ##
> ## If you want to contact me (the author) please use the e-mail
> ## addresses listed below. Do not esitate in reporting bugs, enhancement
> ## or anything seems useful in developing this software:
> ##
> ##    [EMAIL PROTECTED]
> ##    [EMAIL PROTECTED]
> ##    [EMAIL PROTECTED]
> ##
> 
> ## Thank you for using this software, and remember that Open Projects
> ## are the future of mankind. Do not sleep, partecipate to world wide
> ## efforts to make life easier for all!
> 
> sub addCertsUsers {
>   my @keys = @_;
> 
>   ## Reserved Variables
>   my ( @certsList );
>   my ( $filename, $tmp, $ID, $cert, $ldap, $ret );
> 
>   ## Get Required parameter
>   my $serverDir = getRequired( 'ServerDir' );
> 
>   ## Debugging info
>   my $DEBUG = 0;
> 
>   ## This file has the latest imported certificate's serials
>   $filename = "$serverDir/stuff/lastImport.txt";
> 
>   ## Let's open the stuff/lastImport.txt
>   if( not -e "$filename" ) {
>     configError( "File $filename not found!");
>   }
> 
>   $tmp = $query->getFile( "$filename");
> 
>   if( $tmp eq "" ) {
>     success( "Last Import file was empty.");
>   }
> 
>   my @certsList = split( "\n", $tmp );
> 
>   my $table = $query->buildRefs ( ELEMENTS =>, MAXITEMS =>);
>   my $table .= $query->startTable (COLS=>[ "Cert.-No.",
>                                           "DN",
>                                           "adding dn",
>                                           "adding certificate" ],
>                               WIDTH=>"100%",
>                               TITLE_BGCOLOR=>"#DDCCFF");
> 
>   foreach $ID (@certsList) {
> 
>     my @line = ();
> 
>     my ( $filter, $serID, $parsed, $ret, $entry );
>     ( $serID ) = ( $ID =~ /([a-f0-9]+)/i );
> 
>     ## Let's be sure it is in the right format
>     $serID = uc( $serID );
>     $serID = "0$serID" if( length($serID) % 2 );
> 
>     my $cert = $db->getItem ( DATATYPE => VALID_CERTIFICATE,
>                               KEY => $serID );
> 
>     if( not $cert ) {
>       $table .= $query->addTableLine( DATA => [
>                     "<FONT COLOR=\"Red\">".
>                     "ERROR [$serID] : can't get certificate" .
>                     " from dB!\n</FONT>" ] );
>       next;
>     }
> 
>     $parsed = $cert->getParsed();
> 
>     push ( @line, $serID, $parsed->{DN});
>     $ret = addLDAPobject ( CERTIFICATE=>$cert );
> 
>     my $text;
>     $text .= "<FONT COLOR=\"Red\">" if ( not $ret->{STATUS} );
>     $text .= $ret->{DESC};
>     $text .= "</FONT>" if ( not $ret->{STATUS} );
>     push ( @line, $text);
> 
>     if( $ret->{STATUS} ) {
>       $ret = addLDAPattribute ( CERTIFICATE => $cert , NOPRINT => true);
> 
>       if ($ret->{STATUS}) {
>         push (@line, "success");
>       } else {
>         push (@line, "Error : ".$ret->{CODE});
>       }
>     } else {
>       push (@line, "operation not performed");
>     }
> 
>     $table .= $query->addTableLine ( DATA => [ @line ]);
> 
>   }
> 
>   $table .= $query->endTable;
>   print $table;
> 
>   return "Ok.";
> }
> 
> sub addLDAPobject {
> 
>   ######################################################
>   ## only certs makes sense because a CRL can only be ##
>   ## produced if a valid CA-cert exists               ##
>   ######################################################
> 
>   my $keys = { @_ };
>   local ( $obj, $parsed, $serID, $ldap, $ret, $dn, $cn, $sn, $email );
> 
>   my $DEBUG = 0;
> 
>   ## check the type of the attribute
>   $obj   = $keys->{CERTIFICATE};
>   return if ( not $obj );
> 
>   ## get the needed data
>   my $cert_dn    = $obj->getParsed ()->{DN};
>   my $cert_cn    = $obj->getParsed ()->{CN};
>   my $cert_serID = $obj->getParsed ()->{SERIAL};
>   my $cert_email = $obj->getParsed ()->{EMAIL};
>   my $cert_ou    = $obj->getParsed ()->{OU};
>   my $cert_o     = $obj->getParsed ()->{O};
>   my $cert_l     = $obj->getParsed ()->{L};
>   my $cert_st    = $obj->getParsed ()->{ST};
> 
>   ## debugging
>   print "Information of the Object:<br>\n" if ($DEBUG);
>   print "dn    ".$cert_dn."<br>\n" if ($DEBUG);
>   print "cn    ".$cert_cn."<br>\n" if ($DEBUG);
>   print "serID ".$cert_serID."<br>\n" if ($DEBUG);
>   print "email ".$cert_email."<br>\n" if ($DEBUG);
>   print "ou    ".$cert_ou."<br>\n" if ($DEBUG);
>   print "o     ".$cert_o."<br>\n" if ($DEBUG);
>   print "l     ".$cert_l."<br>\n" if ($DEBUG);
>   print "st    ".$cert_st."<br>\n" if ($DEBUG);
>   print "End of the information of the Object.<br>\n" if ($DEBUG);
> 
>   ## here we could perform some operations with the data
>   ## sn is not the real sn sometimes but you can find
>   ## the person via a search with a wildcard
>   my $cert_sn = $cert_cn;
>   $cert_sn =~ s/^[^ ]* //;
>   my $ou_counter = 0;
>   my @ou_array   = ();
> 
>   ## Get the Connection to the Server
>   if ( not ( $ldap = LDAP_connect() )) {
>     print "<FONT COLOR=\"Red\">";
>     print "LDAP [$serID]: Connection Refused by server!\n";
>     print "</FONT><BR>\n";
> 
>     return;
>   };
> 
>   ## Let's bind for a predetermined User
>   $ret = LDAP_bind( LDAP => $ldap );
>   if( not $ret->{STATUS} ) {
>     print "Failed in Bind: " . $ret->{CODE} . "\n";
>     LDAP_disconnect( LDAP => $ldap );
>     return $ret->{CODE};
>   };
> 
>   ## build the array from the LDAP root
>   my $basedn = getRequired ('basedn');
>   my @basedn_array = ();
>   my $h_attribute;
>   while ($basedn) {
>     ## get the last element
>     $h_attribute = $basedn;
>     $basedn =~ s/^[^,]*,//;
>     $h_attribute = substr ($h_attribute, 
>                            0, 
>                            length ($h_attribute) - length ($basedn));
>     if ( not $h_attribute ) {
>       $h_attribute = $basedn;
>       $basedn = "";
>     }
>     $h_attribute =~ s/,//;
>     $h_attribute =~ s/(^ )|( $)//g;
>     print "element of baseDN: ".$h_attribute."<br>\n" if ($DEBUG);
>     if ($h_attribute =~ /^\s*ou\s*=.*$/i) {
>       $ou_array [$ou_counter] = $h_attribute;
>       $ou_array [$ou_counter] =~ s/^\s*ou\s*=\s*//i;
>       $ou_counter++;
>     }
>     push (@basedn_array, $h_attribute);
>   }
> 
>   ## build the array from the DN
>   my $h_dn = $cert_dn;
>   my @dn_array = ();
>   my $h_attribute;
>   while ($h_dn) {
>     ## get the last element
>     $h_attribute = $h_dn;
>     $h_dn =~ s/^[^\/,]*\///;
>     $h_attribute = substr ($h_attribute, 
>                            0, 
>                            length ($h_attribute) - length ($h_dn));
>     if ( not $h_attribute ) {
>       $h_attribute = $h_dn;
>       $h_dn = "";
>     }
>     $h_attribute =~ s/\///;
>     $h_attribute =~ s/(^ )|( $)//g;
>     print "element of the inserted DN: ".$h_attribute."<br>\n" if ($DEBUG);
>     push (@dn_array, $h_attribute);
>   }
> 
>   ## verify that the root in the DN is ok
>   print "Checking RootDN of Certificate ...<br>\n" if ($DEBUG);
>   print "Inserted DN\t\t\tBaseDN<br>\n" if ($DEBUG);
>   while (scalar (@basedn_array) and scalar (@dn_array)) {
>     my $h_basedn = pop (@basedn_array);
>     my $h_dn     = pop (@dn_array);
>     print $h_dn."\t\t".$h_basedn."<br>\n" if ($DEBUG);
>     ## this dn cannot be added under the root-dn
>     if ( (uc $h_basedn) ne (uc $h_dn) ) {
>       LDAP_disconnect ( $ldap );
>       return { STATUS => 0 , 
>                DESC => "Error ( dn conflicts with basedn )",
>                CODE => -1 };
>     }
>   }
>   ## dn which should be inserted is shorter then the root-dn
>   print "Checking the length of the DN of the Certificate ...<br>\n" if ($DEBUG);
>   if ( scalar (@basedn_array) ) {
>     LDAP_disconnect ( $ldap );
>     return { STATUS => 0 , 
>              DESC => "Error ( dn is shorter then basedn )",
>              CODE => -2 };
>   }
>   ## if dn == basedn then their is no error because this can 
>   ## be the CA-dn
>   return { STATUS => 1, CODE => 0, DESC => "Success" }
>     if (!scalar (@dn_array));
> 
>   ## setup the tree for the DN
>   ## attention only the last ldapadd must be successful !!!
>   print "Building the missing nodes of the LDAP-tree ...<br>\n" if ($DEBUG);
>   my $add_dn = getRequired ('basedn');
>   my $actual_element;
>   my $use_ldap_add = 0;
>   while (scalar (@dn_array)) {
>     $actual_element = pop @dn_array;
>     if ($actual_element =~ /^\s*ou\s*=.*$/i) {
>       $ou_array [$ou_counter] = $actual_element;
>       $ou_array [$ou_counter] =~ s/^\s*ou\s*=\s*//i;
>       $ou_counter++;
>     }
> 
>     ## prepare the needed strings
>     $add_dn = $actual_element.",".$add_dn;
>     print "Try to add $add_dn ...<br>\n" if ($DEBUG);
> 
>     ## check that the entry not exist in the LDAP-tree
>     my $base          = $add_dn;
>     #$base             =~ s/^[^,]*,//;
>     my $search_filter = $add_dn;
>     $search_filter    =~ s/,.*$//g;
>     $search_filter    =~ s/^email=/mail=/i;
>     $search_filter    = "(".$search_filter.")";
>     print "LDAP Searchfilter: ".$search_filter."<br>\n" if ($DEBUG);
>     print "LDAP Base: ".$base."<br>\n" if ($DEBUG);
>     my $ldap_search_mesg = $ldap->search (
>                              base => $base,
>                              scope => "sub",
>                              filter => $search_filter);
>     print "LDAP Search Mesg-Code ".$ldap_search_mesg->code."<br>\n" if ($DEBUG);
>     print "LDAP Search Mesg-Count ".$ldap_search_mesg->count."<br>\n" if ($DEBUG);
>     ## I stop the insertion because of a searcherror too
>     if ( not $ldap_search_mesg or 
>          #$ldap_search_mesg->code or
>          $ldap_search_mesg->count) {
>       ## node/leaf exists
>       print "node exists<br>\n" if ($DEBUG);
>       next;
>     }
>     $use_ldap_add = 1;
> 
>     ## insert the different types
>     ## attention: I don't insert here a CA!!!
>     ## this most be done otherwise because I cannot declare
>     ## any o and ou to be a (sub)CA
>     my @attr;
>     if ($add_dn =~ /^\s*(cn|email|serialNumber)\s*=.*$/i) {
>       return undef if (not $cert_sn or not $cert_cn);
>       push @attr, 'cn' => $cert_cn;
>       push @attr, 'sn' => $cert_sn;
>       push @attr, 'objectclass' => [ 'top',
>                                      'person',
>                                      'organizationalPerson',
>                                      'inetOrgPerson' 
>                                    ];
>       push @attr, 'ou'   => [ @ou_array ] if (scalar @ou_array);
>       push @attr, 'o'    => $cert_o       if ($cert_o);
>       push @attr, 'mail' => $cert_email   if ($cert_email);
>       push @attr, 'st'   => $cert_st      if ($cert_st and $add_dn =~ /\s*st\s*=/i);
>       push @attr, 'l'    => $cert_l       if ($cert_l  and $add_dn =~ /\s*l\s*=/i);
>     } elsif ($add_dn =~ /^\s*ou\s*=.*$/i) {
>       return undef if (not scalar @ou_array);
>       push @attr, 'ou' => [ @ou_array ];
>       push @attr, 'authorityRevocationList;binary' => '';
>       push @attr, 'certificateRevocationList;binary' => '';
>       push @attr, 'cACertificate;binary' => '';
>       push @attr, 'objectclass' => [ 'top',
>                                      'organizationalUnit',
>                                      'certificationAuthority'
>                                    ];
>       push @attr, 'st' => $cert_st if ($cert_st and $add_dn =~ /\s*st\s*=/i);
>       push @attr, 'l'  => $cert_l  if ($cert_l  and $add_dn =~ /\s*l\s*=/i);
>     } elsif ($add_dn =~ /^\s*o\s*=.*$/i) {
>       return undef if (not $cert_o);
>       push @attr, 'o' => $cert_o;
>       push @attr, 'authorityRevocationList;binary' => '';
>       push @attr, 'certificateRevocationList;binary' => '';
>       push @attr, 'cACertificate;binary' => '';
>       push @attr, 'objectclass' => [ 'top',
>                                      'organization',
>                                      'certificationAuthority'
>                                    ];
>       push @attr, 'st' => $cert_st if ($cert_st and $add_dn =~ /\s*st\s*=/i);
>       push @attr, 'l'  => $cert_l  if ($cert_l  and $add_dn =~ /\s*l\s*=/i);
>     } elsif ($add_dn =~ /^\s*c\s*=.*$/i) {
>       return undef if (not $cert_c);
>       push @attr, 'c' => $cert_c;
>       push @attr, 'objectclass' => [ 'top',
>                                      'country'
>                                    ];
>     } elsif ($type =~ /^st$/i) {
>       return undef if (not $cert_st);
>       push @attr, 'st' => $cert_st;
>       push @attr, 'objectclass' => [ 'top',
>                                      'locality'
>                                    ];
>     } elsif ($type =~ /^l$/i) {
>       return undef if (not $cert_l);
>       push @attr, 'st' => $cert_l;
>       push @attr, 'objectclass' => [ 'top',
>                                      'locality'
>                                    ];
>     } else {
>       return undef;
>     }
> 
>     print "Attributes for the insertion:<br>\n" if ($DEBUG);
>     foreach $h (keys %{$attr}) {
>       print "$h = $attr->{$h}<br>\n" if ($DEBUG);
>     }
> 
>     $ldapadd_result = $ldap->add ( $add_dn , attr => [ @attr ] );
>     print "The resultcode of the nodeinsertion was ".
>           $ldapadd_result->code.".<br>\n" if ($DEBUG);
>     last if ($ldapadd_result->code);
>   }
> 
>   if ($use_ldap_add) {
>     if( $ldapadd_result->code ) {
>       ## print "<FONT COLOR=\"Red\">";
>       ## print "Error Adding DN [$serID]: " . $ldapadd_result->code ."<BR>\n";
>       ## print "</FONT>";
>       LDAP_disconnect ( $ldap );
>       return { STATUS => 0 , 
>                DESC => "Error ( code " . 
>                        $ldapadd_result->code . " )",
>                CODE => $ldapadd_result->code };
>     }
>   }
> 
>   LDAP_disconnect ( $ldap );
>   return { STATUS => 1, CODE => 0, DESC => "Success" };
> }
> 
> ## this function add certificates and CRLs to the directory
> sub addLDAPattribute {
>   my $keys = { @_ };
>   my $obj;
>   local $ret;
>   my $ldap;
>   my $noprint;
>   my $dn;
>   my $attr;
> 
>   my $DEBUG = 0;
> 
>   ## check the type of the attribute
>   if ( $keys->{CERTIFICATE} ) {
>     $obj = $keys->{CERTIFICATE};
>     $attr = "userCertificate";
>   } elsif ( $keys->{AUTHORITY_CERTIFICATE} ) {
>     $obj = $keys->{AUTHORITY_CERTIFICATE};
>     $attr = "cACertificate";
>   } elsif ( $keys->{CRL} ) {
>     $obj = $keys->{CRL};
>     $attr = "certificateRevocationList";
>   } elsif ( $keys->{AUTHORITY_CRL} ) {
>     $obj = $keys->{AUTHORITY_CRL};
>     $attr = "authorityRevocationList";
>   }
>   $attr .= ";binary";
>   return if ( not $obj );
> 
>   ## set output mode
>   $noprint = $keys->{NOPRINT};
>   $noprint = 0 if ($DEBUG);
> 
>   ## Initializing Connection to LDAP Server
>   if ( not ( $ldap = LDAP_connect() )) {
>     return;
>   }
> 
>   ## Let's bind for a predetermined User
>   $ret = LDAP_bind( LDAP => $ldap );
>   if ( not $ret->{STATUS} ) {
>     LDAP_disconnect ( LDAP => $ldap );
>     return;
>   }
> 
>   ## get dn
>   if ( $attr =~ /CERTIFICATE/i ) {
>     $dn = $obj->getParsed()->{DN};
>   } elsif ( $type =~ /revocationList/i ) {
>     $dn = $obj->getParsed()->{ISSUER};
>   }
>   $dn =~ s/\//,/g;
>   $dn =~ s/^ *,* *//g;
>   ## fix problems with big letters
>   $dn =~ s/email=/email=/i;
>   $dn =~ s/cn=/cn=/i;
>   $dn =~ s/c=/c=/i;
>   $dn =~ s/ou=/ou=/i;
>   $dn =~ s/o=/o=/i;
>   $dn =~ s/st=/st=/i;
>   $dn =~ s/l=/l=/i;
> 
>   ## $serID = $cert->getParsed()->{SERIAL};
>   print "addLDAPattribute: DN= ".$dn."<br>\n" if ($DEBUG);
>   print "attr: ".$attr."<br>\n" if ($DEBUG);
> 
>   ## search the attribute
>   my $search_filter = $dn;
>   $search_filter =~ s/,.*$//g;
>   $search_filter =~ s/^email=/mail=/i;
>   $search_filter = "(".$search_filter.")";
>   print "LDAP Searchfilter: ".$search_filter."<br>\n" if ($DEBUG);
>   my $mesg = $ldap->search (
>                base => $dn,
>                scope => "base",
>                filter => $search_filter);
>   print "LDAP Search Mesg-Code ".$mesg->code."<br>\n" if ($DEBUG);
>   print "LDAP Search Mesg-Count ".$mesg->count."<br>\n" if ($DEBUG);
> 
>   ## I stop the insertion because of a searcherror too
>   if ( not $mesg or 
>        $mesg->code or
>        not $mesg->count) {
>     ## search failed
>     if (!$noprint)  {
>       print "Search for the attribute failed.\n";
>     }
>     if ($mesg) {
>       $code = $mesg->code;
>     } else {
>       $code = 1;
>     }
>     LDAP_disconnect( LDAP => $ldap );
>     return { STATUS => 0 , CODE => $code };
>   }
> 
>   ## we can get only one entry because scope is set to "base"a
> 
>   ## load values
>   my @values = $mesg->entry (0)->get_value ( $attr);
>   push @values, $obj->getDER();
> 
>   ## remove doubles
>   @values = sort @values;
>   for (my $i=1; $i < scalar @values; $i++) {
>     if ($values[$i] eq $values[$i-1]) {
>       splice @values, $i;
>       $i--;
>     }
>   }
> 
>   ## insert into ldap
> 
>   $mesg = $ldap->modify ($dn, replace => {$attr => [ @values ]});
> 
>   if( $mesg->code ) { 
>  
>     $txt = "Unknown Error ( " . $mesg->code . " )";
> 
>     if (!$noprint)  {
>       print "$txt\n";
>     }
>     LDAP_disconnect( LDAP => $ldap );
>     return { STATUS => 0 , CODE => $mesg->code };
>   } else {
>     $txt = "Attribute successfully inserted."
>   }
> 
>   LDAP_disconnect( LDAP => $ldap );
>   if (!$noprint) {
>   # print "LDAP Result [$serID]: Success ( " . $mesg->code ." )<BR>\n";
>     print "Success (".$txt.")\n";
>   }
>   return { STATUS => 1, 
>            DESC => "Success (".$txt.")",
>            CODE => 0 };
> }
> 
> sub LDAPsearch {
> 
>       my $keys = { @_ };
>       my ( $mseg, $ldap, $limit, $ldapBase, $serID, $filter, $ret );
>       
>       $filter = $keys->{FILTER};
>       $serID  = $keys->{SERIAL};
> 
>       return if ( not $filter );
> 
>       ## Get required configuration keys
>       $ldapBase = getRequired( 'basedn' );
> 
>       ## Initializing Connection to LDAP Server
>         if ( not ( $ldap = LDAP_connect() )) {
>               print "<FONT COLOR=\"Red\">";
>                 print "LDAP [$serID]: Connection Refused by server!\n";
>               print "</FONT><BR>\n";
> 
>                 return;
>         };
> 
>         ## Let's bind for a predetermined User
>       $ret = LDAP_bind( LDAP => $ldap );
>       if( not $ret->{STATUS} ) {
>                 print "Failed in Bind: " . $ret->{CODE} . "\n";
>                 LDAP_disconnect( LDAP => $ldap );
>                 return $ret->{CODE};
>         };
> 
>       $mesg = $ldap->search ( base => "$ldapBase",
>                               filter => "$filter" );
> 
>       if ( $mesg->code ) {
>               LDAP_disconnect( LDAP => $ldap );
>               return;
>       }
> 
>       return { COUNT => $mesg->count, ENTRIES => $mesg->entries };
> };
> 
> 
> sub LDAP_connect {
> 
>       my $keys = { @_ };
>       my ( $ldap, $ldapSrv, $port, $ldapUsr, $ldapBase, $ldaplim,
>            $ldapPwd, $filter, @attrs, $ret );
> 
>       ## Initializing Connection to LDAP Server
>         $ldapSrv  = getRequired( 'ldapserver' ); 
> 
>         $port     = getRequired('ldapport');
>         $ldaplim  = getRequired('ldaplimit');
> 
>         ## if no initialization found, get defaults
>         $port   = 389 unless $LDAP_Port;
> 
>       ## Get the Connection to the Server
>         $ldap = Net::LDAP->new ("$ldapSrv", 
>                                port => "$port",
>                                async => 0 );
> 
>       return if( not $ldap );
> 
>       return $ldap;
> 
> }
> 
> sub LDAP_disconnect {
> 
>       $keys => {@_};
> 
>       my $ldap = $keys->{LDAP};
> 
>       return {STATUS => 0 } if ( not $ldap );
>       $ldap->unbind;
> 
>       return {STATUS => 1};
> }
> 
> sub LDAP_bind {
> 
>       my $keys = {@_};
> 
>       ## Get Required Parameters
>         my $ldapUsr  = getRequired('ldaproot');
>         my $ldapPwd  = getRequired('ldappwd');
> 
>       ## Get ldap passed ref
>       my $ldap = $keys->{LDAP};
> 
>       ## Return if no object passed
>       return if( not $ldap );
> 
>       ## Try to bind to selected user
>         my $mesg = $ldap->bind( "$ldapUsr",
>                               'password' => "$ldapPwd" );
> 
>       ## if got an error, return it
>       if ( $mesg->code ) {
>                 LDAP_disconnect( LDAP => $ldap );
>                 return { STATUS => 0, CODE => $mesg->code };
>         };
> 
>       return { STATUS => 1 };
> }
> 
> 1;
> 
> ___END___;
> 




-- 
********************************
David William Botsch
[EMAIL PROTECTED]
********************************
## RA Server Management Utility 
## (c) 1999 by Massimiliano Pala
## All Rights Reserved
##
## Project Information:
##
##      Current Version ..................... $VER
##      Project Started on .................. 17/12/1998
##      Last Modified on .................... 30/03/2001
##      Project Closed on ................... n/a
##
## Program currently tested with OpenLDAP v.1.2 on Linux, Solaris
## and Sleepycat DB.
##
## DISC CLAIMER: THIS SOFTWARE IS GIVEN AS IS WITHOUT ANY WARRANTIES
## ABOUT ANY DAMAGE DERIVED BY THE USE ( CORRECT OR NOT ) OF THIS
## SOFTWARE. THE AUTHOR IS THEREFORE NOT RESPONSABLE IN ANY WAY OF
## DAMAGES RELATED IN ANY WAY TO THIS OR SUPPORTED SOFTWARE AS WELL.
##
## If you want to contact me (the author) please use the e-mail
## addresses listed below. Do not esitate in reporting bugs, enhancement
## or anything seems useful in developing this software:
##
##      [EMAIL PROTECTED]
##      [EMAIL PROTECTED]
##      [EMAIL PROTECTED]
##

## Thank you for using this software, and remember that Open Projects
## are the future of mankind. Do not sleep, partecipate to world wide
## efforts to make life easier for all!

sub addCertsUsers {
  my @keys = @_;

  ## Reserved Variables
  my ( @certsList );
  my ( $filename, $tmp, $ID, $cert, $ldap );

  ## Get Required parameter
  my $serverDir = getRequired( 'ServerDir' );

  ## Debugging info
  my $DEBUG = 0;

  ## This file has the latest imported certificate's serials
  $filename = "$serverDir/stuff/lastImport.txt";

  ## Let's open the stuff/lastImport.txt
  if( not -e "$filename" ) {
    configError( "File $filename not found!");
  }

  $tmp = $query->getFile( "$filename");

  if( $tmp eq "" ) {
    success( "Last Import file was empty.");
  }

  my @certsList = split( "\n", $tmp );

  my $table = $query->buildRefs ( ELEMENTS =>, MAXITEMS =>);
  my $table .= $query->startTable (COLS=>[ "Cert.-No.",
                                          "DN",
                                          "adding dn",
                                          "adding certificate" ],
                              WIDTH=>"100%",
                              TITLE_BGCOLOR=>"#DDCCFF");

  foreach $ID (@certsList) {

    my @line = ();

    my ( $filter, $serID, $parsed, $ret, $entry );
    ( $serID ) = ( $ID =~ /([a-f0-9]+)/i );

    ## Let's be sure it is in the right format
    $serID = uc( $serID );
    $serID = "0$serID" if( length($serID) % 2 );

    my $cert = $db->getItem ( DATATYPE => VALID_CERTIFICATE,
                              KEY => $serID );

    if( not $cert ) {
      $table .= $query->addTableLine( DATA => [
                    "<FONT COLOR=\"Red\">".
                    "ERROR [$serID] : can't get certificate" .
                    " from dB!\n</FONT>" ] );
      next;
    }

    $parsed = $cert->getParsed();

    push ( @line, $serID, $parsed->{DN});

# dwb7 mod

      $ret = addLDAPcert( CERTIFICATE => $cert , NOPRINT => true);

      if ($ret->{STATUS}) {
        push (@line, "success");
      } else {
        push (@line, "Error : ".$ret->{CODE});
      }


#    $ret = addLDAPuser ( CERTIFICATE=>$cert );

    my $text;
    $text .= "<FONT COLOR=\"Red\">" if ( not $ret->{STATUS} );
    $text .= $ret->{DESC};
    $text .= "</FONT>" if ( not $ret->{STATUS} );
    push ( @line, $text);

#    if( $ret->{STATUS} ) {
#      $ret = addLDAPcert( CERTIFICATE => $cert , NOPRINT => true);

 #     if ($ret->{STATUS}) {
#        push (@line, "success");
#      } else {
#        push (@line, "Error : ".$ret->{CODE});
#      }
#    } else {
#      push (@line, "operation not performed");
#    }

#end mod

    $table .= $query->addTableLine ( DATA => [ @line ]);

  }

  $table .= $query->endTable;
  print $table;

  return "Ok.";
}

sub addLDAPuser {
        my $keys = { @_ };
        my ( $cert, $parsed, $serID, $ldap, $ret );

        $cert = $keys->{CERTIFICATE};
        return if ( not $cert );

        $parsed = $cert->getParsed();
        $serID  = $parsed->{SERIAL};

        ## Get the Connection to the Server
        if ( not ( $ldap = LDAP_connect() )) {
                print "<FONT COLOR=\"Red\">";
                print "LDAP [$serID]: Connection Refused by server!\n";
                print "</FONT><BR>\n";

                return;
        };

        ## Let's bind for a predetermined User
        $ret = LDAP_bind( LDAP => $ldap );
        if( not $ret->{STATUS} ) {
                print "Failed in Bind: " . $ret->{CODE} . "\n";
                LDAP_disconnect( LDAP => $ldap );
                return $ret->{CODE};
        };

        ( $sn ) =  ( $parsed->{CN} =~ /([\S]+?)$/g );

        ####  changed Part ##########

        ## build the array from the LDAP root
        my $basedn = getRequired ('basedn');
        my @basedn_array = ();
        my $h_attribute;
        while ($basedn) {
          ## get the last element
          $h_attribute = $basedn;
          $basedn =~ s/^[^,]*,//;
          $h_attribute = substr ($h_attribute, 
                                 0, 
                                 length ($h_attribute) - length ($basedn));
          if ( not $h_attribute ) {
            $h_attribute = $basedn;
            $basedn = "";
          }
          $h_attribute =~ s/,//;
          $h_attribute =~ s/(^ )|( $)//g;
          print $h_attribute."<br>\n" if ($DEBUG);
          push (@basedn_array, $h_attribute);
        }

        ## build the array from the DN
        my $h_dn = $parsed->{DN};
        my @dn_array = ();
        my $h_attribute;
        while ($h_dn) {
          ## get the last element
          $h_attribute = $h_dn;
          $h_dn =~ s/^[^\/]*\///;
          $h_attribute = substr ($h_attribute, 
                                 0, 
                                 length ($h_attribute) - length ($h_dn));
          if ( not $h_attribute ) {
            $h_attribute = $h_dn;
            $h_dn = "";
          }
          $h_attribute =~ s/\///;
          $h_attribute =~ s/(^ )|( $)//g;
          print $h_attribute."<br>\n" if ($DEBUG);
          push (@dn_array, $h_attribute);
        }

        ## verify that the root in the DN is ok
        while (scalar (@basedn_array) and scalar (@dn_array)) {
          my $h_basedn = pop (@basedn_array);
          my $h_dn     = pop (@dn_array);
          print $h_dn." ".$h_basedn."<br>\n" if ($DEBUG);
          ## this dn cannot be added under the root-dn
          if ( (uc $h_basedn) ne (uc $h_dn) ) {
            LDAP_disconnect ( $ldap );
            return { STATUS => 0 , 
                     DESC => "Error ( dn conflicts with basedn )",
                     CODE => -1 };
          }
        }
        ## dn which should be inserted is shorter then the root-dn
        if ( scalar (@basedn_array) ) {
          LDAP_disconnect ( $ldap );
          return { STATUS => 0 , 
                   DESC => "Error ( dn is shorter then basedn )",
                   CODE => -2 };
        }
        ## if dn == basedn then their is no error because this can 
        ## be the CA-dn
        return { STATUS => 1, CODE => 0, DESC => "Success" }
          if (!scalar (@dn_array));

        ## setup the tree for the DN
        ## attention only the last ldapadd must be successful !!!
        my $add_dn = getRequired ('basedn');
        while (scalar (@dn_array)) {
          $add_dn = pop (@dn_array).",".$add_dn;

          ## detect which type we should insert
          ## here I take care about cn and c and ou and o ...
          my $type;
          if ($add_dn =~ /^ *[oO][uU].*/) {
            $type = "ou";
          } elsif ($add_dn =~ /^ *[oO].*/) {
            $type = "o";
          } elsif ($add_dn =~ /^ *[cC][nN].*/) {
            $type = "cn";
          } elsif ($add_dn =~ /^ *[cC].*/) {
            $type = "c";
          } elsif ($add_dn =~ /^ *mail.*/) {
            $type = "mail";
          } elsif ($add_dn =~ /^ *[sS]erial[nN]umber.*/) {
            $type = "serialNumber";
          } elsif ($add_dn =~ /^ *[sS][tT].*/) {
            $type = "st";
          } elsif ($add_dn =~ /^ *[lL].*/) {
            $type = "l";
          } else {
            ## unknown types will be ignored
            ## I don't set in this case the returnvalue !!!
            ## so the returnvalue is this from the last ldapadd
            $type = "";
          }

          ## insert the different types
          ## attention: I don't insert here a CA!!!
          ## this most be done otherwise because I cannot declare
          ## any o and ou to be a (sub)CA
          if ( ($type eq "cn") or
               ($type eq "mail") or
               ($type eq "serialNumber")) {
            if ( scalar ( @{ $parsed->{OU}}) ) {
              $ldapadd_result = $ldap->add( 
                        $add_dn,
                        'attr' => [
                                        'cn' => $parsed->{CN},
                                        'sn' => $parsed->{SN},
                                        'objectclass' => [
                                                'top',
                                                'person',
                                                'organizationalPerson',
                                                'inetPerson' ],
                                        'ou' => [ @{ $parsed->{OU}} ],
                                        'o' => $parsed->{O},
                                        'usercertificate;binary' => '',
                                        'mail' => $parsed->{MAIL}
                                  ]
                  );
            } else {
              $ldapadd_result = $ldap->add( 
                        $add_dn,
                        'attr' => [
                                        'cn' => $parsed->{CN},
                                        'sn' => $parsed->{SN},
                                        'objectclass' => [
                                                'top',
                                                'person',
                                                'organizationalPerson',
                                                'inetPerson' ],
                                        'o' => $parsed->{O},
                                        'usercertificate;binary' => '',
                                        'mail' => $parsed->{MAIL}
                                  ]
                  );
            }
          } elsif ($type eq "ou") {
            $ldapadd_result = $ldap->add( 
                        $add_dn,
                        'attr' => [
                                        'objectclass' => [
                                                'top',
                                                'organizationalUnit',
                                                'certificationAuthority' ],
                                        'ou' => [ @{ $parsed->{OU}} ],
                                        'o' => $parsed->{O}
                                  ]
                  );
          } elsif ($type eq "o") {
            $ldapadd_result = $ldap->add( 
                        $add_dn,
                        'attr' => [
                                        'objectclass' => [
                                                'top',
                                                'organization',
                                                'certificationAuthority' ],
                                        'o' => $parsed->{O}
                                  ]
                  );
          } elsif ($type eq "c") {
            ## this could be useful for PKIs like Verisign where
            ## you have different toplevel domains, countries and
            ## organizations
            $ldapadd_result = $ldap->add( 
                        $add_dn,
                        'attr' => [
                                        'objectclass' => [
                                                'top',
                                                'country' ]
                                  ]
                  );
          } elsif ($type eq "st") {
            $ldapadd_result = $ldap->add( 
                        $add_dn,
                        'attr' => [
                                        'objectclass' => [
                                                'top',
                                                'locality' ],
                                        'st' => $parsed->{O}
                                  ]
                  );
          } elsif ($type eq "l") {
            $ldapadd_result = $ldap->add( 
                        $add_dn,
                        'attr' => [
                                        'objectclass' => [
                                                'top',
                                                'locality' ],
                                        'l' => $parsed->{O}
                                  ]
                  );
          }
        }

        ########## End of changed part #######################

        if( $ldapadd_result->code && ($ldapadd_result->code != 68) ) {
                ## print "<FONT COLOR=\"Red\">";
                ## print "Error Adding DN [$serID]: " . $ldapadd_result->code 
."<BR>\n";
                ## print "</FONT>";
                LDAP_disconnect ( $ldap );
                return { STATUS => 0 , DESC => "Error ( code " . 
                                                $ldapadd_result->code . " )",
                         CODE => $ldapadd_result->code };
        }

        LDAP_disconnect ( $ldap );
        return { STATUS => 1, CODE => 0, DESC => "Success" };
}

## this function add certificates and CRLs to the directory
sub addLDAPattribute {
  my $keys = { @_ };
  my $obj;
  my $ret;
  my $ldap;
  my $noprint;
  my $dn;
  my $attr;

  my $DEBUG =0;

  ## check the type of the attribute
  if ( $keys->{CERTIFICATE} ) {
    $obj = $keys->{CERTIFICATE};
    $attr = "usercertificate;binary";
  } elsif ( $keys->{AUTHORITY_CERTIFICATE} ) {
    $obj = $keys->{AUTHORITY_CERTIFICATE};
    $attr = "authoritycertificate;binary";
  } elsif ( $keys->{CRL} ) {
    $obj = $keys->{CRL};
    $attr = "certificaterevocationList;binary";
  } elsif ( $keys->{AUTHORITY_CRL} ) {
    $obj = $keys->{AUTHORITY_CRL};
    $attr = "authorityrevocationList;binary";
  }
  return if ( not $obj );

  ## set output mode
  $noprint = $keys->{NOPRINT};


  ## Initializing Connection to LDAP Server
  if ( not ( $ldap = LDAP_connect() )) {
    return;
  }

  ## Let's bind for a predetermined User
  $ret = LDAP_bind( LDAP => $ldap );
  if ( not $ret->{STATUS} ) {
    LDAP_disconnect ( LDAP => $ldap );
    return;
  }

  ## get dn
  if ( $attr =~ /CERTIFICATE/i ) {
    $dn = $cert->getParsed()->{DN};
  } elsif ( $type =~ /revocationList/i ) {
    $dn = $cert->getParsed()->{ISSUER};
  }
  $dn =~ s/\//,/g;
  $dn =~ s/^ *,* *//g;

  ## $serID = $cert->getParsed()->{SERIAL};
  print "addLDAPattribute: DN= ".$dn."<br>\n" if ($DEBUG);

  ## insert into ldap
  $mesg = $ldap->modify ( 
    $dn,
    'add' => { 
              $attr => $obj->getDER()
             }
                        );


  if( $mesg->code ) { 
    my $status;

    if( $mesg->code == 20 ) {
      $status = 1;
      $txt = "Attribute already exists."
    } else {
      $status = 0;
      $txt = "Unknown Error ( " . $mesg->code . " )";
    }

    if (!$noprint)  {
      print "$txt\n";
    }
    LDAP_disconnect( LDAP => $ldap );
    return { STATUS => $status , CODE => $mesg->code };
  }

  LDAP_disconnect( LDAP => $ldap );
  if (!$noprint) {
  # print "LDAP Result [$serID]: Success ( " . $mesg->code ." )<BR>\n";
    print "Success\n";
  }
  return { STATUS => 1, DESC => "Success ( " . $mesg->code ." )",
           CODE => 0 };
}

sub addLDAPcert {
        my $keys = { @_ };
        my ( $ldap, $cert, $ret, $serID );
 
        my $DEBUG =0;

        $cert = $keys->{CERTIFICATE};
        $noprint = $keys->{NOPRINT};

        return if ( not $cert );

        $serID = $cert->getParsed()->{SERIAL};

        ## Initializing Connection to LDAP Server
        if( not ( $ldap = LDAP_connect() )) {
                return;
        }

        ## Let's bind for a predetermined User
        $ret = LDAP_bind( LDAP => $ldap );
        if( not $ret->{STATUS} ) {
                LDAP_disconnect ( LDAP => $ldap );
                return;
        }

        print $cert->getParsed()->{DN}."<br>\n" if ($DEBUG);
        my $dn = $cert->getParsed()->{DN};
        $dn =~ s/\//, /g;
        #mod dwb7
        $dn =~ s/mail/UID/;
        $dn =~ s/\@/,\@/;
        $dn =~ s/\@cornell.edu, CN=[\w+ ]+,/ /;

print "<br>" . $cert->getDER() . "<br>\n";
print $dn . "<br>\n";

        #end mod dwb7

        $mesg = $ldap->modify ( $dn,
                        'replace' => { 
                                "usersmimeCertificate" => $cert->getDER()
                                 }
                        );

        $mesg = $ldap->modify ( $dn,
                        'replace' => { 
                                "userCertificate" => $cert->getDER()
                                 }
                        );

        if( $mesg->code ) { 
                my $status;

                if( $mesg->code == 20 ) {
                        $status = 1;
                        $txt = "Certificate already exists."
                } else {
                        $status = 0;
                        $txt = "Unknown Error ( " . $mesg->code . " )";
                }

                if (!$noprint)  {
                        print "$txt\n";
                }
                LDAP_disconnect( LDAP => $ldap );
                return { STATUS => $status , CODE => $mesg->code };
        }

        LDAP_disconnect( LDAP => $ldap );
        if (!$noprint) {
                # print "LDAP Result [$serID]: Success ( " . $mesg->code ." )<BR>\n";
                print "Success\n";
        }
        return { STATUS => 1, DESC => "Success ( " . $mesg->code ." )",
                                                                CODE => 0 };
}

sub addLDAPcrl {
        my $keys = { @_ };
        my ( $ldap, $cert, $ret, $serID );
 
        my $DEBUG =0;

        $cert = $keys->{CRL};
        $noprint = $keys->{NOPRINT};

        return if ( not $cert );

        ## Initializing Connection to LDAP Server
        if( not ( $ldap = LDAP_connect() )) {
                return;
        }

        ## Let's bind for a predetermined User
        $ret = LDAP_bind( LDAP => $ldap );
        if( not $ret->{STATUS} ) {
                LDAP_disconnect ( LDAP => $ldap );
                return;
        }

        print $cert->getParsed()->{ISSUER}."<br>\n" if ($DEBUG);
        my $dn = $cert->getParsed()->{ISSUER};
        $dn =~ s/\//,/g;
        $dn =~ s/^ *,* *//g;
        $mesg = $ldap->modify ( $dn,
                        'add' => { 
                                "certificaterevocationList;binary" => $cert->getDER()
                                 }
                        );

        if( $mesg->code ) { 
                my $status;

                if( $mesg->code == 20 ) {
                        $status = 1;
                        $txt = "CRL already exists."
                } else {
                        $status = 0;
                        $txt = "Unknown Error ( " . $mesg->code . " )";
                }

                if (!$noprint)  {
                        print "$txt\n";
                }
                LDAP_disconnect( LDAP => $ldap );
                return { STATUS => $status , CODE => $mesg->code };
        }

        LDAP_disconnect( LDAP => $ldap );
        if (!$noprint) {
                # print "LDAP Result [$serID]: Success ( " . $mesg->code ." )<BR>\n";
                print "Success\n";
        }
        return { STATUS => 1, DESC => "Success ( " . $mesg->code ." )",
                                                                CODE => 0 };
}

sub LDAPsearch {

        my $keys = { @_ };
        my ( $mseg, $ldap, $limit, $ldapBase, $serID, $filter, $ret );
        
        $filter = $keys->{FILTER};
        $serID  = $keys->{SERIAL};

        return if ( not $filter );

        ## Get required configuration keys
        $ldapBase = getRequired( 'basedn' );

        ## Initializing Connection to LDAP Server
        if ( not ( $ldap = LDAP_connect() )) {
                print "<FONT COLOR=\"Red\">";
                print "LDAP [$serID]: Connection Refused by server!\n";
                print "</FONT><BR>\n";

                return;
        };

        ## Let's bind for a predetermined User
        $ret = LDAP_bind( LDAP => $ldap );
        if( not $ret->{STATUS} ) {
                print "Failed in Bind: " . $ret->{CODE} . "\n";
                LDAP_disconnect( LDAP => $ldap );
                return $ret->{CODE};
        };

        $mesg = $ldap->search ( base => "$ldapBase",
                                filter => "$filter" );

        if ( $mesg->code ) {
                LDAP_disconnect( LDAP => $ldap );
                return;
        }

        return { COUNT => $mesg->count, ENTRIES => $mesg->entries };
};


sub LDAP_connect {

        my $keys = { @_ };
        my ( $ldap, $ldapSrv, $port, $ldapUsr, $ldapBase, $ldaplim,
             $ldapPwd, $filter, @attrs, $ret );

        ## Initializing Connection to LDAP Server
        $ldapSrv  = getRequired( 'ldapserver' ); 

        $port     = getRequired('ldapport');
        $ldaplim  = getRequired('ldaplimit');

        ## if no initialization found, get defaults
        $port   = 389 unless $LDAP_Port;

        ## Get the Connection to the Server
        $ldap = Net::LDAP->new ("$ldapSrv", 
                                 port => "$port",
                                 async => 0 ,
                                debug => 4);

        return if( not $ldap );

        return $ldap;

}

sub LDAP_disconnect {

        $keys => {@_};

        my $ldap = $keys->{LDAP};

        return {STATUS => 0 } if ( not $ldap );
        $ldap->unbind;

        return {STATUS => 1};
}

sub LDAP_bind {

        my $keys = {@_};

        ## Get Required Parameters
        my $ldapUsr  = getRequired('ldaproot');
        my $ldapPwd  = getRequired('ldappwd');

        ## Get ldap passed ref
        my $ldap = $keys->{LDAP};

        ## Return if no object passed
        return if( not $ldap );

        ## Try to bind to selected user
        my $mesg = $ldap->bind( "$ldapUsr",
                                'password' => "$ldapPwd",
                                'version' => "3" );

        ## if got an error, return it
        if ( $mesg->code ) {
                LDAP_disconnect( LDAP => $ldap );
                return { STATUS => 0, CODE => $mesg->code };
        };

        return { STATUS => 1 };
}

1;

___END___;

Reply via email to