about summary refs log tree commit diff
path: root/debian/patches/07-duid-fallback.patch
blob: 6f07235d1095570015df92417c8f09746cb0393a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
commit 0bf0ee7136dff2b9a6435221987f447e11eea285
Author: Dan Williams <dcbw@redhat.com>
Date:   Fri Mar 15 16:49:39 2013 -0500

    dhcp: look harder for machine-id, and generate random DUID if it doesn't exist (bgo #696109)
    
    Not all systems have machine-id in /etc, some still have it in /var/lib/dbus/
    especially if they aren't using systemd.  Furthermore, if we don't have
    any machine-id file (like in the future, if we don't have a messaebus
    daemon running) fall back to a random DUID as a last resort.

Index: network-manager/src/dhcp-manager/nm-dhcp-client.c
===================================================================
--- network-manager.orig/src/dhcp-manager/nm-dhcp-client.c	2013-05-08 20:19:08.998435531 +0200
+++ network-manager/src/dhcp-manager/nm-dhcp-client.c	2013-05-08 20:19:08.994435487 +0200
@@ -354,40 +354,44 @@
 {
 	GByteArray *duid;
 	char *contents = NULL;
-	GError *error = NULL;
 	GChecksum *sum;
 	guint8 buffer[32]; /* SHA256 digest size */
 	gsize sumlen = sizeof (buffer);
 	const guint16 duid_type = g_htons (4);
 	uuid_t uuid;
-	gboolean success;
+	GRand *rand;
+	guint i;
+	gboolean success = FALSE;
 
 	/* Get the machine ID from /etc/machine-id; it's always in /etc no matter
-	 * where our configured SYSCONFDIR is.
+	 * where our configured SYSCONFDIR is.  Alternatively, it might be in
+	 * LOCALSTATEDIR /lib/dbus/machine-id.
 	 */
-	if (!g_file_get_contents ("/etc/machine-id", &contents, NULL, &error)) {
-		nm_log_warn (LOGD_DHCP6, "Failed to read " SYSCONFDIR "/machine-id to generate DHCPv6 DUID: (%d) %s",
-			         error ? error->code : -1,
-			         error ? error->message : "(unknown)");
-		g_clear_error (&error);
-		return NULL;
+	if (   g_file_get_contents ("/etc/machine-id", &contents, NULL, NULL)
+	    || g_file_get_contents (LOCALSTATEDIR "/lib/dbus/machine-id", &contents, NULL, NULL)) {
+		contents = g_strstrip (contents);
+		success = machine_id_parse (contents, uuid);
+		if (success) {
+			/* Hash the machine ID so it's not leaked to the network */
+			sum = g_checksum_new (G_CHECKSUM_SHA256);
+			g_checksum_update (sum, (const guchar *) &uuid, sizeof (uuid));
+			g_checksum_get_digest (sum, buffer, &sumlen);
+			g_checksum_free (sum);
+		}
+		g_free (contents);
 	}
 
-	contents = g_strstrip (contents);
-	success = machine_id_parse (contents, uuid);
-	g_free (contents);
-
 	if (!success) {
-		nm_log_warn (LOGD_DHCP6, "Failed to parse " SYSCONFDIR "/machine-id to generate DHCPv6 DUID.");
-		return NULL;
+		nm_log_warn (LOGD_DHCP6, "Failed to read " SYSCONFDIR "/machine-id "
+		             "or " LOCALSTATEDIR "/lib/dbus/machine-id to generate "
+		             "DHCPv6 DUID; creating non-persistent random DUID.");
+
+		rand = g_rand_new ();
+		for (i = 0; i < sizeof (buffer) / sizeof (guint32); i++)
+			((guint32 *) buffer)[i] = g_rand_int (rand);
+		g_rand_free (rand);
 	}
 
-	/* Hash the machine ID so it's not leaked to the network */
-	sum = g_checksum_new (G_CHECKSUM_SHA256);
-	g_checksum_update (sum, (const guchar *) &uuid, sizeof (uuid));
-	g_checksum_get_digest (sum, buffer, &sumlen);
-	g_checksum_free (sum);
-
 	/* Generate a DHCP Unique Identifier for DHCPv6 using the
 	 * DUID-UUID method (see RFC 6355 section 4).  Format is:
 	 *
@@ -431,10 +435,11 @@
 
 	if (G_UNLIKELY (duid == NULL)) {
 		duid = generate_duid_from_machine_id ();
+		g_assert (duid);
 
 		if (nm_logging_level_enabled (LOGL_DEBUG)) {
 			escaped = escape_duid (duid);
-			nm_log_dbg (LOGD_DHCP6, "Generated DUID from machine-id: %s", escaped);
+			nm_log_dbg (LOGD_DHCP6, "Generated DUID %s", escaped);
 			g_free (escaped);
 		}
 	}