summaryrefslogtreecommitdiffstats
path: root/libapol/include/apol/infoflow-analysis.h
blob: 61b00a9fe9d99b47f7092734713226d2cc8429bd (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
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
/**
 * @file
 *
 * Routines to perform an information flow analysis, both direct and
 * transitive flows.
 *
 * @author Jeremy A. Mowery jmowery@tresys.com
 * @author Jason Tang  jtang@tresys.com
 *
 * Copyright (C) 2003-2007 Tresys Technology, LLC
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License as published by the Free Software Foundation; either
 *  version 2.1 of the License, or (at your option) any later version.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 */

#ifndef APOL_INFOFLOW_ANALYSIS_H
#define APOL_INFOFLOW_ANALYSIS_H

#ifdef	__cplusplus
extern "C"
{
#endif

#include "policy.h"
#include "vector.h"
#include <qpol/policy.h>

/*
 * Information flows can be either direct (A -> B) or transitive (A ->
 * {stuff} -> B).
 */
#define APOL_INFOFLOW_MODE_DIRECT  0x01
#define APOL_INFOFLOW_MODE_TRANS   0x02

/*
 * All operations are mapped in either an information flow in or an
 * information flow out (using the permission map).  These defines are
 * for the two flow directions plus flows in both or either direction
 * for queries and query results.
 */
#define APOL_INFOFLOW_IN      0x01
#define APOL_INFOFLOW_OUT     0x02
#define APOL_INFOFLOW_BOTH    (APOL_INFOFLOW_IN|APOL_INFOFLOW_OUT)
#define APOL_INFOFLOW_EITHER  0x04

	typedef struct apol_infoflow_graph apol_infoflow_graph_t;
	typedef struct apol_infoflow_analysis apol_infoflow_analysis_t;
	typedef struct apol_infoflow_result apol_infoflow_result_t;
	typedef struct apol_infoflow_step apol_infoflow_step_t;

/**
 * Deallocate all space associated with a particular information flow
 * graph, including the pointer itself.  Afterwards set the pointer to
 * NULL.
 *
 * @param g Reference to an apol_infoflow_graph_t to destroy.
 */
	extern void apol_infoflow_graph_destroy(apol_infoflow_graph_t ** g);

/********** functions to do information flow analysis **********/

/**
 * Execute an information flow analysis against a particular policy.
 * The policy must have had a permission map loaded via
 * apol_policy_open_permmap(), else this analysis will abort
 * immediately.
 *
 * @param p Policy within which to look up allow rules.
 * @param ia A non-NULL structure containing parameters for analysis.
 * @param v Reference to a vector of apol_infoflow_result_t.  The
 * vector will be allocated by this function.  The caller must call
 * apol_vector_destroy() afterwards.  This will be set to NULL upon
 * error.
 * @param g Reference to the information flow graph constructed for
 * the given infoflow analysis object.  The graph will be allocated by
 * this function; the caller is responsible for calling
 * apol_infoflow_graph_destroy() afterwards.  This will be set to NULL
 * upon error.
 *
 * @return 0 on success, negative on error.
 */
	extern int apol_infoflow_analysis_do(const apol_policy_t * p,
					     const apol_infoflow_analysis_t * ia, apol_vector_t ** v, apol_infoflow_graph_t ** g);

/**
 * Execute an information flow analysis against a particular policy
 * and a pre-built information flow graph.  The analysis will keep the
 * same criteria that were used to build the graph, sans differing
 * starting type.
 *
 * @param p Policy within which to look up allow rules.
 * @param g Existing information flow graph to analyze.
 * @param type New string from which to begin analysis.
 * @param v Reference to a vector of apol_infoflow_result_t.  The
 * vector will be allocated by this function.  The caller must call
 * apol_vector_destroy() afterwards.  This will be set to NULL upon no
 * results or upon error.
 *
 * @return 0 on success, negative on error.
 */
	extern int apol_infoflow_analysis_do_more(const apol_policy_t * p, apol_infoflow_graph_t * g, const char *type,
						  apol_vector_t ** v);

/**
 * Prepare an existing transitive infoflow graph to do further
 * searches upon two specific start and end types.  The analysis is by
 * way of a BFS with random restarts; thus each call to
 * apol_infoflow_analysis_trans_further_next() may possibly return
 * additional paths.  This function is needed to prepare the pool of
 * initial states for the search.
 *
 * @param p Policy from which infoflow rules derived.
 * @param g Existing transitive infoflow graph.  If it was already
 * prepared then those values will be first destroyed.
 * @param start_type String from which to begin further analysis.
 * @param end_type String for target infoflow paths.
 *
 * @return 0 on success, < 0 on error.
 */
	extern int apol_infoflow_analysis_trans_further_prepare(const apol_policy_t * p,
								apol_infoflow_graph_t * g, const char *start_type,
								const char *end_type);

/**
 * Find further transitive infoflow paths by way of a random restart.
 * The infoflow graph must be first prepared by first calling
 * apol_infoflow_analysis_trans_further_prepare().  This function will
 * append to vector v any new results it finds.
 *
 * @param p Policy from which infoflow rules derived.
 * @param g Prepared transitive infoflow graph.
 * @param v Pointer to a vector of existing apol_infoflow_result_t
 * pointers.  If this functions finds additional unique results it
 * will append them to this vector.  If the pointer is NULL then this
 * will allocate and return a new vector.  It is the caller's
 * responsibility to call apol_vector_destroy() afterwards.
 *
 * @return 0 on success, < 0 on error.
 */
	extern int apol_infoflow_analysis_trans_further_next(const apol_policy_t * p, apol_infoflow_graph_t * g,
							     apol_vector_t ** v);

/********** functions to create/modify an analysis object **********/

/**
 * Allocate and return a new information analysis structure.  All
 * fields are cleared; one must fill in the details of the analysis
 * before running it.  The caller must call
 * apol_infoflow_analysis_destroy() upon the return value afterwards.
 *
 * @return An initialized information flow analysis structure, or NULL
 * upon error.
 */
	extern apol_infoflow_analysis_t *apol_infoflow_analysis_create(void);

/**
 * Deallocate all memory associated with the referenced information
 * flow analysis, and then set it to NULL.  This function does nothing
 * if the analysis is already NULL.
 *
 * @param ia Reference to an infoflow analysis structure to destroy.
 */
	extern void apol_infoflow_analysis_destroy(apol_infoflow_analysis_t ** ia);

/**
 * Set an information flow analysis mode to be either direct or
 * transitive.  This must be one of the values
 * APOL_INFOFLOW_MODE_DIRECT, or APOL_INFOFLOW_MODE_TRANS.  This
 * function must be called prior to running the analysis.
 *
 * @param p Policy handler, to report errors.
 * @param ia Infoflow analysis to set.
 * @param mode Analysis mode, either direct or transitive.
 *
 * @return 0 on success, negative on error.
 */
	extern int apol_infoflow_analysis_set_mode(const apol_policy_t * p, apol_infoflow_analysis_t * ia, unsigned int mode);

/**
 * Set an information flow analysis to search in a specific direction.
 * For direct infoflow analysis this must be one of the values
 * APOL_INFOFLOW_IN, APOL_INFOFLOW_OUT, APOL_INFOFLOW_BOTH, or
 * APOL_INFOFLOW_EITHER; transitive infoflow only permits the first
 * two.  This function must be called prior to running the analysis.
 *
 * @param p Policy handler, to report errors.
 * @param ia Infoflow analysis to set.
 * @param dir Direction to analyze, using one of the defines above.
 *
 * @return 0 on success, negative on error.
 */
	extern int apol_infoflow_analysis_set_dir(const apol_policy_t * p, apol_infoflow_analysis_t * ia, unsigned int dir);

/**
 * Set an information flow analysis to begin searching using a given
 * type.  This function must be called prior to running the analysis.
 *
 * @param p Policy handler, to report errors.
 * @param ia Infoflow anlysis to set.
 * @param name Begin searching types with this non-NULL name.
 *
 * @return 0 on success, negative on error.
 */
	extern int apol_infoflow_analysis_set_type(const apol_policy_t * p, apol_infoflow_analysis_t * ia, const char *name);

/**
 * Set an information flow analysis to return paths that only go
 * through this intermediate type.  If more than one type is appended
 * to the analysis, every step of a return path will go through at
 * least one of the types.  These intermediate types are ignored when
 * running a direct information flow analysis.
 *
 * @param policy Policy handler, to report errors.
 * @param ia Infoflow analysis to set.
 * @param type Intermediate type which a result must flow through.  If
 * NULL, then clear all existing intermediate types.  (All paths will
 * be returned.)
 * @return 0 on success, negative on error.
 */
	extern int apol_infoflow_analysis_append_intermediate(const apol_policy_t * p, apol_infoflow_analysis_t * ia,
							      const char *type);

/**
 * Set an information flow analysis to return only rules with this
 * object (non-common) class and permission.  If more than one
 * class/perm pair is appended to the query, every rule's class and
 * permissions must be one of those appended.  (I.e., the rule will be
 * a member of the analysis's class/perm pairs.)
 *
 * @param policy Policy handler, to report errors.
 * @param ia Infoflow analysis to set.
 * @param class_name The class to which a result must have access.  If
 * NULL, then accept all class/perm pairs.
 * @param perm_name The permission which a result must have for the
 * given class.  This may be NULL if class_name is also NULL.
 * @return 0 on success, negative on error.
 */
	extern int apol_infoflow_analysis_append_class_perm(const apol_policy_t * p,
							    apol_infoflow_analysis_t * ia, const char *class_name,
							    const char *perm_name);

/**
 * Set an information flow analysis to return only rules with at least
 * one permission whose weight is greater than or equal to the given
 * minimum.  Permission weights are retrieved from the currently
 * loaded permission map.  If the given minimum exceeds
 * APOL_PERMMAP_MAX_WEIGHT it will be clamped to that value.
 *
 * @param policy Policy handler, to report errors.
 * @param ia Infoflow analysis to set.
 * @param min_weight Minimum weight for rules, or negative to accept
 * all rules.
 * @return Always 0.
 */
	extern int apol_infoflow_analysis_set_min_weight(const apol_policy_t * p, apol_infoflow_analysis_t * ia, int min_weight);

/**
 * Set an information flow analysis to return only types matching a
 * regular expression.  Note that the regexp will also match types'
 * aliases.
 *
 * @param p Policy handler, to report errors.
 * @param ia Information flow anlysis to set.
 * @param result Only return types matching this regular expression, or
 * NULL to return all types
 *
 * @return 0 on success, negative on error.
 */
	extern int apol_infoflow_analysis_set_result_regex(const apol_policy_t * p, apol_infoflow_analysis_t * ia,
							   const char *result);

/*************** functions to access infoflow results ***************/

/**
 * Return the direction of an information flow result.  This will be
 * one of APOL_INFOFLOW_IN, APOL_INFOFLOW_OUT, or APOL_INFOFLOW_BOTH.
 *
 * @param result Infoflow result from which to get direction.
 * @return Direction of result or zero on error.
 */
	extern unsigned int apol_infoflow_result_get_dir(const apol_infoflow_result_t * result);

/**
 * Return the start type of an information flow result.  The caller
 * should not free the returned pointer.
 *
 * @param result Infoflow result from which to get start type.
 * @return Pointer to the start type of the infoflow or NULL on error.
 */
	extern const qpol_type_t *apol_infoflow_result_get_start_type(const apol_infoflow_result_t * result);

/**
 * Return the end type of an information flow result.  The caller
 * should not free the returned pointer.
 *
 * @param result Infoflow result from which to get end type.
 * @return Pointer to the end type of the infoflow or NULL on error.
 */
	extern const qpol_type_t *apol_infoflow_result_get_end_type(const apol_infoflow_result_t * result);

/**
 * Return the length of an information flow result.  This represents
 * how easily information flows from the start to end type, where
 * lower numbers are easier than higher numbers.  This is dependent
 * upon the weights assigned in the currently loaded permission map.
 *
 * @param result Infoflow result from which to get length.
 * @return Length of result or zero on error.
 */
	extern unsigned int apol_infoflow_result_get_length(const apol_infoflow_result_t * result);

/**
 * Return the vector of infoflow steps for a particular information
 * flow result.  This is a vector of apol_infoflow_step_t pointers.
 * The caller <b>should not</b> call apol_vector_destroy() upon the
 * returned vector.  Note that for a direct infoflow analysis this
 * vector will consist of exactly one step; for transitive analysis
 * the vector will have multiple steps.
 *
 * @param result Infoflow result from which to get steps.
 *
 * @return Pointer to a vector of steps found between the result's
 * start and end types or NULL on error.
 */
	extern const apol_vector_t *apol_infoflow_result_get_steps(const apol_infoflow_result_t * result);

/**
 * Return the starting type for an information flow step.  The caller
 * should not free the returned pointer.
 *
 * @param step Infoflow step from which to get start type.
 * @return Pointer to the start type for this infoflow step or NULL on error.
 */
	extern const qpol_type_t *apol_infoflow_step_get_start_type(const apol_infoflow_step_t * step);

/**
 * Return the ending type for an information flow step.  The caller
 * should not free the returned pointer.
 *
 * @param step Infoflow step from which to get end type.
 * @return Pointer to the start type for this infoflow step or NULL on error.
 */
	extern const qpol_type_t *apol_infoflow_step_get_end_type(const apol_infoflow_step_t * step);

/**
 * Return the weight of an information flow step.  For a direct
 * infoflow analysis the weight is zero.  For a transitive
 * analysis this is an integer value that quantatizes the amount of
 * information that could flow between the start and end types; it is
 * based upon the currently opened permission map.  It will be a value
 * between APOL_PERMMAP_MIN_WEIGHT and APOL_PERMMAP_MAX_WEIGHT,
 * inclusive.
 *
 * @param step Infoflow step from which to get weight.
 * @return Weight of step or < 0 on error.
 */
	extern int apol_infoflow_step_get_weight(const apol_infoflow_step_t * step);

/**
 * Return the vector of access rules for a particular information
 * step.  This is a vector of qpol_avrule_t pointers.  The caller
 * <b>should not</b> call apol_vector_destroy() upon the returned
 * vector.
 *
 * @param step Infoflow flow step from which to get rules.
 *
 * @return Pointer to a vector of rules relative to the policy originally
 * used to generate the results or NULL on error.
 */
	extern const apol_vector_t *apol_infoflow_step_get_rules(const apol_infoflow_step_t * step);

#ifdef	__cplusplus
}
#endif

#endif