Created abstract servlet to handle HMAC
Implemented HMAC authentication in HlsServlet, but disabled it, because it does not make sense, if you want to support streaming. Also, the path of recordings can only be obtained by guessing without the HMAC key.
This commit is contained in:
parent
aaaca23427
commit
32172fe203
|
@ -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();
|
||||
}
|
||||
}
|
|
@ -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) {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue