init repo

This commit is contained in:
Niklas 2017-07-03 00:32:04 +02:00
commit bbf9f1151f
10 changed files with 916 additions and 0 deletions

70
.gitignore vendored Normal file
View File

@ -0,0 +1,70 @@
*.db
*.sqlite*
settings.json
# Windows image file caches
Thumbs.db
ehthumbs.db
# Manifest created by build
MANIFEST.MF
# Folder config file
Desktop.ini
# Recycle Bin used on file shares
$RECYCLE.BIN/
# Windows Installer files
*.cab
*.msi
*.msm
*.msp
# Windows shortcuts
*.lnk
.DS_Store
.AppleDouble
.LSOverride
# Thumbnails
._*
# Files that might appear on external disk
.Spotlight-V100
.Trashes
# Directories potentially created on remote AFP share
.AppleDB
.AppleDesktop
Network Trash Folder
Temporary Items
.apdisk
nbproject/
dist/
build/
/bin/
# Files created by the bot inside resources folder
resources/bannedUsers.bin
resources/botlogin.txt
resources/phantombot.db
resources/stacktrace.txt
resources/stdio.txt
resources/web/default.html
resources/web/default.txt
resources/scripts/*
# Do not include the class files for GenerateTwitterTokens
genTwitterTokens/classes/generatetwittertokens
# IntelliJ Project files
.idea
out/
*.iml
# Netbeans Project files
nbproject
# Eclipse Project files

View File

@ -0,0 +1,148 @@
package de.gurkengewuerz.termbin;
import org.json.JSONArray;
import org.json.JSONObject;
import org.json.JSONTokener;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;
import java.nio.file.AccessDeniedException;
import java.nio.file.Files;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
* Created by gurkengewuerz.de on 02.07.2017.
*/
public class Config extends JSONObject {
private File file;
private static List<String> ban = new ArrayList<>();
private static List<String> whitelist = new ArrayList<>();
public Config(File file) throws IOException {
this.file = file;
if (!file.exists()) {
file.createNewFile();
}
if (!file.isFile()) {
throw new FileNotFoundException(file.getAbsolutePath() + " not found");
}
if (!file.canRead() || !file.canWrite()) {
throw new AccessDeniedException(file.getAbsolutePath() + " is not accessable");
}
this.put("log", "termvin.log");
this.put("database", "db.sqlite3");
this.put("domain", "http://localhost/");
JSONObject uploadserver = new JSONObject();
uploadserver.put("port", 8888);
uploadserver.put("bind", "0.0.0.0");
this.put("uploadserver", uploadserver);
JSONObject dataserver = new JSONObject();
dataserver.put("port", 8080);
this.put("dataserver", dataserver);
JSONObject apiserver = new JSONObject();
apiserver.put("port", 9090);
this.put("apiserver", apiserver);
JSONArray ban_list = new JSONArray();
ban_list.put("125.38.39.40");
ban_list.put("27.46.74.43");
ban_list.put("210.35.171.4");
this.put("ban_list", ban_list);
JSONArray white_list = new JSONArray();
white_list.put("127.0.0.1");
white_list.put("192.168.1.36");
this.put("white_list", white_list);
}
public void save() {
try {
FileWriter fw = new FileWriter(file.getAbsolutePath());
fw.write(this.toString(4));
fw.close();
loadRestData();
} catch (IOException e) {
Logger.getLogger(getClass().getName()).log(Level.SEVERE, null, e);
}
}
public void load() {
try {
String content = new String(Files.readAllBytes(file.toPath()), "UTF-8");
if (content.isEmpty()) {
save();
return;
}
JSONTokener jt = new JSONTokener(content);
if (jt.nextClean() != 123) {
throw jt.syntaxError("A JSONObject text must begin with '{'");
} else {
while (jt.more()) {
char c = jt.nextClean();
switch (c) {
case '\u0000':
throw jt.syntaxError("A JSONObject text must end with '}'");
case '}':
return;
default:
jt.back();
String key = jt.nextValue().toString();
c = jt.nextClean();
if (c != 58) {
throw jt.syntaxError("Expected a ':' after a key");
}
this.remove(key);
this.putOnce(key, jt.nextValue());
switch (jt.nextClean()) {
case ',':
case ';':
if (jt.nextClean() == 125) {
return;
}
jt.back();
break;
case '}':
loadRestData();
return;
default:
throw jt.syntaxError("Expected a ',' or '}'");
}
}
}
}
} catch (IOException e) {
Logger.getLogger(getClass().getName()).log(Level.SEVERE, null, e);
}
}
private void loadRestData() {
JSONArray json_whitelist = getJSONArray("white_list");
for (int i = 0; i < json_whitelist.length(); i++) {
whitelist.add(json_whitelist.getString(i));
}
JSONArray json_ban = getJSONArray("ban_list");
for (int i = 0; i < json_ban.length(); i++) {
if (whitelist.contains(json_ban.getString(i))) continue;
ban.add(json_ban.getString(i));
}
}
public boolean isBanned(String ipv4) {
return ban.contains(ipv4);
}
}

View File

@ -0,0 +1,61 @@
package de.gurkengewuerz.termbin;
import java.sql.*;
/**
* Created by gurkengewuerz.de on 08.04.2017.
*/
public class Database {
private String sUrl = null;
private int iTimeout = 30;
private Connection conn = null;
private Statement statement = null;
public Database(String sUrlToLoad) throws Exception {
setUrl(sUrlToLoad);
setConnection();
setStatement();
}
private void setUrl(String sUrlVar) {
sUrl = sUrlVar;
}
private void setConnection() throws Exception {
conn = DriverManager.getConnection("jdbc:sqlite:" + sUrl);
}
public Connection getConnection() {
return conn;
}
private void setStatement() throws Exception {
if (conn == null) {
setConnection();
}
statement = conn.createStatement();
statement.setQueryTimeout(iTimeout); // set timeout to 30 sec.
}
public PreparedStatement getPreparedStatement(String sql) throws SQLException {
return conn.prepareStatement(sql);
}
public void executeUpdate(String instruction) throws SQLException {
statement.executeUpdate(instruction);
}
public ResultSet executeQuery(String instruction) throws SQLException {
return statement.executeQuery(instruction);
}
public void closeConnection() {
try {
conn.close();
} catch (Exception ignore) {
}
}
}

View File

@ -0,0 +1,111 @@
package de.gurkengewuerz.termbin.Server;
import de.gurkengewuerz.termbin.Termbin;
import de.gurkengewuerz.termbin.Utils.ImageUtils;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.handler.AbstractHandler;
import org.json.JSONArray;
import org.json.JSONObject;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.PrintWriter;
import java.sql.SQLException;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
* Created by gurkengewuerz.de on 02.07.2017.
*/
public class APIHandler extends AbstractHandler {
@Override
public void handle(String s, Request request, HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws IOException, ServletException {
Logger.getLogger(getClass().getName()).log(Level.INFO, "API Request by " + request.getRemoteAddr() + "@" + s);
if(Termbin.getConfig().isBanned(request.getRemoteAddr())) {
request.setHandled(true);
Logger.getLogger(getClass().getName()).log(Level.INFO, "API Request by " + request.getRemoteAddr() + "@" + s + " closed BANNED");
return;
}
JSONObject returnObject = null;
JSONArray returnArray = null;
request.setCharacterEncoding("UTF-8");
httpServletResponse.setCharacterEncoding("UTF-8");
if (s.equals("/")) { // Describe yourself
httpServletResponse.setStatus(HttpServletResponse.SC_OK);
returnObject = new JSONObject();
returnObject.put("self", "/");
returnObject.put("upload", "/upload/");
} else if (s.startsWith("/upload")) {
returnObject = new JSONObject();
httpServletResponse.setStatus(HttpServletResponse.SC_OK);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
boolean breaked = false;
byte[] buff = new byte[1024];
while (true) {
int n = httpServletRequest.getInputStream().read(buff);
if (n < 0) break;
baos.write(buff, 0, n);
if (baos.size() > 1024 * 1024 * 2) {// 2 MB
breaked = true;
returnObject.put("error", "File too big");
Logger.getLogger(getClass().getName()).log(Level.INFO, "API Request by " + request.getRemoteAddr() + "@" + s + " closed FILE TOO BIG");
break;
}
}
if (!breaked) {
byte[] data = baos.toByteArray();
if (data.length > 3) {
String dataString = new String(data, "UTF-8");
Termbin.FileType ft = Termbin.FileType.TXT;
if (ImageUtils.isValidPNG(data))
ft = Termbin.FileType.PNG;
else if (ImageUtils.isValidJPEG(data))
ft = Termbin.FileType.JPG;
else if (ImageUtils.isValidGIF(data))
ft = Termbin.FileType.GIF;
try {
String uploadID = Termbin.upload(request.getRemoteAddr(), dataString, data, ft);
returnObject.put("key", uploadID);
Logger.getLogger(getClass().getName()).log(Level.INFO, "API Request by " + request.getRemoteAddr() + "@" + s + " closed SUCCESSFULL");
} catch (SQLException e) {
Logger.getLogger(getClass().getName()).log(Level.INFO, "API Request by " + request.getRemoteAddr() + "@" + s + " closed SERVER ERROR");
Logger.getLogger(getClass().getName()).log(Level.SEVERE, null, e);
returnObject.put("error", "Server error");
}
} else {
returnObject.put("error", "data is empty");
Logger.getLogger(getClass().getName()).log(Level.INFO, "API Request by " + request.getRemoteAddr() + "@" + s + " closed EMPTY");
}
}
} else {
httpServletResponse.setStatus(HttpServletResponse.SC_FORBIDDEN);
}
httpServletResponse.setContentType("application/json; charset=utf-8");
PrintWriter out = httpServletResponse.getWriter();
if (returnObject != null) {
out.write(returnObject.toString());
} else if (returnArray != null) {
out.write(returnArray.toString());
} else {
returnObject = new JSONObject();
returnObject.put("error", "not found");
out.write(returnObject.toString());
}
request.setHandled(true);
}
}

View File

@ -0,0 +1,64 @@
package de.gurkengewuerz.termbin.Server;
import de.gurkengewuerz.termbin.Termbin;
import de.gurkengewuerz.termbin.Utils.SQLInjectionEscaper;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.handler.AbstractHandler;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
* Created by gurkengewuerz.de on 02.07.2017.
*/
public class DataHandler extends AbstractHandler {
@Override
public void handle(String s, Request request, HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws IOException, ServletException {
Logger.getLogger(getClass().getName()).log(Level.INFO, "Request by " + request.getRemoteAddr() + "@" + s);
if (Termbin.getConfig().isBanned(request.getRemoteAddr())) {
request.setHandled(true);
Logger.getLogger(getClass().getName()).log(Level.INFO, "Request by " + request.getRemoteAddr() + "@" + s + " closed BANNED");
return;
}
request.setCharacterEncoding("UTF-8");
httpServletResponse.setCharacterEncoding("UTF-8");
try {
ResultSet rs = Termbin.getDatabase().executeQuery("SELECT * FROM data WHERE uniqueid = '" + SQLInjectionEscaper.escapeString(s.substring(1), false) + "' LIMIT 1;");
boolean found = false;
httpServletResponse.setStatus(HttpServletResponse.SC_OK);
while (rs.next()) {
found = true;
httpServletResponse.setContentType(rs.getString("filetype"));
if (rs.getString("filetype").equals("text/plain")) {
httpServletResponse.getOutputStream().write(rs.getString("text").getBytes("UTF-8"));
} else {
httpServletResponse.setContentLength(rs.getBytes("rawData").length);
httpServletResponse.getOutputStream().write(rs.getBytes("rawData"));
}
}
if (!found) {
httpServletResponse.setStatus(HttpServletResponse.SC_NOT_FOUND);
httpServletResponse.getOutputStream().write("<html><body><img src='https://http.cat/404'/></body></html>".getBytes("UTF-8"));
}
} catch (SQLException e) {
Logger.getLogger(getClass().getName()).log(Level.SEVERE, null, e);
httpServletResponse.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
httpServletResponse.getOutputStream().write("<html><body><img src='https://http.cat/500'/></body></html>".getBytes("UTF-8"));
}
request.setHandled(true);
}
}

View File

@ -0,0 +1,131 @@
package de.gurkengewuerz.termbin.Server;
import de.gurkengewuerz.termbin.Termbin;
import de.gurkengewuerz.termbin.Utils.ImageUtils;
import java.io.BufferedWriter;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.net.*;
import java.sql.SQLException;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
* Created by gurkengewuerz.de on 02.07.2017.
*/
public class UploadServer {
public UploadServer(String ipv4, int port) throws IOException {
Logger.getLogger("Main").log(Level.INFO, "Starting...");
int clientNumber = 1;
ServerSocket listener = new ServerSocket(port);
if (!ipv4.isEmpty() && !ipv4.equals("0.0.0.0")) {
listener.bind(new InetSocketAddress(ipv4, port));
}
Logger.getLogger(getClass().getName()).log(Level.INFO, "Started. Waiting for Clients.");
try {
while (true) {
Socket socketOfServer = listener.accept();
new ServiceThread(socketOfServer, clientNumber++).start();
}
} finally {
listener.close();
}
}
private class ServiceThread extends Thread {
private Socket socketOfServer;
private String client;
private String clientIP;
public ServiceThread(Socket socketOfServer, int clientNumber) {
this.socketOfServer = socketOfServer;
this.clientIP = socketOfServer.getInetAddress().toString().substring(1);
this.client = "client#" + clientNumber + "@" + clientIP + ":" + socketOfServer.getPort();
try {
this.socketOfServer.setSoTimeout(2000);
} catch (SocketException e) {
Logger.getLogger(getClass().getName()).log(Level.SEVERE, null, e);
}
Logger.getLogger(getClass().getName()).log(Level.INFO, "opened " + client + " at " + socketOfServer.getLocalAddress() + ":" + socketOfServer.getLocalPort());
if (Termbin.getConfig().isBanned(clientIP)) {
Logger.getLogger(getClass().getName()).log(Level.INFO, "closed " + client + " with error banned");
try {
socketOfServer.close();
} catch (IOException e) {
Logger.getLogger(getClass().getName()).log(Level.SEVERE, null, e);
}
}
}
@Override
public void run() {
try {
if (socketOfServer.isClosed()) return;
BufferedWriter os = new BufferedWriter(new OutputStreamWriter(socketOfServer.getOutputStream()));
ByteArrayOutputStream baos = new ByteArrayOutputStream();
try {
byte[] buff = new byte[1024];
while (true) {
int n = socketOfServer.getInputStream().read(buff);
if (n < 0) break;
baos.write(buff, 0, n);
if (baos.size() > 1024 * 1024 * 2) {// 2 MB
Logger.getLogger(getClass().getName()).log(Level.INFO, "closed " + client + " with file to big");
os.write("File to big!");
os.newLine();
os.flush();
socketOfServer.close();
return;
}
}
} catch (SocketTimeoutException e) {
Logger.getLogger(getClass().getName()).log(Level.INFO, "closed " + client + " with error invalid data");
os.write("Invalid data");
os.newLine();
os.flush();
socketOfServer.close();
return;
}
byte[] data = baos.toByteArray();
if (data.length > 3) {
String dataString = new String(data, "UTF-8");
Termbin.FileType ft = Termbin.FileType.TXT;
if (ImageUtils.isValidPNG(data))
ft = Termbin.FileType.PNG;
else if (ImageUtils.isValidJPEG(data))
ft = Termbin.FileType.JPG;
else if (ImageUtils.isValidGIF(data))
ft = Termbin.FileType.GIF;
try {
String uploadID = Termbin.upload(clientIP, dataString, data, ft);
os.write(Termbin.getConfig().get("domain") + uploadID);
Logger.getLogger(getClass().getName()).log(Level.INFO, "closed " + client + " successfully with ID#" + uploadID);
} catch (SQLException e) {
Logger.getLogger(getClass().getName()).log(Level.SEVERE, null, e);
os.write("Server Error");
}
} else {
os.write("Invalid data");
Logger.getLogger(getClass().getName()).log(Level.INFO, "closed " + client + " with error invalid data");
}
os.newLine();
os.flush();
socketOfServer.close();
} catch (IOException e) {
Logger.getLogger(getClass().getName()).log(Level.SEVERE, null, e);
}
}
}
}

View File

@ -0,0 +1,158 @@
package de.gurkengewuerz.termbin;
import de.gurkengewuerz.termbin.Server.APIHandler;
import de.gurkengewuerz.termbin.Server.DataHandler;
import de.gurkengewuerz.termbin.Server.UploadServer;
import de.gurkengewuerz.termbin.Utils.HashUtils;
import org.eclipse.jetty.server.Server;
import org.json.JSONObject;
import java.io.File;
import java.io.IOException;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
* Created by gurkengewuerz.de on 02.07.2017.
*/
public class Termbin {
private static Database db;
private static Config conf;
public static void main(String args[]) {
File f = new File("." + File.separator + "settings.json");
try {
conf = new Config(f);
} catch (IOException e) {
Logger.getLogger(Termbin.class.getName()).log(Level.SEVERE, null, e);
System.exit(1);
}
conf.load();
try {
db = new Database(conf.getString("database"));
createDatabase();
} catch (Exception e) {
Logger.getLogger(Termbin.class.getName()).log(Level.SEVERE, null, e);
}
Runnable uploadServerTask = () -> {
try {
JSONObject uploadServerConf = conf.getJSONObject("uploadserver");
new UploadServer(uploadServerConf.getString("bind"), uploadServerConf.getInt("port"));
} catch (IOException e) {
Logger.getLogger(Termbin.class.getName()).log(Level.SEVERE, null, e);
}
};
Thread uploadServerThread = new Thread(uploadServerTask);
uploadServerThread.start();
Runnable dataServerTask = () -> {
try {
JSONObject dataServerConf = conf.getJSONObject("dataserver");
Server dataServer = new Server(dataServerConf.getInt("port"));
dataServer.setHandler(new DataHandler());
dataServer.start();
dataServer.join();
} catch (Exception e) {
Logger.getLogger(Termbin.class.getName()).log(Level.SEVERE, null, e);
}
};
Thread dataServerThread = new Thread(dataServerTask);
dataServerThread.start();
Runnable apiServerTask = () -> {
try {
JSONObject apiServerConf = conf.getJSONObject("apiserver");
Server apiServer = new Server(apiServerConf.getInt("port"));
apiServer.setHandler(new APIHandler());
apiServer.start();
apiServer.join();
} catch (Exception e) {
Logger.getLogger(Termbin.class.getName()).log(Level.SEVERE, null, e);
}
};
Thread apiServerThread = new Thread(apiServerTask);
apiServerThread.start();
// TODO: Check if all threads started successfully
// TODO: log to file
// TODO: Arguments (Settings file)
// TODO: print start values (all ports etc.)
// TODO: Config Max lifetime => Check insert time on request
// TODO: Maven
}
public static Database getDatabase() {
return db;
}
public static Config getConfig() {
return conf;
}
public static String upload(String ip, String text, byte[] rawData, FileType fileType) throws SQLException {
String answerID = HashUtils.getSha256(System.currentTimeMillis() + "").substring(0, 8);
PreparedStatement ps = getDatabase().getPreparedStatement("INSERT INTO data (uniqueid, timestamp, fromClient, filetype, text, rawData) VALUES (?, ?, ?, ?, ?, ?);");
ps.setString(1, answerID);
ps.setInt(2, (int) (System.currentTimeMillis() / 1000));
ps.setString(3, ip);
ps.setString(4, fileType.toString());
if (fileType.equals(FileType.TXT)) {
ps.setString(5, text);
ps.setBytes(6, null);
} else {
ps.setString(5, null);
ps.setBytes(6, rawData);
}
ps.execute();
return answerID;
}
public enum FileType {
TXT,
PNG,
JPG,
GIF;
@Override
public String toString() {
switch (this) {
case TXT:
return "text/plain";
case PNG:
return "image/png";
case JPG:
return "image/jpeg";
case GIF:
return "image/gif";
default:
throw new IllegalArgumentException();
}
}
}
private static void createDatabase() throws SQLException {
getDatabase().executeUpdate(
"CREATE TABLE IF NOT EXISTS data (" +
" id INTEGER PRIMARY KEY AUTOINCREMENT," +
" uniqueid char(255) NOT NULL UNIQUE," +
" text text NULL," +
" rawData blob NULL," +
" timestamp float NOT NULL," +
" fromClient char(255) NOT NULL," +
" filetype char(255) NOT NULL" +
");"
);
}
}

View File

@ -0,0 +1,24 @@
package de.gurkengewuerz.termbin.Utils;
import java.security.MessageDigest;
/**
* Created by gurkengewuerz.de on 02.07.2017.
*/
public class HashUtils {
public static String getSha256(String value) {
try {
MessageDigest md = MessageDigest.getInstance("SHA-256");
md.update(value.getBytes());
return bytesToHex(md.digest());
} catch (Exception ex) {
throw new RuntimeException(ex);
}
}
private static String bytesToHex(byte[] bytes) {
StringBuilder result = new StringBuilder();
for (byte b : bytes) result.append(Integer.toString((b & 0xff) + 0x100, 16).substring(1));
return result.toString();
}
}

View File

@ -0,0 +1,78 @@
package de.gurkengewuerz.termbin.Utils;
import java.util.Arrays;
public class ImageUtils {
static byte[] PNG_HEADER = hexStringToByteArray("89504e470d0a1a0a");
/**
* Check if the image is a PNG. The first eight bytes of a PNG file always
* contain the following (decimal) values: 137 80 78 71 13 10 26 10 / Hex:
* 89 50 4e 47 0d 0a 1a 0a
*/
public static boolean isValidPNG(byte[] is) {
try {
byte[] b = Arrays.copyOfRange(is, 0, 8);
if (Arrays.equals(b, PNG_HEADER)) {
return true;
}
} catch (Exception e) {
//Ignore
return false;
}
return false;
}
/**
* Check if the image is a JPEG. JPEG image files begin with FF D8 and end
* with FF D9
*/
public static boolean isValidJPEG(byte[] is) {
try {
// check first 2 bytes:
byte[] b = Arrays.copyOfRange(is, 0, 2);
if ((b[0]&0xff) != 0xff || (b[1]&0xff) != 0xd8) {
return false;
}
// check last 2 bytes:
b = Arrays.copyOfRange(is, is.length - 2, is.length);
if ((b[0]&0xff) != 0xff || (b[1]&0xff) != 0xd9) {
return false;
}
} catch (Exception e) {
// Ignore
return false;
}
return true;
}
/** Check if the image is a valid GIF. GIF files start with GIF and 87a or 89a.
* http://www.onicos.com/staff/iz/formats/gif.html
*/
public static boolean isValidGIF(byte[] is) {
try {
byte[] b = Arrays.copyOfRange(is, 0, 6);
//check 1st 3 bytes
if(b[0]!='G' || b[1]!='I' || b[2]!='F') {
return false;
}
if(b[3]!='8' || !(b[4]=='7' || b[4]=='9') || b[5]!='a') {
return false;
}
} catch(Exception e) {
// Ignore
return false;
}
return true;
}
public static byte[] hexStringToByteArray(String s) {
int len = s.length();
byte[] data = new byte[len / 2];
for (int i = 0; i < len; i += 2) {
data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4)
+ Character.digit(s.charAt(i+1), 16));
}
return data;
}
}

View File

@ -0,0 +1,71 @@
package de.gurkengewuerz.termbin.Utils;
public class SQLInjectionEscaper {
public static String escapeString(String x, boolean escapeDoubleQuotes) {
StringBuilder sBuilder = new StringBuilder(x.length() * 11 / 10);
int stringLength = x.length();
for (int i = 0; i < stringLength; ++i) {
char c = x.charAt(i);
switch (c) {
case 0: /* Must be escaped for 'mysql' */
sBuilder.append('\\');
sBuilder.append('0');
break;
case '\n': /* Must be escaped for logs */
sBuilder.append('\\');
sBuilder.append('n');
break;
case '\r':
sBuilder.append('\\');
sBuilder.append('r');
break;
case '\\':
sBuilder.append('\\');
sBuilder.append('\\');
break;
case '\'':
sBuilder.append('\\');
sBuilder.append('\'');
break;
case '"': /* Better safe than sorry */
if (escapeDoubleQuotes) {
sBuilder.append('\\');
}
sBuilder.append('"');
break;
case '\032': /* This gives problems on Win32 */
sBuilder.append('\\');
sBuilder.append('Z');
break;
case '\u00a5':
case '\u20a9':
// escape characters interpreted as backslash by mysql
// fall through
default:
sBuilder.append(c);
}
}
return sBuilder.toString();
}
}