mobile-rr icon indicating copy to clipboard operation
mobile-rr copied to clipboard

Android Captive Portal Helper isn't triggered.

Open idolpx opened this issue 8 years ago • 87 comments

When connecting on an iOS or OSX device the captive portal is detected and a browser window pops up like it should to be able to accept the agreement and then get rick roll'd. It doesn't launch the browser window on Android though.

idolpx avatar Jul 09 '16 05:07 idolpx

Just tested with Android 6.0.1 on a Nexus 5X, and a Nexus 6. Connecting to the hotspot brings up a "Sign in to wifi network" notification and toast. Clicking the notification loads the captive portal.

What version of android are you running?

ratmandu avatar Aug 12 '16 01:08 ratmandu

I'm using a Galaxy S5 with Android 6.0.1. I'm not sure why my phone doesn't work the same. I'd like for it to open a browser page like it does on iOS. It does pop open a browser when I connect to some captive portals at restaurants and parks with free wifi though. I'd like for mobile-rr to work the same as those captive portals. I just need to do some packet sniffing to find out what the difference is.

idolpx avatar Aug 15 '16 05:08 idolpx

The captive portal also doesn't work for me although I'm on iOS. Is it possible that it's broken on iOS 10? Edit: It seems to work with dev beta 7 / public beta 6

Starbix avatar Aug 19 '16 10:08 Starbix

I don't have an iOS 10 device but will see what I can come up with to test with.

idolpx avatar Aug 20 '16 05:08 idolpx

It just worked once for iOS 10, while it works again if I renew my release in iOS 9

Starbix avatar Aug 20 '16 15:08 Starbix

Please check if my pull request fixes it: https://github.com/idolpx/mobile-rr/pull/10

Noki avatar Aug 20 '16 16:08 Noki

Hmmm... still the same for me on my Android device but if it fixed it for you I'll merge it.
Thanks.

idolpx avatar Aug 21 '16 01:08 idolpx

This doesn't fix it for iOS 10

Starbix avatar Aug 21 '16 10:08 Starbix

Hmm. Stopped working for me as well. Strange thing is that it works sometimes. It might be a caching issue. Probalby it is a good idea to send nocaching headers for the redirects and the captive portal index and set the TTL of DNS answers to 0 seconds.

The DNS setting can be set using:

dnsd.setTTL(0);

And the caching directives could be set using something like this:

AsyncWebServerResponse *response = request->beginResponse(302);
response->addHeader("Cache-Control","no-cache");
response->addHeader("Pragma","no-cache");
response->addHeader ("Location", "http://10.10.10.1/" );
request->send(response);

However that also was not enough. But maybe because of the fact that things are still cached and I don't know how to reset the DNS cache and other caches on my phone.

Noki avatar Aug 21 '16 12:08 Noki

Thanks for the suggestions. I'm adding them now. I still have to do some WiFi sniffing to try and determine the difference between this captive portal and others.

Is there a way to set DHCP option 160. I'm curious if that is what the difference is.

idolpx avatar Aug 27 '16 05:08 idolpx

It looks like it works on iOS 10 (dev beta 8/ public beta 7) now.

Starbix avatar Aug 27 '16 14:08 Starbix

Oh great! Thanks for the feedback.

idolpx avatar Aug 27 '16 15:08 idolpx

on my ios 10.0.1 iphone 6 doestn work anymore...i use a nodemcu and had to change the platformio.ini to this:

[env:nodemcuv2] platform = espressif8266 board = nodemcuv2 framework = arduino build_flags = -ULWIP_OPEN_SRC -Wl,-Tesp8266.flash.4m.ld

than compiling and uploading is no problem anymore...but as said the portal doesnt open...can only go to console if i type the url :/

tpmodding avatar Oct 11 '16 13:10 tpmodding

Not working for me either, but I can't imagine it being a device dns-cache issue because places like McDonald's still cause a pop-up on my phone. Has anyone tried sniffing the wifi when connecting to a mcdoogles hotspot? Tell me a good program to grab wifi frames on connection and I'll try it myself.

By the way, you can see what android does by looking at the source code. Among other things, I see a reference to not follow redirects when pulling the 204. (google CaptivePortalTracker.java for whatever version of android you are curious about)

e.g. / core / java / android / net / CaptivePortalTracker.java

treii28 avatar Sep 19 '17 03:09 treii28

Further testing on my part with your dns server library, and I can see the dns requests are being answered, but I never see the requests combing back to the web server. My guess appears to be dns caching or otherwise not-trusting the response of the local-net address on the part of the mobile device. I'm wondering if there is any way to get the web server code to answer the /generate_204 and other urls regardless of the address they are being sent to. Something similar to IPTables redirects in linux or something. I see they have an lwip implementation in the esp8266 code and some of the libraries (including ESPAsyncTCP) use it for some of their protocol handling. Maybe there's some way in there (it's a tad beyond my skill level at the moment, but I'm trying to find resources to learn as much as I can about it) that could help?

treii28 avatar Sep 23 '17 00:09 treii28

I added a callback to be able to override the IP of a DNS query to point the DNS to an IP that is inactive on the local network and that did not solve the issue either.

This post suggested that method. https://socifi-doc.atlassian.net/wiki/spaces/SC/pages/94371841/DNS+Workaround+to+keep+Android+Splash+Page+and+the+Captive+Portal+Notification+active

I'm just now getting back to this to see if I can come up with a solution. My phone pops up the CP Helper every time at a McDonalds or Taco Bell and other CPs at restaurants but not from this little device. I will do some sniffing again soon to see if I can find any differences.

Any feedback is greatly appreciated. I'd love to solve this issue.

idolpx avatar Jan 05 '18 18:01 idolpx

I'm working on a bit different project which uses Captive Portal. I have rewritten DNS code from scratch using AsyncUDP, extended it to handle most of DNS requests and it still did not help (manual browser navigation redirects correctly). The problem seems to be limited to Samsung devices. I have S7 edge and have no luck with pop-up (only "Internet may not be available" shows). On my Tab Pro with Cyanogen installed it works as intended. It seems that my phone does not request /generate204 from web server (nor does it make any other requests). I've looked into AOSP code and it should visit those URLs, so it seems that Samsung has changed the way that CP detection works. Still I was not able to determine what triggers the pop-up on my phone. Maybe there is some IP whitelist and/or some special DNS answer required.

drzony avatar Feb 08 '18 08:02 drzony

Did you try to implement DNS Option 160 in your custom DNS code? I'm curious if that would activate the CP Helper.

idolpx avatar Feb 17 '18 19:02 idolpx

There is no such thing as DNS option 160, it's DHCP option 160 and it's implemented in DHCP server on ESP (I have verified that), if it was not implemented then the device would not receive address of DNS server (and it would not receive any DNS query packets). From inspection of packets coming to my DNS server I can see that the phone asks for the IPs for google servers and my ESP sends responses (I've verified that those responses are valid). But there are no HTTP requests made to web server, which is weird. If I open Chrome manually then if I type http://github.com then I'm properly redirected to my captive portal (which means that both DNS and web server are working), but there is no "Sign in to WiFi network" popup. As I've written in my post before on my Tab Pro with Cyanogen everything works as expected.

drzony avatar Feb 17 '18 19:02 drzony

Ooops sorry... Yes it is for DHCP but it is not for sending the DNS server address. It is for sending the url for a captive portal within the DHCP configuration. How would you set it in the ESP if it is already implemented?

This article explains it's use a bit better.

http://community.arubanetworks.com/t5/Technology-Blog/RFC-7710-Captive-Portal-Identification-Using-DHCP-or-Router/ba-p/255737

idolpx avatar Feb 18 '18 03:02 idolpx

Unfortunately this would require change in ESP SDK, you can see DHCP options here https://github.com/esp8266/Arduino/blob/f9ac524b13348e18a1ceb00261d947d6c1e0f9b5/tools/sdk/lwip/src/app/dhcpserver.c#L134 Captive portal is only a small part of my project, so checking this out will take some time (and I wonder if it's worth the effort)

drzony avatar Feb 18 '18 10:02 drzony

I just tried with a change to lwip, adding DHCP option 160 to the offer. Unfortunately this didn't help for a Samsung S8; there was no automatic opening of the captive portal browser. I double checked the option looked correct using wireshark on a Linux machine (no captive portal browser opened there either).

I guess option 160 is a dead-end, at least for now.

ChrisSteinbach avatar Apr 17 '18 20:04 ChrisSteinbach

Oh shoot... ok. Thanks for trying it out and letting us know. This bugs me every time I think about it. It has been a while. Getting this working consistently across all devices would be the icing on the cake for the project.

idolpx avatar May 10 '18 15:05 idolpx

Did you guys manage to get it working!??

vidharv avatar Aug 16 '18 11:08 vidharv

I have not looked at it again in a long time. Still an open issue until we find a solution.

idolpx avatar Aug 25 '18 21:08 idolpx

I got it working!

there are some commeted out lines on mobile-rr.ino line 576 ish..

remove the comments and adding

                if ( strstr(domain, "connectivitycheck.gstatic.com") )
                    dnsd.overrideIP =  IPAddress(74, 125, 21, 113);
                // connectivitycheck.android.com -> 74.125.21.113
                if ( strstr(domain, "connectivitycheck.android.com") )
                    dnsd.overrideIP =  IPAddress(74, 125, 21, 113);

                // dns.msftncsi.com -> 131.107.255.255
                if ( strstr(domain, "msftncsi.com") )
                    dnsd.overrideIP =  IPAddress(131, 107, 255, 255);

It works! it seems my phone (s7 edge) was sending the request to connectivitycheck.gstatic.com not to connectivitycheck.android.com

I also enabled dnsd.setTTL(0);

Marfjeh avatar Oct 09 '18 19:10 Marfjeh

@Marfjeh Good job! Do you send in a pull request for all the lazy people? ;-)

Noki avatar Oct 10 '18 06:10 Noki

Sure. i'll fork the project

Marfjeh avatar Oct 10 '18 09:10 Marfjeh

made the pull request. #30

Marfjeh avatar Oct 10 '18 09:10 Marfjeh

Awesome! I will check this out as soon as a get a moment.

idolpx avatar Oct 18 '18 19:10 idolpx