* Re: gssapi authentication for nnimap
2016-02-09 23:31 ` Lars Ingebrigtsen
@ 2016-02-10 4:16 ` Jochen Hein
2016-02-10 4:23 ` Lars Ingebrigtsen
2016-02-10 4:30 ` Lars Ingebrigtsen
2016-02-10 21:37 ` Jochen Hein
2016-02-11 19:51 ` [PATCH] GSSAPI " Jochen Hein
2 siblings, 2 replies; 22+ messages in thread
From: Jochen Hein @ 2016-02-10 4:16 UTC (permalink / raw)
To: Lars Ingebrigtsen; +Cc: Andreas Schwab, ding, Florian Weimer
Lars Ingebrigtsen <larsi@gnus.org> writes:
>> My current guess is that my gssapi-session is already authenticated,
>> but nnimap-open-connection-1 after "ZZZ" is getting confused somehow.
>>
>> Some more debugging shows, that the next statement fails:
>>
>> (if (not (gnus-string-match-p "[*.] \\(OK\\|PREAUTH\\)" greeting))
>> (nnheader-report 'nnimap "%s" greeting)
>>
>> That is somewhat expected, since my call to open-gssapi-stream doesn't
>> set greeting (and I'm almost sure that later capability will also fail).
>
> open-protocol-stream returns the greetings and the capabilities, but
> open-gssapi-stream doesn't do that. So perhaps there should be a
> wrapper around the latter function that will save the greeting and issue
> the capability command?
That seems to be the way forward, yes. I guess that the wrapper willl
look a lot like open-protocol-stream... I'll have a try in the next few
days.
Jochen
--
The only problem with troubleshooting is that the trouble shoots back.
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: gssapi authentication for nnimap
2016-02-10 4:16 ` Jochen Hein
@ 2016-02-10 4:23 ` Lars Ingebrigtsen
2016-02-10 4:30 ` Lars Ingebrigtsen
1 sibling, 0 replies; 22+ messages in thread
From: Lars Ingebrigtsen @ 2016-02-10 4:23 UTC (permalink / raw)
To: Jochen Hein; +Cc: Andreas Schwab, ding, Florian Weimer
Jochen Hein <jochen@jochen.org> writes:
> That seems to be the way forward, yes. I guess that the wrapper willl
> look a lot like open-protocol-stream... I'll have a try in the next few
> days.
Great!
--
(domestic pets only, the antidote for overdose, milk.)
bloggy blog: http://lars.ingebrigtsen.no
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: gssapi authentication for nnimap
2016-02-10 4:16 ` Jochen Hein
2016-02-10 4:23 ` Lars Ingebrigtsen
@ 2016-02-10 4:30 ` Lars Ingebrigtsen
2016-02-10 4:42 ` Jochen Hein
1 sibling, 1 reply; 22+ messages in thread
From: Lars Ingebrigtsen @ 2016-02-10 4:30 UTC (permalink / raw)
To: Jochen Hein; +Cc: Andreas Schwab, ding, Florian Weimer
Jochen Hein <jochen@jochen.org> writes:
> That seems to be the way forward, yes. I guess that the wrapper willl
> look a lot like open-protocol-stream... I'll have a try in the next few
> days.
An idea just occurred to me... This is the definition of
open-network-stream is this:
(open-network-stream NAME BUFFER HOST SERVICE &rest PARAMETERS)
[...]
:type specifies the connection type, one of the following:
nil or ‘network’
-- Begin with an ordinary network connection, and if
the parameters :success and :capability-command
are also supplied, try to upgrade to an encrypted
connection via STARTTLS. Even if that
fails (e.g. if HOST does not support TLS), retain
an unencrypted connection.
‘plain’ -- An ordinary, unencrypted network connection.
‘starttls’ -- Begin with an ordinary connection, and try
upgrading via STARTTLS. If that fails for any
reason, drop the connection; in that case the
returned object is a killed process.
‘tls’ -- A TLS connection.
‘ssl’ -- Equivalent to ‘tls’.
‘shell’ -- A shell connection.
We could extend this to `function', and that function would then deliver
the socket top `open-network-stream'. It'd be exactly like `shell', but
instead of calling the shell, we'd call the function.
The function in this case would be a slight variation over
open-gssapi-stream.
Or rather, it would kinda look like this:
(open-network-stream NAME BUFFER HOST SERVICE
... :type 'function
:connection-function (lambda (name buffer host service parameters)
(open-gssapi-stream name buffer server port nnimap-user)))
Wouldn't that do the trick with the minimal amount of hacking? If so, I
can add the :type 'function to open-network-stream on the Emacs trunk...
--
(domestic pets only, the antidote for overdose, milk.)
bloggy blog: http://lars.ingebrigtsen.no
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: gssapi authentication for nnimap
2016-02-10 4:30 ` Lars Ingebrigtsen
@ 2016-02-10 4:42 ` Jochen Hein
2016-02-10 4:50 ` Lars Ingebrigtsen
0 siblings, 1 reply; 22+ messages in thread
From: Jochen Hein @ 2016-02-10 4:42 UTC (permalink / raw)
To: Lars Ingebrigtsen; +Cc: Andreas Schwab, ding, Florian Weimer
Lars Ingebrigtsen <larsi@gnus.org> writes:
> Jochen Hein <jochen@jochen.org> writes:
>
>> That seems to be the way forward, yes. I guess that the wrapper willl
>> look a lot like open-protocol-stream... I'll have a try in the next few
>> days.
>
> An idea just occurred to me...
...
> We could extend this to `function', and that function would then deliver
> the socket top `open-network-stream'. It'd be exactly like `shell', but
> instead of calling the shell, we'd call the function.
>
> The function in this case would be a slight variation over
> open-gssapi-stream.
>
> Or rather, it would kinda look like this:
>
> (open-network-stream NAME BUFFER HOST SERVICE
> ... :type 'function
> :connection-function (lambda (name buffer host service parameters)
> (open-gssapi-stream name buffer server port nnimap-user)))
>
> Wouldn't that do the trick with the minimal amount of hacking? If so, I
> can add the :type 'function to open-network-stream on the Emacs trunk...
I'm not sure. Right now open-gssapi-stream kills the greeting with
erase-buffer. We need to scrapt greeting first, if needed. Or
something like that. I think I'll have to explore some different paths
to see what might be the best way forward.
Jochen
--
The only problem with troubleshooting is that the trouble shoots back.
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: gssapi authentication for nnimap
2016-02-10 4:42 ` Jochen Hein
@ 2016-02-10 4:50 ` Lars Ingebrigtsen
0 siblings, 0 replies; 22+ messages in thread
From: Lars Ingebrigtsen @ 2016-02-10 4:50 UTC (permalink / raw)
To: Jochen Hein; +Cc: Andreas Schwab, ding, Florian Weimer
Jochen Hein <jochen@jochen.org> writes:
> I'm not sure. Right now open-gssapi-stream kills the greeting with
> erase-buffer. We need to scrapt greeting first, if needed. Or
> something like that.
Oh, OK. But... it doesn't have to do that. :-)
> I think I'll have to explore some different paths
> to see what might be the best way forward.
Okidoke.
--
(domestic pets only, the antidote for overdose, milk.)
bloggy blog: http://lars.ingebrigtsen.no
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: gssapi authentication for nnimap
2016-02-09 23:31 ` Lars Ingebrigtsen
2016-02-10 4:16 ` Jochen Hein
@ 2016-02-10 21:37 ` Jochen Hein
2016-02-11 19:51 ` [PATCH] GSSAPI " Jochen Hein
2 siblings, 0 replies; 22+ messages in thread
From: Jochen Hein @ 2016-02-10 21:37 UTC (permalink / raw)
To: Lars Ingebrigtsen; +Cc: Andreas Schwab, ding, Florian Weimer
Lars Ingebrigtsen <larsi@gnus.org> writes:
> No, open-protocol-stream shouldn't know anything about nnimap.
Maybe, I'm not sure. First, I've been confused, because my changes to
lisp/proto-stream.el didn't have an effect - I still got the message
"Invalid connection type". Gnus uses the function as defined in
network-stream.el from Emacs24. The file proto-stream.el should be
deleted while removing compat stuff :-)
Iff we want to add connection type 'gssapi to open-network-stream we
need to handle the username somehow. gssapi.el execpts to get the
username, but gsasl and imtest work without the name:
$ imtest -m gssapi -p imap imap.jochen.org
...
Authenticated.
...
Feb 10 22:08:06 jupiter imap[6255]: login: [...] jochen@jochen.org GSSAPI User logged in
For my usage that would work - I have no idea if we really need to
handle different usernames on the Gnus host and the IMAP host when using
GSSAPI. We may want to decide that this case will be handled when a
user requests it :-)
So one way forward might be to change the commands in gssapi.el
(untested, I didn't make any changes to open-network-stream yet):
--- gssapi.el.orig 2016-02-10 22:11:24.000000000 +0100
+++ gssapi.el 2016-02-10 22:13:28.000000000 +0100
@@ -29,19 +29,18 @@
(defcustom gssapi-program (list
(concat "gsasl %s %p "
- "--mechanism GSSAPI "
- "--authentication-id %l")
- "imtest -m gssapi -u %l -p %p %s")
+ "--mechanism GSSAPI ")
+ "imtest -m gssapi -p %p %s")
"List of strings containing commands for GSSAPI (krb5) authentication.
-%s is replaced with server hostname, %p with port to connect to,
-and %l with the user name. The program should accept commands on
+%s is replaced with server hostname and %p with port to connect to.
+The program should accept commands on
stdin and return responses to stdout. Each entry in the list is
tried until a successful connection is made."
:version "24.1"
:group 'network
:type '(repeat string))
-(defun open-gssapi-stream (name buffer server port user)
+(defun open-gssapi-stream (name buffer server port)
(let ((cmds gssapi-program)
cmd done)
(with-current-buffer buffer
@@ -57,8 +56,7 @@
cmd
(format-spec-make
?s server
- ?p (number-to-string port)
- ?l user))))
+ ?p (number-to-string port)))))
response)
(when process
(while (and (memq (process-status process) '(open run))
The other option I see is to add an additional parameter to
open-network-stream for usage with type 'gssapi, something like the
following (patch will not work - must patch network-stream.el from emacs):
diff --git a/lisp/proto-stream.el b/lisp/proto-stream.el
index 11ffd0c..a059b0b 100644
--- a/lisp/proto-stream.el
+++ b/lisp/proto-stream.el
@@ -50,6 +50,7 @@
(require 'tls)
(require 'starttls)
+(require 'gssapi)
(autoload 'gnutls-negotiate "gnutls")
(autoload 'open-gnutls-stream "gnutls")
@@ -80,6 +81,9 @@ PARAMETERS should be a sequence of keywords and values:
`tls' -- A TLS connection.
`ssl' -- Equivalent to `tls'.
`shell' -- A shell connection.
+ `gssapi' -- a GSSAPI connection.
+
+:gssapi-user specifies the username for GSSAPI authentication.
:return-list specifies this function's return value.
If omitted or nil, return a process object. A non-nil means to
@@ -129,9 +137,12 @@ PARAMETERS should be a sequence of keywords and values:
'proto-stream-open-starttls)
((memq type '(tls ssl)) 'proto-stream-open-tls)
((eq type 'shell) 'proto-stream-open-shell)
- (t (error "Invalid connection type %s" type))))
+ ((eq type "gssapi") 'proto-stream-open-gssapi)
+ (t (error "Invalid x connection type %s" type))))
(result (funcall connection-function
name buffer host service parameters)))
(if return-list
(list (car result)
:greeting (nth 1 result)
@@ -148,6 +159,26 @@ PARAMETERS should be a sequence of keywords and values:
nil
'plain)))
+(defun proto-stream-open-gssapi (name buffer host service parameters)
+ (let* ((start (with-current-buffer buffer (point)))
+ (gssapi-user (plist-get parameters :gssapi-user))
+ (capability-command (plist-get parameters :capability-command))
+ (eoc (plist-get parameters :end-of-command))
+ (eo-capa (or (plist-get parameters :end-of-capability)
+ eoc))
+ (stream (open-gssapi-stream name buffer host service gssapi-user)))
+ (greeting (proto-stream-get-response stream start eoc))
+ (capabilities (when capability-command
+ (proto-stream-command stream
+ capability-command
+ (or eo-capa eoc))))
+ (list stream
+ (proto-stream-get-response stream start
+ (plist-get parameters :end-of-command))
+ greeting
+ capabitilies
+ 'gssapi)))
+
(defun proto-stream-open-starttls (name buffer host service parameters)
(let* ((start (with-current-buffer buffer (point)))
(require-tls (eq (plist-get parameters :type) 'starttls))
>
>> + (let* ((stream-list
>> + (if (eq nnimap-stream 'gssapi)
>> + (list (open-gssapi-stream
>> + "*nnimap*" (current-buffer) nnimap-address
>> + (nnimap-map-port (car ports)) nnimap-user))
>
> That looks OK...
Here's my minimal and working diff (with fake greeting/capabilities),
the commented hunk was a try to fake gssapi with connection-type 'shell.
The fake was successful for a GSSAPI user, but I failed to run the same
code for a normal mailbox - I guess my lisp skill needs some help...:
diff --git a/lisp/gssapi.el b/lisp/gssapi.el
index 1f72805..ae4fefa 100644
--- a/lisp/gssapi.el
+++ b/lisp/gssapi.el
@@ -92,7 +92,7 @@ tried until a successful connection is made."
(setq response (match-string 1)))))
(accept-process-output process 1)
(sit-for 1))
- (erase-buffer)
+ ;(erase-buffer)
(message "GSSAPI connection: %s" (or response "failed"))
(if (and response (let ((case-fold-search nil))
(not (string-match "failed" response))))
diff --git a/lisp/nnimap.el b/lisp/nnimap.el
index 05251ed..facb36c 100644
--- a/lisp/nnimap.el
+++ b/lisp/nnimap.el
@@ -65,7 +65,7 @@ it will default to `imap'.")
(defvoo nnimap-stream 'undecided
"How nnimap talks to the IMAP server.
The value should be either `undecided', `ssl' or `tls',
-`network', `starttls', `plain', or `shell'.
+`network', `starttls', `plain', `gssapi', or `shell'.
If the value is `undecided', nnimap tries `ssl' first, then falls
back on `network'.")
@@ -408,6 +408,10 @@ textual parts.")
(nnheader-message 7 "Opening connection to %s via shell..."
nnimap-address)
'("imap"))
+ ((eq nnimap-stream 'gssapi)
+ (nnheader-message 7 "Opening connection to %s via GSSAPI..."
+ nnimap-address)
+ '(143))
((memq nnimap-stream '(ssl tls))
(nnheader-message 7 "Opening connection to %s via tls..."
nnimap-address)
@@ -417,7 +421,19 @@ textual parts.")
login-result credentials)
(when nnimap-server-port
(push nnimap-server-port ports))
+
+; (setq nnimap-auth (eq nnimap-stream 'gssapi))
+; (if (eq nnimap-stream 'gssapi)
+; (let ((nnimap-stream 'shell)
+; (nnimap-auth 'gssapi)
+; (nnimap-shell-command "gsasl %s %p --mechanism=GSSAPI --authentication-id=%l"))))
+
(let* ((stream-list
+ (if (eq nnimap-stream 'gssapi)
+ (list (open-gssapi-stream "*nnimap*" (current-buffer) nnimap-address
+ (nnimap-map-port (car ports)) nnimap-user)
+ :greeting "* OK [CAPABILITY IMAP4rev1 LITERAL+ ID ENABLE STARTTLS LOGINDISABLED AUTH=GSSAPI SASL-IR] jupiter.jochen.org Cyrus IMAP git2.5+0-ebian-2.5~dev2015021301-0~kolab2 server ready"
+ :capabilities ". OK [CAPABILITY IMAP4rev1 LITERAL+ ID ENABLE ACL RIGHTS=kxten QUOTA MAILBOX-REFERRALS NAMESPACE UIDPLUS NO_ATOMIC_RENAME UNSELECT CHILDREN MULTIAPPEND BINARY CATENATE CONDSTORE ESEARCH SORT SORT=MODSEQ SORT=DISPLAY SORT=UID THREAD=ORDEREDSUBJECT THREAD=REFERENCES ANNOTATEMORE ANNOTATE-EXPERIMENT-1 METADATA LIST-EXTENDED LIST-STATUS LIST-MYRIGHTS WITHIN QRESYNC SCAN XLIST XMOVE MOVE SPECIAL-USE CREATE-SPECIAL-USE URLAUTH URLAUTH=BINARY LOGINDISABLED COMPRESS=DEFLATE X-QUOTA=STORAGE X-QUOTA=MESSAGE X-QUOTA=X-ANNOTATION-STORAGE X-QUOTA=X-NUM-FOLDERS IDLE] Success (tls protection) SESSIONID=<jupiter.jochen.org-13079-1455130571-1-11713551379411196108>")
(open-protocol-stream
"*nnimap*" (current-buffer) nnimap-address
(nnimap-map-port (car ports))
@@ -433,6 +449,7 @@ textual parts.")
(lambda (capabilities)
(when (gnus-string-match-p "STARTTLS" capabilities)
"1 STARTTLS\r\n"))))
+ )
(stream (car stream-list))
(props (cdr stream-list))
(greeting (plist-get props :greeting))
@@ -463,7 +480,9 @@ textual parts.")
(setf (nnimap-capabilities nnimap-object)
(mapcar #'upcase
(split-string capabilities)))
- (unless (gnus-string-match-p "[*.] PREAUTH" greeting)
+ (unless (or
+ (eq nnimap-stream 'gssapi)
+ (gnus-string-match-p "[*.] PREAUTH" greeting))
(if (not (setq credentials
(if (eq nnimap-authenticator 'anonymous)
(list "anonymous"
> open-protocol-stream returns the greetings and the capabilities, but
> open-gssapi-stream doesn't do that. So perhaps there should be a
> wrapper around the latter function that will save the greeting and issue
> the capability command?
Something like that. First open-gssapi-stream must not call
erase-buffer, see the patch above. Now I'm confused how I can transfer
to code from open-network-stream in my code.
Still unsure how to proceed, but quite happy with my success :-)
Hopefully nobody gets confused by my trial and error hacking...
Jochen
--
The only problem with troubleshooting is that the trouble shoots back.
^ permalink raw reply [flat|nested] 22+ messages in thread
* [PATCH] GSSAPI authentication for nnimap
2016-02-09 23:31 ` Lars Ingebrigtsen
2016-02-10 4:16 ` Jochen Hein
2016-02-10 21:37 ` Jochen Hein
@ 2016-02-11 19:51 ` Jochen Hein
2016-02-13 6:50 ` Lars Ingebrigtsen
2 siblings, 1 reply; 22+ messages in thread
From: Jochen Hein @ 2016-02-11 19:51 UTC (permalink / raw)
To: Lars Ingebrigtsen; +Cc: Andreas Schwab, ding, Florian Weimer
The following patches add GSSAPI support to nnimap. I'll comment what I
did and why above each patch. I'm currently cloning the emacs
repository and I hope to forward port the patches and add/adapt the
documentation accordingly. This post is to gather feedback concerning
the design and the lisp code. Do we need ChangeLog patches as well to
apply the patches to current emacs? Right now I've not worked on
updates to the gnus manual.
The first patch is against gssapi.el from Ma Gnus v0.15, the latest gnus
release. I've removed the options "--authentication-id" from gsasl and
"-u" from imtest invocations. If somebody needs these, we could add the
user parameter back to open-gssapi-stream as an optional parameter.
That way open-network-stream could still call open-gssapi-stream without
changes, other users can pass a username. I'm not sure if the username
is really neded - my usecase works fine without.
If we don't want to add an optional parameter or need to pass the
username from nnimap.el to network-stream.el and finally to gssapi.el,
we could add a property like :gssapi-user to the call to
open-network-stream and pass that to open-gssapi-stream.
The second change is removing the call to erase buffer. That way the
function open-network-stream-gssapi in network-stream.el can fetch the
greeting and capabilities string from the buffer.
I currently know of one difference between gsasl and imtest: connections
with gsasl use TLS, imtest doesn't. If we want that, we can add '-t ""'
to the imtest call according to the imtest manpage:
-t keyfile
Enable TLS. keyfile contains the TLS public and
private keys. Specify "" to negotiate a TLS
encryption layer but not use TLS authentication.
Another option could be to handle STARTTLS in
network-stream-open-gssapi. For my usecase I'll use gsasl, so I've not
added code for that.
Caveat: gsasl in Debian Jessie doesn't handle GSSAPI, so you need to
compile it yourself and make sure gssapi/krb5 is enabled:
https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=768352
https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=776847
Both gsasl and imtest give no useful error message when the user doesn't
have a ticket or it is expired. I've also not tried to handle that case
in my patches. This may need further work.
diff --git a/lisp/gssapi.el b/lisp/gssapi.el
index 1f72805..08b2ec3 100644
--- a/lisp/gssapi.el
+++ b/lisp/gssapi.el
@@ -29,9 +29,8 @@
(defcustom gssapi-program (list
(concat "gsasl %s %p "
- "--mechanism GSSAPI "
- "--authentication-id %l")
- "imtest -m gssapi -u %l -p %p %s")
+ "--mechanism GSSAPI ")
+ "imtest -m gssapi -p %p %s")
"List of strings containing commands for GSSAPI (krb5) authentication.
%s is replaced with server hostname, %p with port to connect to,
and %l with the user name. The program should accept commands on
@@ -41,7 +40,7 @@ tried until a successful connection is made."
:group 'network
:type '(repeat string))
-(defun open-gssapi-stream (name buffer server port user)
+(defun open-gssapi-stream (name buffer server port)
(let ((cmds gssapi-program)
cmd done)
(with-current-buffer buffer
@@ -57,8 +56,7 @@ tried until a successful connection is made."
cmd
(format-spec-make
?s server
- ?p (number-to-string port)
- ?l user))))
+ ?p (number-to-string port)))))
response)
(when process
(while (and (memq (process-status process) '(open run))
@@ -92,7 +90,6 @@ tried until a successful connection is made."
(setq response (match-string 1)))))
(accept-process-output process 1)
(sit-for 1))
- (erase-buffer)
(message "GSSAPI connection: %s" (or response "failed"))
(if (and response (let ((case-fold-search nil))
(not (string-match "failed" response))))
The next patch is against network-stream.el from Emacs 24.4.1.
The first part adds 'gssapi as a valid stream type and calls
network-stream-open-gssapi. The second part simply defines that
function, based on the other open-functions in network-stream.el. No
special handling, no STARTTLS. I've not checked the value of
capabilities that is returned, but further procession in nnimap.el
worked fine.
Most likely this patch needs forward porting to current emacs.
--- network-stream.el.orig 2016-02-11 17:26:06.000000000 +0100
+++ network-stream.el 2016-02-11 18:31:02.000000000 +0100
@@ -44,6 +44,7 @@
(require 'tls)
(require 'starttls)
+(require 'gssapi)
(require 'auth-source)
(autoload 'gnutls-negotiate "gnutls")
@@ -85,6 +86,7 @@
`tls' -- A TLS connection.
`ssl' -- Equivalent to `tls'.
`shell' -- A shell connection.
+ `gssapi' -- a GSSAPI connection.
:return-list specifies this function's return value.
If omitted or nil, return a process object. A non-nil means to
@@ -156,6 +158,7 @@
'network-stream-open-starttls)
((memq type '(tls ssl)) 'network-stream-open-tls)
((eq type 'shell) 'network-stream-open-shell)
+ ((eq type 'gssapi) 'network-stream-open-gssapi)
(t (error "Invalid connection type %s" type))))
result)
(unwind-protect
@@ -172,6 +175,24 @@
:error (nth 4 result))
(car result))))))
+(defun network-stream-open-gssapi (name buffer host service parameters)
+ (let* ((start (with-current-buffer buffer (point)))
+ (capability-command (plist-get parameters :capability-command))
+ (eoc (plist-get parameters :end-of-command))
+ (eo-capa (or (plist-get parameters :end-of-capability)
+ eoc))
+ (stream (open-gssapi-stream name buffer host service))
+ (greeting (network-stream-get-response stream start eoc))
+ (capabilities (when capability-command
+ (network-stream-command stream
+ capability-command
+ (or eo-capa eoc)))))
+ ;; Return (STREAM GREETING CAPABILITIES RESULTING-TYPE)
+ (list stream
+ greeting
+ capabilities
+ 'gssapi)))
+
(defun network-stream-certificate (host service parameters)
(let ((spec (plist-get :client-certificate parameters)))
(cond
And finally we use the facilities in nnimap.el. The patch again is
against Ma Gnus v0.15. We add 'gssapi as a valid stream type, provide a
message when using GSSAPI similar to other stream types.
All the heavy lifting is done in network-stream.el, so only one small
change is needed: When using GSSAPI the connection is already
authenticated, so we don't need to provide any credentials.
diff --git a/lisp/nnimap.el b/lisp/nnimap.el
index 05251ed..2eca2b4 100644
--- a/lisp/nnimap.el
+++ b/lisp/nnimap.el
@@ -65,7 +65,7 @@ it will default to `imap'.")
(defvoo nnimap-stream 'undecided
"How nnimap talks to the IMAP server.
The value should be either `undecided', `ssl' or `tls',
-`network', `starttls', `plain', or `shell'.
+`network', `starttls', `plain', `gssapi', or `shell'.
If the value is `undecided', nnimap tries `ssl' first, then falls
back on `network'.")
@@ -408,6 +408,10 @@ textual parts.")
(nnheader-message 7 "Opening connection to %s via shell..."
nnimap-address)
'("imap"))
+ ((eq nnimap-stream 'gssapi)
+ (nnheader-message 7 "Opening connection to %s via GSSAPI..."
+ nnimap-address)
+ '(143))
((memq nnimap-stream '(ssl tls))
(nnheader-message 7 "Opening connection to %s via tls..."
nnimap-address)
@@ -463,7 +467,9 @@ textual parts.")
(setf (nnimap-capabilities nnimap-object)
(mapcar #'upcase
(split-string capabilities)))
- (unless (gnus-string-match-p "[*.] PREAUTH" greeting)
+ (unless (or
+ (eq nnimap-stream 'gssapi)
+ (gnus-string-match-p "[*.] PREAUTH" greeting))
(if (not (setq credentials
(if (eq nnimap-authenticator 'anonymous)
(list "anonymous"
Any comments?
Jochen
--
The only problem with troubleshooting is that the trouble shoots back.
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH] GSSAPI authentication for nnimap
2016-02-11 19:51 ` [PATCH] GSSAPI " Jochen Hein
@ 2016-02-13 6:50 ` Lars Ingebrigtsen
2016-02-13 10:30 ` Jochen Hein
0 siblings, 1 reply; 22+ messages in thread
From: Lars Ingebrigtsen @ 2016-02-13 6:50 UTC (permalink / raw)
To: Jochen Hein; +Cc: Andreas Schwab, ding, Florian Weimer
Jochen Hein <jochen@jochen.org> writes:
> The following patches add GSSAPI support to nnimap. I'll comment what I
> did and why above each patch. I'm currently cloning the emacs
> repository and I hope to forward port the patches and add/adapt the
> documentation accordingly.
Great!
> This post is to gather feedback concerning the design and the lisp
> code. Do we need ChangeLog patches as well to apply the patches to
> current emacs? Right now I've not worked on updates to the gnus
> manual.
We don't need ChangeLog patches any more, but we generate
"ChangeLog-style" git commits instead. Basically, just use `C-x 4 a',
and type in the change as usual, and then when checking in, vc-mode will
snarf those entries into the commit buffer.
> The first patch is against gssapi.el from Ma Gnus v0.15, the latest gnus
> release. I've removed the options "--authentication-id" from gsasl and
> "-u" from imtest invocations. If somebody needs these, we could add the
> user parameter back to open-gssapi-stream as an optional parameter.
> That way open-network-stream could still call open-gssapi-stream without
> changes, other users can pass a username. I'm not sure if the username
> is really neded - my usecase works fine without.
There's no user name in the default gssapi-program, at least...
> If we don't want to add an optional parameter or need to pass the
> username from nnimap.el to network-stream.el and finally to gssapi.el,
> we could add a property like :gssapi-user to the call to
> open-network-stream and pass that to open-gssapi-stream.
It would be nice if we didn't, but that's a possibility.
> The second change is removing the call to erase buffer. That way the
> function open-network-stream-gssapi in network-stream.el can fetch the
> greeting and capabilities string from the buffer.
>
> I currently know of one difference between gsasl and imtest: connections
> with gsasl use TLS, imtest doesn't. If we want that, we can add '-t ""'
> to the imtest call according to the imtest manpage:
>
> -t keyfile
> Enable TLS. keyfile contains the TLS public and
> private keys. Specify "" to negotiate a TLS
> encryption layer but not use TLS authentication.
>
> Another option could be to handle STARTTLS in
> network-stream-open-gssapi. For my usecase I'll use gsasl, so I've not
> added code for that.
Hm... it would have been nice if this all went through our normal TLS
functions, so that the user could be given the opportunity to use the
network security manager in Emacs, which handles certificate errors and
the like. So I think it would be very nice if
network-stream-open-gssapi handled TLS itself.
> Any comments?
I think everything looked very nice. :-)
--
(domestic pets only, the antidote for overdose, milk.)
bloggy blog: http://lars.ingebrigtsen.no
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH] GSSAPI authentication for nnimap
2016-02-13 6:50 ` Lars Ingebrigtsen
@ 2016-02-13 10:30 ` Jochen Hein
2016-02-14 2:25 ` Lars Ingebrigtsen
0 siblings, 1 reply; 22+ messages in thread
From: Jochen Hein @ 2016-02-13 10:30 UTC (permalink / raw)
To: Lars Ingebrigtsen; +Cc: Andreas Schwab, ding, Florian Weimer
Lars Ingebrigtsen <larsi@gnus.org> writes:
> Jochen Hein <jochen@jochen.org> writes:
>
>> The following patches add GSSAPI support to nnimap. I'll comment what I
>> did and why above each patch. I'm currently cloning the emacs
>> repository and I hope to forward port the patches and add/adapt the
>> documentation accordingly.
>
> Great!
Except that nnimap didn't work for me at all - I'll have a look, but
might want to wait after the cleanup frenzy is over :-) I've also seem
some fixes already...
While you're at it - it might be a good idea to move starttls.el and
gssapi.el from lisp/gnus to lisp/net. Both are used by
network-stream.el. tls.el is already there.
There's also net/imap.el - which also claims to handle GSSAPI. I have
no idea if that's in use anywhere.
>> I currently know of one difference between gsasl and imtest: connections
>> with gsasl use TLS, imtest doesn't. If we want that, we can add '-t ""'
>> to the imtest call according to the imtest manpage:
>>
>> -t keyfile
>> Enable TLS. keyfile contains the TLS public and
>> private keys. Specify "" to negotiate a TLS
>> encryption layer but not use TLS authentication.
>>
>> Another option could be to handle STARTTLS in
>> network-stream-open-gssapi. For my usecase I'll use gsasl, so I've not
>> added code for that.
>
> Hm... it would have been nice if this all went through our normal TLS
> functions, so that the user could be given the opportunity to use the
> network security manager in Emacs, which handles certificate errors and
> the like. So I think it would be very nice if
> network-stream-open-gssapi handled TLS itself.
That might not work with the current approach:
$ imtest -m gssapi -p imap imap
...
. STARTTLS
. BAD Can't Starttls after authentication
On the other hand I expect that someone doing Single-Sign-On with his
mail server will also have the right SSL-certificates in place. For
example, both my server and client have been added to a FreeIPA domain.
So I currently contemplate to add '-t ""' to the imtest command in
gssapi.el, because it matches my use case and we'd use STARTTLS in both
commands. I think we've reached a time where TLS should be enabled by
default.
In list/net I've found sasl*.el - that doesn't do GSSAPI at all, but it
could possibly be implemented there. But I expect that this is beyond
my minimal elisp skill, so that's something to explore much later.
Jochen
--
The only problem with troubleshooting is that the trouble shoots back.
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH] GSSAPI authentication for nnimap
2016-02-13 10:30 ` Jochen Hein
@ 2016-02-14 2:25 ` Lars Ingebrigtsen
0 siblings, 0 replies; 22+ messages in thread
From: Lars Ingebrigtsen @ 2016-02-14 2:25 UTC (permalink / raw)
To: Jochen Hein; +Cc: ding
Jochen Hein <jochen@jochen.org> writes:
> Except that nnimap didn't work for me at all - I'll have a look, but
> might want to wait after the cleanup frenzy is over :-) I've also seem
> some fixes already...
The patch that made nnimap not work at all has been reverted, so things
should be back to normal..
> While you're at it - it might be a good idea to move starttls.el and
> gssapi.el from lisp/gnus to lisp/net. Both are used by
> network-stream.el. tls.el is already there.
Sure.
> On the other hand I expect that someone doing Single-Sign-On with his
> mail server will also have the right SSL-certificates in place. For
> example, both my server and client have been added to a FreeIPA domain.
> So I currently contemplate to add '-t ""' to the imtest command in
> gssapi.el, because it matches my use case and we'd use STARTTLS in both
> commands.
Yeah, that makes sense.
--
(domestic pets only, the antidote for overdose, milk.)
bloggy blog: http://lars.ingebrigtsen.no
^ permalink raw reply [flat|nested] 22+ messages in thread