diff --git a/TODO b/TODO
index 4a68ed1de996173a2502ff284c26dfecbfccde3f..820f480109cb9387b68f0e025a6d43ed2ac6eeba 100644
--- a/TODO
+++ b/TODO
@@ -2,8 +2,6 @@ Current:
 
 * Implement enotify extension:
 	- Limit the number of notifications generated (on a per-method basis)
-* Implement mailto method for the enotify extension:
-	- Finish URI validation to properly recognize invalid characters.
 * Incorporate enotify extension into default compile.  
 
 Next (in order of descending priority/precedence):
diff --git a/src/lib-sieve/plugins/enotify/ntfy-mailto.c b/src/lib-sieve/plugins/enotify/ntfy-mailto.c
index 410b9fb6d1a91d4f955fb6ad2d4f8f335d7711d4..811403124aa8fbe7c8965594c1cdd06f94f1c4d0 100644
--- a/src/lib-sieve/plugins/enotify/ntfy-mailto.c
+++ b/src/lib-sieve/plugins/enotify/ntfy-mailto.c
@@ -11,6 +11,13 @@
  * 
  */
  
+/* FIXME: URI syntax conforms to something somewhere in between RFC 2368 and
+ *   draft-duerst-mailto-bis-05.txt. Should fully migrate to new specification
+ *   when it matures. This requires modifications to the address parser (no
+ *   whitespace allowed within the address itself) and UTF-8 support will be
+ *   required in the URL.
+ */
+ 
 #include "lib.h"
 #include "array.h"
 #include "str.h"
@@ -323,6 +330,12 @@ static bool _uri_parse_recipients
 				str_append_c(to, ch);
 			}
 		} else {
+			if ( *p == ':' || *p == ';' || !_is_qchar(*p) ) {
+				_uri_parse_error
+					(nlog, "invalid character '%c' in 'to' part", *p);
+				return FALSE;
+			}
+
 			/* Content character */
 			str_append_c(to, *p);
 			p++;
@@ -574,6 +587,9 @@ static bool ntfy_mailto_parse_uri
    * some-delims = "!" / "$" / "'" / "(" / ")" / "*"
    *               / "+" / "," / ";" / ":" / "@"
    *
+	 * to         ~= *tqchar
+	 * tqchar     ~= <qchar> without ";" and ":" 
+   * 
 	 * Scheme 'mailto:' already parsed, starting parse after colon
 	 */
 
diff --git a/tests/extensions/enotify/errors.svtest b/tests/extensions/enotify/errors.svtest
index 995e9c8f72d66f1478a901a76c163b3edc277934..7c1a5fbfbf4c40dbfb4b44a23749402d3c7157f6 100644
--- a/tests/extensions/enotify/errors.svtest
+++ b/tests/extensions/enotify/errors.svtest
@@ -4,8 +4,7 @@ require "relational";
 
 require "enotify";
 
-
-test "Invalid URL (FIXME: count only)" {
+test "Invalid URI (FIXME: count only)" {
 	if test_compile "errors/uri.sieve" {
 		test_fail "compile should have failed";
 	}
@@ -15,12 +14,12 @@ test "Invalid URL (FIXME: count only)" {
 	}
 }
 
-test "Invalid mailto URL (FIXME: count only)" {
+test "Invalid mailto URI (FIXME: count only)" {
 	if test_compile "errors/uri-mailto.sieve" {
 		test_fail "compile should have failed";
 	}
 
-	if not test_error :count "eq" :comparator "i;ascii-numeric" "4" {
+	if not test_error :count "eq" :comparator "i;ascii-numeric" "7" {
 		test_fail "wrong number of errors reported";
 	}
 }
diff --git a/tests/extensions/enotify/errors/uri-mailto.sieve b/tests/extensions/enotify/errors/uri-mailto.sieve
index 5970086dc1744696ef523062833fbae3dfb22632..d272fe060bfc015429239356c43b4c176ead75a4 100644
--- a/tests/extensions/enotify/errors/uri-mailto.sieve
+++ b/tests/extensions/enotify/errors/uri-mailto.sieve
@@ -1,11 +1,20 @@
 require "enotify";
 
-# 1: Invalid header name 
+# 1: Invalid character in to part
+notify "mailto:stephan@rename-it.nl;?header=frop";
+
+# 2: Invalid character in hname
+notify "mailto:stephan@rename-it.nl?header<=frop";
+
+# 3: Invalid character in hvalue
+notify "mailto:stephan@rename-it.nl?header=fr>op";
+
+# 4: Invalid header name 
 notify "mailto:stephan@rename-it.nl?header:=frop";
 
-# 2: Invalid recipient
+# 5: Invalid recipient
 notify "mailto:stephan%23rename-it.nl";
 
-# 3: Invalid to header recipient
+# 6: Invalid to header recipient
 notify "mailto:stephan@rename-it.nl?to=nico%23vestingbar.nl";