Commit 2a45d3c7 2a45d3c7220ca06d6fc56a0e7153d05fa33d6ba3 by Sergey Poznyakoff

Implement ID extension.

* imap4d/id.c: New file.
* imap4d/Makefile.am (imap4d_SOURCES): Add id.c, remove version.c.
* imap4d/commands.c: Add ID command.
Remove X-VERSION command.
(SELECT,EXAMINE): Switch to authenticated mode on failure.
* imap4d/imap4d.c (imap4d_argc, imap4d_argv): New variables.
(imap4d_cfg_param): New keyword `id-fields'.
(main): Save command line arguments.
* imap4d/imap4d.h (imap4d_argc, imap4d_argv): New declarations.
* imap4d/select.c (imap4d_select0): Do not reset state to auth on
failure, this is done by util_finish.
* imap4d/version.c: Remove.
* imap4d/capability.c: Announce ID capability, remove X-VERSION.
* imap4d/testsuite/imap4d/x.exp: Use ID instead of X-VERSION.

* TODO, NEWS: Update.

* mailbox/cfg_parser.y (_set_fun,parse_param): Bugfix.
1 parent 1f1f932a
2008-08-20 Sergey Poznyakoff <gray@gnu.org.ua>
Implement ID extension.
* imap4d/id.c: New file.
* imap4d/Makefile.am (imap4d_SOURCES): Add id.c, remove version.c.
* imap4d/commands.c: Add ID command.
Remove X-VERSION command.
(SELECT,EXAMINE): Switch to authenticated mode on failure.
* imap4d/imap4d.c (imap4d_argc, imap4d_argv): New variables.
(imap4d_cfg_param): New keyword `id-fields'.
(main): Save command line arguments.
* imap4d/imap4d.h (imap4d_argc, imap4d_argv): New declarations.
* imap4d/select.c (imap4d_select0): Do not reset state to auth on
failure, this is done by util_finish.
* imap4d/version.c: Remove.
* imap4d/capability.c: Announce ID capability, remove X-VERSION.
* imap4d/testsuite/imap4d/x.exp: Use ID instead of X-VERSION.
* TODO, NEWS: Update.
* mailbox/cfg_parser.y (_set_fun,parse_param): Bugfix.
2008-08-19 Sergey Poznyakoff <gray@gnu.org.ua>
Bugfixes.
......
GNU mailutils NEWS -- history of user-visible changes. 2008-08-18
GNU mailutils NEWS -- history of user-visible changes. 2008-08-20
Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007,
2008 Free Software Foundation, Inc.
See the end of file for copying conditions.
......@@ -92,6 +92,8 @@ IP addresses/ports (or even local sockets) simultaneously.
** Imap4d supports UNSELECT extension.
** Imap4d supports ID extension.
** imap4d supports PREAUTH mode.
Three mechanisms are provided for authentifying the connection in
......
GNU mailutils TODO list. 2008-08-18
GNU mailutils TODO list. 2008-08-20
Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006,
2007, 2008 Free Software Foundation, Inc.
......@@ -85,7 +85,6 @@ mail (from mailutils itself), mutt, pine, netscape, mozilla.
* Implement extensions:
- ID : RFC 2971
- QUOTA : RFC 2087
- ACL : RFC 4314
- CHILDREN : RFC 3348
......
## Process this file with GNU Automake to create Makefile.in
## Copyright (C) 1999, 2000, 2001, 2002, 2003, 2005,
## 2007 Free Software Foundation, Inc.
## 2007, 2008 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
......@@ -37,6 +37,7 @@ imap4d_SOURCES = \
examine.c\
expunge.c\
fetch.c\
id.c\
idle.c\
imap4d.c\
imap4d.h\
......@@ -58,8 +59,7 @@ imap4d_SOURCES = \
sync.c\
uid.c\
unsubscribe.c\
util.c\
version.c
util.c
imap4d_LDADD = \
@IMAP_AUTHOBJS@\
......
......@@ -50,10 +50,10 @@ imap4d_capability_init ()
static char *capa[] = {
"IMAP4rev1",
"NAMESPACE",
"ID",
"IDLE",
"LITERAL+",
"UNSELECT",
"X-VERSION",
NULL
};
int i;
......
......@@ -25,8 +25,8 @@ struct imap4d_command imap4d_command_table [] =
{ "LOGOUT", imap4d_logout, STATE_ALL, STATE_LOGOUT, STATE_NONE, NULL },
{ "AUTHENTICATE", imap4d_authenticate, STATE_NONAUTH, STATE_NONE, STATE_AUTH, NULL },
{ "LOGIN", imap4d_login, STATE_NONAUTH, STATE_NONE, STATE_AUTH, NULL },
{ "SELECT", imap4d_select, STATE_AUTH | STATE_SEL, STATE_NONE, STATE_SEL, NULL },
{ "EXAMINE", imap4d_examine, STATE_AUTH | STATE_SEL, STATE_NONE, STATE_SEL, NULL },
{ "SELECT", imap4d_select, STATE_AUTH | STATE_SEL, STATE_AUTH, STATE_SEL, NULL },
{ "EXAMINE", imap4d_examine, STATE_AUTH | STATE_SEL, STATE_AUTH, STATE_SEL, NULL },
{ "CREATE", imap4d_create, STATE_AUTH | STATE_SEL, STATE_NONE, STATE_NONE, NULL },
{ "DELETE", imap4d_delete, STATE_AUTH | STATE_SEL, STATE_NONE, STATE_NONE, NULL },
{ "RENAME", imap4d_rename, STATE_AUTH | STATE_SEL, STATE_NONE, STATE_NONE, NULL },
......@@ -46,7 +46,7 @@ struct imap4d_command imap4d_command_table [] =
{ "COPY", imap4d_copy, STATE_SEL, STATE_NONE, STATE_NONE, NULL },
{ "UID", imap4d_uid, STATE_SEL, STATE_NONE, STATE_NONE, NULL },
{ "NAMESPACE", imap4d_namespace, STATE_AUTH | STATE_SEL, STATE_NONE, STATE_NONE, NULL },
{ "X-VERSION", imap4d_version, STATE_AUTH | STATE_SEL, STATE_NONE, STATE_NONE, NULL },
{ "ID", imap4d_id, STATE_AUTH | STATE_SEL, STATE_NONE, STATE_NONE, NULL },
{ "IDLE", imap4d_idle, STATE_SEL, STATE_NONE, STATE_NONE, NULL },
#ifdef WITH_TLS
{ "STARTTLS", imap4d_starttls, STATE_NONAUTH, STATE_NONE, STATE_NONE, NULL },
......
/* GNU Mailutils -- a suite of utilities for electronic mail
Copyright (C) 2008 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
the Free Software Foundation; either version 3, or (at your option)
any later version.
GNU Mailutils 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Mailutils; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
MA 02110-1301 USA */
/* Implementation of ID extension (RFC 2971) */
#include "imap4d.h"
#include <sys/utsname.h>
mu_list_t imap4d_id_list;
static int
eat_args (imap4d_tokbuf_t tok)
{
int n = IMAP4_ARG_1;
char *p;
p = imap4d_tokbuf_getarg (tok, n++);
if (!p)
return RESP_BAD;
if (strcasecmp (p, "NIL") == 0)
{
if (imap4d_tokbuf_getarg (tok, n))
return RESP_BAD;
return RESP_OK;
}
else if (p[0] != '(')
return RESP_BAD;
/* Collect arguments */
while ((p = imap4d_tokbuf_getarg (tok, n++)))
{
if (p[0] == ')')
{
if (imap4d_tokbuf_getarg (tok, n))
return RESP_BAD;
return RESP_OK;
}
}
return RESP_BAD;
}
struct id_value
{
char *name;
char *value;
const char *(*fun) (struct id_value *idv);
};
static const char *
get_os (struct id_value *idv)
{
struct utsname uts;
uname(&uts);
return idv->value = mu_strdup (uts.sysname);
}
static const char *
get_os_version (struct id_value *idv)
{
struct utsname uts;
uname(&uts);
return idv->value = mu_strdup (uts.version);
}
static const char *
get_command (struct id_value *idv MU_ARG_UNUSED)
{
return mu_program_name;
}
static char *
build_str (char **argv)
{
size_t size = 0;
int i, j;
char *buf, *p;
for (j = 0; argv[j]; j++)
{
size_t len = strlen (argv[j]);
if (size + len + 1 > 1024)
break;
size += len + 1;
}
buf = mu_alloc (size);
for (i = 0, p = buf; argv[i];)
{
strcpy (p, argv[i]);
p += strlen (p);
if (++i < j)
*p++ = ' ';
else
break;
}
*p = 0;
return buf;
}
static const char *
get_arguments (struct id_value *idv)
{
return idv->value = build_str (imap4d_argv + 1);
}
static const char *
get_environment (struct id_value *idv)
{
extern char **environ;
return idv->value = build_str (environ);
}
static struct id_value id_tab[] = {
{ "name", PACKAGE_NAME },
{ "version", PACKAGE_VERSION },
{ "vendor", "GNU" },
{ "support-url", "http://www.gnu.org/software/mailutils" },
{ "address",
"51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA" },
#if 0
/* FIXME */
{ "date", NULL },
#endif
{ "os", NULL, get_os },
{ "os-version", NULL, get_os_version },
{ "command", NULL, get_command },
{ "arguments", NULL, get_arguments },
{ "environment", NULL, get_environment },
{ NULL }
};
static const char *
get_id_value (const char *name)
{
struct id_value *idv;
const char *val = NULL;
for (idv = id_tab; idv->name; idv++)
{
if (strcmp (idv->name, name) == 0)
{
if (idv->value)
val = idv->value;
else if (idv->fun)
val = idv->fun (idv);
break;
}
}
return val;
}
int
imap4d_id (struct imap4d_command *command, imap4d_tokbuf_t tok)
{
int rc = eat_args (tok);
if (rc != RESP_OK)
return util_finish (command, rc, "Syntax error");
if (imap4d_id_list)
{
mu_iterator_t itr;
mu_list_get_iterator (imap4d_id_list, &itr);
int i;
int outcnt = 0;
for (i = 0, mu_iterator_first (itr);
i < 30 && !mu_iterator_is_done (itr);
i++, mu_iterator_next (itr))
{
const char *p, *q;
size_t len;
mu_iterator_current (itr, (void**)&p);
len = strcspn (p, "=");
if (p[len])
q = p + len + 1;
else
q = get_id_value (p);
if (q)
{
if (outcnt++ == 0)
util_send ("* ID (");
else
util_send (" ");
util_send ("\"%*.*s\" \"%s\"", len, len, p, q);
}
}
mu_iterator_destroy (&itr);
if (outcnt)
util_send (")\r\n");
}
return util_finish (command, RESP_OK, "Completed");
}
......@@ -39,6 +39,10 @@ int create_home_dir; /* Create home directory if it does not
exist */
int home_dir_mode = S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH;
/* Saved command line. */
int imap4d_argc;
char **imap4d_argv;
enum imap4d_preauth preauth_mode;
char *preauth_program;
int preauth_only;
......@@ -328,6 +332,8 @@ static struct mu_cfg_param imap4d_cfg_param[] = {
N_("Name of DES keyfile for decoding ecrypted ident responses.") },
{ "ident-entrypt-only", mu_cfg_bool, &ident_encrypt_only, 0, NULL,
N_("Use only encrypted ident responses.") },
{ "id-fields", MU_CFG_LIST_OF(mu_cfg_string), &imap4d_id_list, 0, NULL,
N_("List of fields to return in response to ID command.") },
{ ".server", mu_cfg_section, NULL, 0, NULL,
N_("Server configuration.") },
TCP_WRAPPERS_CONFIG
......@@ -475,6 +481,9 @@ main (int argc, char **argv)
static int sigtab[] = { SIGILL, SIGBUS, SIGFPE, SIGSEGV, SIGSTOP, SIGPIPE,
SIGABRT };
imap4d_argc = argc;
imap4d_argv = argv;
/* Native Language Support */
MU_APP_INIT_NLS ();
......
......@@ -192,6 +192,9 @@ extern char *ident_keyfile;
extern int ident_encrypt_only;
extern unsigned int idle_timeout;
extern int imap4d_transcript;
extern mu_list_t imap4d_id_list;
extern int imap4d_argc;
extern char **imap4d_argv;
#ifndef HAVE_STRTOK_R
extern char *strtok_r (char *s, const char *delim, char **save_ptr);
......@@ -254,6 +257,7 @@ extern int imap4d_unsubscribe (struct imap4d_command *, imap4d_tokbuf_t);
extern int imap4d_namespace (struct imap4d_command *, imap4d_tokbuf_t);
extern int imap4d_version (struct imap4d_command *, imap4d_tokbuf_t);
extern int imap4d_idle (struct imap4d_command *, imap4d_tokbuf_t);
extern int imap4d_id (struct imap4d_command *, imap4d_tokbuf_t);
extern int imap4d_check_home_dir (const char *dir, uid_t uid, gid_t gid);
......
......@@ -84,7 +84,6 @@ imap4d_select0 (struct imap4d_command *command, const char *mboxname,
status = util_finish (command, RESP_NO, "Could not open %s: %s",
mboxname, mu_strerror (status));
free (mailbox_name);
state = STATE_AUTH;
return status;
}
......
......@@ -20,7 +20,7 @@
imap4d_start
imap4d_test "CAPABILITY" \
"CAPABILITY IMAP4rev1 NAMESPACE IDLE LITERAL+ UNSELECT X-VERSION" \
"CAPABILITY IMAP4rev1 NAMESPACE ID IDLE LITERAL+ UNSELECT" \
"OK"
imap4d_test "NOOP"
......
# -*- tcl -*-
# This file is part of Mailutils testsuite.
# Copyright (C) 2002, 2007 Free Software Foundation
# Copyright (C) 2002, 2007, 2008 Free Software Foundation
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
......@@ -19,13 +19,12 @@
imap4d_start
imap4d_test -message "X-VERSION in initail state" "X-VERSION"\
"BAD X-VERSION Wrong state"
imap4d_test -message "ID in initail state" "ID NIL"\
"BAD ID Wrong state"
imap4d_auth "user!passwd" "guessme"
imap4d_test -message "X-VERSION in auth state" "X-VERSION"\
"X-VERSION GNU imap4d (GNU Mailutils [mu_check_capability VERSION])"\
imap4d_test -message "ID in auth state" "ID NIL"\
"OK"
imap4d_stop
......
/* GNU Mailutils -- a suite of utilities for electronic mail
Copyright (C) 1999, 2001, 2007, 2008 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
the Free Software Foundation; either version 3, or (at your option)
any later version.
GNU Mailutils 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Mailutils; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
MA 02110-1301 USA */
#include "imap4d.h"
int
imap4d_version (struct imap4d_command *command, imap4d_tokbuf_t tok)
{
if (imap4d_tokbuf_argc (tok) != 2)
return util_finish (command, RESP_BAD, "Invalid arguments");
util_send ("* %s GNU %s\r\n", command->name, program_version);
return util_finish (command, RESP_OK, "Completed");
}
......@@ -1045,7 +1045,7 @@ _set_fun (void *item, void *data)
return 1;
}
if (valcvt (clos->sdata, clos->locus, tgt, clos->type, val) == 0)
if (valcvt (clos->sdata, clos->locus, &tgt, clos->type, val) == 0)
mu_list_append (clos->list, tgt);
return 0;
}
......@@ -1086,13 +1086,11 @@ parse_param (struct scan_tree_data *sdata, const mu_cfg_node_t *node)
clos.type = MU_CFG_TYPE (param->type);
if (MU_CFG_IS_LIST (param->type))
{
mu_list_t list;
clos.sdata = sdata;
clos.locus = &node->locus;
mu_list_create (&clos.list);
mu_list_do (node->label->v.list, _set_fun, &clos);
*(mu_list_t*)tgt = list;
*(mu_list_t*)tgt = clos.list;
}
else if (clos.type == mu_cfg_callback)
{
......