Example #1
0
static void emc_server_accept_cb (struct ev_loop *loop, ev_io *w, int revents)
{
	struct emc_tls_server_context *ctx;
	struct sockaddr_storage sockaddr;
	struct sockaddr_in *sockaddr4 = (struct sockaddr_in *) &sockaddr;
	struct sockaddr_in6 *sockaddr6 = (struct sockaddr_in6 *) &sockaddr;
	struct in6_addr addr;
	unsigned int len_inet = sizeof sockaddr;
	nussl_session *nussl_sess;
	int socket;
	int sport;
	char address[INET6_ADDRSTRLEN];
	struct emc_client_context *client_ctx = NULL;

	ctx = w->data;

	nussl_sess = nussl_session_accept(ctx->nussl);
	if (nussl_sess == NULL) {
		log_printf(DEBUG_LEVEL_WARNING, "Error while accepting new connection: %s",
				nussl_get_error(ctx->nussl));
		return;
	}

	if (nussl_session_getpeer(nussl_sess, (struct sockaddr *) &sockaddr, &len_inet) != NUSSL_OK)
	{
		log_printf(DEBUG_LEVEL_WARNING, "WARNING New client connection failed during nussl_session_getpeer(): %s", nussl_get_error(ctx->nussl));
		free(nussl_sess);
		return;
	}

	socket = nussl_session_get_fd(nussl_sess);

	/* Extract client address (convert it to IPv6 if it's IPv4) */
	if (sockaddr6->sin6_family == AF_INET) {
		ipv4_to_ipv6(sockaddr4->sin_addr, &addr);
		sport = ntohs(sockaddr4->sin_port);
	} else {
		addr = sockaddr6->sin6_addr;
		sport = ntohs(sockaddr6->sin6_port);
	}

	format_ipv6(&addr, address, sizeof(address), NULL);
	log_printf(DEBUG_LEVEL_DEBUG, "DEBUG emc: user connection attempt from %s",
			address);

	client_ctx = malloc(sizeof(struct emc_client_context));
	client_ctx->nussl = nussl_sess;
	strncpy(client_ctx->address, address, sizeof(client_ctx->address));
	client_ctx->tls_server_ctx = ctx;
	client_ctx->state = EMC_CLIENT_STATE_HANDSHAKE;

	g_thread_pool_push(server_ctx->pool_tls_handshake, client_ctx, NULL);

}
Example #2
0
struct in6_addr*ipv6_inet_pton(char*ipstring){
	if(ipstring==NULL)return NULL;
	struct in6_addr*ip=malloc(sizeof(struct in6_addr));//IP-Adresse
	if(!inet_pton(AF_INET6,ipstring,ip)){
		//Es handelt sich nicht um eine IPv6 Adresse!
		struct in_addr ipv4;//Fuer Konvertierung notwendig
		if(!inet_pton(AF_INET,ipstring,&ipv4)){
			//Es handelt sich nicht um eine IPv4 Adresse!
			//Adresse kann nicht konvertiert werden!
			free(ip);
			//parseerrorcounter++;//Fehlerzaehler korrigiert
			return NULL;
		}
		//Wird konvertiert
		ipv4_to_ipv6(&ipv4,ip);
	}
	return ip;
}
Example #3
0
/**
 * Function called on new client connection:
 *    - Call accept()
 *    - Drop client if there are to much clients or if NuAuth is in reload
 *    - Create a client_connection structure
 *    - Add client to ::pre_client_list
 *    - Add client to ::tls_sasl_worker queue (see sasl_worker())
 *
 * \return If an error occurs returns 1, else returns 0.
 */
int tls_user_accept(struct tls_user_context_t *context)
{
    struct sockaddr_storage sockaddr;
    struct sockaddr_in *sockaddr4 = (struct sockaddr_in *) &sockaddr;
    struct sockaddr_in6 *sockaddr6 = (struct sockaddr_in6 *) &sockaddr;
    struct in6_addr addr;
    unsigned int len_inet = sizeof sockaddr;
    struct client_connection *current_client_conn;
    struct pre_client_elt *new_pre_client;
    int socket;
    gint option_value;
    unsigned short sport;
    char address[INET6_ADDRSTRLEN];

    current_client_conn = g_new0(struct client_connection, 1);

    current_client_conn->nussl = nussl_session_accept(context->nussl);
    if ( ! current_client_conn->nussl ) {
        /* can be triggered by EAGAIN on non blocking accept socket */
        g_free(current_client_conn);
        return 1;
    }

    if (nussl_session_getpeer(current_client_conn->nussl, (struct sockaddr *) &sockaddr, &len_inet) != NUSSL_OK)
    {
        log_message(WARNING, DEBUG_AREA_MAIN | DEBUG_AREA_USER,
                    "New client connection failed during nussl_session_getpeer(): %s", nussl_get_error(context->nussl));
        g_free(current_client_conn);
        return 1;
    }

    socket = nussl_session_get_fd(current_client_conn->nussl);

    /* if system is in reload: drop new client */
    if (nuauthdatas->need_reload) {
        shutdown(socket, SHUT_RDWR);
        close(socket);
        return 0;
    }

    /* Extract client address (convert it to IPv6 if it's IPv4) */
    /* if (sockaddr.ss_family == AF_INET) { -> same as tls_nufw.c */
    if (sockaddr6->sin6_family == AF_INET) {
        ipv4_to_ipv6(sockaddr4->sin_addr, &addr);
        sport = ntohs(sockaddr4->sin_port);
    } else {
        addr = sockaddr6->sin6_addr;
        sport = ntohs(sockaddr6->sin6_port);
    }

    format_ipv6(&addr, address, sizeof(address), NULL);
    log_message(DEBUG, DEBUG_AREA_MAIN | DEBUG_AREA_USER,
                "nuauth: user connection attempt from %s\n",
                address);

    if (get_number_of_clients() >= context->nuauth_tls_max_clients) {
        log_message(WARNING, DEBUG_AREA_MAIN | DEBUG_AREA_USER,
                    "too many clients (%d configured)",
                    context->nuauth_tls_max_clients);
        shutdown(socket, SHUT_RDWR);
        close(socket);
        return 1;
    }

    current_client_conn->socket = socket;
    current_client_conn->addr = addr;
    current_client_conn->sport = sport;
    current_client_conn->str_addr = g_strdup(address);
    current_client_conn->srv_context = context;

    /* Set KEEP ALIVE on connection */
    option_value = 1;
    setsockopt(socket,
               SOL_SOCKET, SO_KEEPALIVE,
               &option_value, sizeof(option_value));

    /* give the connection to a separate thread */
    /*  add element to pre_client
       create pre_client_elt */
    new_pre_client = g_new0(struct pre_client_elt, 1);
    new_pre_client->socket = socket;
    new_pre_client->validity =
        time(NULL) + context->nuauth_auth_nego_timeout;

    g_static_mutex_lock(&pre_client_list_mutex);
    pre_client_list = g_slist_prepend(pre_client_list, new_pre_client);
    g_static_mutex_unlock(&pre_client_list_mutex);

    thread_pool_push(nuauthdatas->tls_sasl_worker,
                     current_client_conn, NULL);
    return 0;
}