switched to maven
Check if all threads started successfully
log to file
Arguments (settings file)
print start values
Config Max lifetime
This commit is contained in:
Niklas 2017-07-03 21:53:52 +02:00
parent bbf9f1151f
commit 58482bf285
12 changed files with 236 additions and 56 deletions

4
.gitignore vendored
View File

@ -63,8 +63,12 @@ genTwitterTokens/classes/generatetwittertokens
.idea
out/
*.iml
target/
# Netbeans Project files
nbproject
# Eclipse Project files
*access*

22
README.md Normal file
View File

@ -0,0 +1,22 @@
## NGINX Reverse Config
server {
listen 80;
listen [::]:80;
server_name paste.mc8051.de;
root /var/www/html/;
index index.html index.php index.htm;
client_max_body_size 25m;
## Definition Reverse Proxy ##
location / {
proxy_pass http://127.0.0.1:8080/;
proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504;
proxy_redirect off;
proxy_buffering off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}

90
pom.xml Normal file
View File

@ -0,0 +1,90 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>de.gurkengewuerz</groupId>
<artifactId>termbin</artifactId>
<version>1.0-SNAPSHOT</version>
<licenses>
<license>
<name>MIT License</name>
<url>https://opensource.org/licenses/MIT</url>
<distribution>repo</distribution>
</license>
</licenses>
<developers>
<developer>
<name>Gurkengewuerz</name>
<email>admin@gurkengewuerz.de</email>
<url>https://gurkengewuerz.de</url>
<timezone>Europe/Berlin</timezone>
</developer>
</developers>
<dependencies>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-server</artifactId>
<version>9.4.3.v20170317</version>
</dependency>
<dependency>
<groupId>org.xerial</groupId>
<artifactId>sqlite-jdbc</artifactId>
<version>3.16.1</version>
</dependency>
<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
<version>20160810</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.5</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.5.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.6</version>
<configuration>
<appendAssemblyId>false</appendAssemblyId>
<finalName>${project.artifactId}</finalName>
<descriptorRefs>
<descriptorRef>
jar-with-dependencies
</descriptorRef>
</descriptorRefs>
<archive>
<manifest>
<mainClass>${project.groupId}.${project.artifactId}.Termbin</mainClass>
</manifest>
</archive>
</configuration>
<executions>
<execution>
<id>assamble</id>
<goals>
<goal>single</goal>
</goals>
<phase>package</phase>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

View File

@ -20,8 +20,12 @@ import java.util.logging.Logger;
*/
public class Config extends JSONObject {
private File file;
private static List<String> ban = new ArrayList<>();
private static List<String> whitelist = new ArrayList<>();
private List<String> ban = new ArrayList<>();
private List<String> whitelist = new ArrayList<>();
private JSONObject uploadServerConf;
private JSONObject dataServerConf;
private JSONObject apiServerConf;
public Config(File file) throws IOException {
this.file = file;
@ -38,9 +42,11 @@ public class Config extends JSONObject {
throw new AccessDeniedException(file.getAbsolutePath() + " is not accessable");
}
this.put("log", "termvin.log");
this.put("accesslog", "access");
this.put("database", "db.sqlite3");
this.put("domain", "http://localhost/");
this.put("uploadlifetime", 24 * 7); // 1 week hours
this.put("maxkb", 1024 * 2); // 2 mb
JSONObject uploadserver = new JSONObject();
uploadserver.put("port", 8888);
@ -48,7 +54,7 @@ public class Config extends JSONObject {
this.put("uploadserver", uploadserver);
JSONObject dataserver = new JSONObject();
dataserver.put("port", 8080);
dataserver.put("port", 7070);
this.put("dataserver", dataserver);
JSONObject apiserver = new JSONObject();
@ -116,7 +122,7 @@ public class Config extends JSONObject {
jt.back();
break;
case '}':
loadRestData();
save();
return;
default:
throw jt.syntaxError("Expected a ',' or '}'");
@ -140,9 +146,29 @@ public class Config extends JSONObject {
if (whitelist.contains(json_ban.getString(i))) continue;
ban.add(json_ban.getString(i));
}
uploadServerConf = getJSONObject("uploadserver");
dataServerConf = getJSONObject("dataserver");
apiServerConf = getJSONObject("apiserver");
}
public boolean isBanned(String ipv4) {
return ban.contains(ipv4);
}
public List<String> getBans() {
return ban;
}
public JSONObject getUploadServerConfig() {
return uploadServerConf;
}
public JSONObject getDataServerConfig() {
return dataServerConf;
}
public JSONObject getApiServerConfig() {
return apiServerConf;
}
}

View File

@ -24,7 +24,8 @@ 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);
Logger.getLogger(getClass().getName()).log(Level.INFO, "API Request by " + request.getHeader("User-Agent") + " " + request.getRemoteAddr() + "@" + s);
Termbin.getAccesslog().log(Level.INFO, request.getRemoteAddr() + " - - " + request.getHeader("User-Agent") + " - " + s);
if (Termbin.getConfig().isBanned(request.getRemoteAddr())) {
request.setHandled(true);
@ -53,7 +54,7 @@ public class APIHandler extends AbstractHandler {
int n = httpServletRequest.getInputStream().read(buff);
if (n < 0) break;
baos.write(buff, 0, n);
if (baos.size() > 1024 * 1024 * 2) {// 2 MB
if (baos.size() > 1024 * Termbin.getConfig().getInt("maxkb")) {
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");

View File

@ -21,7 +21,8 @@ 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);
Logger.getLogger(getClass().getName()).log(Level.INFO, "API Request by " + request.getHeader("User-Agent") + " " + request.getRemoteAddr() + "@" + s);
Termbin.getAccesslog().log(Level.INFO, request.getRemoteAddr() + " - - " + request.getHeader("User-Agent") + " - " + s);
if (Termbin.getConfig().isBanned(request.getRemoteAddr())) {
request.setHandled(true);
@ -37,6 +38,8 @@ public class DataHandler extends AbstractHandler {
boolean found = false;
httpServletResponse.setStatus(HttpServletResponse.SC_OK);
while (rs.next()) {
if ((((System.currentTimeMillis() / 1000) - rs.getFloat("timestamp")) / 60 / 60) > Termbin.getConfig().getInt("uploadlifetime"))
break;
found = true;
httpServletResponse.setContentType(rs.getString("filetype"));
if (rs.getString("filetype").equals("text/plain")) {
@ -49,12 +52,14 @@ public class DataHandler extends AbstractHandler {
if (!found) {
httpServletResponse.setStatus(HttpServletResponse.SC_NOT_FOUND);
httpServletResponse.setContentType("text/html");
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.setContentType("text/html");
httpServletResponse.getOutputStream().write("<html><body><img src='https://http.cat/500'/></body></html>".getBytes("UTF-8"));
}

View File

@ -17,16 +17,21 @@ import java.util.logging.Logger;
*/
public class UploadServer {
private ServerSocket listener;
private int clientNumber = 1;
public UploadServer(String ipv4, int port) throws IOException {
Logger.getLogger("Main").log(Level.INFO, "Starting...");
int clientNumber = 1;
ServerSocket listener = new ServerSocket(port);
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.");
}
public void start() throws IOException {
try {
while (true) {
Socket socketOfServer = listener.accept();
@ -53,7 +58,7 @@ public class UploadServer {
Logger.getLogger(getClass().getName()).log(Level.SEVERE, null, e);
}
Logger.getLogger(getClass().getName()).log(Level.INFO, "opened " + client + " at " + socketOfServer.getLocalAddress() + ":" + socketOfServer.getLocalPort());
Termbin.getAccesslog().log(Level.INFO, clientIP + " - - socket " + socketOfServer.getLocalPort());
if (Termbin.getConfig().isBanned(clientIP)) {
Logger.getLogger(getClass().getName()).log(Level.INFO, "closed " + client + " with error banned");
try {
@ -77,7 +82,7 @@ public class UploadServer {
int n = socketOfServer.getInputStream().read(buff);
if (n < 0) break;
baos.write(buff, 0, n);
if (baos.size() > 1024 * 1024 * 2) {// 2 MB
if (baos.size() > 1024 * Termbin.getConfig().getInt("maxkb")) {// 2 MB
Logger.getLogger(getClass().getName()).log(Level.INFO, "closed " + client + " with file to big");
os.write("File to big!");
os.newLine();

View File

@ -5,14 +5,14 @@ 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;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import java.util.logging.*;
/**
* Created by gurkengewuerz.de on 02.07.2017.
@ -21,74 +21,94 @@ public class Termbin {
private static Database db;
private static Config conf;
private static final Logger accesslog = Logger.getLogger("Accesslog");
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);
public static void main(String args[]) throws Exception {
String settingsFile = "." + File.separator + "settings.json";
if (args.length >= 1) {
settingsFile = args[0];
}
File f = new File(settingsFile);
conf = new Config(f);
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 = () -> {
FileHandler fh = new FileHandler(conf.getString("accesslog") + ".%u.log", 5242880, 5, true);
// FileHandler fh = new FileHandler(conf.getString("accesslog") + ".log", true);
SimpleFormatter sf = new SimpleFormatter();
fh.setFormatter(sf);
accesslog.setUseParentHandlers(false);
accesslog.addHandler(fh);
CountDownLatch lock = new CountDownLatch(3);
Thread uploadServerThread = new Thread(() -> {
try {
JSONObject uploadServerConf = conf.getJSONObject("uploadserver");
new UploadServer(uploadServerConf.getString("bind"), uploadServerConf.getInt("port"));
UploadServer uploadServer = new UploadServer(conf.getUploadServerConfig().getString("bind"), conf.getUploadServerConfig().getInt("port"));
lock.countDown();
uploadServer.start();
} catch (IOException e) {
Logger.getLogger(Termbin.class.getName()).log(Level.SEVERE, null, e);
}
};
Thread uploadServerThread = new Thread(uploadServerTask);
});
uploadServerThread.start();
Runnable dataServerTask = () -> {
Thread dataServerThread = new Thread(() -> {
try {
JSONObject dataServerConf = conf.getJSONObject("dataserver");
Server dataServer = new Server(dataServerConf.getInt("port"));
Server dataServer = new Server(conf.getDataServerConfig().getInt("port"));
dataServer.setHandler(new DataHandler());
dataServer.start();
dataServer.join();
lock.countDown();
} catch (Exception e) {
Logger.getLogger(Termbin.class.getName()).log(Level.SEVERE, null, e);
}
};
Thread dataServerThread = new Thread(dataServerTask);
});
dataServerThread.start();
Runnable apiServerTask = () -> {
Thread apiServerThread = new Thread(() -> {
try {
JSONObject apiServerConf = conf.getJSONObject("apiserver");
Server apiServer = new Server(apiServerConf.getInt("port"));
Server apiServer = new Server(conf.getApiServerConfig().getInt("port"));
apiServer.setHandler(new APIHandler());
apiServer.start();
apiServer.join();
lock.countDown();
} 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
boolean counts = lock.await(4, TimeUnit.SECONDS);
if (counts) {
String cr = System.getProperty("line.separator");
String stringInfo = cr +
"########################################" + cr +
" Configfile: " + f.getAbsolutePath() + cr +
" Domain: " + conf.getString("domain") + cr +
" Upload Lifetime: " + conf.getInt("uploadlifetime") + "h" + cr +
" Upload Size: " + conf.getInt("maxkb") + "kb" + cr +
" Bans listed: " + conf.getBans().size() + cr +
" Accesslog: " + conf.getString("accesslog") + cr +
" Upload Server: " + conf.getUploadServerConfig().getString("bind") + ":" + conf.getUploadServerConfig().getInt("port") + cr +
" API Server: 0.0.0.0:" + conf.getApiServerConfig().getInt("port") + cr +
" Data Server: 0.0.0.0:" + conf.getDataServerConfig().getInt("port") + cr +
"########################################" + cr;
Logger.getLogger(Termbin.class.getName()).log(Level.INFO, stringInfo);
Runtime.getRuntime().addShutdownHook(new Thread(() -> {
for (Handler h : accesslog.getHandlers()) {
h.close();
}
}));
} else {
Logger.getLogger(Termbin.class.getName()).log(Level.SEVERE, "Servers couldn't started!");
System.exit(1);
}
}
public static Database getDatabase() {
@ -100,8 +120,12 @@ public class Termbin {
return conf;
}
public static Logger getAccesslog() {
return accesslog;
}
public static String upload(String ip, String text, byte[] rawData, FileType fileType) throws SQLException {
String answerID = HashUtils.getSha256(System.currentTimeMillis() + "").substring(0, 8);
String answerID = HashUtils.getSha256(System.currentTimeMillis() + ip).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));
@ -110,9 +134,12 @@ public class Termbin {
if (fileType.equals(FileType.TXT)) {
ps.setString(5, text);
ps.setBytes(6, null);
getAccesslog().log(Level.INFO, ip + " - - upload with text " + " id#" + answerID);
} else {
ps.setString(5, null);
ps.setBytes(6, rawData);
getAccesslog().log(Level.INFO, ip + "upload with " + rawData.length + " bytes " + " id#" + answerID);
}
ps.execute();