mirror of https://gogs.blitter.com/RLabs/xs
Compare commits
14 Commits
Author | SHA1 | Date |
---|---|---|
Russ Magee | dbaa8b5b62 | |
Russ Magee | 77c9b8654f | |
Russ Magee | e42645a2b3 | |
Russ Magee | 057a3c01c7 | |
Russ Magee | 540cb8ff3a | |
Russ Magee | ae67ee6201 | |
Russ Magee | 8827d67cc6 | |
Russtopia | 17d7bc01ef | |
Russ Magee | 89ad0e0998 | |
Russ Magee | 713f44086a | |
Russ Magee | 08cccb6929 | |
Russ Magee | 6212119621 | |
Russtopia | faf8769ac4 | |
Russ Magee | 32b669192b |
4
Makefile
4
Makefile
|
@ -1,4 +1,4 @@
|
|||
VERSION := 0.9.6
|
||||
VERSION := 0.9.10
|
||||
.PHONY: lint vis clean common client server passwd\
|
||||
subpkgs install uninstall reinstall scc
|
||||
|
||||
|
@ -73,7 +73,7 @@ tools:
|
|||
|
||||
common:
|
||||
$(GO) build .
|
||||
go install .
|
||||
go install -a .
|
||||
|
||||
|
||||
client: common
|
||||
|
|
10
README.md
10
README.md
|
@ -197,15 +197,17 @@ or is interrupted.
|
|||
### Setting up an 'authtoken' for scripted (password-free) logins
|
||||
|
||||
Use the -g option of xs to request a token from the remote server, which will return a
|
||||
hostname:token string. Place this string into $HOME/.xs_id to allow logins without
|
||||
entering a password (obviously, $HOME/.xs_id on both server and client for the user
|
||||
hostname:token string. Place this string into $HOME/.config/xs/.xs_id to allow logins without
|
||||
entering a password (obviously, $HOME/.config/xs/.xs_id on both server and client for the user
|
||||
should *not* be world-readable.)
|
||||
|
||||
```
|
||||
$ xs -g user@host.net >~/.xs_id
|
||||
$ xs -g user@host.net >>~/.config/xs/.xs_id
|
||||
```
|
||||
[enter password blindly, authtoken entry will be stored in ~/.xs_id]
|
||||
[enter password blindly, authtoken entry will be stored in ~/.config/xs/.xs_id]
|
||||
|
||||
NOTE you may need to remove older entries for the same host if this is not the first time you have added
|
||||
it to your .xs_id file.
|
||||
|
||||
### File Copying using xc
|
||||
|
||||
|
|
9
auth.go
9
auth.go
|
@ -23,6 +23,7 @@ import (
|
|||
"runtime"
|
||||
"strings"
|
||||
|
||||
"blitter.com/go/xs/xsnet"
|
||||
"github.com/jameskeane/bcrypt"
|
||||
passlib "gopkg.in/hlandau/passlib.v1"
|
||||
)
|
||||
|
@ -52,7 +53,7 @@ func VerifyPass(ctx *AuthCtx, user, password string) (bool, error) {
|
|||
} else if runtime.GOOS == "freebsd" {
|
||||
pwFileName = "/etc/master.passwd"
|
||||
} else {
|
||||
pwFileName = "unsupported"
|
||||
return false, errors.New("Unsupported platform")
|
||||
}
|
||||
pwFileData, e := ctx.reader(pwFileName)
|
||||
if e != nil {
|
||||
|
@ -154,7 +155,7 @@ func AuthUserByPasswd(ctx *AuthCtx, username string, auth string, fname string)
|
|||
// ------------- End xs-local passwd auth routine(s) -----------
|
||||
|
||||
// AuthUserByToken checks user login information against an auth token.
|
||||
// Auth tokens are stored in each user's $HOME/.xs_id and are requested
|
||||
// Auth tokens are stored in each user's $HOME/.config/xs/.xs_id and are requested
|
||||
// via the -g option.
|
||||
// The function also check system /etc/passwd to cross-check the user
|
||||
// actually exists.
|
||||
|
@ -172,9 +173,9 @@ func AuthUserByToken(ctx *AuthCtx, username string, connhostname string, auth st
|
|||
return false
|
||||
}
|
||||
|
||||
b, e := ctx.reader(fmt.Sprintf("%s/.xs_id", u.HomeDir))
|
||||
b, e := ctx.reader(fmt.Sprintf("%s/%s", u.HomeDir, xsnet.XS_ID_AUTHTOKFILE))
|
||||
if e != nil {
|
||||
log.Printf("INFO: Cannot read %s/.xs_id\n", u.HomeDir)
|
||||
log.Printf("INFO: Cannot read %s/%s\n", u.HomeDir, xsnet.XS_ID_AUTHTOKFILE)
|
||||
return false
|
||||
}
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
export GOPATH="${HOME}/go"
|
||||
export PATH=/usr/local/bin:/usr/bin:/usr/lib/ccache/bin:/bin:$GOPATH/bin
|
||||
unset GO111MODULE
|
||||
export GOPROXY="direct"
|
||||
#export GOPROXY="direct"
|
||||
#!# GOCACHE will be phased out in v1.12. [github.com/golang/go/issues/26809]
|
||||
#!export GOCACHE="${HOME}/.cache/go-build"
|
||||
|
||||
|
@ -46,12 +46,12 @@ go test -v .
|
|||
############
|
||||
stage "Test(Authtoken)"
|
||||
############
|
||||
if [ -f ~/.xs_id ]; then
|
||||
echo "Clearing test user $USER ~/.xs_id file ..."
|
||||
mv ~/.xs_id ~/.xs_id.bak
|
||||
if [ -f ~/.config/xs/.xs_id ]; then
|
||||
echo "Clearing test user $USER .xs_id file ..."
|
||||
mv ~/.config/xs/.xs_id ~/.config/xs/.xs_id.bak
|
||||
fi
|
||||
echo "Setting dummy authtoken in ~/.xs_id ..."
|
||||
echo "localhost:${USER}:asdfasdfasdf" >~/.xs_id
|
||||
echo "Setting dummy authtoken in .xs_id ..."
|
||||
echo "localhost:${USER}:asdfasdfasdf" >~/.config/xs/.xs_id
|
||||
echo "Performing remote command on @localhost via authtoken login ..."
|
||||
tokentest=$(timeout 10 xs -x "echo -n FOO" @localhost)
|
||||
if [ "${tokentest}" != "FOO" ]; then
|
||||
|
@ -91,9 +91,9 @@ stage "Test(xc C->S)"
|
|||
############
|
||||
echo "TODO ..."
|
||||
|
||||
if [ -f ~/.xs_id.bak ]; then
|
||||
echo "Restoring test user $USER ~/.xs_id file ..."
|
||||
mv ~/.xs_id.bak ~/.xs_id
|
||||
if [ -f ~/.config/xs/.xs_id.bak ]; then
|
||||
echo "Restoring test user $USER .xs_id file ..."
|
||||
mv ~/.config/xs/.xs_id.bak ~/.config/xs/.xs_id
|
||||
fi
|
||||
|
||||
############
|
||||
|
|
34
go.mod
34
go.mod
|
@ -1,38 +1,36 @@
|
|||
module blitter.com/go/xs
|
||||
|
||||
go 1.20
|
||||
go 1.22.0
|
||||
|
||||
require (
|
||||
blitter.com/go/chacha20 v0.0.0-20200130200441-214e4085f54c
|
||||
blitter.com/go/cryptmt v1.0.2
|
||||
blitter.com/go/goutmp v1.0.6
|
||||
blitter.com/go/groestl v0.0.0-20220410000905-c4decbf31d64
|
||||
blitter.com/go/herradurakex v1.0.0
|
||||
blitter.com/go/hopscotch v0.1.1
|
||||
blitter.com/go/kyber v0.0.0-20200130200857-6f2021cb88d9
|
||||
blitter.com/go/mtwist v1.0.1
|
||||
blitter.com/go/newhope v0.0.0-20200130200750-192fc08a8aae
|
||||
github.com/aead/chacha20 v0.0.0-20180709150244-8b13a72661da
|
||||
github.com/creack/pty v1.1.18
|
||||
github.com/creack/pty v1.1.21
|
||||
github.com/jameskeane/bcrypt v0.0.0-20120420032655-c3cd44c1e20f
|
||||
github.com/klauspost/cpuid/v2 v2.2.5
|
||||
github.com/klauspost/reedsolomon v1.11.8
|
||||
github.com/kuking/go-frodokem v1.0.2
|
||||
github.com/mattn/go-isatty v0.0.19
|
||||
github.com/pkg/errors v0.9.1
|
||||
github.com/templexxx/cpufeat v0.0.0-20180724012125-cef66df7f161
|
||||
github.com/templexxx/xor v0.0.0-20191217153810-f85b25db303b
|
||||
github.com/tjfoc/gmsm v1.4.1
|
||||
github.com/mattn/go-isatty v0.0.20
|
||||
github.com/xtaci/kcp-go v5.4.20+incompatible
|
||||
golang.org/x/crypto v0.13.0
|
||||
golang.org/x/net v0.15.0
|
||||
golang.org/x/sys v0.12.0
|
||||
gopkg.in/hlandau/easymetric.v1 v1.0.0
|
||||
gopkg.in/hlandau/measurable.v1 v1.0.1
|
||||
golang.org/x/crypto v0.20.0
|
||||
golang.org/x/sys v0.17.0
|
||||
gopkg.in/hlandau/passlib.v1 v1.0.11
|
||||
)
|
||||
|
||||
require (
|
||||
blitter.com/go/chacha20 v0.0.0-20200130200441-214e4085f54c // indirect
|
||||
blitter.com/go/mtwist v1.0.1 // indirect
|
||||
github.com/klauspost/cpuid/v2 v2.2.6 // indirect
|
||||
github.com/klauspost/reedsolomon v1.12.1 // indirect
|
||||
github.com/pkg/errors v0.9.1 // indirect
|
||||
github.com/templexxx/cpufeat v0.0.0-20180724012125-cef66df7f161 // indirect
|
||||
github.com/templexxx/xor v0.0.0-20191217153810-f85b25db303b // indirect
|
||||
github.com/tjfoc/gmsm v1.4.1 // indirect
|
||||
github.com/xtaci/lossyconn v0.0.0-20200209145036-adba10fffc37 // indirect
|
||||
golang.org/x/text v0.13.0 // indirect
|
||||
golang.org/x/net v0.21.0 // indirect
|
||||
gopkg.in/hlandau/easymetric.v1 v1.0.0 // indirect
|
||||
gopkg.in/hlandau/measurable.v1 v1.0.1 // indirect
|
||||
)
|
||||
|
|
32
go.sum
32
go.sum
|
@ -4,8 +4,6 @@ blitter.com/go/cryptmt v1.0.2 h1:ZcLhQk7onUssXyQwG3GdXDXctCVnNL+b7aFuvwOdKXc=
|
|||
blitter.com/go/cryptmt v1.0.2/go.mod h1:tdME2J3O4agaDAYIYNQzzuB28yVGnPSMmV3a/ucSU84=
|
||||
blitter.com/go/goutmp v1.0.6 h1:jRKRw2WalVBza4T50etAfbvT2xp9G5uykIHTvyB5r0k=
|
||||
blitter.com/go/goutmp v1.0.6/go.mod h1:DnK/uLBu1/1yLFiuVlmwvWErzAWVp+pDv7t6ZaQRLNc=
|
||||
blitter.com/go/groestl v0.0.0-20220410000905-c4decbf31d64 h1:SH6cZ4JiOTmWGeVd5hCgt8gsMvfPPHWpEwNdxfsBugM=
|
||||
blitter.com/go/groestl v0.0.0-20220410000905-c4decbf31d64/go.mod h1:YMdIR/gCtFwU/a09jyWAwUu2J9CQejUFwkfD+PyVg+4=
|
||||
blitter.com/go/herradurakex v1.0.0 h1:6XaxY+JLT1HUWPF0gYJnjX3pVjrw4YhYZEzZ1U0wkyc=
|
||||
blitter.com/go/herradurakex v1.0.0/go.mod h1:m3+vYZX+2dDjdo+n/HDnXEYJX9pwmNeQLgAfJM8mtxw=
|
||||
blitter.com/go/hopscotch v0.1.1 h1:hh809THr3I52J5G5QozNhDSd+qGwXWGqLh3FJBGrp+o=
|
||||
|
@ -23,8 +21,8 @@ github.com/aead/chacha20 v0.0.0-20180709150244-8b13a72661da/go.mod h1:eHEWzANqSi
|
|||
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
||||
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
||||
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
|
||||
github.com/creack/pty v1.1.18 h1:n56/Zwd5o6whRC5PMGretI4IdRLlmBXYNjScPaBgsbY=
|
||||
github.com/creack/pty v1.1.18/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4=
|
||||
github.com/creack/pty v1.1.21 h1:1/QdRyBaHHJP61QkWMXlOIBfsgdDeeKfK8SYVUWJKf0=
|
||||
github.com/creack/pty v1.1.21/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4=
|
||||
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||
|
@ -47,14 +45,14 @@ github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMyw
|
|||
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/jameskeane/bcrypt v0.0.0-20120420032655-c3cd44c1e20f h1:UWGE8Vi+1Agt0lrvnd7UsmvwqWKRzb9byK9iQmsbY0Y=
|
||||
github.com/jameskeane/bcrypt v0.0.0-20120420032655-c3cd44c1e20f/go.mod h1:u+9Snq0w+ZdYKi8BBoaxnEwWu0fY4Kvu9ByFpM51t1s=
|
||||
github.com/klauspost/cpuid/v2 v2.2.5 h1:0E5MSMDEoAulmXNFquVs//DdoomxaoTY1kUhbc/qbZg=
|
||||
github.com/klauspost/cpuid/v2 v2.2.5/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws=
|
||||
github.com/klauspost/reedsolomon v1.11.8 h1:s8RpUW5TK4hjr+djiOpbZJB4ksx+TdYbRH7vHQpwPOY=
|
||||
github.com/klauspost/reedsolomon v1.11.8/go.mod h1:4bXRN+cVzMdml6ti7qLouuYi32KHJ5MGv0Qd8a47h6A=
|
||||
github.com/klauspost/cpuid/v2 v2.2.6 h1:ndNyv040zDGIDh8thGkXYjnFtiN02M1PVVF+JE/48xc=
|
||||
github.com/klauspost/cpuid/v2 v2.2.6/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws=
|
||||
github.com/klauspost/reedsolomon v1.12.1 h1:NhWgum1efX1x58daOBGCFWcxtEhOhXKKl1HAPQUp03Q=
|
||||
github.com/klauspost/reedsolomon v1.12.1/go.mod h1:nEi5Kjb6QqtbofI6s+cbG/j1da11c96IBYBSnVGtuBs=
|
||||
github.com/kuking/go-frodokem v1.0.2 h1:sxdguENCyr6WnLbJ/cjz0AYCW75H1b+E6zXY2ldZnUU=
|
||||
github.com/kuking/go-frodokem v1.0.2/go.mod h1:83ZX1kHOd72ouCsvbffCqJIj7Ih83MQTAjH2QbqzLZk=
|
||||
github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA=
|
||||
github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
|
||||
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
|
@ -81,8 +79,8 @@ golang.org/x/crypto v0.0.0-20200128174031-69ecbb4d6d5d/go.mod h1:LzIPMQfyMNhhGPh
|
|||
golang.org/x/crypto v0.0.0-20200510223506-06a226fb4e37/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20201012173705-84dcc777aaee/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.13.0 h1:mvySKfSWJ+UKUii46M40LOvyWfN0s2U+46/jDd0e6Ck=
|
||||
golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc=
|
||||
golang.org/x/crypto v0.20.0 h1:jmAMJJZXr5KiCw05dfYK9QnqaqKLYXijU23lsEdcQqg=
|
||||
golang.org/x/crypto v0.20.0/go.mod h1:Xwo95rrVNIoSMx9wa1JroENMToLWn3RNVrTBpLHgZPQ=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
|
||||
|
@ -93,8 +91,8 @@ golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73r
|
|||
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20201010224723-4f7140c49acb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.15.0 h1:ugBLEUaxABaB5AJqW9enI0ACdci2RUd4eP51NTBvuJ8=
|
||||
golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk=
|
||||
golang.org/x/net v0.21.0 h1:AQyQV4dYCvJ7vGmJyKki9+PBdyvhkSd8EIx/qb0AYv4=
|
||||
golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
|
@ -106,12 +104,10 @@ golang.org/x/sys v0.0.0-20190902133755-9109b7679e13/go.mod h1:h1NjWce9XRLGQEsW7w
|
|||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
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.12.0 h1:CM0HF96J0hcLAwsHPJZjfdNzs0gftsLfgKt57wWHJ0o=
|
||||
golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.17.0 h1:25cE3gD+tdBA7lp7QfhuV+rJiE9YXTcS3VG1SqssI/Y=
|
||||
golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
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.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k=
|
||||
golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
|
||||
|
|
50
xs/xs.go
50
xs/xs.go
|
@ -689,23 +689,24 @@ func sendSessionParams(conn io.Writer /* *xsnet.Conn*/, rec *xs.Session) (e erro
|
|||
// TODO: reduce gocyclo
|
||||
func main() { //nolint: funlen, gocyclo
|
||||
var (
|
||||
isInteractive bool
|
||||
vopt bool
|
||||
gopt bool // true: login via password, asking server to generate authToken
|
||||
dbg bool
|
||||
shellMode bool // true: act as shell, false: file copier
|
||||
cipherAlg string
|
||||
hmacAlg string
|
||||
kexAlg string
|
||||
server string
|
||||
port uint
|
||||
cmdStr string
|
||||
tunSpecStr string // lport1:rport1[,lport2:rport2,...]
|
||||
rekeySecs uint
|
||||
copySrc []byte
|
||||
copyDst string
|
||||
copyQuiet bool
|
||||
copyLimitBPS uint
|
||||
isInteractive bool
|
||||
vopt bool
|
||||
gopt bool // true: login via password, asking server to generate authToken
|
||||
dbg bool
|
||||
shellMode bool // true: act as shell, false: file copier
|
||||
cipherAlg string
|
||||
hmacAlg string
|
||||
kexAlg string
|
||||
server string
|
||||
port uint
|
||||
cmdStr string
|
||||
tunSpecStr string // lport1:rport1[,lport2:rport2,...]
|
||||
rekeySecs uint
|
||||
remodRequested bool // true: when rekeying, switch to random cipher/hmac alg
|
||||
copySrc []byte
|
||||
copyDst string
|
||||
copyQuiet bool
|
||||
copyLimitBPS uint
|
||||
|
||||
authCookie string
|
||||
chaffEnabled bool
|
||||
|
@ -745,8 +746,9 @@ func main() { //nolint: funlen, gocyclo
|
|||
KEX_FRODOKEM_976AES
|
||||
KEX_FRODOKEM_976SHAKE`)
|
||||
flag.StringVar(&kcpMode, "K", "unused", "KCP `alg`, one of [KCP_NONE | KCP_AES | KCP_BLOWFISH | KCP_CAST5 | KCP_SM4 | KCP_SALSA20 | KCP_SIMPLEXOR | KCP_TEA | KCP_3DES | KCP_TWOFISH | KCP_XTEA] to use KCP (github.com/xtaci/kcp-go) reliable UDP instead of TCP") //nolint:lll
|
||||
flag.UintVar(&port, "p", 2000, "``port") //nolint:gomnd,lll
|
||||
flag.UintVar(&port, "p", 2000, "``port") //nolint:gomnd,lll
|
||||
flag.UintVar(&rekeySecs, "r", 300, "rekey interval in `secs`")
|
||||
flag.BoolVar(&remodRequested, "R", false, "Borg Countermeasures (remodulate cipher/hmac alg on each rekey)")
|
||||
//nolint:gocritic,nolintlint // flag.StringVar(&authCookie, "a", "", "auth cookie")
|
||||
flag.BoolVar(&chaffEnabled, "e", true, "enable chaff pkts")
|
||||
flag.UintVar(&chaffFreqMin, "f", 100, "chaff pkt freq min `msecs`") //nolint:gomnd
|
||||
|
@ -885,7 +887,7 @@ func main() { //nolint: funlen, gocyclo
|
|||
if !gopt {
|
||||
// See if we can log in via an auth token
|
||||
u, _ := user.Current()
|
||||
ab, aerr := os.ReadFile(fmt.Sprintf("%s/.xs_id", u.HomeDir))
|
||||
ab, aerr := os.ReadFile(fmt.Sprintf("%s/%s", u.HomeDir, xsnet.XS_ID_AUTHTOKFILE))
|
||||
if aerr == nil {
|
||||
for _, line := range strings.Split(string(ab), "\n") {
|
||||
line += "\n"
|
||||
|
@ -903,7 +905,7 @@ func main() { //nolint: funlen, gocyclo
|
|||
_, _ = fmt.Fprintln(os.Stderr, "[no authtoken, use -g to request one from server]")
|
||||
}
|
||||
} else {
|
||||
log.Printf("[cannot read %s/.xs_id]\n", u.HomeDir)
|
||||
log.Printf("[cannot read %s/%s]\n", u.HomeDir, xsnet.XS_ID_AUTHTOKFILE)
|
||||
}
|
||||
}
|
||||
runtime.GC()
|
||||
|
@ -967,7 +969,13 @@ func main() { //nolint: funlen, gocyclo
|
|||
if kcpMode != "unused" {
|
||||
proto = "kcp"
|
||||
}
|
||||
conn, err := xsnet.Dial(proto, server, cipherAlg, hmacAlg, kexAlg, kcpMode)
|
||||
|
||||
remodExtArg := ""
|
||||
if remodRequested {
|
||||
remodExtArg = "OPT_REMOD"
|
||||
}
|
||||
// Pass opt to Dial() via extensions arg
|
||||
conn, err := xsnet.Dial(proto, server, cipherAlg, hmacAlg, kexAlg, kcpMode, remodExtArg)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
exitWithStatus(XSNetDialFailed)
|
||||
|
|
22
xsd/xsd.go
22
xsd/xsd.go
|
@ -530,12 +530,14 @@ func main() { //nolint:funlen,gocyclo
|
|||
var dbg bool
|
||||
var laddr string
|
||||
var rekeySecs uint
|
||||
var remodSupported bool // true: when rekeying, switch to random cipher/hmac alg
|
||||
|
||||
var useSystemPasswd bool
|
||||
|
||||
flag.BoolVar(&vopt, "v", false, "show version")
|
||||
flag.UintVar(&rekeySecs, "r", 300, "rekey interval in `secs`")
|
||||
flag.StringVar(&laddr, "l", ":2000", "interface[:port] to listen") //nolint:gomnd,lll
|
||||
flag.BoolVar(&remodSupported, "R", false, "Borg Countermeasures (remodulate cipher/hmac alg on each rekey)")
|
||||
flag.StringVar(&laddr, "l", ":2000", "interface[:port] to listen") //nolint:gomnd,lll
|
||||
flag.StringVar(&kcpMode, "K", "unused", `set to one of ["KCP_NONE","KCP_AES", "KCP_BLOWFISH", "KCP_CAST5", "KCP_SM4", "KCP_SALSA20", "KCP_SIMPLEXOR", "KCP_TEA", "KCP_3DES", "KCP_TWOFISH", "KCP_XTEA"] to use KCP (github.com/xtaci/kcp-go) reliable UDP instead of TCP`) //nolint:lll
|
||||
flag.BoolVar(&useSysLogin, "L", false, "use system login")
|
||||
flag.BoolVar(&chaffEnabled, "e", true, "enable chaff pkts")
|
||||
|
@ -702,6 +704,22 @@ func main() { //nolint:funlen,gocyclo
|
|||
} else {
|
||||
log.Println("Accepted client")
|
||||
|
||||
// Only enable cipher alg changes on re-key if we were told
|
||||
// to support it (launching xsd with -R), *and* the client
|
||||
// proposes to use it.
|
||||
if !remodSupported {
|
||||
if (conn.Opts() & xsnet.CORemodulateShields) != 0 {
|
||||
logger.LogDebug("[client proposed cipher/hmac remod, but we don't support it.]")
|
||||
conn.Close()
|
||||
continue
|
||||
}
|
||||
} else {
|
||||
if conn.Opts()&xsnet.CORemodulateShields != 0 {
|
||||
logger.LogDebug("[cipher/hmac remodulation active]")
|
||||
} else {
|
||||
logger.LogDebug("[cipher/hmac remodulation inactive]")
|
||||
}
|
||||
}
|
||||
conn.RekeyHelper(rekeySecs)
|
||||
|
||||
// Set up chaffing to client
|
||||
|
@ -823,7 +841,7 @@ func main() { //nolint:funlen,gocyclo
|
|||
hname := goutmp.GetHost(addr.String())
|
||||
logger.LogNotice(fmt.Sprintf("[Generating autologin token for [%s@%s]]\n", rec.Who(), hname)) //nolint:errcheck
|
||||
token := GenAuthToken(string(rec.Who()), string(rec.ConnHost()))
|
||||
tokenCmd := fmt.Sprintf("echo %q | tee -a ~/.xs_id", token)
|
||||
tokenCmd := fmt.Sprintf("echo %q | tee -a ~/%s", token, xsnet.XS_ID_AUTHTOKFILE)
|
||||
cmdStatus, runErr := runShellAs(string(rec.Who()), hname, string(rec.TermType()), tokenCmd, false, hc, chaffEnabled)
|
||||
// Returned hopefully via an EOF or exit/logout;
|
||||
// Clear current op so user can enter next, or EOF
|
||||
|
|
|
@ -22,6 +22,7 @@ import (
|
|||
|
||||
"blitter.com/go/cryptmt"
|
||||
"blitter.com/go/hopscotch"
|
||||
"blitter.com/go/xs/logger"
|
||||
"github.com/aead/chacha20/chacha"
|
||||
"golang.org/x/crypto/blowfish"
|
||||
"golang.org/x/crypto/twofish"
|
||||
|
@ -57,9 +58,19 @@ func expandKeyMat(keymat []byte, blocksize int) []byte {
|
|||
return keymat
|
||||
}
|
||||
|
||||
/* (Re-)initialize the keystream and hmac state for an xsnet.Conn, returning
|
||||
a cipherStream and hash
|
||||
*/
|
||||
// Choose a cipher and hmac alg from supported sets, given two uint8 values
|
||||
func getNewStreamAlgs(cb uint8, hb uint8) (config uint32) {
|
||||
// Get new cipher and hash algs (clamped to valid values) based on
|
||||
// the input rekeying data
|
||||
c := (cb % CAlgNoneDisallowed)
|
||||
h := (hb % HmacNoneDisallowed)
|
||||
config = uint32(h<<8) | uint32(c)
|
||||
logger.LogDebug(fmt.Sprintf("[Chose new algs [%d:%d]", h, c))
|
||||
return
|
||||
}
|
||||
|
||||
// (Re-)initialize the keystream and hmac state for an xsnet.Conn, returning
|
||||
// a cipherStream and hash
|
||||
func (hc *Conn) getStream(keymat []byte) (rc cipher.Stream, mc hash.Hash, err error) {
|
||||
var key []byte
|
||||
var block cipher.Block
|
||||
|
|
|
@ -122,5 +122,23 @@ const (
|
|||
HmacNoneDisallowed
|
||||
)
|
||||
|
||||
// Conn opts outside of basic kex/cipher/hmac connect config
|
||||
const (
|
||||
CONone = iota
|
||||
CORemodulateShields // if set, rekeying also reselects random cipher/hmac alg
|
||||
)
|
||||
|
||||
type COValue uint32
|
||||
|
||||
// Available HMACs for hkex.Conn
|
||||
type CSHmacAlg uint32
|
||||
|
||||
// Some bounds-checking consts
|
||||
const (
|
||||
REKEY_SECS_MIN = 1
|
||||
REKEY_SECS_MAX = 28800 // 8 hours
|
||||
CHAFF_FREQ_MSECS_MIN = 1
|
||||
CHAFF_FREQ_MSECS_MAX = 300000 // 5 minutes
|
||||
)
|
||||
|
||||
const XS_ID_AUTHTOKFILE = ".config/xs/.xs_id"
|
||||
|
|
62
xsnet/net.go
62
xsnet/net.go
|
@ -241,7 +241,7 @@ func (hc *Conn) SetConnOpts(copts uint32) {
|
|||
//
|
||||
// Consumers of this lib may use this for protocol-level options not part
|
||||
// of the KEx or encryption info used by the connection.
|
||||
func (hc Conn) Opts() uint32 {
|
||||
func (hc *Conn) Opts() uint32 {
|
||||
return hc.opts
|
||||
}
|
||||
|
||||
|
@ -363,6 +363,9 @@ func (hc *Conn) applyConnExtensions(extensions ...string) {
|
|||
log.Println("[extension arg = H_SHA512]")
|
||||
hc.cipheropts &= (0xFFFF00FF)
|
||||
hc.cipheropts |= (HmacSHA512 << 8)
|
||||
case "OPT_REMOD":
|
||||
log.Println("[extension arg = OPT_REMOD]")
|
||||
hc.opts |= CORemodulateShields
|
||||
//default:
|
||||
// log.Printf("[Dial ext \"%s\" ignored]\n", s)
|
||||
}
|
||||
|
@ -1351,6 +1354,11 @@ func (hc *Conn) Read(b []byte) (n int, err error) {
|
|||
//logger.LogDebug(fmt.Sprintf("[Got rekey [%02x %02x %02x ...]\n",
|
||||
// payloadBytes[0], payloadBytes[1], payloadBytes[2]))
|
||||
rekeyData := payloadBytes
|
||||
if (hc.opts & CORemodulateShields) != 0 {
|
||||
hc.Lock()
|
||||
hc.cipheropts = getNewStreamAlgs(rekeyData[0], rekeyData[1])
|
||||
hc.Unlock()
|
||||
}
|
||||
hc.r, hc.rm, err = hc.getStream(rekeyData)
|
||||
case CSOTermSize:
|
||||
fmt.Sscanf(string(payloadBytes), "%d %d", &hc.Rows, &hc.Cols)
|
||||
|
@ -1585,27 +1593,61 @@ func (hc *Conn) StartupChaff() {
|
|||
}
|
||||
|
||||
func (hc *Conn) ShutdownChaff() {
|
||||
hc.Lock()
|
||||
hc.chaff.shutdown = true
|
||||
hc.Unlock()
|
||||
log.Println("Chaffing SHUTDOWN")
|
||||
}
|
||||
|
||||
func (hc *Conn) SetupChaff(msecsMin uint, msecsMax uint, szMax uint) {
|
||||
// Enforce bounds on chaff frequency and pkt size
|
||||
hc.Lock()
|
||||
if hc.chaff.msecsMin < CHAFF_FREQ_MSECS_MIN {
|
||||
hc.chaff.msecsMin = CHAFF_FREQ_MSECS_MIN
|
||||
}
|
||||
if hc.chaff.msecsMax > CHAFF_FREQ_MSECS_MAX {
|
||||
hc.chaff.msecsMax = CHAFF_FREQ_MSECS_MAX
|
||||
}
|
||||
hc.Unlock()
|
||||
|
||||
hc.chaff.msecsMin = msecsMin //move these to params of chaffHelper() ?
|
||||
hc.chaff.msecsMax = msecsMax
|
||||
hc.chaff.szMax = szMax
|
||||
}
|
||||
|
||||
func (hc *Conn) ShutdownRekey() {
|
||||
hc.Lock()
|
||||
hc.rekey = 0
|
||||
hc.Unlock()
|
||||
}
|
||||
|
||||
func (hc *Conn) RekeyHelper(intervalSecs uint) {
|
||||
if intervalSecs < REKEY_SECS_MIN {
|
||||
intervalSecs = REKEY_SECS_MIN
|
||||
}
|
||||
if intervalSecs > REKEY_SECS_MAX {
|
||||
intervalSecs = REKEY_SECS_MAX
|
||||
}
|
||||
|
||||
go func() {
|
||||
hc.Lock()
|
||||
hc.rekey = intervalSecs
|
||||
hc.Unlock()
|
||||
|
||||
for {
|
||||
if hc.rekey != 0 {
|
||||
hc.Lock()
|
||||
rekey := hc.rekey
|
||||
hc.Unlock()
|
||||
|
||||
if rekey != 0 {
|
||||
jitter := rand.Intn(int(rekey)) / 4
|
||||
rekey = rekey - uint(jitter)
|
||||
if rekey < 1 {
|
||||
rekey = 1
|
||||
}
|
||||
|
||||
//logger.LogDebug(fmt.Sprintf("[rekeyHelper Loop]\n"))
|
||||
time.Sleep(time.Duration(hc.rekey) * time.Second)
|
||||
time.Sleep(time.Duration(rekey) * time.Second)
|
||||
|
||||
// Send rekey to other end
|
||||
rekeyData := make([]byte, 64)
|
||||
|
@ -1615,6 +1657,9 @@ func (hc *Conn) RekeyHelper(intervalSecs uint) {
|
|||
//logger.LogDebug("[+rekeyHelper]")
|
||||
_, err = hc.WritePacket(rekeyData, CSORekey)
|
||||
hc.Lock()
|
||||
if (hc.opts & CORemodulateShields) != 0 {
|
||||
hc.cipheropts = getNewStreamAlgs(rekeyData[0], rekeyData[1])
|
||||
}
|
||||
hc.w, hc.wm, err = hc.getStream(rekeyData)
|
||||
//logger.LogDebug("[-rekeyHelper]")
|
||||
hc.Unlock()
|
||||
|
@ -1635,7 +1680,10 @@ func (hc *Conn) chaffHelper() {
|
|||
var nextDuration int
|
||||
for {
|
||||
//logger.LogDebug(fmt.Sprintf("[chaffHelper Loop]\n"))
|
||||
if !hc.chaff.shutdown {
|
||||
hc.Lock()
|
||||
shutdown := hc.chaff.shutdown
|
||||
hc.Unlock()
|
||||
if !shutdown {
|
||||
var bufTmp []byte
|
||||
bufTmp = make([]byte, rand.Intn(int(hc.chaff.szMax)))
|
||||
min := int(hc.chaff.msecsMin)
|
||||
|
@ -1646,7 +1694,9 @@ func (hc *Conn) chaffHelper() {
|
|||
//logger.LogDebug("[-chaffHelper]")
|
||||
if err != nil {
|
||||
log.Println("[ *** error - chaffHelper shutting down *** ]")
|
||||
hc.Lock()
|
||||
hc.chaff.shutdown = true
|
||||
hc.Unlock()
|
||||
break
|
||||
}
|
||||
} else {
|
||||
|
@ -1670,7 +1720,9 @@ func (hc *Conn) ShutdownKeepAlive() {
|
|||
}
|
||||
|
||||
func (hc *Conn) ResetKeepAlive() {
|
||||
hc.Lock()
|
||||
hc.keepalive = 3
|
||||
hc.Unlock()
|
||||
log.Println("KeepAlive RESET")
|
||||
}
|
||||
|
||||
|
@ -1689,7 +1741,9 @@ func (hc *Conn) keepaliveHelper() {
|
|||
break
|
||||
}
|
||||
time.Sleep(time.Duration(nextDuration) * time.Millisecond)
|
||||
hc.Lock()
|
||||
hc.keepalive -= 1
|
||||
hc.Unlock()
|
||||
//logger.LogDebug(fmt.Sprintf("[keepAlive is now %d]\n", hc.keepalive))
|
||||
|
||||
//if rand.Intn(8) == 0 {
|
||||
|
|
Loading…
Reference in New Issue