-rw-r--r-- | lib/consumer.cc | 1 |
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 | ||
17 | namespace opkele { | 18 | namespace 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") |