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); }
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 */ 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; }
/** 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; }