diff --git a/acinclude.m4 b/acinclude.m4 index e9c5a5d..3561e16 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -324,6 +324,48 @@ AC_DEFUN([LOCATE_SPHINX], ]) AC_SUBST(SPHINX_BUILD) +################## +# Locate libssh2 # +################## +AC_DEFUN([LOCATE_LIBSSH2], +[ + AC_ARG_WITH(libssh2, [ --with-libssh2=DIR root directory for libssh2 installation], + [ + if test "$withval" != no + then + LIBSSH2_HOME="$withval" + if test ! -f "${LIBSSH2_HOME}/include/libssh2.h" + then + AC_MSG_ERROR([Could not find your LIBSSH2 installation in ${LIBSSH2_HOME}]) + else + LIBSSH2_INCLUDE=-I${LIBSSH2_HOME}/include + LIBSSH2_LIB=-L${LIBSSH2_HOME}/lib + fi + fi + ], + [ + LIBSSH2_HOME=/usr/local + if test ! -f "${LIBSSH2_HOME}/include/libssh2.h" + then + LIBSSH2_HOME=/usr + if test ! -f "${LIBSSH2_HOME}/include/libssh2.h" + then + LIBSSH2_HOME=/mingw + if test ! -f "${LIBSSH2_HOME}/include/libssh2.h" + then + AC_MSG_ERROR([Could not find your LIBSSH2 installation. You might need to use the --with-libssh2=DIR configure option]) + fi + fi + fi + + LIBSSH2_INCLUDE=-I${LIBSSH2_HOME}/include + LIBSSH2_LIB=-L${LIBSSH2_HOME}/lib + ]) + + CPPFLAGS="${CPPFLAGS} ${LIBSSH2_INCLUDE}" + LDFLAGS="${LDFLAGS} ${LIBSSH2_LIB}" +]) + ######################################## # Enable Database Designer in pgAdmin3 # ######################################## @@ -720,6 +762,42 @@ AC_DEFUN([CHECK_EDB_LIBPQ], AC_SUBST(EDB_LIBPQ) ################################################ +# Check session handshake function in libssh2 # +################################################ +AC_DEFUN([CHECK_LIBSSH2_HANDSHAKE_FUNC], +[ + AC_LANG_SAVE + AC_LANG_C + AC_CHECK_LIB(ssh2, libssh2_session_handshake, [HAVE_LIBSSH2_HANDSHAKE_FUNC=yes], [HAVE_LIBSSH2_HANDSHAKE_FUNC=no]) + AC_LANG_RESTORE +]) +AC_SUBST(LIBSSH2_HANDSHAKE_FUNC) + +################################### +# Check exit function in libssh2 # +################################### +AC_DEFUN([CHECK_LIBSSH2_EXIT_FUNC], +[ + AC_LANG_SAVE + AC_LANG_C + AC_CHECK_LIB(ssh2, libssh2_exit, [HAVE_LIBSSH2_EXIT_FUNC=yes], [HAVE_LIBSSH2_EXIT_FUNC=no]) + AC_LANG_RESTORE +]) +AC_SUBST(LIBSSH2_EXIT_FUNC) + +########################################## +# Check SSL library linked with libssh2 # +########################################## +AC_DEFUN([CHECK_LIBSSH2_CRYPTO_LIBRARY], +[ + AC_LANG_SAVE + AC_LANG_C + AC_CHECK_LIB(ssh2, libssh2_md5, [IS_LIBSSH2_OPENSSL_CRYPTO=yes], [IS_LIBSSH2_OPENSSL_CRYPTO=no]) + AC_LANG_RESTORE +]) +AC_SUBST(LIBSSH2_CRYPTO_LIBRARY) + +################################################ # Check for wxWidgets libraries and headers # ################################################ AC_DEFUN([SETUP_WXWIDGETS], @@ -847,6 +925,18 @@ AC_SUBST(XSLT_CONFIG) AC_SUBST(pgadmin3_LDADD) ######################### +# Setup libssh2 headers # +######################### +AC_DEFUN([SETUP_LIBSSH2], +[ + if test -n "${LIBSSH2_HOME}" + then + pgadmin3_LDADD="${pgadmin3_LDADD} -L$LIBSSH2_HOME/lib -lssh2" + fi +]) +AC_SUBST(pgadmin3_LDADD) + +######################### # Configuration summary # ######################### AC_DEFUN([SUMMARY], @@ -882,6 +972,9 @@ AC_DEFUN([SUMMARY], echo "libxslt xslt-config binary: $XSLT_CONFIG" echo "libxslt version: libxslt "`$XSLT_CONFIG --version` echo + echo "libssh2 include directory: $LIBSSH2_INCLUDE" + echo "libssh2 lib directory: $LIBSSH2_LIB" + echo if test "$HAVE_DATABASEDESIGNER" = yes then echo "Building Database Designer: Yes" diff --git a/configure.ac.in b/configure.ac.in index e05eb0b..c466246 100644 --- a/configure.ac.in +++ b/configure.ac.in @@ -63,6 +63,15 @@ CHECK_LIBXML2 LOCATE_LIBXSLT SETUP_LIBXSLT +LOCATE_LIBSSH2 +SETUP_LIBSSH2 +CHECK_LIBSSH2_HANDSHAKE_FUNC +AM_CONDITIONAL([HAVE_LIBSSH2_HANDSHAKE_FUNC], [test x$HAVE_LIBSSH2_HANDSHAKE_FUNC = xyes]) +CHECK_LIBSSH2_EXIT_FUNC +AM_CONDITIONAL([HAVE_LIBSSH2_EXIT_FUNC], [test x$HAVE_LIBSSH2_EXIT_FUNC = xyes]) +CHECK_LIBSSH2_CRYPTO_LIBRARY +AM_CONDITIONAL([IS_LIBSSH2_OPENSSL_CRYPTO], [test x$IS_LIBSSH2_OPENSSL_CRYPTO = xyes]) + LOCATE_SPHINX AM_CONDITIONAL([SPHINX_BUILD], [test x$SPHINX_BUILD != x]) diff --git a/pgadmin/Makefile.am b/pgadmin/Makefile.am index 9af9354..ba5fbd3 100644 --- a/pgadmin/Makefile.am +++ b/pgadmin/Makefile.am @@ -65,6 +65,18 @@ else __EDB_LIBPQ= endif +if IS_LIBSSH2_OPENSSL_CRYPTO + __IS_LIBSSH2_CYRPTO=-DIS_LIBSSH2_OPENSSL_CRYPTO +endif + +if HAVE_LIBSSH2_EXIT_FUNC + __HAVE_LIBSSH2_EXIT_FUNC=-DHAVE_LIBSSH2_EXIT_FUNC +endif + +if HAVE_LIBSSH2_HANDSHAKE_FUNC + __HAVE_LIBSSH2_HANDSHAKE_FUNC=-DHAVE_LIBSSH2_HANDSHAKE_FUNC +endif + if !APPBUNDLE nobase_dist_pkgdata_DATA = \ @@ -76,7 +88,7 @@ nobase_dist_pkgdata_DATA += \ $(TMP_ui) endif -AM_CPPFLAGS = -DDATA_DIR=\"$(pkgdatadir)/\" -I$(top_srcdir)/pgadmin/include $(__CPPFLAGS) $(__EDB_LIBPQ) +AM_CPPFLAGS = -DDATA_DIR=\"$(pkgdatadir)/\" -I$(top_srcdir)/pgadmin/include $(__CPPFLAGS) $(__EDB_LIBPQ) $(__IS_LIBSSH2_CYRPTO) $(__HAVE_LIBSSH2_EXIT_FUNC) $(__HAVE_LIBSSH2_HANDSHAKE_FUNC) # Automake trys to execute install-exec-hook if it appears anywhere in the file, so we need a dummy # for non-APPBUNDLE cases. diff --git a/pgadmin/dlg/dlgServer.cpp b/pgadmin/dlg/dlgServer.cpp index 2839480..7f4ac6d 100644 --- a/pgadmin/dlg/dlgServer.cpp +++ b/pgadmin/dlg/dlgServer.cpp @@ -54,6 +54,15 @@ #define pickerSSLCrl CTRL_FILEPICKER("pickerSSLCrl") #define chkSSLCompression CTRL_CHECKBOX("chkSSLCompression") +#define chkSSHTunnel CTRL_CHECKBOX("chkSSHTunnel") +#define txtTunnelHost CTRL_TEXT("txtTunnelHost") +#define txtTunnelUsername CTRL_TEXT("txtTunnelUsername") +#define radioBtnPassword CTRL_RADIOBUTTON("radioBtnPassword") +#define radioBtnKeyfile CTRL_RADIOBUTTON("radioBtnKeyfile") +#define txtTunnelPassword CTRL_TEXT("txtTunnelPassword") +#define pickerPublicKeyFile CTRL_FILEPICKER("pickerPublicKeyFile") +#define pickerIdentityFile CTRL_FILEPICKER("pickerIdentityFile") +#define stPublicKeyFile CTRL_STATIC("stPublicKeyFile") BEGIN_EVENT_TABLE(dlgServer, dlgProperty) EVT_NOTEBOOK_PAGE_CHANGED(XRCID("nbNotebook"), dlgServer::OnPageSelect) @@ -80,6 +89,9 @@ BEGIN_EVENT_TABLE(dlgServer, dlgProperty) EVT_COMBOBOX(XRCID("cbGroup"), dlgProperty::OnChange) EVT_CHECKBOX(XRCID("chkSSLCompression"), dlgProperty::OnChange) EVT_BUTTON(wxID_OK, dlgServer::OnOK) + EVT_CHECKBOX(XRCID("chkSSHTunnel"), dlgServer::OnCheckSSHTunnel) + EVT_RADIOBUTTON(XRCID("radioBtnPassword"), dlgServer::OnChangeAuthOption) + EVT_RADIOBUTTON(XRCID("radioBtnKeyfile"), dlgServer::OnChangeAuthOption) END_EVENT_TABLE(); @@ -134,6 +146,15 @@ dlgServer::dlgServer(pgaFactory *f, frmMain *frame, pgServer *node) groupitem = browser->GetNextChild(browser->GetRootItem(), groupcookie); } } + + EnableSSHTunnelControls(false); + radioBtnPassword->SetValue(true); + radioBtnKeyfile->SetValue(false); + +#ifdef IS_LIBSSH2_OPENSSL_CRYPTO + stPublicKeyFile->Show(false); + pickerPublicKeyFile->Show(false); +#endif } @@ -197,6 +218,13 @@ void dlgServer::OnOK(wxCommandEvent &ev) server->SetSSLRootCert(pickerSSLRootCert->GetPath()); server->SetSSLCrl(pickerSSLCrl->GetPath()); server->iSetSSLCompression(chkSSLCompression->GetValue()); + server->iSetSSHTunnel(chkSSHTunnel->GetValue()); + server->SetTunnelHost(txtTunnelHost->GetValue()); + server->SetTunnelUserName(txtTunnelUsername->GetValue()); + server->iSetAuthModePwd(radioBtnPassword->GetValue()); + server->SetTunnelPassword(txtTunnelPassword->GetValue()); + server->SetPublicKeyFile(pickerPublicKeyFile->GetPath()); + server->SetIdentityFile(pickerIdentityFile->GetPath()); wxColour colour = colourPicker->GetColour(); wxString sColour = colour.GetAsString(wxC2S_HTML_SYNTAX); server->iSetColour(sColour); @@ -225,7 +253,14 @@ void dlgServer::OnOK(wxCommandEvent &ev) server->GetRestore(), server->GetSSL(), server->GetColour(), - server->GetGroup()); + server->GetGroup(), + server->GetSSHTunnel(), + server->GetTunnelHost(), + server->GetTunnelUserName(), + server->GetAuthModePwd(), + server->GetTunnelPassword(), + server->GetPublicKeyFile(), + server->GetIdentityFile()); newserver->iSetDbRestriction(server->GetDbRestriction().Trim()); newserver->iSetServiceID(server->GetServiceID().Trim()); newserver->iSetDiscoveryID(server->GetDiscoveryID().Trim()); @@ -413,6 +448,23 @@ int dlgServer::Go(bool modal) chkSSLCompression->SetValue(server->GetSSLCompression()); + chkSSHTunnel->SetValue(server->GetSSHTunnel()); + txtTunnelHost->SetValue(server->GetTunnelHost()); + txtTunnelUsername->SetValue(server->GetTunnelUserName()); + if (server->GetAuthModePwd()) + { + radioBtnPassword->SetValue(true); + radioBtnKeyfile->SetValue(false); + } + else + { + radioBtnPassword->SetValue(false); + radioBtnKeyfile->SetValue(true); + } + txtTunnelPassword->SetValue(server->GetTunnelPassword()); + pickerPublicKeyFile->SetPath(server->GetPublicKeyFile()); + pickerIdentityFile->SetPath(server->GetIdentityFile()); + stPassword->Disable(); txtPassword->Disable(); if (connection) @@ -438,6 +490,17 @@ int dlgServer::Go(bool modal) pickerSSLCrl->Disable(); chkSSLCompression->Disable(); EnableOK(false); + chkSSHTunnel->Enable(false); + EnableSSHTunnelControls(false); + } + else + { + if (server->GetSSHTunnel()) + { + chkSSHTunnel->Enable(true); + EnableSSHTunnelControls(true); + EnableAuthenticationOptions(); + } } } else @@ -467,13 +530,30 @@ wxString dlgServer::GetPassword() pgObject *dlgServer::CreateObject(pgCollection *collection) { wxString name = GetName(); + pgServer *obj = NULL; - pgServer *obj = new pgServer(GetName(), txtHostAddr->GetValue(), txtDescription->GetValue(), - txtService->GetValue(), cbDatabase->GetValue(), - txtUsername->GetValue(), StrToLong(txtPort->GetValue()), - chkTryConnect->GetValue() && chkStorePwd->GetValue(), - txtRolename->GetValue(), chkRestore->GetValue(), cbSSL->GetCurrentSelection(), - colourPicker->GetColourString(), cbGroup->GetValue()); + if (chkSSHTunnel->GetValue()) + { + obj = new pgServer(GetName(), txtHostAddr->GetValue(), txtDescription->GetValue(), + txtService->GetValue(), cbDatabase->GetValue(), + txtUsername->GetValue(), StrToLong(txtPort->GetValue()), + chkTryConnect->GetValue() && chkStorePwd->GetValue(), + txtRolename->GetValue(), chkRestore->GetValue(), cbSSL->GetCurrentSelection(), + colourPicker->GetColourString(), cbGroup->GetValue(), + chkSSHTunnel->GetValue(), txtTunnelHost->GetValue(), txtTunnelUsername->GetValue(), + radioBtnPassword->GetValue(), + txtTunnelPassword->GetValue(), pickerPublicKeyFile->GetPath(), + pickerIdentityFile->GetPath()); + } + else + { + obj = new pgServer(GetName(), txtHostAddr->GetValue(), txtDescription->GetValue(), + txtService->GetValue(), cbDatabase->GetValue(), + txtUsername->GetValue(), StrToLong(txtPort->GetValue()), + chkTryConnect->GetValue() && chkStorePwd->GetValue(), + txtRolename->GetValue(), chkRestore->GetValue(), cbSSL->GetCurrentSelection(), + colourPicker->GetColourString(), cbGroup->GetValue()); + } obj->iSetDbRestriction(txtDbRestriction->GetValue().Trim()); @@ -550,3 +630,46 @@ wxString dlgServer::GetSql() { return wxEmptyString; } + +void dlgServer::OnCheckSSHTunnel(wxCommandEvent &ev) +{ + if (chkSSHTunnel->IsChecked()) + { + EnableSSHTunnelControls(true); + EnableAuthenticationOptions(); + } + else + { + EnableSSHTunnelControls(false); + } +} + +void dlgServer::OnChangeAuthOption(wxCommandEvent &ev) +{ + EnableAuthenticationOptions(); +} + +void dlgServer::EnableSSHTunnelControls(const bool& bEnable) +{ + txtTunnelHost->Enable(bEnable); + txtTunnelUsername->Enable(bEnable); + pickerPublicKeyFile->Enable(bEnable); + pickerIdentityFile->Enable(bEnable); + radioBtnPassword->Enable(bEnable); + radioBtnKeyfile->Enable(bEnable); + txtTunnelPassword->Enable(bEnable); +} + +void dlgServer::EnableAuthenticationOptions() +{ + if (radioBtnPassword->GetValue()) + { + pickerIdentityFile->Enable(false); + pickerPublicKeyFile->Enable(false); + } + else + { + pickerIdentityFile->Enable(true); + pickerPublicKeyFile->Enable(true); + } +} diff --git a/pgadmin/frm/frmMain.cpp b/pgadmin/frm/frmMain.cpp index 12a9e1e..d3ef8bc 100644 --- a/pgadmin/frm/frmMain.cpp +++ b/pgadmin/frm/frmMain.cpp @@ -1195,6 +1195,13 @@ void frmMain::StoreServers() settings->Write(key + wxT("SSLRootCert"), server->GetSSLRootCert()); settings->Write(key + wxT("SSLCrl"), server->GetSSLCrl()); settings->WriteBool(key + wxT("SSLCompression"), server->GetSSLCompression()); + settings->WriteBool(key + wxT("SSHTunnel"), server->GetSSHTunnel()); + settings->Write(key + wxT("TunnelHost"), server->GetTunnelHost()); + settings->Write(key + wxT("TunnelUserName"), server->GetTunnelUserName()); + settings->WriteBool(key + wxT("TunnelModePwd"), server->GetAuthModePwd()); + settings->Write(key + wxT("TunnelPassword"), server->GetTunnelPassword()); + settings->Write(key + wxT("PublicKeyFile"), server->GetPublicKeyFile()); + settings->Write(key + wxT("IdentityFile"), server->GetIdentityFile()); pgCollection *coll = browser->FindCollection(databaseFactory, server->GetId()); if (coll) diff --git a/pgadmin/include/dlg/dlgServer.h b/pgadmin/include/dlg/dlgServer.h index 0fd8f33..71b4dad 100644 --- a/pgadmin/include/dlg/dlgServer.h +++ b/pgadmin/include/dlg/dlgServer.h @@ -46,6 +46,11 @@ private: void OnPageSelect(wxNotebookEvent &event); void OnChangeColour(wxColourPickerEvent &ev); void OnChangeFile(wxFileDirPickerEvent &ev); + void OnCheckSSHTunnel(wxCommandEvent &ev); + void OnChangeAuthOption(wxCommandEvent &ev); + + void EnableSSHTunnelControls(const bool& bEnable); + void EnableAuthenticationOptions(); DECLARE_EVENT_TABLE() }; diff --git a/pgadmin/include/pgAdmin3.h b/pgadmin/include/pgAdmin3.h index 7a9bbdd..9a0f61d 100644 --- a/pgadmin/include/pgAdmin3.h +++ b/pgadmin/include/pgAdmin3.h @@ -19,6 +19,10 @@ #include #include +#ifdef WIN32 +#include +#endif + #include "utils/misc.h" #include #include "ctl/ctlSQLBox.h" diff --git a/pgadmin/include/schema/pgServer.h b/pgadmin/include/schema/pgServer.h index c73cec3..0492e40 100644 --- a/pgadmin/include/schema/pgServer.h +++ b/pgadmin/include/schema/pgServer.h @@ -17,7 +17,7 @@ class frmMain; - +class CSSHTunnelThread; class pgServerFactory : public pgaFactory { @@ -41,7 +41,12 @@ extern pgServerFactory serverFactory; class pgServer : public pgObject { public: - pgServer(const wxString &newServer = wxT(""), const wxString &newHostAddr = wxT(""), const wxString &newDescription = wxT(""), const wxString &newService = wxT(""), const wxString &newDatabase = wxT(""), const wxString &newUsername = wxT(""), int newPort = 5432, bool storePwd = false, const wxString &newRolename = wxT(""), bool restore = true, int sslMode = 0, const wxString &colour = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW).GetAsString(wxC2S_HTML_SYNTAX), const wxString &group = wxEmptyString); + pgServer(const wxString &newServer = wxT(""), const wxString &newHostAddr = wxT(""), const wxString &newDescription = wxT(""), + const wxString &newService = wxT(""), const wxString &newDatabase = wxT(""), const wxString &newUsername = wxT(""), int newPort = 5432, + bool storePwd = false, const wxString &newRolename = wxT(""), bool restore = true, int sslMode = 0, + const wxString &colour = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW).GetAsString(wxC2S_HTML_SYNTAX), const wxString &group = wxEmptyString, + bool sshTunnel = false, const wxString &newTunnelHost = wxEmptyString, const wxString &newTunnelUserName = wxEmptyString, bool authModePwd = true, + const wxString &newTunnelPassword = wxEmptyString, const wxString &newPublicKey = wxEmptyString, const wxString &newIdentityFile = wxEmptyString); ~pgServer(); int GetIconId(); @@ -433,11 +438,86 @@ public: sslcompression = b; } + //SSH Tunnel + bool GetSSHTunnel() const + { + return sshTunnel; + } + void iSetSSHTunnel(const bool b) + { + sshTunnel = b; + } + bool GetAuthModePwd() const + { + return authModePwd; + } + void iSetAuthModePwd(const bool b) + { + authModePwd = b; + } + wxString GetLocalListenHost() const + { + return local_listenhost; + } + void SetLocalListenHost(const wxString &s) + { + local_listenhost = s; + } + int GetLocalListenPort() const + { + return local_listenport; + } + void SetLocalListenPort(int newVal) + { + local_listenport = newVal; + } + wxString GetTunnelHost() const + { + return tunnelHost; + } + void SetTunnelHost(const wxString &s) + { + tunnelHost = s; + } + wxString GetTunnelUserName() const + { + return tunnelUserName; + } + void SetTunnelUserName(const wxString &s) + { + tunnelUserName = s; + } + wxString GetTunnelPassword() const + { + return tunnelPassword; + } + void SetTunnelPassword(const wxString &s) + { + tunnelPassword = s; + } + wxString GetPublicKeyFile() const + { + return publicKeyFile; + } + void SetPublicKeyFile(const wxString &s) + { + publicKeyFile = s; + } + wxString GetIdentityFile() const + { + return identityFile; + } + void SetIdentityFile(const wxString &s) + { + identityFile = s; + } + void ShowDependencies(frmMain *form, ctlListView *Dependencies, const wxString &where = wxEmptyString); void ShowDependents(frmMain *form, ctlListView *referencedBy, const wxString &where = wxEmptyString); private: wxString passwordFilename(); + bool createSSHTunnel(); pgConn *conn; long serverIndex; @@ -460,6 +540,12 @@ private: wxString receiveLoc, replayLoc, replayTimestamp; wxDateTime confLoadedSince; + //SSH Tunnel + CSSHTunnelThread *tunnelObj; + bool sshTunnel, authModePwd; + int local_listenport; + wxString tunnelHost, tunnelUserName, tunnelPassword, publicKeyFile, identityFile, local_listenhost; + #ifdef WIN32 SC_HANDLE scmHandle; SC_HANDLE serviceHandle; @@ -602,4 +688,4 @@ public: bool CheckEnable(pgObject *obj); }; -#endif +#endif \ No newline at end of file diff --git a/pgadmin/include/utils/module.mk b/pgadmin/include/utils/module.mk index bdc8ba4..3d18e95 100644 --- a/pgadmin/include/utils/module.mk +++ b/pgadmin/include/utils/module.mk @@ -22,7 +22,8 @@ pgadmin3_SOURCES += \ $(srcdir)/include/utils/sysProcess.h \ $(srcdir)/include/utils/sysSettings.h \ $(srcdir)/include/utils/utffile.h \ - $(srcdir)/include/utils/macros.h + $(srcdir)/include/utils/macros.h \ + $(srcdir)/include/utils/sshTunnel.h EXTRA_DIST += \ $(srcdir)/include/utils/module.mk diff --git a/pgadmin/include/utils/sshTunnel.h b/pgadmin/include/utils/sshTunnel.h new file mode 100644 index 0000000..860c184 --- /dev/null +++ b/pgadmin/include/utils/sshTunnel.h @@ -0,0 +1,104 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2012, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// sshTunnel.h - Used to create SSH Tunnel +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef __SSH_TUNNELING +#define __SSH_TUNNELING + +#ifdef WIN32 +#include +#undef ssize_t +#define ssize_t SSIZE_T +#else +#include +#include +#include +#include +#include +#include +#endif + +#include + +#include +#include +#include +#include + +enum enAuthenticationMethod +{ + AUTH_NONE = 0, + AUTH_PASSWORD, + AUTH_PUBLICKEY +}; + +class CSSHTunnelThread : + public wxThread +{ +public: + CSSHTunnelThread(const wxString tunnelhost, const wxString remote_desthost, const unsigned int remote_destport, + const wxString username, const wxString password, const wxString publickey, const wxString privatekey, + const enAuthenticationMethod& enAuthMethod); + virtual ~CSSHTunnelThread(void); + virtual void *Entry(); + bool Initialize(); + void Cleanup(); + + wxString GetLocalListenIP() const + { + return m_local_listenip; + } + + unsigned int GetLocalListenPort() const + { + return m_local_listenport; + } + +private: + long resolveDNS(const char * host, wxArrayString &arrIPAddress); + + int m_listensock, m_sock, m_forwardsock; + struct sockaddr_in m_sin; + socklen_t m_sinlen; + LIBSSH2_CHANNEL *m_channel; + LIBSSH2_SESSION *m_session; + + wxString m_publickey; + wxString m_privatekey; + wxString m_username; + wxString m_password; + wxString m_tunnelhost; + wxString m_local_listenip; + wxString m_remote_desthost; + unsigned int m_local_listenport; + unsigned int m_remote_destport; + enAuthenticationMethod m_enAuthMethod; +}; + +class CSubThread : + public wxThread +{ +public: + CSubThread(const struct sockaddr_in sin, const wxString remote_desthost, const unsigned int remote_destport, + LIBSSH2_SESSION *session, LIBSSH2_CHANNEL *channel, int forwardsock); + virtual ~CSubThread(void); + virtual void *Entry(); + +private: + struct sockaddr_in m_sin; + wxString m_remote_desthost; + unsigned int m_remote_destport; + LIBSSH2_SESSION *m_session; + LIBSSH2_CHANNEL *m_channel; + int m_forwardsock; +}; + +#endif diff --git a/pgadmin/pgAdmin3.vcxproj b/pgadmin/pgAdmin3.vcxproj index 521b1e1..391f562 100644 --- a/pgadmin/pgAdmin3.vcxproj +++ b/pgadmin/pgAdmin3.vcxproj @@ -160,8 +160,8 @@ MaxSpeed AnySuitable - $(WXWIN)/lib/vc_dll/mswu/;$(WXWIN)/include;$(WXWIN)/contrib/include;$(PGDIR)/include;$(PGBUILD)/include/;$(PGBUILD)/libxml2/include/;$(PGBUILD)/libxslt/include/;$(PGBUILD)/iconv/include/;include/;$(PGDIR)/include/server;%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_DEPRECATE=1;NDEBUG;WIN32;_WINDOWS;__WINDOWS__;__WIN95__;__WIN32__;WINVER=0x0400;STRICT;__WXMSW__;WXUSINGDLL;wxUSE_UNICODE=1;UNICODE;EMBED_XRC;SSL;HAVE_CONNINFO_PARSE;%(PreprocessorDefinitions) + $(WXWIN)/lib/vc_dll/mswu/;$(WXWIN)/include;$(WXWIN)/contrib/include;$(PGDIR)/include;$(PGBUILD)/include/;$(PGBUILD)/libxml2/include/;$(PGBUILD)/libxslt/include/;$(PGBUILD)/iconv/include/;include/;$(PGDIR)/include/server;$(LIBSSH2)/include;%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_DEPRECATE=1;HAVE_LIBSSH2_HANDSHAKE_FUNC;HAVE_LIBSSH2_EXIT_FUNC;IS_LIBSSH2_OPENSSL_CRYPTO;NDEBUG;WIN32;_WINDOWS;__WINDOWS__;__WIN95__;__WIN32__;WINVER=0x0400;STRICT;__WXMSW__;WXUSINGDLL;wxUSE_UNICODE=1;UNICODE;EMBED_XRC;SSL;HAVE_CONNINFO_PARSE;%(PreprocessorDefinitions) true MultiThreadedDLL true @@ -182,10 +182,10 @@ $(WXWIN)/include;%(AdditionalIncludeDirectories) - wxbase28u.lib;wxbase28u_xml.lib;wxbase28u_net.lib;wxmsw28u_adv.lib;wxmsw28u_core.lib;wxmsw28u_html.lib;wxmsw28u_aui.lib;wxregexu.lib;wxpng.lib;wxzlib.lib;wxjpeg.lib;wxtiff.lib;wxmsw28u_stc.lib;wxmsw28u_xrc.lib;wxexpat.lib;libpq.lib;libxml2.lib;libxslt.lib;iconv.lib;comctl32.lib;rpcrt4.lib;wsock32.lib;winmm.lib;%(AdditionalDependencies) + wxbase28u.lib;wxbase28u_xml.lib;wxbase28u_net.lib;wxmsw28u_adv.lib;wxmsw28u_core.lib;wxmsw28u_html.lib;wxmsw28u_aui.lib;wxregexu.lib;wxpng.lib;wxzlib.lib;wxjpeg.lib;wxtiff.lib;wxmsw28u_stc.lib;wxmsw28u_xrc.lib;wxexpat.lib;libpq.lib;libxml2.lib;libxslt.lib;iconv.lib;comctl32.lib;rpcrt4.lib;ws2_32.lib;winmm.lib;libssh2.lib;%(AdditionalDependencies) .\Release/pgAdmin3.exe true - $(WXWIN)/lib/vc_dll;$(PGDIR)/lib;$(PGBUILD)/lib;$(PGBUILD)/libxml2/lib;$(PGBUILD)/libxslt/lib;$(PGBUILD)/iconv/lib;%(AdditionalLibraryDirectories) + $(WXWIN)/lib/vc_dll;$(PGDIR)/lib;$(PGBUILD)/lib;$(PGBUILD)/libxml2/lib;$(PGBUILD)/libxslt/lib;$(PGBUILD)/iconv/lib;$(LIBSSH2)/win32/Release_dll;%(AdditionalLibraryDirectories) libcd.lib;libcid.lib;msvcrtd.lib;%(IgnoreSpecificDefaultLibraries) true .\Release/pgAdmin3.pdb @@ -273,8 +273,8 @@ Disabled - $(WXWIN)/lib/vc_dll/mswud/;$(WXWIN)/include;$(WXWIN)/contrib/include;$(PGDIR)/include;$(PGBUILD)/include/;$(PGBUILD)/libxml2/include/;$(PGBUILD)/libxslt/include/;$(PGBUILD)/iconv/include/;include/;$(PGDIR)/include/server;%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_DEPRECATE=1;WIN32;_DEBUG;_WINDOWS;__WINDOWS__;__WXMSW__;WXUSINGDLL;DEBUG=1;__WXDEBUG__;__WIN95__;__WIN32__;WINVER=0x0400;STRICT;wxUSE_UNICODE=1;UNICODE;SSL;HAVE_CONNINFO_PARSE;%(PreprocessorDefinitions) + $(WXWIN)/lib/vc_dll/mswud/;$(WXWIN)/include;$(WXWIN)/contrib/include;$(PGDIR)/include;$(PGBUILD)/include/;$(PGBUILD)/libxml2/include/;$(PGBUILD)/libxslt/include/;$(PGBUILD)/iconv/include/;include/;$(PGDIR)/include/server;$(LIBSSH2)/include;%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_DEPRECATE=1;HAVE_LIBSSH2_HANDSHAKE_FUNC;HAVE_LIBSSH2_EXIT_FUNC;IS_LIBSSH2_OPENSSL_CRYPTO;WIN32;_DEBUG;_WINDOWS;__WINDOWS__;__WXMSW__;WXUSINGDLL;DEBUG=1;__WXDEBUG__;__WIN95__;__WIN32__;WINVER=0x0400;STRICT;wxUSE_UNICODE=1;UNICODE;SSL;HAVE_CONNINFO_PARSE;%(PreprocessorDefinitions) true MultiThreadedDebugDLL Use @@ -296,10 +296,10 @@ $(WXWIN)/include;%(AdditionalIncludeDirectories) - wxbase28ud.lib;wxbase28ud_xml.lib;wxbase28ud_net.lib;wxmsw28ud_adv.lib;wxmsw28ud_core.lib;wxmsw28ud_html.lib;wxmsw28ud_aui.lib;wxregexud.lib;wxpngd.lib;wxzlibd.lib;wxjpegd.lib;wxtiffd.lib;wxmsw28ud_stc.lib;wxmsw28ud_xrc.lib;wxexpatd.lib;libpq.lib;libxml2.lib;libxslt.lib;iconv.lib;comctl32.lib;rpcrt4.lib;wsock32.lib;winmm.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;oleaut32.lib;ole32.lib;shell32.lib;odbc32.lib;%(AdditionalDependencies) + wxbase28ud.lib;wxbase28ud_xml.lib;wxbase28ud_net.lib;wxmsw28ud_adv.lib;wxmsw28ud_core.lib;wxmsw28ud_html.lib;wxmsw28ud_aui.lib;wxregexud.lib;wxpngd.lib;wxzlibd.lib;wxjpegd.lib;wxtiffd.lib;wxmsw28ud_stc.lib;wxmsw28ud_xrc.lib;wxexpatd.lib;libpq.lib;libxml2.lib;libxslt.lib;iconv.lib;comctl32.lib;rpcrt4.lib;ws2_32.lib;winmm.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;oleaut32.lib;ole32.lib;shell32.lib;odbc32.lib;libssh2.lib;%(AdditionalDependencies) .\Debug/pgAdmin3.exe true - $(WXWIN)/lib/vc_dll;$(PGDIR)/lib;$(PGBUILD)/lib;$(PGBUILD)/libxml2/lib;$(PGBUILD)/libxslt/lib;$(PGBUILD)/iconv/lib;%(AdditionalLibraryDirectories) + $(WXWIN)/lib/vc_dll;$(PGDIR)/lib;$(PGBUILD)/lib;$(PGBUILD)/libxml2/lib;$(PGBUILD)/libxslt/lib;$(PGBUILD)/iconv/lib;$(LIBSSH2)/win32/Debug_dll;%(AdditionalLibraryDirectories) libcd.lib;libcid.lib;msvcrt.lib;%(IgnoreSpecificDefaultLibraries) true .\Debug/pgAdmin3.pdb @@ -393,8 +393,8 @@ Disabled - $(WXWIN)/lib/vc_dll/mswud/;$(WXWIN)/include;$(WXWIN)/contrib/include;$(PGDIR)/include;$(PGBUILD)/include/;$(PGBUILD)/libxml2/include/;$(PGBUILD)/libxslt/include/;$(PGBUILD)/iconv/include/;include/;$(PGDIR)/include/server;%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_DEPRECATE=1;WIN32;_DEBUG;_WINDOWS;__WINDOWS__;__WXMSW__;WXUSINGDLL;DEBUG=1;__WXDEBUG__;__WIN95__;__WIN32__;WINVER=0x0400;STRICT;wxUSE_UNICODE=1;UNICODE;SSL;HAVE_CONNINFO_PARSE;%(PreprocessorDefinitions) + $(WXWIN)/lib/vc_dll/mswud/;$(WXWIN)/include;$(WXWIN)/contrib/include;$(PGDIR)/include;$(PGBUILD)/include/;$(PGBUILD)/libxml2/include/;$(PGBUILD)/libxslt/include/;$(PGBUILD)/iconv/include/;include/;$(PGDIR)/include/server;$(LIBSSH2)/include;%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_DEPRECATE=1;HAVE_LIBSSH2_HANDSHAKE_FUNC;HAVE_LIBSSH2_EXIT_FUNC;IS_LIBSSH2_OPENSSL_CRYPTO;WIN32;_DEBUG;_WINDOWS;__WINDOWS__;__WXMSW__;WXUSINGDLL;DEBUG=1;__WXDEBUG__;__WIN95__;__WIN32__;WINVER=0x0400;STRICT;wxUSE_UNICODE=1;UNICODE;SSL;HAVE_CONNINFO_PARSE;%(PreprocessorDefinitions) true MultiThreadedDebugDLL Use @@ -416,10 +416,10 @@ $(WXWIN)/include;%(AdditionalIncludeDirectories) - wxbase29ud.lib;wxbase29ud_xml.lib;wxbase29ud_net.lib;wxmsw29ud_adv.lib;wxmsw29ud_core.lib;wxmsw29ud_html.lib;wxmsw29ud_aui.lib;wxregexud.lib;wxpngd.lib;wxzlibd.lib;wxjpegd.lib;wxtiffd.lib;wxmsw29ud_stc.lib;wxmsw29ud_xrc.lib;wxexpatd.lib;libpq.lib;libxml2.lib;libxslt.lib;iconv.lib;comctl32.lib;rpcrt4.lib;wsock32.lib;winmm.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;oleaut32.lib;ole32.lib;shell32.lib;odbc32.lib;%(AdditionalDependencies) + wxbase29ud.lib;wxbase29ud_xml.lib;wxbase29ud_net.lib;wxmsw29ud_adv.lib;wxmsw29ud_core.lib;wxmsw29ud_html.lib;wxmsw29ud_aui.lib;wxregexud.lib;wxpngd.lib;wxzlibd.lib;wxjpegd.lib;wxtiffd.lib;wxmsw29ud_stc.lib;wxmsw29ud_xrc.lib;wxexpatd.lib;libpq.lib;libxml2.lib;libxslt.lib;iconv.lib;comctl32.lib;rpcrt4.lib;ws2_32.lib;winmm.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;oleaut32.lib;ole32.lib;shell32.lib;odbc32.lib;libssh2.lib;%(AdditionalDependencies) .\Debug/pgAdmin3.exe true - $(WXWIN)/lib/vc_dll;$(PGDIR)/lib;$(PGBUILD)/lib;$(PGBUILD)/libxml2/lib;$(PGBUILD)/libxslt/lib;$(PGBUILD)/iconv/lib;%(AdditionalLibraryDirectories) + $(WXWIN)/lib/vc_dll;$(PGDIR)/lib;$(PGBUILD)/lib;$(PGBUILD)/libxml2/lib;$(PGBUILD)/libxslt/lib;$(PGBUILD)/iconv/lib;$(LIBSSH2)/win32/Debug_dll;%(AdditionalLibraryDirectories) libcd.lib;libcid.lib;msvcrt.lib;%(IgnoreSpecificDefaultLibraries) true .\Debug/pgAdmin3.pdb @@ -514,8 +514,8 @@ MaxSpeed AnySuitable - $(WXWIN)/lib/vc_dll/mswu/;$(WXWIN)/include;$(WXWIN)/contrib/include;$(PGDIR)/include;$(PGBUILD)/include/;$(PGBUILD)/libxml2/include/;$(PGBUILD)/libxslt/include/;$(PGBUILD)/iconv/include/;include/;$(PGDIR)/include/server;%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_DEPRECATE=1;NDEBUG;WIN32;_WINDOWS;__WINDOWS__;__WIN95__;__WIN32__;WINVER=0x0400;STRICT;__WXMSW__;WXUSINGDLL;wxUSE_UNICODE=1;UNICODE;EMBED_XRC;SSL;HAVE_CONNINFO_PARSE;%(PreprocessorDefinitions) + $(WXWIN)/lib/vc_dll/mswu/;$(WXWIN)/include;$(WXWIN)/contrib/include;$(PGDIR)/include;$(PGBUILD)/include/;$(PGBUILD)/libxml2/include/;$(PGBUILD)/libxslt/include/;$(PGBUILD)/iconv/include/;include/;$(PGDIR)/include/server;$(LIBSSH2)/include;%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_DEPRECATE=1;HAVE_LIBSSH2_HANDSHAKE_FUNC;HAVE_LIBSSH2_EXIT_FUNC;IS_LIBSSH2_OPENSSL_CRYPTO;NDEBUG;WIN32;_WINDOWS;__WINDOWS__;__WIN95__;__WIN32__;WINVER=0x0400;STRICT;__WXMSW__;WXUSINGDLL;wxUSE_UNICODE=1;UNICODE;EMBED_XRC;SSL;HAVE_CONNINFO_PARSE;%(PreprocessorDefinitions) true MultiThreadedDLL true @@ -536,10 +536,10 @@ $(WXWIN)/include;%(AdditionalIncludeDirectories) - wxbase29u.lib;wxbase29u_xml.lib;wxbase29u_net.lib;wxmsw29u_adv.lib;wxmsw29u_core.lib;wxmsw29u_html.lib;wxmsw29u_aui.lib;wxregexu.lib;wxpng.lib;wxzlib.lib;wxjpeg.lib;wxtiff.lib;wxmsw29u_stc.lib;wxmsw29u_xrc.lib;wxexpat.lib;libpq.lib;libxml2.lib;libxslt.lib;iconv.lib;comctl32.lib;rpcrt4.lib;wsock32.lib;winmm.lib;%(AdditionalDependencies) + wxbase29u.lib;wxbase29u_xml.lib;wxbase29u_net.lib;wxmsw29u_adv.lib;wxmsw29u_core.lib;wxmsw29u_html.lib;wxmsw29u_aui.lib;wxregexu.lib;wxpng.lib;wxzlib.lib;wxjpeg.lib;wxtiff.lib;wxmsw29u_stc.lib;wxmsw29u_xrc.lib;wxexpat.lib;libpq.lib;libxml2.lib;libxslt.lib;iconv.lib;comctl32.lib;rpcrt4.lib;ws2_32.lib;winmm.lib;libssh2.lib;%(AdditionalDependencies) .\Release/pgAdmin3.exe true - $(WXWIN)/lib/vc_dll;$(PGDIR)/lib;$(PGBUILD)/lib;$(PGBUILD)/libxml2/lib;$(PGBUILD)/libxslt/lib;$(PGBUILD)/iconv/lib;%(AdditionalLibraryDirectories) + $(WXWIN)/lib/vc_dll;$(PGDIR)/lib;$(PGBUILD)/lib;$(PGBUILD)/libxml2/lib;$(PGBUILD)/libxslt/lib;$(PGBUILD)/iconv/lib;$(LIBSSH2)/win32/Release_dll;%(AdditionalLibraryDirectories) libcd.lib;libcid.lib;msvcrtd.lib;%(IgnoreSpecificDefaultLibraries) true .\Release/pgAdmin3.pdb @@ -985,6 +985,7 @@ + @@ -1497,6 +1498,7 @@ + @@ -1612,6 +1614,7 @@ + @@ -2239,4 +2242,4 @@ - \ No newline at end of file + diff --git a/pgadmin/pgAdmin3.vcxproj.filters b/pgadmin/pgAdmin3.vcxproj.filters index d18999d..d2dc0bf 100644 --- a/pgadmin/pgAdmin3.vcxproj.filters +++ b/pgadmin/pgAdmin3.vcxproj.filters @@ -143,6 +143,108 @@ {e5220fd8-f837-4fbe-ac01-ef346e8b2d22} + + {d8a57bb3-01aa-4ef3-94b6-1f2e5c3f07fc} + + + {2c3cdfd8-8827-4fef-8dc6-ee3f72f057e8} + + + {8c168e54-f1c4-8dc6-85d0-4daec103d4f3} + + + {df42f3fa-0ac8-4d56-b9c4-1913d5a2c2f0} + + + {9cc76601-f308-4f0b-82be-1913d5a2c2f0} + + + {9ee05a7a-1c91-43e2-c06d-65837ad81162} + + + {685491dc-ad16-4121-4bc1-ba1ae331c95a} + + + {3c9dc817-cc28-4bc1-4121-a9b5ff563a60} + + + {ec385f56-5a98-cc28-834a-23ddee4662d3} + + + {e6836e8e-e9b4-834a-bf2d-53bec570bb0a} + + + {5a6cbaf8-e51d-4721-a511-f348f06d5b43} + + + {14d6562a-41a3-4346-943f-2312193634cb} + + + {0e4d3fb0-dd45-4c7b-813c-b4ceaf66280f} + + + {7d6c4241-1d80-4d6d-ee74-77eb1f97a5bc} + + + {8303ba8b-33bb-46ba-9ea6-55408815381d} + + + {9d006cc1-5abd-4497-8237-26e619952c47} + + + {287ed0c1-2508-46eb-96a7-7fb9f31013b6} + + + {e6be15c5-873a-4919-8cbb-e5fb0cbbf6a9} + + + {6f6ac2df-13ba-4b4d-8321-1a82a4a3e0b2} + + + {7b58f0d3-eaa9-4f23-40d4-0962a35e45f2} + + + {4c63ed7e-71d0-562a-b3fd-c7241f69369c} + + + {731ece13-cb12-4792-868a-454029f103d9} + + + {31655331-e359-4e58-8486-8b6a509d7801} + + + {a5ffb112-00dd-47a1-906c-491faff00c2e} + + + {42c54433-eebe-4dee-b2ef-6ade6560a444} + + + {cd2ecb72-ced4-492e-8196-b855bb03429d} + + + {e1243dab-46ce-46ad-b949-18a181ae84cc} + + + {978d5153-e038-457c-b332-7db2ff0979fc} + + + {50123ec9-0424-4d82-9ce8-5e77b0dbfa8c} + + + {73c56a26-f48b-4333-b321-c31a2b161e89} + + + {df9631db-f808-4c98-acc0-aab1b9d4ac5f} + + + {c0a6ed25-2b3e-4f8a-aa48-5d12472536ec} + + + {e5220fd8-f837-4fbe-ac01-ef346e8b2d22} + + + {d4220fd8-f837-4fbe-ac01-ef346e8b2d22} + @@ -482,1018 +584,1021 @@ frm - include\schema + schema - include\schema + schema - include\schema + schema - include\schema + schema - include\schema + schema - include\schema + schema - include\schema + schema - include\schema + schema - include\schema + schema - include\schema + schema - include\schema + schema - include\schema + schema - include\schema + schema - include\schema + schema - include\schema + schema - include\schema + schema - include\schema + schema - include\schema + schema - include\schema + schema - include\schema + schema - include\schema + schema - include\schema + schema - include\schema + schema - include\schema + schema - include\schema + schema - include\schema + schema - include\schema + schema - include\schema + schema - include\schema + schema - include\schema + schema - include\schema + schema - include\schema + schema - include\schema + schema - include\schema + schema - include\schema + schema - include\schema + schema - include\schema + schema - include\schema + schema - include\schema + schema - include\schema + schema - include\schema + schema - include\schema + schema - include\schema + schema - include\schema + schema - include\schema + schema - include\schema + schema - include\schema + schema - include\schema + schema - include\schema + schema - include\schema + schema - include\slony + slony - include\slony + slony - include\slony + slony - include\slony + slony - include\slony + slony - include\slony + slony - include\slony + slony - include\slony + slony - include\slony + slony - include\slony + slony - include\slony + slony - include\slony + slony - include\slony + slony - include\slony + slony - include\slony + slony - include\slony + slony - include\slony + slony ui - include\utils + utils - include\utils + utils - include\utils + utils - include\utils + utils - include\utils + utils - include\utils + utils - include\utils + utils - include\utils + utils - include\utils + utils - include\utils + utils - include\utils + utils - include\utils + utils - include\debugger + debugger - include\debugger + debugger - include\debugger + debugger - include\debugger + debugger - include\debugger + debugger - include\debugger + debugger - include\debugger + debugger - include\debugger + debugger - include\debugger + debugger - include\debugger + debugger - include\debugger + debugger - include\debugger + debugger - include\debugger + debugger - include\debugger + debugger - include\debugger + debugger - include\gqb + gqb - include\gqb + gqb - include\gqb + gqb - include\gqb + gqb - include\gqb + gqb - include\gqb + gqb - include\gqb + gqb - include\gqb + gqb - include\gqb + gqb - include\gqb + gqb - include\gqb + gqb - include\gqb + gqb - include\gqb + gqb - include\gqb + gqb - include\gqb + gqb - include\gqb + gqb - include\gqb + gqb - include\gqb + gqb - include\gqb + gqb - include\pgscript + pgscript - include\pgscript + pgscript - include\pgscript + pgscript - include\pgscript\exceptions + pgscript\exceptions - include\pgscript\exceptions + pgscript\exceptions - include\pgscript\exceptions + pgscript\exceptions - include\pgscript\exceptions + pgscript\exceptions - include\pgscript\exceptions + pgscript\exceptions - include\pgscript\exceptions + pgscript\exceptions - include\pgscript\exceptions + pgscript\exceptions - include\pgscript\exceptions + pgscript\exceptions - include\pgscript\expressions + pgscript\expressions - include\pgscript\expressions + pgscript\expressions - include\pgscript\expressions + pgscript\expressions - include\pgscript\expressions + pgscript\expressions - include\pgscript\expressions + pgscript\expressions - include\pgscript\expressions + pgscript\expressions - include\pgscript\expressions + pgscript\expressions - include\pgscript\expressions + pgscript\expressions - include\pgscript\expressions + pgscript\expressions - include\pgscript\expressions + pgscript\expressions - include\pgscript\expressions + pgscript\expressions - include\pgscript\expressions + pgscript\expressions - include\pgscript\expressions + pgscript\expressions - include\pgscript\expressions + pgscript\expressions - include\pgscript\expressions + pgscript\expressions - include\pgscript\expressions + pgscript\expressions - include\pgscript\expressions + pgscript\expressions - include\pgscript\expressions + pgscript\expressions - include\pgscript\expressions + pgscript\expressions - include\pgscript\expressions + pgscript\expressions - include\pgscript\expressions + pgscript\expressions - include\pgscript\expressions + pgscript\expressions - include\pgscript\expressions + pgscript\expressions - include\pgscript\expressions + pgscript\expressions - include\pgscript\expressions + pgscript\expressions - include\pgscript\expressions + pgscript\expressions - include\pgscript\expressions + pgscript\expressions - include\pgscript\expressions + pgscript\expressions - include\pgscript\expressions + pgscript\expressions - include\pgscript\expressions + pgscript\expressions - include\pgscript\expressions + pgscript\expressions - include\pgscript\expressions + pgscript\expressions - include\pgscript\expressions + pgscript\expressions - include\pgscript\expressions + pgscript\expressions - include\pgscript\expressions + pgscript\expressions - include\pgscript\expressions + pgscript\expressions - include\pgscript\expressions + pgscript\expressions - include\pgscript\generators + pgscript\generators - include\pgscript\generators + pgscript\generators - include\pgscript\generators + pgscript\generators - include\pgscript\generators + pgscript\generators - include\pgscript\generators + pgscript\generators - include\pgscript\generators + pgscript\generators - include\pgscript\generators + pgscript\generators - include\pgscript\generators + pgscript\generators - include\pgscript\generators + pgscript\generators - include\pgscript\generators + pgscript\generators - include\pgscript\generators + pgscript\generators - include\pgscript\objects + pgscript\objects - include\pgscript\objects + pgscript\objects - include\pgscript\objects + pgscript\objects - include\pgscript\objects + pgscript\objects - include\pgscript\objects + pgscript\objects - include\pgscript\statements + pgscript\statements - include\pgscript\statements + pgscript\statements - include\pgscript\statements + pgscript\statements - include\pgscript\statements + pgscript\statements - include\pgscript\statements + pgscript\statements - include\pgscript\statements + pgscript\statements - include\pgscript\statements + pgscript\statements - include\pgscript\statements + pgscript\statements - include\pgscript\statements + pgscript\statements - include\pgscript\statements + pgscript\statements - include\pgscript\statements + pgscript\statements - include\pgscript\utilities + pgscript\utilities - include\pgscript\utilities + pgscript\utilities - include\pgscript\utilities + pgscript\utilities - include\pgscript\utilities + pgscript\utilities - include\pgscript\utilities + pgscript\utilities - include\pgscript\utilities + pgscript\utilities - include\pgscript\utilities\m_apm + pgscript\utilities\m_apm - include\pgscript\utilities\m_apm + pgscript\utilities\m_apm - include\pgscript\utilities\m_apm + pgscript\utilities\m_apm - include\pgscript\utilities\m_apm + pgscript\utilities\m_apm - include\pgscript\utilities\m_apm + pgscript\utilities\m_apm - include\pgscript\utilities\m_apm + pgscript\utilities\m_apm - include\pgscript\utilities\m_apm + pgscript\utilities\m_apm - include\pgscript\utilities\m_apm + pgscript\utilities\m_apm - include\pgscript\utilities\m_apm + pgscript\utilities\m_apm - include\pgscript\utilities\m_apm + pgscript\utilities\m_apm - include\pgscript\utilities\m_apm + pgscript\utilities\m_apm - include\pgscript\utilities\m_apm + pgscript\utilities\m_apm - include\pgscript\utilities\m_apm + pgscript\utilities\m_apm - include\pgscript\utilities\m_apm + pgscript\utilities\m_apm - include\pgscript\utilities\m_apm + pgscript\utilities\m_apm - include\pgscript\utilities\m_apm + pgscript\utilities\m_apm - include\pgscript\utilities\m_apm + pgscript\utilities\m_apm - include\pgscript\utilities\m_apm + pgscript\utilities\m_apm - include\pgscript\utilities\m_apm + pgscript\utilities\m_apm - include\pgscript\utilities\m_apm + pgscript\utilities\m_apm - include\pgscript\utilities\m_apm + pgscript\utilities\m_apm - include\pgscript\utilities\m_apm + pgscript\utilities\m_apm - include\pgscript\utilities\m_apm + pgscript\utilities\m_apm - include\pgscript\utilities\m_apm + pgscript\utilities\m_apm - include\pgscript\utilities\m_apm + pgscript\utilities\m_apm - include\pgscript\utilities\m_apm + pgscript\utilities\m_apm - include\pgscript\utilities\m_apm + pgscript\utilities\m_apm - include\pgscript\utilities\m_apm + pgscript\utilities\m_apm - include\pgscript\utilities\m_apm + pgscript\utilities\m_apm - include\pgscript\utilities\m_apm + pgscript\utilities\m_apm - include\pgscript\utilities\m_apm + pgscript\utilities\m_apm - include\pgscript\utilities\m_apm + pgscript\utilities\m_apm - include\pgscript\utilities\m_apm + pgscript\utilities\m_apm - include\pgscript\utilities\m_apm + pgscript\utilities\m_apm - include\pgscript\utilities\m_apm + pgscript\utilities\m_apm - include\pgscript\utilities\m_apm + pgscript\utilities\m_apm - include\pgscript\utilities\m_apm + pgscript\utilities\m_apm - include\pgscript\utilities\m_apm + pgscript\utilities\m_apm - include\ogl + ogl - include\ogl + ogl - include\ogl + ogl - include\ogl + ogl - include\ogl + ogl - include\ogl + ogl - include\ogl + ogl - include\ogl + ogl - include\ogl + ogl - include\ogl + ogl - include\ogl + ogl - include\ogl + ogl - include\dd\dditems\figures + dd\dditems\figures - include\dd\dditems\figures + dd\dditems\figures - include\dd\dditems\figures + dd\dditems\figures - include\dd\dditems\figures + dd\dditems\figures - include\dd\dditems\figures + dd\dditems\figures - include\dd\dditems\figures + dd\dditems\figures - include\dd\dditems\figures + dd\dditems\figures - include\dd\dditems\figures + dd\dditems\figures - include\dd\dditems\figures\xml + dd\dditems\figures\xml - include\dd\dditems\handles + dd\dditems\handles - include\dd\dditems\handles + dd\dditems\handles - include\dd\dditems\handles + dd\dditems\handles - include\dd\dditems\handles + dd\dditems\handles - include\dd\dditems\handles + dd\dditems\handles - include\dd\dditems\handles + dd\dditems\handles - include\dd\dditems\locators + dd\dditems\locators - include\dd\dditems\locators + dd\dditems\locators - include\dd\dditems\locators + dd\dditems\locators - include\dd\dditems\locators + dd\dditems\locators - include\dd\dditems\locators + dd\dditems\locators - include\dd\dditems\locators + dd\dditems\locators - include\dd\dditems\tools + dd\dditems\tools - include\dd\dditems\tools + dd\dditems\tools - include\dd\dditems\utilities + dd\dditems\utilities - include\dd\dditems\utilities + dd\dditems\utilities - include\dd\dditems\utilities + dd\dditems\utilities - include\dd\ddmodel + dd\ddmodel - include\dd\ddmodel + dd\ddmodel - include\dd\ddmodel + dd\ddmodel - include\dd\ddmodel + dd\ddmodel - include\dd\ddmodel + dd\ddmodel - include\dd\ddmodel + dd\ddmodel - include\dd\ddmodel + dd\ddmodel - include\hotdraw\connectors + hotdraw\connectors - include\hotdraw\connectors + hotdraw\connectors - include\hotdraw\connectors + hotdraw\connectors - include\hotdraw\connectors + hotdraw\connectors - include\hotdraw\figures + hotdraw\figures - include\hotdraw\figures + hotdraw\figures - include\hotdraw\figures + hotdraw\figures - include\hotdraw\figures + hotdraw\figures - include\hotdraw\figures + hotdraw\figures - include\hotdraw\figures + hotdraw\figures - include\hotdraw\figures + hotdraw\figures - include\hotdraw\figures + hotdraw\figures - include\hotdraw\figures + hotdraw\figures - include\hotdraw\figures + hotdraw\figures - include\hotdraw\figures + hotdraw\figures - include\hotdraw\figures + hotdraw\figures - include\hotdraw\figures + hotdraw\figures - include\hotdraw\figures\defaultAttributes + hotdraw\figures\defaultAttributes - include\hotdraw\figures\defaultAttributes + hotdraw\figures\defaultAttributes - include\hotdraw\figures\defaultAttributes + hotdraw\figures\defaultAttributes - include\hotdraw\figures\defaultAttributes + hotdraw\figures\defaultAttributes - include\hotdraw\figures\xml + hotdraw\figures\xml - include\hotdraw\handles + hotdraw\handles - include\hotdraw\handles + hotdraw\handles - include\hotdraw\handles + hotdraw\handles - include\hotdraw\handles + hotdraw\handles - include\hotdraw\handles + hotdraw\handles - include\hotdraw\handles + hotdraw\handles - include\hotdraw\handles + hotdraw\handles - include\hotdraw\handles + hotdraw\handles - include\hotdraw\locators + hotdraw\locators - include\hotdraw\locators + hotdraw\locators - include\hotdraw\main + hotdraw\main - include\hotdraw\main + hotdraw\main - include\hotdraw\main + hotdraw\main - include\hotdraw\tools + hotdraw\tools - include\hotdraw\tools + hotdraw\tools - include\hotdraw\tools + hotdraw\tools - include\hotdraw\tools + hotdraw\tools - include\hotdraw\tools + hotdraw\tools - include\hotdraw\tools + hotdraw\tools - include\hotdraw\tools + hotdraw\tools - include\hotdraw\tools + hotdraw\tools - include\hotdraw\tools + hotdraw\tools - include\hotdraw\tools + hotdraw\tools - include\hotdraw\tools + hotdraw\tools - include\hotdraw\tools + hotdraw\tools - include\hotdraw\tools + hotdraw\tools - include\hotdraw\tools + hotdraw\tools - include\hotdraw\tools + hotdraw\tools - include\hotdraw\utilities + hotdraw\utilities - include\hotdraw\utilities + hotdraw\utilities - include\hotdraw\utilities + hotdraw\utilities - include\hotdraw\utilities + hotdraw\utilities - include\hotdraw\utilities + hotdraw\utilities - include\hotdraw\utilities + hotdraw\utilities - include\hotdraw\utilities + hotdraw\utilities - include\hotdraw\utilities + hotdraw\utilities - include\hotdraw\utilities + hotdraw\utilities + + utils + @@ -1650,10 +1755,10 @@ include\hotdraw\utilities - include\schema + schema - include\slony + slony ui @@ -1893,112 +1998,112 @@ ui - include\utils + utils - include\utils + utils - include\utils + utils - include\gqb + gqb - include\pgscript + pgscript - include\pgscript + pgscript - include\pgscript + pgscript - include\pgscript + pgscript - include\pgscript + pgscript - include\pgscript\exceptions + pgscript\exceptions - include\pgscript\expressions + pgscript\expressions - include\pgscript\generators + pgscript\generators - include\pgscript\objects + pgscript\objects - include\pgscript\statements + pgscript\statements - include\pgscript\utilities + pgscript\utilities - include\pgscript\utilities\m_apm + pgscript\utilities\m_apm - include\ogl + ogl - include\ogl + ogl - include\dd + dd - include\dd\dditems + dd\dditems - include\dd\dditems\figures + dd\dditems\figures - include\dd\dditems\handles + dd\dditems\handles - include\dd\dditems\locators + dd\dditems\locators - include\dd\dditems\tools + dd\dditems\tools - include\dd\dditems\utilities + dd\dditems\utilities - include\dd\ddmodel + dd\ddmodel - include\hotdraw + hotdraw - include\hotdraw\connectors + hotdraw\connectors - include\hotdraw\figures + hotdraw\figures - include\hotdraw\figures\defaultAttributes + hotdraw\figures\defaultAttributes - include\hotdraw\figures\xml + hotdraw\figures\xml - include\hotdraw\handles + hotdraw\handles - include\hotdraw\locators + hotdraw\locators - include\hotdraw\main + hotdraw\main - include\hotdraw\tools + hotdraw\tools - include\hotdraw\utilities + hotdraw\utilities @@ -3311,6 +3416,9 @@ include\hotdraw\utilities + + include\utils + diff --git a/pgadmin/precomp.cpp b/pgadmin/precomp.cpp index 58d2abb..edee794 100644 --- a/pgadmin/precomp.cpp +++ b/pgadmin/precomp.cpp @@ -9,6 +9,10 @@ // ////////////////////////////////////////////////////////////////////////// +#ifdef WIN32 +#define WIN32_LEAN_AND_MEAN +#endif + #include #include "pgAdmin3.h" diff --git a/pgadmin/schema/pgServer.cpp b/pgadmin/schema/pgServer.cpp index 28b5308..8df57ea 100644 --- a/pgadmin/schema/pgServer.cpp +++ b/pgadmin/schema/pgServer.cpp @@ -37,10 +37,14 @@ #include "utils/registry.h" #include "frm/frmReport.h" #include "dlg/dlgServer.h" +#include "utils/sshTunnel.h" #define DEFAULT_PG_DATABASE wxT("postgres") -pgServer::pgServer(const wxString &newName, const wxString &newHostAddr, const wxString &newDescription, const wxString &newService, const wxString &newDatabase, const wxString &newUsername, int newPort, bool _storePwd, const wxString &newRolename, bool _restore, int _ssl, const wxString &_colour, const wxString &_group) +pgServer::pgServer(const wxString &newName, const wxString &newHostAddr, const wxString &newDescription, const wxString &newService, + const wxString &newDatabase, const wxString &newUsername, int newPort, bool _storePwd, const wxString &newRolename, bool _restore, + int _ssl, const wxString &_colour, const wxString &_group, bool _sshTunnel, const wxString &newTunnelHost, const wxString &newTunnelUserName, + bool _authModePwd, const wxString &newTunnelPassword, const wxString &newPublicKey, const wxString &newIdentity) : pgObject(serverFactory, newName) { description = newDescription; @@ -65,6 +69,17 @@ pgServer::pgServer(const wxString &newName, const wxString &newHostAddr, const w restore = _restore; superUser = false; createPrivilege = false; + + // SSH Tunnel + tunnelObj = NULL; + sshTunnel = _sshTunnel; + tunnelHost = newTunnelHost; + tunnelUserName = newTunnelUserName; + authModePwd = _authModePwd; + tunnelPassword = newTunnelPassword; + publicKeyFile = newPublicKey; + identityFile = newIdentity; + #ifdef WIN32 scmHandle = 0; serviceHandle = 0; @@ -76,6 +91,12 @@ pgServer::~pgServer() if (conn) delete conn; + if(tunnelObj) + { + delete tunnelObj; + tunnelObj = NULL; + } + #ifdef WIN32 if (serviceHandle) CloseServiceHandle(serviceHandle); @@ -188,7 +209,16 @@ pgConn *pgServer::CreateConn(wxString dbName, OID oid, wxString applicationname) dbName = GetDatabaseName(); oid = dbOid; } - pgConn *conn = new pgConn(GetName(), service, hostaddr, dbName, username, password, port, rolename, ssl, oid, applicationname, sslcert, sslkey, sslrootcert, sslcrl, sslcompression); + + pgConn *conn = NULL; + if(sshTunnel) + { + conn = new pgConn(local_listenhost, service, hostaddr, dbName, username, password, local_listenport, rolename, ssl, oid, applicationname, sslcert, sslkey, sslrootcert, sslcrl, sslcompression); + } + else + { + conn = new pgConn(GetName(), service, hostaddr, dbName, username, password, port, rolename, ssl, oid, applicationname, sslcert, sslkey, sslrootcert, sslcrl, sslcompression); + } if (conn && conn->GetStatus() != PGCONN_OK) { @@ -666,23 +696,46 @@ int pgServer::Connect(frmMain *form, bool askPassword, const wxString &pwd, bool form->StartMsg(_("Connecting to database")); + wxString host; + int iPort; + if(sshTunnel) + { + // Create SSH Tunnel if required + if(!tunnelObj) + { + if(!createSSHTunnel()) + { + form->EndMsg(false); + return PGCONN_BAD; + } + } + + host = local_listenhost; + iPort = local_listenport; + } + else + { + host = GetName(); + iPort = port; + } + if (database.IsEmpty()) { - conn = new pgConn(GetName(), service, hostaddr, DEFAULT_PG_DATABASE, username, password, port, rolename, ssl, 0, appearanceFactory->GetLongAppName() + _(" - Browser"), sslcert, sslkey, sslrootcert, sslcrl, sslcompression); + conn = new pgConn(host, service, hostaddr, DEFAULT_PG_DATABASE, username, password, iPort, rolename, ssl, 0, appearanceFactory->GetLongAppName() + _(" - Browser"), sslcert, sslkey, sslrootcert, sslcrl, sslcompression); if (conn->GetStatus() == PGCONN_OK) database = DEFAULT_PG_DATABASE; else if (conn->GetStatus() == PGCONN_BAD && conn->GetLastError().Find( wxT("database \"") DEFAULT_PG_DATABASE wxT("\" does not exist")) >= 0) { delete conn; - conn = new pgConn(GetName(), service, hostaddr, wxT("template1"), username, password, port, rolename, ssl, 0, appearanceFactory->GetLongAppName() + _(" - Browser"), sslcert, sslkey, sslrootcert, sslcrl, sslcompression); + conn = new pgConn(host, service, hostaddr, wxT("template1"), username, password, iPort, rolename, ssl, 0, appearanceFactory->GetLongAppName() + _(" - Browser"), sslcert, sslkey, sslrootcert, sslcrl, sslcompression); if (conn && conn->GetStatus() == PGCONN_OK) database = wxT("template1"); } } else { - conn = new pgConn(GetName(), service, hostaddr, database, username, password, port, rolename, ssl, 0, appearanceFactory->GetLongAppName() + _(" - Browser"), sslcert, sslkey, sslrootcert, sslcrl, sslcompression); + conn = new pgConn(host, service, hostaddr, database, username, password, iPort, rolename, ssl, 0, appearanceFactory->GetLongAppName() + _(" - Browser"), sslcert, sslkey, sslrootcert, sslcrl, sslcompression); if (!conn) { form->EndMsg(false); @@ -1216,6 +1269,47 @@ bool pgServer::AddNamedRestorePoint() return false; } +bool pgServer::createSSHTunnel() +{ + bool retVal = false; + + tunnelObj = new CSSHTunnelThread(tunnelHost, GetName(), port, tunnelUserName, tunnelPassword, publicKeyFile, + identityFile, authModePwd ? AUTH_PASSWORD : AUTH_PUBLICKEY); + + if(tunnelObj) + { + if(tunnelObj->Initialize()) + { + if ( tunnelObj->Create() != wxTHREAD_NO_ERROR ) + { + delete tunnelObj; + tunnelObj = NULL; + wxLogError(_("SSH Error: Unable to create SSH Tunnling Thread")); + } + else + { + if (tunnelObj->Run() != wxTHREAD_NO_ERROR ) + { + delete tunnelObj; + tunnelObj = NULL; + wxLogError(_("SSH Error: Unable to start SSH Tunnling Thread")); + } + + SetLocalListenHost(tunnelObj->GetLocalListenIP()); + SetLocalListenPort(tunnelObj->GetLocalListenPort()); + retVal = true; + } + } + else + { + delete tunnelObj; + tunnelObj = NULL; + } + } + + return retVal; +} + pgServerCollection::pgServerCollection(pgaFactory *factory) : pgCollection(factory) @@ -1289,6 +1383,7 @@ pgObject *pgServerFactory::CreateObjects(pgCollection *obj, ctlTree *browser, co wxString key, servername, hostaddr, description, service, database, username, lastDatabase, lastSchema; wxString storePwd, rolename, restore, serviceID, discoveryID, dbRestriction, colour; wxString group, sslcert, sslkey, sslrootcert, sslcrl, sslcompression; + wxString sshTunnel, authModePwd, tunnelHost, tunnelUserName, tunnelPassword, publicKeyFile, identityFile; pgServer *server = 0; wxArrayString discoveredServers; @@ -1327,6 +1422,13 @@ pgObject *pgServerFactory::CreateObjects(pgCollection *obj, ctlTree *browser, co settings->Read(key + wxT("SSLRootCert"), &sslrootcert, wxEmptyString); settings->Read(key + wxT("SSLCrl"), &sslcrl, wxEmptyString); settings->Read(key + wxT("SSLCompression"), &sslcompression, wxT("true")); + settings->Read(key + wxT("SSHTunnel"), &sshTunnel, wxT("false")); + settings->Read(key + wxT("TunnelHost"), &tunnelHost, wxEmptyString); + settings->Read(key + wxT("TunnelUserName"), &tunnelUserName, wxEmptyString); + settings->Read(key + wxT("TunnelModePwd"), &authModePwd, wxT("true")); + settings->Read(key + wxT("TunnelPassword"), &tunnelPassword, wxEmptyString); + settings->Read(key + wxT("PublicKeyFile"), &publicKeyFile, wxEmptyString); + settings->Read(key + wxT("IdentityFile"), &identityFile, wxEmptyString); // Sanitize the colour colour = colour.Trim(); @@ -1361,7 +1463,8 @@ pgObject *pgServerFactory::CreateObjects(pgCollection *obj, ctlTree *browser, co } // Add the Server node - server = new pgServer(servername, hostaddr, description, service, database, username, port, StrToBool(storePwd), rolename, StrToBool(restore), ssl); + server = new pgServer(servername, hostaddr, description, service, database, username, port, StrToBool(storePwd), rolename, StrToBool(restore), ssl, + colour, group, StrToBool(sshTunnel), tunnelHost, tunnelUserName, StrToBool(authModePwd), tunnelPassword, publicKeyFile, identityFile); server->iSetLastDatabase(lastDatabase); server->iSetLastSchema(lastSchema); server->iSetService(service); @@ -1369,8 +1472,6 @@ pgObject *pgServerFactory::CreateObjects(pgCollection *obj, ctlTree *browser, co server->iSetDiscoveryID(discoveryID); server->iSetDiscovered(false); server->iSetDbRestriction(dbRestriction); - server->iSetColour(colour); - server->iSetGroup(group); server->iSetServerIndex(loop); server->SetSSLCert(sslcert); server->SetSSLKey(sslkey); @@ -1378,6 +1479,7 @@ pgObject *pgServerFactory::CreateObjects(pgCollection *obj, ctlTree *browser, co server->SetSSLCrl(sslcrl); server->iSetSSLCompression(StrToBool(sslcompression)); + found = false; if (browser->ItemHasChildren(obj->GetId())) { @@ -1992,4 +2094,4 @@ bool addnamedrestorepointServiceFactory::CheckEnable(pgObject *obj) return server->GetConnected() && server->connection()->BackendMinimumVersion(9, 1) && !server->GetInRecovery(); } return false; -} +} \ No newline at end of file diff --git a/pgadmin/ui/dlgServer.xrc b/pgadmin/ui/dlgServer.xrc index c0bbd77..60f5ef5 100644 --- a/pgadmin/ui/dlgServer.xrc +++ b/pgadmin/ui/dlgServer.xrc @@ -257,6 +257,130 @@ + + + + 2 + 5 + 5 + 1 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + 0 + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 2 + 10 + 10 + 1 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + Select identity file + * + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + Select public key file + *.pub + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + diff --git a/pgadmin/utils/module.mk b/pgadmin/utils/module.mk index 350aaa6..b01d295 100644 --- a/pgadmin/utils/module.mk +++ b/pgadmin/utils/module.mk @@ -21,7 +21,8 @@ pgadmin3_SOURCES += \ $(srcdir)/utils/sysSettings.cpp \ $(srcdir)/utils/tabcomplete.c \ $(srcdir)/utils/utffile.cpp \ - $(srcdir)/utils/macros.cpp + $(srcdir)/utils/macros.cpp \ + $(srcdir)/utils/sshTunnel.cpp EXTRA_DIST += \ $(srcdir)/utils/module.mk \ diff --git a/pgadmin/utils/sshTunnel.cpp b/pgadmin/utils/sshTunnel.cpp new file mode 100644 index 0000000..3addc50 --- /dev/null +++ b/pgadmin/utils/sshTunnel.cpp @@ -0,0 +1,409 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2012, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// sshTunnel.cpp - Used to create SSH Tunnel +// +////////////////////////////////////////////////////////////////////////// + +// App headers +#include "pgAdmin3.h" +#include "utils/sshTunnel.h" + +CSSHTunnelThread::CSSHTunnelThread(const wxString tunnelhost, const wxString remote_desthost, const unsigned int remote_destport, + const wxString username, const wxString password, const wxString publickey, const wxString privatekey, + const enAuthenticationMethod& enAuthMethod) + : m_tunnelhost(tunnelhost), m_remote_desthost(remote_desthost), m_remote_destport(remote_destport), m_username(username), + m_password(password), m_publickey(publickey), m_privatekey(privatekey), m_enAuthMethod(enAuthMethod) +{ + m_local_listenip = wxEmptyString; + m_local_listenport = 0; + m_listensock = -1, m_sock = -1, m_forwardsock = -1; + m_channel = NULL; + m_session = NULL; +} + +CSSHTunnelThread::~CSSHTunnelThread(void) +{ +} + +bool CSSHTunnelThread::Initialize() +{ + int rc, auth = AUTH_NONE; + const char *fingerprint; + char *userauthlist; + +#ifdef WIN32 + char sockopt; + WSADATA wsadata; + + WSAStartup(MAKEWORD(2, 0), &wsadata); +#else + int sockopt; +#endif + + wxArrayString arrTunnelHostIP; + long errorno = resolveDNS(m_tunnelhost.mb_str(), arrTunnelHostIP); + + if (errorno == 0) + { + /* Connect to SSH server */ + m_sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); + m_sin.sin_family = AF_INET; + if (INADDR_NONE == (m_sin.sin_addr.s_addr = inet_addr(arrTunnelHostIP.Item(0).mb_str()))) + { + wxLogError(_("SSH error: Error in inet address!\n")); + return false; + } + m_sin.sin_port = htons(22); + if (connect(m_sock, (struct sockaddr*)(&m_sin), + sizeof(struct sockaddr_in)) != 0) + { + wxLogError(_("SSH error: Could not connect to socket")); + return false; + } + + /* Create a session instance */ + m_session = libssh2_session_init(); + + if (!m_session) + { + wxLogError(_("SSH error: Could not initialize SSH session!\n")); + return false; + } + + /* ... start it up. This will trade welcome banners, exchange keys, + * and setup crypto, compression, and MAC layers + */ +#ifdef HAVE_LIBSSH2_HANDSHAKE_FUNC + rc = libssh2_session_handshake(m_session, m_sock); +#else + rc = libssh2_session_startup(m_session, m_sock); +#endif + if (rc) + { + wxLogError(_("SSH error: Error when starting up SSH session: %d\n"), rc); + return false; + } + + /* At this point we havn't yet authenticated. The first thing to do + * is check the hostkey's fingerprint against our known hosts Your app + * may have it hard coded, may go to a file, may present it to the + * user, that's your call + */ + fingerprint = libssh2_hostkey_hash(m_session, LIBSSH2_HOSTKEY_HASH_SHA1); + + /* check what authentication methods are available */ + userauthlist = libssh2_userauth_list(m_session, m_username.mb_str(), strlen(m_username.mb_str())); + + if (strstr(userauthlist, "password")) + auth |= AUTH_PASSWORD; + if (strstr(userauthlist, "publickey")) + auth |= AUTH_PUBLICKEY; + + if ((auth & AUTH_PASSWORD) && (m_enAuthMethod == AUTH_PASSWORD)) + auth = AUTH_PASSWORD; + if ((auth & AUTH_PUBLICKEY) && (m_enAuthMethod == AUTH_PUBLICKEY)) + auth = AUTH_PUBLICKEY; + + if (auth & AUTH_PASSWORD) + { + rc = libssh2_userauth_password(m_session, m_username.mb_str(), m_password.mb_str()); + if (rc) + { + wxLogError(_("SSH error: Authentication by password failed with error code %d\n"), rc); + Cleanup(); + return false; + } + } + else if (auth & AUTH_PUBLICKEY) + { +#ifdef IS_LIBSSH2_OPENSSL_CRYPTO + rc = libssh2_userauth_publickey_fromfile(m_session, m_username.mb_str(), NULL, m_privatekey.mb_str(), m_password.mb_str()); +#else + rc = libssh2_userauth_publickey_fromfile(m_session, m_username.mb_str(), m_publickey.mb_str(), m_privatekey.mb_str(), m_password.mb_str()); +#endif + if (rc) + { + wxLogError(_("SSH error: Authentication by identity file failed with error code %d\n"), rc); + Cleanup(); + return false; + } + } + else + { + wxLogError(_("SSH error: No supported authentication methods found!\n")); + Cleanup(); + return false; + } + + //Get the IP Address of local machine + char hostname[256]; + gethostname(hostname, sizeof(hostname)); + wxArrayString arrLocalIP; + resolveDNS(hostname, arrLocalIP); + + m_listensock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); + m_sin.sin_family = AF_INET; + // Give port no to 0 so that bind will automatically select the available port. + m_sin.sin_port = htons(0); + if (INADDR_NONE == (m_sin.sin_addr.s_addr = inet_addr(arrLocalIP.Item(0).mb_str()))) + { + wxLogError(_("SSH error: inet_addr failed")); + Cleanup(); + return false; + } + + sockopt = 1; + setsockopt(m_listensock, SOL_SOCKET, SO_REUSEADDR, &sockopt, sizeof(sockopt)); + m_sinlen = sizeof(m_sin); + if (-1 == bind(m_listensock, (struct sockaddr *)&m_sin, m_sinlen)) + { + wxLogError(_("SSH error: bind failed")); + Cleanup(); + return false; + } + if (getsockname(m_listensock, (struct sockaddr *)&m_sin, &m_sinlen) == -1) + { + wxLogError(_("SSH error: getsockname() failed")); + Cleanup(); + return false; + } + + if (-1 == listen(m_listensock, 2)) + { + wxLogError(_("SSH error: listen failed")); + Cleanup(); + return false; + } + + m_local_listenip = wxString(inet_ntoa(m_sin.sin_addr), wxConvLibc); + m_local_listenport = ntohs(m_sin.sin_port); + + wxLogInfo(wxT("Waiting for TCP connection on %s:%d...\n"), + m_local_listenip.c_str(), m_local_listenport); + + return true; + } + else + { + wxLogError(_("SSH error: Unable to resolve host: %s with error code %d\n"), m_tunnelhost.c_str(), errorno); + } + + return false; +} + +void * CSSHTunnelThread::Entry() +{ + while (1) + { + m_forwardsock = accept(m_listensock, (struct sockaddr *) & m_sin, &m_sinlen); + if (-1 == m_forwardsock) + { + wxLogError(_("SSH error: accept failed")); + Cleanup(); + break; + } + // Create thread for read/write. + CSubThread *subThread = new CSubThread(m_sin, m_remote_desthost, m_remote_destport, m_session, m_channel, m_forwardsock); + if ( subThread->Create() != wxTHREAD_NO_ERROR ) + { + delete subThread; + subThread = NULL; + } + else + { + if (subThread->Run() != wxTHREAD_NO_ERROR ) + { + delete subThread; + subThread = NULL; + } + } + } + + return NULL; +} + +void CSSHTunnelThread::Cleanup() +{ + +#ifdef WIN32 + closesocket(m_forwardsock); + closesocket(m_listensock); +#else + close(m_forwardsock); + close(m_listensock); +#endif + + if (m_channel) + libssh2_channel_free(m_channel); + + libssh2_session_disconnect(m_session, "Client disconnecting normally"); + + libssh2_session_free(m_session); + +#ifdef WIN32 + closesocket(m_sock); +#else + close(m_sock); +#endif + +#ifdef HAVE_LIBSSH2_EXIT_FUNC + libssh2_exit(); +#endif +} + +long CSSHTunnelThread::resolveDNS(const char * host, wxArrayString &arrIPAddress) +{ + long errorno = 0; + struct in_addr addr; + struct hostent* remoteHost = gethostbyname(host); + if (remoteHost != NULL) + { + if (remoteHost->h_addrtype == AF_INET) + { + int i = 0; + while (remoteHost->h_addr_list[i] != 0) + { + addr.s_addr = *(u_long *) remoteHost->h_addr_list[i++]; + arrIPAddress.Add(wxString((char*) inet_ntoa(addr), wxConvLocal)); + } + } + } + else + { +#ifdef WIN32 + errorno = GetLastError(); +#else + errorno = errno; +#endif + } + + return errorno; +} + +CSubThread::CSubThread(const struct sockaddr_in sin, const wxString remote_desthost, const unsigned int remote_destport, + LIBSSH2_SESSION *session, LIBSSH2_CHANNEL *channel, int forwardsock) + : m_sin(sin), m_remote_desthost(remote_desthost), m_remote_destport(remote_destport), + m_session(session), m_channel(channel), m_forwardsock(forwardsock) +{ +} + +CSubThread::~CSubThread(void) +{ +} + +void * +CSubThread::Entry() +{ + fd_set fds; + struct timeval tv; + ssize_t len, wr; + char buf[16384]; + int rc, i = 0; + + const char *shost = inet_ntoa(m_sin.sin_addr); + unsigned int sport = ntohs(m_sin.sin_port); + + wxLogInfo(wxT("\nForwarding connection from %s:%d here to remote %s:%d\n"), inet_ntoa(m_sin.sin_addr), + sport, m_remote_desthost.c_str(), m_remote_destport); + + /* Must use blocking here to avoid connect errors */ + libssh2_session_set_blocking(m_session, 1); + + m_channel = libssh2_channel_direct_tcpip_ex(m_session, m_remote_desthost.mb_str(), + m_remote_destport, shost, sport); + + if (!m_channel) + { + wxLogError(_("SSH error: Could not open the direct-tcpip channel!\n (Note that this can be a problem at the server! Please review the server logs.)\n")); + goto shutdown; + } + + /* Must use non-blocking IO hereafter due to the current libssh2 API */ + libssh2_session_set_blocking(m_session, 0); + + while (1) + { + FD_ZERO(&fds); + FD_SET(m_forwardsock, &fds); + tv.tv_sec = 0; + tv.tv_usec = 100000; + rc = select(m_forwardsock + 1, &fds, NULL, NULL, &tv); + if (-1 == rc) + { + wxLogError(_("SSH error: select failed")); + goto shutdown; + } + if (rc && FD_ISSET(m_forwardsock, &fds)) + { + len = recv(m_forwardsock, buf, sizeof(buf), 0); + if (len < 0) + { + wxLogError(_("SSH error: read failed")); + goto shutdown; + } + else if (0 == len) + { + wxLogInfo(_("The client at %s:%d disconnected!\n"), shost, sport); + goto shutdown; + } + wr = 0; + do + { + i = libssh2_channel_write(m_channel, buf, len); + + if (i < 0) + { + wxLogError(_("SSH error: libssh2_channel_write: %d\n"), i); + goto shutdown; + } + wr += i; + } + while (i > 0 && wr < len); + } + while (1) + { + len = libssh2_channel_read(m_channel, buf, sizeof(buf)); + + if (LIBSSH2_ERROR_EAGAIN == len) + break; + else if (len < 0) + { + wxLogError(_("SSH error: libssh2_channel_read: %d"), (int)len); + goto shutdown; + } + wr = 0; + while (wr < len) + { + i = send(m_forwardsock, buf + wr, len - wr, 0); + if (i <= 0) + { + wxLogError(_("SSH error: write failed")); + goto shutdown; + } + wr += i; + } + if (libssh2_channel_eof(m_channel)) + { + wxLogInfo(_("The server at %s:%d disconnected!\n"), + m_remote_desthost.c_str(), m_remote_destport); + goto shutdown; + } + } + } +shutdown: +#ifdef WIN32 + closesocket(m_forwardsock); +#else + close(m_forwardsock); +#endif + + if (m_channel) + libssh2_channel_free(m_channel); + + return NULL; +}