Betfair API'ing Certificate login using C++ boost SSL Sockets - c++

Firstly, thanks for coming here. I'm trying to login with betfair using a certificate login using boost's ssl sockets however, once I send my http login POST, I receive the message CERT_AUTH_REQUIRED. On the betfair website it says this means "Certificate required or certificate present but could not authenticate with it".
I am able to connect, handshake and send/receive data. However, I just can't seem to login with my code. I've tested the exact certificates using curl without any problems.
* ALPN, server accepted to use http/1.1
* Server certificate:
* subject: C=IE; ST=Leinster; L=Dublin; O=Paddy Power Betfair Public Limi
ted Company; OU=IT Networks; CN=betfair.com
* start date: Sep 11 05:50:38 2018 GMT
* expire date: Sep 11 05:59:00 2020 GMT
* issuer: C=US; O=HydrantID (Avalanche Cloud Corporation); CN=HydrantID S
SL ICA G2
* SSL certificate verify result: self signed certificate in certificate c
hain (19), continuing anyway.
> POST /api/certlogin HTTP/1.1
> Host: identitysso-cert.betfair.com
> User-Agent: curl/7.46.0
> Accept: */*
> X-Application: AOxcQMZwVN3jOsLZ4
> Content-Length: 41
> Content-Type: application/x-www-form-urlencoded
>
* upload completely sent off: 41 out of 41 bytes
< HTTP/1.1 200 OK
< Content-Type: text/plain;charset=ISO-8859-1
< Content-Length: 87
< Date: Wed, 06 Mar 2019 11:09:35 GMT
<
{"sessionToken":"ZFbyo3HeAh07UFTHzhhGjOyQFeX2MKdHHHHtAm2S7FXw=","loginStatus":"SU
CCESS"}* Connection #0 to host identitysso-cert.betfair.com left intact
I have further tested these certificates with python code that also works.
My C++ code is below. I've tried sending incorrect passwords which result in the status from server INVALID_USERNAME_OR_PASSWORD instead.
boost::asio::ssl::context ctx(boost::asio::ssl::context::tlsv12);
// load certificates
ctx.load_verify_file(cert_filename.c_str());
// ctx.use_private_key_file(private_filename.c_str(), boost::asio::ssl::context::pem);
ctx.use_rsa_private_key_file(private_filename.c_str(), boost::asio::ssl::context::pem);
mSocket.reset(new boost::asio::ssl::stream<tcp::socket>(mIoService, ctx));
mSocket->set_verify_mode(boost::asio::ssl::verify_peer);
mSocket->set_verify_callback(
boost::bind(&BetfairSession::VerifyCertificate, this, _1, _2));
tcp::resolver resolver(mIoService);
tcp::resolver::query query("identitysso-cert.betfair.com", port);
tcp::resolver::iterator endpointIter = resolver.resolve(query);
Many thanks in advance :)

I think you are confusing the client certificate and the CA List.
This:
ctx.load_verify_file(cert_filename.c_str());
Is loading a list of CA certificates to verify the server certificate against.
You can find a example of this list here:
http://curl.haxx.se/ca/cacert.pem
You also need to setup the certificate to use for the SSL connection, you do this with the "use_certificate_chain_file" method.
e.g.
ctx.use_certificate_chain_file(cert_filename.c_str());

Related

Cognito authorization endpoint (without client secret) returning Invalid client error message

I have a problem with Cognito and api clients like Postman or Insomnia.
There is a mobile app that makes calls to the backend.
There is an AWS Cognito instance, with one user pool and one API client, configured for using Authorization Code, with Cognito User Pool set as an Identity Provider
At first, the API client was configured to use client secret. I was able to make API calls from Postman or Insomnia using Oauth2 authentication, but for some unknown reason I wasn't able to authenticate using the mobile app
Then there was a change in the infrastructure - the old API Client entry in Cognito was recreated, but configured NOT to use client secret. We immediately removed client secret data from the code. After that, I was able to log in from the mobile application and send requests to the backend, but now I cannot authenticate with Postman/Insomnia. The browser window is opening, I can see the credentials form, I can properly login, but after that when Postman is calling the token endpoint, I get a browser window with one message in it:
An error was encountered with the requested page.
And I do not receive my tokens. Postman says:
Authentication failed
Couldn’t complete authentication. Check the Postman Console for more details.
Insomnia:
[oauth2] Failed to fetch token url=https://my-app-address.amazoncognito.com/oauth2/token status=400
And finally, here's the Insomnia's response timeline:
* Preparing request to https://my-app-name.auth.eu-west-1.amazoncognito.com/oauth2/token
* Current time is 2023-01-04T10:56:38.314Z
* Enable automatic URL encoding
* Using default HTTP version
* Enable timeout of 30000ms
* Enable SSL validation
* Enable cookie sending with jar of 2 cookies
* Found bundle for host my-app-name.auth.eu-west-1.amazoncognito.com: 0x12f2ee990 [can multiplex]
* Re-using existing connection! (#13) with host my-app-name.auth.eu-west-1.amazoncognito.com
* Connected to my-app-name.auth.eu-west-1.amazoncognito.com (x.x.x.x) port 443 (#13)
* Using Stream ID: 9 (easy handle 0x14e9f8400)
> POST /oauth2/token HTTP/2
> Host: my-app-name.auth.eu-west-1.amazoncognito.com
> user-agent: insomnia/2022.7.0
> cookie: XSRF-TOKEN=f1264cb4-b688-41a3-9126-cf021df2fa30
> content-type: application/x-www-form-urlencoded
> accept: application/x-www-form-urlencoded, application/json
> authorization: Basic MzJkN2JvnzNhNUTzNGNIN3UzdjY5b3Zkb246ZXI=
> content-length: 166
| grant_type=authorization_code&code=9e3e6ae8-30c7-6c5c-9aee-1930131a6624&redirect_uri=myapp%3A%2F%2Ffrontpage&code_verifier=dhQD1EtvMm_yP6eGorgQU7budSloaspeuGUM_OzS34k
* We are completely uploaded and fine
< HTTP/2 400
< date: Wed, 04 Jan 2023 10:56:38 GMT
< content-type: application/json;charset=UTF-8
< x-amz-cognito-request-id: 71156586-7bd3-4485-944c-07b5b930ce15
< x-content-type-options: nosniff
< x-xss-protection: 1; mode=block
< cache-control: no-cache, no-store, max-age=0, must-revalidate
< pragma: no-cache
< expires: 0
< strict-transport-security: max-age=31536000 ; includeSubDomains
< x-frame-options: DENY
< server: Server
* Received 26 B chunk
* Connection #13 to host my-app-name.auth.eu-west-1.amazoncognito.com left intact
| {"error":"invalid_client"}
And the cognito user pool config:
resource "aws_cognito_user_pool_client" "my_app_client" {
name = "my-app-dev"
user_pool_id = aws_cognito_user_pool.default.id
allowed_oauth_flows = ["code"]
allowed_oauth_flows_user_pool_client = true
allowed_oauth_scopes = ["email", "openid"]
callback_urls = ["myapp://frontpage"]
logout_urls = ["myapp://signout"]
supported_identity_providers = ["COGNITO"]
}
What could be the reason why I am unable to authenticate using Postman/Insomnia and receive such errors? Could this be something related to AWS configuration? Or I'm doing something wrong?
As you have not configured the client secret in the App client, authorization header should not be added in the token request.
As mentioned in the document, authorization header needs to be provided only if the client was issued a secret.

Different server/IP - no more connection?

I'm using Mailgun through my local installation of Mautic. It used to connect correctly. Today however I got this error message: Unable to connect with TLS encryption Log data: ++ Starting Swift_SmtpTransport << 220-node6237.myfcloud.com ESMTP Exim 4.95 #2 Tue, 12 Apr 2022 13:38:14 +0000 220-We do not authorize the use of this system to transport unsolicited, 220 and/or bulk e-mail. >> EHLO dashboard.nsking.ee << 250-node6237.myfcloud.com Hello dashboard.nsking.ee [194.233.160.33] 250-SIZE 52428800 250-8BITMIME 250-PIPELINING 250-PIPE_CONNECT 250-AUTH PLAIN LOGIN 250-STARTTLS 250 HELP >> STARTTLS << 220 TLS go ahead !! Unable to connect with TLS encryption (code: 0) ++ Starting Swift_SmtpTransport << 220-node6237.myfcloud.com ESMTP Exim 4.95 #2 Tue, 12 Apr 2022 13:38:14 +0000 220-We do not authorize the use of this system to transport unsolicited, 220 and/or bulk e-mail. >> EHLO dashboard.nsking.ee << 250-node6237.myfcloud.com Hello dashboard.nsking.ee [194.233.160.33] 250-SIZE 52428800 250-8BITMIME 250-PIPELINING 250-PIPE_CONNECT 250-AUTH PLAIN LOGIN 250-STARTTLS 250 HELP >> STARTTLS << 220 TLS go ahead !! Unable to connect with TLS encryption (code: 0)
What is the cause of it? Keep in mind, nothing has changed in our installation except the server name and the IP.
I tried to change to SSL and I got this error:
Connection could not be established with host smtp.mailgun.org :stream_socket_client(): Peer certificate CN=node6237.myfcloud.com' did not match expected CN=smtp.mailgun.org' Log data: ++ Starting Swift_SmtpTransport !! Connection could not be established with host smtp.mailgun.org :stream_socket_client(): Peer certificate CN=node6237.myfcloud.com' did not match expected CN=smtp.mailgun.org' (code: 0)
++ Starting Swift_SmtpTransport !! Connection could not be established with host smtp.mailgun.org :stream_socket_client(): Peer certificate CN=node6237.myfcloud.com' did not match expected CN=smtp.mailgun.org' (code: 0)

webserver based on node.js couldn't parse the right data which sent by method 'POST' via CURL

I implemented a simple webserver based on node.js, which handle the data
sent by method 'POST' via libCURL.
Client: c++ code based on libCURL
Server: Node.js
Result:
Client
I implemented a simple webserver based on node.js, which handle the data
sent by method 'POST' via libCURL.
Client: c++ code based on libCURL
Server: Node.js
###Client####
>>>
* Found bundle for host 109.123.121.146: 0x1b13f00 [can pipeline]
* Re-using existing connection! (#0) with host 109.123.121.146
* Connected to 109.123.121.146 (109.123.121.146) port 8124 (#0)
> POST / HTTP/1.1
Host: 109.123.121.146:8124
Accept: */*
Content-Type: text/xml
Content-Length: 11
* upload completely sent off: 11 out of 11 bytes
< HTTP/1.1 200 OK
HTTP/1.1 200 OK
< Content-Type: text/plain;charset=utf-8
Content-Type: text/plain;charset=utf-8
< Date: Thu, 05 Jan 2017 21:14:05 GMT
Date: Thu, 05 Jan 2017 21:14:05 GMT
< Connection: keep-alive
Connection: keep-alive
< Transfer-Encoding: chunked
Transfer-Encoding: chunked
<
* Connection #0 to host 109.123.121.146 left intact
###Server####
####### 'POST' ######
Partial body: B=~� size:11
Body: B=~� size:11 ---->> why the data is invalid char, size is right.
Source Code
Client.cpp
string strUrl = "http://109.123.121.146:8124/";
string strLog = "Hello,CURL!";
curl_easy_setopt(g_curl_handle, CURLOPT_URL, strUrl.c_str());
curl_easy_setopt(g_curl_handle, CURLOPT_POST, 1);
curl_easy_setopt(g_curl_handle, CURLOPT_POSTFIELDS, strLog.c_str());
Server.js
req.addListener('data', function (data) {
body += data;
console.log("Partial body: " + data + " size:"+data.toString().length);
});
req.addListener('end', function () {
console.log("Body: " + body + " size:"+body.toString().length);
});
I wonder why the request data is invalid char:"B=~�" , or not the right string "Hello,CURL!",
Anyone konws, help to explain to me, thanks ~~~

POST url encoded form to Amazon API Gateway

I'm creating a webhook to receive notifications from a 3rd-party service, they sent the data in the body of a POST with content type application/x-www-form-urlencoded.
But it generates the same error:
{"message": "Could not parse request body into json: Unrecognized token \'name\': was expecting \'null\', \'true\', \'false\' or NaN\n at [Source: [B#456fe137; line: 1, column: 6]"}
I could reproduce the error with the following curl call:
% curl -v -X POST -d 'name=Ignacio&city=Tehuixtla' https://rl9b6lh8gk.execute-api.us-east-1.amazonaws.com/prod/mandrillListener
* Trying 54.230.227.63...
* Connected to rl9b6lh8gk.execute-api.us-east-1.amazonaws.com (54.230.227.63) port 443 (#0)
* TLS 1.2 connection using TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
* Server certificate: *.execute-api.us-east-1.amazonaws.com
* Server certificate: Symantec Class 3 Secure Server CA - G4
* Server certificate: VeriSign Class 3 Public Primary Certification Authority - G5
> POST /prod/mandrillListener HTTP/1.1
> Host: rl9b6lh8gk.execute-api.us-east-1.amazonaws.com
> User-Agent: curl/7.43.0
> Accept: */*
> Content-Length: 27
> Content-Type: application/x-www-form-urlencoded
>
* upload completely sent off: 27 out of 27 bytes
< HTTP/1.1 400 Bad Request
< Content-Type: application/json
< Content-Length: 180
< Connection: keep-alive
< Date: Thu, 28 Jan 2016 12:29:40 GMT
< x-amzn-RequestId: cd4d9232-c5ba-11e5-a158-b9b39f0b0599
< X-Cache: Error from cloudfront
< Via: 1.1 1915b8b49d2fbff532431a79650103eb.cloudfront.net (CloudFront)
< X-Amz-Cf-Id: cxU2_b5DzIw4M_n3hJBFXTu9AVRBL3GpbQqUId9IxgS004DfLYqYmg==
<
* Connection #0 to host rl9b6lh8gk.execute-api.us-east-1.amazonaws.com left intact
{"message": "Could not parse request body into json: Unrecognized token \'name\': was expecting \'null\', \'true\', \'false\' or NaN\n at [Source: [B#d92973b; line: 1, column: 6]"}
If I wrap the body with double-quotes it works fine:
% curl -v -X POST -d '"name=Ignacio&city=Tehuixtla"' https://rl9b6lh8gk.execute-api.us-east-1.amazonaws.com/prod/mandrillListener
* Trying 54.230.227.19...
* Connected to rl9b6lh8gk.execute-api.us-east-1.amazonaws.com (54.230.227.19) port 443 (#0)
* TLS 1.2 connection using TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
* Server certificate: *.execute-api.us-east-1.amazonaws.com
* Server certificate: Symantec Class 3 Secure Server CA - G4
* Server certificate: VeriSign Class 3 Public Primary Certification Authority - G5
> POST /prod/mandrillListener HTTP/1.1
> Host: rl9b6lh8gk.execute-api.us-east-1.amazonaws.com
> User-Agent: curl/7.43.0
> Accept: */*
> Content-Length: 29
> Content-Type: application/x-www-form-urlencoded
>
* upload completely sent off: 29 out of 29 bytes
< HTTP/1.1 200 OK
< Content-Type: application/json
< Content-Length: 6
< Connection: keep-alive
< Date: Thu, 28 Jan 2016 12:33:20 GMT
< x-amzn-RequestId: 50610606-c5bb-11e5-b140-5d837ffe26ed
< X-Cache: Miss from cloudfront
< Via: 1.1 a670cda0e28541e40881b95b60c672b7.cloudfront.net (CloudFront)
< X-Amz-Cf-Id: mCLKL4eOnpUMd15IXQZw0RStJHw9Vdf3ivdCl37dcmno2JFOfxw0Vg==
<
* Connection #0 to host rl9b6lh8gk.execute-api.us-east-1.amazonaws.com left intact
"true"%
The lamba has only one line:
context.succeed('true');
How can I make the api gateway do not treat the body as json?
I tried the documentation about template mapping with no success, I even tried to convert it to a static template, with no variables at all! In all cases the error happens before getting to my code.
Try to set mapping template as following:
{
"body" : $input.json('$')
}
This would convert you string into json and pass to lambda.
From amazon docs:
$input.json(x) function evaluates a JSONPath expression and returns the results as a JSON string.
This is not entirely related, but if you are new to Amazon API Gateway, one additional step I did not know was required was to (re) deploy your API after adding the mapping template as others have suggested (in the case you had previously deployed your API). This cost me a bunch of debugging time as I did not understand why I was continuing to get this error even after making the suggestions posted here.
If using the AWS Console,
navigate to any pane within your API
Select Actions menu at the top
Select Deploy API from the menu, choose the relevant stage and confirm
The mapping template to make form data work is pretty complicated. Here is a gist: https://gist.github.com/ryanray/668022ad2432e38493df
Also, you can see this post I wrote that has an example of how to integrate with Slack(their hooks send a POST as form data to API Gateway): http://www.ryanray.me/serverless-slack-integrations
In the API Gateway, select the POST method for your resource, select Integration Request and create a new Mapping Template for application/x-www-form-urlencoded:
#set($body = $input.path('$'))
#set($jsonString = $util.urlencode($body))
#set($json = $util.parsejson($jsonString))
{
"body" : $json,
}
Alternatively, you can simply pass the url encoded string:
#set($body = $input.path('$'))
{
"body" : "$body",
}
and url decode and parse the JSON in your lambda.

HTTP/1.1 401 Unauthorized in Response Headers in Load runner for GET Requests

I am new to Load runner , Am facing am issue while play back of the script
LR 12.50
O.S Windows 7 SP2
Protocol is Mobile HTTP/HTML
Recording mode is Proxy
Let me explain my scenario
While executing following function:
web_custom_request("authenticate",
"URL=https://ws-xx.xxx.com/tcs/rest/authenticate?include=user,company",
"Method=POST",
"Resource=0",
"RecContentType=application/json",
"Referer=",
"Snapshot=t1.inf",
"Mode=HTTP",
"EncType=application/json",
"Body={\"password\":\"xxx\",\"username\":\"xxx\",\"version\":\"1.0.40\"}",
LAST);
For the above POST method , am getting response as below
HTTP/1.1 200 OK\r\n
Date: Tue, 13 Oct 2015 19:19:21 GMT\r\n
Server: Apache-Coyote/1.1\r\n
Content-Type: application/json\r\n
Set-Cookie: dtCookie=DBE9311E44E5C47902702DC762030583|TXlBcHB8MQ; Path=/;
Domain=.xxx.com\r\n
Connection: close\r\n
Transfer-Encoding: chunked\r\n
Which is fine ,Now the second custom request is shown below
web_custom_request("profiles",
"URL=https://ws-test.xxx.com/tcs/rest/profiles",
"Method=GET",
"Resource=1",
"RecContentType=application/json",
"Referer=",
"Snapshot=t2.inf",
LAST);
For the above GET requests in the replay logs am getting:
401 unauthorized error.
GET /tcs/rest/profiles HTTP/1.1\r\n
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT)\r\n
Accept: */*\r\n
Connection: Keep-Alive\r\n
Host: ws-test.xxx.com\r\n
Cookie: dtCookie=DBE9311E44E5C47902702DC762030583|TXlBcHB8MQ\r\n
\r\n
t=5921ms: 172-byte response headers for "https://ws-test.xxx.com/tcs/rest/profiles" (RelFrameId=1, Internal ID=2)
HTTP/1.1 401 Unauthorized\r\n
Date: Tue, 13 Oct 2015 19:19:22 GMT\r\n
Server: Apache-Coyote/1.1\r\n
Content-Type: application/json\r\n
Connection: close\r\n
Transfer-Encoding: chunked\r\n
\r\n
t=5922ms: 4-byte chunked response overhead for "https://ws-test.xxx.com/tcs/rest/profiles" (RelFrameId=1, Internal ID=2)
8b\r\n
t=5923ms: 139-byte chunked response body for "https://ws-test.xxx.com/tcs/rest/profiles" (RelFrameId=1, Internal ID=2)
{"errors":[{"message":"Authentication required to access endpoint","status":"401","code":"
NotAuthenticated","header":"Not Authenticated"}]}
I refereed this link.
My understanding from the above custom request , login is success but the next
subsequent requests are getting failed.
I have used web_cleanup_cookies() function but didn't solve the issue .
I tried to capture the Cookie ID using the below function
web_reg_save_param("COOKIE_ID",
"LR= Cookie: dtCookie=" ,
"RB= |TXlBcHB8MQ\r\n",
"Ord=All",
"RelFrameId=1",
"Search=All",
LAST);
web_add_header("Cookie",lr_eval_string("{COOKIE_ID}"));
Now question is where to place parameter "COOKIE_ID" in my script while there is
no value in script for COOKIE_ID?
How to handle this issue ? Can anybody please help me .
Please add below headers to the script
web_set_sockets_option("SSL_VERSION","TLS");
web_set_user("username", "password", "domain:portno" );
web_set_sockets_option("INITIAL_BASIC_AUTH","1");
In Vugen, Select snapshot view and compare both record and replay requests, suspecting there might be a missing of header in replay request.
If cookie is the only thing changing you can add it by using web_add_cookie function.