int arms_restore_state(arms_context_t *res, const char *state, size_t size) { const struct arms_dumped_state *newstate; const struct dumped_rsinfo *rsinfo; MD5_CTX md5ctx; unsigned char digest[16]; int i; /* check size */ if (size < arms_size_of_state()) { return ARMS_ESIZE; } /* restore res from state array */ newstate = (const struct arms_dumped_state *)state; MD5_Init(&md5ctx); MD5_Update(&md5ctx, newstate, sizeof(*newstate) - sizeof(newstate->digest)); MD5_Final(digest, &md5ctx); if (memcmp(digest, newstate->digest, sizeof(digest)) != 0) { /* digest is not valid, invalid state */ return ARMS_EINVAL; } if (newstate->state_version != ARMS_STATE_VERSION) { /* version mismatch, cannot use state data. */ return ARMS_EINVAL; } RESTORE(rs_endpoint); RESTORE(rs_preshared_key); /* acmi (RS list) */ acmi_reset_server(res->acmi, ACMI_CONFIG_CONFSOL); for (i = 0; i < 5; i++) { rsinfo = &newstate->rsinfo[i]; if (rsinfo->url[0] != '\0') { acmi_set_url(res->acmi, ACMI_CONFIG_CONFSOL, rsinfo->url, URL_MAX_LEN, i); if (rsinfo->cert[0] == '\0') continue; acmi_set_cert(res->acmi, ACMI_CONFIG_CONFSOL, rsinfo->cert, strlen(rsinfo->cert) + 1, i); } } acmi_set_current_server(res->acmi, ACMI_CONFIG_CONFSOL, newstate->current_server); acmi_set_rmax(res->acmi, ACMI_CONFIG_CONFSOL, newstate->retry_max); acmi_set_rint(res->acmi, ACMI_CONFIG_CONFSOL, newstate->retry_int); acmi_set_lltimeout(res->acmi, ACMI_CONFIG_CONFSOL, newstate->lltimeout); acmi_put_lines(res->acmi, ACMI_CONFIG_CONFSOL, newstate->line_defs, newstate->num_line); res->last_line = newstate->last_line; res->result = newstate->result; #if defined(ARMS_DEBUG) && defined (DEBUG_ENABLE) acmi_dump(res->acmi); #endif return 0; }
/* * API */ int arms_load_config(arms_context_t *res, const char *encrypted_config, size_t len) { int i; char *plain; if (res == NULL) return ARMS_EFATAL; #ifdef USE_KEY plain = decrypt_lsconfig((unsigned char *)encrypted_config, len); #else plain = strdup(encrypted_config); #endif if (plain == NULL) { libarms_log(ARMS_LOG_EINITIAL_CONFIG, "initial config decrypt error."); return ARMS_EINVAL; } /* len is encrypted len. plain length is ...??? */ res->lsconf = parse_lsconfig(plain, len); if (res->lsconf == NULL) { libarms_log(ARMS_LOG_EINITIAL_CONFIG, "initial config parse error."); free(plain); return ARMS_EINVAL; } free(plain); #if defined(ARMS_DEBUG) && defined(DEBUG_ENABLE) print_lsconfig(res->lsconf); #endif acmi_clear(res->acmi, ACMI_CONFIG_RSSOL); for (i = 0; i < res->lsconf->num_url; i++) { if (res->lsconf->url[i] == NULL) break; acmi_set_url(res->acmi, ACMI_CONFIG_RSSOL, res->lsconf->url[i], URL_MAX_LEN, i); } acmi_set_rmax(res->acmi, ACMI_CONFIG_RSSOL, res->lsconf->retry_max); acmi_set_rint(res->acmi, ACMI_CONFIG_RSSOL, res->lsconf->retry_int); acmi_set_lltimeout(res->acmi, ACMI_CONFIG_RSSOL, LLTIMEOUT); acmi_set_anonpppoe(res->acmi, ACMI_CONFIG_RSSOL, res->lsconf->anonid, res->lsconf->anonpass); acmi_set_anonpppoe_ipv6(res->acmi, ACMI_CONFIG_RSSOL, res->lsconf->v6anonid, res->lsconf->v6anonpass); acmi_set_anonmobile(res->acmi, ACMI_CONFIG_RSSOL, res->lsconf->telno, res->lsconf->cid, res->lsconf->apn, res->lsconf->pdp_type, res->lsconf->pppid, res->lsconf->ppppass); #if defined(ARMS_DEBUG) && defined (DEBUG_ENABLE) acmi_dump(res->acmi); #endif return 0; }