-
-
Save hildred/1a869164d85bc5d841c88c2dfb289f5d to your computer and use it in GitHub Desktop.
TigerVNC SSH pipe
This file contains hidden or 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 +107,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); | |
+#else | |
+ char *args[] = { "/bin/sh", "-c", (char *)vncServerName, NULL }; | |
+ sock = new PipeSocket(args[0], args); | |
+#endif | |
} 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 hidden or 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