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); }
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; }
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; }
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; }
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); }
/** * 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; }
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; }
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); } }
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; }
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); }
/* * 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); }