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

功能请求:将 --no-check-certificate 添加为可选开关,以绕过证书验证 #119

Closed
lidawei97688 opened this issue Jan 13, 2025 · 5 comments · Fixed by #120
Closed
Assignees

Comments

@lidawei97688
Copy link

我正在使用的一些webdav正在使用自己制作的自签名证书,而且也已经将根证书和中间证书安装到了安卓手机里,但是RSAF似乎并不会去读取根证书,以至于没办法以RSAF使用自签名证书的webdav服务,希望能添加--no-check-certificate到可选开关里(rclone lsd myWebDAVsNAS: --no-check-certificate),这样就能使用自己的webdav服务了
Screenshot_2025-01-13-23-09-55-035_com google android documentsui

@chenxiaolong chenxiaolong self-assigned this Jan 13, 2025
@chenxiaolong
Copy link
Owner

Thanks for the suggestion. I will take a look after work today and see if I can add support for loading certificates from Android's user trust store.

@chenxiaolong
Copy link
Owner

It looks like user certificates are not working because the underlying golang TLS implementation uses the wrong certificate directories on Android. I've reported a bug here: golang/go#71258

I'll see if I can find a workaround.

chenxiaolong added a commit that referenced this issue Jan 14, 2025
golang does not support Android's various trust stores well. The CA
certificates in /system/etc/security/cacerts are the only ones that are
properly read. The updatable apex trust store in Android 14+ and the
user trust store are ignored. System CA certificates that the user
disables are still permitted to be used.

This commit implements our own certificate loading mechanism that loads
from all of Android's trust stores and respects disabled certificates.
We generate a combined PEM file in a temp file and feed that to rclone's
CaCert option.

While live reloading is supported, the user experience is not that
great. Due to rclone's caching, when certificates are reloaded, they
only take effect in new remotes. The user will need to delete and
recreate the remote, export and reimport, or force close RSAF.

Fixes: #119

Signed-off-by: Andrew Gunnerson <accounts+github@chiller3.com>
@chenxiaolong
Copy link
Owner

Please give #120 a try. Test build:

RSAF should now work with CA certificates imported in Android's settings. NOTE: If you add or remove a certificate while RSAF is already running, you will need to force close RSAF to reload the certificates.

@lidawei97688
Copy link
Author

Please give #120 a try. Test build:请尝试 #120 。测试版本:

RSAF should now work with CA certificates imported in Android's settings. NOTE: If you add or remove a certificate while RSAF is already running, you will need to force close RSAF to reload the certificates.RSAF 现在应该可以与在 Android 设置中导入的 CA 证书一起使用。注意:如果 RSAF 已经运行时你添加或移除了一个证书,你需要强制关闭 RSAF 以重新加载证书。

It's OK👍
Screenshot_2025-01-14-13-07-23-112_com google android documentsui

@chenxiaolong
Copy link
Owner

Great, thanks for testing! I will release version 3.1 with the fix tomorrow.

chenxiaolong added a commit that referenced this issue Jan 16, 2025
The initial implementation of loading Android's CA trust stores wrote
the certificates to a temporary file and then passed them to rclone via
the CaCert config option. This would only get loaded when a new backend
Fs instance was created. If the backend was already created, the user
would need to delete and recreate the remote or force quit RSAF, which
is a terrible user experience.

Unfortunately, reloading by recreating the Fs and VFS instances would
not provide a good experience either. The VFS would need to be shut
down, interrupting VFS writeback, and we need to wait for the garbage
collector to clean up the VFS instance so that the corresponding Fs
instance would be unpinned from the cache. This precludes the CA
reloading process from being automatic.

Instead, this commit makes use of a per-request hook to set the trusted
CA certificates on every connection. This requires a soft-fork of rclone
to add a hook point to fshttp.(*Transport).RoundTrip(). The patch is
extremely simple and is easy to port to future versions of rclone. No
other patches will be added to the fork and I plan to switch back to the
upstream version if another good solution is found, even if hacky.

Some other approaches I tried or considered:

* Replace fshttp.isCertificateExpired() using go:linkname and in the
  replacement, update the tls.Config.RootCAs in addition to executing a
  copy of the original code. This function would be called during each
  RoundTrip() invocation. This approach does not work with how gomobile
  builds rcbridge as a library and causes duplicate symbol errors during
  linking.
* Add the code as is done in this commit, except via a -toolexec program
  that preprocesses the AST of the go sources. This approach does not
  work because -toolexec is not invoked at the necessary points when
  compiling with gomobile.
* Patch fshttp.isCertificateExpired() at runtime by inserting a jump
  call to our own implementation. This is error prone, requires specific
  assembly code for each CPU architecture, and does not work if the
  function we want to patch was inlined.

This commit also fixes a bug where a remote's Fs instance is not
properly removed from rclone's cache when deleting the remote.

Issue: #119

Signed-off-by: Andrew Gunnerson <accounts+github@chiller3.com>
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 a pull request may close this issue.

2 participants