Compare commits
15 Commits
3e3dbddcae
...
vala-sshwi
| Author | SHA1 | Date | |
|---|---|---|---|
| 6840a25901 | |||
| af24e54ce1 | |||
| 0cd699b2d3 | |||
| a2a0d85e5d | |||
| 8f39f4e907 | |||
|
|
b01b552834 | ||
|
|
e81f5f4238 | ||
|
|
7486d335c4 | ||
|
|
ed2e2dacac | ||
|
|
3d5d14137a | ||
|
|
f44a71c9b5 | ||
|
|
981be0c5d2 | ||
|
|
5ab64e931b | ||
|
|
56fd8ee768 | ||
|
|
bc80b52c84 |
@@ -18,7 +18,8 @@ Major dependencies includes:
|
|||||||
- [iconv-lite](https://github.com/ashtuchkin/iconv-lite), Licensed under MIT license
|
- [iconv-lite](https://github.com/ashtuchkin/iconv-lite), Licensed under MIT license
|
||||||
- [buffer](https://github.com/feross/buffer), Licensed under MIT license
|
- [buffer](https://github.com/feross/buffer), Licensed under MIT license
|
||||||
- [fontfaceobserver](https://github.com/bramstein/fontfaceobserver), [View license](https://github.com/bramstein/fontfaceobserver/blob/master/LICENSE)
|
- [fontfaceobserver](https://github.com/bramstein/fontfaceobserver), [View license](https://github.com/bramstein/fontfaceobserver/blob/master/LICENSE)
|
||||||
- [Nerd Font](https://www.nerdfonts.com/), packaged by [@azurity/pure-nerd-font](http://github.com/azurity/pure-nerd-font)
|
- [Hack Font](https://github.com/source-foundry/Hack), [View license](https://github.com/source-foundry/Hack/blob/master/LICENSE.md)
|
||||||
|
- [Nerd Fonts](https://www.nerdfonts.com/), packaged by [@azurity/pure-nerd-font](http://github.com/azurity/pure-nerd-font)
|
||||||
includes icons from following fonts:
|
includes icons from following fonts:
|
||||||
- [Powerline Extra Symbols](https://github.com/ryanoasis/powerline-extra-symbols), Licensed under MIT license
|
- [Powerline Extra Symbols](https://github.com/ryanoasis/powerline-extra-symbols), Licensed under MIT license
|
||||||
- [Font Awesome](https://github.com/FortAwesome/Font-Awesome), [View license](https://github.com/FortAwesome/Font-Awesome/blob/6.x/LICENSE.txt)
|
- [Font Awesome](https://github.com/FortAwesome/Font-Awesome), [View license](https://github.com/FortAwesome/Font-Awesome/blob/6.x/LICENSE.txt)
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
FROM ubuntu:devel AS base
|
FROM ubuntu:devel AS base
|
||||||
RUN set -ex && \
|
RUN set -ex && \
|
||||||
cd / && \
|
cd / && \
|
||||||
echo '#!/bin/sh' > /try.sh && echo 'res=0; for i in $(seq 0 36); do $@; res=$?; [ $res -eq 0 ] && exit $res || sleep 10; done; exit $res' >> /try.sh && chmod +x /try.sh && \
|
echo '#!/bin/sh' > /try.sh && echo 'res=1; for i in $(seq 0 36); do $@; res=$?; [ $res -eq 0 ] && exit $res || sleep 10; done; exit $res' >> /try.sh && chmod +x /try.sh && \
|
||||||
echo '#!/bin/sh' > /child.sh && echo 'cpid=""; ret=0; i=0; for c in "$@"; do ( (((((eval "$c"; echo $? >&3) | sed "s/^/|-($i) /" >&4) 2>&1 | sed "s/^/|-($i)!/" >&2) 3>&1) | (read xs; exit $xs)) 4>&1) & ppid=$!; cpid="$cpid $ppid"; echo "+ Child $i (PID $ppid): $c ..."; i=$((i+1)); done; for c in $cpid; do wait $c; cret=$?; [ $cret -eq 0 ] && continue; echo "* Child PID $c has failed." >&2; ret=$cret; done; exit $ret' >> /child.sh && chmod +x /child.sh && \
|
echo '#!/bin/sh' > /child.sh && echo 'cpid=""; ret=0; i=0; for c in "$@"; do ( (((((eval "$c"; echo $? >&3) | sed "s/^/|-($i) /" >&4) 2>&1 | sed "s/^/|-($i)!/" >&2) 3>&1) | (read xs; exit $xs)) 4>&1) & ppid=$!; cpid="$cpid $ppid"; echo "+ Child $i (PID $ppid): $c ..."; i=$((i+1)); done; for c in $cpid; do wait $c; cret=$?; [ $cret -eq 0 ] && continue; echo "* Child PID $c has failed." >&2; ret=$cret; done; exit $ret' >> /child.sh && chmod +x /child.sh && \
|
||||||
export PATH=$PATH:/ && \
|
export PATH=$PATH:/ && \
|
||||||
export DEBIAN_FRONTEND=noninteractive && \
|
export DEBIAN_FRONTEND=noninteractive && \
|
||||||
@@ -68,6 +68,7 @@ ENV SSHWIFTY_HOSTNAME= \
|
|||||||
SSHWIFTY_ONLYALLOWPRESETREMOTES=
|
SSHWIFTY_ONLYALLOWPRESETREMOTES=
|
||||||
COPY --from=builder /sshwifty /
|
COPY --from=builder /sshwifty /
|
||||||
COPY . /sshwifty-src
|
COPY . /sshwifty-src
|
||||||
|
RUN apk add --no-cache tzdata
|
||||||
RUN set -ex && \
|
RUN set -ex && \
|
||||||
adduser -D sshwifty && \
|
adduser -D sshwifty && \
|
||||||
chmod +x /sshwifty && \
|
chmod +x /sshwifty && \
|
||||||
|
|||||||
@@ -254,45 +254,45 @@ func (s socket) Get(
|
|||||||
// DO NOT rely on this if you want to secured communitcation, in
|
// DO NOT rely on this if you want to secured communitcation, in
|
||||||
// that case, you need to use HTTPS.
|
// that case, you need to use HTTPS.
|
||||||
//
|
//
|
||||||
readNonce := [socketGCMStandardNonceSize]byte{}
|
// readNonce := [socketGCMStandardNonceSize]byte{}
|
||||||
_, nonceReadErr := io.ReadFull(&wsReader, readNonce[:])
|
// _, nonceReadErr := io.ReadFull(&wsReader, readNonce[:])
|
||||||
|
|
||||||
if nonceReadErr != nil {
|
// if nonceReadErr != nil {
|
||||||
return NewError(http.StatusBadRequest, fmt.Sprintf(
|
// return NewError(http.StatusBadRequest, fmt.Sprintf(
|
||||||
"Unable to read initial client nonce: %s", nonceReadErr.Error()))
|
// "Unable to read initial client nonce: %s", nonceReadErr.Error()))
|
||||||
}
|
// }
|
||||||
|
|
||||||
writeNonce := [socketGCMStandardNonceSize]byte{}
|
// writeNonce := [socketGCMStandardNonceSize]byte{}
|
||||||
nonceReadErr = s.generateNonce(writeNonce[:])
|
// nonceReadErr = s.generateNonce(writeNonce[:])
|
||||||
|
|
||||||
if nonceReadErr != nil {
|
// if nonceReadErr != nil {
|
||||||
return NewError(http.StatusBadRequest, fmt.Sprintf(
|
// return NewError(http.StatusBadRequest, fmt.Sprintf(
|
||||||
"Unable to generate initial server nonce: %s",
|
// "Unable to generate initial server nonce: %s",
|
||||||
nonceReadErr.Error()))
|
// nonceReadErr.Error()))
|
||||||
}
|
// }
|
||||||
|
|
||||||
_, nonceSendErr := wsWriter.Write(writeNonce[:])
|
// _, nonceSendErr := wsWriter.Write(writeNonce[:])
|
||||||
|
|
||||||
if nonceSendErr != nil {
|
// if nonceSendErr != nil {
|
||||||
return NewError(http.StatusBadRequest, fmt.Sprintf(
|
// return NewError(http.StatusBadRequest, fmt.Sprintf(
|
||||||
"Unable to send server nonce to client: %s", nonceSendErr.Error()))
|
// "Unable to send server nonce to client: %s", nonceSendErr.Error()))
|
||||||
}
|
// }
|
||||||
|
|
||||||
cipherKey := s.buildCipherKey(r)
|
// cipherKey := s.buildCipherKey(r)
|
||||||
|
|
||||||
readCipher, writeCipher, cipherCreationErr := s.createCipher(cipherKey[:])
|
// readCipher, writeCipher, cipherCreationErr := s.createCipher(cipherKey[:])
|
||||||
|
|
||||||
if cipherCreationErr != nil {
|
// if cipherCreationErr != nil {
|
||||||
return NewError(http.StatusInternalServerError, fmt.Sprintf(
|
// return NewError(http.StatusInternalServerError, fmt.Sprintf(
|
||||||
"Unable to create cipher: %s", cipherCreationErr.Error()))
|
// "Unable to create cipher: %s", cipherCreationErr.Error()))
|
||||||
}
|
// }
|
||||||
|
|
||||||
// Start service
|
// Start service
|
||||||
const cipherReadBufSize = 4096
|
const cipherReadBufSize = 4096
|
||||||
|
|
||||||
cipherReadBuf := [cipherReadBufSize]byte{}
|
cipherReadBuf := [cipherReadBufSize]byte{}
|
||||||
cipherWriteBuf := [cipherReadBufSize]byte{}
|
cipherWriteBuf := [cipherReadBufSize]byte{}
|
||||||
maxWriteLen := int(cipherReadBufSize) - (writeCipher.Overhead() + 2)
|
maxWriteLen := int(cipherReadBufSize) // - (writeCipher.Overhead() + 2)
|
||||||
|
|
||||||
senderLock := sync.Mutex{}
|
senderLock := sync.Mutex{}
|
||||||
cmdExec, cmdExecErr := s.commander.New(
|
cmdExec, cmdExecErr := s.commander.New(
|
||||||
@@ -301,7 +301,7 @@ func (s socket) Get(
|
|||||||
DialTimeout: s.commonCfg.DecideDialTimeout(s.serverCfg.ReadTimeout),
|
DialTimeout: s.commonCfg.DecideDialTimeout(s.serverCfg.ReadTimeout),
|
||||||
},
|
},
|
||||||
rw.NewFetchReader(func() ([]byte, error) {
|
rw.NewFetchReader(func() ([]byte, error) {
|
||||||
defer s.increaseNonce(readNonce[:])
|
// defer s.increaseNonce(readNonce[:])
|
||||||
|
|
||||||
// Size is unencrypted
|
// Size is unencrypted
|
||||||
_, rErr := io.ReadFull(&wsReader, cipherReadBuf[:2])
|
_, rErr := io.ReadFull(&wsReader, cipherReadBuf[:2])
|
||||||
@@ -326,8 +326,10 @@ func (s socket) Get(
|
|||||||
return nil, rErr
|
return nil, rErr
|
||||||
}
|
}
|
||||||
|
|
||||||
return readCipher.Open(
|
copy(cipherReadBuf[2:], rData)
|
||||||
cipherReadBuf[:0], readNonce[:], rData, nil)
|
return cipherReadBuf[2 : 2+packageSize], nil
|
||||||
|
// return readCipher.Open(
|
||||||
|
// cipherReadBuf[:0], readNonce[:], rData, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
_, rErr = io.ReadFull(&wsReader, cipherReadBuf[:packageSize])
|
_, rErr = io.ReadFull(&wsReader, cipherReadBuf[:packageSize])
|
||||||
@@ -336,11 +338,12 @@ func (s socket) Get(
|
|||||||
return nil, rErr
|
return nil, rErr
|
||||||
}
|
}
|
||||||
|
|
||||||
return readCipher.Open(
|
return cipherReadBuf[:packageSize], nil
|
||||||
cipherReadBuf[:0],
|
// return readCipher.Open(
|
||||||
readNonce[:],
|
// cipherReadBuf[:0],
|
||||||
cipherReadBuf[:packageSize],
|
// readNonce[:],
|
||||||
nil)
|
// cipherReadBuf[:packageSize],
|
||||||
|
// nil)
|
||||||
}),
|
}),
|
||||||
socketPackageWriter{
|
socketPackageWriter{
|
||||||
w: wsWriter,
|
w: wsWriter,
|
||||||
@@ -354,15 +357,18 @@ func (s socket) Get(
|
|||||||
readLen = maxWriteLen
|
readLen = maxWriteLen
|
||||||
}
|
}
|
||||||
|
|
||||||
encrypted := writeCipher.Seal(
|
// encrypted := writeCipher.Seal(
|
||||||
cipherWriteBuf[2:2],
|
// cipherWriteBuf[2:2],
|
||||||
writeNonce[:],
|
// writeNonce[:],
|
||||||
b[start:start+readLen],
|
// b[start:start+readLen],
|
||||||
nil)
|
// nil)
|
||||||
|
|
||||||
s.increaseNonce(writeNonce[:])
|
// s.increaseNonce(writeNonce[:])
|
||||||
|
|
||||||
encryptedSize := uint16(len(encrypted))
|
copy(cipherWriteBuf[2+start:2+start+readLen], b[start:start+readLen])
|
||||||
|
|
||||||
|
// encryptedSize := uint16(len(cipherWriteBuf[2:]))
|
||||||
|
encryptedSize := readLen
|
||||||
|
|
||||||
if encryptedSize <= 0 {
|
if encryptedSize <= 0 {
|
||||||
return ErrSocketInvalidDataPackage
|
return ErrSocketInvalidDataPackage
|
||||||
|
|||||||
21
docker-compose.example.yaml
Normal file
21
docker-compose.example.yaml
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
version: "3.9"
|
||||||
|
|
||||||
|
services:
|
||||||
|
sshwifty:
|
||||||
|
image: sshwifty:dev
|
||||||
|
container_name: sshwifty
|
||||||
|
user: "nobody:nobody"
|
||||||
|
build: ./
|
||||||
|
restart: always
|
||||||
|
# environment:
|
||||||
|
# - SSHWIFTY_SHAREDKEY=WEB_ACCESS_PASSWORD
|
||||||
|
ports:
|
||||||
|
- "127.0.0.1:8182:8182/tcp"
|
||||||
|
stdin_open: true
|
||||||
|
tty: true
|
||||||
|
# deploy:
|
||||||
|
# replicas: 3
|
||||||
|
# resources:
|
||||||
|
# limits:
|
||||||
|
# cpus: '0.3'
|
||||||
|
# memory: 600M
|
||||||
6
go.mod
6
go.mod
@@ -21,7 +21,7 @@ go 1.13
|
|||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/gorilla/websocket v1.5.0
|
github.com/gorilla/websocket v1.5.0
|
||||||
golang.org/x/crypto v0.0.0-20220829220503-c86fa9a7ed90
|
golang.org/x/crypto v0.2.0
|
||||||
golang.org/x/net v0.0.0-20220909164309-bea034e7d591
|
golang.org/x/net v0.2.0
|
||||||
golang.org/x/sys v0.0.0-20220909162455-aba9fc2a8ff2 // indirect
|
golang.org/x/sys v0.2.0 // indirect
|
||||||
)
|
)
|
||||||
|
|||||||
34
go.sum
34
go.sum
@@ -2,6 +2,9 @@ github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0U
|
|||||||
github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||||
github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc=
|
github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc=
|
||||||
github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||||
|
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
||||||
|
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||||
|
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||||
golang.org/x/crypto v0.0.0-20220210151621-f4118a5b28e2 h1:XdAboW3BNMv9ocSCOk/u1MFioZGzCNkiJZ19v9Oe3Ig=
|
golang.org/x/crypto v0.0.0-20220210151621-f4118a5b28e2 h1:XdAboW3BNMv9ocSCOk/u1MFioZGzCNkiJZ19v9Oe3Ig=
|
||||||
golang.org/x/crypto v0.0.0-20220210151621-f4118a5b28e2/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
golang.org/x/crypto v0.0.0-20220210151621-f4118a5b28e2/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||||
golang.org/x/crypto v0.0.0-20220411220226-7b82a4e95df4 h1:kUhD7nTDoI3fVd9G4ORWrbV5NY0liEs/Jg2pv5f+bBA=
|
golang.org/x/crypto v0.0.0-20220411220226-7b82a4e95df4 h1:kUhD7nTDoI3fVd9G4ORWrbV5NY0liEs/Jg2pv5f+bBA=
|
||||||
@@ -16,6 +19,15 @@ golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa h1:zuSxTR4o9y82ebqCUJYNGJ
|
|||||||
golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||||
golang.org/x/crypto v0.0.0-20220829220503-c86fa9a7ed90 h1:Y/gsMcFOcR+6S6f3YeMKl5g+dZMEWqcz5Czj/GWYbkM=
|
golang.org/x/crypto v0.0.0-20220829220503-c86fa9a7ed90 h1:Y/gsMcFOcR+6S6f3YeMKl5g+dZMEWqcz5Czj/GWYbkM=
|
||||||
golang.org/x/crypto v0.0.0-20220829220503-c86fa9a7ed90/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
golang.org/x/crypto v0.0.0-20220829220503-c86fa9a7ed90/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||||
|
golang.org/x/crypto v0.0.0-20220919173607-35f4265a4bc0 h1:a5Yg6ylndHHYJqIPrdq0AhvR6KTvDTAvgBtaidhEevY=
|
||||||
|
golang.org/x/crypto v0.0.0-20220919173607-35f4265a4bc0/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||||
|
golang.org/x/crypto v0.0.0-20220924013350-4ba4fb4dd9e7 h1:WJywXQVIb56P2kAvXeMGTIgQ1ZHQxR60+F9dLsodECc=
|
||||||
|
golang.org/x/crypto v0.0.0-20220924013350-4ba4fb4dd9e7/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||||
|
golang.org/x/crypto v0.2.0 h1:BRXPfhNivWL5Yq0BGQ39a2sW6t44aODpfxkWjYdzewE=
|
||||||
|
golang.org/x/crypto v0.2.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4=
|
||||||
|
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
||||||
|
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
|
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||||
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||||
golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd h1:O7DYs+zxREGLKzKoMQrtrEacpb0ZVXA5rIwylE2Xchk=
|
golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd h1:O7DYs+zxREGLKzKoMQrtrEacpb0ZVXA5rIwylE2Xchk=
|
||||||
golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
|
golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
|
||||||
@@ -27,10 +39,20 @@ golang.org/x/net v0.0.0-20220617184016-355a448f1bc9 h1:Yqz/iviulwKwAREEeUd3nbBFn
|
|||||||
golang.org/x/net v0.0.0-20220617184016-355a448f1bc9/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
golang.org/x/net v0.0.0-20220617184016-355a448f1bc9/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||||
golang.org/x/net v0.0.0-20220708220712-1185a9018129 h1:vucSRfWwTsoXro7P+3Cjlr6flUMtzCwzlvkxEQtHHB0=
|
golang.org/x/net v0.0.0-20220708220712-1185a9018129 h1:vucSRfWwTsoXro7P+3Cjlr6flUMtzCwzlvkxEQtHHB0=
|
||||||
golang.org/x/net v0.0.0-20220708220712-1185a9018129/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
golang.org/x/net v0.0.0-20220708220712-1185a9018129/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||||
|
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||||
golang.org/x/net v0.0.0-20220811182439-13a9a731de15 h1:cik0bxZUSJVDyaHf1hZPSDsU8SZHGQZQMeueXCE7yBQ=
|
golang.org/x/net v0.0.0-20220811182439-13a9a731de15 h1:cik0bxZUSJVDyaHf1hZPSDsU8SZHGQZQMeueXCE7yBQ=
|
||||||
golang.org/x/net v0.0.0-20220811182439-13a9a731de15/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk=
|
golang.org/x/net v0.0.0-20220811182439-13a9a731de15/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk=
|
||||||
golang.org/x/net v0.0.0-20220909164309-bea034e7d591 h1:D0B/7al0LLrVC8aWF4+oxpv/m8bc7ViFfVS8/gXGdqI=
|
golang.org/x/net v0.0.0-20220909164309-bea034e7d591 h1:D0B/7al0LLrVC8aWF4+oxpv/m8bc7ViFfVS8/gXGdqI=
|
||||||
golang.org/x/net v0.0.0-20220909164309-bea034e7d591/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk=
|
golang.org/x/net v0.0.0-20220909164309-bea034e7d591/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk=
|
||||||
|
golang.org/x/net v0.0.0-20220919232410-f2f64ebce3c1 h1:TWZxd/th7FbRSMret2MVQdlI8uT49QEtwZdvJrxjEHU=
|
||||||
|
golang.org/x/net v0.0.0-20220919232410-f2f64ebce3c1/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk=
|
||||||
|
golang.org/x/net v0.0.0-20220923203811-8be639271d50 h1:vKyz8L3zkd+xrMeIaBsQ/MNVPVFSffdaU3ZyYlBGFnI=
|
||||||
|
golang.org/x/net v0.0.0-20220923203811-8be639271d50/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk=
|
||||||
|
golang.org/x/net v0.2.0 h1:sZfSu1wtKLGlWI4ZZayP0ck9Y73K1ynO6gqzTdBVdPU=
|
||||||
|
golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY=
|
||||||
|
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
|
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
|
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
@@ -46,13 +68,25 @@ golang.org/x/sys v0.0.0-20220615213510-4f61da869c0c h1:aFV+BgZ4svzjfabn8ERpuB4JI
|
|||||||
golang.org/x/sys v0.0.0-20220615213510-4f61da869c0c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20220615213510-4f61da869c0c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8 h1:0A+M6Uqn+Eje4kHMK80dtF3JCXC4ykBgQG4Fe06QRhQ=
|
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8 h1:0A+M6Uqn+Eje4kHMK80dtF3JCXC4ykBgQG4Fe06QRhQ=
|
||||||
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
|
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab h1:2QkjZIsXupsJbJIdSjjUOgWK3aEtzyuh2mPt3l/CkeU=
|
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab h1:2QkjZIsXupsJbJIdSjjUOgWK3aEtzyuh2mPt3l/CkeU=
|
||||||
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.0.0-20220909162455-aba9fc2a8ff2 h1:wM1k/lXfpc5HdkJJyW9GELpd8ERGdnh8sMGL6Gzq3Ho=
|
golang.org/x/sys v0.0.0-20220909162455-aba9fc2a8ff2 h1:wM1k/lXfpc5HdkJJyW9GELpd8ERGdnh8sMGL6Gzq3Ho=
|
||||||
golang.org/x/sys v0.0.0-20220909162455-aba9fc2a8ff2/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20220909162455-aba9fc2a8ff2/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
|
golang.org/x/sys v0.0.0-20220919091848-fb04ddd9f9c8 h1:h+EGohizhe9XlX18rfpa8k8RAc5XyaeamM+0VHRd4lc=
|
||||||
|
golang.org/x/sys v0.0.0-20220919091848-fb04ddd9f9c8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
|
golang.org/x/sys v0.2.0 h1:ljd4t30dBnAvMZaQCevtY0xLLD0A+bRZXbgLMLU1F/A=
|
||||||
|
golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||||
|
golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc=
|
||||||
|
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
|
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||||
|
golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
|
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||||
|
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
||||||
|
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
|
|||||||
3657
package-lock.json
generated
3657
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
35
package.json
35
package.json
@@ -5,30 +5,31 @@
|
|||||||
"main": "",
|
"main": "",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@azurity/pure-nerd-font": "1.0.0",
|
"@azurity/pure-nerd-font": "1.0.0",
|
||||||
"@babel/core": "^7.19.0",
|
"@babel/core": "^7.20.2",
|
||||||
"@babel/eslint-parser": "^7.18.9",
|
"@babel/eslint-parser": "^7.19.1",
|
||||||
"@babel/plugin-transform-runtime": "^7.18.10",
|
"@babel/plugin-transform-runtime": "^7.19.6",
|
||||||
"@babel/preset-env": "^7.19.0",
|
"@babel/preset-env": "^7.20.2",
|
||||||
"@babel/register": "^7.18.9",
|
"@babel/register": "^7.18.9",
|
||||||
"@babel/runtime": "^7.19.0",
|
"@babel/runtime": "^7.20.1",
|
||||||
"babel-loader": "^8.2.5",
|
"babel-loader": "^9.1.0",
|
||||||
"buffer": "^6.0.3",
|
"buffer": "^6.0.3",
|
||||||
"clean-webpack-plugin": "^4.0.0",
|
"clean-webpack-plugin": "^4.0.0",
|
||||||
"copy-webpack-plugin": "^11.0.0",
|
"copy-webpack-plugin": "^11.0.0",
|
||||||
"css-loader": "^6.7.1",
|
"css-loader": "^6.7.1",
|
||||||
"css-minimizer-webpack-plugin": "^4.1.0",
|
"css-minimizer-webpack-plugin": "^4.2.2",
|
||||||
"cwebp-bin": "^8.0.0",
|
"cwebp-bin": "^8.0.0",
|
||||||
"eslint": "^8.23.1",
|
"eslint": "^8.27.0",
|
||||||
"eslint-config-prettier": "^8.5.0",
|
"eslint-config-prettier": "^8.5.0",
|
||||||
"eslint-plugin-prettier": "^4.2.1",
|
"eslint-plugin-prettier": "^4.2.1",
|
||||||
"eslint-plugin-vue": "^9.4.0",
|
"eslint-plugin-vue": "^9.7.0",
|
||||||
"eslint-webpack-plugin": "^3.2.0",
|
"eslint-webpack-plugin": "^3.2.0",
|
||||||
"favicons": "^7.0.0",
|
"favicons": "^7.0.2",
|
||||||
"fontfaceobserver": "^2.3.0",
|
"fontfaceobserver": "^2.3.0",
|
||||||
"html-loader": "^4.1.0",
|
"hack-font": "^3.3.0",
|
||||||
|
"html-loader": "^4.2.0",
|
||||||
"html-webpack-plugin": "^5.5.0",
|
"html-webpack-plugin": "^5.5.0",
|
||||||
"iconv-lite": "^0.6.3",
|
"iconv-lite": "^0.6.3",
|
||||||
"image-minimizer-webpack-plugin": "^3.4.0",
|
"image-minimizer-webpack-plugin": "^3.8.0",
|
||||||
"imagemin": "^8.0.1",
|
"imagemin": "^8.0.1",
|
||||||
"imagemin-gifsicle": "^7.0.0",
|
"imagemin-gifsicle": "^7.0.0",
|
||||||
"imagemin-mozjpeg": "^10.0.0",
|
"imagemin-mozjpeg": "^10.0.0",
|
||||||
@@ -36,7 +37,7 @@
|
|||||||
"imagemin-svgo": "^10.0.1",
|
"imagemin-svgo": "^10.0.1",
|
||||||
"imagemin-webp": "^7.0.0",
|
"imagemin-webp": "^7.0.0",
|
||||||
"mini-css-extract-plugin": "^2.6.1",
|
"mini-css-extract-plugin": "^2.6.1",
|
||||||
"mocha": "^10.0.0",
|
"mocha": "^10.1.0",
|
||||||
"normalize.css": "^8.0.1",
|
"normalize.css": "^8.0.1",
|
||||||
"prettier": "^2.7.1",
|
"prettier": "^2.7.1",
|
||||||
"roboto-fontface": "^0.10.0",
|
"roboto-fontface": "^0.10.0",
|
||||||
@@ -45,12 +46,12 @@
|
|||||||
"vue": "^2.6.14",
|
"vue": "^2.6.14",
|
||||||
"vue-loader": "^15.9.8",
|
"vue-loader": "^15.9.8",
|
||||||
"vue-template-compiler": "^2.6.14",
|
"vue-template-compiler": "^2.6.14",
|
||||||
"webpack": "^5.74.0",
|
"webpack": "^5.75.0",
|
||||||
"webpack-cli": "^4.10.0",
|
"webpack-cli": "^4.10.0",
|
||||||
"webpack-favicons": "^1.3.8",
|
"webpack-favicons": "^1.3.8",
|
||||||
"xterm": "^4.19.0",
|
"xterm": "^5.0.0",
|
||||||
"xterm-addon-fit": "^0.5.0",
|
"xterm-addon-fit": "^0.6.0",
|
||||||
"xterm-addon-web-links": "^0.6.0"
|
"xterm-addon-web-links": "^0.7.0"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "NODE_ENV=development webpack --mode=development --config=webpack.config.js --watch",
|
"dev": "NODE_ENV=development webpack --mode=development --config=webpack.config.js --watch",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"HostName": "",
|
"HostName": "",
|
||||||
"SharedKey": "WEB_ACCESS_PASSWORD",
|
"SharedKey": "",
|
||||||
"DialTimeout": 5,
|
"DialTimeout": 5,
|
||||||
"Socks5": "",
|
"Socks5": "",
|
||||||
"Socks5User": "",
|
"Socks5User": "",
|
||||||
|
|||||||
18
ui/app.js
18
ui/app.js
@@ -286,16 +286,16 @@ function startApp(rootEl) {
|
|||||||
clientTime = new Date().getTime(),
|
clientTime = new Date().getTime(),
|
||||||
timeDiff = Math.abs(serverTime - clientTime);
|
timeDiff = Math.abs(serverTime - clientTime);
|
||||||
|
|
||||||
if (timeDiff > maxTimeDiff) {
|
// if (timeDiff > maxTimeDiff) {
|
||||||
this.loadErr =
|
// this.loadErr =
|
||||||
"The time difference between this client " +
|
// "The time difference between this client " +
|
||||||
"and the backend server is beyond operational limit.\r\n\r\n" +
|
// "and the backend server is beyond operational limit.\r\n\r\n" +
|
||||||
"Please try reload the page, and if the problem persisted, " +
|
// "Please try reload the page, and if the problem persisted, " +
|
||||||
"consider to adjust your local time so both the client and " +
|
// "consider to adjust your local time so both the client and " +
|
||||||
"the server are running at same date time";
|
// "the server are running at same date time";
|
||||||
|
|
||||||
return;
|
// return;
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
let self = this;
|
let self = this;
|
||||||
|
|||||||
@@ -20,7 +20,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<div id="home">
|
<div id="home">
|
||||||
<header id="home-header">
|
<header id="home-header">
|
||||||
<h1 id="home-hd-title">Sshwifty</h1>
|
<h1 id="home-hd-title">Vala Terminal</h1>
|
||||||
|
|
||||||
<a id="home-hd-delay" href="javascript:;" @click="showDelayWindow">
|
<a id="home-hd-delay" href="javascript:;" @click="showDelayWindow">
|
||||||
<span
|
<span
|
||||||
@@ -32,7 +32,6 @@
|
|||||||
socket.message
|
socket.message
|
||||||
}}</span>
|
}}</span>
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
<a
|
<a
|
||||||
id="home-hd-plus"
|
id="home-hd-plus"
|
||||||
class="icon icon-plus1"
|
class="icon icon-plus1"
|
||||||
@@ -75,6 +74,8 @@
|
|||||||
servers without downloading any additional software.
|
servers without downloading any additional software.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
<h1>Eli Cohen</h1>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
To get started, click the
|
To get started, click the
|
||||||
<span
|
<span
|
||||||
|
|||||||
@@ -2,14 +2,14 @@ import * as history from "./history.js";
|
|||||||
import { ECHO_FAILED } from "./socket.js";
|
import { ECHO_FAILED } from "./socket.js";
|
||||||
|
|
||||||
export function build(ctx) {
|
export function build(ctx) {
|
||||||
const connectionStatusNotConnected = "Sshwifty is ready to connect";
|
const connectionStatusNotConnected = "Vala Terminal is ready to connect";
|
||||||
const connectionStatusConnecting =
|
const connectionStatusConnecting =
|
||||||
"Connecting to Sshwifty backend server. It should only take " +
|
"Connecting to Vala Terminal backend server. It should only take " +
|
||||||
"less than a second, or two";
|
"less than a second, or two";
|
||||||
const connectionStatusDisconnected =
|
const connectionStatusDisconnected =
|
||||||
"Sshwifty is disconnected from it's backend server";
|
"Vala Terminal is disconnected from it's backend server";
|
||||||
const connectionStatusConnected =
|
const connectionStatusConnected =
|
||||||
"Sshwifty is connected to it's backend server, user interface operational";
|
"Vala Terminal is connected to it's backend server, user interface operational";
|
||||||
const connectionStatusUnmeasurable =
|
const connectionStatusUnmeasurable =
|
||||||
"Unable to measure connection delay. The connection maybe very " +
|
"Unable to measure connection delay. The connection maybe very " +
|
||||||
"busy or already lost";
|
"busy or already lost";
|
||||||
|
|||||||
@@ -20,7 +20,7 @@
|
|||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8" />
|
<meta charset="utf-8" />
|
||||||
<title>Sshwifty Web SSH Client</title>
|
<title>Vala Terminal</title>
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
@@ -28,7 +28,7 @@
|
|||||||
<div id="landing-message">
|
<div id="landing-message">
|
||||||
<div id="landing-message-logo"></div>
|
<div id="landing-message-logo"></div>
|
||||||
|
|
||||||
<h1 id="landing-message-title">Loading Sshwifty</h1>
|
<h1 id="landing-message-title">Loading Vala Terminal</h1>
|
||||||
|
|
||||||
<div id="landing-message-info">
|
<div id="landing-message-info">
|
||||||
<p>
|
<p>
|
||||||
@@ -45,9 +45,6 @@
|
|||||||
Copyright © 2019-2022 Ni Rui <ranqus@gmail.com>
|
Copyright © 2019-2022 Ni Rui <ranqus@gmail.com>
|
||||||
</p>
|
</p>
|
||||||
<p class="copy">
|
<p class="copy">
|
||||||
<a href="https://github.com/nirui/sshwifty" target="blank">
|
|
||||||
Source code
|
|
||||||
</a>
|
|
||||||
|
|
||||||
<a href="/sshwifty/assets/DEPENDENCIES.md" target="blank">
|
<a href="/sshwifty/assets/DEPENDENCIES.md" target="blank">
|
||||||
Third-party
|
Third-party
|
||||||
|
|||||||
30
ui/socket.js
30
ui/socket.js
@@ -36,10 +36,10 @@ class Dial {
|
|||||||
* decrypt socket traffic
|
* decrypt socket traffic
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
constructor(address, timeout, privateKey) {
|
constructor(address, timeout) {
|
||||||
this.address = address;
|
this.address = address;
|
||||||
this.timeout = timeout;
|
this.timeout = timeout;
|
||||||
this.privateKey = privateKey;
|
// this.privateKey = privateKey;
|
||||||
this.keepAliveTicker = null;
|
this.keepAliveTicker = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -205,17 +205,17 @@ class Dial {
|
|||||||
10 // max 10 buffered requests
|
10 // max 10 buffered requests
|
||||||
);
|
);
|
||||||
|
|
||||||
let senderNonce = crypt.generateNonce();
|
// let senderNonce = crypt.generateNonce();
|
||||||
sd.send(senderNonce);
|
// sd.send(senderNonce);
|
||||||
|
|
||||||
let receiverNonce = await reader.readN(rd, crypt.GCMNonceSize);
|
// let receiverNonce = await reader.readN(rd, crypt.GCMNonceSize);
|
||||||
|
|
||||||
let key = await this.buildKey();
|
// let key = await this.buildKey();
|
||||||
|
|
||||||
sdDataConvert = async (rawData) => {
|
sdDataConvert = async (rawData) => {
|
||||||
let encoded = await crypt.encryptGCM(key, senderNonce, rawData);
|
let encoded = rawData; // await crypt.encryptGCM(key, senderNonce, rawData);
|
||||||
|
|
||||||
crypt.increaseNonce(senderNonce);
|
// crypt.increaseNonce(senderNonce);
|
||||||
|
|
||||||
let dataToSend = new Uint8Array(encoded.byteLength + 2);
|
let dataToSend = new Uint8Array(encoded.byteLength + 2);
|
||||||
|
|
||||||
@@ -236,13 +236,13 @@ class Dial {
|
|||||||
dSize <<= 8;
|
dSize <<= 8;
|
||||||
dSize |= dSizeBytes[1];
|
dSize |= dSizeBytes[1];
|
||||||
|
|
||||||
let decoded = await crypt.decryptGCM(
|
// let decoded = await crypt.decryptGCM(
|
||||||
key,
|
// key,
|
||||||
receiverNonce,
|
// receiverNonce,
|
||||||
await reader.readN(rd, dSize)
|
let decoded = await reader.readN(rd, dSize);
|
||||||
);
|
// );
|
||||||
|
|
||||||
crypt.increaseNonce(receiverNonce);
|
// crypt.increaseNonce(receiverNonce);
|
||||||
|
|
||||||
r.feed(
|
r.feed(
|
||||||
new reader.Buffer(new Uint8Array(decoded), () => {}),
|
new reader.Buffer(new Uint8Array(decoded), () => {}),
|
||||||
@@ -276,7 +276,7 @@ export class Socket {
|
|||||||
* @param {number} echoInterval Echo interval
|
* @param {number} echoInterval Echo interval
|
||||||
*/
|
*/
|
||||||
constructor(address, privateKey, timeout, echoInterval) {
|
constructor(address, privateKey, timeout, echoInterval) {
|
||||||
this.dial = new Dial(address, timeout, privateKey);
|
this.dial = new Dial(address, timeout);
|
||||||
this.echoInterval = echoInterval;
|
this.echoInterval = echoInterval;
|
||||||
this.streamHandler = null;
|
this.streamHandler = null;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,19 +19,20 @@
|
|||||||
|
|
||||||
@charset "utf-8";
|
@charset "utf-8";
|
||||||
|
|
||||||
|
@import "~hack-font/build/web/hack.css";
|
||||||
@import "~@azurity/pure-nerd-font/pure-nerd-font.css";
|
@import "~@azurity/pure-nerd-font/pure-nerd-font.css";
|
||||||
|
|
||||||
#connector-resource-preload-control-console {
|
#connector-resource-preload-control-console {
|
||||||
font-family: PureNerdFont;
|
font-family: PureNerdFont, Hack;
|
||||||
}
|
}
|
||||||
#connector-resource-preload-control-console::after {
|
#connector-resource-preload-control-console::after {
|
||||||
content: " ";
|
content: " ";
|
||||||
font-family: PureNerdFont;
|
font-family: PureNerdFont, Hack;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
#connector-resource-preload-control-console::before {
|
#connector-resource-preload-control-console::before {
|
||||||
content: " ";
|
content: " ";
|
||||||
font-family: PureNerdFont;
|
font-family: PureNerdFont, Hack;
|
||||||
font-style: italic;
|
font-style: italic;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -21,7 +21,7 @@
|
|||||||
<div class="screen-console">
|
<div class="screen-console">
|
||||||
<div
|
<div
|
||||||
class="console-console"
|
class="console-console"
|
||||||
:style="'font-family: ' + typeface + ', inherit'"
|
:style="'font-family: ' + typefaces + ', inherit'"
|
||||||
>
|
>
|
||||||
<h2 style="display: none">Console</h2>
|
<h2 style="display: none">Console</h2>
|
||||||
|
|
||||||
@@ -117,15 +117,15 @@ import { consoleScreenKeys } from "./screen_console_keys.js";
|
|||||||
import "./screen_console.css";
|
import "./screen_console.css";
|
||||||
import "xterm/css/xterm.css";
|
import "xterm/css/xterm.css";
|
||||||
|
|
||||||
const termTypeFace = "PureNerdFont";
|
const termTypeFaces = "PureNerdFont, Hack";
|
||||||
const termFallbackTypeFace = "monospace";
|
const termFallbackTypeFace = "\"Cascadia Code\" , monospace";
|
||||||
const termTypeFaceLoadTimeout = 3000;
|
const termTypeFaceLoadTimeout = 3000;
|
||||||
const termTypeFaceLoadError =
|
const termTypeFaceLoadError =
|
||||||
'Remote font "' +
|
'Remote font ' +
|
||||||
termTypeFace +
|
termTypeFaces +
|
||||||
'" is unavailable, using "' +
|
' is unavailable, using ' +
|
||||||
termFallbackTypeFace +
|
termFallbackTypeFace +
|
||||||
'" instead until the remote font is loaded';
|
' instead until the remote font is loaded';
|
||||||
const termDefaultFontSize = 16;
|
const termDefaultFontSize = 16;
|
||||||
const termMinFontSize = 8;
|
const termMinFontSize = 8;
|
||||||
const termMaxFontSize = 36;
|
const termMaxFontSize = 36;
|
||||||
@@ -138,10 +138,11 @@ class Term {
|
|||||||
this.closed = false;
|
this.closed = false;
|
||||||
this.fontSize = termDefaultFontSize;
|
this.fontSize = termDefaultFontSize;
|
||||||
this.term = new Terminal({
|
this.term = new Terminal({
|
||||||
|
allowProposedApi: true,
|
||||||
allowTransparency: false,
|
allowTransparency: false,
|
||||||
cursorBlink: true,
|
cursorBlink: true,
|
||||||
cursorStyle: "block",
|
cursorStyle: "block",
|
||||||
fontFamily: termTypeFace + ", " + termFallbackTypeFace,
|
fontFamily: termTypeFaces + ", " + termFallbackTypeFace,
|
||||||
fontSize: this.fontSize,
|
fontSize: this.fontSize,
|
||||||
logLevel: process.env.NODE_ENV === "development" ? "info" : "off",
|
logLevel: process.env.NODE_ENV === "development" ? "info" : "off",
|
||||||
theme: {
|
theme: {
|
||||||
@@ -154,7 +155,6 @@ class Term {
|
|||||||
if (this.closed) {
|
if (this.closed) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.control.send(data);
|
this.control.send(data);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -162,7 +162,6 @@ class Term {
|
|||||||
if (this.closed) {
|
if (this.closed) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.control.sendBinary(data);
|
this.control.sendBinary(data);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -170,28 +169,23 @@ class Term {
|
|||||||
if (this.closed) {
|
if (this.closed) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!this.control.echo()) {
|
if (!this.control.echo()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const printable =
|
const printable =
|
||||||
!ev.domEvent.altKey &&
|
!ev.domEvent.altKey &&
|
||||||
!ev.domEvent.altGraphKey &&
|
!ev.domEvent.altGraphKey &&
|
||||||
!ev.domEvent.ctrlKey &&
|
!ev.domEvent.ctrlKey &&
|
||||||
!ev.domEvent.metaKey;
|
!ev.domEvent.metaKey;
|
||||||
|
|
||||||
switch (ev.domEvent.key) {
|
switch (ev.domEvent.key) {
|
||||||
case "Enter":
|
case "Enter":
|
||||||
ev.domEvent.preventDefault();
|
ev.domEvent.preventDefault();
|
||||||
this.writeStr("\r\n");
|
this.writeStr("\r\n");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "Backspace":
|
case "Backspace":
|
||||||
ev.domEvent.preventDefault();
|
ev.domEvent.preventDefault();
|
||||||
this.writeStr("\b \b");
|
this.writeStr("\b \b");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
if (printable) {
|
if (printable) {
|
||||||
ev.domEvent.preventDefault();
|
ev.domEvent.preventDefault();
|
||||||
@@ -200,49 +194,6 @@ class Term {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// It seems Xtermjs now handles copy paste by itself, following code is no
|
|
||||||
// longer useful
|
|
||||||
// this.term.attachCustomKeyEventHandler(async (ev) => {
|
|
||||||
// if (this.closed) {
|
|
||||||
// return true;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// if (
|
|
||||||
// ev.type == "keyup" &&
|
|
||||||
// ((ev.key.toLowerCase() === "v" && ev.shiftKey && ev.ctrlKey) ||
|
|
||||||
// (ev.key === "Insert" && ev.shiftKey))
|
|
||||||
// ) {
|
|
||||||
// try {
|
|
||||||
// let text = await window.navigator.clipboard.readText();
|
|
||||||
|
|
||||||
// this.writeEchoStr(text);
|
|
||||||
// } catch (e) {
|
|
||||||
// alert(
|
|
||||||
// "Unable to paste: " +
|
|
||||||
// e +
|
|
||||||
// ". Please try again without using the Control+Shift+V / " +
|
|
||||||
// "Shift+Insert hot key"
|
|
||||||
// );
|
|
||||||
// }
|
|
||||||
// return false;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// if (
|
|
||||||
// ev.type == "keyup" &&
|
|
||||||
// ((ev.key.toLowerCase() === "c" && ev.shiftKey && ev.ctrlKey) ||
|
|
||||||
// (ev.key === "Insert" && ev.ctrlKey))
|
|
||||||
// ) {
|
|
||||||
// try {
|
|
||||||
// window.navigator.clipboard.writeText(this.term.getSelection());
|
|
||||||
// } catch (e) {
|
|
||||||
// alert("Unable to copy: " + e);
|
|
||||||
// }
|
|
||||||
// return false;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// return true;
|
|
||||||
// });
|
|
||||||
|
|
||||||
let resizeDelay = null,
|
let resizeDelay = null,
|
||||||
oldRows = 0,
|
oldRows = 0,
|
||||||
oldCols = 0;
|
oldCols = 0;
|
||||||
@@ -251,30 +202,23 @@ class Term {
|
|||||||
if (this.closed) {
|
if (this.closed) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dim.cols === oldCols && dim.rows === oldRows) {
|
if (dim.cols === oldCols && dim.rows === oldRows) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
oldRows = dim.rows;
|
oldRows = dim.rows;
|
||||||
oldCols = dim.cols;
|
oldCols = dim.cols;
|
||||||
|
|
||||||
if (resizeDelay !== null) {
|
if (resizeDelay !== null) {
|
||||||
clearTimeout(resizeDelay);
|
clearTimeout(resizeDelay);
|
||||||
resizeDelay = null;
|
resizeDelay = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
resizeDelay = setTimeout(() => {
|
resizeDelay = setTimeout(() => {
|
||||||
resizeDelay = null;
|
resizeDelay = null;
|
||||||
|
|
||||||
if (!isNumber(dim.cols) || !isNumber(dim.rows)) {
|
if (!isNumber(dim.cols) || !isNumber(dim.rows)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!dim.cols || !dim.rows) {
|
if (!dim.cols || !dim.rows) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.control.resize({
|
this.control.resize({
|
||||||
rows: dim.rows,
|
rows: dim.rows,
|
||||||
cols: dim.cols,
|
cols: dim.cols,
|
||||||
@@ -287,7 +231,6 @@ class Term {
|
|||||||
if (this.closed) {
|
if (this.closed) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.term.open(root);
|
this.term.open(root);
|
||||||
this.term.loadAddon(this.fit);
|
this.term.loadAddon(this.fit);
|
||||||
this.term.loadAddon(new WebLinksAddon());
|
this.term.loadAddon(new WebLinksAddon());
|
||||||
@@ -304,7 +247,6 @@ class Term {
|
|||||||
// }) {
|
// }) {
|
||||||
// this.term.loadAddon(new WebglAddon());
|
// this.term.loadAddon(new WebglAddon());
|
||||||
// }
|
// }
|
||||||
|
|
||||||
this.refit();
|
this.refit();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -312,7 +254,6 @@ class Term {
|
|||||||
if (this.closed) {
|
if (this.closed) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
this.term.textarea.dispatchEvent(event);
|
this.term.textarea.dispatchEvent(event);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
@@ -324,13 +265,10 @@ class Term {
|
|||||||
if (this.closed) {
|
if (this.closed) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.control.send(d);
|
this.control.send(d);
|
||||||
|
|
||||||
if (!this.control.echo()) {
|
if (!this.control.echo()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.writeStr(d);
|
this.writeStr(d);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -338,7 +276,6 @@ class Term {
|
|||||||
if (this.closed) {
|
if (this.closed) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
this.term.write(d);
|
this.term.write(d);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
@@ -350,7 +287,6 @@ class Term {
|
|||||||
if (this.closed) {
|
if (this.closed) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
this.term.write(d);
|
this.term.write(d);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
@@ -362,7 +298,6 @@ class Term {
|
|||||||
if (this.closed) {
|
if (this.closed) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.term.options.fontFamily = value;
|
this.term.options.fontFamily = value;
|
||||||
this.refit();
|
this.refit();
|
||||||
}
|
}
|
||||||
@@ -371,11 +306,9 @@ class Term {
|
|||||||
if (this.closed) {
|
if (this.closed) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.fontSize >= termMaxFontSize) {
|
if (this.fontSize >= termMaxFontSize) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.fontSize += 2;
|
this.fontSize += 2;
|
||||||
this.term.options.fontSize = this.fontSize;
|
this.term.options.fontSize = this.fontSize;
|
||||||
this.refit();
|
this.refit();
|
||||||
@@ -385,11 +318,9 @@ class Term {
|
|||||||
if (this.closed) {
|
if (this.closed) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.fontSize <= termMinFontSize) {
|
if (this.fontSize <= termMinFontSize) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.fontSize -= 2;
|
this.fontSize -= 2;
|
||||||
this.term.options.fontSize = this.fontSize;
|
this.term.options.fontSize = this.fontSize;
|
||||||
this.refit();
|
this.refit();
|
||||||
@@ -399,7 +330,6 @@ class Term {
|
|||||||
if (this.closed) {
|
if (this.closed) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
this.term.focus();
|
this.term.focus();
|
||||||
this.refit();
|
this.refit();
|
||||||
@@ -412,7 +342,6 @@ class Term {
|
|||||||
if (this.closed) {
|
if (this.closed) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
this.term.blur();
|
this.term.blur();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
@@ -424,7 +353,6 @@ class Term {
|
|||||||
if (this.closed) {
|
if (this.closed) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
this.fit.fit();
|
this.fit.fit();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
@@ -440,9 +368,7 @@ class Term {
|
|||||||
if (this.closed) {
|
if (this.closed) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.closed = true;
|
this.closed = true;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
this.term.dispose();
|
this.term.dispose();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
@@ -490,7 +416,7 @@ export default {
|
|||||||
return {
|
return {
|
||||||
screenKeys: consoleScreenKeys,
|
screenKeys: consoleScreenKeys,
|
||||||
term: new Term(this.control),
|
term: new Term(this.control),
|
||||||
typeface: termTypeFace,
|
typefaces: termTypeFaces,
|
||||||
runner: null,
|
runner: null,
|
||||||
eventHandlers: {
|
eventHandlers: {
|
||||||
keydown: null,
|
keydown: null,
|
||||||
@@ -530,25 +456,22 @@ export default {
|
|||||||
this.deinit();
|
this.deinit();
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
loadRemoteFont(typeface, timeout) {
|
loadRemoteFont(typefaces, timeout) {
|
||||||
return Promise.all([
|
const tfs = typefaces.split(",");
|
||||||
new FontFaceObserver(typeface).load(null, timeout),
|
let observers = [];
|
||||||
new FontFaceObserver(typeface, {
|
for (let v in tfs) {
|
||||||
|
observers.push(new FontFaceObserver(tfs[v].trim()).load(null, timeout))
|
||||||
|
observers.push(new FontFaceObserver(tfs[v].trim(), {
|
||||||
weight: "bold",
|
weight: "bold",
|
||||||
}).load(null, timeout),
|
}).load(null, timeout))
|
||||||
]);
|
}
|
||||||
|
return Promise.all(observers);
|
||||||
},
|
},
|
||||||
async retryLoadRemoteFont(typeface, timeout, onSuccess) {
|
async retryLoadRemoteFont(typefaces, timeout, onSuccess) {
|
||||||
const self = this;
|
const self = this;
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
if (self.term.destroyed()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
onSuccess(await self.loadRemoteFont(typeface, timeout));
|
onSuccess(await self.loadRemoteFont(typefaces, timeout));
|
||||||
|
|
||||||
return;
|
return;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
// Retry
|
// Retry
|
||||||
@@ -557,41 +480,29 @@ export default {
|
|||||||
},
|
},
|
||||||
async openTerm(root, callbacks) {
|
async openTerm(root, callbacks) {
|
||||||
const self = this;
|
const self = this;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await self.loadRemoteFont(termTypeFace, termTypeFaceLoadTimeout);
|
await self.loadRemoteFont(termTypeFaces, termTypeFaceLoadTimeout);
|
||||||
|
|
||||||
if (self.term.destroyed()) {
|
if (self.term.destroyed()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
root.innerHTML = "";
|
root.innerHTML = "";
|
||||||
|
|
||||||
self.term.init(root);
|
self.term.init(root);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
// Ignore
|
// Ignore
|
||||||
}
|
}
|
||||||
|
|
||||||
if (self.term.destroyed()) {
|
if (self.term.destroyed()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
root.innerHTML = "";
|
root.innerHTML = "";
|
||||||
|
|
||||||
callbacks.warn(termTypeFaceLoadError, false);
|
callbacks.warn(termTypeFaceLoadError, false);
|
||||||
|
|
||||||
self.term.setFont(termFallbackTypeFace);
|
self.term.setFont(termFallbackTypeFace);
|
||||||
self.term.init(root);
|
self.term.init(root);
|
||||||
|
self.retryLoadRemoteFont(termTypeFaces, termTypeFaceLoadTimeout, () => {
|
||||||
self.retryLoadRemoteFont(termTypeFace, termTypeFaceLoadTimeout, () => {
|
|
||||||
if (self.term.destroyed()) {
|
if (self.term.destroyed()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
self.term.setFont(termTypeFaces);
|
||||||
self.term.setFont(termTypeFace);
|
|
||||||
|
|
||||||
callbacks.warn(termTypeFaceLoadError, true);
|
callbacks.warn(termTypeFaceLoadError, true);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|||||||
Reference in New Issue
Block a user