aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAris Adamantiadis <aris@0xbadc0de.be>2013-03-05 10:10:34 +0100
committerAndreas Schneider <asn@cryptomilk.org>2013-07-13 14:51:00 +0200
commit86ae29b30dc21aed0daa92006874e05b07a6ac99 (patch)
treeca8127eaa11bbd0076eec1cf3664a1b63ca5db53
parent65eccf19693dd2f6d4525062fdc04720f373af6f (diff)
downloadlibssh-86ae29b30dc21aed0daa92006874e05b07a6ac99.tar.gz
libssh-86ae29b30dc21aed0daa92006874e05b07a6ac99.tar.xz
libssh-86ae29b30dc21aed0daa92006874e05b07a6ac99.zip
gssapi: implement ticket delegation
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
-rw-r--r--include/libssh/libssh.h1
-rw-r--r--src/gssapi.c52
2 files changed, 39 insertions, 14 deletions
diff --git a/include/libssh/libssh.h b/include/libssh/libssh.h
index 880c9d6f..0ec64ab5 100644
--- a/include/libssh/libssh.h
+++ b/include/libssh/libssh.h
@@ -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 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 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_close(ssh_scp scp);
LIBSSH_API int ssh_scp_deny_request(ssh_scp scp, const char *reason);
diff --git a/src/gssapi.c b/src/gssapi.c
index 64e08ac3..6027f4c3 100644
--- a/src/gssapi.c
+++ b/src/gssapi.c
@@ -55,6 +55,7 @@ struct ssh_gssapi_struct{
struct {
gss_name_t server_name; /* identity of server */
gss_OID oid; /* mech being used for authentication */
+ gss_cred_id_t client_deleg_creds; /* delegated creds (const, not freeable) */
} client;
};
@@ -409,12 +410,25 @@ SSH_PACKET_CALLBACK(ssh_packet_userauth_gssapi_mic){
* @returns gssapi credentials handle.
* @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)
return NULL;
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 */
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){
oid = &supported->elements[i];
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),
0, NULL, &input_token, NULL, &output_token, NULL, NULL);
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);
+ ctx = GSS_C_NO_CONTEXT;
}
return SSH_OK;
@@ -645,6 +660,7 @@ SSH_PACKET_CALLBACK(ssh_packet_userauth_gssapi_response){
gss_OID_set tmp;
char *hexa;
ssh_string token;
+ gss_cred_id_t creds = GSS_C_NO_CREDENTIAL;
(void)type;
(void)user;
@@ -664,19 +680,23 @@ SSH_PACKET_CALLBACK(ssh_packet_userauth_gssapi_response){
ssh_set_error(session, SSH_FATAL, "Invalid OID");
return SSH_PACKET_USED;
}
- gss_create_empty_oid_set(&min_stat, &tmp);
- gss_add_oid_set_member(&min_stat, oid, &tmp);
- maj_stat = gss_acquire_cred(&min_stat, session->gssapi->client_name, 0,
- tmp, GSS_C_INITIATE,
- &session->gssapi->client_creds, NULL, NULL);
- gss_release_oid_set(&min_stat, &tmp);
- if (GSS_ERROR(maj_stat)){
- ssh_gssapi_log_error(session,SSH_LOG_WARNING,"Error acquiring credentials",maj_stat);
- 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_add_oid_set_member(&min_stat, oid, &tmp);
+ maj_stat = gss_acquire_cred(&min_stat, session->gssapi->client_name, 0,
+ tmp, GSS_C_INITIATE,
+ &session->gssapi->client_creds, NULL, NULL);
+ gss_release_oid_set(&min_stat, &tmp);
+ if (GSS_ERROR(maj_stat)){
+ ssh_gssapi_log_error(session,SSH_LOG_WARNING,"Error acquiring credentials",maj_stat);
+ return SSH_PACKET_USED;
+ }
}
/* prepare the first TOKEN response */
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),
0, NULL, &input_token, NULL, &output_token, NULL, NULL);
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;
OM_uint32 ret_flags=0;
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;
int deleg = 0;
//char *name;
@@ -758,9 +779,12 @@ SSH_PACKET_CALLBACK(ssh_packet_userauth_gssapi_token_client){
SAFE_FREE(hexa);
input_token.length = ssh_string_len(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,
- 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),
0, NULL, &input_token, NULL, &output_token, NULL, NULL);