~ci-train-bot/lightdm/lightdm-ubuntu-yakkety-landing-032

« back to all changes in this revision

Viewing changes to liblightdm-gobject/greeter.c

  • Committer: Robert Ancell
  • Date: 2016-06-27 04:04:49 UTC
  • Revision ID: robert.ancell@canonical.com-20160627040449-tar947ju9pqseegq
Return errors from all liblightdm methods

Show diffs side-by-side

added added

removed removed

Lines of Context:
127
127
typedef struct
128
128
{
129
129
    GObject parent_instance;
 
130
    LightDMGreeter *greeter;
130
131
    GCancellable *cancellable;
131
132
    GAsyncReadyCallback callback;
132
133
    gpointer user_data;
133
134
    gboolean complete;
134
 
    gboolean connected;
135
 
    guint32 return_code;
 
135
    gboolean result;
 
136
    GError *error;
136
137
    gchar *dir;
137
138
} Request;
138
139
typedef struct
144
145
#define REQUEST(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), request_get_type (), Request))
145
146
G_DEFINE_TYPE_WITH_CODE (Request, request, G_TYPE_OBJECT, G_IMPLEMENT_INTERFACE (G_TYPE_ASYNC_RESULT, request_iface_init));
146
147
 
 
148
static gboolean from_server_cb (GIOChannel *source, GIOCondition condition, gpointer data);
 
149
 
147
150
GType
148
151
lightdm_greeter_error_get_type (void)
149
152
{
151
154
 
152
155
    if (G_UNLIKELY(enum_type == 0)) {
153
156
        static const GEnumValue values[] = {
 
157
            { LIGHTDM_GREETER_ERROR_COMMUNICATION_ERROR, "LIGHTDM_GREETER_ERROR_COMMUNICATION_ERROR", "communication-error" },
154
158
            { LIGHTDM_GREETER_ERROR_CONNECTION_FAILED, "LIGHTDM_GREETER_ERROR_CONNECTION_FAILED", "connection-failed" },
155
159
            { LIGHTDM_GREETER_ERROR_SESSION_FAILED, "LIGHTDM_GREETER_ERROR_SESSION_FAILED", "session-failed" },
 
160
            { LIGHTDM_GREETER_ERROR_NO_AUTOLOGIN, "LIGHTDM_GREETER_ERROR_NO_AUTOLOGIN", "no-autologin" },
 
161
            { LIGHTDM_GREETER_ERROR_INVALID_USER, "LIGHTDM_GREETER_ERROR_INVALID_USER", "invalid-user" },          
156
162
            { 0, NULL, NULL }
157
163
        };
158
164
        enum_type = g_enum_register_static (g_intern_static_string ("LightDMGreeterError"), values);
231
237
}
232
238
 
233
239
static Request *
234
 
request_new (GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data)
 
240
request_new (LightDMGreeter *greeter, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data)
235
241
{
236
242
    Request *request;
237
243
 
238
244
    request = g_object_new (request_get_type (), NULL);
 
245
    request->greeter = g_object_ref (greeter);
239
246
    if (cancellable)
240
247
        request->cancellable = g_object_ref (cancellable);
241
248
    request->callback = callback;
244
251
    return request;
245
252
}
246
253
 
 
254
static gboolean
 
255
request_callback_cb (gpointer data)
 
256
{
 
257
    Request *request = data;
 
258
    if (request->callback)
 
259
        request->callback (G_OBJECT (request->greeter), G_ASYNC_RESULT (request), request->user_data);
 
260
    g_object_unref (request);
 
261
    return G_SOURCE_REMOVE;
 
262
}
 
263
 
247
264
static void
248
 
request_complete (Request *request, GObject *object)
 
265
request_complete (Request *request)
249
266
{
250
267
    request->complete = TRUE;
251
268
 
255
272
    if (request->cancellable && g_cancellable_is_cancelled (request->cancellable))
256
273
        return;
257
274
 
258
 
    request->callback (object, G_ASYNC_RESULT (request), request->user_data);
 
275
    g_idle_add (request_callback_cb, g_object_ref (request));
259
276
}
260
277
 
261
278
static gboolean
276
293
    return 4;
277
294
}
278
295
 
279
 
static void
280
 
write_int (guint8 *buffer, gint buffer_length, guint32 value, gsize *offset)
 
296
static gboolean
 
297
write_int (guint8 *buffer, gint buffer_length, guint32 value, gsize *offset, GError **error)
281
298
{
282
299
    if (*offset + 4 >= buffer_length)
283
 
        return;
 
300
    {
 
301
        g_set_error_literal (error, LIGHTDM_GREETER_ERROR, LIGHTDM_GREETER_ERROR_COMMUNICATION_ERROR,
 
302
                             "Not enough buffer space to write integer");
 
303
        return FALSE;
 
304
    }
284
305
    buffer[*offset] = value >> 24;
285
306
    buffer[*offset+1] = (value >> 16) & 0xFF;
286
307
    buffer[*offset+2] = (value >> 8) & 0xFF;
287
308
    buffer[*offset+3] = value & 0xFF;
288
309
    *offset += 4;
 
310
 
 
311
    return TRUE;
289
312
}
290
313
 
291
 
static void
292
 
write_string (guint8 *buffer, gint buffer_length, const gchar *value, gsize *offset)
 
314
static gboolean
 
315
write_string (guint8 *buffer, gint buffer_length, const gchar *value, gsize *offset, GError **error)
293
316
{
294
317
    gint length = 0;
295
318
 
296
319
    if (value)
297
320
        length = strlen (value);
298
 
    write_int (buffer, buffer_length, length, offset);
 
321
    if (!write_int (buffer, buffer_length, length, offset, error))
 
322
        return FALSE;
299
323
    if (*offset + length >= buffer_length)
300
 
        return;
 
324
    {
 
325
        g_set_error (error, LIGHTDM_GREETER_ERROR, LIGHTDM_GREETER_ERROR_COMMUNICATION_ERROR,
 
326
                     "Not enough buffer space to write string of length %d octets", length);
 
327
        return FALSE;
 
328
    }
301
329
    if (value)
302
330
        memcpy (buffer + *offset, value, length);
303
331
    *offset += length;
 
332
 
 
333
    return TRUE;
304
334
}
305
335
 
306
336
static guint32
352
382
        return int_length ();
353
383
}
354
384
 
355
 
static void
356
 
write_header (guint8 *buffer, gint buffer_length, guint32 id, guint32 length, gsize *offset)
 
385
static gboolean
 
386
write_header (guint8 *buffer, gint buffer_length, guint32 id, guint32 length, gsize *offset, GError **error)
357
387
{
358
 
    write_int (buffer, buffer_length, id, offset);
359
 
    write_int (buffer, buffer_length, length, offset);
 
388
    return write_int (buffer, buffer_length, id, offset, error) &&
 
389
           write_int (buffer, buffer_length, length, offset, error);
360
390
}
361
391
 
362
392
static guint32
367
397
}
368
398
 
369
399
static gboolean
370
 
send_message (LightDMGreeter *greeter, guint8 *message, gsize message_length)
 
400
connect_to_daemon (LightDMGreeter *greeter, GError **error)
 
401
{
 
402
    LightDMGreeterPrivate *priv = GET_PRIVATE (greeter);
 
403
    const gchar *to_server_fd, *from_server_fd;
 
404
 
 
405
    if (priv->to_server_channel || priv->from_server_channel)
 
406
        return TRUE;
 
407
 
 
408
    to_server_fd = g_getenv ("LIGHTDM_TO_SERVER_FD");
 
409
    from_server_fd = g_getenv ("LIGHTDM_FROM_SERVER_FD");
 
410
    if (!to_server_fd || !from_server_fd)
 
411
    {
 
412
        g_set_error_literal (error, LIGHTDM_GREETER_ERROR, LIGHTDM_GREETER_ERROR_CONNECTION_FAILED,
 
413
                             "Unable to determine socket to daemon");
 
414
        return FALSE;
 
415
    }
 
416
 
 
417
    priv->to_server_channel = g_io_channel_unix_new (atoi (to_server_fd));
 
418
    priv->from_server_channel = g_io_channel_unix_new (atoi (from_server_fd));
 
419
    g_io_add_watch (priv->from_server_channel, G_IO_IN, from_server_cb, greeter);
 
420
 
 
421
    if (!g_io_channel_set_encoding (priv->to_server_channel, NULL, error) ||
 
422
        !g_io_channel_set_encoding (priv->from_server_channel, NULL, error))
 
423
        return FALSE;
 
424
 
 
425
    return TRUE;
 
426
}
 
427
 
 
428
static gboolean
 
429
send_message (LightDMGreeter *greeter, guint8 *message, gsize message_length, GError **error)
371
430
{
372
431
    LightDMGreeterPrivate *priv = GET_PRIVATE (greeter);
373
432
    gchar *data;
374
433
    gsize data_length;
375
 
    GError *error = NULL;
376
434
    guint32 stated_length;
 
435
    GError *flush_error = NULL;
377
436
 
378
 
    if (!priv->to_server_channel)
 
437
    if (!connect_to_daemon (greeter, error))
379
438
        return FALSE;
380
439
 
381
440
    /* Double check that we're sending well-formed messages.  If we say we're
386
445
    stated_length = HEADER_SIZE + get_message_length (message, message_length);
387
446
    if (stated_length != message_length)
388
447
    {
389
 
        g_warning ("Refusing to write malformed packet to daemon: declared size is %u, but actual size is %zu", stated_length, message_length);
 
448
        g_set_error (error, LIGHTDM_GREETER_ERROR, LIGHTDM_GREETER_ERROR_COMMUNICATION_ERROR,
 
449
                     "Refusing to write malformed packet to daemon: declared size is %u, but actual size is %zu",
 
450
                     stated_length, message_length);
390
451
        return FALSE;
391
452
    }
392
453
 
396
457
    {
397
458
        GIOStatus status;
398
459
        gsize n_written;
 
460
        GError *write_error = NULL;
399
461
 
400
 
        status = g_io_channel_write_chars (priv->to_server_channel, data, data_length, &n_written, &error);
401
 
        if (error)
402
 
            g_warning ("Error writing to daemon: %s", error->message);
403
 
        g_clear_error (&error);
404
 
        if (status != G_IO_STATUS_NORMAL)
 
462
        status = g_io_channel_write_chars (priv->to_server_channel, data, data_length, &n_written, &write_error);
 
463
        if (write_error)
 
464
            g_set_error (error, LIGHTDM_GREETER_ERROR, LIGHTDM_GREETER_ERROR_COMMUNICATION_ERROR,
 
465
                         "Failed to write to daemon: %s",
 
466
                         write_error->message);
 
467
        g_clear_error (&write_error);
 
468
        if (status != G_IO_STATUS_NORMAL) 
405
469
            return FALSE;
406
470
        data_length -= n_written;
407
471
        data += n_written;
408
472
    }
409
473
 
410
474
    g_debug ("Wrote %zi bytes to daemon", message_length);
411
 
    g_io_channel_flush (priv->to_server_channel, &error);
412
 
    if (error)
413
 
        g_warning ("Failed to flush data to daemon: %s", error->message);
414
 
    g_clear_error (&error);
 
475
    if (!g_io_channel_flush (priv->to_server_channel, &flush_error))
 
476
    {
 
477
        g_set_error (error, LIGHTDM_GREETER_ERROR, LIGHTDM_GREETER_ERROR_COMMUNICATION_ERROR,
 
478
                     "Failed to write to daemon: %s",
 
479
                     flush_error->message);
 
480
        g_clear_error (&flush_error);
 
481
        return FALSE;
 
482
    }
415
483
 
416
484
    return TRUE;
417
485
}
454
522
    request = g_list_nth_data (priv->connect_requests, 0);
455
523
    if (request)
456
524
    {
457
 
        request->connected = TRUE;
458
 
        request_complete (request, G_OBJECT (greeter));
 
525
        request->result = TRUE;
 
526
        request_complete (request);
459
527
        priv->connect_requests = g_list_remove (priv->connect_requests, request);
460
528
        g_object_unref (request);
461
529
    }
606
674
    request = g_list_nth_data (priv->start_session_requests, 0);
607
675
    if (request)
608
676
    {
609
 
        request->return_code = read_int (message, message_length, offset);
610
 
        request_complete (request, G_OBJECT (greeter));
 
677
        guint32 return_code;
 
678
 
 
679
        return_code = read_int (message, message_length, offset);
 
680
        if (return_code == 0)
 
681
            request->result = TRUE;
 
682
        else
 
683
            request->error = g_error_new (LIGHTDM_GREETER_ERROR, LIGHTDM_GREETER_ERROR_SESSION_FAILED,
 
684
                                          "Session returned error code %d", return_code);
 
685
        request_complete (request);
611
686
        priv->start_session_requests = g_list_remove (priv->start_session_requests, request);
612
687
        g_object_unref (request);
613
688
    }
629
704
        {
630
705
            g_free (request->dir);
631
706
            request->dir = NULL;
 
707
            request->error = g_error_new (LIGHTDM_GREETER_ERROR, LIGHTDM_GREETER_ERROR_INVALID_USER,
 
708
                                          "No such user");
632
709
        }
633
 
        request_complete (request, G_OBJECT (greeter));
 
710
        request_complete (request);
634
711
        priv->ensure_shared_data_dir_requests = g_list_remove (priv->ensure_shared_data_dir_requests, request);
635
712
        g_object_unref (request);
636
713
    }
673
750
    }
674
751
}
675
752
 
676
 
static guint8 *
677
 
recv_message (LightDMGreeter *greeter, gsize *length, gboolean block)
 
753
static gboolean
 
754
recv_message (LightDMGreeter *greeter, gboolean block, guint8 **message, gsize *length, GError **error)
678
755
{
679
756
    LightDMGreeterPrivate *priv = GET_PRIVATE (greeter);
680
757
    gsize n_to_read, n_read;
681
 
    guint8 *buffer;
682
 
    GError *error = NULL;
683
758
 
684
 
    if (!priv->from_server_channel)
685
 
        return NULL;
 
759
    if (!connect_to_daemon (greeter, error))
 
760
        return FALSE;
686
761
 
687
762
    /* Read the header, or the whole message if we already have that */
688
763
    n_to_read = HEADER_SIZE;
692
767
    do
693
768
    {
694
769
        GIOStatus status;
 
770
        GError *read_error = NULL;
 
771
 
695
772
        status = g_io_channel_read_chars (priv->from_server_channel,
696
773
                                          (gchar *) priv->read_buffer + priv->n_read,
697
774
                                          n_to_read - priv->n_read,
698
775
                                          &n_read,
699
 
                                          &error);
700
 
        if (error)
701
 
            g_warning ("Error reading from server: %s", error->message);
702
 
        g_clear_error (&error);
 
776
                                          &read_error);
703
777
        if (status != G_IO_STATUS_NORMAL)
704
 
            break;
 
778
        {
 
779
            g_set_error (error, LIGHTDM_GREETER_ERROR, LIGHTDM_GREETER_ERROR_COMMUNICATION_ERROR,
 
780
                         "Failed to read from daemon: %s",
 
781
                         read_error->message);
 
782
            g_clear_error (&read_error);
 
783
            return FALSE;
 
784
        }
705
785
 
706
786
        g_debug ("Read %zi bytes from daemon", n_read);
707
787
 
710
790
 
711
791
    /* Stop if haven't got all the data we want */
712
792
    if (priv->n_read != n_to_read)
713
 
        return NULL;
 
793
    {
 
794
        if (message)
 
795
            *message = NULL;
 
796
        if (length)
 
797
            *length = 0;
 
798
        return TRUE;
 
799
    }
714
800
 
715
801
    /* If have header, rerun for content */
716
802
    if (priv->n_read == HEADER_SIZE)
719
805
        if (n_to_read > 0)
720
806
        {
721
807
            priv->read_buffer = g_realloc (priv->read_buffer, HEADER_SIZE + n_to_read);
722
 
            return recv_message (greeter, length, block);
 
808
            return recv_message (greeter, block, message, length, error);
723
809
        }
724
810
    }
725
811
 
726
 
    buffer = priv->read_buffer;
727
 
    *length = priv->n_read;
 
812
    if (message)
 
813
        *message = priv->read_buffer;
 
814
    else
 
815
        g_free (priv->read_buffer);
 
816
    if (length)
 
817
        *length = priv->n_read;
728
818
 
729
819
    priv->read_buffer = g_malloc (priv->n_read);
730
820
    priv->n_read = 0;
731
821
 
732
 
    return buffer;
 
822
    return TRUE;
733
823
}
734
824
 
735
825
static gboolean
738
828
    LightDMGreeter *greeter = data;
739
829
    guint8 *message;
740
830
    gsize message_length;
 
831
    GError *error = NULL;
741
832
 
742
833
    /* Read one message and process it */
743
 
    message = recv_message (greeter, &message_length, FALSE);
 
834
    if (!recv_message (greeter, FALSE, &message, &message_length, &error))
 
835
    {
 
836
        // FIXME: Should push this up to the client somehow
 
837
        g_warning ("Failed to read from daemon: %s\n", error->message);
 
838
        g_clear_error (&error);
 
839
        return G_SOURCE_REMOVE;
 
840
    }
 
841
 
744
842
    if (message)
745
843
    {
746
844
        handle_message (greeter, message, message_length);
747
845
        g_free (message);
748
846
    }
749
847
 
750
 
    return TRUE;
 
848
    return G_SOURCE_CONTINUE;
751
849
}
752
850
 
753
851
static gboolean
754
 
send_connect (LightDMGreeter *greeter, gboolean resettable)
 
852
send_connect (LightDMGreeter *greeter, gboolean resettable, GError **error)
755
853
{
756
854
    guint8 message[MAX_MESSAGE_LENGTH];
757
855
    gsize offset = 0;
758
856
 
759
857
    g_debug ("Connecting to display manager...");
760
 
    write_header (message, MAX_MESSAGE_LENGTH, GREETER_MESSAGE_CONNECT, string_length (VERSION) + int_length (), &offset);
761
 
    write_string (message, MAX_MESSAGE_LENGTH, VERSION, &offset);
762
 
    write_int (message, MAX_MESSAGE_LENGTH, resettable ? 1 : 0, &offset);
763
 
 
764
 
    return send_message (greeter, message, offset);
 
858
    return write_header (message, MAX_MESSAGE_LENGTH, GREETER_MESSAGE_CONNECT, string_length (VERSION) + int_length (), &offset, error) &&
 
859
           write_string (message, MAX_MESSAGE_LENGTH, VERSION, &offset, error) &&
 
860
           write_int (message, MAX_MESSAGE_LENGTH, resettable ? 1 : 0, &offset, error) &&
 
861
           send_message (greeter, message, offset, error);
765
862
}
766
863
 
767
864
static gboolean
768
 
send_start_session (LightDMGreeter *greeter, const gchar *session)
 
865
send_start_session (LightDMGreeter *greeter, const gchar *session, GError **error)
769
866
{
770
867
    guint8 message[MAX_MESSAGE_LENGTH];
771
868
    gsize offset = 0;
775
872
    else
776
873
        g_debug ("Starting default session");
777
874
 
778
 
    write_header (message, MAX_MESSAGE_LENGTH, GREETER_MESSAGE_START_SESSION, string_length (session), &offset);
779
 
    write_string (message, MAX_MESSAGE_LENGTH, session, &offset);
780
 
    return send_message (greeter, message, offset);
 
875
    return write_header (message, MAX_MESSAGE_LENGTH, GREETER_MESSAGE_START_SESSION, string_length (session), &offset, error) &&
 
876
           write_string (message, MAX_MESSAGE_LENGTH, session, &offset, error) &&
 
877
           send_message (greeter, message, offset, error);
781
878
}
782
879
 
783
880
static gboolean
784
 
send_ensure_shared_data_dir (LightDMGreeter *greeter, const gchar *username)
 
881
send_ensure_shared_data_dir (LightDMGreeter *greeter, const gchar *username, GError **error)
785
882
{
786
883
    guint8 message[MAX_MESSAGE_LENGTH];
787
884
    gsize offset = 0;
788
885
 
789
886
    g_debug ("Ensuring data directory for user %s", username);
790
887
 
791
 
    write_header (message, MAX_MESSAGE_LENGTH, GREETER_MESSAGE_ENSURE_SHARED_DIR, string_length (username), &offset);
792
 
    write_string (message, MAX_MESSAGE_LENGTH, username, &offset);
793
 
    return send_message (greeter, message, offset);
 
888
    return write_header (message, MAX_MESSAGE_LENGTH, GREETER_MESSAGE_ENSURE_SHARED_DIR, string_length (username), &offset, error) &&
 
889
           write_string (message, MAX_MESSAGE_LENGTH, username, &offset, error) &&
 
890
           send_message (greeter, message, offset, error);
794
891
}
795
892
 
796
893
/**
811
908
{
812
909
    LightDMGreeterPrivate *priv;
813
910
    Request *request;
 
911
    GError *error = NULL;
814
912
 
815
913
    g_return_if_fail (LIGHTDM_IS_GREETER (greeter));
816
914
 
817
915
    priv = GET_PRIVATE (greeter);
818
916
 
819
 
    request = request_new (cancellable, callback, user_data);
820
 
    priv->connect_requests = g_list_append (priv->connect_requests, request);
821
 
    send_connect (greeter, priv->resettable);
 
917
    request = request_new (greeter, cancellable, callback, user_data);
 
918
    if (send_connect (greeter, priv->resettable, &error))
 
919
        priv->connect_requests = g_list_append (priv->connect_requests, request);
 
920
    else
 
921
    {
 
922
        request->error = error;
 
923
        request_complete (request);
 
924
        g_object_unref (request);
 
925
    }
822
926
}
823
927
 
824
928
/**
837
941
    Request *request = REQUEST (result);
838
942
 
839
943
    g_return_val_if_fail (LIGHTDM_IS_GREETER (greeter), FALSE);
840
 
 
841
 
    if (request->connected)
842
 
        return TRUE;
843
 
    else
844
 
    {
845
 
        g_set_error_literal (error, LIGHTDM_GREETER_ERROR, LIGHTDM_GREETER_ERROR_CONNECTION_FAILED, "Failed to connect to daemon");
846
 
        return FALSE;
847
 
    }
 
944
  
 
945
    g_propagate_error (error, request->error);
 
946
    return request->result;
848
947
}
849
948
 
850
949
/**
867
966
    priv = GET_PRIVATE (greeter);
868
967
 
869
968
    /* Read until we are connected */
870
 
    send_connect (greeter, priv->resettable);
871
 
    request = request_new (NULL, NULL, NULL);
 
969
    if (!send_connect (greeter, priv->resettable, error))
 
970
        return FALSE;
 
971
    request = request_new (greeter, NULL, NULL, NULL);
872
972
    priv->connect_requests = g_list_append (priv->connect_requests, g_object_ref (request));
873
973
    do
874
974
    {
875
975
        guint8 *message;
876
976
        gsize message_length;
877
977
 
878
 
        message = recv_message (greeter, &message_length, TRUE);
879
 
        if (!message)
880
 
            break;
 
978
        if (!recv_message (greeter, TRUE, &message, &message_length, error))
 
979
            return FALSE;
881
980
        handle_message (greeter, message, message_length);
882
981
        g_free (message);
883
982
    } while (!request->complete);
1154
1253
 * lightdm_greeter_authenticate:
1155
1254
 * @greeter: A #LightDMGreeter
1156
1255
 * @username: (allow-none): A username or #NULL to prompt for a username.
 
1256
 * @error: return location for a #GError, or %NULL
1157
1257
 *
1158
1258
 * Starts the authentication procedure for a user.
 
1259
 *
 
1260
 * Return value: #TRUE if authentication request sent.
1159
1261
 **/
1160
 
void
1161
 
lightdm_greeter_authenticate (LightDMGreeter *greeter, const gchar *username)
 
1262
gboolean
 
1263
lightdm_greeter_authenticate (LightDMGreeter *greeter, const gchar *username, GError **error)
1162
1264
{
1163
1265
    LightDMGreeterPrivate *priv;
1164
1266
    guint8 message[MAX_MESSAGE_LENGTH];
1165
1267
    gsize offset = 0;
1166
1268
 
1167
 
    g_return_if_fail (LIGHTDM_IS_GREETER (greeter));
 
1269
    g_return_val_if_fail (LIGHTDM_IS_GREETER (greeter), FALSE);
1168
1270
 
1169
1271
    priv = GET_PRIVATE (greeter);
1170
1272
 
1171
 
    g_return_if_fail (priv->connected);
 
1273
    g_return_val_if_fail (priv->connected, FALSE);
1172
1274
 
1173
1275
    priv->cancelling_authentication = FALSE;
1174
1276
    priv->authenticate_sequence_number++;
1181
1283
    }
1182
1284
 
1183
1285
    g_debug ("Starting authentication for user %s...", username);
1184
 
    write_header (message, MAX_MESSAGE_LENGTH, GREETER_MESSAGE_AUTHENTICATE, int_length () + string_length (username), &offset);
1185
 
    write_int (message, MAX_MESSAGE_LENGTH, priv->authenticate_sequence_number, &offset);
1186
 
    write_string (message, MAX_MESSAGE_LENGTH, username, &offset);
1187
 
    send_message (greeter, message, offset);
 
1286
    return write_header (message, MAX_MESSAGE_LENGTH, GREETER_MESSAGE_AUTHENTICATE, int_length () + string_length (username), &offset, error) &&
 
1287
           write_int (message, MAX_MESSAGE_LENGTH, priv->authenticate_sequence_number, &offset, error) &&
 
1288
           write_string (message, MAX_MESSAGE_LENGTH, username, &offset, error) &&
 
1289
           send_message (greeter, message, offset, error);
1188
1290
}
1189
1291
 
1190
1292
/**
1191
1293
 * lightdm_greeter_authenticate_as_guest:
1192
1294
 * @greeter: A #LightDMGreeter
 
1295
 * @error: return location for a #GError, or %NULL
1193
1296
 *
1194
1297
 * Starts the authentication procedure for the guest user.
 
1298
 *
 
1299
 * Return value: #TRUE if authentication request sent.
1195
1300
 **/
1196
 
void
1197
 
lightdm_greeter_authenticate_as_guest (LightDMGreeter *greeter)
 
1301
gboolean
 
1302
lightdm_greeter_authenticate_as_guest (LightDMGreeter *greeter, GError **error)
1198
1303
{
1199
1304
    LightDMGreeterPrivate *priv;
1200
1305
    guint8 message[MAX_MESSAGE_LENGTH];
1201
1306
    gsize offset = 0;
1202
1307
 
1203
 
    g_return_if_fail (LIGHTDM_IS_GREETER (greeter));
 
1308
    g_return_val_if_fail (LIGHTDM_IS_GREETER (greeter), FALSE);
1204
1309
 
1205
1310
    priv = GET_PRIVATE (greeter);
1206
1311
 
1207
 
    g_return_if_fail (priv->connected);
 
1312
    g_return_val_if_fail (priv->connected, FALSE);
1208
1313
 
1209
1314
    priv->cancelling_authentication = FALSE;
1210
1315
    priv->authenticate_sequence_number++;
1214
1319
    priv->authentication_user = NULL;
1215
1320
 
1216
1321
    g_debug ("Starting authentication for guest account...");
1217
 
    write_header (message, MAX_MESSAGE_LENGTH, GREETER_MESSAGE_AUTHENTICATE_AS_GUEST, int_length (), &offset);
1218
 
    write_int (message, MAX_MESSAGE_LENGTH, priv->authenticate_sequence_number, &offset);
1219
 
    send_message (greeter, message, offset);
 
1322
    return write_header (message, MAX_MESSAGE_LENGTH, GREETER_MESSAGE_AUTHENTICATE_AS_GUEST, int_length (), &offset, error) &&
 
1323
           write_int (message, MAX_MESSAGE_LENGTH, priv->authenticate_sequence_number, &offset, error) &&
 
1324
           send_message (greeter, message, offset, error);
1220
1325
}
1221
1326
 
1222
1327
/**
1223
1328
 * lightdm_greeter_authenticate_autologin:
1224
1329
 * @greeter: A #LightDMGreeter
 
1330
 * @error: return location for a #GError, or %NULL
1225
1331
 *
1226
1332
 * Starts the authentication procedure for the automatic login user.
 
1333
 *
 
1334
 * Return value: #TRUE if authentication request sent.
1227
1335
 **/
1228
 
void
1229
 
lightdm_greeter_authenticate_autologin (LightDMGreeter *greeter)
 
1336
gboolean
 
1337
lightdm_greeter_authenticate_autologin (LightDMGreeter *greeter, GError **error)
1230
1338
{
1231
1339
    const gchar *user;
1232
1340
 
1233
1341
    user = lightdm_greeter_get_autologin_user_hint (greeter);
1234
1342
    if (lightdm_greeter_get_autologin_guest_hint (greeter))
1235
 
        lightdm_greeter_authenticate_as_guest (greeter);
 
1343
        return lightdm_greeter_authenticate_as_guest (greeter, error);
1236
1344
    else if (user)
1237
 
        lightdm_greeter_authenticate (greeter, user);
 
1345
        return lightdm_greeter_authenticate (greeter, user, error);
 
1346
    else
 
1347
    {
 
1348
        g_set_error_literal (error, LIGHTDM_GREETER_ERROR, LIGHTDM_GREETER_ERROR_NO_AUTOLOGIN,
 
1349
                             "Can't authenticate autologin; autologin not configured");
 
1350
        return FALSE;
 
1351
    }
1238
1352
}
1239
1353
 
1240
1354
/**
1242
1356
 * @greeter: A #LightDMGreeter
1243
1357
 * @session: The name of a remote session
1244
1358
 * @username: (allow-none): A username of #NULL to prompt for a username.
 
1359
 * @error: return location for a #GError, or %NULL
1245
1360
 *
1246
1361
 * Start authentication for a remote session type.
 
1362
 *
 
1363
 * Return value: #TRUE if authentication request sent.
1247
1364
 **/
1248
 
void
1249
 
lightdm_greeter_authenticate_remote (LightDMGreeter *greeter, const gchar *session, const gchar *username)
 
1365
gboolean
 
1366
lightdm_greeter_authenticate_remote (LightDMGreeter *greeter, const gchar *session, const gchar *username, GError **error)
1250
1367
{
1251
1368
    LightDMGreeterPrivate *priv;
1252
1369
    guint8 message[MAX_MESSAGE_LENGTH];
1253
1370
    gsize offset = 0;
1254
1371
 
1255
 
    g_return_if_fail (LIGHTDM_IS_GREETER (greeter));
 
1372
    g_return_val_if_fail (LIGHTDM_IS_GREETER (greeter), FALSE);
1256
1373
 
1257
1374
    priv = GET_PRIVATE (greeter);
1258
1375
 
1259
 
    g_return_if_fail (priv->connected);
 
1376
    g_return_val_if_fail (priv->connected, FALSE);
1260
1377
 
1261
1378
    priv->cancelling_authentication = FALSE;
1262
1379
    priv->authenticate_sequence_number++;
1269
1386
        g_debug ("Starting authentication for remote session %s as user %s...", session, username);
1270
1387
    else
1271
1388
        g_debug ("Starting authentication for remote session %s...", session);
1272
 
    write_header (message, MAX_MESSAGE_LENGTH, GREETER_MESSAGE_AUTHENTICATE_REMOTE, int_length () + string_length (session) + string_length (username), &offset);
1273
 
    write_int (message, MAX_MESSAGE_LENGTH, priv->authenticate_sequence_number, &offset);
1274
 
    write_string (message, MAX_MESSAGE_LENGTH, session, &offset);
1275
 
    write_string (message, MAX_MESSAGE_LENGTH, username, &offset);
1276
 
    send_message (greeter, message, offset);
 
1389
 
 
1390
    return write_header (message, MAX_MESSAGE_LENGTH, GREETER_MESSAGE_AUTHENTICATE_REMOTE, int_length () + string_length (session) + string_length (username), &offset, error) &&
 
1391
           write_int (message, MAX_MESSAGE_LENGTH, priv->authenticate_sequence_number, &offset, error) &&
 
1392
           write_string (message, MAX_MESSAGE_LENGTH, session, &offset, error) &&
 
1393
           write_string (message, MAX_MESSAGE_LENGTH, username, &offset, error) &&
 
1394
           send_message (greeter, message, offset, error);
1277
1395
}
1278
1396
 
1279
1397
/**
1280
1398
 * lightdm_greeter_respond:
1281
1399
 * @greeter: A #LightDMGreeter
1282
1400
 * @response: Response to a prompt
 
1401
 * @error: return location for a #GError, or %NULL
1283
1402
 *
1284
1403
 * Provide response to a prompt.  May be one in a series.
 
1404
 *
 
1405
 * Return value: #TRUE if response sent.
1285
1406
 **/
1286
 
void
1287
 
lightdm_greeter_respond (LightDMGreeter *greeter, const gchar *response)
 
1407
gboolean
 
1408
lightdm_greeter_respond (LightDMGreeter *greeter, const gchar *response, GError **error)
1288
1409
{
1289
1410
    LightDMGreeterPrivate *priv;
1290
1411
    guint8 message[MAX_MESSAGE_LENGTH];
1291
1412
    gsize offset = 0;
1292
1413
 
1293
 
    g_return_if_fail (LIGHTDM_IS_GREETER (greeter));
1294
 
    g_return_if_fail (response != NULL);
 
1414
    g_return_val_if_fail (LIGHTDM_IS_GREETER (greeter), FALSE);
 
1415
    g_return_val_if_fail (response != NULL, FALSE);
1295
1416
 
1296
1417
    priv = GET_PRIVATE (greeter);
1297
1418
 
1298
 
    g_return_if_fail (priv->connected);
1299
 
    g_return_if_fail (priv->n_responses_waiting > 0);
 
1419
    g_return_val_if_fail (priv->connected, FALSE);
 
1420
    g_return_val_if_fail (priv->n_responses_waiting > 0, FALSE);
1300
1421
 
1301
1422
    priv->n_responses_waiting--;
1302
1423
    priv->responses_received = g_list_append (priv->responses_received, g_strdup (response));
1312
1433
        for (iter = priv->responses_received; iter; iter = iter->next)
1313
1434
            msg_length += string_length ((gchar *)iter->data);
1314
1435
 
1315
 
        write_header (message, MAX_MESSAGE_LENGTH, GREETER_MESSAGE_CONTINUE_AUTHENTICATION, msg_length, &offset);
1316
 
        write_int (message, MAX_MESSAGE_LENGTH, g_list_length (priv->responses_received), &offset);
 
1436
        if (!write_header (message, MAX_MESSAGE_LENGTH, GREETER_MESSAGE_CONTINUE_AUTHENTICATION, msg_length, &offset, error) ||
 
1437
            !write_int (message, MAX_MESSAGE_LENGTH, g_list_length (priv->responses_received), &offset, error))
 
1438
            return FALSE;
1317
1439
        for (iter = priv->responses_received; iter; iter = iter->next)
1318
 
            write_string (message, MAX_MESSAGE_LENGTH, (gchar *)iter->data, &offset);
1319
 
        send_message (greeter, message, offset);
 
1440
        {
 
1441
            if (!write_string (message, MAX_MESSAGE_LENGTH, (gchar *)iter->data, &offset, error))
 
1442
                return FALSE;
 
1443
        }
 
1444
        if (!send_message (greeter, message, offset, error))
 
1445
            return FALSE;
1320
1446
 
1321
1447
        g_list_free_full (priv->responses_received, g_free);
1322
1448
        priv->responses_received = NULL;
1323
1449
    }
 
1450
 
 
1451
    return TRUE;
1324
1452
}
1325
1453
 
1326
1454
/**
1327
1455
 * lightdm_greeter_cancel_authentication:
1328
1456
 * @greeter: A #LightDMGreeter
 
1457
 * @error: return location for a #GError, or %NULL
1329
1458
 *
1330
1459
 * Cancel the current user authentication.
 
1460
 *
 
1461
 * Return value: #TRUE if cancel request sent.
1331
1462
 **/
1332
 
void
1333
 
lightdm_greeter_cancel_authentication (LightDMGreeter *greeter)
 
1463
gboolean
 
1464
lightdm_greeter_cancel_authentication (LightDMGreeter *greeter, GError **error)
1334
1465
{
1335
1466
    LightDMGreeterPrivate *priv;
1336
1467
    guint8 message[MAX_MESSAGE_LENGTH];
1337
1468
    gsize offset = 0;
1338
1469
 
1339
 
    g_return_if_fail (LIGHTDM_IS_GREETER (greeter));
 
1470
    g_return_val_if_fail (LIGHTDM_IS_GREETER (greeter), FALSE);
1340
1471
 
1341
1472
    priv = GET_PRIVATE (greeter);
1342
1473
 
1343
 
    g_return_if_fail (priv->connected);
 
1474
    g_return_val_if_fail (priv->connected, FALSE);
1344
1475
 
1345
1476
    priv->cancelling_authentication = TRUE;
1346
 
    write_header (message, MAX_MESSAGE_LENGTH, GREETER_MESSAGE_CANCEL_AUTHENTICATION, 0, &offset);
1347
 
    send_message (greeter, message, offset);
 
1477
    return write_header (message, MAX_MESSAGE_LENGTH, GREETER_MESSAGE_CANCEL_AUTHENTICATION, 0, &offset, error) &&
 
1478
           send_message (greeter, message, offset, error);
1348
1479
}
1349
1480
 
1350
1481
/**
1396
1527
 * lightdm_greeter_set_language:
1397
1528
 * @greeter: A #LightDMGreeter
1398
1529
 * @language: The language to use for this user in the form of a locale specification (e.g. "de_DE.UTF-8").
 
1530
 * @error: return location for a #GError, or %NULL
1399
1531
 *
1400
1532
 * Set the language for the currently authenticated user.
 
1533
 *
 
1534
 * Return value: #TRUE if set language request sent.
1401
1535
 **/
1402
 
void
1403
 
lightdm_greeter_set_language (LightDMGreeter *greeter, const gchar *language)
 
1536
gboolean
 
1537
lightdm_greeter_set_language (LightDMGreeter *greeter, const gchar *language, GError **error)
1404
1538
{
1405
1539
    LightDMGreeterPrivate *priv;
1406
1540
    guint8 message[MAX_MESSAGE_LENGTH];
1407
1541
    gsize offset = 0;
1408
1542
 
1409
 
    g_return_if_fail (LIGHTDM_IS_GREETER (greeter));
 
1543
    g_return_val_if_fail (LIGHTDM_IS_GREETER (greeter), FALSE);
1410
1544
 
1411
1545
    priv = GET_PRIVATE (greeter);
1412
1546
 
1413
 
    g_return_if_fail (priv->connected);
 
1547
    g_return_val_if_fail (priv->connected, FALSE);
1414
1548
 
1415
 
    write_header (message, MAX_MESSAGE_LENGTH, GREETER_MESSAGE_SET_LANGUAGE, string_length (language), &offset);
1416
 
    write_string (message, MAX_MESSAGE_LENGTH, language, &offset);
1417
 
    send_message (greeter, message, offset);
 
1549
    return write_header (message, MAX_MESSAGE_LENGTH, GREETER_MESSAGE_SET_LANGUAGE, string_length (language), &offset, error) &&
 
1550
           write_string (message, MAX_MESSAGE_LENGTH, language, &offset, error) &&
 
1551
           send_message (greeter, message, offset, error);
1418
1552
}
1419
1553
 
1420
1554
/**
1436
1570
{
1437
1571
    LightDMGreeterPrivate *priv;
1438
1572
    Request *request;
 
1573
    GError *error = NULL;
1439
1574
 
1440
1575
    g_return_if_fail (LIGHTDM_IS_GREETER (greeter));
1441
1576
 
1442
1577
    priv = GET_PRIVATE (greeter);
1443
1578
 
1444
 
    send_start_session (greeter, session);
1445
 
    request = request_new (cancellable, callback, user_data);
 
1579
    request = request_new (greeter, cancellable, callback, user_data);
1446
1580
    priv->start_session_requests = g_list_append (priv->start_session_requests, request);
 
1581
    if (!send_start_session (greeter, session, &error))
 
1582
    {
 
1583
        request->error = error;
 
1584
        request_complete (request);
 
1585
    }
1447
1586
}
1448
1587
 
1449
1588
/**
1463
1602
 
1464
1603
    g_return_val_if_fail (LIGHTDM_IS_GREETER (greeter), FALSE);
1465
1604
 
1466
 
    if (request->return_code == 0)
1467
 
        return TRUE;
1468
 
    else
1469
 
    {
1470
 
        g_set_error (error, LIGHTDM_GREETER_ERROR, LIGHTDM_GREETER_ERROR_SESSION_FAILED, "Session returned error code %d", request->return_code);
1471
 
        return FALSE;
1472
 
    }
 
1605
    g_propagate_error (error, request->error);
 
1606
    return request->result;
1473
1607
}
1474
1608
 
1475
1609
/**
1496
1630
    g_return_val_if_fail (priv->is_authenticated, FALSE);
1497
1631
 
1498
1632
    /* Read until the session is started */
1499
 
    send_start_session (greeter, session);
1500
 
    request = request_new (NULL, NULL, NULL);
 
1633
    if (!send_start_session (greeter, session, error))
 
1634
        return FALSE;
 
1635
    request = request_new (greeter, NULL, NULL, NULL);
1501
1636
    priv->start_session_requests = g_list_append (priv->start_session_requests, g_object_ref (request));
1502
1637
    do
1503
1638
    {
1504
1639
        guint8 *message;
1505
1640
        gsize message_length;
1506
1641
 
1507
 
        message = recv_message (greeter, &message_length, TRUE);
1508
 
        if (!message)
1509
 
            break;
 
1642
        if (!recv_message (greeter, TRUE, &message, &message_length, error))
 
1643
            return FALSE;
1510
1644
        handle_message (greeter, message, message_length);
1511
1645
        g_free (message);
1512
1646
    } while (!request->complete);
1538
1672
{
1539
1673
    LightDMGreeterPrivate *priv;
1540
1674
    Request *request;
 
1675
    GError *error = NULL;
1541
1676
 
1542
1677
    g_return_if_fail (LIGHTDM_IS_GREETER (greeter));
1543
1678
 
1544
1679
    priv = GET_PRIVATE (greeter);
1545
1680
 
1546
 
    send_ensure_shared_data_dir (greeter, username);
1547
 
    request = request_new (cancellable, callback, user_data);
 
1681
    request = request_new (greeter, cancellable, callback, user_data);
1548
1682
    priv->ensure_shared_data_dir_requests = g_list_append (priv->ensure_shared_data_dir_requests, request);
 
1683
    if (!send_ensure_shared_data_dir (greeter, username, &error))
 
1684
    {
 
1685
        request->error = error;
 
1686
        request_complete (request);
 
1687
    }
1549
1688
}
1550
1689
 
1551
1690
/**
1552
1691
 * lightdm_greeter_ensure_shared_data_dir_finish:
1553
1692
 * @result: A #GAsyncResult.
1554
1693
 * @greeter: A #LightDMGreeter
 
1694
 * @error: return location for a #GError, or %NULL
1555
1695
 *
1556
1696
 * Function to call from lightdm_greeter_ensure_shared_data_dir callback.
1557
1697
 *
1558
1698
 * Return value: The path to the shared directory, free with g_free.
1559
1699
 **/
1560
1700
gchar *
1561
 
lightdm_greeter_ensure_shared_data_dir_finish (LightDMGreeter *greeter, GAsyncResult *result)
 
1701
lightdm_greeter_ensure_shared_data_dir_finish (LightDMGreeter *greeter, GAsyncResult *result, GError **error)
1562
1702
{
 
1703
    Request *request = REQUEST (result);
 
1704
 
1563
1705
    g_return_val_if_fail (LIGHTDM_IS_GREETER (greeter), NULL);
1564
 
    return g_strdup (REQUEST (result)->dir);
 
1706
 
 
1707
    g_propagate_error (error, request->error);
 
1708
    return g_strdup (request->dir);
1565
1709
}
1566
1710
 
1567
1711
/**
1568
1712
 * lightdm_greeter_ensure_shared_data_dir_sync:
1569
1713
 * @greeter: A #LightDMGreeter
1570
1714
 * @username: A username
 
1715
 * @error: return location for a #GError, or %NULL
1571
1716
 *
1572
1717
 * Ensure that a shared data dir for the given user is available.  Both the
1573
1718
 * greeter user and @username will have write access to that folder.  The
1583
1728
 * Return value: The path to the shared directory, free with g_free.
1584
1729
 **/
1585
1730
gchar *
1586
 
lightdm_greeter_ensure_shared_data_dir_sync (LightDMGreeter *greeter, const gchar *username)
 
1731
lightdm_greeter_ensure_shared_data_dir_sync (LightDMGreeter *greeter, const gchar *username, GError **error)
1587
1732
{
1588
1733
    LightDMGreeterPrivate *priv;
1589
1734
    Request *request;
1590
 
    gchar *data_dir;
1591
1735
 
1592
1736
    g_return_val_if_fail (LIGHTDM_IS_GREETER (greeter), NULL);
1593
1737
 
1596
1740
    g_return_val_if_fail (priv->connected, NULL);
1597
1741
 
1598
1742
    /* Read until a response */
1599
 
    send_ensure_shared_data_dir (greeter, username);
1600
 
    request = request_new (NULL, NULL, NULL);
 
1743
    if (!send_ensure_shared_data_dir (greeter, username, error))
 
1744
        return NULL;
 
1745
    request = request_new (greeter, NULL, NULL, NULL);
1601
1746
    priv->ensure_shared_data_dir_requests = g_list_append (priv->ensure_shared_data_dir_requests, g_object_ref (request));
1602
1747
    do
1603
1748
    {
1604
1749
        guint8 *message;
1605
1750
        gsize message_length;
1606
1751
 
1607
 
        message = recv_message (greeter, &message_length, TRUE);
1608
 
        if (!message)
1609
 
            break;
 
1752
        if (!recv_message (greeter, TRUE, &message, &message_length, error))
 
1753
            return FALSE;
1610
1754
        handle_message (greeter, message, message_length);
1611
1755
        g_free (message);
1612
1756
    } while (!request->complete);
1613
1757
 
1614
 
    data_dir = g_strdup (request->dir);
1615
 
    g_object_unref (request);
1616
 
 
1617
 
    return data_dir;
 
1758
    return lightdm_greeter_ensure_shared_data_dir_finish (greeter, G_ASYNC_RESULT (request), error);
1618
1759
}
1619
1760
 
1620
1761
static void
1621
1762
lightdm_greeter_init (LightDMGreeter *greeter)
1622
1763
{
1623
1764
    LightDMGreeterPrivate *priv = GET_PRIVATE (greeter);
1624
 
    const gchar *fd;
1625
1765
 
1626
1766
    priv->read_buffer = g_malloc (HEADER_SIZE);
1627
1767
    priv->hints = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
1628
 
 
1629
 
    fd = g_getenv ("LIGHTDM_TO_SERVER_FD");
1630
 
    if (fd)
1631
 
    {
1632
 
        GError *error = NULL;
1633
 
 
1634
 
        priv->to_server_channel = g_io_channel_unix_new (atoi (fd));
1635
 
        g_io_channel_set_encoding (priv->to_server_channel, NULL, &error);
1636
 
        if (error)
1637
 
            g_warning ("Failed to set encoding on to server channel to binary: %s\n", error->message);
1638
 
        g_clear_error (&error);
1639
 
    }
1640
 
    else
1641
 
        g_warning ("No LIGHTDM_TO_SERVER_FD environment variable");
1642
 
 
1643
 
    fd = g_getenv ("LIGHTDM_FROM_SERVER_FD");
1644
 
    if (fd)
1645
 
    {
1646
 
        GError *error = NULL;
1647
 
 
1648
 
        priv->from_server_channel = g_io_channel_unix_new (atoi (fd));
1649
 
        g_io_channel_set_encoding (priv->from_server_channel, NULL, &error);
1650
 
        if (error)
1651
 
            g_warning ("Failed to set encoding on from server channel to binary: %s\n", error->message);
1652
 
        g_clear_error (&error);
1653
 
        g_io_add_watch (priv->from_server_channel, G_IO_IN, from_server_cb, greeter);
1654
 
    }
1655
 
    else
1656
 
        g_warning ("No LIGHTDM_FROM_SERVER_FD environment variable");
1657
1768
}
1658
1769
 
1659
1770
static void
1660
1771
lightdm_greeter_set_property (GObject      *object,
1661
 
                          guint         prop_id,
1662
 
                          const GValue *value,
1663
 
                          GParamSpec   *pspec)
 
1772
                              guint         prop_id,
 
1773
                              const GValue *value,
 
1774
                              GParamSpec   *pspec)
1664
1775
{
1665
1776
    G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1666
1777
}
1667
1778
 
1668
1779
static void
1669
1780
lightdm_greeter_get_property (GObject    *object,
1670
 
                          guint       prop_id,
1671
 
                          GValue     *value,
1672
 
                          GParamSpec *pspec)
 
1781
                              guint       prop_id,
 
1782
                              GValue     *value,
 
1783
                              GParamSpec *pspec)
1673
1784
{
1674
1785
    LightDMGreeter *self;
1675
1786
 
1985
2096
{
1986
2097
    Request *request = REQUEST (object);
1987
2098
 
 
2099
    g_clear_object (&request->greeter);
 
2100
    g_clear_object (&request->cancellable);
1988
2101
    g_free (request->dir);
1989
 
    g_clear_object (&request->cancellable);
1990
2102
 
1991
2103
    G_OBJECT_CLASS (request_parent_class)->finalize (object);
1992
2104
}
2005
2117
}
2006
2118
 
2007
2119
static GObject *
2008
 
request_get_source_object (GAsyncResult *res)
 
2120
request_get_source_object (GAsyncResult *result)
2009
2121
{
2010
 
    return NULL;
 
2122
    return g_object_ref (REQUEST (result)->greeter);
2011
2123
}
2012
2124
 
2013
2125
static void