sshconnect2.c revision 60573
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" 31RCSID("$OpenBSD: sshconnect2.c,v 1.10 2000/05/08 17:42:25 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 */ 59extern char *client_version_string; 60extern char *server_version_string; 61extern Options options; 62 63/* 64 * SSH2 key exchange 65 */ 66 67unsigned char *session_id2 = NULL; 68int session_id2_len = 0; 69 70void 71ssh_kex2(char *host, struct sockaddr *hostaddr) 72{ 73 Kex *kex; 74 char *cprop[PROPOSAL_MAX]; 75 char *sprop[PROPOSAL_MAX]; 76 Buffer *client_kexinit; 77 Buffer *server_kexinit; 78 int payload_len, dlen; 79 unsigned int klen, kout; 80 char *ptr; 81 char *signature = NULL; 82 unsigned int slen; 83 char *server_host_key_blob = NULL; 84 Key *server_host_key; 85 unsigned int sbloblen; 86 DH *dh; 87 BIGNUM *dh_server_pub = 0; 88 BIGNUM *shared_secret = 0; 89 int i; 90 unsigned char *kbuf; 91 unsigned char *hash; 92 93/* KEXINIT */ 94 95 debug("Sending KEX init."); 96 if (options.ciphers != NULL) { 97 myproposal[PROPOSAL_ENC_ALGS_CTOS] = 98 myproposal[PROPOSAL_ENC_ALGS_STOC] = options.ciphers; 99 } else if (options.cipher == SSH_CIPHER_3DES) { 100 myproposal[PROPOSAL_ENC_ALGS_CTOS] = 101 myproposal[PROPOSAL_ENC_ALGS_STOC] = 102 cipher_name(SSH_CIPHER_3DES_CBC); 103 } else if (options.cipher == SSH_CIPHER_BLOWFISH) { 104 myproposal[PROPOSAL_ENC_ALGS_CTOS] = 105 myproposal[PROPOSAL_ENC_ALGS_STOC] = 106 cipher_name(SSH_CIPHER_BLOWFISH_CBC); 107 } 108 if (options.compression) { 109 myproposal[PROPOSAL_COMP_ALGS_CTOS] = "zlib"; 110 myproposal[PROPOSAL_COMP_ALGS_STOC] = "zlib"; 111 } else { 112 myproposal[PROPOSAL_COMP_ALGS_CTOS] = "none"; 113 myproposal[PROPOSAL_COMP_ALGS_STOC] = "none"; 114 } 115 for (i = 0; i < PROPOSAL_MAX; i++) 116 cprop[i] = xstrdup(myproposal[i]); 117 118 client_kexinit = kex_init(cprop); 119 packet_start(SSH2_MSG_KEXINIT); 120 packet_put_raw(buffer_ptr(client_kexinit), buffer_len(client_kexinit)); 121 packet_send(); 122 packet_write_wait(); 123 124 debug("done"); 125 126 packet_read_expect(&payload_len, SSH2_MSG_KEXINIT); 127 128 /* save payload for session_id */ 129 server_kexinit = xmalloc(sizeof(*server_kexinit)); 130 buffer_init(server_kexinit); 131 ptr = packet_get_raw(&payload_len); 132 buffer_append(server_kexinit, ptr, payload_len); 133 134 /* skip cookie */ 135 for (i = 0; i < 16; i++) 136 (void) packet_get_char(); 137 /* kex init proposal strings */ 138 for (i = 0; i < PROPOSAL_MAX; i++) { 139 sprop[i] = packet_get_string(NULL); 140 debug("got kexinit string: %s", sprop[i]); 141 } 142 i = (int) packet_get_char(); 143 debug("first kex follow == %d", i); 144 i = packet_get_int(); 145 debug("reserved == %d", i); 146 packet_done(); 147 148 debug("done read kexinit"); 149 kex = kex_choose_conf(cprop, sprop, 0); 150 151/* KEXDH */ 152 153 debug("Sending SSH2_MSG_KEXDH_INIT."); 154 155 /* generate and send 'e', client DH public key */ 156 dh = dh_new_group1(); 157 packet_start(SSH2_MSG_KEXDH_INIT); 158 packet_put_bignum2(dh->pub_key); 159 packet_send(); 160 packet_write_wait(); 161 162#ifdef DEBUG_KEXDH 163 fprintf(stderr, "\np= "); 164 bignum_print(dh->p); 165 fprintf(stderr, "\ng= "); 166 bignum_print(dh->g); 167 fprintf(stderr, "\npub= "); 168 bignum_print(dh->pub_key); 169 fprintf(stderr, "\n"); 170 DHparams_print_fp(stderr, dh); 171#endif 172 173 debug("Wait SSH2_MSG_KEXDH_REPLY."); 174 175 packet_read_expect(&payload_len, SSH2_MSG_KEXDH_REPLY); 176 177 debug("Got SSH2_MSG_KEXDH_REPLY."); 178 179 /* key, cert */ 180 server_host_key_blob = packet_get_string(&sbloblen); 181 server_host_key = dsa_key_from_blob(server_host_key_blob, sbloblen); 182 if (server_host_key == NULL) 183 fatal("cannot decode server_host_key_blob"); 184 185 check_host_key(host, hostaddr, server_host_key, 186 options.user_hostfile2, options.system_hostfile2); 187 188 /* DH paramter f, server public DH key */ 189 dh_server_pub = BN_new(); 190 if (dh_server_pub == NULL) 191 fatal("dh_server_pub == NULL"); 192 packet_get_bignum2(dh_server_pub, &dlen); 193 194#ifdef DEBUG_KEXDH 195 fprintf(stderr, "\ndh_server_pub= "); 196 bignum_print(dh_server_pub); 197 fprintf(stderr, "\n"); 198 debug("bits %d", BN_num_bits(dh_server_pub)); 199#endif 200 201 /* signed H */ 202 signature = packet_get_string(&slen); 203 packet_done(); 204 205 if (!dh_pub_is_valid(dh, dh_server_pub)) 206 packet_disconnect("bad server public DH value"); 207 208 klen = DH_size(dh); 209 kbuf = xmalloc(klen); 210 kout = DH_compute_key(kbuf, dh_server_pub, dh); 211#ifdef DEBUG_KEXDH 212 debug("shared secret: len %d/%d", klen, kout); 213 fprintf(stderr, "shared secret == "); 214 for (i = 0; i< kout; i++) 215 fprintf(stderr, "%02x", (kbuf[i])&0xff); 216 fprintf(stderr, "\n"); 217#endif 218 shared_secret = BN_new(); 219 220 BN_bin2bn(kbuf, kout, shared_secret); 221 memset(kbuf, 0, klen); 222 xfree(kbuf); 223 224 /* calc and verify H */ 225 hash = kex_hash( 226 client_version_string, 227 server_version_string, 228 buffer_ptr(client_kexinit), buffer_len(client_kexinit), 229 buffer_ptr(server_kexinit), buffer_len(server_kexinit), 230 server_host_key_blob, sbloblen, 231 dh->pub_key, 232 dh_server_pub, 233 shared_secret 234 ); 235 xfree(server_host_key_blob); 236 buffer_free(client_kexinit); 237 buffer_free(server_kexinit); 238 xfree(client_kexinit); 239 xfree(server_kexinit); 240#ifdef DEBUG_KEXDH 241 fprintf(stderr, "hash == "); 242 for (i = 0; i< 20; i++) 243 fprintf(stderr, "%02x", (hash[i])&0xff); 244 fprintf(stderr, "\n"); 245#endif 246 if (dsa_verify(server_host_key, (unsigned char *)signature, slen, hash, 20) != 1) 247 fatal("dsa_verify failed for server_host_key"); 248 key_free(server_host_key); 249 250 kex_derive_keys(kex, hash, shared_secret); 251 packet_set_kex(kex); 252 253 /* have keys, free DH */ 254 DH_free(dh); 255 256 /* save session id */ 257 session_id2_len = 20; 258 session_id2 = xmalloc(session_id2_len); 259 memcpy(session_id2, hash, session_id2_len); 260 261 debug("Wait SSH2_MSG_NEWKEYS."); 262 packet_read_expect(&payload_len, SSH2_MSG_NEWKEYS); 263 packet_done(); 264 debug("GOT SSH2_MSG_NEWKEYS."); 265 266 debug("send SSH2_MSG_NEWKEYS."); 267 packet_start(SSH2_MSG_NEWKEYS); 268 packet_send(); 269 packet_write_wait(); 270 debug("done: send SSH2_MSG_NEWKEYS."); 271 272#ifdef DEBUG_KEXDH 273 /* send 1st encrypted/maced/compressed message */ 274 packet_start(SSH2_MSG_IGNORE); 275 packet_put_cstring("markus"); 276 packet_send(); 277 packet_write_wait(); 278#endif 279 debug("done: KEX2."); 280} 281/* 282 * Authenticate user 283 */ 284int 285ssh2_try_passwd(const char *server_user, const char *host, const char *service) 286{ 287 static int attempt = 0; 288 char prompt[80]; 289 char *password; 290 291 if (attempt++ > options.number_of_password_prompts) 292 return 0; 293 294 snprintf(prompt, sizeof(prompt), "%.30s@%.40s's password: ", 295 server_user, host); 296 password = read_passphrase(prompt, 0); 297 packet_start(SSH2_MSG_USERAUTH_REQUEST); 298 packet_put_cstring(server_user); 299 packet_put_cstring(service); 300 packet_put_cstring("password"); 301 packet_put_char(0); 302 packet_put_cstring(password); 303 memset(password, 0, strlen(password)); 304 xfree(password); 305 packet_send(); 306 packet_write_wait(); 307 return 1; 308} 309 310int 311ssh2_try_pubkey(char *filename, 312 const char *server_user, const char *host, const char *service) 313{ 314 Buffer b; 315 Key *k; 316 unsigned char *blob, *signature; 317 int bloblen, slen; 318 struct stat st; 319 320 if (stat(filename, &st) != 0) { 321 debug("key does not exist: %s", filename); 322 return 0; 323 } 324 debug("try pubkey: %s", filename); 325 326 k = key_new(KEY_DSA); 327 if (!load_private_key(filename, "", k, NULL)) { 328 int success = 0; 329 char *passphrase; 330 char prompt[300]; 331 snprintf(prompt, sizeof prompt, 332 "Enter passphrase for DSA key '%.100s': ", 333 filename); 334 passphrase = read_passphrase(prompt, 0); 335 success = load_private_key(filename, passphrase, k, NULL); 336 memset(passphrase, 0, strlen(passphrase)); 337 xfree(passphrase); 338 if (!success) 339 return 0; 340 } 341 dsa_make_key_blob(k, &blob, &bloblen); 342 343 /* data to be signed */ 344 buffer_init(&b); 345 buffer_append(&b, session_id2, session_id2_len); 346 buffer_put_char(&b, SSH2_MSG_USERAUTH_REQUEST); 347 buffer_put_cstring(&b, server_user); 348 buffer_put_cstring(&b, 349 datafellows & SSH_BUG_PUBKEYAUTH ? 350 "ssh-userauth" : 351 service); 352 buffer_put_cstring(&b, "publickey"); 353 buffer_put_char(&b, 1); 354 buffer_put_cstring(&b, KEX_DSS); 355 buffer_put_string(&b, blob, bloblen); 356 357 /* generate signature */ 358 dsa_sign(k, &signature, &slen, buffer_ptr(&b), buffer_len(&b)); 359 key_free(k); 360#ifdef DEBUG_DSS 361 buffer_dump(&b); 362#endif 363 if (datafellows & SSH_BUG_PUBKEYAUTH) { 364 /* e.g. ssh-2.0.13: data-to-be-signed != data-on-the-wire */ 365 buffer_clear(&b); 366 buffer_append(&b, session_id2, session_id2_len); 367 buffer_put_char(&b, SSH2_MSG_USERAUTH_REQUEST); 368 buffer_put_cstring(&b, server_user); 369 buffer_put_cstring(&b, service); 370 buffer_put_cstring(&b, "publickey"); 371 buffer_put_char(&b, 1); 372 buffer_put_cstring(&b, KEX_DSS); 373 buffer_put_string(&b, blob, bloblen); 374 } 375 xfree(blob); 376 /* append signature */ 377 buffer_put_string(&b, signature, slen); 378 xfree(signature); 379 380 /* skip session id and packet type */ 381 if (buffer_len(&b) < session_id2_len + 1) 382 fatal("ssh2_try_pubkey: internal error"); 383 buffer_consume(&b, session_id2_len + 1); 384 385 /* put remaining data from buffer into packet */ 386 packet_start(SSH2_MSG_USERAUTH_REQUEST); 387 packet_put_raw(buffer_ptr(&b), buffer_len(&b)); 388 buffer_free(&b); 389 390 /* send */ 391 packet_send(); 392 packet_write_wait(); 393 return 1; 394} 395 396void 397ssh_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} 475