diff -urN imap-2001a.RELEASE-CANDIDATE.2.orig/Makefile imap-2001a.RELEASE-CANDIDATE.2/Makefile --- imap-2001a.RELEASE-CANDIDATE.2.orig/Makefile Fri Oct 19 18:53:15 2001 +++ imap-2001a.RELEASE-CANDIDATE.2/Makefile Mon Oct 29 17:46:41 2001 @@ -211,8 +211,17 @@ # years. The Orthodox and Gregorian calendars diverge by 1 day for # gradually-increasing intervals, starting at 2800-2900, and becoming # permanent at 48,300. +# +# -DBLOCKFSWANDERING +# Will prevent fileops with '/' or '..', or anything else that would +# let a user wander around your server's filesystem +# (like select /etc/passwd). +# If used in conjunction with DHOMEMAILDIR, it will prevent a cracker +# to browse through a user's homedir if they somehow steal their mail +# password (they'd be confined to the mail directory) +# (by Marc MERLIN, http://marc.merlins.org/linux/uwimap/) -EXTRACFLAGS= +EXTRACFLAGS=-DBLOCKFSWANDERING # Extra linker flags (additional/alternative libraries, etc.) diff -urN imap-2001a.RELEASE-CANDIDATE.2.orig/src/osdep/unix/env_unix.c imap-2001a.RELEASE-CANDIDATE.2/src/osdep/unix/env_unix.c --- imap-2001a.RELEASE-CANDIDATE.2.orig/src/osdep/unix/env_unix.c Wed Oct 17 20:35:20 2001 +++ imap-2001a.RELEASE-CANDIDATE.2/src/osdep/unix/env_unix.c Thu Nov 1 15:27:15 2001 @@ -833,12 +856,37 @@ char *mailboxfile (char *dst,char *name) { + char tmp[MAILTMPLEN]; struct passwd *pw; char *dir = mymailboxdir (); *dst = '\0'; /* default to empty string */ /* check invalid name */ if (!name || !*name || (*name == '{') || (strlen (name) > NETMAXMBX)) return NIL; + +#ifdef BLOCKFSWANDERING +/* + * As far as I can tell, all file accesses go through this, so blocking unwanted + * paths here should be enough. Let me know if I'm wrong + * -- Marc 2001/11/01 + */ + + /* Preventing names that start with # is bad because clients like netscape + * will do 18 different queries based on those names, and they will all + * fail one per one. You are responsible for making sure that #ftp or + * #public doesn't lead to anything you don't want people to see + */ + + /* netscape will also try to select "~" which is ok, let's not deny that */ + /* ~/foo is cool too, as well as /var/spool/mail/foo */ + if ((name[0] == '/' && strstr(name, MAILSPOOL) != name) || (name[0] == '~' && name[1] != 0 && name[1] != '/') || (strstr(name, "..") != NULL)) + { + sprintf (tmp,"Security: mailboxfile() blocked access to %s by %s", name, myUserName); + syslog (LOG_ERR, tmp); + MM_LOG (tmp,ERROR); + return NIL; + } +#endif /* check for INBOX */ if (((name[0] == 'I') || (name[0] == 'i')) && ((name[1] == 'N') || (name[1] == 'n')) &&