jeffreydwalter / arlo

Python module for interacting with Netgear's Arlo camera system.
Apache License 2.0
517 stars 124 forks source link

Add automatic Gmail MFA #160

Closed booi closed 3 years ago

booi commented 3 years ago

Hi all, I noticed that Arlo was enforcing MFA on all accounts now and this could break the Arlo python library which I use to backup videos.

This is a preliminary PR to add support for automatic MFA retrieval and submission without using SMS or other paid services. The only prerequisite is using a Gmail account. This PR also adds a new LoginMFA method that is conditionally called and contains a process that I've reverse engineered from Arlo's website.

What this PR still needs:

I'm copy and pasting the content in docs/ARLO_MFA.md here to aid in review.

Instructions

  1. Login with a new or existing Gmail account.
    • The script will have read-only permissions on this gmail account.
    • Care is taken to only search and load emails relevant to Arlo MFA but the script does have access to the entire mailbox.
    • While this implementation is completely private, it's recommended to use a separate gmail account for Arlo login purposes.
  2. Create or use an existing Google Cloud project.
  3. Enable the Gmail API
    • Go to APIs & Services -> Library
    • Search for Gmail
    • Enable the Gmail API
  4. Setup the OAuth consent screen
    • Go to APIs & Services -> OAuth consent screen
    • Setup OAuth consent screen
      • The app name and emails can be anything.
    • Scopes
      • Add Scopes
      • Filter for "Gmail API"
      • Add the scope ".../auth/gmail.readonly"
    • Test Users
      • Add the gmail address of your Arlo login
  5. Create OAuth 2.0 Client ID credentials
    • Click on Create Credentials -> OAuth client id
    • Under Application type, select "Web application"
    • Name can be anything
    • Under "Authorized redirect URIs", add "http://localhost:7788"
    • Click Create
    • Close the window with the credentials, we will save them in the next step.
  6. Save the OAuth client credential package
    • For the newly client id row, click the download button (down arrow) on the right side
    • Save this credential in your project as "google_client_credentials.json"
  7. Run the gmail_oauth.py script
    • This will open a browser and ask you to login and authenticate with Google
    • It may warn you that this is a test application, please force continue
    • Approve of the gmail read only scope on the next screen
    • This script will save a file called gmail.credentials. This file will allow us to persistently access the gmail account programmatically.
  8. Update your project to pass the name of this file into the Arlo class.
    • For example, instead of arlo = Arlo(USERNAME, PASSWORD)
    • Call arlo = Arlo(USERNAME, PASSWORD, '/path/to/gmail.credentials)

How it works

We are creating an OAuth application and registering it with Google. The gmail_oauth.py script forwards you to authenticate with this application and grant your application read-only access to your mailbox.

When we initialize the Arlo class, the LoginMFA function:

booi commented 3 years ago

I am able to successfully authenticate with this PR. However, it appears that the api has changed.

After authentication, when I attempt to use the library, I get this error

401 Client Error: Unauthorized for url: https://my.arlo.com/hmsweb/users/library

Looking at my network trace interacting with the website, the API seems to live at myapi.arlo.com now instead of my.arlo.com/hmsweb. I didn't investigate further to see if this is merely a hostname change or a different API altogether.

jeffreydwalter commented 3 years ago

@booi I haven't taken a look at your code yet, but 2FA is not required yet. With 2FA disabled, this library still works as-is.

When I login using the web interface, I do see the endpoints it's calling are different, and I believe required if you want to use 2FA.

I unfortunately don't really have time to add support for 2FA, but I'd be really happy to accept a PR that makes it all work.

jeffreydwalter commented 3 years ago

@booi I FINALLY got around to integrating your PR into this library. (Had to deal with a bug in requests/urllib3). I have a branch with your code merged in and the auth issue you were describing is fixed (it was the requests/urllib3 bug).

If you're still out there, would appreciate it if you'd give the branch a try and let me know if I merged it correctly.

Thanks!

booi commented 3 years ago

@jeffreydwalter Hi! Sorry I must have missed the notification of this / don't pay a lot of attention to github emails. It appears to be merged correctly.

You know, I ended up not using it since 2fa was not mandatory back then but it appears to be mandatory now so could come in useful?

cgmckeever commented 2 years ago

@booi @jeffreydwalter (Apologies if this has been discussed - and I could have sworn I saw this referenced elsewhere). Since these app that is granted gmail permission is in test status, the certs expire in 7 days. Is this correct? My service just started dying, and I found this post reference the 7 day .

Any workarounds to this, or is it just something that needs to be done weekly?

booi commented 2 years ago

Ah interesting, that's why it stopped working periodically for me. I wonder if this is a (relatively) new behavior. I think the best thing to do would be to promote your app to production and take it out of test mode?

If you end up doing that, please report back

cgmckeever commented 2 years ago

Not sure how easy it will to be pass this ....

Screen Shot 2022-01-10 at 7 24 42 AM
cgmckeever commented 2 years ago

@booi looks like there is more you can do within a Google Workspace. I converted, will find out in 7 days ;) https://stackoverflow.com/questions/70653369/google-cloud-api-services-oauth-with-a-testing-app/70653489#70653489 https://support.google.com/a/answer/7378726?hl=en