jsiegenthaler / homebridge-eosstb

A homebridge plugin for the EOS set-top box as used by Sunrise, Telenet, Ziggo, Virgin Media and maybe more in various countries on the Horizon Go (HGO) platform
https://github.com/jsiegenthaler/homebridge-eosstb
32 stars 4 forks source link

Failing to complete the login process on Virginmedia #8

Closed jbroomfi closed 3 years ago

jbroomfi commented 3 years ago

Describe Your Problem: I subscribe to VirginMedia in the UK and have two TiVo boxes installed both of which are connected to the internal network. I found your HB plugin and thought I'd give it a try but looking in the HB logs the plugin is not completing the login process at Step 3. I can see in the logs an HTTP Status code of 405 (line 143) which suggests the method being called is not allowed.

Your plugin looks very promising with more functionality over channels, volume level and integration with the guide.

Full Disclosure I do have other plugins running on the Homebridge server (Camera UI, Tuya, Denon TV, Bravia and Rpi) but as far as I can tell, there are no conflicts. If needed I can setup eosstb on a docker instance and run it in isolation to be sure though.

I have inserted the filtered HB log file containing just the log lines that pertain to the Plugin below.

Logs:

[20/02/2021, 16:19:26] [Virginmedia TiVo Service] Creating eosstb GB session...
[20/02/2021, 16:19:26] [Virginmedia TiVo Service] Step 1: get authentication details from https://web-api-prod-obo.horizon.tv/oesp/v4/GB/eng/web/authorization
[20/02/2021, 16:19:26] [Virginmedia TiVo Service] end of getSessionGB, no session created
[20/02/2021, 16:19:26] [Virginmedia TiVo Service] +++INTERCEPTOR HTTP REQUEST: 
Method: get 
URL: https://web-api-prod-obo.horizon.tv/oesp/v4/GB/eng/web/authorization 
BaseURL: undefined 
Headers: {
  common: { Accept: 'application/json, text/plain, */*' },
  delete: {},
  get: {},
  head: {},
  post: { 'Content-Type': 'application/x-www-form-urlencoded' },
  put: { 'Content-Type': 'application/x-www-form-urlencoded' },
  patch: { 'Content-Type': 'application/x-www-form-urlencoded' }
} 
WithCredentials: true
[20/02/2021, 16:19:27] [Virginmedia TiVo Service] +++INTERCEPTED SESSION COOKIEJAR:
 Promise { [] }
[20/02/2021, 16:19:27] [Virginmedia TiVo Service] +++INTERCEPTED HTTP RESPONSE: 200 OK 
Headers: {
  'access-control-allow-credentials': 'true',
  'access-control-expose-headers': 'X-DRM-Device-ID,X-OESP-Version,X-OESP-Session-Response,Warning',
  'content-type': 'application/json;charset=UTF-8',
  server: 'openresty',
  'x-cache-debug': 'MISS',
  'x-oesp-version': '232.0.2.22',
  'x-request-id': '/GB/eng/web/authorization - 1b00a63e-8844-4b17-a058-d98326b0c632',
  'x-edgeconnect-midmile-rtt': '0',
  'x-edgeconnect-origin-mex-latency': '15',
  date: 'Sat, 20 Feb 2021 16:19:27 GMT',
  'content-length': '1495',
  connection: 'close',
  'access-control-allow-origin': 'https://www.horizon.tv'
}
[20/02/2021, 16:19:27] [Virginmedia TiVo Service] +++INTERCEPTED SESSION COOKIEJAR:
 Promise { [] }
[20/02/2021, 16:19:27] [Virginmedia TiVo Service] Step 1 got apiAuthorizationUrl response
[20/02/2021, 16:19:27] [Virginmedia TiVo Service] Step 1 results: authState 86e329ee-c664-49d3-babf-28aad91032e6
[20/02/2021, 16:19:27] [Virginmedia TiVo Service] Step 1 results: authAuthorizationUri https://id.virginmedia.com/oidc/authorize?response_type=code&state=86e329ee-c664-49d3-babf-28aad91032e6&nonce=170a1d3d-aa59-4b10-b2eb-8846cffa5d7e&client_id=9b471ffe-7ff5-497b-9059-8dcb7c0d66f5&redirect_uri=https%3A%2F%2Fvirgintvgo.virginmedia.com%2Fobo_en%2Flogin_success&claims=%7B%22id_token%22%3A%7B%22ukHouseholdId%22%3Anull%7D%7D
[20/02/2021, 16:19:27] [Virginmedia TiVo Service] Step 1 response.status: 200 OK
[20/02/2021, 16:19:27] [Virginmedia TiVo Service] Step 1 results: authValidtyToken eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOiJvZXNwYXBpIiwiZXhwIjoiMTYxMzgzODE0NzMxMSIsImxnaTpub25jZSI6IjE3MGExZDNkLWFhNTktNGIxMC1iMmViLTg4NDZjZmZhNWQ3ZSIsImxnaTpzdGF0ZSI6Ijg2ZTMyOWVlLWM2NjQtNDlkMy1iYWJmLTI4YWFkOTEwMzJlNiJ9.2JK5ADg83Gb-9XM3xgADBBb6bkif1px4Lv9WJX6DCPM
[20/02/2021, 16:19:27] [Virginmedia TiVo Service] Step 2 get AUTH cookie from https://id.virginmedia.com/oidc/authorize?response_type=code&state=86e329ee-c664-49d3-babf-28aad91032e6&nonce=170a1d3d-aa59-4b10-b2eb-8846cffa5d7e&client_id=9b471ffe-7ff5-497b-9059-8dcb7c0d66f5&redirect_uri=https%3A%2F%2Fvirgintvgo.virginmedia.com%2Fobo_en%2Flogin_success&claims=%7B%22id_token%22%3A%7B%22ukHouseholdId%22%3Anull%7D%7D
[20/02/2021, 16:19:27] [Virginmedia TiVo Service] +++INTERCEPTOR HTTP REQUEST: 
Method: get 
URL: https://id.virginmedia.com/oidc/authorize?response_type=code&state=86e329ee-c664-49d3-babf-28aad91032e6&nonce=170a1d3d-aa59-4b10-b2eb-8846cffa5d7e&client_id=9b471ffe-7ff5-497b-9059-8dcb7c0d66f5&redirect_uri=https%3A%2F%2Fvirgintvgo.virginmedia.com%2Fobo_en%2Flogin_success&claims=%7B%22id_token%22%3A%7B%22ukHouseholdId%22%3Anull%7D%7D 
BaseURL: undefined 
Headers: {
  common: { Accept: 'application/json, text/plain, */*' },
  delete: {},
  get: {},
  head: {},
  post: { 'Content-Type': 'application/x-www-form-urlencoded' },
  put: { 'Content-Type': 'application/x-www-form-urlencoded' },
  patch: { 'Content-Type': 'application/x-www-form-urlencoded' }
} 
WithCredentials: true
[20/02/2021, 16:19:27] [Virginmedia TiVo Service] +++INTERCEPTED SESSION COOKIEJAR:
 Promise { [] }
[20/02/2021, 16:19:27] [Virginmedia TiVo Service] +++INTERCEPTOR HTTP REQUEST: 
Method: get 
URL: https://id.virginmedia.com/sign-in/?protocol=oidc 
BaseURL: undefined 
Headers: {
  common: { Accept: 'application/json, text/plain, */*' },
  delete: {},
  get: {},
  head: {},
  post: { 'Content-Type': 'application/x-www-form-urlencoded' },
  put: { 'Content-Type': 'application/x-www-form-urlencoded' },
  patch: { 'Content-Type': 'application/x-www-form-urlencoded' },
  Accept: 'application/json, text/plain, */*',
  'User-Agent': 'axios/0.21.1'
} 
WithCredentials: true
[20/02/2021, 16:19:27] [Virginmedia TiVo Service] Step 3 post login to https://id.virginmedia.com/sign-in/?protocol=oidc
[20/02/2021, 16:19:27] [Virginmedia TiVo Service] +++INTERCEPTOR HTTP REQUEST: 
Method: post 
URL: https://id.virginmedia.com/sign-in/?protocol=oidc 
BaseURL: undefined 
Headers: {
  common: { Accept: 'application/json, text/plain, */*' },
  delete: {},
  get: {},
  head: {},
  post: { 'Content-Type': 'application/x-www-form-urlencoded' },
  put: { 'Content-Type': 'application/x-www-form-urlencoded' },
  patch: { 'Content-Type': 'application/x-www-form-urlencoded' }
} 
WithCredentials: true
[20/02/2021, 16:19:27] [Virginmedia TiVo Service] Step 3 Unable to login, http error: Error: Request failed with status code 405
    at createError (/usr/lib/node_modules/homebridge-eosstb/node_modules/axios/lib/core/createError.js:16:15)
    at settle (/usr/lib/node_modules/homebridge-eosstb/node_modules/axios/lib/core/settle.js:17:12)
    at /usr/lib/node_modules/homebridge-eosstb/node_modules/axios-cookiejar-support/lib/interceptors/response.js:83:25
    at new Promise (<anonymous>)
    at responseInterceptor (/usr/lib/node_modules/homebridge-eosstb/node_modules/axios-cookiejar-support/lib/interceptors/response.js:82:9)
    at /usr/lib/node_modules/homebridge-eosstb/node_modules/axios-cookiejar-support/lib/index.js:130:67
    at processTicksAndRejections (internal/process/task_queues.js:93:5) {
  config: {
    url: 'https://id.virginmedia.com/sign-in/?protocol=oidc',
    method: 'post',
    data: '[XXXXXXX%40XXXXXXXXXXX.co.uk]&credential=[XXXXXXXXXXX]',
    headers: {
      Accept: 'application/json, text/plain, */*',
      'Content-Type': 'application/x-www-form-urlencoded',
      Cookie: 'ULM-JSESSIONID=9C70A57B0040B74880F4747C5D7D7841',
      'User-Agent': 'axios/0.21.1',
      'Content-Length': 54
    },
    params: 'protocol=oidc&rememberme=true',
    transformRequest: [ [Function: transformRequest] ],
    transformResponse: [ [Function: transformResponse] ],
    timeout: 0,
    withCredentials: true,
    adapter: [Function: httpAdapter],
    xsrfHeaderName: 'X-XSRF-TOKEN',
    maxContentLength: -1,
    maxBodyLength: -1,
    maxRedirects: 0,
    jar: CookieJar {
      rejectPublicSuffixes: true,
      enableLooseMode: false,
      allowSpecialUseDomain: false,
      store: { idx: {
        'virginmedia.com': {
          '/': {
            'ULM-JSESSIONID': Cookie="ULM-JSESSIONID=9C70A57B0040B74880F4747C5D7D7841; Domain=virginmedia.com; Path=/; Secure; HttpOnly; hostOnly=false; aAge=107ms; cAge=318ms"
          }
        }
      } },
      prefixSecurity: 'silent',
      _cloneSync: [Function (anonymous)],
      _importCookiesSync: [Function (anonymous)],
      getCookiesSync: [Function (anonymous)],
      getCookieStringSync: [Function (anonymous)],
      getSetCookieStringsSync: [Function (anonymous)],
      removeAllCookiesSync: [Function (anonymous)],
      setCookieSync: [Function (anonymous)],
      serializeSync: [Function (anonymous)]
    },
    ignoreCookieErrors: true,
    validateStatus: [Function: validateStatus]
  },
  request: <ref *1> ClientRequest {
    _events: [Object: null prototype] {
      error: [Function: handleRequestError],
      prefinish: [Function: requestOnPrefinish]
    },
    _eventsCount: 2,
    _maxListeners: undefined,
    outputData: [],
    outputSize: 0,
    writable: true,
    destroyed: false,
    _last: true,
    chunkedEncoding: false,
    shouldKeepAlive: false,
    _defaultKeepAlive: true,
    useChunkedEncodingByDefault: true,
    sendDate: false,
    _removedConnection: false,
    _removedContLen: false,
    _removedTE: false,
    _contentLength: 54,
    _hasBody: true,
    _trailer: '',
    finished: true,
    _headerSent: true,
    socket: TLSSocket {
      _tlsOptions: [Object],
      _secureEstablished: true,
      _securePending: false,
      _newSessionPending: false,
      _controlReleased: true,
      secureConnecting: false,
      _SNICallback: null,
      servername: 'id.virginmedia.com',
      alpnProtocol: false,
      authorized: true,
      authorizationError: null,
      encrypted: true,
      _events: [Object: null prototype],
      _eventsCount: 10,
      connecting: false,
      _hadError: false,
      _parent: null,
      _host: 'id.virginmedia.com',
      _readableState: [ReadableState],
      _maxListeners: undefined,
      _writableState: [WritableState],
      allowHalfOpen: false,
      _sockname: null,
      _pendingData: null,
      _pendingEncoding: '',
      server: undefined,
      _server: null,
      ssl: [TLSWrap],
      _requestCert: true,
      _rejectUnauthorized: true,
      parser: null,
      _httpMessage: [Circular *1],
      [Symbol(res)]: [TLSWrap],
      [Symbol(verified)]: true,
      [Symbol(pendingSession)]: null,
      [Symbol(async_id_symbol)]: 544,
      [Symbol(kHandle)]: [TLSWrap],
      [Symbol(kSetNoDelay)]: false,
      [Symbol(lastWriteQueueSize)]: 0,
      [Symbol(timeout)]: null,
      [Symbol(kBuffer)]: null,
      [Symbol(kBufferCb)]: null,
      [Symbol(kBufferGen)]: null,
      [Symbol(kCapture)]: false,
      [Symbol(kBytesRead)]: 0,
      [Symbol(kBytesWritten)]: 0,
      [Symbol(connect-options)]: [Object],
      [Symbol(RequestTimeout)]: undefined
    },
    _header: 'POST /sign-in/?protocol=oidc&0=protocol%3Doidc%26rememberme%3Dtrue HTTP/1.1\r\n' +
      'Accept: application/json, text/plain, */*\r\n' +
      'Content-Type: application/x-www-form-urlencoded\r\n' +
      'Cookie: ULM-JSESSIONID=9C70A57B0040B74880F4747C5D7D7841\r\n' +
      'User-Agent: axios/0.21.1\r\n' +
      'Content-Length: 54\r\n' +
      'Host: id.virginmedia.com\r\n' +
      'Connection: close\r\n' +
      '\r\n',
    _keepAliveTimeout: 0,
    _onPendingData: [Function: noopPendingOutput],
    agent: Agent {
      _events: [Object: null prototype],
      _eventsCount: 2,
      _maxListeners: undefined,
      defaultPort: 443,
      protocol: 'https:',
      options: [Object],
      requests: {},
      sockets: [Object],
      freeSockets: {},
      keepAliveMsecs: 1000,
      keepAlive: false,
      maxSockets: Infinity,
      maxFreeSockets: 256,
      scheduling: 'fifo',
      maxTotalSockets: Infinity,
      totalSocketCount: 1,
      maxCachedSessions: 100,
      _sessionCache: [Object],
      [Symbol(kCapture)]: false
    },
    socketPath: undefined,
    method: 'POST',
    maxHeaderSize: undefined,
    insecureHTTPParser: undefined,
    path: '/sign-in/?protocol=oidc&0=protocol%3Doidc%26rememberme%3Dtrue',
    _ended: true,
    res: IncomingMessage {
      _readableState: [ReadableState],
      _events: [Object: null prototype],
      _eventsCount: 3,
      _maxListeners: undefined,
      socket: [TLSSocket],
      httpVersionMajor: 1,
      httpVersionMinor: 1,
      httpVersion: '1.1',
      complete: true,
      headers: [Object],
      rawHeaders: [Array],
      trailers: {},
      rawTrailers: [],
      aborted: false,
      upgrade: false,
      url: '',
      method: null,
      statusCode: 405,
      statusMessage: 'Not Allowed',
      client: [TLSSocket],
      _consuming: false,
      _dumped: false,
      req: [Circular *1],
      [Symbol(kCapture)]: false,
      [Symbol(RequestTimeout)]: undefined
    },
    aborted: false,
    timeoutCb: null,
    upgradeOrConnect: false,
    parser: null,
    maxHeadersCount: null,
    reusedSocket: false,
    host: 'id.virginmedia.com',
    protocol: 'https:',
    [Symbol(kCapture)]: false,
    [Symbol(kNeedDrain)]: false,
    [Symbol(corked)]: 0,
    [Symbol(kOutHeaders)]: [Object: null prototype] {
      accept: [Array],
      'content-type': [Array],
      cookie: [Array],
      'user-agent': [Array],
      'content-length': [Array],
      host: [Array]
    }
  },
  response: {
    status: 405,
    statusText: 'Not Allowed',
    headers: {
      server: 'openresty',
      date: 'Sat, 20 Feb 2021 16:19:27 GMT',
      'content-type': 'text/html',
      'content-length': '166',
      connection: 'close'
    },
    config: {
      url: 'https://id.virginmedia.com/sign-in/?protocol=oidc',
      method: 'post',
      data: 'username=[XXXXXXX%40XXXXXXXXXXX.co.uk]&credential=[XXXXXXXXXXX]',
      headers: [Object],
      params: 'protocol=oidc&rememberme=true',
      transformRequest: [Array],
      transformResponse: [Array],
      timeout: 0,
      withCredentials: true,
      adapter: [Function: httpAdapter],
      xsrfHeaderName: 'X-XSRF-TOKEN',
      maxContentLength: -1,
      maxBodyLength: -1,
      maxRedirects: 0,
      jar: [CookieJar],
      ignoreCookieErrors: true,
      validateStatus: [Function: validateStatus]
    },
    request: <ref *1> ClientRequest {
      _events: [Object: null prototype],
      _eventsCount: 2,
      _maxListeners: undefined,
      outputData: [],
      outputSize: 0,
      writable: true,
      destroyed: false,
      _last: true,
      chunkedEncoding: false,
      shouldKeepAlive: false,
      _defaultKeepAlive: true,
      useChunkedEncodingByDefault: true,
      sendDate: false,
      _removedConnection: false,
      _removedContLen: false,
      _removedTE: false,
      _contentLength: 54,
      _hasBody: true,
      _trailer: '',
      finished: true,
      _headerSent: true,
      socket: [TLSSocket],
      _header: 'POST /sign-in/?protocol=oidc&0=protocol%3Doidc%26rememberme%3Dtrue HTTP/1.1\r\n' +
        'Accept: application/json, text/plain, */*\r\n' +
        'Content-Type: application/x-www-form-urlencoded\r\n' +
        'Cookie: ULM-JSESSIONID=9C70A57B0040B74880F4747C5D7D7841\r\n' +
        'User-Agent: axios/0.21.1\r\n' +
        'Content-Length: 54\r\n' +
        'Host: id.virginmedia.com\r\n' +
        'Connection: close\r\n' +
        '\r\n',
      _keepAliveTimeout: 0,
      _onPendingData: [Function: noopPendingOutput],
      agent: [Agent],
      socketPath: undefined,
      method: 'POST',
      maxHeaderSize: undefined,
      insecureHTTPParser: undefined,
      path: '/sign-in/?protocol=oidc&0=protocol%3Doidc%26rememberme%3Dtrue',
      _ended: true,
      res: [IncomingMessage],
      aborted: false,
      timeoutCb: null,
      upgradeOrConnect: false,
      parser: null,
      maxHeadersCount: null,
      reusedSocket: false,
      host: 'id.virginmedia.com',
      protocol: 'https:',
      [Symbol(kCapture)]: false,
      [Symbol(kNeedDrain)]: false,
      [Symbol(corked)]: 0,
      [Symbol(kOutHeaders)]: [Object: null prototype]
    },
    data: '<html>\r\n' +
      '<head><title>405 Not Allowed</title></head>\r\n' +
      '<body bgcolor="white">\r\n' +
      '<center><h1>405 Not Allowed</h1></center>\r\n' +
      '<hr><center>nginx</center>\r\n' +
      '</body>\r\n' +
      '</html>\r\n'
  },
  isAxiosError: true,
  toJSON: [Function: toJSON]
}
[20/02/2021, 16:19:27] [Virginmedia TiVo Service] +++INTERCEPTED SESSION COOKIEJAR:
 Promise {
  [
    Cookie="ULM-JSESSIONID=9C70A57B0040B74880F4747C5D7D7841; Domain=virginmedia.com; Path=/; Secure; HttpOnly; hostOnly=false; aAge=0ms; cAge=35ms"
  ]
}
[20/02/2021, 16:19:27] [Virginmedia TiVo Service] +++INTERCEPTED HTTP RESPONSE: 200 OK 
Headers: {
  server: 'openresty',
  date: 'Sat, 20 Feb 2021 16:19:27 GMT',
  'content-type': 'text/html',
  'content-length': '30339',
  'last-modified': 'Fri, 21 Sep 2018 12:13:04 GMT',
  connection: 'close',
  vary: 'Accept-Encoding',
  etag: '"5ba4e050-7683"',
  expires: 'Sat, 20 Feb 2021 16:24:27 GMT',
  'cache-control': 'max-age=300',
  'accept-ranges': 'bytes'
}

homebridge.log

Plugin Config: eosstb-config.json.txt

homebridge-config.json.txt

Environment: Running HomeBridge on a Raspberry Pi 4 4GB connected via Ethernet

jsiegenthaler commented 3 years ago

@jbroomfi Great to have you on board, you are literally Virgin Media User #2. The logon process is very much work in progress, but I solved the Telenet logon last week and I'm now able to invest time in the Virgin Media logon. If you're able and willing to help, we can make this work. Thanks heaps for the logs, I'll go through them tonight (later, I'm watching some racing on TV right now). Make sure you remove your password from any log files you post!

jbroomfi commented 3 years ago

@jsiegenthaler I'm more than willing to help out where I can with this. Just let me know what you need.

Update: I thought I'd scrubbed the logins from the files but checking it again I had to make a few edits to remove things I'd missed first time around. Thanks for the heads up on that, I'll double check that if I need to upload any logs in the future.

jbroomfi commented 3 years ago

@jsiegenthaler I've checked HomeBridge for updates and noticed that both HomeBridge itself had an update (1.3.1) and your plug-in also had an update (v0.1.9). NPM has also been updated as well.

Environment Update: Plugin Version: v0.1.9 Homebridge Version: v.1.3.1 Node.js Version: v14.15.5 NPM Version: v7.5.4 Operating System: Raspbian GNU/Linux Buster (10)

Despite the updates and restart of HB, I'm still getting the same login error at Step 3.

jsiegenthaler commented 3 years ago

Thank you. Your comments reveal that you have good technical knowledge. Are you willing to assist me in getting the GB session working? I cannot go further from my location here in CH, I need to test from a user on the Virgin Media Network. I'll try and contact you by email.... hmmm... I cannot find your mail. Are you on reddit?

jbroomfi commented 3 years ago

Ok understood

Do we need to setup a Zoom session or something like that?

Edit: I am on reddit, username JayCloth29 if that's easier.

On 24 Feb 2021, at 09:26, jsiegenthaler notifications@github.com wrote:

Thank you. Your comments reveal that you have technical knowledge. Are you willing to assist me in getting the GB session working? I cannot go further from my location here in CH, I need to test from a user on the Virgin Media Network.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/jsiegenthaler/homebridge-eosstb/issues/8#issuecomment-784936914, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABQMVBPREAVVBABEHWEIIGDTATA5JANCNFSM4X6B4N3A.

jsiegenthaler commented 3 years ago

Thanks for the phone call @jbroomfi unfortunately, as we discovered, your settop box is an older TiVo that runs on an older platform and uses completely different communication methods. Thus I am sorry to say this plugin can not work on the older TiVo Virgin Media boxes.