2 * Copyright (c) 2000 Markus Friedl. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
13 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
14 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
15 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
16 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
17 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
18 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
19 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
20 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
21 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
22 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 RCSID("$OpenBSD: sshconnect2.c,v 1.63 2001/04/04 00:06:54 markus Exp $");
28 #include <openssl/bn.h>
29 #include <openssl/md5.h>
30 #include <openssl/dh.h>
31 #include <openssl/hmac.h>
44 #include "myproposal.h"
46 #include "sshconnect.h"
58 extern char *client_version_string;
59 extern char *server_version_string;
60 extern Options options;
66 u_char *session_id2 = NULL;
67 int session_id2_len = 0;
70 struct sockaddr *xxx_hostaddr;
75 check_host_key_callback(Key *hostkey)
77 check_host_key(xxx_host, xxx_hostaddr, hostkey,
78 options.user_hostfile2, options.system_hostfile2);
83 ssh_kex2(char *host, struct sockaddr *hostaddr)
88 xxx_hostaddr = hostaddr;
90 if (options.ciphers == (char *)-1) {
91 log("No valid ciphers for protocol version 2 given, using defaults.");
92 options.ciphers = NULL;
94 if (options.ciphers != NULL) {
95 myproposal[PROPOSAL_ENC_ALGS_CTOS] =
96 myproposal[PROPOSAL_ENC_ALGS_STOC] = options.ciphers;
98 myproposal[PROPOSAL_ENC_ALGS_CTOS] =
99 compat_cipher_proposal(myproposal[PROPOSAL_ENC_ALGS_CTOS]);
100 myproposal[PROPOSAL_ENC_ALGS_STOC] =
101 compat_cipher_proposal(myproposal[PROPOSAL_ENC_ALGS_STOC]);
102 if (options.compression) {
103 myproposal[PROPOSAL_COMP_ALGS_CTOS] =
104 myproposal[PROPOSAL_COMP_ALGS_STOC] = "zlib";
106 myproposal[PROPOSAL_COMP_ALGS_CTOS] =
107 myproposal[PROPOSAL_COMP_ALGS_STOC] = "none";
109 if (options.macs != NULL) {
110 myproposal[PROPOSAL_MAC_ALGS_CTOS] =
111 myproposal[PROPOSAL_MAC_ALGS_STOC] = options.macs;
114 kex = kex_start(myproposal);
115 kex->client_version_string=client_version_string;
116 kex->server_version_string=server_version_string;
117 kex->check_host_key=&check_host_key_callback;
121 /* start key exchange */
122 dispatch_run(DISPATCH_BLOCK, &kex->newkeys, kex);
124 session_id2 = kex->session_id;
125 session_id2_len = kex->session_id_len;
128 /* send 1st encrypted/maced/compressed message */
129 packet_start(SSH2_MSG_IGNORE);
130 packet_put_cstring("markus");
134 debug("done: ssh_kex2.");
141 typedef struct Authctxt Authctxt;
142 typedef struct Authmethod Authmethod;
144 typedef int sign_cb_fn(
145 Authctxt *authctxt, Key *key,
146 u_char **sigp, int *lenp, u_char *data, int datalen);
149 const char *server_user;
152 AuthenticationConnection *agent;
157 sign_cb_fn *last_key_sign;
161 char *name; /* string to compare against server's list */
162 int (*userauth)(Authctxt *authctxt);
163 int *enabled; /* flag in option struct that enables method */
164 int *batch_flag; /* flag in option struct that disables method */
167 void input_userauth_success(int type, int plen, void *ctxt);
168 void input_userauth_failure(int type, int plen, void *ctxt);
169 void input_userauth_banner(int type, int plen, void *ctxt);
170 void input_userauth_error(int type, int plen, void *ctxt);
171 void input_userauth_info_req(int type, int plen, void *ctxt);
172 void input_userauth_pk_ok(int type, int plen, void *ctxt);
174 int userauth_none(Authctxt *authctxt);
175 int userauth_pubkey(Authctxt *authctxt);
176 int userauth_passwd(Authctxt *authctxt);
177 int userauth_kbdint(Authctxt *authctxt);
179 void userauth(Authctxt *authctxt, char *authlist);
182 sign_and_send_pubkey(Authctxt *authctxt, Key *k,
183 sign_cb_fn *sign_callback);
184 void clear_auth_state(Authctxt *authctxt);
186 Authmethod *authmethod_get(char *authlist);
187 Authmethod *authmethod_lookup(const char *name);
188 char *authmethods_get(void);
190 Authmethod authmethods[] = {
193 &options.pubkey_authentication,
197 &options.password_authentication,
198 &options.batch_mode},
199 {"keyboard-interactive",
201 &options.kbd_interactive_authentication,
202 &options.batch_mode},
207 {NULL, NULL, NULL, NULL}
211 ssh_userauth2(const char *server_user, char *host)
218 if (options.challenge_reponse_authentication)
219 options.kbd_interactive_authentication = 1;
221 debug("send SSH2_MSG_SERVICE_REQUEST");
222 packet_start(SSH2_MSG_SERVICE_REQUEST);
223 packet_put_cstring("ssh-userauth");
226 type = packet_read(&plen);
227 if (type != SSH2_MSG_SERVICE_ACCEPT) {
228 fatal("denied SSH2_MSG_SERVICE_ACCEPT: %d", type);
230 if (packet_remaining() > 0) {
231 char *reply = packet_get_string(&plen);
232 debug("service_accept: %s", reply);
235 debug("buggy server: service_accept w/o service");
238 debug("got SSH2_MSG_SERVICE_ACCEPT");
240 if (options.preferred_authentications == NULL)
241 options.preferred_authentications = authmethods_get();
243 /* setup authentication context */
244 authctxt.agent = ssh_get_authentication_connection();
245 authctxt.server_user = server_user;
246 authctxt.host = host;
247 authctxt.service = "ssh-connection"; /* service name */
248 authctxt.success = 0;
249 authctxt.method = authmethod_lookup("none");
250 authctxt.authlist = NULL;
251 if (authctxt.method == NULL)
252 fatal("ssh_userauth2: internal error: cannot send userauth none request");
254 /* initial userauth request */
255 userauth_none(&authctxt);
257 //dispatch_init(&input_userauth_error);
258 for (i = 50; i <= 254; i++) {
259 dispatch_set(i, &input_userauth_error);
261 dispatch_set(SSH2_MSG_USERAUTH_SUCCESS, &input_userauth_success);
262 dispatch_set(SSH2_MSG_USERAUTH_FAILURE, &input_userauth_failure);
263 dispatch_set(SSH2_MSG_USERAUTH_BANNER, &input_userauth_banner);
264 dispatch_run(DISPATCH_BLOCK, &authctxt.success, &authctxt); /* loop until success */
266 if (authctxt.agent != NULL)
267 ssh_close_authentication_connection(authctxt.agent);
269 debug("ssh-userauth2 successful: method %s", authctxt.method->name);
272 userauth(Authctxt *authctxt, char *authlist)
274 if (authlist == NULL) {
275 authlist = authctxt->authlist;
277 if (authctxt->authlist)
278 xfree(authctxt->authlist);
279 authctxt->authlist = authlist;
282 Authmethod *method = authmethod_get(authlist);
284 fatal("Permission denied (%s).", authlist);
285 authctxt->method = method;
286 if (method->userauth(authctxt) != 0) {
287 debug2("we sent a %s packet, wait for reply", method->name);
290 debug2("we did not send a packet, disable method");
291 method->enabled = NULL;
296 input_userauth_error(int type, int plen, void *ctxt)
298 fatal("input_userauth_error: bad message during authentication: "
302 input_userauth_banner(int type, int plen, void *ctxt)
305 debug3("input_userauth_banner");
306 msg = packet_get_string(NULL);
307 lang = packet_get_string(NULL);
308 fprintf(stderr, "%s", msg);
313 input_userauth_success(int type, int plen, void *ctxt)
315 Authctxt *authctxt = ctxt;
316 if (authctxt == NULL)
317 fatal("input_userauth_success: no authentication context");
318 if (authctxt->authlist)
319 xfree(authctxt->authlist);
320 clear_auth_state(authctxt);
321 authctxt->success = 1; /* break out */
324 input_userauth_failure(int type, int plen, void *ctxt)
326 Authctxt *authctxt = ctxt;
327 char *authlist = NULL;
330 if (authctxt == NULL)
331 fatal("input_userauth_failure: no authentication context");
333 authlist = packet_get_string(NULL);
334 partial = packet_get_char();
338 log("Authenticated with partial success.");
339 debug("authentications that can continue: %s", authlist);
341 clear_auth_state(authctxt);
342 userauth(authctxt, authlist);
345 input_userauth_pk_ok(int type, int plen, void *ctxt)
347 Authctxt *authctxt = ctxt;
350 int alen, blen, pktype, sent = 0;
351 char *pkalg, *pkblob, *fp;
353 if (authctxt == NULL)
354 fatal("input_userauth_pk_ok: no authentication context");
355 if (datafellows & SSH_BUG_PKOK) {
356 /* this is similar to SSH_BUG_PKAUTH */
357 debug2("input_userauth_pk_ok: SSH_BUG_PKOK");
358 pkblob = packet_get_string(&blen);
360 buffer_append(&b, pkblob, blen);
361 pkalg = buffer_get_string(&b, &alen);
364 pkalg = packet_get_string(&alen);
365 pkblob = packet_get_string(&blen);
369 debug("input_userauth_pk_ok: pkalg %s blen %d lastkey %p hint %d",
370 pkalg, blen, authctxt->last_key, authctxt->last_key_hint);
373 if (authctxt->last_key == NULL ||
374 authctxt->last_key_sign == NULL) {
375 debug("no last key or no sign cb");
378 if ((pktype = key_type_from_name(pkalg)) == KEY_UNSPEC) {
379 debug("unknown pkalg %s", pkalg);
382 if ((key = key_from_blob(pkblob, blen)) == NULL) {
383 debug("no key from blob. pkalg %s", pkalg);
386 fp = key_fingerprint(key, SSH_FP_MD5, SSH_FP_HEX);
387 debug2("input_userauth_pk_ok: fp %s", fp);
389 if (!key_equal(key, authctxt->last_key)) {
390 debug("key != last_key");
393 sent = sign_and_send_pubkey(authctxt, key,
394 authctxt->last_key_sign);
403 clear_auth_state(authctxt);
404 dispatch_set(SSH2_MSG_USERAUTH_PK_OK, NULL);
406 /* try another method if we did not send a packet*/
408 userauth(authctxt, NULL);
413 userauth_none(Authctxt *authctxt)
415 /* initial userauth request */
416 packet_start(SSH2_MSG_USERAUTH_REQUEST);
417 packet_put_cstring(authctxt->server_user);
418 packet_put_cstring(authctxt->service);
419 packet_put_cstring(authctxt->method->name);
425 userauth_passwd(Authctxt *authctxt)
427 static int attempt = 0;
431 if (attempt++ >= options.number_of_password_prompts)
435 error("Permission denied, please try again.");
437 snprintf(prompt, sizeof(prompt), "%.30s@%.128s's password: ",
438 authctxt->server_user, authctxt->host);
439 password = read_passphrase(prompt, 0);
440 packet_start(SSH2_MSG_USERAUTH_REQUEST);
441 packet_put_cstring(authctxt->server_user);
442 packet_put_cstring(authctxt->service);
443 packet_put_cstring(authctxt->method->name);
445 packet_put_cstring(password);
446 memset(password, 0, strlen(password));
448 packet_inject_ignore(64);
454 clear_auth_state(Authctxt *authctxt)
456 /* XXX clear authentication state */
457 if (authctxt->last_key != NULL && authctxt->last_key_hint == -1) {
458 debug3("clear_auth_state: key_free %p", authctxt->last_key);
459 key_free(authctxt->last_key);
461 authctxt->last_key = NULL;
462 authctxt->last_key_hint = -2;
463 authctxt->last_key_sign = NULL;
467 sign_and_send_pubkey(Authctxt *authctxt, Key *k, sign_cb_fn *sign_callback)
470 u_char *blob, *signature;
476 debug3("sign_and_send_pubkey");
478 if (key_to_blob(k, &blob, &bloblen) == 0) {
479 /* we cannot handle this key */
480 debug3("sign_and_send_pubkey: cannot handle key");
483 /* data to be signed */
485 if (datafellows & SSH_OLD_SESSIONID) {
486 buffer_append(&b, session_id2, session_id2_len);
487 skip = session_id2_len;
489 buffer_put_string(&b, session_id2, session_id2_len);
490 skip = buffer_len(&b);
492 buffer_put_char(&b, SSH2_MSG_USERAUTH_REQUEST);
493 buffer_put_cstring(&b, authctxt->server_user);
494 buffer_put_cstring(&b,
495 datafellows & SSH_BUG_PKSERVICE ?
498 if (datafellows & SSH_BUG_PKAUTH) {
499 buffer_put_char(&b, have_sig);
501 buffer_put_cstring(&b, authctxt->method->name);
502 buffer_put_char(&b, have_sig);
503 buffer_put_cstring(&b, key_ssh_name(k));
505 buffer_put_string(&b, blob, bloblen);
507 /* generate signature */
508 ret = (*sign_callback)(authctxt, k, &signature, &slen,
509 buffer_ptr(&b), buffer_len(&b));
518 if (datafellows & SSH_BUG_PKSERVICE) {
520 buffer_append(&b, session_id2, session_id2_len);
521 skip = session_id2_len;
522 buffer_put_char(&b, SSH2_MSG_USERAUTH_REQUEST);
523 buffer_put_cstring(&b, authctxt->server_user);
524 buffer_put_cstring(&b, authctxt->service);
525 buffer_put_cstring(&b, authctxt->method->name);
526 buffer_put_char(&b, have_sig);
527 if (!(datafellows & SSH_BUG_PKAUTH))
528 buffer_put_cstring(&b, key_ssh_name(k));
529 buffer_put_string(&b, blob, bloblen);
533 /* append signature */
534 buffer_put_string(&b, signature, slen);
537 /* skip session id and packet type */
538 if (buffer_len(&b) < skip + 1)
539 fatal("userauth_pubkey: internal error");
540 buffer_consume(&b, skip + 1);
542 /* put remaining data from buffer into packet */
543 packet_start(SSH2_MSG_USERAUTH_REQUEST);
544 packet_put_raw(buffer_ptr(&b), buffer_len(&b));
552 send_pubkey_test(Authctxt *authctxt, Key *k, sign_cb_fn *sign_callback,
556 int bloblen, have_sig = 0;
558 debug3("send_pubkey_test");
560 if (key_to_blob(k, &blob, &bloblen) == 0) {
561 /* we cannot handle this key */
562 debug3("send_pubkey_test: cannot handle key");
565 /* register callback for USERAUTH_PK_OK message */
566 authctxt->last_key_sign = sign_callback;
567 authctxt->last_key_hint = hint;
568 authctxt->last_key = k;
569 dispatch_set(SSH2_MSG_USERAUTH_PK_OK, &input_userauth_pk_ok);
571 packet_start(SSH2_MSG_USERAUTH_REQUEST);
572 packet_put_cstring(authctxt->server_user);
573 packet_put_cstring(authctxt->service);
574 packet_put_cstring(authctxt->method->name);
575 packet_put_char(have_sig);
576 if (!(datafellows & SSH_BUG_PKAUTH))
577 packet_put_cstring(key_ssh_name(k));
578 packet_put_string(blob, bloblen);
585 load_identity_file(char *filename)
588 char prompt[300], *passphrase;
592 if (stat(filename, &st) < 0) {
593 debug3("no such identity: %s", filename);
596 private = key_load_private_type(KEY_UNSPEC, filename, "", NULL);
597 if (private == NULL) {
598 if (options.batch_mode)
600 snprintf(prompt, sizeof prompt,
601 "Enter passphrase for key '%.100s': ", filename);
602 for (i = 0; i < options.number_of_password_prompts; i++) {
603 passphrase = read_passphrase(prompt, 0);
604 if (strcmp(passphrase, "") != 0) {
605 private = key_load_private_type(KEY_UNSPEC, filename,
609 debug2("no passphrase given, try next key");
612 memset(passphrase, 0, strlen(passphrase));
614 if (private != NULL || quit)
616 debug2("bad passphrase given, try again...");
623 identity_sign_cb(Authctxt *authctxt, Key *key, u_char **sigp, int *lenp,
624 u_char *data, int datalen)
629 idx = authctxt->last_key_hint;
632 private = load_identity_file(options.identity_files[idx]);
635 ret = key_sign(private, sigp, lenp, data, datalen);
640 int agent_sign_cb(Authctxt *authctxt, Key *key, u_char **sigp, int *lenp,
641 u_char *data, int datalen)
643 return ssh_agent_sign(authctxt->agent, key, sigp, lenp, data, datalen);
646 int key_sign_cb(Authctxt *authctxt, Key *key, u_char **sigp, int *lenp,
647 u_char *data, int datalen)
649 return key_sign(key, sigp, lenp, data, datalen);
653 userauth_pubkey_agent(Authctxt *authctxt)
655 static int called = 0;
661 if (ssh_get_num_identities(authctxt->agent, 2) == 0)
662 debug2("userauth_pubkey_agent: no keys at all");
665 k = ssh_get_next_identity(authctxt->agent, &comment, 2);
667 debug2("userauth_pubkey_agent: no more keys");
669 debug("userauth_pubkey_agent: testing agent key %s", comment);
671 ret = send_pubkey_test(authctxt, k, agent_sign_cb, -1);
676 debug2("userauth_pubkey_agent: no message sent");
681 userauth_pubkey(Authctxt *authctxt)
688 if (authctxt->agent != NULL) {
690 sent = userauth_pubkey_agent(authctxt);
691 } while(!sent && authctxt->agent->howmany > 0);
693 while (!sent && idx < options.num_identity_files) {
694 key = options.identity_keys[idx];
695 filename = options.identity_files[idx];
697 debug("try privkey: %s", filename);
698 key = load_identity_file(filename);
700 sent = sign_and_send_pubkey(authctxt, key,
704 } else if (key->type != KEY_RSA1) {
705 debug("try pubkey: %s", filename);
706 sent = send_pubkey_test(authctxt, key,
707 identity_sign_cb, idx);
715 * Send userauth request message specifying keyboard-interactive method.
718 userauth_kbdint(Authctxt *authctxt)
720 static int attempt = 0;
722 if (attempt++ >= options.number_of_password_prompts)
725 debug2("userauth_kbdint");
726 packet_start(SSH2_MSG_USERAUTH_REQUEST);
727 packet_put_cstring(authctxt->server_user);
728 packet_put_cstring(authctxt->service);
729 packet_put_cstring(authctxt->method->name);
730 packet_put_cstring(""); /* lang */
731 packet_put_cstring(options.kbd_interactive_devices ?
732 options.kbd_interactive_devices : "");
735 dispatch_set(SSH2_MSG_USERAUTH_INFO_REQUEST, &input_userauth_info_req);
740 * parse INFO_REQUEST, prompt user and send INFO_RESPONSE
743 input_userauth_info_req(int type, int plen, void *ctxt)
745 Authctxt *authctxt = ctxt;
746 char *name, *inst, *lang, *prompt, *response;
747 u_int num_prompts, i;
750 debug2("input_userauth_info_req");
752 if (authctxt == NULL)
753 fatal("input_userauth_info_req: no authentication context");
755 name = packet_get_string(NULL);
756 inst = packet_get_string(NULL);
757 lang = packet_get_string(NULL);
758 if (strlen(name) > 0)
760 if (strlen(inst) > 0)
766 num_prompts = packet_get_int();
768 * Begin to build info response packet based on prompts requested.
769 * We commit to providing the correct number of responses, so if
770 * further on we run into a problem that prevents this, we have to
771 * be sure and clean this up and send a correct error response.
773 packet_start(SSH2_MSG_USERAUTH_INFO_RESPONSE);
774 packet_put_int(num_prompts);
776 for (i = 0; i < num_prompts; i++) {
777 prompt = packet_get_string(NULL);
778 echo = packet_get_char();
780 response = cli_prompt(prompt, echo);
782 packet_put_cstring(response);
783 memset(response, 0, strlen(response));
787 packet_done(); /* done with parsing incoming message. */
789 packet_inject_ignore(64);
793 /* find auth method */
796 * given auth method name, if configurable options permit this method fill
797 * in auth_ident field and return true, otherwise return false.
800 authmethod_is_enabled(Authmethod *method)
804 /* return false if options indicate this method is disabled */
805 if (method->enabled == NULL || *method->enabled == 0)
807 /* return false if batch mode is enabled but method needs interactive mode */
808 if (method->batch_flag != NULL && *method->batch_flag != 0)
814 authmethod_lookup(const char *name)
816 Authmethod *method = NULL;
818 for (method = authmethods; method->name != NULL; method++)
819 if (strcmp(name, method->name) == 0)
821 debug2("Unrecognized authentication method name: %s", name ? name : "NULL");
825 /* XXX internal state */
826 static Authmethod *current = NULL;
827 static char *supported = NULL;
828 static char *preferred = NULL;
830 * Given the authentication method list sent by the server, return the
831 * next method we should try. If the server initially sends a nil list,
832 * use a built-in default list.
835 authmethod_get(char *authlist)
841 /* Use a suitable default if we're passed a nil list. */
842 if (authlist == NULL || strlen(authlist) == 0)
843 authlist = options.preferred_authentications;
845 if (supported == NULL || strcmp(authlist, supported) != 0) {
846 debug3("start over, passed a different list %s", authlist);
847 if (supported != NULL)
849 supported = xstrdup(authlist);
850 preferred = options.preferred_authentications;
851 debug3("preferred %s", preferred);
853 } else if (current != NULL && authmethod_is_enabled(current))
857 if ((name = match_list(preferred, supported, &next)) == NULL) {
858 debug("no more auth methods to try");
863 debug3("authmethod_lookup %s", name);
864 debug3("remaining preferred: %s", preferred);
865 if ((current = authmethod_lookup(name)) != NULL &&
866 authmethod_is_enabled(current)) {
867 debug3("authmethod_is_enabled %s", name);
868 debug("next auth method to try is %s", name);
877 authmethods_get(void)
879 Authmethod *method = NULL;
883 for (method = authmethods; method->name != NULL; method++) {
884 if (authmethod_is_enabled(method)) {
886 strlcat(buf, DELIM, sizeof buf);
887 strlcat(buf, method->name, sizeof buf);