void apol_portcon_query_destroy(apol_portcon_query_t ** po) { if (*po != NULL) { apol_context_destroy(&((*po)->context)); free(*po); *po = NULL; } }
apol_context_t *apol_context_create_from_qpol_context(const apol_policy_t * p, const qpol_context_t * context) { apol_context_t *c = NULL; const qpol_user_t *user; const qpol_role_t *role; const qpol_type_t *type; const qpol_mls_range_t *range; const char *user_name, *role_name, *type_name; apol_mls_range_t *apol_range = NULL; if ((c = apol_context_create()) == NULL) { ERR(p, "%s", strerror(ENOMEM)); goto err; } if (qpol_context_get_user(p->p, context, &user) < 0 || qpol_context_get_role(p->p, context, &role) < 0 || qpol_context_get_type(p->p, context, &type) < 0 || qpol_context_get_range(p->p, context, &range) < 0) { goto err; } if (qpol_user_get_name(p->p, user, &user_name) < 0 || qpol_role_get_name(p->p, role, &role_name) < 0 || qpol_type_get_name(p->p, type, &type_name) < 0) { goto err; } if (qpol_policy_has_capability(p->p, QPOL_CAP_MLS)) { /* if the policy is MLS then convert the range, else * rely upon the default value of NULL */ if ((apol_range = apol_mls_range_create_from_qpol_mls_range(p, range)) == NULL) { goto err; } } if (apol_context_set_user(p, c, user_name) < 0 || apol_context_set_role(p, c, role_name) < 0 || apol_context_set_type(p, c, type_name) < 0 || apol_context_set_range(p, c, apol_range) < 0) { goto err; } return c; err: apol_mls_range_destroy(&apol_range); apol_context_destroy(&c); return NULL; }
/** * Get statistics regarding a policy's ports. * If this function is given a name, it will attempt to * get statistics about a particular port; otherwise * the function get statistics about all of the policy's ports. * * @param name Reference to an port's name; if NULL, * all ports will be considered * @param policydb Reference to a policy * * @return 0 on success, < 0 on error. */ static PyObject* get_ports(const char *num, const apol_policy_t * policydb) { const qpol_portcon_t *portcon = NULL; qpol_iterator_t *iter = NULL; uint16_t low_port, high_port; uint8_t ocon_proto; qpol_policy_t *q = apol_policy_get_qpol(policydb); const qpol_context_t *ctxt = NULL; const char *proto_str = NULL; const char *type = NULL; const apol_mls_range_t *range = NULL; char *range_str = NULL; apol_context_t *c = NULL; int error = 0; int rt = 0; PyObject *dict = NULL; PyObject *list = PyList_New(0); if (!list) goto err; if (qpol_policy_get_portcon_iter(q, &iter)) goto err; for (; !qpol_iterator_end(iter); qpol_iterator_next(iter)) { if (qpol_iterator_get_item(iter, (void **)&portcon)) goto err; if (qpol_portcon_get_low_port(q, portcon, &low_port)) goto err; if (qpol_portcon_get_high_port(q, portcon, &high_port)) goto err; if (qpol_portcon_get_protocol(q, portcon, &ocon_proto)) goto err; if (num) { if (atoi(num) < low_port || atoi(num) > high_port) continue; } if ((ocon_proto != IPPROTO_TCP) && (ocon_proto != IPPROTO_UDP)) goto err; if (qpol_portcon_get_context(q, portcon, &ctxt)) { PyErr_SetString(PyExc_RuntimeError, "Could not get for port context."); goto err; } if ((proto_str = apol_protocol_to_str(ocon_proto)) == NULL) { PyErr_SetString(PyExc_RuntimeError, "Invalid protocol for port"); goto err; } if ((c = apol_context_create_from_qpol_context(policydb, ctxt)) == NULL) { goto err; } if((type = apol_context_get_type(c)) == NULL) { apol_context_destroy(&c); goto err; } dict = PyDict_New(); if (!dict) goto err; if (py_insert_string(dict, "type", type)) goto err; if((range = apol_context_get_range(c)) != NULL) { range_str = apol_mls_range_render(policydb, range); if (range_str == NULL) { goto err; } if (py_insert_string(dict, "range", range_str)) goto err; } if (py_insert_string(dict, "protocol", proto_str)) goto err; if (py_insert_long(dict, "high", high_port)) goto err; if (py_insert_long(dict, "low", low_port)) goto err; rt = py_append_obj(list, dict); Py_DECREF(dict); dict = NULL; if (rt) goto err; } goto cleanup; err: error = errno; PyErr_SetString(PyExc_RuntimeError,strerror(errno)); py_decref(list); list = NULL; py_decref(dict); dict = NULL; cleanup: free(range_str); apol_context_destroy(&c); qpol_iterator_destroy(&iter); errno = error; return list; }
apol_context_t *apol_context_create_from_literal(const char *context_string) { apol_context_t *c = NULL; bool is_context_compiled = false; regex_t context_regex; const size_t nmatch = 5; regmatch_t pmatch[nmatch]; if ((c = apol_context_create()) == NULL) { goto err; } if (regcomp(&context_regex, "^([^:]*):([^:]*):([^:]*):?(.*)$", REG_EXTENDED) != 0) { goto err; } is_context_compiled = true; if (regexec(&context_regex, context_string, nmatch, pmatch, 0) != 0) { errno = EIO; goto err; } const char *s; size_t len; assert(pmatch[1].rm_so == 0); s = context_string + pmatch[1].rm_so; len = pmatch[1].rm_eo - pmatch[1].rm_so; // no +1 to avoid copying colon if (len != 0 && *s != '*' && (c->user = strndup(s, len)) == NULL) { goto err; } assert(pmatch[2].rm_so != -1); s = context_string + pmatch[2].rm_so; len = pmatch[2].rm_eo - pmatch[2].rm_so; // no +1 to avoid copying colon if (len != 0 && *s != '*' && (c->role = strndup(s, len)) == NULL) { goto err; } assert(pmatch[3].rm_so != -1); s = context_string + pmatch[3].rm_so; len = pmatch[3].rm_eo - pmatch[3].rm_so; // no +1 to avoid copying colon if (len != 0 && *s != '*' && (c->type = strndup(s, len)) == NULL) { goto err; } if (pmatch[4].rm_so != -1) { s = context_string + pmatch[4].rm_so; len = pmatch[4].rm_eo - pmatch[4].rm_so; if (len != 0 && *s != '*' && (c->range = apol_mls_range_create_from_literal(s)) == NULL) { goto err; } } regfree(&context_regex); return c; err: apol_context_destroy(&c); if (is_context_compiled) { regfree(&context_regex); } return NULL; }