#include #include #include #include "amcus/iauth.h" #include "amcus/amcus.h" #include "amcus/config.h" #include "util/dprintf.h" static struct amcus_config config; static char local_ip[16]; static char subnet[16]; static char router_ip[16]; static char auth_srv_ip[16]; void iauth_set_config(struct amcus_config *cfg) { memcpy(&config, cfg, sizeof(*cfg)); uint32_t netenv_ip_prefix = cfg->netenv.subnet; uint32_t netenv_ip_iface = cfg->netenv.subnet | cfg->netenv.addr_suffix; uint32_t netenv_ip_router = cfg->netenv.subnet | cfg->netenv.router_suffix; sprintf_s(local_ip, _countof(local_ip), "%i.%i.%i.%i", (uint8_t) (netenv_ip_iface >> 24), (uint8_t) (netenv_ip_iface >> 16), (uint8_t) (netenv_ip_iface >> 8), (uint8_t) (netenv_ip_iface )); sprintf_s(subnet, _countof(subnet), "%i.%i.%i.%i", (uint8_t) (netenv_ip_prefix >> 24), (uint8_t) (netenv_ip_prefix >> 16), (uint8_t) (netenv_ip_prefix >> 8), (uint8_t) (netenv_ip_prefix )); sprintf_s(router_ip, _countof(router_ip), "%i.%i.%i.%i", (uint8_t) (netenv_ip_router >> 24), (uint8_t) (netenv_ip_router >> 16), (uint8_t) (netenv_ip_router >> 8), (uint8_t) (netenv_ip_router )); } static ULONG REF_COUNT = 0; static bool is_init = true; static int amauthd_state = DAEMON_DL; static HRESULT STDMETHODCALLTYPE IAuth_QueryInterface(IAuth FAR *This, REFIID riid, void **ppvObj) { dprintf("IAuth: QueryInterface\n"); if (ppvObj == NULL) { return E_POINTER; } if (IsEqualGUID(riid, &amcus_rclsid)) { This->lpVtbl->AddRef(This); *ppvObj = This; return S_OK; } return E_NOINTERFACE; } static ULONG STDMETHODCALLTYPE IAuth_AddRef(IAuth FAR *This) { // dprintf("IAuth: AddRef\n"); return ++REF_COUNT; } static ULONG STDMETHODCALLTYPE IAuth_Release(IAuth FAR *This) { // dprintf("IAuth: Release\n"); return --REF_COUNT; } static HRESULT STDMETHODCALLTYPE IAuth_Initialize(IAuth FAR *This, int64_t p0) { dprintf("IAuth: %s hit! p0 %I64d\n", __func__, p0); if (is_init) { return 1; } is_init = true; amauthd_state = DAEMON_INIT; return 0; } static HRESULT STDMETHODCALLTYPE IAuth_Finalize(IAuth FAR *This) { dprintf("IAuth: %s hit!\n", __func__); if (!is_init) { return 1; } is_init = false; amauthd_state = DAEMON_UNKNOWN; return 0; } static HRESULT STDMETHODCALLTYPE IAuth_Func5(IAuth FAR *This, int64_t p0) { dprintf("IAuth: %s hit! p0 %I64d\n", __func__, p0); return S_OK; } static LONG STDMETHODCALLTYPE IAuth_Func6(IAuth FAR *This) { dprintf("IAuth: %s hit!\n", __func__); return 1; } static HRESULT STDMETHODCALLTYPE IAuth_Func7(IAuth FAR *This) { dprintf("IAuth: %s hit!\n", __func__); return S_OK; } static HRESULT STDMETHODCALLTYPE IAuth_Func8(IAuth FAR *This) { dprintf("IAuth: %s hit!\n", __func__); return S_OK; } // Likely has to do with mucha and the updater static HRESULT STDMETHODCALLTYPE IAuth_GetUpdaterState(IAuth FAR *This, struct amcus_state *arr) { // dprintf("IAuth: %s hit!\n", __func__); memset(arr, 0, sizeof(*arr)); char cacfg_ver[6]; wcstombs_s(NULL, cacfg_ver, sizeof(cacfg_ver), config.cacfg_game_ver, sizeof(config.cacfg_game_ver)); double ver_d = atof(cacfg_ver); int ver_top = (int)ver_d; int ver_btm = (int)(ver_d * 100); if (ver_top != 0) { ver_btm %= (ver_top * 100); } arr->allnet_state.state = DAEMON_IDLE; arr->allnet_state.auth_state = 2; arr->allnet_state.auth_count = 1; arr->mucha_state.state = DAEMON_DL; arr->mucha_state.auth_state = 2; arr->mucha_state.auth_count = 1; arr->mucha_state.state_dlexec = DLEXEC_PROC; arr->mucha_state.state_dlstep = DLSTEP_IDLE; arr->mucha_state.state_dllan = DLLAN_DISABLE; arr->mucha_state.state_dlwan = DLWAN_COMPLETE; arr->mucha_state.state_io = DAEMON_IO_NONE; arr->mucha_state.cacfg_ver_major = ver_top; arr->mucha_state.cacfg_ver_minor = ver_btm; arr->mucha_state.app_ver_major = ver_top; arr->mucha_state.app_ver_minor = ver_btm; arr->mucha_state.dl_check_complete = 1; arr->clock_status = 1; arr->auth_type = AUTH_TYPE_ALLNET; arr->cab_mode = DAEMON_MODE_STANDALONE; arr->state = amauthd_state; switch (amauthd_state) { case DAEMON_INIT: amauthd_state = DAEMON_AUTH_START; break; case DAEMON_AUTH_START: amauthd_state = DAEMON_IDLE; break; case DAEMON_IDLE: amauthd_state = DAEMON_DL; break; default: break; } return S_OK; } // Valid valnues for mode are STANDALONE, CLIENT, SERVER static HRESULT STDMETHODCALLTYPE IAuth_GetCabinetConfig(IAuth FAR *This, struct amcus_network_state *arr) { // dprintf("IAuth: %s hit!\n", __func__); memset(arr, 0, sizeof(*arr)); if (!is_init) { return E_ACCESSDENIED; } char am_serial[12]; char dongle_serial[13]; wcstombs_s(NULL, am_serial, sizeof(am_serial), config.am_serial, sizeof(config.am_serial)); wcstombs_s(NULL, dongle_serial, sizeof(dongle_serial), config.dongle.serial, sizeof(config.dongle.serial)); strcpy_s(arr->mode, sizeof(arr->mode), "STANDALONE"); strcpy_s(arr->pcbid, sizeof(arr->pcbid), am_serial); strcpy_s(arr->dongle_serial, sizeof(arr->dongle_serial), dongle_serial); strcpy_s(arr->shop_router_ip, sizeof(arr->shop_router_ip), router_ip); // router ip strcpy_s(arr->auth_server_ip, sizeof(arr->auth_server_ip), router_ip); // "default" in dnshook strcpy_s(arr->local_ip, sizeof(arr->local_ip), local_ip); // fake ip strcpy_s(arr->subnet_mask, sizeof(arr->subnet_mask), subnet); // fake subnet strcpy_s(arr->gateway, sizeof(arr->gateway), router_ip); // router ip strcpy_s(arr->primary_dns, sizeof(arr->primary_dns), router_ip); // Pokken doesn't read this it seems arr->hop_count = 1; arr->line_type = TYPE_FFT; return S_OK; } // Gets things like version and game id static HRESULT STDMETHODCALLTYPE IAuth_GetVersionInfo(IAuth FAR *This, struct amcus_version_info *arr) { // dprintf("IAuth: %s hit!\n", __func__); memset(arr, 0, sizeof(*arr)); if (!is_init) { return E_ACCESSDENIED; } char game_id[5]; char game_cd[5]; char am_ver[6]; char cacfg_ver[6]; wcstombs_s(NULL, game_id, sizeof(game_id), config.game_id, sizeof(config.game_id)); wcstombs_s(NULL, game_cd, sizeof(game_cd), config.game_cd, sizeof(config.game_cd)); wcstombs_s(NULL, am_ver, sizeof(am_ver), config.am_game_ver, sizeof(config.am_game_ver)); wcstombs_s(NULL, cacfg_ver, sizeof(cacfg_ver), config.cacfg_game_ver, sizeof(config.cacfg_game_ver)); strcpy_s(arr->game_rev, sizeof(arr->game_rev), "1"); strcpy_s(arr->auth_type, sizeof(arr->auth_type), "ALL.NET"); strcpy_s(arr->game_id, sizeof(arr->game_id), game_id); strcpy_s(arr->game_ver, sizeof(arr->game_ver), am_ver); // version sent in allnet request strcpy_s(arr->game_cd, sizeof(arr->game_cd), game_cd); // unique per game, PKFN, S121, SAO1, etc strcpy_s(arr->cacfg_game_ver, sizeof(arr->cacfg_game_ver), cacfg_ver); // first 2 are 0 = A - 25 = Z, 2nd two are the two digits strcpy_s(arr->game_board_type, sizeof(arr->game_board_type), "0"); strcpy_s(arr->game_board_id, sizeof(arr->game_board_id), "PCB"); strcpy_s(arr->auth_url, sizeof(arr->auth_url), "localhost"); // doesn't matter return S_OK; } static HRESULT STDMETHODCALLTYPE IAuth_Func12(IAuth FAR *This) { dprintf("IAuth: %s hit!\n", __func__); return S_OK; } static HRESULT STDMETHODCALLTYPE IAuth_Func13(IAuth FAR *This) { dprintf("IAuth: %s hit!\n", __func__); return S_OK; } // Response from All.net, thanks mon! static HRESULT STDMETHODCALLTYPE IAuth_GetAuthServerResp(IAuth FAR *This, struct amcus_auth_server_resp *arr) { // dprintf("IAuth: %s hit!\n", __func__); memset(arr, 0, sizeof(*arr)); if (!is_init) { return E_ACCESSDENIED; } char uri[257]; char host[257]; wcstombs_s(NULL, uri, sizeof(uri), config.server_uri, sizeof(config.server_uri)); wcstombs_s(NULL, host, sizeof(host), config.server_host, sizeof(config.server_host)); strcpy_s(arr->uri, sizeof(arr->uri), uri); strcpy_s(arr->host, sizeof(arr->host), host); strcpy_s(arr->shop_name, sizeof(arr->shop_name), "Test Shop!"); strcpy_s(arr->shop_nickname, sizeof(arr->shop_nickname), "Test Shop"); strcpy_s(arr->region0, sizeof(arr->region0), "1"); strcpy_s(arr->region_name0, sizeof(arr->region_name0), "W"); strcpy_s(arr->region_name1, sizeof(arr->region_name1), "X"); strcpy_s(arr->region_name2, sizeof(arr->region_name2), "Y"); strcpy_s(arr->region_name3, sizeof(arr->region_name3), "Z"); strcpy_s(arr->place_id, sizeof(arr->place_id), "123"); strcpy_s(arr->setting, sizeof(arr->setting), "1"); strcpy_s(arr->country, sizeof(arr->country), "JPN"); strcpy_s(arr->timezone, sizeof(arr->timezone), "+0900"); strcpy_s(arr->res_class, sizeof(arr->res_class), "PowerOnResponseVer2"); return S_OK; } static HRESULT STDMETHODCALLTYPE IAuth_Func15(IAuth FAR *This) { dprintf("IAuth: %s hit!\n", __func__); return S_OK; } static HRESULT STDMETHODCALLTYPE IAuth_Func16(IAuth FAR *This) { dprintf("IAuth: %s hit!\n", __func__); return S_OK; } static HRESULT STDMETHODCALLTYPE IAuth_Func17(IAuth FAR *This) { dprintf("IAuth: %s hit!\n", __func__); return S_OK; } static HRESULT STDMETHODCALLTYPE IAuth_GetMuchaAuthResponse(IAuth FAR *This, struct mucha_boardauth_resp *arr) { // dprintf("IAuth: %s hit!\n", __func__); memset(arr, 0, sizeof(*arr)); if (!is_init) { return E_ACCESSDENIED; } strcpy_s(arr->shop_name, sizeof(arr->shop_name), "Bananatools Default Shop"); strcpy_s(arr->shop_name_en, sizeof(arr->shop_name_en), "Bananatools Default Shop"); strcpy_s(arr->shop_nickname, sizeof(arr->shop_nickname), "Bananatools"); strcpy_s(arr->shop_nickname_en, sizeof(arr->shop_nickname_en), "Bananatools"); strcpy_s(arr->place_id, sizeof(arr->place_id), "JPN123"); strcpy_s(arr->country_cd, sizeof(arr->country_cd), "JPN"); strcpy_s(arr->area0, sizeof(arr->area0), "008"); strcpy_s(arr->area0_en, sizeof(arr->area0_en), "008"); strcpy_s(arr->area1, sizeof(arr->area1), "009"); strcpy_s(arr->area1_en, sizeof(arr->area1_en), "009"); strcpy_s(arr->area2, sizeof(arr->area2), "010"); strcpy_s(arr->area2_en, sizeof(arr->area2_en), "010"); strcpy_s(arr->area3, sizeof(arr->area3), "011"); strcpy_s(arr->area3_en, sizeof(arr->area3_en), "011"); strcpy_s(arr->prefecture_id, sizeof(arr->prefecture_id), "1"); strcpy_s(arr->expiration_date, sizeof(arr->expiration_date), "null"); strcpy_s(arr->consume_token, sizeof(arr->consume_token), "0"); strcpy_s(arr->force_boot, sizeof(arr->force_boot), "0"); strcpy_s(arr->use_token, sizeof(arr->use_token), "0"); strcpy_s(arr->dongle_flag, sizeof(arr->dongle_flag), "1"); strcpy_s(arr->url_charge, sizeof(arr->url_charge), "https://localhost/charge/"); strcpy_s(arr->url_file, sizeof(arr->url_file), "https://localhost/file/"); strcpy_s(arr->url_url1, sizeof(arr->url_url1), "https://localhost/url1/"); strcpy_s(arr->url_url2, sizeof(arr->url_url2), "https://localhost/url2/"); strcpy_s(arr->url_url3, sizeof(arr->url_url3), "https://localhost/url3/"); return S_OK; } // Another struct static HRESULT STDMETHODCALLTYPE IAuth_Func19(IAuth FAR *This, struct mucha_updater_state *arr) { // dprintf("IAuth: %s hit!\n", __func__); memset(arr, 0, sizeof(*arr)); if (!is_init) { return E_ACCESSDENIED; } arr->state = 1; // if this isn't 1 taiko thinks it isn't auth'd return 1; } // Converts allnet responsed to mucha info static HRESULT STDMETHODCALLTYPE IAuth_Func20(IAuth FAR *This) { dprintf("IAuth: %s hit!\n", __func__); return S_OK; } // dl_mode_lan and dl_mode_wan enable/disable? static HRESULT STDMETHODCALLTYPE IAuth_Func21(IAuth FAR *This) { dprintf("IAuth: %s hit!\n", __func__); return S_OK; } static HRESULT STDMETHODCALLTYPE IAuth_Func22(IAuth FAR *This) { dprintf("IAuth: %s hit!\n", __func__); return S_OK; } // Called after 30, p0 usually 0 static HRESULT STDMETHODCALLTYPE IAuth_Func23(IAuth FAR *This, int64_t p0) { dprintf("IAuth: %s hit! %I64d\n", __func__, p0); if (!is_init) { return E_ACCESSDENIED; } return S_OK; } // more dtmode stuff static HRESULT STDMETHODCALLTYPE IAuth_Func24(IAuth FAR *This) { dprintf("IAuth: %s hit!\n", __func__); return S_OK; } // something to do with fileio and version and the like? static HRESULT STDMETHODCALLTYPE IAuth_Func25(IAuth FAR *This) { dprintf("IAuth: %s hit!\n", __func__); return 1; } // no clue static HRESULT STDMETHODCALLTYPE IAuth_Func26(IAuth FAR *This) { dprintf("IAuth: %s hit!\n", __func__); return S_OK; } // something to do with downloaded patches static HRESULT STDMETHODCALLTYPE IAuth_Func27(IAuth FAR *This) { dprintf("IAuth: %s hit!\n", __func__); return 1; } // no clue static HRESULT STDMETHODCALLTYPE IAuth_Func28(IAuth FAR *This) { dprintf("IAuth: %s hit!\n", __func__); return S_OK; } // no clue static HRESULT STDMETHODCALLTYPE IAuth_Func29(IAuth FAR *This) { dprintf("IAuth: %s hit!\n", __func__); return S_OK; } // Called before 23, function unknown static HRESULT STDMETHODCALLTYPE IAuth_Func30(IAuth FAR *This) { dprintf("IAuth: %s hit!\n", __func__); if (!is_init) { return E_ACCESSDENIED; } return S_OK; } // no clue static HRESULT STDMETHODCALLTYPE IAuth_Func31(IAuth FAR *This) { dprintf("IAuth: %s hit!\n", __func__); return S_OK; } // just seems to allocate stuff static HRESULT STDMETHODCALLTYPE IAuth_Func32(IAuth FAR *This, int64_t p0, int64_t* p1) { dprintf("IAuth: %s hit! p0 %I64d p1 %I64d\n", __func__, p0, *p1); return S_OK; } // no clue static HRESULT STDMETHODCALLTYPE IAuth_Func33(IAuth FAR *This, int64_t p0, int64_t* p1, int64_t* p2, int64_t* p3, int64_t* p4) { dprintf("IAuth: %s hit! p0 %I64d p1 %I64d p2 %I64d p3 %I64d p4 %I64d\n", __func__, p0, *p1, *p2, *p3, *p4); return S_OK; } IAuthVtbl iauth_vtbl = { .QueryInterface = IAuth_QueryInterface, .AddRef = IAuth_AddRef, .Release = IAuth_Release, .Initialize = IAuth_Initialize, .Finalize = IAuth_Finalize, .Func5 = IAuth_Func5, .Func6 = IAuth_Func6, .Func7 = IAuth_Func7, .Func8 = IAuth_Func8, .GetUpdaterState = IAuth_GetUpdaterState, .GetCabinetConfig = IAuth_GetCabinetConfig, .GetVersionInfo = IAuth_GetVersionInfo, .Func12 = IAuth_Func12, .Func13 = IAuth_Func13, .GetAuthServerResp = IAuth_GetAuthServerResp, .Func15 = IAuth_Func15, .Func16 = IAuth_Func16, .Func17 = IAuth_Func17, .GetMuchaAuthResponse = IAuth_GetMuchaAuthResponse, .Func19 = IAuth_Func19, .Func20 = IAuth_Func20, .Func21 = IAuth_Func21, .Func22 = IAuth_Func22, .Func23 = IAuth_Func23, .Func24 = IAuth_Func24, .Func25 = IAuth_Func25, .Func26 = IAuth_Func26, .Func27 = IAuth_Func27, .Func28 = IAuth_Func28, .Func29 = IAuth_Func29, .Func30 = IAuth_Func30, .Func31 = IAuth_Func31, .Func32 = IAuth_Func32, .Func33 = IAuth_Func33, }; IAuth iauth_stub_object = { .lpVtbl = &iauth_vtbl, }; IAuth *iauth_stub = &iauth_stub_object;