7 Commits
1.4 ... 1.5

Author SHA1 Message Date
KingToolbox
21662a08f6 Update features and roadmap of version 1.5 2020-08-22 08:02:17 +08:00
KingToolbox
479b939b54 Add a safe encryption class. 2020-07-28 02:05:46 +08:00
KingToolbox
516b5aaa1f Add a scope guard template class. 2020-07-28 01:47:29 +08:00
KingToolbox
067d6e4045 Add a high-performance spin mutex class. 2020-07-28 01:43:10 +08:00
KingToolbox
1ec05ef658 Add a quick circular buffer class. 2020-07-28 01:38:01 +08:00
kingToolbox
822069d840 Add intro video links 2020-07-25 13:33:40 +08:00
kingToolbox
a246c1d81d Update features and todo list 2020-07-21 07:23:02 +08:00
9 changed files with 407 additions and 27 deletions

View File

@@ -1,5 +1,5 @@
# WindTerm
An innovative fast SSH/Telnet/Serial/Shell/sftp client.
A professional SSH/Telnet/Serial/Shell/Sftp client for DevOps.
_Hello WindTerm :rose:, hello world!_
@@ -7,6 +7,7 @@ _Hello WindTerm :rose:, hello world!_
# License
**Completely FREE for commercial and non-commercial use without limitations.**
**All source codes (except thirdparty directory) are provided under the terms of Apache-2.0 license.**
# Introduction
@@ -28,31 +29,41 @@ Main Window:
![MainWindow](https://github.com/kingToolbox/WindTerm/blob/master/images/screenshots/WindTerm.png)
Quick Bar:
![QuickBar](https://github.com/kingToolbox/WindTerm/blob/master/images/screenshots/QuickBar.png)
Split views:
![SplitView](https://github.com/kingToolbox/WindTerm/blob/master/images/screenshots/SplitView.png)
# Features
- **Supports highlighting the opening and closing delimiter, such as (), [], {} and the customed delimiters.**
- **Integrated sftp, scp client, supports download, upload, remove, rename, make new file/directory and so on.**
- **Local and remote modes with vim keybindings. (Using Shift+Enter key to switch between remote and local mode**)
- **Command palette.**
- **Command sender.**
- SSH v2, Telnet, Raw Tcp, Serial, Shell protocols implemented.
- Support vt100, vt220, vt340, vt420, vt520, xterm, xterm-256-colors.
- Support color schemes like vscode.
- Support time stamp, folding, outlining, split views.
- Support unicode, true-color, mouse protocol, etc.
- Support auto wrap mode.
- Support SSH auto login with password, public-key, keyboard-interactive, gssapi-with-mic.
- Support SSH auto execution when session authenticated.
- Support searching and previewing.
- **Supports highlighting the opening and closing delimiter, such as (), [], {} and the customed delimiters.** [Intro Video](https://kingtoolbox.github.io/2020/06/28/pair/)
- **Integrated sftp, scp client, supports download, upload, remove, rename, make new file/directory and so on.** [Intro Video](https://kingtoolbox.github.io/tags/transfer/)
- **Local and remote modes with vim keybindings. (Using Shift+Enter key to switch between remote and local mode**) [Intro Video](https://kingtoolbox.github.io/2020/06/21/keyboard-modes/)
- **Command palette.** [Intro Video](https://kingtoolbox.github.io/tags/command-palette/)
- **Command sender.** [Intro Video](https://kingtoolbox.github.io/tags/sender/)
- **Quick Bar.** [Intro Video](https://kingtoolbox.github.io/2020/08/22/quickbar/)
- **Paste Dialog.** [Intro Video](https://kingtoolbox.github.io/2020/08/22/paste_dialog/)
- SSH v2, Telnet, Raw Tcp, Serial, Shell protocols implemented. [Intro Video](https://kingtoolbox.github.io/2020/01/22/new-session/)
- Supports vt100, vt220, vt340, vt420, vt520, xterm, xterm-256-colors.
- Supports color schemes like vscode. [Intro Video](https://kingtoolbox.github.io/2020/01/23/highlight/)
- Supports time stamp, folding, outlining, split views.
- Supports unicode, true-color, mouse protocol, etc.
- Supports auto wrap mode. [Intro Video](https://kingtoolbox.github.io/2020/01/22/auto-wrap/)
- Supports SSH auto login with password, public-key, keyboard-interactive, gssapi-with-mic. [Intro Video](https://kingtoolbox.github.io/2020/01/23/auto-login/)
- Supports session logging. [Intro Video](https://kingtoolbox.github.io/2020/07/21/logging/)
- Supports SSH auto execution when session authenticated.
- Supports SSH agent forwarding. [Intro Video](https://kingtoolbox.github.io/2020/08/22/ssh_agent_forwarding/)
- Supports X11 forwarding. [Intro Video](https://kingtoolbox.github.io/2020/07/21/x11_forwarding/)
- Supports direct/local port forwarding, reverse/remote port forwarding and dynamic port forwarding. [Intro Video](https://kingtoolbox.github.io/2020/07/21/port_forwarding/)
- Supports searching and previewing. [Intro Video](https://kingtoolbox.github.io/2020/01/22/search-and-mark/)
- Session dialog and session tree.
- Rename and duplicate session.
- Restore last sessions and layouts when restart.
- Rename and duplicate session. [Intro Video](https://kingtoolbox.github.io/tags/tabbar/)
- Restore last sessions and layouts when restart. [Intro Video](https://kingtoolbox.github.io/2020/01/22/restore-sessions/)
- Protocols and terms can be customed.
- All vttest tests have passed except Tektronix 4014.
- High performance, low memory, low latency.
- High performance, low memory, low latency. [Intro Video](https://kingtoolbox.github.io/2020/01/23/windterm-putty-performance/)
# Sftp Performance
@@ -258,30 +269,27 @@ DIGEdit is the text component of WindTerm.
**Release cycle:**
2-3 weeks.
2-4 weeks.
**Next release (Early Julyfor reference only):**
- X11 forwarding
- Port forwarding (Tunnel)
**Next release (Early Septemberfor reference only):**
- Auto complete
- External tools
**Todo list:**
- Protocols:
- Rlogin
- SSH
- X11 Forwarding
- Port forwarding (Tunnel)
- ProxyCommand
- UI:
- Config dialog
- Local filer for cmd, powershell
- Quick command bar.
- Terminal:
- Linux bash
- MacOs bash
- Session:
- Proxy
- Chat mode
- Log and log viewer
- Log viewer
- File transfer:
- ftp, ftps
- Xmodem, Ymodem, Zmodem(sz, rz)

Binary file not shown.

After

Width:  |  Height:  |  Size: 185 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 234 KiB

90
src/CircularBuffer.h Normal file
View File

@@ -0,0 +1,90 @@
/*
* Copyright 2020, WindTerm.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef CIRCULARBUFFER_H
#define CIRCULARBUFFER_H
#pragma once
#include <QtAlgorithms>
#include <QtGlobal>
#define ROUND_UP_POW2(value) { (1 << (32 - qCountLeadingZeroBits(value))) }
template <typename T>
class CircularBuffer {
public:
CircularBuffer(quint32 capacity)
: m_currentIndex(0) {
Q_ASSERT(capacity < (1 << 31));
m_capacity = ROUND_UP_POW2(capacity);
m_mask = m_capacity - 1;
m_buffer = static_cast<qint64 *>(calloc(m_capacity, sizeof(qint64)));
clear();
}
~CircularBuffer() {
free(m_buffer);
m_buffer = nullptr;
}
void append(const T &value) {
m_buffer[++m_currentIndex & m_mask] = value;
}
const T &at(qint64 index) const {
Q_ASSERT(index >= std::max<qint64>(0, m_currentIndex + 1 - m_capacity) && index <= m_currentIndex);
return m_buffer[index & m_mask];
}
int capacity() const { return m_capacity; }
void clear() {
m_currentIndex = -1;
memset(m_buffer, 0xFF, m_capacity * sizeof(qint64));
#ifdef _DEBUG
for (int i = 0; i < m_capacity; i++) {
Q_ASSERT(m_buffer[i] == -1);
}
#endif // _DEBUG
}
qint64 currentIndex() const { return m_currentIndex; }
qint64 minIndex() const { return std::max<qint64>(0, m_currentIndex + 1 - m_capacity); }
const T &operator [](qint64 index) const {
Q_ASSERT(index >= std::max<qint64>(0, m_currentIndex + 1 - m_capacity) && index <= m_currentIndex);
return m_buffer[index & m_mask];
}
private:
T *m_buffer;
qint64 m_currentIndex;
int m_capacity;
int m_mask;
};
class Int64CircularBuffer : public CircularBuffer<qint64> {
public:
Int64CircularBuffer(quint32 capacity)
: CircularBuffer<qint64>(capacity)
{}
};
#endif // CIRCULARBUFFER_H

91
src/Cryptographic.cpp Normal file
View File

@@ -0,0 +1,91 @@
/*
* Copyright 2020, WindTerm.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "Cryptographic.h"
#include <QByteArray>
#include <qpassworddigestor.h>
#include <QRandomGenerator>
#include "openssl/evp.h"
constexpr int AES_256_IV_LENGTH = 16;
constexpr int AES_256_KEY_LENGTH = 32;
constexpr int PBKDF2_LENGTH = AES_256_IV_LENGTH + AES_256_KEY_LENGTH;
constexpr int PBKDF2_ITERATION_COUNT = 100000;
QByteArray Cryptographic::decrypt(const QByteArray &data, const QByteArray &pbkdf2) {
return doCrypt(QByteArray::fromBase64(data), Cryptographic::key(pbkdf2), Cryptographic::iv(pbkdf2), 0);
}
QByteArray Cryptographic::doCrypt(QByteArray data, const QByteArray &key, const QByteArray &iv, int enc) {
QByteArray crypted(data.length() + EVP_MAX_BLOCK_LENGTH, '\0');
int cryptedLength = 0;
int length;
EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new();
EVP_CipherInit_ex(
ctx,
EVP_aes_256_cbc(),
nullptr,
reinterpret_cast<const uchar *>(key.constData()),
reinterpret_cast<const uchar *>(iv.constData()),
enc
);
EVP_CipherUpdate(
ctx,
reinterpret_cast<uchar *>(crypted.data()),
&length,
reinterpret_cast<const uchar *>(data.constData()),
data.length()
);
cryptedLength += length;
EVP_CipherFinal_ex(ctx, reinterpret_cast<uchar *>(crypted.data() + cryptedLength), &length);
cryptedLength += length;
EVP_CIPHER_CTX_free(ctx);
crypted.resize(cryptedLength);
return crypted;
}
QByteArray Cryptographic::encrypt(const QByteArray &data, const QByteArray &pbkdf2) {
QByteArray encrypted = doCrypt(data, Cryptographic::key(pbkdf2), Cryptographic::iv(pbkdf2), 1);
return encrypted.toBase64();
}
QByteArray Cryptographic::iv(const QByteArray &pbkdf2) {
Q_ASSERT(pbkdf2.length() == PBKDF2_LENGTH);
return QByteArray::fromRawData(pbkdf2.constData() + AES_256_KEY_LENGTH, AES_256_IV_LENGTH);
}
QByteArray Cryptographic::key(const QByteArray &pbkdf2) {
Q_ASSERT(pbkdf2.length() == PBKDF2_LENGTH);
return QByteArray::fromRawData(pbkdf2.constData(), AES_256_KEY_LENGTH);
}
QByteArray Cryptographic::pbkdf2(const QByteArray &password, const QByteArray &salt) {
return QPasswordDigestor::deriveKeyPbkdf2(QCryptographicHash::Sha3_512, password, salt, PBKDF2_ITERATION_COUNT, PBKDF2_LENGTH);
}
QByteArray Cryptographic::salt() {
QByteArray number = QByteArray::number(QRandomGenerator::system()->generate64());
QByteArray numberHash = QCryptographicHash::hash(number, QCryptographicHash::Sha512);
return numberHash.toBase64();
}

39
src/Cryptographic.h Normal file
View File

@@ -0,0 +1,39 @@
/*
* Copyright 2020, WindTerm.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef CRYPTOGRAPHIC_H
#define CRYPTOGRAPHIC_H
#pragma once
class QByteArray;
class Cryptographic {
public:
Cryptographic() = default;
static QByteArray decrypt(const QByteArray &data, const QByteArray &pbkdf2);
static QByteArray encrypt(const QByteArray &data, const QByteArray &pbkdf2);
static QByteArray pbkdf2(const QByteArray &password, const QByteArray &salt);
static QByteArray salt();
private:
static QByteArray doCrypt(QByteArray data, const QByteArray &key, const QByteArray &iv, int enc);
static QByteArray iv(const QByteArray &pbkdf2);
static QByteArray key(const QByteArray &pbkdf2);
};
#endif // CRYPTOGRAPHIC_H

View File

@@ -4,6 +4,22 @@
Below is a list of (some) WindTerm components in alphabetical order, along with a brief description of each.
## CircularBuffer.h
A quick circular buffer template class.
## Cryptographic.h/cpp
A very safe encryption class using the PBKDF2-algorithm as defined in RFC 8018. WindTerm uses this class together with the user's master password to protect user data, including passwords, private keys and so on.
## Onigmo
An improved version based on Onigmo 5.13.5. In particular, **the addition of iterator makes it possible to match gap buffer or nonadjacent memory blocks.** Please refer to the sample files for how to use.
An improved version based on Onigmo 5.13.5. In particular, **the addition of iterator makes it possible to match gap buffer or nonadjacent memory blocks.** Please refer to the sample files for how to use.
## ScopeGuard.h
A class of which the sole purpose is to run the function f in its destructor. This is useful for guaranteeing your cleanup code is executed.
## Spin.h
A high-performance spin mutex and locker.

57
src/ScopeGuard.h Normal file
View File

@@ -0,0 +1,57 @@
/*
* Copyright 2020, WindTerm.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef SCOPEGUARD_H
#define SCOPEGUARD_H
class ScopeGuard {
typedef std::function<void()> GuardFunction;
public:
ScopeGuard(GuardFunction acquire, GuardFunction release)
: m_active(true)
, m_release(std::move(release))
{
acquire();
}
~ScopeGuard() {
if (m_active) {
m_release();
}
}
ScopeGuard() = delete;
ScopeGuard(const ScopeGuard &) = delete;
ScopeGuard &operator=(const ScopeGuard &) = delete;
ScopeGuard(ScopeGuard &&other)
: m_active(other.m_active)
, m_release(std::move(other.m_release))
{
other.cancel();
}
void cancel() {
m_active = false;
}
private:
bool m_active;
GuardFunction m_release;
};
#endif // SCOPEGUARD_H

79
src/Spin.h Normal file
View File

@@ -0,0 +1,79 @@
/*
* Copyright 2020, WindTerm.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef SPIN_H
#define SPIN_H
#pragma once
#include <atomic>
#include <thread>
class SpinMutex {
public:
SpinMutex() {
unlock();
}
void yield(size_t nCount) {
if (nCount < 2) {
} else if (nCount < 16) {
std::this_thread::yield();
} else if (nCount < 32) {
std::this_thread::sleep_for(std::chrono::nanoseconds(100));
} else {
std::this_thread::sleep_for(std::chrono::microseconds(10));
}
}
void lock() {
for (size_t i = 0; !try_lock(); i++) {
yield(i);
}
}
void unlock() {
flag.clear(std::memory_order_release);
}
bool try_lock() {
return flag.test_and_set(std::memory_order_acquire) == false;
}
private:
SpinMutex(const SpinMutex &) = delete;
SpinMutex &operator=(const SpinMutex &) = delete;
std::atomic_flag flag;
};
template <typename LockType>
class ThreadLocker {
public:
ThreadLocker(LockType& m_, bool bLock_ = true) : m(m_), bLock(bLock_) {
if (bLock) m.lock();
}
~ThreadLocker() {
if (bLock) m.unlock();
}
private:
LockType& m;
bool bLock;
};
#endif // SPIN_H