--- src/xsasl/xsasl_dovecot_server.c.orig 2006-10-29 11:23:28.687500000 +0300 +++ src/xsasl/xsasl_dovecot_server.c 2006-10-29 11:55:53.093750000 +0300 @@ -82,6 +82,12 @@ */ #define AUTH_TIMEOUT 10 +#define SEC_PROPS_NOPLAINTEXT 0x00000001 +#define SEC_PROPS_NOACTIVE 0x00000002 +#define SEC_PROPS_NODICTIONARY 0x00000004 +#define SEC_PROPS_NOANONYMOUS 0x00000008 +#define SEC_PROPS_MUTUAL_AUTH 0x00000010 + /* * Class variables. */ @@ -90,6 +96,7 @@ VSTREAM *sasl_stream; char *socket_path; char *mechanism_list; /* applicable mechanisms */ + unsigned int sec_props; unsigned int request_id_counter; } XSASL_DOVECOT_SERVER_IMPL; @@ -129,9 +136,10 @@ const char *myname = "xsasl_dovecot_server_connect"; VSTRING *line_str, *mechanisms_str; VSTREAM *sasl_stream; - char *line, *cmd, *mech_name; + char *line, *cmd, *mech_name, *mech_opt; unsigned int major_version, minor_version; int fd, success; + int skip; if (msg_verbose) msg_info("%s: Connecting", myname); @@ -182,10 +190,31 @@ } else if (strcmp(cmd, "MECH") == 0 && line != NULL) { mech_name = line; line = split_at(line, '\t'); + /* Filter this mech */ + skip = (xp->sec_props & SEC_PROPS_MUTUAL_AUTH) == SEC_PROPS_MUTUAL_AUTH; + while(line != NULL && !skip) { + mech_opt = line; + line = split_at(line, '\t'); + if (strcmp(mech_opt, "anonymous") == 0 && (xp->sec_props & SEC_PROPS_NOANONYMOUS)) { + skip = 1; + } else if (strcmp(mech_opt, "plaintext") == 0 && (xp->sec_props & SEC_PROPS_NOPLAINTEXT)) { + skip = 1; + } else if (strcmp(mech_opt, "dictionary") == 0 && (xp->sec_props & SEC_PROPS_NODICTIONARY)) { + skip = 1; + } else if (strcmp(mech_opt, "active") == 0 && (xp->sec_props & SEC_PROPS_NOACTIVE)) { + skip = 1; + } else if (strcmp(mech_opt, "private") == 0) { + skip = 1; + } else if (strcmp(mech_opt, "mutual-auth") == 0 && (xp->sec_props & SEC_PROPS_MUTUAL_AUTH)) { + skip = 0; + } + } - if (VSTRING_LEN(mechanisms_str) > 0) - VSTRING_ADDCH(mechanisms_str, ' '); - vstring_strcat(mechanisms_str, mech_name); + if(!skip) { + if (VSTRING_LEN(mechanisms_str) > 0) + VSTRING_ADDCH(mechanisms_str, ' '); + vstring_strcat(mechanisms_str, mech_name); + } } else if (strcmp(cmd, "DONE") == 0) { /* Handshake finished. */ success = 1; @@ -258,9 +287,10 @@ VSTREAM *unused_stream, const char *service, const char *realm, - const char *unused_sec_props) + const char *sec_props) { const char *myname = "xsasl_dovecot_server_create"; + char *sec_props_copy, *one_prop, *s; XSASL_DOVECOT_SERVER *server; if (msg_verbose) @@ -279,10 +309,31 @@ server->xsasl.get_mechanism_list = xsasl_dovecot_server_get_mechanism_list; server->xsasl.get_username = xsasl_dovecot_server_get_username; server->impl = (XSASL_DOVECOT_SERVER_IMPL *) impl; + server->impl->sec_props = 0; server->sasl_line = vstring_alloc(256); server->username = 0; server->service = mystrdup(service); server->last_request_id = 0; + + /* + * Make security options + */ + sec_props_copy = mystrdup(sec_props); + s = sec_props_copy; + while((one_prop = mystrtok(&s, " \t\n\r,")) != NULL) { + if (strcmp(one_prop,"noplaintext") == 0) { + server->impl->sec_props |= SEC_PROPS_NOPLAINTEXT; + } else if (strcmp(one_prop,"noactive") == 0) { + server->impl->sec_props |= SEC_PROPS_NOACTIVE; + } else if (strcmp(one_prop,"nodictionary") == 0) { + server->impl->sec_props |= SEC_PROPS_NODICTIONARY; + } else if (strcmp(one_prop,"noanonymous") == 0) { + server->impl->sec_props |= SEC_PROPS_NOANONYMOUS; + } else if (strcmp(one_prop,"mutual_auth") == 0) { + server->impl->sec_props |= SEC_PROPS_MUTUAL_AUTH; + } + } + myfree(sec_props_copy); return (&server->xsasl); }