iOS VPN auto disconnected after sometime - ios

I'm working on a VPN application, VPN working fine but after 15-20 minutes, its automatically disconnected.
Here is configuration I'm using
let vpnProtocol = NEVPNProtocolIKEv2()
vpnProtocol.username = CredentialsManager.shared.accessToken
vpnProtocol.localIdentifier = CredentialsManager.shared.accessToken
print("VPN Connecting to \(self.region.name ?? "Error! Must be a valid region name!")")
if let region = self.region {
f
vpnProtocol.serverAddress = region.serverAddress
vpnProtocol.remoteIdentifier = region.serverAddress
}
let encodedIdentifier = "Secret Password".data(using: .utf8)!
let item = [kSecClass: kSecClassGenericPassword,
kSecAttrGeneric: encodedIdentifier,
kSecAttrAccount: encodedIdentifier,
kSecMatchLimit: kSecMatchLimitOne,
kSecReturnPersistentRef: kCFBooleanTrue as Any,
kSecAttrService: "XYZ"] as [CFString : Any]
var passwordReference: CFTypeRef?
SecItemCopyMatching(item as CFDictionary, &passwordReference)
vpnProtocol.passwordReference = passwordReference as? Data
vpnProtocol.authenticationMethod = .none
vpnProtocol.useExtendedAuthentication = true
vpnProtocol.ikeSecurityAssociationParameters.encryptionAlgorithm =
.algorithmAES256GCM
vpnProtocol.ikeSecurityAssociationParameters.integrityAlgorithm = .SHA384
vpnProtocol.ikeSecurityAssociationParameters.diffieHellmanGroup = .group14
vpnProtocol.childSecurityAssociationParameters.encryptionAlgorithm = .algorithmAES256GCM
vpnProtocol.childSecurityAssociationParameters.integrityAlgorithm = .SHA384
vpnProtocol.childSecurityAssociationParameters.diffieHellmanGroup = .group14
vpnProtocol.disconnectOnSleep = false
self.vpnManager.protocolConfiguration = vpnProtocol
let connectRule = NEOnDemandRuleConnect()
connectRule.interfaceTypeMatch = .any
self.vpnManager.onDemandRules = [connectRule]
self.vpnManager.isOnDemandEnabled = self.connectOnDemand
self.vpnManager.localizedDescription = "XYZ VPN"
self.vpnManager.isEnabled = true
Please help me out, how to identify problem that causing auto disconnect.

change your VPN protocol with this: NEVPNProtocolIPSec
maybe it will help you.

You have configured "connect on demand", so it will connect back automatically when you will access resource next time. That is how VPN on iOS works, it will always close connection on idle.

Related

AWS DynamoDB updateItem problems in Swift 4

I am trying to update an item in my dynamoDB noSQL database. Having some troubles implementing this in swift as there is no swift documentation yet.
I was able to create an item in the database successfully, updating an item seems to be a whole other monster.
Swift Code:
var updatedValue: AWSDynamoDBAttributeValue = AWSDynamoDBAttributeValue()
updatedValue.s = self.UserID
let dynamo: AWSDynamoDB = AWSDynamoDB()
let AddToHistory = Users()
AddToHistory?._campany = self.CompanyTextBox.text!
AddToHistory?._personalSite = self.PersonalTitleTextBox.text!
AddToHistory?._facebook = self.FacebookTextBox.text!
AddToHistory?._linkedIn = self.LinkedInTextBox.text!
AddToHistory?._title = self.TitleTextBox.text!
AddToHistory?._bio = self.BioTextBox.text!
let updateInput: AWSDynamoDBUpdateItemInput = AWSDynamoDBUpdateItemInput()
updateInput.tableName = "myTableName"
updateInput.key = ["_userId": updatedValue]
let updatedCompany = AWSDynamoDBAttributeValue()
updatedCompany?.s = AddToHistory?._campany
let updatedFacebook = AWSDynamoDBAttributeValue()
updatedFacebook?.s = AddToHistory?._facebook
let updatedLinkedIn = AWSDynamoDBAttributeValue()
updatedLinkedIn?.s = AddToHistory?._linkedIn
let updatedPersonalSite = AWSDynamoDBAttributeValue()
updatedPersonalSite?.s = AddToHistory?._personalSite
let updatedTitle = AWSDynamoDBAttributeValue()
updatedTitle?.s = AddToHistory?._title
let updatedBio = AWSDynamoDBAttributeValue()
updatedBio?.s = AddToHistory?._bio
updateInput.expressionAttributeValues = [
"_campany" : updatedCompany!,
"_facebook" : updatedFacebook!,
"_linkedIn" : updatedLinkedIn!,
"_personalSite" : updatedPersonalSite!,
"_title" : updatedTitle!,
"_bio" : updatedBio!,
]
updateInput.returnValues = AWSDynamoDBReturnValue.updatedNew
dynamo.updateItem(updateInput).continueOnSuccessWith(block: { (task:AWSTask!) -> AnyObject! in
if (task.error == nil) {
}
return nil
}
)
Not getting any warnings or errors in the editor, however when I run the app and press the button which runs this code, I get this exception thrown:
Terminating app due to uncaught exception
'NSInternalInconsistencyException', reason: '- init is not a valid
initializer. Use + defaultDynamoDB or + DynamoDBForKey: instead.'
Not sure what I am missing here, it must be something to do with the way I am initializing the dynamoDB object. Tried accessing a default method for init, but there is no such method. :(
Any help would be greatly appreciated, thanks in advance!
Thanks to Jake.lange's comment, I realized I could have used the object mapper that i used to create items to update them as well. Heres the code incase others run into this problem :)
//db connection mapper
let objectMapper = AWSDynamoDBObjectMapper.default()
//new instancer of User class
let itemToUpdate:CheckaraUsers = CheckaraUsers()
//populate
itemToUpdate._userId = UserID
itemToUpdate._firstName = FirstName
itemToUpdate._lastName = LastName
itemToUpdate._campany = AddToHistory?._campany
itemToUpdate._facebook = AddToHistory?._facebook
itemToUpdate._linkedIn = AddToHistory?._linkedIn
itemToUpdate._personalSite = AddToHistory?._personalSite
itemToUpdate._title = AddToHistory?._title
itemToUpdate._bio = AddToHistory?._bio
//save to dynamoDB
objectMapper.save(itemToUpdate, completionHandler:{(error: Error?) -> Void in
if let error = error {
print("Amazon DynamoDB Save Error: \(error)")
}
print("Saved Information!!!")
})
Your definition was wrong.
Change this:
let dynamo: AWSDynamoDB = AWSDynamoDB()
to:
let dynamo: AWSDynamoDB = AWSDynamoDB.default()

PayTM SDK : Transaction Failed

I am integrating PayTM in my app which is in ios (Swift) and I am facing issue which title is "Transaction Failed" and the message is "MissingKeys"
I have used following code
merchant = PGMerchantConfiguration.default()!
merchant.checksumGenerationURL = "http://getlook.in/cgi-bin/checksum_generate.cgi"
merchant.checksumValidationURL = "http://getlook.in/cgi-bin/checksum_validate.cgi"
merchant.clientSSLCertPath = nil
merchant.clientSSLCertPassword = nil
merchant.merchantID = "rriver57770575448885"
merchant.website = "APP_STAGING"
merchant.industryID = "Retail"
merchant.channelID = "WAP"
var orderDict = [String: String]()
orderDict["MID"] = "rriver57770575448885" // Merchant ID
orderDict["CHANNEL_ID"] = "WAP" // Channel Id
orderDict["INDUSTRY_TYPE_ID"] = "Retail" // Industry Type
orderDict["WEBSITE"] = "APP_STAGING"
orderDict["TXN_AMOUNT"] = "10"; // amount to charge // mandatory
orderDict["ORDER_ID"] = "\(Date().timeIntervalSince1970)";//change order id every time on new transaction
orderDict["REQUEST_TYPE"] = "DEFAULT";// remain same
orderDict["CUST_ID"] = "123456789027"; // change acc. to your database user/customers
orderDict["MOBILE_NO"] = "8798987874";// optional
orderDict["EMAIL"] = "test#paytm.com"; //optional
let pgOrder = PGOrder(params: orderDict)
let transaction = PGTransactionViewController.init(transactionFor: pgOrder)
transaction?.serverType = eServerTypeProduction
transaction?.merchant = merchant
transaction?.loggingEnabled = true
transaction?.delegate = self
self.present(transaction!, animated: true, completion: nil)
please help!
In this code you have missed a parameter called chechSumHash. include that too.
orderDict["CHECKSUMHASH"] = CheckSum;
checkSumHash can be generated in the backend by the help of Paytm checksum generation kit. the checksum is a unique string which will change according to the parameter that we have send for checksum generation Api

TouchID with KeyChain - Enter Passcode screen appears malformed (Swift)

I am having a hard time with this one:
Our app uses TouchID to retrieve secrets from the KeyChain that are used to authenticate to a WebApp in a WKWebView. All is fine when the user successfully authenticates with TouchID.
The problem arises when the user fails TouchID and then taps on "Enter Passcode" to authenticate via device passcode instead. I noticed that the screen that gets presented is plain white, and the passcode text-box does not show a value for the last character entered until it is masked, creating a strange user experience. This seems like a bug to me, unless I am somehow missing a configuration requirement.
// global arguments for the touchId keychain queries
let kSecClassValue = NSString(format: kSecClass)
let kSecAttrAccountValue = NSString(format: kSecAttrAccount)
let kSecValueDataValue = NSString(format: kSecValueData)
let kSecClassGenericPasswordValue = NSString(format: kSecClassGenericPassword)
let kSecAttrServiceValue = NSString(format: kSecAttrService)
let kSecMatchLimitValue = NSString(format: kSecMatchLimit)
let kSecReturnDataValue = NSString(format: kSecReturnData)
let kSecMatchLimitOneValue = NSString(format: kSecMatchLimitOne)
let kSecAttrAccessControlValue = NSString(format: kSecAttrAccessControl)
let kSecUseOperationPromptValue = NSString(format: kSecUseOperationPrompt)
// set access control
let accessControl = SecAccessControlCreateWithFlags(kCFAllocatorDefault,
kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly, .UserPresence, nil)
// Instantiate a new default keychain query
// Tell the query to return a result
// Limit our results to one item
var keychainQuery: NSMutableDictionary = NSMutableDictionary(objects: [kSecClassGenericPasswordValue, service, userAccount, kCFBooleanTrue, kSecMatchLimitOneValue, "Place your finger to authenticate.", accessControl.takeUnretainedValue()], forKeys: [kSecClassValue, kSecAttrServiceValue, kSecAttrAccountValue, kSecReturnDataValue, kSecMatchLimitValue, kSecUseOperationPromptValue, kSecAttrAccessControlValue])
var dataTypeRef :Unmanaged<AnyObject>?
// Search for the keychain item
touchIdStatusCode = SecItemCopyMatching(keychainQuery, &dataTypeRef)
Here is the generated keychainQuery dictionary:
{
"accc" = "<SecAccessControlRef: 0x170621140>";
"acct" = “MY_ACCOUNT”;
"class" = genp;
"m_Limit" = "m_LimitOne";
"r_Data" = 1;
"svce" = “MY_SERVICE”;
"u_OpPrompt" = "Place your finger to authenticate.";
}
This behavior exists on the latest iOS version (8.4). Here is the screen I was referring to:
My question is: Am I somehow causing the screen to be broken by the way I am invoking TouchID? Or is this perfectly normal for this scenario?
Thanks, and sorry for the lengthy post!
The issue described is a bug that was confirmed by Apple engineers. It still exists as of iOS 9.0.2.

How to send all traffic over a VPN connection?

I am creating an application to connect to a VPN server.
I have worked out how to do this, but need to be able to send all traffic over the connection.
Is there any code which can do this?
So far I have tried:
let manager: NEVPNManager = NEVPNManager.sharedManager()
var p = NEVPNProtocolIPSec()
manager.`protocol` = p
let pw = ""
println(manager.connection.status)
p.username = ""
p.passwordReference = pw.dataUsingEncoding(NSUTF8StringEncoding)
p.serverAddress = ""
p.authenticationMethod = NEVPNIKEAuthenticationMethod.SharedSecret
//p.sharedSecretReference = getPasscodeNSData("vpnSharedSecret")
p.useExtendedAuthentication = true
p.disconnectOnSleep = false
No, I don't think there is any way to switch all system IP traffic over a VPN connection. Apple doesn't let apps muck around with the OS like that.

RTCDataChannel not working iOS

I'm using RTCDataChannel. But messages which i'm sending through the channel are not receiving at the other peer.
Here is the code:
let audioConstraint : RTCPair = RTCPair(key: "OfferToReceiveAudio", value: "true")
let videoConstraint : RTCPair = RTCPair(key: "OfferToReceiveVideo", value: "true")
let dtlsConstraint : RTCPair = RTCPair(key: "DtlsSrtpKeyAgreement", value: "true")
let mediaContraints : RTCMediaConstraints = RTCMediaConstraints(mandatoryConstraints: [audioConstraint, videoConstraint], optionalConstraints: [ dtlsConstraint])
RTCPeerConnectionFactory.initializeSSL()
peerConnection = peerConnectionFactory.peerConnectionWithICEServers(servers, constraints: mediaContraints, delegate: self)
dataChannels = peerConnection?.createDataChannelWithLabel(channelName,config: nil)
dataChannels?.delegate = self
var message : NSData = NSData(base64EncodedString: "helloo")
var buffer : RTCDataBuffer = RTCDataBuffer(data: message, isBinary: true)
dataChannels?.sendData(buffer)
Have you resolved it?
One of the two peers should create data channel and other should attach the received data channel object to its data channel object.
The initiator should create datachannel before sending offer. Hope this might be helpful
I had the same problem until I set the option not to nil. If I skipped the steamId, it would not send. Even though the channel is open.
RTCDataChannelInit *dataInit = [[RTCDataChannelInit alloc] init];
dataInit.isNegotiated = YES;
dataInit.isOrdered = YES;
dataInit.maxRetransmits = 30;
dataInit.maxRetransmitTimeMs = 30000;
dataInit.streamId = 12; //important setting
self.dataChannel = [_peerConnection createDataChannelWithLabel:kRTCDataChannelLabel config:dataInit];
self.dataChannel.delegate = self;

Resources