2005-11-11 09:02:46 +01:00
// transfer.java
// -----------------------
// part of YaCy caching proxy
// (C) by Michael Peter Christen; mc@anomic.de
// first published on http://www.anomic.de
// Frankfurt, Germany, 2004
// created 07.11.2005
//
2006-01-18 01:03:28 +01:00
// $LastChangedDate$
// $LastChangedRevision$
// $LastChangedBy$
2005-11-11 09:02:46 +01:00
//
// 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
//
// Using this software in any meaning (reading, learning, copying, compiling,
// running) means that you agree that the Author(s) is (are) not responsible
// for cost, loss of data or any harm that may be caused directly or indirectly
// by usage of this softare or this documentation. The usage of this software
// is on your own risk. The installation and usage (starting/running) of this
// software may allow other people or application to access your computer and
// any attached devices and is highly dependent on the configuration of the
// software which must be done by the user of the software; the author(s) is
// (are) also not responsible for proper configuration and usage of the
// software, even if provoked by documentation provided together with
// the software.
//
// Any changes to this file according to the GPL as documented in the file
// gpl.txt aside this file in the shipment you received can be done to the
// lines that follows this copyright notice here, but changes must not be
// done inside the copyright notive above. A re-distribution must contain
// the intact and unchanged copyright notice.
// Contributions and changes to the program code must be marked as such.
import java.io.File ;
import java.io.IOException ;
import de.anomic.http.httpHeader ;
2006-01-04 01:39:00 +01:00
import de.anomic.kelondro.kelondroBase64Order ;
2005-11-11 09:02:46 +01:00
import de.anomic.plasma.plasmaRankingDistribution ;
2006-09-30 00:27:20 +02:00
import de.anomic.plasma.plasmaSwitchboard ;
import de.anomic.server.serverCodings ;
2005-11-11 09:02:46 +01:00
import de.anomic.server.serverFileUtils ;
import de.anomic.server.serverObjects ;
import de.anomic.server.serverSwitch ;
import de.anomic.yacy.yacyCore ;
import de.anomic.yacy.yacySeed ;
public final class transfer {
public static serverObjects respond ( httpHeader header , serverObjects post , serverSwitch env ) {
if ( post = = null | | env = = null ) return null ;
plasmaSwitchboard sb = ( plasmaSwitchboard ) env ;
serverObjects prop = new serverObjects ( ) ;
2005-12-07 00:51:29 +01:00
String process = post . get ( " process " , " " ) ; // permission or store
//String key = post.get("key", ""); // a transmission key from the client
String otherpeer = post . get ( " iam " , " " ) ; // identification of the client (a peer-hash)
String purpose = post . get ( " purpose " , " " ) ; // declares how the file shall be treated
String filename = post . get ( " filename " , " " ) ; // a name of a file without path
2005-12-05 10:13:13 +01:00
//long filesize = Long.parseLong((String) post.get("filesize", "")); // the size of the file
2006-01-18 03:18:23 +01:00
2006-01-17 23:19:18 +01:00
prop . put ( " process " , 0 ) ;
2007-01-16 15:07:54 +01:00
prop . putASIS ( " response " , " denied " ) ; // reject is default and is overwritten if ok
prop . putASIS ( " process_access " , " " ) ;
prop . putASIS ( " process_address " , " " ) ;
prop . putASIS ( " process_protocol " , " " ) ;
prop . putASIS ( " process_path " , " " ) ;
prop . putASIS ( " process_maxsize " , " 0 " ) ;
2006-01-18 03:18:23 +01:00
if ( ! sb . rankingOn ) { return prop ; }
2005-11-11 09:02:46 +01:00
yacySeed otherseed = yacyCore . seedDB . get ( otherpeer ) ;
2006-01-17 22:50:40 +01:00
if ( ( otherseed = = null ) | | ( filename . indexOf ( " .. " ) > = 0 ) ) {
2006-01-17 23:19:18 +01:00
// reject unknown peers: this does not appear fair, but anonymous senders are dangerous
// reject paths that contain '..' because they are dangerous
if ( otherseed = = null ) sb . getLog ( ) . logFine ( " RankingTransmission: rejected unknown peer ' " + otherpeer + " ', current IP " + header . get ( " CLIENTIP " , " unknown " ) ) ;
if ( filename . indexOf ( " .. " ) > = 0 ) sb . getLog ( ) . logFine ( " RankingTransmission: rejected wrong path ' " + filename + " ' from peer " + otherseed . getName ( ) + " / " + otherseed . getAddress ( ) + " , current IP " + header . get ( " CLIENTIP " , " unknown " ) ) ;
2005-11-11 09:02:46 +01:00
return prop ;
}
String otherpeerName = otherseed . hash + " : " + otherseed . getName ( ) ;
if ( process . equals ( " permission " ) ) {
prop . put ( " process " , 0 ) ;
2006-03-13 21:12:31 +01:00
if ( ( ( purpose . equals ( " crcon " ) ) & & ( filename . startsWith ( " CRG " ) ) & & ( filename . endsWith ( " .cr.gz " ) ) ) | | ( ( filename . startsWith ( " domlist " ) ) & & ( filename . endsWith ( " .txt.gz " ) | | filename . endsWith ( " .zip " ) ) ) ) {
2005-11-11 09:02:46 +01:00
// consolidation of cr files
//System.out.println("yacy/transfer:post=" + post.toString());
2005-12-05 10:13:13 +01:00
//String cansendprotocol = (String) post.get("can-send-protocol", "http");
2006-01-04 01:39:00 +01:00
String access = kelondroBase64Order . enhancedCoder . encode ( serverCodings . encodeMD5Raw ( otherpeer + " : " + filename ) ) + " : " + kelondroBase64Order . enhancedCoder . encode ( serverCodings . encodeMD5Raw ( " " + System . currentTimeMillis ( ) ) ) ;
2007-01-16 15:07:54 +01:00
prop . putASIS ( " response " , " ok " ) ;
prop . putASIS ( " process_access " , access ) ;
prop . putASIS ( " process_address " , yacyCore . seedDB . mySeed . getAddress ( ) ) ;
prop . putASIS ( " process_protocol " , " http " ) ;
prop . putASIS ( " process_path " , " " ) ; // currently empty; the store process will find a path
prop . putASIS ( " process_maxsize " , " -1 " ) ; // if response is too big we return the size of the file
2006-01-04 01:39:00 +01:00
sb . rankingPermissions . put ( serverCodings . encodeMD5Hex ( kelondroBase64Order . standardCoder . encodeString ( access ) ) , filename ) ;
2005-11-11 09:02:46 +01:00
sb . getLog ( ) . logFine ( " RankingTransmission: granted peer " + otherpeerName + " to send CR file " + filename ) ;
}
return prop ;
}
if ( process . equals ( " store " ) ) {
prop . put ( " process " , 1 ) ;
if ( purpose . equals ( " crcon " ) ) {
byte [ ] filebytes = ( byte [ ] ) post . get ( " filename$file " ) ;
2005-12-07 00:51:29 +01:00
String accesscode = post . get ( " access " , " " ) ; // one-time authentication
String md5 = post . get ( " md5 " , " " ) ; // one-time authentication
2005-12-05 01:17:12 +01:00
//java.util.HashMap perm = sb.rankingPermissions;
2005-11-11 09:02:46 +01:00
//System.out.println("PERMISSIONDEBUG: accesscode=" + accesscode + ", permissions=" + perm.toString());
String grantedFile = ( String ) sb . rankingPermissions . get ( accesscode ) ;
2007-01-16 15:07:54 +01:00
prop . putASIS ( " process_tt " , " " ) ;
2005-11-11 09:02:46 +01:00
if ( ( grantedFile = = null ) | | ( ! ( grantedFile . equals ( filename ) ) ) ) {
// fraud-access of this interface
2007-01-16 15:07:54 +01:00
prop . putASIS ( " response " , " denied " ) ;
2005-11-11 09:02:46 +01:00
sb . getLog ( ) . logFine ( " RankingTransmission: denied " + otherpeerName + " to send CR file " + filename + " : wrong access code " ) ;
} else {
sb . rankingPermissions . remove ( accesscode ) ; // not needed any more
File path = new File ( sb . rankingPath , plasmaRankingDistribution . CR_OTHER ) ;
path . mkdirs ( ) ;
File file = new File ( path , filename ) ;
try {
2006-01-17 20:01:20 +01:00
if ( file . getCanonicalPath ( ) . toString ( ) . startsWith ( path . getCanonicalPath ( ) . toString ( ) ) ) {
serverFileUtils . write ( filebytes , file ) ;
String md5t = serverCodings . encodeMD5Hex ( file ) ;
if ( md5t . equals ( md5 ) ) {
2007-01-16 15:07:54 +01:00
prop . putASIS ( " response " , " ok " ) ;
2006-01-17 20:01:20 +01:00
sb . getLog ( ) . logFine ( " RankingTransmission: received from peer " + otherpeerName + " CR file " + filename ) ;
} else {
2007-01-16 15:07:54 +01:00
prop . putASIS ( " response " , " transfer failure " ) ;
2006-01-17 23:19:18 +01:00
sb . getLog ( ) . logFine ( " RankingTransmission: transfer failure from peer " + otherpeerName + " for CR file " + filename ) ;
2006-01-17 20:01:20 +01:00
}
} else {
//exploit?
2007-01-16 15:07:54 +01:00
prop . putASIS ( " response " , " io error " ) ;
2006-01-17 20:01:20 +01:00
return prop ;
2005-11-11 09:02:46 +01:00
}
} catch ( IOException e ) {
2007-01-16 15:07:54 +01:00
prop . putASIS ( " response " , " io error " ) ;
2005-11-11 09:02:46 +01:00
}
}
}
return prop ;
}
2006-01-18 03:18:23 +01:00
2005-11-11 09:02:46 +01:00
// wrong access
sb . getLog ( ) . logFine ( " RankingTransmission: rejected unknown process " + process + " : " + purpose + " from peer " + otherpeerName ) ;
return prop ;
}
}