Example #1
0
int
main (int argc, char *argv[])
{
	gboolean retry = FALSE, allow_interaction = FALSE;
	gchar *vpn_name = NULL;
	gchar *vpn_uuid = NULL;
	gchar *vpn_service = NULL;
	gs_unref_hashtable GHashTable *data = NULL;
	gs_unref_hashtable GHashTable *secrets = NULL;
	gboolean need_password = FALSE;
	gboolean need_user_certpass = FALSE;
	gboolean need_machine_certpass = FALSE;
	gs_free char *prompt = NULL;
	nm_auto_free_secret char *new_password = NULL;
	nm_auto_free_secret char *new_user_certpass = NULL;
	nm_auto_free_secret char *new_machine_certpass = NULL;
	nm_auto_free_secret char *existing_password = NULL;
	nm_auto_free_secret char *existing_user_certpass = NULL;
	nm_auto_free_secret char *existing_machine_certpass = NULL;
	gboolean external_ui_mode = FALSE;
	gboolean ask_user;
	NoSecretsRequiredFunc no_secrets_required_func;
	AskUserFunc ask_user_func;
	FinishFunc finish_func;

	GOptionContext *context;
	GOptionEntry entries[] = {
			{ "reprompt", 'r', 0, G_OPTION_ARG_NONE, &retry, "Reprompt for passwords", NULL},
			{ "uuid", 'u', 0, G_OPTION_ARG_STRING, &vpn_uuid, "UUID of VPN connection", NULL},
			{ "name", 'n', 0, G_OPTION_ARG_STRING, &vpn_name, "Name of VPN connection", NULL},
			{ "service", 's', 0, G_OPTION_ARG_STRING, &vpn_service, "VPN service type", NULL},
			{ "allow-interaction", 'i', 0, G_OPTION_ARG_NONE, &allow_interaction, "Allow user interaction", NULL},
			{ "external-ui-mode", 0, 0, G_OPTION_ARG_NONE, &external_ui_mode, "External UI mode", NULL},
			{ NULL }
		};

	bindtextdomain (GETTEXT_PACKAGE, NULL);
	bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
	textdomain (GETTEXT_PACKAGE);

	context = g_option_context_new ("- l2tp auth dialog");
	g_option_context_add_main_entries (context, entries, GETTEXT_PACKAGE);
	g_option_context_add_group (context, gtk_get_option_group (FALSE));
	g_option_context_parse (context, &argc, &argv, NULL);
	g_option_context_free (context);

	if (vpn_uuid == NULL || vpn_name == NULL || vpn_service == NULL) {
		fprintf (stderr, "A connection UUID, name, and VPN plugin service name are required.\n");
		return EXIT_FAILURE;
	}

	if (strcmp (vpn_service, NM_DBUS_SERVICE_L2TP) != 0) {
		fprintf (stderr, "This dialog only works with the '%s' service\n", NM_DBUS_SERVICE_L2TP);
		return EXIT_FAILURE;
	}

	if (!nm_vpn_service_plugin_read_vpn_details (0, &data, &secrets)) {
		fprintf (stderr, "Failed to read '%s' (%s) data and secrets from stdin.\n",
		         vpn_name, vpn_uuid);
		return EXIT_FAILURE;
	}

	if (external_ui_mode) {
		no_secrets_required_func = eui_no_secrets_required;
		ask_user_func = NULL;
		finish_func = eui_finish;
	} else {
		no_secrets_required_func = std_no_secrets_required;
		ask_user_func = std_ask_user;
		finish_func = std_finish;
	}

	/* Determine which passwords are actually required,
	 * from looking at the VPN configuration.
	 */
	prompt = get_passwords_required (data, &need_password, &need_user_certpass, &need_machine_certpass);
	if (!prompt)
		prompt = g_strdup_printf (_("You need to authenticate to access the Virtual Private Network ā€œ%sā€."), vpn_name);

	/* Exit early if we don't need any passwords */
	if (!need_password && !need_user_certpass && !need_machine_certpass) {
		no_secrets_required_func ();
		return EXIT_SUCCESS;
	}

	get_existing_passwords (data,
	                        secrets,
	                        vpn_uuid,
	                        need_password,
	                        need_user_certpass,
	                        need_machine_certpass,
	                        &existing_password,
	                        &existing_user_certpass,
	                        &existing_machine_certpass);
	if (need_password && !existing_password)
		ask_user = TRUE;
	else if (need_user_certpass && !existing_user_certpass)
		ask_user = TRUE;
	else if (need_machine_certpass && !existing_machine_certpass)
		ask_user = TRUE;
	else
		ask_user = FALSE;

	/* If interaction is allowed then ask the user, otherwise pass back
	 * whatever existing secrets we can find.
	 */
	if (   ask_user_func
	    && allow_interaction
	    && (ask_user || retry)) {
		if (!ask_user_func (vpn_name,
		                    prompt,
		                    need_password,
		                    existing_password,
		                    &new_password,
		                    need_user_certpass,
		                    existing_user_certpass,
		                    &new_user_certpass,
		                    need_machine_certpass,
		                    existing_machine_certpass,
		                    &new_machine_certpass))
			return EXIT_FAILURE;
	}

	finish_func (vpn_name,
	             prompt,
	             allow_interaction,
	             need_password,
	             new_password ? new_password : existing_password,
	             need_user_certpass,
	             new_user_certpass ? new_user_certpass : existing_user_certpass,
	             need_machine_certpass,
	             new_machine_certpass ? new_machine_certpass : existing_machine_certpass);
	return EXIT_SUCCESS;
}
Example #2
0
int 
main (int argc, char *argv[])
{
	gboolean retry = FALSE, allow_interaction = FALSE, external_ui_mode = FALSE;
	char *vpn_name = NULL, *vpn_uuid = NULL, *vpn_service = NULL;
	GHashTable *data = NULL, *secrets = NULL;
	gboolean need_password = FALSE, need_group_password = FALSE;
	char *existing_password = NULL, *existing_group_password = NULL;
	char *new_password = NULL, *new_group_password = NULL;
	GError *error = NULL;
	char **hints = NULL;
	char *prompt = NULL;
	gboolean canceled = FALSE, ask_user = FALSE;

	NoSecretsRequiredFunc no_secrets_required_func = NULL;
	AskUserFunc ask_user_func = NULL;
	FinishFunc finish_func = NULL;

	GOptionContext *context;
	GOptionEntry entries[] = {
			{ "reprompt", 'r', 0, G_OPTION_ARG_NONE, &retry, "Reprompt for passwords", NULL},
			{ "uuid", 'u', 0, G_OPTION_ARG_STRING, &vpn_uuid, "UUID of VPN connection", NULL},
			{ "name", 'n', 0, G_OPTION_ARG_STRING, &vpn_name, "Name of VPN connection", NULL},
			{ "service", 's', 0, G_OPTION_ARG_STRING, &vpn_service, "VPN service type", NULL},
			{ "allow-interaction", 'i', 0, G_OPTION_ARG_NONE, &allow_interaction, "Allow user interaction", NULL},
			{ "external-ui-mode", 0, 0, G_OPTION_ARG_NONE, &external_ui_mode, "External UI mode", NULL},
			{ "hint", 't', 0, G_OPTION_ARG_STRING_ARRAY, &hints, "Hints from the VPN plugin", NULL},
			{ NULL }
		};

	bindtextdomain (GETTEXT_PACKAGE, NULL);
	bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
	gtk_init (&argc, &argv);
	textdomain (GETTEXT_PACKAGE);

	context = g_option_context_new ("- IPsec auth dialog");
	g_option_context_add_main_entries (context, entries, GETTEXT_PACKAGE);

	if (!g_option_context_parse (context, &argc, &argv, &error)) {
		fprintf (stderr, "Error parsing options: %s\n", error->message);
		g_error_free (error);
		return 1;
	}

	g_option_context_free (context);

	if (!vpn_uuid || !vpn_service || !vpn_name) {
		fprintf (stderr, "A connection UUID, name, and VPN plugin service name are required.\n");
		return 1;
	}

	if (   strcmp (vpn_service, NM_VPN_SERVICE_TYPE_LIBRESWAN) != 0
	    && strcmp (vpn_service, NM_VPN_SERVICE_TYPE_OPENSWAN) != 0) {
		fprintf (stderr, "This dialog only works with the '%s' service\n", NM_VPN_SERVICE_TYPE_LIBRESWAN);
		return 1;
	}

	if (!nm_vpn_service_plugin_read_vpn_details (0, &data, &secrets)) {
		fprintf (stderr, "Failed to read '%s' (%s) data and secrets from stdin.\n",
		         vpn_name, vpn_uuid);
		return 1;
	}

	if (external_ui_mode) {
		no_secrets_required_func = eui_no_secrets_required;
		finish_func = eui_finish;
	} else {
		no_secrets_required_func = std_no_secrets_required;
		ask_user_func = std_ask_user;
		finish_func = std_finish;
	}

	/* Determine which passwords are actually required, either from hints or
	 * from looking at the VPN configuration.
	 */
	prompt = get_passwords_required (data, hints, &need_password, &need_group_password);
	if (!prompt)
		prompt = g_strdup_printf (_("You need to authenticate to access the Virtual Private Network ā€œ%sā€."), vpn_name);

	/* Exit early if we don't need any passwords */
	if (!need_password && !need_group_password)
		no_secrets_required_func ();
	else {
		get_existing_passwords (data,
		                        secrets,
		                        vpn_uuid,
		                        need_password,
		                        need_group_password,
		                        &existing_password,
		                        &existing_group_password);
		if (need_password && !existing_password)
			ask_user = TRUE;
		if (need_group_password && !existing_group_password)
			ask_user = TRUE;

		/* If interaction is allowed then ask the user, otherwise pass back
		 * whatever existing secrets we can find.
		 */
		if (ask_user_func && allow_interaction && (ask_user || retry)) {
			canceled = !ask_user_func (vpn_name,
			                           prompt,
			                           retry,
			                           need_password,
			                           existing_password,
			                           &new_password,
			                           need_group_password,
			                           existing_group_password,
			                           &new_group_password);
		}

		if (!canceled) {
			finish_func (vpn_name,
			             prompt,
			             allow_interaction,
			             retry,
			             need_password,
			             new_password ? new_password : existing_password,
			             need_group_password,
			             new_group_password ? new_group_password : existing_group_password);
		}

		free_secret (existing_password);
		free_secret (existing_group_password);
		free_secret (new_password);
		free_secret (new_group_password);
	}

	if (data)
		g_hash_table_unref (data);
	if (secrets)
		g_hash_table_unref (secrets);
	if (hints)
		g_strfreev (hints);
	g_free (prompt);
	return canceled ? 1 : 0;
}