summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarc Deslauriers <marc.deslauriers@ubuntu.com>2011-06-28 12:32:24 +0100
committerDavid Zeuthen <davidz@redhat.com>2011-08-01 10:00:07 -0400
commit4b4f6666ae66a554bfd7180ac99973a66db22a08 (patch)
tree0605a138616bd552c23024dc60d3cfadcdfdf3c1
parentec0fc445d0cbf96b8748003021c603d0303b5ef3 (diff)
Fix multi-line pam prompt handling
Some pam modules may attempt to display multi-line prompts to the user. In these cases, PolicyKit was failing. This patch fixes the issue by escaping the prompt before passing it and unescaping it again. Signed-off-by: David Zeuthen <davidz@redhat.com>
-rw-r--r--src/polkitagent/polkitagenthelper-pam.c14
-rw-r--r--src/polkitagent/polkitagentsession.c28
2 files changed, 24 insertions, 18 deletions
diff --git a/src/polkitagent/polkitagenthelper-pam.c b/src/polkitagent/polkitagenthelper-pam.c
index f777829..85a2671 100644
--- a/src/polkitagent/polkitagenthelper-pam.c
+++ b/src/polkitagent/polkitagenthelper-pam.c
@@ -226,6 +226,7 @@ conversation_function (int n, const struct pam_message **msg, struct pam_respons
struct pam_response *aresp;
char buf[PAM_MAX_RESP_SIZE];
int i;
+ gchar *escaped = NULL;
data = data;
if (n <= 0 || n > PAM_MAX_NUM_MSG)
@@ -257,14 +258,15 @@ conversation_function (int n, const struct pam_message **msg, struct pam_respons
#ifdef PAH_DEBUG
fprintf (stderr, "polkit-agent-helper-1: writing `%s' to stdout\n", msg[i]->msg);
#endif /* PAH_DEBUG */
- fputs (msg[i]->msg, stdout);
- if (strlen (msg[i]->msg) > 0 && msg[i]->msg[strlen (msg[i]->msg) - 1] != '\n')
- {
+ if (strlen (msg[i]->msg) > 0 && msg[i]->msg[strlen (msg[i]->msg) - 1] == '\n')
+ msg[i]->msg[strlen (msg[i]->msg) - 1] == '\0';
+ escaped = g_strescape (msg[i]->msg, NULL);
+ fputs (escaped, stdout);
+ g_free (escaped);
#ifdef PAH_DEBUG
- fprintf (stderr, "polkit-agent-helper-1: writing newline to stdout\n");
+ fprintf (stderr, "polkit-agent-helper-1: writing newline to stdout\n");
#endif /* PAH_DEBUG */
- fputc ('\n', stdout);
- }
+ fputc ('\n', stdout);
#ifdef PAH_DEBUG
fprintf (stderr, "polkit-agent-helper-1: flushing stdout\n");
#endif /* PAH_DEBUG */
diff --git a/src/polkitagent/polkitagentsession.c b/src/polkitagent/polkitagentsession.c
index bb467be..ad3bbc3 100644
--- a/src/polkitagent/polkitagentsession.c
+++ b/src/polkitagent/polkitagentsession.c
@@ -441,11 +441,12 @@ io_watch_have_data (GIOChannel *channel,
gpointer user_data)
{
PolkitAgentSession *session = POLKIT_AGENT_SESSION (user_data);
- gchar *line;
+ gchar *line, *unescaped;
GError *error;
error = NULL;
line = NULL;
+ unescaped = NULL;
if (!session->helper_is_running)
{
@@ -473,42 +474,44 @@ io_watch_have_data (GIOChannel *channel,
if (strlen (line) > 0 && line[strlen (line) - 1] == '\n')
line[strlen (line) - 1] = '\0';
+ unescaped = g_strcompress (line);
+
if (G_UNLIKELY (_show_debug ()))
- g_print ("PolkitAgentSession: read `%s' from helper\n", line);
+ g_print ("PolkitAgentSession: read `%s' from helper\n", unescaped);
- if (g_str_has_prefix (line, "PAM_PROMPT_ECHO_OFF "))
+ if (g_str_has_prefix (unescaped, "PAM_PROMPT_ECHO_OFF "))
{
- const gchar *s = line + sizeof "PAM_PROMPT_ECHO_OFF " - 1;
+ const gchar *s = unescaped + sizeof "PAM_PROMPT_ECHO_OFF " - 1;
if (G_UNLIKELY (_show_debug ()))
g_print ("PolkitAgentSession: emitting ::request('%s', FALSE)\n", s);
g_signal_emit_by_name (session, "request", s, FALSE);
}
- else if (g_str_has_prefix (line, "PAM_PROMPT_ECHO_ON "))
+ else if (g_str_has_prefix (unescaped, "PAM_PROMPT_ECHO_ON "))
{
- const gchar *s = line + sizeof "PAM_PROMPT_ECHO_ON " - 1;
+ const gchar *s = unescaped + sizeof "PAM_PROMPT_ECHO_ON " - 1;
if (G_UNLIKELY (_show_debug ()))
g_print ("PolkitAgentSession: emitting ::request('%s', TRUE)\n", s);
g_signal_emit_by_name (session, "request", s, TRUE);
}
- else if (g_str_has_prefix (line, "PAM_ERROR_MSG "))
+ else if (g_str_has_prefix (unescaped, "PAM_ERROR_MSG "))
{
- const gchar *s = line + sizeof "PAM_ERROR_MSG " - 1;
+ const gchar *s = unescaped + sizeof "PAM_ERROR_MSG " - 1;
if (G_UNLIKELY (_show_debug ()))
g_print ("PolkitAgentSession: emitting ::show-error('%s')\n", s);
g_signal_emit_by_name (session, "show-error", s);
}
- else if (g_str_has_prefix (line, "PAM_TEXT_INFO "))
+ else if (g_str_has_prefix (unescaped, "PAM_TEXT_INFO "))
{
- const gchar *s = line + sizeof "PAM_TEXT_INFO " - 1;
+ const gchar *s = unescaped + sizeof "PAM_TEXT_INFO " - 1;
if (G_UNLIKELY (_show_debug ()))
g_print ("PolkitAgentSession: emitting ::show-info('%s')\n", s);
g_signal_emit_by_name (session, "show-info", s);
}
- else if (g_str_has_prefix (line, "SUCCESS"))
+ else if (g_str_has_prefix (unescaped, "SUCCESS"))
{
complete_session (session, TRUE);
}
- else if (g_str_has_prefix (line, "FAILURE"))
+ else if (g_str_has_prefix (unescaped, "FAILURE"))
{
complete_session (session, FALSE);
}
@@ -521,6 +524,7 @@ io_watch_have_data (GIOChannel *channel,
out:
g_free (line);
+ g_free (unescaped);
/* keep the IOChannel around */
return TRUE;