From 682578fcf74d4598e39eca81e09d81810d3fc28d Mon Sep 17 00:00:00 2001
From: Jimmy Yuen Ho Wong <wyuenho@gmail.com>
Date: Tue, 10 Jul 2018 14:23:20 +0100
Subject: 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.
---
 lisp/net/net-utils.el | 75 ++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 74 insertions(+), 1 deletion(-)

(limited to 'lisp/net/net-utils.el')

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 @@
 ;; still use them for queries).  Actually the trend these
 ;; days is for /sbin to be a symlink to /usr/sbin, but we still need to
 ;; search both for older systems.
+
+(require 'subr-x)
+(require 'cl-lib)
+
 (defun net-utils--executable-find-sbin (command)
   "Return absolute name of COMMAND if found in an sbin directory."
   (let ((exec-path '("/sbin" "/usr/sbin" "/usr/local/sbin")))
@@ -514,7 +518,11 @@ Optional argument NAME-SERVER says which server to use for
 DNS resolution.
 Interactively, prompt for NAME-SERVER if invoked with prefix argument.
 
-This command uses `nslookup-program' for looking up the DNS information."
+This command uses `nslookup-program' for looking up the DNS information.
+
+See also: `nslookup-host-ipv4', `nslookup-host-ipv6' for
+non-interactive versions of this function more suitable for use
+in Lisp code."
   (interactive
    (list (read-from-minibuffer "Lookup host: " (net-utils-machine-at-point))
          (if current-prefix-arg (read-from-minibuffer "Name server: "))))
@@ -530,6 +538,71 @@ This command uses `nslookup-program' for looking up the DNS information."
      nslookup-program
      options)))
 
+;;;###autoload
+(defun nslookup-host-ipv4 (host &optional name-server format)
+  "Return the IPv4 address for HOST (name or IP address).
+Optional argument NAME-SERVER says which server to use for DNS
+resolution.
+
+If FORMAT is `string', returns the IP address as a
+string (default).  If FORMAT is `vector', returns a 4-integer
+vector of octets.
+
+This command uses `nslookup-program' to look up DNS records."
+  (let* ((args `(,nslookup-program "-type=A" ,host ,name-server))
+         (output (shell-command-to-string
+                  (string-join (cl-remove nil args) " ")))
+         (ip (or (and (string-match
+                       "Name:.*\nAddress: *\\(\\([0-9]\\{1,3\\}\\.?\\)\\{4\\}\\)"
+                       output)
+                      (match-string 1 output))
+                 host)))
+    (cond ((memq format '(string nil))
+           ip)
+          ((eq format 'vector)
+           (apply #'vector (mapcar #'string-to-number (split-string ip "\\."))))
+          (t (error "Invalid format: %s" format)))))
+
+(defun ipv6-expand (ipv6-vector)
+  (let ((len (length ipv6-vector)))
+    (if (< len 8)
+        (let* ((pivot (cl-position 0 ipv6-vector))
+               (head (cl-subseq ipv6-vector 0 pivot))
+               (tail (cl-subseq ipv6-vector (1+ pivot) len)))
+          (vconcat head (make-vector (- 8 (1- len)) 0) tail))
+      ipv6-vector)))
+
+;;;###autoload
+(defun nslookup-host-ipv6 (host &optional name-server format)
+  "Return the IPv6 address for HOST (name or IP address).
+Optional argument NAME-SERVER says which server to use for DNS
+resolution.
+
+If FORMAT is `string', returns the IP address as a
+string (default).  If FORMAT is `vector', returns a 8-integer
+vector of hextets.
+
+This command uses `nslookup-program' to look up DNS records."
+  (let* ((args `(,nslookup-program "-type=AAAA" ,host ,name-server))
+         (output (shell-command-to-string
+                  (string-join (cl-remove nil args) " ")))
+         (hextet "[0-9a-fA-F]\\{1,4\\}")
+         (ip-regex (concat "\\(\\(" hextet "[:]\\)\\{1,6\\}\\([:]?\\(" hextet "\\)\\{1,6\\}\\)\\)"))
+         (ip (or (and (string-match
+                       (if (eq system-type 'windows-nt)
+                           (concat "Name:.*\nAddress: *" ip-regex)
+                         (concat "has AAAA address " ip-regex))
+                       output)
+                      (match-string 1 output))
+                 host)))
+    (cond ((memq format '(string nil))
+           ip)
+          ((eq format 'vector)
+           (ipv6-expand (apply #'vector
+                               (cl-loop for hextet in (split-string ip "[:]")
+                                        collect (string-to-number hextet 16)))))
+          (t (error "Invalid format: %s" format)))))
+
 ;;;###autoload
 (defun nslookup ()
   "Run `nslookup-program'."
-- 
cgit v1.2.3