Ticket #27250: openssh-5.3p1-gsskex-all-20100124.patch
File openssh-5.3p1-gsskex-all-20100124.patch, 88.2 KB (added by lassi.tuura@…, 14 years ago) |
---|
-
openssh-5.3p1
old new 1 1 /* $OpenBSD: gss-serv.c,v 1.22 2008/05/08 12:02:23 djm Exp $ */ 2 2 3 3 /* 4 * Copyright (c) 2001-200 3Simon Wilkinson. All rights reserved.4 * Copyright (c) 2001-2009 Simon Wilkinson. All rights reserved. 5 5 * 6 6 * Redistribution and use in source and binary forms, with or without 7 7 * modification, are permitted provided that the following conditions … … 45 45 #include "channels.h" 46 46 #include "session.h" 47 47 #include "misc.h" 48 #include "servconf.h" 49 #include "uidswap.h" 48 50 49 51 #include "ssh-gss.h" 52 #include "monitor_wrap.h" 53 54 extern ServerOptions options; 50 55 51 56 static ssh_gssapi_client gssapi_client = 52 57 { GSS_C_EMPTY_BUFFER, GSS_C_EMPTY_BUFFER, 53 GSS_C_NO_CREDENTIAL, NULL, {NULL, NULL, NULL}};58 GSS_C_NO_CREDENTIAL, GSS_C_NO_NAME, NULL, {NULL, NULL, NULL}, 0, 0}; 54 59 55 60 ssh_gssapi_mech gssapi_null_mech = 56 { NULL, NULL, {0, NULL}, NULL, NULL, NULL, NULL };61 { NULL, NULL, {0, NULL}, NULL, NULL, NULL, NULL, NULL}; 57 62 58 63 #ifdef KRB5 59 64 extern ssh_gssapi_mech gssapi_kerberos_mech; … … 81 86 char lname[MAXHOSTNAMELEN]; 82 87 gss_OID_set oidset; 83 88 84 gss_create_empty_oid_set(&status, &oidset); 85 gss_add_oid_set_member(&status, ctx->oid, &oidset); 89 if (options.gss_strict_acceptor) { 90 gss_create_empty_oid_set(&status, &oidset); 91 gss_add_oid_set_member(&status, ctx->oid, &oidset); 92 93 if (gethostname(lname, MAXHOSTNAMELEN)) { 94 gss_release_oid_set(&status, &oidset); 95 return (-1); 96 } 86 97 87 if (gethostname(lname, MAXHOSTNAMELEN)) { 88 gss_release_oid_set(&status, &oidset); 89 return (-1); 90 } 98 if (GSS_ERROR(ssh_gssapi_import_name(ctx, lname))) { 99 gss_release_oid_set(&status, &oidset); 100 return (ctx->major); 101 } 102 103 if ((ctx->major = gss_acquire_cred(&ctx->minor, 104 ctx->name, 0, oidset, GSS_C_ACCEPT, &ctx->creds, 105 NULL, NULL))) 106 ssh_gssapi_error(ctx); 91 107 92 if (GSS_ERROR(ssh_gssapi_import_name(ctx, lname))) {93 108 gss_release_oid_set(&status, &oidset); 94 109 return (ctx->major); 110 } else { 111 ctx->name = GSS_C_NO_NAME; 112 ctx->creds = GSS_C_NO_CREDENTIAL; 95 113 } 96 97 if ((ctx->major = gss_acquire_cred(&ctx->minor, 98 ctx->name, 0, oidset, GSS_C_ACCEPT, &ctx->creds, NULL, NULL))) 99 ssh_gssapi_error(ctx); 100 101 gss_release_oid_set(&status, &oidset); 102 return (ctx->major); 114 return GSS_S_COMPLETE; 103 115 } 104 116 105 117 /* Privileged */ … … 114 126 } 115 127 116 128 /* Unprivileged */ 129 char * 130 ssh_gssapi_server_mechanisms() { 131 gss_OID_set supported; 132 133 ssh_gssapi_supported_oids(&supported); 134 return (ssh_gssapi_kex_mechs(supported, &ssh_gssapi_server_check_mech, 135 NULL, NULL)); 136 } 137 138 /* Unprivileged */ 139 int 140 ssh_gssapi_server_check_mech(Gssctxt **dum, gss_OID oid, const char *data, 141 const char *dummy) { 142 Gssctxt *ctx = NULL; 143 int res; 144 145 res = !GSS_ERROR(PRIVSEP(ssh_gssapi_server_ctx(&ctx, oid))); 146 ssh_gssapi_delete_ctx(&ctx); 147 148 return (res); 149 } 150 151 /* Unprivileged */ 117 152 void 118 153 ssh_gssapi_supported_oids(gss_OID_set *oidset) 119 154 { … … 123 158 gss_OID_set supported; 124 159 125 160 gss_create_empty_oid_set(&min_status, oidset); 126 gss_indicate_mechs(&min_status, &supported); 161 162 if (GSS_ERROR(gss_indicate_mechs(&min_status, &supported))) 163 return; 127 164 128 165 while (supported_mechs[i]->name != NULL) { 129 166 if (GSS_ERROR(gss_test_oid_set_member(&min_status, … … 247 284 ssh_gssapi_getclient(Gssctxt *ctx, ssh_gssapi_client *client) 248 285 { 249 286 int i = 0; 287 int equal = 0; 288 gss_name_t new_name = GSS_C_NO_NAME; 289 gss_buffer_desc ename = GSS_C_EMPTY_BUFFER; 290 291 if (options.gss_store_rekey && client->used && ctx->client_creds) { 292 if (client->mech->oid.length != ctx->oid->length || 293 (memcmp(client->mech->oid.elements, 294 ctx->oid->elements, ctx->oid->length) !=0)) { 295 debug("Rekeyed credentials have different mechanism"); 296 return GSS_S_COMPLETE; 297 } 298 299 if ((ctx->major = gss_inquire_cred_by_mech(&ctx->minor, 300 ctx->client_creds, ctx->oid, &new_name, 301 NULL, NULL, NULL))) { 302 ssh_gssapi_error(ctx); 303 return (ctx->major); 304 } 305 306 ctx->major = gss_compare_name(&ctx->minor, client->name, 307 new_name, &equal); 250 308 251 gss_buffer_desc ename; 309 if (GSS_ERROR(ctx->major)) { 310 ssh_gssapi_error(ctx); 311 return (ctx->major); 312 } 313 314 if (!equal) { 315 debug("Rekeyed credentials have different name"); 316 return GSS_S_COMPLETE; 317 } 318 319 debug("Marking rekeyed credentials for export"); 320 321 gss_release_name(&ctx->minor, &client->name); 322 gss_release_cred(&ctx->minor, &client->creds); 323 client->name = new_name; 324 client->creds = ctx->client_creds; 325 ctx->client_creds = GSS_C_NO_CREDENTIAL; 326 client->updated = 1; 327 return GSS_S_COMPLETE; 328 } 252 329 253 330 client->mech = NULL; 254 331 … … 263 340 if (client->mech == NULL) 264 341 return GSS_S_FAILURE; 265 342 343 if (ctx->client_creds && 344 (ctx->major = gss_inquire_cred_by_mech(&ctx->minor, 345 ctx->client_creds, ctx->oid, &client->name, NULL, NULL, NULL))) { 346 ssh_gssapi_error(ctx); 347 return (ctx->major); 348 } 349 266 350 if ((ctx->major = gss_display_name(&ctx->minor, ctx->client, 267 351 &client->displayname, NULL))) { 268 352 ssh_gssapi_error(ctx); … … 280 364 return (ctx->major); 281 365 } 282 366 367 gss_release_buffer(&ctx->minor, &ename); 368 283 369 /* We can't copy this structure, so we just move the pointer to it */ 284 370 client->creds = ctx->client_creds; 285 371 ctx->client_creds = GSS_C_NO_CREDENTIAL; … … 327 413 328 414 /* Privileged */ 329 415 int 330 ssh_gssapi_userok(char *user )416 ssh_gssapi_userok(char *user, struct passwd *pw) 331 417 { 332 418 OM_uint32 lmin; 333 419 … … 337 423 return 0; 338 424 } 339 425 if (gssapi_client.mech && gssapi_client.mech->userok) 340 if ((*gssapi_client.mech->userok)(&gssapi_client, user)) 426 if ((*gssapi_client.mech->userok)(&gssapi_client, user)) { 427 gssapi_client.used = 1; 428 gssapi_client.store.owner = pw; 341 429 return 1; 342 else {430 } else { 343 431 /* Destroy delegated credentials if userok fails */ 344 432 gss_release_buffer(&lmin, &gssapi_client.displayname); 345 433 gss_release_buffer(&lmin, &gssapi_client.exportedname); … … 352 440 return (0); 353 441 } 354 442 355 /* Privileged */ 356 OM_uint32 357 ssh_gssapi_checkmic(Gssctxt *ctx, gss_buffer_t gssbuf, gss_buffer_t gssmic) 443 /* These bits are only used for rekeying. The unpriviledged child is running 444 * as the user, the monitor is root. 445 * 446 * In the child, we want to : 447 * *) Ask the monitor to store our credentials into the store we specify 448 * *) If it succeeds, maybe do a PAM update 449 */ 450 451 /* Stuff for PAM */ 452 453 #ifdef USE_PAM 454 static int ssh_gssapi_simple_conv(int n, const struct pam_message **msg, 455 struct pam_response **resp, void *data) 358 456 { 359 ctx->major = gss_verify_mic(&ctx->minor, ctx->context, 360 gssbuf, gssmic, NULL); 457 return (PAM_CONV_ERR); 458 } 459 #endif 361 460 362 return (ctx->major); 461 void 462 ssh_gssapi_rekey_creds() { 463 int ok; 464 int ret; 465 #ifdef USE_PAM 466 pam_handle_t *pamh = NULL; 467 struct pam_conv pamconv = {ssh_gssapi_simple_conv, NULL}; 468 char *envstr; 469 #endif 470 471 if (gssapi_client.store.filename == NULL && 472 gssapi_client.store.envval == NULL && 473 gssapi_client.store.envvar == NULL) 474 return; 475 476 ok = PRIVSEP(ssh_gssapi_update_creds(&gssapi_client.store)); 477 478 if (!ok) 479 return; 480 481 debug("Rekeyed credentials stored successfully"); 482 483 /* Actually managing to play with the ssh pam stack from here will 484 * be next to impossible. In any case, we may want different options 485 * for rekeying. So, use our own :) 486 */ 487 #ifdef USE_PAM 488 if (!use_privsep) { 489 debug("Not even going to try and do PAM with privsep disabled"); 490 return; 491 } 492 493 ret = pam_start("sshd-rekey", gssapi_client.store.owner->pw_name, 494 &pamconv, &pamh); 495 if (ret) 496 return; 497 498 xasprintf(&envstr, "%s=%s", gssapi_client.store.envvar, 499 gssapi_client.store.envval); 500 501 ret = pam_putenv(pamh, envstr); 502 if (!ret) 503 pam_setcred(pamh, PAM_REINITIALIZE_CRED); 504 pam_end(pamh, PAM_SUCCESS); 505 #endif 506 } 507 508 int 509 ssh_gssapi_update_creds(ssh_gssapi_ccache *store) { 510 int ok = 0; 511 512 /* Check we've got credentials to store */ 513 if (!gssapi_client.updated) 514 return 0; 515 516 gssapi_client.updated = 0; 517 518 temporarily_use_uid(gssapi_client.store.owner); 519 if (gssapi_client.mech && gssapi_client.mech->updatecreds) 520 ok = (*gssapi_client.mech->updatecreds)(store, &gssapi_client); 521 else 522 debug("No update function for this mechanism"); 523 524 restore_uid(); 525 526 return ok; 363 527 } 364 528 365 529 #endif -
openssh-5.3p1
old new 92 92 options->kerberos_ticket_cleanup = -1; 93 93 options->kerberos_get_afs_token = -1; 94 94 options->gss_authentication=-1; 95 options->gss_keyex = -1; 95 96 options->gss_cleanup_creds = -1; 97 options->gss_strict_acceptor = -1; 98 options->gss_store_rekey = -1; 96 99 options->password_authentication = -1; 97 100 options->kbd_interactive_authentication = -1; 98 101 options->challenge_response_authentication = -1; … … 210 213 options->kerberos_get_afs_token = 0; 211 214 if (options->gss_authentication == -1) 212 215 options->gss_authentication = 0; 216 if (options->gss_keyex == -1) 217 options->gss_keyex = 0; 213 218 if (options->gss_cleanup_creds == -1) 214 219 options->gss_cleanup_creds = 1; 220 if (options->gss_strict_acceptor == -1) 221 options->gss_strict_acceptor = 1; 222 if (options->gss_store_rekey == -1) 223 options->gss_store_rekey = 0; 215 224 if (options->password_authentication == -1) 216 225 options->password_authentication = 1; 217 226 if (options->kbd_interactive_authentication == -1) … … 302 311 sBanner, sUseDNS, sHostbasedAuthentication, 303 312 sHostbasedUsesNameFromPacketOnly, sClientAliveInterval, 304 313 sClientAliveCountMax, sAuthorizedKeysFile, sAuthorizedKeysFile2, 305 sGssAuthentication, sGssCleanupCreds, sAcceptEnv, sPermitTunnel, 314 sGssAuthentication, sGssCleanupCreds, sGssStrictAcceptor, 315 sGssKeyEx, sGssStoreRekey, 316 sAcceptEnv, sPermitTunnel, 306 317 sMatch, sPermitOpen, sForceCommand, sChrootDirectory, 307 318 sUsePrivilegeSeparation, sAllowAgentForwarding, 308 319 sZeroKnowledgePasswordAuthentication, … … 364 375 #ifdef GSSAPI 365 376 { "gssapiauthentication", sGssAuthentication, SSHCFG_ALL }, 366 377 { "gssapicleanupcredentials", sGssCleanupCreds, SSHCFG_GLOBAL }, 378 { "gssapistrictacceptorcheck", sGssStrictAcceptor, SSHCFG_GLOBAL }, 379 { "gssapikeyexchange", sGssKeyEx, SSHCFG_GLOBAL }, 380 { "gssapistorecredentialsonrekey", sGssStoreRekey, SSHCFG_GLOBAL }, 367 381 #else 368 382 { "gssapiauthentication", sUnsupported, SSHCFG_ALL }, 369 383 { "gssapicleanupcredentials", sUnsupported, SSHCFG_GLOBAL }, 384 { "gssapistrictacceptorcheck", sUnsupported, SSHCFG_GLOBAL }, 385 { "gssapikeyexchange", sUnsupported, SSHCFG_GLOBAL }, 386 { "gssapistorecredentialsonrekey", sUnsupported, SSHCFG_GLOBAL }, 370 387 #endif 371 388 { "passwordauthentication", sPasswordAuthentication, SSHCFG_ALL }, 372 389 { "kbdinteractiveauthentication", sKbdInteractiveAuthentication, SSHCFG_ALL }, … … 891 908 intptr = &options->gss_authentication; 892 909 goto parse_flag; 893 910 911 case sGssKeyEx: 912 intptr = &options->gss_keyex; 913 goto parse_flag; 914 894 915 case sGssCleanupCreds: 895 916 intptr = &options->gss_cleanup_creds; 896 917 goto parse_flag; 897 918 919 case sGssStrictAcceptor: 920 intptr = &options->gss_strict_acceptor; 921 goto parse_flag; 922 923 case sGssStoreRekey: 924 intptr = &options->gss_store_rekey; 925 goto parse_flag; 926 898 927 case sPasswordAuthentication: 899 928 intptr = &options->password_authentication; 900 929 goto parse_flag; -
openssh-5.3p1
old new 91 91 int kerberos_get_afs_token; /* If true, try to get AFS token if 92 92 * authenticated with Kerberos. */ 93 93 int gss_authentication; /* If true, permit GSSAPI authentication */ 94 int gss_keyex; /* If true, permit GSSAPI key exchange */ 94 95 int gss_cleanup_creds; /* If true, destroy cred cache on logout */ 96 int gss_strict_acceptor; /* If true, restrict the GSSAPI acceptor name */ 97 int gss_store_rekey; 95 98 int password_authentication; /* If true, permit password 96 99 * authentication. */ 97 100 int kbd_interactive_authentication; /* If true, permit */ -
openssh-5.3p1
old new 73 73 # GSSAPI options 74 74 #GSSAPIAuthentication no 75 75 #GSSAPICleanupCredentials yes 76 #GSSAPIStrictAcceptorCheck yes 77 #GSSAPIKeyExchange no 76 78 77 79 # Set this to 'yes' to enable PAM authentication, account processing, 78 80 # and session processing. If this is enabled, PAM authentication will -
sshd_config.5
old new 379 379 The default is 380 380 .Dq no . 381 381 Note that this option applies to protocol version 2 only. 382 .It Cm GSSAPIKeyExchange 383 Specifies whether key exchange based on GSSAPI is allowed. GSSAPI key exchange 384 doesn't rely on ssh keys to verify host identity. 385 The default is 386 .Dq no . 387 Note that this option applies to protocol version 2 only. 382 388 .It Cm GSSAPICleanupCredentials 383 389 Specifies whether to automatically destroy the user's credentials cache 384 390 on logout. 385 391 The default is 386 392 .Dq yes . 387 393 Note that this option applies to protocol version 2 only. 394 .It Cm GSSAPIStrictAcceptorCheck 395 Determines whether to be strict about the identity of the GSSAPI acceptor 396 a client authenticates against. If 397 .Dq yes 398 then the client must authenticate against the 399 .Pa host 400 service on the current hostname. If 401 .Dq no 402 then the client may authenticate against any service key stored in the 403 machine's default store. This facility is provided to assist with operation 404 on multi homed machines. 405 The default is 406 .Dq yes . 407 Note that this option applies only to protocol version 2 GSSAPI connections, 408 and setting it to 409 .Dq no 410 may only work with recent Kerberos GSSAPI libraries. 411 .It Cm GSSAPIStoreCredentialsOnRekey 412 Controls whether the user's GSSAPI credentials should be updated following a 413 successful connection rekeying. This option can be used to accepted renewed 414 or updated credentials from a compatible client. The default is 415 .Dq no . 388 416 .It Cm HostbasedAuthentication 389 417 Specifies whether rhosts or /etc/hosts.equiv authentication together 390 418 with successful public key client host authentication is allowed -
openssh-5.3p1
old new 127 127 oClearAllForwardings, oNoHostAuthenticationForLocalhost, 128 128 oEnableSSHKeysign, oRekeyLimit, oVerifyHostKeyDNS, oConnectTimeout, 129 129 oAddressFamily, oGssAuthentication, oGssDelegateCreds, 130 oGssTrustDns, oGssKeyEx, oGssClientIdentity, oGssRenewalRekey, 130 131 oServerAliveInterval, oServerAliveCountMax, oIdentitiesOnly, 131 132 oSendEnv, oControlPath, oControlMaster, oHashKnownHosts, 132 133 oTunnel, oTunnelDevice, oLocalCommand, oPermitLocalCommand, … … 164 165 { "afstokenpassing", oUnsupported }, 165 166 #if defined(GSSAPI) 166 167 { "gssapiauthentication", oGssAuthentication }, 168 { "gssapikeyexchange", oGssKeyEx }, 167 169 { "gssapidelegatecredentials", oGssDelegateCreds }, 170 { "gssapitrustdns", oGssTrustDns }, 171 { "gssapiclientidentity", oGssClientIdentity }, 172 { "gssapirenewalforcesrekey", oGssRenewalRekey }, 168 173 #else 169 174 { "gssapiauthentication", oUnsupported }, 175 { "gssapikeyexchange", oUnsupported }, 170 176 { "gssapidelegatecredentials", oUnsupported }, 177 { "gssapitrustdns", oUnsupported }, 178 { "gssapiclientidentity", oUnsupported }, 179 { "gssapirenewalforcesrekey", oUnsupported }, 171 180 #endif 172 181 { "fallbacktorsh", oDeprecated }, 173 182 { "usersh", oDeprecated }, … … 454 463 intptr = &options->gss_authentication; 455 464 goto parse_flag; 456 465 466 case oGssKeyEx: 467 intptr = &options->gss_keyex; 468 goto parse_flag; 469 457 470 case oGssDelegateCreds: 458 471 intptr = &options->gss_deleg_creds; 459 472 goto parse_flag; 460 473 474 case oGssTrustDns: 475 intptr = &options->gss_trust_dns; 476 goto parse_flag; 477 478 case oGssClientIdentity: 479 charptr = &options->gss_client_identity; 480 goto parse_string; 481 482 case oGssRenewalRekey: 483 intptr = &options->gss_renewal_rekey; 484 goto parse_flag; 485 461 486 case oBatchMode: 462 487 intptr = &options->batch_mode; 463 488 goto parse_flag; … … 1013 1038 options->pubkey_authentication = -1; 1014 1039 options->challenge_response_authentication = -1; 1015 1040 options->gss_authentication = -1; 1041 options->gss_keyex = -1; 1016 1042 options->gss_deleg_creds = -1; 1043 options->gss_trust_dns = -1; 1044 options->gss_renewal_rekey = -1; 1045 options->gss_client_identity = NULL; 1017 1046 options->password_authentication = -1; 1018 1047 options->kbd_interactive_authentication = -1; 1019 1048 options->kbd_interactive_devices = NULL; … … 1105 1134 options->challenge_response_authentication = 1; 1106 1135 if (options->gss_authentication == -1) 1107 1136 options->gss_authentication = 0; 1137 if (options->gss_keyex == -1) 1138 options->gss_keyex = 0; 1108 1139 if (options->gss_deleg_creds == -1) 1109 1140 options->gss_deleg_creds = 0; 1141 if (options->gss_trust_dns == -1) 1142 options->gss_trust_dns = 0; 1143 if (options->gss_renewal_rekey == -1) 1144 options->gss_renewal_rekey = 0; 1110 1145 if (options->password_authentication == -1) 1111 1146 options->password_authentication = 1; 1112 1147 if (options->kbd_interactive_authentication == -1) -
openssh-5.3p1
old new 44 44 int challenge_response_authentication; 45 45 /* Try S/Key or TIS, authentication. */ 46 46 int gss_authentication; /* Try GSS authentication */ 47 int gss_keyex; /* Try GSS key exchange */ 47 48 int gss_deleg_creds; /* Delegate GSS credentials */ 49 int gss_trust_dns; /* Trust DNS for GSS canonicalization */ 50 int gss_renewal_rekey; /* Credential renewal forces rekey */ 51 char *gss_client_identity; /* Principal to initiate GSSAPI with */ 48 52 int password_authentication; /* Try password 49 53 * authentication. */ 50 54 int kbd_interactive_authentication; /* Try keyboard-interactive auth. */ -
ssh_config.5
old new 478 478 The default is 479 479 .Dq no . 480 480 Note that this option applies to protocol version 2 only. 481 .It Cm GSSAPIKeyExchange 482 Specifies whether key exchange based on GSSAPI may be used. When using 483 GSSAPI key exchange the server need not have a host key. 484 The default is 485 .Dq no . 486 Note that this option applies to protocol version 2 only. 487 .It Cm GSSAPIClientIdentity 488 If set, specifies the GSSAPI client identity that ssh should use when 489 connecting to the server. The default is unset, which means that the default 490 identity will be used. 481 491 .It Cm GSSAPIDelegateCredentials 482 492 Forward (delegate) credentials to the server. 483 493 The default is 484 494 .Dq no . 485 Note that this option applies to protocol version 2 only. 495 Note that this option applies to protocol version 2 connections using GSSAPI. 496 .It Cm GSSAPIRenewalForcesRekey 497 If set to 498 .Dq yes 499 then renewal of the client's GSSAPI credentials will force the rekeying of the 500 ssh connection. With a compatible server, this can delegate the renewed 501 credentials to a session on the server. 502 The default is 503 .Dq no . 504 .It Cm GSSAPITrustDns 505 Set to 506 .Dq yes to indicate that the DNS is trusted to securely canonicalize 507 the name of the host being connected to. If 508 .Dq no, the hostname entered on the 509 command line will be passed untouched to the GSSAPI library. 510 The default is 511 .Dq no . 512 This option only applies to protocol version 2 connections using GSSAPI. 486 513 .It Cm HashKnownHosts 487 514 Indicates that 488 515 .Xr ssh 1 -
sshconnect2.c
old new 105 105 { 106 106 Kex *kex; 107 107 108 #ifdef GSSAPI 109 char *orig = NULL, *gss = NULL; 110 char *gss_host = NULL; 111 #endif 112 108 113 xxx_host = host; 109 114 xxx_hostaddr = hostaddr; 110 115 116 #ifdef GSSAPI 117 if (options.gss_keyex) { 118 /* Add the GSSAPI mechanisms currently supported on this 119 * client to the key exchange algorithm proposal */ 120 orig = myproposal[PROPOSAL_KEX_ALGS]; 121 122 if (options.gss_trust_dns) 123 gss_host = (char *)get_canonical_hostname(1); 124 else 125 gss_host = host; 126 127 gss = ssh_gssapi_client_mechanisms(gss_host, options.gss_client_identity); 128 if (gss) { 129 debug("Offering GSSAPI proposal: %s", gss); 130 xasprintf(&myproposal[PROPOSAL_KEX_ALGS], 131 "%s,%s", gss, orig); 132 } 133 } 134 #endif 135 111 136 if (options.ciphers == (char *)-1) { 112 137 logit("No valid ciphers for protocol version 2 given, using defaults."); 113 138 options.ciphers = NULL; … … 135 160 myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = 136 161 options.hostkeyalgorithms; 137 162 163 #ifdef GSSAPI 164 /* If we've got GSSAPI algorithms, then we also support the 165 * 'null' hostkey, as a last resort */ 166 if (options.gss_keyex && gss) { 167 orig = myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS]; 168 xasprintf(&myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS], 169 "%s,null", orig); 170 xfree(gss); 171 } 172 #endif 173 138 174 if (options.rekey_limit) 139 175 packet_set_rekey_limit((u_int32_t)options.rekey_limit); 140 176 … … 144 180 kex->kex[KEX_DH_GRP14_SHA1] = kexdh_client; 145 181 kex->kex[KEX_DH_GEX_SHA1] = kexgex_client; 146 182 kex->kex[KEX_DH_GEX_SHA256] = kexgex_client; 183 #ifdef GSSAPI 184 if (options.gss_keyex) { 185 kex->kex[KEX_GSS_GRP1_SHA1] = kexgss_client; 186 kex->kex[KEX_GSS_GRP14_SHA1] = kexgss_client; 187 kex->kex[KEX_GSS_GEX_SHA1] = kexgss_client; 188 } 189 #endif 147 190 kex->client_version_string=client_version_string; 148 191 kex->server_version_string=server_version_string; 149 192 kex->verify_host_key=&verify_host_key_callback; 150 193 194 #ifdef GSSAPI 195 if (options.gss_keyex) { 196 kex->gss_deleg_creds = options.gss_deleg_creds; 197 kex->gss_trust_dns = options.gss_trust_dns; 198 kex->gss_client = options.gss_client_identity; 199 kex->gss_host = gss_host; 200 } 201 #endif 202 151 203 xxx_kex = kex; 152 204 153 205 dispatch_run(DISPATCH_BLOCK, &kex->done, kex); … … 236 288 void input_gssapi_hash(int type, u_int32_t, void *); 237 289 void input_gssapi_error(int, u_int32_t, void *); 238 290 void input_gssapi_errtok(int, u_int32_t, void *); 291 int userauth_gsskeyex(Authctxt *authctxt); 239 292 #endif 240 293 241 294 void userauth(Authctxt *, char *); … … 251 304 252 305 Authmethod authmethods[] = { 253 306 #ifdef GSSAPI 307 {"gssapi-keyex", 308 userauth_gsskeyex, 309 NULL, 310 &options.gss_authentication, 311 NULL}, 254 312 {"gssapi-with-mic", 255 313 userauth_gssapi, 256 314 NULL, … … 542 600 static u_int mech = 0; 543 601 OM_uint32 min; 544 602 int ok = 0; 603 const char *gss_host; 604 605 if (options.gss_trust_dns) 606 gss_host = get_canonical_hostname(1); 607 else 608 gss_host = authctxt->host; 545 609 546 610 /* Try one GSSAPI method at a time, rather than sending them all at 547 611 * once. */ 548 612 549 613 if (gss_supported == NULL) 550 gss_indicate_mechs(&min, &gss_supported); 614 if (GSS_ERROR(gss_indicate_mechs(&min, &gss_supported))) { 615 gss_supported = NULL; 616 return 0; 617 } 551 618 552 619 /* Check to see if the mechanism is usable before we offer it */ 553 620 while (mech < gss_supported->count && !ok) { 554 621 /* My DER encoding requires length<128 */ 555 622 if (gss_supported->elements[mech].length < 128 && 556 623 ssh_gssapi_check_mechanism(&gssctxt, 557 &gss_supported->elements[mech], authctxt->host)) { 624 &gss_supported->elements[mech], gss_host, 625 options.gss_client_identity)) { 558 626 ok = 1; /* Mechanism works */ 559 627 } else { 560 628 mech++; … … 651 719 { 652 720 Authctxt *authctxt = ctxt; 653 721 Gssctxt *gssctxt; 654 int oidlen;655 char *oidv;722 u_int oidlen; 723 u_char *oidv; 656 724 657 725 if (authctxt == NULL) 658 726 fatal("input_gssapi_response: no authentication context"); … … 762 830 xfree(msg); 763 831 xfree(lang); 764 832 } 833 834 int 835 userauth_gsskeyex(Authctxt *authctxt) 836 { 837 Buffer b; 838 gss_buffer_desc gssbuf; 839 gss_buffer_desc mic = GSS_C_EMPTY_BUFFER; 840 OM_uint32 ms; 841 842 static int attempt = 0; 843 if (attempt++ >= 1) 844 return (0); 845 846 if (gss_kex_context == NULL) { 847 debug("No valid Key exchange context"); 848 return (0); 849 } 850 851 ssh_gssapi_buildmic(&b, authctxt->server_user, authctxt->service, 852 "gssapi-keyex"); 853 854 gssbuf.value = buffer_ptr(&b); 855 gssbuf.length = buffer_len(&b); 856 857 if (GSS_ERROR(ssh_gssapi_sign(gss_kex_context, &gssbuf, &mic))) { 858 buffer_free(&b); 859 return (0); 860 } 861 862 packet_start(SSH2_MSG_USERAUTH_REQUEST); 863 packet_put_cstring(authctxt->server_user); 864 packet_put_cstring(authctxt->service); 865 packet_put_cstring(authctxt->method->name); 866 packet_put_string(mic.value, mic.length); 867 packet_send(); 868 869 buffer_free(&b); 870 gss_release_buffer(&ms, &mic); 871 872 return (1); 873 } 874 765 875 #endif /* GSSAPI */ 766 876 767 877 int -
openssh-5.3p1
old new 53 53 int valid; /* user exists and is allowed to login */ 54 54 int attempt; 55 55 int failures; 56 int server_caused_failure; 56 57 int force_pwchange; 57 58 char *user; /* username sent by the client */ 58 59 char *service; -
openssh-5.3p1
old new 1 1 /* $OpenBSD: auth2-gss.c,v 1.16 2007/10/29 00:52:45 dtucker Exp $ */ 2 2 3 3 /* 4 * Copyright (c) 2001-200 3Simon Wilkinson. All rights reserved.4 * Copyright (c) 2001-2007 Simon Wilkinson. All rights reserved. 5 5 * 6 6 * Redistribution and use in source and binary forms, with or without 7 7 * modification, are permitted provided that the following conditions … … 52 52 static void input_gssapi_exchange_complete(int type, u_int32_t plen, void *ctxt); 53 53 static void input_gssapi_errtok(int, u_int32_t, void *); 54 54 55 /* 56 * The 'gssapi_keyex' userauth mechanism. 57 */ 58 static int 59 userauth_gsskeyex(Authctxt *authctxt) 60 { 61 int authenticated = 0; 62 Buffer b; 63 gss_buffer_desc mic, gssbuf; 64 u_int len; 65 66 mic.value = packet_get_string(&len); 67 mic.length = len; 68 69 packet_check_eom(); 70 71 ssh_gssapi_buildmic(&b, authctxt->user, authctxt->service, 72 "gssapi-keyex"); 73 74 gssbuf.value = buffer_ptr(&b); 75 gssbuf.length = buffer_len(&b); 76 77 /* gss_kex_context is NULL with privsep, so we can't check it here */ 78 if (!GSS_ERROR(PRIVSEP(ssh_gssapi_checkmic(gss_kex_context, 79 &gssbuf, &mic)))) 80 authenticated = PRIVSEP(ssh_gssapi_userok(authctxt->user, 81 authctxt->pw)); 82 83 buffer_free(&b); 84 xfree(mic.value); 85 86 return (authenticated); 87 } 88 55 89 /* 56 90 * We only support those mechanisms that we know about (ie ones that we know 57 91 * how to check local user kuserok and the like) … … 102 136 103 137 if (!present) { 104 138 xfree(doid); 139 authctxt->server_caused_failure = 1; 105 140 return (0); 106 141 } 107 142 … … 109 144 if (ctxt != NULL) 110 145 ssh_gssapi_delete_ctx(&ctxt); 111 146 xfree(doid); 147 authctxt->server_caused_failure = 1; 112 148 return (0); 113 149 } 114 150 … … 242 278 243 279 packet_check_eom(); 244 280 245 authenticated = PRIVSEP(ssh_gssapi_userok(authctxt->user)); 281 authenticated = PRIVSEP(ssh_gssapi_userok(authctxt->user, 282 authctxt->pw)); 246 283 247 284 authctxt->postponed = 0; 248 285 dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_TOKEN, NULL); … … 277 314 gssbuf.length = buffer_len(&b); 278 315 279 316 if (!GSS_ERROR(PRIVSEP(ssh_gssapi_checkmic(gssctxt, &gssbuf, &mic)))) 280 authenticated = PRIVSEP(ssh_gssapi_userok(authctxt->user)); 317 authenticated = 318 PRIVSEP(ssh_gssapi_userok(authctxt->user, authctxt->pw)); 281 319 else 282 320 logit("GSSAPI MIC check failed"); 283 321 … … 292 330 userauth_finish(authctxt, authenticated, "gssapi-with-mic"); 293 331 } 294 332 333 Authmethod method_gsskeyex = { 334 "gssapi-keyex", 335 userauth_gsskeyex, 336 &options.gss_authentication 337 }; 338 295 339 Authmethod method_gssapi = { 296 340 "gssapi-with-mic", 297 341 userauth_gssapi, -
openssh-5.3p1
old new 69 69 extern Authmethod method_kbdint; 70 70 extern Authmethod method_hostbased; 71 71 #ifdef GSSAPI 72 extern Authmethod method_gsskeyex; 72 73 extern Authmethod method_gssapi; 73 74 #endif 74 75 #ifdef JPAKE … … 79 80 &method_none, 80 81 &method_pubkey, 81 82 #ifdef GSSAPI 83 &method_gsskeyex, 82 84 &method_gssapi, 83 85 #endif 84 86 #ifdef JPAKE … … 274 276 #endif 275 277 276 278 authctxt->postponed = 0; 279 authctxt->server_caused_failure = 0; 277 280 278 281 /* try to authenticate user */ 279 282 m = authmethod_lookup(method); … … 346 349 } else { 347 350 348 351 /* Allow initial try of "none" auth without failure penalty */ 349 if (authctxt->attempt > 1 || strcmp(method, "none") != 0) 352 if (!authctxt->server_caused_failure && 353 (authctxt->attempt > 1 || strcmp(method, "none") != 0)) 350 354 authctxt->failures++; 351 355 if (authctxt->failures >= options.max_authtries) { 352 356 #ifdef SSH_AUDIT_EVENTS -
openssh-5.3p1
old new 166 166 167 167 len = strlen(authctxt->krb5_ticket_file) + 6; 168 168 authctxt->krb5_ccname = xmalloc(len); 169 #ifdef USE_CCAPI 170 snprintf(authctxt->krb5_ccname, len, "API:%s", 171 authctxt->krb5_ticket_file); 172 #else 169 173 snprintf(authctxt->krb5_ccname, len, "FILE:%s", 170 174 authctxt->krb5_ticket_file); 175 #endif 171 176 172 177 #ifdef USE_PAM 173 178 if (options.use_pam) … … 219 224 #ifndef HEIMDAL 220 225 krb5_error_code 221 226 ssh_krb5_cc_gen(krb5_context ctx, krb5_ccache *ccache) { 222 int tmpfd,ret;227 int ret; 223 228 char ccname[40]; 224 229 mode_t old_umask; 230 #ifdef USE_CCAPI 231 char cctemplate[] = "API:krb5cc_%d"; 232 #else 233 char cctemplate[] = "FILE:/tmp/krb5cc_%d_XXXXXXXXXX"; 234 int tmpfd; 235 #endif 225 236 226 237 ret = snprintf(ccname, sizeof(ccname), 227 "FILE:/tmp/krb5cc_%d_XXXXXXXXXX", geteuid());238 cctemplate, geteuid()); 228 239 if (ret < 0 || (size_t)ret >= sizeof(ccname)) 229 240 return ENOMEM; 230 241 242 #ifndef USE_CCAPI 231 243 old_umask = umask(0177); 232 244 tmpfd = mkstemp(ccname + strlen("FILE:")); 233 245 umask(old_umask); … … 242 254 return errno; 243 255 } 244 256 close(tmpfd); 257 #endif 245 258 246 259 return (krb5_cc_resolve(ctx, ccname, ccache)); 247 260 } -
gss-serv-krb5.c
old new 1 1 /* $OpenBSD: gss-serv-krb5.c,v 1.7 2006/08/03 03:34:42 deraadt Exp $ */ 2 2 3 3 /* 4 * Copyright (c) 2001-200 3Simon Wilkinson. All rights reserved.4 * Copyright (c) 2001-2007 Simon Wilkinson. All rights reserved. 5 5 * 6 6 * Redistribution and use in source and binary forms, with or without 7 7 * modification, are permitted provided that the following conditions … … 120 120 krb5_principal princ; 121 121 OM_uint32 maj_status, min_status; 122 122 int len; 123 const char *new_ccname; 123 124 124 125 if (client->creds == NULL) { 125 126 debug("No credentials stored"); … … 168 169 return; 169 170 } 170 171 171 client->store.filename = xstrdup(krb5_cc_get_name(krb_context, ccache)); 172 new_ccname = krb5_cc_get_name(krb_context, ccache); 173 172 174 client->store.envvar = "KRB5CCNAME"; 173 len = strlen(client->store.filename) + 6; 174 client->store.envval = xmalloc(len); 175 snprintf(client->store.envval, len, "FILE:%s", client->store.filename); 175 #ifdef USE_CCAPI 176 xasprintf(&client->store.envval, "API:%s", new_ccname); 177 client->store.filename = NULL; 178 #else 179 xasprintf(&client->store.envval, "FILE:%s", new_ccname); 180 client->store.filename = xstrdup(new_ccname); 181 #endif 176 182 177 183 #ifdef USE_PAM 178 184 if (options.use_pam) … … 184 190 return; 185 191 } 186 192 193 int 194 ssh_gssapi_krb5_updatecreds(ssh_gssapi_ccache *store, 195 ssh_gssapi_client *client) 196 { 197 krb5_ccache ccache = NULL; 198 krb5_principal principal = NULL; 199 char *name = NULL; 200 krb5_error_code problem; 201 OM_uint32 maj_status, min_status; 202 203 if ((problem = krb5_cc_resolve(krb_context, store->envval, &ccache))) { 204 logit("krb5_cc_resolve(): %.100s", 205 krb5_get_err_text(krb_context, problem)); 206 return 0; 207 } 208 209 /* Find out who the principal in this cache is */ 210 if ((problem = krb5_cc_get_principal(krb_context, ccache, 211 &principal))) { 212 logit("krb5_cc_get_principal(): %.100s", 213 krb5_get_err_text(krb_context, problem)); 214 krb5_cc_close(krb_context, ccache); 215 return 0; 216 } 217 218 if ((problem = krb5_unparse_name(krb_context, principal, &name))) { 219 logit("krb5_unparse_name(): %.100s", 220 krb5_get_err_text(krb_context, problem)); 221 krb5_free_principal(krb_context, principal); 222 krb5_cc_close(krb_context, ccache); 223 return 0; 224 } 225 226 227 if (strcmp(name,client->exportedname.value)!=0) { 228 debug("Name in local credentials cache differs. Not storing"); 229 krb5_free_principal(krb_context, principal); 230 krb5_cc_close(krb_context, ccache); 231 krb5_free_unparsed_name(krb_context, name); 232 return 0; 233 } 234 krb5_free_unparsed_name(krb_context, name); 235 236 /* Name matches, so lets get on with it! */ 237 238 if ((problem = krb5_cc_initialize(krb_context, ccache, principal))) { 239 logit("krb5_cc_initialize(): %.100s", 240 krb5_get_err_text(krb_context, problem)); 241 krb5_free_principal(krb_context, principal); 242 krb5_cc_close(krb_context, ccache); 243 return 0; 244 } 245 246 krb5_free_principal(krb_context, principal); 247 248 if ((maj_status = gss_krb5_copy_ccache(&min_status, client->creds, 249 ccache))) { 250 logit("gss_krb5_copy_ccache() failed. Sorry!"); 251 krb5_cc_close(krb_context, ccache); 252 return 0; 253 } 254 255 return 1; 256 } 257 187 258 ssh_gssapi_mech gssapi_kerberos_mech = { 188 259 "toWM5Slw5Ew8Mqkay+al2g==", 189 260 "Kerberos", … … 191 262 NULL, 192 263 &ssh_gssapi_krb5_userok, 193 264 NULL, 194 &ssh_gssapi_krb5_storecreds 265 &ssh_gssapi_krb5_storecreds, 266 &ssh_gssapi_krb5_updatecreds 195 267 }; 196 268 197 269 #endif /* KRB5 */ -
openssh-5.3p1
old new 120 120 #include "roaming.h" 121 121 #include "version.h" 122 122 123 #ifdef USE_SECURITY_SESSION_API 124 #include <Security/AuthSession.h> 125 #endif 126 123 127 #ifdef LIBWRAP 124 128 #include <tcpd.h> 125 129 #include <syslog.h> … … 1531 1535 logit("Disabling protocol version 1. Could not load host key"); 1532 1536 options.protocol &= ~SSH_PROTO_1; 1533 1537 } 1538 #ifndef GSSAPI 1539 /* The GSSAPI key exchange can run without a host key */ 1534 1540 if ((options.protocol & SSH_PROTO_2) && !sensitive_data.have_ssh2_key) { 1535 1541 logit("Disabling protocol version 2. Could not load host key"); 1536 1542 options.protocol &= ~SSH_PROTO_2; 1537 1543 } 1544 #endif 1538 1545 if (!(options.protocol & (SSH_PROTO_1|SSH_PROTO_2))) { 1539 1546 logit("sshd: no hostkeys available -- exiting."); 1540 1547 exit(1); … … 1818 1825 /* Log the connection. */ 1819 1826 verbose("Connection from %.500s port %d", remote_ip, remote_port); 1820 1827 1828 #ifdef USE_SECURITY_SESSION_API 1829 /* 1830 * Create a new security session for use by the new user login if 1831 * the current session is the root session or we are not launched 1832 * by inetd (eg: debugging mode or server mode). We do not 1833 * necessarily need to create a session if we are launched from 1834 * inetd because Panther xinetd will create a session for us. 1835 * 1836 * The only case where this logic will fail is if there is an 1837 * inetd running in a non-root session which is not creating 1838 * new sessions for us. Then all the users will end up in the 1839 * same session (bad). 1840 * 1841 * When the client exits, the session will be destroyed for us 1842 * automatically. 1843 * 1844 * We must create the session before any credentials are stored 1845 * (including AFS pags, which happens a few lines below). 1846 */ 1847 { 1848 OSStatus err = 0; 1849 SecuritySessionId sid = 0; 1850 SessionAttributeBits sattrs = 0; 1851 1852 err = SessionGetInfo(callerSecuritySession, &sid, &sattrs); 1853 if (err) 1854 error("SessionGetInfo() failed with error %.8X", 1855 (unsigned) err); 1856 else 1857 debug("Current Session ID is %.8X / Session Attributes are %.8X", 1858 (unsigned) sid, (unsigned) sattrs); 1859 1860 if (inetd_flag && !(sattrs & sessionIsRoot)) 1861 debug("Running in inetd mode in a non-root session... " 1862 "assuming inetd created the session for us."); 1863 else { 1864 debug("Creating new security session..."); 1865 err = SessionCreate(0, sessionHasTTY | sessionIsRemote); 1866 if (err) 1867 error("SessionCreate() failed with error %.8X", 1868 (unsigned) err); 1869 1870 err = SessionGetInfo(callerSecuritySession, &sid, 1871 &sattrs); 1872 if (err) 1873 error("SessionGetInfo() failed with error %.8X", 1874 (unsigned) err); 1875 else 1876 debug("New Session ID is %.8X / Session Attributes are %.8X", 1877 (unsigned) sid, (unsigned) sattrs); 1878 } 1879 } 1880 #endif 1881 1821 1882 /* 1822 1883 * We don't want to listen forever unless the other side 1823 1884 * successfully authenticates itself. So we set up an alarm which is … … 2195 2256 2196 2257 myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = list_hostkey_types(); 2197 2258 2259 #ifdef GSSAPI 2260 { 2261 char *orig; 2262 char *gss = NULL; 2263 char *newstr = NULL; 2264 orig = myproposal[PROPOSAL_KEX_ALGS]; 2265 2266 /* 2267 * If we don't have a host key, then there's no point advertising 2268 * the other key exchange algorithms 2269 */ 2270 2271 if (strlen(myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS]) == 0) 2272 orig = NULL; 2273 2274 if (options.gss_keyex) 2275 gss = ssh_gssapi_server_mechanisms(); 2276 else 2277 gss = NULL; 2278 2279 if (gss && orig) 2280 xasprintf(&newstr, "%s,%s", gss, orig); 2281 else if (gss) 2282 newstr = gss; 2283 else if (orig) 2284 newstr = orig; 2285 2286 /* 2287 * If we've got GSSAPI mechanisms, then we've got the 'null' host 2288 * key alg, but we can't tell people about it unless its the only 2289 * host key algorithm we support 2290 */ 2291 if (gss && (strlen(myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS])) == 0) 2292 myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = "null"; 2293 2294 if (newstr) 2295 myproposal[PROPOSAL_KEX_ALGS] = newstr; 2296 else 2297 fatal("No supported key exchange algorithms"); 2298 } 2299 #endif 2300 2198 2301 /* start key exchange */ 2199 2302 kex = kex_setup(myproposal); 2200 2303 kex->kex[KEX_DH_GRP1_SHA1] = kexdh_server; 2201 2304 kex->kex[KEX_DH_GRP14_SHA1] = kexdh_server; 2202 2305 kex->kex[KEX_DH_GEX_SHA1] = kexgex_server; 2203 2306 kex->kex[KEX_DH_GEX_SHA256] = kexgex_server; 2307 #ifdef GSSAPI 2308 if (options.gss_keyex) { 2309 kex->kex[KEX_GSS_GRP1_SHA1] = kexgss_server; 2310 kex->kex[KEX_GSS_GRP14_SHA1] = kexgss_server; 2311 kex->kex[KEX_GSS_GEX_SHA1] = kexgss_server; 2312 } 2313 #endif 2204 2314 kex->server = 1; 2205 2315 kex->client_version_string=client_version_string; 2206 2316 kex->server_version_string=server_version_string; -
configure.ac
old new 477 477 [Use tunnel device compatibility to OpenBSD]) 478 478 AC_DEFINE(SSH_TUN_PREPEND_AF, 1, 479 479 [Prepend the address family to IP tunnel traffic]) 480 AC_MSG_CHECKING(if we have the Security Authorization Session API) 481 AC_TRY_COMPILE([#include <Security/AuthSession.h>], 482 [SessionCreate(0, 0);], 483 [ac_cv_use_security_session_api="yes" 484 AC_DEFINE(USE_SECURITY_SESSION_API, 1, 485 [platform has the Security Authorization Session API]) 486 LIBS="$LIBS -framework Security" 487 AC_MSG_RESULT(yes)], 488 [ac_cv_use_security_session_api="no" 489 AC_MSG_RESULT(no)]) 490 AC_MSG_CHECKING(if we have an in-memory credentials cache) 491 AC_TRY_COMPILE( 492 [#include <Kerberos/Kerberos.h>], 493 [cc_context_t c; 494 (void) cc_initialize (&c, 0, NULL, NULL);], 495 [AC_DEFINE(USE_CCAPI, 1, 496 [platform uses an in-memory credentials cache]) 497 LIBS="$LIBS -framework Security" 498 AC_MSG_RESULT(yes) 499 if test "x$ac_cv_use_security_session_api" = "xno"; then 500 AC_MSG_ERROR(*** Need a security framework to use the credentials cache API ***) 501 fi], 502 [AC_MSG_RESULT(no)] 503 ) 480 504 m4_pattern_allow(AU_IPv) 481 505 AC_CHECK_DECL(AU_IPv4, [], 482 506 AC_DEFINE(AU_IPv4, 0, [System only supports IPv4 audit records]) -
new file openssh-5.3p1/ChangeLog.gssapi
- + 1 20100124 2 - [ sshconnect2.c ] 3 Adapt to deal with additional element in Authmethod structure. Thanks to 4 Colin Watson 5 - [ clientloop.c ] 6 Protect credentials updated code with suitable #ifdefs. Thanks to Colin 7 Watson 8 9 20090615 10 - [ gss-genr.c gss-serv.c kexgssc.c kexgsss.c monitor.c sshconnect2.c 11 sshd.c ] 12 Fix issues identified by Greg Hudson following a code review 13 Check return value of gss_indicate_mechs 14 Protect GSSAPI calls in monitor, so they can only be used if enabled 15 Check return values of bignum functions in key exchange 16 Use BN_clear_free to clear other side's DH value 17 Make ssh_gssapi_id_kex more robust 18 Only configure kex table pointers if GSSAPI is enabled 19 Don't leak mechanism list, or gss mechanism list 20 Cast data.length before printing 21 If serverkey isn't provided, use an empty string, rather than NULL 22 23 20090201 24 - [ gss-genr.c gss-serv.c kex.h kexgssc.c readconf.c readconf.h ssh-gss.h 25 ssh_config.5 sshconnet2.c ] 26 Add support for the GSSAPIClientIdentity option, which allows the user 27 to specify which GSSAPI identity to use to contact a given server 28 29 20080404 30 - [ gss-serv.c ] 31 Add code to actually implement GSSAPIStrictAcceptCheck, which had somehow 32 been omitted from a previous version of this patch. Reported by Borislav 33 Stoichkov 34 35 20070317 36 - [ gss-serv-krb5.c ] 37 Remove C99ism, where new_ccname was being declared in the middle of a 38 function 39 40 20061220 41 - [ servconf.c ] 42 Make default for GSSAPIStrictAcceptorCheck be Yes, to match previous, and 43 documented, behaviour. Reported by Dan Watson. 44 45 20060910 46 - [ gss-genr.c kexgssc.c kexgsss.c kex.h monitor.c sshconnect2.c sshd.c 47 ssh-gss.h ] 48 add support for gss-group14-sha1 key exchange mechanisms 49 - [ gss-serv.c servconf.c servconf.h sshd_config sshd_config.5 ] 50 Add GSSAPIStrictAcceptorCheck option to allow the disabling of 51 acceptor principal checking on multi-homed machines. 52 <Bugzilla #928> 53 - [ sshd_config ssh_config ] 54 Add settings for GSSAPIKeyExchange and GSSAPITrustDNS to the sample 55 configuration files 56 - [ kexgss.c kegsss.c sshconnect2.c sshd.c ] 57 Code cleanup. Replace strlen/xmalloc/snprintf sequences with xasprintf() 58 Limit length of error messages displayed by client 59 60 20060909 61 - [ gss-genr.c gss-serv.c ] 62 move ssh_gssapi_acquire_cred() and ssh_gssapi_server_ctx to be server 63 only, where they belong 64 <Bugzilla #1225> 65 66 20060829 67 - [ gss-serv-krb5.c ] 68 Fix CCAPI credentials cache name when creating KRB5CCNAME environment 69 variable 70 71 20060828 72 - [ gss-genr.c ] 73 Avoid Heimdal context freeing problem 74 <Fixed upstream 20060829> 75 76 20060818 77 - [ gss-genr.c ssh-gss.h sshconnect2.c ] 78 Make sure that SPENGO is disabled 79 <Bugzilla #1218 - Fixed upstream 20060818> 80 81 20060421 82 - [ gssgenr.c, sshconnect2.c ] 83 a few type changes (signed versus unsigned, int versus size_t) to 84 fix compiler errors/warnings 85 (from jbasney AT ncsa.uiuc.edu) 86 - [ kexgssc.c, sshconnect2.c ] 87 fix uninitialized variable warnings 88 (from jbasney AT ncsa.uiuc.edu) 89 - [ gssgenr.c ] 90 pass oid to gss_display_status (helpful when using GSSAPI mechglue) 91 (from jbasney AT ncsa.uiuc.edu) 92 <Bugzilla #1220 > 93 - [ gss-serv-krb5.c ] 94 #ifdef HAVE_GSSAPI_KRB5 should be #ifdef HAVE_GSSAPI_KRB5_H 95 (from jbasney AT ncsa.uiuc.edu) 96 <Fixed upstream 20060304> 97 - [ readconf.c, readconf.h, ssh_config.5, sshconnect2.c 98 add client-side GssapiKeyExchange option 99 (from jbasney AT ncsa.uiuc.edu) 100 - [ sshconnect2.c ] 101 add support for GssapiTrustDns option for gssapi-with-mic 102 (from jbasney AT ncsa.uiuc.edu) 103 <gssapi-with-mic support is Bugzilla #1008> -
openssh-5.3p1
old new LIBSSH_OBJS=acss.o authfd.o authfile.o b 74 74 monitor_fdpass.o rijndael.o ssh-dss.o ssh-rsa.o dh.o kexdh.o \ 75 75 kexgex.o kexdhc.o kexgexc.o msg.o progressmeter.o dns.o \ 76 76 entropy.o gss-genr.o umac.o jpake.o schnorr.o \ 77 ssh-pkcs11.o 77 ssh-pkcs11.o kexgssc.o 78 78 79 79 SSHOBJS= ssh.o readconf.o clientloop.o sshtty.o \ 80 80 sshconnect.o sshconnect1.o sshconnect2.o mux.o \ … … 85 86 auth2-none.o auth2-passwd.o auth2-pubkey.o auth2-jpake.o \ 86 87 monitor_mm.o monitor.o monitor_wrap.o kexdhs.o kexgexs.o \ 87 88 auth-krb5.o \ 88 auth2-gss.o gss-serv.o gss-serv-krb5.o \89 auth2-gss.o gss-serv.o gss-serv-krb5.o kexgsss.o\ 89 90 loginrec.o auth-pam.o auth-shadow.o auth-sia.o md5crypt.o \ 90 91 audit.o audit-bsm.o platform.o sftp-server.o sftp-common.o \ 91 92 roaming_common.o -
openssh-5.3p1
old new 1 1 /* $OpenBSD: gss-genr.c,v 1.20 2009/06/22 05:39:28 dtucker Exp $ */ 2 2 3 3 /* 4 * Copyright (c) 2001-200 7Simon Wilkinson. All rights reserved.4 * Copyright (c) 2001-2009 Simon Wilkinson. All rights reserved. 5 5 * 6 6 * Redistribution and use in source and binary forms, with or without 7 7 * modification, are permitted provided that the following conditions … … 39 39 #include "buffer.h" 40 40 #include "log.h" 41 41 #include "ssh2.h" 42 #include "cipher.h" 43 #include "key.h" 44 #include "kex.h" 45 #include <openssl/evp.h> 42 46 43 47 #include "ssh-gss.h" 44 48 45 49 extern u_char *session_id2; 46 50 extern u_int session_id2_len; 47 51 52 typedef struct { 53 char *encoded; 54 gss_OID oid; 55 } ssh_gss_kex_mapping; 56 57 /* 58 * XXX - It would be nice to find a more elegant way of handling the 59 * XXX passing of the key exchange context to the userauth routines 60 */ 61 62 Gssctxt *gss_kex_context = NULL; 63 64 static ssh_gss_kex_mapping *gss_enc2oid = NULL; 65 66 int 67 ssh_gssapi_oid_table_ok() { 68 return (gss_enc2oid != NULL); 69 } 70 71 /* 72 * Return a list of the gss-group1-sha1 mechanisms supported by this program 73 * 74 * We test mechanisms to ensure that we can use them, to avoid starting 75 * a key exchange with a bad mechanism 76 */ 77 78 char * 79 ssh_gssapi_client_mechanisms(const char *host, const char *client) { 80 gss_OID_set gss_supported; 81 OM_uint32 min_status; 82 83 if (GSS_ERROR(gss_indicate_mechs(&min_status, &gss_supported))) 84 return NULL; 85 86 return(ssh_gssapi_kex_mechs(gss_supported, ssh_gssapi_check_mechanism, 87 host, client)); 88 } 89 90 char * 91 ssh_gssapi_kex_mechs(gss_OID_set gss_supported, ssh_gssapi_check_fn *check, 92 const char *host, const char *client) { 93 Buffer buf; 94 size_t i; 95 int oidpos, enclen; 96 char *mechs, *encoded; 97 u_char digest[EVP_MAX_MD_SIZE]; 98 char deroid[2]; 99 const EVP_MD *evp_md = EVP_md5(); 100 EVP_MD_CTX md; 101 102 if (gss_enc2oid != NULL) { 103 for (i = 0; gss_enc2oid[i].encoded != NULL; i++) 104 xfree(gss_enc2oid[i].encoded); 105 xfree(gss_enc2oid); 106 } 107 108 gss_enc2oid = xmalloc(sizeof(ssh_gss_kex_mapping) * 109 (gss_supported->count + 1)); 110 111 buffer_init(&buf); 112 113 oidpos = 0; 114 for (i = 0; i < gss_supported->count; i++) { 115 if (gss_supported->elements[i].length < 128 && 116 (*check)(NULL, &(gss_supported->elements[i]), host, client)) { 117 118 deroid[0] = SSH_GSS_OIDTYPE; 119 deroid[1] = gss_supported->elements[i].length; 120 121 EVP_DigestInit(&md, evp_md); 122 EVP_DigestUpdate(&md, deroid, 2); 123 EVP_DigestUpdate(&md, 124 gss_supported->elements[i].elements, 125 gss_supported->elements[i].length); 126 EVP_DigestFinal(&md, digest, NULL); 127 128 encoded = xmalloc(EVP_MD_size(evp_md) * 2); 129 enclen = __b64_ntop(digest, EVP_MD_size(evp_md), 130 encoded, EVP_MD_size(evp_md) * 2); 131 132 if (oidpos != 0) 133 buffer_put_char(&buf, ','); 134 135 buffer_append(&buf, KEX_GSS_GEX_SHA1_ID, 136 sizeof(KEX_GSS_GEX_SHA1_ID) - 1); 137 buffer_append(&buf, encoded, enclen); 138 buffer_put_char(&buf, ','); 139 buffer_append(&buf, KEX_GSS_GRP1_SHA1_ID, 140 sizeof(KEX_GSS_GRP1_SHA1_ID) - 1); 141 buffer_append(&buf, encoded, enclen); 142 buffer_put_char(&buf, ','); 143 buffer_append(&buf, KEX_GSS_GRP14_SHA1_ID, 144 sizeof(KEX_GSS_GRP14_SHA1_ID) - 1); 145 buffer_append(&buf, encoded, enclen); 146 147 gss_enc2oid[oidpos].oid = &(gss_supported->elements[i]); 148 gss_enc2oid[oidpos].encoded = encoded; 149 oidpos++; 150 } 151 } 152 gss_enc2oid[oidpos].oid = NULL; 153 gss_enc2oid[oidpos].encoded = NULL; 154 155 buffer_put_char(&buf, '\0'); 156 157 mechs = xmalloc(buffer_len(&buf)); 158 buffer_get(&buf, mechs, buffer_len(&buf)); 159 buffer_free(&buf); 160 161 if (strlen(mechs) == 0) { 162 xfree(mechs); 163 mechs = NULL; 164 } 165 166 return (mechs); 167 } 168 169 gss_OID 170 ssh_gssapi_id_kex(Gssctxt *ctx, char *name, int kex_type) { 171 int i = 0; 172 173 switch (kex_type) { 174 case KEX_GSS_GRP1_SHA1: 175 if (strlen(name) < sizeof(KEX_GSS_GRP1_SHA1_ID)) 176 return GSS_C_NO_OID; 177 name += sizeof(KEX_GSS_GRP1_SHA1_ID) - 1; 178 break; 179 case KEX_GSS_GRP14_SHA1: 180 if (strlen(name) < sizeof(KEX_GSS_GRP14_SHA1_ID)) 181 return GSS_C_NO_OID; 182 name += sizeof(KEX_GSS_GRP14_SHA1_ID) - 1; 183 break; 184 case KEX_GSS_GEX_SHA1: 185 if (strlen(name) < sizeof(KEX_GSS_GEX_SHA1_ID)) 186 return GSS_C_NO_OID; 187 name += sizeof(KEX_GSS_GEX_SHA1_ID) - 1; 188 break; 189 default: 190 return GSS_C_NO_OID; 191 } 192 193 while (gss_enc2oid[i].encoded != NULL && 194 strcmp(name, gss_enc2oid[i].encoded) != 0) 195 i++; 196 197 if (gss_enc2oid[i].oid != NULL && ctx != NULL) 198 ssh_gssapi_set_oid(ctx, gss_enc2oid[i].oid); 199 200 return gss_enc2oid[i].oid; 201 } 202 48 203 /* Check that the OID in a data stream matches that in the context */ 49 204 int 50 205 ssh_gssapi_check_oid(Gssctxt *ctx, void *data, size_t len) … … 197 352 } 198 353 199 354 ctx->major = gss_init_sec_context(&ctx->minor, 200 GSS_C_NO_CREDENTIAL, &ctx->context, ctx->name, ctx->oid,355 ctx->client_creds, &ctx->context, ctx->name, ctx->oid, 201 356 GSS_C_MUTUAL_FLAG | GSS_C_INTEG_FLAG | deleg_flag, 202 357 0, NULL, recv_tok, NULL, send_tok, flags, NULL); 203 358 … … 227 382 } 228 383 229 384 OM_uint32 385 ssh_gssapi_client_identity(Gssctxt *ctx, const char *name) 386 { 387 gss_buffer_desc gssbuf; 388 gss_name_t gssname; 389 OM_uint32 status; 390 gss_OID_set oidset; 391 392 gssbuf.value = (void *) name; 393 gssbuf.length = strlen(gssbuf.value); 394 395 gss_create_empty_oid_set(&status, &oidset); 396 gss_add_oid_set_member(&status, ctx->oid, &oidset); 397 398 ctx->major = gss_import_name(&ctx->minor, &gssbuf, 399 GSS_C_NT_USER_NAME, &gssname); 400 401 if (!ctx->major) 402 ctx->major = gss_acquire_cred(&ctx->minor, 403 gssname, 0, oidset, GSS_C_INITIATE, 404 &ctx->client_creds, NULL, NULL); 405 406 gss_release_name(&status, &gssname); 407 gss_release_oid_set(&status, &oidset); 408 409 if (ctx->major) 410 ssh_gssapi_error(ctx); 411 412 return(ctx->major); 413 } 414 415 OM_uint32 230 416 ssh_gssapi_sign(Gssctxt *ctx, gss_buffer_t buffer, gss_buffer_t hash) 231 417 { 418 if (ctx == NULL) 419 return -1; 420 232 421 if ((ctx->major = gss_get_mic(&ctx->minor, ctx->context, 233 422 GSS_C_QOP_DEFAULT, buffer, hash))) 234 423 ssh_gssapi_error(ctx); … … 236 425 return (ctx->major); 237 426 } 238 427 428 /* Priviledged when used by server */ 429 OM_uint32 430 ssh_gssapi_checkmic(Gssctxt *ctx, gss_buffer_t gssbuf, gss_buffer_t gssmic) 431 { 432 if (ctx == NULL) 433 return -1; 434 435 ctx->major = gss_verify_mic(&ctx->minor, ctx->context, 436 gssbuf, gssmic, NULL); 437 438 return (ctx->major); 439 } 440 239 441 void 240 442 ssh_gssapi_buildmic(Buffer *b, const char *user, const char *service, 241 443 const char *context) … … 249 451 } 250 452 251 453 int 252 ssh_gssapi_check_mechanism(Gssctxt **ctx, gss_OID oid, const char *host) 454 ssh_gssapi_check_mechanism(Gssctxt **ctx, gss_OID oid, const char *host, 455 const char *client) 253 456 { 254 457 gss_buffer_desc token = GSS_C_EMPTY_BUFFER; 255 458 OM_uint32 major, minor; 256 459 gss_OID_desc spnego_oid = {6, (void *)"\x2B\x06\x01\x05\x05\x02"}; 460 Gssctxt *intctx = NULL; 461 462 if (ctx == NULL) 463 ctx = &intctx; 257 464 258 465 /* RFC 4462 says we MUST NOT do SPNEGO */ 259 466 if (oid->length == spnego_oid.length && … … 263 470 ssh_gssapi_build_ctx(ctx); 264 471 ssh_gssapi_set_oid(*ctx, oid); 265 472 major = ssh_gssapi_import_name(*ctx, host); 473 474 if (!GSS_ERROR(major) && client) 475 major = ssh_gssapi_client_identity(*ctx, client); 476 266 477 if (!GSS_ERROR(major)) { 267 478 major = ssh_gssapi_init_ctx(*ctx, 0, GSS_C_NO_BUFFER, &token, 268 479 NULL); … … 272 483 GSS_C_NO_BUFFER); 273 484 } 274 485 275 if (GSS_ERROR(major) )486 if (GSS_ERROR(major) || intctx != NULL) 276 487 ssh_gssapi_delete_ctx(ctx); 277 488 278 489 return (!GSS_ERROR(major)); 279 490 } 280 491 492 int 493 ssh_gssapi_credentials_updated(Gssctxt *ctxt) { 494 static gss_name_t saved_name = GSS_C_NO_NAME; 495 static OM_uint32 saved_lifetime = 0; 496 static gss_OID saved_mech = GSS_C_NO_OID; 497 static gss_name_t name; 498 static OM_uint32 last_call = 0; 499 OM_uint32 lifetime, now, major, minor; 500 int equal; 501 gss_cred_usage_t usage = GSS_C_INITIATE; 502 503 now = time(NULL); 504 505 if (ctxt) { 506 debug("Rekey has happened - updating saved versions"); 507 508 if (saved_name != GSS_C_NO_NAME) 509 gss_release_name(&minor, &saved_name); 510 511 major = gss_inquire_cred(&minor, GSS_C_NO_CREDENTIAL, 512 &saved_name, &saved_lifetime, NULL, NULL); 513 514 if (!GSS_ERROR(major)) { 515 saved_mech = ctxt->oid; 516 saved_lifetime+= now; 517 } else { 518 /* Handle the error */ 519 } 520 return 0; 521 } 522 523 if (now - last_call < 10) 524 return 0; 525 526 last_call = now; 527 528 if (saved_mech == GSS_C_NO_OID) 529 return 0; 530 531 major = gss_inquire_cred(&minor, GSS_C_NO_CREDENTIAL, 532 &name, &lifetime, NULL, NULL); 533 if (major == GSS_S_CREDENTIALS_EXPIRED) 534 return 0; 535 else if (GSS_ERROR(major)) 536 return 0; 537 538 major = gss_compare_name(&minor, saved_name, name, &equal); 539 gss_release_name(&minor, &name); 540 if (GSS_ERROR(major)) 541 return 0; 542 543 if (equal && (saved_lifetime < lifetime + now - 10)) 544 return 1; 545 546 return 0; 547 } 548 281 549 #endif /* GSSAPI */ -
openssh-5.3p1
old new 49 49 #include "dispatch.h" 50 50 #include "monitor.h" 51 51 52 #ifdef GSSAPI 53 #include "ssh-gss.h" 54 #endif 55 52 56 #if OPENSSL_VERSION_NUMBER >= 0x00907000L 53 57 # if defined(HAVE_EVP_SHA256) 54 58 # define evp_ssh_sha256 EVP_sha256 … … 325 329 k->kex_type = KEX_DH_GEX_SHA256; 326 330 k->evp_md = evp_ssh_sha256(); 327 331 #endif 332 #ifdef GSSAPI 333 } else if (strncmp(k->name, KEX_GSS_GEX_SHA1_ID, 334 sizeof(KEX_GSS_GEX_SHA1_ID) - 1) == 0) { 335 k->kex_type = KEX_GSS_GEX_SHA1; 336 k->evp_md = EVP_sha1(); 337 } else if (strncmp(k->name, KEX_GSS_GRP1_SHA1_ID, 338 sizeof(KEX_GSS_GRP1_SHA1_ID) - 1) == 0) { 339 k->kex_type = KEX_GSS_GRP1_SHA1; 340 k->evp_md = EVP_sha1(); 341 } else if (strncmp(k->name, KEX_GSS_GRP14_SHA1_ID, 342 sizeof(KEX_GSS_GRP14_SHA1_ID) - 1) == 0) { 343 k->kex_type = KEX_GSS_GRP14_SHA1; 344 k->evp_md = EVP_sha1(); 345 #endif 328 346 } else 329 347 fatal("bad kex alg %s", k->name); 330 348 } -
openssh-5.3p1
old new 66 66 KEX_DH_GRP14_SHA1, 67 67 KEX_DH_GEX_SHA1, 68 68 KEX_DH_GEX_SHA256, 69 KEX_GSS_GRP1_SHA1, 70 KEX_GSS_GRP14_SHA1, 71 KEX_GSS_GEX_SHA1, 69 72 KEX_MAX 70 73 }; 71 74 … … 121 124 sig_atomic_t done; 122 125 int flags; 123 126 const EVP_MD *evp_md; 127 #ifdef GSSAPI 128 int gss_deleg_creds; 129 int gss_trust_dns; 130 char *gss_host; 131 char *gss_client; 132 #endif 124 133 char *client_version_string; 125 134 char *server_version_string; 126 135 int (*verify_host_key)(Key *); … … 143 152 void kexgex_client(Kex *); 144 153 void kexgex_server(Kex *); 145 154 155 #ifdef GSSAPI 156 void kexgss_client(Kex *); 157 void kexgss_server(Kex *); 158 #endif 159 146 160 void 147 161 kex_dh_hash(char *, char *, char *, int, char *, int, u_char *, int, 148 162 BIGNUM *, BIGNUM *, BIGNUM *, u_char **, u_int *); -
new file openssh-5.3p1/kexgssc.c
- + 1 /* 2 * Copyright (c) 2001-2009 Simon Wilkinson. 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 27 #ifdef GSSAPI 28 29 #include "includes.h" 30 31 #include <openssl/crypto.h> 32 #include <openssl/bn.h> 33 34 #include <string.h> 35 36 #include "xmalloc.h" 37 #include "buffer.h" 38 #include "ssh2.h" 39 #include "key.h" 40 #include "cipher.h" 41 #include "kex.h" 42 #include "log.h" 43 #include "packet.h" 44 #include "dh.h" 45 46 #include "ssh-gss.h" 47 48 void 49 kexgss_client(Kex *kex) { 50 gss_buffer_desc send_tok = GSS_C_EMPTY_BUFFER; 51 gss_buffer_desc recv_tok, gssbuf, msg_tok, *token_ptr; 52 Gssctxt *ctxt; 53 OM_uint32 maj_status, min_status, ret_flags; 54 u_int klen, kout, slen = 0, hashlen, strlen; 55 DH *dh; 56 BIGNUM *dh_server_pub = NULL; 57 BIGNUM *shared_secret = NULL; 58 BIGNUM *p = NULL; 59 BIGNUM *g = NULL; 60 u_char *kbuf, *hash; 61 u_char *serverhostkey = NULL; 62 u_char *empty = ""; 63 char *msg; 64 char *lang; 65 int type = 0; 66 int first = 1; 67 int nbits = 0, min = DH_GRP_MIN, max = DH_GRP_MAX; 68 69 /* Initialise our GSSAPI world */ 70 ssh_gssapi_build_ctx(&ctxt); 71 if (ssh_gssapi_id_kex(ctxt, kex->name, kex->kex_type) 72 == GSS_C_NO_OID) 73 fatal("Couldn't identify host exchange"); 74 75 if (ssh_gssapi_import_name(ctxt, kex->gss_host)) 76 fatal("Couldn't import hostname"); 77 78 if (kex->gss_client && 79 ssh_gssapi_client_identity(ctxt, kex->gss_client)) 80 fatal("Couldn't acquire client credentials"); 81 82 switch (kex->kex_type) { 83 case KEX_GSS_GRP1_SHA1: 84 dh = dh_new_group1(); 85 break; 86 case KEX_GSS_GRP14_SHA1: 87 dh = dh_new_group14(); 88 break; 89 case KEX_GSS_GEX_SHA1: 90 debug("Doing group exchange\n"); 91 nbits = dh_estimate(kex->we_need * 8); 92 packet_start(SSH2_MSG_KEXGSS_GROUPREQ); 93 packet_put_int(min); 94 packet_put_int(nbits); 95 packet_put_int(max); 96 97 packet_send(); 98 99 packet_read_expect(SSH2_MSG_KEXGSS_GROUP); 100 101 if ((p = BN_new()) == NULL) 102 fatal("BN_new() failed"); 103 packet_get_bignum2(p); 104 if ((g = BN_new()) == NULL) 105 fatal("BN_new() failed"); 106 packet_get_bignum2(g); 107 packet_check_eom(); 108 109 if (BN_num_bits(p) < min || BN_num_bits(p) > max) 110 fatal("GSSGRP_GEX group out of range: %d !< %d !< %d", 111 min, BN_num_bits(p), max); 112 113 dh = dh_new_group(g, p); 114 break; 115 default: 116 fatal("%s: Unexpected KEX type %d", __func__, kex->kex_type); 117 } 118 119 /* Step 1 - e is dh->pub_key */ 120 dh_gen_key(dh, kex->we_need * 8); 121 122 /* This is f, we initialise it now to make life easier */ 123 dh_server_pub = BN_new(); 124 if (dh_server_pub == NULL) 125 fatal("dh_server_pub == NULL"); 126 127 token_ptr = GSS_C_NO_BUFFER; 128 129 do { 130 debug("Calling gss_init_sec_context"); 131 132 maj_status = ssh_gssapi_init_ctx(ctxt, 133 kex->gss_deleg_creds, token_ptr, &send_tok, 134 &ret_flags); 135 136 if (GSS_ERROR(maj_status)) { 137 if (send_tok.length != 0) { 138 packet_start(SSH2_MSG_KEXGSS_CONTINUE); 139 packet_put_string(send_tok.value, 140 send_tok.length); 141 } 142 fatal("gss_init_context failed"); 143 } 144 145 /* If we've got an old receive buffer get rid of it */ 146 if (token_ptr != GSS_C_NO_BUFFER) 147 xfree(recv_tok.value); 148 149 if (maj_status == GSS_S_COMPLETE) { 150 /* If mutual state flag is not true, kex fails */ 151 if (!(ret_flags & GSS_C_MUTUAL_FLAG)) 152 fatal("Mutual authentication failed"); 153 154 /* If integ avail flag is not true kex fails */ 155 if (!(ret_flags & GSS_C_INTEG_FLAG)) 156 fatal("Integrity check failed"); 157 } 158 159 /* 160 * If we have data to send, then the last message that we 161 * received cannot have been a 'complete'. 162 */ 163 if (send_tok.length != 0) { 164 if (first) { 165 packet_start(SSH2_MSG_KEXGSS_INIT); 166 packet_put_string(send_tok.value, 167 send_tok.length); 168 packet_put_bignum2(dh->pub_key); 169 first = 0; 170 } else { 171 packet_start(SSH2_MSG_KEXGSS_CONTINUE); 172 packet_put_string(send_tok.value, 173 send_tok.length); 174 } 175 packet_send(); 176 gss_release_buffer(&min_status, &send_tok); 177 178 /* If we've sent them data, they should reply */ 179 do { 180 type = packet_read(); 181 if (type == SSH2_MSG_KEXGSS_HOSTKEY) { 182 debug("Received KEXGSS_HOSTKEY"); 183 if (serverhostkey) 184 fatal("Server host key received more than once"); 185 serverhostkey = 186 packet_get_string(&slen); 187 } 188 } while (type == SSH2_MSG_KEXGSS_HOSTKEY); 189 190 switch (type) { 191 case SSH2_MSG_KEXGSS_CONTINUE: 192 debug("Received GSSAPI_CONTINUE"); 193 if (maj_status == GSS_S_COMPLETE) 194 fatal("GSSAPI Continue received from server when complete"); 195 recv_tok.value = packet_get_string(&strlen); 196 recv_tok.length = strlen; 197 break; 198 case SSH2_MSG_KEXGSS_COMPLETE: 199 debug("Received GSSAPI_COMPLETE"); 200 packet_get_bignum2(dh_server_pub); 201 msg_tok.value = packet_get_string(&strlen); 202 msg_tok.length = strlen; 203 204 /* Is there a token included? */ 205 if (packet_get_char()) { 206 recv_tok.value= 207 packet_get_string(&strlen); 208 recv_tok.length = strlen; 209 /* If we're already complete - protocol error */ 210 if (maj_status == GSS_S_COMPLETE) 211 packet_disconnect("Protocol error: received token when complete"); 212 } else { 213 /* No token included */ 214 if (maj_status != GSS_S_COMPLETE) 215 packet_disconnect("Protocol error: did not receive final token"); 216 } 217 break; 218 case SSH2_MSG_KEXGSS_ERROR: 219 debug("Received Error"); 220 maj_status = packet_get_int(); 221 min_status = packet_get_int(); 222 msg = packet_get_string(NULL); 223 lang = packet_get_string(NULL); 224 fatal("GSSAPI Error: \n%.400s",msg); 225 default: 226 packet_disconnect("Protocol error: didn't expect packet type %d", 227 type); 228 } 229 token_ptr = &recv_tok; 230 } else { 231 /* No data, and not complete */ 232 if (maj_status != GSS_S_COMPLETE) 233 fatal("Not complete, and no token output"); 234 } 235 } while (maj_status & GSS_S_CONTINUE_NEEDED); 236 237 /* 238 * We _must_ have received a COMPLETE message in reply from the 239 * server, which will have set dh_server_pub and msg_tok 240 */ 241 242 if (type != SSH2_MSG_KEXGSS_COMPLETE) 243 fatal("Didn't receive a SSH2_MSG_KEXGSS_COMPLETE when I expected it"); 244 245 /* Check f in range [1, p-1] */ 246 if (!dh_pub_is_valid(dh, dh_server_pub)) 247 packet_disconnect("bad server public DH value"); 248 249 /* compute K=f^x mod p */ 250 klen = DH_size(dh); 251 kbuf = xmalloc(klen); 252 kout = DH_compute_key(kbuf, dh_server_pub, dh); 253 if (kout < 0) 254 fatal("DH_compute_key: failed"); 255 256 shared_secret = BN_new(); 257 if (shared_secret == NULL) 258 fatal("kexgss_client: BN_new failed"); 259 260 if (BN_bin2bn(kbuf, kout, shared_secret) == NULL) 261 fatal("kexdh_client: BN_bin2bn failed"); 262 263 memset(kbuf, 0, klen); 264 xfree(kbuf); 265 266 switch (kex->kex_type) { 267 case KEX_GSS_GRP1_SHA1: 268 case KEX_GSS_GRP14_SHA1: 269 kex_dh_hash( kex->client_version_string, 270 kex->server_version_string, 271 buffer_ptr(&kex->my), buffer_len(&kex->my), 272 buffer_ptr(&kex->peer), buffer_len(&kex->peer), 273 (serverhostkey ? serverhostkey : empty), slen, 274 dh->pub_key, /* e */ 275 dh_server_pub, /* f */ 276 shared_secret, /* K */ 277 &hash, &hashlen 278 ); 279 break; 280 case KEX_GSS_GEX_SHA1: 281 kexgex_hash( 282 kex->evp_md, 283 kex->client_version_string, 284 kex->server_version_string, 285 buffer_ptr(&kex->my), buffer_len(&kex->my), 286 buffer_ptr(&kex->peer), buffer_len(&kex->peer), 287 (serverhostkey ? serverhostkey : empty), slen, 288 min, nbits, max, 289 dh->p, dh->g, 290 dh->pub_key, 291 dh_server_pub, 292 shared_secret, 293 &hash, &hashlen 294 ); 295 break; 296 default: 297 fatal("%s: Unexpected KEX type %d", __func__, kex->kex_type); 298 } 299 300 gssbuf.value = hash; 301 gssbuf.length = hashlen; 302 303 /* Verify that the hash matches the MIC we just got. */ 304 if (GSS_ERROR(ssh_gssapi_checkmic(ctxt, &gssbuf, &msg_tok))) 305 packet_disconnect("Hash's MIC didn't verify"); 306 307 xfree(msg_tok.value); 308 309 DH_free(dh); 310 if (serverhostkey) 311 xfree(serverhostkey); 312 BN_clear_free(dh_server_pub); 313 314 /* save session id */ 315 if (kex->session_id == NULL) { 316 kex->session_id_len = hashlen; 317 kex->session_id = xmalloc(kex->session_id_len); 318 memcpy(kex->session_id, hash, kex->session_id_len); 319 } 320 321 if (kex->gss_deleg_creds) 322 ssh_gssapi_credentials_updated(ctxt); 323 324 if (gss_kex_context == NULL) 325 gss_kex_context = ctxt; 326 else 327 ssh_gssapi_delete_ctx(&ctxt); 328 329 kex_derive_keys(kex, hash, hashlen, shared_secret); 330 BN_clear_free(shared_secret); 331 kex_finish(kex); 332 } 333 334 #endif /* GSSAPI */ -
new file openssh-5.3p1/kexgsss.c
- + 1 /* 2 * Copyright (c) 2001-2009 Simon Wilkinson. 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 27 #ifdef GSSAPI 28 29 #include <string.h> 30 31 #include <openssl/crypto.h> 32 #include <openssl/bn.h> 33 34 #include "xmalloc.h" 35 #include "buffer.h" 36 #include "ssh2.h" 37 #include "key.h" 38 #include "cipher.h" 39 #include "kex.h" 40 #include "log.h" 41 #include "packet.h" 42 #include "dh.h" 43 #include "ssh-gss.h" 44 #include "monitor_wrap.h" 45 #include "servconf.h" 46 47 extern ServerOptions options; 48 49 void 50 kexgss_server(Kex *kex) 51 { 52 OM_uint32 maj_status, min_status; 53 54 /* 55 * Some GSSAPI implementations use the input value of ret_flags (an 56 * output variable) as a means of triggering mechanism specific 57 * features. Initializing it to zero avoids inadvertently 58 * activating this non-standard behaviour. 59 */ 60 61 OM_uint32 ret_flags = 0; 62 gss_buffer_desc gssbuf, recv_tok, msg_tok; 63 gss_buffer_desc send_tok = GSS_C_EMPTY_BUFFER; 64 Gssctxt *ctxt = NULL; 65 u_int slen, klen, kout, hashlen; 66 u_char *kbuf, *hash; 67 DH *dh; 68 int min = -1, max = -1, nbits = -1; 69 BIGNUM *shared_secret = NULL; 70 BIGNUM *dh_client_pub = NULL; 71 int type = 0; 72 gss_OID oid; 73 char *mechs; 74 75 /* Initialise GSSAPI */ 76 77 /* If we're rekeying, privsep means that some of the private structures 78 * in the GSSAPI code are no longer available. This kludges them back 79 * into life 80 */ 81 if (!ssh_gssapi_oid_table_ok()) 82 if ((mechs = ssh_gssapi_server_mechanisms())) 83 xfree(mechs); 84 85 debug2("%s: Identifying %s", __func__, kex->name); 86 oid = ssh_gssapi_id_kex(NULL, kex->name, kex->kex_type); 87 if (oid == GSS_C_NO_OID) 88 fatal("Unknown gssapi mechanism"); 89 90 debug2("%s: Acquiring credentials", __func__); 91 92 if (GSS_ERROR(PRIVSEP(ssh_gssapi_server_ctx(&ctxt, oid)))) 93 fatal("Unable to acquire credentials for the server"); 94 95 switch (kex->kex_type) { 96 case KEX_GSS_GRP1_SHA1: 97 dh = dh_new_group1(); 98 break; 99 case KEX_GSS_GRP14_SHA1: 100 dh = dh_new_group14(); 101 break; 102 case KEX_GSS_GEX_SHA1: 103 debug("Doing group exchange"); 104 packet_read_expect(SSH2_MSG_KEXGSS_GROUPREQ); 105 min = packet_get_int(); 106 nbits = packet_get_int(); 107 max = packet_get_int(); 108 min = MAX(DH_GRP_MIN, min); 109 max = MIN(DH_GRP_MAX, max); 110 packet_check_eom(); 111 if (max < min || nbits < min || max < nbits) 112 fatal("GSS_GEX, bad parameters: %d !< %d !< %d", 113 min, nbits, max); 114 dh = PRIVSEP(choose_dh(min, nbits, max)); 115 if (dh == NULL) 116 packet_disconnect("Protocol error: no matching group found"); 117 118 packet_start(SSH2_MSG_KEXGSS_GROUP); 119 packet_put_bignum2(dh->p); 120 packet_put_bignum2(dh->g); 121 packet_send(); 122 123 packet_write_wait(); 124 break; 125 default: 126 fatal("%s: Unexpected KEX type %d", __func__, kex->kex_type); 127 } 128 129 dh_gen_key(dh, kex->we_need * 8); 130 131 do { 132 debug("Wait SSH2_MSG_GSSAPI_INIT"); 133 type = packet_read(); 134 switch(type) { 135 case SSH2_MSG_KEXGSS_INIT: 136 if (dh_client_pub != NULL) 137 fatal("Received KEXGSS_INIT after initialising"); 138 recv_tok.value = packet_get_string(&slen); 139 recv_tok.length = slen; 140 141 if ((dh_client_pub = BN_new()) == NULL) 142 fatal("dh_client_pub == NULL"); 143 144 packet_get_bignum2(dh_client_pub); 145 146 /* Send SSH_MSG_KEXGSS_HOSTKEY here, if we want */ 147 break; 148 case SSH2_MSG_KEXGSS_CONTINUE: 149 recv_tok.value = packet_get_string(&slen); 150 recv_tok.length = slen; 151 break; 152 default: 153 packet_disconnect( 154 "Protocol error: didn't expect packet type %d", 155 type); 156 } 157 158 maj_status = PRIVSEP(ssh_gssapi_accept_ctx(ctxt, &recv_tok, 159 &send_tok, &ret_flags)); 160 161 xfree(recv_tok.value); 162 163 if (maj_status != GSS_S_COMPLETE && send_tok.length == 0) 164 fatal("Zero length token output when incomplete"); 165 166 if (dh_client_pub == NULL) 167 fatal("No client public key"); 168 169 if (maj_status & GSS_S_CONTINUE_NEEDED) { 170 debug("Sending GSSAPI_CONTINUE"); 171 packet_start(SSH2_MSG_KEXGSS_CONTINUE); 172 packet_put_string(send_tok.value, send_tok.length); 173 packet_send(); 174 gss_release_buffer(&min_status, &send_tok); 175 } 176 } while (maj_status & GSS_S_CONTINUE_NEEDED); 177 178 if (GSS_ERROR(maj_status)) { 179 if (send_tok.length > 0) { 180 packet_start(SSH2_MSG_KEXGSS_CONTINUE); 181 packet_put_string(send_tok.value, send_tok.length); 182 packet_send(); 183 } 184 fatal("accept_ctx died"); 185 } 186 187 if (!(ret_flags & GSS_C_MUTUAL_FLAG)) 188 fatal("Mutual Authentication flag wasn't set"); 189 190 if (!(ret_flags & GSS_C_INTEG_FLAG)) 191 fatal("Integrity flag wasn't set"); 192 193 if (!dh_pub_is_valid(dh, dh_client_pub)) 194 packet_disconnect("bad client public DH value"); 195 196 klen = DH_size(dh); 197 kbuf = xmalloc(klen); 198 kout = DH_compute_key(kbuf, dh_client_pub, dh); 199 if (kout < 0) 200 fatal("DH_compute_key: failed"); 201 202 shared_secret = BN_new(); 203 if (shared_secret == NULL) 204 fatal("kexgss_server: BN_new failed"); 205 206 if (BN_bin2bn(kbuf, kout, shared_secret) == NULL) 207 fatal("kexgss_server: BN_bin2bn failed"); 208 209 memset(kbuf, 0, klen); 210 xfree(kbuf); 211 212 switch (kex->kex_type) { 213 case KEX_GSS_GRP1_SHA1: 214 case KEX_GSS_GRP14_SHA1: 215 kex_dh_hash( 216 kex->client_version_string, kex->server_version_string, 217 buffer_ptr(&kex->peer), buffer_len(&kex->peer), 218 buffer_ptr(&kex->my), buffer_len(&kex->my), 219 NULL, 0, /* Change this if we start sending host keys */ 220 dh_client_pub, dh->pub_key, shared_secret, 221 &hash, &hashlen 222 ); 223 break; 224 case KEX_GSS_GEX_SHA1: 225 kexgex_hash( 226 kex->evp_md, 227 kex->client_version_string, kex->server_version_string, 228 buffer_ptr(&kex->peer), buffer_len(&kex->peer), 229 buffer_ptr(&kex->my), buffer_len(&kex->my), 230 NULL, 0, 231 min, nbits, max, 232 dh->p, dh->g, 233 dh_client_pub, 234 dh->pub_key, 235 shared_secret, 236 &hash, &hashlen 237 ); 238 break; 239 default: 240 fatal("%s: Unexpected KEX type %d", __func__, kex->kex_type); 241 } 242 243 BN_clear_free(dh_client_pub); 244 245 if (kex->session_id == NULL) { 246 kex->session_id_len = hashlen; 247 kex->session_id = xmalloc(kex->session_id_len); 248 memcpy(kex->session_id, hash, kex->session_id_len); 249 } 250 251 gssbuf.value = hash; 252 gssbuf.length = hashlen; 253 254 if (GSS_ERROR(PRIVSEP(ssh_gssapi_sign(ctxt,&gssbuf,&msg_tok)))) 255 fatal("Couldn't get MIC"); 256 257 packet_start(SSH2_MSG_KEXGSS_COMPLETE); 258 packet_put_bignum2(dh->pub_key); 259 packet_put_string(msg_tok.value,msg_tok.length); 260 261 if (send_tok.length != 0) { 262 packet_put_char(1); /* true */ 263 packet_put_string(send_tok.value, send_tok.length); 264 } else { 265 packet_put_char(0); /* false */ 266 } 267 packet_send(); 268 269 gss_release_buffer(&min_status, &send_tok); 270 gss_release_buffer(&min_status, &msg_tok); 271 272 if (gss_kex_context == NULL) 273 gss_kex_context = ctxt; 274 else 275 ssh_gssapi_delete_ctx(&ctxt); 276 277 DH_free(dh); 278 279 kex_derive_keys(kex, hash, hashlen, shared_secret); 280 BN_clear_free(shared_secret); 281 kex_finish(kex); 282 283 /* If this was a rekey, then save out any delegated credentials we 284 * just exchanged. */ 285 if (options.gss_store_rekey) 286 ssh_gssapi_rekey_creds(); 287 } 288 #endif /* GSSAPI */ -
openssh-5.3p1
old new key_type_from_name(char *name) 1020 1020 return KEY_RSA_CERT; 1021 1021 } else if (strcmp(name, "ssh-dss-cert-v01@openssh.com") == 0) { 1022 1022 return KEY_DSA_CERT; 1023 } else if (strcmp(name, "null") == 0) { 1024 return KEY_NULL; 1023 1025 } 1024 1026 debug2("key_type_from_name: unknown key type '%s'", name); 1025 1027 return KEY_UNSPEC; -
openssh-5.3p1
old new enum types { 39 39 KEY_DSA_CERT, 40 40 KEY_RSA_CERT_V00, 41 41 KEY_DSA_CERT_V00, 42 KEY_NULL, 42 43 KEY_UNSPEC 43 44 }; 44 45 enum fp_type { -
openssh-5.3p1
old new 172 172 int mm_answer_gss_accept_ctx(int, Buffer *); 173 173 int mm_answer_gss_userok(int, Buffer *); 174 174 int mm_answer_gss_checkmic(int, Buffer *); 175 int mm_answer_gss_sign(int, Buffer *); 176 int mm_answer_gss_updatecreds(int, Buffer *); 175 177 #endif 176 178 177 179 #ifdef SSH_AUDIT_EVENTS … … 241 243 {MONITOR_REQ_GSSSTEP, MON_ISAUTH, mm_answer_gss_accept_ctx}, 242 244 {MONITOR_REQ_GSSUSEROK, MON_AUTH, mm_answer_gss_userok}, 243 245 {MONITOR_REQ_GSSCHECKMIC, MON_ISAUTH, mm_answer_gss_checkmic}, 246 {MONITOR_REQ_GSSSIGN, MON_ONCE, mm_answer_gss_sign}, 244 247 #endif 245 248 #ifdef JPAKE 246 249 {MONITOR_REQ_JPAKE_GET_PWDATA, MON_ONCE, mm_answer_jpake_get_pwdata}, … … 253 256 }; 254 257 255 258 struct mon_table mon_dispatch_postauth20[] = { 259 #ifdef GSSAPI 260 {MONITOR_REQ_GSSSETUP, 0, mm_answer_gss_setup_ctx}, 261 {MONITOR_REQ_GSSSTEP, 0, mm_answer_gss_accept_ctx}, 262 {MONITOR_REQ_GSSSIGN, 0, mm_answer_gss_sign}, 263 {MONITOR_REQ_GSSUPCREDS, 0, mm_answer_gss_updatecreds}, 264 #endif 256 265 {MONITOR_REQ_MODULI, 0, mm_answer_moduli}, 257 266 {MONITOR_REQ_SIGN, 0, mm_answer_sign}, 258 267 {MONITOR_REQ_PTY, 0, mm_answer_pty}, … … 357 366 /* Permit requests for moduli and signatures */ 358 367 monitor_permit(mon_dispatch, MONITOR_REQ_MODULI, 1); 359 368 monitor_permit(mon_dispatch, MONITOR_REQ_SIGN, 1); 369 #ifdef GSSAPI 370 /* and for the GSSAPI key exchange */ 371 monitor_permit(mon_dispatch, MONITOR_REQ_GSSSETUP, 1); 372 #endif 360 373 } else { 361 374 mon_dispatch = mon_dispatch_proto15; 362 375 … … 443 456 monitor_permit(mon_dispatch, MONITOR_REQ_MODULI, 1); 444 457 monitor_permit(mon_dispatch, MONITOR_REQ_SIGN, 1); 445 458 monitor_permit(mon_dispatch, MONITOR_REQ_TERM, 1); 459 #ifdef GSSAPI 460 /* and for the GSSAPI key exchange */ 461 monitor_permit(mon_dispatch, MONITOR_REQ_GSSSETUP, 1); 462 #endif 446 463 } else { 447 464 mon_dispatch = mon_dispatch_postauth15; 448 465 monitor_permit(mon_dispatch, MONITOR_REQ_TERM, 1); … … 1706 1723 kex->kex[KEX_DH_GRP14_SHA1] = kexdh_server; 1707 1724 kex->kex[KEX_DH_GEX_SHA1] = kexgex_server; 1708 1725 kex->kex[KEX_DH_GEX_SHA256] = kexgex_server; 1726 #ifdef GSSAPI 1727 if (options.gss_keyex) { 1728 kex->kex[KEX_GSS_GRP1_SHA1] = kexgss_server; 1729 kex->kex[KEX_GSS_GRP14_SHA1] = kexgss_server; 1730 kex->kex[KEX_GSS_GEX_SHA1] = kexgss_server; 1731 } 1732 #endif 1709 1733 kex->server = 1; 1710 1734 kex->hostkey_type = buffer_get_int(m); 1711 1735 kex->kex_type = buffer_get_int(m); … … 1911 1935 OM_uint32 major; 1912 1936 u_int len; 1913 1937 1938 if (!options.gss_authentication && !options.gss_keyex) 1939 fatal("In GSSAPI monitor when GSSAPI is disabled"); 1940 1914 1941 goid.elements = buffer_get_string(m, &len); 1915 1942 goid.length = len; 1916 1943 … … 1938 1965 OM_uint32 flags = 0; /* GSI needs this */ 1939 1966 u_int len; 1940 1967 1968 if (!options.gss_authentication && !options.gss_keyex) 1969 fatal("In GSSAPI monitor when GSSAPI is disabled"); 1970 1941 1971 in.value = buffer_get_string(m, &len); 1942 1972 in.length = len; 1943 1973 major = ssh_gssapi_accept_ctx(gsscontext, &in, &out, &flags); … … 1955 1985 monitor_permit(mon_dispatch, MONITOR_REQ_GSSSTEP, 0); 1956 1986 monitor_permit(mon_dispatch, MONITOR_REQ_GSSUSEROK, 1); 1957 1987 monitor_permit(mon_dispatch, MONITOR_REQ_GSSCHECKMIC, 1); 1988 monitor_permit(mon_dispatch, MONITOR_REQ_GSSSIGN, 1); 1958 1989 } 1959 1990 return (0); 1960 1991 } … … 1966 1997 OM_uint32 ret; 1967 1998 u_int len; 1968 1999 2000 if (!options.gss_authentication && !options.gss_keyex) 2001 fatal("In GSSAPI monitor when GSSAPI is disabled"); 2002 1969 2003 gssbuf.value = buffer_get_string(m, &len); 1970 2004 gssbuf.length = len; 1971 2005 mic.value = buffer_get_string(m, &len); … … 1992 2026 { 1993 2027 int authenticated; 1994 2028 1995 authenticated = authctxt->valid && ssh_gssapi_userok(authctxt->user); 2029 if (!options.gss_authentication && !options.gss_keyex) 2030 fatal("In GSSAPI monitor when GSSAPI is disabled"); 2031 2032 authenticated = authctxt->valid && 2033 ssh_gssapi_userok(authctxt->user, authctxt->pw); 1996 2034 1997 2035 buffer_clear(m); 1998 2036 buffer_put_int(m, authenticated); … … 2005 2043 /* Monitor loop will terminate if authenticated */ 2006 2044 return (authenticated); 2007 2045 } 2046 2047 int 2048 mm_answer_gss_sign(int socket, Buffer *m) 2049 { 2050 gss_buffer_desc data; 2051 gss_buffer_desc hash = GSS_C_EMPTY_BUFFER; 2052 OM_uint32 major, minor; 2053 u_int len; 2054 2055 if (!options.gss_authentication && !options.gss_keyex) 2056 fatal("In GSSAPI monitor when GSSAPI is disabled"); 2057 2058 data.value = buffer_get_string(m, &len); 2059 data.length = len; 2060 if (data.length != 20) 2061 fatal("%s: data length incorrect: %d", __func__, 2062 (int) data.length); 2063 2064 /* Save the session ID on the first time around */ 2065 if (session_id2_len == 0) { 2066 session_id2_len = data.length; 2067 session_id2 = xmalloc(session_id2_len); 2068 memcpy(session_id2, data.value, session_id2_len); 2069 } 2070 major = ssh_gssapi_sign(gsscontext, &data, &hash); 2071 2072 xfree(data.value); 2073 2074 buffer_clear(m); 2075 buffer_put_int(m, major); 2076 buffer_put_string(m, hash.value, hash.length); 2077 2078 mm_request_send(socket, MONITOR_ANS_GSSSIGN, m); 2079 2080 gss_release_buffer(&minor, &hash); 2081 2082 /* Turn on getpwnam permissions */ 2083 monitor_permit(mon_dispatch, MONITOR_REQ_PWNAM, 1); 2084 2085 /* And credential updating, for when rekeying */ 2086 monitor_permit(mon_dispatch, MONITOR_REQ_GSSUPCREDS, 1); 2087 2088 return (0); 2089 } 2090 2091 int 2092 mm_answer_gss_updatecreds(int socket, Buffer *m) { 2093 ssh_gssapi_ccache store; 2094 int ok; 2095 2096 store.filename = buffer_get_string(m, NULL); 2097 store.envvar = buffer_get_string(m, NULL); 2098 store.envval = buffer_get_string(m, NULL); 2099 2100 ok = ssh_gssapi_update_creds(&store); 2101 2102 xfree(store.filename); 2103 xfree(store.envvar); 2104 xfree(store.envval); 2105 2106 buffer_clear(m); 2107 buffer_put_int(m, ok); 2108 2109 mm_request_send(socket, MONITOR_ANS_GSSUPCREDS, m); 2110 2111 return(0); 2112 } 2113 2008 2114 #endif /* GSSAPI */ 2009 2115 2010 2116 #ifdef JPAKE -
openssh-5.3p1
old new 53 53 MONITOR_REQ_GSSSTEP, MONITOR_ANS_GSSSTEP, 54 54 MONITOR_REQ_GSSUSEROK, MONITOR_ANS_GSSUSEROK, 55 55 MONITOR_REQ_GSSCHECKMIC, MONITOR_ANS_GSSCHECKMIC, 56 MONITOR_REQ_GSSSIGN, MONITOR_ANS_GSSSIGN, 57 MONITOR_REQ_GSSUPCREDS, MONITOR_ANS_GSSUPCREDS, 56 58 MONITOR_REQ_PAM_START, 57 59 MONITOR_REQ_PAM_ACCOUNT, MONITOR_ANS_PAM_ACCOUNT, 58 60 MONITOR_REQ_PAM_INIT_CTX, MONITOR_ANS_PAM_INIT_CTX, -
monitor_wrap.c
old new 1248 1248 } 1249 1249 1250 1250 int 1251 mm_ssh_gssapi_userok(char *user )1251 mm_ssh_gssapi_userok(char *user, struct passwd *pw) 1252 1252 { 1253 1253 Buffer m; 1254 1254 int authenticated = 0; … … 1265 1265 debug3("%s: user %sauthenticated",__func__, authenticated ? "" : "not "); 1266 1266 return (authenticated); 1267 1267 } 1268 1269 OM_uint32 1270 mm_ssh_gssapi_sign(Gssctxt *ctx, gss_buffer_desc *data, gss_buffer_desc *hash) 1271 { 1272 Buffer m; 1273 OM_uint32 major; 1274 u_int len; 1275 1276 buffer_init(&m); 1277 buffer_put_string(&m, data->value, data->length); 1278 1279 mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_GSSSIGN, &m); 1280 mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_GSSSIGN, &m); 1281 1282 major = buffer_get_int(&m); 1283 hash->value = buffer_get_string(&m, &len); 1284 hash->length = len; 1285 1286 buffer_free(&m); 1287 1288 return(major); 1289 } 1290 1291 int 1292 mm_ssh_gssapi_update_creds(ssh_gssapi_ccache *store) 1293 { 1294 Buffer m; 1295 int ok; 1296 1297 buffer_init(&m); 1298 1299 buffer_put_cstring(&m, store->filename ? store->filename : ""); 1300 buffer_put_cstring(&m, store->envvar ? store->envvar : ""); 1301 buffer_put_cstring(&m, store->envval ? store->envval : ""); 1302 1303 mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_GSSUPCREDS, &m); 1304 mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_GSSUPCREDS, &m); 1305 1306 ok = buffer_get_int(&m); 1307 1308 buffer_free(&m); 1309 1310 return (ok); 1311 } 1312 1268 1313 #endif /* GSSAPI */ 1269 1314 1270 1315 #ifdef JPAKE -
monitor_wrap.h
old new 57 57 OM_uint32 mm_ssh_gssapi_server_ctx(Gssctxt **, gss_OID); 58 58 OM_uint32 mm_ssh_gssapi_accept_ctx(Gssctxt *, 59 59 gss_buffer_desc *, gss_buffer_desc *, OM_uint32 *); 60 int mm_ssh_gssapi_userok(char *user );60 int mm_ssh_gssapi_userok(char *user, struct passwd *); 61 61 OM_uint32 mm_ssh_gssapi_checkmic(Gssctxt *, gss_buffer_t, gss_buffer_t); 62 OM_uint32 mm_ssh_gssapi_sign(Gssctxt *, gss_buffer_t, gss_buffer_t); 63 int mm_ssh_gssapi_update_creds(ssh_gssapi_ccache *); 62 64 #endif 63 65 64 66 #ifdef USE_PAM -
openssh-5.3p1
old new 1 1 /* $OpenBSD: ssh-gss.h,v 1.10 2007/06/12 08:20:00 djm Exp $ */ 2 2 /* 3 * Copyright (c) 2001-200 3Simon Wilkinson. All rights reserved.3 * Copyright (c) 2001-2009 Simon Wilkinson. All rights reserved. 4 4 * 5 5 * Redistribution and use in source and binary forms, with or without 6 6 * modification, are permitted provided that the following conditions … … 60 60 61 61 #define SSH_GSS_OIDTYPE 0x06 62 62 63 #define SSH2_MSG_KEXGSS_INIT 30 64 #define SSH2_MSG_KEXGSS_CONTINUE 31 65 #define SSH2_MSG_KEXGSS_COMPLETE 32 66 #define SSH2_MSG_KEXGSS_HOSTKEY 33 67 #define SSH2_MSG_KEXGSS_ERROR 34 68 #define SSH2_MSG_KEXGSS_GROUPREQ 40 69 #define SSH2_MSG_KEXGSS_GROUP 41 70 #define KEX_GSS_GRP1_SHA1_ID "gss-group1-sha1-" 71 #define KEX_GSS_GRP14_SHA1_ID "gss-group14-sha1-" 72 #define KEX_GSS_GEX_SHA1_ID "gss-gex-sha1-" 73 63 74 typedef struct { 64 75 char *filename; 65 76 char *envvar; 66 77 char *envval; 78 struct passwd *owner; 67 79 void *data; 68 80 } ssh_gssapi_ccache; 69 81 … … 71 83 gss_buffer_desc displayname; 72 84 gss_buffer_desc exportedname; 73 85 gss_cred_id_t creds; 86 gss_name_t name; 74 87 struct ssh_gssapi_mech_struct *mech; 75 88 ssh_gssapi_ccache store; 89 int used; 90 int updated; 76 91 } ssh_gssapi_client; 77 92 78 93 typedef struct ssh_gssapi_mech_struct { … … 83 98 int (*userok) (ssh_gssapi_client *, char *); 84 99 int (*localname) (ssh_gssapi_client *, char **); 85 100 void (*storecreds) (ssh_gssapi_client *); 101 int (*updatecreds) (ssh_gssapi_ccache *, ssh_gssapi_client *); 86 102 } ssh_gssapi_mech; 87 103 88 104 typedef struct { … … 93 109 gss_OID oid; /* client */ 94 110 gss_cred_id_t creds; /* server */ 95 111 gss_name_t client; /* server */ 96 gss_cred_id_t client_creds; /* server*/112 gss_cred_id_t client_creds; /* both */ 97 113 } Gssctxt; 98 114 99 115 extern ssh_gssapi_mech *supported_mechs[]; 116 extern Gssctxt *gss_kex_context; 100 117 101 118 int ssh_gssapi_check_oid(Gssctxt *, void *, size_t); 102 119 void ssh_gssapi_set_oid_data(Gssctxt *, void *, size_t); … … 116 133 void ssh_gssapi_delete_ctx(Gssctxt **); 117 134 OM_uint32 ssh_gssapi_sign(Gssctxt *, gss_buffer_t, gss_buffer_t); 118 135 void ssh_gssapi_buildmic(Buffer *, const char *, const char *, const char *); 119 int ssh_gssapi_check_mechanism(Gssctxt **, gss_OID, const char *); 136 int ssh_gssapi_check_mechanism(Gssctxt **, gss_OID, const char *, const char *); 137 OM_uint32 ssh_gssapi_client_identity(Gssctxt *, const char *); 138 int ssh_gssapi_credentials_updated(Gssctxt *); 120 139 121 140 /* In the server */ 141 typedef int ssh_gssapi_check_fn(Gssctxt **, gss_OID, const char *, 142 const char *); 143 char *ssh_gssapi_client_mechanisms(const char *, const char *); 144 char *ssh_gssapi_kex_mechs(gss_OID_set, ssh_gssapi_check_fn *, const char *, 145 const char *); 146 gss_OID ssh_gssapi_id_kex(Gssctxt *, char *, int); 147 int ssh_gssapi_server_check_mech(Gssctxt **,gss_OID, const char *, 148 const char *); 122 149 OM_uint32 ssh_gssapi_server_ctx(Gssctxt **, gss_OID); 123 int ssh_gssapi_userok(char *name );150 int ssh_gssapi_userok(char *name, struct passwd *); 124 151 OM_uint32 ssh_gssapi_checkmic(Gssctxt *, gss_buffer_t, gss_buffer_t); 125 152 void ssh_gssapi_do_child(char ***, u_int *); 126 153 void ssh_gssapi_cleanup_creds(void); 127 154 void ssh_gssapi_storecreds(void); 128 155 156 char *ssh_gssapi_server_mechanisms(void); 157 int ssh_gssapi_oid_table_ok(); 158 159 int ssh_gssapi_update_creds(ssh_gssapi_ccache *store); 129 160 #endif /* GSSAPI */ 130 161 131 162 #endif /* _SSH_GSS_H */ -
openssh-5.3p1
old new 26 26 # HostbasedAuthentication no 27 27 # GSSAPIAuthentication no 28 28 # GSSAPIDelegateCredentials no 29 # GSSAPIKeyExchange no 30 # GSSAPITrustDNS no 29 31 # BatchMode no 30 32 # CheckHostIP yes 31 33 # AddressFamily any -
clientloop.c
old new 111 111 #include "msg.h" 112 112 #include "roaming.h" 113 113 114 #ifdef GSSAPI 115 #include "ssh-gss.h" 116 #endif 117 114 118 /* import options */ 115 119 extern Options options; 116 120 … … 1430 1434 /* Do channel operations unless rekeying in progress. */ 1431 1435 if (!rekeying) { 1432 1436 channel_after_select(readset, writeset); 1437 1438 #ifdef GSSAPI 1439 if (options.gss_renewal_rekey && 1440 ssh_gssapi_credentials_updated(GSS_C_NO_CONTEXT)) { 1441 debug("credentials updated - forcing rekey"); 1442 need_rekeying = 1; 1443 } 1444 #endif 1445 1433 1446 if (need_rekeying || packet_need_rekeying()) { 1434 1447 debug("need rekeying"); 1435 1448 xxx_kex->done = 0;