added security layer for ViewImage:

- images may be requested by localhost and authorized users only, if the request is done using a clear-text URL
- the image may be requested also using a code that can be a license to retrieve a URL for everyone
- some servelets produce URL licenses for ViewImage, like image search results


git-svn-id: https://svn.berlios.de/svnroot/repos/yacy/trunk@4027 6c8d7289-2bf4-0310-a012-ef5d649a1542
pull/1/head
orbiter 18 years ago
parent 9a860cf397
commit 62347b50f4

@ -61,13 +61,29 @@ public class ViewImage {
plasmaSwitchboard sb = (plasmaSwitchboard)env;
String urls = post.get("url", "");
URL url;
try {
url = new URL(urls);
// the url to the image can be either submitted with an url in clear text, or using a license key
// if the url is given as clear text, the user must be authorized as admin
// the license can be used also from non-authorized users
String urlString = post.get("url", "");
String urlLicense = post.get("code", "");
boolean auth = ((String) header.get("CLIENTIP", "")).equals("localhost") || sb.verifyAuthentication(header, true); // handle access rights
URL url = null;
if ((urlString.length() > 0) && (auth)) try {
url = new URL(urlString);
} catch (MalformedURLException e1) {
return null;
url = null;
}
if ((url == null) && (urlLicense.length() > 0)) {
url = sb.licensedURLs.releaseLicense(urlLicense);
urlString = url.toNormalform(true, true);
}
if (url == null) return null;
System.out.println("loading image from " + url.toString());
int width = post.getInt("width", 0);
int height = post.getInt("height", 0);
int maxwidth = post.getInt("maxwidth", 0);
@ -78,7 +94,7 @@ public class ViewImage {
Object[] resource = sb.snippetCache.getResource(url, true, timeout, false);
byte[] imgb = null;
if (resource == null) {
if (urls.endsWith(".ico")) {
if (urlString.endsWith(".ico")) {
// load default favicon dfltfvcn.ico
try {
imgb = serverFileUtils.read(new File(sb.getRootPath(), "htroot/env/grafics/dfltfvcn.ico"));
@ -103,9 +119,8 @@ public class ViewImage {
}
// read image
Image image = ymageImageParser.parse(urls.toString(), imgb);
Image image = ymageImageParser.parse(urlString.toString(), imgb);
boolean auth = ((String) header.get("CLIENTIP", "")).equals("localhost") || sb.verifyAuthentication(header, false); // handle access rights
if ((auth) && ((width == 0) || (height == 0)) && (maxwidth == 0) && (maxheight == 0)) return image;
// find original size

@ -231,12 +231,12 @@ function handleImageState(req, progressbar) {
for (i = 0; i < links; i++) {
var type = response.getElementsByTagName("type")[i].firstChild.data;
var href = response.getElementsByTagName("href")[i].firstChild.data;
var code = response.getElementsByTagName("code")[i].firstChild.data;
var name = response.getElementsByTagName("name")[i].firstChild.data;
var attr = response.getElementsByTagName("attr")[i].firstChild.data;
// <a href="#[url]#"><img src="/ViewImage.png?maxwidth=96&amp;maxheight=96&amp;url=#[url]#" /></a><br /><a href="#[url]#">#[name]#</a>
var img = document.createElement("img");
img.setAttribute("src", "/ViewImage.png?maxwidth=96&maxheight=96&url=" + href);
var img = document.createElement("img");
img.setAttribute("src", "/ViewImage.png?maxwidth=96&maxheight=96&code=" + code);
img.setAttribute("alt", name);
var imganchor = document.createElement("a");

@ -77,8 +77,14 @@ public class snippet {
plasmaSnippetCache.MediaSnippet ms;
for (int i = 0; i < mediaSnippets.size(); i++) {
ms = (plasmaSnippetCache.MediaSnippet) mediaSnippets.get(i);
try {
url = new URL(ms.href);
} catch (MalformedURLException e) {
continue;
}
prop.put("link_" + i + "_type", ms.type);
prop.put("link_" + i + "_href", ms.href);
prop.put("link_" + i + "_code", switchboard.licensedURLs.aquireLicense(url));
prop.put("link_" + i + "_name", ms.name);
prop.put("link_" + i + "_attr", ms.attr);
}

@ -8,7 +8,8 @@
#{link}#
<link>
<type>#[type]#</type>
<href>#[href]#</href>
<href>#[href]#</href>
<code>#[code]#</code>
<name>#[name]#</name>
<attr>#[attr]#</attr>
</link>

@ -150,7 +150,7 @@ document.getElementById("Enter").value = "search again - catch up more links";
#(/recommend)#
</div>
#(/authorized)#
<h4 class="linktitle"><img src="ViewImage.png?width=16&height=16&url=#[favicon]#" id="f#[urlhash]#" class="favicon" width="16" height="16" /><a href="#[url]#" target="_parent">#[description]#</a></h4>
<h4 class="linktitle"><img src="ViewImage.png?width=16&height=16&code=#[faviconCode]#" id="f#[urlhash]#" class="favicon" width="16" height="16" /><a href="#[url]#" target="_parent">#[description]#</a></h4>
<p class="snippet iconindented"><span class="#(snippet)#snippetLoading::snippetLoaded#(/snippet)#" id="h#[urlhash]#">#(snippet)#loading snippet ...::#[text]##(/snippet)#</span></p>
<p class="url iconindented"><a href="#[url]#" id="url#[urlhash]#" target="_parent">#[urlname]#</a></p>
<p class="urlinfo iconindented">#[date]# | YBR-#[ybr]# | <a href="ViewFile.html?urlHash=#[urlhash]#&amp;words=#[words]#">Info</a> | <a href="yacysearch.html?cat=image&amp;url=#[url]#&amp;search=#[former]#">Pictures</a></p>

@ -323,8 +323,10 @@ public class yacysearch {
try{
URL url=new URL(result.getUrl());
int port=url.getPort();
//TODO: parse <link rel="favicon" /> ...
prop.put("type_results_" + i + "_favicon", url.getProtocol() + "://" + url.getHost() + ((port != -1) ? (":" + String.valueOf(port)) : "") + "/favicon.ico");
URL faviconURL = new URL(url.getProtocol() + "://" + url.getHost() + ((port != -1) ? (":" + String.valueOf(port)) : "") + "/favicon.ico");
// TODO: parse <link rel="favicon" /> ...
// aquire license for favicon url loading
prop.put("type_results_" + i + "_faviconCode", sb.licensedURLs.aquireLicense(faviconURL));
}catch(MalformedURLException e){}
prop.put("type_results_" + i + "_urlhash", result.getUrlhash());
prop.put("type_results_" + i + "_urlhexhash", yacySeed.b64Hash2hexHash(result.getUrlhash()));

@ -0,0 +1,75 @@
// URLLicense.java
// (C) 2007 by Michael Peter Christen; mc@yacy.net, Frankfurt a. M., Germany
// first published 03.07.2007 on http://yacy.net
//
// This is a part of YaCy, a peer-to-peer based web search engine
//
// $LastChangedDate: 2006-04-02 22:40:07 +0200 (So, 02 Apr 2006) $
// $LastChangedRevision: 1986 $
// $LastChangedBy: orbiter $
//
// LICENSE
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
package de.anomic.data;
import java.util.HashMap;
import java.util.Random;
import de.anomic.net.URL;
public class URLLicense {
// this class defines a license-generation for URLs
// it is used in case of snippet- and preview-Image-fetching to grant also non-authorized users the usage of a image-fetcher servlet
private Random random;
private HashMap permissions;
private int keylen;
public URLLicense(int keylen) {
this.permissions = new HashMap();
this.random = new Random(System.currentTimeMillis());
this.keylen = keylen;
}
public String aquireLicense(URL url) {
// generate license key
String license = "";
while (license.length() < keylen) license += Integer.toHexString(random.nextInt());
license = license.substring(0, keylen);
// store reference to url with license key
synchronized (permissions) {
permissions.put(license, url);
}
// return the license key
return license;
}
public URL releaseLicense(String license) {
URL url = null;
synchronized (permissions) {
url = (URL) permissions.remove(license);
}
if (url == null) {
System.out.println("DEBUG-URLLICENSE: no URL license present for code=" + license);
} else {
System.out.println("DEBUG-URLLICENSE: granted download of " + url.toString());
}
return url;
}
}

@ -124,6 +124,7 @@ import java.util.Set;
import java.util.TreeMap;
import java.util.TreeSet;
import de.anomic.data.URLLicense;
import de.anomic.data.blogBoard;
import de.anomic.data.blogBoardComments;
import de.anomic.data.bookmarksDB;
@ -258,6 +259,8 @@ public final class plasmaSwitchboard extends serverAbstractSwitch implements ser
public double totalQPM = 0d;
public TreeMap clusterhashes; // map of peerhash(String)/alternative-local-address as ip:port or only ip (String) or null if address in seed should be used
public boolean acceptLocalURLs, acceptGlobalURLs;
public URLLicense licensedURLs;
/*
* Remote Proxy configuration
*/
@ -948,6 +951,9 @@ public final class plasmaSwitchboard extends serverAbstractSwitch implements ser
i++;
}
// initiate url license object
licensedURLs = new URLLicense(8);
// set URL domain acceptance
this.acceptGlobalURLs = "global.any".indexOf(getConfig("network.unit.domain", "global")) >= 0;
this.acceptLocalURLs = "local.any".indexOf(getConfig("network.unit.domain", "global")) >= 0;

Loading…
Cancel
Save