kssl.c 75 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260
  1. /* ssl/kssl.c */
  2. /*
  3. * Written by Vern Staats <staatsvr@asc.hpc.mil> for the OpenSSL project
  4. * 2000.
  5. */
  6. /* ====================================================================
  7. * Copyright (c) 2000 The OpenSSL Project. All rights reserved.
  8. *
  9. * Redistribution and use in source and binary forms, with or without
  10. * modification, are permitted provided that the following conditions
  11. * are met:
  12. *
  13. * 1. Redistributions of source code must retain the above copyright
  14. * notice, this list of conditions and the following disclaimer.
  15. *
  16. * 2. Redistributions in binary form must reproduce the above copyright
  17. * notice, this list of conditions and the following disclaimer in
  18. * the documentation and/or other materials provided with the
  19. * distribution.
  20. *
  21. * 3. All advertising materials mentioning features or use of this
  22. * software must display the following acknowledgment:
  23. * "This product includes software developed by the OpenSSL Project
  24. * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
  25. *
  26. * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
  27. * endorse or promote products derived from this software without
  28. * prior written permission. For written permission, please contact
  29. * licensing@OpenSSL.org.
  30. *
  31. * 5. Products derived from this software may not be called "OpenSSL"
  32. * nor may "OpenSSL" appear in their names without prior written
  33. * permission of the OpenSSL Project.
  34. *
  35. * 6. Redistributions of any form whatsoever must retain the following
  36. * acknowledgment:
  37. * "This product includes software developed by the OpenSSL Project
  38. * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
  39. *
  40. * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
  41. * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  42. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  43. * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
  44. * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  45. * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  46. * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  47. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  48. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
  49. * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  50. * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
  51. * OF THE POSSIBILITY OF SUCH DAMAGE.
  52. * ====================================================================
  53. *
  54. * This product includes cryptographic software written by Eric Young
  55. * (eay@cryptsoft.com). This product includes software written by Tim
  56. * Hudson (tjh@cryptsoft.com).
  57. *
  58. */
  59. /*-
  60. * ssl/kssl.c -- Routines to support (& debug) Kerberos5 auth for openssl
  61. *
  62. * 19990701 VRS Started.
  63. * 200011?? Jeffrey Altman, Richard Levitte
  64. * Generalized for Heimdal, Newer MIT, & Win32.
  65. * Integrated into main OpenSSL 0.9.7 snapshots.
  66. * 20010413 Simon Wilkinson, VRS
  67. * Real RFC2712 KerberosWrapper replaces AP_REQ.
  68. */
  69. #include <openssl/opensslconf.h>
  70. #include <string.h>
  71. #define KRB5_PRIVATE 1
  72. #include <openssl/ssl.h>
  73. #include <openssl/evp.h>
  74. #include <openssl/objects.h>
  75. #include <openssl/krb5_asn.h>
  76. #include "kssl_lcl.h"
  77. #ifndef OPENSSL_NO_KRB5
  78. # ifndef ENOMEM
  79. # define ENOMEM KRB5KRB_ERR_GENERIC
  80. # endif
  81. /*
  82. * When OpenSSL is built on Windows, we do not want to require that
  83. * the Kerberos DLLs be available in order for the OpenSSL DLLs to
  84. * work. Therefore, all Kerberos routines are loaded at run time
  85. * and we do not link to a .LIB file.
  86. */
  87. # if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_WIN32)
  88. /*
  89. * The purpose of the following pre-processor statements is to provide
  90. * compatibility with different releases of MIT Kerberos for Windows.
  91. * All versions up to 1.2 used macros. But macros do not allow for
  92. * a binary compatible interface for DLLs. Therefore, all macros are
  93. * being replaced by function calls. The following code will allow
  94. * an OpenSSL DLL built on Windows to work whether or not the macro
  95. * or function form of the routines are utilized.
  96. */
  97. # ifdef krb5_cc_get_principal
  98. # define NO_DEF_KRB5_CCACHE
  99. # undef krb5_cc_get_principal
  100. # endif
  101. # define krb5_cc_get_principal kssl_krb5_cc_get_principal
  102. # define krb5_free_data_contents kssl_krb5_free_data_contents
  103. # define krb5_free_context kssl_krb5_free_context
  104. # define krb5_auth_con_free kssl_krb5_auth_con_free
  105. # define krb5_free_principal kssl_krb5_free_principal
  106. # define krb5_mk_req_extended kssl_krb5_mk_req_extended
  107. # define krb5_get_credentials kssl_krb5_get_credentials
  108. # define krb5_cc_default kssl_krb5_cc_default
  109. # define krb5_sname_to_principal kssl_krb5_sname_to_principal
  110. # define krb5_init_context kssl_krb5_init_context
  111. # define krb5_free_ticket kssl_krb5_free_ticket
  112. # define krb5_rd_req kssl_krb5_rd_req
  113. # define krb5_kt_default kssl_krb5_kt_default
  114. # define krb5_kt_resolve kssl_krb5_kt_resolve
  115. /* macros in mit 1.2.2 and earlier; functions in mit 1.2.3 and greater */
  116. # ifndef krb5_kt_close
  117. # define krb5_kt_close kssl_krb5_kt_close
  118. # endif /* krb5_kt_close */
  119. # ifndef krb5_kt_get_entry
  120. # define krb5_kt_get_entry kssl_krb5_kt_get_entry
  121. # endif /* krb5_kt_get_entry */
  122. # define krb5_auth_con_init kssl_krb5_auth_con_init
  123. # define krb5_principal_compare kssl_krb5_principal_compare
  124. # define krb5_decrypt_tkt_part kssl_krb5_decrypt_tkt_part
  125. # define krb5_timeofday kssl_krb5_timeofday
  126. # define krb5_rc_default kssl_krb5_rc_default
  127. # ifdef krb5_rc_initialize
  128. # undef krb5_rc_initialize
  129. # endif
  130. # define krb5_rc_initialize kssl_krb5_rc_initialize
  131. # ifdef krb5_rc_get_lifespan
  132. # undef krb5_rc_get_lifespan
  133. # endif
  134. # define krb5_rc_get_lifespan kssl_krb5_rc_get_lifespan
  135. # ifdef krb5_rc_destroy
  136. # undef krb5_rc_destroy
  137. # endif
  138. # define krb5_rc_destroy kssl_krb5_rc_destroy
  139. # define valid_cksumtype kssl_valid_cksumtype
  140. # define krb5_checksum_size kssl_krb5_checksum_size
  141. # define krb5_kt_free_entry kssl_krb5_kt_free_entry
  142. # define krb5_auth_con_setrcache kssl_krb5_auth_con_setrcache
  143. # define krb5_auth_con_getrcache kssl_krb5_auth_con_getrcache
  144. # define krb5_get_server_rcache kssl_krb5_get_server_rcache
  145. /* Prototypes for built in stubs */
  146. void kssl_krb5_free_data_contents(krb5_context, krb5_data *);
  147. void kssl_krb5_free_principal(krb5_context, krb5_principal);
  148. krb5_error_code kssl_krb5_kt_resolve(krb5_context,
  149. krb5_const char *, krb5_keytab *);
  150. krb5_error_code kssl_krb5_kt_default(krb5_context, krb5_keytab *);
  151. krb5_error_code kssl_krb5_free_ticket(krb5_context, krb5_ticket *);
  152. krb5_error_code kssl_krb5_rd_req(krb5_context, krb5_auth_context *,
  153. krb5_const krb5_data *,
  154. krb5_const_principal, krb5_keytab,
  155. krb5_flags *, krb5_ticket **);
  156. krb5_boolean kssl_krb5_principal_compare(krb5_context, krb5_const_principal,
  157. krb5_const_principal);
  158. krb5_error_code kssl_krb5_mk_req_extended(krb5_context,
  159. krb5_auth_context *,
  160. krb5_const krb5_flags,
  161. krb5_data *,
  162. krb5_creds *, krb5_data *);
  163. krb5_error_code kssl_krb5_init_context(krb5_context *);
  164. void kssl_krb5_free_context(krb5_context);
  165. krb5_error_code kssl_krb5_cc_default(krb5_context, krb5_ccache *);
  166. krb5_error_code kssl_krb5_sname_to_principal(krb5_context,
  167. krb5_const char *,
  168. krb5_const char *,
  169. krb5_int32, krb5_principal *);
  170. krb5_error_code kssl_krb5_get_credentials(krb5_context,
  171. krb5_const krb5_flags,
  172. krb5_ccache,
  173. krb5_creds *, krb5_creds * *);
  174. krb5_error_code kssl_krb5_auth_con_init(krb5_context, krb5_auth_context *);
  175. krb5_error_code kssl_krb5_cc_get_principal(krb5_context context,
  176. krb5_ccache cache,
  177. krb5_principal *principal);
  178. krb5_error_code kssl_krb5_auth_con_free(krb5_context, krb5_auth_context);
  179. size_t kssl_krb5_checksum_size(krb5_context context, krb5_cksumtype ctype);
  180. krb5_boolean kssl_valid_cksumtype(krb5_cksumtype ctype);
  181. krb5_error_code krb5_kt_free_entry(krb5_context, krb5_keytab_entry FAR *);
  182. krb5_error_code kssl_krb5_auth_con_setrcache(krb5_context,
  183. krb5_auth_context, krb5_rcache);
  184. krb5_error_code kssl_krb5_get_server_rcache(krb5_context,
  185. krb5_const krb5_data *,
  186. krb5_rcache *);
  187. krb5_error_code kssl_krb5_auth_con_getrcache(krb5_context,
  188. krb5_auth_context,
  189. krb5_rcache *);
  190. /* Function pointers (almost all Kerberos functions are _stdcall) */
  191. static void (_stdcall *p_krb5_free_data_contents) (krb5_context, krb5_data *)
  192. = NULL;
  193. static void (_stdcall *p_krb5_free_principal) (krb5_context, krb5_principal)
  194. = NULL;
  195. static krb5_error_code(_stdcall *p_krb5_kt_resolve)
  196. (krb5_context, krb5_const char *, krb5_keytab *) = NULL;
  197. static krb5_error_code(_stdcall *p_krb5_kt_default) (krb5_context,
  198. krb5_keytab *) = NULL;
  199. static krb5_error_code(_stdcall *p_krb5_free_ticket) (krb5_context,
  200. krb5_ticket *) = NULL;
  201. static krb5_error_code(_stdcall *p_krb5_rd_req) (krb5_context,
  202. krb5_auth_context *,
  203. krb5_const krb5_data *,
  204. krb5_const_principal,
  205. krb5_keytab, krb5_flags *,
  206. krb5_ticket **) = NULL;
  207. static krb5_error_code(_stdcall *p_krb5_mk_req_extended)
  208. (krb5_context, krb5_auth_context *,
  209. krb5_const krb5_flags, krb5_data *, krb5_creds *, krb5_data *) = NULL;
  210. static krb5_error_code(_stdcall *p_krb5_init_context) (krb5_context *) = NULL;
  211. static void (_stdcall *p_krb5_free_context) (krb5_context) = NULL;
  212. static krb5_error_code(_stdcall *p_krb5_cc_default) (krb5_context,
  213. krb5_ccache *) = NULL;
  214. static krb5_error_code(_stdcall *p_krb5_sname_to_principal)
  215. (krb5_context, krb5_const char *, krb5_const char *,
  216. krb5_int32, krb5_principal *) = NULL;
  217. static krb5_error_code(_stdcall *p_krb5_get_credentials)
  218. (krb5_context, krb5_const krb5_flags, krb5_ccache,
  219. krb5_creds *, krb5_creds **) = NULL;
  220. static krb5_error_code(_stdcall *p_krb5_auth_con_init)
  221. (krb5_context, krb5_auth_context *) = NULL;
  222. static krb5_error_code(_stdcall *p_krb5_cc_get_principal)
  223. (krb5_context context, krb5_ccache cache, krb5_principal *principal) = NULL;
  224. static krb5_error_code(_stdcall *p_krb5_auth_con_free)
  225. (krb5_context, krb5_auth_context) = NULL;
  226. static krb5_error_code(_stdcall *p_krb5_decrypt_tkt_part)
  227. (krb5_context, krb5_const krb5_keyblock *, krb5_ticket *) = NULL;
  228. static krb5_error_code(_stdcall *p_krb5_timeofday)
  229. (krb5_context context, krb5_int32 *timeret) = NULL;
  230. static krb5_error_code(_stdcall *p_krb5_rc_default)
  231. (krb5_context context, krb5_rcache *rc) = NULL;
  232. static krb5_error_code(_stdcall *p_krb5_rc_initialize)
  233. (krb5_context context, krb5_rcache rc, krb5_deltat lifespan) = NULL;
  234. static krb5_error_code(_stdcall *p_krb5_rc_get_lifespan)
  235. (krb5_context context, krb5_rcache rc, krb5_deltat *lifespan) = NULL;
  236. static krb5_error_code(_stdcall *p_krb5_rc_destroy)
  237. (krb5_context context, krb5_rcache rc) = NULL;
  238. static krb5_boolean(_stdcall *p_krb5_principal_compare)
  239. (krb5_context, krb5_const_principal, krb5_const_principal) = NULL;
  240. static size_t (_stdcall *p_krb5_checksum_size) (krb5_context context,
  241. krb5_cksumtype ctype) = NULL;
  242. static krb5_boolean(_stdcall *p_valid_cksumtype) (krb5_cksumtype ctype) =
  243. NULL;
  244. static krb5_error_code(_stdcall *p_krb5_kt_free_entry)
  245. (krb5_context, krb5_keytab_entry *) = NULL;
  246. static krb5_error_code(_stdcall *p_krb5_auth_con_setrcache) (krb5_context,
  247. krb5_auth_context,
  248. krb5_rcache) =
  249. NULL;
  250. static krb5_error_code(_stdcall *p_krb5_get_server_rcache) (krb5_context,
  251. krb5_const
  252. krb5_data *,
  253. krb5_rcache *) =
  254. NULL;
  255. static krb5_error_code(*p_krb5_auth_con_getrcache) (krb5_context,
  256. krb5_auth_context,
  257. krb5_rcache *) = NULL;
  258. static krb5_error_code(_stdcall *p_krb5_kt_close) (krb5_context context,
  259. krb5_keytab keytab) = NULL;
  260. static krb5_error_code(_stdcall *p_krb5_kt_get_entry) (krb5_context context,
  261. krb5_keytab keytab,
  262. krb5_const_principal
  263. principal,
  264. krb5_kvno vno,
  265. krb5_enctype enctype,
  266. krb5_keytab_entry
  267. *entry) = NULL;
  268. static int krb5_loaded = 0; /* only attempt to initialize func ptrs once */
  269. /* Function to Load the Kerberos 5 DLL and initialize function pointers */
  270. void load_krb5_dll(void)
  271. {
  272. HANDLE hKRB5_32;
  273. krb5_loaded++;
  274. hKRB5_32 = LoadLibrary(TEXT("KRB5_32"));
  275. if (!hKRB5_32)
  276. return;
  277. (FARPROC) p_krb5_free_data_contents =
  278. GetProcAddress(hKRB5_32, "krb5_free_data_contents");
  279. (FARPROC) p_krb5_free_context =
  280. GetProcAddress(hKRB5_32, "krb5_free_context");
  281. (FARPROC) p_krb5_auth_con_free =
  282. GetProcAddress(hKRB5_32, "krb5_auth_con_free");
  283. (FARPROC) p_krb5_free_principal =
  284. GetProcAddress(hKRB5_32, "krb5_free_principal");
  285. (FARPROC) p_krb5_mk_req_extended =
  286. GetProcAddress(hKRB5_32, "krb5_mk_req_extended");
  287. (FARPROC) p_krb5_get_credentials =
  288. GetProcAddress(hKRB5_32, "krb5_get_credentials");
  289. (FARPROC) p_krb5_cc_get_principal =
  290. GetProcAddress(hKRB5_32, "krb5_cc_get_principal");
  291. (FARPROC) p_krb5_cc_default = GetProcAddress(hKRB5_32, "krb5_cc_default");
  292. (FARPROC) p_krb5_sname_to_principal =
  293. GetProcAddress(hKRB5_32, "krb5_sname_to_principal");
  294. (FARPROC) p_krb5_init_context =
  295. GetProcAddress(hKRB5_32, "krb5_init_context");
  296. (FARPROC) p_krb5_free_ticket =
  297. GetProcAddress(hKRB5_32, "krb5_free_ticket");
  298. (FARPROC) p_krb5_rd_req = GetProcAddress(hKRB5_32, "krb5_rd_req");
  299. (FARPROC) p_krb5_principal_compare =
  300. GetProcAddress(hKRB5_32, "krb5_principal_compare");
  301. (FARPROC) p_krb5_decrypt_tkt_part =
  302. GetProcAddress(hKRB5_32, "krb5_decrypt_tkt_part");
  303. (FARPROC) p_krb5_timeofday = GetProcAddress(hKRB5_32, "krb5_timeofday");
  304. (FARPROC) p_krb5_rc_default = GetProcAddress(hKRB5_32, "krb5_rc_default");
  305. (FARPROC) p_krb5_rc_initialize =
  306. GetProcAddress(hKRB5_32, "krb5_rc_initialize");
  307. (FARPROC) p_krb5_rc_get_lifespan =
  308. GetProcAddress(hKRB5_32, "krb5_rc_get_lifespan");
  309. (FARPROC) p_krb5_rc_destroy = GetProcAddress(hKRB5_32, "krb5_rc_destroy");
  310. (FARPROC) p_krb5_kt_default = GetProcAddress(hKRB5_32, "krb5_kt_default");
  311. (FARPROC) p_krb5_kt_resolve = GetProcAddress(hKRB5_32, "krb5_kt_resolve");
  312. (FARPROC) p_krb5_auth_con_init =
  313. GetProcAddress(hKRB5_32, "krb5_auth_con_init");
  314. (FARPROC) p_valid_cksumtype = GetProcAddress(hKRB5_32, "valid_cksumtype");
  315. (FARPROC) p_krb5_checksum_size =
  316. GetProcAddress(hKRB5_32, "krb5_checksum_size");
  317. (FARPROC) p_krb5_kt_free_entry =
  318. GetProcAddress(hKRB5_32, "krb5_kt_free_entry");
  319. (FARPROC) p_krb5_auth_con_setrcache =
  320. GetProcAddress(hKRB5_32, "krb5_auth_con_setrcache");
  321. (FARPROC) p_krb5_get_server_rcache =
  322. GetProcAddress(hKRB5_32, "krb5_get_server_rcache");
  323. (FARPROC) p_krb5_auth_con_getrcache =
  324. GetProcAddress(hKRB5_32, "krb5_auth_con_getrcache");
  325. (FARPROC) p_krb5_kt_close = GetProcAddress(hKRB5_32, "krb5_kt_close");
  326. (FARPROC) p_krb5_kt_get_entry =
  327. GetProcAddress(hKRB5_32, "krb5_kt_get_entry");
  328. }
  329. /* Stubs for each function to be dynamicly loaded */
  330. void kssl_krb5_free_data_contents(krb5_context CO, krb5_data *data)
  331. {
  332. if (!krb5_loaded)
  333. load_krb5_dll();
  334. if (p_krb5_free_data_contents)
  335. p_krb5_free_data_contents(CO, data);
  336. }
  337. krb5_error_code
  338. kssl_krb5_mk_req_extended(krb5_context CO,
  339. krb5_auth_context *pACO,
  340. krb5_const krb5_flags F,
  341. krb5_data *pD1, krb5_creds *pC, krb5_data *pD2)
  342. {
  343. if (!krb5_loaded)
  344. load_krb5_dll();
  345. if (p_krb5_mk_req_extended)
  346. return (p_krb5_mk_req_extended(CO, pACO, F, pD1, pC, pD2));
  347. else
  348. return KRB5KRB_ERR_GENERIC;
  349. }
  350. krb5_error_code
  351. kssl_krb5_auth_con_init(krb5_context CO, krb5_auth_context *pACO)
  352. {
  353. if (!krb5_loaded)
  354. load_krb5_dll();
  355. if (p_krb5_auth_con_init)
  356. return (p_krb5_auth_con_init(CO, pACO));
  357. else
  358. return KRB5KRB_ERR_GENERIC;
  359. }
  360. krb5_error_code
  361. kssl_krb5_auth_con_free(krb5_context CO, krb5_auth_context ACO)
  362. {
  363. if (!krb5_loaded)
  364. load_krb5_dll();
  365. if (p_krb5_auth_con_free)
  366. return (p_krb5_auth_con_free(CO, ACO));
  367. else
  368. return KRB5KRB_ERR_GENERIC;
  369. }
  370. krb5_error_code
  371. kssl_krb5_get_credentials(krb5_context CO,
  372. krb5_const krb5_flags F,
  373. krb5_ccache CC, krb5_creds *pCR, krb5_creds **ppCR)
  374. {
  375. if (!krb5_loaded)
  376. load_krb5_dll();
  377. if (p_krb5_get_credentials)
  378. return (p_krb5_get_credentials(CO, F, CC, pCR, ppCR));
  379. else
  380. return KRB5KRB_ERR_GENERIC;
  381. }
  382. krb5_error_code
  383. kssl_krb5_sname_to_principal(krb5_context CO,
  384. krb5_const char *pC1,
  385. krb5_const char *pC2,
  386. krb5_int32 I, krb5_principal *pPR)
  387. {
  388. if (!krb5_loaded)
  389. load_krb5_dll();
  390. if (p_krb5_sname_to_principal)
  391. return (p_krb5_sname_to_principal(CO, pC1, pC2, I, pPR));
  392. else
  393. return KRB5KRB_ERR_GENERIC;
  394. }
  395. krb5_error_code kssl_krb5_cc_default(krb5_context CO, krb5_ccache *pCC)
  396. {
  397. if (!krb5_loaded)
  398. load_krb5_dll();
  399. if (p_krb5_cc_default)
  400. return (p_krb5_cc_default(CO, pCC));
  401. else
  402. return KRB5KRB_ERR_GENERIC;
  403. }
  404. krb5_error_code kssl_krb5_init_context(krb5_context *pCO)
  405. {
  406. if (!krb5_loaded)
  407. load_krb5_dll();
  408. if (p_krb5_init_context)
  409. return (p_krb5_init_context(pCO));
  410. else
  411. return KRB5KRB_ERR_GENERIC;
  412. }
  413. void kssl_krb5_free_context(krb5_context CO)
  414. {
  415. if (!krb5_loaded)
  416. load_krb5_dll();
  417. if (p_krb5_free_context)
  418. p_krb5_free_context(CO);
  419. }
  420. void kssl_krb5_free_principal(krb5_context c, krb5_principal p)
  421. {
  422. if (!krb5_loaded)
  423. load_krb5_dll();
  424. if (p_krb5_free_principal)
  425. p_krb5_free_principal(c, p);
  426. }
  427. krb5_error_code
  428. kssl_krb5_kt_resolve(krb5_context con, krb5_const char *sz, krb5_keytab *kt)
  429. {
  430. if (!krb5_loaded)
  431. load_krb5_dll();
  432. if (p_krb5_kt_resolve)
  433. return (p_krb5_kt_resolve(con, sz, kt));
  434. else
  435. return KRB5KRB_ERR_GENERIC;
  436. }
  437. krb5_error_code kssl_krb5_kt_default(krb5_context con, krb5_keytab *kt)
  438. {
  439. if (!krb5_loaded)
  440. load_krb5_dll();
  441. if (p_krb5_kt_default)
  442. return (p_krb5_kt_default(con, kt));
  443. else
  444. return KRB5KRB_ERR_GENERIC;
  445. }
  446. krb5_error_code kssl_krb5_free_ticket(krb5_context con, krb5_ticket *kt)
  447. {
  448. if (!krb5_loaded)
  449. load_krb5_dll();
  450. if (p_krb5_free_ticket)
  451. return (p_krb5_free_ticket(con, kt));
  452. else
  453. return KRB5KRB_ERR_GENERIC;
  454. }
  455. krb5_error_code
  456. kssl_krb5_rd_req(krb5_context con, krb5_auth_context *pacon,
  457. krb5_const krb5_data *data,
  458. krb5_const_principal princ, krb5_keytab keytab,
  459. krb5_flags *flags, krb5_ticket **pptkt)
  460. {
  461. if (!krb5_loaded)
  462. load_krb5_dll();
  463. if (p_krb5_rd_req)
  464. return (p_krb5_rd_req(con, pacon, data, princ, keytab, flags, pptkt));
  465. else
  466. return KRB5KRB_ERR_GENERIC;
  467. }
  468. krb5_boolean
  469. krb5_principal_compare(krb5_context con, krb5_const_principal princ1,
  470. krb5_const_principal princ2)
  471. {
  472. if (!krb5_loaded)
  473. load_krb5_dll();
  474. if (p_krb5_principal_compare)
  475. return (p_krb5_principal_compare(con, princ1, princ2));
  476. else
  477. return KRB5KRB_ERR_GENERIC;
  478. }
  479. krb5_error_code
  480. krb5_decrypt_tkt_part(krb5_context con, krb5_const krb5_keyblock *keys,
  481. krb5_ticket *ticket)
  482. {
  483. if (!krb5_loaded)
  484. load_krb5_dll();
  485. if (p_krb5_decrypt_tkt_part)
  486. return (p_krb5_decrypt_tkt_part(con, keys, ticket));
  487. else
  488. return KRB5KRB_ERR_GENERIC;
  489. }
  490. krb5_error_code krb5_timeofday(krb5_context con, krb5_int32 *timeret)
  491. {
  492. if (!krb5_loaded)
  493. load_krb5_dll();
  494. if (p_krb5_timeofday)
  495. return (p_krb5_timeofday(con, timeret));
  496. else
  497. return KRB5KRB_ERR_GENERIC;
  498. }
  499. krb5_error_code krb5_rc_default(krb5_context con, krb5_rcache *rc)
  500. {
  501. if (!krb5_loaded)
  502. load_krb5_dll();
  503. if (p_krb5_rc_default)
  504. return (p_krb5_rc_default(con, rc));
  505. else
  506. return KRB5KRB_ERR_GENERIC;
  507. }
  508. krb5_error_code
  509. krb5_rc_initialize(krb5_context con, krb5_rcache rc, krb5_deltat lifespan)
  510. {
  511. if (!krb5_loaded)
  512. load_krb5_dll();
  513. if (p_krb5_rc_initialize)
  514. return (p_krb5_rc_initialize(con, rc, lifespan));
  515. else
  516. return KRB5KRB_ERR_GENERIC;
  517. }
  518. krb5_error_code
  519. krb5_rc_get_lifespan(krb5_context con, krb5_rcache rc, krb5_deltat *lifespanp)
  520. {
  521. if (!krb5_loaded)
  522. load_krb5_dll();
  523. if (p_krb5_rc_get_lifespan)
  524. return (p_krb5_rc_get_lifespan(con, rc, lifespanp));
  525. else
  526. return KRB5KRB_ERR_GENERIC;
  527. }
  528. krb5_error_code krb5_rc_destroy(krb5_context con, krb5_rcache rc)
  529. {
  530. if (!krb5_loaded)
  531. load_krb5_dll();
  532. if (p_krb5_rc_destroy)
  533. return (p_krb5_rc_destroy(con, rc));
  534. else
  535. return KRB5KRB_ERR_GENERIC;
  536. }
  537. size_t krb5_checksum_size(krb5_context context, krb5_cksumtype ctype)
  538. {
  539. if (!krb5_loaded)
  540. load_krb5_dll();
  541. if (p_krb5_checksum_size)
  542. return (p_krb5_checksum_size(context, ctype));
  543. else
  544. return KRB5KRB_ERR_GENERIC;
  545. }
  546. krb5_boolean valid_cksumtype(krb5_cksumtype ctype)
  547. {
  548. if (!krb5_loaded)
  549. load_krb5_dll();
  550. if (p_valid_cksumtype)
  551. return (p_valid_cksumtype(ctype));
  552. else
  553. return KRB5KRB_ERR_GENERIC;
  554. }
  555. krb5_error_code krb5_kt_free_entry(krb5_context con, krb5_keytab_entry *entry)
  556. {
  557. if (!krb5_loaded)
  558. load_krb5_dll();
  559. if (p_krb5_kt_free_entry)
  560. return (p_krb5_kt_free_entry(con, entry));
  561. else
  562. return KRB5KRB_ERR_GENERIC;
  563. }
  564. /* Structure definitions */
  565. # ifndef NO_DEF_KRB5_CCACHE
  566. # ifndef krb5_x
  567. # define krb5_x(ptr,args) ((ptr)?((*(ptr)) args):(abort(),1))
  568. # define krb5_xc(ptr,args) ((ptr)?((*(ptr)) args):(abort(),(char*)0))
  569. # endif
  570. typedef krb5_pointer krb5_cc_cursor; /* cursor for sequential lookup */
  571. typedef struct _krb5_ccache {
  572. krb5_magic magic;
  573. struct _krb5_cc_ops FAR *ops;
  574. krb5_pointer data;
  575. } *krb5_ccache;
  576. typedef struct _krb5_cc_ops {
  577. krb5_magic magic;
  578. char *prefix;
  579. char *(KRB5_CALLCONV *get_name)
  580. (krb5_context, krb5_ccache);
  581. krb5_error_code(KRB5_CALLCONV *resolve)
  582. (krb5_context, krb5_ccache *, const char *);
  583. krb5_error_code(KRB5_CALLCONV *gen_new)
  584. (krb5_context, krb5_ccache *);
  585. krb5_error_code(KRB5_CALLCONV *init)
  586. (krb5_context, krb5_ccache, krb5_principal);
  587. krb5_error_code(KRB5_CALLCONV *destroy)
  588. (krb5_context, krb5_ccache);
  589. krb5_error_code(KRB5_CALLCONV *close)
  590. (krb5_context, krb5_ccache);
  591. krb5_error_code(KRB5_CALLCONV *store)
  592. (krb5_context, krb5_ccache, krb5_creds *);
  593. krb5_error_code(KRB5_CALLCONV *retrieve)
  594. (krb5_context, krb5_ccache, krb5_flags, krb5_creds *, krb5_creds *);
  595. krb5_error_code(KRB5_CALLCONV *get_princ)
  596. (krb5_context, krb5_ccache, krb5_principal *);
  597. krb5_error_code(KRB5_CALLCONV *get_first)
  598. (krb5_context, krb5_ccache, krb5_cc_cursor *);
  599. krb5_error_code(KRB5_CALLCONV *get_next)
  600. (krb5_context, krb5_ccache, krb5_cc_cursor *, krb5_creds *);
  601. krb5_error_code(KRB5_CALLCONV *end_get)
  602. (krb5_context, krb5_ccache, krb5_cc_cursor *);
  603. krb5_error_code(KRB5_CALLCONV *remove_cred)
  604. (krb5_context, krb5_ccache, krb5_flags, krb5_creds *);
  605. krb5_error_code(KRB5_CALLCONV *set_flags)
  606. (krb5_context, krb5_ccache, krb5_flags);
  607. } krb5_cc_ops;
  608. # endif /* NO_DEF_KRB5_CCACHE */
  609. krb5_error_code
  610. kssl_krb5_cc_get_principal
  611. (krb5_context context, krb5_ccache cache, krb5_principal *principal) {
  612. if (p_krb5_cc_get_principal)
  613. return (p_krb5_cc_get_principal(context, cache, principal));
  614. else
  615. return (krb5_x((cache)->ops->get_princ, (context, cache, principal)));
  616. }
  617. krb5_error_code
  618. kssl_krb5_auth_con_setrcache(krb5_context con, krb5_auth_context acon,
  619. krb5_rcache rcache)
  620. {
  621. if (p_krb5_auth_con_setrcache)
  622. return (p_krb5_auth_con_setrcache(con, acon, rcache));
  623. else
  624. return KRB5KRB_ERR_GENERIC;
  625. }
  626. krb5_error_code
  627. kssl_krb5_get_server_rcache(krb5_context con, krb5_const krb5_data *data,
  628. krb5_rcache *rcache)
  629. {
  630. if (p_krb5_get_server_rcache)
  631. return (p_krb5_get_server_rcache(con, data, rcache));
  632. else
  633. return KRB5KRB_ERR_GENERIC;
  634. }
  635. krb5_error_code
  636. kssl_krb5_auth_con_getrcache(krb5_context con, krb5_auth_context acon,
  637. krb5_rcache *prcache)
  638. {
  639. if (p_krb5_auth_con_getrcache)
  640. return (p_krb5_auth_con_getrcache(con, acon, prcache));
  641. else
  642. return KRB5KRB_ERR_GENERIC;
  643. }
  644. krb5_error_code kssl_krb5_kt_close(krb5_context context, krb5_keytab keytab)
  645. {
  646. if (p_krb5_kt_close)
  647. return (p_krb5_kt_close(context, keytab));
  648. else
  649. return KRB5KRB_ERR_GENERIC;
  650. }
  651. krb5_error_code
  652. kssl_krb5_kt_get_entry(krb5_context context, krb5_keytab keytab,
  653. krb5_const_principal principal, krb5_kvno vno,
  654. krb5_enctype enctype, krb5_keytab_entry *entry)
  655. {
  656. if (p_krb5_kt_get_entry)
  657. return (p_krb5_kt_get_entry
  658. (context, keytab, principal, vno, enctype, entry));
  659. else
  660. return KRB5KRB_ERR_GENERIC;
  661. }
  662. # endif /* OPENSSL_SYS_WINDOWS || OPENSSL_SYS_WIN32 */
  663. /*
  664. * memory allocation functions for non-temporary storage (e.g. stuff that
  665. * gets saved into the kssl context)
  666. */
  667. static void *kssl_calloc(size_t nmemb, size_t size)
  668. {
  669. void *p;
  670. p = OPENSSL_malloc(nmemb * size);
  671. if (p) {
  672. memset(p, 0, nmemb * size);
  673. }
  674. return p;
  675. }
  676. # define kssl_malloc(size) OPENSSL_malloc((size))
  677. # define kssl_realloc(ptr, size) OPENSSL_realloc(ptr, size)
  678. # define kssl_free(ptr) OPENSSL_free((ptr))
  679. char
  680. *kstring(char *string)
  681. {
  682. static char *null = "[NULL]";
  683. return ((string == NULL) ? null : string);
  684. }
  685. /*
  686. * Given KRB5 enctype (basically DES or 3DES), return closest match openssl
  687. * EVP_ encryption algorithm. Return NULL for unknown or problematic
  688. * (krb5_dk_encrypt) enctypes. Assume ENCTYPE_*_RAW (krb5_raw_encrypt) are
  689. * OK.
  690. */
  691. const EVP_CIPHER *kssl_map_enc(krb5_enctype enctype)
  692. {
  693. switch (enctype) {
  694. case ENCTYPE_DES_HMAC_SHA1: /* EVP_des_cbc(); */
  695. case ENCTYPE_DES_CBC_CRC:
  696. case ENCTYPE_DES_CBC_MD4:
  697. case ENCTYPE_DES_CBC_MD5:
  698. case ENCTYPE_DES_CBC_RAW:
  699. return EVP_des_cbc();
  700. break;
  701. case ENCTYPE_DES3_CBC_SHA1: /* EVP_des_ede3_cbc(); */
  702. case ENCTYPE_DES3_CBC_SHA:
  703. case ENCTYPE_DES3_CBC_RAW:
  704. return EVP_des_ede3_cbc();
  705. break;
  706. default:
  707. return NULL;
  708. break;
  709. }
  710. }
  711. /*
  712. * Return true:1 if p "looks like" the start of the real authenticator
  713. * described in kssl_skip_confound() below. The ASN.1 pattern is "62 xx 30
  714. * yy" (APPLICATION-2, SEQUENCE), where xx-yy =~ 2, and xx and yy are
  715. * possibly multi-byte length fields.
  716. */
  717. static int kssl_test_confound(unsigned char *p)
  718. {
  719. int len = 2;
  720. int xx = 0, yy = 0;
  721. if (*p++ != 0x62)
  722. return 0;
  723. if (*p > 0x82)
  724. return 0;
  725. switch (*p) {
  726. case 0x82:
  727. p++;
  728. xx = (*p++ << 8);
  729. xx += *p++;
  730. break;
  731. case 0x81:
  732. p++;
  733. xx = *p++;
  734. break;
  735. case 0x80:
  736. return 0;
  737. default:
  738. xx = *p++;
  739. break;
  740. }
  741. if (*p++ != 0x30)
  742. return 0;
  743. if (*p > 0x82)
  744. return 0;
  745. switch (*p) {
  746. case 0x82:
  747. p++;
  748. len += 2;
  749. yy = (*p++ << 8);
  750. yy += *p++;
  751. break;
  752. case 0x81:
  753. p++;
  754. len++;
  755. yy = *p++;
  756. break;
  757. case 0x80:
  758. return 0;
  759. default:
  760. yy = *p++;
  761. break;
  762. }
  763. return (xx - len == yy) ? 1 : 0;
  764. }
  765. /*
  766. * Allocate, fill, and return cksumlens array of checksum lengths. This
  767. * array holds just the unique elements from the krb5_cksumarray[]. array[n]
  768. * == 0 signals end of data. The krb5_cksumarray[] was an internal variable
  769. * that has since been replaced by a more general method for storing the
  770. * data. It should not be used. Instead we use real API calls and make a
  771. * guess for what the highest assigned CKSUMTYPE_ constant is. As of 1.2.2
  772. * it is 0x000c (CKSUMTYPE_HMAC_SHA1_DES3). So we will use 0x0010.
  773. */
  774. static size_t *populate_cksumlens(void)
  775. {
  776. int i, j, n;
  777. static size_t *cklens = NULL;
  778. # ifdef KRB5_MIT_OLD11
  779. n = krb5_max_cksum;
  780. # else
  781. n = 0x0010;
  782. # endif /* KRB5_MIT_OLD11 */
  783. # ifdef KRB5CHECKAUTH
  784. if (!cklens && !(cklens = (size_t *)calloc(sizeof(int), n + 1)))
  785. return NULL;
  786. for (i = 0; i < n; i++) {
  787. if (!valid_cksumtype(i))
  788. continue; /* array has holes */
  789. for (j = 0; j < n; j++) {
  790. if (cklens[j] == 0) {
  791. cklens[j] = krb5_checksum_size(NULL, i);
  792. break; /* krb5 elem was new: add */
  793. }
  794. if (cklens[j] == krb5_checksum_size(NULL, i)) {
  795. break; /* ignore duplicate elements */
  796. }
  797. }
  798. }
  799. # endif /* KRB5CHECKAUTH */
  800. return cklens;
  801. }
  802. /*-
  803. * Return pointer to start of real authenticator within authenticator, or
  804. * return NULL on error.
  805. * Decrypted authenticator looks like this:
  806. * [0 or 8 byte confounder] [4-24 byte checksum] [real authent'r]
  807. * This hackery wouldn't be necessary if MIT KRB5 1.0.6 had the
  808. * krb5_auth_con_getcksumtype() function advertised in its krb5.h.
  809. */
  810. unsigned char *kssl_skip_confound(krb5_enctype etype, unsigned char *a)
  811. {
  812. int i, conlen;
  813. size_t cklen;
  814. static size_t *cksumlens = NULL;
  815. unsigned char *test_auth;
  816. conlen = (etype) ? 8 : 0;
  817. if (!cksumlens && !(cksumlens = populate_cksumlens()))
  818. return NULL;
  819. for (i = 0; (cklen = cksumlens[i]) != 0; i++) {
  820. test_auth = a + conlen + cklen;
  821. if (kssl_test_confound(test_auth))
  822. return test_auth;
  823. }
  824. return NULL;
  825. }
  826. /*
  827. * Set kssl_err error info when reason text is a simple string kssl_err =
  828. * struct { int reason; char text[KSSL_ERR_MAX+1]; }
  829. */
  830. void kssl_err_set(KSSL_ERR *kssl_err, int reason, char *text)
  831. {
  832. if (kssl_err == NULL)
  833. return;
  834. kssl_err->reason = reason;
  835. BIO_snprintf(kssl_err->text, KSSL_ERR_MAX, "%s", text);
  836. return;
  837. }
  838. /*
  839. * Display contents of krb5_data struct, for debugging
  840. */
  841. void print_krb5_data(char *label, krb5_data *kdata)
  842. {
  843. int i;
  844. fprintf(stderr, "%s[%d] ", label, kdata->length);
  845. for (i = 0; i < (int)kdata->length; i++) {
  846. if (0 && isprint((int)kdata->data[i]))
  847. fprintf(stderr, "%c ", kdata->data[i]);
  848. else
  849. fprintf(stderr, "%02x ", (unsigned char)kdata->data[i]);
  850. }
  851. fprintf(stderr, "\n");
  852. }
  853. /*
  854. * Display contents of krb5_authdata struct, for debugging
  855. */
  856. void print_krb5_authdata(char *label, krb5_authdata **adata)
  857. {
  858. if (adata == NULL) {
  859. fprintf(stderr, "%s, authdata==0\n", label);
  860. return;
  861. }
  862. fprintf(stderr, "%s [%p]\n", label, (void *)adata);
  863. # if 0
  864. {
  865. int i;
  866. fprintf(stderr, "%s[at%d:%d] ", label, adata->ad_type, adata->length);
  867. for (i = 0; i < adata->length; i++) {
  868. fprintf(stderr, (isprint(adata->contents[i])) ? "%c " : "%02x",
  869. adata->contents[i]);
  870. }
  871. fprintf(stderr, "\n");
  872. }
  873. # endif
  874. }
  875. /*
  876. * Display contents of krb5_keyblock struct, for debugging
  877. */
  878. void print_krb5_keyblock(char *label, krb5_keyblock *keyblk)
  879. {
  880. int i;
  881. if (keyblk == NULL) {
  882. fprintf(stderr, "%s, keyblk==0\n", label);
  883. return;
  884. }
  885. # ifdef KRB5_HEIMDAL
  886. fprintf(stderr, "%s\n\t[et%d:%d]: ", label, keyblk->keytype,
  887. keyblk->keyvalue->length);
  888. for (i = 0; i < (int)keyblk->keyvalue->length; i++) {
  889. fprintf(stderr, "%02x",
  890. (unsigned char *)(keyblk->keyvalue->contents)[i]);
  891. }
  892. fprintf(stderr, "\n");
  893. # else
  894. fprintf(stderr, "%s\n\t[et%d:%d]: ", label, keyblk->enctype,
  895. keyblk->length);
  896. for (i = 0; i < (int)keyblk->length; i++) {
  897. fprintf(stderr, "%02x", keyblk->contents[i]);
  898. }
  899. fprintf(stderr, "\n");
  900. # endif
  901. }
  902. /*
  903. * Display contents of krb5_principal_data struct, for debugging
  904. * (krb5_principal is typedef'd == krb5_principal_data *)
  905. */
  906. static void print_krb5_princ(char *label, krb5_principal_data *princ)
  907. {
  908. int i, ui, uj;
  909. fprintf(stderr, "%s principal Realm: ", label);
  910. if (princ == NULL)
  911. return;
  912. for (ui = 0; ui < (int)princ->realm.length; ui++)
  913. putchar(princ->realm.data[ui]);
  914. fprintf(stderr, " (nametype %d) has %d strings:\n", princ->type,
  915. princ->length);
  916. for (i = 0; i < (int)princ->length; i++) {
  917. fprintf(stderr, "\t%d [%d]: ", i, princ->data[i].length);
  918. for (uj = 0; uj < (int)princ->data[i].length; uj++) {
  919. putchar(princ->data[i].data[uj]);
  920. }
  921. fprintf(stderr, "\n");
  922. }
  923. return;
  924. }
  925. /*- Given krb5 service (typically "kssl") and hostname in kssl_ctx,
  926. * Return encrypted Kerberos ticket for service @ hostname.
  927. * If authenp is non-NULL, also return encrypted authenticator,
  928. * whose data should be freed by caller.
  929. * (Originally was: Create Kerberos AP_REQ message for SSL Client.)
  930. *
  931. * 19990628 VRS Started; Returns Kerberos AP_REQ message.
  932. * 20010409 VRS Modified for RFC2712; Returns enc tkt.
  933. * 20010606 VRS May also return optional authenticator.
  934. */
  935. krb5_error_code kssl_cget_tkt( /* UPDATE */ KSSL_CTX *kssl_ctx,
  936. /*
  937. * OUT
  938. */ krb5_data **enc_ticketp,
  939. /*
  940. * UPDATE
  941. */ krb5_data *authenp,
  942. /*
  943. * OUT
  944. */ KSSL_ERR *kssl_err)
  945. {
  946. krb5_error_code krb5rc = KRB5KRB_ERR_GENERIC;
  947. krb5_context krb5context = NULL;
  948. krb5_auth_context krb5auth_context = NULL;
  949. krb5_ccache krb5ccdef = NULL;
  950. krb5_creds krb5creds, *krb5credsp = NULL;
  951. krb5_data krb5_app_req;
  952. kssl_err_set(kssl_err, 0, "");
  953. memset((char *)&krb5creds, 0, sizeof(krb5creds));
  954. if (!kssl_ctx) {
  955. kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT, "No kssl_ctx defined.\n");
  956. goto err;
  957. } else if (!kssl_ctx->service_host) {
  958. kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT,
  959. "kssl_ctx service_host undefined.\n");
  960. goto err;
  961. }
  962. if ((krb5rc = krb5_init_context(&krb5context)) != 0) {
  963. BIO_snprintf(kssl_err->text, KSSL_ERR_MAX,
  964. "krb5_init_context() fails: %d\n", krb5rc);
  965. kssl_err->reason = SSL_R_KRB5_C_INIT;
  966. goto err;
  967. }
  968. if ((krb5rc = krb5_sname_to_principal(krb5context,
  969. kssl_ctx->service_host,
  970. (kssl_ctx->service_name) ?
  971. kssl_ctx->service_name : KRB5SVC,
  972. KRB5_NT_SRV_HST,
  973. &krb5creds.server)) != 0) {
  974. BIO_snprintf(kssl_err->text, KSSL_ERR_MAX,
  975. "krb5_sname_to_principal() fails for %s/%s\n",
  976. kssl_ctx->service_host,
  977. (kssl_ctx->
  978. service_name) ? kssl_ctx->service_name : KRB5SVC);
  979. kssl_err->reason = SSL_R_KRB5_C_INIT;
  980. goto err;
  981. }
  982. if ((krb5rc = krb5_cc_default(krb5context, &krb5ccdef)) != 0) {
  983. kssl_err_set(kssl_err, SSL_R_KRB5_C_CC_PRINC,
  984. "krb5_cc_default fails.\n");
  985. goto err;
  986. }
  987. if ((krb5rc = krb5_cc_get_principal(krb5context, krb5ccdef,
  988. &krb5creds.client)) != 0) {
  989. kssl_err_set(kssl_err, SSL_R_KRB5_C_CC_PRINC,
  990. "krb5_cc_get_principal() fails.\n");
  991. goto err;
  992. }
  993. if ((krb5rc = krb5_get_credentials(krb5context, 0, krb5ccdef,
  994. &krb5creds, &krb5credsp)) != 0) {
  995. kssl_err_set(kssl_err, SSL_R_KRB5_C_GET_CRED,
  996. "krb5_get_credentials() fails.\n");
  997. goto err;
  998. }
  999. *enc_ticketp = &krb5credsp->ticket;
  1000. # ifdef KRB5_HEIMDAL
  1001. kssl_ctx->enctype = krb5credsp->session.keytype;
  1002. # else
  1003. kssl_ctx->enctype = krb5credsp->keyblock.enctype;
  1004. # endif
  1005. krb5rc = KRB5KRB_ERR_GENERIC;
  1006. /* caller should free data of krb5_app_req */
  1007. /*
  1008. * 20010406 VRS deleted for real KerberosWrapper 20010605 VRS reinstated
  1009. * to offer Authenticator to KerberosWrapper
  1010. */
  1011. krb5_app_req.length = 0;
  1012. if (authenp) {
  1013. krb5_data krb5in_data;
  1014. const unsigned char *p;
  1015. long arlen;
  1016. KRB5_APREQBODY *ap_req;
  1017. authenp->length = 0;
  1018. krb5in_data.data = NULL;
  1019. krb5in_data.length = 0;
  1020. if ((krb5rc = krb5_mk_req_extended(krb5context,
  1021. &krb5auth_context, 0, &krb5in_data,
  1022. krb5credsp, &krb5_app_req)) != 0) {
  1023. kssl_err_set(kssl_err, SSL_R_KRB5_C_MK_REQ,
  1024. "krb5_mk_req_extended() fails.\n");
  1025. goto err;
  1026. }
  1027. arlen = krb5_app_req.length;
  1028. p = (unsigned char *)krb5_app_req.data;
  1029. ap_req = (KRB5_APREQBODY *)d2i_KRB5_APREQ(NULL, &p, arlen);
  1030. if (ap_req) {
  1031. authenp->length = i2d_KRB5_ENCDATA(ap_req->authenticator, NULL);
  1032. if (authenp->length && (authenp->data = malloc(authenp->length))) {
  1033. unsigned char *adp = (unsigned char *)authenp->data;
  1034. authenp->length =
  1035. i2d_KRB5_ENCDATA(ap_req->authenticator, &adp);
  1036. }
  1037. }
  1038. if (ap_req)
  1039. KRB5_APREQ_free((KRB5_APREQ *) ap_req);
  1040. if (krb5_app_req.length)
  1041. kssl_krb5_free_data_contents(krb5context, &krb5_app_req);
  1042. }
  1043. # ifdef KRB5_HEIMDAL
  1044. if (kssl_ctx_setkey(kssl_ctx, &krb5credsp->session)) {
  1045. kssl_err_set(kssl_err, SSL_R_KRB5_C_INIT,
  1046. "kssl_ctx_setkey() fails.\n");
  1047. }
  1048. # else
  1049. if (kssl_ctx_setkey(kssl_ctx, &krb5credsp->keyblock)) {
  1050. kssl_err_set(kssl_err, SSL_R_KRB5_C_INIT,
  1051. "kssl_ctx_setkey() fails.\n");
  1052. }
  1053. # endif
  1054. else
  1055. krb5rc = 0;
  1056. err:
  1057. # ifdef KSSL_DEBUG
  1058. kssl_ctx_show(kssl_ctx);
  1059. # endif /* KSSL_DEBUG */
  1060. if (krb5creds.client)
  1061. krb5_free_principal(krb5context, krb5creds.client);
  1062. if (krb5creds.server)
  1063. krb5_free_principal(krb5context, krb5creds.server);
  1064. if (krb5auth_context)
  1065. krb5_auth_con_free(krb5context, krb5auth_context);
  1066. if (krb5context)
  1067. krb5_free_context(krb5context);
  1068. return (krb5rc);
  1069. }
  1070. /*-
  1071. * Given d2i_-decoded asn1ticket, allocate and return a new krb5_ticket.
  1072. * Return Kerberos error code and kssl_err struct on error.
  1073. * Allocates krb5_ticket and krb5_principal; caller should free these.
  1074. *
  1075. * 20010410 VRS Implemented krb5_decode_ticket() as
  1076. * old_krb5_decode_ticket(). Missing from MIT1.0.6.
  1077. * 20010615 VRS Re-cast as openssl/asn1 d2i_*() functions.
  1078. * Re-used some of the old krb5_decode_ticket()
  1079. * code here. This tkt should alloc/free just
  1080. * like the real thing.
  1081. */
  1082. static krb5_error_code kssl_TKT2tkt( /* IN */ krb5_context krb5context,
  1083. /*
  1084. * IN
  1085. */ KRB5_TKTBODY *asn1ticket,
  1086. /*
  1087. * OUT
  1088. */ krb5_ticket **krb5ticket,
  1089. /*
  1090. * OUT
  1091. */ KSSL_ERR *kssl_err)
  1092. {
  1093. krb5_error_code krb5rc = KRB5KRB_ERR_GENERIC;
  1094. krb5_ticket *new5ticket = NULL;
  1095. ASN1_GENERALSTRING *gstr_svc, *gstr_host;
  1096. *krb5ticket = NULL;
  1097. if (asn1ticket == NULL || asn1ticket->realm == NULL ||
  1098. asn1ticket->sname == NULL ||
  1099. sk_ASN1_GENERALSTRING_num(asn1ticket->sname->namestring) < 2) {
  1100. BIO_snprintf(kssl_err->text, KSSL_ERR_MAX,
  1101. "Null field in asn1ticket.\n");
  1102. kssl_err->reason = SSL_R_KRB5_S_RD_REQ;
  1103. return KRB5KRB_ERR_GENERIC;
  1104. }
  1105. if ((new5ticket = (krb5_ticket *)calloc(1, sizeof(krb5_ticket))) == NULL) {
  1106. BIO_snprintf(kssl_err->text, KSSL_ERR_MAX,
  1107. "Unable to allocate new krb5_ticket.\n");
  1108. kssl_err->reason = SSL_R_KRB5_S_RD_REQ;
  1109. return ENOMEM; /* or KRB5KRB_ERR_GENERIC; */
  1110. }
  1111. gstr_svc = sk_ASN1_GENERALSTRING_value(asn1ticket->sname->namestring, 0);
  1112. gstr_host = sk_ASN1_GENERALSTRING_value(asn1ticket->sname->namestring, 1);
  1113. if ((krb5rc = kssl_build_principal_2(krb5context,
  1114. &new5ticket->server,
  1115. asn1ticket->realm->length,
  1116. (char *)asn1ticket->realm->data,
  1117. gstr_svc->length,
  1118. (char *)gstr_svc->data,
  1119. gstr_host->length,
  1120. (char *)gstr_host->data)) != 0) {
  1121. free(new5ticket);
  1122. BIO_snprintf(kssl_err->text, KSSL_ERR_MAX,
  1123. "Error building ticket server principal.\n");
  1124. kssl_err->reason = SSL_R_KRB5_S_RD_REQ;
  1125. return krb5rc; /* or KRB5KRB_ERR_GENERIC; */
  1126. }
  1127. krb5_princ_type(krb5context, new5ticket->server) =
  1128. asn1ticket->sname->nametype->data[0];
  1129. new5ticket->enc_part.enctype = asn1ticket->encdata->etype->data[0];
  1130. new5ticket->enc_part.kvno = asn1ticket->encdata->kvno->data[0];
  1131. new5ticket->enc_part.ciphertext.length =
  1132. asn1ticket->encdata->cipher->length;
  1133. if ((new5ticket->enc_part.ciphertext.data =
  1134. calloc(1, asn1ticket->encdata->cipher->length)) == NULL) {
  1135. free(new5ticket);
  1136. BIO_snprintf(kssl_err->text, KSSL_ERR_MAX,
  1137. "Error allocating cipher in krb5ticket.\n");
  1138. kssl_err->reason = SSL_R_KRB5_S_RD_REQ;
  1139. return KRB5KRB_ERR_GENERIC;
  1140. } else {
  1141. memcpy(new5ticket->enc_part.ciphertext.data,
  1142. asn1ticket->encdata->cipher->data,
  1143. asn1ticket->encdata->cipher->length);
  1144. }
  1145. *krb5ticket = new5ticket;
  1146. return 0;
  1147. }
  1148. /*-
  1149. * Given krb5 service name in KSSL_CTX *kssl_ctx (typically "kssl"),
  1150. * and krb5 AP_REQ message & message length,
  1151. * Return Kerberos session key and client principle
  1152. * to SSL Server in KSSL_CTX *kssl_ctx.
  1153. *
  1154. * 19990702 VRS Started.
  1155. */
  1156. krb5_error_code kssl_sget_tkt( /* UPDATE */ KSSL_CTX *kssl_ctx,
  1157. /*
  1158. * IN
  1159. */ krb5_data *indata,
  1160. /*
  1161. * OUT
  1162. */ krb5_ticket_times *ttimes,
  1163. /*
  1164. * OUT
  1165. */ KSSL_ERR *kssl_err)
  1166. {
  1167. krb5_error_code krb5rc = KRB5KRB_ERR_GENERIC;
  1168. static krb5_context krb5context = NULL;
  1169. static krb5_auth_context krb5auth_context = NULL;
  1170. krb5_ticket *krb5ticket = NULL;
  1171. KRB5_TKTBODY *asn1ticket = NULL;
  1172. const unsigned char *p;
  1173. krb5_keytab krb5keytab = NULL;
  1174. krb5_keytab_entry kt_entry;
  1175. krb5_principal krb5server;
  1176. krb5_rcache rcache = NULL;
  1177. kssl_err_set(kssl_err, 0, "");
  1178. if (!kssl_ctx) {
  1179. kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT, "No kssl_ctx defined.\n");
  1180. goto err;
  1181. }
  1182. # ifdef KSSL_DEBUG
  1183. fprintf(stderr, "in kssl_sget_tkt(%s)\n",
  1184. kstring(kssl_ctx->service_name));
  1185. # endif /* KSSL_DEBUG */
  1186. if (!krb5context && (krb5rc = krb5_init_context(&krb5context))) {
  1187. kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT,
  1188. "krb5_init_context() fails.\n");
  1189. goto err;
  1190. }
  1191. if (krb5auth_context &&
  1192. (krb5rc = krb5_auth_con_free(krb5context, krb5auth_context))) {
  1193. kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT,
  1194. "krb5_auth_con_free() fails.\n");
  1195. goto err;
  1196. } else
  1197. krb5auth_context = NULL;
  1198. if (!krb5auth_context &&
  1199. (krb5rc = krb5_auth_con_init(krb5context, &krb5auth_context))) {
  1200. kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT,
  1201. "krb5_auth_con_init() fails.\n");
  1202. goto err;
  1203. }
  1204. if ((krb5rc = krb5_auth_con_getrcache(krb5context, krb5auth_context,
  1205. &rcache))) {
  1206. kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT,
  1207. "krb5_auth_con_getrcache() fails.\n");
  1208. goto err;
  1209. }
  1210. if ((krb5rc = krb5_sname_to_principal(krb5context, NULL,
  1211. (kssl_ctx->service_name) ?
  1212. kssl_ctx->service_name : KRB5SVC,
  1213. KRB5_NT_SRV_HST,
  1214. &krb5server)) != 0) {
  1215. kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT,
  1216. "krb5_sname_to_principal() fails.\n");
  1217. goto err;
  1218. }
  1219. if (rcache == NULL) {
  1220. if ((krb5rc = krb5_get_server_rcache(krb5context,
  1221. krb5_princ_component(krb5context,
  1222. krb5server,
  1223. 0),
  1224. &rcache))) {
  1225. kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT,
  1226. "krb5_get_server_rcache() fails.\n");
  1227. goto err;
  1228. }
  1229. }
  1230. if ((krb5rc =
  1231. krb5_auth_con_setrcache(krb5context, krb5auth_context, rcache))) {
  1232. kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT,
  1233. "krb5_auth_con_setrcache() fails.\n");
  1234. goto err;
  1235. }
  1236. /*
  1237. * kssl_ctx->keytab_file == NULL ==> use Kerberos default
  1238. */
  1239. if (kssl_ctx->keytab_file) {
  1240. krb5rc = krb5_kt_resolve(krb5context, kssl_ctx->keytab_file,
  1241. &krb5keytab);
  1242. if (krb5rc) {
  1243. kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT,
  1244. "krb5_kt_resolve() fails.\n");
  1245. goto err;
  1246. }
  1247. } else {
  1248. krb5rc = krb5_kt_default(krb5context, &krb5keytab);
  1249. if (krb5rc) {
  1250. kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT,
  1251. "krb5_kt_default() fails.\n");
  1252. goto err;
  1253. }
  1254. }
  1255. /*- Actual Kerberos5 krb5_recvauth() has initial conversation here
  1256. * o check KRB5_SENDAUTH_BADAUTHVERS
  1257. * unless KRB5_RECVAUTH_SKIP_VERSION
  1258. * o check KRB5_SENDAUTH_BADAPPLVERS
  1259. * o send "0" msg if all OK
  1260. */
  1261. /*-
  1262. * 20010411 was using AP_REQ instead of true KerberosWrapper
  1263. *
  1264. * if ((krb5rc = krb5_rd_req(krb5context, &krb5auth_context,
  1265. * &krb5in_data, krb5server, krb5keytab,
  1266. * &ap_option, &krb5ticket)) != 0) { Error }
  1267. */
  1268. p = (unsigned char *)indata->data;
  1269. if ((asn1ticket = (KRB5_TKTBODY *)d2i_KRB5_TICKET(NULL, &p,
  1270. (long)indata->length))
  1271. == NULL) {
  1272. BIO_snprintf(kssl_err->text, KSSL_ERR_MAX,
  1273. "d2i_KRB5_TICKET() ASN.1 decode failure.\n");
  1274. kssl_err->reason = SSL_R_KRB5_S_RD_REQ;
  1275. goto err;
  1276. }
  1277. /*
  1278. * Was: krb5rc = krb5_decode_ticket(krb5in_data,&krb5ticket)) != 0)
  1279. */
  1280. if ((krb5rc = kssl_TKT2tkt(krb5context, asn1ticket, &krb5ticket,
  1281. kssl_err)) != 0) {
  1282. BIO_snprintf(kssl_err->text, KSSL_ERR_MAX,
  1283. "Error converting ASN.1 ticket to krb5_ticket.\n");
  1284. kssl_err->reason = SSL_R_KRB5_S_RD_REQ;
  1285. goto err;
  1286. }
  1287. if (!krb5_principal_compare(krb5context, krb5server, krb5ticket->server)) {
  1288. krb5rc = KRB5_PRINC_NOMATCH;
  1289. BIO_snprintf(kssl_err->text, KSSL_ERR_MAX,
  1290. "server principal != ticket principal\n");
  1291. kssl_err->reason = SSL_R_KRB5_S_RD_REQ;
  1292. goto err;
  1293. }
  1294. if ((krb5rc = krb5_kt_get_entry(krb5context, krb5keytab,
  1295. krb5ticket->server,
  1296. krb5ticket->enc_part.kvno,
  1297. krb5ticket->enc_part.enctype,
  1298. &kt_entry)) != 0) {
  1299. BIO_snprintf(kssl_err->text, KSSL_ERR_MAX,
  1300. "krb5_kt_get_entry() fails with %x.\n", krb5rc);
  1301. kssl_err->reason = SSL_R_KRB5_S_RD_REQ;
  1302. goto err;
  1303. }
  1304. if ((krb5rc = krb5_decrypt_tkt_part(krb5context, &kt_entry.key,
  1305. krb5ticket)) != 0) {
  1306. BIO_snprintf(kssl_err->text, KSSL_ERR_MAX,
  1307. "krb5_decrypt_tkt_part() failed.\n");
  1308. kssl_err->reason = SSL_R_KRB5_S_RD_REQ;
  1309. goto err;
  1310. } else {
  1311. krb5_kt_free_entry(krb5context, &kt_entry);
  1312. # ifdef KSSL_DEBUG
  1313. {
  1314. int i;
  1315. krb5_address **paddr = krb5ticket->enc_part2->caddrs;
  1316. fprintf(stderr, "Decrypted ticket fields:\n");
  1317. fprintf(stderr, "\tflags: %X, transit-type: %X",
  1318. krb5ticket->enc_part2->flags,
  1319. krb5ticket->enc_part2->transited.tr_type);
  1320. print_krb5_data("\ttransit-data: ",
  1321. &(krb5ticket->enc_part2->transited.tr_contents));
  1322. fprintf(stderr, "\tcaddrs: %p, authdata: %p\n",
  1323. krb5ticket->enc_part2->caddrs,
  1324. krb5ticket->enc_part2->authorization_data);
  1325. if (paddr) {
  1326. fprintf(stderr, "\tcaddrs:\n");
  1327. for (i = 0; paddr[i] != NULL; i++) {
  1328. krb5_data d;
  1329. d.length = paddr[i]->length;
  1330. d.data = paddr[i]->contents;
  1331. print_krb5_data("\t\tIP: ", &d);
  1332. }
  1333. }
  1334. fprintf(stderr, "\tstart/auth/end times: %d / %d / %d\n",
  1335. krb5ticket->enc_part2->times.starttime,
  1336. krb5ticket->enc_part2->times.authtime,
  1337. krb5ticket->enc_part2->times.endtime);
  1338. }
  1339. # endif /* KSSL_DEBUG */
  1340. }
  1341. krb5rc = KRB5_NO_TKT_SUPPLIED;
  1342. if (!krb5ticket || !krb5ticket->enc_part2 ||
  1343. !krb5ticket->enc_part2->client ||
  1344. !krb5ticket->enc_part2->client->data ||
  1345. !krb5ticket->enc_part2->session) {
  1346. kssl_err_set(kssl_err, SSL_R_KRB5_S_BAD_TICKET,
  1347. "bad ticket from krb5_rd_req.\n");
  1348. } else if (kssl_ctx_setprinc(kssl_ctx, KSSL_CLIENT,
  1349. &krb5ticket->enc_part2->client->realm,
  1350. krb5ticket->enc_part2->client->data,
  1351. krb5ticket->enc_part2->client->length)) {
  1352. kssl_err_set(kssl_err, SSL_R_KRB5_S_BAD_TICKET,
  1353. "kssl_ctx_setprinc() fails.\n");
  1354. } else if (kssl_ctx_setkey(kssl_ctx, krb5ticket->enc_part2->session)) {
  1355. kssl_err_set(kssl_err, SSL_R_KRB5_S_BAD_TICKET,
  1356. "kssl_ctx_setkey() fails.\n");
  1357. } else if (krb5ticket->enc_part2->flags & TKT_FLG_INVALID) {
  1358. krb5rc = KRB5KRB_AP_ERR_TKT_INVALID;
  1359. kssl_err_set(kssl_err, SSL_R_KRB5_S_BAD_TICKET,
  1360. "invalid ticket from krb5_rd_req.\n");
  1361. } else
  1362. krb5rc = 0;
  1363. kssl_ctx->enctype = krb5ticket->enc_part.enctype;
  1364. ttimes->authtime = krb5ticket->enc_part2->times.authtime;
  1365. ttimes->starttime = krb5ticket->enc_part2->times.starttime;
  1366. ttimes->endtime = krb5ticket->enc_part2->times.endtime;
  1367. ttimes->renew_till = krb5ticket->enc_part2->times.renew_till;
  1368. err:
  1369. # ifdef KSSL_DEBUG
  1370. kssl_ctx_show(kssl_ctx);
  1371. # endif /* KSSL_DEBUG */
  1372. if (asn1ticket)
  1373. KRB5_TICKET_free((KRB5_TICKET *) asn1ticket);
  1374. if (krb5keytab)
  1375. krb5_kt_close(krb5context, krb5keytab);
  1376. if (krb5ticket)
  1377. krb5_free_ticket(krb5context, krb5ticket);
  1378. if (krb5server)
  1379. krb5_free_principal(krb5context, krb5server);
  1380. return (krb5rc);
  1381. }
  1382. /*
  1383. * Allocate & return a new kssl_ctx struct.
  1384. */
  1385. KSSL_CTX *kssl_ctx_new(void)
  1386. {
  1387. return ((KSSL_CTX *)kssl_calloc(1, sizeof(KSSL_CTX)));
  1388. }
  1389. /*
  1390. * Frees a kssl_ctx struct and any allocated memory it holds. Returns NULL.
  1391. */
  1392. KSSL_CTX *kssl_ctx_free(KSSL_CTX *kssl_ctx)
  1393. {
  1394. if (kssl_ctx == NULL)
  1395. return kssl_ctx;
  1396. if (kssl_ctx->key)
  1397. OPENSSL_cleanse(kssl_ctx->key, kssl_ctx->length);
  1398. if (kssl_ctx->key)
  1399. kssl_free(kssl_ctx->key);
  1400. if (kssl_ctx->client_princ)
  1401. kssl_free(kssl_ctx->client_princ);
  1402. if (kssl_ctx->service_host)
  1403. kssl_free(kssl_ctx->service_host);
  1404. if (kssl_ctx->service_name)
  1405. kssl_free(kssl_ctx->service_name);
  1406. if (kssl_ctx->keytab_file)
  1407. kssl_free(kssl_ctx->keytab_file);
  1408. kssl_free(kssl_ctx);
  1409. return (KSSL_CTX *)NULL;
  1410. }
  1411. /*
  1412. * Given an array of (krb5_data *) entity (and optional realm), set the plain
  1413. * (char *) client_princ or service_host member of the kssl_ctx struct.
  1414. */
  1415. krb5_error_code
  1416. kssl_ctx_setprinc(KSSL_CTX *kssl_ctx, int which,
  1417. krb5_data *realm, krb5_data *entity, int nentities)
  1418. {
  1419. char **princ;
  1420. int length;
  1421. int i;
  1422. if (kssl_ctx == NULL || entity == NULL)
  1423. return KSSL_CTX_ERR;
  1424. switch (which) {
  1425. case KSSL_CLIENT:
  1426. princ = &kssl_ctx->client_princ;
  1427. break;
  1428. case KSSL_SERVER:
  1429. princ = &kssl_ctx->service_host;
  1430. break;
  1431. default:
  1432. return KSSL_CTX_ERR;
  1433. break;
  1434. }
  1435. if (*princ)
  1436. kssl_free(*princ);
  1437. /* Add up all the entity->lengths */
  1438. length = 0;
  1439. for (i = 0; i < nentities; i++) {
  1440. length += entity[i].length;
  1441. }
  1442. /* Add in space for the '/' character(s) (if any) */
  1443. length += nentities - 1;
  1444. /* Space for the ('@'+realm+NULL | NULL) */
  1445. length += ((realm) ? realm->length + 2 : 1);
  1446. if ((*princ = kssl_calloc(1, length)) == NULL)
  1447. return KSSL_CTX_ERR;
  1448. else {
  1449. for (i = 0; i < nentities; i++) {
  1450. strncat(*princ, entity[i].data, entity[i].length);
  1451. if (i < nentities - 1) {
  1452. strcat(*princ, "/");
  1453. }
  1454. }
  1455. if (realm) {
  1456. strcat(*princ, "@");
  1457. (void)strncat(*princ, realm->data, realm->length);
  1458. }
  1459. }
  1460. return KSSL_CTX_OK;
  1461. }
  1462. /*- Set one of the plain (char *) string members of the kssl_ctx struct.
  1463. * Default values should be:
  1464. * which == KSSL_SERVICE => "khost" (KRB5SVC)
  1465. * which == KSSL_KEYTAB => "/etc/krb5.keytab" (KRB5KEYTAB)
  1466. */
  1467. krb5_error_code kssl_ctx_setstring(KSSL_CTX *kssl_ctx, int which, char *text)
  1468. {
  1469. char **string;
  1470. if (!kssl_ctx)
  1471. return KSSL_CTX_ERR;
  1472. switch (which) {
  1473. case KSSL_SERVICE:
  1474. string = &kssl_ctx->service_name;
  1475. break;
  1476. case KSSL_SERVER:
  1477. string = &kssl_ctx->service_host;
  1478. break;
  1479. case KSSL_CLIENT:
  1480. string = &kssl_ctx->client_princ;
  1481. break;
  1482. case KSSL_KEYTAB:
  1483. string = &kssl_ctx->keytab_file;
  1484. break;
  1485. default:
  1486. return KSSL_CTX_ERR;
  1487. break;
  1488. }
  1489. if (*string)
  1490. kssl_free(*string);
  1491. if (!text) {
  1492. *string = '\0';
  1493. return KSSL_CTX_OK;
  1494. }
  1495. if ((*string = kssl_calloc(1, strlen(text) + 1)) == NULL)
  1496. return KSSL_CTX_ERR;
  1497. else
  1498. strcpy(*string, text);
  1499. return KSSL_CTX_OK;
  1500. }
  1501. /*
  1502. * Copy the Kerberos session key from a (krb5_keyblock *) to a kssl_ctx
  1503. * struct. Clear kssl_ctx->key if Kerberos session key is NULL.
  1504. */
  1505. krb5_error_code kssl_ctx_setkey(KSSL_CTX *kssl_ctx, krb5_keyblock *session)
  1506. {
  1507. int length;
  1508. krb5_enctype enctype;
  1509. krb5_octet FAR *contents = NULL;
  1510. if (!kssl_ctx)
  1511. return KSSL_CTX_ERR;
  1512. if (kssl_ctx->key) {
  1513. OPENSSL_cleanse(kssl_ctx->key, kssl_ctx->length);
  1514. kssl_free(kssl_ctx->key);
  1515. }
  1516. if (session) {
  1517. # ifdef KRB5_HEIMDAL
  1518. length = session->keyvalue->length;
  1519. enctype = session->keytype;
  1520. contents = session->keyvalue->contents;
  1521. # else
  1522. length = session->length;
  1523. enctype = session->enctype;
  1524. contents = session->contents;
  1525. # endif
  1526. kssl_ctx->enctype = enctype;
  1527. kssl_ctx->length = length;
  1528. } else {
  1529. kssl_ctx->enctype = ENCTYPE_UNKNOWN;
  1530. kssl_ctx->length = 0;
  1531. return KSSL_CTX_OK;
  1532. }
  1533. if ((kssl_ctx->key =
  1534. (krb5_octet FAR *)kssl_calloc(1, kssl_ctx->length)) == NULL) {
  1535. kssl_ctx->length = 0;
  1536. return KSSL_CTX_ERR;
  1537. } else
  1538. memcpy(kssl_ctx->key, contents, length);
  1539. return KSSL_CTX_OK;
  1540. }
  1541. /*
  1542. * Display contents of kssl_ctx struct
  1543. */
  1544. void kssl_ctx_show(KSSL_CTX *kssl_ctx)
  1545. {
  1546. int i;
  1547. printf("kssl_ctx: ");
  1548. if (kssl_ctx == NULL) {
  1549. printf("NULL\n");
  1550. return;
  1551. } else
  1552. printf("%p\n", (void *)kssl_ctx);
  1553. printf("\tservice:\t%s\n",
  1554. (kssl_ctx->service_name) ? kssl_ctx->service_name : "NULL");
  1555. printf("\tclient:\t%s\n",
  1556. (kssl_ctx->client_princ) ? kssl_ctx->client_princ : "NULL");
  1557. printf("\tserver:\t%s\n",
  1558. (kssl_ctx->service_host) ? kssl_ctx->service_host : "NULL");
  1559. printf("\tkeytab:\t%s\n",
  1560. (kssl_ctx->keytab_file) ? kssl_ctx->keytab_file : "NULL");
  1561. printf("\tkey [%d:%d]:\t", kssl_ctx->enctype, kssl_ctx->length);
  1562. for (i = 0; i < kssl_ctx->length && kssl_ctx->key; i++) {
  1563. printf("%02x", kssl_ctx->key[i]);
  1564. }
  1565. printf("\n");
  1566. return;
  1567. }
  1568. int kssl_keytab_is_available(KSSL_CTX *kssl_ctx)
  1569. {
  1570. krb5_context krb5context = NULL;
  1571. krb5_keytab krb5keytab = NULL;
  1572. krb5_keytab_entry entry;
  1573. krb5_principal princ = NULL;
  1574. krb5_error_code krb5rc = KRB5KRB_ERR_GENERIC;
  1575. int rc = 0;
  1576. if ((krb5rc = krb5_init_context(&krb5context)))
  1577. return (0);
  1578. /*
  1579. * kssl_ctx->keytab_file == NULL ==> use Kerberos default
  1580. */
  1581. if (kssl_ctx->keytab_file) {
  1582. krb5rc = krb5_kt_resolve(krb5context, kssl_ctx->keytab_file,
  1583. &krb5keytab);
  1584. if (krb5rc)
  1585. goto exit;
  1586. } else {
  1587. krb5rc = krb5_kt_default(krb5context, &krb5keytab);
  1588. if (krb5rc)
  1589. goto exit;
  1590. }
  1591. /* the host key we are looking for */
  1592. krb5rc = krb5_sname_to_principal(krb5context, NULL,
  1593. kssl_ctx->
  1594. service_name ? kssl_ctx->service_name :
  1595. KRB5SVC, KRB5_NT_SRV_HST, &princ);
  1596. if (krb5rc)
  1597. goto exit;
  1598. krb5rc = krb5_kt_get_entry(krb5context, krb5keytab, princ,
  1599. /* IGNORE_VNO */
  1600. 0,
  1601. /* IGNORE_ENCTYPE */
  1602. 0, &entry);
  1603. if (krb5rc == KRB5_KT_NOTFOUND) {
  1604. rc = 1;
  1605. goto exit;
  1606. } else if (krb5rc)
  1607. goto exit;
  1608. krb5_kt_free_entry(krb5context, &entry);
  1609. rc = 1;
  1610. exit:
  1611. if (krb5keytab)
  1612. krb5_kt_close(krb5context, krb5keytab);
  1613. if (princ)
  1614. krb5_free_principal(krb5context, princ);
  1615. if (krb5context)
  1616. krb5_free_context(krb5context);
  1617. return (rc);
  1618. }
  1619. int kssl_tgt_is_available(KSSL_CTX *kssl_ctx)
  1620. {
  1621. krb5_error_code krb5rc = KRB5KRB_ERR_GENERIC;
  1622. krb5_context krb5context = NULL;
  1623. krb5_ccache krb5ccdef = NULL;
  1624. krb5_creds krb5creds, *krb5credsp = NULL;
  1625. int rc = 0;
  1626. memset((char *)&krb5creds, 0, sizeof(krb5creds));
  1627. if (!kssl_ctx)
  1628. return (0);
  1629. if (!kssl_ctx->service_host)
  1630. return (0);
  1631. if ((krb5rc = krb5_init_context(&krb5context)) != 0)
  1632. goto err;
  1633. if ((krb5rc = krb5_sname_to_principal(krb5context,
  1634. kssl_ctx->service_host,
  1635. (kssl_ctx->service_name) ?
  1636. kssl_ctx->service_name : KRB5SVC,
  1637. KRB5_NT_SRV_HST,
  1638. &krb5creds.server)) != 0)
  1639. goto err;
  1640. if ((krb5rc = krb5_cc_default(krb5context, &krb5ccdef)) != 0)
  1641. goto err;
  1642. if ((krb5rc = krb5_cc_get_principal(krb5context, krb5ccdef,
  1643. &krb5creds.client)) != 0)
  1644. goto err;
  1645. if ((krb5rc = krb5_get_credentials(krb5context, 0, krb5ccdef,
  1646. &krb5creds, &krb5credsp)) != 0)
  1647. goto err;
  1648. rc = 1;
  1649. err:
  1650. # ifdef KSSL_DEBUG
  1651. kssl_ctx_show(kssl_ctx);
  1652. # endif /* KSSL_DEBUG */
  1653. if (krb5creds.client)
  1654. krb5_free_principal(krb5context, krb5creds.client);
  1655. if (krb5creds.server)
  1656. krb5_free_principal(krb5context, krb5creds.server);
  1657. if (krb5context)
  1658. krb5_free_context(krb5context);
  1659. return (rc);
  1660. }
  1661. # if !defined(OPENSSL_SYS_WINDOWS) && !defined(OPENSSL_SYS_WIN32)
  1662. void kssl_krb5_free_data_contents(krb5_context context, krb5_data *data)
  1663. {
  1664. # ifdef KRB5_HEIMDAL
  1665. data->length = 0;
  1666. if (data->data)
  1667. free(data->data);
  1668. # elif defined(KRB5_MIT_OLD11)
  1669. if (data->data) {
  1670. krb5_xfree(data->data);
  1671. data->data = 0;
  1672. }
  1673. # else
  1674. krb5_free_data_contents(NULL, data);
  1675. # endif
  1676. }
  1677. # endif
  1678. /* !OPENSSL_SYS_WINDOWS && !OPENSSL_SYS_WIN32 */
  1679. /*
  1680. * Given pointers to KerberosTime and struct tm structs, convert the
  1681. * KerberosTime string to struct tm. Note that KerberosTime is a
  1682. * ASN1_GENERALIZEDTIME value, constrained to GMT with no fractional seconds
  1683. * as defined in RFC 1510. Return pointer to the (partially) filled in
  1684. * struct tm on success, return NULL on failure.
  1685. */
  1686. static struct tm *k_gmtime(ASN1_GENERALIZEDTIME *gtime, struct tm *k_tm)
  1687. {
  1688. char c, *p;
  1689. if (!k_tm)
  1690. return NULL;
  1691. if (gtime == NULL || gtime->length < 14)
  1692. return NULL;
  1693. if (gtime->data == NULL)
  1694. return NULL;
  1695. p = (char *)&gtime->data[14];
  1696. c = *p;
  1697. *p = '\0';
  1698. p -= 2;
  1699. k_tm->tm_sec = atoi(p);
  1700. *(p + 2) = c;
  1701. c = *p;
  1702. *p = '\0';
  1703. p -= 2;
  1704. k_tm->tm_min = atoi(p);
  1705. *(p + 2) = c;
  1706. c = *p;
  1707. *p = '\0';
  1708. p -= 2;
  1709. k_tm->tm_hour = atoi(p);
  1710. *(p + 2) = c;
  1711. c = *p;
  1712. *p = '\0';
  1713. p -= 2;
  1714. k_tm->tm_mday = atoi(p);
  1715. *(p + 2) = c;
  1716. c = *p;
  1717. *p = '\0';
  1718. p -= 2;
  1719. k_tm->tm_mon = atoi(p) - 1;
  1720. *(p + 2) = c;
  1721. c = *p;
  1722. *p = '\0';
  1723. p -= 4;
  1724. k_tm->tm_year = atoi(p) - 1900;
  1725. *(p + 4) = c;
  1726. return k_tm;
  1727. }
  1728. /*
  1729. * Helper function for kssl_validate_times(). We need context->clockskew,
  1730. * but krb5_context is an opaque struct. So we try to sneek the clockskew
  1731. * out through the replay cache. If that fails just return a likely default
  1732. * (300 seconds).
  1733. */
  1734. static krb5_deltat get_rc_clockskew(krb5_context context)
  1735. {
  1736. krb5_rcache rc;
  1737. krb5_deltat clockskew;
  1738. if (krb5_rc_default(context, &rc))
  1739. return KSSL_CLOCKSKEW;
  1740. if (krb5_rc_initialize(context, rc, 0))
  1741. return KSSL_CLOCKSKEW;
  1742. if (krb5_rc_get_lifespan(context, rc, &clockskew)) {
  1743. clockskew = KSSL_CLOCKSKEW;
  1744. }
  1745. (void)krb5_rc_destroy(context, rc);
  1746. return clockskew;
  1747. }
  1748. /*
  1749. * kssl_validate_times() combines (and more importantly exposes) the MIT KRB5
  1750. * internal function krb5_validate_times() and the in_clock_skew() macro.
  1751. * The authenticator client time is checked to be within clockskew secs of
  1752. * the current time and the current time is checked to be within the ticket
  1753. * start and expire times. Either check may be omitted by supplying a NULL
  1754. * value. Returns 0 for valid times, SSL_R_KRB5* error codes otherwise. See
  1755. * Also: (Kerberos source)/krb5/lib/krb5/krb/valid_times.c 20010420 VRS
  1756. */
  1757. krb5_error_code kssl_validate_times(krb5_timestamp atime,
  1758. krb5_ticket_times *ttimes)
  1759. {
  1760. krb5_deltat skew;
  1761. krb5_timestamp start, now;
  1762. krb5_error_code rc;
  1763. krb5_context context;
  1764. if ((rc = krb5_init_context(&context)))
  1765. return SSL_R_KRB5_S_BAD_TICKET;
  1766. skew = get_rc_clockskew(context);
  1767. if ((rc = krb5_timeofday(context, &now)))
  1768. return SSL_R_KRB5_S_BAD_TICKET;
  1769. krb5_free_context(context);
  1770. if (atime && labs(atime - now) >= skew)
  1771. return SSL_R_KRB5_S_TKT_SKEW;
  1772. if (!ttimes)
  1773. return 0;
  1774. start = (ttimes->starttime != 0) ? ttimes->starttime : ttimes->authtime;
  1775. if (start - now > skew)
  1776. return SSL_R_KRB5_S_TKT_NYV;
  1777. if ((now - ttimes->endtime) > skew)
  1778. return SSL_R_KRB5_S_TKT_EXPIRED;
  1779. # ifdef KSSL_DEBUG
  1780. fprintf(stderr, "kssl_validate_times: %d |<- | %d - %d | < %d ->| %d\n",
  1781. start, atime, now, skew, ttimes->endtime);
  1782. # endif /* KSSL_DEBUG */
  1783. return 0;
  1784. }
  1785. /*
  1786. * Decode and decrypt given DER-encoded authenticator, then pass
  1787. * authenticator ctime back in *atimep (or 0 if time unavailable). Returns
  1788. * krb5_error_code and kssl_err on error. A NULL authenticator
  1789. * (authentp->length == 0) is not considered an error. Note that
  1790. * kssl_check_authent() makes use of the KRB5 session key; you must call
  1791. * kssl_sget_tkt() to get the key before calling this routine.
  1792. */
  1793. krb5_error_code kssl_check_authent(
  1794. /*
  1795. * IN
  1796. */ KSSL_CTX *kssl_ctx,
  1797. /*
  1798. * IN
  1799. */ krb5_data *authentp,
  1800. /*
  1801. * OUT
  1802. */ krb5_timestamp *atimep,
  1803. /*
  1804. * OUT
  1805. */ KSSL_ERR *kssl_err)
  1806. {
  1807. krb5_error_code krb5rc = 0;
  1808. KRB5_ENCDATA *dec_authent = NULL;
  1809. KRB5_AUTHENTBODY *auth = NULL;
  1810. krb5_enctype enctype;
  1811. EVP_CIPHER_CTX ciph_ctx;
  1812. const EVP_CIPHER *enc = NULL;
  1813. unsigned char iv[EVP_MAX_IV_LENGTH];
  1814. const unsigned char *p;
  1815. unsigned char *unenc_authent;
  1816. int outl, unencbufsize;
  1817. struct tm tm_time, *tm_l, *tm_g;
  1818. time_t now, tl, tg, tr, tz_offset;
  1819. EVP_CIPHER_CTX_init(&ciph_ctx);
  1820. *atimep = 0;
  1821. kssl_err_set(kssl_err, 0, "");
  1822. # ifndef KRB5CHECKAUTH
  1823. authentp = NULL;
  1824. # else
  1825. # if KRB5CHECKAUTH == 0
  1826. authentp = NULL;
  1827. # endif
  1828. # endif /* KRB5CHECKAUTH */
  1829. if (authentp == NULL || authentp->length == 0)
  1830. return 0;
  1831. # ifdef KSSL_DEBUG
  1832. {
  1833. unsigned int ui;
  1834. fprintf(stderr, "kssl_check_authent: authenticator[%d]:\n",
  1835. authentp->length);
  1836. p = authentp->data;
  1837. for (ui = 0; ui < authentp->length; ui++)
  1838. fprintf(stderr, "%02x ", p[ui]);
  1839. fprintf(stderr, "\n");
  1840. }
  1841. # endif /* KSSL_DEBUG */
  1842. unencbufsize = 2 * authentp->length;
  1843. if ((unenc_authent = calloc(1, unencbufsize)) == NULL) {
  1844. kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT,
  1845. "Unable to allocate authenticator buffer.\n");
  1846. krb5rc = KRB5KRB_ERR_GENERIC;
  1847. goto err;
  1848. }
  1849. p = (unsigned char *)authentp->data;
  1850. if ((dec_authent = d2i_KRB5_ENCDATA(NULL, &p,
  1851. (long)authentp->length)) == NULL) {
  1852. kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT,
  1853. "Error decoding authenticator.\n");
  1854. krb5rc = KRB5KRB_AP_ERR_BAD_INTEGRITY;
  1855. goto err;
  1856. }
  1857. enctype = dec_authent->etype->data[0]; /* should = kssl_ctx->enctype */
  1858. # if !defined(KRB5_MIT_OLD11)
  1859. switch (enctype) {
  1860. case ENCTYPE_DES3_CBC_SHA1: /* EVP_des_ede3_cbc(); */
  1861. case ENCTYPE_DES3_CBC_SHA:
  1862. case ENCTYPE_DES3_CBC_RAW:
  1863. krb5rc = 0; /* Skip, can't handle derived keys */
  1864. goto err;
  1865. }
  1866. # endif
  1867. enc = kssl_map_enc(enctype);
  1868. memset(iv, 0, sizeof iv); /* per RFC 1510 */
  1869. if (enc == NULL) {
  1870. /*
  1871. * Disable kssl_check_authent for ENCTYPE_DES3_CBC_SHA1. This
  1872. * enctype indicates the authenticator was encrypted using key-usage
  1873. * derived keys which openssl cannot decrypt.
  1874. */
  1875. goto err;
  1876. }
  1877. if (!EVP_CipherInit(&ciph_ctx, enc, kssl_ctx->key, iv, 0)) {
  1878. kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT,
  1879. "EVP_CipherInit error decrypting authenticator.\n");
  1880. krb5rc = KRB5KRB_AP_ERR_BAD_INTEGRITY;
  1881. goto err;
  1882. }
  1883. outl = dec_authent->cipher->length;
  1884. if (!EVP_Cipher
  1885. (&ciph_ctx, unenc_authent, dec_authent->cipher->data, outl)) {
  1886. kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT,
  1887. "EVP_Cipher error decrypting authenticator.\n");
  1888. krb5rc = KRB5KRB_AP_ERR_BAD_INTEGRITY;
  1889. goto err;
  1890. }
  1891. EVP_CIPHER_CTX_cleanup(&ciph_ctx);
  1892. # ifdef KSSL_DEBUG
  1893. {
  1894. int padl;
  1895. fprintf(stderr, "kssl_check_authent: decrypted authenticator[%d] =\n",
  1896. outl);
  1897. for (padl = 0; padl < outl; padl++)
  1898. fprintf(stderr, "%02x ", unenc_authent[padl]);
  1899. fprintf(stderr, "\n");
  1900. }
  1901. # endif /* KSSL_DEBUG */
  1902. if ((p = kssl_skip_confound(enctype, unenc_authent)) == NULL) {
  1903. kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT,
  1904. "confounded by authenticator.\n");
  1905. krb5rc = KRB5KRB_AP_ERR_BAD_INTEGRITY;
  1906. goto err;
  1907. }
  1908. outl -= p - unenc_authent;
  1909. if ((auth = (KRB5_AUTHENTBODY *)d2i_KRB5_AUTHENT(NULL, &p,
  1910. (long)outl)) == NULL) {
  1911. kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT,
  1912. "Error decoding authenticator body.\n");
  1913. krb5rc = KRB5KRB_AP_ERR_BAD_INTEGRITY;
  1914. goto err;
  1915. }
  1916. memset(&tm_time, 0, sizeof(struct tm));
  1917. if (k_gmtime(auth->ctime, &tm_time) &&
  1918. ((tr = mktime(&tm_time)) != (time_t)(-1))) {
  1919. now = time(&now);
  1920. tm_l = localtime(&now);
  1921. tl = mktime(tm_l);
  1922. tm_g = gmtime(&now);
  1923. tg = mktime(tm_g);
  1924. tz_offset = tg - tl;
  1925. *atimep = (krb5_timestamp)(tr - tz_offset);
  1926. }
  1927. # ifdef KSSL_DEBUG
  1928. fprintf(stderr, "kssl_check_authent: returns %d for client time ",
  1929. *atimep);
  1930. if (auth && auth->ctime && auth->ctime->length && auth->ctime->data)
  1931. fprintf(stderr, "%.*s\n", auth->ctime->length, auth->ctime->data);
  1932. else
  1933. fprintf(stderr, "NULL\n");
  1934. # endif /* KSSL_DEBUG */
  1935. err:
  1936. if (auth)
  1937. KRB5_AUTHENT_free((KRB5_AUTHENT *) auth);
  1938. if (dec_authent)
  1939. KRB5_ENCDATA_free(dec_authent);
  1940. if (unenc_authent)
  1941. free(unenc_authent);
  1942. EVP_CIPHER_CTX_cleanup(&ciph_ctx);
  1943. return krb5rc;
  1944. }
  1945. /*
  1946. * Replaces krb5_build_principal_ext(), with varargs length == 2 (svc, host),
  1947. * because I don't know how to stub varargs. Returns krb5_error_code ==
  1948. * ENOMEM on alloc error, otherwise passes back newly constructed principal,
  1949. * which should be freed by caller.
  1950. */
  1951. krb5_error_code kssl_build_principal_2(
  1952. /*
  1953. * UPDATE
  1954. */ krb5_context context,
  1955. /*
  1956. * OUT
  1957. */ krb5_principal *princ,
  1958. /*
  1959. * IN
  1960. */ int rlen, const char *realm,
  1961. /*
  1962. * IN
  1963. */ int slen, const char *svc,
  1964. /*
  1965. * IN
  1966. */ int hlen, const char *host)
  1967. {
  1968. krb5_data *p_data = NULL;
  1969. krb5_principal new_p = NULL;
  1970. char *new_r = NULL;
  1971. if ((p_data = (krb5_data *)calloc(2, sizeof(krb5_data))) == NULL ||
  1972. (new_p = (krb5_principal)calloc(1, sizeof(krb5_principal_data)))
  1973. == NULL)
  1974. goto err;
  1975. new_p->length = 2;
  1976. new_p->data = p_data;
  1977. if ((new_r = calloc(1, rlen + 1)) == NULL)
  1978. goto err;
  1979. memcpy(new_r, realm, rlen);
  1980. krb5_princ_set_realm_length(context, new_p, rlen);
  1981. krb5_princ_set_realm_data(context, new_p, new_r);
  1982. if ((new_p->data[0].data = calloc(1, slen + 1)) == NULL)
  1983. goto err;
  1984. memcpy(new_p->data[0].data, svc, slen);
  1985. new_p->data[0].length = slen;
  1986. if ((new_p->data[1].data = calloc(1, hlen + 1)) == NULL)
  1987. goto err;
  1988. memcpy(new_p->data[1].data, host, hlen);
  1989. new_p->data[1].length = hlen;
  1990. krb5_princ_type(context, new_p) = KRB5_NT_UNKNOWN;
  1991. *princ = new_p;
  1992. return 0;
  1993. err:
  1994. if (new_p && new_p[0].data)
  1995. free(new_p[0].data);
  1996. if (new_p && new_p[1].data)
  1997. free(new_p[1].data);
  1998. if (new_p)
  1999. free(new_p);
  2000. if (new_r)
  2001. free(new_r);
  2002. return ENOMEM;
  2003. }
  2004. void SSL_set0_kssl_ctx(SSL *s, KSSL_CTX *kctx)
  2005. {
  2006. s->kssl_ctx = kctx;
  2007. }
  2008. KSSL_CTX *SSL_get0_kssl_ctx(SSL *s)
  2009. {
  2010. return s->kssl_ctx;
  2011. }
  2012. char *kssl_ctx_get0_client_princ(KSSL_CTX *kctx)
  2013. {
  2014. if (kctx)
  2015. return kctx->client_princ;
  2016. return NULL;
  2017. }
  2018. #else /* !OPENSSL_NO_KRB5 */
  2019. # if defined(PEDANTIC) || defined(OPENSSL_SYS_VMS)
  2020. static void *dummy = &dummy;
  2021. # endif
  2022. #endif /* !OPENSSL_NO_KRB5 */