/** * TCP connection established. * Set up socket options, SSL, etc. * * Locality: broker thread */ static void rd_kafka_transport_connected (rd_kafka_transport_t *rktrans) { rd_kafka_broker_t *rkb = rktrans->rktrans_rkb; rd_rkb_dbg(rkb, BROKER, "CONNECT", "Connected to %s", rd_sockaddr2str(rkb->rkb_addr_last, RD_SOCKADDR2STR_F_PORT | RD_SOCKADDR2STR_F_FAMILY)); /* Set socket send & receive buffer sizes if configuerd */ if (rkb->rkb_rk->rk_conf.socket_sndbuf_size != 0) { if (setsockopt(rktrans->rktrans_s, SOL_SOCKET, SO_SNDBUF, (void *)&rkb->rkb_rk->rk_conf.socket_sndbuf_size, sizeof(rkb->rkb_rk->rk_conf. socket_sndbuf_size)) == SOCKET_ERROR) rd_rkb_log(rkb, LOG_WARNING, "SNDBUF", "Failed to set socket send " "buffer size to %i: %s", rkb->rkb_rk->rk_conf.socket_sndbuf_size, socket_strerror(socket_errno)); } if (rkb->rkb_rk->rk_conf.socket_rcvbuf_size != 0) { if (setsockopt(rktrans->rktrans_s, SOL_SOCKET, SO_RCVBUF, (void *)&rkb->rkb_rk->rk_conf.socket_rcvbuf_size, sizeof(rkb->rkb_rk->rk_conf. socket_rcvbuf_size)) == SOCKET_ERROR) rd_rkb_log(rkb, LOG_WARNING, "RCVBUF", "Failed to set socket receive " "buffer size to %i: %s", rkb->rkb_rk->rk_conf.socket_rcvbuf_size, socket_strerror(socket_errno)); } #if WITH_SSL if (rkb->rkb_proto == RD_KAFKA_PROTO_SSL || rkb->rkb_proto == RD_KAFKA_PROTO_SASL_SSL) { char errstr[512]; /* Set up SSL connection. * This is also an asynchronous operation so dont * propagate to broker_connect_done() just yet. */ if (rd_kafka_transport_ssl_connect(rkb, rktrans, errstr, sizeof(errstr)) == -1) { rd_kafka_transport_connect_done(rktrans, errstr); return; } return; } #endif /* Propagate connect success */ rd_kafka_transport_connect_done(rktrans, NULL); }
/** * Execute kinit to refresh ticket. * * Returns 0 on success, -1 on error. * * Locality: any */ static int rd_kafka_sasl_kinit_refresh (rd_kafka_broker_t *rkb) { rd_kafka_t *rk = rkb->rkb_rk; int r; char *cmd; char errstr[128]; if (!rk->rk_conf.sasl.kinit_cmd || !strstr(rk->rk_conf.sasl.mechanisms, "GSSAPI")) return 0; /* kinit not configured */ /* Build kinit refresh command line using string rendering and config */ cmd = rd_string_render(rk->rk_conf.sasl.kinit_cmd, errstr, sizeof(errstr), render_callback, rkb); if (!cmd) { rd_rkb_log(rkb, LOG_ERR, "SASLREFRESH", "Failed to construct kinit command " "from sasl.kerberos.kinit.cmd template: %s", errstr); return -1; } /* Execute kinit */ rd_rkb_dbg(rkb, SECURITY, "SASLREFRESH", "Refreshing SASL keys with command: %s", cmd); mtx_lock(&rd_kafka_sasl_kinit_lock); r = system(cmd); mtx_unlock(&rd_kafka_sasl_kinit_lock); if (r == -1) { rd_rkb_log(rkb, LOG_ERR, "SASLREFRESH", "SASL key refresh failed: Failed to execute %s", cmd); rd_free(cmd); return -1; } else if (WIFSIGNALED(r)) { rd_rkb_log(rkb, LOG_ERR, "SASLREFRESH", "SASL key refresh failed: %s: received signal %d", cmd, WTERMSIG(r)); rd_free(cmd); return -1; } else if (WIFEXITED(r) && WEXITSTATUS(r) != 0) { rd_rkb_log(rkb, LOG_ERR, "SASLREFRESH", "SASL key refresh failed: %s: exited with code %d", cmd, WEXITSTATUS(r)); rd_free(cmd); return -1; } rd_free(cmd); rd_rkb_dbg(rkb, SECURITY, "SASLREFRESH", "SASL key refreshed"); return 0; }
/** * Serves the entire OpenSSL error queue and logs each error. * The last error is not logged but returned in 'errstr'. * * If 'rkb' is non-NULL broker-specific logging will be used, * else it will fall back on global 'rk' debugging. */ static char *rd_kafka_ssl_error (rd_kafka_t *rk, rd_kafka_broker_t *rkb, char *errstr, size_t errstr_size) { unsigned long l; const char *file, *data; int line, flags; int cnt = 0; while ((l = ERR_get_error_line_data(&file, &line, &data, &flags)) != 0) { char buf[256]; if (cnt++ > 0) { /* Log last message */ if (rkb) rd_rkb_log(rkb, LOG_ERR, "SSL", "%s", errstr); else rd_kafka_log(rk, LOG_ERR, "SSL", "%s", errstr); } ERR_error_string_n(l, buf, sizeof(buf)); rd_snprintf(errstr, errstr_size, "%s:%d: %s: %s", file, line, buf, (flags & ERR_TXT_STRING) ? data : ""); } if (cnt == 0) rd_snprintf(errstr, errstr_size, "No error"); return errstr; }
static int rd_kafka_sasl_cb_log (void *context, int level, const char *message){ rd_kafka_transport_t *rktrans = context; if (level >= LOG_DEBUG) rd_rkb_dbg(rktrans->rktrans_rkb, SECURITY, "LIBSASL", "%s", message); else rd_rkb_log(rktrans->rktrans_rkb, level, "LIBSASL", "%s", message); return SASL_OK; }