@point3/node-rdkafka 3.6.0-1

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