-
Notifications
You must be signed in to change notification settings - Fork 30
/
relay.el
139 lines (118 loc) · 4.81 KB
/
relay.el
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
;; relay.el -- relayed network connection hack
;; Copyright (c) 2001 Shun-ichi Goto.
;; Author: Shun-ichi GOTO <[email protected]>
;; Created: Tue May 15 01:25:22 2001
;; Version: 1.11
;; Keywords: network, socks
;;; Commentary:
;; This packege contains alternative function of open-network-stream
;; to make relayed network connection using external command like ssh
;; and connect(*) command.
;;
;; (*) connect command can be get from
;; http://www.imasy.or.jp/~gotoh/ssh/connect.c
;; It can be compiled UNIXes and Win32 environments.
;;; Resstriction
;; * Interactive authentication is not supported. For example,
;; password or passphrase prompt of ssh with tty is not handled. So
;; you should prepare other method to authentication like ssh-agent
;; or ssh-ask-pass.
;;; Instalation:
;; Put this package into load-path'ed directory.
;;; Usage:
;; Define relay-command-alist for your environment.
;; Then use relay-open-network-stream instead of open-network-stream.
;; Or, advice open-network-stream like this:
;;
;; (defadvice open-network-stream (around relay (name buffer host service)
;; activate)
;; "Open network stream with relaying."
;; (require 'relay)
;; (defvar relay-internal-using-p nil)
;; (if relay-internal-using-p
;; ad-do-it ; not relayed, use standard way.
;; (let ((relay-internal-using-p t))
;; ;; make connction using specified command
;; (setq ad-return-value
;; (relay-open-network-stream name buffer host service)))))
;;
;; If you use this with Wanderlust,
;; (setq elmo-network-stream-type-alist
;; (cons '("!relay" relay relay relay-open-network-stream)
;; elmo-network-stream-type-alist))
;;
;; If you send mail through the SMTP server inside of your organization
;; from outside, you can relay to the SMTP server like this:
;;
;; (setq relay-command-alist
;; (cons '(("^smtp\\.your\\.domain\\.org$" . (25 "smtp"))
;; "ssh" "somehost.your.domain.org" "connect" host port)
;; smtp-open-connection-function #'relay-open-network-stream)
;;
;; In expression above, this entry is used only when making smtp
;; service to smtp.your.domain.org, and not used for another service
;; (like POP). To send message with smtp.el, you should also set
;; `smtp-open-connection-function' as `relay-open-network-stream',
;; or advice `open-network-stream' function.
;;; Code:
(defvar relay-command-alist nil
"*Alist of destination and relay command to connect there. For each
element, car is destination host regex for target hostname, or cons of
regex and list of services. And cdr is list for relay command
execution. If regexp (and also service) is matches with HOST (and
SERVICE) of `relay-open-network-stream', invoke command specified in
its cdr. You can use two special symbol 'host and 'service as target
hostname and service given as argument of `relay-open-network-stream'.
For example:
(setq relay-command-alist
'((\"^news\\\\.imasy\\\\.or\\\\.jp$\"
\"ssh\" \"-C\" \"-1\" \"tasogare.imasy.or.jp\" \"connect\"
host service)
(\"^news\\\\.biglobe\\\\.ne\\\\.jp$\"
\"ssh\" \"-C\" \"gotoh.cjb.net\" \"connect\" host service)
((\"^smtp\\\\.my-company\\\\.co\\\\.jp$\" . (25 \"smtp\"))
\"ssh\" \"firewall.my-company.co.jp\" \"connect\" host service))
NOTE: Authentication are not considered. We assume making
connection does not use tty for authentication. We hope to
use ssh-agent or ssh-askpass for SSH, and host authentication
for SOCKS.
")
(defun relay-prepare-command (host service)
"Determine relaly command from `relay-command-alist' and prepare to call.
Result is list of string for calling with `start-process'."
(let ((alist relay-command-alist)
dest regexp services cmdl )
(while alist
(setq dest (caar alist)
cmdl (cdar alist))
(cond
((consp dest)
(setq regexp (car dest)
services (cdr dest)))
((stringp dest)
(setq regexp dest
services nil))
(t (error "Invalid entry in relay-command-alist %s" (car alist))))
(if (and (or (null services)
(member service services))
(or (eq regexp t) ; default
(and regexp (string-match regexp host))))
;; found!
(setq alist nil)
;; or more loop
(setq cmdl nil
alist (cdr alist))))
;; make result list
(and cmdl
(mapcar (lambda (arg) (format "%s" (eval arg))) cmdl))))
(defun relay-open-network-stream (name buffer host service)
"Alternative function of `open-network-stream'.
If route is not found in `relay-command-alist', make direct
connection without relaying."
(let ((cmdl (relay-prepare-command host service)))
(if (null cmdl)
(open-network-stream name buffer host service) ; usual way
(apply (function start-process) name buffer cmdl))))
;;;
(provide 'relay)
;; relay.el ends here