Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
948a484ca5 | ||
|
|
cda3ee6bf9 | ||
|
|
071e2132f1 | ||
|
|
3512be30cf | ||
|
|
0bb279eec8 | ||
|
|
75331d9025 | ||
|
|
99a46eafc8 | ||
|
|
ac9300f5be | ||
|
|
4e4e5154f4 | ||
|
|
b54c096762 | ||
|
|
5d409ec1de |
@@ -8,7 +8,7 @@ list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/cmake")
|
||||
set(PROJECT_VERSION_MAJOR "0")
|
||||
set(PROJECT_VERSION_MINOR "9")
|
||||
set(PROJECT_VERSION_PATCH "0")
|
||||
set(PROJECT_VERSION_BUILD "-RC7")
|
||||
set(PROJECT_VERSION_BUILD "-RC8")
|
||||
set(PROJECT_VERSION "${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH}${PROJECT_VERSION_BUILD}")
|
||||
|
||||
# Modules
|
||||
|
||||
@@ -9,14 +9,17 @@
|
||||
# SYSTEM_OPENBSD
|
||||
# SYSTEM_NETBSD
|
||||
#
|
||||
# 2) Build types checks
|
||||
# 2) Additional Linux distro check
|
||||
# SYSTEM_LINUX_RHEL
|
||||
#
|
||||
# 3) Build types checks
|
||||
#
|
||||
# BUILD_DEBUG
|
||||
# BUILD_RELEASE
|
||||
# BUILD_RELWITHDEBINFO
|
||||
# BUILD_MINSIZEREL
|
||||
#
|
||||
# 3) Link "lib groups" and "whole-archive" options
|
||||
# 4) Link "lib groups" and "whole-archive" options
|
||||
#
|
||||
# LINK_LIBGROUP_START
|
||||
# LINK_LIBGROUP_END
|
||||
@@ -30,6 +33,9 @@ elseif(CMAKE_SYSTEM_NAME MATCHES "Windows")
|
||||
set(SYSTEM_WINDOWS TRUE)
|
||||
elseif(CMAKE_SYSTEM_NAME MATCHES "Linux")
|
||||
set(SYSTEM_LINUX TRUE)
|
||||
if(EXISTS "/etc/redhat-release")
|
||||
set(SYSTEM_LINUX_RHEL TRUE)
|
||||
endif()
|
||||
elseif(CMAKE_SYSTEM_NAME MATCHES "FreeBSD")
|
||||
set(SYSTEM_FREEBSD TRUE)
|
||||
set(SYSTEM_BSD TRUE)
|
||||
@@ -52,6 +58,18 @@ elseif("${CMAKE_BUILD_TYPE}" MATCHES "MinSizeRel")
|
||||
set(BUILD_MINSIZEREL TRUE)
|
||||
endif()
|
||||
|
||||
# Compiler checks
|
||||
# We check Clang using MATCH instead of strict equality, because as of CMake 3.0.0 the
|
||||
# CMAKE_<LANG>_COMPILER_ID value for Apple-provided Clang is AppleClang. To test
|
||||
# for both the Apple-provided Clang and the regular Clang we use MATCH.
|
||||
if(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
|
||||
set(COMPILER_CLANG TRUE)
|
||||
elseif(CMAKE_CXX_COMPILER_ID MATCHES "^GNU$")
|
||||
set(COMPILER_GCC TRUE)
|
||||
elseif(CMAKE_CXX_COMPILER_ID MATCHES "^MSVC$")
|
||||
set(COMPILER_MSVC TRUE)
|
||||
endif()
|
||||
|
||||
# Link "groups" and "whole-archive" options
|
||||
if(SYSTEM_LINUX OR SYSTEM_FREEBSD OR SYSTEM_OPENBSD)
|
||||
set(LINK_LIBGROUP_START -Wl,--start-group)
|
||||
|
||||
@@ -18,7 +18,7 @@ if(SYSTEM_LINUX)
|
||||
set(bin_dir bin)
|
||||
set(lib_dir lib)
|
||||
set(resources_dir share)
|
||||
set(license_dir .)
|
||||
set(license_dir ${resources_dir}/doc/robomongo)
|
||||
|
||||
set(qt_plugins_dir ${lib_dir})
|
||||
set(qt_conf_dir ${bin_dir})
|
||||
@@ -82,6 +82,16 @@ if(SYSTEM_LINUX)
|
||||
QGtk2ThemePlugin
|
||||
QXcbIntegrationPlugin)
|
||||
|
||||
# Install icons
|
||||
install(
|
||||
DIRECTORY "${CMAKE_SOURCE_DIR}/install/linux/icons/"
|
||||
DESTINATION "${resources_dir}/icons")
|
||||
|
||||
# Install desktop shortcut
|
||||
install(
|
||||
FILES "${CMAKE_SOURCE_DIR}/install/linux/robomongo.desktop"
|
||||
DESTINATION "${resources_dir}/applications")
|
||||
|
||||
elseif(SYSTEM_MACOSX)
|
||||
install_qt_lib(MacExtras DBus)
|
||||
install_qt_plugins(
|
||||
@@ -105,4 +115,3 @@ elseif(SYSTEM_WINDOWS)
|
||||
set(CMAKE_INSTALL_SYSTEM_RUNTIME_DESTINATION .)
|
||||
include(InstallRequiredSystemLibraries)
|
||||
endif()
|
||||
|
||||
|
||||
@@ -52,9 +52,16 @@ target_architecture(target_arch)
|
||||
# Package file name
|
||||
set(CPACK_PACKAGE_FILE_NAME ${package_file_name}-${package_file_version}-${system_name}-${target_arch}-${git_hash})
|
||||
|
||||
if(SYSTEM_LINUX)
|
||||
set(CPACK_GENERATOR TGZ)
|
||||
if(SYSTEM_LINUX_RHEL)
|
||||
set(CPACK_GENERATOR RPM)
|
||||
set(CPACK_PACKAGE_DESCRIPTION_FILE "${CMAKE_SOURCE_DIR}/DESCRIPTION")
|
||||
set(CPACK_RPM_PACKAGE_LICENSE "GPLv3")
|
||||
set(CPACK_RPM_PACKAGE_DEBUG 1)
|
||||
list(APPEND CPACK_RPM_USER_FILELIST "%attr(755,root,root) /usr/share/icons")
|
||||
list(APPEND CPACK_RPM_USER_FILELIST "%attr(755,root,root) /usr/share/applications")
|
||||
|
||||
elseif(SYSTEM_LINUX)
|
||||
set(CPACK_GENERATOR TGZ)
|
||||
|
||||
elseif(SYSTEM_MACOSX)
|
||||
set(CPACK_GENERATOR DragNDrop)
|
||||
|
||||
@@ -10,6 +10,7 @@ elseif(SYSTEM_WINDOWS)
|
||||
# The /MP option can reduce the total time to compile the source files. This option
|
||||
# causes the compiler to create one or more copies of itself, each in a separate process.
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /MP")
|
||||
set(CMAKE_C_FLAGS "${CMAKE_CXX_FLAGS} /MP")
|
||||
|
||||
set(CMAKE_CXX_STANDARD_LIBRARIES "${CMAKE_CXX_STANDARD_LIBRARIES} psapi.lib bcrypt.lib Iphlpapi.lib dbghelp.lib ws2_32.lib winmm.lib version.lib")
|
||||
endif()
|
||||
|
||||
|
After Width: | Height: | Size: 10 KiB |
|
After Width: | Height: | Size: 717 B |
|
After Width: | Height: | Size: 1.4 KiB |
|
After Width: | Height: | Size: 29 KiB |
|
After Width: | Height: | Size: 3.3 KiB |
|
After Width: | Height: | Size: 3.6 KiB |
|
After Width: | Height: | Size: 6.8 KiB |
|
After Width: | Height: | Size: 6.8 KiB |
@@ -0,0 +1,8 @@
|
||||
[Desktop Entry]
|
||||
Encoding=UTF-8
|
||||
Name=Robomongo
|
||||
Comment=Shell-centric cross-platform MongoDB management tool
|
||||
Exec=robomongo
|
||||
Icon=robomongo
|
||||
Type=Application
|
||||
Categories=Development;Utility;
|
||||
@@ -169,13 +169,13 @@ namespace Robomongo
|
||||
}
|
||||
|
||||
void App::handle(LogEvent *event) {
|
||||
if (event->level == LogEvent::ERROR) {
|
||||
if (event->level == LogEvent::RBM_ERROR) {
|
||||
LOG_MSG(event->message, mongo::logger::LogSeverity::Error());
|
||||
} else if (event->level == LogEvent::WARN) {
|
||||
} else if (event->level == LogEvent::RBM_WARN) {
|
||||
LOG_MSG(event->message, mongo::logger::LogSeverity::Warning());
|
||||
} else if (event->level == LogEvent::INFO) {
|
||||
} else if (event->level == LogEvent::RBM_INFO) {
|
||||
LOG_MSG(event->message, mongo::logger::LogSeverity::Info());
|
||||
} else if (event->level == LogEvent::DEBUG) {
|
||||
} else if (event->level == LogEvent::RBM_DEBUG) {
|
||||
LOG_MSG(event->message, mongo::logger::LogSeverity::Log());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1062,10 +1062,10 @@ namespace Robomongo
|
||||
R_EVENT
|
||||
|
||||
enum LogLevel {
|
||||
ERROR = 1,
|
||||
WARN = 2,
|
||||
INFO = 3,
|
||||
DEBUG = 100 // log as much as possible
|
||||
RBM_ERROR = 1,
|
||||
RBM_WARN = 2,
|
||||
RBM_INFO = 3,
|
||||
RBM_DEBUG = 100 // log as much as possible
|
||||
};
|
||||
|
||||
LogEvent(QObject *sender, const std::string& message, LogLevel level) :
|
||||
|
||||
@@ -72,7 +72,7 @@ namespace Robomongo
|
||||
return;
|
||||
|
||||
_sshConfig = new rbm_ssh_tunnel_config;
|
||||
_sshConfig->sshserverip = const_cast<char*>(_sshhost.c_str());
|
||||
_sshConfig->sshserverhost = const_cast<char*>(_sshhost.c_str());
|
||||
_sshConfig->sshserverport = static_cast<unsigned int>(_sshport);
|
||||
_sshConfig->remotehost = const_cast<char*>(_remotehost.c_str());
|
||||
_sshConfig->remoteport = static_cast<unsigned int>(_remoteport);
|
||||
|
||||
@@ -22,6 +22,9 @@ namespace Robomongo
|
||||
QVariant toVariant() const;
|
||||
void fromVariant(const QVariantMap &map);
|
||||
|
||||
/*
|
||||
* Domain or IPv4 or IPv6 address
|
||||
*/
|
||||
std::string host() const { return _host; }
|
||||
void setHost(const std::string &host) { _host = host; }
|
||||
|
||||
@@ -57,7 +60,7 @@ namespace Robomongo
|
||||
void setLogLevel(const int logLevel) { _logLevel = logLevel; }
|
||||
|
||||
private:
|
||||
std::string _host;
|
||||
std::string _host; // domain or IPv4/v6
|
||||
int _port;
|
||||
std::string _userName;
|
||||
std::string _userPassword;
|
||||
|
||||
@@ -164,7 +164,7 @@ namespace Robomongo
|
||||
connection->auth(authParams);
|
||||
emit authStatus("", true);
|
||||
}
|
||||
} catch (const mongo::UserException &ex) {
|
||||
} catch (const mongo::UserException &) {
|
||||
emit authStatus("", false);
|
||||
}
|
||||
|
||||
|
||||
@@ -44,8 +44,6 @@ namespace Robomongo
|
||||
QWidget *parent) : QDialog(parent),
|
||||
_user(user)
|
||||
{
|
||||
VERIFY(!user.version() < MongoUser::minimumSupportedVersion);
|
||||
|
||||
setWindowTitle("Add User");
|
||||
setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint); // Remove help button (?)
|
||||
setMinimumSize(minimumSize);
|
||||
@@ -120,7 +118,6 @@ namespace Robomongo
|
||||
QWidget *parent) : QDialog(parent),
|
||||
_user(user)
|
||||
{
|
||||
VERIFY(user.version() < MongoUser::minimumSupportedVersion);
|
||||
setWindowTitle("Add User");
|
||||
setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint); // Remove help button (?)
|
||||
setMinimumSize(minimumSize);
|
||||
|
||||
@@ -203,7 +203,7 @@ namespace miutil
|
||||
if( !isLocalFormat ){
|
||||
sprintf( buf, "%04d-%02d-%02d%c%02d:%02d:%02d.%03dZ",
|
||||
static_cast<int>(d.year()), d.month().as_number(), d.day().as_number(), sep,
|
||||
t.hours(), t.minutes(), t.seconds(),(static_cast<int64_t>(t.total_milliseconds()))%1000 );
|
||||
t.hours(), t.minutes(), t.seconds(),(static_cast<int>(t.total_milliseconds()))%1000 );
|
||||
}
|
||||
else{
|
||||
boost::posix_time::ptime timeP(d,t);
|
||||
@@ -225,7 +225,7 @@ namespace miutil
|
||||
sprintf(utc_buff,diffT.hours()>0?"+%02d:%02d":"%03d:%02d",diffT.hours(),abs(diffM));
|
||||
sprintf( buf, "%04d-%02d-%02d%c%02d:%02d:%02d.%03d",
|
||||
static_cast<int>(d.year()), d.month().as_number(), d.day().as_number(), sep,
|
||||
t.hours(), t.minutes(), t.seconds(),(static_cast<int64_t>(t.total_milliseconds()))%1000);
|
||||
t.hours(), t.minutes(), t.seconds(),(static_cast<int>(t.total_milliseconds()))%1000);
|
||||
strcat(buf,utc_buff);
|
||||
}
|
||||
|
||||
@@ -344,7 +344,7 @@ namespace miutil
|
||||
td = boost::posix_time::time_duration(hourOffset, minuteOffset, 0);
|
||||
return pt - td;
|
||||
}
|
||||
catch(const std::out_of_range &ex)
|
||||
catch(const std::out_of_range &)
|
||||
{
|
||||
isSuccessfull = false;
|
||||
return boost::posix_time::ptime();
|
||||
|
||||
@@ -3,15 +3,16 @@
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
|
||||
enum {BUF_SIZE = 1024 };
|
||||
|
||||
int log_error(const char *format, ...)
|
||||
{
|
||||
int errsave = errno;
|
||||
const int buf_size = 1024;
|
||||
char buf[buf_size];
|
||||
char buf[BUF_SIZE];
|
||||
va_list args;
|
||||
|
||||
va_start(args, format);
|
||||
vsnprintf(buf, buf_size, format, args);
|
||||
vsnprintf(buf, BUF_SIZE, format, args);
|
||||
|
||||
if (errsave) {
|
||||
fprintf(stderr, "Error (%d): %s. %s\n", errno, strerror(errsave), buf);
|
||||
@@ -25,12 +26,11 @@ int log_error(const char *format, ...)
|
||||
|
||||
int log_msg(const char *format, ...)
|
||||
{
|
||||
const int buf_size = 1024;
|
||||
char buf[buf_size];
|
||||
char buf[BUF_SIZE];
|
||||
va_list args;
|
||||
|
||||
va_start(args, format);
|
||||
vsnprintf(buf, buf_size, format, args);
|
||||
vsnprintf(buf, BUF_SIZE, format, args);
|
||||
|
||||
printf("%s\n", buf);
|
||||
|
||||
@@ -42,9 +42,8 @@ int log_msg(const char *format, ...)
|
||||
* errsave: use 0, if you are not logging errors (i.e. errno == 0).
|
||||
*/
|
||||
void ssh_log_v(struct rbm_session* session, enum rbm_ssh_log_type type, const char *format, va_list args, int errsave) {
|
||||
const size_t bufsize = 2000;
|
||||
char buf[bufsize];
|
||||
vsnprintf(buf, bufsize, format, args);
|
||||
char buf[BUF_SIZE];
|
||||
vsnprintf(buf, BUF_SIZE, format, args);
|
||||
|
||||
if (type == RBM_SSH_LOG_TYPE_ERROR ||
|
||||
type == RBM_SSH_LOG_TYPE_WARN) {
|
||||
|
||||
@@ -5,6 +5,10 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// We do not need to use IPv6 for local bind. But we do support IPv6 for remote connection.
|
||||
// It means we can ignore MSVC warning: "Use inet_ntop() or InetNtop() instead" of "inet_ntoa"
|
||||
#define _WINSOCK_DEPRECATED_NO_WARNINGS
|
||||
|
||||
#include <libssh2.h>
|
||||
#include <stdarg.h> // for va_list in log functions
|
||||
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
#include "ssh.h"
|
||||
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
@@ -11,10 +10,16 @@ int main(int argc, char *argv[]) {
|
||||
config.localport = 27040;
|
||||
config.username = "dmitry";
|
||||
config.password = "";
|
||||
|
||||
#ifdef WIN32
|
||||
config.privatekeyfile = "d:\\ubuntik";
|
||||
#else
|
||||
config.privatekeyfile = "/Users/dmitry/.ssh/ubuntik";
|
||||
#endif
|
||||
|
||||
config.publickeyfile = NULL; //"/Users/dmitry/.ssh/ubuntik.pub";
|
||||
config.passphrase = "";
|
||||
config.sshserverip = "198.61.166.171";
|
||||
config.sshserverhost = "198.61.166.171";
|
||||
config.sshserverport = 22;
|
||||
config.remotehost = "localhost";
|
||||
config.remoteport = 27017;
|
||||
@@ -27,7 +32,7 @@ int main(int argc, char *argv[]) {
|
||||
struct rbm_ssh_session *session = NULL;
|
||||
session = rbm_ssh_session_create(&config);
|
||||
if (!session) {
|
||||
printf("Unable to create session. Shutdown");
|
||||
printf("Unable to create session. Shutdown\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -35,7 +40,7 @@ int main(int argc, char *argv[]) {
|
||||
printf("II About to open tunnel...\n");
|
||||
|
||||
if (rbm_ssh_session_setup(session) == -1) {
|
||||
printf("Setup failed. Shutdowning...");
|
||||
printf("Setup failed. Shutdowning...\n");
|
||||
rbm_ssh_session_close(session);
|
||||
return 1;
|
||||
}
|
||||
@@ -44,7 +49,7 @@ int main(int argc, char *argv[]) {
|
||||
//
|
||||
printf("About to open tunnel...\n");
|
||||
if (rbm_ssh_open_tunnel(session) != 0) {
|
||||
printf("Tunnel stopped because of error.");
|
||||
printf("Tunnel stopped because of error.\n");
|
||||
return 1;
|
||||
}
|
||||
//
|
||||
|
||||
@@ -1,19 +1,36 @@
|
||||
#include "robomongo/ssh/private.h"
|
||||
#include "robomongo/ssh/libssh2_config.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h> // close()
|
||||
|
||||
#ifdef WIN32
|
||||
#include <windows.h>
|
||||
#include <winsock2.h>
|
||||
#include <ws2tcpip.h>
|
||||
#else
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <sys/time.h>
|
||||
#include <netdb.h>
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include <signal.h>
|
||||
#include <stdio.h>
|
||||
|
||||
static int handle_new_client_connections(struct rbm_session *connection, int *fdmax, fd_set *masterset);
|
||||
static int handle_ssh_connections(struct rbm_session *connection, fd_set *masterset);
|
||||
static int handle_client_connections(struct rbm_session *connection, rbm_socket_t i, fd_set *masterset);
|
||||
|
||||
static void rbm_sleep_ms(int ms);
|
||||
static void rbm_socket_close(rbm_socket_t socket);
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Public API
|
||||
//===----------------------------------------------------------------------===//
|
||||
@@ -23,14 +40,28 @@ static int handle_client_connections(struct rbm_session *connection, rbm_socket_
|
||||
* Returns 0 if succeeded, or a negative value for error.
|
||||
*/
|
||||
int rbm_ssh_init() {
|
||||
#ifndef WIN32
|
||||
// Ignore SIGPIPE signal. If we will not do that, an attempt to send/write
|
||||
// to the socket that do not have readers will force OS to generate SIGPIPE
|
||||
// signal. Default handler for this signal is a termination of program.
|
||||
// While signal is ignored, send/write will still return error code, that
|
||||
// should be handled by the code.
|
||||
signal(SIGPIPE, SIG_IGN);
|
||||
#endif
|
||||
|
||||
int err = libssh2_init(0);
|
||||
int err;
|
||||
|
||||
#ifdef WIN32
|
||||
WSADATA wsadata;
|
||||
err = WSAStartup(MAKEWORD(2,0), &wsadata);
|
||||
if (err) {
|
||||
log_error("WSAStartup failed with error code: (%d)", err);
|
||||
return RBM_ERROR;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
err = libssh2_init(0);
|
||||
if (err) {
|
||||
log_error("Initialization of LIBSSH2 failed with error code: (%d)", err);
|
||||
return RBM_ERROR;
|
||||
@@ -44,6 +75,10 @@ int rbm_ssh_init() {
|
||||
*/
|
||||
void rbm_ssh_cleanup() {
|
||||
libssh2_exit();
|
||||
|
||||
#ifdef WIN32
|
||||
WSACleanup();
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -89,7 +124,7 @@ void rbm_ssh_session_close(struct rbm_ssh_session *sshsession) {
|
||||
struct rbm_session *session = (struct rbm_session*)sshsession->handle;
|
||||
if (session->localsocket != rbm_socket_invalid) {
|
||||
ssh_log_debug(session, "Closing local accept socket");
|
||||
close(session->localsocket);
|
||||
rbm_socket_close(session->localsocket);
|
||||
session->localsocket = rbm_socket_invalid;
|
||||
}
|
||||
|
||||
@@ -102,8 +137,6 @@ void rbm_ssh_session_close(struct rbm_ssh_session *sshsession) {
|
||||
|
||||
int rbm_ssh_open_tunnel(struct rbm_ssh_session *sshsession) {
|
||||
struct rbm_session *connection = (struct rbm_session*)sshsession->handle;
|
||||
const int ERROR = -1;
|
||||
const int SUCCESS = 0;
|
||||
int rc = 0;
|
||||
|
||||
while (1) {
|
||||
@@ -118,33 +151,31 @@ int rbm_ssh_open_tunnel(struct rbm_ssh_session *sshsession) {
|
||||
|
||||
if (rbm_ssh_setup(connection) == -1) {
|
||||
rbm_ssh_session_close(sshsession);
|
||||
return ERROR;
|
||||
return RBM_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
return SUCCESS;
|
||||
return RBM_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
// Returns -1 on error, 0 when otherwise
|
||||
int rbm_ssh_session_setup(struct rbm_ssh_session *sshsession) {
|
||||
struct rbm_session *session = (struct rbm_session*)sshsession->handle;
|
||||
const int ERROR = -1;
|
||||
const int SUCCESS = 0;
|
||||
struct rbm_ssh_tunnel_config *config = session->config;
|
||||
|
||||
if (rbm_ssh_setup(session) == -1)
|
||||
return ERROR;
|
||||
return RBM_ERROR;
|
||||
|
||||
session->localsocket = socket_listen(session, config->localip, (int *) &config->localport);
|
||||
if (session->localsocket == -1) {
|
||||
session->localsocket = rbm_socket_invalid;
|
||||
return ERROR; // errors are already logged by socket_listen
|
||||
return RBM_ERROR; // errors are already logged by socket_listen
|
||||
}
|
||||
|
||||
ssh_log_debug(session, "Waiting for TCP connection on %s:%d...", config->localip, config->localport);
|
||||
|
||||
return SUCCESS;
|
||||
return RBM_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
@@ -187,7 +218,7 @@ void rbm_channel_close(struct rbm_channel *channel) {
|
||||
|
||||
// 3. Close socket
|
||||
if (channel->socket != rbm_socket_invalid) {
|
||||
close(channel->socket);
|
||||
rbm_socket_close(channel->socket);
|
||||
channel->socket = rbm_socket_invalid;
|
||||
}
|
||||
|
||||
@@ -222,28 +253,26 @@ struct rbm_channel *rbm_channel_find_by_socket(struct rbm_session *session, rbm_
|
||||
|
||||
// Returns -1 on error, 0 when otherwise
|
||||
int rbm_ssh_setup(struct rbm_session *session) {
|
||||
const int ERROR = -1;
|
||||
const int SUCCESS = 0;
|
||||
struct rbm_ssh_tunnel_config *config = session->config;
|
||||
|
||||
ssh_log_debug(session, "Connecting to SSH server (%s:%d)...", config->sshserverip, config->sshserverport);
|
||||
ssh_log_debug(session, "Connecting to SSH server (%s:%d)...", config->sshserverhost, config->sshserverport);
|
||||
|
||||
session->sshsocket = socket_connect(session, config->sshserverip, config->sshserverport);
|
||||
session->sshsocket = socket_connect(session, config->sshserverhost, config->sshserverport);
|
||||
if (session->sshsocket == -1) {
|
||||
session->sshsocket = rbm_socket_invalid;
|
||||
return ERROR; // errors are already logged by socket_connect
|
||||
return RBM_ERROR; // errors are already logged by socket_connect
|
||||
}
|
||||
|
||||
session->sshsession = ssh_connect(session, session->sshsocket, config->authtype, config->username, config->password,
|
||||
config->publickeyfile, config->privatekeyfile, config->passphrase);
|
||||
if (session->sshsession == 0) {
|
||||
return ERROR; // errors are already logged by ssh_connect
|
||||
return RBM_ERROR; // errors are already logged by ssh_connect
|
||||
}
|
||||
|
||||
// Must use non-blocking IO hereafter due to the current libssh3 API
|
||||
libssh2_session_set_blocking(session->sshsession, 0);
|
||||
|
||||
return SUCCESS;
|
||||
return RBM_SUCCESS;
|
||||
}
|
||||
|
||||
void rbm_session_cleanup(struct rbm_session *session) {
|
||||
@@ -272,15 +301,13 @@ void rbm_session_cleanup(struct rbm_session *session) {
|
||||
// 3.
|
||||
if (session->sshsocket != rbm_socket_invalid) {
|
||||
ssh_log_debug(session, "Closing SSH socket");
|
||||
close(session->sshsocket);
|
||||
rbm_socket_close(session->sshsocket);
|
||||
session->sshsocket = rbm_socket_invalid;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int rbm_open_tunnel(struct rbm_session *connection) {
|
||||
const int ERROR = -1;
|
||||
const int SUCCESS = 0;
|
||||
rbm_socket_t local_socket = connection->localsocket;
|
||||
rbm_socket_t ssh_socket = connection->sshsocket;
|
||||
|
||||
@@ -290,9 +317,8 @@ int rbm_open_tunnel(struct rbm_session *connection) {
|
||||
|
||||
int fdmax; // maximum socket (file descriptor) number
|
||||
int isocket; // index for traversing sockets
|
||||
fd_set masterset, readset, clearset;
|
||||
fd_set masterset, readset;
|
||||
FD_ZERO(&masterset);
|
||||
FD_ZERO(&clearset);
|
||||
|
||||
// Add the listener to the master set
|
||||
FD_SET(local_socket, &masterset);
|
||||
@@ -305,9 +331,9 @@ int rbm_open_tunnel(struct rbm_session *connection) {
|
||||
|
||||
readset = masterset; // copy set
|
||||
|
||||
// If readset has no descriptors, it means that
|
||||
// If local (accept) socket is closed, it means that
|
||||
// session is closed and we should stop our work
|
||||
if (!memcmp(&readset, &clearset, sizeof(fd_set)))
|
||||
if (!FD_ISSET(local_socket, &readset))
|
||||
break;
|
||||
|
||||
ssh_log_debug(connection, "* Okay, we are ready to select.");
|
||||
@@ -346,18 +372,18 @@ int rbm_open_tunnel(struct rbm_session *connection) {
|
||||
|
||||
if (rc == -1) {
|
||||
ssh_log_warn(connection, "SSH tunnel shutdown because of error");
|
||||
return ERROR;
|
||||
return RBM_ERROR;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (errors >= maxerrors) {
|
||||
ssh_log_warn(connection, "SSH tunnel shutdown because of series of successive EAGAIN errors");
|
||||
return ERROR;
|
||||
return RBM_ERROR;
|
||||
}
|
||||
|
||||
rbm_ssh_session_close(connection->publicsession);
|
||||
return SUCCESS;
|
||||
return RBM_SUCCESS;
|
||||
}
|
||||
|
||||
// Return -1 on error. 0 otherwise.
|
||||
@@ -367,8 +393,6 @@ static int handle_new_client_connections(struct rbm_session *connection, int *fd
|
||||
LIBSSH2_SESSION* session = connection->sshsession;
|
||||
struct rbm_ssh_tunnel_config* config = connection->config;
|
||||
rbm_socket_t newfd = rbm_socket_invalid;
|
||||
const int ERROR = -1;
|
||||
const int SUCCESS = 0;
|
||||
|
||||
ssh_log_debug(connection, "Data on accept socket is available");
|
||||
|
||||
@@ -378,7 +402,7 @@ static int handle_new_client_connections(struct rbm_session *connection, int *fd
|
||||
// handle new connections
|
||||
if ((newfd = accept(local_socket, (struct sockaddr *) &remoteaddr, &slen)) == -1) {
|
||||
ssh_log_error(connection, "Error on accept()");
|
||||
return ERROR;
|
||||
return RBM_ERROR;
|
||||
} else {
|
||||
FD_SET(newfd, masterset); // add to master set
|
||||
|
||||
@@ -405,7 +429,8 @@ static int handle_new_client_connections(struct rbm_session *connection, int *fd
|
||||
|
||||
// Error 35: Resource temporarily unavailable.
|
||||
if (lerr == LIBSSH2_ERROR_EAGAIN) {
|
||||
usleep(200 * 1000);
|
||||
rbm_sleep_ms(200);
|
||||
// usleep(200 * 1000);
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -418,22 +443,20 @@ static int handle_new_client_connections(struct rbm_session *connection, int *fd
|
||||
|
||||
if (!channel) {
|
||||
ssh_log_error(connection, "Failed to create SSH channel");
|
||||
return ERROR;
|
||||
return RBM_ERROR;
|
||||
}
|
||||
|
||||
if (rbm_channel_create(connection, newfd, channel) == NULL) {
|
||||
return ERROR;
|
||||
return RBM_ERROR;
|
||||
}
|
||||
|
||||
return SUCCESS;
|
||||
return RBM_SUCCESS;
|
||||
}
|
||||
|
||||
// 0: success
|
||||
// -1:
|
||||
static int handle_ssh_connections(struct rbm_session *connection, fd_set *masterset) {
|
||||
const int AGAIN = -2;
|
||||
const int ERROR = -1;
|
||||
const int SUCCESS = 0;
|
||||
struct rbm_ssh_tunnel_config* config = connection->config;
|
||||
|
||||
ssh_log_debug(connection, "Data on SSH socket is available");
|
||||
@@ -442,11 +465,11 @@ static int handle_ssh_connections(struct rbm_session *connection, fd_set *master
|
||||
if (connection->channelssize == 0) {
|
||||
FD_CLR(connection->localsocket, masterset); // remove from master set
|
||||
FD_CLR(connection->sshsocket, masterset); // remove from master set
|
||||
return SUCCESS;
|
||||
return RBM_SUCCESS;
|
||||
}
|
||||
|
||||
int s = 0;
|
||||
int result = SUCCESS;
|
||||
int result = RBM_SUCCESS;
|
||||
int eagain = 0;
|
||||
while (s < connection->channelssize) {
|
||||
struct rbm_channel *context = connection->channels[s];
|
||||
@@ -479,9 +502,9 @@ static int handle_ssh_connections(struct rbm_session *connection, fd_set *master
|
||||
// Endless cycle:
|
||||
// Network is down. libssh2_channel_read: -43. (Error #50)
|
||||
|
||||
result = ERROR;
|
||||
result = RBM_ERROR;
|
||||
ssh_log_error(connection, "libssh2_channel_read: %d", len);
|
||||
return ERROR;
|
||||
return RBM_ERROR;
|
||||
}
|
||||
|
||||
firstflag = 0;
|
||||
@@ -492,14 +515,14 @@ static int handle_ssh_connections(struct rbm_session *connection, fd_set *master
|
||||
while (wr < len) {
|
||||
rc = send(context->socket, context->outbuf + wr, len - wr, 0);
|
||||
if (rc <= 0) {
|
||||
result = ERROR;
|
||||
result = RBM_ERROR;
|
||||
ssh_log_error(connection, "Failure to write data to client");
|
||||
break;
|
||||
}
|
||||
wr += rc;
|
||||
}
|
||||
if (libssh2_channel_eof(context->channel)) {
|
||||
result = SUCCESS;
|
||||
result = RBM_SUCCESS;
|
||||
ssh_log_debug(connection, "The server at %s:%d disconnected!\n",
|
||||
config->remotehost, config->remoteport);
|
||||
break;
|
||||
@@ -511,16 +534,14 @@ static int handle_ssh_connections(struct rbm_session *connection, fd_set *master
|
||||
}
|
||||
|
||||
static int handle_client_connections(struct rbm_session *connection, rbm_socket_t i, fd_set *masterset) {
|
||||
const int ERROR = -1;
|
||||
const int SUCCESS = 0;
|
||||
int result = SUCCESS;
|
||||
int result = RBM_SUCCESS;
|
||||
ssh_log_debug(connection, "Data on client socket is available");
|
||||
|
||||
struct rbm_channel *context = rbm_channel_find_by_socket(connection, i);
|
||||
if (!context) {
|
||||
close(i); // bye!
|
||||
rbm_socket_close(i); // bye!
|
||||
FD_CLR(i, masterset); // remove from master set
|
||||
return ERROR;
|
||||
return RBM_ERROR;
|
||||
}
|
||||
|
||||
// Read data from a client
|
||||
@@ -528,16 +549,16 @@ static int handle_client_connections(struct rbm_session *connection, rbm_socket_
|
||||
if (nbytes <= 0) {
|
||||
if (nbytes == 0) {
|
||||
// Normal situation
|
||||
result = SUCCESS;
|
||||
result = RBM_SUCCESS;
|
||||
ssh_log_debug(connection, "Client disconnected");
|
||||
} else {
|
||||
// Got error
|
||||
result = ERROR;
|
||||
result = RBM_ERROR;
|
||||
ssh_log_error(connection, "Error when recv()");
|
||||
}
|
||||
|
||||
// In both these cases, close and cleanup connection
|
||||
// close(context->socket); // bye!
|
||||
// rbm_socket_close(context->socket); // bye!
|
||||
FD_CLR(context->socket, masterset); // remove from master set
|
||||
rbm_channel_close(context);
|
||||
|
||||
@@ -562,20 +583,20 @@ static int handle_client_connections(struct rbm_session *connection, rbm_socket_
|
||||
|
||||
if (again > againmax) {
|
||||
ssh_log_warn(connection, "Number of attempts to libssh2_channel_write exсeed max value");
|
||||
return ERROR;
|
||||
return RBM_ERROR;
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
if (rc < 0) {
|
||||
ssh_log_error(connection, "Failed to write to SSH channel");
|
||||
return ERROR;
|
||||
return RBM_ERROR;
|
||||
}
|
||||
wr += rc;
|
||||
}
|
||||
ssh_log_debug(connection, "Written %d bytes to tunnel", wr);
|
||||
|
||||
return SUCCESS;
|
||||
return RBM_SUCCESS;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -583,27 +604,35 @@ static int handle_client_connections(struct rbm_session *connection, rbm_socket_
|
||||
*/
|
||||
static rbm_socket_t socket_connect(struct rbm_session* session, char *ip, int port) {
|
||||
rbm_socket_t sock;
|
||||
struct sockaddr_in sin;
|
||||
struct addrinfo hints, *res;
|
||||
int err;
|
||||
char cport[20];
|
||||
|
||||
/* Connect to SSH server */
|
||||
sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
|
||||
// We need port as decimal chars for "getaddrinfo"
|
||||
sprintf(cport, "%d", port);
|
||||
|
||||
memset(&hints, 0, sizeof(hints));
|
||||
hints.ai_family = PF_UNSPEC;
|
||||
hints.ai_socktype = SOCK_STREAM;
|
||||
err = getaddrinfo(ip, cport, &hints, &res);
|
||||
if (err) {
|
||||
ssh_log_error(session, "Failed to get address info");
|
||||
return -1;
|
||||
}
|
||||
|
||||
sock = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
|
||||
if (sock == rbm_socket_invalid) {
|
||||
ssh_log_error(session, "Failed to open socket");
|
||||
return -1;
|
||||
}
|
||||
|
||||
sin.sin_family = AF_INET;
|
||||
if (INADDR_NONE == (sin.sin_addr.s_addr = inet_addr(ip))) {
|
||||
ssh_log_error(session, "Call to inet_addr failed");
|
||||
return -1;
|
||||
}
|
||||
|
||||
sin.sin_port = htons(port);
|
||||
if (connect(sock, (struct sockaddr*)(&sin), sizeof(struct sockaddr_in)) != 0) {
|
||||
/* Connect to SSH server */
|
||||
if (connect(sock, res->ai_addr, res->ai_addrlen) != 0) {
|
||||
ssh_log_error(session, "Failed to connect to %s:%d", ip, port);
|
||||
return -1;
|
||||
}
|
||||
|
||||
freeaddrinfo(res);
|
||||
return sock;
|
||||
}
|
||||
|
||||
@@ -613,7 +642,13 @@ static rbm_socket_t socket_connect(struct rbm_session* session, char *ip, int po
|
||||
rbm_socket_t socket_listen(struct rbm_session *rsession, char *ip, int *port) {
|
||||
rbm_socket_t listensock;
|
||||
struct sockaddr_in sin;
|
||||
|
||||
#ifdef WIN32
|
||||
char sockopt;
|
||||
#else
|
||||
int sockopt;
|
||||
#endif
|
||||
|
||||
socklen_t sinlen;
|
||||
|
||||
listensock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
|
||||
@@ -657,7 +692,7 @@ rbm_socket_t socket_listen(struct rbm_session *rsession, char *ip, int *port) {
|
||||
*/
|
||||
LIBSSH2_SESSION *ssh_connect(struct rbm_session *rsession, rbm_socket_t sock, enum rbm_ssh_auth_type type, char *username, char *password,
|
||||
char *publickeypath, char *privatekeypath, char *passphrase) {
|
||||
int rc, i, auth = RBM_SSH_AUTH_TYPE_NONE;
|
||||
int rc, auth = RBM_SSH_AUTH_TYPE_NONE;
|
||||
LIBSSH2_SESSION *session;
|
||||
const char *fingerprint;
|
||||
char *userauthlist;
|
||||
@@ -729,3 +764,19 @@ LIBSSH2_SESSION *ssh_connect(struct rbm_session *rsession, rbm_socket_t sock, en
|
||||
|
||||
return session;
|
||||
}
|
||||
|
||||
static void rbm_sleep_ms(int ms) {
|
||||
#ifdef WIN32
|
||||
Sleep(ms);
|
||||
#else
|
||||
usleep(ms * 1000);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void rbm_socket_close(rbm_socket_t socket) {
|
||||
#ifdef WIN32
|
||||
closesocket(socket);
|
||||
#else
|
||||
close(socket);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -33,7 +33,7 @@ struct rbm_ssh_tunnel_config {
|
||||
char *localip;
|
||||
unsigned int localport;
|
||||
|
||||
// Remote host and port to connect to
|
||||
// Remote host (domain or IPv4/v6) and port to connect to
|
||||
char *remotehost; // Resolved by the remote server
|
||||
unsigned int remoteport;
|
||||
|
||||
@@ -41,9 +41,9 @@ struct rbm_ssh_tunnel_config {
|
||||
char *username;
|
||||
char *password; // May be NULL or ""
|
||||
|
||||
// Remote IP and (host, port) in remote network
|
||||
char *sshserverip;
|
||||
unsigned int sshserverport; // SSH port
|
||||
// Remote host (domain or IPv4/v6)
|
||||
char *sshserverhost;
|
||||
unsigned int sshserverport;
|
||||
|
||||
// Logging facilities
|
||||
enum rbm_ssh_log_type loglevel;
|
||||
|
||||
@@ -49,31 +49,7 @@ include(SocketLibraries)
|
||||
|
||||
if (WIN32)
|
||||
# Statically linking to OpenSSL requires crypt32 for some Windows APIs.
|
||||
# This should really be handled by FindOpenSSL.cmake.
|
||||
list(APPEND LIBRARIES crypt32)
|
||||
list(APPEND PC_LIBS -lcrypt32)
|
||||
|
||||
find_file(DLL_LIBEAY32
|
||||
NAMES libeay32.dll crypto.dll
|
||||
HINTS ${_OPENSSL_ROOT_HINTS} PATHS ${_OPENSSL_ROOT_PATHS}
|
||||
PATH_SUFFIXES bin)
|
||||
|
||||
if (NOT DLL_LIBEAY32)
|
||||
message(WARNING "Unable to find OpenSSL libeay32 DLL, executables may not run")
|
||||
endif()
|
||||
|
||||
find_file(DLL_SSLEAY32
|
||||
NAMES ssleay32.dll ssl.dll
|
||||
HINTS ${_OPENSSL_ROOT_HINTS} PATHS ${_OPENSSL_ROOT_PATHS}
|
||||
PATH_SUFFIXES bin)
|
||||
|
||||
if (NOT DLL_SSLEAY32)
|
||||
message(WARNING "Unable to find OpenSSL ssleay32 DLL, executables may not run")
|
||||
endif()
|
||||
|
||||
if(DLL_LIBEAY32 AND DLL_SSLEAY32)
|
||||
list(APPEND _RUNTIME_DEPENDENCIES ${DLL_LIBEAY32} ${DLL_SSLEAY32})
|
||||
endif()
|
||||
endif()
|
||||
|
||||
set(HAVE_EVP_AES_128_CTR YES)
|
||||
@@ -252,3 +228,7 @@ else()
|
||||
target_link_libraries(libssh2 PRIVATE ${LIBRARIES})
|
||||
endif()
|
||||
|
||||
# Ignore single compiler warning for this third-party project
|
||||
if(COMPILER_MSVC)
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /wd4133")
|
||||
endif()
|
||||
|
||||
@@ -51,7 +51,7 @@ file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/opensslconf.h.cmake "${CONF}")
|
||||
#~2DO: set BUILDINF_DATE to `date LC_ALL=C LC_TIME=C`
|
||||
configure_file(${crypto_dir}/buildinf.h.cmake buildinf.h)
|
||||
|
||||
if(WIN32 AND MINGW AND NOT CYGWIN)
|
||||
if(WIN32)
|
||||
set(OPENSSL_EXPORT_VAR_AS_FUNCTION true)
|
||||
endif()
|
||||
configure_file(${CMAKE_CURRENT_BINARY_DIR}/opensslconf.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/openssl/opensslconf.h)
|
||||
@@ -281,3 +281,9 @@ target_include_directories(ssl
|
||||
${ssl_dir}/..
|
||||
PUBLIC
|
||||
${ssl_dir}/../include )
|
||||
|
||||
|
||||
# Ignore 4 types of compiler warnings for this third-party project
|
||||
if(COMPILER_MSVC)
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /wd4267 /wd4244 /wd4996 /wd4273")
|
||||
endif()
|
||||
@@ -25,3 +25,10 @@ target_include_directories(qjson
|
||||
target_compile_definitions(qjson
|
||||
PUBLIC
|
||||
QJSON_STATIC)
|
||||
|
||||
if (COMPILER_CLANG OR COMPILER_GCC)
|
||||
# Project uses autogenerated code that have "register" variables
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-deprecated-register")
|
||||
elseif(COMPILER_MSVC)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /wd4065")
|
||||
endif()
|
||||
@@ -245,3 +245,15 @@ target_compile_definitions(qscintilla
|
||||
SCINTILLA_QT
|
||||
SCI_LEXER)
|
||||
|
||||
# Project produces three types of warnings that are all not critical.
|
||||
# We are turning them off to remove noise
|
||||
if (COMPILER_CLANG OR COMPILER_GCC)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-dangling-else -Wno-parentheses -Wno-switch")
|
||||
elseif(COMPILER_MSVC)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /wd4554 /wd4099")
|
||||
|
||||
# Suppress the following warning: MacPasteboardMime.obj : warning LNK4221: This object
|
||||
# file does not define any previously undefined public symbols, so it will not be used
|
||||
# by any link operation that consumes this library
|
||||
set(CMAKE_STATIC_LINKER_FLAGS "${CMAKE_STATIC_LINKER_FLAGS} /IGNORE:4221")
|
||||
endif()
|
||||
|
||||