/* * Check whether the request satisfies the conditions for generating a referral * TGT. The caller checks whether the hostname component looks like a FQDN. */ static krb5_boolean is_referral_req(kdc_realm_t *kdc_active_realm, krb5_kdc_req *request) { krb5_boolean ret = FALSE; char *stype = NULL; char *ref_services = kdc_active_realm->realm_host_based_services; char *nonref_services = kdc_active_realm->realm_no_host_referral; if (!(request->kdc_options & KDC_OPT_CANONICALIZE)) return FALSE; if (request->kdc_options & KDC_OPT_ENC_TKT_IN_SKEY) return FALSE; if (krb5_princ_size(kdc_context, request->server) != 2) return FALSE; stype = data2string(krb5_princ_component(kdc_context, request->server, 0)); if (stype == NULL) return FALSE; switch (krb5_princ_type(kdc_context, request->server)) { case KRB5_NT_UNKNOWN: /* Allow referrals for NT-UNKNOWN principals, if configured. */ if (kdc_active_realm->realm_host_based_services != NULL) { if (!krb5_match_config_pattern(ref_services, stype) && !krb5_match_config_pattern(ref_services, KRB5_CONF_ASTERISK)) goto cleanup; } else goto cleanup; /* FALLTHROUGH */ case KRB5_NT_SRV_HST: case KRB5_NT_SRV_INST: /* Deny referrals for specific service types, if configured. */ if (kdc_active_realm->realm_no_host_referral != NULL) { if (krb5_match_config_pattern(nonref_services, stype)) goto cleanup; if (krb5_match_config_pattern(nonref_services, KRB5_CONF_ASTERISK)) goto cleanup; } ret = TRUE; break; default: goto cleanup; } cleanup: free(stype); return ret; }
BehaviorTreeNode* CNormalMode::askQuestionToPlayerSequence(int player, int round) { std::string playerCam = (std::string)"player"+data2string(player+1)+(std::string)"cam1"; BehaviorTreeInternalNode* sequence; (sequence = new ParallelNode(FAIL_ON_ONE, SUCCEED_ON_ALL)) ->addChild((new SequentialNode()) ->addChild(new CPlayDialogue(_questions[player+(numPlayers()*round)]->getId())) ->addChild(new CAnimateAvatarNode(_players[player], "LEGS_NERVOUS", "TORSO_JUMP", "HEAD_HARD_SWINGING")) ->addChild(new CSetButtonStatus(_bPlayerName[player], CButton::HIGHLIGHTED)) ->addChild(new CCameraNode(playerCam)) // Camara a jugador 1 ->addChild(new CSetQuestionInHud(_questions[player+(numPlayers()*round)])) ->addChild(new CUiComponentVisibility(_game->questionsGui(), true)) // Muestra interfaz pregunta ->addChild(new CFadeUiNode(_fQuestionsGui, 0.001f)) // Hacemos un fade para mostrar el interfaz ) //->addChild(new CTimerButtonNode(_bClock, _timePerQuestion)) ; return sequence; }
/* * Find a remote realm TGS principal for an unknown host-based service * principal. */ static krb5_int32 find_referral_tgs(kdc_realm_t *kdc_active_realm, krb5_kdc_req *request, krb5_principal *krbtgt_princ) { krb5_error_code retval = KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN; char **realms = NULL, *hostname = NULL; krb5_data srealm = request->server->realm; if (!is_referral_req(kdc_active_realm, request)) goto cleanup; hostname = data2string(krb5_princ_component(kdc_context, request->server, 1)); if (hostname == NULL) { retval = ENOMEM; goto cleanup; } /* If the hostname doesn't contain a '.', it's not a FQDN. */ if (strchr(hostname, '.') == NULL) goto cleanup; retval = krb5_get_host_realm(kdc_context, hostname, &realms); if (retval) { /* no match found */ kdc_err(kdc_context, retval, "unable to find realm of host"); goto cleanup; } /* Don't return a referral to the empty realm or the service realm. */ if (realms == NULL || realms[0] == NULL || *realms[0] == '\0' || data_eq_string(srealm, realms[0])) { retval = KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN; goto cleanup; } retval = krb5_build_principal(kdc_context, krbtgt_princ, srealm.length, srealm.data, "krbtgt", realms[0], (char *)0); cleanup: krb5_free_host_realm(kdc_context, realms); free(hostname); return retval; }
/* * Check whether the request satisfies the conditions for generating a referral * TGT. The caller checks whether the hostname component looks like a FQDN. */ static krb5_boolean is_referral_req(kdc_realm_t *kdc_active_realm, krb5_kdc_req *request) { krb5_boolean ret = FALSE; char *stype = NULL; char *hostbased = kdc_active_realm->realm_hostbased; char *no_referral = kdc_active_realm->realm_no_referral; if (!(request->kdc_options & KDC_OPT_CANONICALIZE)) return FALSE; if (request->kdc_options & KDC_OPT_ENC_TKT_IN_SKEY) return FALSE; if (krb5_princ_size(kdc_context, request->server) != 2) return FALSE; stype = data2string(krb5_princ_component(kdc_context, request->server, 0)); if (stype == NULL) return FALSE; switch (krb5_princ_type(kdc_context, request->server)) { case KRB5_NT_UNKNOWN: /* Allow referrals for NT-UNKNOWN principals, if configured. */ if (!in_list(hostbased, stype) && !in_list(hostbased, "*")) goto cleanup; /* FALLTHROUGH */ case KRB5_NT_SRV_HST: case KRB5_NT_SRV_INST: /* Deny referrals for specific service types, if configured. */ if (in_list(no_referral, stype) || in_list(no_referral, "*")) goto cleanup; ret = TRUE; break; default: goto cleanup; } cleanup: free(stype); return ret; }
int ril_request_get_sim_status(void *data, size_t size, RIL_Token token) { void *card_status_data; size_t card_status_size; #if RIL_VERSION >= 6 RIL_CardStatus_v6 *card_status; #else RIL_CardStatus *card_status; #endif struct ril_request *request; int rc; rc = ril_radio_state_check(RADIO_STATE_SIM_NOT_READY); if (rc < 0) return RIL_REQUEST_UNHANDLED; request = ril_request_find_request_status(RIL_REQUEST_GET_SIM_STATUS, RIL_REQUEST_HANDLED); if (request != NULL) return RIL_REQUEST_UNHANDLED; card_status_size = ril_request_data_size_get(RIL_REQUEST_GET_SIM_STATUS); card_status_data = ril_request_data_get(RIL_REQUEST_GET_SIM_STATUS); #if RIL_VERSION >= 6 if (card_status_data != NULL && card_status_size >= sizeof(RIL_CardStatus_v6)) { card_status = (RIL_CardStatus_v6 *) ril_request_data_get(RIL_REQUEST_GET_SIM_STATUS); #else if (card_status_data != NULL && card_status_size >= sizeof(RIL_CardStatus)) { card_status = (RIL_CardStatus *) ril_request_data_get(RIL_REQUEST_GET_SIM_STATUS); #endif ril_request_complete(token, RIL_E_SUCCESS, card_status_data, card_status_size); free(card_status_data); return RIL_REQUEST_COMPLETED; } else { rc = ipc_fmt_send(ipc_fmt_request_seq(token), IPC_SEC_PIN_STATUS, IPC_TYPE_GET, NULL, 0); if (rc < 0) { ril_request_complete(token, RIL_E_GENERIC_FAILURE, NULL, 0); return RIL_REQUEST_COMPLETED; } return RIL_REQUEST_HANDLED; } } int ipc_sec_phone_lock(struct ipc_message *message) { struct ipc_sec_phone_lock_response_data *data; int active; if (message == NULL || message->data == NULL || message->size < sizeof(struct ipc_sec_phone_lock_response_data)) return -1; if (message->type != IPC_TYPE_RESP || !ipc_seq_valid(message->aseq)) return 0; data = (struct ipc_sec_phone_lock_response_data *) message->data; active = !!data->active; ril_request_complete(ipc_fmt_request_token(message->aseq), RIL_E_SUCCESS, &active, sizeof(active)); return 0; } int ril_request_query_facility_lock(void *data, size_t size, RIL_Token token) { struct ipc_sec_phone_lock_request_get_data request_data; char **values = NULL; int rc; if (data == NULL || size < 4 * sizeof(char *)) goto error; rc = ril_radio_state_check(RADIO_STATE_SIM_READY); if (rc < 0) return RIL_REQUEST_UNHANDLED; values = (char **) data; request_data.facility_type = ril2ipc_sec_facility_type(values[0]); if (request_data.facility_type == 0) goto error; strings_array_free(values, size); values = NULL; rc = ipc_fmt_send(ipc_fmt_request_seq(token), IPC_SEC_PHONE_LOCK, IPC_TYPE_GET, (void *) &request_data, sizeof(request_data)); if (rc < 0) goto error; rc = RIL_REQUEST_HANDLED; goto complete; error: if (values != NULL) strings_array_free(values, size); ril_request_complete(token, RIL_E_GENERIC_FAILURE, NULL, 0); rc = RIL_REQUEST_COMPLETED; complete: return rc; } int ipc_sec_callback(struct ipc_message *message) { struct ipc_sec_lock_infomation_request_data request_data; struct ipc_gen_phone_res_data *data; struct ril_request *request = NULL; void *request_complete_data; size_t request_complete_size; unsigned char facility_type; char **values; int retry_count; int rc; if (message == NULL || message->data == NULL || message->size < sizeof(struct ipc_gen_phone_res_data)) return -1; data = (struct ipc_gen_phone_res_data *) message->data; request = ril_request_find_token(ipc_fmt_request_token(message->aseq)); if (request == NULL) goto error; if (request->request == RIL_REQUEST_ENTER_SIM_PIN || request->request == RIL_REQUEST_CHANGE_SIM_PIN) { // Grab the count of remaining tries before completing the request ril_request_data_set_uniq(request->request, (void *) data, sizeof(struct ipc_gen_phone_res_data)); rc = ipc_sec_lock_infomation_setup(&request_data, IPC_SEC_PIN_TYPE_PIN1); if (rc < 0) { ril_request_data_free(request->request); goto error; } rc = ipc_fmt_send(message->aseq, IPC_SEC_LOCK_INFOMATION, IPC_TYPE_GET, (void *) &request_data, sizeof(request_data)); if (rc < 0) { ril_request_data_free(request->request); goto error; } } else if (request->request == RIL_REQUEST_ENTER_SIM_PIN2 || request->request == RIL_REQUEST_CHANGE_SIM_PIN2) { // Grab the count of remaining tries before completing the request ril_request_data_set_uniq(request->request, (void *) data, sizeof(struct ipc_gen_phone_res_data)); rc = ipc_sec_lock_infomation_setup(&request_data, IPC_SEC_PIN_TYPE_PIN2); if (rc < 0) { ril_request_data_free(request->request); goto error; } rc = ipc_fmt_send(message->aseq, IPC_SEC_LOCK_INFOMATION, IPC_TYPE_GET, (void *) &request_data, sizeof(request_data)); if (rc < 0) { ril_request_data_free(request->request); goto error; } } else if (request->request == RIL_REQUEST_SET_FACILITY_LOCK) { values = (char **) request->data; request_complete_size = ril_request_data_size_get(RIL_REQUEST_SET_FACILITY_LOCK); request_complete_data = ril_request_data_get(RIL_REQUEST_SET_FACILITY_LOCK); rc = ipc_gen_phone_res_check(data); if (request_complete_data != NULL && request_complete_size > 0 && rc >= 0) { rc = ipc_gen_phone_res_expect_callback(message->aseq, IPC_SEC_PHONE_LOCK, ipc_sec_callback); if (rc < 0) { strings_array_free(values, request->size); goto error; } rc = ipc_fmt_send(message->aseq, IPC_SEC_PHONE_LOCK, IPC_TYPE_SET, request_complete_data, request_complete_size); if (rc < 0) { strings_array_free(values, request->size); goto error; } } else { // When FD facility PIN2 unlock failed, ask the count of remaining tries directly facility_type = ril2ipc_sec_facility_type(values[0]); strings_array_free(values, request->size); // Grab the count of remaining tries before completing the request ril_request_data_set_uniq(RIL_REQUEST_SET_FACILITY_LOCK, (void *) data, sizeof(struct ipc_gen_phone_res_data)); if (facility_type == IPC_SEC_FACILITY_TYPE_FD) { rc = ipc_sec_lock_infomation_setup(&request_data, IPC_SEC_PIN_TYPE_PIN2); if (rc < 0) { ril_request_data_free(request->request); goto error; } } else { rc = ipc_sec_lock_infomation_setup(&request_data, IPC_SEC_PIN_TYPE_PIN1); if (rc < 0) { ril_request_data_free(request->request); goto error; } } rc = ipc_fmt_send(message->aseq, IPC_SEC_LOCK_INFOMATION, IPC_TYPE_GET, (void *) &request_data, sizeof(request_data)); if (rc < 0) { ril_request_data_free(request->request); goto error; } } } else if (request->request == RIL_REQUEST_SIM_IO) { request_complete_size = ril_request_data_size_get(RIL_REQUEST_SIM_IO); request_complete_data = ril_request_data_get(RIL_REQUEST_SIM_IO); rc = ipc_gen_phone_res_check(data); if (rc < 0) { ril_request_complete(request->token, RIL_E_SIM_PIN2, NULL, 0); goto complete; } if (request_complete_data != NULL && request_complete_size > 0) { rc = ipc_fmt_send(message->aseq, IPC_SEC_RSIM_ACCESS, IPC_TYPE_GET, request_complete_data, request_complete_size); if (rc < 0) goto error; } else { goto error; } } else { retry_count = -1; rc = ipc_gen_phone_res_check(data); if (rc < 0) { if ((data->code & 0xff) == 0x10) { RIL_LOGE("%s: Wrong password", __func__); ril_request_complete(ipc_fmt_request_token(message->aseq), RIL_E_PASSWORD_INCORRECT, &retry_count, sizeof(retry_count)); } else if ((data->code & 0xff) == 0x0c) { RIL_LOGE("%s: Wrong password and no attempts left", __func__); retry_count = 0; ril_request_complete(ipc_fmt_request_token(message->aseq), RIL_E_PASSWORD_INCORRECT, &retry_count, sizeof(retry_count)); } else { ril_request_complete(ipc_fmt_request_token(message->aseq), RIL_E_GENERIC_FAILURE, &retry_count, sizeof(retry_count)); } } else { ril_request_complete(ipc_fmt_request_token(message->aseq), RIL_E_SUCCESS, &retry_count, sizeof(retry_count)); } } if (request->request == RIL_REQUEST_ENTER_SIM_PUK || request->request == RIL_REQUEST_ENTER_SIM_PUK2) ril_request_unsolicited(RIL_UNSOL_RESPONSE_SIM_STATUS_CHANGED, NULL, 0); goto complete; error: if (request != NULL) ril_request_complete(request->token, RIL_E_GENERIC_FAILURE, NULL, 0); complete: return 0; } int ril_request_set_facility_lock(void *data, size_t size, RIL_Token token) { struct ipc_sec_phone_lock_request_set_data request_data; struct ipc_sec_pin_status_request_data pin_request_data; struct ril_request *request; unsigned char facility_type; unsigned char active; char **values = NULL; int rc; if (data == NULL || size < 4 * sizeof(char *)) goto error; rc = ril_radio_state_check(RADIO_STATE_SIM_READY); if (rc < 0) return RIL_REQUEST_UNHANDLED; request = ril_request_find_request_status(RIL_REQUEST_SET_FACILITY_LOCK, RIL_REQUEST_HANDLED); if (request != NULL) return RIL_REQUEST_UNHANDLED; values = (char **) data; facility_type = ril2ipc_sec_facility_type(values[0]); if (facility_type == 0) goto error; active = values[1][0] == '1'; rc = ipc_sec_phone_lock_request_set_setup(&request_data, facility_type, active, values[2]); if (rc < 0) goto error; if (facility_type == IPC_SEC_FACILITY_TYPE_FD) { // FD facility requires PIN2 unlock first rc = ipc_sec_pin_status_setup(&pin_request_data, IPC_SEC_PIN_TYPE_PIN2, values[2], NULL); if (rc < 0) goto error; ril_request_data_set_uniq(RIL_REQUEST_SET_FACILITY_LOCK, &request_data, sizeof(request_data)); rc = ipc_gen_phone_res_expect_callback(ipc_fmt_request_seq(token), IPC_SEC_PIN_STATUS, ipc_sec_callback); if (rc < 0) { ril_request_data_free(RIL_REQUEST_SET_FACILITY_LOCK); goto error; } rc = ipc_fmt_send(ipc_fmt_request_seq(token), IPC_SEC_PIN_STATUS, IPC_TYPE_SET, (void *) &pin_request_data, sizeof(pin_request_data)); if (rc < 0) { ril_request_data_free(RIL_REQUEST_SET_FACILITY_LOCK); goto error; } rc = RIL_REQUEST_HANDLED; goto complete; } rc = ipc_gen_phone_res_expect_callback(ipc_fmt_request_seq(token), IPC_SEC_PHONE_LOCK, ipc_sec_callback); if (rc < 0) goto error; rc = ipc_fmt_send(ipc_fmt_request_seq(token), IPC_SEC_PHONE_LOCK, IPC_TYPE_SET, (void *) &request_data, sizeof(request_data)); if (rc < 0) goto error; rc = RIL_REQUEST_HANDLED; goto complete; error: if (values != NULL) strings_array_free(values, size); ril_request_complete(token, RIL_E_GENERIC_FAILURE, NULL, 0); rc = RIL_REQUEST_COMPLETED; complete: return rc; } int ril_request_enter_sim_pin(void *data, size_t size, RIL_Token token) { struct ipc_sec_pin_status_request_data request_data; struct ril_request *request; char **values = NULL; int rc; if (data == NULL || size < 2 * sizeof(char *) || ril_data == NULL) goto error; rc = ril_radio_state_check(RADIO_STATE_SIM_NOT_READY); if (rc < 0) return RIL_REQUEST_UNHANDLED; request = ril_request_find_request_status(RIL_REQUEST_ENTER_SIM_PIN, RIL_REQUEST_HANDLED); if (request != NULL) return RIL_REQUEST_UNHANDLED; values = (char **) data; if (values[0] == NULL) goto error; if (ril_data->sim_pin != NULL) free(ril_data->sim_pin); ril_data->sim_pin = strdup(values[0]); rc = ipc_sec_pin_status_setup(&request_data, IPC_SEC_PIN_TYPE_PIN1, values[0], NULL); if (rc < 0) goto error; strings_array_free(values, size); values = NULL; rc = ipc_gen_phone_res_expect_callback(ipc_fmt_request_seq(token), IPC_SEC_PIN_STATUS, ipc_sec_callback); if (rc < 0) goto error; rc = ipc_fmt_send(ipc_fmt_request_seq(token), IPC_SEC_PIN_STATUS, IPC_TYPE_SET, (void *) &request_data, sizeof(request_data)); if (rc < 0) goto error; rc = RIL_REQUEST_HANDLED; goto complete; error: if (values != NULL) strings_array_free(values, size); ril_request_complete(token, RIL_E_GENERIC_FAILURE, NULL, 0); rc = RIL_REQUEST_COMPLETED; complete: return rc; } int ril_request_enter_sim_puk(void *data, size_t size, RIL_Token token) { struct ipc_sec_pin_status_request_data request_data; struct ril_request *request; char **values = NULL; int rc; if (data == NULL || size < 2 * sizeof(char *)) goto error; rc = ril_radio_state_check(RADIO_STATE_SIM_NOT_READY); if (rc < 0) return RIL_REQUEST_UNHANDLED; request = ril_request_find_request_status(RIL_REQUEST_ENTER_SIM_PUK, RIL_REQUEST_HANDLED); if (request != NULL) return RIL_REQUEST_UNHANDLED; values = (char **) data; rc = ipc_sec_pin_status_setup(&request_data, IPC_SEC_PIN_TYPE_PIN1, values[1], values[0]); if (rc < 0) goto error; strings_array_free(values, size); values = NULL; rc = ipc_gen_phone_res_expect_callback(ipc_fmt_request_seq(token), IPC_SEC_PIN_STATUS, ipc_sec_callback); if (rc < 0) goto error; rc = ipc_fmt_send(ipc_fmt_request_seq(token), IPC_SEC_PIN_STATUS, IPC_TYPE_SET, (void *) &request_data, sizeof(request_data)); if (rc < 0) goto error; rc = RIL_REQUEST_HANDLED; goto complete; error: if (values != NULL) strings_array_free(values, size); ril_request_complete(token, RIL_E_GENERIC_FAILURE, NULL, 0); rc = RIL_REQUEST_COMPLETED; complete: return rc; } int ril_request_enter_sim_pin2(void *data, size_t size, RIL_Token token) { struct ipc_sec_pin_status_request_data request_data; struct ril_request *request; char **values = NULL; int rc; if (data == NULL || size < 2 * sizeof(char *)) goto error; rc = ril_radio_state_check(RADIO_STATE_SIM_NOT_READY); if (rc < 0) return RIL_REQUEST_UNHANDLED; request = ril_request_find_request_status(RIL_REQUEST_ENTER_SIM_PIN2, RIL_REQUEST_HANDLED); if (request != NULL) return RIL_REQUEST_UNHANDLED; values = (char **) data; rc = ipc_sec_pin_status_setup(&request_data, IPC_SEC_PIN_TYPE_PIN2, values[0], NULL); if (rc < 0) goto error; strings_array_free(values, size); values = NULL; rc = ipc_gen_phone_res_expect_callback(ipc_fmt_request_seq(token), IPC_SEC_PIN_STATUS, ipc_sec_callback); if (rc < 0) goto error; rc = ipc_fmt_send(ipc_fmt_request_seq(token), IPC_SEC_PIN_STATUS, IPC_TYPE_SET, (void *) &request_data, sizeof(request_data)); if (rc < 0) goto error; rc = RIL_REQUEST_HANDLED; goto complete; error: if (values != NULL) strings_array_free(values, size); ril_request_complete(token, RIL_E_GENERIC_FAILURE, NULL, 0); rc = RIL_REQUEST_COMPLETED; complete: return rc; } int ril_request_enter_sim_puk2(void *data, size_t size, RIL_Token token) { struct ipc_sec_pin_status_request_data request_data; struct ril_request *request; char **values = NULL; int rc; if (data == NULL || size < 2 * sizeof(char *)) goto error; rc = ril_radio_state_check(RADIO_STATE_SIM_NOT_READY); if (rc < 0) return RIL_REQUEST_UNHANDLED; request = ril_request_find_request_status(RIL_REQUEST_ENTER_SIM_PUK2, RIL_REQUEST_HANDLED); if (request != NULL) return RIL_REQUEST_UNHANDLED; values = (char **) data; rc = ipc_sec_pin_status_setup(&request_data, IPC_SEC_PIN_TYPE_PIN2, values[1], values[0]); if (rc < 0) goto error; strings_array_free(values, size); values = NULL; rc = ipc_gen_phone_res_expect_callback(ipc_fmt_request_seq(token), IPC_SEC_PIN_STATUS, ipc_sec_callback); if (rc < 0) goto error; rc = ipc_fmt_send(ipc_fmt_request_seq(token), IPC_SEC_PIN_STATUS, IPC_TYPE_SET, (void *) &request_data, sizeof(request_data)); if (rc < 0) goto error; rc = RIL_REQUEST_HANDLED; goto complete; error: if (values != NULL) strings_array_free(values, size); ril_request_complete(token, RIL_E_GENERIC_FAILURE, NULL, 0); rc = RIL_REQUEST_COMPLETED; complete: return rc; } int ril_request_change_sim_pin(void *data, size_t size, RIL_Token token) { struct ipc_sec_change_locking_pw_data request_data; struct ril_request *request; char **values = NULL; int rc; if (data == NULL || size < 3 * sizeof(char *)) goto error; request = ril_request_find_request_status(RIL_REQUEST_CHANGE_SIM_PIN, RIL_REQUEST_HANDLED); if (request != NULL) return RIL_REQUEST_UNHANDLED; rc = ril_radio_state_check(RADIO_STATE_SIM_READY); if (rc < 0) return RIL_REQUEST_UNHANDLED; values = (char **) data; rc = ipc_sec_change_locking_pw_setup(&request_data, IPC_SEC_FACILITY_TYPE_SC, values[0], values[1]); if (rc < 0) goto error; strings_array_free(values, size); values = NULL; rc = ipc_gen_phone_res_expect_callback(ipc_fmt_request_seq(token), IPC_SEC_CHANGE_LOCKING_PW, ipc_sec_callback); if (rc < 0) goto error; rc = ipc_fmt_send(ipc_fmt_request_seq(token), IPC_SEC_CHANGE_LOCKING_PW, IPC_TYPE_SET, (void *) &request_data, sizeof(request_data)); if (rc < 0) goto error; rc = RIL_REQUEST_HANDLED; goto complete; error: if (values != NULL) strings_array_free(values, size); ril_request_complete(token, RIL_E_GENERIC_FAILURE, NULL, 0); rc = RIL_REQUEST_COMPLETED; complete: return rc; } int ril_request_change_sim_pin2(void *data, size_t size, RIL_Token token) { struct ipc_sec_change_locking_pw_data request_data; struct ril_request *request; char **values = NULL; int rc; if (data == NULL || size < 3 * sizeof(char *)) goto error; request = ril_request_find_request_status(RIL_REQUEST_CHANGE_SIM_PIN, RIL_REQUEST_HANDLED); if (request != NULL) return RIL_REQUEST_UNHANDLED; rc = ril_radio_state_check(RADIO_STATE_SIM_READY); if (rc < 0) return RIL_REQUEST_UNHANDLED; values = (char **) data; rc = ipc_sec_change_locking_pw_setup(&request_data, IPC_SEC_FACILITY_TYPE_FD, values[0], values[1]); if (rc < 0) goto error; strings_array_free(values, size); values = NULL; rc = ipc_gen_phone_res_expect_callback(ipc_fmt_request_seq(token), IPC_SEC_CHANGE_LOCKING_PW, ipc_sec_callback); if (rc < 0) goto error; rc = ipc_fmt_send(ipc_fmt_request_seq(token), IPC_SEC_CHANGE_LOCKING_PW, IPC_TYPE_SET, (void *) &request_data, sizeof(request_data)); if (rc < 0) goto error; rc = RIL_REQUEST_HANDLED; goto complete; error: if (values != NULL) strings_array_free(values, size); ril_request_complete(token, RIL_E_GENERIC_FAILURE, NULL, 0); rc = RIL_REQUEST_COMPLETED; complete: return rc; } int ipc_sec_rsim_access(struct ipc_message *message) { struct ipc_sec_rsim_access_response_header *header; struct ipc_sec_rsim_access_usim_response_header *usim_header; struct sim_file_response sim_file_response; struct ril_request *request; struct ril_client *client; struct ipc_fmt_data *ipc_fmt_data; RIL_SIM_IO_Response response; #if RIL_VERSION >= 6 RIL_SIM_IO_v6 *sim_io; #else RIL_SIM_IO *sim_io; #endif unsigned char *p; unsigned int offset; unsigned int i; void *data; size_t size; if (message == NULL || message->data == NULL || message->size < sizeof(struct ipc_sec_rsim_access_response_header)) return -1; client = ril_client_find_id(RIL_CLIENT_IPC_FMT); if (client == NULL || client->data == NULL) return 0; if (message->type != IPC_TYPE_RESP || !ipc_seq_valid(message->aseq)) return 0; ipc_fmt_data = (struct ipc_fmt_data *) client->data; header = (struct ipc_sec_rsim_access_response_header *) message->data; size = ipc_sec_rsim_access_size_extract(message->data, message->size); data = ipc_sec_rsim_access_extract(message->data, message->size); request = ril_request_find_token(ipc_fmt_request_token(message->aseq)); #if RIL_VERSION >= 6 if (request == NULL || request->data == NULL || request->size < sizeof(RIL_SIM_IO_v6)) #else if (request == NULL || request->data == NULL || request->size < sizeof(RIL_SIM_IO)) #endif return 0; #if RIL_VERSION >= 6 sim_io = (RIL_SIM_IO_v6 *) request->data; #else sim_io = (RIL_SIM_IO *) request->data; #endif memset(&response, 0, sizeof(response)); response.sw1 = header->sw1; response.sw2 = header->sw2; switch (sim_io->command) { case SIM_COMMAND_READ_BINARY: case SIM_COMMAND_READ_RECORD: if (header->length == 0) break; response.simResponse = data2string(data, header->length); break; case SIM_COMMAND_GET_RESPONSE: if (header->length == 0) break; if (ipc_fmt_data->sim_icc_type_data.type == 0x01) { response.simResponse = data2string(data, header->length); break; } if (header->length < sizeof(struct ipc_sec_rsim_access_usim_response_header)) break; usim_header = (struct ipc_sec_rsim_access_usim_response_header *) data; memset(&sim_file_response, 0, sizeof(sim_file_response)); offset = sizeof(struct ipc_sec_rsim_access_usim_response_header) + usim_header->offset; if (offset > header->length) break; offset = usim_header->offset - 2; p = (unsigned char *) usim_header + offset; sim_file_response.file_id[0] = p[0]; sim_file_response.file_id[1] = p[1]; offset = header->length - 2; p = (unsigned char *) usim_header; while (offset > 2) { if (p[offset] == 0x88) { offset -= 2; break; } offset--; } if (offset <= 2) break; p = (unsigned char *) usim_header + offset; sim_file_response.file_size[0] = p[0]; sim_file_response.file_size[1] = p[1]; // Fallback to EF sim_file_response.file_type = SIM_FILE_TYPE_EF; for (i = 0; i < sim_file_ids_count; i++) { if (sim_io->fileid == sim_file_ids[i].file_id) { sim_file_response.file_type = sim_file_ids[i].type; break; } } sim_file_response.access_condition[0] = 0x00; sim_file_response.access_condition[1] = 0xff; sim_file_response.access_condition[2] = 0xff; sim_file_response.file_status = 0x01; sim_file_response.file_length = 0x02; switch (usim_header->file_structure) { case IPC_SEC_RSIM_FILE_STRUCTURE_TRANSPARENT: sim_file_response.file_structure = SIM_FILE_STRUCTURE_TRANSPARENT; break; case IPC_SEC_RSIM_FILE_STRUCTURE_LINEAR_FIXED: default: sim_file_response.file_structure = SIM_FILE_STRUCTURE_LINEAR_FIXED; break; } sim_file_response.record_length = usim_header->length; response.simResponse = data2string((void *) &sim_file_response, sizeof(sim_file_response)); break; case SIM_COMMAND_UPDATE_BINARY: case SIM_COMMAND_UPDATE_RECORD: case SIM_COMMAND_SEEK: default: response.simResponse = NULL; break; } ril_request_complete(ipc_fmt_request_token(message->aseq), RIL_E_SUCCESS, (void *) &response, sizeof(response)); if (response.simResponse != NULL) free(response.simResponse); return 0; } int ril_request_sim_io(void *data, size_t size, RIL_Token token) { struct ipc_sec_rsim_access_request_header request_header; struct ipc_sec_pin_status_request_data pin_request_data; struct ril_request *request; #if RIL_VERSION >= 6 RIL_SIM_IO_v6 *sim_io = NULL; #else RIL_SIM_IO *sim_io = NULL; #endif void *sim_io_data = NULL; size_t sim_io_size = 0; void *request_data = NULL; size_t request_size = 0; int pin_request = 0; int rc; #if RIL_VERSION >= 6 if (data == NULL || size < sizeof(RIL_SIM_IO_v6)) #else if (data == NULL || size < sizeof(RIL_SIM_IO)) #endif goto error; rc = ril_radio_state_check(RADIO_STATE_SIM_READY); if (rc < 0) return RIL_REQUEST_UNHANDLED; request = ril_request_find_request_status(RIL_REQUEST_SIM_IO, RIL_REQUEST_HANDLED); if (request != NULL) return RIL_REQUEST_UNHANDLED; #if RIL_VERSION >= 6 sim_io = (RIL_SIM_IO_v6 *) data; #else sim_io = (RIL_SIM_IO *) data; #endif if (sim_io->data != NULL) { sim_io_size = string2data_size(sim_io->data); if (sim_io_size == 0) goto error; sim_io_data = string2data(sim_io->data); if (sim_io_data == NULL) goto error; } if (sim_io->pin2 != NULL) { // PIN2 unlock first pin_request = 1; rc = ipc_sec_pin_status_setup(&pin_request_data, IPC_SEC_PIN_TYPE_PIN2, sim_io->pin2, NULL); if (rc < 0) goto error; } if (sim_io->path != NULL) free(sim_io->path); if (sim_io->data != NULL) free(sim_io->data); if (sim_io->pin2 != NULL) free(sim_io->pin2); #if RIL_VERSION >= 6 if (sim_io->aidPtr != NULL) free(sim_io->aidPtr); #endif memset(&request_header, 0, sizeof(request_header)); request_header.command = sim_io->command; request_header.file_id = sim_io->fileid; request_header.p1 = sim_io->p1; request_header.p2 = sim_io->p2; request_header.p3 = sim_io->p3; sim_io = NULL; request_size = ipc_sec_rsim_access_size_setup(&request_header, sim_io_data, sim_io_size); if (request_size == 0) goto error; request_data = ipc_sec_rsim_access_setup(&request_header, sim_io_data, sim_io_size); if (request_data == NULL) goto error; if (pin_request) { // PIN2 unlock first ril_request_data_set_uniq(RIL_REQUEST_SIM_IO, request_data, request_size); rc = ipc_gen_phone_res_expect_callback(ipc_fmt_request_seq(token), IPC_SEC_PIN_STATUS, ipc_sec_callback); if (rc < 0) { ril_request_data_free(RIL_REQUEST_SIM_IO); goto error; } rc = ipc_fmt_send(ipc_fmt_request_seq(token), IPC_SEC_PIN_STATUS, IPC_TYPE_SET, (void *) &pin_request_data, sizeof(pin_request_data)); if (rc < 0) { ril_request_data_free(RIL_REQUEST_SIM_IO); goto error; } rc = RIL_REQUEST_HANDLED; goto complete; } rc = ipc_fmt_send(ipc_fmt_request_seq(token), IPC_SEC_RSIM_ACCESS, IPC_TYPE_GET, request_data, request_size); if (rc < 0) goto error; rc = RIL_REQUEST_HANDLED; goto complete; error: if (sim_io != NULL) { if (sim_io->path != NULL) free(sim_io->path); if (sim_io->data != NULL) free(sim_io->data); if (sim_io->pin2 != NULL) free(sim_io->pin2); #if RIL_VERSION >= 6 if (sim_io->aidPtr != NULL) free(sim_io->aidPtr); #endif } ril_request_complete(token, RIL_E_GENERIC_FAILURE, NULL, 0); rc = RIL_REQUEST_COMPLETED; complete: if (sim_io_data != NULL && sim_io_size > 0) free(sim_io_data); if (request_data != NULL && request_size > 0) free(request_data); return rc; } int ipc_sec_sim_icc_type(struct ipc_message *message) { struct ipc_sec_sim_icc_type_data *data; struct ril_client *client; struct ipc_fmt_data *ipc_fmt_data; if (message == NULL || message->data == NULL || message->size < sizeof(struct ipc_sec_sim_icc_type_data)) return -1; client = ril_client_find_id(RIL_CLIENT_IPC_FMT); if (client == NULL || client->data == NULL) return 0; ipc_fmt_data = (struct ipc_fmt_data *) client->data; data = (struct ipc_sec_sim_icc_type_data *) message->data; if (ipc_fmt_data->sim_icc_type_data.type != data->type) ipc_fmt_data->sim_icc_type_data.type = data->type; return 0; } int ipc_sec_lock_infomation(struct ipc_message *message) { struct ipc_sec_lock_infomation_response_data *data; struct ipc_gen_phone_res_data *gen_phone_res; int requests[] = { RIL_REQUEST_ENTER_SIM_PIN, RIL_REQUEST_CHANGE_SIM_PIN, RIL_REQUEST_ENTER_SIM_PIN2, RIL_REQUEST_CHANGE_SIM_PIN2, RIL_REQUEST_SET_FACILITY_LOCK }; void *gen_phone_res_data = NULL; size_t gen_phone_res_size = 0; int retry_count; unsigned int count; unsigned int i; int rc; if (message == NULL || message->data == NULL || message->size < sizeof(struct ipc_sec_lock_infomation_response_data)) return -1; rc = ril_radio_state_check(RADIO_STATE_SIM_NOT_READY); if (rc < 0) return 0; if (message->type != IPC_TYPE_RESP || !ipc_seq_valid(message->aseq)) return 0; data = (struct ipc_sec_lock_infomation_response_data *) message->data; if (data->type != IPC_SEC_PIN_TYPE_PIN1 && data->type != IPC_SEC_PIN_TYPE_PIN2) return 0; count = sizeof(requests) / sizeof(int); for (i = 0; i < count; i++) { gen_phone_res_size = ril_request_data_size_get(requests[i]); if (gen_phone_res_size < sizeof(struct ipc_gen_phone_res_data)) continue; gen_phone_res_data = ril_request_data_get(requests[i]); if (gen_phone_res_data == NULL) continue; break; } if (gen_phone_res_data == NULL || gen_phone_res_size < sizeof(struct ipc_gen_phone_res_data)) return 0; gen_phone_res = (struct ipc_gen_phone_res_data *) gen_phone_res_data; retry_count = data->retry_count; rc = ipc_gen_phone_res_check(gen_phone_res); if (rc < 0) { if ((gen_phone_res->code & 0xff) == 0x10) { RIL_LOGE("%s: Wrong password and %d attempts left", __func__, retry_count); ril_request_complete(ipc_fmt_request_token(message->aseq), RIL_E_PASSWORD_INCORRECT, &retry_count, sizeof(retry_count)); } else if ((gen_phone_res->code & 0xff) == 0x0c) { RIL_LOGE("%s: Wrong password and no attempts left", __func__); retry_count = 0; ril_request_complete(ipc_fmt_request_token(message->aseq), RIL_E_PASSWORD_INCORRECT, &retry_count, sizeof(retry_count)); } else { ril_request_complete(ipc_fmt_request_token(message->aseq), RIL_E_GENERIC_FAILURE, &retry_count, sizeof(retry_count)); } } else { ril_request_complete(ipc_fmt_request_token(message->aseq), RIL_E_SUCCESS, &retry_count, sizeof(retry_count)); } free(gen_phone_res_data); return 0; }
krb5_error_code add_to_transited(krb5_data *tgt_trans, krb5_data *new_trans, krb5_principal tgs, krb5_principal client, krb5_principal server) { krb5_error_code retval; char *realm; char *trans; char *otrans, *otrans_ptr; size_t bufsize; /* The following are for stepping through the transited field */ char prev[MAX_REALM_LN]; char next[MAX_REALM_LN]; char current[MAX_REALM_LN]; char exp[MAX_REALM_LN]; /* Expanded current realm name */ int i; int clst, nlst; /* count of last character in current and next */ int pl, pl1; /* prefix length */ int added; /* TRUE = new realm has been added */ realm = data2string(krb5_princ_realm(kdc_context, tgs)); if (realm == NULL) return(ENOMEM); otrans = data2string(tgt_trans); if (otrans == NULL) { free(realm); return(ENOMEM); } /* Keep track of start so we can free */ otrans_ptr = otrans; /* +1 for null, +1 for extra comma which may be added between +1 for potential space when leading slash in realm */ bufsize = strlen(realm) + strlen(otrans) + 3; if (bufsize > MAX_REALM_LN) bufsize = MAX_REALM_LN; if (!(trans = (char *) malloc(bufsize))) { retval = ENOMEM; goto fail; } if (new_trans->data) free(new_trans->data); new_trans->data = trans; new_trans->length = 0; trans[0] = '\0'; /* For the purpose of appending, the realm preceding the first */ /* realm in the transited field is considered the null realm */ prev[0] = '\0'; /* read field into current */ for (i = 0; *otrans != '\0';) { if (*otrans == '\\') { if (*(++otrans) == '\0') break; else continue; } if (*otrans == ',') { otrans++; break; } current[i++] = *otrans++; if (i >= MAX_REALM_LN) { retval = KRB5KRB_AP_ERR_ILL_CR_TKT; goto fail; } } current[i] = '\0'; added = (krb5_princ_realm(kdc_context, client)->length == strlen(realm) && !strncmp(krb5_princ_realm(kdc_context, client)->data, realm, strlen(realm))) || (krb5_princ_realm(kdc_context, server)->length == strlen(realm) && !strncmp(krb5_princ_realm(kdc_context, server)->data, realm, strlen(realm))); while (current[0]) { /* figure out expanded form of current name */ clst = strlen(current) - 1; if (current[0] == ' ') { strncpy(exp, current+1, sizeof(exp) - 1); exp[sizeof(exp) - 1] = '\0'; } else if ((current[0] == '/') && (prev[0] == '/')) { strncpy(exp, prev, sizeof(exp) - 1); exp[sizeof(exp) - 1] = '\0'; if (strlen(exp) + strlen(current) + 1 >= MAX_REALM_LN) { retval = KRB5KRB_AP_ERR_ILL_CR_TKT; goto fail; } strncat(exp, current, sizeof(exp) - 1 - strlen(exp)); } else if (current[clst] == '.') { strncpy(exp, current, sizeof(exp) - 1); exp[sizeof(exp) - 1] = '\0'; if (strlen(exp) + strlen(prev) + 1 >= MAX_REALM_LN) { retval = KRB5KRB_AP_ERR_ILL_CR_TKT; goto fail; } strncat(exp, prev, sizeof(exp) - 1 - strlen(exp)); } else { strncpy(exp, current, sizeof(exp) - 1); exp[sizeof(exp) - 1] = '\0'; } /* read field into next */ for (i = 0; *otrans != '\0';) { if (*otrans == '\\') { if (*(++otrans) == '\0') break; else continue; } if (*otrans == ',') { otrans++; break; } next[i++] = *otrans++; if (i >= MAX_REALM_LN) { retval = KRB5KRB_AP_ERR_ILL_CR_TKT; goto fail; } } next[i] = '\0'; nlst = i - 1; if (!strcmp(exp, realm)) added = TRUE; /* If we still have to insert the new realm */ if (!added) { /* Is the next field compressed? If not, and if the new */ /* realm is a subrealm of the current realm, compress */ /* the new realm, and insert immediately following the */ /* current one. Note that we can not do this if the next*/ /* field is already compressed since it would mess up */ /* what has already been done. In most cases, this is */ /* not a problem because the realm to be added will be a */ /* subrealm of the next field too, and we will catch */ /* it in a future iteration. */ /* Note that the second test here is an unsigned comparison, so the first half (or a cast) is also required. */ assert(nlst < 0 || nlst < (int)sizeof(next)); if ((nlst < 0 || next[nlst] != '.') && (next[0] != '/') && (pl = subrealm(exp, realm))) { added = TRUE; current[sizeof(current) - 1] = '\0'; if (strlen(current) + (pl>0?pl:-pl) + 2 >= MAX_REALM_LN) { retval = KRB5KRB_AP_ERR_ILL_CR_TKT; goto fail; } strncat(current, ",", sizeof(current) - 1 - strlen(current)); if (pl > 0) { strncat(current, realm, (unsigned) pl); } else { strncat(current, realm+strlen(realm)+pl, (unsigned) (-pl)); } } /* Whether or not the next field is compressed, if the */ /* realm to be added is a superrealm of the current realm,*/ /* then the current realm can be compressed. First the */ /* realm to be added must be compressed relative to the */ /* previous realm (if possible), and then the current */ /* realm compressed relative to the new realm. Note that */ /* if the realm to be added is also a superrealm of the */ /* previous realm, it would have been added earlier, and */ /* we would not reach this step this time around. */ else if ((pl = subrealm(realm, exp))) { added = TRUE; current[0] = '\0'; if ((pl1 = subrealm(prev,realm))) { if (strlen(current) + (pl1>0?pl1:-pl1) + 1 >= MAX_REALM_LN) { retval = KRB5KRB_AP_ERR_ILL_CR_TKT; goto fail; } if (pl1 > 0) { strncat(current, realm, (unsigned) pl1); } else { strncat(current, realm+strlen(realm)+pl1, (unsigned) (-pl1)); } } else { /* If not a subrealm */ if ((realm[0] == '/') && prev[0]) { if (strlen(current) + 2 >= MAX_REALM_LN) { retval = KRB5KRB_AP_ERR_ILL_CR_TKT; goto fail; } strncat(current, " ", sizeof(current) - 1 - strlen(current)); current[sizeof(current) - 1] = '\0'; } if (strlen(current) + strlen(realm) + 1 >= MAX_REALM_LN) { retval = KRB5KRB_AP_ERR_ILL_CR_TKT; goto fail; } strncat(current, realm, sizeof(current) - 1 - strlen(current)); current[sizeof(current) - 1] = '\0'; } if (strlen(current) + (pl>0?pl:-pl) + 2 >= MAX_REALM_LN) { retval = KRB5KRB_AP_ERR_ILL_CR_TKT; goto fail; } strncat(current,",", sizeof(current) - 1 - strlen(current)); current[sizeof(current) - 1] = '\0'; if (pl > 0) { strncat(current, exp, (unsigned) pl); } else { strncat(current, exp+strlen(exp)+pl, (unsigned)(-pl)); } } } if (new_trans->length != 0) { if (strlcat(trans, ",", bufsize) >= bufsize) { retval = KRB5KRB_AP_ERR_ILL_CR_TKT; goto fail; } } if (strlcat(trans, current, bufsize) >= bufsize) { retval = KRB5KRB_AP_ERR_ILL_CR_TKT; goto fail; } new_trans->length = strlen(trans); strncpy(prev, exp, sizeof(prev) - 1); prev[sizeof(prev) - 1] = '\0'; strncpy(current, next, sizeof(current) - 1); current[sizeof(current) - 1] = '\0'; } if (!added) { if (new_trans->length != 0) { if (strlcat(trans, ",", bufsize) >= bufsize) { retval = KRB5KRB_AP_ERR_ILL_CR_TKT; goto fail; } } if((realm[0] == '/') && trans[0]) { if (strlcat(trans, " ", bufsize) >= bufsize) { retval = KRB5KRB_AP_ERR_ILL_CR_TKT; goto fail; } } if (strlcat(trans, realm, bufsize) >= bufsize) { retval = KRB5KRB_AP_ERR_ILL_CR_TKT; goto fail; } new_trans->length = strlen(trans); } retval = 0; fail: free(realm); free(otrans_ptr); return (retval); }