1
0
mirror of https://git.libssh.org/projects/libssh.git synced 2025-08-08 19:02:06 +03:00

gssapi: implement ticket delegation

Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
This commit is contained in:
Aris Adamantiadis
2013-03-05 10:10:34 +01:00
committed by Andreas Schneider
parent 65eccf1969
commit 86ae29b30d
2 changed files with 39 additions and 14 deletions

View File

@@ -499,6 +499,7 @@ LIBSSH_API int ssh_pki_export_pubkey_file(const ssh_key key,
LIBSSH_API void ssh_print_hexa(const char *descr, const unsigned char *what, size_t len); LIBSSH_API void ssh_print_hexa(const char *descr, const unsigned char *what, size_t len);
LIBSSH_API int ssh_send_ignore (ssh_session session, const char *data); LIBSSH_API int ssh_send_ignore (ssh_session session, const char *data);
LIBSSH_API int ssh_send_debug (ssh_session session, const char *message, int always_display); LIBSSH_API int ssh_send_debug (ssh_session session, const char *message, int always_display);
LIBSSH_API void ssh_gssapi_set_creds(ssh_session session, const ssh_gssapi_creds creds);
LIBSSH_API int ssh_scp_accept_request(ssh_scp scp); LIBSSH_API int ssh_scp_accept_request(ssh_scp scp);
LIBSSH_API int ssh_scp_close(ssh_scp scp); LIBSSH_API int ssh_scp_close(ssh_scp scp);
LIBSSH_API int ssh_scp_deny_request(ssh_scp scp, const char *reason); LIBSSH_API int ssh_scp_deny_request(ssh_scp scp, const char *reason);

View File

@@ -55,6 +55,7 @@ struct ssh_gssapi_struct{
struct { struct {
gss_name_t server_name; /* identity of server */ gss_name_t server_name; /* identity of server */
gss_OID oid; /* mech being used for authentication */ gss_OID oid; /* mech being used for authentication */
gss_cred_id_t client_deleg_creds; /* delegated creds (const, not freeable) */
} client; } client;
}; };
@@ -409,12 +410,25 @@ SSH_PACKET_CALLBACK(ssh_packet_userauth_gssapi_mic){
* @returns gssapi credentials handle. * @returns gssapi credentials handle.
* @returns NULL if no forwardable token is available. * @returns NULL if no forwardable token is available.
*/ */
LIBSSH_API ssh_gssapi_creds ssh_gssapi_get_creds(ssh_session session){ ssh_gssapi_creds ssh_gssapi_get_creds(ssh_session session){
if (!session || !session->gssapi || session->gssapi->client_creds == GSS_C_NO_CREDENTIAL) if (!session || !session->gssapi || session->gssapi->client_creds == GSS_C_NO_CREDENTIAL)
return NULL; return NULL;
return (ssh_gssapi_creds)session->gssapi->client_creds; return (ssh_gssapi_creds)session->gssapi->client_creds;
} }
/** @brief Set the forwadable ticket to be given to the server for authentication.
* @param[in] creds gssapi credentials handle.
*/
void ssh_gssapi_set_creds(ssh_session session, const ssh_gssapi_creds creds){
if (!session)
return;
if(!session->gssapi)
ssh_gssapi_init(session);
if(!session->gssapi)
return;
session->gssapi->client.client_deleg_creds = (gss_cred_id_t)creds;
}
#endif /* SERVER */ #endif /* SERVER */
static int ssh_gssapi_send_auth_mic(ssh_session session, ssh_string *oid_set, int n_oid){ static int ssh_gssapi_send_auth_mic(ssh_session session, ssh_string *oid_set, int n_oid){
@@ -529,7 +543,7 @@ static int ssh_gssapi_match(ssh_session session, char *hostname, char *username,
for (i=0; i<supported->count; ++i){ for (i=0; i<supported->count; ++i){
oid = &supported->elements[i]; oid = &supported->elements[i];
maj_stat = gss_init_sec_context(&min_stat, maj_stat = gss_init_sec_context(&min_stat,
GSS_C_NO_CREDENTIAL, &ctx, host_name, oid, session->gssapi->client.client_deleg_creds, &ctx, host_name, oid,
GSS_C_MUTUAL_FLAG | GSS_C_INTEG_FLAG | (deleg ? GSS_C_DELEG_FLAG : 0), GSS_C_MUTUAL_FLAG | GSS_C_INTEG_FLAG | (deleg ? GSS_C_DELEG_FLAG : 0),
0, NULL, &input_token, NULL, &output_token, NULL, NULL); 0, NULL, &input_token, NULL, &output_token, NULL, NULL);
if (!GSS_ERROR(maj_stat)){ if (!GSS_ERROR(maj_stat)){
@@ -547,6 +561,7 @@ static int ssh_gssapi_match(ssh_session session, char *hostname, char *username,
} }
} }
gss_delete_sec_context(&min_stat,&ctx, &output_token); gss_delete_sec_context(&min_stat,&ctx, &output_token);
ctx = GSS_C_NO_CONTEXT;
} }
return SSH_OK; return SSH_OK;
@@ -645,6 +660,7 @@ SSH_PACKET_CALLBACK(ssh_packet_userauth_gssapi_response){
gss_OID_set tmp; gss_OID_set tmp;
char *hexa; char *hexa;
ssh_string token; ssh_string token;
gss_cred_id_t creds = GSS_C_NO_CREDENTIAL;
(void)type; (void)type;
(void)user; (void)user;
@@ -664,6 +680,9 @@ SSH_PACKET_CALLBACK(ssh_packet_userauth_gssapi_response){
ssh_set_error(session, SSH_FATAL, "Invalid OID"); ssh_set_error(session, SSH_FATAL, "Invalid OID");
return SSH_PACKET_USED; return SSH_PACKET_USED;
} }
if (session->gssapi->client.client_deleg_creds != GSS_C_NO_CREDENTIAL)
creds = session->gssapi->client.client_deleg_creds;
if (creds == GSS_C_NO_CREDENTIAL){
gss_create_empty_oid_set(&min_stat, &tmp); gss_create_empty_oid_set(&min_stat, &tmp);
gss_add_oid_set_member(&min_stat, oid, &tmp); gss_add_oid_set_member(&min_stat, oid, &tmp);
maj_stat = gss_acquire_cred(&min_stat, session->gssapi->client_name, 0, maj_stat = gss_acquire_cred(&min_stat, session->gssapi->client_name, 0,
@@ -674,9 +693,10 @@ SSH_PACKET_CALLBACK(ssh_packet_userauth_gssapi_response){
ssh_gssapi_log_error(session,SSH_LOG_WARNING,"Error acquiring credentials",maj_stat); ssh_gssapi_log_error(session,SSH_LOG_WARNING,"Error acquiring credentials",maj_stat);
return SSH_PACKET_USED; return SSH_PACKET_USED;
} }
}
/* prepare the first TOKEN response */ /* prepare the first TOKEN response */
maj_stat = gss_init_sec_context(&min_stat, maj_stat = gss_init_sec_context(&min_stat,
session->gssapi->client_creds, &session->gssapi->ctx, session->gssapi->client.server_name, oid, creds, &session->gssapi->ctx, session->gssapi->client.server_name, oid,
GSS_C_MUTUAL_FLAG | GSS_C_INTEG_FLAG | (deleg ? GSS_C_DELEG_FLAG : 0), GSS_C_MUTUAL_FLAG | GSS_C_INTEG_FLAG | (deleg ? GSS_C_DELEG_FLAG : 0),
0, NULL, &input_token, NULL, &output_token, NULL, NULL); 0, NULL, &input_token, NULL, &output_token, NULL, NULL);
if(GSS_ERROR(maj_stat)){ if(GSS_ERROR(maj_stat)){
@@ -736,6 +756,7 @@ SSH_PACKET_CALLBACK(ssh_packet_userauth_gssapi_token_client){
gss_name_t client_name = GSS_C_NO_NAME; gss_name_t client_name = GSS_C_NO_NAME;
OM_uint32 ret_flags=0; OM_uint32 ret_flags=0;
gss_cred_id_t deleg_cred = GSS_C_NO_CREDENTIAL; gss_cred_id_t deleg_cred = GSS_C_NO_CREDENTIAL;
gss_cred_id_t creds = GSS_C_NO_CREDENTIAL;
gss_channel_bindings_t input_bindings=GSS_C_NO_CHANNEL_BINDINGS; gss_channel_bindings_t input_bindings=GSS_C_NO_CHANNEL_BINDINGS;
int deleg = 0; int deleg = 0;
//char *name; //char *name;
@@ -758,9 +779,12 @@ SSH_PACKET_CALLBACK(ssh_packet_userauth_gssapi_token_client){
SAFE_FREE(hexa); SAFE_FREE(hexa);
input_token.length = ssh_string_len(token); input_token.length = ssh_string_len(token);
input_token.value = ssh_string_data(token); input_token.value = ssh_string_data(token);
if (session->gssapi->client.client_deleg_creds != GSS_C_NO_CREDENTIAL)
creds = session->gssapi->client.client_deleg_creds;
else
creds = session->gssapi->client_creds;
maj_stat = gss_init_sec_context(&min_stat, maj_stat = gss_init_sec_context(&min_stat,
session->gssapi->client_creds, &session->gssapi->ctx, session->gssapi->client.server_name, session->gssapi->client.oid, creds, &session->gssapi->ctx, session->gssapi->client.server_name, session->gssapi->client.oid,
GSS_C_MUTUAL_FLAG | GSS_C_INTEG_FLAG | (deleg ? GSS_C_DELEG_FLAG : 0), GSS_C_MUTUAL_FLAG | GSS_C_INTEG_FLAG | (deleg ? GSS_C_DELEG_FLAG : 0),
0, NULL, &input_token, NULL, &output_token, NULL, NULL); 0, NULL, &input_token, NULL, &output_token, NULL, NULL);