]> andersk Git - openssh.git/blob - sshconnect2.c
22ad39e7f3860825686248b0b89f982b1ffaedc9
[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  * 3. All advertising materials mentioning features or use of this software
13  *    must display the following acknowledgement:
14  *      This product includes software developed by Markus Friedl.
15  * 4. The name of the author may not be used to endorse or promote products
16  *    derived from this software without specific prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28  */
29
30 #include "includes.h"
31 RCSID("$OpenBSD: sshconnect2.c,v 1.16 2000/07/16 08:27:22 markus Exp $");
32
33 #include <openssl/bn.h>
34 #include <openssl/rsa.h>
35 #include <openssl/dsa.h>
36 #include <openssl/md5.h>
37 #include <openssl/dh.h>
38 #include <openssl/hmac.h>
39
40 #include "ssh.h"
41 #include "xmalloc.h"
42 #include "rsa.h"
43 #include "buffer.h"
44 #include "packet.h"
45 #include "cipher.h"
46 #include "uidswap.h"
47 #include "compat.h"
48 #include "readconf.h"
49 #include "bufaux.h"
50 #include "ssh2.h"
51 #include "kex.h"
52 #include "myproposal.h"
53 #include "key.h"
54 #include "dsa.h"
55 #include "sshconnect.h"
56 #include "authfile.h"
57
58 /* import */
59 extern char *client_version_string;
60 extern char *server_version_string;
61 extern Options options;
62
63 /*
64  * SSH2 key exchange
65  */
66
67 unsigned char *session_id2 = NULL;
68 int session_id2_len = 0;
69
70 void
71 ssh_kex_dh(Kex *kex, char *host, struct sockaddr *hostaddr,
72     Buffer *client_kexinit, Buffer *server_kexinit)
73 {
74         int plen, dlen;
75         unsigned int klen, kout;
76         char *signature = NULL;
77         unsigned int slen;
78         char *server_host_key_blob = NULL;
79         Key *server_host_key;
80         unsigned int sbloblen;
81         DH *dh;
82         BIGNUM *dh_server_pub = 0;
83         BIGNUM *shared_secret = 0;
84         unsigned char *kbuf;
85         unsigned char *hash;
86
87         debug("Sending SSH2_MSG_KEXDH_INIT.");
88         /* generate and send 'e', client DH public key */
89         dh = dh_new_group1();
90         packet_start(SSH2_MSG_KEXDH_INIT);
91         packet_put_bignum2(dh->pub_key);
92         packet_send();
93         packet_write_wait();
94
95 #ifdef DEBUG_KEXDH
96         fprintf(stderr, "\np= ");
97         bignum_print(dh->p);
98         fprintf(stderr, "\ng= ");
99         bignum_print(dh->g);
100         fprintf(stderr, "\npub= ");
101         bignum_print(dh->pub_key);
102         fprintf(stderr, "\n");
103         DHparams_print_fp(stderr, dh);
104 #endif
105
106         debug("Wait SSH2_MSG_KEXDH_REPLY.");
107
108         packet_read_expect(&plen, SSH2_MSG_KEXDH_REPLY);
109
110         debug("Got SSH2_MSG_KEXDH_REPLY.");
111
112         /* key, cert */
113         server_host_key_blob = packet_get_string(&sbloblen);
114         server_host_key = dsa_key_from_blob(server_host_key_blob, sbloblen);
115         if (server_host_key == NULL)
116                 fatal("cannot decode server_host_key_blob");
117
118         check_host_key(host, hostaddr, server_host_key,
119             options.user_hostfile2, options.system_hostfile2);
120
121         /* DH paramter f, server public DH key */
122         dh_server_pub = BN_new();
123         if (dh_server_pub == NULL)
124                 fatal("dh_server_pub == NULL");
125         packet_get_bignum2(dh_server_pub, &dlen);
126
127 #ifdef DEBUG_KEXDH
128         fprintf(stderr, "\ndh_server_pub= ");
129         bignum_print(dh_server_pub);
130         fprintf(stderr, "\n");
131         debug("bits %d", BN_num_bits(dh_server_pub));
132 #endif
133
134         /* signed H */
135         signature = packet_get_string(&slen);
136         packet_done();
137
138         if (!dh_pub_is_valid(dh, dh_server_pub))
139                 packet_disconnect("bad server public DH value");
140
141         klen = DH_size(dh);
142         kbuf = xmalloc(klen);
143         kout = DH_compute_key(kbuf, dh_server_pub, dh);
144 #ifdef DEBUG_KEXDH
145         debug("shared secret: len %d/%d", klen, kout);
146         fprintf(stderr, "shared secret == ");
147         for (i = 0; i< kout; i++)
148                 fprintf(stderr, "%02x", (kbuf[i])&0xff);
149         fprintf(stderr, "\n");
150 #endif
151         shared_secret = BN_new();
152
153         BN_bin2bn(kbuf, kout, shared_secret);
154         memset(kbuf, 0, klen);
155         xfree(kbuf);
156
157         /* calc and verify H */
158         hash = kex_hash(
159             client_version_string,
160             server_version_string,
161             buffer_ptr(client_kexinit), buffer_len(client_kexinit),
162             buffer_ptr(server_kexinit), buffer_len(server_kexinit),
163             server_host_key_blob, sbloblen,
164             dh->pub_key,
165             dh_server_pub,
166             shared_secret
167         );
168         xfree(server_host_key_blob);
169         DH_free(dh);
170 #ifdef DEBUG_KEXDH
171         fprintf(stderr, "hash == ");
172         for (i = 0; i< 20; i++)
173                 fprintf(stderr, "%02x", (hash[i])&0xff);
174         fprintf(stderr, "\n");
175 #endif
176         if (dsa_verify(server_host_key, (unsigned char *)signature, slen, hash, 20) != 1)
177                 fatal("dsa_verify failed for server_host_key");
178         key_free(server_host_key);
179
180         kex_derive_keys(kex, hash, shared_secret);
181         packet_set_kex(kex);
182
183         /* save session id */
184         session_id2_len = 20;
185         session_id2 = xmalloc(session_id2_len);
186         memcpy(session_id2, hash, session_id2_len);
187 }
188
189 void
190 ssh_kex2(char *host, struct sockaddr *hostaddr)
191 {
192         int i, plen;
193         Kex *kex;
194         Buffer *client_kexinit, *server_kexinit;
195         char *sprop[PROPOSAL_MAX];
196
197         if (options.ciphers != NULL) {
198                 myproposal[PROPOSAL_ENC_ALGS_CTOS] =
199                 myproposal[PROPOSAL_ENC_ALGS_STOC] = options.ciphers;
200         } else if (options.cipher == SSH_CIPHER_3DES) {
201                 myproposal[PROPOSAL_ENC_ALGS_CTOS] =
202                 myproposal[PROPOSAL_ENC_ALGS_STOC] =
203                     (char *) cipher_name(SSH_CIPHER_3DES_CBC);
204         } else if (options.cipher == SSH_CIPHER_BLOWFISH) {
205                 myproposal[PROPOSAL_ENC_ALGS_CTOS] =
206                 myproposal[PROPOSAL_ENC_ALGS_STOC] =
207                     (char *) cipher_name(SSH_CIPHER_BLOWFISH_CBC);
208         }
209         if (options.compression) {
210                 myproposal[PROPOSAL_COMP_ALGS_CTOS] = "zlib";
211                 myproposal[PROPOSAL_COMP_ALGS_STOC] = "zlib";
212         } else {
213                 myproposal[PROPOSAL_COMP_ALGS_CTOS] = "none";
214                 myproposal[PROPOSAL_COMP_ALGS_STOC] = "none";
215         }
216
217         /* buffers with raw kexinit messages */
218         server_kexinit = xmalloc(sizeof(*server_kexinit));
219         buffer_init(server_kexinit);
220         client_kexinit = kex_init(myproposal);
221
222         /* algorithm negotiation */
223         kex_exchange_kexinit(client_kexinit, server_kexinit, sprop);
224         kex = kex_choose_conf(myproposal, sprop, 0);
225         for (i = 0; i < PROPOSAL_MAX; i++)
226                 xfree(sprop[i]);
227
228         /* server authentication and session key agreement */
229         ssh_kex_dh(kex, host, hostaddr, client_kexinit, server_kexinit);
230
231         buffer_free(client_kexinit);
232         buffer_free(server_kexinit);
233         xfree(client_kexinit);
234         xfree(server_kexinit);
235
236         debug("Wait SSH2_MSG_NEWKEYS.");
237         packet_read_expect(&plen, SSH2_MSG_NEWKEYS);
238         packet_done();
239         debug("GOT SSH2_MSG_NEWKEYS.");
240
241         debug("send SSH2_MSG_NEWKEYS.");
242         packet_start(SSH2_MSG_NEWKEYS);
243         packet_send();
244         packet_write_wait();
245         debug("done: send SSH2_MSG_NEWKEYS.");
246
247 #ifdef DEBUG_KEXDH
248         /* send 1st encrypted/maced/compressed message */
249         packet_start(SSH2_MSG_IGNORE);
250         packet_put_cstring("markus");
251         packet_send();
252         packet_write_wait();
253 #endif
254         debug("done: KEX2.");
255 }
256
257 /*
258  * Authenticate user
259  */
260 int
261 ssh2_try_passwd(const char *server_user, const char *host, const char *service)
262 {
263         static int attempt = 0;
264         char prompt[80];
265         char *password;
266
267         if (attempt++ >= options.number_of_password_prompts)
268                 return 0;
269
270         if(attempt != 1)
271                 error("Permission denied, please try again.");
272
273         snprintf(prompt, sizeof(prompt), "%.30s@%.40s's password: ",
274             server_user, host);
275         password = read_passphrase(prompt, 0);
276         packet_start(SSH2_MSG_USERAUTH_REQUEST);
277         packet_put_cstring(server_user);
278         packet_put_cstring(service);
279         packet_put_cstring("password");
280         packet_put_char(0);
281         packet_put_cstring(password);
282         memset(password, 0, strlen(password));
283         xfree(password);
284         packet_send();
285         packet_write_wait();
286         return 1;
287 }
288
289 typedef int sign_fn(
290     Key *key,
291     unsigned char **sigp, int *lenp,
292     unsigned char *data, int datalen);
293
294 void
295 ssh2_sign_and_send_pubkey(Key *k, sign_fn *do_sign,
296     const char *server_user, const char *host, const char *service)
297 {
298         Buffer b;
299         unsigned char *blob, *signature;
300         int bloblen, slen;
301         int skip = 0;
302
303         dsa_make_key_blob(k, &blob, &bloblen);
304
305         /* data to be signed */
306         buffer_init(&b);
307         if (datafellows & SSH_COMPAT_SESSIONID_ENCODING) {
308                 buffer_put_string(&b, session_id2, session_id2_len);
309                 skip = buffer_len(&b);
310         } else {
311                 buffer_append(&b, session_id2, session_id2_len);
312                 skip = session_id2_len; 
313         }
314         buffer_put_char(&b, SSH2_MSG_USERAUTH_REQUEST);
315         buffer_put_cstring(&b, server_user);
316         buffer_put_cstring(&b,
317             datafellows & SSH_BUG_PUBKEYAUTH ?
318             "ssh-userauth" :
319             service);
320         buffer_put_cstring(&b, "publickey");
321         buffer_put_char(&b, 1);
322         buffer_put_cstring(&b, KEX_DSS); 
323         buffer_put_string(&b, blob, bloblen);
324
325         /* generate signature */
326         do_sign(k, &signature, &slen, buffer_ptr(&b), buffer_len(&b));
327         key_free(k); /* XXX */
328 #ifdef DEBUG_DSS
329         buffer_dump(&b);
330 #endif
331         if (datafellows & SSH_BUG_PUBKEYAUTH) {
332                 buffer_clear(&b);
333                 buffer_append(&b, session_id2, session_id2_len);
334                 buffer_put_char(&b, SSH2_MSG_USERAUTH_REQUEST);
335                 buffer_put_cstring(&b, server_user);
336                 buffer_put_cstring(&b, service);
337                 buffer_put_cstring(&b, "publickey");
338                 buffer_put_char(&b, 1);
339                 buffer_put_cstring(&b, KEX_DSS); 
340                 buffer_put_string(&b, blob, bloblen);
341         }
342         xfree(blob);
343         /* append signature */
344         buffer_put_string(&b, signature, slen);
345         xfree(signature);
346
347         /* skip session id and packet type */
348         if (buffer_len(&b) < skip + 1)
349                 fatal("ssh2_try_pubkey: internal error");
350         buffer_consume(&b, skip + 1);
351
352         /* put remaining data from buffer into packet */
353         packet_start(SSH2_MSG_USERAUTH_REQUEST);
354         packet_put_raw(buffer_ptr(&b), buffer_len(&b));
355         buffer_free(&b);
356
357         /* send */
358         packet_send();
359         packet_write_wait();
360 }
361
362 int
363 ssh2_try_pubkey(char *filename,
364     const char *server_user, const char *host, const char *service)
365 {
366         Key *k;
367         struct stat st;
368
369         if (stat(filename, &st) != 0) {
370                 debug("key does not exist: %s", filename);
371                 return 0;
372         }
373         debug("try pubkey: %s", filename);
374
375         k = key_new(KEY_DSA);
376         if (!load_private_key(filename, "", k, NULL)) {
377                 int success = 0;
378                 char *passphrase;
379                 char prompt[300];
380                 snprintf(prompt, sizeof prompt,
381                      "Enter passphrase for DSA key '%.100s': ",
382                      filename);
383                 passphrase = read_passphrase(prompt, 0);
384                 success = load_private_key(filename, passphrase, k, NULL);
385                 memset(passphrase, 0, strlen(passphrase));
386                 xfree(passphrase);
387                 if (!success) {
388                         key_free(k);
389                         return 0;
390                 }
391         }
392         ssh2_sign_and_send_pubkey(k, dsa_sign, server_user, host, service);
393         return 1;
394 }
395
396 void
397 ssh_userauth2(const char *server_user, char *host)
398 {
399         int type;
400         int plen;
401         int sent;
402         unsigned int dlen;
403         int partial;
404         int i = 0;
405         char *auths;
406         char *service = "ssh-connection";               /* service name */
407
408         debug("send SSH2_MSG_SERVICE_REQUEST");
409         packet_start(SSH2_MSG_SERVICE_REQUEST);
410         packet_put_cstring("ssh-userauth");
411         packet_send();
412         packet_write_wait();
413
414         type = packet_read(&plen);
415         if (type != SSH2_MSG_SERVICE_ACCEPT) {
416                 fatal("denied SSH2_MSG_SERVICE_ACCEPT: %d", type);
417         }
418         if (packet_remaining() > 0) {
419                 char *reply = packet_get_string(&plen);
420                 debug("service_accept: %s", reply);
421                 xfree(reply);
422         } else {
423                 /* payload empty for ssh-2.0.13 ?? */
424                 debug("buggy server: service_accept w/o service");
425         }
426         packet_done();
427         debug("got SSH2_MSG_SERVICE_ACCEPT");
428
429         /* INITIAL request for auth */
430         packet_start(SSH2_MSG_USERAUTH_REQUEST);
431         packet_put_cstring(server_user);
432         packet_put_cstring(service);
433         packet_put_cstring("none");
434         packet_send();
435         packet_write_wait();
436
437         for (;;) {
438                 sent = 0;
439                 type = packet_read(&plen);
440                 if (type == SSH2_MSG_USERAUTH_SUCCESS)
441                         break;
442                 if (type != SSH2_MSG_USERAUTH_FAILURE)
443                         fatal("access denied: %d", type);
444                 /* SSH2_MSG_USERAUTH_FAILURE means: try again */
445                 auths = packet_get_string(&dlen);
446                 debug("authentications that can continue: %s", auths);
447                 partial = packet_get_char();
448                 packet_done();
449                 if (partial)
450                         debug("partial success");
451                 if (options.dsa_authentication &&
452                     strstr(auths, "publickey") != NULL) {
453                         while (i < options.num_identity_files2) {
454                                 sent = ssh2_try_pubkey(
455                                     options.identity_files2[i++],
456                                     server_user, host, service);
457                                 if (sent)
458                                         break;
459                         }
460                 }
461                 if (!sent) {
462                         if (options.password_authentication &&
463                             !options.batch_mode &&
464                             strstr(auths, "password") != NULL) {
465                                 sent = ssh2_try_passwd(server_user, host, service);
466                         }
467                 }
468                 if (!sent)
469                         fatal("Permission denied (%s).", auths);
470                 xfree(auths);
471         }
472         packet_done();
473         debug("ssh-userauth2 successfull");
474 }
This page took 0.258281 seconds and 3 git commands to generate.