summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org.ua>2007-12-03 16:27:57 +0000
committerSergey Poznyakoff <gray@gnu.org.ua>2007-12-03 16:27:57 +0000
commitd2ff515169cd571e5120641bfa9df2d7cb9f4b7c (patch)
treef913af1abdd1a6b32c972bd1e596be53cde94f9d
parent0a05ac90b7c7ea1863e8fd083813d6a498980e41 (diff)
downloadmailutils-d2ff515169cd571e5120641bfa9df2d7cb9f4b7c.tar.gz
mailutils-d2ff515169cd571e5120641bfa9df2d7cb9f4b7c.tar.bz2
* gnulib.modules: Add des. Sort lines.
* imap4d/Makefile.am (imap4d_SOURCES): Add preauth.c * imap4d/authenticate.c (imap4d_authenticate): Use imap4d_session_setup. * imap4d/imap4d.c (imap4d_session_setup) (imap4d_session_setup.0): New functions. (imap4d_mainloop): Implement PREAUTH mode. * imap4d/imap4d.h (RESP_PREAUTH): New define. (enum imap4d_preauth): New data type. (preauth_mode,preauth_program,preauth_only,ident_port): New globals. (imap4d_session_setup,imap4d_session_setup.0): New functions. * imap4d/login.c (imap4d_login): Use imap4d_session_setup0. * imap4d/util.c (sc2string): Handle RESP_PREAUTH * lib/.cvsignore, m4/.cvsignore: Update. * mailbox/tcp.c: Fix indentation.
-rw-r--r--ChangeLog21
-rw-r--r--gnulib.modules11
-rw-r--r--imap4d/Makefile.am1
-rw-r--r--imap4d/authenticate.c21
-rw-r--r--imap4d/imap4d.c165
-rw-r--r--imap4d/imap4d.h22
-rw-r--r--imap4d/login.c15
-rw-r--r--imap4d/util.c3
-rw-r--r--lib/.cvsignore2
-rw-r--r--m4/.cvsignore1
-rw-r--r--mailbox/tcp.c5
11 files changed, 210 insertions, 57 deletions
diff --git a/ChangeLog b/ChangeLog
index b98abadc1..9958c8ea3 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,24 @@
+2007-12-03 Sergey Poznyakoff <gray@gnu.org.ua>
+
+ * gnulib.modules: Add des. Sort lines.
+ * imap4d/Makefile.am (imap4d_SOURCES): Add preauth.c
+ * imap4d/authenticate.c (imap4d_authenticate): Use
+ imap4d_session_setup.
+ * imap4d/imap4d.c (imap4d_session_setup)
+ (imap4d_session_setup.0): New functions.
+ (imap4d_mainloop): Implement PREAUTH mode.
+ * imap4d/imap4d.h (RESP_PREAUTH): New define.
+ (enum imap4d_preauth): New data type.
+ (preauth_mode,preauth_program,preauth_only,ident_port): New
+ globals.
+ (imap4d_session_setup,imap4d_session_setup.0): New functions.
+ * imap4d/login.c (imap4d_login): Use imap4d_session_setup0.
+ * imap4d/util.c (sc2string): Handle RESP_PREAUTH
+
+ * lib/.cvsignore, m4/.cvsignore: Update.
+
+ * mailbox/tcp.c: Fix indentation.
+
2007-12-02 Sergey Poznyakoff <gray@gnu.org.ua>
* mailbox/cfg_format.c: New file.
diff --git a/gnulib.modules b/gnulib.modules
index d53f61f5b..831e49515 100644
--- a/gnulib.modules
+++ b/gnulib.modules
@@ -3,14 +3,13 @@
# FIXME: regex and glob are used by libmailutils...
-gettext
-strtok_r
-getline
-argp
-xalloc
alloca
+argp
+crypto/des
fnmatch
+getline
getpass-gnu
+gettext
malloc
mbswidth
obstack
@@ -18,4 +17,6 @@ realloc
setenv
snprintf
strcase
+strtok_r
vasprintf
+xalloc
diff --git a/imap4d/Makefile.am b/imap4d/Makefile.am
index 2226734ad..a7cd419e8 100644
--- a/imap4d/Makefile.am
+++ b/imap4d/Makefile.am
@@ -46,6 +46,7 @@ imap4d_SOURCES = \
lsub.c\
namespace.c\
noop.c\
+ preauth.c\
rename.c\
search.c\
select.c\
diff --git a/imap4d/authenticate.c b/imap4d/authenticate.c
index f0eacfaa2..72879a7d0 100644
--- a/imap4d/authenticate.c
+++ b/imap4d/authenticate.c
@@ -119,25 +119,12 @@ imap4d_authenticate (struct imap4d_command *command, char *arg)
if (adata.result == RESP_OK && adata.username)
{
- auth_data = mu_get_auth_by_name (adata.username);
- if (auth_data == NULL)
+ if (imap4d_session_setup (adata.username))
return util_finish (command, RESP_NO,
"User name or passwd rejected");
-
- homedir = mu_normalize_path (strdup (auth_data->dir), "/");
- if (imap4d_check_home_dir (homedir, auth_data->uid, auth_data->gid))
- return util_finish (command, RESP_NO,
- "User name or passwd rejected");
-
- if (auth_data->change_uid)
- setuid (auth_data->uid);
-
- util_chdir (homedir);
- namespace_init (homedir);
- mu_diag_output (MU_DIAG_INFO, _("User `%s' logged in"), adata.username);
-
- return util_finish (command, RESP_OK,
- "%s authentication successful", auth_type);
+ else
+ return util_finish (command, RESP_OK,
+ "%s authentication successful", auth_type);
}
return util_finish (command, adata.result,
diff --git a/imap4d/imap4d.c b/imap4d/imap4d.c
index cdf953974..186e2fc8d 100644
--- a/imap4d/imap4d.c
+++ b/imap4d/imap4d.c
@@ -44,6 +44,12 @@ 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;
+enum imap4d_preauth preauth_mode;
+char *preauth_program;
+int preauth_only;
+int ident_port;
+char *ident_keyfile;
+int ident_encrypt_only;
/* Number of child processes. */
size_t children;
@@ -170,6 +176,100 @@ cb_mode (mu_debug_t debug, void *data, char *arg)
return 0;
}
+int
+parse_preauth_scheme (mu_debug_t debug, const char *scheme, mu_url_t url)
+{
+ int rc = 0;
+ if (strcmp (scheme, "stdio") == 0)
+ preauth_mode = preauth_stdio;
+ else if (strcmp (scheme, "prog") == 0)
+ {
+ char *path;
+ rc = mu_url_aget_path (url, &path);
+ if (rc)
+ {
+ mu_cfg_format_error (debug, MU_DEBUG_ERROR,
+ _("URL error: cannot get path: %s"),
+ mu_strerror (rc));
+ return 1;
+ }
+ preauth_program = path;
+ preauth_mode = preauth_prog;
+ }
+ else if (strcmp (scheme, "ident") == 0)
+ {
+ struct servent *sp;
+ long n;
+ if (url && mu_url_get_port (url, &n) == 0)
+ ident_port = (short) n;
+ else if (sp = getservbyname ("auth", "tcp"))
+ ident_port = ntohs (sp->s_port);
+ else
+ ident_port = 113;
+ preauth_mode = preauth_ident;
+ }
+ else
+ {
+ mu_cfg_format_error (debug, MU_DEBUG_ERROR, _("unknown preauth scheme"));
+ rc = 1;
+ }
+
+ return rc;
+}
+
+/* preauth prog:///usr/sbin/progname
+ preauth ident[://:port]
+ preauth stdio
+*/
+static int
+cb_preauth (mu_debug_t debug, void *data, char *arg)
+{
+ if (strcmp (arg, "stdio") == 0)
+ preauth_mode = preauth_stdio;
+ else if (strcmp (arg, "ident") == 0)
+ return parse_preauth_scheme (debug, arg, NULL);
+ else if (arg[0] == '/')
+ {
+ preauth_program = xstrdup (arg);
+ preauth_mode = preauth_prog;
+ }
+ else
+ {
+ mu_url_t url;
+ char *scheme;
+ int rc = mu_url_create (&url, arg);
+
+ if (rc)
+ {
+ mu_cfg_format_error (debug, MU_DEBUG_ERROR,
+ _("cannot create URL: %s"), mu_strerror (rc));
+ return 1;
+ }
+ rc = mu_url_parse (url);
+ if (rc)
+ {
+ mu_cfg_format_error (debug, MU_DEBUG_ERROR,
+ "%s: %s", arg, mu_strerror (rc));
+ return 1;
+ }
+
+ rc = mu_url_aget_scheme (url, &scheme);
+ if (rc)
+ {
+ mu_url_destroy (&url);
+ mu_cfg_format_error (debug, MU_DEBUG_ERROR,
+ _("URL error: %s"), mu_strerror (rc));
+ return 1;
+ }
+
+ rc = parse_preauth_scheme (debug, scheme, url);
+ mu_url_destroy (&url);
+ free (scheme);
+ return rc;
+ }
+ return 0;
+}
+
static struct mu_cfg_param imap4d_cfg_param[] = {
{ "other-namespace", mu_cfg_callback, NULL, cb_other },
{ "shared-namespace", mu_cfg_callback, NULL, cb_shared },
@@ -177,6 +277,10 @@ static struct mu_cfg_param imap4d_cfg_param[] = {
{ "create-home-dir", mu_cfg_bool, &create_home_dir },
{ "home-dir-mode", mu_cfg_callback, NULL, cb_mode },
{ "tls-required", mu_cfg_int, &tls_required },
+ { "preauth", mu_cfg_callback, NULL, cb_preauth },
+ { "preauth-only", mu_cfg_bool, &preauth_only },
+ { "ident-keyfile", mu_cfg_string, &ident_keyfile },
+ { "ident-entrypt-only", mu_cfg_bool, &ident_encrypt_only },
{ NULL }
};
@@ -214,16 +318,16 @@ main (int argc, char **argv)
auth_gssapi_init ();
auth_gsasl_init ();
-
+
#ifdef USE_LIBPAM
if (!mu_pam_service)
mu_pam_service = "gnu-imap4d";
#endif
- if (mu_gocs_daemon.mode == MODE_INTERACTIVE && isatty (0))
+ if (mu_gocs_daemon.mode == MODE_INTERACTIVE)
{
- /* If input is a tty, switch to debug mode */
- debug_mode = 1;
+ if (preauth_mode != preauth_stdio)
+ debug_mode = 1;
}
else
{
@@ -304,6 +408,36 @@ main (int argc, char **argv)
return status;
}
+int
+imap4d_session_setup0 ()
+{
+ homedir = mu_normalize_path (strdup (auth_data->dir), "/");
+ if (imap4d_check_home_dir (homedir, auth_data->uid, auth_data->gid))
+ return 1;
+
+ if (auth_data->change_uid)
+ setuid (auth_data->uid);
+
+ util_chdir (homedir);
+ namespace_init (homedir);
+ mu_diag_output (MU_DIAG_INFO,
+ _("User `%s' logged in (source: %s)"), auth_data->name,
+ auth_data->source);
+ return 0;
+}
+
+int
+imap4d_session_setup (char *username)
+{
+ auth_data = mu_get_auth_by_name (username);
+ if (auth_data == NULL)
+ {
+ mu_diag_output (MU_DIAG_INFO, _("User `%s': nonexistent"), username);
+ return 1;
+ }
+ return imap4d_session_setup0 ();
+}
+
static int
imap4d_mainloop (int fd, FILE *infile, FILE *outfile)
{
@@ -316,28 +450,21 @@ imap4d_mainloop (int fd, FILE *infile, FILE *outfile)
util_setio (infile, outfile);
- /* log information on the connecting client */
- if (!debug_mode)
+ if (debug_mode)
{
- struct sockaddr_in cs;
- int len = sizeof cs;
-
- mu_diag_output (MU_DIAG_INFO, _("Incoming connection opened"));
- if (getpeername (fd, (struct sockaddr *) &cs, &len) < 0)
- mu_diag_output (MU_DIAG_ERROR, _("Cannot obtain IP address of client: %s"),
- strerror (errno));
- else
- mu_diag_output (MU_DIAG_INFO, _("Connect from %s"), inet_ntoa (cs.sin_addr));
- text = "IMAP4rev1";
+ mu_diag_output (MU_DIAG_INFO, _("Started in debugging mode"));
+ text = "IMAP4rev1 Debugging mode";
}
+ else if (imap4d_preauth_setup (fd) == 0)
+ text = "IMAP4rev1";
else
{
- mu_diag_output (MU_DIAG_INFO, _("Started in debugging mode"));
- text = "IMAP4rev1 Debugging mode";
+ util_flush_output ();
+ return EXIT_SUCCESS;
}
/* Greetings. */
- util_out (RESP_OK, text);
+ util_out ((state == STATE_AUTH) ? RESP_PREAUTH : RESP_OK, "%s", text);
util_flush_output ();
while (1)
diff --git a/imap4d/imap4d.h b/imap4d/imap4d.h
index bb2f03938..43d2d84e9 100644
--- a/imap4d/imap4d.h
+++ b/imap4d/imap4d.h
@@ -128,7 +128,8 @@ struct imap4d_command
#define RESP_NO 2
#define RESP_BYE 3
#define RESP_NONE 4
-
+#define RESP_PREAUTH 5
+
/* Error values. */
#define OK 0
#define ERR_NO_MEM 1
@@ -153,6 +154,16 @@ struct imap4d_command
#define IMAP_CAPA_STARTTLS "STARTTLS"
#define IMAP_CAPA_LOGINDISABLED "LOGINDISABLED"
#define IMAP_CAPA_XTLSREQUIRED "XTLSREQUIRED"
+
+/* Preauth types */
+enum imap4d_preauth
+ {
+ preauth_none,
+ preauth_stdio,
+ preauth_ident,
+ preauth_prog
+ };
+
extern struct imap4d_command imap4d_command_table[];
extern mu_mailbox_t mbox;
@@ -166,6 +177,12 @@ extern const char *program_version;
extern int login_disabled;
extern int tls_required;
+extern enum imap4d_preauth preauth_mode;
+extern char *preauth_program;
+extern int preauth_only;
+extern int ident_port;
+extern char *ident_keyfile;
+extern int ident_encrypt_only;
#ifndef HAVE_STRTOK_R
extern char *strtok_r (char *s, const char *delim, char **save_ptr);
@@ -235,6 +252,9 @@ extern int namespace_init (char *path);
extern char * namespace_getfullpath (char *name, const char *delim);
extern char * namespace_checkfullpath (char *name, const char *pattern,
const char *delim);
+int imap4d_session_setup (char *username);
+int imap4d_session_setup0 (void);
+
/* Capability functions */
extern void imap4d_capability_add (const char *str);
extern void imap4d_capability_remove (const char *str);
diff --git a/imap4d/login.c b/imap4d/login.c
index c498df577..bdf385fd3 100644
--- a/imap4d/login.c
+++ b/imap4d/login.c
@@ -56,19 +56,8 @@ imap4d_login (struct imap4d_command *command, char *arg)
return util_finish (command, RESP_NO, "User name or passwd rejected");
}
- homedir = mu_normalize_path (strdup (auth_data->dir), "/");
- if (imap4d_check_home_dir (homedir, auth_data->uid, auth_data->gid))
- return util_finish (command, RESP_NO,
- "User name or passwd rejected");
-
- if (auth_data->change_uid)
- setuid (auth_data->uid);
-
- util_chdir (homedir);
-
- namespace_init (homedir);
- mu_diag_output (MU_DIAG_INFO, _("User `%s' logged in (source: %s)"), username,
- auth_data->source);
+ if (imap4d_session_setup0 ())
+ return util_finish (command, RESP_NO, "User name or passwd rejected");
return util_finish (command, RESP_OK, "Completed");
}
diff --git a/imap4d/util.c b/imap4d/util.c
index 8c390faf5..55fd1c6f9 100644
--- a/imap4d/util.c
+++ b/imap4d/util.c
@@ -676,6 +676,9 @@ sc2string (int rc)
case RESP_BYE:
return "BYE ";
+
+ case RESP_PREAUTH:
+ return "PREAUTH ";
}
return "";
}
diff --git a/lib/.cvsignore b/lib/.cvsignore
index 32d4f0404..494fca35f 100644
--- a/lib/.cvsignore
+++ b/lib/.cvsignore
@@ -30,6 +30,8 @@ chdir-long.h
chown.c
config.charset
creat-safer.c
+des.c
+des.h
dirent.h
dirent.in.h
dirfd.c
diff --git a/m4/.cvsignore b/m4/.cvsignore
index 45b64c307..8b0dd4b11 100644
--- a/m4/.cvsignore
+++ b/m4/.cvsignore
@@ -9,6 +9,7 @@ chown.m4
codeset.m4
d-ino.m4
d-type.m4
+des.m4
dirfd.m4
dirname.m4
dos.m4
diff --git a/mailbox/tcp.c b/mailbox/tcp.c
index 84cc2b142..0f2768416 100644
--- a/mailbox/tcp.c
+++ b/mailbox/tcp.c
@@ -320,7 +320,7 @@ mu_tcp_stream_create_with_source_ip (mu_stream_t *stream,
return ENOMEM;
tcp->fd = -1;
tcp->host = strdup (host);
- if(!tcp->host)
+ if (!tcp->host)
{
free (tcp);
return ENOMEM;
@@ -329,7 +329,8 @@ mu_tcp_stream_create_with_source_ip (mu_stream_t *stream,
tcp->state = TCP_STATE_INIT;
tcp->source_addr = source_ip;
if ((ret = mu_stream_create (stream,
- flags | MU_STREAM_NO_CHECK | MU_STREAM_RDWR, tcp)))
+ flags | MU_STREAM_NO_CHECK | MU_STREAM_RDWR,
+ tcp)))
{
free (tcp->host);
free (tcp);

Return to:

Send suggestions and report system problems to the System administrator.