mirror of
https://git.jabber.space/devs/cproof.git
synced 2026-08-01 10:36:22 +00:00
Merge pull request #1459 from wstrm/issue-1359
Restore old behavior when executing eval_password command
This commit is contained in:
95
src/common.c
95
src/common.c
@@ -471,92 +471,35 @@ get_mentions(gboolean whole_word, gboolean case_sensitive, const char* const mes
|
|||||||
return mentions;
|
return mentions;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Take an NULL-terminated array used as the tokens of a command, and optionally
|
|
||||||
* pointers to the string arrays that will store each lines of the call standard
|
|
||||||
* output and standard error.
|
|
||||||
*
|
|
||||||
* argv - NULL-terminated string array containing the tokens of the command
|
|
||||||
* line to spawn
|
|
||||||
* output_ptr - a pointer to the string array where to store spawned command
|
|
||||||
* standard output
|
|
||||||
* set to NULL to ignore the command standard output
|
|
||||||
* error_ptr - a pointer to the string array where to store spawned command
|
|
||||||
* standard error
|
|
||||||
* set to NULL to ignore the command standard error
|
|
||||||
*
|
|
||||||
* Returns:
|
|
||||||
* - TRUE if the command has been successfully spawned and exited normally
|
|
||||||
* - FALSE otherwise
|
|
||||||
*/
|
|
||||||
gboolean
|
gboolean
|
||||||
call_external(gchar** argv, gchar*** const output_ptr, gchar*** const error_ptr)
|
call_external(gchar** argv, gchar** std_out, gchar** std_err)
|
||||||
{
|
{
|
||||||
gchar* stdout_str = NULL;
|
|
||||||
gchar** stdout_str_ptr = &stdout_str;
|
|
||||||
gchar* stderr_str = NULL;
|
|
||||||
gchar** stderr_str_ptr = &stderr_str;
|
|
||||||
GSpawnFlags flags = G_SPAWN_SEARCH_PATH;
|
GSpawnFlags flags = G_SPAWN_SEARCH_PATH;
|
||||||
gint status;
|
if (std_out == NULL)
|
||||||
GError* error = NULL;
|
|
||||||
gchar* cmd = NULL;
|
|
||||||
|
|
||||||
cmd = g_strjoinv(" ", argv);
|
|
||||||
log_debug("Calling external: %s", cmd);
|
|
||||||
|
|
||||||
if (!output_ptr) {
|
|
||||||
stdout_str_ptr = NULL;
|
|
||||||
flags |= G_SPAWN_STDOUT_TO_DEV_NULL;
|
flags |= G_SPAWN_STDOUT_TO_DEV_NULL;
|
||||||
}
|
if (std_err == NULL)
|
||||||
|
|
||||||
if (!error_ptr) {
|
|
||||||
stderr_str_ptr = NULL;
|
|
||||||
flags |= G_SPAWN_STDERR_TO_DEV_NULL;
|
flags |= G_SPAWN_STDERR_TO_DEV_NULL;
|
||||||
}
|
|
||||||
|
|
||||||
if (!g_spawn_sync(NULL, argv, NULL, flags, NULL, NULL, stdout_str_ptr, stderr_str_ptr, &status, &error)) {
|
gint exit_status;
|
||||||
log_error("Spawning '%s' failed: %s.", cmd, error->message);
|
gboolean spawn_result;
|
||||||
g_error_free(error);
|
GError* spawn_error;
|
||||||
error = NULL;
|
spawn_result = g_spawn_sync(NULL, // Inherit the parent PWD.
|
||||||
return FALSE;
|
argv,
|
||||||
}
|
NULL, // Inherit the parent environment.
|
||||||
|
flags,
|
||||||
|
NULL, NULL, // No func. before exec() in child.
|
||||||
|
std_out, std_err,
|
||||||
|
&exit_status, &spawn_error);
|
||||||
|
|
||||||
if (!g_spawn_check_exit_status(status, &error)) {
|
if (!spawn_result
|
||||||
log_error("Calling '%s' failed: %s.", cmd, error->message);
|
|| !g_spawn_check_exit_status(exit_status, &spawn_error)) {
|
||||||
g_error_free(error);
|
gchar* cmd = g_strjoinv(" ", argv);
|
||||||
error = NULL;
|
log_error("Spawning '%s' failed with '%s'.", cmd, spawn_error->message);
|
||||||
g_free(cmd);
|
g_free(cmd);
|
||||||
cmd = NULL;
|
g_error_free(spawn_error);
|
||||||
g_free(stdout_str);
|
|
||||||
stdout_str = NULL;
|
|
||||||
stdout_str_ptr = NULL;
|
|
||||||
if (stderr_str && strlen(stderr_str)) {
|
|
||||||
log_error("Called command returned the following on stderr: %s.", stderr_str);
|
|
||||||
}
|
|
||||||
g_free(stderr_str);
|
|
||||||
stderr_str = NULL;
|
|
||||||
stderr_str_ptr = NULL;
|
|
||||||
return FALSE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
g_free(cmd);
|
return spawn_result;
|
||||||
cmd = NULL;
|
|
||||||
|
|
||||||
if (output_ptr) {
|
|
||||||
*output_ptr = g_strsplit(stdout_str, "\n", 0);
|
|
||||||
g_free(stdout_str);
|
|
||||||
stdout_str = NULL;
|
|
||||||
stdout_str_ptr = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (error_ptr) {
|
|
||||||
*error_ptr = g_strsplit(stderr_str, "\n", 0);
|
|
||||||
g_free(stderr_str);
|
|
||||||
stderr_str = NULL;
|
|
||||||
stderr_str_ptr = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
gchar**
|
gchar**
|
||||||
|
|||||||
@@ -104,10 +104,10 @@ void get_file_paths_recursive(const char* directory, GSList** contents);
|
|||||||
|
|
||||||
char* get_random_string(int length);
|
char* get_random_string(int length);
|
||||||
|
|
||||||
gboolean call_external(gchar** argv, gchar*** const output_ptr, gchar*** const error_ptr);
|
gboolean call_external(gchar** argv, gchar** std_out, gchar** std_err);
|
||||||
gchar** format_call_external_argv(const char* template, const char* url, const char* filename);
|
gchar** format_call_external_argv(const char* template, const char* url, const char* filename);
|
||||||
|
|
||||||
gchar* unique_filename_from_url(const char* url, const char* path);
|
gchar* unique_filename_from_url(const char* url, const char* path);
|
||||||
gchar* get_expanded_path(const char *path);
|
gchar* get_expanded_path(const char* path);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -36,6 +36,7 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
#include <glib.h>
|
#include <glib.h>
|
||||||
|
|
||||||
@@ -200,27 +201,49 @@ account_eval_password(ProfAccount* account)
|
|||||||
assert(account != NULL);
|
assert(account != NULL);
|
||||||
assert(account->eval_password != NULL);
|
assert(account->eval_password != NULL);
|
||||||
|
|
||||||
gchar** output = NULL;
|
errno = 0;
|
||||||
gchar** error = NULL;
|
|
||||||
|
|
||||||
gchar* argv[] = { "sh", "-c", account->eval_password, NULL };
|
FILE* stream = popen(account->eval_password, "r");
|
||||||
if (!call_external(argv, &output, &error)) {
|
if (stream == NULL) {
|
||||||
|
const char* errmsg = strerror(errno);
|
||||||
|
if (errmsg) {
|
||||||
|
log_error("Could not execute `eval_password` command (%s).",
|
||||||
|
errmsg);
|
||||||
|
} else {
|
||||||
|
log_error("Failed to allocate memory for `eval_password` command.");
|
||||||
|
}
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!output || !output[0]) {
|
account->password = g_malloc(READ_BUF_SIZE);
|
||||||
log_error("Failed to read eval_password output");
|
|
||||||
g_strfreev(output);
|
|
||||||
output = NULL;
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
account->password = strdup(output[0]);
|
|
||||||
g_strfreev(output);
|
|
||||||
output = NULL;
|
|
||||||
|
|
||||||
if (!account->password) {
|
if (!account->password) {
|
||||||
log_error("Failed to allocate enough memory to read eval_password output");
|
log_error("Failed to allocate enough memory to read `eval_password` "
|
||||||
|
"output.");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
account->password = fgets(account->password, READ_BUF_SIZE, stream);
|
||||||
|
if (!account->password) {
|
||||||
|
log_error("Failed to read password from stream.");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
int exit_status = pclose(stream);
|
||||||
|
if (exit_status > 0) {
|
||||||
|
log_error("Command for `eval_password` returned error status (%s).",
|
||||||
|
exit_status);
|
||||||
|
return FALSE;
|
||||||
|
} else if (exit_status < 0) {
|
||||||
|
log_error("Failed to close stream for `eval_password` command output "
|
||||||
|
"(%s).",
|
||||||
|
strerror(errno));
|
||||||
|
return FALSE;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Remove leading and trailing whitespace from output.
|
||||||
|
g_strstrip(account->password);
|
||||||
|
if (!account->password) {
|
||||||
|
log_error("Empty password returned by `eval_password` command.");
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user