Commit 558a5b14 558a5b14c77602a3e416cd37e1e9bb4685967370 by Sergey Poznyakoff

* include/mailutils/secret.h: New file.

* include/mailutils/types.hin (mu_secret_t): New type.
* include/mailutils/auth.h (mu_ticket_destroy): Remove 2nd arg (owner).
(mu_ticket_ref, mu_ticket_unref): New functions.
(mu_ticket_set_destroy): New function.
(mu_ticket_set_pop): Remove.
(mu_ticket_get_cred, mu_ticket_set_get_cred): New functions.
(mu_ticket_get_data): Return data pointer.
(mu_ticket_set_secret, mu_ticket_set_plain): New functions.
(mu_wicket_create): Remove 2nd arg.
(mu_wicket_set_filename, mu_wicket_get_filename): Remove.
(mu_wicket_set_ticket): Remove.
(mu_wicket_get_ticket): Change proto.
(mu_wicket_set_destroy, mu_wicket_set_data)
(mu_wicket_get_data, mu_wicket_set_get_ticket): New functions.
(mu_file_wicket_create): New function.
* include/mailutils/mailutils.h: Include secret.h
[MU_COMPAT]: Remove.
* include/mailutils/url.h (mu_url_sget_passwd, mu_url_aget_passwd)
(mu_url_get_passwd)
(mu_url_get_secret): New function.

* libproto/include/auth0.h: Rewrite.
* libproto/include/imap0.h (struct _f_imap): Replace passwd with
mu_secret_t secret.
* libproto/include/url0.h (struct _mu_url): Replace passwd with
mu_secret_t secret.
(_get_passwd): Replace with _get_secret

* mailbox/secret.c: New function.
* mailbox/Makefile.am (libmailutils_la_SOURCES): Add secret.c.

* mailbox/ticket.c: Rewrite from scratch.
* mailbox/wicket.c: Rewrite from scratch.

* libproto/imap/folder.c: Rewrite using mu_secret_t.
* libproto/pop/mbox.c: Rewrite using mu_secret_t.

* libproto/mailer/prog.c, libproto/mailer/sendmail.c,
mailbox/auth.c, mailbox/url.c, movemail/movemail.c: Reflect changes
to ticket/wicket system.
* mailbox/mbx_default.c: Use new mu_wicket_t functions.

* python/libmu_py/auth.c (api_wicket_get_filename)
(api_wicket_set_filename): Remove. Not applicable any more.
* python/libmu_py/url.c (api_url_get_passwd): Temporarly
commented out.

* include/mailutils/Makefile.am (pkginclude_HEADERS): Add secret.h.
* examples/url-parse.c: Use mu_secret_t calls.

* imap4d/namespace.c: Minor changes.
* libmu_auth/pam.c: Likewise.
1 parent cbdb11e1
GNU mailutils NEWS -- history of user-visible changes. 2009-04-14
GNU mailutils NEWS -- history of user-visible changes. 2009-05-25
Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007,
2008, 2009 Free Software Foundation, Inc.
See the end of file for copying conditions.
......@@ -20,6 +20,10 @@ namespace and visible home directory.
* API
* Wicket/Ticket functions
[FIXME: Describe]
* New mailbox formats
Three new append-only mailbox formats are introduced. The URL syntax of
......
/* GNU Mailutils -- a suite of utilities for electronic mail
Copyright (C) 1999, 2000, 2001, 2007 Free Software Foundation, Inc.
Copyright (C) 1999, 2000, 2001, 2007, 2009 Free Software Foundation, Inc.
GNU Mailutils is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
......@@ -25,6 +25,7 @@
#include <mailutils/error.h>
#include <mailutils/errno.h>
#include <mailutils/url.h>
#include <mailutils/secret.h>
#define CAT2(a,b) a ## b
......@@ -84,6 +85,7 @@ main ()
{
int rc;
const char *buf;
mu_secret_t secret;
str[strlen (str) - 1] = '\0'; /* chop newline */
if (strspn (str, " \t") == strlen (str))
......@@ -104,7 +106,21 @@ main ()
GET_AND_PRINT (scheme, u, buf, rc);
GET_AND_PRINT (user, u, buf, rc);
GET_AND_PRINT (passwd, u, buf, rc);
rc = mu_url_get_secret (u, &secret);
if (rc == MU_ERR_NOENT)
printf ("\tpasswd <>\n");
else if (rc)
{
mu_error ("cannot get %s: %s", "passwd", mu_strerror (rc));
exit (1);
}
else
{
printf ("\tpasswd <%s>\n", mu_secret_password (secret));
mu_secret_password_unref (secret);
}
GET_AND_PRINT (auth, u, buf, rc);
GET_AND_PRINT (host, u, buf, rc);
......
......@@ -23,8 +23,8 @@ typedef int (*nsfp_t) (void *closure, int ns, char *path, int delim);
mu_list_t namespace[NS_MAX];
static char *
printable_pathname (char *str)
static const char *
printable_pathname (const char *str)
{
if (strncmp (str, imap4d_homedir, strlen (imap4d_homedir)) == 0)
{
......@@ -39,7 +39,7 @@ static int
print_namespace_fun (void *item, void *data)
{
int *pcount = data;
char *dir = printable_pathname (item);
const char *dir = printable_pathname (item);
char *suf = (dir[0] && dir[strlen (dir) - 1] != '/') ? "/" : "";
if ((*pcount)++)
util_send (" ");
......
......@@ -85,6 +85,7 @@ pkginclude_HEADERS = \
refcount.h\
registrar.h\
sha1.h\
secret.h\
server.h\
sieve.h\
stream.h\
......
/* GNU Mailutils -- a suite of utilities for electronic mail
Copyright (C) 1999, 2000, 2001, 2005, 2007 Free Software Foundation, Inc.
Copyright (C) 1999, 2000, 2001, 2005, 2007,
2009 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
......@@ -25,16 +26,29 @@
extern "C" {
#endif
extern int mu_ticket_create (mu_ticket_t *, void *owner);
extern void mu_ticket_destroy (mu_ticket_t *, void *owner);
extern int mu_ticket_set_destroy (mu_ticket_t, void (*) (mu_ticket_t), void *);
extern int mu_ticket_create (mu_ticket_t *, void *);
extern int mu_ticket_ref (mu_ticket_t);
extern int mu_ticket_unref (mu_ticket_t);
extern void mu_ticket_destroy (mu_ticket_t *);
extern int mu_ticket_set_destroy (mu_ticket_t,
void (*) (mu_ticket_t), void *);
extern void *mu_ticket_get_owner (mu_ticket_t);
extern int mu_ticket_set_pop (mu_ticket_t,
int (*_pop) (mu_ticket_t, mu_url_t, const char *, char **), void *);
extern int mu_ticket_pop (mu_ticket_t, mu_url_t, const char *, char **);
extern int mu_ticket_get_cred (mu_ticket_t ticket,
mu_url_t url, const char *challenge,
char **pplain, mu_secret_t *psec);
extern int mu_ticket_set_get_cred (mu_ticket_t,
int (*) (mu_ticket_t, mu_url_t,
const char *,
char **, mu_secret_t *),
void *);
extern int mu_ticket_set_data (mu_ticket_t, void *, void *owner);
extern int mu_ticket_get_data (mu_ticket_t, void **);
extern void *mu_ticket_get_data (mu_ticket_t);
extern int mu_ticket_set_secret (mu_ticket_t ticket, mu_secret_t secret);
int mu_ticket_set_plain (mu_ticket_t ticket, const char *text);
extern int mu_authority_create (mu_authority_t *, mu_ticket_t, void *);
extern void mu_authority_destroy (mu_authority_t *, void *);
......@@ -42,19 +56,25 @@ extern void *mu_authority_get_owner (mu_authority_t);
extern int mu_authority_set_ticket (mu_authority_t, mu_ticket_t);
extern int mu_authority_get_ticket (mu_authority_t, mu_ticket_t *);
extern int mu_authority_authenticate (mu_authority_t);
extern int mu_authority_set_authenticate (mu_authority_t,
int (*_authenticate) (mu_authority_t), void *);
extern int mu_authority_set_authenticate (mu_authority_t,
int (*_authenticate) (mu_authority_t), void *);
extern int mu_authority_create_null (mu_authority_t *pauthority, void *owner);
extern int mu_wicket_create (mu_wicket_t *, const char *);
extern void mu_wicket_destroy (mu_wicket_t *);
extern int mu_wicket_set_filename (mu_wicket_t, const char *);
extern int mu_wicket_get_filename (mu_wicket_t, char *, size_t, size_t *);
extern int mu_wicket_set_ticket (mu_wicket_t,
int (*) (mu_wicket_t, const char *,
const char *, mu_ticket_t *));
extern int mu_wicket_get_ticket (mu_wicket_t, mu_ticket_t *, const char *, const char *);
extern int mu_wicket_create (mu_wicket_t *);
extern int mu_wicket_get_ticket (mu_wicket_t wicket, const char *user,
mu_ticket_t *pticket);
extern int mu_wicket_ref (mu_wicket_t wicket);
extern int mu_wicket_unref (mu_wicket_t wicket);
extern void mu_wicket_destroy (mu_wicket_t *pwicket);
extern int mu_wicket_set_destroy (mu_wicket_t wicket,
void (*_destroy) (mu_wicket_t));
extern int mu_wicket_set_data (mu_wicket_t wicket, void *data);
extern void *mu_wicket_get_data (mu_wicket_t wicket);
extern int mu_wicket_set_get_ticket (mu_wicket_t wicket,
int (*_get_ticket) (mu_wicket_t, void *,
const char *, mu_ticket_t *));
extern int mu_file_wicket_create (mu_wicket_t *pwicket, const char *filename);
#ifdef __cplusplus
}
......
......@@ -62,9 +62,6 @@
#include <mailutils/version.h>
#include <mailutils/vartab.h>
#include <mailutils/io.h>
#ifdef MU_COMPAT
# error "Version 0.6 is no longer supported. Please, update your program."
#endif
#include <mailutils/secret.h>
/* EOF */
......
/* GNU Mailutils -- a suite of utilities for electronic mail
Copyright (C) 2009 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 of the License, 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 this library; if not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301 USA */
#ifndef _MAILUTILS_SECRET_H
#define _MAILUTILS_SECRET_H
#include <mailutils/types.h>
#ifdef __cplusplus
extern "C" {
#endif
int mu_secret_create (mu_secret_t *psec, const char *value, size_t len);
int mu_secret_dup (mu_secret_t sec, mu_secret_t *newsec);
void mu_secret_destroy (mu_secret_t *psec);
const char *mu_secret_password (mu_secret_t sec);
void mu_secret_password_unref (mu_secret_t sec);
size_t mu_secret_length (mu_secret_t sec);
void mu_secret_ref (mu_secret_t sec);
int mu_secret_unref (mu_secret_t sec);
#ifdef __cplusplus
}
#endif
#endif
......@@ -112,6 +112,7 @@ typedef struct _mu_ip_server *mu_ip_server_t;
typedef struct _mu_m_server *mu_m_server_t;
typedef struct _mu_opool *mu_opool_t;
typedef struct _mu_progmailer *mu_progmailer_t;
typedef struct _mu_secret *mu_secret_t;
#define MU_FOLDER_ATTRIBUTE_DIRECTORY 0x001
#define MU_FOLDER_ATTRIBUTE_FILE 0x002
......
......@@ -41,9 +41,7 @@ extern int mu_url_sget_user (const mu_url_t, const char **);
extern int mu_url_aget_user (const mu_url_t, char **);
extern int mu_url_get_user (const mu_url_t, char *, size_t, size_t *);
extern int mu_url_sget_passwd (const mu_url_t, const char **);
extern int mu_url_aget_passwd (const mu_url_t, char **);
extern int mu_url_get_passwd (const mu_url_t, char *, size_t, size_t *);
extern int mu_url_get_secret (const mu_url_t url, mu_secret_t *psecret);
extern int mu_url_sget_auth (const mu_url_t, const char **);
extern int mu_url_aget_auth (const mu_url_t, char **);
......
/* GNU Mailutils -- a suite of utilities for electronic mail
Copyright (C) 2002, 2007, 2008 Free Software Foundation, Inc.
Copyright (C) 2002, 2007, 2008, 2009 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
......@@ -64,6 +64,10 @@ static char *_user;
while (0)
#ifndef PAM_AUTHTOK_RECOVER_ERR
# define PAM_AUTHTOK_RECOVER_ERR PAM_CONV_ERR
#endif
static int
mu_pam_conv (int num_msg, const struct pam_message **msg,
struct pam_response **resp, void *appdata_ptr MU_ARG_UNUSED)
......
......@@ -50,6 +50,7 @@
#include <mailutils/argcv.h>
#include <mailutils/tls.h>
#include <mailutils/nls.h>
#include <mailutils/secret.h>
/* For dbg purposes set to one to see different level of traffic. */
/* Print to stderr the command sent to the IMAP server. */
......@@ -181,40 +182,42 @@ authenticate_imap_login (mu_authority_t auth)
mu_authority_get_ticket (auth, &ticket);
if (f_imap->user)
free (f_imap->user);
if (f_imap->passwd)
free (f_imap->passwd);
/* Was it in the URL? */
status = mu_url_aget_user (folder->url, &f_imap->user);
if (status == MU_ERR_NOENT)
mu_ticket_pop (ticket, folder->url, "Imap User: ", &f_imap->user);
status = mu_ticket_get_cred (ticket, folder->url,
"Imap User: ", &f_imap->user, NULL);
if (status == MU_ERR_NOENT || f_imap->user == NULL)
return MU_ERR_NOUSERNAME;
else if (status)
return status;
status = mu_url_aget_passwd (folder->url, &f_imap->passwd);
status = mu_url_get_secret (folder->url, &f_imap->secret);
if (status == MU_ERR_NOENT)
mu_ticket_pop (ticket, folder->url, "Imap Passwd: ",
&f_imap->passwd);
status = mu_ticket_get_cred (ticket, folder->url,
"Imap Passwd: ",
NULL, &f_imap->secret);
if (status == MU_ERR_NOENT || !f_imap->secret)
/* FIXME: Is this always right? The user might legitimately have
no password */
return MU_ERR_NOPASSWORD;
else if (status)
return status;
if (f_imap->user == NULL)
return MU_ERR_NOUSERNAME;
if (f_imap->passwd == NULL)
return MU_ERR_NOPASSWORD;
status = imap_writeline (f_imap, "g%u LOGIN \"%s\" \"%s\"\r\n",
f_imap->seq, f_imap->user, f_imap->passwd);
f_imap->seq, f_imap->user,
mu_secret_password (f_imap->secret));
mu_secret_password_unref (f_imap->secret);
mu_secret_unref (f_imap->secret);
f_imap->secret = NULL;
CHECK_ERROR_CLOSE (folder, f_imap, status);
MU_DEBUG2 (folder->debug, MU_DEBUG_TRACE, "g%u LOGIN %s *\n",
f_imap->seq, f_imap->user);
f_imap->seq++;
free (f_imap->user);
f_imap->user = NULL;
/* We have to nuke the passwd. */
memset (f_imap->passwd, '\0', strlen (f_imap->passwd));
free (f_imap->passwd);
f_imap->passwd = NULL;
f_imap->secret = NULL;
f_imap->state = IMAP_LOGIN;
}
......
/* GNU Mailutils -- a suite of utilities for electronic mail
Copyright (C) 1999, 2000, 2001, 2005, 2007 Free Software Foundation, Inc.
Copyright (C) 1999, 2000, 2001, 2005, 2007,
2009 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
......@@ -33,11 +34,17 @@ extern "C" {
struct _mu_ticket
{
void *owner;
char *challenge;
void *owner; /* Object owner. Not actually needed, but retained
for a while. */
unsigned int refcnt; /* Reference counter */
char *plain; /* Plaintext credential (if any) */
mu_secret_t secret; /* Secret credential (if any) */
void (*_destroy) (mu_ticket_t); /* Destroy function */
/* Function for obtaining credentials */
int (*_get_cred) (mu_ticket_t, mu_url_t, const char *, char **,
mu_secret_t *);
/* Additional data for _get_cred */
void *data;
int (*_pop) (mu_ticket_t, mu_url_t, const char *challenge, char **);
void (*_destroy) (mu_ticket_t);
};
struct _mu_authority
......@@ -49,8 +56,10 @@ struct _mu_authority
struct _mu_wicket
{
char *filename;
int (*_get_ticket) (mu_wicket_t, const char *, const char *, mu_ticket_t *);
unsigned int refcnt; /* Reference counter */
void *data;
int (*_get_ticket) (mu_wicket_t, void *, const char *, mu_ticket_t *);
void (*_destroy) (mu_wicket_t);
};
......
/* GNU Mailutils -- a suite of utilities for electronic mail
Copyright (C) 1999, 2000, 2001, 2005, 2007 Free Software Foundation, Inc.
Copyright (C) 1999, 2000, 2001, 2005, 2007,
2009 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
......@@ -178,7 +179,7 @@ struct _f_imap
/* Login */
char *user;
char *passwd;
mu_secret_t secret;
/* AUTHENTICATE states */
enum imap_auth_state auth_state;
......
......@@ -35,7 +35,7 @@ struct _mu_url
char *name;
char *scheme;
char *user;
char *passwd;
mu_secret_t secret;
char *auth;
char *host;
long port;
......@@ -53,7 +53,7 @@ struct _mu_url
/* Methods */
int (*_get_scheme) (const mu_url_t, char *, size_t, size_t *);
int (*_get_user) (const mu_url_t, char *, size_t, size_t *);
int (*_get_passwd) (const mu_url_t, char *, size_t, size_t *);
int (*_get_secret) (const mu_url_t, mu_secret_t *);
int (*_get_auth) (const mu_url_t, char *, size_t, size_t *);
int (*_get_host) (const mu_url_t, char *, size_t, size_t *);
int (*_get_port) (const mu_url_t, long *);
......
......@@ -69,7 +69,7 @@ static int
_url_prog_init (mu_url_t url)
{
/* not valid in a prog url */
if (url->passwd || url->auth || url->host || url->port)
if (url->secret || url->auth || url->host || url->port)
return EINVAL;
if (!url->path)
return EINVAL;
......
......@@ -53,7 +53,7 @@ static int
_url_sendmail_init (mu_url_t url)
{
/* not valid in a sendmail url */
if (url->user || url->passwd || url->auth || url->qargc
if (url->user || url->secret || url->auth || url->qargc
|| url->host || url->port)
return EINVAL;
......
......@@ -51,6 +51,7 @@
#include <mailutils/property.h>
#include <mailutils/stream.h>
#include <mailutils/url.h>
#include <mailutils/secret.h>
#include <mailutils/tls.h>
#include <mailutils/md5.h>
#include <mailutils/io.h>
......@@ -207,7 +208,8 @@ struct _pop_data
int is_updated;
char *user; /* Temporary holders for user and passwd. */
char *passwd; /* Temporary holders for passwd memset (0) when finish. */
mu_secret_t secret;
char *digest;
mu_mailbox_t mbox; /* Back pointer. */
} ;
......@@ -532,22 +534,23 @@ _pop_user (mu_authority_t auth)
CHECK_ERROR_CLOSE (mbox, mpd, EACCES);
}
status = pop_get_passwd (auth);
if (status != 0 || mpd->passwd == NULL || mpd->passwd[0] == '\0')
if (status != 0 || mpd->secret == NULL)
{
pop_writeline (mpd, "QUIT\r\n");
MU_DEBUG (mbox->debug, MU_DEBUG_PROT, mpd->buffer);
pop_write (mpd);
CHECK_ERROR_CLOSE (mbox, mpd, MU_ERR_NOPASSWORD);
}
status = pop_writeline (mpd, "PASS %s\r\n", mpd->passwd);
status = pop_writeline (mpd, "PASS %s\r\n",
mu_secret_password (mpd->secret));
mu_secret_password_unref (mpd->secret);
mu_secret_unref (mpd->secret);
mpd->secret = NULL;
MU_DEBUG (mbox->debug, MU_DEBUG_PROT, "PASS ***\n");
/* Leave not trail of the passwd. */
memset (mpd->passwd, '\0', strlen (mpd->passwd));
free (mpd->passwd);
mpd->passwd = NULL;
CHECK_ERROR_CLOSE (mbox, mpd, status);
mpd->state = POP_AUTH_PASS;
/* FIXME: Merge these two cases */
case POP_AUTH_PASS:
/* Send passwd. */
status = pop_write (mpd);
......@@ -599,7 +602,7 @@ _pop_apop (mu_authority_t auth)
/* Fetch the secret from them. */
status = pop_get_passwd (auth);
if (status != 0 || mpd->passwd == NULL || mpd->passwd[0] == '\0')
if (status != 0 || mpd->secret == NULL)
{
CHECK_ERROR_CLOSE (mbox, mpd, EINVAL);
}
......@@ -610,14 +613,14 @@ _pop_apop (mu_authority_t auth)
{
CHECK_ERROR_CLOSE (mbox, mpd, status);
}
status = pop_writeline (mpd, "APOP %s %s\r\n", mpd->user, mpd->passwd);
status = pop_writeline (mpd, "APOP %s %s\r\n", mpd->user, mpd->digest);
MU_DEBUG (mbox->debug, MU_DEBUG_PROT, mpd->buffer);
/* We have to obscure the md5 string. */
memset (mpd->passwd, '\0', strlen (mpd->passwd));
memset (mpd->digest, '\0', strlen (mpd->digest));
free (mpd->user);
free (mpd->passwd);
free (mpd->digest);
mpd->user = NULL;
mpd->passwd = NULL;
mpd->digest = NULL;
CHECK_ERROR_CLOSE (mbox, mpd, status);
mpd->state = POP_APOP;
......@@ -2114,10 +2117,11 @@ pop_get_user (mu_authority_t auth)
/* Was it in the URL? */
status = mu_url_aget_user (mbox->url, &mpd->user);
if (status == MU_ERR_NOENT)
mu_ticket_pop (ticket, mbox->url, "Pop User: ", &mpd->user);
else if (status)
return status;
return 0;
status = mu_ticket_get_cred (ticket, mbox->url, "Pop User: ",
&mpd->user, NULL);
if (status == MU_ERR_NOENT || mpd->user == NULL)
return MU_ERR_NOUSERNAME;
return status;
}
/* Extract the User from the URL or the ticket. */
......@@ -2131,17 +2135,15 @@ pop_get_passwd (mu_authority_t auth)
int status;
mu_authority_get_ticket (auth, &ticket);
if (mpd->passwd)
{
free (mpd->passwd);
mpd->passwd = NULL;
}
/* Was it in the URL? */
status = mu_url_aget_passwd (mbox->url, &mpd->passwd);
status = mu_url_get_secret (mbox->url, &mpd->secret);
if (status == MU_ERR_NOENT)
mu_ticket_pop (ticket, mbox->url, "Pop Passwd: ", &mpd->passwd);
else if (status)
return status;
status = mu_ticket_get_cred (ticket, mbox->url, "Pop Passwd: ",
NULL, &mpd->secret);
if (status == MU_ERR_NOENT || !mpd->secret)
/* FIXME: Is this always right? The user might legitimately have
no password */
return MU_ERR_NOPASSWORD;
return 0;
}
......@@ -2189,15 +2191,19 @@ pop_get_md5 (pop_data_t mpd)
mu_md5_init_ctx (&md5context);
mu_md5_process_bytes (timestamp, strlen (timestamp), &md5context);
mu_md5_process_bytes (mpd->passwd, strlen (mpd->passwd), &md5context);
mu_md5_process_bytes (mu_secret_password (mpd->secret),
mu_secret_length (mpd->secret),
&md5context);
mu_secret_password_unref (mpd->secret);
mu_secret_unref (mpd->secret);
mpd->secret = NULL;
mu_md5_finish_ctx (&md5context, md5digest);
for (tmp = digest, n = 0; n < 16; n++, tmp += 2)
sprintf (tmp, "%02x", md5digest[n]);
*tmp = '\0';
free (timestamp);
free (mpd->passwd);
mpd->passwd = strdup (digest);
mpd->digest = strdup (digest);
return 0;
}
......
......@@ -113,6 +113,7 @@ libmailutils_la_SOURCES = \
refcount.c\
rfc2047.c\
sha1.c\
secret.c\
server.c\
socket_stream.c\
stream.c\
......
/* GNU Mailutils -- a suite of utilities for electronic mail
Copyright (C) 1999, 2000, 2001, 2004, 2005,
2007 Free Software Foundation, Inc.
2007, 2009 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
......@@ -68,7 +68,7 @@ mu_authority_destroy (mu_authority_t *pauthority, void *owner)
mu_authority_t authority = *pauthority;
if (authority->owner == owner)
{
mu_ticket_destroy (&(authority->ticket), authority);
mu_ticket_destroy (&authority->ticket);
free (authority);
}
*pauthority = NULL;
......@@ -87,7 +87,7 @@ mu_authority_set_ticket (mu_authority_t authority, mu_ticket_t ticket)
if (authority == NULL)
return EINVAL;
if (authority->ticket)
mu_ticket_destroy (&(authority->ticket), authority);
mu_ticket_destroy (&authority->ticket);
authority->ticket = ticket;
return 0;
}
......
......@@ -350,11 +350,11 @@ attach_auth_ticket (mu_mailbox_t mbox)
MU_DEBUG1 (mbox->debug, MU_DEBUG_TRACE1,
"Reading user ticket file %s\n", filename);
if ((rc = mu_wicket_create (&wicket, filename)) == 0)
if ((rc = mu_file_wicket_create (&wicket, filename)) == 0)
{
mu_ticket_t ticket;
if ((rc = mu_wicket_get_ticket (wicket, &ticket, 0, 0)) == 0)
if ((rc = mu_wicket_get_ticket (wicket, NULL, &ticket)) == 0)
{
rc = mu_authority_set_ticket (auth, ticket);
MU_DEBUG1 (mbox->debug, MU_DEBUG_TRACE1,
......
/* GNU Mailutils -- a suite of utilities for electronic mail
Copyright (C) 2009 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 of the License, 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 this library; if not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301 USA */
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <stdlib.h>
#include <string.h>
#include <mailutils/types.h>
#include <mailutils/secret.h>
#include <mailutils/errno.h>
struct _mu_secret
{
unsigned int refcnt; /* Number of references to this object */
size_t length; /* Secret length */
unsigned char *obptr; /* Obfuscated data */
unsigned char *clptr; /* Cleartext data */
unsigned int clref; /* Number of references to clptr returned
this far */
};
static unsigned char xchar;
static void
obfuscate (const unsigned char *input, unsigned char *output, size_t len)
{
if (!xchar)
xchar = random () % 255;
while (len--)
*output++ = *input++ ^ xchar;
}
int
mu_secret_create (mu_secret_t *psec, const char *value, size_t len)
{
mu_secret_t sec;
sec = calloc (1, sizeof (sec[0]) + 2 * (len + 1));
if (!sec)
return ENOMEM;
sec->obptr = (unsigned char*)(sec + 1);
sec->clptr = sec->obptr + len + 1;
obfuscate (value, sec->obptr, len);
sec->length = len;
*psec = sec;
mu_secret_ref (sec);
return 0;
}
int
mu_secret_dup (mu_secret_t sec, mu_secret_t *newsec)
{
const char *pass = mu_secret_password (sec);
int rc = mu_secret_create (newsec, pass, strlen (pass));
mu_secret_password_unref (sec);
return rc;
}
void
mu_secret_ref (mu_secret_t sec)
{
if (sec)
sec->refcnt++;
}
/* Decrement reference counter in SEC. If it falls to 0, free memory
allocated for SEC and return 0. Otherwise, return MU_ERR_EXISTS,
indicating that someone else is still holding it.
Return EINVAL if sec==NULL. */
int
mu_secret_unref (mu_secret_t sec)
{
if (sec)
{
if (sec->refcnt)
sec->refcnt--;
if (sec->refcnt == 0)
{
memset (sec->clptr, 0, sec->length);
memset (sec->obptr, 0, sec->length);
free (sec);
return 0;
}
return MU_ERR_EXISTS;
}
return EINVAL;
}
void
mu_secret_destroy (mu_secret_t *psec)
{
if (psec && *psec && mu_secret_unref (*psec) == 0)
*psec = NULL;
}
const char *
mu_secret_password (mu_secret_t sec)
{
if (!sec)
return 0;
if (sec->clref++ == 0)
obfuscate (sec->obptr, sec->clptr, sec->length);
return (const char*) sec->clptr;
}
size_t
mu_secret_length (mu_secret_t sec)
{
if (!sec)
return 0;
return sec->length;
}
void
mu_secret_password_unref (mu_secret_t sec)
{
if (--sec->clref == 0)
memset (sec->clptr, 0, sec->length);
}
/* GNU Mailutils -- a suite of utilities for electronic mail
Copyright (C) 1999, 2000, 2001, 2004, 2005,
2007 Free Software Foundation, Inc.
2007, 2009 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
......@@ -31,10 +31,11 @@
#include <mailutils/mutil.h>
#include <mailutils/errno.h>
#include <mailutils/secret.h>
#include <auth0.h>
static void
echo_off(struct termios *stored_settings)
echo_off (struct termios *stored_settings)
{
struct termios new_settings;
tcgetattr (0, stored_settings);
......@@ -44,7 +45,7 @@ echo_off(struct termios *stored_settings)
}
static void
echo_on(struct termios *stored_settings)
echo_on (struct termios *stored_settings)
{
tcsetattr (0, TCSANOW, stored_settings);
}
......@@ -59,31 +60,51 @@ mu_ticket_create (mu_ticket_t *pticket, void *owner)
if (ticket == NULL)
return ENOMEM;
ticket->owner = owner;
mu_ticket_ref (ticket);
*pticket = ticket;
return 0;
}
void
mu_ticket_destroy (mu_ticket_t *pticket, void *owner)
int
mu_ticket_ref (mu_ticket_t ticket)
{
if (pticket && *pticket)
if (!ticket)
return EINVAL;
ticket->refcnt++;
return 0;
}
int
mu_ticket_unref (mu_ticket_t ticket)
{
if (!ticket)
return EINVAL;
if (ticket->refcnt)
ticket->refcnt--;
if (ticket->refcnt == 0)
{
mu_ticket_t ticket = *pticket;
if (ticket->owner == owner)
{
if (ticket->_destroy)
ticket->_destroy (ticket);
if (ticket->challenge)
free (ticket->challenge);
free (ticket);
}
*pticket = NULL;
if (ticket->plain)
free (ticket->plain);
if (ticket->secret)
mu_secret_destroy (&ticket->secret);
if (ticket->_destroy)
ticket->_destroy (ticket);
free (ticket);
return 0;
}
return MU_ERR_EXISTS;
}
void
mu_ticket_destroy (mu_ticket_t *pticket)
{
if (pticket && *pticket && mu_ticket_unref (*pticket) == 0)
*pticket = NULL;
}
int
mu_ticket_set_destroy (mu_ticket_t ticket, void (*_destroy) (mu_ticket_t),
void *owner)
mu_ticket_set_destroy (mu_ticket_t ticket,
void (*_destroy) (mu_ticket_t), void *owner)
{
if (ticket == NULL)
return EINVAL;
......@@ -100,39 +121,83 @@ mu_ticket_get_owner (mu_ticket_t ticket)
}
int
mu_ticket_set_pop (mu_ticket_t ticket,
int (*_pop) (mu_ticket_t, mu_url_t, const char *, char **),
void *owner)
mu_ticket_set_get_cred (mu_ticket_t ticket,
int (*_get_cred) (mu_ticket_t, mu_url_t,
const char *,
char **, mu_secret_t *),
void *owner)
{
if (ticket == NULL)
return EINVAL;
if (ticket->owner != owner)
return EACCES;
ticket->_pop = _pop;
ticket->_get_cred = _get_cred;
return 0;
}
int
mu_ticket_pop (mu_ticket_t ticket, mu_url_t url, const char *challenge, char **parg)
mu_ticket_set_secret (mu_ticket_t ticket, mu_secret_t secret)
{
if (ticket == NULL)
return EINVAL;
if (ticket->secret)
mu_secret_unref (ticket->secret);
mu_secret_ref (secret);
ticket->secret = secret;
return 0;
}
int
mu_ticket_set_plain (mu_ticket_t ticket, const char *text)
{
int rc = -1;
if (ticket == NULL)
return EINVAL;
if (parg == NULL)
if (ticket->plain)
free (ticket->plain);
ticket->plain = strdup (text);
if (!ticket->plain)
return ENOMEM;
return 0;
}
int
mu_ticket_get_cred (mu_ticket_t ticket, mu_url_t url, const char *challenge,
char **pplain, mu_secret_t *psec)
{
int rc = 0;
char arg[256];
if (ticket == NULL || (pplain && psec))
return EINVAL;
if (pplain == NULL && psec == NULL)
return MU_ERR_OUT_PTR_NULL;
if (ticket->_pop)
rc = ticket->_pop (ticket, url, challenge, parg);
if (rc != 0 && isatty (fileno (stdin)))
if (ticket->_get_cred)
{
int res = ticket->_get_cred (ticket, url, challenge, pplain, psec);
if (res == 0)
return res;
}
if (pplain && ticket->plain)
{
*pplain = strdup (ticket->plain);
if (!*pplain)
return ENOMEM;
}
if (psec && ticket->secret)
{
mu_secret_ref (ticket->secret);
*psec = ticket->secret;
return 0;
}
if (isatty (fileno (stdin)))
{
char arg[256];
struct termios stored_settings;
int echo = 1;
int echo = pplain != NULL;
/* Being smart if we see "Passwd" and turning off echo. */
if (strstr (challenge, "ass") != NULL
|| strstr (challenge, "ASS") != NULL)
echo = 0;
printf ("%s", challenge);
fflush (stdout);
if (!echo)
......@@ -145,21 +210,25 @@ mu_ticket_pop (mu_ticket_t ticket, mu_url_t url, const char *challenge, char **p
fflush (stdout);
}
arg [strlen (arg) - 1] = '\0'; /* nuke the trailing line. */
*parg = strdup (arg);
rc = 0;
}
if (pplain)
{
*pplain = strdup (arg);
if (!*pplain)
return ENOMEM;
}
else
rc = mu_secret_create (psec, arg, strlen (arg));
return rc;
}
int
mu_ticket_get_data (mu_ticket_t ticket, void **data)
void *
mu_ticket_get_data (mu_ticket_t ticket)
{
if (ticket == NULL)
return EINVAL;
if (data == NULL)
return MU_ERR_OUT_PTR_NULL;
*data = ticket->data;
return 0;
if (!ticket)
return NULL;
return ticket->data;
}
int
......
/* GNU Mailutils -- a suite of utilities for electronic mail
Copyright (C) 2003, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
Copyright (C) 2003, 2005, 2006, 2007, 2008,
2009 Free Software Foundation, Inc.
GNU Mailutils is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
......@@ -161,34 +162,24 @@ lock_mailbox (mu_mailbox_t mbox)
}
/* A password ticket: returns the cleantext password. */
void
password_destroy (mu_ticket_t t)
{
char *p = mu_ticket_get_owner (t);
free (p);
}
int
password_pop (mu_ticket_t t, mu_url_t u, const char *challenge, char **ppwd)
{
char *p = mu_ticket_get_owner (t);
*ppwd = strdup (p);
return 0;
}
void
attach_passwd_ticket (mu_mailbox_t mbx, char *passwd)
{
mu_folder_t folder = NULL;
mu_authority_t auth = NULL;
char *p = strdup (passwd);
mu_secret_t secret;
mu_ticket_t t;
int rc;
rc = mu_secret_create (&secret, passwd, strlen (passwd));
if (rc)
{
mu_error ("mu_secret_create: %s", mu_strerror (rc));
exit (1);
}
mu_ticket_create (&t, p);
mu_ticket_set_destroy (t, password_destroy, p);
mu_ticket_set_pop (t, password_pop, p);
mu_ticket_create (&t, NULL);
mu_ticket_set_secret (t, secret);
if ((rc = mu_mailbox_get_folder (mbx, &folder)))
die (mbx, _("mu_mailbox_get_folder failed"), rc);
......
......@@ -434,7 +434,7 @@ api_ticket_destroy (PyObject *self, PyObject *args)
if (!PyArg_ParseTuple (args, "O!", &PyTicketType, &py_ticket))
return NULL;
mu_ticket_destroy (&py_ticket->ticket, NULL);
mu_ticket_destroy (&py_ticket->ticket);
return _ro (Py_None);
}
......@@ -452,7 +452,7 @@ api_wicket_create (PyObject *self, PyObject *args)
if (!PyArg_ParseTuple (args, "O!s", &PyWicketType, &py_wicket, &filename))
return NULL;
status = mu_wicket_create (&py_wicket->wicket, filename);
status = mu_file_wicket_create (&py_wicket->wicket, filename);
return _ro (PyInt_FromLong (status));
}
......@@ -468,38 +468,6 @@ api_wicket_destroy (PyObject *self, PyObject *args)
return _ro (Py_None);
}
static PyObject *
api_wicket_get_filename (PyObject *self, PyObject *args)
{
int status;
size_t n;
char filename[512];
PyWicket *py_wicket;
memset (filename, 0, sizeof (filename));
if (!PyArg_ParseTuple (args, "O!", &PyWicketType, &py_wicket))
return NULL;
status = mu_wicket_get_filename (py_wicket->wicket, filename,
sizeof (filename), &n);
return status_object (status, PyString_FromString (filename));
}
static PyObject *
api_wicket_set_filename (PyObject *self, PyObject *args)
{
int status;
char *filename;
PyWicket *py_wicket;
if (!PyArg_ParseTuple (args, "O!s", &PyWicketType, &py_wicket, &filename))
return NULL;
status = mu_wicket_set_filename (py_wicket->wicket, filename);
return _ro (PyInt_FromLong (status));
}
/*
* mu_auth
*/
......@@ -645,12 +613,6 @@ static PyMethodDef methods[] = {
{ "wicket_destroy", (PyCFunction) api_wicket_destroy, METH_VARARGS,
"" },
{ "wicket_get_filename", (PyCFunction) api_wicket_get_filename, METH_VARARGS,
"" },
{ "wicket_set_filename", (PyCFunction) api_wicket_set_filename, METH_VARARGS,
"" },
{ "register_module", (PyCFunction) api_register_module, METH_VARARGS,
"" },
......
......@@ -160,6 +160,9 @@ api_url_get_user (PyObject *self, PyObject *args)
return status_object (status, PyString_FromString (buf ? buf : ""));
}
#if 0
/* FIXME: Returning plaintext (unobfuscated) password from
a secret actually makes the latter useless. */
static PyObject *
api_url_get_passwd (PyObject *self, PyObject *args)
{
......@@ -173,6 +176,7 @@ api_url_get_passwd (PyObject *self, PyObject *args)
status = mu_url_sget_passwd (py_url->url, &buf);
return status_object (status, PyString_FromString (buf ? buf : ""));
}
#endif
static PyObject *
api_url_get_auth (PyObject *self, PyObject *args)
......@@ -267,7 +271,9 @@ static PyMethodDef methods[] = {
{ "get_port", (PyCFunction) api_url_get_port, METH_VARARGS, "" },
{ "get_scheme", (PyCFunction) api_url_get_scheme, METH_VARARGS, "" },
{ "get_user", (PyCFunction) api_url_get_user, METH_VARARGS, "" },
#if 0 /*FIXME: See above */
{ "get_passwd", (PyCFunction) api_url_get_passwd, METH_VARARGS, "" },
#endif
{ "get_auth", (PyCFunction) api_url_get_auth, METH_VARARGS, "" },
{ "get_host", (PyCFunction) api_url_get_host, METH_VARARGS, "" },
{ "get_path", (PyCFunction) api_url_get_path, METH_VARARGS, "" },
......