Last active
October 13, 2016 20:55
-
-
Save hifi/4321ffe9d56612b2449f to your computer and use it in GitHub Desktop.
TigerVNC SSH pipe
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/common/network/Socket.h b/common/network/Socket.h | |
index 378a900..11a4318 100644 | |
--- a/common/network/Socket.h | |
+++ b/common/network/Socket.h | |
@@ -43,7 +43,7 @@ namespace network { | |
} | |
rdr::FdInStream &inStream() {return *instream;} | |
rdr::FdOutStream &outStream() {return *outstream;} | |
- int getFd() {return outstream->getFd();} | |
+ int getFd() {return instream->getFd();} | |
// if shutdown() is overridden then the override MUST call on to here | |
virtual void shutdown() {isShutdown_ = true;} | |
diff --git a/vncviewer/CConn.cxx b/vncviewer/CConn.cxx | |
index f8b45af..f561377 100644 | |
--- a/vncviewer/CConn.cxx | |
+++ b/vncviewer/CConn.cxx | |
@@ -49,6 +49,7 @@ | |
#include "i18n.h" | |
#include "parameters.h" | |
#include "vncviewer.h" | |
+#include "PipeSocket.h" | |
#ifdef WIN32 | |
#include "win32.h" | |
@@ -105,10 +106,14 @@ CConn::CConn(const char* vncServerName, network::Socket* socket=NULL) | |
if(sock == NULL) { | |
try { | |
+#if 0 | |
getHostAndPort(vncServerName, &serverHost, &serverPort); | |
sock = new network::TcpSocket(serverHost, serverPort); | |
vlog.info(_("connected to host %s port %d"), serverHost, serverPort); | |
+#endif | |
+ char *args[] = { "/bin/sh", "-c", (char *)vncServerName, NULL }; | |
+ sock = new PipeSocket(args[0], args); | |
} catch (rdr::Exception& e) { | |
vlog.error("%s", e.str()); | |
fl_alert("%s", e.str()); | |
diff --git a/vncviewer/PipeSocket.h b/vncviewer/PipeSocket.h | |
new file mode 100644 | |
index 0000000..80f0bb8 | |
--- /dev/null | |
+++ b/vncviewer/PipeSocket.h | |
@@ -0,0 +1,48 @@ | |
+#ifndef WIN32 | |
+#include <unistd.h> | |
+#endif | |
+ | |
+#include <network/Socket.h> | |
+ | |
+class PipeSocket : public network::Socket { | |
+ public: | |
+ PipeSocket(const char *path, char *const args[]) { | |
+#ifdef WIN32 | |
+ throw rdr::SystemException(_("pipe is only supported on non-Windows platforms")); | |
+#else | |
+ int stdin_fds[2]; | |
+ int stdout_fds[2]; | |
+ | |
+ pipe(stdin_fds); | |
+ pipe(stdout_fds); | |
+ | |
+ if (fork() == 0) { | |
+ dup2(stdin_fds[0], STDIN_FILENO); | |
+ dup2(stdout_fds[1], STDOUT_FILENO); | |
+ | |
+ close(stdin_fds[1]); | |
+ close(stdout_fds[0]); | |
+ close(STDERR_FILENO); | |
+ | |
+ execv(path, args); | |
+ perror("execv"); | |
+ exit(1); | |
+ } | |
+ | |
+ close(stdin_fds[0]); | |
+ close(stdout_fds[1]); | |
+ | |
+ instream = new rdr::FdInStream(stdout_fds[0]); | |
+ outstream = new rdr::FdOutStream(stdin_fds[1]); | |
+ ownStreams = true; | |
+#endif | |
+ } | |
+ | |
+ int getMyPort() { return 0; }; | |
+ | |
+ char* getPeerAddress() { return "pipe"; }; | |
+ int getPeerPort() { return 0; } | |
+ char* getPeerEndpoint() { return "pipe"; } | |
+ | |
+ bool sameMachine() { return 0; } | |
+}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/perl | |
use strict; | |
use POSIX; | |
use IO::Socket::UNIX; | |
use IO::Select; | |
my $spath = '.Xvnc.sock'; | |
if (!-e $spath) { | |
my $pid; | |
my $server = IO::Socket::UNIX->new( | |
Type => SOCK_STREAM(), | |
Local => $spath, | |
Listen => 1, | |
) or die "Failed to open $spath: $!"; | |
if (!defined($pid = fork())) { | |
die "cannot fork: $!"; | |
} elsif ($pid == 0) { | |
POSIX::dup2($server->fileno(), 0); | |
POSIX::close(1); | |
POSIX::close(2); | |
open STDOUT, '>/dev/null'; | |
open STDERR, '>/dev/null'; | |
system "/usr/bin/xinit", "--", "/usr/bin/Xvnc", "-inetd", "-nolisten", "tcp", "-once", "-SecurityTypes", "none"; | |
unlink $spath; | |
exit; | |
} | |
} | |
my $pipe = IO::Socket::UNIX->new( | |
Type => SOCK_STREAM(), | |
Peer => $spath, | |
) or die; | |
my $select = IO::Select->new(); | |
$select->add(\*STDIN); | |
$select->add($pipe); | |
while (my @ready = $select->can_read()) { | |
foreach my $fh (@ready) { | |
my $buf; | |
if ($fh == \*STDIN) { | |
my $len = sysread STDIN, $buf, 1024; | |
$len > 0 || exit; | |
syswrite $pipe, $buf, $len; | |
} else { | |
my $len = sysread $pipe, $buf, 1024; | |
$len > 0 || exit; | |
syswrite STDOUT, $buf, $len; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment