[layer23] Fixed and completed SIM's PIN handling
Use VTY to handle PIN: enable sim pin 1 xxxx sim change-pin 1 xxxx yyyy sim disable-pin 1 xxxx sim enable-pin 1 xxxx sim unlock-pin 1 uuuuuuuu yyyy 1 = mobile station "1" xxxx = current PIN yyyy = new PIN uuuuuuuu = unlock key (PuK)
This commit is contained in:
parent
0856c8a6a5
commit
5e1cf12d67
|
@ -174,8 +174,8 @@ struct gsm_sim {
|
|||
int job_state;
|
||||
|
||||
uint8_t reset;
|
||||
uint8_t pin1[8], pin2[8];
|
||||
uint8_t pin1_len, pin2_len;
|
||||
uint8_t chv1_remain, chv2_remain;
|
||||
uint8_t unblk1_remain, unblk2_remain;
|
||||
};
|
||||
|
||||
struct sim_hdr {
|
||||
|
@ -215,16 +215,16 @@ struct gsm1111_response_mfdf_gsm {
|
|||
uint8_t rfu1;
|
||||
uint8_t chv1_remain:4,
|
||||
rfu2:3,
|
||||
chv1_init;
|
||||
chv1_init:1;
|
||||
uint8_t unblk1_remain:4,
|
||||
rfu3:3,
|
||||
unblk1_init;
|
||||
unblk1_init:1;
|
||||
uint8_t chv2_remain:4,
|
||||
rfu4:3,
|
||||
chv2_init;
|
||||
chv2_init:1;
|
||||
uint8_t unblk2_remain:4,
|
||||
rfu5:3,
|
||||
unblk2_init;
|
||||
unblk2_init:1;
|
||||
uint8_t more_data[0];
|
||||
} __attribute__ ((packed));
|
||||
|
||||
|
|
|
@ -81,7 +81,8 @@ int gsm_subscr_init(struct osmocom_ms *ms);
|
|||
int gsm_subscr_exit(struct osmocom_ms *ms);
|
||||
int gsm_subscr_testcard(struct osmocom_ms *ms, uint16_t mcc, uint16_t mnc);
|
||||
int gsm_subscr_simcard(struct osmocom_ms *ms);
|
||||
void gsm_subscr_sim_pin(struct osmocom_ms *ms, char *pin);
|
||||
void gsm_subscr_sim_pin(struct osmocom_ms *ms, char *pin1, char *pin2,
|
||||
int8_t mode);
|
||||
int gsm_subscr_write_loci(struct osmocom_ms *ms);
|
||||
int gsm_subscr_generate_kc(struct osmocom_ms *ms, uint8_t key_seq,
|
||||
uint8_t *rand, uint8_t no_sim);
|
||||
|
|
|
@ -411,7 +411,7 @@ static int gsm1111_tx_change_chv(struct osmocom_ms *ms, uint8_t chv_no,
|
|||
buffer[1] = GSM1111_INST_CHANGE_CHV;
|
||||
buffer[2] = 0x00;
|
||||
buffer[3] = chv_no;
|
||||
buffer[4] = 8;
|
||||
buffer[4] = 16;
|
||||
for (i = 0; i < 8; i++) {
|
||||
if (i < length_old)
|
||||
buffer[5 + i] = chv_old[i];
|
||||
|
@ -485,7 +485,7 @@ static int gsm1111_tx_unblock_chv(struct osmocom_ms *ms, uint8_t chv_no,
|
|||
buffer[1] = GSM1111_INST_UNBLOCK_CHV;
|
||||
buffer[2] = 0x00;
|
||||
buffer[3] = (chv_no == 1) ? 0 : chv_no;
|
||||
buffer[4] = 8;
|
||||
buffer[4] = 16;
|
||||
for (i = 0; i < 8; i++) {
|
||||
if (i < length_unblk)
|
||||
buffer[5 + i] = chv_unblk[i];
|
||||
|
@ -654,8 +654,8 @@ static int gsm1111_tx_terminal_response(struct osmocom_ms *ms, uint8_t *data,
|
|||
static int sim_process_job(struct osmocom_ms *ms)
|
||||
{
|
||||
struct gsm_sim *sim = &ms->sim;
|
||||
uint8_t *payload;
|
||||
uint16_t payload_len;
|
||||
uint8_t *payload, *payload2;
|
||||
uint16_t payload_len, payload_len2;
|
||||
struct sim_hdr *sh;
|
||||
uint8_t cause;
|
||||
int i;
|
||||
|
@ -734,82 +734,98 @@ static int sim_process_job(struct osmocom_ms *ms)
|
|||
sim->job_state = SIM_JST_RUN_GSM_ALGO;
|
||||
return gsm1111_tx_run_gsm_algo(ms, payload);
|
||||
case SIM_JOB_PIN1_UNLOCK:
|
||||
payload_len = strlen((char *)payload);
|
||||
if (payload_len < 4 || payload_len > 8) {
|
||||
LOGP(DSIM, LOGL_ERROR, "key not in range 4..8\n");
|
||||
break;
|
||||
}
|
||||
sim->job_state = SIM_JST_PIN1_UNLOCK;
|
||||
memcpy(sim->pin1, payload, payload_len);
|
||||
sim->pin1_len = payload_len;
|
||||
return gsm1111_tx_verify_chv(ms, 0x01, payload, payload_len);
|
||||
case SIM_JOB_PIN2_UNLOCK:
|
||||
payload_len = strlen((char *)payload);
|
||||
if (payload_len < 4 || payload_len > 8) {
|
||||
LOGP(DSIM, LOGL_ERROR, "key not in range 4..8\n");
|
||||
break;
|
||||
}
|
||||
sim->job_state = SIM_JST_PIN2_UNLOCK;
|
||||
memcpy(sim->pin2, payload, payload_len);
|
||||
sim->pin2_len = payload_len;
|
||||
return gsm1111_tx_verify_chv(ms, 0x02, payload, payload_len);
|
||||
case SIM_JOB_PIN1_CHANGE:
|
||||
if (!sim->pin1_len) {
|
||||
LOGP(DSIM, LOGL_ERROR, "no pin set\n");
|
||||
payload_len = strlen((char *)payload);
|
||||
payload2 = payload + payload_len + 1;
|
||||
payload_len2 = strlen((char *)payload2);
|
||||
if (payload_len < 4 || payload_len > 8) {
|
||||
LOGP(DSIM, LOGL_ERROR, "key1 not in range 4..8\n");
|
||||
break;
|
||||
}
|
||||
if (payload_len < 4 || payload_len > 8 || !sim->pin1_len) {
|
||||
LOGP(DSIM, LOGL_ERROR, "key not in range 4..8\n");
|
||||
if (payload_len2 < 4 || payload_len2 > 8) {
|
||||
LOGP(DSIM, LOGL_ERROR, "key2 not in range 4..8\n");
|
||||
break;
|
||||
}
|
||||
sim->job_state = SIM_JST_PIN1_CHANGE;
|
||||
return gsm1111_tx_change_chv(ms, 0x01, sim->pin1, sim->pin1_len,
|
||||
payload, payload_len);
|
||||
return gsm1111_tx_change_chv(ms, 0x01, payload, payload_len,
|
||||
payload2, payload_len2);
|
||||
case SIM_JOB_PIN2_CHANGE:
|
||||
if (!sim->pin2_len) {
|
||||
LOGP(DSIM, LOGL_ERROR, "no pin set\n");
|
||||
payload_len = strlen((char *)payload);
|
||||
payload2 = payload + payload_len + 1;
|
||||
payload_len2 = strlen((char *)payload2);
|
||||
if (payload_len < 4 || payload_len > 8) {
|
||||
LOGP(DSIM, LOGL_ERROR, "key1 not in range 4..8\n");
|
||||
break;
|
||||
}
|
||||
if (payload_len2 < 4 || payload_len2 > 8) {
|
||||
LOGP(DSIM, LOGL_ERROR, "key2 not in range 4..8\n");
|
||||
break;
|
||||
}
|
||||
sim->job_state = SIM_JST_PIN2_CHANGE;
|
||||
return gsm1111_tx_change_chv(ms, 0x02, payload, payload_len,
|
||||
payload2, payload_len2);
|
||||
case SIM_JOB_PIN1_DISABLE:
|
||||
payload_len = strlen((char *)payload);
|
||||
if (payload_len < 4 || payload_len > 8) {
|
||||
LOGP(DSIM, LOGL_ERROR, "key not in range 4..8\n");
|
||||
break;
|
||||
}
|
||||
sim->job_state = SIM_JST_PIN2_CHANGE;
|
||||
return gsm1111_tx_change_chv(ms, 0x02, sim->pin1, sim->pin1_len,
|
||||
payload, payload_len);
|
||||
case SIM_JOB_PIN1_DISABLE:
|
||||
if (!sim->pin1_len) {
|
||||
LOGP(DSIM, LOGL_ERROR, "no pin set\n");
|
||||
break;
|
||||
}
|
||||
sim->job_state = SIM_JST_PIN1_DISABLE;
|
||||
return gsm1111_tx_disable_chv(ms, sim->pin1, sim->pin1_len);
|
||||
return gsm1111_tx_disable_chv(ms, payload, payload_len);
|
||||
case SIM_JOB_PIN1_ENABLE:
|
||||
if (!sim->pin1_len) {
|
||||
LOGP(DSIM, LOGL_ERROR, "no pin set\n");
|
||||
payload_len = strlen((char *)payload);
|
||||
if (payload_len < 4 || payload_len > 8) {
|
||||
LOGP(DSIM, LOGL_ERROR, "key not in range 4..8\n");
|
||||
break;
|
||||
}
|
||||
sim->job_state = SIM_JST_PIN1_ENABLE;
|
||||
return gsm1111_tx_enable_chv(ms, sim->pin1, sim->pin1_len);
|
||||
return gsm1111_tx_enable_chv(ms, payload, payload_len);
|
||||
case SIM_JOB_PIN1_UNBLOCK:
|
||||
if (payload_len < 12 || payload_len > 16) {
|
||||
LOGP(DSIM, LOGL_ERROR, "key not in range 4..8\n");
|
||||
payload_len = strlen((char *)payload);
|
||||
payload2 = payload + payload_len + 1;
|
||||
payload_len2 = strlen((char *)payload2);
|
||||
if (payload_len != 8) {
|
||||
LOGP(DSIM, LOGL_ERROR, "key1 not 8 digits\n");
|
||||
break;
|
||||
}
|
||||
sim->job_state = SIM_JST_PIN1_UNLOCK;
|
||||
memcpy(sim->pin1, payload + 8, payload_len - 8);
|
||||
sim->pin1_len = payload_len;
|
||||
if (payload_len2 < 4 || payload_len2 > 8) {
|
||||
LOGP(DSIM, LOGL_ERROR, "key2 not in range 4..8\n");
|
||||
break;
|
||||
}
|
||||
sim->job_state = SIM_JST_PIN1_UNBLOCK;
|
||||
/* NOTE: CHV1 is coded 0x00 here */
|
||||
return gsm1111_tx_unblock_chv(ms, 0x00, payload, 8, payload + 8,
|
||||
payload_len - 8);
|
||||
return gsm1111_tx_unblock_chv(ms, 0x00, payload, payload_len,
|
||||
payload2, payload_len2);
|
||||
case SIM_JOB_PIN2_UNBLOCK:
|
||||
if (payload_len < 12 || payload_len > 16) {
|
||||
LOGP(DSIM, LOGL_ERROR, "key not in range 4..8\n");
|
||||
payload_len = strlen((char *)payload);
|
||||
payload2 = payload + payload_len + 1;
|
||||
payload_len2 = strlen((char *)payload2);
|
||||
if (payload_len != 8) {
|
||||
LOGP(DSIM, LOGL_ERROR, "key1 not 8 digits\n");
|
||||
break;
|
||||
}
|
||||
sim->job_state = SIM_JST_PIN2_UNLOCK;
|
||||
memcpy(sim->pin2, payload + 8, payload_len - 8);
|
||||
sim->pin2_len = payload_len;
|
||||
return gsm1111_tx_unblock_chv(ms, 0x02, payload, 8, payload + 8,
|
||||
payload_len - 8);
|
||||
if (payload_len2 < 4 || payload_len2 > 8) {
|
||||
LOGP(DSIM, LOGL_ERROR, "key2 not in range 4..8\n");
|
||||
break;
|
||||
}
|
||||
sim->job_state = SIM_JST_PIN2_UNBLOCK;
|
||||
return gsm1111_tx_unblock_chv(ms, 0x02, payload, payload_len,
|
||||
payload2, payload_len2);
|
||||
}
|
||||
|
||||
LOGP(DSIM, LOGL_ERROR, "unknown job %x, please fix\n", sh->job_type);
|
||||
|
@ -861,12 +877,58 @@ int sim_apdu_resp(struct osmocom_ms *ms, struct msgb *msg)
|
|||
|
||||
switch (sw1) {
|
||||
case GSM1111_STAT_SECURITY:
|
||||
LOGP(DSIM, LOGL_NOTICE, "SIM Security\n");
|
||||
pin_cause[0] = SIM_CAUSE_PIN1_REQUIRED;
|
||||
pin_cause[1] = 1; /* PIN retries left */
|
||||
gsm_sim_reply(ms, SIM_JOB_ERROR, pin_cause, 2);
|
||||
msgb_free(msg);
|
||||
return 0;
|
||||
LOGP(DSIM, LOGL_NOTICE, "SIM Security\n");
|
||||
/* error */
|
||||
if (sw2 != GSM1111_SEC_NO_ACCESS && sw2 != GSM1111_SEC_BLOCKED)
|
||||
goto sim_error;
|
||||
|
||||
/* select the right remaining counter an cause */
|
||||
// FIXME: read status to replace "*_remain"-counters
|
||||
switch (sim->job_state) {
|
||||
case SIM_JST_PIN1_UNBLOCK:
|
||||
if (sw2 == GSM1111_SEC_NO_ACCESS) {
|
||||
pin_cause[0] = SIM_CAUSE_PIN1_BLOCKED;
|
||||
pin_cause[1] = --sim->unblk1_remain;
|
||||
} else {
|
||||
pin_cause[0] = SIM_CAUSE_PUC_BLOCKED;
|
||||
pin_cause[1] = 0;
|
||||
}
|
||||
break;
|
||||
case SIM_JST_PIN2_UNLOCK:
|
||||
case SIM_JST_PIN2_CHANGE:
|
||||
if (sw2 == GSM1111_SEC_NO_ACCESS && sim->chv2_remain) {
|
||||
pin_cause[0] = SIM_CAUSE_PIN2_REQUIRED;
|
||||
pin_cause[1] = sim->chv2_remain--;
|
||||
} else {
|
||||
pin_cause[0] = SIM_CAUSE_PIN2_BLOCKED;
|
||||
pin_cause[1] = sim->unblk2_remain;
|
||||
}
|
||||
break;
|
||||
case SIM_JST_PIN2_UNBLOCK:
|
||||
if (sw2 == GSM1111_SEC_NO_ACCESS) {
|
||||
pin_cause[0] = SIM_CAUSE_PIN2_BLOCKED;
|
||||
pin_cause[1] = --sim->unblk2_remain;
|
||||
} else {
|
||||
pin_cause[0] = SIM_CAUSE_PUC_BLOCKED;
|
||||
pin_cause[1] = 0;
|
||||
}
|
||||
case SIM_JST_PIN1_UNLOCK:
|
||||
case SIM_JST_PIN1_CHANGE:
|
||||
case SIM_JST_PIN1_DISABLE:
|
||||
case SIM_JST_PIN1_ENABLE:
|
||||
default:
|
||||
if (sw2 == GSM1111_SEC_NO_ACCESS && sim->chv1_remain) {
|
||||
pin_cause[0] = SIM_CAUSE_PIN1_REQUIRED;
|
||||
pin_cause[1] = sim->chv1_remain--;
|
||||
} else {
|
||||
pin_cause[0] = SIM_CAUSE_PIN1_BLOCKED;
|
||||
pin_cause[1] = sim->unblk1_remain;
|
||||
}
|
||||
break;
|
||||
}
|
||||
gsm_sim_reply(ms, SIM_JOB_ERROR, pin_cause, 2);
|
||||
msgb_free(msg);
|
||||
return 0;
|
||||
case GSM1111_STAT_MEM_PROBLEM:
|
||||
if (sw2 >= 0x40) {
|
||||
LOGP(DSIM, LOGL_NOTICE, "memory of SIM failed\n");
|
||||
|
@ -885,29 +947,9 @@ int sim_apdu_resp(struct osmocom_ms *ms, struct msgb *msg)
|
|||
case GSM1111_STAT_RESPONSE:
|
||||
case GSM1111_STAT_RESPONSE_TOO:
|
||||
LOGP(DSIM, LOGL_INFO, "command successfull\n");
|
||||
switch (sh->job_type) {
|
||||
case SIM_JOB_PIN1_CHANGE:
|
||||
memcpy(sim->pin1, payload, payload_len);
|
||||
sim->pin1_len = payload_len;
|
||||
break;
|
||||
case SIM_JOB_PIN2_CHANGE:
|
||||
memcpy(sim->pin2, payload, payload_len);
|
||||
sim->pin2_len = payload_len;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
LOGP(DSIM, LOGL_INFO, "command failed\n");
|
||||
switch (sh->job_type) {
|
||||
case SIM_JOB_PIN1_UNLOCK:
|
||||
case SIM_JOB_PIN1_UNBLOCK:
|
||||
sim->pin1_len = 0;
|
||||
break;
|
||||
case SIM_JOB_PIN2_UNLOCK:
|
||||
case SIM_JOB_PIN2_UNBLOCK:
|
||||
sim->pin2_len = 0;
|
||||
break;
|
||||
}
|
||||
request_error:
|
||||
cause = SIM_CAUSE_REQUEST_ERROR;
|
||||
gsm_sim_reply(ms, SIM_JOB_ERROR, &cause, 1);
|
||||
|
@ -939,6 +981,10 @@ int sim_apdu_resp(struct osmocom_ms *ms, struct msgb *msg)
|
|||
}
|
||||
mfdf = (struct gsm1111_response_mfdf *)data;
|
||||
mfdf_gsm = (struct gsm1111_response_mfdf_gsm *)(data + 13);
|
||||
sim->chv1_remain = mfdf_gsm->chv1_remain;
|
||||
sim->chv2_remain = mfdf_gsm->chv2_remain;
|
||||
sim->unblk1_remain = mfdf_gsm->unblk1_remain;
|
||||
sim->unblk2_remain = mfdf_gsm->unblk2_remain;
|
||||
/* if MF was selected */
|
||||
if (sim->path[0] == 0) {
|
||||
/* if MF was selected, but MF is not indicated */
|
||||
|
|
|
@ -560,6 +560,7 @@ static void subscr_sim_query_cb(struct osmocom_ms *ms, struct msgb *msg)
|
|||
uint8_t *payload = msg->data + sizeof(*sh);
|
||||
uint16_t payload_len = msg->len - sizeof(*sh);
|
||||
int rc;
|
||||
struct subscr_sim_file *sf = &subscr_sim_files[subscr->sim_file_index];
|
||||
|
||||
/* error handling */
|
||||
if (sh->job_type == SIM_JOB_ERROR) {
|
||||
|
@ -581,10 +582,22 @@ static void subscr_sim_query_cb(struct osmocom_ms *ms, struct msgb *msg)
|
|||
|
||||
vty_notify(ms, NULL);
|
||||
vty_notify(ms, "PIN is blocked\n");
|
||||
if (payload[1]) {
|
||||
vty_notify(ms, "Please give PUC for ICCID %s "
|
||||
"(you have %d tries left)\n",
|
||||
subscr->iccid, payload[1]);
|
||||
}
|
||||
subscr->sim_pin_required = 1;
|
||||
break;
|
||||
case SIM_CAUSE_PUC_BLOCKED:
|
||||
LOGP(DMM, LOGL_NOTICE, "PUC is blocked\n");
|
||||
|
||||
vty_notify(ms, NULL);
|
||||
vty_notify(ms, "PUC is blocked\n");
|
||||
subscr->sim_pin_required = 1;
|
||||
break;
|
||||
default:
|
||||
if (!subscr_sim_files[subscr->sim_file_index].
|
||||
mandatory) {
|
||||
if (sf->func && !sf->mandatory) {
|
||||
LOGP(DMM, LOGL_NOTICE, "SIM reading failed, "
|
||||
"ignoring!\n");
|
||||
goto ignore;
|
||||
|
@ -599,10 +612,19 @@ static void subscr_sim_query_cb(struct osmocom_ms *ms, struct msgb *msg)
|
|||
return;
|
||||
}
|
||||
|
||||
/* call function do decode SIM reply */
|
||||
rc = subscr_sim_files[subscr->sim_file_index].func(ms, payload,
|
||||
payload_len);
|
||||
/* if pin was successfully unlocked, then resend request */
|
||||
if (subscr->sim_pin_required) {
|
||||
subscr->sim_pin_required = 0;
|
||||
subscr_sim_request(ms);
|
||||
return;
|
||||
}
|
||||
|
||||
/* done when nothing more to read. this happens on PIN requests */
|
||||
if (!sf->func)
|
||||
return;
|
||||
|
||||
/* call function do decode SIM reply */
|
||||
rc = sf->func(ms, payload, payload_len);
|
||||
if (rc) {
|
||||
LOGP(DMM, LOGL_NOTICE, "SIM reading failed, file invalid\n");
|
||||
if (subscr_sim_files[subscr->sim_file_index].mandatory) {
|
||||
|
@ -624,23 +646,45 @@ ignore:
|
|||
}
|
||||
|
||||
/* enter PIN */
|
||||
void gsm_subscr_sim_pin(struct osmocom_ms *ms, char *pin)
|
||||
void gsm_subscr_sim_pin(struct osmocom_ms *ms, char *pin1, char *pin2,
|
||||
int8_t mode)
|
||||
{
|
||||
struct gsm_subscriber *subscr = &ms->subscr;
|
||||
struct msgb *nmsg;
|
||||
uint8_t job;
|
||||
|
||||
if (!subscr->sim_pin_required) {
|
||||
LOGP(DMM, LOGL_ERROR, "No PIN required now\n");
|
||||
return;
|
||||
switch (mode) {
|
||||
case -1:
|
||||
job = SIM_JOB_PIN1_DISABLE;
|
||||
LOGP(DMM, LOGL_INFO, "disabling PIN %s\n", pin1);
|
||||
break;
|
||||
case 1:
|
||||
job = SIM_JOB_PIN1_ENABLE;
|
||||
LOGP(DMM, LOGL_INFO, "enabling PIN %s\n", pin1);
|
||||
break;
|
||||
case 2:
|
||||
job = SIM_JOB_PIN1_CHANGE;
|
||||
LOGP(DMM, LOGL_INFO, "changing PIN %s to %s\n", pin1, pin2);
|
||||
break;
|
||||
case 99:
|
||||
job = SIM_JOB_PIN1_UNBLOCK;
|
||||
LOGP(DMM, LOGL_INFO, "unblocking PIN %s with PUC %s\n", pin1,
|
||||
pin2);
|
||||
break;
|
||||
default:
|
||||
if (!subscr->sim_pin_required) {
|
||||
LOGP(DMM, LOGL_ERROR, "No PIN required now\n");
|
||||
return;
|
||||
}
|
||||
LOGP(DMM, LOGL_INFO, "entering PIN %s\n", pin1);
|
||||
job = SIM_JOB_PIN1_UNLOCK;
|
||||
}
|
||||
|
||||
subscr->sim_pin_required = 0;
|
||||
LOGP(DMM, LOGL_INFO, "Unlocking PIN %s\n", pin);
|
||||
nmsg = gsm_sim_msgb_alloc(subscr->sim_handle_update,
|
||||
SIM_JOB_PIN1_UNLOCK);
|
||||
nmsg = gsm_sim_msgb_alloc(subscr->sim_handle_query, job);
|
||||
if (!nmsg)
|
||||
return;
|
||||
memcpy(msgb_put(nmsg, strlen(pin)), pin, strlen(pin));
|
||||
memcpy(msgb_put(nmsg, strlen(pin1) + 1), pin1, strlen(pin1) + 1);
|
||||
memcpy(msgb_put(nmsg, strlen(pin2) + 1), pin2, strlen(pin2) + 1);
|
||||
sim_job(ms, nmsg);
|
||||
}
|
||||
|
||||
|
|
|
@ -423,12 +423,105 @@ DEFUN(sim_pin, sim_pin_cmd, "sim pin MS_NAME PIN",
|
|||
if (!ms)
|
||||
return CMD_WARNING;
|
||||
|
||||
if (strlen(argv[1]) < 4 || strlen(argv[1]) > 8) {
|
||||
vty_out(vty, "PIN must be in range 4..8!%s", VTY_NEWLINE);
|
||||
return CMD_WARNING;
|
||||
}
|
||||
|
||||
if (!ms->subscr.sim_pin_required) {
|
||||
vty_out(vty, "No PIN is required at this time!%s", VTY_NEWLINE);
|
||||
return CMD_WARNING;
|
||||
}
|
||||
|
||||
gsm_subscr_sim_pin(ms, (char *)argv[1]);
|
||||
gsm_subscr_sim_pin(ms, (char *)argv[1], "", 0);
|
||||
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFUN(sim_disable_pin, sim_disable_pin_cmd, "sim disable-pin MS_NAME PIN",
|
||||
"SIM actions\nDisable PIN of SIM card\nName of MS (see \"show ms\")\n"
|
||||
"PIN number")
|
||||
{
|
||||
struct osmocom_ms *ms;
|
||||
|
||||
ms = get_ms(argv[0], vty);
|
||||
if (!ms)
|
||||
return CMD_WARNING;
|
||||
|
||||
if (strlen(argv[1]) < 4 || strlen(argv[1]) > 8) {
|
||||
vty_out(vty, "PIN must be in range 4..8!%s", VTY_NEWLINE);
|
||||
return CMD_WARNING;
|
||||
}
|
||||
|
||||
gsm_subscr_sim_pin(ms, (char *)argv[1], "", -1);
|
||||
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFUN(sim_enable_pin, sim_enable_pin_cmd, "sim enable-pin MS_NAME PIN",
|
||||
"SIM actions\nEnable PIN of SIM card\nName of MS (see \"show ms\")\n"
|
||||
"PIN number")
|
||||
{
|
||||
struct osmocom_ms *ms;
|
||||
|
||||
ms = get_ms(argv[0], vty);
|
||||
if (!ms)
|
||||
return CMD_WARNING;
|
||||
|
||||
if (strlen(argv[1]) < 4 || strlen(argv[1]) > 8) {
|
||||
vty_out(vty, "PIN must be in range 4..8!%s", VTY_NEWLINE);
|
||||
return CMD_WARNING;
|
||||
}
|
||||
|
||||
gsm_subscr_sim_pin(ms, (char *)argv[1], "", 1);
|
||||
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFUN(sim_change_pin, sim_change_pin_cmd, "sim change-pin MS_NAME OLD NEW",
|
||||
"SIM actions\nChange PIN of SIM card\nName of MS (see \"show ms\")\n"
|
||||
"Old PIN number\nNew PIN number")
|
||||
{
|
||||
struct osmocom_ms *ms;
|
||||
|
||||
ms = get_ms(argv[0], vty);
|
||||
if (!ms)
|
||||
return CMD_WARNING;
|
||||
|
||||
if (strlen(argv[1]) < 4 || strlen(argv[1]) > 8) {
|
||||
vty_out(vty, "Old PIN must be in range 4..8!%s", VTY_NEWLINE);
|
||||
return CMD_WARNING;
|
||||
}
|
||||
if (strlen(argv[2]) < 4 || strlen(argv[2]) > 8) {
|
||||
vty_out(vty, "New PIN must be in range 4..8!%s", VTY_NEWLINE);
|
||||
return CMD_WARNING;
|
||||
}
|
||||
|
||||
gsm_subscr_sim_pin(ms, (char *)argv[1], (char *)argv[2], 2);
|
||||
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFUN(sim_unblock_pin, sim_unblock_pin_cmd, "sim unblock-pin MS_NAME PUC NEW",
|
||||
"SIM actions\nChange PIN of SIM card\nName of MS (see \"show ms\")\n"
|
||||
"Personal Unblock Key\nNew PIN number")
|
||||
{
|
||||
struct osmocom_ms *ms;
|
||||
|
||||
ms = get_ms(argv[0], vty);
|
||||
if (!ms)
|
||||
return CMD_WARNING;
|
||||
|
||||
if (strlen(argv[1]) != 8) {
|
||||
vty_out(vty, "PUC must be 8 digits!%s", VTY_NEWLINE);
|
||||
return CMD_WARNING;
|
||||
}
|
||||
if (strlen(argv[2]) < 4 || strlen(argv[2]) > 8) {
|
||||
vty_out(vty, "PIN must be in range 4..8!%s", VTY_NEWLINE);
|
||||
return CMD_WARNING;
|
||||
}
|
||||
|
||||
gsm_subscr_sim_pin(ms, (char *)argv[1], (char *)argv[2], 99);
|
||||
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
@ -1258,6 +1351,10 @@ int ms_vty_init(void)
|
|||
install_element(ENABLE_NODE, &sim_reader_cmd);
|
||||
install_element(ENABLE_NODE, &sim_remove_cmd);
|
||||
install_element(ENABLE_NODE, &sim_pin_cmd);
|
||||
install_element(ENABLE_NODE, &sim_disable_pin_cmd);
|
||||
install_element(ENABLE_NODE, &sim_enable_pin_cmd);
|
||||
install_element(ENABLE_NODE, &sim_change_pin_cmd);
|
||||
install_element(ENABLE_NODE, &sim_unblock_pin_cmd);
|
||||
install_element(ENABLE_NODE, &network_search_cmd);
|
||||
install_element(ENABLE_NODE, &network_show_cmd);
|
||||
install_element(ENABLE_NODE, &network_select_cmd);
|
||||
|
|
Loading…
Reference in New Issue