diff options
author | Sergey Poznyakoff <gray@gnu.org.ua> | 2007-12-03 16:27:57 +0000 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org.ua> | 2007-12-03 16:27:57 +0000 |
commit | d2ff515169cd571e5120641bfa9df2d7cb9f4b7c (patch) | |
tree | f913af1abdd1a6b32c972bd1e596be53cde94f9d | |
parent | 0a05ac90b7c7ea1863e8fd083813d6a498980e41 (diff) | |
download | mailutils-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-- | ChangeLog | 21 | ||||
-rw-r--r-- | gnulib.modules | 11 | ||||
-rw-r--r-- | imap4d/Makefile.am | 1 | ||||
-rw-r--r-- | imap4d/authenticate.c | 21 | ||||
-rw-r--r-- | imap4d/imap4d.c | 165 | ||||
-rw-r--r-- | imap4d/imap4d.h | 22 | ||||
-rw-r--r-- | imap4d/login.c | 15 | ||||
-rw-r--r-- | imap4d/util.c | 3 | ||||
-rw-r--r-- | lib/.cvsignore | 2 | ||||
-rw-r--r-- | m4/.cvsignore | 1 | ||||
-rw-r--r-- | mailbox/tcp.c | 5 |
11 files changed, 210 insertions, 57 deletions
@@ -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); |