mirror of
https://github.com/fhem/fhem-mirror.git
synced 2025-04-19 12:46:03 +00:00
01_FHEMWEB.js: add rescueDialog
git-svn-id: https://svn.fhem.de/fhem/trunk@26494 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
parent
fade4763e3
commit
afc7346a5e
@ -189,16 +189,17 @@ FHEMWEB_Initialize($)
|
|||||||
menuEntries
|
menuEntries
|
||||||
mainInputLength
|
mainInputLength
|
||||||
nameDisplay
|
nameDisplay
|
||||||
|
nrAxis
|
||||||
ploteditor:always,onClick,never
|
ploteditor:always,onClick,never
|
||||||
plotfork:1,0
|
plotfork:1,0
|
||||||
plotmode:gnuplot-scroll,gnuplot-scroll-svg,SVG
|
plotmode:gnuplot-scroll,gnuplot-scroll-svg,SVG
|
||||||
plotEmbed:2,1,0
|
plotEmbed:2,1,0
|
||||||
plotsize
|
plotsize
|
||||||
plotWeekStartDay:0,1,2,3,4,5,6
|
plotWeekStartDay:0,1,2,3,4,5,6
|
||||||
nrAxis
|
|
||||||
redirectCmds:0,1
|
redirectCmds:0,1
|
||||||
redirectTo
|
redirectTo
|
||||||
refresh
|
refresh
|
||||||
|
rescueDialog:1,0
|
||||||
reverseLogs:0,1
|
reverseLogs:0,1
|
||||||
roomIcons:textField-long
|
roomIcons:textField-long
|
||||||
showUsedFiles:0,1
|
showUsedFiles:0,1
|
||||||
@ -1247,7 +1248,7 @@ FW_dataAttr()
|
|||||||
addParam($FW_wname, "styleData", "").
|
addParam($FW_wname, "styleData", "").
|
||||||
addParam("global", "language", "EN").
|
addParam("global", "language", "EN").
|
||||||
"data-availableJs='$FW_fhemwebjs' ".
|
"data-availableJs='$FW_fhemwebjs' ".
|
||||||
"data-webName='$FW_wname '";
|
"data-webName='$FW_wname' ";
|
||||||
}
|
}
|
||||||
|
|
||||||
sub
|
sub
|
||||||
@ -1742,27 +1743,44 @@ FW_roomOverview($)
|
|||||||
my $sfx = AttrVal("global", "language", "EN");
|
my $sfx = AttrVal("global", "language", "EN");
|
||||||
$sfx = ($sfx eq "EN" ? "" : "_$sfx");
|
$sfx = ($sfx eq "EN" ? "" : "_$sfx");
|
||||||
my @list = (
|
my @list = (
|
||||||
"Everything", "$FW_ME?room=all",
|
'Everything', "$FW_ME?room=all",
|
||||||
"", "",
|
'', '',
|
||||||
"Commandref", "$FW_ME/docs/commandref${sfx}.html",
|
'Commandref', "$FW_ME/docs/commandref${sfx}.html",
|
||||||
"Remote doc", "http://fhem.de/fhem.html#Documentation",
|
'Remote doc', 'http://fhem.de/fhem.html#Documentation',
|
||||||
"Edit files", "$FW_ME?cmd=style%20list",
|
'Edit files', "$FW_ME?cmd=style%20list",
|
||||||
"Select style", "$FW_ME?cmd=style%20select",
|
'Select style', "$FW_ME?cmd=style%20select",
|
||||||
"Event monitor", "$FW_ME?cmd=style%20eventMonitor",
|
'Event monitor', "$FW_ME?cmd=style%20eventMonitor",
|
||||||
"", "");
|
'', '');
|
||||||
my $lastname = ","; # Avoid double "".
|
|
||||||
|
|
||||||
my $lfn = "Logfile";
|
my $lfn = "Logfile";
|
||||||
if($defs{$lfn}) { # Add the current Logfile to the list if defined
|
if($defs{$lfn}) { # Add the current Logfile to the list if defined
|
||||||
my @l = FW_fileList($defs{$lfn}{logfile},1);
|
my @l = FW_fileList($defs{$lfn}{logfile},1);
|
||||||
my $fn = pop @l;
|
my $fn = pop @l;
|
||||||
splice @list, 4,0, ("Logfile",
|
splice @list, 4,0, ('Logfile',
|
||||||
"$FW_ME/FileLog_logWrapper?dev=$lfn&type=text&file=$fn");
|
"$FW_ME/FileLog_logWrapper?dev=$lfn&type=text&file=$fn");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(AttrVal($FW_wname, 'rescueDialog', undef)) {
|
||||||
|
my $pid = $defs{$FW_wname}{rescuePID};
|
||||||
|
$pid = 0 if(!$pid || !kill(0,$pid));
|
||||||
|
my $key="";
|
||||||
|
|
||||||
|
if(!-r "certs/fhemrescue.pub") {
|
||||||
|
mkdir("certs");
|
||||||
|
`ssh-keygen -N "" -t ed25519 -f certs/fhemrescue`;
|
||||||
|
}
|
||||||
|
if(open(my $fh, "certs/fhemrescue.pub")) {
|
||||||
|
$key = <$fh>;
|
||||||
|
close($fh);
|
||||||
|
}
|
||||||
|
splice @list, @list-2,0, ('Rescue',
|
||||||
|
"javascript:FW_rescueClient(\"$pid\",\"$key\")");
|
||||||
|
}
|
||||||
|
|
||||||
my @me = split(",", AttrVal($FW_wname, "menuEntries", ""));
|
my @me = split(",", AttrVal($FW_wname, "menuEntries", ""));
|
||||||
push @list, @me, "", "" if(@me);
|
push @list, @me, "", "" if(@me);
|
||||||
|
|
||||||
|
my $lastname = ",";
|
||||||
for(my $idx = 0; $idx < @list; $idx+= 2) {
|
for(my $idx = 0; $idx < @list; $idx+= 2) {
|
||||||
next if($FW_hiddenroom{$list[$idx]} || $list[$idx] eq $lastname);
|
next if($FW_hiddenroom{$list[$idx]} || $list[$idx] eq $lastname);
|
||||||
push @list1, $list[$idx];
|
push @list1, $list[$idx];
|
||||||
@ -3445,12 +3463,16 @@ sub
|
|||||||
FW_Set($@)
|
FW_Set($@)
|
||||||
{
|
{
|
||||||
my ($hash, @a) = @_;
|
my ($hash, @a) = @_;
|
||||||
my %cmd = ("rereadicons" => 1, "clearSvgCache" => 1);
|
my %cmd = ("rereadicons" => ":noArg", "clearSvgCache" => ":noArg");
|
||||||
|
if(AttrVal($hash->{NAME}, "rescueDialog", "")) {
|
||||||
|
$cmd{"rescueStart"} = "";
|
||||||
|
$cmd{"rescueTerminate"} = ":noArg";
|
||||||
|
}
|
||||||
|
|
||||||
return "no set value specified" if(@a < 2);
|
return "no set value specified" if(@a < 2);
|
||||||
return ("Unknown argument $a[1], choose one of ".
|
return ("Unknown argument $a[1], choose one of ".
|
||||||
join(" ", map { "$_:noArg" } sort keys %cmd))
|
join(" ", map { "$_$cmd{$_}" } sort keys %cmd))
|
||||||
if(!$cmd{$a[1]});
|
if(!defined($cmd{$a[1]}));
|
||||||
|
|
||||||
if($a[1] eq "rereadicons") {
|
if($a[1] eq "rereadicons") {
|
||||||
my @dirs = keys %FW_icons;
|
my @dirs = keys %FW_icons;
|
||||||
@ -3459,6 +3481,7 @@ FW_Set($@)
|
|||||||
FW_readIcons($d);
|
FW_readIcons($d);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if($a[1] eq "clearSvgCache") {
|
if($a[1] eq "clearSvgCache") {
|
||||||
my $cDir = "$FW_dir/SVGcache";
|
my $cDir = "$FW_dir/SVGcache";
|
||||||
if(opendir(DH, $cDir)) {
|
if(opendir(DH, $cDir)) {
|
||||||
@ -3468,6 +3491,31 @@ FW_Set($@)
|
|||||||
return "Can't open $cDir: $!";
|
return "Can't open $cDir: $!";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if($a[1] eq "rescueStart") {
|
||||||
|
return "error: rescueStart needs two arguments: host and port"
|
||||||
|
if(!$a[2] || !$a[3] || $a[3] !~ m/[0-9]{1,5}/ || $a[3] > 65536);
|
||||||
|
return "error: rescue process is running with PID $hash->{rescuePID}"
|
||||||
|
if($hash->{rescuePID} && kill(0, $hash->{rescuePID}));
|
||||||
|
return "error: certificate certs/fhemrescue is not available"
|
||||||
|
if(! -r "certs/fhemrescue");
|
||||||
|
$hash->{rescuePID} = fhemFork();
|
||||||
|
return "error: cannot fork rescue pid\n"
|
||||||
|
if($hash->{rescuePID} == -1);
|
||||||
|
return undef if($hash->{rescuePID}); # Parent
|
||||||
|
my $cmd = "exec ssh -N -R0.0.0.0:18083:localhost:$hash->{PORT} ".
|
||||||
|
"-i certs/fhemrescue -p$a[3] fhemrescue\@$a[2]";
|
||||||
|
Log 1, "Starting $cmd";
|
||||||
|
exec($cmd);
|
||||||
|
}
|
||||||
|
|
||||||
|
if($a[1] eq "rescueTerminate") {
|
||||||
|
return "error: nothing to terminate"
|
||||||
|
if(!$hash->{rescuePID});
|
||||||
|
kill(15, $hash->{rescuePID});
|
||||||
|
delete($hash->{rescuePID});
|
||||||
|
}
|
||||||
|
|
||||||
return undef;
|
return undef;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4206,6 +4254,48 @@ FW_log($$)
|
|||||||
seconds).
|
seconds).
|
||||||
</li><br>
|
</li><br>
|
||||||
|
|
||||||
|
<a id="FHEMWEB-attr-rescueDialog"></a>
|
||||||
|
<li>rescueDialog<br>
|
||||||
|
If set, show a Rescue link in the menu. The goal is to be able to get
|
||||||
|
help from someone with more knowlege (rescuer), who is then able to
|
||||||
|
remote control this installation.<br>
|
||||||
|
After opening the dialog, a key is shown, which is to be sent to the
|
||||||
|
rescuer. After the rescuer installed the key (see below), the
|
||||||
|
connection can be established, by entering the adress of the
|
||||||
|
rescuers server.<br><br>
|
||||||
|
|
||||||
|
<b>TODO for the rescuer:</b>
|
||||||
|
<ul>
|
||||||
|
<li>Forward a public IP/PORT combination to your SSH server.</li>
|
||||||
|
<li>create a fhemrescue user on this server, and store the key from
|
||||||
|
the client:<br>
|
||||||
|
<ul><code>
|
||||||
|
useradd -d /tmp -s /bin/false fhemrescue<br>
|
||||||
|
echo "KEY_FROM_THE_CLIENT" > /etc/sshd/fhemrescue.auth<br>
|
||||||
|
chown fhemrescue:fhemrescue /etc/sshd/fhemrescue.auth<br>
|
||||||
|
chmod 600 /etc/sshd/fhemrescue.auth
|
||||||
|
</code></ul>
|
||||||
|
</li>
|
||||||
|
<li>Append to /etc/ssh/sshd_config:<br>
|
||||||
|
<ul><code>
|
||||||
|
Match User fhemrescue<br>
|
||||||
|
<ul>
|
||||||
|
AllowTcpForwarding remote<br>
|
||||||
|
PermitTTY no<br>
|
||||||
|
GatewayPorts yes<br>
|
||||||
|
ForceCommand /bin/false<br>
|
||||||
|
AuthorizedKeysFile /etc/ssh/fhemrescue.auth<br>
|
||||||
|
</ul>
|
||||||
|
</code></ul>
|
||||||
|
</li>
|
||||||
|
<li>Restart sshd, e.g. with systemctl restart sshd
|
||||||
|
</li>
|
||||||
|
<li>Tell the client your public IP/PORT.</li>
|
||||||
|
<li>After the client started the connection in the rescue dialog, you
|
||||||
|
can access the clients FHEM via your host, port 18083.</li>
|
||||||
|
</ul>
|
||||||
|
</li><br>
|
||||||
|
|
||||||
<a id="FHEMWEB-attr-reverseLogs"></a>
|
<a id="FHEMWEB-attr-reverseLogs"></a>
|
||||||
<li>reverseLogs<br>
|
<li>reverseLogs<br>
|
||||||
Display the lines from the logfile in a reversed order, newest on the
|
Display the lines from the logfile in a reversed order, newest on the
|
||||||
@ -4987,6 +5077,53 @@ FW_log($$)
|
|||||||
Refresh, z.B. nach 5 Sekunden.
|
Refresh, z.B. nach 5 Sekunden.
|
||||||
</li><br>
|
</li><br>
|
||||||
|
|
||||||
|
<a id="FHEMWEB-attr-rescueDialog"></a>
|
||||||
|
<li>rescueDialog<br>
|
||||||
|
Falls gesetzt, im Menue wird ein Rescue Link angezeigt. Das Ziel ist
|
||||||
|
von jemanden mit mehr Wissen (Retter) Hilfe zu bekommen, indem er die
|
||||||
|
lokale FHEM-Installation fernsteuert.<br>
|
||||||
|
Nach öffnen des Dialogs wird ein Schlüssel angezeigt, was dem
|
||||||
|
Retter zu schicken ist. Nachdem er diesen Schlüssel bei sich
|
||||||
|
installiert hat, muss seine Adresse (Host und Port) im Dialog
|
||||||
|
eingetragen werden. Danach kann er die Verbindung fernsteuern.
|
||||||
|
<br><br>
|
||||||
|
|
||||||
|
<b>TODO für den Retter:</b>
|
||||||
|
<ul>
|
||||||
|
<li>eine öffentliche IP/PORT Kombination zum eigenen SSH Server
|
||||||
|
weiterleiten.</li>
|
||||||
|
|
||||||
|
<li>einen fhemrescue Benutzer auf diesem Server anlegen, und den
|
||||||
|
Schlüssel vom Hilfesuchenden eintragen:<br>
|
||||||
|
<ul><code>
|
||||||
|
useradd -d /tmp -s /bin/false fhemrescue<br>
|
||||||
|
echo "KEY_FROM_THE_CLIENT" > /etc/sshd/fhemrescue.auth<br>
|
||||||
|
chown fhemrescue:fhemrescue /etc/sshd/fhemrescue.auth<br>
|
||||||
|
chmod 600 /etc/sshd/fhemrescue.auth
|
||||||
|
</code></ul>
|
||||||
|
</li>
|
||||||
|
<li>Zu /etc/ssh/sshd_config Folgendes hinzufügen:<br>
|
||||||
|
<ul><code>
|
||||||
|
Match User fhemrescue<br>
|
||||||
|
<ul>
|
||||||
|
AllowTcpForwarding remote<br>
|
||||||
|
PermitTTY no<br>
|
||||||
|
GatewayPorts yes<br>
|
||||||
|
ForceCommand /bin/false<br>
|
||||||
|
AuthorizedKeysFile /etc/ssh/fhemrescue.auth<br>
|
||||||
|
</ul>
|
||||||
|
</code></ul>
|
||||||
|
</li>
|
||||||
|
<li>sshd neu starten, z.Bsp. mit systemctl restart sshd
|
||||||
|
</li>
|
||||||
|
<li>Dem Hilfesuchenden die öffentliche IP/PORT Kombination
|
||||||
|
mitteilen.</li>
|
||||||
|
<li>Nachdem der Hilfesuchende diese Daten eingegeben hat, und die
|
||||||
|
Verbindung gestartet hat, kann die Remote-FHEM-Installation ueber
|
||||||
|
den eigenen SSH-Server, Port 1803 erreicht wedern.</li>
|
||||||
|
</ul>
|
||||||
|
</li><br>
|
||||||
|
|
||||||
<a id="FHEMWEB-attr-reverseLogs"></a>
|
<a id="FHEMWEB-attr-reverseLogs"></a>
|
||||||
<li>reverseLogs<br>
|
<li>reverseLogs<br>
|
||||||
Damit wird das Logfile umsortiert, die neuesten Einträge stehen
|
Damit wird das Logfile umsortiert, die neuesten Einträge stehen
|
||||||
|
@ -2239,6 +2239,56 @@ FW_checkNotifydev(reName)
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function
|
||||||
|
FW_rescueClient(pid, key)
|
||||||
|
{
|
||||||
|
let html='<div id="rescueDialog" style="display:none">';
|
||||||
|
if(!pid || pid == "0") {
|
||||||
|
html += '<b>Key (send it to the rescuer):</b><br>'+
|
||||||
|
(key ? '<code>'+key+'</code>' : 'Not found, generate one first');
|
||||||
|
html += '<br><br>';
|
||||||
|
}
|
||||||
|
|
||||||
|
let buttons = [];
|
||||||
|
|
||||||
|
if(key) {
|
||||||
|
if(pid && pid != "0") {
|
||||||
|
html += "<div>There is a connection with pid "+pid+"</div><br>";
|
||||||
|
buttons.push({
|
||||||
|
text:"Terminate connection",
|
||||||
|
click:function(){
|
||||||
|
FW_cmd(FW_root+
|
||||||
|
"?cmd=set "+$("body").attr("data-webname")+
|
||||||
|
" rescueTerminate&XHR=1");
|
||||||
|
setTimeout(function(){ location.reload() }, 1000);
|
||||||
|
}});
|
||||||
|
|
||||||
|
} else {
|
||||||
|
html += "Address (rescuer will tell you host and port)<br>";
|
||||||
|
html += "<input type='text' size='20' placeholder='host port' >";
|
||||||
|
|
||||||
|
buttons.push({
|
||||||
|
text:"Start connection",
|
||||||
|
click:function(){
|
||||||
|
FW_cmd(FW_root+
|
||||||
|
"?cmd=set "+$("body").attr("data-webname")+" rescueStart "+
|
||||||
|
$("#rescueDialog input").val()+"&XHR=1");
|
||||||
|
setTimeout(function(){ location.reload() }, 1000);
|
||||||
|
}});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
buttons.push({ text:"Cancel", click:function(){ $(this).dialog('close')} });
|
||||||
|
|
||||||
|
$('body').append(html);
|
||||||
|
|
||||||
|
$('#rescueDialog').dialog({
|
||||||
|
modal:true, closeOnEscape:true, width:"auto",
|
||||||
|
close:function(){ $('#rescueDialog').remove(); },
|
||||||
|
buttons:buttons
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
=pod
|
=pod
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user