Gnus development mailing list
 help / color / mirror / Atom feed
* Get certificate from LDAP for S/MIME encryption (patch)
@ 2005-02-12 20:08 Arne Jørgensen
  2005-02-13  0:22 ` Simon Josefsson
  0 siblings, 1 reply; 13+ messages in thread
From: Arne Jørgensen @ 2005-02-12 20:08 UTC (permalink / raw)


[-- Attachment #1: Type: text/plain, Size: 1644 bytes --]

Hi,

Downloading certificates for S/MIME encryption from LDAP servers has
been on the (at least my) wish list for at long time.

I have written a patch for smime.el and mml-smime.el that implements
this.

You need to set `smime-ldap-host-list' to a list of LDAP server to ask
for the certificate. (dir.certifikat.dk has my certificate ...)

At the moment the functions are added to Gnus at the same places where
you will find the support for getting certificates via DNS. So the
functionality is only at hand if you choose to encrypt a part and not
a message. But this is general problem not directly related to LDAP
support.[1]

A major drawback is that it will only work with the Emacs 22 (the cvs
version). This is partly because Emacs 21.3's ldap.el is written
towards OpenLDAP v1 (and I think everybody uses OpenLDAP v2 these
days) and partly because a regexp in that ldap.el does not recognise
attribute description like the binary part of
"userCertificate;binary". A patch for Emacs 21.3's ldap.el is
attached.

I have not tested it on 20.7 (is it still supported by Gnus?). I tried
building No Gnus on 20.7, but that didn't work (this may be because of
a bad emacs installation on the machine with 20.7). It will probably
not work on 20.7 because as fare as I can see there is no ldap.el in
20.7.

Kind regards,

Arne

[1] Actually I will probably volunteer to reimplement the user
    interface to the S/MIME stuff. But before coding we should agree
    on how we would like it to be. (And PGP and S/MIME should probably
    share the same interface ideas and I know noting about PGP (yet)).
-- 
Arne Jørgensen <http://arnested.dk/>


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: Patch for smime.el and mml-smime.el --]
[-- Type: text/x-patch, Size: 3468 bytes --]

Index: lisp/smime.el
===================================================================
RCS file: /usr/local/cvsroot/gnus/lisp/smime.el,v
retrieving revision 7.5
diff -u -p -r7.5 smime.el
--- lisp/smime.el	19 Sep 2004 20:24:26 -0000	7.5
+++ lisp/smime.el	12 Feb 2005 19:38:41 -0000
@@ -119,6 +119,7 @@
 ;;; Code:
 
 (require 'dig)
+(require 'ldap)
 (eval-when-compile (require 'cl))
 
 (defgroup smime nil
@@ -215,6 +216,11 @@ If nil, use system defaults."
 		 string)
   :group 'smime)
 
+(defcustom smime-ldap-host-list nil
+  "A list of LDAP hosts with S/MIME user certificates."
+  :type '(repeat (string :tag "Host name"))
+  :group 'smime)
+
 (defvar smime-details-buffer "*OpenSSL output*")
 
 ;; Use mm-util?
@@ -555,6 +561,33 @@ A string or a list of strings is returne
       (kill-buffer digbuf)
       retbuf))
 
+(defun smime-cert-by-ldap-1 (mail host)
+  "Get cetificate for MAIL from the ldap server at HOST."
+  (let ((ldapresult (ldap-search (concat "mail=" mail) host '("userCertificate") nil))
+	(retbuf (generate-new-buffer (format "*certificate for %s*" mail))))
+    (if (> (length ldapresult) 1)
+	(with-current-buffer retbuf
+	  (set-buffer-multibyte nil)
+	  (insert (nth 1 (car (nth 1 ldapresult))))
+	  (goto-char (point-min))
+	  (if (smime-call-openssl-region (point-min) (point-max) t "x509" "-inform" "DER" "-outform" "PEM")
+	      (progn 
+		(delete-region (point) (point-max))
+		retbuf)
+	    (kill-buffer retbuf)
+	    nil))
+      (kill-buffer retbuf)
+      nil)))
+
+(defun smime-cert-by-ldap (mail)
+  "Find certificate for MAIL."
+  (if smime-ldap-host-list
+      (catch 'certbuf
+	(dolist (host smime-ldap-host-list)
+	  (let ((retbuf (smime-cert-by-ldap-1 mail host)))
+	    (when retbuf 
+	      (throw 'certbuf retbuf)))))))
+  
 ;; User interface.
 
 (defvar smime-buffer "*SMIME*")
Index: lisp/mml-smime.el
===================================================================
RCS file: /usr/local/cvsroot/gnus/lisp/mml-smime.el,v
retrieving revision 7.3
diff -u -p -r7.3 mml-smime.el
--- lisp/mml-smime.el	20 May 2004 08:02:40 -0000	7.3
+++ lisp/mml-smime.el	12 Feb 2005 19:38:42 -0000
@@ -115,6 +115,25 @@
       (quit))
     result))
 
+(defun mml-smime-get-dns-ldap ()
+  ;; todo: deal with comma separated multiple recipients
+  (let (result who bad cert)
+    (condition-case ()
+	(while (not result)
+	  (setq who (read-from-minibuffer
+		     (format "%sLookup certificate for: " (or bad ""))
+		     (cadr (funcall gnus-extract-address-components
+				    (or (save-excursion
+					  (save-restriction
+					    (message-narrow-to-headers)
+					    (message-fetch-field "to")))
+					"")))))
+	  (if (setq cert (smime-cert-by-ldap who))
+	      (setq result (list 'certfile (buffer-name cert)))
+	    (setq bad (format "`%s' not found. " who))))
+      (quit))
+    result))
+
 (defun mml-smime-encrypt-query ()
   ;; todo: add ldap support (xemacs ldap api?)
   ;; todo: try dns/ldap automatically first, before prompting user
@@ -122,9 +141,11 @@
     (while (not done)
       (ecase (read (gnus-completing-read-with-default
 		    "dns" "Fetch certificate from"
-		    '(("dns") ("file")) nil t))
+		    '(("dns") ("ldap") ("file")) nil t))
 	(dns (setq certs (append certs
 				 (mml-smime-get-dns-cert))))
+	(ldap (setq certs (append certs
+				 (mml-smime-get-dns-ldap))))
 	(file (setq certs (append certs
 				  (mml-smime-get-file-cert)))))
       (setq done (not (y-or-n-p "Add more recipients? "))))

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #3: Patch for Emacs 21.3's ldap.el --]
[-- Type: text/x-patch, Size: 1100 bytes --]

--- ldap.el~	2005-02-12 19:39:37.000000000 +0100
+++ ldap.el	2005-02-12 19:39:32.000000000 +0100
@@ -568,12 +568,18 @@ an alist of attribute/value pairs."
 			   buf
 			   nil	  
 			   ,@arglist
-			   "-t"		; Write values to temp files
+			   "-tt"		; Write values to temp files
+			   "-x"
+			   "-LL"
 			   ,@ldap-ldapsearch-args
 			   ,@filter))
       (insert "\n")
       (goto-char (point-min))
       
+      (while (re-search-forward "[\t\n\f]+ " nil t)
+	(replace-match "" nil nil))
+      (goto-char (point-min))
+
       (if (looking-at "usage")
 	  (error "Incorrect ldapsearch invocation")
 	(message "Parsing results... ")
@@ -584,9 +590,9 @@ an alist of attribute/value pairs."
 					       (end-of-line)
 					       (point))))
 	  (forward-line 1)
-	  (while (looking-at "^\\(\\w*\\)[=:\t ]+\\(<[\t ]*file://\\)?\\(.*\\)$")
+	  (while (looking-at "^\\(\\w*\\)\\(;\\w*\\)?[=:\t ]+\\(<[\t ]*file://\\)?\\(.*\\)$")
 	    (setq name (match-string 1)
-		  value (match-string 3))
+		  value (match-string 4))
 	    (save-excursion
 	      (set-buffer bufval)
 	      (erase-buffer)

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: Get certificate from LDAP for S/MIME encryption (patch)
  2005-02-12 20:08 Get certificate from LDAP for S/MIME encryption (patch) Arne Jørgensen
@ 2005-02-13  0:22 ` Simon Josefsson
  2005-02-13 16:10   ` Arne Jørgensen
                     ` (3 more replies)
  0 siblings, 4 replies; 13+ messages in thread
From: Simon Josefsson @ 2005-02-13  0:22 UTC (permalink / raw)
  Cc: ding

Arne Jørgensen <arne@arnested.dk> writes:

> I have written a patch for smime.el and mml-smime.el that implements
> this.

Neat!

> At the moment the functions are added to Gnus at the same places where
> you will find the support for getting certificates via DNS. So the
> functionality is only at hand if you choose to encrypt a part and not
> a message. But this is general problem not directly related to LDAP
> support.[1]

This came up recently as well.  If you want to work on fixing that, it
would be appreciated.

> A major drawback is that it will only work with the Emacs 22 (the cvs
> version). This is partly because Emacs 21.3's ldap.el is written
> towards OpenLDAP v1 (and I think everybody uses OpenLDAP v2 these
> days) and partly because a regexp in that ldap.el does not recognise
> attribute description like the binary part of
> "userCertificate;binary". A patch for Emacs 21.3's ldap.el is
> attached.

Can you post it to emacs-devel@gnu.org?  If nobody objects to it, but
nobody apply it, ping me and I might be able to.

> I have not tested it on 20.7 (is it still supported by Gnus?).  I
> tried building No Gnus on 20.7, but that didn't work (this may be
> because of a bad emacs installation on the machine with 20.7). It
> will probably not work on 20.7 because as fare as I can see there is
> no ldap.el in 20.7.

CVS Gnus do not support 20.7.

> [1] Actually I will probably volunteer to reimplement the user
>     interface to the S/MIME stuff. But before coding we should agree
>     on how we would like it to be. (And PGP and S/MIME should probably
>     share the same interface ideas and I know noting about PGP (yet)).

Great.  What is there to agree on?  Is there something wrong with
making the MML tag for individual parts work on the "global" security
MML tag?

Have you assigned copyright on your work?  It is required before we
can install your patch.

Thanks!



^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: Get certificate from LDAP for S/MIME encryption (patch)
  2005-02-13  0:22 ` Simon Josefsson
@ 2005-02-13 16:10   ` Arne Jørgensen
  2005-02-17 23:32     ` Arne Jørgensen
  2005-02-13 20:02   ` Arne Jørgensen
                     ` (2 subsequent siblings)
  3 siblings, 1 reply; 13+ messages in thread
From: Arne Jørgensen @ 2005-02-13 16:10 UTC (permalink / raw)


[-- Attachment #1: Type: text/plain, Size: 3725 bytes --]

Simon Josefsson <jas@extundo.com> writes:

> Arne Jørgensen <arne@arnested.dk> writes:
>
>> I have written a patch for smime.el and mml-smime.el that implements
>> this.
>
> Neat!
>
>> At the moment the functions are added to Gnus at the same places where
>> you will find the support for getting certificates via DNS. So the
>> functionality is only at hand if you choose to encrypt a part and not
>> a message. But this is general problem not directly related to LDAP
>> support.[1]
>
> This came up recently as well.  If you want to work on fixing that, it
> would be appreciated.

See below.

>> A major drawback is that it will only work with the Emacs 22 (the cvs
>> version). This is partly because Emacs 21.3's ldap.el is written
>> towards OpenLDAP v1 (and I think everybody uses OpenLDAP v2 these
>> days) and partly because a regexp in that ldap.el does not recognise
>> attribute description like the binary part of
>> "userCertificate;binary". A patch for Emacs 21.3's ldap.el is
>> attached.
>
> Can you post it to emacs-devel@gnu.org?  If nobody objects to it, but
> nobody apply it, ping me and I might be able to.

Well, CVS Emacs' ldap.el is already written towards OpenLDAP v2 and
I got the patches to retrieve ";binary" stuff applied about a week
ago.

There are no realeases planned in the 21.x series except for security
fixes (like the newly released 21.4). The next realease from cvs trunk
will be 22.

In stead I have implemented a `smime-ldap-search' that will just call
`ldap-search' when running in Emacs 22 an above, and use a slightly
rewritten version of the same function in Emacs 21. See attached file
and new patch to use it.

>> I have not tested it on 20.7 (is it still supported by Gnus?).  I
>> tried building No Gnus on 20.7, but that didn't work (this may be
>> because of a bad emacs installation on the machine with 20.7). It
>> will probably not work on 20.7 because as fare as I can see there is
>> no ldap.el in 20.7.
>
> CVS Gnus do not support 20.7.

Great. I hadn't noticed.

>> [1] Actually I will probably volunteer to reimplement the user
>>     interface to the S/MIME stuff. But before coding we should agree
>>     on how we would like it to be. (And PGP and S/MIME should probably
>>     share the same interface ideas and I know noting about PGP (yet)).
>
> Great.  What is there to agree on?  Is there something wrong with
> making the MML tag for individual parts work on the "global" security
> MML tag?

I don't think so. That was part of what I was thinking on.

Other thoughts are:

 - gnus should try to find the certificate without asking the user.
   Probably a list of preferred methods ('dns 'ldap 'file 'ask).

 - better access to locally cached certificates (this was mentioned in
   the recent thread on comp.emacs.gnus also). We could just store the
   certificates in a dir with the email adress as file name.

 - maybe wait until the messages is to be sent before we ask which
   certificates to use. At the moment you will not sign/encrypt to
   adresse added after you have put ind the mml tags. Dns and
   ldap stores the certificates in a temporary buffer - what happens
   if you file the mail as a draft and leave Emacs?

 - havent verified this recently, but I think gnus will send a message
   even though openssl fails (ie because of a typo in the password).
   This should probably be considered a security bug.

 - use password.el to cache passwords as you mentioned on
   comp.emacs.gnus.

> Have you assigned copyright on your work?  It is required before we
> can install your patch.

Yes. I signed papers for Gnus some time around christmas 2003.

> Thanks!

Always a pleasure.

Kind regards,
-- 
Arne Jørgensen <http://arnested.dk/>


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: Patch for mml-smime.el and smime.el --]
[-- Type: text/x-patch, Size: 4647 bytes --]

Index: lisp/mml-smime.el
===================================================================
RCS file: /usr/local/cvsroot/gnus/lisp/mml-smime.el,v
retrieving revision 7.3
diff -u -p -r7.3 mml-smime.el
--- lisp/mml-smime.el	20 May 2004 08:02:40 -0000	7.3
+++ lisp/mml-smime.el	13 Feb 2005 15:40:20 -0000
@@ -1,5 +1,5 @@
 ;;; mml-smime.el --- S/MIME support for MML
-;; Copyright (c) 2000, 2001, 2003 Free Software Foundation, Inc.
+;; Copyright (c) 2000, 2001, 2003, 2005 Free Software Foundation, Inc.
 
 ;; Author: Simon Josefsson <simon@josefsson.org>
 ;; Keywords: Gnus, MIME, S/MIME, MML
@@ -115,6 +115,25 @@
       (quit))
     result))
 
+(defun mml-smime-get-dns-ldap ()
+  ;; todo: deal with comma separated multiple recipients
+  (let (result who bad cert)
+    (condition-case ()
+	(while (not result)
+	  (setq who (read-from-minibuffer
+		     (format "%sLookup certificate for: " (or bad ""))
+		     (cadr (funcall gnus-extract-address-components
+				    (or (save-excursion
+					  (save-restriction
+					    (message-narrow-to-headers)
+					    (message-fetch-field "to")))
+					"")))))
+	  (if (setq cert (smime-cert-by-ldap who))
+	      (setq result (list 'certfile (buffer-name cert)))
+	    (setq bad (format "`%s' not found. " who))))
+      (quit))
+    result))
+
 (defun mml-smime-encrypt-query ()
   ;; todo: add ldap support (xemacs ldap api?)
   ;; todo: try dns/ldap automatically first, before prompting user
@@ -122,9 +141,11 @@
     (while (not done)
       (ecase (read (gnus-completing-read-with-default
 		    "dns" "Fetch certificate from"
-		    '(("dns") ("file")) nil t))
+		    '(("dns") ("ldap") ("file")) nil t))
 	(dns (setq certs (append certs
 				 (mml-smime-get-dns-cert))))
+	(ldap (setq certs (append certs
+				 (mml-smime-get-dns-ldap))))
 	(file (setq certs (append certs
 				  (mml-smime-get-file-cert)))))
       (setq done (not (y-or-n-p "Add more recipients? "))))
Index: lisp/smime.el
===================================================================
RCS file: /usr/local/cvsroot/gnus/lisp/smime.el,v
retrieving revision 7.5
diff -u -p -r7.5 smime.el
--- lisp/smime.el	19 Sep 2004 20:24:26 -0000	7.5
+++ lisp/smime.el	13 Feb 2005 15:40:21 -0000
@@ -1,5 +1,5 @@
 ;;; smime.el --- S/MIME support library
-;; Copyright (c) 2000, 2001, 2003 Free Software Foundation, Inc.
+;; Copyright (c) 2000, 2001, 2003, 2005 Free Software Foundation, Inc.
 
 ;; Author: Simon Josefsson <simon@josefsson.org>
 ;; Keywords: SMIME X.509 PEM OpenSSL
@@ -26,7 +26,7 @@
 ;; This library perform S/MIME operations from within Emacs.
 ;;
 ;; Functions for fetching certificates from public repositories are
-;; provided, currently only from DNS.  LDAP support (via EUDC) is planned.
+;; provided, currently from DNS and LDAP.
 ;;
 ;; It uses OpenSSL (tested with version 0.9.5a and 0.9.6) for signing,
 ;; encryption and decryption.
@@ -115,10 +115,12 @@
 ;; 2000-06-05  initial version, committed to Gnus CVS contrib/
 ;; 2000-10-28  retrieve certificates via DNS CERT RRs
 ;; 2001-10-14  posted to gnu.emacs.sources
+;; 2005-02-13  retrieve certificates via LDAP
 
 ;;; Code:
 
 (require 'dig)
+(require 'smime-ldap)
 (eval-when-compile (require 'cl))
 
 (defgroup smime nil
@@ -215,6 +217,11 @@ If nil, use system defaults."
 		 string)
   :group 'smime)
 
+(defcustom smime-ldap-host-list nil
+  "A list of LDAP hosts with S/MIME user certificates."
+  :type '(repeat (string :tag "Host name"))
+  :group 'smime)
+
 (defvar smime-details-buffer "*OpenSSL output*")
 
 ;; Use mm-util?
@@ -555,6 +562,33 @@ A string or a list of strings is returne
       (kill-buffer digbuf)
       retbuf))
 
+(defun smime-cert-by-ldap-1 (mail host)
+  "Get cetificate for MAIL from the ldap server at HOST."
+  (let ((ldapresult (smime-ldap-search (concat "mail=" mail) host '("userCertificate") nil))
+	(retbuf (generate-new-buffer (format "*certificate for %s*" mail))))
+    (if (> (length ldapresult) 1)
+	(with-current-buffer retbuf
+	  (set-buffer-multibyte nil)
+	  (insert (nth 1 (car (nth 1 ldapresult))))
+	  (goto-char (point-min))
+	  (if (smime-call-openssl-region (point-min) (point-max) t "x509" "-inform" "DER" "-outform" "PEM")
+	      (progn 
+		(delete-region (point) (point-max))
+		retbuf)
+	    (kill-buffer retbuf)
+	    nil))
+      (kill-buffer retbuf)
+      nil)))
+
+(defun smime-cert-by-ldap (mail)
+  "Find certificate for MAIL."
+  (if smime-ldap-host-list
+      (catch 'certbuf
+	(dolist (host smime-ldap-host-list)
+	  (let ((retbuf (smime-cert-by-ldap-1 mail host)))
+	    (when retbuf 
+	      (throw 'certbuf retbuf)))))))
+  
 ;; User interface.
 
 (defvar smime-buffer "*SMIME*")

[-- Attachment #3: Slightly changed version of ldap-search for Emacs 21 --]
[-- Type: application/emacs-lisp, Size: 7837 bytes --]

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: Get certificate from LDAP for S/MIME encryption (patch)
  2005-02-13  0:22 ` Simon Josefsson
  2005-02-13 16:10   ` Arne Jørgensen
@ 2005-02-13 20:02   ` Arne Jørgensen
  2005-02-14 13:42   ` Arne Jørgensen
       [not found]   ` <877jlbrzdq.fsf@seamus.arnested.dk>
  3 siblings, 0 replies; 13+ messages in thread
From: Arne Jørgensen @ 2005-02-13 20:02 UTC (permalink / raw)


[-- Attachment #1: Type: text/plain, Size: 3725 bytes --]

Simon Josefsson <jas@extundo.com> writes:

> Arne Jørgensen <arne@arnested.dk> writes:
>
>> I have written a patch for smime.el and mml-smime.el that implements
>> this.
>
> Neat!
>
>> At the moment the functions are added to Gnus at the same places where
>> you will find the support for getting certificates via DNS. So the
>> functionality is only at hand if you choose to encrypt a part and not
>> a message. But this is general problem not directly related to LDAP
>> support.[1]
>
> This came up recently as well.  If you want to work on fixing that, it
> would be appreciated.

See below.

>> A major drawback is that it will only work with the Emacs 22 (the cvs
>> version). This is partly because Emacs 21.3's ldap.el is written
>> towards OpenLDAP v1 (and I think everybody uses OpenLDAP v2 these
>> days) and partly because a regexp in that ldap.el does not recognise
>> attribute description like the binary part of
>> "userCertificate;binary". A patch for Emacs 21.3's ldap.el is
>> attached.
>
> Can you post it to emacs-devel@gnu.org?  If nobody objects to it, but
> nobody apply it, ping me and I might be able to.

Well, CVS Emacs' ldap.el is already written towards OpenLDAP v2 and
I got the patches to retrieve ";binary" stuff applied about a week
ago.

There are no realeases planned in the 21.x series except for security
fixes (like the newly released 21.4). The next realease from cvs trunk
will be 22.

In stead I have implemented a `smime-ldap-search' that will just call
`ldap-search' when running in Emacs 22 an above, and use a slightly
rewritten version of the same function in Emacs 21. See attached file
and new patch to use it.

>> I have not tested it on 20.7 (is it still supported by Gnus?).  I
>> tried building No Gnus on 20.7, but that didn't work (this may be
>> because of a bad emacs installation on the machine with 20.7). It
>> will probably not work on 20.7 because as fare as I can see there is
>> no ldap.el in 20.7.
>
> CVS Gnus do not support 20.7.

Great. I hadn't noticed.

>> [1] Actually I will probably volunteer to reimplement the user
>>     interface to the S/MIME stuff. But before coding we should agree
>>     on how we would like it to be. (And PGP and S/MIME should probably
>>     share the same interface ideas and I know noting about PGP (yet)).
>
> Great.  What is there to agree on?  Is there something wrong with
> making the MML tag for individual parts work on the "global" security
> MML tag?

I don't think so. That was part of what I was thinking on.

Other thoughts are:

 - gnus should try to find the certificate without asking the user.
   Probably a list of preferred methods ('dns 'ldap 'file 'ask).

 - better access to locally cached certificates (this was mentioned in
   the recent thread on comp.emacs.gnus also). We could just store the
   certificates in a dir with the email adress as file name.

 - maybe wait until the messages is to be sent before we ask which
   certificates to use. At the moment you will not sign/encrypt to
   adresse added after you have put ind the mml tags. Dns and
   ldap stores the certificates in a temporary buffer - what happens
   if you file the mail as a draft and leave Emacs?

 - havent verified this recently, but I think gnus will send a message
   even though openssl fails (ie because of a typo in the password).
   This should probably be considered a security bug.

 - use password.el to cache passwords as you mentioned on
   comp.emacs.gnus.

> Have you assigned copyright on your work?  It is required before we
> can install your patch.

Yes. I signed papers for Gnus some time around christmas 2003.

> Thanks!

Always a pleasure.

Kind regards,
-- 
Arne Jørgensen <http://arnested.dk/>


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: Patch for mml-smime.el and smime.el --]
[-- Type: text/x-patch, Size: 4647 bytes --]

Index: lisp/mml-smime.el
===================================================================
RCS file: /usr/local/cvsroot/gnus/lisp/mml-smime.el,v
retrieving revision 7.3
diff -u -p -r7.3 mml-smime.el
--- lisp/mml-smime.el	20 May 2004 08:02:40 -0000	7.3
+++ lisp/mml-smime.el	13 Feb 2005 15:40:20 -0000
@@ -1,5 +1,5 @@
 ;;; mml-smime.el --- S/MIME support for MML
-;; Copyright (c) 2000, 2001, 2003 Free Software Foundation, Inc.
+;; Copyright (c) 2000, 2001, 2003, 2005 Free Software Foundation, Inc.
 
 ;; Author: Simon Josefsson <simon@josefsson.org>
 ;; Keywords: Gnus, MIME, S/MIME, MML
@@ -115,6 +115,25 @@
       (quit))
     result))
 
+(defun mml-smime-get-dns-ldap ()
+  ;; todo: deal with comma separated multiple recipients
+  (let (result who bad cert)
+    (condition-case ()
+	(while (not result)
+	  (setq who (read-from-minibuffer
+		     (format "%sLookup certificate for: " (or bad ""))
+		     (cadr (funcall gnus-extract-address-components
+				    (or (save-excursion
+					  (save-restriction
+					    (message-narrow-to-headers)
+					    (message-fetch-field "to")))
+					"")))))
+	  (if (setq cert (smime-cert-by-ldap who))
+	      (setq result (list 'certfile (buffer-name cert)))
+	    (setq bad (format "`%s' not found. " who))))
+      (quit))
+    result))
+
 (defun mml-smime-encrypt-query ()
   ;; todo: add ldap support (xemacs ldap api?)
   ;; todo: try dns/ldap automatically first, before prompting user
@@ -122,9 +141,11 @@
     (while (not done)
       (ecase (read (gnus-completing-read-with-default
 		    "dns" "Fetch certificate from"
-		    '(("dns") ("file")) nil t))
+		    '(("dns") ("ldap") ("file")) nil t))
 	(dns (setq certs (append certs
 				 (mml-smime-get-dns-cert))))
+	(ldap (setq certs (append certs
+				 (mml-smime-get-dns-ldap))))
 	(file (setq certs (append certs
 				  (mml-smime-get-file-cert)))))
       (setq done (not (y-or-n-p "Add more recipients? "))))
Index: lisp/smime.el
===================================================================
RCS file: /usr/local/cvsroot/gnus/lisp/smime.el,v
retrieving revision 7.5
diff -u -p -r7.5 smime.el
--- lisp/smime.el	19 Sep 2004 20:24:26 -0000	7.5
+++ lisp/smime.el	13 Feb 2005 15:40:21 -0000
@@ -1,5 +1,5 @@
 ;;; smime.el --- S/MIME support library
-;; Copyright (c) 2000, 2001, 2003 Free Software Foundation, Inc.
+;; Copyright (c) 2000, 2001, 2003, 2005 Free Software Foundation, Inc.
 
 ;; Author: Simon Josefsson <simon@josefsson.org>
 ;; Keywords: SMIME X.509 PEM OpenSSL
@@ -26,7 +26,7 @@
 ;; This library perform S/MIME operations from within Emacs.
 ;;
 ;; Functions for fetching certificates from public repositories are
-;; provided, currently only from DNS.  LDAP support (via EUDC) is planned.
+;; provided, currently from DNS and LDAP.
 ;;
 ;; It uses OpenSSL (tested with version 0.9.5a and 0.9.6) for signing,
 ;; encryption and decryption.
@@ -115,10 +115,12 @@
 ;; 2000-06-05  initial version, committed to Gnus CVS contrib/
 ;; 2000-10-28  retrieve certificates via DNS CERT RRs
 ;; 2001-10-14  posted to gnu.emacs.sources
+;; 2005-02-13  retrieve certificates via LDAP
 
 ;;; Code:
 
 (require 'dig)
+(require 'smime-ldap)
 (eval-when-compile (require 'cl))
 
 (defgroup smime nil
@@ -215,6 +217,11 @@ If nil, use system defaults."
 		 string)
   :group 'smime)
 
+(defcustom smime-ldap-host-list nil
+  "A list of LDAP hosts with S/MIME user certificates."
+  :type '(repeat (string :tag "Host name"))
+  :group 'smime)
+
 (defvar smime-details-buffer "*OpenSSL output*")
 
 ;; Use mm-util?
@@ -555,6 +562,33 @@ A string or a list of strings is returne
       (kill-buffer digbuf)
       retbuf))
 
+(defun smime-cert-by-ldap-1 (mail host)
+  "Get cetificate for MAIL from the ldap server at HOST."
+  (let ((ldapresult (smime-ldap-search (concat "mail=" mail) host '("userCertificate") nil))
+	(retbuf (generate-new-buffer (format "*certificate for %s*" mail))))
+    (if (> (length ldapresult) 1)
+	(with-current-buffer retbuf
+	  (set-buffer-multibyte nil)
+	  (insert (nth 1 (car (nth 1 ldapresult))))
+	  (goto-char (point-min))
+	  (if (smime-call-openssl-region (point-min) (point-max) t "x509" "-inform" "DER" "-outform" "PEM")
+	      (progn 
+		(delete-region (point) (point-max))
+		retbuf)
+	    (kill-buffer retbuf)
+	    nil))
+      (kill-buffer retbuf)
+      nil)))
+
+(defun smime-cert-by-ldap (mail)
+  "Find certificate for MAIL."
+  (if smime-ldap-host-list
+      (catch 'certbuf
+	(dolist (host smime-ldap-host-list)
+	  (let ((retbuf (smime-cert-by-ldap-1 mail host)))
+	    (when retbuf 
+	      (throw 'certbuf retbuf)))))))
+  
 ;; User interface.
 
 (defvar smime-buffer "*SMIME*")

[-- Attachment #3: Slightly changed version of ldap-search for Emacs 21 --]
[-- Type: application/emacs-lisp, Size: 7837 bytes --]

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: Get certificate from LDAP for S/MIME encryption (patch)
  2005-02-13  0:22 ` Simon Josefsson
  2005-02-13 16:10   ` Arne Jørgensen
  2005-02-13 20:02   ` Arne Jørgensen
@ 2005-02-14 13:42   ` Arne Jørgensen
       [not found]   ` <877jlbrzdq.fsf@seamus.arnested.dk>
  3 siblings, 0 replies; 13+ messages in thread
From: Arne Jørgensen @ 2005-02-14 13:42 UTC (permalink / raw)


[-- Attachment #1: Type: text/plain, Size: 3723 bytes --]

Simon Josefsson <jas@extundo.com> writes:

> Arne Jørgensen <arne@arnested.dk> writes:
>
>> I have written a patch for smime.el and mml-smime.el that implements
>> this.
>
> Neat!
>
>> At the moment the functions are added to Gnus at the same places where
>> you will find the support for getting certificates via DNS. So the
>> functionality is only at hand if you choose to encrypt a part and not
>> a message. But this is general problem not directly related to LDAP
>> support.[1]
>
> This came up recently as well.  If you want to work on fixing that, it
> would be appreciated.

See below.

>> A major drawback is that it will only work with the Emacs 22 (the cvs
>> version). This is partly because Emacs 21.3's ldap.el is written
>> towards OpenLDAP v1 (and I think everybody uses OpenLDAP v2 these
>> days) and partly because a regexp in that ldap.el does not recognise
>> attribute description like the binary part of
>> "userCertificate;binary". A patch for Emacs 21.3's ldap.el is
>> attached.
>
> Can you post it to emacs-devel@gnu.org?  If nobody objects to it, but
> nobody apply it, ping me and I might be able to.

Well, CVS Emacs' ldap.el is already written towards OpenLDAP v2 and
I got the patches to retrieve ";binary" stuff applied about a week
ago.

There are no realeases planned in the 21.x series except for security
fixes (like the newly released 21.4). The next realease from cvs trunk
will be 22.

In stead I have implemented a `smime-ldap-search' that will just call
`ldap-search' when running in Emacs 22 an above, and use a slightly
rewritten version of the same function in Emacs 21. See attached file
and new patch to use it.

>> I have not tested it on 20.7 (is it still supported by Gnus?).  I
>> tried building No Gnus on 20.7, but that didn't work (this may be
>> because of a bad emacs installation on the machine with 20.7). It
>> will probably not work on 20.7 because as fare as I can see there is
>> no ldap.el in 20.7.
>
> CVS Gnus do not support 20.7.

Great. I hadn't noticed.

>> [1] Actually I will probably volunteer to reimplement the user
>>     interface to the S/MIME stuff. But before coding we should agree
>>     on how we would like it to be. (And PGP and S/MIME should probably
>>     share the same interface ideas and I know noting about PGP (yet)).
>
> Great.  What is there to agree on?  Is there something wrong with
> making the MML tag for individual parts work on the "global" security
> MML tag?

I don't think so. That was part of what I was thinking on.

Other thoughts are:

 - gnus should try to find the certificate without asking the user.
   Probably a list of preferred methods ('dns 'ldap 'file 'ask).

 - better access to locally cached certificates (this was mentioned in
   the recent thread on gnu.emacs.gnus also). We could just store the
   certificates in a dir with the email adress as file name.

 - maybe wait until the messages is to be sent before we ask which
   certificates to use. At the moment you will not sign/encrypt to
   adresse added after you have put ind the mml tags. Dns and
   ldap stores the certificates in a temporary buffer - what happens
   if you file the mail as a draft and leave Emacs?

 - havent verified this recently, but I think gnus will send a message
   even though openssl fails (ie because of a typo in the password).
   This should probably be considered a security bug.

 - use password.el to cache passwords as you mentioned on
   gnu.emacs.gnus.

> Have you assigned copyright on your work?  It is required before we
> can install your patch.

Yes. I signed papers for Gnus some time around christmas 2003.

> Thanks!

Always a pleasure.

Kind regards,
-- 
Arne Jørgensen <http://arnested.dk/>


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: Patch for mml-smime.el and smime.el --]
[-- Type: text/x-patch, Size: 4647 bytes --]

Index: lisp/mml-smime.el
===================================================================
RCS file: /usr/local/cvsroot/gnus/lisp/mml-smime.el,v
retrieving revision 7.3
diff -u -p -r7.3 mml-smime.el
--- lisp/mml-smime.el	20 May 2004 08:02:40 -0000	7.3
+++ lisp/mml-smime.el	13 Feb 2005 15:40:20 -0000
@@ -1,5 +1,5 @@
 ;;; mml-smime.el --- S/MIME support for MML
-;; Copyright (c) 2000, 2001, 2003 Free Software Foundation, Inc.
+;; Copyright (c) 2000, 2001, 2003, 2005 Free Software Foundation, Inc.
 
 ;; Author: Simon Josefsson <simon@josefsson.org>
 ;; Keywords: Gnus, MIME, S/MIME, MML
@@ -115,6 +115,25 @@
       (quit))
     result))
 
+(defun mml-smime-get-dns-ldap ()
+  ;; todo: deal with comma separated multiple recipients
+  (let (result who bad cert)
+    (condition-case ()
+	(while (not result)
+	  (setq who (read-from-minibuffer
+		     (format "%sLookup certificate for: " (or bad ""))
+		     (cadr (funcall gnus-extract-address-components
+				    (or (save-excursion
+					  (save-restriction
+					    (message-narrow-to-headers)
+					    (message-fetch-field "to")))
+					"")))))
+	  (if (setq cert (smime-cert-by-ldap who))
+	      (setq result (list 'certfile (buffer-name cert)))
+	    (setq bad (format "`%s' not found. " who))))
+      (quit))
+    result))
+
 (defun mml-smime-encrypt-query ()
   ;; todo: add ldap support (xemacs ldap api?)
   ;; todo: try dns/ldap automatically first, before prompting user
@@ -122,9 +141,11 @@
     (while (not done)
       (ecase (read (gnus-completing-read-with-default
 		    "dns" "Fetch certificate from"
-		    '(("dns") ("file")) nil t))
+		    '(("dns") ("ldap") ("file")) nil t))
 	(dns (setq certs (append certs
 				 (mml-smime-get-dns-cert))))
+	(ldap (setq certs (append certs
+				 (mml-smime-get-dns-ldap))))
 	(file (setq certs (append certs
 				  (mml-smime-get-file-cert)))))
       (setq done (not (y-or-n-p "Add more recipients? "))))
Index: lisp/smime.el
===================================================================
RCS file: /usr/local/cvsroot/gnus/lisp/smime.el,v
retrieving revision 7.5
diff -u -p -r7.5 smime.el
--- lisp/smime.el	19 Sep 2004 20:24:26 -0000	7.5
+++ lisp/smime.el	13 Feb 2005 15:40:21 -0000
@@ -1,5 +1,5 @@
 ;;; smime.el --- S/MIME support library
-;; Copyright (c) 2000, 2001, 2003 Free Software Foundation, Inc.
+;; Copyright (c) 2000, 2001, 2003, 2005 Free Software Foundation, Inc.
 
 ;; Author: Simon Josefsson <simon@josefsson.org>
 ;; Keywords: SMIME X.509 PEM OpenSSL
@@ -26,7 +26,7 @@
 ;; This library perform S/MIME operations from within Emacs.
 ;;
 ;; Functions for fetching certificates from public repositories are
-;; provided, currently only from DNS.  LDAP support (via EUDC) is planned.
+;; provided, currently from DNS and LDAP.
 ;;
 ;; It uses OpenSSL (tested with version 0.9.5a and 0.9.6) for signing,
 ;; encryption and decryption.
@@ -115,10 +115,12 @@
 ;; 2000-06-05  initial version, committed to Gnus CVS contrib/
 ;; 2000-10-28  retrieve certificates via DNS CERT RRs
 ;; 2001-10-14  posted to gnu.emacs.sources
+;; 2005-02-13  retrieve certificates via LDAP
 
 ;;; Code:
 
 (require 'dig)
+(require 'smime-ldap)
 (eval-when-compile (require 'cl))
 
 (defgroup smime nil
@@ -215,6 +217,11 @@ If nil, use system defaults."
 		 string)
   :group 'smime)
 
+(defcustom smime-ldap-host-list nil
+  "A list of LDAP hosts with S/MIME user certificates."
+  :type '(repeat (string :tag "Host name"))
+  :group 'smime)
+
 (defvar smime-details-buffer "*OpenSSL output*")
 
 ;; Use mm-util?
@@ -555,6 +562,33 @@ A string or a list of strings is returne
       (kill-buffer digbuf)
       retbuf))
 
+(defun smime-cert-by-ldap-1 (mail host)
+  "Get cetificate for MAIL from the ldap server at HOST."
+  (let ((ldapresult (smime-ldap-search (concat "mail=" mail) host '("userCertificate") nil))
+	(retbuf (generate-new-buffer (format "*certificate for %s*" mail))))
+    (if (> (length ldapresult) 1)
+	(with-current-buffer retbuf
+	  (set-buffer-multibyte nil)
+	  (insert (nth 1 (car (nth 1 ldapresult))))
+	  (goto-char (point-min))
+	  (if (smime-call-openssl-region (point-min) (point-max) t "x509" "-inform" "DER" "-outform" "PEM")
+	      (progn 
+		(delete-region (point) (point-max))
+		retbuf)
+	    (kill-buffer retbuf)
+	    nil))
+      (kill-buffer retbuf)
+      nil)))
+
+(defun smime-cert-by-ldap (mail)
+  "Find certificate for MAIL."
+  (if smime-ldap-host-list
+      (catch 'certbuf
+	(dolist (host smime-ldap-host-list)
+	  (let ((retbuf (smime-cert-by-ldap-1 mail host)))
+	    (when retbuf 
+	      (throw 'certbuf retbuf)))))))
+  
 ;; User interface.
 
 (defvar smime-buffer "*SMIME*")

[-- Attachment #3: Slightly changed version of ldap-search for Emacs 21 --]
[-- Type: application/emacs-lisp, Size: 7837 bytes --]

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: Get certificate from LDAP for S/MIME encryption (patch)
       [not found]   ` <877jlbrzdq.fsf@seamus.arnested.dk>
@ 2005-02-14 15:37     ` Simon Josefsson
  2005-02-14 19:01       ` Arne Jørgensen
  0 siblings, 1 reply; 13+ messages in thread
From: Simon Josefsson @ 2005-02-14 15:37 UTC (permalink / raw)
  Cc: ding

Arne Jørgensen <arne@arnested.dk> writes:

> Simon Josefsson <jas@extundo.com> writes:
>
> Hi Simon,
>
> I'm sending this to you as e-mail because I have tried to post it to
> gmane.emacs.gnus.general three times now without success. Feel free to
> forward it to the list.

I've cc'ed the mailing list.

FWIW, with this setting:

 '(gnus-mailing-list-groups "gmane\\|gnus.gnus-bug")
 '(message-extra-wide-headers (quote ("Original-To")))

You can read from gmane group, and posting will go via e-mail instead
of via gmane.org.

There are some advantages with this approach: hashcash works, no
connectivity dependency on gmane.org for posting, authors are Cc'ed
properly.

And some disadvantages: you need to be subscribed to subscriber-only
lists.

> Well, CVS Emacs' ldap.el is already written towards OpenLDAP v2 and
> I got the patches to retrieve ";binary" stuff applied about a week
> ago.

Great.

> In stead I have implemented a `smime-ldap-search' that will just call
> `ldap-search' when running in Emacs 22 an above, and use a slightly
> rewritten version of the same function in Emacs 21. See attached file
> and new patch to use it.

Applied.  I modified some things, please verify it still work.

>>> [1] Actually I will probably volunteer to reimplement the user
>>>     interface to the S/MIME stuff. But before coding we should agree
>>>     on how we would like it to be. (And PGP and S/MIME should probably
>>>     share the same interface ideas and I know noting about PGP (yet)).
>>
>> Great.  What is there to agree on?  Is there something wrong with
>> making the MML tag for individual parts work on the "global" security
>> MML tag?
>
> I don't think so. That was part of what I was thinking on.

Thanks for working on this!  I wish I had more time to help.

> Other thoughts are:
>
>  - gnus should try to find the certificate without asking the user.
>    Probably a list of preferred methods ('dns 'ldap 'file 'ask).

Yup.

Btw, I changed the default from dns to ldap.

Is auto-querying from LDAP sources reliable?  Is there any suitable
default-value for `smime-ldap-host-list'?  It should be very safe to
auto-query DNS.

>  - better access to locally cached certificates (this was mentioned in
>    the recent thread on gnu.emacs.gnus also). We could just store the
>    certificates in a dir with the email adress as file name.

Yes.

I wish there was a standard for Unix S/MIME MUAs for this, so Gnus
wouldn't have to invent its own ideas.

>  - maybe wait until the messages is to be sent before we ask which
>    certificates to use. At the moment you will not sign/encrypt to
>    adresse added after you have put ind the mml tags. Dns and
>    ldap stores the certificates in a temporary buffer - what happens
>    if you file the mail as a draft and leave Emacs?

Good point.  The current behavior could probably be considered a bug.

>  - havent verified this recently, but I think gnus will send a message
>    even though openssl fails (ie because of a typo in the password).
>    This should probably be considered a security bug.

Yup.

>  - use password.el to cache passwords as you mentioned on
>    gnu.emacs.gnus.

Yup.

IMHO, there is another major important item:

- Replace use of OpenSSL with gpgsm.

I will try to work on that.  I started some time ago, but never got
gpgsm to sign messages properly.  If we fix this last OpenSSL use in
Gnus, there wouldn't be no need for Gnus users to ever have to install
OpenSSL, which I consider to be a big win.

Thanks,
Simon



^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: Get certificate from LDAP for S/MIME encryption (patch)
  2005-02-14 15:37     ` Simon Josefsson
@ 2005-02-14 19:01       ` Arne Jørgensen
  2005-02-14 22:36         ` Simon Josefsson
  0 siblings, 1 reply; 13+ messages in thread
From: Arne Jørgensen @ 2005-02-14 19:01 UTC (permalink / raw)
  Cc: ding

Simon Josefsson <jas@extundo.com> writes:

> Arne Jørgensen <arne@arnested.dk> writes:
>
>> Simon Josefsson <jas@extundo.com> writes:
>>
>> Hi Simon,
>>
>> I'm sending this to you as e-mail because I have tried to post it to
>> gmane.emacs.gnus.general three times now without success. Feel free to
>> forward it to the list.
>
> I've cc'ed the mailing list.

And not arrived yet either. Maybe the mailing list is out of order.

>> In stead I have implemented a `smime-ldap-search' that will just call
>> `ldap-search' when running in Emacs 22 an above, and use a slightly
>> rewritten version of the same function in Emacs 21. See attached file
>> and new patch to use it.
>
> Applied.  I modified some things, please verify it still work.

All looks fine and still works.

The funny (load-library "net/ldap") was because the eudc package on my
debian had an incompatible ldap.elc installed, but that might be a
debian bug.

>> Other thoughts are:
>>
>>  - gnus should try to find the certificate without asking the user.
>>    Probably a list of preferred methods ('dns 'ldap 'file 'ask).
>
> Yup.
>
> Btw, I changed the default from dns to ldap.

Nice :-)

> Is auto-querying from LDAP sources reliable?  Is there any suitable
> default-value for `smime-ldap-host-list'?  It should be very safe to
> auto-query DNS.

Well the default value, nil, should be fine. Then no certificate is
returned. And if the certificate is not found on the servers it ask
nil is returned too. It should be pretty safe...

>>  - better access to locally cached certificates (this was mentioned in
>>    the recent thread on gnu.emacs.gnus also). We could just store the
>>    certificates in a dir with the email adress as file name.
>
> Yes.
>
> I wish there was a standard for Unix S/MIME MUAs for this, so Gnus
> wouldn't have to invent its own ideas.

Agreed. But I don't think we'll waste much work on just mapping
addresses to file names.

> IMHO, there is another major important item:
>
> - Replace use of OpenSSL with gpgsm.
>
> I will try to work on that.  I started some time ago, but never got
> gpgsm to sign messages properly.  If we fix this last OpenSSL use in
> Gnus, there wouldn't be no need for Gnus users to ever have to install
> OpenSSL, which I consider to be a big win.

I knew ;-)

Unfortunately there is no gpgsm in debian/unstable but replacing
openssl would be really good!

Didn't you work on integrating the gnutls libraries in emacs a long
time ago? Could gnutls do s/mime stuff too?

Another thing I was thinking of was verifying usercertificates
received through dns/ldap/filecache before using them. If we
auto-query them, we shouldn't stop at the first found certificate in
the search path but the first that verifies.

And then I just found a bug when you want to read a mail with an
encrypted attachment.

Kind regards,
-- 
Arne Jørgensen <http://arnested.dk/>



^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: Get certificate from LDAP for S/MIME encryption (patch)
  2005-02-14 19:01       ` Arne Jørgensen
@ 2005-02-14 22:36         ` Simon Josefsson
  2005-02-14 22:50           ` Arne Jørgensen
  2005-02-17 23:27           ` Arne Jørgensen
  0 siblings, 2 replies; 13+ messages in thread
From: Simon Josefsson @ 2005-02-14 22:36 UTC (permalink / raw)
  Cc: ding

Arne Jørgensen <arne@arnested.dk> writes:

>>> In stead I have implemented a `smime-ldap-search' that will just call
>>> `ldap-search' when running in Emacs 22 an above, and use a slightly
>>> rewritten version of the same function in Emacs 21. See attached file
>>> and new patch to use it.
>>
>> Applied.  I modified some things, please verify it still work.
>
> All looks fine and still works.

Great!

> The funny (load-library "net/ldap") was because the eudc package on my
> debian had an incompatible ldap.elc installed, but that might be a
> debian bug.

I think it should be reported as a Debian bug.  If it turns out this
might affect many people, maybe we can analyze the situation further
and come up with something better.

>> Is auto-querying from LDAP sources reliable?  Is there any suitable
>> default-value for `smime-ldap-host-list'?  It should be very safe to
>> auto-query DNS.
>
> Well the default value, nil, should be fine. Then no certificate is
> returned. And if the certificate is not found on the servers it ask
> nil is returned too. It should be pretty safe...

And what if there is a non-nil value in the variable?  Will the code
fall back and return nil on any failures?  I.e., missing openldap,
network timeouts etc.  Or will it throw an error?  The latter should
be avoided, IMHO.

>> IMHO, there is another major important item:
>>
>> - Replace use of OpenSSL with gpgsm.
>>
>> I will try to work on that.  I started some time ago, but never got
>> gpgsm to sign messages properly.  If we fix this last OpenSSL use in
>> Gnus, there wouldn't be no need for Gnus users to ever have to install
>> OpenSSL, which I consider to be a big win.
>
> I knew ;-)
>
> Unfortunately there is no gpgsm in debian/unstable but replacing
> openssl would be really good!

gpgsm appear to be a bit unstable.  It would be nice if someone
packaged it, though.

> Didn't you work on integrating the gnutls libraries in emacs a long
> time ago? Could gnutls do s/mime stuff too?

There is some PKCS#7 stuff in gnutls, so it might be possible to make
that work.  But if gpgsm is supposed to be a free and generic S/MIME
implementation, I think we should try to avoid reinventing it before
we have tried harder to use it.  I'll have another go at it sometime.

> Another thing I was thinking of was verifying usercertificates
> received through dns/ldap/filecache before using them. If we
> auto-query them, we shouldn't stop at the first found certificate in
> the search path but the first that verifies.

User configurable, though.  I would want an approach that, if there
are multiple matching certificates, uses one of that certificates that
verify, if any, but otherwise just pick any of them.

> And then I just found a bug when you want to read a mail with an
> encrypted attachment.

Send a patch. :)

Thanks.



^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: Get certificate from LDAP for S/MIME encryption (patch)
  2005-02-14 22:36         ` Simon Josefsson
@ 2005-02-14 22:50           ` Arne Jørgensen
  2005-02-14 23:02             ` Simon Josefsson
  2005-02-17 23:27           ` Arne Jørgensen
  1 sibling, 1 reply; 13+ messages in thread
From: Arne Jørgensen @ 2005-02-14 22:50 UTC (permalink / raw)
  Cc: ding

Simon Josefsson <jas@extundo.com> writes:

> Arne Jørgensen <arne@arnested.dk> writes:

>> The funny (load-library "net/ldap") was because the eudc package on my
>> debian had an incompatible ldap.elc installed, but that might be a
>> debian bug.
>
> I think it should be reported as a Debian bug.  If it turns out this
> might affect many people, maybe we can analyze the situation further
> and come up with something better.

Already reported
<http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=295285>

>>> Is auto-querying from LDAP sources reliable?  Is there any suitable
>>> default-value for `smime-ldap-host-list'?  It should be very safe to
>>> auto-query DNS.
>>
>> Well the default value, nil, should be fine. Then no certificate is
>> returned. And if the certificate is not found on the servers it ask
>> nil is returned too. It should be pretty safe...
>
> And what if there is a non-nil value in the variable?  Will the code
> fall back and return nil on any failures?  I.e., missing openldap,
> network timeouts etc.  Or will it throw an error?  The latter should
> be avoided, IMHO.

There's room for testing here ;-) I'll have a closer look ..
Wednesday.

>> Didn't you work on integrating the gnutls libraries in emacs a long
>> time ago? Could gnutls do s/mime stuff too?
>
> There is some PKCS#7 stuff in gnutls, so it might be possible to make
> that work.  But if gpgsm is supposed to be a free and generic S/MIME
> implementation, I think we should try to avoid reinventing it before
> we have tried harder to use it.  I'll have another go at it sometime.

You're right. From time to time I just dream about not having to
depend on external programs -- after debugging with different versions
of openldap and an openssl 0.9.7d (FC2) that segfaulted on smime
-encrypt.

>> Another thing I was thinking of was verifying usercertificates
>> received through dns/ldap/filecache before using them. If we
>> auto-query them, we shouldn't stop at the first found certificate in
>> the search path but the first that verifies.
>
> User configurable, though. 

Of course.

> I would want an approach that, if there are multiple matching
> certificates, uses one of that certificates that verify, if any, but
> otherwise just pick any of them.

Yes, or if no verifiable certificates is found ask (configurable)
whether to use a certificate that doesn't verify.

>> And then I just found a bug when you want to read a mail with an
>> encrypted attachment.
>
> Send a patch. :)

Sure. I'll look in to it Wednesday.

Kind regards,
-- 
Arne Jørgensen <http://arnested.dk/>



^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: Get certificate from LDAP for S/MIME encryption (patch)
  2005-02-14 22:50           ` Arne Jørgensen
@ 2005-02-14 23:02             ` Simon Josefsson
  0 siblings, 0 replies; 13+ messages in thread
From: Simon Josefsson @ 2005-02-14 23:02 UTC (permalink / raw)
  Cc: ding

Arne Jørgensen <arne@arnested.dk> writes:

>>> Didn't you work on integrating the gnutls libraries in emacs a long
>>> time ago? Could gnutls do s/mime stuff too?
>>
>> There is some PKCS#7 stuff in gnutls, so it might be possible to make
>> that work.  But if gpgsm is supposed to be a free and generic S/MIME
>> implementation, I think we should try to avoid reinventing it before
>> we have tried harder to use it.  I'll have another go at it sometime.
>
> You're right. From time to time I just dream about not having to
> depend on external programs

Implementing S/MIME in elisp isn't all that difficult, but it will be
a nightmare to maintain and keep interoperable.

Making the Emacs interface to external programs more reliable is
useful instead.  Since I think we have a bit more influence over
gnutls/gpgsm compared to openldap/openssl, it should not be impossible
to make that work smoothly.

Thanks.



^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: Get certificate from LDAP for S/MIME encryption (patch)
  2005-02-14 22:36         ` Simon Josefsson
  2005-02-14 22:50           ` Arne Jørgensen
@ 2005-02-17 23:27           ` Arne Jørgensen
  2005-02-22 16:57             ` Simon Josefsson
  1 sibling, 1 reply; 13+ messages in thread
From: Arne Jørgensen @ 2005-02-17 23:27 UTC (permalink / raw)


Simon Josefsson <jas@extundo.com> writes:

> Arne Jørgensen <arne@arnested.dk> writes:
>
>> Well the default value, nil, should be fine. Then no certificate is
>> returned. And if the certificate is not found on the servers it ask
>> nil is returned too. It should be pretty safe...
>
> And what if there is a non-nil value in the variable?  Will the code
> fall back and return nil on any failures?  I.e., missing openldap,
> network timeouts etc.  Or will it throw an error?  The latter should
> be avoided, IMHO.

I have now testet smime-cert-by-ldap some more.

No matter what the value of smime-ldap-host-list is (nil, unreachable
host, not a host name, a host without ldap, a host with ldap but
without the certificate) it will return a certificate or nil.

The only thing that will make it fail is if there is no ldapsearch
program available (btw so will smime-cert-by-dns if there is no dig).

Maybe this can be solved by using condition-case and installing an
error handler. But I just learn about condition-case a few minutes
ago.

I don't think auto-query of certificates is the first thing on my todo
list for smime anyway, so there is time to think.

Kind regards,
-- 
Arne Jørgensen <http://arnested.dk/>




^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: Get certificate from LDAP for S/MIME encryption (patch)
  2005-02-13 16:10   ` Arne Jørgensen
@ 2005-02-17 23:32     ` Arne Jørgensen
  0 siblings, 0 replies; 13+ messages in thread
From: Arne Jørgensen @ 2005-02-17 23:32 UTC (permalink / raw)


[-- Attachment #1: Type: text/plain, Size: 714 bytes --]

Arne Jørgensen <arne@arnested.dk> writes:

>  - havent verified this recently, but I think gnus will send a message
>    even though openssl fails (ie because of a typo in the password).
>    This should probably be considered a security bug.

It will send a mail unsigned if you make an error typing your
password.

The attach patch will avoid this (and also if encryption fails).

The patch also adds a bit to the doc for `smime-ldap-host-list'.

And since the PEM format is just a base64 of DER there is really no
reason to call openssl to do the conversion so I rewrote
`smime-cert-by-ldap-1' to use `base64-encode-string' instead. Also in
the patch.

Kind regards,
-- 
Arne Jørgensen <http://arnested.dk/>


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: smime.patch --]
[-- Type: text/x-patch, Size: 3546 bytes --]

Index: lisp/smime.el
===================================================================
RCS file: /usr/local/cvsroot/gnus/lisp/smime.el,v
retrieving revision 7.8
diff -u -p -r7.8 smime.el
--- lisp/smime.el	14 Feb 2005 15:24:44 -0000	7.8
+++ lisp/smime.el	17 Feb 2005 23:16:37 -0000
@@ -218,7 +218,9 @@ If nil, use system defaults."
   :group 'smime)
 
 (defcustom smime-ldap-host-list nil
-  "A list of LDAP hosts with S/MIME user certificates."
+  "A list of LDAP hosts with S/MIME user certificates.
+If needed search base, binddn, passwd, etc. for the LDAP host
+must be set in `ldap-host-parameters-alist'."
   :type '(repeat (string :tag "Host name"))
   :group 'smime)
 
@@ -339,16 +341,17 @@ is expected to contain of a PEM encoded 
 KEYFILE should contain a PEM encoded key and certificate."
   (interactive)
   (with-current-buffer (or buffer (current-buffer))
-    (smime-sign-region
-     (point-min) (point-max)
-     (if keyfile
-	 keyfile
-       (smime-get-key-with-certs-by-email
-	(completing-read
-	 (concat "Sign using which key? "
-		 (if smime-keys (concat "(default " (caar smime-keys) ") ")
-		   ""))
-	 smime-keys nil nil (car-safe (car-safe smime-keys))))))))
+    (unless (smime-sign-region
+	     (point-min) (point-max)
+	     (if keyfile
+		 keyfile
+	       (smime-get-key-with-certs-by-email
+		(completing-read
+		 (concat "Sign using which key? "
+			 (if smime-keys (concat "(default " (caar smime-keys) ") ")
+			   ""))
+		 smime-keys nil nil (car-safe (car-safe smime-keys))))))
+      (error "Signing failed"))))
 
 (defun smime-encrypt-buffer (&optional certfiles buffer)
   "S/MIME encrypt BUFFER for recipients specified in CERTFILES.
@@ -357,11 +360,12 @@ a PEM encoded key and certificate.  Uses
 nil."
   (interactive)
   (with-current-buffer (or buffer (current-buffer))
-    (smime-encrypt-region
-     (point-min) (point-max)
-     (or certfiles
-	 (list (read-file-name "Recipient's S/MIME certificate: "
-			       smime-certificate-directory nil))))))
+    (unless (smime-encrypt-region
+	     (point-min) (point-max)
+	     (or certfiles
+		 (list (read-file-name "Recipient's S/MIME certificate: "
+				       smime-certificate-directory nil))))
+      (error "Encryption failed"))))
 
 ;; Verify+decrypt region
 
@@ -567,21 +571,21 @@ A string or a list of strings is returne
   "Get cetificate for MAIL from the ldap server at HOST."
   (let ((ldapresult (smime-ldap-search (concat "mail=" mail)
 				       host '("userCertificate") nil))
-	(retbuf (generate-new-buffer (format "*certificate for %s*" mail))))
+	(retbuf (generate-new-buffer (format "*certificate for %s*" mail)))
+	cert)
     (if (> (length ldapresult) 1)
 	(with-current-buffer retbuf
-	  (set-buffer-multibyte nil)
-	  (insert (nth 1 (car (nth 1 ldapresult))))
-	  (goto-char (point-min))
-	  (if (smime-call-openssl-region (point-min) (point-max) t "x509"
-					 "-inform" "DER" "-outform" "PEM")
-	      (progn
-		(delete-region (point) (point-max))
-		retbuf)
-	    (kill-buffer retbuf)
-	    nil))
+	  (setq cert (base64-encode-string (nth 1 (car (nth 1 ldapresult))) t))
+	  (insert "-----BEGIN CERTIFICATE-----\n")
+	  (let ((i 0) (len (length cert)))
+	    (while (> (- len 64) i)
+	      (insert (substring cert i (+ i 64)) "\n")
+	      (setq i (+ i 64)))
+	    (insert (substring cert i len) "\n"))
+	  (insert "-----END CERTIFICATE-----\n"))
       (kill-buffer retbuf)
-      nil)))
+      (setq retbuf nil))
+    retbuf))
 
 (defun smime-cert-by-ldap (mail)
   "Find certificate via LDAP for address MAIL."

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: Get certificate from LDAP for S/MIME encryption (patch)
  2005-02-17 23:27           ` Arne Jørgensen
@ 2005-02-22 16:57             ` Simon Josefsson
  0 siblings, 0 replies; 13+ messages in thread
From: Simon Josefsson @ 2005-02-22 16:57 UTC (permalink / raw)
  Cc: ding

Arne Jørgensen <arne@arnested.dk> writes:

> The only thing that will make it fail is if there is no ldapsearch
> program available (btw so will smime-cert-by-dns if there is no dig).
>
> Maybe this can be solved by using condition-case and installing an
> error handler. But I just learn about condition-case a few minutes
> ago.

It might be easier to wrap the call-process in a unwind-protect.

> I don't think auto-query of certificates is the first thing on my todo
> list for smime anyway, so there is time to think.

No hurry; it was just a "neat feature".  The idea is in the ding
archives now, if someone wants to pick this up later on.



^ permalink raw reply	[flat|nested] 13+ messages in thread

end of thread, other threads:[~2005-02-22 16:57 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2005-02-12 20:08 Get certificate from LDAP for S/MIME encryption (patch) Arne Jørgensen
2005-02-13  0:22 ` Simon Josefsson
2005-02-13 16:10   ` Arne Jørgensen
2005-02-17 23:32     ` Arne Jørgensen
2005-02-13 20:02   ` Arne Jørgensen
2005-02-14 13:42   ` Arne Jørgensen
     [not found]   ` <877jlbrzdq.fsf@seamus.arnested.dk>
2005-02-14 15:37     ` Simon Josefsson
2005-02-14 19:01       ` Arne Jørgensen
2005-02-14 22:36         ` Simon Josefsson
2005-02-14 22:50           ` Arne Jørgensen
2005-02-14 23:02             ` Simon Josefsson
2005-02-17 23:27           ` Arne Jørgensen
2005-02-22 16:57             ` Simon Josefsson

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).