secrets: merge branch 'elbs-unicon:fix_auth_retries'

https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/1381
This commit is contained in:
Thomas Haller 2022-10-25 09:07:27 +02:00
commit 11a34405ef
No known key found for this signature in database
GPG key ID: 29C2366E4DFC5728
14 changed files with 120 additions and 69 deletions

View file

@ -1172,8 +1172,10 @@ _con_get_try_complete_early(Request *req)
}
/* Do we have everything we need? */
if (NM_FLAGS_HAS(req->con.get.flags, NM_SECRET_AGENT_GET_SECRETS_FLAG_ONLY_SYSTEM)
|| ((nm_connection_need_secrets(tmp, NULL) == NULL)
&& !NM_FLAGS_HAS(req->con.get.flags, NM_SECRET_AGENT_GET_SECRETS_FLAG_REQUEST_NEW))) {
|| (NM_FLAGS_HAS(req->con.get.flags, NM_SECRET_AGENT_GET_SECRETS_FLAG_REQUEST_NEW)
&& !nm_connection_need_secrets_for_rerequest(tmp))
|| (!NM_FLAGS_HAS(req->con.get.flags, NM_SECRET_AGENT_GET_SECRETS_FLAG_REQUEST_NEW)
&& !nm_connection_need_secrets(tmp, NULL))) {
_LOGD(NULL, "(" LOG_REQ_FMT ") system settings secrets sufficient", LOG_REQ_ARG(req));
/* Got everything, we're done */

View file

@ -2333,6 +2333,45 @@ nm_connection_update_secrets(NMConnection *connection,
return success;
}
static const char *
_need_secrets(NMConnection *connection, gboolean check_rerequest, GPtrArray **hints)
{
NMSetting *setting_before = NULL;
NMConnectionPrivate *priv;
int i;
nm_assert(NM_IS_CONNECTION(connection));
nm_assert(!hints || !*hints);
priv = NM_CONNECTION_GET_PRIVATE(connection);
/* Get list of settings in priority order */
for (i = 0; i < (int) _NM_META_SETTING_TYPE_NUM; i++) {
NMSetting *setting = priv->settings[nm_meta_setting_types_by_priority[i]];
GPtrArray *secrets;
if (!setting)
continue;
nm_assert(!setting_before || _nm_setting_sort_for_nm_assert(setting_before, setting) < 0);
nm_assert(!setting_before || _nm_setting_compare_priority(setting_before, setting) <= 0);
setting_before = setting;
secrets = _nm_setting_need_secrets(setting, check_rerequest);
if (!secrets)
continue;
if (hints)
*hints = secrets;
else
g_ptr_array_free(secrets, TRUE);
return nm_setting_get_name(setting);
}
return NULL;
}
/**
* nm_connection_need_secrets:
* @connection: the #NMConnection
@ -2355,41 +2394,24 @@ nm_connection_update_secrets(NMConnection *connection,
const char *
nm_connection_need_secrets(NMConnection *connection, GPtrArray **hints)
{
NMSetting *setting_before = NULL;
NMConnectionPrivate *priv;
int i;
g_return_val_if_fail(NM_IS_CONNECTION(connection), NULL);
if (hints)
g_return_val_if_fail(*hints == NULL, NULL);
g_return_val_if_fail(!hints || !*hints, NULL);
priv = NM_CONNECTION_GET_PRIVATE(connection);
return _need_secrets(connection, FALSE, hints);
}
/* Get list of settings in priority order */
for (i = 0; i < (int) _NM_META_SETTING_TYPE_NUM; i++) {
NMSetting *setting = priv->settings[nm_meta_setting_types_by_priority[i]];
GPtrArray *secrets;
/**
* nm_connection_need_secrets_for_rerequest:
* @connection: the #NMConnection
*
* Returns TRUE if some secret needs to be re-requested
**/
gboolean
nm_connection_need_secrets_for_rerequest(NMConnection *connection)
{
g_return_val_if_fail(NM_IS_CONNECTION(connection), FALSE);
if (!setting)
continue;
nm_assert(!setting_before || _nm_setting_sort_for_nm_assert(setting_before, setting) < 0);
nm_assert(!setting_before || _nm_setting_compare_priority(setting_before, setting) <= 0);
setting_before = setting;
secrets = _nm_setting_need_secrets(setting);
if (!secrets)
continue;
if (hints)
*hints = secrets;
else
g_ptr_array_free(secrets, TRUE);
return nm_setting_get_name(setting);
}
return NULL;
return !!_need_secrets(connection, TRUE, NULL);
}
/**

View file

@ -67,7 +67,10 @@ _crypto_format_to_ck(NMCryptoFileFormat format)
/*****************************************************************************/
typedef void (*EAPMethodNeedSecretsFunc)(NMSetting8021x *self, GPtrArray *secrets, gboolean phase2);
typedef void (*EAPMethodNeedSecretsFunc)(NMSetting8021x *self,
GPtrArray *secrets,
gboolean phase2,
gboolean check_rerequest);
typedef gboolean (*EAPMethodValidateFunc)(NMSetting8021x *self, gboolean phase2, GError **error);
@ -2500,32 +2503,45 @@ nm_setting_802_1x_get_optional(NMSetting8021x *setting)
/*****************************************************************************/
static void
need_secrets_password(NMSetting8021x *self, GPtrArray *secrets, gboolean phase2)
need_secrets_password(NMSetting8021x *self,
GPtrArray *secrets,
gboolean phase2,
gboolean check_rerequest)
{
NMSetting8021xPrivate *priv = NM_SETTING_802_1X_GET_PRIVATE(self);
if (nm_str_is_empty(priv->password)
&& (!priv->password_raw || !g_bytes_get_size(priv->password_raw))) {
if (check_rerequest
|| (nm_str_is_empty(priv->password)
&& (!priv->password_raw || !g_bytes_get_size(priv->password_raw)))) {
g_ptr_array_add(secrets, NM_SETTING_802_1X_PASSWORD);
g_ptr_array_add(secrets, NM_SETTING_802_1X_PASSWORD_RAW);
}
}
static void
need_secrets_sim(NMSetting8021x *self, GPtrArray *secrets, gboolean phase2)
need_secrets_sim(NMSetting8021x *self,
GPtrArray *secrets,
gboolean phase2,
gboolean check_rerequest)
{
NMSetting8021xPrivate *priv = NM_SETTING_802_1X_GET_PRIVATE(self);
if (nm_str_is_empty(priv->pin))
if (check_rerequest || nm_str_is_empty(priv->pin))
g_ptr_array_add(secrets, NM_SETTING_802_1X_PIN);
}
static void
need_secrets_tls(NMSetting8021x *self, GPtrArray *secrets, gboolean phase2)
need_secrets_tls(NMSetting8021x *self,
GPtrArray *secrets,
gboolean phase2,
gboolean check_rerequest)
{
NMSetting8021xPrivate *priv = NM_SETTING_802_1X_GET_PRIVATE(self);
NMSetting8021xCKScheme scheme;
/* If check_rerequest is TRUE do not return secrets, unless missing.
* This secret cannot be wrong. */
if (!NM_FLAGS_HAS(phase2 ? priv->phase2_private_key_password_flags
: priv->private_key_password_flags,
NM_SETTING_SECRET_FLAG_NOT_REQUIRED)) {
@ -2719,7 +2735,10 @@ verify_ttls(NMSetting8021x *self, gboolean phase2, GError **error)
}
static void
need_secrets_phase2(NMSetting8021x *self, GPtrArray *secrets, gboolean phase2)
need_secrets_phase2(NMSetting8021x *self,
GPtrArray *secrets,
gboolean phase2,
gboolean check_rerequest)
{
NMSetting8021xPrivate *priv = NM_SETTING_802_1X_GET_PRIVATE(self);
char *method = NULL;
@ -2740,7 +2759,7 @@ need_secrets_phase2(NMSetting8021x *self, GPtrArray *secrets, gboolean phase2)
if (!eap_methods_table[i].ns_func)
continue;
if (nm_streq(eap_methods_table[i].method, method)) {
(*eap_methods_table[i].ns_func)(self, secrets, TRUE);
(*eap_methods_table[i].ns_func)(self, secrets, TRUE, check_rerequest);
break;
}
}
@ -3030,7 +3049,7 @@ verify(NMSetting *setting, NMConnection *connection, GError **error)
/*****************************************************************************/
static GPtrArray *
need_secrets(NMSetting *setting)
need_secrets(NMSetting *setting, gboolean check_rerequest)
{
NMSetting8021x *self = NM_SETTING_802_1X(setting);
NMSetting8021xPrivate *priv = NM_SETTING_802_1X_GET_PRIVATE(self);
@ -3049,7 +3068,7 @@ need_secrets(NMSetting *setting)
if (eap_methods_table[i].ns_func == NULL)
continue;
if (!strcmp(eap_methods_table[i].method, method)) {
(*eap_methods_table[i].ns_func)(self, secrets, FALSE);
(*eap_methods_table[i].ns_func)(self, secrets, FALSE, check_rerequest);
/* Only break out of the outer loop if this EAP method
* needed secrets.

View file

@ -225,12 +225,12 @@ verify_secrets(NMSetting *setting, NMConnection *connection, GError **error)
}
static GPtrArray *
need_secrets(NMSetting *setting)
need_secrets(NMSetting *setting, gboolean check_rerequest)
{
NMSettingAdslPrivate *priv = NM_SETTING_ADSL_GET_PRIVATE(setting);
GPtrArray *secrets = NULL;
if (priv->password && *priv->password)
if (!check_rerequest && priv->password && *priv->password)
return NULL;
if (!(priv->password_flags & NM_SETTING_SECRET_FLAG_NOT_REQUIRED)) {

View file

@ -174,12 +174,12 @@ verify_secrets(NMSetting *setting, NMConnection *connection, GError **error)
}
static GPtrArray *
need_secrets(NMSetting *setting)
need_secrets(NMSetting *setting, gboolean check_rerequest)
{
NMSettingCdmaPrivate *priv = NM_SETTING_CDMA_GET_PRIVATE(setting);
GPtrArray *secrets = NULL;
if (!nm_str_is_empty(priv->password))
if (!check_rerequest && !nm_str_is_empty(priv->password))
return NULL;
if (priv->username) {

View file

@ -460,12 +460,12 @@ verify_secrets(NMSetting *setting, NMConnection *connection, GError **error)
}
static GPtrArray *
need_secrets(NMSetting *setting)
need_secrets(NMSetting *setting, gboolean check_rerequest)
{
NMSettingGsmPrivate *priv = NM_SETTING_GSM_GET_PRIVATE(setting);
GPtrArray *secrets = NULL;
if (priv->password && *priv->password)
if (!check_rerequest && priv->password && *priv->password)
return NULL;
if (priv->username) {

View file

@ -215,13 +215,13 @@ nm_setting_macsec_get_send_sci(NMSettingMacsec *setting)
}
static GPtrArray *
need_secrets(NMSetting *setting)
need_secrets(NMSetting *setting, gboolean check_rerequest)
{
NMSettingMacsecPrivate *priv = NM_SETTING_MACSEC_GET_PRIVATE(setting);
GPtrArray *secrets = NULL;
if (priv->mode == NM_SETTING_MACSEC_MODE_PSK) {
if (!priv->mka_cak
if ((check_rerequest || !priv->mka_cak)
&& !NM_FLAGS_HAS(priv->mka_cak_flags, NM_SETTING_SECRET_FLAG_NOT_REQUIRED)) {
secrets = g_ptr_array_sized_new(1);
g_ptr_array_add(secrets, NM_SETTING_MACSEC_MKA_CAK);

View file

@ -178,12 +178,12 @@ verify(NMSetting *setting, NMConnection *connection, GError **error)
}
static GPtrArray *
need_secrets(NMSetting *setting)
need_secrets(NMSetting *setting, gboolean check_rerequest)
{
NMSettingPppoePrivate *priv = NM_SETTING_PPPOE_GET_PRIVATE(setting);
GPtrArray *secrets = NULL;
if (priv->password)
if (!check_rerequest && priv->password)
return NULL;
if (!(priv->password_flags & NM_SETTING_SECRET_FLAG_NOT_REQUIRED)) {

View file

@ -100,7 +100,7 @@ struct _NMSettingClass {
gboolean (*verify_secrets)(NMSetting *setting, NMConnection *connection, GError **error);
GPtrArray *(*need_secrets)(NMSetting *setting);
GPtrArray *(*need_secrets)(NMSetting *setting, gboolean check_rerequest);
int (*update_one_secret)(NMSetting *setting, const char *key, GVariant *value, GError **error);
@ -1046,7 +1046,7 @@ gboolean _nm_setting_use_legacy_property(NMSetting *setting,
const char *legacy_property,
const char *new_property);
GPtrArray *_nm_setting_need_secrets(NMSetting *setting);
GPtrArray *_nm_setting_need_secrets(NMSetting *setting, gboolean check_rerequest);
gboolean _nm_setting_should_compare_secret_property(NMSetting *setting,
NMSetting *other,

View file

@ -801,7 +801,7 @@ set_secret_flags(NMSetting *setting,
}
static GPtrArray *
need_secrets(NMSetting *setting)
need_secrets(NMSetting *setting, gboolean check_rerequest)
{
/* Assume that VPN connections need secrets since they almost always will */
return g_ptr_array_sized_new(1);

View file

@ -1800,13 +1800,13 @@ verify_secrets(NMSetting *setting, NMConnection *connection, GError **error)
}
static GPtrArray *
need_secrets(NMSetting *setting)
need_secrets(NMSetting *setting, gboolean check_rerequest)
{
NMSettingWireGuardPrivate *priv = NM_SETTING_WIREGUARD_GET_PRIVATE(setting);
GPtrArray *secrets = NULL;
guint i;
if (!priv->private_key_valid) {
if (check_rerequest || !priv->private_key_valid) {
secrets = g_ptr_array_new_full(1, g_free);
g_ptr_array_add(secrets, g_strdup(NM_SETTING_WIREGUARD_PRIVATE_KEY));
}

View file

@ -815,7 +815,7 @@ nm_setting_wireless_security_get_fils(NMSettingWirelessSecurity *setting)
}
static GPtrArray *
need_secrets(NMSetting *setting)
need_secrets(NMSetting *setting, gboolean check_rerequest)
{
NMSettingWirelessSecurity *self = NM_SETTING_WIRELESS_SECURITY(setting);
NMSettingWirelessSecurityPrivate *priv = NM_SETTING_WIRELESS_SECURITY_GET_PRIVATE(self);
@ -828,22 +828,22 @@ need_secrets(NMSetting *setting)
/* Static WEP */
if (strcmp(priv->key_mgmt, "none") == 0) {
if ((priv->wep_tx_keyidx == 0)
&& !nm_utils_wep_key_valid(priv->wep_key0, priv->wep_key_type)) {
&& (check_rerequest || !nm_utils_wep_key_valid(priv->wep_key0, priv->wep_key_type))) {
g_ptr_array_add(secrets, NM_SETTING_WIRELESS_SECURITY_WEP_KEY0);
return secrets;
}
if ((priv->wep_tx_keyidx == 1)
&& !nm_utils_wep_key_valid(priv->wep_key1, priv->wep_key_type)) {
&& (check_rerequest || !nm_utils_wep_key_valid(priv->wep_key1, priv->wep_key_type))) {
g_ptr_array_add(secrets, NM_SETTING_WIRELESS_SECURITY_WEP_KEY1);
return secrets;
}
if ((priv->wep_tx_keyidx == 2)
&& !nm_utils_wep_key_valid(priv->wep_key2, priv->wep_key_type)) {
&& (check_rerequest || !nm_utils_wep_key_valid(priv->wep_key2, priv->wep_key_type))) {
g_ptr_array_add(secrets, NM_SETTING_WIRELESS_SECURITY_WEP_KEY2);
return secrets;
}
if ((priv->wep_tx_keyidx == 3)
&& !nm_utils_wep_key_valid(priv->wep_key3, priv->wep_key_type)) {
&& (check_rerequest || !nm_utils_wep_key_valid(priv->wep_key3, priv->wep_key_type))) {
g_ptr_array_add(secrets, NM_SETTING_WIRELESS_SECURITY_WEP_KEY3);
return secrets;
}
@ -852,7 +852,7 @@ need_secrets(NMSetting *setting)
/* WPA-PSK infrastructure */
if (strcmp(priv->key_mgmt, "wpa-psk") == 0) {
if (!nm_utils_wpa_psk_valid(priv->psk)) {
if (check_rerequest || !nm_utils_wpa_psk_valid(priv->psk)) {
g_ptr_array_add(secrets, NM_SETTING_WIRELESS_SECURITY_PSK);
return secrets;
}
@ -861,7 +861,7 @@ need_secrets(NMSetting *setting)
/* SAE, used in MESH and WPA3-Personal */
if (strcmp(priv->key_mgmt, "sae") == 0) {
if (!priv->psk || !*priv->psk) {
if (check_rerequest || !priv->psk || !*priv->psk) {
g_ptr_array_add(secrets, NM_SETTING_WIRELESS_SECURITY_PSK);
return secrets;
}
@ -870,7 +870,7 @@ need_secrets(NMSetting *setting)
/* LEAP */
if (priv->auth_alg && !strcmp(priv->auth_alg, "leap") && !strcmp(priv->key_mgmt, "ieee8021x")) {
if (!priv->leap_password || !*priv->leap_password) {
if (check_rerequest || !priv->leap_password || !*priv->leap_password) {
g_ptr_array_add(secrets, NM_SETTING_WIRELESS_SECURITY_LEAP_PASSWORD);
return secrets;
}

View file

@ -3181,6 +3181,12 @@ _nm_setting_clear_secrets(NMSetting *setting,
/**
* _nm_setting_need_secrets:
* @setting: the #NMSetting
* @check_rerequest: If %TRUE: the stored secrets might be wrong and the agent
* should query the user for the correct credentials. If an #NMSetting knows
* that this cannot be the case it should *not* return the corresponding
* setting object. Otherwise it should always return it, even if it is not
* missing.
* If %FALSE: only return it when it is missing.
*
* Returns an array of property names for each secret which may be required
* to make a successful connection. The returned hints are only intended as a
@ -3193,14 +3199,14 @@ _nm_setting_clear_secrets(NMSetting *setting,
* free the elements.
**/
GPtrArray *
_nm_setting_need_secrets(NMSetting *setting)
_nm_setting_need_secrets(NMSetting *setting, gboolean check_rerequest)
{
GPtrArray *secrets = NULL;
g_return_val_if_fail(NM_IS_SETTING(setting), NULL);
if (NM_SETTING_GET_CLASS(setting)->need_secrets)
secrets = NM_SETTING_GET_CLASS(setting)->need_secrets(setting);
secrets = NM_SETTING_GET_CLASS(setting)->need_secrets(setting, check_rerequest);
return secrets;
}

View file

@ -1051,4 +1051,6 @@ gboolean _nm_ip_tunnel_mode_is_layer2(NMIPTunnelMode mode);
GPtrArray *_nm_setting_ip_config_get_dns_array(NMSettingIPConfig *setting);
gboolean nm_connection_need_secrets_for_rerequest(NMConnection *connection);
#endif