1 /*
2  * Copyright (c) 2014 Balabit
3  * Copyright (c) 2014 Laszlo Budai
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2.1 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
18  *
19  * As an additional exemption you are allowed to compile & link against the
20  * OpenSSL libraries as published by the OpenSSL project. See the file
21  * COPYING for details.
22  *
23  */
24 
25 #include "host-id.h"
26 #include "str-format.h"
27 #include "messages.h"
28 #include <openssl/rand.h>
29 
30 guint32 global_host_id = 0;
31 
32 static guint32
_create_host_id(void)33 _create_host_id(void)
34 {
35   union
36   {
37     unsigned char _raw[sizeof(guint32)];
38     guint32 id;
39   } host_id;
40 
41   RAND_bytes(host_id._raw, sizeof(host_id._raw));
42 
43   return host_id.id;
44 }
45 
46 static gboolean
_load_host_id_from_legacy_persist_entry(PersistState * state,guint32 * host_id)47 _load_host_id_from_legacy_persist_entry(PersistState *state, guint32 *host_id)
48 {
49   gsize size;
50   guint8 version;
51   PersistEntryHandle handle = persist_state_lookup_entry(state, HOST_ID_LEGACY_PERSIST_KEY, &size, &version);
52 
53   if (!handle)
54     return FALSE;
55 
56   guint32 *mapped_hostid = persist_state_map_entry(state, handle);
57 
58   *host_id = *mapped_hostid;
59 
60   persist_state_unmap_entry(state, handle);
61 
62   return TRUE;
63 }
64 
65 gboolean
host_id_init(PersistState * state)66 host_id_init(PersistState *state)
67 {
68   gsize size;
69   guint8 version;
70   PersistEntryHandle handle;
71   HostIdState *host_id_state;
72   gboolean host_id_found = TRUE;
73   guint32 legacy_hostid = 0;
74 
75 
76   handle = persist_state_lookup_entry(state, HOST_ID_PERSIST_KEY, &size, &version);
77   if (handle == 0)
78     {
79       host_id_found = FALSE;
80 
81       handle = persist_state_alloc_entry(state, HOST_ID_PERSIST_KEY, sizeof(HostIdState));
82       if (handle == 0)
83         {
84           msg_error("host-id: could not allocate persist state");
85           return FALSE;
86         }
87     }
88 
89   host_id_state = persist_state_map_entry(state, handle);
90 
91   if (!host_id_found)
92     {
93       if (_load_host_id_from_legacy_persist_entry(state, &legacy_hostid))
94         {
95           host_id_state->host_id = legacy_hostid;
96         }
97       else
98         {
99           host_id_state->host_id = _create_host_id();
100         }
101     }
102 
103   global_host_id = host_id_state->host_id;
104 
105   persist_state_unmap_entry(state, handle);
106 
107   return TRUE;
108 }
109 
110 guint32
host_id_get(void)111 host_id_get(void)
112 {
113   return global_host_id;
114 }
115 
116 void
host_id_append_formatted_id(GString * str,guint32 id)117 host_id_append_formatted_id(GString *str, guint32 id)
118 {
119   format_uint32_padded(str, 8, '0', 16, id);
120 }
121