Files
koreader/plugins/SSH.koplugin/main.lua
poire-z 850be52177 Keep some menus open when Tap or Hold (#4189)
TouchMenu: added options to menu items with the following defaults:
    keep_menu_open = false
    hold_keep_menu_open = true
So, default for Tap callback is to close menu, and for Hold callback
to keep menu open.
In both cases, provide the TouchMenu instance as the 1st argument to
the callback functions (instead of a refresh_menu_func I added in #3941)
so the callback can do more things, like closing, refreshing,
changing menu items text and re-ordering...

ReaderZooming: show symbol for default (like it was done for
ReaderFont, ReaderHyphenation...)
TextEditor plugin: update the previously opened files list in real
time, so the menu can be kept open and used as the TextEditor main
interface.
SSH plugin: keep menu open and update the Start/Stop state in real time
ReadTimer plugin: tried to do what feels right (but I don't use it)

Also remove forgotten cp in the move/paste file code
2018-09-04 23:55:58 +02:00

190 lines
6.6 KiB
Lua

local DataStorage = require("datastorage")
local Device = require("device")
local InfoMessage = require("ui/widget/infomessage") -- luacheck:ignore
local InputDialog = require("ui/widget/inputdialog")
local UIManager = require("ui/uimanager")
local WidgetContainer = require("ui/widget/container/widgetcontainer")
local ffiutil = require("ffi/util")
local logger = require("logger")
local util = require("util")
local _ = require("gettext")
local T = ffiutil.template
-- This plugin uses a patched dropbear that adds two things:
-- the -n option to bypass password checks
-- reads the authorized_keys file from the relative path: settings/SSH/authorized_keys
local path = DataStorage:getFullDataDir()
if not util.pathExists("dropbear") then
return { disabled = true, }
end
local SSH = WidgetContainer:new{
name = 'SSH',
is_doc_only = false,
}
function SSH:init()
self.SSH_port = G_reader_settings:readSetting("SSH_port") or "2222"
self.allow_no_password = false
self.ui.menu:registerToMainMenu(self)
end
function SSH:start()
local cmd = string.format("%s %s %s %s%s %s",
"./dropbear",
"-E",
"-R",
"-p", self.SSH_port,
"-P /tmp/dropbear_koreader.pid")
if self.allow_no_password then
cmd = string.format("%s %s", cmd, "-n")
end
-- Make a hole in the Kindle's firewall
if Device:isKindle() then
os.execute(string.format("%s %s %s",
"iptables -A INPUT -p tcp --dport", self.SSH_port,
"-m conntrack --ctstate NEW,ESTABLISHED -j ACCEPT"))
os.execute(string.format("%s %s %s",
"iptables -A OUTPUT -p tcp --sport", self.SSH_port,
"-m conntrack --ctstate ESTABLISHED -j ACCEPT"))
end
-- An SSH/telnet server of course needs to be able to manipulate pseudoterminals...
-- Kobo's init scripts fail to set this up...
if Device:isKobo() then
os.execute([[if [ ! -d "/dev/pts" ] ; then
mkdir -p /dev/pts
mount -t devpts devpts /dev/pts
fi]])
end
if not util.pathExists(path.."/settings/SSH/") then
os.execute("mkdir "..path.."/settings/SSH")
end
logger.dbg("[Network] Launching SSH server : ", cmd)
if os.execute(cmd) == 0 then
local info = InfoMessage:new{
timeout = 5,
text = string.format("%s %s \n %s",
_("SSH port: "), self.SSH_port,
Device.retrieveNetworkInfo and Device:retrieveNetworkInfo() or _("Could not retrieve network info.")),
}
UIManager:show(info)
else
local info = InfoMessage:new{
timeout = 5,
text = _("Error"),
}
UIManager:show(info)
end
end
function SSH:isRunning()
return util.pathExists("/tmp/dropbear_koreader.pid")
end
function SSH:stop()
os.execute("cat /tmp/dropbear_koreader.pid | xargs kill")
-- Plug the hole in the Kindle's firewall
if Device:isKindle() then
os.execute(string.format("%s %s %s",
"iptables -D INPUT -p tcp --dport", self.SSH_port,
"-m conntrack --ctstate NEW,ESTABLISHED -j ACCEPT"))
os.execute(string.format("%s %s %s",
"iptables -D OUTPUT -p tcp --sport", self.SSH_port,
"-m conntrack --ctstate ESTABLISHED -j ACCEPT"))
end
end
function SSH:show_port_dialog()
self.port_dialog = InputDialog:new{
title = _("Choose SSH port"),
input = self.SSH_port,
input_type = "number",
input_hint = self.SSH_port,
buttons = {
{
{
text = _("Cancel"),
callback = function()
UIManager:close(self.port_dialog)
end,
},
{
text = _("Save"),
is_enter_default = true,
callback = function()
local value = tonumber(self.port_dialog:getInputText())
if value then
self.SSH_port = value
G_reader_settings:saveSetting("SSH_port", self.SSH_port)
UIManager:close(self.port_dialog)
end
end
},
},
},
}
UIManager:show(self.port_dialog)
self.port_dialog:onShowKeyboard()
end
function SSH:addToMainMenu(menu_items)
menu_items.ssh = {
text = _("SSH server"),
sub_item_table = {
{
text = _("Start SSH server"),
keep_menu_open = true,
callback = function(touchmenu_instance)
self:start()
-- sleeping might not be needed, but it gives the feeling
-- something has been done and feedback is accurate
ffiutil.sleep(1)
touchmenu_instance:updateItems()
end,
enabled_func = function() return not self:isRunning() end,
},
{
text = _("Stop SSH server"),
keep_menu_open = true,
callback = function(touchmenu_instance)
self:stop()
-- sleeping might not be needed, but it gives the feeling
-- something has been done and feedback is accurate
ffiutil.sleep(1)
touchmenu_instance:updateItems()
end,
enabled_func = function() return self:isRunning() end,
},
{
text = _("Change SSH port"),
keep_menu_open = true,
enabled_func = function() return not self:isRunning() end,
callback = function() return self:show_port_dialog() end,
},
{
text = _("Login without password (DANGEROUS)"),
checked_func = function() return self.allow_no_password end,
enabled_func = function() return not self:isRunning() end,
callback = function() self.allow_no_password = not self.allow_no_password end,
},
{
text = _("SSH public key"),
keep_menu_open = true,
callback = function()
local info = InfoMessage:new{
timeout = 60,
text = T(_("Put your public SSH keys in %1"), path.."/settings/SSH/authorized_keys"),
}
UIManager:show(info)
end,
},
}
}
end
return SSH