url-gw.el 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260
  1. ;;; url-gw.el --- Gateway munging for URL loading
  2. ;; Copyright (C) 1997-1998, 2004-2012 Free Software Foundation, Inc.
  3. ;; Author: Bill Perry <wmperry@gnu.org>
  4. ;; Keywords: comm, data, processes
  5. ;; This file is part of GNU Emacs.
  6. ;; GNU Emacs is free software: you can redistribute it and/or modify
  7. ;; it under the terms of the GNU General Public License as published by
  8. ;; the Free Software Foundation, either version 3 of the License, or
  9. ;; (at your option) any later version.
  10. ;; GNU Emacs is distributed in the hope that it will be useful,
  11. ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. ;; GNU General Public License for more details.
  14. ;; You should have received a copy of the GNU General Public License
  15. ;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
  16. ;;; Code:
  17. (eval-when-compile (require 'cl))
  18. (require 'url-vars)
  19. ;; Fixme: support SSH explicitly or via a url-gateway-rlogin-program?
  20. (autoload 'socks-open-network-stream "socks")
  21. (defgroup url-gateway nil
  22. "URL gateway variables."
  23. :group 'url)
  24. (defcustom url-gateway-local-host-regexp nil
  25. "A regular expression specifying local hostnames/machines."
  26. :type '(choice (const nil) regexp)
  27. :group 'url-gateway)
  28. (defcustom url-gateway-prompt-pattern
  29. "^[^#$%>;]*[#$%>;] *" ;; "bash\\|\$ *\r?$\\|> *\r?"
  30. "A regular expression matching a shell prompt."
  31. :type 'regexp
  32. :group 'url-gateway)
  33. (defcustom url-gateway-rlogin-host nil
  34. "What hostname to actually rlog into before doing a telnet."
  35. :type '(choice (const nil) string)
  36. :group 'url-gateway)
  37. (defcustom url-gateway-rlogin-user-name nil
  38. "Username to log into the remote machine with when using rlogin."
  39. :type '(choice (const nil) string)
  40. :group 'url-gateway)
  41. (defcustom url-gateway-rlogin-parameters '("telnet" "-8")
  42. "Parameters to `url-open-rlogin'.
  43. This list will be used as the parameter list given to rsh."
  44. :type '(repeat string)
  45. :group 'url-gateway)
  46. (defcustom url-gateway-telnet-host nil
  47. "What hostname to actually login to before doing a telnet."
  48. :type '(choice (const nil) string)
  49. :group 'url-gateway)
  50. (defcustom url-gateway-telnet-parameters '("exec" "telnet" "-8")
  51. "Parameters to `url-open-telnet'.
  52. This list will be executed as a command after logging in via telnet."
  53. :type '(repeat string)
  54. :group 'url-gateway)
  55. (defcustom url-gateway-telnet-login-prompt "^\r*.?login:"
  56. "Prompt that tells us we should send our username when logging in w/telnet."
  57. :type 'regexp
  58. :group 'url-gateway)
  59. (defcustom url-gateway-telnet-password-prompt "^\r*.?password:"
  60. "Prompt that tells us we should send our password when logging in w/telnet."
  61. :type 'regexp
  62. :group 'url-gateway)
  63. (defcustom url-gateway-telnet-user-name nil
  64. "User name to log in via telnet with."
  65. :type '(choice (const nil) string)
  66. :group 'url-gateway)
  67. (defcustom url-gateway-telnet-password nil
  68. "Password to use to log in via telnet with."
  69. :type '(choice (const nil) string)
  70. :group 'url-gateway)
  71. (defcustom url-gateway-broken-resolution nil
  72. "Whether to use nslookup to resolve hostnames.
  73. This should be used when your version of Emacs cannot correctly use DNS,
  74. but your machine can. This usually happens if you are running a statically
  75. linked Emacs under SunOS 4.x."
  76. :type 'boolean
  77. :group 'url-gateway)
  78. (defcustom url-gateway-nslookup-program "nslookup"
  79. "If non-nil then a string naming nslookup program."
  80. :type '(choice (const :tag "None" :value nil) string)
  81. :group 'url-gateway)
  82. ;; Stolen from ange-ftp
  83. ;;;###autoload
  84. (defun url-gateway-nslookup-host (host)
  85. "Attempt to resolve the given HOST using nslookup if possible."
  86. (interactive "sHost: ")
  87. (if url-gateway-nslookup-program
  88. (let ((proc (start-process " *nslookup*" " *nslookup*"
  89. url-gateway-nslookup-program host))
  90. (res host))
  91. (set-process-query-on-exit-flag proc nil)
  92. (with-current-buffer (process-buffer proc)
  93. (while (memq (process-status proc) '(run open))
  94. (accept-process-output proc))
  95. (goto-char (point-min))
  96. (if (re-search-forward "Name:.*\nAddress: *\\(.*\\)$" nil t)
  97. (setq res (buffer-substring (match-beginning 1)
  98. (match-end 1))))
  99. (kill-buffer (current-buffer)))
  100. res)
  101. host))
  102. ;; Stolen from red gnus nntp.el
  103. (defun url-wait-for-string (regexp proc)
  104. "Wait until string matching REGEXP arrives in process PROC's buffer."
  105. (let ((buf (current-buffer)))
  106. (goto-char (point-min))
  107. (while (not (re-search-forward regexp nil t))
  108. (accept-process-output proc)
  109. (set-buffer buf)
  110. (goto-char (point-min)))))
  111. ;; Stolen from red gnus nntp.el
  112. (defun url-open-rlogin (name buffer host service)
  113. "Open a connection using rsh."
  114. (if (not (stringp service))
  115. (setq service (int-to-string service)))
  116. (let ((proc (if url-gateway-rlogin-user-name
  117. (start-process
  118. name buffer "rsh"
  119. url-gateway-rlogin-host "-l" url-gateway-rlogin-user-name
  120. (mapconcat 'identity
  121. (append url-gateway-rlogin-parameters
  122. (list host service)) " "))
  123. (start-process
  124. name buffer "rsh" url-gateway-rlogin-host
  125. (mapconcat 'identity
  126. (append url-gateway-rlogin-parameters
  127. (list host service))
  128. " ")))))
  129. (set-buffer buffer)
  130. (url-wait-for-string "^\r*200" proc)
  131. (beginning-of-line)
  132. (delete-region (point-min) (point))
  133. proc))
  134. ;; Stolen from red gnus nntp.el
  135. (defun url-open-telnet (name buffer host service)
  136. (if (not (stringp service))
  137. (setq service (int-to-string service)))
  138. (with-current-buffer (get-buffer-create buffer)
  139. (erase-buffer)
  140. (let ((proc (start-process name buffer "telnet" "-8"))
  141. (case-fold-search t))
  142. (when (memq (process-status proc) '(open run))
  143. (process-send-string proc "set escape \^X\n")
  144. (process-send-string proc (concat
  145. "open " url-gateway-telnet-host "\n"))
  146. (url-wait-for-string url-gateway-telnet-login-prompt proc)
  147. (process-send-string
  148. proc (concat
  149. (or url-gateway-telnet-user-name
  150. (setq url-gateway-telnet-user-name (read-string "login: ")))
  151. "\n"))
  152. (url-wait-for-string url-gateway-telnet-password-prompt proc)
  153. (process-send-string
  154. proc (concat
  155. (or url-gateway-telnet-password
  156. (setq url-gateway-telnet-password
  157. (read-passwd "Password: ")))
  158. "\n"))
  159. (erase-buffer)
  160. (url-wait-for-string url-gateway-prompt-pattern proc)
  161. (process-send-string
  162. proc (concat (mapconcat 'identity
  163. (append url-gateway-telnet-parameters
  164. (list host service)) " ") "\n"))
  165. (url-wait-for-string "^\r*Escape character.*\r*\n+" proc)
  166. (delete-region (point-min) (match-end 0))
  167. (process-send-string proc "\^]\n")
  168. (url-wait-for-string "^telnet" proc)
  169. (process-send-string proc "mode character\n")
  170. (accept-process-output proc 1)
  171. (sit-for 1)
  172. (goto-char (point-min))
  173. (forward-line 1)
  174. (delete-region (point) (point-max)))
  175. proc)))
  176. ;;;###autoload
  177. (defun url-open-stream (name buffer host service)
  178. "Open a stream to HOST, possibly via a gateway.
  179. Args per `open-network-stream'.
  180. Will not make a connection if `url-gateway-unplugged' is non-nil.
  181. Might do a non-blocking connection; use `process-status' to check."
  182. (unless url-gateway-unplugged
  183. (let ((gw-method (if (and url-gateway-local-host-regexp
  184. (not (eq 'tls url-gateway-method))
  185. (not (eq 'ssl url-gateway-method))
  186. (string-match
  187. url-gateway-local-host-regexp
  188. host))
  189. 'native
  190. url-gateway-method))
  191. ;; An attempt to deal with denied connections, and attempt
  192. ;; to reconnect
  193. (cur-retries 0)
  194. (retry t)
  195. (errobj nil)
  196. (conn nil))
  197. ;; If the user told us to do DNS for them, do it.
  198. (if url-gateway-broken-resolution
  199. (setq host (url-gateway-nslookup-host host)))
  200. (condition-case errobj
  201. ;; This is a clean way to ensure the new process inherits the
  202. ;; right coding systems in both Emacs and XEmacs.
  203. (let ((coding-system-for-read 'binary)
  204. (coding-system-for-write 'binary))
  205. (setq conn (case gw-method
  206. ((tls ssl native)
  207. (if (eq gw-method 'native)
  208. (setq gw-method 'plain))
  209. (open-network-stream
  210. name buffer host service
  211. :type gw-method
  212. ;; Use non-blocking socket if we can.
  213. :nowait (featurep 'make-network-process
  214. '(:nowait t))))
  215. (socks
  216. (socks-open-network-stream name buffer host service))
  217. (telnet
  218. (url-open-telnet name buffer host service))
  219. (rlogin
  220. (url-open-rlogin name buffer host service))
  221. (otherwise
  222. (error "Bad setting of url-gateway-method: %s"
  223. url-gateway-method))))))
  224. conn)))
  225. (provide 'url-gw)
  226. ;;; url-gw.el ends here