summaryrefslogtreecommitdiffabout
path: root/lib/consumer.cc
Unidiff
Diffstat (limited to 'lib/consumer.cc') (more/less context) (show whitespace changes)
-rw-r--r--lib/consumer.cc1
1 files changed, 1 insertions, 0 deletions
diff --git a/lib/consumer.cc b/lib/consumer.cc
index ebda262..801496e 100644
--- a/lib/consumer.cc
+++ b/lib/consumer.cc
@@ -1,100 +1,101 @@
1#include <algorithm> 1#include <algorithm>
2#include <cassert> 2#include <cassert>
3#include <cstring> 3#include <cstring>
4#include <opkele/util.h> 4#include <opkele/util.h>
5#include <opkele/util-internal.h>
5#include <opkele/curl.h> 6#include <opkele/curl.h>
6#include <opkele/exception.h> 7#include <opkele/exception.h>
7#include <opkele/data.h> 8#include <opkele/data.h>
8#include <opkele/consumer.h> 9#include <opkele/consumer.h>
9#include <openssl/sha.h> 10#include <openssl/sha.h>
10#include <openssl/hmac.h> 11#include <openssl/hmac.h>
11#include <iostream> 12#include <iostream>
12 13
13#include "config.h" 14#include "config.h"
14 15
15#include <pcre.h> 16#include <pcre.h>
16 17
17namespace opkele { 18namespace opkele {
18 using namespace std; 19 using namespace std;
19 using util::curl_t; 20 using util::curl_t;
20 using util::curl_pick_t; 21 using util::curl_pick_t;
21 22
22 class pcre_matches_t { 23 class pcre_matches_t {
23 public: 24 public:
24 int *_ov; 25 int *_ov;
25 int _s; 26 int _s;
26 27
27 pcre_matches_t() : _ov(0), _s(0) { } 28 pcre_matches_t() : _ov(0), _s(0) { }
28 pcre_matches_t(int s) : _ov(0), _s(s) { 29 pcre_matches_t(int s) : _ov(0), _s(s) {
29 if(_s&1) ++_s; 30 if(_s&1) ++_s;
30 _s += _s>>1; 31 _s += _s>>1;
31 _ov = new int[_s]; 32 _ov = new int[_s];
32 } 33 }
33 ~pcre_matches_t() throw() { if(_ov) delete[] _ov; } 34 ~pcre_matches_t() throw() { if(_ov) delete[] _ov; }
34 35
35 int begin(int i) const { return _ov[i<<1]; } 36 int begin(int i) const { return _ov[i<<1]; }
36 int end(int i) const { return _ov[(i<<1)+1]; } 37 int end(int i) const { return _ov[(i<<1)+1]; }
37 int length(int i) const { int t=i<<1; return _ov[t+1]-_ov[t]; } 38 int length(int i) const { int t=i<<1; return _ov[t+1]-_ov[t]; }
38 }; 39 };
39 40
40 class pcre_t { 41 class pcre_t {
41 public: 42 public:
42 pcre *_p; 43 pcre *_p;
43 44
44 pcre_t() : _p(0) { } 45 pcre_t() : _p(0) { }
45 pcre_t(pcre *p) : _p(p) { } 46 pcre_t(pcre *p) : _p(p) { }
46 pcre_t(const char *re,int opts) : _p(0) { 47 pcre_t(const char *re,int opts) : _p(0) {
47 static const char *errptr; static int erroffset; 48 static const char *errptr; static int erroffset;
48 _p = pcre_compile(re,opts,&errptr,&erroffset,NULL); 49 _p = pcre_compile(re,opts,&errptr,&erroffset,NULL);
49 if(!_p) 50 if(!_p)
50 throw internal_error(OPKELE_CP_ string("Failed to compile regexp: ")+errptr); 51 throw internal_error(OPKELE_CP_ string("Failed to compile regexp: ")+errptr);
51 } 52 }
52 ~pcre_t() throw() { if(_p) (*pcre_free)(_p); } 53 ~pcre_t() throw() { if(_p) (*pcre_free)(_p); }
53 54
54 pcre_t& operator=(pcre *p) { if(_p) (*pcre_free)(_p); _p=p; return *this; } 55 pcre_t& operator=(pcre *p) { if(_p) (*pcre_free)(_p); _p=p; return *this; }
55 56
56 operator const pcre*(void) const { return _p; } 57 operator const pcre*(void) const { return _p; }
57 operator pcre*(void) { return _p; } 58 operator pcre*(void) { return _p; }
58 59
59 int exec(const string& s,pcre_matches_t& m) { 60 int exec(const string& s,pcre_matches_t& m) {
60 if(!_p) 61 if(!_p)
61 throw internal_error(OPKELE_CP_ "Trying to execute absent regexp"); 62 throw internal_error(OPKELE_CP_ "Trying to execute absent regexp");
62 return pcre_exec(_p,NULL,s.c_str(),s.length(),0,0,m._ov,m._s); 63 return pcre_exec(_p,NULL,s.c_str(),s.length(),0,0,m._ov,m._s);
63 } 64 }
64 }; 65 };
65 66
66 assoc_t consumer_t::associate(const string& server) { 67 assoc_t consumer_t::associate(const string& server) {
67 util::dh_t dh = DH_new(); 68 util::dh_t dh = DH_new();
68 if(!dh) 69 if(!dh)
69 throw exception_openssl(OPKELE_CP_ "failed to DH_new()"); 70 throw exception_openssl(OPKELE_CP_ "failed to DH_new()");
70 dh->p = util::dec_to_bignum(data::_default_p); 71 dh->p = util::dec_to_bignum(data::_default_p);
71 dh->g = util::dec_to_bignum(data::_default_g); 72 dh->g = util::dec_to_bignum(data::_default_g);
72 if(!DH_generate_key(dh)) 73 if(!DH_generate_key(dh))
73 throw exception_openssl(OPKELE_CP_ "failed to DH_generate_key()"); 74 throw exception_openssl(OPKELE_CP_ "failed to DH_generate_key()");
74 string request = 75 string request =
75 "openid.mode=associate" 76 "openid.mode=associate"
76 "&openid.assoc_type=HMAC-SHA1" 77 "&openid.assoc_type=HMAC-SHA1"
77 "&openid.session_type=DH-SHA1" 78 "&openid.session_type=DH-SHA1"
78 "&openid.dh_consumer_public="; 79 "&openid.dh_consumer_public=";
79 request += util::url_encode(util::bignum_to_base64(dh->pub_key)); 80 request += util::url_encode(util::bignum_to_base64(dh->pub_key));
80 curl_pick_t curl = curl_pick_t::easy_init(); 81 curl_pick_t curl = curl_pick_t::easy_init();
81 if(!curl) 82 if(!curl)
82 throw exception_curl(OPKELE_CP_ "failed to initialize curl"); 83 throw exception_curl(OPKELE_CP_ "failed to initialize curl");
83 CURLcode r; 84 CURLcode r;
84 (r=curl.misc_sets()) 85 (r=curl.misc_sets())
85 || (r=curl.easy_setopt(CURLOPT_URL,server.c_str())) 86 || (r=curl.easy_setopt(CURLOPT_URL,server.c_str()))
86 || (r=curl.easy_setopt(CURLOPT_POST,1)) 87 || (r=curl.easy_setopt(CURLOPT_POST,1))
87 || (r=curl.easy_setopt(CURLOPT_POSTFIELDS,request.data())) 88 || (r=curl.easy_setopt(CURLOPT_POSTFIELDS,request.data()))
88 || (r=curl.easy_setopt(CURLOPT_POSTFIELDSIZE,request.length())) 89 || (r=curl.easy_setopt(CURLOPT_POSTFIELDSIZE,request.length()))
89 || (r=curl.set_write()) 90 || (r=curl.set_write())
90 ; 91 ;
91 if(r) 92 if(r)
92 throw exception_curl(OPKELE_CP_ "failed to set curly options",r); 93 throw exception_curl(OPKELE_CP_ "failed to set curly options",r);
93 if( (r=curl.easy_perform()) ) 94 if( (r=curl.easy_perform()) )
94 throw exception_curl(OPKELE_CP_ "failed to perform curly request",r); 95 throw exception_curl(OPKELE_CP_ "failed to perform curly request",r);
95 params_t p; p.parse_keyvalues(curl.response); 96 params_t p; p.parse_keyvalues(curl.response);
96 if(p.has_param("assoc_type") && p.get_param("assoc_type")!="HMAC-SHA1") 97 if(p.has_param("assoc_type") && p.get_param("assoc_type")!="HMAC-SHA1")
97 throw bad_input(OPKELE_CP_ "unsupported assoc_type"); 98 throw bad_input(OPKELE_CP_ "unsupported assoc_type");
98 string st; 99 string st;
99 if(p.has_param("session_type")) st = p.get_param("session_type"); 100 if(p.has_param("session_type")) st = p.get_param("session_type");
100 if((!st.empty()) && st!="DH-SHA1") 101 if((!st.empty()) && st!="DH-SHA1")