mirror of https://gogs.blitter.com/RLabs/xs
Compare commits
No commits in common. "master" and "v0.8.10" have entirely different histories.
160
.golangci.yml
160
.golangci.yml
|
@ -1,160 +0,0 @@
|
|||
linters-settings:
|
||||
depguard:
|
||||
list-type: blacklist
|
||||
packages:
|
||||
# logging is allowed only by logutils.Log, logrus
|
||||
# is allowed to use only in logutils package
|
||||
- github.com/sirupsen/logrus
|
||||
packages-with-error-message:
|
||||
- github.com/sirupsen/logrus: "logging is allowed only by logutils.Log"
|
||||
dupl:
|
||||
threshold: 125
|
||||
funlen:
|
||||
lines: 125
|
||||
statements: 50
|
||||
gci:
|
||||
local-prefixes: github.com/golangci/golangci-lint
|
||||
goconst:
|
||||
min-len: 2
|
||||
min-occurrences: 2
|
||||
gocritic:
|
||||
enabled-tags:
|
||||
- diagnostic
|
||||
- experimental
|
||||
- performance
|
||||
#- style
|
||||
#- opinionated
|
||||
disabled-checks:
|
||||
- commentFormatting
|
||||
- commentedOutCode
|
||||
- dupImport # https://github.com/go-critic/go-critic/issues/845
|
||||
- ifElseChain
|
||||
- octalLiteral
|
||||
- whyNoLint
|
||||
- wrapperFunc
|
||||
gocyclo:
|
||||
min-complexity: 15
|
||||
goimports:
|
||||
local-prefixes: github.com/golangci/golangci-lint
|
||||
gomnd:
|
||||
settings:
|
||||
mnd:
|
||||
# don't include the "operation" and "assign"
|
||||
checks: argument,case,condition,return
|
||||
govet:
|
||||
check-shadowing: true
|
||||
settings:
|
||||
printf:
|
||||
funcs:
|
||||
- (github.com/golangci/golangci-lint/pkg/logutils.Log).Infof
|
||||
- (github.com/golangci/golangci-lint/pkg/logutils.Log).Warnf
|
||||
- (github.com/golangci/golangci-lint/pkg/logutils.Log).Errorf
|
||||
- (github.com/golangci/golangci-lint/pkg/logutils.Log).Fatalf
|
||||
lll:
|
||||
line-length: 140
|
||||
maligned:
|
||||
suggest-new: true
|
||||
misspell:
|
||||
locale: en_CA
|
||||
nolintlint:
|
||||
allow-leading-space: true # don't require machine-readable nolint directives (i.e. with no leading space)
|
||||
allow-unused: false # report any unused nolint directives
|
||||
require-explanation: false # don't require an explanation for nolint directives
|
||||
require-specific: false # don't require nolint directives to be specific about which linter is being skipped
|
||||
|
||||
linters:
|
||||
# please, do not use `enable-all`: it's deprecated and will be removed soon.
|
||||
# inverted configuration with `enable-all` and `disable` is not scalable during updates of golangci-lint
|
||||
disable-all: true
|
||||
enable:
|
||||
- bodyclose
|
||||
- depguard
|
||||
- dogsled
|
||||
- dupl
|
||||
- errcheck
|
||||
- exhaustive
|
||||
- exportloopref
|
||||
- funlen
|
||||
- gochecknoinits
|
||||
- goconst
|
||||
- gocritic
|
||||
- gocyclo
|
||||
- gofmt
|
||||
- goimports
|
||||
#- golint
|
||||
- gomnd
|
||||
- goprintffuncname
|
||||
- gosec
|
||||
- gosimple
|
||||
- govet
|
||||
- ineffassign
|
||||
#- interfacer
|
||||
- lll
|
||||
- misspell
|
||||
#- nakedret
|
||||
- noctx
|
||||
- nolintlint
|
||||
- rowserrcheck
|
||||
#- scopelint
|
||||
- staticcheck
|
||||
#- structcheck
|
||||
- stylecheck
|
||||
- typecheck
|
||||
- unconvert
|
||||
- unparam
|
||||
- unused
|
||||
#- varcheck
|
||||
- whitespace
|
||||
|
||||
# don't enable:
|
||||
# - asciicheck
|
||||
# - deadcode
|
||||
# - gochecknoglobals
|
||||
# - gocognit
|
||||
# - godot
|
||||
# - godox
|
||||
# - goerr113
|
||||
# - golint
|
||||
# - interfacer
|
||||
# - maligned
|
||||
# - nestif
|
||||
# - prealloc
|
||||
## - rowserrcheck
|
||||
# - scopelint
|
||||
# - structcheck
|
||||
# - testpackage
|
||||
# - varcheck
|
||||
# - wsl
|
||||
|
||||
issues:
|
||||
# Excluding configuration per-path, per-linter, per-text and per-source
|
||||
exclude-rules:
|
||||
- path: _test\.go
|
||||
linters:
|
||||
- gomnd
|
||||
|
||||
# https://github.com/go-critic/go-critic/issues/926
|
||||
- linters:
|
||||
- gocritic
|
||||
text: "unnecessaryDefer:"
|
||||
|
||||
# TODO temporary rule, must be removed
|
||||
# seems related to v0.34.1, but I was not able to reproduce locally,
|
||||
# I was also not able to reproduce in the CI of a fork,
|
||||
# only the golangci-lint CI seems to be affected by this invalid analysis.
|
||||
- path: pkg/golinters/scopelint.go
|
||||
text: 'directive `//nolint:interfacer` is unused for linter interfacer'
|
||||
|
||||
run:
|
||||
skip-dirs:
|
||||
- test/testdata_etc
|
||||
- internal/cache
|
||||
- internal/renameio
|
||||
- internal/robustio
|
||||
|
||||
# golangci.com configuration
|
||||
# https://github.com/golangci/golangci/wiki/Configuration
|
||||
service:
|
||||
golangci-lint-version: 1.23.x # use the fixed version to not introduce new linters unexpectedly
|
||||
prepare:
|
||||
- echo "here I can run custom commands, but no preparation needed for this repo"
|
|
@ -55,7 +55,5 @@ to the project. Any intent to deviate the project from its original purpose
|
|||
of existence will constitute grounds for remedial action which may include
|
||||
expulsion from the project.
|
||||
|
||||
This document is based upon the original Code of Merit version 1.0 (Dec 4 2018).
|
||||
This document is based upon the Code of Merit version 1.0 (Dec 4 2018).
|
||||
(https://web.archive.org/web/20181204203029/http://code-of-merit.org/)
|
||||
|
||||
Updated version (Mar 29 2020): https://codeofmerit.org/code/
|
|
@ -1,6 +1,6 @@
|
|||
MIT License
|
||||
|
||||
Copyright (c) 2017 - 2021 Russell Magee (xs/xsd/xsnet/xspasswd)
|
||||
Copyright (c) 2017 - 2019 Russell Magee (xs/xsd/xsnet/xspasswd)
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
110
Makefile
110
Makefile
|
@ -1,57 +1,24 @@
|
|||
VERSION := 0.9.13
|
||||
.PHONY: lint vis clean common client server passwd\
|
||||
subpkgs install uninstall reinstall scc
|
||||
.PHONY: lint vis clean common client server passwd subpkgs install uninstall reinstall
|
||||
|
||||
## Tag version of binaries with build info wrt.
|
||||
## GO111MODULE(=on) and vendor/ setup vs. $GOPATH pkg builds
|
||||
############################################################
|
||||
ifeq ($(shell go env GOMOD),)
|
||||
MTAG=
|
||||
else
|
||||
MTAG="-m"
|
||||
endif
|
||||
|
||||
# If available, one may build 'garbled' binaries
|
||||
# See https://github.com/burrowers/garble.git
|
||||
ifeq ($(GARBLE),y)
|
||||
GO=garble -literals -tiny -debugdir=garbled
|
||||
else
|
||||
GO=go
|
||||
endif
|
||||
|
||||
ifneq ($(VENDOR),)
|
||||
GOBUILDOPTS :=-v -mod vendor
|
||||
VTAG = "-v"
|
||||
else
|
||||
GOBUILDOPTS=
|
||||
VTAG =
|
||||
endif
|
||||
############################################################
|
||||
#ifeq ($(MAKEOPTS),)
|
||||
MAKEOPTS = $(MAKEOPTS)
|
||||
#endif
|
||||
|
||||
GIT_COMMIT := $(shell git rev-list -1 HEAD)
|
||||
|
||||
VERSION := 0.8.10
|
||||
#ifeq ($(BUILDOPTS),)
|
||||
BUILDOPTS :=$(BUILDOPTS)"$(GOBUILDOPTS) -ldflags \"-X main.version=$(VERSION)$(MTAG)$(VTAG) -X main.gitCommit=$(GIT_COMMIT)\""
|
||||
BUILDOPTS :=$(BUILDOPTS)" -ldflags \"-X main.version=$(VERSION) -X main.gitCommit=$(GIT_COMMIT)\""
|
||||
#endif
|
||||
|
||||
SUBPKGS = logger spinsult xsnet
|
||||
TOOLS = xs xsd
|
||||
TOOLS = xspasswd xs xsd
|
||||
SUBDIRS = $(LIBS) $(TOOLS)
|
||||
|
||||
ifeq ($(GOOS),)
|
||||
GOOS=$(shell go env GOOS)
|
||||
endif
|
||||
|
||||
ifeq ($(GOOS),windows)
|
||||
INSTPREFIX = /usr
|
||||
else
|
||||
INSTPREFIX = /usr/local
|
||||
endif
|
||||
|
||||
all: common client server
|
||||
all: common client server passwd
|
||||
|
||||
clean:
|
||||
@echo "Make: $(MAKE)"
|
||||
go clean .
|
||||
for d in $(SUBDIRS); do\
|
||||
$(MAKE) -C $$d clean;\
|
||||
|
@ -69,52 +36,69 @@ tools:
|
|||
|
||||
|
||||
common:
|
||||
$(GO) build .
|
||||
go install -a .
|
||||
go build .
|
||||
go install .
|
||||
|
||||
|
||||
client: common
|
||||
$(MAKE) BUILDOPTS=$(BUILDOPTS) -C xs
|
||||
|
||||
|
||||
ifeq ($(MSYSTEM),)
|
||||
ifneq ($(GOOS),windows)
|
||||
server: common
|
||||
ifeq ($(GOOS),windows)
|
||||
echo "Build of xsd server for Windows not yet supported"
|
||||
else
|
||||
$(MAKE) BUILDOPTS=$(BUILDOPTS) -C xsd
|
||||
else
|
||||
echo "Cross-build of xsd server for Windows not yet supported"
|
||||
endif
|
||||
else
|
||||
server: common
|
||||
echo "xsd server not (yet) supported on Windows"
|
||||
endif
|
||||
|
||||
scc:
|
||||
@scc --exclude-dir=bacillus,vendor,garbled --cocomo-project-type=rlabs,3,1.12,1,1
|
||||
|
||||
passwd: common
|
||||
$(MAKE) BUILDOPTS=$(BUILDOPTS) -C xspasswd
|
||||
|
||||
vis:
|
||||
@which go-callvis >/dev/null 2>&1; \
|
||||
stat=$$?; if [ $$stat -ne "0" ]; then \
|
||||
/bin/echo "go-callvis not found. Run go get https://github.com/TrueFurby/go-callvis to install."; \
|
||||
/bin/echo "go-callvis not found. Run go get github.com/Russtopia/go-callvis to install."; \
|
||||
else \
|
||||
$(MAKE) -C xs vis;\
|
||||
$(MAKE) -C xsd vis;\
|
||||
make -C xs vis;\
|
||||
make -C xsd vis;\
|
||||
make -C xspasswd vis; \
|
||||
fi
|
||||
|
||||
lint:
|
||||
$(MAKE) -C xsd lint
|
||||
$(MAKE) -C xs lint
|
||||
make -C xspasswd lint
|
||||
make -C xsd lint
|
||||
make -C xs lint
|
||||
|
||||
reinstall: uninstall install
|
||||
|
||||
install:
|
||||
ifeq ($(GOOS),windows)
|
||||
cp xs/xs $(INSTPREFIX)/bin/xs
|
||||
cp xs/xs $(INSTPREFIX)/bin/xc
|
||||
@echo "Install of xsd server for Windows not yet supported"
|
||||
else
|
||||
cp xs/xs $(INSTPREFIX)/bin
|
||||
cd $(INSTPREFIX)/bin && ln -s xs xc && cd -
|
||||
cp xsd/xsd $(INSTPREFIX)/sbin
|
||||
ifeq ($(MSYSTEM),)
|
||||
ifneq ($(GOOS),windows)
|
||||
cp xsd/xsd xspasswd/xspasswd $(INSTPREFIX)/sbin
|
||||
else
|
||||
mv $(INSTPREFIX)/bin/xs $(INSTPREFIX)/bin/_xs
|
||||
cp xs/mintty_wrapper.sh $(INSTPREFIX)/bin/xs
|
||||
echo "Cross-build of xsd server for Windows not yet supported"
|
||||
endif
|
||||
else
|
||||
echo "Cross-build of xsd server for Windows not yet supported"
|
||||
endif
|
||||
cd $(INSTPREFIX)/bin && ln -s xs xc && cd -
|
||||
|
||||
|
||||
uninstall:
|
||||
rm -f $(INSTPREFIX)/bin/xs $(INSTPREFIX)/bin/xc
|
||||
ifndef $(WIN_MSYS)
|
||||
rm -f $(INSTPREFIX)/sbin/xsd
|
||||
rm -f $(INSTPREFIX)/bin/xs $(INSTPREFIX)/bin/xc $(INSTPREFIX)/bin/_xs
|
||||
ifeq ($(MSYSTEM),)
|
||||
ifneq ($(GOOS),windows)
|
||||
rm -f $(INSTPREFIX)/sbin/xsd $(INSTPREFIX)/sbin/xspasswd
|
||||
else
|
||||
endif
|
||||
else
|
||||
endif
|
||||
|
|
119
README.md
119
README.md
|
@ -1,20 +1,12 @@
|
|||
[](https://godoc.org/blitter.com/go/xs)
|
||||
|
||||
# XS
|
||||
|
||||

|
||||
# XS
|
||||
--
|
||||
|
||||
XS (**X**perimental **S**hell) is a simple alternative to ssh (<5% total SLOCC) written from scratch in Go.
|
||||
A testbed for candidate PQC (Post-Quantum Cryptography) KEMs (Key-Encapsulation Mechanisms) and symmetric
|
||||
session encryption algorithms.
|
||||
|
||||
xs also features integrated traffic chaffing to obscure interactive session and file copy activity.
|
||||
Supports encrypted interactive and non-interactive sessions (remote commands), remote file copying and tunnels.
|
||||
|
||||
Runs on Linux, FreeBSD, Windows (client only, MSYS) and Android (within Termux). https://gogs.blitter.com/RLabs/xs
|
||||
|
||||
It is stable to the point that I use it for day-to-day remote access in place of, and in preference to, ssh.
|
||||
XS (**X**perimental **S**hell) is a golang implementation of a simple remote shell client and
|
||||
server, similar in role to ssh, offering encrypted interactive and non-interactive sessions,
|
||||
file copying and tunnels with traffic obfuscation ('chaffing').
|
||||
|
||||
***
|
||||
**NOTE: Due to the experimental nature of the KEX/KEM algorithms used, and the novelty of the overall codebase, this package SHOULD BE CONSIDERED EXTREMELY EXPERIMENTAL and USED WITH CAUTION. It DEFINITELY SHOULD NOT be used for any sensitive applications. USE AT YOUR OWN RISK. NEITHER WARRANTY NOR CLAIM OF FITNESS FOR PURPOSE IS EXPRESSED OR IMPLIED.**
|
||||
|
@ -32,9 +24,9 @@ Currently supported exchanges are:
|
|||
|
||||
* The HerraduraKEx key exchange algorithm first released at
|
||||
[Omar Elejandro Herrera Reyna's HerraduraKEx project](http://github.com/Caume/HerraduraKEx);
|
||||
* The KYBER IND-CCA-2 secure key encapsulation mechanism, [pq-crystals Kyber](https://pq-crystals.org/kyber/) :: [Yawning/kyber golang implementation](https://gitlab.com/yawning/kyber)
|
||||
* The NEWHOPE algorithm [newhopecrypto.org](https://www.newhopecrypto.org/) :: [Yawning/newhope golang implementation](https://gitlab.com/yawning/newhope)
|
||||
* The FrodoKEM algorithm [frodokem.org](https://frodokem.org/) :: Go version by [Eduardo E. S. Riccardi](https://github.com/kuking/go-frodokem)
|
||||
* The KYBER IND-CCA-2 secure key encapsulation mechanism, [pq-crystals Kyber](https://pq-crystals.org/kyber/) :: [Yawning/kyber golang implementation](https://git.schwanenlied.me/yawning/kyber)
|
||||
* The NEWHOPE algorithm [newhopecrypto.org](https://www.newhopecrypto.org/) :: [Yawning/go-newhope golang implementation](https://git.schwanenlied.me/yawning/newhope)
|
||||
|
||||
|
||||
Currently supported session algorithms:
|
||||
|
||||
|
@ -43,27 +35,10 @@ Currently supported session algorithms:
|
|||
* Twofish-128
|
||||
* Blowfish-64
|
||||
* CryptMTv1 (64bit) (https://eprint.iacr.org/2005/165.pdf)
|
||||
* ChaCha20 (https://github.com/aead/chacha20)
|
||||
* HOPSCOTCH (https://gogs.blitter.com/Russtopia/hopscotch)
|
||||
|
||||
[HMAC]
|
||||
* HMAC-SHA256
|
||||
* HMAC-SHA512
|
||||
* WHIRLPOOL
|
||||
|
||||
***
|
||||
**A Note on 'cryptographic agility'**
|
||||
|
||||
It has been suggested recently to me that offering multiple cryptographic primitives is considered bad in 2021.
|
||||
|
||||
An interesting question. See [this write-up for a discussion](https://paragonie.com/blog/2019/10/against-agility-in-cryptography-protocols).
|
||||
|
||||
xs operates via the philosophy that **it is the server admin's prerogitive to configure local policy wrt. allowed cryptographic primitives**. The connection protocol makes no allowance for any sort of 'downgrades' or algo substitution during negotiation; there is no 'fallback' mode or two-way negotiation of what primitives to use, which would open the possibility of downgrade attacks. Unlike `ssh`, the server does not offer to clients a list of supported algorithms; the client can only offer a single configuration to the server, which it simply accepts or rejects without comment to the client.
|
||||
|
||||
In all releases prior to v0.9.3, absent a specific whitelist of algs to allow, the server allows 'all' combinations of the above cryptographic primitives to be proposed by clients (but again, **only one** combination is proposed by the client in a single connect attempt). If the admin wishes to restrict the accepted algorithms now or at any future time, they may use the `-aK`, `-aC` and `-aH` options when launching the server to define a whitelist which excludes certain primitives.
|
||||
|
||||
As of release v0.9.3, the default when supplying no explicit KEX, cipher or HMAC algorithms to `xsd` results in *no* algs being accepted; so the admin must decide on a specific whitelist of algorithms.
|
||||
***
|
||||
|
||||
|
||||
### Conn
|
||||
|
@ -79,7 +54,8 @@ Packets are subject to padding (random size, randomly applied as prefix or postf
|
|||
Chaffing and tunnels, if specified, are set up during initial client->server connection. Packets from the client local port(s) are sent through the main secured connection to the server's remote port(s), and vice versa, tagged with a chaff or tunnel specifier so that they can be discarded as chaff or de-multiplexed and delivered to the proper tunnel endpoints, respectively.
|
||||
|
||||
### Accounts and Passwords
|
||||
Within the ```xspasswd/``` directory is a password-setting utility, ```xspasswd```, used if one wishes ```xs``` access to use separate credentials from those of the default (likely ssh) login method. In this mode, ```xsd``` uses its own password file distinct from the system /etc/passwd to authenticate clients, using standard bcrypt+salt storage. Activate this mode by invoking ```xsd``` with ```-s false```.
|
||||
Within the xspasswd/ directory is a password-setting utility. XS uses its own password file distinct from the system /etc/passwd to authenticate clients, using standard bcrypt+salt storage. This is currently done to allow alternate login credentials via xs vs. console/ssh login, due to the experimental nature of the program. At some point in the future an option to use the system's /etc/passwd and /etc/shadow may be implemented, making the use of the auxilliary xspasswd utility optional or obsolete.
|
||||
|
||||
|
||||
HERRADURA KEX
|
||||
|
||||
|
@ -94,40 +70,41 @@ KYBER IND-CCA-2 KEM
|
|||
|
||||
As of this time (Oct 2018) Kyber is one of the candidate algorithms submitted to the [NIST post-quantum cryptography project](https://csrc.nist.gov/Projects/Post-Quantum-Cryptography). The authors recommend using it in "... so-called hybrid mode in combination with established "pre-quantum" security; for example in combination with elliptic-curve Diffie-Hellman." THIS PROJECT DOES NOT DO THIS (in case you didn't notice yet, THIS PROJECT IS EXPERIMENTAL.)
|
||||
|
||||
### Dependencies:
|
||||
|
||||
### Installing
|
||||
|
||||
As of Go 1.8, one can directly use `go install` to get the client `xs` and server `xsd` binaries; however it is not recommended, as `xsd` requires root and for general use should be in one of the system directories, akin to other daemons. If one insists, the following will work to place them in $HOME/go/bin:
|
||||
|
||||
```
|
||||
$ go install blitter.com/go/xs/xs@latest
|
||||
$ go install blitter.com/go/xs/xsd@latest
|
||||
```
|
||||
|
||||
(NOTE the `-v` (version) option for binaries obtained in this manner will be blank; another reason to build them yourself locally using the steps below.)
|
||||
|
||||
* Recent version of go (tested, at various times, with go-1.9 to go-1.12.4)
|
||||
* [github.com/mattn/go-isatty](http://github.com/mattn/go-isatty) //terminal tty detection
|
||||
* [github.com/kr/pty](http://github.com/kr/pty) //unix pty control (server pty connections)
|
||||
* [github.com/jameskeane/bcrypt](http://github.com/jameskeane/bcrypt) //password storage/auth
|
||||
* [blitter.com/go/goutmp](https://gogs.blitter.com/RLabs/goutmp) // wtmp/lastlog C bindings for user accounting
|
||||
* [https://git.schwanenlied.me/yawning/kyber](https://git.schwanenlied.me/yawning/kyber) // golang Kyber KEM
|
||||
* [https://git.schwanenlied.me/yawning/newhope](https://git.schwanenlied.me/yawning/newhope) // golang NEWHOPE,NEWHOPE-SIMPLE KEX
|
||||
* [blitter.com/go/mtwist](https://gogs.blitter.com/RLabs/mtwist) // 64-bit Mersenne Twister PRNG
|
||||
* [blitter.com/go/cryptmt](https://gogs.blitter.com/RLabs/cryptmt) // CryptMTv1 stream cipher
|
||||
|
||||
### Get source code
|
||||
|
||||
```
|
||||
$ git clone https://gogs.blitter.com/RLabs/xs
|
||||
$ go get -u blitter.com/go/xs
|
||||
$ cd $GOPATH/src/blitter.com/go/xs
|
||||
$ go build ./... # install all dependent go pkgs
|
||||
```
|
||||
|
||||
|
||||
### To build
|
||||
|
||||
```
|
||||
$ cd xs
|
||||
$ make clean && make
|
||||
$ cd $GOPATH/src/blitter.com/go/xs
|
||||
$ make clean all
|
||||
```
|
||||
|
||||
### To install, uninstall, re-install (xsd server)
|
||||
### To install, uninstall, re-install
|
||||
|
||||
```
|
||||
$ sudo make [install | uninstall | reinstall]
|
||||
```
|
||||
|
||||
### To manage service (openrc init)
|
||||
### To manage service (assuming openrc init)
|
||||
|
||||
An example init script (xsd.initrc) is provided. Consult your Linux distribution documentation for proper service/daemon installation. For openrc,
|
||||
|
||||
|
@ -136,23 +113,13 @@ $ sudo cp xsd.initrc /etc/init.d/xsd
|
|||
$ sudo rc-config add xsd default
|
||||
```
|
||||
|
||||
### To manage service (sysV init)
|
||||
|
||||
An example init script (xsd.sysvrc) is provided. Consult your Linux distribution documentation for proper service/daemon installation. For sysV init,
|
||||
|
||||
```
|
||||
$ sudo cp xsd.sysvrc /etc/init.d/xsd
|
||||
$ sudo sysv-rc-conf --level 2345 xsd on
|
||||
```
|
||||
|
||||
The make system assumes installation in /usr/local/sbin (xsd, xspasswd) and /usr/local/bin (xs/xc symlink).
|
||||
|
||||
```
|
||||
$ sudo rc-config [start | restart | stop] xsd
|
||||
# .. or sudo /etc/init.d/xsd [start | restart stop]
|
||||
```
|
||||
|
||||
### To set accounts & passwords (DEPRECATED: `-s` is now true by default)
|
||||
### To set accounts & passwords:
|
||||
|
||||
```
|
||||
$ sudo touch /etc/xs.passwd
|
||||
|
@ -187,18 +154,10 @@ 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/.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
|
||||
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
|
||||
should *not* be world-readable.)
|
||||
|
||||
```
|
||||
$ xs -g user@host.net >>~/.config/xs/.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
|
||||
|
||||
xc is a symlink to xs, and the binary checks its own filename to determine whether
|
||||
|
@ -224,21 +183,9 @@ xc uses a 'tarpipe' to send file data over the encrypted channel. Use the -d fla
|
|||
|
||||
NOTE: Renaming while copying (eg., 'cp /foo/bar/fileA ./fileB') is NOT supported. Put another way, the destination (whether local or remote) must ALWAYS be a directory.
|
||||
|
||||
If the 'pv' pipeview utility is available (http://www.ivarch.com/programs/pv.shtml) file transfer progress and bandwidth control will be available (suppress the former with the -q option, set the latter with -L <bytes_per_second>).
|
||||
|
||||
Special care should be taken when doing client → server copies: since the tarpipe (should) always succeed at least sending data to the remote side, a destination with no write permission will not return a nonzero status and the client closes its end after sending all data, giving the server no opportunity to send an error code to the client.
|
||||
It is recommended to test beforehand if the server-side destination is writable (and optionally if the destination already exists, if one does not want to clobber an existing path) by:
|
||||
|
||||
```
|
||||
$ xs -x "test -w /dest/path" me@myserver ## If clobbering /dest/path is OK, or
|
||||
$ xs -x "test -w /dest/path -o ! -e /dest/path" me@myserver ## To prevent clobbering
|
||||
```
|
||||
|
||||
Perhaps in future a more complex handshake will be devised to allow the client to half-close the tarpipe, allowing the server to complete its side of the operation and send back its success or failure code, but the current connection protocol does not allow this. If this is a deal-breaking feature, please contact the maintainer.
|
||||
|
||||
### Tunnels
|
||||
|
||||
Simple tunnels (client → server, no reverse tunnels for now) are supported.
|
||||
Simple tunnels (client -> server, no reverse tunnels for now) are supported.
|
||||
|
||||
Syntax: xs -T=<tunspec>{,<tunspec>...}
|
||||
.. where <tunspec> is <localport:remoteport>
|
||||
|
@ -249,9 +196,3 @@ Example, tunnelling ssh through xs
|
|||
* [client side, term A] ```$ xs -T=6002:7002 user@server```
|
||||
* [client side, term B] ```$ ssh user@localhost -p 6002```
|
||||
|
||||
|
||||
### Building for FreeBSD
|
||||
|
||||
The Makefile(s) to build require GNU make (gmake).
|
||||
Please install and invoke build via:
|
||||
```$ gmake clean all```
|
||||
|
|
103
auth.go
103
auth.go
|
@ -2,7 +2,7 @@ package xs
|
|||
|
||||
// Package xs - a secure terminal client/server written from scratch in Go
|
||||
//
|
||||
// Copyright (c) 2017-2020 Russell Magee
|
||||
// Copyright (c) 2017-2019 Russell Magee
|
||||
// Licensed under the terms of the MIT license (see LICENSE.mit in this
|
||||
// distribution)
|
||||
//
|
||||
|
@ -18,44 +18,20 @@ import (
|
|||
"io"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"os"
|
||||
"os/user"
|
||||
"runtime"
|
||||
"strings"
|
||||
|
||||
"blitter.com/go/xs/xsnet"
|
||||
"github.com/jameskeane/bcrypt"
|
||||
passlib "gopkg.in/hlandau/passlib.v1"
|
||||
)
|
||||
|
||||
type AuthCtx struct {
|
||||
reader func(string) ([]byte, error) // eg. ioutil.ReadFile()
|
||||
userlookup func(string) (*user.User, error) // eg. os/user.Lookup()
|
||||
}
|
||||
|
||||
func NewAuthCtx( /*reader func(string) ([]byte, error), userlookup func(string) (*user.User, error)*/ ) (ret *AuthCtx) {
|
||||
ret = &AuthCtx{ioutil.ReadFile, user.Lookup}
|
||||
return
|
||||
}
|
||||
|
||||
// --------- System passwd/shadow auth routine(s) --------------
|
||||
|
||||
// VerifyPass verifies a password against system standard shadow file
|
||||
// Verify a password against system standard shadow file
|
||||
// Note auxilliary fields for expiry policy are *not* inspected.
|
||||
func VerifyPass(ctx *AuthCtx, user, password string) (bool, error) {
|
||||
if ctx.reader == nil {
|
||||
ctx.reader = ioutil.ReadFile // dependency injection hides that this is required
|
||||
}
|
||||
func VerifyPass(user, password string) (bool, error) {
|
||||
passlib.UseDefaults(passlib.Defaults20180601)
|
||||
var pwFileName string
|
||||
if runtime.GOOS == "linux" {
|
||||
pwFileName = "/etc/shadow"
|
||||
} else if runtime.GOOS == "freebsd" {
|
||||
pwFileName = "/etc/master.passwd"
|
||||
} else {
|
||||
return false, errors.New("Unsupported platform")
|
||||
}
|
||||
pwFileData, e := ctx.reader(pwFileName)
|
||||
pwFileData, e := ioutil.ReadFile("/etc/shadow")
|
||||
if e != nil {
|
||||
return false, e
|
||||
}
|
||||
|
@ -94,14 +70,8 @@ func VerifyPass(ctx *AuthCtx, user, password string) (bool, error) {
|
|||
// This checks /etc/xs.passwd for auth info, and system /etc/passwd
|
||||
// to cross-check the user actually exists.
|
||||
// nolint: gocyclo
|
||||
func AuthUserByPasswd(ctx *AuthCtx, username string, auth string, fname string) (valid bool, allowedCmds string) {
|
||||
if ctx.reader == nil {
|
||||
ctx.reader = ioutil.ReadFile // dependency injection hides that this is required
|
||||
}
|
||||
if ctx.userlookup == nil {
|
||||
ctx.userlookup = user.Lookup // again for dependency injection as dep is now hidden
|
||||
}
|
||||
b, e := ctx.reader(fname) // nolint: gosec
|
||||
func AuthUserByPasswd(username string, auth string, fname string) (valid bool, allowedCmds string) {
|
||||
b, e := ioutil.ReadFile(fname) // nolint: gosec
|
||||
if e != nil {
|
||||
valid = false
|
||||
log.Printf("ERROR: Cannot read %s!\n", fname)
|
||||
|
@ -145,8 +115,7 @@ func AuthUserByPasswd(ctx *AuthCtx, username string, auth string, fname string)
|
|||
r = nil
|
||||
runtime.GC()
|
||||
|
||||
_, userErr := ctx.userlookup(username)
|
||||
if userErr != nil {
|
||||
if !userExistsOnSystem(username) {
|
||||
valid = false
|
||||
}
|
||||
return
|
||||
|
@ -154,28 +123,26 @@ func AuthUserByPasswd(ctx *AuthCtx, username string, auth string, fname string)
|
|||
|
||||
// ------------- End xs-local passwd auth routine(s) -----------
|
||||
|
||||
func userExistsOnSystem(who string) bool {
|
||||
_, userErr := user.Lookup(who)
|
||||
return userErr == nil
|
||||
}
|
||||
|
||||
// AuthUserByToken checks user login information against an auth token.
|
||||
// Auth tokens are stored in each user's $HOME/.config/xs/.xs_id and are requested
|
||||
// Auth tokens are stored in each user's $HOME/.xs_id and are requested
|
||||
// via the -g option.
|
||||
// The function also check system /etc/passwd to cross-check the user
|
||||
// actually exists.
|
||||
func AuthUserByToken(ctx *AuthCtx, username string, connhostname string, auth string) (valid bool) {
|
||||
if ctx.reader == nil {
|
||||
ctx.reader = ioutil.ReadFile // dependency injection hides that this is required
|
||||
}
|
||||
if ctx.userlookup == nil {
|
||||
ctx.userlookup = user.Lookup // again for dependency injection as dep is now hidden
|
||||
}
|
||||
|
||||
func AuthUserByToken(username string, connhostname string, auth string) (valid bool) {
|
||||
auth = strings.TrimSpace(auth)
|
||||
u, ue := ctx.userlookup(username)
|
||||
u, ue := user.Lookup(username)
|
||||
if ue != nil {
|
||||
return false
|
||||
}
|
||||
|
||||
b, e := ctx.reader(fmt.Sprintf("%s/%s", u.HomeDir, xsnet.XS_ID_AUTHTOKFILE))
|
||||
b, e := ioutil.ReadFile(fmt.Sprintf("%s/.xs_id", u.HomeDir))
|
||||
if e != nil {
|
||||
log.Printf("INFO: Cannot read %s/%s\n", u.HomeDir, xsnet.XS_ID_AUTHTOKFILE)
|
||||
log.Printf("INFO: Cannot read %s/.xs_id\n", u.HomeDir)
|
||||
return false
|
||||
}
|
||||
|
||||
|
@ -183,53 +150,25 @@ func AuthUserByToken(ctx *AuthCtx, username string, connhostname string, auth st
|
|||
|
||||
r.Comma = ':'
|
||||
r.Comment = '#'
|
||||
r.FieldsPerRecord = 3 // connhost:username:authtoken
|
||||
r.FieldsPerRecord = 2 // connhost:authtoken
|
||||
for {
|
||||
record, err := r.Read()
|
||||
if err == io.EOF {
|
||||
return false
|
||||
}
|
||||
if len(record) < 3 ||
|
||||
len(record[0]) < 1 ||
|
||||
len(record[1]) < 1 ||
|
||||
len(record[2]) < 1 {
|
||||
return false
|
||||
}
|
||||
record[0] = strings.TrimSpace(record[0])
|
||||
record[1] = strings.TrimSpace(record[1])
|
||||
record[2] = strings.TrimSpace(record[2])
|
||||
//fmt.Println("auth:", auth, "record:",
|
||||
// strings.Join([]string{record[0], record[1], record[2]}, ":"))
|
||||
// strings.Join([]string{record[0], record[1]}, ":"))
|
||||
|
||||
if (connhostname == record[0]) &&
|
||||
username == record[1] &&
|
||||
(auth == strings.Join([]string{record[0], record[1], record[2]}, ":")) {
|
||||
(auth == strings.Join([]string{record[0], record[1]}, ":")) {
|
||||
valid = true
|
||||
break
|
||||
}
|
||||
}
|
||||
_, userErr := ctx.userlookup(username)
|
||||
if userErr != nil {
|
||||
if !userExistsOnSystem(username) {
|
||||
valid = false
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func GetTool(tool string) (ret string) {
|
||||
ret = "/bin/" + tool
|
||||
_, err := os.Stat(ret)
|
||||
if err == nil {
|
||||
return ret
|
||||
}
|
||||
ret = "/usr/bin/" + tool
|
||||
_, err = os.Stat(ret)
|
||||
if err == nil {
|
||||
return ret
|
||||
}
|
||||
ret = "/usr/local/bin/" + tool
|
||||
_, err = os.Stat(ret)
|
||||
if err == nil {
|
||||
return ret
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
|
212
auth_test.go
212
auth_test.go
|
@ -1,212 +0,0 @@
|
|||
package xs
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"os/user"
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
type userVerifs struct {
|
||||
user string
|
||||
passwd string
|
||||
good bool
|
||||
}
|
||||
|
||||
var (
|
||||
dummyShadowA = `johndoe:$6$EeQlTtn/KXdSh6CW$UHbFuEw3UA0Jg9/GoPHxgWk6Ws31x3IjqsP22a9pVMOte0yQwX1.K34oI4FACu8GRg9DArJ5RyWUE9m98qwzZ1:18310:0:99999:7:::
|
||||
joebloggs:$6$F.0IXOrb0w0VJHG1$3O4PYyng7F3hlh42mbroEdQZvslybY5etPPiLMQJ1xosjABY.Q4xqAfyIfe03Du61ZjGQIt3nL0j12P9k1fsK/:18310:0:99999:7:::
|
||||
disableduser:!:18310::::::`
|
||||
|
||||
dummyAuthTokenFile = "hostA:johndoe:abcdefg\nhostB:imposter:wxyz\n"
|
||||
|
||||
dummyXsPasswdFile = `#username:salt:authCookie
|
||||
bobdobbs:$2a$12$9vqGkFqikspe/2dTARqu1O:$2a$12$9vqGkFqikspe/2dTARqu1OuDKCQ/RYWsnaFjmi.HtmECRkxcZ.kBK
|
||||
notbob:$2a$12$cZpiYaq5U998cOkXzRKdyu:$2a$12$cZpiYaq5U998cOkXzRKdyuJ2FoEQyVLa3QkYdPQk74VXMoAzhvuP6
|
||||
`
|
||||
|
||||
testGoodUsers = []userVerifs{
|
||||
{"johndoe", "testpass", true},
|
||||
{"joebloggs", "testpass2", true},
|
||||
{"johndoe", "badpass", false},
|
||||
}
|
||||
|
||||
testXsPasswdUsers = []userVerifs{
|
||||
{"bobdobbs", "praisebob", true},
|
||||
{"notbob", "imposter", false},
|
||||
}
|
||||
|
||||
userlookup_arg_u string
|
||||
readfile_arg_f string
|
||||
)
|
||||
|
||||
func newMockAuthCtx(reader func(string) ([]byte, error), userlookup func(string) (*user.User, error)) (ret *AuthCtx) {
|
||||
ret = &AuthCtx{reader, userlookup}
|
||||
return
|
||||
}
|
||||
|
||||
func _mock_user_Lookup(username string) (*user.User, error) {
|
||||
username = userlookup_arg_u
|
||||
if username == "baduser" {
|
||||
return &user.User{}, errors.New("bad user")
|
||||
}
|
||||
urec := &user.User{Uid: "1000", Gid: "1000", Username: username, Name: "Full Name", HomeDir: "/home/user"}
|
||||
fmt.Printf(" [mock user rec:%v]\n", urec)
|
||||
return urec, nil
|
||||
}
|
||||
|
||||
func _mock_ioutil_ReadFile(f string) ([]byte, error) {
|
||||
f = readfile_arg_f
|
||||
if f == "/etc/shadow" {
|
||||
fmt.Println(" [mocking ReadFile(\"/etc/shadow\")]")
|
||||
return []byte(dummyShadowA), nil
|
||||
}
|
||||
if f == "/etc/xs.passwd" {
|
||||
fmt.Println(" [mocking ReadFile(\"/etc/xs.passwd\")]")
|
||||
return []byte(dummyXsPasswdFile), nil
|
||||
}
|
||||
if strings.Contains(f, "/.xs_id") {
|
||||
fmt.Println(" [mocking ReadFile(\".xs_id\")]")
|
||||
return []byte(dummyAuthTokenFile), nil
|
||||
}
|
||||
return []byte{}, errors.New("no readfile_arg_f supplied")
|
||||
}
|
||||
|
||||
func _mock_ioutil_ReadFileEmpty(f string) ([]byte, error) {
|
||||
return []byte{}, nil
|
||||
}
|
||||
|
||||
func _mock_ioutil_ReadFileHasError(f string) ([]byte, error) {
|
||||
return []byte{}, errors.New("IO Error")
|
||||
}
|
||||
|
||||
func TestVerifyPass(t *testing.T) {
|
||||
readfile_arg_f = "/etc/shadow"
|
||||
ctx := newMockAuthCtx(_mock_ioutil_ReadFile, nil)
|
||||
for idx, rec := range testGoodUsers {
|
||||
stat, e := VerifyPass(ctx, rec.user, rec.passwd)
|
||||
if rec.good && (!stat || e != nil) {
|
||||
t.Fatalf("failed %d\n", idx)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestVerifyPassFailsOnEmptyFile(t *testing.T) {
|
||||
ctx := newMockAuthCtx(_mock_ioutil_ReadFileEmpty, nil)
|
||||
stat, e := VerifyPass(ctx, "johndoe", "somepass")
|
||||
if stat || (e == nil) {
|
||||
t.Fatal("failed to fail w/empty file")
|
||||
}
|
||||
}
|
||||
|
||||
func TestVerifyPassFailsOnFileError(t *testing.T) {
|
||||
ctx := newMockAuthCtx(_mock_ioutil_ReadFileEmpty, nil)
|
||||
stat, e := VerifyPass(ctx, "johndoe", "somepass")
|
||||
if stat || (e == nil) {
|
||||
t.Fatal("failed to fail on ioutil.ReadFile error")
|
||||
}
|
||||
}
|
||||
|
||||
func TestVerifyPassFailsOnDisabledEntry(t *testing.T) {
|
||||
ctx := newMockAuthCtx(_mock_ioutil_ReadFileEmpty, nil)
|
||||
stat, e := VerifyPass(ctx, "disableduser", "!")
|
||||
if stat || (e == nil) {
|
||||
t.Fatal("failed to fail on disabled user entry")
|
||||
}
|
||||
}
|
||||
|
||||
////
|
||||
|
||||
func TestAuthUserByTokenFailsOnMissingEntryForHost(t *testing.T) {
|
||||
ctx := newMockAuthCtx(_mock_ioutil_ReadFile, _mock_user_Lookup)
|
||||
stat := AuthUserByToken(ctx, "johndoe", "hostZ", "abcdefg")
|
||||
if stat {
|
||||
t.Fatal("failed to fail on missing/mismatched host entry")
|
||||
}
|
||||
}
|
||||
|
||||
func TestAuthUserByTokenFailsOnMissingEntryForUser(t *testing.T) {
|
||||
ctx := newMockAuthCtx(_mock_ioutil_ReadFile, _mock_user_Lookup)
|
||||
stat := AuthUserByToken(ctx, "unkuser", "hostA", "abcdefg")
|
||||
if stat {
|
||||
t.Fatal("failed to fail on wrong user")
|
||||
}
|
||||
}
|
||||
|
||||
func TestAuthUserByTokenFailsOnUserLookupFailure(t *testing.T) {
|
||||
ctx := newMockAuthCtx(_mock_ioutil_ReadFile, _mock_user_Lookup)
|
||||
userlookup_arg_u = "baduser"
|
||||
stat := AuthUserByToken(ctx, "johndoe", "hostA", "abcdefg")
|
||||
if stat {
|
||||
t.Fatal("failed to fail with bad return from user.Lookup()")
|
||||
}
|
||||
}
|
||||
|
||||
func TestAuthUserByTokenFailsOnMismatchedTokenForUser(t *testing.T) {
|
||||
ctx := newMockAuthCtx(_mock_ioutil_ReadFile, _mock_user_Lookup)
|
||||
stat := AuthUserByToken(ctx, "johndoe", "hostA", "badtoken")
|
||||
if stat {
|
||||
t.Fatal("failed to fail with valid user, bad token")
|
||||
}
|
||||
}
|
||||
|
||||
func TestAuthUserByTokenSucceedsWithMatchedUserAndToken(t *testing.T) {
|
||||
ctx := newMockAuthCtx(_mock_ioutil_ReadFile, _mock_user_Lookup)
|
||||
userlookup_arg_u = "johndoe"
|
||||
readfile_arg_f = "/.xs_id"
|
||||
stat := AuthUserByToken(ctx, userlookup_arg_u, "hostA", "hostA:johndoe:abcdefg")
|
||||
if !stat {
|
||||
t.Fatal("failed with valid user and token")
|
||||
}
|
||||
}
|
||||
|
||||
func TestAuthUserByPasswdFailsOnEmptyFile(t *testing.T) {
|
||||
ctx := newMockAuthCtx(_mock_ioutil_ReadFileEmpty, _mock_user_Lookup)
|
||||
userlookup_arg_u = "bobdobbs"
|
||||
readfile_arg_f = "/etc/xs.passwd"
|
||||
stat, _ := AuthUserByPasswd(ctx, userlookup_arg_u, "praisebob", readfile_arg_f)
|
||||
if stat {
|
||||
t.Fatal("failed to fail with missing xs.passwd file")
|
||||
}
|
||||
}
|
||||
|
||||
func TestAuthUserByPasswdFailsOnBadAuth(t *testing.T) {
|
||||
ctx := newMockAuthCtx(_mock_ioutil_ReadFile, _mock_user_Lookup)
|
||||
userlookup_arg_u = "bobdobbs"
|
||||
readfile_arg_f = "/etc/xs.passwd"
|
||||
stat, _ := AuthUserByPasswd(ctx, userlookup_arg_u, "wrongpass", readfile_arg_f)
|
||||
if stat {
|
||||
t.Fatal("failed to fail with valid user, incorrect passwd in xs.passwd file")
|
||||
}
|
||||
}
|
||||
|
||||
func TestAuthUserByPasswdFailsOnBadUser(t *testing.T) {
|
||||
ctx := newMockAuthCtx(_mock_ioutil_ReadFile, _mock_user_Lookup)
|
||||
userlookup_arg_u = "bobdobbs"
|
||||
readfile_arg_f = "/etc/xs.passwd"
|
||||
stat, _ := AuthUserByPasswd(ctx, userlookup_arg_u, "theotherbob", readfile_arg_f)
|
||||
if stat {
|
||||
t.Fatal("failed to fail on invalid user vs. xs.passwd file")
|
||||
}
|
||||
}
|
||||
|
||||
func TestAuthUserByPasswdPassesOnGoodAuth(t *testing.T) {
|
||||
ctx := newMockAuthCtx(_mock_ioutil_ReadFile, _mock_user_Lookup)
|
||||
userlookup_arg_u = "bobdobbs"
|
||||
readfile_arg_f = "/etc/xs.passwd"
|
||||
stat, _ := AuthUserByPasswd(ctx, userlookup_arg_u, "praisebob", readfile_arg_f)
|
||||
if !stat {
|
||||
t.Fatal("failed on valid user w/correct passwd in xs.passwd file")
|
||||
}
|
||||
}
|
||||
|
||||
func TestAuthUserByPasswdPassesOnOtherGoodAuth(t *testing.T) {
|
||||
ctx := newMockAuthCtx(_mock_ioutil_ReadFile, _mock_user_Lookup)
|
||||
userlookup_arg_u = "notbob"
|
||||
readfile_arg_f = "/etc/xs.passwd"
|
||||
stat, _ := AuthUserByPasswd(ctx, userlookup_arg_u, "imposter", readfile_arg_f)
|
||||
if !stat {
|
||||
t.Fatal("failed on valid user 2nd entry w/correct passwd in xs.passwd file")
|
||||
}
|
||||
}
|
|
@ -1,114 +0,0 @@
|
|||
#!/bin/bash
|
||||
#
|
||||
## bacillus (https://gogs.blitter.com/Russtopia/bacillus) build/test CI script
|
||||
|
||||
export GOPATH="${HOME}/go"
|
||||
export PATH=/usr/local/bin:/usr/bin:/usr/lib/ccache/bin:/bin:$GOPATH/bin
|
||||
unset GO111MODULE
|
||||
#export GOPROXY="direct"
|
||||
#!# GOCACHE will be phased out in v1.12. [github.com/golang/go/issues/26809]
|
||||
#!export GOCACHE="${HOME}/.cache/go-build"
|
||||
|
||||
echo "workdir: ${BACILLUS_WORKDIR}"
|
||||
mkdir -p "${BACILLUS_ARTFDIR}"
|
||||
|
||||
echo "---"
|
||||
go env
|
||||
echo "---"
|
||||
echo "passed env:"
|
||||
env
|
||||
echo "---"
|
||||
|
||||
cd ${REPO}
|
||||
branch=$(git for-each-ref --sort=-committerdate --format='%(refname)' | head -n 1)
|
||||
echo "Building most recent push on branch $branch"
|
||||
git checkout "$branch"
|
||||
ls
|
||||
|
||||
go mod init
|
||||
go mod tidy
|
||||
|
||||
############
|
||||
stage "Build"
|
||||
############
|
||||
echo "Invoking 'make clean' ..."
|
||||
make clean
|
||||
echo "Invoking 'make all' ..."
|
||||
make all
|
||||
|
||||
############
|
||||
stage "Lint"
|
||||
############
|
||||
make lint
|
||||
|
||||
############
|
||||
stage "UnitTests"
|
||||
############
|
||||
go test -v .
|
||||
|
||||
############
|
||||
stage "Test(Authtoken)"
|
||||
############
|
||||
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" >~/.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
|
||||
echo "AUTHTOKEN LOGIN FAILED"
|
||||
exit 1
|
||||
else
|
||||
echo "client cmd performed OK."
|
||||
unset tokentest
|
||||
fi
|
||||
|
||||
############
|
||||
stage "Test(xc S->C)"
|
||||
############
|
||||
echo "Testing secure copy from server -> client ..."
|
||||
./xc_testfiles.sh
|
||||
|
||||
tmpdir=$$
|
||||
mkdir -p /tmp/$tmpdir
|
||||
cd /tmp/$tmpdir
|
||||
xc @localhost:${BACILLUS_WORKDIR}/build/xs/cptest .
|
||||
echo -n "Integrity check on copied files (sha1sum) ..."
|
||||
sha1sum $(find cptest -type f | sort) >sc.sha1sum
|
||||
diff sc.sha1sum ${BACILLUS_WORKDIR}/build/xs/cptest.sha1sum
|
||||
stat=$?
|
||||
cd -
|
||||
|
||||
rm -rf /tmp/$tmpdir
|
||||
if [ $stat -eq "0" ]; then
|
||||
echo "OK."
|
||||
else
|
||||
echo "FAILED!"
|
||||
exit $stat
|
||||
fi
|
||||
|
||||
############
|
||||
stage "Test(xc C->S)"
|
||||
############
|
||||
echo "TODO ..."
|
||||
|
||||
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
|
||||
|
||||
############
|
||||
stage "Artifacts"
|
||||
############
|
||||
echo -n "Creating tarfile ..."
|
||||
tar -cz --exclude=.git --exclude=cptest -f ${BACILLUS_ARTFDIR}/xs.tgz .
|
||||
|
||||
############
|
||||
stage "Cleanup"
|
||||
############
|
||||
rm -rf cptest
|
||||
|
||||
echo
|
||||
echo "--Done--"
|
|
@ -1,6 +1,6 @@
|
|||
// Package xs - a secure terminal client/server written from scratch in Go
|
||||
//
|
||||
// Copyright (c) 2017-2020 Russell Magee
|
||||
// Copyright (c) 2017-2019 Russell Magee
|
||||
// Licensed under the terms of the MIT license (see LICENSE.mit in this
|
||||
// distribution)
|
||||
//
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
6010a446cdcf8c1203c2d08998cc69a8c88f77d5 cptest/file16KB
|
||||
f086ea96f3718efd78e6791178f967585acb3701 cptest/file1KB
|
||||
6061e16c3d3840712d0b8e5268c49b5c2f8137ac cptest/file32KB
|
||||
490af32035bbe737480f06439a02d91a171ac407 cptest/file6B
|
||||
e4a8a4ad9678b7265a28c5f0cb5b078e1049ea23 cptest/subdir/file32MB
|
||||
82b50550c7d0e0d6ac18d9d0796b6814c3e038bf cptest/subdir/file64MB
|
||||
306637b5c621892078ebadd9454a78820a000598 cptest/file16KB
|
||||
1a118dfff291352eb4aec02c34f4f957669460fc cptest/file1KB
|
||||
f474d5da45890b7cb5b0ae84c8ade5abcb3b4474 cptest/file32KB
|
||||
03939175ceac92b9c6464d037a0243e22563c423 cptest/file6B
|
||||
da67c7698b25d94c0cc20284ba9d4008cdee201b cptest/subdir/file32MB
|
||||
9da9888265371375b48c224b94a0b3132b7ddc41 cptest/subdir/file64MB
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
module blitter.com/go/xs
|
||||
|
||||
go 1.12
|
||||
|
||||
require (
|
||||
blitter.com/go/cryptmt v1.0.0
|
||||
blitter.com/go/goutmp v1.0.1
|
||||
blitter.com/go/herradurakex v1.0.0
|
||||
blitter.com/go/mtwist v1.0.1 // indirect
|
||||
blitter.com/go/wanderer v0.8.0
|
||||
git.schwanenlied.me/yawning/chacha20.git v0.0.0-20170904085104-e3b1f968fc63 // indirect
|
||||
git.schwanenlied.me/yawning/kyber.git v0.0.0-20180530164001-a270899bd22c
|
||||
git.schwanenlied.me/yawning/newhope.git v0.0.0-20170622154529-9598792ba8f2
|
||||
github.com/jameskeane/bcrypt v0.0.0-20120420032655-c3cd44c1e20f
|
||||
github.com/klauspost/cpuid v1.2.2 // indirect
|
||||
github.com/klauspost/reedsolomon v1.9.3 // indirect
|
||||
github.com/kr/pty v1.1.4
|
||||
github.com/mattn/go-isatty v0.0.7
|
||||
github.com/pkg/errors v0.8.1 // indirect
|
||||
github.com/templexxx/cpufeat v0.0.0-20180724012125-cef66df7f161 // indirect
|
||||
github.com/templexxx/xor v0.0.0-20181023030647-4e92f724b73b // indirect
|
||||
github.com/tjfoc/gmsm v1.0.1 // indirect
|
||||
github.com/xtaci/kcp-go v5.4.19+incompatible
|
||||
golang.org/x/crypto v0.0.0-20190417174047-f416ebab96af
|
||||
golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553 // indirect
|
||||
golang.org/x/sys v0.0.0-20190416152802-12500544f89f
|
||||
gopkg.in/hlandau/easymetric.v1 v1.0.0 // indirect
|
||||
gopkg.in/hlandau/measurable.v1 v1.0.1 // indirect
|
||||
gopkg.in/hlandau/passlib.v1 v1.0.10
|
||||
)
|
|
@ -0,0 +1,53 @@
|
|||
blitter.com/go/cryptmt v1.0.0 h1:n+cNP/ReZrNe/w5FbD8DSfv0Wpj48nxhmMoLEk4hPXs=
|
||||
blitter.com/go/cryptmt v1.0.0/go.mod h1:tdME2J3O4agaDAYIYNQzzuB28yVGnPSMmV3a/ucSU84=
|
||||
blitter.com/go/goutmp v1.0.1 h1:jBqtp6pDwSbF4QEC3DjNfyaS8Nv5dFCOyaTfSbbb7TU=
|
||||
blitter.com/go/goutmp v1.0.1/go.mod h1:gtlbjC8xGzMk/Cf0BpnVltSa3awOqJ+B5WAxVptTMxk=
|
||||
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/mtwist v1.0.0 h1:/Vg6k12+DC+fokeRrLApL22hZS/EqEazJTo/FDdbDog=
|
||||
blitter.com/go/mtwist v1.0.0/go.mod h1:aU82Nx8+b1v8oZRNqImfEDzDTPim81rY0ACKAIclV18=
|
||||
blitter.com/go/mtwist v1.0.1 h1:PxmoWexfMpLmc8neHP/PcRc3s17ct7iz4d5W/qJVt04=
|
||||
blitter.com/go/mtwist v1.0.1/go.mod h1:aU82Nx8+b1v8oZRNqImfEDzDTPim81rY0ACKAIclV18=
|
||||
blitter.com/go/wanderer v0.8.0 h1:xT7lKdKLSyonVf0vZW6R46E3gz3B5pJ1VDBlsa4ULDI=
|
||||
blitter.com/go/wanderer v0.8.0/go.mod h1:FX1pAnZ5woEavy5CUIZco0/Gc2Msb3U0zsmi+6Hs4Rw=
|
||||
git.schwanenlied.me/yawning/chacha20.git v0.0.0-20170904085104-e3b1f968fc63 h1:bwZNsbw3qFbg6ox55HrA37nPmh+/wtJxZ7uWeiAdUUc=
|
||||
git.schwanenlied.me/yawning/chacha20.git v0.0.0-20170904085104-e3b1f968fc63/go.mod h1:NYi4Ifd1g/YbhIDgDfw6t7QdsW4tofQWMX/+FiDtJWs=
|
||||
git.schwanenlied.me/yawning/kyber.git v0.0.0-20180530164001-a270899bd22c/go.mod h1:QrbgzU5EL/1jaMD5pD4Tiikj3R5elPMa+RMwFUTGwQU=
|
||||
git.schwanenlied.me/yawning/newhope.git v0.0.0-20170622154529-9598792ba8f2 h1:89TYv/+wotJ+QWrH5B/yN0pEQutr2V/5za0VoYiVGCM=
|
||||
git.schwanenlied.me/yawning/newhope.git v0.0.0-20170622154529-9598792ba8f2/go.mod h1:weMqACFGzJs4Ni+K9shsRd02N4LkDrtGlkRxISK+II0=
|
||||
github.com/jameskeane/bcrypt v0.0.0-20120420032655-c3cd44c1e20f/go.mod h1:u+9Snq0w+ZdYKi8BBoaxnEwWu0fY4Kvu9ByFpM51t1s=
|
||||
github.com/klauspost/cpuid v1.2.2 h1:1xAgYebNnsb9LKCdLOvFWtAxGU/33mjJtyOVbmUa0Us=
|
||||
github.com/klauspost/cpuid v1.2.2/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek=
|
||||
github.com/klauspost/reedsolomon v1.9.3 h1:N/VzgeMfHmLc+KHMD1UL/tNkfXAt8FnUqlgXGIduwAY=
|
||||
github.com/klauspost/reedsolomon v1.9.3/go.mod h1:CwCi+NUr9pqSVktrkN+Ondf06rkhYZ/pcNv7fu+8Un4=
|
||||
github.com/kr/pty v1.1.4 h1:5Myjjh3JY/NaAi4IsUbHADytDyl1VE1Y9PXDlL+P/VQ=
|
||||
github.com/kr/pty v1.1.4/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/mattn/go-isatty v0.0.7 h1:UvyT9uN+3r7yLEYSlJsbQGdsaB/a0DlgWP3pql6iwOc=
|
||||
github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
|
||||
github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
|
||||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/templexxx/cpufeat v0.0.0-20180724012125-cef66df7f161 h1:89CEmDvlq/F7SJEOqkIdNDGJXrQIhuIx9D2DBXjavSU=
|
||||
github.com/templexxx/cpufeat v0.0.0-20180724012125-cef66df7f161/go.mod h1:wM7WEvslTq+iOEAMDLSzhVuOt5BRZ05WirO+b09GHQU=
|
||||
github.com/templexxx/xor v0.0.0-20181023030647-4e92f724b73b h1:mnG1fcsIB1d/3vbkBak2MM0u+vhGhlQwpeimUi7QncM=
|
||||
github.com/templexxx/xor v0.0.0-20181023030647-4e92f724b73b/go.mod h1:5XA7W9S6mni3h5uvOC75dA3m9CCCaS83lltmc0ukdi4=
|
||||
github.com/tjfoc/gmsm v1.0.1 h1:R11HlqhXkDospckjZEihx9SW/2VW0RgdwrykyWMFOQU=
|
||||
github.com/tjfoc/gmsm v1.0.1/go.mod h1:XxO4hdhhrzAd+G4CjDqaOkd0hUzmtPR/d3EiBBMn/wc=
|
||||
github.com/xtaci/kcp-go v5.4.19+incompatible h1:vv7Ar1D9WZGiv6deIOluxrC26Oin/2jFtx8sFU5tlvw=
|
||||
github.com/xtaci/kcp-go v5.4.19+incompatible/go.mod h1:bN6vIwHQbfHaHtFpEssmWsN45a+AZwO7eyRCmEIbtvE=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20190417174047-f416ebab96af h1:6qGQw30u837TXZbCmLFR9AVA+RjJU1LIbvk0oIkDZGY=
|
||||
golang.org/x/crypto v0.0.0-20190417174047-f416ebab96af/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE=
|
||||
golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553 h1:efeOvDhwQ29Dj3SdAV/MJf8oukgn+8D8WgaCaRMchF8=
|
||||
golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190403152447-81d4e9dc473e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190416152802-12500544f89f h1:1ZH9RnjNgLzh6YrsRp/c6ddZ8Lq0fq9xztNOoWJ2sz4=
|
||||
golang.org/x/sys v0.0.0-20190416152802-12500544f89f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
gopkg.in/hlandau/easymetric.v1 v1.0.0 h1:ZbfbH7W3giuVDjWUoFhDOjjv20hiPr5HZ2yMV5f9IeE=
|
||||
gopkg.in/hlandau/easymetric.v1 v1.0.0/go.mod h1:yh75hypuFzAxmvECh3ZKGCvFnIfapYJh2wv7ASaX2RE=
|
||||
gopkg.in/hlandau/measurable.v1 v1.0.1 h1:wH5UZKCRUnRr1iD+xIZfwhtxhmr+bprRJttqA1Rklf4=
|
||||
gopkg.in/hlandau/measurable.v1 v1.0.1/go.mod h1:6N+SYJGMTmetsx7wskULP+juuO+++tsHJkAgzvzsbuM=
|
||||
gopkg.in/hlandau/passlib.v1 v1.0.10 h1:q5xh9ZHp907XTjVw8/EqG03//fnlITnIYQmv4Gn7TpE=
|
||||
gopkg.in/hlandau/passlib.v1 v1.0.10/go.mod h1:wxGAv2CtQHlzWY8NJp+p045yl4WHyX7v2T6XbOcmqjM=
|
|
@ -2,14 +2,8 @@
|
|||
|
||||
EXE = $(notdir $(shell pwd))
|
||||
|
||||
ifeq ($(GARBLE),y)
|
||||
GO=garble -literals -tiny -debugdir=garbled
|
||||
else
|
||||
GO = go
|
||||
endif
|
||||
|
||||
all:
|
||||
$(GO) build .
|
||||
go build .
|
||||
|
||||
clean:
|
||||
$(RM) $(EXE) $(EXE).exe
|
||||
|
|
|
@ -1,156 +0,0 @@
|
|||
// +build freebsd
|
||||
|
||||
// Package logger is a wrapper around UNIX syslog, so that it also may
|
||||
// be wrapped with something else for Windows (Sadly, the stdlib log/syslog
|
||||
// is frozen, and there is no Windows implementation.)
|
||||
package logger
|
||||
|
||||
import (
|
||||
sl "log/syslog"
|
||||
)
|
||||
|
||||
// Priority is the logger priority
|
||||
type Priority = sl.Priority
|
||||
|
||||
// Writer is a syslog Writer
|
||||
type Writer = sl.Writer
|
||||
|
||||
// nolint: golint
|
||||
const (
|
||||
// Severity.
|
||||
|
||||
// From /usr/include/sys/syslog.h.
|
||||
// These are the same on Linux, BSD, and OS X.
|
||||
LOG_EMERG Priority = iota
|
||||
LOG_ALERT
|
||||
LOG_CRIT
|
||||
LOG_ERR
|
||||
LOG_WARNING
|
||||
LOG_NOTICE
|
||||
LOG_INFO
|
||||
LOG_DEBUG
|
||||
)
|
||||
|
||||
// nolint: golint
|
||||
const (
|
||||
// Facility.
|
||||
|
||||
// From /usr/include/sys/syslog.h.
|
||||
// These are the same up to LOG_FTP on Linux, BSD, and OS X.
|
||||
LOG_KERN Priority = iota << 3
|
||||
LOG_USER
|
||||
LOG_MAIL
|
||||
LOG_DAEMON
|
||||
LOG_AUTH
|
||||
LOG_SYSLOG
|
||||
LOG_LPR
|
||||
LOG_NEWS
|
||||
LOG_UUCP
|
||||
LOG_CRON
|
||||
LOG_AUTHPRIV
|
||||
LOG_FTP
|
||||
_ // unused
|
||||
_ // unused
|
||||
_ // unused
|
||||
_ // unused
|
||||
LOG_LOCAL0
|
||||
LOG_LOCAL1
|
||||
LOG_LOCAL2
|
||||
LOG_LOCAL3
|
||||
LOG_LOCAL4
|
||||
LOG_LOCAL5
|
||||
LOG_LOCAL6
|
||||
LOG_LOCAL7
|
||||
)
|
||||
|
||||
var (
|
||||
l *sl.Writer
|
||||
)
|
||||
|
||||
// New returns a new log Writer.
|
||||
func New(flags Priority, tag string) (w *Writer, e error) {
|
||||
w, e = sl.New(flags, tag)
|
||||
l = w
|
||||
return w, e
|
||||
}
|
||||
|
||||
// Alert returns a log Alert error
|
||||
func Alert(s string) error {
|
||||
if l != nil {
|
||||
return l.Alert(s)
|
||||
}
|
||||
return nil
|
||||
|
||||
}
|
||||
|
||||
// LogClose closes the log Writer.
|
||||
func LogClose() error {
|
||||
if l != nil {
|
||||
return l.Close()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// LogCrit returns a log Alert error
|
||||
func LogCrit(s string) error {
|
||||
if l != nil {
|
||||
return l.Crit(s)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// LogDebug returns a log Debug error
|
||||
func LogDebug(s string) error {
|
||||
if l != nil {
|
||||
return l.Debug(s)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// LogEmerg returns a log Emerg error
|
||||
func LogEmerg(s string) error {
|
||||
if l != nil {
|
||||
return l.Emerg(s)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// LogErr returns a log Err error
|
||||
func LogErr(s string) error {
|
||||
if l != nil {
|
||||
return l.Err(s)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// LogInfo returns a log Info error
|
||||
func LogInfo(s string) error {
|
||||
if l != nil {
|
||||
return l.Info(s)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// LogNotice returns a log Notice error
|
||||
func LogNotice(s string) error {
|
||||
if l != nil {
|
||||
return l.Notice(s)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// LogWarning returns a log Warning error
|
||||
func LogWarning(s string) error {
|
||||
if l != nil {
|
||||
return l.Warning(s)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// LogWrite writes to the logger at default level
|
||||
func LogWrite(b []byte) (int, error) {
|
||||
if l != nil {
|
||||
return l.Write(b)
|
||||
}
|
||||
return len(b),nil
|
||||
}
|
|
@ -11,7 +11,6 @@ import (
|
|||
|
||||
// Priority is the logger priority
|
||||
type Priority = sl.Priority
|
||||
|
||||
// Writer is a syslog Writer
|
||||
type Writer = sl.Writer
|
||||
|
||||
|
@ -76,81 +75,50 @@ func New(flags Priority, tag string) (w *Writer, e error) {
|
|||
|
||||
// Alert returns a log Alert error
|
||||
func Alert(s string) error {
|
||||
if l != nil {
|
||||
return l.Alert(s)
|
||||
}
|
||||
return nil
|
||||
|
||||
}
|
||||
|
||||
// LogClose closes the log Writer.
|
||||
func LogClose() error {
|
||||
if l != nil {
|
||||
return l.Close()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// LogCrit returns a log Alert error
|
||||
func LogCrit(s string) error {
|
||||
if l != nil {
|
||||
return l.Crit(s)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// LogDebug returns a log Debug error
|
||||
func LogDebug(s string) error {
|
||||
if l != nil {
|
||||
return l.Debug(s)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// LogEmerg returns a log Emerg error
|
||||
func LogEmerg(s string) error {
|
||||
if l != nil {
|
||||
return l.Emerg(s)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// LogErr returns a log Err error
|
||||
func LogErr(s string) error {
|
||||
if l != nil {
|
||||
return l.Err(s)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// LogInfo returns a log Info error
|
||||
func LogInfo(s string) error {
|
||||
if l != nil {
|
||||
return l.Info(s)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// LogNotice returns a log Notice error
|
||||
func LogNotice(s string) error {
|
||||
if l != nil {
|
||||
return l.Notice(s)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// LogWarning returns a log Warning error
|
||||
func LogWarning(s string) error {
|
||||
if l != nil {
|
||||
return l.Warning(s)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// LogWrite writes to the logger at default level
|
||||
func LogWrite(b []byte) (int, error) {
|
||||
if l != nil {
|
||||
return l.Write(b)
|
||||
}
|
||||
return len(b),nil
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
// +build windows
|
||||
|
||||
//
|
||||
// Wrapper around UNIX syslog, so that it also may be wrapped
|
||||
// with something else for Windows.
|
||||
package logger
|
||||
|
|
|
@ -2,7 +2,7 @@ package xs
|
|||
|
||||
// Package xs - a secure terminal client/server written from scratch in Go
|
||||
//
|
||||
// Copyright (c) 2017-2020 Russell Magee
|
||||
// Copyright (c) 2017-2019 Russell Magee
|
||||
// Licensed under the terms of the MIT license (see LICENSE.mit in this
|
||||
// distribution)
|
||||
//
|
||||
|
@ -96,7 +96,7 @@ func (h Session) AuthCookie(reallyShow bool) []byte {
|
|||
return []byte("**REDACTED**")
|
||||
}
|
||||
|
||||
// SetAuthCookie stores the authcookie (essentially the password) used to
|
||||
// SetAuthCookie stores the authcookie (essential the password) used to
|
||||
// authenticate the Session.
|
||||
func (h *Session) SetAuthCookie(a []byte) {
|
||||
h.authCookie = a
|
||||
|
|
|
@ -1,30 +0,0 @@
|
|||
package xs
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func _newMockSession() (s *Session) {
|
||||
s = &Session{op: []byte("A"),
|
||||
who: []byte("johndoe"),
|
||||
connhost: []byte("host"),
|
||||
termtype: []byte("vt100"),
|
||||
cmd: []byte("/bin/false"),
|
||||
authCookie: []byte("authcookie"),
|
||||
status: 0}
|
||||
return s
|
||||
}
|
||||
|
||||
func TestSessionAuthCookieShowTrue(t *testing.T) {
|
||||
sess := _newMockSession()
|
||||
if string(sess.AuthCookie(true)) != string(sess.authCookie) {
|
||||
t.Fatal("Failed to return unredacted authcookie on request")
|
||||
}
|
||||
}
|
||||
|
||||
func TestSessionAuthCookieShowFalse(t *testing.T) {
|
||||
sess := _newMockSession()
|
||||
if string(sess.AuthCookie(false)) != string("**REDACTED**") {
|
||||
t.Fatal("Failed to return redacted authcookie on request")
|
||||
}
|
||||
}
|
|
@ -1,18 +1,11 @@
|
|||
.PHONY: info clean lib
|
||||
|
||||
ifeq ($(GARBLE),y)
|
||||
GO = garble -literals -tiny -debugdir=garbled
|
||||
else
|
||||
GO = go
|
||||
endif
|
||||
|
||||
all: lib
|
||||
|
||||
clean:
|
||||
go clean .
|
||||
|
||||
lib: info
|
||||
$(GO) build .
|
||||
go install .
|
||||
|
||||
ifneq ($(MSYSTEM),)
|
||||
|
|
128
termmode_bsd.go
128
termmode_bsd.go
|
@ -1,128 +0,0 @@
|
|||
// +build freebsd
|
||||
|
||||
package xs
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"io"
|
||||
"unsafe"
|
||||
|
||||
unix "golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
/* -------------
|
||||
* minimal terminal APIs brought in from ssh/terminal
|
||||
* (they have no real business being there as they aren't specific to
|
||||
* ssh, but as of Go v1.10, late 2019, core go stdlib hasn't yet done
|
||||
* the planned terminal lib reorgs.)
|
||||
* ------------- */
|
||||
|
||||
// From github.com/golang/crypto/blob/master/ssh/terminal/util_linux.go
|
||||
const getTermios = unix.TIOCGETA
|
||||
const setTermios = unix.TIOCSETA
|
||||
|
||||
// From github.com/golang/crypto/blob/master/ssh/terminal/util.go
|
||||
|
||||
// State contains the state of a terminal.
|
||||
type State struct {
|
||||
termios unix.Termios
|
||||
}
|
||||
|
||||
// MakeRaw put the terminal connected to the given file descriptor into raw
|
||||
// mode and returns the previous state of the terminal so that it can be
|
||||
// restored.
|
||||
func MakeRaw(fd uintptr) (*State, error) {
|
||||
var oldState State
|
||||
if _, _, err := unix.Syscall(unix.SYS_IOCTL, fd, getTermios, uintptr(unsafe.Pointer(&oldState.termios))); err != 0 {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
newState := oldState.termios
|
||||
newState.Iflag &^= (unix.IGNBRK | unix.BRKINT | unix.PARMRK | unix.ISTRIP | unix.INLCR | unix.IGNCR | unix.ICRNL | unix.IXON)
|
||||
newState.Oflag &^= unix.OPOST
|
||||
newState.Lflag &^= (unix.ECHO | unix.ECHONL | unix.ICANON | unix.ISIG | unix.IEXTEN)
|
||||
newState.Cflag &^= (unix.CSIZE | unix.PARENB)
|
||||
newState.Cflag |= unix.CS8
|
||||
newState.Cc[unix.VMIN] = 1
|
||||
newState.Cc[unix.VTIME] = 0
|
||||
|
||||
if _, _, err := unix.Syscall(unix.SYS_IOCTL, fd, setTermios, uintptr(unsafe.Pointer(&newState))); err != 0 {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &oldState, nil
|
||||
}
|
||||
|
||||
// Restore restores the terminal connected to the given file descriptor to a
|
||||
// previous state.
|
||||
func Restore(fd uintptr, state *State) error {
|
||||
if state != nil {
|
||||
if _, _, err := unix.Syscall(unix.SYS_IOCTL, fd, setTermios, uintptr(unsafe.Pointer(state))); err != 0 {
|
||||
return err
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
} else {
|
||||
return errors.New("nil State")
|
||||
}
|
||||
}
|
||||
|
||||
// ReadPassword reads a line of input from a terminal without local echo. This
|
||||
// is commonly used for inputting passwords and other sensitive data. The slice
|
||||
// returned does not include the \n.
|
||||
func ReadPassword(fd uintptr) ([]byte, error) {
|
||||
var oldState State
|
||||
if _, _, err := unix.Syscall(unix.SYS_IOCTL, fd, getTermios, uintptr(unsafe.Pointer(&oldState.termios))); err != 0 {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
newState := oldState.termios
|
||||
newState.Lflag &^= unix.ECHO
|
||||
newState.Lflag |= unix.ICANON | unix.ISIG
|
||||
newState.Iflag |= unix.ICRNL
|
||||
if _, _, err := unix.Syscall(unix.SYS_IOCTL, fd, setTermios, uintptr(unsafe.Pointer(&newState))); err != 0 {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
defer func() {
|
||||
unix.Syscall(unix.SYS_IOCTL, fd, setTermios, uintptr(unsafe.Pointer(&oldState.termios)))
|
||||
}()
|
||||
|
||||
return readPasswordLine(passwordReader(fd))
|
||||
}
|
||||
|
||||
// passwordReader is an io.Reader that reads from a specific file descriptor.
|
||||
type passwordReader int
|
||||
|
||||
func (r passwordReader) Read(buf []byte) (int, error) {
|
||||
return unix.Read(int(r), buf)
|
||||
}
|
||||
|
||||
// readPasswordLine reads from reader until it finds \n or io.EOF.
|
||||
// The slice returned does not include the \n.
|
||||
// readPasswordLine also ignores any \r it finds.
|
||||
func readPasswordLine(reader io.Reader) ([]byte, error) {
|
||||
var buf [1]byte
|
||||
var ret []byte
|
||||
|
||||
for {
|
||||
n, err := reader.Read(buf[:])
|
||||
if n > 0 {
|
||||
switch buf[0] {
|
||||
case '\n':
|
||||
return ret, nil
|
||||
case '\r':
|
||||
// remove \r from passwords on Windows
|
||||
default:
|
||||
ret = append(ret, buf[0])
|
||||
}
|
||||
continue
|
||||
}
|
||||
if err != nil {
|
||||
if err == io.EOF && len(ret) > 0 {
|
||||
return ret, nil
|
||||
}
|
||||
return ret, err
|
||||
}
|
||||
}
|
||||
}
|
|
@ -5,7 +5,6 @@ package xs
|
|||
import (
|
||||
"errors"
|
||||
"io"
|
||||
"os"
|
||||
|
||||
unix "golang.org/x/sys/unix"
|
||||
)
|
||||
|
@ -31,9 +30,8 @@ type State struct {
|
|||
// MakeRaw put the terminal connected to the given file descriptor into raw
|
||||
// mode and returns the previous state of the terminal so that it can be
|
||||
// restored.
|
||||
func MakeRaw(f *os.File) (*State, error) {
|
||||
fd := f.Fd()
|
||||
termios, err := unix.IoctlGetTermios(int(fd), ioctlReadTermios)
|
||||
func MakeRaw(fd int) (*State, error) {
|
||||
termios, err := unix.IoctlGetTermios(fd, ioctlReadTermios)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -49,7 +47,7 @@ func MakeRaw(f *os.File) (*State, error) {
|
|||
termios.Cflag |= unix.CS8
|
||||
termios.Cc[unix.VMIN] = 1
|
||||
termios.Cc[unix.VTIME] = 0
|
||||
if err := unix.IoctlSetTermios(int(fd), ioctlWriteTermios, termios); err != nil {
|
||||
if err := unix.IoctlSetTermios(fd, ioctlWriteTermios, termios); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
|
@ -58,8 +56,8 @@ func MakeRaw(f *os.File) (*State, error) {
|
|||
|
||||
// GetState returns the current state of a terminal which may be useful to
|
||||
// restore the terminal after a signal.
|
||||
func GetState(f *os.File) (*State, error) {
|
||||
termios, err := unix.IoctlGetTermios(int(f.Fd()), ioctlReadTermios)
|
||||
func GetState(fd int) (*State, error) {
|
||||
termios, err := unix.IoctlGetTermios(fd, ioctlReadTermios)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -69,9 +67,9 @@ func GetState(f *os.File) (*State, error) {
|
|||
|
||||
// Restore restores the terminal connected to the given file descriptor to a
|
||||
// previous state.
|
||||
func Restore(f *os.File, state *State) error {
|
||||
func Restore(fd int, state *State) error {
|
||||
if state != nil {
|
||||
return unix.IoctlSetTermios(int(f.Fd()), ioctlWriteTermios, &state.termios)
|
||||
return unix.IoctlSetTermios(fd, ioctlWriteTermios, &state.termios)
|
||||
} else {
|
||||
return errors.New("nil State")
|
||||
}
|
||||
|
@ -80,9 +78,8 @@ func Restore(f *os.File, state *State) error {
|
|||
// ReadPassword reads a line of input from a terminal without local echo. This
|
||||
// is commonly used for inputting passwords and other sensitive data. The slice
|
||||
// returned does not include the \n.
|
||||
func ReadPassword(f *os.File) ([]byte, error) {
|
||||
fd := f.Fd()
|
||||
termios, err := unix.IoctlGetTermios(int(fd), ioctlReadTermios)
|
||||
func ReadPassword(fd int) ([]byte, error) {
|
||||
termios, err := unix.IoctlGetTermios(fd, ioctlReadTermios)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -91,12 +88,12 @@ func ReadPassword(f *os.File) ([]byte, error) {
|
|||
newState.Lflag &^= unix.ECHO
|
||||
newState.Lflag |= unix.ICANON | unix.ISIG
|
||||
newState.Iflag |= unix.ICRNL
|
||||
if err := unix.IoctlSetTermios(int(fd), ioctlWriteTermios, &newState); err != nil {
|
||||
if err := unix.IoctlSetTermios(fd, ioctlWriteTermios, &newState); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
defer func() {
|
||||
_ = unix.IoctlSetTermios(int(fd), ioctlWriteTermios, termios) // nolint: gosec
|
||||
_ = unix.IoctlSetTermios(fd, ioctlWriteTermios, termios) // nolint: gosec
|
||||
}()
|
||||
|
||||
return readPasswordLine(passwordReader(fd))
|
|
@ -1,6 +1,5 @@
|
|||
//go:build windows
|
||||
// +build windows
|
||||
|
||||
//
|
||||
// Note the terminal manipulation functions herein are mostly stubs. They
|
||||
// don't really do anything and the xs demo client depends on a wrapper
|
||||
// script using the 'stty' tool to actually set the proper mode for
|
||||
|
@ -16,12 +15,10 @@
|
|||
package xs
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
"io"
|
||||
"os/exec"
|
||||
"os/signal"
|
||||
|
||||
"golang.org/x/sys/windows"
|
||||
)
|
||||
|
||||
type State struct {
|
||||
|
@ -30,84 +27,67 @@ type State struct {
|
|||
// MakeRaw put the terminal connected to the given file descriptor into raw
|
||||
// mode and returns the previous state of the terminal so that it can be
|
||||
// restored.
|
||||
func MakeRaw(f *os.File) (*State, error) {
|
||||
cmd := exec.Command("stty", "-echo", "raw")
|
||||
cmd.Stdin = f
|
||||
err := cmd.Run()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
return &State{}, err
|
||||
}
|
||||
|
||||
// MSYS2/CYGWIN: wintty needs CTRL-C caught
|
||||
// ----------------------------------------
|
||||
c := make(chan os.Signal, 1)
|
||||
signal.Notify(c, os.Interrupt, os.Kill)
|
||||
go func() {
|
||||
for sig := range c {
|
||||
_ = sig
|
||||
//fmt.Println(sig)
|
||||
}
|
||||
}()
|
||||
// ----------------------------------------
|
||||
|
||||
func MakeRaw(fd int) (*State, error) {
|
||||
// This doesn't really work. The exec.Command() runs a sub-shell
|
||||
// so the stty mods don't affect the client process.
|
||||
cmd := exec.Command("stty", "-echo raw")
|
||||
cmd.Run()
|
||||
return &State{}, nil
|
||||
}
|
||||
|
||||
// GetState returns the current state of a terminal which may be useful to
|
||||
// restore the terminal after a signal.
|
||||
func GetState(f *os.File) (*State, error) {
|
||||
func GetState(fd int) (*State, error) {
|
||||
return &State{}, nil
|
||||
}
|
||||
|
||||
// Restore restores the terminal connected to the given file descriptor to a
|
||||
// previous state.
|
||||
func Restore(f *os.File, state *State) error {
|
||||
cmd := exec.Command("stty", "sane")
|
||||
cmd.Stdin = f
|
||||
err := cmd.Run()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
return nil
|
||||
}
|
||||
func Restore(fd int, state *State) error {
|
||||
cmd := exec.Command("stty", "echo cooked")
|
||||
cmd.Run()
|
||||
return nil
|
||||
}
|
||||
|
||||
// ReadPassword reads a line of input from a terminal without local echo. This
|
||||
// is commonly used for inputting passwords and other sensitive data. The slice
|
||||
// returned does not include the \n.
|
||||
func ReadPassword(f *os.File) (pw []byte, err error) {
|
||||
sttycmd, err := exec.LookPath("stty")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
//fmt.Printf("stty found at: %v\n", sttycmd)
|
||||
cmdOff := exec.Command(sttycmd, "-echo")
|
||||
cmdOff.Stdin = f //os.Stdin
|
||||
cmdOff.Stdout = nil //os.Stdout
|
||||
cmdOff.Stderr = nil //os.Stderr
|
||||
err = cmdOff.Run()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
func ReadPassword(fd int) ([]byte, error) {
|
||||
return readPasswordLine(passwordReader(fd))
|
||||
}
|
||||
|
||||
//fmt.Printf("Enter password:")
|
||||
scanner := bufio.NewScanner(os.Stdin)
|
||||
scanner.Scan()
|
||||
err = scanner.Err()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
// passwordReader is an io.Reader that reads from a specific file descriptor.
|
||||
type passwordReader windows.Handle
|
||||
|
||||
func (r passwordReader) Read(buf []byte) (int, error) {
|
||||
return windows.Read(windows.Handle(r), buf)
|
||||
}
|
||||
|
||||
// readPasswordLine reads from reader until it finds \n or io.EOF.
|
||||
// The slice returned does not include the \n.
|
||||
// readPasswordLine also ignores any \r it finds.
|
||||
func readPasswordLine(reader io.Reader) ([]byte, error) {
|
||||
var buf [1]byte
|
||||
var ret []byte
|
||||
|
||||
for {
|
||||
n, err := reader.Read(buf[:])
|
||||
if n > 0 {
|
||||
switch buf[0] {
|
||||
case '\n':
|
||||
return ret, nil
|
||||
case '\r':
|
||||
// remove \r from passwords on Windows
|
||||
default:
|
||||
ret = append(ret, buf[0])
|
||||
}
|
||||
continue
|
||||
}
|
||||
pw = scanner.Bytes()
|
||||
fmt.Println()
|
||||
cmdOn := exec.Command(sttycmd, "echo")
|
||||
cmdOn.Stdin = f //os.Stdin
|
||||
cmdOn.Stdout = nil //os.Stdout
|
||||
cmdOn.Stderr = nil //os.Stderr
|
||||
err = cmdOn.Run()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
if err == io.EOF && len(ret) > 0 {
|
||||
return ret, nil
|
||||
}
|
||||
return ret, err
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
|
|
@ -1,14 +0,0 @@
|
|||
#!/bin/bash
|
||||
|
||||
## setup.sh - create some files for xc copy testing
|
||||
dir=cptest
|
||||
|
||||
mkdir -p ${dir}/subdir
|
||||
dd bs=1024 count=16 if=/dev/urandom of=${dir}/file16KB
|
||||
dd bs=1024 count=16 if=/dev/urandom of=${dir}/file1KB
|
||||
dd bs=1024 count=16 if=/dev/urandom of=${dir}/file32KB
|
||||
dd bs=1024 count=16 if=/dev/urandom of=${dir}/file6B
|
||||
dd bs=1048576 count=32 if=/dev/urandom of=${dir}/subdir/file32MB
|
||||
dd bs=1048576 count=64 if=/dev/urandom of=${dir}/subdir/file64MB
|
||||
|
||||
sha1sum $(find ${dir} -type f | sort) >${dir}.sha1sum
|
10
xs/Makefile
10
xs/Makefile
|
@ -1,17 +1,11 @@
|
|||
.PHONY: clean all vis lint
|
||||
|
||||
ifeq ($(GARBLE),y)
|
||||
GO = garble -literals -tiny -debugdir=garbled
|
||||
else
|
||||
GO = go
|
||||
endif
|
||||
|
||||
EXTPKGS = bytes,errors,flag,fmt,internal,io,log,net,os,path,runtime,time,strings,sync,syscall,binary,encoding
|
||||
EXE = $(notdir $(shell pwd))
|
||||
|
||||
all:
|
||||
echo "BUILDOPTS:" $(BUILDOPTS)
|
||||
$(GO) build $(BUILDOPTS) .
|
||||
go build $(BUILDOPTS) .
|
||||
|
||||
clean:
|
||||
$(RM) $(EXE) $(EXE).exe
|
||||
|
@ -21,4 +15,4 @@ vis:
|
|||
../fixup-gv.sh xs.go && cat xs-vis.gv | dot -Tpng -oxs-vis-fixedup.png
|
||||
|
||||
lint:
|
||||
-golangci-lint run
|
||||
-gometalinter --deadline=60s | sort
|
||||
|
|
|
@ -0,0 +1,37 @@
|
|||
#!/bin/bash
|
||||
#
|
||||
## This wrapper may be used within the MSYS/mintty Windows
|
||||
## shell environment to have a functioning hkexsh client with
|
||||
## working 'raw' mode and hidden password entry.
|
||||
##
|
||||
## mintty uses named pipes and ptys to get a more POSIX-like
|
||||
## terminal (incl. VT/ANSI codes) rather than the dumb Windows
|
||||
## console interface; however Go on Windows does not have functioning
|
||||
## MSYS/mintty code to set raw, echo etc. modes.
|
||||
##
|
||||
## Someday it would be preferable to put native Windows term mode
|
||||
## code into the client build, but this is 'good enough' for now
|
||||
## (with the exception of tty rows/cols not being set based on
|
||||
## info from the server).
|
||||
##
|
||||
## INSTALLATION
|
||||
## --
|
||||
## Build the client, put it somewhere in your $PATH with this
|
||||
## wrapper and edit the name of the client binary
|
||||
## eg.,
|
||||
## $ cp hkexsh.exe /usr/bin/.hkexsh.exe
|
||||
## $ cp mintty_wrapper.sh /usr/bin/hkexsh
|
||||
####
|
||||
trap cleanup EXIT ERR
|
||||
|
||||
cleanup() {
|
||||
stty sane
|
||||
}
|
||||
|
||||
if [ ${1}x == "-hx" ]; then
|
||||
./hkexsh -h
|
||||
else
|
||||
stty -echo raw icrnl
|
||||
./hkexsh $@
|
||||
fi
|
||||
|
|
@ -1,5 +1,4 @@
|
|||
//go:build linux || freebsd
|
||||
// +build linux freebsd
|
||||
// +build linux
|
||||
|
||||
package main
|
||||
|
||||
|
@ -31,7 +30,7 @@ func handleTermResizes(conn *xsnet.Conn) {
|
|||
log.Println(err)
|
||||
}
|
||||
termSzPacket := fmt.Sprintf("%d %d", rows, cols)
|
||||
conn.WritePacket([]byte(termSzPacket), xsnet.CSOTermSize) //nolint:errcheck
|
||||
conn.WritePacket([]byte(termSzPacket), xsnet.CSOTermSize) // nolint: errcheck,gosec
|
||||
}
|
||||
}()
|
||||
ch <- syscall.SIGWINCH // Initial resize.
|
Binary file not shown.
Before Width: | Height: | Size: 1.2 MiB After Width: | Height: | Size: 1.1 MiB |
645
xs/xs-vis.gv
645
xs/xs-vis.gv
|
@ -10,7 +10,7 @@ digraph gocallvis {
|
|||
pad="0.0";
|
||||
nodesep="0.35";
|
||||
|
||||
node [shape="box" style="filled,rounded" fillcolor="honeydew" fontname="Verdana" penwidth="1.0" margin="0.05,0.0"];
|
||||
node [shape="ellipse" style="filled" fillcolor="honeydew" fontname="Verdana" penwidth="1.0" margin="0.05,0.0"];
|
||||
edge [minlen="2"]
|
||||
|
||||
subgraph "cluster_focus" {
|
||||
|
@ -20,135 +20,129 @@ labelloc="t";
|
|||
labeljust="c";
|
||||
fontsize="18";
|
||||
|
||||
"blitter.com/go/xs/xs.restoreTermState" [ fillcolor="lightblue" label="restoreTermState" penwidth="0.5" tooltip="blitter.com/go/xs/xs.restoreTermState | defined in xs.go:1117\nat xs.go:1118: calling [blitter.com/go/xs.Restore]" ]
|
||||
"blitter.com/go/xs/xs.main$2" [ fillcolor="lightblue" label="deferCloseChaff" style="dotted,filled" tooltip="blitter.com/go/xs/xs.main$2 | defined in xs.go:996\nat xs.go:999: calling [blitter.com/go/xs/xs.exitWithStatus]\nat xs.go:997: calling [blitter.com/go/xs/xs.restoreTermState]" ]
|
||||
"blitter.com/go/xs/xs.exitWithStatus" [ penwidth="0.5" tooltip="blitter.com/go/xs/xs.exitWithStatus | defined in xs.go:1122" fillcolor="lightblue" label="exitWithStatus" ]
|
||||
"blitter.com/go/xs/xs.doCopyMode" [ fillcolor="lightblue" label="doCopyMode" penwidth="0.5" tooltip="blitter.com/go/xs/xs.doCopyMode | defined in xs.go:354\nat xs.go:435: calling [(*blitter.com/go/xs/xsnet.Conn).GetStatus]\nat xs.go:438: calling [(*blitter.com/go/xs/xsnet.Conn).GetStatus]\nat xs.go:473: calling [(*blitter.com/go/xs/xsnet.Conn).GetStatus]\nat xs.go:475: calling [(*blitter.com/go/xs/xsnet.Conn).GetStatus]\nat xs.go:430: calling [(*blitter.com/go/xs/xsnet.Conn).SetStatus]\nat xs.go:444: calling [blitter.com/go/xs/xs.buildCmdRemoteToLocal]\nat xs.go:424: calling [(blitter.com/go/xs/xsnet.Conn).Read]\nat xs.go:356: calling [(blitter.com/go/xs.Session).Cmd]\nat xs.go:441: calling [(blitter.com/go/xs.Session).Cmd]\nat xs.go:417: calling [(*blitter.com/go/xs/xsnet.Conn).WritePacket]\nat xs.go:364: calling [blitter.com/go/xs/xs.buildCmdLocalToRemote]" ]
|
||||
"blitter.com/go/xs/xs.buildCmdLocalToRemote" [ tooltip="blitter.com/go/xs/xs.buildCmdLocalToRemote | defined in xs.go:270\nat xs.go:283: calling [blitter.com/go/xs.GetTool]\nat xs.go:311: calling [blitter.com/go/xs.GetTool]\nat xs.go:312: calling [blitter.com/go/xs.GetTool]\nat xs.go:335: calling [blitter.com/go/xs/xs.getTreeSizeSubCmd]" fillcolor="lightblue" label="buildCmdLocalToRemote" penwidth="0.5" ]
|
||||
"blitter.com/go/xs/xs.getTreeSizeSubCmd" [ fillcolor="lightblue" label="getTreeSizeSubCmd" penwidth="0.5" tooltip="blitter.com/go/xs/xs.getTreeSizeSubCmd | defined in xs.go:342" ]
|
||||
"blitter.com/go/xs/xs.buildCmdRemoteToLocal" [ fillcolor="lightblue" label="buildCmdRemoteToLocal" penwidth="0.5" tooltip="blitter.com/go/xs/xs.buildCmdRemoteToLocal | defined in xs.go:244\nat xs.go:256: calling [blitter.com/go/xs.GetTool]\nat xs.go:263: calling [blitter.com/go/xs.GetTool]" ]
|
||||
"blitter.com/go/xs/xs.copyBuffer" [ fillcolor="lightblue" label="copyBuffer" penwidth="0.5" tooltip="blitter.com/go/xs/xs.copyBuffer | defined in xs.go:128\nat xs.go:186: calling [blitter.com/go/xs/xs.copyBuffer$2]\nat xs.go:186: calling [blitter.com/go/xs/xs.copyBuffer$3]\nat xs.go:193: calling [(blitter.com/go/xs/xsnet.Conn).Write]\nat xs.go:186: calling [blitter.com/go/xs/xs.copyBuffer$1]" ]
|
||||
"blitter.com/go/xs/xs.copyBuffer$1" [ fillcolor="lightblue" label="copyBuffer$1" style="dotted,filled" tooltip="blitter.com/go/xs/xs.copyBuffer$1 | defined in xs.go:144" ]
|
||||
"blitter.com/go/xs/xs.copyBuffer$2" [ fillcolor="lightblue" label="copyBuffer$2" style="dotted,filled" tooltip="blitter.com/go/xs/xs.copyBuffer$2 | defined in xs.go:145" ]
|
||||
"blitter.com/go/xs/xs.copyBuffer$3" [ fillcolor="lightblue" label="copyBuffer$3" style="dotted,filled" tooltip="blitter.com/go/xs/xs.copyBuffer$3 | defined in xs.go:146" ]
|
||||
"blitter.com/go/xs/xs.reqTunnel" [ tooltip="blitter.com/go/xs/xs.reqTunnel | defined in xs.go:584\nat xs.go:594: calling [(*blitter.com/go/xs/xsnet.Conn).WritePacket]\nat xs.go:593: calling [blitter.com/go/xs/logger.LogDebug]" fillcolor="lightblue" label="reqTunnel" penwidth="0.5" ]
|
||||
"blitter.com/go/xs/xs.main" [ fillcolor="lightblue" label="main" penwidth="0.5" tooltip="blitter.com/go/xs/xs.main | defined in xs.go:680\nat xs.go:1056: calling [(*blitter.com/go/xs/xsnet.Conn).ShutdownChaff]\nat xs.go:1027: calling [(blitter.com/go/xs.Session).Status]\nat xs.go:1089: calling [(blitter.com/go/xs.Session).Status]\nat xs.go:1091: calling [(blitter.com/go/xs.Session).Status]\nat xs.go:1101: calling [(blitter.com/go/xs.Session).Status]\nat xs.go:864: calling [blitter.com/go/xs/logger.New]\nat xs.go:978: calling [blitter.com/go/xs.MakeRaw]\nat xs.go:1075: calling [blitter.com/go/xs/xs.main$3]\nat xs.go:1039: calling [(blitter.com/go/xs/xsnet.Conn).Read]\nat xs.go:960: calling [blitter.com/go/xs/xsnet.Dial]\nat xs.go:1081: calling [blitter.com/go/xs/xs.launchTuns]\nat xs.go:977: calling [github.com/mattn/go-isatty.IsTerminal]\nat xs.go:772: calling [blitter.com/go/xs/xs.exitWithStatus]\nat xs.go:853: calling [blitter.com/go/xs/xs.exitWithStatus]\nat xs.go:963: calling [blitter.com/go/xs/xs.exitWithStatus]\nat xs.go:1027: calling [blitter.com/go/xs/xs.exitWithStatus]\nat xs.go:1101: calling [blitter.com/go/xs/xs.exitWithStatus]\nat xs.go:1082: calling [blitter.com/go/xs/xs.doShellMode]\nat xs.go:1050: calling [(*blitter.com/go/xs/xsnet.Conn).SetupChaff]\nat xs.go:1022: calling [blitter.com/go/xs/xs.sendSessionParams]\nat xs.go:796: calling [blitter.com/go/xs/xs.parseNonSwitchArgs]\nat xs.go:1024: calling [blitter.com/go/xs/xs.restoreTermState]\nat xs.go:1090: calling [blitter.com/go/xs/xs.restoreTermState]\nat xs.go:1096: calling [blitter.com/go/xs/xs.restoreTermState]\nat xs.go:1055: calling [(*blitter.com/go/xs/xsnet.Conn).DisableChaff]\nat xs.go:1025: calling [(*blitter.com/go/xs.Session).SetStatus]\nat xs.go:1043: calling [(*blitter.com/go/xs.Session).SetStatus]\nat xs.go:1047: calling [(*blitter.com/go/xs.Session).SetStatus]\nat xs.go:1086: calling [(*blitter.com/go/xs.Session).SetStatus]\nat xs.go:852: calling [blitter.com/go/xs/xs.usageShell]\nat xs.go:984: calling [blitter.com/go/xs/xs.restoreTermState]\nat xs.go:1005: calling [blitter.com/go/xs.ReadPassword]\nat xs.go:1054: calling [(*blitter.com/go/xs/xsnet.Conn).EnableChaff]\nat xs.go:1085: calling [blitter.com/go/xs/xs.doCopyMode]\nat xs.go:972: calling [(*blitter.com/go/xs/xsnet.Conn).Close]\nat xs.go:1046: calling [blitter.com/go/xs/xs.rejectUserMsg]\nat xs.go:852: calling [blitter.com/go/xs/xs.usageCp]\nat xs.go:790: calling [blitter.com/go/xs/xs.main$1]\nat xs.go:803: calling [blitter.com/go/xs/xs.localUserName]\nat xs.go:865: calling [blitter.com/go/xs/xsnet.Init]\nat xs.go:1021: calling [blitter.com/go/xs.NewSession]" ]
|
||||
"blitter.com/go/xs/xs.parseNonSwitchArgs" [ label="parseNonSwitchArgs" penwidth="0.5" tooltip="blitter.com/go/xs/xs.parseNonSwitchArgs | defined in xs.go:599" fillcolor="lightblue" ]
|
||||
"blitter.com/go/xs/xs.main$1" [ fillcolor="lightblue" label="deferRestore" style="dotted,filled" tooltip="blitter.com/go/xs/xs.main$1 | defined in xs.go:790" ]
|
||||
"blitter.com/go/xs/xs.localUserName" [ fillcolor="lightblue" label="localUserName" penwidth="0.5" tooltip="blitter.com/go/xs/xs.localUserName | defined in xs.go:1106" ]
|
||||
"blitter.com/go/xs/xs.sendSessionParams" [ fillcolor="lightblue" label="sendSessionParams" penwidth="0.5" tooltip="blitter.com/go/xs/xs.sendSessionParams | defined in xs.go:649\nat xs.go:651: calling [(blitter.com/go/xs.Session).Cmd]\nat xs.go:671: calling [(blitter.com/go/xs.Session).Cmd]\nat xs.go:651: calling [(blitter.com/go/xs.Session).AuthCookie]\nat xs.go:675: calling [(blitter.com/go/xs.Session).AuthCookie]\nat xs.go:651: calling [(blitter.com/go/xs.Session).Who]\nat xs.go:659: calling [(blitter.com/go/xs.Session).Who]\nat xs.go:651: calling [(blitter.com/go/xs.Session).Op]\nat xs.go:655: calling [(blitter.com/go/xs.Session).Op]\nat xs.go:651: calling [(blitter.com/go/xs.Session).TermType]\nat xs.go:667: calling [(blitter.com/go/xs.Session).TermType]\nat xs.go:651: calling [(blitter.com/go/xs.Session).ConnHost]\nat xs.go:663: calling [(blitter.com/go/xs.Session).ConnHost]\nat xs.go:675: calling [(blitter.com/go/xs/xsnet.Conn).Write]\nat xs.go:671: calling [(blitter.com/go/xs/xsnet.Conn).Write]\nat xs.go:667: calling [(blitter.com/go/xs/xsnet.Conn).Write]\nat xs.go:663: calling [(blitter.com/go/xs/xsnet.Conn).Write]\nat xs.go:659: calling [(blitter.com/go/xs/xsnet.Conn).Write]\nat xs.go:655: calling [(blitter.com/go/xs/xsnet.Conn).Write]" ]
|
||||
"blitter.com/go/xs/xs.rejectUserMsg" [ fillcolor="lightblue" label="rejectUserMsg" penwidth="0.5" tooltip="blitter.com/go/xs/xs.rejectUserMsg | defined in xs.go:576\nat xs.go:577: calling [blitter.com/go/xs/spinsult.GetSentence]" ]
|
||||
"blitter.com/go/xs/xs.main$3" [ fillcolor="lightblue" label="main$3" style="dotted,filled" tooltip="blitter.com/go/xs/xs.main$3 | defined in xs.go:1065\nat xs.go:1068: calling [math/rand.Intn]\nat xs.go:1072: calling [(*blitter.com/go/xs/xsnet.Conn).WritePacket]" ]
|
||||
"blitter.com/go/xs/xs.launchTuns" [ fillcolor="lightblue" label="launchTuns" penwidth="0.5" tooltip="blitter.com/go/xs/xs.launchTuns | defined in xs.go:634\nat xs.go:645: calling [blitter.com/go/xs/xs.reqTunnel]" ]
|
||||
"blitter.com/go/xs/xs.doShellMode$1" [ tooltip="blitter.com/go/xs/xs.doShellMode$1 | defined in xs.go:490\nat xs.go:509: calling [blitter.com/go/xs/xs.exitWithStatus]\nat xs.go:519: calling [blitter.com/go/xs/xs.exitWithStatus]\nat xs.go:507: calling [(crypto/x509.SystemRootsError).Error]\nat xs.go:513: calling [(*blitter.com/go/xs.Session).SetStatus]\nat xs.go:507: calling [(crypto/x509.CertificateInvalidError).Error]\nat xs.go:507: calling [(vendor/golang.org/x/net/idna.labelError).Error]\nat xs.go:507: calling [(crypto/tls.RecordHeaderError).Error]\nat xs.go:507: calling [(crypto/x509.UnknownAuthorityError).Error]\nat xs.go:513: calling [(*blitter.com/go/xs/xsnet.Conn).GetStatus]\nat xs.go:507: calling [(crypto/tls.alert).Error]\nat xs.go:507: calling [(context.deadlineExceededError).Error]\nat xs.go:507: calling [(crypto/aes.KeySizeError).Error]\nat xs.go:507: calling [(crypto/x509.UnhandledCriticalExtension).Error]\nat xs.go:507: calling [(compress/flate.CorruptInputError).Error]\nat xs.go:507: calling [(*github.com/pkg/errors.fundamental).Error]\nat xs.go:491: calling [blitter.com/go/xs/xs.doShellMode$1$1]\nat xs.go:507: calling [(crypto/x509.HostnameError).Error]\nat xs.go:507: calling [(*crypto/tls.permanentError).Error]\nat xs.go:507: calling [(vendor/golang.org/x/net/idna.runeError).Error]\nat xs.go:514: calling [(blitter.com/go/xs.Session).Status]\nat xs.go:519: calling [(blitter.com/go/xs.Session).Status]\nat xs.go:503: calling [blitter.com/go/xs/xs.restoreTermState]\nat xs.go:518: calling [blitter.com/go/xs/xs.restoreTermState]\nat xs.go:507: calling [(compress/flate.InternalError).Error]" fillcolor="lightblue" label="shellRemoteToStdin" style="dotted,filled" ]
|
||||
"blitter.com/go/xs/xs.doShellMode$1$1" [ fillcolor="lightblue" label="doShellMode$1$1" style="dotted,filled" tooltip="blitter.com/go/xs/xs.doShellMode$1$1 | defined in xs.go:491" ]
|
||||
"blitter.com/go/xs/xs.doShellMode" [ fillcolor="lightblue" label="doShellMode" penwidth="0.5" tooltip="blitter.com/go/xs/xs.doShellMode | defined in xs.go:483\nat xs.go:522: calling [blitter.com/go/xs/xs.doShellMode$1]\nat xs.go:551: calling [blitter.com/go/xs/xs.doShellMode$2]\nat xs.go:527: calling [blitter.com/go/xs/xs.handleTermResizes]" ]
|
||||
"blitter.com/go/xs/xs.handleTermResizes$1" [ tooltip="blitter.com/go/xs/xs.handleTermResizes$1 | defined in termsize_unix.go:21\nat termsize_unix.go:33: calling [(*blitter.com/go/xs/xsnet.Conn).WritePacket]\nat termsize_unix.go:27: calling [blitter.com/go/xs/xs.GetSize]" fillcolor="lightblue" label="handleTermResizes$1" style="dotted,filled" ]
|
||||
"blitter.com/go/xs/xs.GetSize" [ penwidth="1.5" tooltip="blitter.com/go/xs/xs.GetSize | defined in xs.go:221" fillcolor="lightblue" label="GetSize" ]
|
||||
"blitter.com/go/xs/xs.handleTermResizes" [ fillcolor="lightblue" label="handleTermResizes" penwidth="0.5" tooltip="blitter.com/go/xs/xs.handleTermResizes | defined in termsize_unix.go:16\nat termsize_unix.go:21: calling [blitter.com/go/xs/xs.handleTermResizes$1]" ]
|
||||
"blitter.com/go/xs/xs.Copy" [ tooltip="blitter.com/go/xs/xs.Copy | defined in xs.go:115\nat xs.go:116: calling [blitter.com/go/xs/xs.copyBuffer]" fillcolor="lightblue" label="Copy" penwidth="1.5" ]
|
||||
"blitter.com/go/xs/xs.doShellMode$2$1" [ fillcolor="lightblue" label="doShellMode$2$1" style="dotted,filled" tooltip="blitter.com/go/xs/xs.doShellMode$2$1 | defined in xs.go:536\nat xs.go:539: calling [blitter.com/go/xs/xs.Copy]" ]
|
||||
"blitter.com/go/xs/xs.doShellMode$2" [ style="dotted,filled" tooltip="blitter.com/go/xs/xs.doShellMode$2 | defined in xs.go:534\nat xs.go:546: calling [blitter.com/go/xs/xs.restoreTermState]\nat xs.go:548: calling [blitter.com/go/xs/xs.exitWithStatus]\nat xs.go:541: calling [blitter.com/go/xs/xs.doShellMode$2$1]" fillcolor="lightblue" label="shellStdinToRemote" ]
|
||||
"blitter.com/go/xs/xs.usageShell" [ fillcolor="lightblue" label="usageShell" penwidth="0.5" tooltip="blitter.com/go/xs/xs.usageShell | defined in xs.go:559" ]
|
||||
"blitter.com/go/xs/xs.usageCp" [ label="usageCp" penwidth="0.5" tooltip="blitter.com/go/xs/xs.usageCp | defined in xs.go:565" fillcolor="lightblue" ]
|
||||
"blitter.com/go/xs/xs.reqTunnel" [ fillcolor="lightblue" label="reqTunnel" penwidth="0.5" ]
|
||||
"blitter.com/go/xs/xs.launchTuns" [ label="launchTuns" penwidth="0.5" fillcolor="lightblue" ]
|
||||
"blitter.com/go/xs/xs.main$3" [ fillcolor="lightblue" label="main$3" style="dotted,filled" ]
|
||||
"blitter.com/go/xs/xs.doCopyMode" [ fillcolor="lightblue" label="doCopyMode" penwidth="0.5" ]
|
||||
"blitter.com/go/xs/xs.copyBuffer" [ fillcolor="lightblue" label="copyBuffer" penwidth="0.5" ]
|
||||
"blitter.com/go/xs/xs.copyBuffer$1" [ label="copyBuffer$1" style="dotted,filled" fillcolor="lightblue" ]
|
||||
"blitter.com/go/xs/xs.copyBuffer$2" [ label="copyBuffer$2" style="dotted,filled" fillcolor="lightblue" ]
|
||||
"blitter.com/go/xs/xs.copyBuffer$3" [ fillcolor="lightblue" label="copyBuffer$3" style="dotted,filled" ]
|
||||
"blitter.com/go/xs/xs.Copy" [ label="Copy" penwidth="1.5" fillcolor="lightblue" ]
|
||||
"blitter.com/go/xs/xs.doShellMode$1" [ fillcolor="lightblue" label="shellRemoteToStdin" style="dotted,filled" ]
|
||||
"blitter.com/go/xs/xs.doShellMode$1$1" [ fillcolor="lightblue" label="doShellMode$1$1" style="dotted,filled" ]
|
||||
"blitter.com/go/xs/xs.exitWithStatus" [ fillcolor="lightblue" label="exitWithStatus" penwidth="0.5" ]
|
||||
"blitter.com/go/xs/xs.doShellMode" [ label="doShellMode" penwidth="0.5" fillcolor="lightblue" ]
|
||||
"blitter.com/go/xs/xs.handleTermResizes$1" [ fillcolor="lightblue" label="handleTermResizes$1" style="dotted,filled" ]
|
||||
"blitter.com/go/xs/xs.GetSize" [ fillcolor="lightblue" label="GetSize" penwidth="1.5" ]
|
||||
"blitter.com/go/xs/xs.handleTermResizes" [ label="handleTermResizes" penwidth="0.5" fillcolor="lightblue" ]
|
||||
"blitter.com/go/xs/xs.doShellMode$2$1" [ fillcolor="lightblue" label="doShellMode$2$1" style="dotted,filled" ]
|
||||
"blitter.com/go/xs/xs.doShellMode$2" [ fillcolor="lightblue" label="shellStdinToRemote" style="dotted,filled" ]
|
||||
"blitter.com/go/xs/xs.sendSessionParams" [ fillcolor="lightblue" label="sendSessionParams" penwidth="0.5" ]
|
||||
"blitter.com/go/xs/xs.main" [ label="main" penwidth="0.5" fillcolor="lightblue" ]
|
||||
"blitter.com/go/xs/xs.parseNonSwitchArgs" [ fillcolor="lightblue" label="parseNonSwitchArgs" penwidth="0.5" ]
|
||||
"blitter.com/go/xs/xs.main$1" [ fillcolor="lightblue" label="deferRestore" style="dotted,filled" ]
|
||||
"blitter.com/go/xs/xs.main$2" [ fillcolor="lightblue" label="deferCloseChaff" style="dotted,filled" ]
|
||||
"blitter.com/go/xs/xs.rejectUserMsg" [ fillcolor="lightblue" label="rejectUserMsg" penwidth="0.5" ]
|
||||
"blitter.com/go/xs/xs.usageShell" [ fillcolor="lightblue" label="usageShell" penwidth="0.5" ]
|
||||
"blitter.com/go/xs/xs.usageCp" [ label="usageCp" penwidth="0.5" fillcolor="lightblue" ]
|
||||
|
||||
subgraph "cluster_blitter.com/go/xs" {
|
||||
style="filled";
|
||||
penwidth="0.8";
|
||||
style="filled";
|
||||
rank="sink";
|
||||
tooltip="package: blitter.com/go/xs";
|
||||
label="xs";
|
||||
URL="/?f=blitter.com/go/xs";
|
||||
penwidth="0.8";
|
||||
fontsize="16";
|
||||
fillcolor="lightyellow";
|
||||
fontname="Tahoma bold";
|
||||
fontname="bold";
|
||||
label="[xs]";
|
||||
URL="/?f=blitter.com/go/xs";
|
||||
|
||||
"blitter.com/go/xs.Restore" [ tooltip="blitter.com/go/xs.Restore | defined in termmode_linux.go:70" fillcolor="moccasin" label="Restore" penwidth="1.5" ]
|
||||
"blitter.com/go/xs.GetTool" [ fillcolor="moccasin" label="GetTool" penwidth="1.5" tooltip="blitter.com/go/xs.GetTool | defined in auth.go:217" ]
|
||||
"blitter.com/go/xs.MakeRaw" [ fillcolor="moccasin" label="MakeRaw" penwidth="1.5" tooltip="blitter.com/go/xs.MakeRaw | defined in termmode_linux.go:33" ]
|
||||
"blitter.com/go/xs.ReadPassword" [ tooltip="blitter.com/go/xs.ReadPassword | defined in termmode_linux.go:81" fillcolor="moccasin" label="ReadPassword" penwidth="1.5" ]
|
||||
"blitter.com/go/xs.NewSession" [ fillcolor="moccasin" label="NewSession" penwidth="1.5" tooltip="blitter.com/go/xs.NewSession | defined in session.go:130" ]
|
||||
"blitter.com/go/xs.Restore" [ fillcolor="moccasin" label="Restore" penwidth="1.5" ]
|
||||
"blitter.com/go/xs.MakeRaw" [ penwidth="1.5" fillcolor="moccasin" label="MakeRaw" ]
|
||||
"blitter.com/go/xs.ReadPassword" [ fillcolor="moccasin" label="ReadPassword" penwidth="1.5" ]
|
||||
"blitter.com/go/xs.NewSession" [ fillcolor="moccasin" label="NewSession" penwidth="1.5" ]
|
||||
|
||||
subgraph "cluster_*blitter.com/go/xs.Session" {
|
||||
fillcolor="wheat2";
|
||||
label="(*Session)";
|
||||
tooltip="type: *blitter.com/go/xs.Session";
|
||||
penwidth="0.5";
|
||||
fontsize="15";
|
||||
fontcolor="#222222";
|
||||
labelloc="b";
|
||||
style="rounded,filled";
|
||||
|
||||
"(*blitter.com/go/xs.Session).SetStatus" [ fillcolor="moccasin" label="SetStatus" penwidth="1.5" tooltip="(*blitter.com/go/xs.Session).SetStatus | defined in session.go:125" ]
|
||||
|
||||
}
|
||||
|
||||
subgraph "cluster_blitter.com/go/xs.Session" {
|
||||
penwidth="0.5";
|
||||
fontsize="15";
|
||||
fontsize="15";
|
||||
fontcolor="#222222";
|
||||
labelloc="b";
|
||||
style="rounded,filled";
|
||||
fillcolor="wheat2";
|
||||
label="(*Session)";
|
||||
tooltip="type: *blitter.com/go/xs.Session";
|
||||
penwidth="0.5";
|
||||
|
||||
"(*blitter.com/go/xs.Session).SetStatus" [ fillcolor="moccasin" label="SetStatus" penwidth="1.5" ]
|
||||
|
||||
}
|
||||
|
||||
subgraph "cluster_blitter.com/go/xs.Session" {
|
||||
style="rounded,filled";
|
||||
fillcolor="wheat2";
|
||||
label="(Session)";
|
||||
tooltip="type: blitter.com/go/xs.Session";
|
||||
penwidth="0.5";
|
||||
fontsize="15";
|
||||
fontcolor="#222222";
|
||||
labelloc="b";
|
||||
|
||||
"(blitter.com/go/xs.Session).Cmd" [ fillcolor="moccasin" label="Cmd" penwidth="1.5" tooltip="(blitter.com/go/xs.Session).Cmd | defined in session.go:79" ]
|
||||
"(blitter.com/go/xs.Session).Op" [ fillcolor="moccasin" label="Op" penwidth="1.5" tooltip="(blitter.com/go/xs.Session).Op | defined in session.go:36" ]
|
||||
"(blitter.com/go/xs.Session).Who" [ fillcolor="moccasin" label="Who" penwidth="1.5" tooltip="(blitter.com/go/xs.Session).Who | defined in session.go:46" ]
|
||||
"(blitter.com/go/xs.Session).ConnHost" [ label="ConnHost" penwidth="1.5" tooltip="(blitter.com/go/xs.Session).ConnHost | defined in session.go:56" fillcolor="moccasin" ]
|
||||
"(blitter.com/go/xs.Session).TermType" [ fillcolor="moccasin" label="TermType" penwidth="1.5" tooltip="(blitter.com/go/xs.Session).TermType | defined in session.go:67" ]
|
||||
"(blitter.com/go/xs.Session).AuthCookie" [ fillcolor="moccasin" label="AuthCookie" penwidth="1.5" tooltip="(blitter.com/go/xs.Session).AuthCookie | defined in session.go:92" ]
|
||||
"(blitter.com/go/xs.Session).Status" [ penwidth="1.5" tooltip="(blitter.com/go/xs.Session).Status | defined in session.go:120" fillcolor="moccasin" label="Status" ]
|
||||
"(blitter.com/go/xs.Session).Cmd" [ fillcolor="moccasin" label="Cmd" penwidth="1.5" ]
|
||||
"(blitter.com/go/xs.Session).Status" [ penwidth="1.5" fillcolor="moccasin" label="Status" ]
|
||||
"(blitter.com/go/xs.Session).Op" [ fillcolor="moccasin" label="Op" penwidth="1.5" ]
|
||||
"(blitter.com/go/xs.Session).Who" [ fillcolor="moccasin" label="Who" penwidth="1.5" ]
|
||||
"(blitter.com/go/xs.Session).ConnHost" [ fillcolor="moccasin" label="ConnHost" penwidth="1.5" ]
|
||||
"(blitter.com/go/xs.Session).TermType" [ fillcolor="moccasin" label="TermType" penwidth="1.5" ]
|
||||
"(blitter.com/go/xs.Session).AuthCookie" [ label="AuthCookie" penwidth="1.5" fillcolor="moccasin" ]
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
subgraph "cluster_blitter.com/go/xs/logger" {
|
||||
penwidth="0.8";
|
||||
fontsize="16";
|
||||
fontname="Tahoma bold";
|
||||
fontsize="16";
|
||||
URL="/?f=blitter.com/go/xs/logger";
|
||||
tooltip="package: blitter.com/go/xs/logger";
|
||||
penwidth="0.8";
|
||||
style="filled";
|
||||
fillcolor="lightyellow";
|
||||
fontname="bold";
|
||||
rank="sink";
|
||||
label="logger";
|
||||
label="[logger]";
|
||||
tooltip="package: blitter.com/go/xs/logger";
|
||||
|
||||
"blitter.com/go/xs/logger.LogDebug" [ fillcolor="moccasin" label="LogDebug" penwidth="1.5" tooltip="blitter.com/go/xs/logger.LogDebug | defined in logger_linux.go:103" ]
|
||||
"blitter.com/go/xs/logger.New" [ fillcolor="moccasin" label="New" penwidth="1.5" tooltip="blitter.com/go/xs/logger.New | defined in logger_linux.go:71" ]
|
||||
"blitter.com/go/xs/logger.LogDebug" [ fillcolor="moccasin" label="LogDebug" penwidth="1.5" ]
|
||||
"blitter.com/go/xs/logger.New" [ fillcolor="moccasin" label="New" penwidth="1.5" ]
|
||||
|
||||
}
|
||||
|
||||
subgraph "cluster_blitter.com/go/xs/spinsult" {
|
||||
penwidth="0.8";
|
||||
style="filled";
|
||||
fontname="Tahoma bold";
|
||||
rank="sink";
|
||||
fontsize="16";
|
||||
fillcolor="lightyellow";
|
||||
label="spinsult";
|
||||
fillcolor="lightyellow";
|
||||
fontname="bold";
|
||||
label="[spinsult]";
|
||||
URL="/?f=blitter.com/go/xs/spinsult";
|
||||
tooltip="package: blitter.com/go/xs/spinsult";
|
||||
penwidth="0.8";
|
||||
fontsize="16";
|
||||
style="filled";
|
||||
rank="sink";
|
||||
|
||||
"blitter.com/go/xs/spinsult.GetSentence" [ label="GetSentence" penwidth="1.5" tooltip="blitter.com/go/xs/spinsult.GetSentence | defined in spinsult.go:43" fillcolor="moccasin" ]
|
||||
"blitter.com/go/xs/spinsult.GetSentence" [ fillcolor="moccasin" label="GetSentence" penwidth="1.5" ]
|
||||
|
||||
}
|
||||
|
||||
subgraph "cluster_blitter.com/go/xs/xsnet" {
|
||||
fontname="Tahoma bold";
|
||||
penwidth="0.8";
|
||||
fillcolor="lightyellow";
|
||||
fontname="bold";
|
||||
rank="sink";
|
||||
label="xsnet";
|
||||
tooltip="package: blitter.com/go/xs/xsnet";
|
||||
penwidth="0.8";
|
||||
URL="/?f=blitter.com/go/xs/xsnet";
|
||||
fontsize="16";
|
||||
style="filled";
|
||||
fillcolor="lightyellow";
|
||||
URL="/?f=blitter.com/go/xs/xsnet";
|
||||
label="[xsnet]";
|
||||
tooltip="package: blitter.com/go/xs/xsnet";
|
||||
|
||||
"blitter.com/go/xs/xsnet.Init" [ fillcolor="moccasin" label="Init" penwidth="1.5" tooltip="blitter.com/go/xs/xsnet.Init | defined in net.go:198" ]
|
||||
"blitter.com/go/xs/xsnet.Dial" [ fillcolor="moccasin" label="Dial" penwidth="1.5" tooltip="blitter.com/go/xs/xsnet.Dial | defined in net.go:899" ]
|
||||
"blitter.com/go/xs/xsnet.Init" [ fillcolor="moccasin" label="Init" penwidth="1.5" ]
|
||||
"blitter.com/go/xs/xsnet.Dial" [ label="Dial" penwidth="1.5" fillcolor="moccasin" ]
|
||||
|
||||
subgraph "cluster_*blitter.com/go/xs/xsnet.Conn" {
|
||||
fontcolor="#222222";
|
||||
|
@ -160,29 +154,29 @@ tooltip="type: *blitter.com/go/xs/xsnet.Conn";
|
|||
penwidth="0.5";
|
||||
fontsize="15";
|
||||
|
||||
"(*blitter.com/go/xs/xsnet.Conn).WritePacket" [ fillcolor="moccasin" label="WritePacket" penwidth="1.5" tooltip="(*blitter.com/go/xs/xsnet.Conn).WritePacket | defined in net.go:1437" ]
|
||||
"(*blitter.com/go/xs/xsnet.Conn).SetStatus" [ label="SetStatus" penwidth="1.5" tooltip="(*blitter.com/go/xs/xsnet.Conn).SetStatus | defined in net.go:218" fillcolor="moccasin" ]
|
||||
"(*blitter.com/go/xs/xsnet.Conn).GetStatus" [ fillcolor="moccasin" label="GetStatus" penwidth="1.5" tooltip="(*blitter.com/go/xs/xsnet.Conn).GetStatus | defined in net.go:214" ]
|
||||
"(*blitter.com/go/xs/xsnet.Conn).Close" [ fillcolor="moccasin" label="Close" penwidth="1.5" tooltip="(*blitter.com/go/xs/xsnet.Conn).Close | defined in net.go:979" ]
|
||||
"(*blitter.com/go/xs/xsnet.Conn).SetupChaff" [ penwidth="1.5" tooltip="(*blitter.com/go/xs/xsnet.Conn).SetupChaff | defined in net.go:1563" fillcolor="moccasin" label="SetupChaff" ]
|
||||
"(*blitter.com/go/xs/xsnet.Conn).EnableChaff" [ fillcolor="moccasin" label="EnableChaff" penwidth="1.5" tooltip="(*blitter.com/go/xs/xsnet.Conn).EnableChaff | defined in net.go:1546" ]
|
||||
"(*blitter.com/go/xs/xsnet.Conn).DisableChaff" [ fillcolor="moccasin" label="DisableChaff" penwidth="1.5" tooltip="(*blitter.com/go/xs/xsnet.Conn).DisableChaff | defined in net.go:1553" ]
|
||||
"(*blitter.com/go/xs/xsnet.Conn).ShutdownChaff" [ tooltip="(*blitter.com/go/xs/xsnet.Conn).ShutdownChaff | defined in net.go:1558" fillcolor="moccasin" label="ShutdownChaff" penwidth="1.5" ]
|
||||
"(*blitter.com/go/xs/xsnet.Conn).WritePacket" [ penwidth="1.5" fillcolor="moccasin" label="WritePacket" ]
|
||||
"(*blitter.com/go/xs/xsnet.Conn).SetStatus" [ fillcolor="moccasin" label="SetStatus" penwidth="1.5" ]
|
||||
"(*blitter.com/go/xs/xsnet.Conn).Close" [ penwidth="1.5" fillcolor="moccasin" label="Close" ]
|
||||
"(*blitter.com/go/xs/xsnet.Conn).SetupChaff" [ penwidth="1.5" fillcolor="moccasin" label="SetupChaff" ]
|
||||
"(*blitter.com/go/xs/xsnet.Conn).EnableChaff" [ fillcolor="moccasin" label="EnableChaff" penwidth="1.5" ]
|
||||
"(*blitter.com/go/xs/xsnet.Conn).DisableChaff" [ fillcolor="moccasin" label="DisableChaff" penwidth="1.5" ]
|
||||
"(*blitter.com/go/xs/xsnet.Conn).ShutdownChaff" [ fillcolor="moccasin" label="ShutdownChaff" penwidth="1.5" ]
|
||||
|
||||
}
|
||||
|
||||
subgraph "cluster_blitter.com/go/xs/xsnet.Conn" {
|
||||
label="(Conn)";
|
||||
labelloc="b";
|
||||
style="rounded,filled";
|
||||
fillcolor="wheat2";
|
||||
label="(Conn)";
|
||||
tooltip="type: blitter.com/go/xs/xsnet.Conn";
|
||||
penwidth="0.5";
|
||||
fontsize="15";
|
||||
fontcolor="#222222";
|
||||
labelloc="b";
|
||||
style="rounded,filled";
|
||||
fillcolor="wheat2";
|
||||
|
||||
"(blitter.com/go/xs/xsnet.Conn).Read" [ penwidth="1.5" tooltip="(blitter.com/go/xs/xsnet.Conn).Read | defined in net.go:1192" fillcolor="moccasin" label="Read" ]
|
||||
"(blitter.com/go/xs/xsnet.Conn).Write" [ fillcolor="moccasin" label="Write" penwidth="1.5" tooltip="(blitter.com/go/xs/xsnet.Conn).Write | defined in net.go:1431" ]
|
||||
"(blitter.com/go/xs/xsnet.Conn).Read" [ label="Read" penwidth="1.5" fillcolor="moccasin" ]
|
||||
"(blitter.com/go/xs/xsnet.Conn).GetStatus" [ fillcolor="moccasin" label="GetStatus" penwidth="1.5" ]
|
||||
"(blitter.com/go/xs/xsnet.Conn).Write" [ label="Write" penwidth="1.5" fillcolor="moccasin" ]
|
||||
|
||||
}
|
||||
|
||||
|
@ -190,41 +184,41 @@ fillcolor="wheat2";
|
|||
|
||||
subgraph "cluster_compress/flate" {
|
||||
fontsize="16";
|
||||
style="filled";
|
||||
fillcolor="lightyellow";
|
||||
label="flate";
|
||||
fillcolor="#E0FFE1";
|
||||
label="[compress/flate]";
|
||||
URL="/?f=compress/flate";
|
||||
penwidth="0.8";
|
||||
fontname="Tahoma bold";
|
||||
style="filled";
|
||||
fontname="bold";
|
||||
rank="sink";
|
||||
tooltip="package: compress/flate";
|
||||
|
||||
|
||||
subgraph "cluster_compress/flate.CorruptInputError" {
|
||||
fontcolor="#222222";
|
||||
labelloc="b";
|
||||
style="rounded,filled";
|
||||
fillcolor="wheat2";
|
||||
label="(CorruptInputError)";
|
||||
tooltip="type: compress/flate.CorruptInputError";
|
||||
penwidth="0.5";
|
||||
fontsize="15";
|
||||
|
||||
"(compress/flate.CorruptInputError).Error" [ penwidth="1.5" tooltip="(compress/flate.CorruptInputError).Error | defined in inflate.go:35" fillcolor="moccasin" label="Error" ]
|
||||
|
||||
}
|
||||
|
||||
subgraph "cluster_compress/flate.InternalError" {
|
||||
tooltip="type: compress/flate.InternalError";
|
||||
tooltip="type: compress/flate.CorruptInputError";
|
||||
penwidth="0.5";
|
||||
fontsize="15";
|
||||
fontcolor="#222222";
|
||||
labelloc="b";
|
||||
style="rounded,filled";
|
||||
fillcolor="wheat2";
|
||||
label="(InternalError)";
|
||||
fillcolor="#c2e3c2";
|
||||
label="(CorruptInputError)";
|
||||
|
||||
"(compress/flate.InternalError).Error" [ tooltip="(compress/flate.InternalError).Error | defined in inflate.go:42" fillcolor="moccasin" label="Error" penwidth="1.5" ]
|
||||
"(compress/flate.CorruptInputError).Error" [ penwidth="1.5" fillcolor="#adedad" label="Error" ]
|
||||
|
||||
}
|
||||
|
||||
subgraph "cluster_compress/flate.InternalError" {
|
||||
fontsize="15";
|
||||
fontcolor="#222222";
|
||||
labelloc="b";
|
||||
style="rounded,filled";
|
||||
fillcolor="#c2e3c2";
|
||||
label="(InternalError)";
|
||||
tooltip="type: compress/flate.InternalError";
|
||||
penwidth="0.5";
|
||||
|
||||
"(compress/flate.InternalError).Error" [ fillcolor="#adedad" label="Error" penwidth="1.5" ]
|
||||
|
||||
}
|
||||
|
||||
|
@ -233,224 +227,210 @@ label="(InternalError)";
|
|||
subgraph "cluster_context" {
|
||||
fontsize="16";
|
||||
style="filled";
|
||||
label="context";
|
||||
penwidth="0.8";
|
||||
fillcolor="lightyellow";
|
||||
fontname="Tahoma bold";
|
||||
fontname="bold";
|
||||
rank="sink";
|
||||
label="[context]";
|
||||
URL="/?f=context";
|
||||
tooltip="package: context";
|
||||
fillcolor="#E0FFE1";
|
||||
|
||||
|
||||
subgraph "cluster_context.deadlineExceededError" {
|
||||
style="rounded,filled";
|
||||
fillcolor="wheat2";
|
||||
fontsize="15";
|
||||
fontcolor="#222222";
|
||||
labelloc="b";
|
||||
style="rounded,filled";
|
||||
fillcolor="#c2e3c2";
|
||||
label="(deadlineExceededError)";
|
||||
tooltip="type: context.deadlineExceededError";
|
||||
penwidth="0.5";
|
||||
fontsize="15";
|
||||
fontcolor="#222222";
|
||||
labelloc="b";
|
||||
|
||||
"(context.deadlineExceededError).Error" [ fillcolor="moccasin" label="Error" penwidth="1.5" tooltip="(context.deadlineExceededError).Error | defined in context.go:165" ]
|
||||
"(context.deadlineExceededError).Error" [ fillcolor="#adedad" label="Error" penwidth="1.5" ]
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
subgraph "cluster_crypto/aes" {
|
||||
penwidth="0.8";
|
||||
style="filled";
|
||||
fontname="Tahoma bold";
|
||||
style="filled";
|
||||
fillcolor="#E0FFE1";
|
||||
rank="sink";
|
||||
label="aes";
|
||||
label="[crypto/aes]";
|
||||
penwidth="0.8";
|
||||
fontsize="16";
|
||||
fontname="bold";
|
||||
URL="/?f=crypto/aes";
|
||||
tooltip="package: crypto/aes";
|
||||
fontsize="16";
|
||||
fillcolor="lightyellow";
|
||||
|
||||
|
||||
subgraph "cluster_crypto/aes.KeySizeError" {
|
||||
style="rounded,filled";
|
||||
fillcolor="wheat2";
|
||||
fontcolor="#222222";
|
||||
labelloc="b";
|
||||
style="rounded,filled";
|
||||
fillcolor="#c2e3c2";
|
||||
label="(KeySizeError)";
|
||||
tooltip="type: crypto/aes.KeySizeError";
|
||||
penwidth="0.5";
|
||||
fontsize="15";
|
||||
fontcolor="#222222";
|
||||
labelloc="b";
|
||||
|
||||
"(crypto/aes.KeySizeError).Error" [ fillcolor="moccasin" label="Error" penwidth="1.5" tooltip="(crypto/aes.KeySizeError).Error | defined in cipher.go:24" ]
|
||||
"(crypto/aes.KeySizeError).Error" [ fillcolor="#adedad" label="Error" penwidth="1.5" ]
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
subgraph "cluster_crypto/tls" {
|
||||
penwidth="0.8";
|
||||
tooltip="package: crypto/tls";
|
||||
fontsize="16";
|
||||
fontname="Tahoma bold";
|
||||
URL="/?f=crypto/tls";
|
||||
tooltip="package: crypto/tls";
|
||||
style="filled";
|
||||
fillcolor="lightyellow";
|
||||
fontname="bold";
|
||||
rank="sink";
|
||||
label="tls";
|
||||
label="[crypto/tls]";
|
||||
URL="/?f=crypto/tls";
|
||||
penwidth="0.8";
|
||||
fillcolor="#E0FFE1";
|
||||
|
||||
|
||||
subgraph "cluster_*crypto/tls.permanentError" {
|
||||
label="(*permanentError)";
|
||||
tooltip="type: *crypto/tls.permanentError";
|
||||
penwidth="0.5";
|
||||
fontsize="15";
|
||||
fontcolor="#222222";
|
||||
labelloc="b";
|
||||
style="rounded,filled";
|
||||
fillcolor="wheat2";
|
||||
|
||||
"(*crypto/tls.permanentError).Error" [ tooltip="(*crypto/tls.permanentError).Error | defined in conn.go:184" fillcolor="moccasin" label="Error" penwidth="1.5" ]
|
||||
|
||||
}
|
||||
|
||||
subgraph "cluster_crypto/tls.RecordHeaderError" {
|
||||
fillcolor="wheat2";
|
||||
fontcolor="#222222";
|
||||
labelloc="b";
|
||||
style="rounded,filled";
|
||||
fillcolor="#c2e3c2";
|
||||
label="(RecordHeaderError)";
|
||||
tooltip="type: crypto/tls.RecordHeaderError";
|
||||
penwidth="0.5";
|
||||
fontsize="15";
|
||||
fontcolor="#222222";
|
||||
labelloc="b";
|
||||
style="rounded,filled";
|
||||
|
||||
"(crypto/tls.RecordHeaderError).Error" [ tooltip="(crypto/tls.RecordHeaderError).Error | defined in conn.go:571" fillcolor="moccasin" label="Error" penwidth="1.5" ]
|
||||
"(crypto/tls.RecordHeaderError).Error" [ fillcolor="#adedad" label="Error" penwidth="1.5" ]
|
||||
|
||||
}
|
||||
|
||||
subgraph "cluster_crypto/tls.alert" {
|
||||
fontcolor="#222222";
|
||||
penwidth="0.5";
|
||||
fontsize="15";
|
||||
fontcolor="#222222";
|
||||
labelloc="b";
|
||||
style="rounded,filled";
|
||||
fillcolor="wheat2";
|
||||
fillcolor="#c2e3c2";
|
||||
label="(alert)";
|
||||
tooltip="type: crypto/tls.alert";
|
||||
penwidth="0.5";
|
||||
fontsize="15";
|
||||
|
||||
"(crypto/tls.alert).Error" [ fillcolor="moccasin" label="Error" penwidth="1.5" tooltip="(crypto/tls.alert).Error | defined in alert.go:97" ]
|
||||
"(crypto/tls.alert).Error" [ fillcolor="#adedad" label="Error" penwidth="1.5" ]
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
subgraph "cluster_crypto/x509" {
|
||||
URL="/?f=crypto/x509";
|
||||
style="filled";
|
||||
fillcolor="lightyellow";
|
||||
fontname="Tahoma bold";
|
||||
rank="sink";
|
||||
label="x509";
|
||||
penwidth="0.8";
|
||||
tooltip="package: crypto/x509";
|
||||
penwidth="0.8";
|
||||
fontsize="16";
|
||||
style="filled";
|
||||
fillcolor="#E0FFE1";
|
||||
fontname="bold";
|
||||
rank="sink";
|
||||
label="[crypto/x509]";
|
||||
URL="/?f=crypto/x509";
|
||||
|
||||
|
||||
subgraph "cluster_crypto/x509.CertificateInvalidError" {
|
||||
label="(CertificateInvalidError)";
|
||||
tooltip="type: crypto/x509.CertificateInvalidError";
|
||||
penwidth="0.5";
|
||||
penwidth="0.5";
|
||||
fontsize="15";
|
||||
fontcolor="#222222";
|
||||
labelloc="b";
|
||||
style="rounded,filled";
|
||||
fillcolor="wheat2";
|
||||
fillcolor="#c2e3c2";
|
||||
label="(CertificateInvalidError)";
|
||||
tooltip="type: crypto/x509.CertificateInvalidError";
|
||||
|
||||
"(crypto/x509.CertificateInvalidError).Error" [ fillcolor="moccasin" label="Error" penwidth="1.5" tooltip="(crypto/x509.CertificateInvalidError).Error | defined in verify.go:67" ]
|
||||
"(crypto/x509.CertificateInvalidError).Error" [ fillcolor="#adedad" label="Error" penwidth="1.5" ]
|
||||
|
||||
}
|
||||
|
||||
subgraph "cluster_crypto/x509.HostnameError" {
|
||||
tooltip="type: crypto/x509.HostnameError";
|
||||
labelloc="b";
|
||||
style="rounded,filled";
|
||||
fillcolor="#c2e3c2";
|
||||
label="(HostnameError)";
|
||||
tooltip="type: crypto/x509.HostnameError";
|
||||
penwidth="0.5";
|
||||
fontsize="15";
|
||||
fontcolor="#222222";
|
||||
labelloc="b";
|
||||
style="rounded,filled";
|
||||
fillcolor="wheat2";
|
||||
label="(HostnameError)";
|
||||
|
||||
"(crypto/x509.HostnameError).Error" [ fillcolor="moccasin" label="Error" penwidth="1.5" tooltip="(crypto/x509.HostnameError).Error | defined in verify.go:98" ]
|
||||
"(crypto/x509.HostnameError).Error" [ fillcolor="#adedad" label="Error" penwidth="1.5" ]
|
||||
|
||||
}
|
||||
|
||||
subgraph "cluster_crypto/x509.SystemRootsError" {
|
||||
tooltip="type: crypto/x509.SystemRootsError";
|
||||
penwidth="0.5";
|
||||
fontsize="15";
|
||||
fontsize="15";
|
||||
fontcolor="#222222";
|
||||
labelloc="b";
|
||||
style="rounded,filled";
|
||||
fillcolor="wheat2";
|
||||
fillcolor="#c2e3c2";
|
||||
label="(SystemRootsError)";
|
||||
tooltip="type: crypto/x509.SystemRootsError";
|
||||
penwidth="0.5";
|
||||
|
||||
"(crypto/x509.SystemRootsError).Error" [ label="Error" penwidth="1.5" tooltip="(crypto/x509.SystemRootsError).Error | defined in verify.go:159" fillcolor="moccasin" ]
|
||||
"(crypto/x509.SystemRootsError).Error" [ fillcolor="#adedad" label="Error" penwidth="1.5" ]
|
||||
|
||||
}
|
||||
|
||||
subgraph "cluster_crypto/x509.UnhandledCriticalExtension" {
|
||||
label="(UnhandledCriticalExtension)";
|
||||
style="rounded,filled";
|
||||
fillcolor="#c2e3c2";
|
||||
label="(UnhandledCriticalExtension)";
|
||||
tooltip="type: crypto/x509.UnhandledCriticalExtension";
|
||||
penwidth="0.5";
|
||||
fontsize="15";
|
||||
fontcolor="#222222";
|
||||
labelloc="b";
|
||||
style="rounded,filled";
|
||||
fillcolor="wheat2";
|
||||
|
||||
"(crypto/x509.UnhandledCriticalExtension).Error" [ label="Error" penwidth="1.5" tooltip="(crypto/x509.UnhandledCriticalExtension).Error | defined in x509.go:893" fillcolor="moccasin" ]
|
||||
"(crypto/x509.UnhandledCriticalExtension).Error" [ fillcolor="#adedad" label="Error" penwidth="1.5" ]
|
||||
|
||||
}
|
||||
|
||||
subgraph "cluster_crypto/x509.UnknownAuthorityError" {
|
||||
fontsize="15";
|
||||
fontcolor="#222222";
|
||||
labelloc="b";
|
||||
style="rounded,filled";
|
||||
fillcolor="wheat2";
|
||||
style="rounded,filled";
|
||||
fillcolor="#c2e3c2";
|
||||
label="(UnknownAuthorityError)";
|
||||
tooltip="type: crypto/x509.UnknownAuthorityError";
|
||||
penwidth="0.5";
|
||||
fontsize="15";
|
||||
fontcolor="#222222";
|
||||
labelloc="b";
|
||||
|
||||
"(crypto/x509.UnknownAuthorityError).Error" [ tooltip="(crypto/x509.UnknownAuthorityError).Error | defined in verify.go:138" fillcolor="moccasin" label="Error" penwidth="1.5" ]
|
||||
"(crypto/x509.UnknownAuthorityError).Error" [ fillcolor="#adedad" label="Error" penwidth="1.5" ]
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
subgraph "cluster_github.com/mattn/go-isatty" {
|
||||
penwidth="0.8";
|
||||
fontsize="16";
|
||||
fontname="Tahoma bold";
|
||||
rank="sink";
|
||||
style="filled";
|
||||
fontname="bold";
|
||||
penwidth="0.8";
|
||||
fillcolor="lightyellow";
|
||||
label="isatty";
|
||||
rank="sink";
|
||||
label="[isatty]";
|
||||
URL="/?f=github.com/mattn/go-isatty";
|
||||
tooltip="package: github.com/mattn/go-isatty";
|
||||
fontsize="16";
|
||||
style="filled";
|
||||
|
||||
"github.com/mattn/go-isatty.IsTerminal" [ penwidth="1.5" tooltip="github.com/mattn/go-isatty.IsTerminal | defined in isatty_tcgets.go:10" fillcolor="moccasin" label="IsTerminal" ]
|
||||
"github.com/mattn/go-isatty.IsTerminal" [ label="IsTerminal" penwidth="1.5" fillcolor="moccasin" ]
|
||||
|
||||
}
|
||||
|
||||
subgraph "cluster_github.com/pkg/errors" {
|
||||
fontname="Tahoma bold";
|
||||
label="errors";
|
||||
style="filled";
|
||||
fillcolor="lightyellow";
|
||||
URL="/?f=github.com/pkg/errors";
|
||||
tooltip="package: github.com/pkg/errors";
|
||||
rank="sink";
|
||||
label="[errors]";
|
||||
tooltip="package: github.com/pkg/errors";
|
||||
penwidth="0.8";
|
||||
fontsize="16";
|
||||
style="filled";
|
||||
fillcolor="lightyellow";
|
||||
fontname="bold";
|
||||
|
||||
|
||||
subgraph "cluster_*github.com/pkg/errors.fundamental" {
|
||||
|
@ -463,160 +443,107 @@ labelloc="b";
|
|||
style="rounded,filled";
|
||||
fillcolor="wheat2";
|
||||
|
||||
"(*github.com/pkg/errors.fundamental).Error" [ fillcolor="moccasin" label="Error" penwidth="1.5" tooltip="(*github.com/pkg/errors.fundamental).Error | defined in errors.go:125" ]
|
||||
"(*github.com/pkg/errors.fundamental).Error" [ penwidth="1.5" fillcolor="moccasin" label="Error" ]
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
subgraph "cluster_math/rand" {
|
||||
style="filled";
|
||||
fillcolor="lightyellow";
|
||||
penwidth="0.8";
|
||||
fillcolor="#E0FFE1";
|
||||
rank="sink";
|
||||
URL="/?f=math/rand";
|
||||
tooltip="package: math/rand";
|
||||
penwidth="0.8";
|
||||
fontsize="16";
|
||||
fontname="Tahoma bold";
|
||||
label="rand";
|
||||
|
||||
"math/rand.Intn" [ fillcolor="moccasin" label="Intn" penwidth="1.5" tooltip="math/rand.Intn | defined in rand.go:337" ]
|
||||
|
||||
}
|
||||
|
||||
subgraph "cluster_vendor/golang.org/x/net/idna" {
|
||||
URL="/?f=vendor/golang.org/x/net/idna";
|
||||
penwidth="0.8";
|
||||
fontname="Tahoma bold";
|
||||
fillcolor="lightyellow";
|
||||
rank="sink";
|
||||
label="idna";
|
||||
tooltip="package: vendor/golang.org/x/net/idna";
|
||||
fontsize="16";
|
||||
style="filled";
|
||||
fontname="bold";
|
||||
label="[math/rand]";
|
||||
tooltip="package: math/rand";
|
||||
|
||||
|
||||
subgraph "cluster_vendor/golang.org/x/net/idna.labelError" {
|
||||
style="rounded,filled";
|
||||
fillcolor="wheat2";
|
||||
label="(labelError)";
|
||||
tooltip="type: vendor/golang.org/x/net/idna.labelError";
|
||||
penwidth="0.5";
|
||||
fontsize="15";
|
||||
fontcolor="#222222";
|
||||
labelloc="b";
|
||||
|
||||
"(vendor/golang.org/x/net/idna.labelError).Error" [ fillcolor="moccasin" label="Error" penwidth="1.5" tooltip="(vendor/golang.org/x/net/idna.labelError).Error | defined in idna10.0.0.go:324" ]
|
||||
|
||||
}
|
||||
|
||||
subgraph "cluster_vendor/golang.org/x/net/idna.runeError" {
|
||||
style="rounded,filled";
|
||||
fillcolor="wheat2";
|
||||
label="(runeError)";
|
||||
tooltip="type: vendor/golang.org/x/net/idna.runeError";
|
||||
penwidth="0.5";
|
||||
fontsize="15";
|
||||
fontcolor="#222222";
|
||||
labelloc="b";
|
||||
|
||||
"(vendor/golang.org/x/net/idna.runeError).Error" [ tooltip="(vendor/golang.org/x/net/idna.runeError).Error | defined in idna10.0.0.go:331" fillcolor="moccasin" label="Error" penwidth="1.5" ]
|
||||
"math/rand.Intn" [ fillcolor="#adedad" label="Intn" penwidth="1.5" ]
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
"blitter.com/go/xs/xs.doShellMode$1" -> "blitter.com/go/xs/xs.exitWithStatus" [ tooltip="at xs.go:509: calling [blitter.com/go/xs/xs.exitWithStatus]\nat xs.go:519: calling [blitter.com/go/xs/xs.exitWithStatus]" ]
|
||||
"blitter.com/go/xs/xs.doShellMode$1" -> "(crypto/x509.SystemRootsError).Error" [ style="dashed" color="saddlebrown" tooltip="at xs.go:507: calling [(crypto/x509.SystemRootsError).Error]" ]
|
||||
"blitter.com/go/xs/xs.main$2" -> "blitter.com/go/xs/xs.exitWithStatus" [ tooltip="at xs.go:999: calling [blitter.com/go/xs/xs.exitWithStatus]" ]
|
||||
"blitter.com/go/xs/xs.doCopyMode" -> "(*blitter.com/go/xs/xsnet.Conn).GetStatus" [ color="saddlebrown" tooltip="at xs.go:435: calling [(*blitter.com/go/xs/xsnet.Conn).GetStatus]\nat xs.go:438: calling [(*blitter.com/go/xs/xsnet.Conn).GetStatus]\nat xs.go:473: calling [(*blitter.com/go/xs/xsnet.Conn).GetStatus]\nat xs.go:475: calling [(*blitter.com/go/xs/xsnet.Conn).GetStatus]" ]
|
||||
"blitter.com/go/xs/xs.main" -> "(*blitter.com/go/xs/xsnet.Conn).ShutdownChaff" [ arrowhead="normalnoneodiamond" color="saddlebrown" tooltip="at xs.go:1056: calling [(*blitter.com/go/xs/xsnet.Conn).ShutdownChaff]" ]
|
||||
"blitter.com/go/xs/xs.doShellMode$1" -> "(*blitter.com/go/xs.Session).SetStatus" [ color="saddlebrown" tooltip="at xs.go:513: calling [(*blitter.com/go/xs.Session).SetStatus]" ]
|
||||
"blitter.com/go/xs/xs.doShellMode" -> "blitter.com/go/xs/xs.doShellMode$1" [ arrowhead="normalnoneodot" tooltip="at xs.go:522: calling [blitter.com/go/xs/xs.doShellMode$1]" ]
|
||||
"blitter.com/go/xs/xs.main$2" -> "blitter.com/go/xs/xs.restoreTermState" [ tooltip="at xs.go:997: calling [blitter.com/go/xs/xs.restoreTermState]" ]
|
||||
"blitter.com/go/xs/xs.doCopyMode" -> "(*blitter.com/go/xs/xsnet.Conn).SetStatus" [ color="saddlebrown" tooltip="at xs.go:430: calling [(*blitter.com/go/xs/xsnet.Conn).SetStatus]" ]
|
||||
"blitter.com/go/xs/xs.sendSessionParams" -> "(blitter.com/go/xs.Session).Cmd" [ tooltip="at xs.go:651: calling [(blitter.com/go/xs.Session).Cmd]\nat xs.go:671: calling [(blitter.com/go/xs.Session).Cmd]" color="saddlebrown" ]
|
||||
"blitter.com/go/xs/xs.main" -> "(blitter.com/go/xs.Session).Status" [ color="saddlebrown" tooltip="at xs.go:1027: calling [(blitter.com/go/xs.Session).Status]\nat xs.go:1089: calling [(blitter.com/go/xs.Session).Status]\nat xs.go:1091: calling [(blitter.com/go/xs.Session).Status]\nat xs.go:1101: calling [(blitter.com/go/xs.Session).Status]" ]
|
||||
"blitter.com/go/xs/xs.main$3" -> "math/rand.Intn" [ tooltip="at xs.go:1068: calling [math/rand.Intn]" color="saddlebrown" ]
|
||||
"blitter.com/go/xs/xs.doShellMode$1" -> "(crypto/x509.CertificateInvalidError).Error" [ style="dashed" color="saddlebrown" tooltip="at xs.go:507: calling [(crypto/x509.CertificateInvalidError).Error]" ]
|
||||
"blitter.com/go/xs/xs.doShellMode$2" -> "blitter.com/go/xs/xs.restoreTermState" [ tooltip="at xs.go:546: calling [blitter.com/go/xs/xs.restoreTermState]" ]
|
||||
"blitter.com/go/xs/xs.doShellMode$2" -> "blitter.com/go/xs/xs.exitWithStatus" [ tooltip="at xs.go:548: calling [blitter.com/go/xs/xs.exitWithStatus]" ]
|
||||
"blitter.com/go/xs/xs.restoreTermState" -> "blitter.com/go/xs.Restore" [ color="saddlebrown" tooltip="at xs.go:1118: calling [blitter.com/go/xs.Restore]" ]
|
||||
"blitter.com/go/xs/xs.main" -> "blitter.com/go/xs/logger.New" [ color="saddlebrown" tooltip="at xs.go:864: calling [blitter.com/go/xs/logger.New]" ]
|
||||
"blitter.com/go/xs/xs.main" -> "blitter.com/go/xs.MakeRaw" [ color="saddlebrown" tooltip="at xs.go:978: calling [blitter.com/go/xs.MakeRaw]" ]
|
||||
"blitter.com/go/xs/xs.sendSessionParams" -> "(blitter.com/go/xs.Session).AuthCookie" [ color="saddlebrown" tooltip="at xs.go:651: calling [(blitter.com/go/xs.Session).AuthCookie]\nat xs.go:675: calling [(blitter.com/go/xs.Session).AuthCookie]" ]
|
||||
"blitter.com/go/xs/xs.main" -> "blitter.com/go/xs/xs.main$3" [ arrowhead="normalnoneodot" tooltip="at xs.go:1075: calling [blitter.com/go/xs/xs.main$3]" ]
|
||||
"blitter.com/go/xs/xs.doCopyMode" -> "blitter.com/go/xs/xs.buildCmdRemoteToLocal" [ tooltip="at xs.go:444: calling [blitter.com/go/xs/xs.buildCmdRemoteToLocal]" ]
|
||||
"blitter.com/go/xs/xs.doCopyMode" -> "(blitter.com/go/xs/xsnet.Conn).Read" [ color="saddlebrown" tooltip="at xs.go:424: calling [(blitter.com/go/xs/xsnet.Conn).Read]" ]
|
||||
"blitter.com/go/xs/xs.sendSessionParams" -> "(blitter.com/go/xs.Session).Who" [ tooltip="at xs.go:651: calling [(blitter.com/go/xs.Session).Who]\nat xs.go:659: calling [(blitter.com/go/xs.Session).Who]" color="saddlebrown" ]
|
||||
"blitter.com/go/xs/xs.main" -> "(blitter.com/go/xs/xsnet.Conn).Read" [ color="saddlebrown" tooltip="at xs.go:1039: calling [(blitter.com/go/xs/xsnet.Conn).Read]" ]
|
||||
"blitter.com/go/xs/xs.main" -> "blitter.com/go/xs/xsnet.Dial" [ color="saddlebrown" tooltip="at xs.go:960: calling [blitter.com/go/xs/xsnet.Dial]" ]
|
||||
"blitter.com/go/xs/xs.sendSessionParams" -> "(blitter.com/go/xs.Session).Op" [ color="saddlebrown" tooltip="at xs.go:651: calling [(blitter.com/go/xs.Session).Op]\nat xs.go:655: calling [(blitter.com/go/xs.Session).Op]" ]
|
||||
"blitter.com/go/xs/xs.rejectUserMsg" -> "blitter.com/go/xs/spinsult.GetSentence" [ color="saddlebrown" tooltip="at xs.go:577: calling [blitter.com/go/xs/spinsult.GetSentence]" ]
|
||||
"blitter.com/go/xs/xs.main" -> "blitter.com/go/xs/xs.launchTuns" [ tooltip="at xs.go:1081: calling [blitter.com/go/xs/xs.launchTuns]" ]
|
||||
"blitter.com/go/xs/xs.doShellMode$1" -> "(vendor/golang.org/x/net/idna.labelError).Error" [ style="dashed" color="saddlebrown" tooltip="at xs.go:507: calling [(vendor/golang.org/x/net/idna.labelError).Error]" ]
|
||||
"blitter.com/go/xs/xs.Copy" -> "blitter.com/go/xs/xs.copyBuffer" [ tooltip="at xs.go:116: calling [blitter.com/go/xs/xs.copyBuffer]" ]
|
||||
"blitter.com/go/xs/xs.main" -> "github.com/mattn/go-isatty.IsTerminal" [ color="saddlebrown" tooltip="at xs.go:977: calling [github.com/mattn/go-isatty.IsTerminal]" ]
|
||||
"blitter.com/go/xs/xs.sendSessionParams" -> "(blitter.com/go/xs.Session).TermType" [ color="saddlebrown" tooltip="at xs.go:651: calling [(blitter.com/go/xs.Session).TermType]\nat xs.go:667: calling [(blitter.com/go/xs.Session).TermType]" ]
|
||||
"blitter.com/go/xs/xs.doShellMode$1" -> "(crypto/tls.RecordHeaderError).Error" [ style="dashed" color="saddlebrown" tooltip="at xs.go:507: calling [(crypto/tls.RecordHeaderError).Error]" ]
|
||||
"blitter.com/go/xs/xs.doShellMode$1" -> "(crypto/x509.UnknownAuthorityError).Error" [ style="dashed" color="saddlebrown" tooltip="at xs.go:507: calling [(crypto/x509.UnknownAuthorityError).Error]" ]
|
||||
"blitter.com/go/xs/xs.main" -> "blitter.com/go/xs/xs.exitWithStatus" [ tooltip="at xs.go:772: calling [blitter.com/go/xs/xs.exitWithStatus]\nat xs.go:853: calling [blitter.com/go/xs/xs.exitWithStatus]\nat xs.go:963: calling [blitter.com/go/xs/xs.exitWithStatus]\nat xs.go:1027: calling [blitter.com/go/xs/xs.exitWithStatus]\nat xs.go:1101: calling [blitter.com/go/xs/xs.exitWithStatus]" ]
|
||||
"blitter.com/go/xs/xs.doShellMode$2" -> "blitter.com/go/xs/xs.doShellMode$2$1" [ tooltip="at xs.go:541: calling [blitter.com/go/xs/xs.doShellMode$2$1]" ]
|
||||
"blitter.com/go/xs/xs.main" -> "blitter.com/go/xs/xs.doShellMode" [ tooltip="at xs.go:1082: calling [blitter.com/go/xs/xs.doShellMode]" ]
|
||||
"blitter.com/go/xs/xs.doShellMode" -> "blitter.com/go/xs/xs.doShellMode$2" [ arrowhead="normalnoneodot" tooltip="at xs.go:551: calling [blitter.com/go/xs/xs.doShellMode$2]" ]
|
||||
"blitter.com/go/xs/xs.buildCmdLocalToRemote" -> "blitter.com/go/xs.GetTool" [ color="saddlebrown" tooltip="at xs.go:283: calling [blitter.com/go/xs.GetTool]\nat xs.go:311: calling [blitter.com/go/xs.GetTool]\nat xs.go:312: calling [blitter.com/go/xs.GetTool]" ]
|
||||
"blitter.com/go/xs/xs.doShellMode$1" -> "(*blitter.com/go/xs/xsnet.Conn).GetStatus" [ color="saddlebrown" tooltip="at xs.go:513: calling [(*blitter.com/go/xs/xsnet.Conn).GetStatus]" ]
|
||||
"blitter.com/go/xs/xs.doShellMode$1" -> "(crypto/tls.alert).Error" [ style="dashed" color="saddlebrown" tooltip="at xs.go:507: calling [(crypto/tls.alert).Error]" ]
|
||||
"blitter.com/go/xs/xs.doShellMode" -> "blitter.com/go/xs/xs.handleTermResizes" [ tooltip="at xs.go:527: calling [blitter.com/go/xs/xs.handleTermResizes]" ]
|
||||
"blitter.com/go/xs/xs.main" -> "(*blitter.com/go/xs/xsnet.Conn).SetupChaff" [ color="saddlebrown" tooltip="at xs.go:1050: calling [(*blitter.com/go/xs/xsnet.Conn).SetupChaff]" ]
|
||||
"blitter.com/go/xs/xs.doShellMode$1" -> "(context.deadlineExceededError).Error" [ style="dashed" color="saddlebrown" tooltip="at xs.go:507: calling [(context.deadlineExceededError).Error]" ]
|
||||
"blitter.com/go/xs/xs.doShellMode$1" -> "(crypto/aes.KeySizeError).Error" [ style="dashed" color="saddlebrown" tooltip="at xs.go:507: calling [(crypto/aes.KeySizeError).Error]" ]
|
||||
"blitter.com/go/xs/xs.doShellMode$2$1" -> "blitter.com/go/xs/xs.Copy" [ tooltip="at xs.go:539: calling [blitter.com/go/xs/xs.Copy]" ]
|
||||
"blitter.com/go/xs/xs.doCopyMode" -> "(blitter.com/go/xs.Session).Cmd" [ color="saddlebrown" tooltip="at xs.go:356: calling [(blitter.com/go/xs.Session).Cmd]\nat xs.go:441: calling [(blitter.com/go/xs.Session).Cmd]" ]
|
||||
"blitter.com/go/xs/xs.doCopyMode" -> "(*blitter.com/go/xs/xsnet.Conn).WritePacket" [ tooltip="at xs.go:417: calling [(*blitter.com/go/xs/xsnet.Conn).WritePacket]" color="saddlebrown" ]
|
||||
"blitter.com/go/xs/xs.sendSessionParams" -> "(blitter.com/go/xs.Session).ConnHost" [ color="saddlebrown" tooltip="at xs.go:651: calling [(blitter.com/go/xs.Session).ConnHost]\nat xs.go:663: calling [(blitter.com/go/xs.Session).ConnHost]" ]
|
||||
"blitter.com/go/xs/xs.main" -> "blitter.com/go/xs/xs.sendSessionParams" [ tooltip="at xs.go:1022: calling [blitter.com/go/xs/xs.sendSessionParams]" ]
|
||||
"blitter.com/go/xs/xs.doCopyMode" -> "blitter.com/go/xs/xs.buildCmdLocalToRemote" [ tooltip="at xs.go:364: calling [blitter.com/go/xs/xs.buildCmdLocalToRemote]" ]
|
||||
"blitter.com/go/xs/xs.main" -> "blitter.com/go/xs/xs.parseNonSwitchArgs" [ tooltip="at xs.go:796: calling [blitter.com/go/xs/xs.parseNonSwitchArgs]" ]
|
||||
"blitter.com/go/xs/xs.main" -> "blitter.com/go/xs/xs.restoreTermState" [ tooltip="at xs.go:1024: calling [blitter.com/go/xs/xs.restoreTermState]\nat xs.go:1090: calling [blitter.com/go/xs/xs.restoreTermState]\nat xs.go:1096: calling [blitter.com/go/xs/xs.restoreTermState]" ]
|
||||
"blitter.com/go/xs/xs.main" -> "(*blitter.com/go/xs/xsnet.Conn).DisableChaff" [ color="saddlebrown" tooltip="at xs.go:1055: calling [(*blitter.com/go/xs/xsnet.Conn).DisableChaff]" arrowhead="normalnoneodiamond" ]
|
||||
"blitter.com/go/xs/xs.launchTuns" -> "blitter.com/go/xs/xs.reqTunnel" [ tooltip="at xs.go:645: calling [blitter.com/go/xs/xs.reqTunnel]" ]
|
||||
"blitter.com/go/xs/xs.doShellMode$1" -> "(crypto/x509.UnhandledCriticalExtension).Error" [ style="dashed" color="saddlebrown" tooltip="at xs.go:507: calling [(crypto/x509.UnhandledCriticalExtension).Error]" ]
|
||||
"blitter.com/go/xs/xs.doShellMode$1" -> "(compress/flate.CorruptInputError).Error" [ style="dashed" color="saddlebrown" tooltip="at xs.go:507: calling [(compress/flate.CorruptInputError).Error]" ]
|
||||
"blitter.com/go/xs/xs.buildCmdLocalToRemote" -> "blitter.com/go/xs/xs.getTreeSizeSubCmd" [ tooltip="at xs.go:335: calling [blitter.com/go/xs/xs.getTreeSizeSubCmd]" ]
|
||||
"blitter.com/go/xs/xs.buildCmdRemoteToLocal" -> "blitter.com/go/xs.GetTool" [ color="saddlebrown" tooltip="at xs.go:256: calling [blitter.com/go/xs.GetTool]\nat xs.go:263: calling [blitter.com/go/xs.GetTool]" ]
|
||||
"blitter.com/go/xs/xs.sendSessionParams" -> "(blitter.com/go/xs/xsnet.Conn).Write" [ style="dashed" color="saddlebrown" tooltip="at xs.go:675: calling [(blitter.com/go/xs/xsnet.Conn).Write]\nat xs.go:671: calling [(blitter.com/go/xs/xsnet.Conn).Write]\nat xs.go:667: calling [(blitter.com/go/xs/xsnet.Conn).Write]\nat xs.go:663: calling [(blitter.com/go/xs/xsnet.Conn).Write]\nat xs.go:659: calling [(blitter.com/go/xs/xsnet.Conn).Write]\nat xs.go:655: calling [(blitter.com/go/xs/xsnet.Conn).Write]" ]
|
||||
"blitter.com/go/xs/xs.main" -> "(*blitter.com/go/xs.Session).SetStatus" [ color="saddlebrown" tooltip="at xs.go:1025: calling [(*blitter.com/go/xs.Session).SetStatus]\nat xs.go:1043: calling [(*blitter.com/go/xs.Session).SetStatus]\nat xs.go:1047: calling [(*blitter.com/go/xs.Session).SetStatus]\nat xs.go:1086: calling [(*blitter.com/go/xs.Session).SetStatus]" ]
|
||||
"blitter.com/go/xs/xs.doShellMode$1" -> "(*github.com/pkg/errors.fundamental).Error" [ style="dashed" color="saddlebrown" tooltip="at xs.go:507: calling [(*github.com/pkg/errors.fundamental).Error]" ]
|
||||
"blitter.com/go/xs/xs.handleTermResizes" -> "blitter.com/go/xs/xs.handleTermResizes$1" [ arrowhead="normalnoneodot" tooltip="at termsize_unix.go:21: calling [blitter.com/go/xs/xs.handleTermResizes$1]" ]
|
||||
"blitter.com/go/xs/xs.main" -> "blitter.com/go/xs/xs.usageShell" [ style="dashed" tooltip="at xs.go:852: calling [blitter.com/go/xs/xs.usageShell]" ]
|
||||
"blitter.com/go/xs/xs.main" -> "blitter.com/go/xs/xs.restoreTermState" [ arrowhead="normalnoneodiamond" tooltip="at xs.go:984: calling [blitter.com/go/xs/xs.restoreTermState]" ]
|
||||
"blitter.com/go/xs/xs.main" -> "blitter.com/go/xs.ReadPassword" [ color="saddlebrown" tooltip="at xs.go:1005: calling [blitter.com/go/xs.ReadPassword]" ]
|
||||
"blitter.com/go/xs/xs.doShellMode$1" -> "blitter.com/go/xs/xs.doShellMode$1$1" [ arrowhead="normalnoneodiamond" tooltip="at xs.go:491: calling [blitter.com/go/xs/xs.doShellMode$1$1]" ]
|
||||
"blitter.com/go/xs/xs.handleTermResizes$1" -> "(*blitter.com/go/xs/xsnet.Conn).WritePacket" [ color="saddlebrown" tooltip="at termsize_unix.go:33: calling [(*blitter.com/go/xs/xsnet.Conn).WritePacket]" ]
|
||||
"blitter.com/go/xs/xs.main" -> "(*blitter.com/go/xs/xsnet.Conn).EnableChaff" [ color="saddlebrown" tooltip="at xs.go:1054: calling [(*blitter.com/go/xs/xsnet.Conn).EnableChaff]" ]
|
||||
"blitter.com/go/xs/xs.doShellMode$1" -> "(crypto/x509.HostnameError).Error" [ style="dashed" color="saddlebrown" tooltip="at xs.go:507: calling [(crypto/x509.HostnameError).Error]" ]
|
||||
"blitter.com/go/xs/xs.doShellMode$1" -> "(*crypto/tls.permanentError).Error" [ color="saddlebrown" tooltip="at xs.go:507: calling [(*crypto/tls.permanentError).Error]" style="dashed" ]
|
||||
"blitter.com/go/xs/xs.main" -> "blitter.com/go/xs/xs.doCopyMode" [ tooltip="at xs.go:1085: calling [blitter.com/go/xs/xs.doCopyMode]" ]
|
||||
"blitter.com/go/xs/xs.copyBuffer" -> "blitter.com/go/xs/xs.copyBuffer$2" [ style="dashed" tooltip="at xs.go:186: calling [blitter.com/go/xs/xs.copyBuffer$2]" ]
|
||||
"blitter.com/go/xs/xs.copyBuffer" -> "blitter.com/go/xs/xs.copyBuffer$3" [ style="dashed" tooltip="at xs.go:186: calling [blitter.com/go/xs/xs.copyBuffer$3]" ]
|
||||
"blitter.com/go/xs/xs.main" -> "(*blitter.com/go/xs/xsnet.Conn).Close" [ arrowhead="normalnoneodiamond" color="saddlebrown" tooltip="at xs.go:972: calling [(*blitter.com/go/xs/xsnet.Conn).Close]" ]
|
||||
"blitter.com/go/xs/xs.main" -> "blitter.com/go/xs/xs.rejectUserMsg" [ tooltip="at xs.go:1046: calling [blitter.com/go/xs/xs.rejectUserMsg]" ]
|
||||
"blitter.com/go/xs/xs.main" -> "blitter.com/go/xs/xs.usageCp" [ tooltip="at xs.go:852: calling [blitter.com/go/xs/xs.usageCp]" style="dashed" ]
|
||||
"blitter.com/go/xs/xs.doShellMode$1" -> "(vendor/golang.org/x/net/idna.runeError).Error" [ color="saddlebrown" tooltip="at xs.go:507: calling [(vendor/golang.org/x/net/idna.runeError).Error]" style="dashed" ]
|
||||
"blitter.com/go/xs/xs.copyBuffer" -> "(blitter.com/go/xs/xsnet.Conn).Write" [ tooltip="at xs.go:193: calling [(blitter.com/go/xs/xsnet.Conn).Write]" style="dashed" color="saddlebrown" ]
|
||||
"blitter.com/go/xs/xs.copyBuffer" -> "blitter.com/go/xs/xs.copyBuffer$1" [ style="dashed" tooltip="at xs.go:186: calling [blitter.com/go/xs/xs.copyBuffer$1]" ]
|
||||
"blitter.com/go/xs/xs.main" -> "blitter.com/go/xs/xs.main$1" [ tooltip="at xs.go:790: calling [blitter.com/go/xs/xs.main$1]" arrowhead="normalnoneodot" ]
|
||||
"blitter.com/go/xs/xs.main" -> "blitter.com/go/xs/xs.localUserName" [ tooltip="at xs.go:803: calling [blitter.com/go/xs/xs.localUserName]" ]
|
||||
"blitter.com/go/xs/xs.reqTunnel" -> "(*blitter.com/go/xs/xsnet.Conn).WritePacket" [ color="saddlebrown" tooltip="at xs.go:594: calling [(*blitter.com/go/xs/xsnet.Conn).WritePacket]" ]
|
||||
"blitter.com/go/xs/xs.main" -> "blitter.com/go/xs/xsnet.Init" [ color="saddlebrown" tooltip="at xs.go:865: calling [blitter.com/go/xs/xsnet.Init]" ]
|
||||
"blitter.com/go/xs/xs.main" -> "blitter.com/go/xs.NewSession" [ tooltip="at xs.go:1021: calling [blitter.com/go/xs.NewSession]" color="saddlebrown" ]
|
||||
"blitter.com/go/xs/xs.doShellMode$1" -> "(blitter.com/go/xs.Session).Status" [ tooltip="at xs.go:514: calling [(blitter.com/go/xs.Session).Status]\nat xs.go:519: calling [(blitter.com/go/xs.Session).Status]" color="saddlebrown" ]
|
||||
"blitter.com/go/xs/xs.handleTermResizes$1" -> "blitter.com/go/xs/xs.GetSize" [ tooltip="at termsize_unix.go:27: calling [blitter.com/go/xs/xs.GetSize]" ]
|
||||
"blitter.com/go/xs/xs.reqTunnel" -> "blitter.com/go/xs/logger.LogDebug" [ color="saddlebrown" tooltip="at xs.go:593: calling [blitter.com/go/xs/logger.LogDebug]" ]
|
||||
"blitter.com/go/xs/xs.main$3" -> "(*blitter.com/go/xs/xsnet.Conn).WritePacket" [ tooltip="at xs.go:1072: calling [(*blitter.com/go/xs/xsnet.Conn).WritePacket]" color="saddlebrown" ]
|
||||
"blitter.com/go/xs/xs.doShellMode$1" -> "blitter.com/go/xs/xs.restoreTermState" [ tooltip="at xs.go:503: calling [blitter.com/go/xs/xs.restoreTermState]\nat xs.go:518: calling [blitter.com/go/xs/xs.restoreTermState]" ]
|
||||
"blitter.com/go/xs/xs.doShellMode$1" -> "(compress/flate.InternalError).Error" [ tooltip="at xs.go:507: calling [(compress/flate.InternalError).Error]" style="dashed" color="saddlebrown" ]
|
||||
"blitter.com/go/xs/xs.reqTunnel" -> "blitter.com/go/xs/logger.LogDebug" [ color="saddlebrown" ]
|
||||
"blitter.com/go/xs/xs.reqTunnel" -> "(*blitter.com/go/xs/xsnet.Conn).WritePacket" [ color="saddlebrown" ]
|
||||
"blitter.com/go/xs/xs.launchTuns" -> "blitter.com/go/xs/xs.reqTunnel" [ ]
|
||||
"blitter.com/go/xs/xs.main$3" -> "math/rand.Intn" [ color="saddlebrown" ]
|
||||
"blitter.com/go/xs/xs.main$3" -> "(*blitter.com/go/xs/xsnet.Conn).WritePacket" [ color="saddlebrown" ]
|
||||
"blitter.com/go/xs/xs.doCopyMode" -> "(blitter.com/go/xs.Session).Cmd" [ color="saddlebrown" ]
|
||||
"blitter.com/go/xs/xs.doCopyMode" -> "(*blitter.com/go/xs/xsnet.Conn).WritePacket" [ color="saddlebrown" ]
|
||||
"blitter.com/go/xs/xs.doCopyMode" -> "(blitter.com/go/xs/xsnet.Conn).Read" [ color="saddlebrown" ]
|
||||
"blitter.com/go/xs/xs.doCopyMode" -> "(*blitter.com/go/xs/xsnet.Conn).SetStatus" [ color="saddlebrown" ]
|
||||
"blitter.com/go/xs/xs.doCopyMode" -> "(blitter.com/go/xs/xsnet.Conn).GetStatus" [ color="saddlebrown" ]
|
||||
"blitter.com/go/xs/xs.copyBuffer" -> "(blitter.com/go/xs/xsnet.Conn).Write" [ color="saddlebrown" style="dashed" ]
|
||||
"blitter.com/go/xs/xs.copyBuffer" -> "blitter.com/go/xs/xs.copyBuffer$1" [ style="dashed" ]
|
||||
"blitter.com/go/xs/xs.copyBuffer" -> "blitter.com/go/xs/xs.copyBuffer$2" [ style="dashed" ]
|
||||
"blitter.com/go/xs/xs.copyBuffer" -> "blitter.com/go/xs/xs.copyBuffer$3" [ style="dashed" ]
|
||||
"blitter.com/go/xs/xs.Copy" -> "blitter.com/go/xs/xs.copyBuffer" [ ]
|
||||
"blitter.com/go/xs/xs.doShellMode$1" -> "blitter.com/go/xs/xs.doShellMode$1$1" [ arrowhead="normalnoneodiamond" ]
|
||||
"blitter.com/go/xs/xs.doShellMode$1" -> "blitter.com/go/xs.Restore" [ color="saddlebrown" ]
|
||||
"blitter.com/go/xs/xs.doShellMode$1" -> "(blitter.com/go/xs/xsnet.Conn).GetStatus" [ color="saddlebrown" ]
|
||||
"blitter.com/go/xs/xs.doShellMode$1" -> "(*blitter.com/go/xs.Session).SetStatus" [ color="saddlebrown" ]
|
||||
"blitter.com/go/xs/xs.doShellMode$1" -> "(blitter.com/go/xs.Session).Status" [ color="saddlebrown" ]
|
||||
"blitter.com/go/xs/xs.doShellMode$1" -> "blitter.com/go/xs/xs.exitWithStatus" [ ]
|
||||
"blitter.com/go/xs/xs.doShellMode$1" -> "(crypto/x509.CertificateInvalidError).Error" [ style="dashed" color="saddlebrown" ]
|
||||
"blitter.com/go/xs/xs.doShellMode$1" -> "(crypto/aes.KeySizeError).Error" [ style="dashed" color="saddlebrown" ]
|
||||
"blitter.com/go/xs/xs.doShellMode$1" -> "(crypto/x509.HostnameError).Error" [ color="saddlebrown" style="dashed" ]
|
||||
"blitter.com/go/xs/xs.doShellMode$1" -> "(crypto/x509.UnhandledCriticalExtension).Error" [ style="dashed" color="saddlebrown" ]
|
||||
"blitter.com/go/xs/xs.doShellMode$1" -> "(context.deadlineExceededError).Error" [ style="dashed" color="saddlebrown" ]
|
||||
"blitter.com/go/xs/xs.doShellMode$1" -> "(compress/flate.CorruptInputError).Error" [ style="dashed" color="saddlebrown" ]
|
||||
"blitter.com/go/xs/xs.doShellMode$1" -> "(crypto/tls.RecordHeaderError).Error" [ style="dashed" color="saddlebrown" ]
|
||||
"blitter.com/go/xs/xs.doShellMode$1" -> "(crypto/x509.UnknownAuthorityError).Error" [ style="dashed" color="saddlebrown" ]
|
||||
"blitter.com/go/xs/xs.doShellMode$1" -> "(crypto/x509.SystemRootsError).Error" [ style="dashed" color="saddlebrown" ]
|
||||
"blitter.com/go/xs/xs.doShellMode$1" -> "(compress/flate.InternalError).Error" [ style="dashed" color="saddlebrown" ]
|
||||
"blitter.com/go/xs/xs.doShellMode$1" -> "(crypto/tls.alert).Error" [ style="dashed" color="saddlebrown" ]
|
||||
"blitter.com/go/xs/xs.doShellMode$1" -> "(*github.com/pkg/errors.fundamental).Error" [ style="dashed" color="saddlebrown" ]
|
||||
"blitter.com/go/xs/xs.doShellMode" -> "blitter.com/go/xs/xs.doShellMode$1" [ arrowhead="normalnoneodot" ]
|
||||
"blitter.com/go/xs/xs.handleTermResizes$1" -> "blitter.com/go/xs/xs.GetSize" [ ]
|
||||
"blitter.com/go/xs/xs.handleTermResizes$1" -> "(*blitter.com/go/xs/xsnet.Conn).WritePacket" [ color="saddlebrown" ]
|
||||
"blitter.com/go/xs/xs.handleTermResizes" -> "blitter.com/go/xs/xs.handleTermResizes$1" [ arrowhead="normalnoneodot" ]
|
||||
"blitter.com/go/xs/xs.doShellMode" -> "blitter.com/go/xs/xs.handleTermResizes" [ ]
|
||||
"blitter.com/go/xs/xs.doShellMode$2$1" -> "blitter.com/go/xs/xs.Copy" [ ]
|
||||
"blitter.com/go/xs/xs.doShellMode$2" -> "blitter.com/go/xs/xs.doShellMode$2$1" [ ]
|
||||
"blitter.com/go/xs/xs.doShellMode$2" -> "blitter.com/go/xs.Restore" [ color="saddlebrown" ]
|
||||
"blitter.com/go/xs/xs.doShellMode$2" -> "blitter.com/go/xs/xs.exitWithStatus" [ ]
|
||||
"blitter.com/go/xs/xs.doShellMode" -> "blitter.com/go/xs/xs.doShellMode$2" [ arrowhead="normalnoneodot" ]
|
||||
"blitter.com/go/xs/xs.sendSessionParams" -> "(blitter.com/go/xs.Session).Op" [ color="saddlebrown" ]
|
||||
"blitter.com/go/xs/xs.sendSessionParams" -> "(blitter.com/go/xs.Session).Who" [ color="saddlebrown" ]
|
||||
"blitter.com/go/xs/xs.sendSessionParams" -> "(blitter.com/go/xs.Session).ConnHost" [ color="saddlebrown" ]
|
||||
"blitter.com/go/xs/xs.sendSessionParams" -> "(blitter.com/go/xs.Session).TermType" [ color="saddlebrown" ]
|
||||
"blitter.com/go/xs/xs.sendSessionParams" -> "(blitter.com/go/xs.Session).Cmd" [ color="saddlebrown" ]
|
||||
"blitter.com/go/xs/xs.sendSessionParams" -> "(blitter.com/go/xs.Session).AuthCookie" [ color="saddlebrown" ]
|
||||
"blitter.com/go/xs/xs.sendSessionParams" -> "(blitter.com/go/xs/xsnet.Conn).Write" [ style="dashed" color="saddlebrown" ]
|
||||
"blitter.com/go/xs/xs.main" -> "blitter.com/go/xs/xs.parseNonSwitchArgs" [ ]
|
||||
"blitter.com/go/xs/xs.main" -> "blitter.com/go/xs/xs.main$1" [ arrowhead="normalnoneodot" ]
|
||||
"blitter.com/go/xs/xs.main" -> "blitter.com/go/xs/xs.exitWithStatus" [ ]
|
||||
"blitter.com/go/xs/xs.main" -> "blitter.com/go/xs/logger.New" [ color="saddlebrown" ]
|
||||
"blitter.com/go/xs/xs.main" -> "blitter.com/go/xs/xsnet.Init" [ color="saddlebrown" ]
|
||||
"blitter.com/go/xs/xs.main" -> "blitter.com/go/xs/xsnet.Dial" [ color="saddlebrown" ]
|
||||
"blitter.com/go/xs/xs.main" -> "(*blitter.com/go/xs/xsnet.Conn).Close" [ arrowhead="normalnoneodiamond" color="saddlebrown" ]
|
||||
"blitter.com/go/xs/xs.main" -> "github.com/mattn/go-isatty.IsTerminal" [ color="saddlebrown" ]
|
||||
"blitter.com/go/xs/xs.main" -> "blitter.com/go/xs.MakeRaw" [ color="saddlebrown" ]
|
||||
"blitter.com/go/xs/xs.main$2" -> "blitter.com/go/xs.Restore" [ color="saddlebrown" ]
|
||||
"blitter.com/go/xs/xs.main" -> "blitter.com/go/xs/xs.main$2" [ arrowhead="normalnoneodiamond" ]
|
||||
"blitter.com/go/xs/xs.main" -> "blitter.com/go/xs.ReadPassword" [ color="saddlebrown" ]
|
||||
"blitter.com/go/xs/xs.main" -> "blitter.com/go/xs.NewSession" [ color="saddlebrown" ]
|
||||
"blitter.com/go/xs/xs.main" -> "blitter.com/go/xs/xs.sendSessionParams" [ ]
|
||||
"blitter.com/go/xs/xs.main" -> "(blitter.com/go/xs/xsnet.Conn).Read" [ color="saddlebrown" ]
|
||||
"blitter.com/go/xs/xs.main" -> "(*blitter.com/go/xs.Session).SetStatus" [ color="saddlebrown" ]
|
||||
"blitter.com/go/xs/xs.rejectUserMsg" -> "blitter.com/go/xs/spinsult.GetSentence" [ color="saddlebrown" ]
|
||||
"blitter.com/go/xs/xs.main" -> "blitter.com/go/xs/xs.rejectUserMsg" [ ]
|
||||
"blitter.com/go/xs/xs.main" -> "(*blitter.com/go/xs/xsnet.Conn).SetupChaff" [ color="saddlebrown" ]
|
||||
"blitter.com/go/xs/xs.main" -> "(*blitter.com/go/xs/xsnet.Conn).EnableChaff" [ color="saddlebrown" ]
|
||||
"blitter.com/go/xs/xs.main" -> "(*blitter.com/go/xs/xsnet.Conn).DisableChaff" [ arrowhead="normalnoneodiamond" color="saddlebrown" ]
|
||||
"blitter.com/go/xs/xs.main" -> "(*blitter.com/go/xs/xsnet.Conn).ShutdownChaff" [ arrowhead="normalnoneodiamond" color="saddlebrown" ]
|
||||
"blitter.com/go/xs/xs.main" -> "blitter.com/go/xs/xs.main$3" [ arrowhead="normalnoneodot" ]
|
||||
"blitter.com/go/xs/xs.main" -> "blitter.com/go/xs/xs.launchTuns" [ ]
|
||||
"blitter.com/go/xs/xs.main" -> "blitter.com/go/xs/xs.doShellMode" [ ]
|
||||
"blitter.com/go/xs/xs.main" -> "(blitter.com/go/xs.Session).Status" [ color="saddlebrown" ]
|
||||
"blitter.com/go/xs/xs.main" -> "blitter.com/go/xs/xs.doCopyMode" [ ]
|
||||
"blitter.com/go/xs/xs.main" -> "blitter.com/go/xs.Restore" [ color="saddlebrown" ]
|
||||
"blitter.com/go/xs/xs.main" -> "blitter.com/go/xs/xs.usageShell" [ style="dashed" ]
|
||||
"blitter.com/go/xs/xs.main" -> "blitter.com/go/xs/xs.usageCp" [ style="dashed" ]
|
||||
}
|
||||
|
|
|
@ -6,9 +6,7 @@ XSD_USER=root
|
|||
XSD_HOME=/var/run
|
||||
INST_PREFIX=/usr/local
|
||||
COMMAND=$INST_PREFIX/sbin/xsd
|
||||
#ARGS="-L -aK KEX_all -aC C_all -aH H_all"
|
||||
echo "SET ARGS in this script to define allow KEX, cipher and hmac algs"
|
||||
exit 1
|
||||
ARGS=""
|
||||
|
||||
depend() {
|
||||
need net
|
||||
|
@ -30,7 +28,7 @@ start() {
|
|||
-d ${XSD_HOME} \
|
||||
--make-pidfile --pidfile ${XSD_PIDFILE} \
|
||||
--start --quiet --background \
|
||||
--exec "${COMMAND}" -- ${ARGS}
|
||||
--exec "${COMMAND}" "${ARGS}"
|
||||
eend $?
|
||||
}
|
||||
|
||||
|
|
166
xsd.sysvrc
166
xsd.sysvrc
|
@ -1,166 +0,0 @@
|
|||
#! /bin/sh
|
||||
|
||||
### BEGIN INIT INFO
|
||||
# Provides: xsd
|
||||
# Required-Start: $remote_fs $syslog
|
||||
# Required-Stop: $remote_fs $syslog
|
||||
# Default-Start: 2 3 4 5
|
||||
# Default-Stop:
|
||||
# Short-Description: eXperimental Shell Daemon
|
||||
### END INIT INFO
|
||||
|
||||
set -e
|
||||
|
||||
echo "SET XSD_OPTS in this script to define allow KEX, cipher and hmac algs"
|
||||
#XSD_OPTS="-L -aK KEX_all -aC C_all -aH H_all"
|
||||
exit 1
|
||||
|
||||
# /etc/init.d/xsd: start and stop the eXperimental "secure" Shell Daemon
|
||||
|
||||
test -x /usr/local/sbin/xsd || exit 0
|
||||
( /usr/local/sbin/xsd -h 2>&1 | grep -q chaff ) 2>/dev/null || exit 0
|
||||
|
||||
umask 022
|
||||
|
||||
#if test -f /etc/default/ssh; then
|
||||
# . /etc/default/ssh
|
||||
#fi
|
||||
|
||||
. /lib/lsb/init-functions
|
||||
|
||||
if [ -n "$2" ]; then
|
||||
XSD_OPTS="$XSD_OPTS $2"
|
||||
fi
|
||||
|
||||
# Are we running from init?
|
||||
run_by_init() {
|
||||
([ "$previous" ] && [ "$runlevel" ]) || [ "$runlevel" = S ]
|
||||
}
|
||||
|
||||
check_for_no_start() {
|
||||
# forget it if we're trying to start, and /etc/xsd_not_to_be_run exists
|
||||
if [ -e /etc/xsd_not_to_be_run ]; then
|
||||
if [ "$1" = log_end_msg ]; then
|
||||
log_end_msg 0 || true
|
||||
fi
|
||||
if ! run_by_init; then
|
||||
log_action_msg "eXperimental Shell Daemon not in use (/etc/xsd_not_to_be_run)" || true
|
||||
fi
|
||||
exit 0
|
||||
fi
|
||||
}
|
||||
|
||||
check_dev_null() {
|
||||
if [ ! -c /dev/null ]; then
|
||||
if [ "$1" = log_end_msg ]; then
|
||||
log_end_msg 1 || true
|
||||
fi
|
||||
if ! run_by_init; then
|
||||
log_action_msg "/dev/null is not a character device!" || true
|
||||
fi
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
#check_privsep_dir() {
|
||||
# # Create the PrivSep empty dir if necessary
|
||||
# if [ ! -d /run/sshd ]; then
|
||||
# mkdir /run/sshd
|
||||
# chmod 0755 /run/sshd
|
||||
# fi
|
||||
#}
|
||||
|
||||
#check_config() {
|
||||
# if [ ! -e /etc/xsd_not_to_be_run ]; then
|
||||
# /usr/local/sbin/xsd $XSD_OPTS -t || exit 1
|
||||
# fi
|
||||
#}
|
||||
|
||||
export PATH="${PATH:+$PATH:}/usr/local/sbin:/usr/sbin:/sbin"
|
||||
|
||||
case "$1" in
|
||||
start)
|
||||
#check_privsep_dir
|
||||
check_for_no_start
|
||||
check_dev_null
|
||||
log_daemon_msg "Starting eXperimental Shell Daemon" "xsd" || true
|
||||
if start-stop-daemon --start -b --quiet --oknodo --chuid 0:0 --exec /usr/local/sbin/xsd -- $XSD_OPTS; then
|
||||
log_end_msg 0 || true
|
||||
else
|
||||
log_end_msg 1 || true
|
||||
fi
|
||||
;;
|
||||
stop)
|
||||
log_daemon_msg "Stopping eXperimental Shell Daemon" "xsd" || true
|
||||
if start-stop-daemon --stop --quiet --oknodo --exec /usr/local/sbin/xsd; then
|
||||
log_end_msg 0 || true
|
||||
else
|
||||
log_end_msg 1 || true
|
||||
fi
|
||||
;;
|
||||
|
||||
reload|force-reload)
|
||||
check_for_no_start
|
||||
#check_config
|
||||
log_daemon_msg "Reloading eXperimental Shell Daemon's configuration" "xsd" || true
|
||||
if start-stop-daemon --stop --signal 1 --quiet --oknodo --exec /usr/local/sbin/xsd; then
|
||||
log_end_msg 0 || true
|
||||
else
|
||||
log_end_msg 1 || true
|
||||
fi
|
||||
;;
|
||||
|
||||
restart)
|
||||
#check_privsep_dir
|
||||
#check_config
|
||||
log_daemon_msg "Restarting eXperimental Shell Daemon" "xsd" || true
|
||||
start-stop-daemon --stop --quiet --oknodo --retry 30 --exec /usr/local/sbin/xsd
|
||||
check_for_no_start log_end_msg
|
||||
check_dev_null log_end_msg
|
||||
if start-stop-daemon --start -b --quiet --oknodo --chuid 0:0 --exec /usr/local/sbin/xsd -- $XSD_OPTS; then
|
||||
log_end_msg 0 || true
|
||||
else
|
||||
log_end_msg 1 || true
|
||||
fi
|
||||
;;
|
||||
|
||||
try-restart)
|
||||
#check_privsep_dir
|
||||
#check_config
|
||||
log_daemon_msg "Restarting eXperimental Shell Daemon" "xsd" || true
|
||||
RET=0
|
||||
start-stop-daemon --stop --quiet --retry 30 --exec /usr/local/sbin/xsd || RET="$?"
|
||||
case $RET in
|
||||
0)
|
||||
# old daemon stopped
|
||||
check_for_no_start log_end_msg
|
||||
check_dev_null log_end_msg
|
||||
if start-stop-daemon --start -b --quiet --oknodo --chuid 0:0 --exec /usr/local/sbin/xsd -- $XSD_OPTS; then
|
||||
log_end_msg 0 || true
|
||||
else
|
||||
log_end_msg 1 || true
|
||||
fi
|
||||
;;
|
||||
1)
|
||||
# daemon not running
|
||||
log_progress_msg "(not running)" || true
|
||||
log_end_msg 0 || true
|
||||
;;
|
||||
*)
|
||||
# failed to stop
|
||||
log_progress_msg "(failed to stop)" || true
|
||||
log_end_msg 1 || true
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
|
||||
status)
|
||||
status_of_proc -p /run/xsd.pid /usr/local/sbin/xsd xsd && exit 0 || exit $?
|
||||
;;
|
||||
|
||||
*)
|
||||
log_action_msg "Usage: /etc/init.d/xsd {start|stop|reload|force-reload|restart|try-restart|status}" || true
|
||||
exit 1
|
||||
esac
|
||||
|
||||
exit 0
|
10
xsd/Makefile
10
xsd/Makefile
|
@ -1,16 +1,10 @@
|
|||
.PHONY: clean all vis lint
|
||||
|
||||
ifeq ($(GARBLE),y)
|
||||
GO = garble -literals -tiny -debugdir=garbled
|
||||
else
|
||||
GO = go
|
||||
endif
|
||||
|
||||
EXTPKGS = binary,bytes,crypto,encoding,errors,flag,fmt,internal,io,log,net,os,path,runtime,time,strings,sync,syscall
|
||||
EXE = $(notdir $(shell pwd))
|
||||
|
||||
all:
|
||||
$(GO) build $(BUILDOPTS) .
|
||||
go build $(BUILDOPTS) .
|
||||
|
||||
clean:
|
||||
$(RM) $(EXE) $(EXE).exe
|
||||
|
@ -20,5 +14,5 @@ vis:
|
|||
../fixup-gv.sh xsd.go && cat xsd-vis.gv | dot -Tpng -oxsd-vis-fixedup.png
|
||||
|
||||
lint:
|
||||
-golangci-lint run
|
||||
-gometalinter --deadline=60s | sort
|
||||
|
||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 1.1 MiB After Width: | Height: | Size: 782 KiB |
579
xsd/xsd-vis.gv
579
xsd/xsd-vis.gv
File diff suppressed because one or more lines are too long
772
xsd/xsd.go
772
xsd/xsd.go
File diff suppressed because it is too large
Load Diff
|
@ -1,18 +1,12 @@
|
|||
.PHONY: info clean lib
|
||||
|
||||
ifeq ($(GARBLE),y)
|
||||
GO = garble -tiny -literals -debugdir=garbled
|
||||
else
|
||||
GO = go
|
||||
endif
|
||||
|
||||
all: lib
|
||||
|
||||
clean:
|
||||
go clean .
|
||||
|
||||
lib: info
|
||||
$(GO) install .
|
||||
go install .
|
||||
|
||||
ifneq ($(MSYSTEM),)
|
||||
info:
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
package xsnet
|
||||
|
||||
// Copyright (c) 2017-2020 Russell Magee
|
||||
// Copyright (c) 2017-2019 Russell Magee
|
||||
// Licensed under the terms of the MIT license (see LICENSE.mit in this
|
||||
// distribution)
|
||||
//
|
||||
|
@ -21,12 +21,10 @@ import (
|
|||
"log"
|
||||
|
||||
"blitter.com/go/cryptmt"
|
||||
"blitter.com/go/hopscotch"
|
||||
"blitter.com/go/xs/logger"
|
||||
"github.com/aead/chacha20/chacha"
|
||||
"blitter.com/go/wanderer"
|
||||
"golang.org/x/crypto/blowfish"
|
||||
"golang.org/x/crypto/twofish"
|
||||
whirlpool "github.com/jzelinskie/whirlpool"
|
||||
|
||||
// hash algos must be manually imported thusly:
|
||||
// (Would be nice if the golang pkg docs were more clear
|
||||
// on this...)
|
||||
|
@ -58,20 +56,10 @@ func expandKeyMat(keymat []byte, blocksize int) []byte {
|
|||
return keymat
|
||||
}
|
||||
|
||||
// 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) {
|
||||
/* Support functionality to set up encryption after a channel has
|
||||
been negotiated via xsnet.go
|
||||
*/
|
||||
func (hc Conn) getStream(keymat []byte) (rc cipher.Stream, mc hash.Hash, err error) {
|
||||
var key []byte
|
||||
var block cipher.Block
|
||||
var iv []byte
|
||||
|
@ -115,25 +103,11 @@ func (hc *Conn) getStream(keymat []byte) (rc cipher.Stream, mc hash.Hash, err er
|
|||
rc = cipher.NewOFB(block, iv)
|
||||
log.Printf("[cipher BLOWFISH_64 (%d)]\n", copts)
|
||||
case CAlgCryptMT1:
|
||||
rc = cryptmt.New(nil, nil, keymat)
|
||||
//NOTE: this alg is not based on block cipher, no IV
|
||||
rc = cryptmt.NewCipher(keymat)
|
||||
log.Printf("[cipher CRYPTMT1 (%d)]\n", copts)
|
||||
case CAlgHopscotch:
|
||||
rc = hopscotch.New(nil, nil, 4, keymat)
|
||||
//NOTE: this alg is not based on block cipher, no IV
|
||||
log.Printf("[cipher HOPSCOTCH (%d)]\n", copts)
|
||||
case CAlgChaCha20_12:
|
||||
keymat = expandKeyMat(keymat, chacha.KeySize)
|
||||
key = keymat[0:chacha.KeySize]
|
||||
ivlen = chacha.INonceSize
|
||||
iv = keymat[chacha.KeySize : chacha.KeySize+ivlen]
|
||||
rc, err = chacha.NewCipher(iv, key, chacha.INonceSize)
|
||||
if err != nil {
|
||||
log.Printf("[ChaCha20 config error]\n")
|
||||
fmt.Printf("[ChaCha20 config error]\n")
|
||||
}
|
||||
// TODO: SetCounter() to something derived from key or nonce or extra keymat?
|
||||
log.Printf("[cipher CHACHA20_12 (%d)]\n", copts)
|
||||
case CAlgWanderer:
|
||||
rc = wanderer.NewCodec(nil, nil, keymat, 3, 3)
|
||||
log.Printf("[cipher WANDERER (%d)]\n", copts)
|
||||
default:
|
||||
log.Printf("[invalid cipher (%d)]\n", copts)
|
||||
fmt.Printf("DOOFUS SET A VALID CIPHER ALG (%d)\n", copts)
|
||||
|
@ -157,9 +131,6 @@ func (hc *Conn) getStream(keymat []byte) (rc cipher.Stream, mc hash.Hash, err er
|
|||
if !halg.Available() {
|
||||
log.Fatal("hash not available!")
|
||||
}
|
||||
case HmacWHIRLPOOL:
|
||||
log.Printf("[hash HmacWHIRLPOOL (%d)]\n", hopts)
|
||||
mc = whirlpool.New()
|
||||
default:
|
||||
log.Printf("[invalid hmac (%d)]\n", hopts)
|
||||
fmt.Printf("DOOFUS SET A VALID HMAC ALG (%d)\n", hopts)
|
||||
|
@ -168,7 +139,7 @@ func (hc *Conn) getStream(keymat []byte) (rc cipher.Stream, mc hash.Hash, err er
|
|||
//os.Exit(1)
|
||||
}
|
||||
|
||||
if err == nil && ivlen > 0 {
|
||||
if err != nil {
|
||||
// Feed the IV into the hmac: all traffic in the connection must
|
||||
// feed its data into the hmac afterwards, so both ends can xor
|
||||
// that with the stream to detect corruption.
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// consts.go - consts for xsnet
|
||||
|
||||
// Copyright (c) 2017-2020 Russell Magee
|
||||
// Copyright (c) 2017-2019 Russell Magee
|
||||
// Licensed under the terms of the MIT license (see LICENSE.mit in this
|
||||
// distribution)
|
||||
//
|
||||
|
@ -29,10 +29,6 @@ const (
|
|||
KEX_NEWHOPE_SIMPLE // 'NewHopeLP-Simple' - https://eprint.iacr.org/2016/1157
|
||||
KEX_resvd14
|
||||
KEX_resvd15
|
||||
KEX_FRODOKEM_1344AES
|
||||
KEX_FRODOKEM_1344SHAKE
|
||||
KEX_FRODOKEM_976AES
|
||||
KEX_FRODOKEM_976SHAKE
|
||||
KEX_invalid = 255
|
||||
)
|
||||
|
||||
|
@ -52,8 +48,6 @@ const (
|
|||
CSEKEXAlgDenied // server rejected proposed KEX alg
|
||||
CSECipherAlgDenied // server rejected proposed Cipher alg
|
||||
CSEHMACAlgDenied // server rejected proposed HMAC alg
|
||||
CSEConnDead // connection keepalives expired
|
||||
CSELoginTimeout
|
||||
)
|
||||
|
||||
// Extended (>255 UNIX exit status) codes
|
||||
|
@ -77,8 +71,6 @@ const (
|
|||
CSOTunKeepAlive // client tunnel heartbeat
|
||||
CSOTunDisconn // server -> client: tunnel rport disconnected
|
||||
CSOTunHangup // client -> server: tunnel lport hung up
|
||||
CSOKeepAlive // bidir keepalive packet to monitor main connection
|
||||
CSORekey // TODO: rekey/re-select session cipher/hash algs
|
||||
)
|
||||
|
||||
// TunEndpoint.tunCtl control values - used to control workers for client
|
||||
|
@ -98,8 +90,8 @@ const (
|
|||
// Channel status Op byte type (see CSONone, ... and CSENone, ...)
|
||||
type CSOType uint32
|
||||
|
||||
// TODO: this should be small (max unfragmented packet size?)
|
||||
const MAX_PAYLOAD_LEN = 2*1024*1024*1024 - 1
|
||||
//TODO: this should be small (max unfragmented packet size?)
|
||||
const MAX_PAYLOAD_LEN = 4*1024*1024*1024 - 1
|
||||
|
||||
// Session symmetric crypto algs
|
||||
const (
|
||||
|
@ -107,8 +99,7 @@ const (
|
|||
CAlgTwofish128 // golang.org/x/crypto/twofish
|
||||
CAlgBlowfish64 // golang.org/x/crypto/blowfish
|
||||
CAlgCryptMT1 //cryptmt using mtwist64
|
||||
CAlgChaCha20_12
|
||||
CAlgHopscotch
|
||||
CAlgWanderer // inhouse experimental crypto alg
|
||||
CAlgNoneDisallowed
|
||||
)
|
||||
|
||||
|
@ -119,27 +110,8 @@ type CSCipherAlg uint32
|
|||
const (
|
||||
HmacSHA256 = iota
|
||||
HmacSHA512
|
||||
HmacWHIRLPOOL
|
||||
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"
|
||||
|
|
|
@ -40,7 +40,7 @@ func getKCPalgnum(extensions []string) (k KCPAlg) {
|
|||
switch s {
|
||||
case "KCP_NONE":
|
||||
k = KCP_NONE
|
||||
break //golint:ignore SA4011 out of for
|
||||
break //out of for
|
||||
case "KCP_AES":
|
||||
k = KCP_AES
|
||||
break //out of for
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,13 +0,0 @@
|
|||
//go:build linux
|
||||
// +build linux
|
||||
|
||||
package xsnet
|
||||
|
||||
import (
|
||||
"syscall"
|
||||
)
|
||||
|
||||
func (hc *Conn) kill() {
|
||||
syscall.Kill(hc.Pproc, syscall.SIGABRT) //nolint:errcheck
|
||||
}
|
||||
|
|
@ -1,13 +0,0 @@
|
|||
//go:build windows
|
||||
// +build windows
|
||||
|
||||
package xsnet
|
||||
|
||||
import (
|
||||
"os/exec"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
func (hc *Conn) kill() {
|
||||
exec.Command("taskkill", "/f", "/pid", strconv.Itoa(hc.Pproc)).Run()
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
// hkextun.go - Tunnel setup using an established xsnet.Conn
|
||||
|
||||
// Copyright (c) 2017-2020 Russell Magee
|
||||
// Copyright (c) 2017-2019 Russell Magee
|
||||
// Licensed under the terms of the MIT license (see LICENSE.mit in this
|
||||
// distribution)
|
||||
//
|
||||
|
@ -37,8 +37,6 @@ type (
|
|||
// client starts worker to receive/send data using lport
|
||||
// ... client disconnects: sends remhost [CSOTunClose:rport]
|
||||
// ... or server disconnects: sends client [CSOTunClose:lport]
|
||||
// ... or server disconnects: due to client failing to send TunKeepAlive
|
||||
// events for too long
|
||||
// server at any time sends [CSOTunRefused:rport] if daemon died
|
||||
// --
|
||||
|
||||
|
|
|
@ -1,16 +1,10 @@
|
|||
.PHONY: clean all vis lint
|
||||
|
||||
ifeq ($(GARBLE),y)
|
||||
GO = garble -tiny -literals -debugdir=garbled
|
||||
else
|
||||
GO = go
|
||||
endif
|
||||
|
||||
EXTPKGS = bytes,errors,flag,fmt,internal,io,log,net,os,path,runtime,time,strings,sync,syscall,binary,encoding
|
||||
EXE = $(notdir $(shell pwd))
|
||||
|
||||
all:
|
||||
$(GO) build $(BUILDOPTS) .
|
||||
go build $(BUILDOPTS) .
|
||||
|
||||
clean:
|
||||
$(RM) $(EXE) $(EXE).exe
|
||||
|
@ -19,4 +13,4 @@ vis:
|
|||
go-callvis -format png -file xspasswd-vis -ignore $(EXTPKGS) -group pkg,type .
|
||||
|
||||
lint:
|
||||
-golangci-lint run
|
||||
-gometalinter --deadline=60s | sort
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// Util to generate/store passwords for users in a file akin to /etc/passwd
|
||||
// suitable for the xs server, using bcrypt.
|
||||
// suitable for the demo hkexsh server, using bcrypt.
|
||||
//
|
||||
// Copyright (c) 2017-2020 Russell Magee
|
||||
// Copyright (c) 2017-2019 Russell Magee
|
||||
// Licensed under the terms of the MIT license (see LICENSE.mit in this
|
||||
// distribution)
|
||||
//
|
||||
|
@ -59,7 +59,7 @@ func main() {
|
|||
uname = userName
|
||||
|
||||
fmt.Printf("New Password:")
|
||||
ab, err := xs.ReadPassword(os.Stdin.Fd())
|
||||
ab, err := xs.ReadPassword(int(os.Stdin.Fd()))
|
||||
fmt.Printf("\r\n")
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
|
@ -68,7 +68,7 @@ func main() {
|
|||
newpw = string(ab)
|
||||
|
||||
fmt.Printf("Confirm:")
|
||||
ab, err = xs.ReadPassword(os.Stdin.Fd())
|
||||
ab, err = xs.ReadPassword(int(os.Stdin.Fd()))
|
||||
fmt.Printf("\r\n")
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
|
|
Loading…
Reference in New Issue