Skip to content

Commit b92182c

Browse files
committed
merge 'security password' branch
1 parent ff924a2 commit b92182c

23 files changed

+685
-136
lines changed

acinclude.m4

+8
Original file line numberDiff line numberDiff line change
@@ -689,4 +689,12 @@ AC_DEFUN([DM_UPGRADE_STEPS], [dnl
689689
AC_SUBST(MYSQL_32003)
690690
AC_SUBST(SQLITE_32003)
691691
692+
PGSQL_32004=`sed -e 's/\"/\\\"/g' -e 's/^/\"/' -e 's/$/\\\n\"/' -e '$!s/$/ \\\\/' sql/postgresql/upgrades/32004.psql`
693+
MYSQL_32004=`sed -e 's/\"/\\\"/g' -e 's/^/\"/' -e 's/$/\\\n\"/' -e '$!s/$/ \\\\/' sql/mysql/upgrades/32004.mysql`
694+
SQLITE_32004=`sed -e 's/\"/\\\"/g' -e 's/^/\"/' -e 's/$/\\\n\"/' -e '$!s/$/ \\\\/' sql/sqlite/upgrades/32004.sqlite`
695+
AC_SUBST(PGSQL_32004)
696+
AC_SUBST(MYSQL_32004)
697+
AC_SUBST(SQLITE_32004)
698+
699+
692700
])

configure.in

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
# Copyright (C) 1999-2004 IC & S [email protected]
22
# Copyright (C) 2004-2013 NFG Net Facilities Group [email protected]
33

4-
AC_INIT([dbmail], [3.1.1], [[email protected]])
4+
<<<<<<< HEAD
5+
AC_INIT([dbmail], [3.1.3.1], [[email protected]])
56
AC_CONFIG_AUX_DIR(config)
67
AM_CONFIG_HEADER(config.h:config.in)
78
AC_CONFIG_MACRO_DIR([m4])

doc/README.security-password

+71
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
2+
Security Password
3+
=================
4+
5+
DBMail now supports a special, separate password.
6+
7+
This separate password allows you to specify behavior when users log into one
8+
of the DBMail servers using this password.
9+
10+
The use-case for this feature is when you want to provide your users with an
11+
unobtrusive way to delete all sensitive messages from their accounts, even when
12+
under duress or active observation. When a lot of messages are affected the
13+
login delay will be somewhat greater, but other than that, it is impossible to
14+
tell that anything out of the ordinary has happpened.
15+
16+
Changes
17+
-------
18+
19+
A small schema-migration is required and provided in
20+
sql/DRIVER/upgrades/31202.xxx. If you run a version prior to 3.2.0 you will
21+
have to apply it manually.
22+
23+
The password can be specified with the --security-password argument of
24+
dbmail-users. The same encryption as for the regular password is used.
25+
26+
The behavior after logging in using this password can be set per user using the
27+
--security-action argument of dbmail-users. Currently two actions are
28+
hard-coded, but you can expand them as needed.
29+
30+
Security-action:
31+
----------------
32+
33+
0: do nothing. This is also the default behavior.
34+
1: delete everything. In this case all mailboxes owned by the authenticated
35+
user are deleted immediately and irretrievably.
36+
2 and higher: these can be configured through the security_action setting
37+
in dbmail.conf:
38+
39+
The first two are hard-coded, as said. It is not possible to override them in
40+
dbmail.conf. Trying to do so will invalidate the entry in dbmail.conf.
41+
42+
An example:
43+
44+
security_action = 2:\Deleted;3:\Flagged \Deleted Important $Important
45+
46+
In this case two additional behaviors are defined. When a user has
47+
security-action 2, and logs on using the security-password all messages that
48+
have the \Deleted system-flag set are queued for later deletion by dbmail-util,
49+
and are immediately inaccessible to the user.
50+
51+
For users with security-action 3, all messages that have the \Flagged or
52+
\Deleted system flags, or have a user labels 'Important' or '$Important' are
53+
queued for deletion and are also immediately inaccessible to the user.
54+
55+
Please Note:
56+
------------
57+
58+
This feature is not without risks if used casually. Instruct your users
59+
carefully! Also make sure the security password can never be the same as the
60+
regular password because in that case it just won't work.
61+
62+
Messages that have been queued for deletion *can*, if required, be restored to
63+
visibility by a system adminitrator by setting the status field. If the
64+
security action was set to '1' however, only a restore from backup of the
65+
database will bring back the deleted mail.
66+
67+
68+
LDAP support is currently not available. Please contact [email protected] if you
69+
required this feature and need LDAP authentication.
70+
71+
#EOF

sql/mysql/create_tables.mysql

+3
Original file line numberDiff line numberDiff line change
@@ -384,6 +384,9 @@ CREATE TABLE `dbmail_users` (
384384
`cursieve_size` bigint(20) NOT NULL default '0',
385385
`encryption_type` varchar(255) NOT NULL default '',
386386
`last_login` datetime NOT NULL default '1979-11-03 22:05:58',
387+
`spasswd` varchar(255) NOT NULL default '',
388+
`saction` smallint NOT NULL default '0',
389+
`active` smallint NOT NULL default '1',
387390
PRIMARY KEY (`user_idnr`),
388391
UNIQUE KEY `userid_index` (`userid`)
389392
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

sql/mysql/upgrades/32004.mysql

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
2+
BEGIN;
3+
ALTER TABLE dbmail_users ADD COLUMN spasswd VARCHAR(130) DEFAULT '' NOT NULL;
4+
ALTER TABLE dbmail_users ADD COLUMN saction SMALLINT DEFAULT '0' NOT NULL;
5+
ALTER TABLE dbmail_users ADD COLUMN active SMALLINT DEFAULT '1' NOT NULL;
6+
7+
INSERT INTO dbmail_upgrade_steps (from_version, to_version, applied) values (32001, 32004, now());
8+
COMMIT;

sql/oracle/dbmail_schema.sql

+3
Original file line numberDiff line numberDiff line change
@@ -514,6 +514,9 @@ CREATE TABLE dbmail_users (
514514
cursieve_size number(20) default '0' NOT NULL,
515515
encryption_type varchar2(255) default NULL,
516516
last_login timestamp default TO_TIMESTAMP('1979-11-03 22:05:58','YYYY-MM-DD HH24:MI:SS') NOT NULL
517+
spasswd varchar2(255) default NULL,
518+
saction number(1) default '0' NOT NULL,
519+
active number(1) default '1' NOT NULL
517520
);
518521
CREATE UNIQUE INDEX dbmail_users_idx ON dbmail_users (user_idnr) TABLESPACE DBMAIL_TS_IDX;
519522
ALTER TABLE dbmail_users ADD CONSTRAINT dbmail_users_pk PRIMARY KEY (user_idnr) USING INDEX dbmail_users_idx;

sql/postgresql/create_tables.pgsql

+3
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,9 @@ CREATE TABLE dbmail_users (
6262
cursieve_size INT8 DEFAULT '0' NOT NULL,
6363
encryption_type VARCHAR(20) DEFAULT '' NOT NULL,
6464
last_login TIMESTAMP DEFAULT '1979-11-03 22:05:58' NOT NULL,
65+
spasswd VARCHAR(130) DEFAULT '' NOT NULL,
66+
saction SMALLINT DEFAULT '0' NOT NULL,
67+
active SMALLINT DEFAULT '1' NOT NULL
6568
PRIMARY KEY (user_idnr)
6669
);
6770

sql/postgresql/upgrades/32004.pgsql

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
2+
BEGIN;
3+
ALTER TABLE dbmail_users ADD COLUMN spasswd VARCHAR(130) DEFAULT '' NOT NULL;
4+
ALTER TABLE dbmail_users ADD COLUMN saction SMALLINT DEFAULT '0' NOT NULL;
5+
ALTER TABLE dbmail_users ADD COLUMN active SMALLINT DEFAULT '1' NOT NULL;
6+
7+
INSERT INTO dbmail_upgrade_steps (from_version, to_version) values (32001, 32004);
8+
COMMIT;

sql/sqlite/create_tables.sqlite

+4-1
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,10 @@ CREATE TABLE dbmail_users (
5353
maxmail_size INTEGER DEFAULT '0' NOT NULL,
5454
curmail_size INTEGER DEFAULT '0' NOT NULL,
5555
encryption_type TEXT DEFAULT '' NOT NULL,
56-
last_login DATETIME DEFAULT '1979-11-03 22:05:58' NOT NULL
56+
last_login DATETIME DEFAULT '1979-11-03 22:05:58' NOT NULL,
57+
spasswd TEXT NOT NULL DEFAULT '',
58+
saction SMALLINT NOT NULL DEFAULT '0',
59+
active BOOLEAN NOT NULL DEFAULT '1'
5760
);
5861
CREATE UNIQUE INDEX dbmail_users_1 ON dbmail_users(userid);
5962

sql/sqlite/upgrades/32004.sqlite

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
2+
BEGIN;
3+
ALTER TABLE dbmail_users ADD COLUMN spasswd VARCHAR(130) DEFAULT '' NOT NULL;
4+
ALTER TABLE dbmail_users ADD COLUMN saction SMALLINT DEFAULT '0' NOT NULL;
5+
ALTER TABLE dbmail_users ADD COLUMN active SMALLINT DEFAULT '1' NOT NULL;
6+
7+
INSERT INTO dbmail_upgrade_steps (from_version, to_version) values (32001, 32004);
8+
COMMIT;

src/dbmail-imapsession.c

+1-3
Original file line numberDiff line numberDiff line change
@@ -1314,13 +1314,11 @@ int dbmail_imap_session_handle_auth(ImapSession * self, const char * username, c
13141314
{
13151315
uint64_t userid = 0;
13161316

1317+
TRACE(TRACE_DEBUG, "[%p] trying to validate user [%s]", self, username);
13171318
int valid = auth_validate(self->ci, username, password, &userid);
13181319

13191320
if (self->ci->auth)
13201321
username = Cram_getUsername(self->ci->auth);
1321-
1322-
TRACE(TRACE_DEBUG, "[%p] trying to validate user [%s]", self, username);
1323-
13241322

13251323
switch(valid) {
13261324
case -1: /* a db-error occurred */

src/dbmail-user.c

+31-5
Original file line numberDiff line numberDiff line change
@@ -428,18 +428,18 @@ int do_aliases(const uint64_t useridnr,
428428
GList *current_aliases, *matching_aliases, *matching_alias_del;
429429

430430
if (no_to_all) {
431-
qprintf("Pretending to remove aliases for user id number [%" PRIu64 "]\n",
432-
useridnr);
433431
if (alias_del) {
432+
qprintf("Pretending to remove aliases for user id number [%" PRIu64 "]\n",
433+
useridnr);
434434
alias_del = g_list_first(alias_del);
435435
while (alias_del) {
436436
qprintf(" [%s]\n", (char *)alias_del->data);
437437
alias_del = g_list_next(alias_del);
438438
}
439439
}
440-
qprintf("Pretending to add aliases for user id number [%" PRIu64 "]\n",
441-
useridnr);
442440
if (alias_add) {
441+
qprintf("Pretending to add aliases for user id number [%" PRIu64 "]\n",
442+
useridnr);
443443
alias_add = g_list_first(alias_add);
444444
while (alias_add) {
445445
qprintf(" [%s]\n", (char *)alias_add->data);
@@ -521,6 +521,32 @@ int do_aliases(const uint64_t useridnr,
521521
return result;
522522
}
523523

524+
int do_spasswd(const uint64_t useridnr, const char * const spasswd)
525+
{
526+
if (no_to_all) {
527+
qprintf("Pretending to set security password for user [%" PRIu64 "] to [%s]\n", useridnr, spasswd);
528+
return 1;
529+
}
530+
return db_user_set_security_password(useridnr, spasswd);
531+
}
532+
533+
int do_saction(const uint64_t useridnr, long int saction)
534+
{
535+
if (no_to_all) {
536+
qprintf("Pretending to set security action for user [%" PRIu64 "] to [%ld]\n", useridnr, saction);
537+
return 1;
538+
}
539+
return db_user_set_security_action(useridnr, saction);
540+
}
541+
542+
int do_enable(const uint64_t useridnr, bool enable)
543+
{
544+
if (no_to_all) {
545+
qprintf("Pretending to %s authentication for user [%" PRIu64 "]\n", enable?"enable":"disable", useridnr);
546+
return 1;
547+
}
548+
return db_user_set_active(useridnr, enable);
549+
}
524550

525551
int do_delete(const uint64_t useridnr, const char * const name)
526552
{
@@ -708,7 +734,7 @@ int do_empty(uint64_t useridnr)
708734
qprintf("Emptying mailbox... ");
709735
fflush(stdout);
710736

711-
result = db_empty_mailbox(useridnr);
737+
result = db_empty_mailbox(useridnr, 1);
712738
if (result != 0) {
713739
qerrorf("Error. Please check the log.\n");
714740
} else {

src/dbmail-user.h

+3-10
Original file line numberDiff line numberDiff line change
@@ -43,16 +43,6 @@ int mkpassword(const char * const user, const char * const passwd,
4343
const char * const passwdtype, const char * const passwdfile,
4444
char ** password, char ** enctype);
4545

46-
struct change_flags {
47-
unsigned int newuser : 1;
48-
unsigned int newmaxmail : 1;
49-
unsigned int newclientid : 1;
50-
unsigned int newpasswd : 1;
51-
unsigned int newpasswdfile : 1;
52-
unsigned int newpasswdstdin : 1;
53-
unsigned int newpasswdshadow : 1;
54-
};
55-
5646
/* The prodigious use of const ensures that programming
5747
* mistakes inside of these functions don't cause us to
5848
* use incorrect values when calling auth_ and db_ internals.
@@ -75,6 +65,9 @@ int do_clientid(const uint64_t useridnr, const uint64_t clientid);
7565
int do_password(const uint64_t useridnr,
7666
const char * const password,
7767
const char * const enctype);
68+
int do_spasswd(const uint64_t useridnr, const char * const password);
69+
int do_saction(const uint64_t useridnr, long int saction);
70+
int do_enable(const uint64_t useridnr, bool enable);
7871
int do_aliases(const uint64_t useridnr,
7972
GList * alias_add,
8073
GList * alias_del);

src/dbmail.h.in

+3
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,9 @@
205205
#define DM_PGSQL_32003 @PGSQL_32003@
206206
#define DM_SQLITE_32003 @SQLITE_32003@
207207

208+
#define DM_MYSQL_32004 @MYSQL_32004@
209+
#define DM_PGSQL_32004 @PGSQL_32004@
210+
#define DM_SQLITE_32004 @SQLITE_32004@
208211

209212
/* include dbmail.conf for autocreation */
210213
#define DM_DEFAULT_CONFIGURATION @DM_DEFAULT_CONFIGURATION@

src/dbmailtypes.h

+2
Original file line numberDiff line numberDiff line change
@@ -408,6 +408,7 @@ typedef struct {
408408
Field_T tls_ciphers;
409409
int (*ClientHandler) (client_sock *);
410410
void (*cb) (struct evhttp_request *, void *);
411+
GTree *security_actions;
411412
} ServerConfig_T;
412413

413414

@@ -494,6 +495,7 @@ typedef struct {
494495
gchar *hdrplist;
495496
GList *names;
496497
GTree *headers;
498+
GList *names;
497499
} body_fetch;
498500

499501

src/dm_config.c

+50
Original file line numberDiff line numberDiff line change
@@ -496,3 +496,53 @@ char * config_get_pidfile(ServerConfig_T *config, const char *name)
496496
return res;
497497
}
498498

499+
void config_get_security_actions(ServerConfig_T *config)
500+
{
501+
Field_T var;
502+
char **values;
503+
uint64_t *key;
504+
char *value;
505+
506+
if (config->security_actions)
507+
return;
508+
509+
GTree *actions = g_tree_new_full((GCompareDataFunc)ucmp, NULL, g_free, g_free);
510+
511+
memset(var, '\0', sizeof(var));
512+
GETCONFIGVALUE("security_action", "DBMAIL", var);
513+
key = g_new0(uint64_t, 1);
514+
*key = 0;
515+
g_tree_insert(actions, key, g_strdup("NONE"));
516+
key = g_new0(uint64_t, 1);
517+
*key = 1;
518+
g_tree_insert(actions, key, g_strdup("ALL"));
519+
520+
if (strlen(var) > 2) { // 2:a;3:b
521+
int i = 0;
522+
values = g_strsplit(var, ";", 0);
523+
while (values[i]) {
524+
uint64_t tmp = dm_strtoull(values[i], &value, 10);
525+
if ((tmp == 0) || (value == NULL) || (value[0] != ':')) {
526+
TRACE(TRACE_NOTICE, "error parsing security action");
527+
break;
528+
}
529+
if (g_tree_lookup(actions, &tmp)) {
530+
TRACE(TRACE_ERR, "duplicate security action specified [%" PRIu64 "]",
531+
tmp);
532+
TRACE(TRACE_ERR, "ignoring security_action configuration. using defaults.");
533+
break;
534+
}
535+
value++;
536+
key = g_new0(uint64_t, 1);
537+
*key = tmp;
538+
g_tree_insert(actions, key, g_strdup(value));
539+
i++;
540+
}
541+
i = 0;
542+
g_strfreev(values);
543+
}
544+
545+
config->security_actions = actions;
546+
}
547+
548+

src/dm_config.h

+1
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ void pidfile_create(const char *pidFile, pid_t pid);
7171

7272
void config_get_timeout(ServerConfig_T *config, const char * const service);
7373
void config_get_logfiles(ServerConfig_T *config, const char * const service);
74+
void config_get_security_actions(ServerConfig_T *config);
7475

7576
char * config_get_pidfile(ServerConfig_T *config, const char *name);
7677
char * config_get_statefile(ServerConfig_T *config, const char *name);

0 commit comments

Comments
 (0)