5 Commits

Author SHA1 Message Date
6840a25901 change udp->tcp 2023-01-11 15:51:33 +02:00
af24e54ce1 return the udp-telnet to tcp-telent with bar 2023-01-11 15:43:04 +02:00
0cd699b2d3 cancel timezone error 2023-01-05 09:46:33 +02:00
a2a0d85e5d add TZ to Dockerfile 2023-01-05 08:03:38 +02:00
8f39f4e907 telnet tcp->udp, https->http 2023-01-04 22:46:11 +02:00
8 changed files with 81 additions and 76 deletions

View File

@@ -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 && \

View File

@@ -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

View File

@@ -1,6 +1,6 @@
{ {
"HostName": "", "HostName": "",
"SharedKey": "WEB_ACCESS_PASSWORD", "SharedKey": "",
"DialTimeout": 5, "DialTimeout": 5,
"Socks5": "", "Socks5": "",
"Socks5User": "", "Socks5User": "",

View File

@@ -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;

View File

@@ -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

View File

@@ -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";

View File

@@ -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 &copy; 2019-2022 Ni Rui &lt;ranqus@gmail.com&gt; Copyright &copy; 2019-2022 Ni Rui &lt;ranqus@gmail.com&gt;
</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

View File

@@ -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;
} }