Commit ac04b917 ac04b91746a9192b6492fa43fe56200a8c21c65c by Sergey Poznyakoff

Fix handling of URL authentication credentials in SMTP AUTH.

Provide special functions for storing and retrieving URL from
mu_smtp_t object, instead of using MU_SMTP_PARAM_URL.  The major
drawback of the latter is that URLs in textual form can contain
obfuscated access credentials, which makes them unusable for
authentication.

* include/mailutils/smtp.h (mu_smtp_set_url)
(mu_smtp_get_url)
(mu_smtp_set_secret,mu_smtp_get_secret): New protos.
* include/mailutils/sys/smtp.h (_mu_smtp) <url>: New member.
* libproto/mailer/smtp_secret.c: New file.
* libproto/mailer/smtp_url.c: New file.
* libproto/mailer/Makefile.am (libmu_mailer_la_SOURCES): Add new files.
* libproto/mailer/smtp.c (smtp_open): Use mu_smtp_set_url to preserve
URL credentials.
* libproto/mailer/smtp_auth.c (_mu_smtp_fixup_params): Use smtp->url.
* libproto/mailer/smtp_create.c (mu_smtp_destroy): Destroy smtp->url.
* libproto/mailer/smtp_param.c (mu_smtp_set_param): Special
handling for MU_SMTP_PARAM_URL.
(mu_smtp_get_param): Likewise.
1 parent 0256b723
......@@ -55,6 +55,11 @@ int mu_smtp_disconnect (mu_smtp_t smtp);
int mu_smtp_ehlo (mu_smtp_t smtp);
int mu_smtp_set_param (mu_smtp_t smtp, int code, const char *val);
int mu_smtp_get_param (mu_smtp_t smtp, int code, const char **param);
int mu_smtp_set_url (mu_smtp_t smtp, mu_url_t url);
int mu_smtp_get_url (mu_smtp_t smtp, mu_url_t *purl);
int mu_smtp_set_secret (mu_smtp_t smtp, mu_secret_t secret);
int mu_smtp_get_secret (mu_smtp_t smtp, mu_secret_t *secret);
int mu_smtp_capa_test (mu_smtp_t smtp, const char *capa, const char **pret);
int mu_smtp_starttls (mu_smtp_t smtp);
......
......@@ -57,6 +57,7 @@ struct _mu_smtp
/* User-supplied data */
char *param[MU_SMTP_MAX_PARAM];
mu_url_t url;
mu_list_t authmech; /* List of allowed authentication mechs */
mu_secret_t secret;
......
......@@ -44,11 +44,13 @@ libmu_mailer_la_SOURCES = \
smtp_mech.c\
smtp_open.c\
smtp_param.c\
smtp_quit.c\
smtp_rcpt.c\
smtp_rset.c\
smtp_secret.c\
smtp_send.c\
smtp_starttls.c\
smtp_trace.c\
smtp_quit.c\
smtp_url.c\
remote.c
......
......@@ -162,8 +162,7 @@ smtp_open (mu_mailer_t mailer, int flags)
mu_smtp_trace_mask (smtp_mailer->smtp, MU_SMTP_TRACE_SET,
MU_XSCRIPT_PAYLOAD);
mu_smtp_set_param (smtp_mailer->smtp, MU_SMTP_PARAM_URL,
mu_url_to_string (mailer->url));
mu_smtp_set_url (smtp_mailer->smtp, mailer->url);
if (mu_url_sget_auth (mailer->url, &auth) == 0)
smtp_mailer_add_auth_mech (smtp_mailer, auth);
......
......@@ -53,7 +53,6 @@ static int
_mu_smtp_fixup_params (mu_smtp_t smtp)
{
const char *str;
mu_url_t url;
mu_ticket_t ticket = NULL;
int flags = 0;
int rc;
......@@ -67,26 +66,19 @@ _mu_smtp_fixup_params (mu_smtp_t smtp)
if ((flags & (_HAS_USERNAME|_HAS_PASSWORD)) == (_HAS_USERNAME|_HAS_PASSWORD))
return 0; /* Nothing to do */
if (!smtp->param[MU_SMTP_PARAM_URL])
if (!smtp->url)
return 0;
rc = mu_url_create (&url, smtp->param[MU_SMTP_PARAM_URL]);
if (rc)
{
mu_diag_output (MU_DIAG_ERROR, "cannot create URL: %s",
mu_strerror (rc));
return rc;
}
if (!(flags & _HAS_USERNAME))
{
rc = mu_url_sget_user (url, &str);
rc = mu_url_sget_user (smtp->url, &str);
if (rc == 0 &&
mu_smtp_set_param (smtp, MU_SMTP_PARAM_USERNAME, str) == 0)
flags |= _HAS_USERNAME;
}
if (!(flags & _HAS_PASSWORD) && mu_url_get_secret (url, &smtp->secret) == 0)
if (!(flags & _HAS_PASSWORD) &&
mu_url_get_secret (smtp->url, &smtp->secret) == 0)
flags |= _HAS_PASSWORD;
if ((!(flags & _HAS_USERNAME) ||
......@@ -94,18 +86,17 @@ _mu_smtp_fixup_params (mu_smtp_t smtp)
get_ticket (&ticket) == 0)
{
if (!(flags & _HAS_USERNAME) &&
mu_ticket_get_cred (ticket, url, "SMTP User: ",
mu_ticket_get_cred (ticket, smtp->url, "SMTP User: ",
&smtp->param[MU_SMTP_PARAM_USERNAME],
NULL) == 0)
flags |= _HAS_USERNAME;
if (!(flags & _HAS_PASSWORD) && !smtp->secret)
mu_ticket_get_cred (ticket, url, "SMTP Passwd: ",
mu_ticket_get_cred (ticket, smtp->url, "SMTP Passwd: ",
NULL, &smtp->secret);
mu_ticket_destroy (&ticket);
}
mu_url_destroy (&url);
return 0;
}
......
......@@ -22,6 +22,7 @@
#include <mailutils/list.h>
#include <mailutils/secret.h>
#include <mailutils/smtp.h>
#include <mailutils/url.h>
#include <mailutils/stream.h>
#include <mailutils/sys/smtp.h>
......@@ -66,6 +67,7 @@ mu_smtp_destroy (mu_smtp_t *psmtp)
mu_secret_password_unref (smtp->secret);
mu_secret_destroy (&smtp->secret);
}
mu_url_destroy (&smtp->url);
for (i = 0; i < MU_SMTP_MAX_PARAM; i++)
{
......
......@@ -25,6 +25,7 @@
#include <mailutils/cctype.h>
#include <mailutils/list.h>
#include <mailutils/secret.h>
#include <mailutils/url.h>
#include <mailutils/smtp.h>
#include <mailutils/sys/smtp.h>
......@@ -51,6 +52,18 @@ mu_smtp_set_param (mu_smtp_t smtp, int pcode, const char *newparam)
MU_SMTP_FCLR (smtp, _MU_SMTP_CLNPASS);
return mu_secret_create (&smtp->secret, newparam, strlen (newparam));
}
else if (pcode == MU_SMTP_PARAM_URL)
{
mu_url_t url;
int rc;
rc = mu_url_create (&url, newparam);
if (rc)
return rc;
mu_url_destroy (&smtp->url);
smtp->url = url;
return 0;
}
param = strdup (newparam);
if (!param)
......@@ -73,6 +86,14 @@ mu_smtp_get_param (mu_smtp_t smtp, int pcode, const char **pparam)
smtp->param[pcode] = (char*) mu_secret_password (smtp->secret);
MU_SMTP_FSET (smtp, _MU_SMTP_CLNPASS);
}
else if (pcode == MU_SMTP_PARAM_URL)
{
if (smtp->url)
{
*pparam = mu_url_to_string (smtp->url);
return 0;
}
}
*pparam = smtp->param[pcode];
return 0;
......
/* GNU Mailutils -- a suite of utilities for electronic mail
Copyright (C) 2010-2012 Free Software Foundation, Inc.
This library is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 3, or (at your option)
any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with GNU Mailutils. If not, see <http://www.gnu.org/licenses/>. */
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <mailutils/errno.h>
#include <mailutils/secret.h>
#include <mailutils/smtp.h>
#include <mailutils/sys/smtp.h>
int
mu_smtp_set_secret (mu_smtp_t smtp, mu_secret_t secret)
{
if (!smtp)
return EINVAL;
if (smtp->secret)
{
if (MU_SMTP_FISSET (smtp, _MU_SMTP_CLNPASS))
mu_secret_password_unref (smtp->secret);
mu_secret_destroy (&smtp->secret);
}
if (!secret)
return 0;
return mu_secret_dup (secret, &smtp->secret);
}
int
mu_smtp_get_secret (mu_smtp_t smtp, mu_secret_t *secret)
{
if (!smtp)
return EINVAL;
if (!smtp->secret)
return MU_ERR_NOENT;
*secret = smtp->secret;
mu_secret_ref (smtp->secret);
return 0;
}
/* GNU Mailutils -- a suite of utilities for electronic mail
Copyright (C) 2010-2012 Free Software Foundation, Inc.
This library is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 3, or (at your option)
any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with GNU Mailutils. If not, see <http://www.gnu.org/licenses/>. */
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <mailutils/errno.h>
#include <mailutils/url.h>
#include <mailutils/secret.h>
#include <mailutils/smtp.h>
#include <mailutils/sys/smtp.h>
int
mu_smtp_set_url (mu_smtp_t smtp, mu_url_t url)
{
if (!smtp)
return EINVAL;
mu_url_destroy (&smtp->url);
if (!url)
return 0;
return mu_url_dup (url, &smtp->url);
}
int
mu_smtp_get_url (mu_smtp_t smtp, mu_url_t *purl)
{
if (!smtp || !purl)
return EINVAL;
if (!smtp->url)
return MU_ERR_NOENT;
*purl = smtp->url;
return 0;
}