-rw-r--r-- | lib/consumer.cc | 2 |
1 files changed, 1 insertions, 1 deletions
diff --git a/lib/consumer.cc b/lib/consumer.cc index dc49405..30a5507 100644 --- a/lib/consumer.cc +++ b/lib/consumer.cc @@ -1,108 +1,108 @@ #include <algorithm> #include <cassert> #include <opkele/util.h> #include <opkele/exception.h> #include <opkele/data.h> #include <opkele/consumer.h> #include <openssl/sha.h> #include <openssl/hmac.h> #include <curl/curl.h> #include <pcre++.h> #include <iostream> #include "config.h" namespace opkele { using namespace std; class curl_t { public: CURL *_c; curl_t() : _c(0) { } curl_t(CURL *c) : _c(c) { } ~curl_t() throw() { if(_c) curl_easy_cleanup(_c); } curl_t& operator=(CURL *c) { if(_c) curl_easy_cleanup(_c); _c=c; return *this; } operator const CURL*(void) const { return _c; } operator CURL*(void) { return _c; } }; static CURLcode curl_misc_sets(CURL* c) { CURLcode r; (r=curl_easy_setopt(c,CURLOPT_FOLLOWLOCATION,1)) || (r=curl_easy_setopt(c,CURLOPT_MAXREDIRS,5)) || (r=curl_easy_setopt(c,CURLOPT_DNS_CACHE_TIMEOUT,120)) || (r=curl_easy_setopt(c,CURLOPT_DNS_USE_GLOBAL_CACHE,1)) || (r=curl_easy_setopt(c,CURLOPT_USERAGENT,PACKAGE_NAME"/"PACKAGE_VERSION)) || (r=curl_easy_setopt(c,CURLOPT_TIMEOUT,20)) #ifdef DISABLE_CURL_SSL_VERIFYHOST || (r=curl_easy_setopt(c,CURLOPT_SSL_VERIFYHOST,0)) #endif -#ifdef DISABLE_CURL_SSL_VERYPEER +#ifdef DISABLE_CURL_SSL_VERIFYPEER || (r=curl_easy_setopt(c,CURLOPT_SSL_VERIFYPEER,0)) #endif ; return r; } static size_t _curl_tostring(void *ptr,size_t size,size_t nmemb,void *stream) { string *str = (string*)stream; size_t bytes = size*nmemb; size_t get = min(16384-str->length(),bytes); str->append((const char*)ptr,get); return get; } assoc_t consumer_t::associate(const string& server) { util::dh_t dh = DH_new(); if(!dh) throw exception_openssl(OPKELE_CP_ "failed to DH_new()"); dh->p = util::dec_to_bignum(data::_default_p); dh->g = util::dec_to_bignum(data::_default_g); if(!DH_generate_key(dh)) throw exception_openssl(OPKELE_CP_ "failed to DH_generate_key()"); string request = "openid.mode=associate" "&openid.assoc_type=HMAC-SHA1" "&openid.session_type=DH-SHA1" "&openid.dh_consumer_public="; request += util::url_encode(util::bignum_to_base64(dh->pub_key)); curl_t curl = curl_easy_init(); if(!curl) throw exception_curl(OPKELE_CP_ "failed to curl_easy_init()"); string response; CURLcode r; (r=curl_misc_sets(curl)) || (r=curl_easy_setopt(curl,CURLOPT_URL,server.c_str())) || (r=curl_easy_setopt(curl,CURLOPT_POST,1)) || (r=curl_easy_setopt(curl,CURLOPT_POSTFIELDS,request.data())) || (r=curl_easy_setopt(curl,CURLOPT_POSTFIELDSIZE,request.length())) || (r=curl_easy_setopt(curl,CURLOPT_WRITEFUNCTION,_curl_tostring)) || (r=curl_easy_setopt(curl,CURLOPT_WRITEDATA,&response)) ; if(r) throw exception_curl(OPKELE_CP_ "failed to curl_easy_setopt()",r); if(r=curl_easy_perform(curl)) throw exception_curl(OPKELE_CP_ "failed to curl_easy_perform()",r); params_t p; p.parse_keyvalues(response); if(p.has_param("assoc_type") && p.get_param("assoc_type")!="HMAC-SHA1") throw bad_input(OPKELE_CP_ "unsupported assoc_type"); string st; if(p.has_param("session_type")) st = p.get_param("session_type"); if((!st.empty()) && st!="DH-SHA1") throw bad_input(OPKELE_CP_ "unsupported session_type"); secret_t secret; if(st.empty()) { secret.from_base64(p.get_param("mac_key")); }else{ util::bignum_t s_pub = util::base64_to_bignum(p.get_param("dh_server_public")); vector<unsigned char> ck(DH_size(dh)); int cklen = DH_compute_key(&(ck.front()),s_pub,dh); if(cklen<0) throw exception_openssl(OPKELE_CP_ "failed to DH_compute_key()"); ck.resize(cklen); // OpenID algorithm requires extra zero in case of set bit here if(ck[0]&0x80) ck.insert(ck.begin(),1,0); |