]> andersk Git - openssh.git/blob - sshconnect2.c
- (djm) Added patch from Nalin Dahyabhai <nalin@redhat.com> to enable
[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.29 2000/11/23 21:03:47 markus Exp $");
27
28 #include <openssl/bn.h>
29 #include <openssl/rsa.h>
30 #include <openssl/dsa.h>
31 #include <openssl/md5.h>
32 #include <openssl/dh.h>
33 #include <openssl/hmac.h>
34
35 #include "ssh.h"
36 #include "xmalloc.h"
37 #include "rsa.h"
38 #include "buffer.h"
39 #include "packet.h"
40 #include "uidswap.h"
41 #include "compat.h"
42 #include "readconf.h"
43 #include "bufaux.h"
44 #include "ssh2.h"
45 #include "kex.h"
46 #include "myproposal.h"
47 #include "key.h"
48 #include "sshconnect.h"
49 #include "authfile.h"
50 #include "cli.h"
51 #include "dispatch.h"
52 #include "authfd.h"
53
54 void ssh_dh1_client(Kex *, char *, struct sockaddr *, Buffer *, Buffer *);
55 void ssh_dhgex_client(Kex *, char *, struct sockaddr *, Buffer *, Buffer *);
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 unsigned char *session_id2 = NULL;
67 int session_id2_len = 0;
68
69 void
70 ssh_kex2(char *host, struct sockaddr *hostaddr)
71 {
72         int i, plen;
73         Kex *kex;
74         Buffer *client_kexinit, *server_kexinit;
75         char *sprop[PROPOSAL_MAX];
76
77         if (options.ciphers == (char *)-1) {
78                 log("No valid ciphers for protocol version 2 given, using defaults.");
79                 options.ciphers = NULL;
80         }
81         if (options.ciphers != NULL) {
82                 myproposal[PROPOSAL_ENC_ALGS_CTOS] =
83                 myproposal[PROPOSAL_ENC_ALGS_STOC] = options.ciphers;
84         }
85         if (options.compression) {
86                 myproposal[PROPOSAL_COMP_ALGS_CTOS] = "zlib";
87                 myproposal[PROPOSAL_COMP_ALGS_STOC] = "zlib";
88         } else {
89                 myproposal[PROPOSAL_COMP_ALGS_CTOS] = "none";
90                 myproposal[PROPOSAL_COMP_ALGS_STOC] = "none";
91         }
92
93         /* buffers with raw kexinit messages */
94         server_kexinit = xmalloc(sizeof(*server_kexinit));
95         buffer_init(server_kexinit);
96         client_kexinit = kex_init(myproposal);
97
98         /* algorithm negotiation */
99         kex_exchange_kexinit(client_kexinit, server_kexinit, sprop);
100         kex = kex_choose_conf(myproposal, sprop, 0);
101         for (i = 0; i < PROPOSAL_MAX; i++)
102                 xfree(sprop[i]);
103
104         /* server authentication and session key agreement */
105         switch(kex->kex_type) {
106         case DH_GRP1_SHA1:
107                 ssh_dh1_client(kex, host, hostaddr,
108                                client_kexinit, server_kexinit);
109                 break;
110         case DH_GEX_SHA1:
111                 ssh_dhgex_client(kex, host, hostaddr, client_kexinit,
112                                  server_kexinit);
113                 break;
114         default:
115                 fatal("Unsupported key exchange %d", kex->kex_type);
116         }
117
118         buffer_free(client_kexinit);
119         buffer_free(server_kexinit);
120         xfree(client_kexinit);
121         xfree(server_kexinit);
122
123         debug("Wait SSH2_MSG_NEWKEYS.");
124         packet_read_expect(&plen, SSH2_MSG_NEWKEYS);
125         packet_done();
126         debug("GOT SSH2_MSG_NEWKEYS.");
127
128         debug("send SSH2_MSG_NEWKEYS.");
129         packet_start(SSH2_MSG_NEWKEYS);
130         packet_send();
131         packet_write_wait();
132         debug("done: send SSH2_MSG_NEWKEYS.");
133
134 #ifdef DEBUG_KEXDH
135         /* send 1st encrypted/maced/compressed message */
136         packet_start(SSH2_MSG_IGNORE);
137         packet_put_cstring("markus");
138         packet_send();
139         packet_write_wait();
140 #endif
141         debug("done: KEX2.");
142 }
143
144 /* diffie-hellman-group1-sha1 */
145
146 void
147 ssh_dh1_client(Kex *kex, char *host, struct sockaddr *hostaddr, 
148                Buffer *client_kexinit, Buffer *server_kexinit)
149 {
150 #ifdef DEBUG_KEXDH
151         int i;
152 #endif
153         int plen, dlen;
154         unsigned int klen, kout;
155         char *signature = NULL;
156         unsigned int slen;
157         char *server_host_key_blob = NULL;
158         Key *server_host_key;
159         unsigned int sbloblen;
160         DH *dh;
161         BIGNUM *dh_server_pub = 0;
162         BIGNUM *shared_secret = 0;
163         unsigned char *kbuf;
164         unsigned char *hash;
165
166         debug("Sending SSH2_MSG_KEXDH_INIT.");
167         /* generate and send 'e', client DH public key */
168         dh = dh_new_group1();
169         packet_start(SSH2_MSG_KEXDH_INIT);
170         packet_put_bignum2(dh->pub_key);
171         packet_send();
172         packet_write_wait();
173
174 #ifdef DEBUG_KEXDH
175         fprintf(stderr, "\np= ");
176         BN_print_fp(stderr, dh->p);
177         fprintf(stderr, "\ng= ");
178         BN_print_fp(stderr, dh->g);
179         fprintf(stderr, "\npub= ");
180         BN_print_fp(stderr, dh->pub_key);
181         fprintf(stderr, "\n");
182         DHparams_print_fp(stderr, dh);
183 #endif
184
185         debug("Wait SSH2_MSG_KEXDH_REPLY.");
186
187         packet_read_expect(&plen, SSH2_MSG_KEXDH_REPLY);
188
189         debug("Got SSH2_MSG_KEXDH_REPLY.");
190
191         /* key, cert */
192         server_host_key_blob = packet_get_string(&sbloblen);
193         server_host_key = key_from_blob(server_host_key_blob, sbloblen);
194         if (server_host_key == NULL)
195                 fatal("cannot decode server_host_key_blob");
196
197         check_host_key(host, hostaddr, server_host_key,
198                        options.user_hostfile2, options.system_hostfile2);
199
200         /* DH paramter f, server public DH key */
201         dh_server_pub = BN_new();
202         if (dh_server_pub == NULL)
203                 fatal("dh_server_pub == NULL");
204         packet_get_bignum2(dh_server_pub, &dlen);
205
206 #ifdef DEBUG_KEXDH
207         fprintf(stderr, "\ndh_server_pub= ");
208         BN_print_fp(stderr, dh_server_pub);
209         fprintf(stderr, "\n");
210         debug("bits %d", BN_num_bits(dh_server_pub));
211 #endif
212
213         /* signed H */
214         signature = packet_get_string(&slen);
215         packet_done();
216
217         if (!dh_pub_is_valid(dh, dh_server_pub))
218                 packet_disconnect("bad server public DH value");
219
220         klen = DH_size(dh);
221         kbuf = xmalloc(klen);
222         kout = DH_compute_key(kbuf, dh_server_pub, dh);
223 #ifdef DEBUG_KEXDH
224         debug("shared secret: len %d/%d", klen, kout);
225         fprintf(stderr, "shared secret == ");
226         for (i = 0; i< kout; i++)
227                 fprintf(stderr, "%02x", (kbuf[i])&0xff);
228         fprintf(stderr, "\n");
229 #endif
230         shared_secret = BN_new();
231
232         BN_bin2bn(kbuf, kout, shared_secret);
233         memset(kbuf, 0, klen);
234         xfree(kbuf);
235
236         /* calc and verify H */
237         hash = kex_hash(
238             client_version_string,
239             server_version_string,
240             buffer_ptr(client_kexinit), buffer_len(client_kexinit),
241             buffer_ptr(server_kexinit), buffer_len(server_kexinit),
242             server_host_key_blob, sbloblen,
243             dh->pub_key,
244             dh_server_pub,
245             shared_secret
246         );
247         xfree(server_host_key_blob);
248         DH_free(dh);
249 #ifdef DEBUG_KEXDH
250         fprintf(stderr, "hash == ");
251         for (i = 0; i< 20; i++)
252                 fprintf(stderr, "%02x", (hash[i])&0xff);
253         fprintf(stderr, "\n");
254 #endif
255         if (key_verify(server_host_key, (unsigned char *)signature, slen, hash, 20) != 1)
256                 fatal("key_verify failed for server_host_key");
257         key_free(server_host_key);
258
259         kex_derive_keys(kex, hash, shared_secret);
260         packet_set_kex(kex);
261
262         /* save session id */
263         session_id2_len = 20;
264         session_id2 = xmalloc(session_id2_len);
265         memcpy(session_id2, hash, session_id2_len);
266 }
267
268 /* diffie-hellman-group-exchange-sha1 */
269
270 /*
271  * Estimates the group order for a Diffie-Hellman group that has an
272  * attack complexity approximately the same as O(2**bits).  Estimate
273  * with:  O(exp(1.9223 * (ln q)^(1/3) (ln ln q)^(2/3)))
274  */
275
276 int
277 dh_estimate(int bits)
278 {
279         
280         if (bits < 64)
281                 return (512);   /* O(2**63) */
282         if (bits < 128)
283                 return (1024);  /* O(2**86) */
284         if (bits < 192)
285                 return (2048);  /* O(2**116) */
286         return (4096);          /* O(2**156) */
287 }
288
289 void
290 ssh_dhgex_client(Kex *kex, char *host, struct sockaddr *hostaddr,
291                  Buffer *client_kexinit, Buffer *server_kexinit)
292 {
293 #ifdef DEBUG_KEXDH
294         int i;
295 #endif
296         int plen, dlen;
297         unsigned int klen, kout;
298         char *signature = NULL;
299         unsigned int slen, nbits;
300         char *server_host_key_blob = NULL;
301         Key *server_host_key;
302         unsigned int sbloblen;
303         DH *dh;
304         BIGNUM *dh_server_pub = 0;
305         BIGNUM *shared_secret = 0;
306         BIGNUM *p = 0, *g = 0;
307         unsigned char *kbuf;
308         unsigned char *hash;
309
310         nbits = dh_estimate(kex->enc[MODE_OUT].cipher->key_len * 8);
311
312         debug("Sending SSH2_MSG_KEX_DH_GEX_REQUEST.");
313         packet_start(SSH2_MSG_KEX_DH_GEX_REQUEST);
314         packet_put_int(nbits);
315         packet_send();
316         packet_write_wait();
317
318 #ifdef DEBUG_KEXDH
319         fprintf(stderr, "\nnbits = %d", nbits);
320 #endif
321
322         debug("Wait SSH2_MSG_KEX_DH_GEX_GROUP.");
323
324         packet_read_expect(&plen, SSH2_MSG_KEX_DH_GEX_GROUP);
325
326         debug("Got SSH2_MSG_KEX_DH_GEX_GROUP.");
327
328         if ((p = BN_new()) == NULL)
329                 fatal("BN_new");
330         packet_get_bignum2(p, &dlen);
331         if ((g = BN_new()) == NULL)
332                 fatal("BN_new");
333         packet_get_bignum2(g, &dlen);
334         if ((dh = dh_new_group(g, p)) == NULL)
335                 fatal("dh_new_group");
336
337 #ifdef DEBUG_KEXDH
338         fprintf(stderr, "\np= ");
339         BN_print_fp(stderr, dh->p);
340         fprintf(stderr, "\ng= ");
341         BN_print_fp(stderr, dh->g);
342         fprintf(stderr, "\npub= ");
343         BN_print_fp(stderr, dh->pub_key);
344         fprintf(stderr, "\n");
345         DHparams_print_fp(stderr, dh);
346 #endif
347
348         debug("Sending SSH2_MSG_KEX_DH_GEX_INIT.");
349         /* generate and send 'e', client DH public key */
350         packet_start(SSH2_MSG_KEX_DH_GEX_INIT);
351         packet_put_bignum2(dh->pub_key);
352         packet_send();
353         packet_write_wait();
354
355         debug("Wait SSH2_MSG_KEX_DH_GEX_REPLY.");
356
357         packet_read_expect(&plen, SSH2_MSG_KEX_DH_GEX_REPLY);
358
359         debug("Got SSH2_MSG_KEXDH_REPLY.");
360
361         /* key, cert */
362         server_host_key_blob = packet_get_string(&sbloblen);
363         server_host_key = key_from_blob(server_host_key_blob, sbloblen);
364         if (server_host_key == NULL)
365                 fatal("cannot decode server_host_key_blob");
366
367         check_host_key(host, hostaddr, server_host_key,
368                        options.user_hostfile2, options.system_hostfile2);
369
370         /* DH paramter f, server public DH key */
371         dh_server_pub = BN_new();
372         if (dh_server_pub == NULL)
373                 fatal("dh_server_pub == NULL");
374         packet_get_bignum2(dh_server_pub, &dlen);
375
376 #ifdef DEBUG_KEXDH
377         fprintf(stderr, "\ndh_server_pub= ");
378         BN_print_fp(stderr, dh_server_pub);
379         fprintf(stderr, "\n");
380         debug("bits %d", BN_num_bits(dh_server_pub));
381 #endif
382
383         /* signed H */
384         signature = packet_get_string(&slen);
385         packet_done();
386
387         if (!dh_pub_is_valid(dh, dh_server_pub))
388                 packet_disconnect("bad server public DH value");
389
390         klen = DH_size(dh);
391         kbuf = xmalloc(klen);
392         kout = DH_compute_key(kbuf, dh_server_pub, dh);
393 #ifdef DEBUG_KEXDH
394         debug("shared secret: len %d/%d", klen, kout);
395         fprintf(stderr, "shared secret == ");
396         for (i = 0; i< kout; i++)
397                 fprintf(stderr, "%02x", (kbuf[i])&0xff);
398         fprintf(stderr, "\n");
399 #endif
400         shared_secret = BN_new();
401
402         BN_bin2bn(kbuf, kout, shared_secret);
403         memset(kbuf, 0, klen);
404         xfree(kbuf);
405
406         /* calc and verify H */
407         hash = kex_hash_gex(
408             client_version_string,
409             server_version_string,
410             buffer_ptr(client_kexinit), buffer_len(client_kexinit),
411             buffer_ptr(server_kexinit), buffer_len(server_kexinit),
412             server_host_key_blob, sbloblen,
413             nbits, dh->p, dh->g, 
414             dh->pub_key,
415             dh_server_pub,
416             shared_secret
417         );
418         xfree(server_host_key_blob);
419         DH_free(dh);
420 #ifdef DEBUG_KEXDH
421         fprintf(stderr, "hash == ");
422         for (i = 0; i< 20; i++)
423                 fprintf(stderr, "%02x", (hash[i])&0xff);
424         fprintf(stderr, "\n");
425 #endif
426         if (key_verify(server_host_key, (unsigned char *)signature, slen, hash, 20) != 1)
427                 fatal("key_verify failed for server_host_key");
428         key_free(server_host_key);
429
430         kex_derive_keys(kex, hash, shared_secret);
431         packet_set_kex(kex);
432
433         /* save session id */
434         session_id2_len = 20;
435         session_id2 = xmalloc(session_id2_len);
436         memcpy(session_id2, hash, session_id2_len);
437 }
438
439 /*
440  * Authenticate user
441  */
442
443 typedef struct Authctxt Authctxt;
444 typedef struct Authmethod Authmethod;
445
446 typedef int sign_cb_fn(
447     Authctxt *authctxt, Key *key,
448     unsigned char **sigp, int *lenp, unsigned char *data, int datalen);
449
450 struct Authctxt {
451         const char *server_user;
452         const char *host;
453         const char *service;
454         AuthenticationConnection *agent;
455         Authmethod *method;
456         int success;
457 };
458 struct Authmethod {
459         char    *name;          /* string to compare against server's list */
460         int     (*userauth)(Authctxt *authctxt);
461         int     *enabled;       /* flag in option struct that enables method */
462         int     *batch_flag;    /* flag in option struct that disables method */
463 };
464
465 void    input_userauth_success(int type, int plen, void *ctxt);
466 void    input_userauth_failure(int type, int plen, void *ctxt);
467 void    input_userauth_error(int type, int plen, void *ctxt);
468 void    input_userauth_info_req(int type, int plen, void *ctxt);
469
470 int     userauth_none(Authctxt *authctxt);
471 int     userauth_pubkey(Authctxt *authctxt);
472 int     userauth_passwd(Authctxt *authctxt);
473 int     userauth_kbdint(Authctxt *authctxt);
474
475 void    authmethod_clear();
476 Authmethod *authmethod_get(char *authlist);
477 Authmethod *authmethod_lookup(const char *name);
478
479 Authmethod authmethods[] = {
480         {"publickey",
481                 userauth_pubkey,
482                 &options.pubkey_authentication,
483                 NULL},
484         {"password",
485                 userauth_passwd,
486                 &options.password_authentication,
487                 &options.batch_mode},
488         {"keyboard-interactive",
489                 userauth_kbdint,
490                 &options.kbd_interactive_authentication,
491                 &options.batch_mode},
492         {"none",
493                 userauth_none,
494                 NULL,
495                 NULL},
496         {NULL, NULL, NULL, NULL}
497 };
498
499 void
500 ssh_userauth2(const char *server_user, char *host)
501 {
502         Authctxt authctxt;
503         int type;
504         int plen;
505
506         debug("send SSH2_MSG_SERVICE_REQUEST");
507         packet_start(SSH2_MSG_SERVICE_REQUEST);
508         packet_put_cstring("ssh-userauth");
509         packet_send();
510         packet_write_wait();
511         type = packet_read(&plen);
512         if (type != SSH2_MSG_SERVICE_ACCEPT) {
513                 fatal("denied SSH2_MSG_SERVICE_ACCEPT: %d", type);
514         }
515         if (packet_remaining() > 0) {
516                 char *reply = packet_get_string(&plen);
517                 debug("service_accept: %s", reply);
518                 xfree(reply);
519                 packet_done();
520         } else {
521                 debug("buggy server: service_accept w/o service");
522         }
523         packet_done();
524         debug("got SSH2_MSG_SERVICE_ACCEPT");
525
526         /* setup authentication context */
527         authctxt.agent = ssh_get_authentication_connection();
528         authctxt.server_user = server_user;
529         authctxt.host = host;
530         authctxt.service = "ssh-connection";            /* service name */
531         authctxt.success = 0;
532         authctxt.method = authmethod_lookup("none");
533         if (authctxt.method == NULL)
534                 fatal("ssh_userauth2: internal error: cannot send userauth none request");
535         authmethod_clear();
536
537         /* initial userauth request */
538         userauth_none(&authctxt);
539
540         dispatch_init(&input_userauth_error);
541         dispatch_set(SSH2_MSG_USERAUTH_SUCCESS, &input_userauth_success);
542         dispatch_set(SSH2_MSG_USERAUTH_FAILURE, &input_userauth_failure);
543         dispatch_run(DISPATCH_BLOCK, &authctxt.success, &authctxt);     /* loop until success */
544
545         if (authctxt.agent != NULL)
546                 ssh_close_authentication_connection(authctxt.agent);
547
548         debug("ssh-userauth2 successfull: method %s", authctxt.method->name);
549 }
550 void
551 input_userauth_error(int type, int plen, void *ctxt)
552 {
553         fatal("input_userauth_error: bad message during authentication");
554 }
555 void
556 input_userauth_success(int type, int plen, void *ctxt)
557 {
558         Authctxt *authctxt = ctxt;
559         if (authctxt == NULL)
560                 fatal("input_userauth_success: no authentication context");
561         authctxt->success = 1;                  /* break out */
562 }
563 void
564 input_userauth_failure(int type, int plen, void *ctxt)
565 {
566         Authmethod *method = NULL;
567         Authctxt *authctxt = ctxt;
568         char *authlist = NULL;
569         int partial;
570
571         if (authctxt == NULL)
572                 fatal("input_userauth_failure: no authentication context");
573
574         authlist = packet_get_string(NULL);
575         partial = packet_get_char();
576         packet_done();
577
578         if (partial != 0)
579                 debug("partial success");
580         debug("authentications that can continue: %s", authlist);
581
582         for (;;) {
583                 method = authmethod_get(authlist);
584                 if (method == NULL)
585                         fatal("Unable to find an authentication method");
586                 authctxt->method = method;
587                 if (method->userauth(authctxt) != 0) {
588                         debug2("we sent a %s packet, wait for reply", method->name);
589                         break;
590                 } else {
591                         debug2("we did not send a packet, disable method");
592                         method->enabled = NULL;
593                 }
594         }       
595         xfree(authlist);
596 }
597
598 int
599 userauth_none(Authctxt *authctxt)
600 {
601         /* initial userauth request */
602         packet_start(SSH2_MSG_USERAUTH_REQUEST);
603         packet_put_cstring(authctxt->server_user);
604         packet_put_cstring(authctxt->service);
605         packet_put_cstring(authctxt->method->name);
606         packet_send();
607         packet_write_wait();
608         return 1;
609 }
610
611 int
612 userauth_passwd(Authctxt *authctxt)
613 {
614         static int attempt = 0;
615         char prompt[80];
616         char *password;
617
618         if (attempt++ >= options.number_of_password_prompts)
619                 return 0;
620
621         if(attempt != 1)
622                 error("Permission denied, please try again.");
623
624         snprintf(prompt, sizeof(prompt), "%.30s@%.40s's password: ",
625             authctxt->server_user, authctxt->host);
626         password = read_passphrase(prompt, 0);
627         packet_start(SSH2_MSG_USERAUTH_REQUEST);
628         packet_put_cstring(authctxt->server_user);
629         packet_put_cstring(authctxt->service);
630         packet_put_cstring(authctxt->method->name);
631         packet_put_char(0);
632         packet_put_cstring(password);
633         memset(password, 0, strlen(password));
634         xfree(password);
635         packet_send();
636         packet_write_wait();
637         return 1;
638 }
639
640 int
641 sign_and_send_pubkey(Authctxt *authctxt, Key *k, sign_cb_fn *sign_callback)
642 {
643         Buffer b;
644         unsigned char *blob, *signature;
645         int bloblen, slen;
646         int skip = 0;
647         int ret = -1;
648         int have_sig = 1;
649
650         if (key_to_blob(k, &blob, &bloblen) == 0) {
651                 /* we cannot handle this key */
652                 return 0;
653         }
654         /* data to be signed */
655         buffer_init(&b);
656         if (datafellows & SSH_OLD_SESSIONID) {
657                 buffer_append(&b, session_id2, session_id2_len);
658                 skip = session_id2_len; 
659         } else {
660                 buffer_put_string(&b, session_id2, session_id2_len);
661                 skip = buffer_len(&b);
662         }
663         buffer_put_char(&b, SSH2_MSG_USERAUTH_REQUEST);
664         buffer_put_cstring(&b, authctxt->server_user);
665         buffer_put_cstring(&b,
666             datafellows & SSH_BUG_PUBKEYAUTH ?
667             "ssh-userauth" :
668             authctxt->service);
669         buffer_put_cstring(&b, authctxt->method->name);
670         buffer_put_char(&b, have_sig);
671         buffer_put_cstring(&b, key_ssh_name(k)); 
672         buffer_put_string(&b, blob, bloblen);
673
674         /* generate signature */
675         ret = (*sign_callback)(authctxt, k, &signature, &slen, buffer_ptr(&b), buffer_len(&b));
676         if (ret == -1) {
677                 xfree(blob);
678                 buffer_free(&b);
679                 return 0;
680         }
681 #ifdef DEBUG_PK
682         buffer_dump(&b);
683 #endif
684         if (datafellows & SSH_BUG_PUBKEYAUTH) {
685                 buffer_clear(&b);
686                 buffer_append(&b, session_id2, session_id2_len);
687                 buffer_put_char(&b, SSH2_MSG_USERAUTH_REQUEST);
688                 buffer_put_cstring(&b, authctxt->server_user);
689                 buffer_put_cstring(&b, authctxt->service);
690                 buffer_put_cstring(&b, authctxt->method->name);
691                 buffer_put_char(&b, have_sig);
692                 buffer_put_cstring(&b, key_ssh_name(k)); 
693                 buffer_put_string(&b, blob, bloblen);
694         }
695         xfree(blob);
696         /* append signature */
697         buffer_put_string(&b, signature, slen);
698         xfree(signature);
699
700         /* skip session id and packet type */
701         if (buffer_len(&b) < skip + 1)
702                 fatal("userauth_pubkey: internal error");
703         buffer_consume(&b, skip + 1);
704
705         /* put remaining data from buffer into packet */
706         packet_start(SSH2_MSG_USERAUTH_REQUEST);
707         packet_put_raw(buffer_ptr(&b), buffer_len(&b));
708         buffer_free(&b);
709
710         /* send */
711         packet_send();
712         packet_write_wait();
713
714         return 1;
715 }
716
717 /* sign callback */
718 int key_sign_cb(Authctxt *authctxt, Key *key, unsigned char **sigp, int *lenp,
719     unsigned char *data, int datalen)
720 {
721         return key_sign(key, sigp, lenp, data, datalen);
722 }
723
724 int
725 userauth_pubkey_identity(Authctxt *authctxt, char *filename)
726 {
727         Key *k;
728         int i, ret, try_next;
729         struct stat st;
730
731         if (stat(filename, &st) != 0) {
732                 debug("key does not exist: %s", filename);
733                 return 0;
734         }
735         debug("try pubkey: %s", filename);
736
737         k = key_new(KEY_UNSPEC);
738         if (!load_private_key(filename, "", k, NULL)) {
739                 int success = 0;
740                 char *passphrase;
741                 char prompt[300];
742                 snprintf(prompt, sizeof prompt,
743                      "Enter passphrase for key '%.100s': ", filename);
744                 for (i = 0; i < options.number_of_password_prompts; i++) {
745                         passphrase = read_passphrase(prompt, 0);
746                         if (strcmp(passphrase, "") != 0) {
747                                 success = load_private_key(filename, passphrase, k, NULL);
748                                 try_next = 0;
749                         } else {
750                                 debug2("no passphrase given, try next key");
751                                 try_next = 1;
752                         }
753                         memset(passphrase, 0, strlen(passphrase));
754                         xfree(passphrase);
755                         if (success || try_next)
756                                 break;
757                         debug2("bad passphrase given, try again...");
758                 }
759                 if (!success) {
760                         key_free(k);
761                         return 0;
762                 }
763         }
764         ret = sign_and_send_pubkey(authctxt, k, key_sign_cb);
765         key_free(k);
766         return ret;
767 }
768
769 /* sign callback */
770 int agent_sign_cb(Authctxt *authctxt, Key *key, unsigned char **sigp, int *lenp,
771     unsigned char *data, int datalen)
772 {
773         return ssh_agent_sign(authctxt->agent, key, sigp, lenp, data, datalen);
774 }
775
776 int
777 userauth_pubkey_agent(Authctxt *authctxt)
778 {
779         static int called = 0;
780         int ret = 0;
781         char *comment;
782         Key *k;
783
784         if (called == 0) {
785                 if (ssh_get_num_identities(authctxt->agent, 2) == 0)
786                         debug2("userauth_pubkey_agent: no keys at all");
787                 called = 1;
788         }
789         k = ssh_get_next_identity(authctxt->agent, &comment, 2);
790         if (k == NULL) {
791                 debug2("userauth_pubkey_agent: no more keys");
792         } else {
793                 debug("userauth_pubkey_agent: trying agent key %s", comment);
794                 xfree(comment);
795                 ret = sign_and_send_pubkey(authctxt, k, agent_sign_cb);
796                 key_free(k);
797         }
798         if (ret == 0)
799                 debug2("userauth_pubkey_agent: no message sent");
800         return ret;
801 }
802
803 int
804 userauth_pubkey(Authctxt *authctxt)
805 {
806         static int idx = 0;
807         int sent = 0;
808
809         if (authctxt->agent != NULL) {
810                 do {
811                         sent = userauth_pubkey_agent(authctxt);
812                 } while(!sent && authctxt->agent->howmany > 0);
813         }
814         while (!sent && idx < options.num_identity_files) {
815                 if (options.identity_files_type[idx] != KEY_RSA1)
816                         sent = userauth_pubkey_identity(authctxt,
817                             options.identity_files[idx]);
818                 idx++;
819         }
820         return sent;
821 }
822
823 /*
824  * Send userauth request message specifying keyboard-interactive method.
825  */
826 int
827 userauth_kbdint(Authctxt *authctxt)
828 {
829         static int attempt = 0;
830
831         if (attempt++ >= options.number_of_password_prompts)
832                 return 0;
833
834         debug2("userauth_kbdint");
835         packet_start(SSH2_MSG_USERAUTH_REQUEST);
836         packet_put_cstring(authctxt->server_user);
837         packet_put_cstring(authctxt->service);
838         packet_put_cstring(authctxt->method->name);
839         packet_put_cstring("");                                 /* lang */
840         packet_put_cstring(options.kbd_interactive_devices ?
841             options.kbd_interactive_devices : "");
842         packet_send();
843         packet_write_wait();
844
845         dispatch_set(SSH2_MSG_USERAUTH_INFO_REQUEST, &input_userauth_info_req);
846         return 1;
847 }
848
849 /*
850  * parse SSH2_MSG_USERAUTH_INFO_REQUEST, prompt user and send
851  * SSH2_MSG_USERAUTH_INFO_RESPONSE
852  */
853 void
854 input_userauth_info_req(int type, int plen, void *ctxt)
855 {
856         Authctxt *authctxt = ctxt;
857         char *name = NULL;
858         char *inst = NULL;
859         char *lang = NULL;
860         char *prompt = NULL;
861         char *response = NULL;
862         unsigned int num_prompts, i;
863         int echo = 0;
864
865         debug2("input_userauth_info_req");
866
867         if (authctxt == NULL)
868                 fatal("input_userauth_info_req: no authentication context");
869
870         name = packet_get_string(NULL);
871         inst = packet_get_string(NULL);
872         lang = packet_get_string(NULL);
873
874         if (strlen(name) > 0)
875                 cli_mesg(name);
876         xfree(name);
877
878         if (strlen(inst) > 0)
879                 cli_mesg(inst);
880         xfree(inst);
881         xfree(lang);                            /* unused */
882
883         num_prompts = packet_get_int();
884         /*
885          * Begin to build info response packet based on prompts requested.
886          * We commit to providing the correct number of responses, so if
887          * further on we run into a problem that prevents this, we have to
888          * be sure and clean this up and send a correct error response.
889          */
890         packet_start(SSH2_MSG_USERAUTH_INFO_RESPONSE);
891         packet_put_int(num_prompts);
892
893         for (i = 0; i < num_prompts; i++) {
894                 prompt = packet_get_string(NULL);
895                 echo = packet_get_char();
896
897                 response = cli_prompt(prompt, echo);
898
899                 packet_put_cstring(response);
900                 memset(response, 0, strlen(response));
901                 xfree(response);
902                 xfree(prompt);
903         }
904         packet_done(); /* done with parsing incoming message. */
905
906         packet_send();
907         packet_write_wait();
908 }
909
910 /* find auth method */
911
912 #define DELIM   ","
913
914 static char *def_authlist = "publickey,password";
915 static char *authlist_current = NULL;    /* clean copy used for comparison */
916 static char *authname_current = NULL;    /* last used auth method */
917 static char *authlist_working = NULL;    /* copy that gets modified by strtok_r() */
918 static char *authlist_state = NULL;      /* state variable for strtok_r() */
919
920 /*
921  * Before starting to use a new authentication method list sent by the
922  * server, reset internal variables.  This should also be called when
923  * finished processing server list to free resources.
924  */
925 void
926 authmethod_clear()
927 {
928         if (authlist_current != NULL) {
929                 xfree(authlist_current);
930                 authlist_current = NULL;
931         }
932         if (authlist_working != NULL) {
933                 xfree(authlist_working);
934                 authlist_working = NULL;
935         }
936         if (authname_current != NULL) {
937                 xfree(authname_current);
938                 authlist_state = NULL;
939         }
940         if (authlist_state != NULL)
941                 authlist_state = NULL;
942         return;
943 }
944
945 /*
946  * given auth method name, if configurable options permit this method fill
947  * in auth_ident field and return true, otherwise return false.
948  */
949 int
950 authmethod_is_enabled(Authmethod *method)
951 {
952         if (method == NULL)
953                 return 0;
954         /* return false if options indicate this method is disabled */
955         if  (method->enabled == NULL || *method->enabled == 0)
956                 return 0;
957         /* return false if batch mode is enabled but method needs interactive mode */
958         if  (method->batch_flag != NULL && *method->batch_flag != 0)
959                 return 0;
960         return 1;
961 }
962
963 Authmethod *
964 authmethod_lookup(const char *name)
965 {
966         Authmethod *method = NULL;
967         if (name != NULL)
968                 for (method = authmethods; method->name != NULL; method++)
969                         if (strcmp(name, method->name) == 0)
970                                 return method;
971         debug2("Unrecognized authentication method name: %s", name ? name : "NULL");
972         return NULL;
973 }
974
975 /*
976  * Given the authentication method list sent by the server, return the
977  * next method we should try.  If the server initially sends a nil list,
978  * use a built-in default list.  If the server sends a nil list after
979  * previously sending a valid list, continue using the list originally
980  * sent.
981  */ 
982
983 Authmethod *
984 authmethod_get(char *authlist)
985 {
986         char *name = NULL, *authname_old;
987         Authmethod *method = NULL;
988         
989         /* Use a suitable default if we're passed a nil list.  */
990         if (authlist == NULL || strlen(authlist) == 0)
991                 authlist = def_authlist;
992
993         if (authlist_current == NULL || strcmp(authlist, authlist_current) != 0) {
994                 /* start over if passed a different list */
995                 debug3("start over, passed a different list");
996                 authmethod_clear();
997                 authlist_current = xstrdup(authlist);
998                 authlist_working = xstrdup(authlist);
999                 name = strtok_r(authlist_working, DELIM, &authlist_state);
1000         } else {
1001                 /*
1002                  * try to use previously used authentication method
1003                  * or continue to use previously passed list
1004                  */
1005                 name = (authname_current != NULL) ?
1006                     authname_current : strtok_r(NULL, DELIM, &authlist_state);
1007         }
1008
1009         while (name != NULL) {
1010                 debug3("authmethod_lookup %s", name);
1011                 method = authmethod_lookup(name);
1012                 if (method != NULL && authmethod_is_enabled(method)) {
1013                         debug3("authmethod_is_enabled %s", name);
1014                         break;
1015                 }
1016                 name = strtok_r(NULL, DELIM, &authlist_state);
1017                 method = NULL;
1018         }
1019
1020         authname_old = authname_current;
1021         if (method != NULL) {
1022                 debug("next auth method to try is %s", name);
1023                 authname_current = xstrdup(name);
1024         } else {
1025                 debug("no more auth methods to try");
1026                 authname_current = NULL;
1027         }
1028
1029         if (authname_old != NULL)
1030                 xfree(authname_old);
1031
1032         return (method);
1033 }
This page took 0.115542 seconds and 5 git commands to generate.