]> git.cworth.org Git - notmuch-wiki/blob - remoteusage/124.mdwn
script & doc in par with nottoomuch-remote.(bash|rst)
[notmuch-wiki] / remoteusage / 124.mdwn
1 ## Remoteusage without password-free login requirement
2
3 This is alternative to [[remoteusage|remoteusage]] where password-free
4 login is not a requirement. See [[remoteusage|remoteusage]] page for
5 other requirements and general information.
6
7 This solution uses one pre-made ssh connection where the client is put
8 into "master" mode (-M) for connection sharing. The wrapper script then
9 uses the control socket created by this pre-made ssh connection for
10 its own connection. As long as master ssh connection is live, slave
11 can use it. Disconnecting master all future attempts to connect
12 from the script will fail.
13
14 At the end of this document there is information for some possible ways
15 how master ssh connection can be done.
16
17 ## The script
18
19 Write the following code to a file, for example `remote-notmuch.sh`.
20
21         #!/bin/bash
22
23         # http://notmuchmail.org/remoteusage/124/
24
25         set -eu
26         # To trace execution, uncomment next line.
27         #BASH_XTRACEFD=6; exec 6>>remote-errors; echo -- >&6; set -x
28
29         readonly SSH_CONTROL_SOCK='~'/.ssh/master-user@host:22
30
31         readonly notmuch=notmuch
32
33         printf -v ARGS '%q ' "$@" # bash feature
34
35         readonly SSH_CONTROL_ARGS='-oControlMaster=no -S '$SSH_CONTROL_SOCK
36
37         if ssh -q $SSH_CONTROL_ARGS 0.1 $notmuch $ARGS
38         then exit 0
39         else ev=$?
40         fi
41
42         # continuing here in case ssh exited with nonzero value.
43
44         case $* in
45          'config get user.primary_email') echo 'nobody@nowhere.invalid'; exit 0 ;;
46          'config get user.name') echo 'nobody'; exit 0 ;;
47          'count'*'--batch'*) while read line; do echo 1; done; exit 0 ;;
48          'count'*) echo 1; exit 0 ;;
49          'search-tags'*) echo 'errors'; exit 0 ;;
50          'search'*'--output=tags'*) echo 'errors'; exit 0 ;;
51         esac
52
53         # for unhandled command line print only to stderr...
54         exec >&2
55
56         if ssh $SSH_CONTROL_ARGS -O check 0.1
57         then
58          echo ' Control socket is alive but something failed during data transmission'
59          exit $ev
60         fi
61
62         echo " See`sed '1d;2d;s/.//;q' "$0"` for help"
63         #EOF
64
65 Note the `0.1` in ssh command line. It is used to avoid any opportunistic
66 behaviour ssh might do; for example if control socket is not alive ssh
67 would attempt to do it's own ssh connection to remote ssh server. As
68 address `0.1` is invalid this attempt will fail early.
69
70 ## Test
71
72 Easiest way to test this script is to run the pre-made ssh connection
73 using the following command line:
74
75         ssh -M -S '~'/.ssh/master-user@host:22 [user@]remotehost sleep 600
76
77 (replace `[user@]remotehost` with your login info). Doing this the
78 above wrapper script can be run unmodified. After the above command has
79 been run on **one terminal**, enter `chmod +x remote-notmuch.sh` in
80 **another terminal** and then test the script with
81
82         ./remote-notmuch.sh help
83
84 Note that the '~' in the ssh command line above is inside single quotes
85 for a reason. In this case shell never expand it to `$HOME` -- ssh does
86 it by not reading `$HOME` but checking the real user home directory
87 from `/etc/passwd`.  For security purposes this is just how it should
88 be.
89
90 ## Tune
91
92 The path `'~'/.ssh/master-user@host:22` might look too generic to be
93 used as is as the control socket after initial testing (but it can
94 be used). It is presented as a template for what could be configured
95 to `$HOME/.ssh/config`. For example:
96
97         Host *
98             ControlPath ~/.ssh/master-%h@%p:%r
99
100 is a good entry to be written in `$HOME/.ssh/config`;
101 [[remoteusage|remoteusage]] uses the same. Now, let's say you'd
102 make your pre-made ssh connection with command
103
104         ssh -M alice@example.org
105
106 After configuring
107 `readonly SSH_CONTROL_SOCK='~'/.ssh/master-alice@example.org:22`
108 to the `./remote-notmuch.sh` wrapper script testing with
109 `./remote-notmuch.sh help` should work fine.
110
111 An alternative strategy is to symlink the configured socket to
112 the one in ``./nottoomuch-remote.bash`` like:
113
114         ln -sfT master-alice@example.org:22 ~/.ssh/master-notmuch@remote:22
115
116 This also provides easy way to switch to another master connection without
117 need to edit this script.
118
119 ## Configure Emacs on the client computer ##
120
121 See the section *Configure Emacs on the client computer* in
122 [[remoteusage|remoteusage]] how to do this. The instructions are the same.
123
124
125 ## Creating master connection
126
127 As mentioned so many times, using this solution requires one pre-made
128 ssh connection in "master" mode. The simplest way is to dedicate one
129 terminal for the connection with shell access to the remote machine:
130
131         ssh -M -S '~'/.ssh/master-user@host:22 [user@]remotehost
132
133 One possibility is to have this dedicated terminal in a way that the
134 connection has (for example 1 hour) timeout:
135
136         ssh -M -S '~'/.ssh/master-user@host:22 [user@]remotehost sleep 3600
137
138 The above holds the terminal. The next alternative puts the command in
139 background:
140
141         ssh -f -M -S '~'/.ssh/master-user@host:22 [user@]remotehost sleep 3600
142
143 If you don't want this to timeout so soon, use a longer sleep, like 99999999
144 (8 9:s, 1157 days, a bit more than 3 years).
145
146 A more "exotic" solution would be to make a shell script running on remote
147 machine, checking/inotifying when new mail arrives. When mail arrives it
148 could send message back to local host, where a graphical client (to be written)
149 pops up on display providing info about received mail (and exiting this
150 graphical client connection to remote host is terminated).
151
152 ## Troubleshooting
153
154 If you experience strange output when using from emacs first attempt to just
155 run
156
157         ./remote-notmuch.sh help
158
159 from command line and observe output. If it looks as it should be next uncomment
160 the line
161
162         #BASH_XTRACEFD=6; exec 6>>remote-errors; echo -- >&6; set -x
163
164 in `./remote-notmuch.sh` and attempt to use it from emacs again -- and then
165 examine the contents of `remote-errors` in the working directory emacs was
166 started.