示例#1
0
void k4_write_identity_data(k4_dlg_data * d) {
    khm_handle csp_ident = NULL;
    khm_handle csp_k4 = NULL;
    khm_handle identity = NULL;

    if (KHM_SUCCEEDED(khui_cw_get_primary_id(d->nc, &identity)) &&
        KHM_SUCCEEDED(kcdb_identity_get_config(identity,
                                               KHM_FLAG_CREATE,
                                               &csp_ident))) {
        khc_open_space(csp_ident, CSNAME_KRB4CRED,
                       KHM_FLAG_CREATE | KCONF_FLAG_WRITEIFMOD,
                       &csp_k4);

        if (csp_k4) {
            khc_write_int32(csp_k4, L"Krb4NewCreds", !!d->k4_enabled);
            khc_write_int32(csp_k4, L"Krb4Method", d->method);

            khc_close_space(csp_k4);
        }

        khc_close_space(csp_ident);
    }

    if (identity)
        kcdb_identity_release(identity);
}
示例#2
0
void k4_read_identity_data(k4_dlg_data * d) {
    khm_handle csp_ident = NULL;
    khm_handle csp_k4 = NULL;
    khm_handle identity = NULL;

    khm_int32 idflags = 0;
    khm_int32 t;

    if (KHM_SUCCEEDED(khc_read_int32(csp_params, L"Krb4NewCreds", &t)))
        d->k4_enabled = !!t;
    else
        d->k4_enabled = TRUE;

    if (KHM_SUCCEEDED(khc_read_int32(csp_params, L"Krb4Method", &t)))
        d->method = t;
    else
        d->method = K4_METHOD_AUTO;

    if (KHM_SUCCEEDED(khc_read_int32(csp_params, L"DefaultLifetime", &t)))
        d->lifetime = t;
    else
        d->lifetime = 10 * 60 * 60; /* 10 hours */

    if (KHM_SUCCEEDED(khui_cw_get_primary_id(d->nc, &identity))) {

        if (KHM_SUCCEEDED(kcdb_identity_get_config(identity, 0,
                                                   &csp_ident))) {

            khc_open_space(csp_ident, CSNAME_KRB4CRED, 0, &csp_k4);

            if (csp_k4) {
                if (KHM_SUCCEEDED(khc_read_int32(csp_k4, L"Krb4NewCreds", &t)))
                    d->k4_enabled = !!t;
                if (KHM_SUCCEEDED(khc_read_int32(csp_k4, L"Krb4Method", &t)))
                    d->method = t;
                khc_close_space(csp_k4);
            }

            khc_close_space(csp_ident);
        }

        if (d->k4_enabled) {
            d->k4_enabled = k4_should_identity_get_k4(identity);
        }
    } else {
        d->k4_enabled = FALSE;
    }

    if (d->method < 0 || d->method > K4_METHOD_K524)
        d->method = K4_METHOD_AUTO;

    if (identity)
        kcdb_identity_release(identity);
}
示例#3
0
void
k4_id_read_params(k4_id_data * d) {
    khm_handle ident = NULL;
    khm_handle csp_ident = NULL;
    khm_handle csp_idk4 = NULL;
    khm_int32 flags = 0;
    khm_int32 t;

    khc_read_int32(csp_params, L"Krb4NewCreds", &d->gettix);

    ident = khui_cfg_get_data(d->cfg.ctx_node);

    if (ident == NULL) {
        d->gettix = 0;
        goto done;
    }

    kcdb_identity_get_flags(ident, &flags);

    if (!(flags & KCDB_IDENT_FLAG_DEFAULT)) {
        d->gettix = 0;
        goto done;
    }

    d->is_default_ident = TRUE;

    if (d->gettix == 0)
        goto done;

    if (KHM_FAILED(kcdb_identity_get_config(ident, 0, &csp_ident)))
        goto done;

    if (KHM_FAILED(khc_open_space(csp_ident, CSNAME_KRB4CRED,
                                  0, &csp_idk4)))
        goto close_config;

    if (KHM_SUCCEEDED(khc_read_int32(csp_idk4, L"Krb4NewCreds", &t)) &&
        !t)
        d->gettix = 1;

 close_config:
    if (csp_ident)
        khc_close_space(csp_ident);

    if (csp_idk4)
        khc_close_space(csp_idk4);

 done:
    if (ident)
        kcdb_identity_release(ident);

    return;
}
示例#4
0
khm_boolean k4_should_identity_get_k4(khm_handle ident) {
    khm_int32 idflags = 0;
    khm_int32 t = TRUE;
    khm_handle csp_ident = NULL;
    khm_handle csp_k4 = NULL;
    khm_boolean get_k4 = TRUE;
    khm_boolean id_spec = FALSE;

    if (KHM_FAILED(kcdb_identity_get_flags(ident, &idflags)))
        return FALSE;

    if (!(idflags & KCDB_IDENT_FLAG_DEFAULT)) {
        /* we only support k4 for one identity, and that is the
           default identity.  If we are trying to get tickets for a
           non-default identity, then we start off as disabled unless
           there is no default identity. */

        khm_handle defident = NULL;

        if (KHM_SUCCEEDED(kcdb_identity_get_default(&defident))) {
            kcdb_identity_release(defident);

            return FALSE;
        }
    }

    if (KHM_SUCCEEDED(kcdb_identity_get_config(ident, 0, &csp_ident))) {
        if (KHM_SUCCEEDED(khc_open_space(csp_ident, CSNAME_KRB4CRED, 0,
                                         &csp_k4))) {
            khm_int32 t = 0;

            if (KHM_SUCCEEDED(khc_read_int32(csp_k4, L"Krb4NewCreds", &t))) {
                get_k4 = !!t;
                id_spec = TRUE;
            }

            khc_close_space(csp_k4);
        }
        khc_close_space(csp_ident);
    }

    /* if there was a value specified for the identity, then that
       takes precedence. */
    if (id_spec || !get_k4)
        return get_k4;

    if (KHM_SUCCEEDED(khc_read_int32(csp_params, L"Krb4NewCreds", &t)) &&
        !t)
        return FALSE;

    return TRUE;
}
示例#5
0
khm_boolean
k4_id_write_params(HWND hwnd, k4_id_data * d) {
    khm_handle ident = NULL;
    khm_int32 flags = 0;
    khm_handle csp_ident = NULL;
    khm_handle csp_idk4 = NULL;
    khm_int32 gettix = 0;
    khm_boolean applied = FALSE;

    ident = khui_cfg_get_data(d->cfg.ctx_node);
    if (ident == NULL)
        return FALSE;

    kcdb_identity_get_flags(ident, &flags);

    if (!(flags & KCDB_IDENT_FLAG_DEFAULT))
        goto done_apply;

    if (IsDlgButtonChecked(hwnd, IDC_CFG_GETTIX) == BST_CHECKED)
        gettix = TRUE;

    if (KHM_FAILED(kcdb_identity_get_config(ident, KHM_FLAG_CREATE,
                                            &csp_ident)))
        goto done_apply;

    if (KHM_FAILED(khc_open_space(csp_ident, CSNAME_KRB4CRED,
                                  KHM_FLAG_CREATE | KCONF_FLAG_WRITEIFMOD,
                                  &csp_idk4)))
        goto done_apply;

    khc_write_int32(csp_idk4, L"Krb4NewCreds", gettix);

    applied = TRUE;

 done_apply:
    if (ident)
        kcdb_identity_release(ident);

    if (csp_ident)
        khc_close_space(csp_ident);

    if (csp_idk4)
        khc_close_space(csp_idk4);

    return applied;
}
示例#6
0
void k4_write_identity_data(k4_dlg_data * d) {
    khm_handle csp_ident = NULL;
    khm_handle csp_k4 = NULL;

    if (d->nc->n_identities > 0 &&
        d->nc->identities[0] &&
        KHM_SUCCEEDED(kcdb_identity_get_config(d->nc->identities[0],
                                               KHM_FLAG_CREATE,
                                               &csp_ident))) {
        khc_open_space(csp_ident, CSNAME_KRB4CRED,
                       KHM_FLAG_CREATE | KCONF_FLAG_WRITEIFMOD,
                       &csp_k4);

        if (csp_k4) {
            khc_write_int32(csp_k4, L"Krb4NewCreds", !!d->k4_enabled);
            khc_write_int32(csp_k4, L"Krb4Method", d->method);

            khc_close_space(csp_k4);
        }

        khc_close_space(csp_ident);
    }
}
示例#7
0
/* dialog box procedure for the "Add new identity" dialog */
INT_PTR CALLBACK
khm_cfg_add_ident_proc(HWND hwnd,
                       UINT umsg,
                       WPARAM wParam,
                       LPARAM lParam) {
    add_ident_data * d;

    switch(umsg) {
    case WM_INITDIALOG:
        /* we create a new credentials blob and pull in the identity
           selectors from the identity provider. */
        d = PMALLOC(sizeof(*d));
        ZeroMemory(d, sizeof(*d));

        khui_cw_create_cred_blob(&d->nc);
#ifdef DEBUG
        assert(d->nc != NULL);
#endif
        if (d->nc == NULL) {
            PFREE(d);
            break;
        }

        if (KHM_FAILED(kcdb_identpro_get_ui_cb(&d->nc->ident_cb))) {
            /* this should have worked.  The only reason it would fail
               is if there is no identity provider or if the identity
               provider does not support providing idnetity
               selectors. */
            khui_cw_destroy_cred_blob(d->nc);
            PFREE(d);
            break;
        }

#pragma warning(push)
#pragma warning(disable: 4244)
        SetWindowLongPtr(hwnd, DWLP_USER, (LONG_PTR) d);
#pragma warning(pop)

        /* get metrics for dynamic controls */
        get_ctrl_row_metrics(&d->dim_small,
                             GetDlgItem(hwnd, IDC_SM_LBL),
                             GetDlgItem(hwnd, IDC_SM_CTL));
        get_ctrl_row_metrics(&d->dim_medium,
                             GetDlgItem(hwnd, IDC_MED_LBL),
                             GetDlgItem(hwnd, IDC_MED_CTL));
        get_ctrl_row_metrics(&d->dim_large,
                             GetDlgItem(hwnd, IDC_LG_LBL),
                             GetDlgItem(hwnd, IDC_LG_CTL));

        {
            RECT rlbl;
            RECT rctl;
            RECT rwnd;

            GetWindowRect(GetDlgItem(hwnd, IDC_SM_LBL),
                          &rlbl);
            GetWindowRect(GetDlgItem(hwnd, IDC_SM_CTL),
                          &rctl);
            GetWindowRect(hwnd, &rwnd);

            OffsetRect(&rlbl, -rwnd.left, -rwnd.top);
            OffsetRect(&rctl, -rwnd.left, -rwnd.top);

            d->current_x = rlbl.left;
            d->current_y = rctl.top - GetSystemMetrics(SM_CYCAPTION);

            GetWindowRect(GetDlgItem(hwnd, IDC_MED_CTL),
                          &rlbl);
            OffsetRect(&rlbl, -rwnd.left, -rwnd.top);

            d->row_gap = rlbl.top - rctl.bottom;
        }

        d->nc->hwnd = hwnd;

        /* now call the UI callback and make it create the
           controls. */
        d->nc->ident_cb(d->nc, WMNC_IDENT_INIT, NULL, 0, 0,
                        (LPARAM) hwnd);

        break;

    case WM_DESTROY:
        d = (add_ident_data *)(LONG_PTR)
            GetWindowLongPtr(hwnd, DWLP_USER);
        if (d == NULL)
            break;

        d->nc->ident_cb(d->nc, WMNC_IDENT_EXIT, NULL, 0, 0, 0);

        khui_cw_destroy_cred_blob(d->nc);
        PFREE(d);
        break;

    case KHUI_WM_NC_NOTIFY:
        d = (add_ident_data *)(LONG_PTR)
            GetWindowLongPtr(hwnd, DWLP_USER);

        switch(HIWORD(wParam)) {
        case WMNC_ADD_CONTROL_ROW:
            {
                khui_control_row * row;
                RECT r_lbl, r_inp, r_enc;
                struct ctrl_row_dimensions * dim;
                HFONT hf;

                row = (khui_control_row *) lParam;

#ifdef DEBUG
                assert(row->label);
                assert(row->input);
                assert(d);
#endif

                if (row->size == KHUI_CTRLSIZE_SMALL) {
                    dim = &d->dim_small;
                } else if (row->size == KHUI_CTRLSIZE_HALF) {
                    dim = &d->dim_medium;
                } else {
                    dim = &d->dim_large;
#ifdef DEBUG
                    assert(row->size == KHUI_CTRLSIZE_FULL);
#endif
                }

                CopyRect(&r_enc, &dim->enclosure);
                CopyRect(&r_lbl, &dim->label);
                CopyRect(&r_inp, &dim->control);

                OffsetRect(&r_enc, d->current_x, d->current_y);
                OffsetRect(&r_lbl, r_enc.left, r_enc.top);
                OffsetRect(&r_inp, r_enc.left, r_enc.top);

                d->current_y += r_enc.bottom - r_enc.top;

                hf = (HFONT) SendDlgItemMessage(hwnd, IDOK, WM_GETFONT, 0, 0);

                if (row->label) {
                    SetWindowPos(row->label,
                                 ((d->hwnd_last_ctrl != NULL)?
                                  d->hwnd_last_ctrl :
                                  HWND_TOP),
                                 r_lbl.left, r_lbl.top,
                                 r_lbl.right - r_lbl.left,
                                 r_lbl.bottom - r_lbl.top,
                                 SWP_DEFERERASE | SWP_NOACTIVATE |
                                 SWP_NOOWNERZORDER);
                    if (hf)
                        SendMessage(row->label, WM_SETFONT,
                                    (WPARAM) hf,
                                    TRUE);
                    d->hwnd_last_ctrl = row->label;
                }

                if (row->input) {
                    SetWindowPos(row->input,
                                 ((d->hwnd_last_ctrl != NULL)?
                                  d->hwnd_last_ctrl :
                                  HWND_TOP),
                                 r_inp.left, r_inp.top,
                                 r_inp.right - r_inp.left,
                                 r_inp.bottom - r_inp.top,
                                 SWP_DEFERERASE | SWP_NOACTIVATE |
                                 SWP_NOOWNERZORDER);
                    if (hf)
                        SendMessage(row->input, WM_SETFONT,
                                    (WPARAM) hf,
                                    TRUE);
                    d->hwnd_last_ctrl = row->input;
                }
            }
            break;

        case WMNC_IDENTITY_CHANGE:
            break;
        }
        return TRUE;

    case WM_COMMAND:
        if (LOWORD(wParam) == IDOK) {
            wchar_t idname[KCDB_IDENT_MAXCCH_NAME];
            wchar_t err_msg[1024];
            khm_handle ident = NULL;
            khm_handle csp_ident = NULL;
            khm_size cb;
            khm_int32 rv = KHM_ERROR_SUCCESS;

            d = (add_ident_data *)(LONG_PTR)
                GetWindowLongPtr(hwnd, DWLP_USER);

            if (!d || !d->nc)
                break;

            /* check if there was an identity selected */
            if (d->nc->n_identities == 0 ||
                d->nc->identities[0] == NULL) {

                StringCbCopy(idname, sizeof(idname), L"");

                LoadString(khm_hInstance, IDS_CFG_IDNAME_NON,
                           err_msg, ARRAYLENGTH(err_msg));

                goto show_failure;
            }

            ident = d->nc->identities[0];
            kcdb_identity_hold(ident);

            cb = sizeof(idname);
            kcdb_identity_get_name(ident, idname, &cb);

            /* now we have to create the identity configuration. */
            if (KHM_FAILED(rv = kcdb_identity_get_config(ident,
                                                         KHM_FLAG_CREATE,
                                                         &csp_ident))) {
                wchar_t fmt[256];

                LoadString(khm_hInstance, IDS_CFG_IDNAME_CCC,
                           fmt, ARRAYLENGTH(fmt));
                StringCbPrintf(err_msg, sizeof(err_msg), fmt, rv);

                kcdb_identity_release(ident);

                goto show_failure;
            }

            /* create a value so that the configuration space will
               actually be created in the registry.  We don't want
               this new identity to be sticky. */
            khc_write_int32(csp_ident, L"Sticky", 0);

            khm_refresh_config();

            kcdb_identity_release(ident);
            khc_close_space(csp_ident);

            EndDialog(hwnd, 0);
            break;

        show_failure:
            {
                wchar_t title[512];
                wchar_t fmt[256];

                if (!err_msg[0])
                    break;

                LoadString(khm_hInstance, IDS_CFG_IDNAME_PRB,
                           fmt, ARRAYLENGTH(fmt));
                StringCbPrintf(title, sizeof(title), fmt, idname);

                MessageBox(hwnd, err_msg, title, MB_OK | MB_ICONSTOP);

                /* don't end the dialog yet */
                break;
            }
            break;
            
        } else if (LOWORD(wParam) == IDCANCEL) {
            EndDialog(hwnd, 1);
        } else {
            d = (add_ident_data *)(LONG_PTR)
                GetWindowLongPtr(hwnd, DWLP_USER);

            if (d && d->nc && d->nc->ident_cb) {
                return d->nc->ident_cb(d->nc, WMNC_IDENT_WMSG,
                                       hwnd, umsg, wParam, lParam);
            }
        }
        break;
    }

    return FALSE;
}
示例#8
0
static void
write_params_ident(ident_data * d) {
    khm_handle csp_ident;

    if (d->saved.monitor == d->work.monitor &&
        d->saved.auto_renew == d->work.auto_renew &&
        d->saved.sticky == d->work.sticky &&
        !d->removed)
        return;

    if (KHM_FAILED(kcdb_identity_get_config(d->ident, KHM_PERM_WRITE,
                                            &csp_ident))) {
#ifdef DEBUG
        assert(FALSE);
#endif
        return;
    }

    if (d->removed) {
        khm_handle h = NULL;
        khm_int32 flags = 0;

        khc_remove_space(csp_ident);

        /* calling kcdb_identity_get_config() will update the
           KCDB_IDENT_FLAG_CONFIG flag for the identity to reflect the
           fact that it nolonger has a configuration. */
        kcdb_identity_get_config(d->ident, 0, &h);
        if (h) {
            /* what the ? */
#ifdef DEBUG
            assert(FALSE);
#endif
            khc_close_space(h);
        }
#ifdef DEBUG
        kcdb_identity_get_flags(d->ident, &flags);
        assert(!(flags & KCDB_IDENT_FLAG_CONFIG));
#endif

    } else {

        if (d->saved.monitor != d->work.monitor)
            khc_write_int32(csp_ident, L"Monitor", !!d->work.monitor);

        if (d->saved.auto_renew != d->work.auto_renew)
            khc_write_int32(csp_ident, L"AllowAutoRenew",
                            !!d->work.auto_renew);

        if (d->saved.sticky != d->work.sticky) {
            kcdb_identity_set_flags(d->ident,
                                    (d->work.sticky)?KCDB_IDENT_FLAG_STICKY:0,
                                    KCDB_IDENT_FLAG_STICKY);
        }
    }

    khc_close_space(csp_ident);

    d->saved = d->work;

    d->applied = TRUE;

    if (d->hwnd)
        PostMessage(d->hwnd, KHUI_WM_CFG_NOTIFY,
                    MAKEWPARAM(0, WMCFG_UPDATE_STATE), 0);

    khm_refresh_config();
}
示例#9
0
static void
read_params_ident(ident_data * d) {
    khm_handle csp_ident;
    khm_handle csp_cw;
    khm_int32 t;

    if (KHM_FAILED(kcdb_identity_get_config(d->ident,
                                            KHM_PERM_READ,
                                            &csp_ident))) {
        csp_ident = NULL;
    }

    if (KHM_SUCCEEDED(khc_open_space(NULL, L"CredWindow", KHM_PERM_READ,
                                     &csp_cw))) {
        if (csp_ident) {
            khc_shadow_space(csp_ident,
                             csp_cw);
            khc_close_space(csp_cw);
        } else {
            csp_ident = csp_cw;
        }
        csp_cw = NULL;
    } else {
#ifdef DEBUG
        assert(FALSE);
#endif
        d->saved.monitor = TRUE;
        d->saved.auto_renew = TRUE;
        d->saved.sticky = FALSE;
        d->work = d->saved;

        if (csp_ident)
            khc_close_space(csp_ident);

        return;
    }

    if (KHM_FAILED(khc_read_int32(csp_ident, L"Monitor", &t))) {
#ifdef DEBUG
        assert(FALSE);
#endif
        d->saved.monitor = TRUE;
    } else {
        d->saved.monitor = !!t;
    }

    if (KHM_FAILED(khc_read_int32(csp_ident, L"AllowAutoRenew", &t))) {
#ifdef DEBUG
        assert(FALSE);
#endif
        d->saved.auto_renew = TRUE;
    } else {
        d->saved.auto_renew = !!t;
    }

    if (KHM_FAILED(khc_read_int32(csp_ident, L"Sticky", &t))) {
        d->saved.sticky = FALSE;
    } else {
        d->saved.sticky = !!t;
    }

    khc_close_space(csp_ident);

    d->work = d->saved;
    d->applied = FALSE;
}
示例#10
0
static krb5_error_code KRB5_CALLCONV
kinit_prompter(krb5_context context,
               void *data,
               const char *name,
               const char *banner,
               int num_prompts,
               krb5_prompt prompts[])
{
    int i;
    k5_kinit_task * kt;
    khm_size ncp;
    krb5_error_code code = 0;
    BOOL new_prompts = TRUE;
    khm_handle csp_prcache = NULL;

    kt = (k5_kinit_task *) data;
    assert(kt && kt->magic == K5_KINIT_TASK_MAGIC);

    EnterCriticalSection(&kt->cs);

    if (kt->state == K5_KINIT_STATE_ABORTED) {
        LeaveCriticalSection(&kt->cs);
        return KRB5_LIBOS_PWDINTR;
    }

#ifdef DEBUG
    assert(kt->state == K5_KINIT_STATE_INCALL ||
           kt->state == K5_KINIT_STATE_CONFIRM);

    _reportf(L"k5_kinit_prompter() received %d prompts with name=[%S] banner=[%S]",
             num_prompts,
             name, banner);
    for (i=0; i < num_prompts; i++) {
        _reportf(L"Prompt[%d]: string[%S]", i, prompts[i].prompt);
    }
#endif

    /* we got prompts?  Then we assume that the principal is valid */

    if (!kt->is_valid_principal) {
        kt->is_valid_principal = TRUE;

        /* if the flags that were used to call kinit were restricted
           because we didn't know the validity of the principal, then
           we need to go back and retry the call with the correct
           flags. */
        if (kt->params.forwardable ||
            kt->params.proxiable ||
            kt->params.renewable) {

            _reportf(L"Retrying kinit call due to restricted flags on first call.");
            kt->state = K5_KINIT_STATE_RETRY;
            LeaveCriticalSection(&kt->cs);

            return KRB5_LIBOS_PWDINTR;
        }
    }

    /* check if we are already showing the right prompts */
    khui_cw_get_prompt_count(kt->nc, &ncp);

    if (num_prompts != (int) ncp && num_prompts != 0)
        goto _show_new_prompts;

    for (i=0; i < num_prompts; i++) {
        wchar_t wprompt[KHUI_MAXCCH_PROMPT];
        khui_new_creds_prompt * p;

        if(prompts[i].prompt) {
            AnsiStrToUnicode(wprompt, sizeof(wprompt),
                             prompts[i].prompt);
        } else {
            wprompt[0] = L'\0';
        }

        if (KHM_FAILED(khui_cw_get_prompt(kt->nc, i, &p)))
            break;

        if (                    /* if we received a prompt string,
                                   then it should be the same as the
                                   one that is displayed */
            (wprompt[0] != L'\0' &&
             (p->prompt == NULL ||
              wcscmp(wprompt, p->prompt))) ||

                                /* if we didn't receive one, then
                                   there shouldn't be one displayed.
                                   This case really shouldn't happen
                                   in reality, but we check anyway. */
            (wprompt[0] == L'\0' &&
             p->prompt != NULL) ||

                                /* the type should match */
            (prompts[i].type != p->type) ||

                                /* if this prompt should be hidden,
                                   then it must also be so */
            (prompts[i].hidden &&
             !(p->flags & KHUI_NCPROMPT_FLAG_HIDDEN)) ||
            (!prompts[i].hidden &&
             (p->flags & KHUI_NCPROMPT_FLAG_HIDDEN))
            )

            break;
    }

    if (i >= num_prompts) {

        new_prompts = FALSE;

        /* ok. looks like we are already showing the same set of
           prompts that we were supposed to show.  Sync up the values
           and go ahead. */
        goto _process_prompts;
    }

 _show_new_prompts:
    if (num_prompts == 0) {

        assert(FALSE);

        khui_cw_notify_identity_state(kt->nc,
                                      kt->nct->hwnd_panel,
                                      NULL,
                                      KHUI_CWNIS_READY |
                                      KHUI_CWNIS_NOPROGRESS |
                                      KHUI_CWNIS_VALIDATED, 0);

        code = 0;
        kt->is_null_password = TRUE;
        goto _process_prompts;
    }

    /* in addition to showing new prompts, we also cache the first set
       of prompts. */
    if (kt->prompt_set_index == 0) {
        khm_handle csp_idconfig = NULL;
        khm_handle csp_idk5 = NULL;

        kcdb_identity_get_config(kt->identity,
                                 KHM_FLAG_CREATE,
                                 &csp_idconfig);

        if (csp_idconfig != NULL)
            khc_open_space(csp_idconfig,
                           CSNAME_KRB5CRED,
                           KHM_FLAG_CREATE,
                           &csp_idk5);

        if (csp_idk5 != NULL)
            khc_open_space(csp_idk5,
                           CSNAME_PROMPTCACHE,
                           KHM_FLAG_CREATE,
                           &csp_prcache);

        khc_close_space(csp_idconfig);
        khc_close_space(csp_idk5);
    }

    {
        wchar_t wbanner[KHUI_MAXCCH_BANNER];
        wchar_t wname[KHUI_MAXCCH_PNAME];

        if(banner)
            AnsiStrToUnicode(wbanner, sizeof(wbanner), banner);
        else
            wbanner[0] = L'\0';

        if(name)
            AnsiStrToUnicode(wname, sizeof(wname), name);
        else
            LoadString(hResModule, IDS_PNAME_PW, wname, ARRAYLENGTH(wname));

        khui_cw_clear_prompts(kt->nc);

        khui_cw_begin_custom_prompts(kt->nc, num_prompts, wbanner, wname);

        if (csp_prcache) {
            FILETIME current;
            FILETIME lifetime;
            FILETIME expiry;
            khm_int64 iexpiry;
            khm_int32 t = 0;

            khc_write_string(csp_prcache, L"Banner", wbanner);
            khc_write_string(csp_prcache, L"Name", (name)? wname: L"");
            khc_write_int32(csp_prcache, L"PromptCount", (khm_int32) num_prompts);

            GetSystemTimeAsFileTime(&current);
#ifdef USE_PROMPT_CACHE_LIFETIME
            khc_read_int32(csp_params, L"PromptCacheLifetime", &t);
            if (t == 0)
                t = 172800;         /* 48 hours */
#else
            khc_read_int32(csp_params, L"MaxRenewLifetime", &t);
            if (t == 0)
                t = 2592000;    /* 30 days */
            t += 604800;        /* + 7 days */
#endif
            TimetToFileTimeInterval(t, &lifetime);
            expiry = FtAdd(&current, &lifetime);
            iexpiry = FtToInt(&expiry);

            khc_write_int64(csp_prcache, L"ExpiresOn", iexpiry);
        }
    }

    for(i=0; i < num_prompts; i++) {
        wchar_t wprompt[KHUI_MAXCCH_PROMPT];

        if(prompts[i].prompt) {
            AnsiStrToUnicode(wprompt, sizeof(wprompt),
                             prompts[i].prompt);
        } else {
            wprompt[0] = 0;
        }

        khui_cw_add_prompt(kt->nc, prompts[i].type,
                           wprompt, NULL,
                           (prompts[i].hidden?KHUI_NCPROMPT_FLAG_HIDDEN:0));

        if (csp_prcache) {
            khm_handle csp_p = NULL;
            wchar_t wnum[8];    /* should be enough for 10
                                   million prompts */

            wnum[0] = 0;
            StringCbPrintf(wnum, sizeof(wnum), L"%d", i);

            khc_open_space(csp_prcache, wnum, KHM_FLAG_CREATE, &csp_p);

            if (csp_p) {
                khc_write_string(csp_p, L"Prompt", wprompt);
                khc_write_int32(csp_p, L"Type", prompts[i].type);
                khc_write_int32(csp_p, L"Flags",
                                (prompts[i].hidden?
                                 KHUI_NCPROMPT_FLAG_HIDDEN:0));

                khc_close_space(csp_p);
            }
        }
    }

    if (csp_prcache) {
        khc_close_space(csp_prcache);
        csp_prcache = NULL;
    }

 _process_prompts:
    if (new_prompts) {
        kt->state = K5_KINIT_STATE_WAIT;

        kcdb_identity_set_flags(kt->identity,
                                KCDB_IDENT_FLAG_VALID | KCDB_IDENT_FLAG_KEY_EXPORT,
                                KCDB_IDENT_FLAG_VALID | KCDB_IDENT_FLAG_KEY_EXPORT);
        khui_cw_notify_identity_state(kt->nc, kt->nct->hwnd_panel, L"",
                                      KHUI_CWNIS_VALIDATED |
                                      KHUI_CWNIS_READY, 0);

        SetEvent(kt->h_parent_wait);
        LeaveCriticalSection(&kt->cs);
        WaitForSingleObject(kt->h_task_wait, INFINITE);
        EnterCriticalSection(&kt->cs);
    }

    /* we get here after the user selects an action that either
       cancels the credentials acquisition operation or triggers the
       actual acquisition of credentials. */
    if (kt->state != K5_KINIT_STATE_INCALL &&
        kt->state != K5_KINIT_STATE_CONFIRM) {
        code = KRB5_LIBOS_PWDINTR;
        goto _exit;
    }

    kt->is_null_password = FALSE;

    /* otherwise, we need to get the data back from the UI and return
       0 */

    khui_cw_sync_prompt_values(kt->nc);

    for(i=0; i<num_prompts; i++) {
        krb5_data * d;
        wchar_t wbuf[512];
        khm_size cbbuf;
        size_t cch;

        d = prompts[i].reply;

        cbbuf = sizeof(wbuf);
        if(KHM_SUCCEEDED(khui_cw_get_prompt_value(kt->nc, i, wbuf, &cbbuf))) {
            UnicodeStrToAnsi(d->data, d->length, wbuf);
            if(SUCCEEDED(StringCchLengthA(d->data, d->length, &cch)))
                d->length = (unsigned int) cch;
            else
                d->length = 0;
        } else {
            assert(FALSE);
            d->length = 0;
        }

        if (prompts[i].type == KRB5_PROMPT_TYPE_PASSWORD &&
            d->length == 0)

            kt->is_null_password = TRUE;
    }

    if (khui_cw_get_persist_private_data(kt->nc) &&
        num_prompts == 1 &&
	prompts[0].type == KRB5_PROMPT_TYPE_PASSWORD &&
        prompts[0].reply->length != 0) {
        k5_reply_to_acqpriv_id_request(kt->nc, prompts[0].reply);
    }

 _exit:

    kt->prompt_set_index++;

    LeaveCriticalSection(&kt->cs);

    /* entering a NULL password is equivalent to cancelling out */
    if (kt->is_null_password)
        return KRB5_LIBOS_PWDINTR;
    else
        return code;
}
示例#11
0
/* Returns true if we find cached prompts.
   Called with kt->cs held.
 */
static khm_boolean
cached_kinit_prompter(k5_kinit_task * kt) {
    khm_boolean rv = FALSE;
    khm_handle csp_idconfig = NULL;
    khm_handle csp_k5config = NULL;
    khm_handle csp_prcache = NULL;
    khm_size cb;
    khm_size n_cur_prompts;
    khm_int32 n_prompts;
    khm_int32 i;
    khm_int64 iexpiry;
    FILETIME expiry;

    assert(kt->nc);

    if (KHM_FAILED(kcdb_identity_get_config(kt->identity, 0, &csp_idconfig)) ||

        KHM_FAILED(khc_open_space(csp_idconfig, CSNAME_KRB5CRED,
                                  0, &csp_k5config)) ||

        KHM_FAILED(khc_open_space(csp_k5config, CSNAME_PROMPTCACHE,
                                  0, &csp_prcache)) ||

        KHM_FAILED(khc_read_int32(csp_prcache, L"PromptCount",
                                  &n_prompts)) ||
        n_prompts == 0)

        goto _cleanup;

    if (KHM_SUCCEEDED(khc_read_int64(csp_prcache, L"ExpiresOn", &iexpiry))) {
        FILETIME current;

        /* has the cache expired? */
        expiry = IntToFt(iexpiry);
        GetSystemTimeAsFileTime(&current);

        if (CompareFileTime(&expiry, &current) < 0)
            /* already expired */
            goto _cleanup;
    } else {
        /* if there is no value for ExpiresOn, we assume the prompts
           have already expired. */
        goto _cleanup;
    }

    /* we found a prompt cache.  We take this to imply that the
       principal is valid. */
    kt->is_valid_principal = TRUE;

    /* check if there are any prompts currently showing.  If there are
       we check if they are the same as the ones we are going to show.
       In which case we just reuse the exisitng prompts */
    if (KHM_FAILED(khui_cw_get_prompt_count(kt->nc, &n_cur_prompts)) ||
        n_prompts != (khm_int32) n_cur_prompts)
        goto _show_new_prompts;

    for(i = 0; i < n_prompts; i++) {
        wchar_t wsname[8];
        wchar_t wprompt[KHUI_MAXCCH_PROMPT];
        khm_handle csp_p = NULL;
        khm_int32 p_type;
        khm_int32 p_flags;
        khui_new_creds_prompt * p;

        if (KHM_FAILED(khui_cw_get_prompt(kt->nc, i, &p)))
            break;

        StringCbPrintf(wsname, sizeof(wsname), L"%d", i);

        if (KHM_FAILED(khc_open_space(csp_prcache, wsname, 0, &csp_p)))
            break;

        cb = sizeof(wprompt);
        if (KHM_FAILED(khc_read_string(csp_p, L"Prompt",
                                       wprompt, &cb))) {
            khc_close_space(csp_p);
            break;
        }

        if (KHM_FAILED(khc_read_int32(csp_p, L"Type", &p_type)))
            p_type = 0;

        if (KHM_FAILED(khc_read_int32(csp_p, L"Flags", &p_flags)))
            p_flags = 0;

        if (                    /* if we received a prompt string,
                                   then it should be the same as the
                                   one that is displayed */
            (wprompt[0] &&
             (p->prompt == NULL ||
              wcscmp(wprompt, p->prompt))) ||

                                /* if we didn't receive one, then
                                   there shouldn't be one displayed.
                                   This case really shouldn't happen
                                   in reality, but we check anyway. */
            (!wprompt[0] &&
             p->prompt != NULL) ||

                                /* the type should match */
            (p_type != p->type) ||

                                /* if this prompt should be hidden,
                                   then it must also be so */
            (p_flags != p->flags)
            ) {

            khc_close_space(csp_p);
            break;

        }


        khc_close_space(csp_p);
    }

    if (i == n_prompts) {
        /* We are already showing the right set of prompts. */
        rv = TRUE;
        goto _cleanup;
    }

 _show_new_prompts:

    khui_cw_clear_prompts(kt->nc);

    {
        wchar_t wbanner[KHUI_MAXCCH_BANNER];
        wchar_t wpname[KHUI_MAXCCH_PNAME];

        cb = sizeof(wbanner);
        if (KHM_FAILED(khc_read_string(csp_prcache, L"Banner",
                                      wbanner, &cb)))
            wbanner[0] = 0;

        cb = sizeof(wpname);
        if (KHM_FAILED(khc_read_string(csp_prcache, L"Name",
                                       wpname, &cb)))
            wpname[0] = 0;

        if (wpname[0] == L'\0')
            LoadString(hResModule, IDS_PNAME_PW, wpname, ARRAYLENGTH(wpname));

        khui_cw_begin_custom_prompts(kt->nc,
                                     n_prompts,
                                     (wbanner[0]? wbanner: NULL),
                                     (wpname[0]? wpname: NULL));
    }

    for(i = 0; i < n_prompts; i++) {
        wchar_t wsname[8];
        wchar_t wprompt[KHUI_MAXCCH_PROMPT];
        khm_handle csp_p = NULL;
        khm_int32 p_type;
        khm_int32 p_flags;

        StringCbPrintf(wsname, sizeof(wsname), L"%d", i);

        if (KHM_FAILED(khc_open_space(csp_prcache, wsname, 0, &csp_p)))
            break;

        cb = sizeof(wprompt);
        if (KHM_FAILED(khc_read_string(csp_p, L"Prompt",
                                       wprompt, &cb))) {
            khc_close_space(csp_p);
            break;
        }

        if (KHM_FAILED(khc_read_int32(csp_p, L"Type", &p_type)))
            p_type = 0;

        if (KHM_FAILED(khc_read_int32(csp_p, L"Flags", &p_flags)))
            p_flags = 0;

        khui_cw_add_prompt(kt->nc, p_type, wprompt, NULL, p_flags);

        khc_close_space(csp_p);
    }

    if (i < n_prompts) {
        khui_cw_clear_prompts(kt->nc);
    } else {
        rv = TRUE;
    }

 _cleanup:

    if (csp_prcache)
        khc_close_space(csp_prcache);

    if (csp_k5config)
        khc_close_space(csp_k5config);

    if (csp_idconfig)
        khc_close_space(csp_idconfig);

    return rv;
}