static gint slng_passwd_add(int argc, char *argv[], const gchar *mode, GOptionContext *ctx) { gchar *answer; gint remaining_unused_index = 0; if (!credentials_key) credentials_key = consume_next_from_remaining(credentials_remaining, &remaining_unused_index); if (!credentials_key) { gchar *usage = g_option_context_get_help(ctx, TRUE, NULL); fprintf(stderr, "Error: missing arguments!\n%s\n", usage); g_free(usage); return 1; } if (!is_syslog_ng_running()) return 1; if (!credentials_secret) credentials_secret = consume_next_from_remaining(credentials_remaining, &remaining_unused_index); gchar *secret_to_store; if (credentials_secret) { secret_to_store = g_strdup(credentials_secret); if (!secret_to_store) g_assert_not_reached(); } else { gsize buff_size = 256; secret_to_store = g_malloc0(buff_size); if (!secret_to_store) g_assert_not_reached(); read_password_from_stdin(secret_to_store, &buff_size); } gint retval = asprintf(&answer, "PWD %s %s %s", "add", credentials_key, secret_to_store); if (retval == -1) g_assert_not_reached(); secret_storage_wipe(secret_to_store, strlen(secret_to_store)); g_free(secret_to_store); if (credentials_secret) secret_storage_wipe(credentials_secret, strlen(credentials_secret)); gint result = _dispatch_command(answer); secret_storage_wipe(answer, strlen(answer)); g_free(answer); return result; }
static gint _dispatch_command(const gchar *cmd) { gint retval = 0; gchar *dispatchable_command = g_strdup_printf("%s\n", cmd); GString *rsp = slng_run_command(dispatchable_command); if (_is_response_empty(rsp)) { retval = 1; } else { retval = _process_response_status(rsp); printf("%s\n", rsp->str); } clear_and_free(rsp); secret_storage_wipe(dispatchable_command, strlen(dispatchable_command)); g_free(dispatchable_command); return retval; }
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); }