diff options
| author | Michael Biebl <biebl@debian.org> | 2022-05-04 15:35:24 +0200 |
|---|---|---|
| committer | Michael Biebl <biebl@debian.org> | 2022-05-04 15:35:24 +0200 |
| commit | 9959fdb2e8ddd06f2161798ca0a39c77d67c652d (patch) | |
| tree | 2ce24a336d2b1c5fd5dec3090db312eded6c78ba /src/nmcli/connections.c | |
| parent | 8c623dddbdebe354cb94bfc559a5371a14865317 (diff) | |
New upstream version 1.37.92 upstream/1.37.92
Diffstat (limited to 'src/nmcli/connections.c')
| -rw-r--r-- | src/nmcli/connections.c | 337 |
1 files changed, 279 insertions, 58 deletions
diff --git a/src/nmcli/connections.c b/src/nmcli/connections.c index 025f96a1..ecf8e2e2 100644 --- a/src/nmcli/connections.c +++ b/src/nmcli/connections.c @@ -513,6 +513,40 @@ _con_show_fcn_get_type(NMConnection *c, NMActiveConnection *ac, NMMetaAccessorGe return connection_type_to_display(s, get_type); } +static const char * +_connection_check_deprecated(NMConnection *c) +{ + NMSettingWirelessSecurity *s_wsec; + const char *key_mgmt; + const char *type; + + type = nm_connection_get_connection_type(c); + + if (strcmp(type, NM_SETTING_WIMAX_SETTING_NAME) == 0) + return _("WiMax is no longer supported"); + + s_wsec = nm_connection_get_setting_wireless_security(c); + if (s_wsec) { + key_mgmt = nm_setting_wireless_security_get_key_mgmt(s_wsec); + if (NM_IN_STRSET(key_mgmt, "ieee8021x", "none")) + return _("WEP encryption is known to be insecure"); + } + + return NULL; +} + +static NMMetaColor +_connection_to_color(NMConnection *c, NMActiveConnection *ac) +{ + if (ac) + return nmc_active_connection_state_to_color(ac); + + if (_connection_check_deprecated(c)) + return NM_META_COLOR_CONNECTION_DEPRECATED; + + return NM_META_COLOR_CONNECTION_UNKNOWN; +} + static gconstpointer _metagen_con_show_get_fcn(NMC_META_GENERIC_INFO_GET_FCN_ARGS) { @@ -523,7 +557,7 @@ _metagen_con_show_get_fcn(NMC_META_GENERIC_INFO_GET_FCN_ARGS) const char *s; char *s_mut; - NMC_HANDLE_COLOR(nmc_active_connection_state_to_color(ac)); + NMC_HANDLE_COLOR(_connection_to_color(c, ac)); if (c) s_con = nm_connection_get_setting_connection(c); @@ -1197,10 +1231,10 @@ usage_connection_delete(void) { g_printerr(_("Usage: nmcli connection delete { ARGUMENTS | help }\n" "\n" - "ARGUMENTS := [id | uuid | path] <ID>\n" + "ARGUMENTS := [id | uuid | path] <ID>, ...\n" "\n" - "Delete a connection profile.\n" - "The profile is identified by its name, UUID or D-Bus path.\n\n")); + "Delete connection profiles.\n" + "The profiles are identified by their name, UUID or D-Bus path.\n\n")); } static void @@ -1261,6 +1295,17 @@ usage_connection_export(void) } static void +usage_connection_migrate(void) +{ + g_printerr(_("Usage: nmcli connection migrate { ARGUMENTS | help }\n" + "\n" + "ARGUMENTS := [--plugin <plugin>] [id | uuid | path] <ID>, ...\n" + "\n" + "Migrate connection profiles to a different settings plugin,\n" + "such as \"keyfile\" (default) or \"ifcfg-rh\".\n\n")); +} + +static void quit(void) { if (nm_clear_g_source(&progress_id)) @@ -1410,13 +1455,13 @@ nmc_connection_profile_details(NMConnection *connection, NmCli *nmc) TRUE, &prop_array, &error); - if (error) { + if (!print_settings_array) { + g_return_val_if_fail(error, FALSE); g_string_printf(nmc->return_text, _("Error: 'connection show': %s"), error->message); g_error_free(error); nmc->return_value = NMC_RESULT_ERROR_USER_INPUT; return FALSE; } - g_assert(print_settings_array); /* Main header */ { @@ -1478,9 +1523,6 @@ nmc_active_connection_state_to_color(NMActiveConnection *ac) { NMActiveConnectionState state; - if (!ac) - return NM_META_COLOR_CONNECTION_UNKNOWN; - if (NM_FLAGS_HAS(nm_active_connection_get_state_flags(ac), NM_ACTIVATION_STATE_FLAG_EXTERNAL)) return NM_META_COLOR_CONNECTION_EXTERNAL; @@ -1520,13 +1562,13 @@ nmc_active_connection_details(NMActiveConnection *acon, NmCli *nmc) TRUE, &group_fields, &error); - if (error) { + if (!print_groups) { + g_return_val_if_fail(error, FALSE); g_string_printf(nmc->return_text, _("Error: 'connection show': %s"), error->message); g_error_free(error); nmc->return_value = NMC_RESULT_ERROR_USER_INPUT; return FALSE; } - g_assert(print_groups); /* Main header */ { @@ -1881,6 +1923,7 @@ con_show_get_items_cmp(gconstpointer pa, gconstpointer pb, gpointer user_data) } } + NM_CMP_DIRECT(!!_connection_check_deprecated(c_a), !!_connection_check_deprecated(c_b)); NM_CMP_DIRECT_STRCMP0(nm_connection_get_uuid(c_a), nm_connection_get_uuid(c_b)); NM_CMP_DIRECT_STRCMP0(nm_connection_get_path(c_a), nm_connection_get_path(c_b)); } @@ -2150,7 +2193,7 @@ do_connections_show(const NMCCommand *cmd, NmCli *nmc, int argc, const char *con goto finish; break; default: - g_assert_not_reached(); + g_return_if_reached(); break; } } @@ -2470,7 +2513,7 @@ find_device_for_connection(NmCli *nmc, g_return_val_if_fail(error == NULL || *error == NULL, FALSE); s_con = nm_connection_get_setting_connection(connection); - g_assert(s_con); + g_return_val_if_fail(s_con, FALSE); con_type = nm_setting_connection_get_connection_type(s_con); if (nm_streq(con_type, NM_SETTING_VPN_SETTING_NAME)) { @@ -2959,7 +3002,7 @@ do_connection_up(const NMCCommand *cmd, NmCli *nmc, int argc, const char *const gs_free char *line = NULL; /* nmc_do_cmd() should not call this with argc=0. */ - g_assert(!nmc->complete); + g_return_if_fail(!nmc->complete); line = nmc_readline(&nmc->nmc_config, PROMPT_CONNECTION); nmc_string_to_arg_array(line, NULL, TRUE, &arg_arr, &arg_num); @@ -3215,7 +3258,7 @@ do_connection_down(const NMCCommand *cmd, NmCli *nmc, int argc, const char *cons if (argc == 0) { /* nmc_do_cmd() should not call this with argc=0. */ - g_assert(!nmc->complete); + g_return_if_fail(!nmc->complete); if (nmc->ask) { gs_free char *line = NULL; @@ -3660,7 +3703,8 @@ is_setting_mandatory(NMConnection *connection, NMSetting *setting) guint i; s_con = nm_connection_get_setting_connection(connection); - g_assert(s_con); + g_return_val_if_fail(s_con, FALSE); + c_type = nm_setting_connection_get_connection_type(s_con); s_type = nm_setting_connection_get_slave_type(s_con); @@ -3739,7 +3783,7 @@ normalized_master_for_slave(const GPtrArray *connections, for (i = 0; i < connections->len; i++) { connection = NM_CONNECTION(connections->pdata[i]); s_con = nm_connection_get_setting_connection(connection); - g_assert(s_con); + g_return_val_if_fail(s_con, NULL); con_type = nm_setting_connection_get_connection_type(s_con); if (type && !nm_streq0(con_type, type)) continue; @@ -4243,7 +4287,7 @@ con_settings(NMConnection *connection, g_return_val_if_fail(slv_settings, FALSE); s_con = nm_connection_get_setting_connection(connection); - g_assert(s_con); + g_return_val_if_fail(s_con, FALSE); con_type = nm_setting_connection_get_slave_type(s_con); *slv_settings = nm_meta_setting_info_valid_parts_for_slave_type(con_type, NULL); @@ -5209,14 +5253,52 @@ nmc_process_connection_properties(NmCli *nmc, } static void +connection_warnings(NmCli *nmc, NMConnection *connection) +{ + const GPtrArray *connections; + guint i, found; + const char *id; + const char *deprecated; + + deprecated = _connection_check_deprecated(NM_CONNECTION(connection)); + if (deprecated) + g_printerr(_("Warning: %s.\n"), deprecated); + + connections = nm_client_get_connections(nmc->client); + if (!connections) + return; + + id = nm_connection_get_id(connection); + found = 0; + for (i = 0; i < connections->len; i++) { + NMConnection *candidate = NM_CONNECTION(connections->pdata[i]); + + if ((NMConnection *) connection == candidate) + continue; + if (nm_streq0(nm_connection_get_id(candidate), id)) + found++; + } + + if (found > 0) { + g_printerr(g_dngettext(GETTEXT_PACKAGE, + "Warning: There is another connection with the name '%1$s'. " + "Reference the connection by its uuid '%2$s'\n", + "Warning: There are %3$u other connections with the name " + "'%1$s'. Reference the connection by its uuid '%2$s'\n", + found), + id, + nm_connection_get_uuid(NM_CONNECTION(connection)), + found); + } +} + +static void add_connection_cb(GObject *client, GAsyncResult *result, gpointer user_data) { nm_auto_free_add_connection_info AddConnectionInfo *info = user_data; NmCli *nmc = info->nmc; NMRemoteConnection *connection; GError *error = NULL; - const GPtrArray *connections; - guint i, found; connection = nm_client_add_connection2_finish(NM_CLIENT(client), result, NULL, &error); if (error) { @@ -5227,29 +5309,7 @@ add_connection_cb(GObject *client, GAsyncResult *result, gpointer user_data) g_error_free(error); nmc->return_value = NMC_RESULT_ERROR_CON_ACTIVATION; } else { - connections = nm_client_get_connections(nmc->client); - if (connections) { - found = 0; - for (i = 0; i < connections->len; i++) { - NMConnection *candidate = NM_CONNECTION(connections->pdata[i]); - - if ((NMConnection *) connection == candidate) - continue; - if (nm_streq0(nm_connection_get_id(candidate), info->new_id)) - found++; - } - if (found > 0) { - g_printerr(g_dngettext(GETTEXT_PACKAGE, - "Warning: There is another connection with the name '%1$s'. " - "Reference the connection by its uuid '%2$s'\n", - "Warning: There are %3$u other connections with the name " - "'%1$s'. Reference the connection by its uuid '%2$s'\n", - found), - info->new_id, - nm_connection_get_uuid(NM_CONNECTION(connection)), - found); - } - } + connection_warnings(nmc, NM_CONNECTION(connection)); /* We print here human readable text, but as scripts might parse this output * (with LANG=C), this is important to not change in the future. At least @@ -7252,7 +7312,8 @@ editor_show_status_line(NMConnection *connection, gboolean dirty, gboolean temp) const char *con_type, *con_id, *con_uuid; s_con = nm_connection_get_setting_connection(connection); - g_assert(s_con); + g_return_if_fail(s_con); + con_type = nm_setting_connection_get_connection_type(s_con); con_id = nm_connection_get_id(connection); con_uuid = nm_connection_get_uuid(connection); @@ -7595,15 +7656,18 @@ confirm_connection_saving(const NmcConfig *nmc_config, NMConnection *local, NMCo gboolean confirmed = TRUE; s_con_loc = nm_connection_get_setting_connection(local); - g_assert(s_con_loc); + g_return_val_if_fail(s_con_loc, FALSE); + ac_local = nm_setting_connection_get_autoconnect(s_con_loc); if (remote) { s_con_rem = nm_connection_get_setting_connection(remote); - g_assert(s_con_rem); + g_return_val_if_fail(s_con_rem, FALSE); + ac_remote = nm_setting_connection_get_autoconnect(s_con_rem); - } else + } else { ac_remote = FALSE; + } if (ac_local && !ac_remote) { gs_free char *answer = NULL; @@ -8280,9 +8344,12 @@ editor_menu_main(NmCli *nmc, NMConnection *connection, const char *connection_ty connection_changed = FALSE; } - source = g_timeout_source_new(10 * NM_UTILS_MSEC_PER_SEC); - g_source_set_callback(source, editor_save_timeout, &timeout, NULL); - g_source_attach(source, g_main_loop_get_context(loop)); + source = nm_g_source_attach(nm_g_timeout_source_new(10 * NM_UTILS_MSEC_PER_SEC, + G_PRIORITY_DEFAULT, + editor_save_timeout, + &timeout, + NULL), + g_main_loop_get_context(loop)); while (!nmc_editor_cb_called && !timeout) g_main_context_iteration(NULL, TRUE); @@ -8527,7 +8594,8 @@ editor_init_new_connection(NmCli *nmc, NMConnection *connection, const char *sla const char *con_type; s_con = nm_connection_get_setting_connection(connection); - g_assert(s_con); + g_return_if_fail(s_con); + con_type = nm_setting_connection_get_connection_type(s_con); /* Initialize new connection according to its type using sensible defaults. */ @@ -8851,6 +8919,8 @@ modify_connection_cb(GObject *connection, GAsyncResult *result, gpointer user_da error->message); nmc->return_value = NMC_RESULT_ERROR_UNKNOWN; } else { + connection_warnings(nmc, NM_CONNECTION(connection)); + if (nmc->nmc_config.print_output == NMC_PRINT_PRETTY) { g_print(_("Connection '%s' (%s) successfully modified.\n"), nm_connection_get_id(NM_CONNECTION(connection)), @@ -8955,7 +9025,7 @@ do_connection_clone(const NMCCommand *cmd, NmCli *nmc, int argc, const char *con gs_free char *line = NULL; /* nmc_do_cmd() should not call this with argc=0. */ - g_assert(!nmc->complete); + g_return_if_fail(!nmc->complete); line = nmc_readline(&nmc->nmc_config, PROMPT_CONNECTION); nmc_string_to_arg_array(line, NULL, TRUE, &arg_arr, &arg_num); @@ -9054,7 +9124,7 @@ do_connection_delete(const NMCCommand *cmd, NmCli *nmc, int argc, const char *co gs_free char *line = NULL; /* nmc_do_cmd() should not call this with argc=0. */ - g_assert(!nmc->complete); + g_return_if_fail(!nmc->complete); line = nmc_readline(&nmc->nmc_config, PROMPT_CONNECTIONS); nmc_string_to_arg_array(line, NULL, TRUE, &arg_arr, &arg_num); @@ -9079,8 +9149,11 @@ do_connection_delete(const NMCCommand *cmd, NmCli *nmc, int argc, const char *co nmc->return_value = error->code; g_clear_error(&error); - if (nmc->return_value != NMC_RESULT_ERROR_NOT_FOUND) + if (nmc->return_value != NMC_RESULT_ERROR_NOT_FOUND) { + g_string_free(invalid_cons, TRUE); + invalid_cons = NULL; goto finish; + } if (!invalid_cons) invalid_cons = g_string_new(NULL); @@ -9133,7 +9206,6 @@ finish: g_string_printf(nmc->return_text, _("Error: cannot delete unknown connection(s): %s."), invalid_cons->str); - nmc->return_value = NMC_RESULT_ERROR_NOT_FOUND; } } @@ -9192,7 +9264,7 @@ do_connection_monitor(const NMCCommand *cmd, NmCli *nmc, int argc, const char *c /* No connections specified. Monitor all. */ /* nmc_do_cmd() should not call this with argc=0. */ - g_assert(!nmc->complete); + g_return_if_fail(!nmc->complete); connections = nm_client_get_connections(nmc->client); } else { @@ -9349,7 +9421,7 @@ do_connection_import(const NMCCommand *cmd, NmCli *nmc, int argc, const char *co if (argc == 0) { /* nmc_do_cmd() should not call this with argc=0. */ - g_assert(!nmc->complete); + g_return_if_fail(!nmc->complete); if (nmc->ask) { type_ask = @@ -9492,7 +9564,7 @@ do_connection_export(const NMCCommand *cmd, NmCli *nmc, int argc, const char *co gs_free char *line = NULL; /* nmc_do_cmd() should not call this with argc=0. */ - g_assert(!nmc->complete); + g_return_if_fail(!nmc->complete); line = nmc_readline(&nmc->nmc_config, PROMPT_VPN_CONNECTION); nmc_string_to_arg_array(line, NULL, TRUE, &arg_arr, &arg_num); @@ -9586,6 +9658,154 @@ finish: unlink(path); } +static void +migrate_cb(GObject *obj, GAsyncResult *result, gpointer user_data) +{ + ConnectionCbInfo *info = (ConnectionCbInfo *) user_data; + NMConnection *connection = NM_CONNECTION(obj); + gs_unref_variant GVariant *res = NULL; + GError *error = NULL; + + res = nm_remote_connection_update2_finish(NM_REMOTE_CONNECTION(obj), result, &error); + if (!res) { + g_string_printf(info->nmc->return_text, _("Error: not all connections migrated.")); + g_printerr(_("Error: Connection migration failed: %s\n"), error->message); + g_error_free(error); + info->nmc->return_value = NMC_RESULT_ERROR_UNKNOWN; + } else { + g_print(_("Connection '%s' (%s) successfully migrated.\n"), + nm_connection_get_id(connection), + nm_connection_get_uuid(connection)); + } + connection_cb_info_finish(info, obj); +} + +static void +do_connection_migrate(const NMCCommand *cmd, NmCli *nmc, int argc, const char *const *argv) +{ + NMConnection *connection; + ConnectionCbInfo *info = NULL; + gs_strfreev char **arg_arr = NULL; + const char *const *arg_ptr; + guint i; + int arg_num; + nm_auto_free_gstring GString *invalid_cons = NULL; + gs_unref_ptrarray GPtrArray *found_cons = NULL; + GError *error = NULL; + const char *plugin = "keyfile"; + const GPtrArray *connections = NULL; + int option; + + if (nmc->timeout == -1) + nmc->timeout = 10; + + while ((option = next_arg(nmc, &argc, &argv, "--plugin", NULL)) > 0) { + switch (option) { + case 1: /* --plugin */ + argc--; + argv++; + if (!argc) { + g_set_error_literal(&error, NMCLI_ERROR, 0, _("'--plugin' argument is missing")); + goto finish; + } + plugin = *argv; + break; + default: + g_return_if_reached(); + break; + } + } + + arg_ptr = argv; + arg_num = argc; + if (argc == 0) { + if (nmc->ask) { + gs_free char *line = NULL; + + /* nmc_do_cmd() should not call this with argc=0. */ + g_return_if_fail(!nmc->complete); + + line = nmc_readline(&nmc->nmc_config, PROMPT_CONNECTIONS); + nmc_string_to_arg_array(line, NULL, TRUE, &arg_arr, &arg_num); + arg_ptr = (const char *const *) arg_arr; + } + } + + while (arg_num > 0) { + const char *cur_selector, *cur_value; + + connection = + get_connection(nmc, &arg_num, &arg_ptr, &cur_selector, &cur_value, &found_cons, &error); + if (!connection) { + if (!nmc->complete) + g_printerr(_("Error: %s.\n"), error->message); + g_string_printf(nmc->return_text, _("Error: not all connections found.")); + nmc->return_value = error->code; + g_clear_error(&error); + + if (nmc->return_value != NMC_RESULT_ERROR_NOT_FOUND) { + g_string_free(invalid_cons, TRUE); + invalid_cons = NULL; + goto finish; + } + + if (!invalid_cons) + invalid_cons = g_string_new(NULL); + if (cur_selector) + g_string_append_printf(invalid_cons, "%s '%s', ", cur_selector, cur_value); + else + g_string_append_printf(invalid_cons, "'%s', ", cur_value); + } + } + + if (nmc->complete) + goto finish; + + if (invalid_cons) + goto finish; + + if (!found_cons) { + /* No connections specified explicitly? Fine, add all. */ + found_cons = g_ptr_array_new(); + connections = nm_client_get_connections(nmc->client); + for (i = 0; i < connections->len; i++) { + connection = connections->pdata[i]; + g_ptr_array_add(found_cons, connection); + } + } + + info = g_slice_new0(ConnectionCbInfo); + info->nmc = nmc; + info->obj_list = g_ptr_array_sized_new(found_cons->len); + for (i = 0; i < found_cons->len; i++) { + connection = found_cons->pdata[i]; + g_ptr_array_add(info->obj_list, g_object_ref(connection)); + } + info->timeout_id = g_timeout_add_seconds(nmc->timeout, connection_op_timeout_cb, info); + info->cancellable = g_cancellable_new(); + + nmc->nowait_flag = (nmc->timeout == 0); + nmc->should_wait++; + + for (i = 0; i < found_cons->len; i++) { + nm_remote_connection_update2(NM_REMOTE_CONNECTION(found_cons->pdata[i]), + NULL, + 0, + g_variant_new_parsed("{'plugin': <%s>}", plugin), + info->cancellable, + migrate_cb, + info); + } + +finish: + if (invalid_cons) { + g_string_truncate(invalid_cons, invalid_cons->len - 2); /* truncate trailing ", " */ + g_string_printf(nmc->return_text, + _("Error: cannot migrate unknown connection(s): %s."), + invalid_cons->str); + } +} + static char * gen_func_connection_names(const char *text, int state) { @@ -9693,6 +9913,7 @@ nmc_command_func_connection(const NMCCommand *cmd, NmCli *nmc, int argc, const c {"clone", do_connection_clone, usage_connection_clone, TRUE, TRUE}, {"import", do_connection_import, usage_connection_import, TRUE, TRUE}, {"export", do_connection_export, usage_connection_export, TRUE, TRUE}, + {"migrate", do_connection_migrate, usage_connection_migrate, TRUE, TRUE}, {"monitor", do_connection_monitor, usage_connection_monitor, TRUE, TRUE}, {NULL, do_connections_show, usage, TRUE, TRUE}, }; |