cli-authpasswd.c 3.9 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
/*
 * Dropbear SSH
 * 
 * Copyright (c) 2002,2003 Matt Johnston
 * All rights reserved.
 * 
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 * 
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 * 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE. */

Matt Johnston's avatar
Matt Johnston committed
25
26
27
28
29
#include "includes.h"
#include "buffer.h"
#include "dbutil.h"
#include "session.h"
#include "ssh.h"
Matt Johnston's avatar
Matt Johnston committed
30
#include "runopts.h"
Matt Johnston's avatar
Matt Johnston committed
31

32
#if DROPBEAR_CLI_PASSWORD_AUTH
33

34
#if DROPBEAR_CLI_ASKPASS_HELPER
35
36
37
38
39
40
/* Returns 1 if we want to use the askpass program, 0 otherwise */
static int want_askpass()
{
	char* askpass_prog = NULL;

	askpass_prog = getenv("SSH_ASKPASS");
41
42
43
	return askpass_prog && 
		((!isatty(STDIN_FILENO) && getenv("DISPLAY") )
		 	|| getenv("SSH_ASKPASS_ALWAYS"));
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
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
}

/* returns a statically allocated password from a helper app, or NULL
 * on failure */
static char *gui_getpass(const char *prompt) {

	pid_t pid;
	int p[2], maxlen, len, status;
	static char buf[DROPBEAR_MAX_CLI_PASS + 1];
	char* helper = NULL;

	TRACE(("enter gui_getpass"))

	helper = getenv("SSH_ASKPASS");
	if (!helper)
	{
		TRACE(("leave gui_getpass: no askpass program"))
		return NULL;
	}

	if (pipe(p) < 0) {
		TRACE(("error creating child pipe"))
		return NULL;
	}

	pid = fork();

	if (pid < 0) {
		TRACE(("fork error"))
		return NULL;
	}

	if (!pid) {
		/* child */
		close(p[0]);
		if (dup2(p[1], STDOUT_FILENO) < 0) {
			TRACE(("error redirecting stdout"))
			exit(1);
		}
		close(p[1]);
		execlp(helper, helper, prompt, (char *)0);
		TRACE(("execlp error"))
		exit(1);
	}

	close(p[1]);
	maxlen = sizeof(buf);
	while (maxlen > 0) {
		len = read(p[0], buf + sizeof(buf) - maxlen, maxlen);
		if (len > 0) {
			maxlen -= len;
		} else {
			if (errno != EINTR)
				break;
		}
	}

	close(p[0]);

	while (waitpid(pid, &status, 0) < 0 && errno == EINTR)
		;
	if (!WIFEXITED(status) || WEXITSTATUS(status) != 0)
		return(NULL);

	len = sizeof(buf) - maxlen;
	buf[len] = '\0';
	if (len > 0 && buf[len - 1] == '\n')
		buf[len - 1] = '\0';

	TRACE(("leave gui_getpass"))
	return(buf);
}
116
#endif /* DROPBEAR_CLI_ASKPASS_HELPER */
117

118
void cli_auth_password() {
Matt Johnston's avatar
Matt Johnston committed
119
120

	char* password = NULL;
121
	char prompt[80];
Matt Johnston's avatar
Matt Johnston committed
122

123
	TRACE(("enter cli_auth_password"))
Matt Johnston's avatar
Matt Johnston committed
124
	CHECKCLEARTOWRITE();
125

126
127
	snprintf(prompt, sizeof(prompt), "%[email protected]%s's password: ", 
				cli_opts.username, cli_opts.remotehost);
128
#if DROPBEAR_CLI_ASKPASS_HELPER
129
	if (want_askpass())
130
	{
131
		password = gui_getpass(prompt);
132
133
134
135
		if (!password) {
			dropbear_exit("No password");
		}
	} else
136
#endif
137
	{
138
		password = getpass_or_cancel(prompt);
139
	}
Matt Johnston's avatar
Matt Johnston committed
140
141
142

	buf_putbyte(ses.writepayload, SSH_MSG_USERAUTH_REQUEST);

143
	buf_putstring(ses.writepayload, cli_opts.username,
Matt Johnston's avatar
Matt Johnston committed
144
			strlen(cli_opts.username));
Matt Johnston's avatar
Matt Johnston committed
145

146
	buf_putstring(ses.writepayload, SSH_SERVICE_CONNECTION,
Matt Johnston's avatar
Matt Johnston committed
147
148
			SSH_SERVICE_CONNECTION_LEN);

149
	buf_putstring(ses.writepayload, AUTH_METHOD_PASSWORD,
Matt Johnston's avatar
Matt Johnston committed
150
151
152
153
			AUTH_METHOD_PASSWORD_LEN);

	buf_putbyte(ses.writepayload, 0); /* FALSE - so says the spec */

154
	buf_putstring(ses.writepayload, password, strlen(password));
Matt Johnston's avatar
Matt Johnston committed
155
156
157
158

	encrypt_packet();
	m_burn(password, strlen(password));

159
	TRACE(("leave cli_auth_password"))
Matt Johnston's avatar
Matt Johnston committed
160
}
161
#endif	/* DROPBEAR_CLI_PASSWORD_AUTH */