]> andersk Git - gssapi-openssh.git/blob - openssh/sshconnect2.c
GSSAPI patch for OpenSSH 3.0.2p1 Protocol version 2 by Simon Wilkinson from
[gssapi-openssh.git] / openssh / 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 #ifdef GSSAPI
58 #include "ssh-gss.h"
59 #endif
60
61 /* import */
62 extern char *client_version_string;
63 extern char *server_version_string;
64 extern Options options;
65
66 /*
67  * SSH2 key exchange
68  */
69
70 u_char *session_id2 = NULL;
71 int session_id2_len = 0;
72
73 char *xxx_host;
74 struct sockaddr *xxx_hostaddr;
75
76 Kex *xxx_kex = NULL;
77
78 static int
79 verify_host_key_callback(Key *hostkey)
80 {
81         if (verify_host_key(xxx_host, xxx_hostaddr, hostkey) == -1)
82                 fatal("Host key verification failed.");
83         return 0;
84 }
85
86 void
87 ssh_kex2(char *host, struct sockaddr *hostaddr)
88 {
89         Kex *kex;
90
91         xxx_host = host;
92         xxx_hostaddr = hostaddr;
93
94 #ifdef GSSAPI
95         /* This is a bit of a nasty kludge. This adds the GSSAPI included
96          * key exchange methods to the top of the list, allowing the GSSAPI
97          * code to decide whether each one should be included or not.
98          */     
99         {
100                 char *orig, *gss;
101                 int len;
102                 orig = myproposal[PROPOSAL_KEX_ALGS];
103                 gss = ssh_gssapi_mechanisms(0,host);
104                 if (gss) {
105                    len = strlen(orig)+strlen(gss)+2;
106                    myproposal[PROPOSAL_KEX_ALGS]=xmalloc(len);
107                    snprintf(myproposal[PROPOSAL_KEX_ALGS],len,"%s,%s",gss,orig);
108                    /* If we've got GSSAPI algorithms, then we also support the
109                     * 'null' hostkey, as a last resort */
110                    orig=myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS];
111                    len = strlen(orig)+sizeof(",null");
112                    myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS]=xmalloc(len);
113                    snprintf(myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS],len,"%s,null",orig);  
114                 }
115         }
116 #endif
117
118         if (options.ciphers == (char *)-1) {
119                 log("No valid ciphers for protocol version 2 given, using defaults.");
120                 options.ciphers = NULL;
121         }
122         if (options.ciphers != NULL) {
123                 myproposal[PROPOSAL_ENC_ALGS_CTOS] =
124                 myproposal[PROPOSAL_ENC_ALGS_STOC] = options.ciphers;
125         }
126         myproposal[PROPOSAL_ENC_ALGS_CTOS] =
127             compat_cipher_proposal(myproposal[PROPOSAL_ENC_ALGS_CTOS]);
128         myproposal[PROPOSAL_ENC_ALGS_STOC] =
129             compat_cipher_proposal(myproposal[PROPOSAL_ENC_ALGS_STOC]);
130         if (options.compression) {
131                 myproposal[PROPOSAL_COMP_ALGS_CTOS] =
132                 myproposal[PROPOSAL_COMP_ALGS_STOC] = "zlib";
133         } else {
134                 myproposal[PROPOSAL_COMP_ALGS_CTOS] =
135                 myproposal[PROPOSAL_COMP_ALGS_STOC] = "none";
136         }
137         if (options.macs != NULL) {
138                 myproposal[PROPOSAL_MAC_ALGS_CTOS] =
139                 myproposal[PROPOSAL_MAC_ALGS_STOC] = options.macs;
140         }
141         if (options.hostkeyalgorithms != NULL)
142                 myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] =
143                     options.hostkeyalgorithms;
144
145         /* start key exchange */
146         kex = kex_setup(myproposal);
147         kex->client_version_string=client_version_string;
148         kex->server_version_string=server_version_string;
149         kex->verify_host_key=&verify_host_key_callback;
150         kex->host=host;
151
152 #ifdef GSSAPI
153         kex->options.gss_deleg_creds=options.gss_deleg_creds;
154 #endif
155
156         xxx_kex = kex;
157
158         dispatch_run(DISPATCH_BLOCK, &kex->done, kex);
159
160         session_id2 = kex->session_id;
161         session_id2_len = kex->session_id_len;
162
163 #ifdef DEBUG_KEXDH
164         /* send 1st encrypted/maced/compressed message */
165         packet_start(SSH2_MSG_IGNORE);
166         packet_put_cstring("markus");
167         packet_send();
168         packet_write_wait();
169 #endif
170         debug("done: ssh_kex2.");
171 }
172
173 /*
174  * Authenticate user
175  */
176
177 typedef struct Authctxt Authctxt;
178 typedef struct Authmethod Authmethod;
179
180 typedef int sign_cb_fn(
181     Authctxt *authctxt, Key *key,
182     u_char **sigp, int *lenp, u_char *data, int datalen);
183
184 struct Authctxt {
185         const char *server_user;
186         const char *local_user;
187         const char *host;
188         const char *service;
189         Authmethod *method;
190         int success;
191         char *authlist;
192         /* pubkey */
193         Key *last_key;
194         sign_cb_fn *last_key_sign;
195         int last_key_hint;
196         AuthenticationConnection *agent;
197         /* hostbased */
198         Key **keys;
199         int nkeys;
200         /* kbd-interactive */
201         int info_req_seen;
202         /* generic */
203         void *methoddata;
204 };
205 struct Authmethod {
206         char    *name;          /* string to compare against server's list */
207         int     (*userauth)(Authctxt *authctxt);
208         int     *enabled;       /* flag in option struct that enables method */
209         int     *batch_flag;    /* flag in option struct that disables method */
210 };
211
212 void    input_userauth_success(int type, int plen, void *ctxt);
213 void    input_userauth_failure(int type, int plen, void *ctxt);
214 void    input_userauth_banner(int type, int plen, void *ctxt);
215 void    input_userauth_error(int type, int plen, void *ctxt);
216 void    input_userauth_info_req(int type, int plen, void *ctxt);
217 void    input_userauth_pk_ok(int type, int plen, void *ctxt);
218
219 int     userauth_none(Authctxt *authctxt);
220 int     userauth_pubkey(Authctxt *authctxt);
221 int     userauth_passwd(Authctxt *authctxt);
222 int     userauth_kbdint(Authctxt *authctxt);
223 int     userauth_hostbased(Authctxt *authctxt);
224
225 #ifdef GSSAPI
226 int     userauth_external(Authctxt *authctxt);
227 int     userauth_gssapi(Authctxt *authctxt);
228 void    input_gssapi_response(int type, int plen, void *ctxt);
229 void    input_gssapi_token(int type, int plen, void *ctxt);
230 void    input_gssapi_hash(int type, int plen, void *ctxt);
231
232 int     gss_host_key_ok=0;
233 #endif
234
235 void    userauth(Authctxt *authctxt, char *authlist);
236
237 static int sign_and_send_pubkey(Authctxt *, Key *, sign_cb_fn *);
238 static void clear_auth_state(Authctxt *);
239
240 static Authmethod *authmethod_get(char *authlist);
241 static Authmethod *authmethod_lookup(const char *name);
242 static char *authmethods_get(void);
243
244 Authmethod authmethods[] = {
245 #ifdef GSSAPI
246         {"external-keyx",
247                 userauth_external,
248                 &options.gss_authentication,
249                 NULL},
250         {"gssapi",
251                 userauth_gssapi,
252                 &options.gss_authentication,
253                 NULL},
254 #endif
255         {"hostbased",
256                 userauth_hostbased,
257                 &options.hostbased_authentication,
258                 NULL},
259         {"publickey",
260                 userauth_pubkey,
261                 &options.pubkey_authentication,
262                 NULL},
263         {"keyboard-interactive",
264                 userauth_kbdint,
265                 &options.kbd_interactive_authentication,
266                 &options.batch_mode},
267         {"password",
268                 userauth_passwd,
269                 &options.password_authentication,
270                 &options.batch_mode},
271         {"none",
272                 userauth_none,
273                 NULL,
274                 NULL},
275         {NULL, NULL, NULL, NULL}
276 };
277
278 void
279 ssh_userauth2(const char *local_user, const char *server_user, char *host,
280     Key **keys, int nkeys)
281 {
282         Authctxt authctxt;
283         int type;
284         int plen;
285
286         if (options.challenge_response_authentication)
287                 options.kbd_interactive_authentication = 1;
288
289         debug("send SSH2_MSG_SERVICE_REQUEST");
290         packet_start(SSH2_MSG_SERVICE_REQUEST);
291         packet_put_cstring("ssh-userauth");
292         packet_send();
293         packet_write_wait();
294         type = packet_read(&plen);
295         if (type != SSH2_MSG_SERVICE_ACCEPT) {
296                 fatal("denied SSH2_MSG_SERVICE_ACCEPT: %d", type);
297         }
298         if (packet_remaining() > 0) {
299                 char *reply = packet_get_string(&plen);
300                 debug("service_accept: %s", reply);
301                 xfree(reply);
302         } else {
303                 debug("buggy server: service_accept w/o service");
304         }
305         packet_done();
306         debug("got SSH2_MSG_SERVICE_ACCEPT");
307
308         if (options.preferred_authentications == NULL)
309                 options.preferred_authentications = authmethods_get();
310
311         /* setup authentication context */
312         memset(&authctxt, 0, sizeof(authctxt));
313         authctxt.agent = ssh_get_authentication_connection();
314         authctxt.server_user = server_user;
315         authctxt.local_user = local_user;
316         authctxt.host = host;
317         authctxt.service = "ssh-connection";            /* service name */
318         authctxt.success = 0;
319         authctxt.method = authmethod_lookup("none");
320         authctxt.authlist = NULL;
321         authctxt.methoddata = NULL;
322         authctxt.keys = keys;
323         authctxt.nkeys = nkeys;
324         authctxt.info_req_seen = 0;
325         if (authctxt.method == NULL)
326                 fatal("ssh_userauth2: internal error: cannot send userauth none request");
327
328         /* initial userauth request */
329         userauth_none(&authctxt);
330
331         dispatch_init(&input_userauth_error);
332         dispatch_set(SSH2_MSG_USERAUTH_SUCCESS, &input_userauth_success);
333         dispatch_set(SSH2_MSG_USERAUTH_FAILURE, &input_userauth_failure);
334         dispatch_set(SSH2_MSG_USERAUTH_BANNER, &input_userauth_banner);
335         dispatch_run(DISPATCH_BLOCK, &authctxt.success, &authctxt);     /* loop until success */
336
337         if (authctxt.agent != NULL)
338                 ssh_close_authentication_connection(authctxt.agent);
339
340         debug("ssh-userauth2 successful: method %s", authctxt.method->name);
341 }
342 void
343 userauth(Authctxt *authctxt, char *authlist)
344 {
345         if (authctxt->methoddata!=NULL) {
346                 xfree(authctxt->methoddata);
347                 authctxt->methoddata=NULL;
348         }
349            
350         if (authlist == NULL) {
351                 authlist = authctxt->authlist;
352         } else {
353                 if (authctxt->authlist)
354                         xfree(authctxt->authlist);
355                 authctxt->authlist = authlist;
356         }
357         for (;;) {
358                 Authmethod *method = authmethod_get(authlist);
359                 if (method == NULL)
360                         fatal("Permission denied (%s).", authlist);
361                 authctxt->method = method;
362                 if (method->userauth(authctxt) != 0) {
363                         debug2("we sent a %s packet, wait for reply", method->name);
364                         break;
365                 } else {
366                         debug2("we did not send a packet, disable method");
367                         method->enabled = NULL;
368                 }
369         }
370 }
371 void
372 input_userauth_error(int type, int plen, void *ctxt)
373 {
374         fatal("input_userauth_error: bad message during authentication: "
375            "type %d", type);
376 }
377 void
378 input_userauth_banner(int type, int plen, void *ctxt)
379 {
380         char *msg, *lang;
381         debug3("input_userauth_banner");
382         msg = packet_get_string(NULL);
383         lang = packet_get_string(NULL);
384         fprintf(stderr, "%s", msg);
385         xfree(msg);
386         xfree(lang);
387 }
388 void
389 input_userauth_success(int type, int plen, void *ctxt)
390 {
391         Authctxt *authctxt = ctxt;
392         if (authctxt == NULL)
393                 fatal("input_userauth_success: no authentication context");
394         if (authctxt->authlist)
395                 xfree(authctxt->authlist);
396         if (authctxt->methoddata)
397                 xfree(authctxt->methoddata);
398         clear_auth_state(authctxt);
399         authctxt->success = 1;                  /* break out */
400 }
401 void
402 input_userauth_failure(int type, int plen, void *ctxt)
403 {
404         Authctxt *authctxt = ctxt;
405         char *authlist = NULL;
406         int partial;
407
408         if (authctxt == NULL)
409                 fatal("input_userauth_failure: no authentication context");
410
411         authlist = packet_get_string(NULL);
412         partial = packet_get_char();
413         packet_done();
414
415         if (partial != 0)
416                 log("Authenticated with partial success.");
417         debug("authentications that can continue: %s", authlist);
418
419         clear_auth_state(authctxt);
420         userauth(authctxt, authlist);
421 }
422 void
423 input_userauth_pk_ok(int type, int plen, void *ctxt)
424 {
425         Authctxt *authctxt = ctxt;
426         Key *key = NULL;
427         Buffer b;
428         int alen, blen, sent = 0;
429         char *pkalg, *pkblob, *fp;
430
431         if (authctxt == NULL)
432                 fatal("input_userauth_pk_ok: no authentication context");
433         if (datafellows & SSH_BUG_PKOK) {
434                 /* this is similar to SSH_BUG_PKAUTH */
435                 debug2("input_userauth_pk_ok: SSH_BUG_PKOK");
436                 pkblob = packet_get_string(&blen);
437                 buffer_init(&b);
438                 buffer_append(&b, pkblob, blen);
439                 pkalg = buffer_get_string(&b, &alen);
440                 buffer_free(&b);
441         } else {
442                 pkalg = packet_get_string(&alen);
443                 pkblob = packet_get_string(&blen);
444         }
445         packet_done();
446
447         debug("input_userauth_pk_ok: pkalg %s blen %d lastkey %p hint %d",
448             pkalg, blen, authctxt->last_key, authctxt->last_key_hint);
449
450         do {
451                 if (authctxt->last_key == NULL ||
452                     authctxt->last_key_sign == NULL) {
453                         debug("no last key or no sign cb");
454                         break;
455                 }
456                 if (key_type_from_name(pkalg) == KEY_UNSPEC) {
457                         debug("unknown pkalg %s", pkalg);
458                         break;
459                 }
460                 if ((key = key_from_blob(pkblob, blen)) == NULL) {
461                         debug("no key from blob. pkalg %s", pkalg);
462                         break;
463                 }
464                 fp = key_fingerprint(key, SSH_FP_MD5, SSH_FP_HEX);
465                 debug2("input_userauth_pk_ok: fp %s", fp);
466                 xfree(fp);
467                 if (!key_equal(key, authctxt->last_key)) {
468                         debug("key != last_key");
469                         break;
470                 }
471                 sent = sign_and_send_pubkey(authctxt, key,
472                    authctxt->last_key_sign);
473         } while(0);
474
475         if (key != NULL)
476                 key_free(key);
477         xfree(pkalg);
478         xfree(pkblob);
479
480         /* unregister */
481         clear_auth_state(authctxt);
482         dispatch_set(SSH2_MSG_USERAUTH_PK_OK, NULL);
483
484         /* try another method if we did not send a packet*/
485         if (sent == 0)
486                 userauth(authctxt, NULL);
487
488 }
489
490 #ifdef GSSAPI
491 int 
492 userauth_gssapi(Authctxt *authctxt)
493 {
494         int i;
495         Gssctxt *gssctxt;
496         static int tries=0;
497
498         /* For now, we only make one attempt at this. We could try offering
499          * the server different GSSAPI OIDs until we get bored, I suppose.
500          */     
501         if (tries++>0) return 0;
502
503         gssctxt=xmalloc(sizeof(Gssctxt));
504
505         /* Initialise as much of our context as we can, so failures can be
506          * trapped before sending any packets.
507          */
508         ssh_gssapi_build_ctx(gssctxt);
509         if (ssh_gssapi_import_name(gssctxt,authctxt->host)) {
510                 return(0);
511         }
512         authctxt->methoddata=(void *)gssctxt;
513                 
514         packet_start(SSH2_MSG_USERAUTH_REQUEST);
515         packet_put_cstring(authctxt->server_user);
516         packet_put_cstring(authctxt->service);
517         packet_put_cstring(authctxt->method->name);
518
519         /* FIXME: This assumes that our current GSSAPI implementation
520          * supports all of the mechanisms listed in supported_mechs.
521          * This may not be the case - we should use something along
522          * the lines of the code in gss_genr to remove the ones that
523          * aren't supported */
524         packet_put_int(GSS_LAST_ENTRY);
525         for (i=0;i<GSS_LAST_ENTRY;i++) {
526                 packet_put_string(supported_mechs[i].oid.elements,
527                                   supported_mechs[i].oid.length);
528         }
529         packet_send();
530         packet_write_wait();
531
532         dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_RESPONSE,&input_gssapi_response);
533         dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_TOKEN,&input_gssapi_token);
534         
535         return 1;
536 }
537
538 void
539 input_gssapi_response(int type, int plen, void *ctxt) 
540 {
541         Authctxt *authctxt = ctxt;
542         Gssctxt *gssctxt;
543         OM_uint32 status,ms;
544         int oidlen;
545         char *oidv;
546         gss_buffer_desc send_tok;
547         
548         if (authctxt == NULL)
549                 fatal("input_gssapi_response: no authentication context");
550         gssctxt = authctxt->methoddata;
551         
552         /* Setup our OID */
553         oidv=packet_get_string(&oidlen);
554         ssh_gssapi_set_oid_data(gssctxt,oidv,oidlen);
555         
556         packet_done();
557         
558         status = ssh_gssapi_init_ctx(gssctxt, options.gss_deleg_creds,
559                                      GSS_C_NO_BUFFER, &send_tok, 
560                                      NULL);
561         if (GSS_ERROR(status)) {
562                 /* Start again with next method on list */
563                 debug("Trying to start again");
564                 userauth(authctxt,NULL);
565                 return;
566         }
567
568         /* We must have data to send */                                 
569         packet_start(SSH2_MSG_USERAUTH_GSSAPI_TOKEN);
570         packet_put_string(send_tok.value,send_tok.length);
571         packet_send();
572         packet_write_wait();
573         gss_release_buffer(&ms, &send_tok);
574 }
575
576 void
577 input_gssapi_token(int type, int plen, void *ctxt)
578 {
579         Authctxt *authctxt = ctxt;
580         Gssctxt *gssctxt;
581         gss_buffer_desc send_tok,recv_tok;
582         OM_uint32 status;
583         
584         if (authctxt == NULL)
585                 fatal("input_gssapi_response: no authentication context");
586         gssctxt = authctxt->methoddata;
587         
588         recv_tok.value=packet_get_string(&recv_tok.length);
589
590         status=ssh_gssapi_init_ctx(gssctxt, options.gss_deleg_creds,
591                                    &recv_tok, &send_tok, NULL);
592
593         packet_done();
594         
595         if (GSS_ERROR(status)) {
596                 /* Start again with the next method in the list */
597                 userauth(authctxt,NULL);
598                 return;
599         }
600         
601         if (send_tok.length>0) {
602                 packet_start(SSH2_MSG_USERAUTH_GSSAPI_TOKEN);
603                 packet_put_string(send_tok.value,send_tok.length);
604                 packet_send();
605                 packet_write_wait();
606         }
607         
608         if (status == GSS_S_COMPLETE) {
609                 /* If that succeeded, send a exchange complete message */
610                 packet_start(SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE);
611                 packet_send();
612                 packet_write_wait();
613         }
614 }
615
616 int
617 userauth_external(Authctxt *authctxt)
618 {
619         static int attempt =0;
620         
621         if (attempt++ >= 1)
622                 return 0;
623                                 
624         debug2("userauth_external");
625         packet_start(SSH2_MSG_USERAUTH_REQUEST);
626         packet_put_cstring(authctxt->server_user);
627         packet_put_cstring(authctxt->service);
628         packet_put_cstring(authctxt->method->name);
629         packet_send();
630         packet_write_wait();
631         return 1;
632 }                                                                                                
633 #endif /* GSSAPI */
634
635 int
636 userauth_none(Authctxt *authctxt)
637 {
638         /* initial userauth request */
639         packet_start(SSH2_MSG_USERAUTH_REQUEST);
640         packet_put_cstring(authctxt->server_user);
641         packet_put_cstring(authctxt->service);
642         packet_put_cstring(authctxt->method->name);
643         packet_send();
644         return 1;
645
646 }
647
648 int
649 userauth_passwd(Authctxt *authctxt)
650 {
651         static int attempt = 0;
652         char prompt[80];
653         char *password;
654
655         if (attempt++ >= options.number_of_password_prompts)
656                 return 0;
657
658         if(attempt != 1)
659                 error("Permission denied, please try again.");
660
661         snprintf(prompt, sizeof(prompt), "%.30s@%.128s's password: ",
662             authctxt->server_user, authctxt->host);
663         password = read_passphrase(prompt, 0);
664         packet_start(SSH2_MSG_USERAUTH_REQUEST);
665         packet_put_cstring(authctxt->server_user);
666         packet_put_cstring(authctxt->service);
667         packet_put_cstring(authctxt->method->name);
668         packet_put_char(0);
669         packet_put_cstring(password);
670         memset(password, 0, strlen(password));
671         xfree(password);
672         packet_add_padding(64);
673         packet_send();
674         return 1;
675 }
676
677 static void
678 clear_auth_state(Authctxt *authctxt)
679 {
680         /* XXX clear authentication state */
681         if (authctxt->last_key != NULL && authctxt->last_key_hint == -1) {
682                 debug3("clear_auth_state: key_free %p", authctxt->last_key);
683                 key_free(authctxt->last_key);
684         }
685         authctxt->last_key = NULL;
686         authctxt->last_key_hint = -2;
687         authctxt->last_key_sign = NULL;
688 }
689
690 static int
691 sign_and_send_pubkey(Authctxt *authctxt, Key *k, sign_cb_fn *sign_callback)
692 {
693         Buffer b;
694         u_char *blob, *signature;
695         int bloblen, slen;
696         int skip = 0;
697         int ret = -1;
698         int have_sig = 1;
699
700         debug3("sign_and_send_pubkey");
701
702         if (key_to_blob(k, &blob, &bloblen) == 0) {
703                 /* we cannot handle this key */
704                 debug3("sign_and_send_pubkey: cannot handle key");
705                 return 0;
706         }
707         /* data to be signed */
708         buffer_init(&b);
709         if (datafellows & SSH_OLD_SESSIONID) {
710                 buffer_append(&b, session_id2, session_id2_len);
711                 skip = session_id2_len;
712         } else {
713                 buffer_put_string(&b, session_id2, session_id2_len);
714                 skip = buffer_len(&b);
715         }
716         buffer_put_char(&b, SSH2_MSG_USERAUTH_REQUEST);
717         buffer_put_cstring(&b, authctxt->server_user);
718         buffer_put_cstring(&b,
719             datafellows & SSH_BUG_PKSERVICE ?
720             "ssh-userauth" :
721             authctxt->service);
722         if (datafellows & SSH_BUG_PKAUTH) {
723                 buffer_put_char(&b, have_sig);
724         } else {
725                 buffer_put_cstring(&b, authctxt->method->name);
726                 buffer_put_char(&b, have_sig);
727                 buffer_put_cstring(&b, key_ssh_name(k));
728         }
729         buffer_put_string(&b, blob, bloblen);
730
731         /* generate signature */
732         ret = (*sign_callback)(authctxt, k, &signature, &slen,
733             buffer_ptr(&b), buffer_len(&b));
734         if (ret == -1) {
735                 xfree(blob);
736                 buffer_free(&b);
737                 return 0;
738         }
739 #ifdef DEBUG_PK
740         buffer_dump(&b);
741 #endif
742         if (datafellows & SSH_BUG_PKSERVICE) {
743                 buffer_clear(&b);
744                 buffer_append(&b, session_id2, session_id2_len);
745                 skip = session_id2_len;
746                 buffer_put_char(&b, SSH2_MSG_USERAUTH_REQUEST);
747                 buffer_put_cstring(&b, authctxt->server_user);
748                 buffer_put_cstring(&b, authctxt->service);
749                 buffer_put_cstring(&b, authctxt->method->name);
750                 buffer_put_char(&b, have_sig);
751                 if (!(datafellows & SSH_BUG_PKAUTH))
752                         buffer_put_cstring(&b, key_ssh_name(k));
753                 buffer_put_string(&b, blob, bloblen);
754         }
755         xfree(blob);
756
757         /* append signature */
758         buffer_put_string(&b, signature, slen);
759         xfree(signature);
760
761         /* skip session id and packet type */
762         if (buffer_len(&b) < skip + 1)
763                 fatal("userauth_pubkey: internal error");
764         buffer_consume(&b, skip + 1);
765
766         /* put remaining data from buffer into packet */
767         packet_start(SSH2_MSG_USERAUTH_REQUEST);
768         packet_put_raw(buffer_ptr(&b), buffer_len(&b));
769         buffer_free(&b);
770         packet_send();
771
772         return 1;
773 }
774
775 static int
776 send_pubkey_test(Authctxt *authctxt, Key *k, sign_cb_fn *sign_callback,
777     int hint)
778 {
779         u_char *blob;
780         int bloblen, have_sig = 0;
781
782         debug3("send_pubkey_test");
783
784         if (key_to_blob(k, &blob, &bloblen) == 0) {
785                 /* we cannot handle this key */
786                 debug3("send_pubkey_test: cannot handle key");
787                 return 0;
788         }
789         /* register callback for USERAUTH_PK_OK message */
790         authctxt->last_key_sign = sign_callback;
791         authctxt->last_key_hint = hint;
792         authctxt->last_key = k;
793         dispatch_set(SSH2_MSG_USERAUTH_PK_OK, &input_userauth_pk_ok);
794
795         packet_start(SSH2_MSG_USERAUTH_REQUEST);
796         packet_put_cstring(authctxt->server_user);
797         packet_put_cstring(authctxt->service);
798         packet_put_cstring(authctxt->method->name);
799         packet_put_char(have_sig);
800         if (!(datafellows & SSH_BUG_PKAUTH))
801                 packet_put_cstring(key_ssh_name(k));
802         packet_put_string(blob, bloblen);
803         xfree(blob);
804         packet_send();
805         return 1;
806 }
807
808 static Key *
809 load_identity_file(char *filename)
810 {
811         Key *private;
812         char prompt[300], *passphrase;
813         int quit, i;
814         struct stat st;
815
816         if (stat(filename, &st) < 0) {
817                 debug3("no such identity: %s", filename);
818                 return NULL;
819         }
820         private = key_load_private_type(KEY_UNSPEC, filename, "", NULL);
821         if (private == NULL) {
822                 if (options.batch_mode)
823                         return NULL;
824                 snprintf(prompt, sizeof prompt,
825                      "Enter passphrase for key '%.100s': ", filename);
826                 for (i = 0; i < options.number_of_password_prompts; i++) {
827                         passphrase = read_passphrase(prompt, 0);
828                         if (strcmp(passphrase, "") != 0) {
829                                 private = key_load_private_type(KEY_UNSPEC, filename,
830                                     passphrase, NULL);
831                                 quit = 0;
832                         } else {
833                                 debug2("no passphrase given, try next key");
834                                 quit = 1;
835                         }
836                         memset(passphrase, 0, strlen(passphrase));
837                         xfree(passphrase);
838                         if (private != NULL || quit)
839                                 break;
840                         debug2("bad passphrase given, try again...");
841                 }
842         }
843         return private;
844 }
845
846 static int
847 identity_sign_cb(Authctxt *authctxt, Key *key, u_char **sigp, int *lenp,
848     u_char *data, int datalen)
849 {
850         Key *private;
851         int idx, ret;
852
853         idx = authctxt->last_key_hint;
854         if (idx < 0)
855                 return -1;
856
857         /* private key is stored in external hardware */
858         if (options.identity_keys[idx]->flags & KEY_FLAG_EXT) 
859                 return key_sign(options.identity_keys[idx], sigp, lenp, data, datalen);
860
861         private = load_identity_file(options.identity_files[idx]);
862         if (private == NULL)
863                 return -1;
864         ret = key_sign(private, sigp, lenp, data, datalen);
865         key_free(private);
866         return ret;
867 }
868
869 static int
870 agent_sign_cb(Authctxt *authctxt, Key *key, u_char **sigp, int *lenp,
871     u_char *data, int datalen)
872 {
873         return ssh_agent_sign(authctxt->agent, key, sigp, lenp, data, datalen);
874 }
875
876 static int
877 key_sign_cb(Authctxt *authctxt, Key *key, u_char **sigp, int *lenp,
878     u_char *data, int datalen)
879 {
880         return key_sign(key, sigp, lenp, data, datalen);
881 }
882
883 static int
884 userauth_pubkey_agent(Authctxt *authctxt)
885 {
886         static int called = 0;
887         int ret = 0;
888         char *comment;
889         Key *k;
890
891         if (called == 0) {
892                 if (ssh_get_num_identities(authctxt->agent, 2) == 0)
893                         debug2("userauth_pubkey_agent: no keys at all");
894                 called = 1;
895         }
896         k = ssh_get_next_identity(authctxt->agent, &comment, 2);
897         if (k == NULL) {
898                 debug2("userauth_pubkey_agent: no more keys");
899         } else {
900                 debug("userauth_pubkey_agent: testing agent key %s", comment);
901                 xfree(comment);
902                 ret = send_pubkey_test(authctxt, k, agent_sign_cb, -1);
903                 if (ret == 0)
904                         key_free(k);
905         }
906         if (ret == 0)
907                 debug2("userauth_pubkey_agent: no message sent");
908         return ret;
909 }
910
911 int
912 userauth_pubkey(Authctxt *authctxt)
913 {
914         static int idx = 0;
915         int sent = 0;
916         Key *key;
917         char *filename;
918
919         if (authctxt->agent != NULL) {
920                 do {
921                         sent = userauth_pubkey_agent(authctxt);
922                 } while(!sent && authctxt->agent->howmany > 0);
923         }
924         while (!sent && idx < options.num_identity_files) {
925                 key = options.identity_keys[idx];
926                 filename = options.identity_files[idx];
927                 if (key == NULL) {
928                         debug("try privkey: %s", filename);
929                         key = load_identity_file(filename);
930                         if (key != NULL) {
931                                 sent = sign_and_send_pubkey(authctxt, key,
932                                     key_sign_cb);
933                                 key_free(key);
934                         }
935                 } else if (key->type != KEY_RSA1) {
936                         debug("try pubkey: %s", filename);
937                         sent = send_pubkey_test(authctxt, key,
938                             identity_sign_cb, idx);
939                 }
940                 idx++;
941         }
942         return sent;
943 }
944
945 /*
946  * Send userauth request message specifying keyboard-interactive method.
947  */
948 int
949 userauth_kbdint(Authctxt *authctxt)
950 {
951         static int attempt = 0;
952
953         if (attempt++ >= options.number_of_password_prompts)
954                 return 0;
955         /* disable if no SSH2_MSG_USERAUTH_INFO_REQUEST has been seen */
956         if (attempt > 1 && !authctxt->info_req_seen) {
957                 debug3("userauth_kbdint: disable: no info_req_seen");
958                 dispatch_set(SSH2_MSG_USERAUTH_INFO_REQUEST, NULL);
959                 return 0;
960         }
961
962         debug2("userauth_kbdint");
963         packet_start(SSH2_MSG_USERAUTH_REQUEST);
964         packet_put_cstring(authctxt->server_user);
965         packet_put_cstring(authctxt->service);
966         packet_put_cstring(authctxt->method->name);
967         packet_put_cstring("");                                 /* lang */
968         packet_put_cstring(options.kbd_interactive_devices ?
969             options.kbd_interactive_devices : "");
970         packet_send();
971
972         dispatch_set(SSH2_MSG_USERAUTH_INFO_REQUEST, &input_userauth_info_req);
973         return 1;
974 }
975
976 /*
977  * parse INFO_REQUEST, prompt user and send INFO_RESPONSE
978  */
979 void
980 input_userauth_info_req(int type, int plen, void *ctxt)
981 {
982         Authctxt *authctxt = ctxt;
983         char *name, *inst, *lang, *prompt, *response;
984         u_int num_prompts, i;
985         int echo = 0;
986
987         debug2("input_userauth_info_req");
988
989         if (authctxt == NULL)
990                 fatal("input_userauth_info_req: no authentication context");
991
992         authctxt->info_req_seen = 1;
993
994         name = packet_get_string(NULL);
995         inst = packet_get_string(NULL);
996         lang = packet_get_string(NULL);
997         if (strlen(name) > 0)
998                 log("%s", name);
999         if (strlen(inst) > 0)
1000                 log("%s", inst);
1001         xfree(name);
1002         xfree(inst);
1003         xfree(lang);
1004
1005         num_prompts = packet_get_int();
1006         /*
1007          * Begin to build info response packet based on prompts requested.
1008          * We commit to providing the correct number of responses, so if
1009          * further on we run into a problem that prevents this, we have to
1010          * be sure and clean this up and send a correct error response.
1011          */
1012         packet_start(SSH2_MSG_USERAUTH_INFO_RESPONSE);
1013         packet_put_int(num_prompts);
1014
1015         debug2("input_userauth_info_req: num_prompts %d", num_prompts);
1016         for (i = 0; i < num_prompts; i++) {
1017                 prompt = packet_get_string(NULL);
1018                 echo = packet_get_char();
1019
1020                 response = read_passphrase(prompt, echo ? RP_ECHO : 0);
1021
1022                 packet_put_cstring(response);
1023                 memset(response, 0, strlen(response));
1024                 xfree(response);
1025                 xfree(prompt);
1026         }
1027         packet_done(); /* done with parsing incoming message. */
1028
1029         packet_add_padding(64);
1030         packet_send();
1031 }
1032
1033 /*
1034  * this will be move to an external program (ssh-keysign) ASAP. ssh-keysign
1035  * will be setuid-root and the sbit can be removed from /usr/bin/ssh.
1036  */
1037 int
1038 userauth_hostbased(Authctxt *authctxt)
1039 {
1040         Key *private = NULL;
1041         Buffer b;
1042         u_char *signature, *blob;
1043         char *chost, *pkalg, *p;
1044         const char *service;
1045         u_int blen, slen;
1046         int ok, i, len, found = 0;
1047
1048         /* check for a useful key */
1049         for (i = 0; i < authctxt->nkeys; i++) {
1050                 private = authctxt->keys[i];
1051                 if (private && private->type != KEY_RSA1) {
1052                         found = 1;
1053                         /* we take and free the key */
1054                         authctxt->keys[i] = NULL;
1055                         break;
1056                 }
1057         }
1058         if (!found) {
1059                 debug("userauth_hostbased: no more client hostkeys");
1060                 return 0;
1061         }
1062         if (key_to_blob(private, &blob, &blen) == 0) {
1063                 key_free(private);
1064                 return 0;
1065         }
1066         /* figure out a name for the client host */
1067         p = get_local_name(packet_get_connection_in());
1068         if (p == NULL) {
1069                 error("userauth_hostbased: cannot get local ipaddr/name");
1070                 key_free(private);
1071                 return 0;
1072         }
1073         len = strlen(p) + 2;
1074         chost = xmalloc(len);
1075         strlcpy(chost, p, len);
1076         strlcat(chost, ".", len);
1077         debug2("userauth_hostbased: chost %s", chost);
1078
1079         service = datafellows & SSH_BUG_HBSERVICE ? "ssh-userauth" :
1080             authctxt->service;
1081         pkalg = xstrdup(key_ssh_name(private));
1082         buffer_init(&b);
1083         /* construct data */
1084         buffer_put_string(&b, session_id2, session_id2_len);
1085         buffer_put_char(&b, SSH2_MSG_USERAUTH_REQUEST);
1086         buffer_put_cstring(&b, authctxt->server_user);
1087         buffer_put_cstring(&b, service);
1088         buffer_put_cstring(&b, authctxt->method->name);
1089         buffer_put_cstring(&b, pkalg);
1090         buffer_put_string(&b, blob, blen);
1091         buffer_put_cstring(&b, chost);
1092         buffer_put_cstring(&b, authctxt->local_user);
1093 #ifdef DEBUG_PK
1094         buffer_dump(&b);
1095 #endif
1096         ok = key_sign(private, &signature, &slen, buffer_ptr(&b), buffer_len(&b));
1097         key_free(private);
1098         buffer_free(&b);
1099         if (ok != 0) {
1100                 error("key_sign failed");
1101                 xfree(chost);
1102                 xfree(pkalg);
1103                 return 0;
1104         }
1105         packet_start(SSH2_MSG_USERAUTH_REQUEST);
1106         packet_put_cstring(authctxt->server_user);
1107         packet_put_cstring(authctxt->service);
1108         packet_put_cstring(authctxt->method->name);
1109         packet_put_cstring(pkalg);
1110         packet_put_string(blob, blen);
1111         packet_put_cstring(chost);
1112         packet_put_cstring(authctxt->local_user);
1113         packet_put_string(signature, slen);
1114         memset(signature, 's', slen);
1115         xfree(signature);
1116         xfree(chost);
1117         xfree(pkalg);
1118
1119         packet_send();
1120         return 1;
1121 }
1122
1123 /* find auth method */
1124
1125 /*
1126  * given auth method name, if configurable options permit this method fill
1127  * in auth_ident field and return true, otherwise return false.
1128  */
1129 static int
1130 authmethod_is_enabled(Authmethod *method)
1131 {
1132         if (method == NULL)
1133                 return 0;
1134         /* return false if options indicate this method is disabled */
1135         if  (method->enabled == NULL || *method->enabled == 0)
1136                 return 0;
1137         /* return false if batch mode is enabled but method needs interactive mode */
1138         if  (method->batch_flag != NULL && *method->batch_flag != 0)
1139                 return 0;
1140         return 1;
1141 }
1142
1143 static Authmethod *
1144 authmethod_lookup(const char *name)
1145 {
1146         Authmethod *method = NULL;
1147         if (name != NULL)
1148                 for (method = authmethods; method->name != NULL; method++)
1149                         if (strcmp(name, method->name) == 0)
1150                                 return method;
1151         debug2("Unrecognized authentication method name: %s", name ? name : "NULL");
1152         return NULL;
1153 }
1154
1155 /* XXX internal state */
1156 static Authmethod *current = NULL;
1157 static char *supported = NULL;
1158 static char *preferred = NULL;
1159 /*
1160  * Given the authentication method list sent by the server, return the
1161  * next method we should try.  If the server initially sends a nil list,
1162  * use a built-in default list.
1163  */
1164 static Authmethod *
1165 authmethod_get(char *authlist)
1166 {
1167
1168         char *name = NULL;
1169         int next;
1170
1171         /* Use a suitable default if we're passed a nil list.  */
1172         if (authlist == NULL || strlen(authlist) == 0)
1173                 authlist = options.preferred_authentications;
1174
1175         if (supported == NULL || strcmp(authlist, supported) != 0) {
1176                 debug3("start over, passed a different list %s", authlist);
1177                 if (supported != NULL)
1178                         xfree(supported);
1179                 supported = xstrdup(authlist);
1180                 preferred = options.preferred_authentications;
1181                 debug3("preferred %s", preferred);
1182                 current = NULL;
1183         } else if (current != NULL && authmethod_is_enabled(current))
1184                 return current;
1185
1186         for (;;) {
1187                 if ((name = match_list(preferred, supported, &next)) == NULL) {
1188                         debug("no more auth methods to try");
1189                         current = NULL;
1190                         return NULL;
1191                 }
1192                 preferred += next;
1193                 debug3("authmethod_lookup %s", name);
1194                 debug3("remaining preferred: %s", preferred);
1195                 if ((current = authmethod_lookup(name)) != NULL &&
1196                     authmethod_is_enabled(current)) {
1197                         debug3("authmethod_is_enabled %s", name);
1198                         debug("next auth method to try is %s", name);
1199                         return current;
1200                 }
1201         }
1202 }
1203
1204
1205 #define DELIM   ","
1206
1207 static char *
1208 authmethods_get(void)
1209 {
1210         Authmethod *method = NULL;
1211         char buf[1024];
1212
1213         buf[0] = '\0';
1214         for (method = authmethods; method->name != NULL; method++) {
1215                 if (authmethod_is_enabled(method)) {
1216                         if (buf[0] != '\0')
1217                                 strlcat(buf, DELIM, sizeof buf);
1218                         strlcat(buf, method->name, sizeof buf);
1219                 }
1220         }
1221         return xstrdup(buf);
1222 }
This page took 0.490616 seconds and 5 git commands to generate.