/* All this effort to report an error ... */
-void
-ssh_gssapi_error(OM_uint32 major_status,OM_uint32 minor_status) {
+static void
+ssh_gssapi_error_ex(OM_uint32 major_status,OM_uint32 minor_status,
+ int send_packet) {
OM_uint32 lmaj, lmin;
gss_buffer_desc msg;
OM_uint32 ctx;
&ctx, &msg);
if (lmaj == GSS_S_COMPLETE) {
debug((char *)msg.value);
+ if (send_packet) packet_send_debug((char *)msg.value);
(void) gss_release_buffer(&lmin, &msg);
}
} while (ctx!=0);
&ctx, &msg);
if (lmaj == GSS_S_COMPLETE) {
debug((char *)msg.value);
+ if (send_packet) packet_send_debug((char *)msg.value);
(void) gss_release_buffer(&lmin, &msg);
}
} while (ctx!=0);
}
+void
+ssh_gssapi_error(OM_uint32 major_status,OM_uint32 minor_status) {
+ ssh_gssapi_error_ex(major_status, minor_status, 0);
+}
+
+void
+ssh_gssapi_send_error(OM_uint32 major_status,OM_uint32 minor_status) {
+ ssh_gssapi_error_ex(major_status, minor_status, 1);
+}
+
+
+
+
/* Initialise our GSSAPI context. We use this opaque structure to contain all
* of the data which both the client and server need to persist across
* {accept,init}_sec_context calls, so that when we do it from the userauth
NULL,
&ctx->client_creds);
if (GSS_ERROR(maj_status)) {
- ssh_gssapi_error(maj_status,min_status);
+ ssh_gssapi_send_error(maj_status,min_status);
}
if (ctx->client_creds) {
ssh_gssapi_build_ctx(&ctxt);
if (ssh_gssapi_id_kex(&ctxt,kex->name))
- fatal("Unknown gssapi mechanism");
+ packet_disconnect("Unknown gssapi mechanism");
if (ssh_gssapi_acquire_cred(&ctxt))
- fatal("Unable to acquire credentials for the server");
+ packet_disconnect("Unable to acquire credentials for the server");
do {
debug("Wait SSH2_MSG_GSSAPI_INIT");
switch(type) {
case SSH2_MSG_KEXGSS_INIT:
if (dh_client_pub!=NULL)
- fatal("Received KEXGSS_INIT after initialising");
+ packet_disconnect("Received KEXGSS_INIT after initialising");
recv_tok.value=packet_get_string(&recv_tok.length);
dh_client_pub = BN_new();
break;
case SSH2_MSG_KEXGSS_CONTINUE:
if (dh_client_pub == NULL)
- fatal("Received KEXGSS_CONTINUE without initialising");
+ packet_disconnect("Received KEXGSS_CONTINUE without initialising");
recv_tok.value=packet_get_string(&recv_tok.length);
break;
default:
#ifdef GSS_C_GLOBUS_LIMITED_PROXY_FLAG
if (ret_flags & GSS_C_GLOBUS_LIMITED_PROXY_FLAG) {
- fatal("Limited proxy is not allowed.");
+ packet_disconnect("Limited proxy is not allowed in gssapi key exchange.");
}
#endif
}
} while (maj_status & GSS_S_CONTINUE_NEEDED);
- if (GSS_ERROR(maj_status))
- fatal("gss_accept_context died");
-
+ if (GSS_ERROR(maj_status)) {
+ ssh_gssapi_send_error(maj_status,min_status);
+ packet_disconnect("gssapi key exchange handshake failed");
+ }
+
debug("gss_complete");
- if (!(ret_flags & GSS_C_MUTUAL_FLAG))
- fatal("mutual authentication flag wasn't set");
-
- if (!(ret_flags & GSS_C_INTEG_FLAG))
- fatal("Integrity flag wasn't set");
+ if (!(ret_flags & GSS_C_MUTUAL_FLAG)) {
+ ssh_gssapi_send_error(maj_status,min_status);
+ packet_disconnect("gssapi mutual authentication failed");
+ }
+ if (!(ret_flags & GSS_C_INTEG_FLAG)) {
+ ssh_gssapi_send_error(maj_status,min_status);
+ packet_disconnect("gssapi channel integrity not established");
+ }
dh = dh_new_group1();
dh_gen_key(dh, kex->we_need * 8);
GSS_C_QOP_DEFAULT,
&gssbuf,
&msg_tok))) {
- ssh_gssapi_error(maj_status,min_status);
- fatal("Couldn't get MIC");
+ ssh_gssapi_send_error(maj_status,min_status);
+ packet_disconnect("Couldn't get MIC");
}
packet_start(SSH2_MSG_KEXGSS_COMPLETE);
if (ssh_gssapi_getclient(&ctxt,&gssapi_client_type,
&gssapi_client_name,
&gssapi_client_creds)) {
- fatal("Couldn't convert client name");
+ packet_disconnect("Couldn't convert client name");
}
gss_release_buffer(&min_status, &send_tok);