Index: Makefile =================================================================== --- Makefile (revision 33897) +++ Makefile (working copy) @@ -163,6 +163,7 @@ services/connection_socket.o \ services/service_process.o \ services/service_process_vncviewer.o \ + services/service_process_remote_port_forwarding.o \ services/service.o \ services/service_agent.o \ services/service_tcp.o \ @@ -692,6 +693,8 @@ services/service_process.h \ services/service_process_vncviewer.cc \ services/service_process_vncviewer.h \ + services/service_process_remote_port_forwarding.cc \ + services/service_process_remote_port_forwarding.h \ services/service_unix.cc \ services/service_unix.h \ services/service_unix_win32.cc \ Index: services/service_process.cc =================================================================== --- services/service_process.cc (revision 33897) +++ services/service_process.cc (working copy) @@ -110,7 +110,11 @@ logfile.Log(logname + "[E]: " + stderr_rest + "...", 3); } +void ServiceProcess::onProcessLost() +{ +} + /*! * \brief Callback on each line parser in parseData() * \return true if line is consumed otherwise false @@ -163,6 +167,7 @@ TLUtils::LongToString(ready_fd) + " for service " + me->logname, 4); Fl::remove_fd(ready_fd); + me->onProcessLost(); } else { // Error logfile.Log((string)"ServiceProcess: read error (" + strerror(errno) + @@ -238,6 +243,7 @@ if ((me->stdout_handle == INVALID_HANDLE_VALUE) && (me->stderr_handle == INVALID_HANDLE_VALUE)) { Fl::remove_check(ServiceProcess::check, instance); + me->onProcessLost(); } } Index: services/service_process.h =================================================================== --- services/service_process.h (revision 33897) +++ services/service_process.h (working copy) @@ -43,6 +43,7 @@ string stdout_rest, stderr_rest; string logname; + virtual void onProcessLost(); virtual bool onDataLine(string line, bool is_stderr); virtual void parseData( const char * data, int size, bool is_stderr ); Index: services/service_process_remote_port_forwarding.cc =================================================================== --- services/service_process_remote_port_forwarding.cc (nonexistent) +++ services/service_process_remote_port_forwarding.cc (working copy) @@ -0,0 +1,30 @@ +// -*- mode: C++; c-basic-offset: 4; -*- +// +// Copyright 2018 Cendio AB. +// For more information, see http://www.cendio.com + +#include +#include + +#include "../tlclient_util.h" + +#include "service_process_remote_port_forwarding.h" + +using namespace tcpservices; + +ServiceProcessRemotePortForwarding::ServiceProcessRemotePortForwarding(SSHTunnel *tunnel, int port, + int stdout_fd, int stderr_fd, string logname) + : ServiceProcess::ServiceProcess(stdout_fd, stderr_fd, logname), + tunnel(tunnel), + port(port) +{ +} + +ServiceProcessRemotePortForwarding::~ServiceProcessRemotePortForwarding() +{ +} + +void ServiceProcessRemotePortForwarding::onProcessLost() +{ + tunnel->CancelRemotePortForwarding(port); +} Index: services/service_process_remote_port_forwarding.h =================================================================== --- services/service_process_remote_port_forwarding.h (nonexistent) +++ services/service_process_remote_port_forwarding.h (working copy) @@ -0,0 +1,36 @@ +// -*- mode: C++; c-basic-offset: 4; -*- +// +// Copyright 2018 Cendio AB. +// For more information, see http://www.cendio.com + +#ifndef __SERVICE_PROCESS_REMOTE_PORT_FORWARDING_H__ +#define __SERVICE_PROCESS_REMOTE_PORT_FORWARDING_H__ + +#include +#include "service_process.h" + +#include "../tlclient_ssh.h" + +using std::string; + +namespace tcpservices +{ + +class ServiceProcessRemotePortForwarding : public ServiceProcess +{ + public: + ServiceProcessRemotePortForwarding(SSHTunnel *tunnel, int port, + int stdout_fd, int stderr_fd, string logname); + virtual ~ServiceProcessRemotePortForwarding(); + + protected: + virtual void onProcessLost(); + + private: + SSHTunnel *tunnel; + string address; + int port; +}; + +} +#endif /* __SERVICE_PROCESS_REMOTE_PORT_FORWARDING_H__ */ Index: tlclient_session.cc =================================================================== --- tlclient_session.cc (revision 33897) +++ tlclient_session.cc (working copy) @@ -54,6 +54,7 @@ #include "services/service_lpd.h" #include "services/service_process.h" #include "services/service_process_vncviewer.h" +#include "services/service_process_remote_port_forwarding.h" #ifdef __APPLE__ #include @@ -2175,7 +2176,8 @@ logfile.Log("PulseAudio pid is " + TLUtils::LongToString(pulseaudio_pid), 3); - services.push_back(new ServiceProcess(stdout_fd, stderr_fd, "pulseaudio")); + services.push_back(new ServiceProcessRemotePortForwarding(agent_tunnel, local_pulse_port, + stdout_fd, stderr_fd, "pulseaudio")); oldpath = LD_LIBRARY_PATH "=" + oldpath; putenv(strdup(oldpath.c_str())); @@ -2188,10 +2190,10 @@ } catch (TLException e) { throw TLException(ERR_PULSE_ERROR, string(_("Couldn't start pulseaudio")) + ": " + e.message()); } - services.push_back(new ServiceProcess(pulseproc->hOutputRead, - pulseproc->hErrorRead, - "pulseaudio")); + services.push_back(new ServiceProcessRemotePortForwarding(agent_tunnel, local_pulse_port, + pulseproc->hOutputRead, pulseproc->hErrorRead, "pulseaudio")); + #endif // WIN32 } @@ -2279,7 +2281,8 @@ logfile.Log("smart card daemon pid is " + TLUtils::LongToString(smartcard_pid), 3); - services.push_back(new ServiceProcess(stdout_fd, stderr_fd, "pcsctun")); + services.push_back(new ServiceProcessRemotePortForwarding(agent_tunnel, local_smartcard_port, + stdout_fd, stderr_fd, "pcsctun")); #else @@ -2289,9 +2292,8 @@ } catch (TLException e) { throw TLException(ERR_SMARTCARD_ERROR, string(_("Couldn't start smart card daemon")) + ": " + e.message()); } - services.push_back(new ServiceProcess(smartcard_proc->hOutputRead, - smartcard_proc->hErrorRead, - "pcsctun")); + services.push_back(new ServiceProcessRemotePortForwarding(agent_tunnel, local_smartcard_port, + smartcard_proc->hOutputRead, smartcard_proc->hErrorRead, "pcsctun")); #endif // WIN32 } @@ -2420,7 +2422,8 @@ logfile.Log("unfsd pid is " + TLUtils::LongToString(unfsd_pid), 3); - services.push_back(new ServiceProcess(stdout_fd, stderr_fd, "unfsd")); + services.push_back(new ServiceProcessRemotePortForwarding(agent_tunnel, local_nfs_port, + stdout_fd, stderr_fd, "unfsd")); #else @@ -2430,9 +2433,8 @@ } catch (TLException e) { throw TLException(ERR_PROCESS_ERROR, string(_("Couldn't start unfsd")) + ": " + e.message()); } - services.push_back(new ServiceProcess(unfsd_process->hOutputRead, - unfsd_process->hErrorRead, - "unfsd")); + services.push_back(new ServiceProcessRemotePortForwarding(agent_tunnel, local_nfs_port, + unfsd_process->hOutputRead, unfsd_process->hErrorRead, "unfsd")); #endif /* WIN32 */ @@ -2509,7 +2511,8 @@ logfile.Log("sercd pid is " + TLUtils::LongToString(sercd_pids[devnum]), 3); - services.push_back(new ServiceProcess(stdout_fd, stderr_fd, "sercd")); + services.push_back(new ServiceProcessRemotePortForwarding(agent_tunnel, local_serial_ports[devnum], + stdout_fd, stderr_fd, "sercd")); #else try { // Show console window if loglevel => 5 @@ -2517,9 +2520,9 @@ } catch (TLException e) { throw TLException(ERR_PROCESS_ERROR, string(_("Couldn't start sercd")) + ": " + e.message()); } - services.push_back(new ServiceProcess(sercd_processes[devnum]->hOutputRead, - sercd_processes[devnum]->hErrorRead, - "sercd")); + services.push_back(new ServiceProcessRemotePortForwarding(agent_tunnel, local_serial_ports[devnum], + sercd_processes[devnum]->hOutputRead, + sercd_processes[devnum]->hErrorRead, "sercd")); #endif /* WIN32 */ Index: tlclient_ssh.cc =================================================================== --- tlclient_ssh.cc (revision 33897) +++ tlclient_ssh.cc (working copy) @@ -722,6 +722,11 @@ arg_vector.addArgument("-N"); + // Force pseudo-terminal allocation to be able to use escape + // characters control of the ssh connection. This is used for + // taking down tunnels during an active connection. + arg_vector.addArgument("-t"); + // We disable the standard host key checking so that tlclient // can make all decisions. This allows us to be more flexible // about key storage. @@ -2203,7 +2208,21 @@ return banner; } +/*! + * \brief Cancel an existing remote port-forwarding + \param[in] port, The identifying port + */ +void SSHTunnel::CancelRemotePortForwarding(int port) +{ + int fd; + char buf[512]; + fd = GetSSHStdoutFd(); + + snprintf(buf, sizeof(buf), "~C-KR%d\r\n", port); + write(fd, buf, strlen(buf)); +} + #ifdef FEATURE_SMARTCARD_AUTH bool SSHTunnel::SSHAgentCallback(const char *input, size_t input_len, char *output, size_t *output_len, void *data) Index: tlclient_ssh.h =================================================================== --- tlclient_ssh.h (revision 33897) +++ tlclient_ssh.h (working copy) @@ -91,6 +91,8 @@ void SetIgnoreBanner(string banner); string GetBanner(); + void CancelRemotePortForwarding(int port); + private: enum host_key_status { HOST_OK,