Compare commits

...

35 Commits

Author SHA1 Message Date
773a0081e3 remove (wrong) version line from .desktop file 2018-05-15 22:48:18 -04:00
8b69f9fe03 better handling of non-git builds 2018-05-14 12:55:03 -04:00
0b2dfd80e2 move protocol version to new line in --version output (fix display issue in created manpages) 2018-05-14 12:23:24 -04:00
c7569f8af7 update manpages 2018-05-12 18:35:18 -04:00
walker0643
b8ad9b8aba Set theme jekyll-theme-slate 2018-05-12 18:24:22 -04:00
9ab77545ee fix ipv6 handling between GUI and barriers/barrierc; zero-fill sockaddr_in(6) structs prior to initializing; update --help output 2018-05-12 17:42:55 -04:00
f4301a7618 fix usage of m_pname and rename to m_exename 2018-05-12 17:32:26 -04:00
f299558cdf remove stale definitions 2018-05-12 17:20:35 -04:00
7fd6711829 remove stale references to syntool/synwinhk 2018-05-10 11:42:08 -04:00
b43581c2f5 remove explicit paths from .desktop file 2018-05-07 13:21:25 -04:00
bd4c214c39 bump version to 2.1. remove dependence on git for tarball builds. 2018-05-07 13:20:40 -04:00
642eb33446 make linux/bsd data directory conform to freedesktop standards. fixes #31 2018-05-07 12:57:06 -04:00
walker0643
0b5ca57b9c Merge pull request #26 from debauchee/nosyntool
Drop syntool. In the process some platform-dependent locations have changed. Some users may need to recreate config files or copy the from the old location(s).
2018-04-14 18:20:19 -04:00
a7fb1b56f6 Merge branch 'master' into nosyntool 2018-04-01 21:14:32 -04:00
5e19820425 remove dangling handler..fixes race condition when a clipboard event is queued but not dispatched before disconnect 2018-04-01 21:13:56 -04:00
9e7792e2ae add comment re C++17 to MSWindowsUtil.cpp 2018-04-01 14:57:22 -04:00
42a8f69050 better comments in PathUtilities.cpp 2018-04-01 14:47:34 -04:00
1734e6d7f6 Merge branch 'master' into nosyntool 2018-04-01 14:04:53 -04:00
6c4199b11a fix mainwindow icon 2018-04-01 14:00:52 -04:00
767188799e add desktop name to DEBUG output. when is desktop ever NOT "Default" ? 2018-04-01 13:59:14 -04:00
e6d0f40a36 add legal header to new files 2018-04-01 12:43:55 -04:00
129e61a33a server should look for config in the profile() dir rather than the personal() dir. removed personal() since it is no longer used. 2018-03-31 22:48:59 -04:00
4c04f39685 reimplement path operations basename() and concat() in Common. these were the last bits remaining in ArchFile* so it was removed 2018-03-31 22:41:00 -04:00
131a19d478 reimplement ArchFile*::getSystemDirectory() as DataDirectories::systemconfig(). windows will now use ProgramData by default rather than C:\Windows 2018-03-30 14:39:12 -04:00
6c5acdd552 remove DataDirectory wrappers in ArchFile* 2018-03-30 14:01:18 -04:00
d81054ab6e remove some stale code and put windows service logfile in a better spot 2018-03-29 21:41:30 -04:00
1be86a9248 remove syntool, CoreInterface, and WebClient 2018-03-29 17:14:57 -04:00
ea025f5958 fix --profile-dir argument 2018-03-29 17:13:45 -04:00
6e5b340bcc replace CoreInterface syntool calls with DataDirectory calls 2018-03-29 16:38:50 -04:00
451bd72b30 MSWindowsWatchdog checks active desktop without external call to syntool 2018-03-29 16:32:51 -04:00
c16fd089f6 old personal and profile directory functions now wrap the new implementations 2018-03-29 16:12:45 -04:00
96627f4f07 reimplement finding personal & profile directories on unix (not yet used) 2018-03-29 15:54:41 -04:00
c5e70af09a DataDirectories header should be shared between platform-specific implementations 2018-03-29 15:50:23 -04:00
72cc7e3d89 link gui with common; reimplement finding personal and profile directories on windows (not yet used) 2018-03-29 14:01:07 -04:00
fe818a4955 add console for ctrl+c to daemon app when debugging in foreground 2018-03-29 12:02:35 -04:00
61 changed files with 596 additions and 1534 deletions

1
_config.yml Normal file
View File

@@ -0,0 +1 @@
theme: jekyll-theme-slate

View File

@@ -1,7 +1,7 @@
cmake_minimum_required (VERSION 3.4)
set (BARRIER_VERSION_MAJOR 2)
set (BARRIER_VERSION_MINOR 0)
set (BARRIER_VERSION_MINOR 1)
set (BARRIER_VERSION_PATCH 0)
#
@@ -44,24 +44,24 @@ if (NOT DEFINED BARRIER_REVISION)
if (DEFINED ENV{GIT_COMMIT})
string (SUBSTRING $ENV{GIT_COMMIT} 0 8 BARRIER_REVISION)
else()
execute_process (
COMMAND git rev-parse --short=8 HEAD
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
OUTPUT_VARIABLE BARRIER_REVISION
OUTPUT_STRIP_TRAILING_WHITESPACE
)
find_program (GIT_BINARY git)
if (NOT GIT_BINARY STREQUAL "GIT_BINARY-NOTFOUND")
execute_process (
COMMAND git rev-parse --short=8 HEAD
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
OUTPUT_VARIABLE BARRIER_REVISION
OUTPUT_STRIP_TRAILING_WHITESPACE
)
endif()
endif()
endif()
if (DEFINED BARRIER_REVISION)
string(LENGTH ${BARRIER_REVISION} BARRIER_REVISION_LENGTH)
if (NOT ((BARRIER_REVISION MATCHES "^[a-f0-9]+") AND (BARRIER_REVISION_LENGTH EQUAL "8")))
message (FATAL_ERROR "BARRIER_REVISION ('${BARRIER_REVISION}') should be a short commit hash")
endif()
unset (BARRIER_REVISION_LENGTH)
else()
set (BARRIER_REVISION "0badc0de")
string(LENGTH "${BARRIER_REVISION}" BARRIER_REVISION_LENGTH)
if (NOT BARRIER_REVISION_LENGTH EQUAL 8 OR NOT BARRIER_REVISION MATCHES "^[a-f0-9]+")
set (BARRIER_REVISION "00000000")
message (WARNING "revision not found. setting to ${BARRIER_REVISION}")
endif()
unset (BARRIER_REVISION_LENGTH)
if (DEFINED ENV{BUILD_NUMBER})
set (BARRIER_BUILD_NUMBER $ENV{BUILD_NUMBER})

View File

@@ -18,7 +18,6 @@ Work seamlessly across Windows, macOS and Linux.
%{_bindir}/barrier
%{_bindir}/barrierc
%{_bindir}/barriers
%{_bindir}/syntool
%attr(644,-,-) %{_datarootdir}/applications/barrier.desktop
%attr(644,-,-) %{_datarootdir}/icons/hicolor/scalable/apps/barrier.svg

View File

@@ -60,8 +60,6 @@
<fire:FirewallException Id="ServerFirewallException" IgnoreFailure="yes" Name="$(var.Name)" Scope="any"/>
</File>
<File Source="$(var.BinPath)/barrierc.exe"/>
<File Source="$(var.BinPath)/syntool.exe"/>
<File Source="$(var.BinPath)/synwinhk.dll"/>
<File Source="$(var.OpenSSLBinPath)/libeay32.dll"/>
<File Source="$(var.OpenSSLBinPath)/ssleay32.dll"/>
<File Source="$(var.OpenSSLBinPath)/openssl.exe"/>

View File

@@ -1,5 +1,5 @@
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.47.6.
.TH BARRIERC "1" "March 2018" "barrierc 2.0.0, protocol version 1.6" "User Commands"
.TH BARRIERC "1" "May 2018" "barrierc 2.1.0-snapshot" "User Commands"
.SH NAME
barrierc \- Barrier Keyboard/Mouse Client
.SH SYNOPSIS
@@ -59,9 +59,10 @@ display version information and exit.
.PP
Default options are marked with a *
.PP
The server address is of the form: [<hostname>][:<port>]. The hostname
must be the address or hostname of the server. The port overrides the
default port, 24800.
The server address is of the form: [<hostname>][:<port>]. The hostname
must be the address or hostname of the server. Placing brackets around
an IPv6 address is required when also specifying a port number and
optional otherwise. The default port number is 24800.
.SH COPYRIGHT
Copyright \(co 2018 Debauchee Open Source Group
.br

View File

@@ -1,5 +1,5 @@
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.47.6.
.TH BARRIERS "1" "March 2018" "barriers 2.0.0, protocol version 1.6" "User Commands"
.TH BARRIERS "1" "May 2018" "barriers 2.1.0-snapshot" "User Commands"
.SH NAME
barriers \- Barrier Keyboard/Mouse Server
.SH SYNOPSIS
@@ -63,13 +63,14 @@ Default options are marked with a *
.PP
The argument for \fB\-\-address\fR is of the form: [<hostname>][:<port>]. The
hostname must be the address or hostname of an interface on the system.
The default is to listen on all interfaces. The port overrides the
default port, 24800.
Placing brackets around an IPv6 address is required when also specifying
a port number and optional otherwise. The default is to listen on all
interfaces using port number 24800.
.PP
If no configuration file pathname is provided then the first of the
following to load successfully sets the configuration:
.IP
$HOME/.barrier.conf
$HOME/.local/share/barrier/barrier.conf
\fI\,/etc/barrier.conf\/\fP
.SH COPYRIGHT
Copyright \(co 2018 Debauchee Open Source Group

View File

@@ -1,10 +1,8 @@
[Desktop Entry]
Type=Application
Version=1.0
Name=Barrier
Comment=Keyboard and mouse sharing solution
Path=/usr/bin
Exec=/usr/bin/barrier
Exec=barrier
Icon=barrier
Terminal=false
Categories=Utility;

View File

@@ -1,11 +0,0 @@
[Desktop Entry]
Type=Application
Version=1.0
Name=Barrier
Comment=Keyboard and mouse sharing solution
Path=/usr/bin
Exec=/usr/bin/barrier2
Icon=barrier
Terminal=false
Categories=Utility;
Keywords=keyboard;mouse;sharing;network;share;

View File

@@ -16,7 +16,6 @@
add_subdirectory(barrierc)
add_subdirectory(barriers)
add_subdirectory(syntool)
if (WIN32)
add_subdirectory(barrierd)

View File

@@ -1,27 +0,0 @@
# barrier -- mouse and keyboard sharing utility
# Copyright (C) 2014-2016 Symless Ltd.
#
# This package is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# found in the file LICENSE that should have accompanied this file.
#
# This package is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
file(GLOB headers "*.h")
file(GLOB sources "*.cpp")
add_executable(syntool ${sources})
target_link_libraries(syntool
synlib arch base client common io ipc mt net platform server ${libs} ${OPENSSL_LIBS})
if (${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
install (TARGETS syntool DESTINATION ${BARRIER_BUNDLE_BINARY_DIR})
elseif (${CMAKE_SYSTEM_NAME} MATCHES "Linux")
install (TARGETS syntool DESTINATION bin)
endif()

View File

@@ -1,31 +0,0 @@
/*
* barrier -- mouse and keyboard sharing utility
* Copyright (C) 2014-2016 Symless Ltd.
*
* This package is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* found in the file LICENSE that should have accompanied this file.
*
* This package is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "barrier/ToolApp.h"
#include "arch/Arch.h"
int
main(int argc, char** argv)
{
#if SYSAPI_WIN32
// record window instance for tray icon, etc
ArchMiscWindows::setInstanceWin32(GetModuleHandle(NULL));
#endif
ToolApp app;
return app.run(argc, argv);
}

View File

@@ -45,6 +45,8 @@ if (HAVE_X11)
target_link_libraries (barrier X11)
endif()
target_link_libraries (barrier common)
if (${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
install (TARGETS barrier DESTINATION ${BARRIER_BUNDLE_BINARY_DIR})
elseif (${CMAKE_SYSTEM_NAME} MATCHES "Linux")

View File

@@ -1,96 +0,0 @@
/*
* barrier -- mouse and keyboard sharing utility
* Copyright (C) 2015-2016 Symless Ltd.
*
* This package is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* found in the file LICENSE that should have accompanied this file.
*
* This package is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "CoreInterface.h"
#include "CommandProcess.h"
#include "QUtility.h"
#include <QCoreApplication>
#include <QProcess>
#include <QtGlobal>
#include <QDir>
#include <stdexcept>
static const char kCoreBinary[] = "syntool";
#ifdef Q_WS_WIN
static const char kSerialKeyFilename[] = "Barrier.subkey";
#else
static const char kSerialKeyFilename[] = ".barrier.subkey";
#endif
CoreInterface::CoreInterface()
{
}
QString CoreInterface::getProfileDir()
{
QStringList args("--get-profile-dir");
return run(args);
}
QString CoreInterface::getInstalledDir()
{
QStringList args("--get-installed-dir");
return run(args);
}
QString CoreInterface::getArch()
{
QStringList args("--get-arch");
return run(args);
}
QString CoreInterface::getSerialKeyFilePath()
{
QString filename = getProfileDir() + QDir::separator() + kSerialKeyFilename;
return filename;
}
QString CoreInterface::notifyUpdate (QString const& fromVersion,
QString const& toVersion,
QString const& serialKey) {
QStringList args("--notify-update");
QString input(fromVersion + ":" + toVersion + ":" + serialKey);
input.append("\n");
return run(args, input);
}
QString CoreInterface::notifyActivation(const QString& identity)
{
QStringList args("--notify-activation");
QString input(identity + ":" + hash(getFirstMacAddress()));
QString os= getOSInformation();
if (!os.isEmpty()) {
input.append(":").append(os);
}
input.append("\n");
return run(args, input);
}
QString CoreInterface::run(const QStringList& args, const QString& input)
{
QString program(
QCoreApplication::applicationDirPath()
+ "/" + kCoreBinary);
CommandProcess commandProcess(program, args, input);
return commandProcess.run();
}

View File

@@ -1,36 +0,0 @@
/*
* barrier -- mouse and keyboard sharing utility
* Copyright (C) 2015-2016 Symless Ltd.
*
* This package is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* found in the file LICENSE that should have accompanied this file.
*
* This package is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <QString>
class CoreInterface
{
public:
CoreInterface();
QString getProfileDir();
QString getInstalledDir();
QString getArch();
QString getSerialKeyFilePath();
QString notifyActivation(const QString& identity);
QString notifyUpdate (QString const& fromVersion,
QString const& toVersion,
QString const& serialKey);
QString run(const QStringList& args, const QString& input = "");
};

View File

@@ -17,7 +17,7 @@
#include "Fingerprint.h"
#include "CoreInterface.h"
#include "common/DataDirectories.h"
#include <QDir>
#include <QTextStream>
@@ -125,8 +125,7 @@ void Fingerprint::persistDirectory()
QString Fingerprint::directoryPath()
{
CoreInterface coreInterface;
QString profileDir = coreInterface.getProfileDir();
auto profileDir = QString::fromStdString(DataDirectories::profile());
return QString("%1/%2")
.arg(profileDir)

View File

@@ -21,9 +21,6 @@
class Fingerprint
{
private:
Fingerprint(const QString& filename);
public:
void trust(const QString& fingerprintText, bool append = true);
bool isTrusted(const QString& fingerprintText);
@@ -32,15 +29,14 @@ public:
QString filePath() const;
bool fileExists() const;
public:
static Fingerprint local();
static Fingerprint trustedServers();
static Fingerprint trustedClients();
static QString directoryPath();
static QString localFingerprint();
static bool localFingerprintExists();
static void persistDirectory();
private:
Fingerprint(const QString& filename);
QString m_Filename;
};

View File

@@ -31,6 +31,7 @@
#include "ProcessorArch.h"
#include "SslCertificate.h"
#include "ShutdownCh.h"
#include "common/DataDirectories.h"
#include <QtCore>
#include <QtGui>
@@ -72,6 +73,8 @@ static const char* barrierIconFiles[] =
":/res/icons/16x16/barrier-transfering.png"
};
static const char* barrierLargeIcon = ":/res/icons/256x256/barrier.ico";
MainWindow::MainWindow(QSettings& settings, AppConfig& appConfig) :
m_Settings(settings),
m_AppConfig(&appConfig),
@@ -104,7 +107,7 @@ MainWindow::MainWindow(QSettings& settings, AppConfig& appConfig) :
setAttribute(Qt::WA_X11NetWmWindowTypeDialog, true);
setupUi(this);
setWindowIcon(QIcon(barrierLargeIcon));
createMenuBar();
loadSettings();
initConnections();
@@ -285,13 +288,8 @@ void MainWindow::saveSettings()
void MainWindow::setIcon(qBarrierState state)
{
QIcon icon;
icon.addFile(barrierIconFiles[state]);
setWindowIcon(icon);
if (m_pTrayIcon)
m_pTrayIcon->setIcon(icon);
m_pTrayIcon->setIcon(QIcon(barrierIconFiles[state]));
}
void MainWindow::trayActivated(QSystemTrayIcon::ActivationReason reason)
@@ -503,7 +501,7 @@ void MainWindow::startBarrier()
// launched the process (e.g. when launched with elevation). setting the
// profile dir on launch ensures it uses the same profile dir is used
// no matter how its relaunched.
args << "--profile-dir" << getProfileRootForArg();
args << "--profile-dir" << QString::fromStdString("\"" + DataDirectories::profile() + "\"");
#endif
if ((barrierType() == barrierClient && !clientArgs(args, app))
@@ -583,7 +581,7 @@ bool MainWindow::clientArgs(QStringList& args, QString& app)
if (m_pCheckBoxAutoConfig->isChecked()) {
if (m_pComboServerList->count() != 0) {
QString serverIp = m_pComboServerList->currentText();
args << serverIp + ":" + QString::number(appConfig().port());
args << "[" + serverIp + "]:" + QString::number(appConfig().port());
return true;
}
}
@@ -597,7 +595,7 @@ bool MainWindow::clientArgs(QStringList& args, QString& app)
return false;
}
args << m_pLineEditHostname->text() + ":" + QString::number(appConfig().port());
args << "[" + m_pLineEditHostname->text() + "]:" + QString::number(appConfig().port());
return true;
}
@@ -639,8 +637,10 @@ QString MainWindow::configFilename()
QString MainWindow::address()
{
QString i = appConfig().networkInterface();
return (!i.isEmpty() ? i : "") + ":" + QString::number(appConfig().port());
QString address = appConfig().networkInterface();
if (!address.isEmpty())
address = "[" + address + "]";
return address + ":" + QString::number(appConfig().port());
}
QString MainWindow::appPath(const QString& name)
@@ -1252,21 +1252,6 @@ void MainWindow::bonjourInstallFinished()
m_pCheckBoxAutoConfig->setChecked(true);
}
QString MainWindow::getProfileRootForArg()
{
CoreInterface coreInterface;
QString dir = coreInterface.getProfileDir();
// HACK: strip our app name since we're returning the root dir.
#if defined(Q_OS_WIN)
dir.replace("\\Barrier", "");
#else
dir.replace("/.barrier", "");
#endif
return QString("\"%1\"").arg(dir);
}
void MainWindow::windowStateChanged()
{
if (windowState() == Qt::WindowMinimized && appConfig().getMinimizeToTray())

View File

@@ -166,7 +166,6 @@ public slots:
bool isBonjourRunning();
void downloadBonjour();
void promptAutoConfig();
QString getProfileRootForArg();
void checkConnected(const QString& line);
void checkFingerprint(const QString& line);
void restartBarrier();

View File

@@ -18,7 +18,6 @@
#include "SettingsDialog.h"
#include "CoreInterface.h"
#include "BarrierLocale.h"
#include "QBarrierApplication.h"
#include "QUtility.h"

View File

@@ -23,7 +23,6 @@
#include <QDialog>
#include "ui_SettingsDialogBase.h"
#include "BarrierLocale.h"
#include "CoreInterface.h"
class AppConfig;
@@ -43,7 +42,6 @@ class SettingsDialog : public QDialog, public Ui::SettingsDialogBase
private:
AppConfig& m_appConfig;
BarrierLocale m_Locale;
CoreInterface m_CoreInterface;
private slots:
void on_m_pComboLanguage_currentIndexChanged(int index);

View File

@@ -17,7 +17,6 @@
#include "SetupWizard.h"
#include "MainWindow.h"
#include "WebClient.h"
#include "QBarrierApplication.h"
#include "QUtility.h"

View File

@@ -16,8 +16,8 @@
*/
#include "SslCertificate.h"
#include "Fingerprint.h"
#include "common/DataDirectories.h"
#include <QProcess>
#include <QDir>
@@ -37,7 +37,7 @@ static const char kConfigFile[] = "barrier.conf";
SslCertificate::SslCertificate(QObject *parent) :
QObject(parent)
{
m_ProfileDir = m_CoreInterface.getProfileDir();
m_ProfileDir = QString::fromStdString(DataDirectories::profile());
if (m_ProfileDir.isEmpty()) {
emit error(tr("Failed to get profile directory."));
}

View File

@@ -17,8 +17,6 @@
#pragma once
#include "CoreInterface.h"
#include <QObject>
class SslCertificate : public QObject
@@ -43,5 +41,4 @@ private:
private:
QString m_ProfileDir;
QString m_ToolOutput;
CoreInterface m_CoreInterface;
};

View File

@@ -1,83 +0,0 @@
/*
* barrier -- mouse and keyboard sharing utility
* Copyright (C) 2015-2016 Symless Ltd.
*
* This package is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* found in the file LICENSE that should have accompanied this file.
*
* This package is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "WebClient.h"
#include "QUtility.h"
#include <QProcess>
#include <QMessageBox>
#include <QCoreApplication>
#include <stdexcept>
bool
WebClient::getEdition (int& edition, QString& errorOut) {
QString responseJson = request();
/* TODO: This is horrible and should be ripped out as soon as we move
* to Qt 5. See issue #5630
*/
QRegExp resultRegex(".*\"result\".*:.*(true|false).*");
if (resultRegex.exactMatch (responseJson)) {
QString boolString = resultRegex.cap(1);
if (boolString == "true") {
QRegExp editionRegex(".*\"edition\".*:.*\"([^\"]+)\".*");
if (editionRegex.exactMatch(responseJson)) {
QString e = editionRegex.cap(1);
edition = e.toInt();
return true;
} else {
throw std::runtime_error ("Unrecognised server response.");
}
} else {
errorOut = tr("Login failed. Invalid email address or password.");
return false;
}
} else {
QRegExp errorRegex(".*\"error\".*:.*\"([^\"]+)\".*");
if (errorRegex.exactMatch (responseJson)) {
errorOut = errorRegex.cap(1).replace("\\n", "\n");
return false;
} else {
throw std::runtime_error ("Unrecognised server response.");
}
}
}
bool
WebClient::setEmail (QString email, QString& errorOut) {
if (email.isEmpty()) {
errorOut = tr("Your email address cannot be left blank.");
return false;
}
m_Email = email;
return true;
}
bool
WebClient::setPassword (QString password, QString&) {
m_Password = password;
return true;
}
QString
WebClient::request() {
QStringList args("--login-auth");
QString credentials (m_Email + ":" + hash(m_Password) + "\n");
return m_CoreInterface.run (args, credentials);
}

View File

@@ -1,49 +0,0 @@
/*
* barrier -- mouse and keyboard sharing utility
* Copyright (C) 2015-2016 Symless Ltd.
*
* This package is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* found in the file LICENSE that should have accompanied this file.
*
* This package is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef WEBCLIENT_H
#define WEBCLIENT_H
#include <QString>
#include <QObject>
#include "CoreInterface.h"
class QMessageBox;
class QWidget;
class QStringList;
class WebClient : public QObject
{
Q_OBJECT
public:
bool getEdition (int& edition, QString& errorOut);
bool setEmail (QString email, QString& errorOut);
bool setPassword (QString password, QString& errorOut);
signals:
void error(QString e);
private:
QString request();
QString m_Email;
QString m_Password;
CoreInterface m_CoreInterface;
};
#endif // WEBCLIENT_H

View File

@@ -40,7 +40,6 @@
#if SYSAPI_WIN32
# include "arch/win32/ArchConsoleWindows.h"
# include "arch/win32/ArchDaemonWindows.h"
# include "arch/win32/ArchFileWindows.h"
# include "arch/win32/ArchLogWindows.h"
# include "arch/win32/ArchMiscWindows.h"
# include "arch/win32/ArchMultithreadWindows.h"
@@ -54,7 +53,6 @@
#elif SYSAPI_UNIX
# include "arch/unix/ArchConsoleUnix.h"
# include "arch/unix/ArchDaemonUnix.h"
# include "arch/unix/ArchFileUnix.h"
# include "arch/unix/ArchLogUnix.h"
# if HAVE_PTHREAD
# include "arch/unix/ArchMultithreadPosix.h"
@@ -86,7 +84,6 @@ typically at the beginning of \c main().
*/
class Arch : public ARCH_CONSOLE,
public ARCH_DAEMON,
public ARCH_FILE,
public ARCH_LOG,
public ARCH_MULTITHREAD,
public ARCH_NETWORK,

View File

@@ -1,105 +0,0 @@
/*
* barrier -- mouse and keyboard sharing utility
* Copyright (C) 2012-2016 Symless Ltd.
* Copyright (C) 2002 Chris Schoeneman
*
* This package is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* found in the file LICENSE that should have accompanied this file.
*
* This package is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include "common/IInterface.h"
#include "common/stdstring.h"
#include "base/String.h"
//! Interface for architecture dependent file system operations
/*!
This interface defines the file system operations required by
barrier. Each architecture must implement this interface.
*/
class IArchFile : public IInterface {
public:
//! @name manipulators
//@{
//! Extract base name
/*!
Find the base name in the given \c pathname.
*/
virtual const char* getBasename(const char* pathname) = 0;
//! Get user's home directory
/*!
Returns the user's home directory. Returns the empty string if
this cannot be determined.
*/
virtual std::string getUserDirectory() = 0;
//! Get system directory
/*!
Returns the ussystem configuration file directory.
*/
virtual std::string getSystemDirectory() = 0;
//! Get installed directory
/*!
Returns the directory in which Barrier is installed.
*/
virtual std::string getInstalledDirectory() = 0;
//! Get log directory
/*!
Returns the log file directory.
*/
virtual std::string getLogDirectory() = 0;
//! Get plugins directory
/*!
Returns the plugin files directory. If no plugin directory is set,
this will return the plugin folder within the user's profile.
*/
virtual std::string getPluginDirectory() = 0;
//! Get user's profile directory
/*!
Returns the user's profile directory. If no profile directory is set,
this will return the user's profile according to the operating system,
which will depend on which user launched the program.
*/
virtual std::string getProfileDirectory() = 0;
//! Concatenate path components
/*!
Concatenate pathname components with a directory separator
between them. This should not check if the resulting path
is longer than allowed by the system; we'll rely on the
system calls to tell us that.
*/
virtual std::string concatPath(
const std::string& prefix,
const std::string& suffix) = 0;
//@}
//! Set the user's profile directory
/*
Returns the user's profile directory.
*/
virtual void setProfileDirectory(const String& s) = 0;
//@}
//! Set the user's plugin directory
/*
Returns the user's plugin directory.
*/
virtual void setPluginDirectory(const String& s) = 0;
};

View File

@@ -1,163 +0,0 @@
/*
* barrier -- mouse and keyboard sharing utility
* Copyright (C) 2012-2016 Symless Ltd.
* Copyright (C) 2002 Chris Schoeneman
*
* This package is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* found in the file LICENSE that should have accompanied this file.
*
* This package is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "arch/unix/ArchFileUnix.h"
#include <stdio.h>
#include <unistd.h>
#include <pwd.h>
#include <sys/types.h>
#include <cstring>
//
// ArchFileUnix
//
ArchFileUnix::ArchFileUnix()
{
// do nothing
}
ArchFileUnix::~ArchFileUnix()
{
// do nothing
}
const char*
ArchFileUnix::getBasename(const char* pathname)
{
if (pathname == NULL) {
return NULL;
}
const char* basename = strrchr(pathname, '/');
if (basename != NULL) {
return basename + 1;
}
else {
return pathname;
}
}
std::string
ArchFileUnix::getUserDirectory()
{
char* buffer = NULL;
std::string dir;
#if HAVE_GETPWUID_R
struct passwd pwent;
struct passwd* pwentp;
#if defined(_SC_GETPW_R_SIZE_MAX)
long size = sysconf(_SC_GETPW_R_SIZE_MAX);
if (size == -1) {
size = BUFSIZ;
}
#else
long size = BUFSIZ;
#endif
buffer = new char[size];
getpwuid_r(getuid(), &pwent, buffer, size, &pwentp);
#else
struct passwd* pwentp = getpwuid(getuid());
#endif
if (pwentp != NULL && pwentp->pw_dir != NULL) {
dir = pwentp->pw_dir;
}
delete[] buffer;
return dir;
}
std::string
ArchFileUnix::getSystemDirectory()
{
return "/etc";
}
std::string
ArchFileUnix::getInstalledDirectory()
{
#if WINAPI_XWINDOWS
return "/usr/bin";
#else
return "/Applications/Barrier.app/Contents/MacOS";
#endif
}
std::string
ArchFileUnix::getLogDirectory()
{
return "/var/log";
}
std::string
ArchFileUnix::getPluginDirectory()
{
if (!m_pluginDirectory.empty()) {
return m_pluginDirectory;
}
#if WINAPI_XWINDOWS
return getProfileDirectory().append("/plugins");
#else
return getProfileDirectory().append("/Plugins");
#endif
}
std::string
ArchFileUnix::getProfileDirectory()
{
String dir;
if (!m_profileDirectory.empty()) {
dir = m_profileDirectory;
}
else {
#if WINAPI_XWINDOWS
dir = getUserDirectory().append("/.barrier");
#else
dir = getUserDirectory().append("/Library/Application Support/Barrier");
#endif
}
return dir;
}
std::string
ArchFileUnix::concatPath(const std::string& prefix,
const std::string& suffix)
{
std::string path;
path.reserve(prefix.size() + 1 + suffix.size());
path += prefix;
if (path.size() == 0 || path[path.size() - 1] != '/') {
path += '/';
}
path += suffix;
return path;
}
void
ArchFileUnix::setProfileDirectory(const String& s)
{
m_profileDirectory = s;
}
void
ArchFileUnix::setPluginDirectory(const String& s)
{
m_pluginDirectory = s;
}

View File

@@ -1,47 +0,0 @@
/*
* barrier -- mouse and keyboard sharing utility
* Copyright (C) 2012-2016 Symless Ltd.
* Copyright (C) 2002 Chris Schoeneman
*
* This package is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* found in the file LICENSE that should have accompanied this file.
*
* This package is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include "arch/IArchFile.h"
#define ARCH_FILE ArchFileUnix
//! Unix implementation of IArchFile
class ArchFileUnix : public IArchFile {
public:
ArchFileUnix();
virtual ~ArchFileUnix();
// IArchFile overrides
virtual const char* getBasename(const char* pathname);
virtual std::string getUserDirectory();
virtual std::string getSystemDirectory();
virtual std::string getInstalledDirectory();
virtual std::string getLogDirectory();
virtual std::string getPluginDirectory();
virtual std::string getProfileDirectory();
virtual std::string concatPath(const std::string& prefix,
const std::string& suffix);
virtual void setProfileDirectory(const String& s);
virtual void setPluginDirectory(const String& s);
private:
String m_profileDirectory;
String m_pluginDirectory;
};

View File

@@ -113,6 +113,11 @@ ArchNetworkBSD::newSocket(EAddressFamily family, ESocketType type)
}
try {
setBlockingOnSocket(fd, false);
if (family == kINET6) {
int flag = 0;
if (setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &flag, sizeof(flag)) != 0)
throwError(errno);
}
}
catch (...) {
close(fd);
@@ -647,8 +652,8 @@ ArchNetworkBSD::newAnyAddr(EAddressFamily family)
switch (family) {
case kINET: {
auto* ipAddr = TYPED_ADDR(struct sockaddr_in, addr);
memset(ipAddr, 0, sizeof(struct sockaddr_in));
ipAddr->sin_family = AF_INET;
ipAddr->sin_port = 0;
ipAddr->sin_addr.s_addr = INADDR_ANY;
addr->m_len = (socklen_t)sizeof(struct sockaddr_in);
break;
@@ -656,8 +661,8 @@ ArchNetworkBSD::newAnyAddr(EAddressFamily family)
case kINET6: {
auto* ipAddr = TYPED_ADDR(struct sockaddr_in6, addr);
memset(ipAddr, 0, sizeof(struct sockaddr_in6));
ipAddr->sin6_family = AF_INET6;
ipAddr->sin6_port = 0;
memcpy(&ipAddr->sin6_addr, &in6addr_any, sizeof(in6addr_any));
addr->m_len = (socklen_t)sizeof(struct sockaddr_in6);
break;

View File

@@ -1,203 +0,0 @@
/*
* barrier -- mouse and keyboard sharing utility
* Copyright (C) 2012-2016 Symless Ltd.
* Copyright (C) 2002 Chris Schoeneman
*
* This package is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* found in the file LICENSE that should have accompanied this file.
*
* This package is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "arch/win32/ArchFileWindows.h"
#define WIN32_LEAN_AND_MEAN
#include <Windows.h>
#include <shlobj.h>
#include <tchar.h>
#include <string.h>
//
// ArchFileWindows
//
ArchFileWindows::ArchFileWindows()
{
// do nothing
}
ArchFileWindows::~ArchFileWindows()
{
// do nothing
}
const char*
ArchFileWindows::getBasename(const char* pathname)
{
if (pathname == NULL) {
return NULL;
}
// check for last slash
const char* basename = strrchr(pathname, '/');
if (basename != NULL) {
++basename;
}
else {
basename = pathname;
}
// check for last backslash
const char* basename2 = strrchr(pathname, '\\');
if (basename2 != NULL && basename2 > basename) {
basename = basename2 + 1;
}
return basename;
}
std::string
ArchFileWindows::getUserDirectory()
{
// try %HOMEPATH%
TCHAR dir[MAX_PATH];
DWORD size = sizeof(dir) / sizeof(TCHAR);
DWORD result = GetEnvironmentVariable(_T("HOMEPATH"), dir, size);
if (result != 0 && result <= size) {
// sanity check -- if dir doesn't appear to start with a
// drive letter and isn't a UNC name then don't use it
// FIXME -- allow UNC names
if (dir[0] != '\0' && (dir[1] == ':' ||
((dir[0] == '\\' || dir[0] == '/') &&
(dir[1] == '\\' || dir[1] == '/')))) {
return dir;
}
}
// get the location of the personal files. that's as close to
// a home directory as we're likely to find.
ITEMIDLIST* idl;
if (SUCCEEDED(SHGetSpecialFolderLocation(NULL, CSIDL_PERSONAL, &idl))) {
TCHAR* path = NULL;
if (SHGetPathFromIDList(idl, dir)) {
DWORD attr = GetFileAttributes(dir);
if (attr != 0xffffffff && (attr & FILE_ATTRIBUTE_DIRECTORY) != 0)
path = dir;
}
IMalloc* shalloc;
if (SUCCEEDED(SHGetMalloc(&shalloc))) {
shalloc->Free(idl);
shalloc->Release();
}
if (path != NULL) {
return path;
}
}
// use root of C drive as a default
return "C:";
}
std::string
ArchFileWindows::getSystemDirectory()
{
// get windows directory
char dir[MAX_PATH];
if (GetWindowsDirectory(dir, sizeof(dir)) != 0) {
return dir;
}
else {
// can't get it. use C:\ as a default.
return "C:";
}
}
std::string
ArchFileWindows::getInstalledDirectory()
{
char fileNameBuffer[MAX_PATH];
GetModuleFileName(NULL, fileNameBuffer, MAX_PATH);
std::string fileName(fileNameBuffer);
size_t lastSlash = fileName.find_last_of("\\");
fileName = fileName.substr(0, lastSlash);
return fileName;
}
std::string
ArchFileWindows::getLogDirectory()
{
return getInstalledDirectory();
}
std::string
ArchFileWindows::getPluginDirectory()
{
if (!m_pluginDirectory.empty()) {
return m_pluginDirectory;
}
std::string dir = getProfileDirectory();
dir.append("\\Plugins");
return dir;
}
std::string
ArchFileWindows::getProfileDirectory()
{
String dir;
if (!m_profileDirectory.empty()) {
dir = m_profileDirectory;
}
else {
TCHAR result[MAX_PATH];
if (SUCCEEDED(SHGetFolderPath(NULL, CSIDL_LOCAL_APPDATA, NULL, 0, result))) {
dir = result;
}
else {
dir = getUserDirectory();
}
}
// HACK: append program name, this seems wrong.
dir.append("\\Barrier");
return dir;
}
std::string
ArchFileWindows::concatPath(const std::string& prefix,
const std::string& suffix)
{
std::string path;
path.reserve(prefix.size() + 1 + suffix.size());
path += prefix;
if (path.size() == 0 ||
(path[path.size() - 1] != '\\' &&
path[path.size() - 1] != '/')) {
path += '\\';
}
path += suffix;
return path;
}
void
ArchFileWindows::setProfileDirectory(const String& s)
{
m_profileDirectory = s;
}
void
ArchFileWindows::setPluginDirectory(const String& s)
{
m_pluginDirectory = s;
}

View File

@@ -1,47 +0,0 @@
/*
* barrier -- mouse and keyboard sharing utility
* Copyright (C) 2012-2016 Symless Ltd.
* Copyright (C) 2002 Chris Schoeneman
*
* This package is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* found in the file LICENSE that should have accompanied this file.
*
* This package is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include "arch/IArchFile.h"
#define ARCH_FILE ArchFileWindows
//! Win32 implementation of IArchFile
class ArchFileWindows : public IArchFile {
public:
ArchFileWindows();
virtual ~ArchFileWindows();
// IArchFile overrides
virtual const char* getBasename(const char* pathname);
virtual std::string getUserDirectory();
virtual std::string getSystemDirectory();
virtual std::string getInstalledDirectory();
virtual std::string getLogDirectory();
virtual std::string getPluginDirectory();
virtual std::string getProfileDirectory();
virtual std::string concatPath(const std::string& prefix,
const std::string& suffix);
virtual void setProfileDirectory(const String& s);
virtual void setPluginDirectory(const String& s);
private:
String m_profileDirectory;
String m_pluginDirectory;
};

View File

@@ -213,10 +213,10 @@ ArchNetworkWinsock::newSocket(EAddressFamily family, ESocketType type)
}
try {
setBlockingOnSocket(fd, false);
BOOL flag = 0;
int size = sizeof(flag);
if (setsockopt_winsock(fd, IPPROTO_IPV6, IPV6_V6ONLY, &flag, size) == SOCKET_ERROR) {
throwError(getsockerror_winsock());
if (family == kINET6) {
int flag = 0;
if (setsockopt_winsock(fd, IPPROTO_IPV6, IPV6_V6ONLY, &flag, sizeof(flag)) == SOCKET_ERROR)
throwError(getsockerror_winsock());
}
}
catch (...) {
@@ -685,8 +685,8 @@ ArchNetworkWinsock::newAnyAddr(EAddressFamily family)
case kINET: {
addr = ArchNetAddressImpl::alloc(sizeof(struct sockaddr_in));
auto* ipAddr = TYPED_ADDR(struct sockaddr_in, addr);
memset(ipAddr, 0, sizeof(struct sockaddr_in));
ipAddr->sin_family = AF_INET;
ipAddr->sin_port = 0;
ipAddr->sin_addr.s_addr = INADDR_ANY;
break;
}
@@ -694,8 +694,8 @@ ArchNetworkWinsock::newAnyAddr(EAddressFamily family)
case kINET6: {
addr = ArchNetAddressImpl::alloc(sizeof(struct sockaddr_in6));
auto* ipAddr = TYPED_ADDR(struct sockaddr_in6, addr);
memset(ipAddr, 0, sizeof(struct sockaddr_in6));
ipAddr->sin6_family = AF_INET6;
ipAddr->sin6_port = 0;
memcpy(&ipAddr->sin6_addr, &in6addr_any, sizeof(in6addr_any));
break;
}

View File

@@ -21,9 +21,7 @@
#include "base/Log.h"
#include "common/Version.h"
#include "barrier/protocol_types.h"
#include "arch/Arch.h"
#include "base/XBase.h"
#include "arch/XArch.h"
#include "base/log_outputters.h"
#include "barrier/XBarrier.h"
#include "barrier/ArgsBase.h"
@@ -32,9 +30,9 @@
#include "ipc/IpcMessage.h"
#include "ipc/Ipc.h"
#include "base/EventQueue.h"
#include "common/DataDirectories.h"
#if SYSAPI_WIN32
#include "arch/win32/ArchMiscWindows.h"
#include "base/IEventQueue.h"
#include "base/TMethodJob.h"
#endif
@@ -81,18 +79,9 @@ App::~App()
void
App::version()
{
char buffer[500];
sprintf(
buffer,
"%s %s, protocol version %d.%d\n%s",
argsBase().m_pname,
kVersion,
kProtocolMajorVersion,
kProtocolMinorVersion,
kCopyright
);
std::cout << buffer << std::endl;
std::cout << argsBase().m_exename << " " << kVersion << std::endl;
std::cout <<"Protocol version " << kProtocolMajorVersion << "." << kProtocolMinorVersion << std::endl;
std::cout << kCopyright << std::endl;
}
int
@@ -175,13 +164,12 @@ App::initApp(int argc, const char** argv)
// parse command line
parseArgs(argc, argv);
ARCH->setProfileDirectory(argsBase().m_profileDirectory);
ARCH->setPluginDirectory(argsBase().m_pluginDirectory);
DataDirectories::profile(argsBase().m_profileDirectory);
// set log filter
if (!CLOG->setFilter(argsBase().m_logFilter)) {
LOG((CLOG_PRINT "%s: unrecognized log level `%s'" BYE,
argsBase().m_pname, argsBase().m_logFilter, argsBase().m_pname));
argsBase().m_exename.c_str(), argsBase().m_logFilter, argsBase().m_exename.c_str()));
m_bye(kExitArgs);
}
loggingFilterWarning();

View File

@@ -21,10 +21,10 @@
#include "barrier/App.h"
#include "barrier/ServerArgs.h"
#include "barrier/ClientArgs.h"
#include "barrier/ToolArgs.h"
#include "barrier/ArgsBase.h"
#include "base/Log.h"
#include "base/String.h"
#include "common/PathUtilities.h"
#ifdef WINAPI_MSWINDOWS
#include <VersionHelpers.h>
@@ -62,7 +62,7 @@ ArgParser::parseServerArgs(ServerArgs& args, int argc, const char* const* argv)
args.m_configFile = argv[++i];
}
else {
LOG((CLOG_PRINT "%s: unrecognized option `%s'" BYE, args.m_pname, argv[i], args.m_pname));
LOG((CLOG_PRINT "%s: unrecognized option `%s'" BYE, args.m_exename.c_str(), argv[i], args.m_exename.c_str()));
return false;
}
}
@@ -107,7 +107,7 @@ ArgParser::parseClientArgs(ClientArgs& args, int argc, const char* const* argv)
return true;
}
LOG((CLOG_PRINT "%s: unrecognized option `%s'" BYE, args.m_pname, argv[i], args.m_pname));
LOG((CLOG_PRINT "%s: unrecognized option `%s'" BYE, args.m_exename.c_str(), argv[i], args.m_exename.c_str()));
return false;
}
}
@@ -118,7 +118,7 @@ ArgParser::parseClientArgs(ClientArgs& args, int argc, const char* const* argv)
// exactly one non-option argument (server-address)
if (i == argc) {
LOG((CLOG_PRINT "%s: a server address or name is required" BYE,
args.m_pname, args.m_pname));
args.m_exename.c_str(), args.m_exename.c_str()));
return false;
}
@@ -171,46 +171,6 @@ ArgParser::parsePlatformArg(ArgsBase& argsBase, const int& argc, const char* con
#endif
}
bool
ArgParser::parseToolArgs(ToolArgs& args, int argc, const char* const* argv)
{
for (int i = 1; i < argc; ++i) {
if (isArg(i, argc, argv, NULL, "--get-active-desktop", 0)) {
args.m_printActiveDesktopName = true;
return true;
}
else if (isArg(i, argc, argv, NULL, "--login-auth", 0)) {
args.m_loginAuthenticate = true;
return true;
}
else if (isArg(i, argc, argv, NULL, "--get-installed-dir", 0)) {
args.m_getInstalledDir = true;
return true;
}
else if (isArg(i, argc, argv, NULL, "--get-profile-dir", 0)) {
args.m_getProfileDir = true;
return true;
}
else if (isArg(i, argc, argv, NULL, "--get-arch", 0)) {
args.m_getArch = true;
return true;
}
else if (isArg(i, argc, argv, NULL, "--notify-activation", 0)) {
args.m_notifyActivation = true;
return true;
}
else if (isArg(i, argc, argv, NULL, "--notify-update", 0)) {
args.m_notifyUpdate = true;
return true;
}
else {
return false;
}
}
return false;
}
bool
ArgParser::parseGenericArgs(int argc, const char* const* argv, int& i)
{
@@ -353,7 +313,7 @@ ArgParser::isArg(
// match. check args left.
if (argi + minRequiredParameters >= argc) {
LOG((CLOG_PRINT "%s: missing arguments for `%s'" BYE,
argsBase().m_pname, argv[argi], argsBase().m_pname));
argsBase().m_exename.c_str(), argv[argi], argsBase().m_exename.c_str()));
argsBase().m_shouldExit = true;
return false;
}
@@ -496,7 +456,7 @@ void
ArgParser::updateCommonArgs(const char* const* argv)
{
argsBase().m_name = ARCH->getHostName();
argsBase().m_pname = ARCH->getBasename(argv[0]);
argsBase().m_exename = PathUtilities::basename(argv[0]);
}
bool
@@ -510,7 +470,7 @@ ArgParser::checkUnexpectedArgs()
LOG((CLOG_ERR
"the --daemon argument is not supported on windows. "
"instead, install %s as a service (--service install)",
argsBase().m_pname));
argsBase().m_exename.c_str()));
return true;
}
#endif

View File

@@ -22,7 +22,6 @@
class ServerArgs;
class ClientArgs;
class ToolArgs;
class ArgsBase;
class App;
@@ -34,7 +33,6 @@ public:
bool parseServerArgs(ServerArgs& args, int argc, const char* const* argv);
bool parseClientArgs(ClientArgs& args, int argc, const char* const* argv);
bool parsePlatformArg(ArgsBase& argsBase, const int& argc, const char* const* argv, int& i);
bool parseToolArgs(ToolArgs& args, int argc, const char* const* argv);
bool parseGenericArgs(int argc, const char* const* argv, int& i);
bool parseDeprecatedArgs(int argc, const char* const* argv, int& i);
void setArgsBase(ArgsBase& argsBase) { m_argsBase = &argsBase; }

View File

@@ -33,7 +33,6 @@ m_disableXInitThreads(false),
m_backend(false),
m_restartable(true),
m_noHooks(false),
m_pname(NULL),
m_logFilter(NULL),
m_logFile(NULL),
m_display(NULL),

View File

@@ -30,7 +30,7 @@ public:
bool m_backend;
bool m_restartable;
bool m_noHooks;
const char* m_pname;
std::string m_exename;
const char* m_logFilter;
const char* m_logFile;
const char* m_display;

View File

@@ -40,10 +40,7 @@
#include "base/TMethodJob.h"
#include "base/Log.h"
#include "common/Version.h"
#if SYSAPI_WIN32
#include "arch/win32/ArchMiscWindows.h"
#endif
#include "common/PathUtilities.h"
#if WINAPI_MSWINDOWS
#include "platform/MSWindowsScreen.h"
@@ -98,7 +95,7 @@ ClientApp::parseArgs(int argc, const char* const* argv)
// Priddy.
if (!args().m_restartable || e.getError() == XSocketAddress::kBadPort) {
LOG((CLOG_PRINT "%s: %s" BYE,
args().m_pname, e.what(), args().m_pname));
args().m_exename.c_str(), e.what(), args().m_exename.c_str()));
m_bye(kExitFailed);
}
}
@@ -123,7 +120,7 @@ ClientApp::help()
std::ostringstream buffer;
buffer << "Start the barrier client and connect to a remote server component." << std::endl
<< std::endl
<< "Usage: " << args().m_pname << " [--yscroll <delta>]" << WINAPI_ARG << HELP_SYS_ARGS
<< "Usage: " << args().m_exename << " [--yscroll <delta>]" << WINAPI_ARG << HELP_SYS_ARGS
<< HELP_COMMON_ARGS << " <server-address>" << std::endl
<< std::endl
<< "Options:" << std::endl
@@ -134,9 +131,10 @@ ClientApp::help()
<< std::endl
<< "Default options are marked with a *" << std::endl
<< std::endl
<< "The server address is of the form: [<hostname>][:<port>]. The hostname" << std::endl
<< "must be the address or hostname of the server. The port overrides the" << std::endl
<< "default port, " << kDefaultPort << "." << std::endl;
<< "The server address is of the form: [<hostname>][:<port>]. The hostname" << std::endl
<< "must be the address or hostname of the server. Placing brackets around" << std::endl
<< "an IPv6 address is required when also specifying a port number and " << std::endl
<< "optional otherwise. The default port number is " << kDefaultPort << "." << std::endl;
LOG((CLOG_PRINT "%s", buffer.str().c_str()));
}
@@ -519,7 +517,7 @@ ClientApp::runInner(int argc, char** argv, ILogOutputter* outputter, StartupFunc
{
// general initialization
m_serverAddress = new NetworkAddress;
args().m_pname = ARCH->getBasename(argv[0]);
args().m_exename = PathUtilities::basename(argv[0]);
// install caller's output filter
if (outputter != NULL) {

View File

@@ -39,6 +39,8 @@
#include "base/Log.h"
#include "base/TMethodEventJob.h"
#include "common/Version.h"
#include "common/DataDirectories.h"
#include "common/PathUtilities.h"
#if SYSAPI_WIN32
#include "arch/win32/ArchMiscWindows.h"
@@ -99,7 +101,7 @@ ServerApp::parseArgs(int argc, const char* const* argv)
}
catch (XSocketAddress& e) {
LOG((CLOG_PRINT "%s: %s" BYE,
args().m_pname, e.what(), args().m_pname));
args().m_exename.c_str(), e.what(), args().m_exename.c_str()));
m_bye(kExitArgs);
}
}
@@ -124,7 +126,7 @@ ServerApp::help()
std::ostringstream buffer;
buffer << "Start the barrier server component." << std::endl
<< std::endl
<< "Usage: " << args().m_pname
<< "Usage: " << args().m_exename
<< " [--address <address>]"
<< " [--config <pathname>]"
<< WINAPI_ARGS << HELP_SYS_ARGS << HELP_COMMON_ARGS << std::endl
@@ -137,13 +139,14 @@ ServerApp::help()
<< std::endl
<< "The argument for --address is of the form: [<hostname>][:<port>]. The" << std::endl
<< "hostname must be the address or hostname of an interface on the system." << std::endl
<< "The default is to listen on all interfaces. The port overrides the" << std::endl
<< "default port, " << kDefaultPort << "." << std::endl
<< "Placing brackets around an IPv6 address is required when also specifying " << std::endl
<< "a port number and optional otherwise. The default is to listen on all" << std::endl
<< "interfaces using port number " << kDefaultPort << "." << std::endl
<< std::endl
<< "If no configuration file pathname is provided then the first of the" << std::endl
<< "following to load successfully sets the configuration:" << std::endl
<< " $HOME/" << USR_CONFIG_NAME << std::endl
<< " " << ARCH->concatPath(ARCH->getSystemDirectory(), SYS_CONFIG_NAME) << std::endl;
<< " " << PathUtilities::concat(DataDirectories::profile(), SYS_CONFIG_NAME) << std::endl
<< " " << PathUtilities::concat(DataDirectories::systemconfig(), SYS_CONFIG_NAME) << std::endl;
LOG((CLOG_PRINT "%s", buffer.str().c_str()));
}
@@ -180,11 +183,10 @@ ServerApp::loadConfig()
// load the default configuration if no explicit file given
else {
// get the user's home directory
String path = ARCH->getUserDirectory();
String path = DataDirectories::profile();
if (!path.empty()) {
// complete path
path = ARCH->concatPath(path, USR_CONFIG_NAME);
path = PathUtilities::concat(path, USR_CONFIG_NAME);
// now try loading the user's configuration
if (loadConfig(path)) {
@@ -194,9 +196,9 @@ ServerApp::loadConfig()
}
if (!loaded) {
// try the system-wide config file
path = ARCH->getSystemDirectory();
path = DataDirectories::systemconfig();
if (!path.empty()) {
path = ARCH->concatPath(path, SYS_CONFIG_NAME);
path = PathUtilities::concat(path, SYS_CONFIG_NAME);
if (loadConfig(path)) {
loaded = true;
args().m_configFile = path;
@@ -206,7 +208,7 @@ ServerApp::loadConfig()
}
if (!loaded) {
LOG((CLOG_PRINT "%s: no configuration available", args().m_pname));
LOG((CLOG_PRINT "%s: no configuration available", args().m_exename.c_str()));
m_bye(kExitConfig);
}
}
@@ -505,6 +507,16 @@ ServerApp::openServerScreen()
return screen;
}
static const char* const family_string(IArchNetwork::EAddressFamily family)
{
if (family == IArchNetwork::kINET)
return "IPv4";
if (family == IArchNetwork::kINET6)
// assume IPv6 sockets are setup to support IPv4 traffic as well
return "IPv4/IPv6";
return "Unknown";
}
bool
ServerApp::startServer()
{
@@ -530,13 +542,15 @@ ServerApp::startServer()
double retryTime;
ClientListener* listener = NULL;
try {
listener = openClientListener(args().m_config->getBarrierAddress());
auto listenAddress = args().m_config->getBarrierAddress();
auto family = family_string(ARCH->getAddrFamily(listenAddress.getAddress()));
listener = openClientListener(listenAddress);
m_server = openServer(*args().m_config, m_primaryClient);
listener->setServer(m_server);
m_server->setListener(listener);
m_listener = listener;
updateStatus();
LOG((CLOG_NOTE "started server, waiting for clients"));
LOG((CLOG_NOTE "started server (%s), waiting for clients", family));
m_serverState = kStarted;
return true;
}
@@ -779,7 +793,7 @@ ServerApp::runInner(int argc, char** argv, ILogOutputter* outputter, StartupFunc
// general initialization
m_barrierAddress = new NetworkAddress;
args().m_config = new Config(m_events);
args().m_pname = ARCH->getBasename(argv[0]);
args().m_exename = PathUtilities::basename(argv[0]);
// install caller's output filter
if (outputter != NULL) {

View File

@@ -1,205 +0,0 @@
/*
* barrier -- mouse and keyboard sharing utility
* Copyright (C) 2014-2016 Symless Ltd.
*
* This package is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* found in the file LICENSE that should have accompanied this file.
*
* This package is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "barrier/ToolApp.h"
#include "barrier/ArgParser.h"
#include "arch/Arch.h"
#include "base/Log.h"
#include "base/String.h"
#include <iostream>
#include <sstream>
#if SYSAPI_WIN32
#include "platform/MSWindowsSession.h"
#endif
#define JSON_URL "https://symless.com/account/json/"
enum {
kErrorOk,
kErrorArgs,
kErrorException,
kErrorUnknown
};
UInt32
ToolApp::run(int argc, char** argv)
{
if (argc <= 1) {
std::cerr << "no args" << std::endl;
return kErrorArgs;
}
try {
ArgParser argParser(this);
bool result = argParser.parseToolArgs(m_args, argc, argv);
if (!result) {
m_bye(kExitArgs);
}
if (m_args.m_printActiveDesktopName) {
#if SYSAPI_WIN32
MSWindowsSession session;
String name = session.getActiveDesktopName();
if (name.empty()) {
LOG((CLOG_CRIT "failed to get active desktop name"));
return kExitFailed;
}
else {
String output = barrier::string::sprintf("activeDesktop:%s", name.c_str());
LOG((CLOG_INFO "%s", output.c_str()));
}
#endif
}
else if (m_args.m_loginAuthenticate) {
loginAuth();
}
else if (m_args.m_getInstalledDir) {
std::cout << ARCH->getInstalledDirectory() << std::endl;
}
else if (m_args.m_getProfileDir) {
std::cout << ARCH->getProfileDirectory() << std::endl;
}
else if (m_args.m_getArch) {
std::cout << ARCH->getPlatformName() << std::endl;
}
else if (m_args.m_notifyUpdate) {
notifyUpdate();
}
else if (m_args.m_notifyActivation) {
notifyActivation();
}
else {
throw XBarrier("Nothing to do");
}
}
catch (std::exception& e) {
LOG((CLOG_CRIT "An error occurred: %s\n", e.what()));
return kExitFailed;
}
catch (...) {
LOG((CLOG_CRIT "An unknown error occurred.\n"));
return kExitFailed;
}
#if WINAPI_XWINDOWS
// HACK: avoid sigsegv on linux
m_bye(kErrorOk);
#endif
return kErrorOk;
}
void
ToolApp::help()
{
}
void
ToolApp::loginAuth()
{
String credentials;
std::cin >> credentials;
std::vector<String> parts = barrier::string::splitString(credentials, ':');
size_t count = parts.size();
if (count == 2 ) {
String email = parts[0];
String password = parts[1];
std::stringstream ss;
ss << JSON_URL << "auth/";
ss << "?email=" << ARCH->internet().urlEncode(email);
ss << "&password=" << password;
std::cout << ARCH->internet().get(ss.str()) << std::endl;
}
else {
throw XBarrier("Invalid credentials.");
}
}
void
ToolApp::notifyUpdate()
{
String data;
std::cin >> data;
std::vector<String> parts = barrier::string::splitString(data, ':');
size_t count = parts.size();
if (count == 3) {
std::stringstream ss;
ss << JSON_URL << "notify/update";
ss << "?from=" << parts[0];
ss << "&to=" << parts[1];
std::cout << ARCH->internet().get(ss.str()) << std::endl;
}
else {
throw XBarrier("Invalid update data.");
}
}
void
ToolApp::notifyActivation()
{
String info;
std::cin >> info;
std::vector<String> parts = barrier::string::splitString(info, ':');
size_t count = parts.size();
if (count == 3 || count == 4) {
String action = parts[0];
String identity = parts[1];
String macHash = parts[2];
String os;
if (count == 4) {
os = parts[3];
}
else {
os = ARCH->getOSName();
}
std::stringstream ss;
ss << JSON_URL << "notify/";
ss << "?action=" << action;
ss << "&identity=" << ARCH->internet().urlEncode(identity);
ss << "&mac=" << ARCH->internet().urlEncode(macHash);
ss << "&os=" << ARCH->internet().urlEncode(ARCH->getOSName());
ss << "&arch=" << ARCH->internet().urlEncode(ARCH->getPlatformName());
try {
std::cout << ARCH->internet().get(ss.str()) << std::endl;
}
catch (std::exception& e) {
LOG((CLOG_NOTE "An error occurred during notification: %s\n", e.what()));
}
catch (...) {
LOG((CLOG_NOTE "An unknown error occurred during notification.\n"));
}
}
else {
LOG((CLOG_NOTE "notification failed"));
}
}

View File

@@ -1,37 +0,0 @@
/*
* barrier -- mouse and keyboard sharing utility
* Copyright (C) 2014-2016 Symless Ltd.
*
* This package is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* found in the file LICENSE that should have accompanied this file.
*
* This package is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include "barrier/App.h"
#include "barrier/ToolArgs.h"
#include "common/basic_types.h"
class ToolApp : public MinimalApp
{
public:
UInt32 run(int argc, char** argv);
void help();
private:
void loginAuth();
void notifyActivation();
void notifyUpdate();
private:
ToolArgs m_args;
};

View File

@@ -1,29 +0,0 @@
/*
* barrier -- mouse and keyboard sharing utility
* Copyright (C) 2014-2016 Symless Ltd.
*
* This package is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* found in the file LICENSE that should have accompanied this file.
*
* This package is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "barrier/ToolArgs.h"
ToolArgs::ToolArgs() :
m_printActiveDesktopName(false),
m_loginAuthenticate(false),
m_getInstalledDir(false),
m_getProfileDir(false),
m_getArch(false),
m_notifyActivation(false),
m_notifyUpdate(false)
{
}

View File

@@ -1,34 +0,0 @@
/*
* barrier -- mouse and keyboard sharing utility
* Copyright (C) 2014-2016 Symless Ltd.
*
* This package is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* found in the file LICENSE that should have accompanied this file.
*
* This package is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include "base/String.h"
class ToolArgs {
public:
ToolArgs();
public:
bool m_printActiveDesktopName;
bool m_loginAuthenticate;
bool m_getInstalledDir;
bool m_getProfileDir;
bool m_getArch;
bool m_notifyActivation;
bool m_notifyUpdate;
};

View File

@@ -33,6 +33,7 @@
#include "base/EventQueue.h"
#include "base/log_outputters.h"
#include "base/Log.h"
#include "common/DataDirectories.h"
#include "arch/win32/ArchMiscWindows.h"
#include "arch/win32/XArchWindows.h"
@@ -41,6 +42,7 @@
#include "platform/MSWindowsDebugOutputter.h"
#include "platform/MSWindowsWatchdog.h"
#include "platform/MSWindowsEventQueueBuffer.h"
#include "platform/MSWindowsUtil.h"
#define WIN32_LEAN_AND_MEAN
#include <Windows.h>
@@ -130,8 +132,10 @@ DaemonApp::run(int argc, char** argv)
}
if (foreground) {
// run process in foreground instead of daemonizing.
// useful for debugging.
// add a console to catch Ctrl+C and run process in foreground
// instead of daemonizing. useful for debugging.
if (IsDebuggerPresent())
AllocConsole();
mainLoop(false);
}
else {
@@ -239,14 +243,10 @@ DaemonApp::foregroundError(const char* message)
std::string
DaemonApp::logFilename()
{
string logFilename;
logFilename = ARCH->setting("LogFilename");
if (logFilename.empty()) {
logFilename = ARCH->getLogDirectory();
logFilename.append("/");
logFilename.append(LOG_FILENAME);
}
string logFilename = ARCH->setting("LogFilename");
if (logFilename.empty())
logFilename = DataDirectories::global() + "\\" + LOG_FILENAME;
MSWindowsUtil::createDirectory(logFilename, true);
return logFilename;
}

View File

@@ -81,6 +81,7 @@ ServerProxy::~ServerProxy()
setKeepAliveRate(-1.0);
m_events->removeHandler(m_events->forIStream().inputReady(),
m_stream->getEventTarget());
m_events->removeHandler(m_events->forClipboard().clipboardSending(), this);
}
void

View File

@@ -17,8 +17,24 @@
file(GLOB headers "*.h")
file(GLOB sources "*.cpp")
if (WIN32)
file(GLOB arch_headers "win32/*.h")
file(GLOB arch_sources "win32/*.cpp")
elseif (UNIX)
file(GLOB arch_headers "unix/*.h")
file(GLOB arch_sources "unix/*.cpp")
endif()
list(APPEND headers ${arch_headers})
list(APPEND sources ${arch_sources})
if (BARRIER_ADD_HEADERS)
list(APPEND sources ${headers})
endif()
add_library(common STATIC ${sources})
if (HAVE_GETPWUID_R)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DHAVE_GETPWUID_R=1")
endif()

View File

@@ -0,0 +1,41 @@
/*
* barrier -- mouse and keyboard sharing utility
* Copyright (C) 2018 Debauchee Open Source Group
*
* This package is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* found in the file LICENSE that should have accompanied this file.
*
* This package is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <string>
class DataDirectories
{
public:
static const std::string& profile();
static const std::string& profile(const std::string& path);
static const std::string& global();
static const std::string& global(const std::string& path);
static const std::string& systemconfig();
static const std::string& systemconfig(const std::string& path);
private:
// static class
DataDirectories() {}
static std::string _profile;
static std::string _global;
static std::string _systemconfig;
};

View File

@@ -0,0 +1,23 @@
/*
* barrier -- mouse and keyboard sharing utility
* Copyright (C) 2018 Debauchee Open Source Group
*
* This package is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* found in the file LICENSE that should have accompanied this file.
*
* This package is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "DataDirectories.h"
// static member
std::string DataDirectories::_profile;
std::string DataDirectories::_global;
std::string DataDirectories::_systemconfig;

View File

@@ -0,0 +1,75 @@
/*
* barrier -- mouse and keyboard sharing utility
* Copyright (C) 2018 Debauchee Open Source Group
*
* This package is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* found in the file LICENSE that should have accompanied this file.
*
* This package is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/*
These functions cover the vast majority of cases for different paths across
windows and unixes. They are not, however, fullproof and probably don't cover
fringe cases very well. The library below might be used as an alternative if
these implementations prove to be insufficient. As the library's readme states
it is simply a temporary band-aid until std::filesystem is integrated (C++17
has it in std::experimental) and this class should also be treated as such.
https://github.com/wjakob/filesystem/
*/
#include "PathUtilities.h"
// keep the default platform delimiter as the first in the list
#ifdef _WIN32
static const char *Delimiters = "\\/";
#else
static const char *Delimiters = "/";
#endif
static const char DefaultDelimiter = Delimiters[0];
std::string PathUtilities::basename(const std::string& path)
{
return path.substr(path.find_last_of(Delimiters) + 1);
}
std::string PathUtilities::concat(const std::string& left, const std::string& right)
{
// although npos is usually (-1) we can't count on that so handle it explicitly
auto leftEnd = left.find_last_not_of(Delimiters);
if (leftEnd == std::string::npos)
leftEnd = 0;
else
++leftEnd;
auto rightStart = right.find_first_not_of(Delimiters, 0);
if (rightStart == std::string::npos) {
// both left/right are empty
if (left.size() == 0 && right.size() == 0)
return "";
// right is full of delims, left is okay
if (leftEnd > 0)
return left.substr(0, leftEnd);
// both left/right useless but at least one has delims
return std::string(1, DefaultDelimiter);
}
if (leftEnd == 0) {
// right is okay and not prefixed with delims, left is empty
if (left.size() == 0 && rightStart == 0)
return right.substr(rightStart);
// (right is okay and prefixed with delims) OR left is full of delims
return DefaultDelimiter + right.substr(rightStart);
}
// concatenation using both left and right
return left.substr(0, leftEnd) + DefaultDelimiter + right.substr(rightStart);
}

View File

@@ -0,0 +1,31 @@
/*
* barrier -- mouse and keyboard sharing utility
* Copyright (C) 2018 Debauchee Open Source Group
*
* This package is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* found in the file LICENSE that should have accompanied this file.
*
* This package is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <string>
class PathUtilities
{
public:
static std::string basename(const std::string& path);
static std::string concat(const std::string& left, const std::string& right);
private:
// static class
PathUtilities() {}
};

View File

@@ -0,0 +1,114 @@
/*
* barrier -- mouse and keyboard sharing utility
* Copyright (C) 2018 Debauchee Open Source Group
*
* This package is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* found in the file LICENSE that should have accompanied this file.
*
* This package is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "../DataDirectories.h"
#include <unistd.h> // sysconf
#include <stdlib.h> // getenv
#include <sys/types.h> // getpwuid(_r)
#include <pwd.h> // getpwuid(_r)
const std::string ProfileSubdir = "/barrier";
static std::string pw_dir(struct passwd* pwentp)
{
if (pwentp != NULL && pwentp->pw_dir != NULL)
return pwentp->pw_dir;
return "";
}
#ifdef HAVE_GETPWUID_R
static std::string unix_home()
{
long size = -1;
#if defined(_SC_GETPW_R_SIZE_MAX)
size = sysconf(_SC_GETPW_R_SIZE_MAX);
#endif
if (size == -1)
size = BUFSIZ;
struct passwd pwent;
struct passwd* pwentp;
std::string buffer(size, 0);
getpwuid_r(getuid(), &pwent, &buffer[0], size, &pwentp);
return pw_dir(pwentp);
}
#else // not HAVE_GETPWUID_R
static std::string unix_home()
{
return pw_dir(getpwuid(getuid()));
}
#endif // HAVE_GETPWUID_R
static std::string profile_basedir()
{
#ifdef WINAPI_XWINDOWS
// linux/bsd adheres to freedesktop standards
// https://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html
const char* dir = getenv("XDG_DATA_HOME");
if (dir != NULL)
return dir;
return unix_home() + "/.local/share";
#else
// macos has its own standards
// https://developer.apple.com/library/content/documentation/General/Conceptual/MOSXAppProgrammingGuide/AppRuntime/AppRuntime.html
return unix_home() + "/Library/Application Support";
#endif
}
const std::string& DataDirectories::profile()
{
if (_profile.empty())
_profile = profile_basedir() + ProfileSubdir;
return _profile;
}
const std::string& DataDirectories::profile(const std::string& path)
{
_profile = path;
return _profile;
}
const std::string& DataDirectories::global()
{
if (_global.empty())
// TODO: where on a unix system should public/global shared data go?
// as of march 2018 global() is not used for unix
_global = "/tmp";
return _global;
}
const std::string& DataDirectories::global(const std::string& path)
{
_global = path;
return _global;
}
const std::string& DataDirectories::systemconfig()
{
if (_systemconfig.empty())
_systemconfig = "/etc";
return _systemconfig;
}
const std::string& DataDirectories::systemconfig(const std::string& path)
{
_systemconfig = path;
return _systemconfig;
}

View File

@@ -0,0 +1,81 @@
/*
* barrier -- mouse and keyboard sharing utility
* Copyright (C) 2018 Debauchee Open Source Group
*
* This package is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* found in the file LICENSE that should have accompanied this file.
*
* This package is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "../DataDirectories.h"
#include <Shlobj.h>
std::string unicode_to_mb(const WCHAR* utfStr)
{
int utfLength = lstrlenW(utfStr);
int mbLength = WideCharToMultiByte(CP_UTF8, 0, utfStr, utfLength, NULL, 0, NULL, NULL);
std::string mbStr(mbLength, 0);
WideCharToMultiByte(CP_UTF8, 0, utfStr, utfLength, &mbStr[0], mbLength, NULL, NULL);
return mbStr;
}
std::string known_folder_path(const KNOWNFOLDERID& id)
{
std::string path;
WCHAR* buffer;
HRESULT result = SHGetKnownFolderPath(id, 0, NULL, &buffer);
if (result == S_OK) {
path = unicode_to_mb(buffer);
CoTaskMemFree(buffer);
}
return path;
}
const std::string& DataDirectories::profile()
{
if (_profile.empty())
_profile = known_folder_path(FOLDERID_LocalAppData) + "\\Barrier";
return _profile;
}
const std::string& DataDirectories::profile(const std::string& path)
{
_profile = path;
return _profile;
}
const std::string& DataDirectories::global()
{
if (_global.empty())
_global = known_folder_path(FOLDERID_ProgramData) + "\\Barrier";
return _global;
}
const std::string& DataDirectories::global(const std::string& path)
{
_global = path;
return _global;
}
const std::string& DataDirectories::systemconfig()
{
// systemconfig() is a special case in that it will track the current value
// of global() unless and until it is explictly set otherwise
// previously it would default to the windows folder which was horrible!
if (_systemconfig.empty())
return global();
return _systemconfig;
}
const std::string& DataDirectories::systemconfig(const std::string& path)
{
_systemconfig = path;
return _systemconfig;
}

View File

@@ -28,6 +28,45 @@
// NetworkAddress
//
static bool parse_address(const std::string& address, std::string& host, int& port)
{
/* Three cases ---
* brackets: parse inside for host, check end for port as :INTEGER. DONE
* one colon: ipv4 address with port. DONE
* otherwise: all host, no port. DONE
*
* very, very little error checking. depends on address being trimmed before call.
*
* does not override port with a default value if no port was found in address.
*/
if (address[0] == '[') {
// bracketed host possibly followed by port as :INTEGER
auto endBracket = address.find(']', 1);
if (endBracket == std::string::npos)
return false;
host = address.substr(1, endBracket - 1);
if (endBracket + 1 < address.length()) {
// port follows (or garbage)
if (address[endBracket + 1] != ':')
return false;
port = std::strtol(&address[endBracket + 2], nullptr, 10);
}
} else {
auto colon = address.find(':');
if (colon != std::string::npos && address.find(':', colon + 1) == std::string::npos) {
// one single colon, must be ipv4 with port
host = address.substr(0, colon);
port = std::strtol(&address[colon + 1], nullptr, 10);
} else {
// no colons (ipv4) or more than one colon (ipv6), both without port
host = address;
}
}
return true;
}
// name re-resolution adapted from a patch by Brent Priddy.
NetworkAddress::NetworkAddress() :
@@ -62,50 +101,9 @@ NetworkAddress::NetworkAddress(const String& hostname, int port) :
m_hostname(hostname),
m_port(port)
{
// check for port suffix
String::size_type i = m_hostname.rfind(':');
if (i != String::npos && i + 1 < m_hostname.size()) {
// found a colon. see if it looks like an IPv6 address.
bool colonNotation = false;
bool dotNotation = false;
bool doubleColon = false;
for (String::size_type j = 0; j < i; ++j) {
if (m_hostname[j] == ':') {
colonNotation = true;
dotNotation = false;
if (m_hostname[j + 1] == ':') {
doubleColon = true;
}
}
else if (m_hostname[j] == '.' && colonNotation) {
dotNotation = true;
}
}
// port suffix is ambiguous with IPv6 notation if there's
// a double colon and the end of the address is not in dot
// notation. in that case we assume it's not a port suffix.
// the user can replace the double colon with zeros to
// disambiguate.
if ((!doubleColon || dotNotation) && !colonNotation) {
// parse port from hostname
char* end;
const char* chostname = m_hostname.c_str();
long suffixPort = strtol(chostname + i + 1, &end, 10);
if (end == chostname + i + 1 || *end != '\0') {
throw XSocketAddress(XSocketAddress::kBadPort,
m_hostname, m_port);
}
// trim port from hostname
m_hostname.erase(i);
// save port
m_port = static_cast<int>(suffixPort);
}
}
// check port number
if (!parse_address(hostname, m_hostname, m_port))
throw XSocketAddress(XSocketAddress::kUnknown,
m_hostname, m_port);
checkPort();
}
@@ -145,7 +143,7 @@ NetworkAddress::resolve()
// if hostname is empty then use wildcard address otherwise look
// up the name.
if (m_hostname.empty()) {
m_address = ARCH->newAnyAddr(IArchNetwork::kINET);
m_address = ARCH->newAnyAddr(IArchNetwork::kINET6);
}
else {
m_address = ARCH->nameToAddr(m_hostname);

View File

@@ -22,6 +22,7 @@
#include "net/SocketMultiplexer.h"
#include "net/TSocketMultiplexerMethodJob.h"
#include "arch/XArch.h"
#include "common/DataDirectories.h"
static const char s_certificateDir[] = { "SSL" };
static const char s_certificateFilename[] = { "Barrier.pem" };
@@ -54,7 +55,7 @@ SecureListenSocket::accept()
}
String certificateFilename = barrier::string::sprintf("%s/%s/%s",
ARCH->getProfileDirectory().c_str(),
DataDirectories::profile().c_str(),
s_certificateDir,
s_certificateFilename);

View File

@@ -23,6 +23,7 @@
#include "mt/Lock.h"
#include "arch/XArch.h"
#include "base/Log.h"
#include "common/DataDirectories.h"
#include <openssl/ssl.h>
#include <openssl/err.h>
@@ -699,7 +700,7 @@ SecureSocket::verifyCertFingerprint()
String trustedServersFilename;
trustedServersFilename = barrier::string::sprintf(
"%s/%s/%s",
ARCH->getProfileDirectory().c_str(),
DataDirectories::profile().c_str(),
kFingerprintDirName,
kFingerprintTrustedServersFilename);

View File

@@ -22,6 +22,7 @@
#include "platform/ImmuneKeysReader.h"
#include "barrier/protocol_types.h"
#include "barrier/XScreen.h"
#include "common/DataDirectories.h"
#include "base/Log.h"
//
@@ -52,7 +53,7 @@ static BYTE g_keyState[256] = { 0 };
static bool g_fakeServerInput = false;
static std::vector<DWORD> g_immuneKeys;
static const std::string ImmuneKeysPath = ArchFileWindows().getProfileDirectory() + "\\ImmuneKeys.txt";
static const std::string ImmuneKeysPath = DataDirectories::profile() + "\\ImmuneKeys.txt";
static std::vector<DWORD> immune_keys_list()
{

View File

@@ -62,3 +62,23 @@ MSWindowsUtil::getErrorString(HINSTANCE hinstance, DWORD error, DWORD id)
return result;
}
}
/*
This is a quick and dirty iterative CreateDirectory() wrapper that does zero
error checking. A much better cross-platform option exists in C++17 via
std::filesystem. If/when the project is updated to use 17 this function should
absolutley be replaced!
*/
void
MSWindowsUtil::createDirectory(const std::string& path, bool stripLast)
{
// create parent directories
for (auto pos = path.find_first_of('\\'); pos != std::string::npos; pos = path.find_first_of('\\', pos + 1))
CreateDirectory(path.substr(0, pos).c_str(), NULL);
if (!stripLast)
// create innermost directory
CreateDirectory(path.c_str(), NULL);
}

View File

@@ -37,4 +37,11 @@ public:
found return the string for \p id, replacing ${1} with \p error.
*/
static String getErrorString(HINSTANCE, DWORD error, DWORD id);
//! Create directory
/*!
Create directory \p recursively optionally stripping the last component
(presumably the filename) if \p is set.
*/
static void createDirectory(const std::string& path, bool stripLast = false);
};

View File

@@ -44,7 +44,20 @@ enum {
typedef VOID (WINAPI *SendSas)(BOOL asUser);
const char g_activeDesktop[] = {"activeDesktop:"};
std::string activeDesktopName()
{
const std::size_t BufferLength = 1024;
std::string name;
HDESK desk = OpenInputDesktop(0, FALSE, GENERIC_READ);
if (desk != NULL) {
TCHAR buffer[BufferLength];
if (GetUserObjectInformation(desk, UOI_NAME, buffer, BufferLength - 1, NULL) == TRUE)
name = buffer;
CloseDesktop(desk);
}
LOG((CLOG_DEBUG "found desktop name: %.64s", name.c_str()));
return name;
}
MSWindowsWatchdog::MSWindowsWatchdog(
bool daemonized,
@@ -64,22 +77,8 @@ MSWindowsWatchdog::MSWindowsWatchdog(
m_processRunning(false),
m_fileLogOutputter(NULL),
m_autoElevated(false),
m_ready(false),
m_daemonized(daemonized)
{
m_mutex = ARCH->newMutex();
m_condVar = ARCH->newCondVar();
}
MSWindowsWatchdog::~MSWindowsWatchdog()
{
if (m_condVar != NULL) {
ARCH->closeCondVar(m_condVar);
}
if (m_mutex != NULL) {
ARCH->closeMutex(m_mutex);
}
}
void
@@ -288,12 +287,9 @@ MSWindowsWatchdog::startProcess()
if (!m_daemonized) {
createRet = doStartProcessAsSelf(m_command);
} else {
SECURITY_ATTRIBUTES sa;
ZeroMemory(&sa, sizeof(SECURITY_ATTRIBUTES));
m_autoElevated = activeDesktopName() != "Default";
getActiveDesktop(&sa);
ZeroMemory(&sa, sizeof(SECURITY_ATTRIBUTES));
SECURITY_ATTRIBUTES sa{ 0 };
HANDLE userToken = getUserToken(&sa);
m_elevateProcess = m_autoElevated ? m_autoElevated : m_elevateProcess;
m_autoElevated = false;
@@ -408,7 +404,7 @@ MSWindowsWatchdog::getCommand() const
}
// seems like a fairly convoluted way to get the process name
const char* launchName = App::instance().argsBase().m_pname;
const char* launchName = App::instance().argsBase().m_exename.c_str();
std::string args = ARCH->commandLine();
// build up a full command line
@@ -444,11 +440,7 @@ MSWindowsWatchdog::outputLoop(void*)
}
else {
buffer[bytesRead] = '\0';
testOutput(buffer);
m_ipcLogOutputter.write(kINFO, buffer);
if (m_fileLogOutputter != NULL) {
m_fileLogOutputter->write(kINFO, buffer);
}
@@ -549,63 +541,3 @@ MSWindowsWatchdog::shutdownExistingProcesses()
CloseHandle(snapshot);
m_processRunning = false;
}
void
MSWindowsWatchdog::getActiveDesktop(LPSECURITY_ATTRIBUTES security)
{
String installedDir = ARCH->getInstalledDirectory();
if (!installedDir.empty()) {
String syntoolCommand;
syntoolCommand.append("\"").append(installedDir).append("\\").append("syntool").append("\"");
syntoolCommand.append(" --get-active-desktop");
m_session.updateActiveSession();
bool elevateProcess = m_elevateProcess;
m_elevateProcess = true;
HANDLE userToken = getUserToken(security);
m_elevateProcess = elevateProcess;
BOOL createRet = doStartProcessAsUser(syntoolCommand, userToken, security);
if (!createRet) {
DWORD rc = GetLastError();
RevertToSelf();
}
else {
LOG((CLOG_DEBUG "launched syntool to check active desktop"));
}
ARCH->lockMutex(m_mutex);
int waitTime = 0;
while (!m_ready) {
if (waitTime >= MAXIMUM_WAIT_TIME) {
break;
}
ARCH->waitCondVar(m_condVar, m_mutex, 1.0);
waitTime++;
}
m_ready = false;
ARCH->unlockMutex(m_mutex);
}
}
void
MSWindowsWatchdog::testOutput(String buffer)
{
// HACK: check standard output seems hacky.
size_t i = buffer.find(g_activeDesktop);
if (i != String::npos) {
size_t s = sizeof(g_activeDesktop);
String defaultDesktop("Default");
String sub = buffer.substr(i + s - 1, defaultDesktop.size());
if (sub != defaultDesktop) {
m_autoElevated = true;
}
ARCH->lockMutex(m_mutex);
m_ready = true;
ARCH->broadcastCondVar(m_condVar);
ARCH->unlockMutex(m_mutex);
}
}

View File

@@ -39,7 +39,6 @@ public:
bool autoDetectCommand,
IpcServer& ipcServer,
IpcLogOutputter& ipcLogOutputter);
virtual ~MSWindowsWatchdog();
void startAsync();
std::string getCommand() const;
@@ -58,9 +57,6 @@ private:
void startProcess();
BOOL doStartProcessAsUser(String& command, HANDLE userToken, LPSECURITY_ATTRIBUTES sa);
BOOL doStartProcessAsSelf(String& command);
void sendSas();
void getActiveDesktop(LPSECURITY_ATTRIBUTES security);
void testOutput(String buffer);
private:
Thread* m_thread;
@@ -80,9 +76,6 @@ private:
bool m_processRunning;
FileLogOutputter* m_fileLogOutputter;
bool m_autoElevated;
ArchMutex m_mutex;
ArchCond m_condVar;
bool m_ready;
bool m_daemonized;
};