kssl.c 74 KB

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