bolt-device.c 21.8 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
/*
 * Copyright © 2017 Red Hat, Inc
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library. If not, see <http://www.gnu.org/licenses/>.
 *
 * Authors:
 *       Christian J. Kellner <christian@kellner.me>
 */

#include "config.h"

23
#include "bolt-dbus.h"
24
#include "bolt-device.h"
25
#include "bolt-enums.h"
26
#include "bolt-error.h"
27
#include "bolt-io.h"
28
#include "bolt-manager.h"
29
#include "bolt-store.h"
30
#include "bolt-str.h"
31

32
#include <dirent.h>
33
34
#include <libudev.h>

35
36
37
38
39
/* dbus method calls */
static gboolean    handle_authorize (BoltDBusDevice        *object,
                                     GDBusMethodInvocation *invocation,
                                     gpointer               user_data);

40
41
42
43
44

static gboolean    handle_forget (BoltDBusDevice        *object,
                                  GDBusMethodInvocation *invocation,
                                  gpointer               user_data);

45
46
47
48
struct _BoltDevice
{
  BoltDBusDeviceSkeleton object;

49
50
  /* weak reference */
  BoltManager *mgr;
51

52
53
54
55
56
  char        *dbus_path;

  char        *uid;
  char        *name;
  char        *vendor;
57

58
59
  BoltStatus   status;

60
  /* when device is attached */
61
62
  char        *syspath;
  BoltSecurity security;
63
  char        *parent;
64
65

  /* when device is stored */
66
  BoltStore   *store;
67
68
  BoltPolicy   policy;
  BoltKeyState key;
69
70
71
72
73
74
};


enum {
  PROP_0,

75
  PROP_MANAGER,
76
77
78
79
80
  PROP_STORE,

  PROP_LAST,

  /* overridden */
81
  PROP_UID,
82
83
  PROP_NAME,
  PROP_VENDOR,
84
  PROP_STATUS,
85

86
  PROP_PARENT,
87
  PROP_SYSFS,
88
  PROP_SECURITY,
89

90
91
92
  PROP_STORED,
  PROP_POLICY,
  PROP_HAVE_KEY,
93
94
};

95
static GParamSpec *props[PROP_LAST] = {NULL, };
96

97
98
99
100
101
102
103
enum {
  SIGNAL_STATUS_CHANGED,
  SIGNAL_LAST
};

static guint signals[SIGNAL_LAST] = {0};

104
105
106
107
108
109
110
111
112
G_DEFINE_TYPE (BoltDevice,
               bolt_device,
               BOLT_DBUS_TYPE_DEVICE_SKELETON)

static void
bolt_device_finalize (GObject *object)
{
  BoltDevice *dev = BOLT_DEVICE (object);

113
114
  g_clear_object (&dev->store);

115
116
  g_free (dev->dbus_path);

117
  g_free (dev->uid);
118
119
  g_free (dev->name);
  g_free (dev->vendor);
120
121

  g_free (dev->parent);
122
  g_free (dev->syspath);
123
124
125
126
127

  G_OBJECT_CLASS (bolt_device_parent_class)->finalize (object);
}

static void
128
bolt_device_init (BoltDevice *dev)
129
{
130
131
  g_signal_connect (dev, "handle-authorize",
                    G_CALLBACK (handle_authorize), NULL);
132
133
  g_signal_connect (dev, "handle-forget",
                    G_CALLBACK (handle_forget), NULL);
134
135
136
137
138
139
140
141
142
143
144
145
}

static void
bolt_device_get_property (GObject    *object,
                          guint       prop_id,
                          GValue     *value,
                          GParamSpec *pspec)
{
  BoltDevice *dev = BOLT_DEVICE (object);

  switch (prop_id)
    {
146
147
148
149
    case PROP_MANAGER:
      g_value_set_object (value, dev->mgr);
      break;

150
151
152
153
    case PROP_STORE:
      g_value_set_object (value, dev->store);
      break;

154
155
156
157
    case PROP_UID:
      g_value_set_string (value, dev->uid);
      break;

158
159
160
161
162
163
164
165
    case PROP_NAME:
      g_value_set_string (value, dev->name);
      break;

    case PROP_VENDOR:
      g_value_set_string (value, dev->vendor);
      break;

166
167
168
169
    case PROP_STATUS:
      g_value_set_uint (value, dev->status);
      break;

170
171
172
173
    case PROP_PARENT:
      g_value_set_string (value, dev->parent);
      break;

174
175
176
177
    case PROP_SYSFS:
      g_value_set_string (value, dev->syspath);
      break;

178
179
180
181
    case PROP_SECURITY:
      g_value_set_uint (value, dev->security);
      break;

182
    case PROP_STORED:
183
      g_value_set_boolean (value, dev->store != NULL);
184
185
186
187
188
189
190
191
192
193
      break;

    case PROP_POLICY:
      g_value_set_uint (value, dev->policy);
      break;

    case PROP_HAVE_KEY:
      g_value_set_uint (value, dev->key);
      break;

194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
    }
}

static void
bolt_device_set_property (GObject      *object,
                          guint         prop_id,
                          const GValue *value,
                          GParamSpec   *pspec)
{
  BoltDevice *dev = BOLT_DEVICE (object);

  switch (prop_id)
    {
209

210
211
212
213
214
215
216
    case PROP_MANAGER:
      g_return_if_fail (dev->mgr == NULL);
      dev->mgr = g_value_get_object (value);
      g_object_add_weak_pointer (G_OBJECT (dev->mgr),
                                 (gpointer *) &dev->mgr);
      break;

217
218
219
220
221
    case PROP_STORE:
      dev->store = g_value_dup_object (value);
      g_object_notify (object, "stored");
      break;

222
    case PROP_UID:
223
      g_return_if_fail (dev->uid == NULL);
224
225
226
      dev->uid = g_value_dup_string (value);
      break;

227
    case PROP_NAME:
228
      g_clear_pointer (&dev->name, g_free);
229
      dev->name = g_value_dup_string (value);
230
231
232
      break;

    case PROP_VENDOR:
233
      g_clear_pointer (&dev->vendor, g_free);
234
      dev->vendor = g_value_dup_string (value);
235
236
      break;

237
    case PROP_STATUS:
238
239
240
241
242
243
244
245
246
247
248
249
250
      {
        BoltStatus old = dev->status;
        BoltStatus now = g_value_get_uint (value);
        if (old == now)
          break;

        dev->status = now;
        g_signal_emit (dev,
                       signals[SIGNAL_STATUS_CHANGED],
                       0,
                       old);
        break;
      }
251

252
253
254
255
256
    case PROP_PARENT:
      g_clear_pointer (&dev->parent, g_free);
      dev->parent = g_value_dup_string (value);
      break;

257
    case PROP_SYSFS:
258
      g_clear_pointer (&dev->syspath, g_free);
259
260
      dev->syspath = g_value_dup_string (value);
      break;
261
262
263
264

    case PROP_SECURITY:
      dev->security = g_value_get_uint (value);
      break;
265

266
267
268
269
270
271
272
273
    case PROP_POLICY:
      dev->policy = g_value_get_uint (value);
      break;

    case PROP_HAVE_KEY:
      dev->key = g_value_get_uint (value);
      break;

274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
    }
}


static void
bolt_device_class_init (BoltDeviceClass *klass)
{
  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);

  gobject_class->finalize = bolt_device_finalize;

  gobject_class->get_property = bolt_device_get_property;
  gobject_class->set_property = bolt_device_set_property;

290
291
292
293
294
295
296
  props[PROP_MANAGER] =
    g_param_spec_object ("manager",
                         NULL, NULL,
                         BOLT_TYPE_MANAGER,
                         G_PARAM_READWRITE |
                         G_PARAM_STATIC_NICK);

297
298
299
300
301
302
303
304
305
306
307
  props[PROP_STORE] =
    g_param_spec_object ("store",
                         NULL, NULL,
                         BOLT_TYPE_STORE,
                         G_PARAM_READWRITE |
                         G_PARAM_STATIC_NICK);

  g_object_class_install_properties (gobject_class,
                                     PROP_LAST,
                                     props);

308
309
310
  g_object_class_override_property (gobject_class,
                                    PROP_UID,
                                    "uid");
311
312
313
314
315
316
317
318
319

  g_object_class_override_property (gobject_class,
                                    PROP_NAME,
                                    "name");

  g_object_class_override_property (gobject_class,
                                    PROP_VENDOR,
                                    "vendor");

320
321
322
323
  g_object_class_override_property (gobject_class,
                                    PROP_STATUS,
                                    "status");

324
325
326
327
  g_object_class_override_property (gobject_class,
                                    PROP_PARENT,
                                    "parent");

328
329
330
331
  g_object_class_override_property (gobject_class,
                                    PROP_SYSFS,
                                    "sysfs-path");

332
333
334
335
  g_object_class_override_property (gobject_class,
                                    PROP_SECURITY,
                                    "security");

336
337
  g_object_class_override_property (gobject_class,
                                    PROP_STORED,
338
                                    "stored");
339
340
341
342
343
344
345
346
347

  g_object_class_override_property (gobject_class,
                                    PROP_POLICY,
                                    "policy");

  g_object_class_override_property (gobject_class,
                                    PROP_HAVE_KEY,
                                    "key");

348
349
350
351
352
353
354
355
356
357
358

  signals[SIGNAL_STATUS_CHANGED] =
    g_signal_new ("status-changed",
                  G_TYPE_FROM_CLASS (gobject_class),
                  G_SIGNAL_RUN_LAST,
                  0,
                  NULL, NULL,
                  NULL,
                  G_TYPE_NONE,
                  1, BOLT_TYPE_STATUS);

359
}
360
361
362

/* internal methods */

363
364
static const char *
read_sysattr_name (struct udev_device *udev, const char *attr, GError **error)
365
366
{
  g_autofree char *s = NULL;
367
  const char *v;
368
369

  s = g_strdup_printf ("%s_name", attr);
370
371
372
373
374
375
  v = udev_device_get_sysattr_value (udev, s);

  if (v != NULL)
    return v;

  v = udev_device_get_sysattr_value (udev, attr);
376

377
  if (v == NULL)
378
379
380
    g_set_error (error,
                 BOLT_ERROR, BOLT_ERROR_UDEV,
                 "failed to get sysfs attr: %s", attr);
381
382

  return v;
383
384
}

385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
static gint
read_sysfs_attr_int (struct udev_device *device, const char *attr)
{
  const char *str;
  char *end;
  gint64 val;

  str = udev_device_get_sysattr_value (device, attr);

  if (str == NULL)
    return 0;

  val = g_ascii_strtoull (str, &end, 0);

  if (str == end)
    return 0;

  if (val > G_MAXINT || val < G_MININT)
    {
      g_warning ("value read from sysfs outside of guint's range.");
      val = 0;
    }

  return (gint) val;
}

static gboolean
string_nonzero (const char *str)
{
  return str != NULL && str[0] != '\0';
}

417
418
419
420
421
422
423
424
425
426
427
428
static const char *
bolt_sysfs_get_parent_uid (struct udev_device *udev)
{
  struct udev_device *parent;
  const char *uid = NULL;

  parent = udev_device_get_parent (udev);
  if (parent)
    uid = udev_device_get_sysattr_value (parent, "unique_id");
  return uid;
}

429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
static BoltStatus
bolt_status_from_udev (struct udev_device *udev)
{
  gint authorized;
  const char *key;
  gboolean have_key;

  authorized = read_sysfs_attr_int (udev, "authorized");

  if (authorized == 2)
    return BOLT_STATUS_AUTHORIZED_SECURE;

  key = udev_device_get_sysattr_value (udev, "key");
  have_key = string_nonzero (key);

  if (authorized == 1)
    {
      if (have_key)
        return BOLT_STATUS_AUTHORIZED_NEWKEY;
      else
        return BOLT_STATUS_AUTHORIZED;
    }
  else if (authorized == 0 && have_key)
    {
      return BOLT_STATUS_AUTH_ERROR;
    }

  return BOLT_STATUS_CONNECTED;
}

459
460

static struct udev_device *
461
bolt_sysfs_domain_for_device (struct udev_device *udev)
462
463
464
465
466
467
468
469
{
  struct udev_device *parent;
  gboolean found;

  found = FALSE;
  parent = udev;
  do
    {
470
      const char *devtype;
471
472
473
474
      parent = udev_device_get_parent (parent);
      if (!parent)
        break;

475
476
      devtype = udev_device_get_devtype (parent);
      found = bolt_streq (devtype, "thunderbolt_domain");
477
478
479
480
481
482
483
484
485
486
487
488
489
490

    }
  while (!found);

  return found ? parent : NULL;
}

static BoltSecurity
security_for_udev (struct udev_device *udev)
{
  struct udev_device *parent = NULL;
  const char *v;
  BoltSecurity s;

491
  parent = bolt_sysfs_domain_for_device (udev);
492
493
494
495
496
497
498
499
500
501
502
503
  if (parent == NULL)
    {
      g_warning ("Failed to determine domain device");
      return BOLT_SECURITY_NONE;
    }

  v = udev_device_get_sysattr_value (parent, "security");
  s = bolt_security_from_string (v);

  return s;
}

504
505
506
507
/*  device authorization */

typedef struct
{
508
  BoltAuth *auth;
509
510

  /* the outer callback  */
511
512
  GAsyncReadyCallback callback;
  gpointer            user_data;
513
514
515
516
517
518
519
520
521

} AuthData;

static void
auth_data_free (gpointer data)
{
  AuthData *auth = data;

  g_debug ("freeing auth data");
522
  g_clear_object (&auth->auth);
523
524
525
  g_slice_free (AuthData, auth);
}

526
527
static gboolean
authorize_device_internal (BoltDevice *dev,
528
                           BoltAuth   *auth,
529
                           GError    **error)
530
531
{
  g_autoptr(DIR) devdir = NULL;
532
533
  BoltKey *key;
  BoltSecurity level;
534
535
  gboolean ok;

536
537
538
  key = bolt_auth_get_key (auth);
  level = bolt_auth_get_level (auth);

539
  devdir = bolt_opendir (dev->syspath, error);
540
  if (devdir == NULL)
541
    return FALSE;
542

543
  ok = bolt_verify_uid (dirfd (devdir), dev->uid, error);
544
  if (!ok)
545
546
    return FALSE;

547
  if (key)
548
    {
549
550
551
552
553
554
555
      int keyfd;

      g_debug ("[%s] writing key", dev->uid);
      keyfd = bolt_openat (dirfd (devdir), "key", O_WRONLY | O_CLOEXEC, error);
      if (keyfd < 0)
        return FALSE;

556
      ok = bolt_key_write_to (key, keyfd, &level, error);
557
558
559
      close (keyfd);
      if (!ok)
        return FALSE;
560
561
    }

562
  g_debug ("[%s] writing authorization", dev->uid);
563
564
  ok = bolt_write_char_at (dirfd (devdir),
                           "authorized",
565
                           level,
566
567
568
569
570
571
572
573
574
575
576
577
                           error);
  return ok;
}

static void
authorize_in_thread (GTask        *task,
                     gpointer      source,
                     gpointer      context,
                     GCancellable *cancellable)
{
  g_autoptr(GError) error = NULL;
  BoltDevice *dev = source;
578
579
  AuthData *auth_data = context;
  BoltAuth *auth = auth_data->auth;
580
581
582
  gboolean ok;

  ok = authorize_device_internal (dev, auth, &error);
583
584

  if (!ok)
585
586
587
    g_task_return_new_error (task, BOLT_ERROR, BOLT_ERROR_FAILED,
                             "failed to authorize device: %s",
                             error->message);
588
  else
589
    g_task_return_boolean (task, TRUE);
590
591
592
593
594
595
596
}

static void
authorize_thread_done (GObject      *object,
                       GAsyncResult *res,
                       gpointer      user_data)
{
597
  g_autoptr(GError) error = NULL;
598
599
  BoltDevice *dev = BOLT_DEVICE (object);
  GTask *task = G_TASK (res);
600
  BoltStatus status;
601
602
  AuthData *auth_data;
  BoltAuth *auth;
603
604
  gboolean ok;

605
606
607
  auth_data = g_task_get_task_data (task);
  auth = auth_data->auth;

608
609
  ok = g_task_propagate_boolean (task, &error);

610
  if (!ok)
611
    {
612
      status = BOLT_STATUS_AUTH_ERROR;
613
614
      g_object_set (dev, "status", status, NULL);
      bolt_auth_return_error (auth, &error);
615
616
    }

617
618
619
620
  if (auth_data->callback)
    auth_data->callback (G_OBJECT (dev),
                         G_ASYNC_RESULT (auth),
                         auth_data->user_data);
621
622
}

623
624
625
626
627
void
bolt_device_authorize (BoltDevice         *dev,
                       BoltAuth           *auth,
                       GAsyncReadyCallback callback,
                       gpointer            user_data)
628
629
630
631
{
  AuthData *auth_data;
  GTask *task;

632
633
  g_object_set (auth, "device", dev, NULL);

634
635
636
  if (dev->status != BOLT_STATUS_CONNECTED &&
      dev->status != BOLT_STATUS_AUTH_ERROR)
    {
637
638
      bolt_auth_return_new_error (auth, BOLT_ERROR, BOLT_ERROR_FAILED,
                                  "wrong device state: %u", dev->status);
639

640
641
      if (callback)
        callback (G_OBJECT (dev), G_ASYNC_RESULT (auth), user_data);
642

643
      return;
644
645
646
    }

  task = g_task_new (dev, NULL, authorize_thread_done, NULL);
647
648
649
  auth_data = g_slice_new (AuthData);
  auth_data->callback = callback;
  auth_data->user_data = user_data;
650
  auth_data->auth = g_object_ref (auth);
651
652
  g_task_set_task_data (task, auth_data, auth_data_free);

653
  g_object_set (dev, "status", BOLT_STATUS_AUTHORIZING, NULL);
654
655
656
657
658
659
660
661
662

  g_task_run_in_thread (task, authorize_in_thread);
  g_object_unref (task);
}


/* dbus methods */

static void
663
664
665
handle_authorize_done (GObject      *device,
                       GAsyncResult *res,
                       gpointer      user_data)
666
{
667
668
669
670
671
672
673
674
675
  GDBusMethodInvocation *inv;
  GError *error = NULL;
  BoltAuth *auth;
  BoltDevice *dev;
  gboolean ok;

  dev = BOLT_DEVICE (device);
  inv  = user_data;
  auth = BOLT_AUTH (res);
676

677
  ok = bolt_auth_check (auth, &error);
678
  if (ok)
679
    bolt_dbus_device_complete_authorize (BOLT_DBUS_DEVICE (dev), inv);
680
  else
681
    g_dbus_method_invocation_take_error (inv, error);
682
683
684
685
}

static gboolean
handle_authorize (BoltDBusDevice        *object,
686
                  GDBusMethodInvocation *inv,
687
688
689
690
                  gpointer               user_data)
{
  BoltDevice *dev = BOLT_DEVICE (object);
  GError *error = NULL;
691
692
693
  BoltAuth *auth;
  BoltSecurity level;
  BoltKey *key;
694

695
696
  level = dev->security;
  key = NULL;
697

698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
  if (level == BOLT_SECURITY_SECURE)
    {
      if (dev->key)
        key = bolt_store_get_key (dev->store, dev->uid, &error);
      else
        level = BOLT_SECURITY_USER;
    }

  if (level == BOLT_SECURITY_SECURE && key == NULL)
    {
      g_dbus_method_invocation_take_error (inv, error);
      return TRUE;
    }

  auth = bolt_auth_new (dev, level, key);
  bolt_device_authorize (dev, auth, handle_authorize_done, inv);
714
715
716
717

  return TRUE;
}

718
719
720
721
722
723
724
725
726
727
728
729
static gboolean
handle_forget (BoltDBusDevice        *object,
               GDBusMethodInvocation *inv,
               gpointer               user_data)
{
  g_autoptr(GError) key_err = NULL;
  g_autoptr(GError) dev_err = NULL;
  BoltDevice *dev;
  gboolean key_ok, dev_ok;

  dev = BOLT_DEVICE (object);

730
  key_ok = bolt_store_del_key (dev->store, dev->uid, &key_err);
731
732
733
  if (!key_ok && bolt_err_notfound (key_err))
    key_ok = TRUE;

734
  dev_ok = bolt_store_del_device (dev->store, dev->uid, &dev_err);
735
736
737
738
739
740
741
742
743
744
745
746
747

  g_debug ("[%s] forgetting: key: %d, dev: %d", dev->uid, key_ok, dev_ok);

  if (!dev_ok)
    g_dbus_method_invocation_take_error (inv, g_steal_pointer (&dev_err));
  else if (!key_ok)
    g_dbus_method_invocation_take_error (inv, g_steal_pointer (&key_err));
  else
    bolt_dbus_device_complete_forget (BOLT_DBUS_DEVICE (dev), inv);

  return TRUE;
}

748
749
750
/* public methods */

BoltDevice *
751
bolt_device_new_for_udev (struct udev_device *udev,
752
753
                          GError            **error)
{
754
755
756
757
  const char *uid;
  const char *name;
  const char *vendor;
  const char *syspath;
758
  const char *parent;
759
  BoltDevice *dev;
760

761
762
763
764
765
766
767
  uid = udev_device_get_sysattr_value (udev, "unique_id");
  if (udev == NULL)
    {
      g_set_error (error, BOLT_ERROR, BOLT_ERROR_UDEV,
                   "could not get unique_id for udev");
      return NULL;
    }
768

769
770
  syspath = udev_device_get_syspath (udev);
  g_return_val_if_fail (syspath != NULL, NULL);
771

772
  name = read_sysattr_name (udev, "device", error);
773
774
775
  if (name == NULL)
    return NULL;

776
  vendor = read_sysattr_name (udev, "vendor", error);
777
778
  if (vendor == NULL)
    return NULL;
779

780
  parent = bolt_sysfs_get_parent_uid (udev);
781
  dev = g_object_new (BOLT_TYPE_DEVICE,
782
783
784
785
                      "uid", uid,
                      "name", name,
                      "vendor", vendor,
                      "sysfs-path", syspath,
786
                      "parent", parent,
787
788
                      NULL);

789
  dev->status = bolt_status_from_udev (udev);
790
  dev->security = security_for_udev (udev);
791

792
793
794
  return dev;
}

795
const char *
796
797
798
799
bolt_device_export (BoltDevice      *device,
                    GDBusConnection *connection,
                    GError         **error)
{
800
  const char *path;
801
  gboolean ok;
802
803

  g_return_val_if_fail (BOLT_IS_DEVICE (device), FALSE);
804

805
  path = bolt_device_get_object_path (device);
806

807
808
809
810
811
  ok = g_dbus_interface_skeleton_export (G_DBUS_INTERFACE_SKELETON (device),
                                         connection,
                                         path,
                                         error);
  return ok ? path : NULL;
812
813
814
815
816
817
818
}

void
bolt_device_unexport (BoltDevice *device)
{
  g_dbus_interface_skeleton_unexport (G_DBUS_INTERFACE_SKELETON (device));
}
819

820
821
822
823
824
825

BoltStatus
bolt_device_connected (BoltDevice         *dev,
                       struct udev_device *udev)
{
  const char *syspath;
826
  const char *parent;
827
828
829
830
831
832
  BoltSecurity security;
  BoltStatus status;

  syspath = udev_device_get_syspath (udev);
  status = bolt_status_from_udev (udev);
  security = security_for_udev (udev);
833
  parent = bolt_sysfs_get_parent_uid (udev);
834
835

  g_object_set (G_OBJECT (dev),
836
                "parent", parent,
837
838
839
840
841
                "sysfs-path", syspath,
                "security", security,
                "status", status,
                NULL);

842
843
  g_debug ("[%s] parent is %s", dev->uid, dev->parent);

844
845
846
847
848
849
850
  return status;
}

BoltStatus
bolt_device_disconnected (BoltDevice *dev)
{
  g_object_set (G_OBJECT (dev),
851
                "parent", NULL,
852
853
854
855
856
                "sysfs-path", NULL,
                "security", BOLT_SECURITY_NONE,
                "status", BOLT_STATUS_DISCONNECTED,
                NULL);

857
858
859
860
861
862
863
864
865
866
  /* check if we have a new key for the device, and
   * if so, change its state to KEY_HAVE, because
   * now it is not new anymore.
   */
  if (dev->key == BOLT_KEY_NEW)
    {
      dev->key = BOLT_KEY_HAVE;
      g_object_notify (G_OBJECT (dev), "key");
    }

867
868
869
870
871
872
  return dev->status;
}

gboolean
bolt_device_is_connected (BoltDevice *device)
{
873
  return bolt_status_is_connected (device->status);
874
875
}

876
877
878
879
880
881
882
883
884
885
886
887
888
BoltStatus
bolt_device_update_from_udev (BoltDevice         *dev,
                              struct udev_device *udev)
{
  BoltStatus status = bolt_status_from_udev (udev);

  g_object_set (G_OBJECT (dev),
                "status", status,
                NULL);

  return status;
}

889
BoltKeyState
890
bolt_device_get_keystate (BoltDevice *dev)
891
892
893
894
{
  return dev->key;
}

895
896
897
898
899
900
const char *
bolt_device_get_name (BoltDevice *dev)
{
  return dev->name;
}

901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
const char *
bolt_device_get_object_path (BoltDevice *device)
{
  g_return_val_if_fail (BOLT_IS_DEVICE (device), FALSE);

  if (device->dbus_path == NULL)
    {
      char *path = NULL;

      path = g_strdup_printf ("/org/freedesktop/Bolt/devices/%s", device->uid);
      g_strdelimit (path, "-", '_');

      device->dbus_path = path;
    }

  return device->dbus_path;
}
918

919
920
921
922
923
924
BoltPolicy
bolt_device_get_policy (BoltDevice *dev)
{
  return dev->policy;
}

925
926
927
928
929
930
const char *
bolt_device_get_uid (BoltDevice *dev)
{
  return dev->uid;
}

931
932
933
934
935
936
BoltSecurity
bolt_device_get_security (BoltDevice *dev)
{
  return dev->security;
}

Christian Kellner's avatar
Christian Kellner committed
937
938
939
940
941
942
BoltStatus
bolt_device_get_status (BoltDevice *dev)
{
  return dev->status;
}

943
944
gboolean
bolt_device_get_stored (BoltDevice *dev)
945
{
946
  return dev->store != NULL;
947
948
}

949
950
951
952
953
const char *
bolt_device_get_syspath (BoltDevice *dev)
{
  return dev->syspath;
}
954
955
956
957
958
959

const char *
bolt_device_get_vendor (BoltDevice *dev)
{
  return dev->vendor;
}