comparison cli-authpasswd.c @ 173:257f09a63dab

* add SSH_ASKPASS support (based on patch from Paul Whittaker * don't exit if setnonblocking() fails with "not supported by device" (allows redirection from /dev/null)
author Matt Johnston <matt@ucc.asn.au>
date Mon, 28 Feb 2005 13:01:00 +0000
parents 0cfba3034be5
children efbaf6b03837
comparison
equal deleted inserted replaced
172:3e49d8d18005 173:257f09a63dab
28 #include "session.h" 28 #include "session.h"
29 #include "ssh.h" 29 #include "ssh.h"
30 #include "runopts.h" 30 #include "runopts.h"
31 31
32 #ifdef ENABLE_CLI_PASSWORD_AUTH 32 #ifdef ENABLE_CLI_PASSWORD_AUTH
33
34 #ifdef ENABLE_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 && !isatty(STDIN_FILENO) && getenv("DISPLAY");
42 }
43
44 /* returns a statically allocated password from a helper app, or NULL
45 * on failure */
46 static char *gui_getpass(const char *prompt) {
47
48 pid_t pid;
49 int p[2], maxlen, len, status;
50 static char buf[DROPBEAR_MAX_CLI_PASS + 1];
51 char* helper = NULL;
52
53 TRACE(("enter gui_getpass"))
54
55 helper = getenv("SSH_ASKPASS");
56 if (!helper)
57 {
58 TRACE(("leave gui_getpass: no askpass program"))
59 return NULL;
60 }
61
62 if (pipe(p) < 0) {
63 TRACE(("error creating child pipe"))
64 return NULL;
65 }
66
67 pid = fork();
68
69 if (pid < 0) {
70 TRACE(("fork error"))
71 return NULL;
72 }
73
74 if (!pid) {
75 /* child */
76 close(p[0]);
77 if (dup2(p[1], STDOUT_FILENO) < 0) {
78 TRACE(("error redirecting stdout"))
79 exit(1);
80 }
81 close(p[1]);
82 execlp(helper, helper, prompt, (char *)0);
83 TRACE(("execlp error"))
84 exit(1);
85 }
86
87 close(p[1]);
88 maxlen = sizeof(buf);
89 while (maxlen > 0) {
90 len = read(p[0], buf + sizeof(buf) - maxlen, maxlen);
91 if (len > 0) {
92 maxlen -= len;
93 } else {
94 if (errno != EINTR)
95 break;
96 }
97 }
98
99 close(p[0]);
100
101 while (waitpid(pid, &status, 0) < 0 && errno == EINTR)
102 ;
103 if (!WIFEXITED(status) || WEXITSTATUS(status) != 0)
104 return(NULL);
105
106 len = sizeof(buf) - maxlen;
107 buf[len] = '\0';
108 if (len > 0 && buf[len - 1] == '\n')
109 buf[len - 1] = '\0';
110
111 TRACE(("leave gui_getpass"))
112 return(buf);
113 }
114 #endif /* ENABLE_CLI_ASKPASS_HELPER */
115
33 int cli_auth_password() { 116 int cli_auth_password() {
34 117
35 char* password = NULL; 118 char* password = NULL;
119
36 TRACE(("enter cli_auth_password")) 120 TRACE(("enter cli_auth_password"))
121 CHECKCLEARTOWRITE();
37 122
38 CHECKCLEARTOWRITE(); 123 #ifdef ENABLE_CLI_ASKPASS_HELPER
39 password = getpass("Password: "); 124 if (want_askpass())
125 password = gui_getpass("Password: ");
126 else
127 #endif
128 password = getpass("Password: ");
129
130 if (password == NULL)
131 return 0;
40 132
41 buf_putbyte(ses.writepayload, SSH_MSG_USERAUTH_REQUEST); 133 buf_putbyte(ses.writepayload, SSH_MSG_USERAUTH_REQUEST);
42 134
43 buf_putstring(ses.writepayload, cli_opts.username, 135 buf_putstring(ses.writepayload, cli_opts.username,
44 strlen(cli_opts.username)); 136 strlen(cli_opts.username));
58 150
59 TRACE(("leave cli_auth_password")) 151 TRACE(("leave cli_auth_password"))
60 return 1; /* Password auth can always be tried */ 152 return 1; /* Password auth can always be tried */
61 153
62 } 154 }
63 #endif 155 #endif /* ENABLE_CLI_PASSWORD_AUTH */