gssapi: gssapi callbacks serverside
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
Этот коммит содержится в:
родитель
31a129ee9e
Коммит
b0ab39a6f1
@ -106,7 +106,6 @@ typedef void (*ssh_global_request_callback) (ssh_session session,
|
|||||||
typedef ssh_channel (*ssh_channel_open_request_x11_callback) (ssh_session session,
|
typedef ssh_channel (*ssh_channel_open_request_x11_callback) (ssh_session session,
|
||||||
const char * originator_address, int originator_port, void *userdata);
|
const char * originator_address, int originator_port, void *userdata);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The structure to replace libssh functions with appropriate callbacks.
|
* The structure to replace libssh functions with appropriate callbacks.
|
||||||
*/
|
*/
|
||||||
@ -137,7 +136,6 @@ struct ssh_callbacks_struct {
|
|||||||
/** This function will be called when an incoming X11 request is received.
|
/** This function will be called when an incoming X11 request is received.
|
||||||
*/
|
*/
|
||||||
ssh_channel_open_request_x11_callback channel_open_request_x11_function;
|
ssh_channel_open_request_x11_callback channel_open_request_x11_function;
|
||||||
|
|
||||||
};
|
};
|
||||||
typedef struct ssh_callbacks_struct *ssh_callbacks;
|
typedef struct ssh_callbacks_struct *ssh_callbacks;
|
||||||
|
|
||||||
@ -202,6 +200,49 @@ typedef int (*ssh_service_request_callback) (ssh_session session, const char *se
|
|||||||
*/
|
*/
|
||||||
typedef ssh_channel (*ssh_channel_open_request_session_callback) (ssh_session session, void *userdata);
|
typedef ssh_channel (*ssh_channel_open_request_session_callback) (ssh_session session, void *userdata);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @brief handle the beginning of a GSSAPI authentication, server side.
|
||||||
|
* @param session current session handler
|
||||||
|
* @param user the username of the client
|
||||||
|
* @param n_oid number of available oids
|
||||||
|
* @param oids OIDs provided by the client
|
||||||
|
* @returns an ssh_string containing the chosen OID, that's supported by both
|
||||||
|
* client and server.
|
||||||
|
* @warning It is not necessary to fill this callback in if libssh is linked
|
||||||
|
* with libgssapi.
|
||||||
|
*/
|
||||||
|
typedef ssh_string (*ssh_gssapi_select_oid_callback) (ssh_session session, const char *user,
|
||||||
|
int n_oid, ssh_string *oids, void *userdata);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @brief handle the negociation of a security context, server side.
|
||||||
|
* @param session current session handler
|
||||||
|
* @param[in] input_token input token provided by client
|
||||||
|
* @param[out] output_token output of the gssapi accept_sec_context method,
|
||||||
|
* NULL after completion.
|
||||||
|
* @returns SSH_OK if the token was generated correctly or accept_sec_context
|
||||||
|
* returned GSS_S_COMPLETE
|
||||||
|
* @returns SSH_ERROR in case of error
|
||||||
|
* @warning It is not necessary to fill this callback in if libssh is linked
|
||||||
|
* with libgssapi.
|
||||||
|
*/
|
||||||
|
typedef int (*ssh_gssapi_accept_sec_ctx_callback) (ssh_session session,
|
||||||
|
ssh_string input_token, ssh_string *output_token, void *userdata);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @brief Verify and authenticates a MIC, server side.
|
||||||
|
* @param session current session handler
|
||||||
|
* @param[in] mic input mic to be verified provided by client
|
||||||
|
* @param[in] mic_buffer buffer of data to be signed.
|
||||||
|
* @param[in] mic_buffer_size size of mic_buffer
|
||||||
|
* @returns SSH_OK if the MIC was authenticated correctly
|
||||||
|
* @returns SSH_ERROR in case of error
|
||||||
|
* @warning It is not necessary to fill this callback in if libssh is linked
|
||||||
|
* with libgssapi.
|
||||||
|
*/
|
||||||
|
typedef int (*ssh_gssapi_verify_mic_callback) (ssh_session session,
|
||||||
|
ssh_string mic, void *mic_buffer, size_t mic_buffer_size, void *userdata);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This structure can be used to implement a libssh server, with appropriate callbacks.
|
* This structure can be used to implement a libssh server, with appropriate callbacks.
|
||||||
*/
|
*/
|
||||||
@ -235,6 +276,15 @@ struct ssh_server_callbacks_struct {
|
|||||||
* the client
|
* the client
|
||||||
*/
|
*/
|
||||||
ssh_channel_open_request_session_callback channel_open_request_session_function;
|
ssh_channel_open_request_session_callback channel_open_request_session_function;
|
||||||
|
/** This function will be called when a new gssapi authentication is attempted.
|
||||||
|
*/
|
||||||
|
ssh_gssapi_select_oid_callback gssapi_select_oid_function;
|
||||||
|
/** This function will be called when a gssapi token comes in.
|
||||||
|
*/
|
||||||
|
ssh_gssapi_accept_sec_ctx_callback gssapi_accept_sec_ctx_function;
|
||||||
|
/* This function will be called when a MIC needs to be verified.
|
||||||
|
*/
|
||||||
|
ssh_gssapi_verify_mic_callback gssapi_verify_mic_function;
|
||||||
};
|
};
|
||||||
typedef struct ssh_server_callbacks_struct *ssh_server_callbacks;
|
typedef struct ssh_server_callbacks_struct *ssh_server_callbacks;
|
||||||
|
|
||||||
|
60
src/gssapi.c
60
src/gssapi.c
@ -144,7 +144,23 @@ int ssh_gssapi_handle_userauth(ssh_session session, const char *user, uint32_t n
|
|||||||
int present=0;
|
int present=0;
|
||||||
int oid_count=0;
|
int oid_count=0;
|
||||||
struct gss_OID_desc_struct oid;
|
struct gss_OID_desc_struct oid;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
if (ssh_callbacks_exists(session->server_callbacks, gssapi_select_oid_function)){
|
||||||
|
ssh_string oid_s = session->server_callbacks->gssapi_select_oid_function(session,
|
||||||
|
user, n_oid, oids,
|
||||||
|
session->server_callbacks->userdata);
|
||||||
|
if (oid_s != NULL){
|
||||||
|
if (ssh_gssapi_init(session) == SSH_ERROR)
|
||||||
|
return SSH_ERROR;
|
||||||
|
session->gssapi->state = SSH_GSSAPI_STATE_RCV_TOKEN;
|
||||||
|
rc = ssh_gssapi_send_response(session, oid_s);
|
||||||
|
ssh_string_free(oid_s);
|
||||||
|
return rc;
|
||||||
|
} else {
|
||||||
|
return ssh_auth_reply_default(session,0);
|
||||||
|
}
|
||||||
|
}
|
||||||
gss_create_empty_oid_set(&min_stat, &both_supported);
|
gss_create_empty_oid_set(&min_stat, &both_supported);
|
||||||
|
|
||||||
maj_stat = gss_indicate_mechs(&min_stat, &supported);
|
maj_stat = gss_indicate_mechs(&min_stat, &supported);
|
||||||
@ -273,6 +289,27 @@ SSH_PACKET_CALLBACK(ssh_packet_userauth_gssapi_token_server){
|
|||||||
ssh_set_error(session, SSH_REQUEST_DENIED, "ssh_packet_userauth_gssapi_token: invalid packet");
|
ssh_set_error(session, SSH_REQUEST_DENIED, "ssh_packet_userauth_gssapi_token: invalid packet");
|
||||||
return SSH_PACKET_USED;
|
return SSH_PACKET_USED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ssh_callbacks_exists(session->server_callbacks, gssapi_accept_sec_ctx_function)){
|
||||||
|
ssh_string out_token=NULL;
|
||||||
|
int rc = session->server_callbacks->gssapi_accept_sec_ctx_function(session,
|
||||||
|
token, &out_token, session->server_callbacks->userdata);
|
||||||
|
if (rc == SSH_ERROR){
|
||||||
|
ssh_auth_reply_default(session, 0);
|
||||||
|
ssh_gssapi_free(session);
|
||||||
|
session->gssapi=NULL;
|
||||||
|
return SSH_PACKET_USED;
|
||||||
|
}
|
||||||
|
if (ssh_string_len(out_token) != 0){
|
||||||
|
buffer_add_u8(session->out_buffer, SSH2_MSG_USERAUTH_GSSAPI_TOKEN);
|
||||||
|
buffer_add_ssh_string(session->out_buffer,out_token);
|
||||||
|
packet_send(session);
|
||||||
|
ssh_string_free(out_token);
|
||||||
|
} else {
|
||||||
|
session->gssapi->state = SSH_GSSAPI_STATE_RCV_MIC;
|
||||||
|
}
|
||||||
|
return SSH_PACKET_USED;
|
||||||
|
}
|
||||||
hexa = ssh_get_hexa(ssh_string_data(token),ssh_string_len(token));
|
hexa = ssh_get_hexa(ssh_string_data(token),ssh_string_len(token));
|
||||||
ssh_log(session, SSH_LOG_PACKET, "GSSAPI Token : %s",hexa);
|
ssh_log(session, SSH_LOG_PACKET, "GSSAPI Token : %s",hexa);
|
||||||
SAFE_FREE(hexa);
|
SAFE_FREE(hexa);
|
||||||
@ -346,7 +383,7 @@ SSH_PACKET_CALLBACK(ssh_packet_userauth_gssapi_mic){
|
|||||||
OM_uint32 maj_stat, min_stat;
|
OM_uint32 maj_stat, min_stat;
|
||||||
gss_buffer_desc mic_buf = GSS_C_EMPTY_BUFFER;
|
gss_buffer_desc mic_buf = GSS_C_EMPTY_BUFFER;
|
||||||
gss_buffer_desc mic_token_buf = GSS_C_EMPTY_BUFFER;
|
gss_buffer_desc mic_token_buf = GSS_C_EMPTY_BUFFER;
|
||||||
ssh_buffer mic_buffer;
|
ssh_buffer mic_buffer = NULL;
|
||||||
|
|
||||||
(void)user;
|
(void)user;
|
||||||
(void)type;
|
(void)type;
|
||||||
@ -367,6 +404,13 @@ SSH_PACKET_CALLBACK(ssh_packet_userauth_gssapi_mic){
|
|||||||
ssh_set_error_oom(session);
|
ssh_set_error_oom(session);
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
if (ssh_callbacks_exists(session->server_callbacks, gssapi_verify_mic_function)){
|
||||||
|
int rc = session->server_callbacks->gssapi_verify_mic_function(session, mic_token,
|
||||||
|
ssh_buffer_get_begin(mic_buffer), ssh_buffer_get_len(mic_buffer),
|
||||||
|
session->server_callbacks->userdata);
|
||||||
|
if (rc != SSH_OK)
|
||||||
|
goto error;
|
||||||
|
} else {
|
||||||
mic_buf.length = ssh_buffer_get_len(mic_buffer);
|
mic_buf.length = ssh_buffer_get_len(mic_buffer);
|
||||||
mic_buf.value = ssh_buffer_get_begin(mic_buffer);
|
mic_buf.value = ssh_buffer_get_begin(mic_buffer);
|
||||||
mic_token_buf.length = ssh_string_len(mic_token);
|
mic_token_buf.length = ssh_string_len(mic_token);
|
||||||
@ -375,10 +419,9 @@ SSH_PACKET_CALLBACK(ssh_packet_userauth_gssapi_mic){
|
|||||||
maj_stat = gss_verify_mic(&min_stat, session->gssapi->ctx, &mic_buf, &mic_token_buf, NULL);
|
maj_stat = gss_verify_mic(&min_stat, session->gssapi->ctx, &mic_buf, &mic_token_buf, NULL);
|
||||||
ssh_gssapi_log_error(session, 0, "verifying MIC", maj_stat);
|
ssh_gssapi_log_error(session, 0, "verifying MIC", maj_stat);
|
||||||
ssh_gssapi_log_error(session, 0, "verifying MIC (min stat)", min_stat);
|
ssh_gssapi_log_error(session, 0, "verifying MIC (min stat)", min_stat);
|
||||||
if (maj_stat == GSS_S_DEFECTIVE_TOKEN)
|
if (maj_stat == GSS_S_DEFECTIVE_TOKEN || GSS_ERROR(maj_stat))
|
||||||
|
|
||||||
if(GSS_ERROR(maj_stat))
|
|
||||||
goto error;
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
if (ssh_callbacks_exists(session->server_callbacks, auth_gssapi_mic_function)){
|
if (ssh_callbacks_exists(session->server_callbacks, auth_gssapi_mic_function)){
|
||||||
switch(session->server_callbacks->auth_gssapi_mic_function(session,
|
switch(session->server_callbacks->auth_gssapi_mic_function(session,
|
||||||
@ -395,12 +438,17 @@ SSH_PACKET_CALLBACK(ssh_packet_userauth_gssapi_mic){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//ssh_gssapi_free(session);
|
goto end;
|
||||||
return SSH_PACKET_USED;
|
|
||||||
|
|
||||||
error:
|
error:
|
||||||
ssh_auth_reply_default(session,0);
|
ssh_auth_reply_default(session,0);
|
||||||
|
|
||||||
|
end:
|
||||||
ssh_gssapi_free(session);
|
ssh_gssapi_free(session);
|
||||||
|
if(mic_buffer != NULL)
|
||||||
|
ssh_buffer_free(mic_buffer);
|
||||||
|
if(mic_token != NULL)
|
||||||
|
ssh_string_free(mic_token);
|
||||||
return SSH_PACKET_USED;
|
return SSH_PACKET_USED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Загрузка…
x
Ссылка в новой задаче
Block a user