aboutsummaryrefslogtreecommitdiffstats
path: root/lib/ssh/test/ssh_test_cli.erl
blob: cd9ad5f2ff192adf1c97525e10a29d682d8fee0a (plain) (blame)
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
-module(ssh_test_cli).

-export([init/1, terminate/2, handle_ssh_msg/2, handle_msg/2]).

-record(state, {
	  type,
	  id, 
	  ref,
	  port
	 }).

init([Type]) ->
    {ok, #state{type = Type}}.

handle_msg({ssh_channel_up, Id, Ref}, S) ->
    User = get_ssh_user(Ref), 
    ok = ssh_connection:send(Ref,
			     Id,
			     << "\r\nYou are accessing a dummy, type \"q\" to exit\r\n\n" >>),
    Port = run_portprog(User, S#state.type),
    {ok, S#state{port = Port, id = Id, ref = Ref}};

handle_msg({Port, {data, Data}}, S = #state{port = Port}) ->
    ok = ssh_connection:send(S#state.ref, S#state.id, Data),
    {ok, S};
handle_msg({Port, {exit_status, Exit}}, S = #state{port = Port}) ->
    if 
        S#state.type =:= cli ->
            ok = ssh_connection:send(S#state.ref, S#state.id, << "\r\n" >>);
        true ->
            ok
    end,
    ok = ssh_connection:exit_status(S#state.ref, S#state.id, Exit),
    {stop, S#state.id, S#state{port = undefined}};
handle_msg({'EXIT', Port, _}, S = #state{port = Port}) ->
    ok = ssh_connection:exit_status(S#state.ref, S#state.id, 0),
    {stop, S#state.id, S#state{port = undefined}};
handle_msg(_Msg, S) ->
    {ok, S}.

handle_ssh_msg({ssh_cm, Ref, {data, Id, _Type, <<"q">>}}, S) ->
    ssh_connection:send_eof(Ref, Id),
    {stop, Id,  S};
handle_ssh_msg({ssh_cm, _Ref, {data, _Id, _Type, Data}}, S) ->
    true = port_command(S#state.port, Data),
    {ok, S};
handle_ssh_msg({ssh_cm, _, {eof, _}}, S) ->
    {ok, S};
handle_ssh_msg({ssh_cm, Ref, {env, Id, WantReply, _Var, _Value}}, S) ->
    ok = ssh_connection:reply_request(Ref, WantReply, success, Id),
    {ok, S};
handle_ssh_msg({ssh_cm, Ref, {pty, Id, WantReply, _Terminal_jox}}, S) ->
    ok = ssh_connection:reply_request(Ref, WantReply, success, Id),
    {ok, S};
handle_ssh_msg({ssh_cm, Ref, {shell, Id, WantReply}}, S) ->
    ok = ssh_connection:reply_request(Ref, WantReply, success, Id),
    {ok, S};
handle_ssh_msg({ssh_cm, _, {signal, _, _}}, S) ->
    %% Ignore signals according to RFC 4254 section 6.9.
    {ok, S};
handle_ssh_msg({ssh_cm, _,
	{window_change, _Id, _Width, _Height, _Pixw, _PixH}}, S) ->
    {ok, S};
handle_ssh_msg({ssh_cm, _, {exit_signal, Id, _, _, _}},
	       S) ->
    {stop, Id,  S}.

terminate(_Why, _S) ->
    nop.

run_portprog(User, cli) ->
    Pty_bin = os:find_executable("cat"), 
    open_port({spawn_executable, Pty_bin},
	      [stream, {cd, "/tmp"}, {env, [{"USER", User}]},
	       {args, []}, binary,
	       exit_status, use_stdio, stderr_to_stdout]).

get_ssh_user(Ref) ->
    [{user, User}] = ssh:connection_info(Ref, [user]),
    User.