diff --git a/src/main/java/ctbrec/recorder/server/AbstractCtbrecServlet.java b/src/main/java/ctbrec/recorder/server/AbstractCtbrecServlet.java new file mode 100644 index 00000000..1c0085b6 --- /dev/null +++ b/src/main/java/ctbrec/recorder/server/AbstractCtbrecServlet.java @@ -0,0 +1,47 @@ +package ctbrec.recorder.server; + +import java.io.BufferedReader; +import java.io.IOException; +import java.security.InvalidKeyException; +import java.security.NoSuchAlgorithmException; + +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; + +import ctbrec.Config; +import ctbrec.Hmac; + +public abstract class AbstractCtbrecServlet extends HttpServlet { + + boolean checkAuthentication(HttpServletRequest req, String body) throws IOException, InvalidKeyException, NoSuchAlgorithmException, IllegalStateException { + boolean authenticated = false; + if(Config.getInstance().getSettings().key != null) { + String reqParamHmac = req.getParameter("hmac"); + String httpHeaderHmac = req.getHeader("CTBREC-HMAC"); + String hmac = null; + if(reqParamHmac != null) { + hmac = reqParamHmac; + } + if(httpHeaderHmac != null) { + hmac = httpHeaderHmac; + } + + byte[] key = Config.getInstance().getSettings().key; + authenticated = Hmac.validate(body, key, hmac); + } else { + authenticated = true; + } + return authenticated; + } + + + String body(HttpServletRequest req) throws IOException { + StringBuilder body = new StringBuilder(); + BufferedReader br = req.getReader(); + String line= null; + while( (line = br.readLine()) != null ) { + body.append(line).append("\n"); + } + return body.toString().trim(); + } +} diff --git a/src/main/java/ctbrec/recorder/server/HlsServlet.java b/src/main/java/ctbrec/recorder/server/HlsServlet.java index 88631098..a36239ec 100644 --- a/src/main/java/ctbrec/recorder/server/HlsServlet.java +++ b/src/main/java/ctbrec/recorder/server/HlsServlet.java @@ -6,7 +6,6 @@ import java.io.FileNotFoundException; import java.io.IOException; import javax.servlet.ServletException; -import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @@ -18,7 +17,7 @@ import com.iheartradio.m3u8.PlaylistException; import ctbrec.Config; -public class HlsServlet extends HttpServlet { +public class HlsServlet extends AbstractCtbrecServlet { private static final transient Logger LOG = LoggerFactory.getLogger(HlsServlet.class); @@ -34,8 +33,24 @@ public class HlsServlet extends HttpServlet { File recordingsDir = new File(config.getSettings().recordingsDir); File requestedFile = new File(recordingsDir, request); + // try { + // boolean isRequestAuthenticated = checkAuthentication(req, req.getRequestURI()); + // if (!isRequestAuthenticated) { + // resp.setStatus(SC_UNAUTHORIZED); + // String response = "{\"status\": \"error\", \"msg\": \"HMAC does not match\"}"; + // resp.getWriter().write(response); + // return; + // } + // } catch (InvalidKeyException | NoSuchAlgorithmException | IllegalStateException e1) { + // resp.setStatus(SC_UNAUTHORIZED); + // String response = "{\"status\": \"error\", \"msg\": \"Authentication failed\"}"; + // resp.getWriter().write(response); + // return; + // } + if (requestedFile.getCanonicalPath().startsWith(config.getSettings().recordingsDir)) { if (requestedFile.getName().equals("playlist.m3u8")) { + try { servePlaylist(req, resp, requestedFile); } catch (ParseException | PlaylistException e) { diff --git a/src/main/java/ctbrec/recorder/server/HttpServer.java b/src/main/java/ctbrec/recorder/server/HttpServer.java index 9faaf749..8632e865 100644 --- a/src/main/java/ctbrec/recorder/server/HttpServer.java +++ b/src/main/java/ctbrec/recorder/server/HttpServer.java @@ -1,6 +1,7 @@ package ctbrec.recorder.server; import java.io.IOException; +import java.net.BindException; import org.eclipse.jetty.server.Handler; import org.eclipse.jetty.server.HttpConfiguration; @@ -82,8 +83,13 @@ public class HttpServer { holder = new ServletHolder(hlsServlet); handler.addServletWithMapping(holder, "/hls/*"); - server.start(); - server.join(); + try { + server.start(); + server.join(); + } catch (BindException e) { + LOG.error("Port {} is already in use", http.getPort(), e); + System.exit(1); + } } public static void main(String[] args) throws Exception { diff --git a/src/main/java/ctbrec/recorder/server/RecorderServlet.java b/src/main/java/ctbrec/recorder/server/RecorderServlet.java index a660b7b1..976c5b68 100644 --- a/src/main/java/ctbrec/recorder/server/RecorderServlet.java +++ b/src/main/java/ctbrec/recorder/server/RecorderServlet.java @@ -5,16 +5,12 @@ import static javax.servlet.http.HttpServletResponse.SC_INTERNAL_SERVER_ERROR; import static javax.servlet.http.HttpServletResponse.SC_OK; import static javax.servlet.http.HttpServletResponse.SC_UNAUTHORIZED; -import java.io.BufferedReader; import java.io.IOException; -import java.security.InvalidKeyException; -import java.security.NoSuchAlgorithmException; import java.time.Instant; import java.util.Iterator; import java.util.List; import javax.servlet.ServletException; -import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @@ -24,14 +20,12 @@ import org.slf4j.LoggerFactory; import com.squareup.moshi.JsonAdapter; import com.squareup.moshi.Moshi; -import ctbrec.Config; -import ctbrec.Hmac; import ctbrec.InstantJsonAdapter; import ctbrec.Model; import ctbrec.Recording; import ctbrec.recorder.Recorder; -public class RecorderServlet extends HttpServlet { +public class RecorderServlet extends AbstractCtbrecServlet { private static final transient Logger LOG = LoggerFactory.getLogger(RecorderServlet.class); @@ -129,31 +123,6 @@ public class RecorderServlet extends HttpServlet { } } - private boolean checkAuthentication(HttpServletRequest req, String body) throws IOException, InvalidKeyException, NoSuchAlgorithmException, IllegalStateException { - boolean authenticated = false; - if(Config.getInstance().getSettings().key != null) { - if(req.getHeader("CTBREC-HMAC") == null) { - authenticated = false; - } - - byte[] key = Config.getInstance().getSettings().key; - authenticated = Hmac.validate(body, key, req.getHeader("CTBREC-HMAC")); - } else { - authenticated = true; - } - return authenticated; - } - - private String body(HttpServletRequest req) throws IOException { - StringBuilder body = new StringBuilder(); - BufferedReader br = req.getReader(); - String line= null; - while( (line = br.readLine()) != null ) { - body.append(line).append("\n"); - } - return body.toString().trim(); - } - private static class Request { public String action; public Model model;