Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

backend: Add Apple iCloud Drive backend #7717

Draft
wants to merge 19 commits into
base: master
Choose a base branch
from

Conversation

lostb1t
Copy link

@lostb1t lostb1t commented Apr 2, 2024

What is the purpose of this change?

Add support for a new backend, iCloud Drive

Was the change discussed in an issue or in the forum before?

#1778

Checklist

  • I have read the contribution guidelines.
  • I have added tests for all changes in this PR if appropriate.
  • I have added documentation for the changes if appropriate.
  • All commit messages are in house style.
  • I'm done, this Pull Request is ready for review :-)

Notes

This feature branch is in a working state, feedback on finished implementations is appreciated. Ill keep it in draft untill everything is implemented and ill update the TODO accordingly

This PR is only for iCloud Drive. Ill continue work on Photos once this PR is merged.

Todo

Rclone Interfaces

Fs
  • List
  • Mkdir
  • Rmdir
  • Put
Object
  • Open
  • Update
  • Remove
Mover
  • Move
DirMove
  • DirMove
Copier
  • Copy

@ncw
Copy link
Member

ncw commented Apr 2, 2024

Nice work :-)

Some quick questions

  • where did the client_id come from?
  • are you running through the integration tests?

Thank you

@lostb1t
Copy link
Author

lostb1t commented Apr 2, 2024

Nice work :-)

Some quick questions

  • where did the client_id come from?
  • are you running through the integration tests?

Thank you

not sure what client_id you are referring to? and no I havent run any integration test yet.
Will do whenimplemented all interfaces.

@lostb1t
Copy link
Author

lostb1t commented Apr 4, 2024

fyi: so iCloud doesn't have functionality for updating/replacing files. At least not something I can find reverse engineering

So if a file exists I move it to iCloud trash. And upload a new version of the file.
After successful upload the file is removed from trash or restored from trash if upload failed.

@lostb1t
Copy link
Author

lostb1t commented Apr 5, 2024

@ncw how one handle folder invalidation? drive uses etags for files and folders. If a file or folder within a folder changes then the parent folders etag changes. This means I have to clear almost the whole tree from child to parent.

Not sure how to handle that in general, what if a users change it locally but file/folder has changed remotely in between. What error should I raise on that? (if etags are not matching)

cachedir doesn't seem to refresh after invalidation, see:

// TODO: wing it for now. Dont know why it doesnt pick up refreshed entries after flushing

When calling flushdir at the end of rmdir I see the call for FindLeaf but the cachedir entries aren't updated.

@ncw
Copy link
Member

ncw commented Apr 5, 2024

@lostb1t

not sure what client_id you are referring to?

This one at the top of the source!

clientId      = "e9f98057fb916de2bbd755ef280d7257146a76e5118f27ab2e9a3d065c20c17e"

and no I haven't run any integration test yet. Will do when implemented all interfaces.

Running the integration tests will guide you through what you need to do. You can start running them as soon as you've done List.

fyi: so iCloud doesn't have functionality for updating/replacing files. At least not something I can find reverse engineering

So if a file exists I move it to iCloud trash. And upload a new version of the file. After successful upload the file is removed from trash or restored from trash if upload failed.

Seems OK!

how one handle folder invalidation? drive uses etags for files and folders. If a file or folder within a folder changes then the parent folders etag changes. This means I have to clear almost the whole tree from child to parent.
Not sure how to handle that in general, what if a users change it locally but file/folder has changed remotely in between. What error should I raise on that? (if etags are not matching)

Do you have to use the etags? They are optional for most cloud storage systems and rclone doesn't use them. This means that the last write wins which is what we want. If you can't ignore etags then refresh the etag and try again.

cachedir doesn't seem to refresh after invalidation, see:

// TODO: wing it for now. Dont know why it doesnt pick up refreshed entries after flushing

When calling flushdir at the end of rmdir I see the call for FindLeaf but the cachedir entries aren't updated.

Not sure!

@lostb1t
Copy link
Author

lostb1t commented Apr 5, 2024

@lostb1t

not sure what client_id you are referring to?

This one at the top of the source!

clientId      = "e9f98057fb916de2bbd755ef280d7257146a76e5118f27ab2e9a3d065c20c17e"

and no I haven't run any integration test yet. Will do when implemented all interfaces.

Running the integration tests will guide you through what you need to do. You can start running them as soon as you've done List.

fyi: so iCloud doesn't have functionality for updating/replacing files. At least not something I can find reverse engineering
So if a file exists I move it to iCloud trash. And upload a new version of the file. After successful upload the file is removed from trash or restored from trash if upload failed.

Seems OK!

how one handle folder invalidation? drive uses etags for files and folders. If a file or folder within a folder changes then the parent folders etag changes. This means I have to clear almost the whole tree from child to parent.
Not sure how to handle that in general, what if a users change it locally but file/folder has changed remotely in between. What error should I raise on that? (if etags are not matching)

Do you have to use the etags? They are optional for most cloud storage systems and rclone doesn't use them. This means that the last write wins which is what we want. If you can't ignore etags then refresh the etag and try again.

cachedir doesn't seem to refresh after invalidation, see:

// TODO: wing it for now. Dont know why it doesnt pick up refreshed entries after flushing

When calling flushdir at the end of rmdir I see the call for FindLeaf but the cachedir entries aren't updated.

Not sure!

etags are needed for file operations unfortunately, but I can just refresh it when it got stale.

the clientid is a static that icloud.com uses. So I reuse it to mimic the browser.

@lostb1t
Copy link
Author

lostb1t commented Apr 9, 2024

@ncw small question. iCloud Drive does not allow uploading empty files so check the size and raise ErrorCantUploadEmptyFiles when its 0

But when using macOS finder to copy a file, I get an partial file with zero length (while the actually file isn't empty)

Not sure howto handle this.

@ncw
Copy link
Member

ncw commented Apr 10, 2024

@lostb1t

small question. iCloud Drive does not allow uploading empty files so check the size and raise ErrorCantUploadEmptyFiles when its 0

That sounds correct.

But when using macOS finder to copy a file, I get an partial file with zero length (while the actually file isn't empty)

Are you using rclone mount in the finder?

So you are seeing a zero length file in the finder? I'm not sure what you mean by a partial file?

Can you reproduce this without the rclone mount? So using rclone copy? If so please paste your command line and the log with -vv.

@lostb1t
Copy link
Author

lostb1t commented Apr 11, 2024

Its slow but finished alle interfaces and all integration test are passing 🎉

Only documentation left before its ready for review.

@ncw
Copy link
Member

ncw commented Apr 13, 2024

Its slow but finished all interfaces and all integration test are passing 🎉

Well done!

You are running the full suite from test_all?

Only documentation left before its ready for review.

:-)

@epetousis
Copy link

@lostb1t not sure if it's too early for bug reports, but currently it looks like app folders aren't being represented as folders, but rather as files.

@lostb1t
Copy link
Author

lostb1t commented Apr 14, 2024

@lostb1t not sure if it's too early for bug reports, but currently it looks like app folders aren't being represented as folders, but rather as files.

bug reports are welcome. Will fix with the following pass, tnx

@lostb1t
Copy link
Author

lostb1t commented Apr 15, 2024

@epetousis this has been fixed

@lostb1t
Copy link
Author

lostb1t commented Apr 15, 2024

crap i broke my icloud. Too many trash items and now the endpoint is broken lol

the icloud web api is a mess

@lostb1t lostb1t changed the title backend: Add Apple iCloud (drive) backend backend: Add Apple iCloud Drive backend Apr 15, 2024
@epetousis
Copy link

Fix works great. Much appreciated!

@cyayon
Copy link

cyayon commented Apr 19, 2024

Hi,
I setup successfully and authentication seems ok, but I do not see any files or directories on my iCloud account.
I tried ls, lsl, lsd... no file.

thanks.

@lostb1t
Copy link
Author

lostb1t commented Apr 20, 2024

Hi,

I setup successfully and authentication seems ok, but I do not see any files or directories on my iCloud account.

I tried ls, lsl, lsd... no file.

thanks.

@cyayon Could you post a log from the command with the -vv flag (e.g. output from rclone -vv ls

@cyayon
Copy link

cyayon commented May 1, 2024

Great !

Another thing, I found the download very slow (about 1MB/s) for a large 3GB file.

When using Finder, the download speed is much higher (about 20MB/s).

Is there some reason ?

Thank you very much.

@lostb1t
Copy link
Author

lostb1t commented May 1, 2024

Great !

Another thing, I found the download very slow (about 1MB/s) for a large 3GB file.

When using Finder, the download speed is much higher (about 20MB/s).

Is there some reason ?

Thank you very much.

if you say finder so you mean apples native drive integration?

@cyayon
Copy link

cyayon commented May 1, 2024

Yes on macOS (and files.app on iOS).

@lostb1t
Copy link
Author

lostb1t commented May 1, 2024

different apis. Apple probaply using a private api we dont have access to. This uses the web api.

So if you want to compare use icloud.com, those speeds should
match with the rclone implementation

@cyayon
Copy link

cyayon commented May 1, 2024

I understand.
It is not really important as I use Rclone only for backup all my cloud storage accounts.
Thanks !

@hurryman2212
Copy link

With the current HEAD commit, I did rclone config with successful 2FA, and rclone mount iCloud: ~/iCloud/rclone ls iCloud:/rclone lsd iCloud: but the remote always shows nothing (0 items, Free space: 1.0PiB).

When I try to copy a non-zero-bytes file into it, when mounted, it says Cannot find PCS auth info from request:

./Sources/rclone/rclone mount --verbose iCloud: ~/iCloud
2024/05/09 20:21:54 INFO  : : poll-interval is not supported by this remote
2024/05/09 20:21:54 NOTICE: : --vfs-cache-mode writes or full is recommended for this remote as it can't stream
2024/05/09 20:22:00 NOTICE: Local file system at /tmp/rclone-spool480232071: --checksum is in use but the source and destination have no hashes in common; falling back to --size-only
2024/05/09 20:22:01 ERROR : 1.pdf: Failed to copy: GET https://p126-docws.icloud.com:443/ws/com.apple.CloudDocs/list/lookup_by_id?document_id=root&unified_format=false failed, status 400, err: HTTP error 400 (400 Bad Request) returned body: "{\n  \"uuid\" : \"9cdfa44c-a396-46a9-b175-fe5e4d414870\",\n  \"messageForDeveloper\" : \"Cannot find PCS auth info from request\",\n  \"error_code\" : \"InvalidRequestException\",\n  \"serverErrorCode\" : \"BAD_REQUEST\",\n  \"reason\" : \"Cannot find PCS auth info from request\"\n}"
2024/05/09 20:22:01 INFO  : 1.pdf: Deleted
2024/05/09 20:22:01 INFO  : Local file system at /tmp/rclone-spool480232071: Removing directory
2024/05/09 20:22:01 ERROR : 1.pdf: WriteFileHandle.New Rcat failed: GET https://p126-docws.icloud.com:443/ws/com.apple.CloudDocs/list/lookup_by_id?document_id=root&unified_format=false failed, status 400, err: HTTP error 400 (400 Bad Request) returned body: "{\n  \"uuid\" : \"9cdfa44c-a396-46a9-b175-fe5e4d414870\",\n  \"messageForDeveloper\" : \"Cannot find PCS auth info from request\",\n  \"error_code\" : \"InvalidRequestException\",\n  \"serverErrorCode\" : \"BAD_REQUEST\",\n  \"reason\" : \"Cannot find PCS auth info from request\"\n}"
2024/05/09 20:22:01 ERROR : 1.pdf: WriteFileHandle.Flush error: GET https://p126-docws.icloud.com:443/ws/com.apple.CloudDocs/list/lookup_by_id?document_id=root&unified_format=false failed, status 400, err: HTTP error 400 (400 Bad Request) returned body: "{\n  \"uuid\" : \"9cdfa44c-a396-46a9-b175-fe5e4d414870\",\n  \"messageForDeveloper\" : \"Cannot find PCS auth info from request\",\n  \"error_code\" : \"InvalidRequestException\",\n  \"serverErrorCode\" : \"BAD_REQUEST\",\n  \"reason\" : \"Cannot find PCS auth info from request\"\n}"
2024/05/09 20:22:01 ERROR : IO error: GET https://p126-docws.icloud.com:443/ws/com.apple.CloudDocs/list/lookup_by_id?document_id=root&unified_format=false failed, status 400, err: HTTP error 400 (400 Bad Request) returned body: "{\n  \"uuid\" : \"9cdfa44c-a396-46a9-b175-fe5e4d414870\",\n  \"messageForDeveloper\" : \"Cannot find PCS auth info from request\",\n  \"error_code\" : \"InvalidRequestException\",\n  \"serverErrorCode\" : \"BAD_REQUEST\",\n  \"reason\" : \"Cannot find PCS auth info from request\"\n}"
2024/05/09 20:22:01 ERROR : IO error: can't open file - writer failed
2024/05/09 20:22:01 ERROR : IO error: can't open file - writer failed

ENV: Xubuntu 24.04 (6.8.0-31-generic)

@lostb1t
Copy link
Author

lostb1t commented May 9, 2024

@hurryman2212 > do you maybe have advanced data protection enabled? thats currently not supported and need to be disabled.

@hurryman2212
Copy link

hurryman2212 commented May 9, 2024

@hurryman2212 > do you maybe have advanced data protection enabled? thats currently not supported and need to be disabled.

It has been almost a year since they introduced it and I enabled it, I think, so I have completely forgotten about it.. Thank you!

Indeed, it was due to ADP. Now, it is working fine, although performance-wise, there are some issues as @cyayon reported. On my environment, ls on each sub-directory initially after mount is very slow, so --vfs-cache-mode write|full is definitely needed here.

@cyayon
Copy link

cyayon commented May 20, 2024

Hi,
Today, I had to refresh 2FA authentication manually (rclone config, edit, re-enter 2FA code).

Is it normal ? I thank that it will be done without human interaction.

Thanks.

@lostb1t
Copy link
Author

lostb1t commented May 29, 2024

@cyayon it should selfrenew. Could you send me the log when this occurs again?

@cyayon
Copy link

cyayon commented May 29, 2024

@cyayon it should selfrenew. Could you send me the log when this occurs again?

Hi,

Here is a log :

2024/05/24 19:40:14 DEBUG : rclone: Version "v1.67.0-DEV" starting with parameters ["/opt/rclone/rclone-icloud" "sync" "--config" "/etc/rclone/rclone.conf" "-x" "--local-no-check-updated" "--progress" "-vv" "--suffix=.BackupMGR_3274985_2024-05-24-19:40" " "icloud_xxx:/Documents" "[/mnt/datas/cloud/users/lya/iCloud/xxxx](mailto:%2Fmnt%2Fdatas%2Fcloud%2Fusers%2Flya%2Ficloud%2Fxxxx)/Documents"]
2024/05/24 19:40:14 DEBUG : Creating backend with remote "icloud_xxxx:/Documents"
2024/05/24 19:40:14 DEBUG : Using config file from "/etc/rclone/rclone.conf"
2024/05/24 19:40:15 DEBUG : icloud: Authenticating as [xxxx](mailto:xxx)
2024/05/24 19:40:16 DEBUG : Saving config "cookies" in section "icloud_xxxx" of the config file
2024/05/24 19:40:16 DEBUG : Keeping previous permissions for config file: -r--r-----
2024/05/24 19:40:16 DEBUG : fs cache: renaming cache item "icloud_xxxx:/Documents" to be canonical "icloud_xxxx:Documents"
2024/05/24 19:40:16 DEBUG : Creating backend with remote "[/mnt/datas/cloud/users/lya/iCloud/xxxx](mailto:%2Fmnt%2Fdatas%2Fcloud%2Fusers%2Flya%2Ficloud%2Fxxxx)/Documents"
2024/05/24 19:40:16 DEBUG : local: detected overridden config - adding "{RZq88}" suffix to name
2024/05/24 19:40:16 DEBUG : fs cache: renaming cache item "[/mnt/datas/cloud/users/lya/iCloud/xxxx](mailto:%2Fmnt%2Fdatas%2Fcloud%2Fusers%2Flya%2Ficloud%2Fxxx)/Documents" to be canonical "local{RZq88}:[/mnt/datas/cloud/users/lya/iCloud/xxxx](mailto:%2Fmnt%2Fdatas%2Fcloud%2Fusers%2Flya%2Ficloud%2Fxxx/Documents"

2024/05/24 19:40:16 ERROR : Documents: error reading source root directory: directory not found
Transferred:   	          0 B / 0 B, -, 0 B/s, ETA -
Elapsed time:         1.9s

@cyayon
Copy link

cyayon commented Jun 6, 2024

Hi,

Same issue today.

/opt/rclone/rclone-icloud ls --config /etc/rclone/rclone.conf -vvvv 'icloud_xxx:/'
2024/06/06 14:13:20 DEBUG : rclone: Version "v1.67.0-DEV" starting with parameters ["/opt/rclone/rclone-icloud" "ls" "--config" "/etc/rclone/rclone.conf" "-vvvv" "icloud_xxxx:/"]
2024/06/06 14:13:20 DEBUG : Creating backend with remote "icloud_sxxx:/"
2024/06/06 14:13:20 DEBUG : Using config file from "/etc/rclone/rclone.conf"
2024/06/06 14:13:20 DEBUG : icloud: Authenticating as xxxx
2024/06/06 14:13:21 DEBUG : Saving config "cookies" in section "icloud_xxx" of the config file
2024/06/06 14:13:21 DEBUG : Keeping previous permissions for config file: -r--r-----
2024/06/06 14:13:21 DEBUG : fs cache: renaming cache item "icloud_xxx:/" to be canonical "icloud_xxx:"
2024/06/06 14:13:22 DEBUG : 10 go routines active

I have to refresh token and 2FA again...

@fcrespo82
Copy link

Hi @lostb1t I was trying to test it and got this error

2024/06/19 11:58:54 Fatal error: POST https://setup.icloud.com/setup/ws/1/accountLogin failed, status 400, err: HTTP error 400 (400 Bad Request) returned body: "{"success":false,"error":"Invalid Session Token"}"

How can I debug it? And how can I help in the project overall?

@lostb1t
Copy link
Author

lostb1t commented Jun 19, 2024

Hi @lostb1t I was trying to test it and got this error

2024/06/19 11:58:54 Fatal error: POST https://setup.icloud.com/setup/ws/1/accountLogin failed, status 400, err: HTTP error 400 (400 Bad Request) returned body: "{"success":false,"error":"Invalid Session Token"}"

How can I debug it? And how can I help in the project overall?

did you run the config succesfully? (2fa)

@fcrespo82
Copy link

fcrespo82 commented Jun 19, 2024

Hi @lostb1t I was trying to test it and got this error

2024/06/19 11:58:54 Fatal error: POST https://setup.icloud.com/setup/ws/1/accountLogin failed, status 400, err: HTTP error 400 (400 Bad Request) returned body: "{"success":false,"error":"Invalid Session Token"}"

How can I debug it? And how can I help in the project overall?

did you run the config succesfully? (2fa)

This happened when trying to create the remote. Below is the attempt to create the remote. It never asked for the 2fa and no code was sent to my device.

❯ ./rclone config -vvv
2024/06/19 16:21:48 DEBUG : rclone: Version "v1.67.0-beta.7874.d2259ab8d.feature/icloud" starting with parameters ["./rclone" "config" "-vvv"]
2024/06/19 16:21:48 DEBUG : Using config file from "/home/fernando/.config/rclone/rclone.conf"
Current remotes:

Name                 Type
====                 ====
OneDrive             onedrive

e) Edit existing remote
n) New remote
d) Delete remote
r) Rename remote
c) Copy remote
s) Set configuration password
q) Quit config
e/n/d/r/c/s/q> n

Enter name for new remote.
name> iCloudDrive

Option Storage.
Type of storage to configure.
Choose a number from below, or type in your own value.
...
55 / iCloud Drive
   \ (iclouddrive)
...
Storage> 55

2024/06/19 16:22:03 DEBUG : iCloudDrive: config in: state="*all", result=""
2024/06/19 16:22:03 DEBUG : iCloudDrive: config out: out=&{State:*all-set,0,false Option: OAuth:<nil> Error: Result:}, err=<nil>
2024/06/19 16:22:03 DEBUG : iCloudDrive: config: reading config parameter "apple_id"
Option apple_id.
Apple ID.
Enter a value.
apple_id> [email protected]

2024/06/19 16:22:13 DEBUG : iCloudDrive: config in: state="*all-set,0,false", result="[email protected]"
2024/06/19 16:22:13 DEBUG : Saving config "apple_id" in section "iCloudDrive" of the config file
2024/06/19 16:22:13 DEBUG : iCloudDrive: config out: out=&{State:*all,1,false Option:<nil> OAuth:<nil> Error: Result:}, err=<nil>
2024/06/19 16:22:13 DEBUG : iCloudDrive: config in: state="*all,1,false", result=""
2024/06/19 16:22:13 DEBUG : iCloudDrive: config out: out=&{State:*all-set,1,false Option: OAuth:<nil> Error: Result:}, err=<nil>
2024/06/19 16:22:13 DEBUG : iCloudDrive: config: reading config parameter "password"
Option password.
Password.
Choose an alternative below. Press Enter for the default (n).
y) Yes, type in my own password
g) Generate random password
n) No, leave this optional password blank (default)
y/g/n> 

2024/06/19 16:22:18 DEBUG : iCloudDrive: config in: state="*all-set,1,false", result=""
2024/06/19 16:22:18 DEBUG : iCloudDrive: config out: out=&{State:*all,2,false Option:<nil> OAuth:<nil> Error: Result:}, err=<nil>
2024/06/19 16:22:18 DEBUG : iCloudDrive: config in: state="*all,2,false", result=""
2024/06/19 16:22:18 DEBUG : iCloudDrive: config out: out=&{State:*all,3,false Option:<nil> OAuth:<nil> Error: Result:}, err=<nil>
2024/06/19 16:22:18 DEBUG : iCloudDrive: config in: state="*all,3,false", result=""
2024/06/19 16:22:18 DEBUG : iCloudDrive: config out: out=&{State:*all,4,false Option:<nil> OAuth:<nil> Error: Result:}, err=<nil>
2024/06/19 16:22:18 DEBUG : iCloudDrive: config in: state="*all,4,false", result=""
2024/06/19 16:22:18 DEBUG : iCloudDrive: config out: out=&{State:*all,5,false Option:<nil> OAuth:<nil> Error: Result:}, err=<nil>
2024/06/19 16:22:18 DEBUG : iCloudDrive: config in: state="*all,5,false", result=""
2024/06/19 16:22:18 DEBUG : iCloudDrive: config out: out=&{State:*all,6,false Option:<nil> OAuth:<nil> Error: Result:}, err=<nil>
2024/06/19 16:22:18 DEBUG : iCloudDrive: config in: state="*all,6,false", result=""
2024/06/19 16:22:18 DEBUG : iCloudDrive: config out: out=&{State:*all-advanced Option:false OAuth:<nil> Error: Result:}, err=<nil>
2024/06/19 16:22:18 DEBUG : iCloudDrive: config: reading config parameter "config_fs_advanced"
Edit advanced config?
y) Yes
n) No (default)
y/n> 

2024/06/19 16:22:39 DEBUG : iCloudDrive: config in: state="*all-advanced", result="false"
2024/06/19 16:22:39 DEBUG : iCloudDrive: config out: out=&{State:*postconfig Option:<nil> OAuth:<nil> Error: Result:}, err=<nil>
2024/06/19 16:22:39 DEBUG : iCloudDrive: config in: state="*postconfig", result=""
2024/06/19 16:22:39 DEBUG : iCloudDrive: config in: state="", result=""
2024/06/19 16:22:39 DEBUG : iCloudDrive: config out: out=&{State:password Option: OAuth:<nil> Error: Result:}, err=<nil>
2024/06/19 16:22:39 DEBUG : iCloudDrive: config out: out=&{State:password Option: OAuth:<nil> Error: Result:}, err=<nil>
2024/06/19 16:22:39 DEBUG : iCloudDrive: config: reading config parameter "config_password"
Option config_password.
Two-factor authentication: please enter your password (it won't be saved in the configuration)
Choose an alternative below. Press Enter for the default (n).
y) Yes, type in my own password
g) Generate random password
n) No, leave this optional password blank (default)
y/g/n> y
Enter the password:
password:
Confirm the password:
password:

2024/06/19 16:23:54 DEBUG : iCloudDrive: config in: state="password", result="[REDACTED]"
2024/06/19 16:23:54 DEBUG : Saving config "password" in section "iCloudDrive" of the config file
2024/06/19 16:23:54 DEBUG : iCloudDrive: config out: out=&{State:authenticate Option:<nil> OAuth:<nil> Error: Result:}, err=<nil>
2024/06/19 16:23:54 DEBUG : iCloudDrive: config in: state="authenticate", result=""
2024/06/19 16:23:54 DEBUG : icloud: Authenticating as [email protected]
2024/06/19 16:23:55 DEBUG : iCloudDrive: config out: out=<nil>, err=POST https://setup.icloud.com/setup/ws/1/accountLogin failed, status 400, err: HTTP error 400 (400 Bad Request) returned body: "{\"success\":false,\"error\":\"Invalid Session Token\"}"
Error: POST https://setup.icloud.com/setup/ws/1/accountLogin failed, status 400, err: HTTP error 400 (400 Bad Request) returned body: "{\"success\":false,\"error\":\"Invalid Session Token\"}"
Usage:
  rclone config [flags]
  rclone config [command]

Available Commands:
  create      Create a new remote with name, type and options.
  delete      Delete an existing remote.
  disconnect  Disconnects user from remote
  dump        Dump the config file as JSON.
  edit        Enter an interactive configuration session.
  file        Show path of configuration file in use.
  password    Update password in an existing remote.
  paths       Show paths used for configuration, cache, temp etc.
  providers   List in JSON format all the providers and options.
  reconnect   Re-authenticates user with remote.
  redacted    Print redacted (decrypted) config file, or the redacted config for a single remote.
  show        Print (decrypted) config file, or the config for a single remote.
  touch       Ensure configuration file exists.
  update      Update options in an existing remote.
  userinfo    Prints info about logged in user of remote.

Flags:
  -h, --help   help for config

Use "rclone [command] --help" for more information about a command.
Use "rclone help flags" for to see the global flags.
Use "rclone help backends" for a list of supported services.

2024/06/19 16:23:55 Fatal error: POST https://setup.icloud.com/setup/ws/1/accountLogin failed, status 400, err: HTTP error 400 (400 Bad Request) returned body: "{\"success\":false,\"error\":\"Invalid Session Token\"}"

@lostb1t
Copy link
Author

lostb1t commented Jun 20, 2024

Make sure 2fa is enabled on your account. I made the password required just now, could you pull the changes and try again?

@lostb1t
Copy link
Author

lostb1t commented Jun 20, 2024

Hi,

Same issue today.


/opt/rclone/rclone-icloud ls --config /etc/rclone/rclone.conf -vvvv 'icloud_xxx:/'

2024/06/06 14:13:20 DEBUG : rclone: Version "v1.67.0-DEV" starting with parameters ["/opt/rclone/rclone-icloud" "ls" "--config" "/etc/rclone/rclone.conf" "-vvvv" "icloud_xxxx:/"]

2024/06/06 14:13:20 DEBUG : Creating backend with remote "icloud_sxxx:/"

2024/06/06 14:13:20 DEBUG : Using config file from "/etc/rclone/rclone.conf"

2024/06/06 14:13:20 DEBUG : icloud: Authenticating as xxxx

2024/06/06 14:13:21 DEBUG : Saving config "cookies" in section "icloud_xxx" of the config file

2024/06/06 14:13:21 DEBUG : Keeping previous permissions for config file: -r--r-----

2024/06/06 14:13:21 DEBUG : fs cache: renaming cache item "icloud_xxx:/" to be canonical "icloud_xxx:"

2024/06/06 14:13:22 DEBUG : 10 go routines active

I have to refresh token and 2FA again...

Seems something not going right when reauthenticating. Not sure why on first glance. Cookies are
refreshed but seems something else is off. Will have to find some time to dig in.

@fcrespo82
Copy link

Make sure 2fa is enabled on your account. I made the password required just now, could you pull the changes and try again?

Yes, I had 2fa setup in my account.

And yes, the change made it work, it was a couple of things that made it not work.

  1. My account was, for some reason, blocked; and
  2. I wasn't putting my password on the first field.

I successfully mounted the drive and now will use it an make some tests. If anything goes wrong, I'll report it back.

Thank you very much for this rClone backend!

I am recently migrating to Linux after the hole Microsoft Recall fiasco, and I rely some of my daily workflow on iCloud, this was the missing piece for the migration.

PS: Do you have GitHub sponsor, ko-fi, ...?

@lostb1t
Copy link
Author

lostb1t commented Jun 20, 2024

k this sucks but it seems the trust token is only valid for 30 days. After that it has to be renewed with an MFA code.... not ... ideal...

im open to suggestions on howto handle this the least intrusive way

@cyayon
Copy link

cyayon commented Jun 20, 2024

Hi,

It seems that the other GitHub project icloud_photos_downloader have also the same issue.

I am using this while waiting for native rclone support for iCloud photo (backup). And each 30 days (I think) I have to renew with MFA (for me, my wife and son...)

I will ask ask directly on this other GitHub project if there is a solution. I will post here the issue link.

@cyayon
Copy link

cyayon commented Jun 20, 2024

@cyayon
Copy link

cyayon commented Jun 20, 2024

An idea here (not great) : boredazfcuk/docker-icloudpd#524
Another (not great too) : icloud-photos-downloader/icloud_photos_downloader#803 (comment)

Another solution could be to add WebUI for password/MFA : icloud-photos-downloader/icloud_photos_downloader#805 to be able to renew directly on rclone without the need of an apple device...

@byte-bandit
Copy link

I spent a few minutes debugging the "iCloud Drive" app for Windows, and it looks like they're using gRPC & protobuf in those. Unfortunately my reverse engineering skills are pretty limited, but maybe it's worth pursuing this in the future to improve the performance and speed here.

@lostb1t
Copy link
Author

lostb1t commented Jun 25, 2024

I spent a few minutes debugging the "iCloud Drive" app for Windows, and it looks like they're using gRPC & protobuf in those. Unfortunately my reverse engineering skills are pretty limited, but maybe it's worth pursuing this in the future to improve the performance and speed here.

Apple uses SSL pinning so its unfortunately impossible to reverse engineer it with a MITM.

The only way this was possible
is because of the icloud web app which can be reverse engineered as the https connection is terminated by the browser and not a private app

@byte-bandit
Copy link

I spent a few minutes debugging the "iCloud Drive" app for Windows, and it looks like they're using gRPC & protobuf in those. Unfortunately my reverse engineering skills are pretty limited, but maybe it's worth pursuing this in the future to improve the performance and speed here.

Apple uses SSL pinning so its unfortunately impossible to reverse engineer it with a MITM.

The only way this was possible is because of the icloud web app which can be reverse engineered as the https connection is terminated by the browser and not a private app

I think by using something like IDA to inspect actual control flow it might be possible to reverse engineer the protocol from the binary, but it's very tedious and definitely above my experience with this. Just leaving it for inspiration.

@fcrespo82
Copy link

Hi, it's me again. I'm trying this integration, and it is in a good working condition with minor hiccups.

I don't know if i did something wrong, but now I'm getting errors when trying to sync.

Here is the log rclone-iCloudDrive.log

One specific folder is not able to send files, but all my iCloud is not seeing changes that I make on other locations.

What can I do to help debug this?

@lostb1t
Copy link
Author

lostb1t commented Jun 30, 2024

@fcrespo82 can you post your mount command

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

9 participants