]> andersk Git - openssh.git/blob - sshconnect2.c
- markus@cvs.openbsd.org 2001/11/07 16:03:17
[openssh.git] / sshconnect2.c
1 /*
2  * Copyright (c) 2000 Markus Friedl.  All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
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.
12  *
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.
23  */
24
25 #include "includes.h"
26 RCSID("$OpenBSD: sshconnect2.c,v 1.85 2001/11/07 16:03:17 markus Exp $");
27
28 #include <openssl/bn.h>
29 #include <openssl/md5.h>
30 #include <openssl/dh.h>
31 #include <openssl/hmac.h>
32
33 #include "ssh.h"
34 #include "ssh2.h"
35 #include "xmalloc.h"
36 #include "rsa.h"
37 #include "buffer.h"
38 #include "packet.h"
39 #include "uidswap.h"
40 #include "compat.h"
41 #include "bufaux.h"
42 #include "cipher.h"
43 #include "kex.h"
44 #include "myproposal.h"
45 #include "key.h"
46 #include "sshconnect.h"
47 #include "authfile.h"
48 #include "dh.h"
49 #include "authfd.h"
50 #include "log.h"
51 #include "readconf.h"
52 #include "readpass.h"
53 #include "match.h"
54 #include "dispatch.h"
55 #include "canohost.h"
56
57 /* import */
58 extern char *client_version_string;
59 extern char *server_version_string;
60 extern Options options;
61
62 /*
63  * SSH2 key exchange
64  */
65
66 u_char *session_id2 = NULL;
67 int session_id2_len = 0;
68
69 char *xxx_host;
70 struct sockaddr *xxx_hostaddr;
71
72 Kex *xxx_kex = NULL;
73
74 static int
75 verify_host_key_callback(Key *hostkey)
76 {
77         if (verify_host_key(xxx_host, xxx_hostaddr, hostkey) == -1)
78                 fatal("Host key verification failed.");
79         return 0;
80 }
81
82 void
83 ssh_kex2(char *host, struct sockaddr *hostaddr)
84 {
85         Kex *kex;
86
87         xxx_host = host;
88         xxx_hostaddr = hostaddr;
89
90         if (options.ciphers == (char *)-1) {
91                 log("No valid ciphers for protocol version 2 given, using defaults.");
92                 options.ciphers = NULL;
93         }
94         if (options.ciphers != NULL) {
95                 myproposal[PROPOSAL_ENC_ALGS_CTOS] =
96                 myproposal[PROPOSAL_ENC_ALGS_STOC] = options.ciphers;
97         }
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";
105         } else {
106                 myproposal[PROPOSAL_COMP_ALGS_CTOS] =
107                 myproposal[PROPOSAL_COMP_ALGS_STOC] = "none";
108         }
109         if (options.macs != NULL) {
110                 myproposal[PROPOSAL_MAC_ALGS_CTOS] =
111                 myproposal[PROPOSAL_MAC_ALGS_STOC] = options.macs;
112         }
113         if (options.hostkeyalgorithms != NULL)
114                 myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] =
115                     options.hostkeyalgorithms;
116
117         /* start key exchange */
118         kex = kex_setup(myproposal);
119         kex->client_version_string=client_version_string;
120         kex->server_version_string=server_version_string;
121         kex->verify_host_key=&verify_host_key_callback;
122
123         xxx_kex = kex;
124
125         dispatch_run(DISPATCH_BLOCK, &kex->done, kex);
126
127         session_id2 = kex->session_id;
128         session_id2_len = kex->session_id_len;
129
130 #ifdef DEBUG_KEXDH
131         /* send 1st encrypted/maced/compressed message */
132         packet_start(SSH2_MSG_IGNORE);
133         packet_put_cstring("markus");
134         packet_send();
135         packet_write_wait();
136 #endif
137         debug("done: ssh_kex2.");
138 }
139
140 /*
141  * Authenticate user
142  */
143
144 typedef struct Authctxt Authctxt;
145 typedef struct Authmethod Authmethod;
146
147 typedef int sign_cb_fn(
148     Authctxt *authctxt, Key *key,
149     u_char **sigp, int *lenp, u_char *data, int datalen);
150
151 struct Authctxt {
152         const char *server_user;
153         const char *local_user;
154         const char *host;
155         const char *service;
156         Authmethod *method;
157         int success;
158         char *authlist;
159         /* pubkey */
160         Key *last_key;
161         sign_cb_fn *last_key_sign;
162         int last_key_hint;
163         AuthenticationConnection *agent;
164         /* hostbased */
165         Key **keys;
166         int nkeys;
167         /* kbd-interactive */
168         int info_req_seen;
169 };
170 struct Authmethod {
171         char    *name;          /* string to compare against server's list */
172         int     (*userauth)(Authctxt *authctxt);
173         int     *enabled;       /* flag in option struct that enables method */
174         int     *batch_flag;    /* flag in option struct that disables method */
175 };
176
177 void    input_userauth_success(int type, int plen, void *ctxt);
178 void    input_userauth_failure(int type, int plen, void *ctxt);
179 void    input_userauth_banner(int type, int plen, void *ctxt);
180 void    input_userauth_error(int type, int plen, void *ctxt);
181 void    input_userauth_info_req(int type, int plen, void *ctxt);
182 void    input_userauth_pk_ok(int type, int plen, void *ctxt);
183
184 int     userauth_none(Authctxt *authctxt);
185 int     userauth_pubkey(Authctxt *authctxt);
186 int     userauth_passwd(Authctxt *authctxt);
187 int     userauth_kbdint(Authctxt *authctxt);
188 int     userauth_hostbased(Authctxt *authctxt);
189
190 void    userauth(Authctxt *authctxt, char *authlist);
191
192 static int sign_and_send_pubkey(Authctxt *, Key *, sign_cb_fn *);
193 static void clear_auth_state(Authctxt *);
194
195 static Authmethod *authmethod_get(char *authlist);
196 static Authmethod *authmethod_lookup(const char *name);
197 static char *authmethods_get(void);
198
199 Authmethod authmethods[] = {
200         {"hostbased",
201                 userauth_hostbased,
202                 &options.hostbased_authentication,
203                 NULL},
204         {"publickey",
205                 userauth_pubkey,
206                 &options.pubkey_authentication,
207                 NULL},
208         {"keyboard-interactive",
209                 userauth_kbdint,
210                 &options.kbd_interactive_authentication,
211                 &options.batch_mode},
212         {"password",
213                 userauth_passwd,
214                 &options.password_authentication,
215                 &options.batch_mode},
216         {"none",
217                 userauth_none,
218                 NULL,
219                 NULL},
220         {NULL, NULL, NULL, NULL}
221 };
222
223 void
224 ssh_userauth2(const char *local_user, const char *server_user, char *host,
225     Key **keys, int nkeys)
226 {
227         Authctxt authctxt;
228         int type;
229         int plen;
230
231         if (options.challenge_response_authentication)
232                 options.kbd_interactive_authentication = 1;
233
234         debug("send SSH2_MSG_SERVICE_REQUEST");
235         packet_start(SSH2_MSG_SERVICE_REQUEST);
236         packet_put_cstring("ssh-userauth");
237         packet_send();
238         packet_write_wait();
239         type = packet_read(&plen);
240         if (type != SSH2_MSG_SERVICE_ACCEPT) {
241                 fatal("denied SSH2_MSG_SERVICE_ACCEPT: %d", type);
242         }
243         if (packet_remaining() > 0) {
244                 char *reply = packet_get_string(&plen);
245                 debug("service_accept: %s", reply);
246                 xfree(reply);
247         } else {
248                 debug("buggy server: service_accept w/o service");
249         }
250         packet_done();
251         debug("got SSH2_MSG_SERVICE_ACCEPT");
252
253         if (options.preferred_authentications == NULL)
254                 options.preferred_authentications = authmethods_get();
255
256         /* setup authentication context */
257         memset(&authctxt, 0, sizeof(authctxt));
258         authctxt.agent = ssh_get_authentication_connection();
259         authctxt.server_user = server_user;
260         authctxt.local_user = local_user;
261         authctxt.host = host;
262         authctxt.service = "ssh-connection";            /* service name */
263         authctxt.success = 0;
264         authctxt.method = authmethod_lookup("none");
265         authctxt.authlist = NULL;
266         authctxt.keys = keys;
267         authctxt.nkeys = nkeys;
268         authctxt.info_req_seen = 0;
269         if (authctxt.method == NULL)
270                 fatal("ssh_userauth2: internal error: cannot send userauth none request");
271
272         /* initial userauth request */
273         userauth_none(&authctxt);
274
275         dispatch_init(&input_userauth_error);
276         dispatch_set(SSH2_MSG_USERAUTH_SUCCESS, &input_userauth_success);
277         dispatch_set(SSH2_MSG_USERAUTH_FAILURE, &input_userauth_failure);
278         dispatch_set(SSH2_MSG_USERAUTH_BANNER, &input_userauth_banner);
279         dispatch_run(DISPATCH_BLOCK, &authctxt.success, &authctxt);     /* loop until success */
280
281         if (authctxt.agent != NULL)
282                 ssh_close_authentication_connection(authctxt.agent);
283
284         debug("ssh-userauth2 successful: method %s", authctxt.method->name);
285 }
286 void
287 userauth(Authctxt *authctxt, char *authlist)
288 {
289         if (authlist == NULL) {
290                 authlist = authctxt->authlist;
291         } else {
292                 if (authctxt->authlist)
293                         xfree(authctxt->authlist);
294                 authctxt->authlist = authlist;
295         }
296         for (;;) {
297                 Authmethod *method = authmethod_get(authlist);
298                 if (method == NULL)
299                         fatal("Permission denied (%s).", authlist);
300                 authctxt->method = method;
301                 if (method->userauth(authctxt) != 0) {
302                         debug2("we sent a %s packet, wait for reply", method->name);
303                         break;
304                 } else {
305                         debug2("we did not send a packet, disable method");
306                         method->enabled = NULL;
307                 }
308         }
309 }
310 void
311 input_userauth_error(int type, int plen, void *ctxt)
312 {
313         fatal("input_userauth_error: bad message during authentication: "
314            "type %d", type);
315 }
316 void
317 input_userauth_banner(int type, int plen, void *ctxt)
318 {
319         char *msg, *lang;
320         debug3("input_userauth_banner");
321         msg = packet_get_string(NULL);
322         lang = packet_get_string(NULL);
323         fprintf(stderr, "%s", msg);
324         xfree(msg);
325         xfree(lang);
326 }
327 void
328 input_userauth_success(int type, int plen, void *ctxt)
329 {
330         Authctxt *authctxt = ctxt;
331         if (authctxt == NULL)
332                 fatal("input_userauth_success: no authentication context");
333         if (authctxt->authlist)
334                 xfree(authctxt->authlist);
335         clear_auth_state(authctxt);
336         authctxt->success = 1;                  /* break out */
337 }
338 void
339 input_userauth_failure(int type, int plen, void *ctxt)
340 {
341         Authctxt *authctxt = ctxt;
342         char *authlist = NULL;
343         int partial;
344
345         if (authctxt == NULL)
346                 fatal("input_userauth_failure: no authentication context");
347
348         authlist = packet_get_string(NULL);
349         partial = packet_get_char();
350         packet_done();
351
352         if (partial != 0)
353                 log("Authenticated with partial success.");
354         debug("authentications that can continue: %s", authlist);
355
356         clear_auth_state(authctxt);
357         userauth(authctxt, authlist);
358 }
359 void
360 input_userauth_pk_ok(int type, int plen, void *ctxt)
361 {
362         Authctxt *authctxt = ctxt;
363         Key *key = NULL;
364         Buffer b;
365         int alen, blen, sent = 0;
366         char *pkalg, *pkblob, *fp;
367
368         if (authctxt == NULL)
369                 fatal("input_userauth_pk_ok: no authentication context");
370         if (datafellows & SSH_BUG_PKOK) {
371                 /* this is similar to SSH_BUG_PKAUTH */
372                 debug2("input_userauth_pk_ok: SSH_BUG_PKOK");
373                 pkblob = packet_get_string(&blen);
374                 buffer_init(&b);
375                 buffer_append(&b, pkblob, blen);
376                 pkalg = buffer_get_string(&b, &alen);
377                 buffer_free(&b);
378         } else {
379                 pkalg = packet_get_string(&alen);
380                 pkblob = packet_get_string(&blen);
381         }
382         packet_done();
383
384         debug("input_userauth_pk_ok: pkalg %s blen %d lastkey %p hint %d",
385             pkalg, blen, authctxt->last_key, authctxt->last_key_hint);
386
387         do {
388                 if (authctxt->last_key == NULL ||
389                     authctxt->last_key_sign == NULL) {
390                         debug("no last key or no sign cb");
391                         break;
392                 }
393                 if (key_type_from_name(pkalg) == KEY_UNSPEC) {
394                         debug("unknown pkalg %s", pkalg);
395                         break;
396                 }
397                 if ((key = key_from_blob(pkblob, blen)) == NULL) {
398                         debug("no key from blob. pkalg %s", pkalg);
399                         break;
400                 }
401                 fp = key_fingerprint(key, SSH_FP_MD5, SSH_FP_HEX);
402                 debug2("input_userauth_pk_ok: fp %s", fp);
403                 xfree(fp);
404                 if (!key_equal(key, authctxt->last_key)) {
405                         debug("key != last_key");
406                         break;
407                 }
408                 sent = sign_and_send_pubkey(authctxt, key,
409                    authctxt->last_key_sign);
410         } while(0);
411
412         if (key != NULL)
413                 key_free(key);
414         xfree(pkalg);
415         xfree(pkblob);
416
417         /* unregister */
418         clear_auth_state(authctxt);
419         dispatch_set(SSH2_MSG_USERAUTH_PK_OK, NULL);
420
421         /* try another method if we did not send a packet*/
422         if (sent == 0)
423                 userauth(authctxt, NULL);
424
425 }
426
427 int
428 userauth_none(Authctxt *authctxt)
429 {
430         /* initial userauth request */
431         packet_start(SSH2_MSG_USERAUTH_REQUEST);
432         packet_put_cstring(authctxt->server_user);
433         packet_put_cstring(authctxt->service);
434         packet_put_cstring(authctxt->method->name);
435         packet_send();
436         return 1;
437 }
438
439 int
440 userauth_passwd(Authctxt *authctxt)
441 {
442         static int attempt = 0;
443         char prompt[80];
444         char *password;
445
446         if (attempt++ >= options.number_of_password_prompts)
447                 return 0;
448
449         if(attempt != 1)
450                 error("Permission denied, please try again.");
451
452         snprintf(prompt, sizeof(prompt), "%.30s@%.128s's password: ",
453             authctxt->server_user, authctxt->host);
454         password = read_passphrase(prompt, 0);
455         packet_start(SSH2_MSG_USERAUTH_REQUEST);
456         packet_put_cstring(authctxt->server_user);
457         packet_put_cstring(authctxt->service);
458         packet_put_cstring(authctxt->method->name);
459         packet_put_char(0);
460         packet_put_cstring(password);
461         memset(password, 0, strlen(password));
462         xfree(password);
463         packet_add_padding(64);
464         packet_send();
465         return 1;
466 }
467
468 static void
469 clear_auth_state(Authctxt *authctxt)
470 {
471         /* XXX clear authentication state */
472         if (authctxt->last_key != NULL && authctxt->last_key_hint == -1) {
473                 debug3("clear_auth_state: key_free %p", authctxt->last_key);
474                 key_free(authctxt->last_key);
475         }
476         authctxt->last_key = NULL;
477         authctxt->last_key_hint = -2;
478         authctxt->last_key_sign = NULL;
479 }
480
481 static int
482 sign_and_send_pubkey(Authctxt *authctxt, Key *k, sign_cb_fn *sign_callback)
483 {
484         Buffer b;
485         u_char *blob, *signature;
486         int bloblen, slen;
487         int skip = 0;
488         int ret = -1;
489         int have_sig = 1;
490
491         debug3("sign_and_send_pubkey");
492
493         if (key_to_blob(k, &blob, &bloblen) == 0) {
494                 /* we cannot handle this key */
495                 debug3("sign_and_send_pubkey: cannot handle key");
496                 return 0;
497         }
498         /* data to be signed */
499         buffer_init(&b);
500         if (datafellows & SSH_OLD_SESSIONID) {
501                 buffer_append(&b, session_id2, session_id2_len);
502                 skip = session_id2_len;
503         } else {
504                 buffer_put_string(&b, session_id2, session_id2_len);
505                 skip = buffer_len(&b);
506         }
507         buffer_put_char(&b, SSH2_MSG_USERAUTH_REQUEST);
508         buffer_put_cstring(&b, authctxt->server_user);
509         buffer_put_cstring(&b,
510             datafellows & SSH_BUG_PKSERVICE ?
511             "ssh-userauth" :
512             authctxt->service);
513         if (datafellows & SSH_BUG_PKAUTH) {
514                 buffer_put_char(&b, have_sig);
515         } else {
516                 buffer_put_cstring(&b, authctxt->method->name);
517                 buffer_put_char(&b, have_sig);
518                 buffer_put_cstring(&b, key_ssh_name(k));
519         }
520         buffer_put_string(&b, blob, bloblen);
521
522         /* generate signature */
523         ret = (*sign_callback)(authctxt, k, &signature, &slen,
524             buffer_ptr(&b), buffer_len(&b));
525         if (ret == -1) {
526                 xfree(blob);
527                 buffer_free(&b);
528                 return 0;
529         }
530 #ifdef DEBUG_PK
531         buffer_dump(&b);
532 #endif
533         if (datafellows & SSH_BUG_PKSERVICE) {
534                 buffer_clear(&b);
535                 buffer_append(&b, session_id2, session_id2_len);
536                 skip = session_id2_len;
537                 buffer_put_char(&b, SSH2_MSG_USERAUTH_REQUEST);
538                 buffer_put_cstring(&b, authctxt->server_user);
539                 buffer_put_cstring(&b, authctxt->service);
540                 buffer_put_cstring(&b, authctxt->method->name);
541                 buffer_put_char(&b, have_sig);
542                 if (!(datafellows & SSH_BUG_PKAUTH))
543                         buffer_put_cstring(&b, key_ssh_name(k));
544                 buffer_put_string(&b, blob, bloblen);
545         }
546         xfree(blob);
547
548         /* append signature */
549         buffer_put_string(&b, signature, slen);
550         xfree(signature);
551
552         /* skip session id and packet type */
553         if (buffer_len(&b) < skip + 1)
554                 fatal("userauth_pubkey: internal error");
555         buffer_consume(&b, skip + 1);
556
557         /* put remaining data from buffer into packet */
558         packet_start(SSH2_MSG_USERAUTH_REQUEST);
559         packet_put_raw(buffer_ptr(&b), buffer_len(&b));
560         buffer_free(&b);
561         packet_send();
562
563         return 1;
564 }
565
566 static int
567 send_pubkey_test(Authctxt *authctxt, Key *k, sign_cb_fn *sign_callback,
568     int hint)
569 {
570         u_char *blob;
571         int bloblen, have_sig = 0;
572
573         debug3("send_pubkey_test");
574
575         if (key_to_blob(k, &blob, &bloblen) == 0) {
576                 /* we cannot handle this key */
577                 debug3("send_pubkey_test: cannot handle key");
578                 return 0;
579         }
580         /* register callback for USERAUTH_PK_OK message */
581         authctxt->last_key_sign = sign_callback;
582         authctxt->last_key_hint = hint;
583         authctxt->last_key = k;
584         dispatch_set(SSH2_MSG_USERAUTH_PK_OK, &input_userauth_pk_ok);
585
586         packet_start(SSH2_MSG_USERAUTH_REQUEST);
587         packet_put_cstring(authctxt->server_user);
588         packet_put_cstring(authctxt->service);
589         packet_put_cstring(authctxt->method->name);
590         packet_put_char(have_sig);
591         if (!(datafellows & SSH_BUG_PKAUTH))
592                 packet_put_cstring(key_ssh_name(k));
593         packet_put_string(blob, bloblen);
594         xfree(blob);
595         packet_send();
596         return 1;
597 }
598
599 static Key *
600 load_identity_file(char *filename)
601 {
602         Key *private;
603         char prompt[300], *passphrase;
604         int quit, i;
605         struct stat st;
606
607         if (stat(filename, &st) < 0) {
608                 debug3("no such identity: %s", filename);
609                 return NULL;
610         }
611         private = key_load_private_type(KEY_UNSPEC, filename, "", NULL);
612         if (private == NULL) {
613                 if (options.batch_mode)
614                         return NULL;
615                 snprintf(prompt, sizeof prompt,
616                      "Enter passphrase for key '%.100s': ", filename);
617                 for (i = 0; i < options.number_of_password_prompts; i++) {
618                         passphrase = read_passphrase(prompt, 0);
619                         if (strcmp(passphrase, "") != 0) {
620                                 private = key_load_private_type(KEY_UNSPEC, filename,
621                                     passphrase, NULL);
622                                 quit = 0;
623                         } else {
624                                 debug2("no passphrase given, try next key");
625                                 quit = 1;
626                         }
627                         memset(passphrase, 0, strlen(passphrase));
628                         xfree(passphrase);
629                         if (private != NULL || quit)
630                                 break;
631                         debug2("bad passphrase given, try again...");
632                 }
633         }
634         return private;
635 }
636
637 static int
638 identity_sign_cb(Authctxt *authctxt, Key *key, u_char **sigp, int *lenp,
639     u_char *data, int datalen)
640 {
641         Key *private;
642         int idx, ret;
643
644         idx = authctxt->last_key_hint;
645         if (idx < 0)
646                 return -1;
647
648         /* private key is stored in external hardware */
649         if (options.identity_keys[idx]->flags & KEY_FLAG_EXT) 
650                 return key_sign(options.identity_keys[idx], sigp, lenp, data, datalen);
651
652         private = load_identity_file(options.identity_files[idx]);
653         if (private == NULL)
654                 return -1;
655         ret = key_sign(private, sigp, lenp, data, datalen);
656         key_free(private);
657         return ret;
658 }
659
660 static int
661 agent_sign_cb(Authctxt *authctxt, Key *key, u_char **sigp, int *lenp,
662     u_char *data, int datalen)
663 {
664         return ssh_agent_sign(authctxt->agent, key, sigp, lenp, data, datalen);
665 }
666
667 static int
668 key_sign_cb(Authctxt *authctxt, Key *key, u_char **sigp, int *lenp,
669     u_char *data, int datalen)
670 {
671         return key_sign(key, sigp, lenp, data, datalen);
672 }
673
674 static int
675 userauth_pubkey_agent(Authctxt *authctxt)
676 {
677         static int called = 0;
678         int ret = 0;
679         char *comment;
680         Key *k;
681
682         if (called == 0) {
683                 if (ssh_get_num_identities(authctxt->agent, 2) == 0)
684                         debug2("userauth_pubkey_agent: no keys at all");
685                 called = 1;
686         }
687         k = ssh_get_next_identity(authctxt->agent, &comment, 2);
688         if (k == NULL) {
689                 debug2("userauth_pubkey_agent: no more keys");
690         } else {
691                 debug("userauth_pubkey_agent: testing agent key %s", comment);
692                 xfree(comment);
693                 ret = send_pubkey_test(authctxt, k, agent_sign_cb, -1);
694                 if (ret == 0)
695                         key_free(k);
696         }
697         if (ret == 0)
698                 debug2("userauth_pubkey_agent: no message sent");
699         return ret;
700 }
701
702 int
703 userauth_pubkey(Authctxt *authctxt)
704 {
705         static int idx = 0;
706         int sent = 0;
707         Key *key;
708         char *filename;
709
710         if (authctxt->agent != NULL) {
711                 do {
712                         sent = userauth_pubkey_agent(authctxt);
713                 } while(!sent && authctxt->agent->howmany > 0);
714         }
715         while (!sent && idx < options.num_identity_files) {
716                 key = options.identity_keys[idx];
717                 filename = options.identity_files[idx];
718                 if (key == NULL) {
719                         debug("try privkey: %s", filename);
720                         key = load_identity_file(filename);
721                         if (key != NULL) {
722                                 sent = sign_and_send_pubkey(authctxt, key,
723                                     key_sign_cb);
724                                 key_free(key);
725                         }
726                 } else if (key->type != KEY_RSA1) {
727                         debug("try pubkey: %s", filename);
728                         sent = send_pubkey_test(authctxt, key,
729                             identity_sign_cb, idx);
730                 }
731                 idx++;
732         }
733         return sent;
734 }
735
736 /*
737  * Send userauth request message specifying keyboard-interactive method.
738  */
739 int
740 userauth_kbdint(Authctxt *authctxt)
741 {
742         static int attempt = 0;
743
744         if (attempt++ >= options.number_of_password_prompts)
745                 return 0;
746         /* disable if no SSH2_MSG_USERAUTH_INFO_REQUEST has been seen */
747         if (attempt > 1 && !authctxt->info_req_seen) {
748                 debug3("userauth_kbdint: disable: no info_req_seen");
749                 dispatch_set(SSH2_MSG_USERAUTH_INFO_REQUEST, NULL);
750                 return 0;
751         }
752
753         debug2("userauth_kbdint");
754         packet_start(SSH2_MSG_USERAUTH_REQUEST);
755         packet_put_cstring(authctxt->server_user);
756         packet_put_cstring(authctxt->service);
757         packet_put_cstring(authctxt->method->name);
758         packet_put_cstring("");                                 /* lang */
759         packet_put_cstring(options.kbd_interactive_devices ?
760             options.kbd_interactive_devices : "");
761         packet_send();
762
763         dispatch_set(SSH2_MSG_USERAUTH_INFO_REQUEST, &input_userauth_info_req);
764         return 1;
765 }
766
767 /*
768  * parse INFO_REQUEST, prompt user and send INFO_RESPONSE
769  */
770 void
771 input_userauth_info_req(int type, int plen, void *ctxt)
772 {
773         Authctxt *authctxt = ctxt;
774         char *name, *inst, *lang, *prompt, *response;
775         u_int num_prompts, i;
776         int echo = 0;
777
778         debug2("input_userauth_info_req");
779
780         if (authctxt == NULL)
781                 fatal("input_userauth_info_req: no authentication context");
782
783         authctxt->info_req_seen = 1;
784
785         name = packet_get_string(NULL);
786         inst = packet_get_string(NULL);
787         lang = packet_get_string(NULL);
788         if (strlen(name) > 0)
789                 log("%s", name);
790         if (strlen(inst) > 0)
791                 log("%s", inst);
792         xfree(name);
793         xfree(inst);
794         xfree(lang);
795
796         num_prompts = packet_get_int();
797         /*
798          * Begin to build info response packet based on prompts requested.
799          * We commit to providing the correct number of responses, so if
800          * further on we run into a problem that prevents this, we have to
801          * be sure and clean this up and send a correct error response.
802          */
803         packet_start(SSH2_MSG_USERAUTH_INFO_RESPONSE);
804         packet_put_int(num_prompts);
805
806         debug2("input_userauth_info_req: num_prompts %d", num_prompts);
807         for (i = 0; i < num_prompts; i++) {
808                 prompt = packet_get_string(NULL);
809                 echo = packet_get_char();
810
811                 response = read_passphrase(prompt, echo ? RP_ECHO : 0);
812
813                 packet_put_cstring(response);
814                 memset(response, 0, strlen(response));
815                 xfree(response);
816                 xfree(prompt);
817         }
818         packet_done(); /* done with parsing incoming message. */
819
820         packet_add_padding(64);
821         packet_send();
822 }
823
824 /*
825  * this will be move to an external program (ssh-keysign) ASAP. ssh-keysign
826  * will be setuid-root and the sbit can be removed from /usr/bin/ssh.
827  */
828 int
829 userauth_hostbased(Authctxt *authctxt)
830 {
831         Key *private = NULL;
832         Buffer b;
833         u_char *signature, *blob;
834         char *chost, *pkalg, *p;
835         const char *service;
836         u_int blen, slen;
837         int ok, i, len, found = 0;
838
839         /* check for a useful key */
840         for (i = 0; i < authctxt->nkeys; i++) {
841                 private = authctxt->keys[i];
842                 if (private && private->type != KEY_RSA1) {
843                         found = 1;
844                         /* we take and free the key */
845                         authctxt->keys[i] = NULL;
846                         break;
847                 }
848         }
849         if (!found) {
850                 debug("userauth_hostbased: no more client hostkeys");
851                 return 0;
852         }
853         if (key_to_blob(private, &blob, &blen) == 0) {
854                 key_free(private);
855                 return 0;
856         }
857         /* figure out a name for the client host */
858         p = get_local_name(packet_get_connection_in());
859         if (p == NULL) {
860                 error("userauth_hostbased: cannot get local ipaddr/name");
861                 key_free(private);
862                 return 0;
863         }
864         len = strlen(p) + 2;
865         chost = xmalloc(len);
866         strlcpy(chost, p, len);
867         strlcat(chost, ".", len);
868         debug2("userauth_hostbased: chost %s", chost);
869
870         service = datafellows & SSH_BUG_HBSERVICE ? "ssh-userauth" :
871             authctxt->service;
872         pkalg = xstrdup(key_ssh_name(private));
873         buffer_init(&b);
874         /* construct data */
875         buffer_put_string(&b, session_id2, session_id2_len);
876         buffer_put_char(&b, SSH2_MSG_USERAUTH_REQUEST);
877         buffer_put_cstring(&b, authctxt->server_user);
878         buffer_put_cstring(&b, service);
879         buffer_put_cstring(&b, authctxt->method->name);
880         buffer_put_cstring(&b, pkalg);
881         buffer_put_string(&b, blob, blen);
882         buffer_put_cstring(&b, chost);
883         buffer_put_cstring(&b, authctxt->local_user);
884 #ifdef DEBUG_PK
885         buffer_dump(&b);
886 #endif
887         ok = key_sign(private, &signature, &slen, buffer_ptr(&b), buffer_len(&b));
888         key_free(private);
889         buffer_free(&b);
890         if (ok != 0) {
891                 error("key_sign failed");
892                 xfree(chost);
893                 xfree(pkalg);
894                 return 0;
895         }
896         packet_start(SSH2_MSG_USERAUTH_REQUEST);
897         packet_put_cstring(authctxt->server_user);
898         packet_put_cstring(authctxt->service);
899         packet_put_cstring(authctxt->method->name);
900         packet_put_cstring(pkalg);
901         packet_put_string(blob, blen);
902         packet_put_cstring(chost);
903         packet_put_cstring(authctxt->local_user);
904         packet_put_string(signature, slen);
905         memset(signature, 's', slen);
906         xfree(signature);
907         xfree(chost);
908         xfree(pkalg);
909
910         packet_send();
911         return 1;
912 }
913
914 /* find auth method */
915
916 /*
917  * given auth method name, if configurable options permit this method fill
918  * in auth_ident field and return true, otherwise return false.
919  */
920 static int
921 authmethod_is_enabled(Authmethod *method)
922 {
923         if (method == NULL)
924                 return 0;
925         /* return false if options indicate this method is disabled */
926         if  (method->enabled == NULL || *method->enabled == 0)
927                 return 0;
928         /* return false if batch mode is enabled but method needs interactive mode */
929         if  (method->batch_flag != NULL && *method->batch_flag != 0)
930                 return 0;
931         return 1;
932 }
933
934 static Authmethod *
935 authmethod_lookup(const char *name)
936 {
937         Authmethod *method = NULL;
938         if (name != NULL)
939                 for (method = authmethods; method->name != NULL; method++)
940                         if (strcmp(name, method->name) == 0)
941                                 return method;
942         debug2("Unrecognized authentication method name: %s", name ? name : "NULL");
943         return NULL;
944 }
945
946 /* XXX internal state */
947 static Authmethod *current = NULL;
948 static char *supported = NULL;
949 static char *preferred = NULL;
950 /*
951  * Given the authentication method list sent by the server, return the
952  * next method we should try.  If the server initially sends a nil list,
953  * use a built-in default list.
954  */
955 static Authmethod *
956 authmethod_get(char *authlist)
957 {
958
959         char *name = NULL;
960         int next;
961
962         /* Use a suitable default if we're passed a nil list.  */
963         if (authlist == NULL || strlen(authlist) == 0)
964                 authlist = options.preferred_authentications;
965
966         if (supported == NULL || strcmp(authlist, supported) != 0) {
967                 debug3("start over, passed a different list %s", authlist);
968                 if (supported != NULL)
969                         xfree(supported);
970                 supported = xstrdup(authlist);
971                 preferred = options.preferred_authentications;
972                 debug3("preferred %s", preferred);
973                 current = NULL;
974         } else if (current != NULL && authmethod_is_enabled(current))
975                 return current;
976
977         for (;;) {
978                 if ((name = match_list(preferred, supported, &next)) == NULL) {
979                         debug("no more auth methods to try");
980                         current = NULL;
981                         return NULL;
982                 }
983                 preferred += next;
984                 debug3("authmethod_lookup %s", name);
985                 debug3("remaining preferred: %s", preferred);
986                 if ((current = authmethod_lookup(name)) != NULL &&
987                     authmethod_is_enabled(current)) {
988                         debug3("authmethod_is_enabled %s", name);
989                         debug("next auth method to try is %s", name);
990                         return current;
991                 }
992         }
993 }
994
995
996 #define DELIM   ","
997
998 static char *
999 authmethods_get(void)
1000 {
1001         Authmethod *method = NULL;
1002         char buf[1024];
1003
1004         buf[0] = '\0';
1005         for (method = authmethods; method->name != NULL; method++) {
1006                 if (authmethod_is_enabled(method)) {
1007                         if (buf[0] != '\0')
1008                                 strlcat(buf, DELIM, sizeof buf);
1009                         strlcat(buf, method->name, sizeof buf);
1010                 }
1011         }
1012         return xstrdup(buf);
1013 }
This page took 0.784363 seconds and 5 git commands to generate.