1
- #! /usr/bin/env bash
1
+ #! /usr/bin/sh
2
2
# Usage:
3
3
# conductor.sh token
4
4
5
- set -euo pipefail
6
-
7
5
# Global variables
8
6
login_shell=" "
9
7
shell_name=" "
@@ -32,7 +30,7 @@ die() {
32
30
it2ssh_verbose=0
33
31
34
32
log () {
35
- if [[ $it2ssh_verbose == 0 ] ]; then
33
+ if [ " $it2ssh_verbose " -eq 0 ]; then
36
34
return
37
35
fi
38
36
printf " [$$ ] %s: %s\n" $( date +%H:%M:%S) " $* " >> /tmp/it2ssh.log
@@ -63,16 +61,16 @@ first_word() {
63
61
drop_first_word () {
64
62
local input=" $1 "
65
63
log drop first word from: " $input "
66
- if [[ $ input == * " " * ] ]; then
64
+ if [ " ${ input#* } " != " $input " ]; then
67
65
printf " %s" " ${input#* } "
68
66
fi
69
67
}
70
68
71
- if command -v base64 > /dev/null 2> /dev/null ; then
69
+ if command -v base64 > /dev/null 2>&1 ; then
72
70
log " found base64 command"
73
71
base64_encode () { command base64 | command tr -d \\ n\\ r; }
74
72
base64_decode () { command base64 -d; }
75
- elif command -v b64encode > /dev/null 2> /dev/null ; then
73
+ elif command -v b64encode > /dev/null 2>&1 ; then
76
74
log " found b64encode, b64decode commands"
77
75
base64_encode () { command b64encode - | command sed ' 1d;$d' | command tr -d \\ n\\ r; }
78
76
base64_decode () { command fold -w 76 | command b64decode -r; }
@@ -99,10 +97,10 @@ parse_passwd_record() {
99
97
# sets $login_shell as a side effect.
100
98
# returns if it looks executable.
101
99
login_shell_is_ok () {
102
- log login_shell_is_ok
100
+ log login_shell_is_ok with arg " $1 "
103
101
[ -n " $1 " ] && login_shell=$( echo $1 | parse_passwd_record)
104
102
[ -n " $login_shell " -a -x " $login_shell " ] && return 0
105
- log " login shell of $login_shell is ok "
103
+ log " login shell of $login_shell is bad "
106
104
return 1
107
105
}
108
106
@@ -126,7 +124,7 @@ detect_python() {
126
124
[ -z " $python " ] && python=$( command -v python2)
127
125
[ -z " $python " ] && python=$( command -v python)
128
126
if [ -z " $python " -o ! -x " $python " ]; then python=" " ; return 1; fi
129
- log no python
127
+ log found python at $ python
130
128
return 0
131
129
}
132
130
@@ -143,7 +141,7 @@ detect_perl() {
143
141
perl_detected=" 1"
144
142
perl=$( command -v perl)
145
143
if [ -z " $perl " -o ! -x " $perl " ]; then perl=" " ; return 1; fi
146
- log no perl
144
+ log found perl at $ perl
147
145
return 0
148
146
}
149
147
@@ -158,8 +156,8 @@ using_shell_env() {
158
156
159
157
guess_login_shell () {
160
158
[ -n " $login_shell " ] || using_getent || using_id || using_python || using_perl || using_passwd || using_shell_env || login_shell=" sh"
161
- printf " %s" ${ login_shell}
162
- log login shell is ${ login_shell}
159
+ printf " %s" " $ login_shell"
160
+ log login shell is " $ login_shell"
163
161
}
164
162
165
163
# Execute login shell
@@ -175,17 +173,17 @@ execute_with_perl() {
175
173
176
174
execute_with_python () {
177
175
if detect_python; then
178
- log execute login shell using python
179
- exec " $perl " " -e" " exec {'$login_shell '} '-$shell_name '"
176
+ log execute login shell: " $python " " -c" " import os; os.execlp('$login_shell ', '-' '$shell_name ')"
180
177
exec " $python " " -c" " import os; os.execlp('$login_shell ', '-' '$shell_name ')"
181
178
fi
182
179
return 1
183
180
}
184
181
185
182
exec_login_shell () {
186
183
local login_shell=${1}
184
+ shell_name=$( command basename " $login_shell " )
187
185
188
- log exec_login_shell " $login_shell "
186
+ log exec_login_shell " $login_shell " with name " $shell_name "
189
187
190
188
# We need to pass the first argument to the executed program with a leading -
191
189
# to make sure the shell executes as a login shell. Note that not all shells
@@ -198,6 +196,7 @@ exec_login_shell() {
198
196
log failed, just run it with -l
199
197
# TODO - this is complicated, come back and do it later.
200
198
# execute_sh_with_posix_env
199
+ unset RCOUNT
201
200
exec " $login_shell " " -l"
202
201
log failed completely
203
202
printf " %s\n" " Could not execute the shell $login_shell as a login shell" > /dev/stderr
@@ -214,7 +213,7 @@ conductor_cmd_exec_login_shell() {
214
213
}
215
214
216
215
really_exec_login_shell () {
217
- exec_login_shell $( command basename $( guess_login_shell) )
216
+ exec_login_shell $( guess_login_shell)
218
217
}
219
218
220
219
# Set an environment variable.
@@ -244,24 +243,24 @@ conductor_cmd_runpython() {
244
243
245
244
really_run_python () {
246
245
log really_run_python
247
- rce='
246
+ unset RCOUNT
247
+ exec python3 << ENDOFSCRIPT
248
248
import os
249
249
import sys
250
250
tty_path = os.ttyname(sys.stdout.fileno())
251
251
sys.stdin = open(tty_path, "r")
252
252
try:
253
- print(f"\033]135;:{os.getpid()}\033\\\033]135;:end ' " $boundary " ' r 0\033\\", end="", flush=True)
253
+ print(f"\033]135;:{os.getpid()}\033\\ \033]135;:end $boundary r 0\033\\ \\ ", end="", flush=True)
254
254
program=""
255
255
for line in sys.stdin:
256
256
if line.rstrip() == "EOF":
257
257
exec(program)
258
- print(f"\033]135;:unhook\033\\", end="", flush=True)
258
+ print(f"\033]135;:unhook\033\\\\ ", end="", flush=True)
259
259
break
260
260
program += line
261
261
except Exception as e:
262
262
print(e)
263
- '
264
- exec python3 <<< " $rce"
263
+ ENDOFSCRIPT
265
264
log " unexpected return from exec"
266
265
exit 0
267
266
}
@@ -275,20 +274,21 @@ really_run() {
275
274
fi
276
275
log exec " $SHELL " -c " $* "
277
276
printf " \e]135;:"
277
+ unset RCOUNT
278
278
exec " $SHELL " -c " $* "
279
279
printf " \e\\ "
280
280
}
281
281
282
282
conductor_cmd_shell () {
283
283
log conductor_cmd_shell
284
- if [ " $# " -lt 2 ]; then
284
+ if [ " $# " -lt 1 ]; then
285
285
log bad args
286
286
(exit 1)
287
287
return
288
288
fi
289
289
printf " \e]135;:"
290
290
set +e
291
- set +o pipefail
291
+ log will run $*
292
292
$*
293
293
printf " \e\\ "
294
294
}
@@ -357,8 +357,9 @@ conductor_cmd_eval() {
357
357
local mydir=$( mktemp -d " ${TMPDIR:-/ tmp/ } it2ssh.XXXXXXXXXXXX" )
358
358
local file=" $mydir /it2ssh-eval"
359
359
log " mydir=$mydir tmpdir=${TMPDIR:-/ tmp/ } file=$file "
360
- base64_decode <<< " $b64" > " $file "
361
- source " $file "
360
+ printf " %s" " $b64 " | base64_decode > " $file "
361
+ log will source " $file " with content $( cat " $file " )
362
+ . " $file "
362
363
rm -f " $file "
363
364
log " $file " finished executing
364
365
}
@@ -370,6 +371,17 @@ write() {
370
371
# Main Loop
371
372
# ###############################################################################
372
373
374
+ randomnumber () {
375
+ if [ -z " ${RCOUNT} " ]; then
376
+ export RCOUNT=0
377
+ else
378
+ export RCOUNT=$(( RCOUNT + 1 ))
379
+ fi
380
+
381
+ printf " %s." $RCOUNT
382
+ awk ' BEGIN { srand(); print int(rand() * 65536)""int(rand() * 65536)""int(rand() * 65536)""int(rand() * 65536) }'
383
+ }
384
+
373
385
handle_command () {
374
386
local unparsed=${1}
375
387
@@ -380,39 +392,38 @@ handle_command() {
380
392
local args=$( drop_first_word " ${unparsed} " )
381
393
log args is $args
382
394
383
- local boundary=" ${RANDOM}${RANDOM}${RANDOM}${RANDOM} "
395
+ local boundary=$( randomnumber )
384
396
write begin $boundary
385
397
log invoke $cmd_name with arguments $args
386
398
set +e
387
- set +o pipefail
388
- if [[ $( type -t conductor_cmd_${cmd_name} ) == function ]]; then
399
+ if ( LC_ALL=C type conductor_cmd_${cmd_name} 2> /dev/null | head -n 1 | grep -q function ); then
389
400
conductor_cmd_${cmd_name} $args
390
401
else
391
402
write " bad command ${cmd_name} "
392
403
false
393
404
fi
394
- if [[ $run_python == 1 ] ]; then
405
+ if [ $run_python = 1 ]; then
395
406
really_run_python " $boundary "
396
407
fi
397
408
write end $boundary $? r
398
- if [[ $quit == 1 ]]; then
409
+ if [ $quit = 1 ]; then
410
+ log quitting
399
411
exit 0
400
412
fi
401
- if [[ $exec_shell == 1 ] ]; then
413
+ if [ $exec_shell = 1 ]; then
402
414
log successfully executed the login shell. Unhook.
403
415
write unhook
404
416
cleanup
405
417
really_exec_login_shell
406
418
fi
407
- if [[ $run_cmd == 1 ] ]; then
419
+ if [ $run_cmd = 1 ]; then
408
420
log successfully ran a command. Unhook.
409
421
write unhook
410
422
cleanup
411
423
really_run $args
412
424
fi
413
425
414
426
set -e
415
- set -o pipefail
416
427
}
417
428
418
429
iterate () {
@@ -438,7 +449,7 @@ drain_stdin() {
438
449
while :
439
450
do
440
451
key=" $( printf x; dd bs=1 count=1 2> /dev/null; printf x) "
441
- if [[ " $key " == " xx" ] ]; then
452
+ if [ " $key " = " xx" ]; then
442
453
log " done draining"
443
454
break
444
455
fi
@@ -448,10 +459,10 @@ drain_stdin() {
448
459
}
449
460
450
461
main () {
451
- local token=$( base64_decode <<< $1 )
452
- local uniqueid=$( base64_decode <<< $2 )
453
- local booleanargs=$( base64_decode <<< $3 )
454
- local sshargs=$( base64_decode <<< $4 )
462
+ local token=$( printf " %s " " $1 " | base64_decode )
463
+ local uniqueid=$( printf " %s " " $2 " | base64_decode )
464
+ local booleanargs=$( printf " %s " " $3 " | base64_decode )
465
+ local sshargs=$( printf " %s " " $4 " | base64_decode )
455
466
456
467
log starting with token $token
457
468
log $( env)
0 commit comments