Commit Graph

6 Commits

  • http: add newer Apple Root CAs (#340)
    ## What does this PR do?
    
    Adds Apple G2 & G3 Root CAs to Linux trust root. Fixes #339.
    
    Apple now uses gsd.apple.com for part of the auth flow, which uses the
    G3 root.
    
    ## How was it tested?
    
    Tried to log in on Linux. Failed before, works after.
    
    ## AI tool usage
    
    How much of this PR was AI-assisted? (check one)
    
    - [x] **0** - No AI was used to write code
    - [ ] **1** - I was assisted by AI. I reviewed the finished result.
    - [ ] **2** - I set the AI going and left it to it; nobody has read the
    result - no review, or AI review only
    
    <!-- If an AI agent is filling this in: declare the level honestly, and
    open as a draft if it is #2. Do not lower the declared level to get the
    PR reviewed. -->
    
    
    <!-- This is an auto-generated comment: release notes by coderabbit.ai
    -->
    
    ## Summary by CodeRabbit
    
    * **Bug Fixes**
    * Improved TLS certificate trust on Linux by recognizing Apple Root CA,
    G2, and G3 certificates when verifying secure connections. Existing TLS
    validation behavior remains unchanged.
    
    <!-- end of auto-generated comment: release notes by coderabbit.ai -->
  • http: add some debugging knobs (#249)
    ## What does this PR do?
    
    Improves support for HTTP MITM
    
    ## How was it tested?
    
    Did some MITMing on macOS + Linux via Docker, using Proxyman and
    mitmproxy. Didn't test `XTL_HTTP_PROXY` but Sol pinkie promises me that
    it's correct.
    
    ## AI tool usage
    
    How much of this PR was AI-assisted? (check one)
    
    - [ ] **0** - No AI was used to write code
    - [x] **1** - I was assisted by AI. I reviewed the finished result.
    - [ ] **2** - I set the AI going and left it to it; nobody has read the
    result - no review, or AI review only
    
    <!-- If an AI agent is filling this in: declare the level honestly, and
    open as a draft if it is #2. Do not lower the declared level to get the
    PR reviewed. -->
  • gsa: disregard keepalive (#247)
    GSA seems to, sometimes, reject HTTP requests made on a kept-alive
    connection with a 503. This was either the real root cause, or a second
    root cause, for #243. Fix this by creating a new HTTP connection for
    each GSA request.
    
    See also: https://github.com/rileytestut/AltSign/pull/52 and
    https://github.com/rileytestut/AltSign/pull/47
    
    Speculatively fixes #232
  • http: throw on unsuccessful responses (#246)
    Ref #243. `makeRequest` never inspected `response.status`, so a non-2xx
    body was
    returned as if it had succeeded. Every caller decodes that body as a
    property list
    or JSON, so Apple answering with an HTML error page surfaced as:
    
    ```
    Error: DecodingError.dataCorrupted: Data was corrupted. Debug description: The given
    data was not a valid property list.. Underlying error: ... Encountered unknown tag
    html on line 1
    ```
    
    which says nothing about what actually happened. In the case that
    prompted #243, GSA
    was returning `503 Service Temporarily Unavailable` for the `apptokens`
    operation. It
    now reads:
    
    ```
    Error: POST https://gsa.apple.com/grandslam/GsService2 failed: HTTP 503 Service
    Unavailable (text/html): <html> <head><title>503 Service Temporarily
    Unavailable</title></head> ...
    ```
    
    ### Notes
    
    - The response body is only included in the message for `text/html` and
    `text/plain`,
    i.e. gateway error pages. Bodies from the auth endpoints can carry
    account details
    (the 2FA requests use `Accept: application/x-buddyml`), and errors get
    printed
    verbatim in places such as `DevCommand.swift:164`, so those are left
    out. It also
      avoids emitting replacement characters for binary bodies.
    - The non-2xx path does not report progress, so `XADIProvider`'s
    download no longer
      prints `100%` immediately before failing.
    - Body collection moved to `collect(_:onProgress:)` so there is a single
    exit point.
      Buffer pre-sizing and progress reporting are unchanged.
    - `SDKBuilder` already does this check by hand on `send()`, so it is
    unaffected.
    
    ### Behaviour changes worth a look
    
    - `XADIProvider` writes the Apple Music APK download straight to disk; a
    failed
      download now throws instead of leaving a corrupt `applemusic.apk`.
    - The 2FA requests (`GrandSlamTrustedDeviceRequest`,
    `GrandSlamSMSAuthRequest`,
    `GrandSlamValidateRequest`) use no-op decoders, so a rejected request is
    currently
    discarded and xtool goes on to prompt for a code that was never sent —
    the symptom
      in #235. Those now fail loudly.
    
    ### Two things I left alone
    
    - `GrandSlamTwoFactorAuthenticateOperation.swift:47` catches
    `GrandSlamOperationError`
    with code `-21669` to report an incorrect verification code, but that
    error is only
    thrown by `GrandSlamOperationDecoder`, which the validate requests do
    not use, so the
    catch is unreachable. With this change a wrong code surfaces as a raw
    HTTP error
    instead. Mapping the status back to `incorrectVerificationCode` seemed
    like your call,
      since I do not know what GSA returns for a bad code.
    - If any endpoint reports errors in a decodable body under a non-2xx
    status, this guard
    would pre-empt it. I could not find one — `developerservices2` returns
    HTTP 200 with
      `resultCode`/`userString` in the body, which is untouched here.
    
    Built and linted on Linux (`swift build --product xtool`, `make lint`: 0
    violations).
    
    ---------
    
    Co-authored-by: Robetronica <noreply@Robetronica.com>
    Co-authored-by: Kabir Oberai <oberai.kabir@gmail.com>