コード例 #1
0
ファイル: repeater.c プロジェクト: iRaveren/rdr2netflow
int rdr_repeater_step(struct rdr_repeater_ctx_t *ctx, fd_set *readfds, fd_set *writefds)
{
   struct endpoint_t *ep;

   assert(ctx);
   assert(readfds);
   assert(writefds);

   for (ep = ctx->head; ep != NULL; ep = ep->next) {
      switch (ep->status) {
	 case S_CONNECTING:
	    assert(ep->s >= 0);

	    if (!FD_ISSET(ep->s, writefds))
	       break;

	    /* Socket ready for writing */
	    if (finish_socket_opening(ctx, ep) < 0) {
	       try_reopen_socket(ctx, ep);
	    }
	    break;
	 case S_WRITING:
	    assert(ep->s >= 0);

	    if (FD_ISSET(ep->s, readfds)) {
	       ssize_t rcvd;
	       unsigned char buf[1];
	       tcflush(ep->s, TCIFLUSH);
	       rcvd = read(ep->s, &buf, 1);
	       if (rcvd == 0) {
		  if (ctx->verbose)
		     fprintf(stderr, "%s Connection %s closed \n", TAG, get_endpoint_name(ep));
		  try_reopen_socket(ctx, ep);
		  break;
	       }else if (rcvd < 0) {
		  if (errno != EAGAIN && (errno != EINTR)) {
		     if (ctx->verbose)
			fprintf(stderr, "%s %s read() error: %s\n", TAG, get_endpoint_name(ep), strerror(errno));
		     try_reopen_socket(ctx, ep);
		     break;
		  }
	       }
	    }

	    if (FD_ISSET(ep->s, writefds))
	       buffered_write(ctx, ep, NULL, 0);
	    break;
	 case S_WAITING:
	    try_reopen_socket(ctx, ep);
	    break;
	 case S_NOT_INITIALIZED:
	 default:
	    /* UNREACHABLE  */
	    assert(0);
	    break;
      }
   }

   return 1;
}
コード例 #2
0
ファイル: repeater.c プロジェクト: iRaveren/rdr2netflow
static int finish_socket_opening(struct rdr_repeater_ctx_t *ctx, struct endpoint_t *ep)
{
   socklen_t peer_name_len;
   struct sockaddr_storage peer_name;

   assert(ctx);
   assert(ep);
   assert(ep->status == S_CONNECTING);

   /* Socket ready for writing */
   peer_name_len=sizeof(peer_name);
   if (getpeername(ep->s, (struct sockaddr *)&peer_name, &peer_name_len) < 0) {
      int error;
      socklen_t error_len;

      error_len = sizeof(error);
      error = 0;
      if (errno == ENOTCONN) {
	 if (getsockopt(ep->s, SOL_SOCKET, SO_ERROR, &error, &error_len) < 0)
	    error = errno;
      }else
	 error = errno;
      if (ctx->verbose > 1)
	 fprintf(stderr, "%s connect(%s) error: %s\n", TAG, get_endpoint_name(ep), strerror(error));
      return -1;
   }else {
      if (ctx->verbose)
	 fprintf(stderr, "%s connection with %s established successfully\n", TAG, get_endpoint_name(ep));
      ep->status = S_WRITING;
   }

   return 1;
}
コード例 #3
0
void web_server::run(void)
{
	pthread_attr_t attr;

	pthread_check(pthread_attr_init(&attr), "pthread_attr_init");
	pthread_check(pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED), "pthread_attr_setdetachstate");

	for(;;)
	{
		int client_fd = accept(fd, NULL, NULL);

		if (client_fd == -1)
		{
			dolog(LOG_INFO, "web_server: accept failed: %s", strerror(errno));

			continue;
		}

		std::string host = get_endpoint_name(client_fd);

		dolog(LOG_INFO, "web_server: connected with %s", host.c_str());

		http_client_t *p_client = new http_client_t;
		p_client -> p_server = this;
		p_client -> fd = client_fd;

		pthread_t thread;
		pthread_check(pthread_create(&thread, &attr, thread_wrapper_http_server, reinterpret_cast<void *>(p_client)), "pthread_create");
	}
}
コード例 #4
0
ファイル: repeater.c プロジェクト: iRaveren/rdr2netflow
int rdr_repeater_init_connection(struct rdr_repeater_ctx_t *ctx, unsigned socket_buf_size, int verbose)
{
   struct endpoint_t *ep;

   assert(ctx);

   ctx->s_bufsize = socket_buf_size;
   ctx->verbose = verbose;

   if (ctx->verbose && (ctx->head != NULL)) {
      fprintf(stderr, "Repeat all incoming TCP packets to hosts: ");
      for (ep = ctx->head; ep != NULL; ep = ep->next) {
	 fprintf(stderr, "%s%s", get_endpoint_name(ep), ep->next == NULL ? "\n" : ", ");
      }
   }

   for (ep = ctx->head; ep != NULL; ep = ep->next) {
      purge_buffer(ep);
      try_reopen_socket(ctx, ep);
      assert(ep->status != S_NOT_INITIALIZED);
   }

   return 1;
}
コード例 #5
0
ファイル: repeater.c プロジェクト: iRaveren/rdr2netflow
static int buffered_write(struct rdr_repeater_ctx_t *ctx, struct endpoint_t *ep,
      void *data, size_t data_size)
{
   ssize_t written;

   assert(ctx);
   assert(ep);

   /* TODO useless memory move */
   if (data != NULL) {
      /* Append data */
      if (sizeof(ep->buf) < data_size) {
	 if (ctx->verbose >= 10)
	    fprintf(stderr, "%s %s Buffer overflow. %u bytes packet skipped\n",
		  TAG, get_endpoint_name(ep), (unsigned)data_size);
	 return 0;
      }

      if (sizeof(ep->buf) - ep->iptr < data_size) {
	 if (sizeof(ep->buf) - ep->iptr + ep->optr >= data_size) {
	    memmove(ep->buf, &ep->buf[ep->optr], ep->iptr - ep->optr);
	    ep->iptr -= ep->optr;
	    ep->optr = 0;
	 }else {
	    if (ctx->verbose >= 10)
	       fprintf(stderr, "%s %s Buffer overflow. %u bytes skipped\n",
		     TAG, get_endpoint_name(ep), ep->iptr+1);
	    purge_buffer(ep);
	 }
      }
      assert(ep->iptr + data_size <= sizeof(ep->buf));
      memcpy(&ep->buf[ep->iptr], data, data_size);
      ep->iptr += data_size;
   }

   if (ep->status != S_WRITING)
      return 0;

   if (ep->iptr == ep->optr) {
      if (data == NULL) {
	 int error;
	 socklen_t error_len;

	 /* No data. Check socket status  */
	 error = 0;
	 error_len = sizeof(error);
	 if (getsockopt(ep->s, SOL_SOCKET, SO_ERROR, &error, &error_len) < 0)
	    error = errno;
	 if (error != 0) {
	    if (ctx->verbose)
	       fprintf(stderr, "%s %s socket error: %s\n", TAG, get_endpoint_name(ep), strerror(error));
	    try_reopen_socket(ctx, ep);
	    return -1;

	 }
      }
      return 0;
   }

   assert(ep->optr < ep->iptr);

   written = write(ep->s, &ep->buf[ep->optr], ep->iptr - ep->optr);
   if (written < 0) {
      if (errno == EAGAIN || (errno == EINTR))
	 return 0;
      /* Error  */
      if (ctx->verbose)
	 fprintf(stderr, "%s write() error: %s\n", TAG, strerror(errno));
      try_reopen_socket(ctx, ep);
   }else {
      ep->optr += written;
      if (ep->optr == ep->iptr)
	 ep->iptr = ep->optr = 0;
   }

   return written;
}
コード例 #6
0
ファイル: repeater.c プロジェクト: iRaveren/rdr2netflow
static int open_socket(struct rdr_repeater_ctx_t *ctx, struct endpoint_t *ep)
{
   int old_status;
   int flags;

   assert(ctx);
   assert(ep);

   assert(ep->status == S_NOT_INITIALIZED);
   assert(ep->s < 0);
   assert(ep->addrinfo != NULL);
   assert(ep->cur_addr != NULL);

   if (ctx->verbose > 1)
      fprintf(stderr, "%s Trying %s...\n", TAG, get_endpoint_name(ep));
   ep->s = socket(ep->cur_addr->ai_family,
	 ep->cur_addr->ai_socktype, ep->cur_addr->ai_protocol);
   if (ep->s < 0) {
      if (ctx->verbose > 1)
	 fprintf(stderr, "%s Socket() error: %s\n", TAG, strerror(errno));
      return -1;
   }

#ifdef SO_SNDBUF
   if (ctx->s_bufsize > 0) {
      unsigned sndbuf;
      sndbuf = ctx->s_bufsize;
      if (setsockopt(ep->s, SOL_SOCKET, SO_SNDBUF, &sndbuf, sizeof(sndbuf)) < 0) {
	 perror("setsockopt(SO_SNDBUF) error");
	 close(ep->s);
	 ep->s = -1;
	 return -1;
      }
   }
#endif

   flags = fcntl(ep->s, F_GETFL, 0);
   fcntl(ep->s, F_SETFL, flags | O_NONBLOCK);

   old_status = ep->status;
   ep->status = S_CONNECTING;
   if (connect(ep->s, ep->cur_addr->ai_addr, ep->cur_addr->ai_addrlen) < 0) {
      if (errno != EINPROGRESS) {
	 if (ctx->verbose > 1)
	    fprintf(stderr, "%s connect(%s) error: %s\n", TAG, get_endpoint_name(ep),
		  strerror(errno));
	 close(ep->s);
	 ep->s = -1;
	 ep->status = old_status;
	 return -1;
      }
   }else {
      if (finish_socket_opening(ctx, ep) < 0) {
	 close(ep->s);
	 ep->s = -1;
	 ep->status = old_status;
	 return -1;
      }
   }

   return ep->s;
}
コード例 #7
0
ファイル: auth.cpp プロジェクト: artasoftkey/entropybroker
int auth_eb_user(int fd, int to, users *user_map, std::string & username_out, std::string & password, long long unsigned int *challenge, bool is_proxy_auth, bool *is_server_in, std::string & type, random_source *rs, encrypt_stream *es, hasher *mac, std::string handshake_hash, unsigned int max_get_put_size, statistics_global *sg)
{
	std::string host = get_endpoint_name(fd);

	const char *ts = is_proxy_auth ? "Proxy-auth" : "Connection";

	/* Inform the client about the hash-functions and ciphers that are used */
	std::string mac_data = mac -> get_name();
	std::string cipher_data = es -> get_name();

	if (send_length_data(fd, handshake_hash.c_str(), handshake_hash.size(), to) == -1)
	{
		dolog(LOG_INFO, "%s failure sending handshake hash (fd: %d, host: %s)", ts, fd, host.c_str());
		return -1;
	}
	if (send_length_data(fd, mac_data.c_str(), mac_data.size(), to) == -1)
	{
		dolog(LOG_INFO, "%s failure sending data MAC (fd: %d, host: %s)", ts, fd, host.c_str());
		return -1;
	}
	if (send_length_data(fd, cipher_data.c_str(), cipher_data.size(), to) == -1)
	{
		dolog(LOG_INFO, "%s failure sending data cipher (fd: %d, host: %s)", ts, fd, host.c_str());
		return -1;
	}
	/////

	/* send random with which will be concatenated to the password and then hashed */
	long long unsigned int rnd = 9;
	rs -> get(reinterpret_cast<unsigned char *>(&rnd), sizeof rnd);

	char rnd_str[128];
	unsigned int rnd_str_size = snprintf(rnd_str, sizeof rnd_str, "%llu", rnd);

	*challenge = rnd;

	if (rnd_str_size == 0)
		error_exit("INTERNAL ERROR: random string is 0 characters!");

	if (send_length_data(fd, rnd_str, rnd_str_size, to) == -1)
	{
		dolog(LOG_INFO, "%s failure sending random (fd: %d, host: %s)", ts, fd, host.c_str());
		return -1;
	}
	/////

	/* receive username */
	char *username = NULL;
	unsigned int username_length = 0;
	if (recv_length_data(fd, &username, &username_length, to) == -1)
	{
		dolog(LOG_INFO, "%s receiving username (fd: %d, host: %s)", ts, fd, host.c_str());
		return -1;
	}

	dolog(LOG_INFO, "User '%s'[len: %d] requesting access (fd: %d, host: %s)", username, username_length, fd, host.c_str());

	if (username == NULL || username[0] == 0x00 || username_length == 0)
	{
		dolog(LOG_WARNING, "Empty username");
		sg -> put_history_log(HL_LOGIN_OTHER, host, "", "", get_ts(), 0, "empty username");
		free(username);
		return -1;
	}

	username_out.assign(username);

	bool user_known = user_map -> get_password(username_out, password);
	if (!user_known)
	{
		dolog(LOG_WARNING, "User '%s' not known, (fd: %d, host: %s)", username, fd, host.c_str());

		sg -> put_history_log(HL_LOGIN_USER_FAIL, host, "", username_out, get_ts(), 0, "username not known");

		user_known = false;
	}
	free(username);
	/////

	/* receive hashed password */
	hasher *hh = hasher::select_hasher(handshake_hash);
	int hash_len = hh -> get_hash_size();

	char hash_cmp_str[256], *hash_cmp = reinterpret_cast<char *>(malloc(hash_len)), *hash_in = reinterpret_cast<char *>(malloc(hash_len));
	int hash_cmp_str_len = snprintf(hash_cmp_str, sizeof hash_cmp_str, "%s %s", rnd_str, password.c_str());

	if (!hash_cmp || !hash_in)
		error_exit("out of memory");

	hh -> do_hash((unsigned char *)hash_cmp_str, hash_cmp_str_len, reinterpret_cast<unsigned char *>(hash_cmp));

	if (READ_TO(fd, hash_in, hash_len, to) != hash_len)
	{
		dolog(LOG_INFO, "%s receiving hash failed (fd: %d, host: %s)", ts, fd, host.c_str());
		free(hash_cmp);
		free(hash_in);
		delete hh;
		return -1;
	}

	if (!user_known || memcmp(hash_cmp, hash_in, hash_len) != 0)
	{
		dolog(LOG_INFO, "%s authentication failed! (fd: %d, host: %s)", ts, fd, host.c_str());
		free(hash_cmp);
		free(hash_in);
		delete hh;
		sg -> put_history_log(HL_LOGIN_PW_FAIL, host, "", username_out, get_ts(), 0, "hash mismatch");
		return -1;
	}
	free(hash_cmp);
	free(hash_in);
	delete hh;
	/////

	/* receive a byte which indicates if the other end is a client or a server */
        char is_server = 0;
        if (READ_TO(fd, &is_server, 1, to) != 1)
        {
                dolog(LOG_INFO, "%s failed retrieving server/client (fd: %d, host: %s)", ts, fd, host.c_str());
                return -1;
        }
	*is_server_in = is_server ? true : false;
	/////

	/* receive a string which describes the other send */
	char *type_in = NULL;
	unsigned int type_in_size = 0;

	if (recv_length_data(fd, &type_in, &type_in_size, to) == -1)
	{
                dolog(LOG_INFO, "%s failed retrieving type (fd: %d, host: %s)", ts, fd, host.c_str());
		return -1;
	}
	type = std::string(type_in);
	free(type_in);
	/////

	/* how many bits can be put/get in one go */
	unsigned char max_get_put_size_bytes[4];
	uint_to_uchar(max_get_put_size, max_get_put_size_bytes);
	if (WRITE_TO(fd, max_get_put_size_bytes, 4, to) == -1)
	{
		dolog(LOG_INFO, "Connection closed (fd: %d, host: %s)", fd, host.c_str());
		return -1;
	}

	dolog(LOG_INFO, "%s authentication ok (fd: %d, host: %s)", ts, fd, host.c_str());

	double now_ts = get_ts();
	user_map -> set_last_login(username_out, now_ts);
	sg -> put_history_log(HL_LOGIN_OK, host, type, username_out, now_ts, 0, "");

	return 0;
}