aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLars Ingebrigtsen2018-06-24 15:36:50 +0200
committerLars Ingebrigtsen2018-06-24 15:37:00 +0200
commit6584bc6720fce6a830ab18538f89acc80da597f1 (patch)
treef4b3c9d48fd6c8b9a36b1634e28c04e411089000
parent16c2f03c15078c4bd98c4b1e4d15701ba45550c3 (diff)
downloademacs-6584bc6720fce6a830ab18538f89acc80da597f1.tar.gz
emacs-6584bc6720fce6a830ab18538f89acc80da597f1.zip
Refactor the protocol NSM checks for flexibility
* doc/emacs/misc.texi (Network Security): Mention network-security-protocol-checks. * lisp/net/nsm.el (network-security-protocol-checks): New variable. (nsm-check-protocol): Refactor the checks into separate functions for greater flexibility. (nsm-protocol-check--diffie-hellman-prime-bits) (nsm-protocol-check--rc4, nsm-protocol-check--ssl) (nsm-protocol-check--signature-sha1): Refactored out of the big function.
-rw-r--r--doc/emacs/misc.texi16
-rw-r--r--etc/NEWS5
-rw-r--r--lisp/net/nsm.el133
3 files changed, 98 insertions, 56 deletions
diff --git a/doc/emacs/misc.texi b/doc/emacs/misc.texi
index 24586eb2813..177cc8fa469 100644
--- a/doc/emacs/misc.texi
+++ b/doc/emacs/misc.texi
@@ -402,6 +402,22 @@ This means that one can't casually read the settings file to see what
402servers the user has connected to. If this variable is @code{t}, 402servers the user has connected to. If this variable is @code{t},
403@acronym{NSM} will also save host names in the 403@acronym{NSM} will also save host names in the
404@code{nsm-settings-file}. 404@code{nsm-settings-file}.
405
406@item network-security-protocol-checks
407@vindex network-security-protocol-checks
408The protocol network checks (mostly for @acronym{TLS} weaknesses) is
409controlled via the @code{network-security-protocol-checks} variable.
410
411It's an alist where the first element is the name of the check,
412the second is the security level where the check kicks in, and the
413optional third element is a parameter supplied to the check.
414
415An element like @code{(rc4 medium)} will result in the function
416@code{nsm-protocol-check--rc4} being called like thus:
417@code{(nsm-protocol-check--rc4 host port status optional-parameter)}.
418The function should return non-@code{nil} if the connection should
419proceed and @code{nil} otherwise.
420
405@end table 421@end table
406 422
407 423
diff --git a/etc/NEWS b/etc/NEWS
index 12757f61d20..8ee4831b6ed 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -131,6 +131,11 @@ used to remove comments before calling the libxml functions to parse
131the data. 131the data.
132 132
133+++ 133+++
134** The Network Security Manager now allows more fine-grained control
135of what checks to run via the `network-security-protocol-checks'
136variable.
137
138+++
134** New function 'fill-polish-nobreak-p', to be used in 'fill-nobreak-predicate'. 139** New function 'fill-polish-nobreak-p', to be used in 'fill-nobreak-predicate'.
135It blocks line breaking after a one-letter word, also in the case when 140It blocks line breaking after a one-letter word, also in the case when
136this word is preceded by a non-space, but non-alphanumeric character. 141this word is preceded by a non-space, but non-alphanumeric character.
diff --git a/lisp/net/nsm.el b/lisp/net/nsm.el
index d6fe967fc70..8f09e8dfa91 100644
--- a/lisp/net/nsm.el
+++ b/lisp/net/nsm.el
@@ -26,6 +26,7 @@
26 26
27(require 'cl-lib) 27(require 'cl-lib)
28(require 'rmc) ; read-multiple-choice 28(require 'rmc) ; read-multiple-choice
29(require 'subr-x)
29 30
30(defvar nsm-permanent-host-settings nil) 31(defvar nsm-permanent-host-settings nil)
31(defvar nsm-temporary-host-settings nil) 32(defvar nsm-temporary-host-settings nil)
@@ -118,12 +119,10 @@ unencrypted."
118 process)))))) 119 process))))))
119 120
120(defun nsm-check-tls-connection (process host port status settings) 121(defun nsm-check-tls-connection (process host port status settings)
121 (let ((process (nsm-check-certificate process host port status settings))) 122 (when-let ((process
122 (if (and process 123 (nsm-check-certificate process host port status settings)))
123 (>= (nsm-level network-security-level) (nsm-level 'high))) 124 ;; Do further protocol-level checks.
124 ;; Do further protocol-level checks if the security is high. 125 (nsm-check-protocol process host port status settings)))
125 (nsm-check-protocol process host port status settings)
126 process)))
127 126
128(declare-function gnutls-peer-status-warning-describe "gnutls.c" 127(declare-function gnutls-peer-status-warning-describe "gnutls.c"
129 (status-symbol)) 128 (status-symbol))
@@ -182,57 +181,79 @@ unencrypted."
182 nil) 181 nil)
183 process)))))) 182 process))))))
184 183
184(defvar network-security-protocol-checks
185 '((diffie-hellman-prime-bits high 1024)
186 (rc4 high)
187 (signature-sha1 high)
188 (ssl high))
189 "This variable specifies what TLS connection checks to perform.
190It's an alist where the first element is the name of the check,
191the second is the security level where the check kicks in, and the
192optional third element is a parameter supplied to the check.
193
194An element like `(rc4 medium)' will result in the function
195`nsm-protocol-check--rc4' being called with the parameters
196HOST PORT STATUS OPTIONAL-PARAMETER.")
197
185(defun nsm-check-protocol (process host port status settings) 198(defun nsm-check-protocol (process host port status settings)
186 (let ((prime-bits (plist-get status :diffie-hellman-prime-bits)) 199 (cl-loop for check in network-security-protocol-checks
187 (signature-algorithm 200 for type = (intern (format ":%s" (car check)) obarray)
188 (plist-get (plist-get status :certificate) :signature-algorithm)) 201 while process
189 (encryption (format "%s-%s-%s" 202 ;; Skip the check if the user has already said that this
190 (plist-get status :key-exchange) 203 ;; host is OK for this type of "error".
191 (plist-get status :cipher) 204 when (and (not (memq type (plist-get settings :conditions)))
192 (plist-get status :mac))) 205 (< (nsm-level network-security-level)
193 (protocol (plist-get status :protocol))) 206 (nsm-level (cadr check))))
194 (cond 207 do (let ((result
195 ((and prime-bits 208 (funcall (intern (format "nsm-protocol-check--%s"
196 (< prime-bits 1024) 209 (car check))
197 (not (memq :diffie-hellman-prime-bits 210 obarray)
198 (plist-get settings :conditions))) 211 host port status (nth 2 check))))
199 (not 212 (unless result
200 (nsm-query 213 (delete-process process)
201 host port status :diffie-hellman-prime-bits 214 (setq process nil))))
202 "The Diffie-Hellman prime bits (%s) used for this connection to %s:%s is less than what is considered safe (%s)." 215 ;; If a test failed we return nil, otherwise the process object.
203 prime-bits host port 1024))) 216 process)
204 (delete-process process) 217
205 nil) 218(defun nsm--encryption (status)
206 ((and (string-match "\\bRC4\\b" encryption) 219 (format "%s-%s-%s"
207 (not (memq :rc4 (plist-get settings :conditions))) 220 (plist-get status :key-exchange)
208 (not 221 (plist-get status :cipher)
209 (nsm-query 222 (plist-get status :mac)))
210 host port status :rc4 223
211 "The connection to %s:%s uses the RC4 algorithm (%s), which is believed to be unsafe." 224(defun nsm-protocol-check--diffie-hellman-prime-bits (host port status bits)
212 host port encryption))) 225 (let ((prime-bits (plist-get status :diffie-hellman-prime-bits)))
213 (delete-process process) 226 (or (not prime-bits)
214 nil) 227 (>= prime-bits bits)
215 ((and (string-match "\\bSHA1\\b" signature-algorithm) 228 (nsm-query
216 (not (memq :signature-sha1 (plist-get settings :conditions))) 229 host port status :diffie-hellman-prime-bits
217 (not 230 "The Diffie-Hellman prime bits (%s) used for this connection to %s:%s is less than what is considered safe (%s)."
218 (nsm-query 231 prime-bits host port bits))))
219 host port status :signature-sha1 232
220 "The certificate used to verify the connection to %s:%s uses the SHA1 algorithm (%s), which is believed to be unsafe." 233(defun nsm-protocol-check--rc4 (host port status _)
221 host port signature-algorithm))) 234 (or (not (string-match "\\bRC4\\b" (nsm--encryption status)))
222 (delete-process process) 235 (nsm-query
223 nil) 236 host port status :rc4
224 ((and protocol 237 "The connection to %s:%s uses the RC4 algorithm (%s), which is believed to be unsafe."
225 (string-match "SSL" protocol) 238 host port (nsm--encryption status))))
226 (not (memq :ssl (plist-get settings :conditions))) 239
227 (not 240(defun nsm-protocol-check--signature-sha1 (host port status _)
228 (nsm-query 241 (let ((signature-algorithm
229 host port status :ssl 242 (plist-get (plist-get status :certificate) :signature-algorithm)))
230 "The connection to %s:%s uses the %s protocol, which is believed to be unsafe." 243 (or (not (string-match "\\bSHA1\\b" signature-algorithm))
231 host port protocol))) 244 (nsm-query
232 (delete-process process) 245 host port status :signature-sha1
233 nil) 246 "The certificate used to verify the connection to %s:%s uses the SHA1 algorithm (%s), which is believed to be unsafe."
234 (t 247 host port signature-algorithm))))
235 process)))) 248
249(defun nsm-protocol-check--ssl (host port status _)
250 (let ((protocol (plist-get status :protocol)))
251 (or (not protocol)
252 (not (string-match "SSL" protocol))
253 (nsm-query
254 host port status :ssl
255 "The connection to %s:%s uses the %s protocol, which is believed to be unsafe."
256 host port protocol))))
236 257
237(defun nsm-fingerprint (status) 258(defun nsm-fingerprint (status)
238 (plist-get (plist-get status :certificate) :public-key-id)) 259 (plist-get (plist-get status :certificate) :public-key-id))