Curl command works on CLI but Alamofire fails to authenticate - swift

Here is the curl command that works:
curl -d {"Key1":"value1"} -k -vvvv --request POST --header "Content-Type: application/json" --key KEY.pem --cacert CRT.pem --cert KEY.pem "URL"
How do I translate this to Alamofire request command? I get the authentication failure errors:
Connection 1: default TLS Trust evaluation failed(-9807)
2020-04-09 01:51:46.604692-0600 CertificatePinningExample[7192:1891639] Connection 1: TLS Trust encountered error 3:-9807
2020-04-09 01:51:46.604879-0600 CertificatePinningExample[7192:1891639] Connection 1: encountered error(3:-9807)
2020-04-09 01:51:46.606672-0600 CertificatePinningExample[7192:1891639] Connection 1: unable to determine interface type without an established connection
2020-04-09 01:51:46.650936-0600 CertificatePinningExample[7192:1891639] Task <9E539D4B-9694-426E-B382-6350044743B0>.<1> HTTP load failed, 0/0 bytes (error code: -1202 [3:-9807])
2020-04-09 01:51:46.662507-0600 CertificatePinningExample[7192:1891652] Task <9E539D4B-9694-426E-B382-6350044743B0>.<1> finished with error [-1202] Error Domain=NSURLErrorDomain Code=-1202 "The certificate for this server is invalid. You might be connecting to a server that is pretending to be “BLAH” which could put your confidential information at risk." UserInfo={NSLocalizedRecoverySuggestion=Would you like to connect to the server anyway?, _kCFStreamErrorDomainKey=3, NSErrorPeerCertificateChainKey=(
// Alamofire code to fire up the request
override func viewDidLoad() {
super.viewDidLoad()
let evaluators = [
"SERVER_IP":
PinnedCertificatesTrustEvaluator(certificates:
getCertificates()
)
]
let session = Session(
serverTrustManager: ServerTrustManager(evaluators: evaluators)
)
let url = URL(string: "URL_TO_HIT")!
//enableCertificatePinning()
var dict: NSDictionary = ["SessionId":""]
var data: Data = Data.init()
do {
data = try JSONSerialization.data(withJSONObject: dict, options: [])
} catch{
data = "".data(using: .utf8)!
}
//let data = try JSONSerialization.data(withJSONObject: dict, options: [])
let request = AF.request(url, method: .post)
// 2
request.responseJSON { (data) in
print(data)
}
}
private func getCertificates() -> [SecCertificate] {
let url = Bundle.main.url(forResource: "ExampleCert", withExtension: "der")!
let localCertificate = try! Data(contentsOf: url) as CFData
guard let certificate = SecCertificateCreateWithData(nil, localCertificate)
else { return [] }
return [certificate]
}
My concern is: Alamofire is asking for only one cert vs I am using three cert flags in curl. How do I translate Alamofire request to the same as curl?

Related

Disable checking https certificate: Swift

I trying to make a https call to my web service from a ios application.
So I used:
//...
func sendMessage() {
let defaults = UserDefaults.standard
let url = URL(string: defaults.string(forKey:"host")! + ":" + defaults.string(forKey:"port")! + "/garage")!
var request = URLRequest(url: url)
request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
request.httpMethod = "POST"
let parameters: [String: String] = [
"identifier": defaults.string(forKey: "secret")!
]
request.httpBody = parameters.percentEncoded()
let session = URLSession(configuration: URLSessionConfiguration.default, delegate: self, delegateQueue: nil)
let task = session.dataTask(with: request) { data, response, error in
guard let data = data,
let response = response as? HTTPURLResponse,
error == nil else { // check for fundamental networking error
print("error", error ?? "Unknown error")
return
}
guard (200 ... 299) ~= response.statusCode else { // check for http errors
print("statusCode should be 2xx, but is \(response.statusCode)")
print("response = \(response)")
return
}
let responseString = String(data: data, encoding: .utf8)
debugPrint("responseString = \(responseString)")
}
task.resume()
}
//...
extension ViewController: URLSessionDelegate {
public func urlSession(_ session: URLSession, didReceive challenge: URLAuthenticationChallenge, completionHandler: #escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) {
//Trust the certificate even if not valid
let urlCredential = URLCredential(trust: challenge.protectionSpace.serverTrust!)
completionHandler(.useCredential, urlCredential)
}
}
I installed the ca at on the target system too. But I also try to ignore the certificate.
I always get following error instead of a response:
2020-07-03 14:41:27.742361+0200 GarageOpener[5177:223905] ATS failed system trust
2020-07-03 14:41:27.742484+0200 GarageOpener[5177:223905] Connection 1: system TLS Trust evaluation failed(-9802)
2020-07-03 14:41:27.742642+0200 GarageOpener[5177:223905] Connection 1: TLS Trust encountered error 3:-9802
2020-07-03 14:41:27.742776+0200 GarageOpener[5177:223905] Connection 1: encountered error(3:-9802)
2020-07-03 14:41:27.746709+0200 GarageOpener[5177:223905] Task <63EC553D-485C-478D-813B-AF0C1D3D3223>.<1> HTTP load failed, 0/0 bytes (error code: -1200 [3:-9802])
2020-07-03 14:41:27.749778+0200 GarageOpener[5177:223905] Task <63EC553D-485C-478D-813B-AF0C1D3D3223>.<1> finished with error [-1200] Error Domain=NSURLErrorDomain Code=-1200 "An SSL error has occurred and a secure connection to the server cannot be made." UserInfo={NSURLErrorFailingURLPeerTrustErrorKey=<SecTrustRef: 0x600002b187e0>, NSLocalizedRecoverySuggestion=Would you like to connect to the server anyway?, _kCFStreamErrorDomainKey=3, _kCFStreamErrorCodeKey=-9802, NSErrorPeerCertificateChainKey=(
"<cert(0x7fd6f2035600) s: *.mydomain.de i: *.mydomain.de>"
), NSUnderlyingError=0x600001773cf0 {Error Domain=kCFErrorDomainCFNetwork Code=-1200 "(null)" UserInfo={_kCFStreamPropertySSLClientCertificateState=0, kCFStreamPropertySSLPeerTrust=<SecTrustRef: 0x600002b187e0>, _kCFNetworkCFStreamSSLErrorOriginalValue=-9802, _kCFStreamErrorDomainKey=3, _kCFStreamErrorCodeKey=-9802, kCFStreamPropertySSLPeerCertificates=(
"<cert(0x7fd6f2035600) s: *.mydomain.de i: *.mydomain.de>"
)}}, NSLocalizedDescription=An SSL error has occurred and a secure connection to the server cannot be made., NSErrorFailingURLKey=https://subdomain.mydomain.de:443/garage, NSErrorFailingURLStringKey=https://subdomain.mydomain.de:443/garage, NSErrorClientCertificateStateKey=0}
"3"
error Error Domain=NSURLErrorDomain Code=-1200 "An SSL error has occurred and a secure connection to the server cannot be made." UserInfo={NSURLErrorFailingURLPeerTrustErrorKey=<SecTrustRef: 0x600002b187e0>, NSLocalizedRecoverySuggestion=Would you like to connect to the server anyway?, _kCFStreamErrorDomainKey=3, _kCFStreamErrorCodeKey=-9802, NSErrorPeerCertificateChainKey=(
"<cert(0x7fd6f2035600) s: *.mydomain.de i: *.mydomain.de>"
), NSUnderlyingError=0x600001773cf0 {Error Domain=kCFErrorDomainCFNetwork Code=-1200 "(null)" UserInfo={_kCFStreamPropertySSLClientCertificateState=0, kCFStreamPropertySSLPeerTrust=<SecTrustRef: 0x600002b187e0>, _kCFNetworkCFStreamSSLErrorOriginalValue=-9802, _kCFStreamErrorDomainKey=3, _kCFStreamErrorCodeKey=-9802, kCFStreamPropertySSLPeerCertificates=(
"<cert(0x7fd6f2035600) s: *.mydomain.de i: *.mydomain.de>"
)}}, NSLocalizedDescription=An SSL error has occurred and a secure connection to the server cannot be made., NSErrorFailingURLKey=https://subdomain.mydomain.de:443/garage, NSErrorFailingURLStringKey=https://subdomain.mydomain.de:443/garage, NSErrorClientCertificateStateKey=0}
I know ignore isn't a good idea and it would allow man in the middle attacks. But at least the connection would be encrypted. And if somebody has the ability to make a man in the middle attack in my WLAN I have bigger problems than this.
Please help ;)
Okay, maybe it's time to answer my question.
The first I did wrong was the signing of the certificate.
I just set the domain/ip-address of the server in the Common Name (CN) entry of the certificate.
That is an outdated solution. You need to set the subjectAltName for modern applications: http://wiki.cacert.org/FAQ/subjectAltName .
But it feels very ugly to use the instructions from that wiki site to self-sign a certificate. So I used the awesome tool certstrap: https://github.com/square/certstrap
After that:
I passed the server.key and server.crt (private and signed public
key) to the server and configured everything fine.
I downloaded the CA (ca.crt) that I created (on the iphone).
You need to go to the settings->general->profiles and trust your
certificate.
Finally, you need to trust the certificate again:
https://support.apple.com/en-us/HT204477#:~:text=If%20you%20want%20to%20turn,Mobile%20Device%20Management%20(MDM).
Done. My application worked!

Swift 4 URLsession with Authentication API Key

I am trying to make a POST Request for the Shippo REST API in Swift, but since it needs an API Authentication key I cannot figure out how to implement the key in the URLSession in Swift 4. As the Apple documentation puts it I cannot use urlsession.shared method.
The cURL command is:
curl https://api.goshippo.com/addresses/ \
-H "Authorization: ShippoToken shippo_test_Token_Here" \
-d name="Shawn Ippotle" \ -d company="Shippo" \
-d street1="215 Clayton St." \
-d street2="" \
-d city="San Francisco" \
-d state="CA" \
-d zip=94117 \
-d country="US" \
-d phone="+1 555 341 9393" \
-d email="shippotle#goshippo.com"\
-d is_residential=True\
-d metadata="Customer ID 123456"
what about something like:
// preparing http request
let yourUrl = URL(string: "https://api.goshippo.com/addresses/")! // whatever is your url
let yourAuthorizationToken = "ShippoToken shippo_test_Token_Here" // whatever is your token
let yourPayload = Data() // whatever is your payload
var request = URLRequest(url:yourUrl)
request.httpMethod = "POST"
request.setValue(yourAuthorizationToken, forHTTPHeaderField: "Authorization")
request.httpBody = yourPayload
// executing the call
let session = URLSession(configuration: URLSessionConfiguration.default)
let task = session.dataTask(with: request, completionHandler: {data, response, error -> Void in
// your stuff here
})
task.resume()
Here it is using Alamofire. I hope this helps. I have tested it and it works.
func mainRequest(){
var headers: HTTPHeaders = [
"content-type": "application/json"
]
let credentials = "shippo_test_8dc780c66d5dae1c42868596c0b359ba89108df9"
headers["Authorization"] = "ShippoToken \(credentials)"
var parameters:Parameters = [String : Any]()
parameters["name"] = "Shawn Ippotle"
parameters["company"] = "Shippo"
parameters["street1"] = "215 Clayton St."
parameters["street2"] = ""
parameters["city"] = "San Francisco"
parameters["state"] = "CA"
parameters["zip"] = "94117"
parameters["phone"] = "+1 555 341 9393"
parameters["country"] = "US"
parameters["email"] = "shippotle#goshippo.com"
parameters["is_residential"] = "True"
parameters["metadata"] = "Customer ID 123456"
let url = "https://api.goshippo.com/addresses"
Alamofire.request(url, method: .post, parameters: parameters , encoding: JSONEncoding.default, headers: headers)
.responseJSON { (response) in
switch response.result {
case .success(let value):
let swiftyJson = JSON(value)
print ("return as JSON using swiftyJson is: \(swiftyJson)")
case .failure(let error):
print ("error: \(error)")
}
}
}

VPN Connection with NEVPNProtocolIKEv2 - ios/swift

I have to make a VPN connection with protocol IKEv2 using a certificate.
I already have the Network Extensions entitlements.
Starting with the certificate that i'm using:
I request that certificate with an ACS request that returns me the UserCertificate in Base64 that i need to send with the VPN connection.
Example User Certificate in Base64 received:
"MIIFqTCCA5GgAwIBAgIQdwPEs5oyDHNNp7e2ZyhwADANBgkqhkiG9w0 ... N972fR4pncgdIA=="
In order to pass that certificate in the "identityData" parameter i have to convert this to Data with the PKCS12 format as i understand.
This is my conversion from Base64 to Data:
certificate = SecCertificateCreateWithData(nil, Data(base64Encoded: "Base64_String_Here")! as CFData)!
certificateData = SecCertificateCopyData(certificate!) as Data
I'm able to print the Data as NSData and i get this example:
308205a9 30820391 a0030201 02021077 03c4b39a 320c734d a7b7b667 28700030 0d06092a 864886f7 0d01010b 05003060
311c301a 06035504 030c1354 45535420 5646435a 20455043 20537562 4341310c 300a0603 55040b0c 03455043 31253023
06035504 0a0c1c56 6f646166 6f6e6520 437a6563 68205265 7075626c 69632061 2e732e31 0b300906 03550406 1302435a
301e170d 31373131 31373131 32393531 5a170d31 39313131 38313132 3935315a 30818731 43304106 03550403 0c3a3467
66693233 30303339 39303030 30313433 31403467 66692e65 70632e6d 6e633030 332e6d63 63323330 2e336770 706e6574
776f726b 2e6f7267 310c300a 06035504 0b0c0345 50433125 30230603 55040a0c 1c566f64 61666f6e 6520437a 65636820
52657075 626c6963 20612e73 2e310b30 09060355 04061302 435a3082 0122300d 06092a86 4886f70d 01010105 00038201
0f003082 010a0282 010100cc 5effc8d7 fb357559 678fb8fc 48fd3558 8af4f236 a27295a6 b484bad0 921f8077 35ddbceb
5c064492 2f9df462 2a44c4fc 85b80cfa eec6b84b b13aefa1 69e4e6b3 db8ef30b 202229c7 421bfb8f 3f47c24f 6e3f7abc
ca7d216b 31d2a02c 94c3ef6c 9d50c2ab a590d99f 5d7afddb acbcc045 53949653 97034063 404cbe00 6aaec239 b37b2ce9
5c63d126 127247a5 75446c6b fa2e2217 6706a36c a0db0630 dac90d10 00ff24a8 2f189f18 37233151 f9825f60 aa8f66e7
89d656b9 5a52d9e3 b52cb3bc 5badb801 d9ea3685 8930cb3b 490ccba0 247f4bde 00b46d5e a63b1018 4ad8a581 978f5570
82f06f7f ba60db83 abcb4391 2f221e69 14bbdc46 ce19ae95 33773f02 03010001 a3820135 30820131 30370608 2b060105
05070101 042b3029 30270608 2b060105 05073001 861b6874 74703a2f 2f6f6373 702d6570 632e766f 6461666f 6e652e63
7a301d06 03551d0e 04160414 ea45a2e8 94fe37bc 08af3fab 60f9869b 5980d3cf 30090603 551d1304 02300030 1f060355
1d230418 30168014 f3c6b0f4 961565ab 232c6060 3e16f790 f63334b1 30440603 551d2004 3d303b30 39060960 86480186
f8420108 302c302a 06082b06 01050507 0201161e 68747470 3a2f2f70 6b692e76 6f646166 6f6e652e 637a2f70 6f6c6963
792f3040 0603551d 1f043930 373035a0 33a03186 2f687474 703a2f2f 706b692e 766f6461 666f6e65 2e637a2f 63726c2f
74657374 5f766663 7a5f6570 635f6361 2e63726c 300e0603 551d0f01 01ff0404 030203f8 30130603 551d2504 0c300a06
082b0601 05050703 02300d06 092a8648 86f70d01 010b0500 03820201 004cacde 1d7b7843 43aa546c 8984e308 57a12a27
0b9a2873 2adb598d da29fe4c ee087c92 3f18bbaa 1f3ef0b9 39e18d50 db982f87 36689c03 07ab7d11 a1665bf0 f6057de5
e89fe2fe 3f9c476b 8a28749c f9d7636c 8ece6012 d0a53902 ec437171 0af85024 0963bf85 518fa150 43dc7fe8 30c42f09
62cd2a31 c38e54ba de2b8a01 6e6804b2 b66c36c1 4626fc37 65064a65 d5087412 8e541e12 51525c4c e1f4a7e2 94a31397
2806d327 7a3c65c7 50e7db59 99460ae9 a446391e 5bbce05e 1f205e1c 118cd7aa 02e9881f 75b5b40d f2aa09bc bb7abf22
b11b3e31 2f0e78ae ee497d26 ef314b1d f16008af c433a653 983db0a9 97cbbca1 5a9e8d4d 3d34ee87 858e4f3d d2c5c111
05ccdcfa b1a41afe 2624ba31 decd561a 791e97e0 197b8bfe 97ebb3ad 7b511c1d e820c83f 81cdb9ed 21d59b49 7fb0bb39
69e735e7 350af763 ab26ee3d 7e954ef7 e5c994f6 c8f104ac 4f19ed25 9855f14c 619935d6 0d9f1206 910ffe03 74c312d5
b39da039 650d9004 e2186914 cfa19052 a2e47f1c 5af90903 959ab99f 2c52a9d8 f737b59f 00cababa 0b4f7236 e9102ee4
a76ed0a0 6d827860 653d6e62 f52fcc77 d9afdc90 53d942fe 434c8901 ab2a93e8 cc7c8555 eb6a94e5 0e1cc18c 9d6c8b48
ed9204eb 623f74d2 219a5ca9 032caa7c 900ed208 b88f5fb2 5c53bcd3 e82c48f8 80450f40 f05706c1 072427cb 815e8590
4fbf5137 def67d1e 299dc81d 20
So, basically the var certificateData is the one that i'm using in the parameter "identityData".
Here is what i do in order to connect the VPN:
First i set all the parameters that are required:
vpnManager = NEVPNManager.shared()
vpnManager!.loadFromPreferences { error in
var hasProtocolConfig = false;
if #available(iOS 9, *) {
hasProtocolConfig = self.vpnManager!.protocolConfiguration != nil
} else {
hasProtocolConfig = self.vpnManager!.`protocol` != nil
}
if hasProtocolConfig == true {
let p = NEVPNProtocolIKEv2()
p.serverAddress = "X.X.X.X"
p.localIdentifier = "My_Local_Identifier"
p.remoteIdentifier = "My_Remote_Identifier"
p.identityData = certificateData
p.ikeSecurityAssociationParameters.integrityAlgorithm = NEVPNIKEv2IntegrityAlgorithm.SHA256
p.ikeSecurityAssociationParameters.encryptionAlgorithm = NEVPNIKEv2EncryptionAlgorithm.algorithmAES128
p.ikeSecurityAssociationParameters.diffieHellmanGroup = NEVPNIKEv2DiffieHellmanGroup.group14
p.serverCertificateIssuerCommonName = "My_IssuerCommonName"
p.serverCertificateCommonName = "My_CommonName"
p.authenticationMethod = NEVPNIKEAuthenticationMethod.certificate
p.useExtendedAuthentication = true
p.disconnectOnSleep = false
if #available(iOS 9, *) {
self.vpnManager.protocolConfiguration = p
} else {
self.vpnManager.`protocol` = p
}
self.vpnManager.isEnabled = true
self.vpnManager.saveToPreferences { error in
if let e = error{
print("[VPN] error saving: " + e.localizedDescription)
} else {
print("[VPN] vpn saved")
Timer.scheduledTimer(timeInterval: 5, target: self, selector: #selector(self.connectVPN), userInfo: nil, repeats: false)
}
return
}
Then i establish the VPN connection:
do {
try vpnManager!.connection.startVPNTunnel()
} catch let error {
print("Error starting VPN Connection \(error.localizedDescription)");
}
If i understand this well, Since i am not able to force the "Notify: EAP_ONLY_AUTHENTICATION", i have to use "NEVPNIKEAuthentication.certificate", otherwise i could set it to ".none".
The ikeAssociationParameters are the right ones as i check with the server side.
When i try to connect to the VPN i get the status:
Connecting -> Disconnected
Any ideia of what i am doing wrong with this connection?

Socket self signed certificate handshake failure

I am using Starscream socket library and am trying to use WSS however I am having a handshake failure. I got my self signed certificate, I converted it to a .der file. Here is the code I am trying
var socket = WebSocket(url: URL(string: "wss://192.168.1.130:6223")!, protocols: [])
override func viewDidLoad() {
super.viewDidLoad()
do
{
let urlPath = Bundle.main.path(forResource: "my_cert", ofType: "der")
let url = NSURL.fileURL(withPath: urlPath!)
let certificateData = try Data(contentsOf: url)
let certificate: SecCertificate =
SecCertificateCreateWithData(kCFAllocatorDefault, certificateData as CFData)!
var trust: SecTrust?
let policy = SecPolicyCreateBasicX509()
let status = SecTrustCreateWithCertificates(certificate, policy, &trust)
if status == errSecSuccess {
let key = SecTrustCopyPublicKey(trust!)!;
let ssl = SSLCert(key: key)
socket.security = SSLSecurity(certs: [ssl], usePublicKeys: true)
socket.delegate = self
socket.connect()
}
}catch let error as NSError
{
print(error)
}
}
So when I try to connect, I get the following error message
2017-07-07 11:06:26.590 CertificateTesting[5180:81661] CFNetwork
SSLHandshake failed (-9807) websocket is disconnected: The operation
couldn’t be completed. (OSStatus error -9807.)
The certificate should work fine, my Android colleague has tried it on his side and has had no issues. The only way I can get it working on my side is if I disable SSL validation like so
socket.disableSSLCertValidation = true
Does anyone have any experience using self signed SSL with sockets. Any information would be much appreciated.
Edit:
I called verify ssl command, it returns
➜ CertificateTesting git:(master) ✗ openssl verify -my_cert.der ca-cert.pem server-cert.pem
usage: verify [-verbose] [-CApath path] [-CAfile file] [-purpose purpose] [-crl_check] [-engine e] cert1 cert2 ...
recognized usages:
sslclient SSL client
sslserver SSL server
nssslserver Netscape SSL server
smimesign S/MIME signing
smimeencrypt S/MIME encryption
crlsign CRL signing
any Any Purpose
ocsphelper OCSP helper
Does that look okay?
You can give a try using the common name in the WebSocket instead of IP.
var socket = WebSocket(url: URL(string: "wss://192.168.1.130:6223")!, protocols: [])
You can verify the common name in the certificate using the command
openssl x509 -in <certificate file> -text
Validate the SSL handshake using following command
openssl s_client -host <common name mentioned in the cert> -port <port> -cert <client_cert file> -key <client_key file> -CAfile <ca_cert file>
in an old swift app, i had the same problem using REST API and WS exposed by a self signed certificate.
Websocket protocol is embedded in HTTP/S protocol, also the handshake.
So generate the certificate .cert:
echo -n | openssl s_client -connect yoururl:443 | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' > name_youwant.cert
Import the .cert file in the asset of the app that will use it.
In the class that estabilish the websocket connection, implement URLSessionDelegate.
And then use this logic to validate the self signed certificate:
Note: NSBundle.mainBundle().pathForResource(Config.certificate, ofType: ".cert") -> Config.certificate is a static string that indicate the name of file.
// uncomment if self signed certificate is used on the backend
public func URLSession(session: NSURLSession, didReceiveChallenge challenge: NSURLAuthenticationChallenge, completionHandler: (NSURLSessionAuthChallengeDisposition, NSURLCredential?) -> Void) {
let serverTrust = challenge.protectionSpace.serverTrust
let certificate = SecTrustGetCertificateAtIndex(serverTrust!, 0)
let certificateData = SecCertificateCopyData(certificate!)
let remoteCertificateData = certificateData as NSData
let cerPath = NSBundle.mainBundle().pathForResource(Config.certificate, ofType: ".cert")
let localCertData = NSData(contentsOfFile: cerPath!)!
if localCertData.isEqualToData(remoteCertificateData) {
completionHandler(NSURLSessionAuthChallengeDisposition.UseCredential,NSURLCredential(forTrust:
challenge.protectionSpace.serverTrust!))
}else{
completionHandler(NSURLSessionAuthChallengeDisposition.CancelAuthenticationChallenge,nil)
}
}
Hope this helps.
Regards,

"A stable connection to the server could not be established"

I trying to connect to Google with OAuth2. I have got access_token and user email. Here is not problem.
let singleton: Singleton = Singleton.sharedInstance
singleton.session.authType = MCOAuthType.XOAuth2 // session:IMAPSession
singleton.session.OAuth2Token = singleton.accessToken
singleton.session.username = singleton.email
singleton.session.hostname = "imap.gmail.ru"
singleton.session.port = 993
singleton.session.connectionType = MCOConnectionType.StartTLS
Next step i create fetch operation and get an error
let requestKind = MCOIMAPMessagesRequestKind.Headers | MCOIMAPMessagesRequestKind.Flags | MCOIMAPMessagesRequestKind.Structure
let uids = MCOIndexSet(range: MCORangeMake(1, UINT64_MAX))
let folder = "INBOX"
let fetchOperation = singleton.session.fetchMessagesOperationWithFolder(folder, requestKind: requestKind, uids: uids)
fetchOperation.start { (error, fetchedMessages, vanishedMessages) -> Void in
if (error != nil)
{
println("Error: \(error)") // this line return me error
}
Error: Error Domain=MCOErrorDomain Code=1 "A stable connection to the server could not be established." UserInfo=0x7f9e260036b0 {NSLocalizedDescription=A stable connection to the server could not be established.}
Error: Error Domain=MCOErrorDomain Code=1 "A stable connection to the server could not be established." UserInfo=0x7f9e23c46c00 {NSLocalizedDescription=A stable connection to the server could not be established.}
what could be the problem?
Here's the working code guys:
var smtpSession = MCOSMTPSession()
smtpSession.hostname = "xxxxxxxx"
smtpSession.username = "xxxxxxx"
smtpSession.password = "xxxxxxxx"
smtpSession.port = 8465
smtpSession.authType = MCOAuthType.SASLPlain
smtpSession.connectionType = MCOConnectionType.TLS
smtpSession.connectionLogger = {(connectionID, type, data) in
if data != nil {
if let string = NSString(data: data, encoding: NSUTF8StringEncoding){
NSLog("Connectionlogger: \(string)")
}
}
}
var builder = MCOMessageBuilder()
builder.header.to = [MCOAddress(displayName: "Rool", mailbox: "xxxxxxx#hxxxx.com")]
builder.header.from = MCOAddress(displayName: "Matt R", mailbox: "xxxxxx#sxxxxxx.com")
builder.header.subject = "My message"
builder.htmlBody = "<h3>This is a test message!</h3>"
let rfc822Data = builder.data()
let sendOperation = smtpSession.sendOperationWithData(rfc822Data)
sendOperation.start { (error) -> Void in
if (error != nil) {
NSLog("Error sending email: \(error)")
} else {
NSLog("Successfully sent email!")
}
}
PS: I used this code for SMTP2GO and It's working flawlessly, just make sure you're using the right port.