mirror of
https://github.com/Sneed-Group/pypush-plus-plus
synced 2025-01-09 17:33:47 +00:00
264 lines
No EOL
8.7 KiB
Python
264 lines
No EOL
8.7 KiB
Python
# Add parent directory to path
|
||
import sys
|
||
sys.path.append("..")
|
||
sys.path.append(".")
|
||
|
||
import gsa
|
||
import requests
|
||
import uuid
|
||
import plistlib
|
||
from base64 import b64encode, b64decode
|
||
import json
|
||
import random
|
||
|
||
CONFIG_PATH = "examples/cloudkit.json"
|
||
# See if we have a search party token saved
|
||
import os
|
||
if os.path.exists(CONFIG_PATH):
|
||
print("Using saved config...")
|
||
#print("Found search party token!")
|
||
with open(CONFIG_PATH, "r") as f:
|
||
j = json.load(f)
|
||
cloudkit_token = j["cloudkit_token"]
|
||
ds_prs_id = j["ds_prs_id"]
|
||
|
||
else:
|
||
# Prompt for username and password
|
||
USERNAME = input("Username: ")
|
||
PASSWORD = input("Password: ")
|
||
|
||
print("Authenticating with Grand Slam...")
|
||
g = gsa.authenticate(USERNAME, PASSWORD)
|
||
#print(g)
|
||
pet = g["t"]["com.apple.gs.idms.pet"]["token"]
|
||
print("Authenticated!")
|
||
#print(g)
|
||
|
||
data = {
|
||
"apple-id": USERNAME,
|
||
#"delegates": {"com.apple.private.ids": {"protocol-version": "4"}},
|
||
"delegates": {"com.apple.mobileme": {}},
|
||
"password": pet,
|
||
"client-id": str(uuid.uuid4()),
|
||
|
||
}
|
||
data = plistlib.dumps(data)
|
||
from emulated import nac
|
||
|
||
print("Generating validation data...")
|
||
v = nac.generate_validation_data()
|
||
print("Generated validation data!")
|
||
|
||
headers = {
|
||
"X-Apple-ADSID": g["adsid"],
|
||
"X-Mme-Nas-Qualify": b64encode(v).decode(),
|
||
"User-Agent": "com.apple.iCloudHelper/282 CFNetwork/1408.0.4 Darwin/22.5.0",
|
||
"X-Mme-Client-Info": gsa.build_client(emulated_app="accountsd") # Otherwise we get MOBILEME_TERMS_OF_SERVICE_UPDATE on some accounts
|
||
}
|
||
headers.update(gsa.generate_anisette_headers())
|
||
|
||
print(headers)
|
||
|
||
print("Logging in to iCloud...")
|
||
r = requests.post(
|
||
"https://setup.icloud.com/setup/prefpane/login",
|
||
auth=(USERNAME, pet),
|
||
data=data,
|
||
headers=headers,
|
||
verify=False,
|
||
)
|
||
|
||
print(r)
|
||
print(r.headers)
|
||
r = plistlib.loads(r.content)
|
||
print(r)
|
||
|
||
cloudkit_token = r['delegates']['com.apple.mobileme']['service-data']['tokens']['cloudKitToken']
|
||
ds_prs_id = r['delegates']['com.apple.mobileme']['service-data']['appleAccountInfo']['dsPrsID'] # This can also be obtained from the grandslam response
|
||
|
||
print("Logged in!")
|
||
|
||
with open(CONFIG_PATH, "w") as f:
|
||
json.dump({
|
||
"cloudkit_token": cloudkit_token,
|
||
"ds_prs_id": ds_prs_id,
|
||
}, f, indent=4)
|
||
|
||
print("CloudKit token: ", cloudkit_token)
|
||
|
||
headers = {
|
||
"x-cloudkit-authtoken": cloudkit_token,
|
||
"x-cloudkit-userid": "_ec5fa262446ad56fb4bda84d00e981ff", # Hash of bundle id and icloud id
|
||
"x-cloudkit-containerid": "iCloud.dev.jjtech.experiments.cktest",
|
||
"x-cloudkit-bundleid": "dev.jjtech.experiments.cktest",
|
||
"x-cloudkit-bundleversion": "1",
|
||
"x-cloudkit-databasescope": "Public",
|
||
"x-cloudkit-environment": "Sandbox",
|
||
|
||
"accept": "application/x-protobuf",
|
||
"content-type": 'application/x-protobuf; desc="https://gateway.icloud.com:443/static/protobuf/CloudDB/CloudDBClient.desc"; messageType=RequestOperation; delimited=true',
|
||
|
||
"x-apple-operation-id": random.randbytes(8).hex(),
|
||
"x-apple-request-uuid": str(uuid.uuid4()).upper()
|
||
|
||
|
||
}
|
||
|
||
headers.update(gsa.generate_anisette_headers())
|
||
|
||
import cloudkit_pb2
|
||
|
||
# header {
|
||
# applicationContainer: "iCloud.dev.jjtech.experiments.cktest"
|
||
# applicationBundle: "dev.jjtech.experiments.cktest"
|
||
# applicationVersion: "1"
|
||
# deviceIdentifier {
|
||
# name: "776D147D-DAF3-495F-A834-12526DAECA5C"
|
||
# type: DEVICE
|
||
# }
|
||
# deviceSoftwareVersion: "13.4.1"
|
||
# deviceHardwareVersion: "MacBookPro18,3"
|
||
# deviceLibraryName: "com.apple.cloudkit.CloudKitDaemon"
|
||
# deviceLibraryVersion: "2060.11"
|
||
# locale {
|
||
# languageCode: "en-US"
|
||
# regionCode: "US"
|
||
# }
|
||
# mmcsProtocolVersion: "5.0"
|
||
# applicationContainerEnvironment: SANDBOX
|
||
# deviceAssignedName: "James\342\200\231s Laptop"
|
||
# deviceHardwareID: "776D147D-DAF3-495F-A834-12526DAECA5C"
|
||
# targetDatabase: PUBLIC_DB
|
||
# isolationLevel: ZONE
|
||
# unk1: 0
|
||
# unk2: "7B40B37D-2503-5161-9B4E-84D20478694C"
|
||
# deviceSerial: "X5T0QFNHXP"
|
||
# unk3: 0
|
||
# unk4: 1
|
||
# }
|
||
# request {
|
||
# operationUUID: "B1FC75B3-D69E-4368-BD0A-93170C7A3017"
|
||
# type: RECORD_SAVE_TYPE
|
||
# last: true
|
||
# }
|
||
# recordSaveRequest {
|
||
# record {
|
||
# recordIdentifier {
|
||
# value {
|
||
# name: "699F278B-1381-4480-8297-7751B88B8F06"
|
||
# type: RECORD
|
||
# }
|
||
# zoneIdentifier {
|
||
# value {
|
||
# name: "_defaultZone"
|
||
# type: RECORD_ZONE
|
||
# }
|
||
# ownerIdentifier {
|
||
# name: "_defaultOwner"
|
||
# type: USER
|
||
# }
|
||
# }
|
||
# }
|
||
# type {
|
||
# name: "ToDoItem"
|
||
# }
|
||
# recordField {
|
||
# identifier {
|
||
# name: "name"
|
||
# }
|
||
# value {
|
||
# type: STRING_TYPE
|
||
# stringValue: "Test item"
|
||
# }
|
||
# }
|
||
# }
|
||
# unk1: 1
|
||
# unk2: 2
|
||
# }
|
||
|
||
from typing import Literal
|
||
|
||
#def build_cloudkit_record_save_request(container: str, sandbox: bool, database: Literal["PUBLIC"] | Literal["PRIVATE"] | Literal["SHARED"], zone: str, ):
|
||
|
||
request = cloudkit_pb2.RequestOperation()
|
||
request.header.applicationContainer = "iCloud.dev.jjtech.experiments.cktest"
|
||
#request.header.applicationBundle = "dev.jjtech.experiments.cktest"
|
||
#request.header.applicationVersion = "1"
|
||
#request.header.deviceIdentifier.name = "776D147D-DAF3-495F-A834-12526DAECA5C"
|
||
#request.header.deviceIdentifier.type = cloudkit_pb2.Identifier.Type.DEVICE
|
||
#request.header.deviceSoftwareVersion = "13.4.1"
|
||
#request.header.deviceHardwareVersion = "MacBookPro18,3"
|
||
#request.header.deviceLibraryName = "com.apple.cloudkit.CloudKitDaemon"
|
||
#request.header.deviceLibraryVersion = "2060.11"
|
||
#request.header.locale.languageCode = "en-US"
|
||
#request.header.locale.regionCode = "US"
|
||
#request.header.mmcsProtocolVersion = "5.0"
|
||
request.header.applicationContainerEnvironment = cloudkit_pb2.RequestOperation.Header.ContainerEnvironment.SANDBOX
|
||
#request.header.deviceAssignedName = "James’s Laptop"
|
||
request.header.deviceHardwareID = str(uuid.uuid4()).upper()
|
||
request.header.targetDatabase = cloudkit_pb2.RequestOperation.Header.Database.PUBLIC_DB
|
||
request.header.isolationLevel = cloudkit_pb2.RequestOperation.Header.IsolationLevel.ZONE
|
||
#request.header.unk1 = 0
|
||
#request.header.unk2 = "7B40B37D-2503-5161-9B4E-84D20478694C"
|
||
#request.header.deviceSerial = "X5T0QFNHXP"
|
||
#request.header.unk3 = 0
|
||
#request.header.unk4 = 1
|
||
request.request.operationUUID = str(uuid.uuid4()).upper()
|
||
request.request.type = cloudkit_pb2.Operation.Type.RECORD_SAVE_TYPE
|
||
request.request.last = True
|
||
request.recordSaveRequest.record.recordIdentifier.value.name = str(uuid.uuid4()).upper()
|
||
request.recordSaveRequest.record.recordIdentifier.value.type = cloudkit_pb2.Identifier.Type.RECORD
|
||
request.recordSaveRequest.record.recordIdentifier.zoneIdentifier.value.name = "_defaultZone"
|
||
request.recordSaveRequest.record.recordIdentifier.zoneIdentifier.value.type = cloudkit_pb2.Identifier.Type.RECORD_ZONE
|
||
request.recordSaveRequest.record.recordIdentifier.zoneIdentifier.ownerIdentifier.name = "_defaultOwner"
|
||
request.recordSaveRequest.record.recordIdentifier.zoneIdentifier.ownerIdentifier.type = cloudkit_pb2.Identifier.Type.USER
|
||
request.recordSaveRequest.record.type.name = "ToDoItem"
|
||
# RecordField is a repeated field, so we have to append to it
|
||
request.recordSaveRequest.record.recordField.append(cloudkit_pb2.Record.Field())
|
||
request.recordSaveRequest.record.recordField[0].identifier.name = "name"
|
||
request.recordSaveRequest.record.recordField[0].value.type = cloudkit_pb2.Record.Field.Value.Type.STRING_TYPE
|
||
request.recordSaveRequest.record.recordField[0].value.stringValue = "Test pypush 5"
|
||
#request.recordSaveRequest.record.recordField.identifier.name = "name"
|
||
#request.recordSaveRequest.record.recordField.value.type = cloudkit_pb2.Record.Field.Value.Type.STRING_TYPE
|
||
#request.recordSaveRequest.record.recordField.value.stringValue = "Test item"
|
||
#request.recordSaveRequest.unk1 = 1
|
||
#request.recordSaveRequest.unk2 = 2
|
||
|
||
|
||
|
||
# WHAT ARE THESE BYTES???
|
||
body = b"\xfe\x03" + request.SerializeToString()
|
||
r =requests.post(
|
||
"https://gateway.icloud.com/ckdatabase/api/client/record/save",
|
||
headers=headers,
|
||
data=body,
|
||
verify=False
|
||
)
|
||
|
||
print(r.content)
|
||
# import time
|
||
|
||
# r = requests.post(
|
||
# "https://gateway.icloud.com/acsnservice/fetch",
|
||
# auth=(ds_prs_id, search_party_token),
|
||
# headers=gsa.generate_anisette_headers(),
|
||
# json={
|
||
# "search": [
|
||
# {
|
||
# "startDate": 1697662550688,
|
||
# "endDate": 1697673599999,
|
||
# "ids": [
|
||
# "/a8rQOW7Ucg2OOBo0D3i/7IZAbvRXcO+5y/1w0QVE4s="
|
||
# ]
|
||
# }
|
||
# ]
|
||
# }
|
||
|
||
# )
|
||
|
||
# #print(r.headers)
|
||
# if r.status_code != 200 or len(r.content) == 0:
|
||
# print("Error fetching locations (ratelimit?): ", r.status_code, r.headers)
|
||
# exit(1)
|
||
# r = r.content.decode()
|
||
# print(json.dumps(json.loads(r), indent=4)) |