Search in sources :

Example 1 with ByteBuilder

use of com.zimbra.common.mime.HeaderUtils.ByteBuilder in project zm-mailbox by Zimbra.

the class MimeHeader method decode.

@SuppressWarnings("null")
static String decode(final byte[] content, final int start, final int length, final Charset charset) {
    // short-circuit if there are only ASCII characters and no "=?"
    final int end = start + length;
    boolean complicated = false;
    for (int pos = start; pos < end && !complicated; pos++) {
        byte c = content[pos];
        if (c <= 0 || c >= 0x7F || (c == '=' && pos < end - 1 && content[pos + 1] == '?')) {
            complicated = true;
        }
    }
    if (!complicated) {
        return unfold(createString(content, start, length, charset));
    }
    ByteBuilder builder = new ByteBuilder(length, decodingCharset(charset));
    String value = null;
    boolean encoded = false;
    Boolean encwspenc = Boolean.FALSE;
    int questions = 0, wsplength = 0;
    for (int pos = start; pos < end; pos++) {
        byte c = content[pos];
        if (c == '\r' || c == '\n') {
        // ignore folding
        } else if (c == '=' && pos < end - 2 && content[pos + 1] == '?' && (!encoded || content[pos + 2] != '=')) {
            // "=?" marks the beginning of an encoded-word
            if (!builder.isEmpty()) {
                value = builder.appendTo(value);
            }
            builder.reset();
            builder.write('=');
            encoded = true;
            questions = 0;
        } else if (c == '?' && encoded && ++questions > 3 && pos < end - 1 && content[pos + 1] == '=') {
            // "?=" may mean the end of an encoded-word, so see if it decodes correctly
            builder.write('?');
            builder.write('=');
            String decoded = HeaderUtils.decodeWord(builder.toByteArray());
            boolean valid = decoded != null;
            if (valid) {
                pos++;
            } else {
                decoded = builder.pop().toString();
            }
            // drop all whitespace between encoded-words
            if (valid && encwspenc == Boolean.TRUE) {
                value = value.substring(0, value.length() - wsplength);
            }
            value = value == null ? decoded : value + decoded;
            encwspenc = valid ? null : Boolean.FALSE;
            wsplength = 0;
            encoded = false;
            builder.reset();
        } else {
            builder.write(c);
            // track whitespace after encoded-words (enc wsp enc => remove wsp)
            boolean isWhitespace = c == ' ' || c == '\t';
            if (!encoded && encwspenc != Boolean.FALSE) {
                encwspenc = isWhitespace;
                wsplength = isWhitespace ? wsplength + 1 : 0;
            }
        }
    }
    if (!builder.isEmpty()) {
        value = builder.appendTo(value);
    }
    return value == null ? "" : value;
}
Also used : ByteBuilder(com.zimbra.common.mime.HeaderUtils.ByteBuilder)

Example 2 with ByteBuilder

use of com.zimbra.common.mime.HeaderUtils.ByteBuilder in project zm-mailbox by Zimbra.

the class FileUploadServletTest method testFileUploadAuthTokenNotCsrfEnabled.

@Test
public void testFileUploadAuthTokenNotCsrfEnabled() throws Exception {
    URL url = new URL("http://localhost:7070/service/upload?lbfums=");
    ByteBuilder bb = new ByteBuilder(CharsetUtil.UTF_8);
    addFormField(bb, "_charset_", "");
    addFormField(bb, "filename1", filename1);
    addFormFile(bb, filename1, "text/plain", content1);
    endForm(bb);
    byte[] form = bb.toByteArray();
    HashMap<String, String> headers = new HashMap<String, String>();
    Account acct = Provisioning.getInstance().get(Key.AccountBy.name, "test@zimbra.com");
    XMLElement req = new XMLElement(AccountConstants.AUTH_REQUEST);
    com.zimbra.common.soap.Element a = req.addUniqueElement(AccountConstants.E_ACCOUNT);
    a.addAttribute(AccountConstants.A_BY, "name");
    a.setText(acct.getName());
    req.addUniqueElement(AccountConstants.E_PASSWORD).setText("secret");
    Element response = new Auth().handle(req, ServiceTestUtil.getRequestContext(acct));
    String authToken = response.getElement(AccountConstants.E_AUTH_TOKEN).getText();
    MockHttpServletRequest mockreq = new MockHttpServletRequest(form, url, "multipart/form-data; boundary=" + boundary, 7070, "test", headers);
    mockreq.setAttribute(CsrfFilter.CSRF_TOKEN_CHECK, Boolean.FALSE);
    Cookie cookie = new Cookie("ZM_AUTH_TOKEN", authToken);
    mockreq.setCookies(cookie);
    MockHttpServletResponse resp = new MockHttpServletResponse();
    servlet.doPost(mockreq, resp);
    String respStrg = resp.output.toString();
    System.out.println(respStrg);
    assertTrue(respStrg.contains("200"));
}
Also used : Cookie(javax.servlet.http.Cookie) Account(com.zimbra.cs.account.Account) HashMap(java.util.HashMap) Element(com.zimbra.common.soap.Element) XMLElement(com.zimbra.common.soap.Element.XMLElement) XMLElement(com.zimbra.common.soap.Element.XMLElement) URL(java.net.URL) ByteBuilder(com.zimbra.common.mime.HeaderUtils.ByteBuilder) Auth(com.zimbra.cs.service.account.Auth) Element(com.zimbra.common.soap.Element) Test(org.junit.Test)

Example 3 with ByteBuilder

use of com.zimbra.common.mime.HeaderUtils.ByteBuilder in project zm-mailbox by Zimbra.

the class FileUploadServletTest method testFileUploadAuthTokenCsrfEnabledButNoCsrfToken.

@Test
public void testFileUploadAuthTokenCsrfEnabledButNoCsrfToken() throws Exception {
    URL url = new URL("http://localhost:7070/service/upload?lbfums=");
    ByteBuilder bb = new ByteBuilder(CharsetUtil.UTF_8);
    addFormField(bb, "_charset_", "");
    addFormField(bb, "filename1", filename1);
    addFormFile(bb, filename1, "text/plain", content1);
    endForm(bb);
    byte[] form = bb.toByteArray();
    HashMap<String, String> headers = new HashMap<String, String>();
    Account acct = Provisioning.getInstance().get(Key.AccountBy.name, "test@zimbra.com");
    XMLElement req = new XMLElement(AccountConstants.AUTH_REQUEST);
    req.addAttribute(AccountConstants.A_CSRF_SUPPORT, "1");
    com.zimbra.common.soap.Element a = req.addUniqueElement(AccountConstants.E_ACCOUNT);
    a.addAttribute(AccountConstants.A_BY, "name");
    a.setText(acct.getName());
    req.addUniqueElement(AccountConstants.E_PASSWORD).setText("secret");
    Map<String, Object> context = ServiceTestUtil.getRequestContext(acct);
    MockHttpServletRequest authReq = (MockHttpServletRequest) context.get(SoapServlet.SERVLET_REQUEST);
    authReq.setAttribute(Provisioning.A_zimbraCsrfTokenCheckEnabled, Boolean.TRUE);
    Random nonceGen = new Random();
    authReq.setAttribute(CsrfFilter.CSRF_SALT, nonceGen.nextInt() + 1);
    Element response = new Auth().handle(req, context);
    String authToken = response.getElement(AccountConstants.E_AUTH_TOKEN).getText();
    MockHttpServletRequest mockreq = new MockHttpServletRequest(form, url, "multipart/form-data; boundary=" + boundary, 7070, "test", headers);
    mockreq.setAttribute(CsrfFilter.CSRF_TOKEN_CHECK, Boolean.TRUE);
    Cookie cookie = new Cookie("ZM_AUTH_TOKEN", authToken);
    mockreq.setCookies(cookie);
    MockHttpServletResponse resp = new MockHttpServletResponse();
    servlet.doPost(mockreq, resp);
    // <html><head><script language='javascript'>function doit() { window.parent._uploadManager.loaded(401,'null'); }
    // </script></head><body onload='doit()'></body></html>
    String respStrg = resp.output.toString();
    assertTrue(respStrg.contains("401"));
}
Also used : Cookie(javax.servlet.http.Cookie) Account(com.zimbra.cs.account.Account) HashMap(java.util.HashMap) Element(com.zimbra.common.soap.Element) XMLElement(com.zimbra.common.soap.Element.XMLElement) XMLElement(com.zimbra.common.soap.Element.XMLElement) URL(java.net.URL) ByteBuilder(com.zimbra.common.mime.HeaderUtils.ByteBuilder) Random(java.util.Random) Auth(com.zimbra.cs.service.account.Auth) Element(com.zimbra.common.soap.Element) Test(org.junit.Test)

Example 4 with ByteBuilder

use of com.zimbra.common.mime.HeaderUtils.ByteBuilder in project zm-mailbox by Zimbra.

the class FileUploadServletTest method testFileUploadAuthTokenCsrfEnabled2.

@Test
public void testFileUploadAuthTokenCsrfEnabled2() throws Exception {
    HashMap<String, String> headers = new HashMap<String, String>();
    Account acct = Provisioning.getInstance().get(Key.AccountBy.name, "test2@zimbra.com");
    XMLElement req = new XMLElement(AccountConstants.AUTH_REQUEST);
    req.addAttribute(AccountConstants.A_CSRF_SUPPORT, "1");
    com.zimbra.common.soap.Element a = req.addUniqueElement(AccountConstants.E_ACCOUNT);
    a.addAttribute(AccountConstants.A_BY, "name");
    a.setText(acct.getName());
    req.addUniqueElement(AccountConstants.E_PASSWORD).setText("secret");
    Map<String, Object> context = ServiceTestUtil.getRequestContext(acct);
    MockHttpServletRequest authReq = (MockHttpServletRequest) context.get(SoapServlet.SERVLET_REQUEST);
    authReq.setAttribute(Provisioning.A_zimbraCsrfTokenCheckEnabled, Boolean.TRUE);
    Random nonceGen = new Random();
    authReq.setAttribute(CsrfFilter.CSRF_SALT, nonceGen.nextInt() + 1);
    Element response = new Auth().handle(req, context);
    String authToken = response.getElement(AccountConstants.E_AUTH_TOKEN).getText();
    String csrfToken = response.getElement("csrfToken").getText();
    URL url = new URL("http://localhost:7070/service/upload?lbfums=");
    ByteBuilder bb = new ByteBuilder(CharsetUtil.UTF_8);
    addFormField(bb, "_charset_", "");
    addFormField(bb, "filename1", filename1);
    addFormField(bb, "csrfToken", csrfToken);
    addFormFile(bb, filename1, "text/plain", content1);
    endForm(bb);
    byte[] form = bb.toByteArray();
    MockHttpServletRequest mockreq = new MockHttpServletRequest(form, url, "multipart/form-data; boundary=" + boundary, 7070, "test", headers);
    mockreq.setAttribute(CsrfFilter.CSRF_TOKEN_CHECK, Boolean.TRUE);
    Cookie cookie = new Cookie("ZM_AUTH_TOKEN", authToken);
    mockreq.setCookies(cookie);
    MockHttpServletResponse resp = new MockHttpServletResponse();
    servlet.doPost(mockreq, resp);
    String respStrg = resp.output.toString();
    assertTrue(respStrg.contains("200"));
}
Also used : Cookie(javax.servlet.http.Cookie) Account(com.zimbra.cs.account.Account) HashMap(java.util.HashMap) Element(com.zimbra.common.soap.Element) XMLElement(com.zimbra.common.soap.Element.XMLElement) XMLElement(com.zimbra.common.soap.Element.XMLElement) URL(java.net.URL) ByteBuilder(com.zimbra.common.mime.HeaderUtils.ByteBuilder) Random(java.util.Random) Auth(com.zimbra.cs.service.account.Auth) Element(com.zimbra.common.soap.Element) Test(org.junit.Test)

Example 5 with ByteBuilder

use of com.zimbra.common.mime.HeaderUtils.ByteBuilder in project zm-mailbox by Zimbra.

the class FileUploadServletTest method testFilenames.

@Test
public void testFilenames() throws Exception {
    ByteBuilder bb = new ByteBuilder(CharsetUtil.UTF_8);
    addFormField(bb, "_charset_", "");
    addFormField(bb, "filename1", filename1);
    addFormFile(bb, filename1, "text/plain", content1);
    addFormField(bb, "filename2", filename2);
    addFormFile(bb, filename2, "text/plain", content2);
    addFormField(bb, "filename3", "");
    addFormFile(bb, "", null, null);
    endForm(bb);
    List<Upload> uploads = uploadForm(bb.toByteArray());
    Assert.assertEquals(2, uploads == null ? 0 : uploads.size());
    compareUploads(uploads.get(0), filename1, content1.getBytes(CharsetUtil.UTF_8));
    compareUploads(uploads.get(1), filename2, content2.getBytes(CharsetUtil.UTF_8));
}
Also used : ByteBuilder(com.zimbra.common.mime.HeaderUtils.ByteBuilder) Upload(com.zimbra.cs.service.FileUploadServlet.Upload) Test(org.junit.Test)

Aggregations

ByteBuilder (com.zimbra.common.mime.HeaderUtils.ByteBuilder)10 Test (org.junit.Test)8 HashMap (java.util.HashMap)5 Element (com.zimbra.common.soap.Element)4 XMLElement (com.zimbra.common.soap.Element.XMLElement)4 Account (com.zimbra.cs.account.Account)4 Upload (com.zimbra.cs.service.FileUploadServlet.Upload)4 Auth (com.zimbra.cs.service.account.Auth)4 URL (java.net.URL)4 Cookie (javax.servlet.http.Cookie)4 Random (java.util.Random)3 UnsupportedEncodingException (java.io.UnsupportedEncodingException)1 Charset (java.nio.charset.Charset)1 LinkedHashMap (java.util.LinkedHashMap)1 Map (java.util.Map)1 TreeMap (java.util.TreeMap)1