예제 #1
0
/**
 * 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);
}
예제 #2
0
/**
 * 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;
}
예제 #3
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;
}
예제 #4
0
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;
}