Merge branch 'nm-psk'

This adds support for PSK authentication to the NetworkManager frontend.
This commit is contained in:
Tobias Brunner
2013-11-27 18:37:11 +01:00
5 changed files with 128 additions and 87 deletions
+12 -4
View File
@@ -412,9 +412,10 @@ static gboolean connect_(NMVPNPlugin *plugin, NMConnection *connection,
loose_gateway_id = TRUE; loose_gateway_id = TRUE;
} }
if (auth_class == AUTH_CLASS_EAP) if (auth_class == AUTH_CLASS_EAP ||
auth_class == AUTH_CLASS_PSK)
{ {
/* username/password authentication ... */ /* username/password or PSK authentication ... */
str = nm_setting_vpn_get_data_item(vpn, "user"); str = nm_setting_vpn_get_data_item(vpn, "user");
if (str) if (str)
{ {
@@ -548,7 +549,14 @@ static gboolean connect_(NMVPNPlugin *plugin, NMConnection *connection,
auth->add(auth, AUTH_RULE_IDENTITY, user); auth->add(auth, AUTH_RULE_IDENTITY, user);
peer_cfg->add_auth_cfg(peer_cfg, auth, TRUE); peer_cfg->add_auth_cfg(peer_cfg, auth, TRUE);
auth = auth_cfg_create(); auth = auth_cfg_create();
auth->add(auth, AUTH_RULE_AUTH_CLASS, AUTH_CLASS_PUBKEY); if (auth_class == AUTH_CLASS_PSK)
{
auth->add(auth, AUTH_RULE_AUTH_CLASS, AUTH_CLASS_PSK);
}
else
{
auth->add(auth, AUTH_RULE_AUTH_CLASS, AUTH_CLASS_PUBKEY);
}
auth->add(auth, AUTH_RULE_IDENTITY, gateway); auth->add(auth, AUTH_RULE_IDENTITY, gateway);
auth->add(auth, AUTH_RULE_IDENTITY_LOOSE, loose_gateway_id); auth->add(auth, AUTH_RULE_IDENTITY_LOOSE, loose_gateway_id);
peer_cfg->add_auth_cfg(peer_cfg, auth, FALSE); peer_cfg->add_auth_cfg(peer_cfg, auth, FALSE);
@@ -623,7 +631,7 @@ static gboolean need_secrets(NMVPNPlugin *plugin, NMConnection *connection,
method = nm_setting_vpn_get_data_item(settings, "method"); method = nm_setting_vpn_get_data_item(settings, "method");
if (method) if (method)
{ {
if (streq(method, "eap")) if (streq(method, "eap") || streq(method, "psk"))
{ {
if (nm_setting_vpn_get_secret(settings, "password")) if (nm_setting_vpn_get_secret(settings, "password"))
{ {
+18 -4
View File
@@ -99,7 +99,7 @@ static char* get_connection_type(char *uuid)
fprintf (stderr, "Failed to read data and secrets from stdin.\n"); fprintf (stderr, "Failed to read data and secrets from stdin.\n");
return NULL; return NULL;
} }
method = g_hash_table_lookup (data, "method"); method = g_hash_table_lookup (data, "method");
if (method) if (method)
method = g_strdup(method); method = g_strdup(method);
@@ -118,7 +118,7 @@ int main (int argc, char *argv[])
gchar *name = NULL, *uuid = NULL, *service = NULL, *keyring = NULL, *pass; gchar *name = NULL, *uuid = NULL, *service = NULL, *keyring = NULL, *pass;
GOptionContext *context; GOptionContext *context;
char *agent, *type; char *agent, *type;
guint32 itemid; guint32 itemid, minlen = 0;
GtkWidget *dialog; GtkWidget *dialog;
GOptionEntry entries[] = { GOptionEntry entries[] = {
{ "reprompt", 'r', 0, G_OPTION_ARG_NONE, &retry, "Reprompt for passwords", NULL}, { "reprompt", 'r', 0, G_OPTION_ARG_NONE, &retry, "Reprompt for passwords", NULL},
@@ -159,7 +159,8 @@ int main (int argc, char *argv[])
fprintf(stderr, "Connection lookup failed\n"); fprintf(stderr, "Connection lookup failed\n");
return 1; return 1;
} }
if (!strcmp(type, "eap") || !strcmp(type, "key") || !strcmp(type, "smartcard")) if (!strcmp(type, "eap") || !strcmp(type, "key") || !strcmp(type, "psk") ||
!strcmp(type, "smartcard"))
{ {
pass = lookup_password(name, service); pass = lookup_password(name, service);
if ((!pass || retry) && allow_interaction) if ((!pass || retry) && allow_interaction)
@@ -178,6 +179,14 @@ int main (int argc, char *argv[])
NULL, NULL, TRUE); NULL, NULL, TRUE);
gnome_password_dialog_set_show_remember(GNOME_PASSWORD_DIALOG(dialog), TRUE); gnome_password_dialog_set_show_remember(GNOME_PASSWORD_DIALOG(dialog), TRUE);
} }
else if (!strcmp(type, "psk"))
{
dialog = gnome_password_dialog_new(_("VPN password required"),
_("Pre-shared key required to establish VPN connection (min. 20 characters):"),
NULL, NULL, TRUE);
gnome_password_dialog_set_show_remember(GNOME_PASSWORD_DIALOG(dialog), TRUE);
minlen = 20;
}
else /* smartcard */ else /* smartcard */
{ {
dialog = gnome_password_dialog_new(_("VPN password required"), dialog = gnome_password_dialog_new(_("VPN password required"),
@@ -190,12 +199,18 @@ int main (int argc, char *argv[])
{ {
gnome_password_dialog_set_password(GNOME_PASSWORD_DIALOG(dialog), pass); gnome_password_dialog_set_password(GNOME_PASSWORD_DIALOG(dialog), pass);
} }
too_short_retry:
if (!gnome_password_dialog_run_and_block(GNOME_PASSWORD_DIALOG(dialog))) if (!gnome_password_dialog_run_and_block(GNOME_PASSWORD_DIALOG(dialog)))
{ {
return 1; return 1;
} }
pass = gnome_password_dialog_get_password(GNOME_PASSWORD_DIALOG(dialog)); pass = gnome_password_dialog_get_password(GNOME_PASSWORD_DIALOG(dialog));
if (minlen && strlen(pass) < minlen)
{
goto too_short_retry;
}
switch (gnome_password_dialog_get_remember(GNOME_PASSWORD_DIALOG(dialog))) switch (gnome_password_dialog_get_remember(GNOME_PASSWORD_DIALOG(dialog)))
{ {
case GNOME_PASSWORD_DIALOG_REMEMBER_NOTHING: case GNOME_PASSWORD_DIALOG_REMEMBER_NOTHING:
@@ -244,4 +259,3 @@ int main (int argc, char *argv[])
wait_for_quit (); wait_for_quit ();
return 0; return 0;
} }
+1 -1
View File
@@ -1,5 +1,5 @@
# List of source files containing translatable strings. # List of source files containing translatable strings.
# Please keep this file sorted alphabetically. # Please keep this file sorted alphabetically.
properties/nm-strongswan.c properties/nm-strongswan.c
properties/nm-strongswan-dialog.ui [type: gettext/glade]properties/nm-strongswan-dialog.ui
auth-dialog/main.c auth-dialog/main.c
+83 -76
View File
@@ -6,19 +6,20 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: NetworkManager-strongswan\n" "Project-Id-Version: NetworkManager-strongswan\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2010-08-11 16:12+0200\n" "POT-Creation-Date: 2013-11-25 18:14+0100\n"
"PO-Revision-Date: 2010-02-18 09:20+0100\n" "PO-Revision-Date: 2010-02-18 09:20+0100\n"
"Last-Translator: Martin Willi <[email protected]>\n" "Last-Translator: Martin Willi <[email protected]>\n"
"Language-Team: de <[email protected]>\n" "Language-Team: de <[email protected]>\n"
"Language: German\n"
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
#: ../properties/nm-strongswan.c:38 #: ../properties/nm-strongswan.c:37
msgid "IPsec/IKEv2 (strongswan)" msgid "IPsec/IKEv2 (strongswan)"
msgstr "IPsec/IKEv2 (strongswan)" msgstr "IPsec/IKEv2 (strongswan)"
#: ../properties/nm-strongswan.c:39 #: ../properties/nm-strongswan.c:38
msgid "IPsec with the IKEv2 key exchange protocol." msgid "IPsec with the IKEv2 key exchange protocol."
msgstr "IPsec mit dem IKEv2 Protokoll." msgstr "IPsec mit dem IKEv2 Protokoll."
@@ -38,47 +39,27 @@ msgstr "Smartcard"
msgid "EAP" msgid "EAP"
msgstr "EAP" msgstr "EAP"
#: ../properties/nm-strongswan-dialog.glade.h:1 #: ../properties/nm-strongswan.c:212
msgid "<b>Client</b>" msgid "Pre-shared key"
msgstr "<b>Client</b>" msgstr "Pre-shared Key"
#: ../properties/nm-strongswan-dialog.glade.h:2 #: ../properties/nm-strongswan-dialog.ui.h:1
msgid "<b>Gateway</b>" msgid "<b>Gateway</b>"
msgstr "<b>Gateway</b>" msgstr "<b>Gateway</b>"
#: ../properties/nm-strongswan-dialog.glade.h:3 #: ../properties/nm-strongswan-dialog.ui.h:2
msgid "<b>Options</b>" msgid "_Address:"
msgstr "<b>Optionen</b>" msgstr "_Adresse:"
#: ../properties/nm-strongswan-dialog.glade.h:4 #: ../properties/nm-strongswan-dialog.ui.h:3
msgid "An IP address or hostname the Gateway can be contacted." msgid "An IP address or hostname the Gateway can be contacted."
msgstr "Ein IP-Adresse oder einen Rechnernamen des Gateways." msgstr "Ein IP-Adresse oder einen Rechnernamen des Gateways."
#: ../properties/nm-strongswan-dialog.glade.h:5 #: ../properties/nm-strongswan-dialog.ui.h:4
msgid "Au_thentication:"
msgstr "Au_thentisierung:"
#: ../properties/nm-strongswan-dialog.glade.h:6
msgid "Authentication Method to use for authentication against the Gateway. "
msgstr "Methode zur Authentisierung gegenüber dem Gateway."
#: ../properties/nm-strongswan-dialog.glade.h:7
msgid "C_ertificate:" msgid "C_ertificate:"
msgstr "Z_ertifikat:" msgstr "Z_ertifikat:"
#: ../properties/nm-strongswan-dialog.glade.h:8 #: ../properties/nm-strongswan-dialog.ui.h:5
msgid "Ce_rtificate:"
msgstr "Ze_rtifikat:"
#: ../properties/nm-strongswan-dialog.glade.h:9
msgid "Client certificate to use for client authentication."
msgstr "Zertifikat des Clients für dessen Authentisierung."
#: ../properties/nm-strongswan-dialog.glade.h:10
msgid "En_force UDP encapsulation"
msgstr "Erzwingen einer zusätzlichen Einbettung der Datenpakete in _UDP"
#: ../properties/nm-strongswan-dialog.glade.h:11
msgid "" msgid ""
"Gateway or CA certificate to use for gateway authentication. If none is " "Gateway or CA certificate to use for gateway authentication. If none is "
"specified, pre-installed CA certificates are used." "specified, pre-installed CA certificates are used."
@@ -86,19 +67,11 @@ msgstr ""
"Gateway- oder CA-Zertifikat für die Authentisierung des Gateways. Ohne " "Gateway- oder CA-Zertifikat für die Authentisierung des Gateways. Ohne "
"Angabe eines Zertifikates werden die CA-Zertifikate des Systems verwendet." "Angabe eines Zertifikates werden die CA-Zertifikate des Systems verwendet."
#: ../properties/nm-strongswan-dialog.glade.h:12 #: ../properties/nm-strongswan-dialog.ui.h:6
msgid "" msgid "<b>Client</b>"
"IPComp compresses raw IP packets before they get encrypted. This saves some " msgstr "<b>Client</b>"
"bandwidth, but uses more processing power."
msgstr ""
"IPComp komprimiert IP-Pakete, bevor sie verschlüsselt werden. Diese Option "
"kann Bandbreite sparen, benötigt jedoch zusätzliche Rechenleistung."
#: ../properties/nm-strongswan-dialog.glade.h:13 #: ../properties/nm-strongswan-dialog.ui.h:7
msgid "Private _key:"
msgstr "Privater _Schlüssel:"
#: ../properties/nm-strongswan-dialog.glade.h:14
msgid "" msgid ""
"Private key to use for client authentication. This key has to match the " "Private key to use for client authentication. This key has to match the "
"certificates public key and may be encrypted." "certificates public key and may be encrypted."
@@ -106,20 +79,39 @@ msgstr ""
"Privater Schlüssel für die Authentisierung des Clients. Dieser Schlüssel " "Privater Schlüssel für die Authentisierung des Clients. Dieser Schlüssel "
"muss zum konfigurierten Zertifikat passen und kann verschlüsselt sein." "muss zum konfigurierten Zertifikat passen und kann verschlüsselt sein."
#: ../properties/nm-strongswan-dialog.glade.h:15 #: ../properties/nm-strongswan-dialog.ui.h:8
msgid "Private _key:"
msgstr "Privater _Schlüssel:"
#: ../properties/nm-strongswan-dialog.ui.h:9
msgid "Au_thentication:"
msgstr "Au_thentisierung:"
#: ../properties/nm-strongswan-dialog.ui.h:10
msgid "_Username:"
msgstr "_Benutzername:"
#: ../properties/nm-strongswan-dialog.ui.h:11
msgid "The username (identity) to use for authentication against the gateway."
msgstr "Benutzername/Identität für die Authentisierung gegenüber dem Gateway."
#: ../properties/nm-strongswan-dialog.ui.h:12
msgid "Ce_rtificate:"
msgstr "Ze_rtifikat:"
#: ../properties/nm-strongswan-dialog.ui.h:13
msgid "Client certificate to use for client authentication."
msgstr "Zertifikat des Clients für dessen Authentisierung."
#: ../properties/nm-strongswan-dialog.ui.h:14
msgid "<b>Options</b>"
msgstr "<b>Optionen</b>"
#: ../properties/nm-strongswan-dialog.ui.h:15
msgid "Request an _inner IP address" msgid "Request an _inner IP address"
msgstr "_Innere IP-Adresse beziehen" msgstr "_Innere IP-Adresse beziehen"
#: ../properties/nm-strongswan-dialog.glade.h:16 #: ../properties/nm-strongswan-dialog.ui.h:16
msgid ""
"Some firewalls block ESP traffic. Enforcing UDP capsulation even if no NAT "
"situation is detected might help in such cases."
msgstr ""
"Manche Firewalls blockieren Datenverkehr mit dem ESP-Protokoll. Das "
"erzwingen einer zustzlichen Einbettung in UDP, auch wenn kein NAT-Router "
"detektiert wurde, kann in solchen Situationen hilfreich sein."
#: ../properties/nm-strongswan-dialog.glade.h:17
msgid "" msgid ""
"The Gateway may provide addresses from a pool to use for communication in " "The Gateway may provide addresses from a pool to use for communication in "
"the Gateways network. Check to request such an address." "the Gateways network. Check to request such an address."
@@ -128,46 +120,61 @@ msgstr ""
"Kommunikation im dahinterliegenden Netz verwenden kann. Aktivieren, um eine " "Kommunikation im dahinterliegenden Netz verwenden kann. Aktivieren, um eine "
"solche Adresse zu beziehen." "solche Adresse zu beziehen."
#: ../properties/nm-strongswan-dialog.glade.h:18 #: ../properties/nm-strongswan-dialog.ui.h:17
msgid "The username (identity) to use for authentication against the gateway." msgid "En_force UDP encapsulation"
msgstr "Benutzername/Identität für die Authentisierung gegenüber dem Gateway." msgstr "Erzwingen einer zusätzlichen Einbettung der Datenpakete in _UDP"
#: ../properties/nm-strongswan-dialog.glade.h:19 #: ../properties/nm-strongswan-dialog.ui.h:18
msgid ""
"Some firewalls block ESP traffic. Enforcing UDP capsulation even if no NAT "
"situation is detected might help in such cases."
msgstr ""
"Manche Firewalls blockieren Datenverkehr mit dem ESP-Protokoll. Das "
"erzwingen einer zustzlichen Einbettung in UDP, auch wenn kein NAT-Router "
"detektiert wurde, kann in solchen Situationen hilfreich sein."
#: ../properties/nm-strongswan-dialog.ui.h:19
msgid "Use IP c_ompression" msgid "Use IP c_ompression"
msgstr "IP-Pakete k_omprimieren" msgstr "IP-Pakete k_omprimieren"
#: ../properties/nm-strongswan-dialog.glade.h:20 #: ../properties/nm-strongswan-dialog.ui.h:20
msgid "_Address:" msgid ""
msgstr "_Adresse:" "IPComp compresses raw IP packets before they get encrypted. This saves some "
"bandwidth, but uses more processing power."
msgstr ""
"IPComp komprimiert IP-Pakete, bevor sie verschlüsselt werden. Diese Option "
"kann Bandbreite sparen, benötigt jedoch zusätzliche Rechenleistung."
#: ../properties/nm-strongswan-dialog.glade.h:21 #: ../auth-dialog/main.c:170 ../auth-dialog/main.c:177
msgid "_Username:" #: ../auth-dialog/main.c:184 ../auth-dialog/main.c:191
msgstr "_Benutzername:"
#: ../auth-dialog/main.c:172 ../auth-dialog/main.c:179
#: ../auth-dialog/main.c:186
msgid "VPN password required" msgid "VPN password required"
msgstr "VPN Passwort notwendig" msgstr "VPN Passwort notwendig"
#: ../auth-dialog/main.c:173 #: ../auth-dialog/main.c:171
msgid "EAP password required to establish VPN connection:" msgid "EAP password required to establish VPN connection:"
msgstr "Für die Erstellung des VPN-Tunnels ist ein EAP-Passwort erforderlich:" msgstr "Für die Erstellung des VPN-Tunnels ist ein EAP-Passwort erforderlich:"
#: ../auth-dialog/main.c:180 #: ../auth-dialog/main.c:178
msgid "Private key decryption password required to establish VPN connection:" msgid "Private key decryption password required to establish VPN connection:"
msgstr "" msgstr ""
"Der Private Schlüssel für die Erstellung des VPN-Tunnels ist durch ein " "Der Private Schlüssel für die Erstellung des VPN-Tunnels ist durch ein "
"Passwort geschützt:" "Passwort geschützt:"
#: ../auth-dialog/main.c:187 #: ../auth-dialog/main.c:185
#, fuzzy msgid ""
"Pre-shared key required to establish VPN connection (min. 20 characters):"
msgstr ""
"Für die Erstellung des VPN-Tunnels ist ein Pre-shared Key erforderlich (min. "
"20 Zeichen):"
#: ../auth-dialog/main.c:192
msgid "Smartcard PIN required to establish VPN connection:" msgid "Smartcard PIN required to establish VPN connection:"
msgstr "Für die Smartcard ist eine PIN erforderlich:" msgstr "Für die Smartcard ist eine PIN erforderlich:"
#: ../auth-dialog/main.c:233 #: ../auth-dialog/main.c:242
msgid "" msgid ""
"Configuration uses ssh-agent for authentication, but ssh-agent is not " "Configuration uses ssh-agent for authentication, but ssh-agent is not "
"running!" "running!"
msgstr "" msgstr ""
"Die Konfiguration verwendet ssh-agent fr die Authentisierung, aber ssh-agent " "Die Konfiguration verwendet ssh-agent für die Authentisierung, aber ssh-"
"ist nicht gestartet!" "agent ist nicht gestartet!"
+14 -2
View File
@@ -1,4 +1,5 @@
/* /*
* Copyright (C) 2013 Tobias Brunner
* Copyright (C) 2008 Martin Willi * Copyright (C) 2008 Martin Willi
* Hochschule fuer Technik Rapperswil * Hochschule fuer Technik Rapperswil
* Copyright (C) 2005 David Zeuthen * Copyright (C) 2005 David Zeuthen
@@ -30,7 +31,6 @@
#include <nm-vpn-plugin-ui-interface.h> #include <nm-vpn-plugin-ui-interface.h>
#include <nm-setting-vpn.h> #include <nm-setting-vpn.h>
#include <nm-setting-connection.h> #include <nm-setting-connection.h>
#include <nm-setting-ip4-config.h>
#include "nm-strongswan.h" #include "nm-strongswan.h"
@@ -149,6 +149,7 @@ static void update_layout (GtkWidget *widget, StrongswanPluginUiWidgetPrivate *p
gtk_widget_hide (GTK_WIDGET (gtk_builder_get_object (priv->builder, "userkey-button"))); gtk_widget_hide (GTK_WIDGET (gtk_builder_get_object (priv->builder, "userkey-button")));
break; break;
case 3: case 3:
case 4:
gtk_widget_show (GTK_WIDGET (gtk_builder_get_object (priv->builder, "user-label"))); gtk_widget_show (GTK_WIDGET (gtk_builder_get_object (priv->builder, "user-label")));
gtk_widget_show (GTK_WIDGET (gtk_builder_get_object (priv->builder, "user-entry"))); gtk_widget_show (GTK_WIDGET (gtk_builder_get_object (priv->builder, "user-entry")));
gtk_widget_hide (GTK_WIDGET (gtk_builder_get_object (priv->builder, "usercert-label"))); gtk_widget_hide (GTK_WIDGET (gtk_builder_get_object (priv->builder, "usercert-label")));
@@ -208,6 +209,7 @@ init_plugin_ui (StrongswanPluginUiWidget *self, NMConnection *connection, GError
gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (widget), _("Certificate/ssh-agent")); gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (widget), _("Certificate/ssh-agent"));
gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (widget), _("Smartcard")); gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (widget), _("Smartcard"));
gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (widget), _("EAP")); gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (widget), _("EAP"));
gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (widget), _("Pre-shared key"));
value = nm_setting_vpn_get_data_item (settings, "method"); value = nm_setting_vpn_get_data_item (settings, "method");
if (value) { if (value) {
if (g_strcmp0 (value, "key") == 0) { if (g_strcmp0 (value, "key") == 0) {
@@ -222,6 +224,9 @@ init_plugin_ui (StrongswanPluginUiWidget *self, NMConnection *connection, GError
if (g_strcmp0 (value, "eap") == 0) { if (g_strcmp0 (value, "eap") == 0) {
gtk_combo_box_set_active (GTK_COMBO_BOX (widget), 3); gtk_combo_box_set_active (GTK_COMBO_BOX (widget), 3);
} }
if (g_strcmp0 (value, "psk") == 0) {
gtk_combo_box_set_active (GTK_COMBO_BOX (widget), 4);
}
} }
if (gtk_combo_box_get_active (GTK_COMBO_BOX (widget)) == -1) if (gtk_combo_box_get_active (GTK_COMBO_BOX (widget)) == -1)
{ {
@@ -351,6 +356,14 @@ update_connection (NMVpnPluginUiWidgetInterface *iface,
} }
str = "eap"; str = "eap";
break; break;
case 4:
widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "user-entry"));
str = (char *) gtk_entry_get_text (GTK_ENTRY (widget));
if (str && strlen (str)) {
nm_setting_vpn_add_data_item (settings, "user", str);
}
str = "psk";
break;
} }
nm_setting_vpn_add_data_item (settings, "method", str); nm_setting_vpn_add_data_item (settings, "method", str);
@@ -536,4 +549,3 @@ nm_vpn_plugin_ui_factory (GError **error)
return NM_VPN_PLUGIN_UI_INTERFACE (g_object_new (STRONGSWAN_TYPE_PLUGIN_UI, NULL)); return NM_VPN_PLUGIN_UI_INTERFACE (g_object_new (STRONGSWAN_TYPE_PLUGIN_UI, NULL));
} }