diff options
| author | Lars Ingebrigtsen | 2018-06-24 15:36:50 +0200 |
|---|---|---|
| committer | Lars Ingebrigtsen | 2018-06-24 15:37:00 +0200 |
| commit | 6584bc6720fce6a830ab18538f89acc80da597f1 (patch) | |
| tree | f4b3c9d48fd6c8b9a36b1634e28c04e411089000 | |
| parent | 16c2f03c15078c4bd98c4b1e4d15701ba45550c3 (diff) | |
| download | emacs-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.texi | 16 | ||||
| -rw-r--r-- | etc/NEWS | 5 | ||||
| -rw-r--r-- | lisp/net/nsm.el | 133 |
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 | |||
| 402 | servers the user has connected to. If this variable is @code{t}, | 402 | servers 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 | ||
| 408 | The protocol network checks (mostly for @acronym{TLS} weaknesses) is | ||
| 409 | controlled via the @code{network-security-protocol-checks} variable. | ||
| 410 | |||
| 411 | It's an alist where the first element is the name of the check, | ||
| 412 | the second is the security level where the check kicks in, and the | ||
| 413 | optional third element is a parameter supplied to the check. | ||
| 414 | |||
| 415 | An 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)}. | ||
| 418 | The function should return non-@code{nil} if the connection should | ||
| 419 | proceed and @code{nil} otherwise. | ||
| 420 | |||
| 405 | @end table | 421 | @end table |
| 406 | 422 | ||
| 407 | 423 | ||
| @@ -131,6 +131,11 @@ used to remove comments before calling the libxml functions to parse | |||
| 131 | the data. | 131 | the data. |
| 132 | 132 | ||
| 133 | +++ | 133 | +++ |
| 134 | ** The Network Security Manager now allows more fine-grained control | ||
| 135 | of what checks to run via the `network-security-protocol-checks' | ||
| 136 | variable. | ||
| 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'. |
| 135 | It blocks line breaking after a one-letter word, also in the case when | 140 | It blocks line breaking after a one-letter word, also in the case when |
| 136 | this word is preceded by a non-space, but non-alphanumeric character. | 141 | this 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. | ||
| 190 | It's an alist where the first element is the name of the check, | ||
| 191 | the second is the security level where the check kicks in, and the | ||
| 192 | optional third element is a parameter supplied to the check. | ||
| 193 | |||
| 194 | An element like `(rc4 medium)' will result in the function | ||
| 195 | `nsm-protocol-check--rc4' being called with the parameters | ||
| 196 | HOST 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)) |