~ubuntu-branches/ubuntu/vivid/whoopsie/vivid-proposed

« back to all changes in this revision

Viewing changes to src/identifier.c

  • Committer: Package Import Robot
  • Author(s): Evan Dandrea, Brian Murray, John Lenton, Ted Gould
  • Date: 2014-06-02 11:10:40 UTC
  • Revision ID: package-import@ubuntu.com-20140602111040-q81ojkfwo7w6gx36
Tags: 0.2.27
[ Brian Murray ]
* Log that we are offline because we are using a network connection where
  one may have to pay for data usage.

[ John Lenton ]
* Ask ofono for the IMEI as an id source.
* Don't return null string during session start (LP: #1311571).
* Fix attempting to remove a source that has already been removed.

[ Ted Gould ]
* Don't break if whoopsie is running (i.e. developer system).

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#include <gio/gio.h>
1
2
#include <glib.h>
2
3
#include <gcrypt.h>
3
4
#include <sys/types.h>
11
12
 
12
13
#include "identifier.h"
13
14
 
 
15
static char* ofono_name = "org.ofono";
 
16
static gint fail_next_get_mac = 0;
 
17
static gint fail_next_get_uuid = 0;
 
18
 
 
19
void whoopsie_identifier_set_ofono_name (char *name) {
 
20
    ofono_name = name;
 
21
}
 
22
 
14
23
void
15
24
whoopsie_hex_to_char (char* buf, const char *str, int len)
16
25
{
41
50
 
42
51
    g_return_if_fail (res);
43
52
 
 
53
    if (g_atomic_int_compare_and_exchange (&fail_next_get_mac, WHOOPSIE_FAIL_GENERIC, 0)) {
 
54
        g_set_error (error, g_quark_from_static_string ("whoopsie-quark"), WHOOPSIE_FAILED_BY_REQUEST,
 
55
                     "Failed by tester request");
 
56
        return;
 
57
    }
 
58
 
44
59
    sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP);
45
60
    if (sock == -1) {
46
61
        g_set_error (error, g_quark_from_static_string ("whoopsie-quark"), 0,
59
74
 
60
75
    it = ifc.ifc_req;
61
76
 
62
 
    for (i = ifc.ifc_len / sizeof(struct ifreq); --i >= 0; it++) {
63
 
        strcpy(ifr.ifr_name, it->ifr_name);
64
 
        if (ioctl(sock, SIOCGIFFLAGS, &ifr) == 0) {
65
 
            if (! (ifr.ifr_flags & IFF_LOOPBACK)) { // don't count loopback
66
 
                if (ioctl(sock, SIOCGIFHWADDR, &ifr) == 0) {
67
 
                    success = TRUE;
68
 
                    break;
 
77
    if (!g_atomic_int_compare_and_exchange (&fail_next_get_mac, WHOOPSIE_FAIL_MAC_SIOCGIFFLAGS, 0)) {
 
78
        for (i = ifc.ifc_len / sizeof(struct ifreq); --i >= 0; it++) {
 
79
            strcpy(ifr.ifr_name, it->ifr_name);
 
80
            if (ioctl(sock, SIOCGIFFLAGS, &ifr) == 0) {
 
81
                if (! (ifr.ifr_flags & IFF_LOOPBACK)) { // don't count loopback
 
82
                    if (ioctl(sock, SIOCGIFHWADDR, &ifr) == 0) {
 
83
                        success = TRUE;
 
84
                        break;
 
85
                    }
69
86
                }
70
87
            }
71
88
        }
73
90
 
74
91
    close (sock);
75
92
 
76
 
    if (!success)
 
93
    if (!success) {
 
94
        g_set_error (error, g_quark_from_static_string ("whoopsie-quark"), 0,
 
95
                     "Unable to find a hardware address");
77
96
        return;
 
97
    }
78
98
 
79
99
    *res = g_malloc (18);
80
100
    sprintf (*res, "%02x:%02x:%02x:%02x:%02x:%02x",
93
113
 
94
114
    g_return_if_fail (res);
95
115
 
 
116
    if (g_atomic_int_compare_and_exchange (&fail_next_get_uuid, WHOOPSIE_FAIL_GENERIC, 0)) {
 
117
        g_set_error (error, g_quark_from_static_string ("whoopsie-quark"), WHOOPSIE_FAILED_BY_REQUEST,
 
118
                     "Failed by tester request");
 
119
        return;
 
120
    }
 
121
 
96
122
    fp = open ("/sys/class/dmi/id/product_uuid", O_RDONLY);
97
123
    if (fp < 0) {
98
124
        g_set_error (error, g_quark_from_static_string ("whoopsie-quark"), 0,
148
174
    gcry_md_close (sha512);
149
175
}
150
176
 
 
177
void whoopsie_identifier_append_imei (char** result, GError** error)
 
178
{
 
179
    GVariant* res;
 
180
    GError* err = NULL;
 
181
 
 
182
    GDBusConnection* con = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, &err);
 
183
 
 
184
    if (err != NULL) {
 
185
        g_set_error (error, g_quark_from_static_string ("whoopsie-quark"), 0,
 
186
                     "Unable to connect to the bus: %s", err->message);
 
187
        return;
 
188
    }
 
189
 
 
190
    res = g_dbus_connection_call_sync (con, ofono_name, "/",
 
191
                                       "org.ofono.Manager", "GetModems",
 
192
                                       NULL, G_VARIANT_TYPE ("(a(oa{sv}))"),
 
193
                                       G_DBUS_CALL_FLAGS_NONE,
 
194
                                       -1, NULL, &err);
 
195
 
 
196
    if (err != NULL) {
 
197
        g_set_error (error, g_quark_from_static_string ("whoopsie-quark"), 0,
 
198
                     "Unable to call ofono's GetModems: %s", err->message);
 
199
        return;
 
200
    }
 
201
    g_object_unref (con);
 
202
 
 
203
    /* res is an a(oa{sv}) */
 
204
    GVariant* var1 = g_variant_get_child_value (res, 0);
 
205
    g_variant_unref (res);
 
206
    /* but the first array can be empty */
 
207
    if (g_variant_n_children (var1) < 1) {
 
208
        g_set_error (error, g_quark_from_static_string ("whoopsie-quark"), 0,
 
209
                     "No modems in GetModems response");
 
210
        return;
 
211
    }
 
212
    GVariant* var2 = g_variant_get_child_value (var1, 0);
 
213
    g_variant_unref (var1);
 
214
    GVariant* var3 = g_variant_get_child_value (var2, 1);
 
215
    g_variant_unref (var2);
 
216
    GVariant* var4 = g_variant_lookup_value (var3, "Serial", G_VARIANT_TYPE ("s"));
 
217
    g_variant_unref (var3);
 
218
    if (var4 == NULL) {
 
219
        g_set_error (error, g_quark_from_static_string ("whoopsie-quark"), 0,
 
220
                     "No Serial key in GetModems response");
 
221
        return;
 
222
    }
 
223
    gsize imei_len;
 
224
    const gchar* imei = g_variant_get_string(var4, &imei_len);
 
225
    if (imei_len < 15 || imei_len > 16) {
 
226
        g_set_error (error, g_quark_from_static_string ("whoopsie-quark"), 0,
 
227
                     "GetModems' Serial key is not an IMEI (has length %zu)", imei_len);
 
228
        return;
 
229
    }
 
230
 
 
231
    size_t old_len = *result ? strlen(*result) : 0;
 
232
 
 
233
    *result = g_realloc (*result, old_len + imei_len + 1);
 
234
    strcpy (*result + old_len, imei);
 
235
 
 
236
    g_variant_unref(var4);
 
237
}
 
238
 
151
239
void
152
240
whoopsie_identifier_generate (char** res, GError** error)
153
241
{
165
253
    }
166
254
 
167
255
    whoopsie_identifier_get_mac_address (&identifier, error);
168
 
    if ((!error || !(*error)) && identifier)
 
256
    if ((!error || !(*error)) && identifier) {
 
257
        whoopsie_identifier_append_imei (&identifier, error);
 
258
        if (error && *error) {
 
259
            g_error_free (*error);
 
260
            *error = NULL;
 
261
        }
 
262
 
169
263
        goto out;
 
264
    }
170
265
 
171
266
    return;
172
267
 
176
271
    g_free (identifier);
177
272
}
178
273
 
 
274
void whoopsie_identifier_fail_next_get_mac (gint how)
 
275
{
 
276
    g_atomic_int_set (&fail_next_get_mac, how);
 
277
}
 
278
 
 
279
void whoopsie_identifier_fail_next_get_uuid ()
 
280
{
 
281
    g_atomic_int_set (&fail_next_get_uuid, 1);
 
282
}