Public Access
The SSH App opens one session to a shell, over libssh (LibSSH-ESP32 5.10.0) on mbedTLS. A server is trusted the first time on its fingerprint, and a changed key is a warning with Cancel selected. The password is typed each time and kept nowhere; or the device makes itself an Ed25519 key, whose public half is shown, written to /ssh/id_ed25519.pub and printed by `ssh status`. lib/term is the terminal: what a shell, less, top, nano and vim send, with sixteen colours, scroll regions, the alternate screen and 100 lines of scrollback. Five text sizes with Ctrl and + or -, from 60x20 to 26x8, told to the far end. The session goes on when the App is left; SSH shows in the Status Bar. `ssh user@host` in the Shell opens the App. Also: - Keys that aren't characters carry Shift, Ctrl and Alt. The terminal needs it, and it makes Ctrl+Fn+up/down in a note and Shift+Tab in Gemini work from the real keyboard. - IRC doesn't try to connect under 60 KB free: started with a session open, its TLS handshake took the heap down to 236 bytes. - libssh's own curve25519 is left out of the build (scripts/libssh_filter.py): libsodium's has the same names. Costs 292 KB of flash and about 50 KB of heap while a session is open; not started under 75 KB free. Docs: guide page, how-to, FAQ, home page, Status Bar, SD card folders, the memory how-to, README, glossary, N1 notes with Q254 to Q266 and the checks. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EhqxQ49eCju4CzKYNjZzwT
72 lines
2.2 KiB
C++
72 lines
2.2 KiB
C++
#pragma once
|
|
|
|
#include <memory>
|
|
#include <string>
|
|
#include <vector>
|
|
|
|
#include "app.h"
|
|
#include "dialog_model.h"
|
|
#include "line_editor.h"
|
|
#include "list_model.h"
|
|
#include "services/ssh_service.h"
|
|
#include "services/storage_service.h"
|
|
#include "settings.h"
|
|
#include "ui/canvas.h"
|
|
|
|
namespace roro {
|
|
|
|
// The SSH App (issue #2, docs/milestones/N1.md): the saved hosts, and a terminal on the one that
|
|
// is connected. Leaving it with Home doesn't end the session; coming back finds it.
|
|
class SshApp : public App {
|
|
public:
|
|
static constexpr const char* kPublicKeyPath = "/ssh/id_ed25519.pub";
|
|
|
|
SshApp(SshService& ssh, Settings& settings, StorageService& storage) : ssh_(ssh), settings_(settings), storage_(storage) {}
|
|
|
|
void onEnter() override;
|
|
bool onKey(const KeyEvent& e) override;
|
|
bool textEntryActive() const override { return view_ == View::Entry || (view_ == View::Session && !dialog_); }
|
|
void help(std::vector<KeyHelp>& out) const override;
|
|
const char* helpTitle() const override;
|
|
void update(uint32_t nowMs) override;
|
|
void draw(Canvas& c) override;
|
|
|
|
// `ssh user@host` from the Shell or a console: "" or why not.
|
|
std::string connectTo(const std::string& target);
|
|
|
|
private:
|
|
enum class View { Hosts, Entry, Session, Key };
|
|
struct Font {
|
|
const lgfx::IFont* font;
|
|
int w, h;
|
|
};
|
|
static const Font kFonts[5];
|
|
|
|
void grid(int& cols, int& rows) const;
|
|
void connect(const term::SshTarget& target);
|
|
void setFont(int index);
|
|
bool sessionKey(const KeyEvent& e);
|
|
void drawHosts(Canvas& c);
|
|
void drawSession(Canvas& c);
|
|
void drawTerminal(Canvas& c);
|
|
void drawKey(Canvas& c);
|
|
void say(const std::string& text);
|
|
void writePublicKey();
|
|
|
|
SshService& ssh_;
|
|
Settings& settings_;
|
|
StorageService& storage_;
|
|
View view_ = View::Hosts;
|
|
ListModel list_{8};
|
|
std::vector<std::string> hosts_;
|
|
LineEditor entry_{96}, password_{96};
|
|
std::unique_ptr<DialogModel> dialog_;
|
|
enum class Ask { None, Trust, NewKey, Forget } ask_ = Ask::None;
|
|
SshService::State shownState_ = SshService::State::Idle;
|
|
std::string message_;
|
|
uint32_t messageMs_ = 0, shownRevision_ = 0, lastDrawMs_ = 0;
|
|
int font_ = 1, scroll_ = 0;
|
|
};
|
|
|
|
} // namespace roro
|