LCOV - code coverage report
Current view: top level - source4/auth/gensec - pygensec.c (source / functions) Hit Total Coverage
Test: coverage report for master 2b515b7d Lines: 235 432 54.4 %
Date: 2024-02-28 12:06:22 Functions: 20 24 83.3 %

          Line data    Source code
       1             : /* 
       2             :    Unix SMB/CIFS implementation.
       3             :    Copyright (C) Jelmer Vernooij <jelmer@samba.org> 2009
       4             :    
       5             :    This program is free software; you can redistribute it and/or modify
       6             :    it under the terms of the GNU General Public License as published by
       7             :    the Free Software Foundation; either version 3 of the License, or
       8             :    (at your option) any later version.
       9             :    
      10             :    This program is distributed in the hope that it will be useful,
      11             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      12             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      13             :    GNU General Public License for more details.
      14             :    
      15             :    You should have received a copy of the GNU General Public License
      16             :    along with this program.  If not, see <http://www.gnu.org/licenses/>.
      17             : */
      18             : 
      19             : #include "lib/replace/system/python.h"
      20             : #include "python/py3compat.h"
      21             : #include "includes.h"
      22             : #include "python/modules.h"
      23             : #include "param/pyparam.h"
      24             : #include "auth/gensec/gensec.h"
      25             : #include "auth/gensec/gensec_internal.h" /* TODO: remove this */
      26             : #include "auth/credentials/pycredentials.h"
      27             : #include "libcli/util/pyerrors.h"
      28             : #include "python/modules.h"
      29             : #include <pytalloc.h>
      30             : #include <tevent.h>
      31             : #include "librpc/rpc/pyrpc_util.h"
      32             : 
      33           0 : static PyObject *py_get_name_by_authtype(PyObject *self, PyObject *args)
      34             : {
      35           0 :         int type;
      36           0 :         const char *name;
      37           0 :         struct gensec_security *security;
      38             : 
      39           0 :         if (!PyArg_ParseTuple(args, "i", &type))
      40           0 :                 return NULL;
      41             : 
      42           0 :         security = pytalloc_get_type(self, struct gensec_security);
      43             : 
      44           0 :         name = gensec_get_name_by_authtype(security, type);
      45           0 :         if (name == NULL)
      46           0 :                 Py_RETURN_NONE;
      47             : 
      48           0 :         return PyUnicode_FromString(name);
      49             : }
      50             : 
      51         664 : static struct gensec_settings *settings_from_object(TALLOC_CTX *mem_ctx, PyObject *object)
      52             : {
      53           0 :         struct gensec_settings *s;
      54           0 :         PyObject *py_hostname, *py_lp_ctx;
      55             : 
      56         664 :         if (!PyDict_Check(object)) {
      57           0 :                 PyErr_SetString(PyExc_ValueError, "settings should be a dictionary");
      58           0 :                 return NULL;
      59             :         }
      60             : 
      61         664 :         s = talloc_zero(mem_ctx, struct gensec_settings);
      62         664 :         if (!s) return NULL;
      63             : 
      64         664 :         py_hostname = PyDict_GetItemString(object, "target_hostname");
      65         664 :         if (!py_hostname) {
      66           0 :                 PyErr_SetString(PyExc_ValueError, "settings.target_hostname not found");
      67           0 :                 return NULL;
      68             :         }
      69             : 
      70         664 :         py_lp_ctx = PyDict_GetItemString(object, "lp_ctx");
      71         664 :         if (!py_lp_ctx) {
      72           0 :                 PyErr_SetString(PyExc_ValueError, "settings.lp_ctx not found");
      73           0 :                 return NULL;
      74             :         }
      75             : 
      76         664 :         s->target_hostname = PyUnicode_AsUTF8(py_hostname);
      77         664 :         s->lp_ctx = lpcfg_from_py_object(s, py_lp_ctx);
      78         664 :         return s;
      79             : }
      80             : 
      81         619 : static PyObject *py_gensec_start_client(PyTypeObject *type, PyObject *args, PyObject *kwargs)
      82             : {
      83           0 :         NTSTATUS status;
      84           0 :         PyObject *self;
      85           0 :         struct gensec_settings *settings;
      86         619 :         const char *kwnames[] = { "settings", NULL };
      87         619 :         PyObject *py_settings = Py_None;
      88           0 :         struct gensec_security *gensec;
      89           0 :         TALLOC_CTX *frame;
      90             : 
      91         619 :         if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O", discard_const_p(char *, kwnames), &py_settings))
      92           0 :                 return NULL;
      93             : 
      94         619 :         frame = talloc_stackframe();
      95             : 
      96         619 :         if (py_settings != Py_None) {
      97         619 :                 settings = settings_from_object(frame, py_settings);
      98         619 :                 if (settings == NULL) {
      99           0 :                         PyErr_NoMemory();
     100           0 :                         TALLOC_FREE(frame);
     101           0 :                         return NULL;
     102             :                 }
     103             :         } else {
     104           0 :                 settings = talloc_zero(frame, struct gensec_settings);
     105           0 :                 if (settings == NULL) {
     106           0 :                         PyErr_NoMemory();
     107           0 :                         TALLOC_FREE(frame);
     108           0 :                         return NULL;
     109             :                 }
     110             : 
     111           0 :                 settings->lp_ctx = loadparm_init_global(true);
     112           0 :                 if (settings->lp_ctx == NULL) {
     113           0 :                         PyErr_NoMemory();
     114           0 :                         TALLOC_FREE(frame);
     115           0 :                         return NULL;
     116             :                 }
     117             :         }
     118             : 
     119         619 :         status = gensec_init();
     120         619 :         if (!NT_STATUS_IS_OK(status)) {
     121           0 :                 PyErr_SetNTSTATUS(status);
     122           0 :                 TALLOC_FREE(frame);
     123           0 :                 return NULL;
     124             :         }
     125             : 
     126         619 :         status = gensec_client_start(frame, &gensec, settings);
     127         619 :         if (!NT_STATUS_IS_OK(status)) {
     128           0 :                 PyErr_SetNTSTATUS(status);
     129           0 :                 TALLOC_FREE(frame);
     130           0 :                 return NULL;
     131             :         }
     132             : 
     133         619 :         self = pytalloc_steal(type, gensec);
     134         619 :         TALLOC_FREE(frame);
     135             : 
     136         619 :         return (PyObject *)self;
     137             : }
     138             : 
     139          45 : static PyObject *py_gensec_start_server(PyTypeObject *type, PyObject *args, PyObject *kwargs)
     140             : {
     141           0 :         NTSTATUS status;
     142           0 :         PyObject *self;
     143          45 :         struct gensec_settings *settings = NULL;
     144          45 :         const char *kwnames[] = { "settings", "auth_context", NULL };
     145          45 :         PyObject *py_settings = Py_None;
     146          45 :         PyObject *py_auth_context = Py_None;
     147           0 :         struct gensec_security *gensec;
     148          45 :         struct auth4_context *auth_context = NULL;
     149           0 :         TALLOC_CTX *frame;
     150             : 
     151          45 :         if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OO", discard_const_p(char *, kwnames), &py_settings, &py_auth_context))
     152           0 :                 return NULL;
     153             : 
     154          45 :         frame = talloc_stackframe();
     155             : 
     156          45 :         if (py_settings != Py_None) {
     157          45 :                 settings = settings_from_object(frame, py_settings);
     158          45 :                 if (settings == NULL) {
     159           0 :                         PyErr_NoMemory();
     160           0 :                         TALLOC_FREE(frame);
     161           0 :                         return NULL;
     162             :                 }
     163             :         } else {
     164           0 :                 settings = talloc_zero(frame, struct gensec_settings);
     165           0 :                 if (settings == NULL) {
     166           0 :                         PyErr_NoMemory();
     167           0 :                         TALLOC_FREE(frame);
     168           0 :                         return NULL;
     169             :                 }
     170             : 
     171           0 :                 settings->lp_ctx = loadparm_init_global(true);
     172           0 :                 if (settings->lp_ctx == NULL) {
     173           0 :                         PyErr_NoMemory();
     174           0 :                         TALLOC_FREE(frame);
     175           0 :                         return NULL;
     176             :                 }
     177             :         }
     178             : 
     179          45 :         if (py_auth_context != Py_None) {
     180          45 :                 bool ok = py_check_dcerpc_type(py_auth_context,
     181             :                                                "samba.auth",
     182             :                                                "AuthContext");
     183          45 :                 if (!ok) {
     184           0 :                         return NULL;
     185             :                 }
     186             : 
     187          45 :                 auth_context = pytalloc_get_type(py_auth_context,
     188             :                                                  struct auth4_context);
     189          45 :                 if (!auth_context) {
     190           0 :                         PyErr_Format(PyExc_TypeError,
     191             :                                      "Expected auth.AuthContext for auth_context argument, got %s",
     192             :                                      pytalloc_get_name(py_auth_context));
     193           0 :                         return NULL;
     194             :                 }
     195             :         }
     196             : 
     197          45 :         status = gensec_init();
     198          45 :         if (!NT_STATUS_IS_OK(status)) {
     199           0 :                 PyErr_SetNTSTATUS(status);
     200           0 :                 TALLOC_FREE(frame);
     201           0 :                 return NULL;
     202             :         }
     203             : 
     204          45 :         status = gensec_server_start(frame, settings, auth_context, &gensec);
     205          45 :         if (!NT_STATUS_IS_OK(status)) {
     206           0 :                 PyErr_SetNTSTATUS(status);
     207           0 :                 TALLOC_FREE(frame);
     208           0 :                 return NULL;
     209             :         }
     210             : 
     211          45 :         self = pytalloc_steal(type, gensec);
     212          45 :         TALLOC_FREE(frame);
     213             : 
     214          45 :         return self;
     215             : }
     216             : 
     217          28 : static PyObject *py_gensec_set_target_hostname(PyObject *self, PyObject *args)
     218             : {
     219          28 :         struct gensec_security *security = pytalloc_get_type(self, struct gensec_security);
     220           0 :         char *target_hostname;
     221           0 :         NTSTATUS status;
     222             : 
     223          28 :         if (!PyArg_ParseTuple(args, "s", &target_hostname))
     224           0 :                 return NULL;
     225             : 
     226          28 :         status = gensec_set_target_hostname(security, target_hostname);
     227          28 :         if (!NT_STATUS_IS_OK(status)) {
     228           0 :                 PyErr_SetNTSTATUS(status);
     229           0 :                 return NULL;
     230             :         }
     231             :         
     232          28 :         Py_RETURN_NONE;
     233             : }
     234             : 
     235          28 : static PyObject *py_gensec_set_target_service(PyObject *self, PyObject *args)
     236             : {
     237          28 :         struct gensec_security *security = pytalloc_get_type(self, struct gensec_security);
     238           0 :         char *target_service;
     239           0 :         NTSTATUS status;
     240             : 
     241          28 :         if (!PyArg_ParseTuple(args, "s", &target_service))
     242           0 :                 return NULL;
     243             : 
     244          28 :         status = gensec_set_target_service(security, target_service);
     245          28 :         if (!NT_STATUS_IS_OK(status)) {
     246           0 :                 PyErr_SetNTSTATUS(status);
     247           0 :                 return NULL;
     248             :         }
     249             :         
     250          28 :         Py_RETURN_NONE;
     251             : }
     252             : 
     253           0 : static PyObject *py_gensec_set_target_service_description(PyObject *self, PyObject *args)
     254             : {
     255           0 :         struct gensec_security *security = pytalloc_get_type(self, struct gensec_security);
     256           0 :         char *target_service_description;
     257           0 :         NTSTATUS status;
     258             : 
     259           0 :         if (!PyArg_ParseTuple(args, "s", &target_service_description))
     260           0 :                 return NULL;
     261             : 
     262           0 :         status = gensec_set_target_service_description(security,
     263             :                                                        target_service_description);
     264           0 :         if (!NT_STATUS_IS_OK(status)) {
     265           0 :                 PyErr_SetNTSTATUS(status);
     266           0 :                 return NULL;
     267             :         }
     268             : 
     269           0 :         Py_RETURN_NONE;
     270             : }
     271             : 
     272         628 : static PyObject *py_gensec_set_credentials(PyObject *self, PyObject *args)
     273             : {
     274         628 :         PyObject *py_creds = Py_None;
     275           0 :         struct cli_credentials *creds;
     276         628 :         struct gensec_security *security = pytalloc_get_type(self, struct gensec_security);
     277           0 :         NTSTATUS status;
     278             : 
     279         628 :         if (!PyArg_ParseTuple(args, "O", &py_creds))
     280           0 :                 return NULL;
     281             : 
     282         628 :         creds = PyCredentials_AsCliCredentials(py_creds);
     283         628 :         if (!creds) {
     284           0 :                 PyErr_Format(
     285             :                         PyExc_TypeError,
     286             :                         "Expected samba.credentials for credentials argument, "
     287             :                         "got %s", pytalloc_get_name(py_creds));
     288           0 :                 return NULL;
     289             :         }
     290             : 
     291         628 :         status = gensec_set_credentials(security, creds);
     292         628 :         if (!NT_STATUS_IS_OK(status)) {
     293           0 :                 PyErr_SetNTSTATUS(status);
     294           0 :                 return NULL;
     295             :         }
     296             : 
     297         628 :         Py_RETURN_NONE;
     298             : }
     299             : 
     300          31 : static PyObject *py_gensec_session_info(PyObject *self,
     301             :                 PyObject *Py_UNUSED(ignored))
     302             : {
     303           0 :         TALLOC_CTX *mem_ctx;
     304           0 :         NTSTATUS status;
     305           0 :         PyObject *py_session_info;
     306          31 :         struct gensec_security *security = pytalloc_get_type(self, struct gensec_security);
     307           0 :         struct auth_session_info *info;
     308          31 :         if (security->ops == NULL) {
     309           2 :                 PyErr_SetString(PyExc_RuntimeError, "no mechanism selected");
     310           2 :                 return NULL;
     311             :         }
     312          29 :         mem_ctx = talloc_new(NULL);
     313          29 :         if (mem_ctx == NULL) {
     314           0 :                 return PyErr_NoMemory();
     315             :         }
     316             : 
     317          29 :         status = gensec_session_info(security, mem_ctx, &info);
     318          29 :         if (NT_STATUS_IS_ERR(status)) {
     319           1 :                 talloc_free(mem_ctx);
     320           1 :                 PyErr_SetNTSTATUS(status);
     321           1 :                 return NULL;
     322             :         }
     323             : 
     324          28 :         py_session_info = py_return_ndr_struct("samba.dcerpc.auth", "session_info",
     325             :                                                  info, info);
     326          28 :         talloc_free(mem_ctx);
     327          28 :         return py_session_info;
     328             : }
     329             : 
     330          48 : static PyObject *py_gensec_session_key(PyObject *self,
     331             :                 PyObject *Py_UNUSED(ignored))
     332             : {
     333           0 :         TALLOC_CTX *mem_ctx;
     334           0 :         NTSTATUS status;
     335          48 :         struct gensec_security *security = pytalloc_get_type(self, struct gensec_security);
     336          48 :         DATA_BLOB session_key = data_blob_null;
     337           0 :         static PyObject *session_key_obj = NULL;
     338             : 
     339          48 :         if (security->ops == NULL) {
     340           0 :                 PyErr_SetString(PyExc_RuntimeError, "no mechanism selected");
     341           0 :                 return NULL;
     342             :         }
     343          48 :         mem_ctx = talloc_new(NULL);
     344          48 :         if (mem_ctx == NULL) {
     345           0 :                 return PyErr_NoMemory();
     346             :         }
     347             : 
     348          48 :         status = gensec_session_key(security, mem_ctx, &session_key);
     349          48 :         if (!NT_STATUS_IS_OK(status)) {
     350           0 :                 talloc_free(mem_ctx);
     351           0 :                 PyErr_SetNTSTATUS(status);
     352           0 :                 return NULL;
     353             :         }
     354             : 
     355          96 :         session_key_obj = PyBytes_FromStringAndSize((const char *)session_key.data,
     356          48 :                                                      session_key.length);
     357          48 :         talloc_free(mem_ctx);
     358          48 :         return session_key_obj;
     359             : }
     360             : 
     361          27 : static PyObject *py_gensec_start_mech_by_name(PyObject *self, PyObject *args)
     362             : {
     363           0 :         char *name;
     364          27 :         struct gensec_security *security = pytalloc_get_type(self, struct gensec_security);
     365           0 :         NTSTATUS status;
     366             : 
     367          27 :         if (!PyArg_ParseTuple(args, "s", &name))
     368           0 :                 return NULL;
     369             : 
     370          27 :         status = gensec_start_mech_by_name(security, name);
     371          27 :         if (!NT_STATUS_IS_OK(status)) {
     372           2 :                 PyErr_SetNTSTATUS(status);
     373           2 :                 return NULL;
     374             :         }
     375             : 
     376          25 :         Py_RETURN_NONE;
     377             : }
     378             : 
     379          95 : static PyObject *py_gensec_start_mech_by_sasl_name(PyObject *self, PyObject *args)
     380             : {
     381           0 :         char *sasl_name;
     382          95 :         struct gensec_security *security = pytalloc_get_type(self, struct gensec_security);
     383           0 :         NTSTATUS status;
     384             : 
     385          95 :         if (!PyArg_ParseTuple(args, "s", &sasl_name))
     386           0 :                 return NULL;
     387             : 
     388          95 :         status = gensec_start_mech_by_sasl_name(security, sasl_name);
     389          95 :         if (!NT_STATUS_IS_OK(status)) {
     390           0 :                 PyErr_SetNTSTATUS(status);
     391           0 :                 return NULL;
     392             :         }
     393             : 
     394          95 :         Py_RETURN_NONE;
     395             : }
     396             : 
     397         510 : static PyObject *py_gensec_start_mech_by_authtype(PyObject *self, PyObject *args)
     398             : {
     399           0 :         int authtype, level;
     400         510 :         struct gensec_security *security = pytalloc_get_type(self, struct gensec_security);
     401           0 :         NTSTATUS status;
     402         510 :         if (!PyArg_ParseTuple(args, "ii", &authtype, &level))
     403           0 :                 return NULL;
     404             : 
     405         510 :         status = gensec_start_mech_by_authtype(security, authtype, level);
     406         510 :         if (!NT_STATUS_IS_OK(status)) {
     407           0 :                 PyErr_SetNTSTATUS(status);
     408           0 :                 return NULL;
     409             :         }
     410             : 
     411         510 :         Py_RETURN_NONE;
     412             : }
     413             : 
     414         639 : static PyObject *py_gensec_want_feature(PyObject *self, PyObject *args)
     415             : {
     416           0 :         int feature;
     417         639 :         struct gensec_security *security = pytalloc_get_type(self, struct gensec_security);
     418             :         /* This is i (and declared as an int above) by design, as they are handled as an integer in python */
     419         639 :         if (!PyArg_ParseTuple(args, "i", &feature))
     420           0 :                 return NULL;
     421             : 
     422         639 :         gensec_want_feature(security, feature);
     423             : 
     424         639 :         Py_RETURN_NONE;
     425             : }
     426             : 
     427           0 : static PyObject *py_gensec_have_feature(PyObject *self, PyObject *args)
     428             : {
     429           0 :         int feature;
     430           0 :         struct gensec_security *security = pytalloc_get_type(self, struct gensec_security);
     431             :         /* This is i (and declared as an int above) by design, as they are handled as an integer in python */
     432           0 :         if (!PyArg_ParseTuple(args, "i", &feature))
     433           0 :                 return NULL;
     434             : 
     435           0 :         if (gensec_have_feature(security, feature)) {
     436           0 :                 Py_RETURN_TRUE;
     437             :         } 
     438           0 :         Py_RETURN_FALSE;
     439             : }
     440             : 
     441           4 : static PyObject *py_gensec_set_max_update_size(PyObject *self, PyObject *args)
     442             : {
     443           4 :         struct gensec_security *security = pytalloc_get_type(self, struct gensec_security);
     444           4 :         unsigned int max_update_size = 0;
     445             : 
     446           4 :         if (!PyArg_ParseTuple(args, "I", &max_update_size))
     447           0 :                 return NULL;
     448             : 
     449           4 :         gensec_set_max_update_size(security, max_update_size);
     450             : 
     451           4 :         Py_RETURN_NONE;
     452             : }
     453             : 
     454           0 : static PyObject *py_gensec_max_update_size(PyObject *self,
     455             :                 PyObject *Py_UNUSED(ignored))
     456             : {
     457           0 :         struct gensec_security *security = pytalloc_get_type(self, struct gensec_security);
     458           0 :         unsigned int max_update_size = gensec_max_update_size(security);
     459             : 
     460           0 :         return PyLong_FromLong(max_update_size);
     461             : }
     462             : 
     463        4065 : static PyObject *py_gensec_update(PyObject *self, PyObject *args)
     464             : {
     465           0 :         NTSTATUS status;
     466           0 :         TALLOC_CTX *mem_ctx;
     467           0 :         DATA_BLOB in, out;
     468           0 :         PyObject *py_bytes, *result, *py_in;
     469        4065 :         struct gensec_security *security = pytalloc_get_type(self, struct gensec_security);
     470           0 :         PyObject *finished_processing;
     471        4065 :         char *data = NULL;
     472           0 :         Py_ssize_t len;
     473           0 :         int err;
     474             : 
     475        4065 :         if (!PyArg_ParseTuple(args, "O", &py_in))
     476           0 :                 return NULL;
     477             : 
     478        4065 :         mem_ctx = talloc_new(NULL);
     479        4065 :         if (mem_ctx == NULL) {
     480           0 :                 return PyErr_NoMemory();
     481             :         }
     482             : 
     483        4065 :         err = PyBytes_AsStringAndSize(py_in, &data, &len);
     484        4065 :         if (err) {
     485           0 :                 talloc_free(mem_ctx);
     486           0 :                 return NULL;
     487             :         }
     488             : 
     489             :         /*
     490             :          * Make a copy of the input buffer, as gensec_update may modify its
     491             :          * input argument.
     492             :          */
     493        4065 :         in = data_blob_talloc(mem_ctx, data, len);
     494        4065 :         if (!in.data) {
     495           0 :                 talloc_free(mem_ctx);
     496           0 :                 return PyErr_NoMemory();
     497             :         }
     498             : 
     499        4065 :         status = gensec_update(security, mem_ctx, in, &out);
     500             : 
     501        4065 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)
     502         440 :             && !NT_STATUS_IS_OK(status)) {
     503           6 :                 PyErr_SetNTSTATUS(status);
     504           6 :                 talloc_free(mem_ctx);
     505           6 :                 return NULL;
     506             :         }
     507        4059 :         py_bytes = PyBytes_FromStringAndSize((const char *)out.data,
     508        4059 :                                              out.length);
     509        4059 :         talloc_free(mem_ctx);
     510             : 
     511        4059 :         if (NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
     512        3625 :                 finished_processing = Py_False;
     513             :         } else {
     514         434 :                 finished_processing = Py_True;
     515             :         }
     516             : 
     517        4059 :         result = PyTuple_Pack(2, finished_processing, py_bytes);
     518        4059 :         Py_XDECREF(py_bytes);
     519        4059 :         return result;
     520             : }
     521             : 
     522          48 : static PyObject *py_gensec_wrap(PyObject *self, PyObject *args)
     523             : {
     524           0 :         NTSTATUS status;
     525             : 
     526           0 :         TALLOC_CTX *mem_ctx;
     527           0 :         DATA_BLOB in, out;
     528           0 :         PyObject *ret, *py_in;
     529          48 :         struct gensec_security *security = pytalloc_get_type(self, struct gensec_security);
     530             : 
     531          48 :         if (!PyArg_ParseTuple(args, "O", &py_in))
     532           0 :                 return NULL;
     533             : 
     534          48 :         mem_ctx = talloc_new(NULL);
     535          48 :         if (mem_ctx == NULL) {
     536           0 :                 return PyErr_NoMemory();
     537             :         }
     538             : 
     539          48 :         if (!PyBytes_Check(py_in)) {
     540           0 :                 talloc_free(mem_ctx);
     541           0 :                 PyErr_Format(PyExc_TypeError, "bytes expected");
     542           0 :                 return NULL;
     543             :         }
     544          48 :         in.data = (uint8_t *)PyBytes_AsString(py_in);
     545          48 :         in.length = PyBytes_Size(py_in);
     546             : 
     547          48 :         status = gensec_wrap(security, mem_ctx, &in, &out);
     548             : 
     549          48 :         if (!NT_STATUS_IS_OK(status)) {
     550           0 :                 PyErr_SetNTSTATUS(status);
     551           0 :                 talloc_free(mem_ctx);
     552           0 :                 return NULL;
     553             :         }
     554             : 
     555          48 :         ret = PyBytes_FromStringAndSize((const char *)out.data, out.length);
     556          48 :         talloc_free(mem_ctx);
     557          48 :         return ret;
     558             : }
     559             : 
     560             : 
     561          48 : static PyObject *py_gensec_unwrap(PyObject *self, PyObject *args)
     562             : {
     563           0 :         NTSTATUS status;
     564             : 
     565           0 :         TALLOC_CTX *mem_ctx;
     566           0 :         DATA_BLOB in, out;
     567           0 :         PyObject *ret, *py_in;
     568          48 :         struct gensec_security *security = pytalloc_get_type(self, struct gensec_security);
     569          48 :         char *data = NULL;
     570           0 :         Py_ssize_t len;
     571           0 :         int err;
     572             : 
     573          48 :         if (!PyArg_ParseTuple(args, "O", &py_in))
     574           0 :                 return NULL;
     575             : 
     576          48 :         mem_ctx = talloc_new(NULL);
     577          48 :         if (mem_ctx == NULL) {
     578           0 :                 return PyErr_NoMemory();
     579             :         }
     580             : 
     581          48 :         err = PyBytes_AsStringAndSize(py_in, &data, &len);
     582          48 :         if (err) {
     583           0 :                 talloc_free(mem_ctx);
     584           0 :                 return NULL;
     585             :         }
     586             : 
     587             :         /*
     588             :          * Make a copy of the input buffer, as gensec_unwrap may modify its
     589             :          * input argument.
     590             :          */
     591          48 :         in = data_blob_talloc(mem_ctx, data, len);
     592          48 :         if (!in.data) {
     593           0 :                 talloc_free(mem_ctx);
     594           0 :                 return PyErr_NoMemory();
     595             :         }
     596             : 
     597          48 :         status = gensec_unwrap(security, mem_ctx, &in, &out);
     598             : 
     599          48 :         if (!NT_STATUS_IS_OK(status)) {
     600           0 :                 PyErr_SetNTSTATUS(status);
     601           0 :                 talloc_free(mem_ctx);
     602           0 :                 return NULL;
     603             :         }
     604             : 
     605          48 :         ret = PyBytes_FromStringAndSize((const char *)out.data, out.length);
     606          48 :         talloc_free(mem_ctx);
     607          48 :         return ret;
     608             : }
     609             : 
     610         396 : static PyObject *py_gensec_sig_size(PyObject *self, PyObject *args)
     611             : {
     612         396 :         struct gensec_security *security = pytalloc_get_type(self, struct gensec_security);
     613         396 :         Py_ssize_t data_size = 0;
     614         396 :         size_t sig_size = 0;
     615             : 
     616         396 :         if (!PyArg_ParseTuple(args, "n", &data_size)) {
     617           0 :                 return NULL;
     618             :         }
     619             : 
     620         396 :         sig_size = gensec_sig_size(security, data_size);
     621             : 
     622         396 :         return PyLong_FromSize_t(sig_size);
     623             : }
     624             : 
     625         407 : static PyObject *py_gensec_sign_packet(PyObject *self, PyObject *args)
     626             : {
     627           0 :         NTSTATUS status;
     628         407 :         TALLOC_CTX *mem_ctx = NULL;
     629         407 :         Py_ssize_t data_length = 0;
     630         407 :         Py_ssize_t pdu_length = 0;
     631           0 :         DATA_BLOB data, pdu, sig;
     632           0 :         PyObject *py_sig;
     633         407 :         struct gensec_security *security = pytalloc_get_type(self, struct gensec_security);
     634             : 
     635         407 :         if (!PyArg_ParseTuple(args, "z#z#", &data.data, &data_length, &pdu.data, &pdu_length)) {
     636           0 :                 return NULL;
     637             :         }
     638         407 :         data.length = data_length;
     639         407 :         pdu.length = pdu_length;
     640             : 
     641         407 :         mem_ctx = talloc_new(NULL);
     642         407 :         if (mem_ctx == NULL) {
     643           0 :                 return PyErr_NoMemory();
     644             :         }
     645             : 
     646         407 :         status = gensec_sign_packet(security, mem_ctx,
     647         407 :                                     data.data, data.length,
     648         407 :                                     pdu.data, pdu.length, &sig);
     649         407 :         if (!NT_STATUS_IS_OK(status)) {
     650           0 :                 PyErr_SetNTSTATUS(status);
     651           0 :                 talloc_free(mem_ctx);
     652           0 :                 return NULL;
     653             :         }
     654             : 
     655         407 :         py_sig = PyBytes_FromStringAndSize((const char *)sig.data, sig.length);
     656         407 :         talloc_free(mem_ctx);
     657         407 :         return py_sig;
     658             : }
     659             : 
     660         209 : static PyObject *py_gensec_check_packet(PyObject *self, PyObject *args)
     661             : {
     662           0 :         NTSTATUS status;
     663         209 :         Py_ssize_t data_length = 0;
     664         209 :         Py_ssize_t pdu_length = 0;
     665         209 :         Py_ssize_t sig_length = 0;
     666           0 :         DATA_BLOB data, pdu, sig;
     667         209 :         struct gensec_security *security = pytalloc_get_type(self, struct gensec_security);
     668             : 
     669         209 :         if (!PyArg_ParseTuple(args, "z#z#z#",
     670             :                               &data.data, &data_length,
     671             :                               &pdu.data, &pdu_length,
     672             :                               &sig.data, &sig_length)) {
     673           0 :                 return NULL;
     674             :         }
     675         209 :         data.length = data_length;
     676         209 :         pdu.length = pdu_length;
     677         209 :         sig.length = sig_length;
     678             : 
     679         209 :         status = gensec_check_packet(security,
     680         209 :                                      data.data, data.length,
     681         209 :                                      pdu.data, pdu.length, &sig);
     682         209 :         if (!NT_STATUS_IS_OK(status)) {
     683           0 :                 PyErr_SetNTSTATUS(status);
     684           0 :                 return NULL;
     685             :         }
     686             : 
     687         209 :         Py_RETURN_NONE;
     688             : }
     689             : 
     690             : static PyMethodDef py_gensec_security_methods[] = {
     691             :         { "start_client", PY_DISCARD_FUNC_SIG(PyCFunction,
     692             :                                               py_gensec_start_client),
     693             :                 METH_VARARGS|METH_KEYWORDS|METH_CLASS,
     694             :                 "S.start_client(settings) -> gensec" },
     695             :         { "start_server", PY_DISCARD_FUNC_SIG(PyCFunction,
     696             :                                               py_gensec_start_server),
     697             :                 METH_VARARGS|METH_KEYWORDS|METH_CLASS,
     698             :                 "S.start_server(auth_ctx, settings) -> gensec" },
     699             :         { "set_credentials", (PyCFunction)py_gensec_set_credentials, METH_VARARGS, 
     700             :                 "S.set_credentials(credentials)" },
     701             :         { "set_target_hostname", (PyCFunction)py_gensec_set_target_hostname, METH_VARARGS, 
     702             :                 "S.set_target_hostname(target_hostname) \n This sets the Kerberos target hostname to obtain a ticket for." },
     703             :         { "set_target_service", (PyCFunction)py_gensec_set_target_service, METH_VARARGS, 
     704             :                 "S.set_target_service(target_service) \n This sets the Kerberos target service to obtain a ticket for.  The default value is 'host'" },
     705             :         { "set_target_service_description", (PyCFunction)py_gensec_set_target_service_description, METH_VARARGS,
     706             :                 "S.set_target_service_description(target_service_description) \n This description is set server-side and used in authentication and authorization logs.  The default value is that provided to set_target_service() or None."},
     707             :         { "session_info", (PyCFunction)py_gensec_session_info, METH_NOARGS,
     708             :                 "S.session_info() -> info" },
     709             :         { "session_key", (PyCFunction)py_gensec_session_key, METH_NOARGS,
     710             :                 "S.session_key() -> key" },
     711             :         { "start_mech_by_name", (PyCFunction)py_gensec_start_mech_by_name, METH_VARARGS,
     712             :                 "S.start_mech_by_name(name)" },
     713             :         { "start_mech_by_sasl_name", (PyCFunction)py_gensec_start_mech_by_sasl_name, METH_VARARGS,
     714             :                 "S.start_mech_by_sasl_name(name)" },
     715             :         { "start_mech_by_authtype", (PyCFunction)py_gensec_start_mech_by_authtype, METH_VARARGS,
     716             :                 "S.start_mech_by_authtype(authtype, level)" },
     717             :         { "get_name_by_authtype", (PyCFunction)py_get_name_by_authtype, METH_VARARGS,
     718             :                 "S.get_name_by_authtype(authtype) -> name\nLookup an auth type." },
     719             :         { "want_feature", (PyCFunction)py_gensec_want_feature, METH_VARARGS,
     720             :                 "S.want_feature(feature)\n Request that GENSEC negotiate a particular feature." },
     721             :         { "have_feature", (PyCFunction)py_gensec_have_feature, METH_VARARGS,
     722             :                 "S.have_feature()\n Return True if GENSEC negotiated a particular feature." },
     723             :         { "set_max_update_size",  (PyCFunction)py_gensec_set_max_update_size, METH_VARARGS,
     724             :                 "S.set_max_update_size(max_size) \n Some mechs can fragment update packets, needs to be use before the mech is started." },
     725             :         { "max_update_size",  (PyCFunction)py_gensec_max_update_size, METH_NOARGS,
     726             :                 "S.max_update_size() \n Return the current max_update_size." },
     727             :         { "update",  (PyCFunction)py_gensec_update, METH_VARARGS,
     728             :                 "S.update(blob_in) -> (finished, blob_out)\nPerform one step in a GENSEC dance.  Repeat with new packets until finished is true or exception." },
     729             :         { "wrap",  (PyCFunction)py_gensec_wrap, METH_VARARGS,
     730             :                 "S.wrap(blob_in) -> blob_out\nPackage one clear packet into a wrapped GENSEC packet." },
     731             :         { "unwrap",  (PyCFunction)py_gensec_unwrap, METH_VARARGS,
     732             :                 "S.unwrap(blob_in) -> blob_out\nPerform one wrapped GENSEC packet into a clear packet." },
     733             :         { "sig_size",  (PyCFunction)py_gensec_sig_size, METH_VARARGS,
     734             :                 "S.sig_size(data_size) -> sig_size\nSize of the DCERPC packet signature" },
     735             :         { "sign_packet",  (PyCFunction)py_gensec_sign_packet, METH_VARARGS,
     736             :                 "S.sign_packet(data, whole_pdu) -> sig\nSign a DCERPC packet." },
     737             :         { "check_packet",  (PyCFunction)py_gensec_check_packet, METH_VARARGS,
     738             :                 "S.check_packet(data, whole_pdu, sig)\nCheck a DCERPC packet." },
     739             :         {0}
     740             : };
     741             : 
     742             : static struct PyModuleDef moduledef = {
     743             :     PyModuleDef_HEAD_INIT,
     744             :     .m_name = "gensec",
     745             :     .m_doc = "Generic Security Interface.",
     746             :     .m_size = -1,
     747             : };
     748             : 
     749             : static PyTypeObject Py_Security = {
     750             :         .tp_name = "gensec.Security",
     751             :         .tp_flags = Py_TPFLAGS_DEFAULT,
     752             :         .tp_methods = py_gensec_security_methods,
     753             : };
     754             : 
     755        3178 : MODULE_INIT_FUNC(gensec)
     756             : {
     757         132 :         PyObject *m;
     758             : 
     759        3178 :         if (pytalloc_BaseObject_PyType_Ready(&Py_Security) < 0)
     760           0 :                 return NULL;
     761             : 
     762        3178 :         m = PyModule_Create(&moduledef);
     763        3178 :         if (m == NULL)
     764           0 :                 return NULL;
     765             : 
     766        3178 :         PyModule_AddObject(m, "FEATURE_SESSION_KEY",     PyLong_FromLong(GENSEC_FEATURE_SESSION_KEY));
     767        3178 :         PyModule_AddObject(m, "FEATURE_SIGN",            PyLong_FromLong(GENSEC_FEATURE_SIGN));
     768        3178 :         PyModule_AddObject(m, "FEATURE_SEAL",            PyLong_FromLong(GENSEC_FEATURE_SEAL));
     769        3178 :         PyModule_AddObject(m, "FEATURE_DCE_STYLE",       PyLong_FromLong(GENSEC_FEATURE_DCE_STYLE));
     770        3178 :         PyModule_AddObject(m, "FEATURE_ASYNC_REPLIES",   PyLong_FromLong(GENSEC_FEATURE_ASYNC_REPLIES));
     771        3178 :         PyModule_AddObject(m, "FEATURE_DATAGRAM_MODE",   PyLong_FromLong(GENSEC_FEATURE_DATAGRAM_MODE));
     772        3178 :         PyModule_AddObject(m, "FEATURE_SIGN_PKT_HEADER", PyLong_FromLong(GENSEC_FEATURE_SIGN_PKT_HEADER));
     773        3178 :         PyModule_AddObject(m, "FEATURE_NEW_SPNEGO",      PyLong_FromLong(GENSEC_FEATURE_NEW_SPNEGO));
     774             : 
     775        2462 :         Py_INCREF(&Py_Security);
     776        3178 :         PyModule_AddObject(m, "Security", (PyObject *)&Py_Security);
     777             : 
     778        3178 :         return m;
     779             : }

Generated by: LCOV version 1.14