I have an app that displays a warning to the user when they attempt to contact a server with a self-signed or otherwise untrusted SSL certificate. If they choose to proceed, we use connection:didReceiveAuthenticationChallenge to continue with the HTTPS request by creating a credential for the server trust. This is the common way that connections are made to untrusted servers on iOS.
What I'm wondering if there's a way to only create this server trust for a particular connection, or if it's possible to rescind the trust at a later time. What we've found is that the server trust lasts for as long as the app is running. We'd like to be able to prompt the user again at a later time to make sure they still want to proceed. Is this possible? Is there a way for the trust to only "last" for one connection, or to find the trust and somehow remove it so that we go through the process again for that same server?
Are you not releasing the connection after the data is received. If you are releasing it it should ask every time. Make sure the cache property for you connection is not enabled
Related
Is there any configuration like android user-permission in iOS to control access to internet?
I think all new projects access to internet by default, is that correct?
When I send a request to the internet it returns 0 http-error code, it means I can't access to the internet.
yes, it is correct all the new ios project have access to the internet by default.
A status code of 0 in an NSHTTPURLResponse object generally means there was no response and can occur for various reasons. The server will never return a status of 0 as this is not a valid HTTP status code.
Any http request will first be processed by the operating system, and during that phase you can get an error. Getting an error means that your request never got a response from the server (and with the exception of https requests where certificates were not accepted, most likely didn't reach the server).
If this phase succeeds, then you get eventually a reply from the server. This may take time, you may have to wait 60 seconds. Which is why you do all your internet requests on a background thread. That reply will have a status code (status, not error). The status code is NEVER 0.
By default, iOS doesn't allow http requests, and doesn't allow https requests to unsave servers, so you better use only https unless you have a very good reason. You will need a very good reason to convince Apple to let your app on the app store if you want http requests to succeed. But if you get this wrong, you get an error quite early on.
A status of zero most likely means that a background request didn't finish by the time you read the status, a basic programming mistake. You need to learn how background threads and callbacks work. Without that, you won't be able to use http successfully.
Also google for "Reachability" which can tell you if your app currently has internet access (like when WiFi and Mobile Data are turned off, or in Airplane mode).
I have some logic that communicates with a backend server which has two versions, a NSURLConnection and NSURLSession. The latter was made because NSURLConnection is deprecated, and also we want to leverage the background download ability. These classes are written to support client-side certificates for authenticating the client.
The classes that do this communication is called from a few different types of routines throughout my application.
The issue I am seeing is that when using the NSURLSession version, I see that a SSL (TLSv1) session is never being reused, and there is a full chain of [Client Hello, Server Hello, Certificate, Certificate, Client Key Exchange, Certificate Verify, etc.] for each connection. Looking at the "Client Hello" message, I can see there is never a "session ID" in the message, so I think this is why the SSL session is never reused.
On the older, NSURLConnection version, I see that often the session is reused, and a previous session ID is given in the "Client Hello" message.
In both of these approaches, I am creating a new instance of NSURLConnection or NSURLSession. I think what is going on is that NSURLConnection works across the entire app, whereas NSURLSession does not.
However, I am not sure how I should be writing my NSURLSession logic so that the SSL session is shared between server and client and the client cert isn't sent every time. I think one way might be to use a single NSURLSession instance, but I am not sure if this is the right design pattern.
With NSURLSession, connections are not shared across multiple sessions, because different sessions can have different limits on the maximum number of concurrent connections, different keep-alive settings, different proxy settings, etc.
Thus, if you're only making one request per session, you'll end up creating a new connection every time, complete with the full TLS setup overhead.
There are two straightforward ways to fix this:
Create a single session when you launch the app and use it everywhere.
Use the shared session ([NSURLSession sharedSession]).
If you're doing background downloading, that session needs to be created once, when your app first starts, and then never recreated (unless the session was created in response to your app getting relaunched in the background to handle some task's results, in which case IIRC the session becomes invalid, so you'll recreate it again if your app subsequently gets launched in the usual way or whatever).
Assume that I connected to the broker with "clean session=false" and started receiving events, in case of disconnection ideally my application will still receive data on connection. But if the application is crashed I want to have a fresh start and clear my session.
Can I clear my session on the MQTT broker and have a fresh start?
From the documentation I concluded that if I wanted to do that I would need to do the following:
application start
connect using "clean session=true" // this will cause any current session to be removed along with its data
every thing related to the session is purged from server
disconnect
connect using "clean session=false" and start getting the data.
I got the idea from
http://www.hivemq.com/blog/mqtt-essentials-part-3-client-broker-connection-establishment
"If clean session is set to true, the broker won’t store anything for
the client and will also purge all information from a previous
persistent session."
Is this the correct way to clear a previous session?
Yes, that is the only way to clear a session for a client.
When NEVPNProtocol property is updated by the server such that the username & password isn't valid anymore, is there a way we can handle this?
Lets say if we turn on onDemandEnabled flag for NEVPNManager, and when the server invalidates the credential (since the user has been blacklisted), is there a way we can toggle this programmatically? From the end user's experience perspective, the user would wait for a long time to fail webpage loading. Background fetch using a timer might not work if the app is killed.
Other than using push notifications, is there a better way to solve this issue?
I didn't try it myself, but what you should do is when you configure your VPN and set the onDemandEnabled, you need to define the onDemandRules.
There you have NEOnDemandRuleDisconnect, which will prevent your VPN from starting, and will disconnect it if it's already active.
https://developer.apple.com/library/ios/documentation/NetworkExtension/Reference/NEOnDemandRuleDisconnectClassRef/index.html#//apple_ref/occ/cl/NEOnDemandRuleDisconnect
This way even if your VPN is active, you will use it only when the rules still applies.
Edit: you can also use onDemandRule - probeURL . With this, before any activation of your VPN, it will send a request to a server of your choice. The server will return an answer if you should use your VPN or not.
I'm in need of some guidance on managing vijava ServiceInstance connection. I'm creating a GUI application which allows the end user to manage, create and modify VMs from vCenter. So, when the application first launches, the user enters IP address of vCenter server, username and password. I create a ServiceInstance object to create the connection. Once the connection is establish, I leave it open for the user to perform tasks until the application is closed where terminate the session by login out.
My questions is, should I establish a connection every time the user needs to perform a task that requires a connection to vCenter and then log out once the task is complete? Or just establish one connection and use that same connection to perform tasks and terminate the session when the application closes?
Establishing new connection will influence the performance. On the other hand if you will have one connection and it will stay open, you may have security issues in case password of vCenter has changed and your connection will remain open.
I think that the best solution is to use one connection, but manage the timeout of the connection. And then close it when you have timeout and reopen it.