#include <string> #include <iostream> #include <sstream> #include <fstream> #include <iomanip> #include <curl/curl.h> static ostringstream curl_result; /* curl write callback, to fill tidy's input buffer... */ uint write_cb(char *in, uint size, uint nmemb, void *out) { int r = size * nmemb; in[r] = '\0'; curl_result << in; return(r); } static bool recaptcha_check_answer(const char *private_key, const char *remoteip, const char *challenge, const char *response, std::string &error) { if (!remoteip || !*remoteip) { error = "For security reasons, you must pass the remote ip to reCAPTCHA"; return false; } //discard spam submissions if (!challenge || !*challenge || !response || !*response) { error = "Captcha challenge or response missing"; return false; } CURL *curl; CURLcode res; struct curl_httppost *formpost=NULL; struct curl_httppost *lastptr=NULL; if(curl_global_init(CURL_GLOBAL_SSL)) { error = "Error initialising curl library"; return false; } curl = curl_easy_init(); if(!curl) { error = "Error initialising curl library"; return false; } curl_formadd(&formpost, &lastptr, CURLFORM_COPYNAME, "privatekey", CURLFORM_COPYCONTENTS, private_key, CURLFORM_END); curl_formadd(&formpost, &lastptr, CURLFORM_COPYNAME, "remoteip", CURLFORM_COPYCONTENTS, remoteip, CURLFORM_END); curl_formadd(&formpost, &lastptr, CURLFORM_COPYNAME, "challenge", CURLFORM_COPYCONTENTS, challenge, CURLFORM_END); curl_formadd(&formpost, &lastptr, CURLFORM_COPYNAME, "response", CURLFORM_COPYCONTENTS, response, CURLFORM_END); const char *surl = "https://api-verify.recaptcha.net/verify"; curl_easy_setopt(curl, CURLOPT_URL, surl); curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L); curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 1L); curl_easy_setopt(curl, CURLOPT_HTTPPOST, formpost); #ifdef SKIP_HOSTNAME_VERFICATION /* * If the site you're connecting to uses a different host name that what * they have mentioned in their server certificate's commonName (or * subjectAltName) fields, libcurl will refuse to connect. You can skip * this check, but this will make the connection less secure. */ curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L); #endif curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_cb); res = curl_easy_perform(curl); /* always cleanup */ curl_easy_cleanup(curl); if(res && res != CURLE_RECV_ERROR) { std::ostringstream err; err << "Error " << res << " contacting captcha server"; error = err.str(); return false; } std::string resp = curl_result.str(); std::string::size_type pos = resp.find("\n"); std::string part1 = pos == std::string::npos ? resp : resp.substr(0, pos); if(part1 == "true") return true; error = pos == std::string::npos ? "Unknown captcha error" : "Captcha error:" + resp.substr(pos); return false; }This code relies on the curl library to handle the communication with the reCAPTCHA server.
Wednesday, 3 October 2012
Using reCAPTCHA from C++
I wanted to add reCAPTCHA to some old C++ CGI code, but I couldn't find a reCAPTCHA library for C++. Neither could a few other people I saw looking.
So I wrote the following code, which I am happy to share:
Subscribe to:
Posts (Atom)