author | Michael Krelin <hacker@klever.net> | 2008-02-16 17:49:22 (UTC) |
---|---|---|
committer | Michael Krelin <hacker@klever.net> | 2008-02-16 17:49:22 (UTC) |
commit | 21bddce2d98394865cf2ed0b144f92bbb6993bc9 (patch) (unidiff) | |
tree | e30194fab08a704885ae00c711e1707dc73bed83 | |
parent | ccdfc6eacec435a59d773127762ad0b6bce07149 (diff) | |
download | libopkele-21bddce2d98394865cf2ed0b144f92bbb6993bc9.zip libopkele-21bddce2d98394865cf2ed0b144f92bbb6993bc9.tar.gz libopkele-21bddce2d98394865cf2ed0b144f92bbb6993bc9.tar.bz2 |
moved some stuff out of the now installed util.h header
Signed-off-by: Michael Krelin <hacker@klever.net>
-rw-r--r-- | include/Makefile.am | 3 | ||||
-rw-r--r-- | include/opkele/util-internal.h | 92 | ||||
-rw-r--r-- | include/opkele/util.h | 92 | ||||
-rw-r--r-- | lib/basic_op.cc | 1 | ||||
-rw-r--r-- | lib/basic_rp.cc | 1 | ||||
-rw-r--r-- | lib/consumer.cc | 1 | ||||
-rw-r--r-- | lib/server.cc | 1 | ||||
-rw-r--r-- | test/idiscover.cc | 1 |
8 files changed, 110 insertions, 82 deletions
diff --git a/include/Makefile.am b/include/Makefile.am index 9f5982c..f842bb9 100644 --- a/include/Makefile.am +++ b/include/Makefile.am | |||
@@ -1,32 +1,33 @@ | |||
1 | NODIST_HEADERS_ = \ | 1 | NODIST_HEADERS_ = \ |
2 | opkele/acconfig.h \ | 2 | opkele/acconfig.h \ |
3 | opkele/tr1-mem.h | 3 | opkele/tr1-mem.h |
4 | 4 | ||
5 | nobase_include_HEADERS = \ | 5 | nobase_include_HEADERS = \ |
6 | opkele/opkele-config.h \ | 6 | opkele/opkele-config.h \ |
7 | opkele/types.h \ | 7 | opkele/types.h \ |
8 | opkele/association.h \ | 8 | opkele/association.h \ |
9 | opkele/exception.h \ | 9 | opkele/exception.h \ |
10 | opkele/server.h \ | 10 | opkele/server.h \ |
11 | opkele/consumer.h \ | 11 | opkele/consumer.h \ |
12 | opkele/extension.h \ | 12 | opkele/extension.h \ |
13 | opkele/sreg.h \ | 13 | opkele/sreg.h \ |
14 | opkele/extension_chain.h \ | 14 | opkele/extension_chain.h \ |
15 | opkele/xconsumer.h \ | 15 | opkele/xconsumer.h \ |
16 | opkele/xserver.h \ | 16 | opkele/xserver.h \ |
17 | opkele/uris.h \ | 17 | opkele/uris.h \ |
18 | opkele/tr1-mem.h \ | 18 | opkele/tr1-mem.h \ |
19 | opkele/basic_rp.h opkele/prequeue_rp.h \ | 19 | opkele/basic_rp.h opkele/prequeue_rp.h \ |
20 | opkele/iterator.h \ | 20 | opkele/iterator.h \ |
21 | opkele/basic_op.h opkele/verify_op.h \ | 21 | opkele/basic_op.h opkele/verify_op.h \ |
22 | opkele/util.h \ | ||
22 | ${NODIST_HEADERS_} | 23 | ${NODIST_HEADERS_} |
23 | 24 | ||
24 | noinst_HEADERS = \ | 25 | noinst_HEADERS = \ |
25 | opkele/data.h \ | 26 | opkele/data.h \ |
26 | opkele/curl.h opkele/expat.h opkele/tidy.h \ | 27 | opkele/curl.h opkele/expat.h opkele/tidy.h \ |
27 | opkele/util.h \ | 28 | opkele/util-internal.h \ |
28 | opkele/debug.h \ | 29 | opkele/debug.h \ |
29 | opkele/discovery.h | 30 | opkele/discovery.h |
30 | 31 | ||
31 | dist-hook: | 32 | dist-hook: |
32 | rm -f $(addprefix ${distdir}/,${NODIST_HEADERS_}) | 33 | rm -f $(addprefix ${distdir}/,${NODIST_HEADERS_}) |
diff --git a/include/opkele/util-internal.h b/include/opkele/util-internal.h new file mode 100644 index 0000000..ec091ce --- a/dev/null +++ b/include/opkele/util-internal.h | |||
@@ -0,0 +1,92 @@ | |||
1 | #ifndef __OPKELE_UTIL_INTERNAL_H | ||
2 | #define __OPKELE_UTIL_INTERNAL_H | ||
3 | |||
4 | #include <openssl/bn.h> | ||
5 | #include <openssl/dh.h> | ||
6 | |||
7 | namespace opkele { | ||
8 | namespace util { | ||
9 | |||
10 | /** | ||
11 | * Convenience class encapsulating SSL BIGNUM object for the purpose of | ||
12 | * automatical freeing. | ||
13 | */ | ||
14 | class bignum_t { | ||
15 | public: | ||
16 | BIGNUM *_bn; | ||
17 | |||
18 | bignum_t() : _bn(0) { } | ||
19 | bignum_t(BIGNUM *bn) : _bn(bn) { } | ||
20 | ~bignum_t() throw() { if(_bn) BN_free(_bn); } | ||
21 | |||
22 | bignum_t& operator=(BIGNUM *bn) { if(_bn) BN_free(_bn); _bn = bn; return *this; } | ||
23 | |||
24 | operator const BIGNUM*(void) const { return _bn; } | ||
25 | operator BIGNUM*(void) { return _bn; } | ||
26 | }; | ||
27 | /** | ||
28 | * Convenience clas encapsulating SSL DH object for the purpose of | ||
29 | * automatic freeing. | ||
30 | */ | ||
31 | class dh_t { | ||
32 | public: | ||
33 | DH *_dh; | ||
34 | |||
35 | dh_t() : _dh(0) { } | ||
36 | dh_t(DH *dh) : _dh(dh) { } | ||
37 | ~dh_t() throw() { if(_dh) DH_free(_dh); } | ||
38 | |||
39 | dh_t& operator=(DH *dh) { if(_dh) DH_free(_dh); _dh = dh; return *this; } | ||
40 | |||
41 | operator const DH*(void) const { return _dh; } | ||
42 | operator DH*(void) { return _dh; } | ||
43 | |||
44 | DH* operator->() { return _dh; } | ||
45 | const DH* operator->() const { return _dh; } | ||
46 | }; | ||
47 | |||
48 | /** | ||
49 | * Convert base64-encoded SSL BIGNUM to internal representation. | ||
50 | * @param b64 base64-encoded number | ||
51 | * @return SSL BIGNUM | ||
52 | * @throw failed_conversion in case of error | ||
53 | */ | ||
54 | BIGNUM *base64_to_bignum(const string& b64); | ||
55 | /** | ||
56 | * Convert decimal representation to SSL BIGNUM. | ||
57 | * @param dec decimal representation | ||
58 | * @return resulting BIGNUM | ||
59 | * @throw failed_conversion in case of error | ||
60 | */ | ||
61 | BIGNUM *dec_to_bignum(const string& dec); | ||
62 | /** | ||
63 | * Convert SSL BIGNUM data to base64 encoded string. | ||
64 | * @param bn BIGNUM | ||
65 | * @return base64encoded string | ||
66 | */ | ||
67 | string bignum_to_base64(const BIGNUM *bn); | ||
68 | |||
69 | string abi_demangle(const char* mn); | ||
70 | |||
71 | class change_mode_message_proxy : public basic_openid_message { | ||
72 | public: | ||
73 | const basic_openid_message& x; | ||
74 | const string& mode; | ||
75 | |||
76 | change_mode_message_proxy(const basic_openid_message& xx,const string& m) : x(xx), mode(m) { } | ||
77 | |||
78 | bool has_field(const string& n) const { return x.has_field(n); } | ||
79 | const string& get_field(const string& n) const { | ||
80 | return (n=="mode")?mode:x.get_field(n); } | ||
81 | bool has_ns(const string& uri) const {return x.has_ns(uri); } | ||
82 | string get_ns(const string& uri) const { return x.get_ns(uri); } | ||
83 | fields_iterator fields_begin() const { | ||
84 | return x.fields_begin(); } | ||
85 | fields_iterator fields_end() const { | ||
86 | return x.fields_end(); } | ||
87 | }; | ||
88 | |||
89 | } | ||
90 | } | ||
91 | |||
92 | #endif /* __OPKELE_UTIL_INTERNAL_H */ | ||
diff --git a/include/opkele/util.h b/include/opkele/util.h index bc1a0ea..60955e1 100644 --- a/include/opkele/util.h +++ b/include/opkele/util.h | |||
@@ -1,184 +1,114 @@ | |||
1 | #ifndef __OPKELE_UTIL_H | 1 | #ifndef __OPKELE_UTIL_H |
2 | #define __OPKELE_UTIL_H | 2 | #define __OPKELE_UTIL_H |
3 | 3 | ||
4 | #include <time.h> | 4 | #include <time.h> |
5 | #include <string> | 5 | #include <string> |
6 | #include <vector> | 6 | #include <vector> |
7 | #include <openssl/bn.h> | ||
8 | #include <openssl/dh.h> | ||
9 | #include <opkele/types.h> | 7 | #include <opkele/types.h> |
10 | 8 | ||
11 | namespace opkele { | 9 | namespace opkele { |
12 | using std::string; | 10 | using std::string; |
13 | using std::vector; | 11 | using std::vector; |
14 | 12 | ||
15 | /** | 13 | /** |
16 | * @brief opkele utils namespace | 14 | * @brief opkele utils namespace |
17 | */ | 15 | */ |
18 | namespace util { | 16 | namespace util { |
19 | 17 | ||
20 | /** | 18 | /** |
21 | * Convenience class encapsulating SSL BIGNUM object for the purpose of | ||
22 | * automatical freeing. | ||
23 | */ | ||
24 | class bignum_t { | ||
25 | public: | ||
26 | BIGNUM *_bn; | ||
27 | |||
28 | bignum_t() : _bn(0) { } | ||
29 | bignum_t(BIGNUM *bn) : _bn(bn) { } | ||
30 | ~bignum_t() throw() { if(_bn) BN_free(_bn); } | ||
31 | |||
32 | bignum_t& operator=(BIGNUM *bn) { if(_bn) BN_free(_bn); _bn = bn; return *this; } | ||
33 | |||
34 | operator const BIGNUM*(void) const { return _bn; } | ||
35 | operator BIGNUM*(void) { return _bn; } | ||
36 | }; | ||
37 | /** | ||
38 | * Convenience clas encapsulating SSL DH object for the purpose of | ||
39 | * automatic freeing. | ||
40 | */ | ||
41 | class dh_t { | ||
42 | public: | ||
43 | DH *_dh; | ||
44 | |||
45 | dh_t() : _dh(0) { } | ||
46 | dh_t(DH *dh) : _dh(dh) { } | ||
47 | ~dh_t() throw() { if(_dh) DH_free(_dh); } | ||
48 | |||
49 | dh_t& operator=(DH *dh) { if(_dh) DH_free(_dh); _dh = dh; return *this; } | ||
50 | |||
51 | operator const DH*(void) const { return _dh; } | ||
52 | operator DH*(void) { return _dh; } | ||
53 | |||
54 | DH* operator->() { return _dh; } | ||
55 | const DH* operator->() const { return _dh; } | ||
56 | }; | ||
57 | |||
58 | /** | ||
59 | * Convert base64-encoded SSL BIGNUM to internal representation. | ||
60 | * @param b64 base64-encoded number | ||
61 | * @return SSL BIGNUM | ||
62 | * @throw failed_conversion in case of error | ||
63 | */ | ||
64 | BIGNUM *base64_to_bignum(const string& b64); | ||
65 | /** | ||
66 | * Convert decimal representation to SSL BIGNUM. | ||
67 | * @param dec decimal representation | ||
68 | * @return resulting BIGNUM | ||
69 | * @throw failed_conversion in case of error | ||
70 | */ | ||
71 | BIGNUM *dec_to_bignum(const string& dec); | ||
72 | /** | ||
73 | * Convert SSL BIGNUM data to base64 encoded string. | ||
74 | * @param bn BIGNUM | ||
75 | * @return base64encoded string | ||
76 | */ | ||
77 | string bignum_to_base64(const BIGNUM *bn); | ||
78 | |||
79 | /** | ||
80 | * Convert internal time representation to w3c format | 19 | * Convert internal time representation to w3c format |
81 | * @param t internal representation | 20 | * @param t internal representation |
82 | * @return w3c time | 21 | * @return w3c time |
83 | * @throw failed_conversion in case of error | 22 | * @throw failed_conversion in case of error |
84 | */ | 23 | */ |
85 | string time_to_w3c(time_t t); | 24 | string time_to_w3c(time_t t); |
86 | /** | 25 | /** |
87 | * Convert W3C time representation to internal time_t | 26 | * Convert W3C time representation to internal time_t |
88 | * @param w w3c representation | 27 | * @param w w3c representation |
89 | * @return converted time | 28 | * @return converted time |
90 | * @throw failed_conversion in case of error | 29 | * @throw failed_conversion in case of error |
91 | */ | 30 | */ |
92 | time_t w3c_to_time(const string& w); | 31 | time_t w3c_to_time(const string& w); |
93 | 32 | ||
94 | /** | 33 | /** |
95 | * Encode string to the representation suitable for using in URL. | 34 | * Encode string to the representation suitable for using in URL. |
96 | * @param str string to encode | 35 | * @param str string to encode |
97 | * @return encoded string | 36 | * @return encoded string |
98 | * @throw failed_conversion in case of failure | 37 | * @throw failed_conversion in case of failure |
99 | */ | 38 | */ |
100 | string url_encode(const string& str); | 39 | string url_encode(const string& str); |
101 | 40 | ||
102 | /** | 41 | /** |
103 | * Make string suitable for using as x(ht)ml attribute. | 42 | * Make string suitable for using as x(ht)ml attribute. |
104 | * @param str string to escape | 43 | * @param str string to escape |
105 | * @return escaped string | 44 | * @return escaped string |
106 | */ | 45 | */ |
107 | string attr_escape(const string& str); | 46 | string attr_escape(const string& str); |
108 | 47 | ||
109 | /** | 48 | /** |
110 | * Convert number to string | 49 | * Convert number to string |
111 | * @param l number | 50 | * @param l number |
112 | * @return string representation | 51 | * @return string representation |
113 | * @throw failed_conversion in case of failure | 52 | * @throw failed_conversion in case of failure |
114 | */ | 53 | */ |
115 | string long_to_string(long l); | 54 | string long_to_string(long l); |
116 | /** | 55 | /** |
117 | * Convert string to number | 56 | * Convert string to number |
118 | * @param s string, containing the number | 57 | * @param s string, containing the number |
119 | * @return the number | 58 | * @return the number |
120 | * @throw failed_conversion in case of failure | 59 | * @throw failed_conversion in case of failure |
121 | */ | 60 | */ |
122 | long string_to_long(const string& s); | 61 | long string_to_long(const string& s); |
123 | 62 | ||
124 | /** | 63 | /** |
125 | * Encode binary data using base64. | 64 | * Encode binary data using base64. |
126 | * @param data pointer to binary data | 65 | * @param data pointer to binary data |
127 | * @param length length of data | 66 | * @param length length of data |
128 | * @return encoded data | 67 | * @return encoded data |
129 | */ | 68 | */ |
130 | string encode_base64(const void *data,size_t length); | 69 | string encode_base64(const void *data,size_t length); |
131 | /** | 70 | /** |
132 | * Decode binary data from base64 representation. | 71 | * Decode binary data from base64 representation. |
133 | * @param data base64-encoded data | 72 | * @param data base64-encoded data |
134 | * @param rv container for decoded binary | 73 | * @param rv container for decoded binary |
135 | */ | 74 | */ |
136 | void decode_base64(const string& data,vector<unsigned char>& rv); | 75 | void decode_base64(const string& data,vector<unsigned char>& rv); |
137 | 76 | ||
138 | /** | 77 | /** |
139 | * Normalize http(s) URI according to RFC3986, section 6. URI is | 78 | * Normalize http(s) URI according to RFC3986, section 6. URI is |
140 | * expected to have scheme: in front of it. | 79 | * expected to have scheme: in front of it. |
141 | * @param uri URI | 80 | * @param uri URI |
142 | * @return normalized URI | 81 | * @return normalized URI |
143 | * @throw not_implemented in case of non-httpi(s) URI | 82 | * @throw not_implemented in case of non-httpi(s) URI |
144 | * @throw bad_input in case of malformed URI | 83 | * @throw bad_input in case of malformed URI |
145 | */ | 84 | */ |
146 | string rfc_3986_normalize_uri(const string& uri); | 85 | string rfc_3986_normalize_uri(const string& uri); |
147 | 86 | ||
148 | /** | 87 | /** |
149 | * Match URI against realm | 88 | * Match URI against realm |
150 | * @param uri URI to match | 89 | * @param uri URI to match |
151 | * @param realm realm to match against | 90 | * @param realm realm to match against |
152 | * @return true if URI matches realm | 91 | * @return true if URI matches realm |
153 | */ | 92 | */ |
154 | bool uri_matches_realm(const string& uri,const string& realm); | 93 | bool uri_matches_realm(const string& uri,const string& realm); |
155 | 94 | ||
95 | /** | ||
96 | * Strip fragment part from URI | ||
97 | * @param uri input/output parameter containing the URI | ||
98 | * @return reference to uri | ||
99 | */ | ||
156 | string& strip_uri_fragment_part(string& uri); | 100 | string& strip_uri_fragment_part(string& uri); |
157 | 101 | ||
158 | string abi_demangle(const char* mn); | 102 | /** |
159 | 103 | * Calculate signature and encode it using base64 | |
104 | * @param assoc association being used for signing | ||
105 | * @param om openid message | ||
106 | * @return base64 representation of the signature | ||
107 | */ | ||
160 | string base64_signature(const assoc_t& assoc,const basic_openid_message& om); | 108 | string base64_signature(const assoc_t& assoc,const basic_openid_message& om); |
161 | 109 | ||
162 | class change_mode_message_proxy : public basic_openid_message { | ||
163 | public: | ||
164 | const basic_openid_message& x; | ||
165 | const string& mode; | ||
166 | |||
167 | change_mode_message_proxy(const basic_openid_message& xx,const string& m) : x(xx), mode(m) { } | ||
168 | |||
169 | bool has_field(const string& n) const { return x.has_field(n); } | ||
170 | const string& get_field(const string& n) const { | ||
171 | return (n=="mode")?mode:x.get_field(n); } | ||
172 | bool has_ns(const string& uri) const {return x.has_ns(uri); } | ||
173 | string get_ns(const string& uri) const { return x.get_ns(uri); } | ||
174 | fields_iterator fields_begin() const { | ||
175 | return x.fields_begin(); } | ||
176 | fields_iterator fields_end() const { | ||
177 | return x.fields_end(); } | ||
178 | }; | ||
179 | |||
180 | } | 110 | } |
181 | 111 | ||
182 | } | 112 | } |
183 | 113 | ||
184 | #endif /* __OPKELE_UTIL_H */ | 114 | #endif /* __OPKELE_UTIL_H */ |
diff --git a/lib/basic_op.cc b/lib/basic_op.cc index c247493..fa659ac 100644 --- a/lib/basic_op.cc +++ b/lib/basic_op.cc | |||
@@ -1,136 +1,137 @@ | |||
1 | #include <time.h> | 1 | #include <time.h> |
2 | #include <cassert> | 2 | #include <cassert> |
3 | #include <openssl/sha.h> | 3 | #include <openssl/sha.h> |
4 | #include <openssl/hmac.h> | 4 | #include <openssl/hmac.h> |
5 | #include <opkele/data.h> | 5 | #include <opkele/data.h> |
6 | #include <opkele/basic_op.h> | 6 | #include <opkele/basic_op.h> |
7 | #include <opkele/exception.h> | 7 | #include <opkele/exception.h> |
8 | #include <opkele/util.h> | 8 | #include <opkele/util.h> |
9 | #include <opkele/util-internal.h> | ||
9 | #include <opkele/uris.h> | 10 | #include <opkele/uris.h> |
10 | 11 | ||
11 | namespace opkele { | 12 | namespace opkele { |
12 | 13 | ||
13 | void basic_OP::reset_vars() { | 14 | void basic_OP::reset_vars() { |
14 | assoc.reset(); | 15 | assoc.reset(); |
15 | return_to.clear(); realm.clear(); | 16 | return_to.clear(); realm.clear(); |
16 | claimed_id.clear(); identity.clear(); | 17 | claimed_id.clear(); identity.clear(); |
17 | invalidate_handle.clear(); | 18 | invalidate_handle.clear(); |
18 | } | 19 | } |
19 | 20 | ||
20 | bool basic_OP::has_return_to() const { | 21 | bool basic_OP::has_return_to() const { |
21 | return !return_to.empty(); | 22 | return !return_to.empty(); |
22 | } | 23 | } |
23 | const string& basic_OP::get_return_to() const { | 24 | const string& basic_OP::get_return_to() const { |
24 | if(return_to.empty()) | 25 | if(return_to.empty()) |
25 | throw no_return_to(OPKELE_CP_ "No return_to URL provided with request"); | 26 | throw no_return_to(OPKELE_CP_ "No return_to URL provided with request"); |
26 | return return_to; | 27 | return return_to; |
27 | } | 28 | } |
28 | 29 | ||
29 | const string& basic_OP::get_realm() const { | 30 | const string& basic_OP::get_realm() const { |
30 | assert(!realm.empty()); | 31 | assert(!realm.empty()); |
31 | return realm; | 32 | return realm; |
32 | } | 33 | } |
33 | 34 | ||
34 | bool basic_OP::has_identity() const { | 35 | bool basic_OP::has_identity() const { |
35 | return !identity.empty(); | 36 | return !identity.empty(); |
36 | } | 37 | } |
37 | const string& basic_OP::get_claimed_id() const { | 38 | const string& basic_OP::get_claimed_id() const { |
38 | if(claimed_id.empty()) | 39 | if(claimed_id.empty()) |
39 | throw non_identity(OPKELE_CP_ "attempting to retrieve claimed_id of non-identity related request"); | 40 | throw non_identity(OPKELE_CP_ "attempting to retrieve claimed_id of non-identity related request"); |
40 | assert(!identity.empty()); | 41 | assert(!identity.empty()); |
41 | return claimed_id; | 42 | return claimed_id; |
42 | } | 43 | } |
43 | const string& basic_OP::get_identity() const { | 44 | const string& basic_OP::get_identity() const { |
44 | if(identity.empty()) | 45 | if(identity.empty()) |
45 | throw non_identity(OPKELE_CP_ "attempting to retrieve identity of non-identity related request"); | 46 | throw non_identity(OPKELE_CP_ "attempting to retrieve identity of non-identity related request"); |
46 | assert(!claimed_id.empty()); | 47 | assert(!claimed_id.empty()); |
47 | return identity; | 48 | return identity; |
48 | } | 49 | } |
49 | 50 | ||
50 | bool basic_OP::is_id_select() const { | 51 | bool basic_OP::is_id_select() const { |
51 | return identity==IDURI_SELECT20; | 52 | return identity==IDURI_SELECT20; |
52 | } | 53 | } |
53 | 54 | ||
54 | void basic_OP::select_identity(const string& c,const string& i) { | 55 | void basic_OP::select_identity(const string& c,const string& i) { |
55 | claimed_id = c; identity = i; | 56 | claimed_id = c; identity = i; |
56 | } | 57 | } |
57 | void basic_OP::set_claimed_id(const string& c) { | 58 | void basic_OP::set_claimed_id(const string& c) { |
58 | claimed_id = c; | 59 | claimed_id = c; |
59 | } | 60 | } |
60 | 61 | ||
61 | basic_openid_message& basic_OP::associate( | 62 | basic_openid_message& basic_OP::associate( |
62 | basic_openid_message& oum, | 63 | basic_openid_message& oum, |
63 | const basic_openid_message& inm) try { | 64 | const basic_openid_message& inm) try { |
64 | assert(inm.get_field("mode")=="associate"); | 65 | assert(inm.get_field("mode")=="associate"); |
65 | util::dh_t dh; | 66 | util::dh_t dh; |
66 | util::bignum_t c_pub; | 67 | util::bignum_t c_pub; |
67 | unsigned char key_digest[SHA256_DIGEST_LENGTH]; | 68 | unsigned char key_digest[SHA256_DIGEST_LENGTH]; |
68 | size_t d_len = 0; | 69 | size_t d_len = 0; |
69 | string sts = inm.get_field("session_type"); | 70 | string sts = inm.get_field("session_type"); |
70 | string ats = inm.get_field("assoc_type"); | 71 | string ats = inm.get_field("assoc_type"); |
71 | if(sts=="DH-SHA1" || sts=="DH-SHA256") { | 72 | if(sts=="DH-SHA1" || sts=="DH-SHA256") { |
72 | if(!(dh = DH_new())) | 73 | if(!(dh = DH_new())) |
73 | throw exception_openssl(OPKELE_CP_ "failed to DH_new()"); | 74 | throw exception_openssl(OPKELE_CP_ "failed to DH_new()"); |
74 | c_pub = util::base64_to_bignum(inm.get_field("dh_consumer_public")); | 75 | c_pub = util::base64_to_bignum(inm.get_field("dh_consumer_public")); |
75 | try { dh->p = util::base64_to_bignum(inm.get_field("dh_modulus")); | 76 | try { dh->p = util::base64_to_bignum(inm.get_field("dh_modulus")); |
76 | }catch(failed_lookup&) { | 77 | }catch(failed_lookup&) { |
77 | dh->p = util::dec_to_bignum(data::_default_p); } | 78 | dh->p = util::dec_to_bignum(data::_default_p); } |
78 | try { dh->g = util::base64_to_bignum(inm.get_field("dh_gen")); | 79 | try { dh->g = util::base64_to_bignum(inm.get_field("dh_gen")); |
79 | }catch(failed_lookup&) { | 80 | }catch(failed_lookup&) { |
80 | dh->g = util::dec_to_bignum(data::_default_g); } | 81 | dh->g = util::dec_to_bignum(data::_default_g); } |
81 | if(!DH_generate_key(dh)) | 82 | if(!DH_generate_key(dh)) |
82 | throw exception_openssl(OPKELE_CP_ "failed to DH_generate_key()"); | 83 | throw exception_openssl(OPKELE_CP_ "failed to DH_generate_key()"); |
83 | vector<unsigned char> ck(DH_size(dh)+1); | 84 | vector<unsigned char> ck(DH_size(dh)+1); |
84 | unsigned char *ckptr = &(ck.front())+1; | 85 | unsigned char *ckptr = &(ck.front())+1; |
85 | int cklen = DH_compute_key(ckptr,c_pub,dh); | 86 | int cklen = DH_compute_key(ckptr,c_pub,dh); |
86 | if(cklen<0) | 87 | if(cklen<0) |
87 | throw exception_openssl(OPKELE_CP_ "failed to DH_compute_key()"); | 88 | throw exception_openssl(OPKELE_CP_ "failed to DH_compute_key()"); |
88 | if(cklen && (*ckptr)&0x80) { | 89 | if(cklen && (*ckptr)&0x80) { |
89 | (*(--ckptr)) = 0; ++cklen; } | 90 | (*(--ckptr)) = 0; ++cklen; } |
90 | if(sts=="DH-SHA1") { | 91 | if(sts=="DH-SHA1") { |
91 | SHA1(ckptr,cklen,key_digest); d_len = SHA_DIGEST_LENGTH; | 92 | SHA1(ckptr,cklen,key_digest); d_len = SHA_DIGEST_LENGTH; |
92 | }else if(sts=="DH-SHA256") { | 93 | }else if(sts=="DH-SHA256") { |
93 | SHA256(ckptr,cklen,key_digest); d_len = SHA256_DIGEST_LENGTH; | 94 | SHA256(ckptr,cklen,key_digest); d_len = SHA256_DIGEST_LENGTH; |
94 | }else | 95 | }else |
95 | throw internal_error(OPKELE_CP_ "I thought I knew the session type"); | 96 | throw internal_error(OPKELE_CP_ "I thought I knew the session type"); |
96 | }else | 97 | }else |
97 | throw unsupported(OPKELE_CP_ "Unsupported session_type"); | 98 | throw unsupported(OPKELE_CP_ "Unsupported session_type"); |
98 | assoc_t a; | 99 | assoc_t a; |
99 | if(ats=="HMAC-SHA1") | 100 | if(ats=="HMAC-SHA1") |
100 | a = alloc_assoc(ats,SHA_DIGEST_LENGTH,false); | 101 | a = alloc_assoc(ats,SHA_DIGEST_LENGTH,false); |
101 | else if(ats=="HMAC-SHA256") | 102 | else if(ats=="HMAC-SHA256") |
102 | a = alloc_assoc(ats,SHA256_DIGEST_LENGTH,false); | 103 | a = alloc_assoc(ats,SHA256_DIGEST_LENGTH,false); |
103 | else | 104 | else |
104 | throw unsupported(OPKELE_CP_ "Unsupported assoc_type"); | 105 | throw unsupported(OPKELE_CP_ "Unsupported assoc_type"); |
105 | oum.reset_fields(); | 106 | oum.reset_fields(); |
106 | oum.set_field("ns",OIURI_OPENID20); | 107 | oum.set_field("ns",OIURI_OPENID20); |
107 | oum.set_field("assoc_type",a->assoc_type()); | 108 | oum.set_field("assoc_type",a->assoc_type()); |
108 | oum.set_field("assoc_handle",a->handle()); | 109 | oum.set_field("assoc_handle",a->handle()); |
109 | oum.set_field("expires_in",util::long_to_string(a->expires_in())); | 110 | oum.set_field("expires_in",util::long_to_string(a->expires_in())); |
110 | secret_t secret = a->secret(); | 111 | secret_t secret = a->secret(); |
111 | if(sts=="DH-SHA1" || sts=="DH-SHA256") { | 112 | if(sts=="DH-SHA1" || sts=="DH-SHA256") { |
112 | if(d_len != secret.size()) | 113 | if(d_len != secret.size()) |
113 | throw bad_input(OPKELE_CP_ "Association secret and session MAC are not of the same size"); | 114 | throw bad_input(OPKELE_CP_ "Association secret and session MAC are not of the same size"); |
114 | oum.set_field("session_type",sts); | 115 | oum.set_field("session_type",sts); |
115 | oum.set_field("dh_server_public",util::bignum_to_base64(dh->pub_key)); | 116 | oum.set_field("dh_server_public",util::bignum_to_base64(dh->pub_key)); |
116 | string b64; secret.enxor_to_base64(key_digest,b64); | 117 | string b64; secret.enxor_to_base64(key_digest,b64); |
117 | oum.set_field("enc_mac_key",b64); | 118 | oum.set_field("enc_mac_key",b64); |
118 | }else /* TODO: support cleartext over encrypted connection */ | 119 | }else /* TODO: support cleartext over encrypted connection */ |
119 | throw unsupported(OPKELE_CP_ "Unsupported session type"); | 120 | throw unsupported(OPKELE_CP_ "Unsupported session type"); |
120 | return oum; | 121 | return oum; |
121 | } catch(unsupported& u) { | 122 | } catch(unsupported& u) { |
122 | oum.reset_fields(); | 123 | oum.reset_fields(); |
123 | oum.set_field("ns",OIURI_OPENID20); | 124 | oum.set_field("ns",OIURI_OPENID20); |
124 | oum.set_field("error",u.what()); | 125 | oum.set_field("error",u.what()); |
125 | oum.set_field("error_code","unsupported-type"); | 126 | oum.set_field("error_code","unsupported-type"); |
126 | oum.set_field("session_type","DH-SHA256"); | 127 | oum.set_field("session_type","DH-SHA256"); |
127 | oum.set_field("assoc_type","HMAC-SHA256"); | 128 | oum.set_field("assoc_type","HMAC-SHA256"); |
128 | return oum; | 129 | return oum; |
129 | } | 130 | } |
130 | 131 | ||
131 | void basic_OP::checkid_(const basic_openid_message& inm, | 132 | void basic_OP::checkid_(const basic_openid_message& inm, |
132 | extension_t *ext) { | 133 | extension_t *ext) { |
133 | reset_vars(); | 134 | reset_vars(); |
134 | string modestr = inm.get_field("mode"); | 135 | string modestr = inm.get_field("mode"); |
135 | if(modestr=="checkid_setup") | 136 | if(modestr=="checkid_setup") |
136 | mode = mode_checkid_setup; | 137 | mode = mode_checkid_setup; |
diff --git a/lib/basic_rp.cc b/lib/basic_rp.cc index a0ad130..e65d9fb 100644 --- a/lib/basic_rp.cc +++ b/lib/basic_rp.cc | |||
@@ -1,136 +1,137 @@ | |||
1 | #include <cassert> | 1 | #include <cassert> |
2 | #include <openssl/sha.h> | 2 | #include <openssl/sha.h> |
3 | #include <openssl/hmac.h> | 3 | #include <openssl/hmac.h> |
4 | #include <opkele/basic_rp.h> | 4 | #include <opkele/basic_rp.h> |
5 | #include <opkele/exception.h> | 5 | #include <opkele/exception.h> |
6 | #include <opkele/uris.h> | 6 | #include <opkele/uris.h> |
7 | #include <opkele/data.h> | 7 | #include <opkele/data.h> |
8 | #include <opkele/util.h> | 8 | #include <opkele/util.h> |
9 | #include <opkele/util-internal.h> | ||
9 | #include <opkele/curl.h> | 10 | #include <opkele/curl.h> |
10 | 11 | ||
11 | namespace opkele { | 12 | namespace opkele { |
12 | 13 | ||
13 | static void dh_get_secret( | 14 | static void dh_get_secret( |
14 | secret_t& secret, const basic_openid_message& om, | 15 | secret_t& secret, const basic_openid_message& om, |
15 | const char *exp_assoc, const char *exp_sess, | 16 | const char *exp_assoc, const char *exp_sess, |
16 | util::dh_t& dh, | 17 | util::dh_t& dh, |
17 | size_t d_len, unsigned char *(*d_fun)(const unsigned char*,size_t,unsigned char*), | 18 | size_t d_len, unsigned char *(*d_fun)(const unsigned char*,size_t,unsigned char*), |
18 | size_t exp_s_len) try { | 19 | size_t exp_s_len) try { |
19 | if(om.get_field("assoc_type")!=exp_assoc || om.get_field("session_type")!=exp_sess) | 20 | if(om.get_field("assoc_type")!=exp_assoc || om.get_field("session_type")!=exp_sess) |
20 | throw bad_input(OPKELE_CP_ "Unexpected associate response"); | 21 | throw bad_input(OPKELE_CP_ "Unexpected associate response"); |
21 | util::bignum_t s_pub = util::base64_to_bignum(om.get_field("dh_server_public")); | 22 | util::bignum_t s_pub = util::base64_to_bignum(om.get_field("dh_server_public")); |
22 | vector<unsigned char> ck(DH_size(dh)+1); | 23 | vector<unsigned char> ck(DH_size(dh)+1); |
23 | unsigned char *ckptr = &(ck.front())+1; | 24 | unsigned char *ckptr = &(ck.front())+1; |
24 | int cklen = DH_compute_key(ckptr,s_pub,dh); | 25 | int cklen = DH_compute_key(ckptr,s_pub,dh); |
25 | if(cklen<0) | 26 | if(cklen<0) |
26 | throw exception_openssl(OPKELE_CP_ "failed to DH_compute_key()"); | 27 | throw exception_openssl(OPKELE_CP_ "failed to DH_compute_key()"); |
27 | if(cklen && (*ckptr)&0x80) { | 28 | if(cklen && (*ckptr)&0x80) { |
28 | (*(--ckptr))=0; ++cklen; } | 29 | (*(--ckptr))=0; ++cklen; } |
29 | assert(d_len<=SHA256_DIGEST_LENGTH); | 30 | assert(d_len<=SHA256_DIGEST_LENGTH); |
30 | unsigned char key_digest[SHA256_DIGEST_LENGTH]; | 31 | unsigned char key_digest[SHA256_DIGEST_LENGTH]; |
31 | secret.enxor_from_base64((*d_fun)(ckptr,cklen,key_digest),om.get_field("enc_mac_key")); | 32 | secret.enxor_from_base64((*d_fun)(ckptr,cklen,key_digest),om.get_field("enc_mac_key")); |
32 | if(secret.size()!=exp_s_len) | 33 | if(secret.size()!=exp_s_len) |
33 | throw bad_input(OPKELE_CP_ "Secret length isn't consistent with association type"); | 34 | throw bad_input(OPKELE_CP_ "Secret length isn't consistent with association type"); |
34 | }catch(opkele::failed_lookup& ofl) { | 35 | }catch(opkele::failed_lookup& ofl) { |
35 | throw bad_input(OPKELE_CP_ "Incoherent response from OP"); | 36 | throw bad_input(OPKELE_CP_ "Incoherent response from OP"); |
36 | } OPKELE_RETHROW | 37 | } OPKELE_RETHROW |
37 | 38 | ||
38 | static void direct_request(basic_openid_message& oum,const basic_openid_message& inm,const string& OP) { | 39 | static void direct_request(basic_openid_message& oum,const basic_openid_message& inm,const string& OP) { |
39 | util::curl_pick_t curl = util::curl_pick_t::easy_init(); | 40 | util::curl_pick_t curl = util::curl_pick_t::easy_init(); |
40 | if(!curl) | 41 | if(!curl) |
41 | throw exception_curl(OPKELE_CP_ "failed to initialize curl"); | 42 | throw exception_curl(OPKELE_CP_ "failed to initialize curl"); |
42 | string request = inm.query_string(); | 43 | string request = inm.query_string(); |
43 | CURLcode r; | 44 | CURLcode r; |
44 | (r=curl.misc_sets()) | 45 | (r=curl.misc_sets()) |
45 | || (r=curl.easy_setopt(CURLOPT_URL,OP.c_str())) | 46 | || (r=curl.easy_setopt(CURLOPT_URL,OP.c_str())) |
46 | || (r=curl.easy_setopt(CURLOPT_POST,1)) | 47 | || (r=curl.easy_setopt(CURLOPT_POST,1)) |
47 | || (r=curl.easy_setopt(CURLOPT_POSTFIELDS,request.data())) | 48 | || (r=curl.easy_setopt(CURLOPT_POSTFIELDS,request.data())) |
48 | || (r=curl.easy_setopt(CURLOPT_POSTFIELDSIZE,request.length())) | 49 | || (r=curl.easy_setopt(CURLOPT_POSTFIELDSIZE,request.length())) |
49 | || (r=curl.set_write()); | 50 | || (r=curl.set_write()); |
50 | if(r) | 51 | if(r) |
51 | throw exception_curl(OPKELE_CP_ "failed to set curly options",r); | 52 | throw exception_curl(OPKELE_CP_ "failed to set curly options",r); |
52 | if( (r=curl.easy_perform()) ) | 53 | if( (r=curl.easy_perform()) ) |
53 | throw exception_curl(OPKELE_CP_ "failed to perform curly request",r); | 54 | throw exception_curl(OPKELE_CP_ "failed to perform curly request",r); |
54 | oum.from_keyvalues(curl.response); | 55 | oum.from_keyvalues(curl.response); |
55 | } | 56 | } |
56 | 57 | ||
57 | 58 | ||
58 | assoc_t basic_RP::associate(const string& OP) { | 59 | assoc_t basic_RP::associate(const string& OP) { |
59 | util::dh_t dh = DH_new(); | 60 | util::dh_t dh = DH_new(); |
60 | if(!dh) | 61 | if(!dh) |
61 | throw exception_openssl(OPKELE_CP_ "failed to DH_new()"); | 62 | throw exception_openssl(OPKELE_CP_ "failed to DH_new()"); |
62 | dh->p = util::dec_to_bignum(data::_default_p); | 63 | dh->p = util::dec_to_bignum(data::_default_p); |
63 | dh->g = util::dec_to_bignum(data::_default_g); | 64 | dh->g = util::dec_to_bignum(data::_default_g); |
64 | if(!DH_generate_key(dh)) | 65 | if(!DH_generate_key(dh)) |
65 | throw exception_openssl(OPKELE_CP_ "failed to DH_generate_key()"); | 66 | throw exception_openssl(OPKELE_CP_ "failed to DH_generate_key()"); |
66 | openid_message_t req; | 67 | openid_message_t req; |
67 | req.set_field("ns",OIURI_OPENID20); | 68 | req.set_field("ns",OIURI_OPENID20); |
68 | req.set_field("mode","associate"); | 69 | req.set_field("mode","associate"); |
69 | req.set_field("dh_modulus",util::bignum_to_base64(dh->p)); | 70 | req.set_field("dh_modulus",util::bignum_to_base64(dh->p)); |
70 | req.set_field("dh_gen",util::bignum_to_base64(dh->g)); | 71 | req.set_field("dh_gen",util::bignum_to_base64(dh->g)); |
71 | req.set_field("dh_consumer_public",util::bignum_to_base64(dh->pub_key)); | 72 | req.set_field("dh_consumer_public",util::bignum_to_base64(dh->pub_key)); |
72 | openid_message_t res; | 73 | openid_message_t res; |
73 | req.set_field("assoc_type","HMAC-SHA256"); | 74 | req.set_field("assoc_type","HMAC-SHA256"); |
74 | req.set_field("session_type","DH-SHA256"); | 75 | req.set_field("session_type","DH-SHA256"); |
75 | secret_t secret; | 76 | secret_t secret; |
76 | int expires_in; | 77 | int expires_in; |
77 | try { | 78 | try { |
78 | direct_request(res,req,OP); | 79 | direct_request(res,req,OP); |
79 | dh_get_secret( secret, res, | 80 | dh_get_secret( secret, res, |
80 | "HMAC-SHA256", "DH-SHA256", | 81 | "HMAC-SHA256", "DH-SHA256", |
81 | dh, SHA256_DIGEST_LENGTH, SHA256, SHA256_DIGEST_LENGTH ); | 82 | dh, SHA256_DIGEST_LENGTH, SHA256, SHA256_DIGEST_LENGTH ); |
82 | expires_in = util::string_to_long(res.get_field("expires_in")); | 83 | expires_in = util::string_to_long(res.get_field("expires_in")); |
83 | }catch(exception&) { | 84 | }catch(exception&) { |
84 | try { | 85 | try { |
85 | req.set_field("assoc_type","HMAC-SHA1"); | 86 | req.set_field("assoc_type","HMAC-SHA1"); |
86 | req.set_field("session_type","DH-SHA1"); | 87 | req.set_field("session_type","DH-SHA1"); |
87 | direct_request(res,req,OP); | 88 | direct_request(res,req,OP); |
88 | dh_get_secret( secret, res, | 89 | dh_get_secret( secret, res, |
89 | "HMAC-SHA1", "DH-SHA1", | 90 | "HMAC-SHA1", "DH-SHA1", |
90 | dh, SHA_DIGEST_LENGTH, SHA1, SHA_DIGEST_LENGTH ); | 91 | dh, SHA_DIGEST_LENGTH, SHA1, SHA_DIGEST_LENGTH ); |
91 | expires_in = util::string_to_long(res.get_field("expires_in")); | 92 | expires_in = util::string_to_long(res.get_field("expires_in")); |
92 | }catch(bad_input&) { | 93 | }catch(bad_input&) { |
93 | throw dumb_RP(OPKELE_CP_ "OP failed to supply an association"); | 94 | throw dumb_RP(OPKELE_CP_ "OP failed to supply an association"); |
94 | } | 95 | } |
95 | } | 96 | } |
96 | return store_assoc( | 97 | return store_assoc( |
97 | OP, res.get_field("assoc_handle"), | 98 | OP, res.get_field("assoc_handle"), |
98 | res.get_field("assoc_type"), secret, | 99 | res.get_field("assoc_type"), secret, |
99 | expires_in ); | 100 | expires_in ); |
100 | } | 101 | } |
101 | 102 | ||
102 | basic_openid_message& basic_RP::checkid_( | 103 | basic_openid_message& basic_RP::checkid_( |
103 | basic_openid_message& rv, | 104 | basic_openid_message& rv, |
104 | mode_t mode, | 105 | mode_t mode, |
105 | const string& return_to,const string& realm, | 106 | const string& return_to,const string& realm, |
106 | extension_t *ext) { | 107 | extension_t *ext) { |
107 | rv.reset_fields(); | 108 | rv.reset_fields(); |
108 | rv.set_field("ns",OIURI_OPENID20); | 109 | rv.set_field("ns",OIURI_OPENID20); |
109 | if(mode==mode_checkid_immediate) | 110 | if(mode==mode_checkid_immediate) |
110 | rv.set_field("mode","checkid_immediate"); | 111 | rv.set_field("mode","checkid_immediate"); |
111 | else if(mode==mode_checkid_setup) | 112 | else if(mode==mode_checkid_setup) |
112 | rv.set_field("mode","checkid_setup"); | 113 | rv.set_field("mode","checkid_setup"); |
113 | else | 114 | else |
114 | throw bad_input(OPKELE_CP_ "unknown checkid_* mode"); | 115 | throw bad_input(OPKELE_CP_ "unknown checkid_* mode"); |
115 | if(realm.empty() && return_to.empty()) | 116 | if(realm.empty() && return_to.empty()) |
116 | throw bad_input(OPKELE_CP_ "At least one of realm and return_to must be non-empty"); | 117 | throw bad_input(OPKELE_CP_ "At least one of realm and return_to must be non-empty"); |
117 | if(!realm.empty()) { | 118 | if(!realm.empty()) { |
118 | rv.set_field("realm",realm); | 119 | rv.set_field("realm",realm); |
119 | rv.set_field("trust_root",realm); | 120 | rv.set_field("trust_root",realm); |
120 | } | 121 | } |
121 | if(!return_to.empty()) | 122 | if(!return_to.empty()) |
122 | rv.set_field("return_to",return_to); | 123 | rv.set_field("return_to",return_to); |
123 | const openid_endpoint_t& ep = get_endpoint(); | 124 | const openid_endpoint_t& ep = get_endpoint(); |
124 | rv.set_field("claimed_id",ep.claimed_id); | 125 | rv.set_field("claimed_id",ep.claimed_id); |
125 | rv.set_field("identity",ep.local_id); | 126 | rv.set_field("identity",ep.local_id); |
126 | try { | 127 | try { |
127 | rv.set_field("assoc_handle",find_assoc(ep.uri)->handle()); | 128 | rv.set_field("assoc_handle",find_assoc(ep.uri)->handle()); |
128 | }catch(dumb_RP& drp) { | 129 | }catch(dumb_RP& drp) { |
129 | }catch(failed_lookup& fl) { | 130 | }catch(failed_lookup& fl) { |
130 | try { | 131 | try { |
131 | rv.set_field("assoc_handle",associate(ep.uri)->handle()); | 132 | rv.set_field("assoc_handle",associate(ep.uri)->handle()); |
132 | }catch(dumb_RP& drp) { } | 133 | }catch(dumb_RP& drp) { } |
133 | } OPKELE_RETHROW | 134 | } OPKELE_RETHROW |
134 | if(ext) ext->rp_checkid_hook(rv); | 135 | if(ext) ext->rp_checkid_hook(rv); |
135 | return rv; | 136 | return rv; |
136 | } | 137 | } |
diff --git a/lib/consumer.cc b/lib/consumer.cc index ebda262..801496e 100644 --- a/lib/consumer.cc +++ b/lib/consumer.cc | |||
@@ -1,132 +1,133 @@ | |||
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") |
101 | throw bad_input(OPKELE_CP_ "unsupported session_type"); | 102 | throw bad_input(OPKELE_CP_ "unsupported session_type"); |
102 | secret_t secret; | 103 | secret_t secret; |
103 | if(st.empty()) { | 104 | if(st.empty()) { |
104 | secret.from_base64(p.get_param("mac_key")); | 105 | secret.from_base64(p.get_param("mac_key")); |
105 | }else{ | 106 | }else{ |
106 | util::bignum_t s_pub = util::base64_to_bignum(p.get_param("dh_server_public")); | 107 | util::bignum_t s_pub = util::base64_to_bignum(p.get_param("dh_server_public")); |
107 | vector<unsigned char> ck(DH_size(dh)+1); | 108 | vector<unsigned char> ck(DH_size(dh)+1); |
108 | unsigned char *ckptr = &(ck.front())+1; | 109 | unsigned char *ckptr = &(ck.front())+1; |
109 | int cklen = DH_compute_key(ckptr,s_pub,dh); | 110 | int cklen = DH_compute_key(ckptr,s_pub,dh); |
110 | if(cklen<0) | 111 | if(cklen<0) |
111 | throw exception_openssl(OPKELE_CP_ "failed to DH_compute_key()"); | 112 | throw exception_openssl(OPKELE_CP_ "failed to DH_compute_key()"); |
112 | if(cklen && (*ckptr)&0x80) { | 113 | if(cklen && (*ckptr)&0x80) { |
113 | (*(--ckptr)) = 0; ++cklen; | 114 | (*(--ckptr)) = 0; ++cklen; |
114 | } | 115 | } |
115 | unsigned char key_sha1[SHA_DIGEST_LENGTH]; | 116 | unsigned char key_sha1[SHA_DIGEST_LENGTH]; |
116 | SHA1(ckptr,cklen,key_sha1); | 117 | SHA1(ckptr,cklen,key_sha1); |
117 | secret.enxor_from_base64(key_sha1,p.get_param("enc_mac_key")); | 118 | secret.enxor_from_base64(key_sha1,p.get_param("enc_mac_key")); |
118 | } | 119 | } |
119 | int expires_in = 0; | 120 | int expires_in = 0; |
120 | if(p.has_param("expires_in")) { | 121 | if(p.has_param("expires_in")) { |
121 | expires_in = util::string_to_long(p.get_param("expires_in")); | 122 | expires_in = util::string_to_long(p.get_param("expires_in")); |
122 | }else if(p.has_param("issued") && p.has_param("expiry")) { | 123 | }else if(p.has_param("issued") && p.has_param("expiry")) { |
123 | expires_in = util::w3c_to_time(p.get_param("expiry"))-util::w3c_to_time(p.get_param("issued")); | 124 | expires_in = util::w3c_to_time(p.get_param("expiry"))-util::w3c_to_time(p.get_param("issued")); |
124 | }else | 125 | }else |
125 | throw bad_input(OPKELE_CP_ "no expiration information"); | 126 | throw bad_input(OPKELE_CP_ "no expiration information"); |
126 | return store_assoc(server,p.get_param("assoc_handle"),secret,expires_in); | 127 | return store_assoc(server,p.get_param("assoc_handle"),secret,expires_in); |
127 | } | 128 | } |
128 | 129 | ||
129 | string consumer_t::checkid_immediate(const string& identity,const string& return_to,const string& trust_root,extension_t *ext) { | 130 | string consumer_t::checkid_immediate(const string& identity,const string& return_to,const string& trust_root,extension_t *ext) { |
130 | return checkid_(mode_checkid_immediate,identity,return_to,trust_root,ext); | 131 | return checkid_(mode_checkid_immediate,identity,return_to,trust_root,ext); |
131 | } | 132 | } |
132 | string consumer_t::checkid_setup(const string& identity,const string& return_to,const string& trust_root,extension_t *ext) { | 133 | string consumer_t::checkid_setup(const string& identity,const string& return_to,const string& trust_root,extension_t *ext) { |
diff --git a/lib/server.cc b/lib/server.cc index 776f1ae..0dea1eb 100644 --- a/lib/server.cc +++ b/lib/server.cc | |||
@@ -1,133 +1,134 @@ | |||
1 | #include <cstring> | 1 | #include <cstring> |
2 | #include <vector> | 2 | #include <vector> |
3 | #include <openssl/sha.h> | 3 | #include <openssl/sha.h> |
4 | #include <openssl/hmac.h> | 4 | #include <openssl/hmac.h> |
5 | #include <opkele/util.h> | 5 | #include <opkele/util.h> |
6 | #include <opkele/util-internal.h> | ||
6 | #include <opkele/exception.h> | 7 | #include <opkele/exception.h> |
7 | #include <opkele/server.h> | 8 | #include <opkele/server.h> |
8 | #include <opkele/data.h> | 9 | #include <opkele/data.h> |
9 | 10 | ||
10 | namespace opkele { | 11 | namespace opkele { |
11 | using namespace std; | 12 | using namespace std; |
12 | 13 | ||
13 | void server_t::associate(const params_t& pin,params_t& pout) { | 14 | void server_t::associate(const params_t& pin,params_t& pout) { |
14 | util::dh_t dh; | 15 | util::dh_t dh; |
15 | util::bignum_t c_pub; | 16 | util::bignum_t c_pub; |
16 | unsigned char key_sha1[SHA_DIGEST_LENGTH]; | 17 | unsigned char key_sha1[SHA_DIGEST_LENGTH]; |
17 | enum { | 18 | enum { |
18 | sess_cleartext, | 19 | sess_cleartext, |
19 | sess_dh_sha1 | 20 | sess_dh_sha1 |
20 | } st = sess_cleartext; | 21 | } st = sess_cleartext; |
21 | if( | 22 | if( |
22 | pin.has_param("openid.session_type") | 23 | pin.has_param("openid.session_type") |
23 | && pin.get_param("openid.session_type")=="DH-SHA1" ) { | 24 | && pin.get_param("openid.session_type")=="DH-SHA1" ) { |
24 | /* TODO: fallback to cleartext in case of exceptions here? */ | 25 | /* TODO: fallback to cleartext in case of exceptions here? */ |
25 | if(!(dh = DH_new())) | 26 | if(!(dh = DH_new())) |
26 | throw exception_openssl(OPKELE_CP_ "failed to DH_new()"); | 27 | throw exception_openssl(OPKELE_CP_ "failed to DH_new()"); |
27 | c_pub = util::base64_to_bignum(pin.get_param("openid.dh_consumer_public")); | 28 | c_pub = util::base64_to_bignum(pin.get_param("openid.dh_consumer_public")); |
28 | if(pin.has_param("openid.dh_modulus")) | 29 | if(pin.has_param("openid.dh_modulus")) |
29 | dh->p = util::base64_to_bignum(pin.get_param("openid.dh_modulus")); | 30 | dh->p = util::base64_to_bignum(pin.get_param("openid.dh_modulus")); |
30 | else | 31 | else |
31 | dh->p = util::dec_to_bignum(data::_default_p); | 32 | dh->p = util::dec_to_bignum(data::_default_p); |
32 | if(pin.has_param("openid.dh_gen")) | 33 | if(pin.has_param("openid.dh_gen")) |
33 | dh->g = util::base64_to_bignum(pin.get_param("openid.dh_gen")); | 34 | dh->g = util::base64_to_bignum(pin.get_param("openid.dh_gen")); |
34 | else | 35 | else |
35 | dh->g = util::dec_to_bignum(data::_default_g); | 36 | dh->g = util::dec_to_bignum(data::_default_g); |
36 | if(!DH_generate_key(dh)) | 37 | if(!DH_generate_key(dh)) |
37 | throw exception_openssl(OPKELE_CP_ "failed to DH_generate_key()"); | 38 | throw exception_openssl(OPKELE_CP_ "failed to DH_generate_key()"); |
38 | vector<unsigned char> ck(DH_size(dh)+1); | 39 | vector<unsigned char> ck(DH_size(dh)+1); |
39 | unsigned char *ckptr = &(ck.front())+1; | 40 | unsigned char *ckptr = &(ck.front())+1; |
40 | int cklen = DH_compute_key(ckptr,c_pub,dh); | 41 | int cklen = DH_compute_key(ckptr,c_pub,dh); |
41 | if(cklen<0) | 42 | if(cklen<0) |
42 | throw exception_openssl(OPKELE_CP_ "failed to DH_compute_key()"); | 43 | throw exception_openssl(OPKELE_CP_ "failed to DH_compute_key()"); |
43 | if(cklen && (*ckptr)&0x80) { | 44 | if(cklen && (*ckptr)&0x80) { |
44 | (*(--ckptr)) = 0; ++cklen; | 45 | (*(--ckptr)) = 0; ++cklen; |
45 | } | 46 | } |
46 | SHA1(ckptr,cklen,key_sha1); | 47 | SHA1(ckptr,cklen,key_sha1); |
47 | st = sess_dh_sha1; | 48 | st = sess_dh_sha1; |
48 | } | 49 | } |
49 | assoc_t assoc = alloc_assoc(mode_associate); | 50 | assoc_t assoc = alloc_assoc(mode_associate); |
50 | time_t now = time(0); | 51 | time_t now = time(0); |
51 | pout.clear(); | 52 | pout.clear(); |
52 | pout["assoc_type"] = assoc->assoc_type(); | 53 | pout["assoc_type"] = assoc->assoc_type(); |
53 | pout["assoc_handle"] = assoc->handle(); | 54 | pout["assoc_handle"] = assoc->handle(); |
54 | /* TODO: eventually remove deprecated stuff */ | 55 | /* TODO: eventually remove deprecated stuff */ |
55 | pout["issued"] = util::time_to_w3c(now); | 56 | pout["issued"] = util::time_to_w3c(now); |
56 | pout["expiry"] = util::time_to_w3c(now+assoc->expires_in()); | 57 | pout["expiry"] = util::time_to_w3c(now+assoc->expires_in()); |
57 | pout["expires_in"] = util::long_to_string(assoc->expires_in()); | 58 | pout["expires_in"] = util::long_to_string(assoc->expires_in()); |
58 | secret_t secret = assoc->secret(); | 59 | secret_t secret = assoc->secret(); |
59 | switch(st) { | 60 | switch(st) { |
60 | case sess_dh_sha1: | 61 | case sess_dh_sha1: |
61 | pout["session_type"] = "DH-SHA1"; | 62 | pout["session_type"] = "DH-SHA1"; |
62 | pout["dh_server_public"] = util::bignum_to_base64(dh->pub_key); | 63 | pout["dh_server_public"] = util::bignum_to_base64(dh->pub_key); |
63 | secret.enxor_to_base64(key_sha1,pout["enc_mac_key"]); | 64 | secret.enxor_to_base64(key_sha1,pout["enc_mac_key"]); |
64 | break; | 65 | break; |
65 | default: | 66 | default: |
66 | secret.to_base64(pout["mac_key"]); | 67 | secret.to_base64(pout["mac_key"]); |
67 | break; | 68 | break; |
68 | } | 69 | } |
69 | } | 70 | } |
70 | 71 | ||
71 | void server_t::checkid_immediate(const params_t& pin,string& return_to,params_t& pout,extension_t *ext) { | 72 | void server_t::checkid_immediate(const params_t& pin,string& return_to,params_t& pout,extension_t *ext) { |
72 | checkid_(mode_checkid_immediate,pin,return_to,pout,ext); | 73 | checkid_(mode_checkid_immediate,pin,return_to,pout,ext); |
73 | } | 74 | } |
74 | 75 | ||
75 | void server_t::checkid_setup(const params_t& pin,string& return_to,params_t& pout,extension_t *ext) { | 76 | void server_t::checkid_setup(const params_t& pin,string& return_to,params_t& pout,extension_t *ext) { |
76 | checkid_(mode_checkid_setup,pin,return_to,pout,ext); | 77 | checkid_(mode_checkid_setup,pin,return_to,pout,ext); |
77 | } | 78 | } |
78 | 79 | ||
79 | void server_t::checkid_(mode_t mode,const params_t& pin,string& return_to,params_t& pout,extension_t *ext) { | 80 | void server_t::checkid_(mode_t mode,const params_t& pin,string& return_to,params_t& pout,extension_t *ext) { |
80 | if(mode!=mode_checkid_immediate && mode!=mode_checkid_setup) | 81 | if(mode!=mode_checkid_immediate && mode!=mode_checkid_setup) |
81 | throw bad_input(OPKELE_CP_ "invalid checkid_* mode"); | 82 | throw bad_input(OPKELE_CP_ "invalid checkid_* mode"); |
82 | pout.clear(); | 83 | pout.clear(); |
83 | assoc_t assoc; | 84 | assoc_t assoc; |
84 | try { | 85 | try { |
85 | assoc = retrieve_assoc(pin.get_param("openid.assoc_handle")); | 86 | assoc = retrieve_assoc(pin.get_param("openid.assoc_handle")); |
86 | }catch(failed_lookup& fl) { | 87 | }catch(failed_lookup& fl) { |
87 | // no handle specified or no valid handle found, going dumb | 88 | // no handle specified or no valid handle found, going dumb |
88 | assoc = alloc_assoc(mode_checkid_setup); | 89 | assoc = alloc_assoc(mode_checkid_setup); |
89 | if(pin.has_param("openid.assoc_handle")) | 90 | if(pin.has_param("openid.assoc_handle")) |
90 | pout["invalidate_handle"]=pin.get_param("openid.assoc_handle"); | 91 | pout["invalidate_handle"]=pin.get_param("openid.assoc_handle"); |
91 | } | 92 | } |
92 | string trust_root; | 93 | string trust_root; |
93 | try { | 94 | try { |
94 | trust_root = pin.get_param("openid.trust_root"); | 95 | trust_root = pin.get_param("openid.trust_root"); |
95 | }catch(failed_lookup& fl) { } | 96 | }catch(failed_lookup& fl) { } |
96 | string identity = pin.get_param("openid.identity"); | 97 | string identity = pin.get_param("openid.identity"); |
97 | return_to = pin.get_param("openid.return_to"); | 98 | return_to = pin.get_param("openid.return_to"); |
98 | validate(*assoc,pin,identity,trust_root); | 99 | validate(*assoc,pin,identity,trust_root); |
99 | pout["mode"] = "id_res"; | 100 | pout["mode"] = "id_res"; |
100 | pout["assoc_handle"] = assoc->handle(); | 101 | pout["assoc_handle"] = assoc->handle(); |
101 | if(pin.has_param("openid.assoc_handle") && assoc->stateless()) | 102 | if(pin.has_param("openid.assoc_handle") && assoc->stateless()) |
102 | pout["invalidate_handle"] = pin.get_param("openid.assoc_handle"); | 103 | pout["invalidate_handle"] = pin.get_param("openid.assoc_handle"); |
103 | pout["identity"] = identity; | 104 | pout["identity"] = identity; |
104 | pout["return_to"] = return_to; | 105 | pout["return_to"] = return_to; |
105 | /* TODO: eventually remove deprecated stuff */ | 106 | /* TODO: eventually remove deprecated stuff */ |
106 | time_t now = time(0); | 107 | time_t now = time(0); |
107 | pout["issued"] = util::time_to_w3c(now); | 108 | pout["issued"] = util::time_to_w3c(now); |
108 | pout["valid_to"] = util::time_to_w3c(now+120); | 109 | pout["valid_to"] = util::time_to_w3c(now+120); |
109 | pout["exipres_in"] = "120"; | 110 | pout["exipres_in"] = "120"; |
110 | pout["signed"]="mode,identity,return_to"; | 111 | pout["signed"]="mode,identity,return_to"; |
111 | if(ext) ext->checkid_hook(pin,pout); | 112 | if(ext) ext->checkid_hook(pin,pout); |
112 | pout["sig"] = util::base64_signature(assoc,pout); | 113 | pout["sig"] = util::base64_signature(assoc,pout); |
113 | } | 114 | } |
114 | 115 | ||
115 | void server_t::check_authentication(const params_t& pin,params_t& pout) { | 116 | void server_t::check_authentication(const params_t& pin,params_t& pout) { |
116 | vector<unsigned char> sig; | 117 | vector<unsigned char> sig; |
117 | const string& sigenc = pin.get_param("openid.sig"); | 118 | const string& sigenc = pin.get_param("openid.sig"); |
118 | util::decode_base64(sigenc,sig); | 119 | util::decode_base64(sigenc,sig); |
119 | assoc_t assoc; | 120 | assoc_t assoc; |
120 | try { | 121 | try { |
121 | assoc = retrieve_assoc(pin.get_param("openid.assoc_handle")); | 122 | assoc = retrieve_assoc(pin.get_param("openid.assoc_handle")); |
122 | }catch(failed_lookup& fl) { | 123 | }catch(failed_lookup& fl) { |
123 | throw failed_assertion(OPKELE_CP_ "invalid handle or handle not specified"); | 124 | throw failed_assertion(OPKELE_CP_ "invalid handle or handle not specified"); |
124 | } | 125 | } |
125 | if(!assoc->stateless()) | 126 | if(!assoc->stateless()) |
126 | throw stateful_handle(OPKELE_CP_ "will not do check_authentication on a stateful handle"); | 127 | throw stateful_handle(OPKELE_CP_ "will not do check_authentication on a stateful handle"); |
127 | const string& slist = pin.get_param("openid.signed"); | 128 | const string& slist = pin.get_param("openid.signed"); |
128 | string kv; | 129 | string kv; |
129 | string::size_type p =0; | 130 | string::size_type p =0; |
130 | while(true) { | 131 | while(true) { |
131 | string::size_type co = slist.find(',',p); | 132 | string::size_type co = slist.find(',',p); |
132 | string f = (co==string::npos)?slist.substr(p):slist.substr(p,co-p); | 133 | string f = (co==string::npos)?slist.substr(p):slist.substr(p,co-p); |
133 | kv += f; | 134 | kv += f; |
diff --git a/test/idiscover.cc b/test/idiscover.cc index 44df9ce..4b1e90c 100644 --- a/test/idiscover.cc +++ b/test/idiscover.cc | |||
@@ -1,40 +1,41 @@ | |||
1 | #include <iostream> | 1 | #include <iostream> |
2 | #include <stdexcept> | 2 | #include <stdexcept> |
3 | #include <iterator> | 3 | #include <iterator> |
4 | #include <algorithm> | 4 | #include <algorithm> |
5 | using namespace std; | 5 | using namespace std; |
6 | #include <opkele/exception.h> | 6 | #include <opkele/exception.h> |
7 | #include <opkele/discovery.h> | 7 | #include <opkele/discovery.h> |
8 | #include <opkele/util.h> | 8 | #include <opkele/util.h> |
9 | #include <opkele/util-internal.h> | ||
9 | 10 | ||
10 | namespace opkele { | 11 | namespace opkele { |
11 | ostream& operator<<(ostream& o,const opkele::openid_endpoint_t& oep) { | 12 | ostream& operator<<(ostream& o,const opkele::openid_endpoint_t& oep) { |
12 | o | 13 | o |
13 | << " URI: " << oep.uri << endl | 14 | << " URI: " << oep.uri << endl |
14 | << " Claimed ID: " << oep.claimed_id << endl | 15 | << " Claimed ID: " << oep.claimed_id << endl |
15 | << " Local ID: " << oep.local_id << endl; | 16 | << " Local ID: " << oep.local_id << endl; |
16 | return o; | 17 | return o; |
17 | } | 18 | } |
18 | } | 19 | } |
19 | 20 | ||
20 | int main(int argc,char **argv) { | 21 | int main(int argc,char **argv) { |
21 | try { | 22 | try { |
22 | if(argc<2) | 23 | if(argc<2) |
23 | throw opkele::exception(OPKELE_CP_ "Please, give me something to resolve"); | 24 | throw opkele::exception(OPKELE_CP_ "Please, give me something to resolve"); |
24 | for(int a=1;a<argc;++a) { | 25 | for(int a=1;a<argc;++a) { |
25 | cout << "==============================================================" << endl | 26 | cout << "==============================================================" << endl |
26 | << "User-supplied ID: " << argv[a] << endl | 27 | << "User-supplied ID: " << argv[a] << endl |
27 | << "Endpoints:" << endl | 28 | << "Endpoints:" << endl |
28 | << " --" << endl; | 29 | << " --" << endl; |
29 | string normalized = opkele::idiscover( | 30 | string normalized = opkele::idiscover( |
30 | ostream_iterator<opkele::openid_endpoint_t>(cout," --\n") | 31 | ostream_iterator<opkele::openid_endpoint_t>(cout," --\n") |
31 | ,argv[a]); | 32 | ,argv[a]); |
32 | cout << "Normalized ID: " << normalized << endl; | 33 | cout << "Normalized ID: " << normalized << endl; |
33 | } | 34 | } |
34 | }catch(exception& e) { | 35 | }catch(exception& e) { |
35 | cerr << "oops, caught " << opkele::util::abi_demangle(typeid(e).name()) << endl | 36 | cerr << "oops, caught " << opkele::util::abi_demangle(typeid(e).name()) << endl |
36 | << " .what(): " << e.what() << endl; | 37 | << " .what(): " << e.what() << endl; |
37 | _exit(1); | 38 | _exit(1); |
38 | } | 39 | } |
39 | _exit(0); | 40 | _exit(0); |
40 | } | 41 | } |