int main(int argc, char *argv[]) { OM_uint32 minor, major; gss_cred_id_t impersonator_cred_handle = GSS_C_NO_CREDENTIAL; gss_cred_id_t user_cred_handle = GSS_C_NO_CREDENTIAL; gss_cred_id_t delegated_cred_handle = GSS_C_NO_CREDENTIAL; gss_name_t user = GSS_C_NO_NAME, target = GSS_C_NO_NAME; gss_OID_set mechs; if (argc < 2 || argc > 5) { fprintf(stderr, "Usage: %s [--spnego] [user] " "[proxy-target] [keytab]\n", argv[0]); fprintf(stderr, " proxy-target and keytab are optional\n"); exit(1); } if (strcmp(argv[1], "--spnego") == 0) { use_spnego++; argc--; argv++; } user = import_name(argv[1]); if (argc > 2 && strcmp(argv[2], "-")) target = import_name(argv[2]); if (argc > 3) { major = krb5_gss_register_acceptor_identity(argv[3]); check_gsserr("krb5_gss_register_acceptor_identity", major, 0); } /* Get default cred. */ mechs = use_spnego ? &mechset_spnego : &mechset_krb5; major = gss_acquire_cred(&minor, GSS_C_NO_NAME, GSS_C_INDEFINITE, mechs, GSS_C_BOTH, &impersonator_cred_handle, NULL, NULL); check_gsserr("gss_acquire_cred", major, minor); printf("Protocol transition tests follow\n"); printf("-----------------------------------\n\n"); test_greet_authz_data(&user); /* Get S4U2Self cred. */ major = gss_acquire_cred_impersonate_name(&minor, impersonator_cred_handle, user, GSS_C_INDEFINITE, mechs, GSS_C_INITIATE, &user_cred_handle, NULL, NULL); check_gsserr("gss_acquire_cred_impersonate_name", major, minor); init_accept_sec_context(user_cred_handle, impersonator_cred_handle, &delegated_cred_handle); printf("\n"); if (target != GSS_C_NO_NAME && delegated_cred_handle != GSS_C_NO_CREDENTIAL) { constrained_delegate(mechs, target, delegated_cred_handle, impersonator_cred_handle); } else if (target != GSS_C_NO_NAME) { fprintf(stderr, "Warning: no delegated cred handle returned\n\n"); fprintf(stderr, "Verify:\n\n"); fprintf(stderr, " - The TGT for the impersonating service is " "forwardable\n"); fprintf(stderr, " - The T2A4D flag set on the impersonating service's " "UAC\n"); fprintf(stderr, " - The user is not marked sensitive and cannot be " "delegated\n"); fprintf(stderr, "\n"); } (void)gss_release_name(&minor, &user); (void)gss_release_name(&minor, &target); (void)gss_release_cred(&minor, &delegated_cred_handle); (void)gss_release_cred(&minor, &impersonator_cred_handle); (void)gss_release_cred(&minor, &user_cred_handle); return 0; }
gss_client_response *authenticate_gss_server_init(const char *service, bool constrained_delegation, const char *username, gss_server_state *state) { OM_uint32 maj_stat; OM_uint32 min_stat; gss_buffer_desc name_token = GSS_C_EMPTY_BUFFER; int ret = AUTH_GSS_COMPLETE; gss_client_response *response = NULL; gss_cred_usage_t usage = GSS_C_ACCEPT; state->context = GSS_C_NO_CONTEXT; state->server_name = GSS_C_NO_NAME; state->client_name = GSS_C_NO_NAME; state->server_creds = GSS_C_NO_CREDENTIAL; state->client_creds = GSS_C_NO_CREDENTIAL; state->username = NULL; state->targetname = NULL; state->response = NULL; state->constrained_delegation = constrained_delegation; state->delegated_credentials_cache = NULL; // Server name may be empty which means we aren't going to create our own creds size_t service_len = strlen(service); if (service_len != 0) { // Import server name first name_token.length = strlen(service); name_token.value = (char *)service; maj_stat = gss_import_name(&min_stat, &name_token, GSS_C_NT_HOSTBASED_SERVICE, &state->server_name); if (GSS_ERROR(maj_stat)) { response = gss_error(__func__, "gss_import_name", maj_stat, min_stat); response->return_code = AUTH_GSS_ERROR; goto end; } if (state->constrained_delegation) { usage = GSS_C_BOTH; } // Get credentials maj_stat = gss_acquire_cred(&min_stat, state->server_name, GSS_C_INDEFINITE, GSS_C_NO_OID_SET, usage, &state->server_creds, NULL, NULL); if (GSS_ERROR(maj_stat)) { response = gss_error(__func__, "gss_acquire_cred", maj_stat, min_stat); response->return_code = AUTH_GSS_ERROR; goto end; } } // If a username was passed, perform the S4U2Self protocol transition to acquire // a credentials from that user as if we had done gss_accept_sec_context. // In this scenario, the passed username is assumed to be already authenticated // by some external mechanism, and we are here to "bootstrap" some gss credentials. // In authenticate_gss_server_step we will bypass the actual authentication step. if (username != NULL) { gss_name_t gss_username; name_token.length = strlen(username); name_token.value = (char *)username; maj_stat = gss_import_name(&min_stat, &name_token, GSS_C_NT_USER_NAME, &gss_username); if (GSS_ERROR(maj_stat)) { response = gss_error(__func__, "gss_import_name", maj_stat, min_stat); response->return_code = AUTH_GSS_ERROR; goto end; } maj_stat = gss_acquire_cred_impersonate_name(&min_stat, state->server_creds, gss_username, GSS_C_INDEFINITE, GSS_C_NO_OID_SET, GSS_C_INITIATE, &state->client_creds, NULL, NULL); if (GSS_ERROR(maj_stat)) { response = gss_error(__func__, "gss_acquire_cred_impersonate_name", maj_stat, min_stat); response->return_code = AUTH_GSS_ERROR; } gss_release_name(&min_stat, &gss_username); if (response != NULL) { goto end; } // because the username MAY be a "local" username, // we want get the canonical name from the acquired creds. maj_stat = gss_inquire_cred(&min_stat, state->client_creds, &state->client_name, NULL, NULL, NULL); if (GSS_ERROR(maj_stat)) { response = gss_error(__func__, "gss_inquire_cred", maj_stat, min_stat); response->return_code = AUTH_GSS_ERROR; goto end; } } end: if(response == NULL) { response = calloc(1, sizeof(gss_client_response)); if(response == NULL) die1("Memory allocation failed"); response->return_code = ret; } // Return the response return response; }
int main(int argc, const char *argv[]) { char buffer[MAX_RPC_SIZE]; uint32_t buflen; gss_cred_id_t impersonator_cred_handle = GSS_C_NO_CREDENTIAL; gss_cred_id_t user_cred_handle = GSS_C_NO_CREDENTIAL; gss_cred_id_t cred_handle = GSS_C_NO_CREDENTIAL; gss_ctx_id_t init_ctx = GSS_C_NO_CONTEXT; gss_ctx_id_t accept_ctx = GSS_C_NO_CONTEXT; gss_buffer_desc in_token = GSS_C_EMPTY_BUFFER; gss_buffer_desc out_token = GSS_C_EMPTY_BUFFER; gss_name_t user_name; gss_name_t target_name; gss_OID_set_desc oid_set = { 1, discard_const(gss_mech_krb5) }; uint32_t ret_maj; uint32_t ret_min; uint32_t time_rec; int ret = -1; if (argc != 3) return -1; ret = t_string_to_name(argv[1], &user_name, GSS_C_NT_USER_NAME); if (ret) { DEBUG("Failed to import user name from argv[1]\n"); ret = -1; goto done; } ret = t_string_to_name(argv[2], &target_name, GSS_C_NT_HOSTBASED_SERVICE); if (ret) { DEBUG("Failed to import server name from argv[2]\n"); ret = -1; goto done; } ret_maj = gss_acquire_cred(&ret_min, GSS_C_NO_NAME, GSS_C_INDEFINITE, &oid_set, GSS_C_BOTH, &impersonator_cred_handle, NULL, NULL); if (ret_maj != GSS_S_COMPLETE) { DEBUG("gss_acquire_cred() failed\n"); t_log_failure(GSS_C_NO_OID, ret_maj, ret_min); ret = -1; goto done; } ret_maj = gss_acquire_cred_impersonate_name(&ret_min, impersonator_cred_handle, user_name, GSS_C_INDEFINITE, &oid_set, GSS_C_INITIATE, &user_cred_handle, NULL, NULL); if (ret_maj != GSS_S_COMPLETE) { DEBUG("gss_acquire_cred_impersonate_name() failed\n"); t_log_failure(GSS_C_NO_OID, ret_maj, ret_min); ret = -1; goto done; } ret_maj = gss_init_sec_context(&ret_min, user_cred_handle, &init_ctx, target_name, GSS_C_NO_OID, GSS_C_MUTUAL_FLAG | GSS_C_REPLAY_FLAG, 0, GSS_C_NO_CHANNEL_BINDINGS, &in_token, NULL, &out_token, NULL, NULL); if (ret_maj != GSS_S_CONTINUE_NEEDED) { DEBUG("gss_init_sec_context() failed\n"); t_log_failure(GSS_C_NO_OID, ret_maj, ret_min); ret = -1; goto done; } /* We get stuff from stdin and spit it out on stderr */ if (!out_token.length) { DEBUG("No output token ?"); ret = -1; goto done; } /* in/out token inverted here intentionally */ ret_maj = gss_accept_sec_context(&ret_min, &accept_ctx, GSS_C_NO_CREDENTIAL, &out_token, GSS_C_NO_CHANNEL_BINDINGS, NULL, NULL, &in_token, NULL, NULL, NULL); if (ret_maj) { DEBUG("Error accepting context\n"); t_log_failure(GSS_C_NO_OID, ret_maj, ret_min); ret = -1; goto done; } if (!in_token.length) { DEBUG("No output token ?"); ret = -1; goto done; } gss_release_buffer(&ret_min, &out_token); ret_maj = gss_init_sec_context(&ret_min, user_cred_handle, &init_ctx, target_name, GSS_C_NO_OID, GSS_C_MUTUAL_FLAG | GSS_C_REPLAY_FLAG, 0, GSS_C_NO_CHANNEL_BINDINGS, &in_token, NULL, &out_token, NULL, NULL); if (ret_maj) { DEBUG("Error initializing context\n"); t_log_failure(GSS_C_NO_OID, ret_maj, ret_min); ret = -1; goto done; } ret = 0; done: gss_release_buffer(&ret_min, &in_token); gss_release_buffer(&ret_min, &out_token); gss_release_cred(&ret_min, &cred_handle); return ret; }
int main(int argc, char *argv[]) { OM_uint32 minor, major; gss_cred_id_t impersonator_cred_handle = GSS_C_NO_CREDENTIAL; gss_cred_id_t user_cred_handle = GSS_C_NO_CREDENTIAL; gss_cred_id_t delegated_cred_handle = GSS_C_NO_CREDENTIAL; gss_name_t user = GSS_C_NO_NAME, target = GSS_C_NO_NAME; gss_OID_set_desc mechs; gss_OID_set actual_mechs = GSS_C_NO_OID_SET; gss_buffer_desc buf; if (argc < 2 || argc > 5) { fprintf(stderr, "Usage: %s [--spnego] [user] " "[proxy-target] [keytab]\n", argv[0]); fprintf(stderr, " proxy-target and keytab are optional\n"); exit(1); } if (strcmp(argv[1], "--spnego") == 0) { use_spnego++; argc--; argv++; } buf.value = argv[1]; buf.length = strlen((char *)buf.value); major = gss_import_name(&minor, &buf, (gss_OID)GSS_KRB5_NT_PRINCIPAL_NAME, &user); if (GSS_ERROR(major)) { displayStatus("gss_import_name(user)", major, minor); goto out; } if (argc > 2 && strcmp(argv[2], "-")) { buf.value = argv[2]; buf.length = strlen((char *)buf.value); major = gss_import_name(&minor, &buf, (gss_OID)GSS_KRB5_NT_PRINCIPAL_NAME, &target); if (GSS_ERROR(major)) { displayStatus("gss_import_name(target)", major, minor); goto out; } } else { target = GSS_C_NO_NAME; } mechs.elements = use_spnego ? (gss_OID)&spnego_mech : (gss_OID)gss_mech_krb5; mechs.count = 1; major = getDefaultCred(&minor, argc > 3 ? argv[3] : NULL, &mechs, &impersonator_cred_handle); if (GSS_ERROR(major)) goto out; printf("Protocol transition tests follow\n"); printf("-----------------------------------\n\n"); /* get S4U2Self cred */ major = gss_acquire_cred_impersonate_name(&minor, impersonator_cred_handle, user, GSS_C_INDEFINITE, &mechs, GSS_C_INITIATE, &user_cred_handle, &actual_mechs, NULL); if (GSS_ERROR(major)) { displayStatus("gss_acquire_cred_impersonate_name", major, minor); goto out; } /* Try to store it in default ccache */ major = gss_store_cred(&minor, user_cred_handle, GSS_C_INITIATE, &mechs.elements[0], 1, 1, NULL, NULL); if (GSS_ERROR(major)) { displayStatus("gss_store_cred", major, minor); goto out; } major = initAcceptSecContext(&minor, user_cred_handle, impersonator_cred_handle, &delegated_cred_handle); if (GSS_ERROR(major)) goto out; printf("\n"); out: (void) gss_release_name(&minor, &user); (void) gss_release_name(&minor, &target); (void) gss_release_cred(&minor, &delegated_cred_handle); (void) gss_release_cred(&minor, &impersonator_cred_handle); (void) gss_release_cred(&minor, &user_cred_handle); (void) gss_release_oid_set(&minor, &actual_mechs); return GSS_ERROR(major) ? 1 : 0; }