aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJimmy Yuen Ho Wong2018-07-10 14:23:20 +0100
committerJimmy Yuen Ho Wong2018-07-14 17:50:44 +0100
commit682578fcf74d4598e39eca81e09d81810d3fc28d (patch)
treed8a8f54c778a831229405cd9706066ac582d3826
parent534a3d5d3a99a6b86a47b3d91840ce8771ee0ae6 (diff)
downloademacs-682578fcf74d4598e39eca81e09d81810d3fc28d.tar.gz
emacs-682578fcf74d4598e39eca81e09d81810d3fc28d.zip
Add option to bypass NSM TLS checks on local networks
* lisp/net/net-utils.el (nslookup-host-ipv4, nslookup-host-ipv6, ipv6-expand): New functions to lookup IPv4 and IPv6 addresses from DNS. * lisp/net/nsm.el (nsm-trust-local-network, nsm-should-check, nsm-check-tls-connection, nsm-check-plain-connection): New defcustom `nsm-trust-local-network' lets users customize whether NSM should check for TLS problems when connecting to the hosts on their local networks. `nsm-should-check' determines whether `nsm-check-tls-connection' and `nsm-check-plain-connection' should perform checks. localhost is implicitly trusted, thus checks are never performed there.
-rw-r--r--lisp/net/net-utils.el75
-rw-r--r--lisp/net/nsm.el76
2 files changed, 148 insertions, 3 deletions
diff --git a/lisp/net/net-utils.el b/lisp/net/net-utils.el
index c9e80804bd3..0ba4aae0ae0 100644
--- a/lisp/net/net-utils.el
+++ b/lisp/net/net-utils.el
@@ -43,6 +43,10 @@
43;; still use them for queries). Actually the trend these 43;; still use them for queries). Actually the trend these
44;; days is for /sbin to be a symlink to /usr/sbin, but we still need to 44;; days is for /sbin to be a symlink to /usr/sbin, but we still need to
45;; search both for older systems. 45;; search both for older systems.
46
47(require 'subr-x)
48(require 'cl-lib)
49
46(defun net-utils--executable-find-sbin (command) 50(defun net-utils--executable-find-sbin (command)
47 "Return absolute name of COMMAND if found in an sbin directory." 51 "Return absolute name of COMMAND if found in an sbin directory."
48 (let ((exec-path '("/sbin" "/usr/sbin" "/usr/local/sbin"))) 52 (let ((exec-path '("/sbin" "/usr/sbin" "/usr/local/sbin")))
@@ -514,7 +518,11 @@ Optional argument NAME-SERVER says which server to use for
514DNS resolution. 518DNS resolution.
515Interactively, prompt for NAME-SERVER if invoked with prefix argument. 519Interactively, prompt for NAME-SERVER if invoked with prefix argument.
516 520
517This command uses `nslookup-program' for looking up the DNS information." 521This command uses `nslookup-program' for looking up the DNS information.
522
523See also: `nslookup-host-ipv4', `nslookup-host-ipv6' for
524non-interactive versions of this function more suitable for use
525in Lisp code."
518 (interactive 526 (interactive
519 (list (read-from-minibuffer "Lookup host: " (net-utils-machine-at-point)) 527 (list (read-from-minibuffer "Lookup host: " (net-utils-machine-at-point))
520 (if current-prefix-arg (read-from-minibuffer "Name server: ")))) 528 (if current-prefix-arg (read-from-minibuffer "Name server: "))))
@@ -531,6 +539,71 @@ This command uses `nslookup-program' for looking up the DNS information."
531 options))) 539 options)))
532 540
533;;;###autoload 541;;;###autoload
542(defun nslookup-host-ipv4 (host &optional name-server format)
543 "Return the IPv4 address for HOST (name or IP address).
544Optional argument NAME-SERVER says which server to use for DNS
545resolution.
546
547If FORMAT is `string', returns the IP address as a
548string (default). If FORMAT is `vector', returns a 4-integer
549vector of octets.
550
551This command uses `nslookup-program' to look up DNS records."
552 (let* ((args `(,nslookup-program "-type=A" ,host ,name-server))
553 (output (shell-command-to-string
554 (string-join (cl-remove nil args) " ")))
555 (ip (or (and (string-match
556 "Name:.*\nAddress: *\\(\\([0-9]\\{1,3\\}\\.?\\)\\{4\\}\\)"
557 output)
558 (match-string 1 output))
559 host)))
560 (cond ((memq format '(string nil))
561 ip)
562 ((eq format 'vector)
563 (apply #'vector (mapcar #'string-to-number (split-string ip "\\."))))
564 (t (error "Invalid format: %s" format)))))
565
566(defun ipv6-expand (ipv6-vector)
567 (let ((len (length ipv6-vector)))
568 (if (< len 8)
569 (let* ((pivot (cl-position 0 ipv6-vector))
570 (head (cl-subseq ipv6-vector 0 pivot))
571 (tail (cl-subseq ipv6-vector (1+ pivot) len)))
572 (vconcat head (make-vector (- 8 (1- len)) 0) tail))
573 ipv6-vector)))
574
575;;;###autoload
576(defun nslookup-host-ipv6 (host &optional name-server format)
577 "Return the IPv6 address for HOST (name or IP address).
578Optional argument NAME-SERVER says which server to use for DNS
579resolution.
580
581If FORMAT is `string', returns the IP address as a
582string (default). If FORMAT is `vector', returns a 8-integer
583vector of hextets.
584
585This command uses `nslookup-program' to look up DNS records."
586 (let* ((args `(,nslookup-program "-type=AAAA" ,host ,name-server))
587 (output (shell-command-to-string
588 (string-join (cl-remove nil args) " ")))
589 (hextet "[0-9a-fA-F]\\{1,4\\}")
590 (ip-regex (concat "\\(\\(" hextet "[:]\\)\\{1,6\\}\\([:]?\\(" hextet "\\)\\{1,6\\}\\)\\)"))
591 (ip (or (and (string-match
592 (if (eq system-type 'windows-nt)
593 (concat "Name:.*\nAddress: *" ip-regex)
594 (concat "has AAAA address " ip-regex))
595 output)
596 (match-string 1 output))
597 host)))
598 (cond ((memq format '(string nil))
599 ip)
600 ((eq format 'vector)
601 (ipv6-expand (apply #'vector
602 (cl-loop for hextet in (split-string ip "[:]")
603 collect (string-to-number hextet 16)))))
604 (t (error "Invalid format: %s" format)))))
605
606;;;###autoload
534(defun nslookup () 607(defun nslookup ()
535 "Run `nslookup-program'." 608 "Run `nslookup-program'."
536 (interactive) 609 (interactive)
diff --git a/lisp/net/nsm.el b/lisp/net/nsm.el
index 50895bc0ad9..e4c52bc9c1c 100644
--- a/lisp/net/nsm.el
+++ b/lisp/net/nsm.el
@@ -62,6 +62,26 @@ checked and warned against."
62(when (eq network-security-level 'paranoid) 62(when (eq network-security-level 'paranoid)
63 (setq network-security-level 'high)) 63 (setq network-security-level 'high))
64 64
65(defcustom nsm-trust-local-network nil
66 "Disable warnings when visiting trusted hosts on local networks.
67
68The default suite of TLS checks in NSM is designed to follow the
69most current security best practices. Under some situations,
70such as attempting to connect to an email server that do not
71follow these practices inside a school or corporate network, NSM
72may produce warnings for such occasions. Setting this option to
73a non-nil value, or a zero-argument function that returns non-nil
74tells NSM to skip checking for potential TLS vulnerabilities when
75connecting to hosts on a local network.
76
77Make sure you know what you are doing before enabling this
78option."
79 :version "27.1"
80 :group 'nsm
81 :type '(choice (const :tag "On" t)
82 (const :tag "Off" nil)
83 (function :tag "Custom function")))
84
65(defcustom nsm-settings-file (expand-file-name "network-security.data" 85(defcustom nsm-settings-file (expand-file-name "network-security.data"
66 user-emacs-directory) 86 user-emacs-directory)
67 "The file the security manager settings will be stored in." 87 "The file the security manager settings will be stored in."
@@ -184,6 +204,55 @@ SETTINGS are the same as those supplied to each check function.
184RESULTS is an alist where the keys are the checks run and the 204RESULTS is an alist where the keys are the checks run and the
185values the results of the checks.") 205values the results of the checks.")
186 206
207(defun nsm-should-check (host)
208 "Determines whether NSM should check for TLS problems for HOST.
209
210If `nsm-trust-local-network' is or returns non-nil, and if the
211host address is a localhost address, a machine address, a direct
212link or a private network address, this function returns
213nil. Non-nil otherwise."
214 (let* ((address (or (nslookup-host-ipv4 host nil 'vector)
215 (nslookup-host-ipv6 host nil 'vector)))
216 (ipv4? (eq (length address) 4)))
217 (not
218 (or (if ipv4?
219 (or
220 ;; (0.x.x.x) this machine
221 (eq (aref address 0) 0)
222 ;; (127.x.x.x) localhost
223 (eq (aref address 0) 0))
224 (or
225 ;; (::) IPv6 this machine
226 (not (cl-mismatch address [0 0 0 0 0 0 0 0]))
227 ;; (::1) IPv6 localhost
228 (not (cl-mismatch address [0 0 0 0 0 0 0 1]))))
229 (and (or (and (functionp nsm-trust-local-network)
230 (funcall nsm-trust-local-network))
231 nsm-trust-local-network)
232 (if ipv4?
233 (or
234 ;; (10.x.x.x) private
235 (eq (aref address 0) 10)
236 ;; (172.16.x.x) private
237 (and (eq (aref address 0) 172)
238 (eq (aref address 0) 16))
239 ;; (192.168.x.x) private
240 (and (eq (aref address 0) 192)
241 (eq (aref address 0) 168))
242 ;; (198.18.x.x) private
243 (and (eq (aref address 0) 198)
244 (eq (aref address 0) 18))
245 ;; (169.254.x.x) link-local
246 (and (eq (aref address 0) 169)
247 (eq (aref address 0) 254)))
248 (memq (aref address 0)
249 '(
250 64512 ;; (fc00::) IPv6 unique local address
251 64768 ;; (fd00::) IPv6 unique local address
252 65152 ;; (fe80::) IPv6 link-local
253 )
254 )))))))
255
187(defun nsm-check-tls-connection (process host port status settings) 256(defun nsm-check-tls-connection (process host port status settings)
188 "Check TLS connection against potential security problems. 257 "Check TLS connection against potential security problems.
189 258
@@ -204,6 +273,7 @@ This function returns the process PROCESS if no problems are
204found, and nil otherwise. 273found, and nil otherwise.
205 274
206See also: `nsm-tls-checks' and `nsm-noninteractive'" 275See also: `nsm-tls-checks' and `nsm-noninteractive'"
276 (when (nsm-should-check host)
207 (let* ((results 277 (let* ((results
208 (cl-loop for check in nsm-tls-checks 278 (cl-loop for check in nsm-tls-checks
209 for type = (intern (format ":%s" 279 for type = (intern (format ":%s"
@@ -234,7 +304,7 @@ See also: `nsm-tls-checks' and `nsm-noninteractive'"
234 (delete-process process) 304 (delete-process process)
235 (setq process nil))) 305 (setq process nil)))
236 (run-hook-with-args 'nsm-tls-post-check-functions 306 (run-hook-with-args 'nsm-tls-post-check-functions
237 host port status settings results)) 307 host port status settings results)))
238 process) 308 process)
239 309
240 310
@@ -678,6 +748,7 @@ protocol."
678 'nsm-fingerprint-ok-p '(status settings) "27.1") 748 'nsm-fingerprint-ok-p '(status settings) "27.1")
679 749
680(defun nsm-check-plain-connection (process host port settings warn-unencrypted) 750(defun nsm-check-plain-connection (process host port settings warn-unencrypted)
751 (if (nsm-should-check host)
681 ;; If this connection used to be TLS, but is now plain, then it's 752 ;; If this connection used to be TLS, but is now plain, then it's
682 ;; possible that we're being Man-In-The-Middled by a proxy that's 753 ;; possible that we're being Man-In-The-Middled by a proxy that's
683 ;; stripping out STARTTLS announcements. 754 ;; stripping out STARTTLS announcements.
@@ -703,7 +774,8 @@ protocol."
703 (delete-process process) 774 (delete-process process)
704 nil) 775 nil)
705 (t 776 (t
706 process)))) 777 process)))
778 process))
707 779
708(defun nsm-query (host port status what problems message) 780(defun nsm-query (host port status what problems message)
709 ;; If there is no user to answer queries, then say `no' to everything. 781 ;; If there is no user to answer queries, then say `no' to everything.