/* Resource free. */ RC_TYPE dyn_dns_destruct(DYN_DNS_CLIENT *p_self) { RC_TYPE rc; if (p_self == NULL) { return RC_OK; } if (p_self->initialized == TRUE) { dyn_dns_shutdown(p_self); } rc = http_client_destruct(&p_self->http_to_ip_server); if (rc != RC_OK) { } rc = http_client_destruct(&p_self->http_to_dyndns); if (rc != RC_OK) { } if (p_self->p_work_buffer != NULL) { free(p_self->p_work_buffer); p_self->p_work_buffer = NULL; } if (p_self->p_req_buffer != NULL) { free(p_self->p_req_buffer); p_self->p_req_buffer = NULL; } if (p_self->info.credentials.p_enc_usr_passwd_buffer != NULL) { free(p_self->info.credentials.p_enc_usr_passwd_buffer); p_self->info.credentials.p_enc_usr_passwd_buffer = NULL; } free(p_self); p_self = NULL; return RC_OK; }
/** Resource free. */ static int free_context(ddns_t *ctx) { int i; if (!ctx) return 0; if (ctx->initialized == 1) dyn_dns_shutdown(ctx); http_client_destruct(ctx->http_to_ip_server, DYNDNS_MAX_SERVER_NUMBER); http_client_destruct(ctx->http_to_dyndns, DYNDNS_MAX_SERVER_NUMBER); free(ctx->work_buf); ctx->work_buf = NULL; free(ctx->request_buf); ctx->request_buf = NULL; for (i = 0; i < DYNDNS_MAX_SERVER_NUMBER; i++) { ddns_info_t *info = &ctx->info[i]; free(info->creds.encoded_password); info->creds.encoded_password = NULL; } free(ctx->cfgfile); ctx->cfgfile = NULL; free(ctx->pidfile); ctx->pidfile = NULL; free(ctx->external_command); ctx->external_command = NULL; free(ctx->bind_interface); ctx->bind_interface = NULL; free(ctx->check_interface); ctx->check_interface = NULL; free(ctx->cache_file); ctx->cache_file = NULL; free(ctx); return 0; }
static int get_req_for_freedns_server(DYN_DNS_CLIENT *p_self, int infcnt, int alcnt) { RC_TYPE rc = RC_OK, rc2; HTTP_CLIENT http_to_dyndns; HTTP_TRANSACTION http_tr; char buffer[256]; unsigned char digestbuf[SHA1_DIGEST_BYTES]; char digeststr[SHA1_DIGEST_BYTES*2+1]; int i; char *buf, *tmp, *line; char host[256], updateurl[256]; char *hash = NULL; if (p_self == NULL) { /* 0 == "No characters written" */ return 0; } // I know it's ugly, http client needs redesign. do { if ((rc = http_client_construct(&http_to_dyndns)) != RC_OK) break; http_client_set_port(&http_to_dyndns, p_self->info[infcnt].dyndns_server_name.port); http_client_set_remote_name(&http_to_dyndns, p_self->info[infcnt].dyndns_server_name.name); http_client_set_bind_iface(&http_to_dyndns, p_self->bind_interface); if ((rc = http_client_init(&http_to_dyndns, "Sending update URL query")) != RC_OK) break; snprintf(buffer, sizeof(buffer), "%s|%s", p_self->info[infcnt].credentials.my_username, p_self->info[infcnt].credentials.my_password); sha1(buffer, strlen(buffer), digestbuf); for (i = 0; i < SHA1_DIGEST_BYTES; i++) sprintf(&digeststr[i*2], "%02x", digestbuf[i]); snprintf(buffer, sizeof(buffer), "/api/?action=getdyndns&sha=%s", digeststr); http_tr.req_len = sprintf(p_self->p_req_buffer, GENERIC_HTTP_REQUEST, buffer, p_self->info[infcnt].dyndns_server_name.name); http_tr.p_req = (char*) p_self->p_req_buffer; http_tr.p_rsp = (char*) p_self->p_work_buffer; http_tr.max_rsp_len = p_self->work_buffer_size - 1; /* Save place for a \0 at the end */ http_tr.rsp_len = 0; rc = http_client_transaction(&http_to_dyndns, &http_tr); http_tr.p_rsp[http_tr.rsp_len] = 0; rc2 = http_client_shutdown(&http_to_dyndns); http_client_destruct(&http_to_dyndns, 1); if (rc != RC_OK || rc2 != RC_OK) break; if ((rc = is_http_status_code_ok(http_tr.status)) != RC_OK) break; tmp = buf = strdup(http_tr.p_rsp_body); for (line = strsep(&tmp, "\n"); line; line = strsep(&tmp, "\n")) { if (*line && sscanf(line, "%255[^|\r\n]|%*[^|\r\n]|%255[^|\r\n]", host, updateurl) == 2 && !strcmp(host, p_self->info[infcnt].alias_info[alcnt].names.name)) { hash = strstr(updateurl, "?"); break; } } free(buf); if (!hash) rc = RC_DYNDNS_RSP_NOTOK; } while (0); if (rc != RC_OK) { logit(LOG_INFO, MODULE_TAG "Update URL query failed"); return 0; } return sprintf(p_self->p_req_buffer, FREEDNS_UPDATE_IP_REQUEST, p_self->info[infcnt].dyndns_server_url, hash, p_self->info[infcnt].my_ip_address.name, p_self->info[infcnt].dyndns_server_name.name); }
/** Resource free. */ RC_TYPE dyn_dns_destruct(DYN_DNS_CLIENT *p_self) { int i; RC_TYPE rc; if (p_self == NULL) { return RC_OK; } if (p_self->initialized == TRUE) { dyn_dns_shutdown(p_self); } rc = http_client_destruct(p_self->http_to_ip_server, DYNDNS_MAX_SERVER_NUMBER); if (rc != RC_OK) { /* XXX */ } rc = http_client_destruct(p_self->http_to_dyndns, DYNDNS_MAX_SERVER_NUMBER); if (rc != RC_OK) { /* XXX */ } free(p_self->p_work_buffer); p_self->p_work_buffer = NULL; free(p_self->p_req_buffer); p_self->p_req_buffer = NULL; i = 0; while (i < DYNDNS_MAX_SERVER_NUMBER) { DYNDNS_INFO_TYPE *info = &p_self->info[i]; free(info->credentials.p_enc_usr_passwd_buffer); info->credentials.p_enc_usr_passwd_buffer = NULL; i++; } free(p_self->cfgfile); p_self->cfgfile = NULL; free(p_self->pidfile); p_self->pidfile = NULL; free(p_self->cachefile); p_self->cachefile = NULL; free(p_self->external_command); p_self->external_command = NULL; free(p_self->bind_interface); p_self->bind_interface = NULL; free(p_self->check_interface); p_self->check_interface = NULL; /* Save old value, if restarted by SIGHUP */ cached_time_since_last_update = p_self->time_since_last_update; cached_num_iterations = p_self->num_iterations; free(p_self); p_self = NULL; return RC_OK; }
/** basic resource allocations for the dyn_dns object */ RC_TYPE dyn_dns_construct(DYN_DNS_CLIENT **pp_self) { RC_TYPE rc; DYN_DNS_CLIENT *p_self; BOOL http_to_dyndns_constructed = FALSE; BOOL http_to_ip_constructed = FALSE; int i; if (pp_self == NULL) { return RC_INVALID_POINTER; } *pp_self = (DYN_DNS_CLIENT *) malloc(sizeof(DYN_DNS_CLIENT)); if (*pp_self == NULL) { return RC_OUT_OF_MEMORY; } do { p_self = *pp_self; memset(p_self, 0, sizeof(DYN_DNS_CLIENT)); /*alloc space for http_to_ip_server data*/ p_self->work_buffer_size = DYNDNS_HTTP_RESPONSE_BUFFER_SIZE; p_self->p_work_buffer = (char*) malloc(p_self->work_buffer_size); if (p_self->p_work_buffer == NULL) { rc = RC_OUT_OF_MEMORY; break; } /*alloc space for request data*/ p_self->req_buffer_size = DYNDNS_HTTP_REQUEST_BUFFER_SIZE; p_self->p_req_buffer = (char*) malloc(p_self->req_buffer_size); if (p_self->p_req_buffer == NULL) { rc = RC_OUT_OF_MEMORY; break; } i = 0; while (i < DYNDNS_MAX_SERVER_NUMBER) { rc = http_client_construct(&p_self->http_to_ip_server[i++]); if (rc != RC_OK) { rc = RC_OUT_OF_MEMORY; break; } } http_to_ip_constructed = TRUE; i = 0; while (i < DYNDNS_MAX_SERVER_NUMBER) { rc = http_client_construct(&p_self->http_to_dyndns[i++]); if (rc != RC_OK) { rc = RC_OUT_OF_MEMORY; break; } } http_to_dyndns_constructed = TRUE; (p_self)->cmd = NO_CMD; (p_self)->normal_update_period_sec = DYNDNS_DEFAULT_SLEEP; (p_self)->sleep_sec = DYNDNS_DEFAULT_SLEEP; (p_self)->total_iterations = DYNDNS_DEFAULT_ITERATIONS; (p_self)->initialized = FALSE; i = 0; while (i < DYNDNS_MAX_SERVER_NUMBER) { p_self->info[i++].credentials.p_enc_usr_passwd_buffer = NULL; } } while (0); if (rc != RC_OK) { free(*pp_self); free(p_self->p_work_buffer); free (p_self->p_work_buffer); if (http_to_dyndns_constructed) { http_client_destruct(p_self->http_to_dyndns, DYNDNS_MAX_SERVER_NUMBER); } if (http_to_ip_constructed) { http_client_destruct(p_self->http_to_ip_server, DYNDNS_MAX_SERVER_NUMBER); } } return RC_OK; }
static int get_req_for_freedns_server(ddns_t *ctx, int infcnt, int alcnt) { int rc = 0, rc2; http_client_t client; http_trans_t trans; char buffer[256]; unsigned char digestbuf[SHA1_DIGEST_BYTES]; char digeststr[SHA1_DIGEST_BYTES * 2 + 1]; int i; char *buf, *tmp, *line; char host[256], updateurl[256]; char *hash = NULL; if (ctx == NULL) { /* 0 == "No characters written" */ return 0; } // I know it's ugly, http client needs redesign. do { if ((rc = http_client_construct(&client)) != 0) break; http_client_set_port(&client, ctx->info[infcnt].dyndns_server_name.port); http_client_set_remote_name(&client, ctx->info[infcnt].dyndns_server_name.name); http_client_set_bind_iface(&client, ctx->bind_interface); if ((rc = http_client_init(&client, "Sending update URL query")) != 0) break; snprintf(buffer, sizeof(buffer), "%s|%s", ctx->info[infcnt].creds.username, ctx->info[infcnt].creds.password); sha1((unsigned char *)buffer, strlen(buffer), digestbuf); for (i = 0; i < SHA1_DIGEST_BYTES; i++) sprintf(&digeststr[i * 2], "%02x", digestbuf[i]); snprintf(buffer, sizeof(buffer), "/api/?action=getdyndns&sha=%s", digeststr); trans.req_len = sprintf(ctx->request_buf, GENERIC_HTTP_REQUEST, buffer, ctx->info[infcnt].dyndns_server_name.name); trans.p_req = (char *)ctx->request_buf; trans.p_rsp = (char *)ctx->work_buf; trans.max_rsp_len = ctx->work_buflen - 1; /* Save place for a \0 at the end */ trans.rsp_len = 0; rc = http_client_transaction(&client, &trans); trans.p_rsp[trans.rsp_len] = 0; rc2 = http_client_shutdown(&client); http_client_destruct(&client, 1); if (rc != 0 || rc2 != 0) break; if ((rc = is_http_status_code_ok(trans.status)) != 0) break; tmp = buf = strdup(trans.p_rsp_body); for (line = strsep(&tmp, "\n"); line; line = strsep(&tmp, "\n")) { if (*line && sscanf(line, "%255[^|\r\n]|%*[^|\r\n]|%255[^|\r\n]", host, updateurl) == 2 && !strcmp(host, ctx->info[infcnt].alias[alcnt].names.name)) { hash = strstr(updateurl, "?"); break; } } free(buf); if (!hash) rc = RC_DYNDNS_RSP_NOTOK; } while (0); if (rc != 0) { logit(LOG_INFO, "Update URL query failed"); return 0; } return sprintf(ctx->request_buf, FREEDNS_UPDATE_IP_REQUEST, ctx->info[infcnt].dyndns_server_url, hash, ctx->info[infcnt].my_ip_address.name, ctx->info[infcnt].dyndns_server_name.name); }
/** basic resource allocations for the dyn_dns object */ static int init_context(ddns_t **pctx) { int rc = 0; ddns_t *ctx; int http_to_dyndns_constructed = 0; int http_to_ip_constructed = 0; int i; if (!pctx) return RC_INVALID_POINTER; *pctx = (ddns_t *)malloc(sizeof(ddns_t)); if (!*pctx) return RC_OUT_OF_MEMORY; do { ctx = *pctx; memset(ctx, 0, sizeof(ddns_t)); /* Alloc space for http_to_ip_server data */ ctx->work_buflen = DYNDNS_HTTP_RESPONSE_BUFFER_SIZE; ctx->work_buf = (char *)malloc(ctx->work_buflen); if (!ctx->work_buf) { rc = RC_OUT_OF_MEMORY; break; } /* Alloc space for request data */ ctx->request_buflen = DYNDNS_HTTP_REQUEST_BUFFER_SIZE; ctx->request_buf = (char *)malloc(ctx->request_buflen); if (!ctx->request_buf) { rc = RC_OUT_OF_MEMORY; break; } i = 0; while (i < DYNDNS_MAX_SERVER_NUMBER) { if (http_client_construct(&ctx->http_to_ip_server[i++])) { rc = RC_OUT_OF_MEMORY; break; } } http_to_ip_constructed = 1; i = 0; while (i < DYNDNS_MAX_SERVER_NUMBER) { if (http_client_construct(&ctx->http_to_dyndns[i++])) { rc = RC_OUT_OF_MEMORY; break; } } http_to_dyndns_constructed = 1; ctx->cmd = NO_CMD; ctx->startup_delay_sec = DYNDNS_DEFAULT_STARTUP_SLEEP; ctx->normal_update_period_sec = DYNDNS_DEFAULT_SLEEP; ctx->sleep_sec = DYNDNS_DEFAULT_SLEEP; ctx->total_iterations = DYNDNS_DEFAULT_ITERATIONS; i = 0; while (i < DYNDNS_MAX_SERVER_NUMBER) ctx->info[i++].creds.encoded_password = NULL; ctx->initialized = 0; } while (0); if (rc) { if (ctx->work_buf) free(ctx->work_buf); if (ctx->request_buf) free(ctx->work_buf); if (http_to_dyndns_constructed) http_client_destruct(ctx->http_to_dyndns, DYNDNS_MAX_SERVER_NUMBER); if (http_to_ip_constructed) http_client_destruct(ctx->http_to_ip_server, DYNDNS_MAX_SERVER_NUMBER); free(ctx); *pctx = NULL; } return 0; }