begin work on libunr web client

pull/241/head
Rick V 5 years ago
parent 07e2336c5d
commit ccb1d74ae0
No known key found for this signature in database
GPG Key ID: C0EDC8723FDC3465

@ -28,8 +28,8 @@ cross-compile build:
# Usage
C:\>lokinet-bootstrap [uri] [local download path]
C:\>lokinet-bootstrap
this is also included in the lokinet installer package.
-despair86
-rick

@ -19,15 +19,19 @@
*/
/* this is now the source code for a minimal http client....probably something
* to do with libabyss -despair
* see bootstrap.c for the lokinet bootstrap client
*/
* to do with libabyss -despair
* see bootstrap.c for the lokinet bootstrap client
*
* This file is part of libuNR.
*/
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#ifdef _WIN32
#include <windows.h>
#include <wincrypt.h>
#endif
#include "miniz.h"
/* PolarSSL */
@ -49,7 +53,11 @@ mbedtls_x509_crt cacert;
unsigned char* ca_certs;
/* imageboard ref just because */
static char userAgent[] = "NetRunner_Micro/0.1 PolarSSL/2.13.0;U;Windows NT ";
#ifndef _WIN32
static char userAgent[] = "NetRunner_Micro/0.1 PolarSSL/2.16.0;U;";
#else
static char userAgent[] = "NetRunner_Micro/0.1 PolarSSL/2.16.0;U;Windows NT ";
#endif
/* netscape ca bundle */
static const unsigned char ca_cert_store_encoded[] =
@ -2198,89 +2206,182 @@ static const unsigned char ca_cert_store_encoded[] =
"pqLPvscxpRcQeVwScZEM7ejGcLtfoecWYaHx+nSHDilOO8UVeX81jha9ckJrgIaUEen99unjsCSN"
"vNycvRG7E2hCmn1FjzkK37f8UhIsyBZNtyX2X3sl/29r4Xgw";
typedef struct url_parser_url
typedef struct url_parser_url
{
char *protocol;
char *host;
int port;
char *path;
char *query_string;
int host_exists;
char *host_ip;
char *protocol;
char *host;
int port;
char *path;
char *query_string;
int host_exists;
char *host_ip;
} url_parser_url_t;
bool initTLS()
static char seed[64];
#ifndef _WIN32
static
try_close(fd)
{
int ret;
for(;;)
{
errno = 0;
ret = close(fd);
if(ret == -1 && errno == EINTR)
continue;
break;
}
return ret;
}
static
try_read(fd, out, count)
char* out;
size_t count;
{
size_t total;
ssize_t partial;
total = 0;
while(total < count)
{
for(;;)
{
errno = 0;
partial = read(fd, out + total, count - total);
if(partial == -1 && errno == EINTR)
continue;
break;
}
if(partial < 1)
return -1;
total += partial;
}
return 0;
}
#endif
bool
get_noise()
{
#ifdef _WIN32
HCRYPTPROV hprovider;
/* On Windows NT 4.0 or later, use CryptoAPI to grab 64 bytes of random data
*/
hprovider = 0;
CryptAcquireContext(&hprovider, NULL, NULL, PROV_RSA_FULL,
CRYPT_VERIFYCONTEXT | CRYPT_SILENT);
CryptGenRandom(hprovider, 64, (BYTE *)&seed);
CryptReleaseContext(hprovider, 0);
#else
int fd;
fd = open("/dev/urandom", O_RDONLY);
if(fd == -1)
goto fail;
if(try_read(fd, seed, 64) != 0)
{
if(try_close(fd) != 0)
goto fail;
goto fail;
}
if(try_close(fd) != 0)
goto fail;
fail:
printf("failed to read /dev/urandom!\n");
return false;
#endif
int r;
seed[63] = '\0'; /* null-terminate for safety */
r = mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func, &entropy,
(const unsigned char *)seed, 64);
if(r)
{
printf("Error: failed to seed internal RNG!\n");
return false;
}
}
bool
initTLS()
{
int inf_status,r;
size_t out;
unsigned long inf_len;
HCRYPTPROV hprovider;
unsigned char* tmp;
char str[512], seed[64];
int inf_status, r;
size_t out;
unsigned long inf_len;
unsigned char *tmp;
char str[512];
mbedtls_net_init(&server_fd);
mbedtls_ssl_init(&ssl);
mbedtls_ssl_config_init(&conf);
mbedtls_x509_crt_init(&cacert);
mbedtls_entropy_init(&entropy);
mbedtls_ctr_drbg_init(&ctr_drbg);
mbedtls_net_init(&server_fd);
mbedtls_ssl_init(&ssl);
mbedtls_ssl_config_init(&conf);
mbedtls_x509_crt_init(&cacert);
mbedtls_entropy_init(&entropy);
mbedtls_ctr_drbg_init(&ctr_drbg);
tmp = malloc(524288);
tmp = malloc(524288);
r = mbedtls_base64_decode(tmp, 524288, &out, ca_cert_store_encoded, sizeof(ca_cert_store_encoded)-1);
if (r)
{
mbedtls_strerror(r, (char*)tmp, 524288);
printf("decoding failed: %s\n", tmp);
free(tmp);
return false;
}
/* inflate ca certs, they are still compressed */
ca_certs = malloc(524288);
inf_len = 524288;
r = mbedtls_base64_decode(tmp, 524288, &out, ca_cert_store_encoded,
sizeof(ca_cert_store_encoded) - 1);
if(r)
{
mbedtls_strerror(r, (char *)tmp, 524288);
printf("decoding failed: %s\n", tmp);
free(tmp);
return false;
}
inf_status = uncompress(ca_certs, &inf_len, tmp, out);
if (inf_status != Z_OK)
{
printf("decompression failed: %s\n", mz_error(inf_status));
free(tmp);
return false;
}
/* inflate ca certs, they are still compressed */
ca_certs = malloc(524288);
inf_len = 524288;
free(tmp);
inf_status = uncompress(ca_certs, &inf_len, tmp, out);
if(inf_status != Z_OK)
{
printf("decompression failed: %s\n", mz_error(inf_status));
free(tmp);
return false;
}
/* On Windows NT 4.0 or later, use CryptoAPI to grab 64 bytes of random data */
hprovider = 0;
CryptAcquireContext(&hprovider, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT | CRYPT_SILENT);
CryptGenRandom(hprovider, 64, (BYTE*)&seed);
CryptReleaseContext(hprovider, 0);
seed[63] = '\0'; /* null-terminate for safety */
free(tmp);
/* Seed the RNG with trash from /dev/urandom or CNG */
if(!get_noise())
return false;
if (mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func, &entropy, (const unsigned char*)seed, 64) != 0) {
return false;
}
r = mbedtls_x509_crt_parse(&cacert, ca_certs, inf_len+1);
if (r < 0) {
mbedtls_strerror(r, str, 512);
printf("parse ca cert store failed\n ! mbedtls_x509_crt_parse returned: %s\n\n", str);
return false;
}
return true;
r = mbedtls_x509_crt_parse(&cacert, ca_certs, inf_len + 1);
if(r < 0)
{
mbedtls_strerror(r, str, 512);
printf(
"parse ca cert store failed\n ! mbedtls_x509_crt_parse returned: "
"%s\n\n",
str);
return false;
}
return true;
}
void free_parsed_url(url_parsed)
free_parsed_url(url_parsed)
url_parser_url_t *url_parsed;
{
if (url_parsed->protocol)
free(url_parsed->protocol);
if (url_parsed->host)
free(url_parsed->host);
if (url_parsed->path)
free(url_parsed->path);
if (url_parsed->query_string)
free(url_parsed->query_string);
if(url_parsed->protocol)
free(url_parsed->protocol);
if(url_parsed->host)
free(url_parsed->host);
if(url_parsed->path)
free(url_parsed->path);
if(url_parsed->query_string)
free(url_parsed->query_string);
free(url_parsed);
free(url_parsed);
}
parse_url(url, verify_host, parsed_url)
@ -2288,316 +2389,341 @@ char *url;
bool verify_host;
url_parser_url_t *parsed_url;
{
char *local_url;
char *token;
char *token_host;
char *host_port;
char *host_ip;
char *local_url;
char *token;
char *token_host;
char *host_port;
char *host_ip;
char *token_ptr;
char *host_token_ptr;
char *token_ptr;
char *host_token_ptr;
char *path = NULL;
char *path = NULL;
/* Copy our string */
local_url = strdup(url);
/* Copy our string */
local_url = strdup(url);
token = strtok_r(local_url, ":", &token_ptr);
parsed_url->protocol = strdup(token);
token = strtok_r(local_url, ":", &token_ptr);
parsed_url->protocol = strdup(token);
/* Host:Port */
token = strtok_r(NULL, "/", &token_ptr);
if(token)
host_port = strdup(token);
else
host_port = (char *)calloc(1, sizeof(char));
/* Host:Port */
token = strtok_r(NULL, "/", &token_ptr);
if (token)
host_port = strdup(token);
else
host_port = (char *) calloc(1, sizeof(char));
token_host = strtok_r(host_port, ":", &host_token_ptr);
parsed_url->host_ip = NULL;
if(token_host)
{
parsed_url->host = strdup(token_host);
token_host = strtok_r(host_port, ":", &host_token_ptr);
parsed_url->host_ip = NULL;
if (token_host) {
parsed_url->host = strdup(token_host);
if(verify_host)
{
struct hostent *host;
host = gethostbyname(parsed_url->host);
if(host != NULL)
{
parsed_url->host_ip = inet_ntoa(*(struct in_addr *)host->h_addr);
parsed_url->host_exists = 1;
}
else
{
parsed_url->host_exists = 0;
}
}
else
{
parsed_url->host_exists = -1;
}
}
else
{
parsed_url->host_exists = -1;
parsed_url->host = NULL;
}
if (verify_host) {
struct hostent *host;
host = gethostbyname(parsed_url->host);
if (host != NULL) {
parsed_url->host_ip = inet_ntoa(* (struct in_addr *) host->h_addr);
parsed_url->host_exists = 1;
} else {
parsed_url->host_exists = 0;
}
} else {
parsed_url->host_exists = -1;
}
} else {
parsed_url->host_exists = -1;
parsed_url->host = NULL;
}
/* Port */
token_host = strtok_r(NULL, ":", &host_token_ptr);
if(token_host)
parsed_url->port = atoi(token_host);
else
parsed_url->port = 0;
/* Port */
token_host = strtok_r(NULL, ":", &host_token_ptr);
if (token_host)
parsed_url->port = atoi(token_host);
else
parsed_url->port = 0;
token_host = strtok_r(NULL, ":", &host_token_ptr);
assert(token_host == NULL);
token_host = strtok_r(NULL, ":", &host_token_ptr);
assert(token_host == NULL);
token = strtok_r(NULL, "?", &token_ptr);
parsed_url->path = NULL;
if(token)
{
path = (char *)realloc(path, sizeof(char) * (strlen(token) + 2));
memset(path, 0, sizeof(char) * (strlen(token) + 2));
strcpy(path, "/");
strcat(path, token);
token = strtok_r(NULL, "?", &token_ptr);
parsed_url->path = NULL;
if (token) {
path = (char *) realloc(path, sizeof(char) * (strlen(token) + 2));
memset(path, 0, sizeof(char) * (strlen(token)+2));
strcpy(path, "/");
strcat(path, token);
parsed_url->path = strdup(path);
parsed_url->path = strdup(path);
free(path);
}
else
{
parsed_url->path = (char *)malloc(sizeof(char) * 2);
strcpy(parsed_url->path, "/");
}
free(path);
} else {
parsed_url->path = (char *) malloc(sizeof(char) * 2);
strcpy(parsed_url->path, "/");
}
token = strtok_r(NULL, "?", &token_ptr);
if(token)
{
parsed_url->query_string =
(char *)malloc(sizeof(char) * (strlen(token) + 1));
strncpy(parsed_url->query_string, token, strlen(token));
}
else
{
parsed_url->query_string = NULL;
}
token = strtok_r(NULL, "?", &token_ptr);
if (token) {
parsed_url->query_string = (char *) malloc(sizeof(char) * (strlen(token) + 1));
strncpy(parsed_url->query_string, token, strlen(token));
} else {
parsed_url->query_string = NULL;
}
token = strtok_r(NULL, "?", &token_ptr);
assert(token == NULL);
token = strtok_r(NULL, "?", &token_ptr);
assert(token == NULL);
free(local_url);
free(host_port);
return 0;
}
free(local_url);
free(host_port);
return 0;
terminate_unr()
{
mbedtls_ssl_close_notify(&ssl);
mbedtls_net_free(&server_fd);
mbedtls_x509_crt_free(&cacert);
mbedtls_ssl_free(&ssl);
mbedtls_ssl_config_free(&conf);
mbedtls_ctr_drbg_free(&ctr_drbg);
mbedtls_entropy_free(&entropy);
}
connect_insecure(uri, ua, savePath)
connect_insecure(uri, ua, savePath)
url_parser_url_t *uri;
char *ua, *savePath;
{
int r, len;
FILE *bootstrapRC;
char rq[4096] = { 0 };
char buf[512] = { 0 };
char path[MAX_PATH] = { 0 };
char *resp;
int r, len;
FILE *bootstrapRC;
char rq[4096] = {0};
char buf[512] = {0};
char path[MAX_PATH] = {0};
char *resp;
printf("\nDownloading %s...", &uri->path[1]);
snprintf(rq, 512, "GET %s HTTP/1.0\r\nHost: %s\r\nUser-Agent: %s\r\n\r\n", uri->path, uri->host, ua);
while ((r = mbedtls_net_send(&ssl, (unsigned char*)rq, strlen(rq))) <= 0)
{
if (r != MBEDTLS_ERR_SSL_WANT_READ && r != MBEDTLS_ERR_SSL_WANT_WRITE)
{
printf("failed! error %d\n\n", r);
return r;
}
}
memset(rq, 0, 4096);
len = 0;
do {
r = mbedtls_net_recv(&ssl, (unsigned char*)buf, 512);
if (r <= 0)
break;
else
{
strncat(rq, buf, r);
len += r;
}
} while (r);
printf("%d bytes downloaded to core.\n", len);
printf("\nDownloading %s...", &uri->path[1]);
snprintf(rq, 512, "GET %s HTTP/1.0\r\nHost: %s\r\nUser-Agent: %s\r\n\r\n",
uri->path, uri->host, ua);
while((r = mbedtls_net_send(&ssl, (unsigned char *)rq, strlen(rq))) <= 0)
{
if(r != MBEDTLS_ERR_SSL_WANT_READ && r != MBEDTLS_ERR_SSL_WANT_WRITE)
{
printf("failed! error %d\n\n", r);
return r;
}
}
memset(rq, 0, 4096);
len = 0;
do
{
r = mbedtls_net_recv(&ssl, (unsigned char *)buf, 512);
if(r <= 0)
break;
else
{
strncat(rq, buf, r);
len += r;
}
} while(r);
printf("%d bytes downloaded to core.\n", len);
if (!strstr(rq, "200 OK"))
{
printf("An error occurred.\n");
printf("Server response:\n%s", rq);
/* TODO: extract HTTP error code and return that instead */
return -1;
}
if(!strstr(rq, "200 OK"))
{
printf("An error occurred.\n");
printf("Server response:\n%s", rq);
/* TODO: extract HTTP error code and return that instead */
return -1;
}
snprintf(path, MAX_PATH, savePath);
resp = strstr(rq, "Content-Length");
r = strcspn(resp, "0123456789");
snprintf(buf, 4, "%s", &resp[r]);
r = atoi(buf);
resp = strstr(rq, "\r\n\r\n");
snprintf(buf, r, "%s", &resp[4]);
printf("Writing %s...\n", path);
bootstrapRC = fopen(path, "wb");
fwrite(buf, 1, r, bootstrapRC);
fclose(bootstrapRC);
snprintf(path, MAX_PATH, savePath);
resp = strstr(rq, "Content-Length");
r = strcspn(resp, "0123456789");
snprintf(buf, 4, "%s", &resp[r]);
r = atoi(buf);
resp = strstr(rq, "\r\n\r\n");
snprintf(buf, r, "%s", &resp[4]);
printf("Writing %s...\n", path);
bootstrapRC = fopen(path, "wb");
fwrite(buf, 1, r, bootstrapRC);
fclose(bootstrapRC);
r = 0;
r = 0;
return r;
return r;
}
main(argc, argv)
char** argv; /* It never occurred to me that this was writable to begin with... */
main(argc, argv)
char **argv; /* It never occurred to me that this was writable to begin with... */
{
DWORD version, major, minor, build, flags;
int r, len;
FILE *bootstrapRC;
char path[MAX_PATH], buf[512], port[8];
char *ua, *rq, *resp, *uri, *savePath;
url_parser_url_t *parsed_uri;
DWORD version, major, minor, build, flags;
int r, len;
FILE *out_file;
char path[MAX_PATH], buf[512], port[8];
char *ua, *rq, *resp, *uri, *savePath;
url_parser_url_t *parsed_uri;
if (argc == 1)
{
printf("Usage: %s [uri] [savepath]\n", argv[0]);
return 1;
}
if(argc >= 3)
{
uri = argv[1];
savePath = argv[2];
parsed_uri = malloc(sizeof(url_parser_url_t));
memset(parsed_uri, 0, sizeof(url_parser_url_t));
r = parse_url(uri, false, parsed_uri);
if(r)
{
printf("Invalid URI pathspec\n");
return -1;
}
}
if (argc >= 3)
{
uri = argv[1];
savePath = argv[2];
parsed_uri = malloc(sizeof(url_parser_url_t));
memset(parsed_uri, 0, sizeof(url_parser_url_t));
r = parse_url(uri, false, parsed_uri);
if (r)
{
printf("Invalid URI pathspec\n");
return -1;
}
}
if(!initTLS())
{
printf("Failed to initialise polarssl\n");
return -1;
}
if (!initTLS())
{
printf("Failed to initialise polarssl\n");
return -1;
}
/* fill in user-agent string */
version = GetVersion();
major = (DWORD)(LOBYTE(LOWORD(version)));
minor = (DWORD)(HIBYTE(LOWORD(version)));
if (version < 0x80000000)
build = (DWORD)(HIWORD(version));
ua = malloc(512);
rq = malloc(4096);
snprintf(ua, 512, "%s%d.%d", userAgent, major, minor);
/* fill in user-agent string */
#ifdef _WIN32
version = GetVersion();
major = (DWORD)(LOBYTE(LOWORD(version)));
minor = (DWORD)(HIBYTE(LOWORD(version)));
if(version < 0x80000000)
build = (DWORD)(HIWORD(version));
#endif
ua = malloc(512);
rq = malloc(4096);
snprintf(ua, 512, "%s%d.%d", userAgent, major, minor);
/* get host name, set port if blank */
if (!strcmp("https", parsed_uri->protocol) && !parsed_uri->port)
parsed_uri->port = 443;
if (!strcmp("http", parsed_uri->protocol) && !parsed_uri->port)
parsed_uri->port = 80;
/* get host name, set port if blank */
if(!strcmp("https", parsed_uri->protocol) && !parsed_uri->port)
parsed_uri->port = 443;
if(!strcmp("http", parsed_uri->protocol) && !parsed_uri->port)
parsed_uri->port = 80;
printf("connecting to %s on port %d...",parsed_uri->host, parsed_uri->port);
sprintf(port, "%d", parsed_uri->port);
r = mbedtls_net_connect(&server_fd, parsed_uri->host, port, MBEDTLS_NET_PROTO_TCP);
if (r)
{
printf("error - failed to connect to server: %d\n", r);
goto exit;
}
printf("connecting to %s on port %d...", parsed_uri->host, parsed_uri->port);
sprintf(port, "%d", parsed_uri->port);
r = mbedtls_net_connect(&server_fd, parsed_uri->host, port,
MBEDTLS_NET_PROTO_TCP);
if(r)
{
printf("error - failed to connect to server: %d\n", r);
goto exit;
}
/* ok this is where the secure vs insecure stuff splits off */
if (strcmp(parsed_uri->protocol, "https"))
{
r = connect_insecure(parsed_uri, ua, savePath);
goto exit;
}
/* ok this is where the secure vs insecure stuff splits off */
if(strcmp(parsed_uri->protocol, "https"))
{
r = connect_insecure(parsed_uri, ua, savePath);
goto exit;
}
/* HTTPS sequence */
r = mbedtls_ssl_config_defaults(&conf, MBEDTLS_SSL_IS_CLIENT, MBEDTLS_SSL_TRANSPORT_STREAM, MBEDTLS_SSL_PRESET_DEFAULT);
if (r)
{
printf("error - failed to set TLS options: %d\n", r);
goto exit;
}
mbedtls_ssl_conf_authmode(&conf, MBEDTLS_SSL_VERIFY_REQUIRED);
mbedtls_ssl_conf_ca_chain(&conf, &cacert, NULL);
mbedtls_ssl_conf_rng(&conf, mbedtls_ctr_drbg_random, &ctr_drbg);
r = mbedtls_ssl_setup(&ssl, &conf);
if (r)
{
printf("error - failed to setup TLS session: %d\n", r);
goto exit;
}
r = mbedtls_ssl_set_hostname(&ssl, parsed_uri->host);
if (r)
{
printf("error - failed to perform SNI: %d\n", r);
goto exit;
}
mbedtls_ssl_set_bio(&ssl, &server_fd, mbedtls_net_send, mbedtls_net_recv, NULL);
while ((r = mbedtls_ssl_handshake(&ssl)) != 0)
{
if (r != MBEDTLS_ERR_SSL_WANT_READ && r != MBEDTLS_ERR_SSL_WANT_WRITE)
{
printf(" failed\n ! mbedtls_ssl_handshake returned -0x%x\n\n", -r);
goto exit;
}
}
if ((flags = mbedtls_ssl_get_verify_result(&ssl)) != 0)
{
char vrfy_buf[512];
printf(" failed\n");
mbedtls_x509_crt_verify_info(vrfy_buf, sizeof(vrfy_buf), " ! ", flags);
printf("%s\n", vrfy_buf);
goto exit;
}
printf("\nDownloading %s...", &parsed_uri->path[1]);
snprintf(rq, 512, "GET %s HTTP/1.0\r\nHost: %s\r\nUser-Agent: %s\r\n\r\n", parsed_uri->path, parsed_uri->host, ua);
while ((r = mbedtls_ssl_write(&ssl, (unsigned char*)rq, strlen(rq))) <= 0)
{
if (r != MBEDTLS_ERR_SSL_WANT_READ && r != MBEDTLS_ERR_SSL_WANT_WRITE)
{
printf("failed! error %d\n\n", r);
goto exit;
}
}
memset(rq, 0, 4096);
len = 0;
do {
r = mbedtls_ssl_read(&ssl, (unsigned char*)buf, 512);
if (r <= 0)
break;
else
{
strncat(rq, buf, r);
len += r;
}
} while (r);
printf("%d bytes downloaded to core.\n", len);
mbedtls_ssl_close_notify(&ssl);
if (!strstr(rq, "200 OK"))
{
printf("An error occurred.\n");
printf("Server response:\n%s", rq);
goto exit;
}
snprintf(path, MAX_PATH, savePath);
resp = strstr(rq, "Content-Length");
r = strcspn(resp, "0123456789");
snprintf(buf, 4, "%s", &resp[r]);
r = atoi(buf);
resp = strstr(rq, "\r\n\r\n");
snprintf(buf, r, "%s", &resp[4]);
printf("Writing %s...\n", path);
bootstrapRC = fopen(path, "wb");
fwrite(buf, 1, r, bootstrapRC);
fclose(bootstrapRC);
/* HTTPS sequence */
r = mbedtls_ssl_config_defaults(&conf, MBEDTLS_SSL_IS_CLIENT,
MBEDTLS_SSL_TRANSPORT_STREAM,
MBEDTLS_SSL_PRESET_DEFAULT);
if(r)
{
printf("error - failed to set TLS options: %d\n", r);
goto exit;
}
mbedtls_ssl_conf_authmode(&conf, MBEDTLS_SSL_VERIFY_REQUIRED);
mbedtls_ssl_conf_ca_chain(&conf, &cacert, NULL);
mbedtls_ssl_conf_rng(&conf, mbedtls_ctr_drbg_random, &ctr_drbg);
r = mbedtls_ssl_setup(&ssl, &conf);
if(r)
{
printf("error - failed to setup TLS session: %d\n", r);
goto exit;
}
r = mbedtls_ssl_set_hostname(&ssl, parsed_uri->host);
if(r)
{
printf("error - failed to perform SNI: %d\n", r);
goto exit;
}
mbedtls_ssl_set_bio(&ssl, &server_fd, mbedtls_net_send, mbedtls_net_recv,
NULL);
while((r = mbedtls_ssl_handshake(&ssl)) != 0)
{
if(r != MBEDTLS_ERR_SSL_WANT_READ && r != MBEDTLS_ERR_SSL_WANT_WRITE)
{
printf(" failed\n ! mbedtls_ssl_handshake returned -0x%x\n\n", -r);
goto exit;
}
}
if((flags = mbedtls_ssl_get_verify_result(&ssl)) != 0)
{
char vrfy_buf[512];
printf(" failed\n");
mbedtls_x509_crt_verify_info(vrfy_buf, sizeof(vrfy_buf), " ! ", flags);
printf("%s\n", vrfy_buf);
goto exit;
}
printf("\nDownloading %s...", &parsed_uri->path[1]);
snprintf(rq, 512, "GET %s HTTP/1.0\r\nHost: %s\r\nUser-Agent: %s\r\n\r\n",
parsed_uri->path, parsed_uri->host, ua);
while((r = mbedtls_ssl_write(&ssl, (unsigned char *)rq, strlen(rq))) <= 0)
{
if(r != MBEDTLS_ERR_SSL_WANT_READ && r != MBEDTLS_ERR_SSL_WANT_WRITE)
{
printf("failed! error %d\n\n", r);
goto exit;
}
}
memset(rq, 0, 4096);
len = 0;
do
{
r = mbedtls_ssl_read(&ssl, (unsigned char *)buf, 512);
if(r <= 0)
break;
else
{
strncat(rq, buf, r);
len += r;
}
} while(r);
printf("%d bytes downloaded to core.\n", len);
mbedtls_ssl_close_notify(&ssl);
if(!strstr(rq, "200 OK"))
{
printf("An error occurred.\n");
printf("Server response:\n%s", rq);
goto exit;
}
snprintf(path, MAX_PATH, savePath);
resp = strstr(rq, "Content-Length");
r = strcspn(resp, "0123456789");
snprintf(buf, 4, "%s", &resp[r]);
r = atoi(buf);
resp = strstr(rq, "\r\n\r\n");
snprintf(buf, r, "%s", &resp[4]);
printf("Writing %s...\n", path);
bootstrapRC = fopen(path, "wb");
fwrite(buf, 1, r, bootstrapRC);
fclose(bootstrapRC);
r = 0;
r = 0;
exit:
mbedtls_ssl_close_notify(&ssl);
mbedtls_net_free(&server_fd);
mbedtls_x509_crt_free(&cacert);
mbedtls_ssl_free(&ssl);
mbedtls_ssl_config_free(&conf);
mbedtls_ctr_drbg_free(&ctr_drbg);
mbedtls_entropy_free(&entropy);
free(ua);
free(rq);
free(ca_certs);
free_parsed_url(parsed_uri);
return r;
}
free(ua);
free(rq);
free(ca_certs);
free_parsed_url(parsed_uri);
terminate_unr();
return r;
}
Loading…
Cancel
Save