summaryrefslogtreecommitdiffabout
authorMichael Krelin <hacker@klever.net>2008-02-08 22:16:15 (UTC)
committer Michael Krelin <hacker@klever.net>2008-02-08 22:16:15 (UTC)
commit16667a21c3052c89218d3e56098f0fc29dca2f1a (patch) (unidiff)
tree7154633a771b96da02cc4c980167b7ad92b6d27e
parentf2ba7be73a62d115f293f5d690efabcafd5fcf4f (diff)
downloadlibopkele-16667a21c3052c89218d3e56098f0fc29dca2f1a.zip
libopkele-16667a21c3052c89218d3e56098f0fc29dca2f1a.tar.gz
libopkele-16667a21c3052c89218d3e56098f0fc29dca2f1a.tar.bz2
minor fixes and making compiler a bit happier
Signed-off-by: Michael Krelin <hacker@klever.net>
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--include/opkele/basic_op.h2
-rw-r--r--include/opkele/expat.h16
-rw-r--r--include/opkele/iterator.h19
-rw-r--r--include/opkele/types.h1
-rw-r--r--lib/basic_op.cc29
-rw-r--r--lib/basic_rp.cc10
-rw-r--r--lib/discovery.cc2
-rw-r--r--lib/expat.cc1
-rw-r--r--lib/extension.cc2
-rw-r--r--lib/openid_message.cc32
-rw-r--r--lib/prequeue_rp.cc4
-rw-r--r--lib/sreg.cc6
-rw-r--r--lib/verify_op.cc4
-rw-r--r--test/OP.cc16
-rw-r--r--test/RP.cc6
-rw-r--r--test/kingate_openid_message.h4
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
@@ -1,96 +1,98 @@
1#ifndef __OPKELE_BASIC_OP_H 1#ifndef __OPKELE_BASIC_OP_H
2#define __OPKELE_BASIC_OP_H 2#define __OPKELE_BASIC_OP_H
3 3
4#include <string> 4#include <string>
5#include <opkele/types.h> 5#include <opkele/types.h>
6#include <opkele/extension.h> 6#include <opkele/extension.h>
7 7
8namespace opkele { 8namespace opkele {
9 using std::string; 9 using std::string;
10 10
11 /** 11 /**
12 * Implementation of basic OP functionality 12 * Implementation of basic OP functionality
13 */ 13 */
14 class basic_OP { 14 class basic_OP {
15 public: 15 public:
16 /** 16 /**
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
81 * @return claimed identifier 83 * @return claimed identifier
82 * @throw non_identity if request is not about identity 84 * @throw non_identity if request is not about identity
83 */ 85 */
84 const string& get_claimed_id() const; 86 const string& get_claimed_id() const;
85 /** 87 /**
86 * Get the identity (OP-Local identifier) being confirmed 88 * Get the identity (OP-Local identifier) being confirmed
87 * @return identity 89 * @return identity
88 * @throw non_identity if request is not about identity 90 * @throw non_identity if request is not about identity
89 */ 91 */
90 const string& get_identity() const; 92 const string& get_identity() const;
91 93
92 /** 94 /**
93 * Is identifier supposed to be selected on our side? 95 * Is identifier supposed to be selected on our side?
94 * @return true if identity is a special identifier select URI 96 * @return true if identity is a special identifier select URI
95 */ 97 */
96 bool is_id_select() const; 98 bool is_id_select() const;
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,91 +1,91 @@
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
7namespace opkele { 7namespace 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); }
84 84
85 }; 85 };
86 86
87 } 87 }
88 88
89} 89}
90 90
91#endif /* __OPKELE_EXPAT_H */ 91#endif /* __OPKELE_EXPAT_H */
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
7namespace opkele { 7namespace 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
@@ -81,96 +81,97 @@ namespace opkele {
81 * @return server name 81 * @return server name
82 */ 82 */
83 virtual string server() const = 0; 83 virtual string server() const = 0;
84 /** 84 /**
85 * retrieve the association handle. 85 * retrieve the association handle.
86 * @return handle 86 * @return handle
87 */ 87 */
88 virtual string handle() const = 0; 88 virtual string handle() const = 0;
89 /** 89 /**
90 * retrieve the association type. 90 * retrieve the association type.
91 * @return association type 91 * @return association type
92 */ 92 */
93 virtual string assoc_type() const = 0; 93 virtual string assoc_type() const = 0;
94 /** 94 /**
95 * retrieve the association secret. 95 * retrieve the association secret.
96 * @return association secret 96 * @return association secret
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:
161 openid_message_t() { } 162 openid_message_t() { }
162 openid_message_t(const basic_openid_message& x) 163 openid_message_t(const basic_openid_message& x)
163 : basic_openid_message(x) { } 164 : basic_openid_message(x) { }
164 165
165 void copy_to(basic_openid_message& x) const; 166 void copy_to(basic_openid_message& x) const;
166 167
167 bool has_field(const string& n) const; 168 bool has_field(const string& n) const;
168 const string& get_field(const string& n) const; 169 const string& get_field(const string& n) const;
169 virtual fields_iterator fields_begin() const; 170 virtual fields_iterator fields_begin() const;
170 virtual fields_iterator fields_end() const; 171 virtual fields_iterator fields_end() const;
171 172
172 void reset_fields(); 173 void reset_fields();
173 void set_field(const string& n,const string& v); 174 void set_field(const string& n,const string& v);
174 void reset_field(const string& n); 175 void reset_field(const string& n);
175 }; 176 };
176 177
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
@@ -21,168 +21,165 @@ namespace opkele {
21 return !return_to.empty(); 21 return !return_to.empty();
22 } 22 }
23 const string& basic_OP::get_return_to() const { 23 const string& basic_OP::get_return_to() const {
24 if(return_to.empty()) 24 if(return_to.empty())
25 throw no_return_to(OPKELE_CP_ "No return_to URL provided with request"); 25 throw no_return_to(OPKELE_CP_ "No return_to URL provided with request");
26 return return_to; 26 return return_to;
27 } 27 }
28 28
29 const string& basic_OP::get_realm() const { 29 const string& basic_OP::get_realm() const {
30 assert(!realm.empty()); 30 assert(!realm.empty());
31 return realm; 31 return realm;
32 } 32 }
33 33
34 bool basic_OP::has_identity() const { 34 bool basic_OP::has_identity() const {
35 return !identity.empty(); 35 return !identity.empty();
36 } 36 }
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_
173 "Both realm and return_to are unset"); 170 "Both realm and return_to are unset");
174 realm = return_to; 171 realm = return_to;
175 } 172 }
176 } 173 }
177 try { 174 try {
178 identity = inm.get_field("identity"); 175 identity = inm.get_field("identity");
179 try { 176 try {
180 claimed_id = inm.get_field("claimed_id"); 177 claimed_id = inm.get_field("claimed_id");
181 }catch(failed_lookup&) { 178 }catch(failed_lookup&) {
182 if(openid2) 179 if(openid2)
183 throw bad_input(OPKELE_CP_ 180 throw bad_input(OPKELE_CP_
184 "claimed_id and identity must be either both present or both absent"); 181 "claimed_id and identity must be either both present or both absent");
185 claimed_id = identity; 182 claimed_id = identity;
186 } 183 }
187 }catch(failed_lookup&) { 184 }catch(failed_lookup&) {
188 if(openid2 && inm.has_field("claimed_id")) 185 if(openid2 && inm.has_field("claimed_id"))
@@ -193,104 +190,104 @@ namespace opkele {
193 if(ext) ext->op_checkid_hook(inm); 190 if(ext) ext->op_checkid_hook(inm);
194 } 191 }
195 192
196 basic_openid_message& basic_OP::id_res(basic_openid_message& om, 193 basic_openid_message& basic_OP::id_res(basic_openid_message& om,
197 extension_t *ext) { 194 extension_t *ext) {
198 assert(!return_to.empty()); 195 assert(!return_to.empty());
199 assert(!is_id_select()); 196 assert(!is_id_select());
200 if(!assoc) { 197 if(!assoc) {
201 assoc = alloc_assoc("HMAC-SHA256",SHA256_DIGEST_LENGTH,true); 198 assoc = alloc_assoc("HMAC-SHA256",SHA256_DIGEST_LENGTH,true);
202 } 199 }
203 time_t now = time(0); 200 time_t now = time(0);
204 struct tm gmt; gmtime_r(&now,&gmt); 201 struct tm gmt; gmtime_r(&now,&gmt);
205 char w3timestr[24]; 202 char w3timestr[24];
206 if(!strftime(w3timestr,sizeof(w3timestr),"%Y-%m-%dT%H:%M:%SZ",&gmt)) 203 if(!strftime(w3timestr,sizeof(w3timestr),"%Y-%m-%dT%H:%M:%SZ",&gmt))
207 throw failed_conversion(OPKELE_CP_ 204 throw failed_conversion(OPKELE_CP_
208 "Failed to build time string for nonce" ); 205 "Failed to build time string for nonce" );
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) {
281 try { 278 try {
282 if(!check_nonce(nonce = inm.get_field("response_nonce"))) 279 if(!check_nonce(nonce = inm.get_field("response_nonce")))
283 throw failed_check_authentication(OPKELE_CP_ "Invalid nonce"); 280 throw failed_check_authentication(OPKELE_CP_ "Invalid nonce");
284 }catch(failed_lookup&) { 281 }catch(failed_lookup&) {
285 throw failed_check_authentication(OPKELE_CP_ "No nonce provided with check_authentication request"); 282 throw failed_check_authentication(OPKELE_CP_ "No nonce provided with check_authentication request");
286 } 283 }
287 } 284 }
288 try { 285 try {
289 assoc = retrieve_assoc(inm.get_field("assoc_handle")); 286 assoc = retrieve_assoc(inm.get_field("assoc_handle"));
290 if(!assoc->stateless()) 287 if(!assoc->stateless())
291 throw failed_check_authentication(OPKELE_CP_ "Will not do check_authentication on a stateful handle"); 288 throw failed_check_authentication(OPKELE_CP_ "Will not do check_authentication on a stateful handle");
292 }catch(failed_lookup&) { 289 }catch(failed_lookup&) {
293 throw failed_check_authentication(OPKELE_CP_ "No assoc_handle or invalid assoc_handle specified with check_authentication request"); 290 throw failed_check_authentication(OPKELE_CP_ "No assoc_handle or invalid assoc_handle specified with check_authentication request");
294 } 291 }
295 static const string idresmode = "id_res"; 292 static const string idresmode = "id_res";
296 try { 293 try {
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,138 +1,140 @@
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
10namespace opkele { 11namespace 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);
123 rv.set_field("identity",ep.local_id); 125 rv.set_field("identity",ep.local_id);
124 try { 126 try {
125 rv.set_field("assoc_handle",find_assoc(ep.uri)->handle()); 127 rv.set_field("assoc_handle",find_assoc(ep.uri)->handle());
126 }catch(dumb_RP& drp) { 128 }catch(dumb_RP& drp) {
127 }catch(failed_lookup& fl) { 129 }catch(failed_lookup& fl) {
128 try { 130 try {
129 rv.set_field("assoc_handle",associate(ep.uri)->handle()); 131 rv.set_field("assoc_handle",associate(ep.uri)->handle());
130 }catch(dumb_RP& drp) { } 132 }catch(dumb_RP& drp) { }
131 } OPKELE_RETHROW 133 } OPKELE_RETHROW
132 if(ext) ext->rp_checkid_hook(rv); 134 if(ext) ext->rp_checkid_hook(rv);
133 return rv; 135 return rv;
134 } 136 }
135 137
136 class signed_part_message_proxy : public basic_openid_message { 138 class signed_part_message_proxy : public basic_openid_message {
137 public: 139 public:
138 const basic_openid_message& x; 140 const basic_openid_message& x;
@@ -189,97 +191,97 @@ namespace opkele {
189 } 191 }
190 q = ++am; 192 q = ++am;
191 } 193 }
192 } 194 }
193 } 195 }
194 196
195 void basic_RP::id_res(const basic_openid_message& om,extension_t *ext) { 197 void basic_RP::id_res(const basic_openid_message& om,extension_t *ext) {
196 bool o2 = om.has_field("ns") 198 bool o2 = om.has_field("ns")
197 && om.get_field("ns")==OIURI_OPENID20; 199 && om.get_field("ns")==OIURI_OPENID20;
198 if( (!o2) && om.has_field("user_setup_url")) 200 if( (!o2) && om.has_field("user_setup_url"))
199 throw id_res_setup(OPKELE_CP_ "assertion failed, setup url provided", 201 throw id_res_setup(OPKELE_CP_ "assertion failed, setup url provided",
200 om.get_field("user_setup_url")); 202 om.get_field("user_setup_url"));
201 string m = om.get_field("mode"); 203 string m = om.get_field("mode");
202 if(o2 && m=="setup_needed") 204 if(o2 && m=="setup_needed")
203 throw id_res_setup(OPKELE_CP_ "setup needed, no setup url provided"); 205 throw id_res_setup(OPKELE_CP_ "setup needed, no setup url provided");
204 if(m=="cancel") 206 if(m=="cancel")
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
270 if(om.has_field("claimed_id")) { 272 if(om.has_field("claimed_id")) {
271 verify_OP( 273 verify_OP(
272 om.get_field("op_endpoint"), 274 om.get_field("op_endpoint"),
273 om.get_field("claimed_id"), 275 om.get_field("claimed_id"),
274 om.get_field("identity") ); 276 om.get_field("identity") );
275 } 277 }
276 278
277 } 279 }
278 if(ext) ext->rp_id_res_hook(om,signeds); 280 if(ext) ext->rp_id_res_hook(om,signeds);
279 } 281 }
280 282
281 void basic_RP::check_authentication(const string& OP, 283 void basic_RP::check_authentication(const string& OP,
282 const basic_openid_message& om){ 284 const basic_openid_message& om){
283 openid_message_t res; 285 openid_message_t res;
284 static const string checkauthmode = "check_authentication"; 286 static const string checkauthmode = "check_authentication";
285 direct_request(res,util::change_mode_message_proxy(om,checkauthmode),OP); 287 direct_request(res,util::change_mode_message_proxy(om,checkauthmode),OP);
diff --git a/lib/discovery.cc b/lib/discovery.cc
index 6f58339..6f9926c 100644
--- a/lib/discovery.cc
+++ b/lib/discovery.cc
@@ -285,97 +285,97 @@ namespace opkele {
285 } 285 }
286 286
287 void html2xrd(endpoint_discovery_iterator& oi,idiscovery_t& id) { 287 void html2xrd(endpoint_discovery_iterator& oi,idiscovery_t& id) {
288 XRD_t& x = id.xrd; 288 XRD_t& x = id.xrd;
289 if(!html_openid2.uris.empty()) { 289 if(!html_openid2.uris.empty()) {
290 html_openid2.types.insert(STURI_OPENID20); 290 html_openid2.types.insert(STURI_OPENID20);
291 x.services.add(-1,html_openid2); 291 x.services.add(-1,html_openid2);
292 queue_endpoints(oi,id,&op_service_types[st_index_2]); 292 queue_endpoints(oi,id,&op_service_types[st_index_2]);
293 } 293 }
294 if(!html_openid1.uris.empty()) { 294 if(!html_openid1.uris.empty()) {
295 html_openid1.types.insert(STURI_OPENID11); 295 html_openid1.types.insert(STURI_OPENID11);
296 x.services.add(-1,html_openid1); 296 x.services.add(-1,html_openid1);
297 queue_endpoints(oi,id,&op_service_types[st_index_1]); 297 queue_endpoints(oi,id,&op_service_types[st_index_1]);
298 } 298 }
299 } 299 }
300 300
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);
366 xrd->clear(); 366 xrd->clear();
367 pt_stack.push_back(n); 367 pt_stack.push_back(n);
368 }else if(xmode&xmode_html) { 368 }else if(xmode&xmode_html) {
369 html_start_element(n,a); 369 html_start_element(n,a);
370 }else{ 370 }else{
371 skipping = -1; 371 skipping = -1;
372 } 372 }
373 }else{ 373 }else{
374 int pt_s = pt_stack.size(); 374 int pt_s = pt_stack.size();
375 if(pt_s==1) { 375 if(pt_s==1) {
376 if(is_qelement(n,NSURI_XRD "\tCanonicalID")) { 376 if(is_qelement(n,NSURI_XRD "\tCanonicalID")) {
377 assert(xrd); 377 assert(xrd);
378 cdata = &(xrd->canonical_ids.add(element_priority(a),string())); 378 cdata = &(xrd->canonical_ids.add(element_priority(a),string()));
379 }else if(is_qelement(n,NSURI_XRD "\tLocalID")) { 379 }else if(is_qelement(n,NSURI_XRD "\tLocalID")) {
380 assert(xrd); 380 assert(xrd);
381 cdata = &(xrd->local_ids.add(element_priority(a),string())); 381 cdata = &(xrd->local_ids.add(element_priority(a),string()));
diff --git a/lib/expat.cc b/lib/expat.cc
index fa6fdde..c4dab7e 100644
--- a/lib/expat.cc
+++ b/lib/expat.cc
@@ -1,63 +1,64 @@
1#include <opkele/expat.h> 1#include <opkele/expat.h>
2 2
3namespace opkele { 3namespace 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
48 static void _comment(void *ud,const XML_Char *d) { 49 static void _comment(void *ud,const XML_Char *d) {
49 ((expat_t*)ud)->comment(d); 50 ((expat_t*)ud)->comment(d);
50 } 51 }
51 52
52 void expat_t::set_comment_handler() { 53 void expat_t::set_comment_handler() {
53 assert(_x); 54 assert(_x);
54 XML_SetCommentHandler(_x,_comment); 55 XML_SetCommentHandler(_x,_comment);
55 } 56 }
56 57
57 static void _start_cdata_section(void *ud) { 58 static void _start_cdata_section(void *ud) {
58 ((expat_t*)ud)->start_cdata_section(); 59 ((expat_t*)ud)->start_cdata_section();
59 } 60 }
60 static void _end_cdata_section(void *ud) { 61 static void _end_cdata_section(void *ud) {
61 ((expat_t*)ud)->end_cdata_section(); 62 ((expat_t*)ud)->end_cdata_section();
62 } 63 }
63 64
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
4namespace opkele { 4namespace 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,216 +1,216 @@
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
9namespace opkele { 9namespace 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);
201 else 201 else
202 signeds.append(fields,fnc,fields.size()-fnc); 202 signeds.append(fields,fnc,fields.size()-fnc);
203 } 203 }
204 } 204 }
205 }catch(failed_lookup&) { 205 }catch(failed_lookup&) {
206 signeds.assign(fields,fnc,fields.size()-fnc); 206 signeds.assign(fields,fnc,fields.size()-fnc);
207 } 207 }
208 set_field("signed",signeds); 208 set_field("signed",signeds);
209 } 209 }
210 210
211 string basic_openid_message::find_ns(const string& uri,const char *pfx) const { 211 string basic_openid_message::find_ns(const string& uri,const char *pfx) const {
212 if(has_field("ns")) 212 if(has_field("ns"))
213 return get_ns(uri); 213 return get_ns(uri);
214 return pfx; 214 return pfx;
215 } 215 }
216 string basic_openid_message::allocate_ns(const string& uri,const char *pfx) { 216 string basic_openid_message::allocate_ns(const string& uri,const char *pfx) {
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
@@ -10,72 +10,72 @@
10#include <opkele/curl.h> 10#include <opkele/curl.h>
11#include <opkele/debug.h> 11#include <opkele/debug.h>
12 12
13namespace opkele { 13namespace opkele {
14 14
15 class __OP_verifier_good_input : public exception { 15 class __OP_verifier_good_input : public exception {
16 public: 16 public:
17 __OP_verifier_good_input(OPKELE_E_PARS) 17 __OP_verifier_good_input(OPKELE_E_PARS)
18 : exception(OPKELE_E_CONS) { } 18 : exception(OPKELE_E_CONS) { }
19 }; 19 };
20 20
21 class OP_verifier : public iterator<output_iterator_tag,openid_endpoint_t,void> { 21 class OP_verifier : public iterator<output_iterator_tag,openid_endpoint_t,void> {
22 public: 22 public:
23 const string& OP; 23 const string& OP;
24 const string& id; 24 const string& id;
25 25
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
@@ -10,102 +10,100 @@ namespace opkele {
10 const char *fieldname; 10 const char *fieldname;
11 sreg_t::fieldbit_t fieldbit; 11 sreg_t::fieldbit_t fieldbit;
12 }fields[] = { 12 }fields[] = {
13 { "nickname", sreg_t::field_nickname }, 13 { "nickname", sreg_t::field_nickname },
14 { "email", sreg_t::field_email }, 14 { "email", sreg_t::field_email },
15 { "fullname", sreg_t::field_fullname }, 15 { "fullname", sreg_t::field_fullname },
16 { "dob", sreg_t::field_dob }, 16 { "dob", sreg_t::field_dob },
17 { "gender", sreg_t::field_gender }, 17 { "gender", sreg_t::field_gender },
18 { "postcode", sreg_t::field_postcode }, 18 { "postcode", sreg_t::field_postcode },
19 { "country", sreg_t::field_country }, 19 { "country", sreg_t::field_country },
20 { "language", sreg_t::field_language }, 20 { "language", sreg_t::field_language },
21 { "timezone", sreg_t::field_timezone } 21 { "timezone", sreg_t::field_timezone }
22 }; 22 };
23 # define fields_BEGINfields 23 # define fields_BEGINfields
24# define fields_END &fields[sizeof(fields)/sizeof(*fields)] 24# define fields_END &fields[sizeof(fields)/sizeof(*fields)]
25 typedef const struct _sreg_field *fields_iterator; 25 typedef const struct _sreg_field *fields_iterator;
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() {
96 has_fields = 0; response.clear(); 94 has_fields = 0; response.clear();
97 } 95 }
98 96
99 static long fields_list_to_bitmask(string& fl) { 97 static long fields_list_to_bitmask(string& fl) {
100 long rv = 0; 98 long rv = 0;
101 while(!fl.empty()) { 99 while(!fl.empty()) {
102 string::size_type co = fl.find(','); 100 string::size_type co = fl.find(',');
103 string fn; 101 string fn;
104 if(co==string::npos) { 102 if(co==string::npos) {
105 fn = fl; fl.erase(); 103 fn = fl; fl.erase();
106 }else{ 104 }else{
107 fn = fl.substr(0,co); fl.erase(0,co+1); 105 fn = fl.substr(0,co); fl.erase(0,co+1);
108 } 106 }
109 fields_iterator f = find(fields_BEGIN,fields_END,fn); 107 fields_iterator f = find(fields_BEGIN,fields_END,fn);
110 if(f!=fields_END) 108 if(f!=fields_END)
111 rv |= f->fieldbit; 109 rv |= f->fieldbit;
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
7namespace opkele { 7namespace 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}
diff --git a/test/OP.cc b/test/OP.cc
index 851d831..6012b2e 100644
--- a/test/OP.cc
+++ b/test/OP.cc
@@ -14,98 +14,98 @@ using namespace std;
14#include <opkele/association.h> 14#include <opkele/association.h>
15#include <opkele/debug.h> 15#include <opkele/debug.h>
16#include <opkele/verify_op.h> 16#include <opkele/verify_op.h>
17#include <opkele/sreg.h> 17#include <opkele/sreg.h>
18 18
19#include "sqlite.h" 19#include "sqlite.h"
20#include "kingate_openid_message.h" 20#include "kingate_openid_message.h"
21 21
22static const string get_self_url(const kingate::cgi_gateway& gw) { 22static const string get_self_url(const kingate::cgi_gateway& gw) {
23 bool s = gw.has_meta("SSL_PROTOCOL_VERSION"); 23 bool s = gw.has_meta("SSL_PROTOCOL_VERSION");
24 string rv = s?"https://":"http://"; 24 string rv = s?"https://":"http://";
25 rv += gw.http_request_header("Host"); 25 rv += gw.http_request_header("Host");
26 const string& port = gw.get_meta("SERVER_PORT"); 26 const string& port = gw.get_meta("SERVER_PORT");
27 if( port!=(s?"443":"80") ) { 27 if( port!=(s?"443":"80") ) {
28 rv += ':'; rv += port; 28 rv += ':'; rv += port;
29 } 29 }
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
37class opdb_t : public sqlite3_t { 37class 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
55class example_op_t : public opkele::verify_OP { 55class 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"
96 " FROM ht_sessions" 96 " FROM ht_sessions"
97 " WHERE hts_id=%Q", 97 " WHERE hts_id=%Q",
98 htc.get_value().c_str()); 98 htc.get_value().c_str());
99 sqlite3_table_t T; int nr,nc; 99 sqlite3_table_t T; int nr,nc;
100 db.get_table(S,T,&nr,&nc); 100 db.get_table(S,T,&nr,&nc);
101 assert(nr==1); assert(nc=1); 101 assert(nr==1); assert(nc=1);
102 return opkele::util::string_to_long(T.get(1,0,nc)); 102 return opkele::util::string_to_long(T.get(1,0,nc));
103 } 103 }
104 104
105 ostream& cookie_header(ostream& o) const { 105 ostream& cookie_header(ostream& o) const {
106 o << "Set-Cookie: " << htc.set_cookie_header() << "\n"; 106 o << "Set-Cookie: " << htc.set_cookie_header() << "\n";
107 return o; 107 return o;
108 } 108 }
109 109
110 opkele::assoc_t alloc_assoc(const string& type,size_t klength,bool sl) { 110 opkele::assoc_t alloc_assoc(const string& type,size_t klength,bool sl) {
111 uuid_t uuid; uuid_generate(uuid); 111 uuid_t uuid; uuid_generate(uuid);
@@ -155,233 +155,233 @@ class example_op_t : public opkele::verify_OP {
155 "couldn't retrieve valid unexpired assoc"); 155 "couldn't retrieve valid unexpired assoc");
156 assert(nr==1); assert(nc==6); 156 assert(nr==1); assert(nc==6);
157 opkele::secret_t secret; opkele::util::decode_base64(T.get(1,2,nc),secret); 157 opkele::secret_t secret; opkele::util::decode_base64(T.get(1,2,nc),secret);
158 return opkele::assoc_t(new opkele::association( 158 return opkele::assoc_t(new opkele::association(
159 "", h, T.get(1,1,nc), secret, 159 "", h, T.get(1,1,nc), secret,
160 strtol(T.get(1,4,nc),0,0), 160 strtol(T.get(1,4,nc),0,0),
161 strtol(T.get(1,3,nc),0,0) )); 161 strtol(T.get(1,3,nc),0,0) ));
162 } 162 }
163 163
164 string& alloc_nonce(string& nonce) { 164 string& alloc_nonce(string& nonce) {
165 uuid_t uuid; uuid_generate(uuid); 165 uuid_t uuid; uuid_generate(uuid);
166 nonce += opkele::util::encode_base64(uuid,sizeof(uuid)); 166 nonce += opkele::util::encode_base64(uuid,sizeof(uuid));
167 sqlite3_mem_t<char*> 167 sqlite3_mem_t<char*>
168 S = sqlite3_mprintf( 168 S = sqlite3_mprintf(
169 "INSERT INTO nonces" 169 "INSERT INTO nonces"
170 " (n_once) VALUES (%Q)", 170 " (n_once) VALUES (%Q)",
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
203int main(int argc,char *argv[]) { 203int 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);
372 if(nr<1) { 372 if(nr<1) {
373 cout << 373 cout <<
374 "<form method='post'>" 374 "<form method='post'>"
375 "set password " 375 "set password "
376 "<input type='hidden' name='op' value='set_password'/>" 376 "<input type='hidden' name='op' value='set_password'/>"
377 "<input type='password' name='password' value=''/>" 377 "<input type='password' name='password' value=''/>"
378 "<input type='submit' name='submit' value='submit'/>" 378 "<input type='submit' name='submit' value='submit'/>"
379 "</form>"; 379 "</form>";
380 }else if(OP.get_authorized()) { 380 }else if(OP.get_authorized()) {
381 cout << 381 cout <<
382 "<br/>" 382 "<br/>"
383 "<a href='" << get_self_url(gw) << "?op=logout'>logout</a>"; 383 "<a href='" << get_self_url(gw) << "?op=logout'>logout</a>";
384 }else{ 384 }else{
385 cout << 385 cout <<
386 "<form method='post'>" 386 "<form method='post'>"
387 "login " 387 "login "
diff --git a/test/RP.cc b/test/RP.cc
index e9744a4..99a792c 100644
--- a/test/RP.cc
+++ b/test/RP.cc
@@ -13,98 +13,98 @@ using namespace std;
13#include <opkele/types.h> 13#include <opkele/types.h>
14#include <opkele/util.h> 14#include <opkele/util.h>
15#include <opkele/uris.h> 15#include <opkele/uris.h>
16#include <opkele/discovery.h> 16#include <opkele/discovery.h>
17#include <opkele/association.h> 17#include <opkele/association.h>
18#include <opkele/sreg.h> 18#include <opkele/sreg.h>
19using namespace opkele; 19using namespace opkele;
20#include <opkele/prequeue_rp.h> 20#include <opkele/prequeue_rp.h>
21#include <opkele/debug.h> 21#include <opkele/debug.h>
22 22
23#include "sqlite.h" 23#include "sqlite.h"
24#include "kingate_openid_message.h" 24#include "kingate_openid_message.h"
25 25
26#undef DUMB_RP 26#undef DUMB_RP
27 27
28#ifdef DUMB_RP 28#ifdef DUMB_RP
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
34class rpdb_t : public sqlite3_t { 34class 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
53class example_rp_t : public opkele::prequeue_RP { 53class 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,
95 util::encode_base64(&(secret.front()),secret.size()).c_str() ); 95 util::encode_base64(&(secret.front()),secret.size()).c_str() );
96 db.exec(S); 96 db.exec(S);
97 return opkele::assoc_t(new opkele::association( 97 return opkele::assoc_t(new opkele::association(
98 OP, handle, type, secret, exp, false )); 98 OP, handle, type, secret, exp, false ));
99 } 99 }
100 100
101 opkele::assoc_t find_assoc( 101 opkele::assoc_t find_assoc(
102 const string& OP) { 102 const string& OP) {
103 DUMBTHROW; 103 DUMBTHROW;
104 DOUT_("Looking for an assoc with '" << OP << '\''); 104 DOUT_("Looking for an assoc with '" << OP << '\'');
105 sqlite3_mem_t<char*> 105 sqlite3_mem_t<char*>
106 S = sqlite3_mprintf( 106 S = sqlite3_mprintf(
107 "SELECT" 107 "SELECT"
108 " a_op,a_handle,a_type,a_secret," 108 " a_op,a_handle,a_type,a_secret,"
109 " strftime('%%s',a_etime) AS a_etime" 109 " strftime('%%s',a_etime) AS a_etime"
110 " FROM assoc" 110 " FROM assoc"
@@ -306,97 +306,97 @@ class example_rp_t : public opkele::prequeue_RP {
306 _nid = T.get(1,0,nc); 306 _nid = T.get(1,0,nc);
307 } 307 }
308 return _nid; 308 return _nid;
309 } 309 }
310 310
311 const string get_this_url() const { 311 const string get_this_url() const {
312 bool s = gw.has_meta("SSL_PROTOCOL_VERSION"); 312 bool s = gw.has_meta("SSL_PROTOCOL_VERSION");
313 string rv = s?"https://":"http://"; 313 string rv = s?"https://":"http://";
314 rv += gw.http_request_header("Host"); 314 rv += gw.http_request_header("Host");
315 const string& port = gw.get_meta("SERVER_PORT"); 315 const string& port = gw.get_meta("SERVER_PORT");
316 if( port!=(s?"443":"80") ) { 316 if( port!=(s?"443":"80") ) {
317 rv += ':'; rv += port; 317 rv += ':'; rv += port;
318 } 318 }
319 rv += gw.get_meta("REQUEST_URI"); 319 rv += gw.get_meta("REQUEST_URI");
320 return rv; 320 return rv;
321 } 321 }
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
354int main(int argc,char *argv[]) { 354int 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) {
387 cout << *i << '=' << om.get_field(*i) << endl; 387 cout << *i << '=' << om.get_field(*i) << endl;
388 } 388 }
389 cout << endl 389 cout << endl
390 << "SREG fields: " << sreg.has_fields << endl; 390 << "SREG fields: " << sreg.has_fields << endl;
391 }else{ 391 }else{
392 cout << 392 cout <<
393 "Content-type: text/html\n\n" 393 "Content-type: text/html\n\n"
394 394
395 "<html>" 395 "<html>"
396 "<head><title>test RP</title></head>" 396 "<head><title>test RP</title></head>"
397 "<body>" 397 "<body>"
398 "<form action='' method='post'>" 398 "<form action='' method='post'>"
399 "<input type='hidden' name='op' value='initiate' />" 399 "<input type='hidden' name='op' value='initiate' />"
400 "<input type='text' name='openid_identity'/>" 400 "<input type='text' name='openid_identity'/>"
401 "<input type='submit' name='submit' value='submit' />" 401 "<input type='submit' name='submit' value='submit' />"
402 "</form>" 402 "</form>"
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
@@ -12,98 +12,98 @@ class join_iterator : public iterator<
12 bool cleanup() { 12 bool cleanup() {
13 bool rv = false; 13 bool rv = false;
14 while(!(ranges.empty() || ranges.front().first!=ranges.front().second)) { 14 while(!(ranges.empty() || ranges.front().first!=ranges.front().second)) {
15 ranges.pop_front(); rv = true; 15 ranges.pop_front(); rv = true;
16 } 16 }
17 return rv; 17 return rv;
18 } 18 }
19 19
20 join_iterator<IT>& add_range(const IT& b,const IT& e) { 20 join_iterator<IT>& add_range(const IT& b,const IT& e) {
21 ranges.push_back(typename ranges_t::value_type(b,e)); 21 ranges.push_back(typename ranges_t::value_type(b,e));
22 cleanup(); 22 cleanup();
23 return *this; 23 return *this;
24 } 24 }
25 25
26 bool operator==(const join_iterator<IT>& x) const { 26 bool operator==(const join_iterator<IT>& x) const {
27 return ranges==x.ranges; } 27 return ranges==x.ranges; }
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
53template<typename IT> 53template<typename IT>
54class cut_prefix_filterator : public opkele::util::basic_filterator<IT> { 54class 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
78class kingate_openid_message_t : public opkele::basic_openid_message { 78class 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 {
94 return gw.get_param("openid."+n); }catch(kingate::exception_notfound& nf) { 94 return gw.get_param("openid."+n); }catch(kingate::exception_notfound& nf) {
95 throw opkele::failed_lookup(OPKELE_CP_ nf.what()); } 95 throw opkele::failed_lookup(OPKELE_CP_ nf.what()); }
96 96
97 fields_iterator fields_begin() const { 97 fields_iterator fields_begin() const {
98 return 98 return
99 pfilterator( keys_iterator( 99 pfilterator( keys_iterator(
100 jitterator() 100 jitterator()
101 .add_range( gw.get.begin(), gw.get.end() ) 101 .add_range( gw.get.begin(), gw.get.end() )
102 .add_range( gw.post.begin(), gw.post.end() ), 102 .add_range( gw.post.begin(), gw.post.end() ),
103 jitterator() 103 jitterator()
104 ), keys_iterator(), "openid." ); 104 ), keys_iterator(), "openid." );
105 } 105 }
106 fields_iterator fields_end() const { 106 fields_iterator fields_end() const {
107 return pfilterator(); 107 return pfilterator();
108 } 108 }
109}; 109};