1*2d543d20SAndroid Build Coastguard Worker /* Workaround for http://bugs.python.org/issue4835 */
2*2d543d20SAndroid Build Coastguard Worker #ifndef SIZEOF_SOCKET_T
3*2d543d20SAndroid Build Coastguard Worker #define SIZEOF_SOCKET_T SIZEOF_INT
4*2d543d20SAndroid Build Coastguard Worker #endif
5*2d543d20SAndroid Build Coastguard Worker
6*2d543d20SAndroid Build Coastguard Worker #include <Python.h>
7*2d543d20SAndroid Build Coastguard Worker #include <unistd.h>
8*2d543d20SAndroid Build Coastguard Worker #include <stdlib.h>
9*2d543d20SAndroid Build Coastguard Worker #include <ctype.h>
10*2d543d20SAndroid Build Coastguard Worker #include <errno.h>
11*2d543d20SAndroid Build Coastguard Worker #include <getopt.h>
12*2d543d20SAndroid Build Coastguard Worker #include <limits.h>
13*2d543d20SAndroid Build Coastguard Worker #include <sepol/sepol.h>
14*2d543d20SAndroid Build Coastguard Worker #include <sepol/policydb.h>
15*2d543d20SAndroid Build Coastguard Worker #include <sepol/policydb/services.h>
16*2d543d20SAndroid Build Coastguard Worker #include <selinux/selinux.h>
17*2d543d20SAndroid Build Coastguard Worker
18*2d543d20SAndroid Build Coastguard Worker #define UNKNOWN -1
19*2d543d20SAndroid Build Coastguard Worker #define BADSCON -2
20*2d543d20SAndroid Build Coastguard Worker #define BADTCON -3
21*2d543d20SAndroid Build Coastguard Worker #define BADTCLASS -4
22*2d543d20SAndroid Build Coastguard Worker #define BADPERM -5
23*2d543d20SAndroid Build Coastguard Worker #define BADCOMPUTE -6
24*2d543d20SAndroid Build Coastguard Worker #define NOPOLICY -7
25*2d543d20SAndroid Build Coastguard Worker #define ALLOW 0
26*2d543d20SAndroid Build Coastguard Worker #define DONTAUDIT 1
27*2d543d20SAndroid Build Coastguard Worker #define TERULE 2
28*2d543d20SAndroid Build Coastguard Worker #define BOOLEAN 3
29*2d543d20SAndroid Build Coastguard Worker #define CONSTRAINT 4
30*2d543d20SAndroid Build Coastguard Worker #define RBAC 5
31*2d543d20SAndroid Build Coastguard Worker #define BOUNDS 6
32*2d543d20SAndroid Build Coastguard Worker
33*2d543d20SAndroid Build Coastguard Worker struct boolean_t {
34*2d543d20SAndroid Build Coastguard Worker char *name;
35*2d543d20SAndroid Build Coastguard Worker int active;
36*2d543d20SAndroid Build Coastguard Worker };
37*2d543d20SAndroid Build Coastguard Worker
38*2d543d20SAndroid Build Coastguard Worker static struct boolean_t **boollist = NULL;
39*2d543d20SAndroid Build Coastguard Worker static int boolcnt = 0;
40*2d543d20SAndroid Build Coastguard Worker
41*2d543d20SAndroid Build Coastguard Worker struct avc_t {
42*2d543d20SAndroid Build Coastguard Worker sepol_handle_t *handle;
43*2d543d20SAndroid Build Coastguard Worker sepol_policydb_t *policydb;
44*2d543d20SAndroid Build Coastguard Worker sepol_security_id_t ssid;
45*2d543d20SAndroid Build Coastguard Worker sepol_security_id_t tsid;
46*2d543d20SAndroid Build Coastguard Worker sepol_security_class_t tclass;
47*2d543d20SAndroid Build Coastguard Worker sepol_access_vector_t av;
48*2d543d20SAndroid Build Coastguard Worker };
49*2d543d20SAndroid Build Coastguard Worker
50*2d543d20SAndroid Build Coastguard Worker static struct avc_t *avc = NULL;
51*2d543d20SAndroid Build Coastguard Worker
52*2d543d20SAndroid Build Coastguard Worker static sidtab_t sidtab;
53*2d543d20SAndroid Build Coastguard Worker
load_booleans(const sepol_bool_t * boolean,void * arg)54*2d543d20SAndroid Build Coastguard Worker static int load_booleans(const sepol_bool_t * boolean,
55*2d543d20SAndroid Build Coastguard Worker void *arg __attribute__ ((__unused__)))
56*2d543d20SAndroid Build Coastguard Worker {
57*2d543d20SAndroid Build Coastguard Worker boollist[boolcnt] = malloc(sizeof(struct boolean_t));
58*2d543d20SAndroid Build Coastguard Worker boollist[boolcnt]->name = strdup(sepol_bool_get_name(boolean));
59*2d543d20SAndroid Build Coastguard Worker boollist[boolcnt]->active = sepol_bool_get_value(boolean);
60*2d543d20SAndroid Build Coastguard Worker boolcnt++;
61*2d543d20SAndroid Build Coastguard Worker return 0;
62*2d543d20SAndroid Build Coastguard Worker }
63*2d543d20SAndroid Build Coastguard Worker
check_booleans(struct boolean_t ** bools)64*2d543d20SAndroid Build Coastguard Worker static int check_booleans(struct boolean_t **bools)
65*2d543d20SAndroid Build Coastguard Worker {
66*2d543d20SAndroid Build Coastguard Worker char errormsg[PATH_MAX];
67*2d543d20SAndroid Build Coastguard Worker struct sepol_av_decision avd;
68*2d543d20SAndroid Build Coastguard Worker unsigned int reason;
69*2d543d20SAndroid Build Coastguard Worker int rc;
70*2d543d20SAndroid Build Coastguard Worker int i;
71*2d543d20SAndroid Build Coastguard Worker sepol_bool_key_t *key = NULL;
72*2d543d20SAndroid Build Coastguard Worker sepol_bool_t *boolean = NULL;
73*2d543d20SAndroid Build Coastguard Worker int fcnt = 0;
74*2d543d20SAndroid Build Coastguard Worker int *foundlist = calloc(boolcnt, sizeof(int));
75*2d543d20SAndroid Build Coastguard Worker if (!foundlist) {
76*2d543d20SAndroid Build Coastguard Worker PyErr_SetString( PyExc_MemoryError, "Out of memory\n");
77*2d543d20SAndroid Build Coastguard Worker return fcnt;
78*2d543d20SAndroid Build Coastguard Worker }
79*2d543d20SAndroid Build Coastguard Worker for (i = 0; i < boolcnt; i++) {
80*2d543d20SAndroid Build Coastguard Worker char *name = boollist[i]->name;
81*2d543d20SAndroid Build Coastguard Worker int active = boollist[i]->active;
82*2d543d20SAndroid Build Coastguard Worker rc = sepol_bool_key_create(avc->handle, name, &key);
83*2d543d20SAndroid Build Coastguard Worker if (rc < 0) {
84*2d543d20SAndroid Build Coastguard Worker PyErr_SetString( PyExc_RuntimeError,
85*2d543d20SAndroid Build Coastguard Worker "Could not create boolean key.\n");
86*2d543d20SAndroid Build Coastguard Worker break;
87*2d543d20SAndroid Build Coastguard Worker }
88*2d543d20SAndroid Build Coastguard Worker rc = sepol_bool_query(avc->handle,
89*2d543d20SAndroid Build Coastguard Worker avc->policydb,
90*2d543d20SAndroid Build Coastguard Worker key, &boolean);
91*2d543d20SAndroid Build Coastguard Worker
92*2d543d20SAndroid Build Coastguard Worker if (rc < 0) {
93*2d543d20SAndroid Build Coastguard Worker snprintf(errormsg, sizeof(errormsg),
94*2d543d20SAndroid Build Coastguard Worker "Could not find boolean %s.\n", name);
95*2d543d20SAndroid Build Coastguard Worker PyErr_SetString( PyExc_RuntimeError, errormsg);
96*2d543d20SAndroid Build Coastguard Worker break;
97*2d543d20SAndroid Build Coastguard Worker }
98*2d543d20SAndroid Build Coastguard Worker
99*2d543d20SAndroid Build Coastguard Worker sepol_bool_set_value(boolean, !active);
100*2d543d20SAndroid Build Coastguard Worker
101*2d543d20SAndroid Build Coastguard Worker rc = sepol_bool_set(avc->handle,
102*2d543d20SAndroid Build Coastguard Worker avc->policydb,
103*2d543d20SAndroid Build Coastguard Worker key, boolean);
104*2d543d20SAndroid Build Coastguard Worker if (rc < 0) {
105*2d543d20SAndroid Build Coastguard Worker snprintf(errormsg, sizeof(errormsg),
106*2d543d20SAndroid Build Coastguard Worker "Could not set boolean data %s.\n", name);
107*2d543d20SAndroid Build Coastguard Worker PyErr_SetString( PyExc_RuntimeError, errormsg);
108*2d543d20SAndroid Build Coastguard Worker break;
109*2d543d20SAndroid Build Coastguard Worker }
110*2d543d20SAndroid Build Coastguard Worker
111*2d543d20SAndroid Build Coastguard Worker /* Reproduce the computation. */
112*2d543d20SAndroid Build Coastguard Worker rc = sepol_compute_av_reason(avc->ssid, avc->tsid, avc->tclass,
113*2d543d20SAndroid Build Coastguard Worker avc->av, &avd, &reason);
114*2d543d20SAndroid Build Coastguard Worker if (rc < 0) {
115*2d543d20SAndroid Build Coastguard Worker snprintf(errormsg, sizeof(errormsg),
116*2d543d20SAndroid Build Coastguard Worker "Error during access vector computation, skipping...");
117*2d543d20SAndroid Build Coastguard Worker PyErr_SetString( PyExc_RuntimeError, errormsg);
118*2d543d20SAndroid Build Coastguard Worker
119*2d543d20SAndroid Build Coastguard Worker sepol_bool_free(boolean);
120*2d543d20SAndroid Build Coastguard Worker break;
121*2d543d20SAndroid Build Coastguard Worker } else {
122*2d543d20SAndroid Build Coastguard Worker if (!reason) {
123*2d543d20SAndroid Build Coastguard Worker foundlist[fcnt] = i;
124*2d543d20SAndroid Build Coastguard Worker fcnt++;
125*2d543d20SAndroid Build Coastguard Worker }
126*2d543d20SAndroid Build Coastguard Worker sepol_bool_set_value(boolean, active);
127*2d543d20SAndroid Build Coastguard Worker rc = sepol_bool_set(avc->handle,
128*2d543d20SAndroid Build Coastguard Worker avc->policydb, key,
129*2d543d20SAndroid Build Coastguard Worker boolean);
130*2d543d20SAndroid Build Coastguard Worker if (rc < 0) {
131*2d543d20SAndroid Build Coastguard Worker snprintf(errormsg, sizeof(errormsg),
132*2d543d20SAndroid Build Coastguard Worker "Could not set boolean data %s.\n",
133*2d543d20SAndroid Build Coastguard Worker name);
134*2d543d20SAndroid Build Coastguard Worker
135*2d543d20SAndroid Build Coastguard Worker PyErr_SetString( PyExc_RuntimeError, errormsg);
136*2d543d20SAndroid Build Coastguard Worker break;
137*2d543d20SAndroid Build Coastguard Worker }
138*2d543d20SAndroid Build Coastguard Worker }
139*2d543d20SAndroid Build Coastguard Worker sepol_bool_free(boolean);
140*2d543d20SAndroid Build Coastguard Worker sepol_bool_key_free(key);
141*2d543d20SAndroid Build Coastguard Worker key = NULL;
142*2d543d20SAndroid Build Coastguard Worker boolean = NULL;
143*2d543d20SAndroid Build Coastguard Worker }
144*2d543d20SAndroid Build Coastguard Worker if (key)
145*2d543d20SAndroid Build Coastguard Worker sepol_bool_key_free(key);
146*2d543d20SAndroid Build Coastguard Worker
147*2d543d20SAndroid Build Coastguard Worker if (boolean)
148*2d543d20SAndroid Build Coastguard Worker sepol_bool_free(boolean);
149*2d543d20SAndroid Build Coastguard Worker
150*2d543d20SAndroid Build Coastguard Worker if (fcnt > 0) {
151*2d543d20SAndroid Build Coastguard Worker *bools = calloc(fcnt + 1, sizeof(struct boolean_t));
152*2d543d20SAndroid Build Coastguard Worker if (!*bools) {
153*2d543d20SAndroid Build Coastguard Worker PyErr_SetString( PyExc_MemoryError, "Out of memory\n");
154*2d543d20SAndroid Build Coastguard Worker free(foundlist);
155*2d543d20SAndroid Build Coastguard Worker return 0;
156*2d543d20SAndroid Build Coastguard Worker }
157*2d543d20SAndroid Build Coastguard Worker
158*2d543d20SAndroid Build Coastguard Worker struct boolean_t *b = *bools;
159*2d543d20SAndroid Build Coastguard Worker for (i = 0; i < fcnt; i++) {
160*2d543d20SAndroid Build Coastguard Worker int ctr = foundlist[i];
161*2d543d20SAndroid Build Coastguard Worker b[i].name = strdup(boollist[ctr]->name);
162*2d543d20SAndroid Build Coastguard Worker b[i].active = !boollist[ctr]->active;
163*2d543d20SAndroid Build Coastguard Worker }
164*2d543d20SAndroid Build Coastguard Worker }
165*2d543d20SAndroid Build Coastguard Worker free(foundlist);
166*2d543d20SAndroid Build Coastguard Worker return fcnt;
167*2d543d20SAndroid Build Coastguard Worker }
168*2d543d20SAndroid Build Coastguard Worker
finish(PyObject * self,PyObject * args)169*2d543d20SAndroid Build Coastguard Worker static PyObject *finish(PyObject *self __attribute__((unused)), PyObject *args) {
170*2d543d20SAndroid Build Coastguard Worker PyObject *result = 0;
171*2d543d20SAndroid Build Coastguard Worker
172*2d543d20SAndroid Build Coastguard Worker if (PyArg_ParseTuple(args,(char *)":finish")) {
173*2d543d20SAndroid Build Coastguard Worker int i = 0;
174*2d543d20SAndroid Build Coastguard Worker if (! avc)
175*2d543d20SAndroid Build Coastguard Worker Py_RETURN_NONE;
176*2d543d20SAndroid Build Coastguard Worker
177*2d543d20SAndroid Build Coastguard Worker for (i = 0; i < boolcnt; i++) {
178*2d543d20SAndroid Build Coastguard Worker free(boollist[i]->name);
179*2d543d20SAndroid Build Coastguard Worker free(boollist[i]);
180*2d543d20SAndroid Build Coastguard Worker }
181*2d543d20SAndroid Build Coastguard Worker free(boollist);
182*2d543d20SAndroid Build Coastguard Worker sepol_sidtab_shutdown(&sidtab);
183*2d543d20SAndroid Build Coastguard Worker sepol_sidtab_destroy(&sidtab);
184*2d543d20SAndroid Build Coastguard Worker sepol_policydb_free(avc->policydb);
185*2d543d20SAndroid Build Coastguard Worker sepol_handle_destroy(avc->handle);
186*2d543d20SAndroid Build Coastguard Worker free(avc);
187*2d543d20SAndroid Build Coastguard Worker avc = NULL;
188*2d543d20SAndroid Build Coastguard Worker boollist = NULL;
189*2d543d20SAndroid Build Coastguard Worker boolcnt = 0;
190*2d543d20SAndroid Build Coastguard Worker
191*2d543d20SAndroid Build Coastguard Worker /* Boilerplate to return "None" */
192*2d543d20SAndroid Build Coastguard Worker Py_RETURN_NONE;
193*2d543d20SAndroid Build Coastguard Worker }
194*2d543d20SAndroid Build Coastguard Worker return result;
195*2d543d20SAndroid Build Coastguard Worker }
196*2d543d20SAndroid Build Coastguard Worker
197*2d543d20SAndroid Build Coastguard Worker
__policy_init(const char * init_path)198*2d543d20SAndroid Build Coastguard Worker static int __policy_init(const char *init_path)
199*2d543d20SAndroid Build Coastguard Worker {
200*2d543d20SAndroid Build Coastguard Worker FILE *fp = NULL;
201*2d543d20SAndroid Build Coastguard Worker const char *curpolicy;
202*2d543d20SAndroid Build Coastguard Worker char errormsg[PATH_MAX+1024+20];
203*2d543d20SAndroid Build Coastguard Worker struct sepol_policy_file *pf = NULL;
204*2d543d20SAndroid Build Coastguard Worker int rc;
205*2d543d20SAndroid Build Coastguard Worker unsigned int cnt;
206*2d543d20SAndroid Build Coastguard Worker
207*2d543d20SAndroid Build Coastguard Worker if (init_path) {
208*2d543d20SAndroid Build Coastguard Worker curpolicy = init_path;
209*2d543d20SAndroid Build Coastguard Worker } else {
210*2d543d20SAndroid Build Coastguard Worker curpolicy = selinux_current_policy_path();
211*2d543d20SAndroid Build Coastguard Worker if (!curpolicy) {
212*2d543d20SAndroid Build Coastguard Worker /* SELinux disabled, must use -p option. */
213*2d543d20SAndroid Build Coastguard Worker snprintf(errormsg, sizeof(errormsg),
214*2d543d20SAndroid Build Coastguard Worker "You must specify the -p option with the path to the policy file.\n");
215*2d543d20SAndroid Build Coastguard Worker PyErr_SetString( PyExc_ValueError, errormsg);
216*2d543d20SAndroid Build Coastguard Worker return 1;
217*2d543d20SAndroid Build Coastguard Worker }
218*2d543d20SAndroid Build Coastguard Worker }
219*2d543d20SAndroid Build Coastguard Worker
220*2d543d20SAndroid Build Coastguard Worker fp = fopen(curpolicy, "re");
221*2d543d20SAndroid Build Coastguard Worker if (!fp) {
222*2d543d20SAndroid Build Coastguard Worker snprintf(errormsg, sizeof(errormsg),
223*2d543d20SAndroid Build Coastguard Worker "unable to open %s: %m\n",
224*2d543d20SAndroid Build Coastguard Worker curpolicy);
225*2d543d20SAndroid Build Coastguard Worker PyErr_SetString( PyExc_ValueError, errormsg);
226*2d543d20SAndroid Build Coastguard Worker return 1;
227*2d543d20SAndroid Build Coastguard Worker }
228*2d543d20SAndroid Build Coastguard Worker
229*2d543d20SAndroid Build Coastguard Worker avc = calloc(1, sizeof(struct avc_t));
230*2d543d20SAndroid Build Coastguard Worker if (!avc) {
231*2d543d20SAndroid Build Coastguard Worker PyErr_SetString( PyExc_MemoryError, "Out of memory\n");
232*2d543d20SAndroid Build Coastguard Worker fclose(fp);
233*2d543d20SAndroid Build Coastguard Worker return 1;
234*2d543d20SAndroid Build Coastguard Worker }
235*2d543d20SAndroid Build Coastguard Worker
236*2d543d20SAndroid Build Coastguard Worker /* Set up a policydb directly so that we can mutate it later
237*2d543d20SAndroid Build Coastguard Worker for testing what booleans might have allowed the access.
238*2d543d20SAndroid Build Coastguard Worker Otherwise, we'd just use sepol_set_policydb_from_file() here. */
239*2d543d20SAndroid Build Coastguard Worker if (sepol_policy_file_create(&pf) ||
240*2d543d20SAndroid Build Coastguard Worker sepol_policydb_create(&avc->policydb)) {
241*2d543d20SAndroid Build Coastguard Worker snprintf(errormsg, sizeof(errormsg),
242*2d543d20SAndroid Build Coastguard Worker "policydb_init failed: %m\n");
243*2d543d20SAndroid Build Coastguard Worker PyErr_SetString( PyExc_RuntimeError, errormsg);
244*2d543d20SAndroid Build Coastguard Worker goto err;
245*2d543d20SAndroid Build Coastguard Worker }
246*2d543d20SAndroid Build Coastguard Worker sepol_policy_file_set_fp(pf, fp);
247*2d543d20SAndroid Build Coastguard Worker if (sepol_policydb_read(avc->policydb, pf)) {
248*2d543d20SAndroid Build Coastguard Worker snprintf(errormsg, sizeof(errormsg),
249*2d543d20SAndroid Build Coastguard Worker "invalid binary policy %s\n", curpolicy);
250*2d543d20SAndroid Build Coastguard Worker PyErr_SetString( PyExc_ValueError, errormsg);
251*2d543d20SAndroid Build Coastguard Worker goto err;
252*2d543d20SAndroid Build Coastguard Worker }
253*2d543d20SAndroid Build Coastguard Worker fclose(fp);
254*2d543d20SAndroid Build Coastguard Worker fp = NULL;
255*2d543d20SAndroid Build Coastguard Worker sepol_set_policydb(&avc->policydb->p);
256*2d543d20SAndroid Build Coastguard Worker avc->handle = sepol_handle_create();
257*2d543d20SAndroid Build Coastguard Worker /* Turn off messages */
258*2d543d20SAndroid Build Coastguard Worker sepol_msg_set_callback(avc->handle, NULL, NULL);
259*2d543d20SAndroid Build Coastguard Worker
260*2d543d20SAndroid Build Coastguard Worker rc = sepol_bool_count(avc->handle,
261*2d543d20SAndroid Build Coastguard Worker avc->policydb, &cnt);
262*2d543d20SAndroid Build Coastguard Worker if (rc < 0) {
263*2d543d20SAndroid Build Coastguard Worker PyErr_SetString( PyExc_RuntimeError, "unable to get bool count\n");
264*2d543d20SAndroid Build Coastguard Worker goto err;
265*2d543d20SAndroid Build Coastguard Worker }
266*2d543d20SAndroid Build Coastguard Worker
267*2d543d20SAndroid Build Coastguard Worker boollist = calloc(cnt, sizeof(*boollist));
268*2d543d20SAndroid Build Coastguard Worker if (!boollist) {
269*2d543d20SAndroid Build Coastguard Worker PyErr_SetString( PyExc_MemoryError, "Out of memory\n");
270*2d543d20SAndroid Build Coastguard Worker goto err;
271*2d543d20SAndroid Build Coastguard Worker }
272*2d543d20SAndroid Build Coastguard Worker
273*2d543d20SAndroid Build Coastguard Worker sepol_bool_iterate(avc->handle, avc->policydb,
274*2d543d20SAndroid Build Coastguard Worker load_booleans, NULL);
275*2d543d20SAndroid Build Coastguard Worker
276*2d543d20SAndroid Build Coastguard Worker /* Initialize the sidtab for subsequent use by sepol_context_to_sid
277*2d543d20SAndroid Build Coastguard Worker and sepol_compute_av_reason. */
278*2d543d20SAndroid Build Coastguard Worker rc = sepol_sidtab_init(&sidtab);
279*2d543d20SAndroid Build Coastguard Worker if (rc < 0) {
280*2d543d20SAndroid Build Coastguard Worker PyErr_SetString( PyExc_RuntimeError, "unable to init sidtab\n");
281*2d543d20SAndroid Build Coastguard Worker goto err;
282*2d543d20SAndroid Build Coastguard Worker }
283*2d543d20SAndroid Build Coastguard Worker sepol_set_sidtab(&sidtab);
284*2d543d20SAndroid Build Coastguard Worker return 0;
285*2d543d20SAndroid Build Coastguard Worker
286*2d543d20SAndroid Build Coastguard Worker err:
287*2d543d20SAndroid Build Coastguard Worker if (boollist)
288*2d543d20SAndroid Build Coastguard Worker free(boollist);
289*2d543d20SAndroid Build Coastguard Worker if (avc){
290*2d543d20SAndroid Build Coastguard Worker if (avc->handle)
291*2d543d20SAndroid Build Coastguard Worker sepol_handle_destroy(avc->handle);
292*2d543d20SAndroid Build Coastguard Worker if (avc->policydb)
293*2d543d20SAndroid Build Coastguard Worker sepol_policydb_free(avc->policydb);
294*2d543d20SAndroid Build Coastguard Worker free(avc);
295*2d543d20SAndroid Build Coastguard Worker }
296*2d543d20SAndroid Build Coastguard Worker if (pf)
297*2d543d20SAndroid Build Coastguard Worker sepol_policy_file_free(pf);
298*2d543d20SAndroid Build Coastguard Worker if (fp)
299*2d543d20SAndroid Build Coastguard Worker fclose(fp);
300*2d543d20SAndroid Build Coastguard Worker return 1;
301*2d543d20SAndroid Build Coastguard Worker }
302*2d543d20SAndroid Build Coastguard Worker
init(PyObject * self,PyObject * args)303*2d543d20SAndroid Build Coastguard Worker static PyObject *init(PyObject *self __attribute__((unused)), PyObject *args) {
304*2d543d20SAndroid Build Coastguard Worker int result;
305*2d543d20SAndroid Build Coastguard Worker char *init_path = NULL;
306*2d543d20SAndroid Build Coastguard Worker if (avc) {
307*2d543d20SAndroid Build Coastguard Worker PyErr_SetString( PyExc_RuntimeError, "init called multiple times");
308*2d543d20SAndroid Build Coastguard Worker return NULL;
309*2d543d20SAndroid Build Coastguard Worker }
310*2d543d20SAndroid Build Coastguard Worker if (!PyArg_ParseTuple(args,(char *)"|s:policy_init",&init_path))
311*2d543d20SAndroid Build Coastguard Worker return NULL;
312*2d543d20SAndroid Build Coastguard Worker result = __policy_init(init_path);
313*2d543d20SAndroid Build Coastguard Worker return Py_BuildValue("i", result);
314*2d543d20SAndroid Build Coastguard Worker }
315*2d543d20SAndroid Build Coastguard Worker
316*2d543d20SAndroid Build Coastguard Worker #define RETURN(X) \
317*2d543d20SAndroid Build Coastguard Worker { \
318*2d543d20SAndroid Build Coastguard Worker return Py_BuildValue("iO", (X), Py_None); \
319*2d543d20SAndroid Build Coastguard Worker }
320*2d543d20SAndroid Build Coastguard Worker
analyze(PyObject * self,PyObject * args)321*2d543d20SAndroid Build Coastguard Worker static PyObject *analyze(PyObject *self __attribute__((unused)) , PyObject *args) {
322*2d543d20SAndroid Build Coastguard Worker char *reason_buf = NULL;
323*2d543d20SAndroid Build Coastguard Worker char * scon;
324*2d543d20SAndroid Build Coastguard Worker char * tcon;
325*2d543d20SAndroid Build Coastguard Worker char *tclassstr;
326*2d543d20SAndroid Build Coastguard Worker PyObject *listObj;
327*2d543d20SAndroid Build Coastguard Worker PyObject *strObj;
328*2d543d20SAndroid Build Coastguard Worker int numlines;
329*2d543d20SAndroid Build Coastguard Worker struct boolean_t *bools;
330*2d543d20SAndroid Build Coastguard Worker unsigned int reason;
331*2d543d20SAndroid Build Coastguard Worker sepol_security_id_t ssid, tsid;
332*2d543d20SAndroid Build Coastguard Worker sepol_security_class_t tclass;
333*2d543d20SAndroid Build Coastguard Worker sepol_access_vector_t perm, av;
334*2d543d20SAndroid Build Coastguard Worker struct sepol_av_decision avd;
335*2d543d20SAndroid Build Coastguard Worker int rc;
336*2d543d20SAndroid Build Coastguard Worker int i = 0;
337*2d543d20SAndroid Build Coastguard Worker
338*2d543d20SAndroid Build Coastguard Worker if (!PyArg_ParseTuple(args,(char *)"sssO!:audit2why",&scon,&tcon,&tclassstr,&PyList_Type, &listObj))
339*2d543d20SAndroid Build Coastguard Worker return NULL;
340*2d543d20SAndroid Build Coastguard Worker
341*2d543d20SAndroid Build Coastguard Worker /* get the number of lines passed to us */
342*2d543d20SAndroid Build Coastguard Worker numlines = PyList_Size(listObj);
343*2d543d20SAndroid Build Coastguard Worker
344*2d543d20SAndroid Build Coastguard Worker /* should raise an error here. */
345*2d543d20SAndroid Build Coastguard Worker if (numlines < 0) return NULL; /* Not a list */
346*2d543d20SAndroid Build Coastguard Worker
347*2d543d20SAndroid Build Coastguard Worker if (!avc)
348*2d543d20SAndroid Build Coastguard Worker RETURN(NOPOLICY)
349*2d543d20SAndroid Build Coastguard Worker
350*2d543d20SAndroid Build Coastguard Worker rc = sepol_context_to_sid(scon, strlen(scon) + 1, &ssid);
351*2d543d20SAndroid Build Coastguard Worker if (rc < 0)
352*2d543d20SAndroid Build Coastguard Worker RETURN(BADSCON)
353*2d543d20SAndroid Build Coastguard Worker
354*2d543d20SAndroid Build Coastguard Worker rc = sepol_context_to_sid(tcon, strlen(tcon) + 1, &tsid);
355*2d543d20SAndroid Build Coastguard Worker if (rc < 0)
356*2d543d20SAndroid Build Coastguard Worker RETURN(BADTCON)
357*2d543d20SAndroid Build Coastguard Worker
358*2d543d20SAndroid Build Coastguard Worker rc = sepol_string_to_security_class(tclassstr, &tclass);
359*2d543d20SAndroid Build Coastguard Worker if (rc < 0)
360*2d543d20SAndroid Build Coastguard Worker RETURN(BADTCLASS)
361*2d543d20SAndroid Build Coastguard Worker
362*2d543d20SAndroid Build Coastguard Worker /* Convert the permission list to an AV. */
363*2d543d20SAndroid Build Coastguard Worker av = 0;
364*2d543d20SAndroid Build Coastguard Worker
365*2d543d20SAndroid Build Coastguard Worker /* iterate over items of the list, grabbing strings, and parsing
366*2d543d20SAndroid Build Coastguard Worker for numbers */
367*2d543d20SAndroid Build Coastguard Worker for (i = 0; i < numlines; i++){
368*2d543d20SAndroid Build Coastguard Worker const char *permstr;
369*2d543d20SAndroid Build Coastguard Worker
370*2d543d20SAndroid Build Coastguard Worker /* grab the string object from the next element of the list */
371*2d543d20SAndroid Build Coastguard Worker strObj = PyList_GetItem(listObj, i); /* Can't fail */
372*2d543d20SAndroid Build Coastguard Worker
373*2d543d20SAndroid Build Coastguard Worker /* make it a string */
374*2d543d20SAndroid Build Coastguard Worker #if PY_MAJOR_VERSION >= 3
375*2d543d20SAndroid Build Coastguard Worker permstr = _PyUnicode_AsString( strObj );
376*2d543d20SAndroid Build Coastguard Worker #else
377*2d543d20SAndroid Build Coastguard Worker permstr = PyString_AsString( strObj );
378*2d543d20SAndroid Build Coastguard Worker #endif
379*2d543d20SAndroid Build Coastguard Worker
380*2d543d20SAndroid Build Coastguard Worker rc = sepol_string_to_av_perm(tclass, permstr, &perm);
381*2d543d20SAndroid Build Coastguard Worker if (rc < 0)
382*2d543d20SAndroid Build Coastguard Worker RETURN(BADPERM)
383*2d543d20SAndroid Build Coastguard Worker
384*2d543d20SAndroid Build Coastguard Worker av |= perm;
385*2d543d20SAndroid Build Coastguard Worker }
386*2d543d20SAndroid Build Coastguard Worker
387*2d543d20SAndroid Build Coastguard Worker /* Reproduce the computation. */
388*2d543d20SAndroid Build Coastguard Worker rc = sepol_compute_av_reason_buffer(ssid, tsid, tclass, av, &avd, &reason, &reason_buf, 0);
389*2d543d20SAndroid Build Coastguard Worker if (rc < 0)
390*2d543d20SAndroid Build Coastguard Worker RETURN(BADCOMPUTE)
391*2d543d20SAndroid Build Coastguard Worker
392*2d543d20SAndroid Build Coastguard Worker if (!reason)
393*2d543d20SAndroid Build Coastguard Worker RETURN(ALLOW)
394*2d543d20SAndroid Build Coastguard Worker
395*2d543d20SAndroid Build Coastguard Worker if (reason & SEPOL_COMPUTEAV_TE) {
396*2d543d20SAndroid Build Coastguard Worker avc->ssid = ssid;
397*2d543d20SAndroid Build Coastguard Worker avc->tsid = tsid;
398*2d543d20SAndroid Build Coastguard Worker avc->tclass = tclass;
399*2d543d20SAndroid Build Coastguard Worker avc->av = av;
400*2d543d20SAndroid Build Coastguard Worker if (check_booleans(&bools) == 0) {
401*2d543d20SAndroid Build Coastguard Worker if (av & ~avd.auditdeny) {
402*2d543d20SAndroid Build Coastguard Worker RETURN(DONTAUDIT)
403*2d543d20SAndroid Build Coastguard Worker } else {
404*2d543d20SAndroid Build Coastguard Worker RETURN(TERULE)
405*2d543d20SAndroid Build Coastguard Worker }
406*2d543d20SAndroid Build Coastguard Worker } else {
407*2d543d20SAndroid Build Coastguard Worker PyObject *outboollist;
408*2d543d20SAndroid Build Coastguard Worker struct boolean_t *b = bools;
409*2d543d20SAndroid Build Coastguard Worker int len = 0;
410*2d543d20SAndroid Build Coastguard Worker while (b->name) {
411*2d543d20SAndroid Build Coastguard Worker len++; b++;
412*2d543d20SAndroid Build Coastguard Worker }
413*2d543d20SAndroid Build Coastguard Worker b = bools;
414*2d543d20SAndroid Build Coastguard Worker outboollist = PyList_New(len);
415*2d543d20SAndroid Build Coastguard Worker len = 0;
416*2d543d20SAndroid Build Coastguard Worker while(b->name) {
417*2d543d20SAndroid Build Coastguard Worker PyObject *bool_ = Py_BuildValue("(si)", b->name, b->active);
418*2d543d20SAndroid Build Coastguard Worker PyList_SetItem(outboollist, len++, bool_);
419*2d543d20SAndroid Build Coastguard Worker b++;
420*2d543d20SAndroid Build Coastguard Worker }
421*2d543d20SAndroid Build Coastguard Worker free(bools);
422*2d543d20SAndroid Build Coastguard Worker /* 'N' steals the reference to outboollist */
423*2d543d20SAndroid Build Coastguard Worker return Py_BuildValue("iN", BOOLEAN, outboollist);
424*2d543d20SAndroid Build Coastguard Worker }
425*2d543d20SAndroid Build Coastguard Worker }
426*2d543d20SAndroid Build Coastguard Worker
427*2d543d20SAndroid Build Coastguard Worker if (reason & SEPOL_COMPUTEAV_CONS) {
428*2d543d20SAndroid Build Coastguard Worker if (reason_buf) {
429*2d543d20SAndroid Build Coastguard Worker PyObject *result = NULL;
430*2d543d20SAndroid Build Coastguard Worker result = Py_BuildValue("is", CONSTRAINT, reason_buf);
431*2d543d20SAndroid Build Coastguard Worker free(reason_buf);
432*2d543d20SAndroid Build Coastguard Worker return result;
433*2d543d20SAndroid Build Coastguard Worker }
434*2d543d20SAndroid Build Coastguard Worker RETURN(CONSTRAINT)
435*2d543d20SAndroid Build Coastguard Worker }
436*2d543d20SAndroid Build Coastguard Worker
437*2d543d20SAndroid Build Coastguard Worker if (reason & SEPOL_COMPUTEAV_RBAC)
438*2d543d20SAndroid Build Coastguard Worker RETURN(RBAC)
439*2d543d20SAndroid Build Coastguard Worker
440*2d543d20SAndroid Build Coastguard Worker if (reason & SEPOL_COMPUTEAV_BOUNDS)
441*2d543d20SAndroid Build Coastguard Worker RETURN(BOUNDS)
442*2d543d20SAndroid Build Coastguard Worker
443*2d543d20SAndroid Build Coastguard Worker RETURN(BADCOMPUTE)
444*2d543d20SAndroid Build Coastguard Worker }
445*2d543d20SAndroid Build Coastguard Worker
446*2d543d20SAndroid Build Coastguard Worker static PyMethodDef audit2whyMethods[] = {
447*2d543d20SAndroid Build Coastguard Worker {"init", init, METH_VARARGS,
448*2d543d20SAndroid Build Coastguard Worker "Initialize policy database."},
449*2d543d20SAndroid Build Coastguard Worker {"analyze", analyze, METH_VARARGS,
450*2d543d20SAndroid Build Coastguard Worker "Analyze AVC."},
451*2d543d20SAndroid Build Coastguard Worker {"finish", finish, METH_VARARGS,
452*2d543d20SAndroid Build Coastguard Worker "Finish using policy, free memory."},
453*2d543d20SAndroid Build Coastguard Worker {NULL, NULL, 0, NULL} /* Sentinel */
454*2d543d20SAndroid Build Coastguard Worker };
455*2d543d20SAndroid Build Coastguard Worker
456*2d543d20SAndroid Build Coastguard Worker #if PY_MAJOR_VERSION >= 3
457*2d543d20SAndroid Build Coastguard Worker /* Module-initialization logic specific to Python 3 */
458*2d543d20SAndroid Build Coastguard Worker static struct PyModuleDef moduledef = {
459*2d543d20SAndroid Build Coastguard Worker PyModuleDef_HEAD_INIT,
460*2d543d20SAndroid Build Coastguard Worker "audit2why",
461*2d543d20SAndroid Build Coastguard Worker NULL,
462*2d543d20SAndroid Build Coastguard Worker 0,
463*2d543d20SAndroid Build Coastguard Worker audit2whyMethods,
464*2d543d20SAndroid Build Coastguard Worker NULL,
465*2d543d20SAndroid Build Coastguard Worker NULL,
466*2d543d20SAndroid Build Coastguard Worker NULL,
467*2d543d20SAndroid Build Coastguard Worker NULL
468*2d543d20SAndroid Build Coastguard Worker };
469*2d543d20SAndroid Build Coastguard Worker
470*2d543d20SAndroid Build Coastguard Worker PyMODINIT_FUNC PyInit_audit2why(void); /* silence -Wmissing-prototypes */
PyInit_audit2why(void)471*2d543d20SAndroid Build Coastguard Worker PyMODINIT_FUNC PyInit_audit2why(void)
472*2d543d20SAndroid Build Coastguard Worker #else
473*2d543d20SAndroid Build Coastguard Worker PyMODINIT_FUNC initaudit2why(void); /* silence -Wmissing-prototypes */
474*2d543d20SAndroid Build Coastguard Worker PyMODINIT_FUNC initaudit2why(void)
475*2d543d20SAndroid Build Coastguard Worker #endif
476*2d543d20SAndroid Build Coastguard Worker {
477*2d543d20SAndroid Build Coastguard Worker PyObject *m;
478*2d543d20SAndroid Build Coastguard Worker #if PY_MAJOR_VERSION >= 3
479*2d543d20SAndroid Build Coastguard Worker m = PyModule_Create(&moduledef);
480*2d543d20SAndroid Build Coastguard Worker if (m == NULL) {
481*2d543d20SAndroid Build Coastguard Worker return NULL;
482*2d543d20SAndroid Build Coastguard Worker }
483*2d543d20SAndroid Build Coastguard Worker #else
484*2d543d20SAndroid Build Coastguard Worker m = Py_InitModule("audit2why", audit2whyMethods);
485*2d543d20SAndroid Build Coastguard Worker #endif
486*2d543d20SAndroid Build Coastguard Worker PyModule_AddIntConstant(m,"UNKNOWN", UNKNOWN);
487*2d543d20SAndroid Build Coastguard Worker PyModule_AddIntConstant(m,"BADSCON", BADSCON);
488*2d543d20SAndroid Build Coastguard Worker PyModule_AddIntConstant(m,"BADTCON", BADTCON);
489*2d543d20SAndroid Build Coastguard Worker PyModule_AddIntConstant(m,"BADTCLASS", BADTCLASS);
490*2d543d20SAndroid Build Coastguard Worker PyModule_AddIntConstant(m,"BADPERM", BADPERM);
491*2d543d20SAndroid Build Coastguard Worker PyModule_AddIntConstant(m,"BADCOMPUTE", BADCOMPUTE);
492*2d543d20SAndroid Build Coastguard Worker PyModule_AddIntConstant(m,"NOPOLICY", NOPOLICY);
493*2d543d20SAndroid Build Coastguard Worker PyModule_AddIntConstant(m,"ALLOW", ALLOW);
494*2d543d20SAndroid Build Coastguard Worker PyModule_AddIntConstant(m,"DONTAUDIT", DONTAUDIT);
495*2d543d20SAndroid Build Coastguard Worker PyModule_AddIntConstant(m,"TERULE", TERULE);
496*2d543d20SAndroid Build Coastguard Worker PyModule_AddIntConstant(m,"BOOLEAN", BOOLEAN);
497*2d543d20SAndroid Build Coastguard Worker PyModule_AddIntConstant(m,"CONSTRAINT", CONSTRAINT);
498*2d543d20SAndroid Build Coastguard Worker PyModule_AddIntConstant(m,"RBAC", RBAC);
499*2d543d20SAndroid Build Coastguard Worker PyModule_AddIntConstant(m,"BOUNDS", BOUNDS);
500*2d543d20SAndroid Build Coastguard Worker
501*2d543d20SAndroid Build Coastguard Worker #if PY_MAJOR_VERSION >= 3
502*2d543d20SAndroid Build Coastguard Worker return m;
503*2d543d20SAndroid Build Coastguard Worker #endif
504*2d543d20SAndroid Build Coastguard Worker }
505