Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use ansi codepage for internal multibyte strings on windows (fixes #976, fixes #974, fixes #444) #979

Merged
merged 1 commit into from
Dec 30, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 11 additions & 10 deletions src/gui/src/CommandProcess.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,34 +30,35 @@ CommandProcess::CommandProcess(QString cmd, QStringList arguments, QString input
QString CommandProcess::run()
{
QProcess process;
QString standardOutput, standardError;
process.setReadChannel(QProcess::StandardOutput);
process.start(m_Command, m_Arguments);
bool success = process.waitForStarted();

QString output, error;
if (success)
{
if (!m_Input.isEmpty()) {
process.write(m_Input.toStdString().c_str());
process.write(m_Input.toLocal8Bit());
}

if (process.waitForFinished()) {
output = process.readAllStandardOutput().trimmed();
error = process.readAllStandardError().trimmed();
standardOutput = QString::fromLocal8Bit(process.readAllStandardOutput().trimmed());
standardError = QString::fromLocal8Bit(process.readAllStandardError().trimmed());
}
}

int code = process.exitCode();
if (!error.isEmpty() || !success || code != 0)
if (!standardError.isEmpty() || !success || code != 0)
{
throw std::runtime_error(
QString("Code: %1\nError: %2")
.arg(process.exitCode())
.arg(error.isEmpty() ? "Unknown" : error)
.toStdString());
std::string(
QString("Code: %1\nError: %2")
.arg(process.exitCode())
.arg(standardError.isEmpty() ? "Unknown" : standardError)
.toLocal8Bit().constData()));
}

emit finished();

return output;
return standardOutput;
}
7 changes: 2 additions & 5 deletions src/gui/src/Fingerprint.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,7 @@
*/

#include "Fingerprint.h"

#include "common/DataDirectories.h"
#include "QUtility.h"

#include <QDir>
#include <QTextStream>
Expand Down Expand Up @@ -125,10 +124,8 @@ void Fingerprint::persistDirectory()

QString Fingerprint::directoryPath()
{
auto profileDir = QString::fromStdString(DataDirectories::profile());

return QString("%1/%2")
.arg(profileDir)
.arg(profilePath())
.arg(kDirName);
}

Expand Down
8 changes: 3 additions & 5 deletions src/gui/src/IpcClient.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -104,14 +104,12 @@ void IpcClient::sendCommand(const QString& command, ElevateMode const elevate)

stream.writeRawData(kIpcMsgCommand, 4);

std::string stdStringCommand = command.toStdString();
const char* charCommand = stdStringCommand.c_str();
int length = (int)strlen(charCommand);
QByteArray utf8Command = command.toUtf8();

char lenBuf[4];
intToBytes(length, lenBuf, 4);
intToBytes(utf8Command.size(), lenBuf, 4);
stream.writeRawData(lenBuf, 4);
stream.writeRawData(charCommand, length);
stream.writeRawData(utf8Command.constData(), utf8Command.size());

char elevateBuf[1];
// Refer to enum ElevateMode documentation for why this flag is mapped this way
Expand Down
3 changes: 1 addition & 2 deletions src/gui/src/MainWindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@
#include "ProcessorArch.h"
#include "SslCertificate.h"
#include "ShutdownCh.h"
#include "common/DataDirectories.h"

#include <QtCore>
#include <QtGui>
Expand Down Expand Up @@ -526,7 +525,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" << QString::fromStdString("\"" + DataDirectories::profile() + "\"");
args << "--profile-dir" << QString("\"%1\"").arg(profilePath());
#endif

if ((barrierType() == barrierClient && !clientArgs(args, app))
Expand Down
9 changes: 9 additions & 0 deletions src/gui/src/QUtility.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@

#include "ProcessorArch.h"
#include "CommandProcess.h"
#include "common/DataDirectories.h"

#if defined(Q_OS_LINUX)
#include <QProcess>
Expand Down Expand Up @@ -113,3 +114,11 @@ QString getOSInformation()

return result;
}

QString profilePath()
{
// Get path to current profile directory, properly converted
// from an OS locale std::string to Unicode QString.
auto localePath = DataDirectories::profile();
return QString::fromLocal8Bit(localePath.c_str(), localePath.size());
}
1 change: 1 addition & 0 deletions src/gui/src/QUtility.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,3 +29,4 @@ QString hash(const QString& string);
QString getFirstMacAddress();
qProcessorArch getProcessorArch();
QString getOSInformation();
QString profilePath();
47 changes: 21 additions & 26 deletions src/gui/src/SslCertificate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@

#include "SslCertificate.h"
#include "Fingerprint.h"
#include "common/DataDirectories.h"
#include "QUtility.h"

#include <QProcess>
#include <QDir>
Expand All @@ -43,13 +43,13 @@ static const char kConfigFile[] = "barrier.conf";
SslCertificate::SslCertificate(QObject *parent) :
QObject(parent)
{
m_ProfileDir = DataDirectories::profile();
if (m_ProfileDir.empty()) {
m_ProfileDir = profilePath();
if (m_ProfileDir.isEmpty()) {
emit error(tr("Failed to get profile directory."));
}
}

std::pair<bool, std::string> SslCertificate::runTool(const QStringList& args)
std::pair<bool, QString> SslCertificate::runTool(const QStringList& args)
{
QString program;
#if defined(Q_OS_WIN)
Expand All @@ -68,17 +68,15 @@ std::pair<bool, std::string> SslCertificate::runTool(const QStringList& args)
#endif

QProcess process;
QString standardOutput, standardError;
process.setEnvironment(environment);
process.start(program, args);

bool success = process.waitForStarted();
std::string output;

QString standardError;
if (success && process.waitForFinished())
{
output = process.readAllStandardOutput().trimmed().toStdString();
standardError = process.readAllStandardError().trimmed();
standardOutput = QString::fromLocal8Bit(process.readAllStandardOutput().trimmed());
standardError = QString::fromLocal8Bit(process.readAllStandardError().trimmed());
}

int code = process.exitCode();
Expand All @@ -89,15 +87,15 @@ std::pair<bool, std::string> SslCertificate::runTool(const QStringList& args)
.arg(program)
.arg(process.exitCode())
.arg(standardError.isEmpty() ? "Unknown" : standardError));
return {false, output};
return {false, standardOutput};
}

return {true, output};
return {true, standardOutput};
}

void SslCertificate::generateCertificate()
{
auto filename = QString::fromStdString(getCertificatePath());
auto filename = getCertificatePath();

QFile file(filename);
if (!file.exists() || !isCertificateValid(filename)) {
Expand All @@ -122,7 +120,7 @@ void SslCertificate::generateCertificate()
arguments.append("-newkey");
arguments.append("rsa:2048");

QDir sslDir(QString::fromStdString(getCertificateDirectory()));
QDir sslDir(getCertificateDirectory());
if (!sslDir.exists()) {
sslDir.mkpath(".");
}
Expand Down Expand Up @@ -159,35 +157,32 @@ void SslCertificate::generateFingerprint(const QString& certificateFilename)

auto ret = runTool(arguments);
bool success = ret.first;
std::string output = ret.second;

if (!success) {
return;
}

// find the fingerprint from the tool output
auto i = output.find_first_of('=');
if (i != std::string::npos) {
i++;
auto fingerprint = output.substr(
i, output.size() - i);
QString fingerprint = ret.second;
auto i = fingerprint.indexOf('=');
if (i != -1) {
fingerprint.remove(0, i+1);

Fingerprint::local().trust(QString::fromStdString(fingerprint), false);
Fingerprint::local().trust(fingerprint, false);
emit info(tr("SSL fingerprint generated."));
}
else {
emit error(tr("Failed to find SSL fingerprint."));
}
}

std::string SslCertificate::getCertificatePath()
QString SslCertificate::getCertificatePath()
{
return getCertificateDirectory() + QDir::separator().toLatin1() + kCertificateFilename;
return getCertificateDirectory() + QDir::separator() + kCertificateFilename;
}

std::string SslCertificate::getCertificateDirectory()
QString SslCertificate::getCertificateDirectory()
{
return m_ProfileDir + QDir::separator().toLatin1() + kSslDir;
return m_ProfileDir + QDir::separator() + kSslDir;
}

bool SslCertificate::isCertificateValid(const QString& path)
Expand All @@ -198,7 +193,7 @@ bool SslCertificate::isCertificateValid(const QString& path)

BIO* bio = BIO_new(BIO_s_file());

auto ret = BIO_read_filename(bio, path.toStdString().c_str());
auto ret = BIO_read_filename(bio, path.toLocal8Bit().constData());
if (!ret) {
emit info(tr("Could not read from default certificate file."));
BIO_free_all(bio);
Expand Down
8 changes: 4 additions & 4 deletions src/gui/src/SslCertificate.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,13 +36,13 @@ public slots:
void generateFinished();

private:
std::pair<bool, std::string> runTool(const QStringList& args);
std::pair<bool, QString> runTool(const QStringList& args);
void generateFingerprint(const QString& certificateFilename);

std::string getCertificatePath();
std::string getCertificateDirectory();
QString getCertificatePath();
QString getCertificateDirectory();

bool isCertificateValid(const QString& path);
private:
std::string m_ProfileDir;
QString m_ProfileDir;
};
3 changes: 2 additions & 1 deletion src/lib/barrier/win32/DaemonApp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
#include "base/log_outputters.h"
#include "base/Log.h"
#include "common/DataDirectories.h"
#include "base/Unicode.h"

#include "arch/win32/ArchMiscWindows.h"
#include "arch/win32/XArchWindows.h"
Expand Down Expand Up @@ -257,7 +258,7 @@ DaemonApp::handleIpcMessage(const Event& e, void*)
switch (m->type()) {
case kIpcCommand: {
IpcCommandMessage* cm = static_cast<IpcCommandMessage*>(m);
String command = cm->command();
String command = Unicode::UTF8ToText(cm->command());

// if empty quotes, clear.
if (command == "\"\"") {
Expand Down
28 changes: 3 additions & 25 deletions src/lib/common/win32/DataDirectories.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,34 +16,12 @@
*/

#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;
}
#include "KnownFolderPaths.h"

const std::string& DataDirectories::profile()
{
if (_profile.empty())
_profile = known_folder_path(FOLDERID_LocalAppData) + "\\Barrier";
_profile = localAppDataPath() + "\\Barrier";
return _profile;
}
const std::string& DataDirectories::profile(const std::string& path)
Expand All @@ -55,7 +33,7 @@ const std::string& DataDirectories::profile(const std::string& path)
const std::string& DataDirectories::global()
{
if (_global.empty())
_global = known_folder_path(FOLDERID_ProgramData) + "\\Barrier";
_global = programDataPath() + "\\Barrier";
return _global;
}
const std::string& DataDirectories::global(const std::string& path)
Expand Down
Loading