From 5553dfaca3f1e2af50e9dcbdace04302dd5934d5 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Daniel=20Kou=C5=99il?= Date: Fri, 17 Feb 2012 23:15:41 +0000 Subject: [PATCH] Added implementation for edg_wll_gss_connect_name() --- org.glite.lbjp-common.gss/src/glite_gss.c | 153 +++++++++++++++++++----------- 1 file changed, 99 insertions(+), 54 deletions(-) diff --git a/org.glite.lbjp-common.gss/src/glite_gss.c b/org.glite.lbjp-common.gss/src/glite_gss.c index 10ecf5b..b7cf7c5 100644 --- a/org.glite.lbjp-common.gss/src/glite_gss.c +++ b/org.glite.lbjp-common.gss/src/glite_gss.c @@ -85,8 +85,7 @@ static void free_hostent(struct hostent *h); static int -try_conn_and_auth(edg_wll_GssCred cred, char const *hostname, - const char *service, gss_OID mech, +try_conn_and_auth(edg_wll_GssCred cred, gss_name_t target, gss_OID mech, char *addr, int addrtype, int port, struct timeval *timeout, edg_wll_GssConnection *connection, edg_wll_GssStatus* gss_code); @@ -827,11 +826,11 @@ end: #define _EXPIRED_ALERT_RETRY_DELAY 10 /* ms */ /** Create a socket and initiate secured connection. */ -int -edg_wll_gss_connect_ext(edg_wll_GssCred cred, char const *hostname, int port, - const char *service, gss_OID_set mechs, - struct timeval *timeout, edg_wll_GssConnection *connection, - edg_wll_GssStatus* gss_code) +static int +gss_connect(edg_wll_GssCred cred, char const *hostname, int port, + gss_name_t target, gss_OID_set mechs, + struct timeval *timeout, edg_wll_GssConnection *connection, + edg_wll_GssStatus* gss_code) { int ret; struct asyn_result ar; @@ -841,6 +840,8 @@ edg_wll_gss_connect_ext(edg_wll_GssCred cred, char const *hostname, int port, unsigned int j,k; int i; gss_OID mech; + gss_OID_set_desc my_mechs = {.count = 0, .elements = GSS_C_NO_OID}; + const char *mech_name; memset(connection, 0, sizeof(*connection)); for (j = 0; j< sizeof(addr_types)/sizeof(*addr_types); j++) { @@ -864,6 +865,19 @@ edg_wll_gss_connect_ext(edg_wll_GssCred cred, char const *hostname, int port, ret = EDG_WLL_GSS_ERROR_HERRNO; continue; } + + if (mechs == GSS_C_NO_OID_SET) { + mech_name = getenv("GLITE_GSS_MECH"); + if (mech_name == NULL) + mech_name = "GSI"; + + mech = get_oid(mech_name); + if (mech != GSS_C_NO_OID) { + my_mechs.elements = mech; + my_mechs.count = 1; + mechs = &my_mechs; + } + } i = 0; while (ar.ent->h_addr_list[i]) @@ -875,7 +889,7 @@ edg_wll_gss_connect_ext(edg_wll_GssCred cred, char const *hostname, int port, else mech = &mechs->elements[k]; - ret = try_conn_and_auth (cred, hostname, service, mech, + ret = try_conn_and_auth (cred, target, mech, ar.ent->h_addr_list[i], ar.ent->h_addrtype, port, timeout, connection, gss_code); if (ret == 0) @@ -898,6 +912,49 @@ edg_wll_gss_connect_ext(edg_wll_GssCred cred, char const *hostname, int port, return ret; } +int +edg_wll_gss_connect_ext(edg_wll_GssCred cred, char const *hostname, int port, + const char *service, gss_OID_set mechs, + struct timeval *timeout, edg_wll_GssConnection *connection, + edg_wll_GssStatus* gss_code) +{ + char *servername = NULL; + gss_name_t target = GSS_C_NO_NAME; + OM_uint32 maj_stat, min_stat; + gss_buffer_desc input_token = GSS_C_EMPTY_BUFFER; + int ret; + + asprintf(&servername, "%s@%s", + (service) ? service : "host", hostname); + if (servername == NULL) { + errno = ENOMEM; + return EDG_WLL_GSS_ERROR_ERRNO; + } + input_token.value = servername; + input_token.length = strlen(servername) + 1; + + maj_stat = gss_import_name(&min_stat, &input_token, + GSS_C_NT_HOSTBASED_SERVICE, &target); + if (GSS_ERROR(maj_stat)) { + if (gss_code) { + gss_code->major_status = maj_stat; + gss_code->minor_status = min_stat; + } + ret = EDG_WLL_GSS_ERROR_GSS; + goto end; + } + + ret = gss_connect(cred, hostname, port, target, mechs, + timeout, connection, gss_code); + +end: + if (target != GSS_C_NO_NAME) + gss_release_name(&min_stat, &target); + free(servername); + + return ret; +} + int edg_wll_gss_connect_name(edg_wll_GssCred cred, char const *hostname, @@ -908,7 +965,37 @@ edg_wll_gss_connect_name(edg_wll_GssCred cred, edg_wll_GssConnection *connection, edg_wll_GssStatus* gss_code) { - return ENOSYS; + gss_name_t target = GSS_C_NO_NAME; + OM_uint32 maj_stat, min_stat; + gss_buffer_desc input_token = GSS_C_EMPTY_BUFFER; + int ret; + + if (servername == NULL) { + errno = ENOSYS; + return EDG_WLL_GSS_ERROR_ERRNO; + } + input_token.value = (char *) servername; + input_token.length = strlen(servername) + 1; + + maj_stat = gss_import_name(&min_stat, &input_token, + GSS_C_NT_USER_NAME, &target); + if (GSS_ERROR(maj_stat)) { + if (gss_code) { + gss_code->major_status = maj_stat; + gss_code->minor_status = min_stat; + } + ret = EDG_WLL_GSS_ERROR_GSS; + goto end; + } + + ret = gss_connect(cred, hostname, port, target, mechs, + timeout, connection, gss_code); + +end: + if (target != GSS_C_NO_NAME) + gss_release_name(&min_stat, &target); + + return ret; } @@ -917,28 +1004,13 @@ edg_wll_gss_connect(edg_wll_GssCred cred, char const *hostname, int port, struct timeval *timeout, edg_wll_GssConnection *connection, edg_wll_GssStatus* gss_code) { - gss_OID_set_desc mechs = {.count = 0, .elements = GSS_C_NO_OID}; - gss_OID oid; - const char *mech; - - mech = getenv("GLITE_GSS_MECH"); - if (mech == NULL) - mech = "GSI"; - - oid = get_oid(mech); - if (oid != GSS_C_NO_OID) { - mechs.elements = oid; - mechs.count = 1; - } - return edg_wll_gss_connect_ext(cred, hostname, port, - NULL, &mechs, + NULL, NULL, timeout, connection, gss_code); } /* try connection and authentication for the given addr*/ -static int try_conn_and_auth (edg_wll_GssCred cred, char const *hostname, - const char *service, gss_OID mech, +static int try_conn_and_auth (edg_wll_GssCred cred, gss_name_t target, gss_OID mech, char *addr, int addrtype, int port, struct timeval *timeout, edg_wll_GssConnection *connection, edg_wll_GssStatus* gss_code) @@ -949,10 +1021,8 @@ static int try_conn_and_auth (edg_wll_GssCred cred, char const *hostname, int context_established = 0; gss_buffer_desc input_token = GSS_C_EMPTY_BUFFER; gss_buffer_desc output_token = GSS_C_EMPTY_BUFFER; - gss_name_t server = GSS_C_NO_NAME; gss_ctx_id_t context = GSS_C_NO_CONTEXT; gss_cred_id_t gss_cred = GSS_C_NO_CREDENTIAL; - char *servername = NULL; int retry = _EXPIRED_ALERT_RETRY_COUNT; maj_stat = min_stat = min_stat2 = req_flags = 0; @@ -966,27 +1036,6 @@ static int try_conn_and_auth (edg_wll_GssCred cred, char const *hostname, if (ret) return ret; - asprintf(&servername, "%s@%s", - (service) ? service : "host", hostname); - if (servername == NULL) { - errno = ENOMEM; - ret = EDG_WLL_GSS_ERROR_ERRNO; - goto end; - } - input_token.value = servername; - input_token.length = strlen(servername) + 1; - - maj_stat = gss_import_name(&min_stat, &input_token, - GSS_C_NT_HOSTBASED_SERVICE, &server); - if (GSS_ERROR(maj_stat)) { - ret = EDG_WLL_GSS_ERROR_GSS; - goto end; - } - - free(servername); - servername = NULL; - memset(&input_token, 0, sizeof(input_token)); - if (cred && cred->gss_cred) gss_cred = cred->gss_cred; @@ -995,7 +1044,7 @@ static int try_conn_and_auth (edg_wll_GssCred cred, char const *hostname, while (!context_established) { /* XXX verify ret_flags match what was requested */ maj_stat = gss_init_sec_context(&min_stat, gss_cred, &context, - server, mech, + target, mech, req_flags | GSS_C_MUTUAL_FLAG | GSS_C_CONF_FLAG, 0, GSS_C_NO_CHANNEL_BINDINGS, &input_token, NULL, &output_token, @@ -1075,10 +1124,6 @@ end: gss_code->major_status = maj_stat; gss_code->minor_status = min_stat; } - if (server != GSS_C_NO_NAME) - gss_release_name(&min_stat2, &server); - if (servername != NULL) - free(servername); if (ret) close(sock); -- 1.8.2.3