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; }
/* * API */ int arms_init(distribution_id_t *distid, arms_context_t **ctxp) { static const struct timeval default_app_evt_timo = { 60, 0 }; static const char *ls_urls[] = { "https://202.221.49.106/arms.cgi", "https://202.221.51.6/arms.cgi", #ifdef USE_INET6 "https://[2001:240:bb88::2]/arms.cgi", "https://[2001:240:bb88::6]/arms.cgi", #endif NULL }; arms_context_t *res; struct _rand_seed { distribution_id_t distid; struct timeval tv; } rand_seed; int i; if (distid == NULL) { return ARMS_EINVAL; } #ifdef ARMS_DEBUG printf("Initialize ARMS library\n"); arms_malloc_init(); #endif *ctxp = res = arms_alloc_context(); if (res == NULL) { return ARMS_ESYSTEM; } arms_ssl_init(); rand_seed.distid = *distid; gettimeofday(&rand_seed.tv, NULL); #ifdef HAVE_SRANDOM srandom(rand_seed.tv.tv_sec ^ rand_seed.tv.tv_usec); #endif arms_ssl_register_randomness((char *)&rand_seed, sizeof(rand_seed)); /* Initialize resource data */ res->trigger = NULL; res->lsconf = NULL; res->cur_method = ARMS_PUSH_METHOD_UNKNOWN; memcpy(&res->dist_id, distid, sizeof(res->dist_id)); res->line_af = AF_UNSPEC; arms_set_keep_push_wait(res, 1); arms_hb_init(&res->hb_ctx, 1024, res->dist_id); /* Create MI Configuration Store */ res->acmi = acmi_create(); if (res->acmi == NULL) { return ARMS_EFATAL; } /* Load Initial Configuration */ for (i = 0; ls_urls[i] != NULL; i++) { acmi_set_url(res->acmi, ACMI_CONFIG_RSSOL, ls_urls[i], URL_MAX_LEN, i); } acmi_set_rmax(res->acmi, ACMI_CONFIG_RSSOL, LS_RETRY_MAX); acmi_set_rint(res->acmi, ACMI_CONFIG_RSSOL, LS_RETRY_INT); acmi_set_lltimeout(res->acmi, ACMI_CONFIG_RSSOL, LLTIMEOUT); arms_method_init(); arms_set_app_event_interval(res, &default_app_evt_timo); #if 0 print_openssl_ciphers(); #endif #if 0 { struct addrinfo hints, *re; int s, i; memset(&hints, 0, sizeof(hints)); hints.ai_flags = AI_PASSIVE; hints.ai_family = AF_INET; hints.ai_socktype = SOCK_STREAM; getaddrinfo(NULL, "8080", &hints, &re); for (i = 0; i < 1000; i++) { s = socket(re->ai_family, re->ai_socktype, re->ai_protocol); printf("s=%d\n", s); close(s); } } #endif return 0; }