From b63211eafe8329ad6aa5ae7a747a7b759b818cca Mon Sep 17 00:00:00 2001 From: Brian Engert Date: Sat, 4 Jun 2022 12:02:21 -0500 Subject: [PATCH] finishing up the first draft of domain token auth. --- .classpath | 8 +- build.xml | 152 ++++++++---------- src/com/tivo/kmttg/gui/dialog/configMain.java | 49 +++++- src/com/tivo/kmttg/main/config.java | 33 +++- src/com/tivo/kmttg/rpc/GetDomainToken.java | 45 ++++-- src/com/tivo/kmttg/rpc/Remote.java | 18 ++- version | 2 +- 7 files changed, 202 insertions(+), 105 deletions(-) diff --git a/.classpath b/.classpath index bcc3f13f..165e217b 100644 --- a/.classpath +++ b/.classpath @@ -2,8 +2,14 @@ - + + + + + + + diff --git a/build.xml b/build.xml index 1357d80b..fb977197 100644 --- a/build.xml +++ b/build.xml @@ -1,53 +1,52 @@ - - - - - - - - - - + + + + + + + + + + - - + + + + - - - + + - - - - + + - - + + + + - - - - - - - - - - - - - + + + + + + + + + + + @@ -55,52 +54,41 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/com/tivo/kmttg/gui/dialog/configMain.java b/src/com/tivo/kmttg/gui/dialog/configMain.java index 6ae582ca..5d3b2229 100755 --- a/src/com/tivo/kmttg/gui/dialog/configMain.java +++ b/src/com/tivo/kmttg/gui/dialog/configMain.java @@ -66,6 +66,7 @@ import com.tivo.kmttg.main.jobData; import com.tivo.kmttg.main.jobMonitor; import com.tivo.kmttg.main.mdns; +import com.tivo.kmttg.rpc.GetDomainToken; import com.tivo.kmttg.task.autotune; import com.tivo.kmttg.task.custom; import com.tivo.kmttg.util.debug; @@ -81,6 +82,7 @@ public class configMain { private static Button add = null; private static Button del = null; + private static Button domain_token = null; private static Button share_add = null; private static Button share_del = null; private static Button OK = null; @@ -433,6 +435,29 @@ private static void delCB() { } } + // Callback for tivo del button + private static void domainTokenCB() { + log.warn("Refreshing token"); + Thread t = new Thread() + { + public void run() { + GetDomainToken getDT = new GetDomainToken(); + try { + getDT.getToken(); + } catch (Exception e) { + log.error("Failed to get domain token. Check your tivo.com username or password."); + return; + } + if (config.isDomainTokenExpired()) { + log.error("Failed to get domain token. Check your tivo.com username or password."); + return; + } + log.warn("Successfully got token"); + } + }; + t.start(); + } + // Callback for share del button private static void share_delCB() { debug.print(""); @@ -2251,6 +2276,7 @@ private static void create(Stage frame) { add = new Button(); del = new Button(); + domain_token = new Button(); share_add = new Button(); share_del = new Button(); Label VRDexe_label = new Label(); @@ -2403,6 +2429,14 @@ public void handle(ActionEvent e) { } }); + domain_token.setText("Refresh Token"); + domain_token.setOnAction(new EventHandler() { + public void handle(ActionEvent e) { + domainTokenCB(); + } + }); + + share_add.setText("ADD"); share_add.setOnAction(new EventHandler() { public void handle(ActionEvent e) { @@ -2995,6 +3029,8 @@ public void handle(MouseEvent mouseEvent) { gy++; tivo_panel.add(tivo_password_label, 0, gy); tivo_panel.add(tivo_password, 1, gy); + tivo_panel.add(domain_token, 4, gy); + // autotune panel GridPane autotune_panel = new GridPane(); @@ -3616,7 +3652,8 @@ public static void setToolTips() { autotune_chan2.setTooltip(getToolTip("autotune_chan2")); autotune_tivoName.setTooltip(getToolTip("autotune_tivoName")); add.setTooltip(getToolTip("add")); - del.setTooltip(getToolTip("del")); + del.setTooltip(getToolTip("del")); + domain_token.setTooltip(getToolTip("domain_token")); share_add.setTooltip(getToolTip("share_add")); share_del.setTooltip(getToolTip("share_del")); remove_tivo.setTooltip(getToolTip("remove_tivo")); @@ -3810,9 +3847,13 @@ else if (component.equals("del")) { text = "DEL
"; text += "Remove currently selected entry in Tivos list."; } - else if (component.equals("share_add")) { - text = "ADD
"; - text += "Add specified Share Name and associated Share Directory to Shares list."; + else if (component.equals("del")) { + text = "DEL
"; + text += "Remove currently selected entry in Tivos list."; + } + else if (component.equals("domain_token")) { + text = "Refresh Domain token
"; + text += "Force a refresh of your domain token. This uses the tivo.com username and password."; } else if (component.equals("share_del")) { text = "DEL
"; diff --git a/src/com/tivo/kmttg/main/config.java b/src/com/tivo/kmttg/main/config.java index e3d4a391..8947c409 100644 --- a/src/com/tivo/kmttg/main/config.java +++ b/src/com/tivo/kmttg/main/config.java @@ -24,6 +24,7 @@ import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; +import java.util.Date; import java.util.Enumeration; import java.util.Hashtable; import java.util.Iterator; @@ -39,7 +40,7 @@ import com.tivo.kmttg.httpserver.kmttgServer; public class config { - public static String kmttg = "kmttg v2.4p"; + public static String kmttg = "kmttg v2.5-l"; // encoding related public static String encProfDir = ""; @@ -222,6 +223,8 @@ public class config { public static int middlemind_port = 443; private static String tivo_username = ""; private static String tivo_password = ""; + private static String tivo_domain_token = ""; + private static long tivo_domain_token_expires = 0; // httpserver related public static int httpserver_enable = 0; @@ -659,6 +662,24 @@ public static String getTivoPassword() { public static void setTivoPassword(String password) { tivo_password = password; } + + public static String getDomainToken() { + if (tivo_domain_token.length() == 0 && !isDomainTokenExpired()) + return null; + return tivo_domain_token; + } + + public static boolean isDomainTokenExpired() { + System.out.println("DomainToken: " + tivo_domain_token_expires); + System.out.println("now: " + (new Date()).getTime()); + return (new Date()).getTime() > tivo_domain_token_expires; + } + + public static void setDomainToken(String token, long expires) { + tivo_domain_token = token; + tivo_domain_token_expires = expires; + } + private static void defineDefaults() { debug.print(""); @@ -1135,6 +1156,12 @@ private static Boolean parseIni(String config) { if (key.equals("tivo_password")) { tivo_password = line; } + if (key.equals("tivo_domain_token")) { + tivo_domain_token = line; + } + if (key.equals("tivo_domain_token_expires")) { + tivo_domain_token_expires = Long.parseLong(string.removeLeadingTrailingSpaces(line)); + } /*if (key.equals("pyTivo_config")) { pyTivo_config = line; } @@ -1470,6 +1497,10 @@ public static Boolean save() { ofp.write("\n" + tivo_password + "\n\n"); + ofp.write("\n" + tivo_domain_token + "\n\n"); + + ofp.write("\n" + tivo_domain_token_expires + "\n\n"); + //ofp.write("\n" + pyTivo_config + "\n\n"); //ofp.write("\n" + pyTivo_host + "\n\n"); diff --git a/src/com/tivo/kmttg/rpc/GetDomainToken.java b/src/com/tivo/kmttg/rpc/GetDomainToken.java index 0f28828d..b828efdb 100644 --- a/src/com/tivo/kmttg/rpc/GetDomainToken.java +++ b/src/com/tivo/kmttg/rpc/GetDomainToken.java @@ -1,7 +1,11 @@ package com.tivo.kmttg.rpc; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; import java.net.URI; +import java.nio.ByteBuffer; import org.apache.hc.client5.http.classic.methods.HttpGet; import org.apache.hc.core5.http.ClassicHttpRequest; @@ -35,7 +39,8 @@ public GetDomainToken() { public Cookie getToken() throws Exception { HttpGet httpget = new HttpGet("https://online.tivo.com/start/watch/JustForMeTVE?forceAuth=1"); CloseableHttpResponse response = (CloseableHttpResponse) httpClient.execute(httpget); - String responseBody = new String(response.getEntity().getContent().readAllBytes()); + + String responseBody = readResponseBody(response); //System.out.println(responseBody); Pattern pattern = Pattern.compile("name=\\\"SAMLRequest\\\" value=\\\"([^\\\"]*)\\\"", Pattern.MULTILINE); @@ -64,7 +69,7 @@ public Cookie getToken() throws Exception { URI redirectUrl = redirectLocations.get(redirectLocations.size()-1); - responseBody = new String(response.getEntity().getContent().readAllBytes()); + responseBody = readResponseBody(response); //System.out.println(responseBody); pattern = Pattern.compile("auraConfig = ([^;]*);", Pattern.MULTILINE); @@ -95,7 +100,7 @@ public Cookie getToken() throws Exception { .build(); response = (CloseableHttpResponse) httpClient.execute(login); - responseBody = new String(response.getEntity().getContent().readAllBytes()); + responseBody = readResponseBody(response); //System.out.println(responseBody); JSONObject loginResponse = new JSONObject(responseBody); if (! (loginResponse.get("events") instanceof JSONArray) ) { @@ -106,7 +111,7 @@ public Cookie getToken() throws Exception { httpget = new HttpGet(frontDoor); response = (CloseableHttpResponse) httpClient.execute(httpget); - responseBody = new String(response.getEntity().getContent().readAllBytes()); + responseBody = readResponseBody(response); pattern = Pattern.compile("window\\.location\\.href=\\\"([^\\\"]*)\\\"", Pattern.MULTILINE); matcher = pattern.matcher(responseBody); @@ -115,7 +120,7 @@ public Cookie getToken() throws Exception { httpget = new HttpGet("https://tivoidp.tivo.com" + frontDoorResponse); response = (CloseableHttpResponse) httpClient.execute(httpget); - responseBody = new String(response.getEntity().getContent().readAllBytes()); + responseBody = readResponseBody(response); pattern = Pattern.compile("name=\\\"SAMLResponse\\\" value=\\\"([^\\\"]*)\\\"", Pattern.MULTILINE); matcher = pattern.matcher(responseBody); @@ -133,19 +138,31 @@ public Cookie getToken() throws Exception { .build(); response = (CloseableHttpResponse) httpClient.execute(login); - responseBody = new String(response.getEntity().getContent().readAllBytes()); - - - for (Cookie cookie : this.cookieStore.getCookies()) { - if (cookie.getName().equals("domainToken")) { - return cookie; - } - } - return null; + responseBody = readResponseBody(response); + for (Cookie cookie : this.cookieStore.getCookies()) { + if (cookie.getName().equals("domainToken")) { + config.setDomainToken(cookie.getValue(), cookie.getExpiryDate().getTime()); + config.save(); + return cookie; + } + } + return null; } + private String readResponseBody(CloseableHttpResponse response) throws UnsupportedOperationException, IOException { + ByteBuffer bb = ByteBuffer.allocate(1024*1024); + InputStream is = response.getEntity().getContent(); + byte[] data = new byte[4096]; + int read = 0; + + while ((read = is.read(data, 0, data.length)) != -1) { + bb.put(data, 0, read); + } + return new String(bb.array()); + } public static void main(String args[]) throws Exception { + //config.parse(); GetDomainToken dt = new GetDomainToken(); Cookie cookie = dt.getToken(); System.out.println(cookie); diff --git a/src/com/tivo/kmttg/rpc/Remote.java b/src/com/tivo/kmttg/rpc/Remote.java index eca6177a..4296125e 100755 --- a/src/com/tivo/kmttg/rpc/Remote.java +++ b/src/com/tivo/kmttg/rpc/Remote.java @@ -176,17 +176,31 @@ public String bodyId_get() { */ private Boolean Auth_web() { try { - if (config.getTivoUsername() == null) { + if (config.getTivoUsername() == null || config.getTivoPassword() == null) { log.error("tivo.com username & password not set in kmttg or pyTivo config"); return false; } + if (config.isDomainTokenExpired() || config.getDomainToken() == null) { + log.warn("Domain Token expired refreshing token"); + GetDomainToken getDT = new GetDomainToken(); + try { + getDT.getToken(); + } catch (Exception e) { + log.error("Failed to get domain token. Check your tivo.com username or password."); + return false; + } + if (config.isDomainTokenExpired()) { + log.error("Failed to get domain token. Check your tivo.com username or password."); + return false; + } + } JSONObject credential = new JSONObject(); JSONObject h = new JSONObject(); JSONObject domainToken = new JSONObject(); domainToken.put("domain", "tivo"); domainToken.put("type", "domainToken"); - domainToken.put("token", config.getTivoUsername()); + domainToken.put("token", config.getDomainToken()); credential.put("type", "domainTokenCredential"); credential.put("domainToken", domainToken); diff --git a/version b/version index 234cd05e..2e3049c8 100644 --- a/version +++ b/version @@ -1 +1 @@ -v2.4p +v2.5-l