1 /* $OpenBSD: ssh_api.c,v 1.8 2017/04/30 23:13:25 djm Exp $ */ 2 /* 3 * Copyright (c) 2012 Markus Friedl. All rights reserved. 4 * 5 * Permission to use, copy, modify, and distribute this software for any 6 * purpose with or without fee is hereby granted, provided that the above 7 * copyright notice and this permission notice appear in all copies. 8 * 9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16 */ 17 18 #include "ssh_api.h" 19 #include "compat.h" 20 #include "log.h" 21 #include "authfile.h" 22 #include "sshkey.h" 23 #include "misc.h" 24 #include "ssh2.h" 25 #include "version.h" 26 #include "myproposal.h" 27 #include "ssherr.h" 28 #include "sshbuf.h" 29 30 #include <string.h> 31 32 int _ssh_exchange_banner(struct ssh *); 33 int _ssh_send_banner(struct ssh *, char **); 34 int _ssh_read_banner(struct ssh *, char **); 35 int _ssh_order_hostkeyalgs(struct ssh *); 36 int _ssh_verify_host_key(struct sshkey *, struct ssh *); 37 struct sshkey *_ssh_host_public_key(int, int, struct ssh *); 38 struct sshkey *_ssh_host_private_key(int, int, struct ssh *); 39 int _ssh_host_key_sign(struct sshkey *, struct sshkey *, 40 u_char **, size_t *, const u_char *, size_t, const char *, u_int); 41 42 /* 43 * stubs for the server side implementation of kex. 44 * disable privsep so our stubs will never be called. 45 */ 46 int use_privsep = 0; 47 int mm_sshkey_sign(struct sshkey *, u_char **, u_int *, 48 u_char *, u_int, char *, u_int); 49 DH *mm_choose_dh(int, int, int); 50 51 /* Define these two variables here so that they are part of the library */ 52 u_char *session_id2 = NULL; 53 u_int session_id2_len = 0; 54 55 int 56 mm_sshkey_sign(struct sshkey *key, u_char **sigp, u_int *lenp, 57 u_char *data, u_int datalen, char *alg, u_int compat) 58 { 59 return (-1); 60 } 61 62 DH * 63 mm_choose_dh(int min, int nbits, int max) 64 { 65 return (NULL); 66 } 67 68 /* API */ 69 70 int 71 ssh_init(struct ssh **sshp, int is_server, struct kex_params *kex_params) 72 { 73 char *myproposal[PROPOSAL_MAX] = { KEX_CLIENT }; 74 struct ssh *ssh; 75 char **proposal; 76 static int called; 77 int r; 78 79 if (!called) { 80 OpenSSL_add_all_algorithms(); 81 called = 1; 82 } 83 84 if ((ssh = ssh_packet_set_connection(NULL, -1, -1)) == NULL) 85 return SSH_ERR_ALLOC_FAIL; 86 if (is_server) 87 ssh_packet_set_server(ssh); 88 89 /* Initialize key exchange */ 90 proposal = kex_params ? kex_params->proposal : myproposal; 91 if ((r = kex_new(ssh, proposal, &ssh->kex)) != 0) { 92 ssh_free(ssh); 93 return r; 94 } 95 ssh->kex->server = is_server; 96 if (is_server) { 97 #ifdef WITH_OPENSSL 98 ssh->kex->kex[KEX_DH_GRP1_SHA1] = kexdh_server; 99 ssh->kex->kex[KEX_DH_GRP14_SHA1] = kexdh_server; 100 ssh->kex->kex[KEX_DH_GRP14_SHA256] = kexdh_server; 101 ssh->kex->kex[KEX_DH_GRP16_SHA512] = kexdh_server; 102 ssh->kex->kex[KEX_DH_GRP18_SHA512] = kexdh_server; 103 ssh->kex->kex[KEX_DH_GEX_SHA1] = kexgex_server; 104 ssh->kex->kex[KEX_DH_GEX_SHA256] = kexgex_server; 105 ssh->kex->kex[KEX_ECDH_SHA2] = kexecdh_server; 106 #endif /* WITH_OPENSSL */ 107 ssh->kex->kex[KEX_C25519_SHA256] = kexc25519_server; 108 ssh->kex->load_host_public_key=&_ssh_host_public_key; 109 ssh->kex->load_host_private_key=&_ssh_host_private_key; 110 ssh->kex->sign=&_ssh_host_key_sign; 111 } else { 112 #ifdef WITH_OPENSSL 113 ssh->kex->kex[KEX_DH_GRP1_SHA1] = kexdh_client; 114 ssh->kex->kex[KEX_DH_GRP14_SHA1] = kexdh_client; 115 ssh->kex->kex[KEX_DH_GRP14_SHA256] = kexdh_client; 116 ssh->kex->kex[KEX_DH_GRP16_SHA512] = kexdh_client; 117 ssh->kex->kex[KEX_DH_GRP18_SHA512] = kexdh_client; 118 ssh->kex->kex[KEX_DH_GEX_SHA1] = kexgex_client; 119 ssh->kex->kex[KEX_DH_GEX_SHA256] = kexgex_client; 120 ssh->kex->kex[KEX_ECDH_SHA2] = kexecdh_client; 121 #endif /* WITH_OPENSSL */ 122 ssh->kex->kex[KEX_C25519_SHA256] = kexc25519_client; 123 ssh->kex->verify_host_key =&_ssh_verify_host_key; 124 } 125 *sshp = ssh; 126 return 0; 127 } 128 129 void 130 ssh_free(struct ssh *ssh) 131 { 132 struct key_entry *k; 133 134 ssh_packet_close(ssh); 135 /* 136 * we've only created the public keys variants in case we 137 * are a acting as a server. 138 */ 139 while ((k = TAILQ_FIRST(&ssh->public_keys)) != NULL) { 140 TAILQ_REMOVE(&ssh->public_keys, k, next); 141 if (ssh->kex && ssh->kex->server) 142 sshkey_free(k->key); 143 free(k); 144 } 145 while ((k = TAILQ_FIRST(&ssh->private_keys)) != NULL) { 146 TAILQ_REMOVE(&ssh->private_keys, k, next); 147 free(k); 148 } 149 if (ssh->kex) 150 kex_free(ssh->kex); 151 free(ssh); 152 } 153 154 void 155 ssh_set_app_data(struct ssh *ssh, void *app_data) 156 { 157 ssh->app_data = app_data; 158 } 159 160 void * 161 ssh_get_app_data(struct ssh *ssh) 162 { 163 return ssh->app_data; 164 } 165 166 /* Returns < 0 on error, 0 otherwise */ 167 int 168 ssh_add_hostkey(struct ssh *ssh, struct sshkey *key) 169 { 170 struct sshkey *pubkey = NULL; 171 struct key_entry *k = NULL, *k_prv = NULL; 172 int r; 173 174 if (ssh->kex->server) { 175 if ((r = sshkey_from_private(key, &pubkey)) != 0) 176 return r; 177 if ((k = malloc(sizeof(*k))) == NULL || 178 (k_prv = malloc(sizeof(*k_prv))) == NULL) { 179 free(k); 180 sshkey_free(pubkey); 181 return SSH_ERR_ALLOC_FAIL; 182 } 183 k_prv->key = key; 184 TAILQ_INSERT_TAIL(&ssh->private_keys, k_prv, next); 185 186 /* add the public key, too */ 187 k->key = pubkey; 188 TAILQ_INSERT_TAIL(&ssh->public_keys, k, next); 189 r = 0; 190 } else { 191 if ((k = malloc(sizeof(*k))) == NULL) 192 return SSH_ERR_ALLOC_FAIL; 193 k->key = key; 194 TAILQ_INSERT_TAIL(&ssh->public_keys, k, next); 195 r = 0; 196 } 197 198 return r; 199 } 200 201 int 202 ssh_set_verify_host_key_callback(struct ssh *ssh, 203 int (*cb)(struct sshkey *, struct ssh *)) 204 { 205 if (cb == NULL || ssh->kex == NULL) 206 return SSH_ERR_INVALID_ARGUMENT; 207 208 ssh->kex->verify_host_key = cb; 209 210 return 0; 211 } 212 213 int 214 ssh_input_append(struct ssh *ssh, const u_char *data, size_t len) 215 { 216 return sshbuf_put(ssh_packet_get_input(ssh), data, len); 217 } 218 219 int 220 ssh_packet_next(struct ssh *ssh, u_char *typep) 221 { 222 int r; 223 u_int32_t seqnr; 224 u_char type; 225 226 /* 227 * Try to read a packet. Return SSH_MSG_NONE if no packet or not 228 * enough data. 229 */ 230 *typep = SSH_MSG_NONE; 231 if (ssh->kex->client_version_string == NULL || 232 ssh->kex->server_version_string == NULL) 233 return _ssh_exchange_banner(ssh); 234 /* 235 * If we enough data and a dispatch function then 236 * call the function and get the next packet. 237 * Otherwise return the packet type to the caller so it 238 * can decide how to go on. 239 * 240 * We will only call the dispatch function for: 241 * 20-29 Algorithm negotiation 242 * 30-49 Key exchange method specific (numbers can be reused for 243 * different authentication methods) 244 */ 245 for (;;) { 246 if ((r = ssh_packet_read_poll2(ssh, &type, &seqnr)) != 0) 247 return r; 248 if (type > 0 && type < DISPATCH_MAX && 249 type >= SSH2_MSG_KEXINIT && type <= SSH2_MSG_TRANSPORT_MAX && 250 ssh->dispatch[type] != NULL) { 251 if ((r = (*ssh->dispatch[type])(type, seqnr, ssh)) != 0) 252 return r; 253 } else { 254 *typep = type; 255 return 0; 256 } 257 } 258 } 259 260 const u_char * 261 ssh_packet_payload(struct ssh *ssh, size_t *lenp) 262 { 263 return sshpkt_ptr(ssh, lenp); 264 } 265 266 int 267 ssh_packet_put(struct ssh *ssh, int type, const u_char *data, size_t len) 268 { 269 int r; 270 271 if ((r = sshpkt_start(ssh, type)) != 0 || 272 (r = sshpkt_put(ssh, data, len)) != 0 || 273 (r = sshpkt_send(ssh)) != 0) 274 return r; 275 return 0; 276 } 277 278 const u_char * 279 ssh_output_ptr(struct ssh *ssh, size_t *len) 280 { 281 struct sshbuf *output = ssh_packet_get_output(ssh); 282 283 *len = sshbuf_len(output); 284 return sshbuf_ptr(output); 285 } 286 287 int 288 ssh_output_consume(struct ssh *ssh, size_t len) 289 { 290 return sshbuf_consume(ssh_packet_get_output(ssh), len); 291 } 292 293 int 294 ssh_output_space(struct ssh *ssh, size_t len) 295 { 296 return (0 == sshbuf_check_reserve(ssh_packet_get_output(ssh), len)); 297 } 298 299 int 300 ssh_input_space(struct ssh *ssh, size_t len) 301 { 302 return (0 == sshbuf_check_reserve(ssh_packet_get_input(ssh), len)); 303 } 304 305 /* Read other side's version identification. */ 306 int 307 _ssh_read_banner(struct ssh *ssh, char **bannerp) 308 { 309 struct sshbuf *input; 310 const char *s; 311 char buf[256], remote_version[256]; /* must be same size! */ 312 const char *mismatch = "Protocol mismatch.\r\n"; 313 int r, remote_major, remote_minor; 314 size_t i, n, j, len; 315 316 *bannerp = NULL; 317 input = ssh_packet_get_input(ssh); 318 len = sshbuf_len(input); 319 s = (const char *)sshbuf_ptr(input); 320 for (j = n = 0;;) { 321 for (i = 0; i < sizeof(buf) - 1; i++) { 322 if (j >= len) 323 return (0); 324 buf[i] = s[j++]; 325 if (buf[i] == '\r') { 326 buf[i] = '\n'; 327 buf[i + 1] = 0; 328 continue; /**XXX wait for \n */ 329 } 330 if (buf[i] == '\n') { 331 buf[i + 1] = 0; 332 break; 333 } 334 } 335 buf[sizeof(buf) - 1] = 0; 336 if (strncmp(buf, "SSH-", 4) == 0) 337 break; 338 debug("ssh_exchange_identification: %s", buf); 339 if (ssh->kex->server || ++n > 65536) { 340 if ((r = sshbuf_put(ssh_packet_get_output(ssh), 341 mismatch, strlen(mismatch))) != 0) 342 return r; 343 return SSH_ERR_NO_PROTOCOL_VERSION; 344 } 345 } 346 if ((r = sshbuf_consume(input, j)) != 0) 347 return r; 348 349 /* 350 * Check that the versions match. In future this might accept 351 * several versions and set appropriate flags to handle them. 352 */ 353 if (sscanf(buf, "SSH-%d.%d-%[^\n]\n", 354 &remote_major, &remote_minor, remote_version) != 3) 355 return SSH_ERR_INVALID_FORMAT; 356 debug("Remote protocol version %d.%d, remote software version %.100s", 357 remote_major, remote_minor, remote_version); 358 359 ssh->compat = compat_datafellows(remote_version); 360 if (remote_major == 1 && remote_minor == 99) { 361 remote_major = 2; 362 remote_minor = 0; 363 } 364 if (remote_major != 2) 365 return SSH_ERR_PROTOCOL_MISMATCH; 366 chop(buf); 367 debug("Remote version string %.100s", buf); 368 if ((*bannerp = strdup(buf)) == NULL) 369 return SSH_ERR_ALLOC_FAIL; 370 return 0; 371 } 372 373 /* Send our own protocol version identification. */ 374 int 375 _ssh_send_banner(struct ssh *ssh, char **bannerp) 376 { 377 char buf[256]; 378 int r; 379 380 snprintf(buf, sizeof buf, "SSH-2.0-%.100s\r\n", SSH_VERSION); 381 if ((r = sshbuf_put(ssh_packet_get_output(ssh), buf, strlen(buf))) != 0) 382 return r; 383 chop(buf); 384 debug("Local version string %.100s", buf); 385 if ((*bannerp = strdup(buf)) == NULL) 386 return SSH_ERR_ALLOC_FAIL; 387 return 0; 388 } 389 390 int 391 _ssh_exchange_banner(struct ssh *ssh) 392 { 393 struct kex *kex = ssh->kex; 394 int r; 395 396 /* 397 * if _ssh_read_banner() cannot parse a full version string 398 * it will return NULL and we end up calling it again. 399 */ 400 401 r = 0; 402 if (kex->server) { 403 if (kex->server_version_string == NULL) 404 r = _ssh_send_banner(ssh, &kex->server_version_string); 405 if (r == 0 && 406 kex->server_version_string != NULL && 407 kex->client_version_string == NULL) 408 r = _ssh_read_banner(ssh, &kex->client_version_string); 409 } else { 410 if (kex->server_version_string == NULL) 411 r = _ssh_read_banner(ssh, &kex->server_version_string); 412 if (r == 0 && 413 kex->server_version_string != NULL && 414 kex->client_version_string == NULL) 415 r = _ssh_send_banner(ssh, &kex->client_version_string); 416 } 417 if (r != 0) 418 return r; 419 /* start initial kex as soon as we have exchanged the banners */ 420 if (kex->server_version_string != NULL && 421 kex->client_version_string != NULL) { 422 if ((r = _ssh_order_hostkeyalgs(ssh)) != 0 || 423 (r = kex_send_kexinit(ssh)) != 0) 424 return r; 425 } 426 return 0; 427 } 428 429 struct sshkey * 430 _ssh_host_public_key(int type, int nid, struct ssh *ssh) 431 { 432 struct key_entry *k; 433 434 debug3("%s: need %d", __func__, type); 435 TAILQ_FOREACH(k, &ssh->public_keys, next) { 436 debug3("%s: check %s", __func__, sshkey_type(k->key)); 437 if (k->key->type == type && 438 (type != KEY_ECDSA || k->key->ecdsa_nid == nid)) 439 return (k->key); 440 } 441 return (NULL); 442 } 443 444 struct sshkey * 445 _ssh_host_private_key(int type, int nid, struct ssh *ssh) 446 { 447 struct key_entry *k; 448 449 debug3("%s: need %d", __func__, type); 450 TAILQ_FOREACH(k, &ssh->private_keys, next) { 451 debug3("%s: check %s", __func__, sshkey_type(k->key)); 452 if (k->key->type == type && 453 (type != KEY_ECDSA || k->key->ecdsa_nid == nid)) 454 return (k->key); 455 } 456 return (NULL); 457 } 458 459 int 460 _ssh_verify_host_key(struct sshkey *hostkey, struct ssh *ssh) 461 { 462 struct key_entry *k; 463 464 debug3("%s: need %s", __func__, sshkey_type(hostkey)); 465 TAILQ_FOREACH(k, &ssh->public_keys, next) { 466 debug3("%s: check %s", __func__, sshkey_type(k->key)); 467 if (sshkey_equal_public(hostkey, k->key)) 468 return (0); /* ok */ 469 } 470 return (-1); /* failed */ 471 } 472 473 /* offer hostkey algorithms in kexinit depending on registered keys */ 474 int 475 _ssh_order_hostkeyalgs(struct ssh *ssh) 476 { 477 struct key_entry *k; 478 char *orig, *avail, *oavail = NULL, *alg, *replace = NULL; 479 char **proposal; 480 size_t maxlen; 481 int ktype, r; 482 483 /* XXX we de-serialize ssh->kex->my, modify it, and change it */ 484 if ((r = kex_buf2prop(ssh->kex->my, NULL, &proposal)) != 0) 485 return r; 486 orig = proposal[PROPOSAL_SERVER_HOST_KEY_ALGS]; 487 if ((oavail = avail = strdup(orig)) == NULL) { 488 r = SSH_ERR_ALLOC_FAIL; 489 goto out; 490 } 491 maxlen = strlen(avail) + 1; 492 if ((replace = calloc(1, maxlen)) == NULL) { 493 r = SSH_ERR_ALLOC_FAIL; 494 goto out; 495 } 496 *replace = '\0'; 497 while ((alg = strsep(&avail, ",")) && *alg != '\0') { 498 if ((ktype = sshkey_type_from_name(alg)) == KEY_UNSPEC) 499 continue; 500 TAILQ_FOREACH(k, &ssh->public_keys, next) { 501 if (k->key->type == ktype || 502 (sshkey_is_cert(k->key) && k->key->type == 503 sshkey_type_plain(ktype))) { 504 if (*replace != '\0') 505 strlcat(replace, ",", maxlen); 506 strlcat(replace, alg, maxlen); 507 break; 508 } 509 } 510 } 511 if (*replace != '\0') { 512 debug2("%s: orig/%d %s", __func__, ssh->kex->server, orig); 513 debug2("%s: replace/%d %s", __func__, ssh->kex->server, replace); 514 free(orig); 515 proposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = replace; 516 replace = NULL; /* owned by proposal */ 517 r = kex_prop2buf(ssh->kex->my, proposal); 518 } 519 out: 520 free(oavail); 521 free(replace); 522 kex_prop_free(proposal); 523 return r; 524 } 525 526 int 527 _ssh_host_key_sign(struct sshkey *privkey, struct sshkey *pubkey, 528 u_char **signature, size_t *slen, const u_char *data, size_t dlen, 529 const char *alg, u_int compat) 530 { 531 return sshkey_sign(privkey, signature, slen, data, dlen, alg, compat); 532 } 533