static void
t_asn1_get_oid(void) {
	GError *gerr = NULL;
	network_packet p;
	GString *oid;

	p.data = g_string_new_len(C("\x2b\x06\x01\x05\x05\x02"));
	p.offset = 0;

	oid = g_string_new(NULL);

	g_assert_cmpint(TRUE, ==, network_asn1_proto_get_oid(&p, p.data->len, oid, &gerr));
	g_assert_cmpstr("1.3.6.1.5.5.2", ==, oid->str);

	g_string_assign_len(p.data, C("\x2b\x06\x01\x04\x01\x82\x37\x02\x02\x0a"));
	p.offset = 0;
	g_assert_cmpint(TRUE, ==, network_asn1_proto_get_oid(&p, p.data->len, oid, &gerr));
	g_assert_cmpstr("1.3.6.1.4.1.311.2.2.10", ==, oid->str);

	g_string_assign_len(p.data, C("\x2a\x86\x48\x82\xf7\x12\x01\x02\x02"));
	p.offset = 0;
	g_assert_cmpint(TRUE, ==, network_asn1_proto_get_oid(&p, p.data->len, oid, &gerr));
	g_assert_cmpstr("1.2.840.48018.1.2.2", ==, oid->str);


	g_string_free(p.data, TRUE);
}
static void
t_asn1_get_length(void) {
	GError *gerr = NULL;
	network_packet p;
	ASN1Length len;

	p.data = g_string_new_len(C("\x60"));
	p.offset = 0;

	g_assert_cmpint(TRUE, ==, network_asn1_proto_get_length(&p, &len, &gerr));
	g_assert_cmpint(len, ==, 0x60);

	g_string_assign_len(p.data, C("\x81\x80"));
	p.offset = 0;

	g_assert_cmpint(TRUE, ==, network_asn1_proto_get_length(&p, &len, &gerr));
	g_assert_cmpint(len, ==, 0x80);

	g_string_assign_len(p.data, C("\x82\x01\x2d"));
	p.offset = 0;

	g_assert_cmpint(TRUE, ==, network_asn1_proto_get_length(&p, &len, &gerr));
	g_assert_cmpint(len, ==, 0x12d);


	g_string_free(p.data, TRUE);
}
void t_err_packet_append(void) {
	network_mysqld_err_packet_t *err_packet;
	network_packet *packet;

	err_packet = network_mysqld_err_packet_new();
	packet = network_packet_new();
	packet->data = g_string_new(NULL);

	/* check if a empty ok-packet is encoded correctly */
	g_assert_cmpint(0, ==, network_mysqld_proto_append_err_packet(packet->data, err_packet));
	g_assert_cmpint(9, ==, packet->data->len);
	g_assert_cmpint(TRUE, ==, g_memeq(S(packet->data), C("\xff\x00\x00#07000")));

	g_assert_cmpint(0, ==, network_mysqld_proto_get_err_packet(packet, err_packet));

	/* check if encoding and decoding works */
	err_packet->errcode = 3;
	g_string_assign_len(err_packet->errmsg, C("test"));
	g_string_assign_len(err_packet->sqlstate, C("01234"));

	g_string_truncate(packet->data, 0);
	packet->offset = 0;

	g_assert_cmpint(0, ==, network_mysqld_proto_append_err_packet(packet->data, err_packet));
	g_assert_cmpint(13, ==, packet->data->len);
	g_assert_cmpint(TRUE, ==, g_memeq(S(packet->data), C("\xff\x03\x00#01234test")));
	
	network_mysqld_err_packet_free(err_packet);

	err_packet = network_mysqld_err_packet_new();
	g_assert_cmpint(0, ==, network_mysqld_proto_get_err_packet(packet, err_packet));
	g_assert_cmpint(3, ==, err_packet->errcode);
	g_assert_cmpstr("01234", ==, err_packet->sqlstate->str);
	g_assert_cmpstr("test", ==, err_packet->errmsg->str);

	network_mysqld_err_packet_free(err_packet);

	/* check if too-short packet is denied */
	err_packet = network_mysqld_err_packet_new();
	g_string_truncate(packet->data, 0);
	packet->offset = 0;
	g_assert_cmpint(-1, ==, network_mysqld_proto_get_err_packet(packet, err_packet));

	network_mysqld_err_packet_free(err_packet);

	g_string_free(packet->data, TRUE);
	network_packet_free(packet);
}
Exemple #4
0
static gboolean
_kv_scanner_extract_key(KVScanner *self)
{
  const gchar *input_ptr = &self->input[self->input_pos];
  const gchar *start_of_key;
  const gchar *separator;
  gsize len;

  separator = strchr(input_ptr, self->value_separator);
  do
    {
      if (!separator)
        return FALSE;
      start_of_key = separator;
      while (start_of_key > input_ptr && _is_valid_key_character(*(start_of_key - 1)))
        start_of_key--;
      len = separator - start_of_key;
      if (len < 1)
        separator = strchr(separator + 1, self->value_separator);
    }
  while (len < 1);

  g_string_assign_len(self->key, start_of_key, len);
  self->input_pos = separator - self->input + 1;
  return TRUE;
}
Exemple #5
0
network_address *network_address_copy(network_address *dst, network_address *src) {
	if (!dst) dst = network_address_new();

	dst->len = src->len;
	dst->addr = src->addr;
	g_string_assign_len(dst->name, S(src->name));

	return dst;
}
Exemple #6
0
static gboolean
_kv_scanner_decode_value(KVScanner *self)
{
  if (self->parse_value)
    {
      g_string_truncate(self->decoded_value, 0);
      if (self->parse_value(self))
        g_string_assign_len(self->value, self->decoded_value->str, self->decoded_value->len);
    }
  return TRUE;
}
static int network_mysqld_type_data_string_set_string(network_mysqld_type_t *type, const char *src, gsize src_len) {
	GString *dst;

	if (NULL == type->data) {
		type->data = g_string_sized_new(src_len);
	}

	dst = type->data;

	g_string_assign_len(dst, src, src_len);
	
	return 0;
}
Exemple #8
0
void
tls_x509_format_dn(X509_NAME *name, GString *dn)
{
  BIO *bio;
  gchar *buf;
  long len;

  bio = BIO_new(BIO_s_mem());
  X509_NAME_print_ex(bio, name, 0, ASN1_STRFLGS_ESC_2253 | ASN1_STRFLGS_UTF8_CONVERT | XN_FLAG_SEP_CPLUS_SPC | XN_FLAG_DN_REV);
  len = BIO_get_mem_data(bio, &buf);
  g_string_assign_len(dn, buf, len);
  BIO_free(bio);
}
Exemple #9
0
/**
 * move the con->server into connection pool and disconnect the
 * proxy from its backend
 */
int network_connection_pool_lua_add_connection(network_mysqld_con *con, int is_write_sql) {
	network_connection_pool_entry *pool_entry = NULL;
	network_mysqld_con_lua_t *st = con->plugin_con_state;
       guint thread_id;

	/* con-server is already disconnected, got out */
	if (!con->server) return 0;

    /* TODO bug fix */
    /* when mysql return unkonw packet, response is null, insert the socket into pool cause segment fault. */
    /* ? should init socket->challenge  ? */
    /* if response is null, conn has not been authed, use an invalid username. */
    if(!con->server->response)
    {
        g_warning("%s: (remove) remove socket from pool, response is NULL, src is %s, dst is %s",
            G_STRLOC, con->server->src->name->str, con->server->dst->name->str);

        con->server->response = network_mysqld_auth_response_new();
        g_string_assign_len(con->server->response->username, C("mysql_proxy_invalid_user"));
    }

	/* the server connection is still authed */
	con->server->is_authed = 1;

	/* insert the server socket into the connection pool */
       if(is_write_sql == 0) {
              network_connection_pool* pool = chassis_event_thread_pool(st->backend);
              pool_entry = network_connection_pool_add(pool, con->server);
       }else {
              network_connection_pool* pool = chassis_event_thread_secondpool(st->backend);
              pool_entry = network_connection_pool_time_add(pool, con->server, con);
       }

	if (pool_entry) {
		event_set(&(con->server->event), con->server->fd, EV_READ, network_mysqld_con_idle_handle, pool_entry);
		chassis_event_add_local(con->srv, &(con->server->event)); /* add a event, but stay in the same thread */
	}

	g_atomic_int_dec_and_test(&(st->backend->connected_clients));
	st->backend = NULL;
	st->backend_ndx = -1;
	con->server = NULL;
       thread_id = chassis_event_thread_index_get();
       chassis_event_thread_t *thread = g_ptr_array_index(con->srv->threads, thread_id);
       if(thread->block_con_queue->length) {
              if (write(thread->con_write_fd, "", 1) != 1) g_message("%s:pipes - write error: %s", G_STRLOC, g_strerror(errno));
       }

       return 0;
}
/**
 * move the con->server into connection pool and disconnect the 
 * proxy from its backend 
 */
int network_connection_pool_lua_add_connection(network_mysqld_con *con) {
	network_connection_pool_entry *pool_entry = NULL;
	network_mysqld_con_lua_t *st = con->plugin_con_state;

	/* con-server is already disconnected, got out */
	if (!con->server) return 0;

    /* TODO bug fix */
    /* when mysql return unkonw packet, response is null, insert the socket into pool cause segment fault. */
    /* ? should init socket->challenge  ? */
    /* if response is null, conn has not been authed, use an invalid username. */
    if(!con->server->response)
    {
        g_warning("%s: (remove) remove socket from pool, response is NULL, src is %s, dst is %s",
            G_STRLOC, con->server->src->name->str, con->server->dst->name->str);

        con->server->response = network_mysqld_auth_response_new();
        g_string_assign_len(con->server->response->username, C("mysql_proxy_invalid_user"));
    }

	/* the server connection is still authed */
	con->server->is_authed = 1;

	/* insert the server socket into the connection pool */
	network_connection_pool* pool = chassis_event_thread_pool(st->backend);
	pool_entry = network_connection_pool_add(pool, con->server);

	if (pool_entry) {
		event_set(&(con->server->event), con->server->fd, EV_READ, network_mysqld_con_idle_handle, pool_entry);
		chassis_event_add_local(con->srv, &(con->server->event)); /* add a event, but stay in the same thread */
	}

    if (!g_atomic_int_compare_and_exchange(&st->backend->connected_clients, 0, 0)) {
        g_atomic_int_dec_and_test(&st->backend->connected_clients);    
        //g_critical("add_connection: %08x's connected_clients is %d\n", backend,  backend->connected_clients);
    }

//	st->backend->connected_clients--;
	st->backend = NULL;
	st->backend_ndx = -1;
	
	con->server = NULL;

	return 0;
}
Exemple #11
0
static int
stomp_read_data(stomp_connection *connection, GString *buffer)
{
  char tmp_buf[4096];
  int res;

  res = read(connection->socket, tmp_buf, sizeof(tmp_buf));
  if (res < 0)
     return FALSE;

  g_string_assign_len(buffer, tmp_buf, res);
  while (res == sizeof(tmp_buf))
    {
      res = read(connection->socket, tmp_buf, sizeof(tmp_buf));
      g_string_append_len(buffer, tmp_buf, res);
    }
  return TRUE;
}
Exemple #12
0
static gboolean
_kv_scanner_extract_key(KVScanner *self)
{
  const gchar *input_ptr = &self->input[self->input_pos];
  const gchar *start_of_key;
  const gchar *equal;

  equal = strchr(input_ptr, '=');
  if (!equal)
    return FALSE;
  start_of_key = equal - 1;
  while (start_of_key > input_ptr && _is_valid_key_character(*start_of_key))
    start_of_key--;
  if (!_is_valid_key_character(*start_of_key))
    start_of_key++;
  g_string_assign_len(self->key, start_of_key, equal - start_of_key);
  self->input_pos = equal - self->input + 1;
  return TRUE;
}
static void
t_asn1_get_id(void) {
	GError *gerr = NULL;
	network_packet p;
	ASN1Identifier id;

	p.data = g_string_new_len(C("\x60"));
	p.offset = 0;

	g_assert_cmpint(TRUE, ==, network_asn1_proto_get_id(&p, &id, &gerr));
	g_assert_cmpint(id.klass, ==, ASN1_IDENTIFIER_KLASS_APPLICATION);
	g_assert_cmpint(id.type, ==, ASN1_IDENTIFIER_TYPE_CONSTRUCTED);
	g_assert_cmpint(id.value, ==, 0);

	/* we don't support long ids */
	g_string_assign_len(p.data, C("\x1f"));
	p.offset = 0;
	g_assert_cmpint(FALSE, ==, network_asn1_proto_get_id(&p, &id, &gerr));

	g_string_free(p.data, TRUE);
}
  static void
affile_sd_load_pos(LogPipe *s, GlobalConfig *cfg)
{
  AFFileSourceDriver *self = (AFFileSourceDriver *) s;
  gchar *str;
  off_t cur_pos;
  gsize str_len;
  gint version;

  if ((self->flags & AFFILE_PIPE) || !cfg->persist)
    return;

  str = cfg_persist_config_fetch(cfg, affile_sd_format_persist_name(self), &str_len, &version);
  if (!str)
    return;

  if (version == 2)
  {
    /* NOTE: legacy, should be removed once the release after 3.0 is published */
    cur_pos = strtoll(str, NULL, 10);
    log_reader_update_pos((LogReader *) self->reader, cur_pos);
    g_free(str);
  }
  else if (version >= 3)
  {
    GString *g_str = g_string_new("");
    SerializeArchive *archive;

    g_str = g_string_assign_len(g_str, str, str_len);
    archive = serialize_string_archive_new(g_str);

    log_reader_restore_state((LogReader *) self->reader, archive);

    serialize_archive_free(archive);
    g_string_free(g_str, TRUE);
    g_free(str);

  }
}
Exemple #15
0
static int proxy_backend_set(lua_State *L) {
	network_backend_t *backend = *(network_backend_t **)luaL_checkself(L);
	gsize keysize = 0;
	const char *key = luaL_checklstring(L, 2, &keysize);

	if (strleq(key, keysize, C("state"))) {
		backend->state = lua_tointeger(L, -1);
	} else if (strleq(key, keysize, C("uuid"))) {
		if (lua_isstring(L, -1)) {
			size_t s_len = 0;
			const char *s = lua_tolstring(L, -1, &s_len);

			g_string_assign_len(backend->uuid, s, s_len);
		} else if (lua_isnil(L, -1)) {
			g_string_truncate(backend->uuid, 0);
		} else {
			return luaL_error(L, "proxy.global.backends[...].%s has to be a string", key);
		}
	} else {
		return luaL_error(L, "proxy.global.backends[...].%s is not writable", key);
	}
	return 1;
}
Exemple #16
0
static void
control_connection_io_input(void *s)
{
  ControlConnection *self = (ControlConnection *) s;
  GString *command = NULL;
  gchar *nl;
  gint rc;
  gint orig_len;
  GList *iter;

  if (self->input_buffer->len > MAX_CONTROL_LINE_LENGTH)
    {
      /* too much data in input, drop the connection */
      msg_error("Too much data in the control socket input buffer");
      control_server_connection_closed(self->server, self);
      return;
    }

  orig_len = self->input_buffer->len;

  /* NOTE: plus one for the terminating NUL */
  g_string_set_size(self->input_buffer, self->input_buffer->len + 128 + 1);
  rc = self->read(self, self->input_buffer->str + orig_len, 128);
  if (rc < 0)
    {
      if (errno != EAGAIN)
        {
          msg_error("Error reading command on control channel, closing control channel",
                    evt_tag_error("error"));
          goto destroy_connection;
        }
      /* EAGAIN, should try again when data comes */
      control_connection_update_watches(self);
      return;
    }
  else if (rc == 0)
    {
      msg_debug("EOF on control channel, closing connection");
      goto destroy_connection;
    }
  else
    {
      self->input_buffer->len = orig_len + rc;
      self->input_buffer->str[self->input_buffer->len] = 0;
    }

  /* here we have finished reading the input, check if there's a newline somewhere */
  nl = strchr(self->input_buffer->str, '\n');
  if (nl)
    {
      command = g_string_sized_new(128);
      /* command doesn't contain NL */
      g_string_assign_len(command, self->input_buffer->str, nl - self->input_buffer->str);
      secret_storage_wipe(self->input_buffer->str, nl - self->input_buffer->str);
      /* strip NL */
      /*g_string_erase(self->input_buffer, 0, command->len + 1);*/
      g_string_truncate(self->input_buffer, 0);
    }
  else
    {
      /* no EOL in the input buffer, wait for more data */
      control_connection_update_watches(self);
      return;
    }

  iter = g_list_find_custom(get_control_command_list(), command->str,
                            (GCompareFunc)control_command_start_with_command);
  if (iter == NULL)
    {
      msg_error("Unknown command read on control channel, closing control channel",
                evt_tag_str("command", command->str));
      g_string_free(command, TRUE);
      goto destroy_connection;
    }
  ControlCommand *cmd_desc = (ControlCommand *) iter->data;

  cmd_desc->func(self, command, cmd_desc->user_data);
  control_connection_wait_for_output(self);

  secret_storage_wipe(command->str, command->len);
  g_string_free(command, TRUE);
  return;
destroy_connection:
  control_server_connection_closed(self->server, self);
}
Exemple #17
0
/*
 * NOTE: the channel is not in nonblocking mode, thus the control channel
 * may block syslog-ng completely.
 */
static void
control_connection_io_input(void *s)
{
  ControlConnection *self = (ControlConnection *) s;
  GString *command = NULL;
  gchar *nl;
  gint rc;
  gint cmd;
  gint orig_len;
  
  if (self->input_buffer->len > MAX_CONTROL_LINE_LENGTH)
    {
      /* too much data in input, drop the connection */
      msg_error("Too much data in the control socket input buffer",
                NULL);
      control_connection_stop_watches(self);
      control_connection_free(self);
      return;
    }

  orig_len = self->input_buffer->len;

  /* NOTE: plus one for the terminating NUL */
  g_string_set_size(self->input_buffer, self->input_buffer->len + 128 + 1);
  rc = read(self->control_io.fd, self->input_buffer->str + orig_len, 128);
  if (rc < 0)
    {
      if (errno != EAGAIN)
        {
          msg_error("Error reading command on control channel, closing control channel",
                    evt_tag_errno("error", errno),
                    NULL);
          goto destroy_connection;
        }
      /* EAGAIN, should try again when data comes */
      control_connection_update_watches(self);
      return;
    }
  else if (rc == 0)
    {
      msg_error("EOF on control channel, closing connection",
                NULL);
      goto destroy_connection;
    }
  else
    {
      self->input_buffer->len = orig_len + rc;
      self->input_buffer->str[self->input_buffer->len] = 0;
    }

  /* here we have finished reading the input, check if there's a newline somewhere */
  nl = strchr(self->input_buffer->str, '\n');
  if (nl)
    {
      command = g_string_sized_new(128);
      /* command doesn't contain NL */
      g_string_assign_len(command, self->input_buffer->str, nl - self->input_buffer->str);
      /* strip NL */
      g_string_erase(self->input_buffer, 0, command->len + 1);
    }
  else
    {
      /* no EOL in the input buffer, wait for more data */
      control_connection_update_watches(self);
      return;
    }

  for (cmd = 0; commands[cmd].func; cmd++)
    {
      if (strncmp(commands[cmd].command, command->str, strlen(commands[cmd].command)) == 0)
        {
          commands[cmd].func(self, command);
          break;
        }
    }
  if (!commands[cmd].func)
    {
      msg_error("Unknown command read on control channel, closing control channel",
                evt_tag_str("command", command->str), NULL);
      goto destroy_connection;
    }
  control_connection_update_watches(self);
  g_string_free(command, TRUE);
  return;
 destroy_connection:
  control_connection_stop_watches(self);
  control_connection_free(self);

}