Exemplo n.º 1
0
int httpGet(const char* url, u8** buf, u32* size) {
	httpcContext context;
	CHECK(httpcOpenContext(&context, HTTPC_METHOD_GET, (char*)url, 0), "Could not open HTTP context");
	// Add User Agent field (required by Github API calls)
	CHECK(httpcAddRequestHeaderField(&context, (char*)"User-Agent", (char*)"ARN-UPDATER"), "Could not set User Agent");

	CHECK(httpcBeginRequest(&context), "Could not begin request");

	// Add root CA required for Github and AWS URLs
	CHECK(httpcAddTrustedRootCA(&context, digicert_cer, digicert_cer_len), "Could not add Digicert root CA");
	CHECK(httpcAddTrustedRootCA(&context, cybertrust_cer, cybertrust_cer_len), "Could not add Cybertrust root CA");

	u32 statuscode = 0;
	CHECK(httpcGetResponseStatusCode(&context, &statuscode, 0), "Could not get status code");
	if (statuscode != 200) {
		// Handle 3xx codes
		if (statuscode >= 300 && statuscode < 400) {
			char newUrl[1024];
			CHECK(httpcGetResponseHeader(&context, (char*)"Location", newUrl, 1024), "Could not get Location header for 3xx reply");
			CHECK(httpcCloseContext(&context), "Could not close HTTP context");
			return httpGet(newUrl, buf, size);
		}
		throw formatErrMessage("Non-200 status code", statuscode);
	}

	CHECK(httpcGetDownloadSizeState(&context, NULL, size), "Could not get file size");

	*buf = (u8*)std::malloc(*size);
	if (*buf == NULL) throw formatErrMessage("Could not allocate enough memory", *size);
	std::memset(*buf, 0, *size);

	CHECK(httpcDownloadData(&context, *buf, *size, NULL), "Could not download data");

	CHECK(httpcCloseContext(&context), "Could not close HTTP context");

	return 1;
}
Exemplo n.º 2
0
/***
Add a trusted RootCA cert to a context.
@function :addTrustedRootCA
@tparam string DER certificate
@treturn[1] boolean `true` if everything went fine
@treturn[2] boolean `false` in case of error
@treturn[2] integer error code
*/
static int httpc_addTrustedRootCA(lua_State *L) {
	httpcContext *context = lua_touserdata(L, 1);
	u32 certsize;
	u8* cert = (u8*)luaL_checklstring(L, 2, (size_t*)&certsize);
	
	Result ret = httpcAddTrustedRootCA(context, cert, certsize);
	if (ret != 0) {
		lua_pushboolean(L, false);
		lua_pushinteger(L, ret);
		return 2;
	}
	
	lua_pushboolean(L, true);
	return 1;
}
Exemplo n.º 3
0
Result download_config(char *url, u8 *cert, u32 certsize, u8 *filebuffer, u32 dlsize, u32 *out_statuscode)
{
	Result ret=0;
	u32 statuscode=0;
	httpcContext context;

	ret = httpcOpenContext(&context, HTTPC_METHOD_GET, url, 1);
	if(R_FAILED(ret))
	{
		printf("httpcOpenContext returned 0x%08x.\n", (unsigned int)ret);
		return ret;
	}

	ret = httpcAddRequestHeaderField(&context, "User-Agent", "ctr-httpwn/"VERSION);
	if(R_FAILED(ret))
	{
		printf("httpcAddRequestHeaderField returned 0x%08x.\n", (unsigned int)ret);
		httpcCloseContext(&context);
		return ret;
	}

	ret = httpcAddTrustedRootCA(&context, cert, certsize);
	if(R_FAILED(ret))
	{
		printf("httpcAddTrustedRootCA returned 0x%08x.\n", (unsigned int)ret);
		httpcCloseContext(&context);
		return ret;
	}

	ret = httpcBeginRequest(&context);
	if(R_FAILED(ret))
	{
		printf("httpcBeginRequest returned 0x%08x.\n", (unsigned int)ret);
		httpcCloseContext(&context);
		return ret;
	}

	ret = httpcGetResponseStatusCode(&context, &statuscode, 0);
	if(R_FAILED(ret))
	{
		printf("httpcGetResponseStatusCode returned 0x%08x.\n", (unsigned int)ret);
		httpcCloseContext(&context);
		return ret;
	}

	if(out_statuscode)*out_statuscode = statuscode;

	if(statuscode==200 || statuscode==500)
	{
		ret = httpcDownloadData(&context, filebuffer, dlsize, NULL);
		if(ret!=0 && statuscode==200)
		{
			printf("httpcDownloadData returned 0x%08x.\n", (unsigned int)ret);
			httpcCloseContext(&context);
			return ret;
		}
	}

	ret = httpcCloseContext(&context);
	if(R_FAILED(ret))
	{
		printf("httpcCloseContext returned 0x%08x.\n", (unsigned int)ret);
		return ret;
	}

	if(statuscode!=200)
	{
		printf("Invalid statuscode: %u.\n", (unsigned int)statuscode);
		return -5;
	}

	return 0;
}