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); ...@@ -55,6 +55,11 @@ int mu_smtp_disconnect (mu_smtp_t smtp);
55 int mu_smtp_ehlo (mu_smtp_t smtp); 55 int mu_smtp_ehlo (mu_smtp_t smtp);
56 int mu_smtp_set_param (mu_smtp_t smtp, int code, const char *val); 56 int mu_smtp_set_param (mu_smtp_t smtp, int code, const char *val);
57 int mu_smtp_get_param (mu_smtp_t smtp, int code, const char **param); 57 int mu_smtp_get_param (mu_smtp_t smtp, int code, const char **param);
58 int mu_smtp_set_url (mu_smtp_t smtp, mu_url_t url);
59 int mu_smtp_get_url (mu_smtp_t smtp, mu_url_t *purl);
60 int mu_smtp_set_secret (mu_smtp_t smtp, mu_secret_t secret);
61 int mu_smtp_get_secret (mu_smtp_t smtp, mu_secret_t *secret);
62
58 int mu_smtp_capa_test (mu_smtp_t smtp, const char *capa, const char **pret); 63 int mu_smtp_capa_test (mu_smtp_t smtp, const char *capa, const char **pret);
59 int mu_smtp_starttls (mu_smtp_t smtp); 64 int mu_smtp_starttls (mu_smtp_t smtp);
60 65
......
...@@ -57,6 +57,7 @@ struct _mu_smtp ...@@ -57,6 +57,7 @@ struct _mu_smtp
57 57
58 /* User-supplied data */ 58 /* User-supplied data */
59 char *param[MU_SMTP_MAX_PARAM]; 59 char *param[MU_SMTP_MAX_PARAM];
60 mu_url_t url;
60 mu_list_t authmech; /* List of allowed authentication mechs */ 61 mu_list_t authmech; /* List of allowed authentication mechs */
61 mu_secret_t secret; 62 mu_secret_t secret;
62 63
......
...@@ -44,11 +44,13 @@ libmu_mailer_la_SOURCES = \ ...@@ -44,11 +44,13 @@ libmu_mailer_la_SOURCES = \
44 smtp_mech.c\ 44 smtp_mech.c\
45 smtp_open.c\ 45 smtp_open.c\
46 smtp_param.c\ 46 smtp_param.c\
47 smtp_quit.c\
47 smtp_rcpt.c\ 48 smtp_rcpt.c\
48 smtp_rset.c\ 49 smtp_rset.c\
50 smtp_secret.c\
49 smtp_send.c\ 51 smtp_send.c\
50 smtp_starttls.c\ 52 smtp_starttls.c\
51 smtp_trace.c\ 53 smtp_trace.c\
52 smtp_quit.c\ 54 smtp_url.c\
53 remote.c 55 remote.c
54 56
......
...@@ -162,8 +162,7 @@ smtp_open (mu_mailer_t mailer, int flags) ...@@ -162,8 +162,7 @@ smtp_open (mu_mailer_t mailer, int flags)
162 mu_smtp_trace_mask (smtp_mailer->smtp, MU_SMTP_TRACE_SET, 162 mu_smtp_trace_mask (smtp_mailer->smtp, MU_SMTP_TRACE_SET,
163 MU_XSCRIPT_PAYLOAD); 163 MU_XSCRIPT_PAYLOAD);
164 164
165 mu_smtp_set_param (smtp_mailer->smtp, MU_SMTP_PARAM_URL, 165 mu_smtp_set_url (smtp_mailer->smtp, mailer->url);
166 mu_url_to_string (mailer->url));
167 166
168 if (mu_url_sget_auth (mailer->url, &auth) == 0) 167 if (mu_url_sget_auth (mailer->url, &auth) == 0)
169 smtp_mailer_add_auth_mech (smtp_mailer, auth); 168 smtp_mailer_add_auth_mech (smtp_mailer, auth);
......
...@@ -53,7 +53,6 @@ static int ...@@ -53,7 +53,6 @@ static int
53 _mu_smtp_fixup_params (mu_smtp_t smtp) 53 _mu_smtp_fixup_params (mu_smtp_t smtp)
54 { 54 {
55 const char *str; 55 const char *str;
56 mu_url_t url;
57 mu_ticket_t ticket = NULL; 56 mu_ticket_t ticket = NULL;
58 int flags = 0; 57 int flags = 0;
59 int rc; 58 int rc;
...@@ -67,26 +66,19 @@ _mu_smtp_fixup_params (mu_smtp_t smtp) ...@@ -67,26 +66,19 @@ _mu_smtp_fixup_params (mu_smtp_t smtp)
67 if ((flags & (_HAS_USERNAME|_HAS_PASSWORD)) == (_HAS_USERNAME|_HAS_PASSWORD)) 66 if ((flags & (_HAS_USERNAME|_HAS_PASSWORD)) == (_HAS_USERNAME|_HAS_PASSWORD))
68 return 0; /* Nothing to do */ 67 return 0; /* Nothing to do */
69 68
70 if (!smtp->param[MU_SMTP_PARAM_URL]) 69 if (!smtp->url)
71 return 0; 70 return 0;
72 71
73 rc = mu_url_create (&url, smtp->param[MU_SMTP_PARAM_URL]);
74 if (rc)
75 {
76 mu_diag_output (MU_DIAG_ERROR, "cannot create URL: %s",
77 mu_strerror (rc));
78 return rc;
79 }
80
81 if (!(flags & _HAS_USERNAME)) 72 if (!(flags & _HAS_USERNAME))
82 { 73 {
83 rc = mu_url_sget_user (url, &str); 74 rc = mu_url_sget_user (smtp->url, &str);
84 if (rc == 0 && 75 if (rc == 0 &&
85 mu_smtp_set_param (smtp, MU_SMTP_PARAM_USERNAME, str) == 0) 76 mu_smtp_set_param (smtp, MU_SMTP_PARAM_USERNAME, str) == 0)
86 flags |= _HAS_USERNAME; 77 flags |= _HAS_USERNAME;
87 } 78 }
88 79
89 if (!(flags & _HAS_PASSWORD) && mu_url_get_secret (url, &smtp->secret) == 0) 80 if (!(flags & _HAS_PASSWORD) &&
81 mu_url_get_secret (smtp->url, &smtp->secret) == 0)
90 flags |= _HAS_PASSWORD; 82 flags |= _HAS_PASSWORD;
91 83
92 if ((!(flags & _HAS_USERNAME) || 84 if ((!(flags & _HAS_USERNAME) ||
...@@ -94,18 +86,17 @@ _mu_smtp_fixup_params (mu_smtp_t smtp) ...@@ -94,18 +86,17 @@ _mu_smtp_fixup_params (mu_smtp_t smtp)
94 get_ticket (&ticket) == 0) 86 get_ticket (&ticket) == 0)
95 { 87 {
96 if (!(flags & _HAS_USERNAME) && 88 if (!(flags & _HAS_USERNAME) &&
97 mu_ticket_get_cred (ticket, url, "SMTP User: ", 89 mu_ticket_get_cred (ticket, smtp->url, "SMTP User: ",
98 &smtp->param[MU_SMTP_PARAM_USERNAME], 90 &smtp->param[MU_SMTP_PARAM_USERNAME],
99 NULL) == 0) 91 NULL) == 0)
100 flags |= _HAS_USERNAME; 92 flags |= _HAS_USERNAME;
101 93
102 if (!(flags & _HAS_PASSWORD) && !smtp->secret) 94 if (!(flags & _HAS_PASSWORD) && !smtp->secret)
103 mu_ticket_get_cred (ticket, url, "SMTP Passwd: ", 95 mu_ticket_get_cred (ticket, smtp->url, "SMTP Passwd: ",
104 NULL, &smtp->secret); 96 NULL, &smtp->secret);
105 mu_ticket_destroy (&ticket); 97 mu_ticket_destroy (&ticket);
106 } 98 }
107 99
108 mu_url_destroy (&url);
109 return 0; 100 return 0;
110 } 101 }
111 102
......
...@@ -22,6 +22,7 @@ ...@@ -22,6 +22,7 @@
22 #include <mailutils/list.h> 22 #include <mailutils/list.h>
23 #include <mailutils/secret.h> 23 #include <mailutils/secret.h>
24 #include <mailutils/smtp.h> 24 #include <mailutils/smtp.h>
25 #include <mailutils/url.h>
25 #include <mailutils/stream.h> 26 #include <mailutils/stream.h>
26 #include <mailutils/sys/smtp.h> 27 #include <mailutils/sys/smtp.h>
27 28
...@@ -66,6 +67,7 @@ mu_smtp_destroy (mu_smtp_t *psmtp) ...@@ -66,6 +67,7 @@ mu_smtp_destroy (mu_smtp_t *psmtp)
66 mu_secret_password_unref (smtp->secret); 67 mu_secret_password_unref (smtp->secret);
67 mu_secret_destroy (&smtp->secret); 68 mu_secret_destroy (&smtp->secret);
68 } 69 }
70 mu_url_destroy (&smtp->url);
69 71
70 for (i = 0; i < MU_SMTP_MAX_PARAM; i++) 72 for (i = 0; i < MU_SMTP_MAX_PARAM; i++)
71 { 73 {
......
...@@ -25,6 +25,7 @@ ...@@ -25,6 +25,7 @@
25 #include <mailutils/cctype.h> 25 #include <mailutils/cctype.h>
26 #include <mailutils/list.h> 26 #include <mailutils/list.h>
27 #include <mailutils/secret.h> 27 #include <mailutils/secret.h>
28 #include <mailutils/url.h>
28 #include <mailutils/smtp.h> 29 #include <mailutils/smtp.h>
29 #include <mailutils/sys/smtp.h> 30 #include <mailutils/sys/smtp.h>
30 31
...@@ -51,6 +52,18 @@ mu_smtp_set_param (mu_smtp_t smtp, int pcode, const char *newparam) ...@@ -51,6 +52,18 @@ mu_smtp_set_param (mu_smtp_t smtp, int pcode, const char *newparam)
51 MU_SMTP_FCLR (smtp, _MU_SMTP_CLNPASS); 52 MU_SMTP_FCLR (smtp, _MU_SMTP_CLNPASS);
52 return mu_secret_create (&smtp->secret, newparam, strlen (newparam)); 53 return mu_secret_create (&smtp->secret, newparam, strlen (newparam));
53 } 54 }
55 else if (pcode == MU_SMTP_PARAM_URL)
56 {
57 mu_url_t url;
58 int rc;
59
60 rc = mu_url_create (&url, newparam);
61 if (rc)
62 return rc;
63 mu_url_destroy (&smtp->url);
64 smtp->url = url;
65 return 0;
66 }
54 67
55 param = strdup (newparam); 68 param = strdup (newparam);
56 if (!param) 69 if (!param)
...@@ -73,6 +86,14 @@ mu_smtp_get_param (mu_smtp_t smtp, int pcode, const char **pparam) ...@@ -73,6 +86,14 @@ mu_smtp_get_param (mu_smtp_t smtp, int pcode, const char **pparam)
73 smtp->param[pcode] = (char*) mu_secret_password (smtp->secret); 86 smtp->param[pcode] = (char*) mu_secret_password (smtp->secret);
74 MU_SMTP_FSET (smtp, _MU_SMTP_CLNPASS); 87 MU_SMTP_FSET (smtp, _MU_SMTP_CLNPASS);
75 } 88 }
89 else if (pcode == MU_SMTP_PARAM_URL)
90 {
91 if (smtp->url)
92 {
93 *pparam = mu_url_to_string (smtp->url);
94 return 0;
95 }
96 }
76 97
77 *pparam = smtp->param[pcode]; 98 *pparam = smtp->param[pcode];
78 return 0; 99 return 0;
......
1 /* GNU Mailutils -- a suite of utilities for electronic mail
2 Copyright (C) 2010-2012 Free Software Foundation, Inc.
3
4 This library is free software; you can redistribute it and/or modify
5 it under the terms of the GNU Lesser General Public License as published by
6 the Free Software Foundation; either version 3, or (at your option)
7 any later version.
8
9 This library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU Lesser General Public License for more details.
13
14 You should have received a copy of the GNU Lesser General Public License
15 along with GNU Mailutils. If not, see <http://www.gnu.org/licenses/>. */
16
17 #ifdef HAVE_CONFIG_H
18 # include <config.h>
19 #endif
20
21 #include <mailutils/errno.h>
22 #include <mailutils/secret.h>
23 #include <mailutils/smtp.h>
24 #include <mailutils/sys/smtp.h>
25
26 int
27 mu_smtp_set_secret (mu_smtp_t smtp, mu_secret_t secret)
28 {
29 if (!smtp)
30 return EINVAL;
31 if (smtp->secret)
32 {
33 if (MU_SMTP_FISSET (smtp, _MU_SMTP_CLNPASS))
34 mu_secret_password_unref (smtp->secret);
35 mu_secret_destroy (&smtp->secret);
36 }
37 if (!secret)
38 return 0;
39 return mu_secret_dup (secret, &smtp->secret);
40 }
41
42 int
43 mu_smtp_get_secret (mu_smtp_t smtp, mu_secret_t *secret)
44 {
45 if (!smtp)
46 return EINVAL;
47 if (!smtp->secret)
48 return MU_ERR_NOENT;
49 *secret = smtp->secret;
50 mu_secret_ref (smtp->secret);
51 return 0;
52 }
1 /* GNU Mailutils -- a suite of utilities for electronic mail
2 Copyright (C) 2010-2012 Free Software Foundation, Inc.
3
4 This library is free software; you can redistribute it and/or modify
5 it under the terms of the GNU Lesser General Public License as published by
6 the Free Software Foundation; either version 3, or (at your option)
7 any later version.
8
9 This library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU Lesser General Public License for more details.
13
14 You should have received a copy of the GNU Lesser General Public License
15 along with GNU Mailutils. If not, see <http://www.gnu.org/licenses/>. */
16
17 #ifdef HAVE_CONFIG_H
18 # include <config.h>
19 #endif
20
21 #include <mailutils/errno.h>
22 #include <mailutils/url.h>
23 #include <mailutils/secret.h>
24 #include <mailutils/smtp.h>
25 #include <mailutils/sys/smtp.h>
26
27 int
28 mu_smtp_set_url (mu_smtp_t smtp, mu_url_t url)
29 {
30 if (!smtp)
31 return EINVAL;
32 mu_url_destroy (&smtp->url);
33 if (!url)
34 return 0;
35 return mu_url_dup (url, &smtp->url);
36 }
37
38 int
39 mu_smtp_get_url (mu_smtp_t smtp, mu_url_t *purl)
40 {
41 if (!smtp || !purl)
42 return EINVAL;
43 if (!smtp->url)
44 return MU_ERR_NOENT;
45 *purl = smtp->url;
46 return 0;
47 }