From cca3417b87f6d5e607ea327a15923c5425755ee9 Mon Sep 17 00:00:00 2001 From: luccioman Date: Mon, 28 Nov 2016 22:10:05 +0100 Subject: [PATCH] Fixed image and favicon viewing for unauthenticated local requests. As reported by @reger24, image and favicon viewing was broken with unauthenticated requests on peers configured to require authentication even from localhost. So I unified viewing rights check in a single new function on ImageViewer class. --- htroot/ViewFavicon.java | 4 +--- htroot/ViewImage.java | 4 +--- htroot/yacysearchitem.java | 20 +++++++++---------- .../net/yacy/visualization/ImageViewer.java | 14 +++++++++++++ 4 files changed, 26 insertions(+), 16 deletions(-) diff --git a/htroot/ViewFavicon.java b/htroot/ViewFavicon.java index bed1dc871..492a5cb3a 100644 --- a/htroot/ViewFavicon.java +++ b/htroot/ViewFavicon.java @@ -29,7 +29,6 @@ import javax.imageio.stream.ImageInputStream; import net.yacy.cora.document.id.DigestURL; import net.yacy.cora.document.id.MultiProtocolURL; -import net.yacy.cora.protocol.Domains; import net.yacy.cora.protocol.HeaderFramework; import net.yacy.cora.protocol.RequestHeader; import net.yacy.cora.storage.ConcurrentARC; @@ -98,8 +97,7 @@ public class ViewFavicon { pngIconCache.clear(); } - final boolean auth = Domains.isLocalhost(header.getRemoteAddr()) - || sb.verifyAuthentication(header); // handle access rights + final boolean auth = ImageViewer.hasFullViewingRights(header, sb); // handle access rights DigestURL url = VIEWER.parseURL(post, auth); diff --git a/htroot/ViewImage.java b/htroot/ViewImage.java index 53f6d5241..1db8970eb 100644 --- a/htroot/ViewImage.java +++ b/htroot/ViewImage.java @@ -29,7 +29,6 @@ import javax.imageio.stream.ImageInputStream; import net.yacy.cora.document.id.DigestURL; import net.yacy.cora.document.id.MultiProtocolURL; -import net.yacy.cora.protocol.Domains; import net.yacy.cora.protocol.HeaderFramework; import net.yacy.cora.protocol.RequestHeader; import net.yacy.http.servlets.TemplateMissingParameterException; @@ -77,8 +76,7 @@ public class ViewImage { } String ext = header.get(HeaderFramework.CONNECTION_PROP_EXT, null); - final boolean auth = Domains.isLocalhost(header.getRemoteAddr()) - || sb.verifyAuthentication(header); // handle access rights + final boolean auth = ImageViewer.hasFullViewingRights(header, sb); // handle access rights DigestURL url = VIEWER.parseURL(post, auth); diff --git a/htroot/yacysearchitem.java b/htroot/yacysearchitem.java index 9e7a2af7e..271c9c4a5 100644 --- a/htroot/yacysearchitem.java +++ b/htroot/yacysearchitem.java @@ -185,7 +185,7 @@ public class yacysearchitem { if ((fileType == FileType.HTML || fileType == FileType.JSON) && !sb.isIntranetMode()) { faviconURL = getFaviconURL(result, new Dimension(16, 16)); } - prop.putHTML("content_faviconUrl", processFaviconURL(authenticated, faviconURL)); + prop.putHTML("content_faviconUrl", processFaviconURL(ImageViewer.hasFullViewingRights(header, sb), faviconURL)); prop.put("content_urlhash", urlhash); prop.put("content_ranking", Float.toString(result.score())); Date[] events = result.events(); @@ -300,7 +300,7 @@ public class yacysearchitem { if (theSearch.query.contentdom == Classification.ContentDomain.IMAGE) { // image search; shows thumbnails - processImage(sb, prop, item, theSearch, target_special_pattern, timeout, authenticated); + processImage(sb, prop, item, theSearch, target_special_pattern, timeout, ImageViewer.hasFullViewingRights(header, sb)); theSearch.query.transmitcount = item + 1; return prop; } @@ -368,14 +368,14 @@ public class yacysearchitem { } /** - * @param authenticated - * true when current user is authenticated + * @param hasFullViewingRights + * true when current user has full favicon viewing rights * @param faviconURL * url icon of web site * @return url to propose in search result or empty string when faviconURL * is null */ - private static String processFaviconURL(final boolean authenticated, DigestURL faviconURL) { + private static String processFaviconURL(final boolean hasFullViewingRights, DigestURL faviconURL) { /* Only use licence code for non authentified users. For authenticated users licence would never be released and would unnecessarily fill URLLicense.permissions. */ StringBuilder contentFaviconURL = new StringBuilder(); if (faviconURL != null) { @@ -384,7 +384,7 @@ public class yacysearchitem { final String viewFaviconExt = !iconUrlExt.isEmpty() && ImageViewer.isBrowserRendered(iconUrlExt) ? iconUrlExt : "png"; contentFaviconURL.append("ViewFavicon.").append(viewFaviconExt).append("?maxwidth=16&maxheight=16&isStatic=true&quadratic"); - if (authenticated) { + if (hasFullViewingRights) { contentFaviconURL.append("&url=").append(faviconURL.toNormalform(true)); } else { contentFaviconURL.append("&code=").append(URLLicense.aquireLicense(faviconURL)); @@ -466,10 +466,10 @@ public class yacysearchitem { * @param theSearch search event * @param target_special_pattern * @param timeout result getting timeOut - * @param authenticated set to true when user authentication is ok + * @param fullViewingRights set to true when current user has full image viewing rights */ private static void processImage(final Switchboard sb, final serverObjects prop, final int item, - final SearchEvent theSearch, final String target_special_pattern, long timeout, boolean authenticated) { + final SearchEvent theSearch, final String target_special_pattern, long timeout, boolean fullViewingRights) { prop.put("content", theSearch.query.contentdom.getCode() + 1); // switch on specific content try { SearchEvent.ImageResult image = theSearch.oneImageResult(item, timeout); @@ -485,7 +485,7 @@ public class yacysearchitem { .append(DEFAULT_IMG_WIDTH).append("&maxheight=").append(DEFAULT_IMG_HEIGHT) .append("&isStatic=true&quadratic"); /* Only use licence code for non authentified users. For authenticated users licence would never be released and would unnecessarily fill URLLicense.permissions. */ - if(authenticated) { + if(fullViewingRights) { thumbURLBuilder.append("&url=").append(imageUrlstring); } else { thumbURLBuilder.append("&code=").append(URLLicense.aquireLicense(image.imageUrl)); @@ -493,7 +493,7 @@ public class yacysearchitem { String thumbURL = thumbURLBuilder.toString(); prop.putHTML("content_item_hrefCache", thumbURL); /* Full size preview URL */ - if(authenticated) { + if(fullViewingRights) { prop.putHTML("content_item_hrefFullPreview", "ViewImage." + viewImageExt + "?isStatic=true&url=" + imageUrlstring); } else { /* Not authenticated : full preview URL must be the same as thumb URL */ diff --git a/source/net/yacy/visualization/ImageViewer.java b/source/net/yacy/visualization/ImageViewer.java index d04cad4f4..f701e72dd 100644 --- a/source/net/yacy/visualization/ImageViewer.java +++ b/source/net/yacy/visualization/ImageViewer.java @@ -41,6 +41,8 @@ import net.yacy.cora.document.id.DigestURL; import net.yacy.cora.document.id.MultiProtocolURL; import net.yacy.cora.federate.yacy.CacheStrategy; import net.yacy.cora.protocol.ClientIdentification; +import net.yacy.cora.protocol.Domains; +import net.yacy.cora.protocol.RequestHeader; import net.yacy.cora.util.ConcurrentLog; import net.yacy.data.InvalidURLLicenceException; import net.yacy.data.URLLicense; @@ -48,6 +50,7 @@ import net.yacy.http.servlets.TemplateMissingParameterException; import net.yacy.peers.graphics.EncodedImage; import net.yacy.repository.Blacklist.BlacklistType; import net.yacy.repository.LoaderDispatcher; +import net.yacy.search.Switchboard; import net.yacy.server.serverObjects; /** @@ -132,6 +135,17 @@ public class ImageViewer { } return inStream; } + + /** + * Check the request header to decide whether full image viewing is allowed for a given request. + * @param header request header. When null, false is returned. + * @param sb switchboard instance. + * @return true when full image view is allowed for this request + */ + public static boolean hasFullViewingRights(final RequestHeader header, Switchboard sb) { + return header != null && (Domains.isLocalhost(header.getRemoteAddr()) + || (sb != null && sb.verifyAuthentication(header))); + } /** * @param formatName