Пример #1
0
/***
Set SSL options for a context.
@function :setSSLOptions
@tparam boolean disableVerify disable server certificate verification if `true`
@tparam[opt=false] boolean tlsv10 use TLS v1.0 if `true`
*/
static int httpc_setSSLOptions(lua_State *L) {
	httpcContext *context = lua_touserdata(L, 1);
	
	bool disVer = lua_toboolean(L, 2);
	bool tsl10 = false;
	if (lua_isboolean(L, 3))
		tsl10 = lua_toboolean(L, 3);
	
	httpcSetSSLOpt(context, (disVer?SSLCOPT_DisableVerify:0)|(tsl10?SSLCOPT_TLSv10:0));
	
	return 0;
}
Пример #2
0
static Result action_url_install_open_src(void* data, u32 index, u32* handle) {
    url_install_data* installData = (url_install_data*) data;

    Result res = 0;

    httpcContext* context = (httpcContext*) calloc(1, sizeof(httpcContext));
    if(context != NULL) {
        if(R_SUCCEEDED(res = httpcOpenContext(context, HTTPC_METHOD_GET, installData->urls[index], 1))) {
            char userAgent[128];
            snprintf(userAgent, sizeof(userAgent), "Mozilla/5.0 (Nintendo 3DS; Mobile; rv:10.0) Gecko/20100101 FBI/%d.%d.%d", VERSION_MAJOR, VERSION_MINOR, VERSION_MICRO);

            if(R_SUCCEEDED(res = httpcSetSSLOpt(context, SSLCOPT_DisableVerify)) && R_SUCCEEDED(res = httpcAddRequestHeaderField(context, "User-Agent", userAgent)) && R_SUCCEEDED(res = httpcBeginRequest(context)) && R_SUCCEEDED(res = httpcGetResponseStatusCode(context, &installData->responseCode, 0))) {
                if(installData->responseCode == 200) {
                    *handle = (u32) context;
                } else if(installData->responseCode == 301 || installData->responseCode == 302 || installData->responseCode == 303) {
                    memset(installData->urls[index], '\0', URL_MAX);
                    if(R_SUCCEEDED(res = httpcGetResponseHeader(context, "Location", installData->urls[index], URL_MAX))) {
                        httpcCloseContext(context);
                        free(context);

                        return action_url_install_open_src(data, index, handle);
                    }
                } else {
                    res = R_FBI_HTTP_RESPONSE_CODE;
                }
            }

            if(R_FAILED(res)) {
                httpcCloseContext(context);
            }
        }

        if(R_FAILED(res)) {
            free(context);
        }
    } else {
        res = R_FBI_OUT_OF_MEMORY;
    }

    return res;
}
Пример #3
0
static Result action_install_cdn_open_src(void* data, u32 index, u32* handle) {
    install_cdn_data* installData = (install_cdn_data*) data;

    Result res = 0;

    httpcContext* context = (httpcContext*) calloc(1, sizeof(httpcContext));
    if(context != NULL) {
        char url[256];
        if(index == 0) {
            snprintf(url, 256, "http://ccs.cdn.c.shop.nintendowifi.net/ccs/download/%016llX/tmd", installData->ticket->titleId);
        } else {
            snprintf(url, 256, "http://ccs.cdn.c.shop.nintendowifi.net/ccs/download/%016llX/%08lX", installData->ticket->titleId, installData->contentIds[index - 1]);
        }

        if(R_SUCCEEDED(res = httpcOpenContext(context, HTTPC_METHOD_GET, url, 1))) {
            httpcSetSSLOpt(context, SSLCOPT_DisableVerify);
            if(R_SUCCEEDED(res = httpcBeginRequest(context)) && R_SUCCEEDED(res = httpcGetResponseStatusCode(context, &installData->responseCode, 0))) {
                if(installData->responseCode == 200) {
                    *handle = (u32) context;
                } else {
                    res = R_FBI_HTTP_RESPONSE_CODE;
                }
            }

            if(R_FAILED(res)) {
                httpcCloseContext(context);
            }
        }

        if(R_FAILED(res)) {
            free(context);
        }
    } else {
        res = R_FBI_OUT_OF_MEMORY;
    }

    return res;
}
Пример #4
0
Result DownloadTitle(std::string titleId, std::string encTitleKey, std::string titleName, std::string region)
{
    // Convert the titleid to a u64 for later use
    char* nTitleId = parse_string(titleId);
    u64 uTitleId = u8_to_u64((u8*)nTitleId, BIG_ENDIAN);
    free (nTitleId);

    // Wait for wifi to be available
    u32 wifi = 0;
    Result ret = 0;
    Result res = 0;
    while(R_SUCCEEDED(ret = ACU_GetWifiStatus(&wifi)) && wifi == 0)
    {
        hidScanInput();
        if (hidKeysDown() & KEY_B)
        {
            ret = -1;
            break;
        }
    }

    if (R_FAILED(ret))
    {
        printf("Unable to access internet.\n");
        return ret;
    }

    std::string outputDir = "/CIAngel";

    if (titleName.length() == 0)
    {
        titleName = titleId;
    }

    // Include region in filename
    if (region.length() > 0)
    {
        titleName = titleName + " (" + region + ")";
    }

    std::string mode_text;
    if(config.GetMode() == CConfig::Mode::DOWNLOAD_CIA)
    {
        mode_text = "create";
    }
    else if(config.GetMode() == CConfig::Mode::INSTALL_CIA)
    {
        mode_text = "install";
    }


    printf("Starting - %s\n", titleName.c_str());

    // If in install mode, download/install the SEED entry
    if (config.GetMode() == CConfig::Mode::INSTALL_CIA)
    {
        // Download and install the SEEDDB entry if install mode
        // Code based on code from FBI: https://github.com/Steveice10/FBI/blob/master/source/core/util.c#L254
        // Copyright (C) 2015 Steveice10
        u8 seed[16];
        static const char* regionStrings[] = {"JP", "US", "GB", "GB", "HK", "KR", "TW"};
        u8 region = CFG_REGION_USA;
        CFGU_GetSystemLanguage(&region);

        if(region <= CFG_REGION_TWN) {
            char url[128];
            snprintf(url, 128, SEED_URL "0x%016llX/ext_key?country=%s", uTitleId, regionStrings[region]);

            httpcContext context;
            if(R_SUCCEEDED(res = httpcOpenContext(&context, HTTPC_METHOD_GET, url, 1))) {
                httpcSetSSLOpt(&context, SSLCOPT_DisableVerify);

                u32 responseCode = 0;
                if(R_SUCCEEDED(res = httpcBeginRequest(&context)) && R_SUCCEEDED(res = httpcGetResponseStatusCode(&context, &responseCode, 0))) {
                    if(responseCode == 200) {
                        u32 pos = 0;
                        u32 bytesRead = 0;
                        while(pos < sizeof(seed) && (R_SUCCEEDED(res = httpcDownloadData(&context, &seed[pos], sizeof(seed) - pos, &bytesRead)) || (u32)res == HTTPC_RESULTCODE_DOWNLOADPENDING)) {
                            pos += bytesRead;
                        }
                    } else {
                        res = -1;
                    }
                }

                httpcCloseContext(&context);
            }

            if (R_SUCCEEDED(res))
            {
                res = InstallSeed(uTitleId, seed);
                if (R_FAILED(res))
                {
                    printf("Error installing SEEDDB entry: 0x%lx\n", res);
                }
            }
        }
    }

    // Make sure the CIA doesn't already exist
    std::string cp = outputDir + "/" + titleName + ".cia";
    if (config.GetMode() == CConfig::Mode::DOWNLOAD_CIA && FileExists(cp.c_str()))
    {
        printf("%s already exists.\n", cp.c_str());
        return 0;
    }

    std::ofstream ofs;

    FILE *oh = fopen((outputDir + "/tmp/tmd").c_str(), "wb");
    if (!oh) 
    {
        printf("Error opening %s/tmp/tmd\n", outputDir.c_str());
        return -1;
    }
    res = DownloadFile((NUS_URL + titleId + "/tmd").c_str(), oh, false);
    fclose(oh);
    if (res != 0)
    {
        printf("Could not download TMD. Internet/Title ID is OK?\n");
        return res;
    }

    // Read version
    std::ifstream tmdfs;
    tmdfs.open(outputDir + "/tmp/tmd", std::ofstream::out | std::ofstream::in | std::ofstream::binary);
    char titleVersion[2];
    tmdfs.seekg(top+0x9C, std::ios::beg);
    tmdfs.read(titleVersion, 0x2);
    tmdfs.close();

    CreateTicket(titleId, encTitleKey, titleVersion, outputDir + "/tmp/ticket");

    printf("Now %s the CIA...\n", mode_text.c_str());

    res = ProcessCIA(outputDir + "/tmp", titleName);
    if (res != 0)
    {
        printf("Could not %s the CIA.\n", mode_text.c_str());
        return res;
    }

    if (config.GetMode() == CConfig::Mode::DOWNLOAD_CIA)
    {
        rename((outputDir + "/tmp/" + titleName + ".cia").c_str(), (outputDir + "/" + titleName + ".cia").c_str());
    }

    printf(" DONE!\n");

    return res;
}
Пример #5
0
static int lua_downstring(lua_State *L){
	int argc = lua_gettop(L);
	#ifndef SKIP_ERROR_HANDLING
	if (argc < 1 || argc > 4) return luaL_error(L, "wrong number of arguments");
	#endif
	const char* url = luaL_checkstring(L,1);
	const char* headers = (argc >= 2) ? luaL_checkstring(L,2) : NULL;
	u8 method = (argc >= 3) ? luaL_checkinteger(L,3) : 0;
	const char* postdata = (argc >= 4) ? luaL_checkstring(L,4) : NULL;
	httpcContext context;
	HTTPC_RequestMethod useMethod = HTTPC_METHOD_GET;

	if(method <= 3 && method >= 1) useMethod = (HTTPC_RequestMethod)method;

	u32 statuscode=0;
	do {
		if (statuscode >= 301 && statuscode <= 308) {
			char newurl[4096];
			httpcGetResponseHeader(&context, (char*)"Location", &newurl[0], 4096);
			url = &newurl[0];

			httpcCloseContext(&context);
		}

		Result ret = httpcOpenContext(&context, useMethod, (char*)url , 0);
		
		// Lets just disable SSL verification instead of loading default certs.
		httpcSetSSLOpt(&context, SSLCOPT_DisableVerify);

		if(headers != NULL){
			char *tokenheader = (char*)malloc(strlen(headers)+1);
			strcpy(tokenheader, headers);
			char *toker = tokenheader;
			char *headername = NULL;
			char *headervalue = NULL;
			do {
				headername = strtok(toker, ":");
				if (headername == NULL) break;
				headervalue = strtok(NULL, "\n");
				if (headervalue == NULL) break;
				if (headervalue[0] == ' ') headervalue++;
				httpcAddRequestHeaderField(&context, headername, headervalue);
				toker = NULL;
			} while (headername != NULL && headervalue != NULL);
			free(tokenheader);
		}

		if (useMethod == HTTPC_METHOD_POST && postdata != NULL) {
			httpcAddPostDataRaw(&context, (u32*)postdata, strlen(postdata));
		}

		#ifndef SKIP_ERROR_HANDLING
		if(ret==0){
		#endif
			httpcBeginRequest(&context);
			long int contentsize=0; // Crash on the += if u32. WTF?
			u32 readSize=0;
			httpcGetResponseStatusCode(&context, &statuscode, 0);
			if (statuscode == 200) {
				unsigned char *buffer = (unsigned char*)malloc(0x1000);
				do {
					ret = httpcDownloadData(&context, buffer+contentsize, 0x1000, &readSize);
					contentsize += readSize;
					if (ret == (s32)HTTPC_RESULTCODE_DOWNLOADPENDING)
						buffer = (unsigned char*)realloc(buffer, contentsize + 0x1000);
				} while (ret == (s32)HTTPC_RESULTCODE_DOWNLOADPENDING);
				buffer = (unsigned char*)realloc(buffer, contentsize + 1);
				buffer[contentsize] = 0;
				lua_pushlstring(L,(const char*)buffer,contentsize);
				free(buffer);
			}
		#ifndef SKIP_ERROR_HANDLING
		}
		#endif
	} while ((statuscode >= 301 && statuscode <= 303) || (statuscode >= 307 && statuscode <= 308));
	#ifndef SKIP_ERROR_HANDLING
	if ((statuscode < 200 && statuscode > 226) && statuscode != 304) luaL_error(L, "error opening url");
	#endif
	httpcCloseContext(&context);
	return 1;
}
Пример #6
0
static int lua_download(lua_State *L){
	int argc = lua_gettop(L);
	#ifndef SKIP_ERROR_HANDLING
	if (argc < 2 || argc > 5) return luaL_error(L, "wrong number of arguments");
	#endif
	const char* url = luaL_checkstring(L,1);
	const char* file = luaL_checkstring(L,2);
	const char* headers = (argc >= 3) ? luaL_checkstring(L,3) : NULL;
	u8 method = (argc >= 4) ? luaL_checkinteger(L,4) : 0;
	const char* postdata = (argc >= 5) ? luaL_checkstring(L,5) : NULL;
	httpcContext context;
	u32 statuscode=0;
	HTTPC_RequestMethod useMethod = HTTPC_METHOD_GET;

	if(method <= 3 && method >= 1) useMethod = (HTTPC_RequestMethod)method;

	do {
		if (statuscode >= 301 && statuscode <= 308) {
			char newurl[4096];
			httpcGetResponseHeader(&context, (char*)"Location", &newurl[0], 4096);
			url = &newurl[0];

			httpcCloseContext(&context);
		}

		Result ret = httpcOpenContext(&context, useMethod, (char*)url, 0);
		
		// Just disable SSL verification instead of loading default certs.
		httpcSetSSLOpt(&context, SSLCOPT_DisableVerify);

		if(headers != NULL){
			char *tokenheader = (char*)malloc(strlen(headers)+1);
			strcpy(tokenheader, headers);
			char *toker = tokenheader;
			char *headername = NULL;
			char *headervalue = NULL;
			do {
				headername = strtok(toker, ":");
				if (headername == NULL) break;
				headervalue = strtok(NULL, "\n");
				if (headervalue == NULL) break;
				if (headervalue[0] == ' ') headervalue++;
				httpcAddRequestHeaderField(&context, headername, headervalue);
				toker = NULL;
			} while (headername != NULL && headervalue != NULL);
			free(tokenheader);
		}

		if (useMethod == HTTPC_METHOD_POST && postdata != NULL) {
			httpcAddPostDataRaw(&context, (u32*)postdata, strlen(postdata));
		}

		#ifndef SKIP_ERROR_HANDLING
		if(ret==0){
		#endif
			httpcBeginRequest(&context);
			u32 contentsize=0;
			httpcGetResponseStatusCode(&context, &statuscode, 0);
			if (statuscode == 200){
				u32 readSize = 0;
				long int bytesWritten = 0;
				u8* buf = (u8*)malloc(0x1000);
				memset(buf, 0, 0x1000);

				Handle fileHandle;
				FS_Archive sdmcArchive=(FS_Archive){ARCHIVE_SDMC, (FS_Path){PATH_EMPTY, 1, (u8*)""}};
				FS_Path filePath=fsMakePath(PATH_ASCII, file);
				FSUSER_OpenFileDirectly( &fileHandle, sdmcArchive, filePath, FS_OPEN_CREATE|FS_OPEN_WRITE, 0x00000000);

				do {
					ret = httpcDownloadData(&context, buf, 0x1000, &readSize);
					FSFILE_Write(fileHandle, NULL, bytesWritten, buf, readSize, 0x10001);
					bytesWritten += readSize;
				} while (ret == (s32)HTTPC_RESULTCODE_DOWNLOADPENDING);

				FSFILE_Close(fileHandle);
				svcCloseHandle(fileHandle);
				free(buf);
			}
		#ifndef SKIP_ERROR_HANDLING
		}
		#endif
	} while ((statuscode >= 301 && statuscode <= 303) || (statuscode >= 307 && statuscode <= 308));
	#ifndef SKIP_ERROR_HANDLING
	if ((statuscode < 200 && statuscode > 226) && statuscode != 304) luaL_error(L, "error opening url");
	#endif
	httpcCloseContext(&context);
	lua_pushinteger(L, statuscode);
	return 1;
}