-rw-r--r-- | include/opkele/basic_op.h | 2 | ||||
-rw-r--r-- | include/opkele/expat.h | 16 | ||||
-rw-r--r-- | include/opkele/iterator.h | 19 | ||||
-rw-r--r-- | include/opkele/types.h | 1 | ||||
-rw-r--r-- | lib/basic_op.cc | 29 | ||||
-rw-r--r-- | lib/basic_rp.cc | 10 | ||||
-rw-r--r-- | lib/discovery.cc | 2 | ||||
-rw-r--r-- | lib/expat.cc | 1 | ||||
-rw-r--r-- | lib/extension.cc | 2 | ||||
-rw-r--r-- | lib/openid_message.cc | 32 | ||||
-rw-r--r-- | lib/prequeue_rp.cc | 4 | ||||
-rw-r--r-- | lib/sreg.cc | 6 | ||||
-rw-r--r-- | lib/verify_op.cc | 4 | ||||
-rw-r--r-- | test/OP.cc | 16 | ||||
-rw-r--r-- | test/RP.cc | 6 | ||||
-rw-r--r-- | test/kingate_openid_message.h | 4 |
16 files changed, 77 insertions, 77 deletions
diff --git a/include/opkele/basic_op.h b/include/opkele/basic_op.h index 0326508..12306dd 100644 --- a/include/opkele/basic_op.h +++ b/include/opkele/basic_op.h | |||
@@ -17,64 +17,66 @@ namespace opkele { | |||
17 | * The request mode for the request being processed | 17 | * The request mode for the request being processed |
18 | */ | 18 | */ |
19 | mode_t mode; | 19 | mode_t mode; |
20 | /** | 20 | /** |
21 | * association used in transaction. reset in case of dumb operation | 21 | * association used in transaction. reset in case of dumb operation |
22 | */ | 22 | */ |
23 | assoc_t assoc; | 23 | assoc_t assoc; |
24 | /** | 24 | /** |
25 | * true if the request is openid2 request | 25 | * true if the request is openid2 request |
26 | */ | 26 | */ |
27 | bool openid2; | 27 | bool openid2; |
28 | /** | 28 | /** |
29 | * The return_to RP endpoint | 29 | * The return_to RP endpoint |
30 | */ | 30 | */ |
31 | string return_to; | 31 | string return_to; |
32 | /** | 32 | /** |
33 | * The realm we authenticate for | 33 | * The realm we authenticate for |
34 | */ | 34 | */ |
35 | string realm; | 35 | string realm; |
36 | /** | 36 | /** |
37 | * Claimed identifier | 37 | * Claimed identifier |
38 | */ | 38 | */ |
39 | string claimed_id; | 39 | string claimed_id; |
40 | /** | 40 | /** |
41 | * The OP-Local identifier | 41 | * The OP-Local identifier |
42 | */ | 42 | */ |
43 | string identity; | 43 | string identity; |
44 | /** | 44 | /** |
45 | * The invalidate handle for the reply request | 45 | * The invalidate handle for the reply request |
46 | */ | 46 | */ |
47 | string invalidate_handle; | 47 | string invalidate_handle; |
48 | 48 | ||
49 | virtual ~basic_OP() { } | ||
50 | |||
49 | void reset_vars(); | 51 | void reset_vars(); |
50 | 52 | ||
51 | /** | 53 | /** |
52 | * @name Request information access | 54 | * @name Request information access |
53 | * Setting and retrieval of the information pertaining to the request being processed | 55 | * Setting and retrieval of the information pertaining to the request being processed |
54 | * @{ | 56 | * @{ |
55 | */ | 57 | */ |
56 | /** | 58 | /** |
57 | * Check if the RP expects us to get back to them. | 59 | * Check if the RP expects us to get back to them. |
58 | * @return true if RP supplied return_to URL | 60 | * @return true if RP supplied return_to URL |
59 | */ | 61 | */ |
60 | bool has_return_to() const; | 62 | bool has_return_to() const; |
61 | /** | 63 | /** |
62 | * Find out where the RP is waiting for us. | 64 | * Find out where the RP is waiting for us. |
63 | * @return the return_to URL supplied | 65 | * @return the return_to URL supplied |
64 | * @throw no_return_to if no return_to is supplied with the request | 66 | * @throw no_return_to if no return_to is supplied with the request |
65 | */ | 67 | */ |
66 | const string& get_return_to() const; | 68 | const string& get_return_to() const; |
67 | 69 | ||
68 | /** | 70 | /** |
69 | * Find out what realm we are authenticating user for | 71 | * Find out what realm we are authenticating user for |
70 | * @return the realm | 72 | * @return the realm |
71 | */ | 73 | */ |
72 | const string& get_realm() const; | 74 | const string& get_realm() const; |
73 | 75 | ||
74 | /** | 76 | /** |
75 | * Check if request is about identity | 77 | * Check if request is about identity |
76 | * @return true if so | 78 | * @return true if so |
77 | */ | 79 | */ |
78 | bool has_identity() const; | 80 | bool has_identity() const; |
79 | /** | 81 | /** |
80 | * Get claimed identifier supplied with the request | 82 | * Get claimed identifier supplied with the request |
diff --git a/include/opkele/expat.h b/include/opkele/expat.h index 60c41ac..3ab1630 100644 --- a/include/opkele/expat.h +++ b/include/opkele/expat.h | |||
@@ -1,83 +1,83 @@ | |||
1 | #ifndef __OPKELE_EXPAT_H | 1 | #ifndef __OPKELE_EXPAT_H |
2 | #define __OPKELE_EXPAT_H | 2 | #define __OPKELE_EXPAT_H |
3 | 3 | ||
4 | #include <cassert> | 4 | #include <cassert> |
5 | #include <expat.h> | 5 | #include <expat.h> |
6 | 6 | ||
7 | namespace opkele { | 7 | namespace opkele { |
8 | 8 | ||
9 | namespace util { | 9 | namespace util { |
10 | 10 | ||
11 | class expat_t { | 11 | class expat_t { |
12 | public: | 12 | public: |
13 | XML_Parser _x; | 13 | XML_Parser _x; |
14 | 14 | ||
15 | expat_t() : _x(0) { } | 15 | expat_t() : _x(0) { } |
16 | expat_t(XML_Parser x) : _x(x) { } | 16 | expat_t(XML_Parser x) : _x(x) { } |
17 | virtual ~expat_t() throw(); | 17 | virtual ~expat_t() throw(); |
18 | 18 | ||
19 | expat_t& operator=(XML_Parser x); | 19 | expat_t& operator=(XML_Parser x); |
20 | 20 | ||
21 | operator const XML_Parser(void) const { return _x; } | 21 | operator const XML_Parser(void) const { return _x; } |
22 | operator XML_Parser(void) { return _x; } | 22 | operator XML_Parser(void) { return _x; } |
23 | 23 | ||
24 | inline bool parse(const char *s,int len,bool final=false) { | 24 | inline bool parse(const char *s,int len,bool final=false) { |
25 | assert(_x); | 25 | assert(_x); |
26 | return XML_Parse(_x,s,len,final); | 26 | return XML_Parse(_x,s,len,final); |
27 | } | 27 | } |
28 | 28 | ||
29 | virtual void start_element(const XML_Char *n,const XML_Char **a) { } | 29 | virtual void start_element(const XML_Char * /* n */,const XML_Char ** /* a */) { } |
30 | virtual void end_element(const XML_Char *n) { } | 30 | virtual void end_element(const XML_Char * /* n */) { } |
31 | void set_element_handler(); | 31 | void set_element_handler(); |
32 | 32 | ||
33 | virtual void character_data(const XML_Char *s,int l) { } | 33 | virtual void character_data(const XML_Char * /* s */,int /* l */) { } |
34 | void set_character_data_handler(); | 34 | void set_character_data_handler(); |
35 | 35 | ||
36 | virtual void processing_instruction(const XML_Char *t,const XML_Char *d) { } | 36 | virtual void processing_instruction(const XML_Char * /* t */,const XML_Char * /* d */) { } |
37 | void set_processing_instruction_handler(); | 37 | void set_processing_instruction_handler(); |
38 | 38 | ||
39 | virtual void comment(const XML_Char *d) { } | 39 | virtual void comment(const XML_Char * /* d */) { } |
40 | void set_comment_handler(); | 40 | void set_comment_handler(); |
41 | 41 | ||
42 | virtual void start_cdata_section() { } | 42 | virtual void start_cdata_section() { } |
43 | virtual void end_cdata_section() { } | 43 | virtual void end_cdata_section() { } |
44 | void set_cdata_section_handler(); | 44 | void set_cdata_section_handler(); |
45 | 45 | ||
46 | virtual void default_handler(const XML_Char *s,int l) { } | 46 | virtual void default_handler(const XML_Char * /* s */,int /* l */) { } |
47 | void set_default_handler(); | 47 | void set_default_handler(); |
48 | void set_default_handler_expand(); | 48 | void set_default_handler_expand(); |
49 | 49 | ||
50 | virtual void start_namespace_decl(const XML_Char *p,const XML_Char *u) { } | 50 | virtual void start_namespace_decl(const XML_Char * /* p */,const XML_Char * /* u */) { } |
51 | virtual void end_namespace_decl(const XML_Char *p) { } | 51 | virtual void end_namespace_decl(const XML_Char * /* p */) { } |
52 | void set_namespace_decl_handler(); | 52 | void set_namespace_decl_handler(); |
53 | 53 | ||
54 | inline enum XML_Error get_error_code() { | 54 | inline enum XML_Error get_error_code() { |
55 | assert(_x); return XML_GetErrorCode(_x); } | 55 | assert(_x); return XML_GetErrorCode(_x); } |
56 | static inline const XML_LChar *error_string(XML_Error c) { | 56 | static inline const XML_LChar *error_string(XML_Error c) { |
57 | return XML_ErrorString(c); } | 57 | return XML_ErrorString(c); } |
58 | 58 | ||
59 | inline long get_current_byte_index() { | 59 | inline long get_current_byte_index() { |
60 | assert(_x); return XML_GetCurrentByteIndex(_x); } | 60 | assert(_x); return XML_GetCurrentByteIndex(_x); } |
61 | inline int get_current_line_number() { | 61 | inline int get_current_line_number() { |
62 | assert(_x); return XML_GetCurrentLineNumber(_x); } | 62 | assert(_x); return XML_GetCurrentLineNumber(_x); } |
63 | inline int get_current_column_number() { | 63 | inline int get_current_column_number() { |
64 | assert(_x); return XML_GetCurrentColumnNumber(_x); } | 64 | assert(_x); return XML_GetCurrentColumnNumber(_x); } |
65 | 65 | ||
66 | inline void set_user_data() { | 66 | inline void set_user_data() { |
67 | assert(_x); XML_SetUserData(_x,this); } | 67 | assert(_x); XML_SetUserData(_x,this); } |
68 | 68 | ||
69 | inline bool set_base(const XML_Char *b) { | 69 | inline bool set_base(const XML_Char *b) { |
70 | assert(_x); return XML_SetBase(_x,b); } | 70 | assert(_x); return XML_SetBase(_x,b); } |
71 | inline const XML_Char *get_base() { | 71 | inline const XML_Char *get_base() { |
72 | assert(_x); return XML_GetBase(_x); } | 72 | assert(_x); return XML_GetBase(_x); } |
73 | 73 | ||
74 | inline int get_specified_attribute_count() { | 74 | inline int get_specified_attribute_count() { |
75 | assert(_x); return XML_GetSpecifiedAttributeCount(_x); } | 75 | assert(_x); return XML_GetSpecifiedAttributeCount(_x); } |
76 | 76 | ||
77 | inline bool set_param_entity_parsing(enum XML_ParamEntityParsing c) { | 77 | inline bool set_param_entity_parsing(enum XML_ParamEntityParsing c) { |
78 | assert(_x); return XML_SetParamEntityParsing(_x,c); } | 78 | assert(_x); return XML_SetParamEntityParsing(_x,c); } |
79 | 79 | ||
80 | inline static XML_Parser parser_create(const XML_Char *e=0) { | 80 | inline static XML_Parser parser_create(const XML_Char *e=0) { |
81 | return XML_ParserCreate(e); } | 81 | return XML_ParserCreate(e); } |
82 | inline static XML_Parser parser_create_ns(const XML_Char *e=0,XML_Char s='\t') { | 82 | inline static XML_Parser parser_create_ns(const XML_Char *e=0,XML_Char s='\t') { |
83 | return XML_ParserCreateNS(e,s); } | 83 | return XML_ParserCreateNS(e,s); } |
diff --git a/include/opkele/iterator.h b/include/opkele/iterator.h index 812a786..28c1c83 100644 --- a/include/opkele/iterator.h +++ b/include/opkele/iterator.h | |||
@@ -1,217 +1,216 @@ | |||
1 | #ifndef __OPKELE_ITERATOR_H | 1 | #ifndef __OPKELE_ITERATOR_H |
2 | #define __OPKELE_ITERATOR_H | 2 | #define __OPKELE_ITERATOR_H |
3 | 3 | ||
4 | #include <cassert> | 4 | #include <cassert> |
5 | #include <iterator> | 5 | #include <iterator> |
6 | 6 | ||
7 | namespace opkele { | 7 | namespace opkele { |
8 | namespace util { | 8 | namespace util { |
9 | using std::iterator; | 9 | using std::iterator; |
10 | using std::forward_iterator_tag; | 10 | using std::forward_iterator_tag; |
11 | using std::output_iterator_tag; | 11 | using std::output_iterator_tag; |
12 | 12 | ||
13 | template <typename T> | 13 | template <typename T> |
14 | class basic_output_iterator_proxy_impl : public iterator<output_iterator_tag,T,void,T*,T&> { | 14 | class basic_output_iterator_proxy_impl : public iterator<output_iterator_tag,T,void,T*,T&> { |
15 | public: | 15 | public: |
16 | virtual ~basic_output_iterator_proxy_impl() { } | 16 | virtual ~basic_output_iterator_proxy_impl() { } |
17 | 17 | ||
18 | virtual basic_output_iterator_proxy_impl<T>* dup() const = 0; | 18 | virtual basic_output_iterator_proxy_impl<T>* dup() const = 0; |
19 | basic_output_iterator_proxy_impl<T>& operator*() { return *this; }; | 19 | basic_output_iterator_proxy_impl<T>& operator*() { return *this; }; |
20 | virtual basic_output_iterator_proxy_impl<T>& operator=(const T& x) = 0; | 20 | virtual basic_output_iterator_proxy_impl<T>& operator=(const T& x) = 0; |
21 | 21 | ||
22 | }; | 22 | }; |
23 | 23 | ||
24 | template<typename IT,typename T=typename IT::value_type> | 24 | template<typename IT,typename T=typename IT::value_type> |
25 | class output_iterator_proxy_impl : public basic_output_iterator_proxy_impl<T> { | 25 | class output_iterator_proxy_impl : public basic_output_iterator_proxy_impl<T> { |
26 | public: | 26 | public: |
27 | IT i; | 27 | IT i; |
28 | 28 | ||
29 | output_iterator_proxy_impl(const IT& i) : i(i) { } | 29 | output_iterator_proxy_impl(const IT& _i) : i(_i) { } |
30 | basic_output_iterator_proxy_impl<T>* dup() const { | 30 | basic_output_iterator_proxy_impl<T>* dup() const { |
31 | return new output_iterator_proxy_impl<IT,T>(i); } | 31 | return new output_iterator_proxy_impl<IT,T>(i); } |
32 | basic_output_iterator_proxy_impl<T>& operator=(const T& x) { | 32 | basic_output_iterator_proxy_impl<T>& operator=(const T& x) { |
33 | (*i) = x; | 33 | (*i) = x; return *this; } |
34 | } | ||
35 | }; | 34 | }; |
36 | 35 | ||
37 | template<typename T> | 36 | template<typename T> |
38 | class output_iterator_proxy : public iterator<output_iterator_tag,T,void,T*,T&> { | 37 | class output_iterator_proxy : public iterator<output_iterator_tag,T,void,T*,T&> { |
39 | public: | 38 | public: |
40 | basic_output_iterator_proxy_impl<T> *I; | 39 | basic_output_iterator_proxy_impl<T> *I; |
41 | 40 | ||
42 | template<typename IT> | 41 | template<typename IT> |
43 | output_iterator_proxy(const IT& i) | 42 | output_iterator_proxy(const IT& i) |
44 | : I(new output_iterator_proxy_impl<IT,T>(i)) { } | 43 | : I(new output_iterator_proxy_impl<IT,T>(i)) { } |
45 | output_iterator_proxy(const output_iterator_proxy<T>& x) | 44 | output_iterator_proxy(const output_iterator_proxy<T>& x) |
46 | : I(x.I->dup()) { } | 45 | : I(x.I->dup()) { } |
47 | ~output_iterator_proxy() { delete I; } | 46 | ~output_iterator_proxy() { delete I; } |
48 | 47 | ||
49 | output_iterator_proxy& operator=(const output_iterator_proxy<T>& x) { | 48 | output_iterator_proxy& operator=(const output_iterator_proxy<T>& x) { |
50 | delete I; I = x.I->dup(); } | 49 | delete I; I = x.I->dup(); } |
51 | 50 | ||
52 | output_iterator_proxy& operator*() { return *this; } | 51 | output_iterator_proxy& operator*() { return *this; } |
53 | output_iterator_proxy& operator=(const T& x) { | 52 | output_iterator_proxy& operator=(const T& x) { |
54 | (**I) = x; } | 53 | (**I) = x; return *this; } |
55 | 54 | ||
56 | output_iterator_proxy& operator++() { return *this; } | 55 | output_iterator_proxy& operator++() { return *this; } |
57 | output_iterator_proxy& operator++(int) { return *this; } | 56 | output_iterator_proxy& operator++(int) { return *this; } |
58 | }; | 57 | }; |
59 | 58 | ||
60 | template <typename T,typename TR=T&,typename TP=T*> | 59 | template <typename T,typename TR=T&,typename TP=T*> |
61 | class basic_forward_iterator_proxy_impl : public iterator<forward_iterator_tag,T,void,TP,TR> { | 60 | class basic_forward_iterator_proxy_impl : public iterator<forward_iterator_tag,T,void,TP,TR> { |
62 | public: | 61 | public: |
63 | virtual ~basic_forward_iterator_proxy_impl() { } | 62 | virtual ~basic_forward_iterator_proxy_impl() { } |
64 | 63 | ||
65 | virtual basic_forward_iterator_proxy_impl<T,TR,TP>* dup() const = 0; | 64 | virtual basic_forward_iterator_proxy_impl<T,TR,TP>* dup() const = 0; |
66 | 65 | ||
67 | virtual bool operator==(const basic_forward_iterator_proxy_impl<T,TR,TP>& x) const = 0; | 66 | virtual bool operator==(const basic_forward_iterator_proxy_impl<T,TR,TP>& x) const = 0; |
68 | virtual bool operator!=(const basic_forward_iterator_proxy_impl<T,TR,TP>& x) const { | 67 | virtual bool operator!=(const basic_forward_iterator_proxy_impl<T,TR,TP>& x) const { |
69 | return !((*this)==x); } | 68 | return !((*this)==x); } |
70 | virtual TR operator*() const = 0; | 69 | virtual TR operator*() const = 0; |
71 | virtual TP operator->() const = 0; | 70 | virtual TP operator->() const = 0; |
72 | virtual void advance() = 0; | 71 | virtual void advance() = 0; |
73 | }; | 72 | }; |
74 | 73 | ||
75 | template <typename IT> | 74 | template <typename IT> |
76 | class forward_iterator_proxy_impl : public basic_forward_iterator_proxy_impl<typename IT::value_type,typename IT::reference,typename IT::pointer> { | 75 | class forward_iterator_proxy_impl : public basic_forward_iterator_proxy_impl<typename IT::value_type,typename IT::reference,typename IT::pointer> { |
77 | public: | 76 | public: |
78 | IT i; | 77 | IT i; |
79 | 78 | ||
80 | forward_iterator_proxy_impl(const IT& i) : i(i) { } | 79 | forward_iterator_proxy_impl(const IT& _i) : i(_i) { } |
81 | 80 | ||
82 | virtual basic_forward_iterator_proxy_impl<typename IT::value_type,typename IT::reference,typename IT::pointer>* dup() const { | 81 | virtual basic_forward_iterator_proxy_impl<typename IT::value_type,typename IT::reference,typename IT::pointer>* dup() const { |
83 | return new forward_iterator_proxy_impl<IT>(i); } | 82 | return new forward_iterator_proxy_impl<IT>(i); } |
84 | 83 | ||
85 | virtual bool operator==(const basic_forward_iterator_proxy_impl<typename IT::value_type,typename IT::reference,typename IT::pointer>& x) const { | 84 | virtual bool operator==(const basic_forward_iterator_proxy_impl<typename IT::value_type,typename IT::reference,typename IT::pointer>& x) const { |
86 | return i==static_cast<const forward_iterator_proxy_impl<IT>*>(&x)->i; } | 85 | return i==static_cast<const forward_iterator_proxy_impl<IT>*>(&x)->i; } |
87 | virtual bool operator!=(const basic_forward_iterator_proxy_impl<typename IT::value_type,typename IT::reference,typename IT::pointer>& x) const { | 86 | virtual bool operator!=(const basic_forward_iterator_proxy_impl<typename IT::value_type,typename IT::reference,typename IT::pointer>& x) const { |
88 | return i!=static_cast<const forward_iterator_proxy_impl<IT>*>(&x)->i; } | 87 | return i!=static_cast<const forward_iterator_proxy_impl<IT>*>(&x)->i; } |
89 | virtual typename IT::reference operator*() const { return *i; } | 88 | virtual typename IT::reference operator*() const { return *i; } |
90 | virtual typename IT::pointer operator->() const { return i.operator->(); } | 89 | virtual typename IT::pointer operator->() const { return i.operator->(); } |
91 | virtual void advance() { ++i; } | 90 | virtual void advance() { ++i; } |
92 | }; | 91 | }; |
93 | 92 | ||
94 | template<typename T,typename TR=T&,typename TP=T*> | 93 | template<typename T,typename TR=T&,typename TP=T*> |
95 | class forward_iterator_proxy : public iterator<forward_iterator_tag,T,void,TP,TR> { | 94 | class forward_iterator_proxy : public iterator<forward_iterator_tag,T,void,TP,TR> { |
96 | public: | 95 | public: |
97 | basic_forward_iterator_proxy_impl<T,TR,TP> *I; | 96 | basic_forward_iterator_proxy_impl<T,TR,TP> *I; |
98 | 97 | ||
99 | template<typename IT> | 98 | template<typename IT> |
100 | forward_iterator_proxy(const IT& i) | 99 | forward_iterator_proxy(const IT& i) |
101 | : I(new forward_iterator_proxy_impl<IT>(i)) { } | 100 | : I(new forward_iterator_proxy_impl<IT>(i)) { } |
102 | forward_iterator_proxy(const forward_iterator_proxy<T,TR,TP>& x) | 101 | forward_iterator_proxy(const forward_iterator_proxy<T,TR,TP>& x) |
103 | : I(x.I->dup()) { } | 102 | : I(x.I->dup()) { } |
104 | ~forward_iterator_proxy() { delete I; } | 103 | ~forward_iterator_proxy() { delete I; } |
105 | 104 | ||
106 | forward_iterator_proxy& operator=(const forward_iterator_proxy<T,TR,TP>& x) { | 105 | forward_iterator_proxy& operator=(const forward_iterator_proxy<T,TR,TP>& x) { |
107 | delete I; I = x.I->dup(); } | 106 | delete I; I = x.I->dup(); } |
108 | 107 | ||
109 | bool operator==(const forward_iterator_proxy<T,TR,TP>& x) const { | 108 | bool operator==(const forward_iterator_proxy<T,TR,TP>& x) const { |
110 | return (*I)==(*(x.I)); } | 109 | return (*I)==(*(x.I)); } |
111 | bool operator!=(const forward_iterator_proxy<T,TR,TP>& x) const { | 110 | bool operator!=(const forward_iterator_proxy<T,TR,TP>& x) const { |
112 | return (*I)!=(*(x.I)); } | 111 | return (*I)!=(*(x.I)); } |
113 | 112 | ||
114 | TR operator*() const { | 113 | TR operator*() const { |
115 | return **I; } | 114 | return **I; } |
116 | TP operator->() const { | 115 | TP operator->() const { |
117 | return I->operator->(); } | 116 | return I->operator->(); } |
118 | 117 | ||
119 | forward_iterator_proxy<T,TR,TP>& operator++() { | 118 | forward_iterator_proxy<T,TR,TP>& operator++() { |
120 | I->advance(); return *this; } | 119 | I->advance(); return *this; } |
121 | forward_iterator_proxy<T,TR,TP>& operator++(int) { | 120 | forward_iterator_proxy<T,TR,TP>& operator++(int) { |
122 | forward_iterator_proxy<T,TR,TP> rv(*this); | 121 | forward_iterator_proxy<T,TR,TP> rv(*this); |
123 | I->advance(); return rv; } | 122 | I->advance(); return rv; } |
124 | }; | 123 | }; |
125 | 124 | ||
126 | template<typename IT> | 125 | template<typename IT> |
127 | class basic_filterator : public iterator< | 126 | class basic_filterator : public iterator< |
128 | typename IT::iterator_category, | 127 | typename IT::iterator_category, |
129 | typename IT::value_type, | 128 | typename IT::value_type, |
130 | typename IT::difference_type, | 129 | typename IT::difference_type, |
131 | typename IT::pointer, | 130 | typename IT::pointer, |
132 | typename IT::reference> { | 131 | typename IT::reference> { |
133 | public: | 132 | public: |
134 | IT it; | 133 | IT it; |
135 | IT ei; | 134 | IT ei; |
136 | bool empty; | 135 | bool empty; |
137 | 136 | ||
138 | basic_filterator() : empty(true) { } | 137 | basic_filterator() : empty(true) { } |
139 | basic_filterator(const IT& bi,const IT& ei) | 138 | basic_filterator(const IT& _bi,const IT& _ei) |
140 | : it(bi), ei(ei) { empty = (bi==ei); } | 139 | : it(_bi), ei(_ei) { empty = (it==ei); } |
141 | basic_filterator(const basic_filterator<IT>& x) | 140 | basic_filterator(const basic_filterator<IT>& x) |
142 | : it(x.it), ei(x.ei), empty(x.empty) { } | 141 | : it(x.it), ei(x.ei), empty(x.empty) { } |
143 | virtual ~basic_filterator() { } | 142 | virtual ~basic_filterator() { } |
144 | 143 | ||
145 | bool operator==(const basic_filterator<IT>& x) const { | 144 | bool operator==(const basic_filterator<IT>& x) const { |
146 | return empty?x.empty:(it==x.it); } | 145 | return empty?x.empty:(it==x.it); } |
147 | bool operator!=(const basic_filterator<IT>& x) const { | 146 | bool operator!=(const basic_filterator<IT>& x) const { |
148 | return empty!=x.empty || it!=x.it; } | 147 | return empty!=x.empty || it!=x.it; } |
149 | 148 | ||
150 | typename IT::reference operator*() const { | 149 | typename IT::reference operator*() const { |
151 | assert(!empty); | 150 | assert(!empty); |
152 | return *it; } | 151 | return *it; } |
153 | typename IT::pointer operator->() const { | 152 | typename IT::pointer operator->() const { |
154 | assert(!empty); | 153 | assert(!empty); |
155 | return it.operator->(); } | 154 | return it.operator->(); } |
156 | 155 | ||
157 | basic_filterator<IT>& operator++() { | 156 | basic_filterator<IT>& operator++() { |
158 | bool found = false; | 157 | bool found = false; |
159 | for(++it;!(it==ei || (found=is_interesting()));++it); | 158 | for(++it;!(it==ei || (found=is_interesting()));++it); |
160 | if(!found) empty=true; | 159 | if(!found) empty=true; |
161 | return *this; | 160 | return *this; |
162 | } | 161 | } |
163 | basic_filterator<IT> operator++(int) { | 162 | basic_filterator<IT> operator++(int) { |
164 | basic_filterator<IT> rv(*this); | 163 | basic_filterator<IT> rv(*this); |
165 | ++(*this); | 164 | ++(*this); |
166 | return rv; | 165 | return rv; |
167 | } | 166 | } |
168 | 167 | ||
169 | void prepare() { | 168 | void prepare() { |
170 | bool found = false; | 169 | bool found = false; |
171 | for(;!(it==ei || (found=is_interesting()));++it); | 170 | for(;!(it==ei || (found=is_interesting()));++it); |
172 | if(!found) empty = true; | 171 | if(!found) empty = true; |
173 | } | 172 | } |
174 | virtual bool is_interesting() const = 0; | 173 | virtual bool is_interesting() const = 0; |
175 | }; | 174 | }; |
176 | 175 | ||
177 | template<typename IT,typename T=typename IT::value_type::first_type,typename TR=T&,typename TP=T*> | 176 | template<typename IT,typename T=typename IT::value_type::first_type,typename TR=T&,typename TP=T*> |
178 | class map_keys_iterator : public iterator< | 177 | class map_keys_iterator : public iterator< |
179 | typename IT::iterator_category, | 178 | typename IT::iterator_category, |
180 | T,void,TP,TR> { | 179 | T,void,TP,TR> { |
181 | public: | 180 | public: |
182 | typedef map_keys_iterator<IT,T,TR,TP> self_type; | 181 | typedef map_keys_iterator<IT,T,TR,TP> self_type; |
183 | IT it; | 182 | IT it; |
184 | IT ei; | 183 | IT ei; |
185 | bool empty; | 184 | bool empty; |
186 | 185 | ||
187 | map_keys_iterator() : empty(true) { } | 186 | map_keys_iterator() : empty(true) { } |
188 | map_keys_iterator(const IT& bi, | 187 | map_keys_iterator(const IT& _bi, |
189 | const IT& ei) | 188 | const IT& _ei) |
190 | : it(bi), ei(ei) { empty = (bi==ei); } | 189 | : it(_bi), ei(_ei) { empty = (it==ei); } |
191 | map_keys_iterator(const self_type& x) | 190 | map_keys_iterator(const self_type& x) |
192 | : it(x.it), ei(x.ei), empty(x.empty) { } | 191 | : it(x.it), ei(x.ei), empty(x.empty) { } |
193 | 192 | ||
194 | bool operator==(const self_type& x) const { | 193 | bool operator==(const self_type& x) const { |
195 | return empty?x.empty:(it==x.it); } | 194 | return empty?x.empty:(it==x.it); } |
196 | bool operator!=(const self_type& x) const { | 195 | bool operator!=(const self_type& x) const { |
197 | return empty!=x.empty || it!=x.it; } | 196 | return empty!=x.empty || it!=x.it; } |
198 | 197 | ||
199 | TR operator*() const { | 198 | TR operator*() const { |
200 | assert(!empty); | 199 | assert(!empty); |
201 | return it->first; } | 200 | return it->first; } |
202 | TP operator->() const { | 201 | TP operator->() const { |
203 | assert(!empty); | 202 | assert(!empty); |
204 | return &(it->first); } | 203 | return &(it->first); } |
205 | 204 | ||
206 | self_type& operator++() { | 205 | self_type& operator++() { |
207 | assert(!empty); | 206 | assert(!empty); |
208 | empty=((++it)==ei); return *this; } | 207 | empty=((++it)==ei); return *this; } |
209 | self_type operator++(int) { | 208 | self_type operator++(int) { |
210 | self_type rv(*this); | 209 | self_type rv(*this); |
211 | ++(*this); return rv; } | 210 | ++(*this); return rv; } |
212 | }; | 211 | }; |
213 | 212 | ||
214 | } | 213 | } |
215 | } | 214 | } |
216 | 215 | ||
217 | #endif /* __OPKELE_ITERATOR_H */ | 216 | #endif /* __OPKELE_ITERATOR_H */ |
diff --git a/include/opkele/types.h b/include/opkele/types.h index 6ab51ef..a3b657d 100644 --- a/include/opkele/types.h +++ b/include/opkele/types.h | |||
@@ -97,64 +97,65 @@ namespace opkele { | |||
97 | */ | 97 | */ |
98 | virtual secret_t secret() const = 0; | 98 | virtual secret_t secret() const = 0; |
99 | /** | 99 | /** |
100 | * retrieve the number of seconds the association expires in. | 100 | * retrieve the number of seconds the association expires in. |
101 | * @return seconds till expiration | 101 | * @return seconds till expiration |
102 | */ | 102 | */ |
103 | virtual int expires_in() const = 0; | 103 | virtual int expires_in() const = 0; |
104 | /** | 104 | /** |
105 | * check whether the association is stateless. | 105 | * check whether the association is stateless. |
106 | * @return true if stateless | 106 | * @return true if stateless |
107 | */ | 107 | */ |
108 | virtual bool stateless() const = 0; | 108 | virtual bool stateless() const = 0; |
109 | /** | 109 | /** |
110 | * check whether the association is expired. | 110 | * check whether the association is expired. |
111 | * @return true if expired | 111 | * @return true if expired |
112 | */ | 112 | */ |
113 | virtual bool is_expired() const = 0; | 113 | virtual bool is_expired() const = 0; |
114 | }; | 114 | }; |
115 | 115 | ||
116 | /** | 116 | /** |
117 | * the shared_ptr<> for association_t object type | 117 | * the shared_ptr<> for association_t object type |
118 | */ | 118 | */ |
119 | typedef tr1mem::shared_ptr<association_t> assoc_t; | 119 | typedef tr1mem::shared_ptr<association_t> assoc_t; |
120 | 120 | ||
121 | class basic_openid_message { | 121 | class basic_openid_message { |
122 | public: | 122 | public: |
123 | typedef list<string> fields_t; | 123 | typedef list<string> fields_t; |
124 | typedef util::forward_iterator_proxy< | 124 | typedef util::forward_iterator_proxy< |
125 | string,const string&,const string* | 125 | string,const string&,const string* |
126 | > fields_iterator; | 126 | > fields_iterator; |
127 | 127 | ||
128 | basic_openid_message() { } | 128 | basic_openid_message() { } |
129 | virtual ~basic_openid_message() { } | ||
129 | basic_openid_message(const basic_openid_message& x); | 130 | basic_openid_message(const basic_openid_message& x); |
130 | void copy_to(basic_openid_message& x) const; | 131 | void copy_to(basic_openid_message& x) const; |
131 | 132 | ||
132 | virtual bool has_field(const string& n) const = 0; | 133 | virtual bool has_field(const string& n) const = 0; |
133 | virtual const string& get_field(const string& n) const = 0; | 134 | virtual const string& get_field(const string& n) const = 0; |
134 | 135 | ||
135 | virtual bool has_ns(const string& uri) const; | 136 | virtual bool has_ns(const string& uri) const; |
136 | virtual string get_ns(const string& uri) const; | 137 | virtual string get_ns(const string& uri) const; |
137 | 138 | ||
138 | virtual fields_iterator fields_begin() const = 0; | 139 | virtual fields_iterator fields_begin() const = 0; |
139 | virtual fields_iterator fields_end() const = 0; | 140 | virtual fields_iterator fields_end() const = 0; |
140 | 141 | ||
141 | virtual string append_query(const string& url) const; | 142 | virtual string append_query(const string& url) const; |
142 | virtual string query_string() const; | 143 | virtual string query_string() const; |
143 | 144 | ||
144 | 145 | ||
145 | virtual void reset_fields(); | 146 | virtual void reset_fields(); |
146 | virtual void set_field(const string& n,const string& v); | 147 | virtual void set_field(const string& n,const string& v); |
147 | virtual void reset_field(const string& n); | 148 | virtual void reset_field(const string& n); |
148 | 149 | ||
149 | virtual void from_keyvalues(const string& kv); | 150 | virtual void from_keyvalues(const string& kv); |
150 | virtual void to_keyvalues(ostream& o) const; | 151 | virtual void to_keyvalues(ostream& o) const; |
151 | 152 | ||
152 | virtual void to_htmlhiddens(ostream& o) const; | 153 | virtual void to_htmlhiddens(ostream& o) const; |
153 | 154 | ||
154 | void add_to_signed(const string& fields); | 155 | void add_to_signed(const string& fields); |
155 | string find_ns(const string& uri,const char *pfx) const; | 156 | string find_ns(const string& uri,const char *pfx) const; |
156 | string allocate_ns(const string& uri,const char *pfx); | 157 | string allocate_ns(const string& uri,const char *pfx); |
157 | }; | 158 | }; |
158 | 159 | ||
159 | class openid_message_t : public basic_openid_message, public map<string,string> { | 160 | class openid_message_t : public basic_openid_message, public map<string,string> { |
160 | public: | 161 | public: |
diff --git a/lib/basic_op.cc b/lib/basic_op.cc index 18446dc..2d82147 100644 --- a/lib/basic_op.cc +++ b/lib/basic_op.cc | |||
@@ -37,136 +37,133 @@ namespace opkele { | |||
37 | const string& basic_OP::get_claimed_id() const { | 37 | const string& basic_OP::get_claimed_id() const { |
38 | if(claimed_id.empty()) | 38 | if(claimed_id.empty()) |
39 | throw non_identity(OPKELE_CP_ "attempting to retrieve claimed_id of non-identity related request"); | 39 | throw non_identity(OPKELE_CP_ "attempting to retrieve claimed_id of non-identity related request"); |
40 | assert(!identity.empty()); | 40 | assert(!identity.empty()); |
41 | return claimed_id; | 41 | return claimed_id; |
42 | } | 42 | } |
43 | const string& basic_OP::get_identity() const { | 43 | const string& basic_OP::get_identity() const { |
44 | if(identity.empty()) | 44 | if(identity.empty()) |
45 | throw non_identity(OPKELE_CP_ "attempting to retrieve identity of non-identity related request"); | 45 | throw non_identity(OPKELE_CP_ "attempting to retrieve identity of non-identity related request"); |
46 | assert(!claimed_id.empty()); | 46 | assert(!claimed_id.empty()); |
47 | return identity; | 47 | return identity; |
48 | } | 48 | } |
49 | 49 | ||
50 | bool basic_OP::is_id_select() const { | 50 | bool basic_OP::is_id_select() const { |
51 | return identity==IDURI_SELECT20; | 51 | return identity==IDURI_SELECT20; |
52 | } | 52 | } |
53 | 53 | ||
54 | void basic_OP::select_identity(const string& c,const string& i) { | 54 | void basic_OP::select_identity(const string& c,const string& i) { |
55 | claimed_id = c; identity = i; | 55 | claimed_id = c; identity = i; |
56 | } | 56 | } |
57 | void basic_OP::set_claimed_id(const string& c) { | 57 | void basic_OP::set_claimed_id(const string& c) { |
58 | claimed_id = c; | 58 | claimed_id = c; |
59 | } | 59 | } |
60 | 60 | ||
61 | basic_openid_message& basic_OP::associate( | 61 | basic_openid_message& basic_OP::associate( |
62 | basic_openid_message& oum, | 62 | basic_openid_message& oum, |
63 | const basic_openid_message& inm) try { | 63 | const basic_openid_message& inm) try { |
64 | assert(inm.get_field("mode")=="associate"); | 64 | assert(inm.get_field("mode")=="associate"); |
65 | util::dh_t dh; | 65 | util::dh_t dh; |
66 | util::bignum_t c_pub; | 66 | util::bignum_t c_pub; |
67 | unsigned char key_digest[SHA256_DIGEST_LENGTH]; | 67 | unsigned char key_digest[SHA256_DIGEST_LENGTH]; |
68 | size_t d_len = 0; | 68 | size_t d_len = 0; |
69 | enum { | ||
70 | sess_cleartext, sess_dh_sha1, sess_dh_sha256 | ||
71 | } st = sess_cleartext; | ||
72 | string sts = inm.get_field("session_type"); | 69 | string sts = inm.get_field("session_type"); |
73 | string ats = inm.get_field("assoc_type"); | 70 | string ats = inm.get_field("assoc_type"); |
74 | if(sts=="DH-SHA1" || sts=="DH-SHA256") { | 71 | if(sts=="DH-SHA1" || sts=="DH-SHA256") { |
75 | if(!(dh = DH_new())) | 72 | if(!(dh = DH_new())) |
76 | throw exception_openssl(OPKELE_CP_ "failed to DH_new()"); | 73 | throw exception_openssl(OPKELE_CP_ "failed to DH_new()"); |
77 | c_pub = util::base64_to_bignum(inm.get_field("dh_consumer_public")); | 74 | c_pub = util::base64_to_bignum(inm.get_field("dh_consumer_public")); |
78 | try { dh->p = util::base64_to_bignum(inm.get_field("dh_modulus")); | 75 | try { dh->p = util::base64_to_bignum(inm.get_field("dh_modulus")); |
79 | }catch(failed_lookup&) { | 76 | }catch(failed_lookup&) { |
80 | dh->p = util::dec_to_bignum(data::_default_p); } | 77 | dh->p = util::dec_to_bignum(data::_default_p); } |
81 | try { dh->g = util::base64_to_bignum(inm.get_field("dh_gen")); | 78 | try { dh->g = util::base64_to_bignum(inm.get_field("dh_gen")); |
82 | }catch(failed_lookup&) { | 79 | }catch(failed_lookup&) { |
83 | dh->g = util::dec_to_bignum(data::_default_g); } | 80 | dh->g = util::dec_to_bignum(data::_default_g); } |
84 | if(!DH_generate_key(dh)) | 81 | if(!DH_generate_key(dh)) |
85 | throw exception_openssl(OPKELE_CP_ "failed to DH_generate_key()"); | 82 | throw exception_openssl(OPKELE_CP_ "failed to DH_generate_key()"); |
86 | vector<unsigned char> ck(DH_size(dh)+1); | 83 | vector<unsigned char> ck(DH_size(dh)+1); |
87 | unsigned char *ckptr = &(ck.front())+1; | 84 | unsigned char *ckptr = &(ck.front())+1; |
88 | int cklen = DH_compute_key(ckptr,c_pub,dh); | 85 | int cklen = DH_compute_key(ckptr,c_pub,dh); |
89 | if(cklen<0) | 86 | if(cklen<0) |
90 | throw exception_openssl(OPKELE_CP_ "failed to DH_compute_key()"); | 87 | throw exception_openssl(OPKELE_CP_ "failed to DH_compute_key()"); |
91 | if(cklen && (*ckptr)&0x80) { | 88 | if(cklen && (*ckptr)&0x80) { |
92 | (*(--ckptr)) = 0; ++cklen; } | 89 | (*(--ckptr)) = 0; ++cklen; } |
93 | if(sts=="DH-SHA1") { | 90 | if(sts=="DH-SHA1") { |
94 | SHA1(ckptr,cklen,key_digest); d_len = SHA_DIGEST_LENGTH; | 91 | SHA1(ckptr,cklen,key_digest); d_len = SHA_DIGEST_LENGTH; |
95 | }else if(sts=="DH-SHA256") { | 92 | }else if(sts=="DH-SHA256") { |
96 | SHA256(ckptr,cklen,key_digest); d_len = SHA256_DIGEST_LENGTH; | 93 | SHA256(ckptr,cklen,key_digest); d_len = SHA256_DIGEST_LENGTH; |
97 | }else | 94 | }else |
98 | throw internal_error(OPKELE_CP_ "I thought I knew the session type"); | 95 | throw internal_error(OPKELE_CP_ "I thought I knew the session type"); |
99 | }else | 96 | }else |
100 | throw unsupported(OPKELE_CP_ "Unsupported session_type"); | 97 | throw unsupported(OPKELE_CP_ "Unsupported session_type"); |
101 | assoc_t assoc; | 98 | assoc_t a; |
102 | if(ats=="HMAC-SHA1") | 99 | if(ats=="HMAC-SHA1") |
103 | assoc = alloc_assoc(ats,SHA_DIGEST_LENGTH,true); | 100 | a = alloc_assoc(ats,SHA_DIGEST_LENGTH,true); |
104 | else if(ats=="HMAC-SHA256") | 101 | else if(ats=="HMAC-SHA256") |
105 | assoc = alloc_assoc(ats,SHA256_DIGEST_LENGTH,true); | 102 | a = alloc_assoc(ats,SHA256_DIGEST_LENGTH,true); |
106 | else | 103 | else |
107 | throw unsupported(OPKELE_CP_ "Unsupported assoc_type"); | 104 | throw unsupported(OPKELE_CP_ "Unsupported assoc_type"); |
108 | oum.reset_fields(); | 105 | oum.reset_fields(); |
109 | oum.set_field("ns",OIURI_OPENID20); | 106 | oum.set_field("ns",OIURI_OPENID20); |
110 | oum.set_field("assoc_type",assoc->assoc_type()); | 107 | oum.set_field("assoc_type",a->assoc_type()); |
111 | oum.set_field("assoc_handle",assoc->handle()); | 108 | oum.set_field("assoc_handle",a->handle()); |
112 | oum.set_field("expires_in",util::long_to_string(assoc->expires_in())); | 109 | oum.set_field("expires_in",util::long_to_string(assoc->expires_in())); |
113 | secret_t secret = assoc->secret(); | 110 | secret_t secret = a->secret(); |
114 | if(sts=="DH-SHA1" || sts=="DH-SHA256") { | 111 | if(sts=="DH-SHA1" || sts=="DH-SHA256") { |
115 | if(d_len != secret.size()) | 112 | if(d_len != secret.size()) |
116 | throw bad_input(OPKELE_CP_ "Association secret and session MAC are not of the same size"); | 113 | throw bad_input(OPKELE_CP_ "Association secret and session MAC are not of the same size"); |
117 | oum.set_field("session_type",sts); | 114 | oum.set_field("session_type",sts); |
118 | oum.set_field("dh_server_public",util::bignum_to_base64(dh->pub_key)); | 115 | oum.set_field("dh_server_public",util::bignum_to_base64(dh->pub_key)); |
119 | string b64; secret.enxor_to_base64(key_digest,b64); | 116 | string b64; secret.enxor_to_base64(key_digest,b64); |
120 | oum.set_field("enc_mac_key",b64); | 117 | oum.set_field("enc_mac_key",b64); |
121 | }else /* TODO: support cleartext over encrypted connection */ | 118 | }else /* TODO: support cleartext over encrypted connection */ |
122 | throw unsupported(OPKELE_CP_ "Unsupported session type"); | 119 | throw unsupported(OPKELE_CP_ "Unsupported session type"); |
123 | return oum; | 120 | return oum; |
124 | } catch(unsupported& u) { | 121 | } catch(unsupported& u) { |
125 | oum.reset_fields(); | 122 | oum.reset_fields(); |
126 | oum.set_field("ns",OIURI_OPENID20); | 123 | oum.set_field("ns",OIURI_OPENID20); |
127 | oum.set_field("error",u.what()); | 124 | oum.set_field("error",u.what()); |
128 | oum.set_field("error_code","unsupported-type"); | 125 | oum.set_field("error_code","unsupported-type"); |
129 | oum.set_field("session_type","DH-SHA256"); | 126 | oum.set_field("session_type","DH-SHA256"); |
130 | oum.set_field("assoc_type","HMAC-SHA256"); | 127 | oum.set_field("assoc_type","HMAC-SHA256"); |
131 | return oum; | 128 | return oum; |
132 | } | 129 | } |
133 | 130 | ||
134 | void basic_OP::checkid_(const basic_openid_message& inm, | 131 | void basic_OP::checkid_(const basic_openid_message& inm, |
135 | extension_t *ext) { | 132 | extension_t *ext) { |
136 | reset_vars(); | 133 | reset_vars(); |
137 | string mode = inm.get_field("mode"); | 134 | string modestr = inm.get_field("mode"); |
138 | if(mode=="checkid_setup") | 135 | if(modestr=="checkid_setup") |
139 | mode = mode_checkid_setup; | 136 | mode = mode_checkid_setup; |
140 | else if(mode=="checkid_immediate") | 137 | else if(modestr=="checkid_immediate") |
141 | mode = mode_checkid_immediate; | 138 | mode = mode_checkid_immediate; |
142 | else | 139 | else |
143 | throw bad_input(OPKELE_CP_ "Invalid checkid_* mode"); | 140 | throw bad_input(OPKELE_CP_ "Invalid checkid_* mode"); |
144 | try { | 141 | try { |
145 | assoc = retrieve_assoc(invalidate_handle=inm.get_field("assoc_handle")); | 142 | assoc = retrieve_assoc(invalidate_handle=inm.get_field("assoc_handle")); |
146 | invalidate_handle.clear(); | 143 | invalidate_handle.clear(); |
147 | }catch(failed_lookup&) { } | 144 | }catch(failed_lookup&) { } |
148 | try { | 145 | try { |
149 | openid2 = (inm.get_field("ns")==OIURI_OPENID20); | 146 | openid2 = (inm.get_field("ns")==OIURI_OPENID20); |
150 | }catch(failed_lookup&) { openid2 = false; } | 147 | }catch(failed_lookup&) { openid2 = false; } |
151 | try { | 148 | try { |
152 | return_to = inm.get_field("return_to"); | 149 | return_to = inm.get_field("return_to"); |
153 | }catch(failed_lookup&) { } | 150 | }catch(failed_lookup&) { } |
154 | if(openid2) { | 151 | if(openid2) { |
155 | try { | 152 | try { |
156 | realm = inm.get_field("realm"); | 153 | realm = inm.get_field("realm"); |
157 | }catch(failed_lookup&) { | 154 | }catch(failed_lookup&) { |
158 | try { | 155 | try { |
159 | realm = inm.get_field("trust_root"); | 156 | realm = inm.get_field("trust_root"); |
160 | }catch(failed_lookup&) { | 157 | }catch(failed_lookup&) { |
161 | if(return_to.empty()) | 158 | if(return_to.empty()) |
162 | throw bad_input(OPKELE_CP_ | 159 | throw bad_input(OPKELE_CP_ |
163 | "Both realm and return_to are unset"); | 160 | "Both realm and return_to are unset"); |
164 | realm = return_to; | 161 | realm = return_to; |
165 | } | 162 | } |
166 | } | 163 | } |
167 | }else{ | 164 | }else{ |
168 | try { | 165 | try { |
169 | realm = inm.get_field("trust_root"); | 166 | realm = inm.get_field("trust_root"); |
170 | }catch(failed_lookup&) { | 167 | }catch(failed_lookup&) { |
171 | if(return_to.empty()) | 168 | if(return_to.empty()) |
172 | throw bad_input(OPKELE_CP_ | 169 | throw bad_input(OPKELE_CP_ |
@@ -209,72 +206,72 @@ namespace opkele { | |||
209 | om.set_field("ns",OIURI_OPENID20); | 206 | om.set_field("ns",OIURI_OPENID20); |
210 | om.set_field("mode","id_res"); | 207 | om.set_field("mode","id_res"); |
211 | om.set_field("op_endpoint",get_op_endpoint()); | 208 | om.set_field("op_endpoint",get_op_endpoint()); |
212 | string ats = "ns,mode,op_endpoint,return_to,response_nonce," | 209 | string ats = "ns,mode,op_endpoint,return_to,response_nonce," |
213 | "assoc_handle,signed"; | 210 | "assoc_handle,signed"; |
214 | if(!identity.empty()) { | 211 | if(!identity.empty()) { |
215 | om.set_field("identity",identity); | 212 | om.set_field("identity",identity); |
216 | om.set_field("claimed_id",claimed_id); | 213 | om.set_field("claimed_id",claimed_id); |
217 | ats += ",identity,claimed_id"; | 214 | ats += ",identity,claimed_id"; |
218 | } | 215 | } |
219 | om.set_field("return_to",return_to); | 216 | om.set_field("return_to",return_to); |
220 | string nonce = w3timestr; | 217 | string nonce = w3timestr; |
221 | om.set_field("response_nonce",alloc_nonce(nonce)); | 218 | om.set_field("response_nonce",alloc_nonce(nonce)); |
222 | if(!invalidate_handle.empty()) { | 219 | if(!invalidate_handle.empty()) { |
223 | om.set_field("invalidate_handle",invalidate_handle); | 220 | om.set_field("invalidate_handle",invalidate_handle); |
224 | ats += ",invalidate_handle"; | 221 | ats += ",invalidate_handle"; |
225 | } | 222 | } |
226 | om.set_field("assoc_handle",assoc->handle()); | 223 | om.set_field("assoc_handle",assoc->handle()); |
227 | om.add_to_signed(ats); | 224 | om.add_to_signed(ats); |
228 | if(ext) ext->op_id_res_hook(om); | 225 | if(ext) ext->op_id_res_hook(om); |
229 | om.set_field("sig",util::base64_signature(assoc,om)); | 226 | om.set_field("sig",util::base64_signature(assoc,om)); |
230 | return om; | 227 | return om; |
231 | } | 228 | } |
232 | 229 | ||
233 | basic_openid_message& basic_OP::cancel(basic_openid_message& om) { | 230 | basic_openid_message& basic_OP::cancel(basic_openid_message& om) { |
234 | assert(!return_to.empty()); | 231 | assert(!return_to.empty()); |
235 | om.set_field("ns",OIURI_OPENID20); | 232 | om.set_field("ns",OIURI_OPENID20); |
236 | om.set_field("mode","cancel"); | 233 | om.set_field("mode","cancel"); |
237 | return om; | 234 | return om; |
238 | } | 235 | } |
239 | 236 | ||
240 | basic_openid_message& basic_OP::error(basic_openid_message& om, | 237 | basic_openid_message& basic_OP::error(basic_openid_message& om, |
241 | const string& error,const string& contact, | 238 | const string& err,const string& contact, |
242 | const string& reference ) { | 239 | const string& reference ) { |
243 | assert(!return_to.empty()); | 240 | assert(!return_to.empty()); |
244 | om.set_field("ns",OIURI_OPENID20); | 241 | om.set_field("ns",OIURI_OPENID20); |
245 | om.set_field("mode","error"); | 242 | om.set_field("mode","error"); |
246 | om.set_field("error",error); | 243 | om.set_field("error",err); |
247 | om.set_field("contact",contact); | 244 | if(!contact.empty()) om.set_field("contact",contact); |
248 | om.set_field("reference",reference); | 245 | if(!reference.empty()) om.set_field("reference",reference); |
249 | return om; | 246 | return om; |
250 | } | 247 | } |
251 | 248 | ||
252 | basic_openid_message& basic_OP::setup_needed( | 249 | basic_openid_message& basic_OP::setup_needed( |
253 | basic_openid_message& oum,const basic_openid_message& inm) { | 250 | basic_openid_message& oum,const basic_openid_message& inm) { |
254 | assert(mode==mode_checkid_immediate); | 251 | assert(mode==mode_checkid_immediate); |
255 | assert(!return_to.empty()); | 252 | assert(!return_to.empty()); |
256 | if(openid2) { | 253 | if(openid2) { |
257 | oum.set_field("ns",OIURI_OPENID20); | 254 | oum.set_field("ns",OIURI_OPENID20); |
258 | oum.set_field("mode","setup_needed"); | 255 | oum.set_field("mode","setup_needed"); |
259 | }else{ | 256 | }else{ |
260 | oum.set_field("mode","id_res"); | 257 | oum.set_field("mode","id_res"); |
261 | static const string setupmode = "checkid_setup"; | 258 | static const string setupmode = "checkid_setup"; |
262 | oum.set_field("user_setup_url", | 259 | oum.set_field("user_setup_url", |
263 | util::change_mode_message_proxy(inm,setupmode) | 260 | util::change_mode_message_proxy(inm,setupmode) |
264 | .append_query(get_op_endpoint())); | 261 | .append_query(get_op_endpoint())); |
265 | } | 262 | } |
266 | return oum; | 263 | return oum; |
267 | } | 264 | } |
268 | 265 | ||
269 | basic_openid_message& basic_OP::check_authentication( | 266 | basic_openid_message& basic_OP::check_authentication( |
270 | basic_openid_message& oum, | 267 | basic_openid_message& oum, |
271 | const basic_openid_message& inm) try { | 268 | const basic_openid_message& inm) try { |
272 | assert(inm.get_field("mode")=="check_authentication"); | 269 | assert(inm.get_field("mode")=="check_authentication"); |
273 | oum.reset_fields(); | 270 | oum.reset_fields(); |
274 | oum.set_field("ns",OIURI_OPENID20); | 271 | oum.set_field("ns",OIURI_OPENID20); |
275 | bool o2; | 272 | bool o2; |
276 | try { | 273 | try { |
277 | o2 = (inm.get_field("ns")==OIURI_OPENID20); | 274 | o2 = (inm.get_field("ns")==OIURI_OPENID20); |
278 | }catch(failed_lookup&) { o2 = false; } | 275 | }catch(failed_lookup&) { o2 = false; } |
279 | string nonce; | 276 | string nonce; |
280 | if(o2) { | 277 | if(o2) { |
diff --git a/lib/basic_rp.cc b/lib/basic_rp.cc index bd45d99..a0ad130 100644 --- a/lib/basic_rp.cc +++ b/lib/basic_rp.cc | |||
@@ -1,122 +1,124 @@ | |||
1 | #include <cassert> | ||
1 | #include <openssl/sha.h> | 2 | #include <openssl/sha.h> |
2 | #include <openssl/hmac.h> | 3 | #include <openssl/hmac.h> |
3 | #include <opkele/basic_rp.h> | 4 | #include <opkele/basic_rp.h> |
4 | #include <opkele/exception.h> | 5 | #include <opkele/exception.h> |
5 | #include <opkele/uris.h> | 6 | #include <opkele/uris.h> |
6 | #include <opkele/data.h> | 7 | #include <opkele/data.h> |
7 | #include <opkele/util.h> | 8 | #include <opkele/util.h> |
8 | #include <opkele/curl.h> | 9 | #include <opkele/curl.h> |
9 | 10 | ||
10 | namespace opkele { | 11 | namespace opkele { |
11 | 12 | ||
12 | static void dh_get_secret( | 13 | static void dh_get_secret( |
13 | secret_t& secret, const basic_openid_message& om, | 14 | secret_t& secret, const basic_openid_message& om, |
14 | const char *exp_assoc, const char *exp_sess, | 15 | const char *exp_assoc, const char *exp_sess, |
15 | util::dh_t& dh, | 16 | util::dh_t& dh, |
16 | size_t d_len, unsigned char *(*d_fun)(const unsigned char*,size_t,unsigned char*), | 17 | size_t d_len, unsigned char *(*d_fun)(const unsigned char*,size_t,unsigned char*), |
17 | size_t exp_s_len) try { | 18 | size_t exp_s_len) try { |
18 | if(om.get_field("assoc_type")!=exp_assoc || om.get_field("session_type")!=exp_sess) | 19 | if(om.get_field("assoc_type")!=exp_assoc || om.get_field("session_type")!=exp_sess) |
19 | throw bad_input(OPKELE_CP_ "Unexpected associate response"); | 20 | throw bad_input(OPKELE_CP_ "Unexpected associate response"); |
20 | util::bignum_t s_pub = util::base64_to_bignum(om.get_field("dh_server_public")); | 21 | util::bignum_t s_pub = util::base64_to_bignum(om.get_field("dh_server_public")); |
21 | vector<unsigned char> ck(DH_size(dh)+1); | 22 | vector<unsigned char> ck(DH_size(dh)+1); |
22 | unsigned char *ckptr = &(ck.front())+1; | 23 | unsigned char *ckptr = &(ck.front())+1; |
23 | int cklen = DH_compute_key(ckptr,s_pub,dh); | 24 | int cklen = DH_compute_key(ckptr,s_pub,dh); |
24 | if(cklen<0) | 25 | if(cklen<0) |
25 | throw exception_openssl(OPKELE_CP_ "failed to DH_compute_key()"); | 26 | throw exception_openssl(OPKELE_CP_ "failed to DH_compute_key()"); |
26 | if(cklen && (*ckptr)&0x80) { | 27 | if(cklen && (*ckptr)&0x80) { |
27 | (*(--ckptr))=0; ++cklen; } | 28 | (*(--ckptr))=0; ++cklen; } |
28 | unsigned char key_digest[d_len]; | 29 | assert(d_len<=SHA256_DIGEST_LENGTH); |
30 | unsigned char key_digest[SHA256_DIGEST_LENGTH]; | ||
29 | secret.enxor_from_base64((*d_fun)(ckptr,cklen,key_digest),om.get_field("enc_mac_key")); | 31 | secret.enxor_from_base64((*d_fun)(ckptr,cklen,key_digest),om.get_field("enc_mac_key")); |
30 | if(secret.size()!=exp_s_len) | 32 | if(secret.size()!=exp_s_len) |
31 | throw bad_input(OPKELE_CP_ "Secret length isn't consistent with association type"); | 33 | throw bad_input(OPKELE_CP_ "Secret length isn't consistent with association type"); |
32 | }catch(opkele::failed_lookup& ofl) { | 34 | }catch(opkele::failed_lookup& ofl) { |
33 | throw bad_input(OPKELE_CP_ "Incoherent response from OP"); | 35 | throw bad_input(OPKELE_CP_ "Incoherent response from OP"); |
34 | } OPKELE_RETHROW | 36 | } OPKELE_RETHROW |
35 | 37 | ||
36 | static void direct_request(basic_openid_message& oum,const basic_openid_message& inm,const string& OP) { | 38 | static void direct_request(basic_openid_message& oum,const basic_openid_message& inm,const string& OP) { |
37 | util::curl_pick_t curl = util::curl_pick_t::easy_init(); | 39 | util::curl_pick_t curl = util::curl_pick_t::easy_init(); |
38 | if(!curl) | 40 | if(!curl) |
39 | throw exception_curl(OPKELE_CP_ "failed to initialize curl"); | 41 | throw exception_curl(OPKELE_CP_ "failed to initialize curl"); |
40 | string request = inm.query_string(); | 42 | string request = inm.query_string(); |
41 | CURLcode r; | 43 | CURLcode r; |
42 | (r=curl.misc_sets()) | 44 | (r=curl.misc_sets()) |
43 | || (r=curl.easy_setopt(CURLOPT_URL,OP.c_str())) | 45 | || (r=curl.easy_setopt(CURLOPT_URL,OP.c_str())) |
44 | || (r=curl.easy_setopt(CURLOPT_POST,1)) | 46 | || (r=curl.easy_setopt(CURLOPT_POST,1)) |
45 | || (r=curl.easy_setopt(CURLOPT_POSTFIELDS,request.data())) | 47 | || (r=curl.easy_setopt(CURLOPT_POSTFIELDS,request.data())) |
46 | || (r=curl.easy_setopt(CURLOPT_POSTFIELDSIZE,request.length())) | 48 | || (r=curl.easy_setopt(CURLOPT_POSTFIELDSIZE,request.length())) |
47 | || (r=curl.set_write()); | 49 | || (r=curl.set_write()); |
48 | if(r) | 50 | if(r) |
49 | throw exception_curl(OPKELE_CP_ "failed to set curly options",r); | 51 | throw exception_curl(OPKELE_CP_ "failed to set curly options",r); |
50 | if( (r=curl.easy_perform()) ) | 52 | if( (r=curl.easy_perform()) ) |
51 | throw exception_curl(OPKELE_CP_ "failed to perform curly request",r); | 53 | throw exception_curl(OPKELE_CP_ "failed to perform curly request",r); |
52 | oum.from_keyvalues(curl.response); | 54 | oum.from_keyvalues(curl.response); |
53 | } | 55 | } |
54 | 56 | ||
55 | 57 | ||
56 | assoc_t basic_RP::associate(const string& OP) { | 58 | assoc_t basic_RP::associate(const string& OP) { |
57 | util::dh_t dh = DH_new(); | 59 | util::dh_t dh = DH_new(); |
58 | if(!dh) | 60 | if(!dh) |
59 | throw exception_openssl(OPKELE_CP_ "failed to DH_new()"); | 61 | throw exception_openssl(OPKELE_CP_ "failed to DH_new()"); |
60 | dh->p = util::dec_to_bignum(data::_default_p); | 62 | dh->p = util::dec_to_bignum(data::_default_p); |
61 | dh->g = util::dec_to_bignum(data::_default_g); | 63 | dh->g = util::dec_to_bignum(data::_default_g); |
62 | if(!DH_generate_key(dh)) | 64 | if(!DH_generate_key(dh)) |
63 | throw exception_openssl(OPKELE_CP_ "failed to DH_generate_key()"); | 65 | throw exception_openssl(OPKELE_CP_ "failed to DH_generate_key()"); |
64 | openid_message_t req; | 66 | openid_message_t req; |
65 | req.set_field("ns",OIURI_OPENID20); | 67 | req.set_field("ns",OIURI_OPENID20); |
66 | req.set_field("mode","associate"); | 68 | req.set_field("mode","associate"); |
67 | req.set_field("dh_modulus",util::bignum_to_base64(dh->p)); | 69 | req.set_field("dh_modulus",util::bignum_to_base64(dh->p)); |
68 | req.set_field("dh_gen",util::bignum_to_base64(dh->g)); | 70 | req.set_field("dh_gen",util::bignum_to_base64(dh->g)); |
69 | req.set_field("dh_consumer_public",util::bignum_to_base64(dh->pub_key)); | 71 | req.set_field("dh_consumer_public",util::bignum_to_base64(dh->pub_key)); |
70 | openid_message_t res; | 72 | openid_message_t res; |
71 | req.set_field("assoc_type","HMAC-SHA256"); | 73 | req.set_field("assoc_type","HMAC-SHA256"); |
72 | req.set_field("session_type","DH-SHA256"); | 74 | req.set_field("session_type","DH-SHA256"); |
73 | secret_t secret; | 75 | secret_t secret; |
74 | int expires_in; | 76 | int expires_in; |
75 | try { | 77 | try { |
76 | direct_request(res,req,OP); | 78 | direct_request(res,req,OP); |
77 | dh_get_secret( secret, res, | 79 | dh_get_secret( secret, res, |
78 | "HMAC-SHA256", "DH-SHA256", | 80 | "HMAC-SHA256", "DH-SHA256", |
79 | dh, SHA256_DIGEST_LENGTH, SHA256, SHA256_DIGEST_LENGTH ); | 81 | dh, SHA256_DIGEST_LENGTH, SHA256, SHA256_DIGEST_LENGTH ); |
80 | expires_in = util::string_to_long(res.get_field("expires_in")); | 82 | expires_in = util::string_to_long(res.get_field("expires_in")); |
81 | }catch(exception& e) { | 83 | }catch(exception&) { |
82 | try { | 84 | try { |
83 | req.set_field("assoc_type","HMAC-SHA1"); | 85 | req.set_field("assoc_type","HMAC-SHA1"); |
84 | req.set_field("session_type","DH-SHA1"); | 86 | req.set_field("session_type","DH-SHA1"); |
85 | direct_request(res,req,OP); | 87 | direct_request(res,req,OP); |
86 | dh_get_secret( secret, res, | 88 | dh_get_secret( secret, res, |
87 | "HMAC-SHA1", "DH-SHA1", | 89 | "HMAC-SHA1", "DH-SHA1", |
88 | dh, SHA_DIGEST_LENGTH, SHA1, SHA_DIGEST_LENGTH ); | 90 | dh, SHA_DIGEST_LENGTH, SHA1, SHA_DIGEST_LENGTH ); |
89 | expires_in = util::string_to_long(res.get_field("expires_in")); | 91 | expires_in = util::string_to_long(res.get_field("expires_in")); |
90 | }catch(bad_input& e) { | 92 | }catch(bad_input&) { |
91 | throw dumb_RP(OPKELE_CP_ "OP failed to supply an association"); | 93 | throw dumb_RP(OPKELE_CP_ "OP failed to supply an association"); |
92 | } | 94 | } |
93 | } | 95 | } |
94 | return store_assoc( | 96 | return store_assoc( |
95 | OP, res.get_field("assoc_handle"), | 97 | OP, res.get_field("assoc_handle"), |
96 | res.get_field("assoc_type"), secret, | 98 | res.get_field("assoc_type"), secret, |
97 | expires_in ); | 99 | expires_in ); |
98 | } | 100 | } |
99 | 101 | ||
100 | basic_openid_message& basic_RP::checkid_( | 102 | basic_openid_message& basic_RP::checkid_( |
101 | basic_openid_message& rv, | 103 | basic_openid_message& rv, |
102 | mode_t mode, | 104 | mode_t mode, |
103 | const string& return_to,const string& realm, | 105 | const string& return_to,const string& realm, |
104 | extension_t *ext) { | 106 | extension_t *ext) { |
105 | rv.reset_fields(); | 107 | rv.reset_fields(); |
106 | rv.set_field("ns",OIURI_OPENID20); | 108 | rv.set_field("ns",OIURI_OPENID20); |
107 | if(mode==mode_checkid_immediate) | 109 | if(mode==mode_checkid_immediate) |
108 | rv.set_field("mode","checkid_immediate"); | 110 | rv.set_field("mode","checkid_immediate"); |
109 | else if(mode==mode_checkid_setup) | 111 | else if(mode==mode_checkid_setup) |
110 | rv.set_field("mode","checkid_setup"); | 112 | rv.set_field("mode","checkid_setup"); |
111 | else | 113 | else |
112 | throw bad_input(OPKELE_CP_ "unknown checkid_* mode"); | 114 | throw bad_input(OPKELE_CP_ "unknown checkid_* mode"); |
113 | if(realm.empty() && return_to.empty()) | 115 | if(realm.empty() && return_to.empty()) |
114 | throw bad_input(OPKELE_CP_ "At least one of realm and return_to must be non-empty"); | 116 | throw bad_input(OPKELE_CP_ "At least one of realm and return_to must be non-empty"); |
115 | if(!realm.empty()) { | 117 | if(!realm.empty()) { |
116 | rv.set_field("realm",realm); | 118 | rv.set_field("realm",realm); |
117 | rv.set_field("trust_root",realm); | 119 | rv.set_field("trust_root",realm); |
118 | } | 120 | } |
119 | if(!return_to.empty()) | 121 | if(!return_to.empty()) |
120 | rv.set_field("return_to",return_to); | 122 | rv.set_field("return_to",return_to); |
121 | const openid_endpoint_t& ep = get_endpoint(); | 123 | const openid_endpoint_t& ep = get_endpoint(); |
122 | rv.set_field("claimed_id",ep.claimed_id); | 124 | rv.set_field("claimed_id",ep.claimed_id); |
@@ -205,65 +207,65 @@ namespace opkele { | |||
205 | throw id_res_cancel(OPKELE_CP_ "authentication cancelled"); | 207 | throw id_res_cancel(OPKELE_CP_ "authentication cancelled"); |
206 | bool go_dumb=false; | 208 | bool go_dumb=false; |
207 | try { | 209 | try { |
208 | string OP = o2 | 210 | string OP = o2 |
209 | ?om.get_field("op_endpoint") | 211 | ?om.get_field("op_endpoint") |
210 | :get_endpoint().uri; | 212 | :get_endpoint().uri; |
211 | assoc_t assoc = retrieve_assoc( | 213 | assoc_t assoc = retrieve_assoc( |
212 | OP,om.get_field("assoc_handle")); | 214 | OP,om.get_field("assoc_handle")); |
213 | if(om.get_field("sig")!=util::base64_signature(assoc,om)) | 215 | if(om.get_field("sig")!=util::base64_signature(assoc,om)) |
214 | throw id_res_mismatch(OPKELE_CP_ "signature mismatch"); | 216 | throw id_res_mismatch(OPKELE_CP_ "signature mismatch"); |
215 | }catch(dumb_RP& drp) { | 217 | }catch(dumb_RP& drp) { |
216 | go_dumb=true; | 218 | go_dumb=true; |
217 | }catch(failed_lookup& e) { | 219 | }catch(failed_lookup& e) { |
218 | go_dumb=true; | 220 | go_dumb=true; |
219 | } OPKELE_RETHROW | 221 | } OPKELE_RETHROW |
220 | if(go_dumb) { | 222 | if(go_dumb) { |
221 | try { | 223 | try { |
222 | string OP = o2 | 224 | string OP = o2 |
223 | ?om.get_field("op_endpoint") | 225 | ?om.get_field("op_endpoint") |
224 | :get_endpoint().uri; | 226 | :get_endpoint().uri; |
225 | check_authentication(OP,om); | 227 | check_authentication(OP,om); |
226 | }catch(failed_check_authentication& fca) { | 228 | }catch(failed_check_authentication& fca) { |
227 | throw id_res_failed(OPKELE_CP_ "failed to check_authentication()"); | 229 | throw id_res_failed(OPKELE_CP_ "failed to check_authentication()"); |
228 | } OPKELE_RETHROW | 230 | } OPKELE_RETHROW |
229 | } | 231 | } |
230 | signed_part_message_proxy signeds(om); | 232 | signed_part_message_proxy signeds(om); |
231 | if(o2) { | 233 | if(o2) { |
232 | check_nonce(om.get_field("op_endpoint"), | 234 | check_nonce(om.get_field("op_endpoint"), |
233 | om.get_field("response_nonce")); | 235 | om.get_field("response_nonce")); |
234 | static const char *mustsign[] = { | 236 | static const char *mustsign[] = { |
235 | "op_endpoint", "return_to", "response_nonce", "assoc_handle", | 237 | "op_endpoint", "return_to", "response_nonce", "assoc_handle", |
236 | "claimed_id", "identity" }; | 238 | "claimed_id", "identity" }; |
237 | for(int ms=0;ms<(sizeof(mustsign)/sizeof(*mustsign));++ms) { | 239 | for(size_t ms=0;ms<(sizeof(mustsign)/sizeof(*mustsign));++ms) { |
238 | if(om.has_field(mustsign[ms]) && !signeds.has_field(mustsign[ms])) | 240 | if(om.has_field(mustsign[ms]) && !signeds.has_field(mustsign[ms])) |
239 | throw bad_input(OPKELE_CP_ string("Field '")+mustsign[ms]+"' is not signed against the specs"); | 241 | throw bad_input(OPKELE_CP_ string("Field '")+mustsign[ms]+"' is not signed against the specs"); |
240 | } | 242 | } |
241 | if( ( | 243 | if( ( |
242 | (om.has_field("claimed_id")?1:0) | 244 | (om.has_field("claimed_id")?1:0) |
243 | ^ | 245 | ^ |
244 | (om.has_field("identity")?1:0) | 246 | (om.has_field("identity")?1:0) |
245 | )&1 ) | 247 | )&1 ) |
246 | throw bad_input(OPKELE_CP_ "claimed_id and identity must be either both present or both absent"); | 248 | throw bad_input(OPKELE_CP_ "claimed_id and identity must be either both present or both absent"); |
247 | 249 | ||
248 | string turl = util::rfc_3986_normalize_uri(get_this_url()); | 250 | string turl = util::rfc_3986_normalize_uri(get_this_url()); |
249 | util::strip_uri_fragment_part(turl); | 251 | util::strip_uri_fragment_part(turl); |
250 | string rurl = util::rfc_3986_normalize_uri(om.get_field("return_to")); | 252 | string rurl = util::rfc_3986_normalize_uri(om.get_field("return_to")); |
251 | util::strip_uri_fragment_part(rurl); | 253 | util::strip_uri_fragment_part(rurl); |
252 | string::size_type | 254 | string::size_type |
253 | tq = turl.find('?'), rq = rurl.find('?'); | 255 | tq = turl.find('?'), rq = rurl.find('?'); |
254 | if( | 256 | if( |
255 | ((tq==string::npos)?turl:turl.substr(0,tq)) | 257 | ((tq==string::npos)?turl:turl.substr(0,tq)) |
256 | != | 258 | != |
257 | ((rq==string::npos)?rurl:rurl.substr(0,rq)) | 259 | ((rq==string::npos)?rurl:rurl.substr(0,rq)) |
258 | ) | 260 | ) |
259 | throw id_res_bad_return_to(OPKELE_CP_ "return_to url doesn't match request url"); | 261 | throw id_res_bad_return_to(OPKELE_CP_ "return_to url doesn't match request url"); |
260 | map<string,string> tp; parse_query(turl,tq,tp); | 262 | map<string,string> tp; parse_query(turl,tq,tp); |
261 | map<string,string> rp; parse_query(rurl,rq,rp); | 263 | map<string,string> rp; parse_query(rurl,rq,rp); |
262 | for(map<string,string>::const_iterator rpi=rp.begin();rpi!=rp.end();++rpi) { | 264 | for(map<string,string>::const_iterator rpi=rp.begin();rpi!=rp.end();++rpi) { |
263 | map<string,string>::const_iterator tpi = tp.find(rpi->first); | 265 | map<string,string>::const_iterator tpi = tp.find(rpi->first); |
264 | if(tpi==tp.end()) | 266 | if(tpi==tp.end()) |
265 | throw id_res_bad_return_to(OPKELE_CP_ string("Parameter '")+rpi->first+"' from return_to is missing from the request"); | 267 | throw id_res_bad_return_to(OPKELE_CP_ string("Parameter '")+rpi->first+"' from return_to is missing from the request"); |
266 | if(tpi->second!=rpi->second) | 268 | if(tpi->second!=rpi->second) |
267 | throw id_res_bad_return_to(OPKELE_CP_ string("Parameter '")+rpi->first+"' from return_to doesn't matche the request"); | 269 | throw id_res_bad_return_to(OPKELE_CP_ string("Parameter '")+rpi->first+"' from return_to doesn't matche the request"); |
268 | } | 270 | } |
269 | 271 | ||
diff --git a/lib/discovery.cc b/lib/discovery.cc index 6f58339..6f9926c 100644 --- a/lib/discovery.cc +++ b/lib/discovery.cc | |||
@@ -301,65 +301,65 @@ namespace opkele { | |||
301 | size_t write(void *p,size_t s,size_t nm) { | 301 | size_t write(void *p,size_t s,size_t nm) { |
302 | /* TODO: limit total size */ | 302 | /* TODO: limit total size */ |
303 | size_t bytes = s*nm; | 303 | size_t bytes = s*nm; |
304 | const char *inbuf = (const char*)p; | 304 | const char *inbuf = (const char*)p; |
305 | if(xmode&xmode_html) { | 305 | if(xmode&xmode_html) { |
306 | size_t mbts = save_html.capacity()-save_html.size(); | 306 | size_t mbts = save_html.capacity()-save_html.size(); |
307 | size_t bts = 0; | 307 | size_t bts = 0; |
308 | if(mbts>0) { | 308 | if(mbts>0) { |
309 | bts = (bytes>mbts)?mbts:bytes; | 309 | bts = (bytes>mbts)?mbts:bytes; |
310 | save_html.append(inbuf,bts); | 310 | save_html.append(inbuf,bts); |
311 | } | 311 | } |
312 | if(skipping<0) return bts; | 312 | if(skipping<0) return bts; |
313 | } | 313 | } |
314 | if(skipping<0) return 0; | 314 | if(skipping<0) return 0; |
315 | bool rp = parse(inbuf,bytes,false); | 315 | bool rp = parse(inbuf,bytes,false); |
316 | if(!rp) { | 316 | if(!rp) { |
317 | parser_choked = true; | 317 | parser_choked = true; |
318 | skipping = -1; | 318 | skipping = -1; |
319 | if(!(xmode&xmode_html)) | 319 | if(!(xmode&xmode_html)) |
320 | bytes = 0; | 320 | bytes = 0; |
321 | } | 321 | } |
322 | return bytes; | 322 | return bytes; |
323 | } | 323 | } |
324 | size_t header(void *p,size_t s,size_t nm) { | 324 | size_t header(void *p,size_t s,size_t nm) { |
325 | size_t bytes = s*nm; | 325 | size_t bytes = s*nm; |
326 | const char *h = (const char*)p; | 326 | const char *h = (const char*)p; |
327 | const char *colon = (const char*)memchr(p,':',bytes); | 327 | const char *colon = (const char*)memchr(p,':',bytes); |
328 | const char *space = (const char*)memchr(p,' ',bytes); | 328 | const char *space = (const char*)memchr(p,' ',bytes); |
329 | if(space && ( (!colon) || space<colon ) ) { | 329 | if(space && ( (!colon) || space<colon ) ) { |
330 | xrds_location.clear(); http_content_type.clear(); | 330 | xrds_location.clear(); http_content_type.clear(); |
331 | }else if(colon) { | 331 | }else if(colon) { |
332 | const char *hv = ++colon; | 332 | const char *hv = ++colon; |
333 | int hnl = colon-h; | 333 | size_t hnl = colon-h; |
334 | int rb; | 334 | int rb; |
335 | for(rb = bytes-hnl-1;rb>0 && isspace(*hv);++hv,--rb); | 335 | for(rb = bytes-hnl-1;rb>0 && isspace(*hv);++hv,--rb); |
336 | while(rb>0 && isspace(hv[rb-1])) --rb; | 336 | while(rb>0 && isspace(hv[rb-1])) --rb; |
337 | if(rb) { | 337 | if(rb) { |
338 | if( (hnl>=sizeof(XRDS_HEADER)) | 338 | if( (hnl>=sizeof(XRDS_HEADER)) |
339 | && !strncasecmp(h,XRDS_HEADER":", | 339 | && !strncasecmp(h,XRDS_HEADER":", |
340 | sizeof(XRDS_HEADER)) ) { | 340 | sizeof(XRDS_HEADER)) ) { |
341 | xrds_location.assign(hv,rb); | 341 | xrds_location.assign(hv,rb); |
342 | }else if( (hnl>=sizeof(CT_HEADER)) | 342 | }else if( (hnl>=sizeof(CT_HEADER)) |
343 | && !strncasecmp(h,CT_HEADER":", | 343 | && !strncasecmp(h,CT_HEADER":", |
344 | sizeof(CT_HEADER)) ) { | 344 | sizeof(CT_HEADER)) ) { |
345 | const char *sc = (const char*)memchr( | 345 | const char *sc = (const char*)memchr( |
346 | hv,';',rb); | 346 | hv,';',rb); |
347 | http_content_type.assign(hv,sc?(sc-hv):rb); | 347 | http_content_type.assign(hv,sc?(sc-hv):rb); |
348 | } | 348 | } |
349 | } | 349 | } |
350 | } | 350 | } |
351 | return curl_t::header(p,s,nm); | 351 | return curl_t::header(p,s,nm); |
352 | } | 352 | } |
353 | 353 | ||
354 | void start_element(const XML_Char *n,const XML_Char **a) { | 354 | void start_element(const XML_Char *n,const XML_Char **a) { |
355 | if(skipping<0) return; | 355 | if(skipping<0) return; |
356 | if(skipping) { | 356 | if(skipping) { |
357 | if(xmode&xmode_html) | 357 | if(xmode&xmode_html) |
358 | html_start_element(n,a); | 358 | html_start_element(n,a); |
359 | ++skipping; return; | 359 | ++skipping; return; |
360 | } | 360 | } |
361 | if(pt_stack.empty()) { | 361 | if(pt_stack.empty()) { |
362 | if(is_qelement(n,NSURI_XRDS "\tXRDS")) | 362 | if(is_qelement(n,NSURI_XRDS "\tXRDS")) |
363 | return; | 363 | return; |
364 | if(is_qelement(n,NSURI_XRD "\tXRD")) { | 364 | if(is_qelement(n,NSURI_XRD "\tXRD")) { |
365 | assert(xrd); | 365 | assert(xrd); |
diff --git a/lib/expat.cc b/lib/expat.cc index fa6fdde..c4dab7e 100644 --- a/lib/expat.cc +++ b/lib/expat.cc | |||
@@ -1,47 +1,48 @@ | |||
1 | #include <opkele/expat.h> | 1 | #include <opkele/expat.h> |
2 | 2 | ||
3 | namespace opkele { | 3 | namespace opkele { |
4 | 4 | ||
5 | namespace util { | 5 | namespace util { |
6 | 6 | ||
7 | expat_t::~expat_t() throw() { | 7 | expat_t::~expat_t() throw() { |
8 | if(_x) | 8 | if(_x) |
9 | XML_ParserFree(_x); | 9 | XML_ParserFree(_x); |
10 | } | 10 | } |
11 | 11 | ||
12 | expat_t& expat_t::operator=(XML_Parser x) { | 12 | expat_t& expat_t::operator=(XML_Parser x) { |
13 | if(_x) | 13 | if(_x) |
14 | XML_ParserFree(_x); | 14 | XML_ParserFree(_x); |
15 | _x = x; | 15 | _x = x; |
16 | return *this; | ||
16 | } | 17 | } |
17 | 18 | ||
18 | static void _start_element(void* ud,const XML_Char *n,const XML_Char **a) { | 19 | static void _start_element(void* ud,const XML_Char *n,const XML_Char **a) { |
19 | ((expat_t*)ud)->start_element(n,a); | 20 | ((expat_t*)ud)->start_element(n,a); |
20 | } | 21 | } |
21 | static void _end_element(void *ud,const XML_Char *n) { | 22 | static void _end_element(void *ud,const XML_Char *n) { |
22 | ((expat_t*)ud)->end_element(n); | 23 | ((expat_t*)ud)->end_element(n); |
23 | } | 24 | } |
24 | 25 | ||
25 | void expat_t::set_element_handler() { | 26 | void expat_t::set_element_handler() { |
26 | assert(_x); | 27 | assert(_x); |
27 | XML_SetElementHandler(_x,_start_element,_end_element); | 28 | XML_SetElementHandler(_x,_start_element,_end_element); |
28 | } | 29 | } |
29 | 30 | ||
30 | static void _character_data(void *ud,const XML_Char *s,int l) { | 31 | static void _character_data(void *ud,const XML_Char *s,int l) { |
31 | ((expat_t*)ud)->character_data(s,l); | 32 | ((expat_t*)ud)->character_data(s,l); |
32 | } | 33 | } |
33 | 34 | ||
34 | void expat_t::set_character_data_handler() { | 35 | void expat_t::set_character_data_handler() { |
35 | assert(_x); | 36 | assert(_x); |
36 | XML_SetCharacterDataHandler(_x,_character_data); | 37 | XML_SetCharacterDataHandler(_x,_character_data); |
37 | } | 38 | } |
38 | 39 | ||
39 | static void _processing_instruction(void *ud,const XML_Char *t,const XML_Char *d) { | 40 | static void _processing_instruction(void *ud,const XML_Char *t,const XML_Char *d) { |
40 | ((expat_t*)ud)->processing_instruction(t,d); | 41 | ((expat_t*)ud)->processing_instruction(t,d); |
41 | } | 42 | } |
42 | 43 | ||
43 | void expat_t::set_processing_instruction_handler() { | 44 | void expat_t::set_processing_instruction_handler() { |
44 | assert(_x); | 45 | assert(_x); |
45 | XML_SetProcessingInstructionHandler(_x,_processing_instruction); | 46 | XML_SetProcessingInstructionHandler(_x,_processing_instruction); |
46 | } | 47 | } |
47 | 48 | ||
diff --git a/lib/extension.cc b/lib/extension.cc index f7aaea5..0f121ca 100644 --- a/lib/extension.cc +++ b/lib/extension.cc | |||
@@ -1,26 +1,26 @@ | |||
1 | #include <opkele/exception.h> | 1 | #include <opkele/exception.h> |
2 | #include <opkele/extension.h> | 2 | #include <opkele/extension.h> |
3 | 3 | ||
4 | namespace opkele { | 4 | namespace opkele { |
5 | 5 | ||
6 | void extension_t::rp_checkid_hook(basic_openid_message&) { | 6 | void extension_t::rp_checkid_hook(basic_openid_message&) { |
7 | throw not_implemented(OPKELE_CP_ "RP checkid_* hook not implemented"); } | 7 | throw not_implemented(OPKELE_CP_ "RP checkid_* hook not implemented"); } |
8 | void extension_t::rp_id_res_hook(const basic_openid_message&, | 8 | void extension_t::rp_id_res_hook(const basic_openid_message&, |
9 | const basic_openid_message&) { | 9 | const basic_openid_message&) { |
10 | throw not_implemented(OPKELE_CP_ "RP id_res hook not implemented"); } | 10 | throw not_implemented(OPKELE_CP_ "RP id_res hook not implemented"); } |
11 | 11 | ||
12 | void extension_t::op_checkid_hook(const basic_openid_message&) { | 12 | void extension_t::op_checkid_hook(const basic_openid_message&) { |
13 | throw not_implemented(OPKELE_CP_ "OP checkid_* hook not implemented"); } | 13 | throw not_implemented(OPKELE_CP_ "OP checkid_* hook not implemented"); } |
14 | void extension_t::op_id_res_hook(basic_openid_message& om) { | 14 | void extension_t::op_id_res_hook(basic_openid_message&) { |
15 | throw not_implemented(OPKELE_CP_ "OP id_res hook not implemented"); } | 15 | throw not_implemented(OPKELE_CP_ "OP id_res hook not implemented"); } |
16 | 16 | ||
17 | 17 | ||
18 | void extension_t::checkid_hook(basic_openid_message&) { | 18 | void extension_t::checkid_hook(basic_openid_message&) { |
19 | throw not_implemented(OPKELE_CP_ "deprecated consumer checkid_* hook not implemented"); } | 19 | throw not_implemented(OPKELE_CP_ "deprecated consumer checkid_* hook not implemented"); } |
20 | void extension_t::id_res_hook(const basic_openid_message&, | 20 | void extension_t::id_res_hook(const basic_openid_message&, |
21 | const basic_openid_message&) { | 21 | const basic_openid_message&) { |
22 | throw not_implemented(OPKELE_CP_ "deprecated consumer id_res hook not implemented"); } | 22 | throw not_implemented(OPKELE_CP_ "deprecated consumer id_res hook not implemented"); } |
23 | 23 | ||
24 | void extension_t::checkid_hook(const basic_openid_message&,basic_openid_message&) { | 24 | void extension_t::checkid_hook(const basic_openid_message&,basic_openid_message&) { |
25 | throw not_implemented(OPKELE_CP_ "deprecated server checkid hook not implemented"); } | 25 | throw not_implemented(OPKELE_CP_ "deprecated server checkid hook not implemented"); } |
26 | } | 26 | } |
diff --git a/lib/openid_message.cc b/lib/openid_message.cc index fdb4b04..521ea85 100644 --- a/lib/openid_message.cc +++ b/lib/openid_message.cc | |||
@@ -1,200 +1,200 @@ | |||
1 | #include <cassert> | 1 | #include <cassert> |
2 | #include <opkele/types.h> | 2 | #include <opkele/types.h> |
3 | #include <opkele/exception.h> | 3 | #include <opkele/exception.h> |
4 | #include <opkele/util.h> | 4 | #include <opkele/util.h> |
5 | #include <opkele/debug.h> | 5 | #include <opkele/debug.h> |
6 | 6 | ||
7 | #include "config.h" | 7 | #include "config.h" |
8 | 8 | ||
9 | namespace opkele { | 9 | namespace opkele { |
10 | using std::input_iterator_tag; | 10 | using std::input_iterator_tag; |
11 | using std::unary_function; | 11 | using std::unary_function; |
12 | 12 | ||
13 | struct __om_copier : public unary_function<const string&,void> { | 13 | struct __om_copier : public unary_function<const string&,void> { |
14 | public: | 14 | public: |
15 | const basic_openid_message& from; | 15 | const basic_openid_message& from; |
16 | basic_openid_message& to; | 16 | basic_openid_message& to; |
17 | 17 | ||
18 | __om_copier(basic_openid_message& to,const basic_openid_message& from) | 18 | __om_copier(basic_openid_message& t,const basic_openid_message& f) |
19 | : from(from), to(to) { | 19 | : from(f), to(t) { |
20 | to.reset_fields(); | 20 | to.reset_fields(); |
21 | } | 21 | } |
22 | 22 | ||
23 | result_type operator()(argument_type f) { | 23 | result_type operator()(argument_type f) { |
24 | to.set_field(f,from.get_field(f)); } | 24 | to.set_field(f,from.get_field(f)); } |
25 | }; | 25 | }; |
26 | 26 | ||
27 | basic_openid_message::basic_openid_message(const basic_openid_message& x) { | 27 | basic_openid_message::basic_openid_message(const basic_openid_message& x) { |
28 | x.copy_to(*this); | 28 | x.copy_to(*this); |
29 | } | 29 | } |
30 | void basic_openid_message::copy_to(basic_openid_message& x) const { | 30 | void basic_openid_message::copy_to(basic_openid_message& x) const { |
31 | for_each(fields_begin(),fields_end(), | 31 | for_each(fields_begin(),fields_end(), |
32 | __om_copier(x,*this) ); | 32 | __om_copier(x,*this) ); |
33 | } | 33 | } |
34 | 34 | ||
35 | struct __om_ns_finder : public unary_function<const string&,bool> { | 35 | struct __om_ns_finder : public unary_function<const string&,bool> { |
36 | public: | 36 | public: |
37 | const basic_openid_message& om; | 37 | const basic_openid_message& om; |
38 | const string& uri; | 38 | const string& uri; |
39 | 39 | ||
40 | __om_ns_finder(const basic_openid_message& om, | 40 | __om_ns_finder(const basic_openid_message& m, |
41 | const string& uri) : om(om), uri(uri) { } | 41 | const string& u) : om(m), uri(u) { } |
42 | 42 | ||
43 | result_type operator()(argument_type f) { | 43 | result_type operator()(argument_type f) { |
44 | return | 44 | return |
45 | (!strncmp(f.c_str(),"ns.",sizeof("ns.")-1)) | 45 | (!strncmp(f.c_str(),"ns.",sizeof("ns.")-1)) |
46 | && om.get_field(f)==uri ; | 46 | && om.get_field(f)==uri ; |
47 | } | 47 | } |
48 | }; | 48 | }; |
49 | 49 | ||
50 | bool basic_openid_message::has_ns(const string& uri) const { | 50 | bool basic_openid_message::has_ns(const string& uri) const { |
51 | fields_iterator ei = fields_end(); | 51 | fields_iterator ei = fields_end(); |
52 | fields_iterator i = find_if(fields_begin(),fields_end(), | 52 | fields_iterator i = find_if(fields_begin(),fields_end(), |
53 | __om_ns_finder(*this,uri)); | 53 | __om_ns_finder(*this,uri)); |
54 | return !(i==ei); | 54 | return !(i==ei); |
55 | } | 55 | } |
56 | string basic_openid_message::get_ns(const string& uri) const { | 56 | string basic_openid_message::get_ns(const string& uri) const { |
57 | fields_iterator ei = fields_end(); | 57 | fields_iterator ei = fields_end(); |
58 | fields_iterator i = find_if(fields_begin(),fields_end(), | 58 | fields_iterator i = find_if(fields_begin(),fields_end(), |
59 | __om_ns_finder(*this,uri)); | 59 | __om_ns_finder(*this,uri)); |
60 | if(i==ei) | 60 | if(i==ei) |
61 | throw failed_lookup(OPKELE_CP_ string("failed to find namespace ")+uri); | 61 | throw failed_lookup(OPKELE_CP_ string("failed to find namespace ")+uri); |
62 | return i->substr(3); | 62 | return i->substr(3); |
63 | } | 63 | } |
64 | 64 | ||
65 | struct __om_query_builder : public unary_function<const string&,void> { | 65 | struct __om_query_builder : public unary_function<const string&,void> { |
66 | public: | 66 | public: |
67 | const basic_openid_message& om; | 67 | const basic_openid_message& om; |
68 | string& rv; | ||
69 | bool first; | 68 | bool first; |
69 | string& rv; | ||
70 | 70 | ||
71 | __om_query_builder(string& rv,const basic_openid_message& om) | 71 | __om_query_builder(string& r,const basic_openid_message& m) |
72 | : om(om), first(true), rv(rv) { | 72 | : om(m), first(true), rv(r) { |
73 | for_each(om.fields_begin(),om.fields_end(),*this); | 73 | for_each(om.fields_begin(),om.fields_end(),*this); |
74 | } | 74 | } |
75 | __om_query_builder(string& rv,const basic_openid_message& om,const string& url) | 75 | __om_query_builder(string& r,const basic_openid_message& m,const string& u) |
76 | : om(om), first(true), rv(rv) { | 76 | : om(m), first(true), rv(r) { |
77 | rv = url; | 77 | rv = u; |
78 | if(rv.find('?')==string::npos) | 78 | if(rv.find('?')==string::npos) |
79 | rv += '?'; | 79 | rv += '?'; |
80 | else | 80 | else |
81 | first = false; | 81 | first = false; |
82 | for_each(om.fields_begin(),om.fields_end(),*this); | 82 | for_each(om.fields_begin(),om.fields_end(),*this); |
83 | } | 83 | } |
84 | 84 | ||
85 | result_type operator()(argument_type f) { | 85 | result_type operator()(argument_type f) { |
86 | if(first) | 86 | if(first) |
87 | first = false; | 87 | first = false; |
88 | else | 88 | else |
89 | rv += '&'; | 89 | rv += '&'; |
90 | rv += "openid."; rv+= f; | 90 | rv += "openid."; rv+= f; |
91 | rv += '='; | 91 | rv += '='; |
92 | rv += util::url_encode(om.get_field(f)); | 92 | rv += util::url_encode(om.get_field(f)); |
93 | } | 93 | } |
94 | }; | 94 | }; |
95 | 95 | ||
96 | string basic_openid_message::append_query(const string& url) const { | 96 | string basic_openid_message::append_query(const string& url) const { |
97 | string rv; | 97 | string rv; |
98 | return __om_query_builder(rv,*this,url).rv; | 98 | return __om_query_builder(rv,*this,url).rv; |
99 | } | 99 | } |
100 | string basic_openid_message::query_string() const { | 100 | string basic_openid_message::query_string() const { |
101 | string rv; | 101 | string rv; |
102 | return __om_query_builder(rv,*this).rv; | 102 | return __om_query_builder(rv,*this).rv; |
103 | } | 103 | } |
104 | 104 | ||
105 | void basic_openid_message::reset_fields() { | 105 | void basic_openid_message::reset_fields() { |
106 | throw not_implemented(OPKELE_CP_ "reset_fields() not implemented"); | 106 | throw not_implemented(OPKELE_CP_ "reset_fields() not implemented"); |
107 | } | 107 | } |
108 | void basic_openid_message::set_field(const string& n,const string& v) { | 108 | void basic_openid_message::set_field(const string&,const string&) { |
109 | throw not_implemented(OPKELE_CP_ "set_field() not implemented"); | 109 | throw not_implemented(OPKELE_CP_ "set_field() not implemented"); |
110 | } | 110 | } |
111 | void basic_openid_message::reset_field(const string& n) { | 111 | void basic_openid_message::reset_field(const string&) { |
112 | throw not_implemented(OPKELE_CP_ "reset_field() not implemented"); | 112 | throw not_implemented(OPKELE_CP_ "reset_field() not implemented"); |
113 | } | 113 | } |
114 | 114 | ||
115 | void basic_openid_message::from_keyvalues(const string& kv) { | 115 | void basic_openid_message::from_keyvalues(const string& kv) { |
116 | reset_fields(); | 116 | reset_fields(); |
117 | string::size_type p = 0; | 117 | string::size_type p = 0; |
118 | while(true) { | 118 | while(true) { |
119 | string::size_type co = kv.find(':',p); | 119 | string::size_type co = kv.find(':',p); |
120 | if(co==string::npos) | 120 | if(co==string::npos) |
121 | break; | 121 | break; |
122 | #ifndef POSTELS_LAW | 122 | #ifndef POSTELS_LAW |
123 | string::size_type nl = kv.find('\n',co+1); | 123 | string::size_type nl = kv.find('\n',co+1); |
124 | if(nl==string::npos) | 124 | if(nl==string::npos) |
125 | throw bad_input(OPKELE_CP_ "malformed input"); | 125 | throw bad_input(OPKELE_CP_ "malformed input"); |
126 | if(nl>co) | 126 | if(nl>co) |
127 | insert(value_type(kv.substr(p,co-p),kv.substr(co+1,nl-co-1))); | 127 | insert(value_type(kv.substr(p,co-p),kv.substr(co+1,nl-co-1))); |
128 | p = nl+1; | 128 | p = nl+1; |
129 | #else /* POSTELS_LAW */ | 129 | #else /* POSTELS_LAW */ |
130 | string::size_type lb = kv.find_first_of("\r\n",co+1); | 130 | string::size_type lb = kv.find_first_of("\r\n",co+1); |
131 | if(lb==string::npos) { | 131 | if(lb==string::npos) { |
132 | set_field(kv.substr(p,co-p),kv.substr(co+1)); | 132 | set_field(kv.substr(p,co-p),kv.substr(co+1)); |
133 | break; | 133 | break; |
134 | } | 134 | } |
135 | if(lb>co) | 135 | if(lb>co) |
136 | set_field(kv.substr(p,co-p),kv.substr(co+1,lb-co-1)); | 136 | set_field(kv.substr(p,co-p),kv.substr(co+1,lb-co-1)); |
137 | string::size_type nolb = kv.find_first_not_of("\r\n",lb); | 137 | string::size_type nolb = kv.find_first_not_of("\r\n",lb); |
138 | if(nolb==string::npos) | 138 | if(nolb==string::npos) |
139 | break; | 139 | break; |
140 | p = nolb; | 140 | p = nolb; |
141 | #endif /* POSTELS_LAW */ | 141 | #endif /* POSTELS_LAW */ |
142 | } | 142 | } |
143 | } | 143 | } |
144 | 144 | ||
145 | struct __om_kv_outputter : public unary_function<const string&,void> { | 145 | struct __om_kv_outputter : public unary_function<const string&,void> { |
146 | public: | 146 | public: |
147 | const basic_openid_message& om; | 147 | const basic_openid_message& om; |
148 | ostream& os; | 148 | ostream& os; |
149 | 149 | ||
150 | __om_kv_outputter(const basic_openid_message& om,ostream& os) | 150 | __om_kv_outputter(const basic_openid_message& m,ostream& s) |
151 | : om(om), os(os) { } | 151 | : om(m), os(s) { } |
152 | 152 | ||
153 | result_type operator()(argument_type f) { | 153 | result_type operator()(argument_type f) { |
154 | os << f << ':' << om.get_field(f) << '\n'; | 154 | os << f << ':' << om.get_field(f) << '\n'; |
155 | } | 155 | } |
156 | }; | 156 | }; |
157 | 157 | ||
158 | void basic_openid_message::to_keyvalues(ostream& o) const { | 158 | void basic_openid_message::to_keyvalues(ostream& o) const { |
159 | for_each(fields_begin(),fields_end(),__om_kv_outputter(*this,o)); | 159 | for_each(fields_begin(),fields_end(),__om_kv_outputter(*this,o)); |
160 | } | 160 | } |
161 | 161 | ||
162 | struct __om_html_outputter : public unary_function<const string&,void> { | 162 | struct __om_html_outputter : public unary_function<const string&,void> { |
163 | public: | 163 | public: |
164 | const basic_openid_message& om; | 164 | const basic_openid_message& om; |
165 | ostream& os; | 165 | ostream& os; |
166 | 166 | ||
167 | __om_html_outputter(const basic_openid_message& om,ostream& os) | 167 | __om_html_outputter(const basic_openid_message& m,ostream& s) |
168 | : om(om), os(os) { } | 168 | : om(m), os(s) { } |
169 | 169 | ||
170 | result_type operator()(argument_type f) { | 170 | result_type operator()(argument_type f) { |
171 | os << | 171 | os << |
172 | "<input type=\"hidden\"" | 172 | "<input type=\"hidden\"" |
173 | " name=\"" << util::attr_escape(f) << "\"" | 173 | " name=\"" << util::attr_escape(f) << "\"" |
174 | " value=\"" << util::attr_escape(om.get_field(f)) << "\" />"; | 174 | " value=\"" << util::attr_escape(om.get_field(f)) << "\" />"; |
175 | } | 175 | } |
176 | }; | 176 | }; |
177 | 177 | ||
178 | void basic_openid_message::to_htmlhiddens(ostream& o) const { | 178 | void basic_openid_message::to_htmlhiddens(ostream& o) const { |
179 | for_each(fields_begin(),fields_end(),__om_html_outputter(*this,o)); | 179 | for_each(fields_begin(),fields_end(),__om_html_outputter(*this,o)); |
180 | } | 180 | } |
181 | 181 | ||
182 | void basic_openid_message::add_to_signed(const string& fields) { | 182 | void basic_openid_message::add_to_signed(const string& fields) { |
183 | string::size_type fnc = fields.find_first_not_of(","); | 183 | string::size_type fnc = fields.find_first_not_of(","); |
184 | if(fnc==string::npos) | 184 | if(fnc==string::npos) |
185 | throw bad_input(OPKELE_CP_ "Trying to add nothing in particular to the list of signed fields"); | 185 | throw bad_input(OPKELE_CP_ "Trying to add nothing in particular to the list of signed fields"); |
186 | string signeds; | 186 | string signeds; |
187 | try { | 187 | try { |
188 | signeds = get_field("signed"); | 188 | signeds = get_field("signed"); |
189 | string::size_type lnc = signeds.find_last_not_of(","); | 189 | string::size_type lnc = signeds.find_last_not_of(","); |
190 | if(lnc==string::npos) | 190 | if(lnc==string::npos) |
191 | signeds.assign(fields,fnc,fields.size()-fnc); | 191 | signeds.assign(fields,fnc,fields.size()-fnc); |
192 | else{ | 192 | else{ |
193 | string::size_type ss = signeds.size(); | 193 | string::size_type ss = signeds.size(); |
194 | if(lnc==(ss-1)) { | 194 | if(lnc==(ss-1)) { |
195 | signeds+= ','; | 195 | signeds+= ','; |
196 | signeds.append(fields,fnc,fields.size()-fnc); | 196 | signeds.append(fields,fnc,fields.size()-fnc); |
197 | }else{ | 197 | }else{ |
198 | if(lnc<(ss-2)) | 198 | if(lnc<(ss-2)) |
199 | signeds.replace(lnc+2,ss-lnc-2, | 199 | signeds.replace(lnc+2,ss-lnc-2, |
200 | fields,fnc,fields.size()-fnc); | 200 | fields,fnc,fields.size()-fnc); |
diff --git a/lib/prequeue_rp.cc b/lib/prequeue_rp.cc index e242f87..3aa960f 100644 --- a/lib/prequeue_rp.cc +++ b/lib/prequeue_rp.cc | |||
@@ -26,56 +26,56 @@ namespace opkele { | |||
26 | OP_verifier(const string& o,const string& i) | 26 | OP_verifier(const string& o,const string& i) |
27 | : OP(o), id(i) { } | 27 | : OP(o), id(i) { } |
28 | 28 | ||
29 | OP_verifier& operator*() { return *this; } | 29 | OP_verifier& operator*() { return *this; } |
30 | OP_verifier& operator=(const openid_endpoint_t& oep) { | 30 | OP_verifier& operator=(const openid_endpoint_t& oep) { |
31 | if(oep.uri==OP) { | 31 | if(oep.uri==OP) { |
32 | if(oep.claimed_id==IDURI_SELECT20 | 32 | if(oep.claimed_id==IDURI_SELECT20 |
33 | || oep.local_id==IDURI_SELECT20 ) | 33 | || oep.local_id==IDURI_SELECT20 ) |
34 | throw bad_input(OPKELE_CP_ "claimed_id is an OP-Id"); | 34 | throw bad_input(OPKELE_CP_ "claimed_id is an OP-Id"); |
35 | if(oep.local_id==id) | 35 | if(oep.local_id==id) |
36 | throw __OP_verifier_good_input(OPKELE_CP_ "Found corresponding endpoint"); | 36 | throw __OP_verifier_good_input(OPKELE_CP_ "Found corresponding endpoint"); |
37 | } | 37 | } |
38 | return *this; | 38 | return *this; |
39 | } | 39 | } |
40 | 40 | ||
41 | OP_verifier& operator++() { return *this; } | 41 | OP_verifier& operator++() { return *this; } |
42 | OP_verifier& operator++(int) { return *this; } | 42 | OP_verifier& operator++(int) { return *this; } |
43 | }; | 43 | }; |
44 | 44 | ||
45 | void prequeue_RP::verify_OP(const string& OP,const string& claimed_id,const string& identity) const { | 45 | void prequeue_RP::verify_OP(const string& OP,const string& claimed_id,const string& identity) const { |
46 | try { | 46 | try { |
47 | idiscover(OP_verifier(OP,identity),claimed_id); | 47 | idiscover(OP_verifier(OP,identity),claimed_id); |
48 | throw id_res_unauthorized(OPKELE_CP_ | 48 | throw id_res_unauthorized(OPKELE_CP_ |
49 | "OP is not authorized to make an assertion regarding the identity"); | 49 | "OP is not authorized to make an assertion regarding the identity"); |
50 | }catch(__OP_verifier_good_input& ovgi) { | 50 | }catch(__OP_verifier_good_input& ovgi) { |
51 | } | 51 | } |
52 | } | 52 | } |
53 | 53 | ||
54 | class endpoint_queuer : public iterator<output_iterator_tag,openid_endpoint_t,void> { | 54 | class endpoint_queuer : public iterator<output_iterator_tag,openid_endpoint_t,void> { |
55 | public: | 55 | public: |
56 | prequeue_RP& rp; | 56 | prequeue_RP& rp; |
57 | 57 | ||
58 | endpoint_queuer(prequeue_RP& rp) : rp(rp) { } | 58 | endpoint_queuer(prequeue_RP& r) : rp(r) { } |
59 | 59 | ||
60 | endpoint_queuer& operator*() { return *this; } | 60 | endpoint_queuer& operator*() { return *this; } |
61 | endpoint_queuer& operator=(const openid_endpoint_t& oep) { | 61 | endpoint_queuer& operator=(const openid_endpoint_t& oep) { |
62 | rp.queue_endpoint(oep); return *this; } | 62 | rp.queue_endpoint(oep); return *this; } |
63 | 63 | ||
64 | endpoint_queuer& operator++() { return *this; } | 64 | endpoint_queuer& operator++() { return *this; } |
65 | endpoint_queuer& operator++(int) { return *this; } | 65 | endpoint_queuer& operator++(int) { return *this; } |
66 | }; | 66 | }; |
67 | 67 | ||
68 | void prequeue_RP::initiate(const string& usi) { | 68 | void prequeue_RP::initiate(const string& usi) { |
69 | begin_queueing(); | 69 | begin_queueing(); |
70 | set_normalized_id( idiscover(endpoint_queuer(*this),usi) ); | 70 | set_normalized_id( idiscover(endpoint_queuer(*this),usi) ); |
71 | end_queueing(); | 71 | end_queueing(); |
72 | } | 72 | } |
73 | 73 | ||
74 | void prequeue_RP::set_normalized_id(const string& nid) { | 74 | void prequeue_RP::set_normalized_id(const string&) { |
75 | } | 75 | } |
76 | 76 | ||
77 | const string prequeue_RP::get_normalized_id() const { | 77 | const string prequeue_RP::get_normalized_id() const { |
78 | throw not_implemented(OPKELE_CP_ "get_normalized_id() is not implemented"); | 78 | throw not_implemented(OPKELE_CP_ "get_normalized_id() is not implemented"); |
79 | } | 79 | } |
80 | 80 | ||
81 | } | 81 | } |
diff --git a/lib/sreg.cc b/lib/sreg.cc index b40cd45..0bd4d2e 100644 --- a/lib/sreg.cc +++ b/lib/sreg.cc | |||
@@ -26,70 +26,68 @@ namespace opkele { | |||
26 | 26 | ||
27 | bool operator==(const struct _sreg_field& fd,const string& fn) { | 27 | bool operator==(const struct _sreg_field& fd,const string& fn) { |
28 | return fd.fieldname==fn; | 28 | return fd.fieldname==fn; |
29 | } | 29 | } |
30 | 30 | ||
31 | void sreg_t::rp_checkid_hook(basic_openid_message& om) { | 31 | void sreg_t::rp_checkid_hook(basic_openid_message& om) { |
32 | string fr, fo; | 32 | string fr, fo; |
33 | for(fields_iterator f=fields_BEGIN;f<fields_END;++f) { | 33 | for(fields_iterator f=fields_BEGIN;f<fields_END;++f) { |
34 | if(f->fieldbit&fields_required) { | 34 | if(f->fieldbit&fields_required) { |
35 | if(!fr.empty()) fr+=","; | 35 | if(!fr.empty()) fr+=","; |
36 | fr += f->fieldname; | 36 | fr += f->fieldname; |
37 | } | 37 | } |
38 | if(f->fieldbit&fields_optional) { | 38 | if(f->fieldbit&fields_optional) { |
39 | if(!fo.empty()) fo+=","; | 39 | if(!fo.empty()) fo+=","; |
40 | fo += f->fieldname; | 40 | fo += f->fieldname; |
41 | } | 41 | } |
42 | } | 42 | } |
43 | string pfx = om.allocate_ns(OIURI_SREG11,"sreg"); | 43 | string pfx = om.allocate_ns(OIURI_SREG11,"sreg"); |
44 | if(!fr.empty()) om.set_field(pfx+".required",fr); | 44 | if(!fr.empty()) om.set_field(pfx+".required",fr); |
45 | if(!fo.empty()) om.set_field(pfx+".optional",fo); | 45 | if(!fo.empty()) om.set_field(pfx+".optional",fo); |
46 | if(!policy_url.empty()) om.set_field(pfx+".policy_url",policy_url); | 46 | if(!policy_url.empty()) om.set_field(pfx+".policy_url",policy_url); |
47 | } | 47 | } |
48 | 48 | ||
49 | void sreg_t::checkid_hook(basic_openid_message& om) { | 49 | void sreg_t::checkid_hook(basic_openid_message& om) { |
50 | rp_checkid_hook(om); } | 50 | rp_checkid_hook(om); } |
51 | 51 | ||
52 | void sreg_t::rp_id_res_hook(const basic_openid_message& om, | 52 | void sreg_t::rp_id_res_hook(const basic_openid_message& om, |
53 | const basic_openid_message& sp) { | 53 | const basic_openid_message& sp) { |
54 | clear(); | 54 | clear(); |
55 | string pfx; | 55 | string pfx; |
56 | try { | 56 | try { |
57 | pfx = om.find_ns(OIURI_SREG11,"sreg"); | 57 | pfx = om.find_ns(OIURI_SREG11,"sreg"); |
58 | }catch(failed_lookup& fl) { | 58 | }catch(failed_lookup&) { |
59 | try { | 59 | try { |
60 | pfx = om.find_ns(OIURI_SREG10,"sreg"); | 60 | pfx = om.find_ns(OIURI_SREG10,"sreg"); |
61 | }catch(failed_lookup& fl) { | 61 | }catch(failed_lookup&) { return; } |
62 | return; | ||
63 | } | ||
64 | } | 62 | } |
65 | pfx += '.'; | 63 | pfx += '.'; |
66 | for(fields_iterator f=fields_BEGIN;f<fields_END;++f) { | 64 | for(fields_iterator f=fields_BEGIN;f<fields_END;++f) { |
67 | string fn = pfx; fn+=f->fieldname; | 65 | string fn = pfx; fn+=f->fieldname; |
68 | if(!sp.has_field(fn)) continue; | 66 | if(!sp.has_field(fn)) continue; |
69 | has_fields |= f->fieldbit; | 67 | has_fields |= f->fieldbit; |
70 | response[f->fieldbit]=sp.get_field(fn); | 68 | response[f->fieldbit]=sp.get_field(fn); |
71 | } | 69 | } |
72 | } | 70 | } |
73 | 71 | ||
74 | void sreg_t::id_res_hook(const basic_openid_message& om, | 72 | void sreg_t::id_res_hook(const basic_openid_message& om, |
75 | const basic_openid_message& sp) { | 73 | const basic_openid_message& sp) { |
76 | rp_id_res_hook(om,sp); } | 74 | rp_id_res_hook(om,sp); } |
77 | 75 | ||
78 | const string& sreg_t::get_field(fieldbit_t fb) const { | 76 | const string& sreg_t::get_field(fieldbit_t fb) const { |
79 | response_t::const_iterator i = response.find(fb); | 77 | response_t::const_iterator i = response.find(fb); |
80 | if(i==response.end()) | 78 | if(i==response.end()) |
81 | throw failed_lookup(OPKELE_CP_ "no field data available"); | 79 | throw failed_lookup(OPKELE_CP_ "no field data available"); |
82 | return i->second; | 80 | return i->second; |
83 | } | 81 | } |
84 | 82 | ||
85 | void sreg_t::set_field(fieldbit_t fb,const string& fv) { | 83 | void sreg_t::set_field(fieldbit_t fb,const string& fv) { |
86 | response[fb] = fv; | 84 | response[fb] = fv; |
87 | has_fields |= fb; | 85 | has_fields |= fb; |
88 | } | 86 | } |
89 | 87 | ||
90 | void sreg_t::reset_field(fieldbit_t fb) { | 88 | void sreg_t::reset_field(fieldbit_t fb) { |
91 | has_fields &= ~fb; | 89 | has_fields &= ~fb; |
92 | response.erase(fb); | 90 | response.erase(fb); |
93 | } | 91 | } |
94 | 92 | ||
95 | void sreg_t::clear() { | 93 | void sreg_t::clear() { |
diff --git a/lib/verify_op.cc b/lib/verify_op.cc index ab21b4f..c493c12 100644 --- a/lib/verify_op.cc +++ b/lib/verify_op.cc | |||
@@ -1,53 +1,53 @@ | |||
1 | #include <opkele/verify_op.h> | 1 | #include <opkele/verify_op.h> |
2 | #include <opkele/discovery.h> | 2 | #include <opkele/discovery.h> |
3 | #include <opkele/exception.h> | 3 | #include <opkele/exception.h> |
4 | #include <opkele/util.h> | 4 | #include <opkele/util.h> |
5 | #include <opkele/uris.h> | 5 | #include <opkele/uris.h> |
6 | 6 | ||
7 | namespace opkele { | 7 | namespace opkele { |
8 | using std::output_iterator_tag; | 8 | using std::output_iterator_tag; |
9 | 9 | ||
10 | class __RP_verifier_good_input : public exception { | 10 | class __RP_verifier_good_input : public exception { |
11 | public: | 11 | public: |
12 | __RP_verifier_good_input(OPKELE_E_PARS) | 12 | __RP_verifier_good_input(OPKELE_E_PARS) |
13 | : exception(OPKELE_E_CONS) { } | 13 | : exception(OPKELE_E_CONS) { } |
14 | }; | 14 | }; |
15 | 15 | ||
16 | class RP_verifier : public iterator<output_iterator_tag,openid_endpoint_t,void> { | 16 | class RP_verifier : public iterator<output_iterator_tag,openid_endpoint_t,void> { |
17 | public: | 17 | public: |
18 | int seen; | ||
19 | const string& return_to; | 18 | const string& return_to; |
19 | int seen; | ||
20 | 20 | ||
21 | RP_verifier(const string& rt) | 21 | RP_verifier(const string& rt) |
22 | : return_to(rt), seen(0) { } | 22 | : return_to(rt), seen(0) { } |
23 | 23 | ||
24 | RP_verifier& operator*() { return *this; } | 24 | RP_verifier& operator*() { return *this; } |
25 | RP_verifier& operator=(const openid_endpoint_t& oep) { | 25 | RP_verifier& operator=(const openid_endpoint_t& oep) { |
26 | if(util::uri_matches_realm(return_to,oep.uri)) | 26 | if(util::uri_matches_realm(return_to,oep.uri)) |
27 | throw __RP_verifier_good_input(OPKELE_CP_ "Found matching realm"); | 27 | throw __RP_verifier_good_input(OPKELE_CP_ "Found matching realm"); |
28 | return *this; | 28 | return *this; |
29 | } | 29 | } |
30 | 30 | ||
31 | RP_verifier& operator++() { ++seen; return *this; } | 31 | RP_verifier& operator++() { ++seen; return *this; } |
32 | RP_verifier& operator++(int) { +seen; return *this; } | 32 | RP_verifier& operator++(int) { ++seen; return *this; } |
33 | }; | 33 | }; |
34 | 34 | ||
35 | void verify_OP::verify_return_to() { | 35 | void verify_OP::verify_return_to() { |
36 | basic_OP::verify_return_to(); | 36 | basic_OP::verify_return_to(); |
37 | try { | 37 | try { |
38 | RP_verifier rpv(return_to); | 38 | RP_verifier rpv(return_to); |
39 | string drealm = realm; | 39 | string drealm = realm; |
40 | string::size_type csss = drealm.find("://*."); | 40 | string::size_type csss = drealm.find("://*."); |
41 | if(csss==4 || csss==5) | 41 | if(csss==4 || csss==5) |
42 | drealm.replace(csss+3,1,"www"); | 42 | drealm.replace(csss+3,1,"www"); |
43 | const char *rtt[] = { STURI_OPENID20_RT, 0 }; | 43 | const char *rtt[] = { STURI_OPENID20_RT, 0 }; |
44 | yadiscover(rpv,drealm,rtt,false); | 44 | yadiscover(rpv,drealm,rtt,false); |
45 | if(rpv.seen) | 45 | if(rpv.seen) |
46 | throw bad_return_to(OPKELE_CP_ "return_to URL doesn't match any found while doing discovery on RP"); | 46 | throw bad_return_to(OPKELE_CP_ "return_to URL doesn't match any found while doing discovery on RP"); |
47 | }catch(__RP_verifier_good_input&) { | 47 | }catch(__RP_verifier_good_input&) { |
48 | }catch(bad_return_to& brt) { | 48 | }catch(bad_return_to& brt) { |
49 | throw; | 49 | throw; |
50 | }catch(exception_network&) { } | 50 | }catch(exception_network&) { } |
51 | } | 51 | } |
52 | 52 | ||
53 | } | 53 | } |
@@ -30,66 +30,66 @@ static const string get_self_url(const kingate::cgi_gateway& gw) { | |||
30 | rv += gw.get_meta("REQUEST_URI"); | 30 | rv += gw.get_meta("REQUEST_URI"); |
31 | string::size_type q = rv.find('?'); | 31 | string::size_type q = rv.find('?'); |
32 | if(q!=string::npos) | 32 | if(q!=string::npos) |
33 | rv.erase(q); | 33 | rv.erase(q); |
34 | return rv; | 34 | return rv; |
35 | } | 35 | } |
36 | 36 | ||
37 | class opdb_t : public sqlite3_t { | 37 | class opdb_t : public sqlite3_t { |
38 | public: | 38 | public: |
39 | opdb_t() | 39 | opdb_t() |
40 | : sqlite3_t("/tmp/OP.db") { | 40 | : sqlite3_t("/tmp/OP.db") { |
41 | assert(_D); | 41 | assert(_D); |
42 | char **resp; int nr,nc; char *errm; | 42 | char **resp; int nr,nc; char *errm; |
43 | if(sqlite3_get_table( | 43 | if(sqlite3_get_table( |
44 | _D, "SELECT a_op FROM assoc LIMIT 0", | 44 | _D, "SELECT a_op FROM assoc LIMIT 0", |
45 | &resp,&nr,&nc,&errm)!=SQLITE_OK) { | 45 | &resp,&nr,&nc,&errm)!=SQLITE_OK) { |
46 | extern const char *__OP_db_bootstrap; | 46 | extern const char *__OP_db_bootstrap; |
47 | DOUT_("Bootstrapping DB"); | 47 | DOUT_("Bootstrapping DB"); |
48 | if(sqlite3_exec(_D,__OP_db_bootstrap,NULL,NULL,&errm)!=SQLITE_OK) | 48 | if(sqlite3_exec(_D,__OP_db_bootstrap,NULL,NULL,&errm)!=SQLITE_OK) |
49 | throw opkele::exception(OPKELE_CP_ string("Failed to boostrap SQLite database: ")+errm); | 49 | throw opkele::exception(OPKELE_CP_ string("Failed to boostrap SQLite database: ")+errm); |
50 | }else | 50 | }else |
51 | sqlite3_free_table(resp); | 51 | sqlite3_free_table(resp); |
52 | } | 52 | } |
53 | }; | 53 | }; |
54 | 54 | ||
55 | class example_op_t : public opkele::verify_OP { | 55 | class example_op_t : public opkele::verify_OP { |
56 | public: | 56 | public: |
57 | kingate::cgi_gateway& gw; | 57 | kingate::cgi_gateway& gw; |
58 | opdb_t db; | 58 | opdb_t db; |
59 | kingate::cookie htc; | 59 | kingate::cookie htc; |
60 | 60 | ||
61 | 61 | ||
62 | example_op_t(kingate::cgi_gateway& gw) | 62 | example_op_t(kingate::cgi_gateway& g) |
63 | : gw(gw) { | 63 | : gw(g) { |
64 | try { | 64 | try { |
65 | htc = gw.cookies.get_cookie("htop_session"); | 65 | htc = gw.cookies.get_cookie("htop_session"); |
66 | sqlite3_mem_t<char*> S = sqlite3_mprintf( | 66 | sqlite3_mem_t<char*> S = sqlite3_mprintf( |
67 | "SELECT 1 FROM ht_sessions WHERE hts_id=%Q", | 67 | "SELECT 1 FROM ht_sessions WHERE hts_id=%Q", |
68 | htc.get_value().c_str()); | 68 | htc.get_value().c_str()); |
69 | sqlite3_table_t T; int nr,nc; | 69 | sqlite3_table_t T; int nr,nc; |
70 | db.get_table(S,T,&nr,&nc); | 70 | db.get_table(S,T,&nr,&nc); |
71 | if(nr<1) | 71 | if(nr<1) |
72 | throw kingate::exception_notfound(CODEPOINT,"forcing cookie generation"); | 72 | throw kingate::exception_notfound(CODEPOINT,"forcing cookie generation"); |
73 | }catch(kingate::exception_notfound& kenf) { | 73 | }catch(kingate::exception_notfound& kenf) { |
74 | uuid_t uuid; uuid_generate(uuid); | 74 | uuid_t uuid; uuid_generate(uuid); |
75 | htc = kingate::cookie("htop_session",opkele::util::encode_base64(uuid,sizeof(uuid))); | 75 | htc = kingate::cookie("htop_session",opkele::util::encode_base64(uuid,sizeof(uuid))); |
76 | sqlite3_mem_t<char*> S = sqlite3_mprintf( | 76 | sqlite3_mem_t<char*> S = sqlite3_mprintf( |
77 | "INSERT INTO ht_sessions (hts_id) VALUES (%Q)", | 77 | "INSERT INTO ht_sessions (hts_id) VALUES (%Q)", |
78 | htc.get_value().c_str()); | 78 | htc.get_value().c_str()); |
79 | db.exec(S); | 79 | db.exec(S); |
80 | } | 80 | } |
81 | } | 81 | } |
82 | 82 | ||
83 | void set_authorized(bool a) { | 83 | void set_authorized(bool a) { |
84 | sqlite3_mem_t<char*> | 84 | sqlite3_mem_t<char*> |
85 | S = sqlite3_mprintf( | 85 | S = sqlite3_mprintf( |
86 | "UPDATE ht_sessions" | 86 | "UPDATE ht_sessions" |
87 | " SET authorized=%d" | 87 | " SET authorized=%d" |
88 | " WHERE hts_id=%Q", | 88 | " WHERE hts_id=%Q", |
89 | (int)a,htc.get_value().c_str()); | 89 | (int)a,htc.get_value().c_str()); |
90 | db.exec(S); | 90 | db.exec(S); |
91 | } | 91 | } |
92 | bool get_authorized() { | 92 | bool get_authorized() { |
93 | sqlite3_mem_t<char*> | 93 | sqlite3_mem_t<char*> |
94 | S = sqlite3_mprintf( | 94 | S = sqlite3_mprintf( |
95 | "SELECT authorized" | 95 | "SELECT authorized" |
@@ -171,201 +171,201 @@ class example_op_t : public opkele::verify_OP { | |||
171 | nonce.c_str() ); | 171 | nonce.c_str() ); |
172 | db.exec(S); | 172 | db.exec(S); |
173 | return nonce; | 173 | return nonce; |
174 | } | 174 | } |
175 | bool check_nonce(const string& nonce) { | 175 | bool check_nonce(const string& nonce) { |
176 | sqlite3_mem_t<char*> | 176 | sqlite3_mem_t<char*> |
177 | S = sqlite3_mprintf( | 177 | S = sqlite3_mprintf( |
178 | "SELECT 1" | 178 | "SELECT 1" |
179 | " FROM nonces" | 179 | " FROM nonces" |
180 | " WHERE n_once=%Q AND n_itime IS NULL", | 180 | " WHERE n_once=%Q AND n_itime IS NULL", |
181 | nonce.c_str()); | 181 | nonce.c_str()); |
182 | sqlite3_table_t T; | 182 | sqlite3_table_t T; |
183 | int nr,nc; | 183 | int nr,nc; |
184 | db.get_table(S,T,&nr,&nc); | 184 | db.get_table(S,T,&nr,&nc); |
185 | return nr>=1; | 185 | return nr>=1; |
186 | } | 186 | } |
187 | void invalidate_nonce(const string& nonce) { | 187 | void invalidate_nonce(const string& nonce) { |
188 | sqlite3_mem_t<char*> | 188 | sqlite3_mem_t<char*> |
189 | S = sqlite3_mprintf( | 189 | S = sqlite3_mprintf( |
190 | "UPDATE nonces" | 190 | "UPDATE nonces" |
191 | " SET n_itime=datetime('now')" | 191 | " SET n_itime=datetime('now')" |
192 | " WHERE n_once=%Q", | 192 | " WHERE n_once=%Q", |
193 | nonce.c_str()); | 193 | nonce.c_str()); |
194 | db.exec(S); | 194 | db.exec(S); |
195 | } | 195 | } |
196 | 196 | ||
197 | const string get_op_endpoint() const { | 197 | const string get_op_endpoint() const { |
198 | return get_self_url(gw); | 198 | return get_self_url(gw); |
199 | } | 199 | } |
200 | 200 | ||
201 | }; | 201 | }; |
202 | 202 | ||
203 | int main(int argc,char *argv[]) { | 203 | int main(int,char **) { |
204 | try { | 204 | try { |
205 | kingate::plaincgi_interface ci; | 205 | kingate::plaincgi_interface ci; |
206 | kingate::cgi_gateway gw(ci); | 206 | kingate::cgi_gateway gw(ci); |
207 | string op; | 207 | string op; |
208 | try { op = gw.get_param("op"); }catch(kingate::exception_notfound&) { } | 208 | try { op = gw.get_param("op"); }catch(kingate::exception_notfound&) { } |
209 | string message; | 209 | string message; |
210 | if(op=="set_password") { | 210 | if(op=="set_password") { |
211 | example_op_t OP(gw); | 211 | example_op_t OP(gw); |
212 | string password = gw.get_param("password"); | 212 | string password = gw.get_param("password"); |
213 | sqlite3_mem_t<char*> | 213 | sqlite3_mem_t<char*> |
214 | Sget = sqlite3_mprintf("SELECT s_password FROM setup LIMIT 1"); | 214 | Sget = sqlite3_mprintf("SELECT s_password FROM setup LIMIT 1"); |
215 | sqlite3_table_t T; int nr,nc; | 215 | sqlite3_table_t T; int nr,nc; |
216 | OP.db.get_table(Sget,T,&nr,&nc); | 216 | OP.db.get_table(Sget,T,&nr,&nc); |
217 | if(nr>=1) | 217 | if(nr>=1) |
218 | throw opkele::exception(OPKELE_CP_ "Password already set"); | 218 | throw opkele::exception(OPKELE_CP_ "Password already set"); |
219 | sqlite3_mem_t<char*> | 219 | sqlite3_mem_t<char*> |
220 | Sset = sqlite3_mprintf( | 220 | Sset = sqlite3_mprintf( |
221 | "INSERT INTO setup (s_password) VALUES (%Q)", | 221 | "INSERT INTO setup (s_password) VALUES (%Q)", |
222 | password.c_str()); | 222 | password.c_str()); |
223 | OP.db.exec(Sset); | 223 | OP.db.exec(Sset); |
224 | op.clear(); | 224 | op.clear(); |
225 | message = "password set"; | 225 | message = "password set"; |
226 | }else if(op=="login") { | 226 | }else if(op=="login") { |
227 | example_op_t OP(gw); | 227 | example_op_t OP(gw); |
228 | string password = gw.get_param("password"); | 228 | string password = gw.get_param("password"); |
229 | sqlite3_mem_t<char*> | 229 | sqlite3_mem_t<char*> |
230 | Sget = sqlite3_mprintf("SELECT s_password FROM setup LIMIT 1"); | 230 | Sget = sqlite3_mprintf("SELECT s_password FROM setup LIMIT 1"); |
231 | sqlite3_table_t T; int nr,nc; | 231 | sqlite3_table_t T; int nr,nc; |
232 | OP.db.get_table(Sget,T,&nr,&nc); | 232 | OP.db.get_table(Sget,T,&nr,&nc); |
233 | if(nr<1) | 233 | if(nr<1) |
234 | throw opkele::exception(OPKELE_CP_ "no password set"); | 234 | throw opkele::exception(OPKELE_CP_ "no password set"); |
235 | if(password!=T.get(1,0,nc)) | 235 | if(password!=T.get(1,0,nc)) |
236 | throw opkele::exception(OPKELE_CP_ "wrong password"); | 236 | throw opkele::exception(OPKELE_CP_ "wrong password"); |
237 | OP.set_authorized(true); | 237 | OP.set_authorized(true); |
238 | op.clear(); | 238 | op.clear(); |
239 | message = "logged in"; | 239 | message = "logged in"; |
240 | OP.cookie_header(cout); | 240 | OP.cookie_header(cout); |
241 | }else if(op=="logout") { | 241 | }else if(op=="logout") { |
242 | example_op_t OP(gw); | 242 | example_op_t OP(gw); |
243 | OP.set_authorized(false); | 243 | OP.set_authorized(false); |
244 | op.clear(); | 244 | op.clear(); |
245 | message = "logged out"; | 245 | message = "logged out"; |
246 | } | 246 | } |
247 | string om; | 247 | string omode; |
248 | try { om = gw.get_param("openid.mode"); }catch(kingate::exception_notfound&) { } | 248 | try { omode = gw.get_param("openid.mode"); }catch(kingate::exception_notfound&) { } |
249 | if(op=="xrds") { | 249 | if(op=="xrds") { |
250 | cout << | 250 | cout << |
251 | "Content-type: application/xrds+xml\n\n" | 251 | "Content-type: application/xrds+xml\n\n" |
252 | "<?xml version='1.0' encoding='utf-8'?>" | 252 | "<?xml version='1.0' encoding='utf-8'?>" |
253 | "<xrds:XRDS xmlns:xrds='xri://$xrds' xmlns='xri://$xrd*($v*2.0)'>" | 253 | "<xrds:XRDS xmlns:xrds='xri://$xrds' xmlns='xri://$xrd*($v*2.0)'>" |
254 | "<XRD>" | 254 | "<XRD>" |
255 | "<Service>" | 255 | "<Service>" |
256 | "<Type>" STURI_OPENID20 "</Type>" | 256 | "<Type>" STURI_OPENID20 "</Type>" |
257 | "<URI>" << get_self_url(gw) << "</URI>" | 257 | "<URI>" << get_self_url(gw) << "</URI>" |
258 | "</Service>"; | 258 | "</Service>"; |
259 | if(gw.has_param("idsel")){ | 259 | if(gw.has_param("idsel")){ |
260 | cout << | 260 | cout << |
261 | "<Service>" | 261 | "<Service>" |
262 | "<Type>" STURI_OPENID20_OP "</Type>" | 262 | "<Type>" STURI_OPENID20_OP "</Type>" |
263 | "<URI>" << get_self_url(gw) << "</URI>"; | 263 | "<URI>" << get_self_url(gw) << "</URI>"; |
264 | } | 264 | } |
265 | cout << | 265 | cout << |
266 | "</XRD>" | 266 | "</XRD>" |
267 | "</xrds:XRDS>"; | 267 | "</xrds:XRDS>"; |
268 | }else if(op=="id_res" || op=="cancel") { | 268 | }else if(op=="id_res" || op=="cancel") { |
269 | kingate_openid_message_t inm(gw); | 269 | kingate_openid_message_t inm(gw); |
270 | example_op_t OP(gw); | 270 | example_op_t OP(gw); |
271 | if(gw.get_param("hts_id")!=OP.htc.get_value()) | 271 | if(gw.get_param("hts_id")!=OP.htc.get_value()) |
272 | throw opkele::exception(OPKELE_CP_ "toying around, huh?"); | 272 | throw opkele::exception(OPKELE_CP_ "toying around, huh?"); |
273 | opkele::sreg_t sreg; | 273 | opkele::sreg_t sreg; |
274 | OP.checkid_(inm,sreg); | 274 | OP.checkid_(inm,sreg); |
275 | OP.cookie_header(cout); | 275 | OP.cookie_header(cout); |
276 | opkele::openid_message_t om; | 276 | opkele::openid_message_t om; |
277 | if(op=="id_res") { | 277 | if(op=="id_res") { |
278 | if(!OP.get_authorized()) | 278 | if(!OP.get_authorized()) |
279 | throw opkele::exception(OPKELE_CP_ "not logged in"); | 279 | throw opkele::exception(OPKELE_CP_ "not logged in"); |
280 | if(OP.is_id_select()) { | 280 | if(OP.is_id_select()) { |
281 | OP.select_identity( get_self_url(gw), get_self_url(gw) ); | 281 | OP.select_identity( get_self_url(gw), get_self_url(gw) ); |
282 | } | 282 | } |
283 | sreg.set_field(opkele::sreg_t::field_nickname,"anonymous"); | 283 | sreg.set_field(opkele::sreg_t::field_nickname,"anonymous"); |
284 | sreg.set_field(opkele::sreg_t::field_fullname,"Ann O'Nymus"); | 284 | sreg.set_field(opkele::sreg_t::field_fullname,"Ann O'Nymus"); |
285 | sreg.set_field(opkele::sreg_t::field_gender,"F"); | 285 | sreg.set_field(opkele::sreg_t::field_gender,"F"); |
286 | sreg.setup_response(); | 286 | sreg.setup_response(); |
287 | cout << | 287 | cout << |
288 | "Status: 302 Going back to RP with id_res\n" | 288 | "Status: 302 Going back to RP with id_res\n" |
289 | "Location: " << OP.id_res(om,sreg).append_query(OP.get_return_to()) | 289 | "Location: " << OP.id_res(om,sreg).append_query(OP.get_return_to()) |
290 | << "\n\n"; | 290 | << "\n\n"; |
291 | }else{ | 291 | }else{ |
292 | cout << | 292 | cout << |
293 | "Status: 302 Going back to RP with cancel\n" | 293 | "Status: 302 Going back to RP with cancel\n" |
294 | "Location: " << OP.cancel(om).append_query(OP.get_return_to()) | 294 | "Location: " << OP.cancel(om).append_query(OP.get_return_to()) |
295 | << "\n\n"; | 295 | << "\n\n"; |
296 | } | 296 | } |
297 | om.to_keyvalues(clog); | 297 | om.to_keyvalues(clog); |
298 | }else if(om=="associate") { | 298 | }else if(omode=="associate") { |
299 | kingate_openid_message_t inm(gw); | 299 | kingate_openid_message_t inm(gw); |
300 | opkele::openid_message_t oum; | 300 | opkele::openid_message_t oum; |
301 | example_op_t OP(gw); | 301 | example_op_t OP(gw); |
302 | OP.associate(oum,inm); | 302 | OP.associate(oum,inm); |
303 | cout << "Content-type: text/plain\n\n"; | 303 | cout << "Content-type: text/plain\n\n"; |
304 | oum.to_keyvalues(cout); | 304 | oum.to_keyvalues(cout); |
305 | }else if(om=="checkid_setup") { | 305 | }else if(omode=="checkid_setup") { |
306 | kingate_openid_message_t inm(gw); | 306 | kingate_openid_message_t inm(gw); |
307 | example_op_t OP(gw); | 307 | example_op_t OP(gw); |
308 | OP.checkid_(inm,0); | 308 | OP.checkid_(inm,0); |
309 | OP.cookie_header(cout) << | 309 | OP.cookie_header(cout) << |
310 | "Content-type: text/html\n" | 310 | "Content-type: text/html\n" |
311 | "\n" | 311 | "\n" |
312 | 312 | ||
313 | "<html>" | 313 | "<html>" |
314 | "<head>" | 314 | "<head>" |
315 | "<title>test OP: confirm authentication</title>" | 315 | "<title>test OP: confirm authentication</title>" |
316 | "</head>" | 316 | "</head>" |
317 | "<body>" | 317 | "<body>" |
318 | "realm: " << OP.get_realm() << "<br/>" | 318 | "realm: " << OP.get_realm() << "<br/>" |
319 | "return_to: " << OP.get_return_to() << "<br/>" | 319 | "return_to: " << OP.get_return_to() << "<br/>" |
320 | "claimed_id: " << OP.get_claimed_id() << "<br/>" | 320 | "claimed_id: " << OP.get_claimed_id() << "<br/>" |
321 | "identity: " << OP.get_identity() << "<br/>"; | 321 | "identity: " << OP.get_identity() << "<br/>"; |
322 | if(OP.is_id_select()) { | 322 | if(OP.is_id_select()) { |
323 | OP.select_identity( get_self_url(gw), get_self_url(gw) ); | 323 | OP.select_identity( get_self_url(gw), get_self_url(gw) ); |
324 | cout << | 324 | cout << |
325 | "selected claimed_id: " << OP.get_claimed_id() << "<br/>" | 325 | "selected claimed_id: " << OP.get_claimed_id() << "<br/>" |
326 | "selected identity: " << OP.get_identity() << "<br/>"; | 326 | "selected identity: " << OP.get_identity() << "<br/>"; |
327 | } | 327 | } |
328 | cout << | 328 | cout << |
329 | "<form method='post'>"; | 329 | "<form method='post'>"; |
330 | inm.to_htmlhiddens(cout); | 330 | inm.to_htmlhiddens(cout); |
331 | cout << | 331 | cout << |
332 | "<input type='hidden' name='hts_id'" | 332 | "<input type='hidden' name='hts_id'" |
333 | " value='" << opkele::util::attr_escape(OP.htc.get_value()) << "'/>" | 333 | " value='" << opkele::util::attr_escape(OP.htc.get_value()) << "'/>" |
334 | "<input type='submit' name='op' value='id_res'/>" | 334 | "<input type='submit' name='op' value='id_res'/>" |
335 | "<input type='submit' name='op' value='cancel'/>" | 335 | "<input type='submit' name='op' value='cancel'/>" |
336 | "</form>" | 336 | "</form>" |
337 | "</body>" | 337 | "</body>" |
338 | "</html>"; | 338 | "</html>"; |
339 | }else if(om=="check_authentication") { | 339 | }else if(omode=="check_authentication") { |
340 | kingate_openid_message_t inm(gw); | 340 | kingate_openid_message_t inm(gw); |
341 | example_op_t OP(gw); | 341 | example_op_t OP(gw); |
342 | opkele::openid_message_t oum; | 342 | opkele::openid_message_t oum; |
343 | OP.check_authentication(oum,inm); | 343 | OP.check_authentication(oum,inm); |
344 | cout << "Content-type: text/plain\n\n"; | 344 | cout << "Content-type: text/plain\n\n"; |
345 | oum.to_keyvalues(cout); | 345 | oum.to_keyvalues(cout); |
346 | oum.to_keyvalues(clog); | 346 | oum.to_keyvalues(clog); |
347 | }else{ | 347 | }else{ |
348 | example_op_t OP(gw); | 348 | example_op_t OP(gw); |
349 | string idsel; | 349 | string idsel; |
350 | if(gw.has_param("idsel")) | 350 | if(gw.has_param("idsel")) |
351 | idsel = "&idsel=idsel"; | 351 | idsel = "&idsel=idsel"; |
352 | OP.cookie_header(cout) << | 352 | OP.cookie_header(cout) << |
353 | "Content-type: text/html\n" | 353 | "Content-type: text/html\n" |
354 | "X-XRDS-Location: " << get_self_url(gw) << "?op=xrds" << idsel << "\n" | 354 | "X-XRDS-Location: " << get_self_url(gw) << "?op=xrds" << idsel << "\n" |
355 | "\n" | 355 | "\n" |
356 | 356 | ||
357 | "<html>" | 357 | "<html>" |
358 | "<head>" | 358 | "<head>" |
359 | "<title>test OP</title>" | 359 | "<title>test OP</title>" |
360 | "<link rel='openid.server' href='" << get_self_url(gw) << "'/>" | 360 | "<link rel='openid.server' href='" << get_self_url(gw) << "'/>" |
361 | "</head>" | 361 | "</head>" |
362 | "<body>" | 362 | "<body>" |
363 | "test openid 2.0 endpoint" | 363 | "test openid 2.0 endpoint" |
364 | "<br/>" | 364 | "<br/>" |
365 | "<a href='" << get_self_url(gw) << "?op=xrds" << idsel << "'>XRDS document</a>" | 365 | "<a href='" << get_self_url(gw) << "?op=xrds" << idsel << "'>XRDS document</a>" |
366 | "<br/>" | 366 | "<br/>" |
367 | "<h1>" << message << "</h1>"; | 367 | "<h1>" << message << "</h1>"; |
368 | sqlite3_mem_t<char*> | 368 | sqlite3_mem_t<char*> |
369 | S = sqlite3_mprintf("SELECT s_password FROM setup LIMIT 1"); | 369 | S = sqlite3_mprintf("SELECT s_password FROM setup LIMIT 1"); |
370 | sqlite3_table_t T; int nr,nc; | 370 | sqlite3_table_t T; int nr,nc; |
371 | OP.db.get_table(S,T,&nr,&nc); | 371 | OP.db.get_table(S,T,&nr,&nc); |
@@ -29,66 +29,66 @@ using namespace opkele; | |||
29 | # define DUMBTHROW throw opkele::dumb_RP(OPKELE_CP_ "This RP is dumb") | 29 | # define DUMBTHROW throw opkele::dumb_RP(OPKELE_CP_ "This RP is dumb") |
30 | #else | 30 | #else |
31 | # define DUMBTHROW (void)0 | 31 | # define DUMBTHROW (void)0 |
32 | #endif | 32 | #endif |
33 | 33 | ||
34 | class rpdb_t : public sqlite3_t { | 34 | class rpdb_t : public sqlite3_t { |
35 | public: | 35 | public: |
36 | rpdb_t() | 36 | rpdb_t() |
37 | : sqlite3_t("/tmp/RP.db") { | 37 | : sqlite3_t("/tmp/RP.db") { |
38 | assert(_D); | 38 | assert(_D); |
39 | char **resp; int nrow,ncol; char *errm; | 39 | char **resp; int nrow,ncol; char *errm; |
40 | if(sqlite3_get_table( | 40 | if(sqlite3_get_table( |
41 | _D,"SELECT a_op FROM assoc LIMIT 0", | 41 | _D,"SELECT a_op FROM assoc LIMIT 0", |
42 | &resp,&nrow,&ncol,&errm)!=SQLITE_OK) { | 42 | &resp,&nrow,&ncol,&errm)!=SQLITE_OK) { |
43 | extern const char *__RP_db_bootstrap; | 43 | extern const char *__RP_db_bootstrap; |
44 | DOUT_("Bootstrapping DB"); | 44 | DOUT_("Bootstrapping DB"); |
45 | if(sqlite3_exec(_D,__RP_db_bootstrap,NULL,NULL,&errm)!=SQLITE_OK) | 45 | if(sqlite3_exec(_D,__RP_db_bootstrap,NULL,NULL,&errm)!=SQLITE_OK) |
46 | throw opkele::exception(OPKELE_CP_ string("Failed to bootstrap SQLite database: ")+errm); | 46 | throw opkele::exception(OPKELE_CP_ string("Failed to bootstrap SQLite database: ")+errm); |
47 | }else | 47 | }else |
48 | sqlite3_free_table(resp); | 48 | sqlite3_free_table(resp); |
49 | 49 | ||
50 | } | 50 | } |
51 | }; | 51 | }; |
52 | 52 | ||
53 | class example_rp_t : public opkele::prequeue_RP { | 53 | class example_rp_t : public opkele::prequeue_RP { |
54 | public: | 54 | public: |
55 | mutable rpdb_t db; | 55 | mutable rpdb_t db; |
56 | kingate::cookie htc; | 56 | kingate::cookie htc; |
57 | long as_id; | 57 | long as_id; |
58 | int ordinal; | 58 | int ordinal; |
59 | kingate::cgi_gateway& gw; | 59 | kingate::cgi_gateway& gw; |
60 | 60 | ||
61 | example_rp_t(kingate::cgi_gateway& gw) | 61 | example_rp_t(kingate::cgi_gateway& g) |
62 | : ordinal(0), have_eqtop(false), gw(gw), as_id(-1) { | 62 | : as_id(-1), ordinal(0), gw(g), have_eqtop(false) { |
63 | try { | 63 | try { |
64 | htc = gw.cookies.get_cookie("ht_session"); | 64 | htc = gw.cookies.get_cookie("ht_session"); |
65 | as_id = opkele::util::string_to_long(gw.get_param("asid")); | 65 | as_id = opkele::util::string_to_long(gw.get_param("asid")); |
66 | }catch(kingate::exception_notfound& kenf) { | 66 | }catch(kingate::exception_notfound& kenf) { |
67 | uuid_t uuid; uuid_generate(uuid); | 67 | uuid_t uuid; uuid_generate(uuid); |
68 | htc = kingate::cookie("ht_session",util::encode_base64(uuid,sizeof(uuid))); | 68 | htc = kingate::cookie("ht_session",util::encode_base64(uuid,sizeof(uuid))); |
69 | sqlite3_mem_t<char*> S = sqlite3_mprintf( | 69 | sqlite3_mem_t<char*> S = sqlite3_mprintf( |
70 | "INSERT INTO ht_sessions (hts_id) VALUES (%Q)", | 70 | "INSERT INTO ht_sessions (hts_id) VALUES (%Q)", |
71 | htc.get_value().c_str()); | 71 | htc.get_value().c_str()); |
72 | db.exec(S); | 72 | db.exec(S); |
73 | } | 73 | } |
74 | } | 74 | } |
75 | 75 | ||
76 | /* Global persistent store */ | 76 | /* Global persistent store */ |
77 | 77 | ||
78 | opkele::assoc_t store_assoc( | 78 | opkele::assoc_t store_assoc( |
79 | const string& OP,const string& handle, | 79 | const string& OP,const string& handle, |
80 | const string& type,const secret_t& secret, | 80 | const string& type,const secret_t& secret, |
81 | int expires_in) { | 81 | int expires_in) { |
82 | DUMBTHROW; | 82 | DUMBTHROW; |
83 | DOUT_("Storing '" << handle << "' assoc with '" << OP << "'"); | 83 | DOUT_("Storing '" << handle << "' assoc with '" << OP << "'"); |
84 | time_t exp = time(0)+expires_in; | 84 | time_t exp = time(0)+expires_in; |
85 | sqlite3_mem_t<char*> | 85 | sqlite3_mem_t<char*> |
86 | S = sqlite3_mprintf( | 86 | S = sqlite3_mprintf( |
87 | "INSERT INTO assoc" | 87 | "INSERT INTO assoc" |
88 | " (a_op,a_handle,a_type,a_ctime,a_etime,a_secret)" | 88 | " (a_op,a_handle,a_type,a_ctime,a_etime,a_secret)" |
89 | " VALUES (" | 89 | " VALUES (" |
90 | " %Q,%Q,%Q," | 90 | " %Q,%Q,%Q," |
91 | " datetime('now'), datetime('now','+%d seconds')," | 91 | " datetime('now'), datetime('now','+%d seconds')," |
92 | " %Q" | 92 | " %Q" |
93 | " );", OP.c_str(), handle.c_str(), type.c_str(), | 93 | " );", OP.c_str(), handle.c_str(), type.c_str(), |
94 | expires_in, | 94 | expires_in, |
@@ -322,65 +322,65 @@ class example_rp_t : public opkele::prequeue_RP { | |||
322 | 322 | ||
323 | void initiate(const string& usi) { | 323 | void initiate(const string& usi) { |
324 | allocate_asid(); | 324 | allocate_asid(); |
325 | prequeue_RP::initiate(usi); | 325 | prequeue_RP::initiate(usi); |
326 | } | 326 | } |
327 | 327 | ||
328 | string get_self_url() const { | 328 | string get_self_url() const { |
329 | string rv = get_this_url(); | 329 | string rv = get_this_url(); |
330 | string::size_type q = rv.find('?'); | 330 | string::size_type q = rv.find('?'); |
331 | if(q!=string::npos) | 331 | if(q!=string::npos) |
332 | rv.erase(q); | 332 | rv.erase(q); |
333 | return rv; | 333 | return rv; |
334 | } | 334 | } |
335 | 335 | ||
336 | void allocate_asid() { | 336 | void allocate_asid() { |
337 | sqlite3_mem_t<char*> S = sqlite3_mprintf( | 337 | sqlite3_mem_t<char*> S = sqlite3_mprintf( |
338 | "INSERT INTO auth_sessions (hts_id)" | 338 | "INSERT INTO auth_sessions (hts_id)" |
339 | " VALUES (%Q)", | 339 | " VALUES (%Q)", |
340 | htc.get_value().c_str()); | 340 | htc.get_value().c_str()); |
341 | db.exec(S); | 341 | db.exec(S); |
342 | as_id = sqlite3_last_insert_rowid(db); | 342 | as_id = sqlite3_last_insert_rowid(db); |
343 | DOUT_("Allocated authentication session id "<<as_id); | 343 | DOUT_("Allocated authentication session id "<<as_id); |
344 | assert(as_id>=0); | 344 | assert(as_id>=0); |
345 | } | 345 | } |
346 | 346 | ||
347 | #ifdef DUMB_RP | 347 | #ifdef DUMB_RP |
348 | virtual assoc_t associate(const string& OP) { | 348 | virtual assoc_t associate(const string& OP) { |
349 | DUMBTHROW; | 349 | DUMBTHROW; |
350 | } | 350 | } |
351 | #endif | 351 | #endif |
352 | }; | 352 | }; |
353 | 353 | ||
354 | int main(int argc,char *argv[]) { | 354 | int main(int,char **) { |
355 | try { | 355 | try { |
356 | kingate::plaincgi_interface ci; | 356 | kingate::plaincgi_interface ci; |
357 | kingate::cgi_gateway gw(ci); | 357 | kingate::cgi_gateway gw(ci); |
358 | string op; | 358 | string op; |
359 | try { op = gw.get_param("op"); }catch(kingate::exception_notfound&) { } | 359 | try { op = gw.get_param("op"); }catch(kingate::exception_notfound&) { } |
360 | if(op=="initiate") { | 360 | if(op=="initiate") { |
361 | example_rp_t rp(gw); | 361 | example_rp_t rp(gw); |
362 | string usi = gw.get_param("openid_identity"); | 362 | string usi = gw.get_param("openid_identity"); |
363 | rp.initiate(usi); | 363 | rp.initiate(usi); |
364 | opkele::sreg_t sreg(opkele::sreg_t::fields_NONE,opkele::sreg_t::fields_ALL); | 364 | opkele::sreg_t sreg(opkele::sreg_t::fields_NONE,opkele::sreg_t::fields_ALL); |
365 | opkele::openid_message_t cm; | 365 | opkele::openid_message_t cm; |
366 | string loc; | 366 | string loc; |
367 | cout << | 367 | cout << |
368 | "Set-Cookie: " << rp.htc.set_cookie_header() << "\n" | 368 | "Set-Cookie: " << rp.htc.set_cookie_header() << "\n" |
369 | "Status: 302 Going to OP\n" | 369 | "Status: 302 Going to OP\n" |
370 | "Location: " << ( | 370 | "Location: " << ( |
371 | loc = rp.checkid_(cm,opkele::mode_checkid_setup, | 371 | loc = rp.checkid_(cm,opkele::mode_checkid_setup, |
372 | rp.get_self_url()+ | 372 | rp.get_self_url()+ |
373 | "?op=confirm&asid="+opkele::util::long_to_string(rp.as_id), | 373 | "?op=confirm&asid="+opkele::util::long_to_string(rp.as_id), |
374 | rp.get_self_url(),&sreg).append_query(rp.get_endpoint().uri) | 374 | rp.get_self_url(),&sreg).append_query(rp.get_endpoint().uri) |
375 | ) | 375 | ) |
376 | << "\n\n"; | 376 | << "\n\n"; |
377 | DOUT_("Going to " << loc); | 377 | DOUT_("Going to " << loc); |
378 | }else if(op=="confirm") { | 378 | }else if(op=="confirm") { |
379 | kingate_openid_message_t om(gw); | 379 | kingate_openid_message_t om(gw); |
380 | example_rp_t rp(gw); | 380 | example_rp_t rp(gw); |
381 | opkele::sreg_t sreg(opkele::sreg_t::fields_NONE,opkele::sreg_t::fields_ALL); | 381 | opkele::sreg_t sreg(opkele::sreg_t::fields_NONE,opkele::sreg_t::fields_ALL); |
382 | rp.id_res(om,&sreg); | 382 | rp.id_res(om,&sreg); |
383 | cout << | 383 | cout << |
384 | "Content-Type: text/plain\n\n"; | 384 | "Content-Type: text/plain\n\n"; |
385 | for(opkele::basic_openid_message::fields_iterator i=om.fields_begin(); | 385 | for(opkele::basic_openid_message::fields_iterator i=om.fields_begin(); |
386 | i!=om.fields_end();++i) { | 386 | i!=om.fields_end();++i) { |
diff --git a/test/kingate_openid_message.h b/test/kingate_openid_message.h index 37dcdfa..7029ff7 100644 --- a/test/kingate_openid_message.h +++ b/test/kingate_openid_message.h | |||
@@ -28,66 +28,66 @@ class join_iterator : public iterator< | |||
28 | bool operator!=(const join_iterator<IT>& x) const { | 28 | bool operator!=(const join_iterator<IT>& x) const { |
29 | return ranges!=x.ranges; } | 29 | return ranges!=x.ranges; } |
30 | 30 | ||
31 | typename IT::reference operator*() const { | 31 | typename IT::reference operator*() const { |
32 | assert(!ranges.empty()); | 32 | assert(!ranges.empty()); |
33 | assert(ranges.front().first!=ranges.front().second); | 33 | assert(ranges.front().first!=ranges.front().second); |
34 | return *ranges.front().first; } | 34 | return *ranges.front().first; } |
35 | typename IT::pointer operator->() const { | 35 | typename IT::pointer operator->() const { |
36 | assert(!ranges.empty()); | 36 | assert(!ranges.empty()); |
37 | assert(ranges.front().first!=ranges.front().second); | 37 | assert(ranges.front().first!=ranges.front().second); |
38 | return ranges.front().first.operator->(); } | 38 | return ranges.front().first.operator->(); } |
39 | 39 | ||
40 | join_iterator<IT>& operator++() { | 40 | join_iterator<IT>& operator++() { |
41 | cleanup(); | 41 | cleanup(); |
42 | if(ranges.empty()) return *this; | 42 | if(ranges.empty()) return *this; |
43 | do { | 43 | do { |
44 | ++ranges.front().first; | 44 | ++ranges.front().first; |
45 | }while(cleanup() && !ranges.empty()); | 45 | }while(cleanup() && !ranges.empty()); |
46 | return *this; | 46 | return *this; |
47 | } | 47 | } |
48 | join_iterator<IT> operator++(int) { | 48 | join_iterator<IT> operator++(int) { |
49 | join_iterator<IT> rv(*this); | 49 | join_iterator<IT> rv(*this); |
50 | ++(*this); return rv; } | 50 | ++(*this); return rv; } |
51 | }; | 51 | }; |
52 | 52 | ||
53 | template<typename IT> | 53 | template<typename IT> |
54 | class cut_prefix_filterator : public opkele::util::basic_filterator<IT> { | 54 | class cut_prefix_filterator : public opkele::util::basic_filterator<IT> { |
55 | public: | 55 | public: |
56 | string pfx; | 56 | string pfx; |
57 | mutable string tmp; | 57 | mutable string tmp; |
58 | 58 | ||
59 | cut_prefix_filterator() { } | 59 | cut_prefix_filterator() { } |
60 | cut_prefix_filterator(const IT& bi,const IT&ei,const string& pfx) | 60 | cut_prefix_filterator(const IT& _bi,const IT&_ei,const string& p) |
61 | : opkele::util::basic_filterator<IT>(bi,ei), pfx(pfx) { | 61 | : opkele::util::basic_filterator<IT>(_bi,_ei), pfx(p) { |
62 | this->prepare(); | 62 | this->prepare(); |
63 | } | 63 | } |
64 | 64 | ||
65 | bool is_interesting() const { | 65 | bool is_interesting() const { |
66 | return pfx.length()==0 || !strncmp(this->it->c_str(),pfx.c_str(),pfx.length()); | 66 | return pfx.length()==0 || !strncmp(this->it->c_str(),pfx.c_str(),pfx.length()); |
67 | } | 67 | } |
68 | 68 | ||
69 | typename IT::reference operator*() const { | 69 | typename IT::reference operator*() const { |
70 | assert(!this->empty); | 70 | assert(!this->empty); |
71 | tmp = *this->it; tmp.erase(0,pfx.length()); | 71 | tmp = *this->it; tmp.erase(0,pfx.length()); |
72 | return tmp; } | 72 | return tmp; } |
73 | typename IT::pointer operator->() const { | 73 | typename IT::pointer operator->() const { |
74 | assert(!this->empty); | 74 | assert(!this->empty); |
75 | return &this->operator*(); } | 75 | return &this->operator*(); } |
76 | }; | 76 | }; |
77 | 77 | ||
78 | class kingate_openid_message_t : public opkele::basic_openid_message { | 78 | class kingate_openid_message_t : public opkele::basic_openid_message { |
79 | typedef join_iterator<kingate::cgi_gateway::params_t::const_iterator> jitterator; | 79 | typedef join_iterator<kingate::cgi_gateway::params_t::const_iterator> jitterator; |
80 | typedef opkele::util::map_keys_iterator< | 80 | typedef opkele::util::map_keys_iterator< |
81 | jitterator, | 81 | jitterator, |
82 | fields_iterator::value_type, | 82 | fields_iterator::value_type, |
83 | fields_iterator::reference, | 83 | fields_iterator::reference, |
84 | fields_iterator::pointer> keys_iterator; | 84 | fields_iterator::pointer> keys_iterator; |
85 | typedef cut_prefix_filterator<keys_iterator> pfilterator; | 85 | typedef cut_prefix_filterator<keys_iterator> pfilterator; |
86 | public: | 86 | public: |
87 | const kingate::cgi_gateway& gw; | 87 | const kingate::cgi_gateway& gw; |
88 | 88 | ||
89 | kingate_openid_message_t(const kingate::cgi_gateway& g) : gw(g) { } | 89 | kingate_openid_message_t(const kingate::cgi_gateway& g) : gw(g) { } |
90 | 90 | ||
91 | bool has_field(const string& n) const { | 91 | bool has_field(const string& n) const { |
92 | return gw.has_param("openid."+n); } | 92 | return gw.has_param("openid."+n); } |
93 | const string& get_field(const string& n) const try { | 93 | const string& get_field(const string& n) const try { |