Search in sources :

Example 1 with BrowserDefang

use of com.zimbra.cs.html.BrowserDefang in project zm-mailbox by Zimbra.

the class Signature method getContents.

public Set<SignatureContent> getContents() {
    Set<SignatureContent> contents = new HashSet<SignatureContent>();
    BrowserDefang defanger = DefangFactory.getDefanger(MimeConstants.CT_TEXT_HTML);
    for (Iterator it = SignatureUtil.ATTR_TYPE_MAP.entrySet().iterator(); it.hasNext(); ) {
        Map.Entry entry = (Map.Entry) it.next();
        String content = getAttr((String) entry.getKey());
        if (content != null) {
            if (entry.getKey().equals(ZAttrProvisioning.A_zimbraPrefMailSignatureHTML)) {
                StringReader reader = new StringReader(content);
                try {
                    content = defanger.defang(reader, false);
                } catch (IOException e) {
                    ZimbraLog.misc.info("Error sanitizing html signature: %s", content);
                }
            }
            contents.add(new SignatureContent((String) entry.getValue(), content));
        }
    }
    return contents;
}
Also used : Iterator(java.util.Iterator) StringReader(java.io.StringReader) BrowserDefang(com.zimbra.cs.html.BrowserDefang) IOException(java.io.IOException) Map(java.util.Map) HashSet(java.util.HashSet)

Example 2 with BrowserDefang

use of com.zimbra.cs.html.BrowserDefang in project zm-mailbox by Zimbra.

the class ToXML method encodeInviteComponent.

public static Element encodeInviteComponent(Element parent, ItemIdFormatter ifmt, OperationContext octxt, CalendarItem calItem, /* may be null */
ItemId calId, /* may be null */
Invite invite, int fields, boolean neuter) throws ServiceException {
    boolean allFields = true;
    if (fields != NOTIFY_FIELDS) {
        allFields = false;
        if (!needToOutput(fields, Change.INVITE)) {
            return parent;
        }
    }
    Element e = parent.addNonUniqueElement(MailConstants.E_INVITE_COMPONENT);
    e.addAttribute(MailConstants.A_CAL_METHOD, invite.getMethod());
    e.addAttribute(MailConstants.A_CAL_COMPONENT_NUM, invite.getComponentNum());
    if (invite.hasRsvp()) {
        e.addAttribute(MailConstants.A_CAL_RSVP, invite.getRsvp());
    }
    boolean allowPrivateAccess = calItem != null ? allowPrivateAccess(octxt, calItem) : true;
    if (allFields) {
        if (invite.isPublic() || allowPrivateAccess) {
            String priority = invite.getPriority();
            if (priority != null) {
                e.addAttribute(MailConstants.A_CAL_PRIORITY, priority);
            }
            e.addAttribute(MailConstants.A_NAME, invite.getName());
            e.addAttribute(MailConstants.A_CAL_LOCATION, invite.getLocation());
            List<String> categories = invite.getCategories();
            if (categories != null) {
                for (String cat : categories) {
                    e.addNonUniqueElement(MailConstants.E_CAL_CATEGORY).setText(cat);
                }
            }
            List<String> comments = invite.getComments();
            if (comments != null) {
                for (String cmt : comments) {
                    e.addNonUniqueElement(MailConstants.E_CAL_COMMENT).setText(cmt);
                }
            }
            List<String> contacts = invite.getContacts();
            if (contacts != null) {
                for (String contact : contacts) {
                    e.addNonUniqueElement(MailConstants.E_CAL_CONTACT).setText(contact);
                }
            }
            Geo geo = invite.getGeo();
            if (geo != null) {
                geo.toXml(e);
            }
            // Percent Complete (VTODO)
            if (invite.isTodo()) {
                String pct = invite.getPercentComplete();
                if (pct != null)
                    e.addAttribute(MailConstants.A_TASK_PERCENT_COMPLETE, pct);
                long completed = invite.getCompleted();
                if (completed != 0) {
                    ParsedDateTime c = ParsedDateTime.fromUTCTime(completed);
                    e.addAttribute(MailConstants.A_TASK_COMPLETED, c.getDateTimePartString());
                }
            }
            // Attendee(s)
            List<ZAttendee> attendees = invite.getAttendees();
            for (ZAttendee at : attendees) {
                at.toXml(e);
            }
            // Alarms
            Iterator<Alarm> alarmsIter = invite.alarmsIterator();
            while (alarmsIter.hasNext()) {
                Alarm alarm = alarmsIter.next();
                alarm.toXml(e);
            }
            // x-prop
            encodeXProps(e, invite.xpropsIterator());
            // fragment
            String fragment = invite.getFragment();
            if (!Strings.isNullOrEmpty(fragment)) {
                e.addAttribute(MailConstants.E_FRAG, fragment, Element.Disposition.CONTENT);
            }
            if (!invite.hasBlobPart()) {
                e.addAttribute(MailConstants.A_CAL_NO_BLOB, true);
            }
            // Description (plain and html)
            String desc = invite.getDescription();
            if (desc != null) {
                Element descElem = e.addNonUniqueElement(MailConstants.E_CAL_DESCRIPTION);
                descElem.setText(desc);
            }
            String descHtml = invite.getDescriptionHtml();
            BrowserDefang defanger = DefangFactory.getDefanger(MimeConstants.CT_TEXT_HTML);
            if (descHtml != null) {
                try {
                    descHtml = StringUtil.stripControlCharacters(descHtml);
                    descHtml = defanger.defang(descHtml, neuter);
                    Element descHtmlElem = e.addNonUniqueElement(MailConstants.E_CAL_DESC_HTML);
                    descHtmlElem.setText(descHtml);
                } catch (IOException ex) {
                    ZimbraLog.calendar.warn("Unable to defang HTML for SetAppointmentRequest", ex);
                }
            }
            if (invite.isEvent()) {
                if (calItem != null && calItem instanceof Appointment) {
                    Instance inst = Instance.fromInvite(calItem.getId(), invite);
                    Appointment appt = (Appointment) calItem;
                    e.addAttribute(MailConstants.A_APPT_FREEBUSY_ACTUAL, appt.getEffectiveFreeBusyActual(invite, inst));
                }
                e.addAttribute(MailConstants.A_APPT_FREEBUSY, invite.getFreeBusy());
                e.addAttribute(MailConstants.A_APPT_TRANSPARENCY, invite.getTransparency());
            }
            // Organizer
            if (invite.hasOrganizer()) {
                ZOrganizer org = invite.getOrganizer();
                org.toXml(e);
            }
            e.addAttribute(MailConstants.A_CAL_URL, invite.getUrl());
        }
        if (invite.isOrganizer()) {
            e.addAttribute(MailConstants.A_CAL_ISORG, true);
        }
        boolean isRecurring = false;
        e.addAttribute("x_uid", invite.getUid());
        e.addAttribute(MailConstants.A_UID, invite.getUid());
        e.addAttribute(MailConstants.A_CAL_SEQUENCE, invite.getSeqNo());
        // zdsync
        e.addAttribute(MailConstants.A_CAL_DATETIME, invite.getDTStamp());
        String itemId = null;
        if (calId != null) {
            itemId = calId.toString(ifmt);
        } else if (calItem != null) {
            itemId = ifmt.formatItemId(calItem);
        }
        if ((itemId != null) && !("0".equals(itemId))) {
            e.addAttribute(MailConstants.A_CAL_ID, /* calItemId */
            itemId);
            if (invite.isEvent()) {
                // for backward compat
                e.addAttribute(MailConstants.A_APPT_ID_DEPRECATE_ME, /* apptId */
                itemId);
            }
            if (calItem != null) {
                ItemId ciFolderId = new ItemId(calItem.getMailbox(), calItem.getFolderId());
                e.addAttribute(MailConstants.A_CAL_ITEM_FOLDER, /* ciFolder */
                ifmt.formatItemId(ciFolderId));
            }
        }
        Recurrence.IRecurrence recur = invite.getRecurrence();
        if (recur != null) {
            isRecurring = true;
            Element recurElt = e.addNonUniqueElement(MailConstants.E_CAL_RECUR);
            recur.toXml(recurElt);
        }
        e.addAttribute(MailConstants.A_CAL_STATUS, invite.getStatus());
        e.addAttribute(MailConstants.A_CAL_CLASS, invite.getClassProp());
        boolean allDay = invite.isAllDayEvent();
        boolean isException = invite.hasRecurId();
        if (isException) {
            e.addAttribute(MailConstants.A_CAL_IS_EXCEPTION, true);
            RecurId rid = invite.getRecurId();
            e.addAttribute(MailConstants.A_CAL_RECURRENCE_ID_Z, rid.getDtZ());
            encodeRecurId(e, rid, allDay);
        }
        boolean forceUTC = DebugConfig.calendarForceUTC && !isRecurring && !isException && !allDay;
        ParsedDateTime dtStart = invite.getStartTime();
        if (dtStart != null) {
            encodeDtStart(e, dtStart, allDay, forceUTC);
        }
        ParsedDateTime dtEnd = invite.getEndTime();
        if (dtEnd != null) {
            encodeDtEnd(e, dtEnd, allDay, invite.isTodo(), forceUTC);
        }
        ParsedDuration dur = invite.getDuration();
        if (dur != null) {
            dur.toXml(e);
        }
        if (allDay) {
            e.addAttribute(MailConstants.A_CAL_ALLDAY, true);
        }
        if (invite.isDraft()) {
            e.addAttribute(MailConstants.A_CAL_DRAFT, true);
        }
        if (invite.isNeverSent()) {
            e.addAttribute(MailConstants.A_CAL_NEVER_SENT, true);
        }
    }
    return e;
}
Also used : Appointment(com.zimbra.cs.mailbox.Appointment) Recurrence(com.zimbra.cs.mailbox.calendar.Recurrence) IRecurrence(com.zimbra.cs.mailbox.calendar.Recurrence.IRecurrence) Instance(com.zimbra.cs.mailbox.CalendarItem.Instance) IRecurrence(com.zimbra.cs.mailbox.calendar.Recurrence.IRecurrence) ParsedDuration(com.zimbra.common.calendar.ParsedDuration) Element(com.zimbra.common.soap.Element) ZOrganizer(com.zimbra.cs.mailbox.calendar.ZOrganizer) BrowserDefang(com.zimbra.cs.html.BrowserDefang) RecurId(com.zimbra.cs.mailbox.calendar.RecurId) IOException(java.io.IOException) ItemId(com.zimbra.cs.service.util.ItemId) Geo(com.zimbra.common.calendar.Geo) ZAttendee(com.zimbra.cs.mailbox.calendar.ZAttendee) Alarm(com.zimbra.cs.mailbox.calendar.Alarm) ParsedDateTime(com.zimbra.common.calendar.ParsedDateTime)

Example 3 with BrowserDefang

use of com.zimbra.cs.html.BrowserDefang in project zm-mailbox by Zimbra.

the class NativeFormatter method sendbackOriginalDoc.

private static void sendbackOriginalDoc(InputStream is, String contentType, String defaultCharset, String filename, String desc, long size, HttpServletRequest req, HttpServletResponse resp) throws IOException {
    String disp = req.getParameter(UserServlet.QP_DISP);
    disp = (disp == null || disp.toLowerCase().startsWith("i")) ? Part.INLINE : Part.ATTACHMENT;
    if (desc != null && desc.length() <= 2048) {
        // do not return ridiculously long header.
        if (desc.contains(" ") && !(desc.startsWith("\"") && desc.endsWith("\""))) {
            desc = "\"" + desc.trim() + "\"";
        }
        resp.addHeader("Content-Description", desc);
    }
    // defang when the html and svg attachment was requested with disposition inline
    if (disp.equals(Part.INLINE) && isScriptableContent(contentType)) {
        BrowserDefang defanger = DefangFactory.getDefanger(contentType);
        String content = defanger.defang(Mime.getTextReader(is, contentType, defaultCharset), true);
        resp.setContentType(contentType);
        String charset = Mime.getCharset(contentType);
        resp.setCharacterEncoding(Strings.isNullOrEmpty(charset) ? Charsets.UTF_8.name() : charset);
        if (!content.isEmpty()) {
            resp.setContentLength(content.getBytes().length);
        }
        resp.getWriter().write(content);
    } else {
        // flash attachment may contain a malicious script hence..
        if (contentType.startsWith(MimeConstants.CT_APPLICATION_SHOCKWAVE_FLASH)) {
            disp = Part.ATTACHMENT;
        }
        resp.setContentType(contentType);
        sendbackBinaryData(req, resp, is, contentType, disp, filename, size);
    }
}
Also used : BrowserDefang(com.zimbra.cs.html.BrowserDefang)

Example 4 with BrowserDefang

use of com.zimbra.cs.html.BrowserDefang in project zm-mailbox by Zimbra.

the class ToXML method addContent.

/**
 * Adds the decoded text content of a message part to the {@link Element}.
 *  The content is added as the value of a new <tt>&lt;content></tt>
 *  sub-element.  <i>Note: This method will only extract the content of a
 *  <b>text/*</b> or <b>xml/*</b> message part.</i>
 *
 * @param elt     The element to add the <tt>&lt;content></tt> to.
 * @param mpi     The message part to extract the content from.
 * @param maxSize The maximum number of characters to inline (<=0 is unlimited).
 * @param neuter  Whether to "neuter" image <tt>src</tt> attributes.
 * @parame defaultCharset  The user's default charset preference.
 * @throws MessagingException when message parsing or CTE-decoding fails
 * @throws IOException on error during parsing or defanging
 * @see HtmlDefang#defang(String, boolean)
 */
private static void addContent(Element elt, MPartInfo mpi, int maxSize, boolean neuter, String defaultCharset, MsgContent wantContent) throws IOException, MessagingException {
    // TODO: support other parts
    String ctype = mpi.getContentType();
    if (!ctype.matches(MimeConstants.CT_TEXT_WILD) && !ctype.matches(MimeConstants.CT_XML_WILD)) {
        return;
    }
    MimePart mp = mpi.getMimePart();
    Mime.repairTransferEncoding(mp);
    String data = null;
    String originalContent = null;
    wantContent = wantContent == null ? MsgContent.full : wantContent;
    try {
        if (maxSize <= 0) {
            maxSize = (int) Provisioning.getInstance().getLocalServer().getMailContentMaxSize();
        } else {
            maxSize = Math.min(maxSize, (int) Provisioning.getInstance().getLocalServer().getMailContentMaxSize());
        }
    } catch (ServiceException e) {
        ZimbraLog.soap.warn("Unable to determine max content size", e);
    }
    boolean wasTruncated = false;
    if (ctype.equals(MimeConstants.CT_TEXT_HTML)) {
        String charset = mpi.getContentTypeParameter(MimeConstants.P_CHARSET);
        InputStream stream = null;
        StringWriter sw = new StringWriter();
        TruncatingWriter tw = null;
        Writer out = sw;
        if (maxSize > 0) {
            tw = new TruncatingWriter(sw, maxSize + 1);
            out = tw;
        }
        Reader reader = null;
        try {
            stream = mp.getInputStream();
            if (charset != null && !charset.trim().isEmpty()) {
                // make sure to feed getTextReader() a full Content-Type header, not just the primary/subtype portion
                reader = Mime.getTextReader(stream, mp.getContentType(), defaultCharset);
                BrowserDefang defanger = DefangFactory.getDefanger(mp.getContentType());
                defanger.defang(reader, neuter, out);
                data = sw.toString();
            } else {
                String cte = mp.getEncoding();
                if (cte != null && !cte.trim().toLowerCase().equals(MimeConstants.ET_7BIT)) {
                    try {
                        DefangFactory.getDefanger(ctype).defang(stream, neuter, out);
                        data = sw.toString();
                    } catch (IOException e) {
                    }
                }
                if (data == null) {
                    reader = Mime.getTextReader(stream, mp.getContentType(), defaultCharset);
                    DefangFactory.getDefanger(ctype).defang(reader, neuter, out);
                    data = sw.toString();
                }
            }
            if (wantContent.equals(MsgContent.original) || wantContent.equals(MsgContent.both)) {
                originalContent = removeQuotedText(data, true);
            }
        } finally {
            if (tw != null) {
                wasTruncated = tw.wasTruncated();
            }
            ByteUtil.closeStream(stream);
            Closeables.closeQuietly(reader);
        }
    } else if (ctype.equals(MimeConstants.CT_TEXT_ENRICHED)) {
        // Enriched text handling is a little funky because TextEnrichedHandler
        // doesn't use Reader and Writer.  As a result, we truncate
        // the source before converting to HTML.
        InputStream stream = mp.getInputStream();
        Reader reader = null;
        try {
            reader = Mime.getTextReader(stream, mp.getContentType(), defaultCharset);
            int maxChars = (maxSize > 0 ? maxSize + 1 : -1);
            String enriched = ByteUtil.getContent(reader, maxChars, false);
            if (enriched.length() == maxChars) {
                // The normal check for truncated data won't work because
                // the length of the converted text is different than the length
                // of the source, so set the attr here.
                wasTruncated = true;
            }
            if (wantContent.equals(MsgContent.original) || wantContent.equals(MsgContent.both)) {
                originalContent = TextEnrichedHandler.convertToHTML(removeQuotedText(enriched, false));
            }
            data = TextEnrichedHandler.convertToHTML(enriched);
        } finally {
            ByteUtil.closeStream(stream);
            Closeables.closeQuietly(reader);
        }
    } else {
        InputStream stream = mp.getInputStream();
        Reader reader = null;
        try {
            reader = Mime.getTextReader(stream, mp.getContentType(), defaultCharset);
            int maxChars = (maxSize > 0 ? maxSize + 1 : -1);
            data = ByteUtil.getContent(reader, maxChars, false);
            if (wantContent.equals(MsgContent.original) || wantContent.equals(MsgContent.both)) {
                originalContent = removeQuotedText(data, false);
            }
            if (data.length() == maxChars) {
                wasTruncated = true;
            }
        } finally {
            ByteUtil.closeStream(stream);
            Closeables.closeQuietly(reader);
        }
    }
    if (data != null && !wantContent.equals(MsgContent.original)) {
        data = StringUtil.stripControlCharacters(data);
        if (wasTruncated) {
            elt.addAttribute(MailConstants.A_TRUNCATED_CONTENT, true);
            if (data.length() > maxSize) {
                data = data.substring(0, maxSize);
            }
        }
        elt.addAttribute(MailConstants.E_CONTENT, data, Element.Disposition.CONTENT);
    }
    if (originalContent != null && (wantContent.equals(MsgContent.original) || wantContent.equals(MsgContent.both))) {
        originalContent = StringUtil.stripControlCharacters(originalContent);
        elt.addUniqueElement(MailConstants.E_ORIG_CONTENT).setText(originalContent);
    }
// TODO: CDATA worth the effort?
}
Also used : ServiceException(com.zimbra.common.service.ServiceException) MailServiceException(com.zimbra.cs.mailbox.MailServiceException) StringWriter(java.io.StringWriter) InputStream(java.io.InputStream) TruncatingWriter(com.zimbra.common.util.TruncatingWriter) MimePart(javax.mail.internet.MimePart) Reader(java.io.Reader) BrowserDefang(com.zimbra.cs.html.BrowserDefang) IOException(java.io.IOException) TruncatingWriter(com.zimbra.common.util.TruncatingWriter) StringWriter(java.io.StringWriter) Writer(java.io.Writer)

Aggregations

BrowserDefang (com.zimbra.cs.html.BrowserDefang)4 IOException (java.io.IOException)3 Geo (com.zimbra.common.calendar.Geo)1 ParsedDateTime (com.zimbra.common.calendar.ParsedDateTime)1 ParsedDuration (com.zimbra.common.calendar.ParsedDuration)1 ServiceException (com.zimbra.common.service.ServiceException)1 Element (com.zimbra.common.soap.Element)1 TruncatingWriter (com.zimbra.common.util.TruncatingWriter)1 Appointment (com.zimbra.cs.mailbox.Appointment)1 Instance (com.zimbra.cs.mailbox.CalendarItem.Instance)1 MailServiceException (com.zimbra.cs.mailbox.MailServiceException)1 Alarm (com.zimbra.cs.mailbox.calendar.Alarm)1 RecurId (com.zimbra.cs.mailbox.calendar.RecurId)1 Recurrence (com.zimbra.cs.mailbox.calendar.Recurrence)1 IRecurrence (com.zimbra.cs.mailbox.calendar.Recurrence.IRecurrence)1 ZAttendee (com.zimbra.cs.mailbox.calendar.ZAttendee)1 ZOrganizer (com.zimbra.cs.mailbox.calendar.ZOrganizer)1 ItemId (com.zimbra.cs.service.util.ItemId)1 InputStream (java.io.InputStream)1 Reader (java.io.Reader)1