@ohos-ports/confluentinc-kafka-javascript 1.10.0-beta.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.
- package/CHANGELOG.md +457 -0
- package/LICENSE.kafkajs +31 -0
- package/LICENSE.node-rdkafka +25 -0
- package/LICENSE.txt +20 -0
- package/README.md +133 -0
- package/binding.gyp +184 -0
- package/build/Release/confluent-kafka-javascript.node +0 -0
- package/build/deps/librdkafka++.so.1 +0 -0
- package/build/deps/librdkafka.Makefile +6 -0
- package/build/deps/librdkafka.so.1 +0 -0
- package/build/deps/librdkafka.target.mk +55 -0
- package/deps/librdkafka/.clang-format +136 -0
- package/deps/librdkafka/.clang-format-cpp +103 -0
- package/deps/librdkafka/.dir-locals.el +10 -0
- package/deps/librdkafka/.formatignore +35 -0
- package/deps/librdkafka/.gdbmacros +19 -0
- package/deps/librdkafka/CHANGELOG.md +2477 -0
- package/deps/librdkafka/CMakeLists.txt +291 -0
- package/deps/librdkafka/CODE_OF_CONDUCT.md +46 -0
- package/deps/librdkafka/CONFIGURATION.md +212 -0
- package/deps/librdkafka/CONTRIBUTING.md +431 -0
- package/deps/librdkafka/Doxyfile +2375 -0
- package/deps/librdkafka/INTRODUCTION.md +2752 -0
- package/deps/librdkafka/LICENSE +26 -0
- package/deps/librdkafka/LICENSE.cjson +22 -0
- package/deps/librdkafka/LICENSE.crc32c +28 -0
- package/deps/librdkafka/LICENSE.fnv1a +18 -0
- package/deps/librdkafka/LICENSE.hdrhistogram +27 -0
- package/deps/librdkafka/LICENSE.lz4 +26 -0
- package/deps/librdkafka/LICENSE.murmur2 +25 -0
- package/deps/librdkafka/LICENSE.nanopb +22 -0
- package/deps/librdkafka/LICENSE.opentelemetry +203 -0
- package/deps/librdkafka/LICENSE.pycrc +23 -0
- package/deps/librdkafka/LICENSE.queue +31 -0
- package/deps/librdkafka/LICENSE.regexp +5 -0
- package/deps/librdkafka/LICENSE.snappy +36 -0
- package/deps/librdkafka/LICENSE.tinycthread +26 -0
- package/deps/librdkafka/LICENSE.wingetopt +49 -0
- package/deps/librdkafka/LICENSES.txt +625 -0
- package/deps/librdkafka/Makefile +125 -0
- package/deps/librdkafka/README.md +201 -0
- package/deps/librdkafka/README.win32 +26 -0
- package/deps/librdkafka/STATISTICS.md +624 -0
- package/deps/librdkafka/configure +214 -0
- package/deps/librdkafka/configure.self +341 -0
- package/deps/librdkafka/dev-conf.sh +123 -0
- package/deps/librdkafka/lds-gen.py +73 -0
- package/deps/librdkafka/mainpage.doxy +40 -0
- package/deps/librdkafka/mklove/Makefile.base +329 -0
- package/deps/librdkafka/mklove/modules/configure.atomics +144 -0
- package/deps/librdkafka/mklove/modules/configure.base +2484 -0
- package/deps/librdkafka/mklove/modules/configure.builtin +70 -0
- package/deps/librdkafka/mklove/modules/configure.cc +186 -0
- package/deps/librdkafka/mklove/modules/configure.cxx +8 -0
- package/deps/librdkafka/mklove/modules/configure.fileversion +65 -0
- package/deps/librdkafka/mklove/modules/configure.gitversion +29 -0
- package/deps/librdkafka/mklove/modules/configure.good_cflags +18 -0
- package/deps/librdkafka/mklove/modules/configure.host +132 -0
- package/deps/librdkafka/mklove/modules/configure.lib +49 -0
- package/deps/librdkafka/mklove/modules/configure.libcurl +99 -0
- package/deps/librdkafka/mklove/modules/configure.libsasl2 +36 -0
- package/deps/librdkafka/mklove/modules/configure.libssl +147 -0
- package/deps/librdkafka/mklove/modules/configure.libzstd +58 -0
- package/deps/librdkafka/mklove/modules/configure.parseversion +95 -0
- package/deps/librdkafka/mklove/modules/configure.pic +16 -0
- package/deps/librdkafka/mklove/modules/configure.socket +20 -0
- package/deps/librdkafka/mklove/modules/configure.zlib +61 -0
- package/deps/librdkafka/mklove/modules/patches/README.md +8 -0
- package/deps/librdkafka/mklove/modules/patches/libcurl.0000-no-runtime-linking-check.patch +11 -0
- package/deps/librdkafka/mklove/modules/patches/libssl.0000-osx-rand-include-fix-OpenSSL-PR16409.patch +56 -0
- package/deps/librdkafka/service.yml +182 -0
- package/deps/librdkafka/src/CMakeLists.txt +379 -0
- package/deps/librdkafka/src/Makefile +105 -0
- package/deps/librdkafka/src/README.lz4.md +30 -0
- package/deps/librdkafka/src/cJSON.c +3191 -0
- package/deps/librdkafka/src/cJSON.h +306 -0
- package/deps/librdkafka/src/crc32c.c +430 -0
- package/deps/librdkafka/src/crc32c.h +38 -0
- package/deps/librdkafka/src/generate_proto.sh +66 -0
- package/deps/librdkafka/src/librdkafka_cgrp_synch.png +0 -0
- package/deps/librdkafka/src/lz4.c +2727 -0
- package/deps/librdkafka/src/lz4.h +842 -0
- package/deps/librdkafka/src/lz4frame.c +2078 -0
- package/deps/librdkafka/src/lz4frame.h +692 -0
- package/deps/librdkafka/src/lz4frame_static.h +47 -0
- package/deps/librdkafka/src/lz4hc.c +1631 -0
- package/deps/librdkafka/src/lz4hc.h +413 -0
- package/deps/librdkafka/src/nanopb/pb.h +917 -0
- package/deps/librdkafka/src/nanopb/pb_common.c +388 -0
- package/deps/librdkafka/src/nanopb/pb_common.h +49 -0
- package/deps/librdkafka/src/nanopb/pb_decode.c +1727 -0
- package/deps/librdkafka/src/nanopb/pb_decode.h +193 -0
- package/deps/librdkafka/src/nanopb/pb_encode.c +1000 -0
- package/deps/librdkafka/src/nanopb/pb_encode.h +185 -0
- package/deps/librdkafka/src/opentelemetry/common.pb.c +32 -0
- package/deps/librdkafka/src/opentelemetry/common.pb.h +170 -0
- package/deps/librdkafka/src/opentelemetry/metrics.options +2 -0
- package/deps/librdkafka/src/opentelemetry/metrics.pb.c +67 -0
- package/deps/librdkafka/src/opentelemetry/metrics.pb.h +966 -0
- package/deps/librdkafka/src/opentelemetry/resource.pb.c +12 -0
- package/deps/librdkafka/src/opentelemetry/resource.pb.h +58 -0
- package/deps/librdkafka/src/queue.h +850 -0
- package/deps/librdkafka/src/rd.h +592 -0
- package/deps/librdkafka/src/rdaddr.c +255 -0
- package/deps/librdkafka/src/rdaddr.h +202 -0
- package/deps/librdkafka/src/rdatomic.h +262 -0
- package/deps/librdkafka/src/rdavg.h +260 -0
- package/deps/librdkafka/src/rdavl.c +210 -0
- package/deps/librdkafka/src/rdavl.h +250 -0
- package/deps/librdkafka/src/rdbase64.c +200 -0
- package/deps/librdkafka/src/rdbase64.h +43 -0
- package/deps/librdkafka/src/rdbuf.c +1884 -0
- package/deps/librdkafka/src/rdbuf.h +375 -0
- package/deps/librdkafka/src/rdcrc32.c +114 -0
- package/deps/librdkafka/src/rdcrc32.h +170 -0
- package/deps/librdkafka/src/rddl.c +179 -0
- package/deps/librdkafka/src/rddl.h +43 -0
- package/deps/librdkafka/src/rdendian.h +175 -0
- package/deps/librdkafka/src/rdfloat.h +67 -0
- package/deps/librdkafka/src/rdfnv1a.c +113 -0
- package/deps/librdkafka/src/rdfnv1a.h +35 -0
- package/deps/librdkafka/src/rdgz.c +120 -0
- package/deps/librdkafka/src/rdgz.h +46 -0
- package/deps/librdkafka/src/rdhdrhistogram.c +721 -0
- package/deps/librdkafka/src/rdhdrhistogram.h +87 -0
- package/deps/librdkafka/src/rdhttp.c +831 -0
- package/deps/librdkafka/src/rdhttp.h +101 -0
- package/deps/librdkafka/src/rdinterval.h +177 -0
- package/deps/librdkafka/src/rdkafka.c +7287 -0
- package/deps/librdkafka/src/rdkafka.h +11795 -0
- package/deps/librdkafka/src/rdkafka_admin.c +10165 -0
- package/deps/librdkafka/src/rdkafka_admin.h +658 -0
- package/deps/librdkafka/src/rdkafka_assignment.c +1282 -0
- package/deps/librdkafka/src/rdkafka_assignment.h +73 -0
- package/deps/librdkafka/src/rdkafka_assignor.c +1800 -0
- package/deps/librdkafka/src/rdkafka_assignor.h +402 -0
- package/deps/librdkafka/src/rdkafka_aux.c +409 -0
- package/deps/librdkafka/src/rdkafka_aux.h +174 -0
- package/deps/librdkafka/src/rdkafka_background.c +222 -0
- package/deps/librdkafka/src/rdkafka_broker.c +6736 -0
- package/deps/librdkafka/src/rdkafka_broker.h +851 -0
- package/deps/librdkafka/src/rdkafka_buf.c +543 -0
- package/deps/librdkafka/src/rdkafka_buf.h +1525 -0
- package/deps/librdkafka/src/rdkafka_cert.c +576 -0
- package/deps/librdkafka/src/rdkafka_cert.h +62 -0
- package/deps/librdkafka/src/rdkafka_cgrp.c +8310 -0
- package/deps/librdkafka/src/rdkafka_cgrp.h +589 -0
- package/deps/librdkafka/src/rdkafka_conf.c +5177 -0
- package/deps/librdkafka/src/rdkafka_conf.h +746 -0
- package/deps/librdkafka/src/rdkafka_confval.h +97 -0
- package/deps/librdkafka/src/rdkafka_coord.c +623 -0
- package/deps/librdkafka/src/rdkafka_coord.h +132 -0
- package/deps/librdkafka/src/rdkafka_error.c +228 -0
- package/deps/librdkafka/src/rdkafka_error.h +80 -0
- package/deps/librdkafka/src/rdkafka_event.c +502 -0
- package/deps/librdkafka/src/rdkafka_event.h +126 -0
- package/deps/librdkafka/src/rdkafka_feature.c +898 -0
- package/deps/librdkafka/src/rdkafka_feature.h +104 -0
- package/deps/librdkafka/src/rdkafka_fetcher.c +3820 -0
- package/deps/librdkafka/src/rdkafka_fetcher.h +62 -0
- package/deps/librdkafka/src/rdkafka_header.c +220 -0
- package/deps/librdkafka/src/rdkafka_header.h +76 -0
- package/deps/librdkafka/src/rdkafka_idempotence.c +807 -0
- package/deps/librdkafka/src/rdkafka_idempotence.h +144 -0
- package/deps/librdkafka/src/rdkafka_int.h +1505 -0
- package/deps/librdkafka/src/rdkafka_interceptor.c +842 -0
- package/deps/librdkafka/src/rdkafka_interceptor.h +104 -0
- package/deps/librdkafka/src/rdkafka_lz4.c +450 -0
- package/deps/librdkafka/src/rdkafka_lz4.h +49 -0
- package/deps/librdkafka/src/rdkafka_metadata.c +2347 -0
- package/deps/librdkafka/src/rdkafka_metadata.h +350 -0
- package/deps/librdkafka/src/rdkafka_metadata_cache.c +1183 -0
- package/deps/librdkafka/src/rdkafka_mock.c +4514 -0
- package/deps/librdkafka/src/rdkafka_mock.h +867 -0
- package/deps/librdkafka/src/rdkafka_mock_cgrp.c +1877 -0
- package/deps/librdkafka/src/rdkafka_mock_handlers.c +5255 -0
- package/deps/librdkafka/src/rdkafka_mock_int.h +1005 -0
- package/deps/librdkafka/src/rdkafka_mock_sharegrp.c +1207 -0
- package/deps/librdkafka/src/rdkafka_msg.c +2619 -0
- package/deps/librdkafka/src/rdkafka_msg.h +629 -0
- package/deps/librdkafka/src/rdkafka_msgbatch.h +62 -0
- package/deps/librdkafka/src/rdkafka_msgset.h +105 -0
- package/deps/librdkafka/src/rdkafka_msgset_reader.c +2099 -0
- package/deps/librdkafka/src/rdkafka_msgset_writer.c +1474 -0
- package/deps/librdkafka/src/rdkafka_offset.c +1565 -0
- package/deps/librdkafka/src/rdkafka_offset.h +150 -0
- package/deps/librdkafka/src/rdkafka_op.c +1219 -0
- package/deps/librdkafka/src/rdkafka_op.h +1065 -0
- package/deps/librdkafka/src/rdkafka_partition.c +5109 -0
- package/deps/librdkafka/src/rdkafka_partition.h +1215 -0
- package/deps/librdkafka/src/rdkafka_pattern.c +228 -0
- package/deps/librdkafka/src/rdkafka_pattern.h +70 -0
- package/deps/librdkafka/src/rdkafka_plugin.c +213 -0
- package/deps/librdkafka/src/rdkafka_plugin.h +41 -0
- package/deps/librdkafka/src/rdkafka_proto.h +739 -0
- package/deps/librdkafka/src/rdkafka_protocol.h +131 -0
- package/deps/librdkafka/src/rdkafka_queue.c +1351 -0
- package/deps/librdkafka/src/rdkafka_queue.h +1235 -0
- package/deps/librdkafka/src/rdkafka_range_assignor.c +1748 -0
- package/deps/librdkafka/src/rdkafka_request.c +7298 -0
- package/deps/librdkafka/src/rdkafka_request.h +761 -0
- package/deps/librdkafka/src/rdkafka_roundrobin_assignor.c +123 -0
- package/deps/librdkafka/src/rdkafka_sasl.c +589 -0
- package/deps/librdkafka/src/rdkafka_sasl.h +63 -0
- package/deps/librdkafka/src/rdkafka_sasl_cyrus.c +722 -0
- package/deps/librdkafka/src/rdkafka_sasl_int.h +89 -0
- package/deps/librdkafka/src/rdkafka_sasl_oauthbearer.c +1833 -0
- package/deps/librdkafka/src/rdkafka_sasl_oauthbearer.h +52 -0
- package/deps/librdkafka/src/rdkafka_sasl_oauthbearer_oidc.c +1827 -0
- package/deps/librdkafka/src/rdkafka_sasl_oauthbearer_oidc.h +52 -0
- package/deps/librdkafka/src/rdkafka_sasl_plain.c +142 -0
- package/deps/librdkafka/src/rdkafka_sasl_scram.c +858 -0
- package/deps/librdkafka/src/rdkafka_sasl_win32.c +550 -0
- package/deps/librdkafka/src/rdkafka_share_acknowledgement.c +1445 -0
- package/deps/librdkafka/src/rdkafka_share_acknowledgement.h +373 -0
- package/deps/librdkafka/src/rdkafka_ssl.c +2235 -0
- package/deps/librdkafka/src/rdkafka_ssl.h +86 -0
- package/deps/librdkafka/src/rdkafka_sticky_assignor.c +4785 -0
- package/deps/librdkafka/src/rdkafka_subscription.c +411 -0
- package/deps/librdkafka/src/rdkafka_telemetry.c +761 -0
- package/deps/librdkafka/src/rdkafka_telemetry.h +52 -0
- package/deps/librdkafka/src/rdkafka_telemetry_decode.c +1307 -0
- package/deps/librdkafka/src/rdkafka_telemetry_decode.h +59 -0
- package/deps/librdkafka/src/rdkafka_telemetry_encode.c +1309 -0
- package/deps/librdkafka/src/rdkafka_telemetry_encode.h +459 -0
- package/deps/librdkafka/src/rdkafka_timer.c +407 -0
- package/deps/librdkafka/src/rdkafka_timer.h +117 -0
- package/deps/librdkafka/src/rdkafka_topic.c +2382 -0
- package/deps/librdkafka/src/rdkafka_topic.h +369 -0
- package/deps/librdkafka/src/rdkafka_transport.c +1309 -0
- package/deps/librdkafka/src/rdkafka_transport.h +99 -0
- package/deps/librdkafka/src/rdkafka_transport_int.h +100 -0
- package/deps/librdkafka/src/rdkafka_txnmgr.c +3256 -0
- package/deps/librdkafka/src/rdkafka_txnmgr.h +171 -0
- package/deps/librdkafka/src/rdkafka_zstd.c +226 -0
- package/deps/librdkafka/src/rdkafka_zstd.h +57 -0
- package/deps/librdkafka/src/rdlist.c +593 -0
- package/deps/librdkafka/src/rdlist.h +444 -0
- package/deps/librdkafka/src/rdlog.c +89 -0
- package/deps/librdkafka/src/rdlog.h +41 -0
- package/deps/librdkafka/src/rdmap.c +508 -0
- package/deps/librdkafka/src/rdmap.h +492 -0
- package/deps/librdkafka/src/rdmurmur2.c +167 -0
- package/deps/librdkafka/src/rdmurmur2.h +35 -0
- package/deps/librdkafka/src/rdports.c +61 -0
- package/deps/librdkafka/src/rdports.h +38 -0
- package/deps/librdkafka/src/rdposix.h +250 -0
- package/deps/librdkafka/src/rdrand.c +151 -0
- package/deps/librdkafka/src/rdrand.h +72 -0
- package/deps/librdkafka/src/rdregex.c +156 -0
- package/deps/librdkafka/src/rdregex.h +43 -0
- package/deps/librdkafka/src/rdsignal.h +57 -0
- package/deps/librdkafka/src/rdstring.c +645 -0
- package/deps/librdkafka/src/rdstring.h +98 -0
- package/deps/librdkafka/src/rdsysqueue.h +404 -0
- package/deps/librdkafka/src/rdtime.h +356 -0
- package/deps/librdkafka/src/rdtypes.h +86 -0
- package/deps/librdkafka/src/rdunittest.c +564 -0
- package/deps/librdkafka/src/rdunittest.h +232 -0
- package/deps/librdkafka/src/rdunittest_acknowledge.c +1177 -0
- package/deps/librdkafka/src/rdunittest_fetcher.c +1211 -0
- package/deps/librdkafka/src/rdunittest_msgset_errors.c +1521 -0
- package/deps/librdkafka/src/rdvarint.c +134 -0
- package/deps/librdkafka/src/rdvarint.h +165 -0
- package/deps/librdkafka/src/rdwin32.h +382 -0
- package/deps/librdkafka/src/rdxxhash.c +1030 -0
- package/deps/librdkafka/src/rdxxhash.h +328 -0
- package/deps/librdkafka/src/regexp.c +1352 -0
- package/deps/librdkafka/src/regexp.h +41 -0
- package/deps/librdkafka/src/snappy.c +1866 -0
- package/deps/librdkafka/src/snappy.h +62 -0
- package/deps/librdkafka/src/snappy_compat.h +138 -0
- package/deps/librdkafka/src/statistics_schema.json +444 -0
- package/deps/librdkafka/src/tinycthread.c +932 -0
- package/deps/librdkafka/src/tinycthread.h +503 -0
- package/deps/librdkafka/src/tinycthread_extra.c +210 -0
- package/deps/librdkafka/src/tinycthread_extra.h +218 -0
- package/deps/librdkafka/src/win32_config.h +58 -0
- package/deps/librdkafka/src-cpp/CMakeLists.txt +90 -0
- package/deps/librdkafka/src-cpp/ConfImpl.cpp +84 -0
- package/deps/librdkafka/src-cpp/ConsumerImpl.cpp +244 -0
- package/deps/librdkafka/src-cpp/HandleImpl.cpp +436 -0
- package/deps/librdkafka/src-cpp/HeadersImpl.cpp +48 -0
- package/deps/librdkafka/src-cpp/KafkaConsumerImpl.cpp +296 -0
- package/deps/librdkafka/src-cpp/Makefile +55 -0
- package/deps/librdkafka/src-cpp/MessageImpl.cpp +38 -0
- package/deps/librdkafka/src-cpp/MetadataImpl.cpp +170 -0
- package/deps/librdkafka/src-cpp/ProducerImpl.cpp +197 -0
- package/deps/librdkafka/src-cpp/QueueImpl.cpp +70 -0
- package/deps/librdkafka/src-cpp/README.md +16 -0
- package/deps/librdkafka/src-cpp/RdKafka.cpp +59 -0
- package/deps/librdkafka/src-cpp/TopicImpl.cpp +124 -0
- package/deps/librdkafka/src-cpp/TopicPartitionImpl.cpp +57 -0
- package/deps/librdkafka/src-cpp/rdkafkacpp.h +3797 -0
- package/deps/librdkafka/src-cpp/rdkafkacpp_int.h +1641 -0
- package/deps/librdkafka/tests/0000-unittests.c +72 -0
- package/deps/librdkafka/tests/0001-multiobj.c +102 -0
- package/deps/librdkafka/tests/0002-unkpart.c +244 -0
- package/deps/librdkafka/tests/0003-msgmaxsize.c +173 -0
- package/deps/librdkafka/tests/0004-conf.c +934 -0
- package/deps/librdkafka/tests/0005-order.c +133 -0
- package/deps/librdkafka/tests/0006-symbols.c +163 -0
- package/deps/librdkafka/tests/0007-autotopic.c +136 -0
- package/deps/librdkafka/tests/0008-reqacks.c +179 -0
- package/deps/librdkafka/tests/0009-mock_cluster.c +272 -0
- package/deps/librdkafka/tests/0011-produce_batch.c +753 -0
- package/deps/librdkafka/tests/0012-produce_consume.c +537 -0
- package/deps/librdkafka/tests/0013-null-msgs.c +473 -0
- package/deps/librdkafka/tests/0014-reconsume-191.c +512 -0
- package/deps/librdkafka/tests/0015-offset_seeks.c +172 -0
- package/deps/librdkafka/tests/0016-client_swname.c +181 -0
- package/deps/librdkafka/tests/0017-compression.c +140 -0
- package/deps/librdkafka/tests/0018-cgrp_term.c +444 -0
- package/deps/librdkafka/tests/0019-list_groups.c +289 -0
- package/deps/librdkafka/tests/0020-destroy_hang.c +162 -0
- package/deps/librdkafka/tests/0021-rkt_destroy.c +72 -0
- package/deps/librdkafka/tests/0022-consume_batch.c +331 -0
- package/deps/librdkafka/tests/0025-timers.c +147 -0
- package/deps/librdkafka/tests/0026-consume_pause.c +547 -0
- package/deps/librdkafka/tests/0028-long_topicnames.c +79 -0
- package/deps/librdkafka/tests/0029-assign_offset.c +202 -0
- package/deps/librdkafka/tests/0030-offset_commit.c +589 -0
- package/deps/librdkafka/tests/0031-get_offsets.c +235 -0
- package/deps/librdkafka/tests/0033-regex_subscribe.c +536 -0
- package/deps/librdkafka/tests/0034-offset_reset.c +398 -0
- package/deps/librdkafka/tests/0035-api_version.c +73 -0
- package/deps/librdkafka/tests/0036-partial_fetch.c +87 -0
- package/deps/librdkafka/tests/0037-destroy_hang_local.c +85 -0
- package/deps/librdkafka/tests/0038-performance.c +121 -0
- package/deps/librdkafka/tests/0039-event.c +284 -0
- package/deps/librdkafka/tests/0040-io_event.c +257 -0
- package/deps/librdkafka/tests/0041-fetch_max_bytes.c +97 -0
- package/deps/librdkafka/tests/0042-many_topics.c +252 -0
- package/deps/librdkafka/tests/0043-no_connection.c +77 -0
- package/deps/librdkafka/tests/0044-partition_cnt.c +94 -0
- package/deps/librdkafka/tests/0045-subscribe_update.c +1010 -0
- package/deps/librdkafka/tests/0046-rkt_cache.c +65 -0
- package/deps/librdkafka/tests/0047-partial_buf_tmout.c +98 -0
- package/deps/librdkafka/tests/0048-partitioner.c +283 -0
- package/deps/librdkafka/tests/0049-consume_conn_close.c +162 -0
- package/deps/librdkafka/tests/0050-subscribe_adds.c +145 -0
- package/deps/librdkafka/tests/0051-assign_adds.c +126 -0
- package/deps/librdkafka/tests/0052-msg_timestamps.c +238 -0
- package/deps/librdkafka/tests/0053-stats_cb.cpp +527 -0
- package/deps/librdkafka/tests/0054-offset_time.cpp +236 -0
- package/deps/librdkafka/tests/0055-producer_latency.c +539 -0
- package/deps/librdkafka/tests/0056-balanced_group_mt.c +315 -0
- package/deps/librdkafka/tests/0057-invalid_topic.cpp +112 -0
- package/deps/librdkafka/tests/0058-log.cpp +123 -0
- package/deps/librdkafka/tests/0059-bsearch.cpp +241 -0
- package/deps/librdkafka/tests/0060-op_prio.cpp +163 -0
- package/deps/librdkafka/tests/0061-consumer_lag.cpp +295 -0
- package/deps/librdkafka/tests/0062-stats_event.c +126 -0
- package/deps/librdkafka/tests/0063-clusterid.cpp +180 -0
- package/deps/librdkafka/tests/0064-interceptors.c +529 -0
- package/deps/librdkafka/tests/0065-yield.cpp +140 -0
- package/deps/librdkafka/tests/0066-plugins.cpp +143 -0
- package/deps/librdkafka/tests/0067-empty_topic.cpp +151 -0
- package/deps/librdkafka/tests/0068-produce_timeout.c +136 -0
- package/deps/librdkafka/tests/0069-consumer_add_parts.c +119 -0
- package/deps/librdkafka/tests/0070-null_empty.cpp +197 -0
- package/deps/librdkafka/tests/0072-headers_ut.c +448 -0
- package/deps/librdkafka/tests/0073-headers.c +381 -0
- package/deps/librdkafka/tests/0074-producev.c +87 -0
- package/deps/librdkafka/tests/0075-retry.c +290 -0
- package/deps/librdkafka/tests/0076-produce_retry.c +452 -0
- package/deps/librdkafka/tests/0077-compaction.c +366 -0
- package/deps/librdkafka/tests/0078-c_from_cpp.cpp +96 -0
- package/deps/librdkafka/tests/0079-fork.c +93 -0
- package/deps/librdkafka/tests/0080-admin_ut.c +3095 -0
- package/deps/librdkafka/tests/0081-admin.c +5633 -0
- package/deps/librdkafka/tests/0082-fetch_max_bytes.cpp +137 -0
- package/deps/librdkafka/tests/0083-cb_event.c +233 -0
- package/deps/librdkafka/tests/0084-destroy_flags.c +208 -0
- package/deps/librdkafka/tests/0085-headers.cpp +392 -0
- package/deps/librdkafka/tests/0086-purge.c +368 -0
- package/deps/librdkafka/tests/0088-produce_metadata_timeout.c +162 -0
- package/deps/librdkafka/tests/0089-max_poll_interval.c +511 -0
- package/deps/librdkafka/tests/0090-idempotence.c +171 -0
- package/deps/librdkafka/tests/0091-max_poll_interval_timeout.c +295 -0
- package/deps/librdkafka/tests/0092-mixed_msgver.c +103 -0
- package/deps/librdkafka/tests/0093-holb.c +200 -0
- package/deps/librdkafka/tests/0094-idempotence_msg_timeout.c +231 -0
- package/deps/librdkafka/tests/0095-all_brokers_down.cpp +122 -0
- package/deps/librdkafka/tests/0097-ssl_verify.cpp +674 -0
- package/deps/librdkafka/tests/0098-consumer-txn.cpp +1218 -0
- package/deps/librdkafka/tests/0099-commit_metadata.c +194 -0
- package/deps/librdkafka/tests/0100-thread_interceptors.cpp +195 -0
- package/deps/librdkafka/tests/0101-fetch-from-follower.cpp +446 -0
- package/deps/librdkafka/tests/0102-static_group_rebalance.c +836 -0
- package/deps/librdkafka/tests/0103-transactions.c +1383 -0
- package/deps/librdkafka/tests/0104-fetch_from_follower_mock.c +625 -0
- package/deps/librdkafka/tests/0105-transactions_mock.c +3930 -0
- package/deps/librdkafka/tests/0106-cgrp_sess_timeout.c +318 -0
- package/deps/librdkafka/tests/0107-topic_recreate.c +259 -0
- package/deps/librdkafka/tests/0109-auto_create_topics.cpp +278 -0
- package/deps/librdkafka/tests/0110-batch_size.cpp +182 -0
- package/deps/librdkafka/tests/0111-delay_create_topics.cpp +127 -0
- package/deps/librdkafka/tests/0112-assign_unknown_part.c +87 -0
- package/deps/librdkafka/tests/0113-cooperative_rebalance.cpp +3473 -0
- package/deps/librdkafka/tests/0114-sticky_partitioning.cpp +176 -0
- package/deps/librdkafka/tests/0115-producer_auth.cpp +182 -0
- package/deps/librdkafka/tests/0116-kafkaconsumer_close.cpp +216 -0
- package/deps/librdkafka/tests/0117-mock_errors.c +331 -0
- package/deps/librdkafka/tests/0118-commit_rebalance.c +154 -0
- package/deps/librdkafka/tests/0119-consumer_auth.cpp +167 -0
- package/deps/librdkafka/tests/0120-asymmetric_subscription.c +185 -0
- package/deps/librdkafka/tests/0121-clusterid.c +115 -0
- package/deps/librdkafka/tests/0122-buffer_cleaning_after_rebalance.c +227 -0
- package/deps/librdkafka/tests/0123-connections_max_idle.c +98 -0
- package/deps/librdkafka/tests/0124-openssl_invalid_engine.c +69 -0
- package/deps/librdkafka/tests/0125-immediate_flush.c +144 -0
- package/deps/librdkafka/tests/0126-oauthbearer_oidc.c +1164 -0
- package/deps/librdkafka/tests/0127-fetch_queue_backoff.cpp +165 -0
- package/deps/librdkafka/tests/0128-sasl_callback_queue.cpp +217 -0
- package/deps/librdkafka/tests/0129-fetch_aborted_msgs.c +79 -0
- package/deps/librdkafka/tests/0130-store_offsets.c +178 -0
- package/deps/librdkafka/tests/0131-connect_timeout.c +81 -0
- package/deps/librdkafka/tests/0132-strategy_ordering.c +179 -0
- package/deps/librdkafka/tests/0133-ssl_keys.c +150 -0
- package/deps/librdkafka/tests/0134-ssl_provider.c +92 -0
- package/deps/librdkafka/tests/0135-sasl_credentials.cpp +279 -0
- package/deps/librdkafka/tests/0136-resolve_cb.c +181 -0
- package/deps/librdkafka/tests/0137-barrier_batch_consume.c +752 -0
- package/deps/librdkafka/tests/0138-admin_mock.c +281 -0
- package/deps/librdkafka/tests/0139-offset_validation_mock.c +950 -0
- package/deps/librdkafka/tests/0140-commit_metadata.cpp +108 -0
- package/deps/librdkafka/tests/0142-reauthentication.c +931 -0
- package/deps/librdkafka/tests/0143-exponential_backoff_mock.c +552 -0
- package/deps/librdkafka/tests/0144-idempotence_mock.c +373 -0
- package/deps/librdkafka/tests/0145-pause_resume_mock.c +119 -0
- package/deps/librdkafka/tests/0146-metadata_mock.c +505 -0
- package/deps/librdkafka/tests/0147-consumer_group_consumer_mock.c +1210 -0
- package/deps/librdkafka/tests/0148-offset_fetch_commit_error_mock.c +569 -0
- package/deps/librdkafka/tests/0149-broker-same-host-port.c +140 -0
- package/deps/librdkafka/tests/0150-telemetry_mock.c +651 -0
- package/deps/librdkafka/tests/0151-purge-brokers.c +566 -0
- package/deps/librdkafka/tests/0152-rebootstrap.c +59 -0
- package/deps/librdkafka/tests/0153-memberid.c +128 -0
- package/deps/librdkafka/tests/0155-share_group_heartbeat_mock.c +2695 -0
- package/deps/librdkafka/tests/0156-share_consumer_fetch_mock.c +1551 -0
- package/deps/librdkafka/tests/0157-share_consumer_ack_mock.c +1788 -0
- package/deps/librdkafka/tests/0158-share_consumer_transactions_mock.c +467 -0
- package/deps/librdkafka/tests/0170-share_consumer_subscription.c +2192 -0
- package/deps/librdkafka/tests/0171-share_consumer_consume.c +2150 -0
- package/deps/librdkafka/tests/0172-share_consumer_acknowledge.c +1919 -0
- package/deps/librdkafka/tests/0173-share_consumer_commit_async.c +2735 -0
- package/deps/librdkafka/tests/0174-share_consumer_concurrency.c +1434 -0
- package/deps/librdkafka/tests/0175-share_consumer_groups.c +574 -0
- package/deps/librdkafka/tests/0176-share_consumer_commit_sync.c +2986 -0
- package/deps/librdkafka/tests/0177-share_consumer_transactions.c +1815 -0
- package/deps/librdkafka/tests/0178-share_consumer_close.c +2102 -0
- package/deps/librdkafka/tests/0179-share_consumer_destroy.c +2482 -0
- package/deps/librdkafka/tests/0180-share_consumer_config.c +1677 -0
- package/deps/librdkafka/tests/0181-share_consumer_topic_delete.c +354 -0
- package/deps/librdkafka/tests/0182-share_consumer_error_handling_mock.c +3358 -0
- package/deps/librdkafka/tests/0183-share_consumer_leader_change_mock.c +1234 -0
- package/deps/librdkafka/tests/0184-share_consumer_topic_recreate.c +1356 -0
- package/deps/librdkafka/tests/0185-share_consumer_max_poll_interval.c +557 -0
- package/deps/librdkafka/tests/0186-share_consumer_fatal_error.c +360 -0
- package/deps/librdkafka/tests/0190-share_consumer_telemetry.c +387 -0
- package/deps/librdkafka/tests/1000-unktopic.c +164 -0
- package/deps/librdkafka/tests/8000-idle.cpp +60 -0
- package/deps/librdkafka/tests/8001-fetch_from_follower_mock_manual.c +113 -0
- package/deps/librdkafka/tests/CMakeLists.txt +193 -0
- package/deps/librdkafka/tests/LibrdkafkaTestApp.py +291 -0
- package/deps/librdkafka/tests/Makefile +182 -0
- package/deps/librdkafka/tests/README.md +514 -0
- package/deps/librdkafka/tests/autotest.sh +33 -0
- package/deps/librdkafka/tests/backtrace.gdb +30 -0
- package/deps/librdkafka/tests/broker_version_tests.py +315 -0
- package/deps/librdkafka/tests/buildbox.sh +17 -0
- package/deps/librdkafka/tests/cleanup-checker-tests.sh +20 -0
- package/deps/librdkafka/tests/cluster_testing.py +203 -0
- package/deps/librdkafka/tests/delete-test-topics.sh +56 -0
- package/deps/librdkafka/tests/fixtures/oauthbearer/jwt_assertion_template.json +10 -0
- package/deps/librdkafka/tests/fixtures/ssl/Makefile +8 -0
- package/deps/librdkafka/tests/fixtures/ssl/README.md +13 -0
- package/deps/librdkafka/tests/fixtures/ssl/client.keystore.intermediate.p12 +0 -0
- package/deps/librdkafka/tests/fixtures/ssl/client.keystore.p12 +0 -0
- package/deps/librdkafka/tests/fixtures/ssl/client2.certificate.intermediate.pem +72 -0
- package/deps/librdkafka/tests/fixtures/ssl/client2.certificate.pem +50 -0
- package/deps/librdkafka/tests/fixtures/ssl/client2.intermediate.key +46 -0
- package/deps/librdkafka/tests/fixtures/ssl/client2.key +46 -0
- package/deps/librdkafka/tests/fixtures/ssl/create_keys.sh +168 -0
- package/deps/librdkafka/tests/fuzzers/Makefile +12 -0
- package/deps/librdkafka/tests/fuzzers/README.md +31 -0
- package/deps/librdkafka/tests/fuzzers/fuzz_regex.c +74 -0
- package/deps/librdkafka/tests/fuzzers/helpers.h +90 -0
- package/deps/librdkafka/tests/gen-ssl-certs.sh +165 -0
- package/deps/librdkafka/tests/interactive_broker_version.py +170 -0
- package/deps/librdkafka/tests/interceptor_test/CMakeLists.txt +16 -0
- package/deps/librdkafka/tests/interceptor_test/Makefile +22 -0
- package/deps/librdkafka/tests/interceptor_test/interceptor_test.c +314 -0
- package/deps/librdkafka/tests/interceptor_test/interceptor_test.h +54 -0
- package/deps/librdkafka/tests/java/IncrementalRebalanceCli.java +97 -0
- package/deps/librdkafka/tests/java/Makefile +13 -0
- package/deps/librdkafka/tests/java/Murmur2Cli.java +46 -0
- package/deps/librdkafka/tests/java/README.md +14 -0
- package/deps/librdkafka/tests/java/TransactionProducerCli.java +162 -0
- package/deps/librdkafka/tests/java/run-class.sh +11 -0
- package/deps/librdkafka/tests/librdkafka.suppressions +483 -0
- package/deps/librdkafka/tests/lz4_manual_test.sh +59 -0
- package/deps/librdkafka/tests/multi-broker-version-test.sh +50 -0
- package/deps/librdkafka/tests/parse-refcnt.sh +43 -0
- package/deps/librdkafka/tests/performance_plot.py +115 -0
- package/deps/librdkafka/tests/plugin_test/Makefile +19 -0
- package/deps/librdkafka/tests/plugin_test/plugin_test.c +58 -0
- package/deps/librdkafka/tests/requirements.txt +2 -0
- package/deps/librdkafka/tests/run-all-tests.sh +81 -0
- package/deps/librdkafka/tests/run-consumer-tests.sh +16 -0
- package/deps/librdkafka/tests/run-producer-tests.sh +16 -0
- package/deps/librdkafka/tests/run-test-batches.py +157 -0
- package/deps/librdkafka/tests/run-test.sh +141 -0
- package/deps/librdkafka/tests/rusage.c +249 -0
- package/deps/librdkafka/tests/sasl_test.py +289 -0
- package/deps/librdkafka/tests/scenarios/README.md +6 -0
- package/deps/librdkafka/tests/scenarios/ak23.json +6 -0
- package/deps/librdkafka/tests/scenarios/default.json +5 -0
- package/deps/librdkafka/tests/scenarios/noautocreate.json +5 -0
- package/deps/librdkafka/tests/share_telemetry_verify/share-otel-collector-config.yaml +28 -0
- package/deps/librdkafka/tests/sockem.c +801 -0
- package/deps/librdkafka/tests/sockem.h +85 -0
- package/deps/librdkafka/tests/sockem_ctrl.c +145 -0
- package/deps/librdkafka/tests/sockem_ctrl.h +61 -0
- package/deps/librdkafka/tests/test.c +8376 -0
- package/deps/librdkafka/tests/test.conf.example +27 -0
- package/deps/librdkafka/tests/test.h +1150 -0
- package/deps/librdkafka/tests/testcpp.cpp +131 -0
- package/deps/librdkafka/tests/testcpp.h +388 -0
- package/deps/librdkafka/tests/testshared.h +416 -0
- package/deps/librdkafka/tests/tools/README.md +4 -0
- package/deps/librdkafka/tests/tools/stats/README.md +21 -0
- package/deps/librdkafka/tests/tools/stats/filter.jq +42 -0
- package/deps/librdkafka/tests/tools/stats/graph.py +150 -0
- package/deps/librdkafka/tests/tools/stats/requirements.txt +3 -0
- package/deps/librdkafka/tests/tools/stats/to_csv.py +124 -0
- package/deps/librdkafka/tests/trivup/trivup-0.15.0.tar.gz +0 -0
- package/deps/librdkafka/tests/until-fail.sh +87 -0
- package/deps/librdkafka/tests/xxxx-assign_partition.c +122 -0
- package/deps/librdkafka/tests/xxxx-metadata.cpp +159 -0
- package/deps/librdkafka/vcpkg.json +23 -0
- package/deps/librdkafka/win32/README.md +5 -0
- package/deps/librdkafka/win32/build-package.bat +3 -0
- package/deps/librdkafka/win32/build.bat +19 -0
- package/deps/librdkafka/win32/common.vcxproj +84 -0
- package/deps/librdkafka/win32/interceptor_test/interceptor_test.vcxproj +87 -0
- package/deps/librdkafka/win32/librdkafka.autopkg.template +54 -0
- package/deps/librdkafka/win32/librdkafka.master.testing.targets +13 -0
- package/deps/librdkafka/win32/librdkafka.sln +226 -0
- package/deps/librdkafka/win32/librdkafka.vcxproj +282 -0
- package/deps/librdkafka/win32/librdkafkacpp/librdkafkacpp.vcxproj +104 -0
- package/deps/librdkafka/win32/msbuild.ps1 +58 -0
- package/deps/librdkafka/win32/openssl_engine_example/openssl_engine_example.vcxproj +132 -0
- package/deps/librdkafka/win32/package-zip.ps1 +46 -0
- package/deps/librdkafka/win32/packages/repositories.config +4 -0
- package/deps/librdkafka/win32/push-package.bat +4 -0
- package/deps/librdkafka/win32/rdkafka_complex_consumer_example_cpp/rdkafka_complex_consumer_example_cpp.vcxproj +67 -0
- package/deps/librdkafka/win32/rdkafka_example/rdkafka_example.vcxproj +97 -0
- package/deps/librdkafka/win32/rdkafka_performance/rdkafka_performance.vcxproj +97 -0
- package/deps/librdkafka/win32/setup-msys2.ps1 +47 -0
- package/deps/librdkafka/win32/setup-vcpkg.ps1 +34 -0
- package/deps/librdkafka/win32/tests/test.conf.example +25 -0
- package/deps/librdkafka/win32/tests/tests.vcxproj +278 -0
- package/deps/librdkafka/win32/win_ssl_cert_store/win_ssl_cert_store.vcxproj +132 -0
- package/deps/librdkafka/win32/wingetopt.c +564 -0
- package/deps/librdkafka/win32/wingetopt.h +101 -0
- package/deps/librdkafka/win32/wintime.h +33 -0
- package/deps/librdkafka.gyp +83 -0
- package/deps/windows-install.py +80 -0
- package/index.d.ts +3 -0
- package/lib/admin.js +732 -0
- package/lib/client.js +679 -0
- package/lib/error.js +501 -0
- package/lib/index.js +8 -0
- package/lib/kafka-consumer-stream.js +399 -0
- package/lib/kafka-consumer.js +798 -0
- package/lib/kafkajs/_admin.js +1052 -0
- package/lib/kafkajs/_common.js +887 -0
- package/lib/kafkajs/_consumer.js +2156 -0
- package/lib/kafkajs/_consumer_cache.js +310 -0
- package/lib/kafkajs/_error.js +298 -0
- package/lib/kafkajs/_kafka.js +125 -0
- package/lib/kafkajs/_linked-list.js +220 -0
- package/lib/kafkajs/_producer.js +863 -0
- package/lib/kafkajs/index.js +5 -0
- package/lib/producer/high-level-producer.js +400 -0
- package/lib/producer-stream.js +337 -0
- package/lib/producer.js +405 -0
- package/lib/rdkafka.js +44 -0
- package/lib/tools/ref-counter.js +53 -0
- package/lib/topic-partition.js +91 -0
- package/lib/topic.js +43 -0
- package/lib/util.js +55 -0
- package/librdkafka.js +12 -0
- package/package.json +85 -0
- package/shim/source_location +54 -0
- package/src/admin.cc +1597 -0
- package/src/admin.h +112 -0
- package/src/binding.cc +76 -0
- package/src/binding.h +25 -0
- package/src/callbacks.cc +676 -0
- package/src/callbacks.h +302 -0
- package/src/common.cc +1628 -0
- package/src/common.h +192 -0
- package/src/config.cc +219 -0
- package/src/config.h +61 -0
- package/src/connection.cc +703 -0
- package/src/connection.h +117 -0
- package/src/errors.cc +119 -0
- package/src/errors.h +60 -0
- package/src/kafka-consumer.cc +1539 -0
- package/src/kafka-consumer.h +147 -0
- package/src/producer.cc +917 -0
- package/src/producer.h +124 -0
- package/src/topic.cc +173 -0
- package/src/topic.h +54 -0
- package/src/workers.cc +1714 -0
- package/src/workers.h +690 -0
- package/types/config.d.ts +1269 -0
- package/types/errors.d.ts +373 -0
- package/types/kafkajs.d.ts +568 -0
- package/types/rdkafka.d.ts +571 -0
- package/util/configure.js +32 -0
- package/util/generate-docs.sh +18 -0
- package/util/get-env.js +6 -0
- package/util/test-compile.js +11 -0
- package/util/test-producer-delivery.js +100 -0
|
@@ -0,0 +1,858 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* librdkafka - The Apache Kafka C/C++ library
|
|
3
|
+
*
|
|
4
|
+
* Copyright (c) 2017-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
|
+
* Builtin SASL SCRAM support when Cyrus SASL is not available
|
|
33
|
+
*/
|
|
34
|
+
#include "rdkafka_int.h"
|
|
35
|
+
#include "rdkafka_transport.h"
|
|
36
|
+
#include "rdkafka_transport_int.h"
|
|
37
|
+
#include "rdkafka_sasl.h"
|
|
38
|
+
#include "rdkafka_sasl_int.h"
|
|
39
|
+
#include "rdrand.h"
|
|
40
|
+
#include "rdunittest.h"
|
|
41
|
+
#include "rdbase64.h"
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
#if WITH_SSL
|
|
45
|
+
#include <openssl/hmac.h>
|
|
46
|
+
#include <openssl/evp.h>
|
|
47
|
+
#include <openssl/sha.h>
|
|
48
|
+
#else
|
|
49
|
+
#error "WITH_SSL (OpenSSL) is required for SASL SCRAM"
|
|
50
|
+
#endif
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* @brief Per-connection state
|
|
55
|
+
*/
|
|
56
|
+
struct rd_kafka_sasl_scram_state {
|
|
57
|
+
enum {
|
|
58
|
+
RD_KAFKA_SASL_SCRAM_STATE_CLIENT_FIRST_MESSAGE,
|
|
59
|
+
RD_KAFKA_SASL_SCRAM_STATE_SERVER_FIRST_MESSAGE,
|
|
60
|
+
RD_KAFKA_SASL_SCRAM_STATE_CLIENT_FINAL_MESSAGE,
|
|
61
|
+
} state;
|
|
62
|
+
rd_chariov_t cnonce; /* client c-nonce */
|
|
63
|
+
rd_chariov_t first_msg_bare; /* client-first-message-bare */
|
|
64
|
+
char *ServerSignatureB64; /* ServerSignature in Base64 */
|
|
65
|
+
const EVP_MD *evp; /* Hash function pointer */
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* @brief Close and free authentication state
|
|
71
|
+
*/
|
|
72
|
+
static void rd_kafka_sasl_scram_close(rd_kafka_transport_t *rktrans) {
|
|
73
|
+
struct rd_kafka_sasl_scram_state *state = rktrans->rktrans_sasl.state;
|
|
74
|
+
|
|
75
|
+
if (!state)
|
|
76
|
+
return;
|
|
77
|
+
|
|
78
|
+
RD_IF_FREE(state->cnonce.ptr, rd_free);
|
|
79
|
+
RD_IF_FREE(state->first_msg_bare.ptr, rd_free);
|
|
80
|
+
RD_IF_FREE(state->ServerSignatureB64, rd_free);
|
|
81
|
+
rd_free(state);
|
|
82
|
+
rktrans->rktrans_sasl.state = NULL;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* @brief Generates a nonce string (a random printable string)
|
|
89
|
+
* @remark dst->ptr will be allocated and must be freed.
|
|
90
|
+
*/
|
|
91
|
+
static void rd_kafka_sasl_scram_generate_nonce(rd_chariov_t *dst) {
|
|
92
|
+
int i;
|
|
93
|
+
dst->size = 32;
|
|
94
|
+
dst->ptr = rd_malloc(dst->size + 1);
|
|
95
|
+
for (i = 0; i < (int)dst->size; i++)
|
|
96
|
+
dst->ptr[i] = (char)rd_jitter(0x2d /*-*/, 0x7e /*~*/);
|
|
97
|
+
dst->ptr[i] = 0;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* @brief Parses inbuf for SCRAM attribute \p attr (e.g., 's')
|
|
103
|
+
* @returns a newly allocated copy of the value, or NULL
|
|
104
|
+
* on failure in which case an error is written to \p errstr
|
|
105
|
+
* prefixed by \p description.
|
|
106
|
+
*/
|
|
107
|
+
static char *rd_kafka_sasl_scram_get_attr(const rd_chariov_t *inbuf,
|
|
108
|
+
char attr,
|
|
109
|
+
const char *description,
|
|
110
|
+
char *errstr,
|
|
111
|
+
size_t errstr_size) {
|
|
112
|
+
size_t of = 0;
|
|
113
|
+
|
|
114
|
+
for (of = 0; of < inbuf->size;) {
|
|
115
|
+
const char *td;
|
|
116
|
+
size_t len;
|
|
117
|
+
|
|
118
|
+
/* Find next delimiter , (if any) */
|
|
119
|
+
td = memchr(&inbuf->ptr[of], ',', inbuf->size - of);
|
|
120
|
+
if (td)
|
|
121
|
+
len = (size_t)(td - &inbuf->ptr[of]);
|
|
122
|
+
else
|
|
123
|
+
len = inbuf->size - of;
|
|
124
|
+
|
|
125
|
+
/* Check if attr "x=" matches */
|
|
126
|
+
if (inbuf->ptr[of] == attr && inbuf->size > of + 1 &&
|
|
127
|
+
inbuf->ptr[of + 1] == '=') {
|
|
128
|
+
char *ret;
|
|
129
|
+
of += 2; /* past = */
|
|
130
|
+
ret = rd_malloc(len - 2 + 1);
|
|
131
|
+
memcpy(ret, &inbuf->ptr[of], len - 2);
|
|
132
|
+
ret[len - 2] = '\0';
|
|
133
|
+
return ret;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
/* Not the attr we are looking for, skip
|
|
137
|
+
* past the next delimiter and continue looking. */
|
|
138
|
+
of += len + 1;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
rd_snprintf(errstr, errstr_size, "%s: could not find attribute (%c)",
|
|
142
|
+
description, attr);
|
|
143
|
+
return NULL;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
|
|
147
|
+
/**
|
|
148
|
+
* @brief Perform H(str) hash function and stores the result in \p out
|
|
149
|
+
* which must be at least EVP_MAX_MD_SIZE.
|
|
150
|
+
* @returns 0 on success, else -1
|
|
151
|
+
*/
|
|
152
|
+
static int rd_kafka_sasl_scram_H(rd_kafka_transport_t *rktrans,
|
|
153
|
+
const rd_chariov_t *str,
|
|
154
|
+
rd_chariov_t *out) {
|
|
155
|
+
|
|
156
|
+
rktrans->rktrans_rkb->rkb_rk->rk_conf.sasl.scram_H(
|
|
157
|
+
(const unsigned char *)str->ptr, str->size,
|
|
158
|
+
(unsigned char *)out->ptr);
|
|
159
|
+
|
|
160
|
+
out->size = rktrans->rktrans_rkb->rkb_rk->rk_conf.sasl.scram_H_size;
|
|
161
|
+
return 0;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
/**
|
|
165
|
+
* @brief Perform HMAC(key,str) and stores the result in \p out
|
|
166
|
+
* which must be at least EVP_MAX_MD_SIZE.
|
|
167
|
+
* @returns 0 on success, else -1
|
|
168
|
+
*/
|
|
169
|
+
static int rd_kafka_sasl_scram_HMAC(rd_kafka_transport_t *rktrans,
|
|
170
|
+
const rd_chariov_t *key,
|
|
171
|
+
const rd_chariov_t *str,
|
|
172
|
+
rd_chariov_t *out) {
|
|
173
|
+
const EVP_MD *evp =
|
|
174
|
+
rktrans->rktrans_rkb->rkb_rk->rk_conf.sasl.scram_evp;
|
|
175
|
+
unsigned int outsize;
|
|
176
|
+
|
|
177
|
+
if (!HMAC(evp, (const unsigned char *)key->ptr, (int)key->size,
|
|
178
|
+
(const unsigned char *)str->ptr, (int)str->size,
|
|
179
|
+
(unsigned char *)out->ptr, &outsize)) {
|
|
180
|
+
rd_rkb_dbg(rktrans->rktrans_rkb, SECURITY, "SCRAM",
|
|
181
|
+
"HMAC failed");
|
|
182
|
+
return -1;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
out->size = outsize;
|
|
186
|
+
|
|
187
|
+
return 0;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
/**
|
|
191
|
+
* @brief Perform \p itcnt iterations of HMAC() on the given buffer \p in
|
|
192
|
+
* using \p salt, writing the output into \p out which must be
|
|
193
|
+
* at least EVP_MAX_MD_SIZE. Actual size is updated in \p *outsize.
|
|
194
|
+
* @returns 0 on success, else -1
|
|
195
|
+
*/
|
|
196
|
+
static int rd_kafka_sasl_scram_Hi(rd_kafka_transport_t *rktrans,
|
|
197
|
+
const rd_chariov_t *in,
|
|
198
|
+
const rd_chariov_t *salt,
|
|
199
|
+
int itcnt,
|
|
200
|
+
rd_chariov_t *out) {
|
|
201
|
+
rd_kafka_broker_t *rkb = rktrans->rktrans_rkb;
|
|
202
|
+
const EVP_MD *evp =
|
|
203
|
+
rktrans->rktrans_rkb->rkb_rk->rk_conf.sasl.scram_evp;
|
|
204
|
+
return rd_kafka_ssl_hmac(rkb, evp, in, salt, itcnt, out);
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
|
|
208
|
+
|
|
209
|
+
/**
|
|
210
|
+
* @returns a SASL value-safe-char encoded string, replacing "," and "="
|
|
211
|
+
* with their escaped counterparts in a newly allocated string.
|
|
212
|
+
*/
|
|
213
|
+
static char *rd_kafka_sasl_safe_string(const char *str) {
|
|
214
|
+
char *safe = NULL, *d = NULL /*avoid warning*/;
|
|
215
|
+
int pass;
|
|
216
|
+
size_t len = 0;
|
|
217
|
+
|
|
218
|
+
/* Pass #1: scan for needed length and allocate.
|
|
219
|
+
* Pass #2: encode string */
|
|
220
|
+
for (pass = 0; pass < 2; pass++) {
|
|
221
|
+
const char *s;
|
|
222
|
+
for (s = str; *s; s++) {
|
|
223
|
+
if (pass == 0) {
|
|
224
|
+
/* If this byte needs to be escaped then
|
|
225
|
+
* 3 output bytes are needed instead of 1. */
|
|
226
|
+
len += (*s == ',' || *s == '=') ? 3 : 1;
|
|
227
|
+
continue;
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
if (*s == ',') {
|
|
231
|
+
*(d++) = '=';
|
|
232
|
+
*(d++) = '2';
|
|
233
|
+
*(d++) = 'C';
|
|
234
|
+
} else if (*s == '=') {
|
|
235
|
+
*(d++) = '=';
|
|
236
|
+
*(d++) = '3';
|
|
237
|
+
*(d++) = 'D';
|
|
238
|
+
} else
|
|
239
|
+
*(d++) = *s;
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
if (pass == 0)
|
|
243
|
+
d = safe = rd_malloc(len + 1);
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
rd_assert(d == safe + (int)len);
|
|
247
|
+
*d = '\0';
|
|
248
|
+
|
|
249
|
+
return safe;
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
|
|
253
|
+
/**
|
|
254
|
+
* @brief Build client-final-message-without-proof
|
|
255
|
+
* @remark out->ptr will be allocated and must be freed.
|
|
256
|
+
*/
|
|
257
|
+
static void
|
|
258
|
+
rd_kafka_sasl_scram_build_client_final_message_wo_proof(const char *snonce,
|
|
259
|
+
rd_chariov_t *out) {
|
|
260
|
+
const char *attr_c = "biws"; /* base64 encode of "n,," */
|
|
261
|
+
|
|
262
|
+
/*
|
|
263
|
+
* client-final-message-without-proof =
|
|
264
|
+
* channel-binding "," nonce [","
|
|
265
|
+
* extensions]
|
|
266
|
+
*/
|
|
267
|
+
out->size = strlen("c=,r=") + strlen(attr_c) + strlen(snonce);
|
|
268
|
+
out->ptr = rd_malloc(out->size + 1);
|
|
269
|
+
rd_snprintf(out->ptr, out->size + 1, "c=%s,r=%s", attr_c, snonce);
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
|
|
273
|
+
/**
|
|
274
|
+
* @brief Build client-final-message
|
|
275
|
+
* @returns -1 on error.
|
|
276
|
+
*/
|
|
277
|
+
static int rd_kafka_sasl_scram_build_client_final_message(
|
|
278
|
+
rd_kafka_transport_t *rktrans,
|
|
279
|
+
const rd_chariov_t *salt,
|
|
280
|
+
const char *server_nonce,
|
|
281
|
+
const rd_chariov_t *server_first_msg,
|
|
282
|
+
int itcnt,
|
|
283
|
+
rd_chariov_t *out) {
|
|
284
|
+
struct rd_kafka_sasl_scram_state *state = rktrans->rktrans_sasl.state;
|
|
285
|
+
rd_kafka_conf_t *conf = &rktrans->rktrans_rkb->rkb_rk->rk_conf;
|
|
286
|
+
rd_chariov_t SaslPassword = RD_ZERO_INIT;
|
|
287
|
+
rd_chariov_t SaltedPassword = {.ptr = rd_alloca(EVP_MAX_MD_SIZE)};
|
|
288
|
+
rd_chariov_t ClientKey = {.ptr = rd_alloca(EVP_MAX_MD_SIZE)};
|
|
289
|
+
rd_chariov_t ServerKey = {.ptr = rd_alloca(EVP_MAX_MD_SIZE)};
|
|
290
|
+
rd_chariov_t StoredKey = {.ptr = rd_alloca(EVP_MAX_MD_SIZE)};
|
|
291
|
+
rd_chariov_t AuthMessage = RD_ZERO_INIT;
|
|
292
|
+
rd_chariov_t ClientSignature = {.ptr = rd_alloca(EVP_MAX_MD_SIZE)};
|
|
293
|
+
rd_chariov_t ServerSignature = {.ptr = rd_alloca(EVP_MAX_MD_SIZE)};
|
|
294
|
+
const rd_chariov_t ClientKeyVerbatim = {.ptr = "Client Key",
|
|
295
|
+
.size = 10};
|
|
296
|
+
const rd_chariov_t ServerKeyVerbatim = {.ptr = "Server Key",
|
|
297
|
+
.size = 10};
|
|
298
|
+
rd_chariov_t ClientProof = {.ptr = rd_alloca(EVP_MAX_MD_SIZE)};
|
|
299
|
+
rd_chariov_t client_final_msg_wo_proof;
|
|
300
|
+
char *ClientProofB64;
|
|
301
|
+
int i;
|
|
302
|
+
|
|
303
|
+
mtx_lock(&conf->sasl.lock);
|
|
304
|
+
rd_strdupa(&SaslPassword.ptr, conf->sasl.password);
|
|
305
|
+
mtx_unlock(&conf->sasl.lock);
|
|
306
|
+
SaslPassword.size = strlen(SaslPassword.ptr);
|
|
307
|
+
|
|
308
|
+
/* Constructing the ClientProof attribute (p):
|
|
309
|
+
*
|
|
310
|
+
* p = Base64-encoded ClientProof
|
|
311
|
+
* SaltedPassword := Hi(Normalize(password), salt, i)
|
|
312
|
+
* ClientKey := HMAC(SaltedPassword, "Client Key")
|
|
313
|
+
* StoredKey := H(ClientKey)
|
|
314
|
+
* AuthMessage := client-first-message-bare + "," +
|
|
315
|
+
* server-first-message + "," +
|
|
316
|
+
* client-final-message-without-proof
|
|
317
|
+
* ClientSignature := HMAC(StoredKey, AuthMessage)
|
|
318
|
+
* ClientProof := ClientKey XOR ClientSignature
|
|
319
|
+
* ServerKey := HMAC(SaltedPassword, "Server Key")
|
|
320
|
+
* ServerSignature := HMAC(ServerKey, AuthMessage)
|
|
321
|
+
*/
|
|
322
|
+
|
|
323
|
+
/* SaltedPassword := Hi(Normalize(password), salt, i) */
|
|
324
|
+
if (rd_kafka_sasl_scram_Hi(rktrans, &SaslPassword, salt, itcnt,
|
|
325
|
+
&SaltedPassword) == -1)
|
|
326
|
+
return -1;
|
|
327
|
+
|
|
328
|
+
/* ClientKey := HMAC(SaltedPassword, "Client Key") */
|
|
329
|
+
if (rd_kafka_sasl_scram_HMAC(rktrans, &SaltedPassword,
|
|
330
|
+
&ClientKeyVerbatim, &ClientKey) == -1)
|
|
331
|
+
return -1;
|
|
332
|
+
|
|
333
|
+
/* StoredKey := H(ClientKey) */
|
|
334
|
+
if (rd_kafka_sasl_scram_H(rktrans, &ClientKey, &StoredKey) == -1)
|
|
335
|
+
return -1;
|
|
336
|
+
|
|
337
|
+
/* client-final-message-without-proof */
|
|
338
|
+
rd_kafka_sasl_scram_build_client_final_message_wo_proof(
|
|
339
|
+
server_nonce, &client_final_msg_wo_proof);
|
|
340
|
+
|
|
341
|
+
/* AuthMessage := client-first-message-bare + "," +
|
|
342
|
+
* server-first-message + "," +
|
|
343
|
+
* client-final-message-without-proof */
|
|
344
|
+
AuthMessage.size = state->first_msg_bare.size + 1 +
|
|
345
|
+
server_first_msg->size + 1 +
|
|
346
|
+
client_final_msg_wo_proof.size;
|
|
347
|
+
AuthMessage.ptr = rd_alloca(AuthMessage.size + 1);
|
|
348
|
+
rd_snprintf(AuthMessage.ptr, AuthMessage.size + 1, "%.*s,%.*s,%.*s",
|
|
349
|
+
(int)state->first_msg_bare.size, state->first_msg_bare.ptr,
|
|
350
|
+
(int)server_first_msg->size, server_first_msg->ptr,
|
|
351
|
+
(int)client_final_msg_wo_proof.size,
|
|
352
|
+
client_final_msg_wo_proof.ptr);
|
|
353
|
+
|
|
354
|
+
/*
|
|
355
|
+
* Calculate ServerSignature for later verification when
|
|
356
|
+
* server-final-message is received.
|
|
357
|
+
*/
|
|
358
|
+
|
|
359
|
+
/* ServerKey := HMAC(SaltedPassword, "Server Key") */
|
|
360
|
+
if (rd_kafka_sasl_scram_HMAC(rktrans, &SaltedPassword,
|
|
361
|
+
&ServerKeyVerbatim, &ServerKey) == -1) {
|
|
362
|
+
rd_free(client_final_msg_wo_proof.ptr);
|
|
363
|
+
return -1;
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
/* ServerSignature := HMAC(ServerKey, AuthMessage) */
|
|
367
|
+
if (rd_kafka_sasl_scram_HMAC(rktrans, &ServerKey, &AuthMessage,
|
|
368
|
+
&ServerSignature) == -1) {
|
|
369
|
+
rd_free(client_final_msg_wo_proof.ptr);
|
|
370
|
+
return -1;
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
/* Store the Base64 encoded ServerSignature for quick comparison */
|
|
374
|
+
state->ServerSignatureB64 = rd_base64_encode_str(&ServerSignature);
|
|
375
|
+
if (state->ServerSignatureB64 == NULL) {
|
|
376
|
+
rd_free(client_final_msg_wo_proof.ptr);
|
|
377
|
+
return -1;
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
/*
|
|
381
|
+
* Continue with client-final-message
|
|
382
|
+
*/
|
|
383
|
+
|
|
384
|
+
/* ClientSignature := HMAC(StoredKey, AuthMessage) */
|
|
385
|
+
if (rd_kafka_sasl_scram_HMAC(rktrans, &StoredKey, &AuthMessage,
|
|
386
|
+
&ClientSignature) == -1) {
|
|
387
|
+
rd_free(client_final_msg_wo_proof.ptr);
|
|
388
|
+
return -1;
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
/* ClientProof := ClientKey XOR ClientSignature */
|
|
392
|
+
assert(ClientKey.size == ClientSignature.size);
|
|
393
|
+
for (i = 0; i < (int)ClientKey.size; i++)
|
|
394
|
+
ClientProof.ptr[i] = ClientKey.ptr[i] ^ ClientSignature.ptr[i];
|
|
395
|
+
ClientProof.size = ClientKey.size;
|
|
396
|
+
|
|
397
|
+
|
|
398
|
+
/* Base64 encoded ClientProof */
|
|
399
|
+
ClientProofB64 = rd_base64_encode_str(&ClientProof);
|
|
400
|
+
if (ClientProofB64 == NULL) {
|
|
401
|
+
rd_free(client_final_msg_wo_proof.ptr);
|
|
402
|
+
return -1;
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
/* Construct client-final-message */
|
|
406
|
+
out->size = client_final_msg_wo_proof.size + strlen(",p=") +
|
|
407
|
+
strlen(ClientProofB64);
|
|
408
|
+
out->ptr = rd_malloc(out->size + 1);
|
|
409
|
+
|
|
410
|
+
rd_snprintf(out->ptr, out->size + 1, "%.*s,p=%s",
|
|
411
|
+
(int)client_final_msg_wo_proof.size,
|
|
412
|
+
client_final_msg_wo_proof.ptr, ClientProofB64);
|
|
413
|
+
rd_free(ClientProofB64);
|
|
414
|
+
rd_free(client_final_msg_wo_proof.ptr);
|
|
415
|
+
|
|
416
|
+
return 0;
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
|
|
420
|
+
/**
|
|
421
|
+
* @brief Handle first message from server
|
|
422
|
+
*
|
|
423
|
+
* Parse server response which looks something like:
|
|
424
|
+
* "r=fyko+d2lbbFgONR....,s=QSXCR+Q6sek8bf92,i=4096"
|
|
425
|
+
*
|
|
426
|
+
* @returns -1 on error.
|
|
427
|
+
*/
|
|
428
|
+
static int
|
|
429
|
+
rd_kafka_sasl_scram_handle_server_first_message(rd_kafka_transport_t *rktrans,
|
|
430
|
+
const rd_chariov_t *in,
|
|
431
|
+
rd_chariov_t *out,
|
|
432
|
+
char *errstr,
|
|
433
|
+
size_t errstr_size) {
|
|
434
|
+
struct rd_kafka_sasl_scram_state *state = rktrans->rktrans_sasl.state;
|
|
435
|
+
char *server_nonce;
|
|
436
|
+
rd_chariov_t salt_b64, salt;
|
|
437
|
+
char *itcntstr;
|
|
438
|
+
const char *endptr;
|
|
439
|
+
int itcnt;
|
|
440
|
+
char *attr_m;
|
|
441
|
+
|
|
442
|
+
/* Mandatory future extension check */
|
|
443
|
+
if ((attr_m = rd_kafka_sasl_scram_get_attr(in, 'm', NULL, NULL, 0))) {
|
|
444
|
+
rd_snprintf(errstr, errstr_size,
|
|
445
|
+
"Unsupported mandatory SCRAM extension");
|
|
446
|
+
rd_free(attr_m);
|
|
447
|
+
return -1;
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
/* Server nonce */
|
|
451
|
+
if (!(server_nonce = rd_kafka_sasl_scram_get_attr(
|
|
452
|
+
in, 'r', "Server nonce in server-first-message", errstr,
|
|
453
|
+
errstr_size)))
|
|
454
|
+
return -1;
|
|
455
|
+
|
|
456
|
+
if (strlen(server_nonce) <= state->cnonce.size ||
|
|
457
|
+
strncmp(state->cnonce.ptr, server_nonce, state->cnonce.size)) {
|
|
458
|
+
rd_snprintf(errstr, errstr_size,
|
|
459
|
+
"Server/client nonce mismatch in "
|
|
460
|
+
"server-first-message");
|
|
461
|
+
rd_free(server_nonce);
|
|
462
|
+
return -1;
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
/* Salt (Base64) */
|
|
466
|
+
if (!(salt_b64.ptr = rd_kafka_sasl_scram_get_attr(
|
|
467
|
+
in, 's', "Salt in server-first-message", errstr,
|
|
468
|
+
errstr_size))) {
|
|
469
|
+
rd_free(server_nonce);
|
|
470
|
+
return -1;
|
|
471
|
+
}
|
|
472
|
+
salt_b64.size = strlen(salt_b64.ptr);
|
|
473
|
+
|
|
474
|
+
/* Convert Salt to binary */
|
|
475
|
+
if (rd_base64_decode(&salt_b64, &salt) == -1) {
|
|
476
|
+
rd_snprintf(errstr, errstr_size,
|
|
477
|
+
"Invalid Base64 Salt in server-first-message");
|
|
478
|
+
rd_free(server_nonce);
|
|
479
|
+
rd_free(salt_b64.ptr);
|
|
480
|
+
return -1;
|
|
481
|
+
}
|
|
482
|
+
rd_free(salt_b64.ptr);
|
|
483
|
+
|
|
484
|
+
/* Iteration count (as string) */
|
|
485
|
+
if (!(itcntstr = rd_kafka_sasl_scram_get_attr(
|
|
486
|
+
in, 'i', "Iteration count in server-first-message", errstr,
|
|
487
|
+
errstr_size))) {
|
|
488
|
+
rd_free(server_nonce);
|
|
489
|
+
rd_free(salt.ptr);
|
|
490
|
+
return -1;
|
|
491
|
+
}
|
|
492
|
+
|
|
493
|
+
/* Iteration count (as int) */
|
|
494
|
+
errno = 0;
|
|
495
|
+
itcnt = (int)strtoul(itcntstr, (char **)&endptr, 10);
|
|
496
|
+
if (itcntstr == endptr || *endptr != '\0' || errno != 0 ||
|
|
497
|
+
itcnt > 1000000) {
|
|
498
|
+
rd_snprintf(errstr, errstr_size,
|
|
499
|
+
"Invalid value (not integer or too large) "
|
|
500
|
+
"for Iteration count in server-first-message");
|
|
501
|
+
rd_free(server_nonce);
|
|
502
|
+
rd_free(salt.ptr);
|
|
503
|
+
rd_free(itcntstr);
|
|
504
|
+
return -1;
|
|
505
|
+
}
|
|
506
|
+
rd_free(itcntstr);
|
|
507
|
+
|
|
508
|
+
/* Build client-final-message */
|
|
509
|
+
if (rd_kafka_sasl_scram_build_client_final_message(
|
|
510
|
+
rktrans, &salt, server_nonce, in, itcnt, out) == -1) {
|
|
511
|
+
rd_snprintf(errstr, errstr_size,
|
|
512
|
+
"Failed to build SCRAM client-final-message");
|
|
513
|
+
rd_free(salt.ptr);
|
|
514
|
+
rd_free(server_nonce);
|
|
515
|
+
return -1;
|
|
516
|
+
}
|
|
517
|
+
|
|
518
|
+
rd_free(server_nonce);
|
|
519
|
+
rd_free(salt.ptr);
|
|
520
|
+
|
|
521
|
+
return 0;
|
|
522
|
+
}
|
|
523
|
+
|
|
524
|
+
/**
|
|
525
|
+
* @brief Handle server-final-message
|
|
526
|
+
*
|
|
527
|
+
* This is the end of authentication and the SCRAM state
|
|
528
|
+
* will be freed at the end of this function regardless of
|
|
529
|
+
* authentication outcome.
|
|
530
|
+
*
|
|
531
|
+
* @returns -1 on failure
|
|
532
|
+
*/
|
|
533
|
+
static int
|
|
534
|
+
rd_kafka_sasl_scram_handle_server_final_message(rd_kafka_transport_t *rktrans,
|
|
535
|
+
const rd_chariov_t *in,
|
|
536
|
+
char *errstr,
|
|
537
|
+
size_t errstr_size) {
|
|
538
|
+
struct rd_kafka_sasl_scram_state *state = rktrans->rktrans_sasl.state;
|
|
539
|
+
char *attr_v, *attr_e;
|
|
540
|
+
|
|
541
|
+
if ((attr_e = rd_kafka_sasl_scram_get_attr(
|
|
542
|
+
in, 'e', "server-error in server-final-message", errstr,
|
|
543
|
+
errstr_size))) {
|
|
544
|
+
/* Authentication failed */
|
|
545
|
+
|
|
546
|
+
rd_snprintf(errstr, errstr_size,
|
|
547
|
+
"SASL SCRAM authentication failed: "
|
|
548
|
+
"broker responded with %s",
|
|
549
|
+
attr_e);
|
|
550
|
+
rd_free(attr_e);
|
|
551
|
+
return -1;
|
|
552
|
+
|
|
553
|
+
} else if ((attr_v = rd_kafka_sasl_scram_get_attr(
|
|
554
|
+
in, 'v', "verifier in server-final-message", errstr,
|
|
555
|
+
errstr_size))) {
|
|
556
|
+
rd_kafka_conf_t *conf;
|
|
557
|
+
|
|
558
|
+
/* Authentication succesful on server,
|
|
559
|
+
* but we need to verify the ServerSignature too. */
|
|
560
|
+
rd_rkb_dbg(rktrans->rktrans_rkb, SECURITY | RD_KAFKA_DBG_BROKER,
|
|
561
|
+
"SCRAMAUTH",
|
|
562
|
+
"SASL SCRAM authentication successful on server: "
|
|
563
|
+
"verifying ServerSignature");
|
|
564
|
+
|
|
565
|
+
if (strcmp(attr_v, state->ServerSignatureB64)) {
|
|
566
|
+
rd_snprintf(errstr, errstr_size,
|
|
567
|
+
"SASL SCRAM authentication failed: "
|
|
568
|
+
"ServerSignature mismatch "
|
|
569
|
+
"(server's %s != ours %s)",
|
|
570
|
+
attr_v, state->ServerSignatureB64);
|
|
571
|
+
rd_free(attr_v);
|
|
572
|
+
return -1;
|
|
573
|
+
}
|
|
574
|
+
rd_free(attr_v);
|
|
575
|
+
|
|
576
|
+
conf = &rktrans->rktrans_rkb->rkb_rk->rk_conf;
|
|
577
|
+
|
|
578
|
+
mtx_lock(&conf->sasl.lock);
|
|
579
|
+
rd_rkb_dbg(rktrans->rktrans_rkb, SECURITY | RD_KAFKA_DBG_BROKER,
|
|
580
|
+
"SCRAMAUTH", "Authenticated as %s using %s",
|
|
581
|
+
conf->sasl.username, conf->sasl.mechanisms);
|
|
582
|
+
mtx_unlock(&conf->sasl.lock);
|
|
583
|
+
|
|
584
|
+
rd_kafka_sasl_auth_done(rktrans);
|
|
585
|
+
return 0;
|
|
586
|
+
|
|
587
|
+
} else {
|
|
588
|
+
rd_snprintf(errstr, errstr_size,
|
|
589
|
+
"SASL SCRAM authentication failed: "
|
|
590
|
+
"no verifier or server-error returned from broker");
|
|
591
|
+
return -1;
|
|
592
|
+
}
|
|
593
|
+
}
|
|
594
|
+
|
|
595
|
+
|
|
596
|
+
|
|
597
|
+
/**
|
|
598
|
+
* @brief Build client-first-message
|
|
599
|
+
*/
|
|
600
|
+
static void
|
|
601
|
+
rd_kafka_sasl_scram_build_client_first_message(rd_kafka_transport_t *rktrans,
|
|
602
|
+
rd_chariov_t *out) {
|
|
603
|
+
char *sasl_username;
|
|
604
|
+
struct rd_kafka_sasl_scram_state *state = rktrans->rktrans_sasl.state;
|
|
605
|
+
rd_kafka_conf_t *conf = &rktrans->rktrans_rkb->rkb_rk->rk_conf;
|
|
606
|
+
|
|
607
|
+
rd_kafka_sasl_scram_generate_nonce(&state->cnonce);
|
|
608
|
+
|
|
609
|
+
mtx_lock(&conf->sasl.lock);
|
|
610
|
+
sasl_username = rd_kafka_sasl_safe_string(conf->sasl.username);
|
|
611
|
+
mtx_unlock(&conf->sasl.lock);
|
|
612
|
+
|
|
613
|
+
out->size =
|
|
614
|
+
strlen("n,,n=,r=") + strlen(sasl_username) + state->cnonce.size;
|
|
615
|
+
out->ptr = rd_malloc(out->size + 1);
|
|
616
|
+
|
|
617
|
+
rd_snprintf(out->ptr, out->size + 1, "n,,n=%s,r=%.*s", sasl_username,
|
|
618
|
+
(int)state->cnonce.size, state->cnonce.ptr);
|
|
619
|
+
rd_free(sasl_username);
|
|
620
|
+
|
|
621
|
+
/* Save client-first-message-bare (skip gs2-header) */
|
|
622
|
+
state->first_msg_bare.size = out->size - 3;
|
|
623
|
+
state->first_msg_bare.ptr =
|
|
624
|
+
rd_memdup(out->ptr + 3, state->first_msg_bare.size);
|
|
625
|
+
}
|
|
626
|
+
|
|
627
|
+
|
|
628
|
+
|
|
629
|
+
/**
|
|
630
|
+
* @brief SASL SCRAM client state machine
|
|
631
|
+
* @returns -1 on failure (errstr set), else 0.
|
|
632
|
+
*/
|
|
633
|
+
static int rd_kafka_sasl_scram_fsm(rd_kafka_transport_t *rktrans,
|
|
634
|
+
const rd_chariov_t *in,
|
|
635
|
+
char *errstr,
|
|
636
|
+
size_t errstr_size) {
|
|
637
|
+
static const char *state_names[] = {
|
|
638
|
+
"client-first-message",
|
|
639
|
+
"server-first-message",
|
|
640
|
+
"client-final-message",
|
|
641
|
+
};
|
|
642
|
+
struct rd_kafka_sasl_scram_state *state = rktrans->rktrans_sasl.state;
|
|
643
|
+
rd_chariov_t out = RD_ZERO_INIT;
|
|
644
|
+
int r = -1;
|
|
645
|
+
rd_ts_t ts_start = rd_clock();
|
|
646
|
+
int prev_state = state->state;
|
|
647
|
+
|
|
648
|
+
rd_rkb_dbg(rktrans->rktrans_rkb, SECURITY, "SASLSCRAM",
|
|
649
|
+
"SASL SCRAM client in state %s", state_names[state->state]);
|
|
650
|
+
|
|
651
|
+
switch (state->state) {
|
|
652
|
+
case RD_KAFKA_SASL_SCRAM_STATE_CLIENT_FIRST_MESSAGE:
|
|
653
|
+
rd_dassert(!in); /* Not expecting any server-input */
|
|
654
|
+
|
|
655
|
+
rd_kafka_sasl_scram_build_client_first_message(rktrans, &out);
|
|
656
|
+
state->state = RD_KAFKA_SASL_SCRAM_STATE_SERVER_FIRST_MESSAGE;
|
|
657
|
+
break;
|
|
658
|
+
|
|
659
|
+
|
|
660
|
+
case RD_KAFKA_SASL_SCRAM_STATE_SERVER_FIRST_MESSAGE:
|
|
661
|
+
rd_dassert(in); /* Requires server-input */
|
|
662
|
+
|
|
663
|
+
if (rd_kafka_sasl_scram_handle_server_first_message(
|
|
664
|
+
rktrans, in, &out, errstr, errstr_size) == -1)
|
|
665
|
+
return -1;
|
|
666
|
+
|
|
667
|
+
state->state = RD_KAFKA_SASL_SCRAM_STATE_CLIENT_FINAL_MESSAGE;
|
|
668
|
+
break;
|
|
669
|
+
|
|
670
|
+
case RD_KAFKA_SASL_SCRAM_STATE_CLIENT_FINAL_MESSAGE:
|
|
671
|
+
rd_dassert(in); /* Requires server-input */
|
|
672
|
+
|
|
673
|
+
r = rd_kafka_sasl_scram_handle_server_final_message(
|
|
674
|
+
rktrans, in, errstr, errstr_size);
|
|
675
|
+
break;
|
|
676
|
+
}
|
|
677
|
+
|
|
678
|
+
if (out.ptr) {
|
|
679
|
+
r = rd_kafka_sasl_send(rktrans, out.ptr, (int)out.size, errstr,
|
|
680
|
+
errstr_size);
|
|
681
|
+
rd_free(out.ptr);
|
|
682
|
+
}
|
|
683
|
+
|
|
684
|
+
ts_start = (rd_clock() - ts_start) / 1000;
|
|
685
|
+
if (ts_start >= 100)
|
|
686
|
+
rd_rkb_dbg(rktrans->rktrans_rkb, SECURITY, "SCRAM",
|
|
687
|
+
"SASL SCRAM state %s handled in %" PRId64 "ms",
|
|
688
|
+
state_names[prev_state], ts_start);
|
|
689
|
+
|
|
690
|
+
|
|
691
|
+
return r;
|
|
692
|
+
}
|
|
693
|
+
|
|
694
|
+
|
|
695
|
+
/**
|
|
696
|
+
* @brief Handle received frame from broker.
|
|
697
|
+
*/
|
|
698
|
+
static int rd_kafka_sasl_scram_recv(rd_kafka_transport_t *rktrans,
|
|
699
|
+
const void *buf,
|
|
700
|
+
size_t size,
|
|
701
|
+
char *errstr,
|
|
702
|
+
size_t errstr_size) {
|
|
703
|
+
const rd_chariov_t in = {.ptr = (char *)buf, .size = size};
|
|
704
|
+
return rd_kafka_sasl_scram_fsm(rktrans, &in, errstr, errstr_size);
|
|
705
|
+
}
|
|
706
|
+
|
|
707
|
+
|
|
708
|
+
/**
|
|
709
|
+
* @brief Initialize and start SASL SCRAM (builtin) authentication.
|
|
710
|
+
*
|
|
711
|
+
* Returns 0 on successful init and -1 on error.
|
|
712
|
+
*
|
|
713
|
+
* @locality broker thread
|
|
714
|
+
*/
|
|
715
|
+
static int rd_kafka_sasl_scram_client_new(rd_kafka_transport_t *rktrans,
|
|
716
|
+
const char *hostname,
|
|
717
|
+
char *errstr,
|
|
718
|
+
size_t errstr_size) {
|
|
719
|
+
struct rd_kafka_sasl_scram_state *state;
|
|
720
|
+
|
|
721
|
+
state = rd_calloc(1, sizeof(*state));
|
|
722
|
+
state->state = RD_KAFKA_SASL_SCRAM_STATE_CLIENT_FIRST_MESSAGE;
|
|
723
|
+
rktrans->rktrans_sasl.state = state;
|
|
724
|
+
|
|
725
|
+
/* Kick off the FSM */
|
|
726
|
+
return rd_kafka_sasl_scram_fsm(rktrans, NULL, errstr, errstr_size);
|
|
727
|
+
}
|
|
728
|
+
|
|
729
|
+
|
|
730
|
+
|
|
731
|
+
/**
|
|
732
|
+
* @brief Validate SCRAM config and look up the hash function
|
|
733
|
+
*/
|
|
734
|
+
static int rd_kafka_sasl_scram_conf_validate(rd_kafka_t *rk,
|
|
735
|
+
char *errstr,
|
|
736
|
+
size_t errstr_size) {
|
|
737
|
+
const char *mech = rk->rk_conf.sasl.mechanisms;
|
|
738
|
+
rd_bool_t both_set;
|
|
739
|
+
|
|
740
|
+
mtx_lock(&rk->rk_conf.sasl.lock);
|
|
741
|
+
both_set = rk->rk_conf.sasl.username && rk->rk_conf.sasl.password;
|
|
742
|
+
mtx_unlock(&rk->rk_conf.sasl.lock);
|
|
743
|
+
|
|
744
|
+
if (!both_set) {
|
|
745
|
+
rd_snprintf(errstr, errstr_size,
|
|
746
|
+
"sasl.username and sasl.password must be set");
|
|
747
|
+
return -1;
|
|
748
|
+
}
|
|
749
|
+
|
|
750
|
+
if (!strcmp(mech, "SCRAM-SHA-1")) {
|
|
751
|
+
rk->rk_conf.sasl.scram_evp = EVP_sha1();
|
|
752
|
+
rk->rk_conf.sasl.scram_H = SHA1;
|
|
753
|
+
rk->rk_conf.sasl.scram_H_size = SHA_DIGEST_LENGTH;
|
|
754
|
+
} else if (!strcmp(mech, "SCRAM-SHA-256")) {
|
|
755
|
+
rk->rk_conf.sasl.scram_evp = EVP_sha256();
|
|
756
|
+
rk->rk_conf.sasl.scram_H = SHA256;
|
|
757
|
+
rk->rk_conf.sasl.scram_H_size = SHA256_DIGEST_LENGTH;
|
|
758
|
+
} else if (!strcmp(mech, "SCRAM-SHA-512")) {
|
|
759
|
+
rk->rk_conf.sasl.scram_evp = EVP_sha512();
|
|
760
|
+
rk->rk_conf.sasl.scram_H = SHA512;
|
|
761
|
+
rk->rk_conf.sasl.scram_H_size = SHA512_DIGEST_LENGTH;
|
|
762
|
+
} else {
|
|
763
|
+
rd_snprintf(errstr, errstr_size,
|
|
764
|
+
"Unsupported hash function: %s "
|
|
765
|
+
"(try SCRAM-SHA-512)",
|
|
766
|
+
mech);
|
|
767
|
+
return -1;
|
|
768
|
+
}
|
|
769
|
+
|
|
770
|
+
return 0;
|
|
771
|
+
}
|
|
772
|
+
|
|
773
|
+
|
|
774
|
+
|
|
775
|
+
const struct rd_kafka_sasl_provider rd_kafka_sasl_scram_provider = {
|
|
776
|
+
.name = "SCRAM (builtin)",
|
|
777
|
+
.client_new = rd_kafka_sasl_scram_client_new,
|
|
778
|
+
.recv = rd_kafka_sasl_scram_recv,
|
|
779
|
+
.close = rd_kafka_sasl_scram_close,
|
|
780
|
+
.conf_validate = rd_kafka_sasl_scram_conf_validate,
|
|
781
|
+
};
|
|
782
|
+
|
|
783
|
+
|
|
784
|
+
|
|
785
|
+
/**
|
|
786
|
+
* @name Unit tests
|
|
787
|
+
*/
|
|
788
|
+
|
|
789
|
+
/**
|
|
790
|
+
* @brief Verify that a random nonce is generated.
|
|
791
|
+
*/
|
|
792
|
+
static int unittest_scram_nonce(void) {
|
|
793
|
+
rd_chariov_t out1 = RD_ZERO_INIT;
|
|
794
|
+
rd_chariov_t out2 = RD_ZERO_INIT;
|
|
795
|
+
|
|
796
|
+
rd_kafka_sasl_scram_generate_nonce(&out1);
|
|
797
|
+
RD_UT_ASSERT(out1.size == 32, "Wrong size %d", (int)out1.size);
|
|
798
|
+
|
|
799
|
+
rd_kafka_sasl_scram_generate_nonce(&out2);
|
|
800
|
+
RD_UT_ASSERT(out1.size == 32, "Wrong size %d", (int)out2.size);
|
|
801
|
+
|
|
802
|
+
RD_UT_ASSERT(memcmp(out1.ptr, out2.ptr, out1.size) != 0,
|
|
803
|
+
"Expected generate_nonce() to return a random nonce");
|
|
804
|
+
|
|
805
|
+
rd_free(out1.ptr);
|
|
806
|
+
rd_free(out2.ptr);
|
|
807
|
+
|
|
808
|
+
RD_UT_PASS();
|
|
809
|
+
}
|
|
810
|
+
|
|
811
|
+
|
|
812
|
+
/**
|
|
813
|
+
* @brief Verify that the safe string function does not overwrite memory.
|
|
814
|
+
* Needs to be run with ASAN (which is done in release-tests) for
|
|
815
|
+
* proper verification.
|
|
816
|
+
*/
|
|
817
|
+
static int unittest_scram_safe(void) {
|
|
818
|
+
const char *inout[] = {
|
|
819
|
+
"just a string",
|
|
820
|
+
"just a string",
|
|
821
|
+
|
|
822
|
+
"another,one,that,needs=escaping!",
|
|
823
|
+
"another=2Cone=2Cthat=2Cneeds=3Descaping!",
|
|
824
|
+
|
|
825
|
+
"overflow?============================",
|
|
826
|
+
"overflow?=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D"
|
|
827
|
+
"=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D",
|
|
828
|
+
|
|
829
|
+
"=3D=3D=3D the mind boggles",
|
|
830
|
+
"=3D3D=3D3D=3D3D the mind boggles",
|
|
831
|
+
|
|
832
|
+
NULL,
|
|
833
|
+
NULL};
|
|
834
|
+
int i;
|
|
835
|
+
|
|
836
|
+
for (i = 0; inout[i]; i += 2) {
|
|
837
|
+
char *out = rd_kafka_sasl_safe_string(inout[i]);
|
|
838
|
+
const char *expected = inout[i + 1];
|
|
839
|
+
|
|
840
|
+
RD_UT_ASSERT(!strcmp(out, expected),
|
|
841
|
+
"Expected sasl_safe_string(%s) => %s, not %s\n",
|
|
842
|
+
inout[i], expected, out);
|
|
843
|
+
|
|
844
|
+
rd_free(out);
|
|
845
|
+
}
|
|
846
|
+
|
|
847
|
+
RD_UT_PASS();
|
|
848
|
+
}
|
|
849
|
+
|
|
850
|
+
|
|
851
|
+
int unittest_scram(void) {
|
|
852
|
+
int fails = 0;
|
|
853
|
+
|
|
854
|
+
fails += unittest_scram_nonce();
|
|
855
|
+
fails += unittest_scram_safe();
|
|
856
|
+
|
|
857
|
+
return fails;
|
|
858
|
+
}
|