kerberos.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465
  1. /**
  2. * Copyright (c) 2006-2009 Apple Inc. All rights reserved.
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. **/
  16. #include <Python.h>
  17. #include "kerberosbasic.h"
  18. #include "kerberospw.h"
  19. #include "kerberosgss.h"
  20. PyObject *KrbException_class;
  21. PyObject *BasicAuthException_class;
  22. PyObject *PwdChangeException_class;
  23. PyObject *GssException_class;
  24. static PyObject *checkPassword(PyObject *self, PyObject *args)
  25. {
  26. const char *user;
  27. const char *pswd;
  28. const char *service;
  29. const char *default_realm;
  30. int result = 0;
  31. if (!PyArg_ParseTuple(args, "ssss", &user, &pswd, &service, &default_realm))
  32. return NULL;
  33. result = authenticate_user_krb5pwd(user, pswd, service, default_realm);
  34. if (result)
  35. return Py_INCREF(Py_True), Py_True;
  36. else
  37. return NULL;
  38. }
  39. static PyObject *changePassword(PyObject *self, PyObject *args)
  40. {
  41. const char *newpswd, *oldpswd;
  42. const char *user;
  43. int result = 0;
  44. if (!PyArg_ParseTuple(args, "sss", &user, &oldpswd, &newpswd))
  45. return NULL;
  46. result = change_user_krb5pwd(user, oldpswd, newpswd);
  47. if (result)
  48. return Py_INCREF(Py_True), Py_True;
  49. else
  50. return NULL;
  51. }
  52. static PyObject *getServerPrincipalDetails(PyObject *self, PyObject *args)
  53. {
  54. const char *service;
  55. const char *hostname;
  56. char* result;
  57. if (!PyArg_ParseTuple(args, "ss", &service, &hostname))
  58. return NULL;
  59. result = server_principal_details(service, hostname);
  60. if (result != NULL)
  61. {
  62. PyObject* pyresult = Py_BuildValue("s", result);
  63. free(result);
  64. return pyresult;
  65. }
  66. else
  67. return NULL;
  68. }
  69. static PyObject* authGSSClientInit(PyObject* self, PyObject* args, PyObject* keywds)
  70. {
  71. const char *service;
  72. gss_client_state *state;
  73. PyObject *pystate;
  74. static char *kwlist[] = {"service", "gssflags", NULL};
  75. long int gss_flags = GSS_C_MUTUAL_FLAG | GSS_C_SEQUENCE_FLAG;
  76. int result = 0;
  77. if (!PyArg_ParseTupleAndKeywords(args, keywds, "s|l", kwlist, &service, &gss_flags))
  78. return NULL;
  79. state = (gss_client_state *) malloc(sizeof(gss_client_state));
  80. pystate = PyCObject_FromVoidPtr(state, NULL);
  81. result = authenticate_gss_client_init(service, gss_flags, state);
  82. if (result == AUTH_GSS_ERROR)
  83. return NULL;
  84. return Py_BuildValue("(iO)", result, pystate);
  85. }
  86. static PyObject *authGSSClientClean(PyObject *self, PyObject *args)
  87. {
  88. gss_client_state *state;
  89. PyObject *pystate;
  90. int result = 0;
  91. if (!PyArg_ParseTuple(args, "O", &pystate))
  92. return NULL;
  93. if (!PyCObject_Check(pystate)) {
  94. PyErr_SetString(PyExc_TypeError, "Expected a context object");
  95. return NULL;
  96. }
  97. state = (gss_client_state *)PyCObject_AsVoidPtr(pystate);
  98. if (state != NULL)
  99. {
  100. result = authenticate_gss_client_clean(state);
  101. free(state);
  102. PyCObject_SetVoidPtr(pystate, NULL);
  103. }
  104. return Py_BuildValue("i", result);
  105. }
  106. static PyObject *authGSSClientStep(PyObject *self, PyObject *args)
  107. {
  108. gss_client_state *state;
  109. PyObject *pystate;
  110. char *challenge;
  111. int result = 0;
  112. if (!PyArg_ParseTuple(args, "Os", &pystate, &challenge))
  113. return NULL;
  114. if (!PyCObject_Check(pystate)) {
  115. PyErr_SetString(PyExc_TypeError, "Expected a context object");
  116. return NULL;
  117. }
  118. state = (gss_client_state *)PyCObject_AsVoidPtr(pystate);
  119. if (state == NULL)
  120. return NULL;
  121. result = authenticate_gss_client_step(state, challenge);
  122. if (result == AUTH_GSS_ERROR)
  123. return NULL;
  124. return Py_BuildValue("i", result);
  125. }
  126. static PyObject *authGSSClientResponse(PyObject *self, PyObject *args)
  127. {
  128. gss_client_state *state;
  129. PyObject *pystate;
  130. if (!PyArg_ParseTuple(args, "O", &pystate))
  131. return NULL;
  132. if (!PyCObject_Check(pystate)) {
  133. PyErr_SetString(PyExc_TypeError, "Expected a context object");
  134. return NULL;
  135. }
  136. state = (gss_client_state *)PyCObject_AsVoidPtr(pystate);
  137. if (state == NULL)
  138. return NULL;
  139. return Py_BuildValue("s", state->response);
  140. }
  141. static PyObject *authGSSClientUserName(PyObject *self, PyObject *args)
  142. {
  143. gss_client_state *state;
  144. PyObject *pystate;
  145. if (!PyArg_ParseTuple(args, "O", &pystate))
  146. return NULL;
  147. if (!PyCObject_Check(pystate)) {
  148. PyErr_SetString(PyExc_TypeError, "Expected a context object");
  149. return NULL;
  150. }
  151. state = (gss_client_state *)PyCObject_AsVoidPtr(pystate);
  152. if (state == NULL)
  153. return NULL;
  154. return Py_BuildValue("s", state->username);
  155. }
  156. static PyObject *authGSSClientUnwrap(PyObject *self, PyObject *args)
  157. {
  158. gss_client_state *state;
  159. PyObject *pystate;
  160. char *challenge;
  161. int result = 0;
  162. if (!PyArg_ParseTuple(args, "Os", &pystate, &challenge))
  163. return NULL;
  164. if (!PyCObject_Check(pystate)) {
  165. PyErr_SetString(PyExc_TypeError, "Expected a context object");
  166. return NULL;
  167. }
  168. state = (gss_client_state *)PyCObject_AsVoidPtr(pystate);
  169. if (state == NULL)
  170. return NULL;
  171. result = authenticate_gss_client_unwrap(state, challenge);
  172. if (result == AUTH_GSS_ERROR)
  173. return NULL;
  174. return Py_BuildValue("i", result);
  175. }
  176. static PyObject *authGSSClientWrap(PyObject *self, PyObject *args)
  177. {
  178. gss_client_state *state;
  179. PyObject *pystate;
  180. char *challenge, *user = NULL;
  181. int result = 0;
  182. if (!PyArg_ParseTuple(args, "Os|z", &pystate, &challenge, &user))
  183. return NULL;
  184. if (!PyCObject_Check(pystate)) {
  185. PyErr_SetString(PyExc_TypeError, "Expected a context object");
  186. return NULL;
  187. }
  188. state = (gss_client_state *)PyCObject_AsVoidPtr(pystate);
  189. if (state == NULL)
  190. return NULL;
  191. result = authenticate_gss_client_wrap(state, challenge, user);
  192. if (result == AUTH_GSS_ERROR)
  193. return NULL;
  194. return Py_BuildValue("i", result);
  195. }
  196. static PyObject *authGSSServerInit(PyObject *self, PyObject *args)
  197. {
  198. const char *service;
  199. gss_server_state *state;
  200. PyObject *pystate;
  201. int result = 0;
  202. if (!PyArg_ParseTuple(args, "s", &service))
  203. return NULL;
  204. state = (gss_server_state *) malloc(sizeof(gss_server_state));
  205. pystate = PyCObject_FromVoidPtr(state, NULL);
  206. result = authenticate_gss_server_init(service, state);
  207. if (result == AUTH_GSS_ERROR)
  208. return NULL;
  209. return Py_BuildValue("(iO)", result, pystate);
  210. }
  211. static PyObject *authGSSServerClean(PyObject *self, PyObject *args)
  212. {
  213. gss_server_state *state;
  214. PyObject *pystate;
  215. int result = 0;
  216. if (!PyArg_ParseTuple(args, "O", &pystate))
  217. return NULL;
  218. if (!PyCObject_Check(pystate)) {
  219. PyErr_SetString(PyExc_TypeError, "Expected a context object");
  220. return NULL;
  221. }
  222. state = (gss_server_state *)PyCObject_AsVoidPtr(pystate);
  223. if (state != NULL)
  224. {
  225. result = authenticate_gss_server_clean(state);
  226. free(state);
  227. PyCObject_SetVoidPtr(pystate, NULL);
  228. }
  229. return Py_BuildValue("i", result);
  230. }
  231. static PyObject *authGSSServerStep(PyObject *self, PyObject *args)
  232. {
  233. gss_server_state *state;
  234. PyObject *pystate;
  235. char *challenge;
  236. int result = 0;
  237. if (!PyArg_ParseTuple(args, "Os", &pystate, &challenge))
  238. return NULL;
  239. if (!PyCObject_Check(pystate)) {
  240. PyErr_SetString(PyExc_TypeError, "Expected a context object");
  241. return NULL;
  242. }
  243. state = (gss_server_state *)PyCObject_AsVoidPtr(pystate);
  244. if (state == NULL)
  245. return NULL;
  246. result = authenticate_gss_server_step(state, challenge);
  247. if (result == AUTH_GSS_ERROR)
  248. return NULL;
  249. return Py_BuildValue("i", result);
  250. }
  251. static PyObject *authGSSServerResponse(PyObject *self, PyObject *args)
  252. {
  253. gss_server_state *state;
  254. PyObject *pystate;
  255. if (!PyArg_ParseTuple(args, "O", &pystate))
  256. return NULL;
  257. if (!PyCObject_Check(pystate)) {
  258. PyErr_SetString(PyExc_TypeError, "Expected a context object");
  259. return NULL;
  260. }
  261. state = (gss_server_state *)PyCObject_AsVoidPtr(pystate);
  262. if (state == NULL)
  263. return NULL;
  264. return Py_BuildValue("s", state->response);
  265. }
  266. static PyObject *authGSSServerUserName(PyObject *self, PyObject *args)
  267. {
  268. gss_server_state *state;
  269. PyObject *pystate;
  270. if (!PyArg_ParseTuple(args, "O", &pystate))
  271. return NULL;
  272. if (!PyCObject_Check(pystate)) {
  273. PyErr_SetString(PyExc_TypeError, "Expected a context object");
  274. return NULL;
  275. }
  276. state = (gss_server_state *)PyCObject_AsVoidPtr(pystate);
  277. if (state == NULL)
  278. return NULL;
  279. return Py_BuildValue("s", state->username);
  280. }
  281. static PyObject *authGSSServerTargetName(PyObject *self, PyObject *args)
  282. {
  283. gss_server_state *state;
  284. PyObject *pystate;
  285. if (!PyArg_ParseTuple(args, "O", &pystate))
  286. return NULL;
  287. if (!PyCObject_Check(pystate)) {
  288. PyErr_SetString(PyExc_TypeError, "Expected a context object");
  289. return NULL;
  290. }
  291. state = (gss_server_state *)PyCObject_AsVoidPtr(pystate);
  292. if (state == NULL)
  293. return NULL;
  294. return Py_BuildValue("s", state->targetname);
  295. }
  296. static PyMethodDef KerberosMethods[] = {
  297. {"checkPassword", checkPassword, METH_VARARGS,
  298. "Check the supplied user/password against Kerberos KDC."},
  299. {"changePassword", changePassword, METH_VARARGS,
  300. "Change the user password."},
  301. {"getServerPrincipalDetails", getServerPrincipalDetails, METH_VARARGS,
  302. "Return the service principal for a given service and hostname."},
  303. {"authGSSClientInit", (PyCFunction)authGSSClientInit, METH_VARARGS | METH_KEYWORDS,
  304. "Initialize client-side GSSAPI operations."},
  305. {"authGSSClientClean", authGSSClientClean, METH_VARARGS,
  306. "Terminate client-side GSSAPI operations."},
  307. {"authGSSClientStep", authGSSClientStep, METH_VARARGS,
  308. "Do a client-side GSSAPI step."},
  309. {"authGSSClientResponse", authGSSClientResponse, METH_VARARGS,
  310. "Get the response from the last client-side GSSAPI step."},
  311. {"authGSSClientUserName", authGSSClientUserName, METH_VARARGS,
  312. "Get the user name from the last client-side GSSAPI step."},
  313. {"authGSSServerInit", authGSSServerInit, METH_VARARGS,
  314. "Initialize server-side GSSAPI operations."},
  315. {"authGSSClientWrap", authGSSClientWrap, METH_VARARGS,
  316. "Do a GSSAPI wrap."},
  317. {"authGSSClientUnwrap", authGSSClientUnwrap, METH_VARARGS,
  318. "Do a GSSAPI unwrap."},
  319. {"authGSSServerClean", authGSSServerClean, METH_VARARGS,
  320. "Terminate server-side GSSAPI operations."},
  321. {"authGSSServerStep", authGSSServerStep, METH_VARARGS,
  322. "Do a server-side GSSAPI step."},
  323. {"authGSSServerResponse", authGSSServerResponse, METH_VARARGS,
  324. "Get the response from the last server-side GSSAPI step."},
  325. {"authGSSServerUserName", authGSSServerUserName, METH_VARARGS,
  326. "Get the user name from the last server-side GSSAPI step."},
  327. {"authGSSServerTargetName", authGSSServerTargetName, METH_VARARGS,
  328. "Get the target name from the last server-side GSSAPI step."},
  329. {NULL, NULL, 0, NULL} /* Sentinel */
  330. };
  331. PyMODINIT_FUNC initkerberos(void)
  332. {
  333. PyObject *m,*d;
  334. m = Py_InitModule("kerberos", KerberosMethods);
  335. d = PyModule_GetDict(m);
  336. /* create the base exception class */
  337. if (!(KrbException_class = PyErr_NewException("kerberos.KrbError", NULL, NULL)))
  338. goto error;
  339. PyDict_SetItemString(d, "KrbError", KrbException_class);
  340. Py_INCREF(KrbException_class);
  341. /* ...and the derived exceptions */
  342. if (!(BasicAuthException_class = PyErr_NewException("kerberos.BasicAuthError", KrbException_class, NULL)))
  343. goto error;
  344. Py_INCREF(BasicAuthException_class);
  345. PyDict_SetItemString(d, "BasicAuthError", BasicAuthException_class);
  346. if (!(PwdChangeException_class = PyErr_NewException("kerberos.PwdChangeError", KrbException_class, NULL)))
  347. goto error;
  348. Py_INCREF(PwdChangeException_class);
  349. PyDict_SetItemString(d, "PwdChangeError", PwdChangeException_class);
  350. if (!(GssException_class = PyErr_NewException("kerberos.GSSError", KrbException_class, NULL)))
  351. goto error;
  352. Py_INCREF(GssException_class);
  353. PyDict_SetItemString(d, "GSSError", GssException_class);
  354. PyDict_SetItemString(d, "AUTH_GSS_COMPLETE", PyInt_FromLong(AUTH_GSS_COMPLETE));
  355. PyDict_SetItemString(d, "AUTH_GSS_CONTINUE", PyInt_FromLong(AUTH_GSS_CONTINUE));
  356. PyDict_SetItemString(d, "GSS_C_DELEG_FLAG", PyInt_FromLong(GSS_C_DELEG_FLAG));
  357. PyDict_SetItemString(d, "GSS_C_MUTUAL_FLAG", PyInt_FromLong(GSS_C_MUTUAL_FLAG));
  358. PyDict_SetItemString(d, "GSS_C_REPLAY_FLAG", PyInt_FromLong(GSS_C_REPLAY_FLAG));
  359. PyDict_SetItemString(d, "GSS_C_SEQUENCE_FLAG", PyInt_FromLong(GSS_C_SEQUENCE_FLAG));
  360. PyDict_SetItemString(d, "GSS_C_CONF_FLAG", PyInt_FromLong(GSS_C_CONF_FLAG));
  361. PyDict_SetItemString(d, "GSS_C_INTEG_FLAG", PyInt_FromLong(GSS_C_INTEG_FLAG));
  362. PyDict_SetItemString(d, "GSS_C_ANON_FLAG", PyInt_FromLong(GSS_C_ANON_FLAG));
  363. PyDict_SetItemString(d, "GSS_C_PROT_READY_FLAG", PyInt_FromLong(GSS_C_PROT_READY_FLAG));
  364. PyDict_SetItemString(d, "GSS_C_TRANS_FLAG", PyInt_FromLong(GSS_C_TRANS_FLAG));
  365. error:
  366. if (PyErr_Occurred())
  367. PyErr_SetString(PyExc_ImportError, "kerberos: init failed");
  368. }