From c2dab16c8c57202952b3824d7a32e5b55cebb4ff Mon Sep 17 00:00:00 2001 From: zzz <zzz@mail.i2p> Date: Fri, 25 Apr 2014 03:42:18 +0000 Subject: [PATCH] * SusiMail: - Add icons for attachments and spam (from Silk icons, same license as others) - Add checks for POST for XSS prevention --- apps/susimail/build.xml | 4 ++ apps/susimail/src/icons/attach.png | Bin 0 -> 391 bytes apps/susimail/src/icons/flag_red.png | Bin 0 -> 665 bytes .../src/src/i2p/susi/webmail/Mail.java | 14 +++++ .../src/src/i2p/susi/webmail/WebMail.java | 52 ++++++++++++------ 5 files changed, 52 insertions(+), 18 deletions(-) create mode 100644 apps/susimail/src/icons/attach.png create mode 100644 apps/susimail/src/icons/flag_red.png diff --git a/apps/susimail/build.xml b/apps/susimail/build.xml index 4c79fdfd2a..bb80ea2744 100644 --- a/apps/susimail/build.xml +++ b/apps/susimail/build.xml @@ -62,6 +62,10 @@ <!-- set if unset --> <property name="workspace.changes.tr" value="" /> <copy file="src/susimail.properties" todir="src/WEB-INF/classes" /> + <mkdir dir="src/WEB-INF/classes/icons" /> + <copy todir="src/WEB-INF/classes/icons" > + <fileset dir="src/icons" /> + </copy> <war destfile="susimail.war" webxml="src/WEB-INF/web.xml" basedir="src/" excludes="WEB-INF/web.xml LICENSE src/**/*"> <manifest> diff --git a/apps/susimail/src/icons/attach.png b/apps/susimail/src/icons/attach.png new file mode 100644 index 0000000000000000000000000000000000000000..ea897cc9f18ca49aa0f30bad4e6b67e4afc7f498 GIT binary patch literal 391 zcmV;20eJq2P)<h;3K|Lk000e1NJLTq000mG000mO1ONa4wfZ;e00004XF*Lt006JZ zHwB960000PbVXQnQ*UN;cVTj606}DLVr3vnZDD6+Qe|Oed2z{QJOBUz8A(JzR4C75 z_|JeJVi8&@J?G_=Q{6UAhFBFWR-FBE()F%K4O{#E=ha~-SR_63{=|(P7wdxlGvrt# ze?wC+Uu4F;{>`oHYyCmI1nr3DC<^9@PyNudrDc9~P$75b!T6T2tv<*K=EzTZ+r6P_ zRz+%oP}<Shj^HWYH{C?x3TCTLdeSw&VS0I79%ss}n699Oo{wB5;l7xuIPpQpjJobJ z?;OtLo00Vai#%Sr%EQB9hI;?|*5$Q~#cQ&zCp?R2@L%BZ#)S_lpnBX}9#u<#IPslf zF+MZhZ@UPggk+Om#mfRw5GPpGd$HS1XEC&(F6YkMnzAKEHOSiYvg<u387y&;%p2(y laNgsoYo4P35s^ir0sur(`Xw3qNKXI&002ovPDHLkV1i2Hu=D@` literal 0 HcmV?d00001 diff --git a/apps/susimail/src/icons/flag_red.png b/apps/susimail/src/icons/flag_red.png new file mode 100644 index 0000000000000000000000000000000000000000..e8a602da7b17a323b2c9afe3d8aac62cb717a0b8 GIT binary patch literal 665 zcmV;K0%rY*P)<h;3K|Lk000e1NJLTq000mG000mO1^@s6AM^iV00004XF*Lt006JZ zHwB960000PbVXQnQ*UN;cVTj606}DLVr3vnZDD6+Qe|Oed2z{QJOBU!D@jB_R5;6} z(_ctaVHn48=?_s3f-WosEn!=hrIfCmq!*2X3c=87keLKw7)S&`QATB38G}LE6z5c? zhRtDW{wcJWxH2s>W2MxECPn{*ELdZ1op0xyVpxzDdhz3h^YVPo^S(T97!Wp}{CC5s zOO0&MCbYN{*S_u5sKy(U<JzwtO|o6lM<M2pnBB7ipQ6Ks>Fm7-Lr)M|odnZ1F`|tp z;QLC~<t;KI1IE;?3%s#Qn!M`8(_ZBwyfI>;7ZS9V!0QqC_yL9nVW1CJTMZN4M(R$+ zOTZBsFr_4h`&3JNv0I_O8fwI~`z}0v3|$@I8UFpf@&;uE8s7DoF&~bRfJhmzX*a6< zs}(O~Kx~<V8Blx?>cpZxH}pS*S{qZRPWYW?G`zW8AQcn3#1@S*BcNV6f!zi<S&(}G zu3Z90Jv<j%@9Gr0s$itFWXfgQ&RA#R-@stPDuZA#f5T7+dD(C*2TTTNcEI=;^xTJg z?F^Tf^UA)TzUw<Bz!L(#tXH&(e+bI0XYPWcbI^1P+%AGQtABn!l=Z`}PY<~Aa%7<S ze2N4Vg#ce{c)wsRg@#%&c7%>r{5lPjYZSt>eR~E27PJ0+es0y~s0ch&nN;M*NkCc% zXiQ#beHkC&om4IpK8qPut?)aNVjs<%39&#|d3=N1!OZi|I!ONj#Vr@M%?lVEC`+Fg zAQwL{?FfzVoB-$9WC=Ju7r^r86-w*!nR~wgLM67#gs;7-00000NkvXXu0mjfgI^=` literal 0 HcmV?d00001 diff --git a/apps/susimail/src/src/i2p/susi/webmail/Mail.java b/apps/susimail/src/src/i2p/susi/webmail/Mail.java index 0d3c231276..ab1acb6211 100644 --- a/apps/susimail/src/src/i2p/susi/webmail/Mail.java +++ b/apps/susimail/src/src/i2p/susi/webmail/Mail.java @@ -70,6 +70,7 @@ class Mail { private MailPart part; String[] to, cc; // addresses only, enclosed by <> private boolean isNew, isSpam; + public String contentType; public String error; @@ -154,6 +155,14 @@ class Mail { this.isNew = isNew; } + public boolean hasAttachment() { + // this isn't right but good enough to start + // if part != null query parts instead? + return contentType != null && + !contentType.contains("text/plain") && + !contentType.contains("multipart/alternative"); + } + /** * * @param address E-mail address to be validated @@ -348,6 +357,11 @@ class Mail { } else if(line.equals( "X-Spam-Flag: YES" )) { // TODO trust.spam.headers config isSpam = true; + } else if(line.toLowerCase(Locale.US).startsWith("content-type:" )) { + // this is duplicated in MailPart but + // we want to know if we have attachments, even if + // we haven't fetched the body + contentType = line.substring(13).trim(); } } } diff --git a/apps/susimail/src/src/i2p/susi/webmail/WebMail.java b/apps/susimail/src/src/i2p/susi/webmail/WebMail.java index babeffbcf5..af8a06b47a 100644 --- a/apps/susimail/src/src/i2p/susi/webmail/WebMail.java +++ b/apps/susimail/src/src/i2p/susi/webmail/WebMail.java @@ -399,7 +399,7 @@ public class WebMail extends HttpServlet MailCache mc = mailCache; Folder<String> f = folder; if (mc != null && f != null) { - if (mc.getMail(true)) { + if (MailCache.FETCH_HEADER) { String[] uidls = mc.getUIDLs(); f.setElements(uidls); } @@ -702,7 +702,7 @@ public class WebMail extends HttpServlet if (!offline) { // prime the cache, request all headers at once // otherwise they are pulled one at a time by sortBy() below - mc.getMail(true); + mc.getMail(MailCache.FETCH_HEADER); } // get through cache so we have the disk-only ones too String[] uidls = mc.getUIDLs(); @@ -767,25 +767,27 @@ public class WebMail extends HttpServlet } /** * Process all buttons, which possibly change internal state. + * Also processes ?show=x for a GET * * @param sessionObject * @param request + * @param isPOST disallow button pushes if false */ - private static void processStateChangeButtons(SessionObject sessionObject, RequestWrapper request ) + private static void processStateChangeButtons(SessionObject sessionObject, RequestWrapper request, boolean isPOST ) { /* * LOGIN/LOGOUT */ - if( sessionObject.state == STATE_AUTH ) + if( sessionObject.state == STATE_AUTH && isPOST ) processLogin( sessionObject, request ); - if( sessionObject.state != STATE_AUTH ) + if( sessionObject.state != STATE_AUTH && isPOST ) processLogout( sessionObject, request ); /* * compose dialog */ - if( sessionObject.state == STATE_NEW ) { + if( sessionObject.state == STATE_NEW && isPOST ) { // We have to make sure to get the state right even if // the user hit the back button previously if( buttonPressed( request, SEND ) ) { @@ -824,7 +826,7 @@ public class WebMail extends HttpServlet /* * message dialog */ - if( sessionObject.state == STATE_SHOW ) { + if( sessionObject.state == STATE_SHOW && isPOST ) { if( buttonPressed( request, LIST ) ) { sessionObject.state = STATE_LIST; } else if (buttonPressed( request, CANCEL ) || @@ -849,7 +851,7 @@ public class WebMail extends HttpServlet * buttons on both folder and message dialog */ if( sessionObject.state == STATE_SHOW || sessionObject.state == STATE_LIST ) { - if( buttonPressed( request, NEW ) ) { + if( isPOST && buttonPressed( request, NEW ) ) { sessionObject.state = STATE_NEW; } @@ -979,8 +981,10 @@ public class WebMail extends HttpServlet } } } + /* * folder view + * SHOW is the one parameter that's a link, not a button, so we allow it for GET */ if( sessionObject.state == STATE_LIST || sessionObject.state == STATE_SHOW) { /* @@ -1039,7 +1043,7 @@ public class WebMail extends HttpServlet if( buttonPressed( request, REFRESH ) ) { sessionObject.mailbox.refresh(); sessionObject.error += sessionObject.mailbox.lastError(); - sessionObject.mailCache.getMail(true); + sessionObject.mailCache.getMail(MailCache.FETCH_HEADER); // get through cache so we have the disk-only ones too String[] uidls = sessionObject.mailCache.getUIDLs(); if (uidls != null) @@ -1360,13 +1364,15 @@ public class WebMail extends HttpServlet ua.startsWith("Vodafone")); } /** + * The entry point for all web page loads * * @param httpRequest * @param response + * @param isPOST disallow button pushes if false * @throws IOException * @throws ServletException */ - private void processRequest( HttpServletRequest httpRequest, HttpServletResponse response ) + private void processRequest( HttpServletRequest httpRequest, HttpServletResponse response, boolean isPOST ) throws IOException, ServletException { String theme = Config.getProperty(CONFIG_THEME, DEFAULT_THEME); @@ -1418,7 +1424,7 @@ public class WebMail extends HttpServlet processComposeButtons( sessionObject, request ); int oldState = sessionObject.state; - processStateChangeButtons( sessionObject, request ); + processStateChangeButtons( sessionObject, request, isPOST ); int newState = sessionObject.state; if (oldState != newState) Debug.debug(Debug.DEBUG, "STATE CHANGE from " + oldState + " to " + newState); @@ -1430,11 +1436,14 @@ public class WebMail extends HttpServlet // Debug.debug(Debug.DEBUG, "Changed idle from " + oldIdle + " to " + newIdle); //} - if( sessionObject.state != STATE_AUTH ) - processGenericButtons( sessionObject, request ); + if( sessionObject.state != STATE_AUTH ) { + if (isPOST) + processGenericButtons( sessionObject, request ); + } if( sessionObject.state == STATE_LIST ) { - processFolderButtons( sessionObject, request ); + if (isPOST) + processFolderButtons( sessionObject, request ); for( Iterator<String> it = sessionObject.folder.currentPageIterator(); it != null && it.hasNext(); ) { String uidl = it.next(); Mail mail = sessionObject.mailCache.getMail( uidl, MailCache.FETCH_HEADER ); @@ -1446,7 +1455,8 @@ public class WebMail extends HttpServlet } if( sessionObject.state == STATE_SHOW ) { - processMessageButtons( sessionObject, request ); + if (isPOST) + processMessageButtons( sessionObject, request ); // If the last message has just been deleted then // sessionObject.state = STATE_LIST and // sessionObject.showUIDL = null @@ -1734,6 +1744,7 @@ public class WebMail extends HttpServlet } return ok; } + /** * */ @@ -1741,8 +1752,9 @@ public class WebMail extends HttpServlet public void doGet( HttpServletRequest request, HttpServletResponse response ) throws IOException, ServletException { - processRequest( request, response ); + processRequest( request, response, false ); } + /** * */ @@ -1750,8 +1762,9 @@ public class WebMail extends HttpServlet public void doPost( HttpServletRequest request, HttpServletResponse response ) throws IOException, ServletException { - processRequest( request, response ); + processRequest( request, response, true ); } + /** * * @param out @@ -1948,7 +1961,10 @@ public class WebMail extends HttpServlet // ", clear=" + sessionObject.clear ); out.println( "<tr class=\"list" + bg + "\"><td><input type=\"checkbox\" class=\"optbox\" name=\"check" + i + "\" value=\"1\"" + ( idChecked ? "checked" : "" ) + ">" + "</td><td>" + - link + mail.shortSender + "</a></td><td> </td><td>" + link + mail.shortSubject + "</a></td><td> </td><td>" + + link + mail.shortSender + "</a></td><td>" + + (mail.hasAttachment() ? "<img src=\"/susimail/icons/attach.png\" alt=\"\">" : " ") + "</td><td>" + + link + mail.shortSubject + "</a></td><td>" + + (mail.isSpam() ? "<img src=\"/susimail/icons/flag_red.png\" alt=\"\">" : " ") + "</td><td>" + // don't let date get split across lines mail.localFormattedDate.replace(" ", " ") + "</td><td> </td><td align=\"right\">" + ((mail.getSize() > 0) ? (DataHelper.formatSize2(mail.getSize()) + 'B') : "???") + "</td></tr>" ); -- GitLab