Esempio n. 1
0
static void change_host_key(void) {
	set_ssh_connect_res(SSH_OK);
	set_ssh_is_server_known_res(SSH_SERVER_KNOWN_CHANGED);

	wsh_ssh_session_t* session = g_slice_new0(wsh_ssh_session_t);
	session->hostname = remote;
	session->username = username;
	session->password = password;
	session->port = port;
	GError* err = NULL;

	wsh_ssh_host(session, &err);
	gint ret = wsh_verify_host_key(session, FALSE, FALSE, &err);

	g_assert(ret == WSH_SSH_NEED_ADD_HOST_KEY);
	g_assert(session->session == NULL);
	g_assert_error(err, WSH_SSH_ERROR, WSH_SSH_HOST_KEY_CHANGED_ERR);

	g_error_free(err);
	g_slice_free(wsh_ssh_session_t, session);
}
Esempio n. 2
0
static void fail_add_host_key(void) {
	set_ssh_connect_res(SSH_OK);
	set_ssh_is_server_known_res(SSH_SERVER_NOT_KNOWN);
	set_ssh_write_knownhost_res(SSH_ERROR);

	wsh_ssh_session_t* session = g_slice_new0(wsh_ssh_session_t);
	session->hostname = remote;
	session->username = username;
	session->password = password;
	session->port = port;
	GError *err = NULL;

	wsh_ssh_host(session, &err);
	gint ret = wsh_verify_host_key(session, TRUE, FALSE, &err);

	g_assert(ret == WSH_SSH_HOST_KEY_ERROR);
	g_assert(session->session == NULL);
	g_assert_error(err, WSH_SSH_ERROR, WSH_SSH_KNOWN_HOSTS_WRITE_ERR);

	g_error_free(err);
	g_slice_free(wsh_ssh_session_t, session);
}
Esempio n. 3
0
static void add_host_key(void) {
	set_ssh_connect_res(SSH_OK);
	set_ssh_is_server_known_res(SSH_SERVER_NOT_KNOWN);
	set_ssh_write_knownhost_res(SSH_OK);

	wsh_ssh_session_t* session = g_slice_new0(wsh_ssh_session_t);
	session->hostname = remote;
	session->username = username;
	session->password = password;
	session->port = port;
	GError *err = NULL;

	wsh_ssh_host(session, &err);
	gint ret = wsh_verify_host_key(session, TRUE, FALSE, &err);

	g_assert(ret == 0);
	g_assert(session->session != NULL);
	g_assert_no_error(err);

	g_free(session->session);
	g_slice_free(wsh_ssh_session_t, session);
}
Esempio n. 4
0
File: remote.c Progetto: worr/wsh
void wshc_try_ssh(wshc_host_info_t* host_info,
                  const wshc_cmd_info_t* cmd_info) {
	g_assert(cmd_info != NULL);
	g_assert(host_info != NULL);

	GError* err = NULL;
	wsh_ssh_session_t session = {
		.hostname = host_info->hostname,
		.username = cmd_info->username,
		.password = cmd_info->password,
		.port = cmd_info->port,
		.session = NULL,
		.ssh_opts = cmd_info->ssh_opts,
	};

	if (session.password == NULL) {
		session.auth_type = WSH_SSH_AUTH_PUBKEY;
		wshc_verbose_print(cmd_info->out, "Using public key authentication\n");
	} else {
		session.auth_type = WSH_SSH_AUTH_PASSWORD;
		wshc_verbose_print(cmd_info->out, "Using password authentication\n");
	}

	wshc_verbose_print(cmd_info->out, "Initiating connection to %s\n",
	                   host_info->hostname);
	if (wsh_ssh_host(&session, &err)) {
		wshc_add_failed_host(cmd_info->out, host_info->hostname, err->message);
		wshc_verbose_print(cmd_info->out, "Connection failed on %s: %s\n",
		                   host_info->hostname, err->message);
		g_error_free(err);
		err = NULL;
		return;
	}
	wshc_verbose_print(cmd_info->out, "Connection to %s successful\n",
	                   host_info->hostname);

	wshc_verbose_print(cmd_info->out, "Verifying host key for %s\n",
	                   host_info->hostname);
	if (wsh_verify_host_key(&session, FALSE, FALSE, &err)) {
		wshc_add_failed_host(cmd_info->out, host_info->hostname, err->message);
		wshc_verbose_print(cmd_info->out, "Host key verification for %s failed: %s\n",
		                   host_info->hostname, err->message);
		g_error_free(err);
		err = NULL;
		return;
	}
	wshc_verbose_print(cmd_info->out, "Host verification for %s successful\n",
	                   host_info->hostname);

	wshc_verbose_print(cmd_info->out, "Authenticating to %s\n",
	                   host_info->hostname);
	if (wsh_ssh_authenticate(&session, &err)) {
		wshc_add_failed_host(cmd_info->out, host_info->hostname, err->message);
		wshc_verbose_print(cmd_info->out, "Failed to authenticate to %s: %s\n",
		                   host_info->hostname, err->message);
		g_error_free(err);
		err = NULL;
		return;
	}
	wshc_verbose_print(cmd_info->out, "Authenticated to %s successfully\n",
	                   host_info->hostname);

	if (cmd_info->script) {
		wshc_verbose_print(cmd_info->out, "Initializing scp subsystem for %s\n",
		                   host_info->hostname);
		if (wsh_ssh_scp_init(&session, "~")) {
			wshc_add_failed_host(cmd_info->out, host_info->hostname, "Could not init scp");
			wshc_verbose_print(cmd_info->out, "Failed to init scp on %s\n",
			                   host_info->hostname);
			return;
		}
		wshc_verbose_print(cmd_info->out, "Initialized scp subsystem on %s\n",
		                   host_info->hostname);

		wshc_verbose_print(cmd_info->out, "Transferring script %s to %s\n",
		                   cmd_info->script, host_info->hostname);
		if (wsh_ssh_scp_file(&session, cmd_info->script, TRUE, &err)) {
			wshc_add_failed_host(cmd_info->out, host_info->hostname, err->message);
			wshc_verbose_print(cmd_info->out, "Failed to transfer script %s to %s\n",
			                   cmd_info->script, host_info->hostname);
			g_error_free(err);
			err = NULL;
		}
		wshc_verbose_print(cmd_info->out, "Transferred script %s to %s successfully\n",
		                   cmd_info->script, host_info->hostname);

		wsh_ssh_scp_cleanup(&session);
	}

	wshc_verbose_print(cmd_info->out, "Execing wshd on %s\n", host_info->hostname);
	if (wsh_ssh_exec_wshd(&session, &err)) {
		wshc_add_failed_host(cmd_info->out, host_info->hostname, err->message);
		wshc_verbose_print(cmd_info->out, "Failed to exec wshd on %s: %s\n",
		                   host_info->hostname, err->message);
		g_error_free(err);
		err = NULL;
		return;
	}
	wshc_verbose_print(cmd_info->out, "Successfully launched wshd %s\n",
	                   host_info->hostname);

	wshc_verbose_print(cmd_info->out, "Sending command info to wshd on %s\n",
	                   host_info->hostname);
	if (wsh_ssh_send_cmd(&session, cmd_info->req, &err)) {
		wshc_verbose_print(cmd_info->out, "Failed to send command to %s: %s\n",
		                   host_info->hostname, err->message);
		wshc_add_failed_host(cmd_info->out, host_info->hostname, err->message);
		g_error_free(err);
		err = NULL;
		return;
	}
	wshc_verbose_print(cmd_info->out,
	                   "Successfully sent command info to wshd on %s\n",
	                   host_info->hostname);

	wshc_verbose_print(cmd_info->out,
	                   "Waiting for response from %s\n", host_info->hostname);
	if (wsh_ssh_recv_cmd_res(&session, host_info->res, &err)) {
		wshc_verbose_print(cmd_info->out,
		                   "Failed to receive a command from %s: %s\n",
		                   host_info->hostname, err->message);
		wshc_add_failed_host(cmd_info->out, host_info->hostname, err->message);
		g_error_free(err);
		err = NULL;
		return;
	}
	wshc_verbose_print(cmd_info->out, "Got response from %s\n",
	                   host_info->hostname);

	wsh_log_client_cmd_status(cmd_info->req->cmd_string, cmd_info->req->username,
	                          host_info->hostname, cmd_info->req->cwd, (*host_info->res)->exit_status);
	wshc_write_output(cmd_info->out, host_info->hostname, *host_info->res);
	wsh_free_unpacked_response(host_info->res);

	wsh_ssh_disconnect(&session);
}
Esempio n. 5
0
File: wscp.c Progetto: worr/wsh
static gint scp_file(const wshc_scp_file_args* args) {
	GError *err = NULL;
	wsh_ssh_session_t session = {
		.session = NULL,
		.channel = NULL,
		.hostname = args->host,
		.username = args->user,
		.password = args->pass,
		.scp = NULL,
		.port = args->port,
	};

	if (session.password == NULL)
		session.auth_type = WSH_SSH_AUTH_PUBKEY;
	else
		session.auth_type = WSH_SSH_AUTH_PASSWORD;

	if (wsh_ssh_host(&session, &err)) {
		g_printerr("%s\n", err->message);
		g_error_free(err);
		return EXIT_FAILURE;
	}

	if (wsh_verify_host_key(&session, FALSE, FALSE, &err)) {
		g_printerr("%s\n", err->message);
		g_error_free(err);
		return EXIT_FAILURE;
	}

	if (wsh_ssh_authenticate(&session, &err)) {
		g_printerr("%s\n", err->message);
		g_error_free(err);
		return EXIT_FAILURE;
	}

	if (wsh_ssh_scp_init(&session, args->location)) {
		g_printerr("Error initializing scp");
		return EXIT_FAILURE;
	}

	for (gint i = 0; i < args->num_files; i++) {
		if (wsh_ssh_scp_file(&session, args->files[i], FALSE, &err)) {
			g_printerr("%s\n", err->message);
			g_error_free(err);
			err = NULL;
		}
	}

	wsh_ssh_scp_cleanup(&session);
	wsh_ssh_disconnect(&session);

	return EXIT_SUCCESS;
}

gint main(gint argc, gchar** argv) {
	GError* err = NULL;
	GOptionContext* context;
	gint ret = EXIT_SUCCESS;
	gchar** hosts = NULL;
	gsize num_hosts = 0;
	gchar* password = NULL;

	wsh_init_logger(WSH_LOGGER_CLIENT);
	wsh_ssh_init();

	if (wsh_client_init(&err)) {
		g_printerr("%s", err->message);
		g_error_free(err);
		return EXIT_FAILURE;
	}

	context = g_option_context_new("[FILENAMES...] - scp file to multiple machines at once");
	g_option_context_add_main_entries(context, entries, NULL);
	if (! g_option_context_parse(context, &argc, &argv, &err)) {
		g_printerr("Option parsing failed: %s\n", err->message);
		g_error_free(err);
		return EXIT_FAILURE;
	}

	if (argc == 1) {
		g_printerr("ERROR: Must provide a host and a file\n\n");
		g_printerr("%s", g_option_context_get_help(context, FALSE, NULL));
		g_option_context_free(context);
		return EXIT_FAILURE;
	}

	gchar* msg = NULL;
	if (! valid_arguments(&msg)) {
		g_printerr("%s\n", msg);
		g_free(msg);

		g_printerr("%s", g_option_context_get_help(context, FALSE, NULL));
		g_option_context_free(context);
		return EXIT_FAILURE;
	}

	g_option_context_free(context);

	// We're done with option validation
	if (username == NULL)
		username = g_strdup(g_get_user_name());

	if (ask_password) {
		if ((ret = wsh_client_lock_password_pages(&passwd_mem))) {
			g_printerr("%s\n", strerror(ret));
			return ret;
		}

		password = ((gchar*)passwd_mem) + (WSH_MAX_PASSWORD_LEN * 0);
		if ((ret = wsh_client_getpass(password, WSH_MAX_PASSWORD_LEN, "SSH password: "******"%s\n", strerror(ret));
			return ret;
		}

		if (! password) return EXIT_FAILURE;
	}

	if (!location)
		location = g_strdup("~");

	if (file_arg) {
		if (wsh_exp_filename(&hosts, &num_hosts, file_arg, &err)) {
			g_printerr("%s\n", err->message);
			g_error_free(err);
			return EXIT_FAILURE;
		}
	}

	if (hosts_arg) {
		hosts = g_strsplit(hosts_arg, ",", 0);
		num_hosts = g_strv_length(hosts);
	}

#ifdef WITH_RANGE
	if (range) {
		if (wsh_exp_range(&hosts, &num_hosts, range, &err)) {
			g_printerr("%s\n", err->message);
			g_error_free(err);
			return EXIT_FAILURE;
		}
	}
#endif

	argv++; argc--;
	for (gint i = 1; i < argc; i++) {
		// scp will catch this, but I'd like to catch it before
		// we start even trying to scp files
		if (!g_file_test(argv[i], G_FILE_TEST_EXISTS)) {
			g_printerr("ERROR: %s doesn't exist\n", argv[i]);
			ret = EXIT_FAILURE;
			goto bad;
		}
	}

	if (threads <= 0) {
		wshc_scp_file_args args;
		args.port = port;
		args.user = username;
		args.pass = password;
		args.files = argv;
		args.num_files = argc;
		args.location = location;

		for (gsize i = 0; i < num_hosts; i++) {
			args.host = hosts[i];
			scp_file(&args);
		}
	} else {
		GThreadPool* gtp;
		if ((gtp = g_thread_pool_new((GFunc)scp_file, NULL, threads, TRUE, &err)) == NULL) {
			g_printerr("%s\n", err->message);
			g_error_free(err);
			return EXIT_FAILURE;
		}

		wshc_scp_file_args args[num_hosts];

		for (gsize i = 0; i < num_hosts; i++) {
			args[i].host = hosts[i];
			args[i].port = port;
			args[i].user = username;
			args[i].pass = password;
			args[i].files = argv;
			args[i].num_files = argc;
			args[i].location = location;

			g_thread_pool_push(gtp, &args[i], NULL);
		}

		g_thread_pool_free(gtp, FALSE, TRUE);
	}

	if (password) {
		memset_s(password, WSH_MAX_PASSWORD_LEN, 0, strlen(password));
		wsh_client_unlock_password_pages(passwd_mem);
	}

bad:
	wsh_ssh_cleanup();
	wsh_exit_logger();

	if (password) g_free(password);
	password = NULL;
	if (range) g_free(range);
	range = NULL;
	if (hosts_arg) g_free(hosts_arg);

	g_free(username);
	username = NULL;

	return ret;
}