Use GnuTLS instead
This commit is contained in:
parent
8b04a3b16a
commit
31b24d9a09
|
@ -79,7 +79,7 @@ pkg_check_modules(GIO REQUIRED gio-2.0)
|
||||||
pkg_check_modules(GOBJECT REQUIRED gobject-2.0)
|
pkg_check_modules(GOBJECT REQUIRED gobject-2.0)
|
||||||
pkg_check_modules(CDIO libcdio)
|
pkg_check_modules(CDIO libcdio)
|
||||||
find_package(Threads)
|
find_package(Threads)
|
||||||
find_package(OpenSSL)
|
find_package(GnuTLS)
|
||||||
find_package(Boost REQUIRED)
|
find_package(Boost REQUIRED)
|
||||||
find_package(Protobuf REQUIRED)
|
find_package(Protobuf REQUIRED)
|
||||||
find_library(PROTOBUF_STATIC_LIBRARY libprotobuf.a libprotobuf)
|
find_library(PROTOBUF_STATIC_LIBRARY libprotobuf.a libprotobuf)
|
||||||
|
|
|
@ -5,7 +5,7 @@ run zypper --non-interactive --gpg-auto-import-keys dup -l -y
|
||||||
|
|
||||||
run zypper --non-interactive --gpg-auto-import-keys install \
|
run zypper --non-interactive --gpg-auto-import-keys install \
|
||||||
lsb-release git tar make cmake gcc gcc-c++ pkg-config gettext-tools \
|
lsb-release git tar make cmake gcc gcc-c++ pkg-config gettext-tools \
|
||||||
glibc-devel glib2-devel glib2-tools dbus-1-devel alsa-devel libpulse-devel libnotify-devel libopenssl-devel \
|
glibc-devel glib2-devel glib2-tools dbus-1-devel alsa-devel libpulse-devel libnotify-devel libgnutls-devel \
|
||||||
boost-devel protobuf-devel sqlite3-devel taglib-devel \
|
boost-devel protobuf-devel sqlite3-devel taglib-devel \
|
||||||
gstreamer-devel gstreamer-plugins-base-devel libxine-devel vlc-devel \
|
gstreamer-devel gstreamer-plugins-base-devel libxine-devel vlc-devel \
|
||||||
libQt5Core-devel libQt5Gui-devel libQt5Widgets-devel libQt5Concurrent-devel libQt5Network-devel libQt5Sql-devel \
|
libQt5Core-devel libQt5Gui-devel libQt5Widgets-devel libQt5Concurrent-devel libQt5Network-devel libQt5Sql-devel \
|
||||||
|
|
|
@ -49,6 +49,7 @@ To build Strawberry from source you need the following installed on your system
|
||||||
* [DBus (linux)](https://www.freedesktop.org/wiki/Software/dbus/)
|
* [DBus (linux)](https://www.freedesktop.org/wiki/Software/dbus/)
|
||||||
* [PulseAudio (linux optional)](https://www.freedesktop.org/wiki/Software/PulseAudio/?)
|
* [PulseAudio (linux optional)](https://www.freedesktop.org/wiki/Software/PulseAudio/?)
|
||||||
* [GStreamer](https://gstreamer.freedesktop.org/), [Xine](https://www.xine-project.org), [VLC](https://www.videolan.org) or [Phonon](https://techbase.kde.org/Phonon)
|
* [GStreamer](https://gstreamer.freedesktop.org/), [Xine](https://www.xine-project.org), [VLC](https://www.videolan.org) or [Phonon](https://techbase.kde.org/Phonon)
|
||||||
|
* [GnuTLS](https://www.gnutls.org/)
|
||||||
|
|
||||||
Optional dependencies:
|
Optional dependencies:
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,7 @@ Build-Depends: debhelper (>= 7),
|
||||||
protobuf-compiler,
|
protobuf-compiler,
|
||||||
libglib2.0-dev,
|
libglib2.0-dev,
|
||||||
libdbus-1-dev,
|
libdbus-1-dev,
|
||||||
libssl-dev,
|
libgnutls28-dev,
|
||||||
libprotobuf-dev,
|
libprotobuf-dev,
|
||||||
libboost-dev,
|
libboost-dev,
|
||||||
libsqlite3-dev,
|
libsqlite3-dev,
|
||||||
|
|
|
@ -10,7 +10,7 @@ makedepends=(git cmake make gcc boost gettext qt5-tools)
|
||||||
depends=(
|
depends=(
|
||||||
desktop-file-utils
|
desktop-file-utils
|
||||||
hicolor-icon-theme
|
hicolor-icon-theme
|
||||||
openssl
|
gnutls
|
||||||
udisks2
|
udisks2
|
||||||
protobuf
|
protobuf
|
||||||
qt5-base
|
qt5-base
|
||||||
|
|
|
@ -41,7 +41,7 @@ BuildRequires: pkgconfig(gio-2.0)
|
||||||
BuildRequires: pkgconfig(gio-unix-2.0)
|
BuildRequires: pkgconfig(gio-unix-2.0)
|
||||||
BuildRequires: pkgconfig(gthread-2.0)
|
BuildRequires: pkgconfig(gthread-2.0)
|
||||||
BuildRequires: pkgconfig(dbus-1)
|
BuildRequires: pkgconfig(dbus-1)
|
||||||
BuildRequires: pkgconfig(openssl)
|
BuildRequires: pkgconfig(gnutls)
|
||||||
BuildRequires: pkgconfig(alsa)
|
BuildRequires: pkgconfig(alsa)
|
||||||
BuildRequires: pkgconfig(protobuf)
|
BuildRequires: pkgconfig(protobuf)
|
||||||
BuildRequires: pkgconfig(sqlite3)
|
BuildRequires: pkgconfig(sqlite3)
|
||||||
|
|
|
@ -140,7 +140,7 @@ Section "Strawberry" Strawberry
|
||||||
File "libprotobuf-18.dll"
|
File "libprotobuf-18.dll"
|
||||||
File "libspeex-1.dll"
|
File "libspeex-1.dll"
|
||||||
File "libsqlite3-0.dll"
|
File "libsqlite3-0.dll"
|
||||||
File "libssl-1_1-x64.dll"
|
File "libssl-3-x64.dll"
|
||||||
File "libstdc++-6.dll"
|
File "libstdc++-6.dll"
|
||||||
File "libtag.dll"
|
File "libtag.dll"
|
||||||
File "libvorbis-0.dll"
|
File "libvorbis-0.dll"
|
||||||
|
@ -384,7 +384,7 @@ Section "Uninstall"
|
||||||
Delete "$INSTDIR\libprotobuf-18.dll"
|
Delete "$INSTDIR\libprotobuf-18.dll"
|
||||||
Delete "$INSTDIR\libspeex-1.dll"
|
Delete "$INSTDIR\libspeex-1.dll"
|
||||||
Delete "$INSTDIR\libsqlite3-0.dll"
|
Delete "$INSTDIR\libsqlite3-0.dll"
|
||||||
Delete "$INSTDIR\libssl-1_1-x64.dll"
|
Delete "$INSTDIR\libssl-3-x64.dll"
|
||||||
Delete "$INSTDIR\libstdc++-6.dll"
|
Delete "$INSTDIR\libstdc++-6.dll"
|
||||||
Delete "$INSTDIR\libtag.dll"
|
Delete "$INSTDIR\libtag.dll"
|
||||||
Delete "$INSTDIR\libvorbis-0.dll"
|
Delete "$INSTDIR\libvorbis-0.dll"
|
||||||
|
|
|
@ -140,7 +140,7 @@ Section "Strawberry" Strawberry
|
||||||
File "libprotobuf-18.dll"
|
File "libprotobuf-18.dll"
|
||||||
File "libspeex-1.dll"
|
File "libspeex-1.dll"
|
||||||
File "libsqlite3-0.dll"
|
File "libsqlite3-0.dll"
|
||||||
File "libssl-1_1.dll"
|
File "libssl-3.dll"
|
||||||
File "libstdc++-6.dll"
|
File "libstdc++-6.dll"
|
||||||
File "libtag.dll"
|
File "libtag.dll"
|
||||||
File "libvorbis-0.dll"
|
File "libvorbis-0.dll"
|
||||||
|
@ -384,7 +384,7 @@ Section "Uninstall"
|
||||||
Delete "$INSTDIR\libprotobuf-18.dll"
|
Delete "$INSTDIR\libprotobuf-18.dll"
|
||||||
Delete "$INSTDIR\libspeex-1.dll"
|
Delete "$INSTDIR\libspeex-1.dll"
|
||||||
Delete "$INSTDIR\libsqlite3-0.dll"
|
Delete "$INSTDIR\libsqlite3-0.dll"
|
||||||
Delete "$INSTDIR\libssl-1_1.dll"
|
Delete "$INSTDIR\libssl-3.dll"
|
||||||
Delete "$INSTDIR\libstdc++-6.dll"
|
Delete "$INSTDIR\libstdc++-6.dll"
|
||||||
Delete "$INSTDIR\libtag.dll"
|
Delete "$INSTDIR\libtag.dll"
|
||||||
Delete "$INSTDIR\libvorbis-0.dll"
|
Delete "$INSTDIR\libvorbis-0.dll"
|
||||||
|
|
|
@ -140,7 +140,7 @@ Section "Strawberry" Strawberry
|
||||||
File "libprotobuf-18.dll"
|
File "libprotobuf-18.dll"
|
||||||
File "libspeex-1.dll"
|
File "libspeex-1.dll"
|
||||||
File "libsqlite3-0.dll"
|
File "libsqlite3-0.dll"
|
||||||
File "libssl-1_1-x64.dll"
|
File "libssl-3-x64.dll"
|
||||||
File "libstdc++-6.dll"
|
File "libstdc++-6.dll"
|
||||||
File "libtag.dll"
|
File "libtag.dll"
|
||||||
File "libvorbis-0.dll"
|
File "libvorbis-0.dll"
|
||||||
|
@ -352,7 +352,7 @@ Section "Uninstall"
|
||||||
Delete "$INSTDIR\libprotobuf-18.dll"
|
Delete "$INSTDIR\libprotobuf-18.dll"
|
||||||
Delete "$INSTDIR\libspeex-1.dll"
|
Delete "$INSTDIR\libspeex-1.dll"
|
||||||
Delete "$INSTDIR\libsqlite3-0.dll"
|
Delete "$INSTDIR\libsqlite3-0.dll"
|
||||||
Delete "$INSTDIR\libssl-1_1-x64.dll"
|
Delete "$INSTDIR\libssl-3-x64.dll"
|
||||||
Delete "$INSTDIR\libstdc++-6.dll"
|
Delete "$INSTDIR\libstdc++-6.dll"
|
||||||
Delete "$INSTDIR\libtag.dll"
|
Delete "$INSTDIR\libtag.dll"
|
||||||
Delete "$INSTDIR\libvorbis-0.dll"
|
Delete "$INSTDIR\libvorbis-0.dll"
|
||||||
|
|
|
@ -140,7 +140,7 @@ Section "Strawberry" Strawberry
|
||||||
File "libprotobuf-18.dll"
|
File "libprotobuf-18.dll"
|
||||||
File "libspeex-1.dll"
|
File "libspeex-1.dll"
|
||||||
File "libsqlite3-0.dll"
|
File "libsqlite3-0.dll"
|
||||||
File "libssl-1_1.dll"
|
File "libssl-3.dll"
|
||||||
File "libstdc++-6.dll"
|
File "libstdc++-6.dll"
|
||||||
File "libtag.dll"
|
File "libtag.dll"
|
||||||
File "libvorbis-0.dll"
|
File "libvorbis-0.dll"
|
||||||
|
@ -352,7 +352,7 @@ Section "Uninstall"
|
||||||
Delete "$INSTDIR\libprotobuf-18.dll"
|
Delete "$INSTDIR\libprotobuf-18.dll"
|
||||||
Delete "$INSTDIR\libspeex-1.dll"
|
Delete "$INSTDIR\libspeex-1.dll"
|
||||||
Delete "$INSTDIR\libsqlite3-0.dll"
|
Delete "$INSTDIR\libsqlite3-0.dll"
|
||||||
Delete "$INSTDIR\libssl-1_1.dll"
|
Delete "$INSTDIR\libssl-3.dll"
|
||||||
Delete "$INSTDIR\libstdc++-6.dll"
|
Delete "$INSTDIR\libstdc++-6.dll"
|
||||||
Delete "$INSTDIR\libtag.dll"
|
Delete "$INSTDIR\libtag.dll"
|
||||||
Delete "$INSTDIR\libvorbis-0.dll"
|
Delete "$INSTDIR\libvorbis-0.dll"
|
||||||
|
|
|
@ -84,7 +84,7 @@ parts:
|
||||||
- g++
|
- g++
|
||||||
- protobuf-compiler
|
- protobuf-compiler
|
||||||
- libglib2.0-dev
|
- libglib2.0-dev
|
||||||
- libssl-dev
|
- libgnutls28-dev
|
||||||
- libdbus-1-dev
|
- libdbus-1-dev
|
||||||
- libprotobuf-dev
|
- libprotobuf-dev
|
||||||
- libboost-dev
|
- libboost-dev
|
||||||
|
|
|
@ -43,7 +43,7 @@ include_directories(${CMAKE_BINARY_DIR})
|
||||||
include_directories(${GLIB_INCLUDE_DIRS})
|
include_directories(${GLIB_INCLUDE_DIRS})
|
||||||
include_directories(${GLIBCONFIG_INCLUDE_DIRS})
|
include_directories(${GLIBCONFIG_INCLUDE_DIRS})
|
||||||
include_directories(${GOBJECT_INCLUDE_DIRS})
|
include_directories(${GOBJECT_INCLUDE_DIRS})
|
||||||
include_directories(${OPENSSL_INCLUDE_DIR})
|
include_directories(${GNUTLS_INCLUDE_DIR})
|
||||||
include_directories(${Boost_INCLUDE_DIRS})
|
include_directories(${Boost_INCLUDE_DIRS})
|
||||||
include_directories(${LIBXML_INCLUDE_DIRS})
|
include_directories(${LIBXML_INCLUDE_DIRS})
|
||||||
include_directories(${CHROMAPRINT_INCLUDE_DIRS})
|
include_directories(${CHROMAPRINT_INCLUDE_DIRS})
|
||||||
|
@ -934,7 +934,7 @@ target_link_libraries(strawberry_lib
|
||||||
${GLIB_LIBRARIES}
|
${GLIB_LIBRARIES}
|
||||||
${GIO_LIBRARIES}
|
${GIO_LIBRARIES}
|
||||||
${GOBJECT_LIBRARIES}
|
${GOBJECT_LIBRARIES}
|
||||||
${OPENSSL_LIBRARIES}
|
${GNUTLS_LIBRARIES}
|
||||||
${QT_LIBRARIES}
|
${QT_LIBRARIES}
|
||||||
${CHROMAPRINT_LIBRARIES}
|
${CHROMAPRINT_LIBRARIES}
|
||||||
${SQLITE_LIBRARIES}
|
${SQLITE_LIBRARIES}
|
||||||
|
|
|
@ -21,10 +21,9 @@
|
||||||
|
|
||||||
#include "localredirectserver.h"
|
#include "localredirectserver.h"
|
||||||
|
|
||||||
#include <openssl/evp.h>
|
#include <gnutls/gnutls.h>
|
||||||
#include <openssl/rsa.h>
|
#include <gnutls/x509.h>
|
||||||
#include <openssl/x509.h>
|
#include <gnutls/abstract.h>
|
||||||
#include <openssl/pem.h>
|
|
||||||
|
|
||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
#include <QIODevice>
|
#include <QIODevice>
|
||||||
|
@ -42,6 +41,7 @@
|
||||||
#include <QByteArray>
|
#include <QByteArray>
|
||||||
#include <QString>
|
#include <QString>
|
||||||
#include <QUrl>
|
#include <QUrl>
|
||||||
|
#include <QDateTime>
|
||||||
|
|
||||||
#include "core/logging.h"
|
#include "core/logging.h"
|
||||||
#include "core/closure.h"
|
#include "core/closure.h"
|
||||||
|
@ -56,79 +56,124 @@ LocalRedirectServer::~LocalRedirectServer() {}
|
||||||
|
|
||||||
bool LocalRedirectServer::GenerateCertificate() {
|
bool LocalRedirectServer::GenerateCertificate() {
|
||||||
|
|
||||||
EVP_PKEY *pkey = EVP_PKEY_new();
|
gnutls_global_init();
|
||||||
q_check_ptr(pkey);
|
|
||||||
|
|
||||||
RSA *rsa = RSA_generate_key(2048, RSA_F4, nullptr, nullptr);
|
gnutls_x509_privkey_t key;
|
||||||
q_check_ptr(rsa);
|
gnutls_x509_privkey_init(&key);
|
||||||
|
|
||||||
EVP_PKEY_assign_RSA(pkey, rsa);
|
unsigned int bits = gnutls_sec_param_to_pk_bits(GNUTLS_PK_RSA, GNUTLS_SEC_PARAM_MEDIUM);
|
||||||
|
gnutls_x509_privkey_generate(key, GNUTLS_PK_RSA, bits, 0);
|
||||||
|
|
||||||
X509 *x509 = X509_new();
|
char buffer[4096] = "";
|
||||||
q_check_ptr(x509);
|
size_t buffer_size = sizeof(buffer);
|
||||||
|
gnutls_x509_privkey_export(key, GNUTLS_X509_FMT_PEM, buffer, &buffer_size);
|
||||||
|
|
||||||
ASN1_INTEGER_set(X509_get_serialNumber(x509), static_cast<uint64_t>(9999999 + qrand() % 1000000));
|
QSslKey ssl_key(QByteArray(buffer, buffer_size), QSsl::Rsa);
|
||||||
|
|
||||||
X509_gmtime_adj(X509_get_notBefore(x509), 0);
|
|
||||||
X509_gmtime_adj(X509_get_notAfter(x509), 31536000L);
|
|
||||||
X509_set_pubkey(x509, pkey);
|
|
||||||
|
|
||||||
X509_NAME *name = X509_get_subject_name(x509);
|
|
||||||
q_check_ptr(name);
|
|
||||||
|
|
||||||
X509_NAME_add_entry_by_txt(name, "C", MBSTRING_ASC, (unsigned char *) "US", -1, -1, 0);
|
|
||||||
X509_NAME_add_entry_by_txt(name, "O", MBSTRING_ASC, (unsigned char *) "Strawberry Music Player", -1, -1, 0);
|
|
||||||
X509_NAME_add_entry_by_txt(name, "CN", MBSTRING_ASC, (unsigned char *) "localhost", -1, -1, 0);
|
|
||||||
X509_set_issuer_name(x509, name);
|
|
||||||
X509_sign(x509, pkey, EVP_sha1());
|
|
||||||
|
|
||||||
BIO *bp_private = BIO_new(BIO_s_mem());
|
|
||||||
q_check_ptr(bp_private);
|
|
||||||
|
|
||||||
if (PEM_write_bio_PrivateKey(bp_private, pkey, nullptr, nullptr, 0, nullptr, nullptr) != 1) {
|
|
||||||
EVP_PKEY_free(pkey);
|
|
||||||
X509_free(x509);
|
|
||||||
BIO_free_all(bp_private);
|
|
||||||
error_ = "PEM_write_bio_PrivateKey() failed.";
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
BIO *bp_public = BIO_new(BIO_s_mem());
|
|
||||||
q_check_ptr(bp_public);
|
|
||||||
|
|
||||||
if (PEM_write_bio_X509(bp_public, x509) != 1) {
|
|
||||||
EVP_PKEY_free(pkey);
|
|
||||||
X509_free(x509);
|
|
||||||
BIO_free_all(bp_public);
|
|
||||||
BIO_free_all(bp_private);
|
|
||||||
error_ = "PEM_write_bio_X509() failed.";
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
const char *buffer;
|
|
||||||
|
|
||||||
long size = BIO_get_mem_data(bp_public, &buffer);
|
|
||||||
q_check_ptr(buffer);
|
|
||||||
|
|
||||||
QSslCertificate ssl_certificate(QByteArray(buffer, size));
|
|
||||||
if (ssl_certificate.isNull()) {
|
|
||||||
error_ = "Failed to generate a random client certificate.";
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
size = BIO_get_mem_data(bp_private, &buffer);
|
|
||||||
q_check_ptr(buffer);
|
|
||||||
|
|
||||||
QSslKey ssl_key(QByteArray(buffer, size), QSsl::Rsa);
|
|
||||||
if (ssl_key.isNull()) {
|
if (ssl_key.isNull()) {
|
||||||
error_ = "Failed to generate a random private key.";
|
error_ = "Failed to generate a random private key.";
|
||||||
|
gnutls_x509_privkey_deinit(key);
|
||||||
|
gnutls_global_deinit();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
EVP_PKEY_free(pkey);
|
gnutls_x509_crt_t crt;
|
||||||
X509_free(x509);
|
if (gnutls_x509_crt_init(&crt) != GNUTLS_E_SUCCESS) {
|
||||||
BIO_free_all(bp_public);
|
error_ = "gnutls_x509_crt_init failed.";
|
||||||
BIO_free_all(bp_private);
|
gnutls_x509_privkey_deinit(key);
|
||||||
|
gnutls_global_deinit();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (gnutls_x509_crt_set_version(crt, 1) != GNUTLS_E_SUCCESS) {
|
||||||
|
error_ = "gnutls_x509_crt_set_version failed.";
|
||||||
|
gnutls_x509_privkey_deinit(key);
|
||||||
|
gnutls_x509_crt_deinit(crt);
|
||||||
|
gnutls_global_deinit();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (gnutls_x509_crt_set_dn_by_oid(crt, GNUTLS_OID_X520_COUNTRY_NAME, 0, "US", 2) != GNUTLS_E_SUCCESS) {
|
||||||
|
error_ = "gnutls_x509_crt_set_dn_by_oid failed.";
|
||||||
|
gnutls_x509_privkey_deinit(key);
|
||||||
|
gnutls_x509_crt_deinit(crt);
|
||||||
|
gnutls_global_deinit();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (gnutls_x509_crt_set_dn_by_oid(crt, GNUTLS_OID_X520_ORGANIZATION_NAME, 0, "Strawberry Music Player", strlen("Strawberry Music Player")) != GNUTLS_E_SUCCESS) {
|
||||||
|
error_ = "gnutls_x509_crt_set_dn_by_oid failed.";
|
||||||
|
gnutls_x509_privkey_deinit(key);
|
||||||
|
gnutls_x509_crt_deinit(crt);
|
||||||
|
gnutls_global_deinit();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (gnutls_x509_crt_set_dn_by_oid(crt, GNUTLS_OID_X520_COMMON_NAME, 0, "localhost", strlen("localhost")) != GNUTLS_E_SUCCESS) {
|
||||||
|
error_ = "gnutls_x509_crt_set_dn_by_oid failed.";
|
||||||
|
gnutls_x509_privkey_deinit(key);
|
||||||
|
gnutls_x509_crt_deinit(crt);
|
||||||
|
gnutls_global_deinit();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (gnutls_x509_crt_set_key(crt, key) != GNUTLS_E_SUCCESS) {
|
||||||
|
error_ = "gnutls_x509_crt_set_key failed.";
|
||||||
|
gnutls_x509_privkey_deinit(key);
|
||||||
|
gnutls_x509_crt_deinit(crt);
|
||||||
|
gnutls_global_deinit();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
quint64 time = QDateTime::currentDateTime().toTime_t();
|
||||||
|
gnutls_x509_crt_set_activation_time(crt, time);
|
||||||
|
if (gnutls_x509_crt_set_expiration_time(crt, time + 31536000L) != GNUTLS_E_SUCCESS) {
|
||||||
|
error_ = "gnutls_x509_crt_set_expiration_time failed.";
|
||||||
|
gnutls_x509_privkey_deinit(key);
|
||||||
|
gnutls_x509_crt_deinit(crt);
|
||||||
|
gnutls_global_deinit();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
quint64 serial = (9999999 + qrand() % 1000000);
|
||||||
|
QByteArray q_serial;
|
||||||
|
q_serial.setNum(serial);
|
||||||
|
|
||||||
|
if (gnutls_x509_crt_set_serial (crt, q_serial.constData(), sizeof(q_serial.size())) != GNUTLS_E_SUCCESS) {
|
||||||
|
error_ = "gnutls_x509_crt_set_serial failed.";
|
||||||
|
gnutls_x509_privkey_deinit(key);
|
||||||
|
gnutls_x509_crt_deinit(crt);
|
||||||
|
gnutls_global_deinit();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
gnutls_privkey_t pkey;
|
||||||
|
gnutls_privkey_init(&pkey);
|
||||||
|
gnutls_privkey_import_x509(pkey, key, 0);
|
||||||
|
gnutls_x509_crt_privkey_sign(crt, crt, pkey, GNUTLS_DIG_SHA256, 0);
|
||||||
|
|
||||||
|
if (gnutls_x509_crt_sign2(crt, crt, key, GNUTLS_DIG_SHA256, 0) != GNUTLS_E_SUCCESS) {
|
||||||
|
error_ = "gnutls_x509_crt_sign2 failed.";
|
||||||
|
gnutls_x509_privkey_deinit(key);
|
||||||
|
gnutls_x509_crt_deinit(crt);
|
||||||
|
gnutls_privkey_deinit(pkey);
|
||||||
|
gnutls_global_deinit();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (gnutls_x509_crt_export(crt, GNUTLS_X509_FMT_PEM, buffer, &buffer_size) != GNUTLS_E_SUCCESS) {
|
||||||
|
error_ = "gnutls_x509_crt_export failed.";
|
||||||
|
gnutls_x509_privkey_deinit(key);
|
||||||
|
gnutls_x509_crt_deinit(crt);
|
||||||
|
gnutls_privkey_deinit(pkey);
|
||||||
|
gnutls_global_deinit();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
gnutls_x509_crt_deinit(crt);
|
||||||
|
gnutls_x509_privkey_deinit(key);
|
||||||
|
gnutls_privkey_deinit(pkey);
|
||||||
|
|
||||||
|
QSslCertificate ssl_certificate(QByteArray(buffer, buffer_size));
|
||||||
|
if (ssl_certificate.isNull()) {
|
||||||
|
error_ = "Failed to generate a random client certificate.";
|
||||||
|
gnutls_global_deinit();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
gnutls_global_deinit();
|
||||||
|
|
||||||
ssl_certificate_ = ssl_certificate;
|
ssl_certificate_ = ssl_certificate;
|
||||||
ssl_key_ = ssl_key;
|
ssl_key_ = ssl_key;
|
||||||
|
@ -179,6 +224,7 @@ void LocalRedirectServer::incomingConnection(qintptr socket_descriptor) {
|
||||||
QSslSocket *ssl_socket = new QSslSocket(this);
|
QSslSocket *ssl_socket = new QSslSocket(this);
|
||||||
if (!ssl_socket->setSocketDescriptor(socket_descriptor)) {
|
if (!ssl_socket->setSocketDescriptor(socket_descriptor)) {
|
||||||
delete ssl_socket;
|
delete ssl_socket;
|
||||||
|
close();
|
||||||
error_ = "Unable to set socket descriptor";
|
error_ = "Unable to set socket descriptor";
|
||||||
emit Finished();
|
emit Finished();
|
||||||
return;
|
return;
|
||||||
|
@ -190,7 +236,7 @@ void LocalRedirectServer::incomingConnection(qintptr socket_descriptor) {
|
||||||
ssl_socket->startServerEncryption();
|
ssl_socket->startServerEncryption();
|
||||||
|
|
||||||
connect(ssl_socket, SIGNAL(sslErrors(QList<QSslError>)), this, SLOT(SSLErrors(QList<QSslError>)));
|
connect(ssl_socket, SIGNAL(sslErrors(QList<QSslError>)), this, SLOT(SSLErrors(QList<QSslError>)));
|
||||||
connect(ssl_socket, SIGNAL(encrypted()), this, SLOT(Encrypted(QSslSocket*)));
|
connect(ssl_socket, SIGNAL(encrypted()), this, SLOT(Encrypted()));
|
||||||
|
|
||||||
socket_ = ssl_socket;
|
socket_ = ssl_socket;
|
||||||
}
|
}
|
||||||
|
@ -198,6 +244,7 @@ void LocalRedirectServer::incomingConnection(qintptr socket_descriptor) {
|
||||||
QTcpSocket *tcp_socket = new QTcpSocket(this);
|
QTcpSocket *tcp_socket = new QTcpSocket(this);
|
||||||
if (!tcp_socket->setSocketDescriptor(socket_descriptor)) {
|
if (!tcp_socket->setSocketDescriptor(socket_descriptor)) {
|
||||||
delete tcp_socket;
|
delete tcp_socket;
|
||||||
|
close();
|
||||||
error_ = "Unable to set socket descriptor";
|
error_ = "Unable to set socket descriptor";
|
||||||
emit Finished();
|
emit Finished();
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -46,7 +46,7 @@ class LocalRedirectServer : public QTcpServer {
|
||||||
const QString &error() const { return error_; }
|
const QString &error() const { return error_; }
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void Finished(QString error = QString());
|
void Finished();
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void NewConnection();
|
void NewConnection();
|
||||||
|
|
|
@ -123,8 +123,6 @@ void ListenBrainzScrobbler::Logout() {
|
||||||
|
|
||||||
void ListenBrainzScrobbler::Authenticate(const bool https) {
|
void ListenBrainzScrobbler::Authenticate(const bool https) {
|
||||||
|
|
||||||
QUrl url(kAuthUrl);
|
|
||||||
|
|
||||||
LocalRedirectServer *server = new LocalRedirectServer(https, this);
|
LocalRedirectServer *server = new LocalRedirectServer(https, this);
|
||||||
if (!server->Listen()) {
|
if (!server->Listen()) {
|
||||||
AuthError(server->error());
|
AuthError(server->error());
|
||||||
|
@ -141,6 +139,7 @@ void ListenBrainzScrobbler::Authenticate(const bool https) {
|
||||||
url_query.addQueryItem("client_id", kClientID);
|
url_query.addQueryItem("client_id", kClientID);
|
||||||
url_query.addQueryItem("redirect_uri", redirect_url.toString());
|
url_query.addQueryItem("redirect_uri", redirect_url.toString());
|
||||||
url_query.addQueryItem("scope", "profile;email;tag;rating;collection;submit_isrc;submit_barcode");
|
url_query.addQueryItem("scope", "profile;email;tag;rating;collection;submit_isrc;submit_barcode");
|
||||||
|
QUrl url(kAuthUrl);
|
||||||
url.setQuery(url_query);
|
url.setQuery(url_query);
|
||||||
|
|
||||||
bool result = QDesktopServices::openUrl(url);
|
bool result = QDesktopServices::openUrl(url);
|
||||||
|
|
|
@ -116,26 +116,25 @@ void ScrobblingAPI20::Logout() {
|
||||||
|
|
||||||
void ScrobblingAPI20::Authenticate(const bool https) {
|
void ScrobblingAPI20::Authenticate(const bool https) {
|
||||||
|
|
||||||
QUrl url(auth_url_);
|
|
||||||
|
|
||||||
LocalRedirectServer *server = new LocalRedirectServer(https, this);
|
LocalRedirectServer *server = new LocalRedirectServer(https, this);
|
||||||
if (!server->Listen()) {
|
if (!server->Listen()) {
|
||||||
AuthError(server->error());
|
AuthError(server->error());
|
||||||
delete server;
|
delete server;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
NewClosure(server, SIGNAL(Finished(QString)), this, &ScrobblingAPI20::RedirectArrived, server);
|
NewClosure(server, SIGNAL(Finished()), this, &ScrobblingAPI20::RedirectArrived, server);
|
||||||
|
|
||||||
QUrl redirect_url(kRedirectUrl);
|
|
||||||
QUrlQuery redirect_url_query;
|
QUrlQuery redirect_url_query;
|
||||||
const QString port = QString::number(server->url().port());
|
const QString port = QString::number(server->url().port());
|
||||||
redirect_url_query.addQueryItem("port", port);
|
redirect_url_query.addQueryItem("port", port);
|
||||||
|
if (https) redirect_url_query.addQueryItem("https", QString("1"));
|
||||||
|
QUrl redirect_url(kRedirectUrl);
|
||||||
redirect_url.setQuery(redirect_url_query);
|
redirect_url.setQuery(redirect_url_query);
|
||||||
|
|
||||||
QUrlQuery url_query;
|
QUrlQuery url_query;
|
||||||
url_query.addQueryItem("api_key", kApiKey);
|
url_query.addQueryItem("api_key", kApiKey);
|
||||||
url_query.addQueryItem("cb", QUrl::toPercentEncoding(redirect_url.toString()));
|
url_query.addQueryItem("cb", redirect_url.toString());
|
||||||
qLog(Debug) << QUrl::toPercentEncoding(redirect_url.toString());
|
QUrl url(auth_url_);
|
||||||
url.setQuery(url_query);
|
url.setQuery(url_query);
|
||||||
|
|
||||||
QMessageBox messagebox(QMessageBox::Information, tr("%1 Scrobbler Authentication").arg(name_), tr("Open URL in web browser?<br /><a href=\"%1\">%1</a><br />Press \"Save\" to copy the URL to clipboard and manually open it in a web browser.").arg(url.toString()), QMessageBox::Open|QMessageBox::Save|QMessageBox::Cancel);
|
QMessageBox messagebox(QMessageBox::Information, tr("%1 Scrobbler Authentication").arg(name_), tr("Open URL in web browser?<br /><a href=\"%1\">%1</a><br />Press \"Save\" to copy the URL to clipboard and manually open it in a web browser.").arg(url.toString()), QMessageBox::Open|QMessageBox::Save|QMessageBox::Cancel);
|
||||||
|
@ -169,9 +168,14 @@ void ScrobblingAPI20::RedirectArrived(LocalRedirectServer *server) {
|
||||||
|
|
||||||
server->deleteLater();
|
server->deleteLater();
|
||||||
|
|
||||||
|
if (!server->error().isEmpty()) {
|
||||||
|
AuthError(server->error());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
QUrl url = server->request_url();
|
QUrl url = server->request_url();
|
||||||
if (!url.isValid()) {
|
if (!url.isValid()) {
|
||||||
AuthError(tr("Invalid reply from web browser. Try using Chromium or Chrome instead."));
|
AuthError(tr("Received invalid reply from web browser. Try the HTTPS option, or use another browser like Chromium or Chrome."));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
QUrlQuery url_query(url);
|
QUrlQuery url_query(url);
|
||||||
|
|
Loading…
Reference in New Issue