Пример #1
0
void khm_cred_destroy_identity(khm_handle identity)
{
    khui_action_context * pctx;
    wchar_t idname[KCDB_IDENT_MAXCCH_NAME];
    khm_size cb;

    if (identity == NULL)
        return;

    pctx = PMALLOC(sizeof(*pctx));
#ifdef DEBUG
    assert(pctx);
#endif

    khui_context_create(pctx,
                        KHUI_SCOPE_IDENT,
                        identity,
                        KCDB_CREDTYPE_INVALID,
                        NULL);

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

    _begin_task(KHERR_CF_TRANSITIVE);
    _report_sr1(KHERR_NONE, IDS_CTX_DESTROY_ID, _dupstr(idname));
    _describe();

    kmq_post_message(KMSG_CRED,
                     KMSG_CRED_DESTROY_CREDS,
                     0,
                     (void *) pctx);

    _end_task();
}
Пример #2
0
void khm_cred_renew_cred(khm_handle cred)
{
    khui_new_creds * c;

    khui_cw_create_cred_blob(&c);

    c->subtype = KMSG_CRED_RENEW_CREDS;
    c->result = KHUI_NC_RESULT_PROCESS;
    khui_context_create(&c->ctx,
                        KHUI_SCOPE_CRED,
                        NULL,
                        KCDB_CREDTYPE_INVALID,
                        cred);

    _begin_task(KHERR_CF_TRANSITIVE);
    _report_sr0(KHERR_NONE, IDS_CTX_RENEW_CREDS);
    _describe();

    /* if we are calling this while processing startup actions, we
       need to keep track of how many we have issued. */
    if (khm_startup.processing) {
        InterlockedIncrement(&khm_startup.pending_renewals);
    }

    kmq_post_message(KMSG_CRED, KMSG_CRED_RENEW_CREDS, 0, (void *) c);

    _end_task();
}
Пример #3
0
/*! \internal
  \brief Uninitialize a plugin

  In addition to terminating the thread, and removing p from the
  linked list and hashtable, it also frees up p.
   
  \note Should only be called from the context of the registrar thread. */
void kmmint_exit_plugin(kmm_plugin_i * p) {
    int np;
    khm_boolean release_plugin = TRUE;

    if(p->state == KMM_PLUGIN_STATE_RUNNING ||
       p->state == KMM_PLUGIN_STATE_INIT) {

        kmq_post_thread_quit_message(p->tid_thread, 0, NULL);
        /* when we post the quit message to the plugin thread, the plugin
           broker terminates the plugin and posts a EXIT_PLUGIN message,
           which calls this function again.  We just exit here because
           the EXIT_PLUGIN message will end up calling us again momentarily */
        return;

    }

    if(p->ht_thread) {
        /* wait for the thread to terminate */
        WaitForSingleObject(p->ht_thread, INFINITE);
        p->ht_thread = NULL;
    }

    EnterCriticalSection(&cs_kmm);

    /* undo reference count done in kmmint_init_plugin() */
    if(p->flags & KMM_PLUGIN_FLAG_IN_MODCOUNT) {

        np = --(p->module->plugin_count);
        p->flags &= ~KMM_PLUGIN_FLAG_IN_MODCOUNT;

    } else {
        /* the plugin was not included in the module's plugin_count.
           We can't base a decision to unload the module based on this
           plugin exiting. */
        np = TRUE;
    }

    /* The plugin is in an error state.  We need to keep the plugin
       record intact so that the failure information is kept around.
       Also, we shouldn't release the plugin if it appears that
       kmmint_init_plugin() was never called for it. */
    if (p->state < KMM_PLUGIN_STATE_HOLD) {
        release_plugin = FALSE;
    }

    LeaveCriticalSection(&cs_kmm);

    if(!np) {
        /*  if this is the last plugin to exit, then notify the
            registrar that the module should be removed as well */
        kmm_hold_module(kmm_handle_from_module(p->module));
        kmq_post_message(KMSG_KMM, KMSG_KMM_I_REG, KMM_REG_EXIT_MODULE, (void *) p->module);
    }

    /* release the hold obtained in kmmint_init_plugin() */
    if (release_plugin)
        kmm_release_plugin(kmm_handle_from_plugin(p));
}
Пример #4
0
void khm_cred_import(void)
{
    _begin_task(KHERR_CF_TRANSITIVE);
    _report_sr0(KHERR_NONE, IDS_CTX_IMPORT);
    _describe();

    kmq_post_message(KMSG_CRED, KMSG_CRED_IMPORT, 0, 0);

    _end_task();
}
Пример #5
0
KHMEXP khm_int32 KHMAPI
khui_alert_queue(khui_alert * alert)
{
    assert(alert->magic == KHUI_ALERT_MAGIC);

    khui_alert_hold(alert);
    kmq_post_message(KMSG_ALERT, KMSG_ALERT_QUEUE, 0, (void *) alert);

    return KHM_ERROR_SUCCESS;
}
Пример #6
0
void khm_cred_destroy_creds(khm_boolean sync, khm_boolean quiet)
{
    khui_action_context * pctx;

    pctx = PMALLOC(sizeof(*pctx));
#ifdef DEBUG
    assert(pctx);
#endif

    khui_context_get(pctx);

    if(pctx->scope == KHUI_SCOPE_NONE && !quiet) {
        /* this really shouldn't be necessary once we start enabling
           and disbling actions based on context */
        wchar_t title[256];
        wchar_t message[256];

        LoadString(khm_hInstance, 
                   IDS_ALERT_NOSEL_TITLE, 
                   title, 
                   ARRAYLENGTH(title));

        LoadString(khm_hInstance, 
                   IDS_ALERT_NOSEL, 
                   message, 
                   ARRAYLENGTH(message));

        khui_alert_show_simple(title, 
                               message, 
                               KHERR_WARNING);

        khui_context_release(pctx);
        PFREE(pctx);

        return;
    }

    _begin_task(KHERR_CF_TRANSITIVE);
    _report_sr0(KHERR_NONE, IDS_CTX_DESTROY_CREDS);
    _describe();

    if (sync)
        kmq_send_message(KMSG_CRED,
                         KMSG_CRED_DESTROY_CREDS,
                         0,
                         (void *) pctx);
    else
        kmq_post_message(KMSG_CRED,
                         KMSG_CRED_DESTROY_CREDS,
                         0,
                         (void *) pctx);

    _end_task();
}
Пример #7
0
KHMEXP khm_int32 KHMAPI 
khui_alert_show(khui_alert * alert)
{
    assert(alert->magic == KHUI_ALERT_MAGIC);

    khui_alert_hold(alert);
    /* the alert will be released when the message is processed */
    kmq_post_message(KMSG_ALERT, KMSG_ALERT_SHOW, 0, (void *) alert);

    return KHM_ERROR_SUCCESS;
}
Пример #8
0
void
kmmint_check_completion(void) {
    if (pending_modules == 0 &&
        pending_plugins == 0 &&
        InterlockedIncrement(&startup_signal) == 1) {

        load_done = TRUE;

        /* TODO: check for orphaned plugins */

        kmq_post_message(KMSG_KMM, KMSG_KMM_I_DONE, 0, 0);
    }
}
Пример #9
0
KHMEXP khm_int32   KHMAPI 
kmm_unload_module(kmm_module module) {

    if(!kmm_is_module(module))
        return KHM_ERROR_INVALID_PARAM;

    kmm_hold_module(module);
    kmq_post_message(KMSG_KMM, 
		     KMSG_KMM_I_REG, 
		     KMM_REG_EXIT_MODULE, 
		     (void *) kmm_module_from_handle(module));

    return KHM_ERROR_SUCCESS;
}
Пример #10
0
DWORD WINAPI
addr_change_thread(LPVOID dummy) {

    HANDLE h_waits[2];
    HANDLE h_notify;

    OVERLAPPED overlap;
    DWORD ret;

    PDESCTHREAD(L"Address change waiter", L"App");

    ZeroMemory(&overlap, sizeof(overlap));

    h_notify = NULL;
    overlap.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);

    do {
        ret = NotifyAddrChange(&h_notify, &overlap);

        if (ret != ERROR_IO_PENDING) {
            goto _end_thread;   /* some error */
        }

        h_waits[0] = overlap.hEvent;
        h_waits[1] = evt_terminate;

        ret = WaitForMultipleObjects(2, h_waits, FALSE, INFINITE);

        if ( ret == WAIT_OBJECT_0 ) {
            Sleep(3000);        /* wait for things to settle down */
            kmq_post_message(KMSG_CRED, KMSG_CRED_ADDR_CHANGE, 0, 0);
        } else {
            goto _end_thread;
        }
    } while(TRUE);
    
 _end_thread:
    ExitThread(0);
    return 0;                   /* unreachable */
}
Пример #11
0
LRESULT 
khm_statusbar_notify(LPNMHDR nmhdr) {
    LPNMMOUSE pnmm;

    switch(nmhdr->code) {
    case NM_CLICK:
    case NM_DBLCLK:
        pnmm = (LPNMMOUSE) nmhdr;

        if (pnmm->dwItemSpec >= (DWORD) khm_n_statusbar_parts)
            return TRUE;

        if (khm_statusbar_parts[pnmm->dwItemSpec].id == KHUI_SBPART_NOTICE) {
            /* means, show next notification */
            kmq_post_message(KMSG_ALERT, KMSG_ALERT_SHOW_QUEUED, 0, 0);
        }

        return TRUE;
    }

    return FALSE;
}
Пример #12
0
void khm_create_statusbar(HWND parent) {
    HWND hwsb;

    hwsb = CreateWindowEx(
        0,
        STATUSCLASSNAME,
        NULL,
        SBARS_SIZEGRIP | WS_CHILD | WS_VISIBLE,
        0,0,0,0,
        parent,
        NULL,
        khm_hInstance,
        NULL);

    if(!hwsb)
        return;

    khm_hwnd_statusbar = hwsb;

    khui_statusbar_set_parts(parent);

    kmq_post_message(KMSG_ALERT, KMSG_ALERT_CHECK_QUEUE, 0, 0);
}
Пример #13
0
void khm_cred_change_password(wchar_t * title)
{
    khui_new_creds * nc;
    LPNETID_DLGINFO pdlginfo;
    khm_size cb;

    if (!khm_cred_begin_dialog())
        return;

    khui_cw_create_cred_blob(&nc);
    nc->subtype = KMSG_CRED_PASSWORD;
    dialog_nc = nc;

    khui_context_get(&nc->ctx);

    kcdb_identpro_get_ui_cb((void *) &nc->ident_cb);

    assert(nc->ident_cb);

    if (title) {

        if (SUCCEEDED(StringCbLength(title, KHUI_MAXCB_TITLE, &cb))) {
            cb += sizeof(wchar_t);

            nc->window_title = PMALLOC(cb);
#ifdef DEBUG
            assert(nc->window_title);
#endif
            StringCbCopy(nc->window_title, cb, title);
        }
    } else if (nc->ctx.cb_vparam == sizeof(NETID_DLGINFO) &&
               (pdlginfo = nc->ctx.vparam) &&
               pdlginfo->size == NETID_DLGINFO_V1_SZ &&
               pdlginfo->in.title[0] &&
               SUCCEEDED(StringCchLength(pdlginfo->in.title,
                                         NETID_TITLE_SZ,
                                         &cb))) {

        cb = (cb + 1) * sizeof(wchar_t);
        nc->window_title = PMALLOC(cb);
#ifdef DEBUG
        assert(nc->window_title);
#endif
        StringCbCopy(nc->window_title, cb, pdlginfo->in.title);
    }

    khm_create_newcredwnd(khm_hwnd_main, nc);

    if (nc->hwnd != NULL) {
        _begin_task(KHERR_CF_TRANSITIVE);
        _report_sr0(KHERR_NONE, IDS_CTX_PASSWORD);
        _describe();

        kmq_post_message(KMSG_CRED, KMSG_CRED_PASSWORD, 0,
                         (void *) nc);

        _end_task();
    } else {
        khui_cw_destroy_cred_blob(nc);
    }
}
Пример #14
0
LRESULT CALLBACK
khm_main_wnd_proc(HWND hwnd,
                  UINT uMsg,
                  WPARAM wParam,
                  LPARAM lParam)
{
    LPNMHDR lpnm;

    switch(uMsg) {
    case WM_CREATE:
        khm_create_main_window_controls(hwnd);
        kmq_subscribe_hwnd(KMSG_CRED, hwnd);
        kmq_subscribe_hwnd(KMSG_ACT, hwnd);
        kmq_subscribe_hwnd(KMSG_KMM, hwnd);
        mw_restart_refresh_timer(hwnd);

        /* if the plug-ins finished loading before the window was
           created, we would have missed the KMSG_KMM_I_DONE message.
           So we check if the module load is complete and if so, fire
           off KMSG_ACT_BEGIN_CMDLINE. */
        if (!kmm_load_pending())
            kmq_post_message(KMSG_ACT, KMSG_ACT_BEGIN_CMDLINE, 0, 0);
        break;

    case WM_DESTROY:
        khm_pre_shutdown();
        kmq_unsubscribe_hwnd(KMSG_ACT, hwnd);
        kmq_unsubscribe_hwnd(KMSG_CRED, hwnd);
        kmq_unsubscribe_hwnd(KMSG_KMM, hwnd);
        HtmlHelp(NULL, NULL, HH_CLOSE_ALL, 0);
        PostQuitMessage(0);
        break;

    case WM_NOTIFY:
        lpnm = (LPNMHDR) lParam;
        if(lpnm->hwndFrom == khui_main_menu_toolbar) {
            return khm_menu_notify_main(lpnm);
        } else if(lpnm->hwndFrom == khui_hwnd_standard_toolbar) {
            return khm_toolbar_notify(lpnm);
        } else if(lpnm->hwndFrom == khm_hwnd_rebar) {
            return khm_rebar_notify(lpnm);
        } else if(lpnm->hwndFrom == khm_hwnd_statusbar) {
            return khm_statusbar_notify(lpnm);
        }
        break;

    case WM_HELP:
        khm_html_help(khm_hwnd_main, NULL, HH_HELP_CONTEXT, IDH_WELCOME);
        break;

    case WM_COMMAND:
        switch(LOWORD(wParam)) {
            /* general actions */
        case KHUI_ACTION_VIEW_REFRESH:
            khm_cred_refresh();
            InvalidateRect(khm_hwnd_main_cred, NULL, FALSE);
            return 0;

        case KHUI_ACTION_PASSWD_ID:
            if (khm_startup.processing)
                return 0;

            khm_cred_change_password(NULL);
            return 0;

        case KHUI_ACTION_NEW_CRED:
            if (khm_startup.processing)
                return 0;

            khm_cred_obtain_new_creds(NULL);
            return 0;

        case KHUI_ACTION_RENEW_CRED:
            if (khm_startup.processing)
                return 0;

            khm_cred_renew_creds();
            return 0;

        case KHUI_ACTION_DESTROY_CRED:
            if (khm_startup.processing)
                return 0;

            khm_cred_destroy_creds(FALSE, FALSE);
            return 0;

        case KHUI_ACTION_SET_DEF_ID:
            if (khm_startup.processing)
                return 0;

            khm_cred_set_default();
            return 0;

        case KHUI_ACTION_EXIT:
            DestroyWindow(hwnd);
            return 0;

        case KHUI_ACTION_OPEN_APP:
            khm_show_main_window();
            return 0;

        case KHUI_ACTION_CLOSE_APP:
            khm_hide_main_window();
            return 0;

        case KHUI_ACTION_OPT_KHIM: {
            khui_config_node node = NULL;

            khui_cfg_open(NULL, L"KhmGeneral", &node);
            khm_show_config_pane(node);
        }
            return 0;

        case KHUI_ACTION_OPT_IDENTS: {
            khui_config_node node = NULL;

            khui_cfg_open(NULL, L"KhmIdentities", &node);
            khm_show_config_pane(node);
        }
            return 0;

        case KHUI_ACTION_OPT_APPEAR: {
            khui_config_node node = NULL;

            khui_cfg_open(NULL, L"KhmAppear", &node);
            khm_show_config_pane(node);
        }
            return 0;

        case KHUI_ACTION_OPT_NOTIF: {
            khui_config_node node = NULL;

            khui_cfg_open(NULL, L"KhmNotifications", &node);
            khm_show_config_pane(node);
        }
            return 0;

        case KHUI_ACTION_OPT_PLUGINS: {
            khui_config_node node = NULL;

            khui_cfg_open(NULL, L"KhmPlugins", &node);
            khm_show_config_pane(node);
        }
            return 0;

        case KHUI_ACTION_HELP_CTX:
            khm_html_help(khm_hwnd_main, NULL, HH_HELP_CONTEXT, IDH_WELCOME);
            return 0;

        case KHUI_ACTION_HELP_CONTENTS:
            khm_html_help(khm_hwnd_main, NULL, HH_DISPLAY_TOC, 0);
            return 0;

        case KHUI_ACTION_HELP_INDEX:
            khm_html_help(khm_hwnd_main, NULL, HH_DISPLAY_INDEX, (DWORD_PTR) L"");
            return 0;

        case KHUI_ACTION_HELP_ABOUT:
            khm_create_about_window();
            return 0;

        case KHUI_ACTION_IMPORT:
            khm_cred_import();
            return 0;

        case KHUI_ACTION_PROPERTIES:
            /* properties are not handled by the main window.
               Just bounce it to credwnd.  However, use SendMessage
               instead of PostMessage so we don't lose context */
            return SendMessage(khm_hwnd_main_cred, uMsg,
                               wParam, lParam);

        case KHUI_ACTION_UICB:
            khm_ui_cb(lParam);
            return 0;

            /* layout control */

        case KHUI_ACTION_VIEW_ALL_IDS:
            return SendMessage(khm_hwnd_main_cred, uMsg,
                               wParam, lParam);

        case KHUI_ACTION_LAYOUT_MINI:

            if (khm_main_wnd_mode == KHM_MAIN_WND_MINI) {
                khm_set_main_window_mode(KHM_MAIN_WND_NORMAL);
            } else {
                khm_set_main_window_mode(KHM_MAIN_WND_MINI);
            }
            return SendMessage(khm_hwnd_main_cred, uMsg,
                               wParam, lParam);

        case KHUI_ACTION_LAYOUT_RELOAD:
            return SendMessage(khm_hwnd_main_cred, uMsg,
                               wParam, lParam);

        case KHUI_ACTION_LAYOUT_ID:
        case KHUI_ACTION_LAYOUT_TYPE:
        case KHUI_ACTION_LAYOUT_LOC:
        case KHUI_ACTION_LAYOUT_CUST:
            khm_set_main_window_mode(KHM_MAIN_WND_NORMAL);
            return SendMessage(khm_hwnd_main_cred, uMsg,
                               wParam, lParam);

            /* menu commands */
        case KHUI_PACTION_MENU:
            if(HIWORD(lParam) == 1)
                mm_last_hot_item = LOWORD(lParam);
            return khm_menu_activate(MENU_ACTIVATE_DEFAULT);

        case KHUI_PACTION_ESC:
            /* if esc is pressed while no menu is active, we close the
               main window */
            if (mm_last_hot_item == -1) {
                khm_close_main_window();
                return 0;
            }

            /* generic, retargetting */
        case KHUI_PACTION_UP:
        case KHUI_PACTION_UP_TOGGLE:
        case KHUI_PACTION_UP_EXTEND:
        case KHUI_PACTION_PGUP:
        case KHUI_PACTION_PGUP_EXTEND:
        case KHUI_PACTION_DOWN:
        case KHUI_PACTION_DOWN_TOGGLE:
        case KHUI_PACTION_DOWN_EXTEND:
        case KHUI_PACTION_PGDN:
        case KHUI_PACTION_PGDN_EXTEND:
        case KHUI_PACTION_LEFT:
        case KHUI_PACTION_RIGHT:
        case KHUI_PACTION_ENTER:
            /* menu tracking */
            if(mm_last_hot_item != -1) {
                switch(LOWORD(wParam)) {
                case KHUI_PACTION_LEFT:
                    khm_menu_activate(MENU_ACTIVATE_LEFT);
                    break;

                case KHUI_PACTION_RIGHT:
                    khm_menu_activate(MENU_ACTIVATE_RIGHT);
                    break;

                case KHUI_PACTION_ESC:
                case KHUI_PACTION_ENTER:
                    khm_menu_activate(MENU_ACTIVATE_NONE);
                    break;

                case KHUI_PACTION_DOWN:
                    khm_menu_track_current();
                    break;
                }
                return 0;
            }

            /*FALLTHROUGH*/
        case KHUI_PACTION_DELETE:

        case KHUI_PACTION_SELALL:
            /* otherwise fallthrough and bounce to the creds window */
            return SendMessage(khm_hwnd_main_cred, uMsg,
                               wParam, lParam);

        default:
            /* handle custom actions here */
            {
                khui_action * act;

                /* check if this is an identity menu action.  (custom
                   actions that were created for renewing or
                   destroying specific identities). */
                if (khm_check_identity_menu_action(LOWORD(wParam)))
                    break;

                act = khui_find_action(LOWORD(wParam));
                if (act && act->listener) {
                    kmq_post_sub_msg(act->listener, KMSG_ACT, KMSG_ACT_ACTIVATE, act->cmd, NULL);
                    return 0;
                }
            }
        }
        break;              /* WM_COMMAND */

    case WM_SYSCOMMAND:
        switch(wParam & 0xfff0) {
        case SC_MINIMIZE:
            khm_hide_main_window();
            return 0;

        case SC_CLOSE:
            khm_close_main_window();
            return 0;
        }
        break;

    case WM_MEASUREITEM:
        /* sent to measure the bitmaps associated with a menu item */
        if(!wParam) /* sent by menu */
            return khm_menu_measure_item(wParam, lParam);
        break;

    case WM_DRAWITEM:
        /* sent to draw a menu item */
        if(!wParam)
            return khm_menu_draw_item(wParam, lParam);
        break;

    case WM_ERASEBKGND:
        /* Don't erase the background.  The whole client area is
           covered with children.  It doesn't need to be erased */
        return TRUE;
        break;

    case WM_SIZE:
        if(hwnd == khm_hwnd_main &&
           (wParam == SIZE_MAXIMIZED || wParam == SIZE_RESTORED)) {
            int cwidth, cheight;
            RECT r_rebar, r_status;

            cwidth = LOWORD(lParam);
            cheight = HIWORD(lParam);

            /* resize the rebar control */
            SendMessage(khm_hwnd_rebar, WM_SIZE, 0, 0);

            khm_update_statusbar(hwnd);

            GetWindowRect(khm_hwnd_rebar, &r_rebar);
            GetWindowRect(khm_hwnd_statusbar, &r_status);

            /* the cred window fills the area between the rebar
               and the status bar */
            MoveWindow(khm_hwnd_main_cred, 0,
                       r_rebar.bottom - r_rebar.top,
                       r_status.right - r_status.left,
                       r_status.top - r_rebar.bottom, TRUE);

            SetTimer(hwnd,
                     MW_RESIZE_TIMER,
                     MW_RESIZE_TIMEOUT,
                     NULL);
            return 0;
        }
        break;

    case WM_MOVE:
        {
            SetTimer(hwnd,
                     MW_RESIZE_TIMER,
                     MW_RESIZE_TIMEOUT,
                     NULL);

            return 0;
        }
        break;

    case WM_MOVING:
        {
            RECT * r;

            r = (RECT *) lParam;
            khm_adjust_window_dimensions_for_display(r,
                                                     KHM_DOCK_AUTO | KHM_DOCKF_XBORDER);
        }
        return TRUE;

    case WM_TIMER:
        if (wParam == MW_RESIZE_TIMER) {
            main_wnd_save_sizepos();

            return 0;

        } else if (wParam == MW_REFRESH_TIMER) {
            kmq_post_message(KMSG_CRED, KMSG_CRED_REFRESH, 0, 0);

            return 0;

        }
        break;

    case WM_MENUSELECT:
        return khm_menu_handle_select(wParam, lParam);

    case KMQ_WM_DISPATCH:
        {
            kmq_message * m;
            khm_int32 rv = KHM_ERROR_SUCCESS;

            kmq_wm_begin(lParam, &m);
            if (m->type == KMSG_ACT &&
                m->subtype == KMSG_ACT_REFRESH) {
                khm_menu_refresh_items();
                khm_update_standard_toolbar();
            } else if (m->type == KMSG_ACT &&
                       m->subtype == KMSG_ACT_BEGIN_CMDLINE) {
                khm_cred_begin_startup_actions();
            } else if (m->type == KMSG_ACT &&
                       m->subtype == KMSG_ACT_CONTINUE_CMDLINE) {
                khm_cred_process_startup_actions();
            } else if (m->type == KMSG_ACT &&
                       m->subtype == KMSG_ACT_END_CMDLINE) {
                /* nothing yet */
            } else if (m->type == KMSG_ACT &&
                       m->subtype == KMSG_ACT_SYNC_CFG) {
                khm_refresh_config();
            } else if (m->type == KMSG_ACT &&
                       m->subtype == KMSG_ACT_ACTIVATE) {
                /* some custom action fired */

                khm_int32 action;
                khui_action * paction;

                action = m->uparam;
                paction = khui_find_action(action);
                if (paction && paction->data == (void *) CFGACTION_MAGIC) {
                    /* a custom configuration needs to be invoked */
                    khui_config_node node;

                    if (KHM_SUCCEEDED(khui_cfg_open(NULL, paction->name, &node))) {
                        khm_show_config_pane(node);
                        khui_cfg_release(node);
                    }
                }
            } else if (m->type == KMSG_CRED &&
                  m->subtype == KMSG_CRED_REFRESH) {
                mw_restart_refresh_timer(hwnd);
            } else if (m->type == KMSG_CRED &&
                       m->subtype == KMSG_CRED_ADDR_CHANGE) {
                khm_cred_addr_change();
            } else if (m->type == KMSG_CRED &&
                       m->subtype == KMSG_CRED_ROOTDELTA) {
                khm_refresh_identity_menus();
            } else if (m->type == KMSG_KMM &&
                       m->subtype == KMSG_KMM_I_DONE) {
                kmq_post_message(KMSG_ACT, KMSG_ACT_BEGIN_CMDLINE, 0, 0);
            }

            return kmq_wm_end(m, rv);
        }

    case WM_KHUI_ASSIGN_COMMANDLINE_V1:
        {
            HANDLE hmap;
            void * xfer;
            wchar_t mapname[256];
            khm_startup_options_v1 * pv1opt;
            int code = KHM_ERROR_SUCCESS;

            StringCbPrintf(mapname, sizeof(mapname),
                           COMMANDLINE_MAP_FMT, (DWORD) lParam);

            hmap = OpenFileMapping(FILE_MAP_READ, FALSE, mapname);

            if (hmap == NULL)
                return 1;

            xfer = MapViewOfFile(hmap, FILE_MAP_READ, 0, 0,
                                 sizeof(*pv1opt));

            if (xfer) {
                pv1opt = (khm_startup_options_v1 *) xfer;

                khm_startup.init = pv1opt->init;
                khm_startup.import = pv1opt->import;
                khm_startup.renew = pv1opt->renew;
                khm_startup.destroy = pv1opt->destroy;

                khm_startup.autoinit = pv1opt->autoinit;
                khm_startup.error_exit = FALSE;

                khm_startup.no_main_window = FALSE;
                khm_startup.remote_exit = FALSE;
                khm_startup.display = 0;

                UnmapViewOfFile(xfer);
            } else {
                code = KHM_ERROR_NOT_FOUND;
            }

            CloseHandle(hmap);

            if(InSendMessage())
                ReplyMessage(code);

            if (code == KHM_ERROR_SUCCESS) {
                khm_startup.exit = FALSE;

                khm_startup.seen = FALSE;
                khm_startup.remote = TRUE;
#ifdef DEBUG
                assert(!khm_startup.processing);
#endif
                khm_startup.processing = FALSE;

                khm_cred_begin_startup_actions();
            }

            return code;
        }

    case WM_KHUI_ASSIGN_COMMANDLINE_V2:
        {
            HANDLE hmap;
            void * xfer;
            wchar_t mapname[256];
            khm_startup_options_v2 *pv2opt = NULL;
            khm_startup_options_v3 *pv3opt = NULL;
            int code = KHM_ERROR_SUCCESS;

            StringCbPrintf(mapname, sizeof(mapname),
                           COMMANDLINE_MAP_FMT, (DWORD) lParam);

            hmap = OpenFileMapping(FILE_MAP_WRITE, FALSE, mapname);

            if (hmap == NULL)
                return 1;

            xfer = MapViewOfFile(hmap, FILE_MAP_WRITE, 0, 0,
                                 sizeof(*pv2opt));

            if (xfer) {
                pv2opt = (khm_startup_options_v2 *) xfer;

                if (pv2opt->magic != STARTUP_OPTIONS_MAGIC ||
                    (pv2opt->cb_size != sizeof(*pv2opt) &&
                     pv2opt->cb_size != sizeof(*pv3opt))) {
                    code = KHM_ERROR_INVALID_PARAM;
                    goto done_with_v2_opt;
                }

                khm_startup.init = pv2opt->init;
                khm_startup.import = pv2opt->import;
                khm_startup.renew = pv2opt->renew;
                khm_startup.destroy = pv2opt->destroy;

                khm_startup.autoinit = pv2opt->autoinit;
                khm_startup.exit = pv2opt->remote_exit;

                pv2opt->code = KHM_ERROR_SUCCESS;

                if (pv2opt->cb_size == sizeof(*pv3opt)) {
                    pv3opt = (khm_startup_options_v3 *) xfer;

                    khm_startup.display = pv3opt->remote_display;
                } else {
                    khm_startup.display = 0;
                }

            done_with_v2_opt:
                UnmapViewOfFile(xfer);
            } else {
                code = KHM_ERROR_NOT_FOUND;
            }

            CloseHandle(hmap);

            if(InSendMessage())
                ReplyMessage(code);

            if (code == KHM_ERROR_SUCCESS) {
                khm_startup.seen = FALSE;
                khm_startup.remote = TRUE;
#ifdef DEBUG
                assert(!khm_startup.processing);
#endif
                khm_startup.processing = FALSE;

                khm_cred_begin_startup_actions();
            }

            return code;
        }

    case WM_KHUI_QUERY_APP_VERSION:
        {
            HANDLE hmap;
            void * xfer;
            wchar_t mapname[256];

            StringCbPrintf(mapname, sizeof(mapname),
                           QUERY_APP_VER_MAP_FMT, (DWORD) lParam);

            hmap = OpenFileMapping(FILE_MAP_READ | FILE_MAP_WRITE,
                                   FALSE, mapname);

            if (hmap == NULL)
                return 1;

            xfer = MapViewOfFile(hmap, FILE_MAP_WRITE, 0, 0,
                                 sizeof(khm_query_app_version));

            if (xfer) {
                khm_process_query_app_ver((khm_query_app_version *) xfer);

                UnmapViewOfFile(xfer);
            }

            CloseHandle(hmap);
        }
        return 0;

    }
    return DefWindowProc(hwnd,uMsg,wParam,lParam);
}
Пример #15
0
void 
khm_cred_dispatch_process_message(khui_new_creds *nc)
{
    khm_size i;
    BOOL pending;
    wchar_t wsinsert[512];
    khm_size cbsize;

    /* see if there's anything to do.  We can check this without
       obtaining a lock */
    if(nc->n_types == 0 ||
       (nc->subtype == KMSG_CRED_NEW_CREDS &&
        nc->n_identities == 0) ||
       (nc->subtype == KMSG_CRED_PASSWORD &&
        nc->n_identities == 0))
        goto _terminate_job;

    /* check dependencies and stuff first */
    EnterCriticalSection(&nc->cs);
    for(i=0; i<nc->n_types; i++) {
        nc->types[i]->flags &= ~ KHUI_NCT_FLAG_PROCESSED;
    }
    LeaveCriticalSection(&nc->cs);

    /* Consindering all that can go wrong here and the desire to
       handle errors here separately from others, we create a new task
       for the purpose of tracking the credentials acquisition
       process. */
    _begin_task(KHERR_CF_TRANSITIVE);

    /* Describe the context */
    if(nc->subtype == KMSG_CRED_NEW_CREDS) {
        cbsize = sizeof(wsinsert);
        kcdb_identity_get_name(nc->identities[0], wsinsert, &cbsize);

        _report_sr1(KHERR_NONE,  IDS_CTX_PROC_NEW_CREDS,
                    _cstr(wsinsert));
        _resolve();
    } else if (nc->subtype == KMSG_CRED_RENEW_CREDS) {
        cbsize = sizeof(wsinsert);

        if (nc->ctx.scope == KHUI_SCOPE_IDENT)
            kcdb_identity_get_name(nc->ctx.identity, wsinsert, &cbsize);
        else if (nc->ctx.scope == KHUI_SCOPE_CREDTYPE) {
            if (nc->ctx.identity != NULL)
                kcdb_identity_get_name(nc->ctx.identity, wsinsert, 
                                       &cbsize);
            else
                kcdb_credtype_get_name(nc->ctx.cred_type, wsinsert,
                                       &cbsize);
        } else if (nc->ctx.scope == KHUI_SCOPE_CRED) {
            kcdb_cred_get_name(nc->ctx.cred, wsinsert, &cbsize);
        } else {
            StringCbCopy(wsinsert, sizeof(wsinsert), L"(?)");
        }

        _report_sr1(KHERR_NONE, IDS_CTX_PROC_RENEW_CREDS, 
                    _cstr(wsinsert));
        _resolve();
    } else if (nc->subtype == KMSG_CRED_PASSWORD) {
        cbsize = sizeof(wsinsert);
        kcdb_identity_get_name(nc->identities[0], wsinsert, &cbsize);

        _report_sr1(KHERR_NONE, IDS_CTX_PROC_PASSWORD,
                    _cstr(wsinsert));
        _resolve();
    } else {
        assert(FALSE);
    }

    _describe();

    pending = khm_cred_dispatch_process_level(nc);

    _end_task();

    if(!pending)
        goto _terminate_job;

    return;

 _terminate_job:
    if (nc->subtype == KMSG_CRED_RENEW_CREDS)
        kmq_post_message(KMSG_CRED, KMSG_CRED_END, 0, (void *) nc);
    else
        PostMessage(nc->hwnd, KHUI_WM_NC_NOTIFY, 
                    MAKEWPARAM(0, WMNC_DIALOG_PROCESS_COMPLETE), 0);
}
Пример #16
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);
}
Пример #17
0
KHMEXP khm_int32   KHMAPI kmm_load_module(wchar_t * modname, 
                                          khm_int32 flags, 
                                          kmm_module * result)
{
    kmm_module_i * m = NULL;
    kmm_module_i * mi;
    size_t cbsize;
    khm_int32 rv = KHM_ERROR_SUCCESS;

    if(FAILED(StringCbLength(modname, KMM_MAXCB_NAME, &cbsize)))
        return KHM_ERROR_INVALID_PARAM;
    cbsize += sizeof(wchar_t);

    EnterCriticalSection(&cs_kmm);
    mi = kmmint_find_module_i(modname);

    if(mi != NULL) {
        kmm_hold_module(kmm_handle_from_module(mi));
        /* check if the module has either failed to load either or if
        it has been terminated.  If so, we try once again to load the
        module. */
        if(!(flags & KMM_LM_FLAG_NOLOAD) && 
            (mi->state < 0 || mi->state == KMM_MODULE_STATE_EXITED)) 
        {
            mi->state = KMM_MODULE_STATE_PREINIT;
        }
    }
    LeaveCriticalSection(&cs_kmm);

    if(flags & KMM_LM_FLAG_NOLOAD) {
        if(result)
            *result = mi;
        else if(mi)
            kmm_release_module(kmm_handle_from_module(mi));

        return (mi)? KHM_ERROR_SUCCESS: KHM_ERROR_NOT_FOUND;
    }

    if(mi) {
        m = mi;
    } else {
        m = kmmint_get_module_i(modname);
        m->state = KMM_MODULE_STATE_PREINIT;
        kmm_hold_module(kmm_handle_from_module(m));
    }

    /* the module is already running or is already being
       worked on by the registrar */
    if(m->state != KMM_MODULE_STATE_PREINIT) {
        if(result)
            *result = kmm_handle_from_module(m);
        else
            kmm_release_module(kmm_handle_from_module(m));

        return KHM_ERROR_EXISTS;
    }

    kmmint_add_to_module_queue();

    if(flags & KMM_LM_FLAG_SYNC) {
        kmm_hold_module(kmm_handle_from_module(m));
        kmq_send_message(KMSG_KMM, 
                         KMSG_KMM_I_REG, 
                         KMM_REG_INIT_MODULE, 
                         (void*) m);
        if(m->state <= 0) {
            /* failed to load ? */
            if(m->state == KMM_MODULE_STATE_FAIL_NOT_FOUND)
                rv = KHM_ERROR_NOT_FOUND;
            else if(m->state == KMM_MODULE_STATE_FAIL_SIGNATURE)
                rv = KHM_ERROR_INVALID_SIGNATURE;
            else
                rv = KHM_ERROR_UNKNOWN;

            kmm_release_module(kmm_handle_from_module(m));
            if(result)
                *result = NULL;
        } else {
            if(result)
                *result = kmm_handle_from_module(m);
            else
                kmm_release_module(kmm_handle_from_module(m));
        }
    } else {
        kmm_hold_module(kmm_handle_from_module(m));
        kmq_post_message(KMSG_KMM, 
                         KMSG_KMM_I_REG, 
                         KMM_REG_INIT_MODULE, 
                         (void*) m);
        if(result)
            *result = kmm_handle_from_module(m);
        else
            kmm_release_module(kmm_handle_from_module(m));
    }

    return rv;
}
Пример #18
0
/*! \internal

  Collect credentials from cs_src to cs_dest which have already been
  selected into cl_dest and cl_src.

  - Credentials in cl_src that are not in cl_dest will get added to
    cs_dest

  - Credentials in cl_dest that are not in cl_src will get removed
    from cs_dest

  - Credentials in cl_dest and cl_src will be updated in cs_dest

  cl_dest and cl_src will be modified.
*/
khm_int32
kcdb_credset_collect_core(kcdb_credset * cs_dest,
                          kcdb_cred ** cl_dest,
                          khm_int32 ncl_dest,
                          kcdb_credset * cs_src,
                          kcdb_cred ** cl_src,
                          khm_int32 ncl_src,
                          khm_int32 * delta)
{
    int i, j;
    int ldelta = 0;
    khm_int32 rv;
    khm_boolean dest_is_root;
    khm_handle last_identity = NULL;

    dest_is_root = (cs_dest == kcdb_root_credset);

    /* find matching credentials and update them */
    for (i=0; i < ncl_dest; i++) {
        if (cl_dest[i]) {
            for (j=0; j < ncl_src; j++) {
                if (cl_src[j] &&
                    kcdb_creds_is_equal((khm_handle) cl_dest[i], (khm_handle) cl_src[j])) {

                    /* depending on whether any changes were made,
                       update ldelta with the proper bit flag */

                    rv = kcdb_cred_update(cl_dest[i], cl_src[j]);
                    if (rv == KHM_ERROR_SUCCESS) {
                        kcdb_credset_update_cred_ref((khm_handle) cs_dest,
                                                     (khm_handle) cl_dest[i]);
                        ldelta |= KCDB_DELTA_MODIFY;

                        if (dest_is_root)
                            check_and_set_refresh_bit_for_identity(cl_dest[i],
                                                                   &last_identity);
                    }

                    cl_src[j] = NULL;
                    cl_dest[i] = NULL;
                    break;
                }
            }
        }
    }

    /* all the creds that are left in cl_dest need to be removed */
    for (i=0; i < ncl_dest; i++) {
        if (cl_dest[i]) {
            if (dest_is_root)
                check_and_set_refresh_bit_for_identity(cl_dest[i],
                                                       &last_identity);

            kcdb_credset_del_cred_ref((khm_handle) cs_dest, (khm_handle) cl_dest[i]);
            ldelta |= KCDB_DELTA_DEL;

            cl_dest[i] = NULL;
        }
    }

    /* all the creds in cl_src need to be added to cs_dest */
    for (j=0; j < ncl_src; j++) {
        if (cl_src[j]) {
            /* duplicate the credential and add it if we are adding it
               to or from the root credential store. */
            if (cs_dest == kcdb_root_credset ||
                cs_src == kcdb_root_credset) {
                khm_handle h;

                if (KHM_SUCCEEDED(kcdb_cred_dup((khm_handle) cl_src[j], &h))) {
                    kcdb_credset_add_cred((khm_handle) cs_dest, h, -1);
                    kcdb_cred_release(h);
                }
            } else {
                kcdb_credset_add_cred((khm_handle) cs_dest, cl_src[j], -1);
            }

            if (dest_is_root)
                check_and_set_refresh_bit_for_identity(cl_src[j],
                                                       &last_identity);
            cl_src[j] = NULL;
            ldelta |= KCDB_DELTA_ADD;
        }
    }

    if (last_identity) {
        kcdb_identity_release(last_identity);
        last_identity = NULL;
    }

    if (delta)
        *delta = ldelta;

    if (dest_is_root && ldelta) {
        /* something changed in the root credential set */
        kmq_post_message(KMSG_CRED,KMSG_CRED_ROOTDELTA,ldelta,NULL);
    }
    return KHM_ERROR_SUCCESS;
}
Пример #19
0
/*! \internal
  \brief Uninitializes a module

  \note Should only be called from the context of the registrar
  thread */
void kmmint_exit_module(kmm_module_i * m) {
    kmm_plugin_i * p;

    /*  Exiting a module happens in two stages.  

        If the module state is running (there are active plugins) then
        those plugins must be exited.  This has to be done from the
        plugin threads.  The signal for the plugins to exit must be
        issued from the registrar.  Therefore, we post messages to the
        registrar for each plugin we want to remove and exit
        kmmint_exit_module().

        When the last plugin is exited, the plugin management code
        automatically signalls the registrar to remove the module.
        kmmint_exit_module() gets called again.  This is the second
        stage, where we call exit_module() for the module and start
        unloading everything.
    */

    EnterCriticalSection(&cs_kmm);

    /* get rid of any dangling uninitialized plugins */
    LPOP(&(m->plugins), &p);
    while(p) {
        p->flags &= ~KMM_PLUGIN_FLAG_IN_MODLIST;
        kmmint_exit_plugin(p);

        /* release hold from kmm_provide_plugin() */
        kmm_release_plugin(kmm_handle_from_plugin(p));

        LPOP(&(m->plugins), &p);
    }

    if(m->state == KMM_MODULE_STATE_RUNNING) {
        int np = 0;

        m->state = KMM_MODULE_STATE_EXITPLUG;

        p = kmm_listed_plugins;

        while(p) {
            if(p->module == m &&
               (p->flags & KMM_PLUGIN_FLAG_IN_MODCOUNT)) {

                kmm_hold_plugin(kmm_handle_from_plugin(p));
                kmq_post_message(KMSG_KMM, KMSG_KMM_I_REG, 
                                 KMM_REG_EXIT_PLUGIN, (void *) p);
                np++;

            }

            p = LNEXT(p);
        }

#ifdef DEBUG
        assert(np == m->plugin_count);
#endif

        if(np > 0) {
            /*  we have to go back and wait for the plugins to exit.
                when the last plugin exits, it automatically posts
                EXIT_MODULE. We can pick up from there when this
                happens. */
            LeaveCriticalSection(&cs_kmm);
            return;
        }

    } else {

#ifdef DEBUG
        assert(m->plugin_count == 0 ||
               m->state == KMM_MODULE_STATE_EXITPLUG);
#endif

        /* if there are still plug-ins waiting to be unloaded, then we
           have to go back and wait for them to finish.  Once they are
           done, kmmint_exit_module() will get called again. */
        if (m->plugin_count > 0) {
            LeaveCriticalSection(&cs_kmm);
            return;
        }
    }

    if(m->flags & KMM_MODULE_FLAG_INITP) {
        exit_module_t p_exit_module;

        if(m->state > 0)
            m->state = KMM_MODULE_STATE_EXIT;

        p_exit_module = 
            (exit_module_t) GetProcAddress(m->h_module, 
                                           EXP_EXIT_MODULE);
        if(p_exit_module) {
            LeaveCriticalSection(&cs_kmm);
            (*p_exit_module)(kmm_handle_from_module(m));
            EnterCriticalSection(&cs_kmm);
        }
    }

    if(m->state > 0)
        m->state = KMM_MODULE_STATE_EXITED;

    LeaveCriticalSection(&cs_kmm);

    if(!(m->flags & KMM_MODULE_FLAG_NOUNLOAD) &&
       m->h_module) {
        FreeLibrary(m->h_module);
    }

    if(!(m->flags & KMM_MODULE_FLAG_NOUNLOAD) &&
       m->h_resource && (m->h_resource != m->h_module)) {
        FreeLibrary(m->h_resource);
    }

    m->h_module = NULL;
    m->h_resource = NULL;

    if (m->flags & KMM_MODULE_FLAG_LOADED) {
#ifdef DEBUG
        assert(kmm_active_modules > 0);
#endif
        kmm_active_modules--;
    }

    m->flags = 0;

    /* release the hold obtained in kmmint_init_module() */
    kmm_release_module(kmm_handle_from_module(m));

    /* Last but not least, now see if there are any modules left that
       are running. If not, we can safely signal an exit. */
    if (kmm_active_modules == 0) {
        SetEvent(evt_exit);
    }
}
Пример #20
0
void
khm_cred_refresh(void) {
    kmq_post_message(KMSG_CRED, KMSG_CRED_REFRESH, 0, NULL);
}
Пример #21
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;
    }
}
Пример #22
0
void kcdb_credtype_post_message(khm_int32 op, kcdb_credtype * type)
{
    kcdb_credtype_hold((kcdb_credtype_i *) type);
    kmq_post_message(KMSG_KCDB, KMSG_KCDB_CREDTYPE, op, (void *) type);
}
Пример #23
0
KHMEXP khm_int32 KHMAPI
khui_cfg_register(khui_config_node vparent,
                  const khui_config_node_reg * reg) {

    size_t cb_name;
    size_t cb_short_desc;
    size_t cb_long_desc;
    khui_config_node_i * node;
    khui_config_node_i * parent;
    khui_config_node t;
    wchar_t * name;
    wchar_t * short_desc;
    wchar_t * long_desc;

    cfgui_init_once();

    if (!reg ||
        FAILED(StringCbLength(reg->name,
                              KHUI_MAXCB_NAME,
                              &cb_name)) ||
        FAILED(StringCbLength(reg->short_desc,
                              KHUI_MAXCB_SHORT_DESC,
                              &cb_short_desc)) ||
        FAILED(StringCbLength(reg->long_desc,
                              KHUI_MAXCB_LONG_DESC,
                              &cb_long_desc)) ||
        (vparent &&
         !cfgui_is_valid_node_handle(vparent)))
        return KHM_ERROR_INVALID_PARAM;

    if (KHM_SUCCEEDED(khui_cfg_open(vparent,
                                  reg->name,
                                  &t))) {
        khui_cfg_release(t);
        return KHM_ERROR_DUPLICATE;
    }

    cb_name += sizeof(wchar_t);
    cb_short_desc += sizeof(wchar_t);
    cb_long_desc += sizeof(wchar_t);

    node = cfgui_create_new_node();

    node->reg = *reg;
    node->reg.flags &= KHUI_CNFLAGMASK_STATIC;

    name = PMALLOC(cb_name);
    StringCbCopy(name, cb_name, reg->name);
    short_desc = PMALLOC(cb_short_desc);
    StringCbCopy(short_desc, cb_short_desc, reg->short_desc);
    long_desc = PMALLOC(cb_long_desc);
    StringCbCopy(long_desc, cb_long_desc, reg->long_desc);

    node->reg.name = name;
    node->reg.short_desc = short_desc;
    node->reg.long_desc = long_desc;
    node->flags = node->reg.flags;

    if (vparent == NULL) {
        parent = cfgui_root_config;
    } else {
        parent = cfgui_node_i_from_handle(vparent);
    }

    /* plugin handles should not be obtained lightly.  For the moment,
       the cleanup of nodes doesn't happen until module unload and
       module unload doesn't happen until all the plugin and module
       handles have been freed. */
    /* node->owner = kmm_this_plugin(); */

    EnterCriticalSection(&cs_cfgui);
    TADDCHILD(parent, node);

    if (hwnd_cfgui) {
        SendMessage(hwnd_cfgui, KHUI_WM_CFG_NOTIFY,
                    MAKEWPARAM(0, WMCFG_SYNC_NODE_LIST), 0);
    }

    LeaveCriticalSection(&cs_cfgui);

    /* when the root config list changes, we need to notify the UI.
       this way, the Options menu can be kept in sync. */
    if (parent == cfgui_root_config) {
        kmq_post_message(KMSG_ACT, KMSG_ACT_SYNC_CFG, 0, 0);
    }

    return KHM_ERROR_SUCCESS;
}
Пример #24
0
void kcdb_type_post_message(khm_int32 op, kcdb_type_i * t)
{
    kcdb_type_hold(t);
    kmq_post_message(KMSG_KCDB, KMSG_KCDB_TYPE, op, (void *) t);
}
Пример #25
0
void khm_cred_obtain_new_creds(wchar_t * title)
{
    khui_new_creds * nc;
    LPNETID_DLGINFO pdlginfo;
    khm_size cb;

    if (!khm_cred_begin_dialog())
        return;

    khui_cw_create_cred_blob(&nc);
    nc->subtype = KMSG_CRED_NEW_CREDS;
    dialog_nc = nc;

    khui_context_get(&nc->ctx);

    kcdb_identpro_get_ui_cb((void *) &nc->ident_cb);

    if (nc->ident_cb == NULL) {
        wchar_t title[256];
        wchar_t msg[512];
        wchar_t suggestion[512];
        khui_alert * a;

        LoadString(khm_hInstance, IDS_ERR_TITLE_NO_IDENTPRO,
                   title, ARRAYLENGTH(title));
        LoadString(khm_hInstance, IDS_ERR_MSG_NO_IDENTPRO,
                   msg, ARRAYLENGTH(msg));
        LoadString(khm_hInstance, IDS_ERR_SUGG_NO_IDENTPRO,
                   suggestion, ARRAYLENGTH(suggestion));

        khui_alert_create_simple(title,
                                 msg,
                                 KHERR_ERROR,
                                 &a);
        khui_alert_set_suggestion(a, suggestion);

        khui_alert_show(a);

        khui_alert_release(a);

        khui_context_release(&nc->ctx);
        nc->result = KHUI_NC_RESULT_CANCEL;
        khm_cred_end_dialog(nc);
        khui_cw_destroy_cred_blob(nc);
        return;
    }

    if (title) {
        if (SUCCEEDED(StringCbLength(title, KHUI_MAXCB_TITLE, &cb))) {
            cb += sizeof(wchar_t);

            nc->window_title = PMALLOC(cb);
#ifdef DEBUG
            assert(nc->window_title);
#endif
            StringCbCopy(nc->window_title, cb, title);
        }
    } else if (nc->ctx.cb_vparam == sizeof(NETID_DLGINFO) &&
               (pdlginfo = nc->ctx.vparam) &&
               pdlginfo->size == NETID_DLGINFO_V1_SZ &&
               pdlginfo->in.title[0] &&
               SUCCEEDED(StringCchLength(pdlginfo->in.title,
                                         NETID_TITLE_SZ,
                                         &cb))) {

        cb = (cb + 1) * sizeof(wchar_t);
        nc->window_title = PMALLOC(cb);
#ifdef DEBUG
        assert(nc->window_title);
#endif
        StringCbCopy(nc->window_title, cb, pdlginfo->in.title);
    }

    khm_create_newcredwnd(khm_hwnd_main, nc);

    if (nc->hwnd != NULL) {
        _begin_task(KHERR_CF_TRANSITIVE);
        _report_sr0(KHERR_NONE, IDS_CTX_NEW_CREDS);
        _describe();

        kmq_post_message(KMSG_CRED, KMSG_CRED_NEW_CREDS, 0, 
                         (void *) nc);

        _end_task();
    } else {
        khui_context_release(&nc->ctx);
        nc->result = KHUI_NC_RESULT_CANCEL;
        khm_cred_end_dialog(nc);
        khui_cw_destroy_cred_blob(nc);
    }
}
Пример #26
0
/*! \internal

Collect credentials from cs2 to cs1 which have already been selected into
cl1 and cl2.

- Credentials in cl2 that are not in cl1 will get added to cs1
- Credentials in cl1 that are not in cl2 will get removed from cs1
- Credentials in cl1 and cl2 will be updated in cs1

cl1 and cl2 will be modified.
*/
khm_int32 
kcdb_credset_collect_core(kcdb_credset * cs1,
                          kcdb_cred ** cl1,
                          khm_int32 ncl1,
                          kcdb_credset * cs2,
                          kcdb_cred ** cl2,
                          khm_int32 ncl2,
                          khm_int32 * delta)
{
    int i, j;
    int ldelta = 0;
    khm_int32 rv;

    /* find matching creds and update them */
    for(i=0; i<ncl1; i++) 
        if(cl1[i]) {
            for(j=0; j<ncl2; j++) 
                if(cl2[j] && kcdb_creds_is_equal((khm_handle) cl1[i], (khm_handle) cl2[j])) {
                    /* they are equivalent. make them equal */

                    /* depending on whether any changes were made,
                        update ldelta with the proper bit flag */

                    rv = kcdb_cred_update(cl1[i], cl2[j]);
                    if (rv == KHM_ERROR_SUCCESS) {
                        kcdb_credset_update_cred_ref((khm_handle) cs1, (khm_handle) cl1[i]);
                        ldelta |= KCDB_DELTA_MODIFY;
                    }

                    cl2[j] = NULL;
                    cl1[i] = NULL;
                    break;
                }
        }

    /* all the creds that are left in cl1 need to be removed */
    for(i=0; i<ncl1; i++)
        if(cl1[i]) {
            kcdb_credset_del_cred_ref((khm_handle) cs1, (khm_handle) cl1[i]);
            cl1[i] = NULL;
            ldelta |= KCDB_DELTA_DEL;
        }

    /* all the creds in cl2 need to be added to cs1 */
    for(j=0; j<ncl2; j++)
        if(cl2[j]) {
            /* duplicate the credential and add it if we are adding it to the
               root credential store. */
            if(cs1 == kcdb_root_credset) {
                khm_handle h;

                if(KHM_SUCCEEDED(kcdb_cred_dup((khm_handle) cl2[j], &h))) {
                    kcdb_credset_add_cred((khm_handle) cs1, h, -1);
                    kcdb_cred_release(h);
                }
            } else
                kcdb_credset_add_cred((khm_handle) cs1, cl2[j], -1);
            cl2[j] = NULL;
            ldelta |= KCDB_DELTA_ADD;
        }

    if(delta)
        *delta = ldelta;

    if((cs1 == kcdb_root_credset) && ldelta) {
        /* something changed in the root credential set */
        kmq_post_message(KMSG_CRED,KMSG_CRED_ROOTDELTA,ldelta,NULL);
    }
    return KHM_ERROR_SUCCESS;
}
Пример #27
0
/*! \internal
  \brief Manages a plugin message thread.

  Each plugin gets its own plugin thread which is used to dispatch
  messages to the plugin.  This acts as the thread function for the
  plugin thread.*/
DWORD WINAPI kmmint_plugin_broker(LPVOID lpParameter)
{
    DWORD rv = 0;
    kmm_plugin_i * p = (kmm_plugin_i *) lpParameter;

    PDESCTHREAD(p->p.name, L"KMM");

    _begin_task(0);
    _report_mr1(KHERR_NONE, MSG_PB_START, _cstr(p->p.name));
    _describe();

    TlsSetValue(tls_kmm, (LPVOID) p);

    kmm_hold_plugin(kmm_handle_from_plugin(p));

    p->tid_thread = GetCurrentThreadId();

    if (IsBadCodePtr(p->p.msg_proc)) {
        _report_mr0(KHERR_WARNING, MSG_PB_INVALID_CODE_PTR);
        rv = KHM_ERROR_INVALID_PARAM;
    } else {
        rv = (*p->p.msg_proc)(KMSG_SYSTEM, KMSG_SYSTEM_INIT, 
                              0, (void *) &(p->p));
        _report_mr1(KHERR_INFO, MSG_PB_INIT_RV, _int32(rv));
    }

    /* if it fails to initialize, we exit the plugin */
    if(KHM_FAILED(rv)) {

        kherr_report(KHERR_ERROR,
                     (wchar_t *) MSG_PB_INIT_FAIL_S,
                     (wchar_t *) KHERR_FACILITY,
                     NULL,
                     (wchar_t *) MSG_PB_INIT_FAIL,
                     (wchar_t *) MSG_PB_INIT_FAIL_G,
                     KHERR_FACILITY_ID,
                     KHERR_SUGGEST_NONE,
                     _cstr(p->p.name),
                     _cstr(p->p.description),
                     _cstr(p->module->path),
                     _cstr(p->module->support),
                     KHERR_RF_MSG_SHORT_DESC |
                     KHERR_RF_MSG_LONG_DESC |
                     KHERR_RF_MSG_SUGGEST
#ifdef _WIN32
                     ,KHERR_HMODULE
#endif
                     );
        _resolve();

        /* exit the plugin first.  Otherwise it may not uninitialize correctly */
        (*p->p.msg_proc)(KMSG_SYSTEM, KMSG_SYSTEM_EXIT, 0, (void *) &(p->p));

        kmmint_remove_from_plugin_queue(p);
        rv = 1;
        _end_task();

        p->state = KMM_PLUGIN_STATE_FAIL_INIT;
        goto _exit;
    }

    /* subscribe to default message classes by plugin type */
    if(p->p.type == KHM_PITYPE_CRED) {
        kmq_subscribe(KMSG_SYSTEM, p->p.msg_proc);
        kmq_subscribe(KMSG_KCDB, p->p.msg_proc);
        kmq_subscribe(KMSG_CRED, p->p.msg_proc);
    } else if(p->p.type == KHM_PITYPE_IDENT) {
        khm_handle h = NULL;

        kmq_subscribe(KMSG_SYSTEM, p->p.msg_proc);
        kmq_subscribe(KMSG_KCDB, p->p.msg_proc);

        kmq_create_subscription(p->p.msg_proc, &h);
        kcdb_identity_set_provider(h);
        /* kcdb deletes the subscription when it's done with it */
    } else if(p->p.type == KHM_PITYPE_CONFIG) {
        /*TODO: subscribe to configuration provider messages here */
    }

    p->state = KMM_PLUGIN_STATE_RUNNING;

    _report_mr0(KHERR_INFO, MSG_PB_INIT_DONE);

    _end_task();

    /* if there were any plugins that were waiting for this one to
       start, we should start them too */
    EnterCriticalSection(&cs_kmm);
    do {
        kmm_plugin_i * pd;
        int i;

        for(i=0; i < p->n_dependants; i++) {
            pd = p->dependants[i];

            pd->n_unresolved--;

            if(pd->n_unresolved == 0) {
                kmmint_add_to_plugin_queue(pd);
                kmm_hold_plugin(kmm_handle_from_plugin(pd));
                kmq_post_message(KMSG_KMM, KMSG_KMM_I_REG, KMM_REG_INIT_PLUGIN, (void *) pd);
            }
        }
    } while(FALSE);
    LeaveCriticalSection(&cs_kmm);

    kmmint_remove_from_plugin_queue(p);

    /* main message loop */
    while(KHM_SUCCEEDED(kmq_dispatch(INFINITE)));

    /* unsubscribe from default message classes by plugin type */
    if(p->p.type == KHM_PITYPE_CRED) {
        kmq_unsubscribe(KMSG_SYSTEM, p->p.msg_proc);
        kmq_unsubscribe(KMSG_KCDB, p->p.msg_proc);
        kmq_unsubscribe(KMSG_CRED, p->p.msg_proc);
    } else if (p->p.type == KHM_PITYPE_IDENT) {
        kmq_unsubscribe(KMSG_KCDB, p->p.msg_proc);
        kmq_unsubscribe(KMSG_SYSTEM, p->p.msg_proc);
        kcdb_identity_set_provider(NULL);
    } else if(p->p.type == KHM_PITYPE_CONFIG) {
        /*TODO: unsubscribe from configuration provider messages here */
    }

    p->p.msg_proc(KMSG_SYSTEM, KMSG_SYSTEM_EXIT, 0, (void *) &(p->p));

 _exit:
    if (p->state >= 0)
        p->state = KMM_PLUGIN_STATE_EXITED;

    /* the following call will automatically release the plugin */
    kmq_post_message(KMSG_KMM, KMSG_KMM_I_REG, 
                     KMM_REG_EXIT_PLUGIN, (void *) p);

    TlsSetValue(tls_kmm, (LPVOID) 0);

    ExitThread(rv);

    /* not reached */
    return rv;
}
Пример #28
0
/*! \internal
  \brief Initialize a plugin

  \note If kmmint_init_plugin() is called on a plugin, then kmmint_exit_plugin()
      \b must be called for the plugin.

  \note Should only be called from the context of the registrar thread */
void kmmint_init_plugin(kmm_plugin_i * p) {
    DWORD dummy;
    khm_handle csp_plugin   = NULL;
    khm_handle csp_plugins  = NULL;
    khm_int32 t;

    /* the following will be undone in kmmint_exit_plugin() */
    kmm_hold_plugin(kmm_handle_from_plugin(p));

    EnterCriticalSection(&cs_kmm);
    if(p->state != KMM_PLUGIN_STATE_REG &&
        p->state != KMM_PLUGIN_STATE_HOLD)
    {
        LeaveCriticalSection(&cs_kmm);
        goto _exit;
    }

    _begin_task(0);
    _report_mr1(KHERR_NONE, MSG_IP_TASK_DESC, _cstr(p->p.name));
    _describe();

    if(p->state == KMM_PLUGIN_STATE_HOLD) {
        /* if this plugin was held, then we already had a hold
           from the initial attempt to start the plugin.  Undo
           the hold we did a few lines earlier. */
        kmm_release_plugin(kmm_handle_from_plugin(p));

        /* same for the plugin count for the module. */
#ifdef DEBUG
        assert(p->flags & KMM_PLUGIN_FLAG_IN_MODCOUNT);
#endif
        p->module->plugin_count--;
        p->flags &= ~KMM_PLUGIN_FLAG_IN_MODCOUNT;
    }

    p->state = KMM_PLUGIN_STATE_PREINIT;

    kmmint_delist_plugin(p);
    kmmint_list_plugin(p);

    LeaveCriticalSection(&cs_kmm);

    if(KHM_FAILED(kmm_get_plugins_config(0, &csp_plugins))) {
        _report_mr0(KHERR_ERROR, MSG_IP_GET_CONFIG);

        p->state = KMM_PLUGIN_STATE_FAIL_UNKNOWN;
        goto _exit;
    }

    if(KHM_FAILED(kmm_get_plugin_config(p->p.name, 0, &csp_plugin))) {
        if(KHM_FAILED(kmm_register_plugin(&(p->p), 0))) {
            _report_mr0(KHERR_ERROR, MSG_IP_NOT_REGISTERED);

            p->state = KMM_PLUGIN_STATE_FAIL_NOT_REGISTERED;
            goto _exit;
        }
        
        if(KHM_FAILED(kmm_get_plugin_config(p->p.name, 0, &csp_plugin))) {
            _report_mr0(KHERR_ERROR, MSG_IP_NOT_REGISTERED);

            p->state = KMM_PLUGIN_STATE_FAIL_NOT_REGISTERED;
            goto _exit;
        }
    }

    if (KHM_SUCCEEDED(khc_read_int32(csp_plugin, L"Disabled", &t)) && t) {
        p->flags |= KMM_PLUGIN_FLAG_DISABLED;
        p->state = KMM_PLUGIN_STATE_FAIL_DISABLED;
        goto _exit;
    }

#if 0
    /*TODO: check the failure count and act accordingly */
    if(KHM_SUCCEEDED(khc_read_int32(csp_plugin, L"FailureCount", &t)) && (t > 0)) {
    }
#endif

    EnterCriticalSection(&cs_kmm);

    p->n_depends = 0;
    p->n_unresolved = 0;
    
    do {
        wchar_t * deps = NULL;
        wchar_t * d;
        khm_size sz = 0;

        if(khc_read_multi_string(csp_plugin, L"Dependencies", 
                                 NULL, &sz) != KHM_ERROR_TOO_LONG)
            break;

        deps = PMALLOC(sz);
        if(KHM_FAILED(khc_read_multi_string(csp_plugin, L"Dependencies", 
                                            deps, &sz))) {
            if(deps)
                PFREE(deps);
            break;
        }

        for(d = deps; d && *d; d = multi_string_next(d)) {
            kmm_plugin_i * pd;
            int i;

            pd = kmmint_get_plugin_i(d);

            if(pd->state == KMM_PLUGIN_STATE_NONE) {
                /* the dependant was not previously known */
                pd->state = KMM_PLUGIN_STATE_PLACEHOLDER;
            }

            for(i=0; i < pd->n_dependants; i++) {
                if(pd->dependants[i] == p)
                    break;
            }

            if(i >= pd->n_dependants) {
                if( pd->n_dependants >= KMM_MAX_DEPENDANTS ) {
                    /*TODO: handle this gracefully */
                    RaiseException(1, EXCEPTION_NONCONTINUABLE, 0, NULL);
                }

                /* released in kmmint_free_plugin() */
                kmm_hold_plugin(kmm_handle_from_plugin(p));
                pd->dependants[pd->n_dependants] = p;
                pd->n_dependants++;
            }

            p->n_depends++;

            if(pd->state != KMM_PLUGIN_STATE_RUNNING) {
                p->n_unresolved++;
            }
        }

        if(p->n_unresolved > 0) {
            p->state = KMM_PLUGIN_STATE_HOLD;
        }

        PFREE(deps);

    } while(FALSE);

#ifdef DEBUG
    assert(!(p->flags & KMM_PLUGIN_FLAG_IN_MODCOUNT));
#endif
    p->flags |= KMM_PLUGIN_FLAG_IN_MODCOUNT;
    p->module->plugin_count++;

    LeaveCriticalSection(&cs_kmm);

    if(p->state == KMM_PLUGIN_STATE_HOLD) {
        _report_mr1(KHERR_INFO, MSG_IP_HOLD, _dupstr(p->p.name));

        goto _exit_post;
    }

    kmmint_add_to_plugin_queue(p);

    p->ht_thread = CreateThread(NULL,
                                0,
                                kmmint_plugin_broker,
                                (LPVOID) p,
                                CREATE_SUSPENDED,
                                &dummy);

    p->state = KMM_PLUGIN_STATE_INIT;

    ResumeThread(p->ht_thread);

_exit_post:
    if(csp_plugin != NULL)
        khc_close_space(csp_plugin);

    if(csp_plugins != NULL)
        khc_close_space(csp_plugins);

    _report_mr2(KHERR_INFO, MSG_IP_STATE, 
                _dupstr(p->p.name), _int32(p->state));

    _end_task();
    
    return;

    /* jump here if an error condition happens before the plugin
       broker thread starts and the plugin should be unloaded */

_exit:
    if(csp_plugin != NULL)
        khc_close_space(csp_plugin);
    if(csp_plugins != NULL)
        khc_close_space(csp_plugins);

    _report_mr2(KHERR_WARNING, MSG_IP_EXITING, 
                _dupstr(p->p.name), _int32(p->state));
    _end_task();


#ifdef ASYNC_PLUGIN_UNLOAD_ON_FAILURE

    kmm_hold_plugin(kmm_handle_from_plugin(p));

    kmq_post_message(KMSG_KMM, KMSG_KMM_I_REG, KMM_REG_EXIT_PLUGIN, (void *) p);

#else

    kmmint_exit_plugin(p);

#endif
}
Пример #29
0
void
kcdbint_identpro_post_message(khm_int32 op, kcdb_identpro_i * p) {
    identpro_hold(p);
    kmq_post_message(KMSG_KCDB, KMSG_KCDB_IDENTPRO, op, (void *) p);
}