mirror of
https://github.com/fenleon/open-madrid.git
synced 2026-10-22 16:12:35 +00:00
registration: step-2 optional extraHeaders (A/B instrumentation — anisette-on-mint falsified live 2026-10-13)
This commit is contained in:
1 parent
7980dd1fe2
commit
e5352e77ce
2 files changed
+21
-4
No files matched your search
@@ -149,8 +149,7 @@ class GsaDelegateLoginClient(
|
||||
val delegates = linkedMapOf<String, Any?>(
|
||||
IDS_DELEGATE_BUNDLE_ID to linkedMapOf("protocol-version" to "4"),
|
||||
MOBILEME_DELEGATE_BUNDLE_ID to linkedMapOf<String, Any?>(),
|
||||
)
|
||||
// The vendored reference (open_absinthe, RE 2026-10-13) ships ONLY the V1 request
|
||||
) // The vendored reference (open_absinthe, RE 2026-10-13) ships ONLY the V1 request
|
||||
// shape on this endpoint: kebab-case `AuthRequest {apple-id, client-id, delegates,
|
||||
// password}` with the PET in the body — the .so has no V2AuthRequest/protocolVersion/
|
||||
// userInfo strings at all. Basic `username:PET` still rides (the closure's
|
||||
@@ -188,6 +187,18 @@ class GsaDelegateLoginClient(
|
||||
put("User-Agent", SIGNIN_USER_AGENT)
|
||||
}
|
||||
val encoded = XmlPlist.encode(body)
|
||||
// A/B instrumentation: dump the exact outgoing request (headers + body) when the
|
||||
// marker exists, for a host-side rustls replay with byte-identical content. The
|
||||
// dump carries the Basic credential — /data/local/tmp only, never logged.
|
||||
if (java.io.File("/data/local/tmp/debug-capture-signin").isFile) {
|
||||
runCatching {
|
||||
java.io.File("/data/local/tmp/debug-last-signin.bin").writeBytes(
|
||||
(listOf("POST $endpoint", "Content-Type: $CONTENT_TYPE") +
|
||||
headers.entries.map { (k, v) -> "$k: $v" } + listOf("", "")).joinToString("\r\n")
|
||||
.toByteArray(Charsets.UTF_8) + encoded,
|
||||
)
|
||||
}
|
||||
}
|
||||
val response = http.post(endpoint, headers, encoded, CONTENT_TYPE)
|
||||
if (response.status != 200) {
|
||||
throw GsaLoginException(
|
||||
|
||||
+8
-2
@@ -78,12 +78,18 @@ class ValidationCertClient(
|
||||
/**
|
||||
* Step 2: POST the single-key `session-info-request` plist body — no anisette, no auth
|
||||
* headers (§1.1: body only) — and return the response's `session-info` data.
|
||||
* [extraHeaders] rides verbatim (the A/B instrumentation: whether the genuine client
|
||||
* binds the VEN session to an anisette identity here has never been wire-observed —
|
||||
* the only accepted captures predate any anisette test).
|
||||
*/
|
||||
suspend fun initializeValidation(sessionInfoRequest: ByteArray): ByteArray {
|
||||
suspend fun initializeValidation(
|
||||
sessionInfoRequest: ByteArray,
|
||||
extraHeaders: Map<String, String> = emptyMap(),
|
||||
): ByteArray {
|
||||
val url = bags.idsBag().url(ValidationBagKeys.INITIALIZE)
|
||||
logEvent("validation: initializing the validation session")
|
||||
val body = XmlPlist.encode(linkedMapOf("session-info-request" to sessionInfoRequest))
|
||||
val response = http.post(url, emptyMap(), body, CONTENT_TYPE)
|
||||
val response = http.post(url, extraHeaders, body, CONTENT_TYPE)
|
||||
if (response.status != 200) {
|
||||
throw ValidationDataException("POST $url → HTTP ${response.status} (§1.1 step 2)")
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user