bolt-device.c 21.7 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
struct _BoltDevice
{
  BoltDBusDeviceSkeleton object;

45 46
  /* device props */
  char      *dbus_path;
47

48 49 50
  char      *uid;
  char      *name;
  char      *vendor;
51

52
  BoltStatus status;
53

54
  /* when device is attached */
55 56
  char        *syspath;
  BoltSecurity security;
57
  char        *parent;
58 59

  /* when device is stored */
60
  BoltStore   *store;
61 62
  BoltPolicy   policy;
  BoltKeyState key;
63 64 65 66 67 68
};


enum {
  PROP_0,

69 70 71 72 73
  PROP_STORE,

  PROP_LAST,

  /* overridden */
74
  PROP_UID,
75 76
  PROP_NAME,
  PROP_VENDOR,
77
  PROP_STATUS,
78

79
  PROP_PARENT,
80
  PROP_SYSFS,
81
  PROP_SECURITY,
82

83 84 85
  PROP_STORED,
  PROP_POLICY,
  PROP_HAVE_KEY,
86 87
};

88
static GParamSpec *props[PROP_LAST] = {NULL, };
89

90 91 92 93 94 95 96
enum {
  SIGNAL_STATUS_CHANGED,
  SIGNAL_LAST
};

static guint signals[SIGNAL_LAST] = {0};

97 98 99 100 101 102 103 104 105
G_DEFINE_TYPE (BoltDevice,
               bolt_device,
               BOLT_DBUS_TYPE_DEVICE_SKELETON)

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

106 107
  g_clear_object (&dev->store);

108 109
  g_free (dev->dbus_path);

110
  g_free (dev->uid);
111 112
  g_free (dev->name);
  g_free (dev->vendor);
113 114

  g_free (dev->parent);
115
  g_free (dev->syspath);
116 117 118 119 120

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

static void
121
bolt_device_init (BoltDevice *dev)
122
{
123 124
  g_signal_connect (dev, "handle-authorize",
                    G_CALLBACK (handle_authorize), NULL);
125 126 127 128 129 130 131 132 133 134 135 136
}

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

  switch (prop_id)
    {
137 138 139 140
    case PROP_STORE:
      g_value_set_object (value, dev->store);
      break;

141 142 143 144
    case PROP_UID:
      g_value_set_string (value, dev->uid);
      break;

145 146 147 148 149 150 151 152
    case PROP_NAME:
      g_value_set_string (value, dev->name);
      break;

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

153 154 155 156
    case PROP_STATUS:
      g_value_set_uint (value, dev->status);
      break;

157 158 159 160
    case PROP_PARENT:
      g_value_set_string (value, dev->parent);
      break;

161 162 163 164
    case PROP_SYSFS:
      g_value_set_string (value, dev->syspath);
      break;

165 166 167 168
    case PROP_SECURITY:
      g_value_set_uint (value, dev->security);
      break;

169
    case PROP_STORED:
170
      g_value_set_boolean (value, dev->store != NULL);
171 172 173 174 175 176 177 178 179 180
      break;

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

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

181 182 183 184 185 186 187 188 189 190 191 192
    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);
193
  GParamSpec *parent;
194 195 196

  switch (prop_id)
    {
197 198 199 200 201
    case PROP_STORE:
      dev->store = g_value_dup_object (value);
      g_object_notify (object, "stored");
      break;

202
    case PROP_UID:
203
      g_return_if_fail (dev->uid == NULL);
204 205 206
      dev->uid = g_value_dup_string (value);
      break;

207
    case PROP_NAME:
208
      g_clear_pointer (&dev->name, g_free);
209
      dev->name = g_value_dup_string (value);
210 211 212
      break;

    case PROP_VENDOR:
213
      g_clear_pointer (&dev->vendor, g_free);
214
      dev->vendor = g_value_dup_string (value);
215 216
      break;

217
    case PROP_STATUS:
218 219 220 221 222 223 224 225 226 227 228 229 230
      {
        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;
      }
231

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

237
    case PROP_SYSFS:
238
      g_clear_pointer (&dev->syspath, g_free);
239 240
      dev->syspath = g_value_dup_string (value);
      break;
241 242 243 244

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

246 247 248 249 250 251 252 253
    case PROP_POLICY:
      dev->policy = g_value_get_uint (value);
      break;

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

254 255 256
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
    }
257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290

  /* This is one gross hack to make the DBus property change
   * signal emission work.
   *   The heart "problem" is a combination of two things:
   *   1) the dbus object properties are override here,
   *      which means the property setter from the parent
   *      (the dbus skeleton) will not be called.
   *   2) The dbus skeleton will only emit the signal on the
   *      bus if it finds that the value has changed, which
   *      it can only detect if its property setter was called
   *   => We need to call the skeleton's set_property function
   *      from here, so it can detect property changes itself.
   */

  /* all properties below PROP_LAST are our own, non-dbus props */
  if (prop_id < PROP_LAST)
    return;

  /* we need to original GParamSpec, since the one we got is
   * the new, overridden one */
  parent = g_object_class_find_property (bolt_device_parent_class,
                                         pspec->name);
  if (parent == NULL)
    return;

  /* the prop_id is *our* prop_id, not the parent's prop_id, which
   * we need. For this to work our property list *after* PROP_LAST
   * need to be in sync with the parent */
  prop_id -= PROP_LAST;

  G_OBJECT_CLASS (bolt_device_parent_class)->set_property (object,
                                                           prop_id,
                                                           value,
                                                           parent);
291 292 293 294 295 296 297 298 299 300 301 302 303
}


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;

304 305 306 307 308 309 310 311 312 313 314
  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);

315 316 317
  g_object_class_override_property (gobject_class,
                                    PROP_UID,
                                    "uid");
318 319 320 321 322 323 324 325 326

  g_object_class_override_property (gobject_class,
                                    PROP_NAME,
                                    "name");

  g_object_class_override_property (gobject_class,
                                    PROP_VENDOR,
                                    "vendor");

327 328 329 330
  g_object_class_override_property (gobject_class,
                                    PROP_STATUS,
                                    "status");

331 332 333 334
  g_object_class_override_property (gobject_class,
                                    PROP_PARENT,
                                    "parent");

335 336 337 338
  g_object_class_override_property (gobject_class,
                                    PROP_SYSFS,
                                    "sysfs-path");

339 340 341 342
  g_object_class_override_property (gobject_class,
                                    PROP_SECURITY,
                                    "security");

343 344
  g_object_class_override_property (gobject_class,
                                    PROP_STORED,
345
                                    "stored");
346 347 348 349 350 351 352 353 354

  g_object_class_override_property (gobject_class,
                                    PROP_POLICY,
                                    "policy");

  g_object_class_override_property (gobject_class,
                                    PROP_HAVE_KEY,
                                    "key");

355 356 357 358 359 360 361 362 363 364 365

  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);

366
}
367 368 369

/* internal methods */

370 371
static const char *
read_sysattr_name (struct udev_device *udev, const char *attr, GError **error)
372 373
{
  g_autofree char *s = NULL;
374
  const char *v;
375 376

  s = g_strdup_printf ("%s_name", attr);
377 378 379 380 381 382
  v = udev_device_get_sysattr_value (udev, s);

  if (v != NULL)
    return v;

  v = udev_device_get_sysattr_value (udev, attr);
383

384
  if (v == NULL)
385 386 387
    g_set_error (error,
                 BOLT_ERROR, BOLT_ERROR_UDEV,
                 "failed to get sysfs attr: %s", attr);
388 389

  return v;
390 391
}

392 393 394 395 396 397 398 399 400 401 402 403
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;

404
  val = g_ascii_strtoll (str, &end, 0);
405 406 407 408 409 410

  if (str == end)
    return 0;

  if (val > G_MAXINT || val < G_MININT)
    {
411
      g_warning ("value read from sysfs outside of gint's range.");
412 413 414 415 416 417 418 419 420 421 422 423
      val = 0;
    }

  return (gint) val;
}

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

424 425 426 427 428 429 430 431 432 433 434 435
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;
}

436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465
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;
}

466 467

static struct udev_device *
468
bolt_sysfs_domain_for_device (struct udev_device *udev)
469 470 471 472 473 474 475 476
{
  struct udev_device *parent;
  gboolean found;

  found = FALSE;
  parent = udev;
  do
    {
477
      const char *devtype;
478 479 480 481
      parent = udev_device_get_parent (parent);
      if (!parent)
        break;

482 483
      devtype = udev_device_get_devtype (parent);
      found = bolt_streq (devtype, "thunderbolt_domain");
484 485 486 487 488 489 490 491

    }
  while (!found);

  return found ? parent : NULL;
}

static BoltSecurity
492
bolt_sysfs_security_for_device (struct udev_device *udev)
493 494 495 496 497
{
  struct udev_device *parent = NULL;
  const char *v;
  BoltSecurity s;

498
  parent = bolt_sysfs_domain_for_device (udev);
499 500 501 502 503 504 505 506 507
  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);

508 509 510 511 512 513
  if (!bolt_security_validate (s))
    {
      g_warning ("invalid security: %s", v);
      s = BOLT_SECURITY_NONE;
    }

514 515 516
  return s;
}

517 518 519 520
/*  device authorization */

typedef struct
{
521
  BoltAuth *auth;
522 523

  /* the outer callback  */
524 525
  GAsyncReadyCallback callback;
  gpointer            user_data;
526 527 528 529 530 531 532 533 534

} AuthData;

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

  g_debug ("freeing auth data");
535
  g_clear_object (&auth->auth);
536 537 538
  g_slice_free (AuthData, auth);
}

539 540
static gboolean
authorize_device_internal (BoltDevice *dev,
541
                           BoltAuth   *auth,
542
                           GError    **error)
543 544
{
  g_autoptr(DIR) devdir = NULL;
545 546
  BoltKey *key;
  BoltSecurity level;
547 548
  gboolean ok;

549 550 551
  key = bolt_auth_get_key (auth);
  level = bolt_auth_get_level (auth);

552
  devdir = bolt_opendir (dev->syspath, error);
553
  if (devdir == NULL)
554
    return FALSE;
555

556
  ok = bolt_verify_uid (dirfd (devdir), dev->uid, error);
557
  if (!ok)
558 559
    return FALSE;

560
  if (key)
561
    {
562 563 564 565 566 567 568
      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;

569
      ok = bolt_key_write_to (key, keyfd, &level, error);
570 571 572
      close (keyfd);
      if (!ok)
        return FALSE;
573 574
    }

575
  g_debug ("[%s] writing authorization", dev->uid);
576 577
  ok = bolt_write_char_at (dirfd (devdir),
                           "authorized",
578
                           level,
579 580 581 582 583 584 585 586 587 588 589 590
                           error);
  return ok;
}

static void
authorize_in_thread (GTask        *task,
                     gpointer      source,
                     gpointer      context,
                     GCancellable *cancellable)
{
  g_autoptr(GError) error = NULL;
  BoltDevice *dev = source;
591 592
  AuthData *auth_data = context;
  BoltAuth *auth = auth_data->auth;
593 594 595
  gboolean ok;

  ok = authorize_device_internal (dev, auth, &error);
596 597

  if (!ok)
598 599 600
    g_task_return_new_error (task, BOLT_ERROR, BOLT_ERROR_FAILED,
                             "failed to authorize device: %s",
                             error->message);
601
  else
602
    g_task_return_boolean (task, TRUE);
603 604 605 606 607 608 609
}

static void
authorize_thread_done (GObject      *object,
                       GAsyncResult *res,
                       gpointer      user_data)
{
610
  g_autoptr(GError) error = NULL;
611 612
  BoltDevice *dev = BOLT_DEVICE (object);
  GTask *task = G_TASK (res);
613
  BoltStatus status;
614 615
  AuthData *auth_data;
  BoltAuth *auth;
616 617
  gboolean ok;

618 619 620
  auth_data = g_task_get_task_data (task);
  auth = auth_data->auth;

621 622
  ok = g_task_propagate_boolean (task, &error);

623
  if (!ok)
624
    {
625
      status = BOLT_STATUS_AUTH_ERROR;
626 627
      g_object_set (dev, "status", status, NULL);
      bolt_auth_return_error (auth, &error);
628 629
    }

630 631 632 633
  if (auth_data->callback)
    auth_data->callback (G_OBJECT (dev),
                         G_ASYNC_RESULT (auth),
                         auth_data->user_data);
634 635
}

636 637 638 639 640
void
bolt_device_authorize (BoltDevice         *dev,
                       BoltAuth           *auth,
                       GAsyncReadyCallback callback,
                       gpointer            user_data)
641 642 643 644
{
  AuthData *auth_data;
  GTask *task;

645 646
  g_object_set (auth, "device", dev, NULL);

647 648 649
  if (dev->status != BOLT_STATUS_CONNECTED &&
      dev->status != BOLT_STATUS_AUTH_ERROR)
    {
650 651
      bolt_auth_return_new_error (auth, BOLT_ERROR, BOLT_ERROR_FAILED,
                                  "wrong device state: %u", dev->status);
652

653 654
      if (callback)
        callback (G_OBJECT (dev), G_ASYNC_RESULT (auth), user_data);
655

656
      return;
657 658 659
    }

  task = g_task_new (dev, NULL, authorize_thread_done, NULL);
660 661 662
  auth_data = g_slice_new (AuthData);
  auth_data->callback = callback;
  auth_data->user_data = user_data;
663
  auth_data->auth = g_object_ref (auth);
664 665
  g_task_set_task_data (task, auth_data, auth_data_free);

666
  g_object_set (dev, "status", BOLT_STATUS_AUTHORIZING, NULL);
667 668 669 670 671 672 673 674 675

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


/* dbus methods */

static void
676 677 678
handle_authorize_done (GObject      *device,
                       GAsyncResult *res,
                       gpointer      user_data)
679
{
680 681 682 683 684 685 686 687 688
  GDBusMethodInvocation *inv;
  GError *error = NULL;
  BoltAuth *auth;
  BoltDevice *dev;
  gboolean ok;

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

690
  ok = bolt_auth_check (auth, &error);
691
  if (ok)
692
    bolt_dbus_device_complete_authorize (BOLT_DBUS_DEVICE (dev), inv);
693
  else
694
    g_dbus_method_invocation_take_error (inv, error);
695 696 697 698
}

static gboolean
handle_authorize (BoltDBusDevice        *object,
699
                  GDBusMethodInvocation *inv,
700 701 702 703
                  gpointer               user_data)
{
  BoltDevice *dev = BOLT_DEVICE (object);
  GError *error = NULL;
704 705 706
  BoltAuth *auth;
  BoltSecurity level;
  BoltKey *key;
707

708 709
  level = dev->security;
  key = NULL;
710

711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726
  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);
727 728 729 730

  return TRUE;
}

731 732 733
/* public methods */

BoltDevice *
734
bolt_device_new_for_udev (struct udev_device *udev,
735 736
                          GError            **error)
{
737 738 739 740
  const char *uid;
  const char *name;
  const char *vendor;
  const char *syspath;
741
  const char *parent;
742
  BoltDevice *dev;
743

744 745 746 747 748 749 750
  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;
    }
751

752 753
  syspath = udev_device_get_syspath (udev);
  g_return_val_if_fail (syspath != NULL, NULL);
754

755
  name = read_sysattr_name (udev, "device", error);
756 757 758
  if (name == NULL)
    return NULL;

759
  vendor = read_sysattr_name (udev, "vendor", error);
760 761
  if (vendor == NULL)
    return NULL;
762

763
  parent = bolt_sysfs_get_parent_uid (udev);
764
  dev = g_object_new (BOLT_TYPE_DEVICE,
765 766 767 768
                      "uid", uid,
                      "name", name,
                      "vendor", vendor,
                      "sysfs-path", syspath,
769
                      "parent", parent,
770 771
                      NULL);

772
  dev->status = bolt_status_from_udev (udev);
773
  dev->security = bolt_sysfs_security_for_device (udev);
774

775 776 777
  return dev;
}

778
const char *
779 780 781 782
bolt_device_export (BoltDevice      *device,
                    GDBusConnection *connection,
                    GError         **error)
{
783
  const char *path;
784
  gboolean ok;
785 786

  g_return_val_if_fail (BOLT_IS_DEVICE (device), FALSE);
787

788
  path = bolt_device_get_object_path (device);
789

790 791 792 793 794
  ok = g_dbus_interface_skeleton_export (G_DBUS_INTERFACE_SKELETON (device),
                                         connection,
                                         path,
                                         error);
  return ok ? path : NULL;
795 796 797 798 799 800 801
}

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

803 804 805 806 807 808

BoltStatus
bolt_device_connected (BoltDevice         *dev,
                       struct udev_device *udev)
{
  const char *syspath;
809
  const char *parent;
810 811 812 813 814
  BoltSecurity security;
  BoltStatus status;

  syspath = udev_device_get_syspath (udev);
  status = bolt_status_from_udev (udev);
815
  security = bolt_sysfs_security_for_device (udev);
816
  parent = bolt_sysfs_get_parent_uid (udev);
817 818

  g_object_set (G_OBJECT (dev),
819
                "parent", parent,
820 821 822 823 824
                "sysfs-path", syspath,
                "security", security,
                "status", status,
                NULL);

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

827 828 829 830 831 832 833
  return status;
}

BoltStatus
bolt_device_disconnected (BoltDevice *dev)
{
  g_object_set (G_OBJECT (dev),
834
                "parent", NULL,
835 836 837 838 839
                "sysfs-path", NULL,
                "security", BOLT_SECURITY_NONE,
                "status", BOLT_STATUS_DISCONNECTED,
                NULL);

840 841 842 843 844
  /* 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)
845
    g_object_set (G_OBJECT (dev), "key", BOLT_KEY_HAVE, NULL);
846

847 848 849 850 851 852
  return dev->status;
}

gboolean
bolt_device_is_connected (BoltDevice *device)
{
853
  return bolt_status_is_connected (device->status);
854 855
}

856 857 858 859 860 861 862 863 864 865 866 867 868
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;
}

869
BoltKeyState
870
bolt_device_get_keystate (BoltDevice *dev)
871 872 873 874
{
  return dev->key;
}

875 876 877 878 879 880
const char *
bolt_device_get_name (BoltDevice *dev)
{
  return dev->name;
}

881 882 883 884 885 886 887 888 889
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;

890
      path = g_strdup_printf (BOLT_DBUS_PATH "/devices/%s", device->uid);
891 892 893 894 895 896 897
      g_strdelimit (path, "-", '_');

      device->dbus_path = path;
    }

  return device->dbus_path;
}
898

899 900 901 902 903 904
BoltPolicy
bolt_device_get_policy (BoltDevice *dev)
{
  return dev->policy;
}

905 906 907 908 909 910
const char *
bolt_device_get_uid (BoltDevice *dev)
{
  return dev->uid;
}

911 912 913 914 915 916
BoltSecurity
bolt_device_get_security (BoltDevice *dev)
{
  return dev->security;
}

Christian Kellner's avatar
Christian Kellner committed
917 918 919 920 921 922
BoltStatus
bolt_device_get_status (BoltDevice *dev)
{
  return dev->status;
}

923 924
gboolean
bolt_device_get_stored (BoltDevice *dev)
925
{
926
  return dev->store != NULL;
927 928
}

929 930 931 932 933
const char *
bolt_device_get_syspath (BoltDevice *dev)
{
  return dev->syspath;
}
934 935 936 937 938 939

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