/src/dropbear/src/cli-authpasswd.c
Line | Count | Source |
1 | | /* |
2 | | * Dropbear SSH |
3 | | * |
4 | | * Copyright (c) 2002,2003 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_PASSWORD_AUTH |
33 | | |
34 | | #if DROPBEAR_CLI_ASKPASS_HELPER |
35 | | /* Returns 1 if we want to use the askpass program, 0 otherwise */ |
36 | | static int want_askpass() |
37 | | { |
38 | | char* askpass_prog = NULL; |
39 | | |
40 | | askpass_prog = getenv("SSH_ASKPASS"); |
41 | | return askpass_prog && |
42 | | ((!isatty(STDIN_FILENO) && getenv("DISPLAY") ) |
43 | | || getenv("SSH_ASKPASS_ALWAYS")); |
44 | | } |
45 | | |
46 | | /* returns a statically allocated password from a helper app, or NULL |
47 | | * on failure */ |
48 | | static char *gui_getpass(const char *prompt) { |
49 | | |
50 | | pid_t pid; |
51 | | int p[2], maxlen, len, status; |
52 | | static char buf[DROPBEAR_MAX_CLI_PASS + 1]; |
53 | | char* helper = NULL; |
54 | | |
55 | | TRACE(("enter gui_getpass")) |
56 | | |
57 | | helper = getenv("SSH_ASKPASS"); |
58 | | if (!helper) |
59 | | { |
60 | | TRACE(("leave gui_getpass: no askpass program")) |
61 | | return NULL; |
62 | | } |
63 | | |
64 | | if (pipe(p) < 0) { |
65 | | TRACE(("error creating child pipe")) |
66 | | return NULL; |
67 | | } |
68 | | |
69 | | pid = fork(); |
70 | | |
71 | | if (pid < 0) { |
72 | | TRACE(("fork error")) |
73 | | return NULL; |
74 | | } |
75 | | |
76 | | if (!pid) { |
77 | | /* child */ |
78 | | close(p[0]); |
79 | | if (dup2(p[1], STDOUT_FILENO) < 0) { |
80 | | TRACE(("error redirecting stdout")) |
81 | | exit(1); |
82 | | } |
83 | | close(p[1]); |
84 | | execlp(helper, helper, prompt, (char *)0); |
85 | | TRACE(("execlp error")) |
86 | | exit(1); |
87 | | } |
88 | | |
89 | | close(p[1]); |
90 | | maxlen = sizeof(buf); |
91 | | while (maxlen > 0) { |
92 | | len = read(p[0], buf + sizeof(buf) - maxlen, maxlen); |
93 | | if (len > 0) { |
94 | | maxlen -= len; |
95 | | } else { |
96 | | if (errno != EINTR) |
97 | | break; |
98 | | } |
99 | | } |
100 | | |
101 | | close(p[0]); |
102 | | |
103 | | while (waitpid(pid, &status, 0) < 0 && errno == EINTR) |
104 | | ; |
105 | | if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) |
106 | | return(NULL); |
107 | | |
108 | | len = sizeof(buf) - maxlen; |
109 | | buf[len] = '\0'; |
110 | | if (len > 0 && buf[len - 1] == '\n') |
111 | | buf[len - 1] = '\0'; |
112 | | |
113 | | TRACE(("leave gui_getpass")) |
114 | | return(buf); |
115 | | } |
116 | | #endif /* DROPBEAR_CLI_ASKPASS_HELPER */ |
117 | | |
118 | 0 | void cli_auth_password() { |
119 | |
|
120 | 0 | char* password = NULL; |
121 | 0 | char prompt[80]; |
122 | |
|
123 | 0 | DEBUG1(("enter cli_auth_password")) |
124 | 0 | CHECKCLEARTOWRITE(); |
125 | |
|
126 | 0 | snprintf(prompt, sizeof(prompt), "%s@%s's password: ", |
127 | 0 | cli_opts.username, cli_opts.remotehost); |
128 | | #if DROPBEAR_CLI_ASKPASS_HELPER |
129 | | if (want_askpass()) |
130 | | { |
131 | | password = gui_getpass(prompt); |
132 | | if (!password) { |
133 | | dropbear_exit("No password"); |
134 | | } |
135 | | } else |
136 | | #endif |
137 | 0 | { |
138 | 0 | password = getpass_or_cancel(prompt); |
139 | 0 | } |
140 | |
|
141 | 0 | buf_putbyte(ses.writepayload, SSH_MSG_USERAUTH_REQUEST); |
142 | |
|
143 | 0 | buf_putstring(ses.writepayload, cli_opts.username, |
144 | 0 | strlen(cli_opts.username)); |
145 | |
|
146 | 0 | buf_putstring(ses.writepayload, SSH_SERVICE_CONNECTION, |
147 | 0 | SSH_SERVICE_CONNECTION_LEN); |
148 | |
|
149 | 0 | buf_putstring(ses.writepayload, AUTH_METHOD_PASSWORD, |
150 | 0 | AUTH_METHOD_PASSWORD_LEN); |
151 | |
|
152 | 0 | buf_putbyte(ses.writepayload, 0); /* FALSE - so says the spec */ |
153 | |
|
154 | 0 | buf_putstring(ses.writepayload, password, strlen(password)); |
155 | |
|
156 | 0 | encrypt_packet(); |
157 | 0 | m_burn(password, strlen(password)); |
158 | 0 | cli_ses.is_trivial_auth = 0; |
159 | 0 | TRACE(("leave cli_auth_password")) |
160 | 0 | } |
161 | | #endif /* DROPBEAR_CLI_PASSWORD_AUTH */ |