@platformatic/rdkafka 4.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (767) hide show
  1. package/.editorconfig +5 -0
  2. package/.jshintignore +1 -0
  3. package/.jshintrc +23 -0
  4. package/CONTRIBUTING.md +237 -0
  5. package/LICENSE.txt +21 -0
  6. package/Makefile +94 -0
  7. package/README.md +630 -0
  8. package/bench/consumer-raw-rdkafka.js +76 -0
  9. package/bench/consumer-subscribe.js +77 -0
  10. package/bench/kafka-consumer-stream.js +100 -0
  11. package/bench/producer-raw-rdkafka.js +125 -0
  12. package/bench/producer-rdkafka.js +117 -0
  13. package/bench/seed.sh +38 -0
  14. package/binding.gyp +155 -0
  15. package/ci/checks/librdkafka-correct-version.js +67 -0
  16. package/ci/checks/librdkafka-exists.js +13 -0
  17. package/ci/librdkafka-defs-generator.js +193 -0
  18. package/ci/prepublish.js +3 -0
  19. package/config.d.ts +1132 -0
  20. package/configure +15 -0
  21. package/cpplint.py +6325 -0
  22. package/deploy.enc +0 -0
  23. package/deps/librdkafka/.clang-format +136 -0
  24. package/deps/librdkafka/.clang-format-cpp +103 -0
  25. package/deps/librdkafka/.dir-locals.el +10 -0
  26. package/deps/librdkafka/.formatignore +33 -0
  27. package/deps/librdkafka/.gdbmacros +19 -0
  28. package/deps/librdkafka/.semaphore/project.yml +43 -0
  29. package/deps/librdkafka/.semaphore/project_public.yml +20 -0
  30. package/deps/librdkafka/.semaphore/semaphore.yml +355 -0
  31. package/deps/librdkafka/CHANGELOG.md +1738 -0
  32. package/deps/librdkafka/CMakeLists.txt +291 -0
  33. package/deps/librdkafka/CODE_OF_CONDUCT.md +46 -0
  34. package/deps/librdkafka/CONFIGURATION.md +189 -0
  35. package/deps/librdkafka/CONTRIBUTING.md +431 -0
  36. package/deps/librdkafka/Doxyfile +2375 -0
  37. package/deps/librdkafka/INTRODUCTION.md +2173 -0
  38. package/deps/librdkafka/LICENSE +26 -0
  39. package/deps/librdkafka/LICENSE.cjson +22 -0
  40. package/deps/librdkafka/LICENSE.crc32c +28 -0
  41. package/deps/librdkafka/LICENSE.fnv1a +18 -0
  42. package/deps/librdkafka/LICENSE.hdrhistogram +27 -0
  43. package/deps/librdkafka/LICENSE.lz4 +26 -0
  44. package/deps/librdkafka/LICENSE.murmur2 +25 -0
  45. package/deps/librdkafka/LICENSE.nanopb +22 -0
  46. package/deps/librdkafka/LICENSE.opentelemetry +203 -0
  47. package/deps/librdkafka/LICENSE.pycrc +23 -0
  48. package/deps/librdkafka/LICENSE.queue +31 -0
  49. package/deps/librdkafka/LICENSE.regexp +5 -0
  50. package/deps/librdkafka/LICENSE.snappy +36 -0
  51. package/deps/librdkafka/LICENSE.tinycthread +26 -0
  52. package/deps/librdkafka/LICENSE.wingetopt +49 -0
  53. package/deps/librdkafka/LICENSES.txt +625 -0
  54. package/deps/librdkafka/Makefile +124 -0
  55. package/deps/librdkafka/README.md +199 -0
  56. package/deps/librdkafka/README.win32 +26 -0
  57. package/deps/librdkafka/STATISTICS.md +624 -0
  58. package/deps/librdkafka/configure +214 -0
  59. package/deps/librdkafka/configure.self +331 -0
  60. package/deps/librdkafka/debian/changelog +111 -0
  61. package/deps/librdkafka/debian/compat +1 -0
  62. package/deps/librdkafka/debian/control +71 -0
  63. package/deps/librdkafka/debian/copyright +99 -0
  64. package/deps/librdkafka/debian/gbp.conf +9 -0
  65. package/deps/librdkafka/debian/librdkafka++1.install +1 -0
  66. package/deps/librdkafka/debian/librdkafka-dev.examples +2 -0
  67. package/deps/librdkafka/debian/librdkafka-dev.install +9 -0
  68. package/deps/librdkafka/debian/librdkafka1.docs +5 -0
  69. package/deps/librdkafka/debian/librdkafka1.install +1 -0
  70. package/deps/librdkafka/debian/librdkafka1.symbols +135 -0
  71. package/deps/librdkafka/debian/rules +19 -0
  72. package/deps/librdkafka/debian/source/format +1 -0
  73. package/deps/librdkafka/debian/watch +2 -0
  74. package/deps/librdkafka/dev-conf.sh +123 -0
  75. package/deps/librdkafka/examples/CMakeLists.txt +79 -0
  76. package/deps/librdkafka/examples/Makefile +167 -0
  77. package/deps/librdkafka/examples/README.md +42 -0
  78. package/deps/librdkafka/examples/alter_consumer_group_offsets.c +338 -0
  79. package/deps/librdkafka/examples/consumer.c +261 -0
  80. package/deps/librdkafka/examples/delete_records.c +233 -0
  81. package/deps/librdkafka/examples/describe_cluster.c +322 -0
  82. package/deps/librdkafka/examples/describe_consumer_groups.c +436 -0
  83. package/deps/librdkafka/examples/describe_topics.c +427 -0
  84. package/deps/librdkafka/examples/elect_leaders.c +317 -0
  85. package/deps/librdkafka/examples/globals.json +11 -0
  86. package/deps/librdkafka/examples/idempotent_producer.c +344 -0
  87. package/deps/librdkafka/examples/incremental_alter_configs.c +348 -0
  88. package/deps/librdkafka/examples/kafkatest_verifiable_client.cpp +961 -0
  89. package/deps/librdkafka/examples/list_consumer_group_offsets.c +359 -0
  90. package/deps/librdkafka/examples/list_consumer_groups.c +365 -0
  91. package/deps/librdkafka/examples/list_offsets.c +327 -0
  92. package/deps/librdkafka/examples/misc.c +287 -0
  93. package/deps/librdkafka/examples/openssl_engine_example.cpp +249 -0
  94. package/deps/librdkafka/examples/producer.c +251 -0
  95. package/deps/librdkafka/examples/producer.cpp +228 -0
  96. package/deps/librdkafka/examples/rdkafka_complex_consumer_example.c +617 -0
  97. package/deps/librdkafka/examples/rdkafka_complex_consumer_example.cpp +467 -0
  98. package/deps/librdkafka/examples/rdkafka_consume_batch.cpp +264 -0
  99. package/deps/librdkafka/examples/rdkafka_example.c +853 -0
  100. package/deps/librdkafka/examples/rdkafka_example.cpp +679 -0
  101. package/deps/librdkafka/examples/rdkafka_performance.c +1781 -0
  102. package/deps/librdkafka/examples/transactions-older-broker.c +668 -0
  103. package/deps/librdkafka/examples/transactions.c +665 -0
  104. package/deps/librdkafka/examples/user_scram.c +492 -0
  105. package/deps/librdkafka/examples/win_ssl_cert_store.cpp +395 -0
  106. package/deps/librdkafka/lds-gen.py +73 -0
  107. package/deps/librdkafka/mainpage.doxy +40 -0
  108. package/deps/librdkafka/mklove/Makefile.base +329 -0
  109. package/deps/librdkafka/mklove/modules/configure.atomics +144 -0
  110. package/deps/librdkafka/mklove/modules/configure.base +2484 -0
  111. package/deps/librdkafka/mklove/modules/configure.builtin +70 -0
  112. package/deps/librdkafka/mklove/modules/configure.cc +186 -0
  113. package/deps/librdkafka/mklove/modules/configure.cxx +8 -0
  114. package/deps/librdkafka/mklove/modules/configure.fileversion +65 -0
  115. package/deps/librdkafka/mklove/modules/configure.gitversion +29 -0
  116. package/deps/librdkafka/mklove/modules/configure.good_cflags +18 -0
  117. package/deps/librdkafka/mklove/modules/configure.host +132 -0
  118. package/deps/librdkafka/mklove/modules/configure.lib +49 -0
  119. package/deps/librdkafka/mklove/modules/configure.libcurl +99 -0
  120. package/deps/librdkafka/mklove/modules/configure.libsasl2 +36 -0
  121. package/deps/librdkafka/mklove/modules/configure.libssl +147 -0
  122. package/deps/librdkafka/mklove/modules/configure.libzstd +58 -0
  123. package/deps/librdkafka/mklove/modules/configure.parseversion +95 -0
  124. package/deps/librdkafka/mklove/modules/configure.pic +16 -0
  125. package/deps/librdkafka/mklove/modules/configure.socket +20 -0
  126. package/deps/librdkafka/mklove/modules/configure.zlib +61 -0
  127. package/deps/librdkafka/mklove/modules/patches/README.md +8 -0
  128. package/deps/librdkafka/mklove/modules/patches/libcurl.0000-no-runtime-linking-check.patch +11 -0
  129. package/deps/librdkafka/mklove/modules/patches/libssl.0000-osx-rand-include-fix-OpenSSL-PR16409.patch +56 -0
  130. package/deps/librdkafka/packaging/RELEASE.md +311 -0
  131. package/deps/librdkafka/packaging/alpine/build-alpine.sh +38 -0
  132. package/deps/librdkafka/packaging/archlinux/PKGBUILD +30 -0
  133. package/deps/librdkafka/packaging/cmake/Config.cmake.in +37 -0
  134. package/deps/librdkafka/packaging/cmake/Modules/FindLZ4.cmake +38 -0
  135. package/deps/librdkafka/packaging/cmake/Modules/FindZSTD.cmake +27 -0
  136. package/deps/librdkafka/packaging/cmake/Modules/LICENSE.FindZstd +178 -0
  137. package/deps/librdkafka/packaging/cmake/README.md +38 -0
  138. package/deps/librdkafka/packaging/cmake/config.h.in +52 -0
  139. package/deps/librdkafka/packaging/cmake/parseversion.cmake +60 -0
  140. package/deps/librdkafka/packaging/cmake/rdkafka.pc.in +12 -0
  141. package/deps/librdkafka/packaging/cmake/try_compile/atomic_32_test.c +8 -0
  142. package/deps/librdkafka/packaging/cmake/try_compile/atomic_64_test.c +8 -0
  143. package/deps/librdkafka/packaging/cmake/try_compile/c11threads_test.c +14 -0
  144. package/deps/librdkafka/packaging/cmake/try_compile/crc32c_hw_test.c +27 -0
  145. package/deps/librdkafka/packaging/cmake/try_compile/dlopen_test.c +11 -0
  146. package/deps/librdkafka/packaging/cmake/try_compile/libsasl2_test.c +7 -0
  147. package/deps/librdkafka/packaging/cmake/try_compile/pthread_setname_darwin_test.c +6 -0
  148. package/deps/librdkafka/packaging/cmake/try_compile/pthread_setname_freebsd_test.c +7 -0
  149. package/deps/librdkafka/packaging/cmake/try_compile/pthread_setname_gnu_test.c +5 -0
  150. package/deps/librdkafka/packaging/cmake/try_compile/rand_r_test.c +7 -0
  151. package/deps/librdkafka/packaging/cmake/try_compile/rdkafka_setup.cmake +122 -0
  152. package/deps/librdkafka/packaging/cmake/try_compile/regex_test.c +10 -0
  153. package/deps/librdkafka/packaging/cmake/try_compile/strndup_test.c +5 -0
  154. package/deps/librdkafka/packaging/cmake/try_compile/sync_32_test.c +8 -0
  155. package/deps/librdkafka/packaging/cmake/try_compile/sync_64_test.c +8 -0
  156. package/deps/librdkafka/packaging/cp/README.md +13 -0
  157. package/deps/librdkafka/packaging/cp/check_features.c +64 -0
  158. package/deps/librdkafka/packaging/cp/verify-deb.sh +33 -0
  159. package/deps/librdkafka/packaging/cp/verify-packages.sh +48 -0
  160. package/deps/librdkafka/packaging/cp/verify-rpm.sh +39 -0
  161. package/deps/librdkafka/packaging/debian/changelog +66 -0
  162. package/deps/librdkafka/packaging/debian/compat +1 -0
  163. package/deps/librdkafka/packaging/debian/control +49 -0
  164. package/deps/librdkafka/packaging/debian/copyright +84 -0
  165. package/deps/librdkafka/packaging/debian/gbp.conf +9 -0
  166. package/deps/librdkafka/packaging/debian/librdkafka-dev.dirs +2 -0
  167. package/deps/librdkafka/packaging/debian/librdkafka-dev.examples +2 -0
  168. package/deps/librdkafka/packaging/debian/librdkafka-dev.install +6 -0
  169. package/deps/librdkafka/packaging/debian/librdkafka-dev.substvars +1 -0
  170. package/deps/librdkafka/packaging/debian/librdkafka.dsc +16 -0
  171. package/deps/librdkafka/packaging/debian/librdkafka1-dbg.substvars +1 -0
  172. package/deps/librdkafka/packaging/debian/librdkafka1.dirs +1 -0
  173. package/deps/librdkafka/packaging/debian/librdkafka1.install +2 -0
  174. package/deps/librdkafka/packaging/debian/librdkafka1.postinst.debhelper +5 -0
  175. package/deps/librdkafka/packaging/debian/librdkafka1.postrm.debhelper +5 -0
  176. package/deps/librdkafka/packaging/debian/librdkafka1.symbols +64 -0
  177. package/deps/librdkafka/packaging/debian/rules +19 -0
  178. package/deps/librdkafka/packaging/debian/source/format +1 -0
  179. package/deps/librdkafka/packaging/debian/watch +2 -0
  180. package/deps/librdkafka/packaging/get_version.py +21 -0
  181. package/deps/librdkafka/packaging/homebrew/README.md +15 -0
  182. package/deps/librdkafka/packaging/homebrew/brew-update-pr.sh +31 -0
  183. package/deps/librdkafka/packaging/mingw-w64/configure-build-msys2-mingw-static.sh +52 -0
  184. package/deps/librdkafka/packaging/mingw-w64/configure-build-msys2-mingw.sh +21 -0
  185. package/deps/librdkafka/packaging/mingw-w64/run-tests.sh +6 -0
  186. package/deps/librdkafka/packaging/mingw-w64/semaphoreci-build.sh +38 -0
  187. package/deps/librdkafka/packaging/mingw-w64/travis-before-install.sh +20 -0
  188. package/deps/librdkafka/packaging/nuget/README.md +84 -0
  189. package/deps/librdkafka/packaging/nuget/artifact.py +177 -0
  190. package/deps/librdkafka/packaging/nuget/cleanup-s3.py +143 -0
  191. package/deps/librdkafka/packaging/nuget/common/p-common__plat-windows__arch-win32__bldtype-Release/msvcr120.zip +0 -0
  192. package/deps/librdkafka/packaging/nuget/common/p-common__plat-windows__arch-win32__bldtype-Release/msvcr140.zip +0 -0
  193. package/deps/librdkafka/packaging/nuget/common/p-common__plat-windows__arch-x64__bldtype-Release/msvcr120.zip +0 -0
  194. package/deps/librdkafka/packaging/nuget/common/p-common__plat-windows__arch-x64__bldtype-Release/msvcr140.zip +0 -0
  195. package/deps/librdkafka/packaging/nuget/nuget.sh +21 -0
  196. package/deps/librdkafka/packaging/nuget/nugetpackage.py +278 -0
  197. package/deps/librdkafka/packaging/nuget/packaging.py +448 -0
  198. package/deps/librdkafka/packaging/nuget/push-to-nuget.sh +21 -0
  199. package/deps/librdkafka/packaging/nuget/release.py +167 -0
  200. package/deps/librdkafka/packaging/nuget/requirements.txt +3 -0
  201. package/deps/librdkafka/packaging/nuget/staticpackage.py +178 -0
  202. package/deps/librdkafka/packaging/nuget/templates/librdkafka.redist.nuspec +21 -0
  203. package/deps/librdkafka/packaging/nuget/templates/librdkafka.redist.props +18 -0
  204. package/deps/librdkafka/packaging/nuget/templates/librdkafka.redist.targets +19 -0
  205. package/deps/librdkafka/packaging/nuget/zfile/__init__.py +0 -0
  206. package/deps/librdkafka/packaging/nuget/zfile/zfile.py +98 -0
  207. package/deps/librdkafka/packaging/rpm/Makefile +92 -0
  208. package/deps/librdkafka/packaging/rpm/README.md +23 -0
  209. package/deps/librdkafka/packaging/rpm/el7-x86_64.cfg +40 -0
  210. package/deps/librdkafka/packaging/rpm/librdkafka.spec +118 -0
  211. package/deps/librdkafka/packaging/rpm/mock-on-docker.sh +96 -0
  212. package/deps/librdkafka/packaging/rpm/tests/Makefile +25 -0
  213. package/deps/librdkafka/packaging/rpm/tests/README.md +8 -0
  214. package/deps/librdkafka/packaging/rpm/tests/run-test.sh +42 -0
  215. package/deps/librdkafka/packaging/rpm/tests/test-on-docker.sh +56 -0
  216. package/deps/librdkafka/packaging/rpm/tests/test.c +77 -0
  217. package/deps/librdkafka/packaging/rpm/tests/test.cpp +34 -0
  218. package/deps/librdkafka/packaging/tools/build-configurations-checks.sh +10 -0
  219. package/deps/librdkafka/packaging/tools/build-deb-package.sh +64 -0
  220. package/deps/librdkafka/packaging/tools/build-debian.sh +65 -0
  221. package/deps/librdkafka/packaging/tools/build-manylinux.sh +68 -0
  222. package/deps/librdkafka/packaging/tools/build-release-artifacts.sh +139 -0
  223. package/deps/librdkafka/packaging/tools/distro-build.sh +38 -0
  224. package/deps/librdkafka/packaging/tools/gh-release-checksums.py +39 -0
  225. package/deps/librdkafka/packaging/tools/rdutcoverage.sh +25 -0
  226. package/deps/librdkafka/packaging/tools/requirements.txt +2 -0
  227. package/deps/librdkafka/packaging/tools/style-format.sh +148 -0
  228. package/deps/librdkafka/service.yml +18 -0
  229. package/deps/librdkafka/src/CMakeLists.txt +374 -0
  230. package/deps/librdkafka/src/Makefile +103 -0
  231. package/deps/librdkafka/src/README.lz4.md +30 -0
  232. package/deps/librdkafka/src/cJSON.c +2834 -0
  233. package/deps/librdkafka/src/cJSON.h +398 -0
  234. package/deps/librdkafka/src/crc32c.c +430 -0
  235. package/deps/librdkafka/src/crc32c.h +38 -0
  236. package/deps/librdkafka/src/generate_proto.sh +66 -0
  237. package/deps/librdkafka/src/librdkafka_cgrp_synch.png +0 -0
  238. package/deps/librdkafka/src/lz4.c +2727 -0
  239. package/deps/librdkafka/src/lz4.h +842 -0
  240. package/deps/librdkafka/src/lz4frame.c +2078 -0
  241. package/deps/librdkafka/src/lz4frame.h +692 -0
  242. package/deps/librdkafka/src/lz4frame_static.h +47 -0
  243. package/deps/librdkafka/src/lz4hc.c +1631 -0
  244. package/deps/librdkafka/src/lz4hc.h +413 -0
  245. package/deps/librdkafka/src/nanopb/pb.h +917 -0
  246. package/deps/librdkafka/src/nanopb/pb_common.c +388 -0
  247. package/deps/librdkafka/src/nanopb/pb_common.h +49 -0
  248. package/deps/librdkafka/src/nanopb/pb_decode.c +1727 -0
  249. package/deps/librdkafka/src/nanopb/pb_decode.h +193 -0
  250. package/deps/librdkafka/src/nanopb/pb_encode.c +1000 -0
  251. package/deps/librdkafka/src/nanopb/pb_encode.h +185 -0
  252. package/deps/librdkafka/src/opentelemetry/common.pb.c +32 -0
  253. package/deps/librdkafka/src/opentelemetry/common.pb.h +170 -0
  254. package/deps/librdkafka/src/opentelemetry/metrics.options +2 -0
  255. package/deps/librdkafka/src/opentelemetry/metrics.pb.c +67 -0
  256. package/deps/librdkafka/src/opentelemetry/metrics.pb.h +966 -0
  257. package/deps/librdkafka/src/opentelemetry/resource.pb.c +12 -0
  258. package/deps/librdkafka/src/opentelemetry/resource.pb.h +58 -0
  259. package/deps/librdkafka/src/queue.h +850 -0
  260. package/deps/librdkafka/src/rd.h +441 -0
  261. package/deps/librdkafka/src/rdaddr.c +255 -0
  262. package/deps/librdkafka/src/rdaddr.h +203 -0
  263. package/deps/librdkafka/src/rdatomic.h +226 -0
  264. package/deps/librdkafka/src/rdavg.h +259 -0
  265. package/deps/librdkafka/src/rdavl.c +210 -0
  266. package/deps/librdkafka/src/rdavl.h +250 -0
  267. package/deps/librdkafka/src/rdbase64.c +169 -0
  268. package/deps/librdkafka/src/rdbase64.h +41 -0
  269. package/deps/librdkafka/src/rdbuf.c +1884 -0
  270. package/deps/librdkafka/src/rdbuf.h +375 -0
  271. package/deps/librdkafka/src/rdcrc32.c +114 -0
  272. package/deps/librdkafka/src/rdcrc32.h +170 -0
  273. package/deps/librdkafka/src/rddl.c +179 -0
  274. package/deps/librdkafka/src/rddl.h +43 -0
  275. package/deps/librdkafka/src/rdendian.h +174 -0
  276. package/deps/librdkafka/src/rdfloat.h +67 -0
  277. package/deps/librdkafka/src/rdfnv1a.c +113 -0
  278. package/deps/librdkafka/src/rdfnv1a.h +35 -0
  279. package/deps/librdkafka/src/rdgz.c +120 -0
  280. package/deps/librdkafka/src/rdgz.h +46 -0
  281. package/deps/librdkafka/src/rdhdrhistogram.c +721 -0
  282. package/deps/librdkafka/src/rdhdrhistogram.h +87 -0
  283. package/deps/librdkafka/src/rdhttp.c +512 -0
  284. package/deps/librdkafka/src/rdhttp.h +83 -0
  285. package/deps/librdkafka/src/rdinterval.h +177 -0
  286. package/deps/librdkafka/src/rdkafka.c +5351 -0
  287. package/deps/librdkafka/src/rdkafka.h +10603 -0
  288. package/deps/librdkafka/src/rdkafka_admin.c +9417 -0
  289. package/deps/librdkafka/src/rdkafka_admin.h +619 -0
  290. package/deps/librdkafka/src/rdkafka_assignment.c +1010 -0
  291. package/deps/librdkafka/src/rdkafka_assignment.h +73 -0
  292. package/deps/librdkafka/src/rdkafka_assignor.c +1786 -0
  293. package/deps/librdkafka/src/rdkafka_assignor.h +402 -0
  294. package/deps/librdkafka/src/rdkafka_aux.c +409 -0
  295. package/deps/librdkafka/src/rdkafka_aux.h +174 -0
  296. package/deps/librdkafka/src/rdkafka_background.c +221 -0
  297. package/deps/librdkafka/src/rdkafka_broker.c +6186 -0
  298. package/deps/librdkafka/src/rdkafka_broker.h +686 -0
  299. package/deps/librdkafka/src/rdkafka_buf.c +540 -0
  300. package/deps/librdkafka/src/rdkafka_buf.h +1524 -0
  301. package/deps/librdkafka/src/rdkafka_cert.c +552 -0
  302. package/deps/librdkafka/src/rdkafka_cert.h +61 -0
  303. package/deps/librdkafka/src/rdkafka_cgrp.c +7262 -0
  304. package/deps/librdkafka/src/rdkafka_cgrp.h +443 -0
  305. package/deps/librdkafka/src/rdkafka_conf.c +4456 -0
  306. package/deps/librdkafka/src/rdkafka_conf.h +668 -0
  307. package/deps/librdkafka/src/rdkafka_confval.h +97 -0
  308. package/deps/librdkafka/src/rdkafka_coord.c +623 -0
  309. package/deps/librdkafka/src/rdkafka_coord.h +132 -0
  310. package/deps/librdkafka/src/rdkafka_error.c +228 -0
  311. package/deps/librdkafka/src/rdkafka_error.h +80 -0
  312. package/deps/librdkafka/src/rdkafka_event.c +502 -0
  313. package/deps/librdkafka/src/rdkafka_event.h +126 -0
  314. package/deps/librdkafka/src/rdkafka_feature.c +461 -0
  315. package/deps/librdkafka/src/rdkafka_feature.h +102 -0
  316. package/deps/librdkafka/src/rdkafka_fetcher.c +1402 -0
  317. package/deps/librdkafka/src/rdkafka_fetcher.h +44 -0
  318. package/deps/librdkafka/src/rdkafka_header.c +220 -0
  319. package/deps/librdkafka/src/rdkafka_header.h +76 -0
  320. package/deps/librdkafka/src/rdkafka_idempotence.c +807 -0
  321. package/deps/librdkafka/src/rdkafka_idempotence.h +144 -0
  322. package/deps/librdkafka/src/rdkafka_int.h +1222 -0
  323. package/deps/librdkafka/src/rdkafka_interceptor.c +819 -0
  324. package/deps/librdkafka/src/rdkafka_interceptor.h +104 -0
  325. package/deps/librdkafka/src/rdkafka_lz4.c +450 -0
  326. package/deps/librdkafka/src/rdkafka_lz4.h +49 -0
  327. package/deps/librdkafka/src/rdkafka_metadata.c +2124 -0
  328. package/deps/librdkafka/src/rdkafka_metadata.h +341 -0
  329. package/deps/librdkafka/src/rdkafka_metadata_cache.c +977 -0
  330. package/deps/librdkafka/src/rdkafka_mock.c +2885 -0
  331. package/deps/librdkafka/src/rdkafka_mock.h +491 -0
  332. package/deps/librdkafka/src/rdkafka_mock_cgrp.c +710 -0
  333. package/deps/librdkafka/src/rdkafka_mock_handlers.c +2817 -0
  334. package/deps/librdkafka/src/rdkafka_mock_int.h +591 -0
  335. package/deps/librdkafka/src/rdkafka_msg.c +2573 -0
  336. package/deps/librdkafka/src/rdkafka_msg.h +614 -0
  337. package/deps/librdkafka/src/rdkafka_msgbatch.h +62 -0
  338. package/deps/librdkafka/src/rdkafka_msgset.h +98 -0
  339. package/deps/librdkafka/src/rdkafka_msgset_reader.c +1806 -0
  340. package/deps/librdkafka/src/rdkafka_msgset_writer.c +1470 -0
  341. package/deps/librdkafka/src/rdkafka_offset.c +1537 -0
  342. package/deps/librdkafka/src/rdkafka_offset.h +150 -0
  343. package/deps/librdkafka/src/rdkafka_op.c +997 -0
  344. package/deps/librdkafka/src/rdkafka_op.h +834 -0
  345. package/deps/librdkafka/src/rdkafka_partition.c +4801 -0
  346. package/deps/librdkafka/src/rdkafka_partition.h +1173 -0
  347. package/deps/librdkafka/src/rdkafka_pattern.c +228 -0
  348. package/deps/librdkafka/src/rdkafka_pattern.h +70 -0
  349. package/deps/librdkafka/src/rdkafka_plugin.c +213 -0
  350. package/deps/librdkafka/src/rdkafka_plugin.h +41 -0
  351. package/deps/librdkafka/src/rdkafka_proto.h +733 -0
  352. package/deps/librdkafka/src/rdkafka_protocol.h +127 -0
  353. package/deps/librdkafka/src/rdkafka_queue.c +1153 -0
  354. package/deps/librdkafka/src/rdkafka_queue.h +1201 -0
  355. package/deps/librdkafka/src/rdkafka_range_assignor.c +1748 -0
  356. package/deps/librdkafka/src/rdkafka_request.c +6817 -0
  357. package/deps/librdkafka/src/rdkafka_request.h +709 -0
  358. package/deps/librdkafka/src/rdkafka_roundrobin_assignor.c +123 -0
  359. package/deps/librdkafka/src/rdkafka_sasl.c +528 -0
  360. package/deps/librdkafka/src/rdkafka_sasl.h +63 -0
  361. package/deps/librdkafka/src/rdkafka_sasl_cyrus.c +722 -0
  362. package/deps/librdkafka/src/rdkafka_sasl_int.h +89 -0
  363. package/deps/librdkafka/src/rdkafka_sasl_oauthbearer.c +1829 -0
  364. package/deps/librdkafka/src/rdkafka_sasl_oauthbearer.h +52 -0
  365. package/deps/librdkafka/src/rdkafka_sasl_oauthbearer_oidc.c +589 -0
  366. package/deps/librdkafka/src/rdkafka_sasl_oauthbearer_oidc.h +37 -0
  367. package/deps/librdkafka/src/rdkafka_sasl_plain.c +142 -0
  368. package/deps/librdkafka/src/rdkafka_sasl_scram.c +857 -0
  369. package/deps/librdkafka/src/rdkafka_sasl_win32.c +550 -0
  370. package/deps/librdkafka/src/rdkafka_ssl.c +1904 -0
  371. package/deps/librdkafka/src/rdkafka_ssl.h +64 -0
  372. package/deps/librdkafka/src/rdkafka_sticky_assignor.c +4781 -0
  373. package/deps/librdkafka/src/rdkafka_subscription.c +278 -0
  374. package/deps/librdkafka/src/rdkafka_telemetry.c +703 -0
  375. package/deps/librdkafka/src/rdkafka_telemetry.h +52 -0
  376. package/deps/librdkafka/src/rdkafka_telemetry_decode.c +1053 -0
  377. package/deps/librdkafka/src/rdkafka_telemetry_decode.h +59 -0
  378. package/deps/librdkafka/src/rdkafka_telemetry_encode.c +993 -0
  379. package/deps/librdkafka/src/rdkafka_telemetry_encode.h +301 -0
  380. package/deps/librdkafka/src/rdkafka_timer.c +402 -0
  381. package/deps/librdkafka/src/rdkafka_timer.h +117 -0
  382. package/deps/librdkafka/src/rdkafka_topic.c +2078 -0
  383. package/deps/librdkafka/src/rdkafka_topic.h +328 -0
  384. package/deps/librdkafka/src/rdkafka_transport.c +1297 -0
  385. package/deps/librdkafka/src/rdkafka_transport.h +94 -0
  386. package/deps/librdkafka/src/rdkafka_transport_int.h +100 -0
  387. package/deps/librdkafka/src/rdkafka_txnmgr.c +3251 -0
  388. package/deps/librdkafka/src/rdkafka_txnmgr.h +171 -0
  389. package/deps/librdkafka/src/rdkafka_zstd.c +226 -0
  390. package/deps/librdkafka/src/rdkafka_zstd.h +57 -0
  391. package/deps/librdkafka/src/rdlist.c +576 -0
  392. package/deps/librdkafka/src/rdlist.h +434 -0
  393. package/deps/librdkafka/src/rdlog.c +89 -0
  394. package/deps/librdkafka/src/rdlog.h +41 -0
  395. package/deps/librdkafka/src/rdmap.c +503 -0
  396. package/deps/librdkafka/src/rdmap.h +492 -0
  397. package/deps/librdkafka/src/rdmurmur2.c +167 -0
  398. package/deps/librdkafka/src/rdmurmur2.h +35 -0
  399. package/deps/librdkafka/src/rdports.c +61 -0
  400. package/deps/librdkafka/src/rdports.h +38 -0
  401. package/deps/librdkafka/src/rdposix.h +250 -0
  402. package/deps/librdkafka/src/rdrand.c +70 -0
  403. package/deps/librdkafka/src/rdrand.h +43 -0
  404. package/deps/librdkafka/src/rdregex.c +156 -0
  405. package/deps/librdkafka/src/rdregex.h +43 -0
  406. package/deps/librdkafka/src/rdsignal.h +57 -0
  407. package/deps/librdkafka/src/rdstring.c +645 -0
  408. package/deps/librdkafka/src/rdstring.h +98 -0
  409. package/deps/librdkafka/src/rdsysqueue.h +404 -0
  410. package/deps/librdkafka/src/rdtime.h +325 -0
  411. package/deps/librdkafka/src/rdtypes.h +86 -0
  412. package/deps/librdkafka/src/rdunittest.c +532 -0
  413. package/deps/librdkafka/src/rdunittest.h +230 -0
  414. package/deps/librdkafka/src/rdvarint.c +134 -0
  415. package/deps/librdkafka/src/rdvarint.h +165 -0
  416. package/deps/librdkafka/src/rdwin32.h +382 -0
  417. package/deps/librdkafka/src/rdxxhash.c +1030 -0
  418. package/deps/librdkafka/src/rdxxhash.h +328 -0
  419. package/deps/librdkafka/src/regexp.c +1347 -0
  420. package/deps/librdkafka/src/regexp.h +41 -0
  421. package/deps/librdkafka/src/snappy.c +1866 -0
  422. package/deps/librdkafka/src/snappy.h +62 -0
  423. package/deps/librdkafka/src/snappy_compat.h +138 -0
  424. package/deps/librdkafka/src/statistics_schema.json +444 -0
  425. package/deps/librdkafka/src/tinycthread.c +932 -0
  426. package/deps/librdkafka/src/tinycthread.h +503 -0
  427. package/deps/librdkafka/src/tinycthread_extra.c +175 -0
  428. package/deps/librdkafka/src/tinycthread_extra.h +208 -0
  429. package/deps/librdkafka/src/win32_config.h +58 -0
  430. package/deps/librdkafka/src-cpp/CMakeLists.txt +90 -0
  431. package/deps/librdkafka/src-cpp/ConfImpl.cpp +84 -0
  432. package/deps/librdkafka/src-cpp/ConsumerImpl.cpp +244 -0
  433. package/deps/librdkafka/src-cpp/HandleImpl.cpp +436 -0
  434. package/deps/librdkafka/src-cpp/HeadersImpl.cpp +48 -0
  435. package/deps/librdkafka/src-cpp/KafkaConsumerImpl.cpp +296 -0
  436. package/deps/librdkafka/src-cpp/Makefile +55 -0
  437. package/deps/librdkafka/src-cpp/MessageImpl.cpp +38 -0
  438. package/deps/librdkafka/src-cpp/MetadataImpl.cpp +170 -0
  439. package/deps/librdkafka/src-cpp/ProducerImpl.cpp +197 -0
  440. package/deps/librdkafka/src-cpp/QueueImpl.cpp +70 -0
  441. package/deps/librdkafka/src-cpp/README.md +16 -0
  442. package/deps/librdkafka/src-cpp/RdKafka.cpp +59 -0
  443. package/deps/librdkafka/src-cpp/TopicImpl.cpp +124 -0
  444. package/deps/librdkafka/src-cpp/TopicPartitionImpl.cpp +57 -0
  445. package/deps/librdkafka/src-cpp/rdkafkacpp.h +3771 -0
  446. package/deps/librdkafka/src-cpp/rdkafkacpp_int.h +1641 -0
  447. package/deps/librdkafka/tests/0000-unittests.c +72 -0
  448. package/deps/librdkafka/tests/0001-multiobj.c +98 -0
  449. package/deps/librdkafka/tests/0002-unkpart.c +244 -0
  450. package/deps/librdkafka/tests/0003-msgmaxsize.c +173 -0
  451. package/deps/librdkafka/tests/0004-conf.c +867 -0
  452. package/deps/librdkafka/tests/0005-order.c +133 -0
  453. package/deps/librdkafka/tests/0006-symbols.c +163 -0
  454. package/deps/librdkafka/tests/0007-autotopic.c +136 -0
  455. package/deps/librdkafka/tests/0008-reqacks.c +179 -0
  456. package/deps/librdkafka/tests/0009-mock_cluster.c +96 -0
  457. package/deps/librdkafka/tests/0011-produce_batch.c +752 -0
  458. package/deps/librdkafka/tests/0012-produce_consume.c +537 -0
  459. package/deps/librdkafka/tests/0013-null-msgs.c +473 -0
  460. package/deps/librdkafka/tests/0014-reconsume-191.c +512 -0
  461. package/deps/librdkafka/tests/0015-offset_seeks.c +172 -0
  462. package/deps/librdkafka/tests/0016-client_swname.c +166 -0
  463. package/deps/librdkafka/tests/0017-compression.c +142 -0
  464. package/deps/librdkafka/tests/0018-cgrp_term.c +333 -0
  465. package/deps/librdkafka/tests/0019-list_groups.c +289 -0
  466. package/deps/librdkafka/tests/0020-destroy_hang.c +162 -0
  467. package/deps/librdkafka/tests/0021-rkt_destroy.c +71 -0
  468. package/deps/librdkafka/tests/0022-consume_batch.c +276 -0
  469. package/deps/librdkafka/tests/0025-timers.c +147 -0
  470. package/deps/librdkafka/tests/0026-consume_pause.c +549 -0
  471. package/deps/librdkafka/tests/0028-long_topicnames.c +79 -0
  472. package/deps/librdkafka/tests/0029-assign_offset.c +204 -0
  473. package/deps/librdkafka/tests/0030-offset_commit.c +589 -0
  474. package/deps/librdkafka/tests/0031-get_offsets.c +235 -0
  475. package/deps/librdkafka/tests/0033-regex_subscribe.c +520 -0
  476. package/deps/librdkafka/tests/0034-offset_reset.c +377 -0
  477. package/deps/librdkafka/tests/0035-api_version.c +73 -0
  478. package/deps/librdkafka/tests/0036-partial_fetch.c +86 -0
  479. package/deps/librdkafka/tests/0037-destroy_hang_local.c +85 -0
  480. package/deps/librdkafka/tests/0038-performance.c +120 -0
  481. package/deps/librdkafka/tests/0039-event.c +284 -0
  482. package/deps/librdkafka/tests/0040-io_event.c +251 -0
  483. package/deps/librdkafka/tests/0041-fetch_max_bytes.c +96 -0
  484. package/deps/librdkafka/tests/0042-many_topics.c +252 -0
  485. package/deps/librdkafka/tests/0043-no_connection.c +77 -0
  486. package/deps/librdkafka/tests/0044-partition_cnt.c +93 -0
  487. package/deps/librdkafka/tests/0045-subscribe_update.c +746 -0
  488. package/deps/librdkafka/tests/0046-rkt_cache.c +65 -0
  489. package/deps/librdkafka/tests/0047-partial_buf_tmout.c +97 -0
  490. package/deps/librdkafka/tests/0048-partitioner.c +283 -0
  491. package/deps/librdkafka/tests/0049-consume_conn_close.c +162 -0
  492. package/deps/librdkafka/tests/0050-subscribe_adds.c +144 -0
  493. package/deps/librdkafka/tests/0051-assign_adds.c +125 -0
  494. package/deps/librdkafka/tests/0052-msg_timestamps.c +220 -0
  495. package/deps/librdkafka/tests/0053-stats_cb.cpp +535 -0
  496. package/deps/librdkafka/tests/0054-offset_time.cpp +236 -0
  497. package/deps/librdkafka/tests/0055-producer_latency.c +366 -0
  498. package/deps/librdkafka/tests/0056-balanced_group_mt.c +311 -0
  499. package/deps/librdkafka/tests/0057-invalid_topic.cpp +112 -0
  500. package/deps/librdkafka/tests/0058-log.cpp +123 -0
  501. package/deps/librdkafka/tests/0059-bsearch.cpp +237 -0
  502. package/deps/librdkafka/tests/0060-op_prio.cpp +163 -0
  503. package/deps/librdkafka/tests/0061-consumer_lag.cpp +275 -0
  504. package/deps/librdkafka/tests/0062-stats_event.c +126 -0
  505. package/deps/librdkafka/tests/0063-clusterid.cpp +180 -0
  506. package/deps/librdkafka/tests/0064-interceptors.c +481 -0
  507. package/deps/librdkafka/tests/0065-yield.cpp +140 -0
  508. package/deps/librdkafka/tests/0066-plugins.cpp +129 -0
  509. package/deps/librdkafka/tests/0067-empty_topic.cpp +148 -0
  510. package/deps/librdkafka/tests/0068-produce_timeout.c +138 -0
  511. package/deps/librdkafka/tests/0069-consumer_add_parts.c +123 -0
  512. package/deps/librdkafka/tests/0070-null_empty.cpp +197 -0
  513. package/deps/librdkafka/tests/0072-headers_ut.c +448 -0
  514. package/deps/librdkafka/tests/0073-headers.c +381 -0
  515. package/deps/librdkafka/tests/0074-producev.c +87 -0
  516. package/deps/librdkafka/tests/0075-retry.c +253 -0
  517. package/deps/librdkafka/tests/0076-produce_retry.c +450 -0
  518. package/deps/librdkafka/tests/0077-compaction.c +357 -0
  519. package/deps/librdkafka/tests/0078-c_from_cpp.cpp +96 -0
  520. package/deps/librdkafka/tests/0079-fork.c +93 -0
  521. package/deps/librdkafka/tests/0080-admin_ut.c +3065 -0
  522. package/deps/librdkafka/tests/0081-admin.c +5333 -0
  523. package/deps/librdkafka/tests/0082-fetch_max_bytes.cpp +133 -0
  524. package/deps/librdkafka/tests/0083-cb_event.c +228 -0
  525. package/deps/librdkafka/tests/0084-destroy_flags.c +212 -0
  526. package/deps/librdkafka/tests/0085-headers.cpp +388 -0
  527. package/deps/librdkafka/tests/0086-purge.c +335 -0
  528. package/deps/librdkafka/tests/0088-produce_metadata_timeout.c +162 -0
  529. package/deps/librdkafka/tests/0089-max_poll_interval.c +506 -0
  530. package/deps/librdkafka/tests/0090-idempotence.c +172 -0
  531. package/deps/librdkafka/tests/0091-max_poll_interval_timeout.c +297 -0
  532. package/deps/librdkafka/tests/0092-mixed_msgver.c +97 -0
  533. package/deps/librdkafka/tests/0093-holb.c +197 -0
  534. package/deps/librdkafka/tests/0094-idempotence_msg_timeout.c +230 -0
  535. package/deps/librdkafka/tests/0095-all_brokers_down.cpp +122 -0
  536. package/deps/librdkafka/tests/0097-ssl_verify.cpp +466 -0
  537. package/deps/librdkafka/tests/0098-consumer-txn.cpp +1218 -0
  538. package/deps/librdkafka/tests/0099-commit_metadata.c +194 -0
  539. package/deps/librdkafka/tests/0100-thread_interceptors.cpp +195 -0
  540. package/deps/librdkafka/tests/0101-fetch-from-follower.cpp +446 -0
  541. package/deps/librdkafka/tests/0102-static_group_rebalance.c +535 -0
  542. package/deps/librdkafka/tests/0103-transactions.c +1383 -0
  543. package/deps/librdkafka/tests/0104-fetch_from_follower_mock.c +624 -0
  544. package/deps/librdkafka/tests/0105-transactions_mock.c +3923 -0
  545. package/deps/librdkafka/tests/0106-cgrp_sess_timeout.c +297 -0
  546. package/deps/librdkafka/tests/0107-topic_recreate.c +259 -0
  547. package/deps/librdkafka/tests/0109-auto_create_topics.cpp +218 -0
  548. package/deps/librdkafka/tests/0110-batch_size.cpp +183 -0
  549. package/deps/librdkafka/tests/0111-delay_create_topics.cpp +127 -0
  550. package/deps/librdkafka/tests/0112-assign_unknown_part.c +98 -0
  551. package/deps/librdkafka/tests/0113-cooperative_rebalance.cpp +3329 -0
  552. package/deps/librdkafka/tests/0114-sticky_partitioning.cpp +176 -0
  553. package/deps/librdkafka/tests/0115-producer_auth.cpp +179 -0
  554. package/deps/librdkafka/tests/0116-kafkaconsumer_close.cpp +214 -0
  555. package/deps/librdkafka/tests/0117-mock_errors.c +321 -0
  556. package/deps/librdkafka/tests/0118-commit_rebalance.c +121 -0
  557. package/deps/librdkafka/tests/0119-consumer_auth.cpp +148 -0
  558. package/deps/librdkafka/tests/0120-asymmetric_subscription.c +180 -0
  559. package/deps/librdkafka/tests/0121-clusterid.c +115 -0
  560. package/deps/librdkafka/tests/0122-buffer_cleaning_after_rebalance.c +227 -0
  561. package/deps/librdkafka/tests/0123-connections_max_idle.c +98 -0
  562. package/deps/librdkafka/tests/0124-openssl_invalid_engine.c +69 -0
  563. package/deps/librdkafka/tests/0125-immediate_flush.c +144 -0
  564. package/deps/librdkafka/tests/0126-oauthbearer_oidc.c +213 -0
  565. package/deps/librdkafka/tests/0127-fetch_queue_backoff.cpp +165 -0
  566. package/deps/librdkafka/tests/0128-sasl_callback_queue.cpp +125 -0
  567. package/deps/librdkafka/tests/0129-fetch_aborted_msgs.c +78 -0
  568. package/deps/librdkafka/tests/0130-store_offsets.c +178 -0
  569. package/deps/librdkafka/tests/0131-connect_timeout.c +81 -0
  570. package/deps/librdkafka/tests/0132-strategy_ordering.c +171 -0
  571. package/deps/librdkafka/tests/0133-ssl_keys.c +128 -0
  572. package/deps/librdkafka/tests/0134-ssl_provider.c +92 -0
  573. package/deps/librdkafka/tests/0135-sasl_credentials.cpp +143 -0
  574. package/deps/librdkafka/tests/0136-resolve_cb.c +181 -0
  575. package/deps/librdkafka/tests/0137-barrier_batch_consume.c +609 -0
  576. package/deps/librdkafka/tests/0138-admin_mock.c +281 -0
  577. package/deps/librdkafka/tests/0139-offset_validation_mock.c +442 -0
  578. package/deps/librdkafka/tests/0140-commit_metadata.cpp +108 -0
  579. package/deps/librdkafka/tests/0142-reauthentication.c +495 -0
  580. package/deps/librdkafka/tests/0143-exponential_backoff_mock.c +553 -0
  581. package/deps/librdkafka/tests/0144-idempotence_mock.c +373 -0
  582. package/deps/librdkafka/tests/0145-pause_resume_mock.c +119 -0
  583. package/deps/librdkafka/tests/0146-metadata_mock.c +444 -0
  584. package/deps/librdkafka/tests/0150-telemetry_mock.c +648 -0
  585. package/deps/librdkafka/tests/1000-unktopic.c +164 -0
  586. package/deps/librdkafka/tests/8000-idle.cpp +60 -0
  587. package/deps/librdkafka/tests/8001-fetch_from_follower_mock_manual.c +113 -0
  588. package/deps/librdkafka/tests/CMakeLists.txt +164 -0
  589. package/deps/librdkafka/tests/LibrdkafkaTestApp.py +266 -0
  590. package/deps/librdkafka/tests/Makefile +182 -0
  591. package/deps/librdkafka/tests/README.md +509 -0
  592. package/deps/librdkafka/tests/autotest.sh +33 -0
  593. package/deps/librdkafka/tests/backtrace.gdb +30 -0
  594. package/deps/librdkafka/tests/broker_version_tests.py +315 -0
  595. package/deps/librdkafka/tests/buildbox.sh +17 -0
  596. package/deps/librdkafka/tests/cleanup-checker-tests.sh +20 -0
  597. package/deps/librdkafka/tests/cluster_testing.py +191 -0
  598. package/deps/librdkafka/tests/delete-test-topics.sh +56 -0
  599. package/deps/librdkafka/tests/fixtures/ssl/Makefile +8 -0
  600. package/deps/librdkafka/tests/fixtures/ssl/README.md +13 -0
  601. package/deps/librdkafka/tests/fixtures/ssl/client.keystore.p12 +0 -0
  602. package/deps/librdkafka/tests/fixtures/ssl/client2.certificate.pem +109 -0
  603. package/deps/librdkafka/tests/fixtures/ssl/client2.key +34 -0
  604. package/deps/librdkafka/tests/fixtures/ssl/create_keys.sh +93 -0
  605. package/deps/librdkafka/tests/fuzzers/Makefile +12 -0
  606. package/deps/librdkafka/tests/fuzzers/README.md +31 -0
  607. package/deps/librdkafka/tests/fuzzers/fuzz_regex.c +74 -0
  608. package/deps/librdkafka/tests/fuzzers/helpers.h +90 -0
  609. package/deps/librdkafka/tests/gen-ssl-certs.sh +165 -0
  610. package/deps/librdkafka/tests/interactive_broker_version.py +170 -0
  611. package/deps/librdkafka/tests/interceptor_test/CMakeLists.txt +16 -0
  612. package/deps/librdkafka/tests/interceptor_test/Makefile +22 -0
  613. package/deps/librdkafka/tests/interceptor_test/interceptor_test.c +314 -0
  614. package/deps/librdkafka/tests/interceptor_test/interceptor_test.h +54 -0
  615. package/deps/librdkafka/tests/java/IncrementalRebalanceCli.java +97 -0
  616. package/deps/librdkafka/tests/java/Makefile +12 -0
  617. package/deps/librdkafka/tests/java/Murmur2Cli.java +46 -0
  618. package/deps/librdkafka/tests/java/README.md +14 -0
  619. package/deps/librdkafka/tests/java/TransactionProducerCli.java +162 -0
  620. package/deps/librdkafka/tests/java/run-class.sh +11 -0
  621. package/deps/librdkafka/tests/librdkafka.suppressions +483 -0
  622. package/deps/librdkafka/tests/lz4_manual_test.sh +59 -0
  623. package/deps/librdkafka/tests/multi-broker-version-test.sh +50 -0
  624. package/deps/librdkafka/tests/parse-refcnt.sh +43 -0
  625. package/deps/librdkafka/tests/performance_plot.py +115 -0
  626. package/deps/librdkafka/tests/plugin_test/Makefile +19 -0
  627. package/deps/librdkafka/tests/plugin_test/plugin_test.c +58 -0
  628. package/deps/librdkafka/tests/requirements.txt +2 -0
  629. package/deps/librdkafka/tests/run-consumer-tests.sh +16 -0
  630. package/deps/librdkafka/tests/run-producer-tests.sh +16 -0
  631. package/deps/librdkafka/tests/run-test.sh +140 -0
  632. package/deps/librdkafka/tests/rusage.c +249 -0
  633. package/deps/librdkafka/tests/sasl_test.py +289 -0
  634. package/deps/librdkafka/tests/scenarios/README.md +6 -0
  635. package/deps/librdkafka/tests/scenarios/ak23.json +6 -0
  636. package/deps/librdkafka/tests/scenarios/default.json +5 -0
  637. package/deps/librdkafka/tests/scenarios/noautocreate.json +5 -0
  638. package/deps/librdkafka/tests/sockem.c +801 -0
  639. package/deps/librdkafka/tests/sockem.h +85 -0
  640. package/deps/librdkafka/tests/sockem_ctrl.c +145 -0
  641. package/deps/librdkafka/tests/sockem_ctrl.h +61 -0
  642. package/deps/librdkafka/tests/test.c +7318 -0
  643. package/deps/librdkafka/tests/test.conf.example +27 -0
  644. package/deps/librdkafka/tests/test.h +979 -0
  645. package/deps/librdkafka/tests/testcpp.cpp +126 -0
  646. package/deps/librdkafka/tests/testcpp.h +360 -0
  647. package/deps/librdkafka/tests/testshared.h +402 -0
  648. package/deps/librdkafka/tests/tools/README.md +4 -0
  649. package/deps/librdkafka/tests/tools/stats/README.md +21 -0
  650. package/deps/librdkafka/tests/tools/stats/filter.jq +42 -0
  651. package/deps/librdkafka/tests/tools/stats/graph.py +150 -0
  652. package/deps/librdkafka/tests/tools/stats/requirements.txt +3 -0
  653. package/deps/librdkafka/tests/tools/stats/to_csv.py +124 -0
  654. package/deps/librdkafka/tests/until-fail.sh +87 -0
  655. package/deps/librdkafka/tests/xxxx-assign_partition.c +122 -0
  656. package/deps/librdkafka/tests/xxxx-metadata.cpp +159 -0
  657. package/deps/librdkafka/vcpkg.json +23 -0
  658. package/deps/librdkafka/win32/README.md +5 -0
  659. package/deps/librdkafka/win32/build-package.bat +3 -0
  660. package/deps/librdkafka/win32/build.bat +19 -0
  661. package/deps/librdkafka/win32/common.vcxproj +84 -0
  662. package/deps/librdkafka/win32/install-openssl.ps1 +33 -0
  663. package/deps/librdkafka/win32/interceptor_test/interceptor_test.vcxproj +87 -0
  664. package/deps/librdkafka/win32/librdkafka.autopkg.template +54 -0
  665. package/deps/librdkafka/win32/librdkafka.master.testing.targets +13 -0
  666. package/deps/librdkafka/win32/librdkafka.sln +226 -0
  667. package/deps/librdkafka/win32/librdkafka.vcxproj +276 -0
  668. package/deps/librdkafka/win32/librdkafkacpp/librdkafkacpp.vcxproj +104 -0
  669. package/deps/librdkafka/win32/msbuild.ps1 +15 -0
  670. package/deps/librdkafka/win32/openssl_engine_example/openssl_engine_example.vcxproj +132 -0
  671. package/deps/librdkafka/win32/package-zip.ps1 +46 -0
  672. package/deps/librdkafka/win32/packages/repositories.config +4 -0
  673. package/deps/librdkafka/win32/push-package.bat +4 -0
  674. package/deps/librdkafka/win32/rdkafka_complex_consumer_example_cpp/rdkafka_complex_consumer_example_cpp.vcxproj +67 -0
  675. package/deps/librdkafka/win32/rdkafka_example/rdkafka_example.vcxproj +97 -0
  676. package/deps/librdkafka/win32/rdkafka_performance/rdkafka_performance.vcxproj +97 -0
  677. package/deps/librdkafka/win32/setup-msys2.ps1 +31 -0
  678. package/deps/librdkafka/win32/setup-vcpkg.ps1 +12 -0
  679. package/deps/librdkafka/win32/tests/test.conf.example +25 -0
  680. package/deps/librdkafka/win32/tests/tests.vcxproj +247 -0
  681. package/deps/librdkafka/win32/win_ssl_cert_store/win_ssl_cert_store.vcxproj +132 -0
  682. package/deps/librdkafka/win32/wingetopt.c +564 -0
  683. package/deps/librdkafka/win32/wingetopt.h +100 -0
  684. package/deps/librdkafka/win32/wintime.h +33 -0
  685. package/deps/librdkafka.gyp +62 -0
  686. package/deps/windows-install.py +73 -0
  687. package/docker-compose.yml +23 -0
  688. package/e2e/admin.spec.js +187 -0
  689. package/e2e/both.spec.js +726 -0
  690. package/e2e/consumer.spec.js +386 -0
  691. package/e2e/groups.spec.js +132 -0
  692. package/e2e/listener.js +51 -0
  693. package/e2e/producer-transaction.spec.js +333 -0
  694. package/e2e/producer.spec.js +283 -0
  695. package/errors.d.ts +347 -0
  696. package/examples/consumer-flow.md +76 -0
  697. package/examples/consumer.md +45 -0
  698. package/examples/docker-alpine.md +30 -0
  699. package/examples/high-level-producer.md +32 -0
  700. package/examples/metadata.md +27 -0
  701. package/examples/oauthbearer-default-flow.md +80 -0
  702. package/examples/producer-cluster.md +103 -0
  703. package/examples/producer.md +73 -0
  704. package/index.d.ts +357 -0
  705. package/lib/admin.js +233 -0
  706. package/lib/client.js +578 -0
  707. package/lib/error.js +472 -0
  708. package/lib/index.js +34 -0
  709. package/lib/kafka-consumer-stream.js +397 -0
  710. package/lib/kafka-consumer.js +698 -0
  711. package/lib/producer/high-level-producer.js +323 -0
  712. package/lib/producer-stream.js +307 -0
  713. package/lib/producer.js +375 -0
  714. package/lib/tools/ref-counter.js +52 -0
  715. package/lib/topic-partition.js +88 -0
  716. package/lib/topic.js +42 -0
  717. package/lib/util.js +29 -0
  718. package/librdkafka.js +12 -0
  719. package/make_docs.sh +59 -0
  720. package/package.json +53 -0
  721. package/renovate.json +30 -0
  722. package/run_docker.sh +42 -0
  723. package/src/admin.cc +624 -0
  724. package/src/admin.h +78 -0
  725. package/src/binding.cc +73 -0
  726. package/src/binding.h +25 -0
  727. package/src/callbacks.cc +614 -0
  728. package/src/callbacks.h +265 -0
  729. package/src/common.cc +582 -0
  730. package/src/common.h +134 -0
  731. package/src/config.cc +167 -0
  732. package/src/config.h +45 -0
  733. package/src/connection.cc +482 -0
  734. package/src/connection.h +108 -0
  735. package/src/errors.cc +96 -0
  736. package/src/errors.h +53 -0
  737. package/src/kafka-consumer.cc +1457 -0
  738. package/src/kafka-consumer.h +136 -0
  739. package/src/per-isolate-data.cc +57 -0
  740. package/src/per-isolate-data.h +39 -0
  741. package/src/producer.cc +873 -0
  742. package/src/producer.h +125 -0
  743. package/src/topic.cc +180 -0
  744. package/src/topic.h +56 -0
  745. package/src/workers.cc +1245 -0
  746. package/src/workers.h +511 -0
  747. package/test/binding.spec.js +66 -0
  748. package/test/consumer.spec.js +91 -0
  749. package/test/error.spec.js +8 -0
  750. package/test/index.spec.js +8 -0
  751. package/test/kafka-consumer-stream.spec.js +298 -0
  752. package/test/kafka-consumer-worker.js +51 -0
  753. package/test/kafka-consumer.spec.js +86 -0
  754. package/test/mocha.opts +1 -0
  755. package/test/mock.js +55 -0
  756. package/test/producer/high-level-producer.spec.js +496 -0
  757. package/test/producer-stream.spec.js +723 -0
  758. package/test/producer-worker.js +53 -0
  759. package/test/producer.spec.js +120 -0
  760. package/test/tools/ref-counter.spec.js +53 -0
  761. package/test/topic-partition.spec.js +104 -0
  762. package/test/util.spec.js +46 -0
  763. package/util/configure.js +30 -0
  764. package/util/get-env.js +6 -0
  765. package/util/test-compile.js +11 -0
  766. package/util/test-producer-delivery.js +100 -0
  767. package/win_install.ps1 +2 -0
@@ -0,0 +1,1904 @@
1
+ /*
2
+ * librdkafka - The Apache Kafka C/C++ library
3
+ *
4
+ * Copyright (c) 2019-2022, Magnus Edenhill
5
+ * 2023, Confluent Inc.
6
+ * All rights reserved.
7
+ *
8
+ * Redistribution and use in source and binary forms, with or without
9
+ * modification, are permitted provided that the following conditions are met:
10
+ *
11
+ * 1. Redistributions of source code must retain the above copyright notice,
12
+ * this list of conditions and the following disclaimer.
13
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
14
+ * this list of conditions and the following disclaimer in the documentation
15
+ * and/or other materials provided with the distribution.
16
+ *
17
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
21
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27
+ * POSSIBILITY OF SUCH DAMAGE.
28
+ */
29
+
30
+
31
+ /**
32
+ * @name OpenSSL integration
33
+ *
34
+ */
35
+
36
+ #include "rdkafka_int.h"
37
+ #include "rdkafka_transport_int.h"
38
+ #include "rdkafka_cert.h"
39
+
40
+ #ifdef _WIN32
41
+ #include <wincrypt.h>
42
+ #pragma comment(lib, "crypt32.lib")
43
+ #pragma comment(lib, "libcrypto.lib")
44
+ #pragma comment(lib, "libssl.lib")
45
+ #endif
46
+
47
+ #include <openssl/x509.h>
48
+ #include <openssl/x509_vfy.h>
49
+
50
+ #if OPENSSL_VERSION_NUMBER >= 0x30000000
51
+ #include <openssl/provider.h>
52
+ #endif
53
+
54
+ #include <ctype.h>
55
+
56
+ #if !_WIN32
57
+ #include <sys/types.h>
58
+ #include <sys/stat.h>
59
+ #include <unistd.h>
60
+ #endif
61
+
62
+
63
+ #if WITH_VALGRIND
64
+ /* OpenSSL relies on uninitialized memory, which Valgrind will whine about.
65
+ * We use in-code Valgrind macros to suppress those warnings. */
66
+ #include <valgrind/memcheck.h>
67
+ #else
68
+ #define VALGRIND_MAKE_MEM_DEFINED(A, B)
69
+ #endif
70
+
71
+
72
+ #if OPENSSL_VERSION_NUMBER < 0x10100000L
73
+ static mtx_t *rd_kafka_ssl_locks;
74
+ static int rd_kafka_ssl_locks_cnt;
75
+ #endif
76
+
77
+
78
+ /**
79
+ * @brief Close and destroy SSL session
80
+ */
81
+ void rd_kafka_transport_ssl_close(rd_kafka_transport_t *rktrans) {
82
+ SSL_shutdown(rktrans->rktrans_ssl);
83
+ SSL_free(rktrans->rktrans_ssl);
84
+ rktrans->rktrans_ssl = NULL;
85
+ }
86
+
87
+
88
+ /**
89
+ * @brief Clear OpenSSL error queue to get a proper error reporting in case
90
+ * the next SSL_*() operation fails.
91
+ */
92
+ static RD_INLINE void
93
+ rd_kafka_transport_ssl_clear_error(rd_kafka_transport_t *rktrans) {
94
+ ERR_clear_error();
95
+ #ifdef _WIN32
96
+ WSASetLastError(0);
97
+ #else
98
+ rd_set_errno(0);
99
+ #endif
100
+ }
101
+
102
+ /**
103
+ * @returns a thread-local single-invocation-use error string for
104
+ * the last thread-local error in OpenSSL, or an empty string
105
+ * if no error.
106
+ */
107
+ const char *rd_kafka_ssl_last_error_str(void) {
108
+ static RD_TLS char errstr[256];
109
+ unsigned long l;
110
+ const char *file, *data, *func;
111
+ int line, flags;
112
+
113
+ #if OPENSSL_VERSION_NUMBER >= 0x30000000
114
+ l = ERR_peek_last_error_all(&file, &line, &func, &data, &flags);
115
+ #else
116
+ l = ERR_peek_last_error_line_data(&file, &line, &data, &flags);
117
+ func = ERR_func_error_string(l);
118
+ #endif
119
+
120
+ if (!l)
121
+ return "";
122
+
123
+ rd_snprintf(errstr, sizeof(errstr), "%lu:%s:%s:%s:%d: %s", l,
124
+ ERR_lib_error_string(l), func, file, line,
125
+ ((flags & ERR_TXT_STRING) && data && *data)
126
+ ? data
127
+ : ERR_reason_error_string(l));
128
+
129
+ return errstr;
130
+ }
131
+
132
+ /**
133
+ * Serves the entire OpenSSL error queue and logs each error.
134
+ * The last error is not logged but returned in 'errstr'.
135
+ *
136
+ * If 'rkb' is non-NULL broker-specific logging will be used,
137
+ * else it will fall back on global 'rk' debugging.
138
+ */
139
+ static char *rd_kafka_ssl_error(rd_kafka_t *rk,
140
+ rd_kafka_broker_t *rkb,
141
+ char *errstr,
142
+ size_t errstr_size) {
143
+ unsigned long l;
144
+ const char *file, *data, *func;
145
+ int line, flags;
146
+ int cnt = 0;
147
+
148
+ if (!rk) {
149
+ rd_assert(rkb);
150
+ rk = rkb->rkb_rk;
151
+ }
152
+
153
+ while (
154
+ #if OPENSSL_VERSION_NUMBER >= 0x30000000
155
+ (l = ERR_get_error_all(&file, &line, &func, &data, &flags))
156
+ #else
157
+ (l = ERR_get_error_line_data(&file, &line, &data, &flags))
158
+ #endif
159
+ ) {
160
+ char buf[256];
161
+
162
+ #if OPENSSL_VERSION_NUMBER < 0x30000000
163
+ func = ERR_func_error_string(l);
164
+ #endif
165
+
166
+ if (cnt++ > 0) {
167
+ /* Log last message */
168
+ if (rkb)
169
+ rd_rkb_log(rkb, LOG_ERR, "SSL", "%s", errstr);
170
+ else
171
+ rd_kafka_log(rk, LOG_ERR, "SSL", "%s", errstr);
172
+ }
173
+
174
+ ERR_error_string_n(l, buf, sizeof(buf));
175
+
176
+ if (!(flags & ERR_TXT_STRING) || !data || !*data)
177
+ data = NULL;
178
+
179
+ /* Include openssl file:line:func if debugging is enabled */
180
+ if (rk->rk_conf.log_level >= LOG_DEBUG)
181
+ rd_snprintf(errstr, errstr_size, "%s:%d:%s %s%s%s",
182
+ file, line, func, buf, data ? ": " : "",
183
+ data ? data : "");
184
+ else
185
+ rd_snprintf(errstr, errstr_size, "%s%s%s", buf,
186
+ data ? ": " : "", data ? data : "");
187
+ }
188
+
189
+ if (cnt == 0)
190
+ rd_snprintf(errstr, errstr_size,
191
+ "No further error information available");
192
+
193
+ return errstr;
194
+ }
195
+
196
+
197
+
198
+ /**
199
+ * Set transport IO event polling based on SSL error.
200
+ *
201
+ * Returns -1 on permanent errors.
202
+ *
203
+ * Locality: broker thread
204
+ */
205
+ static RD_INLINE int
206
+ rd_kafka_transport_ssl_io_update(rd_kafka_transport_t *rktrans,
207
+ int ret,
208
+ char *errstr,
209
+ size_t errstr_size) {
210
+ int serr = SSL_get_error(rktrans->rktrans_ssl, ret);
211
+ int serr2;
212
+
213
+ switch (serr) {
214
+ case SSL_ERROR_WANT_READ:
215
+ rd_kafka_transport_poll_set(rktrans, POLLIN);
216
+ break;
217
+
218
+ case SSL_ERROR_WANT_WRITE:
219
+ rd_kafka_transport_set_blocked(rktrans, rd_true);
220
+ rd_kafka_transport_poll_set(rktrans, POLLOUT);
221
+ break;
222
+
223
+ case SSL_ERROR_SYSCALL:
224
+ serr2 = ERR_peek_error();
225
+ if (serr2)
226
+ rd_kafka_ssl_error(NULL, rktrans->rktrans_rkb, errstr,
227
+ errstr_size);
228
+ else if (!rd_socket_errno || rd_socket_errno == ECONNRESET)
229
+ rd_snprintf(errstr, errstr_size, "Disconnected");
230
+ else
231
+ rd_snprintf(errstr, errstr_size,
232
+ "SSL transport error: %s",
233
+ rd_strerror(rd_socket_errno));
234
+ return -1;
235
+
236
+ case SSL_ERROR_ZERO_RETURN:
237
+ rd_snprintf(errstr, errstr_size, "Disconnected");
238
+ return -1;
239
+
240
+ default:
241
+ rd_kafka_ssl_error(NULL, rktrans->rktrans_rkb, errstr,
242
+ errstr_size);
243
+ return -1;
244
+ }
245
+
246
+ return 0;
247
+ }
248
+
249
+ ssize_t rd_kafka_transport_ssl_send(rd_kafka_transport_t *rktrans,
250
+ rd_slice_t *slice,
251
+ char *errstr,
252
+ size_t errstr_size) {
253
+ ssize_t sum = 0;
254
+ const void *p;
255
+ size_t rlen;
256
+
257
+ rd_kafka_transport_ssl_clear_error(rktrans);
258
+
259
+ while ((rlen = rd_slice_peeker(slice, &p))) {
260
+ int r;
261
+ size_t r2;
262
+
263
+ r = SSL_write(rktrans->rktrans_ssl, p, (int)rlen);
264
+
265
+ if (unlikely(r <= 0)) {
266
+ if (rd_kafka_transport_ssl_io_update(rktrans, r, errstr,
267
+ errstr_size) == -1)
268
+ return -1;
269
+ else
270
+ return sum;
271
+ }
272
+
273
+ /* Update buffer read position */
274
+ r2 = rd_slice_read(slice, NULL, (size_t)r);
275
+ rd_assert((size_t)r == r2 &&
276
+ *"BUG: wrote more bytes than available in slice");
277
+
278
+
279
+ sum += r;
280
+ /* FIXME: remove this and try again immediately and let
281
+ * the next SSL_write() call fail instead? */
282
+ if ((size_t)r < rlen)
283
+ break;
284
+ }
285
+ return sum;
286
+ }
287
+
288
+ ssize_t rd_kafka_transport_ssl_recv(rd_kafka_transport_t *rktrans,
289
+ rd_buf_t *rbuf,
290
+ char *errstr,
291
+ size_t errstr_size) {
292
+ ssize_t sum = 0;
293
+ void *p;
294
+ size_t len;
295
+
296
+ while ((len = rd_buf_get_writable(rbuf, &p))) {
297
+ int r;
298
+
299
+ rd_kafka_transport_ssl_clear_error(rktrans);
300
+
301
+ r = SSL_read(rktrans->rktrans_ssl, p, (int)len);
302
+
303
+ if (unlikely(r <= 0)) {
304
+ if (rd_kafka_transport_ssl_io_update(rktrans, r, errstr,
305
+ errstr_size) == -1)
306
+ return -1;
307
+ else
308
+ return sum;
309
+ }
310
+
311
+ VALGRIND_MAKE_MEM_DEFINED(p, r);
312
+
313
+ /* Update buffer write position */
314
+ rd_buf_write(rbuf, NULL, (size_t)r);
315
+
316
+ sum += r;
317
+
318
+ /* FIXME: remove this and try again immediately and let
319
+ * the next SSL_read() call fail instead? */
320
+ if ((size_t)r < len)
321
+ break;
322
+ }
323
+ return sum;
324
+ }
325
+
326
+
327
+ /**
328
+ * OpenSSL password query callback
329
+ *
330
+ * Locality: application thread
331
+ */
332
+ static int rd_kafka_transport_ssl_passwd_cb(char *buf,
333
+ int size,
334
+ int rwflag,
335
+ void *userdata) {
336
+ rd_kafka_t *rk = userdata;
337
+ int pwlen;
338
+
339
+ rd_kafka_dbg(rk, SECURITY, "SSLPASSWD",
340
+ "Private key requires password");
341
+
342
+ if (!rk->rk_conf.ssl.key_password) {
343
+ rd_kafka_log(rk, LOG_WARNING, "SSLPASSWD",
344
+ "Private key requires password but "
345
+ "no password configured (ssl.key.password)");
346
+ return -1;
347
+ }
348
+
349
+
350
+ pwlen = (int)strlen(rk->rk_conf.ssl.key_password);
351
+ memcpy(buf, rk->rk_conf.ssl.key_password, RD_MIN(pwlen, size));
352
+
353
+ return pwlen;
354
+ }
355
+
356
+
357
+ /**
358
+ * @brief OpenSSL callback to perform additional broker certificate
359
+ * verification and validation.
360
+ *
361
+ * @return 1 on success when the broker certificate
362
+ * is valid and 0 when the certificate is not valid.
363
+ *
364
+ * @sa SSL_CTX_set_verify()
365
+ */
366
+ static int rd_kafka_transport_ssl_cert_verify_cb(int preverify_ok,
367
+ X509_STORE_CTX *x509_ctx) {
368
+ rd_kafka_transport_t *rktrans = rd_kafka_curr_transport;
369
+ rd_kafka_broker_t *rkb;
370
+ rd_kafka_t *rk;
371
+ X509 *cert;
372
+ char *buf = NULL;
373
+ int buf_size;
374
+ int depth;
375
+ int x509_orig_error, x509_error;
376
+ char errstr[512];
377
+ int ok;
378
+
379
+ rd_assert(rktrans != NULL);
380
+ rkb = rktrans->rktrans_rkb;
381
+ rk = rkb->rkb_rk;
382
+
383
+ cert = X509_STORE_CTX_get_current_cert(x509_ctx);
384
+ if (!cert) {
385
+ rd_rkb_log(rkb, LOG_ERR, "SSLCERTVRFY",
386
+ "Failed to get current certificate to verify");
387
+ return 0;
388
+ }
389
+
390
+ depth = X509_STORE_CTX_get_error_depth(x509_ctx);
391
+
392
+ x509_orig_error = x509_error = X509_STORE_CTX_get_error(x509_ctx);
393
+
394
+ buf_size = i2d_X509(cert, (unsigned char **)&buf);
395
+ if (buf_size < 0 || !buf) {
396
+ rd_rkb_log(rkb, LOG_ERR, "SSLCERTVRFY",
397
+ "Unable to convert certificate to X509 format");
398
+ return 0;
399
+ }
400
+
401
+ *errstr = '\0';
402
+
403
+ /* Call application's verification callback. */
404
+ ok = rk->rk_conf.ssl.cert_verify_cb(
405
+ rk, rkb->rkb_nodename, rkb->rkb_nodeid, &x509_error, depth, buf,
406
+ (size_t)buf_size, errstr, sizeof(errstr), rk->rk_conf.opaque);
407
+
408
+ OPENSSL_free(buf);
409
+
410
+ if (!ok) {
411
+ char subject[128];
412
+ char issuer[128];
413
+
414
+ X509_NAME_oneline(X509_get_subject_name(cert), subject,
415
+ sizeof(subject));
416
+ X509_NAME_oneline(X509_get_issuer_name(cert), issuer,
417
+ sizeof(issuer));
418
+ rd_rkb_log(rkb, LOG_ERR, "SSLCERTVRFY",
419
+ "Certificate (subject=%s, issuer=%s) verification "
420
+ "callback failed: %s",
421
+ subject, issuer, errstr);
422
+
423
+ X509_STORE_CTX_set_error(x509_ctx, x509_error);
424
+
425
+ return 0; /* verification failed */
426
+ }
427
+
428
+ /* Clear error */
429
+ if (x509_orig_error != 0 && x509_error == 0)
430
+ X509_STORE_CTX_set_error(x509_ctx, 0);
431
+
432
+ return 1; /* verification successful */
433
+ }
434
+
435
+ /**
436
+ * @brief Set TLSEXT hostname for SNI and optionally enable
437
+ * SSL endpoint identification verification.
438
+ *
439
+ * @returns 0 on success or -1 on error.
440
+ */
441
+ static int rd_kafka_transport_ssl_set_endpoint_id(rd_kafka_transport_t *rktrans,
442
+ char *errstr,
443
+ size_t errstr_size) {
444
+ char name[RD_KAFKA_NODENAME_SIZE];
445
+ char *t;
446
+
447
+ rd_kafka_broker_lock(rktrans->rktrans_rkb);
448
+ rd_snprintf(name, sizeof(name), "%s",
449
+ rktrans->rktrans_rkb->rkb_nodename);
450
+ rd_kafka_broker_unlock(rktrans->rktrans_rkb);
451
+
452
+ /* Remove ":9092" port suffix from nodename */
453
+ if ((t = strrchr(name, ':')))
454
+ *t = '\0';
455
+
456
+ #if (OPENSSL_VERSION_NUMBER >= 0x0090806fL) && !defined(OPENSSL_NO_TLSEXT)
457
+ /* If non-numerical hostname, send it for SNI */
458
+ if (!(/*ipv6*/ (strchr(name, ':') &&
459
+ strspn(name, "0123456789abcdefABCDEF:.[]%") ==
460
+ strlen(name)) ||
461
+ /*ipv4*/ strspn(name, "0123456789.") == strlen(name)) &&
462
+ !SSL_set_tlsext_host_name(rktrans->rktrans_ssl, name))
463
+ goto fail;
464
+ #endif
465
+
466
+ if (rktrans->rktrans_rkb->rkb_rk->rk_conf.ssl.endpoint_identification ==
467
+ RD_KAFKA_SSL_ENDPOINT_ID_NONE)
468
+ return 0;
469
+
470
+ #if OPENSSL_VERSION_NUMBER >= 0x10100000 && !defined(OPENSSL_IS_BORINGSSL)
471
+ if (!SSL_set1_host(rktrans->rktrans_ssl, name))
472
+ goto fail;
473
+ #elif OPENSSL_VERSION_NUMBER >= 0x1000200fL /* 1.0.2 */
474
+ {
475
+ X509_VERIFY_PARAM *param;
476
+
477
+ param = SSL_get0_param(rktrans->rktrans_ssl);
478
+
479
+ if (!X509_VERIFY_PARAM_set1_host(param, name,
480
+ strnlen(name, sizeof(name))))
481
+ goto fail;
482
+ }
483
+ #else
484
+ rd_snprintf(errstr, errstr_size,
485
+ "Endpoint identification not supported on this "
486
+ "OpenSSL version (0x%lx)",
487
+ OPENSSL_VERSION_NUMBER);
488
+ return -1;
489
+ #endif
490
+
491
+ rd_rkb_dbg(rktrans->rktrans_rkb, SECURITY, "ENDPOINT",
492
+ "Enabled endpoint identification using hostname %s", name);
493
+
494
+ return 0;
495
+
496
+ fail:
497
+ rd_kafka_ssl_error(NULL, rktrans->rktrans_rkb, errstr, errstr_size);
498
+ return -1;
499
+ }
500
+
501
+
502
+ /**
503
+ * @brief Set up SSL for a newly connected connection
504
+ *
505
+ * @returns -1 on failure, else 0.
506
+ */
507
+ int rd_kafka_transport_ssl_connect(rd_kafka_broker_t *rkb,
508
+ rd_kafka_transport_t *rktrans,
509
+ char *errstr,
510
+ size_t errstr_size) {
511
+ int r;
512
+
513
+ rktrans->rktrans_ssl = SSL_new(rkb->rkb_rk->rk_conf.ssl.ctx);
514
+ if (!rktrans->rktrans_ssl)
515
+ goto fail;
516
+
517
+ if (!SSL_set_fd(rktrans->rktrans_ssl, (int)rktrans->rktrans_s))
518
+ goto fail;
519
+
520
+ if (rd_kafka_transport_ssl_set_endpoint_id(rktrans, errstr,
521
+ errstr_size) == -1)
522
+ return -1;
523
+
524
+ rd_kafka_transport_ssl_clear_error(rktrans);
525
+
526
+ r = SSL_connect(rktrans->rktrans_ssl);
527
+ if (r == 1) {
528
+ /* Connected, highly unlikely since this is a
529
+ * non-blocking operation. */
530
+ rd_kafka_transport_connect_done(rktrans, NULL);
531
+ return 0;
532
+ }
533
+
534
+ if (rd_kafka_transport_ssl_io_update(rktrans, r, errstr, errstr_size) ==
535
+ -1)
536
+ return -1;
537
+
538
+ return 0;
539
+
540
+ fail:
541
+ rd_kafka_ssl_error(NULL, rkb, errstr, errstr_size);
542
+ return -1;
543
+ }
544
+
545
+
546
+ static RD_UNUSED int
547
+ rd_kafka_transport_ssl_io_event(rd_kafka_transport_t *rktrans, int events) {
548
+ int r;
549
+ char errstr[512];
550
+
551
+ if (events & POLLOUT) {
552
+ rd_kafka_transport_ssl_clear_error(rktrans);
553
+
554
+ r = SSL_write(rktrans->rktrans_ssl, NULL, 0);
555
+ if (rd_kafka_transport_ssl_io_update(rktrans, r, errstr,
556
+ sizeof(errstr)) == -1)
557
+ goto fail;
558
+ }
559
+
560
+ return 0;
561
+
562
+ fail:
563
+ /* Permanent error */
564
+ rd_kafka_broker_fail(rktrans->rktrans_rkb, LOG_ERR,
565
+ RD_KAFKA_RESP_ERR__TRANSPORT, "%s", errstr);
566
+ return -1;
567
+ }
568
+
569
+
570
+ /**
571
+ * @brief Verify SSL handshake was valid.
572
+ */
573
+ static int rd_kafka_transport_ssl_verify(rd_kafka_transport_t *rktrans) {
574
+ long int rl;
575
+ X509 *cert;
576
+
577
+ if (!rktrans->rktrans_rkb->rkb_rk->rk_conf.ssl.enable_verify)
578
+ return 0;
579
+
580
+ #if OPENSSL_VERSION_NUMBER >= 0x30000000
581
+ cert = SSL_get1_peer_certificate(rktrans->rktrans_ssl);
582
+ #else
583
+ cert = SSL_get_peer_certificate(rktrans->rktrans_ssl);
584
+ #endif
585
+ X509_free(cert);
586
+ if (!cert) {
587
+ rd_kafka_broker_fail(rktrans->rktrans_rkb, LOG_ERR,
588
+ RD_KAFKA_RESP_ERR__SSL,
589
+ "Broker did not provide a certificate");
590
+ return -1;
591
+ }
592
+
593
+ if ((rl = SSL_get_verify_result(rktrans->rktrans_ssl)) != X509_V_OK) {
594
+ rd_kafka_broker_fail(rktrans->rktrans_rkb, LOG_ERR,
595
+ RD_KAFKA_RESP_ERR__SSL,
596
+ "Failed to verify broker certificate: %s",
597
+ X509_verify_cert_error_string(rl));
598
+ return -1;
599
+ }
600
+
601
+ rd_rkb_dbg(rktrans->rktrans_rkb, SECURITY, "SSLVERIFY",
602
+ "Broker SSL certificate verified");
603
+ return 0;
604
+ }
605
+
606
+ /**
607
+ * @brief SSL handshake handling.
608
+ * Call repeatedly (based on IO events) until handshake is done.
609
+ *
610
+ * @returns -1 on error, 0 if handshake is still in progress,
611
+ * or 1 on completion.
612
+ */
613
+ int rd_kafka_transport_ssl_handshake(rd_kafka_transport_t *rktrans) {
614
+ rd_kafka_broker_t *rkb = rktrans->rktrans_rkb;
615
+ char errstr[512];
616
+ int r;
617
+
618
+ r = SSL_do_handshake(rktrans->rktrans_ssl);
619
+ if (r == 1) {
620
+ /* SSL handshake done. Verify. */
621
+ if (rd_kafka_transport_ssl_verify(rktrans) == -1)
622
+ return -1;
623
+
624
+ rd_kafka_transport_connect_done(rktrans, NULL);
625
+ return 1;
626
+
627
+ } else if (rd_kafka_transport_ssl_io_update(rktrans, r, errstr,
628
+ sizeof(errstr)) == -1) {
629
+ const char *extra = "";
630
+ rd_kafka_resp_err_t err = RD_KAFKA_RESP_ERR__SSL;
631
+
632
+ if (strstr(errstr, "unexpected message"))
633
+ extra =
634
+ ": client SSL authentication might be "
635
+ "required (see ssl.key.location and "
636
+ "ssl.certificate.location and consult the "
637
+ "broker logs for more information)";
638
+ else if (strstr(errstr,
639
+ "tls_process_server_certificate:"
640
+ "certificate verify failed") ||
641
+ strstr(errstr, "error:0A000086") /*openssl3*/ ||
642
+ strstr(errstr,
643
+ "get_server_certificate:"
644
+ "certificate verify failed"))
645
+ extra =
646
+ ": broker certificate could not be verified, "
647
+ "verify that ssl.ca.location is correctly "
648
+ "configured or root CA certificates are "
649
+ "installed"
650
+ #ifdef __APPLE__
651
+ " (brew install openssl)"
652
+ #elif defined(_WIN32)
653
+ " (add broker's CA certificate to the Windows "
654
+ "Root certificate store)"
655
+ #else
656
+ " (install ca-certificates package)"
657
+ #endif
658
+ ;
659
+ else if (!strcmp(errstr, "Disconnected")) {
660
+ extra = ": connecting to a PLAINTEXT broker listener?";
661
+ /* Disconnects during handshake are most likely
662
+ * not due to SSL, but rather at the transport level */
663
+ err = RD_KAFKA_RESP_ERR__TRANSPORT;
664
+ }
665
+
666
+ rd_kafka_broker_fail(rkb, LOG_ERR, err,
667
+ "SSL handshake failed: %s%s", errstr,
668
+ extra);
669
+ return -1;
670
+ }
671
+
672
+ return 0;
673
+ }
674
+
675
+
676
+
677
+ /**
678
+ * @brief Parse a PEM-formatted string into an EVP_PKEY (PrivateKey) object.
679
+ *
680
+ * @param str Input PEM string, nul-terminated
681
+ *
682
+ * @remark This method does not provide automatic addition of PEM
683
+ * headers and footers.
684
+ *
685
+ * @returns a new EVP_PKEY on success or NULL on error.
686
+ */
687
+ static EVP_PKEY *rd_kafka_ssl_PKEY_from_string(rd_kafka_t *rk,
688
+ const char *str) {
689
+ BIO *bio = BIO_new_mem_buf((void *)str, -1);
690
+ EVP_PKEY *pkey;
691
+
692
+ pkey = PEM_read_bio_PrivateKey(bio, NULL,
693
+ rd_kafka_transport_ssl_passwd_cb, rk);
694
+
695
+ BIO_free(bio);
696
+
697
+ return pkey;
698
+ }
699
+
700
+ /**
701
+ * @brief Parse a PEM-formatted string into an X509 object.
702
+ *
703
+ * @param str Input PEM string, nul-terminated
704
+ *
705
+ * @returns a new X509 on success or NULL on error.
706
+ */
707
+ static X509 *rd_kafka_ssl_X509_from_string(rd_kafka_t *rk, const char *str) {
708
+ BIO *bio = BIO_new_mem_buf((void *)str, -1);
709
+ X509 *x509;
710
+
711
+ x509 =
712
+ PEM_read_bio_X509(bio, NULL, rd_kafka_transport_ssl_passwd_cb, rk);
713
+
714
+ BIO_free(bio);
715
+
716
+ return x509;
717
+ }
718
+
719
+
720
+ #ifdef _WIN32
721
+
722
+ /**
723
+ * @brief Attempt load CA certificates from a Windows Certificate store.
724
+ */
725
+ static int rd_kafka_ssl_win_load_cert_store(rd_kafka_t *rk,
726
+ SSL_CTX *ctx,
727
+ const char *store_name) {
728
+ HCERTSTORE w_store;
729
+ PCCERT_CONTEXT w_cctx = NULL;
730
+ X509_STORE *store;
731
+ int fail_cnt = 0, cnt = 0;
732
+ char errstr[256];
733
+ wchar_t *wstore_name;
734
+ size_t wsize = 0;
735
+ errno_t werr;
736
+
737
+ /* Convert store_name to wide-char */
738
+ werr = mbstowcs_s(&wsize, NULL, 0, store_name, strlen(store_name));
739
+ if (werr || wsize < 2 || wsize > 1000) {
740
+ rd_kafka_log(rk, LOG_ERR, "CERTSTORE",
741
+ "Invalid Windows certificate store name: %.*s%s",
742
+ 30, store_name,
743
+ wsize < 2 ? " (empty)" : " (truncated)");
744
+ return -1;
745
+ }
746
+ wstore_name = rd_alloca(sizeof(*wstore_name) * wsize);
747
+ werr = mbstowcs_s(NULL, wstore_name, wsize, store_name,
748
+ strlen(store_name));
749
+ rd_assert(!werr);
750
+
751
+ w_store = CertOpenStore(CERT_STORE_PROV_SYSTEM, 0, 0,
752
+ CERT_SYSTEM_STORE_CURRENT_USER |
753
+ CERT_STORE_READONLY_FLAG |
754
+ CERT_STORE_OPEN_EXISTING_FLAG,
755
+ wstore_name);
756
+ if (!w_store) {
757
+ rd_kafka_log(
758
+ rk, LOG_ERR, "CERTSTORE",
759
+ "Failed to open Windows certificate "
760
+ "%s store: %s",
761
+ store_name,
762
+ rd_strerror_w32(GetLastError(), errstr, sizeof(errstr)));
763
+ return -1;
764
+ }
765
+
766
+ /* Get the OpenSSL trust store */
767
+ store = SSL_CTX_get_cert_store(ctx);
768
+
769
+ /* Enumerate the Windows certs */
770
+ while ((w_cctx = CertEnumCertificatesInStore(w_store, w_cctx))) {
771
+ X509 *x509;
772
+
773
+ /* Parse Windows cert: DER -> X.509 */
774
+ x509 = d2i_X509(NULL,
775
+ (const unsigned char **)&w_cctx->pbCertEncoded,
776
+ (long)w_cctx->cbCertEncoded);
777
+ if (!x509) {
778
+ fail_cnt++;
779
+ continue;
780
+ }
781
+
782
+ /* Add cert to OpenSSL's trust store */
783
+ if (!X509_STORE_add_cert(store, x509))
784
+ fail_cnt++;
785
+ else
786
+ cnt++;
787
+
788
+ X509_free(x509);
789
+ }
790
+
791
+ if (w_cctx)
792
+ CertFreeCertificateContext(w_cctx);
793
+
794
+ CertCloseStore(w_store, 0);
795
+
796
+ rd_kafka_dbg(rk, SECURITY, "CERTSTORE",
797
+ "%d certificate(s) successfully added from "
798
+ "Windows Certificate %s store, %d failed",
799
+ cnt, store_name, fail_cnt);
800
+
801
+ if (cnt == 0 && fail_cnt > 0)
802
+ return -1;
803
+
804
+ return cnt;
805
+ }
806
+
807
+ /**
808
+ * @brief Load certs from the configured CSV list of Windows Cert stores.
809
+ *
810
+ * @returns the number of successfully loaded certificates, or -1 on error.
811
+ */
812
+ static int rd_kafka_ssl_win_load_cert_stores(rd_kafka_t *rk,
813
+ SSL_CTX *ctx,
814
+ const char *store_names) {
815
+ char *s;
816
+ int cert_cnt = 0, fail_cnt = 0;
817
+
818
+ if (!store_names || !*store_names)
819
+ return 0;
820
+
821
+ rd_strdupa(&s, store_names);
822
+
823
+ /* Parse CSV list ("Root,CA, , ,Something") and load
824
+ * each store in order. */
825
+ while (*s) {
826
+ char *t;
827
+ const char *store_name;
828
+ int r;
829
+
830
+ while (isspace((int)*s) || *s == ',')
831
+ s++;
832
+
833
+ if (!*s)
834
+ break;
835
+
836
+ store_name = s;
837
+
838
+ t = strchr(s, (int)',');
839
+ if (t) {
840
+ *t = '\0';
841
+ s = t + 1;
842
+ for (; t >= store_name && isspace((int)*t); t--)
843
+ *t = '\0';
844
+ } else {
845
+ s = "";
846
+ }
847
+
848
+ r = rd_kafka_ssl_win_load_cert_store(rk, ctx, store_name);
849
+ if (r != -1)
850
+ cert_cnt += r;
851
+ else
852
+ fail_cnt++;
853
+ }
854
+
855
+ if (cert_cnt == 0 && fail_cnt > 0)
856
+ return -1;
857
+
858
+ return cert_cnt;
859
+ }
860
+ #endif /* MSC_VER */
861
+
862
+
863
+
864
+ /**
865
+ * @brief Probe for the system's CA certificate location and if found set it
866
+ * on the \p CTX.
867
+ *
868
+ * @returns 0 if CA location was set, else -1.
869
+ */
870
+ static int rd_kafka_ssl_probe_and_set_default_ca_location(rd_kafka_t *rk,
871
+ SSL_CTX *ctx) {
872
+ #if _WIN32
873
+ /* No standard location on Windows, CA certs are in the ROOT store. */
874
+ return -1;
875
+ #else
876
+ /* The probe paths are based on:
877
+ * https://www.happyassassin.net/posts/2015/01/12/a-note-about-ssltls-trusted-certificate-stores-and-platforms/
878
+ * Golang's crypto probing paths:
879
+ * https://golang.org/search?q=certFiles and certDirectories
880
+ */
881
+ static const char *paths[] = {
882
+ "/etc/pki/tls/certs/ca-bundle.crt",
883
+ "/etc/ssl/certs/ca-bundle.crt",
884
+ "/etc/pki/tls/certs/ca-bundle.trust.crt",
885
+ "/etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem",
886
+
887
+ "/etc/ssl/ca-bundle.pem",
888
+ "/etc/pki/tls/cacert.pem",
889
+ "/etc/ssl/cert.pem",
890
+ "/etc/ssl/cacert.pem",
891
+
892
+ "/etc/certs/ca-certificates.crt",
893
+ "/etc/ssl/certs/ca-certificates.crt",
894
+
895
+ "/etc/ssl/certs",
896
+
897
+ "/usr/local/etc/ssl/cert.pem",
898
+ "/usr/local/etc/ssl/cacert.pem",
899
+
900
+ "/usr/local/etc/ssl/certs/cert.pem",
901
+ "/usr/local/etc/ssl/certs/cacert.pem",
902
+
903
+ /* BSD */
904
+ "/usr/local/share/certs/ca-root-nss.crt",
905
+ "/etc/openssl/certs/ca-certificates.crt",
906
+ #ifdef __APPLE__
907
+ "/private/etc/ssl/cert.pem",
908
+ "/private/etc/ssl/certs",
909
+ "/usr/local/etc/openssl@1.1/cert.pem",
910
+ "/usr/local/etc/openssl@1.0/cert.pem",
911
+ "/usr/local/etc/openssl/certs",
912
+ "/System/Library/OpenSSL",
913
+ #endif
914
+ #ifdef _AIX
915
+ "/var/ssl/certs/ca-bundle.crt",
916
+ #endif
917
+ NULL,
918
+ };
919
+ const char *path = NULL;
920
+ int i;
921
+
922
+ for (i = 0; (path = paths[i]); i++) {
923
+ struct stat st;
924
+ rd_bool_t is_dir;
925
+ int r;
926
+
927
+ if (stat(path, &st) != 0)
928
+ continue;
929
+
930
+ is_dir = S_ISDIR(st.st_mode);
931
+
932
+ if (is_dir && rd_kafka_dir_is_empty(path))
933
+ continue;
934
+
935
+ rd_kafka_dbg(rk, SECURITY, "CACERTS",
936
+ "Setting default CA certificate location "
937
+ "to %s, override with ssl.ca.location",
938
+ path);
939
+
940
+ r = SSL_CTX_load_verify_locations(ctx, is_dir ? NULL : path,
941
+ is_dir ? path : NULL);
942
+ if (r != 1) {
943
+ char errstr[512];
944
+ /* Read error and clear the error stack */
945
+ rd_kafka_ssl_error(rk, NULL, errstr, sizeof(errstr));
946
+ rd_kafka_dbg(rk, SECURITY, "CACERTS",
947
+ "Failed to set default CA certificate "
948
+ "location to %s %s: %s: skipping",
949
+ is_dir ? "directory" : "file", path,
950
+ errstr);
951
+ continue;
952
+ }
953
+
954
+ return 0;
955
+ }
956
+
957
+ rd_kafka_dbg(rk, SECURITY, "CACERTS",
958
+ "Unable to find any standard CA certificate"
959
+ "paths: is the ca-certificates package installed?");
960
+ return -1;
961
+ #endif
962
+ }
963
+
964
+
965
+ /**
966
+ * @brief Registers certificates, keys, etc, on the SSL_CTX
967
+ *
968
+ * @returns -1 on error, or 0 on success.
969
+ */
970
+ static int rd_kafka_ssl_set_certs(rd_kafka_t *rk,
971
+ SSL_CTX *ctx,
972
+ char *errstr,
973
+ size_t errstr_size) {
974
+ rd_bool_t ca_probe = rd_true;
975
+ rd_bool_t check_pkey = rd_false;
976
+ int r;
977
+
978
+ /*
979
+ * ssl_ca, ssl.ca.location, or Windows cert root store,
980
+ * or default paths.
981
+ */
982
+ if (rk->rk_conf.ssl.ca) {
983
+ /* CA certificate chain set with conf_set_ssl_cert() */
984
+ rd_kafka_dbg(rk, SECURITY, "SSL",
985
+ "Loading CA certificate(s) from memory");
986
+
987
+ SSL_CTX_set_cert_store(ctx, rk->rk_conf.ssl.ca->store);
988
+
989
+ /* OpenSSL takes ownership of the store */
990
+ rk->rk_conf.ssl.ca->store = NULL;
991
+
992
+ ca_probe = rd_false;
993
+
994
+ } else {
995
+
996
+ if (rk->rk_conf.ssl.ca_location &&
997
+ strcmp(rk->rk_conf.ssl.ca_location, "probe")) {
998
+ /* CA certificate location, either file or directory. */
999
+ int is_dir =
1000
+ rd_kafka_path_is_dir(rk->rk_conf.ssl.ca_location);
1001
+
1002
+ rd_kafka_dbg(rk, SECURITY, "SSL",
1003
+ "Loading CA certificate(s) from %s %s",
1004
+ is_dir ? "directory" : "file",
1005
+ rk->rk_conf.ssl.ca_location);
1006
+
1007
+ r = SSL_CTX_load_verify_locations(
1008
+ ctx, !is_dir ? rk->rk_conf.ssl.ca_location : NULL,
1009
+ is_dir ? rk->rk_conf.ssl.ca_location : NULL);
1010
+
1011
+ if (r != 1) {
1012
+ rd_snprintf(errstr, errstr_size,
1013
+ "ssl.ca.location failed: ");
1014
+ return -1;
1015
+ }
1016
+
1017
+ ca_probe = rd_false;
1018
+ }
1019
+
1020
+ if (rk->rk_conf.ssl.ca_pem) {
1021
+ /* CA as PEM string */
1022
+ X509 *x509;
1023
+ X509_STORE *store;
1024
+ BIO *bio;
1025
+ int cnt = 0;
1026
+
1027
+ /* Get the OpenSSL trust store */
1028
+ store = SSL_CTX_get_cert_store(ctx);
1029
+ rd_assert(store != NULL);
1030
+
1031
+ rd_kafka_dbg(rk, SECURITY, "SSL",
1032
+ "Loading CA certificate(s) from string");
1033
+
1034
+ bio =
1035
+ BIO_new_mem_buf((void *)rk->rk_conf.ssl.ca_pem, -1);
1036
+ rd_assert(bio != NULL);
1037
+
1038
+ /* Add all certificates to cert store */
1039
+ while ((x509 = PEM_read_bio_X509(
1040
+ bio, NULL, rd_kafka_transport_ssl_passwd_cb,
1041
+ rk))) {
1042
+ if (!X509_STORE_add_cert(store, x509)) {
1043
+ rd_snprintf(errstr, errstr_size,
1044
+ "failed to add ssl.ca.pem "
1045
+ "certificate "
1046
+ "#%d to CA cert store: ",
1047
+ cnt);
1048
+ X509_free(x509);
1049
+ BIO_free(bio);
1050
+ return -1;
1051
+ }
1052
+
1053
+ X509_free(x509);
1054
+ cnt++;
1055
+ }
1056
+
1057
+ if (!BIO_eof(bio) || !cnt) {
1058
+ rd_snprintf(errstr, errstr_size,
1059
+ "failed to read certificate #%d "
1060
+ "from ssl.ca.pem: "
1061
+ "not in PEM format?: ",
1062
+ cnt);
1063
+ BIO_free(bio);
1064
+ return -1;
1065
+ }
1066
+
1067
+ BIO_free(bio);
1068
+
1069
+ rd_kafka_dbg(rk, SECURITY, "SSL",
1070
+ "Loaded %d CA certificate(s) from string",
1071
+ cnt);
1072
+
1073
+
1074
+ ca_probe = rd_false;
1075
+ }
1076
+ }
1077
+
1078
+ if (ca_probe) {
1079
+ #ifdef _WIN32
1080
+ /* Attempt to load CA root certificates from the
1081
+ * configured Windows certificate stores. */
1082
+ r = rd_kafka_ssl_win_load_cert_stores(
1083
+ rk, ctx, rk->rk_conf.ssl.ca_cert_stores);
1084
+ if (r == 0) {
1085
+ rd_kafka_log(
1086
+ rk, LOG_NOTICE, "CERTSTORE",
1087
+ "No CA certificates loaded from "
1088
+ "Windows certificate stores: "
1089
+ "falling back to default OpenSSL CA paths");
1090
+ r = -1;
1091
+ } else if (r == -1)
1092
+ rd_kafka_log(
1093
+ rk, LOG_NOTICE, "CERTSTORE",
1094
+ "Failed to load CA certificates from "
1095
+ "Windows certificate stores: "
1096
+ "falling back to default OpenSSL CA paths");
1097
+ #else
1098
+ r = -1;
1099
+ #endif
1100
+
1101
+ if ((rk->rk_conf.ssl.ca_location &&
1102
+ !strcmp(rk->rk_conf.ssl.ca_location, "probe"))
1103
+ #if WITH_STATIC_LIB_libcrypto
1104
+ || r == -1
1105
+ #endif
1106
+ ) {
1107
+ /* If OpenSSL was linked statically there is a risk
1108
+ * that the system installed CA certificate path
1109
+ * doesn't match the cert path of OpenSSL.
1110
+ * To circumvent this we check for the existence
1111
+ * of standard CA certificate paths and use the
1112
+ * first one that is found.
1113
+ * Ignore failures. */
1114
+ r = rd_kafka_ssl_probe_and_set_default_ca_location(rk,
1115
+ ctx);
1116
+ }
1117
+
1118
+ if (r == -1) {
1119
+ /* Use default CA certificate paths from linked OpenSSL:
1120
+ * ignore failures */
1121
+
1122
+ r = SSL_CTX_set_default_verify_paths(ctx);
1123
+ if (r != 1) {
1124
+ char errstr2[512];
1125
+ /* Read error and clear the error stack. */
1126
+ rd_kafka_ssl_error(rk, NULL, errstr2,
1127
+ sizeof(errstr2));
1128
+ rd_kafka_dbg(
1129
+ rk, SECURITY, "SSL",
1130
+ "SSL_CTX_set_default_verify_paths() "
1131
+ "failed: %s: ignoring",
1132
+ errstr2);
1133
+ }
1134
+ r = 0;
1135
+ }
1136
+ }
1137
+
1138
+ if (rk->rk_conf.ssl.crl_location) {
1139
+ rd_kafka_dbg(rk, SECURITY, "SSL", "Loading CRL from file %s",
1140
+ rk->rk_conf.ssl.crl_location);
1141
+
1142
+ r = SSL_CTX_load_verify_locations(
1143
+ ctx, rk->rk_conf.ssl.crl_location, NULL);
1144
+
1145
+ if (r != 1) {
1146
+ rd_snprintf(errstr, errstr_size,
1147
+ "ssl.crl.location failed: ");
1148
+ return -1;
1149
+ }
1150
+
1151
+
1152
+ rd_kafka_dbg(rk, SECURITY, "SSL", "Enabling CRL checks");
1153
+
1154
+ X509_STORE_set_flags(SSL_CTX_get_cert_store(ctx),
1155
+ X509_V_FLAG_CRL_CHECK);
1156
+ }
1157
+
1158
+
1159
+ /*
1160
+ * ssl_cert, ssl.certificate.location and ssl.certificate.pem
1161
+ */
1162
+ if (rk->rk_conf.ssl.cert) {
1163
+ rd_kafka_dbg(rk, SECURITY, "SSL",
1164
+ "Loading public key from memory");
1165
+
1166
+ rd_assert(rk->rk_conf.ssl.cert->x509);
1167
+ r = SSL_CTX_use_certificate(ctx, rk->rk_conf.ssl.cert->x509);
1168
+ if (r != 1) {
1169
+ rd_snprintf(errstr, errstr_size, "ssl_cert failed: ");
1170
+ return -1;
1171
+ }
1172
+ }
1173
+
1174
+ if (rk->rk_conf.ssl.cert_location) {
1175
+ rd_kafka_dbg(rk, SECURITY, "SSL",
1176
+ "Loading public key from file %s",
1177
+ rk->rk_conf.ssl.cert_location);
1178
+
1179
+ r = SSL_CTX_use_certificate_chain_file(
1180
+ ctx, rk->rk_conf.ssl.cert_location);
1181
+
1182
+ if (r != 1) {
1183
+ rd_snprintf(errstr, errstr_size,
1184
+ "ssl.certificate.location failed: ");
1185
+ return -1;
1186
+ }
1187
+ }
1188
+
1189
+ if (rk->rk_conf.ssl.cert_pem) {
1190
+ X509 *x509;
1191
+
1192
+ rd_kafka_dbg(rk, SECURITY, "SSL",
1193
+ "Loading public key from string");
1194
+
1195
+ x509 =
1196
+ rd_kafka_ssl_X509_from_string(rk, rk->rk_conf.ssl.cert_pem);
1197
+ if (!x509) {
1198
+ rd_snprintf(errstr, errstr_size,
1199
+ "ssl.certificate.pem failed: "
1200
+ "not in PEM format?: ");
1201
+ return -1;
1202
+ }
1203
+
1204
+ r = SSL_CTX_use_certificate(ctx, x509);
1205
+
1206
+ X509_free(x509);
1207
+
1208
+ if (r != 1) {
1209
+ rd_snprintf(errstr, errstr_size,
1210
+ "ssl.certificate.pem failed: ");
1211
+ return -1;
1212
+ }
1213
+ }
1214
+
1215
+
1216
+ /*
1217
+ * ssl_key, ssl.key.location and ssl.key.pem
1218
+ */
1219
+ if (rk->rk_conf.ssl.key) {
1220
+ rd_kafka_dbg(rk, SECURITY, "SSL",
1221
+ "Loading private key file from memory");
1222
+
1223
+ rd_assert(rk->rk_conf.ssl.key->pkey);
1224
+ r = SSL_CTX_use_PrivateKey(ctx, rk->rk_conf.ssl.key->pkey);
1225
+ if (r != 1) {
1226
+ rd_snprintf(errstr, errstr_size,
1227
+ "ssl_key (in-memory) failed: ");
1228
+ return -1;
1229
+ }
1230
+
1231
+ check_pkey = rd_true;
1232
+ }
1233
+
1234
+ if (rk->rk_conf.ssl.key_location) {
1235
+ rd_kafka_dbg(rk, SECURITY, "SSL",
1236
+ "Loading private key file from %s",
1237
+ rk->rk_conf.ssl.key_location);
1238
+
1239
+ r = SSL_CTX_use_PrivateKey_file(
1240
+ ctx, rk->rk_conf.ssl.key_location, SSL_FILETYPE_PEM);
1241
+ if (r != 1) {
1242
+ rd_snprintf(errstr, errstr_size,
1243
+ "ssl.key.location failed: ");
1244
+ return -1;
1245
+ }
1246
+
1247
+ check_pkey = rd_true;
1248
+ }
1249
+
1250
+ if (rk->rk_conf.ssl.key_pem) {
1251
+ EVP_PKEY *pkey;
1252
+
1253
+ rd_kafka_dbg(rk, SECURITY, "SSL",
1254
+ "Loading private key from string");
1255
+
1256
+ pkey =
1257
+ rd_kafka_ssl_PKEY_from_string(rk, rk->rk_conf.ssl.key_pem);
1258
+ if (!pkey) {
1259
+ rd_snprintf(errstr, errstr_size,
1260
+ "ssl.key.pem failed: "
1261
+ "not in PEM format?: ");
1262
+ return -1;
1263
+ }
1264
+
1265
+ r = SSL_CTX_use_PrivateKey(ctx, pkey);
1266
+
1267
+ EVP_PKEY_free(pkey);
1268
+
1269
+ if (r != 1) {
1270
+ rd_snprintf(errstr, errstr_size,
1271
+ "ssl.key.pem failed: ");
1272
+ return -1;
1273
+ }
1274
+
1275
+ /* We no longer need the PEM key (it is cached in the CTX),
1276
+ * clear its memory. */
1277
+ rd_kafka_desensitize_str(rk->rk_conf.ssl.key_pem);
1278
+
1279
+ check_pkey = rd_true;
1280
+ }
1281
+
1282
+
1283
+ /*
1284
+ * ssl.keystore.location
1285
+ */
1286
+ if (rk->rk_conf.ssl.keystore_location) {
1287
+ EVP_PKEY *pkey;
1288
+ X509 *cert;
1289
+ STACK_OF(X509) *ca = NULL;
1290
+ BIO *bio;
1291
+ PKCS12 *p12;
1292
+
1293
+ rd_kafka_dbg(rk, SECURITY, "SSL",
1294
+ "Loading client's keystore file from %s",
1295
+ rk->rk_conf.ssl.keystore_location);
1296
+
1297
+ bio = BIO_new_file(rk->rk_conf.ssl.keystore_location, "rb");
1298
+ if (!bio) {
1299
+ rd_snprintf(errstr, errstr_size,
1300
+ "Failed to open ssl.keystore.location: "
1301
+ "%s: ",
1302
+ rk->rk_conf.ssl.keystore_location);
1303
+ return -1;
1304
+ }
1305
+
1306
+ p12 = d2i_PKCS12_bio(bio, NULL);
1307
+ if (!p12) {
1308
+ BIO_free(bio);
1309
+ rd_snprintf(errstr, errstr_size,
1310
+ "Error reading ssl.keystore.location "
1311
+ "PKCS#12 file: %s: ",
1312
+ rk->rk_conf.ssl.keystore_location);
1313
+ return -1;
1314
+ }
1315
+
1316
+ pkey = EVP_PKEY_new();
1317
+ cert = X509_new();
1318
+ if (!PKCS12_parse(p12, rk->rk_conf.ssl.keystore_password, &pkey,
1319
+ &cert, &ca)) {
1320
+ EVP_PKEY_free(pkey);
1321
+ X509_free(cert);
1322
+ PKCS12_free(p12);
1323
+ BIO_free(bio);
1324
+ if (ca != NULL)
1325
+ sk_X509_pop_free(ca, X509_free);
1326
+ rd_snprintf(errstr, errstr_size,
1327
+ "Failed to parse ssl.keystore.location "
1328
+ "PKCS#12 file: %s: ",
1329
+ rk->rk_conf.ssl.keystore_location);
1330
+ return -1;
1331
+ }
1332
+
1333
+ if (ca != NULL)
1334
+ sk_X509_pop_free(ca, X509_free);
1335
+
1336
+ PKCS12_free(p12);
1337
+ BIO_free(bio);
1338
+
1339
+ r = SSL_CTX_use_certificate(ctx, cert);
1340
+ X509_free(cert);
1341
+ if (r != 1) {
1342
+ EVP_PKEY_free(pkey);
1343
+ rd_snprintf(errstr, errstr_size,
1344
+ "Failed to use ssl.keystore.location "
1345
+ "certificate: ");
1346
+ return -1;
1347
+ }
1348
+
1349
+ r = SSL_CTX_use_PrivateKey(ctx, pkey);
1350
+ EVP_PKEY_free(pkey);
1351
+ if (r != 1) {
1352
+ rd_snprintf(errstr, errstr_size,
1353
+ "Failed to use ssl.keystore.location "
1354
+ "private key: ");
1355
+ return -1;
1356
+ }
1357
+
1358
+ check_pkey = rd_true;
1359
+ }
1360
+
1361
+ #if WITH_SSL_ENGINE
1362
+ /*
1363
+ * If applicable, use OpenSSL engine to fetch SSL certificate.
1364
+ */
1365
+ if (rk->rk_conf.ssl.engine) {
1366
+ STACK_OF(X509_NAME) *cert_names = sk_X509_NAME_new_null();
1367
+ STACK_OF(X509_OBJECT) *roots =
1368
+ X509_STORE_get0_objects(SSL_CTX_get_cert_store(ctx));
1369
+ X509 *x509 = NULL;
1370
+ EVP_PKEY *pkey = NULL;
1371
+ int i = 0;
1372
+ for (i = 0; i < sk_X509_OBJECT_num(roots); i++) {
1373
+ x509 = X509_OBJECT_get0_X509(
1374
+ sk_X509_OBJECT_value(roots, i));
1375
+
1376
+ if (x509)
1377
+ sk_X509_NAME_push(cert_names,
1378
+ X509_get_subject_name(x509));
1379
+ }
1380
+
1381
+ if (cert_names)
1382
+ sk_X509_NAME_free(cert_names);
1383
+
1384
+ x509 = NULL;
1385
+ r = ENGINE_load_ssl_client_cert(
1386
+ rk->rk_conf.ssl.engine, NULL, cert_names, &x509, &pkey,
1387
+ NULL, NULL, rk->rk_conf.ssl.engine_callback_data);
1388
+
1389
+ sk_X509_NAME_free(cert_names);
1390
+ if (r == -1 || !x509 || !pkey) {
1391
+ X509_free(x509);
1392
+ EVP_PKEY_free(pkey);
1393
+ if (r == -1)
1394
+ rd_snprintf(errstr, errstr_size,
1395
+ "OpenSSL "
1396
+ "ENGINE_load_ssl_client_cert "
1397
+ "failed: ");
1398
+ else if (!x509)
1399
+ rd_snprintf(errstr, errstr_size,
1400
+ "OpenSSL engine failed to "
1401
+ "load certificate: ");
1402
+ else
1403
+ rd_snprintf(errstr, errstr_size,
1404
+ "OpenSSL engine failed to "
1405
+ "load private key: ");
1406
+
1407
+ return -1;
1408
+ }
1409
+
1410
+ r = SSL_CTX_use_certificate(ctx, x509);
1411
+ X509_free(x509);
1412
+ if (r != 1) {
1413
+ rd_snprintf(errstr, errstr_size,
1414
+ "Failed to use SSL_CTX_use_certificate "
1415
+ "with engine: ");
1416
+ EVP_PKEY_free(pkey);
1417
+ return -1;
1418
+ }
1419
+
1420
+ r = SSL_CTX_use_PrivateKey(ctx, pkey);
1421
+ EVP_PKEY_free(pkey);
1422
+ if (r != 1) {
1423
+ rd_snprintf(errstr, errstr_size,
1424
+ "Failed to use SSL_CTX_use_PrivateKey "
1425
+ "with engine: ");
1426
+ return -1;
1427
+ }
1428
+
1429
+ check_pkey = rd_true;
1430
+ }
1431
+ #endif /*WITH_SSL_ENGINE*/
1432
+
1433
+ /* Check that a valid private/public key combo was set. */
1434
+ if (check_pkey && SSL_CTX_check_private_key(ctx) != 1) {
1435
+ rd_snprintf(errstr, errstr_size, "Private key check failed: ");
1436
+ return -1;
1437
+ }
1438
+
1439
+ return 0;
1440
+ }
1441
+
1442
+
1443
+ /**
1444
+ * @brief Once per rd_kafka_t handle cleanup of OpenSSL
1445
+ *
1446
+ * @locality any thread
1447
+ *
1448
+ * @locks rd_kafka_wrlock() MUST be held
1449
+ */
1450
+ void rd_kafka_ssl_ctx_term(rd_kafka_t *rk) {
1451
+ SSL_CTX_free(rk->rk_conf.ssl.ctx);
1452
+ rk->rk_conf.ssl.ctx = NULL;
1453
+
1454
+ #if WITH_SSL_ENGINE
1455
+ RD_IF_FREE(rk->rk_conf.ssl.engine, ENGINE_free);
1456
+ #endif
1457
+ }
1458
+
1459
+
1460
+ #if WITH_SSL_ENGINE
1461
+ /**
1462
+ * @brief Initialize and load OpenSSL engine, if configured.
1463
+ *
1464
+ * @returns true on success, false on error.
1465
+ */
1466
+ static rd_bool_t
1467
+ rd_kafka_ssl_ctx_init_engine(rd_kafka_t *rk, char *errstr, size_t errstr_size) {
1468
+ ENGINE *engine;
1469
+
1470
+ /* OpenSSL loads an engine as dynamic id and stores it in
1471
+ * internal list, as per LIST_ADD command below. If engine
1472
+ * already exists in internal list, it is supposed to be
1473
+ * fetched using engine id.
1474
+ */
1475
+ engine = ENGINE_by_id(rk->rk_conf.ssl.engine_id);
1476
+ if (!engine) {
1477
+ engine = ENGINE_by_id("dynamic");
1478
+ if (!engine) {
1479
+ rd_snprintf(errstr, errstr_size,
1480
+ "OpenSSL engine initialization failed in"
1481
+ " ENGINE_by_id: ");
1482
+ return rd_false;
1483
+ }
1484
+ }
1485
+
1486
+ if (!ENGINE_ctrl_cmd_string(engine, "SO_PATH",
1487
+ rk->rk_conf.ssl.engine_location, 0)) {
1488
+ ENGINE_free(engine);
1489
+ rd_snprintf(errstr, errstr_size,
1490
+ "OpenSSL engine initialization failed in"
1491
+ " ENGINE_ctrl_cmd_string SO_PATH: ");
1492
+ return rd_false;
1493
+ }
1494
+
1495
+ if (!ENGINE_ctrl_cmd_string(engine, "LIST_ADD", "1", 0)) {
1496
+ ENGINE_free(engine);
1497
+ rd_snprintf(errstr, errstr_size,
1498
+ "OpenSSL engine initialization failed in"
1499
+ " ENGINE_ctrl_cmd_string LIST_ADD: ");
1500
+ return rd_false;
1501
+ }
1502
+
1503
+ if (!ENGINE_ctrl_cmd_string(engine, "LOAD", NULL, 0)) {
1504
+ ENGINE_free(engine);
1505
+ rd_snprintf(errstr, errstr_size,
1506
+ "OpenSSL engine initialization failed in"
1507
+ " ENGINE_ctrl_cmd_string LOAD: ");
1508
+ return rd_false;
1509
+ }
1510
+
1511
+ if (!ENGINE_init(engine)) {
1512
+ ENGINE_free(engine);
1513
+ rd_snprintf(errstr, errstr_size,
1514
+ "OpenSSL engine initialization failed in"
1515
+ " ENGINE_init: ");
1516
+ return rd_false;
1517
+ }
1518
+
1519
+ rk->rk_conf.ssl.engine = engine;
1520
+
1521
+ return rd_true;
1522
+ }
1523
+ #endif
1524
+
1525
+
1526
+ #if OPENSSL_VERSION_NUMBER >= 0x30000000
1527
+ /**
1528
+ * @brief Wrapper around OSSL_PROVIDER_unload() to expose a free(void*) API
1529
+ * suitable for rd_list_t's free_cb.
1530
+ */
1531
+ static void rd_kafka_ssl_OSSL_PROVIDER_free(void *ptr) {
1532
+ OSSL_PROVIDER *prov = ptr;
1533
+ (void)OSSL_PROVIDER_unload(prov);
1534
+ }
1535
+
1536
+
1537
+ /**
1538
+ * @brief Load OpenSSL 3.0.x providers specified in comma-separated string.
1539
+ *
1540
+ * @remark Only the error preamble/prefix is written here, the actual
1541
+ * OpenSSL error is retrieved from the OpenSSL error stack by
1542
+ * the caller.
1543
+ *
1544
+ * @returns rd_false on failure (errstr will be written to), or rd_true
1545
+ * on successs.
1546
+ */
1547
+ static rd_bool_t rd_kafka_ssl_ctx_load_providers(rd_kafka_t *rk,
1548
+ const char *providers_csv,
1549
+ char *errstr,
1550
+ size_t errstr_size) {
1551
+ size_t provider_cnt, i;
1552
+ char **providers = rd_string_split(
1553
+ providers_csv, ',', rd_true /*skip empty*/, &provider_cnt);
1554
+
1555
+
1556
+ if (!providers || !provider_cnt) {
1557
+ rd_snprintf(errstr, errstr_size,
1558
+ "ssl.providers expects a comma-separated "
1559
+ "list of OpenSSL 3.0.x providers");
1560
+ if (providers)
1561
+ rd_free(providers);
1562
+ return rd_false;
1563
+ }
1564
+
1565
+ rd_list_init(&rk->rk_conf.ssl.loaded_providers, (int)provider_cnt,
1566
+ rd_kafka_ssl_OSSL_PROVIDER_free);
1567
+
1568
+ for (i = 0; i < provider_cnt; i++) {
1569
+ const char *provider = providers[i];
1570
+ OSSL_PROVIDER *prov;
1571
+ const char *buildinfo = NULL;
1572
+ OSSL_PARAM request[] = {{"buildinfo", OSSL_PARAM_UTF8_PTR,
1573
+ (void *)&buildinfo, 0, 0},
1574
+ {NULL, 0, NULL, 0, 0}};
1575
+
1576
+ prov = OSSL_PROVIDER_load(NULL, provider);
1577
+ if (!prov) {
1578
+ rd_snprintf(errstr, errstr_size,
1579
+ "Failed to load OpenSSL provider \"%s\": ",
1580
+ provider);
1581
+ rd_free(providers);
1582
+ return rd_false;
1583
+ }
1584
+
1585
+ if (!OSSL_PROVIDER_get_params(prov, request))
1586
+ buildinfo = "no buildinfo";
1587
+
1588
+ rd_kafka_dbg(rk, SECURITY, "SSL",
1589
+ "OpenSSL provider \"%s\" loaded (%s)", provider,
1590
+ buildinfo);
1591
+
1592
+ rd_list_add(&rk->rk_conf.ssl.loaded_providers, prov);
1593
+ }
1594
+
1595
+ rd_free(providers);
1596
+
1597
+ return rd_true;
1598
+ }
1599
+ #endif
1600
+
1601
+
1602
+
1603
+ /**
1604
+ * @brief Once per rd_kafka_t handle initialization of OpenSSL
1605
+ *
1606
+ * @locality application thread
1607
+ *
1608
+ * @locks rd_kafka_wrlock() MUST be held
1609
+ */
1610
+ int rd_kafka_ssl_ctx_init(rd_kafka_t *rk, char *errstr, size_t errstr_size) {
1611
+ int r;
1612
+ SSL_CTX *ctx = NULL;
1613
+ const char *linking =
1614
+ #if WITH_STATIC_LIB_libcrypto
1615
+ "statically linked "
1616
+ #else
1617
+ ""
1618
+ #endif
1619
+ ;
1620
+
1621
+ #if OPENSSL_VERSION_NUMBER >= 0x10100000
1622
+ rd_kafka_dbg(rk, SECURITY, "OPENSSL",
1623
+ "Using %sOpenSSL version %s "
1624
+ "(0x%lx, librdkafka built with 0x%lx)",
1625
+ linking, OpenSSL_version(OPENSSL_VERSION),
1626
+ OpenSSL_version_num(), OPENSSL_VERSION_NUMBER);
1627
+ #else
1628
+ rd_kafka_dbg(rk, SECURITY, "OPENSSL",
1629
+ "librdkafka built with %sOpenSSL version 0x%lx", linking,
1630
+ OPENSSL_VERSION_NUMBER);
1631
+ #endif
1632
+
1633
+ if (errstr_size > 0)
1634
+ errstr[0] = '\0';
1635
+
1636
+ #if OPENSSL_VERSION_NUMBER >= 0x30000000
1637
+ if (rk->rk_conf.ssl.providers &&
1638
+ !rd_kafka_ssl_ctx_load_providers(rk, rk->rk_conf.ssl.providers,
1639
+ errstr, errstr_size))
1640
+ goto fail;
1641
+ #endif
1642
+
1643
+ #if WITH_SSL_ENGINE
1644
+ if (rk->rk_conf.ssl.engine_location && !rk->rk_conf.ssl.engine) {
1645
+ rd_kafka_dbg(rk, SECURITY, "SSL",
1646
+ "Loading OpenSSL engine from \"%s\"",
1647
+ rk->rk_conf.ssl.engine_location);
1648
+ if (!rd_kafka_ssl_ctx_init_engine(rk, errstr, errstr_size))
1649
+ goto fail;
1650
+ }
1651
+ #endif
1652
+
1653
+ #if OPENSSL_VERSION_NUMBER >= 0x10100000
1654
+ ctx = SSL_CTX_new(TLS_client_method());
1655
+ #else
1656
+ ctx = SSL_CTX_new(SSLv23_client_method());
1657
+ #endif
1658
+ if (!ctx) {
1659
+ rd_snprintf(errstr, errstr_size, "SSL_CTX_new() failed: ");
1660
+ goto fail;
1661
+ }
1662
+
1663
+ #ifdef SSL_OP_NO_SSLv3
1664
+ /* Disable SSLv3 (unsafe) */
1665
+ SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv3);
1666
+ #endif
1667
+
1668
+ /* Key file password callback */
1669
+ SSL_CTX_set_default_passwd_cb(ctx, rd_kafka_transport_ssl_passwd_cb);
1670
+ SSL_CTX_set_default_passwd_cb_userdata(ctx, rk);
1671
+
1672
+ /* Ciphers */
1673
+ if (rk->rk_conf.ssl.cipher_suites) {
1674
+ rd_kafka_dbg(rk, SECURITY, "SSL", "Setting cipher list: %s",
1675
+ rk->rk_conf.ssl.cipher_suites);
1676
+ if (!SSL_CTX_set_cipher_list(ctx,
1677
+ rk->rk_conf.ssl.cipher_suites)) {
1678
+ /* Set a string that will prefix the
1679
+ * the OpenSSL error message (which is lousy)
1680
+ * to make it more meaningful. */
1681
+ rd_snprintf(errstr, errstr_size,
1682
+ "ssl.cipher.suites failed: ");
1683
+ goto fail;
1684
+ }
1685
+ }
1686
+
1687
+ /* Set up broker certificate verification. */
1688
+ SSL_CTX_set_verify(ctx,
1689
+ rk->rk_conf.ssl.enable_verify ? SSL_VERIFY_PEER
1690
+ : SSL_VERIFY_NONE,
1691
+ rk->rk_conf.ssl.cert_verify_cb
1692
+ ? rd_kafka_transport_ssl_cert_verify_cb
1693
+ : NULL);
1694
+
1695
+ #if OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined(LIBRESSL_VERSION_NUMBER)
1696
+ /* Curves */
1697
+ if (rk->rk_conf.ssl.curves_list) {
1698
+ rd_kafka_dbg(rk, SECURITY, "SSL", "Setting curves list: %s",
1699
+ rk->rk_conf.ssl.curves_list);
1700
+ if (!SSL_CTX_set1_curves_list(ctx,
1701
+ rk->rk_conf.ssl.curves_list)) {
1702
+ rd_snprintf(errstr, errstr_size,
1703
+ "ssl.curves.list failed: ");
1704
+ goto fail;
1705
+ }
1706
+ }
1707
+
1708
+ /* Certificate signature algorithms */
1709
+ if (rk->rk_conf.ssl.sigalgs_list) {
1710
+ rd_kafka_dbg(rk, SECURITY, "SSL",
1711
+ "Setting signature algorithms list: %s",
1712
+ rk->rk_conf.ssl.sigalgs_list);
1713
+ if (!SSL_CTX_set1_sigalgs_list(ctx,
1714
+ rk->rk_conf.ssl.sigalgs_list)) {
1715
+ rd_snprintf(errstr, errstr_size,
1716
+ "ssl.sigalgs.list failed: ");
1717
+ goto fail;
1718
+ }
1719
+ }
1720
+ #endif
1721
+
1722
+ /* Register certificates, keys, etc. */
1723
+ if (rd_kafka_ssl_set_certs(rk, ctx, errstr, errstr_size) == -1)
1724
+ goto fail;
1725
+
1726
+
1727
+ #ifdef SSL_OP_IGNORE_UNEXPECTED_EOF
1728
+ /* Ignore unexpected EOF error in OpenSSL 3.x, treating
1729
+ * it like a normal connection close even if
1730
+ * close_notify wasn't received.
1731
+ * see issue #4293 */
1732
+ SSL_CTX_set_options(ctx, SSL_OP_IGNORE_UNEXPECTED_EOF);
1733
+ #endif
1734
+
1735
+ SSL_CTX_set_mode(ctx, SSL_MODE_ENABLE_PARTIAL_WRITE);
1736
+
1737
+ rk->rk_conf.ssl.ctx = ctx;
1738
+
1739
+ return 0;
1740
+
1741
+ fail:
1742
+ r = (int)strlen(errstr);
1743
+ /* If only the error preamble is provided in errstr and ending with
1744
+ * "....: ", then retrieve the last error from the OpenSSL error stack,
1745
+ * else treat the errstr as complete. */
1746
+ if (r > 2 && !strcmp(&errstr[r - 2], ": "))
1747
+ rd_kafka_ssl_error(rk, NULL, errstr + r,
1748
+ (int)errstr_size > r ? (int)errstr_size - r
1749
+ : 0);
1750
+ RD_IF_FREE(ctx, SSL_CTX_free);
1751
+ #if WITH_SSL_ENGINE
1752
+ RD_IF_FREE(rk->rk_conf.ssl.engine, ENGINE_free);
1753
+ #endif
1754
+ rd_list_destroy(&rk->rk_conf.ssl.loaded_providers);
1755
+
1756
+ return -1;
1757
+ }
1758
+
1759
+
1760
+ #if OPENSSL_VERSION_NUMBER < 0x10100000L
1761
+ static RD_UNUSED void
1762
+ rd_kafka_transport_ssl_lock_cb(int mode, int i, const char *file, int line) {
1763
+ if (mode & CRYPTO_LOCK)
1764
+ mtx_lock(&rd_kafka_ssl_locks[i]);
1765
+ else
1766
+ mtx_unlock(&rd_kafka_ssl_locks[i]);
1767
+ }
1768
+ #endif
1769
+
1770
+ static RD_UNUSED unsigned long rd_kafka_transport_ssl_threadid_cb(void) {
1771
+ #ifdef _WIN32
1772
+ /* Windows makes a distinction between thread handle
1773
+ * and thread id, which means we can't use the
1774
+ * thrd_current() API that returns the handle. */
1775
+ return (unsigned long)GetCurrentThreadId();
1776
+ #else
1777
+ return (unsigned long)(intptr_t)thrd_current();
1778
+ #endif
1779
+ }
1780
+
1781
+ #ifdef HAVE_OPENSSL_CRYPTO_THREADID_SET_CALLBACK
1782
+ static void
1783
+ rd_kafka_transport_libcrypto_THREADID_callback(CRYPTO_THREADID *id) {
1784
+ unsigned long thread_id = rd_kafka_transport_ssl_threadid_cb();
1785
+
1786
+ CRYPTO_THREADID_set_numeric(id, thread_id);
1787
+ }
1788
+ #endif
1789
+
1790
+ /**
1791
+ * @brief Global OpenSSL cleanup.
1792
+ */
1793
+ void rd_kafka_ssl_term(void) {
1794
+ #if OPENSSL_VERSION_NUMBER < 0x10100000L
1795
+ int i;
1796
+
1797
+ if (CRYPTO_get_locking_callback() == &rd_kafka_transport_ssl_lock_cb) {
1798
+ CRYPTO_set_locking_callback(NULL);
1799
+ #ifdef HAVE_OPENSSL_CRYPTO_THREADID_SET_CALLBACK
1800
+ CRYPTO_THREADID_set_callback(NULL);
1801
+ #else
1802
+ CRYPTO_set_id_callback(NULL);
1803
+ #endif
1804
+
1805
+ for (i = 0; i < rd_kafka_ssl_locks_cnt; i++)
1806
+ mtx_destroy(&rd_kafka_ssl_locks[i]);
1807
+
1808
+ rd_free(rd_kafka_ssl_locks);
1809
+ }
1810
+ #endif
1811
+ }
1812
+
1813
+
1814
+ /**
1815
+ * @brief Global (once per process) OpenSSL init.
1816
+ */
1817
+ void rd_kafka_ssl_init(void) {
1818
+ #if OPENSSL_VERSION_NUMBER < 0x10100000L
1819
+ int i;
1820
+
1821
+ if (!CRYPTO_get_locking_callback()) {
1822
+ rd_kafka_ssl_locks_cnt = CRYPTO_num_locks();
1823
+ rd_kafka_ssl_locks = rd_malloc(rd_kafka_ssl_locks_cnt *
1824
+ sizeof(*rd_kafka_ssl_locks));
1825
+ for (i = 0; i < rd_kafka_ssl_locks_cnt; i++)
1826
+ mtx_init(&rd_kafka_ssl_locks[i], mtx_plain);
1827
+
1828
+ CRYPTO_set_locking_callback(rd_kafka_transport_ssl_lock_cb);
1829
+
1830
+ #ifdef HAVE_OPENSSL_CRYPTO_THREADID_SET_CALLBACK
1831
+ CRYPTO_THREADID_set_callback(
1832
+ rd_kafka_transport_libcrypto_THREADID_callback);
1833
+ #else
1834
+ CRYPTO_set_id_callback(rd_kafka_transport_ssl_threadid_cb);
1835
+ #endif
1836
+ }
1837
+
1838
+ /* OPENSSL_init_ssl(3) and OPENSSL_init_crypto(3) say:
1839
+ * "As of version 1.1.0 OpenSSL will automatically allocate
1840
+ * all resources that it needs so no explicit initialisation
1841
+ * is required. Similarly it will also automatically
1842
+ * deinitialise as required."
1843
+ */
1844
+ SSL_load_error_strings();
1845
+ SSL_library_init();
1846
+
1847
+ ERR_load_BIO_strings();
1848
+ ERR_load_crypto_strings();
1849
+ OpenSSL_add_all_algorithms();
1850
+ #endif
1851
+ }
1852
+
1853
+ int rd_kafka_ssl_hmac(rd_kafka_broker_t *rkb,
1854
+ const EVP_MD *evp,
1855
+ const rd_chariov_t *in,
1856
+ const rd_chariov_t *salt,
1857
+ int itcnt,
1858
+ rd_chariov_t *out) {
1859
+ unsigned int ressize = 0;
1860
+ unsigned char tempres[EVP_MAX_MD_SIZE];
1861
+ unsigned char *saltplus;
1862
+ int i;
1863
+
1864
+ /* U1 := HMAC(str, salt + INT(1)) */
1865
+ saltplus = rd_alloca(salt->size + 4);
1866
+ memcpy(saltplus, salt->ptr, salt->size);
1867
+ saltplus[salt->size] = 0;
1868
+ saltplus[salt->size + 1] = 0;
1869
+ saltplus[salt->size + 2] = 0;
1870
+ saltplus[salt->size + 3] = 1;
1871
+
1872
+ /* U1 := HMAC(str, salt + INT(1)) */
1873
+ if (!HMAC(evp, (const unsigned char *)in->ptr, (int)in->size, saltplus,
1874
+ salt->size + 4, tempres, &ressize)) {
1875
+ rd_rkb_dbg(rkb, SECURITY, "SSLHMAC", "HMAC priming failed");
1876
+ return -1;
1877
+ }
1878
+
1879
+ memcpy(out->ptr, tempres, ressize);
1880
+
1881
+ /* Ui-1 := HMAC(str, Ui-2) .. */
1882
+ for (i = 1; i < itcnt; i++) {
1883
+ unsigned char tempdest[EVP_MAX_MD_SIZE];
1884
+ int j;
1885
+
1886
+ if (unlikely(!HMAC(evp, (const unsigned char *)in->ptr,
1887
+ (int)in->size, tempres, ressize, tempdest,
1888
+ NULL))) {
1889
+ rd_rkb_dbg(rkb, SECURITY, "SSLHMAC",
1890
+ "Hi() HMAC #%d/%d failed", i, itcnt);
1891
+ return -1;
1892
+ }
1893
+
1894
+ /* U1 XOR U2 .. */
1895
+ for (j = 0; j < (int)ressize; j++) {
1896
+ out->ptr[j] ^= tempdest[j];
1897
+ tempres[j] = tempdest[j];
1898
+ }
1899
+ }
1900
+
1901
+ out->size = ressize;
1902
+
1903
+ return 0;
1904
+ }