-
-
Notifications
You must be signed in to change notification settings - Fork 1.8k
feat: add encryption option for broadcasting #13285
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
base: main
Are you sure you want to change the base?
Changes from 4 commits
97e721c
8bef931
823ab0e
968b505
952b84d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -88,16 +88,6 @@ ShoutConnection::ShoutConnection(BroadcastProfilePtr profile, | |
| errorDialog(tr("Error setting non-blocking mode:"), | ||
| shout_get_error(m_pShout)); | ||
| } | ||
|
|
||
| #ifdef SHOUT_TLS | ||
| // Libshout defaults to SHOUT_TLS_AUTO if build with SHOUT_TLS | ||
| // Sometimes autodetection fails, resulting into no metadata send | ||
| // https://github.com/mixxxdj/mixxx/issues/9599 | ||
| if (shout_set_tls(m_pShout, SHOUT_TLS_DISABLED) != SHOUTERR_SUCCESS) { | ||
| errorDialog(tr("Error setting tls mode:"), | ||
| shout_get_error(m_pShout)); | ||
| } | ||
| #endif | ||
| } | ||
|
|
||
| ShoutConnection::~ShoutConnection() { | ||
|
|
@@ -237,6 +227,24 @@ void ShoutConnection::updateFromPreferences() { | |
| serverUrl.setUserName(login); | ||
| } | ||
|
|
||
| #ifdef SHOUT_TLS | ||
| BroadcastProfile::EncryptionMode encryptionMode = m_pProfile->getEncryptionMode(); | ||
|
|
||
| int result; | ||
| switch (encryptionMode) { | ||
| case BroadcastProfile::EncryptionMode::Disabled: | ||
| result = shout_set_tls(m_pShout, SHOUT_TLS_DISABLED); | ||
| break; | ||
| default: // Required | ||
| result = shout_set_tls(m_pShout, SHOUT_TLS_AUTO_NO_PLAIN); | ||
| break; | ||
| } | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We have these values: Since
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is it still broken? It seems to be working fine on 2.4.6. Explicit mode works well as well, but it require the user to know which RFC/implementation the server is using (startTLS vs full TLS), which depends of how the broadcast server is configured. Reading #8301, I don't think we want the user to have to know/care about this level of details During my test, I tried edge/ingress level TLS (RFC2818), and container level (RFC2817), explicit option worked well as long as you picked the right one. Auto was able to detect the right setup nicely.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @daschuer Are you sure, that this is still broken in 2.4.6 ?
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't have tested this. We can merge this PR once we have version guards for 2.4.6.
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There is no regression risk in this PR. Only risk is for a user to experience regression when enabling TLS, but they have the option to get back to TLS being explicitly disabled. Are you asking to force user with <2.4.6 to stay stuck with TLS disabled?
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Also #13285 (comment) |
||
| if (result != SHOUTERR_SUCCESS) { | ||
| errorDialog(tr("Error setting TLS mode:"), | ||
| shout_get_error(m_pShout)); | ||
| } | ||
| #endif | ||
|
|
||
| kLogger.debug() << "Using server URL:" << serverUrl; | ||
|
|
||
| QByteArray baPassword = m_pProfile->getPassword().toLatin1(); | ||
|
|
@@ -603,6 +611,29 @@ bool ShoutConnection::processConnect() { | |
| kLogger.warning() | ||
| << "processConnect() socket error." | ||
| << "Is socket already in use?"; | ||
| } else if (m_iShoutStatus == SHOUTERR_NOLOGIN) { | ||
| m_lastErrorStr = "Invalid login details"; | ||
| kLogger.warning() | ||
| << "processConnect() failed with no invalid or missing login details:" | ||
| << m_iShoutStatus << shout_get_error(m_pShout); | ||
| #ifdef SHOUT_TLS | ||
| } else if (m_iShoutStatus == SHOUTERR_NOTLS) { | ||
| DEBUG_ASSERT(m_pProfile && | ||
| m_pProfile->getEncryptionMode() == | ||
| BroadcastProfile::EncryptionMode::Required); | ||
| m_lastErrorStr = "The server doesn't not provide the required TLS encryption"; | ||
| kLogger.warning() | ||
| << "processConnect() failed with no valid TLS:" | ||
| << m_iShoutStatus << shout_get_error(m_pShout); | ||
| } else if (m_iShoutStatus == SHOUTERR_TLSBADCERT) { | ||
| DEBUG_ASSERT(m_pProfile && | ||
| m_pProfile->getEncryptionMode() != | ||
| BroadcastProfile::EncryptionMode::Disabled); | ||
| m_lastErrorStr = "The server TLS certificate couldn't be verified"; | ||
| kLogger.warning() | ||
| << "processConnect() failed with a bad TLS certificate:" | ||
| << m_iShoutStatus << shout_get_error(m_pShout); | ||
| #endif | ||
| } else if (timeout >= kConnectRetries) { | ||
| // Not translated, because shout_get_error() returns also English only | ||
| m_lastErrorStr = QStringLiteral("Connection establishment time-out"); | ||
|
|
@@ -987,7 +1018,7 @@ void ShoutConnection::run() { | |
| errorDialog(tr("Can't connect to streaming server"), | ||
| m_lastErrorStr + "\n\n" + | ||
| tr("Please check your connection to the Internet and " | ||
| "verify that your username and password are " | ||
| "verify that your username, password and encryption mode are " | ||
| "correct.")); | ||
| return; | ||
| } | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -56,6 +56,7 @@ constexpr const char* kProfileName = "ProfileName"; | |
| constexpr const char* kReconnectFirstDelay = "ReconnectFirstDelay"; | ||
| constexpr const char* kReconnectPeriod = "ReconnectPeriod"; | ||
| constexpr const char* kServertype = "Servertype"; | ||
| constexpr const char* kEncryptionMode = "EncryptionMode"; | ||
| constexpr const char* kStreamDesc = "StreamDesc"; | ||
| constexpr const char* kStreamGenre = "StreamGenre"; | ||
| constexpr const char* kStreamName = "StreamName"; | ||
|
|
@@ -241,6 +242,7 @@ void BroadcastProfile::copyValuesTo(BroadcastProfilePtr other) { | |
| other->setServertype(this->getServertype()); | ||
| other->setLogin(this->getLogin()); | ||
| other->setPassword(this->getPassword()); | ||
| other->setEncryptionMode(this->getEncryptionMode()); | ||
|
|
||
| other->setEnableReconnect(this->getEnableReconnect()); | ||
| other->setReconnectPeriod(this->getReconnectPeriod()); | ||
|
|
@@ -277,6 +279,7 @@ void BroadcastProfile::copyValuesTo(BroadcastProfilePtr other) { | |
|
|
||
| void BroadcastProfile::adoptDefaultValues() { | ||
| m_secureCredentials = false; | ||
| m_encryptionMode = EncryptionMode::Required; | ||
| m_enabled = false; | ||
|
|
||
| m_host = QString(); | ||
|
|
@@ -348,6 +351,13 @@ bool BroadcastProfile::loadValues(const QString& filename) { | |
| m_host = selectCleanNodeString(doc, kHost, &fixedStrings); | ||
| m_port = XmlParse::selectNodeInt(doc, kPort); | ||
| m_serverType = selectCleanNodeString(doc, kServertype, &fixedStrings); | ||
| switch (static_cast<EncryptionMode>(XmlParse::selectNodeInt(doc, kEncryptionMode))) { | ||
| case EncryptionMode::Required: | ||
| m_encryptionMode = EncryptionMode::Required; | ||
| break; | ||
| default: | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What is the migration path? I think we should keep "Disabled" after upgrade. We may consider to keep the "not set" state that we have the chance to ask the user in pop up box in a later PR (or in this if you like)
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think that's a fair approach, not sure how to deal with the prompt tho. Do we want to consider adding a
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't mind, my idea was to just check if this new option exists or not.
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Updated - the migration path will now default to disable, which is the current behaviour as we don't support TLS in 2.6 |
||
| m_encryptionMode = EncryptionMode::Disabled; | ||
| } | ||
|
|
||
| m_login = selectCleanNodeString(doc, kLogin, &fixedStrings); | ||
| if (m_secureCredentials) { | ||
|
|
@@ -433,6 +443,10 @@ bool BroadcastProfile::save(const QString& filename) { | |
| XmlParse::addElement(doc, docRoot, kHost, m_host); | ||
| XmlParse::addElement(doc, docRoot, kPort, QString::number(m_port)); | ||
| XmlParse::addElement(doc, docRoot, kServertype, m_serverType); | ||
| XmlParse::addElement(doc, | ||
| docRoot, | ||
| kEncryptionMode, | ||
| QString::number(static_cast<int>(m_encryptionMode))); | ||
|
|
||
| XmlParse::addElement(doc, docRoot, kLogin, m_login); | ||
| if (m_secureCredentials) { | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -7,7 +7,7 @@ | |
| <x>0</x> | ||
| <y>0</y> | ||
| <width>715</width> | ||
| <height>1012</height> | ||
| <height>1248</height> | ||
| </rect> | ||
| </property> | ||
| <property name="windowTitle"> | ||
|
|
@@ -158,7 +158,16 @@ | |
| <item> | ||
| <widget class="QWidget" name="widgetReconnectControls" native="true"> | ||
| <layout class="QGridLayout" name="gridLayout_5"> | ||
| <property name="margin"> | ||
| <property name="leftMargin"> | ||
| <number>0</number> | ||
| </property> | ||
| <property name="topMargin"> | ||
| <number>0</number> | ||
| </property> | ||
| <property name="rightMargin"> | ||
| <number>0</number> | ||
| </property> | ||
| <property name="bottomMargin"> | ||
| <number>0</number> | ||
| </property> | ||
| <item row="0" column="0"> | ||
|
|
@@ -598,9 +607,9 @@ | |
| <string notr="true"><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> | ||
| <html><head><meta name="qrichtext" content="1" /><style type="text/css"> | ||
| p, li { white-space: pre-wrap; } | ||
| </style></head><body style=" font-family:'.SF NS Text'; font-size:13pt; font-weight:400; font-style:normal;"> | ||
| <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Ubuntu'; font-size:10pt;"> </span></p> | ||
| <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Lucida Grande';"><br /></p></body></html></string> | ||
| </style></head><body style=" font-family:'Fira Sans Semi-Light'; font-size:10pt; font-weight:400; font-style:normal;"> | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This seems to be an unrelated change. |
||
| <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Ubuntu';"> </span></p> | ||
| <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Lucida Grande'; font-size:13pt;"><br /></p></body></html></string> | ||
| </property> | ||
| </widget> | ||
| </item> | ||
|
|
@@ -674,6 +683,26 @@ p, li { white-space: pre-wrap; } | |
| <string>Server connection</string> | ||
| </property> | ||
| <layout class="QGridLayout"> | ||
| <item row="3" column="0"> | ||
| <layout class="QHBoxLayout" name="horizontalLayout_3"> | ||
| <item> | ||
| <widget class="QLabel" name="label_21"> | ||
| <property name="sizePolicy"> | ||
| <sizepolicy hsizetype="Preferred" vsizetype="Preferred"> | ||
| <horstretch>0</horstretch> | ||
| <verstretch>0</verstretch> | ||
| </sizepolicy> | ||
| </property> | ||
| <property name="text"> | ||
| <string>Encryption</string> | ||
| </property> | ||
| </widget> | ||
| </item> | ||
| <item> | ||
| <widget class="QComboBox" name="encryptionModeComboBox"/> | ||
| </item> | ||
| </layout> | ||
| </item> | ||
| <item row="0" column="0"> | ||
| <layout class="QGridLayout" name="gridLayoutSC"> | ||
| <item row="0" column="0"> | ||
|
|
@@ -787,7 +816,16 @@ p, li { white-space: pre-wrap; } | |
| <item row="1" column="0"> | ||
| <widget class="QWidget" name="groupPasswordStorage" native="true"> | ||
| <layout class="QHBoxLayout" name="horizontalLayout_2"> | ||
| <property name="margin"> | ||
| <property name="leftMargin"> | ||
| <number>0</number> | ||
| </property> | ||
| <property name="topMargin"> | ||
| <number>0</number> | ||
| </property> | ||
| <property name="rightMargin"> | ||
| <number>0</number> | ||
| </property> | ||
| <property name="bottomMargin"> | ||
| <number>0</number> | ||
| </property> | ||
| <item> | ||
|
|
@@ -869,25 +907,21 @@ p, li { white-space: pre-wrap; } | |
| <tabstop>btnDisconnectAll</tabstop> | ||
| <tabstop>btnCreateConnection</tabstop> | ||
| <tabstop>connectOnApply</tabstop> | ||
|
|
||
| <tabstop>comboBoxServerType</tabstop> | ||
| <tabstop>mountpoint</tabstop> | ||
| <tabstop>host</tabstop> | ||
| <tabstop>port</tabstop> | ||
| <tabstop>login</tabstop> | ||
| <tabstop>password</tabstop> | ||
| <tabstop>rbPasswordCleartext</tabstop> | ||
|
|
||
| <tabstop>checkBoxEnableReconnect</tabstop> | ||
| <tabstop>spinBoxFirstDelay</tabstop> | ||
| <tabstop>spinBoxReconnectPeriod</tabstop> | ||
| <tabstop>checkBoxLimitReconnects</tabstop> | ||
| <tabstop>spinBoxMaximumRetries</tabstop> | ||
|
|
||
| <tabstop>comboBoxEncodingBitrate</tabstop> | ||
| <tabstop>comboBoxEncodingFormat</tabstop> | ||
| <tabstop>comboBoxEncodingChannels</tabstop> | ||
|
|
||
| <tabstop>stream_public</tabstop> | ||
| <tabstop>stream_name</tabstop> | ||
| <tabstop>stream_website</tabstop> | ||
|
|
@@ -896,7 +930,6 @@ p, li { white-space: pre-wrap; } | |
| <tabstop>stream_IRC</tabstop> | ||
| <tabstop>stream_AIM</tabstop> | ||
| <tabstop>stream_ICQ</tabstop> | ||
|
|
||
| <tabstop>metadata_format</tabstop> | ||
| <tabstop>enableCustomMetadata</tabstop> | ||
| <tabstop>custom_artist</tabstop> | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should keep the reference to the bug.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is still pending.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This comment is now irrelevant since we've agreed not to use
SHOUT_TLS_AUTO