Ignore:
Timestamp:
Nov 27, 2012, 4:43:17 PM (13 years ago)
Author:
Silvan Scherrer
Message:

Samba Server: updated trunk to 3.6.0

Location:
trunk/server
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/server

  • trunk/server/source4/auth/gensec/pygensec.c

    r414 r745  
    1717*/
    1818
     19#include <Python.h>
    1920#include "includes.h"
    20 #include <Python.h>
    21 #include "param/param.h"
     21#include "param/pyparam.h"
    2222#include "auth/gensec/gensec.h"
     23#include "auth/credentials/pycredentials.h"
    2324#include "libcli/util/pyerrors.h"
    24 #include "pytalloc.h"
     25#include "scripting/python/modules.h"
     26#include "lib/talloc/pytalloc.h"
    2527#include <tevent.h>
    26 
    27 #ifndef Py_RETURN_NONE
    28 #define Py_RETURN_NONE return Py_INCREF(Py_None), Py_None
    29 #endif
     28#include "librpc/rpc/pyrpc_util.h"
    3029
    3130static PyObject *py_get_name_by_authtype(PyObject *self, PyObject *args)
     
    3837                return NULL;
    3938
    40         security = (struct gensec_security *)py_talloc_get_ptr(self);
     39        security = py_talloc_get_type(self, struct gensec_security);
    4140
    4241        name = gensec_get_name_by_authtype(security, type);
     
    4746}
    4847
    49 static struct gensec_settings *settings_from_object(PyObject *object)
    50 {
    51         return NULL; /* FIXME */
     48static struct gensec_settings *settings_from_object(TALLOC_CTX *mem_ctx, PyObject *object)
     49{
     50        struct gensec_settings *s;
     51        PyObject *py_hostname, *py_lp_ctx;
     52
     53        if (!PyDict_Check(object)) {
     54                PyErr_SetString(PyExc_ValueError, "settings should be a dictionary");
     55                return NULL;
     56        }
     57
     58        s = talloc_zero(mem_ctx, struct gensec_settings);
     59        if (!s) return NULL;
     60
     61        py_hostname = PyDict_GetItemString(object, "target_hostname");
     62        if (!py_hostname) {
     63                PyErr_SetString(PyExc_ValueError, "settings.target_hostname not found");
     64                return NULL;
     65        }
     66
     67        py_lp_ctx = PyDict_GetItemString(object, "lp_ctx");
     68        if (!py_lp_ctx) {
     69                PyErr_SetString(PyExc_ValueError, "settings.lp_ctx not found");
     70                return NULL;
     71        }
     72
     73        s->target_hostname = PyString_AsString(py_hostname);
     74        s->lp_ctx = lpcfg_from_py_object(s, py_lp_ctx);
     75        return s;
    5276}
    5377
     
    6084        PyObject *py_settings;
    6185        struct tevent_context *ev;
    62 
    63         if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O", kwnames, &py_settings))
    64                 return NULL;
    65 
    66         settings = settings_from_object(py_settings);
    67         if (settings == NULL)
    68                 return NULL;
    69        
     86        struct gensec_security *gensec;
     87
     88        if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O", discard_const_p(char *, kwnames), &py_settings))
     89                return NULL;
     90
    7091        self = (py_talloc_Object*)type->tp_alloc(type, 0);
    7192        if (self == NULL) {
     
    7899                return NULL;
    79100        }
     101
     102        if (py_settings != Py_None) {
     103                settings = settings_from_object(self->talloc_ctx, py_settings);
     104                if (settings == NULL) {
     105                        PyObject_DEL(self);
     106                        return NULL;
     107                }
     108        } else {
     109                settings = talloc_zero(self->talloc_ctx, struct gensec_settings);
     110                if (settings == NULL) {
     111                        PyObject_DEL(self);
     112                        return NULL;
     113                }
     114
     115                settings->lp_ctx = loadparm_init_global(true);
     116        }
     117
    80118        ev = tevent_context_init(self->talloc_ctx);
    81119        if (ev == NULL) {
     
    84122                return NULL;
    85123        }
    86         status = gensec_client_start(self->talloc_ctx,
    87                 (struct gensec_security **)&self->ptr, ev, settings);
     124
     125        status = gensec_init(settings->lp_ctx);
    88126        if (!NT_STATUS_IS_OK(status)) {
    89127                PyErr_SetNTSTATUS(status);
     
    91129                return NULL;
    92130        }
     131
     132        status = gensec_client_start(self->talloc_ctx, &gensec, ev, settings);
     133        if (!NT_STATUS_IS_OK(status)) {
     134                PyErr_SetNTSTATUS(status);
     135                PyObject_DEL(self);
     136                return NULL;
     137        }
     138
     139        self->ptr = gensec;
     140
    93141        return (PyObject *)self;
    94142}
    95143
     144static PyObject *py_gensec_start_server(PyTypeObject *type, PyObject *args, PyObject *kwargs)
     145{
     146        NTSTATUS status;
     147        py_talloc_Object *self;
     148        struct gensec_settings *settings = NULL;
     149        const char *kwnames[] = { "settings", "auth_context", NULL };
     150        PyObject *py_settings = Py_None;
     151        PyObject *py_auth_context = Py_None;
     152        struct tevent_context *ev;
     153        struct gensec_security *gensec;
     154        struct auth_context *auth_context = NULL;
     155
     156        if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OO", discard_const_p(char *, kwnames), &py_settings, &py_auth_context))
     157                return NULL;
     158
     159        self = (py_talloc_Object*)type->tp_alloc(type, 0);
     160        if (self == NULL) {
     161                PyErr_NoMemory();
     162                return NULL;
     163        }
     164        self->talloc_ctx = talloc_new(NULL);
     165        if (self->talloc_ctx == NULL) {
     166                PyErr_NoMemory();
     167                return NULL;
     168        }
     169
     170        if (py_settings != Py_None) {
     171                settings = settings_from_object(self->talloc_ctx, py_settings);
     172                if (settings == NULL) {
     173                        PyObject_DEL(self);
     174                        return NULL;
     175                }
     176        } else {
     177                settings = talloc_zero(self->talloc_ctx, struct gensec_settings);
     178                if (settings == NULL) {
     179                        PyObject_DEL(self);
     180                        return NULL;
     181                }
     182
     183                settings->lp_ctx = loadparm_init_global(true);
     184        }
     185
     186        ev = tevent_context_init(self->talloc_ctx);
     187        if (ev == NULL) {
     188                PyErr_NoMemory();
     189                PyObject_Del(self);
     190                return NULL;
     191        }
     192
     193        if (py_auth_context != Py_None) {
     194                auth_context = py_talloc_get_type(py_auth_context, struct auth_context);
     195                if (!auth_context) {
     196                        PyErr_Format(PyExc_TypeError,
     197                                     "Expected auth.AuthContext for auth_context argument, got %s",
     198                                     talloc_get_name(py_talloc_get_ptr(py_auth_context)));
     199                        return NULL;
     200                }
     201        }
     202
     203        status = gensec_init(settings->lp_ctx);
     204        if (!NT_STATUS_IS_OK(status)) {
     205                PyErr_SetNTSTATUS(status);
     206                PyObject_DEL(self);
     207                return NULL;
     208        }
     209
     210        status = gensec_server_start(self->talloc_ctx, ev, settings, auth_context, &gensec);
     211        if (!NT_STATUS_IS_OK(status)) {
     212                PyErr_SetNTSTATUS(status);
     213                PyObject_DEL(self);
     214                return NULL;
     215        }
     216
     217        self->ptr = gensec;
     218
     219        return (PyObject *)self;
     220}
     221
     222static PyObject *py_gensec_set_credentials(PyObject *self, PyObject *args)
     223{
     224        PyObject *py_creds = Py_None;
     225        struct cli_credentials *creds;
     226        struct gensec_security *security = py_talloc_get_type(self, struct gensec_security);
     227        NTSTATUS status;
     228
     229        if (!PyArg_ParseTuple(args, "O", &py_creds))
     230                return NULL;
     231
     232        creds = PyCredentials_AsCliCredentials(py_creds);
     233        if (!creds) {
     234                PyErr_Format(PyExc_TypeError,
     235                             "Expected samba.credentaials for credentials argument got  %s",
     236                             talloc_get_name(py_talloc_get_ptr(py_creds)));
     237        }
     238
     239        status = gensec_set_credentials(security, creds);
     240        if (!NT_STATUS_IS_OK(status)) {
     241                PyErr_SetNTSTATUS(status);
     242                return NULL;
     243        }
     244
     245        Py_RETURN_NONE;
     246}
     247
    96248static PyObject *py_gensec_session_info(PyObject *self)
    97249{
    98250        NTSTATUS status;
    99         struct gensec_security *security = (struct gensec_security *)py_talloc_get_ptr(self);
     251        PyObject *py_session_info;
     252        struct gensec_security *security = py_talloc_get_type(self, struct gensec_security);
    100253        struct auth_session_info *info;
     254        if (security->ops == NULL) {
     255                PyErr_SetString(PyExc_RuntimeError, "no mechanism selected");
     256                return NULL;
     257        }
    101258        status = gensec_session_info(security, &info);
    102259        if (NT_STATUS_IS_ERR(status)) {
     
    105262        }
    106263
    107         /* FIXME */
     264        py_session_info = py_return_ndr_struct("samba.auth", "AuthSession",
     265                                                 info, info);
     266        return py_session_info;
     267}
     268
     269static PyObject *py_gensec_start_mech_by_name(PyObject *self, PyObject *args)
     270{
     271        char *name;
     272        struct gensec_security *security = py_talloc_get_type(self, struct gensec_security);
     273        NTSTATUS status;
     274
     275        if (!PyArg_ParseTuple(args, "s", &name))
     276                return NULL;
     277
     278        status = gensec_start_mech_by_name(security, name);
     279        if (!NT_STATUS_IS_OK(status)) {
     280                PyErr_SetNTSTATUS(status);
     281                return NULL;
     282        }
     283
    108284        Py_RETURN_NONE;
     285}
     286
     287static PyObject *py_gensec_start_mech_by_sasl_name(PyObject *self, PyObject *args)
     288{
     289        char *sasl_name;
     290        struct gensec_security *security = py_talloc_get_type(self, struct gensec_security);
     291        NTSTATUS status;
     292
     293        if (!PyArg_ParseTuple(args, "s", &sasl_name))
     294                return NULL;
     295
     296        status = gensec_start_mech_by_sasl_name(security, sasl_name);
     297        if (!NT_STATUS_IS_OK(status)) {
     298                PyErr_SetNTSTATUS(status);
     299                return NULL;
     300        }
     301
     302        Py_RETURN_NONE;
     303}
     304
     305static PyObject *py_gensec_start_mech_by_authtype(PyObject *self, PyObject *args)
     306{
     307        int authtype, level;
     308        struct gensec_security *security = py_talloc_get_type(self, struct gensec_security);
     309        NTSTATUS status;
     310        if (!PyArg_ParseTuple(args, "ii", &authtype, &level))
     311                return NULL;
     312
     313        status = gensec_start_mech_by_authtype(security, authtype, level);
     314        if (!NT_STATUS_IS_OK(status)) {
     315                PyErr_SetNTSTATUS(status);
     316                return NULL;
     317        }
     318
     319        Py_RETURN_NONE;
     320}
     321
     322static PyObject *py_gensec_want_feature(PyObject *self, PyObject *args)
     323{
     324        int feature;
     325        struct gensec_security *security = py_talloc_get_type(self, struct gensec_security);
     326        /* This is i (and declared as an int above) by design, as they are handled as an integer in python */
     327        if (!PyArg_ParseTuple(args, "i", &feature))
     328                return NULL;
     329
     330        gensec_want_feature(security, feature);
     331
     332        Py_RETURN_NONE;
     333}
     334
     335static PyObject *py_gensec_have_feature(PyObject *self, PyObject *args)
     336{
     337        int feature;
     338        struct gensec_security *security = py_talloc_get_type(self, struct gensec_security);
     339        /* This is i (and declared as an int above) by design, as they are handled as an integer in python */
     340        if (!PyArg_ParseTuple(args, "i", &feature))
     341                return NULL;
     342
     343        if (gensec_have_feature(security, feature)) {
     344                return Py_True;
     345        }
     346        return Py_False;
     347}
     348
     349static PyObject *py_gensec_update(PyObject *self, PyObject *args)
     350{
     351        NTSTATUS status;
     352        TALLOC_CTX *mem_ctx;
     353        DATA_BLOB in, out;
     354        PyObject *ret, *py_in;
     355        struct gensec_security *security = py_talloc_get_type(self, struct gensec_security);
     356        PyObject *finished_processing;
     357
     358        if (!PyArg_ParseTuple(args, "O", &py_in))
     359                return NULL;
     360
     361        mem_ctx = talloc_new(NULL);
     362
     363        if (!PyString_Check(py_in)) {
     364                PyErr_Format(PyExc_TypeError, "expected a string");
     365                return NULL;
     366        }
     367
     368        in.data = (uint8_t *)PyString_AsString(py_in);
     369        in.length = PyString_Size(py_in);
     370
     371        status = gensec_update(security, mem_ctx, in, &out);
     372
     373        if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)
     374            && !NT_STATUS_IS_OK(status)) {
     375                PyErr_SetNTSTATUS(status);
     376                talloc_free(mem_ctx);
     377                return NULL;
     378        }
     379        ret = PyString_FromStringAndSize((const char *)out.data, out.length);
     380        talloc_free(mem_ctx);
     381
     382        if (NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
     383                finished_processing = Py_False;
     384        } else {
     385                finished_processing = Py_True;
     386        }
     387
     388        return PyTuple_Pack(2, finished_processing, ret);
     389}
     390
     391static PyObject *py_gensec_wrap(PyObject *self, PyObject *args)
     392{
     393        NTSTATUS status;
     394
     395        TALLOC_CTX *mem_ctx;
     396        DATA_BLOB in, out;
     397        PyObject *ret, *py_in;
     398        struct gensec_security *security = py_talloc_get_type(self, struct gensec_security);
     399
     400        if (!PyArg_ParseTuple(args, "O", &py_in))
     401                return NULL;
     402
     403        mem_ctx = talloc_new(NULL);
     404
     405        if (!PyString_Check(py_in)) {
     406                PyErr_Format(PyExc_TypeError, "expected a string");
     407                return NULL;
     408        }
     409        in.data = (uint8_t *)PyString_AsString(py_in);
     410        in.length = PyString_Size(py_in);
     411
     412        status = gensec_wrap(security, mem_ctx, &in, &out);
     413
     414        if (!NT_STATUS_IS_OK(status)) {
     415                PyErr_SetNTSTATUS(status);
     416                talloc_free(mem_ctx);
     417                return NULL;
     418        }
     419
     420        ret = PyString_FromStringAndSize((const char *)out.data, out.length);
     421        talloc_free(mem_ctx);
     422        return ret;
     423}
     424
     425static PyObject *py_gensec_unwrap(PyObject *self, PyObject *args)
     426{
     427        NTSTATUS status;
     428
     429        TALLOC_CTX *mem_ctx;
     430        DATA_BLOB in, out;
     431        PyObject *ret, *py_in;
     432        struct gensec_security *security = py_talloc_get_type(self, struct gensec_security);
     433
     434        if (!PyArg_ParseTuple(args, "O", &py_in))
     435                return NULL;
     436
     437        mem_ctx = talloc_new(NULL);
     438
     439        if (!PyString_Check(py_in)) {
     440                PyErr_Format(PyExc_TypeError, "expected a string");
     441                return NULL;
     442        }
     443
     444        in.data = (uint8_t *)PyString_AsString(py_in);
     445        in.length = PyString_Size(py_in);
     446
     447        status = gensec_unwrap(security, mem_ctx, &in, &out);
     448
     449        if (!NT_STATUS_IS_OK(status)) {
     450                PyErr_SetNTSTATUS(status);
     451                talloc_free(mem_ctx);
     452                return NULL;
     453        }
     454
     455        ret = PyString_FromStringAndSize((const char *)out.data, out.length);
     456        talloc_free(mem_ctx);
     457        return ret;
    109458}
    110459
     
    112461        { "start_client", (PyCFunction)py_gensec_start_client, METH_VARARGS|METH_KEYWORDS|METH_CLASS,
    113462                "S.start_client(settings) -> gensec" },
    114 /*      { "start_server", (PyCFunction)py_gensec_start_server, METH_VARARGS|METH_KEYWORDS|METH_CLASS,
    115                 "S.start_server(auth_ctx, settings) -> gensec" },*/
     463        { "start_server", (PyCFunction)py_gensec_start_server, METH_VARARGS|METH_KEYWORDS|METH_CLASS,
     464                "S.start_server(auth_ctx, settings) -> gensec" },
     465        { "set_credentials", (PyCFunction)py_gensec_set_credentials, METH_VARARGS,
     466                "S.start_client(credentials)" },
    116467        { "session_info", (PyCFunction)py_gensec_session_info, METH_NOARGS,
    117                 "S.session_info() -> info" },
     468                "S.session_info() -> info" },
     469        { "start_mech_by_name", (PyCFunction)py_gensec_start_mech_by_name, METH_VARARGS,
     470        "S.start_mech_by_name(name)" },
     471        { "start_mech_by_sasl_name", (PyCFunction)py_gensec_start_mech_by_sasl_name, METH_VARARGS,
     472        "S.start_mech_by_sasl_name(name)" },
     473        { "start_mech_by_authtype", (PyCFunction)py_gensec_start_mech_by_authtype, METH_VARARGS, "S.start_mech_by_authtype(authtype, level)" },
    118474        { "get_name_by_authtype", (PyCFunction)py_get_name_by_authtype, METH_VARARGS,
    119475                "S.get_name_by_authtype(authtype) -> name\nLookup an auth type." },
     476        { "want_feature", (PyCFunction)py_gensec_want_feature, METH_VARARGS,
     477          "S.want_feature(feature)\n Request that GENSEC negotiate a particular feature." },
     478        { "have_feature", (PyCFunction)py_gensec_have_feature, METH_VARARGS,
     479          "S.have_feature()\n Return True if GENSEC negotiated a particular feature." },
     480        { "update",  (PyCFunction)py_gensec_update, METH_VARARGS,
     481                "S.update(blob_in) -> (finished, blob_out)\nPerform one step in a GENSEC dance.  Repeat with new packets until finished is true or exception." },
     482        { "wrap",  (PyCFunction)py_gensec_wrap, METH_VARARGS,
     483                "S.wrap(blob_in) -> blob_out\nPackage one clear packet into a wrapped GENSEC packet." },
     484        { "unwrap",  (PyCFunction)py_gensec_unwrap, METH_VARARGS,
     485                "S.unwrap(blob_in) -> blob_out\nPerform one wrapped GENSEC packet into a clear packet." },
     486
    120487        { NULL }
    121488};
     
    126493        .tp_methods = py_gensec_security_methods,
    127494        .tp_basicsize = sizeof(py_talloc_Object),
    128         .tp_dealloc = py_talloc_dealloc,
    129495};
    130496
     497void initgensec(void);
    131498void initgensec(void)
    132499{
    133500        PyObject *m;
     501
     502        Py_Security.tp_base = PyTalloc_GetObjectType();
     503        if (Py_Security.tp_base == NULL)
     504                return;
    134505
    135506        if (PyType_Ready(&Py_Security) < 0)
     
    140511                return;
    141512
     513        PyModule_AddObject(m, "FEATURE_SESSION_KEY",     PyInt_FromLong(GENSEC_FEATURE_SESSION_KEY));
     514        PyModule_AddObject(m, "FEATURE_SIGN",            PyInt_FromLong(GENSEC_FEATURE_SIGN));
     515        PyModule_AddObject(m, "FEATURE_SEAL",            PyInt_FromLong(GENSEC_FEATURE_SEAL));
     516        PyModule_AddObject(m, "FEATURE_DCE_STYLE",       PyInt_FromLong(GENSEC_FEATURE_DCE_STYLE));
     517        PyModule_AddObject(m, "FEATURE_ASYNC_REPLIES",   PyInt_FromLong(GENSEC_FEATURE_ASYNC_REPLIES));
     518        PyModule_AddObject(m, "FEATURE_DATAGRAM_MODE",   PyInt_FromLong(GENSEC_FEATURE_DATAGRAM_MODE));
     519        PyModule_AddObject(m, "FEATURE_SIGN_PKT_HEADER", PyInt_FromLong(GENSEC_FEATURE_SIGN_PKT_HEADER));
     520        PyModule_AddObject(m, "FEATURE_NEW_SPNEGO",      PyInt_FromLong(GENSEC_FEATURE_NEW_SPNEGO));
     521
    142522        Py_INCREF(&Py_Security);
    143523        PyModule_AddObject(m, "Security", (PyObject *)&Py_Security);
Note: See TracChangeset for help on using the changeset viewer.