package crushftp.server;
import java.io.*;
import java.net.*;
import java.util.*;
import java.text.SimpleDateFormat;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import crushftp.handlers.*;
import org.jdom.*;
import org.jdom.input.*;
import org.jdom.output.*;
import crushftp.gui.LOC;
public class ServerSessionHTTP implements Runnable
{
static RandomAccessFile log = null;
static Properties proppatches = null;
static Properties locktokens = null;
static Properties publicpasswords = null;
public int bufferSize = 32768;
byte headerBytes[] = new byte[bufferSize];
public ServerSession thisSession = null;
public Thread this_thread = null;
public Socket sock = null;
public OutputStream original_os = null;
public BufferedInputStream original_is = null;
public boolean keepGoing = true;
SimpleDateFormat lastModifiedSDF = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss z",Locale.US);
int timeoutSeconds = 300;
boolean done = false;
boolean kill_all = false;
RETR_handler retr = new RETR_handler();
STOR_handler stor = new STOR_handler();
Thread stor_Thread = null;
String cacheHeader = "";
Properties globalSessions = null;
boolean writeCookieAuth = false;
SAXBuilder sax = new SAXBuilder();
XMLOutputter xmlOut = null;
SimpleDateFormat sdf_rfc1123 = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss z",Locale.US);
SimpleDateFormat sdf_rfc1123_2 = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'",Locale.US);
String hostString = "";
String domain = "";
Properties server_item;
String proxy = "";
long mimesModified = 0;
Properties mimes = new Properties();
String server_header = "AppleDotMacServer-1B5411";
String CRLF = "\r\n";
Common common_code = null;
ServerStatus server_status_frame = null;
boolean sniffer = false;
ServerSessionNotMacXML ssnmx = new ServerSessionNotMacXML();
String userAgent = "";
Properties dns = new Properties();
public ServerSessionHTTP(Socket sock, ServerStatus server_status_frame, int user_number, String user_ip, int listen_port, String listen_ip, String listen_ip_port, Properties server_item, Properties linked_server)
{
dns.put("WWW.MAC.COM","17.250.248.32");
dns.put("HOMEPAGE.MAC.COM","17.250.248.34");
dns.put("IDISK.MAC.COM","17.250.248.77");
dns.put("CONFIGURATION.APPLE.COM","17.250.248.105");
dns.put("SYNCMGMT.MAC.COM","17.250.248.103");
this.server_status_frame = server_status_frame;
//server_header = "CrushFTP " + server_status_frame.siSG("version_info_str");
this.sock = sock;
this.server_item = server_item;
if (System.getProperties().get("httpSessions") == null) System.getProperties().put("httpSessions", new Properties());
globalSessions = (Properties)System.getProperties().get("httpSessions");
thisSession = new ServerSession(sock, server_status_frame, user_number, user_ip, listen_port, listen_ip, listen_ip_port, server_item, linked_server);
common_code = thisSession.common_code;
thisSession.give_thread_pointer(Thread.currentThread());
thisSession.uiPUT("dont_read","true");
thisSession.uiPUT("dont_write","true");
proxy = thisSession.server_item.getProperty("httpReverseProxy","");
if (!proxy.startsWith("/"))proxy="/"+proxy;if (proxy.endsWith("/"))proxy=proxy.substring(0,proxy.length()-1);
}
public void run()
{
try
{
if (log == null)
{
if (new File("./").getCanonicalPath().toUpperCase().indexOf("NOTMAC") >= 0 || System.getProperty("crushftp.home").toUpperCase().indexOf("NOTMAC") >= 0)
{
try{log = new RandomAccessFile("/Library/Application Support/NotMac/NotMac_"+new Date().getTime()+".log","rw");}catch(Exception e){e.printStackTrace();};
}
}
thisSession.add_log("["+server_item.getProperty("serverType","ftp")+":"+server_item.getProperty("port","21")+"][" + thisSession.uiSG("user_number") + "] "+SG("Accepting connection from")+": " + thisSession.uiSG("user_ip") + ":" + sock.getPort() + CRLF, "ACCEPT");
thisSession.uiPUT("login_date",new Date().toString());
server_status_frame.hold_user_pointer(thisSession.user_info);
thisSession.thread_killer_item = new IdlerKiller(thisSession, new Date().getTime(),2, Thread.currentThread());
original_os = sock.getOutputStream();
original_is = new BufferedInputStream(sock.getInputStream());
while(sock != null && sock.isConnected() && !done)
{
Thread.sleep(thisSession.delayInterval);
keepGoing = true;
if (thisSession.uiBG("refresh_user"))
{
thisSession.uiPUT("refresh_user","false");
thisSession.uVFS = null;
if (!thisSession.verify_user(thisSession.uiSG("user_name"),thisSession.uiSG("current_password"))) break;
}
handle_http_requests();
}
// if (kill_all) server_status_frame.kill_same_name_same_ip(thisSession.user_info);
if (sock != null) sock.close();
}
catch(Exception e)
{
Common.debug(1,e);
thisSession.uiPUT("dieing","true");
}
if (!thisSession.uiBG("didDisconnect"))
{
thisSession.uiPUT("didDisconnect","true");
thisSession.do_event("Disconnected.", "QUIT","");
}
thisSession.add_log("[" + thisSession.uiSG("user_number") + ":" + thisSession.uiSG("user_name") + ":" + thisSession.uiSG("user_ip") + "] *"+SG("Disconnected")+".*", "QUIT");
thisSession.uiPUT("dieing","true");
do_kill();
}
public void give_thread_pointer(Thread this_thread)
{
this.this_thread = this_thread;
thisSession.this_thread = this_thread;
}
public void do_kill()
{
stor.die_now = true;
if (stor_Thread != null) stor_Thread.interrupt();
addSessionCommand("QUIT","");
thisSession.do_kill();
}
public void doSniffer(Vector headers)
{
int port = 443;
String headersStr = "";
for (int x=0; x<headers.size(); x++)
{
String data = headers.elementAt(x).toString();
if (data.toUpperCase().startsWith("HOST: "))
{
hostString = data.substring(data.toUpperCase().indexOf(" ")+1).trim();
thisSession.uiPUT("listen_ip",hostString);//first format "127.0.0.1", second format is "127.0.0.1:80"
if (data.indexOf(":",data.indexOf(" ")) >= 0) thisSession.uiPUT("listen_ip",data.substring(data.indexOf(" ")+1,data.indexOf(":",data.indexOf(" "))).trim());
domain = hostString;
if (domain.indexOf(":") >= 0) domain = domain.substring(0,domain.indexOf(":"));
if (data.toUpperCase().startsWith("X-FORWARDED-HOST: ") && thisSession.uiSG("user_ip").equals("127.0.0.1")) thisSession.uiPUT("user_ip",domain);
port = sock.getLocalPort();
}
if (!data.startsWith("Accept-Encoding") && !data.startsWith("X-"))
{
if (data.startsWith("Connection")) headersStr += "Connection: close\r\n";
else headersStr += data + "\r\n";
}
}
thisSession.server_status_frame.append_log("**************************************************************\r\n"+headersStr,"ACCEPT",thisSession);
try
{
if (log != null) log.write(headersStr.getBytes());
TrustManager[] trustAllCerts = new TrustManager[]{ new X509TrustManager() {
public java.security.cert.X509Certificate[] getAcceptedIssuers() {return null;}
public void checkClientTrusted(java.security.cert.X509Certificate[] certs, String authType) {}
public void checkServerTrusted(java.security.cert.X509Certificate[] certs, String authType) {}
}};
Socket sockOut = new Socket(dns.getProperty(domain.toUpperCase()), port);
if (port == 443)
{
SSLContext sc = SSLContext.getInstance("SSL");
sc.init(null, trustAllCerts, new java.security.SecureRandom());
HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
sockOut = (SSLSocket)sc.getSocketFactory().createSocket(sockOut,domain,port,true);
((SSLSocket)sockOut).setUseClientMode(true);
((SSLSocket)sockOut).startHandshake();
}
class passthrough implements Runnable
{
InputStream in;
OutputStream out;
String id;
public passthrough(String id, InputStream in, OutputStream out)
{
this.in= in;
this.out = out;
this.id = id;
}
public void run()
{
byte b[] = new byte[32768];
int bytes = 0;
try
{
while(bytes >= 0)
{
bytes = in.read(b);
if (bytes > 0)
{
out.write(b,0,bytes);
if (log != null) log.write(b,0,bytes);
thisSession.server_status_frame.append_log("*****************************"+id+"*********************************\r\n"+new String(b,0,bytes),"ACCEPT",thisSession);
out.flush();
}
}
}
catch(Exception e)
{
e.printStackTrace();
}
try {in.close();}catch(Exception e) {}
try {out.close();}catch(Exception e) {}
}
}
sockOut.getOutputStream().write(headersStr.getBytes());
sockOut.getOutputStream().write("\r\n".getBytes());
sockOut.getOutputStream().flush();
new Thread(new passthrough("WROTE",sock.getInputStream(),sockOut.getOutputStream())).start();
Thread t = new Thread(new passthrough("READ",sockOut.getInputStream(),sock.getOutputStream()));
t.start();
t.join();
}
catch(Exception e)
{
e.printStackTrace();
}
done = true;
}
public void handle_http_requests() throws Exception
{
if (proppatches == null && new File(System.getProperty("crushftp.backup")+"backup/proppatches.prop").exists())
{
ObjectInputStream ois = new ObjectInputStream(new FileInputStream(System.getProperty("crushftp.backup")+"backup/proppatches.prop"));
proppatches = (Properties)ois.readObject();
ois.close();
}
if (proppatches == null){proppatches = new Properties();}
if (locktokens == null && new File(System.getProperty("crushftp.backup")+"backup/locktokens.prop").exists())
{
ObjectInputStream ois = new ObjectInputStream(new FileInputStream(System.getProperty("crushftp.backup")+"backup/locktokens.prop"));
locktokens = (Properties)ois.readObject();
ois.close();
}
if (locktokens == null){locktokens = new Properties();}
if (publicpasswords == null && new File(System.getProperty("crushftp.backup")+"backup/publicpasswords.prop").exists())
{
ObjectInputStream ois = new ObjectInputStream(new FileInputStream(System.getProperty("crushftp.backup")+"backup/publicpasswords.prop"));
publicpasswords = (Properties)ois.readObject();
ois.close();
}
if (publicpasswords == null){publicpasswords = new Properties();}
String data = "";
Vector headers = getHeaders();
try
{
if (headers.size() > 0)
{
data = headers.elementAt(0).toString();
data = Common.url_decode(data);
data = Common.replace_str(data,"..","");
data = Common.replace_str(data,"\\","/");
data = Common.replace_str(data,"//","/");
boolean ok = false;
if (data.toUpperCase().startsWith("GET /WEBINTERFACE/")
|| data.toUpperCase().startsWith("GET /FAVICON.ICO")
|| data.toUpperCase().startsWith("GET /CRUSHFTP.JAR")
|| data.toUpperCase().startsWith("HEAD /CRUSHFTP.JAR")) ok = true;
if (data.toUpperCase().startsWith("GET /WEBINTERFACE/CRUSHFTP.JNLP")) ok = false;
if (data.toUpperCase().startsWith("GET /WEBINTERFACE/LOGIN.HTML?")) ok = false;
if (data.toUpperCase().indexOf("/CRUSHIMAGEPREVIEW") >= 0) ok = false;
if (ok)
{
ServerSessionHTTPWI sswi = new ServerSessionHTTPWI(this,headers,original_os);
sswi.serveFile();
return;
}
processMiniURLs(data,headers);
}
}
catch (Exception e)
{
Common.debug(1,e);
}
if (done) return;
String user_dir = "/";
boolean ignoreAuth = false;
boolean forceFileName = false;
long http_len_max = 0;
cacheHeader = "";
thisSession.uiPUT("start_resume_loc","0");
thisSession.uiPUT("byteRanges",new Vector());
if (thisSession.server_item.getProperty("https_redirect","false").equalsIgnoreCase("true") && thisSession.server_item.getProperty("serverType","FTP").toUpperCase().equals("HTTP"))
{
String path = headers.elementAt(0).toString();
int endPos = path.lastIndexOf(" HTTP");
if (endPos < 0) endPos = path.length()-1;
path = path.substring(path.indexOf(" ")+1, endPos);
sendHttpsRedirect(path,headers);
write_command_http("Connection: close");
write_command_http("");
kill_all = true;
done = true;
return;
}
for (int x=0; x<headers.size(); x++) //first loop through and see if they have a cookie for auth
{
data = headers.elementAt(x).toString();
if (data.toUpperCase().startsWith("HOST: ") || data.toUpperCase().startsWith("X-FORWARDED-HOST: "))
{
hostString = data.substring(data.toUpperCase().indexOf(" ")+1).trim();
thisSession.uiPUT("listen_ip",hostString);//first format "127.0.0.1", second format is "127.0.0.1:80"
if (data.indexOf(":",data.indexOf(" ")) >= 0) thisSession.uiPUT("listen_ip",data.substring(data.indexOf(" ")+1,data.indexOf(":",data.indexOf(" "))).trim());
domain = hostString;
if (domain.indexOf(":") >= 0) domain = domain.substring(0,domain.indexOf(":"));
if (data.toUpperCase().startsWith("X-FORWARDED-HOST: ") && thisSession.uiSG("user_ip").equals("127.0.0.1")) thisSession.uiPUT("user_ip",domain);
}
if (data.startsWith("User-Agent: "))
{
userAgent = data.substring("User-Agent: ".length()).trim();
}
else if (data.startsWith("X-Forwarded-For: "))
{
thisSession.uiPUT("user_ip",data.substring(data.indexOf(":")+1).trim());
}
}
if ((hostString.equals("www.mac.com") && sock.getLocalPort() == 80) || (hostString.equals("homepage.mac.com") && sock.getLocalPort() == 80))// || crushftp.gui.MainFrame.scroll_activity_cb.isSelected())
{
//http://homepage.mac.com/username/
//is this user a valid notMac user? If not, then forward them. If so, then serve the pages.
boolean ok = true;
String data0 = headers.elementAt(0).toString();
data0 = data0.substring(data0.indexOf(" ")+2);
if (data0.indexOf("/") >= 0)
{
data0 = data0.substring(0,data0.indexOf("/"));
if (!data0.equals("") && new File("/Library/Application Support/NotMac/Storage/"+data0+"/").exists()) ok = false;
}
if (ok)
{
data = headers.elementAt(0).toString();
data = data.substring(data.indexOf(" ")+1, data.lastIndexOf(" "));
//write_command_http("HTTP/1.0 302 Redirect");
//write_command_http("Pragma: no-cache");
//get host string to put in location.
String baseURL = getBaseUrl(headers);
baseURL = Common.replace_str(baseURL,domain,dns.getProperty(domain.toUpperCase(),domain));
//write_command_http("location: "+baseURL+data);
//write_command_http("");
doSniffer(headers);
return;
}
}
for (int x=0; x<headers.size(); x++) //first loop through and see if they have a cookie for auth
{
data = headers.elementAt(x).toString();
if (data.startsWith("Cookie: "))
{
if (data.indexOf("CrushAuth=") >= 0)
{
String authorization = data.substring(data.indexOf("CrushAuth=")+"CrushAuth=".length());
if (authorization.indexOf("; ") >= 0) authorization = authorization.substring(0,authorization.indexOf("; "));
if (authorization.equals("login"))
{
DEAUTH();
kill_all = true;
done = true;
return;
}
else if (authorization.startsWith("logout"))
{
String sessionid = authorization.substring("logout".length());
globalSessions.remove(thisSession.uiSG("user_ip")+"_"+sessionid+"_user");
globalSessions.remove(thisSession.uiSG("user_ip")+"_"+sessionid+"_pass");
sendRedirect("/",headers);
write_command_http("Connection: close");
write_command_http("Set-Cookie: CrushAuth=; path=/");
thisSession.uiPUT("CrushAuth","");//needed to allow XML to work with Safari since it can't access cookies (CrushUpplet)
write_command_http("");
kill_all = true;
done = true;
thisSession.uVFS = null;
return;
}
else if (authorization.equals("credentials"))
{
done = true;
//let the auth headers below take care of this and set the sessionid in the cookie
//or the POST LOGIN method below
}
else
{
//lookup in "globalSessions" using their IP and this sessionID
//if we find it, get the user/pass out of it, and use it to re-auth them.
try
{
String user = globalSessions.getProperty(thisSession.uiSG("user_ip")+"_"+authorization+"_user");
String pass = globalSessions.getProperty(thisSession.uiSG("user_ip")+"_"+authorization+"_pass");
thisSession.uiPUT("sessionID",authorization);
if (user != null)
{
thisSession.uiPUT("user_name",user);
thisSession.uiPUT("current_password",pass);
thisSession.uiPUT("login_date_stamp",authorization);
if (!thisSession.uiBG("user_logged_in") || thisSession.user.size() < 10)
{
thisSession.uVFS = null;
thisSession.login_user_pass();
}
this_thread.setName(thisSession.uiSG("user_name") + ":(" + thisSession.uiSG("user_number") + ")-" + thisSession.uiSG("user_ip") + " (control)");
//this token is 30 min old, accept it, but send a new cookie back updating the token time.
if (new Date().getTime() - Long.parseLong(authorization) > 1000*60*30)
{
globalSessions.remove(thisSession.uiSG("user_ip")+"_"+authorization+"_user");
globalSessions.remove(thisSession.uiSG("user_ip")+"_"+authorization+"_pass");
writeCookieAuth = true;
continue;
}
thisSession.uiPUT("CrushAuth",authorization);//needed to allow XML to work with Safari since it can't access cookies (CrushUpplet)
}
}
catch(Exception e)
{
Common.debug(1,e);
}
writeCookieAuth = false;
ignoreAuth = true;
}
fixRootDir(null);
}
}
}
if (!ignoreAuth)
{
for (int x=0; x<headers.size(); x++)
{
data = headers.elementAt(x).toString();
if (data.startsWith("Authorization: ") && !thisSession.uiBG("user_logged_in"))
{
String authorization = data.substring("Authorization: Basic ".length());
thisSession.uiPUT("current_password",thisSession.decode(authorization));
thisSession.uiPUT("user_name",thisSession.uiSG("current_password").substring(0,thisSession.uiSG("current_password").indexOf(":")));
thisSession.uiPUT("current_password",thisSession.uiSG("current_password").substring(thisSession.uiSG("current_password").indexOf(":") + 1));
this_thread.setName(thisSession.uiSG("user_name") + ":(" + thisSession.uiSG("user_number") + ")-" + thisSession.uiSG("user_ip") + " (control)");
thisSession.uVFS = null;
boolean good = thisSession.login_user_pass();
if (good)
{
thisSession.do_event("Logged In.", "PASS","");
writeCookieAuth = true;
}
}
else if (data.startsWith("GET /WebInterface/login.html?username=") || data.startsWith("POST /WebInterface/login.html?username=") && !thisSession.uiBG("user_logged_in"))
{
String autoUser = data.substring(data.indexOf("username=")+"username=".length());
int endPos = data.lastIndexOf(" HTTP");
if (endPos < 0) endPos = data.length()-1;
String autoPass = data.substring(data.indexOf("password=")+"password=".length(), endPos)+"&";
thisSession.uiPUT("user_name",autoUser.substring(0,autoUser.indexOf("&")));
thisSession.uiPUT("current_password",autoPass.substring(0,autoPass.indexOf("&")));
this_thread.setName(thisSession.uiSG("user_name") + ":(" + thisSession.uiSG("user_number") + ")-" + thisSession.uiSG("user_ip") + " (control)");
thisSession.uVFS = null;
boolean good = thisSession.login_user_pass();
if (good)
{
String autoPath = "/";
if (data.indexOf("&path=") >= 0) autoPath = data.substring(data.indexOf("&path=")+"&path=".length(), endPos);
if (data.startsWith("GET ")) headers.setElementAt("GET "+autoPath+data.substring(endPos),x);
else if (data.startsWith("POST ")) headers.setElementAt("POST "+autoPath+data.substring(endPos),x);
forceFileName = true;
thisSession.do_event("Logged In.", "PASS","");
writeCookieAuth = true;
}
}
}
}
//NotMac public folders password protection
if(thisSession.uiSG("user_name").equalsIgnoreCase("public"))
{
data = headers.elementAt(0).toString();
String data2 = data.substring(data.indexOf(" "),data.lastIndexOf(" ")).trim();
String username = data2.substring(1,data2.indexOf("/",1));
if (publicpasswords.containsKey(("/"+username+"/Public/").toUpperCase()))
{
if (data2.toUpperCase().indexOf("/PUBLIC/") >= 0)
{
String pass = Common.makeBoundary();
try{pass = common_code.decode_pass(publicpasswords.getProperty(("/"+username+"/Public/").toUpperCase()));}catch(Exception e){}
if (!pass.equals(thisSession.uiSG("current_password"))) DEAUTH();
}
}
}
//done with auth loop, now for the rest of the headerss
for (int x=0; x<headers.size(); x++)
{
data = headers.elementAt(x).toString();
int endPos = data.lastIndexOf(" HTTP");
if (endPos < 0) endPos = data.length()-1;
if (data.startsWith("Connection: "))
{
if (data.toUpperCase().indexOf("CLOSE") >= 0) done = true;//close the socket after the next thing we do.
}
else if (data.toUpperCase().startsWith("GET ") || data.toUpperCase().startsWith("HEAD "))
{
//special case for URL based login credentials
if (data.toUpperCase().startsWith("GET /WEBINTERFACE/LOGIN.HTML?"))
{
data = data.substring(0,data.indexOf("?")) + data.substring(endPos);
headers.setElementAt(data,x);
}
user_dir = data.substring(data.indexOf(" ")+1, endPos);
if (user_dir.indexOf("\\") >= 0) user_dir = user_dir.replace('\\','/');
if (!user_dir.startsWith("/")) user_dir = "/"+user_dir;
}
else if (data.toUpperCase().startsWith("POST ")|| data.toUpperCase().startsWith("PROPFIND ") || data.toUpperCase().startsWith("ACL ") || data.toUpperCase().startsWith("COPY "))
{
user_dir = data.substring(data.indexOf(" ")+1, endPos);
if (user_dir.indexOf("\\") >= 0) user_dir = user_dir.replace('\\','/');
if (!user_dir.startsWith("/")) user_dir = "/"+user_dir;
if (!user_dir.endsWith("/")) user_dir += "/";
}
else if (data.toUpperCase().startsWith("OPTIONS "))
{
user_dir = data.substring(data.indexOf(" ")+1, endPos);
if (user_dir.indexOf("\\") >= 0) user_dir = user_dir.replace('\\','/');
if (!user_dir.startsWith("/")) user_dir = "/"+user_dir;
if (!user_dir.endsWith("/")) user_dir += "/";
write_command_http("HTTP/1.1 200 OK");
write_command_http("Pragma: no-cache");
write_command_http("x-responding-server: sslngn018");
write_command_http("X-dmUser: "+SG("username"));
write_command_http("MS-Author-Via: DAV");
write_command_http("Allow: GET, HEAD, OPTIONS, PUT, POST, COPY, PROPFIND, DELETE, LOCK, MKCOL, MOVE, PROPPATCH, UNLOCK, ACL, DMMKPATH, DMMKPATHS, TRACE, DMPATCHPATHS");
write_command_http("DAV: 1, 2, access-control, <http://apache.org/dav/propset/fs/1>");
write_command_http("Content-Type: text/plain");
write_command_http("Content-Length: 0");
write_command_http("Connection: close");
write_command_http("");
keepGoing = false;
}
else if (data.toUpperCase().startsWith("CONTENT-LENGTH: "))
{
try{http_len_max = Long.parseLong(data.substring(data.toUpperCase().indexOf("CONTENT-LENGTH:") + "CONTENT-LENGTH:".length()).trim());}catch(Exception e){}
}
}
thisSession.runPlugin("command",null);
//log the command for later tracking
try
{
String headersLine0 = headers.elementAt(0).toString();
Properties p = new Properties();p.put("the_command",headersLine0.substring(0,headersLine0.indexOf(" ")));p.put("the_command_data",headersLine0.substring(headersLine0.indexOf(" ")+1,headersLine0.lastIndexOf(" ")));p.put("user_time",server_status_frame.logDateFormat.format(new Date()));p.put("display",p.getProperty("user_time")+" | "+thisSession.uiSG("the_command") + " " + p.getProperty("the_command_data",""));
p.put("stamp",new Date().getTime()+"");
thisSession.uiVG("session_commands").addElement(p);
}
catch(Exception e)
{
Common.debug(1,e);
}
if (!keepGoing)
{
if (http_len_max > 0) get_raw_http_command((int)http_len_max);
done = true;
return;
}
if (thisSession.uiSG("user_name").equals(""))
{
thisSession.uiPUT("user_name","anonymous");
this_thread.setName(thisSession.uiSG("user_name") + ":(" + thisSession.uiSG("user_number") + ")-" + thisSession.uiSG("user_ip") + " (control)");
thisSession.uVFS = null;
thisSession.uiPUT("dont_log","true");
thisSession.login_user_pass();
if (thisSession.uiBG("user_logged_in")) writeCookieAuth = true;
thisSession.uiPUT("dont_log","false");
String attemptedPath = headers.elementAt(0).toString();
attemptedPath = attemptedPath.substring(attemptedPath.indexOf(" ")+1,attemptedPath.lastIndexOf(" "));
if (attemptedPath.toUpperCase().startsWith("/") && !attemptedPath.toUpperCase().startsWith(SG("root_dir").toUpperCase()) && thisSession.IG("max_logins") >= 0)
attemptedPath = SG("root_dir") + attemptedPath.substring(1);
try
{
String headersLine0 = headers.elementAt(0).toString();
if ((thisSession.uVFS == null || thisSession.IG("max_logins") < 0) && !headersLine0.startsWith("PROPFIND")) //no anonymous user...make a fake area for anonymous
{
thisSession.uVFS = new VFS();
if (thisSession.user != null) thisSession.user.put("root_dir","/");
thisSession.uiPUT("user_logged_in","true");
thisSession.uiPUT("user_name","");
if (!headersLine0.toUpperCase().startsWith("GET /WEBINTERFACE/") && headersLine0.toUpperCase().startsWith("GET / "))
{
if (userAgent.toUpperCase().indexOf("IPHOTO") >= 0 || userAgent.toUpperCase().indexOf("ISNETSERVICES") >= 0)
{
thisSession.uiPUT("user_logged_in","false");
}
else
{
sendRedirect("/WebInterface/login.html",headers);
write_command_http("Content-Length: 0");
write_command_http("");
return;
}
}
}
Properties testItem = thisSession.uVFS.get_item(attemptedPath);
if (testItem == null && !(headersLine0.toUpperCase().startsWith("GET /WEBINTERFACE/")))
{
if (headersLine0.startsWith("PROPFIND") || headersLine0.startsWith("DELETE") || headersLine0.startsWith("PUT"))
{
thisSession.uiPUT("user_logged_in","false");
}
else if (headersLine0.startsWith("GET ") && userAgent.toUpperCase().indexOf("IPHOTO") < 0)
{
//special case where we have to deauth if the client is a .Mac client instead of allowing them in as anonymous
if (userAgent.toUpperCase().indexOf("ISNETSERVICES") >= 0 || userAgent.toUpperCase().indexOf("DOTMAC") >= 0)
{
DEAUTH();
return;
}
//bad dir, DEAUTH
sendRedirect("/WebInterface/login.html",headers);
write_command_http("Set-Cookie: referer="+attemptedPath+"; path=/");
write_command_http("Content-Length: 0");
write_command_http("");
return;
}
}
if (headersLine0.startsWith("GET /../")) //WebStatistics user, force login prompt
{
thisSession.uiPUT("user_logged_in","false");
}
}
catch(Exception e)
{
Common.debug(2, e);
}
}
if ((!thisSession.uiBG("user_logged_in")))
{
if (http_len_max > 0) get_raw_http_command((int)http_len_max);
DEAUTH();
}
else //user is logged in
{
fixRootDir(domain);//lock them into a directory if we are using virtual domains
String action = "";
String http_boundary = "";
String ifnonematch = "0";
String move_destination = "";
String depth = "0";
boolean headersOnly = false;
VFS_URL otherFile = null;
if (!user_dir.toUpperCase().startsWith(thisSession.SG("root_dir").toUpperCase())) user_dir = thisSession.SG("root_dir") + (user_dir.startsWith("/")?user_dir.substring(1):user_dir);
thisSession.uiPUT("current_dir",user_dir);
for (int x=0; x<headers.size(); x++)
{
data = headers.elementAt(x).toString();
int endPos = data.lastIndexOf(" HTTP");
if (endPos < 0) endPos = data.length()-1;
thisSession.uiPUT("last_logged_command",(data+" ").substring(0,(data+" ").indexOf(" ")));
if (data.toUpperCase().startsWith("GET ") || data.toUpperCase().startsWith("HEAD "))
{
headersOnly = data.toUpperCase().startsWith("HEAD ");
thisSession.uiPUT("current_dir",data.substring(data.indexOf(" ")+1, endPos));
if (!thisSession.uiSG("current_dir").toUpperCase().startsWith(thisSession.SG("root_dir").toUpperCase())) thisSession.uiPUT("current_dir",thisSession.SG("root_dir") + (thisSession.uiSG("current_dir").startsWith("/")?thisSession.uiSG("current_dir").substring(1):thisSession.uiSG("current_dir")));
if (thisSession.uiSG("current_dir").indexOf("\\") >= 0) thisSession.uiPUT("current_dir",thisSession.uiSG("current_dir").replace('\\','/'));
if (!thisSession.uiSG("current_dir").startsWith("/")) thisSession.uiPUT("current_dir","/"+thisSession.uiSG("current_dir"));
if (thisSession.uiSG("current_dir").endsWith("/"))
{
action = "serve dir";
if (!thisSession.check_access_privs(thisSession.uiSG("current_dir"), "LIST") || !Common.filter_check("U", Common.last(thisSession.uiSG("current_dir")), server_status_frame.SG("filename_filters_str")))
action = "serve empty dir";
}
else
{
action = "serve file";
boolean ok = thisSession.check_access_privs(thisSession.uiSG("current_dir"), "RETR") && Common.filter_check("U", Common.last(thisSession.uiSG("current_dir")), server_status_frame.SG("filename_filters_str"));
try
{
Properties item = thisSession.uVFS.get_item(thisSession.uiSG("current_dir"));
//this is a dir item, they must be missing the "/"
if (item != null && item.getProperty("type","").equals("DIR") && !thisSession.uiSG("current_dir").endsWith("/"))
{
sendRedirect(thisSession.uiSG("current_dir")+"/",headers);
write_command_http("Content-Length: 0");
write_command_http("");
return;
}
if (ok) otherFile = new VFS_URL(item,thisSession.uVFS);
if (otherFile == null && thisSession.uiSG("current_dir").toUpperCase().endsWith(".ZIP"))
{
thisSession.uiPUT("current_dir",thisSession.uiSG("current_dir").substring(0,thisSession.uiSG("current_dir").length()-4));
ok = thisSession.check_access_privs(thisSession.uiSG("current_dir"), "RETR") && Common.filter_check("U", Common.last(thisSession.uiSG("current_dir")), server_status_frame.SG("filename_filters_str"));
item = thisSession.uVFS.get_item(thisSession.uiSG("current_dir"));
if (ok)
{
otherFile = new VFS_URL(item,thisSession.uVFS);
otherFile = new VFS_URL(otherFile.getParent().getPath()+otherFile.getName()+".zip",thisSession.uVFS);
}
else
{
thisSession.uiPUT("current_dir",thisSession.uiSG("current_dir")+".zip");
}
}
}
catch(Exception e)
{
Common.debug(1,e);
}
}
if (data.toUpperCase().startsWith("GET /WEBINTERFACE/"))
{
thisSession.uiPUT("macbinary_enabled","false");
action = "serve file";
String theFile = data.substring(data.indexOf(" ")+1,endPos);
theFile = Common.url_decode(theFile);
theFile = Common.replace_str(theFile,"..","");
theFile = Common.replace_str(theFile,"\\","/");
theFile = Common.replace_str(theFile,"//","/");
otherFile = new VFS_URL(new File(System.getProperty("crushftp.web")+"WebInterface/"+theFile).toURL().toExternalForm(),thisSession.uVFS);
if (theFile.toUpperCase().startsWith("/WEBINTERFACE/") || theFile.toUpperCase().startsWith(thisSession.SG("root_dir").toUpperCase()+"WEBINTERFACE/"))
{
if (!theFile.toUpperCase().endsWith(".JAR")) cacheHeader = "Expires: " + lastModifiedSDF.format(new Date(new Date().getTime()+(1000*60*60*24*1)))+"";
if (theFile.indexOf("/WebInterface/images/CrushImagePreview/") >= 0)
{
//translate first to the users VFS file
theFile = thisSession.uiSG("current_dir");
theFile = Common.replace_str(theFile,"/WebInterface/images/CrushImagePreview","");
String originalTheFile = theFile;
theFile = theFile.substring(0,theFile.lastIndexOf("."));
thisSession.uiPUT("current_dir",theFile);
Properties item = thisSession.uVFS.get_item(thisSession.uiSG("current_dir"));
if (item != null)
{
otherFile = new VFS_URL(item,thisSession.uVFS);
//then get the real local path
String destPath = otherFile.getFile().getCanonicalPath();
if (destPath.indexOf(":") >= 0) destPath = destPath.substring(destPath.indexOf(":")+1);
destPath = destPath.replace('\\','/')+originalTheFile.substring(originalTheFile.lastIndexOf("."));
otherFile = new VFS_URL(new File(System.getProperty("crushftp.web")+"WebInterface/images/CrushImagePreview"+destPath).toURL().toExternalForm(),thisSession.uVFS);
}
}
else otherFile = new VFS_URL(new File(System.getProperty("crushftp.web")+"WebInterface/"+theFile.substring("/webInterface/".length())).toURL().toExternalForm(),thisSession.uVFS);
}
thisSession.user = new Properties();
}
}
else if (data.toUpperCase().startsWith("POST "))
{
thisSession.uiPUT("current_dir",data.substring(data.indexOf(" ")+1, endPos));
if (!thisSession.uiSG("current_dir").toUpperCase().startsWith(thisSession.SG("root_dir").toUpperCase())) thisSession.uiPUT("current_dir",thisSession.SG("root_dir") + (thisSession.uiSG("current_dir").startsWith("/")?thisSession.uiSG("current_dir").substring(1):thisSession.uiSG("current_dir")));
if (thisSession.uiSG("current_dir").indexOf("\\") >= 0) thisSession.uiPUT("current_dir",thisSession.uiSG("current_dir").replace('\\','/'));
if (!thisSession.uiSG("current_dir").startsWith("/")) thisSession.uiPUT("current_dir","/"+thisSession.uiSG("current_dir"));
if (!thisSession.uiSG("current_dir").endsWith("/")) thisSession.uiPUT("current_dir",thisSession.uiSG("current_dir")+"/");
action = "process post";
}
//webdav commands
else if (data.toUpperCase().startsWith("LOCK ") || data.toUpperCase().startsWith("UNLOCK ") || data.toUpperCase().startsWith("DELETE ") || data.toUpperCase().startsWith("MKCOL ") || data.toUpperCase().startsWith("PROPFIND ") || data.toUpperCase().startsWith("PUT ") || data.toUpperCase().startsWith("MOVE ") || data.toUpperCase().startsWith("PROPPATCH ") || data.toUpperCase().startsWith("DMMKPATH ") || data.toUpperCase().startsWith("DMMKPATHS ") || data.toUpperCase().startsWith("ACL ") || data.toUpperCase().startsWith("COPY "))
{
thisSession.uiPUT("current_dir",data.substring(data.indexOf(" ")+1, endPos));
if (!thisSession.uiSG("current_dir").toUpperCase().startsWith(thisSession.SG("root_dir").toUpperCase())) thisSession.uiPUT("current_dir",thisSession.SG("root_dir") + (thisSession.uiSG("current_dir").startsWith("/")?thisSession.uiSG("current_dir").substring(1):thisSession.uiSG("current_dir")));
if (thisSession.uiSG("current_dir").indexOf("\\") >= 0) thisSession.uiPUT("current_dir",thisSession.uiSG("current_dir").replace('\\','/'));
if (!thisSession.uiSG("current_dir").startsWith("/")) thisSession.uiPUT("current_dir","/"+thisSession.uiSG("current_dir"));
action = data.toLowerCase().substring(0,data.indexOf(" "));
}
else if (data.toUpperCase().startsWith("RANGE: BYTES="))//resuming transfers
{
/*
The first 300 bytes:Range: bytes=0-299
The second 300 bytes:Range: bytes=300-599
The last 300 bytes:Range: bytes=-300
Several ranges : bytes 0-299, bytes=500-900, bytes 1000-
The entire file from specified location (2341):Range: bytes=2341-
*/
String amount = data.toUpperCase().substring("RANGE: ".length()) + ",";
StringTokenizer st = new StringTokenizer(amount,",");
Vector byteRanges = new Vector();
thisSession.uiPUT("byteRanges",byteRanges);
while(st.hasMoreElements())
{
String amountStart = st.nextElement().toString().trim();
amountStart = amountStart.substring(amountStart.toUpperCase().indexOf("=")+1).trim();
String amountEnd = amountStart.substring(amountStart.indexOf("-")+1).trim();
amountStart = amountStart.substring(0,amountStart.indexOf("-")).trim();
if (amountStart.equals(""))amountStart = "0";
Properties p = new Properties();
p.put("start", amountStart);
p.put("end", amountEnd);
byteRanges.addElement(p);
if (byteRanges.size() == 1) thisSession.uiPUT("start_resume_loc",amountStart);
}
}
else if (data.toUpperCase().indexOf("BOUNDARY=") >= 0)
{
http_boundary = data.substring(data.toUpperCase().indexOf("BOUNDARY=") + "BOUNDARY=".length()).trim();
}
else if (data.toUpperCase().indexOf("X-WEBDAV-METHOD:") >= 0 && data.toUpperCase().indexOf("DMMKPATH") >= 0)
{
action = data.substring(data.indexOf(" ")).trim().toLowerCase();
}
else if (data.toUpperCase().indexOf("X-WEBDAV-METHOD:") >= 0 && data.toUpperCase().indexOf("DMOVERLAY") >= 0)
{
action = data.substring(data.indexOf(" ")).trim().toLowerCase();
}
else if (data.toUpperCase().indexOf("X-WEBDAV-METHOD:") >= 0 && data.toUpperCase().indexOf("SETPROCESS") >= 0)
{
action = data.substring(data.indexOf(" ")).trim().toLowerCase();
}
else if (data.toUpperCase().indexOf("X-WEBDAV-METHOD:") >= 0 && data.toUpperCase().indexOf("ACL") >= 0)
{
action = data.substring(data.indexOf(" ")).trim().toLowerCase();
}
else if (data.toUpperCase().startsWith("IF-MODIFIED-SINCE: "))
{
ifnonematch = data.substring(data.toUpperCase().indexOf("IF-MODIFIED-SINCE:") + "IF-MODIFIED-SINCE:".length()).trim();
try{ifnonematch = lastModifiedSDF.parse(ifnonematch).getTime() + "";}catch(Exception e){}
}
else if (data.toUpperCase().startsWith("IF-NONE-MATCH: "))
{
ifnonematch = data.substring(data.toUpperCase().indexOf("IF-NONE-MATCH:") + "IF-NONE-MATCH:".length()).trim();
}
else if (data.toUpperCase().startsWith("DEPTH: "))
{
try{depth = data.substring(data.toUpperCase().indexOf("DEPTH:") + "DEPTH:".length()).trim();}catch(Exception e){}
}
else if (data.toUpperCase().startsWith("DESTINATION: ") || data.toUpperCase().startsWith("X-TARGET-HREF:"))
{
move_destination = data.substring(data.toUpperCase().indexOf(" ")).trim();
}
}
String initial_current_dir = thisSession.uiSG("current_dir");
String error_message = "";
if (action.equals("propfind"))
{
String xml = get_raw_http_command((int)http_len_max);
//System.out.println("PROPFIND REQUEST:"+initial_current_dir+"\r\n"+xml);
thisSession.uiVG("user_log").addElement(xml);
Properties commandActions = new Properties();
Vector commandActionsOrder = new Vector();
if (!xml.trim().equals(""))
{
try
{
Document doc = sax.build(new StringReader(xml));
List items = doc.getRootElement().getChildren();
Iterator i = items.iterator();
if (i.hasNext())
{
Element element = (Element)i.next();
List items2 = element.getChildren();
Iterator i2 = items2.iterator();
while (i2.hasNext())
{
Element element2 = (Element)i2.next();
String key = element2.getName();
String val = element2.getText();
commandActions.put(key,val);
commandActionsOrder.addElement(key);
}
}
}
catch(Throwable e)
{
Common.debug(1,e);
}
}
xml = doPropFind(commandActions,depth,false, commandActionsOrder);
if (SG("username").equals("anonymous"))
{
Properties item = thisSession.uVFS.get_item(initial_current_dir);
if (item.getProperty("privs").indexOf("(view)") < 0)
{
//deauth user...probably looking for public iDisk
DEAUTH();
return;
}
}
if (xml != null)
{
write_command_http("HTTP/1.1 207 Multi-Status");
write_standard_headers();
write_command_http("Content-Length: "+(xml.getBytes("UTF8").length+2));
write_command_http("Content-Type: text/xml; charset=utf-8");
String dir = initial_current_dir;
if (dir.startsWith(thisSession.SG("root_dir"))) dir = initial_current_dir.substring(thisSession.SG("root_dir").length()-1);
Properties item = thisSession.uVFS.get_item(initial_current_dir);
if (item != null && item.getProperty("type","").equalsIgnoreCase("DIR") && !dir.endsWith("/"))
{
write_command_http("Content-Location: " + Common.url_encode(dir,"/")+"/");
}
write_command_http("");
write_command_raw(xml+"\r\n");
//System.out.println("PROPFIND RESPONSE:("+depth+")"+xml);
thisSession.uiVG("user_log").addElement(xml);
}
else
{
String msg = "Not Found: Resource does not exist";
write_command_http("HTTP/1.1 404 Not Found: Resource does not exist");
done = true;
write_standard_headers();
write_command_http("Content-Type: text/xml; charset=utf-8");
write_command_http("Content-Length: "+msg.length());
write_command_http("");
write_command_raw(msg);
}
}
else if (action.equals("proppatch"))
{
/*
<?xml version="1.0" encoding="utf-8" ?>
<a:propertyupdate xmlns:a="DAV:" xmlns:b="http://www.apple.com/SyncServices">
<a:set><a:prop><b:dataclassname>com.apple.MailAccounts</b:dataclassname></a:prop></a:set>
<a:set><a:prop><b:displayname>Mail Accounts</b:displayname></a:prop></a:set>
</a:propertyupdate>
*/
String xml = get_raw_http_command((int)http_len_max);
//System.out.println("PROPPATCH REQUEST:"+thisSession.uiSG("current_dir")+"\r\n"+xml);
thisSession.uiVG("user_log").addElement(xml);
Properties commandActions = new Properties();
Vector commandActionsOrder = new Vector();
try
{
Document doc = sax.build(new StringReader(xml));
List items = doc.getRootElement().getChildren();
Iterator i = items.iterator();
while (i.hasNext())
{
Element element = (Element)i.next();
List items2 = element.getChildren();
Iterator i2 = items2.iterator();
while (i2.hasNext())
{
Element element2 = (Element)i2.next();
List items3 = element2.getChildren();
Iterator i3 = items3.iterator();
while (i3.hasNext())
{
Element element4 = (Element)i3.next();
String key = element4.getName();
String val = element4.getText();
commandActions.put(key,val);
commandActionsOrder.addElement(key);
}
}
}
}
catch(Exception e)
{
Common.debug(1,e);
}
Properties item = thisSession.uVFS.get_item(thisSession.uiSG("current_dir"));
Properties commandActions2 = (Properties)proppatches.get(new VFS_URL(item,thisSession.uVFS).getFile().getCanonicalPath());
if (!new VFS_URL(item,thisSession.uVFS).getFile().exists()) commandActions2 = null;
if (commandActions2 == null) commandActions2 = new Properties();
commandActions2.putAll(commandActions);
proppatches.put(new VFS_URL(item,thisSession.uVFS).getFile().getCanonicalPath(),commandActions2);
savePropPatches();
xml = doPropFind(commandActions,depth,true,commandActionsOrder);
if (xml != null)
{
write_command_http("HTTP/1.1 207 Multi-Status");
String dir = initial_current_dir;
if (dir.startsWith(thisSession.SG("root_dir"))) dir = initial_current_dir.substring(thisSession.SG("root_dir").length()-1);
item = thisSession.uVFS.get_item(initial_current_dir);
if (item != null && item.getProperty("type","").equalsIgnoreCase("DIR") && !dir.endsWith("/"))
{
write_command_http("Content-Location: " + Common.url_encode(dir,"/")+"/");
}
write_standard_headers();
write_command_http("Content-Length: "+(xml.getBytes("UTF8").length+2));
write_command_http("Content-Type: text/xml;charset=utf-8");
write_command_http("");
write_command_raw(xml+"\r\n");
//System.out.println("PROPPATCH RESPONSE:("+depth+")"+xml);
thisSession.uiVG("user_log").addElement(xml);
}
else
{
String msg = "Not Found: Resource does not exist";
write_command_http("HTTP/1.1 404 Not Found: Resource does not exist");
write_standard_headers();
write_command_http("Content-Type: text/xml;charset=utf-8");
write_command_http("Content-Length: "+msg.length());
write_command_http("");
write_command_raw(msg);
}
}
else if (action.equals("delete"))
{
String dir = initial_current_dir;
if (dir.startsWith(thisSession.SG("root_dir"))) dir = initial_current_dir.substring(thisSession.SG("root_dir").length()-1);
Properties item = thisSession.uVFS.get_item(initial_current_dir);
Enumeration keys = proppatches.keys();
try
{
String propPath = new VFS_URL(item,thisSession.uVFS).getFile().getCanonicalPath();
while(keys.hasMoreElements())
{
String key = keys.nextElement().toString();
if (key.startsWith(propPath)) proppatches.remove(key);
}
savePropPatches();
}
catch(Exception e)
{
}
thisSession.uiPUT("the_command","DELE");
thisSession.uiPUT("the_command_data",thisSession.uiSG("current_dir"));
error_message += thisSession.do_DELE(true);
thisSession.uVFS.reset();
if (error_message.length() == 0) write_command_http("HTTP/1.1 204 No Content");
else write_command_http("HTTP/1.1 401 Access Denied.");
if (item != null && item.getProperty("type","").equalsIgnoreCase("DIR") && !dir.endsWith("/"))
{
write_command_http("Content-Location: " + Common.url_encode(dir,"/")+"/");
}
if (item != null && item.getProperty("type","").equalsIgnoreCase("DIR"))
{
//NotMac hack
//if an attempt is made to delete the schema items folder, honor it, but then re-create the folder immediately afterwords or else the sync fails. WHY?
if (thisSession.uiSG("current_dir").toUpperCase().indexOf("/LIBRARY/APPLICATION SUPPORT/SYNCSERVICES/SCHEMAS/") >= 0)
{
thisSession.do_MKD(true);
thisSession.uVFS.reset();
}
}
write_standard_headers();
write_command_http("Content-Length: 0");
write_command_http("");
}
else if (action.equals("acl"))
{
String xml = get_raw_http_command((int)http_len_max);
String dir = initial_current_dir;
if (dir.startsWith(thisSession.SG("root_dir"))) dir = initial_current_dir.substring(thisSession.SG("root_dir").length()-1);
Properties item = thisSession.uVFS.get_item(initial_current_dir);
write_command_http("HTTP/1.1 200 OK");
write_standard_headers();
write_command_http("Content-Length: 0");
write_command_http("");
}
else if (action.equals("copy"))
{
thisSession.uVFS.reset();
thisSession.uiPUT("the_command_data",thisSession.uiSG("current_dir"));
String from = thisSession.uiSG("current_dir");
//verify read access
boolean ok = true;
if (thisSession.check_access_privs(thisSession.uiSG("current_dir"), "RETR"))
{
thisSession.uiPUT("current_dir",new URL(move_destination).getPath());
if (!thisSession.uiSG("current_dir").toUpperCase().startsWith(thisSession.SG("root_dir").toUpperCase())) thisSession.uiPUT("current_dir",thisSession.SG("root_dir") + (thisSession.uiSG("current_dir").startsWith("/")?thisSession.uiSG("current_dir").substring(1):thisSession.uiSG("current_dir")));
if (thisSession.uiSG("current_dir").indexOf("\\") >= 0) thisSession.uiPUT("current_dir",thisSession.uiSG("current_dir").replace('\\','/'));
if (!thisSession.uiSG("current_dir").startsWith("/")) thisSession.uiPUT("current_dir","/"+thisSession.uiSG("current_dir"));
thisSession.uiPUT("the_command_data",thisSession.uiSG("current_dir"));
}
else ok = false;
if (ok && thisSession.check_access_privs(thisSession.uiSG("current_dir"), "STOR"))
{
String to = thisSession.uiSG("current_dir");
Properties source = thisSession.uVFS.get_item(from);
Properties dest = thisSession.uVFS.get_item_parent(to);
RandomAccessFile in = new RandomAccessFile(new VFS_URL(source,thisSession.uVFS).getFile().getCanonicalPath(),"r");
RandomAccessFile out = new RandomAccessFile(new VFS_URL(dest,thisSession.uVFS).getFile().getCanonicalPath(),"rw");
byte b[] = new byte[32768];
int bytesRead = 0;
while(bytesRead >= 0)
{
bytesRead = in.read(b);
if (bytesRead >= 0) out.write(b,0,bytesRead);
}
in.close();
out.close();
thisSession.uVFS.reset();
}
if (ok) write_command_http("HTTP/1.1 204 No Content");
else write_command_http("HTTP/1.1 403 Access Denied.");
write_standard_headers();
write_command_http("Content-Length: 0");
write_command_http("");
//verify they passed in a token to use this file
}
else if (action.equals("setprocess"))
{
String accountInfo = "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?><methodResponse><params><param><value>success</value></param></params></methodResponse>";
write_command_http("HTTP/1.1 200 OK");
write_command_http("Pragma: no-cache");
write_standard_headers();
write_command_http("Content-Length: "+accountInfo.length());
write_command_http("Content-Type: text/xml");
write_command_http("");
write_command_raw(accountInfo);thisSession.add_log(accountInfo, "ACCEPT");
return;
}
else if (action.equals("dmmkpath") || action.equals("dmmkpaths"))
{
String the_dir = thisSession.uiSG("current_dir");
if (!the_dir.endsWith("/")) the_dir += "/";
Properties item = null;
Vector reversePath = new Vector();
while(item == null && !the_dir.equals(""))
{
item = thisSession.uVFS.get_item(the_dir);
if (item == null)
{
reversePath.addElement(the_dir);
the_dir = Common.all_but_last(the_dir);
}
}
if (item.getProperty("privs").indexOf("(makedir)") >= 0)
{
//make the dirs for them
new VFS_URL(thisSession.uiSG("current_dir"),thisSession.uVFS).mkdirs();
String xml = get_raw_http_command((int)http_len_max);
//System.out.println("DMMKPATH:"+thisSession.uiSG("current_dir")+"\r\n"+xml);
thisSession.uiVG("user_log").addElement(xml);
try
{
Document doc = sax.build(new StringReader(xml));
Element root = doc.getRootElement();
List instructions = root.getContent();
item = thisSession.uVFS.get_item(thisSession.uiSG("current_dir"));
String basePath = Common.all_but_last(new VFS_URL(item,thisSession.uVFS).getFile().getCanonicalPath());
for (int x=0; x<instructions.size(); x++)
{
Element inst = (Element)instructions.get(x);
String path = Common.url_decode(((Element)inst.getContent().get(1)).getText());
new VFS_URL(basePath+path.substring(1),thisSession.uVFS).mkdirs();
}
}
catch(Exception e)
{
}
}
thisSession.uVFS.reset();
if (error_message.length() == 0 || error_message.indexOf(LOC.G("exists")) >= 0)
{
Element root = new Element("multistatus","DAV:");
Document doc = new Document(root);
Element response = new Element("response","DAV:");
root.addContent(response);
Element href = new Element("href","DAV:");
response.addContent(href);
href.setText(the_dir);
Element status = new Element("status","DAV:");
response.addContent(status);
status.setText("HTTP/1.1 201 Created");
if (xmlOut == null)
{
xmlOut = new XMLOutputter();
Format f = Format.getPrettyFormat();
f.setExpandEmptyElements(false);
//f.setIndent("\t");
xmlOut.setFormat(f);
}
String xml= xmlOut.outputString(doc);
write_command_http("HTTP/1.1 207 Multi-Status");
write_standard_headers();
write_command_http("Content-Length: "+(xml.getBytes("UTF8").length+2));
write_command_http("Content-Type: text/xml;charset=utf-8");
write_command_http("");
write_command_raw(xml+"\r\n");
// System.out.println("DMMKPATH RESPONSE:"+xml);
thisSession.uiVG("user_log").addElement(xml);
thisSession.uVFS.reset();
}
else
{
write_command_http("HTTP/1.1 403 Access Denied.");
write_standard_headers();
write_command_http("Content-Length: 0");
write_command_http("");
}
}
else if (action.equals("mkcol"))
{
thisSession.uiPUT("the_command","MKDIR");
String the_dir = thisSession.uiSG("current_dir");
if (!the_dir.endsWith("/")) the_dir += "/";
thisSession.uiPUT("the_command_data",the_dir);
error_message += thisSession.do_MKD(false);
thisSession.uVFS.reset();
boolean good = false;
if (error_message.length() == 0 || error_message.indexOf(LOC.G("exists")) >= 0)
{
good = true;
Properties item = thisSession.uVFS.get_item(thisSession.uiSG("current_dir")+"/");
thisSession.accessExceptions.put(thisSession.uiSG("current_dir")+"/",item);
write_command_http("HTTP/1.1 201 Created");
for (int x=0; x<headers.size(); x++)
{
data = headers.elementAt(x).toString();
if (data.startsWith("Last-Modified: "))
{
String modified = data.substring(data.indexOf(":")+1).trim();
thisSession.uiPUT("the_command","MDTM");
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
thisSession.uiPUT("the_command_data",thisSession.uiSG("current_dir")+" "+sdf.format(sdf_rfc1123.parse(modified)));
error_message += thisSession.do_MDTM();
}
}
thisSession.uVFS.reset();
}
else write_command_http("HTTP/1.1 403 Access Denied.");
write_standard_headers();
if (good) write_command_http("Content-Location: " + Common.url_encode(the_dir,"/"));
write_command_http("Content-Length: 16"); //without this line, iWeb hangs indefinitely
write_command_http("");
write_command_http("Resource created"); //without this line, iWeb hangs indefinitely
}
else if (action.equals("lock"))
{
String xml = get_raw_http_command((int)http_len_max);
//System.out.println("LOCK REQUEST:"+thisSession.uiSG("current_dir")+"\r\n"+xml);
thisSession.uiVG("user_log").addElement(xml);
Element root = new Element("prop","D","DAV:");
Document doc = new Document(root);
Element lockdiscovery = new Element("lockdiscovery","D", "DAV:");
root.addContent(lockdiscovery);
Element activelock = new Element("activelock","D", "DAV:");
lockdiscovery.addContent(activelock);
Element locktype = new Element("locktype","D", "DAV:");
activelock.addContent(locktype);
Element write = new Element("write","D", "DAV:");
locktype.addContent(write);
Element lockscope = new Element("lockscope","D", "DAV:");
activelock.addContent(lockscope);
Element exclusive = new Element("exclusive","D", "DAV:");
lockscope.addContent(exclusive);
Element depthElement = new Element("depth","D", "DAV:");
activelock.addContent(depthElement);
depthElement.setText(depth);
Element owner = new Element("owner","D", "DAV:");
activelock.addContent(owner);
Element href = new Element("href","D", "DAV:");
owner.addContent(href);
Element synclockinfo = new Element("synclockinfo","SY", "http://www.apple.com/SyncServices");
href.addContent(synclockinfo);
Element lock_user = new Element("lock-user","SY", "SY:");
synclockinfo.addContent(lock_user);
lock_user.setText(SG("username"));
if (xml.indexOf("clientid>") >= 0)
{
Element clientid = new Element("clientid","SY", "SY:");
synclockinfo.addContent(clientid);
clientid.setText(xml.substring(xml.indexOf("clientid>")+9,xml.indexOf("<",xml.indexOf("clientid>"))));
}
if (xml.indexOf("clientname>") >= 0)
{
Element clientname = new Element("clientname","SY", "SY:");
synclockinfo.addContent(clientname);
clientname.setText(xml.substring(xml.indexOf("clientname>")+11,xml.indexOf("<",xml.indexOf("clientname>"))));
}
Element acquiredate = new Element("acquiredate","SY", "SY:");
synclockinfo.addContent(acquiredate);
SimpleDateFormat lockSDF = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss Z");
acquiredate.setText(lockSDF.format(new Date()));
Element timeout = new Element("timeout","D", "DAV:");
activelock.addContent(timeout);
timeout.setText("Second-239");
Properties lock = new Properties();
lock.put("token", (ServerSessionNotMacXML.makeGuid("",3)+"-"+ServerSessionNotMacXML.makeGuid("",7)+"-"+ServerSessionNotMacXML.makeGuid("",3)+"-"+ServerSessionNotMacXML.makeGuid("",10)+"-"+ServerSessionNotMacXML.makeGuid("",9)).toLowerCase());
lock.put("stamp", new Date().getTime()+"");
lock.put("duration", "600");
Properties item = thisSession.uVFS.get_item(initial_current_dir);
try{lock.put("resource", new VFS_URL(item,thisSession.uVFS).getFile().getCanonicalPath().toUpperCase());}catch(Exception e){}
locktokens.put(lock.getProperty("token"), lock);
Element locktoken = new Element("locktoken","D", "DAV:");
activelock.addContent(locktoken);
Element href2 = new Element("href","D", "DAV:");
locktoken.addContent(href2);
href2.setText("dotmaclocktoken:"+lock.getProperty("token"));
if (xmlOut == null)
{
xmlOut = new XMLOutputter();
Format f = Format.getPrettyFormat();
f.setExpandEmptyElements(false);
//f.setIndent("\t");
xmlOut.setFormat(f);
}
xml= xmlOut.outputString(doc);
write_command_http("HTTP/1.1 200 OK");
write_standard_headers();
write_command_http("Content-Length: "+(xml.getBytes("UTF8").length+2));
write_command_http("Content-Type: text/xml;charset=utf-8");
write_command_http("Lock-Token: <dotmaclocktoken:"+lock.getProperty("token")+">");
String dir = initial_current_dir;
if (dir.startsWith(thisSession.SG("root_dir"))) dir = initial_current_dir.substring(thisSession.SG("root_dir").length()-1);
item = thisSession.uVFS.get_item(initial_current_dir);
if (item != null && item.getProperty("type","").equalsIgnoreCase("DIR") && !dir.endsWith("/"))
{
write_command_http("Content-Location: " + Common.url_encode(dir,"/")+"/");
}
write_command_http("");
write_command_raw(xml+"\r\n");
//System.out.println("LOCK RESPONSE:"+xml);
thisSession.uiVG("user_log").addElement(xml);
}
else if (action.equals("unlock"))
{
write_command_http("HTTP/1.1 204 No Content");
write_standard_headers();
write_command_http("Content-Length: 0");
write_command_http("");
//verify they passed in the token to unlock it
Properties lock = new Properties();
lock.put("token", new Date().getTime()+"");
lock.put("stamp", new Date().getTime()+"");
lock.put("duration", "600");
Properties item = thisSession.uVFS.get_item(initial_current_dir);
lock.put("resource", new VFS_URL(item,thisSession.uVFS).getFile().getCanonicalPath().toUpperCase());
locktokens.put(lock.getProperty("token"), lock);
}
else if (action.equals("put"))
{
boolean ok = doPutFile(http_len_max,done);
if (ok)
{
write_command_http("HTTP/1.1 201 Created");
write_command_http("Last-Modified: " + lastModifiedSDF.format(new Date()));
for (int x=0; x<headers.size(); x++)
{
data = headers.elementAt(x).toString();
if (data.startsWith("Last-Modified: "))
{
String modified = data.substring(data.indexOf(":")+1).trim();
thisSession.uiPUT("the_command","MDTM");
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
thisSession.uiPUT("the_command_data",thisSession.uiSG("current_dir")+" "+sdf.format(sdf_rfc1123.parse(modified)));
error_message += thisSession.do_MDTM();
}
}
thisSession.uVFS.reset();
//NotMac hacks :( //special things Apple's servers seem to be doing in the background
if (thisSession.uiSG("current_dir").indexOf("/Web/Sites/iPhoto/") >= 0 && thisSession.uiSG("current_dir").endsWith("index.rss"))
{
//modify file replacing www.mac.com with our server address
Properties item = thisSession.uVFS.get_item(thisSession.uiSG("current_dir"));
RandomAccessFile f = new RandomAccessFile("/Library/Application Support/NotMac/url.txt","r");
byte b[] = new byte[(int)f.length()];
f.readFully(b);
String url = new String(b);
f.close();
url = url.substring(url.indexOf("//"+2,url.lastIndexOf("/")));
f = new RandomAccessFile(new VFS_URL(item,thisSession.uVFS).getFile().getCanonicalPath(),"rw");
b = new byte[(int)f.length()];
f.readFully(b);
String s = new String(b);
s = Common.replace_str(s,"web.mac.com",url);
f.setLength(0);
f.write(s.getBytes());
f.close();
}
else if (thisSession.uiSG("current_dir").indexOf("/.calendars/") >= 0 && thisSession.uiSG("current_dir").endsWith(".ics") && userAgent.indexOf("iCal") >= 0)
{
//add a virtual reference to this calendar to "anonymous"'s account.
String calendarName = Common.last(thisSession.uiSG("current_dir"));
Properties calendars = new Properties();
calendars.put("url","FILE:/"+new File("/Library/Application Support/NotMac/Storage/"+thisSession.uiSG("user_name")+"/Sites/.calendars/"+calendarName).getCanonicalPath());
calendars.put("type","dir");
Vector v = new Vector();
v.addElement(calendars);
common_code.writeXMLObject("/Library/Application Support/NotMac/CrushFTP/users/127.0.0.1_53818/anonymous/VFS/"+thisSession.uiSG("user_name")+"/"+calendarName,v,"VFS");
}
}
else write_command_http("HTTP/1.1 403 Access Denied.");
write_standard_headers();
write_command_http("Content-Length: 0");
write_command_http("");
//verify they passed in a token to use this file
}
else if (action.equals("move") || action.equals("dmoverlay"))
{
thisSession.uVFS.reset();
String rename_from = thisSession.uiSG("current_dir");
thisSession.uiPUT("the_command_data",rename_from);
error_message += thisSession.do_RNFR();
thisSession.uiPUT("current_dir",move_destination);
try{thisSession.uiPUT("current_dir",new URL(move_destination).getPath());}catch(Exception e){Common.debug(2,e);}
if (!thisSession.uiSG("current_dir").toUpperCase().startsWith(thisSession.SG("root_dir").toUpperCase())) thisSession.uiPUT("current_dir",thisSession.SG("root_dir") + (thisSession.uiSG("current_dir").startsWith("/")?thisSession.uiSG("current_dir").substring(1):thisSession.uiSG("current_dir")));
if (thisSession.uiSG("current_dir").indexOf("\\") >= 0) thisSession.uiPUT("current_dir",thisSession.uiSG("current_dir").replace('\\','/'));
if (!thisSession.uiSG("current_dir").startsWith("/")) thisSession.uiPUT("current_dir","/"+thisSession.uiSG("current_dir"));
thisSession.uiPUT("the_command_data",thisSession.uiSG("current_dir"));
if (error_message.length() == 0)
{
if (action.equals("dmoverlay")) //notMac hack...we have to copy overtop the existing directory, not just rename
{
thisSession.uiPUT("the_command","RNTO");
thisSession.uiPUT("last_logged_command","RNTO");
String the_dir = thisSession.fixupDir();
Properties item = thisSession.uVFS.get_item_parent(the_dir);
if (thisSession.check_access_privs(the_dir, thisSession.uiSG("the_command"), item) && Common.filter_check("R", Common.last(the_dir), server_status_frame.SG("filename_filters_str")))
{
Properties item_src = thisSession.uVFS.get_item_or_vitem(rename_from);
VFS_URL v_src = new VFS_URL(item_src,thisSession.uVFS);
VFS_URL v_dest = new VFS_URL(item,thisSession.uVFS);
Common.recurseCopy(v_src.getFile().getCanonicalPath()+"/",v_dest.getFile().getCanonicalPath()+"/");
Common.recurseDelete(v_src.getFile().getCanonicalPath()+"/",false);
}
else
{
error_message += "Access denied";
}
}
else error_message += thisSession.do_RNTO(true);
}
thisSession.uVFS.reset();
if (error_message.length() == 0) write_command_http("HTTP/1.1 204 No Content");
else if (error_message.indexOf("RNFR") >= 0) write_command_http("HTTP/1.1 404 Not Found");
else write_command_http("HTTP/1.1 403 Access Denied.");
write_standard_headers();
write_command_http("Content-Length: 0");
write_command_http("");
//verify they passed in a token to use this file
}
else if (action.equals("process post"))// post item...so get the items and do the action
{
if (thisSession.uiSG("current_dir").equals(thisSession.SG("root_dir") + "StartCrushFTPAdminSession.bin/") && headers.elementAt(0).toString().startsWith("POST ") && thisSession.SG("site").indexOf("(CONNECT)") >= 0)
{
write_command_http("HTTP/1.1 200 OK");
write_command_http("Pragma: no-cache");
write_command_http("Connection: close");
write_standard_headers();
write_command_http("");
thisSession.data_sock = sock;
thisSession.uiPUT("current_user",thisSession.uiSG("user_name"));
thisSession.do_remote_admin_input(original_is);
sock = null;
original_os = null;
original_is = null;
done = true;
return;
}
Vector items = new Vector();
boolean skip_refresh = false;
if (!http_boundary.equals("")) items = get_http_post_items(http_boundary,http_len_max);
else
{
if (thisSession.uiSG("current_dir").toUpperCase().endsWith(".PDF") || thisSession.uiSG("current_dir").toUpperCase().endsWith(".FDF"))
{
boolean ok = doPutFile(http_len_max, done);
String redirectPDF = thisSession.uiSG("current_dir");
if (redirectPDF.endsWith("/")) redirectPDF = redirectPDF.substring(0,redirectPDF.length()-1);
redirectPDF = Common.last(redirectPDF);
String ext = redirectPDF.substring(redirectPDF.indexOf("."));
String base = redirectPDF.substring(0,redirectPDF.indexOf("."));
if (ext.equalsIgnoreCase(".FDF")) ext = ".PDF";
if (ok) sendRedirect("/WebInterface/"+base+"Success"+ext,headers);
else write_command_http("HTTP/1.1 403 Access Denied.");
write_command_http("Connection: close");
write_command_http("");
kill_all = true;
done = true;
thisSession.uVFS = null;
return;
}
else if (thisSession.uiSG("current_dir").equals(thisSession.SG("root_dir") + "servlet/f1.xml.ServiceRequestV3/") && headers.elementAt(0).toString().startsWith("POST "))
{
ssnmx.process(headers,this);
return;
}
else
{
if (http_len_max < 1024*10000)//max post is 10MB
{
String xml = get_raw_http_command((int)http_len_max);
// System.out.println(xml);
thisSession.add_log(xml, "ACCEPT");
if (thisSession.uiSG("current_dir").endsWith("/WebObjects/Info.woa/wa/XMLRPC/accountInfo/")) //iWeb publishing does this
{
if (xml.indexOf("daysLeftUntilExpiration") >= 0) //checks the days until account expires
{
xml = "<?xml version='1.0'?>\r\n"+
"<methodResponse><params><param><value><struct><member><name>daysLeftUntilExpiration</name>\r\n"+
"<value><int>59</int></value></member></struct></value></param></params></methodResponse>\r\n";
}
else if (xml.indexOf("servicesAvailable") >= 0) //may also check the services that are available
{
xml = "<?xml version='1.0'?><methodResponse><params><param><value><struct><member><name>servicesAvailable</name>"+
"<value><array><value><string>iDisk</string></value><value><string>iSync</string></value><value><string>Email</string></value>"+
"<value><string>WebHosting</string></value><value><string>Backup</string></value><value><string>BTMM</string></value></array></value></member></struct></value></param></params></methodResponse>\r\n";
}
write_command_http("HTTP/1.1 200 OK");
write_command_http("Pragma: no-cache");
write_standard_headers();
write_command_http("Content-Length: "+xml.length());
write_command_http("Content-Type: text/html");
write_command_http("");
write_command_raw(xml);thisSession.add_log(xml, "ACCEPT");
return;
}
else if (thisSession.uiSG("current_dir").endsWith("dotMacPreferencesPaneMessage/"))
{
String username = changeUser(xml);
boolean ok = username != null;
if (!ok) username = "anonymous";
RandomAccessFile in = new RandomAccessFile("/Library/Application Support/NotMac/dotMacPreferencesPaneMessage.html","r");
byte b[] = new byte[(int)in.length()];
in.readFully(b);
in.close();
String html = new String(b).replace('\"', '\'');
in = new RandomAccessFile("/Library/Application Support/NotMac/url.txt","r");
b = new byte[(int)in.length()];
in.readFully(b);
in.close();
String url = new String(b).replace('\"', '\'');
html = Common.replace_str(html,"%url%",url);
if (username.equals("anonymous")) html = Common.replace_str(html,"%username%","");
else html = Common.replace_str(html,"%username%",username+"/");
String welcome = "{ \r"+
" messageHTML = \""+html+"\"; \r"+
" service = dotMacPreferencesPaneMessage; \r"+
" servicesAvailable = (iDisk, iSync, Email, WebHosting, BTMM, Backup); \r"+
" statusCode = success; \r"+
" version = 1; \r"+
"}";
if (!ok)
{
//see if they have the cookie crushauth.
//if not, this is the first attempt, so respond OK so the page is loaded
//if the do, say their password is wrong.
boolean foundCookie = false;
for (int x=0; x<headers.size(); x++) //first loop through and see if they have a cookie for auth
{
data = headers.elementAt(x).toString();
if (data.startsWith("Cookie: "))
{
if (data.indexOf("CrushAuth=") >= 0) foundCookie = true;
}
}
if (foundCookie)
{
welcome = "{ \r"+
"messageHTML = \""+html+"\"; \r"+
" service = dotMacPreferencesPaneMessage; \r"+
" forgottenPasswordURL = \"http://www.notmacchallenge.com/\"; \r"+
" servicesAvailable = (iDisk, iSync, Email, WebHosting, BTMM, Backup); \r"+
" statusCode = authorizationFailed; \r"+
"}";
}
write_command_http("HTTP/1.1 401 OK");
}
else write_command_http("HTTP/1.1 200 OK");
welcome = Common.replace_str(welcome,"%status%","Welcome to NotMac!");
write_command_http("Pragma: no-cache");
write_standard_headers();
write_command_http("Content-Length: "+welcome.length());
write_command_http("Content-Type: text/html");
write_command_http("");
write_command_raw(welcome);thisSession.add_log(welcome, "ACCEPT");
return;
}
else if (thisSession.uiSG("current_dir").endsWith("/WebObjects/Info.woa/wa/Query/configureDisk/") || thisSession.uiSG("current_dir").endsWith("retrieveDiskConfiguration/"))
{
String username = changeUser(xml);
boolean ok = username != null;
if (!ok)
{
DEAUTH();
return;
}
long quota = -12345;
long total_quota = -12345;
try{quota=thisSession.get_quota_used("/"+username+"/");}catch(Exception e){}
try{total_quota=thisSession.get_total_quota("/"+username+"/");}catch(Exception e){}
if (quota == -12345) quota = 0;
if (total_quota == -12345) total_quota = 300*1024*1024;
//get the current privs on this dir to see if its read or write for the user named "public"
Properties permissions = (Properties)Common.readXMLObject("/Library/Application Support/NotMac/CrushFTP/users/127.0.0.1_53818/public/VFS.XML");
if (xml.indexOf("guestWriteEnabled = Y") >= 0 || xml.indexOf("guestWriteEnabled = 1") >= 0)
{
if (thisSession.uiSG("current_dir").endsWith("/WebObjects/Info.woa/wa/Query/configureDisk/"))
{
permissions.put(("/"+username+"/Public/").toUpperCase(),"(read)(write)(view)(resume)");
}
}
else if (thisSession.uiSG("current_dir").endsWith("/WebObjects/Info.woa/wa/Query/configureDisk/"))
{
permissions.put(("/"+username+"/Public/").toUpperCase(),"(read)(view)(resume)");
}
try{common_code.writeXMLObject("/Library/Application Support/NotMac/CrushFTP/users/127.0.0.1_53818/public/VFS.XML",permissions,"VFS");}catch(Exception ee){}
boolean guestWriteEnabled = permissions.getProperty(("/"+username+"/Public/").toUpperCase(),"").indexOf("(write)") >= 0;
if (xml.indexOf("generalPassword = ") >= 0 && thisSession.uiSG("current_dir").endsWith("/WebObjects/Info.woa/wa/Query/configureDisk/"))
{
String pass = xml.substring(xml.indexOf("generalPassword = ")+"generalPassword = ".length(),xml.indexOf(";",xml.indexOf("generalPassword = "))).trim();
publicpasswords.put(("/"+username+"/Public/").toUpperCase(),common_code.encode_pass(pass,"DES"));
savePublicPasswords();
}
else if (thisSession.uiSG("current_dir").endsWith("/WebObjects/Info.woa/wa/Query/configureDisk/"))
{
publicpasswords.remove(("/"+username+"/Public/").toUpperCase());
savePublicPasswords();
}
boolean hasGeneralPassword = publicpasswords.containsKey(("/"+username+"/Public/").toUpperCase());
String idiskConfig = "{ \r"+
" payload = {\r"+
" authenticatedReadEnabled = "+(hasGeneralPassword&&!guestWriteEnabled?"Y":"N")+";\r"+
" authenticatedWriteEnabled = "+(hasGeneralPassword&&guestWriteEnabled?"Y":"N")+";\r"+
" guestReadEnabled = Y;\r"+
" guestWriteEnabled = "+(guestWriteEnabled?"Y":"N")+";\r"+
" hasGeneralPassword = "+(hasGeneralPassword?"Y":"N")+";\r";
if (thisSession.uiSG("current_dir").endsWith("retrieveDiskConfiguration/"))
{
idiskConfig += " iDiskQuotaInBytes = "+(total_quota)+";\r"+
" iDiskUsedBytes = "+quota+";\r";
}
idiskConfig += " relativePath = Public;\r"+
"}; \r"+
"statusCode = success;\r"+
"}";
write_command_http("HTTP/1.1 200 OK");
write_command_http("Pragma: no-cache");
write_standard_headers();
write_command_http("Content-Length: "+idiskConfig.length());
write_command_http("Content-Type: text/html");
write_command_http("");
write_command_raw(idiskConfig);thisSession.add_log(idiskConfig, "ACCEPT");
return;
}
else if (thisSession.uiSG("current_dir").endsWith("/WebObjects/RequestRouter.woa/wa/HomePagePublishing/accountInfo/"))
{
Document doc2 = sax.build(new StringReader(xml));
//System.out.println("REQUEST:"+xmlOut.outputString(doc2));
Element root = doc2.getRootElement();
Element dict = root.getChild("dict").getChild("dict");
String fakeStr = "username = "+((Element)dict.getChildren("string").get(0)).getText()+"; \r password = "+((Element)dict.getChildren("string").get(1)).getText()+";";
String username = changeUser(fakeStr);
boolean ok = username != null;
if (!ok)
{
DEAUTH();return;
}
long quota = -12345;
long total_quota = -12345;
try{quota=thisSession.get_quota_used("/"+username+"/");}catch(Exception e){}
try{total_quota=thisSession.get_total_quota("/"+username+"/");}catch(Exception e){}
if (quota == -12345) quota = 0;
if (total_quota == -12345) total_quota = 300*1024*1024;
xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n"+
"<!DOCTYPE plist PUBLIC \"-//Apple Computer//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\r\n"+
"<plist version=\"1.0\">\r\n"+
"<dict>\r\n"+
"<key>iDiskFreeBytes</key>\r\n"+
"<string>"+(total_quota-quota)+"</string>\r\n"+
"<key>sites</key>\r\n"+
"<array>\r\n"+
"<string>"+SG("username")+"</string>\r\n"+
"</array>\r\n"+
"<key>success</key>\r\n"+
"<string>yes</string>\r\n"+
"</dict>\r\n"+
"</plist>\r\n";
write_command_http("HTTP/1.1 200 OK");
write_command_http("Pragma: no-cache");
write_standard_headers();
write_command_http("Content-Length: "+xml.length());
write_command_http("Content-Type: text/html");
write_command_http("");
write_command_raw(xml);thisSession.add_log(xml, "ACCEPT");
return;
}
else if (thisSession.uiSG("current_dir").endsWith("/WebObjects/Info.woa/wa/Query/accountInfo/"))
{
String accountInfo = "{payload = {}; statusCode = success; }";
write_command_http("HTTP/1.1 200 OK");
write_command_http("Pragma: no-cache");
write_standard_headers();
write_command_http("Content-Length: "+accountInfo.length());
write_command_http("Content-Type: text/html");
write_command_http("");
write_command_raw(accountInfo);
return;
}
else if (thisSession.uiSG("current_dir").endsWith("accountInfo/"))
{
String accountInfo = "<?xml version='1.0'?> \r"+
"<methodResponse><params><param><value><struct> \r"+
"<member><name>daysLeftUntilExpiration</name><value><int>-1</int></value></member> \r"+
"</struct></value></param></params></methodResponse> \r";
write_command_http("HTTP/1.1 200 OK");
write_command_http("Pragma: no-cache");
write_standard_headers();
write_command_http("Content-Length: "+accountInfo.length());
write_command_http("Content-Type: text/html");
write_command_http("");
write_command_raw(accountInfo);thisSession.add_log(accountInfo, "ACCEPT");
return;
}
else if (thisSession.uiSG("current_dir").indexOf("/.Temporary Web Resources/") >= 0 && thisSession.uiSG("current_dir").endsWith("/Site/"))
{
String accountInfo = "";
thisSession.uiPUT("the_command","MKDIR");
String the_dir = thisSession.uiSG("current_dir");
if (!the_dir.endsWith("/")) the_dir += "/";
thisSession.uiPUT("the_command_data",the_dir);
error_message += thisSession.do_MKD(true);
thisSession.uVFS.reset();
write_command_http("HTTP/1.1 200 OK");
write_command_http("Pragma: no-cache");
write_standard_headers();
write_command_http("Content-Length: "+accountInfo.length());
write_command_http("Content-Type: text/html");
write_command_http("");
write_command_raw(accountInfo);thisSession.add_log(accountInfo, "ACCEPT");
return;
}
else if (thisSession.uiSG("current_dir").endsWith("/subscribe/") || thisSession.uiSG("current_dir").endsWith("/notify/"))
{
String unixTime = (new Date().getTime()/1000) + "";
unixTime = "0";
String accountInfo = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><methodResponse><params><param><value><struct><member><name>resultCode</name><value>Success</value></member><member><name>timestamp</name><value>"+unixTime+"</value></member><member><name>resultBody</name><value><array><data></data></array></value></member></struct></value></param></params></methodResponse>";
write_command_http("HTTP/1.1 200 OK");
write_command_http("Pragma: no-cache");
write_standard_headers();
write_command_http("Content-Length: "+accountInfo.length());
write_command_http("Content-Type: text/xml");
write_command_http("");
write_command_raw(accountInfo);thisSession.add_log(accountInfo, "ACCEPT");
return;
}
}
}
}
//do action from command
Properties p = new Properties();
for (int x=0; x<items.size(); x++)
{
Properties pp = (Properties)items.elementAt(x);
p.putAll(pp);
}
error_message += p.getProperty("stop_message","");
if (!skip_refresh) skip_refresh = p.getProperty("refresh","true").equalsIgnoreCase("false");
if (p.getProperty("type","").equals("text"))
{
//LOGIN
if (p.getProperty("the_action","").toUpperCase().startsWith("LOGIN"))
{
thisSession.uiPUT("current_password",p.getProperty("password"));
thisSession.uiPUT("user_name",p.getProperty("username"));
this_thread.setName(thisSession.uiSG("user_name") + ":(" + thisSession.uiSG("user_number") + ")-" + thisSession.uiSG("user_ip") + " (control)");
thisSession.uVFS = null;
boolean good = thisSession.login_user_pass();
if (good)
{
thisSession.do_event("Logged In.", "PASS","");
writeCookieAuth = true;
try
{
String id = thisSession.SG("messageForm");
if (id != null && id.substring(id.indexOf(":")+1).equals("always"))
{
Properties user_stat = ((Properties)thisSession.user_info.get("stat"));
if (user_stat.get("messages") == null) user_stat.put("messages",new Properties());
Properties messages = (Properties)user_stat.get("messages");
messages.remove(id.substring(0,id.indexOf(":")));
}
}
catch(Exception e)
{
}
}
if (!skip_refresh)
{
if (p.getProperty("referer","/").equals("") || p.getProperty("referer","/").toUpperCase().indexOf("LOGIN.HTML") >= 0) sendRedirect("/",headers);
else sendRedirect(p.getProperty("referer","/"),headers);
write_command_http("Set-Cookie: referer=; path=/");
write_command_http("");
done = true;
thisSession.uVFS = null;
return;
}
}
//EMAILPASSWORD
else if (p.getProperty("the_action","").toUpperCase().startsWith("EMAILPASSWORD"))
{
String lookupUsername = p.getProperty("username");
Properties lookupUser = common_code.read_user(thisSession.uiSG("listen_ip_port"),lookupUsername);
String result = "";
if (lookupUser.getProperty("site","").toUpperCase().indexOf("(SITE_EMAILPASSWORD)") >= 0)
{
String pass = lookupUser.getProperty("password","");
if (pass.startsWith("SHA:") || pass.startsWith("CRYPT3:")) pass = LOC.G("(Your password is encrypted and cannot be revealed. Please contact your server administrator to have it reset.)");
else pass = common_code.decode_pass(pass);
String to = lookupUser.getProperty("email","");
String from = to;
if (thisSession.server_status_frame.SG("smtp_server").equals(""))
{
result = LOC.G("This server is not configured to send email password reminders.");
}
else if (!to.equals(""))
{
result = common_code.send_mail(thisSession.server_status_frame.SG("discovered_ip"),to,"","", from, LOC.G("CrushFTP Password Reminder"), LOC.G("Your password is : ")+pass+"\r\n\r\n"+LOC.G("Requested from IP:")+thisSession.uiSG("user_ip"), thisSession.server_status_frame.SG("smtp_server"), thisSession.server_status_frame.SG("smtp_user"), thisSession.server_status_frame.SG("smtp_pass"), thisSession.server_status_frame.SG("smtp_ssl").equals("true"));
thisSession.add_log_formatted(LOC.G("Password Emailed to user:")+lookupUsername+" "+to+" "+LOC.G("Email Result:") + result,"POST");
if (result.toUpperCase().indexOf("ERROR") >= 0) result = LOC.G("An error occured when generating the email.");
else result = LOC.G("An email was just sent to the email address associated with your username.");
}
else
{
result = LOC.G("Your username does not have an email specified in its account.");
}
}
else
{
result = LOC.G("Your username does not allow you to have your password emailed to you.");
}
write_command_http("HTTP/1.1 200 OK");
write_command_http("Pragma: no-cache");
write_command_http("Content-Type: text/html;charset=utf-8");
write_standard_headers();
write_command_http("Content-Length: "+(result.length()+2));
write_command_http("");
write_command_http(result);
return;
}
//LOGOUT
else if (p.getProperty("the_action","").toUpperCase().startsWith("LOGOUT"))
{
done = true;
kill_all = true;
String sessionid = thisSession.uiSG("CrushAuth");
globalSessions.remove(thisSession.uiSG("user_ip")+"_"+sessionid+"_user");
globalSessions.remove(thisSession.uiSG("user_ip")+"_"+sessionid+"_pass");
sendRedirect("/WebInterface/login.html",headers);
write_command_http("Connection: close");
write_command_http("Set-Cookie: CrushAuth=; path=/");
thisSession.uiPUT("CrushAuth","");
write_command_http("");
kill_all = true;
done = true;
thisSession.uVFS = null;
return;
}
//MESSAGECONFIRM
else if (p.getProperty("the_action","").toUpperCase().startsWith("MESSAGECONFIRM"))
{
String messageId = p.getProperty("MessageFormId","");
Properties user_stat = ((Properties)thisSession.user_info.get("stat"));
if (user_stat.get("messages") == null) user_stat.put("messages",new Properties());
Properties messages = (Properties)user_stat.get("messages");
if (messageId.length() > 0) messages.put(messageId,p);
if (!skip_refresh)
{
if (p.getProperty("referer","/").equals("")) sendRedirect("/",headers);
else sendRedirect(p.getProperty("referer","/"),headers);
write_command_http("Set-Cookie: referer=; path=/");
write_command_http("Connection: close");
write_command_http("");
done = true;
return;
}
}
//REFRESH
else if (p.getProperty("the_action","").toUpperCase().startsWith("REFRESH"))
{
if (!skip_refresh)
{
String current_dir = thisSession.uiSG("current_dir");
if (current_dir.startsWith(thisSession.SG("root_dir"))) current_dir = current_dir.substring(thisSession.SG("root_dir").length());
if (!current_dir.startsWith("/")) current_dir = "/"+current_dir;
sendRedirect(current_dir,headers);
write_command_http("Set-Cookie: referer=; path=/");
write_command_http("Connection: close");
write_command_http("");
done = true;
return;
}
}
//QUICKLIST
else if (p.getProperty("the_action","").toUpperCase().startsWith("QUICKLIST"))
{
//just accept the post and give a quick list
if (thisSession == null || thisSession.user == null) return;
String curInterface = thisSession.SG("webInterfaceTemplate");
thisSession.user.put("webInterfaceTemplate","/WebInterface/quicklist.xsl");
doServeDir(headersOnly,error_message,null,headers,ifnonematch,true,true);
thisSession.user.put("webInterfaceTemplate",curInterface);
return;
}
//DELE
else if (p.getProperty("the_action","").toUpperCase().startsWith("DELE "))
{
String item_name = p.getProperty("the_action",""); item_name = item_name.substring(item_name.indexOf(" ")+1);
thisSession.uiPUT("the_command","DELE");
String itemList[] = item_name.split(":");
for (int itemLoop=0; itemLoop<itemList.length; itemLoop++)
{
if (itemList[itemLoop].length() > 0)
{
thisSession.uiPUT("the_command_data",itemList[itemLoop]);
String msg = thisSession.do_DELE(true);
error_message += msg.equals("")?"":itemList[itemLoop]+":"+msg;
thisSession.uVFS.reset();
}
}
}
//MKD
else if (p.getProperty("the_action","").toUpperCase().startsWith("MKD "))
{
String item_name = p.getProperty("the_action",""); item_name = item_name.substring(item_name.indexOf(" ")+1);
thisSession.uiPUT("the_command","MKD");
thisSession.uiPUT("the_command_data",item_name.trim());
error_message += thisSession.do_MKD(false);
thisSession.uVFS.reset();
}
//MDTM
else if (p.getProperty("the_action","").toUpperCase().startsWith("MDTM "))
{
String item_data = p.getProperty("the_action",""); item_data = item_data.substring(item_data.indexOf(" ")+1);
thisSession.uiPUT("the_command","MDTM");
thisSession.uiPUT("the_command_data",item_data.trim());
error_message += thisSession.do_MDTM();
thisSession.uVFS.reset();
}
//RNFR RNTO
else if (p.getProperty("the_action","").toUpperCase().startsWith("RNFR "))
{
String item_name = p.getProperty("the_action",""); item_name = item_name.substring(item_name.indexOf(" ")+1,item_name.indexOf(":"));
thisSession.uiPUT("the_command","RNFR");
thisSession.uiPUT("the_command_data",item_name);
error_message += thisSession.do_RNFR();
if (error_message.equals(""))
{
String item_name2 = p.getProperty("the_action",""); item_name2 = item_name2.substring(item_name2.indexOf(":RNTO ")+6);
thisSession.uiPUT("the_command","RNTO");
thisSession.uiPUT("the_command_data",item_name2);
if (!item_name.equals(item_name2))
{
error_message += thisSession.do_RNTO(false);
thisSession.uVFS.reset();
}
}
}
//USEROPTIONS
else if (p.getProperty("the_action","").toUpperCase().equalsIgnoreCase("USEROPTIONS"))
{
if (thisSession.SG("site").indexOf("(SITE_PASS)") >= 0)
{
String current_password = p.getProperty("current_password","");
String new_password1 = p.getProperty("new_password1","");
String new_password2 = p.getProperty("new_password2","");
if (current_password.length() > 0 && new_password1.length() > 0)
{
if (current_password.equals(thisSession.uiSG("current_password")) && new_password1.equals(new_password2) && !thisSession.uiSG("user_name").equalsIgnoreCase("anonymous"))
{
thisSession.do_ChangePass(thisSession.uiSG("user_name"),new_password1);
error_message+=LOC.G("Password updated.");
}
else if (!current_password.equals(thisSession.uiSG("current_password")))
{
error_message+=LOC.G("You did not enter the correct current password.");
}
else if (!new_password1.equals(new_password2))
{
error_message+=LOC.G("You did not enter the same password for verification the second time.");
}
}
}
}
//SEARCH
else if (p.getProperty("the_action","").toUpperCase().equalsIgnoreCase("SEARCH"))
{
boolean name1 = p.getProperty("name1","").equalsIgnoreCase("on");
String name1_action = p.getProperty("name1_action","");
String name1_value = p.getProperty("name1_value","");
boolean name2 = p.getProperty("name2","").equalsIgnoreCase("on");
String name2_action = p.getProperty("name2_action","");
String name2_value = p.getProperty("name2_value","");
boolean date1 = p.getProperty("date1","").equalsIgnoreCase("on");
String date1_action = p.getProperty("date1_action","");
String date1_value = p.getProperty("date1_value","");
boolean date2 = p.getProperty("date2","").equalsIgnoreCase("on");
String date2_action = p.getProperty("date2_action","");
String date2_value = p.getProperty("date2_value","");
boolean size1 = p.getProperty("size1","").equalsIgnoreCase("on");
String size1_action = p.getProperty("size1_action","");
String size1_value = p.getProperty("size1_value","");
boolean type1 = p.getProperty("type1","").equalsIgnoreCase("on");
String type1_action = p.getProperty("type1_action","");
boolean meta1 = p.getProperty("meta1","").equalsIgnoreCase("on");
String meta1_value = p.getProperty("meta1_value","");
Vector metas = new Vector();
if (meta1) metas = thisSession.server_status_frame.getMetchingMetas(meta1_value,thisSession.server_item);
thisSession.uiPUT("the_command","LIST");
thisSession.uiPUT("the_command_data",name1);
Vector listing = new Vector();
Properties status = new Properties();
class Lister implements Runnable
{
Vector listing = null;
Properties status = null;
public Lister(Vector listing, Properties status)
{
this.listing = listing;
this.status = status;
}
public void run()
{
status.put("done","false");
try{thisSession.uVFS.getListing(listing,thisSession.uiSG("current_dir"),20,1000,false,true);}catch(Exception e){}
status.put("done","true");
}
}
new Thread(new Lister(listing,status)).start();
Vector foundItems = new Vector();
SimpleDateFormat mmddyyyy = new SimpleDateFormat("MM/dd/yyyy");
while (listing.size() == 0) Thread.sleep(100);
long processedCount = 0;
while (status.getProperty("done","false").equalsIgnoreCase("false") || listing.size() > 0)
{
while(status.getProperty("done","false").equalsIgnoreCase("false") && listing.size() == 0) Thread.sleep(100);
if (listing.size() == 0) break;
Properties pp = (Properties)listing.elementAt(0);
listing.removeElementAt(0);
processedCount++;
System.getProperties().put("crushftp.activeSearch.info"+thisSession.uiSG("CrushAuth"),"Searched "+processedCount+" items.");
try
{
if (pp.getProperty("privs","").indexOf("(read)") < 0 || pp.getProperty("privs","").indexOf("(invisible)") >= 0 || pp.getProperty("privs","").indexOf("(view)") < 0)
{
//hidden item
}
else
{
boolean name_ok = true;
boolean date_ok = true;
boolean size_ok = true;
boolean type_ok = true;
boolean meta_ok = true;
if (name1)
{
if (name1_action.equalsIgnoreCase("contains") && pp.getProperty("name").toUpperCase().indexOf(name1_value.toUpperCase()) < 0) name_ok = false;
if (name1_action.equalsIgnoreCase("starts with") && !pp.getProperty("name").toUpperCase().startsWith(name1_value.toUpperCase())) name_ok = false;
if (name1_action.equalsIgnoreCase("ends with") && !pp.getProperty("name").toUpperCase().endsWith(name1_value.toUpperCase())) name_ok = false;
}
if (name2)
{
if (name2_action.equalsIgnoreCase("contains") && pp.getProperty("name").toUpperCase().indexOf(name2_value.toUpperCase()) < 0) name_ok = false;
if (name2_action.equalsIgnoreCase("starts with") && !pp.getProperty("name").toUpperCase().startsWith(name2_value.toUpperCase())) name_ok = false;
if (name2_action.equalsIgnoreCase("ends with") && !pp.getProperty("name").toUpperCase().endsWith(name2_value.toUpperCase())) name_ok = false;
}
if (date1)
{
long modified1 = Long.parseLong(pp.getProperty("modified"));
long modified2 = mmddyyyy.parse(date1_value).getTime();
if (date1_action.equalsIgnoreCase("before") && modified2 <= modified1) date_ok = false;
else if (date1_action.equalsIgnoreCase("after") && modified2 >= modified1) date_ok = false;
}
if (date2)
{
long modified1 = Long.parseLong(pp.getProperty("modified"));
long modified2 = mmddyyyy.parse(date2_value).getTime();
if (date2_action.equalsIgnoreCase("before") && modified2 <= modified1) date_ok = false;
else if (date2_action.equalsIgnoreCase("after") && modified2 >= modified1) date_ok = false;
}
if (size1)
{
long file_size1 = Long.parseLong(pp.getProperty("size"));
long file_size2 = Long.parseLong(size1_value)*1024;//kilobytes
if (size1_action.equalsIgnoreCase("bigger than") && file_size2 >= file_size1) size_ok = false;
else if (size1_action.equalsIgnoreCase("smaller than") && file_size2 <= file_size1) size_ok = false;
}
if (type1)
{
String item_type1 = pp.getProperty("type");
if (type1_action.equalsIgnoreCase("file") && !item_type1.equalsIgnoreCase("file")) type_ok = false;
else if (type1_action.equalsIgnoreCase("folder") && !item_type1.equalsIgnoreCase("dir")) type_ok = false;
}
if (meta1)
{
meta_ok = false;
for (int x=0; x<metas.size(); x++)
{
Properties meta_item = (Properties)metas.elementAt(x);
if (meta_item.getProperty("url","").toUpperCase().equals(pp.getProperty("url").toUpperCase()))
{
pp.put("metaInfo",meta_item.get("metaInfo"));
meta_ok = true;
}
}
}
if (name_ok && date_ok && size_ok && type_ok && meta_ok)
{
foundItems.addElement(pp);
String privs = pp.getProperty("privs","");
if (privs.indexOf("(comment") >= 0)
{
privs = privs.substring(0,privs.indexOf("(comment"))+privs.substring(privs.indexOf(")",privs.indexOf("(comment")));
}
privs = Common.replace_str(privs,"(inherited)","");
String current_dir2 = pp.getProperty("root_dir");
if (current_dir2.toUpperCase().startsWith(thisSession.SG("root_dir").toUpperCase())) current_dir2 = current_dir2.substring(thisSession.SG("root_dir").length()-1);
pp.put("privs",privs + "(comment"+Common.url_encode(LOC.G("Containing Folder")+":<a href='"+current_dir2+"'>"+current_dir2+"</a>")+")");
}
}
}
catch(Exception e)
{
Common.debug(1,e);
}
}
System.getProperties().remove("crushftp.activeSearch.info"+thisSession.uiSG("CrushAuth"));
doServeDir(headersOnly,error_message,foundItems,headers,ifnonematch,true,false);
}
//SIZE -- used in Browser upload to get status of upload
else if (p.getProperty("the_action","").toUpperCase().startsWith("SIZE"))
{
write_command_http("HTTP/1.1 200 OK");
write_command_http("Pragma: no-cache");
write_command_http("Content-Type: text/html;charset=utf-8");
write_standard_headers();
//thisSession.uiSG("current_dir");
String sizeInfo = "";
if (!System.getProperties().getProperty("crushftp.activeUpload.info"+thisSession.uiSG("CrushAuth"),"").equals(""))
{
sizeInfo = System.getProperties().getProperty("crushftp.activeUpload.info"+thisSession.uiSG("CrushAuth"),"");
}
write_command_http("Content-Length: "+(sizeInfo.length()+2));
write_command_http("");
write_command_http(sizeInfo);
return;
}
//SEARCHPROGRESS -- used in Browser upload to get status of upload
else if (p.getProperty("the_action","").toUpperCase().startsWith("SEARCHPROGRESS"))
{
write_command_http("HTTP/1.1 200 OK");
write_command_http("Pragma: no-cache");
write_command_http("Content-Type: text/html;charset=utf-8");
write_standard_headers();
//thisSession.uiSG("current_dir");
String searchInfo = "";
if (!System.getProperties().getProperty("crushftp.activeSearch.info"+thisSession.uiSG("CrushAuth"),"").equals(""))
{
searchInfo = System.getProperties().getProperty("crushftp.activeSearch.info"+thisSession.uiSG("CrushAuth"),"");
}
write_command_http("Content-Length: "+(searchInfo.length()+2));
write_command_http("");
write_command_http(searchInfo);
return;
}
//.ZIP
else if (p.getProperty("the_action","").toUpperCase().startsWith("ZIP "))
{
write_command_http("HTTP/1.1 200 OK");
int validSecs = 30;
write_command_http("Cache-Control: post-check="+validSecs+",pre-check="+(validSecs*10));
//write_command_http("Pragma: no-cache"); not allowed or IE 6 can't download in HTTPS
write_command_http("Content-Type: application/zip");
write_standard_headers();
String item_name = p.getProperty("the_action",""); item_name = item_name.substring(item_name.indexOf(" ")+1);
thisSession.uiPUT("the_command","RETR");
String itemList[] = item_name.split(":");
String current_dir = thisSession.uiSG("current_dir");
Properties item = thisSession.uVFS.get_item(thisSession.uiSG("current_dir"));
if(item == null) item = new Properties();
int max = itemList.length;
if (max > 100) max = 100;//prevent DOS by only allowing 100 threads max to be started.
for (int itemLoop=0; itemLoop<max; itemLoop++)
{
if (itemList[itemLoop].length() > 0)
{
String current_dir2 = itemList[itemLoop];
if (!current_dir2.toUpperCase().startsWith(thisSession.SG("root_dir"))) current_dir2 = thisSession.SG("root_dir") + current_dir2.substring(1);
thisSession.uiPUT("current_dir",current_dir2);
if (thisSession.check_access_privs(thisSession.uiSG("current_dir"), "RETR"))
{
common_code.startMultiThreadZipper(thisSession.uVFS, retr,thisSession.uiSG("current_dir"),0);
}
}
}
Thread.sleep(2000);//give time for zipping threads to start
otherFile = new VFS_URL(item,thisSession.uVFS);
thisSession.uiPUT("current_dir",current_dir);
String fname = "archive.zip";
if (itemList.length == 1) fname = itemList[0]+".zip";
if (p.getProperty("item1","").length() > 0) fname = p.getProperty("item1","");
write_command_http("Content-Disposition: attachment; filename=\""+fname+"\"");
write_command_http("Connection: close");
write_command_http("");
done = true;
thisSession.uiPUT("file_transfer_mode","BINARY");
retr.data_os = original_os;
retr.httpDownload = true;
String the_dir = thisSession.uiSG("current_dir");
//allow a plugin to alter the logged file name in case it may have altered the incoming the_command_data
Properties pp = new Properties();
pp.put("the_dir",the_dir);
thisSession.runPlugin("transfer_path", pp);
the_dir = pp.getProperty("the_dir",the_dir);
retr.init_vars(the_dir, thisSession.uiLG("start_resume_loc"), -1, thisSession, item, false, "", otherFile);
retr.runOnce = true;
retr.run();
return;
}
}
//if a file wasn't uploaded, refresh dir.
for (int x=0; x<items.size(); x++)
{
Properties pp = (Properties)items.elementAt(x);
if (pp.getProperty("type","").equals("file"))
{
skip_refresh = true;
}
}
error_message += p.getProperty("callback","");
if (skip_refresh)
{
String s = error_message;
if (s.length() == 0) s = "~~~OK~~~";
write_command_http("HTTP/1.1 200 OK");
write_command_http("Pragma: no-cache");
write_standard_headers();
write_command_http("Content-Type: text/html;charset=utf-8");
write_command_http("Content-Length: "+write_command_http_size(s));
write_command_http("");
write_command_http(s);
}
else doServeDir(headersOnly,error_message, null,headers,ifnonematch,false,false);
}
else if (action.equals("serve dir") || action.equals("serve empty dir"))
{
doServeDir(headersOnly,error_message,null,headers,ifnonematch,false,false);
}
else if (action.equals("serve file"))
{
doServeFile(otherFile, headers, ifnonematch, headersOnly, forceFileName);
}
}
}//end handle_http_requests
public void doServeFile(VFS_URL otherFile, Vector headers, String ifnonematch, boolean headersOnly, boolean forceFileName) throws Exception
{
if (thisSession.uiSG("current_dir").indexOf("webdav-method=TRUTHGET") >= 0)
{
otherFile = new VFS_URL("file:///Library/Application Support/NotMac/truthget.txt",null);
}
if (otherFile == null)
{
if (thisSession.uiSG("current_dir").equals(thisSession.SG("root_dir") + "StartCrushFTPAdminSession.bin") && headers.elementAt(0).toString().startsWith("GET ") && thisSession.SG("site").indexOf("(CONNECT)") >= 0)
{
write_command_http("HTTP/1.1 200 OK");
write_command_http("Pragma: no-cache");
write_standard_headers();
write_command_http("Connection: close");
write_command_http("");
thisSession.data_sock = sock;
thisSession.uiPUT("current_user",thisSession.uiSG("user_name"));
thisSession.do_remote_admin_output();
sock = null;
original_os = null;
original_is = null;
done = true;
return;
}
else
{
boolean ok1 = thisSession.check_access_privs(Common.all_but_last(thisSession.uiSG("current_dir")), "RETR") && Common.filter_check("U", Common.last(thisSession.uiSG("current_dir")), server_status_frame.SG("filename_filters_str"));
boolean ok2 = thisSession.check_access_privs(thisSession.uiSG("current_dir"), "RETR") && Common.filter_check("U", Common.last(thisSession.uiSG("current_dir")), server_status_frame.SG("filename_filters_str"));
if (ok1 || ok2) write_command_http("HTTP/1.1 404 Not Found");
else write_command_http("HTTP/1.1 403 Access Denied.");
write_command_http("Content-Length: 0");
write_command_http("");
}
}
else
{
updateMimes();
String ext = "";
if (otherFile.toString().lastIndexOf(".") >= 0) ext = otherFile.toString().substring(otherFile.toString().lastIndexOf(".")).toUpperCase();
if (mimes.getProperty(ext,"").equals("")) ext = "*";
Properties item = thisSession.uVFS.get_item(thisSession.uiSG("current_dir"));
if(item == null) item = new Properties();
String htmlData = "";
if ((mimes.getProperty(ext,"").toUpperCase().endsWith("/HTML") || mimes.getProperty(ext,"").toUpperCase().endsWith("/X-JAVA-JNLP-FILE")) && (otherFile.toString().indexOf("/WebInterface/") >= 0 || thisSession.uiSG("current_dir").toUpperCase().startsWith("/WEBINTERFACE/") || thisSession.BG("WebServerSSI")))
{
String current_dir = thisSession.uiSG("current_dir");
if (current_dir.startsWith(thisSession.SG("root_dir"))) current_dir = current_dir.substring(thisSession.SG("root_dir").length());
if (!current_dir.startsWith("/")) current_dir = "/"+current_dir;
VFS_URL url = otherFile;
url.getInputStream();
byte b[] = new byte[bufferSize];
htmlData = "";
int bytesRead = 0;
while (bytesRead >= 0)
{
bytesRead = url.read(b);
if (bytesRead > 0) htmlData += new String(b,0,bytesRead);
}
url.close();
if (otherFile.getName().equalsIgnoreCase("login.html"))
{
if (!server_status_frame.SG("default_logo").equals("") && !server_status_frame.SG("default_logo").equalsIgnoreCase("logo.gif"))
{
htmlData = Common.replace_str(htmlData,"logo.gif",server_status_frame.SG("default_logo"));
}
}
else if (otherFile.getName().equalsIgnoreCase("crushftp.jnlp"))
{
htmlData = server_status_frame.change_vars_to_values(htmlData,thisSession);
htmlData = Common.replace_str(htmlData, "%base_url%", getBaseUrl(headers));
}
else if (otherFile.getName().toUpperCase().endsWith(".EXIF"))
{
Common.debug(2,otherFile.getFile().toURL().toString());
htmlData = common_code.readXMLDocumentAndConvert(otherFile.getFile().toURL(),"/WebInterface/exif.xsl");
if (htmlData == null) htmlData = "";
}
if (thisSession.BG("WebServerSSI"))
{
int depth = 0;
while (htmlData.toUpperCase().indexOf("<!--#INCLUDE") >= 0)
{
int loc = htmlData.toUpperCase().indexOf("<!--#INCLUDE");
int loc2 = htmlData.indexOf("\"",loc)+1;
String importFilename = htmlData.substring(loc2,htmlData.indexOf("\"",loc2+2));
Properties importItem = null;
if (importFilename.startsWith("/"))
{
if (!importFilename.startsWith(thisSession.SG("root_dir"))) importFilename = thisSession.SG("root_dir") + importFilename.substring(1);
importItem = thisSession.uVFS.get_item(importFilename);
}
else
{
String the_dir = current_dir;
if (!the_dir.endsWith("/")) the_dir = Common.all_but_last(the_dir);
importFilename = the_dir+importFilename;
if (!importFilename.startsWith(thisSession.SG("root_dir"))) importFilename = thisSession.SG("root_dir") + importFilename.substring(1);
importItem = thisSession.uVFS.get_item(importFilename);
}
String importHtml = "";
if (importItem != null)
{
VFS_URL importUrl = new VFS_URL(importItem,thisSession.uVFS);
importUrl.getInputStream();
bytesRead = 0;
while (bytesRead >= 0)
{
bytesRead = importUrl.read(b);
if (bytesRead > 0) importHtml += new String(b,0,bytesRead);
}
importUrl.close();
}
String replacer = htmlData.substring(loc,htmlData.indexOf("-->",loc)+3);
htmlData = Common.replace_str(htmlData,replacer,importHtml);
if (depth++ > 100) break;
}
}
}
long checkDate = new Date().getTime();
try{checkDate = Long.parseLong(ifnonematch);}catch(Exception e){}
boolean checkOK = false;
if(checkDate > 0 && checkDate >= otherFile.getLastModified() && !headersOnly) checkOK = true;
else if(checkDate > 0 && !headersOnly)//test for offset of exact match by a 24 hour range
{
checkDate -= 1000*60*60*24;//negative 24 hours first
for (int x=0; x<=48; x++)
{
if(checkDate == otherFile.getLastModified()){checkOK = true;break;}
checkDate += (1000*60*60);//1 hour
}
}
if(checkOK)
{
int validSecs = 30;
if (otherFile.getPath().toUpperCase().indexOf("/WEBINTERFACE/") >= 0 || thisSession.BG("WebServerMode"))
{
if (otherFile.getName().toUpperCase().endsWith(".GIF") || otherFile.getName().toUpperCase().endsWith(".PNG") || otherFile.getName().toUpperCase().endsWith(".JPG") || otherFile.getName().toUpperCase().endsWith(".CSS") || otherFile.getName().toUpperCase().endsWith(".XSL") || otherFile.getName().toUpperCase().endsWith(".JS") || otherFile.getName().toUpperCase().endsWith(".ICO") || otherFile.getName().toUpperCase().endsWith(".HTML"))
{
validSecs = 3000;
}
}
write_command_http("HTTP/1.1 304 Not Modified");
write_standard_headers();
write_command_http("Cache-Control: post-check="+validSecs+",pre-check="+(validSecs*10));
if (cacheHeader.length() > 0){write_command_http(cacheHeader);cacheHeader = "";}
write_command_http("Last-Modified: " + lastModifiedSDF.format(new Date(otherFile.getLastModified())));
write_command_http("ETag: "+otherFile.getLastModified()+"");
write_command_http("Content-Length: 0");
write_command_http("");
}
else
{
Vector byteRanges = thisSession.uiVG("byteRanges");
if (byteRanges.size() > 0 && htmlData.length() == 0) write_command_http("HTTP/1.1 206 Partial Content");
else write_command_http("HTTP/1.1 200 OK");
write_standard_headers();
String byteRangeBoundary = Common.makeBoundary();
String contentType = mimes.getProperty(ext,"");
if (byteRanges.size() <= 1) write_command_http("Content-Type: " + contentType);
else if (byteRanges.size() > 1) write_command_http("Content-Type: multipart/byteranges; boundary="+byteRangeBoundary);
if (cacheHeader.length() > 0){write_command_http(cacheHeader);cacheHeader = "";}
write_command_http("Last-Modified: " + lastModifiedSDF.format(new Date(otherFile.getLastModified())));
write_command_http("ETag: "+otherFile.getLastModified()+"");
if (headersOnly) //don't cache header info since we might be using ajax to check progress
{
write_command_http("Pragma: no-cache"); //this is not allowed or IE 6 will not save files when using HTTPS
}
boolean quickWrite = false;
if (htmlData.length() > 0) quickWrite = true;
//populate the real size of the file when none was specified in the byte range header
String amountEnd = otherFile.length()+"";
for (int x=0; x<byteRanges.size(); x++)
{
Properties p = (Properties)byteRanges.elementAt(x);
if (p.getProperty("end","").equals("")) p.put("end",amountEnd);
}
if (!otherFile.exists() && otherFile.getName().toUpperCase().endsWith(".ZIP"))
{
common_code.startMultiThreadZipper(thisSession.uVFS, retr,thisSession.uiSG("current_dir"),2000);
write_command_http("Connection: close");
done = true;
}
else
{
long content_length = 0;
try{content_length = otherFile.length();}catch(Exception e){}
if (byteRanges.size() == 1)
{
Properties p = (Properties)byteRanges.elementAt(0);
write_command_http("Content-Range: "+p.getProperty("start")+"-"+p.getProperty("end")+"/"+content_length);
write_command_http("Content-Length: "+(htmlData.length()>0?(htmlData.length()+2):Long.parseLong(p.getProperty("end"))-Long.parseLong(p.getProperty("start"))));
}
else if (byteRanges.size() <= 1)
{
write_command_http("Content-Length: "+(htmlData.length()>0?(htmlData.length()+2):content_length));
}
else if (byteRanges.size() > 1)
{
long calculatedContentLength = 2;
for (int x=0; x<byteRanges.size(); x++)
{
Properties p = (Properties)byteRanges.elementAt(x);
calculatedContentLength += ("--"+byteRangeBoundary).length()+2;
calculatedContentLength += ("Content-Type: "+contentType).length()+2;
calculatedContentLength += ("Content-range: bytes "+p.getProperty("start")+"-"+p.getProperty("end")+"/"+content_length).length()+2;
calculatedContentLength += 2;
calculatedContentLength += Long.parseLong(p.getProperty("end")) - Long.parseLong(p.getProperty("start"));
calculatedContentLength += 2;
}
calculatedContentLength += ("--"+byteRangeBoundary+"--").length()+2;
write_command_http("Content-Length: "+calculatedContentLength);
}
write_command_http("Accept-Ranges: bytes");
}
if (forceFileName) write_command_http("Content-Disposition: attachment; filename=\""+otherFile.getName()+"\"");
write_command_http("");
if (byteRanges.size() == 0)
{
Properties p = new Properties();
p.put("start","0");
p.put("end","-1");
byteRanges.addElement(p);
}
long content_length = 0;
try{content_length = otherFile.length();}catch(Exception e){}
for (int x=0; x<byteRanges.size(); x++)
{
Properties p = (Properties)byteRanges.elementAt(x);
if (!headersOnly)
{
if (quickWrite) write_command_http(htmlData);
else
{
if (byteRanges.size() > 1)//ADOBE PDF plugin does this on XP's IE
{
if (x == 0) write_command_http("");
write_command_http("--"+byteRangeBoundary);
write_command_http("Content-Type: "+contentType);
write_command_http("Content-range: bytes "+p.getProperty("start")+"-"+p.getProperty("end")+"/"+content_length);
write_command_http("");
}
thisSession.uiPUT("file_transfer_mode","BINARY");
retr.data_os = original_os;
retr.httpDownload = true;
String the_dir = thisSession.uiSG("current_dir");
//allow a plugin to alter the logged file name in case it may have altered the incoming the_command_data
Properties pp = new Properties();
pp.put("the_dir",the_dir);
thisSession.runPlugin("transfer_path", pp);
the_dir = pp.getProperty("the_dir",the_dir);
retr.init_vars(the_dir, Long.parseLong(p.getProperty("start")), Long.parseLong(p.getProperty("end"))+1, thisSession, item, false, "", otherFile);
retr.runOnce = true;
retr.run();
if (byteRanges.size() > 1) write_command_http("");
}
}
}
if (byteRanges.size() > 1) write_command_http("--"+byteRangeBoundary+"--");
}
}
}
public void doServeDir(boolean headersOnly, String error_message, Vector listing, Vector headers, String ifnonematch, boolean closeConnection, boolean forceHTML) throws Exception
{
Properties item = thisSession.uVFS.get_item(thisSession.uiSG("current_dir"));
if(item == null)
{
DEAUTH();
return;
}
if (thisSession.BG("WebServerMode"))
{
Vector v = new Vector();
thisSession.uVFS.getListing(v,thisSession.uiSG("current_dir"), false);
for (int x=0; x<v.size(); x++)
{
Properties p = (Properties)v.elementAt(x);
if (p.getProperty("name").toUpperCase().equals("INDEX.HTML") ||
p.getProperty("name").toUpperCase().equals("INDEX.HTM"))
{
VFS_URL otherFile = new VFS_URL(p,thisSession.uVFS);
doServeFile(otherFile, headers, ifnonematch, false, false);
return;
}
}
}
if (thisSession.BG("DisallowListingDirectories"))
{
String msg = LOC.G("<html><body><h1>Directory listing not allowed.</h1><br/>You're not allowed to view this folder..</body></html>");
write_command_http("HTTP/1.1 403 Not Found");
write_command_http("Pragma: no-cache");
write_command_http("Connection: close");
write_command_http("Content-Length: "+(msg.length()+2));
write_command_http("");
write_command_http(msg);
return;
}
write_command_http("HTTP/1.1 200 OK");
write_command_http("Pragma: no-cache");
write_standard_headers();
String outputMode = "xml";
outputMode = thisSession.server_item.getProperty("httpFormat","HTML").toLowerCase();
if (forceHTML) outputMode = "html";
write_command_http("Content-Type: text/"+outputMode+";charset=utf-8");
String content = "";
try{content = server_status_frame.get_dir_list_url4_0(outputMode,thisSession.uiSG("user_name"),thisSession.uiSG("current_password"),thisSession.uiSG("listen_ip_port"),thisSession,error_message,item.getProperty("privs",""),proxy, listing);}catch(Exception e){Common.debug(1,e);}
write_command_http("Content-Length: "+(write_command_http_size(content)));
write_command_http("Cache-Control: post-check=1,pre-check=1");
if (closeConnection) write_command_http("Connection: Close");
write_command_http("");
if (!headersOnly)write_command_http(content);
}
public boolean doPutFile(long content_length, boolean connectionClose) throws Exception
{
boolean ok = false;
if (thisSession.check_access_privs(thisSession.uiSG("current_dir"), "STOR") && Common.filter_check("U", Common.last(thisSession.uiSG("current_dir")), server_status_frame.SG("filename_filters_str")))
ok = true;
Properties dir_item = thisSession.uVFS.get_item(thisSession.uiSG("current_dir"));
if (dir_item == null) dir_item = thisSession.uVFS.get_item_parent(thisSession.uiSG("current_dir"));
if (ok)
{
if (stor_Thread == null) stor_Thread = new Thread(stor);
Socket local_s = Common.getSTORSocket(thisSession, stor, stor_Thread, "");
OutputStream of_stream = local_s.getOutputStream();
thisSession.uVFS.reset();
if (content_length > 0 || connectionClose)
{
if (content_length > 0) connectionClose = false;//if we have a content length, use that instead
try
{
byte[] b = new byte[bufferSize];
int bytes_read = 0;
while ((connectionClose || content_length > 0) && bytes_read >= 0)
{
if (!connectionClose && content_length < b.length) b = new byte[(int)content_length];
bytes_read = original_is.read(b);
if (bytes_read > 0)
{
content_length -= bytes_read;
of_stream.write(b,0,bytes_read);
}
}
of_stream.flush();
}
catch(Exception e)
{
Common.debug(1,e);
}
}
try{of_stream.close();}catch(Exception e){}
if (stor.active) {try{while (stor.active) Thread.sleep(100);}catch(Exception e){}}
try{local_s.close();}catch(Exception e){}
}
else//discard data
{
get_raw_http_command((int)content_length);
}
thisSession.uVFS.reset();
if (ok) //allow full access to this file since this session just uploaded it
{
Properties item = thisSession.uVFS.get_item(thisSession.uiSG("current_dir"));
thisSession.accessExceptions.put(thisSession.uiSG("current_dir"),item);
}
return ok;
}
public String doPropFind(Properties commandActions, String depth, boolean listProps, Vector fieldOrder) throws Exception
{
if (!thisSession.uiSG("current_dir").toUpperCase().startsWith(thisSession.SG("root_dir").toUpperCase())) thisSession.uiPUT("current_dir",thisSession.SG("root_dir") + (thisSession.uiSG("current_dir").startsWith("/")?thisSession.uiSG("current_dir").substring(1):thisSession.uiSG("current_dir")));
Element root = new Element("multistatus","DAV:");
Document doc = new Document(root);
Properties item = thisSession.uVFS.get_item(thisSession.uiSG("current_dir"));
if (item == null)
{
return null;
}
else
{
if (item.getProperty("type").toUpperCase().equals("DIR") && !thisSession.uiSG("current_dir").endsWith("/"))
thisSession.uiPUT("current_dir",thisSession.uiSG("current_dir")+"/");
Vector items = new Vector();
if (!depth.equals("0"))
{
if (depth.indexOf("inf")>=0) thisSession.uVFS.getListing(items,thisSession.uiSG("current_dir"),999,10000,false,true);
else if (depth.equals("1")) thisSession.uVFS.getListing(items,thisSession.uiSG("current_dir"));
Properties p = new Properties();
p.put("listing",items);
thisSession.runPlugin("list",p);
}
items.insertElementAt(item,0);
Vector hrefs = new Vector();
boolean listAdditionalProps = false;
for(int x=0; x<items.size(); x++)
{
item = (Properties)items.elementAt(x);
String parentPrivs = thisSession.uVFS.get_item(thisSession.uiSG("current_dir")).getProperty("privs","");
if (item.getProperty("privs").toLowerCase().indexOf("(invisible)") < 0 && parentPrivs.toLowerCase().indexOf("(view)") >= 0)
{
if(item.getProperty("name").startsWith(".") && !item.getProperty("name").equalsIgnoreCase(".VolumeIcon.icns") && items.size() > 1)
{
//invisible items are hidden from listings, but not when queried directly
continue;
}
Element href = new Element("href","D","DAV:");
String dir = thisSession.uiSG("current_dir");
if (!thisSession.SG("root_dir").equals("/")) dir = dir.substring(thisSession.SG("root_dir").length()-1);
if (!depth.equals("0") && x > 0) href.setText(Common.url_encode(dir,"/")+Common.url_encode(item.getProperty("name","")));
else href.setText(Common.url_encode(dir,"/"));
if (depth.indexOf("inf") >= 0)
{
dir = item.getProperty("root_dir");
if (dir.startsWith(SG("root_dir"))) dir = dir.substring(SG("root_dir").length()-1);
href.setText(Common.url_encode(dir,"/")+Common.url_encode(item.getProperty("name","")));
}
if (hrefs.indexOf(href.getText()) < 0)
{
hrefs.addElement(href.getText());
Element response = new Element("response","D", "DAV:");
response.addNamespaceDeclaration(root.getNamespace());
root.addContent(response);
response.addContent(href);
Element propstatGood = new Element("propstat","D","DAV:");
Element propstatBad = new Element("propstat","D","DAV:");
Element propGood = new Element("prop","D","DAV:");
Element propBad = new Element("prop","D","DAV:");
propstatGood.addContent(propGood);
propstatBad.addContent(propBad);
Element error404 = new Element("status","D","DAV:").setText("HTTP/1.1 404 Not Found");
long quota = -12345;
long total_quota = -12345;
try{quota=thisSession.get_quota_used(thisSession.uiSG("current_dir"));}catch(Exception e){}
try{total_quota=thisSession.get_total_quota(thisSession.uiSG("current_dir"));}catch(Exception e){}
if (commandActions.size() == 0)
{
//this is a request to get all supported props, so put them all in
commandActions.put("getcontentlength","");
commandActions.put("getlastmodified","");
commandActions.put("modificationdate","");
fieldOrder.addElement("getcontentlength");
fieldOrder.addElement("getlastmodified");
fieldOrder.addElement("modificationdate");
if (item.getProperty("type").toUpperCase().equals("DIR"))
{
commandActions.put("resourceType","");
fieldOrder.addElement("resourceType");
if (quota != -12345)
{
commandActions.put("quota","");
commandActions.put("quotaused","");
if (fieldOrder.indexOf("quota") < 0) fieldOrder.addElement("quota");
if (fieldOrder.indexOf("quotaused") < 0) fieldOrder.addElement("quotaused");
}
}
listAdditionalProps = true;
}
if (quota == -12345) quota = 0;
if (total_quota == -12345) total_quota = 300*1024*1024;
Enumeration keylist = commandActions.keys();
boolean useGood = false;
boolean useBad = false;
if (listProps)
{
Properties commandActions2 = (Properties)proppatches.get(new VFS_URL(item,thisSession.uVFS).getFile().getCanonicalPath());
if (new VFS_URL(item,thisSession.uVFS).getFile().exists())
{
for (int xx=0; xx<fieldOrder.size(); xx++)
{
String key = fieldOrder.elementAt(xx).toString();
if (commandActions2.containsKey(key))
{
//String val = commandActions2.getProperty(key);
useGood = true;
Element elementKey = new Element(key,"http://www.apple.com/SyncServices");
propGood.addContent(elementKey);
//elementKey.setText(val);
}
}
}
}
else
{
for (int xx=0; xx<fieldOrder.size(); xx++)
{
String key = fieldOrder.elementAt(xx).toString();
if (key.equalsIgnoreCase("getlastmodified"))
{
useGood = true;
Element getlastmodified = new Element(key,"D","DAV:");
propGood.addContent(getlastmodified);
getlastmodified.setText(sdf_rfc1123.format(new Date(Long.parseLong(item.getProperty("modified","0")))));
}
else if (key.equalsIgnoreCase("modificationdate"))
{
useGood = true;
Element getlastmodified = new Element(key,"D","DAV:");
propGood.addContent(getlastmodified);
getlastmodified.setText(sdf_rfc1123_2.format(new Date(Long.parseLong(item.getProperty("modified","0")))));
}
else if (key.equalsIgnoreCase("resourcetype") && item.getProperty("type").toUpperCase().equals("DIR"))
{
useGood = true;
if (item.getProperty("type").toUpperCase().equals("DIR")) propGood.addContent(new Element("resourcetype","D","DAV:").addContent(new Element("collection","D","DAV:")));
else propGood.addContent(new Element("resourcetype","D","DAV:"));
}
else if (key.equalsIgnoreCase("getcontentlength"))
{
if (item.getProperty("type").toUpperCase().equals("DIR"))
{
useBad = true;
propBad.addContent(new Element(key,"D","DAV:"));
if (!propstatBad.isAncestor(error404))propstatBad.addContent(error404);
}
else
{
propGood.addContent(new Element(key,"D","DAV:").setText(item.getProperty("size","0")));
useGood = true;
}
}
else if (key.equalsIgnoreCase("quota"))
{
if (!item.getProperty("type").toUpperCase().equals("DIR"))
{
useBad = true;
propBad.addContent(new Element(key,"D","DAV:"));
if (!propstatBad.isAncestor(error404))propstatBad.addContent(error404);
}
else
{
propGood.addContent(new Element(key,"D","DAV:").setText(((total_quota*2)/1024)+""));
useGood = true;
}
}
else if (key.equalsIgnoreCase("quotaused"))
{
if (!item.getProperty("type").toUpperCase().equals("DIR"))
{
useBad = true;
propBad.addContent(new Element(key,"D","DAV:"));
if (!propstatBad.isAncestor(error404))propstatBad.addContent(error404);
}
else
{
propGood.addContent(new Element(key,"D","DAV:").setText(((quota*2)/1024)+""));
useGood = true;
}
}
else if (key.equalsIgnoreCase("dotunderscore"))
{
propGood.addContent(new Element(key,"A","http://www.apple.com/webdav_fs/props/").setText(""));
useGood = true;
}
else if (key.equalsIgnoreCase("dotunderscore-size"))
{
propGood.addContent(new Element(key,"A","http://www.apple.com/webdav_fs/props/").setText("0"));
useGood = true;
}
else if (key.equalsIgnoreCase("current-user-privilege-set_________________"))
{
// http://www.ietf.org/rfc/rfc3744.txt
Element cups = new Element(key,"P","DAV:");
propGood.addContent(cups);
Element privilege = new Element("privilege","D","DAV:");
privilege.addContent(new Element("read","D","DAV:"));
cups.addContent(privilege);
privilege = new Element("privilege","D","DAV:");
privilege.addContent(new Element("write-internal","I","http://idisk.mac.com/_namespace"));
cups.addContent(privilege);
// privilege = new Element("privilege","D","DAV:");
// privilege.addContent(new Element("manage","I","http://idisk.mac.com/_namespace"));
// cups.addContent(privilege);
/*
if (item.getProperty("privs").indexOf("(read)") >= 0)
{
Element privilege = new Element("privilege","D","DAV:");
privilege.addContent(new Element("read","D","DAV:"));
cups.addContent(privilege);
}
if (item.getProperty("privs").indexOf("(write)") >= 0)
{
Element privilege = new Element("privilege","D","DAV:");
privilege.addContent(new Element("write","D","DAV:"));
cups.addContent(privilege);
}
if (item.getProperty("privs").indexOf("(delete)") >= 0)
{
Element privilege = new Element("privilege","D","DAV:");
privilege.addContent(new Element("delete","D","DAV:"));
cups.addContent(privilege);
}
*/
useGood = true;
}
else
{
useBad = true;
Element empty = new Element(key,"D","DAV:");
propBad.addContent(empty);
if (!propstatBad.isAncestor(error404))propstatBad.addContent(error404);
}
}
if (listAdditionalProps)
{
Properties commandActions2 = (Properties)proppatches.get(new VFS_URL(item,thisSession.uVFS).getFile().getCanonicalPath());
if (commandActions2 != null)
{
Enumeration additionalKeyList = commandActions2.keys();
while(additionalKeyList.hasMoreElements())
{
String key = additionalKeyList.nextElement().toString();
String val = commandActions2.getProperty(key);
useGood = true;
Element elementKey = new Element(key,"X","http://www.apple.com/SyncServices");
propGood.addContent(elementKey);
elementKey.setText(val);
}
}
}
}
if (useGood) propstatGood.addContent(new Element("status","D","DAV:").setText("HTTP/1.1 200 OK"));
if (useGood) response.addContent(propstatGood);
if (useBad && !listAdditionalProps) response.addContent(propstatBad);//we don't list bad props if they were just asking for a list of all good props.
}
}
}
}
if (xmlOut == null)
{
xmlOut = new XMLOutputter();
Format f = Format.getPrettyFormat();
f.setExpandEmptyElements(false);
//f.setIndent("\t");
xmlOut.setFormat(f);
}
return xmlOut.outputString(doc);
}
public Vector get_http_post_items(String boundary, long max_len) throws Exception
{
Properties metaInfo = new Properties();
boolean speedCheat = false; //if we find a specific POST data field item, we know its a single file transfer, and dont' bother checkign for the boundary till near the end.
//it allows us to cheat in a special case scenario and achieve much higher bandwidth with HTTP uploads.
Vector items = new Vector();
Properties item = null;
String data = "";
boolean start_new_item = false;
long len = 4;//for one blank line already read, and 2 more for the ending "--" on the last boundary
boolean dataAlreadyRead = false;
while(true)
{
if (boundary.equals("")) break;
if (!dataAlreadyRead)
{
data = get_http_command();len += data.length()+2;data = data.trim();data = new String(data.getBytes(),"UTF8");data = Common.url_decode(data);
}
dataAlreadyRead = false;
if (data.endsWith(boundary)) start_new_item = true;
if (data.endsWith(boundary+"--")) break;
if (start_new_item)
{
item = new Properties();
items.addElement(item);
data = get_http_command();len += data.length()+2;data = data.trim();data = new String(data.getBytes(),"UTF8");data = Common.url_decode(data);
String name = data.substring(data.indexOf("name=\"")+6,data.indexOf("\"",data.indexOf("name=\"")+6));
if (name.endsWith("_SINGLE_FILE_POST")) speedCheat = true;
if (max_len < (bufferSize * 10)) speedCheat = false;
if (data.indexOf("filename") >= 0)
{
System.getProperties().put("crushftp.activeUpload.info"+thisSession.uiSG("CrushAuth"),"PROGRESS:"+len+"/"+max_len+";");
item.put("type","file");
String upload_item = data.substring(data.indexOf("filename=\"")+10,data.indexOf("\"",data.indexOf("filename=\"")+10));
if (upload_item.indexOf("\\") >= 0) upload_item = upload_item.replace('\\','/');
if (upload_item.indexOf("/") >= 0) upload_item = thisSession.last(upload_item);
Properties p = new Properties();
item.put("file",p);
p.put("filename",upload_item);
data = get_http_command();len += data.length()+2;data = data.trim();data = new String(data.getBytes(),"UTF8");data = Common.url_decode(data);
p.put("encoding",data);
get_http_command();len += 2;//blank line
boolean ok = false;
if (thisSession.check_access_privs(thisSession.uiSG("current_dir")+upload_item, "STOR") && Common.filter_check("U", Common.last(thisSession.uiSG("current_dir")+upload_item), server_status_frame.SG("filename_filters_str")))
{
ok = true;
}
else
{
stor.stop_message = LOC.G("Access denied. (You do not have permission or the file extension is not allowed.)");
System.getProperties().put("crushftp.activeUpload.info"+thisSession.uiSG("CrushAuth"),stor.stop_message);
item.put("callback",stor.stop_message);
}
if (upload_item.equals("")) ok = false;
if (ok)
{
System.getProperties().put("crushftp.activeUpload.info"+thisSession.uiSG("CrushAuth"),"PROGRESS:"+len+"/"+max_len+";");
if (stor_Thread == null) stor_Thread = new Thread(stor);
Socket local_s = Common.getSTORSocket(thisSession, stor, stor_Thread, upload_item);
OutputStream of_stream = local_s.getOutputStream();
try
{
byte buffer[] = new byte[bufferSize*2];
byte boundaryBytes[] = ("\r\n--"+boundary).getBytes();
int len1 = 0;
int len2 = 0;
byte[] b = new byte[bufferSize];
int bytes_read = 0;
original_is.mark(0);
thisSession.uiPPUT("file_length",max_len-len);
while ((speedCheat || findSeparator(boundaryBytes,buffer,len1,len2) < 0) && bytes_read >= 0)
{
System.getProperties().put("crushftp.activeUpload.info"+thisSession.uiSG("CrushAuth"),"PROGRESS:"+len+"/"+max_len+";");
original_is.reset();//go back to the position two reads ago
if (len1 > 0 && len2 > 0)
{
of_stream.write(buffer,0,len1);
len += len1;
original_is.skip(len1);//skip forward past the data that has been written to disk
original_is.mark(b.length*3);//mark it so that two entire reads can be re-read when needed
original_is.skip(len2);//skip forward again to the last read location
System.arraycopy(buffer,bufferSize,buffer,0,len2);len1=len2;
}
else
{
System.arraycopy(buffer,bufferSize,buffer,0,len2);len1=len2;
original_is.mark(b.length*3);//mark it so that two entire reads can be re-read when needed
original_is.skip(bytes_read);//skip forward again to the last read location
}
bytes_read = original_is.read(b);
if (bytes_read > 0){System.arraycopy(b,0,buffer,bufferSize,bytes_read);len2=bytes_read;}
//when we get close to the end of our post, then start checking for the boundary if speedCheat was on.
if (max_len - len < bufferSize*4) speedCheat = false;
}
original_is.reset();//reset it back two reads
int loc = findSeparator(boundaryBytes,buffer,len1,len2);
if (loc < bufferSize)
{
of_stream.write(buffer,0,loc);len += loc;
original_is.skip((long)loc);
}
else
{
of_stream.write(buffer,0,len1);len += len1;
of_stream.write(buffer,bufferSize,loc-bufferSize);len += loc-bufferSize;
original_is.skip((long)loc-bufferSize);
}
}
catch(Exception e)
{
Common.debug(1,e);
keepGoing = false;
done = true;
len = max_len;
}
try{of_stream.close();}catch(Exception e){}
while (stor.active) Thread.sleep(100);
try{stor.v.close();}catch(Exception e){}
local_s.close();
thisSession.uVFS.reset();
if (thisSession.uiPG("lastUploadStat") != null) thisSession.uiPG("lastUploadStat").put("metaInfo",metaInfo);
}
if (stor.stop_message.length() > 0) System.getProperties().put("crushftp.activeUpload.info"+thisSession.uiSG("CrushAuth"),stor.stop_message);
else System.getProperties().remove("crushftp.activeUpload.info"+thisSession.uiSG("CrushAuth"));
}
else
{
item.put("type","text");
data = get_http_command();len += data.length()+2;data = data.trim();data = new String(data.getBytes(),"UTF8");data = Common.url_decode(data);
//read till we hit a boundary
String data_item = "";
dataAlreadyRead = true;
while(true)
{
data = get_http_command();len += data.length()+2;data = data.trim();data = new String(data.getBytes(),"UTF8");data = Common.url_decode(data);
if (data.endsWith(boundary)) break;
if (data.endsWith(boundary+"--")) break;
if (len >= max_len) break;
data_item += data+CRLF;
}
data_item = data_item.substring(0,data_item.length()-2);
item.put(name, data_item);
if (name.toUpperCase().startsWith("META_"))
{
thisSession.add_log_formatted(name.substring(5)+":"+data_item,"POST");
metaInfo.put(name.substring(5),data_item);
}
}
start_new_item = false;
}
if (len >= max_len) break;//this may be off in cases where UTF8 data is sent as the resulting bytes will be less than the original actual bytes
}
return items;
}
protected int findByte(byte value, byte[] buffer, int start_pos, int len1, int len2)
{
int loc = start_pos;
while (loc < len2)
{
if (loc == len1) loc = bufferSize;
if (buffer[loc] == value) return loc;
loc++;
}
return -1;
}
protected int findSeparator(byte[] boundary, byte[] buffer, int len1, int len2)
{
len2+=bufferSize;
int start_pos = 0;
while(start_pos >= 0)
{
int loc = findByte(boundary[0],buffer, start_pos, len1, len2);
start_pos = loc;
if (start_pos >= 0) start_pos++;
if (loc < 0) return -1;
if (loc > len2-boundary.length) return -1;
int boundary_loc = 0;
while(loc < buffer.length)
{
loc++;
if (loc == buffer.length || loc == len2) break;
boundary_loc++;
if (boundary_loc == boundary.length)
{
return loc-boundary.length;
}
if (loc == len1) loc = bufferSize;
if (buffer[loc] != boundary[boundary_loc]) break;
}
}
return -1;
}
public boolean wait_for_bytes() throws Exception
{
boolean result = true;
start_idle_thread();
byte[] aByte = new byte[1];
if (!thisSession.uiBG("secure"))
{
//wait 2 minute for http data, then kill it if nothing has been received.
while(sock.isConnected() && !sock.isInputShutdown() && !sock.isOutputShutdown() && original_is.available() == 0 )
{
original_is.mark(2);
if (original_is.read(aByte) < 0)
{
try{original_is.close();}catch(Exception e){}
result = false;
break;
}
original_is.reset();
Thread.sleep(100);
}
}
stop_idle_thread();
return result;
}
public Vector getHeaders() throws Exception
{
Vector headers = new Vector();
try
{
String headerStr = "";
int bytesRead = 0;
if (wait_for_bytes())
{
start_idle_thread();
original_is.mark(128000);
while (bytesRead >= 0)
{
bytesRead = original_is.read(headerBytes);
if (bytesRead > 0)
{
headerStr += new String(headerBytes,0,bytesRead);
}
if (headerStr.indexOf("\r\n\r\n") >= 0 || headerStr.length() > 128000) break;
}
stop_idle_thread();
}
if (headerStr.equals(""))
{
done = true;
}
else
{
bytesRead = headerStr.indexOf("\r\n\r\n")+4;
original_is.reset();
original_is.skip(bytesRead);
headerStr = headerStr.substring(0,bytesRead).trim();
headerStr = Common.url_decode(headerStr);
BufferedReader bsr = new BufferedReader(new StringReader(headerStr));
String data = "";
if (log != null) log.write(("\r\n\r\n"+Thread.currentThread().getName()+new Date()+"\r\n").getBytes());
while ((data=bsr.readLine()) != null)
{
data = data.trim();
headers.addElement(data);
thisSession.add_log_formatted(data,(data+" ").substring(0,(data+" ").indexOf(" ")));
if (log != null) log.write((Thread.currentThread().getName()+data+"\r\n").getBytes());
}
}
}
catch(Exception e)
{
Common.debug(1,e);
if (headers.size() == 0) done = true;
else throw e;
}
return headers;
}
public String get_raw_http_command(int amount) throws Exception
{
String data = "";
start_idle_thread();
while ((data.indexOf("\r\n") < 0 && amount < 0 && data.length()<bufferSize) || (amount > 0 && data.length()<amount))
{
if (!wait_for_bytes()) return "";
byte[] aByte = new byte[1];
if (amount > 0 && amount-data.length() >= aByte.length) aByte = new byte[bufferSize];
if (amount > 0 && amount-data.length() < aByte.length) aByte = new byte[amount];
int bytesRead = 0;
if (amount < 0)
{
aByte = headerBytes;
original_is.mark(70000);
bytesRead = original_is.read(aByte);
if (bytesRead > 0)
{
String s = new String(aByte,0,bytesRead);
bytesRead = s.indexOf("\r\n")+2;
original_is.reset();
original_is.skip(bytesRead);
}
}
else
{
bytesRead = original_is.read(aByte);
}
if (bytesRead < 0)
{
try{original_is.close();}catch(Exception e){}
stop_idle_thread();
return "";
}
data += new String(aByte,0,bytesRead);
}
thisSession.thread_killer_item.last_activity = new Date().getTime();
stop_idle_thread();
if (log != null) log.write((Thread.currentThread().getName()+data).getBytes());
if (amount >= 0 && log != null) log.write("\r\n\r\n".getBytes());
return data;
}
String direction = "";
public String get_http_command() throws Exception
{
String data = get_raw_http_command(-1);
data = data.trim();
data = server_status_frame.strip_variables(data,thisSession);
//if (!direction.equals("READ")) {direction = "READ"; System.out.println("--------------------------READ----------------------");}System.out.println(data);
return data;
}
public void write_command_raw(String data) throws Exception
{
original_os.write(data.getBytes("UTF8"));
original_os.flush();
thisSession.thread_killer_item.last_activity = new Date().getTime();
if (log != null) log.write((Thread.currentThread().getName()+data).getBytes());
}
public int write_command_http_size(String data) throws Exception
{
data = server_status_frame.change_vars_to_values(data, thisSession);
data += CRLF;
return data.getBytes("UTF8").length;
}
public int write_command_http(String data) throws Exception
{
data = server_status_frame.change_vars_to_values(data, thisSession);
if (!data.toUpperCase().startsWith("<"))
{
thisSession.add_log("[" + thisSession.uiSG("user_number") + ":" + thisSession.uiSG("user_name") + ":" + thisSession.uiSG("user_ip") + "] WROTE: *" + data.trim() + "*", "HTTP");
}
data += CRLF;
write_command_raw(data);
if (writeCookieAuth)
{
String id = new Date().getTime()+"";
globalSessions.put(thisSession.uiSG("user_ip")+"_"+id+"_user",thisSession.uiSG("user_name"));
globalSessions.put(thisSession.uiSG("user_ip")+"_"+id+"_pass",thisSession.uiSG("current_password"));
write_command_raw("Set-Cookie: CrushAuth="+id+"; path=/"+CRLF);
thisSession.uiPUT("CrushAuth",id);//needed to allow XML to work with Safari since it can't access cookies (CrushUpplet)
thisSession.uiPUT("login_date_stamp",id);
writeCookieAuth = false;
}
//if (!direction.equals("WRITE")) {direction = "WRITE"; System.out.println("--------------------------WRITE----------------------");}System.out.print(data);
return data.length();
}
public String SG(String data)
{
return thisSession.SG(data);
}
public void write_standard_headers() throws Exception
{
write_command_http("Server: "+server_header);
write_command_http("x-responding-server: sslngn018");
write_command_http("X-dmUser: "+SG("username"));
write_command_http("Date: " + sdf_rfc1123.format(new Date()));
if (done) write_command_http("Connection: close");
else write_command_http("Connection: Keep-Alive");
}
public void write_standard_headers_1_0() throws Exception
{
write_command_http("Date: " + sdf_rfc1123.format(new Date()));
write_command_http("Server: "+server_header);
write_command_http("Connection: close");
}
public void addSessionCommand(String the_command, String the_command_data)
{
Properties pp = new Properties();
pp.put("the_command",the_command);
pp.put("the_command_data",the_command_data);
pp.put("user_time",server_status_frame.logDateFormat.format(new Date()));
pp.put("display",pp.getProperty("user_time")+" | "+the_command + " " + the_command_data);
pp.put("stamp",new Date().getTime()+"");
thisSession.uiVG("session_commands").addElement(pp);
}
public void DEAUTH() throws Exception
{
write_command_http("HTTP/1.1 401 Unauthorized");
write_command_http("Pragma: no-cache");
write_command_http("Connection: close");
write_command_http("WWW-Authenticate: Basic realm=\""+hostString+"\"");
write_command_http("Content-Type: text/html;charset=utf-8");
write_command_http("Set-Cookie: CrushAuth=credentials; path=/");
thisSession.uiPUT("CrushAuth","credentials");//needed to allow XML to work with Safari since it can't access cookies (CrushUpplet)
write_command_http("Content-Length: "+"Unauthorized".length());
write_command_http("");
write_command_raw("Unauthorized");
thisSession.uVFS = null;
done = true;
}
public void fixRootDir(String domain)
{
try
{
if (thisSession == null || thisSession.uVFS == null) return;
thisSession.setupRootDir(domain);
}
catch(Exception e)
{
Common.debug(1,e);
}
}
public void sendRedirect(String path, Vector headers) throws Exception
{
write_command_http("HTTP/1.0 302 Redirect");
write_command_http("Pragma: no-cache");
//get host string to put in location.
String baseURL = getBaseUrl(headers);
if (path.toUpperCase().startsWith("HTTP")) write_command_http("location: "+path);
else write_command_http("location: "+baseURL+path);
}
public String getBaseUrl(Vector headers)
{
for(int xx=0; xx<headers.size(); xx++)
{
String data2 = headers.elementAt(xx).toString();
if (data2.toUpperCase().startsWith("HOST: ") || data2.toUpperCase().startsWith("X-FORWARDED-HOST: "))
{
hostString = data2.substring(data2.toUpperCase().indexOf(":") + 1).trim();
}
}
return server_item.getProperty("serverType","http")+"://" + hostString+proxy;
}
public void sendHttpsRedirect(String path, Vector headers) throws Exception
{
write_command_http("HTTP/1.0 302 Redirect");
write_command_http("Pragma: no-cache");
//get host string to put in location.
for(int xx=0; xx<headers.size(); xx++)
{
String data2 = headers.elementAt(xx).toString();
if (data2.toUpperCase().startsWith("HOST: ") || data2.toUpperCase().startsWith("X-Forwarded-Host: "))
{
hostString = data2.substring(data2.toUpperCase().indexOf(":") + 1).trim();
}
}
if (hostString.indexOf(":") >= 0) hostString = hostString.substring(0,hostString.indexOf(":"));
Vector server_list = (Vector)thisSession.server_status_frame.server_settings.get("server_list");
String port = "443";
for (int x=0; x<server_list.size(); x++)
{
Properties p = (Properties)server_list.elementAt(x);
if (p.getProperty("serverType","FTP").equalsIgnoreCase("HTTPS"))
{
port = p.getProperty("port","443");
break;
}
}
if (port.equals("443")) port = "";
else port = ":"+port;
write_command_http("location: https://" + hostString+port+proxy+path);
}
class idleChecker implements Runnable
{
int secs;
public idleChecker(int secs)
{
this.secs = secs;
}
public void run()
{
try
{
Thread.sleep(secs*1000);
do_kill();
}
catch(Exception e)
{
}
}
}
Thread idle_thread = null;
public void start_idle_thread()
{
if (idle_thread != null)
{
idle_thread.interrupt();
}
idle_thread = new Thread(new idleChecker(timeoutSeconds));
idle_thread.start();
}
public void stop_idle_thread()
{
if (idle_thread != null)
{
idle_thread.interrupt();
}
}
public void updateMimes() throws Exception
{
long mimesModifiedNew = new File(System.getProperty("crushftp.web")+"WebInterface/mime_types.txt").lastModified();
if (mimesModified != mimesModifiedNew)
{
mimes = new Properties();
BufferedReader mimeIn = new BufferedReader(new FileReader(new File(System.getProperty("crushftp.web")+"WebInterface/mime_types.txt")));
String s = mimeIn.readLine();
while(s != null)
{
if (!s.startsWith("#")) try{mimes.put(s.substring(0,s.indexOf(" ")).trim().toUpperCase(),s.substring(s.indexOf(" ")+1).trim());}catch(Exception e){/*bad mime type*/}
s = mimeIn.readLine();
}
mimeIn.close();
}
}
public void processMiniURLs(String header0,Vector headers)
{
try
{
if (header0.toUpperCase().startsWith("GET "))
{
String data = header0.substring(header0.indexOf(" ")+1,header0.lastIndexOf(" "));
String miniURL = data.substring(data.lastIndexOf("/")+1);//miniURL piece
Vector miniURLs = thisSession.server_status_frame.VG("miniURLs");
if (miniURLs != null)
{
for (int x=0; x<miniURLs.size(); x++)
{
Properties p = (Properties)miniURLs.elementAt(x);
if (p.getProperty("key","").equalsIgnoreCase(miniURL))//found a match, translate it
{
boolean expired = false;
SimpleDateFormat sdf = new SimpleDateFormat("MM/dd/yyyy HH:mm aa");
try
{
if(!p.getProperty("expire","").equals(""))
{
if (sdf.parse(p.getProperty("expire","")).getTime() < new Date().getTime()) expired = true;
}
}
catch(Exception e)
{
expired = true;
}
if (expired)
{
miniURLs.removeElementAt(x);
Common.addCommand("save_server_settings",null);
}
else
{
String user = p.getProperty("user","");
String pass = common_code.decode_pass(p.getProperty("pass",""));
String id = new Date().getTime()+"";
globalSessions.put(thisSession.uiSG("user_ip")+"_"+id+"_user",user);
globalSessions.put(thisSession.uiSG("user_ip")+"_"+id+"_pass",pass);
sendRedirect(p.getProperty("redirect","/"),headers);
write_command_http("Connection: close");
write_command_http("Set-Cookie: CrushAuth="+id+"; path=/");
thisSession.uiPUT("CrushAuth",id);
write_command_http("");
done = true;
thisSession.uVFS = null;
}
break;
}
}
}
}
}
catch(Exception e)
{
Common.debug(1,e);
}
}
public void savePropPatches() throws Exception
{
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(System.getProperty("crushftp.backup")+"backup/proppatches.prop.save"));
oos.writeObject(proppatches);
oos.close();
new File(System.getProperty("crushftp.backup")+"backup/proppatches.prop").delete();
new File(System.getProperty("crushftp.backup")+"backup/proppatches.prop.save").renameTo(new File(System.getProperty("crushftp.backup")+"backup/proppatches.prop"));
}
public void savePublicPasswords() throws Exception
{
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(System.getProperty("crushftp.backup")+"backup/publicpasswords.prop.save"));
oos.writeObject(publicpasswords);
oos.close();
new File(System.getProperty("crushftp.backup")+"backup/publicpasswords.prop").delete();
new File(System.getProperty("crushftp.backup")+"backup/publicpasswords.prop.save").renameTo(new File(System.getProperty("crushftp.backup")+"backup/publicpasswords.prop"));
}
public void saveLockTokens() throws Exception
{
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(System.getProperty("crushftp.backup")+"backup/locktokens.prop.save"));
oos.writeObject(locktokens);
oos.close();
new File(System.getProperty("crushftp.backup")+"backup/locktokens.prop").delete();
new File(System.getProperty("crushftp.backup")+"backup/locktokens.prop.save").renameTo(new File(System.getProperty("crushftp.backup")+"backup/locktokens.prop"));
}
public String changeUser(String xml)
{
String username = xml.substring(xml.indexOf("username = ")+"username = ".length(),xml.indexOf(";",xml.indexOf("username = ")));
String password = xml.substring(xml.indexOf("password = ")+"password = ".length(),xml.indexOf(";",xml.indexOf("password = ")));
done = true;//force connection closed after validating user
VFS uVFS = thisSession.uVFS;
thisSession.uVFS = null;
boolean ok = thisSession.verify_user(username.trim(),password.trim());
if (thisSession.uVFS == null) thisSession.uVFS = uVFS;
done = true;
if (ok)
{
thisSession.uiPUT("current_password",password);
thisSession.uiPUT("user_name",username);
this_thread.setName(thisSession.uiSG("user_name") + ":(" + thisSession.uiSG("user_number") + ")-" + thisSession.uiSG("user_ip") + " (control)");
return username;
}
return null;
}
}