Esempio n. 1
0
/* perform shutdown operations */
static void
khm_pre_shutdown(void) {
    khm_handle csp_cw = NULL;
    khm_handle credset = NULL;
    khm_int32 t;
    khm_size s;

    /* Check if we should destroy all credentials on exit... */

    if (KHM_FAILED(khc_open_space(NULL, L"CredWindow", 0, &csp_cw)))
        return;

    if (KHM_FAILED(khc_read_int32(csp_cw, L"DestroyCredsOnExit", &t)) ||
        !t)
        goto _cleanup;

    if (KHM_FAILED(kcdb_credset_create(&credset)))
        goto _cleanup;

    if (KHM_FAILED(kcdb_credset_extract(credset, NULL, NULL,
                                        KCDB_TYPE_INVALID)))
        goto _cleanup;

    if (KHM_FAILED(kcdb_credset_get_size(credset, &s)) ||
        s == 0)
        goto _cleanup;

    kcdb_credset_apply(credset, mw_select_cred, NULL);

    khui_context_set(KHUI_SCOPE_GROUP,
                     NULL,
                     KCDB_CREDTYPE_INVALID,
                     NULL,
                     NULL,
                     0,
                     credset);

    khm_cred_destroy_creds(TRUE, TRUE);

 _cleanup:

    if (credset)
        kcdb_credset_delete(credset);

    if (csp_cw)
        khc_close_space(csp_cw);
}
Esempio n. 2
0
KHMEXP khm_int32 KHMAPI 
kcdb_credset_extract_filtered(khm_handle destcredset,
			      khm_handle sourcecredset,
			      kcdb_cred_filter_func filter,
			      void * rock)
{
    khm_int32 code = KHM_ERROR_SUCCESS;
    kcdb_credset * dest;
    kcdb_credset * src;
    int isRoot = 0;
    khm_size srcSize = 0;
    int i;

    if(!kcdb_credset_is_credset(destcredset))
        return KHM_ERROR_INVALID_PARAM;

    if(sourcecredset) {
        if(!kcdb_credset_is_credset(sourcecredset))
            return KHM_ERROR_INVALID_PARAM;
    } else {
        sourcecredset = kcdb_root_credset;
        isRoot = 1;
    }

    src = (kcdb_credset *) sourcecredset;
    dest = (kcdb_credset *) destcredset;

    if (kcdb_credset_is_sealed(dest))
        return KHM_ERROR_INVALID_OPERATION;

    EnterCriticalSection(&(src->cs));
    EnterCriticalSection(&(dest->cs));

#ifdef DEBUG
    assert(!(dest->flags & KCDB_CREDSET_FLAG_ENUM));
#endif

    if(KHM_FAILED(kcdb_credset_get_size(sourcecredset, &srcSize))) {
        code = KHM_ERROR_UNKNOWN;
        goto _exit;
    }

    kcdb_cred_lock_read();

    dest->flags |= KCDB_CREDSET_FLAG_ENUM;

    for(i=0; i < (int) srcSize; i++) {
        kcdb_cred * c;

        c = src->clist[i].cred;
        if(kcdb_cred_is_active_cred((khm_handle) c) &&
            filter(c, 0, rock))
        {
            if(isRoot) {
                khm_handle newcred;

                kcdb_cred_unlock_read();
                kcdb_cred_dup((khm_handle) c, &newcred);
                kcdb_credset_add_cred(destcredset, newcred, -1);
                kcdb_cred_release(newcred);
                kcdb_cred_lock_read();
            } else {
                kcdb_cred_unlock_read();
                kcdb_credset_add_cred(destcredset, (khm_handle) c, -1);
                kcdb_cred_lock_read();
            }
        }
    }

    dest->flags &= ~KCDB_CREDSET_FLAG_ENUM;

    kcdb_cred_unlock_read();

_exit:
    LeaveCriticalSection(&(dest->cs));
    LeaveCriticalSection(&(src->cs));

    return code;
}
Esempio n. 3
0
void khm_cred_renew_all_identities(void)
{
    khm_size count;
    khm_size cb = 0;
    khm_size n_idents = 0;
    khm_int32 rv;
    wchar_t * ident_names = NULL;
    wchar_t * this_ident;

    kcdb_credset_get_size(NULL, &count);

    /* if there are no credentials, we just skip over the renew
       action. */

    if (count == 0)
        return;

    ident_names = NULL;

    while (TRUE) {
        if (ident_names) {
            PFREE(ident_names);
            ident_names = NULL;
        }

        cb = 0;
        rv = kcdb_identity_enum(KCDB_IDENT_FLAG_EMPTY, 0,
                                NULL,
                                &cb, &n_idents);

        if (n_idents == 0 || rv != KHM_ERROR_TOO_LONG ||
            cb == 0)
            break;

        ident_names = PMALLOC(cb);
        ident_names[0] = L'\0';

        rv = kcdb_identity_enum(KCDB_IDENT_FLAG_EMPTY, 0,
                                ident_names,
                                &cb, &n_idents);

        if (KHM_SUCCEEDED(rv))
            break;
    }

    if (ident_names) {
        for (this_ident = ident_names;
             this_ident && *this_ident;
             this_ident = multi_string_next(this_ident)) {
            khm_handle ident;

            if (KHM_FAILED(kcdb_identity_create(this_ident, 0,
                                                &ident)))
                continue;

            khm_cred_renew_identity(ident);

            kcdb_identity_release(ident);
        }

        PFREE(ident_names);
        ident_names = NULL;
    }
}
Esempio n. 4
0
/* Completion handler for KMSG_CRED messages.  We control the overall
   logic of credentials acquisition and other operations here.  Once a
   credentials operation is triggered, each successive message
   completion notification will be used to dispatch the messages for
   the next step in processing the operation. */
void KHMAPI 
kmsg_cred_completion(kmq_message *m)
{
    khui_new_creds * nc;

#ifdef DEBUG
    assert(m->type == KMSG_CRED);
#else
    if(m->type != KMSG_CRED)
        return; /* huh? */
#endif

    switch(m->subtype) {
    case KMSG_CRED_PASSWORD:
        /* fallthrough */
    case KMSG_CRED_NEW_CREDS:
        /* Cred types have attached themselves.  Trigger the next
           phase. */
        kmq_post_message(KMSG_CRED, KMSG_CRED_DIALOG_SETUP, 0, 
                         m->vparam);
        break;

    case KMSG_CRED_RENEW_CREDS:
        nc = (khui_new_creds *) m->vparam;

        /* khm_cred_dispatch_process_message() deals with the case
           where there are no credential types that wants to
           participate in this operation. */
        khm_cred_dispatch_process_message(nc);
        break;

    case KMSG_CRED_DIALOG_SETUP:
        nc = (khui_new_creds *) m->vparam;

        khm_prep_newcredwnd(nc->hwnd);
            
        /* all the controls have been created.  Now initialize them */
        if (nc->n_types > 0) {
            kmq_post_subs_msg(nc->type_subs, 
                              nc->n_types, 
                              KMSG_CRED, 
                              KMSG_CRED_DIALOG_PRESTART, 
                              0, 
                              m->vparam);
        } else {
            PostMessage(nc->hwnd, KHUI_WM_NC_NOTIFY, 
                        MAKEWPARAM(0, WMNC_DIALOG_PROCESS_COMPLETE), 0);
        }
        break;

    case KMSG_CRED_DIALOG_PRESTART:
        /* all prestart stuff is done.  Now to activate the dialog */
        nc = (khui_new_creds *) m->vparam;
        khm_show_newcredwnd(nc->hwnd);
        
        kmq_post_subs_msg(nc->type_subs,
                          nc->n_types,
                          KMSG_CRED, 
                          KMSG_CRED_DIALOG_START, 
                          0, 
                          m->vparam);
        /* at this point, the dialog window takes over.  We let it run
           the show until KMSG_CRED_DIALOG_END is posted by the dialog
           procedure. */
        break;

    case KMSG_CRED_PROCESS:
        /* a wave of these messages have completed.  We should check
           if there's more */
        nc = (khui_new_creds *) m->vparam;

        /* if we are done processing all the plug-ins, then check if
           there were any errors reported.  Otherwise we dispatch
           another set of messages. */
        if(!khm_cred_dispatch_process_level(nc)) {

            if(kherr_is_error()) {
                khui_alert * alert;
                kherr_event * evt;
                kherr_context * ctx;
                wchar_t ws_tfmt[512];
                wchar_t w_idname[KCDB_IDENT_MAXCCH_NAME];
                wchar_t ws_title[ARRAYLENGTH(ws_tfmt) + KCDB_IDENT_MAXCCH_NAME];
                khm_size cb;

                /* For renewals, we suppress the error message for the
                   following case:

                   - The renewal was for an identity

                   - There are no identity credentials for the
                     identity (no credentials that have the same type
                     as the identity provider). */

                if (nc->subtype == KMSG_CRED_RENEW_CREDS &&
                    nc->ctx.scope == KHUI_SCOPE_IDENT &&
                    nc->ctx.identity != NULL) {
                    khm_handle tcs = NULL; /* credential set */
                    khm_size count = 0;
                    khm_int32 id_ctype = KCDB_CREDTYPE_INVALID;
                    khm_int32 delta = 0;

                    kcdb_identity_get_type(&id_ctype);
                    kcdb_credset_create(&tcs);
                    kcdb_credset_collect(tcs, NULL,
                                         nc->ctx.identity,
                                         id_ctype,
                                         &delta);
                    kcdb_credset_get_size(tcs, &count);
                    kcdb_credset_delete(tcs);

                    if (count == 0) {
                        goto done_with_op;
                    }
                }

                ctx = kherr_peek_context();
                evt = kherr_get_err_event(ctx);
                kherr_evaluate_event(evt);

                khui_alert_create_empty(&alert);

                if (nc->subtype == KMSG_CRED_NEW_CREDS) {

                    khui_alert_set_type(alert, KHUI_ALERTTYPE_ACQUIREFAIL);

                    cb = sizeof(w_idname);
                    if (nc->n_identities == 0 ||
                        KHM_FAILED(kcdb_identity_get_name(nc->identities[0],
                                                          w_idname, &cb))) {
                        /* an identity could not be determined */
                        LoadString(khm_hInstance, IDS_NC_FAILED_TITLE,
                                   ws_title, ARRAYLENGTH(ws_title));
                    } else {
                        LoadString(khm_hInstance, IDS_NC_FAILED_TITLE_I,
                                   ws_tfmt, ARRAYLENGTH(ws_tfmt));
                        StringCbPrintf(ws_title, sizeof(ws_title),
                                       ws_tfmt, w_idname);
                        khui_alert_set_ctx(alert,
                                           KHUI_SCOPE_IDENT,
                                           nc->identities[0],
                                           KCDB_CREDTYPE_INVALID,
                                           NULL);
                    }

                } else if (nc->subtype == KMSG_CRED_PASSWORD) {

                    khui_alert_set_type(alert, KHUI_ALERTTYPE_CHPW);

                    cb = sizeof(w_idname);
                    if (nc->n_identities == 0 ||
                        KHM_FAILED(kcdb_identity_get_name(nc->identities[0],
                                                          w_idname, &cb))) {
                        LoadString(khm_hInstance, IDS_NC_PWD_FAILED_TITLE,
                                   ws_title, ARRAYLENGTH(ws_title));
                    } else {
                        LoadString(khm_hInstance, IDS_NC_PWD_FAILED_TITLE_I,
                                   ws_tfmt, ARRAYLENGTH(ws_tfmt));
                        StringCbPrintf(ws_title, sizeof(ws_title),
                                       ws_tfmt, w_idname);
                        khui_alert_set_ctx(alert,
                                           KHUI_SCOPE_IDENT,
                                           nc->identities[0],
                                           KCDB_CREDTYPE_INVALID,
                                           NULL);
                    }

                } else if (nc->subtype == KMSG_CRED_RENEW_CREDS) {

                    khui_alert_set_type(alert, KHUI_ALERTTYPE_RENEWFAIL);

                    cb = sizeof(w_idname);
                    if (nc->ctx.identity == NULL ||
                        KHM_FAILED(kcdb_identity_get_name(nc->ctx.identity,
                                                          w_idname, &cb))) {
                        LoadString(khm_hInstance, IDS_NC_REN_FAILED_TITLE,
                                   ws_title, ARRAYLENGTH(ws_title));
                    } else {
                        LoadString(khm_hInstance, IDS_NC_REN_FAILED_TITLE_I,
                                   ws_tfmt, ARRAYLENGTH(ws_tfmt));
                        StringCbPrintf(ws_title, sizeof(ws_title),
                                       ws_tfmt, w_idname);
                        khui_alert_set_ctx(alert,
                                           KHUI_SCOPE_IDENT,
                                           nc->ctx.identity,
                                           KCDB_CREDTYPE_INVALID,
                                           NULL);
                    }

                } else {
#ifdef DEBUG
                    assert(FALSE);
#endif
                }

                khui_alert_set_title(alert, ws_title);
                khui_alert_set_severity(alert, evt->severity);

                if(!evt->long_desc)
                    khui_alert_set_message(alert, evt->short_desc);
                else
                    khui_alert_set_message(alert, evt->long_desc);

                if(evt->suggestion)
                    khui_alert_set_suggestion(alert, evt->suggestion);

                if (nc->subtype == KMSG_CRED_RENEW_CREDS &&
                    nc->ctx.identity != NULL) {

                    khm_int32 n_cmd;

                    n_cmd = khm_get_identity_new_creds_action(nc->ctx.identity);

                    if (n_cmd != 0) {
                        khui_alert_add_command(alert, n_cmd);
                        khui_alert_add_command(alert, KHUI_PACTION_CLOSE);

                        khui_alert_set_flags(alert, KHUI_ALERT_FLAG_DISPATCH_CMD,
                                             KHUI_ALERT_FLAG_DISPATCH_CMD);
                    }
                }

                khui_alert_show(alert);
                khui_alert_release(alert);

                kherr_release_context(ctx);

                kherr_clear_error();
            }

        done_with_op:

            if (nc->subtype == KMSG_CRED_RENEW_CREDS) {
                kmq_post_message(KMSG_CRED, KMSG_CRED_END, 0, 
                                 m->vparam);
            } else {
                PostMessage(nc->hwnd, KHUI_WM_NC_NOTIFY, 
                            MAKEWPARAM(0, WMNC_DIALOG_PROCESS_COMPLETE),
                            0);
            }
        }
        break;

    case KMSG_CRED_END:
        /* all is done. */
        {
            khui_new_creds * nc;
            khm_boolean continue_cmdline = TRUE;

            nc = (khui_new_creds *) m->vparam;

            if (nc->subtype == KMSG_CRED_NEW_CREDS ||
                nc->subtype == KMSG_CRED_PASSWORD) {

                khm_cred_end_dialog(nc);

            } else if (nc->subtype == KMSG_CRED_RENEW_CREDS) {

                /* if this is a renewal that was triggered while we
                   were processing the commandline, then we need to
                   update the pending renewal count. */

                if (khm_startup.processing) {
                    LONG renewals;
                    renewals = InterlockedDecrement(&khm_startup.pending_renewals);

                    if (renewals != 0) {
                        continue_cmdline = FALSE;
                    }
                }
            }

            khui_cw_destroy_cred_blob(nc);

            kmq_post_message(KMSG_CRED, KMSG_CRED_REFRESH, 0, 0);

            if (continue_cmdline)
                kmq_post_message(KMSG_ACT, KMSG_ACT_CONTINUE_CMDLINE, 0, 0);
        }
        break;

        /* property sheet stuff */

    case KMSG_CRED_PP_BEGIN:
        /* all the pages should have been added by now.  Just send out
           the precreate message */
        kmq_post_message(KMSG_CRED, KMSG_CRED_PP_PRECREATE, 0, 
                         m->vparam);
        break;

    case KMSG_CRED_PP_END:
        kmq_post_message(KMSG_CRED, KMSG_CRED_PP_DESTROY, 0, 
                         m->vparam);
        break;

    case KMSG_CRED_DESTROY_CREDS:
#ifdef DEBUG
        assert(m->vparam != NULL);
#endif
        khui_context_release((khui_action_context *) m->vparam);
        PFREE(m->vparam);

        kmq_post_message(KMSG_CRED, KMSG_CRED_REFRESH, 0, 0);

        kmq_post_message(KMSG_ACT, KMSG_ACT_CONTINUE_CMDLINE, 0, 0);
        break;

    case KMSG_CRED_IMPORT:
        {
            khm_boolean continue_cmdline = FALSE;
            LONG pending_renewals;

            /* once an import operation ends, we have to trigger a
               renewal so that other plug-ins that didn't participate
               in the import operation can have a chance at getting
               the necessary credentials.

               If we are in the middle of processing the commandline,
               we have to be a little bit careful.  We can't issue a
               commandline conituation message right now because the
               import action is still ongoing (since the renewals are
               part of the action).  Once the renewals have completed,
               the completion handler will automatically issue a
               commandline continuation message.  However, if there
               were no identities to renew, then we have to issue the
               message ourselves.
            */

            InterlockedIncrement(&khm_startup.pending_renewals);

            khm_cred_renew_all_identities();

            pending_renewals = InterlockedDecrement(&khm_startup.pending_renewals);

            if (pending_renewals == 0 && khm_startup.processing)
                kmq_post_message(KMSG_ACT, KMSG_ACT_CONTINUE_CMDLINE, 0, 0);
        }
        break;

    case KMSG_CRED_REFRESH:
        kcdb_identity_refresh_all();
        break;
    }
}
Esempio n. 5
0
void
khm_cred_process_startup_actions(void) {
    khm_handle defident = NULL;

    if (!khm_startup.processing)
        return;

    if (khm_startup.init ||
        khm_startup.renew ||
        khm_startup.destroy ||
        khm_startup.autoinit) {
        kcdb_identity_get_default(&defident);
    }

    /* For asynchronous actions, we trigger the action and then exit
       the loop.  Once the action completes, the completion handler
       will trigger a continuation message which will result in this
       function getting called again.  Then we can proceed with the
       rest of the startup actions. */
    do {
        if (khm_startup.init) {

            khm_cred_obtain_new_creds_for_ident(defident, NULL);
            khm_startup.init = FALSE;
            break;
        }

        if (khm_startup.import) {
            khm_cred_import();
            khm_startup.import = FALSE;

            /* we also set the renew command to false here because we
               trigger a renewal for all the identities at the end of
               the import operation anyway. */
            khm_startup.renew = FALSE;
            break;
        }

        if (khm_startup.renew) {
            LONG pending_renewals;

            /* if there are no credentials, we just skip over the
               renew action. */

            khm_startup.renew = FALSE;

            InterlockedIncrement(&khm_startup.pending_renewals);

            khm_cred_renew_all_identities();

            pending_renewals = InterlockedDecrement(&khm_startup.pending_renewals);

            if (pending_renewals != 0)
                break;

            /* if there were no pending renewals, then we just fall
               through. This means that either there were no
               identities to renew, or all the renewals completed.  If
               all the renewals completed, then the commandline
               contiuation message wasn't triggered.  Either way, we
               must fall through if the count is zero. */
        }

        if (khm_startup.destroy) {

            khm_startup.destroy = FALSE;

            if (defident) {
                khm_cred_destroy_identity(defident);
                break;
            }
        }

        if (khm_startup.autoinit) {
            khm_size count = 0;
            khm_handle credset = NULL;
            khm_int32 ctype_ident = KCDB_CREDTYPE_INVALID;
            khm_int32 delta = 0;

            khm_startup.autoinit = FALSE;

            kcdb_credset_create(&credset);
            kcdb_identity_get_type(&ctype_ident);

            kcdb_credset_collect(credset, NULL,
                                 defident, ctype_ident,
                                 &delta);

            kcdb_credset_get_size(credset, &count);

            kcdb_credset_delete(credset);

            if (count == 0) {
                if (defident)
                    khui_context_set(KHUI_SCOPE_IDENT,
                                     defident,
                                     KCDB_CREDTYPE_INVALID,
                                     NULL, NULL, 0,
                                     NULL);
                else
                    khui_context_reset();

                khm_cred_obtain_new_creds(NULL);
                break;
            }
        }

        if (khm_startup.exit) {
            PostMessage(khm_hwnd_main,
                        WM_COMMAND,
                        MAKEWPARAM(KHUI_ACTION_EXIT, 0), 0);
            khm_startup.exit = FALSE;
            break;
        }

        if (khm_startup.display & SOPTS_DISPLAY_HIDE) {
            khm_hide_main_window();
        } else if (khm_startup.display & SOPTS_DISPLAY_SHOW) {
            khm_show_main_window();
        }
        khm_startup.display = 0;

        /* when we get here, then we are all done with the command
           line stuff */
        khm_startup.processing = FALSE;
        khm_startup.remote = FALSE;

        kmq_post_message(KMSG_ACT, KMSG_ACT_END_CMDLINE, 0, 0);
    } while(FALSE);

    if (defident)
        kcdb_identity_release(defident);
}