Checking existing URL - c++

I am trying to make this working code to check if URL exists (coded Visual C++):
void urlexists()
{
try
{
LPCWSTR pfile(NULL);
HRESULT hRez = URLDownloadToFile(NULL, _T("http://google.com"), (pfile), 0, NULL);
if (hRez != 0)
return;
}
catch (...)
{
return;
}
}
and make it portable for linux distros. What should I do? I didn't found nothing on Internet

As far as the process goes, if you make a GET request to the URL, you will get a 200/OK code back if the resource exists. You will receive a 404 if it does not. Your file will be in the body of the request if the request succeeds. You then copy the request body to the file on disk.
There isn't a good way to make this portable without writing a libcurl, winhttp, and possibly a core foundation implementation. You either need to abstract this and write an implementation for each platform, or use a library that does it for you. There are a few options. Boost has an http client you could use. Also, the AWS SDK for C++ has an http implementation that will do this for you.
Your other option is to read the HTTP spec, open the socket yourself and make the request manually. Fair warning however, this is non-trivial especially if TLS is involved.
If you want to write it yourself, I recommend libcurl for your linux implementation. You are more than welcome to use the examples here as a starting point. https://github.com/awslabs/aws-sdk-cpp/tree/master/aws-cpp-sdk-core/include/aws/core/http

Related

WinHttpSendRequest: 2148074273 insufficient cache

I am building a Rest client with cpprest-sdk to communicate with a web service. The problem is that every once in a while, after sending multiple successful requests (around 50), I get the exception:
WinHttpSendRequest: 2148074273 insufficient cache in function
Or sometimes:
ERROR_WINHTTP_SECURE_FAILURE (12175)
I tried to look for cache options in cpprest-sdk but did not find anything. Since the exceptions happens inside cpprest-sdk when I call .wait() on my task I am not sure if I can use the WINHTTP_STATUS_CALLBACK to check for more details on this error. How can I investigate deeper to find the cause of this error?
Here is my Rest request:
void MyRestClient::PostKeys(const std::string & sKek, const std::string & sKid, const std::string & sCustomerAuthenticator) {
uri_builder oBuilder(U("/keys?customerAuthenticator=") + to_string_t(sCustomerAuthenticator));
oBuilder.append_query(KEK, to_string_t(sKek));
json::value oBody;
oBody[KID] = json::value::string(to_string_t(sKid));
web::http::http_request oRequest;
oRequest.set_method(methods::POST);
oRequest.set_request_uri(oBuilder.to_uri());
oRequest.set_body(oBody);
m_oCurrentTask = oClient.request(oRequest).then([this](http_response oResponse) {
OnPostResponse(oResponse);
});
}
According to https://msdn.microsoft.com/en-us/library/windows/desktop/aa383928(v=vs.85).aspx (4th bullet), Post requests should not be cached so I don't understand why I am getting the first exception. I also tried to disable Https caching as the 6th bullet in the link suggest, but that did not change anything.
Did anyone experienced something similar or have any insight as to what may be happening? Or is this a normal behavior and should I just retry my request when these exceptions happens?
Does your Web Service use TLS with Diffie-Hellman key exchange? If yes, you are probably seeing a bug in SChannel, which is the SSL implementation of Windows, see here for a confirmation. Unfortunately, the only available fix is an update of the Windows version on which your client is running to a recent build of Windows 10.

c++ send request to API on webserver then receive json array response?

I'm wondering the most simple way to send a request to a API on my server then receive the API's response (json array) wihtout using any libraries. I've tried using libs like cURL & boost without any luck which is the reason i want to stay away from them. I've searched for many days for a answer and have not been able to find anything, which is why i've resorted to coming to the stack overflow community!
Even though the question is about not using a library I 'am taking this opportunity to show how easy it is to use a library than the user thinks.
Its better to use pre-built libraries and stop reinventing the wheel. You can use curlcpp library. Its a wrapper for libcurl. Using this library HTTP requests can be made easily. Learning curve is also less and it provides C++ style access which makes it more comfortable to work with.
The following code is taken from their gitHub page - https://github.com/JosephP91/curlcpp
It makes a simple GET request to Google and retrieves the HTML response. You can use this example to hit apis too.
#include "curl_easy.h"
#include "curl_exception.h"
using curl::curl_easy;
using curl::curl_easy_exception;
using curl::curlcpp_traceback;
int main(int argc, const char **argv) {
curl_easy easy;
// Add some option to the curl_easy object.
easy.add<CURLOPT_URL>("http://www.google.it");
easy.add<CURLOPT_FOLLOWLOCATION>(1L);
try {
// Execute the request.
easy.perform();
} catch (curl_easy_exception error) {
// If you want to get the entire error stack we can do:
curlcpp_traceback errors = error.get_traceback();
// Otherwise we could print the stack like this:
error.print_traceback();
// Note that the printing the stack will erase it
}
return 0;
}

Best method to create a c++ app to communicate with nginx

I need to write a C++ interface that can read our data structure and provide the o/p based on query using http protocol.
Server Need
It should be able to serve 100 clients at the same time.
Why C++
All code is already written in C++. So we need to just write a http layer in C++. That's why I am choosing C++ instead of a more conventional web-programming language.
I am thinking to use nginx to serve static files and use its proxy pass to communicate with C++.
There are two approaches I have found:
Write a FastCGI c++ module.
Write a node.js c++ module.
Please just any other suggestion if you have
Can you please list the pros and cons for each method based on prior experience?
No one here seems to have addressed the actual question, though some nice work arounds have been offered. I've been able to build C++ modules for nginx with a couple of minor changes.
Change the module source file name to end with .cpp so gcc realizes it is dealing with C++.
Make sure all your Nginx includes (e.g. ngx_config.h, ngx_core.h, etc.) are wrapped with an extern "C" { } structure. Similarly make sure any functions called through Nginx function pointers are declared with a wrapper.
Add --with-ld-opt="-lstdc++" to your "configure" invocation when setting up Nginx.
With those three steps your module should compile, build, link, and actually work.
I think I will go forward with Nginx module devlopment http://www.evanmiller.org/nginx-modules-guide.html
Why ?
It don't require any other library dependency like fastcgi and
other.
I can use all feature of nginx inside my module.
What you are asking is basically how to turn the c++ process that holds your data strutures into a webserver. That might not be the best way to go about it. (Then again, maybe it is in your situation. It depends on the complexity of the c++ process's interfaces you are trying to expose i guess.)
Anyways, I would try to stick a small http frontend in between the c++ process and the clients that could do the http work and communicate with the c++ backend process using some simple messaging protocol like ZeroMQ/zmq.
zmq in c/c++ is fairly straight forward, and its very efficient and very fast. Using zmq you could very quickly setup a simple webserver frontend in python, or whatever language you prefer that has zmq bindings, and have that frontend communicate asyncronously or syncronously with the backend c++ process using zmq.
The c++ examples and the guide are nice starting points if you are looking into using zmq.
For Node.js there are also a few examples.
Try G-WAN, it allows you to use your c++ application directly.
You may try nginx c function
It is simple to use and built in nginx cache memory on apps layer, wiki for nginx c function
Example project with cpp
Sample code:
#include <stdio.h>
#include <ngx_http_c_func_module.h>
/*** build the program as .so library and copy to the preferred place for nginx to link this library ***/
/*** gcc -shared -o libcfuntest.so -fPIC cfuntest.c ***/
/*** cp libcfuntest.so /etc/nginx/ ***/
int is_service_on = 0;
void ngx_http_c_func_init(ngx_http_c_func_ctx_t* ctx) {
ngx_http_c_func_log(info, ctx, "%s", "Starting The Application");
is_service_on=1;
}
void my_app_simple_get_greeting(ngx_http_c_func_ctx_t *ctx) {
ngx_http_c_func_log_info(ctx, "Calling back and log from my_app_simple_get");
ngx_http_c_func_write_resp(
ctx,
200,
"200 OK",
"text/plain",
"greeting from ngx_http_c_func testing"
);
}
void my_app_simple_get_args(ngx_http_c_func_ctx_t *ctx) {
ngx_http_c_func_log_info(ctx, "Calling back and log from my_app_simple_get_args");
ngx_http_c_func_write_resp(
ctx,
200,
"200 OK",
"text/plain",
ctx->req_args
);
}
void my_app_simple_get_token_args(ngx_http_c_func_ctx_t *ctx) {
ngx_http_c_func_log_info(ctx, "Calling back and log from my_app_simple_get_token_args");
char * tokenArgs = ngx_http_c_func_get_query_param(ctx, "token");
if (! tokenArgs) {
ngx_http_c_func_write_resp(
ctx,
401,
"401 unauthorized",
"text/plain",
"Token Not Found"
);
} else {
ngx_http_c_func_write_resp(
ctx,
401,
"401 unauthorized",
"text/plain",
tokenArgs
);
}
}
void my_app_simple_post(ngx_http_c_func_ctx_t *ctx) {
ngx_http_c_func_log_info(ctx, "Calling back and log from my_app_simple_post");
ngx_http_c_func_write_resp(
ctx,
202,
"202 Accepted and Processing",
"text/plain",
ctx->req_body
);
}
void my_app_simple_get_no_resp(ngx_http_c_func_ctx_t *ctx) {
ngx_http_c_func_log_info(ctx, "Calling back and log from my_app_simple_get_no_resp");
}
void ngx_http_c_func_exit(ngx_http_c_func_ctx_t* ctx) {
ngx_http_c_func_log(info, ctx, "%s\n", "Shutting down The Application");
is_service_on = 0;
}
Just add an HTTP frontend to your C++ code, possibly using a library such as Beast, and then proxy_pass from nginx to your C++ server. You may or may not need nginx at all, depending on your use.

Using libcurl to upload files to DropBox

I'm trying to use the libcurl in a C/C++ application to post files to DropBox.
I would like to use the "/files (POST)" API as documented here...
https://www.dropbox.com/developers/reference/api#files-POST
I am having problems with properly authenticating (OAuth) this call. It is unclear to me how to properly create the authentication signature.
From some a sample I saw, it looked like they were reading in the whole file to create the HMAC-SHA1 encoding on. This seems problematic on large files.
Does anyone have experience or insight using this API or something similar?
I have just use the libouth and libcurl to get information from sina weibo. here is my example for you refer. you can also refer the liboauth test programmer in the tests dir, oauthtest.c
if (use_post)
{
req_url = oauth_sign_url2(test_call_uri, &postarg, OA_HMAC, NULL, c_key, c_secret, t_key, t_secret);
reply = oauth_http_post(req_url,postarg);
}
I suggest using BOOST ASIO . Makes uploading and downloading a breeze.

What's the correct way to verify an SSL certificate in Win32?

I want to verify an SSL certificate in Win32 using C++. I think I want to use the Cert* API so that I can get the benefit of the Windows certificate store. This is what I've come up with.
Is it correct?
Is there a better way to do this?
Am I doing anything wrong?
bool IsValidSSLCertificate( PCCERT_CONTEXT certificate, LPWSTR serverName )
{
LPTSTR usages[] = { szOID_PKIX_KP_SERVER_AUTH };
CERT_CHAIN_PARA params = { sizeof( params ) };
params.RequestedUsage.dwType = USAGE_MATCH_TYPE_AND;
params.RequestedUsage.Usage.cUsageIdentifier = _countof( usages );
params.RequestedUsage.Usage.rgpszUsageIdentifier = usages;
PCCERT_CHAIN_CONTEXT chainContext = 0;
if ( !CertGetCertificateChain( NULL,
certificate,
NULL,
NULL,
&params,
CERT_CHAIN_REVOCATION_CHECK_CHAIN,
NULL,
&chainContext ) )
{
return false;
}
SSL_EXTRA_CERT_CHAIN_POLICY_PARA sslPolicy = { sizeof( sslPolicy ) };
sslPolicy.dwAuthType = AUTHTYPE_SERVER;
sslPolicy.pwszServerName = serverName;
CERT_CHAIN_POLICY_PARA policy = { sizeof( policy ) };
policy.pvExtraPolicyPara = &sslPolicy;
CERT_CHAIN_POLICY_STATUS status = { sizeof( status ) };
BOOL verified = CertVerifyCertificateChainPolicy( CERT_CHAIN_POLICY_SSL,
chainContext,
&policy,
&status );
CertFreeCertificateChain( chainContext );
return verified && status.dwError == 0;
}
You should be aware of RFC3280 section 6.1 and RFC5280 section 6.1. Both describe algorithms for validating certificate paths. Even though Win32 API takes care of some things for you, it could still be valuable to know about the process in general.
Also, here’s a (in my opinion) pretty trustworthy reference: Chromium certificate verification code.
Overall, I think your code isn't incorrect. But here’s a few things I’d look into/change, if I were you:
1. Separate Common Name Validation
Chromium validates certificate common name separately from the chain. Apparently they've noticed some problems with it. See the comments for their rationale:
cert_verify_proc.win.cc:731 // Certificate name validation happens separately, later, using an internal
cert_verify_proc.win.cc:732 // routine that has better support for RFC 6125 name matching.
2. Use CERT_CHAIN_REVOCATION_CHECK_CHAIN_EXCLUDE_ROOT
Chromium also uses the CERT_CHAIN_REVOCATION_CHECK_CHAIN_EXCLUDE_ROOT flag instead of CERT_CHAIN_REVOCATION_CHECK_CHAIN. I actually started to looking into this before I found their code, and it reinforced my belief that you should use CERT_CHAIN_REVOCATION_CHECK_CHAIN_EXCLUDE_ROOT.
Even though both aforementioned RFCs specify that a self-signed trust anchor is not considered part of a chain, the documentation for CertGetCertificateChain (http://msdn.microsoft.com/en-us/library/windows/desktop/aa376078(v=vs.85).aspx) says it builds a chain up to, if possible, a trusted root certificate. A trusted root certificate is defined (on the same page) as a trusted self-signed certificate.
This eliminates the possibility that *EXCLUDE_ROOT might skip revocation checking for a non-root trust anchor (Win32 actually requires trust-anchors to be self-signed, even though it is not required by any RFCs. Though this is not officially documented).
Now, since a root CA certificate can not revoke itself (the CRL could not be signed/verified), it seems to me that these two flags are identical.
I did some googling and stumbled across this forum post: http://social.msdn.microsoft.com/Forums/windowsdesktop/en-US/9f95882a-1a68-477a-80ee-0a7e3c7ae5cf/x509revocationflag-question?forum=windowssecurity. A member of .NET Product Group (supposedly) claims that the flags in practice act the same, if the root is self-signed (in theory, the ENTIRE_CHAIN flag would check the root certificate for revocation if it included a CDP extension, but that can’t happen).
He also recommends to use the *EXCLUDE_ROOT flag, because the other flag could cause an unnecessary network request, if the self-signed root CA includes the CDP extension.
Unfortunately:
I can’t find any officially documented explanation on the differences between the two flags.
Even though it is likely that the linked discussion applies to the same Win32 API flags under the hood of .NET, it is not guaranteed.
To be completely sure that it’s ok to use CERT_CHAIN_REVOCATION_CHECK_CHAIN_EXCLUDE_ROOT, I googled a bit more and found the Chromium SSL certificate verification code I linked to at the top of my reply.
As an added bonus, the Chromium cert_verify_proc_win.cc file contains the following hints about IE verification code:
618: // IE passes a non-NULL pTime argument that specifies the current system
619: // time. IE passes CERT_CHAIN_REVOCATION_CHECK_CHAIN_EXCLUDE_ROOT as the
620: // chain_flags argument.
Not sure how they’d know this, but at this point I’d feel comfortable using CERT_CHAIN_REVOCATION_CHECK_EXCLUDE_ROOT.
3. Different Accepted Certificate Usages
I noticed Chromium also specifies 3 certificate usages instead of 1:
szOID_PKIX_KP_SERVER_AUTH,
szOID_SERVER_GATED_CRYPTO,
szOID_SGC_NETSCAPE
From what I can gather through Google, the other usages can be required by older web browsers, otherwise they can fail to establish a secure connection.
If Chromium deems fit to include these usages, I'd follow suit.
Note that if you change your code, you should also set params.RequestedUsage.dwType to USAGE_MATCH_TYPE_OR instead of USAGE_MATCH_TYPE_AND.
—
I can’t think of any other comments at the moment. But if I were you, I’d check out Chromium source myself (and maybe Firefox too) - just to be sure I haven’t missed anything.
I think the best answer depends on what exactly you are attempting to do.
I will caution you that SSL is based on the assumption that Both endpoints want a secure connection. If either endpoint isn't interested in maintaining security then there is none.
Its a trivial effort to put byte codes in your distributed code that simply returns true for this function. That's why windows moved a lot of validation into the kernel. But they didn't anticipate people running windows on virtual hardware, which makes circumventing the OS just about as trivial.
Now consider that you expect to be provided a cert from some source, but pretending that that source couldn't be provided the same information from a reliable source. And then hand it to you. So You cannot rely on certificates to "prove" anyone is anyone in particular.
The only protection gained from certificates are in preventing outsiders, not endpoints, from breaching the confidentiality of the message being transported.
Any other use is doomed to fail, and it will fail eventually with potentially catastrophic results.
Sorry for the big post. The comment section has a word limit.
The functions CertGetCertificateChain and CertVerifyCertificatePolicy go together. This part is correct.
For CertGetCertificateChain the flag can be set to any of the following three if you want to check for revocation:
CERT_CHAIN_REVOCATION_CHECK_END_CERT
CERT_CHAIN_REVOCATION_CHECK_CHAIN
CERT_CHAIN_REVOCATION_CHECK_CHAIN_EXCLUDE_ROOT.
Only one of them can be used, these three options cannot be ORed. Beside one of these flags you can consider how the chain should be created; using local cache or just CRL or OCSP. For these considerations read this link.
Error in executing the function or more simply if the return value is 0, it does not mean the certificate is invalid, rather you were unable to perform the operation. For error information use GetLastError(). So your logic of returning false is wrong, it is more of a case of throwing the error and let the client code decide whether to try again or go on to do other stuff.
In this link there is a section called "classify the error", please read that. Basically you should check certChainContext->TrustStatus.dwErrorStatus. Here a list of error statuses will be ORed. Please check CERT_TRUST_STATUS msdn reference. So here you can have your business logic. For example, if you find the error status of the value (CERT_TRUST_REVOCATION_STATUS_UNKNOWN | CERT_TRUST_IS_OFFLINE_REVOCATION) that certificate revocation check could not be performed, you have the option to decide what you want (let the cert go or still mark it as invalid).
So, before going to call CertVerifyCertificatePolicy you have the option to discard or already flag a validation error.
If you choose to come to CertVerifyCertificatePolicy, the chromium code is a wonderful reference regarding how to map policy_status.dwError to your error class/enum.