Commit d2ff5151 d2ff515169cd571e5120641bfa9df2d7cb9f4b7c by Sergey Poznyakoff

* 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.
1 parent 0a05ac90
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.
......
......@@ -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
......
......@@ -46,6 +46,7 @@ imap4d_SOURCES = \
lsub.c\
namespace.c\
noop.c\
preauth.c\
rename.c\
search.c\
select.c\
......
......@@ -119,23 +119,10 @@ 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);
else
return util_finish (command, RESP_OK,
"%s authentication successful", auth_type);
}
......
......@@ -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 }
};
......@@ -220,9 +324,9 @@ main (int argc, char **argv)
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 */
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)
......
......@@ -128,6 +128,7 @@ struct imap4d_command
#define RESP_NO 2
#define RESP_BYE 3
#define RESP_NONE 4
#define RESP_PREAUTH 5
/* Error values. */
#define OK 0
......@@ -154,6 +155,16 @@ struct imap4d_command
#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;
extern char *homedir;
......@@ -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);
......
......@@ -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");
}
......
......@@ -676,6 +676,9 @@ sc2string (int rc)
case RESP_BYE:
return "BYE ";
case RESP_PREAUTH:
return "PREAUTH ";
}
return "";
}
......
......@@ -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
......
......@@ -9,6 +9,7 @@ chown.m4
codeset.m4
d-ino.m4
d-type.m4
des.m4
dirfd.m4
dirname.m4
dos.m4
......
......@@ -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);
......