mirror of
https://github.com/ProtonMail/proton-bridge.git
synced 2025-12-16 07:06:45 +00:00
GODT-1673: TLS certs generation for gRPC service
Wait for Bridge certificate and use it for gRPC connection Other: add README file for Bridge-GUI prerequisites GODT-1673: Configure Client/Server to make use of the bridge cert Other : comments + todo on known issue Other: fix go import alias [skip-ci]
This commit is contained in:
@ -162,6 +162,7 @@ func mailLoop(b *base.Base, c *cli.Context) error { //nolint:funlen
|
|||||||
frontendMode,
|
frontendMode,
|
||||||
!c.Bool(base.FlagNoWindow),
|
!c.Bool(base.FlagNoWindow),
|
||||||
b.CrashHandler,
|
b.CrashHandler,
|
||||||
|
b.TLS,
|
||||||
b.Locations,
|
b.Locations,
|
||||||
b.Settings,
|
b.Settings,
|
||||||
b.Listener,
|
b.Listener,
|
||||||
|
|||||||
2
internal/frontend/.gitignore
vendored
2
internal/frontend/.gitignore
vendored
@ -9,3 +9,5 @@ rcc.qrc
|
|||||||
rcc_cgo_*.go
|
rcc_cgo_*.go
|
||||||
*.qmlc
|
*.qmlc
|
||||||
|
|
||||||
|
# QtCreator env
|
||||||
|
CMakeLists.txt.user
|
||||||
|
|||||||
@ -30,37 +30,94 @@ using namespace grpc;
|
|||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
/// \todo GODT-1673 Decide how to generate/store/share this certificate.
|
|
||||||
|
|
||||||
std::string const cert = R"(-----BEGIN CERTIFICATE-----
|
|
||||||
MIIC5TCCAc2gAwIBAgIJAMUQK0VGexMsMA0GCSqGSIb3DQEBCwUAMBQxEjAQBgNV
|
|
||||||
BAMMCWxvY2FsaG9zdDAeFw0yMjA2MTQxNjUyNTVaFw0yMjA3MTQxNjUyNTVaMBQx
|
|
||||||
EjAQBgNVBAMMCWxvY2FsaG9zdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC
|
|
||||||
ggEBAL6T1JQ0jptq512PBLASpCLFB0px7KIzEml0oMUCkVgUF+2cayrvdBXJZnaO
|
|
||||||
SG+/JPnHDcQ/ecgqkh2Ii6a2x2kWA5KqWiV+bSHp0drXyUGJfM85muLsnrhYwJ83
|
|
||||||
HHtweoUVebRZvHn66KjaH8nBJ+YVWyYbSUhJezcg6nBSEtkW+I/XUHu4S2C7FUc5
|
|
||||||
DXPO3yWWZuZ22OZz70DY3uYE/9COuilotuKdj7XgeKDyKIvRXjPFyqGxwnnp6bXC
|
|
||||||
vWvrQdcxy0wM+vZxew3QtA/Ag9uKJU9owP6noauXw95l49lEVIA5KXVNtdaldVht
|
|
||||||
MO/QoelLZC7h79PK22zbii3x930CAwEAAaM6MDgwFAYDVR0RBA0wC4IJbG9jYWxo
|
|
||||||
b3N0MAsGA1UdDwQEAwIHgDATBgNVHSUEDDAKBggrBgEFBQcDATANBgkqhkiG9w0B
|
|
||||||
AQsFAAOCAQEAW/9PE8dcAN+0C3K96Xd6Y3qOOtQhRw+WlZXhtiqMtlJfTjvuGKs9
|
|
||||||
58xuKcTvU5oobxLv+i5+4gpqLjUZZ9FBnYXZIACNVzq4PEXf+YdzcA+y6RS/rqT4
|
|
||||||
dUjsuYrScAmdXK03Duw3HWYrTp8gsJzIaYGTltUrOn0E4k/TsZb/tZ6z+oH7Fi+p
|
|
||||||
wdsI6Ut6Zwm3Z7WLn5DDk8KvFjHjZkdsCb82SFSAUVrzWo5EtbLIY/7y3A5rGp9D
|
|
||||||
t0AVpuGPo5Vn+MW1WA9HT8lhjz0v5wKGMOBi3VYW+Yx8FWHDpacvbZwVM0MjMSAd
|
|
||||||
M7SXYbNDiLF4LwPLsunoLsW133Ky7s99MA==
|
|
||||||
-----END CERTIFICATE-----)";
|
|
||||||
|
|
||||||
|
|
||||||
Empty empty; // re-used across client calls.
|
Empty empty; // re-used across client calls.
|
||||||
|
|
||||||
|
QString const configFolder = "protonmail/bridge";
|
||||||
|
QString const certFile = "cert.pem";
|
||||||
|
|
||||||
int const maxConnectionTimeSecs = 60; ///< Amount of time after which we consider connection attemps to the server have failed.
|
int const maxConnectionTimeSecs = 60; ///< Amount of time after which we consider connection attemps to the server have failed.
|
||||||
|
int const maxCertificateWaitMsecs = 60 * 1000; ///< Ammount of time we wait for he server to generate the certificate.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//****************************************************************************************************************************************************
|
||||||
|
/// \return user configuration directory used by bridge (based on Golang OS/File::UserConfigDir).
|
||||||
|
//****************************************************************************************************************************************************
|
||||||
|
static const QString _userConfigDir(){
|
||||||
|
QString dir;
|
||||||
|
#ifdef Q_OS_WIN
|
||||||
|
dir = qgetenv ("AppData");
|
||||||
|
if (dir.isEmpty())
|
||||||
|
throw Exception("%AppData% is not defined.");
|
||||||
|
#elif defined(Q_OS_IOS) || defined(Q_OS_DARWIN)
|
||||||
|
dir = qgetenv ("HOME");
|
||||||
|
if (dir.isEmpty())
|
||||||
|
throw Exception("$HOME is not defined.");
|
||||||
|
dir += "/Library/Application Support";
|
||||||
|
#else
|
||||||
|
dir = qgetenv ("XDG_CONFIG_HOME");
|
||||||
|
if (dir.isEmpty())
|
||||||
|
dir = qgetenv ("HOME");
|
||||||
|
if (dir.isEmpty())
|
||||||
|
throw Exception("neither $XDG_CONFIG_HOME nor $HOME are defined");
|
||||||
|
dir += "/.config";
|
||||||
|
#endif
|
||||||
|
QString folder = dir + "/" + configFolder;
|
||||||
|
QDir().mkpath(folder);
|
||||||
|
|
||||||
|
return folder;
|
||||||
|
}
|
||||||
|
|
||||||
|
//****************************************************************************************************************************************************
|
||||||
|
/// \brief wait for certificate generation by Bridge
|
||||||
|
/// \return server certificate generated by Bridge
|
||||||
|
//****************************************************************************************************************************************************
|
||||||
|
std::string GRPCClient::getServerCertificate()
|
||||||
|
{
|
||||||
|
const QString filename = _userConfigDir() + "/" + certFile;
|
||||||
|
QFile file(filename);
|
||||||
|
// TODO : the certificate can exist but still be invalid.
|
||||||
|
// If the certificate is close to its limit, the bridge will generate a new one.
|
||||||
|
// If we read the certificate before the bridge rewrites it the certificate will be invalid.
|
||||||
|
if (!file.exists())
|
||||||
|
{
|
||||||
|
// wait for file creation
|
||||||
|
QFileSystemWatcher watcher(this);
|
||||||
|
if (!watcher.addPath(_userConfigDir()))
|
||||||
|
throw Exception("Failed to watch User Config Directory");
|
||||||
|
connect(&watcher, &QFileSystemWatcher::directoryChanged, this, &GRPCClient::configFolderChanged);
|
||||||
|
|
||||||
|
// set up an eventLoop to wait for the certIsReady signal or timeout.
|
||||||
|
QTimer timer;
|
||||||
|
timer.setSingleShot(true);
|
||||||
|
QEventLoop loop;
|
||||||
|
connect(this, &GRPCClient::certIsReady, &loop, &QEventLoop::quit);
|
||||||
|
connect(&timer, &QTimer::timeout, &loop, &QEventLoop::quit);
|
||||||
|
timer.start(maxCertificateWaitMsecs);
|
||||||
|
loop.exec();
|
||||||
|
|
||||||
|
// timeout case.
|
||||||
|
if(!timer.isActive())
|
||||||
|
throw Exception("Server failed to generate certificate on time");
|
||||||
|
//else certIsReadySignal.
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!file.open(QFile::ReadOnly))
|
||||||
|
throw Exception("Failed to read the server certificate");
|
||||||
|
QByteArray qbaCert = file.readAll();
|
||||||
|
std::string cert(qbaCert.constData(), qbaCert.length());
|
||||||
|
file.close();
|
||||||
|
return cert;
|
||||||
|
}
|
||||||
|
|
||||||
|
//****************************************************************************************************************************************************
|
||||||
|
/// \brief Action on UserConfig directory changes, looking for the certificate creation
|
||||||
|
//****************************************************************************************************************************************************
|
||||||
|
void GRPCClient::configFolderChanged()
|
||||||
|
{
|
||||||
|
QFile cert(_userConfigDir() + "/" + certFile);
|
||||||
|
if (cert.exists())
|
||||||
|
emit certIsReady();
|
||||||
|
}
|
||||||
|
|
||||||
//****************************************************************************************************************************************************
|
//****************************************************************************************************************************************************
|
||||||
/// \param[out] outError If the function returns false, this variable contains a description of the error.
|
/// \param[out] outError If the function returns false, this variable contains a description of the error.
|
||||||
@ -71,9 +128,9 @@ bool GRPCClient::connectToServer(QString &outError)
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
SslCredentialsOptions opts;
|
SslCredentialsOptions opts;
|
||||||
opts.pem_root_certs += cert;
|
opts.pem_root_certs += this->getServerCertificate();
|
||||||
|
|
||||||
channel_ = CreateChannel("localhost:9292", grpc::SslCredentials(opts));
|
channel_ = CreateChannel("127.0.0.1:9292", grpc::SslCredentials(opts));
|
||||||
if (!channel_)
|
if (!channel_)
|
||||||
throw Exception("Channel creation failed.");
|
throw Exception("Channel creation failed.");
|
||||||
|
|
||||||
|
|||||||
@ -171,6 +171,7 @@ signals:
|
|||||||
void changeKeychainFinished();
|
void changeKeychainFinished();
|
||||||
void hasNoKeychain();
|
void hasNoKeychain();
|
||||||
void rebuildKeychain();
|
void rebuildKeychain();
|
||||||
|
void certIsReady();
|
||||||
|
|
||||||
signals: // mail releated events
|
signals: // mail releated events
|
||||||
void noActiveKeyForRecipient(QString const &email); // _ func(email string) `signal:noActiveKeyForRecipient`
|
void noActiveKeyForRecipient(QString const &email); // _ func(email string) `signal:noActiveKeyForRecipient`
|
||||||
@ -182,7 +183,8 @@ public:
|
|||||||
grpc::Status startEventStream(); ///< Retrieve and signal the events in the event stream.
|
grpc::Status startEventStream(); ///< Retrieve and signal the events in the event stream.
|
||||||
grpc::Status stopEventStream(); ///< Stop the event stream.
|
grpc::Status stopEventStream(); ///< Stop the event stream.
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void configFolderChanged();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
grpc::Status simpleMethod(SimpleMethod method); ///< perform a gRPC call to a bool setter.
|
grpc::Status simpleMethod(SimpleMethod method); ///< perform a gRPC call to a bool setter.
|
||||||
@ -196,6 +198,7 @@ private:
|
|||||||
grpc::Status getURL(StringGetter getter, QUrl& outValue); ///< Perform a gRPC call to a string getter, with resulted converted to QUrl.
|
grpc::Status getURL(StringGetter getter, QUrl& outValue); ///< Perform a gRPC call to a string getter, with resulted converted to QUrl.
|
||||||
grpc::Status methodWithStringParam(StringParamMethod method, QString const& str); ///< Perfom a gRPC call that takes a string as a parameter and returns an Empty.
|
grpc::Status methodWithStringParam(StringParamMethod method, QString const& str); ///< Perfom a gRPC call that takes a string as a parameter and returns an Empty.
|
||||||
|
|
||||||
|
std::string getServerCertificate(); ///< Wait until server certificates is generated and retrieve it.
|
||||||
void processAppEvent(grpc::AppEvent const &event); ///< Process an 'App' event.
|
void processAppEvent(grpc::AppEvent const &event); ///< Process an 'App' event.
|
||||||
void processLoginEvent(grpc::LoginEvent const &event); ///< Process a 'Login' event.
|
void processLoginEvent(grpc::LoginEvent const &event); ///< Process a 'Login' event.
|
||||||
void processUpdateEvent(grpc::UpdateEvent const &event); ///< Process an 'Update' event.
|
void processUpdateEvent(grpc::UpdateEvent const &event); ///< Process an 'Update' event.
|
||||||
|
|||||||
28
internal/frontend/bridge-gui/README.md
Normal file
28
internal/frontend/bridge-gui/README.md
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
## Prerequisite
|
||||||
|
|
||||||
|
```` bash
|
||||||
|
sudo apt install build-essential
|
||||||
|
sudo apt install tar curl zip unzip
|
||||||
|
sudo apt install linux-headers-$(uname -r)
|
||||||
|
sudo apt install mesa-common-dev libglu1-mesa-dev
|
||||||
|
````
|
||||||
|
|
||||||
|
## Define Qt5DIR
|
||||||
|
|
||||||
|
```` bash
|
||||||
|
export QT5DIR=/opt/Qt/5.13.0/gcc_64
|
||||||
|
````
|
||||||
|
|
||||||
|
## install vcpkg and define VCPKG_ROOT
|
||||||
|
|
||||||
|
```` bash
|
||||||
|
git clone https://github.com/Microsoft/vcpkg.git
|
||||||
|
./vcpkg/bootstrap-vcpkg.sh
|
||||||
|
export VCPKG_ROOT=$PWD/vcpkg
|
||||||
|
````
|
||||||
|
|
||||||
|
## install grpc & protobuf
|
||||||
|
|
||||||
|
```` bash
|
||||||
|
./vcpkg install grpc
|
||||||
|
````
|
||||||
@ -21,6 +21,7 @@ package frontend
|
|||||||
import (
|
import (
|
||||||
"github.com/ProtonMail/proton-bridge/v2/internal/bridge"
|
"github.com/ProtonMail/proton-bridge/v2/internal/bridge"
|
||||||
"github.com/ProtonMail/proton-bridge/v2/internal/config/settings"
|
"github.com/ProtonMail/proton-bridge/v2/internal/config/settings"
|
||||||
|
"github.com/ProtonMail/proton-bridge/v2/internal/config/tls"
|
||||||
"github.com/ProtonMail/proton-bridge/v2/internal/config/useragent"
|
"github.com/ProtonMail/proton-bridge/v2/internal/config/useragent"
|
||||||
"github.com/ProtonMail/proton-bridge/v2/internal/frontend/cli"
|
"github.com/ProtonMail/proton-bridge/v2/internal/frontend/cli"
|
||||||
"github.com/ProtonMail/proton-bridge/v2/internal/frontend/grpc"
|
"github.com/ProtonMail/proton-bridge/v2/internal/frontend/grpc"
|
||||||
@ -47,6 +48,7 @@ func New(
|
|||||||
frontendType string,
|
frontendType string,
|
||||||
showWindowOnStart bool,
|
showWindowOnStart bool,
|
||||||
panicHandler types.PanicHandler,
|
panicHandler types.PanicHandler,
|
||||||
|
tls *tls.TLS,
|
||||||
locations *locations.Locations,
|
locations *locations.Locations,
|
||||||
settings *settings.Settings,
|
settings *settings.Settings,
|
||||||
eventListener listener.Listener,
|
eventListener listener.Listener,
|
||||||
@ -64,6 +66,7 @@ func New(
|
|||||||
programName,
|
programName,
|
||||||
showWindowOnStart,
|
showWindowOnStart,
|
||||||
panicHandler,
|
panicHandler,
|
||||||
|
tls,
|
||||||
locations,
|
locations,
|
||||||
settings,
|
settings,
|
||||||
eventListener,
|
eventListener,
|
||||||
|
|||||||
@ -1,69 +0,0 @@
|
|||||||
// Copyright (c) 2022 Proton AG
|
|
||||||
//
|
|
||||||
// This file is part of Proton Mail Bridge.Bridge.
|
|
||||||
//
|
|
||||||
// Proton Mail Bridge is free software: you can redistribute it and/or modify
|
|
||||||
// it under the terms of the GNU General Public License as published by
|
|
||||||
// the Free Software Foundation, either version 3 of the License, or
|
|
||||||
// (at your option) any later version.
|
|
||||||
//
|
|
||||||
// Proton Mail Bridge 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 Proton Mail Bridge. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
package grpc
|
|
||||||
|
|
||||||
//goland:noinspection SpellCheckingInspection
|
|
||||||
const (
|
|
||||||
serverCert = `-----BEGIN CERTIFICATE-----
|
|
||||||
MIIC5TCCAc2gAwIBAgIJAMUQK0VGexMsMA0GCSqGSIb3DQEBCwUAMBQxEjAQBgNV
|
|
||||||
BAMMCWxvY2FsaG9zdDAeFw0yMjA2MTQxNjUyNTVaFw0yMjA3MTQxNjUyNTVaMBQx
|
|
||||||
EjAQBgNVBAMMCWxvY2FsaG9zdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC
|
|
||||||
ggEBAL6T1JQ0jptq512PBLASpCLFB0px7KIzEml0oMUCkVgUF+2cayrvdBXJZnaO
|
|
||||||
SG+/JPnHDcQ/ecgqkh2Ii6a2x2kWA5KqWiV+bSHp0drXyUGJfM85muLsnrhYwJ83
|
|
||||||
HHtweoUVebRZvHn66KjaH8nBJ+YVWyYbSUhJezcg6nBSEtkW+I/XUHu4S2C7FUc5
|
|
||||||
DXPO3yWWZuZ22OZz70DY3uYE/9COuilotuKdj7XgeKDyKIvRXjPFyqGxwnnp6bXC
|
|
||||||
vWvrQdcxy0wM+vZxew3QtA/Ag9uKJU9owP6noauXw95l49lEVIA5KXVNtdaldVht
|
|
||||||
MO/QoelLZC7h79PK22zbii3x930CAwEAAaM6MDgwFAYDVR0RBA0wC4IJbG9jYWxo
|
|
||||||
b3N0MAsGA1UdDwQEAwIHgDATBgNVHSUEDDAKBggrBgEFBQcDATANBgkqhkiG9w0B
|
|
||||||
AQsFAAOCAQEAW/9PE8dcAN+0C3K96Xd6Y3qOOtQhRw+WlZXhtiqMtlJfTjvuGKs9
|
|
||||||
58xuKcTvU5oobxLv+i5+4gpqLjUZZ9FBnYXZIACNVzq4PEXf+YdzcA+y6RS/rqT4
|
|
||||||
dUjsuYrScAmdXK03Duw3HWYrTp8gsJzIaYGTltUrOn0E4k/TsZb/tZ6z+oH7Fi+p
|
|
||||||
wdsI6Ut6Zwm3Z7WLn5DDk8KvFjHjZkdsCb82SFSAUVrzWo5EtbLIY/7y3A5rGp9D
|
|
||||||
t0AVpuGPo5Vn+MW1WA9HT8lhjz0v5wKGMOBi3VYW+Yx8FWHDpacvbZwVM0MjMSAd
|
|
||||||
M7SXYbNDiLF4LwPLsunoLsW133Ky7s99MA==
|
|
||||||
-----END CERTIFICATE-----`
|
|
||||||
|
|
||||||
serverKey = `-----BEGIN PRIVATE KEY-----
|
|
||||||
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQC+k9SUNI6baudd
|
|
||||||
jwSwEqQixQdKceyiMxJpdKDFApFYFBftnGsq73QVyWZ2jkhvvyT5xw3EP3nIKpId
|
|
||||||
iIumtsdpFgOSqlolfm0h6dHa18lBiXzPOZri7J64WMCfNxx7cHqFFXm0Wbx5+uio
|
|
||||||
2h/JwSfmFVsmG0lISXs3IOpwUhLZFviP11B7uEtguxVHOQ1zzt8llmbmdtjmc+9A
|
|
||||||
2N7mBP/QjropaLbinY+14Hig8iiL0V4zxcqhscJ56em1wr1r60HXMctMDPr2cXsN
|
|
||||||
0LQPwIPbiiVPaMD+p6Grl8PeZePZRFSAOSl1TbXWpXVYbTDv0KHpS2Qu4e/Tytts
|
|
||||||
24ot8fd9AgMBAAECggEBAJFkGpOOnRU4s5YO3BavwgS8p9lFnLAJooxNa7GhSd0W
|
|
||||||
R0MBSEkTMU7FvaPI3L5T5xOfpoMHohLxV1Osrk3bt7oWD1e/GtLr5routejtIx8a
|
|
||||||
kttNKTriJhyhqSJOWy5ZGz+YqKbMpxuwLftTnVjAQX4o4MbrnjbFyHjAZdqW4sY2
|
|
||||||
jLulfEdOave6nxaEocmIkoXEjuX90LB+yNG6ncSYM3GV+IyCVw7DsoU4dLd/IRDa
|
|
||||||
4iJVF7tVdAsZqN6/EVYXpGqG0t1HI8ddacHa1qWgCG3kBB+3faxXZcDJdlRrXLUQ
|
|
||||||
4jLH8oEfXOb5YgCwyYzW2EynXEpG5vjsPmsCWJY/mIECgYEA52av81+lui97KLg+
|
|
||||||
T07XtR8zJPMkHnBNfc6ooWku/+0NuQPpUq14vqzRVut9jBHUDP3xSvrPnXsp15ZA
|
|
||||||
/mipLQLNKssTYtk90cyGqLUkrd/NPLFZLXToBfWBlfazdcJQQRIxZ2dTy5MH+HIU
|
|
||||||
Oio3LZi+iDIbdzzSlmL8PaLit20CgYEA0tYsswhq6OaWx25iu4hBMRlt6hr9qGVW
|
|
||||||
jlzCFjBhlh3YtoBti2w2fsJdU+hUpeXU327fhFmdCQFXtf+Om5CSHihmJ+mHj9O1
|
|
||||||
5Jd6zn4o8szdg5je9T4gt7KG6QdXaFJ2aMuq+SxZl1NIE+9qnf/qom4GHHZ/Nj41
|
|
||||||
vwlQu+zS5lECgYAOzSK0DoorPp5CHIbfy8tAap563pKQ394VDgL7UB8Rf7hA/V8P
|
|
||||||
SslOaP9679U4AGvv6M5mXWSqThZ/E71UiJ1Jo8Q72IGE8SBjKxHx+KQ/+vDF0RJD
|
|
||||||
NhchSnLfhMg14BgCEYfXdWSGwQDhg2qHzet5nyuQyqO3HMzbkblQt/qIgQKBgHLv
|
|
||||||
nPiQmy+SHRplO9+93MQ2d6wKwMNfUztSp9/OyjQ62xxKkO1TtbWOobAPVK4Hx+9y
|
|
||||||
EtmkvK3fFIC763M08eMM5PvXHDa1FFCkn6cYMZyDQDLwUINjNhTOdytr/CN76N8i
|
|
||||||
QHeLzN9o4D814mp1y+R2lFBJ7PmWGlilbGS2KxaxAoGAFMsb1MER+eTOUO3z05Di
|
|
||||||
lts4VRWQhq2frd/on6AcTv4idQox1RcOrKWQbRVgeQVY1SkkHhg8lN0jX3W3EfuQ
|
|
||||||
aOfyky04GbLiwO8NRHZMlORWLxlCkrUrb6Va+LQlT0JvpQbqdbu6Ix8NomG9K697
|
|
||||||
aScKmY7bGC0ki2IIdt2YZ5I=
|
|
||||||
-----END PRIVATE KEY-----`
|
|
||||||
)
|
|
||||||
@ -20,7 +20,7 @@ package grpc
|
|||||||
//go:generate protoc --go_out=. --go_opt=paths=source_relative --go-grpc_out=. --go-grpc_opt=paths=source_relative bridge.proto
|
//go:generate protoc --go_out=. --go_opt=paths=source_relative --go-grpc_out=. --go-grpc_opt=paths=source_relative bridge.proto
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"crypto/tls"
|
cryptotls "crypto/tls"
|
||||||
"net"
|
"net"
|
||||||
"runtime"
|
"runtime"
|
||||||
"strings"
|
"strings"
|
||||||
@ -29,6 +29,7 @@ import (
|
|||||||
|
|
||||||
"github.com/ProtonMail/proton-bridge/v2/internal/bridge"
|
"github.com/ProtonMail/proton-bridge/v2/internal/bridge"
|
||||||
"github.com/ProtonMail/proton-bridge/v2/internal/config/settings"
|
"github.com/ProtonMail/proton-bridge/v2/internal/config/settings"
|
||||||
|
bridgetls "github.com/ProtonMail/proton-bridge/v2/internal/config/tls"
|
||||||
"github.com/ProtonMail/proton-bridge/v2/internal/config/useragent"
|
"github.com/ProtonMail/proton-bridge/v2/internal/config/useragent"
|
||||||
"github.com/ProtonMail/proton-bridge/v2/internal/events"
|
"github.com/ProtonMail/proton-bridge/v2/internal/events"
|
||||||
"github.com/ProtonMail/proton-bridge/v2/internal/frontend/types"
|
"github.com/ProtonMail/proton-bridge/v2/internal/frontend/types"
|
||||||
@ -54,6 +55,7 @@ type Service struct { // nolint:structcheck
|
|||||||
programName string
|
programName string
|
||||||
programVersion string
|
programVersion string
|
||||||
panicHandler types.PanicHandler
|
panicHandler types.PanicHandler
|
||||||
|
tls *bridgetls.TLS
|
||||||
locations *locations.Locations
|
locations *locations.Locations
|
||||||
settings *settings.Settings
|
settings *settings.Settings
|
||||||
eventListener listener.Listener
|
eventListener listener.Listener
|
||||||
@ -78,6 +80,7 @@ func NewService(
|
|||||||
programName string,
|
programName string,
|
||||||
showOnStartup bool,
|
showOnStartup bool,
|
||||||
panicHandler types.PanicHandler,
|
panicHandler types.PanicHandler,
|
||||||
|
tls *bridgetls.TLS,
|
||||||
locations *locations.Locations,
|
locations *locations.Locations,
|
||||||
settings *settings.Settings,
|
settings *settings.Settings,
|
||||||
eventListener listener.Listener,
|
eventListener listener.Listener,
|
||||||
@ -93,6 +96,7 @@ func NewService(
|
|||||||
programName: programName,
|
programName: programName,
|
||||||
programVersion: version,
|
programVersion: version,
|
||||||
panicHandler: panicHandler,
|
panicHandler: panicHandler,
|
||||||
|
tls: tls,
|
||||||
locations: locations,
|
locations: locations,
|
||||||
settings: settings,
|
settings: settings,
|
||||||
eventListener: eventListener,
|
eventListener: eventListener,
|
||||||
@ -109,19 +113,16 @@ func NewService(
|
|||||||
}
|
}
|
||||||
|
|
||||||
s.userAgent.SetPlatform(runtime.GOOS) // TO-DO GODT-1672 In the previous Qt frontend, this routine used QSysInfo::PrettyProductName to return a more accurate description, e.g. "Windows 10" or "MacOS 10.12"
|
s.userAgent.SetPlatform(runtime.GOOS) // TO-DO GODT-1672 In the previous Qt frontend, this routine used QSysInfo::PrettyProductName to return a more accurate description, e.g. "Windows 10" or "MacOS 10.12"
|
||||||
|
config, err := tls.GetConfig()
|
||||||
cert, err := tls.X509KeyPair([]byte(serverCert), []byte(serverKey))
|
config.ClientAuth = cryptotls.NoClientCert // skip client auth if the certificate allow it.
|
||||||
if err != nil {
|
if err != nil {
|
||||||
s.log.WithError(err).Error("could not create key pair")
|
s.log.WithError(err).Error("could not get TLS config")
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
s.initAutostart()
|
s.initAutostart()
|
||||||
|
|
||||||
s.grpcServer = grpc.NewServer(grpc.Creds(credentials.NewTLS(&tls.Config{
|
s.grpcServer = grpc.NewServer(grpc.Creds(credentials.NewTLS(config)))
|
||||||
Certificates: []tls.Certificate{cert},
|
|
||||||
MinVersion: tls.VersionTLS13,
|
|
||||||
})))
|
|
||||||
|
|
||||||
RegisterBridgeServer(s.grpcServer, &s)
|
RegisterBridgeServer(s.grpcServer, &s)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user