ifnet: fix srcdir != builddir issue with certificate paths

If the certificate path from the supplicant config is not absolute,
we need to make it absolute.  When building with a different builddir,
the certificate from the supplicant config is actually in the srcdir,
but the builddir is the current PWD.
This commit is contained in:
Dan Williams
2012-11-30 12:33:21 -06:00
parent 2e6cad94f3
commit e609ca05a2
5 changed files with 70 additions and 44 deletions

View File

@@ -75,24 +75,28 @@ static gboolean eap_simple_reader (const char *eap_method,
const char *ssid, const char *ssid,
NMSetting8021x *s_8021x, NMSetting8021x *s_8021x,
gboolean phase2, gboolean phase2,
const char *basepath,
GError **error); GError **error);
static gboolean eap_tls_reader (const char *eap_method, static gboolean eap_tls_reader (const char *eap_method,
const char *ssid, const char *ssid,
NMSetting8021x *s_8021x, NMSetting8021x *s_8021x,
gboolean phase2, gboolean phase2,
const char *basepath,
GError **error); GError **error);
static gboolean eap_peap_reader (const char *eap_method, static gboolean eap_peap_reader (const char *eap_method,
const char *ssid, const char *ssid,
NMSetting8021x *s_8021x, NMSetting8021x *s_8021x,
gboolean phase2, gboolean phase2,
const char *basepath,
GError **error); GError **error);
static gboolean eap_ttls_reader (const char *eap_method, static gboolean eap_ttls_reader (const char *eap_method,
const char *ssid, const char *ssid,
NMSetting8021x *s_8021x, NMSetting8021x *s_8021x,
gboolean phase2, gboolean phase2,
const char *basepath,
GError **error); GError **error);
typedef struct { typedef struct {
@@ -101,6 +105,7 @@ typedef struct {
const char *ssid, const char *ssid,
NMSetting8021x *s_8021x, NMSetting8021x *s_8021x,
gboolean phase2, gboolean phase2,
const char *basepath,
GError **error); GError **error);
gboolean wifi_phase2_only; gboolean wifi_phase2_only;
} EAPReader; } EAPReader;
@@ -124,6 +129,7 @@ eap_simple_reader (const char *eap_method,
const char *ssid, const char *ssid,
NMSetting8021x *s_8021x, NMSetting8021x *s_8021x,
gboolean phase2, gboolean phase2,
const char *basepath,
GError **error) GError **error)
{ {
const char *value; const char *value;
@@ -152,17 +158,30 @@ eap_simple_reader (const char *eap_method,
return TRUE; return TRUE;
} }
static char *
get_cert (const char *ssid, const char *key, const char *basepath)
{
const char *orig;
/* If it's a relative path, convert to absolute using 'basepath' */
orig = wpa_get_value (ssid, key);
if (g_path_is_absolute (orig))
return g_strdup (orig);
return g_strdup_printf ("%s/%s", basepath, orig);
}
static gboolean static gboolean
eap_tls_reader (const char *eap_method, eap_tls_reader (const char *eap_method,
const char *ssid, const char *ssid,
NMSetting8021x *s_8021x, NMSetting8021x *s_8021x,
gboolean phase2, gboolean phase2,
const char *basepath,
GError **error) GError **error)
{ {
const char *value; const char *value;
const char *ca_cert = NULL; char *ca_cert = NULL;
const char *client_cert = NULL; char *client_cert = NULL;
const char *privkey = NULL; char *privkey = NULL;
const char *privkey_password = NULL; const char *privkey_password = NULL;
gboolean success = FALSE; gboolean success = FALSE;
NMSetting8021xCKFormat privkey_format = NM_SETTING_802_1X_CK_FORMAT_UNKNOWN; NMSetting8021xCKFormat privkey_format = NM_SETTING_802_1X_CK_FORMAT_UNKNOWN;
@@ -178,7 +197,7 @@ eap_tls_reader (const char *eap_method,
g_object_set (s_8021x, NM_SETTING_802_1X_IDENTITY, value, NULL); g_object_set (s_8021x, NM_SETTING_802_1X_IDENTITY, value, NULL);
/* ca cert */ /* ca cert */
ca_cert = wpa_get_value (ssid, phase2 ? "ca_cert2" : "ca_cert"); ca_cert = get_cert (ssid, phase2 ? "ca_cert2" : "ca_cert", basepath);
if (ca_cert) { if (ca_cert) {
if (phase2) { if (phase2) {
if (!nm_setting_802_1x_set_phase2_ca_cert (s_8021x, if (!nm_setting_802_1x_set_phase2_ca_cert (s_8021x,
@@ -215,7 +234,7 @@ eap_tls_reader (const char *eap_method,
} }
/* The private key itself */ /* The private key itself */
privkey = wpa_get_value (ssid, phase2 ? "private_key2" : "private_key"); privkey = get_cert (ssid, phase2 ? "private_key2" : "private_key", basepath);
if (!privkey) { if (!privkey) {
g_set_error (error, ifnet_plugin_error_quark (), 0, g_set_error (error, ifnet_plugin_error_quark (), 0,
"Missing %s for EAP method '%s'.", "Missing %s for EAP method '%s'.",
@@ -248,9 +267,7 @@ eap_tls_reader (const char *eap_method,
*/ */
if (privkey_format == NM_SETTING_802_1X_CK_FORMAT_RAW_KEY if (privkey_format == NM_SETTING_802_1X_CK_FORMAT_RAW_KEY
|| privkey_format == NM_SETTING_802_1X_CK_FORMAT_X509) { || privkey_format == NM_SETTING_802_1X_CK_FORMAT_X509) {
client_cert = wpa_get_value (ssid, client_cert = get_cert (ssid, phase2 ? "client_cert2" : "client_cert", basepath);
phase2 ? "client_cert2" :
"client_cert");
if (!client_cert) { if (!client_cert) {
g_set_error (error, ifnet_plugin_error_quark (), 0, g_set_error (error, ifnet_plugin_error_quark (), 0,
"Missing %s for EAP method '%s'.", "Missing %s for EAP method '%s'.",
@@ -278,6 +295,9 @@ eap_tls_reader (const char *eap_method,
success = TRUE; success = TRUE;
done: done:
g_free (ca_cert);
g_free (client_cert);
g_free (privkey);
return success; return success;
} }
@@ -286,15 +306,16 @@ eap_peap_reader (const char *eap_method,
const char *ssid, const char *ssid,
NMSetting8021x *s_8021x, NMSetting8021x *s_8021x,
gboolean phase2, gboolean phase2,
const char *basepath,
GError **error) GError **error)
{ {
const char *ca_cert = NULL; char *ca_cert = NULL;
const char *inner_auth = NULL; const char *inner_auth = NULL;
const char *peapver = NULL; const char *peapver = NULL;
char **list = NULL, **iter, *lower; char **list = NULL, **iter, *lower;
gboolean success = FALSE; gboolean success = FALSE;
ca_cert = wpa_get_value (ssid, "ca_cert"); ca_cert = get_cert (ssid, "ca_cert", basepath);
if (ca_cert) { if (ca_cert) {
if (!nm_setting_802_1x_set_ca_cert (s_8021x, if (!nm_setting_802_1x_set_ca_cert (s_8021x,
ca_cert, ca_cert,
@@ -346,11 +367,10 @@ eap_peap_reader (const char *eap_method,
if (!(pos = strstr (*iter, "MSCHAPV2")) if (!(pos = strstr (*iter, "MSCHAPV2"))
|| !(pos = strstr (*iter, "MD5")) || !(pos = strstr (*iter, "MD5"))
|| !(pos = strstr (*iter, "GTC"))) { || !(pos = strstr (*iter, "GTC"))) {
if (!eap_simple_reader if (!eap_simple_reader (pos, ssid, s_8021x, TRUE, basepath, error))
(pos, ssid, s_8021x, TRUE, error))
goto done; goto done;
} else if (!(pos = strstr (*iter, "TLS"))) { } else if (!(pos = strstr (*iter, "TLS"))) {
if (!eap_tls_reader (pos, ssid, s_8021x, TRUE, error)) if (!eap_tls_reader (pos, ssid, s_8021x, TRUE, basepath, error))
goto done; goto done;
} else { } else {
g_set_error (error, ifnet_plugin_error_quark (), 0, g_set_error (error, ifnet_plugin_error_quark (), 0,
@@ -377,6 +397,7 @@ eap_peap_reader (const char *eap_method,
success = TRUE; success = TRUE;
done: done:
g_free (ca_cert);
if (list) if (list)
g_strfreev (list); g_strfreev (list);
return success; return success;
@@ -387,16 +408,17 @@ eap_ttls_reader (const char *eap_method,
const char *ssid, const char *ssid,
NMSetting8021x *s_8021x, NMSetting8021x *s_8021x,
gboolean phase2, gboolean phase2,
const char *basepath,
GError **error) GError **error)
{ {
gboolean success = FALSE; gboolean success = FALSE;
const char *anon_ident = NULL; const char *anon_ident = NULL;
const char *ca_cert = NULL; char *ca_cert = NULL;
const char *tmp; const char *tmp;
char **list = NULL, **iter, *inner_auth = NULL; char **list = NULL, **iter, *inner_auth = NULL;
/* ca cert */ /* ca cert */
ca_cert = wpa_get_value (ssid, "ca_cert"); ca_cert = get_cert (ssid, "ca_cert", basepath);
if (ca_cert) { if (ca_cert) {
if (!nm_setting_802_1x_set_ca_cert (s_8021x, if (!nm_setting_802_1x_set_ca_cert (s_8021x,
ca_cert, ca_cert,
@@ -434,20 +456,18 @@ eap_ttls_reader (const char *eap_method,
|| (pos = strstr (*iter, "mschap")) != NULL || (pos = strstr (*iter, "mschap")) != NULL
|| (pos = strstr (*iter, "pap")) != NULL || (pos = strstr (*iter, "pap")) != NULL
|| (pos = strstr (*iter, "chap")) != NULL) { || (pos = strstr (*iter, "chap")) != NULL) {
if (!eap_simple_reader if (!eap_simple_reader (pos, ssid, s_8021x, TRUE, basepath, error))
(pos, ssid, s_8021x, TRUE, error))
goto done; goto done;
g_object_set (s_8021x, NM_SETTING_802_1X_PHASE2_AUTH, g_object_set (s_8021x, NM_SETTING_802_1X_PHASE2_AUTH,
pos, NULL); pos, NULL);
} else if ((pos = strstr (*iter, "tls")) != NULL) { } else if ((pos = strstr (*iter, "tls")) != NULL) {
if (!eap_tls_reader (pos, ssid, s_8021x, TRUE, error)) if (!eap_tls_reader (pos, ssid, s_8021x, TRUE, basepath, error))
goto done; goto done;
g_object_set (s_8021x, NM_SETTING_802_1X_PHASE2_AUTHEAP, g_object_set (s_8021x, NM_SETTING_802_1X_PHASE2_AUTHEAP,
"tls", NULL); "tls", NULL);
} else if ((pos = strstr (*iter, "mschapv2")) != NULL } else if ((pos = strstr (*iter, "mschapv2")) != NULL
|| (pos = strstr (*iter, "md5")) != NULL) { || (pos = strstr (*iter, "md5")) != NULL) {
if (!eap_simple_reader if (!eap_simple_reader (pos, ssid, s_8021x, TRUE, basepath, error)) {
(pos, ssid, s_8021x, TRUE, error)) {
PLUGIN_WARN (IFNET_PLUGIN_NAME, "SIMPLE ERROR"); PLUGIN_WARN (IFNET_PLUGIN_NAME, "SIMPLE ERROR");
goto done; goto done;
} }
@@ -464,6 +484,7 @@ eap_ttls_reader (const char *eap_method,
success = TRUE; success = TRUE;
done: done:
g_free (ca_cert);
if (list) if (list)
g_strfreev (list); g_strfreev (list);
g_free (inner_auth); g_free (inner_auth);
@@ -1385,6 +1406,7 @@ static NMSetting8021x *
fill_8021x (const char *ssid, fill_8021x (const char *ssid,
const char *key_mgmt, const char *key_mgmt,
gboolean wifi, gboolean wifi,
const char *basepath,
GError **error) GError **error)
{ {
NMSetting8021x *s_8021x; NMSetting8021x *s_8021x;
@@ -1426,8 +1448,7 @@ fill_8021x (const char *ssid,
} }
/* Parse EAP method specific options */ /* Parse EAP method specific options */
if (!(*eap->reader) if (!(*eap->reader) (lower, ssid, s_8021x, FALSE, basepath, error)) {
(lower, ssid, s_8021x, FALSE, error)) {
g_free (lower); g_free (lower);
goto error; goto error;
} }
@@ -1462,6 +1483,7 @@ error:
static NMSettingWirelessSecurity * static NMSettingWirelessSecurity *
make_wpa_setting (const char *ssid, make_wpa_setting (const char *ssid,
const char *basepath,
NMSetting8021x **s_8021x, NMSetting8021x **s_8021x,
GError **error) GError **error)
{ {
@@ -1476,8 +1498,7 @@ make_wpa_setting (const char *ssid,
return NULL; return NULL;
} }
wsec = wsec = NM_SETTING_WIRELESS_SECURITY (nm_setting_wireless_security_new ());
NM_SETTING_WIRELESS_SECURITY (nm_setting_wireless_security_new ());
/* mode=1: adhoc /* mode=1: adhoc
* mode=0: infrastructure */ * mode=0: infrastructure */
@@ -1529,7 +1550,7 @@ make_wpa_setting (const char *ssid,
value); value);
goto error; goto error;
} }
*s_8021x = fill_8021x (ssid, value, TRUE, error); *s_8021x = fill_8021x (ssid, value, TRUE, basepath, error);
if (!*s_8021x) if (!*s_8021x)
goto error; goto error;
@@ -1551,6 +1572,7 @@ error:
static NMSettingWirelessSecurity * static NMSettingWirelessSecurity *
make_wireless_security_setting (const char *conn_name, make_wireless_security_setting (const char *conn_name,
const char *basepath,
NMSetting8021x **s_8021x, NMSetting8021x **s_8021x,
GError ** error) GError ** error)
{ {
@@ -1578,7 +1600,7 @@ make_wireless_security_setting (const char *conn_name,
goto error; goto error;
} }
if (!wsec) { if (!wsec) {
wsec = make_wpa_setting (ssid, s_8021x, error); wsec = make_wpa_setting (ssid, basepath, s_8021x, error);
if (error && *error) if (error && *error)
goto error; goto error;
} }
@@ -1635,7 +1657,9 @@ make_pppoe_connection_setting (NMConnection *connection,
} }
NMConnection * NMConnection *
ifnet_update_connection_from_config_block (const char *conn_name, GError **error) ifnet_update_connection_from_config_block (const char *conn_name,
const char *basepath,
GError **error)
{ {
const gchar *type = NULL; const gchar *type = NULL;
NMConnection *connection = NULL; NMConnection *connection = NULL;
@@ -1699,7 +1723,7 @@ ifnet_update_connection_from_config_block (const char *conn_name, GError **error
} }
/* wireless security setting */ /* wireless security setting */
wsec = make_wireless_security_setting (conn_name, &s_8021x, error); wsec = make_wireless_security_setting (conn_name, basepath, &s_8021x, error);
if (wsec) { if (wsec) {
nm_connection_add_setting (connection, nm_connection_add_setting (connection,
NM_SETTING (wsec)); NM_SETTING (wsec));

View File

@@ -25,6 +25,7 @@
#include "net_parser.h" #include "net_parser.h"
NMConnection *ifnet_update_connection_from_config_block (const char *conn_name, NMConnection *ifnet_update_connection_from_config_block (const char *conn_name,
const char *basepath,
GError **error); GError **error);
/* nm_conn_name is used to update nm_ifnet_connection's priv data */ /* nm_conn_name is used to update nm_ifnet_connection's priv data */

View File

@@ -68,7 +68,7 @@ nm_ifnet_connection_new (const char *conn_name, NMConnection *source)
if (source) if (source)
tmp = g_object_ref (source); tmp = g_object_ref (source);
else { else {
tmp = ifnet_update_connection_from_config_block (conn_name, &error); tmp = ifnet_update_connection_from_config_block (conn_name, NULL, &error);
if (!tmp){ if (!tmp){
g_error_free (error); g_error_free (error);
return NULL; return NULL;

View File

@@ -29,6 +29,7 @@ EXTRA_DIST = \
net \ net \
net.all \ net.all \
nm-system-settings.conf \ nm-system-settings.conf \
wpa_supplicant.conf wpa_supplicant.conf \
test_ca_cert.pem
endif endif

View File

@@ -274,31 +274,31 @@ test_new_connection ()
GError *error = NULL; GError *error = NULL;
NMConnection *connection; NMConnection *connection;
connection = ifnet_update_connection_from_config_block ("eth2", &error); connection = ifnet_update_connection_from_config_block ("eth2", NULL, &error);
ASSERT (connection != NULL, "new connection", ASSERT (connection != NULL, "new connection",
"new connection failed: %s", "new connection failed: %s",
error ? error->message : "None"); error ? error->message : "None");
g_object_unref (connection); g_object_unref (connection);
connection = ifnet_update_connection_from_config_block ("qiaomuf", &error); connection = ifnet_update_connection_from_config_block ("qiaomuf", NULL, &error);
ASSERT (connection != NULL, "new connection", ASSERT (connection != NULL, "new connection",
"new connection failed: %s", "new connection failed: %s",
error ? error->message : "NONE"); error ? error->message : "NONE");
g_object_unref (connection); g_object_unref (connection);
connection = ifnet_update_connection_from_config_block ("myxjtu2", &error); connection = ifnet_update_connection_from_config_block ("myxjtu2", NULL, &error);
ASSERT (connection != NULL, "new connection", ASSERT (connection != NULL, "new connection",
"new connection failed: %s", "new connection failed: %s",
error ? error->message : "NONE"); error ? error->message : "NONE");
g_object_unref (connection); g_object_unref (connection);
connection = ifnet_update_connection_from_config_block ("eth9", &error); connection = ifnet_update_connection_from_config_block ("eth9", NULL, &error);
ASSERT (connection != NULL, "new connection", ASSERT (connection != NULL, "new connection",
"new connection(eth9) failed: %s", "new connection(eth9) failed: %s",
error ? error->message : "NONE"); error ? error->message : "NONE");
g_object_unref (connection); g_object_unref (connection);
connection = ifnet_update_connection_from_config_block ("eth10", &error); connection = ifnet_update_connection_from_config_block ("eth10", NULL, &error);
ASSERT (connection != NULL, "new connection", ASSERT (connection != NULL, "new connection",
"new connection(eth10) failed: %s", "new connection(eth10) failed: %s",
error ? error->message : "NONE"); error ? error->message : "NONE");
@@ -309,13 +309,13 @@ test_new_connection ()
#define SUP_GEN_NAME "wpa_supplicant.conf.generate" #define SUP_GEN_NAME "wpa_supplicant.conf.generate"
static void static void
test_update_connection () test_update_connection (const char *basepath)
{ {
GError *error = NULL; GError *error = NULL;
NMConnection *connection; NMConnection *connection;
gboolean success; gboolean success;
connection = ifnet_update_connection_from_config_block ("eth0", &error); connection = ifnet_update_connection_from_config_block ("eth0", basepath, &error);
ASSERT (connection != NULL, "get connection", ASSERT (connection != NULL, "get connection",
"get connection failed: %s", "get connection failed: %s",
error ? error->message : "None"); error ? error->message : "None");
@@ -328,7 +328,7 @@ test_update_connection ()
ASSERT (success, "update connection", "update connection failed %s", "eth0"); ASSERT (success, "update connection", "update connection failed %s", "eth0");
g_object_unref (connection); g_object_unref (connection);
connection = ifnet_update_connection_from_config_block ("0xab3ace", &error); connection = ifnet_update_connection_from_config_block ("0xab3ace", basepath, &error);
ASSERT (connection != NULL, "get connection", "get connection failed: %s", ASSERT (connection != NULL, "get connection", "get connection failed: %s",
error ? error->message : "None"); error ? error->message : "None");
@@ -349,11 +349,11 @@ test_add_connection ()
{ {
NMConnection *connection; NMConnection *connection;
connection = ifnet_update_connection_from_config_block ("eth0", NULL); connection = ifnet_update_connection_from_config_block ("eth0", NULL, NULL);
ASSERT (ifnet_add_new_connection (connection, NET_GEN_NAME, SUP_GEN_NAME, NULL), ASSERT (ifnet_add_new_connection (connection, NET_GEN_NAME, SUP_GEN_NAME, NULL),
"add connection", "add connection failed: %s", "eth0"); "add connection", "add connection failed: %s", "eth0");
g_object_unref (connection); g_object_unref (connection);
connection = ifnet_update_connection_from_config_block ("myxjtu2", NULL); connection = ifnet_update_connection_from_config_block ("myxjtu2", NULL, NULL);
ASSERT (ifnet_add_new_connection (connection, NET_GEN_NAME, SUP_GEN_NAME, NULL), ASSERT (ifnet_add_new_connection (connection, NET_GEN_NAME, SUP_GEN_NAME, NULL),
"add connection", "add connection failed: %s", "myxjtu2"); "add connection", "add connection failed: %s", "myxjtu2");
g_object_unref (connection); g_object_unref (connection);
@@ -368,14 +368,14 @@ test_delete_connection ()
GError *error = NULL; GError *error = NULL;
NMConnection *connection; NMConnection *connection;
connection = ifnet_update_connection_from_config_block ("eth7", &error); connection = ifnet_update_connection_from_config_block ("eth7", NULL, &error);
ASSERT (connection != NULL, "get connection", ASSERT (connection != NULL, "get connection",
"get connection failed: %s", "get connection failed: %s",
error ? error->message : "None"); error ? error->message : "None");
ASSERT (ifnet_delete_connection_in_parsers ("eth7", NET_GEN_NAME, SUP_GEN_NAME), ASSERT (ifnet_delete_connection_in_parsers ("eth7", NET_GEN_NAME, SUP_GEN_NAME),
"delete connection", "delete connection failed: %s", "eth7"); "delete connection", "delete connection failed: %s", "eth7");
g_object_unref (connection); g_object_unref (connection);
connection = ifnet_update_connection_from_config_block ("qiaomuf", &error); connection = ifnet_update_connection_from_config_block ("qiaomuf", NULL, &error);
ASSERT (connection != NULL, "get connection", ASSERT (connection != NULL, "get connection",
"get connection failed: %s", "get connection failed: %s",
error ? error->message : "None"); error ? error->message : "None");
@@ -393,7 +393,7 @@ test_missing_config ()
GError *error = NULL; GError *error = NULL;
NMConnection *connection; NMConnection *connection;
connection = ifnet_update_connection_from_config_block ("eth8", &error); connection = ifnet_update_connection_from_config_block ("eth8", NULL, &error);
ASSERT (connection == NULL && error != NULL, "get connection", ASSERT (connection == NULL && error != NULL, "get connection",
"get connection should fail with 'Unknown config for eth8'"); "get connection should fail with 'Unknown config for eth8'");
} }
@@ -428,7 +428,7 @@ main (int argc, char **argv)
test_wpa_parser (); test_wpa_parser ();
test_convert_ipv4_routes_block (); test_convert_ipv4_routes_block ();
test_new_connection (); test_new_connection ();
test_update_connection (); test_update_connection (argv[1]);
test_add_connection (); test_add_connection ();
test_delete_connection (); test_delete_connection ();
test_missing_config (); test_missing_config ();