anisette is done, how to sign?
This commit is contained in:
@@ -1,9 +1,30 @@
|
||||
#include "appleauth/iauth.h"
|
||||
#include "tier2/fileformats/xml.h"
|
||||
#include "tier2/fileformats/plist.h"
|
||||
#include "http/http.h"
|
||||
#include "openssl/srp.h"
|
||||
#include "openssl/sha.h"
|
||||
#include "tier0/rand.h"
|
||||
|
||||
IHTTPClientManager *g_pHttpClientMgr = NULL;
|
||||
|
||||
// autogenerated
|
||||
#define APPLE_LOCAL_USER "e2e70285da39596ef06153b9c4e1e5dc8d2f983bc5cd63f5b1e292207060d931"
|
||||
#define APPLE_HTTP_HEADER \
|
||||
{ \
|
||||
{"X-Apple-I-Client-Time", "2026-1-1T12:00:00"}, \
|
||||
{"X-Apple-Locale", "en_US"}, \
|
||||
{"X-Apple-I-TimeZone", "Europe/Kyiv"}, \
|
||||
{"X-Mme-Client-Info", "<MacBookPro13,2> <macOS;13.1;22C65> <com.apple.AuthKit/1 (com.apple.dt.Xcode/3594.4.19)>"}, \
|
||||
{"User-Agent", "akd/1.0 CFNetwork/808.1.4"}, \
|
||||
{"X-Apple-I-MD-LU", APPLE_LOCAL_USER}, \
|
||||
{"X-Apple-I-MD-M", "0"}, \
|
||||
{"X-Apple-I-SRL-NO", "0"}, \
|
||||
{"X-Mme-Device-Id", "0"}, \
|
||||
{"Content-Type", "text/x-xml-plist"}, \
|
||||
{"Accept", "*/*"}, \
|
||||
};
|
||||
|
||||
|
||||
class CAppleAuth: public IAppleAuth
|
||||
{
|
||||
public:
|
||||
@@ -12,47 +33,197 @@ public:
|
||||
virtual EAppleAuthStatus SubmitLoginData( const char *szEmail, const char *szPassword ) override;
|
||||
virtual EAppleAuthStatus Submit2FA( const char *szCode ) override;
|
||||
|
||||
CUtlString FetchADIPB();
|
||||
void FetchHeaders( CUtlString szAdiPb );
|
||||
|
||||
IHTTPClient *m_pANIClient;
|
||||
IHTTPClient *m_pGrandSlamClient;
|
||||
|
||||
CUtlString m_szProvisionStart = "/";
|
||||
CUtlString m_szProvisionFinish = "/";
|
||||
CUtlString m_szProvisionStart = "/grandslam/MidService/startMachineProvisioning";
|
||||
CUtlString m_szProvisionFinish = "/grandslam/MidService/finishMachineProvisioning";
|
||||
IJSONObject *pHeader;
|
||||
|
||||
CUtlString m_szAppleIMD;
|
||||
CUtlString m_szAppleIMDM;
|
||||
CUtlString m_szAppleIMDRINFO;
|
||||
|
||||
};
|
||||
|
||||
void CAppleAuth::Init()
|
||||
CUtlString CAppleAuth::FetchADIPB()
|
||||
{
|
||||
CreateInterfaceFn fnHttpFactory = Sys_GetFactory("funnyhttp");
|
||||
g_pHttpClientMgr = (IHTTPClientManager*)fnHttpFactory(HTTP_CLIENT_INTERFACE_VERSION, NULL);
|
||||
|
||||
|
||||
CUtlString szProvisionExpectedInputRaw = NULL;
|
||||
IJSONObject *pObject = NULL;
|
||||
IJSONObject *pPlistObject = NULL;
|
||||
CUtlString szProvisionExpectedInput = NULL;
|
||||
CUtlString szAdiPb = NULL;
|
||||
|
||||
m_pANIClient = g_pHttpClientMgr->Connect("ani.sidestore.io", true, NULL);
|
||||
m_pGrandSlamClient = g_pHttpClientMgr->Connect("gsa.apple.com", true, NULL);
|
||||
|
||||
{
|
||||
HTTPHeaderParam_t params[] = {
|
||||
{"X-Apple-I-Client-Time", "2026-1-1T12:00:00"},
|
||||
{"X-Apple-Locale", "en_US"},
|
||||
{"X-Apple-I-TimeZone", "Europe/Kyiv"},
|
||||
{"X-Mme-Client-Info", "<MacBookPro13,2> <macOS;13.1;22C65> <com.apple.AuthKit/1 (com.apple.dt.Xcode/3594.4.19)>"},
|
||||
{"User-Agent", "akd/1.0 CFNetwork/808.1.4"},
|
||||
{"X-Apple-I-MD-LU", "user"},
|
||||
{"X-Apple-I-MD-M", "0"},
|
||||
{"X-Apple-I-SRL-NO", "0"},
|
||||
{"X-Mme-Device-Id", "0"},
|
||||
{"Content-Type", "text/x-xml-plist"},
|
||||
{"Accept", "*/*"},
|
||||
};
|
||||
HTTPHeaderParam_t params[] = APPLE_HTTP_HEADER;
|
||||
HTTPHeader_t header = {
|
||||
sizeof(params)/sizeof(HTTPHeaderParam_t),
|
||||
params,
|
||||
};
|
||||
m_pGrandSlamClient->Get("/grandslam/GsService2/lookup", &header);
|
||||
HTTPResponse_t r = m_pGrandSlamClient->GetResponse();
|
||||
if (r.m_uCode == 200)
|
||||
if ( r.m_uCode != 200 )
|
||||
{
|
||||
V_printf("%s\n",r.m_message.GetMemory());
|
||||
g_pHttpClientMgr->Disconnect(m_pANIClient);
|
||||
g_pHttpClientMgr->Disconnect(m_pGrandSlamClient);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if ( !m_pANIClient->WebSocket_Connect("/v3/provisioning_session") )
|
||||
Plat_FatalErrorFunc("Failed to init AppleAuth websocket\n");
|
||||
|
||||
// Getting adipb
|
||||
while ( ( szProvisionExpectedInputRaw = m_pANIClient->WebSocket_RecvText() ) != NULL )
|
||||
{
|
||||
pObject = JSONManager()->ReadString(szProvisionExpectedInputRaw);
|
||||
szProvisionExpectedInput = pObject->GetValue("result")->GetStringValue();
|
||||
V_printf("%s\n",szProvisionExpectedInput.GetString());
|
||||
if ( szProvisionExpectedInput == "GiveIdentifier" )
|
||||
{
|
||||
m_pANIClient->WebSocket_SendText("{\"identifier\": \"" APPLE_LOCAL_USER "\"}");
|
||||
continue;
|
||||
}
|
||||
if ( szProvisionExpectedInput == "GiveStartProvisioningData" )
|
||||
{
|
||||
const char *plist =
|
||||
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
|
||||
"<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" "
|
||||
"\"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n"
|
||||
"<plist version=\"1.0\">\n"
|
||||
"<dict>\n"
|
||||
"\t<key>Header</key>\n"
|
||||
"\t<dict/>\n"
|
||||
"\t<key>Request</key>\n"
|
||||
"\t<dict/>\n"
|
||||
"</dict>\n"
|
||||
"</plist>\n";
|
||||
|
||||
HTTPHeaderParam_t params[] = APPLE_HTTP_HEADER;
|
||||
HTTPHeader_t header = {
|
||||
sizeof(params)/sizeof(HTTPHeaderParam_t),
|
||||
params,
|
||||
};
|
||||
m_pGrandSlamClient->Post(m_szProvisionStart, &header, V_strlen(plist), plist);
|
||||
HTTPResponse_t r = m_pGrandSlamClient->GetResponse();
|
||||
if ( r.m_uCode != 200 )
|
||||
{
|
||||
g_pHttpClientMgr->Disconnect(m_pANIClient);
|
||||
g_pHttpClientMgr->Disconnect(m_pGrandSlamClient);
|
||||
return NULL;
|
||||
}
|
||||
IJSONObject *pObject = PropertyListManager()->ReadString(r.m_message);
|
||||
CUtlString spim = pObject->GetValue("Response")->GetObject()->GetValue("spim")->GetStringValue();
|
||||
m_pANIClient->WebSocket_SendText(CUtlString("{\"spim\": \"%s\"}", spim.GetString()));
|
||||
|
||||
continue;
|
||||
}
|
||||
if ( szProvisionExpectedInput == "GiveEndProvisioningData" )
|
||||
{
|
||||
CUtlString cpim = pObject->GetValue("cpim")->GetStringValue();
|
||||
|
||||
CUtlString plist = CUtlString(
|
||||
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
|
||||
"<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" "
|
||||
"\"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n"
|
||||
"<plist version=\"1.0\">\n"
|
||||
"<dict>\n"
|
||||
"\t<key>Header</key>\n"
|
||||
"\t<dict/>\n"
|
||||
"\t<key>Request</key>\n"
|
||||
"\t<dict>\n"
|
||||
"\t<key>cpim</key>\n"
|
||||
"\t<string>%s</string>\n"
|
||||
"\t</dict>\n"
|
||||
"</dict>\n"
|
||||
"</plist>\n", cpim.GetString());
|
||||
|
||||
HTTPHeaderParam_t params[] = APPLE_HTTP_HEADER;
|
||||
HTTPHeader_t header = {
|
||||
sizeof(params)/sizeof(HTTPHeaderParam_t),
|
||||
params,
|
||||
};
|
||||
m_pGrandSlamClient->Post(m_szProvisionFinish, &header, V_strlen(plist), plist);
|
||||
HTTPResponse_t r = m_pGrandSlamClient->GetResponse();
|
||||
if ( r.m_uCode != 200 )
|
||||
{
|
||||
g_pHttpClientMgr->Disconnect(m_pANIClient);
|
||||
g_pHttpClientMgr->Disconnect(m_pGrandSlamClient);
|
||||
return NULL;
|
||||
}
|
||||
IJSONObject *pObject = PropertyListManager()->ReadString(r.m_message);
|
||||
CUtlString tk = pObject->GetValue("Response")->GetObject()->GetValue("tk")->GetStringValue();
|
||||
CUtlString ptm = pObject->GetValue("Response")->GetObject()->GetValue("ptm")->GetStringValue();
|
||||
|
||||
V_printf("%s\n",CUtlString("{\"tk\": \"%s\", \"ptm\": \"%s\"}", tk.GetString(), ptm.GetString()).GetString());
|
||||
m_pANIClient->WebSocket_SendText(CUtlString("{\"tk\": \"%s\", \"ptm\": \"%s\"}", tk.GetString(), ptm.GetString()));
|
||||
|
||||
continue;
|
||||
}
|
||||
if ( szProvisionExpectedInput == "ProvisioningSuccess" )
|
||||
{
|
||||
szAdiPb = pObject->GetValue("adi_pb")->GetStringValue();
|
||||
g_pHttpClientMgr->Disconnect(m_pANIClient);
|
||||
break;
|
||||
}
|
||||
if ( szProvisionExpectedInput == "Timeout" )
|
||||
{
|
||||
break;
|
||||
}
|
||||
g_pHttpClientMgr->Disconnect(m_pANIClient);
|
||||
g_pHttpClientMgr->Disconnect(m_pGrandSlamClient);
|
||||
return NULL;
|
||||
}
|
||||
g_pHttpClientMgr->Disconnect(m_pANIClient);
|
||||
g_pHttpClientMgr->Disconnect(m_pGrandSlamClient);
|
||||
return szAdiPb;
|
||||
}
|
||||
void CAppleAuth::FetchHeaders( CUtlString szAdiPb )
|
||||
{
|
||||
// Get header
|
||||
HTTPHeaderParam_t params[] = {
|
||||
"Content-Type", "application/json",
|
||||
};
|
||||
HTTPHeader_t header = {
|
||||
sizeof(params)/sizeof(HTTPHeaderParam_t),
|
||||
params,
|
||||
};
|
||||
m_pANIClient = g_pHttpClientMgr->Connect("ani.sidestore.io", true, NULL);
|
||||
CUtlString szPostData = CUtlString("{\"identifier\": \"" APPLE_LOCAL_USER "\", \"adi_pb\": \"%s\"}", szAdiPb.GetString());
|
||||
V_printf("%s\n",szPostData.GetString());
|
||||
m_pANIClient->Post("/v3/get_headers", &header, V_strlen(szPostData), szPostData);
|
||||
HTTPResponse_t r = m_pANIClient->GetResponse();
|
||||
V_printf("%i\n",r.m_uCode);
|
||||
if ( r.m_uCode == 200 )
|
||||
{
|
||||
V_printf("%s\n",r.m_message.GetMemory());
|
||||
pHeader = JSONManager()->ReadString(r.m_message);
|
||||
m_szAppleIMD = pHeader->GetValue("X-Apple-I-MD")->GetStringValue();
|
||||
m_szAppleIMDM = pHeader->GetValue("X-Apple-I-MD-M")->GetStringValue();
|
||||
m_szAppleIMDRINFO = pHeader->GetValue("X-Apple-I-MD-RINFO")->GetStringValue();
|
||||
JSONManager()->FreeObject(pHeader);
|
||||
}
|
||||
g_pHttpClientMgr->Disconnect(m_pANIClient);
|
||||
}
|
||||
|
||||
void CAppleAuth::Init()
|
||||
{
|
||||
CreateInterfaceFn fnHttpFactory = Sys_GetFactory("funnyhttp");
|
||||
|
||||
g_pHttpClientMgr = (IHTTPClientManager*)fnHttpFactory(HTTP_CLIENT_INTERFACE_VERSION, NULL);
|
||||
|
||||
|
||||
CUtlString szAdiPb = FetchADIPB();
|
||||
FetchHeaders(szAdiPb);
|
||||
|
||||
|
||||
}
|
||||
|
||||
void CAppleAuth::Shutdown()
|
||||
@@ -62,7 +233,118 @@ void CAppleAuth::Shutdown()
|
||||
|
||||
EAppleAuthStatus CAppleAuth::SubmitLoginData( const char *szEmail, const char *szPassword )
|
||||
{
|
||||
const char *pszUser = "your_username";
|
||||
const char *pszPass = "";
|
||||
|
||||
SRP_gN *pstGN = SRP_get_default_gN("2048");
|
||||
if (!pstGN) return APPLE_AUTH_FAILURE;
|
||||
|
||||
const BIGNUM *pN = pstGN->N;
|
||||
const BIGNUM *pG = pstGN->g;
|
||||
|
||||
unsigned char aucSalt[16];
|
||||
Plat_URandom(sizeof(aucSalt), aucSalt);
|
||||
|
||||
unsigned char aucHash[SHA256_DIGEST_LENGTH];
|
||||
SHA256_CTX stCtx;
|
||||
SHA256_Init(&stCtx);
|
||||
SHA256_Update(&stCtx, aucSalt, sizeof(aucSalt));
|
||||
SHA256_Update(&stCtx, pszUser, strlen(pszUser));
|
||||
SHA256_Update(&stCtx, ":", 1);
|
||||
SHA256_Update(&stCtx, pszPass, strlen(pszPass));
|
||||
SHA256_Final(aucHash, &stCtx);
|
||||
BIGNUM *pX = BN_bin2bn(aucHash, SHA256_DIGEST_LENGTH, NULL);
|
||||
BIGNUM *pV = BN_new();
|
||||
BN_CTX *pstCtx = BN_CTX_new();
|
||||
if (!BN_mod_exp(pV, pG, pX, pN, pstCtx)) return APPLE_AUTH_FAILURE;
|
||||
BN_free(pX);
|
||||
|
||||
BIGNUM *pA = BN_new();
|
||||
BIGNUM *pApriv = BN_new();
|
||||
if (!BN_rand(pApriv, 256, BN_RAND_TOP_ANY, BN_RAND_BOTTOM_ANY)) return APPLE_AUTH_FAILURE;
|
||||
if (!BN_mod_exp(pA, pG, pApriv, pN, pstCtx)) return APPLE_AUTH_FAILURE;
|
||||
|
||||
char *pszA = BN_bn2hex(pA);
|
||||
V_printf("A: %s\n",pszA);
|
||||
CUtlString plist = CUtlString(
|
||||
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
|
||||
"<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" "
|
||||
"\"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n"
|
||||
"<plist version=\"1.0\">\n"
|
||||
"<dict>\n"
|
||||
"\t<key>Header</key>\n"
|
||||
"\t<dict/>\n"
|
||||
|
||||
"\t<key>Request</key>\n"
|
||||
"\t<dict>\n"
|
||||
"\t<key>A2k</key>\n"
|
||||
"\t<string>%s</string>\n"
|
||||
"\t<key>ps</key>\n"
|
||||
"\t<array><string>s2k</string><string>s2k_fo</string></array>\n"
|
||||
"\t<string>%s</string>\n"
|
||||
"\t<key>o</key>\n"
|
||||
"\t<string>complete</string>\n"
|
||||
|
||||
"\t<key>cpd</key>\n"
|
||||
"\t<dict>\n"
|
||||
"\t<key>bootstrap</key>\n"
|
||||
"\t<true/>\n"
|
||||
"\t<key>capp</key>\n"
|
||||
"\t<string>AppStore</string>\n"
|
||||
"\t<key>ckgen</key>\n"
|
||||
"\t<true/>\n"
|
||||
"\t<key>dc</key>\n"
|
||||
"\t<string>#d4c5b3</string>\n"
|
||||
"\t<key>dec</key>\n"
|
||||
"\t<string>#e1e4e3</string>\n"
|
||||
"\t<key>loc</key>\n"
|
||||
"\t<string>en_US</string>\n"
|
||||
"\t<key>pbe</key>\n"
|
||||
"\t<false/>\n"
|
||||
"\t<key>prtn</key>\n"
|
||||
"\t<string>ME349</string>\n"
|
||||
"\t<key>svct</key>\n"
|
||||
"\t<string>iTunes</string>\n"
|
||||
|
||||
"\t<key>X-Apple-I-MD</key>\n"
|
||||
"\t<string>%s</string>\n"
|
||||
|
||||
"\t<key>X-Apple-I-MD-M</key>\n"
|
||||
"\t<string>%s</string>\n"
|
||||
|
||||
"\t<key>X-Apple-I-MD-RINFO</key>\n"
|
||||
"\t<string>%s</string>\n"
|
||||
"\t</dict>\n"
|
||||
|
||||
"\t</dict>\n"
|
||||
"</dict>\n"
|
||||
"</plist>\n", pszA, szEmail, m_szAppleIMD.GetString(), m_szAppleIMDM.GetString(), m_szAppleIMDRINFO.GetString());
|
||||
m_pGrandSlamClient = g_pHttpClientMgr->Connect("gsa.apple.com", true, NULL);
|
||||
HTTPHeaderParam_t params[] = {
|
||||
{"Content-Type", "text/x-xml-plist"},
|
||||
{"Accept", "*/*"},
|
||||
};
|
||||
HTTPHeader_t header = {
|
||||
sizeof(params)/sizeof(HTTPHeaderParam_t),
|
||||
params,
|
||||
};
|
||||
V_printf("%s\n",plist.GetString());
|
||||
m_pGrandSlamClient->Post("/grandslam/GsService2", &header, plist.GetLenght(), plist);
|
||||
HTTPResponse_t stResponse = m_pGrandSlamClient->GetResponse();
|
||||
V_printf("%i\n", stResponse.m_uCode);
|
||||
if (stResponse.m_uCode == 200)
|
||||
{
|
||||
V_printf("%s\n",stResponse.m_message.GetMemory());
|
||||
|
||||
}
|
||||
g_pHttpClientMgr->Disconnect(m_pGrandSlamClient);
|
||||
|
||||
OPENSSL_free(pszA);
|
||||
BN_free(pApriv);
|
||||
BN_free(pA);
|
||||
BN_free(pV);
|
||||
BN_CTX_free(pstCtx);
|
||||
return APPLE_AUTH_SUCCESS;
|
||||
}
|
||||
|
||||
EAppleAuthStatus CAppleAuth::Submit2FA( const char *szCode )
|
||||
|
||||
Reference in New Issue
Block a user