Compare commits

...

512 Commits

Author SHA1 Message Date
Zack 50e0f625bc v10.0.7 2024-05-31 14:32:59 -07:00
Zack 94af2374c3 Merge branch 'main' of github.com:schollz/croc 2024-05-31 14:32:03 -07:00
Zack a4322faa25 ui: add newlines to skipping messages 2024-05-31 14:31:46 -07:00
Zack 23dce2aa3e
Merge pull request #724 from schollz:schollz/issue723
fix: receiver needs to exit without initializing files if no files being transfered
2024-05-31 11:45:51 -07:00
Zack 88002b322d fix: receiver needs to exit without initializing files if no files being transfered 2024-05-31 11:44:56 -07:00
Zack 9246408278 for valid filename tests 2024-05-30 15:21:51 -07:00
Zack fbf1eeedce v10.0.6 2024-05-28 16:24:29 -07:00
Zack e4c9f2d9fb
Merge pull request #721 from schollz:schollz/issue720
show hash progress on large files
2024-05-28 16:21:45 -07:00
Zack c0c3370d9b add highway hash 2024-05-28 16:19:38 -07:00
Zack f6bd13fa06 show hash progress on large files 2024-05-28 16:08:31 -07:00
Zack Scholl f83616e9bd readme: remove coverage badge 2024-05-26 11:37:03 -07:00
Zack Scholl 23f385ab2f readme: update badge for CI 2024-05-26 11:35:54 -07:00
Zack Scholl 78feb393de fix println warnings 2024-05-26 11:33:21 -07:00
Zack 69fc3cee47 v10.0.5 2024-05-26 07:58:08 -07:00
Zack a5da77cf49
Merge pull request #717 from schollz:schollz/issue716
new: add flag `--classic` with warning for passing shared secret on single-user systems
2024-05-26 07:55:31 -07:00
Zack f66e17dd46 add the checks for the classic insecure mode 2024-05-26 07:54:37 -07:00
Zack 63c9201938 new: add flag with warning for passing shared secret on single-user systems 2024-05-26 07:52:12 -07:00
Zack ca7a5979cc need environmental variable on all unix systems 2024-05-26 07:20:48 -07:00
Zack fc457557e0 v10.0.4 2024-05-25 09:02:34 -07:00
Zack f044f4dd86
Merge pull request #713 from schollz:schollz/issue712
escape filenames that have invisible characters while allowing other languages
2024-05-25 09:00:36 -07:00
Zack a2e71c7e1a escape filenames that have invisible characters while allowing other languages
Fixes #712
2024-05-25 08:59:38 -07:00
Zack dff34fa7fc fix comment 2024-05-24 19:44:28 -07:00
Zack Scholl 08103bb7bb v10.0.3 2024-05-24 18:04:29 -07:00
Zack Scholl 4091ef0496 fix: remove hash extra 2024-05-24 18:03:51 -07:00
Zack 381f8369a3 update bug report 2024-05-23 09:49:18 -07:00
Zack a95d67e31c v10.0.2 2024-05-23 09:47:15 -07:00
Zack b0920bbe70
Merge pull request #708 from schollz/fix10
fix message passing for initial secure layer
2024-05-23 09:46:40 -07:00
Zack ed55c746c2 fix message passing for initial secure layer 2024-05-23 09:44:34 -07:00
Zack 8e10eac5c5 fix 2024-05-23 09:34:17 -07:00
Zack 43f1c53538 v10.0.1 2024-05-23 08:35:56 -07:00
Zack 3acac5d53b
Merge pull request #707 from schollz:schollz/issue706
ux: improve the environmental variable messaging for sending/receiving
2024-05-23 08:34:52 -07:00
Zack 66f0d1264a improve the ux around sending 2024-05-23 08:33:00 -07:00
Zack ee713c5146 improve ux around receiving 2024-05-23 08:27:52 -07:00
Zack 6181903c83 go.mod v9 -> v10 2024-05-23 06:25:53 -07:00
Zack 7acd2def69 version bump for breaking change 2024-05-23 06:15:03 -07:00
Zack eb0909033e reduce description lengths 2024-05-22 10:10:55 -07:00
Zack f6d862eac0 bump version 2024-05-20 12:08:57 -07:00
Zack 5a6005f1eb bump version 2024-05-20 12:08:45 -07:00
Zack f6633cbac9
Merge pull request #702 from schollz:schollz/issue599
chore: improve efficiency and remove extraneous reads
2024-05-20 10:39:49 -07:00
Zack d8ef7cda20 chore: improve efficiency and remove extraneous reads 2024-05-20 10:39:22 -07:00
Zack 7622e636e4 fix: refactor gathering ips 2024-05-20 10:16:37 -07:00
Zack bb018fd725 fix: address shared secret before creatgin 2024-05-20 10:16:02 -07:00
Zack 863dabb93a
Merge pull request #701 from schollz/issue598
fix: shared secret should be read from environmental variable
2024-05-20 09:53:39 -07:00
Zack 6f5f16aa1c
Merge pull request #700 from schollz/issue597
fix: establish encryption layer before transfering ip information
2024-05-20 09:53:31 -07:00
Zack 0f1ca436cd
Merge pull request #699 from schollz/issue596
fix: use more secure shared secret as room name
2024-05-20 09:53:17 -07:00
Zack 4929635eb8
Merge pull request #698 from schollz/schollz/issue594
fix: prompt for overwriting when unzipping
2024-05-20 09:53:09 -07:00
Zack 3f12f75fae
Merge pull request #697 from schollz/issue593
fix: client quits when discovering dangerous paths
2024-05-20 09:52:58 -07:00
Zack e255d472a6 fix: shared secret should be read from environmental variable 2024-05-20 09:46:38 -07:00
Zack 2ffd4daeaf fix: establish encryption layer before transfering ip information 2024-05-20 09:37:42 -07:00
Zack accb310337 ignore 2024-05-20 09:11:08 -07:00
Zack 2b4c088100 fix: use more secure shared secret as room name 2024-05-20 09:08:10 -07:00
Zack a591833dbf fix: filter escape sequences in filenames 2024-05-20 08:38:36 -07:00
Zack b3668a6f5c fix: prompt for overwriting when unzipping 2024-05-20 08:31:47 -07:00
Zack b05c3c8c42 fix: client quits when discovering dangerous paths 2024-05-20 08:23:21 -07:00
Zack 13bc190f8b ignore big file 2024-05-20 08:08:38 -07:00
Zack 1b90484bb8 chore: update dependencies 2024-05-20 06:08:20 -07:00
Zack Scholl 05359d6976 update deps 2024-05-12 16:15:52 +00:00
Zack Scholl cc4d74c490 Merge branch 'main' of github.com:schollz/croc 2024-04-06 16:45:03 +00:00
Zack d81116382f bump version to 9.6.15 2024-04-06 09:44:08 -07:00
Zack Scholl 94cc880568 Merge branch 'main' of github.com:schollz/croc 2024-04-06 16:44:02 +00:00
Zack 24b907f4bb chore: update deps 2024-04-06 09:43:27 -07:00
Zack Scholl 8166b2dbed Merge branch 'main' of github.com:schollz/croc 2024-04-05 21:39:02 +00:00
Zack 14187f6f30
Merge pull request #688 from schollz/dependabot/go_modules/golang.org/x/crypto-0.22.0
Bump golang.org/x/crypto from 0.21.0 to 0.22.0
2024-04-05 14:38:56 -07:00
dependabot[bot] 90682d3ebd
Bump golang.org/x/crypto from 0.21.0 to 0.22.0
Bumps [golang.org/x/crypto](https://github.com/golang/crypto) from 0.21.0 to 0.22.0.
- [Commits](https://github.com/golang/crypto/compare/v0.21.0...v0.22.0)

---
updated-dependencies:
- dependency-name: golang.org/x/crypto
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-04-05 08:21:46 +00:00
Zack Scholl f4057aa28b Merge branch 'main' of github.com:schollz/croc 2024-04-04 18:31:02 +00:00
Zack 3c2548aa69
Merge pull request #687 from schollz/dependabot/go_modules/golang.org/x/net-0.23.0
Bump golang.org/x/net from 0.22.0 to 0.23.0
2024-04-04 11:30:06 -07:00
dependabot[bot] 7bab9c3cb5
Bump golang.org/x/net from 0.22.0 to 0.23.0
Bumps [golang.org/x/net](https://github.com/golang/net) from 0.22.0 to 0.23.0.
- [Commits](https://github.com/golang/net/compare/v0.22.0...v0.23.0)

---
updated-dependencies:
- dependency-name: golang.org/x/net
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-04-04 08:06:47 +00:00
Zack Scholl 355628f895 Merge branch 'main' of github.com:schollz/croc 2024-04-01 19:29:03 +00:00
Zack eaffc6dcac
Merge pull request #686 from a1lu/readonly
Avoid to create config dir if not required
2024-04-01 12:28:36 -07:00
a1lu 4baec420c8 Aovoid to create config dir if not required
If `--remember` is not set, the config dir should not created.
2024-04-01 13:39:04 +02:00
a1lu cd89e8043f Introduce var doRemember in cli receive function 2024-04-01 13:15:50 +02:00
Zack Scholl 1324ff8897 Merge branch 'main' of github.com:schollz/croc 2024-03-31 19:11:02 +00:00
Zack 8bc7a62b9e
Merge pull request #683 from a1lu/patch-1
Support spaces in 4 word codes
2024-03-31 12:10:32 -07:00
Zack Scholl 0c49ac3f02 Merge branch 'main' of github.com:schollz/croc 2024-03-31 19:09:02 +00:00
Zack 8b4ab4c86c
Merge pull request #685 from a1lu/config_files
Gracefully handle non existend receive config file
2024-03-31 12:08:50 -07:00
Zack Scholl f8f69e3157 Merge branch 'main' of github.com:schollz/croc 2024-03-31 19:08:03 +00:00
Zack 4e75e131c4
Merge pull request #682 from vihu/rg/update-error-message
Update error message to be more verbose
2024-03-31 12:07:45 -07:00
a1lu e599e56415 Gracefully handle non existend receive config file
If croc shall not remember the config, it should not exit if the config
file could not be opened. This is similar to the handling of the send
config.
2024-03-31 00:08:12 +01:00
a1lu 956598c427 Check $HOME as last 2024-03-30 23:24:52 +01:00
a1lu 618ae1e5d0
Support spaces in 4 word codes
Since the code was extended by the 4 digit block, the patch from https://github.com/schollz/croc/pull/198 did not work anymore.
2024-03-30 22:58:16 +01:00
Zack Scholl 7763a971f2 Merge branch 'main' of github.com:schollz/croc 2024-03-30 18:49:02 +00:00
Zack d2b7c80369 chore: update dependencies 2024-03-30 11:48:03 -07:00
Rahul Garg 241176d8a4
Update error message to be more verbose
Summary
----
This changes the error message (when connecting to an unavailble
channel) like so:

before:

```
$ croc 6764-jimmy-hilton-inside
securing channel...2024/03/28 17:16:25 room not ready
```

after:

```
$ ./croc 6764-jimmy-hilton-inside
securing channel...2024/03/28 17:16:12 room (secure channel) not ready, maybe peer disconnected
```
2024-03-28 17:16:01 -06:00
Zack Scholl 719f9b62c9 Merge branch 'main' of github.com:schollz/croc 2024-03-11 22:51:03 +00:00
Zack Scholl 483c5255bb chore: bump version to 9.6.14 2024-03-11 15:50:04 -07:00
Zack Scholl 03e6dcd220 Merge branch 'main' of github.com:schollz/croc 2024-03-11 22:50:02 +00:00
Zack Scholl 22ddbd83c2 chore: update deps 2024-03-11 15:49:09 -07:00
Zack Scholl 6b930c365b Merge branch 'main' of github.com:schollz/croc 2024-03-11 22:49:03 +00:00
Zack 1f6851f33b
Merge pull request #680 from schollz/dependabot/github_actions/softprops/action-gh-release-2
Bump softprops/action-gh-release from 1 to 2
2024-03-11 15:48:20 -07:00
Zack 61224b4e6b
Merge pull request #678 from schollz/dependabot/go_modules/github.com/stretchr/testify-1.9.0
Bump github.com/stretchr/testify from 1.8.2 to 1.9.0
2024-03-11 15:48:07 -07:00
Zack Scholl 6f2771e7b5 Merge branch 'main' of github.com:schollz/croc 2024-03-11 13:46:03 +00:00
Zack c21beccb7a
Merge pull request #679 from bitraid/fix-win-build
Fix Windows builds
2024-03-11 06:45:41 -07:00
dependabot[bot] 40f5e9ca1e
Bump softprops/action-gh-release from 1 to 2
Bumps [softprops/action-gh-release](https://github.com/softprops/action-gh-release) from 1 to 2.
- [Release notes](https://github.com/softprops/action-gh-release/releases)
- [Changelog](https://github.com/softprops/action-gh-release/blob/master/CHANGELOG.md)
- [Commits](https://github.com/softprops/action-gh-release/compare/v1...v2)

---
updated-dependencies:
- dependency-name: softprops/action-gh-release
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-03-11 08:56:10 +00:00
bitraid ed8c0475bf
Fix Windows builds 2024-03-09 22:31:27 +02:00
dependabot[bot] d7d7d3c8dc
Bump github.com/stretchr/testify from 1.8.2 to 1.9.0
Bumps [github.com/stretchr/testify](https://github.com/stretchr/testify) from 1.8.2 to 1.9.0.
- [Release notes](https://github.com/stretchr/testify/releases)
- [Commits](https://github.com/stretchr/testify/compare/v1.8.2...v1.9.0)

---
updated-dependencies:
- dependency-name: github.com/stretchr/testify
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-03-05 04:57:38 +00:00
Zack Scholl 945ac74690 Merge branch 'main' of github.com:schollz/croc 2024-03-05 04:57:05 +00:00
Zack Scholl fff6f48001 chore: update dependencies 2024-03-04 20:56:40 -08:00
Zack Scholl 28ef8e99ac Merge branch 'main' of github.com:schollz/croc 2024-02-22 22:41:05 +00:00
Zack 28bb36b321 bump version 2024-02-22 14:40:20 -08:00
Zack Scholl ab2cb477a8 Merge branch 'main' of github.com:schollz/croc 2024-02-22 22:40:05 +00:00
Zack abc5029fce update release with LICENSE 2024-02-22 14:39:57 -08:00
Zack e7f67ebea7 update date 2024-02-22 14:39:50 -08:00
Zack Scholl c7f0228786 Merge branch 'main' of github.com:schollz/croc 2024-02-22 22:35:05 +00:00
Zack 741714504a
Merge pull request #671 from dbohdan/main
Build release binaries for DragonFly/Free/Net/OpenBSD
2024-02-22 14:34:06 -08:00
D. Bohdan be8a6689ff build release bins for DragonFly/Free/Net/OpenBSD 2024-02-22 21:22:32 +00:00
Zack Scholl de9c54e57a Merge branch 'main' of github.com:schollz/croc 2024-02-20 15:59:03 +00:00
Zack 53fc9ebd99 bump version 2024-02-20 07:58:27 -08:00
Zack 4159ba7668 do static builds of croc
following https://github.com/golang/go/issues/26492#issuecomment-435462350
2024-02-20 07:57:49 -08:00
Zack Scholl 064f84ccd3 Merge branch 'main' of github.com:schollz/croc 2024-02-19 15:55:51 +00:00
Zack 8ac1e3a501 bump version 2024-02-19 07:47:23 -08:00
Zack 11bc4eecc6 update deps 2024-02-19 07:46:53 -08:00
Zack d92cff92b9 add arm/arm64 builds for windows fixes #664 2024-02-19 07:46:35 -08:00
Zack 00f12b5742
Merge pull request #663 from TravisRoad/main
remove unnecessary trailing newline character when stdout is enabled
2024-02-18 06:32:28 -08:00
Travis 4f1f57b1ba remove unnecessary trailing newline character when stdout is enabled 2024-02-18 10:17:35 +08:00
Zack a240a4b982
Merge pull request #657 from schollz/dependabot/github_actions/actions/stale-9
Bump actions/stale from 5 to 9
2024-02-17 10:29:47 -08:00
Zack 508e0be335
Merge pull request #662 from qk-santi/ports-and-transfers
define ports by amount, not individually - v2
2024-02-17 10:28:58 -08:00
qk-santi e1644401da version compatible basePort and transfers 2024-02-17 19:09:53 +01:00
qk-santi c83eb59963 Revert "define ports by amount, not individually"
This reverts commit 87152f8706.
2024-02-17 18:41:41 +01:00
Zack f874e30151 revert go version back to go.1.21 because of glibc errors 2024-02-16 06:56:33 -08:00
Zack b278f5a41d bump version 2024-02-16 06:56:06 -08:00
Zack ce91e3b420
Merge pull request #660 from qk-santi/ports-and-transfers
define ports by amount, not individually
2024-02-12 08:08:01 -07:00
Zack 30a6b14443
Merge pull request #659 from qk-santi/hide-relay-not-used
hide relay param if not going to be used
2024-02-12 06:37:28 -07:00
qk-santi 87152f8706 define ports by amount, not individually 2024-02-12 09:58:51 +01:00
qk-santi 48eb2a2a7c hide relay param if not going to be used 2024-02-12 09:30:20 +01:00
dependabot[bot] 816ad09a50
Bump actions/stale from 5 to 9
Bumps [actions/stale](https://github.com/actions/stale) from 5 to 9.
- [Release notes](https://github.com/actions/stale/releases)
- [Changelog](https://github.com/actions/stale/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/stale/compare/v5...v9)

---
updated-dependencies:
- dependency-name: actions/stale
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-02-09 09:01:53 +00:00
Zack a2228e80c2
Create stale.yml 2024-02-08 13:43:05 -07:00
Zack Scholl 230de9184d bump version 2024-02-08 13:39:45 -07:00
Zack 3c781069ca
Merge pull request #653 from schollz/dependabot/go_modules/golang.org/x/crypto-0.19.0
Bump golang.org/x/crypto from 0.18.0 to 0.19.0
2024-02-08 13:38:12 -07:00
Zack 7274a8bd4b
Merge pull request #655 from schollz/schollz/issue650
add build for windows 7
2024-02-08 13:37:54 -07:00
Zack Scholl 3382306342 add build for windows 7 2024-02-08 13:37:10 -07:00
dependabot[bot] ad47739c8f
Bump golang.org/x/crypto from 0.18.0 to 0.19.0
Bumps [golang.org/x/crypto](https://github.com/golang/crypto) from 0.18.0 to 0.19.0.
- [Commits](https://github.com/golang/crypto/compare/v0.18.0...v0.19.0)

---
updated-dependencies:
- dependency-name: golang.org/x/crypto
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-02-08 08:07:15 +00:00
Zack 2f33b14b3d
Merge pull request #581 from sitiom/patch-1
switch winget releaser runner to `ubuntu-latest`
2024-02-06 18:12:51 -08:00
Zack 4025efcd48 bump the default.txt 2024-02-06 15:58:18 -08:00
Zack f41a2afead bump version and fix installer 2024-02-06 15:51:07 -08:00
Zack ba75f7badb add release workflow for generating binaries 2024-02-06 15:37:28 -08:00
Zack 55c954117a update deps 2024-02-06 14:33:01 -08:00
Zack 4d083f8d10
Merge pull request #646 from rehanone/fix-docker-deplyment
Fix for the failing CD build
2024-02-06 08:05:08 -08:00
Rehan Mahmood 9ad2af18bd Added the `gcc` and `musl-dev` packages in the builder layer of the Dockerfile. 2024-01-28 14:38:01 -05:00
Zack 47fc96b98f
Merge pull request #645 from rehanone/fix-docker-deplyment
Update and fix the docker image deplyment build
2024-01-25 07:59:36 -08:00
Rehan Mahmood d4bba88fb1 Update and fix the docker image deplyment build 2024-01-25 10:02:01 -05:00
Zack Scholl c1367671b6 bump 9.6.6 2023-11-09 06:56:42 -08:00
Zack Scholl 1e572067ec bump 9.6.6 2023-11-09 06:56:29 -08:00
Zack Scholl 8aa9f040f6 bump 9.6.6 2023-11-09 06:53:42 -08:00
Zack Scholl 96bb34485e update deps 2023-11-09 06:51:31 -08:00
Zack 159f0f8d9b
Merge pull request #625 from gravetii/patch-1
Fix minor error in README
2023-11-05 07:30:14 -08:00
Sandeep c4d5c89e5f
Fix minor error in README 2023-11-03 11:20:41 +05:30
Zack 6ac67b68fc
Merge pull request #570 from PThorpe92/main
.gitignore support
2023-09-23 07:09:30 -07:00
PThorpe92 0af35d7149
feat: add support to respect .gitignore files 2023-09-22 21:15:27 -04:00
Zack f91c7a9948
Merge pull request #587 from ferebee/main
fix architecture detection for Apple Silicon
2023-09-03 19:35:53 -07:00
Zack cff8cddd13
Merge pull request #589 from zx9597446/main
zip file bug on windows and linux
2023-08-18 11:00:46 +02:00
zx9597446 d724f11297 Here is the English translation:
If there are directories in a zip file compressed on the Windows platform, the "\\" in the filepath will cause the files to be extracted normally on Linux, and ls will show filenames containing single quotes.

So when compressing, I replace "\\" with "/" so that it seems there are no issues on both Windows and Linux.
2023-08-17 12:07:07 +08:00
ferebee 80aabea29b fix architecture detection for Apple Silicon
fix auto-install on macOS Apple Silicon, which reports architecture "arm64" on uname -a rather than "aarch64"
2023-08-09 11:42:23 +02:00
sitiom f8bb011eac
switch winget releaser runner to `ubuntu-latest` 2023-07-07 08:52:14 +08:00
Zack Scholl ef68dfa54c bump 9.6.5 2023-07-06 10:10:57 -07:00
Zack Scholl 8ab65d06b5 bump 9.6.5 2023-07-06 10:10:39 -07:00
Zack Scholl 9c82914e7c update deps 2023-07-06 10:00:05 -07:00
Zack 95717f16c9
Merge pull request #579 from glitsj16/systemd-unit
croc.service: use DynamicUser
2023-06-21 05:58:58 -07:00
glitsj16 5a58ae294b
croc.service: use DynamicUser 2023-06-21 01:46:47 +00:00
Zack Scholl 0aa5c80393 upgrade dependencies 2023-05-08 17:39:18 +00:00
Zack 23a8904193
Merge pull request #563 from N0mansky/main
Feat: support http proxy as a complementary way to use in network limited environments.
2023-04-12 09:03:53 -07:00
N0mansky d5e63cd0bf Update: update error messages for http proxy 2023-04-12 18:17:25 +08:00
N0mansky 1b1dc5cdfe Feat: support http proxy as a complementary way to use in network limited environments. 2023-04-12 18:04:15 +08:00
Zack cd1162f85c
Merge pull request #553 from goggle/typos01
Fix some typos
2023-03-27 08:36:56 -07:00
Alexander Seiler ad7a22b218
Fix some typos
Signed-off-by: Alexander Seiler <seileralex@gmail.com>
2023-03-27 17:13:09 +02:00
Zack e3a18cd7a7
Merge pull request #547 from schollz/dependabot/github_actions/docker/setup-buildx-action-2
Bump docker/setup-buildx-action from 1 to 2
2023-03-27 07:43:21 -07:00
Zack 8611bfa44a
Merge pull request #550 from schollz/dependabot/github_actions/actions/setup-go-4
Bump actions/setup-go from 2 to 4
2023-03-27 07:42:58 -07:00
Zack Scholl b3c0625659 localhost -> 127.0.0.1 Fixes #513 2023-03-20 09:16:07 -07:00
dependabot[bot] 40e5893bb8
Bump actions/setup-go from 2 to 4
Bumps [actions/setup-go](https://github.com/actions/setup-go) from 2 to 4.
- [Release notes](https://github.com/actions/setup-go/releases)
- [Commits](https://github.com/actions/setup-go/compare/v2...v4)

---
updated-dependencies:
- dependency-name: actions/setup-go
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-03-16 09:12:12 +00:00
Zack e1b49e6d1c
Merge pull request #549 from BayLee4/main
Enhance tab completion
2023-03-15 08:11:00 -07:00
BayLee4 fae2e81b4a
Enhance tab completion 2023-03-15 10:03:38 +01:00
BayLee4 f5a02df17b
Merge pull request #1 from schollz/main
Merge upstream
2023-03-15 07:40:29 +00:00
dependabot[bot] d813aa2fa9
Bump docker/setup-buildx-action from 1 to 2
Bumps [docker/setup-buildx-action](https://github.com/docker/setup-buildx-action) from 1 to 2.
- [Release notes](https://github.com/docker/setup-buildx-action/releases)
- [Commits](https://github.com/docker/setup-buildx-action/compare/v1...v2)

---
updated-dependencies:
- dependency-name: docker/setup-buildx-action
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-03-14 12:01:02 +00:00
Zack 8d8d06557e
Merge pull request #534 from sitiom/winget-releaser
add winget releaser workflow
2023-03-14 05:00:19 -07:00
Zack Scholl 3ae46c3c18 bump 9.6.4 2023-03-14 04:52:15 -07:00
Zack Scholl 1fce28e72f remove twitter 2023-03-14 04:51:47 -07:00
Zack Scholl ac3caa5564 bump 9.6.4 2023-03-14 04:50:55 -07:00
Zack Scholl 790ee9e6eb bump 9.6.4 2023-03-14 04:50:29 -07:00
Zack Scholl 0656bb7851 bump 9.6.4 2023-03-14 04:50:10 -07:00
Zack Scholl 5ed8204cb1 bump 9.6.4 2023-03-14 04:50:00 -07:00
Zack Scholl 1220d54a65 bump 9.6.4 2023-03-14 04:41:22 -07:00
Zack Scholl 642d20b48d update deps 2023-03-14 04:39:05 -07:00
Zack 58bb226ba5
Merge pull request #542 from stefins/go-version
Upgrade Go version to 1.20 and dependencies to latest
2023-03-14 04:36:56 -07:00
stefins 080c21b66b
Change go version to 1.20 in CI 2023-03-10 20:59:45 +05:30
stefins 4944355b75
Upgrade Go version to 1.20 and dependencies to latest 2023-03-10 20:59:33 +05:30
Zack Scholl 3c1d60d6d2 bump 9.6.3 2023-02-20 07:34:32 -08:00
Zack Scholl 5bdd4453cd bump 9.6.3 2023-02-20 07:34:04 -08:00
Zack Scholl 5b333fc85c bump 9.6.3 2023-02-20 07:33:52 -08:00
Zack Scholl 90e4e33dcd bump 9.6.3 2023-02-20 07:33:34 -08:00
Zack Scholl 3135bd74e3 bump 9.6.3 2023-02-20 07:21:24 -08:00
Zack Scholl 7c98ae3d5a deps 2023-02-20 07:19:47 -08:00
sitiom 908f33cd61
add dependabot 2023-02-13 11:52:34 +08:00
sitiom 9eaba7be7c
add Winget installation instructions 2023-02-12 23:45:11 +08:00
Ryan Caezar Itang b3db9d88c1
add winget releaser workflow 2023-02-12 23:44:34 +08:00
Zack Scholl 9006cde1b3 update deps 2023-02-10 11:59:48 -08:00
Zack 8f75bb8299
Merge pull request #533 from stefins/patch-1
Update CI to run on main branch events
2023-02-10 11:59:21 -08:00
Zack faf64aadf1
Merge pull request #532 from stefins/chmod-file
Chmod new file based on the source file mode
2023-02-10 11:58:59 -08:00
stefins 65760b1189
Update CI to run on main branch events 2023-02-11 01:18:43 +05:30
stefins 24679d4e02
Chmod new file based on the source file mode 2023-02-10 14:53:06 +05:30
Zack Scholl 8b9977a7c4 update 2023-02-07 05:46:10 -08:00
Zack ae71b4b63b
Merge pull request #528 from chncaption/oscs_fix_cfds588au51u2n4fthm0
fix(sec): upgrade gopkg.in/yaml.v3 to 3.0.0
2023-02-07 05:45:44 -08:00
Zack Scholl c462b5948f update go.mod/go.sum 2023-02-07 05:44:17 -08:00
Zack a2c1dc6a89
Merge pull request #526 from BayLee4/main
Implement tab completion for words
2023-02-07 05:40:41 -08:00
chncaption 98391bff63 update gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c to 3.0.0 2023-02-02 22:03:21 +08:00
BayLee4 adadaba75e
Small optimization + consistent variable names style 2023-01-13 16:29:11 +01:00
BayLee4 0024beaedc
Implement tab completion for words 2023-01-12 19:23:50 +01:00
Zack Scholl 63feece074 add testing 2023-01-08 08:11:55 -08:00
Zack Scholl 9e280d7f48 update deps 2023-01-03 18:40:31 +00:00
Zack Scholl 7c7be95d6b update deps 2023-01-03 18:40:20 +00:00
Zack c20beb1be7
not reachable by twitter anymore 2022-12-16 16:35:06 -08:00
Zack Scholl e08c5e7f38 bump 9.6.2 2022-12-06 07:59:30 -08:00
Zack Scholl 3b819346fa bump 9.6.2 2022-12-06 07:58:30 -08:00
Zack Scholl 2467411bae fix install tests 2022-12-06 07:58:15 -08:00
Zack Scholl b436b31970 update deps 2022-12-06 07:45:07 -08:00
Zack Scholl e3ce565ca6 fix: allow remembering hash algorithm 2022-12-05 15:28:25 -08:00
Zack Scholl e04981698c update deps 2022-12-05 15:25:10 -08:00
Zack Scholl 07a67ed54e path -> fpath 2022-12-05 15:24:47 -08:00
Zack 9a8e584aca
Merge pull request #520 from taigrr/gofumpt
run through gofumpt
2022-12-05 15:22:10 -08:00
Tai Groot fa7ae114f5
run through gofumpt 2022-12-05 11:21:04 -08:00
Zack 8a4326bc0d
Merge pull request #519 from taigrr/workflow
update dockerfile to v1.19
2022-12-04 09:37:17 -08:00
Tai Groot ae20f2b5ac
update dockerfile 2022-12-01 21:45:10 -08:00
Zack Scholl cd6eb1ba53 update deps 2022-11-18 20:55:07 -08:00
Zack Scholl 8454008b45 update deps 2022-11-18 20:52:55 -08:00
Zack fce4629120
Merge pull request #515 from taigrr/workflow
Github CI go 1.18 -> 1.19
2022-11-18 20:47:36 -08:00
Tai Groot fd0db2ad55
upgrade github ci workflow 2022-10-30 20:43:51 -07:00
Zack 7f9688c7a1
Merge pull request #512 from IrishMaestro/revision
Typo fix
2022-10-23 10:29:05 -07:00
IrishMaestro f1e15a54ee
Typo fix
typo fix for the word relative
2022-10-22 17:18:16 -05:00
Zack Scholl 0f7f449d7f bump 9.6.1 2022-10-17 13:44:09 -07:00
Zack Scholl b27982a742 update deps 2022-10-17 13:42:39 -07:00
Zack Scholl 30f5a3e84e revert back to flate instead of zstd 2022-09-16 09:19:58 -07:00
Zack Scholl 786fc8d34f update mods 2022-09-16 09:10:08 -07:00
Zack 8de4508876
Merge pull request #506 from V-R-Dighe/develop
Added zstd as a compression algorithm
2022-09-16 09:08:14 -07:00
VRDighe e640e4fce0 Replaced zstd package 2022-09-16 10:19:44 +05:30
VRDighe 4f8b2aba9b Added zstd as a compression algorithm 2022-09-13 20:08:07 +05:30
Zack 1517767129
addresses #496 gettings ports doing LAN 2022-08-12 12:00:26 -07:00
Zack Scholl 3dedd41557 update 2022-08-06 09:32:46 -07:00
Zack 69f939c0cd
Merge pull request #494 from chavacava/fix-493
fix #493: data race in cli.relay
2022-08-05 08:38:07 -07:00
Zack cd5872bd2d
Merge pull request #497 from cuishuang/main
fix some typos
2022-08-05 08:37:36 -07:00
cui fliter 1c6583f925 fix some typos
Signed-off-by: cui fliter <imcusg@gmail.com>
2022-08-05 20:41:18 +08:00
chavacava 40ac320261
fix #493: data race in cli.relay 2022-07-17 10:40:49 +02:00
Zack Scholl 1851327df7 bump 9.6.0 2022-07-08 16:41:04 -07:00
Zack Scholl 0e93f1e285 println -> print os.stderr 2022-07-07 10:46:49 -07:00
Zack Scholl 7e0814a57e update deps 2022-07-07 10:34:20 -07:00
Zack Scholl c6bcb79928 remove zip compression and add --zip to send command 2022-07-07 10:32:23 -07:00
Zack 134673691e
Merge pull request #488 from stefins/zip-folder
Added ability to zip a directory
2022-07-07 10:14:23 -07:00
Stefin d226ba536e Fixed relative path / bug 2022-07-07 18:56:37 +05:30
Stefin b50fe88474 Added support for sending relative folder 2022-07-07 02:58:49 +05:30
Stefin 37ae453ff7 Unzipping file at the reciever end 2022-07-07 00:06:11 +05:30
Stefin ee772c4cec Added UnzipDirectory function 2022-07-07 00:05:56 +05:30
Stefin ed030375e5 Modified the argument for GetFilesInfo in tests 2022-07-06 18:49:32 +05:30
Stefin ad36e21051 Handling the --zip flag 2022-07-06 18:48:19 +05:30
Stefin 4ea9a96d88 Added --zip CLI argument for zipping all the dir specified 2022-07-06 18:47:34 +05:30
Stefin f0f9b80bdf added ZipDirectory function 2022-07-06 18:46:02 +05:30
Zack 7a0c0a8200
Merge pull request #474 from tjanez/fedora-package
add Fedora instructions to README
2022-05-20 09:50:31 -07:00
Zack Scholl 5270755c15 bump 9.5.6 2022-05-18 16:57:22 -07:00
Zack Scholl b7e4a73c27 don't show number of folders if the number is 0 2022-05-18 16:57:00 -07:00
Zack Scholl da5d19ef28 update deps and ui 2022-05-18 16:53:28 -07:00
Zack c68cfcea8a
Merge pull request #478 from DasSkelett/fix/relay-address-behind-dns64
Fix relay IPv4 address resolution behind DNS64
2022-05-18 16:48:51 -07:00
DasSkelett 38ed8ecc3c
Fix relay IPv4 address resolution behind DNS64 2022-05-16 22:04:55 +02:00
Tadej Janež a5d3e00f2b
add Fedora instructions to README 2022-04-29 22:31:59 +02:00
Zack Scholl 9de06a6bf9 bump 9.5.5 2022-04-28 14:30:03 -07:00
Zack Scholl a6a3a57361 update deps 2022-04-28 14:29:42 -07:00
Zack 148c1a6cdd
Merge pull request #470 from iulius98/master
Fixed #463 issue
2022-04-27 16:23:10 -07:00
Zack Scholl 817905cf5a bump 9.5.4 2022-04-27 08:25:06 -07:00
Zack Scholl 6158b42ad1 update deps 2022-04-27 08:23:43 -07:00
Zack Scholl 80539f27c3 avoid deadlock 2022-04-25 06:25:25 -07:00
Zack 35652e60a3
new support system 2022-04-13 06:42:08 -07:00
RCL98 2ad8b1f1ce #463 fixed display at receiving end 2022-04-13 02:23:10 +03:00
RCL98 b316c0159f #463 fixed croc tests for empty folders, and to work in Windows 2022-04-11 00:02:26 +03:00
RCL98 f78ee15605 #463 fixed display for empty folders 2022-04-11 00:00:47 +03:00
iulius98 15d0209a29 #463 added capability to send/receive empty folders 2022-04-09 01:38:22 +03:00
Zack 386c99d057
Merge pull request #462 from davide125/completion
Drop shebang for bash completion
2022-04-07 07:14:20 -07:00
Zack Scholl fd99a405fd bump 9.5.3 2022-04-07 06:05:16 -07:00
Zack Scholl 54f52e5427 bump 9.5.3 2022-04-07 06:04:46 -07:00
Zack Scholl ec949888d8 Merge branch 'master' of github.com:schollz/croc 2022-04-07 06:01:08 -07:00
Zack Scholl 0d52ead66e update default curve 2022-04-07 06:01:02 -07:00
Zack Scholl b715993435 bump 9.5.3 2022-04-07 05:59:24 -07:00
Zack Scholl 7e817e1cbf default to P-256 2022-04-07 05:52:54 -07:00
Zack 4abdbf1ad2
update to go 1.18 2022-04-06 21:48:39 -07:00
Zack Scholl 087c22d833 update readme 2022-04-03 15:21:35 -07:00
Zack Scholl 789b5bf607 update deps 2022-03-30 11:30:36 -07:00
Davide Cavalca e42f81a404 Drop shebang for bash completion 2022-02-27 08:40:56 -08:00
Zack Scholl 20bf7dd91d bump 9.5.2 2022-02-23 08:19:02 -08:00
Zack Scholl 4a8c19b115 bump 9.5.2 2022-02-23 08:16:50 -08:00
Zack Scholl a1a17ce6f7 bump 9.5.2 2022-02-23 08:09:02 -08:00
Zack Scholl 00c4d248fd bump 9.5.2 2022-02-23 08:08:43 -08:00
Zack Scholl 073196ccd2 bump 9.5.2 2022-02-23 08:07:23 -08:00
Zack Scholl 635b362ca0 tcp: send error on fail 2022-02-23 08:03:45 -08:00
Zack Scholl 53f35c1da0 fix ui when sending text 2022-02-23 07:57:40 -08:00
Zack 030ed2a03d
Merge pull request #456 from abhi12299/filenamePrefix
Fix renaming of file with prefix "croc-stdin" on receiver end
2022-02-23 07:52:27 -08:00
Zack Scholl c28d731a66 update deps 2022-02-23 07:31:45 -08:00
Zack Scholl ef6683b550 add more tests 2022-02-23 07:25:13 -08:00
Zack f6a75c8f53
Merge pull request #460 from iulius98/master
#431 fixed remote path
2022-02-23 07:14:46 -08:00
RCL98 7c1a59c102 #431 fixed remote folder name for Windows 2022-02-21 21:50:24 +02:00
iulius98 32a188fa85 #431 Integrate GetFilesInfo function with the code 2022-02-21 20:41:51 +02:00
RCL98 ce8fb796b3 #431 added file informations retrival functions to replace getPaths 2022-02-21 20:16:27 +02:00
Zack 1bd705d2e1
Merge pull request #459 from iulius98/master
#454 fixed local transfer
2022-02-20 07:57:34 -08:00
iulius98 1a635de69c #454 fixed local transfer 2022-02-20 17:40:50 +02:00
Zack 353ae0db16
add more information 2022-02-07 14:06:49 -08:00
Abhishek 9f66842322 fix sending file with prefix "croc-stdin" renaming on receiver end 2022-02-03 23:09:37 +05:30
Zack Scholl 94c0f66a26 bump 9.5.1 2022-02-03 08:51:19 -08:00
Zack Scholl b0e7d4d5df fix tests 2022-02-03 08:45:50 -08:00
Zack Scholl 9b5252d54c update deps 2022-02-03 08:40:49 -08:00
Zack Scholl 1d3c822ef3 allow remembering --internal-dns flag 2022-02-03 08:34:03 -08:00
Zack df78f3333d
Merge pull request #451 from voocel/fix_hash_err
fix hash file error
2022-01-06 04:43:50 -08:00
voocel b45e625298 fix hash file error 2022-01-06 17:44:43 +08:00
Zack Scholl 7390e7ed45 bump 9.5.0 2021-11-18 07:03:47 -08:00
Zack f210ef8877
Merge pull request #435 from AmeyShrivastava/fix-typos
Fix Typos
2021-11-17 10:52:29 -08:00
Amey Shrivastava 2964ede174 Fix Typos (revised)
This commit fixes spelling mistakes (typos) at a few places in the codebase.
(Includes requested corrections)
2021-11-17 23:50:32 +05:30
Zack Scholl cc837fa863 fix ports for tests 2021-11-17 10:11:35 -08:00
Zack Scholl 87bfdf11a8 update deps 2021-11-17 09:40:59 -08:00
Zack c30492609e
Merge pull request #432 from mbattista/master
added throttle upload feature
2021-11-17 09:37:50 -08:00
Zack 2f733891db
Merge pull request #440 from Juneezee/go1.17
build: upgrade to Go 1.17
2021-11-17 09:35:25 -08:00
Zack 3eb66284e0
Merge pull request #434 from HinWaei/fix4
Fixed an error
2021-11-17 09:33:48 -08:00
Eng Zer Jun 1645759742
refactor: move from io/ioutil to io and os packages
The io/ioutil package has been deprecated as of Go 1.16, see
https://golang.org/doc/go1.16#ioutil. This commit replaces the existing
io/ioutil functions with their new definitions in io and os packages.

Signed-off-by: Eng Zer Jun <engzerjun@gmail.com>
2021-11-17 11:39:11 +08:00
Eng Zer Jun da8beb65bf
build: upgrade to Go 1.17
Go 1.17 introduces compiler improvement
(https://golang.org/doc/go1.17#compiler) and supports module graph
pruning (https://golang.org/ref/mod#graph-pruning) and lazy module
loading (https://golang.org/ref/mod#lazy-loading).

This commit applies the changes by running `go mod tidy -go=1.17` to
enable module graph pruning and lazy module loading supported by Go 1.17
or higher.

Signed-off-by: Eng Zer Jun <engzerjun@gmail.com>
2021-11-17 11:39:01 +08:00
Hinux Chau d30433658b
Fixed an error
Fixed an error caused by nonexistence of the directory /etc/bash_completion.d/croc
2021-10-27 22:21:31 +08:00
Marcel Battista d372fa1fa4 fix panic on single digit throttles values 2021-10-19 13:10:43 +02:00
Marcel Battista 8ff3fb9b89 added throttle upload feature 2021-10-19 02:46:54 +02:00
Zack 696479024e
Update ci.yml 2021-10-08 09:43:30 -07:00
Zack 9dfa0284fa update with setup 2021-10-08 09:39:20 -07:00
Zack Scholl a12f374aba can't use the github ci 8084 2021-10-04 08:02:27 -07:00
Zack 8ee1825f84
Merge pull request #424 from jolheiser/fix-const
Fix TCP constant
2021-10-04 07:29:27 -07:00
Zack f99c33d794
Merge pull request #426 from maximbaz/ci
Run tests via Github Actions
2021-10-04 07:26:53 -07:00
Maxim Baz 417b371454
Add CI 2021-10-04 00:16:49 +02:00
jolheiser 2ffb20201c
Fix TCP constant
Signed-off-by: jolheiser <john.olheiser@gmail.com>
2021-10-03 16:23:29 -05:00
Zack Scholl 89efd38c10 bump 9.4.2 2021-10-02 12:38:32 -07:00
Zack Scholl 49f50a53d5 need to listen on all ports 2021-10-02 12:37:16 -07:00
Zack Scholl 5d9afe03ef bump 9.4.1 2021-10-02 12:29:05 -07:00
Zack Scholl 1637765aad debugging 2021-10-02 12:23:36 -07:00
Zack Scholl ce628ea604 debugging 2021-10-02 12:20:18 -07:00
Zack Scholl ff4307c3c6 debugging 2021-10-02 12:18:50 -07:00
Zack Scholl e5f59fa0f9 fix local 2021-10-02 12:02:25 -07:00
Zack Scholl 04662df347 fix local 2021-10-02 11:55:43 -07:00
Zack Scholl 4ea66fbd18 upgrade peerdiscovery 2021-10-02 10:55:12 -07:00
Zack Scholl d96c98f4ce bump 9.4.0 2021-10-02 10:45:00 -07:00
Zack Scholl 31db6a76e5 bump 9.4.0 2021-10-02 10:44:48 -07:00
Zack Scholl a996f3c4f4 bump 9.4.0 2021-10-02 10:44:34 -07:00
Zack Scholl 4334c870f5 bump 9.4.0 2021-10-02 10:44:17 -07:00
Zack Scholl 2b1367a09b bump 9.4.0 2021-10-02 10:44:05 -07:00
Zack Scholl add1650cbd bump 9.4.0 2021-10-02 10:43:14 -07:00
Zack Scholl 04f2dfac97 bump 9.4.0 2021-10-02 10:41:46 -07:00
Zack Scholl 060ce516b1 bump 9.4.0 2021-10-02 10:41:26 -07:00
Zack Scholl 78b6f2d858 update deps 2021-10-02 10:37:20 -07:00
Zack d77c83ce09
Merge pull request #419 from kallydev/patch
Add host flag for relay
2021-10-02 10:35:00 -07:00
Zack a34d29befc
Merge pull request #420 from jolheiser/const
Constants and Message Types
2021-10-02 10:33:52 -07:00
Zack 914d0c98a8
Merge pull request #421 from jolheiser/wildcard
Add wildcard support for files
2021-10-02 10:33:15 -07:00
Zack 55cb35d12b
Merge pull request #422 from BrandonIngalls/gh-405-config-defaults
Do not override defaults with empty values
2021-10-02 10:29:40 -07:00
Brandon Ingalls 860a75fee6 Do not override defaults with empty values
This change will make it so a user who used the -remember
option on an older version of the application will be able
to use the latest version of the software without deleting
their saved config.

fixes schollz/croc#405
relates to schollz/croc#417
2021-10-02 11:12:34 -05:00
jolheiser e380c7b1f1
Add wildcard support
Signed-off-by: jolheiser <john.olheiser@gmail.com>
2021-10-01 16:49:21 -05:00
jolheiser 2381f26c61
Move to consts and "enum"
Signed-off-by: jolheiser <john.olheiser@gmail.com>
2021-10-01 16:24:28 -05:00
KallyDev de454bbf5a
add host flag for relay 2021-10-01 12:55:28 +08:00
Zack Scholl e19e06a652 update deps 2021-09-14 10:44:33 -07:00
Zack 6deafaadae
Merge pull request #412 from adworacz/sendMultifileDocs
Clarify croc's ability to send multiple files/folder
2021-08-29 10:51:04 -07:00
Austin Dworaczyk Wiltshire ef3953a586 Clarify croc's ability to send multiple files/folder
I was personally shocked that I could send multiple files via croc
recently, having done it purely on a whim. The existing CLI
documentation makes no mention of croc's ability to send multiple
files/folders.

This adds it.
2021-08-29 10:16:51 -07:00
Zack Scholl 1d3fdffed6 bump 9.3.0 2021-08-16 12:29:43 -07:00
Zack Scholl 94b2aff637 update deps 2021-08-16 12:28:26 -07:00
Zack 9ce2321d01
Merge pull request #409 from CHTJonas/master
Make internal DNS resolution opt-in
2021-08-16 12:27:57 -07:00
Charlie Jonas d75530b78b Improve built-in list of public DNS recursors 2021-08-16 18:48:03 +01:00
Charlie Jonas f64f68d5a9 Tidy up code slightly 2021-08-16 18:47:25 +01:00
Charlie Jonas be7705efc3 Remove DNS lookup timeouts 2021-08-16 18:32:55 +01:00
Charlie Jonas df2e29b74d Add --internal-dns flag 2021-08-16 18:25:34 +01:00
Zack Scholl b73fdff702 mv goreleaser 2021-08-06 14:35:53 -07:00
Zack Scholl 664936feb2 bump 9.2.1 2021-08-06 13:46:23 -07:00
Zack Scholl 4b1eb6519c update deps 2021-08-06 13:45:23 -07:00
Zack Scholl 86aeed93db move mutex to avoid race condition #407 2021-08-06 09:48:26 -07:00
Zack Scholl 7993e73ac2 update deps 2021-07-29 13:43:21 -07:00
Zack Scholl d922808fd8 change install cmd 2021-06-25 13:19:23 -07:00
Zack Scholl 8d22737fd3 bump 9.2.0 2021-06-21 11:54:11 -07:00
Zack Scholl d442755814 show preparing progress 2021-06-21 11:11:44 -07:00
Zack Scholl 0afdf71305 update deps 2021-06-21 07:43:20 -07:00
Zack Scholl ecf3eb872e allow selecting hash 2021-06-21 07:34:28 -07:00
Zack Scholl 646c879edc bump 9.1.6 2021-06-15 15:08:32 -07:00
Zack Scholl cbe9cbe32a update deps 2021-06-15 14:54:22 -07:00
Zack Scholl 4796404b7e show resume message if resuming
Fixes #402
2021-06-15 14:53:16 -07:00
Zack Scholl 3e2c88c5bc bump 9.1.5 2021-06-10 14:45:24 -07:00
Zack Scholl 0124356cd7 update deps 2021-06-10 14:44:49 -07:00
Zack f2ef6f19a5
Merge pull request #401 from nikoksr/refactor/accept-enter-in-prompts
refactor: Accept enter in prompts
2021-06-10 14:43:11 -07:00
Niko Köser 5e0d6522b0
refactor: accept enter in user prompts
Until now, the process of receiving a file was aborted when an
empty entry (Enter) was made. It is common under *nix that
pressing Enter without prior input of other characters selects
the default answer. This would also make the process more
fluid for croc.

In most usecases the default choice will be 'Y'/'Yes'. The only
exception is the prompt for overwriting existing files. We default
to 'N'/'No' in this prompt to prevent accidental overwriting of
files.
2021-06-10 14:12:05 +02:00
Niko Köser c72aaf63cb
chore(git): ignore .idea and .vscode folders 2021-06-09 16:00:09 +02:00
Zack Scholl a9e77673f4 update deps 2021-05-12 12:04:30 -07:00
Zack Scholl aa93d3e30f Merge branch 'master' of github.com:schollz/croc 2021-05-12 07:19:09 -07:00
Zack Scholl 15a19e1998 use all the config options 2021-05-12 07:19:02 -07:00
Zack Scholl e1ccb58d8f bump 9.1.4 2021-05-12 07:04:38 -07:00
Zack Scholl d0ebb7ad38 longer time for local connections 2021-05-12 07:04:10 -07:00
Zack Scholl 2bfbacf972 bump 9.1.3 2021-05-11 10:06:14 -07:00
Zack Scholl e29b4c47fd update deps 2021-05-11 10:05:37 -07:00
Zack Scholl b4deedf367 upgrade peerdiscovery 2021-05-11 10:04:21 -07:00
Zack Scholl 68e507dbba update peerdiscovery 2021-05-11 07:09:56 -07:00
Zack Scholl 66f30c0565 skip autocomplete installation on fish, Fixes #393 2021-05-10 13:47:17 -07:00
Zack Scholl 340bafba3d bump 9.1.2 2021-05-07 10:23:45 -07:00
Zack Scholl e47776bb10 fix 2021-05-07 10:21:24 -07:00
Zack 422f099e5e
Merge pull request #390 from wamserma/patch-1
Distinguish text message from file in receipient dialog
2021-05-07 10:20:53 -07:00
Zack Scholl bd4886ae3c update deps 2021-05-07 10:18:40 -07:00
Markus Wamser d5fd2060dd
Distinguish text message from file in receipient dialog
Fixes https://github.com/schollz/croc/issues/388
2021-05-01 21:27:44 +02:00
Zack Scholl 7c28279a58 bump 9.1.1 2021-04-29 09:43:50 -07:00
Zack Scholl 27b7cdbf12 bug fix: doesn't ask overwrite text Fixes #384 2021-04-29 09:16:22 -07:00
Zack Scholl 24fb8746a4 fix deadlock 2021-04-29 09:11:29 -07:00
Zack 45cb545a82
Merge pull request #383 from oxzi/dns-prefer-local
Prefer local DNS resolver over public DNS servers
Fixes #301
2021-04-26 10:45:07 -07:00
Alvar Penning 8f5c73837a Prefer local DNS resolver over public DNS servers
The changes cause the local DNS resolver to be used exclusively at
first. If this fails, the public DNS servers are queried as before.

This feature was previously requested. Merging should close #301.

Along the way, three other changes are introduced:

1. A public IPv6 DNS server was added.

2. The lookup returns the first result from a public DNS server and does
   not wait for all queries to be answered.

3. In the unlikely case that no public DNS server is able to answer, an
   error will be returned.
2021-04-26 11:43:45 +02:00
Zack b90f9329ca
Merge pull request #376 from Craeckie/master
Use unprivileged user in docker
2021-04-23 10:28:22 -07:00
Craeckie 968950f783
Use unprivileged user in docker
See 
https://americanexpress.io/do-not-run-dockerized-applications-as-root/
and 
https://engineering.bitnami.com/articles/why-non-root-containers-are-important-for-security.html
2021-04-22 09:53:49 +00:00
Zack Scholl 5b0883e1fe generate key once 2021-04-21 16:57:18 -07:00
Zack Scholl 420030998f add chacha20 2021-04-21 16:53:29 -07:00
Zack Scholl de2bcf114c upgrade imohash 2021-04-21 14:36:50 -07:00
Zack Scholl ab5ae5cbb6 add more benchmarks 2021-04-21 12:40:41 -07:00
Zack Scholl 94b3dba034 update readme 2021-04-20 16:01:44 -07:00
Zack 1a47543be9
Merge pull request #344 from k3b/patch-1
Added reference to croc android-version to README.md
2021-04-20 15:59:44 -07:00
Zack Scholl 407e162ec2 bump 9.1.0 2021-04-20 15:57:46 -07:00
Zack 35106d4dbe
Merge pull request #374 from schollz/v91
V91
2021-04-20 15:55:19 -07:00
Zack Scholl d6af319ad8 fix tests 2021-04-20 15:48:13 -07:00
Zack Scholl 85e7576311 fix 2021-04-20 15:44:28 -07:00
Zack Scholl 7ac7be37af check if file exists 2021-04-20 15:36:46 -07:00
Zack Scholl 669aeb377a check if file exists 2021-04-20 15:35:38 -07:00
Zack Scholl b655afb533 choose hash algorithm 2021-04-20 15:32:05 -07:00
Zack Scholl e9949ce3d7 check file size firsty 2021-04-20 09:08:02 -07:00
Zack Scholl 91a3dd5866 Merge branch 'master' of github.com:schollz/croc 2021-04-17 20:42:20 -07:00
Zack Scholl 026487a833 update docker 2021-04-17 20:40:56 -07:00
Zack Scholl f8ef096784 bump 9.0.0 2021-04-17 20:33:18 -07:00
Zack Scholl 0c2089bd4c update deps 2021-04-17 20:32:55 -07:00
Zack Scholl 5ad68b9ced update readme 2021-04-17 20:31:17 -07:00
Zack Scholl 9286b3c965 show folders when receiving 2021-04-17 20:27:51 -07:00
Zack Scholl c1edf24338 fix race condition 2021-04-17 20:07:50 -07:00
Zack Scholl d38fc18390 update deps 2021-04-17 14:31:32 -07:00
Zack Scholl f4cedd1e91 Merge branch 'master' of github.com:schollz/croc 2021-04-17 11:27:25 -07:00
Zack Scholl fc66c3b91f improve readme 2021-04-17 11:27:20 -07:00
Zack Scholl 2ac7d4f31f fix tests 2021-04-17 11:12:15 -07:00
Zack Scholl a96762b942 fix room deletion if room is full 2021-04-17 10:44:10 -07:00
Zack Scholl 0a0f7a03d7 update version 2021-04-17 10:33:38 -07:00
Zack Scholl 8148e191ae bump 2021-04-17 17:31:44 +00:00
Zack Scholl 25a985464a Merge branch 'master' of github.com:schollz/croc 2021-04-17 17:15:02 +00:00
Zack 333ece706e
Merge pull request #369 from schollz/v9
V9
2021-04-17 10:12:42 -07:00
Zack Scholl daf10395a3 update deps 2021-04-17 09:42:11 -07:00
Zack Scholl 9231b1a661 update utils benchmark 2021-04-17 09:39:47 -07:00
Zack Scholl 3e56d4cdb9 use magic bytes instead of checking max 2021-04-17 09:05:27 -07:00
Zack Scholl cec39ba2ce allow changing curve 2021-04-17 09:01:58 -07:00
Zack Scholl 7a997156ed minor 2021-04-16 17:17:32 -07:00
Zack Scholl c02b4f1256 fix: make sure that only pake messages are unencrypted 2021-04-16 17:15:51 -07:00
Zack Scholl babfd5f35f add option to overwrite automatically 2021-04-16 15:14:21 -07:00
Zack Scholl be5ceae8c7 prompt to overwrite 2021-04-16 15:12:11 -07:00
Zack Scholl 6be4080f05 remove hash exchange 2021-04-16 14:25:57 -07:00
Zack Scholl b0693751c1 fix 2021-04-16 14:01:48 -07:00
Zack Scholl 8250a39534 fix: delete room if full and third-party tries to enter 2021-04-16 09:48:11 -07:00
Zack Scholl 2131e99826 use new pake 2021-04-16 09:20:13 -07:00
Zack Scholl 628043b228 fix: do not use part of secret as room name 2021-04-16 08:13:43 -07:00
Zack Scholl 362a30e5e7 Merge branch 'master' of github.com:schollz/croc 2021-04-15 22:05:04 +00:00
Zack 828de41d6c
Merge pull request #361 from tdussa/BrokenSymlink
Transfer symlinks without touching their targets.
2021-04-15 15:01:49 -07:00
Tobias Dussa 876ce5764b Transfer symlinks without touching their targets. 2021-04-15 17:07:23 +02:00
Zack Scholl 59b287df7f Merge branch 'master' of github.com:schollz/croc 2021-04-13 22:40:03 +00:00
Zack 3fd125178f
Merge pull request #341 from MatejKafka/master
Added CROC_CONFIG_DIR env var to support custom config dir path
2021-04-13 15:38:38 -07:00
Zack 136faac448
Merge pull request #355 from stingalleman/patch-1
Remove dollar icons from commands without output
2021-04-13 15:37:22 -07:00
Zack 85a0bfb898
Merge pull request #359 from mizzunet/patch-1
Enhancements to bug_report.md
2021-04-13 15:36:39 -07:00
Missu 4718f3897c
Commented, added bug label
Commented lines need to be manually removed by the user, so no need to remove those anymore
Added "big" label for this, so easily discoverable from the Issues list
2021-04-08 11:42:19 +05:30
Sting Alleman 068d5c1031
Remove dollar icons from commands without output 2021-04-04 22:57:14 +02:00
Zack Scholl 4dfa1a9236 Merge branch 'master' of github.com:schollz/croc 2021-03-26 23:05:01 +00:00
Zack Scholl 6ba6ec9d32 bump 8.6.12 2021-03-26 16:03:51 -07:00
Zack Scholl c373b38b59 bump 8.6.12 2021-03-26 16:03:31 -07:00
Zack Scholl f2af5b7256 don't know why , but won't compile for freebsd/arm
⨯ release failed after 348.00s error=failed to build for freebsd_arm_7: # golang.org/x/net/ipv4
../../../../pkg/mod/golang.org/x/net@v0.0.0-20210326220855-61e056675ecf/ipv4/sys_freebsd.go:37:79: undefined: unix.MCAST_JOIN_GROUP
../../../../pkg/mod/golang.org/x/net@v0.0.0-20210326220855-61e056675ecf/ipv4/sys_freebsd.go:38:79: undefined: unix.MCAST_LEAVE_GROUP
../../../../pkg/mod/golang.org/x/net@v0.0.0-20210326220855-61e056675ecf/ipv4/sys_freebsd.go:39:79: undefined: unix.MCAST_JOIN_SOURCE_GROUP
../../../../pkg/mod/golang.org/x/net@v0.0.0-20210326220855-61e056675ecf/ipv4/sys_freebsd.go:40:79: undefined: unix.MCAST_LEAVE_SOURCE_GROUP
../../../../pkg/mod/golang.org/x/net@v0.0.0-20210326220855-61e056675ecf/ipv4/sys_freebsd.go:41:79: undefined: unix.MCAST_BLOCK_SOURCE
../../../../pkg/mod/golang.org/x/net@v0.0.0-20210326220855-61e056675ecf/ipv4/sys_freebsd.go:42:79: undefined: unix.MCAST_UNBLOCK_SOURCE
2021-03-26 16:02:39 -07:00
Zack Scholl 483f840401 Merge branch 'master' of github.com:schollz/croc 2021-03-26 22:45:03 +00:00
Zack Scholl ff12c33e7f bump 8.6.12 2021-03-26 15:41:45 -07:00
Zack Scholl e4cecf670b update deps 2021-03-26 15:41:13 -07:00
Zack Scholl 94e0e3ca67 Merge branch 'master' of github.com:schollz/croc 2021-03-26 22:40:03 +00:00
Zack Scholl a9d582cc6a lookup using standard dns 2021-03-26 15:39:33 -07:00
k3b ab9396937c
Added reference to croc android-version to README.md
See https://f-droid.org/en/packages/com.github.howeyc.crocgui/ for details
2021-03-25 12:32:17 +01:00
Matej Kafka c1e546ede6
Added CROC_CONFIG_DIR env var to support custom config dir path 2021-03-20 00:50:50 +01:00
Zack Scholl 63ba28c9b0 Merge branch 'master' of github.com:schollz/croc 2021-03-17 17:20:04 +00:00
Zack 6caf72df82
Merge pull request #340 from jfaltis/xdg-basedir-spec-compliance
Add compliance with XDG Base Directory Specification (XDG_CONFIG_HOME)
2021-03-17 10:17:52 -07:00
Jona 2273438373 add compliance with xdg base directory specification in regards to XDG_CONFIG_HOME 2021-03-17 17:45:07 +01:00
Zack Scholl 50a0d86e3d Merge branch 'master' of github.com:schollz/croc 2021-03-15 19:40:02 +00:00
Zack Scholl 50aa24d86d bump 8.6.11 2021-03-15 12:39:04 -07:00
Zack Scholl 674bff7a13 Merge branch 'master' of github.com:schollz/croc 2021-03-15 19:35:03 +00:00
Zack Scholl 757ed180fb update deps 2021-03-15 12:31:07 -07:00
Zack Scholl 76648a2926 Merge branch 'master' of github.com:schollz/croc 2021-03-15 19:05:04 +00:00
Zack Scholl 0b76edc362 update deps 2021-03-15 12:04:48 -07:00
Zack Scholl c39061c7fc Merge branch 'master' of github.com:schollz/croc 2021-03-15 18:55:03 +00:00
Zack Scholl fb2723d80b don't show description if only sending one file 2021-03-15 11:50:30 -07:00
Zack Scholl f84341a197 Merge branch 'master' of github.com:schollz/croc 2021-03-10 16:20:03 +00:00
Zack 6e9156d49c
Merge pull request #337 from alrs/alrs-fix-server-nil-salt-and-keys
src/tcp: fix dropped errors
2021-03-10 08:16:19 -08:00
Zack cd6d9a5aa0
Merge pull request #338 from alrs/alrs-fix-client-swallowed-errs
src/croc: fix dropped errors
2021-03-10 08:16:06 -08:00
Lars Lehtonen 3e5b876a32
src/croc: fix dropped errors 2021-03-09 16:55:42 -08:00
Lars Lehtonen a9487a332c
src/tcp: fix dropped errors 2021-03-09 16:48:38 -08:00
Zack Scholl de924f6a4f Merge branch 'master' of github.com:schollz/croc 2021-03-08 16:45:04 +00:00
Zack Scholl bb05d48fe9 Merge branch 'master' of github.com:schollz/croc 2021-03-08 16:40:02 +00:00
Zack Scholl d49bb8632b Merge branch 'master' of github.com:schollz/croc 2021-03-05 19:05:02 +00:00
Zack Scholl 105fb9a3ce Merge branch 'master' of github.com:schollz/croc 2021-03-05 17:05:02 +00:00
Zack Scholl a46f09ee1c Merge branch 'master' of github.com:schollz/croc 2021-02-23 20:15:02 +00:00
Zack Scholl 40cda1bed7 Merge branch 'master' of github.com:schollz/croc 2021-02-23 20:10:04 +00:00
Zack Scholl b19a028aea Merge branch 'master' of github.com:schollz/croc 2021-02-19 18:30:03 +00:00
Zack Scholl 1cf309faf2 Merge branch 'master' of github.com:schollz/croc 2021-02-11 22:10:05 +00:00
Zack Scholl eaa18cd502 Merge branch 'master' of github.com:schollz/croc 2021-02-10 17:40:04 +00:00
Zack Scholl 89ea0166fa Merge branch 'master' of github.com:schollz/croc 2021-02-03 18:10:04 +00:00
Zack Scholl 4481fe2336 Merge branch 'master' of github.com:schollz/croc 2021-02-02 14:50:03 +00:00
Zack Scholl 0bec0b26ab Merge branch 'master' of github.com:schollz/croc 2021-02-02 14:45:04 +00:00
Zack Scholl 950b6f83d9 Merge branch 'master' of github.com:schollz/croc 2021-02-01 15:00:03 +00:00
Zack Scholl 2f96b77b73 Merge branch 'master' of github.com:schollz/croc 2021-02-01 14:55:02 +00:00
Zack Scholl 77d0c7ae2e Merge branch 'master' of github.com:schollz/croc 2021-01-26 21:20:03 +00:00
Zack Scholl dab683c9dc Merge branch 'master' of github.com:schollz/croc 2020-12-29 17:35:03 +00:00
Zack Scholl e27c32cf6e Merge branch 'master' of github.com:schollz/croc 2020-12-28 19:05:03 +00:00
Zack Scholl 037dbbd4e9 Merge branch 'master' of github.com:schollz/croc 2020-12-28 18:50:06 +00:00
Zack Scholl af5ba6ead8 Merge branch 'master' of github.com:schollz/croc 2020-11-18 00:15:04 +00:00
Zack Scholl 2ffafd4607 Merge branch 'master' of github.com:schollz/croc 2020-11-18 00:10:04 +00:00
Zack Scholl c55e9be0ef Merge branch 'master' of github.com:schollz/croc 2020-10-23 15:30:05 +00:00
Zack Scholl 10ed62cfd5 Merge branch 'master' of github.com:schollz/croc 2020-10-23 15:05:03 +00:00
Zack Scholl cdb1981358 Merge branch 'master' of github.com:schollz/croc 2020-10-23 00:05:04 +00:00
Zack Scholl a45e66733b Merge branch 'master' of github.com:schollz/croc 2020-10-22 17:20:05 +00:00
Zack Scholl d112f43f63 Merge branch 'master' of github.com:schollz/croc 2020-10-22 17:15:04 +00:00
Zack Scholl 05c82809c6 Merge branch 'master' of github.com:schollz/croc 2020-10-22 17:05:04 +00:00
Zack Scholl 6ad8e08b0c Merge branch 'master' of github.com:schollz/croc 2020-10-22 16:55:03 +00:00
Zack Scholl 6c86188564 Merge branch 'master' of github.com:schollz/croc 2020-10-22 14:45:05 +00:00
Zack Scholl 4663df1059 Merge branch 'master' of github.com:schollz/croc 2020-10-22 14:40:04 +00:00
Zack Scholl 61ffdc61f3 Merge branch 'master' of github.com:schollz/croc 2020-10-21 19:55:03 +00:00
Zack Scholl 1a242711cc Merge branch 'master' of github.com:schollz/croc 2020-10-21 17:30:05 +00:00
Zack Scholl 3129b097af use only local 2020-10-21 10:23:12 -07:00
35 changed files with 2714 additions and 776 deletions

View File

@ -2,28 +2,30 @@
name: Bug report
about: Create a report to help us improve
title: ''
labels: ''
assignees: ''
---
<!-- The comments between these brackets won't show up in the submitted issue (as you can see in the Preview). -->
**Please try to [download the latest version](https://github.com/schollz/croc/releases/latest) of croc before reporting a bug!**
**Describe the bug**
A clear and concise description of what the bug is.
<!-- Please try to download latest, https://github.com/schollz/croc/releases/latest of croc before reporting a bug! -->
**To Reproduce**
## Describe the bug
## To Reproduce
Steps to reproduce the behavior:
1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
4. See error
**Expected behavior**
A clear and concise description of what you expected to happen.
1.
2.
3.
4.
**Version**
Check `croc -version` and report it.
## Expected behaviour
## Version
## Additional context
**Additional context**
Add any other context about the problem here.

10
.github/dependabot.yml vendored Normal file
View File

@ -0,0 +1,10 @@
version: 2
updates:
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "daily"
- package-ecosystem: "gomod"
directory: "/"
schedule:
interval: "daily"

18
.github/workflows/ci.yml vendored Normal file
View File

@ -0,0 +1,18 @@
name: CI
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
unit-tests:
name: Go unit tests
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
with:
go-version: '1.20'
- run: go version
- run: go test -v ./...

View File

@ -4,10 +4,15 @@ name: CD
# Controls when the action will run.
on:
# Triggers the workflow on push or pull request events but only for the master branch
# Triggers the workflow on push or pull request events but only for the main branch
push:
branches: [ master ]
branches:
- '*'
tags:
- 'v*'
pull_request:
branches:
- '*'
# Allows you to run this workflow manually from the Actions tab
workflow_dispatch:
@ -19,32 +24,37 @@ jobs:
steps:
-
name: Checkout
uses: actions/checkout@v2
uses: actions/checkout@v4
-
name: Docker meta
id: docker_meta
uses: crazy-max/ghaction-docker-meta@v1
uses: docker/metadata-action@v5
with:
images: schollz/croc
# tag-semver: "{{version}}"
tag-sha: true
tag-latest: true
# generate Docker tags based on the following events/attributes
tags: |
type=ref,event=branch
type=ref,event=pr
type=semver,pattern={{version}}
type=semver,pattern={{major}}.{{minor}}
type=semver,pattern={{major}}
type=sha
-
name: Set up QEMU
uses: docker/setup-qemu-action@v1
uses: docker/setup-qemu-action@v3
-
name: Set up Docker Buildx
uses: docker/setup-buildx-action@v1
uses: docker/setup-buildx-action@v3
-
name: Login to DockerHub
if: github.event_name != 'pull_request'
uses: docker/login-action@v1
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
-
name: Build and push
uses: docker/build-push-action@v2
uses: docker/build-push-action@v5
with:
context: .
file: ./Dockerfile

123
.github/workflows/release.yml vendored Normal file
View File

@ -0,0 +1,123 @@
name: Make release
on:
release:
types: [created]
workflow_dispatch:
permissions:
contents: write
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout project
uses: actions/checkout@v4
- name: Setup Go
uses: actions/setup-go@v4
with:
go-version: '1.20'
- name: Build Windows 7
run: |
CGO_ENABLED=0 GOOS=windows GOARCH=amd64 go build -ldflags '-extldflags "-static"' -o croc.exe
zip croc_${{ github.event.release.name }}_Windows7-64bit.zip croc.exe
CGO_ENABLED=0 GOOS=windows GOARCH=386 go build -ldflags '-extldflags "-static"' -o croc.exe
zip croc_${{ github.event.release.name }}_Windows7-32bit.zip croc.exe
- name: Setup Go
uses: actions/setup-go@v4
with:
go-version: '1.21'
- name: Prepare source tarball
run: |
git clone -b ${{ github.event.release.name }} --depth 1 https://github.com/schollz/croc croc-${{ github.event.release.name }}
cd croc-${{ github.event.release.name }} && go mod tidy && go mod vendor
cd .. && tar -czvf croc_${{ github.event.release.name }}_src.tar.gz croc-${{ github.event.release.name }}
- name: Build files
run: |
CGO_ENABLED=0 GOOS=windows GOARCH=amd64 go build -ldflags '-extldflags "-static"' -o croc.exe
zip croc_${{ github.event.release.name }}_Windows-64bit.zip croc.exe LICENSE
CGO_ENABLED=0 GOOS=windows GOARCH=386 go build -ldflags '-extldflags "-static"' -o croc.exe
zip croc_${{ github.event.release.name }}_Windows-32bit.zip croc.exe LICENSE
CGO_ENABLED=0 GOOS=windows GOARCH=arm go build -ldflags '-extldflags "-static"' -o croc.exe
zip croc_${{ github.event.release.name }}_Windows-ARM.zip croc.exe LICENSE
CGO_ENABLED=0 GOOS=windows GOARCH=arm64 go build -ldflags '-extldflags "-static"' -o croc.exe
zip croc_${{ github.event.release.name }}_Windows-ARM64.zip croc.exe LICENSE
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -ldflags '-extldflags "-static"' -o croc
tar -czvf croc_${{ github.event.release.name }}_Linux-64bit.tar.gz croc LICENSE
CGO_ENABLED=0 GOOS=linux GOARCH=386 go build -ldflags '-extldflags "-static"' -o croc
tar -czvf croc_${{ github.event.release.name }}_Linux-32bit.tar.gz croc LICENSE
CGO_ENABLED=0 GOOS=linux GOARCH=arm go build -ldflags '-extldflags "-static"' -o croc
tar -czvf croc_${{ github.event.release.name }}_Linux-ARM.tar.gz croc LICENSE
CGO_ENABLED=0 GOOS=linux GOARCH=arm64 go build -ldflags '-extldflags "-static"' -o croc
tar -czvf croc_${{ github.event.release.name }}_Linux-ARM64.tar.gz croc LICENSE
CGO_ENABLED=0 GOOS=darwin GOARCH=amd64 go build -ldflags '-s -extldflags "-sectcreate __TEXT __info_plist Info.plist"' -o croc
tar -czvf croc_${{ github.event.release.name }}_macOS-64bit.tar.gz croc LICENSE
CGO_ENABLED=0 GOOS=darwin GOARCH=arm64 go build -ldflags '-s -extldflags "-sectcreate __TEXT __info_plist Info.plist"' -o croc
tar -czvf croc_${{ github.event.release.name }}_macOS-ARM64.tar.gz croc LICENSE
CGO_ENABLED=0 GOOS=dragonfly GOARCH=amd64 go build -ldflags '' -o croc
tar -czvf croc_${{ github.event.release.name }}_DragonFlyBSD-64bit.tar.gz croc LICENSE
CGO_ENABLED=0 GOOS=freebsd GOARCH=amd64 go build -ldflags '' -o croc
tar -czvf croc_${{ github.event.release.name }}_FreeBSD-64bit.tar.gz croc LICENSE
CGO_ENABLED=0 GOOS=freebsd GOARCH=arm64 go build -ldflags '' -o croc
tar -czvf croc_${{ github.event.release.name }}_FreeBSD-ARM64.tar.gz croc LICENSE
CGO_ENABLED=0 GOOS=netbsd GOARCH=386 go build -ldflags '' -o croc
tar -czvf croc_${{ github.event.release.name }}_NetBSD-32bit.tar.gz croc LICENSE
CGO_ENABLED=0 GOOS=netbsd GOARCH=amd64 go build -ldflags '' -o croc
tar -czvf croc_${{ github.event.release.name }}_NetBSD-64bit.tar.gz croc LICENSE
CGO_ENABLED=0 GOOS=netbsd GOARCH=arm64 go build -ldflags '' -o croc
tar -czvf croc_${{ github.event.release.name }}_NetBSD-ARM64.tar.gz croc LICENSE
CGO_ENABLED=0 GOOS=openbsd GOARCH=amd64 go build -ldflags '' -o croc
tar -czvf croc_${{ github.event.release.name }}_OpenBSD-64bit.tar.gz croc LICENSE
CGO_ENABLED=0 GOOS=openbsd GOARCH=arm64 go build -ldflags '' -o croc
tar -czvf croc_${{ github.event.release.name }}_OpenBSD-ARM64.tar.gz croc LICENSE
- name: Create checksums.txt
run: |
touch croc_${{ github.event.release.name }}_checksums.txt
sha256sum croc_${{ github.event.release.name }}_src.tar.gz >> croc_${{ github.event.release.name }}_checksums.txt
sha256sum croc_${{ github.event.release.name }}_Windows-64bit.zip >> croc_${{ github.event.release.name }}_checksums.txt
sha256sum croc_${{ github.event.release.name }}_Windows-32bit.zip >> croc_${{ github.event.release.name }}_checksums.txt
sha256sum croc_${{ github.event.release.name }}_Windows-ARM.zip >> croc_${{ github.event.release.name }}_checksums.txt
sha256sum croc_${{ github.event.release.name }}_Windows-ARM64.zip >> croc_${{ github.event.release.name }}_checksums.txt
sha256sum croc_${{ github.event.release.name }}_Windows7-64bit.zip >> croc_${{ github.event.release.name }}_checksums.txt
sha256sum croc_${{ github.event.release.name }}_Windows7-32bit.zip >> croc_${{ github.event.release.name }}_checksums.txt
sha256sum croc_${{ github.event.release.name }}_Linux-64bit.tar.gz >> croc_${{ github.event.release.name }}_checksums.txt
sha256sum croc_${{ github.event.release.name }}_Linux-32bit.tar.gz >> croc_${{ github.event.release.name }}_checksums.txt
sha256sum croc_${{ github.event.release.name }}_Linux-ARM.tar.gz >> croc_${{ github.event.release.name }}_checksums.txt
sha256sum croc_${{ github.event.release.name }}_Linux-ARM64.tar.gz >> croc_${{ github.event.release.name }}_checksums.txt
sha256sum croc_${{ github.event.release.name }}_macOS-64bit.tar.gz >> croc_${{ github.event.release.name }}_checksums.txt
sha256sum croc_${{ github.event.release.name }}_macOS-ARM64.tar.gz >> croc_${{ github.event.release.name }}_checksums.txt
sha256sum croc_${{ github.event.release.name }}_DragonFlyBSD-64bit.tar.gz >> croc_${{ github.event.release.name }}_checksums.txt
sha256sum croc_${{ github.event.release.name }}_FreeBSD-64bit.tar.gz >> croc_${{ github.event.release.name }}_checksums.txt
sha256sum croc_${{ github.event.release.name }}_FreeBSD-ARM64.tar.gz >> croc_${{ github.event.release.name }}_checksums.txt
sha256sum croc_${{ github.event.release.name }}_NetBSD-32bit.tar.gz >> croc_${{ github.event.release.name }}_checksums.txt
sha256sum croc_${{ github.event.release.name }}_NetBSD-64bit.tar.gz >> croc_${{ github.event.release.name }}_checksums.txt
sha256sum croc_${{ github.event.release.name }}_NetBSD-ARM64.tar.gz >> croc_${{ github.event.release.name }}_checksums.txt
sha256sum croc_${{ github.event.release.name }}_OpenBSD-64bit.tar.gz >> croc_${{ github.event.release.name }}_checksums.txt
sha256sum croc_${{ github.event.release.name }}_OpenBSD-ARM64.tar.gz >> croc_${{ github.event.release.name }}_checksums.txt
- name: Release
uses: softprops/action-gh-release@v2
with:
files: |
croc_${{ github.event.release.name }}_checksums.txt
croc_${{ github.event.release.name }}_src.tar.gz
croc_${{ github.event.release.name }}_Windows-64bit.zip
croc_${{ github.event.release.name }}_Windows-32bit.zip
croc_${{ github.event.release.name }}_Windows-ARM.zip
croc_${{ github.event.release.name }}_Windows-ARM64.zip
croc_${{ github.event.release.name }}_Windows7-64bit.zip
croc_${{ github.event.release.name }}_Windows7-32bit.zip
croc_${{ github.event.release.name }}_Linux-64bit.tar.gz
croc_${{ github.event.release.name }}_Linux-32bit.tar.gz
croc_${{ github.event.release.name }}_Linux-ARM.tar.gz
croc_${{ github.event.release.name }}_Linux-ARM64.tar.gz
croc_${{ github.event.release.name }}_macOS-64bit.tar.gz
croc_${{ github.event.release.name }}_macOS-ARM64.tar.gz
croc_${{ github.event.release.name }}_DragonFlyBSD-64bit.tar.gz
croc_${{ github.event.release.name }}_FreeBSD-64bit.tar.gz
croc_${{ github.event.release.name }}_FreeBSD-ARM64.tar.gz
croc_${{ github.event.release.name }}_NetBSD-32bit.tar.gz
croc_${{ github.event.release.name }}_NetBSD-64bit.tar.gz
croc_${{ github.event.release.name }}_NetBSD-ARM64.tar.gz
croc_${{ github.event.release.name }}_OpenBSD-64bit.tar.gz
croc_${{ github.event.release.name }}_OpenBSD-ARM64.tar.gz

27
.github/workflows/stale.yml vendored Normal file
View File

@ -0,0 +1,27 @@
# This workflow warns and then closes issues and PRs that have had no activity for a specified amount of time.
#
# You can adjust the behavior by modifying this file.
# For more information, see:
# https://github.com/actions/stale
name: Mark stale issues and pull requests
on:
schedule:
- cron: '19 12 * * *'
jobs:
stale:
runs-on: ubuntu-latest
permissions:
issues: write
pull-requests: write
steps:
- uses: actions/stale@v9
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
stale-issue-message: 'Stale issue message'
stale-pr-message: 'Stale pull request message'
stale-issue-label: 'no-issue-activity'
stale-pr-label: 'no-pr-activity'

14
.github/workflows/winget.yml vendored Normal file
View File

@ -0,0 +1,14 @@
name: Publish to Winget
on:
release:
types: [released]
jobs:
publish:
runs-on: ubuntu-latest
steps:
- uses: vedantmgoyal2009/winget-releaser@v2
with:
identifier: schollz.croc
installers-regex: '_Windows-\w+\.zip$'
token: ${{ secrets.WINGET_TOKEN }}

5
.gitignore vendored
View File

@ -6,3 +6,8 @@ bash_autocomplete
dist
bin
croc-stdin*
.idea/
.vscode/
src/utils/bigfile.test
test1/

View File

@ -21,6 +21,8 @@ build:
ignore:
- goos: darwin
goarch: 386
- goos: freebsd
goarch: arm
goarm:
- 7
nfpms:
@ -91,4 +93,8 @@ scoop:
homepage: "https://schollz.com/software/croc/"
description: "croc is a tool that allows any two computers to simply and securely transfer files and folders."
license: MIT
announce:
twitter:
# Wether its enabled or not.
# Defaults to false.
enabled: false

View File

@ -10,12 +10,12 @@ install: true
script:
- env GO111MODULE=on go build -v
- env GO111MODULE=on go test -v -cover github.com/schollz/croc/v8/src/compress
- env GO111MODULE=on go test -v -cover github.com/schollz/croc/v8/src/croc
- env GO111MODULE=on go test -v -cover github.com/schollz/croc/v8/src/crypt
- env GO111MODULE=on go test -v -cover github.com/schollz/croc/v8/src/tcp
- env GO111MODULE=on go test -v -cover github.com/schollz/croc/v8/src/utils
- env GO111MODULE=on go test -v -cover github.com/schollz/croc/v8/src/comm
- env GO111MODULE=on go test -v -cover github.com/schollz/croc/v10/src/compress
- env GO111MODULE=on go test -v -cover github.com/schollz/croc/v10/src/croc
- env GO111MODULE=on go test -v -cover github.com/schollz/croc/v10/src/crypt
- env GO111MODULE=on go test -v -cover github.com/schollz/croc/v10/src/tcp
- env GO111MODULE=on go test -v -cover github.com/schollz/croc/v10/src/utils
- env GO111MODULE=on go test -v -cover github.com/schollz/croc/v10/src/comm
branches:
except:

View File

@ -1,15 +1,16 @@
FROM golang:1.15-alpine as builder
RUN apk add --no-cache git
FROM golang:1.22-alpine as builder
RUN apk add --no-cache git gcc musl-dev
WORKDIR /go/croc
COPY . .
RUN go build -v -ldflags="-s -w"
FROM alpine:latest
FROM alpine:latest
EXPOSE 9009
EXPOSE 9010
EXPOSE 9011
EXPOSE 9012
EXPOSE 9013
COPY --from=builder /go/croc/croc /go/croc/croc-entrypoint.sh /
USER nobody
ENTRYPOINT ["/croc-entrypoint.sh"]
CMD ["relay"]

View File

@ -1,6 +1,6 @@
MIT License
Copyright (c) 2017-2021 Zack
Copyright (c) 2017-2024 Zack
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal

113
README.md
View File

@ -4,18 +4,11 @@
src="https://user-images.githubusercontent.com/6550035/46709024-9b23ad00-cbf6-11e8-9fb2-ca8b20b7dbec.jpg"
width="408px" border="0" alt="croc">
<br>
<a href="https://github.com/schollz/croc/releases/latest"><img src="https://img.shields.io/badge/version-v8.6.10-brightgreen.svg?style=flat-square" alt="Version"></a>
<a href="https://coveralls.io/github/schollz/croc"><img src="https://img.shields.io/badge/coverage-81%25-green.svg?style=flat-square" alt="Coverage"></a>
<a href="https://travis-ci.org/schollz/croc"><img
src="https://img.shields.io/travis/schollz/croc.svg?style=flat-square" alt="Build
<a href="https://github.com/schollz/croc/releases/latest"><img src="https://img.shields.io/badge/version-v10.0.7-brightgreen.svg?style=flat-square" alt="Version"></a>
<a href="https://github.com/schollz/croc/actions/workflows/ci.yml"><img
src="https://github.com/schollz/croc/actions/workflows/ci.yml/badge.svg" alt="Build
Status"></a>
<p align="center">This project is supported by:</p>
<p align="center">
<a href="https://www.digitalocean.com/">
<img src="https://opensource.nyc3.cdn.digitaloceanspaces.com/attribution/assets/SVG/DO_Logo_horizontal_blue.svg" width="201px">
</a>
</p>
</p>
<p align="center">This project is supported by <a href="https://github.com/sponsors/schollz">Github sponsors</a>.</p>
`croc` is a tool that allows any two computers to simply and securely transfer files and folders. AFAIK, *croc* is the only CLI file-transfer tool that does **all** of the following:
@ -28,7 +21,7 @@ Status"></a>
- **ipv6-first** with ipv4 fallback
- can **use proxy**, like tor
For more information about `croc`, see [my blog post](https://schollz.com/software/croc6).
For more information about `croc`, see [my blog post](https://schollz.com/software/croc6) or read a [recent interview I did](https://console.substack.com/p/console-91).
![Example](src/install/customization.gif)
@ -37,76 +30,87 @@ For more information about `croc`, see [my blog post](https://schollz.com/softwa
Download [the latest release for your system](https://github.com/schollz/croc/releases/latest), or install a release from the command-line:
```
$ curl https://getcroc.schollz.com | bash
curl https://getcroc.schollz.com | bash
```
On macOS you can install the latest release with [Homebrew](https://brew.sh/):
```
$ brew install croc
brew install croc
```
On macOS you can also install the latest release with [MacPorts](https://macports.org/):
```
$ sudo port selfupdate
$ sudo port install croc
sudo port selfupdate
sudo port install croc
```
On Windows you can install the latest release with [Scoop](https://scoop.sh/) or [Chocolatey](https://chocolatey.org):
On Windows you can install the latest release with [Scoop](https://scoop.sh/), [Chocolatey](https://chocolatey.org), or [Winget](https://learn.microsoft.com/en-us/windows/package-manager/):
```
$ scoop install croc
scoop install croc
```
```
$ choco install croc
choco install croc
```
```
winget install schollz.croc
```
On Unix you can install the latest release with [Nix](https://nixos.org/nix):
```
$ nix-env -i croc
nix-env -i croc
```
On Alpine Linux you have to install dependencies first:
```
$ apk add bash coreutils
$ wget -qO- https://getcroc.schollz.com | bash
apk add bash coreutils
wget -qO- https://getcroc.schollz.com | bash
```
On Arch Linux you can install the latest release with `pacman`:
```
$ pacman -S croc
pacman -S croc
```
On Fedora you can install with `dnf`:
```
dnf install croc
```
On Gentoo you can install with `portage`:
```
$ emerge net-misc/croc
emerge net-misc/croc
```
On Termux you can install with `pkg`:
```
$ pkg install croc
pkg install croc
```
On FreeBSD you can install with `pkg`:
```
$ pkg install croc
pkg install croc
```
Or, you can [install Go](https://golang.org/dl/) and build from source (requires Go 1.12+):
Or, you can [install Go](https://golang.org/dl/) and build from source (requires Go 1.17+):
```
$ GO111MODULE=on go get -v github.com/schollz/croc/v8
go install github.com/schollz/croc/v10@latest
```
On Android there is a 3rd party F-Droid app [available to download](https://f-droid.org/en/packages/com.github.howeyc.crocgui/).
## Usage
@ -122,7 +126,7 @@ Code is: code-phrase
Then to receive the file (or folder) on another computer, you can just do
```
$ croc code-phrase
croc code-phrase
```
The code phrase is used to establish password-authenticated key agreement ([PAKE](https://en.wikipedia.org/wiki/Password-authenticated_key_agreement)) which generates a secret key for the sender and recipient to use for end-to-end encryption.
@ -131,24 +135,33 @@ There are a number of configurable options (see `--help`). A set of options (lik
### Custom code phrase
You can send with your own code phrase (must be more than 4 characters).
You can send with your own code phrase (must be more than 6 characters).
```
$ croc send --code [code-phrase] [file(s)-or-folder]
croc send --code [code-phrase] [file(s)-or-folder]
```
### Allow overwriting without prompt
By default, croc will prompt whether to overwrite a file. You can automatically overwrite files by using the `--overwrite` flag (recipient only). For example, receive a file to automatically overwrite:
```
croc --yes --overwrite <code>
```
### Use pipes - stdin and stdout
You can pipe to `croc`:
```
$ cat [filename] | croc send
cat [filename] | croc send
```
In this case `croc` will automatically use the stdin data and send and assign a filename like "croc-stdin-123456789". To receive to `stdout` at you can always just use the `--yes` will automatically approve the transfer and pipe it out to `stdout`.
```
$ croc --yes [code-phrase] > out
croc --yes [code-phrase] > out
```
All of the other text printed to the console is going to `stderr` so it will not interfere with the message going to `stdout`.
@ -159,7 +172,7 @@ All of the other text printed to the console is going to `stderr` so it will not
Sometimes you want to send URLs or short text. In addition to piping, you can easily send text with `croc`:
```
$ croc send --text "hello world"
croc send --text "hello world"
```
This will automatically tell the receiver to use `stdout` when they receive the text so it will be displayed.
@ -170,7 +183,25 @@ This will automatically tell the receiver to use `stdout` when they receive the
You can use a proxy as your connection to the relay by adding a proxy address with `--socks5`. For example, you can send via a tor relay:
```
$ croc --socks5 "127.0.0.1:9050" send SOMEFILE
croc --socks5 "127.0.0.1:9050" send SOMEFILE
```
### Change encryption curve
You can choose from several different elliptic curves to use for encryption by using the `--curve` flag. Only the recipient can choose the curve. For example, receive a file using the P-521 curve:
```
croc --curve p521 <codephrase>
```
Available curves are P-256, P-348, P-521 and SIEC. P-256 is the default curve.
### Change hash algorithm
You can choose from several different hash algorithms. The default is the `xxhash` algorithm which is fast and thorough. If you want to optimize for speed you can use the `imohash` algorithm which is even faster, but since it samples files (versus reading the whole file) it can mistakenly determine that a file is the same on the two computers transferring - though this is only a problem if you are syncing files versus sending a new file to a computer.
```
croc send --hash imohash SOMEFILE
```
### Self-host relay
@ -178,15 +209,15 @@ $ croc --socks5 "127.0.0.1:9050" send SOMEFILE
The relay is needed to staple the parallel incoming and outgoing connections. By default, `croc` uses a public relay but you can also run your own relay:
```
$ croc relay
croc relay
```
By default it uses TCP ports 9009-9013. Make sure to open those up. You can customized the ports (e.g. `croc relay --ports 1111,1112`), but you must have a minimum of **2** ports for the relay. The first port is for communication and the subsequent ports are used for the multiplexed data transfer.
By default it uses TCP ports 9009-9013. Make sure to open those up. You can customize the ports (e.g. `croc relay --ports 1111,1112`), but you must have a minimum of **2** ports for the relay. The first port is for communication and the subsequent ports are used for the multiplexed data transfer.
You can send files using your relay by entering `--relay` to change the relay that you are using if you want to custom host your own.
```
$ croc --relay "myrelay.example.com:9009" send [filename]
croc --relay "myrelay.example.com:9009" send [filename]
```
Note, when sending, you only need to include the first port (the communication port). The subsequent ports for data transfer will be transmitted back to the user from the relay.
@ -197,13 +228,13 @@ If it's easier you can also run a relay with Docker:
```
$ docker run -d -p 9009-9013:9009-9013 -e CROC_PASS='YOURPASSWORD' schollz/croc
docker run -d -p 9009-9013:9009-9013 -e CROC_PASS='YOURPASSWORD' schollz/croc
```
Be sure to include the password for the relay otherwise any requests will be rejected.
```
$ croc --pass YOURPASSWORD --relay "myreal.example.com:9009" send [filename]
croc --pass YOURPASSWORD --relay "myreal.example.com:9009" send [filename]
```
Note: when including `--pass YOURPASSWORD` you can instead pass a file with the password, e.g. `--pass FILEWITHPASSWORD`.
@ -214,6 +245,6 @@ MIT
## Acknowledgements
`croc` has gone through many iterations, and I am awed by all the great contributions! If you feel like contributing, in any way, by all means you can send an Issue, a PR, ask a question, or tweet me ([@yakczar](http://ctt.ec/Rq054)).
`croc` has gone through many iterations, and I am awed by all the great contributions! If you feel like contributing, in any way, by all means you can send an Issue, a PR, or ask a question.
Thanks [@warner](https://github.com/warner) for the [idea](https://github.com/warner/magic-wormhole), [@tscholl2](https://github.com/tscholl2) for the [encryption gists](https://gist.github.com/tscholl2/dc7dc15dc132ea70a98e8542fefffa28), [@skorokithakis](https://github.com/skorokithakis) for [code on proxying two connections](https://www.stavros.io/posts/proxying-two-connections-go/). Finally thanks for making pull requests [@maximbaz](https://github.com/maximbaz), [@meyermarcel](https://github.com/meyermarcel), [@Girbons](https://github.com/Girbons), [@techtide](https://github.com/techtide), [@heymatthew](https://github.com/heymatthew), [@Lunsford94](https://github.com/Lunsford94), [@lummie](https://github.com/lummie), [@jesuiscamille](https://github.com/jesuiscamille), [@threefjord](https://github.com/threefjord), [@marcossegovia](https://github.com/marcossegovia), [@csleong98](https://github.com/csleong98), [@afotescu](https://github.com/afotescu), [@callmefever](https://github.com/callmefever), [@El-JojA](https://github.com/El-JojA), [@anatolyyyyyy](https://github.com/anatolyyyyyy), [@goggle](https://github.com/goggle), [@smileboywtu](https://github.com/smileboywtu), [@nicolashardy](https://github.com/nicolashardy), [@fbartels](https://github.com/fbartels), [@rkuprov](https://github.com/rkuprov), [@hreese](https://github.com/hreese), [@xenrox](https://github.com/xenrox) and [Ipar](https://github.com/lpar)!

View File

@ -4,7 +4,7 @@ After=network.target
[Service]
Type=simple
User=nobody
DynamicUser=yes
CapabilityBoundingSet=CAP_NET_BIND_SERVICE
ExecStart=/usr/bin/croc relay

54
go.mod
View File

@ -1,28 +1,42 @@
module github.com/schollz/croc/v8
module github.com/schollz/croc/v10
go 1.13
go 1.20
require (
github.com/OneOfOne/xxhash v1.2.5 // indirect
github.com/cespare/xxhash v1.1.0
github.com/cpuguy83/go-md2man/v2 v2.0.0 // indirect
github.com/chzyer/readline v1.5.1
github.com/denisbrodbeck/machineid v1.0.1
github.com/kalafut/imohash v1.0.0
github.com/kr/pretty v0.1.0 // indirect
github.com/russross/blackfriday/v2 v2.1.0 // indirect
github.com/kalafut/imohash v1.0.3
github.com/sabhiram/go-gitignore v0.0.0-20210923224102-525f6e181f06
github.com/schollz/cli/v2 v2.2.1
github.com/schollz/logger v1.2.0
github.com/schollz/mnemonicode v1.0.1
github.com/schollz/pake/v2 v2.0.6
github.com/schollz/peerdiscovery v1.6.3
github.com/schollz/progressbar/v3 v3.7.4
github.com/spaolacci/murmur3 v1.1.0 // indirect
github.com/stretchr/testify v1.6.1
github.com/tscholl2/siec v0.0.0-20191122224205-8da93652b094
golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110
golang.org/x/sys v0.0.0-20210305230114-8fe3ee5dd75b // indirect
golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d // indirect
golang.org/x/text v0.3.5 // indirect
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 // indirect
github.com/schollz/mnemonicode v1.0.2-0.20190421205639-63fa713ece0d
github.com/schollz/pake/v3 v3.0.5
github.com/schollz/peerdiscovery v1.7.3
github.com/schollz/progressbar/v3 v3.14.3
github.com/stretchr/testify v1.9.0
golang.org/x/crypto v0.23.0
golang.org/x/net v0.25.0
golang.org/x/time v0.5.0
)
require github.com/minio/highwayhash v1.0.2
require (
github.com/OneOfOne/xxhash v1.2.8 // indirect
github.com/cpuguy83/go-md2man/v2 v2.0.4 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/magisterquis/connectproxy v0.0.0-20200725203833-3582e84f0c9b
github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/rivo/uniseg v0.4.7 // indirect
github.com/russross/blackfriday/v2 v2.1.0 // indirect
github.com/spaolacci/murmur3 v1.1.0 // indirect
github.com/tscholl2/siec v0.0.0-20240310163802-c2c6f6198406 // indirect
github.com/twmb/murmur3 v1.1.8 // indirect
golang.org/x/sys v0.20.0 // indirect
golang.org/x/term v0.20.0 // indirect
golang.org/x/text v0.15.0 // indirect
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)

136
go.sum
View File

@ -1,90 +1,132 @@
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
github.com/OneOfOne/xxhash v1.2.5 h1:zl/OfRA6nftbBK9qTohYBJ5xvw6C/oNKizR7cZGl3cI=
github.com/OneOfOne/xxhash v1.2.5/go.mod h1:eZbhyaAYD41SGSSsnmcpxVoRiQ/MPUTjUdIIOT9Um7Q=
github.com/OneOfOne/xxhash v1.2.8 h1:31czK/TI9sNkxIKfaUfGlU47BAxQ0ztGgd9vPyqimf8=
github.com/OneOfOne/xxhash v1.2.8/go.mod h1:eZbhyaAYD41SGSSsnmcpxVoRiQ/MPUTjUdIIOT9Um7Q=
github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko=
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
github.com/chzyer/logex v1.2.1 h1:XHDu3E6q+gdHgsdTPH6ImJMIp436vR6MPtH8gP05QzM=
github.com/chzyer/logex v1.2.1/go.mod h1:JLbx6lG2kDbNRFnfkgvh4eRJRPX1QCoOIWomwysCBrQ=
github.com/chzyer/readline v1.5.1 h1:upd/6fQk4src78LMRzh5vItIt361/o4uq553V8B5sGI=
github.com/chzyer/readline v1.5.1/go.mod h1:Eh+b79XXUwfKfcPLepksvw2tcLE/Ct21YObkaSkeBlk=
github.com/chzyer/test v1.0.0 h1:p3BQDXSxOhOG0P9z6/hGnII4LGiEPOYBhs8asl/fC04=
github.com/chzyer/test v1.0.0/go.mod h1:2JlltgoNkt4TW/z9V/IzDdFaMTM2JPIi26O1pF38GC8=
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
github.com/cpuguy83/go-md2man/v2 v2.0.0 h1:EoUDS0afbrsXAZ9YQ9jdu/mZ2sXgT1/2yyNng4PGlyM=
github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
github.com/cpuguy83/go-md2man/v2 v2.0.4 h1:wfIWP927BUkWJb2NmU/kNDYIBTh/ziUX91+lVfRxZq4=
github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/denisbrodbeck/machineid v1.0.1 h1:geKr9qtkB876mXguW2X6TU4ZynleN6ezuMSRhl4D7AQ=
github.com/denisbrodbeck/machineid v1.0.1/go.mod h1:dJUwb7PTidGDeYyUBmXZ2GphQBbjJCrnectwCyxcUSI=
github.com/k0kubun/go-ansi v0.0.0-20180517002512-3bf9e2903213/go.mod h1:vNUNkEQ1e29fT/6vq2aBdFsgNPmy8qMdSay1npru+Sw=
github.com/kalafut/imohash v1.0.0 h1:LgCJ+p/BwM2HKpOxFopkeddpzVCfm15EtXMroXD1SYE=
github.com/kalafut/imohash v1.0.0/go.mod h1:c3RHT80ZAp5C/aYgQI92ZlrOymqkZnRDprU87kg75HI=
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kalafut/imohash v1.0.3 h1:p9c61km8+6ZMqKRnERwdoxp/CztrdLNEbpsyGgf+A4M=
github.com/kalafut/imohash v1.0.3/go.mod h1:6cn9lU0Sj8M4eu9UaQm1kR/5y3k/ayB68yntRhGloL4=
github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI=
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
github.com/mattn/go-runewidth v0.0.10 h1:CoZ3S2P7pvtP45xOtBw+/mDL2z0RKI576gSkzRRpdGg=
github.com/mattn/go-runewidth v0.0.10/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk=
github.com/magisterquis/connectproxy v0.0.0-20200725203833-3582e84f0c9b h1:xZ59n7Frzh8CwyfAapUZLSg+gXH5m63YEaFCMpDHhpI=
github.com/magisterquis/connectproxy v0.0.0-20200725203833-3582e84f0c9b/go.mod h1:uDd4sYVYsqcxAB8j+Q7uhL6IJCs/r1kxib1HV4bgOMg=
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/minio/highwayhash v1.0.2 h1:Aak5U0nElisjDCfPSG79Tgzkn2gl66NxOMspRrKnA/g=
github.com/minio/highwayhash v1.0.2/go.mod h1:BQskDq+xkJ12lmlUUi7U0M5Swg3EWR+dLTk+kldvVxY=
github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db h1:62I3jR2EmQ4l5rM/4FEfDWcRD+abF5XlKShorW5LRoQ=
github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db/go.mod h1:l0dey0ia/Uv7NcFFVbCLtqEBQbrT4OCwCSKTEv6enCw=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY=
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ=
github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk=
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/sabhiram/go-gitignore v0.0.0-20210923224102-525f6e181f06 h1:OkMGxebDjyw0ULyrTYWeN0UNCCkmCWfjPnIA2W6oviI=
github.com/sabhiram/go-gitignore v0.0.0-20210923224102-525f6e181f06/go.mod h1:+ePHsJ1keEjQtpvf9HHw0f4ZeJ0TLRsxhunSI2hYJSs=
github.com/schollz/cli/v2 v2.2.1 h1:ou22Mj7ZPjrKz+8k2iDTWaHskEEV5NiAxGrdsCL36VU=
github.com/schollz/cli/v2 v2.2.1/go.mod h1:My6bfphRLZUhZdlFUK8scAxMWHydE7k4s2ed2Dtnn+s=
github.com/schollz/logger v1.2.0 h1:5WXfINRs3lEUTCZ7YXhj0uN+qukjizvITLm3Ca2m0Ho=
github.com/schollz/logger v1.2.0/go.mod h1:P6F4/dGMGcx8wh+kG1zrNEd4vnNpEBY/mwEMd/vn6AM=
github.com/schollz/mnemonicode v1.0.1 h1:LiH5hwADZwjwnfXsaD4xgnMyTAtaKHN+e5AyjRU6WSU=
github.com/schollz/mnemonicode v1.0.1/go.mod h1:cl4UAOhUV0mkdjMj/QYaUZbZZdF8BnOqoz8rHMzwboY=
github.com/schollz/pake/v2 v2.0.6 h1:+x8vTmj4uPHe7TNBcCjcwDmm9uMeFIEqh34u+5a+CCY=
github.com/schollz/pake/v2 v2.0.6/go.mod h1:0NENjRsJxJQQ23Ei2fMSPo/mOtURNk/BWr3Cr9zpJ0w=
github.com/schollz/peerdiscovery v1.6.3 h1:qoawrl3GBwf8ff3Itb0QkaUGDb2k40NwE24MEgFL4Gc=
github.com/schollz/peerdiscovery v1.6.3/go.mod h1:xpt6HDA944jqSLzJMLreYtmhWeS2OW2XW4ZLmCezi00=
github.com/schollz/progressbar/v3 v3.7.4 h1:G2HfclnGJR2HtTOmFkERQcRqo9J20asOFiuD6AnI5EQ=
github.com/schollz/progressbar/v3 v3.7.4/go.mod h1:1H8m5kMPW6q5fyjpDqtBHW1JT22mu2NwHQ1ApuCPh/8=
github.com/schollz/mnemonicode v1.0.2-0.20190421205639-63fa713ece0d h1:3zCjdgCJbo9Fot3UoqZkpGiDgT6Nf+iUnOsDEJQay+c=
github.com/schollz/mnemonicode v1.0.2-0.20190421205639-63fa713ece0d/go.mod h1:cl4UAOhUV0mkdjMj/QYaUZbZZdF8BnOqoz8rHMzwboY=
github.com/schollz/pake/v3 v3.0.5 h1:MnZVdI987lkjln9BSx/zUb724TZISa2jbO+dPj6BvgQ=
github.com/schollz/pake/v3 v3.0.5/go.mod h1:OGbG6htRwSKo6V8R5tg61ufpFmZM1b/PrrSp6g2ZLLc=
github.com/schollz/peerdiscovery v1.7.3 h1:/pt1G0rZ80fSPoI/FgGC5P7MxpkRXD6u0pe6PJbYcIE=
github.com/schollz/peerdiscovery v1.7.3/go.mod h1:mVlPNJ5DWbMi52VzpXxGbqXKdFANx3qw0Jsp3EQMCrE=
github.com/schollz/progressbar/v3 v3.14.3 h1:oOuWW19ka12wxYU1XblR4n16wF/2Y1dBLMarMo6p4xU=
github.com/schollz/progressbar/v3 v3.14.3/go.mod h1:aT3UQ7yGm+2ZjeXPqsjTenwL3ddUiuZ0kfQ/2tHlyNI=
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI=
github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0=
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/tscholl2/siec v0.0.0-20191122224205-8da93652b094 h1:tZWtuLE+LbUwT4OP1oWBSB9zXA8qmQ5qEm4kV9R72oo=
github.com/tscholl2/siec v0.0.0-20191122224205-8da93652b094/go.mod h1:KL9+ubr1JZdaKjgAaHr+tCytEncXBa1pR6FjbTsOJnw=
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/tscholl2/siec v0.0.0-20210707234609-9bdfc483d499/go.mod h1:KL9+ubr1JZdaKjgAaHr+tCytEncXBa1pR6FjbTsOJnw=
github.com/tscholl2/siec v0.0.0-20240310163802-c2c6f6198406 h1:sDWDZkwYqX0jvLWstKzFwh+pYhQNaVg65BgSkCP/f7U=
github.com/tscholl2/siec v0.0.0-20240310163802-c2c6f6198406/go.mod h1:KL9+ubr1JZdaKjgAaHr+tCytEncXBa1pR6FjbTsOJnw=
github.com/twmb/murmur3 v1.1.5/go.mod h1:Qq/R7NUyOfr65zD+6Q5IHKsJLwP7exErjN6lyyq3OSQ=
github.com/twmb/murmur3 v1.1.8 h1:8Yt9taO/WN3l08xErzjeschgZU2QSrwm1kclYq+0aRg=
github.com/twmb/murmur3 v1.1.8/go.mod h1:Qq/R7NUyOfr65zD+6Q5IHKsJLwP7exErjN6lyyq3OSQ=
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83 h1:/ZScEX8SfEmUGRHs0gxpqteO5nfNW6axyZbBdw9A12g=
golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110 h1:qWPm9rbaAMKs8Bq/9LRpbMqxWRVUAQwMI9fVrssnTfw=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU=
golang.org/x/crypto v0.23.0 h1:dIJU/v2J8Mdglj/8rJ6UUOM3Zc9zLZxVZwwxMooUSAI=
golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44=
golang.org/x/net v0.25.0 h1:d/OCCoBEUq33pjydKrGQhw7IlUPI2Oylr+8qLx49kac=
golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20190130150945-aca44879d564/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210305230114-8fe3ee5dd75b h1:ggRgirZABFolTmi3sn6Ivd9SipZwLedQ5wR0aAKnFxU=
golang.org/x/sys v0.0.0-20210305230114-8fe3ee5dd75b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220310020820-b874c991c1a5/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y=
golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20201210144234-2321bbc49cbf/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d h1:SZxvLBoTP5yHO3Frd4z4vrF+DBX9vMVanchswa69toE=
golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk=
golang.org/x/term v0.20.0 h1:VnkxpohqXaOBYJtBmEppKUG6mXpi+4O6purfc2+sMhw=
golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.5 h1:i6eZZ+zk0SOf0xgBpEpPD18qWcJda6q1sxt3S0kzyUQ=
golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
golang.org/x/text v0.15.0 h1:h1V/4gjBv8v9cjcR6+AR5+/cIYK5N/WAgiv4xlsEtAk=
golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk=
golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/tylerb/is.v1 v1.1.2 h1:AB/MANFml2ySf+adwcinvajyHvsYltAOD+rb/8njfSU=
gopkg.in/tylerb/is.v1 v1.1.2/go.mod h1:9yQB2tyIhZ5oph6Kk5Sq7cJMd9c5Jpa1p3hr9kxzPqo=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

View File

@ -7,7 +7,7 @@ package main
import (
"log"
"github.com/schollz/croc/v8/src/cli"
"github.com/schollz/croc/v10/src/cli"
)
func main() {

View File

@ -5,21 +5,24 @@ import (
"errors"
"fmt"
"io"
"io/ioutil"
"os"
"path"
"path/filepath"
"runtime"
"strconv"
"strings"
"time"
"github.com/chzyer/readline"
"github.com/schollz/cli/v2"
"github.com/schollz/croc/v8/src/comm"
"github.com/schollz/croc/v8/src/croc"
"github.com/schollz/croc/v8/src/models"
"github.com/schollz/croc/v8/src/tcp"
"github.com/schollz/croc/v8/src/utils"
"github.com/schollz/croc/v10/src/comm"
"github.com/schollz/croc/v10/src/croc"
"github.com/schollz/croc/v10/src/models"
"github.com/schollz/croc/v10/src/tcp"
"github.com/schollz/croc/v10/src/utils"
log "github.com/schollz/logger"
"github.com/schollz/mnemonicode"
"github.com/schollz/pake/v3"
)
// Version specifies the version
@ -33,7 +36,7 @@ func Run() (err error) {
app := cli.NewApp()
app.Name = "croc"
if Version == "" {
Version = "v8.6.10-0b719b9"
Version = "v10.0.7"
}
app.Version = Version
app.Compiled = time.Now()
@ -41,6 +44,15 @@ func Run() (err error) {
app.UsageText = `Send a file:
croc send file.txt
-git to respect your .gitignore
Send multiple files:
croc send file1.txt file2.txt file3.txt
or
croc send *.jpg
Send everything in a folder:
croc send example-folder-name
Send a file with a custom code:
croc send --code secret-code file.txt
@ -49,35 +61,38 @@ func Run() (err error) {
app.Commands = []*cli.Command{
{
Name: "send",
Usage: "send a file (see options with croc send -h)",
Description: "send a file over the relay",
ArgsUsage: "[filename]",
Usage: "send file(s), or folder (see options with croc send -h)",
Description: "send file(s), or folder, over the relay",
ArgsUsage: "[filename(s) or folder]",
Flags: []cli.Flag{
&cli.BoolFlag{Name: "zip", Usage: "zip folder before sending"},
&cli.StringFlag{Name: "code", Aliases: []string{"c"}, Usage: "codephrase used to connect to relay"},
&cli.StringFlag{Name: "hash", Value: "xxhash", Usage: "hash algorithm (xxhash, imohash, md5)"},
&cli.StringFlag{Name: "text", Aliases: []string{"t"}, Usage: "send some text"},
&cli.BoolFlag{Name: "no-local", Usage: "disable local relay when sending"},
&cli.BoolFlag{Name: "no-multi", Usage: "disable multiplexing"},
&cli.StringFlag{Name: "ports", Value: "9009,9010,9011,9012,9013", Usage: "ports of the local relay (optional)"},
&cli.BoolFlag{Name: "git", Usage: "enable .gitignore respect / don't send ignored files"},
&cli.IntFlag{Name: "port", Value: 9009, Usage: "base port for the relay"},
&cli.IntFlag{Name: "transfers", Value: 4, Usage: "number of ports to use for transfers"},
},
HelpName: "croc send",
Action: func(c *cli.Context) error {
return send(c)
},
Action: send,
},
{
Name: "relay",
Usage: "start your own relay (optional)",
Description: "start relay",
HelpName: "croc relay",
Action: func(c *cli.Context) error {
return relay(c)
},
Action: relay,
Flags: []cli.Flag{
&cli.StringFlag{Name: "host", Usage: "host of the relay"},
&cli.StringFlag{Name: "ports", Value: "9009,9010,9011,9012,9013", Usage: "ports of the relay"},
},
},
}
app.Flags = []cli.Flag{
&cli.BoolFlag{Name: "internal-dns", Usage: "use a built-in DNS stub resolver rather than the host operating system"},
&cli.BoolFlag{Name: "classic", Usage: "toggle between the classic mode (insecure due to local attack vector) and new mode (secure)"},
&cli.BoolFlag{Name: "remember", Usage: "save these settings to reuse next time"},
&cli.BoolFlag{Name: "debug", Usage: "toggle debug mode"},
&cli.BoolFlag{Name: "yes", Usage: "automatically agree to all prompts"},
@ -86,12 +101,17 @@ func Run() (err error) {
&cli.BoolFlag{Name: "ask", Usage: "make sure sender and recipient are prompted"},
&cli.BoolFlag{Name: "local", Usage: "force to use only local connections"},
&cli.BoolFlag{Name: "ignore-stdin", Usage: "ignore piped stdin"},
&cli.BoolFlag{Name: "overwrite", Usage: "do not prompt to overwrite"},
&cli.BoolFlag{Name: "testing", Usage: "flag for testing purposes"},
&cli.StringFlag{Name: "curve", Value: "p256", Usage: "choose an encryption curve (" + strings.Join(pake.AvailableCurves(), ", ") + ")"},
&cli.StringFlag{Name: "ip", Value: "", Usage: "set sender ip if known e.g. 10.0.0.1:9009, [::1]:9009"},
&cli.StringFlag{Name: "relay", Value: models.DEFAULT_RELAY, Usage: "address of the relay", EnvVars: []string{"CROC_RELAY"}},
&cli.StringFlag{Name: "relay6", Value: models.DEFAULT_RELAY6, Usage: "ipv6 address of the relay", EnvVars: []string{"CROC_RELAY6"}},
&cli.StringFlag{Name: "out", Value: ".", Usage: "specify an output folder to receive the file"},
&cli.StringFlag{Name: "pass", Value: models.DEFAULT_PASSPHRASE, Usage: "password for the relay", EnvVars: []string{"CROC_PASS"}},
&cli.StringFlag{Name: "socks5", Value: "", Usage: "add a socks5 proxy", EnvVars: []string{"SOCKS5_PROXY"}},
&cli.StringFlag{Name: "connect", Value: "", Usage: "add a http proxy", EnvVars: []string{"HTTP_PROXY"}},
&cli.StringFlag{Name: "throttleUpload", Value: "", Usage: "Throttle the upload speed e.g. 500k"},
}
app.EnableBashCompletion = true
app.HideHelp = false
@ -106,6 +126,61 @@ func Run() (err error) {
return true
}
// check if "classic" is set
classicFile := getClassicConfigFile(true)
classicInsecureMode := utils.Exists(classicFile)
if c.Bool("classic") {
if classicInsecureMode {
// classic mode not enabled
fmt.Print(`Classic mode is currently ENABLED.
Disabling this mode will prevent the shared secret from being visible
on the host's process list when passed via the command line. On a
multi-user system, this will help ensure that other local users cannot
access the shared secret and receive the files instead of the intended
recipient.
Do you wish to continue to DISABLE the classic mode? (Y/n) `)
choice := strings.ToLower(utils.GetInput(""))
if choice == "y" || choice == "yes" {
os.Remove(classicFile)
fmt.Print("\nClassic mode DISABLED.\n\n")
fmt.Print(`To send and receive, export the CROC_SECRET variable with the code phrase:
Send: CROC_SECRET=*** croc send file.txt
Receive: CROC_SECRET=*** croc` + "\n\n")
} else {
fmt.Print("\nClassic mode ENABLED.\n")
}
} else {
// enable classic mode
// touch the file
fmt.Print(`Classic mode is currently DISABLED.
Please note that enabling this mode will make the shared secret visible
on the host's process list when passed via the command line. On a
multi-user system, this could allow other local users to access the
shared secret and receive the files instead of the intended recipient.
Do you wish to continue to enable the classic mode? (Y/n) `)
choice := strings.ToLower(utils.GetInput(""))
if choice == "y" || choice == "yes" {
fmt.Print("\nClassic mode ENABLED.\n\n")
os.WriteFile(classicFile, []byte("enabled"), 0o644)
fmt.Print(`To send and receive, use the code phrase:
Send: croc send --code *** file.txt
Receive: croc ***` + "\n\n")
} else {
fmt.Print("\nClassic mode DISABLED.\n")
}
}
os.Exit(0)
}
// if trying to send but forgot send, let the user know
if c.Args().Present() && allStringsAreFiles(c.Args().Slice()) {
fnames := []string{}
@ -113,31 +188,19 @@ func Run() (err error) {
_, basename := filepath.Split(fpath)
fnames = append(fnames, "'"+basename+"'")
}
yn := utils.GetInput(fmt.Sprintf("Did you mean to send %s? (y/n) ", strings.Join(fnames, ", ")))
if strings.ToLower(yn) == "y" {
promptMessage := fmt.Sprintf("Did you mean to send %s? (Y/n) ", strings.Join(fnames, ", "))
choice := strings.ToLower(utils.GetInput(promptMessage))
if choice == "" || choice == "y" || choice == "yes" {
return send(c)
}
}
return receive(c)
}
return app.Run(os.Args)
}
func getConfigDir() (homedir string, err error) {
homedir, err = os.UserHomeDir()
if err != nil {
log.Error(err)
return
}
homedir = path.Join(homedir, ".config", "croc")
if _, err = os.Stat(homedir); os.IsNotExist(err) {
log.Debugf("creating home directory %s", homedir)
err = os.MkdirAll(homedir, 0700)
}
return
}
func setDebugLevel(c *cli.Context) {
if c.Bool("debug") {
log.SetLevel("debug")
@ -147,8 +210,8 @@ func setDebugLevel(c *cli.Context) {
}
}
func getConfigFile() string {
configFile, err := getConfigDir()
func getSendConfigFile(requireValidPath bool) string {
configFile, err := utils.GetConfigDir(requireValidPath)
if err != nil {
log.Error(err)
return ""
@ -156,9 +219,27 @@ func getConfigFile() string {
return path.Join(configFile, "send.json")
}
func getClassicConfigFile(requireValidPath bool) string {
configFile, err := utils.GetConfigDir(requireValidPath)
if err != nil {
log.Error(err)
return ""
}
return path.Join(configFile, "classic_enabled")
}
func getReceiveConfigFile(requireValidPath bool) (string, error) {
configFile, err := utils.GetConfigDir(requireValidPath)
if err != nil {
log.Error(err)
return "", err
}
return path.Join(configFile, "receive.json"), nil
}
func determinePass(c *cli.Context) (pass string) {
pass = c.String("pass")
b, err := ioutil.ReadFile(pass)
b, err := os.ReadFile(pass)
if err == nil {
pass = strings.TrimSpace(string(b))
}
@ -168,6 +249,22 @@ func determinePass(c *cli.Context) (pass string) {
func send(c *cli.Context) (err error) {
setDebugLevel(c)
comm.Socks5Proxy = c.String("socks5")
comm.HttpProxy = c.String("connect")
portParam := c.Int("port")
if portParam == 0 {
portParam = 9009
}
transfersParam := c.Int("transfers")
if transfersParam == 0 {
transfersParam = 4
}
ports := make([]string, transfersParam+1)
for i := 0; i <= transfersParam; i++ {
ports[i] = strconv.Itoa(portParam + i)
}
crocOptions := croc.Options{
SharedSecret: c.String("code"),
IsSender: true,
@ -179,19 +276,25 @@ func send(c *cli.Context) (err error) {
DisableLocal: c.Bool("no-local"),
OnlyLocal: c.Bool("local"),
IgnoreStdin: c.Bool("ignore-stdin"),
RelayPorts: strings.Split(c.String("ports"), ","),
RelayPorts: ports,
Ask: c.Bool("ask"),
NoMultiplexing: c.Bool("no-multi"),
RelayPassword: determinePass(c),
SendingText: c.String("text") != "",
NoCompress: c.Bool("no-compress"),
Overwrite: c.Bool("overwrite"),
Curve: c.String("curve"),
HashAlgorithm: c.String("hash"),
ThrottleUpload: c.String("throttleUpload"),
ZipFolder: c.Bool("zip"),
GitIgnore: c.Bool("git"),
}
if crocOptions.RelayAddress != models.DEFAULT_RELAY {
crocOptions.RelayAddress6 = ""
} else if crocOptions.RelayAddress6 != models.DEFAULT_RELAY6 {
crocOptions.RelayAddress = ""
}
b, errOpen := ioutil.ReadFile(getConfigFile())
b, errOpen := os.ReadFile(getSendConfigFile(false))
if errOpen == nil && !c.Bool("remember") {
var rememberedOptions croc.Options
err = json.Unmarshal(b, &rememberedOptions)
@ -200,21 +303,39 @@ func send(c *cli.Context) (err error) {
return
}
// update anything that isn't explicitly set
if !c.IsSet("relay") {
if !c.IsSet("relay") && rememberedOptions.RelayAddress != "" {
crocOptions.RelayAddress = rememberedOptions.RelayAddress
}
if !c.IsSet("no-local") {
crocOptions.DisableLocal = rememberedOptions.DisableLocal
}
if !c.IsSet("ports") {
if !c.IsSet("ports") && len(rememberedOptions.RelayPorts) > 0 {
crocOptions.RelayPorts = rememberedOptions.RelayPorts
}
if !c.IsSet("code") {
crocOptions.SharedSecret = rememberedOptions.SharedSecret
}
if !c.IsSet("pass") {
if !c.IsSet("pass") && rememberedOptions.RelayPassword != "" {
crocOptions.RelayPassword = rememberedOptions.RelayPassword
}
if !c.IsSet("relay6") && rememberedOptions.RelayAddress6 != "" {
crocOptions.RelayAddress6 = rememberedOptions.RelayAddress6
}
if !c.IsSet("overwrite") {
crocOptions.Overwrite = rememberedOptions.Overwrite
}
if !c.IsSet("curve") && rememberedOptions.Curve != "" {
crocOptions.Curve = rememberedOptions.Curve
}
if !c.IsSet("local") {
crocOptions.OnlyLocal = rememberedOptions.OnlyLocal
}
if !c.IsSet("hash") {
crocOptions.HashAlgorithm = rememberedOptions.HashAlgorithm
}
if !c.IsSet("git") {
crocOptions.GitIgnore = rememberedOptions.GitIgnore
}
}
var fnames []string
@ -246,15 +367,40 @@ func send(c *cli.Context) (err error) {
fnames = c.Args().Slice()
}
if len(fnames) == 0 {
return errors.New("must specify file: croc send [filename]")
return errors.New("must specify file: croc send [filename(s) or folder]")
}
classicInsecureMode := utils.Exists(getClassicConfigFile(true))
if !classicInsecureMode {
// if operating system is UNIX, then use environmental variable to set the code
if (!(runtime.GOOS == "windows") && c.IsSet("code")) || os.Getenv("CROC_SECRET") != "" {
crocOptions.SharedSecret = os.Getenv("CROC_SECRET")
if crocOptions.SharedSecret == "" {
fmt.Printf(`On UNIX systems, to send with a custom code phrase,
you need to set the environmental variable CROC_SECRET:
export CROC_SECRET="****"
croc send file.txt
Or you can have the code phrase automaticlaly generated:
croc send file.txt
Or you can go back to the classic croc behavior by enabling classic mode:
croc --classic
`)
os.Exit(0)
}
}
}
if len(crocOptions.SharedSecret) == 0 {
// generate code phrase
crocOptions.SharedSecret = utils.GetRandomName()
}
paths, haveFolder, err := getPaths(fnames)
minimalFileInfos, emptyFoldersToTransfer, totalNumberFolders, err := croc.GetFilesInfo(fnames, crocOptions.ZipFolder, crocOptions.GitIgnore)
if err != nil {
return
}
@ -267,16 +413,13 @@ func send(c *cli.Context) (err error) {
// save the config
saveConfig(c, crocOptions)
err = cr.Send(croc.TransferOptions{
PathToFiles: paths,
KeepPathInRemote: haveFolder,
})
err = cr.Send(minimalFileInfos, emptyFoldersToTransfer, totalNumberFolders)
return
}
func getStdin() (fnames []string, err error) {
f, err := ioutil.TempFile(".", "croc-stdin-")
f, err := os.CreateTemp(".", "croc-stdin-")
if err != nil {
return
}
@ -293,7 +436,7 @@ func getStdin() (fnames []string, err error) {
}
func makeTempFileWithString(s string) (fnames []string, err error) {
f, err := ioutil.TempFile(".", "croc-stdin-")
f, err := os.CreateTemp(".", "croc-stdin-")
if err != nil {
return
}
@ -309,43 +452,11 @@ func makeTempFileWithString(s string) (fnames []string, err error) {
}
fnames = []string{f.Name()}
return
}
func getPaths(fnames []string) (paths []string, haveFolder bool, err error) {
haveFolder = false
paths = []string{}
for _, fname := range fnames {
stat, errStat := os.Stat(fname)
if errStat != nil {
err = errStat
return
}
if stat.IsDir() {
haveFolder = true
err = filepath.Walk(fname,
func(pathName string, info os.FileInfo, err error) error {
if err != nil {
return err
}
if !info.IsDir() {
paths = append(paths, filepath.ToSlash(pathName))
}
return nil
})
if err != nil {
return
}
} else {
paths = append(paths, filepath.ToSlash(fname))
}
}
return
}
func saveConfig(c *cli.Context, crocOptions croc.Options) {
if c.Bool("remember") {
configFile := getConfigFile()
configFile := getSendConfigFile(true)
log.Debug("saving config file")
var bConfig []byte
// if the code wasn't set, don't save it
@ -357,7 +468,7 @@ func saveConfig(c *cli.Context, crocOptions croc.Options) {
log.Error(err)
return
}
err = ioutil.WriteFile(configFile, bConfig, 0644)
err = os.WriteFile(configFile, bConfig, 0o644)
if err != nil {
log.Error(err)
return
@ -366,8 +477,39 @@ func saveConfig(c *cli.Context, crocOptions croc.Options) {
}
}
type TabComplete struct{}
func (t TabComplete) Do(line []rune, pos int) ([][]rune, int) {
var words = strings.SplitAfter(string(line), "-")
var lastPartialWord = words[len(words)-1]
var nbCharacter = len(lastPartialWord)
if nbCharacter == 0 {
// No completion
return [][]rune{[]rune("")}, 0
}
if len(words) == 1 && nbCharacter == utils.NbPinNumbers {
// Check if word is indeed a number
_, err := strconv.Atoi(lastPartialWord)
if err == nil {
return [][]rune{[]rune("-")}, nbCharacter
}
}
var strArray [][]rune
for _, s := range mnemonicode.WordList {
if strings.HasPrefix(s, lastPartialWord) {
var completionCandidate = s[nbCharacter:]
if len(words) <= mnemonicode.WordsRequired(utils.NbBytesWords) {
completionCandidate += "-"
}
strArray = append(strArray, []rune(completionCandidate))
}
}
return strArray, nbCharacter
}
func receive(c *cli.Context) (err error) {
comm.Socks5Proxy = c.String("socks5")
comm.HttpProxy = c.String("connect")
crocOptions := croc.Options{
SharedSecret: c.String("code"),
IsSender: false,
@ -380,6 +522,9 @@ func receive(c *cli.Context) (err error) {
RelayPassword: determinePass(c),
OnlyLocal: c.Bool("local"),
IP: c.String("ip"),
Overwrite: c.Bool("overwrite"),
Curve: c.String("curve"),
TestFlag: c.Bool("testing"),
}
if crocOptions.RelayAddress != models.DEFAULT_RELAY {
crocOptions.RelayAddress6 = ""
@ -391,6 +536,8 @@ func receive(c *cli.Context) (err error) {
case 1:
crocOptions.SharedSecret = c.Args().First()
case 3:
fallthrough
case 4:
var phrase []string
phrase = append(phrase, c.Args().First())
phrase = append(phrase, c.Args().Tail()...)
@ -399,22 +546,22 @@ func receive(c *cli.Context) (err error) {
// load options here
setDebugLevel(c)
configFile, err := getConfigDir()
if err != nil {
log.Error(err)
doRemember := c.Bool("remember")
configFile, err := getReceiveConfigFile(doRemember)
if err != nil && doRemember {
return
}
configFile = path.Join(configFile, "receive.json")
b, errOpen := ioutil.ReadFile(configFile)
if errOpen == nil && !c.Bool("remember") {
b, errOpen := os.ReadFile(configFile)
if errOpen == nil && !doRemember {
var rememberedOptions croc.Options
err = json.Unmarshal(b, &rememberedOptions)
if err != nil {
log.Error(err)
return
}
// update anything that isn't expliciGlobalIsSettly set
if !c.IsSet("relay") {
// update anything that isn't explicitly Globally set
if !c.IsSet("relay") && rememberedOptions.RelayAddress != "" {
crocOptions.RelayAddress = rememberedOptions.RelayAddress
}
if !c.IsSet("yes") {
@ -423,13 +570,61 @@ func receive(c *cli.Context) (err error) {
if crocOptions.SharedSecret == "" {
crocOptions.SharedSecret = rememberedOptions.SharedSecret
}
if !c.IsSet("pass") {
if !c.IsSet("pass") && rememberedOptions.RelayPassword != "" {
crocOptions.RelayPassword = rememberedOptions.RelayPassword
}
if !c.IsSet("relay6") && rememberedOptions.RelayAddress6 != "" {
crocOptions.RelayAddress6 = rememberedOptions.RelayAddress6
}
if !c.IsSet("overwrite") {
crocOptions.Overwrite = rememberedOptions.Overwrite
}
if !c.IsSet("curve") && rememberedOptions.Curve != "" {
crocOptions.Curve = rememberedOptions.Curve
}
if !c.IsSet("local") {
crocOptions.OnlyLocal = rememberedOptions.OnlyLocal
}
}
classicInsecureMode := utils.Exists(getClassicConfigFile(true))
if crocOptions.SharedSecret == "" && os.Getenv("CROC_SECRET") != "" {
crocOptions.SharedSecret = os.Getenv("CROC_SECRET")
} else if !(runtime.GOOS == "windows") && crocOptions.SharedSecret != "" && !classicInsecureMode {
crocOptions.SharedSecret = os.Getenv("CROC_SECRET")
if crocOptions.SharedSecret == "" {
fmt.Printf(`On UNIX systems, to receive with croc you either need
to set a code phrase using your environmental variables:
export CROC_SECRET="****"
croc
Or you can specify the code phrase when you run croc without
declaring the secret on the command line:
croc
Enter receive code: ****
Or you can go back to the classic croc behavior by enabling classic mode:
croc --classic
`)
os.Exit(0)
}
}
if crocOptions.SharedSecret == "" {
crocOptions.SharedSecret = utils.GetInput("Enter receive code: ")
l, err := readline.NewEx(&readline.Config{
Prompt: "Enter receive code: ",
AutoComplete: TabComplete{},
})
if err != nil {
return err
}
crocOptions.SharedSecret, err = l.Readline()
if err != nil {
return err
}
}
if c.String("out") != "" {
if err = os.Chdir(c.String("out")); err != nil {
@ -443,7 +638,7 @@ func receive(c *cli.Context) (err error) {
}
// save the config
if c.Bool("remember") {
if doRemember {
log.Debug("saving config file")
var bConfig []byte
bConfig, err = json.MarshalIndent(crocOptions, "", " ")
@ -451,7 +646,7 @@ func receive(c *cli.Context) (err error) {
log.Error(err)
return
}
err = ioutil.WriteFile(configFile, bConfig, 0644)
err = os.WriteFile(configFile, bConfig, 0o644)
if err != nil {
log.Error(err)
return
@ -469,6 +664,7 @@ func relay(c *cli.Context) (err error) {
if c.Bool("debug") {
debugString = "debug"
}
host := c.String("host")
ports := strings.Split(c.String("ports"), ",")
tcpPorts := strings.Join(ports[1:], ",")
for i, port := range ports {
@ -476,11 +672,11 @@ func relay(c *cli.Context) (err error) {
continue
}
go func(portStr string) {
err = tcp.Run(debugString, portStr, determinePass(c))
err := tcp.Run(debugString, host, portStr, determinePass(c))
if err != nil {
panic(err)
}
}(port)
}
return tcp.Run(debugString, ports[0], determinePass(c), tcpPorts)
return tcp.Run(debugString, host, ports[0], determinePass(c), tcpPorts)
}

View File

@ -10,14 +10,16 @@ import (
"strings"
"time"
"github.com/schollz/croc/v8/src/utils"
"github.com/magisterquis/connectproxy"
"github.com/schollz/croc/v10/src/utils"
log "github.com/schollz/logger"
"golang.org/x/net/proxy"
)
var Socks5Proxy = ""
var HttpProxy = ""
const MAXBYTES = 4000000
var MAGIC_BYTES = []byte("croc")
// Comm is some basic TCP communication
type Comm struct {
@ -39,20 +41,46 @@ func NewConnection(address string, timelimit ...time.Duration) (c *Comm, err err
}
socks5ProxyURL, urlParseError := url.Parse(Socks5Proxy)
if urlParseError != nil {
err = fmt.Errorf("Unable to parse socks proxy url: %s", urlParseError)
err = fmt.Errorf("unable to parse socks proxy url: %s", urlParseError)
log.Debug(err)
return
}
dialer, err = proxy.FromURL(socks5ProxyURL, proxy.Direct)
if err != nil {
err = fmt.Errorf("proxy failed: %w", err)
log.Debug(err)
return
}
log.Debug("dialing with dialer.Dial")
connection, err = dialer.Dial("tcp", address)
} else if HttpProxy != "" && !utils.IsLocalIP(address) {
var dialer proxy.Dialer
// prepend schema if no schema is given
if !strings.Contains(HttpProxy, `://`) {
HttpProxy = `http://` + HttpProxy
}
HttpProxyURL, urlParseError := url.Parse(HttpProxy)
if urlParseError != nil {
err = fmt.Errorf("unable to parse http proxy url: %s", urlParseError)
log.Debug(err)
return
}
dialer, err = connectproxy.New(HttpProxyURL, proxy.Direct)
if err != nil {
err = fmt.Errorf("proxy failed: %w", err)
log.Debug(err)
return
}
log.Debug("dialing with dialer.Dial")
connection, err = dialer.Dial("tcp", address)
} else {
log.Debugf("dialing to %s with timelimit %s", address, tlimit)
connection, err = net.DialTimeout("tcp", address, tlimit)
}
if err != nil {
err = fmt.Errorf("comm.NewConnection failed: %w", err)
log.Debug(err)
return
}
c = New(connection)
@ -95,6 +123,7 @@ func (c *Comm) Write(b []byte) (n int, err error) {
fmt.Println("binary.Write failed:", err)
}
tmpCopy := append(header.Bytes(), b...)
tmpCopy = append(MAGIC_BYTES, tmpCopy...)
n, err = c.connection.Write(tmpCopy)
if err != nil {
err = fmt.Errorf("connection.Write failed: %w", err)
@ -109,19 +138,31 @@ func (c *Comm) Write(b []byte) (n int, err error) {
func (c *Comm) Read() (buf []byte, numBytes int, bs []byte, err error) {
// long read deadline in case waiting for file
if err := c.connection.SetReadDeadline(time.Now().Add(3 * time.Hour)); err != nil {
if err = c.connection.SetReadDeadline(time.Now().Add(3 * time.Hour)); err != nil {
log.Warnf("error setting read deadline: %v", err)
}
// must clear the timeout setting
defer c.connection.SetDeadline(time.Time{})
// read until we get 4 bytes for the header
// read until we get 4 bytes for the magic
header := make([]byte, 4)
_, err = io.ReadFull(c.connection, header)
if err != nil {
log.Debugf("initial read error: %v", err)
return
}
if !bytes.Equal(header, MAGIC_BYTES) {
err = fmt.Errorf("initial bytes are not magic: %x", header)
return
}
// read until we get 4 bytes for the header
header = make([]byte, 4)
_, err = io.ReadFull(c.connection, header)
if err != nil {
log.Debugf("initial read error: %v", err)
return
}
var numBytesUint32 uint32
rbuf := bytes.NewReader(header)
@ -132,14 +173,9 @@ func (c *Comm) Read() (buf []byte, numBytes int, bs []byte, err error) {
return
}
numBytes = int(numBytesUint32)
if numBytes > MAXBYTES {
err = fmt.Errorf("too many bytes: %d", numBytes)
log.Debug(err)
return
}
// shorten the reading deadline in case getting weird data
if err := c.connection.SetReadDeadline(time.Now().Add(10 * time.Second)); err != nil {
if err = c.connection.SetReadDeadline(time.Now().Add(10 * time.Second)); err != nil {
log.Warnf("error setting read deadline: %v", err)
}
buf = make([]byte, numBytes)

View File

@ -11,7 +11,7 @@ import (
)
func TestComm(t *testing.T) {
token := make([]byte, MAXBYTES)
token := make([]byte, 3000)
if _, err := rand.Read(token); err != nil {
t.Error(err)
}
@ -31,7 +31,7 @@ func TestComm(t *testing.T) {
log.Error(err)
}
log.Debugf("client %s connected", connection.RemoteAddr().String())
go func(port string, connection net.Conn) {
go func(_ string, connection net.Conn) {
c := New(connection)
err = c.Send([]byte("hello, world"))
assert.Nil(t, err)
@ -49,7 +49,7 @@ func TestComm(t *testing.T) {
}()
time.Sleep(300 * time.Millisecond)
a, err := NewConnection("localhost:"+port, 10*time.Minute)
a, err := NewConnection("127.0.0.1:"+port, 10*time.Minute)
assert.Nil(t, err)
data, err := a.Receive()
assert.Equal(t, []byte("hello, world"), data)
@ -63,5 +63,4 @@ func TestComm(t *testing.T) {
assert.NotNil(t, a.Send(token))
_, err = a.Write(token)
assert.NotNil(t, err)
}

File diff suppressed because it is too large Load Diff

View File

@ -1,13 +1,16 @@
package croc
import (
"io/ioutil"
"os"
"path"
"path/filepath"
"runtime"
"strings"
"sync"
"testing"
"time"
"github.com/schollz/croc/v8/src/tcp"
"github.com/schollz/croc/v10/src/tcp"
log "github.com/schollz/logger"
"github.com/stretchr/testify/assert"
)
@ -15,11 +18,11 @@ import (
func init() {
log.SetLevel("trace")
go tcp.Run("debug", "8081", "pass123", "8082,8083,8084,8085")
go tcp.Run("debug", "8082", "pass123")
go tcp.Run("debug", "8083", "pass123")
go tcp.Run("debug", "8084", "pass123")
go tcp.Run("debug", "8085", "pass123")
go tcp.Run("debug", "127.0.0.1", "8281", "pass123", "8282,8283,8284,8285")
go tcp.Run("debug", "127.0.0.1", "8282", "pass123")
go tcp.Run("debug", "127.0.0.1", "8283", "pass123")
go tcp.Run("debug", "127.0.0.1", "8284", "pass123")
go tcp.Run("debug", "127.0.0.1", "8285", "pass123")
time.Sleep(1 * time.Second)
}
@ -29,14 +32,17 @@ func TestCrocReadme(t *testing.T) {
log.Debug("setting up sender")
sender, err := New(Options{
IsSender: true,
SharedSecret: "test",
SharedSecret: "8123-testingthecroc",
Debug: true,
RelayAddress: "localhost:8081",
RelayPorts: []string{"8081"},
RelayAddress: "127.0.0.1:8281",
RelayPorts: []string{"8281"},
RelayPassword: "pass123",
Stdout: false,
NoPrompt: true,
DisableLocal: true,
Curve: "siec",
Overwrite: true,
GitIgnore: false,
})
if err != nil {
panic(err)
@ -45,13 +51,15 @@ func TestCrocReadme(t *testing.T) {
log.Debug("setting up receiver")
receiver, err := New(Options{
IsSender: false,
SharedSecret: "test",
SharedSecret: "8123-testingthecroc",
Debug: true,
RelayAddress: "localhost:8081",
RelayAddress: "127.0.0.1:8281",
RelayPassword: "pass123",
Stdout: false,
NoPrompt: true,
DisableLocal: true,
Curve: "siec",
Overwrite: true,
})
if err != nil {
panic(err)
@ -60,9 +68,11 @@ func TestCrocReadme(t *testing.T) {
var wg sync.WaitGroup
wg.Add(2)
go func() {
err := sender.Send(TransferOptions{
PathToFiles: []string{"../../README.md"},
})
filesInfo, emptyFolders, totalNumberFolders, errGet := GetFilesInfo([]string{"../../README.md"}, false, false)
if errGet != nil {
t.Errorf("failed to get minimal info: %v", errGet)
}
err := sender.Send(filesInfo, emptyFolders, totalNumberFolders)
if err != nil {
t.Errorf("send failed: %v", err)
}
@ -80,6 +90,175 @@ func TestCrocReadme(t *testing.T) {
wg.Wait()
}
func TestCrocEmptyFolder(t *testing.T) {
pathName := "../../testEmpty"
defer os.RemoveAll(pathName)
defer os.RemoveAll("./testEmpty")
os.MkdirAll(pathName, 0o755)
log.Debug("setting up sender")
sender, err := New(Options{
IsSender: true,
SharedSecret: "8123-testingthecroc",
Debug: true,
RelayAddress: "127.0.0.1:8281",
RelayPorts: []string{"8281"},
RelayPassword: "pass123",
Stdout: false,
NoPrompt: true,
DisableLocal: true,
Curve: "siec",
Overwrite: true,
})
if err != nil {
panic(err)
}
log.Debug("setting up receiver")
receiver, err := New(Options{
IsSender: false,
SharedSecret: "8123-testingthecroc",
Debug: true,
RelayAddress: "127.0.0.1:8281",
RelayPassword: "pass123",
Stdout: false,
NoPrompt: true,
DisableLocal: true,
Curve: "siec",
Overwrite: true,
})
if err != nil {
panic(err)
}
var wg sync.WaitGroup
wg.Add(2)
go func() {
filesInfo, emptyFolders, totalNumberFolders, errGet := GetFilesInfo([]string{pathName}, false, false)
if errGet != nil {
t.Errorf("failed to get minimal info: %v", errGet)
}
err := sender.Send(filesInfo, emptyFolders, totalNumberFolders)
if err != nil {
t.Errorf("send failed: %v", err)
}
wg.Done()
}()
time.Sleep(100 * time.Millisecond)
go func() {
err := receiver.Receive()
if err != nil {
t.Errorf("receive failed: %v", err)
}
wg.Done()
}()
wg.Wait()
}
func TestCrocSymlink(t *testing.T) {
pathName := "../link-in-folder"
defer os.RemoveAll(pathName)
defer os.RemoveAll("./link-in-folder")
os.MkdirAll(pathName, 0o755)
os.Symlink("../../README.md", filepath.Join(pathName, "README.link"))
log.Debug("setting up sender")
sender, err := New(Options{
IsSender: true,
SharedSecret: "8124-testingthecroc",
Debug: true,
RelayAddress: "127.0.0.1:8281",
RelayPorts: []string{"8281"},
RelayPassword: "pass123",
Stdout: false,
NoPrompt: true,
DisableLocal: true,
Curve: "siec",
Overwrite: true,
GitIgnore: false,
})
if err != nil {
panic(err)
}
log.Debug("setting up receiver")
receiver, err := New(Options{
IsSender: false,
SharedSecret: "8124-testingthecroc",
Debug: true,
RelayAddress: "127.0.0.1:8281",
RelayPassword: "pass123",
Stdout: false,
NoPrompt: true,
DisableLocal: true,
Curve: "siec",
Overwrite: true,
})
if err != nil {
panic(err)
}
var wg sync.WaitGroup
wg.Add(2)
go func() {
filesInfo, emptyFolders, totalNumberFolders, errGet := GetFilesInfo([]string{pathName}, false, false)
if errGet != nil {
t.Errorf("failed to get minimal info: %v", errGet)
}
err = sender.Send(filesInfo, emptyFolders, totalNumberFolders)
if err != nil {
t.Errorf("send failed: %v", err)
}
wg.Done()
}()
time.Sleep(100 * time.Millisecond)
go func() {
err = receiver.Receive()
if err != nil {
t.Errorf("receive failed: %v", err)
}
wg.Done()
}()
wg.Wait()
s, err := filepath.EvalSymlinks(path.Join(pathName, "README.link"))
if s != "../../README.md" && s != "..\\..\\README.md" {
log.Debug(s)
t.Errorf("symlink failed to transfer in folder")
}
if err != nil {
t.Errorf("symlink transfer failed: %s", err.Error())
}
}
func testCrocIgnoreGit(t *testing.T) {
log.SetLevel("trace")
defer os.Remove(".gitignore")
time.Sleep(300 * time.Millisecond)
time.Sleep(1 * time.Second)
file, err := os.Create(".gitignore")
if err != nil {
log.Errorf("error creating file")
}
_, err = file.WriteString("LICENSE")
if err != nil {
log.Errorf("error writing to file")
}
time.Sleep(1 * time.Second)
// due to how files are ignored in this function, all we have to do to test is make sure LICENSE doesn't get included in FilesInfo.
filesInfo, _, _, errGet := GetFilesInfo([]string{"../../LICENSE", ".gitignore", "croc.go"}, false, true)
if errGet != nil {
t.Errorf("failed to get minimal info: %v", errGet)
}
for _, file := range filesInfo {
if strings.Contains(file.Name, "LICENSE") {
t.Errorf("test failed, should ignore LICENSE")
}
}
}
func TestCrocLocal(t *testing.T) {
log.SetLevel("trace")
defer os.Remove("LICENSE")
@ -89,14 +268,17 @@ func TestCrocLocal(t *testing.T) {
log.Debug("setting up sender")
sender, err := New(Options{
IsSender: true,
SharedSecret: "test",
SharedSecret: "8123-testingthecroc",
Debug: true,
RelayAddress: "localhost:8181",
RelayAddress: "127.0.0.1:8181",
RelayPorts: []string{"8181", "8182"},
RelayPassword: "pass123",
Stdout: true,
NoPrompt: true,
DisableLocal: false,
Curve: "siec",
Overwrite: true,
GitIgnore: false,
})
if err != nil {
panic(err)
@ -106,13 +288,15 @@ func TestCrocLocal(t *testing.T) {
log.Debug("setting up receiver")
receiver, err := New(Options{
IsSender: false,
SharedSecret: "test",
SharedSecret: "8123-testingthecroc",
Debug: true,
RelayAddress: "localhost:8181",
RelayAddress: "127.0.0.1:8181",
RelayPassword: "pass123",
Stdout: true,
NoPrompt: true,
DisableLocal: false,
Curve: "siec",
Overwrite: true,
})
if err != nil {
panic(err)
@ -122,10 +306,11 @@ func TestCrocLocal(t *testing.T) {
os.Create("touched")
wg.Add(2)
go func() {
err := sender.Send(TransferOptions{
PathToFiles: []string{"../../LICENSE", "touched"},
KeepPathInRemote: false,
})
filesInfo, emptyFolders, totalNumberFolders, errGet := GetFilesInfo([]string{"../../LICENSE", "touched"}, false, false)
if errGet != nil {
t.Errorf("failed to get minimal info: %v", errGet)
}
err := sender.Send(filesInfo, emptyFolders, totalNumberFolders)
if err != nil {
t.Errorf("send failed: %v", err)
}
@ -145,17 +330,17 @@ func TestCrocLocal(t *testing.T) {
func TestCrocError(t *testing.T) {
content := []byte("temporary file's content")
tmpfile, err := ioutil.TempFile("", "example")
tmpfile, err := os.CreateTemp("", "example")
if err != nil {
panic(err)
}
defer os.Remove(tmpfile.Name()) // clean up
if _, err := tmpfile.Write(content); err != nil {
if _, err = tmpfile.Write(content); err != nil {
panic(err)
}
if err := tmpfile.Close(); err != nil {
if err = tmpfile.Close(); err != nil {
panic(err)
}
@ -163,7 +348,7 @@ func TestCrocError(t *testing.T) {
log.SetLevel("warn")
sender, _ := New(Options{
IsSender: true,
SharedSecret: "test33",
SharedSecret: "8123-testingthecroc2",
Debug: true,
RelayAddress: "doesntexistok.com:8381",
RelayPorts: []string{"8381", "8382"},
@ -171,12 +356,45 @@ func TestCrocError(t *testing.T) {
Stdout: true,
NoPrompt: true,
DisableLocal: true,
Curve: "siec",
Overwrite: true,
})
err = sender.Send(TransferOptions{
PathToFiles: []string{tmpfile.Name()},
KeepPathInRemote: true,
})
filesInfo, emptyFolders, totalNumberFolders, errGet := GetFilesInfo([]string{tmpfile.Name()}, false, false)
if errGet != nil {
t.Errorf("failed to get minimal info: %v", errGet)
}
err = sender.Send(filesInfo, emptyFolders, totalNumberFolders)
log.Debug(err)
assert.NotNil(t, err)
}
func TestCleanUp(t *testing.T) {
// windows allows files to be deleted only if they
// are not open by another program so the remove actions
// from the above tests will not always do a good clean up
// This "test" will make sure
operatingSystem := runtime.GOOS
log.Debugf("The operating system is %s", operatingSystem)
if operatingSystem == "windows" {
time.Sleep(1 * time.Second)
log.Debug("Full cleanup")
var err error
for _, file := range []string{"README.md", "./README.md"} {
err = os.Remove(file)
if err == nil {
log.Debugf("Successfully purged %s", file)
} else {
log.Debugf("%s was already purged.", file)
}
}
for _, folder := range []string{"./testEmpty", "./link-in-folder"} {
err = os.RemoveAll(folder)
if err == nil {
log.Debugf("Successfully purged %s", folder)
} else {
log.Debugf("%s was already purged.", folder)
}
}
}
}

View File

@ -8,6 +8,8 @@ import (
"fmt"
"log"
"golang.org/x/crypto/argon2"
"golang.org/x/crypto/chacha20poly1305"
"golang.org/x/crypto/pbkdf2"
)
@ -37,7 +39,7 @@ func Encrypt(plaintext []byte, key []byte) (encrypted []byte, err error) {
// http://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-38d.pdf
// Section 8.2
ivBytes := make([]byte, 12)
if _, err := rand.Read(ivBytes); err != nil {
if _, err = rand.Read(ivBytes); err != nil {
log.Fatalf("can't initialize crypto: %v", err)
}
b, err := aes.NewCipher(key)
@ -70,3 +72,54 @@ func Decrypt(encrypted []byte, key []byte) (plaintext []byte, err error) {
plaintext, err = aesgcm.Open(nil, encrypted[:12], encrypted[12:], nil)
return
}
// NewArgon2 generates a new key based on a passphrase and salt
// using argon2
// https://pkg.go.dev/golang.org/x/crypto/argon2
func NewArgon2(passphrase []byte, usersalt []byte) (aead cipher.AEAD, salt []byte, err error) {
if len(passphrase) < 1 {
err = fmt.Errorf("need more than that for passphrase")
return
}
if usersalt == nil {
salt = make([]byte, 8)
// http://www.ietf.org/rfc/rfc2898.txt
// Salt.
if _, err = rand.Read(salt); err != nil {
log.Fatalf("can't get random salt: %v", err)
}
} else {
salt = usersalt
}
aead, err = chacha20poly1305.NewX(argon2.IDKey(passphrase, salt, 1, 64*1024, 4, 32))
return
}
// EncryptChaCha will encrypt ChaCha20-Poly1305 using the pre-generated key
// https://pkg.go.dev/golang.org/x/crypto/chacha20poly1305
func EncryptChaCha(plaintext []byte, aead cipher.AEAD) (encrypted []byte, err error) {
nonce := make([]byte, aead.NonceSize(), aead.NonceSize()+len(plaintext)+aead.Overhead())
if _, err := rand.Read(nonce); err != nil {
panic(err)
}
// Encrypt the message and append the ciphertext to the nonce.
encrypted = aead.Seal(nonce, nonce, plaintext, nil)
return
}
// DecryptChaCha will encrypt ChaCha20-Poly1305 using the pre-generated key
// https://pkg.go.dev/golang.org/x/crypto/chacha20poly1305
func DecryptChaCha(encryptedMsg []byte, aead cipher.AEAD) (encrypted []byte, err error) {
if len(encryptedMsg) < aead.NonceSize() {
err = fmt.Errorf("ciphertext too short")
return
}
// Split nonce and ciphertext.
nonce, ciphertext := encryptedMsg[:aead.NonceSize()], encryptedMsg[aead.NonceSize():]
// Decrypt the message and check it wasn't tampered with.
encrypted, err = aead.Open(nil, nonce, ciphertext, nil)
return
}

View File

@ -1,6 +1,7 @@
package crypt
import (
"fmt"
"testing"
"github.com/stretchr/testify/assert"
@ -23,6 +24,23 @@ func BenchmarkDecrypt(b *testing.B) {
}
}
func BenchmarkEncryptChaCha(b *testing.B) {
bob, _, _ := NewArgon2([]byte("password"), nil)
for i := 0; i < b.N; i++ {
EncryptChaCha([]byte("hello, world"), bob)
}
}
func BenchmarkDecryptChaCha(b *testing.B) {
key, _, _ := NewArgon2([]byte("password"), nil)
msg := []byte("hello, world")
enc, _ := EncryptChaCha(msg, key)
b.ResetTimer()
for i := 0; i < b.N; i++ {
DecryptChaCha(enc, key)
}
}
func TestEncryption(t *testing.T) {
key, salt, err := New([]byte("password"), nil)
assert.Nil(t, err)
@ -34,22 +52,54 @@ func TestEncryption(t *testing.T) {
assert.Equal(t, msg, dec)
// check reusing the salt
key2, _, err := New([]byte("password"), salt)
key2, _, _ := New([]byte("password"), salt)
dec, err = Decrypt(enc, key2)
assert.Nil(t, err)
assert.Equal(t, msg, dec)
// check reusing the salt
key2, _, err = New([]byte("wrong password"), salt)
key2, _, _ = New([]byte("wrong password"), salt)
dec, err = Decrypt(enc, key2)
assert.NotNil(t, err)
assert.NotEqual(t, msg, dec)
// error with no password
dec, err = Decrypt([]byte(""), key)
_, err = Decrypt([]byte(""), key)
assert.NotNil(t, err)
// error with small password
_, _, err = New([]byte(""), nil)
assert.NotNil(t, err)
}
func TestEncryptionChaCha(t *testing.T) {
key, salt, err := NewArgon2([]byte("password"), nil)
fmt.Printf("key: %x\n", key)
assert.Nil(t, err)
msg := []byte("hello, world")
enc, err := EncryptChaCha(msg, key)
assert.Nil(t, err)
dec, err := DecryptChaCha(enc, key)
assert.Nil(t, err)
assert.Equal(t, msg, dec)
// check reusing the salt
key2, _, _ := NewArgon2([]byte("password"), salt)
dec, err = DecryptChaCha(enc, key2)
assert.Nil(t, err)
assert.Equal(t, msg, dec)
// check reusing the salt
key2, _, _ = NewArgon2([]byte("wrong password"), salt)
dec, err = DecryptChaCha(enc, key2)
assert.NotNil(t, err)
assert.NotEqual(t, msg, dec)
// error with no password
_, err = DecryptChaCha([]byte(""), key)
assert.NotNil(t, err)
// error with small password
_, _, err = NewArgon2([]byte(""), nil)
assert.NotNil(t, err)
}

View File

@ -13,5 +13,7 @@ release:
cd ../../ && ./src/install/upload-src-tarball.sh
test:
cp zsh_autocomplete ../../
cp bash_autocomplete ../../
cd ../../ && go generate
cd ../../ && goreleaser release --skip-publish

View File

@ -1,5 +1,3 @@
#! /bin/bash
: ${PROG:=$(basename ${BASH_SOURCE})}
_cli_bash_autocomplete() {

View File

@ -86,7 +86,7 @@ print_help() {
Default = /usr/local/bin ('\${PREFIX}/bin' on Termux for Android)
-h
Prints this helpfull message and exit."
Prints this helpful message and exit."
echo "${help_header}"
echo ""
@ -156,10 +156,10 @@ make_tempdir() {
#--- FUNCTION ----------------------------------------------------------------
# NAME: determine_os
# DESCRIPTION: Attempts to determin host os using uname
# DESCRIPTION: Attempts to determine host os using uname
# PARAMETERS: none
# RETURNS: 0 = OS Detected. Also prints detected os to stdout
# 1 = Unkown OS
# 1 = Unknown OS
# 20 = 'uname' not found in path
#-------------------------------------------------------------------------------
determine_os() {
@ -180,10 +180,10 @@ determine_os() {
#--- FUNCTION ----------------------------------------------------------------
# NAME: determine_arch
# DESCRIPTION: Attempt to determin architecture of host
# DESCRIPTION: Attempt to determine architecture of host
# PARAMETERS: none
# RETURNS: 0 = Arch Detected. Also prints detected arch to stdout
# 1 = Unkown arch
# 1 = Unknown arch
# 20 = 'uname' not found in path
#-------------------------------------------------------------------------------
determine_arch() {
@ -238,7 +238,7 @@ download_file() {
#--- FUNCTION ----------------------------------------------------------------
# NAME: checksum_check
# DESCRIPTION: Attempt to verify checksum of downloaded file to ensure
# integrity. Tries multiple tools before faling.
# integrity. Tries multiple tools before failing.
# PARAMETERS: $1 = path to checksum file
# $2 = location of file to check
# $3 = working directory
@ -300,10 +300,10 @@ checksum_check() {
#--- FUNCTION ----------------------------------------------------------------
# NAME: extract_file
# DESCRIPTION: Extracts a file into a location. Attempts to determine which
# tool to use by checking file extention.
# tool to use by checking file extension.
# PARAMETERS: $1 = file to extract
# $2 = location to extract file into
# $3 = extention
# $3 = extension
# RETURNS: Return code of the tool used to extract the file
# 20 = Failed to determine which tool to use
# 30 = Failed to find tool in path
@ -528,7 +528,7 @@ main() {
local autocomplete_install_rcode
croc_bin_name="croc"
croc_version="8.6.10"
croc_version="10.0.7"
croc_dl_ext="tar.gz"
croc_base_url="https://github.com/schollz/croc/releases/download"
prefix="${1}"
@ -587,16 +587,17 @@ main() {
"x86_64" ) croc_arch="64bit";;
"amd64" ) croc_arch="64bit";;
"aarch64" ) croc_arch="ARM64";;
"arm64" ) croc_arch="ARM64";;
"armv7l" ) croc_arch="ARM";;
"i686" ) croc_arch="32bit";;
* ) croc_arch="unknown";;
esac
croc_file="${croc_bin_name}_${croc_version}_${croc_os}-${croc_arch}.${croc_dl_ext}"
croc_checksum_file="${croc_bin_name}_${croc_version}_checksums.txt"
croc_file="${croc_bin_name}_v${croc_version}_${croc_os}-${croc_arch}.${croc_dl_ext}"
croc_checksum_file="${croc_bin_name}_v${croc_version}_checksums.txt"
croc_url="${croc_base_url}/v${croc_version}/${croc_file}"
croc_checksum_url="${croc_base_url}/v${croc_version}/${croc_checksum_file}"
echo "${croc_url}" "${tmpdir}" "${croc_file}"
download_file "${croc_url}" "${tmpdir}" "${croc_file}"
download_file_rcode="${?}"
if [[ "${download_file_rcode}" == "0" ]]; then
@ -684,7 +685,7 @@ main() {
print_message "== Install prefix already exists. No need to create it." "info"
fi
[ ! -d "/etc/bash_completion.d/croc" ] && mkdir -p "/etc/bash_completion.d/croc"
case "${croc_os}" in
"Linux" ) install_file_linux "${tmpdir}/${croc_bin_name}" "${prefix}/";
install_file_rcode="${?}";;
@ -712,26 +713,27 @@ main() {
exit 1
fi
case "$(basename ${SHELL})" in
"bash" ) install_file_linux "${tmpdir}/${bash_autocomplete_file}" "${bash_autocomplete_prefix}/croc";
autocomplete_install_rcode="${?}";;
"zsh" ) install_file_linux "${tmpdir}/${zsh_autocomplete_file}" "${zsh_autocomplete_prefix}/zsh_autocomplete_croc";
autocomplete_install_rcode="${?}";
print_message "== You will need to add the following to your ~/.zshrc to enable autocompletion" "info";
print_message "\nPROG=croc\n_CLI_ZSH_AUTOCOMPLETE_HACK=1\nsource /etc/zsh/zsh_autocomplete_croc\n" "info";;
esac
# case "$(basename ${SHELL})" in
# "bash" ) install_file_linux "${tmpdir}/${bash_autocomplete_file}" "${bash_autocomplete_prefix}/croc";
# autocomplete_install_rcode="${?}";;
# "zsh" ) install_file_linux "${tmpdir}/${zsh_autocomplete_file}" "${zsh_autocomplete_prefix}/zsh_autocomplete_croc";
# autocomplete_install_rcode="${?}";
# print_message "== You will need to add the following to your ~/.zshrc to enable autocompletion" "info";
# print_message "\nPROG=croc\n_CLI_ZSH_AUTOCOMPLETE_HACK=1\nsource /etc/zsh/zsh_autocomplete_croc\n" "info";;
# *) autocomplete_install_rcode="1";;
# esac
if [[ "${autocomplete_install_rcode}" == "0" ]] ; then
print_message "== Installed autocompletions for $(basename "${SHELL}")" "ok"
elif [[ "${autocomplete_install_rcode}" == "1" ]]; then
print_message "== Failed to install ${bash_autocomplete_file}" "error"
elif [[ "${autocomplete_install_rcode}" == "20" ]]; then
print_message "== Failed to locate 'install' command" "error"
elif [[ "${autocomplete_install_rcode}" == "21" ]]; then
print_message "== Failed to locate 'sudo' command" "error"
else
print_message "== Install attempt returned an unexpected value of ${autocomplete_install_rcode}" "error"
fi
# if [[ "${autocomplete_install_rcode}" == "0" ]] ; then
# print_message "== Installed autocompletions for $(basename "${SHELL}")" "ok"
# elif [[ "${autocomplete_install_rcode}" == "1" ]]; then
# print_message "== Failed to install ${bash_autocomplete_file}" "error"
# elif [[ "${autocomplete_install_rcode}" == "20" ]]; then
# print_message "== Failed to locate 'install' command" "error"
# elif [[ "${autocomplete_install_rcode}" == "21" ]]; then
# print_message "== Failed to locate 'sudo' command" "error"
# else
# print_message "== Install attempt returned an unexpected value of ${autocomplete_install_rcode}" "error"
# fi
print_message "== Installation complete" "ok"

View File

@ -2,7 +2,6 @@ package main
import (
"fmt"
"io/ioutil"
"os"
"os/exec"
"strings"
@ -43,7 +42,7 @@ func run() (err error) {
}
func replaceInFile(fname, start, end, replacement string) (err error) {
b, err := ioutil.ReadFile(fname)
b, err := os.ReadFile(fname)
if err != nil {
return
}
@ -58,7 +57,7 @@ func replaceInFile(fname, start, end, replacement string) (err error) {
fmt.Sprintf("%s%s%s", start, replacement, end),
1,
)
err = ioutil.WriteFile(fname, []byte(newF), 0644)
err = os.WriteFile(fname, []byte(newF), 0o644)
return
}

View File

@ -3,17 +3,32 @@ package message
import (
"encoding/json"
"github.com/schollz/croc/v8/src/comm"
"github.com/schollz/croc/v8/src/compress"
"github.com/schollz/croc/v8/src/crypt"
"github.com/schollz/croc/v10/src/comm"
"github.com/schollz/croc/v10/src/compress"
"github.com/schollz/croc/v10/src/crypt"
log "github.com/schollz/logger"
)
// Type is a message type
type Type string
const (
TypePAKE Type = "pake"
TypeExternalIP Type = "externalip"
TypeFinished Type = "finished"
TypeError Type = "error"
TypeCloseRecipient Type = "close-recipient"
TypeCloseSender Type = "close-sender"
TypeRecipientReady Type = "recipientready"
TypeFileInfo Type = "fileinfo"
)
// Message is the possible payload for messaging
type Message struct {
Type string `json:"t,omitempty"`
Type Type `json:"t,omitempty"`
Message string `json:"m,omitempty"`
Bytes []byte `json:"b,omitempty"`
Bytes2 []byte `json:"b2,omitempty"`
Num int `json:"n,omitempty"`
}
@ -43,7 +58,7 @@ func Encode(key []byte, m Message) (b []byte, err error) {
log.Debugf("writing %s message (encrypted)", m.Type)
b, err = crypt.Encrypt(b, key)
} else {
log.Debugf("writing %s message", m.Type)
log.Debugf("writing %s message (unencrypted)", m.Type)
}
return
}
@ -58,5 +73,12 @@ func Decode(key []byte, b []byte) (m Message, err error) {
}
b = compress.Decompress(b)
err = json.Unmarshal(b, &m)
if err == nil {
if key != nil {
log.Debugf("read %s message (encrypted)", m.Type)
} else {
log.Debugf("read %s message (unencrypted)", m.Type)
}
}
return
}

View File

@ -7,18 +7,20 @@ import (
"testing"
"time"
"github.com/schollz/croc/v8/src/comm"
"github.com/schollz/croc/v8/src/crypt"
"github.com/schollz/croc/v10/src/comm"
"github.com/schollz/croc/v10/src/crypt"
log "github.com/schollz/logger"
"github.com/stretchr/testify/assert"
)
var TypeMessage Type = "message"
func TestMessage(t *testing.T) {
log.SetLevel("debug")
m := Message{Type: "message", Message: "hello, world"}
m := Message{Type: TypeMessage, Message: "hello, world"}
e, salt, err := crypt.New([]byte("pass"), nil)
assert.Nil(t, err)
fmt.Println(salt)
fmt.Println(string(salt))
b, err := Encode(e, m)
assert.Nil(t, err)
fmt.Printf("%x\n", b)
@ -35,7 +37,7 @@ func TestMessage(t *testing.T) {
func TestMessageNoPass(t *testing.T) {
log.SetLevel("debug")
m := Message{Type: "message", Message: "hello, world"}
m := Message{Type: TypeMessage, Message: "hello, world"}
b, err := Encode(nil, m)
assert.Nil(t, err)
fmt.Printf("%x\n", b)
@ -65,7 +67,7 @@ func TestSend(t *testing.T) {
log.Error(err)
}
log.Debugf("client %s connected", connection.RemoteAddr().String())
go func(port string, connection net.Conn) {
go func(_ string, connection net.Conn) {
c := comm.New(connection)
err = c.Send([]byte("hello, world"))
assert.Nil(t, err)
@ -82,10 +84,10 @@ func TestSend(t *testing.T) {
}
}()
time.Sleep(300 * time.Millisecond)
a, err := comm.NewConnection("localhost:"+port, 10*time.Minute)
time.Sleep(800 * time.Millisecond)
a, err := comm.NewConnection("127.0.0.1:"+port, 10*time.Minute)
assert.Nil(t, err)
m := Message{Type: "message", Message: "hello, world"}
m := Message{Type: TypeMessage, Message: "hello, world"}
e, salt, err := crypt.New([]byte("pass"), nil)
log.Debug(salt)
assert.Nil(t, err)

View File

@ -2,8 +2,12 @@ package models
import (
"context"
"fmt"
"net"
"time"
"os"
"path"
"github.com/schollz/croc/v10/src/utils"
)
// TCP_BUFFER_SIZE is the maximum packet size
@ -15,50 +19,125 @@ var (
DEFAULT_RELAY6 = "croc6.schollz.com"
DEFAULT_PORT = "9009"
DEFAULT_PASSPHRASE = "pass123"
INTERNAL_DNS = false
)
// publicDNS are servers to be queried if a local lookup fails
var publicDNS = []string{
"1.0.0.1", // Cloudflare
"1.1.1.1", // Cloudflare
"[2606:4700:4700::1111]", // Cloudflare
"[2606:4700:4700::1001]", // Cloudflare
"8.8.4.4", // Google
"8.8.8.8", // Google
"[2001:4860:4860::8844]", // Google
"[2001:4860:4860::8888]", // Google
"9.9.9.9", // Quad9
"149.112.112.112", // Quad9
"[2620:fe::fe]", // Quad9
"[2620:fe::fe:9]", // Quad9
"8.26.56.26", // Comodo
"8.20.247.20", // Comodo
"208.67.220.220", // Cisco OpenDNS
"208.67.222.222", // Cisco OpenDNS
"[2620:119:35::35]", // Cisco OpenDNS
"[2620:119:53::53]", // Cisco OpenDNS
}
func getConfigFile(requireValidPath bool) (fname string, err error) {
configFile, err := utils.GetConfigDir(requireValidPath)
if err != nil {
return
}
fname = path.Join(configFile, "internal-dns")
return
}
func init() {
doRemember := false
for _, flag := range os.Args {
if flag == "--internal-dns" {
INTERNAL_DNS = true
break
}
if flag == "--remember" {
doRemember = true
}
}
if doRemember {
// save in config file
fname, err := getConfigFile(true)
if err == nil {
f, _ := os.Create(fname)
f.Close()
}
}
if !INTERNAL_DNS {
fname, err := getConfigFile(false)
if err == nil {
INTERNAL_DNS = utils.Exists(fname)
}
}
var err error
DEFAULT_RELAY, err = lookupIPs(DEFAULT_RELAY)
var addr string
addr, err = lookup(DEFAULT_RELAY)
if err == nil {
DEFAULT_RELAY += ":" + DEFAULT_PORT
DEFAULT_RELAY = net.JoinHostPort(addr, DEFAULT_PORT)
} else {
DEFAULT_RELAY = ""
}
DEFAULT_RELAY6, err = lookupIPs(DEFAULT_RELAY6)
addr, err = lookup(DEFAULT_RELAY6)
if err == nil {
DEFAULT_RELAY6 = "[" + DEFAULT_RELAY6 + "]:" + DEFAULT_PORT
DEFAULT_RELAY6 = net.JoinHostPort(addr, DEFAULT_PORT)
} else {
DEFAULT_RELAY6 = ""
}
}
func lookupIPs(address string) (ipaddress string, err error) {
var publicDns = []string{"1.1.1.1", "8.8.8.8", "8.8.4.4", "1.0.0.1", "8.26.56.26", "208.67.222.222", "208.67.220.220"}
result := make(chan string, len(publicDns))
for _, dns := range publicDns {
// Resolve a hostname to an IP address using DNS.
func lookup(address string) (ipaddress string, err error) {
if !INTERNAL_DNS {
return localLookupIP(address)
}
type Result struct {
s string
err error
}
result := make(chan Result, len(publicDNS))
for _, dns := range publicDNS {
go func(dns string) {
s, _ := lookupIP(address, dns)
result <- s
var r Result
r.s, r.err = remoteLookupIP(address, dns)
result <- r
}(dns)
}
for i := 0; i < len(publicDns); i++ {
ipaddress = <-result
for i := 0; i < len(publicDNS); i++ {
ipaddress = (<-result).s
if ipaddress != "" {
return
}
}
err = fmt.Errorf("failed to resolve %s: all DNS servers exhausted", address)
return
}
func lookupIP(address, dns string) (ipaddress string, err error) {
// localLookupIP returns a host's IP address based on the local resolver.
func localLookupIP(address string) (ipaddress string, err error) {
ip, err := net.LookupHost(address)
if err != nil {
return
}
ipaddress = ip[0]
return
}
// remoteLookupIP returns a host's IP address based on a remote DNS server.
func remoteLookupIP(address, dns string) (ipaddress string, err error) {
r := &net.Resolver{
PreferGo: true,
Dial: func(ctx context.Context, network, address string) (net.Conn, error) {
d := net.Dialer{
Timeout: time.Millisecond * time.Duration(1000),
}
return d.DialContext(ctx, "udp", dns+":53")
Dial: func(ctx context.Context, network, _ string) (net.Conn, error) {
d := new(net.Dialer)
return d.DialContext(ctx, network, dns+":53")
},
}
ip, err := r.LookupHost(context.Background(), address)

View File

@ -9,14 +9,15 @@ import (
"time"
log "github.com/schollz/logger"
"github.com/schollz/pake/v2"
"github.com/schollz/pake/v3"
"github.com/schollz/croc/v8/src/comm"
"github.com/schollz/croc/v8/src/crypt"
"github.com/schollz/croc/v8/src/models"
"github.com/schollz/croc/v10/src/comm"
"github.com/schollz/croc/v10/src/crypt"
"github.com/schollz/croc/v10/src/models"
)
type server struct {
host string
port string
debugLevel string
banner string
@ -36,12 +37,14 @@ type roomMap struct {
sync.Mutex
}
const pingRoom = "pinglkasjdlfjsaldjf"
var timeToRoomDeletion = 10 * time.Minute
var pingRoom = "pinglkasjdlfjsaldjf"
// Run starts a tcp listener, run async
func Run(debugLevel, port, password string, banner ...string) (err error) {
func Run(debugLevel, host, port, password string, banner ...string) (err error) {
s := new(server)
s.host = host
s.port = port
s.password = password
s.debugLevel = debugLevel
@ -85,10 +88,32 @@ func (s *server) start() (err error) {
}
func (s *server) run() (err error) {
log.Infof("starting TCP server on " + s.port)
server, err := net.Listen("tcp", ":"+s.port)
network := "tcp"
addr := net.JoinHostPort(s.host, s.port)
if s.host != "" {
ip := net.ParseIP(s.host)
if ip == nil {
var tcpIP *net.IPAddr
tcpIP, err = net.ResolveIPAddr("ip", s.host)
if err != nil {
return err
}
ip = tcpIP.IP
}
addr = net.JoinHostPort(ip.String(), s.port)
if s.host != "" {
if ip.To4() != nil {
network = "tcp4"
} else {
network = "tcp6"
}
}
}
addr = strings.Replace(addr, "127.0.0.1", "0.0.0.0", 1)
log.Infof("starting TCP server on " + addr)
server, err := net.Listen(network, addr)
if err != nil {
return fmt.Errorf("error listening on %s: %w", s.port, err)
return fmt.Errorf("error listening on %s: %w", addr, err)
}
defer server.Close()
// spawn a new goroutine whenever a client connects
@ -152,7 +177,7 @@ var weakKey = []byte{1, 2, 3}
func (s *server) clientCommunication(port string, c *comm.Comm) (room string, err error) {
// establish secure password with PAKE for communication with relay
B, err := pake.InitCurve(weakKey, 1, "siec", 1*time.Microsecond)
B, err := pake.InitCurve(weakKey, 1, "siec")
if err != nil {
return
}
@ -160,8 +185,10 @@ func (s *server) clientCommunication(port string, c *comm.Comm) (room string, er
if err != nil {
return
}
log.Debugf("Abytes: %s", Abytes)
if bytes.Equal(Abytes, []byte("ping")) {
room = pingRoom
log.Debug("sending back pong")
c.Send([]byte("pong"))
return
}
@ -170,11 +197,6 @@ func (s *server) clientCommunication(port string, c *comm.Comm) (room string, er
return
}
err = c.Send(B.Bytes())
Abytes, err = c.Receive()
if err != nil {
return
}
err = B.Update(Abytes)
if err != nil {
return
}
@ -186,6 +208,9 @@ func (s *server) clientCommunication(port string, c *comm.Comm) (room string, er
// receive salt
salt, err := c.Receive()
if err != nil {
return
}
strongKeyForEncryption, _, err := crypt.New(strongKey, salt)
if err != nil {
return
@ -202,8 +227,8 @@ func (s *server) clientCommunication(port string, c *comm.Comm) (room string, er
}
if strings.TrimSpace(string(passwordBytes)) != s.password {
err = fmt.Errorf("bad password")
enc, _ := crypt.Decrypt([]byte(err.Error()), strongKeyForEncryption)
if err := c.Send(enc); err != nil {
enc, _ := crypt.Encrypt([]byte(err.Error()), strongKeyForEncryption)
if err = c.Send(enc); err != nil {
return "", fmt.Errorf("send error: %w", err)
}
return
@ -268,7 +293,6 @@ func (s *server) clientCommunication(port string, c *comm.Comm) (room string, er
err = c.Send(bSend)
if err != nil {
log.Error(err)
s.deleteRoom(room)
return
}
return
@ -327,11 +351,11 @@ func (s *server) deleteRoom(room string) {
}
s.rooms.rooms[room] = roomInfo{first: nil, second: nil}
delete(s.rooms.rooms, room)
}
// chanFromConn creates a channel from a Conn object, and sends everything it
// Read()s from the socket to the channel.
//
// Read()s from the socket to the channel.
func chanFromConn(conn net.Conn) chan []byte {
c := make(chan []byte, 1)
if err := conn.SetReadDeadline(time.Now().Add(3 * time.Hour)); err != nil {
@ -388,16 +412,20 @@ func pipe(conn1 net.Conn, conn2 net.Conn) {
}
func PingServer(address string) (err error) {
c, err := comm.NewConnection(address, 200*time.Millisecond)
log.Debugf("pinging %s", address)
c, err := comm.NewConnection(address, 300*time.Millisecond)
if err != nil {
log.Debug(err)
return
}
err = c.Send([]byte("ping"))
if err != nil {
log.Debug(err)
return
}
b, err := c.Receive()
if err != nil {
log.Debug(err)
return
}
if bytes.Equal(b, []byte("pong")) {
@ -415,87 +443,104 @@ func ConnectToTCPServer(address, password, room string, timelimit ...time.Durati
c, err = comm.NewConnection(address)
}
if err != nil {
log.Debug(err)
return
}
// get PAKE connection with server to establish strong key to transfer info
A, err := pake.InitCurve(weakKey, 0, "siec", 1*time.Microsecond)
A, err := pake.InitCurve(weakKey, 0, "siec")
if err != nil {
log.Debug(err)
return
}
err = c.Send(A.Bytes())
if err != nil {
log.Debug(err)
return
}
Bbytes, err := c.Receive()
if err != nil {
log.Debug(err)
return
}
err = A.Update(Bbytes)
if err != nil {
return
}
err = c.Send(A.Bytes())
if err != nil {
log.Debug(err)
return
}
strongKey, err := A.SessionKey()
if err != nil {
log.Debug(err)
return
}
log.Debugf("strong key: %x", strongKey)
strongKeyForEncryption, salt, err := crypt.New(strongKey, nil)
if err != nil {
log.Debug(err)
return
}
// send salt
err = c.Send(salt)
if err != nil {
log.Debug(err)
return
}
log.Debug("sending password")
bSend, err := crypt.Encrypt([]byte(password), strongKeyForEncryption)
if err != nil {
log.Debug(err)
return
}
err = c.Send(bSend)
if err != nil {
log.Debug(err)
return
}
log.Debug("waiting for first ok")
enc, err := c.Receive()
if err != nil {
log.Debug(err)
return
}
data, err := crypt.Decrypt(enc, strongKeyForEncryption)
if err != nil {
log.Debug(err)
return
}
if !strings.Contains(string(data), "|||") {
err = fmt.Errorf("bad response: %s", string(data))
log.Debug(err)
return
}
banner = strings.Split(string(data), "|||")[0]
ipaddr = strings.Split(string(data), "|||")[1]
log.Debug("sending room")
log.Debugf("sending room; %s", room)
bSend, err = crypt.Encrypt([]byte(room), strongKeyForEncryption)
if err != nil {
log.Debug(err)
return
}
err = c.Send(bSend)
if err != nil {
log.Debug(err)
return
}
log.Debug("waiting for room confirmation")
enc, err = c.Receive()
if err != nil {
log.Debug(err)
return
}
data, err = crypt.Decrypt(enc, strongKeyForEncryption)
if err != nil {
log.Debug(err)
return
}
if !bytes.Equal(data, []byte("ok")) {
err = fmt.Errorf("got bad response: %s", data)
log.Debug(err)
return
}
log.Debug("all set")

View File

@ -12,11 +12,11 @@ import (
func BenchmarkConnection(b *testing.B) {
log.SetLevel("trace")
go Run("debug", "8283", "pass123", "8284")
go Run("debug", "127.0.0.1", "8283", "pass123", "8284")
time.Sleep(100 * time.Millisecond)
b.ResetTimer()
for i := 0; i < b.N; i++ {
c, _, _, _ := ConnectToTCPServer("localhost:8283", "pass123", fmt.Sprintf("testroom%d", i), 1*time.Minute)
c, _, _, _ := ConnectToTCPServer("127.0.0.1:8283", "pass123", fmt.Sprintf("testroom%d", i), 1*time.Minute)
c.Close()
}
}
@ -24,22 +24,22 @@ func BenchmarkConnection(b *testing.B) {
func TestTCP(t *testing.T) {
log.SetLevel("error")
timeToRoomDeletion = 100 * time.Millisecond
go Run("debug", "8281", "pass123", "8282")
time.Sleep(100 * time.Millisecond)
err := PingServer("localhost:8281")
go Run("debug", "127.0.0.1", "8381", "pass123", "8382")
time.Sleep(timeToRoomDeletion)
err := PingServer("127.0.0.1:8381")
assert.Nil(t, err)
err = PingServer("localhost:8333")
err = PingServer("127.0.0.1:8333")
assert.NotNil(t, err)
time.Sleep(100 * time.Millisecond)
c1, banner, _, err := ConnectToTCPServer("localhost:8281", "pass123", "testRoom", 1*time.Minute)
assert.Equal(t, banner, "8282")
time.Sleep(timeToRoomDeletion)
c1, banner, _, err := ConnectToTCPServer("127.0.0.1:8381", "pass123", "testRoom", 1*time.Minute)
assert.Equal(t, banner, "8382")
assert.Nil(t, err)
c2, _, _, err := ConnectToTCPServer("localhost:8281", "pass123", "testRoom")
c2, _, _, err := ConnectToTCPServer("127.0.0.1:8381", "pass123", "testRoom")
assert.Nil(t, err)
_, _, _, err = ConnectToTCPServer("localhost:8281", "pass123", "testRoom")
_, _, _, err = ConnectToTCPServer("127.0.0.1:8381", "pass123", "testRoom")
assert.NotNil(t, err)
_, _, _, err = ConnectToTCPServer("localhost:8281", "pass123", "testRoom", 1*time.Nanosecond)
_, _, _, err = ConnectToTCPServer("127.0.0.1:8381", "pass123", "testRoom", 1*time.Nanosecond)
assert.NotNil(t, err)
// try sending data

View File

@ -1,28 +1,64 @@
package utils
import (
"archive/zip"
"bufio"
"bytes"
"compress/flate"
"crypto/md5"
"crypto/rand"
"crypto/sha256"
"encoding/hex"
"fmt"
"io"
"io/ioutil"
"log"
"math"
"math/big"
"net"
"net/http"
"os"
"path"
"path/filepath"
"strings"
"time"
"unicode"
"github.com/cespare/xxhash"
"github.com/kalafut/imohash"
"github.com/minio/highwayhash"
"github.com/schollz/mnemonicode"
"github.com/schollz/progressbar/v3"
)
const NbPinNumbers = 4
const NbBytesWords = 4
// Get or create home directory
func GetConfigDir(requireValidPath bool) (homedir string, err error) {
if envHomedir, isSet := os.LookupEnv("CROC_CONFIG_DIR"); isSet {
homedir = envHomedir
} else if xdgConfigHome, isSet := os.LookupEnv("XDG_CONFIG_HOME"); isSet {
homedir = path.Join(xdgConfigHome, "croc")
} else {
homedir, err = os.UserHomeDir()
if err != nil {
if !requireValidPath {
err = nil
homedir = ""
}
return
}
homedir = path.Join(homedir, ".config", "croc")
}
if requireValidPath {
if _, err = os.Stat(homedir); os.IsNotExist(err) {
err = os.MkdirAll(homedir, 0o700)
}
}
return
}
// Exists reports whether the named file or directory exists.
func Exists(name string) bool {
if _, err := os.Stat(name); err != nil {
@ -41,13 +77,83 @@ func GetInput(prompt string) string {
return strings.TrimSpace(text)
}
// HashFile returns the hash of a file
func HashFile(fname string) (hash256 []byte, err error) {
return IMOHashFile(fname)
// HashFile returns the hash of a file or, in case of a symlink, the
// SHA256 hash of its target. Takes an argument to specify the algorithm to use.
func HashFile(fname string, algorithm string, showProgress ...bool) (hash256 []byte, err error) {
doShowProgress := false
if len(showProgress) > 0 {
doShowProgress = showProgress[0]
}
var fstats os.FileInfo
fstats, err = os.Lstat(fname)
if err != nil {
return nil, err
}
if fstats.Mode()&os.ModeSymlink != 0 {
var target string
target, err = os.Readlink(fname)
if err != nil {
return nil, err
}
return []byte(SHA256(target)), nil
}
switch algorithm {
case "imohash":
return IMOHashFile(fname)
case "md5":
return MD5HashFile(fname, doShowProgress)
case "xxhash":
return XXHashFile(fname, doShowProgress)
case "highway":
return HighwayHashFile(fname, doShowProgress)
}
err = fmt.Errorf("unspecified algorithm")
return
}
// HighwayHashFile returns highwayhash of a file
func HighwayHashFile(fname string, doShowProgress bool) (hashHighway []byte, err error) {
f, err := os.Open(fname)
if err != nil {
return
}
defer f.Close()
key, err := hex.DecodeString("1553c5383fb0b86578c3310da665b4f6e0521acf22eb58a99532ffed02a6b115")
if err != nil {
return
}
h, err := highwayhash.New(key)
if err != nil {
err = fmt.Errorf("could not create highwayhash: %s", err.Error())
return
}
if doShowProgress {
stat, _ := f.Stat()
fnameShort := path.Base(fname)
if len(fnameShort) > 20 {
fnameShort = fnameShort[:20] + "..."
}
bar := progressbar.NewOptions64(stat.Size(),
progressbar.OptionSetWriter(os.Stderr),
progressbar.OptionShowBytes(true),
progressbar.OptionSetDescription(fmt.Sprintf("Hashing %s", fnameShort)),
progressbar.OptionClearOnFinish(),
)
if _, err = io.Copy(io.MultiWriter(h, bar), f); err != nil {
return
}
} else {
if _, err = io.Copy(h, f); err != nil {
return
}
}
hashHighway = h.Sum(nil)
return
}
// MD5HashFile returns MD5 hash
func MD5HashFile(fname string) (hash256 []byte, err error) {
func MD5HashFile(fname string, doShowProgress bool) (hash256 []byte, err error) {
f, err := os.Open(fname)
if err != nil {
return
@ -55,8 +161,25 @@ func MD5HashFile(fname string) (hash256 []byte, err error) {
defer f.Close()
h := md5.New()
if _, err = io.Copy(h, f); err != nil {
return
if doShowProgress {
stat, _ := f.Stat()
fnameShort := path.Base(fname)
if len(fnameShort) > 20 {
fnameShort = fnameShort[:20] + "..."
}
bar := progressbar.NewOptions64(stat.Size(),
progressbar.OptionSetWriter(os.Stderr),
progressbar.OptionShowBytes(true),
progressbar.OptionSetDescription(fmt.Sprintf("Hashing %s", fnameShort)),
progressbar.OptionClearOnFinish(),
)
if _, err = io.Copy(io.MultiWriter(h, bar), f); err != nil {
return
}
} else {
if _, err = io.Copy(h, f); err != nil {
return
}
}
hash256 = h.Sum(nil)
@ -70,8 +193,17 @@ func IMOHashFile(fname string) (hash []byte, err error) {
return
}
var imofull = imohash.NewCustom(0, 0)
// IMOHashFileFull returns imohash of full file
func IMOHashFileFull(fname string) (hash []byte, err error) {
b, err := imofull.SumFile(fname)
hash = b[:]
return
}
// XXHashFile returns the xxhash of a file
func XXHashFile(fname string) (hash256 []byte, err error) {
func XXHashFile(fname string, doShowProgress bool) (hash256 []byte, err error) {
f, err := os.Open(fname)
if err != nil {
return
@ -79,8 +211,25 @@ func XXHashFile(fname string) (hash256 []byte, err error) {
defer f.Close()
h := xxhash.New()
if _, err = io.Copy(h, f); err != nil {
return
if doShowProgress {
stat, _ := f.Stat()
fnameShort := path.Base(fname)
if len(fnameShort) > 20 {
fnameShort = fnameShort[:20] + "..."
}
bar := progressbar.NewOptions64(stat.Size(),
progressbar.OptionSetWriter(os.Stderr),
progressbar.OptionShowBytes(true),
progressbar.OptionSetDescription(fmt.Sprintf("Hashing %s", fnameShort)),
progressbar.OptionClearOnFinish(),
)
if _, err = io.Copy(io.MultiWriter(h, bar), f); err != nil {
return
}
} else {
if _, err = io.Copy(h, f); err != nil {
return
}
}
hash256 = h.Sum(nil)
@ -103,7 +252,7 @@ func PublicIP() (ip string, err error) {
defer resp.Body.Close()
if resp.StatusCode == http.StatusOK {
bodyBytes, err := ioutil.ReadAll(resp.Body)
bodyBytes, err := io.ReadAll(resp.Body)
if err != nil {
return "", err
}
@ -125,13 +274,27 @@ func LocalIP() string {
return localAddr.IP.String()
}
// GetRandomName returns mnemoicoded random name
func GenerateRandomPin() string {
s := ""
max := new(big.Int)
max.SetInt64(9)
for i := 0; i < NbPinNumbers; i++ {
v, err := rand.Int(rand.Reader, max)
if err != nil {
panic(err)
}
s += fmt.Sprintf("%d", v)
}
return s
}
// GetRandomName returns mnemonicoded random name
func GetRandomName() string {
var result []string
bs := make([]byte, 4)
bs := make([]byte, NbBytesWords)
rand.Read(bs)
result = mnemonicode.EncodeWordList(result, bs)
return strings.Join(result, "-")
return GenerateRandomPin() + "-" + strings.Join(result, "-")
}
// ByteCountDecimal converts bytes to human readable byte string
@ -197,7 +360,6 @@ func MissingChunks(fname string, fsize int64, chunkSize int) (chunkRanges []int6
}
}
chunkRanges = append(chunkRanges, int64(curCount+1))
chunks = chunkRanges
}
return
}
@ -236,7 +398,7 @@ func GetLocalIPs() (ips []string, err error) {
}
func RandomFileName() (fname string, err error) {
f, err := ioutil.TempFile(".", "croc-stdin-")
f, err := os.CreateTemp(".", "croc-stdin-")
if err != nil {
return
}
@ -286,7 +448,7 @@ func init() {
}
func IsLocalIP(ipaddress string) bool {
if strings.Contains(ipaddress, "localhost") {
if strings.Contains(ipaddress, "127.0.0.1") {
return true
}
host, _, _ := net.SplitHostPort(ipaddress)
@ -301,3 +463,127 @@ func IsLocalIP(ipaddress string) bool {
}
return false
}
func ZipDirectory(destination string, source string) (err error) {
if _, err = os.Stat(destination); err == nil {
log.Fatalf("%s file already exists!\n", destination)
}
fmt.Fprintf(os.Stderr, "Zipping %s to %s\n", source, destination)
file, err := os.Create(destination)
if err != nil {
log.Fatalln(err)
}
defer file.Close()
writer := zip.NewWriter(file)
// no compression because croc does its compression on the fly
writer.RegisterCompressor(zip.Deflate, func(out io.Writer) (io.WriteCloser, error) {
return flate.NewWriter(out, flate.NoCompression)
})
defer writer.Close()
err = filepath.Walk(source, func(path string, info os.FileInfo, err error) error {
if err != nil {
log.Fatalln(err)
}
if info.Mode().IsRegular() {
f1, err := os.Open(path)
if err != nil {
log.Fatalln(err)
}
defer f1.Close()
zipPath := strings.ReplaceAll(path, source, strings.TrimSuffix(destination, ".zip"))
zipPath = filepath.ToSlash(zipPath)
w1, err := writer.Create(zipPath)
if err != nil {
log.Fatalln(err)
}
if _, err := io.Copy(w1, f1); err != nil {
log.Fatalln(err)
}
fmt.Fprintf(os.Stderr, "\r\033[2K")
fmt.Fprintf(os.Stderr, "\rAdding %s", zipPath)
}
return nil
})
if err != nil {
log.Fatalln(err)
}
fmt.Fprintf(os.Stderr, "\n")
return nil
}
func UnzipDirectory(destination string, source string) error {
archive, err := zip.OpenReader(source)
if err != nil {
log.Fatalln(err)
}
defer archive.Close()
for _, f := range archive.File {
filePath := filepath.Join(destination, f.Name)
fmt.Fprintf(os.Stderr, "\r\033[2K")
fmt.Fprintf(os.Stderr, "\rUnzipping file %s", filePath)
// Issue #593 conceal path traversal vulnerability
// make sure the filepath does not have ".."
filePath = filepath.Clean(filePath)
if strings.Contains(filePath, "..") {
log.Fatalf("Invalid file path %s\n", filePath)
}
if f.FileInfo().IsDir() {
os.MkdirAll(filePath, os.ModePerm)
continue
}
if err := os.MkdirAll(filepath.Dir(filePath), os.ModePerm); err != nil {
log.Fatalln(err)
}
// check if file exists
if _, err := os.Stat(filePath); err == nil {
prompt := fmt.Sprintf("\nOverwrite '%s'? (y/N) ", filePath)
choice := strings.ToLower(GetInput(prompt))
if choice != "y" && choice != "yes" {
fmt.Fprintf(os.Stderr, "Skipping '%s'\n", filePath)
continue
}
}
dstFile, err := os.OpenFile(filePath, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, f.Mode())
if err != nil {
log.Fatalln(err)
}
fileInArchive, err := f.Open()
if err != nil {
log.Fatalln(err)
}
if _, err := io.Copy(dstFile, fileInArchive); err != nil {
log.Fatalln(err)
}
dstFile.Close()
fileInArchive.Close()
}
fmt.Fprintf(os.Stderr, "\n")
return nil
}
// ValidFileName checks if a filename is valid
// by making sure it has no invisible characters
func ValidFileName(fname string) bool {
clean1 := strings.Map(func(r rune) rune {
if unicode.IsGraphic(r) {
return r
}
return -1
}, fname)
clean2 := strings.Map(func(r rune) rune {
if unicode.IsPrint(r) {
return r
}
return -1
}, fname)
return (fname == clean1) && (fname == clean2)
}

View File

@ -3,7 +3,6 @@ package utils
import (
"bytes"
"fmt"
"io/ioutil"
"log"
"math/rand"
"os"
@ -13,15 +12,19 @@ import (
"github.com/stretchr/testify/assert"
)
const TCP_BUFFER_SIZE = 1024 * 64
var bigFileSize = 75000000
func bigFile() {
ioutil.WriteFile("bigfile.test", bytes.Repeat([]byte("z"), 75000000), 0666)
os.WriteFile("bigfile.test", bytes.Repeat([]byte("z"), bigFileSize), 0o666)
}
func BenchmarkMD5(b *testing.B) {
bigFile()
b.ResetTimer()
for i := 0; i < b.N; i++ {
MD5HashFile("bigfile.test")
MD5HashFile("bigfile.test", false)
}
}
@ -29,9 +32,10 @@ func BenchmarkXXHash(b *testing.B) {
bigFile()
b.ResetTimer()
for i := 0; i < b.N; i++ {
XXHashFile("bigfile.test")
XXHashFile("bigfile.test", false)
}
}
func BenchmarkImoHash(b *testing.B) {
bigFile()
b.ResetTimer()
@ -40,6 +44,22 @@ func BenchmarkImoHash(b *testing.B) {
}
}
func BenchmarkHighwayHash(b *testing.B) {
bigFile()
b.ResetTimer()
for i := 0; i < b.N; i++ {
HighwayHashFile("bigfile.test", false)
}
}
func BenchmarkImoHashFull(b *testing.B) {
bigFile()
b.ResetTimer()
for i := 0; i < b.N; i++ {
IMOHashFileFull("bigfile.test")
}
}
func BenchmarkSha256(b *testing.B) {
b.ResetTimer()
for i := 0; i < b.N; i++ {
@ -47,6 +67,14 @@ func BenchmarkSha256(b *testing.B) {
}
}
func BenchmarkMissingChunks(b *testing.B) {
bigFile()
b.ResetTimer()
for i := 0; i < b.N; i++ {
MissingChunks("bigfile.test", int64(bigFileSize), TCP_BUFFER_SIZE/2)
}
}
func TestExists(t *testing.T) {
bigFile()
defer os.Remove("bigfile.test")
@ -58,10 +86,20 @@ func TestExists(t *testing.T) {
func TestMD5HashFile(t *testing.T) {
bigFile()
defer os.Remove("bigfile.test")
b, err := MD5HashFile("bigfile.test")
b, err := MD5HashFile("bigfile.test", false)
assert.Nil(t, err)
assert.Equal(t, "8304ff018e02baad0e3555bade29a405", fmt.Sprintf("%x", b))
_, err = MD5HashFile("bigfile.test.nofile")
_, err = MD5HashFile("bigfile.test.nofile", false)
assert.NotNil(t, err)
}
func TestHighwayHashFile(t *testing.T) {
bigFile()
defer os.Remove("bigfile.test")
b, err := HighwayHashFile("bigfile.test", false)
assert.Nil(t, err)
assert.Equal(t, "3c32999529323ed66a67aeac5720c7bf1301dcc5dca87d8d46595e85ff990329", fmt.Sprintf("%x", b))
_, err = HighwayHashFile("bigfile.test.nofile", false)
assert.NotNil(t, err)
}
@ -76,10 +114,10 @@ func TestIMOHashFile(t *testing.T) {
func TestXXHashFile(t *testing.T) {
bigFile()
defer os.Remove("bigfile.test")
b, err := XXHashFile("bigfile.test")
b, err := XXHashFile("bigfile.test", false)
assert.Nil(t, err)
assert.Equal(t, "4918740eb5ccb6f7", fmt.Sprintf("%x", b))
_, err = XXHashFile("nofile")
_, err = XXHashFile("nofile", false)
assert.NotNil(t, err)
}
@ -99,9 +137,9 @@ func TestMissingChunks(t *testing.T) {
rand.Seed(1)
bigBuff := make([]byte, fileSize)
rand.Read(bigBuff)
ioutil.WriteFile("missing.test", bigBuff, 0644)
os.WriteFile("missing.test", bigBuff, 0o644)
empty := make([]byte, chunkSize)
f, err := os.OpenFile("missing.test", os.O_RDWR, 0644)
f, err := os.OpenFile("missing.test", os.O_RDWR, 0o644)
assert.Nil(t, err)
for block := 0; block < fileSize/chunkSize; block++ {
if block == 0 || block == 4 || block == 5 || block >= 7 {
@ -119,7 +157,7 @@ func TestMissingChunks(t *testing.T) {
os.Remove("missing.test")
content := []byte("temporary file's content")
tmpfile, err := ioutil.TempFile("", "example")
tmpfile, err := os.CreateTemp("", "example")
if err != nil {
log.Fatal(err)
}
@ -151,22 +189,22 @@ func TestMissingChunks(t *testing.T) {
func TestHashFile(t *testing.T) {
content := []byte("temporary file's content")
tmpfile, err := ioutil.TempFile("", "example")
tmpfile, err := os.CreateTemp("", "example")
if err != nil {
log.Fatal(err)
}
defer os.Remove(tmpfile.Name()) // clean up
if _, err := tmpfile.Write(content); err != nil {
if _, err = tmpfile.Write(content); err != nil {
panic(err)
}
if err := tmpfile.Close(); err != nil {
if err = tmpfile.Close(); err != nil {
panic(err)
}
hashed, err := HashFile(tmpfile.Name())
hashed, err := HashFile(tmpfile.Name(), "xxhash")
assert.Nil(t, err)
assert.Equal(t, "18c9673a4bb8325d323e7f24fda9ae1e", fmt.Sprintf("%x", hashed))
assert.Equal(t, "e66c561610ad51e2", fmt.Sprintf("%x", hashed))
}
func TestPublicIP(t *testing.T) {
@ -184,14 +222,41 @@ func TestLocalIP(t *testing.T) {
func TestGetRandomName(t *testing.T) {
name := GetRandomName()
fmt.Println(name)
assert.NotEmpty(t, name)
}
func intSliceSame(a, b []int) bool {
if len(a) != len(b) {
return false
}
for i, v := range a {
if v != b[i] {
return false
}
}
return true
}
func TestFindOpenPorts(t *testing.T) {
openPorts := FindOpenPorts("localhost", 9009, 4)
assert.Equal(t, []int{9009, 9010, 9011, 9012}, openPorts)
openPorts := FindOpenPorts("127.0.0.1", 9009, 4)
if !intSliceSame(openPorts, []int{9009, 9010, 9011, 9012}) && !intSliceSame(openPorts, []int{9014, 9015, 9016, 9017}) {
t.Errorf("openPorts: %v", openPorts)
}
}
func TestIsLocalIP(t *testing.T) {
assert.True(t, IsLocalIP("192.168.0.14:9009"))
}
func TestValidFileName(t *testing.T) {
// contains regular characters
assert.True(t, ValidFileName("中文.csl"))
// contains regular characters
assert.True(t, ValidFileName("[something].csl"))
// contains regular characters
assert.True(t, ValidFileName("[(something)].csl"))
// contains invisible character
assert.False(t, ValidFileName("D中文.cslouglas"))
}