summaryrefslogtreecommitdiffstats
path: root/src/windows/identity/doc/plugin_framework.h
blob: cfe40e458c6be5d90555f5a748edb63ff4eb4cd2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
/*
 * Copyright (c) 2005 Massachusetts Institute of Technology
 * Copyright (c) 2007 Secure Endpoints Inc.
 *
 * Permission is hereby granted, free of charge, to any person
 * obtaining a copy of this software and associated documentation
 * files (the "Software"), to deal in the Software without
 * restriction, including without limitation the rights to use, copy,
 * modify, merge, publish, distribute, sublicense, and/or sell copies
 * of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

/* $Id$ */

/*!
\page pi_framework Plug-in Framework

\section pi_fw_pnm Introduction to Plug-ins, Modules and Messages

\subsection pi_fw_pnm_p Plug-ins

A plug-in is a package that implements a defined API that will perform
credentials management or related tasks on behalf of Network Identity
Manager.

The Network Identity Manager architecture is message based.  The core
of each plug-in is a message handler.  The plug-in integrates with the
application by subscribing to, and handling specific types of
messages.

The plug-in message handler runs in its own thread and receive
asynchronous messages.  There are exceptions, such as when one plug-in
requires another plug-in to handle a specific message before it can
handle the message.  In addition, during certain operations that
require user interaction, each plug-in can delegate code that will run
in the main application thread (the user interface thread) to process
window messages.

\subsection pi_fw_pnw_m Modules

One or more plug-ins can be bundled together into a module.  A module
is a dynamically loadable library which exports a specific set of
callbacks.  Currently, the only two required callbacks for a module
are :

- init_module(), and
- exit_module()

For more information about how a module is structured, see \ref
pi_structure .

\subsection pi_fw_pnm_msg Messages and Message Queues

An integral part of this framework is the messaging system.  Most of
the communication between the Network Identity Manager application and
plug-ins is conducted through passing messages.

A message has a type and subtype and is denoted in this documentation
as \< \e message_type, \e message_subtype\>.  For example, when a
plug-in is loaded, the first message it receives is \< ::KMSG_SYSTEM,
::KMSG_SYSTEM_INIT \>.

Each thread in the application, specially threads that were created
for individual plug-in messages handlers, has an associated message
queue that stores and manages all the messages that have been sent to
subscribers in that thread.

The most common recipient of a message is a message callback function
(see ::kmq_callback_t ). The message handler for a plug-in is one such
example. A message callback function receives the message type,
subtype and two optional parameters for the message.

Any acceptable recipient can subscribe to broadcast messages of any
type.  Once subscribed, whenever a message of that type is broadcast,
the message will get queued on the corresponding message queue.  Then,
one of the dispatch functions can dispatch the message to the correct
callback function. (see ::kmq_dispatch).

Next \subpage pi_fw_pm ...

*/

/*!

\page pi_fw_pm Module Manager

The Module Manager is tasked with loading and unloading modules as
well as managing the plug-in message processing.

When a module is successfully loaded, it registers one or more
plug-ins.  The Module Manager creates a new thread for each of these
plug-ins.  Then the initialization message to the plug-in is sent and
the message dispatch loop is started in this new thread.  Having each
plug-in in a separate thread prevents one plug-in from "hanging" other
plug-ins and the user interface.

\note For compatibility with future versions of Network Identity
Manager, a plug-in should not depend on the fact that it is running in
its own thread.

Read more :
- \ref pi_structure

\section pi_fw_pm_load Module Load Sequence

When kmm_load_module() is called to load a specific module, the
following sequence of events occur:

<ul>

 <li>
  The registration information for the module is located on the
  registry key \c
  \\Software\\MIT\\NetIDMgr\\PluginManager\\Modules\\[ModuleName]. \see
  \ref config
 </li>

 <li> The module will not be loaded if one of the following conditions are
  true:

  <ul>
   <li>
    The \c Disabled value is defined and non-zero.
   </li>

   <li>
    The \c FailureCount value is defined and exceeds the maximum
    failure count.  By default, the maximum failure count is three,
    although it can be set by adding the registry value \c
    ModuleMaxFailureCount in registry key \c
    Software\\MIT\\NetIDMgr\\PluginManager\\Modules .
   </li>
  </ul>
 </li>

 <li>
  The \c ImagePath value from the registration information is used to
  locate the module binary.  If it is not an absolute path, then the
  binary is located using the standard system search path starting
  from the directory in which Network Identity Manager binaries are
  located.
 </li>

 <li>
  The binary is loaded into the address space of Network Identity
  Manager along with any dependencies not already loaded.
 </li>

 <li>
  If the Network Identity Manager core binary is signed, then the
  signature is checked against the system and user certificate stores.
  If this fails, the module is unloaded. See \ref pi_fw_pm_unload.
 </li>

 <li>
  The init_module() entry point for the loaded module is called.  If
  this function returns an error or if no plug-ins are registered,
  then the module is immediately unloaded. See \ref pi_fw_pm_unload.

  <ul>
   <li>
    During processing of init_module(), if any localized resource
    libraries are specified using kmm_set_locale_info(), then one of the
    localized libraries will be loaded. See \ref pi_localization
   </li>

   <li> 
    During processing of init_module(), the module registers all the
    plug-ins that it is implementing by calling kmm_provide_plugin()
    for each.
   </li>
  </ul>
 </li>

 <li>
  Once init_module() returns, each plug-in is initialized.  The method
  by which a plug-in is initialized depends on the plug-in type.  The
  initialization code for the plug-in may indicate that it didn't
  initialize properly, in which case the plug-in is immediately
  unregistered.  No further calls are made to the plug-in.
 </li>

 <li>
  If no plug-in is successfully loaded, the module is unloaded. See
  \ref pi_fw_pm_unload.
 </li>
</ul>

  During normal operation, any registered plug-ins for a module can be
  unloaded explicitly, or the plug-in itself may signal that it should
  be unloaded.  If at anytime, all the plug-ins for the module are
  unloaded, then the module itself is also unloaded unless the \c
  NoUnload registry value is set in the module key.

\section pi_fw_pm_unload Unload sequence

<ul>
 <li>
  For each of the plug-ins that are registered for a module, the exit
  code is invoked.  The method by which this happens depends on the
  plug-in type.  The plug-in is not given a chance to veto the
  decision to unload. Each plug-in is responsible for performing
  cleanup tasks, freeing resources and unsubscribing from any message
  classes that it has subscribed to.
 </li>

 <li>
  Once all the plug-ins have been unloaded, the exit_module() entry
  point is called for the module.
 </li>

 <li>
  If any localized resource libraries were loaded for the module, they
  are unloaded.
 </li>

 <li>
  The module is unloaded.
 </li>
</ul>

The following diagram illustrates the relationship between modules and
plug-ins as implemented in the Kerberos 5 plug-in distributed with
Network Identity Manager.

\image html modules_plugins_krb5.png

 */