Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

setup.icloud.com two-step verification

I'm playing around with iLoot, an open source app that let's you download iCloud backups and I was wondering how it is possible to implement the two factor authentication to it.

I have 2fa enabled on my account and what I get on the first request is this:

First request:

        auth = "Basic %s" % base64.b64encode("%s:%s" % (login, password))
authenticateResponse = plist_request("setup.icloud.com", "POST", "/setup/authenticate/$APPLE_ID$", "", {"Authorization": auth})

plist_request is just a normal python (request) function that request from the url and returns the parsed xml.

First response (in xml format):

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"     "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>protocolVersion</key>
    <string>2</string>

    <key>title</key>
    <string>Verification Required</string>

    <key>localizedError</key>
    <string>MOBILEME_TERMS_OF_SERVICE_UPDATE</string>

    <key>message</key>
    <string>This Apple ID is protected with two-step verification. To sign in, you must verify your identity.</string>

</dict>
</plist>
Request /setup/authenticate/$APPLE_ID$ returned code 409

In case anyone knows what the next call would be to input the two-step verification code, it could help to figure it out.

like image 957
Shayan Avatar asked Oct 28 '14 09:10

Shayan


1 Answers

I'm an iOS guy, not backend guy, but my backend team solved this on their side by using the app-specific password, instead of tokens.

This is how user can generate an app-specific password: Generate App-Specific Password

Then simply use the email and this password, instead of the token formed by dsPrsID:mmeAuthToken. As I learnt for my teammates, you don't have to do base64 encode, just use that new password, and the url:'https://caldav.icloud.com/'

Hope this helps. It was a nightmare for us, no help at all on the internet.

UPDATE

For more info, these are the steps I used on my side (iOS):

  1. I call https://setup.icloud.com/setup/authenticate/"[email protected]", by setting "Basic email:password" as base64 string to "Authorization" http header field.

  2. I check response status code. If 401, it means the password you are sending is an app specific password, so then I send this password (and email) directly to my server, via our internal API, and they are using it to call iCloud APIs, and return me calendars, etc.

  3. If response status code is 409, it means that user tried to login with a normal password, but his account is enabled for 2fa, and I display an error, warning user to go and retrieve his app-specific-password, and use that one, which will lead to step 2, above.

I am not saying this is the only way, but this worked for me. Also, I don't exactly know what's going on on server side, but they are using directly that app-specific-passwrod (and probably the email), to do the job.

like image 79
Beny Boariu Avatar answered Sep 27 '22 20:09

Beny Boariu