# The patch below adds support for the deprecated 'gssapi' authentication # mechanism to OpenSSH 3.8p1. The newer 'gssapi-with-mic' mechanism is included # in this release. The use of 'gssapi' is deprecated due to the presence of # potential man-in-the-middle attacks, which 'gssapi-with-mic' is not # susceptible to. # # To use the patch apply it to a OpenSSH 3.8p1 source tree. After compiling, # backwards compatibility may be obtained by supplying the # 'GssapiEnableMitmAttack yes' option to either the client or server. # # It should be noted that this patch is being made available purely as a means # of easing the process of moving to OpenSSH 3.8p1. Any new installations are # recommended to use the 'gssapi-with-mic' mechanism. Existing installations # are encouraged to upgrade as soon as possible. diff --git a/openssh-6.4p1/auth2-gss.c b/openssh-6.4p1/auth2-gss.c --- a/openssh-6.4p1/auth2-gss.c +++ b/openssh-6.4p1/auth2-gss.c @@ -173,16 +173,25 @@ input_gssapi_token(int type, u_int32_t p dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_TOKEN, NULL); if (flags & GSS_C_INTEG_FLAG) dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_MIC, &input_gssapi_mic); else dispatch_set( SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE, &input_gssapi_exchange_complete); + + /* + * Old style 'gssapi' didn't have the GSSAPI_MIC + * and went straight to sending exchange_complete + */ + if (options.gss_enable_mitm) + dispatch_set( + SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE, + &input_gssapi_exchange_complete); } } gss_release_buffer(&min_status, &send_tok); } static void input_gssapi_errtok(int type, u_int32_t plen, void *ctxt) @@ -291,9 +300,15 @@ input_gssapi_mic(int type, u_int32_t ple } Authmethod method_gssapi = { "gssapi-with-mic", userauth_gssapi, &options.gss_authentication }; +Authmethod method_gssapi_old = { + "gssapi", + userauth_gssapi, + &options.gss_enable_mitm +}; + #endif /* GSSAPI */ diff --git a/openssh-6.4p1/auth2.c b/openssh-6.4p1/auth2.c --- a/openssh-6.4p1/auth2.c +++ b/openssh-6.4p1/auth2.c @@ -65,26 +65,28 @@ extern Buffer loginmsg; extern Authmethod method_none; extern Authmethod method_pubkey; extern Authmethod method_passwd; extern Authmethod method_kbdint; extern Authmethod method_hostbased; #ifdef GSSAPI extern Authmethod method_gssapi; +extern Authmethod method_gssapi_old; #endif #ifdef JPAKE extern Authmethod method_jpake; #endif Authmethod *authmethods[] = { &method_none, &method_pubkey, #ifdef GSSAPI &method_gssapi, + &method_gssapi_old, #endif #ifdef JPAKE &method_jpake, #endif &method_passwd, &method_kbdint, &method_hostbased, NULL diff --git a/openssh-6.4p1/readconf.c b/openssh-6.4p1/readconf.c --- a/openssh-6.4p1/readconf.c +++ b/openssh-6.4p1/readconf.c @@ -126,17 +126,17 @@ typedef enum { oCompressionLevel, oTCPKeepAlive, oNumberOfPasswordPrompts, oUsePrivilegedPort, oLogLevel, oCiphers, oProtocol, oMacs, oGlobalKnownHostsFile2, oUserKnownHostsFile2, oPubkeyAuthentication, oKbdInteractiveAuthentication, oKbdInteractiveDevices, oHostKeyAlias, oDynamicForward, oPreferredAuthentications, oHostbasedAuthentication, oHostKeyAlgorithms, oBindAddress, oPKCS11Provider, oClearAllForwardings, oNoHostAuthenticationForLocalhost, oEnableSSHKeysign, oRekeyLimit, oVerifyHostKeyDNS, oConnectTimeout, - oAddressFamily, oGssAuthentication, oGssDelegateCreds, + oAddressFamily, oGssAuthentication, oGssDelegateCreds, oGssEnableMITM, oServerAliveInterval, oServerAliveCountMax, oIdentitiesOnly, oSendEnv, oControlPath, oControlMaster, oControlPersist, oHashKnownHosts, oTunnel, oTunnelDevice, oLocalCommand, oPermitLocalCommand, oVisualHostKey, oUseRoaming, oZeroKnowledgePasswordAuthentication, oKexAlgorithms, oIPQoS, oRequestTTY, oIgnoreUnknown, oIgnoredUnknownOption, oDeprecated, oUnsupported } OpCodes; @@ -168,19 +168,21 @@ static struct { { "skeyauthentication", oChallengeResponseAuthentication }, /* alias */ { "tisauthentication", oChallengeResponseAuthentication }, /* alias */ { "kerberosauthentication", oUnsupported }, { "kerberostgtpassing", oUnsupported }, { "afstokenpassing", oUnsupported }, #if defined(GSSAPI) { "gssapiauthentication", oGssAuthentication }, { "gssapidelegatecredentials", oGssDelegateCreds }, + { "gssapienablemitmattack", oGssEnableMITM }, #else { "gssapiauthentication", oUnsupported }, { "gssapidelegatecredentials", oUnsupported }, + { "gssapienablemitmattack", oUnsupported }, #endif { "fallbacktorsh", oDeprecated }, { "usersh", oDeprecated }, { "identityfile", oIdentityFile }, { "identityfile2", oIdentityFile }, /* obsolete */ { "identitiesonly", oIdentitiesOnly }, { "hostname", oHostName }, { "hostkeyalias", oHostKeyAlias }, @@ -514,16 +516,20 @@ parse_flag: case oGssAuthentication: intptr = &options->gss_authentication; goto parse_flag; case oGssDelegateCreds: intptr = &options->gss_deleg_creds; goto parse_flag; + + case oGssEnableMITM: + intptr = &options->gss_enable_mitm; + goto parse_flag; case oBatchMode: intptr = &options->batch_mode; goto parse_flag; case oCheckHostIP: intptr = &options->check_host_ip; goto parse_flag; @@ -1164,16 +1170,17 @@ initialize_options(Options * options) options->xauth_location = NULL; options->gateway_ports = -1; options->use_privileged_port = -1; options->rsa_authentication = -1; options->pubkey_authentication = -1; options->challenge_response_authentication = -1; options->gss_authentication = -1; options->gss_deleg_creds = -1; + options->gss_enable_mitm = -1; options->password_authentication = -1; options->kbd_interactive_authentication = -1; options->kbd_interactive_devices = NULL; options->rhosts_rsa_authentication = -1; options->hostbased_authentication = -1; options->batch_mode = -1; options->check_host_ip = -1; options->strict_host_key_checking = -1; @@ -1265,16 +1272,18 @@ fill_default_options(Options * options) if (options->pubkey_authentication == -1) options->pubkey_authentication = 1; if (options->challenge_response_authentication == -1) options->challenge_response_authentication = 1; if (options->gss_authentication == -1) options->gss_authentication = 0; if (options->gss_deleg_creds == -1) options->gss_deleg_creds = 0; + if (options->gss_enable_mitm == -1) + options->gss_enable_mitm = 0; if (options->password_authentication == -1) options->password_authentication = 1; if (options->kbd_interactive_authentication == -1) options->kbd_interactive_authentication = 1; if (options->rhosts_rsa_authentication == -1) options->rhosts_rsa_authentication = 0; if (options->hostbased_authentication == -1) options->hostbased_authentication = 0; diff --git a/openssh-6.4p1/readconf.h b/openssh-6.4p1/readconf.h --- a/openssh-6.4p1/readconf.h +++ b/openssh-6.4p1/readconf.h @@ -44,16 +44,17 @@ typedef struct { * authentication. */ int rsa_authentication; /* Try RSA authentication. */ int pubkey_authentication; /* Try ssh2 pubkey authentication. */ int hostbased_authentication; /* ssh2's rhosts_rsa */ int challenge_response_authentication; /* Try S/Key or TIS, authentication. */ int gss_authentication; /* Try GSS authentication */ int gss_deleg_creds; /* Delegate GSS credentials */ + int gss_enable_mitm; /* Enable old style gssapi auth */ int password_authentication; /* Try password * authentication. */ int kbd_interactive_authentication; /* Try keyboard-interactive auth. */ char *kbd_interactive_devices; /* Keyboard-interactive auth devices. */ int zero_knowledge_password_authentication; /* Try jpake */ int batch_mode; /* Batch mode: do not ask for passwords. */ int check_host_ip; /* Also keep track of keys for IP address */ int strict_host_key_checking; /* Strict host key checking. */ diff --git a/openssh-6.4p1/servconf.c b/openssh-6.4p1/servconf.c --- a/openssh-6.4p1/servconf.c +++ b/openssh-6.4p1/servconf.c @@ -103,16 +103,17 @@ initialize_server_options(ServerOptions options->rsa_authentication = -1; options->pubkey_authentication = -1; options->kerberos_authentication = -1; options->kerberos_or_local_passwd = -1; options->kerberos_ticket_cleanup = -1; options->kerberos_get_afs_token = -1; options->gss_authentication=-1; options->gss_cleanup_creds = -1; + options->gss_enable_mitm = -1; options->password_authentication = -1; options->kbd_interactive_authentication = -1; options->challenge_response_authentication = -1; options->permit_empty_passwd = -1; options->permit_user_env = -1; options->use_login = -1; options->compression = -1; options->rekey_limit = -1; @@ -237,16 +238,18 @@ fill_default_server_options(ServerOption if (options->kerberos_ticket_cleanup == -1) options->kerberos_ticket_cleanup = 1; if (options->kerberos_get_afs_token == -1) options->kerberos_get_afs_token = 0; if (options->gss_authentication == -1) options->gss_authentication = 0; if (options->gss_cleanup_creds == -1) options->gss_cleanup_creds = 1; + if (options->gss_enable_mitm == -1) + options->gss_enable_mitm = 0; if (options->password_authentication == -1) options->password_authentication = 1; if (options->kbd_interactive_authentication == -1) options->kbd_interactive_authentication = 0; if (options->challenge_response_authentication == -1) options->challenge_response_authentication = 1; if (options->permit_empty_passwd == -1) options->permit_empty_passwd = 0; @@ -333,17 +336,17 @@ typedef enum { sPermitUserEnvironment, sUseLogin, sAllowTcpForwarding, sCompression, sRekeyLimit, sAllowUsers, sDenyUsers, sAllowGroups, sDenyGroups, sIgnoreUserKnownHosts, sCiphers, sMacs, sProtocol, sPidFile, sGatewayPorts, sPubkeyAuthentication, sXAuthLocation, sSubsystem, sMaxStartups, sMaxAuthTries, sMaxSessions, sBanner, sUseDNS, sHostbasedAuthentication, sHostbasedUsesNameFromPacketOnly, sClientAliveInterval, sClientAliveCountMax, sAuthorizedKeysFile, - sGssAuthentication, sGssCleanupCreds, sAcceptEnv, sPermitTunnel, + sGssAuthentication, sGssCleanupCreds, sAcceptEnv, sPermitTunnel, sGssEnableMITM, sMatch, sPermitOpen, sForceCommand, sChrootDirectory, sUsePrivilegeSeparation, sAllowAgentForwarding, sZeroKnowledgePasswordAuthentication, sHostCertificate, sRevokedKeys, sTrustedUserCAKeys, sAuthorizedPrincipalsFile, sKexAlgorithms, sIPQoS, sVersionAddendum, sAuthorizedKeysCommand, sAuthorizedKeysCommandUser, sAuthenticationMethods, sHostKeyAgent, sDeprecated, sUnsupported @@ -400,19 +403,21 @@ static struct { { "kerberosticketcleanup", sUnsupported, SSHCFG_GLOBAL }, { "kerberosgetafstoken", sUnsupported, SSHCFG_GLOBAL }, #endif { "kerberostgtpassing", sUnsupported, SSHCFG_GLOBAL }, { "afstokenpassing", sUnsupported, SSHCFG_GLOBAL }, #ifdef GSSAPI { "gssapiauthentication", sGssAuthentication, SSHCFG_ALL }, { "gssapicleanupcredentials", sGssCleanupCreds, SSHCFG_GLOBAL }, + { "gssapienablemitmattack", sGssEnableMITM }, #else { "gssapiauthentication", sUnsupported, SSHCFG_ALL }, { "gssapicleanupcredentials", sUnsupported, SSHCFG_GLOBAL }, + { "gssapienablemitmattack", sUnsupported }, #endif { "passwordauthentication", sPasswordAuthentication, SSHCFG_ALL }, { "kbdinteractiveauthentication", sKbdInteractiveAuthentication, SSHCFG_ALL }, { "challengeresponseauthentication", sChallengeResponseAuthentication, SSHCFG_GLOBAL }, { "skeyauthentication", sChallengeResponseAuthentication, SSHCFG_GLOBAL }, /* alias */ #ifdef JPAKE { "zeroknowledgepasswordauthentication", sZeroKnowledgePasswordAuthentication, SSHCFG_ALL }, #else @@ -1072,16 +1077,20 @@ process_server_config_line(ServerOptions case sGssAuthentication: intptr = &options->gss_authentication; goto parse_flag; case sGssCleanupCreds: intptr = &options->gss_cleanup_creds; goto parse_flag; + case sGssEnableMITM: + intptr = &options->gss_enable_mitm; + goto parse_flag; + case sPasswordAuthentication: intptr = &options->password_authentication; goto parse_flag; case sZeroKnowledgePasswordAuthentication: intptr = &options->zero_knowledge_password_authentication; goto parse_flag; diff --git a/openssh-6.4p1/servconf.h b/openssh-6.4p1/servconf.h --- a/openssh-6.4p1/servconf.h +++ b/openssh-6.4p1/servconf.h @@ -107,16 +107,17 @@ typedef struct { * such as SecurID or * /etc/passwd */ int kerberos_ticket_cleanup; /* If true, destroy ticket * file on logout. */ int kerberos_get_afs_token; /* If true, try to get AFS token if * authenticated with Kerberos. */ int gss_authentication; /* If true, permit GSSAPI authentication */ int gss_cleanup_creds; /* If true, destroy cred cache on logout */ + int gss_enable_mitm; /* If true, enable old style GSSAPI */ int password_authentication; /* If true, permit password * authentication. */ int kbd_interactive_authentication; /* If true, permit */ int challenge_response_authentication; int zero_knowledge_password_authentication; /* If true, permit jpake auth */ int permit_empty_passwd; /* If false, do not permit empty * passwords. */ diff --git a/openssh-6.4p1/ssh_config b/openssh-6.4p1/ssh_config --- a/openssh-6.4p1/ssh_config +++ b/openssh-6.4p1/ssh_config @@ -51,9 +51,16 @@ ForwardX11Trusted yes # Ciphers aes128-ctr,aes192-ctr,aes256-ctr,arcfour256,arcfour128,aes128-cbc,3des-cbc # MACs hmac-md5,hmac-sha1,umac-64@openssh.com,hmac-ripemd160 # EscapeChar ~ # Tunnel no # TunnelDevice any:any # PermitLocalCommand no # VisualHostKey no # ProxyCommand ssh -q -W %h:%p gateway.example.com + +# Set this to 'yes' to enable support for the deprecated 'gssapi' authentication +# mechanism to OpenSSH 3.8p1. The newer 'gssapi-with-mic' mechanism is included +# in this release. The use of 'gssapi' is deprecated due to the presence of +# potential man-in-the-middle attacks, which 'gssapi-with-mic' is not susceptible to. +# GSSAPIEnableMITMAttack no + # RekeyLimit 1G 1h diff --git a/openssh-6.4p1/sshconnect2.c b/openssh-6.4p1/sshconnect2.c --- a/openssh-6.4p1/sshconnect2.c +++ b/openssh-6.4p1/sshconnect2.c @@ -322,16 +322,21 @@ static char *authmethods_get(void); Authmethod authmethods[] = { #ifdef GSSAPI {"gssapi-with-mic", userauth_gssapi, NULL, &options.gss_authentication, NULL}, + {"gssapi", + userauth_gssapi, + NULL, + &options.gss_enable_mitm, + NULL}, #endif {"hostbased", userauth_hostbased, NULL, &options.hostbased_authentication, NULL}, {"publickey", userauth_pubkey, @@ -696,17 +701,19 @@ process_gssapi_token(void *ctxt, gss_buf packet_put_string(send_tok.value, send_tok.length); packet_send(); gss_release_buffer(&ms, &send_tok); } if (status == GSS_S_COMPLETE) { /* send either complete or MIC, depending on mechanism */ - if (!(flags & GSS_C_INTEG_FLAG)) { + + if (strcmp(authctxt->method->name,"gssapi") == 0 || + (!(flags & GSS_C_INTEG_FLAG))) { packet_start(SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE); packet_send(); } else { ssh_gssapi_buildmic(&b, authctxt->server_user, authctxt->service, "gssapi-with-mic"); gssbuf.value = buffer_ptr(&b); gssbuf.length = buffer_len(&b); diff --git a/openssh-6.4p1/sshd_config b/openssh-6.4p1/sshd_config --- a/openssh-6.4p1/sshd_config +++ b/openssh-6.4p1/sshd_config @@ -79,16 +79,23 @@ PasswordAuthentication no #KerberosOrLocalPasswd yes #KerberosTicketCleanup yes #KerberosGetAFSToken no # GSSAPI options #GSSAPIAuthentication no #GSSAPICleanupCredentials yes +# Set this to 'yes' to enable support for the deprecated 'gssapi' authentication +# mechanism to OpenSSH 3.8p1. The newer 'gssapi-with-mic' mechanism is included +# in this release. The use of 'gssapi' is deprecated due to the presence of +# potential man-in-the-middle attacks, which 'gssapi-with-mic' is not susceptible to. +#GSSAPIEnableMITMAttack no + + # Set this to 'yes' to enable PAM authentication, account processing, # and session processing. If this is enabled, PAM authentication will # be allowed through the ChallengeResponseAuthentication and # PasswordAuthentication. Depending on your PAM configuration, # PAM authentication via ChallengeResponseAuthentication may bypass # the setting of "PermitRootLogin without-password". # If you just want the PAM account and session checks to run without # PAM authentication, then enable this but set PasswordAuthentication