kerberos.py 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461
  1. ##
  2. # Copyright (c) 2006-2018 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. """
  17. PyKerberos Function Description.
  18. """
  19. class KrbError(Exception):
  20. pass
  21. class BasicAuthError(KrbError):
  22. pass
  23. class GSSError(KrbError):
  24. pass
  25. def checkPassword(user, pswd, service, default_realm):
  26. """
  27. This function provides a simple way to verify that a user name and password
  28. match those normally used for Kerberos authentication.
  29. It does this by checking that the supplied user name and password can be
  30. used to get a ticket for the supplied service.
  31. If the user name does not contain a realm, then the default realm supplied
  32. is used.
  33. For this to work properly the Kerberos must be configured properly on this
  34. machine.
  35. That will likely mean ensuring that the edu.mit.Kerberos preference file
  36. has the correct realms and KDCs listed.
  37. IMPORTANT: This method is vulnerable to KDC spoofing attacks and it should
  38. only used for testing. Do not use this in any production system - your
  39. security could be compromised if you do.
  40. @param user: A string containing the Kerberos user name.
  41. A realm may be included by appending an C{"@"} followed by the realm
  42. string to the actual user id.
  43. If no realm is supplied, then the realm set in the default_realm
  44. argument will be used.
  45. @param pswd: A string containing the password for the user.
  46. @param service: A string containing the Kerberos service to check access
  47. for.
  48. This will be of the form C{"sss/xx.yy.zz"}, where C{"sss"} is the
  49. service identifier (e.g., C{"http"}, C{"krbtgt"}), and C{"xx.yy.zz"} is
  50. the hostname of the server.
  51. @param default_realm: A string containing the default realm to use if one
  52. is not supplied in the user argument.
  53. Note that Kerberos realms are normally all uppercase (e.g.,
  54. C{"EXAMPLE.COM"}).
  55. @return: True if authentication succeeds, false otherwise.
  56. """
  57. def changePassword(user, oldpswd, newpswd):
  58. """
  59. This function allows to change the user password on the KDC.
  60. @param user: A string containing the Kerberos user name.
  61. A realm may be included by appending a C{"@"} followed by the realm
  62. string to the actual user id.
  63. If no realm is supplied, then the realm set in the default_realm
  64. argument will be used.
  65. @param oldpswd: A string containing the old (current) password for the
  66. user.
  67. @param newpswd: A string containing the new password for the user.
  68. @return: True if password changing succeeds, false otherwise.
  69. """
  70. def getServerPrincipalDetails(service, hostname):
  71. """
  72. This function returns the service principal for the server given a service
  73. type and hostname.
  74. Details are looked up via the C{/etc/keytab} file.
  75. @param service: A string containing the Kerberos service type for the
  76. server.
  77. @param hostname: A string containing the hostname of the server.
  78. @return: A string containing the service principal.
  79. """
  80. """
  81. GSSAPI Function Result Codes:
  82. -1 : Error
  83. 0 : GSSAPI step continuation (only returned by 'Step' function)
  84. 1 : GSSAPI step complete, or function return OK
  85. """
  86. # Some useful result codes
  87. AUTH_GSS_CONTINUE = 0
  88. AUTH_GSS_COMPLETE = 1
  89. # Some useful gss flags
  90. GSS_C_DELEG_FLAG = 1
  91. GSS_C_MUTUAL_FLAG = 2
  92. GSS_C_REPLAY_FLAG = 4
  93. GSS_C_SEQUENCE_FLAG = 8
  94. GSS_C_CONF_FLAG = 16
  95. GSS_C_INTEG_FLAG = 32
  96. GSS_C_ANON_FLAG = 64
  97. GSS_C_PROT_READY_FLAG = 128
  98. GSS_C_TRANS_FLAG = 256
  99. def authGSSClientInit(service, **kwargs):
  100. """
  101. Initializes a context for GSSAPI client-side authentication with the given
  102. service principal.
  103. L{authGSSClientClean} must be called after this function returns an OK
  104. result to dispose of the context once all GSSAPI operations are complete.
  105. @param service: A string containing the service principal in the form
  106. C{"type@fqdn"}.
  107. @param principal: Optional string containing the client principal in the
  108. form C{"user@realm"}.
  109. @param gssflags: Optional integer used to set GSS flags.
  110. (e.g. C{GSS_C_DELEG_FLAG|GSS_C_MUTUAL_FLAG|GSS_C_SEQUENCE_FLAG} will
  111. allow for forwarding credentials to the remote host)
  112. @param delegated: Optional server context containing delegated credentials
  113. @param mech_oid: Optional GGS mech OID
  114. @return: A tuple of (result, context) where result is the result code (see
  115. above) and context is an opaque value that will need to be passed to
  116. subsequent functions.
  117. """
  118. def authGSSClientClean(context):
  119. """
  120. Destroys the context for GSSAPI client-side authentication. This function
  121. is provided for compatibility with earlier versions of PyKerberos but does
  122. nothing. The context object destroys itself when it is reclaimed.
  123. @param context: The context object returned from L{authGSSClientInit}.
  124. @return: A result code (see above).
  125. """
  126. def authGSSClientInquireCred(context):
  127. """
  128. Get the current user name, if any, without a client-side GSSAPI step.
  129. If the principal has already been authenticated via completed client-side
  130. GSSAPI steps then the user name of the authenticated principal is kept. The
  131. user name will be available via authGSSClientUserName.
  132. @param context: The context object returned from L{authGSSClientInit}.
  133. @return: A result code (see above).
  134. """
  135. """
  136. Address Types for Channel Bindings
  137. https://docs.oracle.com/cd/E19455-01/806-3814/6jcugr7dp/index.html#reference-9
  138. """
  139. GSS_C_AF_UNSPEC = 0
  140. GSS_C_AF_LOCAL = 1
  141. GSS_C_AF_INET = 2
  142. GSS_C_AF_IMPLINK = 3
  143. GSS_C_AF_PUP = 4
  144. GSS_C_AF_CHAOS = 5
  145. GSS_C_AF_NS = 6
  146. GSS_C_AF_NBS = 7
  147. GSS_C_AF_ECMA = 8
  148. GSS_C_AF_DATAKIT = 9
  149. GSS_C_AF_CCITT = 10
  150. GSS_C_AF_SNA = 11
  151. GSS_C_AF_DECnet = 12
  152. GSS_C_AF_DLI = 13
  153. GSS_C_AF_LAT = 14
  154. GSS_C_AF_HYLINK = 15
  155. GSS_C_AF_APPLETALK = 16
  156. GSS_C_AF_BSC = 17
  157. GSS_C_AF_DSS = 18
  158. GSS_C_AF_OSI = 19
  159. GSS_C_AF_X25 = 21
  160. GSS_C_AF_NULLADDR = 255
  161. def channelBindings(**kwargs):
  162. """
  163. Builds a gss_channel_bindings_struct which can be used to pass onto
  164. L{authGSSClientStep} to bind onto the auth. Details on Channel Bindings
  165. can be foud at https://tools.ietf.org/html/rfc5929. More details on the
  166. struct can be found at
  167. https://docs.oracle.com/cd/E19455-01/806-3814/overview-52/index.html
  168. @param initiator_addrtype: Optional integer used to set the
  169. initiator_addrtype, defaults to GSS_C_AF_UNSPEC if not set
  170. @param initiator_address: Optional byte string containing the
  171. initiator_address
  172. @param acceptor_addrtype: Optional integer used to set the
  173. acceptor_addrtype, defaults to GSS_C_AF_UNSPEC if not set
  174. @param acceptor_address: Optional byte string containing the
  175. acceptor_address
  176. @param application_data: Optional byte string containing the
  177. application_data. An example would be 'tls-server-end-point:{cert-hash}'
  178. where {cert-hash} is the hash of the server's certificate
  179. @return: A tuple of (result, gss_channel_bindings_struct) where result is
  180. the result code and gss_channel_bindings_struct is the channel bindings
  181. structure that can be passed onto L{authGSSClientStep}
  182. """
  183. def authGSSClientStep(context, challenge, **kwargs):
  184. """
  185. Processes a single GSSAPI client-side step using the supplied server data.
  186. @param context: The context object returned from L{authGSSClientInit}.
  187. @param challenge: A string containing the base64-encoded server data (which
  188. may be empty for the first step).
  189. @param channel_bindings: Optional channel bindings to bind onto the auth
  190. request. This struct can be built using :{channelBindings}
  191. and if not specified it will pass along GSS_C_NO_CHANNEL_BINDINGS as
  192. a default.
  193. @return: A result code (see above).
  194. """
  195. def authGSSClientResponse(context):
  196. """
  197. Get the client response from the last successful GSSAPI client-side step.
  198. @param context: The context object returned from L{authGSSClientInit}.
  199. @return: A string containing the base64-encoded client data to be sent to
  200. the server.
  201. """
  202. def authGSSClientResponseConf(context):
  203. """
  204. Determine whether confidentiality was enabled in the previously unwrapped
  205. buffer.
  206. @param context: The context object returned from L{authGSSClientInit}.
  207. @return: C{1} if confidentiality was enabled in the previously unwrapped
  208. buffer, C{0} otherwise.
  209. """
  210. def authGSSClientUserName(context):
  211. """
  212. Get the user name of the principal authenticated via the now complete
  213. GSSAPI client-side operations, or the current user name obtained via
  214. authGSSClientInquireCred. This method must only be called after
  215. authGSSClientStep or authGSSClientInquireCred return a complete response
  216. code.
  217. @param context: The context object returned from L{authGSSClientInit}.
  218. @return: A string containing the user name.
  219. """
  220. def authGSSClientUnwrap(context, challenge):
  221. """
  222. Perform the client side GSSAPI unwrap step.
  223. @param challenge: A string containing the base64-encoded server data.
  224. @return: A result code (see above)
  225. """
  226. def authGSSClientWrap(context, data, user=None, protect=0):
  227. """
  228. Perform the client side GSSAPI wrap step.
  229. @param data: The result of the L{authGSSClientResponse} after the
  230. L{authGSSClientUnwrap}.
  231. @param user: The user to authorize.
  232. @param protect: If C{0}, then just provide integrity protection.
  233. If C{1}, then provide confidentiality as well.
  234. @return: A result code (see above)
  235. """
  236. def authGSSServerInit(service):
  237. """
  238. Initializes a context for GSSAPI server-side authentication with the given
  239. service principal.
  240. authGSSServerClean must be called after this function returns an OK result
  241. to dispose of the context once all GSSAPI operations are complete.
  242. @param service: A string containing the service principal in the form
  243. C{"type@fqdn"}. To initialize the context for the purpose of accepting
  244. delegated credentials, pass the literal string C{"DELEGATE"}.
  245. @return: A tuple of (result, context) where result is the result code (see
  246. above) and context is an opaque value that will need to be passed to
  247. subsequent functions.
  248. """
  249. def authGSSServerClean(context):
  250. """
  251. Destroys the context for GSSAPI server-side authentication. This function
  252. is provided for compatibility with earlier versions of PyKerberos but does
  253. nothing. The context object destroys itself when it is reclaimed.
  254. @param context: The context object returned from L{authGSSClientInit}.
  255. @return: A result code (see above).
  256. """
  257. def authGSSServerStep(context, challenge):
  258. """
  259. Processes a single GSSAPI server-side step using the supplied client data.
  260. @param context: The context object returned from L{authGSSClientInit}.
  261. @param challenge: A string containing the base64-encoded client data.
  262. @return: A result code (see above).
  263. """
  264. def authGSSServerResponse(context):
  265. """
  266. Get the server response from the last successful GSSAPI server-side step.
  267. @param context: The context object returned from L{authGSSClientInit}.
  268. @return: A string containing the base64-encoded server data to be sent to
  269. the client.
  270. """
  271. def authGSSServerHasDelegated(context):
  272. """
  273. Checks whether a server context has delegated credentials.
  274. @param context: The context object returned from L{authGSSClientInit}.
  275. @return: A bool saying whether delegated credentials are available.
  276. """
  277. def authGSSServerUserName(context):
  278. """
  279. Get the user name of the principal trying to authenticate to the server.
  280. This method must only be called after L{authGSSServerStep} returns a
  281. complete or continue response code.
  282. @param context: The context object returned from L{authGSSClientInit}.
  283. @return: A string containing the user name.
  284. """
  285. def authGSSServerTargetName(context):
  286. """
  287. Get the target name if the server did not supply its own credentials.
  288. This method must only be called after L{authGSSServerStep} returns a
  289. complete or continue response code.
  290. @param context: The context object returned from L{authGSSClientInit}.
  291. @return: A string containing the target name.
  292. """
  293. def authGSSServerStoreDelegate(context):
  294. """
  295. Save the ticket sent to the server in the file C{/tmp/krb5_pyserv_XXXXXX}.
  296. This method must only be called after L{authGSSServerStep} returns a
  297. complete or continue response code.
  298. @param context: The context object returned from L{authGSSClientInit}.
  299. @return: A result code (see above).
  300. """
  301. def authGSSServerCacheName(context):
  302. """
  303. Get the name of the credential cache created with
  304. L{authGSSServerStoreDelegate}.
  305. This method must only be called after L{authGSSServerStoreDelegate}.
  306. @param context: The context object returned from L{authGSSClientInit}.
  307. @return: A string containing the cache name.
  308. """