~ubuntu-branches/ubuntu/natty/gnome-keyring/natty

« back to all changes in this revision

Viewing changes to pkcs11/wrap-layer/gkm-wrap-prompt.c

  • Committer: Bazaar Package Importer
  • Author(s): Sebastien Bacher
  • Date: 2010-12-06 17:58:28 UTC
  • mfrom: (1.1.65 upstream)
  • Revision ID: james.westby@ubuntu.com-20101206175828-8xjojyxw89qacpq7
Tags: 2.92.92.is.2.32.1-0ubuntu1
* New upstream version
* debian/control.in:
  - updated the libglib requirement
* debian/libgcr0.symbols:
  - new version update
* debian/patches/02_uidir_relocate.patch:
  - updated for the new version
* debian/patches/10_git_fix_cka_trusted_collections.patch:
  - dropped, the patch is the new version
* debian/patches/90_git_pam_headers.patch:
  - dropped, the patch is the new version

Show diffs side-by-side

added added

removed removed

Lines of Context:
26
26
 
27
27
#include "egg/egg-secure-memory.h"
28
28
 
 
29
#include "gcr/gcr-unlock-options.h"
 
30
 
29
31
#include "gkm/gkm-attributes.h"
30
32
#include "gkm/gkm-util.h"
31
33
 
89
91
}
90
92
#endif
91
93
 
 
94
static gboolean
 
95
is_login_keyring (CK_ATTRIBUTE_PTR attrs, CK_ULONG n_attrs)
 
96
{
 
97
        gboolean is_login = FALSE;
 
98
        if (!gkm_attributes_find_boolean (attrs, n_attrs, CKA_G_LOGIN_COLLECTION, &is_login))
 
99
                return FALSE;
 
100
        return is_login;
 
101
}
 
102
 
92
103
static gchar*
93
104
auto_unlock_keyring_location (CK_ATTRIBUTE_PTR attrs, CK_ULONG n_attrs)
94
105
{
95
106
        CK_ATTRIBUTE_PTR attr;
96
 
        gboolean is_login = FALSE;
97
107
 
98
 
        if (gkm_attributes_find_boolean (attrs, n_attrs, CKA_G_LOGIN_COLLECTION, &is_login) && is_login)
 
108
        if (is_login_keyring (attrs, n_attrs))
99
109
                return NULL;
100
110
 
101
111
        attr = gkm_attributes_find (attrs, n_attrs, CKA_ID);
223
233
auto_unlock_should_attach (GkmWrapPrompt *self)
224
234
{
225
235
        GkuPrompt *prompt = GKU_PROMPT (self);
226
 
        gint value = 0;
227
 
        return gku_prompt_has_response (prompt) &&
228
 
               gku_prompt_get_unlock_option (prompt, GKU_UNLOCK_AUTO, &value) &&
229
 
               value != 0;
 
236
        const gchar *choice;
 
237
 
 
238
        if (!gku_prompt_has_response (prompt))
 
239
                return FALSE;
 
240
 
 
241
        choice = gku_prompt_get_unlock_choice (prompt);
 
242
        return (choice && g_str_equal (choice, GCR_UNLOCK_OPTION_ALWAYS));
230
243
}
231
244
 
232
245
static void
476
489
get_unlock_options_from_prompt (GkmWrapPrompt *self, CK_ULONG_PTR n_options)
477
490
{
478
491
        CK_ATTRIBUTE_PTR options;
 
492
        const gchar *choice;
479
493
        CK_BBOOL bval;
480
494
        CK_ULONG uval;
481
 
        gint value;
 
495
        guint ttl;
482
496
 
483
497
        g_assert (GKM_WRAP_IS_PROMPT (self));
484
498
        g_assert (n_options);
486
500
        if (!gku_prompt_has_response (GKU_PROMPT (self)))
487
501
                return NULL;
488
502
 
 
503
        ttl = gku_prompt_get_unlock_ttl (GKU_PROMPT (self));
 
504
        choice = gku_prompt_get_unlock_choice (GKU_PROMPT (self));
 
505
        g_return_val_if_fail (choice, NULL);
 
506
 
489
507
        *n_options = 4;
490
508
        options = pool_alloc (self, sizeof (CK_ATTRIBUTE) * (*n_options));
491
509
 
502
520
        options[1].ulValueLen = sizeof (bval);
503
521
 
504
522
        /* CKA_G_DESTRUCT_IDLE */
505
 
        value = 0;
506
 
        gku_prompt_get_unlock_option (GKU_PROMPT (self), GKU_UNLOCK_IDLE, &value);
507
 
        uval = value < 0 ? 0 : value;
 
523
        uval = g_str_equal (choice, GCR_UNLOCK_OPTION_IDLE) ? ttl : 0;
508
524
        options[2].type = CKA_G_DESTRUCT_IDLE;
509
525
        options[2].pValue = pool_dup (self, &uval, sizeof (uval));
510
526
        options[2].ulValueLen = sizeof (uval);
511
527
 
512
528
        /* CKA_G_DESTRUCT_AFTER */
513
 
        value = 0;
514
 
        gku_prompt_get_unlock_option (GKU_PROMPT (self), GKU_UNLOCK_TIMEOUT, &value);
515
 
        uval = value < 0 ? 0 : value;
 
529
        uval = g_str_equal (choice, GCR_UNLOCK_OPTION_TIMEOUT) ? ttl : 0;
516
530
        options[3].type = CKA_G_DESTRUCT_AFTER;
517
531
        options[3].pValue = pool_dup (self, &uval, sizeof (uval));
518
532
        options[3].ulValueLen = sizeof (uval);
523
537
static void
524
538
set_unlock_options_on_prompt (GkmWrapPrompt *self, CK_ATTRIBUTE_PTR options, CK_ULONG n_options)
525
539
{
 
540
        const gchar *choice;
 
541
        gboolean have_ttl = FALSE;
526
542
        gboolean bval;
527
543
        gulong uval;
 
544
        guint ttl = 0;
528
545
 
529
546
        g_assert (GKM_WRAP_IS_PROMPT (self));
530
547
        g_assert (options || !n_options);
531
548
 
532
 
        if (gkm_attributes_find_boolean (options, n_options, CKA_GNOME_TRANSIENT, &bval))
533
 
                gku_prompt_set_unlock_option (GKU_PROMPT (self), GKU_UNLOCK_AUTO, bval ? 0 : 1);
534
 
 
535
 
        if (gkm_attributes_find_ulong (options, n_options, CKA_G_DESTRUCT_IDLE, &uval))
536
 
                gku_prompt_set_unlock_option (GKU_PROMPT (self), GKU_UNLOCK_IDLE, (int)uval);
537
 
 
538
 
        if (gkm_attributes_find_ulong (options, n_options, CKA_G_DESTRUCT_AFTER, &uval))
539
 
                gku_prompt_set_unlock_option (GKU_PROMPT (self), GKU_UNLOCK_TIMEOUT, (int)uval);
 
549
        if (gkm_attributes_find_boolean (options, n_options, CKA_GNOME_TRANSIENT, &bval)) {
 
550
                choice = bval ? GCR_UNLOCK_OPTION_SESSION : GCR_UNLOCK_OPTION_ALWAYS;
 
551
        }
 
552
 
 
553
        if (gkm_attributes_find_ulong (options, n_options, CKA_G_DESTRUCT_IDLE, &uval) && uval) {
 
554
                choice = GCR_UNLOCK_OPTION_IDLE;
 
555
                have_ttl = TRUE;
 
556
                ttl = uval;
 
557
        }
 
558
 
 
559
        if (gkm_attributes_find_ulong (options, n_options, CKA_G_DESTRUCT_AFTER, &uval) && uval) {
 
560
                choice = GCR_UNLOCK_OPTION_TIMEOUT;
 
561
                have_ttl = TRUE;
 
562
                ttl = uval;
 
563
        }
 
564
 
 
565
        gku_prompt_set_unlock_choice (GKU_PROMPT (self), choice);
 
566
        if (have_ttl)
 
567
                gku_prompt_set_unlock_ttl (GKU_PROMPT (self), ttl);
540
568
}
541
569
 
542
570
static CK_ATTRIBUTE_PTR
643
671
        gku_prompt_hide_widget (prompt, "confirm_area");
644
672
        gku_prompt_show_widget (prompt, "details_area");
645
673
        gku_prompt_show_widget (prompt, "password_area");
646
 
        gku_prompt_show_widget (prompt, "lock_area");
647
674
        gku_prompt_show_widget (prompt, "options_area");
648
675
 
649
676
        if (gkm_wrap_login_is_usable ())
650
 
                gku_prompt_show_widget (prompt, "auto_unlock_check");
651
 
        else
652
 
                gku_prompt_hide_widget (prompt, "auto_unlock_check");
 
677
                gku_prompt_set_unlock_sensitive (prompt, GCR_UNLOCK_OPTION_ALWAYS, FALSE, NULL);
653
678
}
654
679
 
655
680
 
723
748
        gku_prompt_hide_widget (prompt, "confirm_area");
724
749
        gku_prompt_show_widget (prompt, "details_area");
725
750
        gku_prompt_show_widget (prompt, "password_area");
726
 
        gku_prompt_show_widget (prompt, "lock_area");
727
751
        gku_prompt_show_widget (prompt, "options_area");
728
 
        gku_prompt_hide_widget (prompt, "auto_unlock_check");
 
752
 
 
753
        /* TODO: After string freeze need to add a reason */
 
754
        if (!gkm_wrap_login_is_usable ())
 
755
                gku_prompt_set_unlock_sensitive (prompt, GCR_UNLOCK_OPTION_ALWAYS, FALSE, NULL);
729
756
}
730
757
 
731
758
static void
736
763
        GkuPrompt *prompt;
737
764
        const gchar *label = NULL;
738
765
        CK_OBJECT_CLASS klass;
739
 
        gboolean is_login = FALSE;
740
766
 
741
767
        g_assert (GKM_WRAP_IS_PROMPT (self));
742
768
 
763
789
                label = _("Unnamed");
764
790
 
765
791
        if (klass == CKO_G_COLLECTION) {
766
 
                if (gkm_attributes_find_boolean (attrs, n_attrs, CKA_G_LOGIN_COLLECTION, &is_login) && is_login)
 
792
                if (is_login_keyring (attrs, n_attrs))
767
793
                        prepare_unlock_keyring_login (self);
768
794
                else
769
795
                        prepare_unlock_keyring_other (self, label);
801
827
        gku_prompt_set_secondary_text (prompt, text);
802
828
        g_free (text);
803
829
 
804
 
        if (gkm_wrap_login_is_usable ()) {
805
 
                gku_prompt_show_widget (prompt, "details_area");
806
 
                gku_prompt_show_widget (prompt, "lock_area");
807
 
                gku_prompt_hide_widget (prompt, "options_area");
808
 
        }
 
830
        gku_prompt_show_widget (prompt, "details_area");
 
831
        gku_prompt_show_widget (prompt, "options_area");
 
832
        gku_prompt_set_unlock_sensitive (prompt, GCR_UNLOCK_OPTION_IDLE, FALSE, NULL);
 
833
        gku_prompt_set_unlock_sensitive (prompt, GCR_UNLOCK_OPTION_TIMEOUT, FALSE, NULL);
 
834
        gku_prompt_set_unlock_sensitive (prompt, GCR_UNLOCK_OPTION_ALWAYS,
 
835
                                         gkm_wrap_login_is_usable (), NULL);
809
836
 
810
837
        g_free (label);
811
838
}
812
839
 
 
840
static void
 
841
fix_login_keyring_if_unlock_failed (GkmWrapPrompt *self, const gchar *password)
 
842
{
 
843
        CK_OBJECT_CLASS klass = CKO_G_CREDENTIAL;
 
844
        CK_OBJECT_HANDLE cred;
 
845
        CK_BBOOL tval = CK_TRUE;
 
846
        CK_ATTRIBUTE attrs[4];
 
847
        gchar *failed;
 
848
        CK_RV rv;
 
849
 
 
850
        failed = gkm_wrap_login_steal_failed_password ();
 
851
 
 
852
        /* Do we have a failed unlock password? */
 
853
        if (!failed || !failed[0]) {
 
854
                egg_secure_strfree (failed);
 
855
                return;
 
856
        }
 
857
 
 
858
        attrs[0].type = CKA_CLASS;
 
859
        attrs[0].pValue = &klass;
 
860
        attrs[0].ulValueLen = sizeof (klass);
 
861
 
 
862
        attrs[1].type = CKA_VALUE;
 
863
        attrs[1].pValue = failed;
 
864
        attrs[1].ulValueLen = strlen (failed);
 
865
 
 
866
        attrs[2].type = CKA_GNOME_TRANSIENT;
 
867
        attrs[2].pValue = &tval;
 
868
        attrs[2].ulValueLen = sizeof (tval);
 
869
 
 
870
        attrs[3].type = CKA_TOKEN;
 
871
        attrs[3].pValue = &tval;
 
872
        attrs[3].ulValueLen = sizeof (tval);
 
873
 
 
874
        /* Create a credential object for the failed password */
 
875
        rv = (self->module->C_CreateObject) (self->session, attrs, G_N_ELEMENTS (attrs), &cred);
 
876
        egg_secure_strfree (failed);
 
877
 
 
878
        if (rv != CKR_OK) {
 
879
                g_warning ("couldn't create credential to fix login password: %s",
 
880
                           gkm_util_rv_to_string (rv));
 
881
                return;
 
882
        }
 
883
 
 
884
        attrs[0].type = CKA_G_CREDENTIAL;
 
885
        attrs[0].pValue = &cred;
 
886
        attrs[0].ulValueLen = sizeof (cred);
 
887
 
 
888
        /* Set the credential on the object */
 
889
        rv = (self->module->C_SetAttributeValue) (self->session, self->object, attrs, 1);
 
890
        if (rv != CKR_OK) {
 
891
                g_warning ("couldn't change credential to fix login keyring password: %s",
 
892
                           gkm_util_rv_to_string (rv));
 
893
                return;
 
894
        }
 
895
 
 
896
        g_message ("fixed login keyring password to match login password");
 
897
}
 
898
 
813
899
/* -----------------------------------------------------------------------------
814
900
 * OBJECT
815
901
 */
870
956
{
871
957
        CredentialPrompt *data;
872
958
        CK_ATTRIBUTE_PTR attr;
873
 
        CK_ATTRIBUTE_PTR options;
874
 
        CK_ULONG n_options, i;
 
959
        CK_ULONG i;
875
960
        CK_OBJECT_CLASS klass;
876
961
        CK_OBJECT_HANDLE object;
877
962
        GkmWrapPrompt *self;
909
994
 
910
995
        data->n_template = n_template;
911
996
 
912
 
        /* Now load up the unlock options into the prompt*/
913
 
        options = get_unlock_options_from_object (self, &n_options);
914
 
        if (options != NULL)
915
 
                set_unlock_options_on_prompt (self, options, n_options);
916
 
 
917
997
        return self;
918
998
}
919
999
 
950
1030
 
951
1031
        if (!data->password) {
952
1032
                prepare_unlock_prompt (self, attrs, n_attrs, self->iteration == 1);
 
1033
 
 
1034
                /* Now load up the unlock options into the prompt*/
 
1035
                if (self->iteration == 1) {
 
1036
                        options = get_unlock_options_from_object (self, &n_options);
 
1037
                        if (options != NULL)
 
1038
                                set_unlock_options_on_prompt (self, options, n_options);
 
1039
                }
 
1040
 
953
1041
                ++(self->iteration);
954
1042
 
955
1043
                gku_prompt_request_attention_sync (NULL, on_prompt_attention,
998
1086
 
999
1087
        /* Save the options, and possibly auto unlock */
1000
1088
        if (call_result == CKR_OK) {
 
1089
 
 
1090
                attrs = get_attributes_from_object (self, &n_attrs);
 
1091
 
 
1092
                /*
 
1093
                 * For the login keyring, we check for a previous unlock failure,
 
1094
                 * that would have come from PAM, and try to change the password to
 
1095
                 * the one that failed earlier.
 
1096
                 */
 
1097
                if (is_login_keyring (attrs, n_attrs))
 
1098
                        fix_login_keyring_if_unlock_failed (self, data->password);
 
1099
 
1001
1100
                options = get_unlock_options_from_prompt (self, &n_options);
1002
1101
                if (options != NULL)
1003
1102
                        set_unlock_options_on_object (self, options, n_options);
1004
1103
 
1005
 
                if (auto_unlock_should_attach (self)) {
1006
 
                        attrs = get_attributes_from_object (self, &n_attrs);
 
1104
                if (auto_unlock_should_attach (self))
1007
1105
                        auto_unlock_attach_object (attrs, n_attrs, data->password);
1008
 
                }
1009
1106
        }
1010
1107
}
1011
1108
 
1039
1136
        gku_prompt_set_secondary_text (prompt, text);
1040
1137
        g_free (text);
1041
1138
 
1042
 
        if (gkm_wrap_login_is_usable ()) {
1043
 
                gku_prompt_show_widget (prompt, "details_area");
1044
 
                gku_prompt_show_widget (prompt, "lock_area");
1045
 
                gku_prompt_hide_widget (prompt, "options_area");
1046
 
        }
 
1139
        gku_prompt_show_widget (prompt, "details_area");
 
1140
        gku_prompt_show_widget (prompt, "options_area");
 
1141
        gku_prompt_set_unlock_sensitive (prompt, GCR_UNLOCK_OPTION_IDLE, FALSE, NULL);
 
1142
        gku_prompt_set_unlock_sensitive (prompt, GCR_UNLOCK_OPTION_TIMEOUT, FALSE, NULL);
 
1143
        gku_prompt_set_unlock_sensitive (prompt, GCR_UNLOCK_OPTION_ALWAYS,
 
1144
                                         gkm_wrap_login_is_usable (), NULL);
1047
1145
 
1048
1146
        g_free (label);
1049
1147
}
1164
1262
        gku_prompt_set_secondary_text (prompt, text);
1165
1263
        g_free (text);
1166
1264
 
1167
 
        if (gkm_wrap_login_is_usable ()) {
1168
 
                gku_prompt_show_widget (prompt, "details_area");
1169
 
                gku_prompt_show_widget (prompt, "lock_area");
1170
 
                gku_prompt_hide_widget (prompt, "options_area");
1171
 
        }
 
1265
        gku_prompt_show_widget (prompt, "details_area");
 
1266
        gku_prompt_show_widget (prompt, "options_area");
 
1267
        gku_prompt_set_unlock_sensitive (prompt, GCR_UNLOCK_OPTION_IDLE, FALSE, NULL);
 
1268
        gku_prompt_set_unlock_sensitive (prompt, GCR_UNLOCK_OPTION_TIMEOUT, FALSE, NULL);
 
1269
        gku_prompt_set_unlock_sensitive (prompt, GCR_UNLOCK_OPTION_ALWAYS,
 
1270
                                         gkm_wrap_login_is_usable (), NULL);
1172
1271
 
1173
1272
        g_free (label);
1174
1273
}