iOS Captive Network Assistant behavior on Hotspots - ios

We have a hotspot product using SMS authentication method. The user chooses our WiFi Hotspot network and is redirected to our login page.
On iOS and Adroid, a Captive Portal pop-up is activated showing our login page. We ask users to fill in a form and submit their phone number. When they click "Submit" we send them an SMS with a verification code.
The login window (hosted on our server) changes to a new page which is displaying a field to enter the verification code. So far so good... If the user sees the "notification popup" for the SMS on his screen on top of the captive window, he can see the code and enter it in the provided field and authenticate.
But if he doesn't have SMS notification set like this, he has to go to his SMS app and look up the code. Now, the only way to do that is to close the Captive popup but then he gets disconnected from our hotspot. If he reconnects he needs to fill in the form again and gets a new SMS but he faces the same problem.
Now, all this time user is not authenticated, so in iOS the captive window displays "Cancel" in the top right corner. I have seen this same method on other hotspots, but from the first Captive window, the control displayed in top right corner is "Done". As far as I know, the difference there is that the "Done" control is shown when the user is authenticated and "Cancel" while he hasn't been authenticated yet.
Is there a way to "fool" the CNA to "think" the user has internet access and display "Done" so when Captive window is closed, the device stays connected to our Hotspot?
We are thinking either some "two-step" authentication, like temporary (to get "Done") and then the "real" one after entering verification code.
Another way might be to use some kind of script (like "Success" trick on iOS) to fool the CNA into thinking there's internet access. But where and how to apply the "Success trick"? In some of the HTML pages in the router? Or somewhere in our login page code?

Different OS versions and different platforms check for internet access in different ways. iOS for example looks for one of these:
http://captive.apple.com/hotspot-detect.html
http://captive.apple.com
etc.
Android uses (among others):
http://clients3.google.com/generate_204
The best solution is for your captive portal to allow access to these through the firewall. If you're using MAC filtering via ipfw or iptables this is easy. If you're doing DNS spoofing it's harder -- for those cases I'd just include the "success" pages in your captive portal package.

Related

How can a user reset permissions settings after declining the JS Geolocation request? (iOS Safari)

After a request is to made for the user's geolocation, using either navigator.geolocation.getCurrentPosition or watchPosition, the user is shown a native permission dialog.
If the user selects "Don't Allow" to the request to share their location, the API correctly responds with a PERMISSION_DENIED code.
However, if the user were to have pressed that by accident, and wishes to clear existing settings, what steps should they follow to do so?
This seems absurd enough to warrant a question.
With Android Chrome; the user can simply press the information icon and adjust the permission.
On iOS Safari, there does not appear to be a way beyond clearing all of Safari's cache and settings; thereby closing the site they were on in the first place.

How to present guest Wi-Fi "terms & conditions" confirmation dialog programmatically?

It is typical setup in bars / restaurants / airports where password-free Wi-Fi is available but requires accepting terms & conditions.
First time customer manually connects to Wi-Fi network which brings confirmation dialog and he accepts it. As result internet connection is alive, no problem here.
However next time customer visits the same place iOS device automatically connects to the known Wi-Fi and shows active Wi-Fi connection icon in status bar. But internet connection isn't available until customer accepts terms & conditions again. To do that customer has to either go to iOS settings or open Safari which brings confirmation dialog automatically.
Our app is designed for bars. Based on above iOS behavior regular customer sees that it has Wi-Fi connection in iPhone status bar, yet our app says "No internet connection". Combined this is very confusing UX.
Question: Is there programatic way to bring Wi-Fi confirmation dialog the same way as Safari does?
iOS should do this automatically if your captive portal is configured correctly.
When it connects to a WiFi network, iOS checks to see if http://captive.apple.com returns "success". If it does then it assumes that it has Internet access. If it returns any other content then it assumes that there is a captive portal and it will open the captive portal authentication screen.
This behaviour is independent of whether the user has connected to that hotspot previously.
Where there can be an issue is when the hotspot de-authenticates the user after some time, as iOS does not continually re-try http://captive.apple.com once it has connected successfully.
Your app can periodically check that http://captive.apple.com returns the correct response and open an SFSafariViewController if it doesn't

Run my app from when connected to a particular wifi : ios

Many Wi-Fi hotspots these days have a "web login", especially free ones. You know, the ones that redirect any HTTP request to their login form.ios first connect to a wifi network then opens up the login page of the network where we fill our credentials and then it let us access the internet. Now I am creating a ios app that runs when connected to a particular network and instead of opening my browser the app takes user credentials once and automatically login for user and user can access the internet. Now how do I open my app whenever the user connects to the network and instead of opening up the app I would like it to show my app notification with the option of Login or Logout in the notification bar.
In android it appears like this:
You need to register a URL scheme within your app, and then configure your login page to call a certain URL containing the information you need. For example, if your app was called "Foobar", a valid URL might look like foobar://auth?user=jacobking&pass=password123. As I said, you will need to tell iOS that your app is listening for the foobar scheme. When iOS receives this URL, it will ask your app delegate if it can open it which you will answer through canOpenURL.
A detailed explaination and code examples can be found here.

How we can detect firewall or sonicwall redirect for our normal request in iOS devices ?

So here is the question
Many times you start your app and and your first API request fails and you realize that even though you're connected through internet You need to login in to Your office' or home network's firewall or sonicwall and login there
So you need to open safari and open your sonicwall page and login there and come back to our app and start it again.
I want my app to detect the same and show the the redirected html page in UIWebView and once the authintication finishes i want to execute the original request withing my app
My question is
1> Is it possible ?
2> If yes how can i achieve it ?
I would suggest using the same captive portal probe URLs that Apple uses in iOS Safari, for maximum compatibility. If those URLs return 200, you shouldn't be behind a (good) captive portal, assuming I'm remembering the details correctly.
You can beef that up further by using reachability APIs to detect network changes, and probing that URL, along with Google's generate_204 URL. And in some places, you'll find Google blocked (China, IIRC), in which case you might also consider a URL with a known, predictable, machine-validateable value, such as Apple's root certificate URL. :-)
When the user signs in, you should get another reachability change event, at which point at least one of your captive portal probes will succeed, and you can reissue any outstanding requests.

Facebook.com and the iOS7 Captive Portal Detection

I created a router that connects to facebook to get some info before a user may access the internet.
First they connect, get the Captive Portal Page and then continue to a facebook login. Since the upgrade to iOS7 it fails to load the facebook login page. On my mac with the Captive Portal Assistant it has no problems and even on the phone itself while using the iOS version of safari there are no problems.
What is going wrong here? Is facebook filtering request from the iOS7 Captive Portal Assistant or is Apple doing some sneaky stuff here?
It seems the problem is widespread and only related to facebook.
Update: I worked with the beta's and they worked fine a few weeks ago. Now with the same beta version it doesn't anymore. So another point for the facebook explaination.
Regards, Cas
This problem was fixed by Apple since IOS 8. But as all iPhone 4 users can't upgrade to IOS 8 this problem is still one.
The IOS 7 devices check for the following domains:
www.appleiphonecell.com
captive.apple.com
captive.apple.com
www.apple.com
www.itools.info
www.ibook.info
www.airport.us
www.thinkdifferent.us
Whitelisting this domains stops the login mask to be appearing as the IOS device thinks, that the internet is working as expected. This way you have control on the things which happens, as the IOS device does not interrupts anything, if you use a normal browser for login.
If you don't whitelist the domains, the following thing happens. I debugged it on routers with several IOS devices and they all did mostly the same:
If you connect to a wifi, the IOS device tries to connect to one of the domains, which are listed above. If it can contact one of the domains, it tries another one. If it can't, it starts the redirect, which is controlled by the router. Sometimes it query one or more domains, before it thinks, that the internet is working.
After the check, the login screen redirects to your router and then to the login screen of your captive portal. This behavior stayed the same as it was on IOS 6 or before.
Now you start an oauth login to a 3rd party provider like Facebook, Google or Twitter. And now the difference appears. You can check it on a router, if you run it in debug mode. As the IOS device goes to an other domain for oauth login (like www.facebook.com) the iPhone thinks, that something changed and starts to query one of the apple domains, which are listed above. The user sees only a white screen and in the background the IOS device tries to contact one of the domains repeatedly. For the user this seems to be an error, as the screen stays white or takes very long to show the login on the 3rd party provider. Sometimes it stops loading and nothing happens forever.
To avoid this behavior, you must whitelist the above listed domains. This is a not a common behavior for IOS users, but this way, your browser have the control of the login session and the IOS device don't interrupt it as it does with the login screen.
Some shallow parts of information is reported on the following sites:
https://supportforums.cisco.com/docs/DOC-36523
http://www.cadincweb.com/why-your-apple-ios-7-device-wont-connect-to-the-wifi-network
https://discussions.apple.com/thread/5355766
I couldn't find a detailed description of the problem and found the one above myself by debugging all parts with some routers and IOS devices like iPhones and iPads.
I've just tested various router settings and noticed that iOS 7 is NOT trying to contact above mentioned sites/URLs when router's DOMAIN field is blank.
My guess is that blank domain points to a consumer-type network set up and Apple is not expecting a Captive Portal at such network. If you have access to administer your router see if you can clear out the DOMAIN field (and restart/retest).
I found my solution to my problem. (a while ago, but I found this post again)
First I found out, iOS makes 3 calls, first to check, second to get the page that needs to be displayed, third to check again after the pageload. Then I discovered, for every POST or GET action made by the page, regarding of the source page was refreshed, iOS checks for an active internet connection. Since the facebook api makes a lot of calls, the browser starts stalling(possible in combination with QoS on my router) and freezes the page.
My Solution:
Since I am in control of the DNS records of the Router I use, I redirected all domains towards my own server.
First I saved the check request, this to later identify the user when he comes back for the 3th request.
When the second request comes I just display an info window that every thing is right, and the user has to click the "Done" button.
The page is loaded, so iOS checks again, but i recognize the user so I display the OK-code Apple also displays. The "Done" button us show, and the user has "internet", according to iOS..
On the page that I display, I instruct the user to open the webbrowser. When he does, he opens a page and my portal with the right page is shown(I can detect this based on the Browser Agent). Then my facebook api start doing its job, and of we go :-)
Let me know if someone needs some more info on how to detect or maybe even a code sample if necessary.
Extra Information
To capture a user on your own server, redirect every request to your processing page using for example .htaccess. The request is made to a domain with a subfile e.g:
http://captive.apple.com/getrT09Nx7G/YNrnUOulnDj/3cfrq3M40iR.html
To keep multiple users apart, use the unique url the device tries to contact when checking for internet, in this case: /getYT09Nx7G/YN1nUOulnDj/3cfMq3M40iR.html

Resources