authfd.c revision 98941
1168404Spjd/* 2168404Spjd * Author: Tatu Ylonen <ylo@cs.hut.fi> 3168404Spjd * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 4168404Spjd * All rights reserved 5185029Spjd * Functions for connecting the local authentication agent. 6185029Spjd * 7168404Spjd * As far as I am concerned, the code I have written for this software 8168404Spjd * can be used freely for any purpose. Any derived versions of this 9168404Spjd * software must be clearly marked as such, and if the derived work is 10168404Spjd * incompatible with the protocol description in the RFC file, it must be 11168404Spjd * called by a name other than "ssh" or "Secure Shell". 12168404Spjd * 13168404Spjd * SSH2 implementation, 14168404Spjd * Copyright (c) 2000 Markus Friedl. All rights reserved. 15168404Spjd * 16168404Spjd * Redistribution and use in source and binary forms, with or without 17168404Spjd * modification, are permitted provided that the following conditions 18168404Spjd * are met: 19168404Spjd * 1. Redistributions of source code must retain the above copyright 20168404Spjd * notice, this list of conditions and the following disclaimer. 21168404Spjd * 2. Redistributions in binary form must reproduce the above copyright 22219089Spjd * notice, this list of conditions and the following disclaimer in the 23224174Smm * documentation and/or other materials provided with the distribution. 24168404Spjd * 25168404Spjd * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 26185029Spjd * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 27185029Spjd * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 28168404Spjd * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 29168404Spjd * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 30168404Spjd * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 31168404Spjd * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 32168404Spjd * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 33185029Spjd * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 34168404Spjd * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 35168404Spjd */ 36168404Spjd 37224174Smm#include "includes.h" 38224174SmmRCSID("$OpenBSD: authfd.c,v 1.55 2002/06/19 00:27:55 deraadt Exp $"); 39224174Smm 40224174Smm#include <openssl/evp.h> 41224174Smm 42224174Smm#include "ssh.h" 43224174Smm#include "rsa.h" 44224174Smm#include "buffer.h" 45168404Spjd#include "bufaux.h" 46168404Spjd#include "xmalloc.h" 47168404Spjd#include "getput.h" 48185029Spjd#include "key.h" 49168404Spjd#include "authfd.h" 50185029Spjd#include "cipher.h" 51185029Spjd#include "kex.h" 52185029Spjd#include "compat.h" 53192800Strasz#include "log.h" 54185029Spjd#include "atomicio.h" 55185029Spjd 56224174Smm/* helper */ 57224174Smmint decode_reply(int type); 58219089Spjd 59168404Spjd/* macro to check for "agent failure" message */ 60168404Spjd#define agent_failed(x) \ 61224174Smm ((x == SSH_AGENT_FAILURE) || (x == SSH_COM_AGENT2_FAILURE) || \ 62224174Smm (x == SSH2_AGENT_FAILURE)) 63224174Smm 64168404Spjd/* Returns the number of the authentication fd, or -1 if there is none. */ 65185029Spjd 66168404Spjdint 67168404Spjdssh_get_authentication_socket(void) 68168404Spjd{ 69185029Spjd const char *authsocket; 70 int sock; 71 struct sockaddr_un sunaddr; 72 73 authsocket = getenv(SSH_AUTHSOCKET_ENV_NAME); 74 if (!authsocket) 75 return -1; 76 77 sunaddr.sun_family = AF_UNIX; 78 strlcpy(sunaddr.sun_path, authsocket, sizeof(sunaddr.sun_path)); 79 80 sock = socket(AF_UNIX, SOCK_STREAM, 0); 81 if (sock < 0) 82 return -1; 83 84 /* close on exec */ 85 if (fcntl(sock, F_SETFD, 1) == -1) { 86 close(sock); 87 return -1; 88 } 89 if (connect(sock, (struct sockaddr *) &sunaddr, sizeof sunaddr) < 0) { 90 close(sock); 91 return -1; 92 } 93 return sock; 94} 95 96static int 97ssh_request_reply(AuthenticationConnection *auth, Buffer *request, Buffer *reply) 98{ 99 int l, len; 100 char buf[1024]; 101 102 /* Get the length of the message, and format it in the buffer. */ 103 len = buffer_len(request); 104 PUT_32BIT(buf, len); 105 106 /* Send the length and then the packet to the agent. */ 107 if (atomicio(write, auth->fd, buf, 4) != 4 || 108 atomicio(write, auth->fd, buffer_ptr(request), 109 buffer_len(request)) != buffer_len(request)) { 110 error("Error writing to authentication socket."); 111 return 0; 112 } 113 /* 114 * Wait for response from the agent. First read the length of the 115 * response packet. 116 */ 117 len = 4; 118 while (len > 0) { 119 l = read(auth->fd, buf + 4 - len, len); 120 if (l == -1 && (errno == EAGAIN || errno == EINTR)) 121 continue; 122 if (l <= 0) { 123 error("Error reading response length from authentication socket."); 124 return 0; 125 } 126 len -= l; 127 } 128 129 /* Extract the length, and check it for sanity. */ 130 len = GET_32BIT(buf); 131 if (len > 256 * 1024) 132 fatal("Authentication response too long: %d", len); 133 134 /* Read the rest of the response in to the buffer. */ 135 buffer_clear(reply); 136 while (len > 0) { 137 l = len; 138 if (l > sizeof(buf)) 139 l = sizeof(buf); 140 l = read(auth->fd, buf, l); 141 if (l == -1 && (errno == EAGAIN || errno == EINTR)) 142 continue; 143 if (l <= 0) { 144 error("Error reading response from authentication socket."); 145 return 0; 146 } 147 buffer_append(reply, (char *) buf, l); 148 len -= l; 149 } 150 return 1; 151} 152 153/* 154 * Closes the agent socket if it should be closed (depends on how it was 155 * obtained). The argument must have been returned by 156 * ssh_get_authentication_socket(). 157 */ 158 159void 160ssh_close_authentication_socket(int sock) 161{ 162 if (getenv(SSH_AUTHSOCKET_ENV_NAME)) 163 close(sock); 164} 165 166/* 167 * Opens and connects a private socket for communication with the 168 * authentication agent. Returns the file descriptor (which must be 169 * shut down and closed by the caller when no longer needed). 170 * Returns NULL if an error occurred and the connection could not be 171 * opened. 172 */ 173 174AuthenticationConnection * 175ssh_get_authentication_connection(void) 176{ 177 AuthenticationConnection *auth; 178 int sock; 179 180 sock = ssh_get_authentication_socket(); 181 182 /* 183 * Fail if we couldn't obtain a connection. This happens if we 184 * exited due to a timeout. 185 */ 186 if (sock < 0) 187 return NULL; 188 189 auth = xmalloc(sizeof(*auth)); 190 auth->fd = sock; 191 buffer_init(&auth->identities); 192 auth->howmany = 0; 193 194 return auth; 195} 196 197/* 198 * Closes the connection to the authentication agent and frees any associated 199 * memory. 200 */ 201 202void 203ssh_close_authentication_connection(AuthenticationConnection *auth) 204{ 205 buffer_free(&auth->identities); 206 close(auth->fd); 207 xfree(auth); 208} 209 210/* Lock/unlock agent */ 211int 212ssh_lock_agent(AuthenticationConnection *auth, int lock, const char *password) 213{ 214 int type; 215 Buffer msg; 216 217 buffer_init(&msg); 218 buffer_put_char(&msg, lock ? SSH_AGENTC_LOCK : SSH_AGENTC_UNLOCK); 219 buffer_put_cstring(&msg, password); 220 221 if (ssh_request_reply(auth, &msg, &msg) == 0) { 222 buffer_free(&msg); 223 return 0; 224 } 225 type = buffer_get_char(&msg); 226 buffer_free(&msg); 227 return decode_reply(type); 228} 229 230/* 231 * Returns the first authentication identity held by the agent. 232 */ 233 234int 235ssh_get_num_identities(AuthenticationConnection *auth, int version) 236{ 237 int type, code1 = 0, code2 = 0; 238 Buffer request; 239 240 switch (version) { 241 case 1: 242 code1 = SSH_AGENTC_REQUEST_RSA_IDENTITIES; 243 code2 = SSH_AGENT_RSA_IDENTITIES_ANSWER; 244 break; 245 case 2: 246 code1 = SSH2_AGENTC_REQUEST_IDENTITIES; 247 code2 = SSH2_AGENT_IDENTITIES_ANSWER; 248 break; 249 default: 250 return 0; 251 } 252 253 /* 254 * Send a message to the agent requesting for a list of the 255 * identities it can represent. 256 */ 257 buffer_init(&request); 258 buffer_put_char(&request, code1); 259 260 buffer_clear(&auth->identities); 261 if (ssh_request_reply(auth, &request, &auth->identities) == 0) { 262 buffer_free(&request); 263 return 0; 264 } 265 buffer_free(&request); 266 267 /* Get message type, and verify that we got a proper answer. */ 268 type = buffer_get_char(&auth->identities); 269 if (agent_failed(type)) { 270 return 0; 271 } else if (type != code2) { 272 fatal("Bad authentication reply message type: %d", type); 273 } 274 275 /* Get the number of entries in the response and check it for sanity. */ 276 auth->howmany = buffer_get_int(&auth->identities); 277 if (auth->howmany > 1024) 278 fatal("Too many identities in authentication reply: %d", 279 auth->howmany); 280 281 return auth->howmany; 282} 283 284Key * 285ssh_get_first_identity(AuthenticationConnection *auth, char **comment, int version) 286{ 287 /* get number of identities and return the first entry (if any). */ 288 if (ssh_get_num_identities(auth, version) > 0) 289 return ssh_get_next_identity(auth, comment, version); 290 return NULL; 291} 292 293Key * 294ssh_get_next_identity(AuthenticationConnection *auth, char **comment, int version) 295{ 296 u_int bits; 297 u_char *blob; 298 u_int blen; 299 Key *key = NULL; 300 301 /* Return failure if no more entries. */ 302 if (auth->howmany <= 0) 303 return NULL; 304 305 /* 306 * Get the next entry from the packet. These will abort with a fatal 307 * error if the packet is too short or contains corrupt data. 308 */ 309 switch (version) { 310 case 1: 311 key = key_new(KEY_RSA1); 312 bits = buffer_get_int(&auth->identities); 313 buffer_get_bignum(&auth->identities, key->rsa->e); 314 buffer_get_bignum(&auth->identities, key->rsa->n); 315 *comment = buffer_get_string(&auth->identities, NULL); 316 if (bits != BN_num_bits(key->rsa->n)) 317 log("Warning: identity keysize mismatch: actual %d, announced %u", 318 BN_num_bits(key->rsa->n), bits); 319 break; 320 case 2: 321 blob = buffer_get_string(&auth->identities, &blen); 322 *comment = buffer_get_string(&auth->identities, NULL); 323 key = key_from_blob(blob, blen); 324 xfree(blob); 325 break; 326 default: 327 return NULL; 328 break; 329 } 330 /* Decrement the number of remaining entries. */ 331 auth->howmany--; 332 return key; 333} 334 335/* 336 * Generates a random challenge, sends it to the agent, and waits for 337 * response from the agent. Returns true (non-zero) if the agent gave the 338 * correct answer, zero otherwise. Response type selects the style of 339 * response desired, with 0 corresponding to protocol version 1.0 (no longer 340 * supported) and 1 corresponding to protocol version 1.1. 341 */ 342 343int 344ssh_decrypt_challenge(AuthenticationConnection *auth, 345 Key* key, BIGNUM *challenge, 346 u_char session_id[16], 347 u_int response_type, 348 u_char response[16]) 349{ 350 Buffer buffer; 351 int success = 0; 352 int i; 353 int type; 354 355 if (key->type != KEY_RSA1) 356 return 0; 357 if (response_type == 0) { 358 log("Compatibility with ssh protocol version 1.0 no longer supported."); 359 return 0; 360 } 361 buffer_init(&buffer); 362 buffer_put_char(&buffer, SSH_AGENTC_RSA_CHALLENGE); 363 buffer_put_int(&buffer, BN_num_bits(key->rsa->n)); 364 buffer_put_bignum(&buffer, key->rsa->e); 365 buffer_put_bignum(&buffer, key->rsa->n); 366 buffer_put_bignum(&buffer, challenge); 367 buffer_append(&buffer, session_id, 16); 368 buffer_put_int(&buffer, response_type); 369 370 if (ssh_request_reply(auth, &buffer, &buffer) == 0) { 371 buffer_free(&buffer); 372 return 0; 373 } 374 type = buffer_get_char(&buffer); 375 376 if (agent_failed(type)) { 377 log("Agent admitted failure to authenticate using the key."); 378 } else if (type != SSH_AGENT_RSA_RESPONSE) { 379 fatal("Bad authentication response: %d", type); 380 } else { 381 success = 1; 382 /* 383 * Get the response from the packet. This will abort with a 384 * fatal error if the packet is corrupt. 385 */ 386 for (i = 0; i < 16; i++) 387 response[i] = buffer_get_char(&buffer); 388 } 389 buffer_free(&buffer); 390 return success; 391} 392 393/* ask agent to sign data, returns -1 on error, 0 on success */ 394int 395ssh_agent_sign(AuthenticationConnection *auth, 396 Key *key, 397 u_char **sigp, u_int *lenp, 398 u_char *data, u_int datalen) 399{ 400 extern int datafellows; 401 Buffer msg; 402 u_char *blob; 403 u_int blen; 404 int type, flags = 0; 405 int ret = -1; 406 407 if (key_to_blob(key, &blob, &blen) == 0) 408 return -1; 409 410 if (datafellows & SSH_BUG_SIGBLOB) 411 flags = SSH_AGENT_OLD_SIGNATURE; 412 413 buffer_init(&msg); 414 buffer_put_char(&msg, SSH2_AGENTC_SIGN_REQUEST); 415 buffer_put_string(&msg, blob, blen); 416 buffer_put_string(&msg, data, datalen); 417 buffer_put_int(&msg, flags); 418 xfree(blob); 419 420 if (ssh_request_reply(auth, &msg, &msg) == 0) { 421 buffer_free(&msg); 422 return -1; 423 } 424 type = buffer_get_char(&msg); 425 if (agent_failed(type)) { 426 log("Agent admitted failure to sign using the key."); 427 } else if (type != SSH2_AGENT_SIGN_RESPONSE) { 428 fatal("Bad authentication response: %d", type); 429 } else { 430 ret = 0; 431 *sigp = buffer_get_string(&msg, lenp); 432 } 433 buffer_free(&msg); 434 return ret; 435} 436 437/* Encode key for a message to the agent. */ 438 439static void 440ssh_encode_identity_rsa1(Buffer *b, RSA *key, const char *comment) 441{ 442 buffer_put_int(b, BN_num_bits(key->n)); 443 buffer_put_bignum(b, key->n); 444 buffer_put_bignum(b, key->e); 445 buffer_put_bignum(b, key->d); 446 /* To keep within the protocol: p < q for ssh. in SSL p > q */ 447 buffer_put_bignum(b, key->iqmp); /* ssh key->u */ 448 buffer_put_bignum(b, key->q); /* ssh key->p, SSL key->q */ 449 buffer_put_bignum(b, key->p); /* ssh key->q, SSL key->p */ 450 buffer_put_cstring(b, comment); 451} 452 453static void 454ssh_encode_identity_ssh2(Buffer *b, Key *key, const char *comment) 455{ 456 buffer_put_cstring(b, key_ssh_name(key)); 457 switch (key->type) { 458 case KEY_RSA: 459 buffer_put_bignum2(b, key->rsa->n); 460 buffer_put_bignum2(b, key->rsa->e); 461 buffer_put_bignum2(b, key->rsa->d); 462 buffer_put_bignum2(b, key->rsa->iqmp); 463 buffer_put_bignum2(b, key->rsa->p); 464 buffer_put_bignum2(b, key->rsa->q); 465 break; 466 case KEY_DSA: 467 buffer_put_bignum2(b, key->dsa->p); 468 buffer_put_bignum2(b, key->dsa->q); 469 buffer_put_bignum2(b, key->dsa->g); 470 buffer_put_bignum2(b, key->dsa->pub_key); 471 buffer_put_bignum2(b, key->dsa->priv_key); 472 break; 473 } 474 buffer_put_cstring(b, comment); 475} 476 477/* 478 * Adds an identity to the authentication server. This call is not meant to 479 * be used by normal applications. 480 */ 481 482int 483ssh_add_identity_constrained(AuthenticationConnection *auth, Key *key, 484 const char *comment, u_int life) 485{ 486 Buffer msg; 487 int type, constrained = (life != 0); 488 489 buffer_init(&msg); 490 491 switch (key->type) { 492 case KEY_RSA1: 493 type = constrained ? 494 SSH_AGENTC_ADD_RSA_ID_CONSTRAINED : 495 SSH_AGENTC_ADD_RSA_IDENTITY; 496 buffer_put_char(&msg, type); 497 ssh_encode_identity_rsa1(&msg, key->rsa, comment); 498 break; 499 case KEY_RSA: 500 case KEY_DSA: 501 type = constrained ? 502 SSH2_AGENTC_ADD_ID_CONSTRAINED : 503 SSH2_AGENTC_ADD_IDENTITY; 504 buffer_put_char(&msg, type); 505 ssh_encode_identity_ssh2(&msg, key, comment); 506 break; 507 default: 508 buffer_free(&msg); 509 return 0; 510 break; 511 } 512 if (constrained) { 513 if (life != 0) { 514 buffer_put_char(&msg, SSH_AGENT_CONSTRAIN_LIFETIME); 515 buffer_put_int(&msg, life); 516 } 517 } 518 if (ssh_request_reply(auth, &msg, &msg) == 0) { 519 buffer_free(&msg); 520 return 0; 521 } 522 type = buffer_get_char(&msg); 523 buffer_free(&msg); 524 return decode_reply(type); 525} 526 527int 528ssh_add_identity(AuthenticationConnection *auth, Key *key, const char *comment) 529{ 530 return ssh_add_identity_constrained(auth, key, comment, 0); 531} 532 533/* 534 * Removes an identity from the authentication server. This call is not 535 * meant to be used by normal applications. 536 */ 537 538int 539ssh_remove_identity(AuthenticationConnection *auth, Key *key) 540{ 541 Buffer msg; 542 int type; 543 u_char *blob; 544 u_int blen; 545 546 buffer_init(&msg); 547 548 if (key->type == KEY_RSA1) { 549 buffer_put_char(&msg, SSH_AGENTC_REMOVE_RSA_IDENTITY); 550 buffer_put_int(&msg, BN_num_bits(key->rsa->n)); 551 buffer_put_bignum(&msg, key->rsa->e); 552 buffer_put_bignum(&msg, key->rsa->n); 553 } else if (key->type == KEY_DSA || key->type == KEY_RSA) { 554 key_to_blob(key, &blob, &blen); 555 buffer_put_char(&msg, SSH2_AGENTC_REMOVE_IDENTITY); 556 buffer_put_string(&msg, blob, blen); 557 xfree(blob); 558 } else { 559 buffer_free(&msg); 560 return 0; 561 } 562 if (ssh_request_reply(auth, &msg, &msg) == 0) { 563 buffer_free(&msg); 564 return 0; 565 } 566 type = buffer_get_char(&msg); 567 buffer_free(&msg); 568 return decode_reply(type); 569} 570 571int 572ssh_update_card(AuthenticationConnection *auth, int add, const char *reader_id, const char *pin) 573{ 574 Buffer msg; 575 int type; 576 577 buffer_init(&msg); 578 buffer_put_char(&msg, add ? SSH_AGENTC_ADD_SMARTCARD_KEY : 579 SSH_AGENTC_REMOVE_SMARTCARD_KEY); 580 buffer_put_cstring(&msg, reader_id); 581 buffer_put_cstring(&msg, pin); 582 if (ssh_request_reply(auth, &msg, &msg) == 0) { 583 buffer_free(&msg); 584 return 0; 585 } 586 type = buffer_get_char(&msg); 587 buffer_free(&msg); 588 return decode_reply(type); 589} 590 591/* 592 * Removes all identities from the agent. This call is not meant to be used 593 * by normal applications. 594 */ 595 596int 597ssh_remove_all_identities(AuthenticationConnection *auth, int version) 598{ 599 Buffer msg; 600 int type; 601 int code = (version==1) ? 602 SSH_AGENTC_REMOVE_ALL_RSA_IDENTITIES : 603 SSH2_AGENTC_REMOVE_ALL_IDENTITIES; 604 605 buffer_init(&msg); 606 buffer_put_char(&msg, code); 607 608 if (ssh_request_reply(auth, &msg, &msg) == 0) { 609 buffer_free(&msg); 610 return 0; 611 } 612 type = buffer_get_char(&msg); 613 buffer_free(&msg); 614 return decode_reply(type); 615} 616 617int 618decode_reply(int type) 619{ 620 switch (type) { 621 case SSH_AGENT_FAILURE: 622 case SSH_COM_AGENT2_FAILURE: 623 case SSH2_AGENT_FAILURE: 624 log("SSH_AGENT_FAILURE"); 625 return 0; 626 case SSH_AGENT_SUCCESS: 627 return 1; 628 default: 629 fatal("Bad response from authentication agent: %d", type); 630 } 631 /* NOTREACHED */ 632 return 0; 633} 634