package zeta.handler;
import java.io.IOException;
import java.net.URLEncoder;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import zeta.ZetaServlet;
import zeta.handler.approve.ApproveBase;
import zeta.util.Base64;
import zeta.util.DatabaseUtils;
import zeta.util.StreamUtils;
import zeta.util.ThrowableHandler;
import BlowfishJ.BlowfishECB;
public class ApproveHandler implements GetHandler {
public ApproveHandler(ZetaServlet servlet) {
this.servlet = servlet;
}
public void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String key = req.getParameter("key");
String keyLength = req.getParameter("length");
if (key != null && key.length() > 0 && keyLength != null) {
Connection con = null;
Statement stmt = null;
try {
con = servlet.getConnection();
stmt = con.createStatement();
String result = approve(servlet, stmt, key, keyLength);
resp.setContentType("text/html");
resp.getOutputStream().print(result);
} catch (SQLException e) {
throw new ServletException(e);
} catch (NumberFormatException e) {
throw new ServletException(e);
} catch (IndexOutOfBoundsException e) {
throw new ServletException(e);
} finally {
DatabaseUtils.close(stmt);
DatabaseUtils.close(con);
}
}
}
public static String generateAddressToApprove(ZetaServlet servlet, String text) throws SQLException, IOException, ServletException {
Connection con = null;
Statement stmt = null;
try {
con = servlet.getConnection();
stmt = con.createStatement();
ResultSet rs = stmt.executeQuery("SELECT web_hostname,web_port,key FROM zeta.server WHERE server_id=" + servlet.getServerId());
byte[] serverKey = (rs.next())? rs.getBytes(3) : null;
if (serverKey == null) {
throw new SQLException("Missing key for server " + servlet.getServerId());
}
BlowfishECB bfecb = new BlowfishECB(serverKey);
byte[] code = text.getBytes("UTF-8");
int codeLength = code.length;
code = StreamUtils.align8(code);
bfecb.encrypt(code);
bfecb.cleanUp();
String link = "http://" + rs.getString(1) + ':' + rs.getInt(2) + servlet.getHandlerAddress(ApproveHandler.class)
+ "?key=" + URLEncoder.encode(Base64.encode(code)) + "&length=" + codeLength;
rs.close();
return link;
} finally {
DatabaseUtils.close(stmt);
DatabaseUtils.close(con);
}
}
public static String decrypt(ZetaServlet servlet, Statement stmt, String key, String keyLength) throws IOException, SQLException {
int serverId = servlet.getServerId();
ResultSet rs = stmt.executeQuery("SELECT key FROM zeta.server WHERE server_id=" + serverId);
byte[] serverKey = (rs.next())? rs.getBytes(1) : null;
rs.close();
if (serverKey == null) {
throw new SQLException("Missing key for server " + serverId);
}
BlowfishECB bfecb = new BlowfishECB(serverKey);
byte[] code = Base64.decode(key);
bfecb.decrypt(code);
bfecb.cleanUp();
return new String(code, 0, Integer.parseInt(keyLength), "UTF-8");
}
static String approve(ZetaServlet servlet, Statement stmt, String key, String keyLength) throws IOException, SQLException {
key = decrypt(servlet, stmt, key, keyLength);
String result = "<html><body><b>Error:</b> The key <p>" + key + "<p>is invalid! Please check if the URL is similar to that in your e-mail.</body></html>";
Integer serverId = ApproveBase.getServerId(key);
if (serverId != null && serverId.intValue() == servlet.getServerId()) {
String user = "";
String eMail = "";
Integer userId = ApproveBase.getUserId(key);
ResultSet rs = stmt.executeQuery("SELECT name,email FROM zeta.user WHERE server_id=" + serverId + " AND id=" + userId);
if (rs.next()) {
user = rs.getString(1);
eMail = rs.getString(2);
}
rs.close();
final Class[] approveClasses = { zeta.handler.approve.ApproveTeamName.class,
zeta.handler.approve.ApproveMessages.class,
zeta.handler.approve.ApproveProperties.class };
for (int i = 0; i < approveClasses.length; ++i) {
try {
ApproveBase approveObj = (ApproveBase)approveClasses[i].getConstructor(new Class[] { ZetaServlet.class, int.class, String.class, String.class }).newInstance(new Object[] { servlet, userId, user, eMail });
String value = approveObj.getValue(key);
if (value != null) {
long timeMillis = ApproveBase.getTimeMillis(key);
if (System.currentTimeMillis()-timeMillis < 7*24*3600*1000) {
result = approveObj.approve(stmt, value, timeMillis);
} else {
result = "<html><body><b>Error:</b> Key expired!</body></html>";
}
break;
}
} catch (Exception e) {
ThrowableHandler.handle(e);
}
}
}
return result;
}
private ZetaServlet servlet;
}