/src/dropbear/src/cli-authinteract.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | * Dropbear SSH |
3 | | * |
4 | | * Copyright (c) 2005 Matt Johnston |
5 | | * All rights reserved. |
6 | | * |
7 | | * Permission is hereby granted, free of charge, to any person obtaining a copy |
8 | | * of this software and associated documentation files (the "Software"), to deal |
9 | | * in the Software without restriction, including without limitation the rights |
10 | | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
11 | | * copies of the Software, and to permit persons to whom the Software is |
12 | | * furnished to do so, subject to the following conditions: |
13 | | * |
14 | | * The above copyright notice and this permission notice shall be included in |
15 | | * all copies or substantial portions of the Software. |
16 | | * |
17 | | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
18 | | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
19 | | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
20 | | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
21 | | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
22 | | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE |
23 | | * SOFTWARE. */ |
24 | | |
25 | | #include "includes.h" |
26 | | #include "buffer.h" |
27 | | #include "dbutil.h" |
28 | | #include "session.h" |
29 | | #include "ssh.h" |
30 | | #include "runopts.h" |
31 | | |
32 | | #if DROPBEAR_CLI_INTERACT_AUTH |
33 | | |
34 | | static char* get_response(char* prompt) |
35 | 0 | { |
36 | 0 | FILE* tty = NULL; |
37 | 0 | char* response = NULL; |
38 | | /* not a password, but a reasonable limit */ |
39 | 0 | char buf[DROPBEAR_MAX_CLI_PASS]; |
40 | 0 | char* ret = NULL; |
41 | |
|
42 | 0 | fprintf(stderr, "%s", prompt); |
43 | |
|
44 | 0 | tty = fopen(_PATH_TTY, "r"); |
45 | 0 | if (tty) { |
46 | 0 | ret = fgets(buf, sizeof(buf), tty); |
47 | 0 | fclose(tty); |
48 | 0 | } else { |
49 | 0 | ret = fgets(buf, sizeof(buf), stdin); |
50 | 0 | } |
51 | |
|
52 | 0 | if (ret == NULL) { |
53 | 0 | response = m_strdup(""); |
54 | 0 | } else { |
55 | 0 | unsigned int buflen = strlen(buf); |
56 | | /* fgets includes newlines */ |
57 | 0 | if (buflen > 0 && buf[buflen-1] == '\n') |
58 | 0 | buf[buflen-1] = '\0'; |
59 | 0 | response = m_strdup(buf); |
60 | 0 | } |
61 | |
|
62 | 0 | m_burn(buf, sizeof(buf)); |
63 | |
|
64 | 0 | return response; |
65 | 0 | } |
66 | | |
67 | 0 | void recv_msg_userauth_info_request() { |
68 | |
|
69 | 0 | char *name = NULL; |
70 | 0 | char *instruction = NULL; |
71 | 0 | unsigned int num_prompts = 0; |
72 | 0 | unsigned int i; |
73 | |
|
74 | 0 | char *prompt = NULL; |
75 | 0 | unsigned int echo = 0; |
76 | 0 | char *response = NULL; |
77 | |
|
78 | 0 | TRACE(("enter recv_msg_recv_userauth_info_request")) |
79 | | |
80 | | /* Let the user know what password/host they are authing for */ |
81 | 0 | if (!cli_ses.interact_request_received) { |
82 | 0 | fprintf(stderr, "Login for %s@%s\n", cli_opts.username, |
83 | 0 | cli_opts.remotehost); |
84 | 0 | } |
85 | 0 | cli_ses.interact_request_received = 1; |
86 | |
|
87 | 0 | name = buf_getstring(ses.payload, NULL); |
88 | 0 | instruction = buf_getstring(ses.payload, NULL); |
89 | | |
90 | | /* language tag */ |
91 | 0 | buf_eatstring(ses.payload); |
92 | |
|
93 | 0 | num_prompts = buf_getint(ses.payload); |
94 | | |
95 | 0 | if (num_prompts >= DROPBEAR_MAX_CLI_INTERACT_PROMPTS) { |
96 | 0 | dropbear_exit("Too many prompts received for keyboard-interactive"); |
97 | 0 | } |
98 | | |
99 | | /* we'll build the response as we go */ |
100 | 0 | CHECKCLEARTOWRITE(); |
101 | 0 | buf_putbyte(ses.writepayload, SSH_MSG_USERAUTH_INFO_RESPONSE); |
102 | 0 | buf_putint(ses.writepayload, num_prompts); |
103 | |
|
104 | 0 | if (strlen(name) > 0) { |
105 | 0 | cleantext(name); |
106 | 0 | fprintf(stderr, "%s", name); |
107 | 0 | } |
108 | 0 | m_free(name); |
109 | |
|
110 | 0 | if (strlen(instruction) > 0) { |
111 | 0 | cleantext(instruction); |
112 | 0 | fprintf(stderr, "%s", instruction); |
113 | 0 | } |
114 | 0 | m_free(instruction); |
115 | |
|
116 | 0 | for (i = 0; i < num_prompts; i++) { |
117 | 0 | unsigned int response_len = 0; |
118 | 0 | cli_ses.is_trivial_auth = 0; |
119 | 0 | prompt = buf_getstring(ses.payload, NULL); |
120 | 0 | cleantext(prompt); |
121 | |
|
122 | 0 | echo = buf_getbool(ses.payload); |
123 | |
|
124 | 0 | if (!echo) { |
125 | 0 | char* p = getpass_or_cancel(prompt); |
126 | 0 | response = m_strdup(p); |
127 | 0 | m_burn(p, strlen(p)); |
128 | 0 | } else { |
129 | 0 | response = get_response(prompt); |
130 | 0 | } |
131 | |
|
132 | 0 | response_len = strlen(response); |
133 | 0 | buf_putstring(ses.writepayload, response, response_len); |
134 | 0 | m_burn(response, response_len); |
135 | 0 | m_free(prompt); |
136 | 0 | m_free(response); |
137 | 0 | } |
138 | |
|
139 | 0 | encrypt_packet(); |
140 | | |
141 | |
|
142 | 0 | TRACE(("leave recv_msg_recv_userauth_info_request")) |
143 | 0 | } |
144 | | |
145 | 0 | void cli_auth_interactive() { |
146 | |
|
147 | 0 | TRACE(("enter cli_auth_interactive")) |
148 | 0 | CHECKCLEARTOWRITE(); |
149 | |
|
150 | 0 | buf_putbyte(ses.writepayload, SSH_MSG_USERAUTH_REQUEST); |
151 | | |
152 | | /* username */ |
153 | 0 | buf_putstring(ses.writepayload, cli_opts.username, |
154 | 0 | strlen(cli_opts.username)); |
155 | | |
156 | | /* service name */ |
157 | 0 | buf_putstring(ses.writepayload, SSH_SERVICE_CONNECTION, |
158 | 0 | SSH_SERVICE_CONNECTION_LEN); |
159 | | |
160 | | /* method */ |
161 | 0 | buf_putstring(ses.writepayload, AUTH_METHOD_INTERACT, |
162 | 0 | AUTH_METHOD_INTERACT_LEN); |
163 | | |
164 | | /* empty language tag */ |
165 | 0 | buf_putstring(ses.writepayload, "", 0); |
166 | | |
167 | | /* empty submethods */ |
168 | 0 | buf_putstring(ses.writepayload, "", 0); |
169 | |
|
170 | 0 | encrypt_packet(); |
171 | 0 | cli_ses.interact_request_received = 0; |
172 | |
|
173 | 0 | TRACE(("leave cli_auth_interactive")) |
174 | |
|
175 | 0 | } |
176 | | #endif /* DROPBEAR_CLI_INTERACT_AUTH */ |